From 9613299717eb791f293c2a1a0802fb34d7480aaa Mon Sep 17 00:00:00 2001 From: elasota <1137273+elasota@users.noreply.github.com> Date: Fri, 19 Jul 2024 19:10:06 -0400 Subject: [PATCH] Update to SDL 2.30.5 --- .gitignore | 19 +- .../app/src/main/AndroidManifest.xml | 5 + .../app/HIDDeviceBLESteamController.java | 10 +- .../java/org/libsdl/app/HIDDeviceManager.java | 103 +- .../java/org/libsdl/app/HIDDeviceUSB.java | 13 +- .../app/src/main/java/org/libsdl/app/SDL.java | 22 +- .../main/java/org/libsdl/app/SDLActivity.java | 1425 +- .../java/org/libsdl/app/SDLAudioManager.java | 175 +- .../org/libsdl/app/SDLControllerManager.java | 282 +- .../main/java/org/libsdl/app/SDLSurface.java | 405 + AerofoilAndroid/make_symlinks.bat | 2 +- AerofoilSDL/AerofoilSDL.props | 4 +- SDL2-2.0.12/CMakeLists.txt | 2212 - SDL2-2.0.12/Makefile.os2 | 140 - SDL2-2.0.12/Makefile.psp | 96 - SDL2-2.0.12/Makefile.wiz | 80 - SDL2-2.0.12/SDL2Config.cmake | 1 - SDL2-2.0.12/VisualC-WinRT/SDL2-WinRT.nuspec | 23 - SDL2-2.0.12/VisualC-WinRT/SDL2-WinRT.targets | 38 - .../SDL2main-WinRT-NonXAML.nuspec | 22 - .../SDL2main-WinRT-NonXAML.targets | 10 - .../VisualC-WinRT/UWP_VS2015/SDL-UWP.vcxproj | 576 - .../UWP_VS2015/SDL-UWP.vcxproj.filters | 777 - .../WinPhone81_VS2013/SDL-WinPhone81.sln | 28 - .../WinPhone81_VS2013/SDL-WinPhone81.vcxproj | 467 - .../SDL-WinPhone81.vcxproj.filters | 738 - .../WinRT81_VS2013/SDL-WinRT81.sln | 34 - .../WinRT81_VS2013/SDL-WinRT81.vcxproj | 572 - .../SDL-WinRT81.vcxproj.filters | 774 - .../tests/loopwave/Assets/Logo.png | Bin 801 -> 0 bytes .../tests/loopwave/Assets/SmallLogo.png | Bin 329 -> 0 bytes .../tests/loopwave/Assets/SplashScreen.png | Bin 2146 -> 0 bytes .../tests/loopwave/Assets/StoreLogo.png | Bin 429 -> 0 bytes .../tests/loopwave/Package.appxmanifest | 42 - .../tests/loopwave/loopwave_VS2012.vcxproj | 170 - .../loopwave/loopwave_VS2012_TemporaryKey.pfx | Bin 2504 -> 0 bytes .../tests/testthread/Assets/Logo.png | Bin 801 -> 0 bytes .../tests/testthread/Assets/SmallLogo.png | Bin 329 -> 0 bytes .../tests/testthread/Assets/SplashScreen.png | Bin 2146 -> 0 bytes .../tests/testthread/Assets/StoreLogo.png | Bin 429 -> 0 bytes .../tests/testthread/Package.appxmanifest | 42 - .../testthread/testthread_VS2012.vcxproj | 160 - .../testthread_VS2012_TemporaryKey.pfx | Bin 2504 -> 0 bytes SDL2-2.0.12/VisualC.html | 146 - SDL2-2.0.12/VisualC/SDL/SDL.vcxproj.filters | 483 - SDL2-2.0.12/Xcode-iOS/Demos/Info.plist | 32 - .../SDL/SDL.xcodeproj/project.pbxproj | 3508 - .../contents.xcworkspacedata | 7 - .../xcshareddata/IDEWorkspaceChecks.plist | 8 - .../xcshareddata/xcschemes/All-iOS.xcscheme | 80 - .../xcshareddata/xcschemes/All-tvOS.xcscheme | 80 - .../PrepareXcodeProjectTemplate.xcscheme | 80 - .../xcschemes/libSDL-iOS-dylib.xcscheme | 80 - .../xcschemes/libSDL-iOS.xcscheme | 80 - .../xcschemes/libSDL-tvOS-dylib.xcscheme | 80 - .../xcschemes/libSDL-tvOS.xcscheme | 80 - .../xcschemes/libSDLmain-iOS.xcscheme | 80 - .../xcschemes/libSDLmain-tvOS.xcscheme | 80 - .../SDL2test.xcodeproj/project.pbxproj | 422 - .../SDL iOS Application/Default-568h@2x.png | Bin 83791 -> 0 bytes .../Template/SDL iOS Application/Default.png | Bin 18383 -> 0 bytes .../Template/SDL iOS Application/Icon.png | Bin 2409 -> 0 bytes .../Template/SDL iOS Application/Info.plist | 28 - .../TemplateIcon.icns | Bin 34248 -> 0 bytes .../TemplateInfo.plist | 10 - .../project.pbxproj | 308 - .../contents.xcworkspacedata | 7 - .../Template/SDL iOS Application/main.c | 100 - SDL2-2.0.12/Xcode-iOS/Test/Info.plist | 26 - SDL2-2.0.12/Xcode-iOS/Test/README | 11 - .../TestiPhoneOS.xcodeproj/project.pbxproj | 3192 - .../xcschemes/Framework-tvOS.xcscheme | 67 - .../xcschemes/Shared Library-iOS.xcscheme | 67 - .../xcschemes/Shared Library-tvOS.xcscheme | 67 - .../xcschemes/Shared Library.xcscheme | 67 - .../xcschemes/Standard DMG.xcscheme | 78 - .../xcschemes/Static Library-iOS.xcscheme | 67 - .../xcschemes/Static Library-tvOS.xcscheme | 67 - .../xcschemes/Static Library.xcscheme | 67 - .../xcschemes/hidapi-iOS.xcscheme | 67 - .../xcschemes/hidapi-tvOS.xcscheme | 67 - .../xcshareddata/xcschemes/hidapi.xcscheme | 67 - SDL2-2.0.12/acinclude/pkg_config.m4 | 133 - .../gradle/wrapper/gradle-wrapper.jar | Bin 53636 -> 0 bytes SDL2-2.0.12/build-scripts/config.guess | 1476 - SDL2-2.0.12/build-scripts/config.sub | 1868 - SDL2-2.0.12/build-scripts/config.sub.patch | 72 - SDL2-2.0.12/build-scripts/iosbuild.sh | 188 - SDL2-2.0.12/build-scripts/os2-buildbot.sh | 42 - SDL2-2.0.12/build-scripts/showrev.sh | 5 - SDL2-2.0.12/build-scripts/update-copyright.sh | 8 - SDL2-2.0.12/build-scripts/updaterev.sh | 20 - .../build-scripts/windows-buildbot-zipper.bat | 40 - SDL2-2.0.12/build-scripts/winrtbuild.bat | 8 - SDL2-2.0.12/build-scripts/winrtbuild.ps1 | 302 - SDL2-2.0.12/cmake/macros.cmake | 73 - SDL2-2.0.12/cmake/sdlchecks.cmake | 1184 - SDL2-2.0.12/debian/changelog | 138 - SDL2-2.0.12/debian/compat | 1 - SDL2-2.0.12/debian/control | 76 - SDL2-2.0.12/debian/copyright | 351 - SDL2-2.0.12/debian/docs | 4 - SDL2-2.0.12/debian/libsdl2-dev.install | 9 - SDL2-2.0.12/debian/libsdl2-dev.manpages | 1 - SDL2-2.0.12/debian/libsdl2.install | 1 - SDL2-2.0.12/debian/rules | 54 - SDL2-2.0.12/debian/sdl2-config.1 | 86 - SDL2-2.0.12/debian/source/format | 1 - SDL2-2.0.12/debian/watch | 2 - SDL2-2.0.12/docs/README-cmake.md | 84 - SDL2-2.0.12/docs/README-emscripten.md | 35 - SDL2-2.0.12/docs/README-hg.md | 22 - SDL2-2.0.12/docs/README-macosx.md | 240 - SDL2-2.0.12/docs/README-psp.md | 19 - SDL2-2.0.12/docs/README-windows.md | 45 - SDL2-2.0.12/include/SDL.h | 136 - SDL2-2.0.12/include/SDL_audio.h | 859 - SDL2-2.0.12/include/SDL_blendmode.h | 123 - SDL2-2.0.12/include/SDL_config.h.cmake | 493 - SDL2-2.0.12/include/SDL_config_psp.h | 164 - SDL2-2.0.12/include/SDL_config_wiz.h | 147 - SDL2-2.0.12/include/SDL_cpuinfo.h | 275 - SDL2-2.0.12/include/SDL_endian.h | 263 - SDL2-2.0.12/include/SDL_error.h | 76 - SDL2-2.0.12/include/SDL_filesystem.h | 136 - SDL2-2.0.12/include/SDL_gamecontroller.h | 420 - SDL2-2.0.12/include/SDL_hints.h | 1364 - SDL2-2.0.12/include/SDL_joystick.h | 418 - SDL2-2.0.12/include/SDL_keyboard.h | 217 - SDL2-2.0.12/include/SDL_log.h | 211 - SDL2-2.0.12/include/SDL_main.h | 180 - SDL2-2.0.12/include/SDL_mouse.h | 302 - SDL2-2.0.12/include/SDL_mutex.h | 251 - SDL2-2.0.12/include/SDL_opengles2_gl2.h | 621 - SDL2-2.0.12/include/SDL_opengles2_gl2ext.h | 2050 - .../include/SDL_opengles2_gl2platform.h | 30 - SDL2-2.0.12/include/SDL_rect.h | 174 - SDL2-2.0.12/include/SDL_render.h | 1158 - SDL2-2.0.12/include/SDL_revision.h | 2 - SDL2-2.0.12/include/SDL_rwops.h | 291 - SDL2-2.0.12/include/SDL_sensor.h | 251 - SDL2-2.0.12/include/SDL_surface.h | 554 - SDL2-2.0.12/include/SDL_system.h | 316 - SDL2-2.0.12/include/SDL_test_font.h | 81 - SDL2-2.0.12/include/SDL_thread.h | 361 - SDL2-2.0.12/include/SDL_timer.h | 115 - SDL2-2.0.12/include/SDL_version.h | 162 - SDL2-2.0.12/include/SDL_video.h | 1275 - SDL2-2.0.12/include/SDL_vulkan.h | 278 - SDL2-2.0.12/lib/x64/SDL2.dll | Bin 1471488 -> 0 bytes SDL2-2.0.12/lib/x64/SDL2.lib | Bin 150888 -> 0 bytes SDL2-2.0.12/lib/x64/SDL2main.lib | Bin 41196 -> 0 bytes SDL2-2.0.12/lib/x64/SDL2test.lib | Bin 935746 -> 0 bytes SDL2-2.0.12/sdl2-config.cmake.in | 39 - SDL2-2.0.12/src/SDL.c | 554 - SDL2-2.0.12/src/SDL_error.c | 309 - SDL2-2.0.12/src/SDL_error_c.h | 65 - SDL2-2.0.12/src/SDL_internal.h | 121 - SDL2-2.0.12/src/SDL_log.c | 452 - SDL2-2.0.12/src/audio/SDL_audiocvt.c | 1683 - SDL2-2.0.12/src/audio/SDL_audiotypecvt.c | 1430 - SDL2-2.0.12/src/audio/SDL_mixer.c | 369 - SDL2-2.0.12/src/audio/alsa/SDL_alsa_audio.c | 998 - .../src/audio/coreaudio/SDL_coreaudio.m | 984 - .../src/audio/pulseaudio/SDL_pulseaudio.c | 782 - .../src/audio/wasapi/SDL_wasapi_win32.c | 457 - .../src/audio/wasapi/SDL_wasapi_winrt.cpp | 304 - SDL2-2.0.12/src/core/android/keyinfotable.h | 175 - SDL2-2.0.12/src/core/linux/SDL_dbus.c | 359 - SDL2-2.0.12/src/core/linux/SDL_fcitx.c | 373 - SDL2-2.0.12/src/core/linux/SDL_ibus.c | 584 - SDL2-2.0.12/src/core/linux/SDL_threadprio.c | 116 - SDL2-2.0.12/src/core/windows/SDL_windows.c | 233 - SDL2-2.0.12/src/core/windows/SDL_windows.h | 75 - SDL2-2.0.12/src/core/windows/SDL_xinput.h | 177 - .../src/core/winrt/SDL_winrtapp_direct3d.h | 92 - SDL2-2.0.12/src/dynapi/SDL_dynapi.c | 361 - SDL2-2.0.12/src/events/SDL_events.c | 1030 - SDL2-2.0.12/src/events/SDL_keyboard.c | 1033 - SDL2-2.0.12/src/events/scancodes_linux.h | 263 - SDL2-2.0.12/src/events/scancodes_xfree86.h | 512 - .../src/filesystem/cocoa/SDL_sysfilesystem.m | 138 - .../src/haptic/windows/SDL_dinputhaptic_c.h | 47 - .../src/haptic/windows/SDL_xinputhaptic_c.h | 47 - SDL2-2.0.12/src/hidapi/SDL_hidapi.c | 752 - SDL2-2.0.12/src/hidapi/linux/hid.cpp | 333 - .../src/hidapi/windows/ddk_build/makefile | 49 - SDL2-2.0.12/src/joystick/SDL_gamecontroller.c | 2163 - SDL2-2.0.12/src/joystick/SDL_joystick.c | 2049 - SDL2-2.0.12/src/joystick/SDL_joystick_c.h | 108 - SDL2-2.0.12/src/joystick/SDL_sysjoystick.h | 159 - .../src/joystick/bsd/SDL_sysjoystick.c | 784 - .../src/joystick/dummy/SDL_sysjoystick.c | 126 - .../src/joystick/hidapi/SDL_hidapi_gamecube.c | 414 - .../src/joystick/hidapi/SDL_hidapi_ps4.c | 539 - .../src/joystick/hidapi/SDL_hidapi_steam.c | 1176 - .../src/joystick/hidapi/SDL_hidapi_switch.c | 1174 - .../src/joystick/hidapi/SDL_hidapi_xbox360.c | 767 - .../src/joystick/hidapi/SDL_hidapi_xboxone.c | 708 - .../src/joystick/hidapi/SDL_hidapijoystick.c | 1112 - .../joystick/hidapi/SDL_hidapijoystick_c.h | 128 - .../src/joystick/iphoneos/SDL_sysjoystick.m | 863 - .../src/joystick/linux/SDL_sysjoystick.c | 1129 - .../src/joystick/psp/SDL_sysjoystick.c | 264 - SDL2-2.0.12/src/joystick/sort_controllers.py | 82 - SDL2-2.0.12/src/joystick/usb_ids.h | 51 - .../src/joystick/windows/SDL_mmjoystick.c | 452 - .../joystick/windows/SDL_windowsjoystick.c | 577 - SDL2-2.0.12/src/main/uikit/SDL_uikit_main.c | 19 - SDL2-2.0.12/src/render/SDL_render.c | 3404 - SDL2-2.0.12/src/render/SDL_sysrender.h | 256 - .../src/render/metal/SDL_shaders_metal_ios.h | 1854 - .../src/render/metal/SDL_shaders_metal_osx.h | 1858 - .../src/render/metal/SDL_shaders_metal_tvos.h | 1854 - .../src/render/opengles2/SDL_shaders_gles2.c | 573 - .../src/render/opengles2/SDL_shaders_gles2.h | 70 - SDL2-2.0.12/src/render/psp/SDL_render_psp.c | 1059 - SDL2-2.0.12/src/render/software/SDL_draw.h | 632 - SDL2-2.0.12/src/stdlib/SDL_iconv.c | 940 - SDL2-2.0.12/src/test/SDL_test_compare.c | 117 - SDL2-2.0.12/src/test/SDL_test_crc32.c | 166 - SDL2-2.0.12/src/test/SDL_test_font.c | 3250 - SDL2-2.0.12/src/test/SDL_test_imageBlit.c | 1559 - .../src/test/SDL_test_imageBlitBlend.c | 2845 - SDL2-2.0.12/src/test/SDL_test_imageFace.c | 247 - .../src/test/SDL_test_imagePrimitives.c | 514 - .../src/test/SDL_test_imagePrimitivesBlend.c | 696 - SDL2-2.0.12/src/test/SDL_test_md5.c | 338 - SDL2-2.0.12/src/test/SDL_test_random.c | 96 - SDL2-2.0.12/src/thread/psp/SDL_syscond.c | 224 - SDL2-2.0.12/src/thread/psp/SDL_sysmutex.c | 136 - .../src/thread/pthread/SDL_systhread.c | 247 - SDL2-2.0.12/src/thread/windows/SDL_sysmutex.c | 110 - SDL2-2.0.12/src/thread/windows/SDL_syssem.c | 152 - SDL2-2.0.12/src/video/SDL_blit.h | 554 - SDL2-2.0.12/src/video/SDL_blit_0.c | 487 - SDL2-2.0.12/src/video/SDL_shape.c | 309 - SDL2-2.0.12/src/video/SDL_stretch.c | 353 - .../src/video/android/SDL_androidkeyboard.c | 391 - .../src/video/cocoa/SDL_cocoakeyboard.m | 607 - .../src/video/cocoa/SDL_cocoamousetap.m | 286 - SDL2-2.0.12/src/video/cocoa/SDL_cocoashape.m | 113 - .../video/emscripten/SDL_emscriptenevents.c | 723 - SDL2-2.0.12/src/video/haiku/SDL_BWin.h | 671 - .../src/video/haiku/SDL_bframebuffer.cc | 259 - .../src/video/khronos/GLES2/gl2platform.h | 38 - .../src/video/khronos/vulkan/vulkan.hpp | 53056 ---------------- .../src/video/khronos/vulkan/vulkan_core.h | 8823 --- .../src/video/khronos/vulkan/vulkan_fuchsia.h | 58 - .../src/video/khronos/vulkan/vulkan_mir.h | 65 - .../src/video/kmsdrm/SDL_kmsdrmmouse.c | 502 - .../src/video/kmsdrm/SDL_kmsdrmopengles.c | 152 - .../src/video/kmsdrm/SDL_kmsdrmvideo.c | 926 - .../src/video/offscreen/SDL_offscreenopengl.h | 54 - SDL2-2.0.12/src/video/psp/SDL_pspgl.c | 210 - SDL2-2.0.12/src/video/uikit/SDL_uikitevents.m | 75 - SDL2-2.0.12/src/video/uikit/SDL_uikitview.m | 348 - SDL2-2.0.12/src/video/uikit/keyinfotable.h | 174 - .../src/video/wayland/SDL_waylandclipboard.c | 123 - .../video/wayland/SDL_waylanddatamanager.c | 477 - .../video/wayland/SDL_waylanddatamanager.h | 103 - .../src/video/wayland/SDL_waylanddyn.h | 110 - .../src/video/wayland/SDL_waylandevents.c | 1264 - .../src/video/wayland/SDL_waylandevents_c.h | 51 - .../src/video/wayland/SDL_waylandmouse.c | 396 - .../src/video/wayland/SDL_waylandopengles.c | 122 - .../src/video/wayland/SDL_waylandsym.h | 128 - .../src/video/wayland/SDL_waylandtouch.h | 352 - .../src/video/wayland/SDL_waylandvideo.c | 539 - .../src/video/wayland/SDL_waylandwindow.c | 931 - .../src/video/wayland/SDL_waylandwindow.h | 106 - SDL2-2.0.12/src/video/windows/SDL_vkeys.h | 76 - .../src/video/windows/SDL_windowsevents.c | 1309 - .../src/video/windows/SDL_windowsmodes.c | 407 - .../src/video/windows/SDL_windowsmouse.c | 321 - .../src/video/windows/SDL_windowsopengl.h | 142 - .../src/video/windows/SDL_windowstaskdialog.h | 156 - .../src/video/windows/SDL_windowsvideo.c | 452 - .../src/video/windows/SDL_windowsvideo.h | 199 - .../src/video/windows/SDL_windowswindow.c | 1011 - .../src/video/winrt/SDL_winrtkeyboard.cpp | 430 - SDL2-2.0.12/src/video/x11/SDL_x11events.c | 1514 - SDL2-2.0.12/src/video/x11/SDL_x11keyboard.c | 546 - SDL2-2.0.12/src/video/x11/SDL_x11messagebox.c | 893 - SDL2-2.0.12/src/video/x11/SDL_x11modes.c | 1112 - SDL2-2.0.12/src/video/x11/SDL_x11xinput2.c | 348 - SDL2-2.0.12/src/video/x11/edid.h | 167 - SDL2-2.0.12/src/video/yuv2rgb/yuv_rgb.h | 381 - SDL2-2.0.12/test/CMakeLists.txt | 155 - SDL2-2.0.12/test/COPYING | 8 - SDL2-2.0.12/test/Makefile.in | 336 - SDL2-2.0.12/test/Makefile.os2 | 91 - SDL2-2.0.12/test/README | 47 - SDL2-2.0.12/test/acinclude.m4 | 359 - SDL2-2.0.12/test/autogen.sh | 12 - SDL2-2.0.12/test/button.bmp | Bin 3746 -> 0 bytes SDL2-2.0.12/test/checkkeys.c | 248 - SDL2-2.0.12/test/configure | 5140 -- SDL2-2.0.12/test/configure.ac | 204 - SDL2-2.0.12/test/controllermap.bmp | Bin 163450 -> 0 bytes SDL2-2.0.12/test/controllermap.c | 789 - SDL2-2.0.12/test/emscripten/joystick-pre.js | 25 - SDL2-2.0.12/test/gcc-fat.sh | 110 - SDL2-2.0.12/test/icon.bmp | Bin 578 -> 0 bytes SDL2-2.0.12/test/loopwave.c | 179 - SDL2-2.0.12/test/loopwavequeue.c | 149 - SDL2-2.0.12/test/moose.dat | Bin 56320 -> 0 bytes SDL2-2.0.12/test/nacl/Makefile | 63 - SDL2-2.0.12/test/nacl/background.js | 40 - SDL2-2.0.12/test/nacl/common.js | 474 - SDL2-2.0.12/test/nacl/index.html | 21 - SDL2-2.0.12/test/nacl/manifest.json | 22 - SDL2-2.0.12/test/picture.xbm | 14 - SDL2-2.0.12/test/relative_mode.markdown | 58 - SDL2-2.0.12/test/sample.bmp | Bin 69202 -> 0 bytes SDL2-2.0.12/test/sample.wav | Bin 121946 -> 0 bytes SDL2-2.0.12/test/shapes/p01_shape24.bmp | Bin 1228938 -> 0 bytes SDL2-2.0.12/test/shapes/p01_shape32alpha.bmp | Bin 1638538 -> 0 bytes SDL2-2.0.12/test/shapes/p01_shape8.bmp | Bin 410678 -> 0 bytes SDL2-2.0.12/test/shapes/p02_shape24.bmp | Bin 1228938 -> 0 bytes SDL2-2.0.12/test/shapes/p02_shape32alpha.bmp | Bin 1638538 -> 0 bytes SDL2-2.0.12/test/shapes/p02_shape8.bmp | Bin 410678 -> 0 bytes SDL2-2.0.12/test/shapes/p03_shape24.bmp | Bin 1228938 -> 0 bytes SDL2-2.0.12/test/shapes/p03_shape8.bmp | Bin 410678 -> 0 bytes SDL2-2.0.12/test/shapes/p04_shape1.bmp | Bin 51346 -> 0 bytes SDL2-2.0.12/test/shapes/p04_shape24.bmp | Bin 1228938 -> 0 bytes SDL2-2.0.12/test/shapes/p04_shape32alpha.bmp | Bin 1638538 -> 0 bytes SDL2-2.0.12/test/shapes/p04_shape8.bmp | Bin 410678 -> 0 bytes SDL2-2.0.12/test/shapes/p05_shape8.bmp | Bin 410678 -> 0 bytes SDL2-2.0.12/test/shapes/p06_shape1alpha.bmp | Bin 1638538 -> 0 bytes SDL2-2.0.12/test/shapes/p06_shape24.bmp | Bin 1228938 -> 0 bytes SDL2-2.0.12/test/shapes/p06_shape32alpha.bmp | Bin 1638538 -> 0 bytes SDL2-2.0.12/test/shapes/p06_shape8.bmp | Bin 410678 -> 0 bytes SDL2-2.0.12/test/shapes/p07_shape24.bmp | Bin 1228938 -> 0 bytes SDL2-2.0.12/test/shapes/p07_shape32alpha.bmp | Bin 1638538 -> 0 bytes SDL2-2.0.12/test/shapes/p07_shape8.bmp | Bin 410678 -> 0 bytes SDL2-2.0.12/test/shapes/p08_shape24.bmp | Bin 1228938 -> 0 bytes SDL2-2.0.12/test/shapes/p08_shape32alpha.bmp | Bin 1638538 -> 0 bytes SDL2-2.0.12/test/shapes/p08_shape8.bmp | Bin 410678 -> 0 bytes SDL2-2.0.12/test/shapes/p09_shape24.bmp | Bin 1228938 -> 0 bytes SDL2-2.0.12/test/shapes/p09_shape32alpha.bmp | Bin 1638538 -> 0 bytes SDL2-2.0.12/test/shapes/p09_shape8.bmp | Bin 410678 -> 0 bytes SDL2-2.0.12/test/shapes/p10_shape1.bmp | Bin 51346 -> 0 bytes SDL2-2.0.12/test/shapes/p10_shape24.bmp | Bin 1228938 -> 0 bytes SDL2-2.0.12/test/shapes/p10_shape32alpha.bmp | Bin 1638538 -> 0 bytes SDL2-2.0.12/test/shapes/p10_shape8.bmp | Bin 410678 -> 0 bytes SDL2-2.0.12/test/shapes/p11_shape24.bmp | Bin 1228938 -> 0 bytes SDL2-2.0.12/test/shapes/p11_shape32alpha.bmp | Bin 1638538 -> 0 bytes SDL2-2.0.12/test/shapes/p11_shape8.bmp | Bin 410678 -> 0 bytes SDL2-2.0.12/test/shapes/p12_shape24.bmp | Bin 1228938 -> 0 bytes SDL2-2.0.12/test/shapes/p12_shape8.bmp | Bin 410678 -> 0 bytes SDL2-2.0.12/test/shapes/p13_shape24.bmp | Bin 1228938 -> 0 bytes SDL2-2.0.12/test/shapes/p13_shape32alpha.bmp | Bin 1638538 -> 0 bytes SDL2-2.0.12/test/shapes/p13_shape8.bmp | Bin 410678 -> 0 bytes SDL2-2.0.12/test/shapes/p14_shape24.bmp | Bin 1228938 -> 0 bytes SDL2-2.0.12/test/shapes/p14_shape8.bmp | Bin 410678 -> 0 bytes SDL2-2.0.12/test/shapes/p15_shape24.bmp | Bin 1228938 -> 0 bytes SDL2-2.0.12/test/shapes/p15_shape32alpha.bmp | Bin 1638538 -> 0 bytes SDL2-2.0.12/test/shapes/p15_shape8.bmp | Bin 410678 -> 0 bytes SDL2-2.0.12/test/shapes/p16_shape1.bmp | Bin 51346 -> 0 bytes SDL2-2.0.12/test/shapes/p16_shape24.bmp | Bin 1228938 -> 0 bytes SDL2-2.0.12/test/shapes/p16_shape8.bmp | Bin 410678 -> 0 bytes SDL2-2.0.12/test/shapes/trollface_24.bmp | Bin 196662 -> 0 bytes SDL2-2.0.12/test/shapes/trollface_32alpha.bmp | Bin 262198 -> 0 bytes SDL2-2.0.12/test/testatomic.c | 727 - SDL2-2.0.12/test/testaudiocapture.c | 165 - SDL2-2.0.12/test/testaudiohotplug.c | 203 - SDL2-2.0.12/test/testaudioinfo.c | 74 - SDL2-2.0.12/test/testautomation.c | 124 - SDL2-2.0.12/test/testautomation_audio.c | 1038 - SDL2-2.0.12/test/testautomation_clipboard.c | 184 - SDL2-2.0.12/test/testautomation_events.c | 201 - SDL2-2.0.12/test/testautomation_hints.c | 168 - SDL2-2.0.12/test/testautomation_keyboard.c | 713 - SDL2-2.0.12/test/testautomation_main.c | 157 - SDL2-2.0.12/test/testautomation_mouse.c | 606 - SDL2-2.0.12/test/testautomation_pixels.c | 531 - SDL2-2.0.12/test/testautomation_platform.c | 584 - SDL2-2.0.12/test/testautomation_rect.c | 1696 - SDL2-2.0.12/test/testautomation_render.c | 1099 - SDL2-2.0.12/test/testautomation_rwops.c | 748 - SDL2-2.0.12/test/testautomation_sdltest.c | 1319 - SDL2-2.0.12/test/testautomation_stdlib.c | 319 - SDL2-2.0.12/test/testautomation_suites.h | 54 - SDL2-2.0.12/test/testautomation_surface.c | 648 - SDL2-2.0.12/test/testautomation_syswm.c | 61 - SDL2-2.0.12/test/testautomation_timer.c | 201 - SDL2-2.0.12/test/testautomation_video.c | 1811 - SDL2-2.0.12/test/testbounds.c | 40 - SDL2-2.0.12/test/testcustomcursor.c | 259 - SDL2-2.0.12/test/testdisplayinfo.c | 96 - SDL2-2.0.12/test/testdraw2.c | 305 - SDL2-2.0.12/test/testdrawchessboard.c | 147 - SDL2-2.0.12/test/testdropfile.c | 99 - SDL2-2.0.12/test/testerror.c | 76 - SDL2-2.0.12/test/testfile.c | 283 - SDL2-2.0.12/test/testfilesystem.c | 60 - SDL2-2.0.12/test/testgamecontroller.c | 396 - SDL2-2.0.12/test/testgesture.c | 297 - SDL2-2.0.12/test/testgl2.c | 440 - SDL2-2.0.12/test/testgles.c | 355 - SDL2-2.0.12/test/testgles2.c | 732 - SDL2-2.0.12/test/testhaptic.c | 369 - SDL2-2.0.12/test/testhittesting.c | 134 - SDL2-2.0.12/test/testhotplug.c | 162 - SDL2-2.0.12/test/testiconv.c | 88 - SDL2-2.0.12/test/testime.c | 801 - SDL2-2.0.12/test/testintersections.c | 363 - SDL2-2.0.12/test/testjoystick.c | 387 - SDL2-2.0.12/test/testkeys.c | 40 - SDL2-2.0.12/test/testloadso.c | 82 - SDL2-2.0.12/test/testlock.c | 128 - SDL2-2.0.12/test/testmessage.c | 193 - SDL2-2.0.12/test/testmultiaudio.c | 199 - SDL2-2.0.12/test/testnative.c | 237 - SDL2-2.0.12/test/testnative.h | 46 - SDL2-2.0.12/test/testnativecocoa.m | 51 - SDL2-2.0.12/test/testnativew32.c | 86 - SDL2-2.0.12/test/testnativex11.c | 53 - SDL2-2.0.12/test/testoffscreen.c | 170 - SDL2-2.0.12/test/testoverlay2.c | 410 - SDL2-2.0.12/test/testplatform.c | 442 - SDL2-2.0.12/test/testpower.c | 80 - SDL2-2.0.12/test/testqsort.c | 106 - SDL2-2.0.12/test/testrelative.c | 126 - SDL2-2.0.12/test/testrendercopyex.c | 225 - SDL2-2.0.12/test/testrendertarget.c | 335 - SDL2-2.0.12/test/testresample.c | 120 - SDL2-2.0.12/test/testrumble.c | 153 - SDL2-2.0.12/test/testscale.c | 216 - SDL2-2.0.12/test/testsem.c | 130 - SDL2-2.0.12/test/testsensor.c | 117 - SDL2-2.0.12/test/testshader.c | 500 - SDL2-2.0.12/test/testshape.c | 200 - SDL2-2.0.12/test/testspriteminimal.c | 194 - SDL2-2.0.12/test/teststreaming.c | 190 - SDL2-2.0.12/test/testthread.c | 130 - SDL2-2.0.12/test/testtimer.c | 122 - SDL2-2.0.12/test/testver.c | 47 - SDL2-2.0.12/test/testviewport.c | 279 - SDL2-2.0.12/test/testvulkan.c | 1189 - SDL2-2.0.12/test/testwm2.c | 163 - SDL2-2.0.12/test/testyuv.bmp | Bin 739398 -> 0 bytes SDL2-2.0.12/test/testyuv.c | 455 - SDL2-2.0.12/test/testyuv_cvt.c | 300 - SDL2-2.0.12/test/testyuv_cvt.h | 16 - SDL2-2.0.12/test/torturethread.c | 113 - SDL2-2.0.12/test/utf8.txt | 287 - ...org-kde-kwin-server-decoration-manager.xml | 94 - .../xdg-shell-unstable-v6.xml | 1044 - {SDL2-2.0.12 => SDL2-2.30.5}/Android.mk | 42 +- {SDL2-2.0.12 => SDL2-2.30.5}/BUGS.txt | 8 +- SDL2-2.30.5/CMakeLists.txt | 3717 ++ {SDL2-2.0.12 => SDL2-2.30.5}/CREDITS.txt | 0 {SDL2-2.0.12 => SDL2-2.30.5}/INSTALL.txt | 19 +- .../COPYING.txt => SDL2-2.30.5/LICENSE.txt | 38 +- {SDL2-2.0.12 => SDL2-2.30.5}/Makefile.in | 30 +- {SDL2-2.0.12 => SDL2-2.30.5}/Makefile.minimal | 29 +- SDL2-2.30.5/Makefile.os2 | 298 + {SDL2-2.0.12 => SDL2-2.30.5}/Makefile.pandora | 12 +- SDL2-2.30.5/Makefile.w32 | 283 + {SDL2-2.0.12 => SDL2-2.30.5}/README-SDL.txt | 0 .../README.txt => SDL2-2.30.5/README.md | 10 +- {SDL2-2.0.12 => SDL2-2.30.5}/SDL2.spec | 4 +- {SDL2-2.0.12 => SDL2-2.30.5}/SDL2.spec.in | 2 +- SDL2-2.30.5/SDL2Config.cmake.in | 77 + {SDL2-2.0.12 => SDL2-2.30.5}/TODO.txt | 2 +- SDL2-2.30.5/VERSION.txt | 1 + SDL2-2.30.5/VisualC-GDK/SDL.sln | 131 + SDL2-2.30.5/VisualC-GDK/SDL/SDL.vcxproj | 797 + .../VisualC-GDK/SDL/SDL.vcxproj.filters | 1392 + .../VisualC-GDK/SDLmain/SDLmain.vcxproj | 211 + .../VisualC-GDK/SDLtest/SDLtest.vcxproj | 226 + SDL2-2.30.5/VisualC-GDK/clean.sh | 7 + SDL2-2.30.5/VisualC-GDK/logos/Logo100x100.png | Bin 0 -> 10832 bytes SDL2-2.30.5/VisualC-GDK/logos/Logo150x150.png | Bin 0 -> 12709 bytes SDL2-2.30.5/VisualC-GDK/logos/Logo44x44.png | Bin 0 -> 7460 bytes SDL2-2.30.5/VisualC-GDK/logos/Logo480x480.png | Bin 0 -> 28677 bytes .../VisualC-GDK/logos/SplashScreenImage.png | Bin 10138 -> 6599 bytes .../shaders/D3D12_PixelShader_Colors.hlsl | 19 + .../shaders/D3D12_PixelShader_NV12_BT601.hlsl | 43 + .../shaders/D3D12_PixelShader_NV12_BT709.hlsl | 43 + .../shaders/D3D12_PixelShader_NV12_JPEG.hlsl | 43 + .../shaders/D3D12_PixelShader_NV21_BT601.hlsl | 43 + .../shaders/D3D12_PixelShader_NV21_BT709.hlsl | 43 + .../shaders/D3D12_PixelShader_NV21_JPEG.hlsl | 43 + .../shaders/D3D12_PixelShader_Textures.hlsl | 24 + .../shaders/D3D12_PixelShader_YUV_BT601.hlsl | 46 + .../shaders/D3D12_PixelShader_YUV_BT709.hlsl | 46 + .../shaders/D3D12_PixelShader_YUV_JPEG.hlsl | 46 + .../shaders/D3D12_VertexShader.hlsl | 95 + .../VisualC-GDK/shaders/buildshaders.bat | 35 + .../testgamecontroller/PackageLayout.xml | 9 + .../testgamecontroller.vcxproj | 444 + .../testgamecontroller.vcxproj.filters | 55 + .../wingdk/MicrosoftGame.config | 34 + .../xboxone/MicrosoftGame.config | 29 + .../xboxseries/MicrosoftGame.config | 29 + .../tests/testgdk/PackageLayout.xml | 10 + .../VisualC-GDK/tests/testgdk/src/testgdk.cpp | 399 +- .../VisualC-GDK/tests/testgdk/testgdk.vcxproj | 401 + .../tests/testgdk/testgdk.vcxproj.filters | 53 + .../tests/testgdk/wingdk/MicrosoftGame.config | 34 + .../testgdk/xboxone/MicrosoftGame.config | 29 + .../testgdk/xboxseries/MicrosoftGame.config | 29 + .../tests/testsprite2/PackageLayout.xml | 9 + .../tests/testsprite2/testsprite2.vcxproj | 395 + .../testsprite2/testsprite2.vcxproj.filters | 52 + .../testsprite2/wingdk/MicrosoftGame.config | 34 + .../testsprite2/xboxone/MicrosoftGame.config | 29 + .../xboxseries/MicrosoftGame.config | 29 + .../VisualC-WinRT}/SDL-UWP.sln | 6 + SDL2-2.30.5/VisualC-WinRT/SDL-UWP.vcxproj | 606 + .../VisualC-WinRT/SDL-UWP.vcxproj.filters | 855 + {SDL2-2.0.12 => SDL2-2.30.5}/VisualC/SDL.sln | 36 + .../VisualC/SDL/SDL.vcxproj | 124 +- SDL2-2.30.5/VisualC/SDL/SDL.vcxproj.filters | 1369 + .../VisualC/SDLmain/SDLmain.vcxproj | 5 + .../VisualC/SDLtest/SDLtest.vcxproj | 5 + {SDL2-2.0.12 => SDL2-2.30.5}/VisualC/clean.sh | 0 .../VisualC/tests/checkkeys/checkkeys.vcxproj | 13 +- .../tests/controllermap/controllermap.vcxproj | 34 +- .../VisualC/tests/loopwave/loopwave.vcxproj | 16 +- .../tests/testatomic/testatomic.vcxproj | 5 + .../testautomation/testautomation.vcxproj | 10 + .../VisualC/tests/testdraw2/testdraw2.vcxproj | 5 + .../VisualC/tests/testfile/testfile.vcxproj | 5 + .../testgamecontroller.vcxproj | 50 +- .../tests/testgesture/testgesture.vcxproj | 5 + .../VisualC/tests/testgl2/testgl2.vcxproj | 5 + .../VisualC/tests/testgles2/testgles2.vcxproj | 5 + .../tests/testjoystick/testjoystick.vcxproj | 5 + .../tests/testoverlay2/testoverlay2.vcxproj | 14 +- .../tests/testplatform/testplatform.vcxproj | 5 + .../VisualC/tests/testpower/testpower.vcxproj | 5 + .../testrendertarget/testrendertarget.vcxproj | 24 +- .../tests/testrumble/testrumble.vcxproj | 5 + .../VisualC/tests/testscale/testscale.vcxproj | 24 +- .../tests/testsensor/testsensor.vcxproj | 204 + .../VisualC/tests/testshape/testshape.vcxproj | 5 + .../tests/testsprite2/testsprite2.vcxproj | 16 +- .../tests/testsurround/testsurround.vcxproj | 210 + .../tests/testvulkan/testvulkan.vcxproj | 5 + .../VisualC/tests/testwm2/testwm2.vcxproj | 210 + .../VisualC/tests/testyuv/testyuv.vcxproj | 13 +- .../unittest/testquit/testquit_VS2012.vcxproj | 15 +- .../visualtest/visualtest_VS2012.vcxproj | 20 +- {SDL2-2.0.12 => SDL2-2.30.5}/WhatsNew.txt | 368 +- .../Xcode-iOS/Demos/Default.png | Bin .../Demos/Demos.xcodeproj/project.pbxproj | 720 +- .../Xcode-iOS/Demos/Icon.png | Bin .../Xcode-iOS/Demos/README | 0 SDL2-2.30.5/Xcode-iOS/Demos/config.xcconfig | 14 + .../Demos/data/bitmapfont/kromasky_16x16.bmp | Bin .../Demos/data/bitmapfont/license.txt | 0 .../Demos/data/drums/ds_brush_snare.wav | Bin .../Xcode-iOS/Demos/data/drums/ds_china.wav | Bin .../Demos/data/drums/ds_kick_big_amb.wav | Bin .../Demos/data/drums/ds_loose_skin_mute.wav | Bin .../Xcode-iOS/Demos/data/icon.bmp | Bin .../Xcode-iOS/Demos/data/ship.bmp | Bin .../Xcode-iOS/Demos/data/space.bmp | Bin .../Xcode-iOS/Demos/data/stroke.bmp | Bin .../Demos/iOS Launch Screen.storyboard | 0 .../Xcode-iOS/Demos/src/accelerometer.c | 12 +- .../Xcode-iOS/Demos/src/common.c | 0 .../Xcode-iOS/Demos/src/common.h | 0 .../Xcode-iOS/Demos/src/fireworks.c | 39 +- .../Xcode-iOS/Demos/src/happy.c | 4 +- .../Xcode-iOS/Demos/src/keyboard.c | 2 +- .../Xcode-iOS/Demos/src/mixer.c | 6 +- .../Xcode-iOS/Demos/src/rectangles.c | 2 +- .../Xcode-iOS/Demos/src/touch.c | 42 +- .../Xcode/SDL/Info-Framework.plist | 4 +- .../Xcode/SDL/SDL.xcodeproj/project.pbxproj | 4343 +- .../xcschemes/Framework-iOS.xcscheme | 0 .../xcschemes/xcFramework-iOS.xcscheme | 8 +- .../Xcode/SDL/SDL2}/Info.plist | 2 +- .../Xcode/SDL/pkg-support/SDL.info | 2 +- .../SDL/pkg-support/resources/License.txt | 2 +- .../SDL/pkg-support/resources/ReadMe.txt | 14 +- .../SDL/pkg-support/resources/SDL_DS_Store | Bin .../Xcode/SDL/pkg-support/sdl_logo.pdf | Bin .../SDLTest/SDLTest.xcodeproj/project.pbxproj | 2740 +- .../Xcode/SDLTest/TestDropFile-Info.plist | 2 +- SDL2-2.30.5/Xcode/SDLTest/config.xcconfig | 14 + .../Xcode/XcodeDocSet/Doxyfile | 0 .../acinclude/ac_check_define.m4 | 4 +- .../acinclude/alsa.m4 | 17 +- .../acinclude/ax_check_compiler_flags.m4 | 0 .../acinclude/ax_compute_relative_paths.m4 | 173 + .../acinclude/ax_gcc_archflag.m4 | 0 .../acinclude/ax_gcc_x86_cpuid.m4 | 0 SDL2-2.30.5/acinclude/ax_normalize_path.m4 | 115 + SDL2-2.30.5/acinclude/ax_recursive_eval.m4 | 56 + {SDL2-2.0.12 => SDL2-2.30.5}/acinclude/esd.m4 | 81 +- .../acinclude/libtool.m4 | 2731 +- .../acinclude/ltoptions.m4 | 129 +- .../acinclude/ltsugar.m4 | 7 +- .../acinclude/ltversion.m4 | 12 +- .../acinclude/lt~obsolete.m4 | 7 +- SDL2-2.30.5/acinclude/pkg.m4 | 275 + .../android-project/app/build.gradle | 24 +- .../android-project/app/jni/Android.mk | 0 .../android-project/app/jni/Application.mk | 0 .../android-project/app/jni/CMakeLists.txt | 0 .../android-project/app/jni/src/Android.mk | 2 +- .../app/jni/src/CMakeLists.txt | 0 .../android-project/app/proguard-rules.pro | 0 .../app/src/main/AndroidManifest.xml | 21 +- .../main/java/org/libsdl/app/HIDDevice.java | 0 .../app/HIDDeviceBLESteamController.java | 10 +- .../java/org/libsdl/app/HIDDeviceManager.java | 103 +- .../java/org/libsdl/app/HIDDeviceUSB.java | 6 +- .../app/src/main/java/org/libsdl/app/SDL.java | 22 +- .../main/java/org/libsdl/app/SDLActivity.java | 1425 +- .../java/org/libsdl/app/SDLAudioManager.java | 175 +- .../org/libsdl/app/SDLControllerManager.java | 282 +- .../main/java/org/libsdl/app/SDLSurface.java | 405 + .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin .../app/src/main/res/values/colors.xml | 0 .../app/src/main/res/values/strings.xml | 0 .../app/src/main/res/values/styles.xml | 5 +- .../android-project/build.gradle | 6 +- .../android-project/gradle.properties | 0 .../gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 54213 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 +- .../android-project/gradlew | 4 +- .../android-project/gradlew.bat | 0 .../android-project/settings.gradle | 0 {SDL2-2.0.12 => SDL2-2.30.5}/autogen.sh | 18 +- SDL2-2.30.5/build-scripts/android-prefab.sh | 351 + .../build-scripts/androidbuild.sh | 0 .../build-scripts/androidbuildlibs.sh | 39 +- .../build-scripts/checker-buildbot.sh | 47 +- .../build-scripts/clang++-fat.sh | 55 +- .../build-scripts/clang-fat.sh | 91 +- SDL2-2.30.5/build-scripts/clang-format-src.sh | 32 + .../build-scripts/codechecker-buildbot.sh | 59 + SDL2-2.30.5/build-scripts/config.guess | 1812 + SDL2-2.30.5/build-scripts/config.sub | 1971 + .../build-scripts/emscripten-buildbot.sh | 7 +- SDL2-2.30.5/build-scripts/fnsince.pl | 188 + .../gen_audio_channel_conversion.c | 450 + .../gen_audio_resampler_filter.c | 163 + .../build-scripts/git-pre-push-hook.pl | 80 + .../build-scripts/install-sh | 414 +- .../build-scripts/ltmain.sh | 5706 +- .../build-scripts/mkinstalldirs | 26 +- .../build-scripts/nacl-buildbot.sh | 0 .../build-scripts/naclbuild.sh | 0 .../build-scripts/raspberrypi-buildbot.sh | 6 +- SDL2-2.30.5/build-scripts/showrev.sh | 48 + .../build-scripts/strip_fPIC.sh | 0 SDL2-2.30.5/build-scripts/test-versioning.sh | 213 + SDL2-2.30.5/build-scripts/update-copyright.sh | 15 + SDL2-2.30.5/build-scripts/update-version.sh | 96 + SDL2-2.30.5/build-scripts/updaterev.sh | 49 + SDL2-2.30.5/build-scripts/wikiheaders.pl | 1656 + .../build-scripts/windows-buildbot-zipper.bat | 28 + SDL2-2.30.5/cmake/test/CMakeLists.txt | 124 + SDL2-2.30.5/cmake/test/jni/Android.mk | 11 + SDL2-2.30.5/cmake/test/main_cli.c | 14 + SDL2-2.30.5/cmake/test/main_gui.c | 28 + SDL2-2.30.5/cmake/test/main_lib.c | 33 + SDL2-2.30.5/cmake/test/test_pkgconfig.sh | 51 + SDL2-2.30.5/cmake/test/test_sdlconfig.sh | 51 + .../cmake_uninstall.cmake.in | 0 {SDL2-2.0.12 => SDL2-2.30.5}/configure | 19163 +++--- {SDL2-2.0.12 => SDL2-2.30.5}/configure.ac | 2301 +- SDL2-2.30.5/docs/CONTRIBUTING.md | 97 + .../docs/README-android.md | 157 +- SDL2-2.30.5/docs/README-cmake.md | 163 + .../docs/README-directfb.md | 52 +- .../docs/README-dynapi.md | 148 +- SDL2-2.30.5/docs/README-emscripten.md | 374 + SDL2-2.30.5/docs/README-gdk.md | 176 + .../docs/README-gesture.md | 6 +- SDL2-2.30.5/docs/README-git.md | 19 + SDL2-2.30.5/docs/README-hg.md | 4 + .../docs/README-ios.md | 147 +- SDL2-2.30.5/docs/README-kmsbsd.md | 27 + .../docs/README-linux.md | 91 +- SDL2-2.30.5/docs/README-macos.md | 285 + SDL2-2.30.5/docs/README-n3ds.md | 28 + .../docs/README-nacl.md | 52 +- SDL2-2.30.5/docs/README-ngage.md | 44 + SDL2-2.30.5/docs/README-os2.md | 92 + .../docs/README-pandora.md | 2 +- .../docs/README-platforms.md | 0 .../docs/README-porting.md | 0 SDL2-2.30.5/docs/README-ps2.md | 51 + SDL2-2.30.5/docs/README-psp.md | 36 + .../docs/README-raspberrypi.md | 98 +- SDL2-2.30.5/docs/README-riscos.md | 41 + .../docs/README-touch.md | 2 +- SDL2-2.30.5/docs/README-versions.md | 60 + SDL2-2.30.5/docs/README-visualc.md | 114 + SDL2-2.30.5/docs/README-vita.md | 33 + .../docs/README-wince.md | 0 SDL2-2.30.5/docs/README-windows.md | 58 + .../docs/README-winrt.md | 226 +- {SDL2-2.0.12 => SDL2-2.30.5}/docs/README.md | 30 +- {SDL2-2.0.12 => SDL2-2.30.5}/docs/doxyfile | 1 + SDL2-2.30.5/docs/release_checklist.md | 49 + SDL2-2.30.5/include/SDL.h | 233 + .../include/SDL_assert.h | 151 +- .../include/SDL_atomic.h | 191 +- SDL2-2.30.5/include/SDL_audio.h | 1500 + .../include/SDL_bits.h | 17 +- SDL2-2.30.5/include/SDL_blendmode.h | 198 + SDL2-2.30.5/include/SDL_clipboard.h | 141 + .../include/SDL_config.h | 12 +- .../include/SDL_config.h.in | 108 +- .../include/SDL_config_android.h | 21 +- SDL2-2.30.5/include/SDL_config_emscripten.h | 218 + .../include/SDL_config_iphoneos.h | 31 +- .../include/SDL_config_macosx.h | 37 +- .../include/SDL_config_minimal.h | 34 +- SDL2-2.30.5/include/SDL_config_ngage.h | 89 + .../include/SDL_config_os2.h | 80 +- .../include/SDL_config_pandora.h | 12 +- SDL2-2.30.5/include/SDL_config_windows.h | 333 + .../include/SDL_config_wingdk.h | 161 +- .../include/SDL_config_winrt.h | 100 +- SDL2-2.30.5/include/SDL_config_xbox.h | 240 + .../include/SDL_copying.h | 2 +- SDL2-2.30.5/include/SDL_cpuinfo.h | 594 + .../include/SDL_egl.h | 1242 +- SDL2-2.30.5/include/SDL_endian.h | 348 + SDL2-2.30.5/include/SDL_error.h | 163 + .../include/SDL_events.h | 601 +- SDL2-2.30.5/include/SDL_filesystem.h | 149 + SDL2-2.30.5/include/SDL_gamecontroller.h | 1096 + .../include/SDL_gesture.h | 42 +- SDL2-2.30.5/include/SDL_guid.h | 100 + .../include/SDL_haptic.h | 523 +- SDL2-2.30.5/include/SDL_hidapi.h | 451 + SDL2-2.30.5/include/SDL_hints.h | 2892 + SDL2-2.30.5/include/SDL_joystick.h | 1074 + SDL2-2.30.5/include/SDL_keyboard.h | 355 + .../include/SDL_keycode.h | 31 +- .../include/SDL_loadso.h | 50 +- SDL2-2.30.5/include/SDL_locale.h | 103 + SDL2-2.30.5/include/SDL_log.h | 404 + SDL2-2.30.5/include/SDL_main.h | 282 + .../include/SDL_messagebox.h | 93 +- .../include/SDL_metal.h | 60 +- SDL2-2.30.5/include/SDL_misc.h | 79 + SDL2-2.30.5/include/SDL_mouse.h | 464 + SDL2-2.30.5/include/SDL_mutex.h | 545 + .../include/SDL_name.h | 2 +- .../include/SDL_opengl.h | 53 +- .../include/SDL_opengl_glext.h | 2499 +- .../include/SDL_opengles.h | 2 +- .../include/SDL_opengles2.h | 4 +- SDL2-2.30.5/include/SDL_opengles2_gl2.h | 656 + SDL2-2.30.5/include/SDL_opengles2_gl2ext.h | 4033 ++ .../include/SDL_opengles2_gl2platform.h | 27 + .../include/SDL_opengles2_khrplatform.h | 57 +- .../include/SDL_pixels.h | 271 +- .../include/SDL_platform.h | 95 +- .../include/SDL_power.h | 36 +- .../include/SDL_quit.h | 2 +- SDL2-2.30.5/include/SDL_rect.h | 376 + SDL2-2.30.5/include/SDL_render.h | 1924 + SDL2-2.30.5/include/SDL_revision.h | 7 + SDL2-2.30.5/include/SDL_rwops.h | 841 + .../include/SDL_scancode.h | 69 +- SDL2-2.30.5/include/SDL_sensor.h | 322 + .../include/SDL_shape.h | 65 +- .../include/SDL_stdinc.h | 331 +- SDL2-2.30.5/include/SDL_surface.h | 997 + SDL2-2.30.5/include/SDL_system.h | 638 + .../include/SDL_syswm.h | 95 +- .../include/SDL_test.h | 2 +- .../include/SDL_test_assert.h | 4 +- .../include/SDL_test_common.h | 30 +- .../include/SDL_test_compare.h | 2 +- .../include/SDL_test_crc32.h | 2 +- SDL2-2.30.5/include/SDL_test_font.h | 168 + .../include/SDL_test_fuzzer.h | 54 +- .../include/SDL_test_harness.h | 12 +- .../include/SDL_test_images.h | 2 +- .../include/SDL_test_log.h | 2 +- .../include/SDL_test_md5.h | 2 +- .../include/SDL_test_memory.h | 2 +- .../include/SDL_test_random.h | 4 +- SDL2-2.30.5/include/SDL_thread.h | 464 + SDL2-2.30.5/include/SDL_timer.h | 222 + .../include/SDL_touch.h | 64 +- .../include/SDL_types.h | 2 +- SDL2-2.30.5/include/SDL_version.h | 204 + SDL2-2.30.5/include/SDL_video.h | 2184 + SDL2-2.30.5/include/SDL_vulkan.h | 215 + .../include/begin_code.h | 47 +- .../include/close_code.h | 6 +- SDL2-2.30.5/lib/x64/SDL2.dll | Bin 0 -> 2531840 bytes SDL2-2.30.5/lib/x64/SDL2.lib | Bin 0 -> 183824 bytes SDL2-2.30.5/lib/x64/SDL2main.lib | Bin 0 -> 36644 bytes SDL2-2.30.5/lib/x64/SDL2test.lib | Bin 0 -> 966202 bytes .../sdl2-config-version.cmake.in | 3 +- SDL2-2.30.5/sdl2-config.cmake.in | 222 + {SDL2-2.0.12 => SDL2-2.30.5}/sdl2-config.in | 9 +- {SDL2-2.0.12 => SDL2-2.30.5}/sdl2.m4 | 49 +- {SDL2-2.0.12 => SDL2-2.30.5}/sdl2.pc.in | 7 +- SDL2-2.30.5/src/SDL.c | 673 + {SDL2-2.0.12 => SDL2-2.30.5}/src/SDL_assert.c | 210 +- .../src/SDL_assert_c.h | 2 +- .../src/SDL_dataqueue.c | 158 +- .../src/SDL_dataqueue.h | 19 +- SDL2-2.30.5/src/SDL_error.c | 123 + SDL2-2.30.5/src/SDL_error_c.h | 44 + SDL2-2.30.5/src/SDL_guid.c | 91 + {SDL2-2.0.12 => SDL2-2.30.5}/src/SDL_hints.c | 106 +- .../src/SDL_hints_c.h | 2 +- SDL2-2.30.5/src/SDL_internal.h | 213 + SDL2-2.30.5/src/SDL_list.c | 89 + .../src/SDL_list.h | 24 +- SDL2-2.30.5/src/SDL_log.c | 611 + SDL2-2.30.5/src/SDL_log_c.h | 33 + SDL2-2.30.5/src/SDL_utils.c | 52 + SDL2-2.30.5/src/SDL_utils_c.h | 32 + .../src/atomic/SDL_atomic.c | 145 +- .../src/atomic/SDL_spinlock.c | 124 +- .../src/audio/SDL_audio.c | 938 +- .../src/audio/SDL_audio_c.h | 18 +- .../src/audio/SDL_audio_channel_converters.h | 1402 + .../src/audio/SDL_audio_resampler_filter.h | 1061 + SDL2-2.30.5/src/audio/SDL_audiocvt.c | 1429 + .../src/audio/SDL_audiodev.c | 48 +- .../src/audio/SDL_audiodev_c.h | 8 +- SDL2-2.30.5/src/audio/SDL_audiotypecvt.c | 1466 + SDL2-2.30.5/src/audio/SDL_mixer.c | 345 + .../src/audio/SDL_sysaudio.h | 68 +- .../src/audio/SDL_wave.c | 343 +- .../src/audio/SDL_wave.h | 50 +- SDL2-2.30.5/src/audio/aaudio/SDL_aaudio.c | 530 + SDL2-2.30.5/src/audio/aaudio/SDL_aaudio.h | 50 + .../src/audio/aaudio/SDL_aaudiofuncs.h | 79 + SDL2-2.30.5/src/audio/alsa/SDL_alsa_audio.c | 991 + .../src/audio/alsa/SDL_alsa_audio.h | 4 +- .../src/audio/android/SDL_androidaudio.c | 117 +- .../src/audio/android/SDL_androidaudio.h | 7 +- .../src/audio/arts/SDL_artsaudio.c | 87 +- .../src/audio/arts/SDL_artsaudio.h | 2 +- .../src/audio/coreaudio/SDL_coreaudio.h | 22 +- .../src/audio/coreaudio/SDL_coreaudio.m | 1314 + .../src/audio/directsound/SDL_directsound.c | 301 +- .../src/audio/directsound/SDL_directsound.h | 4 +- .../src/audio/disk/SDL_diskaudio.c | 128 +- .../src/audio/disk/SDL_diskaudio.h | 4 +- .../src/audio/dsp/SDL_dspaudio.c | 98 +- .../src/audio/dsp/SDL_dspaudio.h | 6 +- .../src/audio/dummy/SDL_dummyaudio.c | 31 +- .../src/audio/dummy/SDL_dummyaudio.h | 4 +- .../audio/emscripten/SDL_emscriptenaudio.c | 177 +- .../audio/emscripten/SDL_emscriptenaudio.h | 4 +- .../src/audio/esd/SDL_esdaudio.c | 63 +- .../src/audio/esd/SDL_esdaudio.h | 2 +- .../src/audio/fusionsound/SDL_fsaudio.c | 85 +- .../src/audio/fusionsound/SDL_fsaudio.h | 2 +- .../src/audio/haiku/SDL_haikuaudio.cc | 98 +- .../src/audio/haiku/SDL_haikuaudio.h | 4 +- .../src/audio/jack/SDL_jackaudio.c | 185 +- .../src/audio/jack/SDL_jackaudio.h | 2 +- SDL2-2.30.5/src/audio/n3ds/SDL_n3dsaudio.c | 337 + SDL2-2.30.5/src/audio/n3ds/SDL_n3dsaudio.h | 50 + .../src/audio/nacl/SDL_naclaudio.c | 102 +- .../src/audio/nacl/SDL_naclaudio.h | 5 +- .../src/audio/nas/SDL_nasaudio.c | 152 +- .../src/audio/nas/SDL_nasaudio.h | 2 +- .../src/audio/netbsd/SDL_netbsdaudio.c | 189 +- .../src/audio/netbsd/SDL_netbsdaudio.h | 6 +- .../src/audio/openslES/SDL_openslES.c | 281 +- .../src/audio/openslES/SDL_openslES.h | 12 +- SDL2-2.30.5/src/audio/os2/SDL_os2audio.c | 601 + SDL2-2.30.5/src/audio/os2/SDL_os2audio.h | 55 + .../src/audio/paudio/SDL_paudio.c | 121 +- .../src/audio/paudio/SDL_paudio.h | 2 +- SDL2-2.30.5/src/audio/pipewire/SDL_pipewire.c | 1387 + SDL2-2.30.5/src/audio/pipewire/SDL_pipewire.h | 47 + SDL2-2.30.5/src/audio/ps2/SDL_ps2audio.c | 177 + SDL2-2.30.5/src/audio/ps2/SDL_ps2audio.h | 46 + .../src/audio/psp/SDL_pspaudio.c | 128 +- .../src/audio/psp/SDL_pspaudio.h | 15 +- .../src/audio/pulseaudio/SDL_pulseaudio.c | 996 + .../src/audio/pulseaudio/SDL_pulseaudio.h | 8 +- .../src/audio/qsa/SDL_qsa_audio.c | 172 +- .../src/audio/qsa/SDL_qsa_audio.h | 5 +- .../src/audio/sndio/SDL_sndioaudio.c | 147 +- .../src/audio/sndio/SDL_sndioaudio.h | 4 +- .../src/audio/sun/SDL_sunaudio.c | 55 +- .../src/audio/sun/SDL_sunaudio.h | 2 +- SDL2-2.30.5/src/audio/vita/SDL_vitaaudio.c | 221 + SDL2-2.30.5/src/audio/vita/SDL_vitaaudio.h | 46 + .../src/audio/wasapi/SDL_wasapi.c | 433 +- .../src/audio/wasapi/SDL_wasapi.h | 11 +- .../src/audio/wasapi/SDL_wasapi_win32.c | 153 + .../src/audio/wasapi/SDL_wasapi_winrt.cpp | 431 + .../src/audio/winmm/SDL_winmm.c | 105 +- .../src/audio/winmm/SDL_winmm.h | 2 +- .../src/core/android/SDL_android.c | 1382 +- .../src/core/android/SDL_android.h | 31 +- .../freebsd/SDL_evdev_kbd_default_keyaccmap.h | 167 + .../src/core/freebsd/SDL_evdev_kbd_freebsd.c | 613 + SDL2-2.30.5/src/core/gdk/SDL_gdk.cpp | 262 + SDL2-2.30.5/src/core/gdk/SDL_gdk.h | 24 + SDL2-2.30.5/src/core/linux/SDL_dbus.c | 603 + .../src/core/linux/SDL_dbus.h | 29 +- .../src/core/linux/SDL_evdev.c | 477 +- .../src/core/linux/SDL_evdev.h | 5 +- .../src/core/linux/SDL_evdev_capabilities.c | 150 + .../src/core/linux/SDL_evdev_capabilities.h | 59 + .../src/core/linux/SDL_evdev_kbd.c | 543 +- .../src/core/linux/SDL_evdev_kbd.h | 5 +- .../linux/SDL_evdev_kbd_default_accents.h | 2 +- .../core/linux/SDL_evdev_kbd_default_keymap.h | 8 +- SDL2-2.30.5/src/core/linux/SDL_fcitx.c | 491 + .../src/core/linux/SDL_fcitx.h | 6 +- SDL2-2.30.5/src/core/linux/SDL_ibus.c | 765 + .../src/core/linux/SDL_ibus.h | 12 +- .../src/core/linux/SDL_ime.c | 68 +- .../src/core/linux/SDL_ime.h | 6 +- SDL2-2.30.5/src/core/linux/SDL_sandbox.c | 47 + SDL2-2.30.5/src/core/linux/SDL_sandbox.h | 39 + SDL2-2.30.5/src/core/linux/SDL_threadprio.c | 352 + .../src/core/linux/SDL_udev.c | 379 +- .../src/core/linux/SDL_udev.h | 31 +- SDL2-2.30.5/src/core/openbsd/SDL_wscons.h | 25 + SDL2-2.30.5/src/core/openbsd/SDL_wscons_kbd.c | 933 + .../src/core/openbsd/SDL_wscons_mouse.c | 134 + SDL2-2.30.5/src/core/os2/SDL_os2.c | 38 + SDL2-2.30.5/src/core/os2/SDL_os2.h | 57 + SDL2-2.30.5/src/core/os2/geniconv/geniconv.c | 161 + SDL2-2.30.5/src/core/os2/geniconv/geniconv.h | 85 + SDL2-2.30.5/src/core/os2/geniconv/iconv.h | 21 + SDL2-2.30.5/src/core/os2/geniconv/os2cp.c | 416 + SDL2-2.30.5/src/core/os2/geniconv/os2cp.h | 32 + SDL2-2.30.5/src/core/os2/geniconv/os2iconv.c | 286 + SDL2-2.30.5/src/core/os2/geniconv/sys2utf8.c | 119 + SDL2-2.30.5/src/core/os2/geniconv/test.c | 69 + SDL2-2.30.5/src/core/os2/iconv2.lbc | 4 + .../src/core/unix/SDL_poll.c | 35 +- .../src/core/unix/SDL_poll.h | 7 +- .../src/core/windows/SDL_directx.h | 35 +- SDL2-2.30.5/src/core/windows/SDL_hid.c | 86 + SDL2-2.30.5/src/core/windows/SDL_hid.h | 215 + SDL2-2.30.5/src/core/windows/SDL_immdevice.c | 543 + SDL2-2.30.5/src/core/windows/SDL_immdevice.h | 44 + SDL2-2.30.5/src/core/windows/SDL_windows.c | 386 + SDL2-2.30.5/src/core/windows/SDL_windows.h | 169 + .../src/core/windows/SDL_xinput.c | 61 +- SDL2-2.30.5/src/core/windows/SDL_xinput.h | 278 + .../src/core/winrt/SDL_winrtapp_common.cpp | 20 +- .../src/core/winrt/SDL_winrtapp_common.h | 2 +- .../src/core/winrt/SDL_winrtapp_direct3d.cpp | 411 +- .../src/core/winrt/SDL_winrtapp_direct3d.h | 93 + .../src/core/winrt/SDL_winrtapp_xaml.cpp | 49 +- .../src/core/winrt/SDL_winrtapp_xaml.h | 4 +- .../src/cpuinfo/SDL_cpuinfo.c | 873 +- SDL2-2.30.5/src/dynapi/SDL2.exports | 874 + SDL2-2.30.5/src/dynapi/SDL_dynapi.c | 525 + .../src/dynapi/SDL_dynapi.h | 24 +- .../src/dynapi/SDL_dynapi_overrides.h | 157 +- .../src/dynapi/SDL_dynapi_procs.h | 208 +- .../src/dynapi/gendynapi.pl | 27 +- .../src/events/SDL_clipboardevents.c | 8 +- .../src/events/SDL_clipboardevents_c.h | 2 +- .../src/events/SDL_displayevents.c | 8 +- .../src/events/SDL_displayevents_c.h | 2 +- .../src/events/SDL_dropevents.c | 18 +- .../src/events/SDL_dropevents_c.h | 2 +- SDL2-2.30.5/src/events/SDL_events.c | 1444 + .../src/events/SDL_events_c.h | 5 +- .../src/events/SDL_gesture.c | 323 +- .../src/events/SDL_gesture_c.h | 4 +- SDL2-2.30.5/src/events/SDL_keyboard.c | 1303 + .../src/events/SDL_keyboard_c.h | 35 +- .../src/events/SDL_keysym_to_scancode.c | 440 + .../src/events/SDL_keysym_to_scancode_c.h | 32 + .../src/events/SDL_mouse.c | 833 +- .../src/events/SDL_mouse_c.h | 78 +- .../src/events/SDL_quit.c | 81 +- SDL2-2.30.5/src/events/SDL_scancode_tables.c | 73 + .../src/events/SDL_scancode_tables_c.h | 37 + .../src/events/SDL_touch.c | 146 +- .../src/events/SDL_touch_c.h | 10 +- .../src/events/SDL_windowevents.c | 55 +- .../src/events/SDL_windowevents_c.h | 4 +- .../src/events/blank_cursor.h | 10 +- .../src/events/default_cursor.h | 5 +- .../src/events}/imKStoUCS.c | 7 +- .../src/events}/imKStoUCS.h | 2 +- SDL2-2.30.5/src/events/scancodes_ascii.h | 170 + .../src/events/scancodes_darwin.h | 8 +- SDL2-2.30.5/src/events/scancodes_linux.h | 850 + .../src/events/scancodes_windows.h | 8 +- SDL2-2.30.5/src/events/scancodes_xfree86.h | 523 + .../src/file/SDL_rwops.c | 371 +- .../src/file/cocoa/SDL_rwopsbundlesupport.h | 4 +- .../src/file/cocoa/SDL_rwopsbundlesupport.m | 49 +- SDL2-2.30.5/src/file/n3ds/SDL_rwopsromfs.c | 92 + SDL2-2.30.5/src/file/n3ds/SDL_rwopsromfs.h | 30 + .../filesystem/android/SDL_sysfilesystem.c | 10 +- .../src/filesystem/cocoa/SDL_sysfilesystem.m | 139 + .../src/filesystem/dummy/SDL_sysfilesystem.c | 8 +- .../filesystem/emscripten/SDL_sysfilesystem.c | 22 +- .../src/filesystem/gdk/SDL_sysfilesystem.cpp | 138 + .../src/filesystem/haiku/SDL_sysfilesystem.cc | 9 +- .../src/filesystem/n3ds/SDL_sysfilesystem.c | 89 + .../src/filesystem/nacl/SDL_sysfilesystem.c | 8 +- .../src/filesystem/os2/SDL_sysfilesystem.c | 129 + .../src/filesystem/ps2/SDL_sysfilesystem.c | 110 + .../src/filesystem/psp/SDL_sysfilesystem.c | 77 + .../src/filesystem/riscos/SDL_sysfilesystem.c | 208 + .../src/filesystem/unix/SDL_sysfilesystem.c | 199 +- .../src/filesystem/vita/SDL_sysfilesystem.c | 93 + .../filesystem/windows/SDL_sysfilesystem.c | 71 +- .../filesystem/winrt/SDL_sysfilesystem.cpp | 93 +- .../src/haptic/SDL_haptic.c | 311 +- .../src/haptic/SDL_haptic_c.h | 2 +- .../src/haptic/SDL_syshaptic.h | 75 +- .../src/haptic/android/SDL_syshaptic.c | 169 +- .../src/haptic/android/SDL_syshaptic_c.h | 0 .../src/haptic/darwin/SDL_syshaptic.c | 359 +- .../src/haptic/darwin/SDL_syshaptic_c.h | 31 + .../src/haptic/dummy/SDL_syshaptic.c | 95 +- .../src/haptic/linux/SDL_syshaptic.c | 396 +- .../src/haptic/windows/SDL_dinputhaptic.c | 463 +- .../src/haptic/windows/SDL_dinputhaptic_c.h | 56 + .../src/haptic/windows/SDL_windowshaptic.c | 131 +- .../src/haptic/windows/SDL_windowshaptic_c.h | 38 +- .../src/haptic/windows/SDL_xinputhaptic.c | 187 +- .../src/haptic/windows/SDL_xinputhaptic_c.h | 56 + .../src/hidapi/AUTHORS.txt | 0 .../src/hidapi/HACKING.txt | 0 .../src/hidapi/LICENSE-bsd.txt | 0 .../src/hidapi/LICENSE-gpl3.txt | 0 .../src/hidapi/LICENSE-orig.txt | 0 .../src/hidapi/LICENSE.txt | 0 .../src/hidapi/Makefile.am | 0 .../src/hidapi/README.txt | 0 SDL2-2.30.5/src/hidapi/SDL_hidapi.c | 1693 + SDL2-2.30.5/src/hidapi/SDL_hidapi_c.h | 35 + .../src/hidapi/android/hid.cpp | 368 +- .../src/hidapi/android/jni/Android.mk | 0 .../src/hidapi/android/jni/Application.mk | 0 .../src/hidapi/android/project.properties | 0 .../src/hidapi/bootstrap | 0 .../src/hidapi/configure.ac | 0 .../src/hidapi/doxygen/Doxyfile | 0 .../src/hidapi/hidapi/hidapi.h | 73 +- .../src/hidapi/hidtest/Makefile.am | 0 .../src/hidapi/hidtest/hidtest.cpp | 0 .../src/hidapi/ios/Makefile-manual | 0 .../src/hidapi/ios/Makefile.am | 0 .../src/hidapi/ios/hid.m | 200 +- .../src/hidapi/libusb/Makefile-manual | 0 .../src/hidapi/libusb/Makefile.am | 0 .../src/hidapi/libusb/Makefile.freebsd | 0 .../src/hidapi/libusb/Makefile.linux | 0 .../src/hidapi/libusb/hid.c | 423 +- .../src/hidapi/libusb/hidusb.cpp | 0 .../src/hidapi/linux/Makefile-manual | 0 .../src/hidapi/linux/Makefile.am | 0 .../src/hidapi/linux/README.txt | 2 +- .../src/hidapi/linux/hid.c | 137 +- .../src/hidapi/linux/hidraw.cpp | 0 .../src/hidapi/m4/ax_pthread.m4 | 0 .../src/hidapi/m4/pkg.m4 | 0 .../src/hidapi/mac/Makefile-manual | 0 .../src/hidapi/mac/Makefile.am | 0 .../src/hidapi/mac/hid.c | 202 +- .../src/hidapi/pc/hidapi-hidraw.pc.in | 0 .../src/hidapi/pc/hidapi-libusb.pc.in | 0 .../src/hidapi/pc/hidapi.pc.in | 0 .../src/hidapi/testgui/Makefile-manual | 0 .../src/hidapi/testgui/Makefile.am | 0 .../src/hidapi/testgui/Makefile.freebsd | 0 .../src/hidapi/testgui/Makefile.linux | 0 .../src/hidapi/testgui/Makefile.mac | 0 .../src/hidapi/testgui/Makefile.mingw | 0 .../TestGUI.app.in/Contents/Info.plist | 0 .../testgui/TestGUI.app.in/Contents/PkgInfo | 0 .../Resources/English.lproj/InfoPlist.strings | Bin .../Contents/Resources/Signal11.icns | Bin .../src/hidapi/testgui/copy_to_bundle.sh | 0 .../src/hidapi/testgui/mac_support.cpp | 0 .../src/hidapi/testgui/mac_support.h | 0 .../src/hidapi/testgui/mac_support_cocoa.m | 0 .../src/hidapi/testgui/start.sh | 0 .../src/hidapi/testgui/test.cpp | 0 .../src/hidapi/testgui/testgui.sln | 0 .../src/hidapi/testgui/testgui.vcproj | 0 .../src/hidapi/udev/99-hid.rules | 0 .../src/hidapi/windows/Makefile-manual | 0 .../src/hidapi/windows/Makefile.am | 0 .../src/hidapi/windows/Makefile.mingw | 0 .../src/hidapi/windows/ddk_build/hidapi.def | 0 .../src/hidapi/windows/ddk_build/sources | 0 .../src/hidapi/windows/hid.c | 293 +- .../src/hidapi/windows/hidapi.sln | 0 .../src/hidapi/windows/hidapi.vcproj | 0 .../src/hidapi/windows/hidtest.vcproj | 0 SDL2-2.30.5/src/joystick/SDL_gamecontroller.c | 3276 + .../src/joystick/SDL_gamecontrollerdb.h | 564 +- SDL2-2.30.5/src/joystick/SDL_joystick.c | 3577 ++ SDL2-2.30.5/src/joystick/SDL_joystick_c.h | 275 + .../src/joystick/SDL_steam_virtual_gamepad.c | 251 + .../src/joystick/SDL_steam_virtual_gamepad.h | 36 + SDL2-2.30.5/src/joystick/SDL_sysjoystick.h | 264 + .../src/joystick/android/SDL_sysjoystick.c | 528 +- .../src/joystick/android/SDL_sysjoystick_c.h | 8 +- .../src/joystick/bsd/SDL_bsdjoystick.c | 898 + SDL2-2.30.5/src/joystick/check_8bitdo.sh | 15 + .../src/joystick/controller_list.h | 353 +- SDL2-2.30.5/src/joystick/controller_type.c | 144 + SDL2-2.30.5/src/joystick/controller_type.h | 80 + .../src/joystick/darwin/SDL_iokitjoystick.c | 562 +- .../src/joystick/darwin/SDL_iokitjoystick_c.h | 37 +- .../src/joystick/dummy/SDL_sysjoystick.c | 159 + .../src/joystick/emscripten/SDL_sysjoystick.c | 177 +- .../joystick/emscripten/SDL_sysjoystick_c.h | 27 +- .../src/joystick/haiku/SDL_haikujoystick.cc | 92 +- .../src/joystick/hidapi/SDL_hidapi_combined.c | 238 + .../src/joystick/hidapi/SDL_hidapi_gamecube.c | 559 + .../src/joystick/hidapi/SDL_hidapi_luna.c | 451 + .../src/joystick/hidapi/SDL_hidapi_nintendo.h | 51 + .../src/joystick/hidapi/SDL_hidapi_ps3.c | 1001 + .../src/joystick/hidapi/SDL_hidapi_ps4.c | 1290 + .../src/joystick/hidapi/SDL_hidapi_ps5.c | 1578 + .../src/joystick/hidapi/SDL_hidapi_rumble.c | 114 +- .../src/joystick/hidapi/SDL_hidapi_rumble.h | 13 +- .../src/joystick/hidapi/SDL_hidapi_shield.c | 603 + .../src/joystick/hidapi/SDL_hidapi_stadia.c | 339 + .../src/joystick/hidapi/SDL_hidapi_steam.c | 1243 + .../joystick/hidapi/SDL_hidapi_steamdeck.c | 425 + .../src/joystick/hidapi/SDL_hidapi_switch.c | 2419 + .../src/joystick/hidapi/SDL_hidapi_wii.c | 1685 + .../src/joystick/hidapi/SDL_hidapi_xbox360.c | 391 + .../src/joystick/hidapi/SDL_hidapi_xbox360w.c | 236 +- .../src/joystick/hidapi/SDL_hidapi_xboxone.c | 1357 + .../src/joystick/hidapi/SDL_hidapijoystick.c | 1684 + .../joystick/hidapi/SDL_hidapijoystick_c.h | 181 + .../hidapi/steam/controller_constants.h | 114 +- .../hidapi/steam/controller_structs.h | 226 +- .../src/joystick/iphoneos/SDL_mfijoystick.m | 2215 + .../src/joystick/iphoneos/SDL_mfijoystick_c.h | 32 +- .../src/joystick/linux/SDL_sysjoystick.c | 2814 + .../src/joystick/linux/SDL_sysjoystick_c.h | 51 +- .../src/joystick/n3ds/SDL_sysjoystick.c | 302 + .../src/joystick/os2/SDL_os2joystick.c | 843 + .../src/joystick/ps2/SDL_sysjoystick.c | 372 + .../src/joystick/psp/SDL_sysjoystick.c | 289 + SDL2-2.30.5/src/joystick/sort_controllers.py | 153 + .../src/joystick/steam/SDL_steamcontroller.c | 3 +- .../src/joystick/steam/SDL_steamcontroller.h | 2 +- SDL2-2.30.5/src/joystick/usb_ids.h | 179 + .../joystick/virtual/SDL_virtualjoystick.c | 750 + .../joystick/virtual/SDL_virtualjoystick_c.h | 60 + .../src/joystick/vita/SDL_sysjoystick.c | 409 + .../src/joystick/windows/SDL_dinputjoystick.c | 943 +- .../joystick/windows/SDL_dinputjoystick_c.h | 22 +- .../joystick/windows/SDL_rawinputjoystick.c | 2217 + .../joystick/windows/SDL_rawinputjoystick_c.h | 19 +- .../windows/SDL_windows_gaming_input.c | 1078 + .../joystick/windows/SDL_windowsjoystick.c | 850 + .../joystick/windows/SDL_windowsjoystick_c.h | 26 +- .../src/joystick/windows/SDL_xinputjoystick.c | 339 +- .../joystick/windows/SDL_xinputjoystick_c.h | 22 +- .../src/libm/e_atan2.c | 0 {SDL2-2.0.12 => SDL2-2.30.5}/src/libm/e_exp.c | 0 .../src/libm/e_fmod.c | 0 {SDL2-2.0.12 => SDL2-2.30.5}/src/libm/e_log.c | 0 .../src/libm/e_log10.c | 0 {SDL2-2.0.12 => SDL2-2.30.5}/src/libm/e_pow.c | 0 .../src/libm/e_rem_pio2.c | 0 .../src/libm/e_sqrt.c | 0 {SDL2-2.0.12 => SDL2-2.30.5}/src/libm/k_cos.c | 0 .../src/libm/k_rem_pio2.c | 12 +- {SDL2-2.0.12 => SDL2-2.30.5}/src/libm/k_sin.c | 0 {SDL2-2.0.12 => SDL2-2.30.5}/src/libm/k_tan.c | 0 .../src/libm/math_libm.h | 2 +- .../src/libm/math_private.h | 5 +- .../src/libm/s_atan.c | 0 .../src/libm/s_copysign.c | 0 {SDL2-2.0.12 => SDL2-2.30.5}/src/libm/s_cos.c | 0 .../src/libm/s_fabs.c | 0 .../src/libm/s_floor.c | 0 .../src/libm/s_scalbn.c | 0 {SDL2-2.0.12 => SDL2-2.30.5}/src/libm/s_sin.c | 0 {SDL2-2.0.12 => SDL2-2.30.5}/src/libm/s_tan.c | 0 .../src/loadso/dlopen/SDL_sysloadso.c | 39 +- .../src/loadso/dummy/SDL_sysloadso.c | 15 +- SDL2-2.30.5/src/loadso/os2/SDL_sysloadso.c | 100 + .../src/loadso/windows/SDL_sysloadso.c | 36 +- SDL2-2.30.5/src/locale/SDL_locale.c | 103 + SDL2-2.30.5/src/locale/SDL_syslocale.h | 37 + .../src/locale/android/SDL_syslocale.c | 31 + SDL2-2.30.5/src/locale/dummy/SDL_syslocale.c | 31 + .../src/locale/emscripten/SDL_syslocale.c | 72 + SDL2-2.30.5/src/locale/haiku/SDL_syslocale.cc | 76 + SDL2-2.30.5/src/locale/macosx/SDL_syslocale.m | 77 + SDL2-2.30.5/src/locale/n3ds/SDL_syslocale.c | 57 + SDL2-2.30.5/src/locale/unix/SDL_syslocale.c | 105 + SDL2-2.30.5/src/locale/vita/SDL_syslocale.c | 70 + .../src/locale/windows/SDL_syslocale.c | 112 + SDL2-2.30.5/src/locale/winrt/SDL_syslocale.c | 55 + .../src/main/android/SDL_android_main.c | 0 .../src/main/dummy/SDL_dummy_main.c | 11 +- SDL2-2.30.5/src/main/gdk/SDL_gdk_main.c | 41 + .../src/main/haiku/SDL_BApp.h | 234 +- .../src/main/haiku/SDL_BeApp.cc | 120 +- .../src/main/haiku/SDL_BeApp.h | 4 +- SDL2-2.30.5/src/main/n3ds/SDL_n3ds_main.c | 61 + .../src/main/nacl/SDL_nacl_main.c | 25 +- SDL2-2.30.5/src/main/ngage/SDL_ngage_main.cpp | 79 + SDL2-2.30.5/src/main/ps2/SDL_ps2_main.c | 74 + .../src/main/psp/SDL_psp_main.c | 26 +- SDL2-2.30.5/src/main/uikit/SDL_uikit_main.c | 23 + .../src/main/windows/SDL_windows_main.c | 52 +- .../src/main/windows/version.rc | 12 +- .../winrt/SDL2-WinRTResource_BlankCursor.cur | Bin .../src/main/winrt/SDL2-WinRTResources.rc | 0 .../src/main/winrt/SDL_winrt_main_NonXAML.cpp | 2 +- SDL2-2.30.5/src/misc/SDL_sysurl.h | 36 + SDL2-2.30.5/src/misc/SDL_url.c | 32 + .../src/misc/android/SDL_sysurl.c | 12 +- SDL2-2.30.5/src/misc/dummy/SDL_sysurl.c | 29 + SDL2-2.30.5/src/misc/emscripten/SDL_sysurl.c | 34 + SDL2-2.30.5/src/misc/haiku/SDL_sysurl.cc | 33 + SDL2-2.30.5/src/misc/ios/SDL_sysurl.m | 36 + SDL2-2.30.5/src/misc/macosx/SDL_sysurl.m | 36 + SDL2-2.30.5/src/misc/riscos/SDL_sysurl.c | 47 + SDL2-2.30.5/src/misc/unix/SDL_sysurl.c | 82 + SDL2-2.30.5/src/misc/vita/SDL_sysurl.c | 42 + SDL2-2.30.5/src/misc/windows/SDL_sysurl.c | 60 + SDL2-2.30.5/src/misc/winrt/SDL_sysurl.cpp | 39 + .../src/power/SDL_power.c | 39 +- .../src/power/SDL_syspower.h | 4 +- .../src/power/android/SDL_syspower.c | 7 +- .../src/power/emscripten/SDL_syspower.c | 10 +- .../src/power/haiku/SDL_syspower.c | 41 +- .../src/power/linux/SDL_syspower.c | 312 +- .../src/power/macosx/SDL_syspower.c | 43 +- SDL2-2.30.5/src/power/n3ds/SDL_syspower.c | 108 + .../src/power/psp/SDL_syspower.c | 18 +- .../src/power/uikit/SDL_syspower.h | 6 +- .../src/power/uikit/SDL_syspower.m | 20 +- SDL2-2.30.5/src/power/vita/SDL_syspower.c | 64 + .../src/power/windows/SDL_syspower.c | 26 +- .../src/power/winrt/SDL_syspower.cpp | 5 +- .../src/render/SDL_d3dmath.c | 7 +- .../src/render/SDL_d3dmath.h | 23 +- SDL2-2.30.5/src/render/SDL_render.c | 4535 ++ SDL2-2.30.5/src/render/SDL_sysrender.h | 334 + .../src/render/SDL_yuv_sw.c | 257 +- .../src/render/SDL_yuv_sw_c.h | 24 +- .../src/render/direct3d/SDL_render_d3d.c | 988 +- .../src/render/direct3d/SDL_shaders_d3d.c | 7 +- .../src/render/direct3d/SDL_shaders_d3d.h | 5 +- .../src/render/direct3d11/SDL_render_d3d11.c | 1532 +- .../render/direct3d11/SDL_render_winrt.cpp | 18 +- .../src/render/direct3d11/SDL_render_winrt.h | 8 +- .../src/render/direct3d11/SDL_shaders_d3d11.c | 53 +- .../src/render/direct3d11/SDL_shaders_d3d11.h | 7 +- .../src/render/direct3d12/SDL_render_d3d12.c | 3144 + .../direct3d12/SDL_render_d3d12_xbox.cpp | 174 + .../render/direct3d12/SDL_render_d3d12_xbox.h | 52 +- .../src/render/direct3d12/SDL_shaders_d3d12.c | 6939 ++ .../src/render/direct3d12/SDL_shaders_d3d12.h | 69 + .../direct3d12/SDL_shaders_d3d12_xboxone.cpp | 144 + .../SDL_shaders_d3d12_xboxseries.cpp | 144 + .../src/render/metal/SDL_render_metal.m | 1106 +- .../src/render/metal/SDL_shaders_metal.metal | 25 +- .../src/render/metal/SDL_shaders_metal_ios.h | 1821 + .../metal/SDL_shaders_metal_iphonesimulator.h | 2058 + .../src/render/metal/SDL_shaders_metal_osx.h | 1825 + .../src/render/metal/SDL_shaders_metal_tvos.h | 1821 + .../metal/SDL_shaders_metal_tvsimulator.h | 2060 + .../src/render/metal/build-metal-shaders.sh | 4 +- .../src/render/opengl/SDL_glfuncs.h | 308 +- .../src/render/opengl/SDL_render_gl.c | 1350 +- .../src/render/opengl/SDL_shaders_gl.c | 138 +- .../src/render/opengl/SDL_shaders_gl.h | 15 +- .../src/render/opengles/SDL_glesfuncs.h | 11 +- .../src/render/opengles/SDL_render_gles.c | 781 +- .../src/render/opengles2/SDL_gles2funcs.h | 9 +- .../src/render/opengles2/SDL_render_gles2.c | 1648 +- .../src/render/opengles2/SDL_shaders_gles2.c | 449 + .../src/render/opengles2/SDL_shaders_gles2.h | 73 + SDL2-2.30.5/src/render/ps2/SDL_render_ps2.c | 712 + SDL2-2.30.5/src/render/psp/SDL_render_psp.c | 1427 + .../src/render/software/SDL_blendfillrect.c | 53 +- .../src/render/software/SDL_blendfillrect.h | 7 +- .../src/render/software/SDL_blendline.c | 89 +- .../src/render/software/SDL_blendline.h | 7 +- .../src/render/software/SDL_blendpoint.c | 51 +- .../src/render/software/SDL_blendpoint.h | 7 +- SDL2-2.30.5/src/render/software/SDL_draw.h | 661 + .../src/render/software/SDL_drawline.c | 63 +- .../src/render/software/SDL_drawline.h | 7 +- .../src/render/software/SDL_drawpoint.c | 19 +- .../src/render/software/SDL_drawpoint.h | 7 +- .../src/render/software/SDL_render_sw.c | 638 +- .../src/render/software/SDL_render_sw_c.h | 4 +- .../src/render/software/SDL_rotate.c | 420 +- .../src/render/software/SDL_rotate.h | 12 +- .../src/render/software/SDL_triangle.c | 940 + .../src/render/software/SDL_triangle.h | 42 + .../src/render/vitagxm/SDL_render_vita_gxm.c | 1230 + .../vitagxm/SDL_render_vita_gxm_memory.c | 179 + .../vitagxm/SDL_render_vita_gxm_memory.h | 44 + .../vitagxm/SDL_render_vita_gxm_shaders.h | 284 + .../vitagxm/SDL_render_vita_gxm_tools.c | 1217 + .../vitagxm/SDL_render_vita_gxm_tools.h | 66 + .../vitagxm/SDL_render_vita_gxm_types.h | 214 + .../src/render/vitagxm/shader_src/clear_f.cg | 4 + .../src/render/vitagxm/shader_src/clear_v.cg | 4 + .../src/render/vitagxm/shader_src/color_f.cg | 4 + .../src/render/vitagxm/shader_src/color_v.cg | 13 + .../render/vitagxm/shader_src/texture_f.cg | 4 + .../render/vitagxm/shader_src/texture_v.cg | 14 + .../src/sensor/SDL_sensor.c | 147 +- .../src/sensor/SDL_sensor_c.h | 4 +- .../src/sensor/SDL_syssensor.h | 30 +- .../src/sensor/android/SDL_androidsensor.c | 66 +- .../src/sensor/android/SDL_androidsensor.h | 3 +- .../sensor/coremotion/SDL_coremotionsensor.h | 3 +- .../sensor/coremotion/SDL_coremotionsensor.m | 99 +- .../src/sensor/dummy/SDL_dummysensor.c | 41 +- .../src/sensor/dummy/SDL_dummysensor.h | 2 +- SDL2-2.30.5/src/sensor/n3ds/SDL_n3dssensor.c | 207 + SDL2-2.30.5/src/sensor/vita/SDL_vitasensor.c | 212 + SDL2-2.30.5/src/sensor/vita/SDL_vitasensor.h | 31 + .../src/sensor/windows/SDL_windowssensor.c | 478 + .../src/sensor/windows/SDL_windowssensor.h | 23 + SDL2-2.30.5/src/stdlib/SDL_crc16.c | 57 + SDL2-2.30.5/src/stdlib/SDL_crc32.c | 55 + .../src/stdlib/SDL_getenv.c | 101 +- SDL2-2.30.5/src/stdlib/SDL_iconv.c | 861 + .../src/stdlib/SDL_malloc.c | 4190 +- .../src/stdlib/SDL_mslibc.c | 554 +- .../src/stdlib/SDL_qsort.c | 90 +- SDL2-2.30.5/src/stdlib/SDL_stdlib.c | 633 + .../src/stdlib/SDL_string.c | 1245 +- .../src/stdlib/SDL_strtokr.c | 7 +- SDL2-2.30.5/src/stdlib/SDL_vacopy.h | 36 + .../src/test/SDL_test_assert.c | 32 +- .../src/test/SDL_test_common.c | 1132 +- SDL2-2.30.5/src/test/SDL_test_compare.c | 140 + SDL2-2.30.5/src/test/SDL_test_crc32.c | 165 + SDL2-2.30.5/src/test/SDL_test_font.c | 3495 + .../src/test/SDL_test_fuzzer.c | 286 +- .../src/test/SDL_test_harness.c | 331 +- SDL2-2.30.5/src/test/SDL_test_imageBlit.c | 1666 + .../src/test/SDL_test_imageBlitBlend.c | 2947 + SDL2-2.30.5/src/test/SDL_test_imageFace.c | 238 + .../src/test/SDL_test_imagePrimitives.c | 519 + .../src/test/SDL_test_imagePrimitivesBlend.c | 692 + .../src/test/SDL_test_log.c | 20 +- SDL2-2.30.5/src/test/SDL_test_md5.c | 347 + .../src/test/SDL_test_memory.c | 41 +- SDL2-2.30.5/src/test/SDL_test_random.c | 104 + .../src/thread/SDL_systhread.h | 22 +- .../src/thread/SDL_thread.c | 232 +- .../src/thread/SDL_thread_c.h | 39 +- .../src/thread/generic/SDL_syscond.c | 59 +- .../src/thread/generic/SDL_syscond_c.h | 42 + .../src/thread/generic/SDL_sysmutex.c | 38 +- .../src/thread/generic}/SDL_sysmutex_c.h | 2 +- .../src/thread/generic/SDL_syssem.c | 57 +- .../src/thread/generic/SDL_systhread.c | 31 +- .../src/thread/generic/SDL_systhread_c.h | 2 +- .../src/thread/generic/SDL_systls.c | 9 +- SDL2-2.30.5/src/thread/n3ds/SDL_syscond.c | 127 + SDL2-2.30.5/src/thread/n3ds/SDL_sysmutex.c | 88 + SDL2-2.30.5/src/thread/n3ds/SDL_sysmutex_c.h | 37 + SDL2-2.30.5/src/thread/n3ds/SDL_syssem.c | 143 + SDL2-2.30.5/src/thread/n3ds/SDL_systhread.c | 139 + SDL2-2.30.5/src/thread/n3ds/SDL_systhread_c.h | 32 + SDL2-2.30.5/src/thread/ngage/SDL_sysmutex.cpp | 112 + SDL2-2.30.5/src/thread/ngage/SDL_syssem.cpp | 173 + .../src/thread/ngage/SDL_systhread.cpp | 115 + .../src/thread/ngage/SDL_systhread_c.h | 25 + SDL2-2.30.5/src/thread/os2/SDL_sysmutex.c | 124 + SDL2-2.30.5/src/thread/os2/SDL_syssem.c | 183 + SDL2-2.30.5/src/thread/os2/SDL_systhread.c | 127 + SDL2-2.30.5/src/thread/os2/SDL_systhread_c.h | 25 + SDL2-2.30.5/src/thread/os2/SDL_systls.c | 89 + SDL2-2.30.5/src/thread/os2/SDL_systls_c.h | 38 + SDL2-2.30.5/src/thread/ps2/SDL_syssem.c | 158 + SDL2-2.30.5/src/thread/ps2/SDL_systhread.c | 140 + SDL2-2.30.5/src/thread/ps2/SDL_systhread_c.h | 24 + SDL2-2.30.5/src/thread/psp/SDL_sysmutex.c | 148 + .../src/thread/psp}/SDL_sysmutex_c.h | 2 +- .../src/thread/psp/SDL_syssem.c | 51 +- .../src/thread/psp/SDL_systhread.c | 28 +- .../src/thread/psp/SDL_systhread_c.h | 2 +- .../src/thread/pthread/SDL_syscond.c | 36 +- .../src/thread/pthread/SDL_sysmutex.c | 51 +- .../src/thread/pthread/SDL_sysmutex_c.h | 2 +- .../src/thread/pthread/SDL_syssem.c | 57 +- .../src/thread/pthread/SDL_systhread.c | 298 + .../src/thread/pthread/SDL_systhread_c.h | 2 +- .../src/thread/pthread/SDL_systls.c | 9 +- .../src/thread/stdcpp/SDL_syscond.cpp | 61 +- .../src/thread/stdcpp/SDL_sysmutex.cpp | 47 +- .../src/thread/stdcpp/SDL_sysmutex_c.h | 2 +- .../src/thread/stdcpp/SDL_systhread.cpp | 83 +- .../src/thread/stdcpp/SDL_systhread_c.h | 4 +- SDL2-2.30.5/src/thread/vita/SDL_sysmutex.c | 144 + SDL2-2.30.5/src/thread/vita/SDL_sysmutex_c.h | 23 + SDL2-2.30.5/src/thread/vita/SDL_syssem.c | 161 + SDL2-2.30.5/src/thread/vita/SDL_systhread.c | 137 + SDL2-2.30.5/src/thread/vita/SDL_systhread_c.h | 26 + .../src/thread/windows/SDL_syscond_cv.c | 287 + SDL2-2.30.5/src/thread/windows/SDL_sysmutex.c | 290 + .../src/thread/windows/SDL_sysmutex_c.h | 77 + SDL2-2.30.5/src/thread/windows/SDL_syssem.c | 444 + .../src/thread/windows/SDL_systhread.c | 164 +- .../src/thread/windows/SDL_systhread_c.h | 2 +- .../src/thread/windows/SDL_systls.c | 12 +- .../src/timer/SDL_timer.c | 147 +- .../src/timer/SDL_timer_c.h | 4 +- .../src/timer/dummy/SDL_systimer.c | 20 +- .../src/timer/haiku/SDL_systimer.c | 22 +- SDL2-2.30.5/src/timer/n3ds/SDL_systimer.c | 75 + SDL2-2.30.5/src/timer/ngage/SDL_systimer.cpp | 92 + SDL2-2.30.5/src/timer/os2/SDL_systimer.c | 180 + SDL2-2.30.5/src/timer/ps2/SDL_systimer.c | 85 + .../src/timer/psp/SDL_systimer.c | 33 +- .../src/timer/unix/SDL_systimer.c | 86 +- SDL2-2.30.5/src/timer/vita/SDL_systimer.c | 85 + .../src/timer/windows/SDL_systimer.c | 94 +- .../src/video/SDL_RLEaccel.c | 1283 +- .../src/video/SDL_RLEaccel_c.h | 6 +- .../src/video/SDL_blit.c | 51 +- SDL2-2.30.5/src/video/SDL_blit.h | 589 + SDL2-2.30.5/src/video/SDL_blit_0.c | 986 + .../src/video/SDL_blit_1.c | 148 +- .../src/video/SDL_blit_A.c | 631 +- .../src/video/SDL_blit_N.c | 1204 +- .../src/video/SDL_blit_auto.c | 2286 +- .../src/video/SDL_blit_auto.h | 6 +- .../src/video/SDL_blit_copy.c | 86 +- .../src/video/SDL_blit_copy.h | 4 +- .../src/video/SDL_blit_slow.c | 124 +- .../src/video/SDL_blit_slow.h | 4 +- .../src/video/SDL_bmp.c | 329 +- .../src/video/SDL_clipboard.c | 72 +- .../src/video/SDL_egl.c | 859 +- .../src/video/SDL_egl_c.h | 98 +- .../src/video/SDL_fillrect.c | 216 +- .../src/video/SDL_pixels.c | 416 +- .../src/video/SDL_pixels_c.h | 17 +- SDL2-2.30.5/src/video/SDL_rect.c | 115 + .../src/video/SDL_rect_c.h | 4 +- .../src/video/SDL_rect_impl.h | 326 +- SDL2-2.30.5/src/video/SDL_shape.c | 341 + .../src/video/SDL_shape_internals.h | 32 +- SDL2-2.30.5/src/video/SDL_stretch.c | 958 + .../src/video/SDL_surface.c | 880 +- .../src/video/SDL_sysvideo.h | 214 +- .../src/video/SDL_video.c | 2707 +- .../src/video/SDL_vulkan_internal.h | 32 +- .../src/video/SDL_vulkan_utils.c | 252 +- .../src/video/SDL_yuv.c | 973 +- .../src/video/SDL_yuv_c.h | 6 +- .../src/video/android/SDL_androidclipboard.c | 10 +- .../src/video/android/SDL_androidclipboard.h | 2 +- .../src/video/android/SDL_androidevents.c | 97 +- .../src/video/android/SDL_androidevents.h | 2 +- .../src/video/android/SDL_androidgl.c | 27 +- .../src/video/android/SDL_androidgl.h | 9 +- .../src/video/android/SDL_androidkeyboard.c | 385 + .../src/video/android/SDL_androidkeyboard.h | 13 +- .../src/video/android/SDL_androidmessagebox.c | 7 +- .../src/video/android/SDL_androidmessagebox.h | 4 +- .../src/video/android/SDL_androidmouse.c | 116 +- .../src/video/android/SDL_androidmouse.h | 2 +- .../src/video/android/SDL_androidtouch.c | 35 +- .../src/video/android/SDL_androidtouch.h | 2 +- .../src/video/android/SDL_androidvideo.c | 158 +- .../src/video/android/SDL_androidvideo.h | 10 +- .../src/video/android/SDL_androidvulkan.c | 82 +- .../src/video/android/SDL_androidvulkan.h | 16 +- .../src/video/android/SDL_androidwindow.c | 70 +- .../src/video/android/SDL_androidwindow.h | 9 +- .../src/video/arm/pixman-arm-asm.h | 0 .../src/video/arm/pixman-arm-neon-asm.S | 0 .../src/video/arm/pixman-arm-neon-asm.h | 0 .../src/video/arm/pixman-arm-simd-asm.S | 0 .../src/video/arm/pixman-arm-simd-asm.h | 0 .../src/video/cocoa/SDL_cocoaclipboard.h | 6 +- .../src/video/cocoa/SDL_cocoaclipboard.m | 34 +- .../src/video/cocoa/SDL_cocoaevents.h | 4 +- .../src/video/cocoa/SDL_cocoaevents.m | 238 +- .../src/video/cocoa/SDL_cocoakeyboard.h | 6 +- .../src/video/cocoa/SDL_cocoakeyboard.m | 480 + .../src/video/cocoa/SDL_cocoamessagebox.h | 4 +- .../src/video/cocoa/SDL_cocoamessagebox.m | 86 +- .../src/video/cocoa/SDL_cocoametalview.h | 14 +- .../src/video/cocoa/SDL_cocoametalview.m | 57 +- .../src/video/cocoa/SDL_cocoamodes.h | 2 +- .../src/video/cocoa/SDL_cocoamodes.m | 193 +- .../src/video/cocoa/SDL_cocoamouse.h | 7 +- .../src/video/cocoa/SDL_cocoamouse.m | 319 +- .../src/video/cocoa/SDL_cocoaopengl.h | 18 +- .../src/video/cocoa/SDL_cocoaopengl.m | 320 +- .../src/video/cocoa/SDL_cocoaopengles.h | 4 +- .../src/video/cocoa/SDL_cocoaopengles.m | 69 +- .../src/video/cocoa/SDL_cocoashape.h | 13 +- SDL2-2.30.5/src/video/cocoa/SDL_cocoashape.m | 127 + .../src/video/cocoa/SDL_cocoavideo.h | 24 +- .../src/video/cocoa/SDL_cocoavideo.m | 121 +- .../src/video/cocoa/SDL_cocoavulkan.h | 4 +- .../src/video/cocoa/SDL_cocoavulkan.m | 68 +- .../src/video/cocoa/SDL_cocoawindow.h | 55 +- .../src/video/cocoa/SDL_cocoawindow.m | 1163 +- .../src/video/directfb/SDL_DirectFB_WM.c | 52 +- .../src/video/directfb/SDL_DirectFB_WM.h | 2 +- .../src/video/directfb/SDL_DirectFB_dyn.c | 20 +- .../src/video/directfb/SDL_DirectFB_dyn.h | 2 +- .../src/video/directfb/SDL_DirectFB_events.c | 99 +- .../src/video/directfb/SDL_DirectFB_events.h | 2 +- .../src/video/directfb/SDL_DirectFB_modes.c | 35 +- .../src/video/directfb/SDL_DirectFB_modes.h | 2 +- .../src/video/directfb/SDL_DirectFB_mouse.c | 48 +- .../src/video/directfb/SDL_DirectFB_mouse.h | 2 +- .../src/video/directfb/SDL_DirectFB_opengl.c | 68 +- .../src/video/directfb/SDL_DirectFB_opengl.h | 4 +- .../src/video/directfb/SDL_DirectFB_render.c | 316 +- .../src/video/directfb/SDL_DirectFB_render.h | 2 +- .../src/video/directfb/SDL_DirectFB_shape.c | 35 +- .../src/video/directfb/SDL_DirectFB_shape.h | 2 +- .../src/video/directfb/SDL_DirectFB_video.c | 62 +- .../src/video/directfb/SDL_DirectFB_video.h | 7 +- .../src/video/directfb/SDL_DirectFB_vulkan.c | 169 + .../src/video/directfb/SDL_DirectFB_vulkan.h | 47 + .../src/video/directfb/SDL_DirectFB_window.c | 96 +- .../src/video/directfb/SDL_DirectFB_window.h | 5 +- .../src/video/dummy/SDL_nullevents.c | 7 +- .../src/video/dummy/SDL_nullevents_c.h | 2 +- .../src/video/dummy/SDL_nullframebuffer.c | 31 +- .../src/video/dummy/SDL_nullframebuffer_c.h | 8 +- .../src/video/dummy/SDL_nullvideo.c | 95 +- .../src/video/dummy/SDL_nullvideo.h | 2 +- .../video/emscripten/SDL_emscriptenevents.c | 1029 + .../video/emscripten/SDL_emscriptenevents.h | 4 +- .../emscripten/SDL_emscriptenframebuffer.c | 39 +- .../emscripten/SDL_emscriptenframebuffer.h | 8 +- .../video/emscripten/SDL_emscriptenmouse.c | 156 +- .../video/emscripten/SDL_emscriptenmouse.h | 3 +- .../video/emscripten/SDL_emscriptenopengles.c | 34 +- .../video/emscripten/SDL_emscriptenopengles.h | 5 +- .../video/emscripten/SDL_emscriptenvideo.c | 169 +- .../video/emscripten/SDL_emscriptenvideo.h | 6 +- SDL2-2.30.5/src/video/haiku/SDL_BApp.h | 427 + SDL2-2.30.5/src/video/haiku/SDL_BWin.h | 754 + .../src/video/haiku/SDL_bclipboard.cc | 14 +- .../src/video/haiku/SDL_bclipboard.h | 2 +- .../src/video/haiku/SDL_bevents.cc | 4 +- .../src/video/haiku/SDL_bevents.h | 2 +- .../src/video/haiku/SDL_bframebuffer.cc | 129 + .../src/video/haiku/SDL_bframebuffer.h | 14 +- .../src/video/haiku/SDL_bkeyboard.cc | 14 +- .../src/video/haiku/SDL_bkeyboard.h | 2 +- .../src/video/haiku/SDL_bmessagebox.cc | 81 +- .../src/video/haiku/SDL_bmessagebox.h | 4 +- .../src/video/haiku/SDL_bmodes.cc | 135 +- .../src/video/haiku/SDL_bmodes.h | 9 +- .../src/video/haiku/SDL_bopengl.cc | 53 +- .../src/video/haiku/SDL_bopengl.h | 23 +- .../src/video/haiku/SDL_bvideo.cc | 166 +- .../src/video/haiku/SDL_bvideo.h | 4 +- .../src/video/haiku/SDL_bwindow.cc | 46 +- .../src/video/haiku/SDL_bwindow.h | 9 +- .../src/video/khronos/EGL/egl.h | 89 +- .../src/video/khronos/EGL/eglext.h | 330 +- .../src/video/khronos/EGL/eglplatform.h | 101 +- .../src/video/khronos/GLES2/gl2.h | 37 +- .../src/video/khronos/GLES2/gl2ext.h | 680 +- .../src/video/khronos/GLES2/gl2platform.h | 27 + .../src/video/khronos/KHR/khrplatform.h | 53 +- .../vk_video/vulkan_video_codec_h264std.h | 312 + .../vulkan_video_codec_h264std_decode.h | 77 + .../vulkan_video_codec_h264std_encode.h | 147 + .../vk_video/vulkan_video_codec_h265std.h | 446 + .../vulkan_video_codec_h265std_decode.h | 67 + .../vulkan_video_codec_h265std_encode.h | 157 + .../vk_video/vulkan_video_codecs_common.h | 36 + .../src/video/khronos/vulkan/vk_icd.h | 126 +- .../src/video/khronos/vulkan/vk_layer.h | 50 +- .../src/video/khronos/vulkan/vk_platform.h | 20 +- .../video/khronos/vulkan/vk_sdk_platform.h | 0 .../src/video/khronos/vulkan/vulkan.h | 48 +- .../src/video/khronos/vulkan/vulkan_android.h | 73 +- .../src/video/khronos/vulkan/vulkan_beta.h | 216 + .../src/video/khronos/vulkan/vulkan_core.h | 19371 ++++++ .../video/khronos/vulkan/vulkan_directfb.h | 55 + .../src/video/khronos/vulkan/vulkan_fuchsia.h | 262 + .../src/video/khronos/vulkan/vulkan_ggp.h | 60 + .../src/video/khronos/vulkan/vulkan_ios.h | 30 +- .../src/video/khronos/vulkan/vulkan_macos.h | 30 +- .../src/video/khronos/vulkan/vulkan_metal.h | 203 + .../src/video/khronos/vulkan/vulkan_screen.h | 108 + .../src/video/khronos/vulkan/vulkan_vi.h | 28 +- .../src/video/khronos/vulkan/vulkan_wayland.h | 28 +- .../src/video/khronos/vulkan/vulkan_win32.h | 128 +- .../src/video/khronos/vulkan/vulkan_xcb.h | 28 +- .../src/video/khronos/vulkan/vulkan_xlib.h | 28 +- .../video/khronos/vulkan/vulkan_xlib_xrandr.h | 26 +- .../src/video/kmsdrm/SDL_kmsdrmdyn.c | 69 +- .../src/video/kmsdrm/SDL_kmsdrmdyn.h | 8 +- .../src/video/kmsdrm/SDL_kmsdrmevents.c | 10 +- .../src/video/kmsdrm/SDL_kmsdrmevents.h | 4 +- .../src/video/kmsdrm/SDL_kmsdrmmouse.c | 451 + .../src/video/kmsdrm/SDL_kmsdrmmouse.h | 22 +- .../src/video/kmsdrm/SDL_kmsdrmopengles.c | 214 + .../src/video/kmsdrm/SDL_kmsdrmopengles.h | 14 +- .../src/video/kmsdrm/SDL_kmsdrmsym.h | 56 +- .../src/video/kmsdrm/SDL_kmsdrmvideo.c | 1688 + .../src/video/kmsdrm/SDL_kmsdrmvideo.h | 109 +- .../src/video/kmsdrm/SDL_kmsdrmvulkan.c | 528 + .../src/video/kmsdrm/SDL_kmsdrmvulkan.h | 53 + SDL2-2.30.5/src/video/n3ds/SDL_n3dsevents.c | 46 + SDL2-2.30.5/src/video/n3ds/SDL_n3dsevents_c.h | 31 + .../src/video/n3ds/SDL_n3dsframebuffer.c | 145 + .../src/video/n3ds/SDL_n3dsframebuffer_c.h | 33 + SDL2-2.30.5/src/video/n3ds/SDL_n3dsswkb.c | 70 + SDL2-2.30.5/src/video/n3ds/SDL_n3dsswkb.h | 38 + SDL2-2.30.5/src/video/n3ds/SDL_n3dstouch.c | 81 + SDL2-2.30.5/src/video/n3ds/SDL_n3dstouch.h | 31 + SDL2-2.30.5/src/video/n3ds/SDL_n3dsvideo.c | 188 + SDL2-2.30.5/src/video/n3ds/SDL_n3dsvideo.h | 38 + .../src/video/nacl/SDL_naclevents.c | 11 +- .../src/video/nacl/SDL_naclevents_c.h | 2 +- .../src/video/nacl/SDL_naclglue.c | 4 +- .../src/video/nacl/SDL_naclopengles.c | 57 +- .../src/video/nacl/SDL_naclopengles.h | 2 +- .../src/video/nacl/SDL_naclvideo.c | 57 +- .../src/video/nacl/SDL_naclvideo.h | 2 +- .../src/video/nacl/SDL_naclwindow.c | 24 +- .../src/video/nacl/SDL_naclwindow.h | 2 +- .../src/video/ngage/SDL_ngageevents.cpp | 196 + .../src/video/ngage/SDL_ngageevents_c.h | 28 + .../src/video/ngage/SDL_ngageframebuffer.cpp | 399 + .../src/video/ngage/SDL_ngageframebuffer_c.h | 38 + .../src/video/ngage/SDL_ngagevideo.cpp | 180 + SDL2-2.30.5/src/video/ngage/SDL_ngagevideo.h | 68 + .../src/video/ngage/SDL_ngagewindow.cpp | 127 + SDL2-2.30.5/src/video/ngage/SDL_ngagewindow.h | 44 + .../src/video/offscreen/SDL_offscreenevents.c | 8 +- .../video/offscreen/SDL_offscreenevents_c.h | 5 +- .../offscreen/SDL_offscreenframebuffer.c | 33 +- .../offscreen/SDL_offscreenframebuffer_c.h | 9 +- .../video/offscreen/SDL_offscreenopengles.c | 84 +- .../video/offscreen/SDL_offscreenopengles.h | 46 + .../src/video/offscreen/SDL_offscreenvideo.c | 82 +- .../src/video/offscreen/SDL_offscreenvideo.h | 4 +- .../src/video/offscreen/SDL_offscreenwindow.c | 24 +- .../src/video/offscreen/SDL_offscreenwindow.h | 22 +- SDL2-2.30.5/src/video/os2/SDL_gradd.h | 171 + SDL2-2.30.5/src/video/os2/SDL_os2dive.c | 331 + SDL2-2.30.5/src/video/os2/SDL_os2messagebox.c | 561 + SDL2-2.30.5/src/video/os2/SDL_os2messagebox.h | 29 + SDL2-2.30.5/src/video/os2/SDL_os2mouse.c | 194 + SDL2-2.30.5/src/video/os2/SDL_os2mouse.h | 33 + SDL2-2.30.5/src/video/os2/SDL_os2output.h | 59 + SDL2-2.30.5/src/video/os2/SDL_os2util.c | 114 + SDL2-2.30.5/src/video/os2/SDL_os2util.h | 38 + SDL2-2.30.5/src/video/os2/SDL_os2video.c | 1699 + SDL2-2.30.5/src/video/os2/SDL_os2video.h | 82 + SDL2-2.30.5/src/video/os2/SDL_os2vman.c | 483 + .../src/video/pandora/SDL_pandora.c | 163 +- .../src/video/pandora/SDL_pandora.h | 3 +- .../src/video/pandora/SDL_pandora_events.c | 7 +- .../src/video/pandora/SDL_pandora_events.h | 2 +- SDL2-2.30.5/src/video/ps2/SDL_ps2video.c | 135 + SDL2-2.30.5/src/video/ps2/SDL_ps2video.h | 42 + .../src/video/psp/SDL_pspevents.c | 104 +- .../src/video/psp/SDL_pspevents_c.h | 8 +- SDL2-2.30.5/src/video/psp/SDL_pspgl.c | 195 + .../src/video/psp/SDL_pspgl_c.h | 24 +- .../src/video/psp/SDL_pspmouse.c | 8 +- .../src/video/psp/SDL_pspmouse_c.h | 2 +- .../src/video/psp/SDL_pspvideo.c | 155 +- .../src/video/psp/SDL_pspvideo.h | 52 +- .../src/video/qnx/gl.c | 38 +- .../src/video/qnx/keyboard.c | 3 +- .../src/video/qnx/sdl_qnx.h | 0 .../src/video/qnx/video.c | 51 +- .../src/video/raspberry/SDL_rpievents.c | 8 +- .../src/video/raspberry/SDL_rpievents_c.h | 4 +- .../src/video/raspberry/SDL_rpimouse.c | 174 +- .../src/video/raspberry/SDL_rpimouse.h | 12 +- .../src/video/raspberry/SDL_rpiopengles.c | 26 +- .../src/video/raspberry/SDL_rpiopengles.h | 12 +- .../src/video/raspberry/SDL_rpivideo.c | 196 +- .../src/video/raspberry/SDL_rpivideo.h | 50 +- SDL2-2.30.5/src/video/riscos/SDL_riscosdefs.h | 53 + .../src/video/riscos/SDL_riscosevents.c | 179 + .../src/video/riscos/SDL_riscosevents_c.h | 35 + .../src/video/riscos/SDL_riscosframebuffer.c | 129 + .../video/riscos/SDL_riscosframebuffer_c.h | 33 + .../src/video/riscos/SDL_riscosmessagebox.c | 70 + .../src/video/riscos/SDL_riscosmessagebox.h | 29 + .../src/video/riscos/SDL_riscosmodes.c | 310 + .../src/video/riscos/SDL_riscosmodes.h | 33 + .../src/video/riscos/SDL_riscosmouse.c | 83 + .../src/video/riscos/SDL_riscosmouse.h | 30 + .../src/video/riscos/SDL_riscosvideo.c | 127 + .../src/video/riscos/SDL_riscosvideo.h | 38 + .../src/video/riscos/SDL_riscoswindow.c | 79 + .../src/video/riscos/SDL_riscoswindow.h | 42 + .../src/video/riscos/scancodes_riscos.h | 158 + .../src/video/sdlgenblit.pl | 150 +- .../src/video/uikit/SDL_uikitappdelegate.h | 2 +- .../src/video/uikit/SDL_uikitappdelegate.m | 135 +- .../src/video/uikit/SDL_uikitclipboard.h | 2 +- .../src/video/uikit/SDL_uikitclipboard.m | 19 +- .../src/video/uikit/SDL_uikitevents.h | 11 +- SDL2-2.30.5/src/video/uikit/SDL_uikitevents.m | 483 + .../src/video/uikit/SDL_uikitmessagebox.h | 4 +- .../src/video/uikit/SDL_uikitmessagebox.m | 112 +- .../src/video/uikit/SDL_uikitmetalview.h | 19 +- .../src/video/uikit/SDL_uikitmetalview.m | 49 +- .../src/video/uikit/SDL_uikitmodes.h | 4 +- .../src/video/uikit/SDL_uikitmodes.m | 120 +- .../src/video/uikit/SDL_uikitopengles.h | 6 +- .../src/video/uikit/SDL_uikitopengles.m | 42 +- .../src/video/uikit/SDL_uikitopenglview.h | 4 +- .../src/video/uikit/SDL_uikitopenglview.m | 16 +- .../src/video/uikit/SDL_uikitvideo.h | 2 +- .../src/video/uikit/SDL_uikitvideo.m | 97 +- .../src/video/uikit/SDL_uikitview.h | 11 +- SDL2-2.30.5/src/video/uikit/SDL_uikitview.m | 489 + .../src/video/uikit/SDL_uikitviewcontroller.h | 14 +- .../src/video/uikit/SDL_uikitviewcontroller.m | 258 +- .../src/video/uikit/SDL_uikitvulkan.h | 4 +- .../src/video/uikit/SDL_uikitvulkan.m | 68 +- .../src/video/uikit/SDL_uikitwindow.h | 5 +- .../src/video/uikit/SDL_uikitwindow.m | 130 +- .../src/video/vita/SDL_vitaframebuffer.c | 118 + .../src/video/vita/SDL_vitaframebuffer.h | 8 +- SDL2-2.30.5/src/video/vita/SDL_vitagl_pvr.c | 126 + SDL2-2.30.5/src/video/vita/SDL_vitagl_pvr_c.h | 33 + SDL2-2.30.5/src/video/vita/SDL_vitagles.c | 222 + SDL2-2.30.5/src/video/vita/SDL_vitagles_c.h | 55 + SDL2-2.30.5/src/video/vita/SDL_vitagles_pvr.c | 97 + .../src/video/vita/SDL_vitagles_pvr_c.h | 34 + SDL2-2.30.5/src/video/vita/SDL_vitakeyboard.c | 189 + SDL2-2.30.5/src/video/vita/SDL_vitakeyboard.h | 33 + .../src/video/vita/SDL_vitamessagebox.c | 127 + .../src/video/vita/SDL_vitamessagebox.h | 33 + SDL2-2.30.5/src/video/vita/SDL_vitamouse.c | 89 + SDL2-2.30.5/src/video/vita/SDL_vitamouse_c.h | 33 + SDL2-2.30.5/src/video/vita/SDL_vitatouch.c | 193 + SDL2-2.30.5/src/video/vita/SDL_vitatouch.h | 35 + SDL2-2.30.5/src/video/vita/SDL_vitavideo.c | 610 + SDL2-2.30.5/src/video/vita/SDL_vitavideo.h | 119 + .../src/video/vivante/SDL_vivanteopengles.c | 14 +- .../src/video/vivante/SDL_vivanteopengles.h | 12 +- .../src/video/vivante/SDL_vivanteplatform.c | 13 +- .../src/video/vivante/SDL_vivanteplatform.h | 4 +- .../src/video/vivante/SDL_vivantevideo.c | 123 +- .../src/video/vivante/SDL_vivantevideo.h | 42 +- .../src/video/vivante/SDL_vivantevulkan.c | 77 +- .../src/video/vivante/SDL_vivantevulkan.h | 17 +- .../src/video/wayland/SDL_waylandclipboard.c | 204 + .../src/video/wayland/SDL_waylandclipboard.h | 5 +- .../video/wayland/SDL_waylanddatamanager.c | 708 + .../video/wayland/SDL_waylanddatamanager.h | 161 + .../src/video/wayland/SDL_waylanddyn.c | 115 +- .../src/video/wayland/SDL_waylanddyn.h | 188 + .../src/video/wayland/SDL_waylandevents.c | 2890 + .../src/video/wayland/SDL_waylandevents_c.h | 180 + .../src/video/wayland/SDL_waylandkeyboard.c | 160 + .../src/video/wayland/SDL_waylandkeyboard.h | 43 + .../src/video/wayland/SDL_waylandmessagebox.c | 252 + .../src/video/wayland/SDL_waylandmessagebox.h | 33 + .../src/video/wayland/SDL_waylandmouse.c | 732 + .../src/video/wayland/SDL_waylandmouse.h | 9 +- .../src/video/wayland/SDL_waylandopengles.c | 200 + .../src/video/wayland/SDL_waylandopengles.h | 13 +- .../src/video/wayland/SDL_waylandsym.h | 239 + .../src/video/wayland/SDL_waylandtouch.c | 149 +- .../src/video/wayland/SDL_waylandtouch.h | 334 + .../src/video/wayland/SDL_waylandvideo.c | 1187 + .../src/video/wayland/SDL_waylandvideo.h | 83 +- .../src/video/wayland/SDL_waylandvulkan.c | 108 +- .../src/video/wayland/SDL_waylandvulkan.h | 17 +- .../src/video/wayland/SDL_waylandwindow.c | 2362 + .../src/video/wayland/SDL_waylandwindow.h | 155 + .../src/video/windows/SDL_msctf.h | 12 +- SDL2-2.30.5/src/video/windows/SDL_vkeys.h | 76 + .../src/video/windows/SDL_windowsclipboard.c | 72 +- .../src/video/windows/SDL_windowsclipboard.h | 4 +- .../src/video/windows/SDL_windowsevents.c | 2118 + .../src/video/windows/SDL_windowsevents.h | 5 +- .../video/windows/SDL_windowsframebuffer.c | 40 +- .../video/windows/SDL_windowsframebuffer.h | 27 + .../src/video/windows/SDL_windowskeyboard.c | 980 +- .../src/video/windows/SDL_windowskeyboard.h | 8 +- .../src/video/windows/SDL_windowsmessagebox.c | 255 +- .../src/video/windows/SDL_windowsmessagebox.h | 4 +- .../src/video/windows/SDL_windowsmodes.c | 849 + .../src/video/windows/SDL_windowsmodes.h | 19 +- .../src/video/windows/SDL_windowsmouse.c | 494 + .../src/video/windows/SDL_windowsmouse.h | 5 +- .../src/video/windows/SDL_windowsopengl.c | 272 +- .../src/video/windows/SDL_windowsopengl.h | 181 + .../src/video/windows/SDL_windowsopengles.c | 44 +- .../src/video/windows/SDL_windowsopengles.h | 10 +- .../src/video/windows/SDL_windowsshape.c | 89 +- .../src/video/windows/SDL_windowsshape.h | 9 +- .../src/video/windows/SDL_windowsvideo.c | 705 + .../src/video/windows/SDL_windowsvideo.h | 475 + .../src/video/windows/SDL_windowsvulkan.c | 72 +- .../src/video/windows/SDL_windowsvulkan.h | 4 +- .../src/video/windows/SDL_windowswindow.c | 1490 + .../src/video/windows/SDL_windowswindow.h | 44 +- .../src/video/windows/wmmsg.h | 8 +- .../src/video/winrt/SDL_winrtevents.cpp | 92 +- .../src/video/winrt/SDL_winrtevents_c.h | 33 +- .../src/video/winrt/SDL_winrtgamebar.cpp | 72 +- .../src/video/winrt/SDL_winrtgamebar_cpp.h | 2 +- .../src/video/winrt/SDL_winrtkeyboard.cpp | 479 + .../src/video/winrt/SDL_winrtmessagebox.cpp | 32 +- .../src/video/winrt/SDL_winrtmessagebox.h | 4 +- .../src/video/winrt/SDL_winrtmouse.cpp | 108 +- .../src/video/winrt/SDL_winrtmouse_c.h | 2 +- .../src/video/winrt/SDL_winrtopengles.cpp | 77 +- .../src/video/winrt/SDL_winrtopengles.h | 21 +- .../src/video/winrt/SDL_winrtpointerinput.cpp | 254 +- .../src/video/winrt/SDL_winrtvideo.cpp | 328 +- .../src/video/winrt/SDL_winrtvideo_cpp.h | 31 +- .../src/video/x11/SDL_x11clipboard.c | 186 +- .../src/video/x11/SDL_x11clipboard.h | 20 +- .../src/video/x11/SDL_x11dyn.c | 77 +- .../src/video/x11/SDL_x11dyn.h | 45 +- SDL2-2.30.5/src/video/x11/SDL_x11events.c | 1811 + .../src/video/x11/SDL_x11events.h | 6 +- .../src/video/x11/SDL_x11framebuffer.c | 109 +- .../src/video/x11/SDL_x11framebuffer.h | 15 +- SDL2-2.30.5/src/video/x11/SDL_x11keyboard.c | 506 + .../src/video/x11/SDL_x11keyboard.h | 10 +- SDL2-2.30.5/src/video/x11/SDL_x11messagebox.c | 859 + .../src/video/x11/SDL_x11messagebox.h | 4 +- SDL2-2.30.5/src/video/x11/SDL_x11modes.c | 895 + .../src/video/x11/SDL_x11modes.h | 49 +- .../src/video/x11/SDL_x11mouse.c | 278 +- .../src/video/x11/SDL_x11mouse.h | 12 +- .../src/video/x11/SDL_x11opengl.c | 443 +- .../src/video/x11/SDL_x11opengl.h | 54 +- .../src/video/x11/SDL_x11opengles.c | 38 +- .../src/video/x11/SDL_x11opengles.h | 12 +- .../src/video/x11/SDL_x11shape.c | 94 +- .../src/video/x11/SDL_x11shape.h | 13 +- .../src/video/x11/SDL_x11sym.h | 90 +- .../src/video/x11/SDL_x11touch.c | 18 +- .../src/video/x11/SDL_x11touch.h | 2 +- .../src/video/x11/SDL_x11video.c | 205 +- .../src/video/x11/SDL_x11video.h | 45 +- .../src/video/x11/SDL_x11vulkan.c | 122 +- .../src/video/x11/SDL_x11vulkan.h | 4 +- .../src/video/x11/SDL_x11window.c | 1201 +- .../src/video/x11/SDL_x11window.h | 33 +- SDL2-2.30.5/src/video/x11/SDL_x11xfixes.c | 214 + SDL2-2.30.5/src/video/x11/SDL_x11xfixes.h | 41 + SDL2-2.30.5/src/video/x11/SDL_x11xinput2.c | 525 + .../src/video/x11/SDL_x11xinput2.h | 6 +- .../src/video/x11/edid-parse.c | 12 +- SDL2-2.30.5/src/video/x11/edid.h | 167 + .../src/video/yuv2rgb/LICENSE | 0 .../src/video/yuv2rgb/README.md | 0 SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb.h | 33 + .../src/video/yuv2rgb/yuv_rgb_common.h | 13 + .../src/video/yuv2rgb/yuv_rgb_internal.h | 74 + SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb_lsx.c | 44 + SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb_lsx.h | 407 + .../src/video/yuv2rgb/yuv_rgb_lsx_func.h | 372 + .../src/video/yuv2rgb/yuv_rgb_sse.c | 586 +- SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb_sse.h | 266 + .../src/video/yuv2rgb/yuv_rgb_sse_func.h | 47 +- SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb_std.c | 179 + SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb_std.h | 131 + .../src/video/yuv2rgb/yuv_rgb_std_func.h | 72 +- .../wayland-protocols/fractional-scale-v1.xml | 102 + .../idle-inhibit-unstable-v1.xml | 83 + ...keyboard-shortcuts-inhibit-unstable-v1.xml | 143 + .../pointer-constraints-unstable-v1.xml | 0 .../primary-selection-unstable-v1.xml | 225 + .../relative-pointer-unstable-v1.xml | 0 .../wayland-protocols/tablet-unstable-v2.xml | 1178 + .../text-input-unstable-v3.xml | 452 + SDL2-2.30.5/wayland-protocols/viewporter.xml | 186 + .../wayland-protocols/wayland.xml | 426 +- .../wayland-protocols/xdg-activation-v1.xml | 186 + .../xdg-decoration-unstable-v1.xml | 0 .../xdg-output-unstable-v1.xml | 220 + .../wayland-protocols/xdg-shell.xml | 198 +- 1908 files changed, 311118 insertions(+), 265103 deletions(-) create mode 100644 AerofoilAndroid/app/src/main/java/org/libsdl/app/SDLSurface.java delete mode 100644 SDL2-2.0.12/CMakeLists.txt delete mode 100644 SDL2-2.0.12/Makefile.os2 delete mode 100644 SDL2-2.0.12/Makefile.psp delete mode 100644 SDL2-2.0.12/Makefile.wiz delete mode 100644 SDL2-2.0.12/SDL2Config.cmake delete mode 100644 SDL2-2.0.12/VisualC-WinRT/SDL2-WinRT.nuspec delete mode 100644 SDL2-2.0.12/VisualC-WinRT/SDL2-WinRT.targets delete mode 100644 SDL2-2.0.12/VisualC-WinRT/SDL2main-WinRT-NonXAML.nuspec delete mode 100644 SDL2-2.0.12/VisualC-WinRT/SDL2main-WinRT-NonXAML.targets delete mode 100644 SDL2-2.0.12/VisualC-WinRT/UWP_VS2015/SDL-UWP.vcxproj delete mode 100644 SDL2-2.0.12/VisualC-WinRT/UWP_VS2015/SDL-UWP.vcxproj.filters delete mode 100644 SDL2-2.0.12/VisualC-WinRT/WinPhone81_VS2013/SDL-WinPhone81.sln delete mode 100644 SDL2-2.0.12/VisualC-WinRT/WinPhone81_VS2013/SDL-WinPhone81.vcxproj delete mode 100644 SDL2-2.0.12/VisualC-WinRT/WinPhone81_VS2013/SDL-WinPhone81.vcxproj.filters delete mode 100644 SDL2-2.0.12/VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.sln delete mode 100644 SDL2-2.0.12/VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.vcxproj delete mode 100644 SDL2-2.0.12/VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.vcxproj.filters delete mode 100644 SDL2-2.0.12/VisualC-WinRT/tests/loopwave/Assets/Logo.png delete mode 100644 SDL2-2.0.12/VisualC-WinRT/tests/loopwave/Assets/SmallLogo.png delete mode 100644 SDL2-2.0.12/VisualC-WinRT/tests/loopwave/Assets/SplashScreen.png delete mode 100644 SDL2-2.0.12/VisualC-WinRT/tests/loopwave/Assets/StoreLogo.png delete mode 100644 SDL2-2.0.12/VisualC-WinRT/tests/loopwave/Package.appxmanifest delete mode 100644 SDL2-2.0.12/VisualC-WinRT/tests/loopwave/loopwave_VS2012.vcxproj delete mode 100644 SDL2-2.0.12/VisualC-WinRT/tests/loopwave/loopwave_VS2012_TemporaryKey.pfx delete mode 100644 SDL2-2.0.12/VisualC-WinRT/tests/testthread/Assets/Logo.png delete mode 100644 SDL2-2.0.12/VisualC-WinRT/tests/testthread/Assets/SmallLogo.png delete mode 100644 SDL2-2.0.12/VisualC-WinRT/tests/testthread/Assets/SplashScreen.png delete mode 100644 SDL2-2.0.12/VisualC-WinRT/tests/testthread/Assets/StoreLogo.png delete mode 100644 SDL2-2.0.12/VisualC-WinRT/tests/testthread/Package.appxmanifest delete mode 100644 SDL2-2.0.12/VisualC-WinRT/tests/testthread/testthread_VS2012.vcxproj delete mode 100644 SDL2-2.0.12/VisualC-WinRT/tests/testthread/testthread_VS2012_TemporaryKey.pfx delete mode 100644 SDL2-2.0.12/VisualC.html delete mode 100644 SDL2-2.0.12/VisualC/SDL/SDL.vcxproj.filters delete mode 100644 SDL2-2.0.12/Xcode-iOS/Demos/Info.plist delete mode 100644 SDL2-2.0.12/Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj delete mode 100644 SDL2-2.0.12/Xcode-iOS/SDL/SDL.xcodeproj/project.xcworkspace/contents.xcworkspacedata delete mode 100644 SDL2-2.0.12/Xcode-iOS/SDL/SDL.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist delete mode 100644 SDL2-2.0.12/Xcode-iOS/SDL/SDL.xcodeproj/xcshareddata/xcschemes/All-iOS.xcscheme delete mode 100644 SDL2-2.0.12/Xcode-iOS/SDL/SDL.xcodeproj/xcshareddata/xcschemes/All-tvOS.xcscheme delete mode 100644 SDL2-2.0.12/Xcode-iOS/SDL/SDL.xcodeproj/xcshareddata/xcschemes/PrepareXcodeProjectTemplate.xcscheme delete mode 100644 SDL2-2.0.12/Xcode-iOS/SDL/SDL.xcodeproj/xcshareddata/xcschemes/libSDL-iOS-dylib.xcscheme delete mode 100644 SDL2-2.0.12/Xcode-iOS/SDL/SDL.xcodeproj/xcshareddata/xcschemes/libSDL-iOS.xcscheme delete mode 100644 SDL2-2.0.12/Xcode-iOS/SDL/SDL.xcodeproj/xcshareddata/xcschemes/libSDL-tvOS-dylib.xcscheme delete mode 100644 SDL2-2.0.12/Xcode-iOS/SDL/SDL.xcodeproj/xcshareddata/xcschemes/libSDL-tvOS.xcscheme delete mode 100644 SDL2-2.0.12/Xcode-iOS/SDL/SDL.xcodeproj/xcshareddata/xcschemes/libSDLmain-iOS.xcscheme delete mode 100644 SDL2-2.0.12/Xcode-iOS/SDL/SDL.xcodeproj/xcshareddata/xcschemes/libSDLmain-tvOS.xcscheme delete mode 100644 SDL2-2.0.12/Xcode-iOS/SDLtest/SDL2test.xcodeproj/project.pbxproj delete mode 100644 SDL2-2.0.12/Xcode-iOS/Template/SDL iOS Application/Default-568h@2x.png delete mode 100644 SDL2-2.0.12/Xcode-iOS/Template/SDL iOS Application/Default.png delete mode 100644 SDL2-2.0.12/Xcode-iOS/Template/SDL iOS Application/Icon.png delete mode 100644 SDL2-2.0.12/Xcode-iOS/Template/SDL iOS Application/Info.plist delete mode 100644 SDL2-2.0.12/Xcode-iOS/Template/SDL iOS Application/___PROJECTNAME___.xcodeproj/TemplateIcon.icns delete mode 100644 SDL2-2.0.12/Xcode-iOS/Template/SDL iOS Application/___PROJECTNAME___.xcodeproj/TemplateInfo.plist delete mode 100644 SDL2-2.0.12/Xcode-iOS/Template/SDL iOS Application/___PROJECTNAME___.xcodeproj/project.pbxproj delete mode 100644 SDL2-2.0.12/Xcode-iOS/Template/SDL iOS Application/___PROJECTNAME___.xcodeproj/project.xcworkspace/contents.xcworkspacedata delete mode 100644 SDL2-2.0.12/Xcode-iOS/Template/SDL iOS Application/main.c delete mode 100644 SDL2-2.0.12/Xcode-iOS/Test/Info.plist delete mode 100644 SDL2-2.0.12/Xcode-iOS/Test/README delete mode 100644 SDL2-2.0.12/Xcode-iOS/Test/TestiPhoneOS.xcodeproj/project.pbxproj delete mode 100644 SDL2-2.0.12/Xcode/SDL/SDL.xcodeproj/xcshareddata/xcschemes/Framework-tvOS.xcscheme delete mode 100644 SDL2-2.0.12/Xcode/SDL/SDL.xcodeproj/xcshareddata/xcschemes/Shared Library-iOS.xcscheme delete mode 100644 SDL2-2.0.12/Xcode/SDL/SDL.xcodeproj/xcshareddata/xcschemes/Shared Library-tvOS.xcscheme delete mode 100644 SDL2-2.0.12/Xcode/SDL/SDL.xcodeproj/xcshareddata/xcschemes/Shared Library.xcscheme delete mode 100644 SDL2-2.0.12/Xcode/SDL/SDL.xcodeproj/xcshareddata/xcschemes/Standard DMG.xcscheme delete mode 100644 SDL2-2.0.12/Xcode/SDL/SDL.xcodeproj/xcshareddata/xcschemes/Static Library-iOS.xcscheme delete mode 100644 SDL2-2.0.12/Xcode/SDL/SDL.xcodeproj/xcshareddata/xcschemes/Static Library-tvOS.xcscheme delete mode 100644 SDL2-2.0.12/Xcode/SDL/SDL.xcodeproj/xcshareddata/xcschemes/Static Library.xcscheme delete mode 100644 SDL2-2.0.12/Xcode/SDL/SDL.xcodeproj/xcshareddata/xcschemes/hidapi-iOS.xcscheme delete mode 100644 SDL2-2.0.12/Xcode/SDL/SDL.xcodeproj/xcshareddata/xcschemes/hidapi-tvOS.xcscheme delete mode 100644 SDL2-2.0.12/Xcode/SDL/SDL.xcodeproj/xcshareddata/xcschemes/hidapi.xcscheme delete mode 100644 SDL2-2.0.12/acinclude/pkg_config.m4 delete mode 100644 SDL2-2.0.12/android-project/gradle/wrapper/gradle-wrapper.jar delete mode 100644 SDL2-2.0.12/build-scripts/config.guess delete mode 100644 SDL2-2.0.12/build-scripts/config.sub delete mode 100644 SDL2-2.0.12/build-scripts/config.sub.patch delete mode 100644 SDL2-2.0.12/build-scripts/iosbuild.sh delete mode 100644 SDL2-2.0.12/build-scripts/os2-buildbot.sh delete mode 100644 SDL2-2.0.12/build-scripts/showrev.sh delete mode 100644 SDL2-2.0.12/build-scripts/update-copyright.sh delete mode 100644 SDL2-2.0.12/build-scripts/updaterev.sh delete mode 100644 SDL2-2.0.12/build-scripts/windows-buildbot-zipper.bat delete mode 100644 SDL2-2.0.12/build-scripts/winrtbuild.bat delete mode 100644 SDL2-2.0.12/build-scripts/winrtbuild.ps1 delete mode 100644 SDL2-2.0.12/cmake/macros.cmake delete mode 100644 SDL2-2.0.12/cmake/sdlchecks.cmake delete mode 100644 SDL2-2.0.12/debian/changelog delete mode 100644 SDL2-2.0.12/debian/compat delete mode 100644 SDL2-2.0.12/debian/control delete mode 100644 SDL2-2.0.12/debian/copyright delete mode 100644 SDL2-2.0.12/debian/docs delete mode 100644 SDL2-2.0.12/debian/libsdl2-dev.install delete mode 100644 SDL2-2.0.12/debian/libsdl2-dev.manpages delete mode 100644 SDL2-2.0.12/debian/libsdl2.install delete mode 100644 SDL2-2.0.12/debian/rules delete mode 100644 SDL2-2.0.12/debian/sdl2-config.1 delete mode 100644 SDL2-2.0.12/debian/source/format delete mode 100644 SDL2-2.0.12/debian/watch delete mode 100644 SDL2-2.0.12/docs/README-cmake.md delete mode 100644 SDL2-2.0.12/docs/README-emscripten.md delete mode 100644 SDL2-2.0.12/docs/README-hg.md delete mode 100644 SDL2-2.0.12/docs/README-macosx.md delete mode 100644 SDL2-2.0.12/docs/README-psp.md delete mode 100644 SDL2-2.0.12/docs/README-windows.md delete mode 100644 SDL2-2.0.12/include/SDL.h delete mode 100644 SDL2-2.0.12/include/SDL_audio.h delete mode 100644 SDL2-2.0.12/include/SDL_blendmode.h delete mode 100644 SDL2-2.0.12/include/SDL_config.h.cmake delete mode 100644 SDL2-2.0.12/include/SDL_config_psp.h delete mode 100644 SDL2-2.0.12/include/SDL_config_wiz.h delete mode 100644 SDL2-2.0.12/include/SDL_cpuinfo.h delete mode 100644 SDL2-2.0.12/include/SDL_endian.h delete mode 100644 SDL2-2.0.12/include/SDL_error.h delete mode 100644 SDL2-2.0.12/include/SDL_filesystem.h delete mode 100644 SDL2-2.0.12/include/SDL_gamecontroller.h delete mode 100644 SDL2-2.0.12/include/SDL_hints.h delete mode 100644 SDL2-2.0.12/include/SDL_joystick.h delete mode 100644 SDL2-2.0.12/include/SDL_keyboard.h delete mode 100644 SDL2-2.0.12/include/SDL_log.h delete mode 100644 SDL2-2.0.12/include/SDL_main.h delete mode 100644 SDL2-2.0.12/include/SDL_mouse.h delete mode 100644 SDL2-2.0.12/include/SDL_mutex.h delete mode 100644 SDL2-2.0.12/include/SDL_opengles2_gl2.h delete mode 100644 SDL2-2.0.12/include/SDL_opengles2_gl2ext.h delete mode 100644 SDL2-2.0.12/include/SDL_opengles2_gl2platform.h delete mode 100644 SDL2-2.0.12/include/SDL_rect.h delete mode 100644 SDL2-2.0.12/include/SDL_render.h delete mode 100644 SDL2-2.0.12/include/SDL_revision.h delete mode 100644 SDL2-2.0.12/include/SDL_rwops.h delete mode 100644 SDL2-2.0.12/include/SDL_sensor.h delete mode 100644 SDL2-2.0.12/include/SDL_surface.h delete mode 100644 SDL2-2.0.12/include/SDL_system.h delete mode 100644 SDL2-2.0.12/include/SDL_test_font.h delete mode 100644 SDL2-2.0.12/include/SDL_thread.h delete mode 100644 SDL2-2.0.12/include/SDL_timer.h delete mode 100644 SDL2-2.0.12/include/SDL_version.h delete mode 100644 SDL2-2.0.12/include/SDL_video.h delete mode 100644 SDL2-2.0.12/include/SDL_vulkan.h delete mode 100644 SDL2-2.0.12/lib/x64/SDL2.dll delete mode 100644 SDL2-2.0.12/lib/x64/SDL2.lib delete mode 100644 SDL2-2.0.12/lib/x64/SDL2main.lib delete mode 100644 SDL2-2.0.12/lib/x64/SDL2test.lib delete mode 100644 SDL2-2.0.12/sdl2-config.cmake.in delete mode 100644 SDL2-2.0.12/src/SDL.c delete mode 100644 SDL2-2.0.12/src/SDL_error.c delete mode 100644 SDL2-2.0.12/src/SDL_error_c.h delete mode 100644 SDL2-2.0.12/src/SDL_internal.h delete mode 100644 SDL2-2.0.12/src/SDL_log.c delete mode 100644 SDL2-2.0.12/src/audio/SDL_audiocvt.c delete mode 100644 SDL2-2.0.12/src/audio/SDL_audiotypecvt.c delete mode 100644 SDL2-2.0.12/src/audio/SDL_mixer.c delete mode 100644 SDL2-2.0.12/src/audio/alsa/SDL_alsa_audio.c delete mode 100644 SDL2-2.0.12/src/audio/coreaudio/SDL_coreaudio.m delete mode 100644 SDL2-2.0.12/src/audio/pulseaudio/SDL_pulseaudio.c delete mode 100644 SDL2-2.0.12/src/audio/wasapi/SDL_wasapi_win32.c delete mode 100644 SDL2-2.0.12/src/audio/wasapi/SDL_wasapi_winrt.cpp delete mode 100644 SDL2-2.0.12/src/core/android/keyinfotable.h delete mode 100644 SDL2-2.0.12/src/core/linux/SDL_dbus.c delete mode 100644 SDL2-2.0.12/src/core/linux/SDL_fcitx.c delete mode 100644 SDL2-2.0.12/src/core/linux/SDL_ibus.c delete mode 100644 SDL2-2.0.12/src/core/linux/SDL_threadprio.c delete mode 100644 SDL2-2.0.12/src/core/windows/SDL_windows.c delete mode 100644 SDL2-2.0.12/src/core/windows/SDL_windows.h delete mode 100644 SDL2-2.0.12/src/core/windows/SDL_xinput.h delete mode 100644 SDL2-2.0.12/src/core/winrt/SDL_winrtapp_direct3d.h delete mode 100644 SDL2-2.0.12/src/dynapi/SDL_dynapi.c delete mode 100644 SDL2-2.0.12/src/events/SDL_events.c delete mode 100644 SDL2-2.0.12/src/events/SDL_keyboard.c delete mode 100644 SDL2-2.0.12/src/events/scancodes_linux.h delete mode 100644 SDL2-2.0.12/src/events/scancodes_xfree86.h delete mode 100644 SDL2-2.0.12/src/filesystem/cocoa/SDL_sysfilesystem.m delete mode 100644 SDL2-2.0.12/src/haptic/windows/SDL_dinputhaptic_c.h delete mode 100644 SDL2-2.0.12/src/haptic/windows/SDL_xinputhaptic_c.h delete mode 100644 SDL2-2.0.12/src/hidapi/SDL_hidapi.c delete mode 100644 SDL2-2.0.12/src/hidapi/linux/hid.cpp delete mode 100644 SDL2-2.0.12/src/hidapi/windows/ddk_build/makefile delete mode 100644 SDL2-2.0.12/src/joystick/SDL_gamecontroller.c delete mode 100644 SDL2-2.0.12/src/joystick/SDL_joystick.c delete mode 100644 SDL2-2.0.12/src/joystick/SDL_joystick_c.h delete mode 100644 SDL2-2.0.12/src/joystick/SDL_sysjoystick.h delete mode 100644 SDL2-2.0.12/src/joystick/bsd/SDL_sysjoystick.c delete mode 100644 SDL2-2.0.12/src/joystick/dummy/SDL_sysjoystick.c delete mode 100644 SDL2-2.0.12/src/joystick/hidapi/SDL_hidapi_gamecube.c delete mode 100644 SDL2-2.0.12/src/joystick/hidapi/SDL_hidapi_ps4.c delete mode 100644 SDL2-2.0.12/src/joystick/hidapi/SDL_hidapi_steam.c delete mode 100644 SDL2-2.0.12/src/joystick/hidapi/SDL_hidapi_switch.c delete mode 100644 SDL2-2.0.12/src/joystick/hidapi/SDL_hidapi_xbox360.c delete mode 100644 SDL2-2.0.12/src/joystick/hidapi/SDL_hidapi_xboxone.c delete mode 100644 SDL2-2.0.12/src/joystick/hidapi/SDL_hidapijoystick.c delete mode 100644 SDL2-2.0.12/src/joystick/hidapi/SDL_hidapijoystick_c.h delete mode 100644 SDL2-2.0.12/src/joystick/iphoneos/SDL_sysjoystick.m delete mode 100644 SDL2-2.0.12/src/joystick/linux/SDL_sysjoystick.c delete mode 100644 SDL2-2.0.12/src/joystick/psp/SDL_sysjoystick.c delete mode 100644 SDL2-2.0.12/src/joystick/sort_controllers.py delete mode 100644 SDL2-2.0.12/src/joystick/usb_ids.h delete mode 100644 SDL2-2.0.12/src/joystick/windows/SDL_mmjoystick.c delete mode 100644 SDL2-2.0.12/src/joystick/windows/SDL_windowsjoystick.c delete mode 100644 SDL2-2.0.12/src/main/uikit/SDL_uikit_main.c delete mode 100644 SDL2-2.0.12/src/render/SDL_render.c delete mode 100644 SDL2-2.0.12/src/render/SDL_sysrender.h delete mode 100644 SDL2-2.0.12/src/render/metal/SDL_shaders_metal_ios.h delete mode 100644 SDL2-2.0.12/src/render/metal/SDL_shaders_metal_osx.h delete mode 100644 SDL2-2.0.12/src/render/metal/SDL_shaders_metal_tvos.h delete mode 100644 SDL2-2.0.12/src/render/opengles2/SDL_shaders_gles2.c delete mode 100644 SDL2-2.0.12/src/render/opengles2/SDL_shaders_gles2.h delete mode 100644 SDL2-2.0.12/src/render/psp/SDL_render_psp.c delete mode 100644 SDL2-2.0.12/src/render/software/SDL_draw.h delete mode 100644 SDL2-2.0.12/src/stdlib/SDL_iconv.c delete mode 100644 SDL2-2.0.12/src/test/SDL_test_compare.c delete mode 100644 SDL2-2.0.12/src/test/SDL_test_crc32.c delete mode 100644 SDL2-2.0.12/src/test/SDL_test_font.c delete mode 100644 SDL2-2.0.12/src/test/SDL_test_imageBlit.c delete mode 100644 SDL2-2.0.12/src/test/SDL_test_imageBlitBlend.c delete mode 100644 SDL2-2.0.12/src/test/SDL_test_imageFace.c delete mode 100644 SDL2-2.0.12/src/test/SDL_test_imagePrimitives.c delete mode 100644 SDL2-2.0.12/src/test/SDL_test_imagePrimitivesBlend.c delete mode 100644 SDL2-2.0.12/src/test/SDL_test_md5.c delete mode 100644 SDL2-2.0.12/src/test/SDL_test_random.c delete mode 100644 SDL2-2.0.12/src/thread/psp/SDL_syscond.c delete mode 100644 SDL2-2.0.12/src/thread/psp/SDL_sysmutex.c delete mode 100644 SDL2-2.0.12/src/thread/pthread/SDL_systhread.c delete mode 100644 SDL2-2.0.12/src/thread/windows/SDL_sysmutex.c delete mode 100644 SDL2-2.0.12/src/thread/windows/SDL_syssem.c delete mode 100644 SDL2-2.0.12/src/video/SDL_blit.h delete mode 100644 SDL2-2.0.12/src/video/SDL_blit_0.c delete mode 100644 SDL2-2.0.12/src/video/SDL_shape.c delete mode 100644 SDL2-2.0.12/src/video/SDL_stretch.c delete mode 100644 SDL2-2.0.12/src/video/android/SDL_androidkeyboard.c delete mode 100644 SDL2-2.0.12/src/video/cocoa/SDL_cocoakeyboard.m delete mode 100644 SDL2-2.0.12/src/video/cocoa/SDL_cocoamousetap.m delete mode 100644 SDL2-2.0.12/src/video/cocoa/SDL_cocoashape.m delete mode 100644 SDL2-2.0.12/src/video/emscripten/SDL_emscriptenevents.c delete mode 100644 SDL2-2.0.12/src/video/haiku/SDL_BWin.h delete mode 100644 SDL2-2.0.12/src/video/haiku/SDL_bframebuffer.cc delete mode 100644 SDL2-2.0.12/src/video/khronos/GLES2/gl2platform.h delete mode 100644 SDL2-2.0.12/src/video/khronos/vulkan/vulkan.hpp delete mode 100644 SDL2-2.0.12/src/video/khronos/vulkan/vulkan_core.h delete mode 100644 SDL2-2.0.12/src/video/khronos/vulkan/vulkan_fuchsia.h delete mode 100644 SDL2-2.0.12/src/video/khronos/vulkan/vulkan_mir.h delete mode 100644 SDL2-2.0.12/src/video/kmsdrm/SDL_kmsdrmmouse.c delete mode 100644 SDL2-2.0.12/src/video/kmsdrm/SDL_kmsdrmopengles.c delete mode 100644 SDL2-2.0.12/src/video/kmsdrm/SDL_kmsdrmvideo.c delete mode 100644 SDL2-2.0.12/src/video/offscreen/SDL_offscreenopengl.h delete mode 100644 SDL2-2.0.12/src/video/psp/SDL_pspgl.c delete mode 100644 SDL2-2.0.12/src/video/uikit/SDL_uikitevents.m delete mode 100644 SDL2-2.0.12/src/video/uikit/SDL_uikitview.m delete mode 100644 SDL2-2.0.12/src/video/uikit/keyinfotable.h delete mode 100644 SDL2-2.0.12/src/video/wayland/SDL_waylandclipboard.c delete mode 100644 SDL2-2.0.12/src/video/wayland/SDL_waylanddatamanager.c delete mode 100644 SDL2-2.0.12/src/video/wayland/SDL_waylanddatamanager.h delete mode 100644 SDL2-2.0.12/src/video/wayland/SDL_waylanddyn.h delete mode 100644 SDL2-2.0.12/src/video/wayland/SDL_waylandevents.c delete mode 100644 SDL2-2.0.12/src/video/wayland/SDL_waylandevents_c.h delete mode 100644 SDL2-2.0.12/src/video/wayland/SDL_waylandmouse.c delete mode 100644 SDL2-2.0.12/src/video/wayland/SDL_waylandopengles.c delete mode 100644 SDL2-2.0.12/src/video/wayland/SDL_waylandsym.h delete mode 100644 SDL2-2.0.12/src/video/wayland/SDL_waylandtouch.h delete mode 100644 SDL2-2.0.12/src/video/wayland/SDL_waylandvideo.c delete mode 100644 SDL2-2.0.12/src/video/wayland/SDL_waylandwindow.c delete mode 100644 SDL2-2.0.12/src/video/wayland/SDL_waylandwindow.h delete mode 100644 SDL2-2.0.12/src/video/windows/SDL_vkeys.h delete mode 100644 SDL2-2.0.12/src/video/windows/SDL_windowsevents.c delete mode 100644 SDL2-2.0.12/src/video/windows/SDL_windowsmodes.c delete mode 100644 SDL2-2.0.12/src/video/windows/SDL_windowsmouse.c delete mode 100644 SDL2-2.0.12/src/video/windows/SDL_windowsopengl.h delete mode 100644 SDL2-2.0.12/src/video/windows/SDL_windowstaskdialog.h delete mode 100644 SDL2-2.0.12/src/video/windows/SDL_windowsvideo.c delete mode 100644 SDL2-2.0.12/src/video/windows/SDL_windowsvideo.h delete mode 100644 SDL2-2.0.12/src/video/windows/SDL_windowswindow.c delete mode 100644 SDL2-2.0.12/src/video/winrt/SDL_winrtkeyboard.cpp delete mode 100644 SDL2-2.0.12/src/video/x11/SDL_x11events.c delete mode 100644 SDL2-2.0.12/src/video/x11/SDL_x11keyboard.c delete mode 100644 SDL2-2.0.12/src/video/x11/SDL_x11messagebox.c delete mode 100644 SDL2-2.0.12/src/video/x11/SDL_x11modes.c delete mode 100644 SDL2-2.0.12/src/video/x11/SDL_x11xinput2.c delete mode 100644 SDL2-2.0.12/src/video/x11/edid.h delete mode 100644 SDL2-2.0.12/src/video/yuv2rgb/yuv_rgb.h delete mode 100644 SDL2-2.0.12/test/CMakeLists.txt delete mode 100644 SDL2-2.0.12/test/COPYING delete mode 100644 SDL2-2.0.12/test/Makefile.in delete mode 100644 SDL2-2.0.12/test/Makefile.os2 delete mode 100644 SDL2-2.0.12/test/README delete mode 100644 SDL2-2.0.12/test/acinclude.m4 delete mode 100644 SDL2-2.0.12/test/autogen.sh delete mode 100644 SDL2-2.0.12/test/button.bmp delete mode 100644 SDL2-2.0.12/test/checkkeys.c delete mode 100644 SDL2-2.0.12/test/configure delete mode 100644 SDL2-2.0.12/test/configure.ac delete mode 100644 SDL2-2.0.12/test/controllermap.bmp delete mode 100644 SDL2-2.0.12/test/controllermap.c delete mode 100644 SDL2-2.0.12/test/emscripten/joystick-pre.js delete mode 100644 SDL2-2.0.12/test/gcc-fat.sh delete mode 100644 SDL2-2.0.12/test/icon.bmp delete mode 100644 SDL2-2.0.12/test/loopwave.c delete mode 100644 SDL2-2.0.12/test/loopwavequeue.c delete mode 100644 SDL2-2.0.12/test/moose.dat delete mode 100644 SDL2-2.0.12/test/nacl/Makefile delete mode 100644 SDL2-2.0.12/test/nacl/background.js delete mode 100644 SDL2-2.0.12/test/nacl/common.js delete mode 100644 SDL2-2.0.12/test/nacl/index.html delete mode 100644 SDL2-2.0.12/test/nacl/manifest.json delete mode 100644 SDL2-2.0.12/test/picture.xbm delete mode 100644 SDL2-2.0.12/test/relative_mode.markdown delete mode 100644 SDL2-2.0.12/test/sample.bmp delete mode 100644 SDL2-2.0.12/test/sample.wav delete mode 100644 SDL2-2.0.12/test/shapes/p01_shape24.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p01_shape32alpha.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p01_shape8.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p02_shape24.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p02_shape32alpha.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p02_shape8.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p03_shape24.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p03_shape8.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p04_shape1.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p04_shape24.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p04_shape32alpha.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p04_shape8.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p05_shape8.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p06_shape1alpha.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p06_shape24.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p06_shape32alpha.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p06_shape8.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p07_shape24.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p07_shape32alpha.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p07_shape8.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p08_shape24.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p08_shape32alpha.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p08_shape8.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p09_shape24.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p09_shape32alpha.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p09_shape8.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p10_shape1.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p10_shape24.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p10_shape32alpha.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p10_shape8.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p11_shape24.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p11_shape32alpha.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p11_shape8.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p12_shape24.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p12_shape8.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p13_shape24.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p13_shape32alpha.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p13_shape8.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p14_shape24.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p14_shape8.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p15_shape24.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p15_shape32alpha.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p15_shape8.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p16_shape1.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p16_shape24.bmp delete mode 100644 SDL2-2.0.12/test/shapes/p16_shape8.bmp delete mode 100644 SDL2-2.0.12/test/shapes/trollface_24.bmp delete mode 100644 SDL2-2.0.12/test/shapes/trollface_32alpha.bmp delete mode 100644 SDL2-2.0.12/test/testatomic.c delete mode 100644 SDL2-2.0.12/test/testaudiocapture.c delete mode 100644 SDL2-2.0.12/test/testaudiohotplug.c delete mode 100644 SDL2-2.0.12/test/testaudioinfo.c delete mode 100644 SDL2-2.0.12/test/testautomation.c delete mode 100644 SDL2-2.0.12/test/testautomation_audio.c delete mode 100644 SDL2-2.0.12/test/testautomation_clipboard.c delete mode 100644 SDL2-2.0.12/test/testautomation_events.c delete mode 100644 SDL2-2.0.12/test/testautomation_hints.c delete mode 100644 SDL2-2.0.12/test/testautomation_keyboard.c delete mode 100644 SDL2-2.0.12/test/testautomation_main.c delete mode 100644 SDL2-2.0.12/test/testautomation_mouse.c delete mode 100644 SDL2-2.0.12/test/testautomation_pixels.c delete mode 100644 SDL2-2.0.12/test/testautomation_platform.c delete mode 100644 SDL2-2.0.12/test/testautomation_rect.c delete mode 100644 SDL2-2.0.12/test/testautomation_render.c delete mode 100644 SDL2-2.0.12/test/testautomation_rwops.c delete mode 100644 SDL2-2.0.12/test/testautomation_sdltest.c delete mode 100644 SDL2-2.0.12/test/testautomation_stdlib.c delete mode 100644 SDL2-2.0.12/test/testautomation_suites.h delete mode 100644 SDL2-2.0.12/test/testautomation_surface.c delete mode 100644 SDL2-2.0.12/test/testautomation_syswm.c delete mode 100644 SDL2-2.0.12/test/testautomation_timer.c delete mode 100644 SDL2-2.0.12/test/testautomation_video.c delete mode 100644 SDL2-2.0.12/test/testbounds.c delete mode 100644 SDL2-2.0.12/test/testcustomcursor.c delete mode 100644 SDL2-2.0.12/test/testdisplayinfo.c delete mode 100644 SDL2-2.0.12/test/testdraw2.c delete mode 100644 SDL2-2.0.12/test/testdrawchessboard.c delete mode 100644 SDL2-2.0.12/test/testdropfile.c delete mode 100644 SDL2-2.0.12/test/testerror.c delete mode 100644 SDL2-2.0.12/test/testfile.c delete mode 100644 SDL2-2.0.12/test/testfilesystem.c delete mode 100644 SDL2-2.0.12/test/testgamecontroller.c delete mode 100644 SDL2-2.0.12/test/testgesture.c delete mode 100644 SDL2-2.0.12/test/testgl2.c delete mode 100644 SDL2-2.0.12/test/testgles.c delete mode 100644 SDL2-2.0.12/test/testgles2.c delete mode 100644 SDL2-2.0.12/test/testhaptic.c delete mode 100644 SDL2-2.0.12/test/testhittesting.c delete mode 100644 SDL2-2.0.12/test/testhotplug.c delete mode 100644 SDL2-2.0.12/test/testiconv.c delete mode 100644 SDL2-2.0.12/test/testime.c delete mode 100644 SDL2-2.0.12/test/testintersections.c delete mode 100644 SDL2-2.0.12/test/testjoystick.c delete mode 100644 SDL2-2.0.12/test/testkeys.c delete mode 100644 SDL2-2.0.12/test/testloadso.c delete mode 100644 SDL2-2.0.12/test/testlock.c delete mode 100644 SDL2-2.0.12/test/testmessage.c delete mode 100644 SDL2-2.0.12/test/testmultiaudio.c delete mode 100644 SDL2-2.0.12/test/testnative.c delete mode 100644 SDL2-2.0.12/test/testnative.h delete mode 100644 SDL2-2.0.12/test/testnativecocoa.m delete mode 100644 SDL2-2.0.12/test/testnativew32.c delete mode 100644 SDL2-2.0.12/test/testnativex11.c delete mode 100644 SDL2-2.0.12/test/testoffscreen.c delete mode 100644 SDL2-2.0.12/test/testoverlay2.c delete mode 100644 SDL2-2.0.12/test/testplatform.c delete mode 100644 SDL2-2.0.12/test/testpower.c delete mode 100644 SDL2-2.0.12/test/testqsort.c delete mode 100644 SDL2-2.0.12/test/testrelative.c delete mode 100644 SDL2-2.0.12/test/testrendercopyex.c delete mode 100644 SDL2-2.0.12/test/testrendertarget.c delete mode 100644 SDL2-2.0.12/test/testresample.c delete mode 100644 SDL2-2.0.12/test/testrumble.c delete mode 100644 SDL2-2.0.12/test/testscale.c delete mode 100644 SDL2-2.0.12/test/testsem.c delete mode 100644 SDL2-2.0.12/test/testsensor.c delete mode 100644 SDL2-2.0.12/test/testshader.c delete mode 100644 SDL2-2.0.12/test/testshape.c delete mode 100644 SDL2-2.0.12/test/testspriteminimal.c delete mode 100644 SDL2-2.0.12/test/teststreaming.c delete mode 100644 SDL2-2.0.12/test/testthread.c delete mode 100644 SDL2-2.0.12/test/testtimer.c delete mode 100644 SDL2-2.0.12/test/testver.c delete mode 100644 SDL2-2.0.12/test/testviewport.c delete mode 100644 SDL2-2.0.12/test/testvulkan.c delete mode 100644 SDL2-2.0.12/test/testwm2.c delete mode 100644 SDL2-2.0.12/test/testyuv.bmp delete mode 100644 SDL2-2.0.12/test/testyuv.c delete mode 100644 SDL2-2.0.12/test/testyuv_cvt.c delete mode 100644 SDL2-2.0.12/test/testyuv_cvt.h delete mode 100644 SDL2-2.0.12/test/torturethread.c delete mode 100644 SDL2-2.0.12/test/utf8.txt delete mode 100644 SDL2-2.0.12/wayland-protocols/org-kde-kwin-server-decoration-manager.xml delete mode 100644 SDL2-2.0.12/wayland-protocols/xdg-shell-unstable-v6.xml rename {SDL2-2.0.12 => SDL2-2.30.5}/Android.mk (86%) rename {SDL2-2.0.12 => SDL2-2.30.5}/BUGS.txt (58%) create mode 100644 SDL2-2.30.5/CMakeLists.txt rename {SDL2-2.0.12 => SDL2-2.30.5}/CREDITS.txt (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/INSTALL.txt (57%) rename SDL2-2.0.12/COPYING.txt => SDL2-2.30.5/LICENSE.txt (88%) rename {SDL2-2.0.12 => SDL2-2.30.5}/Makefile.in (82%) rename {SDL2-2.0.12 => SDL2-2.30.5}/Makefile.minimal (59%) create mode 100644 SDL2-2.30.5/Makefile.os2 rename {SDL2-2.0.12 => SDL2-2.30.5}/Makefile.pandora (88%) create mode 100644 SDL2-2.30.5/Makefile.w32 rename {SDL2-2.0.12 => SDL2-2.30.5}/README-SDL.txt (100%) rename SDL2-2.0.12/README.txt => SDL2-2.30.5/README.md (69%) rename {SDL2-2.0.12 => SDL2-2.30.5}/SDL2.spec (97%) rename {SDL2-2.0.12 => SDL2-2.30.5}/SDL2.spec.in (98%) create mode 100644 SDL2-2.30.5/SDL2Config.cmake.in rename {SDL2-2.0.12 => SDL2-2.30.5}/TODO.txt (88%) create mode 100644 SDL2-2.30.5/VERSION.txt create mode 100644 SDL2-2.30.5/VisualC-GDK/SDL.sln create mode 100644 SDL2-2.30.5/VisualC-GDK/SDL/SDL.vcxproj create mode 100644 SDL2-2.30.5/VisualC-GDK/SDL/SDL.vcxproj.filters create mode 100644 SDL2-2.30.5/VisualC-GDK/SDLmain/SDLmain.vcxproj create mode 100644 SDL2-2.30.5/VisualC-GDK/SDLtest/SDLtest.vcxproj create mode 100644 SDL2-2.30.5/VisualC-GDK/clean.sh create mode 100644 SDL2-2.30.5/VisualC-GDK/logos/Logo100x100.png create mode 100644 SDL2-2.30.5/VisualC-GDK/logos/Logo150x150.png create mode 100644 SDL2-2.30.5/VisualC-GDK/logos/Logo44x44.png create mode 100644 SDL2-2.30.5/VisualC-GDK/logos/Logo480x480.png rename SDL2-2.0.12/test/axis.bmp => SDL2-2.30.5/VisualC-GDK/logos/SplashScreenImage.png (58%) create mode 100644 SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_Colors.hlsl create mode 100644 SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_NV12_BT601.hlsl create mode 100644 SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_NV12_BT709.hlsl create mode 100644 SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_NV12_JPEG.hlsl create mode 100644 SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_NV21_BT601.hlsl create mode 100644 SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_NV21_BT709.hlsl create mode 100644 SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_NV21_JPEG.hlsl create mode 100644 SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_Textures.hlsl create mode 100644 SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_YUV_BT601.hlsl create mode 100644 SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_YUV_BT709.hlsl create mode 100644 SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_YUV_JPEG.hlsl create mode 100644 SDL2-2.30.5/VisualC-GDK/shaders/D3D12_VertexShader.hlsl create mode 100644 SDL2-2.30.5/VisualC-GDK/shaders/buildshaders.bat create mode 100644 SDL2-2.30.5/VisualC-GDK/tests/testgamecontroller/PackageLayout.xml create mode 100644 SDL2-2.30.5/VisualC-GDK/tests/testgamecontroller/testgamecontroller.vcxproj create mode 100644 SDL2-2.30.5/VisualC-GDK/tests/testgamecontroller/testgamecontroller.vcxproj.filters create mode 100644 SDL2-2.30.5/VisualC-GDK/tests/testgamecontroller/wingdk/MicrosoftGame.config create mode 100644 SDL2-2.30.5/VisualC-GDK/tests/testgamecontroller/xboxone/MicrosoftGame.config create mode 100644 SDL2-2.30.5/VisualC-GDK/tests/testgamecontroller/xboxseries/MicrosoftGame.config create mode 100644 SDL2-2.30.5/VisualC-GDK/tests/testgdk/PackageLayout.xml rename SDL2-2.0.12/test/testsprite2.c => SDL2-2.30.5/VisualC-GDK/tests/testgdk/src/testgdk.cpp (54%) create mode 100644 SDL2-2.30.5/VisualC-GDK/tests/testgdk/testgdk.vcxproj create mode 100644 SDL2-2.30.5/VisualC-GDK/tests/testgdk/testgdk.vcxproj.filters create mode 100644 SDL2-2.30.5/VisualC-GDK/tests/testgdk/wingdk/MicrosoftGame.config create mode 100644 SDL2-2.30.5/VisualC-GDK/tests/testgdk/xboxone/MicrosoftGame.config create mode 100644 SDL2-2.30.5/VisualC-GDK/tests/testgdk/xboxseries/MicrosoftGame.config create mode 100644 SDL2-2.30.5/VisualC-GDK/tests/testsprite2/PackageLayout.xml create mode 100644 SDL2-2.30.5/VisualC-GDK/tests/testsprite2/testsprite2.vcxproj create mode 100644 SDL2-2.30.5/VisualC-GDK/tests/testsprite2/testsprite2.vcxproj.filters create mode 100644 SDL2-2.30.5/VisualC-GDK/tests/testsprite2/wingdk/MicrosoftGame.config create mode 100644 SDL2-2.30.5/VisualC-GDK/tests/testsprite2/xboxone/MicrosoftGame.config create mode 100644 SDL2-2.30.5/VisualC-GDK/tests/testsprite2/xboxseries/MicrosoftGame.config rename {SDL2-2.0.12/VisualC-WinRT/UWP_VS2015 => SDL2-2.30.5/VisualC-WinRT}/SDL-UWP.sln (79%) create mode 100644 SDL2-2.30.5/VisualC-WinRT/SDL-UWP.vcxproj create mode 100644 SDL2-2.30.5/VisualC-WinRT/SDL-UWP.vcxproj.filters rename {SDL2-2.0.12 => SDL2-2.30.5}/VisualC/SDL.sln (87%) rename {SDL2-2.0.12 => SDL2-2.30.5}/VisualC/SDL/SDL.vcxproj (80%) create mode 100644 SDL2-2.30.5/VisualC/SDL/SDL.vcxproj.filters rename {SDL2-2.0.12 => SDL2-2.30.5}/VisualC/SDLmain/SDLmain.vcxproj (94%) rename {SDL2-2.0.12 => SDL2-2.30.5}/VisualC/SDLtest/SDLtest.vcxproj (93%) rename {SDL2-2.0.12 => SDL2-2.30.5}/VisualC/clean.sh (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/VisualC/tests/checkkeys/checkkeys.vcxproj (92%) rename {SDL2-2.0.12 => SDL2-2.30.5}/VisualC/tests/controllermap/controllermap.vcxproj (85%) rename {SDL2-2.0.12 => SDL2-2.30.5}/VisualC/tests/loopwave/loopwave.vcxproj (92%) rename {SDL2-2.0.12 => SDL2-2.30.5}/VisualC/tests/testatomic/testatomic.vcxproj (93%) rename {SDL2-2.0.12 => SDL2-2.30.5}/VisualC/tests/testautomation/testautomation.vcxproj (92%) rename {SDL2-2.0.12 => SDL2-2.30.5}/VisualC/tests/testdraw2/testdraw2.vcxproj (93%) rename {SDL2-2.0.12 => SDL2-2.30.5}/VisualC/tests/testfile/testfile.vcxproj (93%) rename {SDL2-2.0.12 => SDL2-2.30.5}/VisualC/tests/testgamecontroller/testgamecontroller.vcxproj (83%) rename {SDL2-2.0.12 => SDL2-2.30.5}/VisualC/tests/testgesture/testgesture.vcxproj (93%) rename {SDL2-2.0.12 => SDL2-2.30.5}/VisualC/tests/testgl2/testgl2.vcxproj (94%) rename {SDL2-2.0.12 => SDL2-2.30.5}/VisualC/tests/testgles2/testgles2.vcxproj (93%) rename {SDL2-2.0.12 => SDL2-2.30.5}/VisualC/tests/testjoystick/testjoystick.vcxproj (93%) rename {SDL2-2.0.12 => SDL2-2.30.5}/VisualC/tests/testoverlay2/testoverlay2.vcxproj (92%) rename {SDL2-2.0.12 => SDL2-2.30.5}/VisualC/tests/testplatform/testplatform.vcxproj (94%) rename {SDL2-2.0.12 => SDL2-2.30.5}/VisualC/tests/testpower/testpower.vcxproj (93%) rename {SDL2-2.0.12 => SDL2-2.30.5}/VisualC/tests/testrendertarget/testrendertarget.vcxproj (92%) rename {SDL2-2.0.12 => SDL2-2.30.5}/VisualC/tests/testrumble/testrumble.vcxproj (93%) rename {SDL2-2.0.12 => SDL2-2.30.5}/VisualC/tests/testscale/testscale.vcxproj (92%) create mode 100644 SDL2-2.30.5/VisualC/tests/testsensor/testsensor.vcxproj rename {SDL2-2.0.12 => SDL2-2.30.5}/VisualC/tests/testshape/testshape.vcxproj (93%) rename {SDL2-2.0.12 => SDL2-2.30.5}/VisualC/tests/testsprite2/testsprite2.vcxproj (92%) create mode 100644 SDL2-2.30.5/VisualC/tests/testsurround/testsurround.vcxproj rename {SDL2-2.0.12 => SDL2-2.30.5}/VisualC/tests/testvulkan/testvulkan.vcxproj (93%) create mode 100644 SDL2-2.30.5/VisualC/tests/testwm2/testwm2.vcxproj rename {SDL2-2.0.12 => SDL2-2.30.5}/VisualC/tests/testyuv/testyuv.vcxproj (93%) rename {SDL2-2.0.12 => SDL2-2.30.5}/VisualC/visualtest/unittest/testquit/testquit_VS2012.vcxproj (92%) rename {SDL2-2.0.12 => SDL2-2.30.5}/VisualC/visualtest/visualtest_VS2012.vcxproj (90%) rename {SDL2-2.0.12 => SDL2-2.30.5}/WhatsNew.txt (55%) rename {SDL2-2.0.12 => SDL2-2.30.5}/Xcode-iOS/Demos/Default.png (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/Xcode-iOS/Demos/Demos.xcodeproj/project.pbxproj (50%) rename {SDL2-2.0.12 => SDL2-2.30.5}/Xcode-iOS/Demos/Icon.png (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/Xcode-iOS/Demos/README (100%) create mode 100644 SDL2-2.30.5/Xcode-iOS/Demos/config.xcconfig rename {SDL2-2.0.12 => SDL2-2.30.5}/Xcode-iOS/Demos/data/bitmapfont/kromasky_16x16.bmp (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/Xcode-iOS/Demos/data/bitmapfont/license.txt (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/Xcode-iOS/Demos/data/drums/ds_brush_snare.wav (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/Xcode-iOS/Demos/data/drums/ds_china.wav (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/Xcode-iOS/Demos/data/drums/ds_kick_big_amb.wav (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/Xcode-iOS/Demos/data/drums/ds_loose_skin_mute.wav (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/Xcode-iOS/Demos/data/icon.bmp (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/Xcode-iOS/Demos/data/ship.bmp (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/Xcode-iOS/Demos/data/space.bmp (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/Xcode-iOS/Demos/data/stroke.bmp (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/Xcode-iOS/Demos/iOS Launch Screen.storyboard (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/Xcode-iOS/Demos/src/accelerometer.c (96%) rename {SDL2-2.0.12 => SDL2-2.30.5}/Xcode-iOS/Demos/src/common.c (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/Xcode-iOS/Demos/src/common.h (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/Xcode-iOS/Demos/src/fireworks.c (94%) rename {SDL2-2.0.12 => SDL2-2.30.5}/Xcode-iOS/Demos/src/happy.c (98%) rename {SDL2-2.0.12 => SDL2-2.30.5}/Xcode-iOS/Demos/src/keyboard.c (99%) rename {SDL2-2.0.12 => SDL2-2.30.5}/Xcode-iOS/Demos/src/mixer.c (98%) rename {SDL2-2.0.12 => SDL2-2.30.5}/Xcode-iOS/Demos/src/rectangles.c (98%) rename {SDL2-2.0.12 => SDL2-2.30.5}/Xcode-iOS/Demos/src/touch.c (72%) rename {SDL2-2.0.12 => SDL2-2.30.5}/Xcode/SDL/Info-Framework.plist (94%) rename {SDL2-2.0.12 => SDL2-2.30.5}/Xcode/SDL/SDL.xcodeproj/project.pbxproj (83%) rename {SDL2-2.0.12 => SDL2-2.30.5}/Xcode/SDL/SDL.xcodeproj/xcshareddata/xcschemes/Framework-iOS.xcscheme (100%) rename SDL2-2.0.12/Xcode/SDL/SDL.xcodeproj/xcshareddata/xcschemes/Framework.xcscheme => SDL2-2.30.5/Xcode/SDL/SDL.xcodeproj/xcshareddata/xcschemes/xcFramework-iOS.xcscheme (90%) rename {SDL2-2.0.12/Xcode/SDL/hidapi => SDL2-2.30.5/Xcode/SDL/SDL2}/Info.plist (94%) rename {SDL2-2.0.12 => SDL2-2.30.5}/Xcode/SDL/pkg-support/SDL.info (94%) rename {SDL2-2.0.12 => SDL2-2.30.5}/Xcode/SDL/pkg-support/resources/License.txt (93%) rename {SDL2-2.0.12 => SDL2-2.30.5}/Xcode/SDL/pkg-support/resources/ReadMe.txt (69%) rename {SDL2-2.0.12 => SDL2-2.30.5}/Xcode/SDL/pkg-support/resources/SDL_DS_Store (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/Xcode/SDL/pkg-support/sdl_logo.pdf (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/Xcode/SDLTest/SDLTest.xcodeproj/project.pbxproj (51%) rename {SDL2-2.0.12 => SDL2-2.30.5}/Xcode/SDLTest/TestDropFile-Info.plist (97%) create mode 100644 SDL2-2.30.5/Xcode/SDLTest/config.xcconfig rename {SDL2-2.0.12 => SDL2-2.30.5}/Xcode/XcodeDocSet/Doxyfile (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/acinclude/ac_check_define.m4 (77%) rename {SDL2-2.0.12 => SDL2-2.30.5}/acinclude/alsa.m4 (94%) rename {SDL2-2.0.12 => SDL2-2.30.5}/acinclude/ax_check_compiler_flags.m4 (100%) create mode 100644 SDL2-2.30.5/acinclude/ax_compute_relative_paths.m4 rename {SDL2-2.0.12 => SDL2-2.30.5}/acinclude/ax_gcc_archflag.m4 (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/acinclude/ax_gcc_x86_cpuid.m4 (100%) create mode 100644 SDL2-2.30.5/acinclude/ax_normalize_path.m4 create mode 100644 SDL2-2.30.5/acinclude/ax_recursive_eval.m4 rename {SDL2-2.0.12 => SDL2-2.30.5}/acinclude/esd.m4 (75%) rename {SDL2-2.0.12 => SDL2-2.30.5}/acinclude/libtool.m4 (71%) rename {SDL2-2.0.12 => SDL2-2.30.5}/acinclude/ltoptions.m4 (73%) rename {SDL2-2.0.12 => SDL2-2.30.5}/acinclude/ltsugar.m4 (95%) rename {SDL2-2.0.12 => SDL2-2.30.5}/acinclude/ltversion.m4 (68%) rename {SDL2-2.0.12 => SDL2-2.30.5}/acinclude/lt~obsolete.m4 (98%) create mode 100644 SDL2-2.30.5/acinclude/pkg.m4 rename {SDL2-2.0.12 => SDL2-2.30.5}/android-project/app/build.gradle (78%) rename {SDL2-2.0.12 => SDL2-2.30.5}/android-project/app/jni/Android.mk (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/android-project/app/jni/Application.mk (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/android-project/app/jni/CMakeLists.txt (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/android-project/app/jni/src/Android.mk (82%) rename {SDL2-2.0.12 => SDL2-2.30.5}/android-project/app/jni/src/CMakeLists.txt (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/android-project/app/proguard-rules.pro (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/android-project/app/src/main/AndroidManifest.xml (74%) rename {SDL2-2.0.12 => SDL2-2.30.5}/android-project/app/src/main/java/org/libsdl/app/HIDDevice.java (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/android-project/app/src/main/java/org/libsdl/app/HIDDeviceBLESteamController.java (99%) rename {SDL2-2.0.12 => SDL2-2.30.5}/android-project/app/src/main/java/org/libsdl/app/HIDDeviceManager.java (89%) rename {SDL2-2.0.12 => SDL2-2.30.5}/android-project/app/src/main/java/org/libsdl/app/HIDDeviceUSB.java (97%) rename {SDL2-2.0.12 => SDL2-2.30.5}/android-project/app/src/main/java/org/libsdl/app/SDL.java (74%) rename {SDL2-2.0.12 => SDL2-2.30.5}/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java (65%) rename {SDL2-2.0.12 => SDL2-2.30.5}/android-project/app/src/main/java/org/libsdl/app/SDLAudioManager.java (67%) rename {SDL2-2.0.12 => SDL2-2.30.5}/android-project/app/src/main/java/org/libsdl/app/SDLControllerManager.java (72%) create mode 100644 SDL2-2.30.5/android-project/app/src/main/java/org/libsdl/app/SDLSurface.java rename {SDL2-2.0.12 => SDL2-2.30.5}/android-project/app/src/main/res/mipmap-hdpi/ic_launcher.png (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/android-project/app/src/main/res/mipmap-mdpi/ic_launcher.png (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/android-project/app/src/main/res/mipmap-xhdpi/ic_launcher.png (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/android-project/app/src/main/res/mipmap-xxhdpi/ic_launcher.png (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/android-project/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/android-project/app/src/main/res/values/colors.xml (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/android-project/app/src/main/res/values/strings.xml (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/android-project/app/src/main/res/values/styles.xml (51%) rename {SDL2-2.0.12 => SDL2-2.30.5}/android-project/build.gradle (80%) rename {SDL2-2.0.12 => SDL2-2.30.5}/android-project/gradle.properties (100%) create mode 100644 SDL2-2.30.5/android-project/gradle/wrapper/gradle-wrapper.jar rename {SDL2-2.0.12 => SDL2-2.30.5}/android-project/gradle/wrapper/gradle-wrapper.properties (79%) rename {SDL2-2.0.12 => SDL2-2.30.5}/android-project/gradlew (96%) rename {SDL2-2.0.12 => SDL2-2.30.5}/android-project/gradlew.bat (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/android-project/settings.gradle (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/autogen.sh (51%) create mode 100644 SDL2-2.30.5/build-scripts/android-prefab.sh rename {SDL2-2.0.12 => SDL2-2.30.5}/build-scripts/androidbuild.sh (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/build-scripts/androidbuildlibs.sh (68%) rename {SDL2-2.0.12 => SDL2-2.30.5}/build-scripts/checker-buildbot.sh (56%) rename SDL2-2.0.12/build-scripts/g++-fat.sh => SDL2-2.30.5/build-scripts/clang++-fat.sh (50%) rename SDL2-2.0.12/build-scripts/gcc-fat.sh => SDL2-2.30.5/build-scripts/clang-fat.sh (50%) create mode 100644 SDL2-2.30.5/build-scripts/clang-format-src.sh create mode 100644 SDL2-2.30.5/build-scripts/codechecker-buildbot.sh create mode 100644 SDL2-2.30.5/build-scripts/config.guess create mode 100644 SDL2-2.30.5/build-scripts/config.sub rename {SDL2-2.0.12 => SDL2-2.30.5}/build-scripts/emscripten-buildbot.sh (81%) create mode 100644 SDL2-2.30.5/build-scripts/fnsince.pl create mode 100644 SDL2-2.30.5/build-scripts/gen_audio_channel_conversion.c create mode 100644 SDL2-2.30.5/build-scripts/gen_audio_resampler_filter.c create mode 100644 SDL2-2.30.5/build-scripts/git-pre-push-hook.pl rename {SDL2-2.0.12 => SDL2-2.30.5}/build-scripts/install-sh (54%) rename {SDL2-2.0.12 => SDL2-2.30.5}/build-scripts/ltmain.sh (64%) rename {SDL2-2.0.12 => SDL2-2.30.5}/build-scripts/mkinstalldirs (91%) rename {SDL2-2.0.12 => SDL2-2.30.5}/build-scripts/nacl-buildbot.sh (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/build-scripts/naclbuild.sh (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/build-scripts/raspberrypi-buildbot.sh (95%) create mode 100644 SDL2-2.30.5/build-scripts/showrev.sh rename {SDL2-2.0.12 => SDL2-2.30.5}/build-scripts/strip_fPIC.sh (100%) create mode 100644 SDL2-2.30.5/build-scripts/test-versioning.sh create mode 100644 SDL2-2.30.5/build-scripts/update-copyright.sh create mode 100644 SDL2-2.30.5/build-scripts/update-version.sh create mode 100644 SDL2-2.30.5/build-scripts/updaterev.sh create mode 100644 SDL2-2.30.5/build-scripts/wikiheaders.pl create mode 100644 SDL2-2.30.5/build-scripts/windows-buildbot-zipper.bat create mode 100644 SDL2-2.30.5/cmake/test/CMakeLists.txt create mode 100644 SDL2-2.30.5/cmake/test/jni/Android.mk create mode 100644 SDL2-2.30.5/cmake/test/main_cli.c create mode 100644 SDL2-2.30.5/cmake/test/main_gui.c create mode 100644 SDL2-2.30.5/cmake/test/main_lib.c create mode 100644 SDL2-2.30.5/cmake/test/test_pkgconfig.sh create mode 100644 SDL2-2.30.5/cmake/test/test_sdlconfig.sh rename {SDL2-2.0.12 => SDL2-2.30.5}/cmake_uninstall.cmake.in (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/configure (56%) rename {SDL2-2.0.12 => SDL2-2.30.5}/configure.ac (68%) create mode 100644 SDL2-2.30.5/docs/CONTRIBUTING.md rename {SDL2-2.0.12 => SDL2-2.30.5}/docs/README-android.md (80%) create mode 100644 SDL2-2.30.5/docs/README-cmake.md rename {SDL2-2.0.12 => SDL2-2.30.5}/docs/README-directfb.md (76%) rename {SDL2-2.0.12 => SDL2-2.30.5}/docs/README-dynapi.md (77%) create mode 100644 SDL2-2.30.5/docs/README-emscripten.md create mode 100644 SDL2-2.30.5/docs/README-gdk.md rename {SDL2-2.0.12 => SDL2-2.30.5}/docs/README-gesture.md (95%) create mode 100644 SDL2-2.30.5/docs/README-git.md create mode 100644 SDL2-2.30.5/docs/README-hg.md rename {SDL2-2.0.12 => SDL2-2.30.5}/docs/README-ios.md (68%) create mode 100644 SDL2-2.30.5/docs/README-kmsbsd.md rename {SDL2-2.0.12 => SDL2-2.30.5}/docs/README-linux.md (52%) create mode 100644 SDL2-2.30.5/docs/README-macos.md create mode 100644 SDL2-2.30.5/docs/README-n3ds.md rename {SDL2-2.0.12 => SDL2-2.30.5}/docs/README-nacl.md (89%) create mode 100644 SDL2-2.30.5/docs/README-ngage.md create mode 100644 SDL2-2.30.5/docs/README-os2.md rename {SDL2-2.0.12 => SDL2-2.30.5}/docs/README-pandora.md (96%) rename {SDL2-2.0.12 => SDL2-2.30.5}/docs/README-platforms.md (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/docs/README-porting.md (100%) create mode 100644 SDL2-2.30.5/docs/README-ps2.md create mode 100644 SDL2-2.30.5/docs/README-psp.md rename {SDL2-2.0.12 => SDL2-2.30.5}/docs/README-raspberrypi.md (70%) create mode 100644 SDL2-2.30.5/docs/README-riscos.md rename {SDL2-2.0.12 => SDL2-2.30.5}/docs/README-touch.md (97%) create mode 100644 SDL2-2.30.5/docs/README-versions.md create mode 100644 SDL2-2.30.5/docs/README-visualc.md create mode 100644 SDL2-2.30.5/docs/README-vita.md rename {SDL2-2.0.12 => SDL2-2.30.5}/docs/README-wince.md (100%) create mode 100644 SDL2-2.30.5/docs/README-windows.md rename {SDL2-2.0.12 => SDL2-2.30.5}/docs/README-winrt.md (81%) rename {SDL2-2.0.12 => SDL2-2.30.5}/docs/README.md (72%) rename {SDL2-2.0.12 => SDL2-2.30.5}/docs/doxyfile (99%) create mode 100644 SDL2-2.30.5/docs/release_checklist.md create mode 100644 SDL2-2.30.5/include/SDL.h rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_assert.h (61%) rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_atomic.h (61%) create mode 100644 SDL2-2.30.5/include/SDL_audio.h rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_bits.h (88%) create mode 100644 SDL2-2.30.5/include/SDL_blendmode.h create mode 100644 SDL2-2.30.5/include/SDL_clipboard.h rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_config.h (83%) rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_config.h.in (82%) rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_config_android.h (90%) create mode 100644 SDL2-2.30.5/include/SDL_config_emscripten.h rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_config_iphoneos.h (85%) rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_config_macosx.h (89%) rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_config_minimal.h (78%) create mode 100644 SDL2-2.30.5/include/SDL_config_ngage.h rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_config_os2.h (76%) rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_config_pandora.h (92%) create mode 100644 SDL2-2.30.5/include/SDL_config_windows.h rename SDL2-2.0.12/include/SDL_config_windows.h => SDL2-2.30.5/include/SDL_config_wingdk.h (70%) rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_config_winrt.h (69%) create mode 100644 SDL2-2.30.5/include/SDL_config_xbox.h rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_copying.h (93%) create mode 100644 SDL2-2.30.5/include/SDL_cpuinfo.h rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_egl.h (56%) create mode 100644 SDL2-2.30.5/include/SDL_endian.h create mode 100644 SDL2-2.30.5/include/SDL_error.h rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_events.h (51%) create mode 100644 SDL2-2.30.5/include/SDL_filesystem.h create mode 100644 SDL2-2.30.5/include/SDL_gamecontroller.h rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_gesture.h (53%) create mode 100644 SDL2-2.30.5/include/SDL_guid.h rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_haptic.h (67%) create mode 100644 SDL2-2.30.5/include/SDL_hidapi.h create mode 100644 SDL2-2.30.5/include/SDL_hints.h create mode 100644 SDL2-2.30.5/include/SDL_joystick.h create mode 100644 SDL2-2.30.5/include/SDL_keyboard.h rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_keycode.h (95%) rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_loadso.h (60%) create mode 100644 SDL2-2.30.5/include/SDL_locale.h create mode 100644 SDL2-2.30.5/include/SDL_log.h create mode 100644 SDL2-2.30.5/include/SDL_main.h rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_messagebox.h (52%) rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_metal.h (52%) create mode 100644 SDL2-2.30.5/include/SDL_misc.h create mode 100644 SDL2-2.30.5/include/SDL_mouse.h create mode 100644 SDL2-2.30.5/include/SDL_mutex.h rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_name.h (94%) rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_opengl.h (98%) rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_opengl_glext.h (84%) rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_opengles.h (95%) rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_opengles2.h (91%) create mode 100644 SDL2-2.30.5/include/SDL_opengles2_gl2.h create mode 100644 SDL2-2.30.5/include/SDL_opengles2_gl2ext.h create mode 100644 SDL2-2.30.5/include/SDL_opengles2_gl2platform.h rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_opengles2_khrplatform.h (84%) rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_pixels.h (60%) rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_platform.h (67%) rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_power.h (56%) rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_quit.h (97%) create mode 100644 SDL2-2.30.5/include/SDL_rect.h create mode 100644 SDL2-2.30.5/include/SDL_render.h create mode 100644 SDL2-2.30.5/include/SDL_revision.h create mode 100644 SDL2-2.30.5/include/SDL_rwops.h rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_scancode.h (85%) create mode 100644 SDL2-2.30.5/include/SDL_sensor.h rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_shape.h (67%) rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_stdinc.h (67%) create mode 100644 SDL2-2.30.5/include/SDL_surface.h create mode 100644 SDL2-2.30.5/include/SDL_system.h rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_syswm.h (71%) rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_test.h (97%) rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_test_assert.h (94%) rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_test_common.h (86%) rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_test_compare.h (97%) rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_test_crc32.h (98%) create mode 100644 SDL2-2.30.5/include/SDL_test_font.h rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_test_fuzzer.h (87%) rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_test_harness.h (94%) rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_test_images.h (97%) rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_test_log.h (96%) rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_test_md5.h (98%) rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_test_memory.h (96%) rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_test_random.h (96%) create mode 100644 SDL2-2.30.5/include/SDL_thread.h create mode 100644 SDL2-2.30.5/include/SDL_timer.h rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_touch.h (56%) rename {SDL2-2.0.12 => SDL2-2.30.5}/include/SDL_types.h (94%) create mode 100644 SDL2-2.30.5/include/SDL_version.h create mode 100644 SDL2-2.30.5/include/SDL_video.h create mode 100644 SDL2-2.30.5/include/SDL_vulkan.h rename {SDL2-2.0.12 => SDL2-2.30.5}/include/begin_code.h (77%) rename {SDL2-2.0.12 => SDL2-2.30.5}/include/close_code.h (92%) create mode 100644 SDL2-2.30.5/lib/x64/SDL2.dll create mode 100644 SDL2-2.30.5/lib/x64/SDL2.lib create mode 100644 SDL2-2.30.5/lib/x64/SDL2main.lib create mode 100644 SDL2-2.30.5/lib/x64/SDL2test.lib rename {SDL2-2.0.12 => SDL2-2.30.5}/sdl2-config-version.cmake.in (81%) create mode 100644 SDL2-2.30.5/sdl2-config.cmake.in rename {SDL2-2.0.12 => SDL2-2.30.5}/sdl2-config.in (73%) rename {SDL2-2.0.12 => SDL2-2.30.5}/sdl2.m4 (89%) rename {SDL2-2.0.12 => SDL2-2.30.5}/sdl2.pc.in (66%) create mode 100644 SDL2-2.30.5/src/SDL.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/SDL_assert.c (67%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/SDL_assert_c.h (94%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/SDL_dataqueue.c (66%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/SDL_dataqueue.h (62%) create mode 100644 SDL2-2.30.5/src/SDL_error.c create mode 100644 SDL2-2.30.5/src/SDL_error_c.h create mode 100644 SDL2-2.30.5/src/SDL_guid.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/SDL_hints.c (67%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/SDL_hints_c.h (95%) create mode 100644 SDL2-2.30.5/src/SDL_internal.h create mode 100644 SDL2-2.30.5/src/SDL_list.c rename SDL2-2.0.12/src/events/SDL_sysevents.h => SDL2-2.30.5/src/SDL_list.h (68%) create mode 100644 SDL2-2.30.5/src/SDL_log.c create mode 100644 SDL2-2.30.5/src/SDL_log_c.h create mode 100644 SDL2-2.30.5/src/SDL_utils.c create mode 100644 SDL2-2.30.5/src/SDL_utils_c.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/atomic/SDL_atomic.c (64%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/atomic/SDL_spinlock.c (61%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/SDL_audio.c (60%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/SDL_audio_c.h (79%) create mode 100644 SDL2-2.30.5/src/audio/SDL_audio_channel_converters.h create mode 100644 SDL2-2.30.5/src/audio/SDL_audio_resampler_filter.h create mode 100644 SDL2-2.30.5/src/audio/SDL_audiocvt.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/SDL_audiodev.c (67%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/SDL_audiodev_c.h (87%) create mode 100644 SDL2-2.30.5/src/audio/SDL_audiotypecvt.c create mode 100644 SDL2-2.30.5/src/audio/SDL_mixer.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/SDL_sysaudio.h (78%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/SDL_wave.c (89%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/SDL_wave.h (77%) create mode 100644 SDL2-2.30.5/src/audio/aaudio/SDL_aaudio.c create mode 100644 SDL2-2.30.5/src/audio/aaudio/SDL_aaudio.h create mode 100644 SDL2-2.30.5/src/audio/aaudio/SDL_aaudiofuncs.h create mode 100644 SDL2-2.30.5/src/audio/alsa/SDL_alsa_audio.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/alsa/SDL_alsa_audio.h (93%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/android/SDL_androidaudio.c (52%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/android/SDL_androidaudio.h (87%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/arts/SDL_artsaudio.c (85%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/arts/SDL_artsaudio.h (96%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/coreaudio/SDL_coreaudio.h (78%) create mode 100644 SDL2-2.30.5/src/audio/coreaudio/SDL_coreaudio.m rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/directsound/SDL_directsound.c (61%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/directsound/SDL_directsound.h (93%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/disk/SDL_diskaudio.c (53%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/disk/SDL_diskaudio.h (92%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/dsp/SDL_dspaudio.c (80%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/dsp/SDL_dspaudio.h (88%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/dummy/SDL_dummyaudio.c (66%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/dummy/SDL_dummyaudio.h (92%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/emscripten/SDL_emscriptenaudio.c (70%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/emscripten/SDL_emscriptenaudio.h (92%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/esd/SDL_esdaudio.c (88%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/esd/SDL_esdaudio.h (96%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/fusionsound/SDL_fsaudio.c (81%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/fusionsound/SDL_fsaudio.h (95%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/haiku/SDL_haikuaudio.cc (70%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/haiku/SDL_haikuaudio.h (92%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/jack/SDL_jackaudio.c (68%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/jack/SDL_jackaudio.h (95%) create mode 100644 SDL2-2.30.5/src/audio/n3ds/SDL_n3dsaudio.c create mode 100644 SDL2-2.30.5/src/audio/n3ds/SDL_n3dsaudio.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/nacl/SDL_naclaudio.c (66%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/nacl/SDL_naclaudio.h (92%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/nas/SDL_nasaudio.c (81%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/nas/SDL_nasaudio.h (96%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/netbsd/SDL_netbsdaudio.c (67%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/netbsd/SDL_netbsdaudio.h (88%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/openslES/SDL_openslES.c (73%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/openslES/SDL_openslES.h (83%) create mode 100644 SDL2-2.30.5/src/audio/os2/SDL_os2audio.c create mode 100644 SDL2-2.30.5/src/audio/os2/SDL_os2audio.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/paudio/SDL_paudio.c (83%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/paudio/SDL_paudio.h (96%) create mode 100644 SDL2-2.30.5/src/audio/pipewire/SDL_pipewire.c create mode 100644 SDL2-2.30.5/src/audio/pipewire/SDL_pipewire.h create mode 100644 SDL2-2.30.5/src/audio/ps2/SDL_ps2audio.c create mode 100644 SDL2-2.30.5/src/audio/ps2/SDL_ps2audio.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/psp/SDL_pspaudio.c (57%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/psp/SDL_pspaudio.h (84%) create mode 100644 SDL2-2.30.5/src/audio/pulseaudio/SDL_pulseaudio.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/pulseaudio/SDL_pulseaudio.h (89%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/qsa/SDL_qsa_audio.c (85%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/qsa/SDL_qsa_audio.h (93%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/sndio/SDL_sndioaudio.c (72%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/sndio/SDL_sndioaudio.h (93%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/sun/SDL_sunaudio.c (92%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/sun/SDL_sunaudio.h (96%) create mode 100644 SDL2-2.30.5/src/audio/vita/SDL_vitaaudio.c create mode 100644 SDL2-2.30.5/src/audio/vita/SDL_vitaaudio.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/wasapi/SDL_wasapi.c (58%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/wasapi/SDL_wasapi.h (83%) create mode 100644 SDL2-2.30.5/src/audio/wasapi/SDL_wasapi_win32.c create mode 100644 SDL2-2.30.5/src/audio/wasapi/SDL_wasapi_winrt.cpp rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/winmm/SDL_winmm.c (83%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/audio/winmm/SDL_winmm.h (96%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/core/android/SDL_android.c (68%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/core/android/SDL_android.h (82%) create mode 100644 SDL2-2.30.5/src/core/freebsd/SDL_evdev_kbd_default_keyaccmap.h create mode 100644 SDL2-2.30.5/src/core/freebsd/SDL_evdev_kbd_freebsd.c create mode 100644 SDL2-2.30.5/src/core/gdk/SDL_gdk.cpp create mode 100644 SDL2-2.30.5/src/core/gdk/SDL_gdk.h create mode 100644 SDL2-2.30.5/src/core/linux/SDL_dbus.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/core/linux/SDL_dbus.h (81%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/core/linux/SDL_evdev.c (63%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/core/linux/SDL_evdev.h (78%) create mode 100644 SDL2-2.30.5/src/core/linux/SDL_evdev_capabilities.c create mode 100644 SDL2-2.30.5/src/core/linux/SDL_evdev_capabilities.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/core/linux/SDL_evdev_kbd.c (60%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/core/linux/SDL_evdev_kbd.h (75%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/core/linux/SDL_evdev_kbd_default_accents.h (99%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/core/linux/SDL_evdev_kbd_default_keymap.h (99%) create mode 100644 SDL2-2.30.5/src/core/linux/SDL_fcitx.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/core/linux/SDL_fcitx.h (90%) create mode 100644 SDL2-2.30.5/src/core/linux/SDL_ibus.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/core/linux/SDL_ibus.h (89%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/core/linux/SDL_ime.c (76%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/core/linux/SDL_ime.h (90%) create mode 100644 SDL2-2.30.5/src/core/linux/SDL_sandbox.c create mode 100644 SDL2-2.30.5/src/core/linux/SDL_sandbox.h create mode 100644 SDL2-2.30.5/src/core/linux/SDL_threadprio.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/core/linux/SDL_udev.c (68%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/core/linux/SDL_udev.h (85%) create mode 100644 SDL2-2.30.5/src/core/openbsd/SDL_wscons.h create mode 100644 SDL2-2.30.5/src/core/openbsd/SDL_wscons_kbd.c create mode 100644 SDL2-2.30.5/src/core/openbsd/SDL_wscons_mouse.c create mode 100644 SDL2-2.30.5/src/core/os2/SDL_os2.c create mode 100644 SDL2-2.30.5/src/core/os2/SDL_os2.h create mode 100644 SDL2-2.30.5/src/core/os2/geniconv/geniconv.c create mode 100644 SDL2-2.30.5/src/core/os2/geniconv/geniconv.h create mode 100644 SDL2-2.30.5/src/core/os2/geniconv/iconv.h create mode 100644 SDL2-2.30.5/src/core/os2/geniconv/os2cp.c create mode 100644 SDL2-2.30.5/src/core/os2/geniconv/os2cp.h create mode 100644 SDL2-2.30.5/src/core/os2/geniconv/os2iconv.c create mode 100644 SDL2-2.30.5/src/core/os2/geniconv/sys2utf8.c create mode 100644 SDL2-2.30.5/src/core/os2/geniconv/test.c create mode 100644 SDL2-2.30.5/src/core/os2/iconv2.lbc rename {SDL2-2.0.12 => SDL2-2.30.5}/src/core/unix/SDL_poll.c (81%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/core/unix/SDL_poll.h (82%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/core/windows/SDL_directx.h (76%) create mode 100644 SDL2-2.30.5/src/core/windows/SDL_hid.c create mode 100644 SDL2-2.30.5/src/core/windows/SDL_hid.h create mode 100644 SDL2-2.30.5/src/core/windows/SDL_immdevice.c create mode 100644 SDL2-2.30.5/src/core/windows/SDL_immdevice.h create mode 100644 SDL2-2.30.5/src/core/windows/SDL_windows.c create mode 100644 SDL2-2.30.5/src/core/windows/SDL_windows.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/core/windows/SDL_xinput.c (66%) create mode 100644 SDL2-2.30.5/src/core/windows/SDL_xinput.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/core/winrt/SDL_winrtapp_common.cpp (73%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/core/winrt/SDL_winrtapp_common.h (95%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/core/winrt/SDL_winrtapp_direct3d.cpp (62%) create mode 100644 SDL2-2.30.5/src/core/winrt/SDL_winrtapp_direct3d.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/core/winrt/SDL_winrtapp_xaml.cpp (73%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/core/winrt/SDL_winrtapp_xaml.h (91%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/cpuinfo/SDL_cpuinfo.c (50%) create mode 100644 SDL2-2.30.5/src/dynapi/SDL2.exports create mode 100644 SDL2-2.30.5/src/dynapi/SDL_dynapi.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/dynapi/SDL_dynapi.h (70%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/dynapi/SDL_dynapi_overrides.h (81%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/dynapi/SDL_dynapi_procs.h (79%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/dynapi/gendynapi.pl (82%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/events/SDL_clipboardevents.c (92%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/events/SDL_clipboardevents_c.h (94%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/events/SDL_displayevents.c (91%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/events/SDL_displayevents_c.h (94%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/events/SDL_dropevents.c (86%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/events/SDL_dropevents_c.h (95%) create mode 100644 SDL2-2.30.5/src/events/SDL_events.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/events/SDL_events_c.h (92%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/events/SDL_gesture.c (66%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/events/SDL_gesture_c.h (91%) create mode 100644 SDL2-2.30.5/src/events/SDL_keyboard.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/events/SDL_keyboard_c.h (62%) create mode 100644 SDL2-2.30.5/src/events/SDL_keysym_to_scancode.c create mode 100644 SDL2-2.30.5/src/events/SDL_keysym_to_scancode_c.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/events/SDL_mouse.c (51%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/events/SDL_mouse_c.h (56%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/events/SDL_quit.c (76%) create mode 100644 SDL2-2.30.5/src/events/SDL_scancode_tables.c create mode 100644 SDL2-2.30.5/src/events/SDL_scancode_tables_c.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/events/SDL_touch.c (75%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/events/SDL_touch_c.h (93%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/events/SDL_windowevents.c (75%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/events/SDL_windowevents_c.h (89%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/events/blank_cursor.h (88%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/events/default_cursor.h (97%) rename {SDL2-2.0.12/src/video/x11 => SDL2-2.30.5/src/events}/imKStoUCS.c (99%) rename {SDL2-2.0.12/src/video/x11 => SDL2-2.30.5/src/events}/imKStoUCS.h (96%) create mode 100644 SDL2-2.30.5/src/events/scancodes_ascii.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/events/scancodes_darwin.h (97%) create mode 100644 SDL2-2.30.5/src/events/scancodes_linux.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/events/scancodes_windows.h (95%) create mode 100644 SDL2-2.30.5/src/events/scancodes_xfree86.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/file/SDL_rwops.c (69%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/file/cocoa/SDL_rwopsbundlesupport.h (89%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/file/cocoa/SDL_rwopsbundlesupport.m (59%) create mode 100644 SDL2-2.30.5/src/file/n3ds/SDL_rwopsromfs.c create mode 100644 SDL2-2.30.5/src/file/n3ds/SDL_rwopsromfs.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/filesystem/android/SDL_sysfilesystem.c (89%) create mode 100644 SDL2-2.30.5/src/filesystem/cocoa/SDL_sysfilesystem.m rename {SDL2-2.0.12 => SDL2-2.30.5}/src/filesystem/dummy/SDL_sysfilesystem.c (90%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/filesystem/emscripten/SDL_sysfilesystem.c (82%) create mode 100644 SDL2-2.30.5/src/filesystem/gdk/SDL_sysfilesystem.cpp rename {SDL2-2.0.12 => SDL2-2.30.5}/src/filesystem/haiku/SDL_sysfilesystem.cc (94%) create mode 100644 SDL2-2.30.5/src/filesystem/n3ds/SDL_sysfilesystem.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/filesystem/nacl/SDL_sysfilesystem.c (88%) create mode 100644 SDL2-2.30.5/src/filesystem/os2/SDL_sysfilesystem.c create mode 100644 SDL2-2.30.5/src/filesystem/ps2/SDL_sysfilesystem.c create mode 100644 SDL2-2.30.5/src/filesystem/psp/SDL_sysfilesystem.c create mode 100644 SDL2-2.30.5/src/filesystem/riscos/SDL_sysfilesystem.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/filesystem/unix/SDL_sysfilesystem.c (53%) create mode 100644 SDL2-2.30.5/src/filesystem/vita/SDL_sysfilesystem.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/filesystem/windows/SDL_sysfilesystem.c (69%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/filesystem/winrt/SDL_sysfilesystem.cpp (71%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/haptic/SDL_haptic.c (73%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/haptic/SDL_haptic_c.h (94%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/haptic/SDL_syshaptic.h (63%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/haptic/android/SDL_syshaptic.c (60%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/haptic/android/SDL_syshaptic_c.h (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/haptic/darwin/SDL_syshaptic.c (82%) create mode 100644 SDL2-2.30.5/src/haptic/darwin/SDL_syshaptic_c.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/haptic/dummy/SDL_syshaptic.c (55%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/haptic/linux/SDL_syshaptic.c (75%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/haptic/windows/SDL_dinputhaptic.c (72%) create mode 100644 SDL2-2.30.5/src/haptic/windows/SDL_dinputhaptic_c.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/haptic/windows/SDL_windowshaptic.c (76%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/haptic/windows/SDL_windowshaptic_c.h (72%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/haptic/windows/SDL_xinputhaptic.c (66%) create mode 100644 SDL2-2.30.5/src/haptic/windows/SDL_xinputhaptic_c.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/AUTHORS.txt (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/HACKING.txt (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/LICENSE-bsd.txt (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/LICENSE-gpl3.txt (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/LICENSE-orig.txt (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/LICENSE.txt (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/Makefile.am (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/README.txt (100%) create mode 100644 SDL2-2.30.5/src/hidapi/SDL_hidapi.c create mode 100644 SDL2-2.30.5/src/hidapi/SDL_hidapi_c.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/android/hid.cpp (71%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/android/jni/Android.mk (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/android/jni/Application.mk (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/android/project.properties (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/bootstrap (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/configure.ac (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/doxygen/Doxyfile (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/hidapi/hidapi.h (86%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/hidtest/Makefile.am (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/hidtest/hidtest.cpp (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/ios/Makefile-manual (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/ios/Makefile.am (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/ios/hid.m (83%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/libusb/Makefile-manual (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/libusb/Makefile.am (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/libusb/Makefile.freebsd (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/libusb/Makefile.linux (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/libusb/hid.c (79%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/libusb/hidusb.cpp (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/linux/Makefile-manual (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/linux/Makefile.am (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/linux/README.txt (97%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/linux/hid.c (89%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/linux/hidraw.cpp (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/m4/ax_pthread.m4 (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/m4/pkg.m4 (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/mac/Makefile-manual (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/mac/Makefile.am (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/mac/hid.c (86%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/pc/hidapi-hidraw.pc.in (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/pc/hidapi-libusb.pc.in (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/pc/hidapi.pc.in (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/testgui/Makefile-manual (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/testgui/Makefile.am (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/testgui/Makefile.freebsd (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/testgui/Makefile.linux (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/testgui/Makefile.mac (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/testgui/Makefile.mingw (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/testgui/TestGUI.app.in/Contents/Info.plist (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/testgui/TestGUI.app.in/Contents/PkgInfo (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/testgui/TestGUI.app.in/Contents/Resources/English.lproj/InfoPlist.strings (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/testgui/TestGUI.app.in/Contents/Resources/Signal11.icns (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/testgui/copy_to_bundle.sh (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/testgui/mac_support.cpp (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/testgui/mac_support.h (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/testgui/mac_support_cocoa.m (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/testgui/start.sh (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/testgui/test.cpp (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/testgui/testgui.sln (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/testgui/testgui.vcproj (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/udev/99-hid.rules (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/windows/Makefile-manual (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/windows/Makefile.am (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/windows/Makefile.mingw (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/windows/ddk_build/hidapi.def (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/windows/ddk_build/sources (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/windows/hid.c (81%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/windows/hidapi.sln (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/windows/hidapi.vcproj (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/hidapi/windows/hidtest.vcproj (100%) create mode 100644 SDL2-2.30.5/src/joystick/SDL_gamecontroller.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/joystick/SDL_gamecontrollerdb.h (59%) create mode 100644 SDL2-2.30.5/src/joystick/SDL_joystick.c create mode 100644 SDL2-2.30.5/src/joystick/SDL_joystick_c.h create mode 100644 SDL2-2.30.5/src/joystick/SDL_steam_virtual_gamepad.c create mode 100644 SDL2-2.30.5/src/joystick/SDL_steam_virtual_gamepad.h create mode 100644 SDL2-2.30.5/src/joystick/SDL_sysjoystick.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/joystick/android/SDL_sysjoystick.c (58%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/joystick/android/SDL_sysjoystick_c.h (90%) create mode 100644 SDL2-2.30.5/src/joystick/bsd/SDL_bsdjoystick.c create mode 100644 SDL2-2.30.5/src/joystick/check_8bitdo.sh rename SDL2-2.0.12/src/joystick/controller_type.h => SDL2-2.30.5/src/joystick/controller_list.h (74%) create mode 100644 SDL2-2.30.5/src/joystick/controller_type.c create mode 100644 SDL2-2.30.5/src/joystick/controller_type.h rename SDL2-2.0.12/src/joystick/darwin/SDL_sysjoystick.c => SDL2-2.30.5/src/joystick/darwin/SDL_iokitjoystick.c (62%) rename SDL2-2.0.12/src/joystick/darwin/SDL_sysjoystick_c.h => SDL2-2.30.5/src/joystick/darwin/SDL_iokitjoystick_c.h (56%) create mode 100644 SDL2-2.30.5/src/joystick/dummy/SDL_sysjoystick.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/joystick/emscripten/SDL_sysjoystick.c (67%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/joystick/emscripten/SDL_sysjoystick_c.h (77%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/joystick/haiku/SDL_haikujoystick.cc (75%) create mode 100644 SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_combined.c create mode 100644 SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_gamecube.c create mode 100644 SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_luna.c create mode 100644 SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_nintendo.h create mode 100644 SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_ps3.c create mode 100644 SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_ps4.c create mode 100644 SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_ps5.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/joystick/hidapi/SDL_hidapi_rumble.c (67%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/joystick/hidapi/SDL_hidapi_rumble.h (70%) create mode 100644 SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_shield.c create mode 100644 SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_stadia.c create mode 100644 SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_steam.c create mode 100644 SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_steamdeck.c create mode 100644 SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_switch.c create mode 100644 SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_wii.c create mode 100644 SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_xbox360.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/joystick/hidapi/SDL_hidapi_xbox360w.c (52%) create mode 100644 SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_xboxone.c create mode 100644 SDL2-2.30.5/src/joystick/hidapi/SDL_hidapijoystick.c create mode 100644 SDL2-2.30.5/src/joystick/hidapi/SDL_hidapijoystick_c.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/joystick/hidapi/steam/controller_constants.h (82%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/joystick/hidapi/steam/controller_structs.h (50%) create mode 100644 SDL2-2.30.5/src/joystick/iphoneos/SDL_mfijoystick.m rename SDL2-2.0.12/src/joystick/iphoneos/SDL_sysjoystick_c.h => SDL2-2.30.5/src/joystick/iphoneos/SDL_mfijoystick_c.h (68%) create mode 100644 SDL2-2.30.5/src/joystick/linux/SDL_sysjoystick.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/joystick/linux/SDL_sysjoystick_c.h (61%) create mode 100644 SDL2-2.30.5/src/joystick/n3ds/SDL_sysjoystick.c create mode 100644 SDL2-2.30.5/src/joystick/os2/SDL_os2joystick.c create mode 100644 SDL2-2.30.5/src/joystick/ps2/SDL_sysjoystick.c create mode 100644 SDL2-2.30.5/src/joystick/psp/SDL_sysjoystick.c create mode 100644 SDL2-2.30.5/src/joystick/sort_controllers.py rename {SDL2-2.0.12 => SDL2-2.30.5}/src/joystick/steam/SDL_steamcontroller.c (96%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/joystick/steam/SDL_steamcontroller.h (96%) create mode 100644 SDL2-2.30.5/src/joystick/usb_ids.h create mode 100644 SDL2-2.30.5/src/joystick/virtual/SDL_virtualjoystick.c create mode 100644 SDL2-2.30.5/src/joystick/virtual/SDL_virtualjoystick_c.h create mode 100644 SDL2-2.30.5/src/joystick/vita/SDL_sysjoystick.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/joystick/windows/SDL_dinputjoystick.c (63%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/joystick/windows/SDL_dinputjoystick_c.h (59%) create mode 100644 SDL2-2.30.5/src/joystick/windows/SDL_rawinputjoystick.c rename SDL2-2.0.12/src/video/cocoa/SDL_cocoamousetap.h => SDL2-2.30.5/src/joystick/windows/SDL_rawinputjoystick_c.h (62%) create mode 100644 SDL2-2.30.5/src/joystick/windows/SDL_windows_gaming_input.c create mode 100644 SDL2-2.30.5/src/joystick/windows/SDL_windowsjoystick.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/joystick/windows/SDL_windowsjoystick_c.h (79%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/joystick/windows/SDL_xinputjoystick.c (58%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/joystick/windows/SDL_xinputjoystick_c.h (62%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/libm/e_atan2.c (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/libm/e_exp.c (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/libm/e_fmod.c (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/libm/e_log.c (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/libm/e_log10.c (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/libm/e_pow.c (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/libm/e_rem_pio2.c (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/libm/e_sqrt.c (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/libm/k_cos.c (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/libm/k_rem_pio2.c (97%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/libm/k_sin.c (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/libm/k_tan.c (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/libm/math_libm.h (96%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/libm/math_private.h (96%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/libm/s_atan.c (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/libm/s_copysign.c (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/libm/s_cos.c (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/libm/s_fabs.c (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/libm/s_floor.c (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/libm/s_scalbn.c (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/libm/s_sin.c (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/libm/s_tan.c (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/loadso/dlopen/SDL_sysloadso.c (72%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/loadso/dummy/SDL_sysloadso.c (86%) create mode 100644 SDL2-2.30.5/src/loadso/os2/SDL_sysloadso.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/loadso/windows/SDL_sysloadso.c (73%) create mode 100644 SDL2-2.30.5/src/locale/SDL_locale.c create mode 100644 SDL2-2.30.5/src/locale/SDL_syslocale.h create mode 100644 SDL2-2.30.5/src/locale/android/SDL_syslocale.c create mode 100644 SDL2-2.30.5/src/locale/dummy/SDL_syslocale.c create mode 100644 SDL2-2.30.5/src/locale/emscripten/SDL_syslocale.c create mode 100644 SDL2-2.30.5/src/locale/haiku/SDL_syslocale.cc create mode 100644 SDL2-2.30.5/src/locale/macosx/SDL_syslocale.m create mode 100644 SDL2-2.30.5/src/locale/n3ds/SDL_syslocale.c create mode 100644 SDL2-2.30.5/src/locale/unix/SDL_syslocale.c create mode 100644 SDL2-2.30.5/src/locale/vita/SDL_syslocale.c create mode 100644 SDL2-2.30.5/src/locale/windows/SDL_syslocale.c create mode 100644 SDL2-2.30.5/src/locale/winrt/SDL_syslocale.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/main/android/SDL_android_main.c (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/main/dummy/SDL_dummy_main.c (70%) create mode 100644 SDL2-2.30.5/src/main/gdk/SDL_gdk_main.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/main/haiku/SDL_BApp.h (67%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/main/haiku/SDL_BeApp.cc (63%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/main/haiku/SDL_BeApp.h (93%) create mode 100644 SDL2-2.30.5/src/main/n3ds/SDL_n3ds_main.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/main/nacl/SDL_nacl_main.c (91%) create mode 100644 SDL2-2.30.5/src/main/ngage/SDL_ngage_main.cpp create mode 100644 SDL2-2.30.5/src/main/ps2/SDL_ps2_main.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/main/psp/SDL_psp_main.c (75%) create mode 100644 SDL2-2.30.5/src/main/uikit/SDL_uikit_main.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/main/windows/SDL_windows_main.c (62%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/main/windows/version.rc (69%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/main/winrt/SDL2-WinRTResource_BlankCursor.cur (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/main/winrt/SDL2-WinRTResources.rc (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/main/winrt/SDL_winrt_main_NonXAML.cpp (98%) create mode 100644 SDL2-2.30.5/src/misc/SDL_sysurl.h create mode 100644 SDL2-2.30.5/src/misc/SDL_url.c rename SDL2-2.0.12/src/haptic/darwin/SDL_syshaptic_c.h => SDL2-2.30.5/src/misc/android/SDL_sysurl.c (81%) create mode 100644 SDL2-2.30.5/src/misc/dummy/SDL_sysurl.c create mode 100644 SDL2-2.30.5/src/misc/emscripten/SDL_sysurl.c create mode 100644 SDL2-2.30.5/src/misc/haiku/SDL_sysurl.cc create mode 100644 SDL2-2.30.5/src/misc/ios/SDL_sysurl.m create mode 100644 SDL2-2.30.5/src/misc/macosx/SDL_sysurl.m create mode 100644 SDL2-2.30.5/src/misc/riscos/SDL_sysurl.c create mode 100644 SDL2-2.30.5/src/misc/unix/SDL_sysurl.c create mode 100644 SDL2-2.30.5/src/misc/vita/SDL_sysurl.c create mode 100644 SDL2-2.30.5/src/misc/windows/SDL_sysurl.c create mode 100644 SDL2-2.30.5/src/misc/winrt/SDL_sysurl.cpp rename {SDL2-2.0.12 => SDL2-2.30.5}/src/power/SDL_power.c (72%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/power/SDL_syspower.h (91%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/power/android/SDL_syspower.c (91%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/power/emscripten/SDL_syspower.c (89%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/power/haiku/SDL_syspower.c (72%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/power/linux/SDL_syspower.c (57%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/power/macosx/SDL_syspower.c (81%) create mode 100644 SDL2-2.30.5/src/power/n3ds/SDL_syspower.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/power/psp/SDL_syspower.c (80%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/power/uikit/SDL_syspower.h (86%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/power/uikit/SDL_syspower.m (87%) create mode 100644 SDL2-2.30.5/src/power/vita/SDL_syspower.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/power/windows/SDL_syspower.c (73%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/power/winrt/SDL_syspower.cpp (91%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/render/SDL_d3dmath.c (94%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/render/SDL_d3dmath.h (79%) create mode 100644 SDL2-2.30.5/src/render/SDL_render.c create mode 100644 SDL2-2.30.5/src/render/SDL_sysrender.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/render/SDL_yuv_sw.c (60%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/render/SDL_yuv_sw_c.h (71%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/render/direct3d/SDL_render_d3d.c (64%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/render/direct3d/SDL_shaders_d3d.c (98%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/render/direct3d/SDL_shaders_d3d.h (94%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/render/direct3d11/SDL_render_d3d11.c (63%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/render/direct3d11/SDL_render_winrt.cpp (88%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/render/direct3d11/SDL_render_winrt.h (82%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/render/direct3d11/SDL_shaders_d3d11.c (98%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/render/direct3d11/SDL_shaders_d3d11.h (93%) create mode 100644 SDL2-2.30.5/src/render/direct3d12/SDL_render_d3d12.c create mode 100644 SDL2-2.30.5/src/render/direct3d12/SDL_render_d3d12_xbox.cpp rename SDL2-2.0.12/include/SDL_clipboard.h => SDL2-2.30.5/src/render/direct3d12/SDL_render_d3d12_xbox.h (54%) create mode 100644 SDL2-2.30.5/src/render/direct3d12/SDL_shaders_d3d12.c create mode 100644 SDL2-2.30.5/src/render/direct3d12/SDL_shaders_d3d12.h create mode 100644 SDL2-2.30.5/src/render/direct3d12/SDL_shaders_d3d12_xboxone.cpp create mode 100644 SDL2-2.30.5/src/render/direct3d12/SDL_shaders_d3d12_xboxseries.cpp rename {SDL2-2.0.12 => SDL2-2.30.5}/src/render/metal/SDL_render_metal.m (72%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/render/metal/SDL_shaders_metal.metal (79%) create mode 100644 SDL2-2.30.5/src/render/metal/SDL_shaders_metal_ios.h create mode 100644 SDL2-2.30.5/src/render/metal/SDL_shaders_metal_iphonesimulator.h create mode 100644 SDL2-2.30.5/src/render/metal/SDL_shaders_metal_osx.h create mode 100644 SDL2-2.30.5/src/render/metal/SDL_shaders_metal_tvos.h create mode 100644 SDL2-2.30.5/src/render/metal/SDL_shaders_metal_tvsimulator.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/render/metal/build-metal-shaders.sh (84%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/render/opengl/SDL_glfuncs.h (67%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/render/opengl/SDL_render_gl.c (53%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/render/opengl/SDL_shaders_gl.c (79%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/render/opengl/SDL_shaders_gl.h (85%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/render/opengles/SDL_glesfuncs.h (91%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/render/opengles/SDL_render_gles.c (59%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/render/opengles2/SDL_gles2funcs.h (94%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/render/opengles2/SDL_render_gles2.c (55%) create mode 100644 SDL2-2.30.5/src/render/opengles2/SDL_shaders_gles2.c create mode 100644 SDL2-2.30.5/src/render/opengles2/SDL_shaders_gles2.h create mode 100644 SDL2-2.30.5/src/render/ps2/SDL_render_ps2.c create mode 100644 SDL2-2.30.5/src/render/psp/SDL_render_psp.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/render/software/SDL_blendfillrect.c (85%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/render/software/SDL_blendfillrect.h (75%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/render/software/SDL_blendline.c (90%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/render/software/SDL_blendline.h (75%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/render/software/SDL_blendpoint.c (85%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/render/software/SDL_blendpoint.h (75%) create mode 100644 SDL2-2.30.5/src/render/software/SDL_draw.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/render/software/SDL_drawline.c (74%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/render/software/SDL_drawline.h (80%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/render/software/SDL_drawpoint.c (85%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/render/software/SDL_drawpoint.h (81%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/render/software/SDL_render_sw.c (51%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/render/software/SDL_render_sw_c.h (88%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/render/software/SDL_rotate.c (54%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/render/software/SDL_rotate.h (70%) create mode 100644 SDL2-2.30.5/src/render/software/SDL_triangle.c create mode 100644 SDL2-2.30.5/src/render/software/SDL_triangle.h create mode 100644 SDL2-2.30.5/src/render/vitagxm/SDL_render_vita_gxm.c create mode 100644 SDL2-2.30.5/src/render/vitagxm/SDL_render_vita_gxm_memory.c create mode 100644 SDL2-2.30.5/src/render/vitagxm/SDL_render_vita_gxm_memory.h create mode 100644 SDL2-2.30.5/src/render/vitagxm/SDL_render_vita_gxm_shaders.h create mode 100644 SDL2-2.30.5/src/render/vitagxm/SDL_render_vita_gxm_tools.c create mode 100644 SDL2-2.30.5/src/render/vitagxm/SDL_render_vita_gxm_tools.h create mode 100644 SDL2-2.30.5/src/render/vitagxm/SDL_render_vita_gxm_types.h create mode 100644 SDL2-2.30.5/src/render/vitagxm/shader_src/clear_f.cg create mode 100644 SDL2-2.30.5/src/render/vitagxm/shader_src/clear_v.cg create mode 100644 SDL2-2.30.5/src/render/vitagxm/shader_src/color_f.cg create mode 100644 SDL2-2.30.5/src/render/vitagxm/shader_src/color_v.cg create mode 100644 SDL2-2.30.5/src/render/vitagxm/shader_src/texture_f.cg create mode 100644 SDL2-2.30.5/src/render/vitagxm/shader_src/texture_v.cg rename {SDL2-2.0.12 => SDL2-2.30.5}/src/sensor/SDL_sensor.c (80%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/sensor/SDL_sensor_c.h (89%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/sensor/SDL_syssensor.h (74%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/sensor/android/SDL_androidsensor.c (75%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/sensor/android/SDL_androidsensor.h (94%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/sensor/coremotion/SDL_coremotionsensor.h (94%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/sensor/coremotion/SDL_coremotionsensor.m (65%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/sensor/dummy/SDL_dummysensor.c (69%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/sensor/dummy/SDL_dummysensor.h (93%) create mode 100644 SDL2-2.30.5/src/sensor/n3ds/SDL_n3dssensor.c create mode 100644 SDL2-2.30.5/src/sensor/vita/SDL_vitasensor.c create mode 100644 SDL2-2.30.5/src/sensor/vita/SDL_vitasensor.h create mode 100644 SDL2-2.30.5/src/sensor/windows/SDL_windowssensor.c create mode 100644 SDL2-2.30.5/src/sensor/windows/SDL_windowssensor.h create mode 100644 SDL2-2.30.5/src/stdlib/SDL_crc16.c create mode 100644 SDL2-2.30.5/src/stdlib/SDL_crc32.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/stdlib/SDL_getenv.c (77%) create mode 100644 SDL2-2.30.5/src/stdlib/SDL_iconv.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/stdlib/SDL_malloc.c (61%) rename SDL2-2.0.12/src/stdlib/SDL_stdlib.c => SDL2-2.30.5/src/stdlib/SDL_mslibc.c (67%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/stdlib/SDL_qsort.c (87%) create mode 100644 SDL2-2.30.5/src/stdlib/SDL_stdlib.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/stdlib/SDL_string.c (55%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/stdlib/SDL_strtokr.c (94%) create mode 100644 SDL2-2.30.5/src/stdlib/SDL_vacopy.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/test/SDL_test_assert.c (84%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/test/SDL_test_common.c (61%) create mode 100644 SDL2-2.30.5/src/test/SDL_test_compare.c create mode 100644 SDL2-2.30.5/src/test/SDL_test_crc32.c create mode 100644 SDL2-2.30.5/src/test/SDL_test_font.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/test/SDL_test_fuzzer.c (61%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/test/SDL_test_harness.c (70%) create mode 100644 SDL2-2.30.5/src/test/SDL_test_imageBlit.c create mode 100644 SDL2-2.30.5/src/test/SDL_test_imageBlitBlend.c create mode 100644 SDL2-2.30.5/src/test/SDL_test_imageFace.c create mode 100644 SDL2-2.30.5/src/test/SDL_test_imagePrimitives.c create mode 100644 SDL2-2.30.5/src/test/SDL_test_imagePrimitivesBlend.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/test/SDL_test_log.c (84%) create mode 100644 SDL2-2.30.5/src/test/SDL_test_md5.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/test/SDL_test_memory.c (83%) create mode 100644 SDL2-2.30.5/src/test/SDL_test_random.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/thread/SDL_systhread.h (81%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/thread/SDL_thread.c (70%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/thread/SDL_thread_c.h (73%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/thread/generic/SDL_syscond.c (77%) create mode 100644 SDL2-2.30.5/src/thread/generic/SDL_syscond_c.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/thread/generic/SDL_sysmutex.c (84%) rename {SDL2-2.0.12/src/thread/psp => SDL2-2.30.5/src/thread/generic}/SDL_sysmutex_c.h (94%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/thread/generic/SDL_syssem.c (81%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/thread/generic/SDL_systhread.c (69%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/thread/generic/SDL_systhread_c.h (94%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/thread/generic/SDL_systls.c (88%) create mode 100644 SDL2-2.30.5/src/thread/n3ds/SDL_syscond.c create mode 100644 SDL2-2.30.5/src/thread/n3ds/SDL_sysmutex.c create mode 100644 SDL2-2.30.5/src/thread/n3ds/SDL_sysmutex_c.h create mode 100644 SDL2-2.30.5/src/thread/n3ds/SDL_syssem.c create mode 100644 SDL2-2.30.5/src/thread/n3ds/SDL_systhread.c create mode 100644 SDL2-2.30.5/src/thread/n3ds/SDL_systhread_c.h create mode 100644 SDL2-2.30.5/src/thread/ngage/SDL_sysmutex.cpp create mode 100644 SDL2-2.30.5/src/thread/ngage/SDL_syssem.cpp create mode 100644 SDL2-2.30.5/src/thread/ngage/SDL_systhread.cpp create mode 100644 SDL2-2.30.5/src/thread/ngage/SDL_systhread_c.h create mode 100644 SDL2-2.30.5/src/thread/os2/SDL_sysmutex.c create mode 100644 SDL2-2.30.5/src/thread/os2/SDL_syssem.c create mode 100644 SDL2-2.30.5/src/thread/os2/SDL_systhread.c create mode 100644 SDL2-2.30.5/src/thread/os2/SDL_systhread_c.h create mode 100644 SDL2-2.30.5/src/thread/os2/SDL_systls.c create mode 100644 SDL2-2.30.5/src/thread/os2/SDL_systls_c.h create mode 100644 SDL2-2.30.5/src/thread/ps2/SDL_syssem.c create mode 100644 SDL2-2.30.5/src/thread/ps2/SDL_systhread.c create mode 100644 SDL2-2.30.5/src/thread/ps2/SDL_systhread_c.h create mode 100644 SDL2-2.30.5/src/thread/psp/SDL_sysmutex.c rename {SDL2-2.0.12/src/thread/generic => SDL2-2.30.5/src/thread/psp}/SDL_sysmutex_c.h (94%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/thread/psp/SDL_syssem.c (77%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/thread/psp/SDL_systhread.c (82%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/thread/psp/SDL_systhread_c.h (94%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/thread/pthread/SDL_syscond.c (81%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/thread/pthread/SDL_sysmutex.c (82%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/thread/pthread/SDL_sysmutex_c.h (94%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/thread/pthread/SDL_syssem.c (81%) create mode 100644 SDL2-2.30.5/src/thread/pthread/SDL_systhread.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/thread/pthread/SDL_systhread_c.h (94%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/thread/pthread/SDL_systls.c (93%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/thread/stdcpp/SDL_syscond.cpp (73%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/thread/stdcpp/SDL_sysmutex.cpp (71%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/thread/stdcpp/SDL_sysmutex_c.h (94%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/thread/stdcpp/SDL_systhread.cpp (70%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/thread/stdcpp/SDL_systhread_c.h (91%) create mode 100644 SDL2-2.30.5/src/thread/vita/SDL_sysmutex.c create mode 100644 SDL2-2.30.5/src/thread/vita/SDL_sysmutex_c.h create mode 100644 SDL2-2.30.5/src/thread/vita/SDL_syssem.c create mode 100644 SDL2-2.30.5/src/thread/vita/SDL_systhread.c create mode 100644 SDL2-2.30.5/src/thread/vita/SDL_systhread_c.h create mode 100644 SDL2-2.30.5/src/thread/windows/SDL_syscond_cv.c create mode 100644 SDL2-2.30.5/src/thread/windows/SDL_sysmutex.c create mode 100644 SDL2-2.30.5/src/thread/windows/SDL_sysmutex_c.h create mode 100644 SDL2-2.30.5/src/thread/windows/SDL_syssem.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/thread/windows/SDL_systhread.c (51%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/thread/windows/SDL_systhread_c.h (94%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/thread/windows/SDL_systls.c (91%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/timer/SDL_timer.c (74%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/timer/SDL_timer_c.h (90%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/timer/dummy/SDL_systimer.c (85%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/timer/haiku/SDL_systimer.c (82%) create mode 100644 SDL2-2.30.5/src/timer/n3ds/SDL_systimer.c create mode 100644 SDL2-2.30.5/src/timer/ngage/SDL_systimer.cpp create mode 100644 SDL2-2.30.5/src/timer/os2/SDL_systimer.c create mode 100644 SDL2-2.30.5/src/timer/ps2/SDL_systimer.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/timer/psp/SDL_systimer.c (78%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/timer/unix/SDL_systimer.c (75%) create mode 100644 SDL2-2.30.5/src/timer/vita/SDL_systimer.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/timer/windows/SDL_systimer.c (65%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/SDL_RLEaccel.c (52%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/SDL_RLEaccel_c.h (86%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/SDL_blit.c (85%) create mode 100644 SDL2-2.30.5/src/video/SDL_blit.h create mode 100644 SDL2-2.30.5/src/video/SDL_blit_0.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/SDL_blit_1.c (76%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/SDL_blit_A.c (69%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/SDL_blit_N.c (75%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/SDL_blit_auto.c (84%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/SDL_blit_auto.h (88%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/SDL_blit_copy.c (62%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/SDL_blit_copy.h (90%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/SDL_blit_slow.c (62%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/SDL_blit_slow.h (90%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/SDL_bmp.c (71%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/SDL_clipboard.c (57%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/SDL_egl.c (56%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/SDL_egl_c.h (66%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/SDL_fillrect.c (60%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/SDL_pixels.c (68%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/SDL_pixels_c.h (67%) create mode 100644 SDL2-2.30.5/src/video/SDL_rect.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/SDL_rect_c.h (90%) rename SDL2-2.0.12/src/video/SDL_rect.c => SDL2-2.30.5/src/video/SDL_rect_impl.h (62%) create mode 100644 SDL2-2.30.5/src/video/SDL_shape.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/SDL_shape_internals.h (67%) create mode 100644 SDL2-2.30.5/src/video/SDL_stretch.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/SDL_surface.c (55%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/SDL_sysvideo.h (60%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/SDL_video.c (57%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/SDL_vulkan_internal.h (82%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/SDL_vulkan_utils.c (74%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/SDL_yuv.c (63%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/SDL_yuv_c.h (91%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/android/SDL_androidclipboard.c (87%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/android/SDL_androidclipboard.h (95%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/android/SDL_androidevents.c (76%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/android/SDL_androidevents.h (94%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/android/SDL_androidgl.c (71%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/android/SDL_androidgl.h (80%) create mode 100644 SDL2-2.30.5/src/video/android/SDL_androidkeyboard.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/android/SDL_androidkeyboard.h (77%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/android/SDL_androidmessagebox.c (86%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/android/SDL_androidmessagebox.h (92%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/android/SDL_androidmouse.c (68%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/android/SDL_androidmouse.h (95%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/android/SDL_androidtouch.c (76%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/android/SDL_androidtouch.h (95%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/android/SDL_androidvideo.c (62%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/android/SDL_androidvideo.h (86%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/android/SDL_androidvulkan.c (72%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/android/SDL_androidvulkan.h (73%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/android/SDL_androidwindow.c (75%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/android/SDL_androidwindow.h (89%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/arm/pixman-arm-asm.h (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/arm/pixman-arm-neon-asm.S (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/arm/pixman-arm-neon-asm.h (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/arm/pixman-arm-simd-asm.S (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/arm/pixman-arm-simd-asm.h (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/cocoa/SDL_cocoaclipboard.h (89%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/cocoa/SDL_cocoaclipboard.m (73%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/cocoa/SDL_cocoaevents.h (86%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/cocoa/SDL_cocoaevents.m (70%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/cocoa/SDL_cocoakeyboard.h (85%) create mode 100644 SDL2-2.30.5/src/video/cocoa/SDL_cocoakeyboard.m rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/cocoa/SDL_cocoamessagebox.h (92%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/cocoa/SDL_cocoamessagebox.m (64%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/cocoa/SDL_cocoametalview.h (81%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/cocoa/SDL_cocoametalview.m (76%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/cocoa/SDL_cocoamodes.h (96%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/cocoa/SDL_cocoamodes.m (78%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/cocoa/SDL_cocoamouse.h (86%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/cocoa/SDL_cocoamouse.m (52%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/cocoa/SDL_cocoaopengl.h (80%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/cocoa/SDL_cocoaopengl.m (55%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/cocoa/SDL_cocoaopengles.h (95%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/cocoa/SDL_cocoaopengles.m (67%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/cocoa/SDL_cocoashape.h (84%) create mode 100644 SDL2-2.30.5/src/video/cocoa/SDL_cocoashape.m rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/cocoa/SDL_cocoavideo.h (87%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/cocoa/SDL_cocoavideo.m (73%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/cocoa/SDL_cocoavulkan.h (93%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/cocoa/SDL_cocoavulkan.m (75%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/cocoa/SDL_cocoawindow.h (74%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/cocoa/SDL_cocoawindow.m (63%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/directfb/SDL_DirectFB_WM.c (89%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/directfb/SDL_DirectFB_WM.h (96%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/directfb/SDL_DirectFB_dyn.c (92%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/directfb/SDL_DirectFB_dyn.h (97%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/directfb/SDL_DirectFB_events.c (89%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/directfb/SDL_DirectFB_events.h (95%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/directfb/SDL_DirectFB_modes.c (93%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/directfb/SDL_DirectFB_modes.h (97%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/directfb/SDL_DirectFB_mouse.c (92%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/directfb/SDL_DirectFB_mouse.h (95%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/directfb/SDL_DirectFB_opengl.c (83%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/directfb/SDL_DirectFB_opengl.h (96%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/directfb/SDL_DirectFB_render.c (77%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/directfb/SDL_DirectFB_render.h (94%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/directfb/SDL_DirectFB_shape.c (83%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/directfb/SDL_DirectFB_shape.h (95%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/directfb/SDL_DirectFB_video.c (92%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/directfb/SDL_DirectFB_video.h (97%) create mode 100644 SDL2-2.30.5/src/video/directfb/SDL_DirectFB_vulkan.c create mode 100644 SDL2-2.30.5/src/video/directfb/SDL_DirectFB_vulkan.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/directfb/SDL_DirectFB_window.c (89%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/directfb/SDL_DirectFB_window.h (93%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/dummy/SDL_nullevents.c (91%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/dummy/SDL_nullevents_c.h (94%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/dummy/SDL_nullframebuffer.c (63%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/dummy/SDL_nullframebuffer_c.h (87%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/dummy/SDL_nullvideo.c (67%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/dummy/SDL_nullvideo.h (94%) create mode 100644 SDL2-2.30.5/src/video/emscripten/SDL_emscriptenevents.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/emscripten/SDL_emscriptenevents.h (95%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/emscripten/SDL_emscriptenframebuffer.c (83%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/emscripten/SDL_emscriptenframebuffer.h (87%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/emscripten/SDL_emscriptenmouse.c (61%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/emscripten/SDL_emscriptenmouse.h (95%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/emscripten/SDL_emscriptenopengles.c (83%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/emscripten/SDL_emscriptenopengles.h (90%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/emscripten/SDL_emscriptenvideo.c (70%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/emscripten/SDL_emscriptenvideo.h (92%) create mode 100644 SDL2-2.30.5/src/video/haiku/SDL_BApp.h create mode 100644 SDL2-2.30.5/src/video/haiku/SDL_BWin.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/haiku/SDL_bclipboard.cc (89%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/haiku/SDL_bclipboard.h (95%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/haiku/SDL_bevents.cc (92%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/haiku/SDL_bevents.h (94%) create mode 100644 SDL2-2.30.5/src/video/haiku/SDL_bframebuffer.cc rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/haiku/SDL_bframebuffer.h (71%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/haiku/SDL_bkeyboard.cc (96%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/haiku/SDL_bkeyboard.h (95%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/haiku/SDL_bmessagebox.cc (90%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/haiku/SDL_bmessagebox.h (93%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/haiku/SDL_bmodes.cc (74%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/haiku/SDL_bmodes.h (85%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/haiku/SDL_bopengl.cc (74%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/haiku/SDL_bopengl.h (61%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/haiku/SDL_bvideo.cc (56%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/haiku/SDL_bvideo.h (92%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/haiku/SDL_bwindow.cc (85%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/haiku/SDL_bwindow.h (91%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/khronos/EGL/egl.h (72%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/khronos/EGL/eglext.h (79%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/khronos/EGL/eglplatform.h (60%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/khronos/GLES2/gl2.h (96%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/khronos/GLES2/gl2ext.h (84%) create mode 100644 SDL2-2.30.5/src/video/khronos/GLES2/gl2platform.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/khronos/KHR/khrplatform.h (85%) create mode 100644 SDL2-2.30.5/src/video/khronos/vk_video/vulkan_video_codec_h264std.h create mode 100644 SDL2-2.30.5/src/video/khronos/vk_video/vulkan_video_codec_h264std_decode.h create mode 100644 SDL2-2.30.5/src/video/khronos/vk_video/vulkan_video_codec_h264std_encode.h create mode 100644 SDL2-2.30.5/src/video/khronos/vk_video/vulkan_video_codec_h265std.h create mode 100644 SDL2-2.30.5/src/video/khronos/vk_video/vulkan_video_codec_h265std_decode.h create mode 100644 SDL2-2.30.5/src/video/khronos/vk_video/vulkan_video_codec_h265std_encode.h create mode 100644 SDL2-2.30.5/src/video/khronos/vk_video/vulkan_video_codecs_common.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/khronos/vulkan/vk_icd.h (54%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/khronos/vulkan/vk_layer.h (84%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/khronos/vulkan/vk_platform.h (79%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/khronos/vulkan/vk_sdk_platform.h (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/khronos/vulkan/vulkan.h (59%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/khronos/vulkan/vulkan_android.h (66%) create mode 100644 SDL2-2.30.5/src/video/khronos/vulkan/vulkan_beta.h create mode 100644 SDL2-2.30.5/src/video/khronos/vulkan/vulkan_core.h create mode 100644 SDL2-2.30.5/src/video/khronos/vulkan/vulkan_directfb.h create mode 100644 SDL2-2.30.5/src/video/khronos/vulkan/vulkan_fuchsia.h create mode 100644 SDL2-2.30.5/src/video/khronos/vulkan/vulkan_ggp.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/khronos/vulkan/vulkan_ios.h (62%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/khronos/vulkan/vulkan_macos.h (63%) create mode 100644 SDL2-2.30.5/src/video/khronos/vulkan/vulkan_metal.h create mode 100644 SDL2-2.30.5/src/video/khronos/vulkan/vulkan_screen.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/khronos/vulkan/vulkan_vi.h (64%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/khronos/vulkan/vulkan_wayland.h (73%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/khronos/vulkan/vulkan_win32.h (70%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/khronos/vulkan/vulkan_xcb.h (73%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/khronos/vulkan/vulkan_xlib.h (73%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/khronos/vulkan/vulkan_xlib_xrandr.h (67%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/kmsdrm/SDL_kmsdrmdyn.c (65%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/kmsdrm/SDL_kmsdrmdyn.h (87%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/kmsdrm/SDL_kmsdrmevents.c (83%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/kmsdrm/SDL_kmsdrmevents.h (88%) create mode 100644 SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmmouse.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/kmsdrm/SDL_kmsdrmmouse.h (67%) create mode 100644 SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmopengles.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/kmsdrm/SDL_kmsdrmopengles.h (79%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/kmsdrm/SDL_kmsdrmsym.h (59%) create mode 100644 SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmvideo.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/kmsdrm/SDL_kmsdrmvideo.h (52%) create mode 100644 SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmvulkan.c create mode 100644 SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmvulkan.h create mode 100644 SDL2-2.30.5/src/video/n3ds/SDL_n3dsevents.c create mode 100644 SDL2-2.30.5/src/video/n3ds/SDL_n3dsevents_c.h create mode 100644 SDL2-2.30.5/src/video/n3ds/SDL_n3dsframebuffer.c create mode 100644 SDL2-2.30.5/src/video/n3ds/SDL_n3dsframebuffer_c.h create mode 100644 SDL2-2.30.5/src/video/n3ds/SDL_n3dsswkb.c create mode 100644 SDL2-2.30.5/src/video/n3ds/SDL_n3dsswkb.h create mode 100644 SDL2-2.30.5/src/video/n3ds/SDL_n3dstouch.c create mode 100644 SDL2-2.30.5/src/video/n3ds/SDL_n3dstouch.h create mode 100644 SDL2-2.30.5/src/video/n3ds/SDL_n3dsvideo.c create mode 100644 SDL2-2.30.5/src/video/n3ds/SDL_n3dsvideo.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/nacl/SDL_naclevents.c (99%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/nacl/SDL_naclevents_c.h (94%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/nacl/SDL_naclglue.c (91%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/nacl/SDL_naclopengles.c (86%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/nacl/SDL_naclopengles.h (96%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/nacl/SDL_naclvideo.c (90%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/nacl/SDL_naclvideo.h (97%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/nacl/SDL_naclwindow.c (85%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/nacl/SDL_naclwindow.h (95%) create mode 100644 SDL2-2.30.5/src/video/ngage/SDL_ngageevents.cpp create mode 100644 SDL2-2.30.5/src/video/ngage/SDL_ngageevents_c.h create mode 100644 SDL2-2.30.5/src/video/ngage/SDL_ngageframebuffer.cpp create mode 100644 SDL2-2.30.5/src/video/ngage/SDL_ngageframebuffer_c.h create mode 100644 SDL2-2.30.5/src/video/ngage/SDL_ngagevideo.cpp create mode 100644 SDL2-2.30.5/src/video/ngage/SDL_ngagevideo.h create mode 100644 SDL2-2.30.5/src/video/ngage/SDL_ngagewindow.cpp create mode 100644 SDL2-2.30.5/src/video/ngage/SDL_ngagewindow.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/offscreen/SDL_offscreenevents.c (90%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/offscreen/SDL_offscreenevents_c.h (91%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/offscreen/SDL_offscreenframebuffer.c (63%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/offscreen/SDL_offscreenframebuffer_c.h (85%) rename SDL2-2.0.12/src/video/offscreen/SDL_offscreenopengl.c => SDL2-2.30.5/src/video/offscreen/SDL_offscreenopengles.c (51%) create mode 100644 SDL2-2.30.5/src/video/offscreen/SDL_offscreenopengles.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/offscreen/SDL_offscreenvideo.c (63%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/offscreen/SDL_offscreenvideo.h (92%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/offscreen/SDL_offscreenwindow.c (83%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/offscreen/SDL_offscreenwindow.h (78%) create mode 100644 SDL2-2.30.5/src/video/os2/SDL_gradd.h create mode 100644 SDL2-2.30.5/src/video/os2/SDL_os2dive.c create mode 100644 SDL2-2.30.5/src/video/os2/SDL_os2messagebox.c create mode 100644 SDL2-2.30.5/src/video/os2/SDL_os2messagebox.h create mode 100644 SDL2-2.30.5/src/video/os2/SDL_os2mouse.c create mode 100644 SDL2-2.30.5/src/video/os2/SDL_os2mouse.h create mode 100644 SDL2-2.30.5/src/video/os2/SDL_os2output.h create mode 100644 SDL2-2.30.5/src/video/os2/SDL_os2util.c create mode 100644 SDL2-2.30.5/src/video/os2/SDL_os2util.h create mode 100644 SDL2-2.30.5/src/video/os2/SDL_os2video.c create mode 100644 SDL2-2.30.5/src/video/os2/SDL_os2video.h create mode 100644 SDL2-2.30.5/src/video/os2/SDL_os2vman.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/pandora/SDL_pandora.c (88%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/pandora/SDL_pandora.h (96%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/pandora/SDL_pandora_events.c (90%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/pandora/SDL_pandora_events.h (94%) create mode 100644 SDL2-2.30.5/src/video/ps2/SDL_ps2video.c create mode 100644 SDL2-2.30.5/src/video/ps2/SDL_ps2video.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/psp/SDL_pspevents.c (69%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/psp/SDL_pspevents_c.h (84%) create mode 100644 SDL2-2.30.5/src/video/psp/SDL_pspgl.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/psp/SDL_pspgl_c.h (74%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/psp/SDL_pspmouse.c (91%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/psp/SDL_pspmouse_c.h (93%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/psp/SDL_pspvideo.c (67%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/psp/SDL_pspvideo.h (61%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/qnx/gl.c (91%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/qnx/keyboard.c (98%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/qnx/sdl_qnx.h (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/qnx/video.c (91%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/raspberry/SDL_rpievents.c (90%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/raspberry/SDL_rpievents_c.h (89%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/raspberry/SDL_rpimouse.c (72%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/raspberry/SDL_rpimouse.h (77%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/raspberry/SDL_rpiopengles.c (80%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/raspberry/SDL_rpiopengles.h (80%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/raspberry/SDL_rpivideo.c (68%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/raspberry/SDL_rpivideo.h (64%) create mode 100644 SDL2-2.30.5/src/video/riscos/SDL_riscosdefs.h create mode 100644 SDL2-2.30.5/src/video/riscos/SDL_riscosevents.c create mode 100644 SDL2-2.30.5/src/video/riscos/SDL_riscosevents_c.h create mode 100644 SDL2-2.30.5/src/video/riscos/SDL_riscosframebuffer.c create mode 100644 SDL2-2.30.5/src/video/riscos/SDL_riscosframebuffer_c.h create mode 100644 SDL2-2.30.5/src/video/riscos/SDL_riscosmessagebox.c create mode 100644 SDL2-2.30.5/src/video/riscos/SDL_riscosmessagebox.h create mode 100644 SDL2-2.30.5/src/video/riscos/SDL_riscosmodes.c create mode 100644 SDL2-2.30.5/src/video/riscos/SDL_riscosmodes.h create mode 100644 SDL2-2.30.5/src/video/riscos/SDL_riscosmouse.c create mode 100644 SDL2-2.30.5/src/video/riscos/SDL_riscosmouse.h create mode 100644 SDL2-2.30.5/src/video/riscos/SDL_riscosvideo.c create mode 100644 SDL2-2.30.5/src/video/riscos/SDL_riscosvideo.h create mode 100644 SDL2-2.30.5/src/video/riscos/SDL_riscoswindow.c create mode 100644 SDL2-2.30.5/src/video/riscos/SDL_riscoswindow.h create mode 100644 SDL2-2.30.5/src/video/riscos/scancodes_riscos.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/sdlgenblit.pl (85%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/uikit/SDL_uikitappdelegate.h (96%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/uikit/SDL_uikitappdelegate.m (85%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/uikit/SDL_uikitclipboard.h (95%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/uikit/SDL_uikitclipboard.m (90%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/uikit/SDL_uikitevents.h (76%) create mode 100644 SDL2-2.30.5/src/video/uikit/SDL_uikitevents.m rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/uikit/SDL_uikitmessagebox.h (92%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/uikit/SDL_uikitmessagebox.m (55%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/uikit/SDL_uikitmetalview.h (79%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/uikit/SDL_uikitmetalview.m (78%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/uikit/SDL_uikitmodes.h (91%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/uikit/SDL_uikitmodes.m (84%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/uikit/SDL_uikitopengles.h (89%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/uikit/SDL_uikitopengles.m (87%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/uikit/SDL_uikitopenglview.h (94%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/uikit/SDL_uikitopenglview.m (95%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/uikit/SDL_uikitvideo.h (95%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/uikit/SDL_uikitvideo.m (80%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/uikit/SDL_uikitview.h (70%) create mode 100644 SDL2-2.30.5/src/video/uikit/SDL_uikitview.m rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/uikit/SDL_uikitviewcontroller.h (89%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/uikit/SDL_uikitviewcontroller.m (72%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/uikit/SDL_uikitvulkan.h (93%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/uikit/SDL_uikitvulkan.m (75%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/uikit/SDL_uikitwindow.h (88%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/uikit/SDL_uikitwindow.m (82%) create mode 100644 SDL2-2.30.5/src/video/vita/SDL_vitaframebuffer.c rename SDL2-2.0.12/src/video/windows/SDL_windowsframebuffer.h => SDL2-2.30.5/src/video/vita/SDL_vitaframebuffer.h (73%) create mode 100644 SDL2-2.30.5/src/video/vita/SDL_vitagl_pvr.c create mode 100644 SDL2-2.30.5/src/video/vita/SDL_vitagl_pvr_c.h create mode 100644 SDL2-2.30.5/src/video/vita/SDL_vitagles.c create mode 100644 SDL2-2.30.5/src/video/vita/SDL_vitagles_c.h create mode 100644 SDL2-2.30.5/src/video/vita/SDL_vitagles_pvr.c create mode 100644 SDL2-2.30.5/src/video/vita/SDL_vitagles_pvr_c.h create mode 100644 SDL2-2.30.5/src/video/vita/SDL_vitakeyboard.c create mode 100644 SDL2-2.30.5/src/video/vita/SDL_vitakeyboard.h create mode 100644 SDL2-2.30.5/src/video/vita/SDL_vitamessagebox.c create mode 100644 SDL2-2.30.5/src/video/vita/SDL_vitamessagebox.h create mode 100644 SDL2-2.30.5/src/video/vita/SDL_vitamouse.c create mode 100644 SDL2-2.30.5/src/video/vita/SDL_vitamouse_c.h create mode 100644 SDL2-2.30.5/src/video/vita/SDL_vitatouch.c create mode 100644 SDL2-2.30.5/src/video/vita/SDL_vitatouch.h create mode 100644 SDL2-2.30.5/src/video/vita/SDL_vitavideo.c create mode 100644 SDL2-2.30.5/src/video/vita/SDL_vitavideo.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/vivante/SDL_vivanteopengles.c (80%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/vivante/SDL_vivanteopengles.h (82%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/vivante/SDL_vivanteplatform.c (85%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/vivante/SDL_vivanteplatform.h (94%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/vivante/SDL_vivantevideo.c (80%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/vivante/SDL_vivantevideo.h (56%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/vivante/SDL_vivantevulkan.c (71%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/vivante/SDL_vivantevulkan.h (74%) create mode 100644 SDL2-2.30.5/src/video/wayland/SDL_waylandclipboard.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/wayland/SDL_waylandclipboard.h (83%) create mode 100644 SDL2-2.30.5/src/video/wayland/SDL_waylanddatamanager.c create mode 100644 SDL2-2.30.5/src/video/wayland/SDL_waylanddatamanager.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/wayland/SDL_waylanddyn.c (52%) create mode 100644 SDL2-2.30.5/src/video/wayland/SDL_waylanddyn.h create mode 100644 SDL2-2.30.5/src/video/wayland/SDL_waylandevents.c create mode 100644 SDL2-2.30.5/src/video/wayland/SDL_waylandevents_c.h create mode 100644 SDL2-2.30.5/src/video/wayland/SDL_waylandkeyboard.c create mode 100644 SDL2-2.30.5/src/video/wayland/SDL_waylandkeyboard.h create mode 100644 SDL2-2.30.5/src/video/wayland/SDL_waylandmessagebox.c create mode 100644 SDL2-2.30.5/src/video/wayland/SDL_waylandmessagebox.h create mode 100644 SDL2-2.30.5/src/video/wayland/SDL_waylandmouse.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/wayland/SDL_waylandmouse.h (78%) create mode 100644 SDL2-2.30.5/src/video/wayland/SDL_waylandopengles.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/wayland/SDL_waylandopengles.h (78%) create mode 100644 SDL2-2.30.5/src/video/wayland/SDL_waylandsym.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/wayland/SDL_waylandtouch.c (66%) create mode 100644 SDL2-2.30.5/src/video/wayland/SDL_waylandtouch.h create mode 100644 SDL2-2.30.5/src/video/wayland/SDL_waylandvideo.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/wayland/SDL_waylandvideo.h (51%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/wayland/SDL_waylandvulkan.c (67%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/wayland/SDL_waylandvulkan.h (72%) create mode 100644 SDL2-2.30.5/src/video/wayland/SDL_waylandwindow.c create mode 100644 SDL2-2.30.5/src/video/wayland/SDL_waylandwindow.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/windows/SDL_msctf.h (97%) create mode 100644 SDL2-2.30.5/src/video/windows/SDL_vkeys.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/windows/SDL_windowsclipboard.c (67%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/windows/SDL_windowsclipboard.h (90%) create mode 100644 SDL2-2.30.5/src/video/windows/SDL_windowsevents.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/windows/SDL_windowsevents.h (83%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/windows/SDL_windowsframebuffer.c (71%) create mode 100644 SDL2-2.30.5/src/video/windows/SDL_windowsframebuffer.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/windows/SDL_windowskeyboard.c (61%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/windows/SDL_windowskeyboard.h (83%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/windows/SDL_windowsmessagebox.c (73%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/windows/SDL_windowsmessagebox.h (91%) create mode 100644 SDL2-2.30.5/src/video/windows/SDL_windowsmodes.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/windows/SDL_windowsmodes.h (63%) create mode 100644 SDL2-2.30.5/src/video/windows/SDL_windowsmouse.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/windows/SDL_windowsmouse.h (86%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/windows/SDL_windowsopengl.c (74%) create mode 100644 SDL2-2.30.5/src/video/windows/SDL_windowsopengl.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/windows/SDL_windowsopengles.c (77%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/windows/SDL_windowsopengles.h (84%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/windows/SDL_windowsshape.c (54%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/windows/SDL_windowsshape.h (82%) create mode 100644 SDL2-2.30.5/src/video/windows/SDL_windowsvideo.c create mode 100644 SDL2-2.30.5/src/video/windows/SDL_windowsvideo.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/windows/SDL_windowsvulkan.c (77%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/windows/SDL_windowsvulkan.h (93%) create mode 100644 SDL2-2.30.5/src/video/windows/SDL_windowswindow.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/windows/SDL_windowswindow.h (67%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/windows/wmmsg.h (99%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/winrt/SDL_winrtevents.cpp (64%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/winrt/SDL_winrtevents_c.h (76%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/winrt/SDL_winrtgamebar.cpp (78%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/winrt/SDL_winrtgamebar_cpp.h (95%) create mode 100644 SDL2-2.30.5/src/video/winrt/SDL_winrtkeyboard.cpp rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/winrt/SDL_winrtmessagebox.cpp (82%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/winrt/SDL_winrtmessagebox.h (92%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/winrt/SDL_winrtmouse.cpp (71%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/winrt/SDL_winrtmouse_c.h (95%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/winrt/SDL_winrtopengles.cpp (76%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/winrt/SDL_winrtopengles.h (72%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/winrt/SDL_winrtpointerinput.cpp (61%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/winrt/SDL_winrtvideo.cpp (70%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/winrt/SDL_winrtvideo_cpp.h (74%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/x11/SDL_x11clipboard.c (50%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/x11/SDL_x11clipboard.h (57%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/x11/SDL_x11dyn.c (70%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/x11/SDL_x11dyn.h (71%) create mode 100644 SDL2-2.30.5/src/video/x11/SDL_x11events.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/x11/SDL_x11events.h (79%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/x11/SDL_x11framebuffer.c (70%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/x11/SDL_x11framebuffer.h (69%) create mode 100644 SDL2-2.30.5/src/video/x11/SDL_x11keyboard.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/x11/SDL_x11keyboard.h (74%) create mode 100644 SDL2-2.30.5/src/video/x11/SDL_x11messagebox.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/x11/SDL_x11messagebox.h (92%) create mode 100644 SDL2-2.30.5/src/video/x11/SDL_x11modes.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/x11/SDL_x11modes.h (55%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/x11/SDL_x11mouse.c (57%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/x11/SDL_x11mouse.h (79%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/x11/SDL_x11opengl.c (64%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/x11/SDL_x11opengl.h (57%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/x11/SDL_x11opengles.c (81%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/x11/SDL_x11opengles.h (84%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/x11/SDL_x11shape.c (50%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/x11/SDL_x11shape.h (77%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/x11/SDL_x11sym.h (88%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/x11/SDL_x11touch.c (82%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/x11/SDL_x11touch.h (94%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/x11/SDL_x11video.c (74%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/x11/SDL_x11video.h (80%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/x11/SDL_x11vulkan.c (77%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/x11/SDL_x11vulkan.h (93%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/x11/SDL_x11window.c (55%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/x11/SDL_x11window.h (76%) create mode 100644 SDL2-2.30.5/src/video/x11/SDL_x11xfixes.c create mode 100644 SDL2-2.30.5/src/video/x11/SDL_x11xfixes.h create mode 100644 SDL2-2.30.5/src/video/x11/SDL_x11xinput2.c rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/x11/SDL_x11xinput2.h (84%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/x11/edid-parse.c (98%) create mode 100644 SDL2-2.30.5/src/video/x11/edid.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/yuv2rgb/LICENSE (100%) rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/yuv2rgb/README.md (100%) create mode 100644 SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb.h create mode 100644 SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb_common.h create mode 100644 SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb_internal.h create mode 100644 SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb_lsx.c create mode 100644 SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb_lsx.h create mode 100644 SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb_lsx_func.h rename SDL2-2.0.12/src/video/yuv2rgb/yuv_rgb.c => SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb_sse.c (54%) create mode 100644 SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb_sse.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/yuv2rgb/yuv_rgb_sse_func.h (93%) create mode 100644 SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb_std.c create mode 100644 SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb_std.h rename {SDL2-2.0.12 => SDL2-2.30.5}/src/video/yuv2rgb/yuv_rgb_std_func.h (92%) create mode 100644 SDL2-2.30.5/wayland-protocols/fractional-scale-v1.xml create mode 100644 SDL2-2.30.5/wayland-protocols/idle-inhibit-unstable-v1.xml create mode 100644 SDL2-2.30.5/wayland-protocols/keyboard-shortcuts-inhibit-unstable-v1.xml rename {SDL2-2.0.12 => SDL2-2.30.5}/wayland-protocols/pointer-constraints-unstable-v1.xml (100%) create mode 100644 SDL2-2.30.5/wayland-protocols/primary-selection-unstable-v1.xml rename {SDL2-2.0.12 => SDL2-2.30.5}/wayland-protocols/relative-pointer-unstable-v1.xml (100%) create mode 100644 SDL2-2.30.5/wayland-protocols/tablet-unstable-v2.xml create mode 100644 SDL2-2.30.5/wayland-protocols/text-input-unstable-v3.xml create mode 100644 SDL2-2.30.5/wayland-protocols/viewporter.xml rename {SDL2-2.0.12 => SDL2-2.30.5}/wayland-protocols/wayland.xml (86%) create mode 100644 SDL2-2.30.5/wayland-protocols/xdg-activation-v1.xml rename {SDL2-2.0.12 => SDL2-2.30.5}/wayland-protocols/xdg-decoration-unstable-v1.xml (100%) create mode 100644 SDL2-2.30.5/wayland-protocols/xdg-output-unstable-v1.xml rename {SDL2-2.0.12 => SDL2-2.30.5}/wayland-protocols/xdg-shell.xml (86%) diff --git a/.gitignore b/.gitignore index 728cae0..bb00b4c 100644 --- a/.gitignore +++ b/.gitignore @@ -39,17 +39,18 @@ ReleasePackageInstaller/bin/* ReleasePackageInstaller/AerofoilPackageDefs.wxi ReleasePackageInstaller/AerofoilPackageVersion.wxi packages/* -!SDL2-2.0.12/lib/x64/* +!SDL2-2.30.5/lib/x64/* CMakeCache.txt CMakeFiles/* Makefile -SDL2-2.0.12/CMakeFiles/* -SDL2-2.0.12/build -SDL2-2.0.12/config.status -SDL2-2.0.12/libtool -SDL2-2.0.12/Makefile.rules -SDL2-2.0.12/sdl2.pc -SDL2-2.0.12/sdl2-config +SDL2-2.30.5/CMakeFiles/* +SDL2-2.30.5/build +SDL2-2.30.5/config.status +SDL2-2.30.5/libtool +SDL2-2.30.5/Makefile.rules +SDL2-2.30.5/sdl2.pc +SDL2-2.30.5/sdl2-config +SDL2-2.30.5/test/* install_manifest.txt ## macOS @@ -61,7 +62,7 @@ AerofoilMac/*.xcodeproj/xcuserdata/ AerofoilMac/build/ AerofoilMac/DerivedData/ *.xcuserstate -SDL2-2.0.12/Xcode/SDL/SDL.xcodeproj/xcuserdata/* +SDL2-2.30.5/Xcode/SDL/SDL.xcodeproj/xcuserdata/* AerofoilMac/Resources/*.gpf AerofoilMac/Resources/Houses/*.gpf AerofoilMac/*.xcodeproj/project.xcworkspace/xcuserdata diff --git a/AerofoilAndroid/app/src/main/AndroidManifest.xml b/AerofoilAndroid/app/src/main/AndroidManifest.xml index ec74e34..b0faf66 100644 --- a/AerofoilAndroid/app/src/main/AndroidManifest.xml +++ b/AerofoilAndroid/app/src/main/AndroidManifest.xml @@ -75,12 +75,17 @@ android:alwaysRetainTaskState="true" android:launchMode="singleInstance" android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|keyboard|keyboardHidden|navigation" + android:preferMinimalPostProcessing="true" android:exported="true" > + + + + - - - - SDL NACL Test - - - -

SDL NACL Test

-

Status: NO-STATUS

- -
- - diff --git a/SDL2-2.0.12/test/nacl/manifest.json b/SDL2-2.0.12/test/nacl/manifest.json deleted file mode 100644 index df6772b..0000000 --- a/SDL2-2.0.12/test/nacl/manifest.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "SDL testgles2", - "version": "33.0.1750.117", - "minimum_chrome_version": "33.0.1750.117", - "manifest_version": 2, - "description": "testgles2", - "offline_enabled": true, - "icons": { - "128": "icon128.png" - }, - "app": { - "background": { - "scripts": ["background.js"] - } - }, - "key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCMN716Qyu0l2EHNFqIJVqVysFcTR6urqhaGGqW4UK7slBaURz9+Sb1b4Ot5P1uQNE5c+CTU5Vu61wpqmSqMMxqHLWdPPMh8uRlyctsb2cxWwG6XoGSvpX29NsQVUFXd4v2tkJm3G9t+V0X8TYskrvWQmnyOW8OEIDvrBhUEfFxWQIDAQAB", - "oauth2": { - "client_id": "903965034255.apps.googleusercontent.com", - "scopes": ["https://www.googleapis.com/auth/drive"] - }, - "permissions": [] -} diff --git a/SDL2-2.0.12/test/picture.xbm b/SDL2-2.0.12/test/picture.xbm deleted file mode 100644 index c873a60..0000000 --- a/SDL2-2.0.12/test/picture.xbm +++ /dev/null @@ -1,14 +0,0 @@ -#define picture_width 32 -#define picture_height 32 -static char picture_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x80, 0x01, 0x18, - 0x64, 0x6f, 0xf6, 0x26, 0x0a, 0x00, 0x00, 0x50, 0xf2, 0xff, 0xff, 0x4f, - 0x14, 0x04, 0x00, 0x28, 0x14, 0x0e, 0x00, 0x28, 0x10, 0x32, 0x00, 0x08, - 0x94, 0x03, 0x00, 0x08, 0xf4, 0x04, 0x00, 0x08, 0xb0, 0x08, 0x00, 0x08, - 0x34, 0x01, 0x00, 0x28, 0x34, 0x01, 0x00, 0x28, 0x12, 0x00, 0x40, 0x48, - 0x12, 0x20, 0xa6, 0x48, 0x14, 0x50, 0x11, 0x29, 0x14, 0x50, 0x48, 0x2a, - 0x10, 0x27, 0xac, 0x0e, 0xd4, 0x71, 0xe8, 0x0a, 0x74, 0x20, 0xa8, 0x0a, - 0x14, 0x20, 0x00, 0x08, 0x10, 0x50, 0x00, 0x08, 0x14, 0x00, 0x00, 0x28, - 0x14, 0x00, 0x00, 0x28, 0xf2, 0xff, 0xff, 0x4f, 0x0a, 0x00, 0x00, 0x50, - 0x64, 0x6f, 0xf6, 0x26, 0x18, 0x80, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/SDL2-2.0.12/test/relative_mode.markdown b/SDL2-2.0.12/test/relative_mode.markdown deleted file mode 100644 index 5b2ed61..0000000 --- a/SDL2-2.0.12/test/relative_mode.markdown +++ /dev/null @@ -1,58 +0,0 @@ -Relative mode testing -===================== - -See test program at the bottom of this file. - -Initial tests: - - - When in relative mode, the mouse shouldn't be moveable outside of the window. - - When the cursor is outside the window when relative mode is enabled, mouse - clicks should not go to whatever app was under the cursor previously. - - When alt/cmd-tabbing between a relative mode app and another app, clicks when - in the relative mode app should also not go to whatever app was under the - cursor previously. - - -Code -==== - - #include - - int PollEvents() - { - SDL_Event event; - while (SDL_PollEvent(&event)) - { - switch (event.type) - { - case SDL_QUIT: - return 1; - default: - break; - } - } - - return 0; - } - - int main(int argc, char *argv[]) - { - SDL_Window *win; - - SDL_Init(SDL_INIT_VIDEO); - - win = SDL_CreateWindow("Test", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, 0); - SDL_SetRelativeMouseMode(SDL_TRUE); - - while (1) - { - if (PollEvents()) - break; - } - - SDL_DestroyWindow(win); - - SDL_Quit(); - - return 0; - } diff --git a/SDL2-2.0.12/test/sample.bmp b/SDL2-2.0.12/test/sample.bmp deleted file mode 100644 index aca8bbca6e0068329c988d63f4a1e8affb15ecf4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 69202 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 diff --git a/SDL2-2.0.12/test/sample.wav b/SDL2-2.0.12/test/sample.wav deleted file mode 100644 index 002f8158151d600e52930f63b0e832508b6e2c90..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 121946 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 za`=$&7XbnU2oNAZfWW)JmHBGryYKP)mjD3*1PBlyKwzxEsu^!=7FHubfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oT69 F@P7^ZPXPb` diff --git a/SDL2-2.0.12/test/shapes/p01_shape8.bmp b/SDL2-2.0.12/test/shapes/p01_shape8.bmp deleted file mode 100644 index 5adca298f715c601d0290c5210760c8614781cc5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 410678 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 diff --git a/SDL2-2.0.12/test/shapes/p02_shape24.bmp b/SDL2-2.0.12/test/shapes/p02_shape24.bmp deleted file mode 100644 index 61e411bb774ee38e755e08b7bb598d728cf1adc7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1228938 zcmeIzJ(4U-QU=gFs7N3oA+rv2G}iD|fq*=l}l4Uw{1f=f}VQc>Md%zuW%(>DNE~@%67?kKg~{?|=Q}-}c2H z|Nr}6|M!)?OUG+5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7CJOxC?Z1gd*_r?W0t5&I z5$N`sJ-u)c5XT@ufB*pktprZL3xnOz%E3AW2oNAZpoc)P*Jk(Q^f0t00RjXF5cnw2 z{SCL&1|PXxK!5-N0tBuJEcHH|eAsKk?jk^d009CIfywW%MB9rK0RjXF5ZDn&^u`Na z%FZM369EDQ2viUV{gx_oxC%*ABLM;g2s{MJyxA5jR5%F`AV46cz+!Ks!pBV+KSdEB zK%kmH;rH0`rB}lFG1lkHrkF*02 zAV46pK--aPH3F{!k@N3t1PBlqFYr1ieM6w1!1#pQkpKY#(FFRcF2Oi?Exa7SQR%h-qj0RlG# z?#w#(5{M~qvnkw8fB=E60x>72QxRw-(6xOmPJjS`YXYrCoOK997P!_O?jk^dKo5b) z)6&@p^bqLLN7f`jfWUEq9+S=ebpMK6yAcDa0j&mge0t6lc5eAnt z5Xd25q!1uL;GjT`p{EK0aRd&wp34XjC@Tn|n!tV! z`jr5IY68(_l=BeCEl_R3sFwhN9|dv`I@J+~Dez-6`jP;FIs!3AlT#6>AW&z{sFVPK zXMqayO^pQN3p{tF&jbjh7l=QUoRB~rf%F4MfdmLV1nSH*l@eG>zDyIRsW8JI+slz$TDmBB_Ev1p!lw0D*i0 z6=s(j2`nv;Z|tau0D(Cxoy1ab=)Qv?X)7RWupR7YS@f!t$9bp!}(0*ekP$0m?f zz-S^sppHP+Ii@ZGYYEhuIVvSU;8|d;N#(Qzk_kLFqt65gR1-)x(3C@96@hA_M!f_G zyb7!`ubh)W8iCg~^bG+5H3ia)HH8p}FHm#HsG0zQcLMRJmJjMeNTWuWq}04 zO$h|T3RIpgY9~P8h(Or!`QP6Aq+009E=1v(8t%MzF+5Wnf1kN^P!o4~9&XXr@0t7aJVPn%q1nvuHTLJ_KWD>YP6|F#Ej6kNo zQwsqC1jbBGyAZf3pj8PFAdpYs=3sO?f!+f7nodOo2oTr=de2Ym6Syp(NeK`jkXzvL zcyuFyege6hPIUwb5ZDCzO;IZoxF(=C2@oJqLEzeibQgh60u`E0jRXh~*aSKaQp*xJ zE1)F_5Fk)Z;Ov}qJ%Q!|)tXMd1PBn=1e%Xi3lcabpc4rYAW&1_)TneZfwlrQn@-gP z2oTr=+D=rf5jZHI0SOQwK;YoObQyt$0{V^s0RjXX4pmDLI3l3w2oNAZU=uhpGhIWV zm4Ln@K!5;&O`z3WwGM%g0-BBh0RjY`1wM{V7ZA8F@Ekdx2@oJaU=z4MU9CW1UqG)B zAV7e?tHA!`^ecgz0e9fB=Cz0$=0Q2Lh)A?xfDW1PBlyaBAebn7}5WaR?9~K;XWBcM5@10{0_l z1p)*J5ZDAxjb9fR7tl2X2oNC9N}%`)Mfs-$TBXi91PBlyaBBRzxUzs|AwYltfwlsb z-zjQ8F3>i0RwF=w0Di+Z^h=$U2@oJa;K&?yO+f*zL4W`O0=)$azFd_2QJ{C~tWSUd0RkUK zu?wmRXbJ)Z2oM+}Q0@Jq-hF{Fsj~|K0t5)`Ph-E963`9=2oNAJQlQi;MzK2rBU5KD z0t5&U*cr%vDkY#72oNAZV5C5)SBzrc35<-Ky$BE>KwuMiH5c|QA`TR`RsEGn?yn2Q$W*aY^2?bl2K(oP`0K&y_6U#SxkXq9&B1Q!r>0?`D< zw@fqv=OHk@3+y;vK+XwF6c``)<2z1du{D9?L3QQ20&-4Zyue!hGTz6I1lH;ir@bH` zsRaq7=?;Z_2}m`8Rsvt4^5ILMm92FMe1*z~Gy+mh;J!ebcIZ^dePJsQ z=oC)N&Jqx50yhO_MR&!0Z&JIRz>2YV=63?}OyIJ>yHNRlU*Iyh8wu=3%dZOw2s44p z0t@9l;88ELyOBV^JUh|_0ZArsP2fV<-11G}n!LLRd<&947Zs3X0%rvlje6K)pY?Y= zfv{nAu;T(^OyI1*@pQTJxWL(`;Cceb)8)#T0y0eClt9cF=Q!1=2jOA@IbvVA3K=GF zP@r;~jI90O<8T>)k+HN_a{&P+a8RIm_AIy~aPXnHjKEHc{1jY3dI@|K2%h1@$NTtb zTtFak{&SZmx&%H79Rswfp<^J_XOG|&1z!=kfSd`Vy@GkyvvAh86#2?R{3BmF4w?ZNqzz>hicWmo};CGac|HmDBvqrmgC^O?Yp zA@OBQ0dXbpED$rLPPH%a`~-a_u%8yc#u1QJ0?z_*lIbMJ1)iUv&jgMq$CYyhWR<{| zz}zU>{f@xbL-c{bogle)q=2jv*aSwV&R#tPB$f-TM zex0Zn%_-^Q!KhE9;*U5XhPWr$XZ5lma!Auj-UxUbHA_ zEGV#ORvo*!K*8`Uxp|5#cv(Oi3kqCLiyM;(6b!$TlVy16a-^}Ez|wJb_~ruD@~__J z5whTA0corza5*Y&Oes(;|LRQ{<3)>-#!>={rqr>!3Y2OA#dgh-#g7Y!Vl{!|*>GhY zfoff#-a6TiT&WzE5{Mi{XPYZfsu2`BH*9v_1mv)kfY=jwCs3*p6#Fg)z8@(dhouBY zM$2An36yFC#jX|3tf!U3Is#cUtgco9b$UUitukYsI|6c8N8nCQ+*?7QPA{mmLZ0K- zD2GJ^;z!X5BM1~}2W3VGTk$gpVI6_uQCI#!fjS+b(u0w3StkJrtRv7VLY7S?P^TkQ znk>4@l_P;g1eQyt15Xqv(iF;^m@!*F1SGJCfV2}hE>NT?lzBW7uIwQoffWRLB*&V$ z1uFD~8gpkjesvO9K_Gq(oiLg}g}zW@wA7V4kN8y(C>3eNHWaAP9cpYC7)zZJki7~5 zry}8E0$&0Zx@U~s5xmqwsMcc?KC6K;B6c{RR zr4A!|=>|#n`g#?2L)s=x4^*|xQxJ#K<*w<-Oi);Q&$1m%Pr6~JQgn^ zkh@1zS0u*K$`rix0?{JpJSz&MZxaQs7|YeqEOogBR?nyN#}UZgDXNQ;v^pn|y4(VF zlC09+0=YXyb-nXr{Z|30%PsKw#C=2Hnn3POQQfsvxa*F9)a4eqlMVM0coxXrDXM#Z z);^CBkhK<-Xa-MYzK_vBKSTVUN}I(amK z+?}GjXnCt}9;r(#P$9r-94U~vS(G+1NcP$Uq%N_5kP~Ptkhoct);20uJ0c);i3N@X zz%>Mp3nXq9r5%rfD_aRjU1EV&A+ZjDO(1czC{4)63rJmJf$?#&V{U=O&7!p2(T!Q1 z)Fl>(89Ap~S0Hh-C~e(Xu6uH+ODwQ%ES)^2K;mXmTFl7hK9$sE708`i)y)#f+Ar#w zm8i=5N?lfg%Bfa+KY^_MqON|KvGO|ssmm(x?uq-Jz#W0C{i3crsc`Q#0jbL>a4iq+ zBCs!zwO`b=|J?oBLqO`X3iL>eH3?+x7j?<@cmb))Dlk4vcB~+fwO`a#A-&ORl)9_} z(URsoIRvuyi@I{;bD=6kE~~&oA#~K`1hRIGx|WOL(g&8etO85N(&2*(WbGPt1rJ`b z%e(@|IQL^;!FdKr4Z)U8Am639-%*0eQ&Vl0O)CL;%PP<+A=V-ADv-5n)b;wT zebZGy zU(~g9EEhez)MXV|G?0!RTp(+|s4IBzQXWt0vI?Y(tD>e0WbGGqO^;T=14vy~fr4RH z@&JLX{i3b`;jzUx0jbL>@a;kSlRy)Jto@>{Ch@SyDFLZVEO06bE++6%AaS!O?c>vT zL307AODxblEfy>;khoctRy^BN%9pyt0#g!Y)5HRan?-4fa~rlasY@&nHgyiRs6gUo zQQD%JT>98jmsnuwWIB96fyB+Cw19a_eY+D6MT&tad~|>T(Ml$$)DJ91+OfDXKe?0oSw@kh(kh@b(FY3*_z;)g4cQD_aRjU3!65QL#>C zf%I*nz{>HSSi9im7MK__-9FOE2&-11=!2Baps96u9&B{nS-J_9_T;jgZ9?3smS1H6{*l z@X}?Ba3JJi@IJeEBoAbu4DjwHb~1fB&d z^o1IqpSaKC1thS7!1!F*adm+TeWAwHQ@Z;3C9sIV>Opn>kpe}ULYX5&Wv^EO2`nP; z`sjT_;GIB`rcma)0Qi24fCSbN7?UWwtS(TeBUHM2R#!j21lAE)J*&U}3rF#Jk>7Y5&t7m&u90^^fr$7ljIldtM%IV^r2fvhP|Jod%Q zubFvO7mt0w@@2BDK)^IQ(g1<7fmir|blKvRfJ~MZIF%C@rx7R{c!j6QaHc}UvaCR+ z7^~%oK-s7({75`pGhRS4D+`Rzn;mBfRL;5DXQj@*`vQ_#Twp&Qe$63JJmkvH5#xMS zNM>;7U^W=$R~k^K(bUT=OG~21hjViQ6QxR^lAJ)J#|8nCZMTL zwal!G1(m=iFe`!fZ7U$p1ax%Up6a)ntP;?z{rYSC%JNJ=N00Bj%R7oI0S$Y(eL~$R z$prLrsFwVA7>OnDCGasVE(j~|^$>j^5H_U__Dw)m2|NpYi-$j#5O{uqJ`-3Xv<~?Y zkW~WD0-9n)f#)aaGl3N|T=vZ3O5jP z0VZ%zpl$H1_D)cMx$ z%73S$HYc?pflgVq>|6oCCeTA*ZmMVP-b2!w1ZL&gzP$xxn?P5A-T{uVepf(?6NnIU zXXqgy+XMy(^oVYRH3!hyf6HUN*2pmtZE0-1!bpr7PTD4gGN}Z5EtF&7uzJRn7SX5xYxfU(Tu?g%4 z+pn1fq@4f(0tDg+WO~1-<)c8H;5i8a0t6}xd>q#6v+L6fREWJA2@oJKS0MeXM1dCs=4R6F1PBnQAaG$gyQP9ah48D9 z009EC1S-5o)Obx`RwnIBfB=CC0@o(9yNU=@XaO}6AV6TeK#`Y-GA|2^&!im*5Fk)N z;PO~@V;zACji5#X1PF{2sPhI<=^cTQnY0%H0t6}u+?mPlEhSK)9n?sG0D&H-4>uPq2{0;@NR^AjLIpp}640)deNt#WG}0t5)GE--TT+Ka$LVD*-9egXst+!ydV zATVCwer~NmfB=Ej1;)=_I}&&Ztll`zPk;b{I|5z=1SSgHiLQGI5FoIwz{J68YXT2} zb$iFj2@oJ~N5Ct9z;uB-0d_9|0t8kRm_B$NfWRiOV*5BV0RjZB37Gr@LJ3@pvAYNm zAh4D|sKM(n1Rerwb&%5%AVA=nfPqgSpun{-yNdt;0;>oF9K4Q1U=vuSiJX%F0Rm?Q z%y|OA1LTzE zh|_3JLVy5)X8|LcKzf1a!23*q0D%Ys=?AX@32Xup+RYgV5FoG#n9Kx9321x*1PDYB zC^dK$OJEa-(0a~5fIwvd)0jY6fy#}qb^-+E3X~nZ3Ma4$%xyrs6ChAizyu~h;2}`6 z{Z&nXz$^iSmjHn;fmv;6UjhWG34Dzm9|#cG1gZ@I^%5X3UckI1K;TD#@y%#Q0tD&^ z{5W=eNr1p6P-hgVlmLN|0%j}$0v`oNwxqoX5U3#VaqPH&0D(=Q!az_X0Rm$L%vAye zP6>=@OuG;ukXzu?*l{rd0uO=QGeLC(2#gUhP6-gWATXvq?LvS+R)Gs+$1Ma1Yyw%w zg1QJ0=q+H15+HC>pm&p6p8$b;0yoEw+X)cZ1o90B6%ioNPr&3PK%k*OzgD#}0Rou> z8jc-H5g@P$WEv4_AwZyqfN4p9KtF*VJ!?$@1XdU5H*>5^fWVi)>Vv}h2@q&2@HHHK zAV8qEK-=cE8UX_93iO^f)+a#Vo4~r`!pR8`XeID%EclZEfiVKDTG%=S2&^bDX3p4! z0D&I`Rva46On|_BfgcBgF9{GBEO5VWgbfIxhKDTBqP1PB}vh(AD_kN|;e0!Jo*YX}gSC~&Q{-9>;vWPynz#nuD} zoDzsUNt}%Uf#U+F8sEhP2t*J#-r%kzKp>_-gh}EI1PELZh&fW6iU5Hl0vB4|Ed&U} z5jfK3t|34mnn0Wx;v@tJTo#BnSe%Cdfqj9?&F)451Of`|_q$&S5QrcUaCA5l0Rs00 zB8(SjAVA=q!2KS#0s#VH1>QBj?+Fl?D-d>QI2Zu}4F%@T8M_l8@GQ`MV4)G=s00Y~6Bs{y>`0)p zK)+tLG64cB3RIqlY9}y8V8zMc%mfGw5EwIp>_VWXz@H3?J@n9{H|B|spP zK!s7MMgnaGGED%r5FjvDpzU#NovGzs0;>xIY)MBVK%kVs>QmJD37i!u z)!>RHKp?ol*$L))0xJpxZ$rl;K%l0;isRIo2^<%w+1IKjKwuSt{;8`H@jCD2wuL95M^_c(x0!s_L zjyT^Ch$*miqd7bQ0tDU(#2mR!Mc`dxeNTV@flLCXJ%Km^nL0}?1PBl~C=h1|J4rQx zgAsKZ0RjXP3sjr@>YXc)xRsPffB=CD0&{1w-75%Oh^1Qy5Fk)Tpu&qljUxr>^o~ji z5Fl`0VB~zZS5|@hIkW-+0tCtmWPLTLtDivGW>Gi+0tA{1^qbXI&Lq%0corl;fB=Dq zK&Cf^TG|R|5CQ}U5EvlPc63{9U4a2%vjqVH1PHteto!0{@;d^rN$?E;0t5)m61X$Z z-5XzER<7(zfB*pk2L&EVzK*I-WDFOrt5Li*b3vrCV zirH{x0t5&U7$z|0WmI98VUNs41PBlykWZk(i?UUX`JTRt2oNAZAc#P#S5=O6f;<$* zAV7csfocLdUZcmWsP=r-OMn0Y0&58zf1|~`axHDAB|v}x0RkTd;=FJ_9@PZ|2oNAZ zAiY4p_i}nV1ri`YfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk I1mX+)KN!N^pa1{> diff --git a/SDL2-2.0.12/test/shapes/p02_shape32alpha.bmp b/SDL2-2.0.12/test/shapes/p02_shape32alpha.bmp deleted file mode 100644 index 6497a7b0d82aa7004b8c3fc5fffa9c0da5a05c16..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1638538 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≪sB=ibc%=ljMh;uzaps_2okKh> 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 diff --git a/SDL2-2.0.12/test/shapes/p04_shape24.bmp b/SDL2-2.0.12/test/shapes/p04_shape24.bmp deleted file mode 100644 index 8cf61298637606882c94a3f38a71755a44d6ae12..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1228938 zcmeIyJ(4urQ3l{ETr9A#uvrH_9&6AlFtD{EOboV!M}+vUIy9Q-p6;%$IzRdI+|Z|( z>8Y-h`J6ZNU;ph-|NW1@{r=yde*OE8U;qB|?{5G8@Y_HA{_$_W{rdYq{QYl#`FH!^ z_y7O%U;p=)U;gm7Km7LZ|Mk!R_t#(l_{Tqf{ro@w`!Bz~^tb=Mf9G$X`iTGm0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0tAi={Mmm52>eCh_|$lk009CQ1?*h{1ilMg94KEWK!CtOf$y8g&jbh@ z92}1kAVA=XfMrX7z@xyGnetr%1PB}vc-%ZbAwb~B?0AL%0RpE5tXTpCo(Y^DD_A@)ZIE2)qzDvUxm1fWV6(@+SfW2z)AFsS+S?T;S9B@;m_o1fB^T-#nfq zK;YRN`J4a&0v`!jrvwOmD)7;Wd6)nJ0zV3Tx_LZLfWVKVpAaBG;GlpNN`Sx>frEqQF#-e#+zDLSJibeSz}-Okl>h+( zM+7WS0tBuL9GNxG5FkL{OW^w2@dg3}ZUSFp%vd|#Nr1pjp!06gI{^Z(1?))z1m+36o<4siK%lL_ytU)a1PI&&+O8Lk z6Cm(RzJ%P+K7K+EE(;0ylx$ zTS#{VdJ5QY1PH_z=((MAO`xzq{I#P(0t9XXg%^?52s9M1*$5EGBG7O_X_-J(fh=oB zodgKn1gh>LeGzCSV4)EpkWrx3n$j$Rk^&hwkD3V(D7lU_MWBy>B}RZiUV%QFN~Z+s z3FO^8Dkngo-bT_9fhGdh7Xbp<1)3}?Z4#&?kbUi_p8$cIK&8E;7Xlpw>@ETXY6x`L zS9&B+Mxe&p(FFklH-R#%Nh1Wx3)or&2via%zp^w)poT!DwWAjT1a1N~wv#Rh6c(_o z2oR_$PZywzdAdr1Wsh>be z0jr4sfer#C*O#UUq!#F~dGtttK^t60q=1D$;75V$Y5(!HJ|u8GTHZjQ zhJbBA;7(v{uUkCYt z!0fPjKY`!^mH>g9z{;R9C$K(sD--T40!IYw0Rl&IGUFNY1ZL#QI|-x^F#ZJg29-a7 zy$N(Wfn5S-zq7!u)IFZt`4;s4mAy^WIP(cqYHfYj`zU{()798F-hfB|nJFgr-=-{0iow7EW7 zP9(5Kz;u@vSQDgOrCxuigo^uBGgJ}GS?25IsI6safFhjr~R}z?!kV@~Ybk};RluW(!6fnhQ1bPPe)2_>0w?;m_ zde0LGC18YW2!sk%iehTqyDn0MO_2m11q^QifyZn0$#H=K0nozn>-HppI07a&yFi>Q z<*g)p2GpN7dn#`$U~E$hw9W0L##4tu@sm>FwFD*!nAxNPlk(uTzXXy-LfO(wAd!H9 zO)8KmV@XR*8VqG8&6~0t3YgY(0u58TvE_8}Q1HgIIGVt50i&8r;P}mYa;!kEoTzr} z?Ry)6;R1#xWKX`IOw84@E|Gg z;{EzMfw2NcGP1zfyY{v<0+AD?wlx`W3V|a6<}s$gk-PIuWPzBuQdQ*4sI8TNVT>uz zDujibjhQZ06^@+N5(${ZXab4Cqtt@}(K4ocWn!K6UEa?G#tN9P zWddU_&f7W*EDNoJI>$`!Qw0py8iA>o=;dt%)}+@dZ3Cw9c>>02fxx`$^JW4!fdw&k zgs>49D`2K(3yi%lZzJ$bV0Mzd|Czkc37ilxP*Vj?+=#CbxF|3+(q4Y?c6^<{mw;)S zB=9Bd2Lf9JCI#DTx7?;f>j@a8NdonvqN9uglj7~Q8N;CFXaeSFhCsAiR!?Vv8435! z&WY0d5CKCpNnptBcnN_a0+T}SwL@;lOWF#Uph*I46Q%Kh0+T}SwE^#1Nm&Gp&pd%F z8Bk{jfq6Oi<_`JM<8T3kGgV;teR&~)(*jeY?&YWN#TVNOn3|~qZF8mZfC5va?&Se* zTuG4yjLd9-$hWVyZUVE@?)}{orQa(8=4H0PmD}-M0%HYcr``L<-j}x(7BDOe1PbRz zYv}|Q1l|$pQla220w!gFz?PeJD1jdZ76jfAKg#=%z;^*-vPR&$xt|H_6`Afhz(llkco6H|4t}1q{Vvfs!fGR8oP(;dflpoG5#e zfQeWvFzFt>mcR*t#o>3{i97O@sshGgy+GA0=_{ka`usaFV@}jOL%=Mo7npI6-bvt` z!20|<@!U=MRxtsCutlI)inNnjV9N+NG<9YaKSaP3Y!Mi8cV0qZh`^Q+aOjY`^OC#* zMqrmf-pr`Hp1`gtaBjUU>FBtC{O=Mten*}pFk4{P6gYSG&3b=W0pZ^$5H=MGYbdaB z5FFhwZ(0`ny#f+QAdbM^S#WxsB&cMKfXwd|SaZuxA#g-s?<_d|$Q^m6jDWyz7bue@ zjT8{rJ`M^fkRmM{6p;4q0tau(V+0lmY##>&EVyMyL=X`52m%q3paudrfd~_!25Iad zAmMV+Swggl7A=^OM#0>cG@423d=->etL5fJY<0&!BI5(07N zLM75zRY11m2vp6OzA_5LnG2O<%#WJi3J7*6fw%YN0RqbeLXC!EmfgF9mI+98D1l}7 z?jQnh1wxI6V&2}D2XYCBbToln`B80cfoRjAp4xfq)}1^@6X=#e{YDmuHXZ7ToEEix zBp}QI1wOh#4-=Rw5O6@0H1)>4e3^hG2NYO#`wk-TRv_SjDCzC3c_6-k7{?TdpBxqT z5r{b>s_K)#lAQ{0Sb>sx(^OJ{uw$aIq={1YF9GQdD%q4K-PCY|ljX@X`Hxn7~wlbmODosd@17;{u|X zQQ-LfdXm6wfs7NR=Gm$6{v!f%m{H)!&3cBw8i9-xq~I0TrpP7&1qP~f3r$iQs?E-ME6{tWEGeeBK!Jhk+(Ps8?rOhtKd|@FXemyfupmXq2_dY2PUQ6JFKOc< z_LYGGowJv^_kkJkDgqY;Qjb#S;xFF2uU{AF9KXE1U%z*6ATUZG?;LfmeAMlG&lQ2r z3C!F3l^ge60%Ha8&Qa&e$7aCWP78DnVbb1D-?c9i7%q@>h&q=&JOf^MMWAyOGxmPv zu6>ulSb>Za)Vb!dx9@G&1v;lOWAE2*+#3jt6393~oogO-@7^;|pmQM8^*-?4y^6p^ zfpp{3x!{X;?dy{SI%hIn?~^j%wFFKGq#K{k1)sQIUs)s2IhMJ4Uy}!?5I7=`Yj!$U zd*n7fvr(XPI1}~0F(Hm7a3_#xa5|TIcWZtPD9|~diFyy193{0CNHjQ|OKqFaT#a{* zXqMh{B}%om1+q*{=Q?XAuu^xOQ<|msN_o>uc7ZHY)49&<8EaL4=b)zOy;T}D8(bj8 z$aF3;cz%@kD9|~s@q2%~FP{+DB@lmJI#;+W70$gP&^fX3d%tqCzDr=NK>T^>T;bTe z_O@jLokJVE_hlJy5P`P>!H1=Dd2jE|17QU^=QeonVKbw!h62HdrE_@=(^#qH&e4tB zd!>x&CA&c6N$Ff$_FSp|mq6zLhwWW53B(ZyJ0_hAixUr(ToLG;;jq15xlrFFFjgS! zm~<{|>=k?4MuE;Tj@kRhFgTjPoj}YP>0H&_1^G3#K<6aK>^*gy6kkjr=8SZ%s#w6Z z(>crmdlyIoaRdSmNavE`1VbgG1UlzAVDF=@)q4nB7YH~YolClYq23TspmU_7^&T)D zN@^<*Z8|#F(>8?V8}FRzXuX#Yn+6jJM4OJz^(2aoQa=^w9PCiNe|mAACooSS)M#`r zX5JNha}a^f@s87bkT58Nz%PL~bJ4jHQS2blIpJ}7?~pV-W)X-p7o97~k`{Gd6zClC zAiZC_L0=~@P$0-qbS`7yZF*I3fzCM((tGfPD6f@3kfG>YMytGOwsX`Y^e%w};s`{T zh|V>{NrFn&2y{++gx=TOvQr2g5r{AmoohI9N1iDr&^hqidoPwH?W7jiJ`SA=NSz$T zUlHgW`@Owixi#M^*v0E`iR;-`jhxoT#?8z}{Kte0uF%>F%vS=kRar z{q4PYfWR_=jf2qn=wsgD6nM&Iv=|6 zt{ojvpz|zj={;Zul+;#W%LsHnv~AKf{!F0rIIQpe*)8~-zIGy?DN%K<5Ej)_cQTX*sOGve3%h zI#0@)-Yca=FWCjwWWMt$*%PAv#R8p&WkK(YZ_{xEUI;7*eCH!x$omt49|bzk%Yxp2 zH1{EaEdmPy-}#6wck0mW0-Z-@cJJAcrXtou_G8@3kYO zy9ffy!rb|w2p6q}Vgj89YGv=mVxyfP0xL7z`K%z5~au40_$_z`NY|`>HW&x<20#gM#k6ysur{1-fZx;v{xy~hR&w~O8bRNK%y~|`h zftX3_Tvfe{=_sQ>=NXLLd&VrO`B5Np#yZ#bcvC(hutlKr7)I`WOBftFP#|);I@dPv zioJ@!MS;$f7{B+6m+R|W1mfqabA?+X;ZOq41Ue66ir$}HoX?{Pq=-}JBBKRHJp_IU zbRNkRy-R6)ffPaNTx9$Rsj#O&=c!E8d(Uvj?>bS0I+q$hNGfbA(0MR(_1-q30UOVi zoX*t-43ClsdJiqmNkDRm!wbi@v&K*Talo|+J6zDv{C40Y^ zhmv0}dC{GlDw$GEH5BMP#f5usnB*T@E_}tETl?{@eMlgqK<7a&+&BqXkbr1O^Ip9_?1W56sN= zSGBsh&dqL5ngR&S7U(?S-Fly$rP=TAc3++Qot-7`ClEoP^NjcGJwoa}t)b^lb?*Ap zgm|7nQi0B6-nREFS#5hkog2>*PIVHvF3@?>JNJG)IkVr;`F1+@K08<5Pau>)=V5Q& zd#D_K71R7uI=BCo0Y4DvBhY!|^&ThZ?xM3moE)lzz)FG6Q?K`%z{^YY}1OXd>z)fIf8krMVpSqO^cNT$z0#*TmFM)%ZIsMqzL4F`` zIz_%npp1Y$K;TYbMz-&c@GF5CG4oCW=>)6-0(SyqGko`QzY-W5FmEG}SHLzP@T0)> zNdNd+9}>78EpH%DM!-TK@J!%b$e+E<=LF6r%C`s<7O)lwJQMgd_Rrqqa{`}c$@2s{ z2-pk+UJD$Vg4b{GR{}>;wZv~#s#oI4>fWWix_?!R%`+>j_fyYTX@-5F0 zcubB@2oU%Zup$T$ATUGVYsvV50D&I`X3U*;5+Fd}$A#lV0tCJbSQG>Z5Ev`)eZ%;f z0D%_*V@J>12oUHj@M6{Y69EEu0-bk--U$#GD{!}7{7QhpYk{!?=xqcD^b~l#XZ)1_ zfk%O!yF%9l2#ghY+$}yKK;W&w*fI1r0tC7Vyj?OLAVAcgB zBLZWG(c1_R=p%4s!+3@OffoXO)`d<95Ev!!Vx{;K0RjgFM$M!55FpS;;NW`k7y$yW z1^O%vof05$UEuXT@mB%_jtg9$M{giNppU@u-Qr0C1l|htSsgkhK;VkN+hyVb0t7x1 zxH6BvOMpNhfsYo8hY1ikBG6}n=#&6~a{@;;iDw89I3aLuBz=njfer#ER*J6>AaGEi z!w%6S0Rra)4z3Z85g>3*;M`#P76Aga1)Bk2z)xBo+m({s=$>^;=2S0oDitG zO!P&7z;S^StHW0a5V$CCd_p}*fIwA&i)+N!2@p6ZP<5r~ivWQm0_XOIZxJ9cMBvDf zdWHajdICchh?fu`a9W_=R?!gw0!IW+FAZNLKwy->kx}&w0Roi-Mr{x8Awb}YK&7ps z7Xk#12wd41zDt0>K!GCz>lp$BY6uKm9bQF%z;%Hdi$xa%2)q`!zALa@ z2@t3uFm`Wv8vz1C1Zu1oT@WDfOkl{O@Dc(9h6_BKS)UUiP(xt&((pn81V#zeSTedG zK;The)Ryob0t99VJkG372oR_tFk@qQCjkNj1!}AsT@WDfU0~pf@G1fX<_UZsTR#&Z zkX>NjuJC381jY(v-!|$eK;XN;*!|#b1PDwO_&&UTCO{ysz|=+I0fq4RXmygN`bQYMm6TF!Kfi(i1H<;cD}D@f%8dJ0Tk2wqNr zz)FFhOH9`UG77BR49+4zV75TUEu>}wJq2cO1Meq5V6i~YRiCU!HEP2EECAGh}21-o4~Rq;2;77wg`0FY5FCQ zMPSQ9a3}!+D+RKwBXtt!Bd~G^b}nobF15!kg2oJ)YfVu376Nu2~b2rM3d z#}Oc~QJ}+4(<6Z_0vlI>qX`gLFOX$5sgpo$f%UWRL;?i13)Eg~x+4%@VEYnK009D9 z1mbTe6%wc|ux0QaN`OEFf!fPWcLX8}MA!goAV6T3K;-SDHUhN;c1^u=2@nV(Pg5C|nuZ_DY3Kum#9gRd9@1R@B;Tvn~x}xiSb4h$&EM-RXru9D$hgt||fq;t0gqS1KV;Ng&RQtAqf7umY8q zo?Zw<5C}W$3L`)ult6@ir3M0(1VRnCVh9k3EKq6n>4m^vfyk4tHUb2q3GCfhPA5=F zAlh`RhX8@#0+kk^UI^?G2tMY@BS0Xgz^;|$Tmm%&V$QXy2oQ)bP-6$`g1|0;_%p6T z0tCVe>{?vTC6HYp>`*I=0D%+&*>|A&3G5O`G2n_MKp?WfuJz?y0(k`@Pqf+y5Xd5s zcL%DRz%GF-)2&Vd1cD3fT4K&6kWnD`I4h3;fkXlscc7XH>=H;c+DaurAilt^Rpwj* zxdh_RvI+?h$R&_#2db99E`eNgty%&EQV8r?XwD^&MIgl>E0O?#bOKp+pgIZc5=b}H z3MN1xi@>h6=3D~t1+q-BItdWSC=h=Ks*u1gfs7NaWf3G7;K&Lt38Akhdbl>mXH z0+Dy1+6e3tNIK5SCO{yUz^)bNTmmr#a?P)52@uFD5OW8rioh;`ytAxw0tC_t>{@ir zB@j&@-S8@y009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly eK!5-N0t5&UAV7cs0RjXF5FkK+009Eq1^yqJ41F&E diff --git a/SDL2-2.0.12/test/shapes/p04_shape32alpha.bmp b/SDL2-2.0.12/test/shapes/p04_shape32alpha.bmp deleted file mode 100644 index 771ebc05337fb29d5d1b94a89d15767d3b54d428..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1638538 zcmeI)JCY<(avjhHAyT49g$5DppiYfzm{mZaj1^%4*b+6G4W_19=<4eH#OHneo-qu& zGBe_Z`$_kkW;7W7=l}ZGAOHQw$AA9yZ~y(5zy0_B{Fk5q{f8g_^y42tKKR?`|Lwp2 z`1^nV{_^kt&tHH1`1wB{um1WEzdrc!zyIxj{J+nafBDN_{`2pD|G)qIw>y6Q=j%Pc z-t`v&0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+z-j`2^&bKR2>gG6)$&O_1PBly&|big9svRb zz6-QZ8YdDUK!CtX0^f7rYXSratdvn|AwYltfwlsE

ZU@Jyg>+Bl5>0RjY85qOsS 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 diff --git a/SDL2-2.0.12/test/shapes/p06_shape24.bmp b/SDL2-2.0.12/test/shapes/p06_shape24.bmp deleted file mode 100644 index 4cc257688f17aad0131b6cc65979184feaddcdef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1228938 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 K1PBn=C-8rtukKL* diff --git a/SDL2-2.0.12/test/shapes/p06_shape32alpha.bmp b/SDL2-2.0.12/test/shapes/p06_shape32alpha.bmp deleted file mode 100644 index 04afd793cdda60d227071d8022e15d1fa5c590ca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1638538 zcmeI(J(6TSRtDe(Oe{d{qZ-y{_x}9|LdRr_xbCe{`9B+|M|cF=U@Kv#;^Z;edkxJp9l~j zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1R{Yy{D;5|fhbqn2@oJafB=E>0yjR%UL~-d!1*2I4FUuR5Fjv4V7m{of(R@m zFmC4?nE(L-1a=Wv=(A_41PELd*yX%Z2LS>E2%HzV`04N(0RkHeoIgRlL4W`O0<#Nj z__@@! z5Fju{AnO^dZUO`dj20Mk>Kl~+fvf_f&phK3AV7e?cY&@G0t*=Ak@2oNA}Oknr#l==t|s4H;nWbqUM0t5)mE>QRDpf>^pb`+TX z95X)x1PBngCa~i-OHBj_+!MHVns|!<0RjY86S()a@HPPgy9lgyc9|~$0t5)$6WHbZ zr49lF&I{Z-J-khT009E43!MLQc!L0el?7Hmv&^3W0RjZ-2(0`qGj{?6jtSH`E%ZWw z009EK2^{;1c!~gl)dY4stJFh)009DZ1y=j6nJ)nXu|VC^L2m>I5FoI-K>S7V7Xk!k z7ufxLQXc^V1PHVhnEg9vegp`77ifDT=$!xo0tB)MeE+)mjR1ie1+tt+>Lfsb0D-;& zGk){Ti2#8gKl+{oMk7Fg0D)`*zO@7h%p;KP{829f0t5(*6`1D>XeI>m35?zSMkhdk z0D6>^6;>sI{sP~3 zn%@WzAV7e?Tmt>Sj7B7|x4>LG+-wLCAV7dXSzzz4vFZr)6)5jAtpo@VAV6R)fxcfy zqY>CwV6L5QHUtO|AVA=~z`kE(l@aJ8@P3E+D**xo2oRW4pwCy*C5?EhgjU8;31PBlyK;W9d`d?}l5U4M3Z8v#~009C72&^Gc z|I4XI0&5Gbv2)Fm009C72;37``)h6X1nLRg+ezLgK!5-N0&5A>`-19;z?uSU?O3xV zK!5-N0(At|{A!yuf%^h=c932O5FkK+z?uU0zodE~u$I7@JJqZS5FkK+KwW{gzTRd_ z;JQHFoufAb1PBlyu(rVUFRC{QtRb-W4mEoM1PBly&_-a5ueezfxF*nM*XWf10RjXF ztSxZutLiNR^9!uKGtHg=0RjXFv=x~DOKye)&Iz>LF?uIJfB*pkdkCESx_X+xyaIdd zNL3IZK!5;&J_7T8(ans&F@Zii#V7;_5FkKcFM(rUSx*s|PhhW|s2TzU2oNC9S75#` zyBQJqEYNqC7>xh{0t5)`CGh!6>j?sL3GB54RYQOP0RjZZ2+Z|$HyZ-)1;*?WqY@xM zfB=EL1m1sb{guF60(h+(1PJUY5Pxy~g}^)l zd+t6}5g0RjXF5ZGIw{MFS;U=D%3cc1DA5FkK+z!-r! zzVc>4;CF#BJHn_02oNAZAcw&3UtTQ)#tY=weX1ltfB*pkV+6*3>CJ$^cY!fG!KefX z5FkJxm%#V0uipra709*wR7-#W0RjZZ2#o#O8=b%}fiXM4s00WQAV46ez^^Z`p9qW- z$hrGeO@IIa0tChgjQipnnZQqhG08V70RjXF5Xddy9ztNGK+`CEj1PBlyKwu4l9(Mv`Qau3z1PBmVOQ7|=K>s-e)=ItE5+Fc;0D;^BIc_JaY%P#`7pa~A0RjXFtR>L; zUZDT|1=dQu*%BZ?fB*pk4}tw}C@O3zU>6Y}K!5-N0_zF1yc_6ye}VN9Z^i@&5FkK+ z!2UNB6}A+xg9s2HK!5;&^#oep4fMUYz8kjAV7csfmeZjZz?KlA@G_XzY`!pfB*pk>j|{DBj|Hqf%Ot@#smluAV7e?tH8cD z6_vFRc+HRB2@oJafB=E@1X|n?^trFVdI>jU0t5&UAVA<%VBedH%4!R|X2t<97lC2oNAZU|oUQ_XPdzDX?zB z&71%M0t5&Ucoo?5wxX(<0SU=$^AV7cs0RjYG1@^nK zsHmpEYhL_LfB*pk1PH7zQ1h;!ul)qpPq+#Q5FkK+0D)J5{cbEOswME66~7Z8K!5-N z0{aNmx-aNwFM)j$t`Y(S2oNAZ;8kF+TZ?LH3B2aS?*s@CAV7e?J_5Dw3;NkhV4sAm zga82o1PBm#71-<6qMBL)uQ~BM0RjXF5FoIRK&|_Ne)baBC*dj~K!5-N0t8+K_PVvG zrk22KPW(=Q009C72<#(J>%O3$eFXMNw@L^QAV7csfk z7Krkpoj^8$xp%7B-4)1|XY~?@1n%x7@9!ZHnsjBEDuuJaMK_C+7wU>-D zw?LE+?F3d8n0v>W-D(1>?gR5C5DBcd2hF#QK$H*d1XdGhvqSVs;HSW9`@wt(L<06S zfrmhp5A6h25U`60j1X91ZRzxCE{U%(QpRg+L^5 zCEMQFM9~qxOB#?Pus@?zgBia|*#|hY%1a=e{x1)?qpe(TC zK2y_ifpRLe66h;%Jh7f6u)aXw-DNZaWr6i~k_zq!lvAOVKp%lS+4U}g)dl+OGNTYE z3#`6>%>SN1ITcz7v=g|OSZ@>9Q=r|B(=&mxz@9rvRYwKNsnANGzQEB;dX7M5f%-d7 zj|9pBnfIC6{qH}@yFzPi0eg)Af#U+T_n-aK9|TGQ^Q7ENdJ2@Xpp8Hcfu1=w7J=ObYV1jU5GV=kzIW7D7AR#w8-cq5 z<+N!fK;VwR-F@kO0wsYvne^_u0;McyBXCDx-Q8g31m+jGvp2mJV>dml)Kq(8_ z2wW9tkx_jTAn;w_>i+Z|fs(-YbonidKq(8_2wWA&vTxK$V5Gp+{pmddC4rGyHugAy zQWmrkxFRqv#YQHOPvFWP^$vlOK)&6h;)g&f3)%>r6|kEK5a=&(cAt8lKuMr~a*a5H zKq(8_2%Hg^A;;!GAgjQcz3N#4C4sDaCv)AU9B3nORv_~pQagds0%!ND=LwVqM(5c0 zeFaJx&_>{lK;Og~jR1j?z?nVkSpp@2Qm(Y^D^SXSHUdWl_T3pOBe0&p(S7SV0wsa< z5^u(L1WFmuM&O9Ro!ohs0D(3FNA|8~2$TfcBvP-l3Y0RSjldCsSu<^31TqU8*}I-0 zP!h+d#fmQNto^=FD8PG=Hoj{%B>4gA+mICkg zu)h%~3AD_kzULDtWk4H&NMODMn-Kv5kwCPMwG$`_L^;yFr$8wK+6a^c_S^xgBCxkW zX)kLdP!iaCC#ddKpp*e^1WE$0+3`C80`m)$_OdntC4u?VY=$)jN*T~b;8mbz=JZ8? zKwp8^{p@!FC4s)FG}>r^QUIZp+@d0P+EI! z1YQMtX3|&$2(%G+-Pe96P!ed9KE2K+P+EI!1YQMZ%dPnkAaGvbbzl3PKuO?yvb?dP zKxyr@5qK3?G27-$fWUWw*M04G0wsa(sqx#c0;RRrM&MOo*ZixCKqi6LeeHJwC4o$P zB6F>!wbw@At3c-cp>_hh34Gn#ekM>7*e&zwDGQX=UK@e00_EgrB|ueAY4Bk&Z+w^9kfW z!n&w)8`Q!2AMv zPdb%H0`sTV3~LBP>#sepK#g4Kg8+dw1oEDADvt!#NUmAl6^PbfdtQONnesjX0_zCm zJ?T^)39OS|Grc1at-toX0(bJ{T>=Ew63BbfsXP)`E5T-aRUle_?Rf>RX32X52&^ZN z_oP#KB(PqJ&G?EywEo)j3S7yNcL)$zQy}k2r}9W(%_N)kS%GN%wdWN$n<38=Ah51L z-jhz{k-)lXHuEzA(fVu8D{v-1o+UtFZGpTeoysGDwG(ajM+Ktw*Pd74Xm&hDfWZ0! zc~3f(M*{1oS_MZ0qV?CFSKvr)JVSuM9s+q!I+aHPdn8*Gp9G@y*Pd74Q)c{~0D*l3 z@}6`mj|BEfw@Tg#MC-3Tr@*_c_!|KNdkW+{?Nl8J?3r>^y$VF@uRW*0Yd-u=fWZC& zIZr!PM*{mNUWE^VX#KV46tF7@5XdKx^R!cSB#>_hPN z$&P2&6^PbfdrpCMlWgV$2wWA&dD^Ku61bWp@2w>et-to10&At$YzYvkA&~R5Q*|Uz zBUAdAUm#k4?KuVJPpladAW&N%=V_ z%dF{p9)W26wdWL=Cz)nKfIu&SoTr_tBY|GIGtO9nX#KV46d0REqZ1%7LLld9r|L*x zLP- zludJKClIZ__M8IklBQ<@1ZEY;dD^Ku5|}lo=2cf9T7T_11?r|tZv+UeAdvI4Q*|V; zLT1hJzCg78+H(rrPm~@A5Lith=V_zY9d`uRW*0?+MXDfWYnoIZr!PM*_R&U41_VqV?CFQ^39;Kp>w$&eKlSkwCs3 zkh9`w{k7*5$hiwtO(3^G&eKlSkwEU zwEo(23api0vn4>FhCt5KPSue>jZEodet~HHwdWL=Ke1*=fIw}5oTr_tBZ1oa(%+l{ z(fVu8DKKYB&58hlmI66XJ5@&lEwiTYc?6>M*Pc^go@AN{0Rp`Qa-Mdojs$w;&NyQQ zqV?CFQ($ZwjZT2T2!WiZovI^&5g9aQe}QQIwdWM*pFkrLATU}W=V_`vTGWYtJcgKT&!hKwve2oTr_tBZ1ZOYrfY6 zqV?CFQ{Y;PyhVV($^to0J5@&lD`(lPX<33;*sd5Us!VoC15NU3CNqlmv2~cB+m9N*U3%pFp(!+H(r* zmv9vkAn-{b=V_<0&6WUx8Ui^_J5@&lH8Q1-`30i&*Pc^g z{=}Lg0RpuJa-Mdojs$AwOMi0;MC-3Tr@)*kH7f!HS_K{RN`+*Pc_L ze*%q2fWT;hoTr_tBZ1L*G=3j}X#KV46zG#WqYxl4lR(bXPSugXOxZM-b^_7*YtJdr zE@^ruKwwsZoTr_tBY|0SYF>2(qV?CFQ=o3T^hSWd3IaJ#J5@&lD`eIj?+ZlhuRW*0 z{Y2@30D;v6a-Mdojs#ZAulZgRh}K_wPJwGF@)iLCD+}a2?Nl8Jtej?n})v{Q8?uw%y6^t(W`{@Qa2 z{GJdk1PJUdkn^-tbtJHR-qrV0AX!?Nl8J)X0=R<`;<8Uwcl0`4ek~1PIg?$a&hSIufXzFa6Ca5Us!VoC0&E)T{^) zXep5Mv{Q8?&@yZKo<|^Bf9*L1=1HcR5FpS?Am?eP>PVnh?u;{5AXnnI zGYRB9=~NyG%#=@aX(te^zxKQW?b4=a0t99g$a~VMJQA2Kqvq2_AX5slGt8{@U{j)K8fn2@sf7An!@1@!nwvh+fL zzzPC+Pdb%H0xRU!9PbN6>#sep!2ML|fdGM31oEDADvtzK$*y_c6NuJddtQNiiSjl9 z0xJpRJ?T^)39OV~bGRCCOU^ z2&^cO_oP#KB(P$R&H21QwEo)j3Y<@oHwX||RUq$4r}9W()hwI$Ie}>XwdWN$mmp6Q zAh5DP-jhz{k-*A%HuvKK(fVu8EpR+Ro+LnERe{{6oa!TiRr74#=LDkl*PdJ8T#7tR zfWV3ZxlcLOM*=Hm*__V{MC-3Tx4`)%d4m9f)dX^%a;lF6R?D&ZUK5DcUwdwWYiaTp z0Rk%t$?F7ao(x?Oo^bl~u5r_nO zbSfp;13Hv(&?+w2JtC(2)q+0Wk%b6 z0`D^5Zv^&Byov}AaIz72Ct!!<5O|jXed5-{r z`2?J31U?DOms&GwA@C^&{!XAp?(|83z!(818i7v&W0Gmq-U6R;;O_)_XVQ2C2(%M$ zq7nEc&@O#?o=MN3!4<0&#-;g#dw71e|09jtH!hXY;%#a3l+!A@C5mmo#q^ATUzEDMsL^z{s2$ zyRX2}On5H0K;KjvjR1j~0=Z8w)gKk8nK^yUFK{#$p35yTf0E6R0D(v#_vxkjqXJQW zwC^c!G#8%BEwE?$RYf3&K;_dn1&-#zbGZecdGRj+0_zFnKD|_bRA9Yi zoADiiqq*=Lfjc?#E&&2#1e{z1jtY!Ps8L4=9L1g;3Q%A5x6Qaf4a@Eroh#lc#ptCpk@~JMS#FP0jCmyI|BF8=k3)5?qtQg z1ResbW!`)V>?q(gB5+q=$9l|))a8k5U44z<}NVny8<;cq%Q&wfxDUXJ^=!;fK!G*ZGkv#{<5<`?HuWkz(Zi? zJ)<@PqXe8T1X>7;%Cm9D3be?QJ_$So#wOe71ojeest{-;u-8se%~63?dD1U|qZ#xZ z0Ro=|oG1iZ34BhUCw3HQl_&iYcnIvcXVgTXw}8`xKudw%c{bi00xdJ8Zvqd2Ig)M` z1lAOAiV$cmu;$J%>$?K2bESU*4}rTm^*(`&0!|MCJp?lDEj9o6(IZ>NAYiW%AaGv5 z$w8op!1-i)V;6xQ`7#E9UG|GQ2=oweVi4#d&?C#nm{*`j#*9JWAu#VQFf#)42skYW z^b(jS^=2|cpjXa}L*OYeBIm{=FuTBWfB2U`FM-+jg!#1<=#?|$5GV<>O}E|&%q>vb z6WR#$5}12;m|bguUO6)kfp-F}bFO~^GYP!g3;sr+m%vPW!d&_b^vaoW2pkpYzYB~= zpuND+{Ckc-FM;-{H^R&Uy>ez80%rwg-Z$n(;Hbda+O_S~KVy>ez80(S)V z+Pm7r2{m?-S@H(0_LraYlh&c{2`y zngTQKC3DIrP&3o|BG5}9-%eF=NuXEWj6Kq=GO2(%Vxk!5`n=q1p4f9QV=fnIqt z4uRGJYwS3)TvecTe)UhFm%yrf(7fvk^vauY2=o%DyF>JrU7%NPjYFW9K=wVY{+|N9 z@@5Fv3a#W7BAK0t5&UAV8ppz)E)$b8RosBXh$RH6h>H0U~D3dPJjRb0t5)O6j<$EV!nL@T4qk) z1PBlyK!Ctlfj+khqpT({HkC#vK!5-N0t8wLtadLk-#!8@GpBC?1PBlyKwzvupWB2{ zRudSTN~04XK!5-N0xbnryO)@6AAy#c(>DPE1PBlyFjkQK+D|en*ad<1PBlqBhc?AVWbrW#-!4y1PBlyK!89?ffes0=G;%9W%l$< zfB*pk1PF`~=y#Ja(ux9OQfX8I1PBlyK%k|-igyxo?kmtTfBGgsfB*pk1o{f}y+s&p zRe`>#G#UW{1PBly&{AO4`-pk>6=<13eG?!+fB*pkeFgg7B8;}GK;KjvjQ{}x1PBml zDX{8&#Ju|pw9KKt2@oJafB=C$0{w3gMqF8-Pb!TMb+ z2oNAZfIuIC{x=9Ct}M_el|~^zfB*pk1X>ELd>1kI{sJwtsBZ!U2oNAZppQWR8-x*8 z7wD5rqYxlKfB*pkEd*A-hnW8uffiZRCjkNk2oNC9M_|nD!KkYX^hu{t2oNAZfB=CO z0;}Ic%zunPi!ADs009C72oUHaFy{7P)Exx+B-AJb2oNAZfIv-w9qu4%7$;COi~1r! zfB*pk1o{Y!yEzzn2Z25*H3|U&1PBlyP*Y%sJBS*_3DnG@z6cN?K!5;&J_6%z4o2QZ zpifebLVy4P0t5)u5ZLAZp^mWvHL|D=0t5&UAV8pxz}Q=Z(RUH(lUAb;AV7cs0RlAy zcDaA3W2``pEb4;*0RjXF5a=T?_SRtZT?G21)hGlA5FkK+Kn;Oi?jPzHFHj?o`XE4n z009C7+6s)nF_^(l0&UZ(cLD?m5FkLHhQLmD54DUJsF6v15FkK+009DR1;*bP%wQ*h zwrSNn0RjXF5Fk)PV5hr>TILX_kxP9LAV7cs0Rn9V=D01G#cl#^(yCVi1PBlyK%j=e zZubuL%p*`EpZXv`fB*pk1nLURb5k&r9R=#9Rc{0c5FkK+Kn;N%?;L8HOQ1$h^+A9D z0RjXF)Df8LmS8r!3e-ufUI-8%K!5;&8UnlCH`FzsK#jcWg8%^n1PBngCota)!Hjkm zxR+LM6Cgl<009Cu1a`h_sBKPx8oAX60RjXF5Fl_(V9witS?w-xEv?=nK!5-N0t9LZ z?0(Ns-@F1f@~aO51PBlyK;WFfyf*_g%OG$rt)3=8fB*pk1ZoImxMQesUV$1J)&~Is z1PBlya86*}n}L~S5jdAvPZJYMo!;N`}2dfB*pk1PGiHnEys#hS>zpCD_vh2oNAZfWR4n zZ1)QFt|4$H!=5ETfB*pk1kMSpaT_qpi~{G9>}di72oNAZ;D|uRJB6Cp5jc`z&k!I$ zfB*pk=LFWd37BbCfpdxWGywtx2oNCfP9W=jLfvZ#yvwk^5gZ`Robj-}gE1PBlyK!89=Ap1Q+{p$*p@~n*j0RjXF z5O^=J?w8-p3H%gzpKyOAK!5-N0tCJaxIYlsMc`|${Y-!W0RjXFlm&MA?yG~qQ=pu5 ztpo@VAV7e?L*V(n^e=(k1nh7E1PBlyK;U009C72oU%su;aI0O$15;zf$if0t5&UAdpv}^o`U;U}u56yIti32oNAZ!2jN3 z=R1zt-V50O1PBlyKp>;Q`>&(F64+lL{3Jo+6M(Ak+R=D**xo2;>vU^F>!Ff#U-CP68DZAV7dXCV}H$L{AdPC6MVHP%8lf z1PJ62$n`Z>ErIg_c}@eB5+Fc;Kn8*HUqWvX$SIKFJWwM60t5)`FOc&qu4)3;1@=D` zR7ijT0RlSk=klR$2PozDfe5gxzuu}Ra9?2G(?Mkf2oNB!qrm+ypB@Mh zcnIuxKB$QR0RjZ}6Y$k0K%kz$ekX*A2oNAZU`K&^Up_q%An*{_@tjZ-0RjXF>?7c7 zO@KfffqhO1l@K66fWS@yZN7SXB|zY-z)oj|S_lvzKww>guiqv=6CluDVBOQg%n1-6 zKwt-f_Fp<95Fii<>~MytfdByl1lAFVzDL>#5a=(k&dFh>1PBlyu%bZ!FPjkw5I7>R z;(21u1PBlyFu%Z&Z;)pQ5Ev^k|4Cwo1PBlyu!6wYubI&a5I8Ha!ntCO1PBlyFt5Pb z?~dmQ5ST|`-jl`52oNAZU`By?zF=lTfWTdW8P6DVB0zuufq4Y(erLQ-fWVvr^PDnf zLVy4P0y7EB`PDKj0t9Lb%yj0M3jqQI2#gb``EAh`0Rr<2j5}?NOn?9Z0y7BA|D`fR z0t8wK%y0&o0|5dA2=o(Z^*zxq0Rn3Y^gDHoM1TMR0wV?1`Z}2{0RlY)MxIH=CP07y zfp!8tz9GgSKwxcwb|;XY2@oJapr^pvUn8?8K%lok&-2Mx1PBlyP+y?;cf)uD2<#!TV11ZELvabD?@009C7t_#faeJ~FK1ab&mKdrn;fB*pkcLZ{L zWmHLk!0ZBd&N1&2AV7e?XMx$j1LjA7KyHE0r~U(eu%B1PBnwAdvG*plSjHG6-Zi!_`QD0D)Qp8NLf@BtT#>z_ruHTLcIYATYDQOy3!EAwXcPz|3crxe*{hfIwS;v0osg6Clt-pzSH5cLD?m z5Xd0V<9lTc0tCte8O|6r5+Fc;z&--yubEZ?IR*CF*(xDGfB*pk;{|fwCRANZV0?nj zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ P009C72oNAJx4{1aXoNQV diff --git a/SDL2-2.0.12/test/shapes/p06_shape8.bmp b/SDL2-2.0.12/test/shapes/p06_shape8.bmp deleted file mode 100644 index 017c1ed776f8251cb53531f72886485ca40b91f8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 410678 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 K1V|uy0{;hh#my@K diff --git a/SDL2-2.0.12/test/shapes/p07_shape24.bmp b/SDL2-2.0.12/test/shapes/p07_shape24.bmp deleted file mode 100644 index fa8012cae8c048e538f84f559f5da1e5bb05ca9c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1228938 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 zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly 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 DW$&PM diff --git a/SDL2-2.0.12/test/shapes/p08_shape32alpha.bmp b/SDL2-2.0.12/test/shapes/p08_shape32alpha.bmp deleted file mode 100644 index 4d1d25e9ff436183f32abf468cc48667ee16887c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1638538 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 diff --git a/SDL2-2.0.12/test/shapes/p08_shape8.bmp b/SDL2-2.0.12/test/shapes/p08_shape8.bmp deleted file mode 100644 index 920f9070ee08a5355fe5872e097f8b6d03107ecf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 410678 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 J0wB;N@P87svs?fG diff --git a/SDL2-2.0.12/test/shapes/p09_shape24.bmp b/SDL2-2.0.12/test/shapes/p09_shape24.bmp deleted file mode 100644 index e5a7c0043d98f084f9d91d099bb33bddd47a01fd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1228938 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 diff --git a/SDL2-2.0.12/test/shapes/p09_shape32alpha.bmp b/SDL2-2.0.12/test/shapes/p09_shape32alpha.bmp deleted file mode 100644 index 250d267d1491cad72a1c13c8eb0d43e07ce2adb3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1638538 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 U0RjXF5FkK+009C72t*P1f6jE^6aWAK diff --git a/SDL2-2.0.12/test/shapes/p09_shape8.bmp b/SDL2-2.0.12/test/shapes/p09_shape8.bmp deleted file mode 100644 index 4d1cd014ec313dcbbef5ce5655084c4456b8ab69..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 410678 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 diff --git a/SDL2-2.0.12/test/shapes/p10_shape1.bmp b/SDL2-2.0.12/test/shapes/p10_shape1.bmp deleted file mode 100644 index 42b5a7f347490c85a373aaaf4dd23275b6eccd9a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51346 zcmeI$u}#B306V-0>nc9D~jm;Dd*Vv=Zo{o z+}v(nhV9tQ$NPD%&vtVh#$A~E<;8B!Y51JOFzsL4i?5a2a`$-kwmq2-tJUiJ{Q32I zzUgQDzGwgGG#xD2f82Wl2_%p}0tqCLKmrLQkU#@BF0A z=9`!Mtq=D<_G(=2_i)++zAyJX_JNk`m;3d6OCi3_kA1A>XF}ZbV;`&enGpB<*vD#q zCd55I_OY6u331PleXQnZLfrFXAFKJ95cmAp$7+5i#63Uuv6`O=anFx^tmbDz-1B1} ztNED__x#w$YJMifJwNubnx6@A&yRhq=4V3O^J5>Y`I!*+{Mg58ekQ~{KlZVjp9yi# zkA1A>XF}ZbV;`&enGpB<*vD#qCd55I_OY6u331PleXQnZLfrFXAFKJ95cmAp$7+5i z#63Uuv6`O=anFx^tmbDz-1B1}tNED__x#w$YJMifJwNubnx6@A&yRhq=4V3O^J5>Y z`I!*+{Mg58ekQ~{KlZVjp9yi#kA1A>XF}ZbV;`&enGpB<*vD#qCd55I_OY6u331Pl zeXQnZLfrFXAFKJ95cmAp$7+5i#63Uuv6`O=anFx^tmbDz-1B1}tNED__x#w$YJMif zJwNubnx6@A&yRhq=4V3O^J5>Y`I!*+{Mg58ekQ~{KlZVjp9yi#kA1A>XF}ZbV;`&e znGpB<*vD#qCd55I_OY6u331PleXQnZLfrFXAFKJ95cmAp$7+5i#63Uuv6`O=anFx^ ztmbDz-1B1}tNED__x#w$YJMifJwNubnx6@A&yRhq=4V3O^J5>Y`I!*+{Mg58ekR0y u>9^+PR>$Rj(~0As_p{$qPauH=5=bC{1QJLffdmprAb|uDNFaef1U>+I;GfL^ diff --git a/SDL2-2.0.12/test/shapes/p10_shape24.bmp b/SDL2-2.0.12/test/shapes/p10_shape24.bmp deleted file mode 100644 index bc1faf4e7b4605ee27a376685706859529eda898..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1228938 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 E0oy;U=l}o! diff --git a/SDL2-2.0.12/test/shapes/p10_shape8.bmp b/SDL2-2.0.12/test/shapes/p10_shape8.bmp deleted file mode 100644 index 64fb5c372067554fc0d3d7f15fce0d17397a2591..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 410678 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 b1-8Hz*aBN%3v7Wcum!fj7T5y+&jtPmU}+S4 diff --git a/SDL2-2.0.12/test/shapes/p11_shape32alpha.bmp b/SDL2-2.0.12/test/shapes/p11_shape32alpha.bmp deleted file mode 100644 index 406d20a815ee196b67353bc40614484a8c6d76c1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1638538 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

Py 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�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 diff --git a/SDL2-2.0.12/test/shapes/p12_shape24.bmp b/SDL2-2.0.12/test/shapes/p12_shape24.bmp deleted file mode 100644 index 582cf994e2e21ad58919600c73b5546748e5300a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1228938 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 diff --git a/SDL2-2.0.12/test/shapes/p12_shape8.bmp b/SDL2-2.0.12/test/shapes/p12_shape8.bmp deleted file mode 100644 index 59377200bbd9ef2b390ac08cabebacbb7e55958b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 410678 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 diff --git a/SDL2-2.0.12/test/shapes/p13_shape24.bmp b/SDL2-2.0.12/test/shapes/p13_shape24.bmp deleted file mode 100644 index 70215db590c7c6c1bac1becf7333d51d5649ff3e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1228938 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 z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk v1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlykRtGZT`e)# diff --git a/SDL2-2.0.12/test/shapes/p13_shape8.bmp b/SDL2-2.0.12/test/shapes/p13_shape8.bmp deleted file mode 100644 index 822b896e1c7026fc5a62d33f604282bd9edbf337..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 410678 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

+MX> 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 OAV7cs0RjYK3j9CtHj-oj diff --git a/SDL2-2.0.12/test/shapes/p14_shape8.bmp b/SDL2-2.0.12/test/shapes/p14_shape8.bmp deleted file mode 100644 index d6f981f58add4872ed72ccc2181b10ec4eea6101..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 410678 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 z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk a1PBlyK!5-N0t5&UAV7cs0RjYW6Zk*>6Vn_3 diff --git a/SDL2-2.0.12/test/shapes/p15_shape32alpha.bmp b/SDL2-2.0.12/test/shapes/p15_shape32alpha.bmp deleted file mode 100644 index 6954a5d91c44dc333c5b4822f046d66858ffd919..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1638538 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 z=WY3??n$)oZT{Q)jm~ju+|6^!A==l?XM3K=d1`#S=WY3??n$)oZT{Q)jm~ju+|6^! zA==l?XM3K=d1`#S=WY3??n$)oZT{Q)jm~ju+|6^!A==l?XM3K=d1`#S=WY3??n$)o zZT{Q)jm~ju+|6^!A==l?XM3K=d1`#S=WY3??n$)oZT{Q)jm~ju+|6^!A==l?XM3K= zd1`#S=WY3??n$)oZT{Q)jm~ju+|6^!A==l?XM3K=d1`#S=WY3??n$)oZT{Q)jm~ju z+|6^!A==l?XM3K=d1`#S=WY3??n$)oZT{Q)jm~ju+|6^!A==l?XM3K=d1`#S=WY3? z?n$)oZT{Q)jm~ju+|6^!A==l?XM3K=d1`#S=WY3??n$)oZT{Q)jm~ju+|6^!A==l? zXM3K=d1`#S=WY3??n$)oZT{Q)jm~ju+|6^!A==l?XM3K=d1`#S=WY3??n$)oZT{Q) zjm~ju+|6^!A==l?XM3K=d1`#S=WY3??n$)oZT{Q)jm~ju+|6^!A==l?XM3K=d1`#S z=WY3??n$)oZT{Q)jm~ju+|6^!A==l?XM3K=d1`#S=WY3??n$)oZT{Q)jm~ju+|6^! zA==l?XM3K=d1`#S=WY3??n$)oZT{Q)jm~ju+|6^!A==l?XM3K=d1`#S=WY3??n$)o zZT{Q)jm~ju+|6^!A==l?XM3K=d1`#S=WY3??n$)oZT{Q)jm~ju+|6^!A==l?XM3K= zd1`#S=WY3??n$)oZT{Q)jm~ju+|6^!A==l?XM3K=d1`#S=WY3??n$)oZT{Q)jm~ju z+|6^!A==l?XM3K=d1`#S=WY3??n$)oZT{Q)jm~ju+|6^!A==l?XM3K=d1`#S=WY3? z?n$)oZT{Q)jm~ju+|6^!A==l?XM3K=d1`#S=WY3??n$)oZT{Q)jm~ju+|6^!A==l? zXM3K=d1`#S=WY3??n$)oZT{Q)jm~ju+|6^!A==l?XM3K=d1`#S=WY3??n$)oZT{Q) zjm~ju+|6^!A==l?XM3K=d1`#S=WY3??n$)oZT{Q)jm~ju+|6^!A==l?XM3K=d1`#S z=WY3??n$)oZT{Q)jm~ju+|6^!A==l?XM3K=d1`#S=WY3??n$)oZT{Q)jm~ju+|6^! zA==l?XM3K=d1`#S=WY3??n$)oZT{Q)jm~ju+|6^!A==l?XM3K=d1`#S=WY3??n$)o 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 I_*Q}c0cCyzH2?qr diff --git a/SDL2-2.0.12/test/shapes/p16_shape8.bmp b/SDL2-2.0.12/test/shapes/p16_shape8.bmp deleted file mode 100644 index 0b4d4221c5c47a45ff8418f747c4fe98218a7b4d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 410678 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 XOuz(8zywUd1WdpLOuz(ok-&ceOT{Tx diff --git a/SDL2-2.0.12/test/shapes/trollface_24.bmp b/SDL2-2.0.12/test/shapes/trollface_24.bmp deleted file mode 100644 index e18c2c2ad129e2dfa612d0c4382bbc26fc21edd8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 196662 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�o2DBOY1($ca-Y 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 diff --git a/SDL2-2.0.12/test/shapes/trollface_32alpha.bmp b/SDL2-2.0.12/test/shapes/trollface_32alpha.bmp deleted file mode 100644 index ee3ecf9be4c95a7e76f338bf2c985d1d97054364..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 262198 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 UQ0hRb1Emg>I#B9BXY0WK4>RWDjQ{`u diff --git a/SDL2-2.0.12/test/testatomic.c b/SDL2-2.0.12/test/testatomic.c deleted file mode 100644 index 0a4e62d..0000000 --- a/SDL2-2.0.12/test/testatomic.c +++ /dev/null @@ -1,727 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ -#include - -#include "SDL.h" - -/* - Absolutely basic tests just to see if we get the expected value - after calling each function. -*/ - -static -char * -tf(SDL_bool tf) -{ - static char *t = "TRUE"; - static char *f = "FALSE"; - - if (tf) - { - return t; - } - - return f; -} - -static -void RunBasicTest() -{ - int value; - SDL_SpinLock lock = 0; - - SDL_atomic_t v; - SDL_bool tfret = SDL_FALSE; - - SDL_Log("\nspin lock---------------------------------------\n\n"); - - SDL_AtomicLock(&lock); - SDL_Log("AtomicLock lock=%d\n", lock); - SDL_AtomicUnlock(&lock); - SDL_Log("AtomicUnlock lock=%d\n", lock); - - SDL_Log("\natomic -----------------------------------------\n\n"); - - SDL_AtomicSet(&v, 0); - tfret = SDL_AtomicSet(&v, 10) == 0 ? SDL_TRUE : SDL_FALSE; - SDL_Log("AtomicSet(10) tfret=%s val=%d\n", tf(tfret), SDL_AtomicGet(&v)); - tfret = SDL_AtomicAdd(&v, 10) == 10 ? SDL_TRUE : SDL_FALSE; - SDL_Log("AtomicAdd(10) tfret=%s val=%d\n", tf(tfret), SDL_AtomicGet(&v)); - - SDL_AtomicSet(&v, 0); - SDL_AtomicIncRef(&v); - tfret = (SDL_AtomicGet(&v) == 1) ? SDL_TRUE : SDL_FALSE; - SDL_Log("AtomicIncRef() tfret=%s val=%d\n", tf(tfret), SDL_AtomicGet(&v)); - SDL_AtomicIncRef(&v); - tfret = (SDL_AtomicGet(&v) == 2) ? SDL_TRUE : SDL_FALSE; - SDL_Log("AtomicIncRef() tfret=%s val=%d\n", tf(tfret), SDL_AtomicGet(&v)); - tfret = (SDL_AtomicDecRef(&v) == SDL_FALSE) ? SDL_TRUE : SDL_FALSE; - SDL_Log("AtomicDecRef() tfret=%s val=%d\n", tf(tfret), SDL_AtomicGet(&v)); - tfret = (SDL_AtomicDecRef(&v) == SDL_TRUE) ? SDL_TRUE : SDL_FALSE; - SDL_Log("AtomicDecRef() tfret=%s val=%d\n", tf(tfret), SDL_AtomicGet(&v)); - - SDL_AtomicSet(&v, 10); - tfret = (SDL_AtomicCAS(&v, 0, 20) == SDL_FALSE) ? SDL_TRUE : SDL_FALSE; - SDL_Log("AtomicCAS() tfret=%s val=%d\n", tf(tfret), SDL_AtomicGet(&v)); - value = SDL_AtomicGet(&v); - tfret = (SDL_AtomicCAS(&v, value, 20) == SDL_TRUE) ? SDL_TRUE : SDL_FALSE; - SDL_Log("AtomicCAS() tfret=%s val=%d\n", tf(tfret), SDL_AtomicGet(&v)); -} - -/**************************************************************************/ -/* Atomic operation test - * Adapted with permission from code by Michael Davidsaver at: - * http://bazaar.launchpad.net/~mdavidsaver/epics-base/atomic/revision/12105#src/libCom/test/epicsAtomicTest.c - * Original copyright 2010 Brookhaven Science Associates as operator of Brookhaven National Lab - * http://www.aps.anl.gov/epics/license/open.php - */ - -/* Tests semantics of atomic operations. Also a stress test - * to see if they are really atomic. - * - * Several threads adding to the same variable. - * at the end the value is compared with the expected - * and with a non-atomic counter. - */ - -/* Number of concurrent incrementers */ -#define NThreads 2 -#define CountInc 100 -#define VALBITS (sizeof(atomicValue)*8) - -#define atomicValue int -#define CountTo ((atomicValue)((unsigned int)(1<<(VALBITS-1))-1)) -#define NInter (CountTo/CountInc/NThreads) -#define Expect (CountTo-NInter*CountInc*NThreads) - -enum { - CountTo_GreaterThanZero = CountTo > 0, -}; -SDL_COMPILE_TIME_ASSERT(size, CountTo_GreaterThanZero); /* check for rollover */ - -static SDL_atomic_t good = { 42 }; - -static atomicValue bad = 42; - -static SDL_atomic_t threadsRunning; - -static SDL_sem *threadDone; - -static -int SDLCALL adder(void* junk) -{ - unsigned long N=NInter; - SDL_Log("Thread subtracting %d %lu times\n",CountInc,N); - while (N--) { - SDL_AtomicAdd(&good, -CountInc); - bad-=CountInc; - } - SDL_AtomicAdd(&threadsRunning, -1); - SDL_SemPost(threadDone); - return 0; -} - -static -void runAdder(void) -{ - Uint32 start, end; - int T=NThreads; - - start = SDL_GetTicks(); - - threadDone = SDL_CreateSemaphore(0); - - SDL_AtomicSet(&threadsRunning, NThreads); - - while (T--) - SDL_CreateThread(adder, "Adder", NULL); - - while (SDL_AtomicGet(&threadsRunning) > 0) - SDL_SemWait(threadDone); - - SDL_DestroySemaphore(threadDone); - - end = SDL_GetTicks(); - - SDL_Log("Finished in %f sec\n", (end - start) / 1000.f); -} - -static -void RunEpicTest() -{ - int b; - atomicValue v; - - SDL_Log("\nepic test---------------------------------------\n\n"); - - SDL_Log("Size asserted to be >= 32-bit\n"); - SDL_assert(sizeof(atomicValue)>=4); - - SDL_Log("Check static initializer\n"); - v=SDL_AtomicGet(&good); - SDL_assert(v==42); - - SDL_assert(bad==42); - - SDL_Log("Test negative values\n"); - SDL_AtomicSet(&good, -5); - v=SDL_AtomicGet(&good); - SDL_assert(v==-5); - - SDL_Log("Verify maximum value\n"); - SDL_AtomicSet(&good, CountTo); - v=SDL_AtomicGet(&good); - SDL_assert(v==CountTo); - - SDL_Log("Test compare and exchange\n"); - - b=SDL_AtomicCAS(&good, 500, 43); - SDL_assert(!b); /* no swap since CountTo!=500 */ - v=SDL_AtomicGet(&good); - SDL_assert(v==CountTo); /* ensure no swap */ - - b=SDL_AtomicCAS(&good, CountTo, 44); - SDL_assert(!!b); /* will swap */ - v=SDL_AtomicGet(&good); - SDL_assert(v==44); - - SDL_Log("Test Add\n"); - - v=SDL_AtomicAdd(&good, 1); - SDL_assert(v==44); - v=SDL_AtomicGet(&good); - SDL_assert(v==45); - - v=SDL_AtomicAdd(&good, 10); - SDL_assert(v==45); - v=SDL_AtomicGet(&good); - SDL_assert(v==55); - - SDL_Log("Test Add (Negative values)\n"); - - v=SDL_AtomicAdd(&good, -20); - SDL_assert(v==55); - v=SDL_AtomicGet(&good); - SDL_assert(v==35); - - v=SDL_AtomicAdd(&good, -50); /* crossing zero down */ - SDL_assert(v==35); - v=SDL_AtomicGet(&good); - SDL_assert(v==-15); - - v=SDL_AtomicAdd(&good, 30); /* crossing zero up */ - SDL_assert(v==-15); - v=SDL_AtomicGet(&good); - SDL_assert(v==15); - - SDL_Log("Reset before count down test\n"); - SDL_AtomicSet(&good, CountTo); - v=SDL_AtomicGet(&good); - SDL_assert(v==CountTo); - - bad=CountTo; - SDL_assert(bad==CountTo); - - SDL_Log("Counting down from %d, Expect %d remaining\n",CountTo,Expect); - runAdder(); - - v=SDL_AtomicGet(&good); - SDL_Log("Atomic %d Non-Atomic %d\n",v,bad); - SDL_assert(v==Expect); - SDL_assert(bad!=Expect); -} - -/* End atomic operation test */ -/**************************************************************************/ - -/**************************************************************************/ -/* Lock-free FIFO test */ - -/* This is useful to test the impact of another thread locking the queue - entirely for heavy-weight manipulation. - */ -#define TEST_SPINLOCK_FIFO - -#define NUM_READERS 4 -#define NUM_WRITERS 4 -#define EVENTS_PER_WRITER 1000000 - -/* The number of entries must be a power of 2 */ -#define MAX_ENTRIES 256 -#define WRAP_MASK (MAX_ENTRIES-1) - -typedef struct -{ - SDL_atomic_t sequence; - SDL_Event event; -} SDL_EventQueueEntry; - -typedef struct -{ - SDL_EventQueueEntry entries[MAX_ENTRIES]; - - char cache_pad1[SDL_CACHELINE_SIZE-((sizeof(SDL_EventQueueEntry)*MAX_ENTRIES)%SDL_CACHELINE_SIZE)]; - - SDL_atomic_t enqueue_pos; - - char cache_pad2[SDL_CACHELINE_SIZE-sizeof(SDL_atomic_t)]; - - SDL_atomic_t dequeue_pos; - - char cache_pad3[SDL_CACHELINE_SIZE-sizeof(SDL_atomic_t)]; - -#ifdef TEST_SPINLOCK_FIFO - SDL_SpinLock lock; - SDL_atomic_t rwcount; - SDL_atomic_t watcher; - - char cache_pad4[SDL_CACHELINE_SIZE-sizeof(SDL_SpinLock)-2*sizeof(SDL_atomic_t)]; -#endif - - SDL_atomic_t active; - - /* Only needed for the mutex test */ - SDL_mutex *mutex; - -} SDL_EventQueue; - -static void InitEventQueue(SDL_EventQueue *queue) -{ - int i; - - for (i = 0; i < MAX_ENTRIES; ++i) { - SDL_AtomicSet(&queue->entries[i].sequence, i); - } - SDL_AtomicSet(&queue->enqueue_pos, 0); - SDL_AtomicSet(&queue->dequeue_pos, 0); -#ifdef TEST_SPINLOCK_FIFO - queue->lock = 0; - SDL_AtomicSet(&queue->rwcount, 0); - SDL_AtomicSet(&queue->watcher, 0); -#endif - SDL_AtomicSet(&queue->active, 1); -} - -static SDL_bool EnqueueEvent_LockFree(SDL_EventQueue *queue, const SDL_Event *event) -{ - SDL_EventQueueEntry *entry; - unsigned queue_pos; - unsigned entry_seq; - int delta; - SDL_bool status; - -#ifdef TEST_SPINLOCK_FIFO - /* This is a gate so an external thread can lock the queue */ - SDL_AtomicLock(&queue->lock); - SDL_assert(SDL_AtomicGet(&queue->watcher) == 0); - SDL_AtomicIncRef(&queue->rwcount); - SDL_AtomicUnlock(&queue->lock); -#endif - - queue_pos = (unsigned)SDL_AtomicGet(&queue->enqueue_pos); - for ( ; ; ) { - entry = &queue->entries[queue_pos & WRAP_MASK]; - entry_seq = (unsigned)SDL_AtomicGet(&entry->sequence); - - delta = (int)(entry_seq - queue_pos); - if (delta == 0) { - /* The entry and the queue position match, try to increment the queue position */ - if (SDL_AtomicCAS(&queue->enqueue_pos, (int)queue_pos, (int)(queue_pos+1))) { - /* We own the object, fill it! */ - entry->event = *event; - SDL_AtomicSet(&entry->sequence, (int)(queue_pos + 1)); - status = SDL_TRUE; - break; - } - } else if (delta < 0) { - /* We ran into an old queue entry, which means it still needs to be dequeued */ - status = SDL_FALSE; - break; - } else { - /* We ran into a new queue entry, get the new queue position */ - queue_pos = (unsigned)SDL_AtomicGet(&queue->enqueue_pos); - } - } - -#ifdef TEST_SPINLOCK_FIFO - SDL_AtomicDecRef(&queue->rwcount); -#endif - return status; -} - -static SDL_bool DequeueEvent_LockFree(SDL_EventQueue *queue, SDL_Event *event) -{ - SDL_EventQueueEntry *entry; - unsigned queue_pos; - unsigned entry_seq; - int delta; - SDL_bool status; - -#ifdef TEST_SPINLOCK_FIFO - /* This is a gate so an external thread can lock the queue */ - SDL_AtomicLock(&queue->lock); - SDL_assert(SDL_AtomicGet(&queue->watcher) == 0); - SDL_AtomicIncRef(&queue->rwcount); - SDL_AtomicUnlock(&queue->lock); -#endif - - queue_pos = (unsigned)SDL_AtomicGet(&queue->dequeue_pos); - for ( ; ; ) { - entry = &queue->entries[queue_pos & WRAP_MASK]; - entry_seq = (unsigned)SDL_AtomicGet(&entry->sequence); - - delta = (int)(entry_seq - (queue_pos + 1)); - if (delta == 0) { - /* The entry and the queue position match, try to increment the queue position */ - if (SDL_AtomicCAS(&queue->dequeue_pos, (int)queue_pos, (int)(queue_pos+1))) { - /* We own the object, fill it! */ - *event = entry->event; - SDL_AtomicSet(&entry->sequence, (int)(queue_pos+MAX_ENTRIES)); - status = SDL_TRUE; - break; - } - } else if (delta < 0) { - /* We ran into an old queue entry, which means we've hit empty */ - status = SDL_FALSE; - break; - } else { - /* We ran into a new queue entry, get the new queue position */ - queue_pos = (unsigned)SDL_AtomicGet(&queue->dequeue_pos); - } - } - -#ifdef TEST_SPINLOCK_FIFO - SDL_AtomicDecRef(&queue->rwcount); -#endif - return status; -} - -static SDL_bool EnqueueEvent_Mutex(SDL_EventQueue *queue, const SDL_Event *event) -{ - SDL_EventQueueEntry *entry; - unsigned queue_pos; - unsigned entry_seq; - int delta; - SDL_bool status = SDL_FALSE; - - SDL_LockMutex(queue->mutex); - - queue_pos = (unsigned)queue->enqueue_pos.value; - entry = &queue->entries[queue_pos & WRAP_MASK]; - entry_seq = (unsigned)entry->sequence.value; - - delta = (int)(entry_seq - queue_pos); - if (delta == 0) { - ++queue->enqueue_pos.value; - - /* We own the object, fill it! */ - entry->event = *event; - entry->sequence.value = (int)(queue_pos + 1); - status = SDL_TRUE; - } else if (delta < 0) { - /* We ran into an old queue entry, which means it still needs to be dequeued */ - } else { - SDL_Log("ERROR: mutex failed!\n"); - } - - SDL_UnlockMutex(queue->mutex); - - return status; -} - -static SDL_bool DequeueEvent_Mutex(SDL_EventQueue *queue, SDL_Event *event) -{ - SDL_EventQueueEntry *entry; - unsigned queue_pos; - unsigned entry_seq; - int delta; - SDL_bool status = SDL_FALSE; - - SDL_LockMutex(queue->mutex); - - queue_pos = (unsigned)queue->dequeue_pos.value; - entry = &queue->entries[queue_pos & WRAP_MASK]; - entry_seq = (unsigned)entry->sequence.value; - - delta = (int)(entry_seq - (queue_pos + 1)); - if (delta == 0) { - ++queue->dequeue_pos.value; - - /* We own the object, fill it! */ - *event = entry->event; - entry->sequence.value = (int)(queue_pos + MAX_ENTRIES); - status = SDL_TRUE; - } else if (delta < 0) { - /* We ran into an old queue entry, which means we've hit empty */ - } else { - SDL_Log("ERROR: mutex failed!\n"); - } - - SDL_UnlockMutex(queue->mutex); - - return status; -} - -static SDL_sem *writersDone; -static SDL_sem *readersDone; -static SDL_atomic_t writersRunning; -static SDL_atomic_t readersRunning; - -typedef struct -{ - SDL_EventQueue *queue; - int index; - char padding1[SDL_CACHELINE_SIZE-(sizeof(SDL_EventQueue*)+sizeof(int))%SDL_CACHELINE_SIZE]; - int waits; - SDL_bool lock_free; - char padding2[SDL_CACHELINE_SIZE-sizeof(int)-sizeof(SDL_bool)]; -} WriterData; - -typedef struct -{ - SDL_EventQueue *queue; - int counters[NUM_WRITERS]; - int waits; - SDL_bool lock_free; - char padding[SDL_CACHELINE_SIZE-(sizeof(SDL_EventQueue*)+sizeof(int)*NUM_WRITERS+sizeof(int)+sizeof(SDL_bool))%SDL_CACHELINE_SIZE]; -} ReaderData; - -static int SDLCALL FIFO_Writer(void* _data) -{ - WriterData *data = (WriterData *)_data; - SDL_EventQueue *queue = data->queue; - int i; - SDL_Event event; - - event.type = SDL_USEREVENT; - event.user.windowID = 0; - event.user.code = 0; - event.user.data1 = data; - event.user.data2 = NULL; - - if (data->lock_free) { - for (i = 0; i < EVENTS_PER_WRITER; ++i) { - event.user.code = i; - while (!EnqueueEvent_LockFree(queue, &event)) { - ++data->waits; - SDL_Delay(0); - } - } - } else { - for (i = 0; i < EVENTS_PER_WRITER; ++i) { - event.user.code = i; - while (!EnqueueEvent_Mutex(queue, &event)) { - ++data->waits; - SDL_Delay(0); - } - } - } - SDL_AtomicAdd(&writersRunning, -1); - SDL_SemPost(writersDone); - return 0; -} - -static int SDLCALL FIFO_Reader(void* _data) -{ - ReaderData *data = (ReaderData *)_data; - SDL_EventQueue *queue = data->queue; - SDL_Event event; - - if (data->lock_free) { - for ( ; ; ) { - if (DequeueEvent_LockFree(queue, &event)) { - WriterData *writer = (WriterData*)event.user.data1; - ++data->counters[writer->index]; - } else if (SDL_AtomicGet(&queue->active)) { - ++data->waits; - SDL_Delay(0); - } else { - /* We drained the queue, we're done! */ - break; - } - } - } else { - for ( ; ; ) { - if (DequeueEvent_Mutex(queue, &event)) { - WriterData *writer = (WriterData*)event.user.data1; - ++data->counters[writer->index]; - } else if (SDL_AtomicGet(&queue->active)) { - ++data->waits; - SDL_Delay(0); - } else { - /* We drained the queue, we're done! */ - break; - } - } - } - SDL_AtomicAdd(&readersRunning, -1); - SDL_SemPost(readersDone); - return 0; -} - -#ifdef TEST_SPINLOCK_FIFO -/* This thread periodically locks the queue for no particular reason */ -static int SDLCALL FIFO_Watcher(void* _data) -{ - SDL_EventQueue *queue = (SDL_EventQueue *)_data; - - while (SDL_AtomicGet(&queue->active)) { - SDL_AtomicLock(&queue->lock); - SDL_AtomicIncRef(&queue->watcher); - while (SDL_AtomicGet(&queue->rwcount) > 0) { - SDL_Delay(0); - } - /* Do queue manipulation here... */ - SDL_AtomicDecRef(&queue->watcher); - SDL_AtomicUnlock(&queue->lock); - - /* Wait a bit... */ - SDL_Delay(1); - } - return 0; -} -#endif /* TEST_SPINLOCK_FIFO */ - -static void RunFIFOTest(SDL_bool lock_free) -{ - SDL_EventQueue queue; - WriterData writerData[NUM_WRITERS]; - ReaderData readerData[NUM_READERS]; - Uint32 start, end; - int i, j; - int grand_total; - char textBuffer[1024]; - size_t len; - - SDL_Log("\nFIFO test---------------------------------------\n\n"); - SDL_Log("Mode: %s\n", lock_free ? "LockFree" : "Mutex"); - - readersDone = SDL_CreateSemaphore(0); - writersDone = SDL_CreateSemaphore(0); - - SDL_memset(&queue, 0xff, sizeof(queue)); - - InitEventQueue(&queue); - if (!lock_free) { - queue.mutex = SDL_CreateMutex(); - } - - start = SDL_GetTicks(); - -#ifdef TEST_SPINLOCK_FIFO - /* Start a monitoring thread */ - if (lock_free) { - SDL_CreateThread(FIFO_Watcher, "FIFOWatcher", &queue); - } -#endif - - /* Start the readers first */ - SDL_Log("Starting %d readers\n", NUM_READERS); - SDL_zeroa(readerData); - SDL_AtomicSet(&readersRunning, NUM_READERS); - for (i = 0; i < NUM_READERS; ++i) { - char name[64]; - SDL_snprintf(name, sizeof (name), "FIFOReader%d", i); - readerData[i].queue = &queue; - readerData[i].lock_free = lock_free; - SDL_CreateThread(FIFO_Reader, name, &readerData[i]); - } - - /* Start up the writers */ - SDL_Log("Starting %d writers\n", NUM_WRITERS); - SDL_zeroa(writerData); - SDL_AtomicSet(&writersRunning, NUM_WRITERS); - for (i = 0; i < NUM_WRITERS; ++i) { - char name[64]; - SDL_snprintf(name, sizeof (name), "FIFOWriter%d", i); - writerData[i].queue = &queue; - writerData[i].index = i; - writerData[i].lock_free = lock_free; - SDL_CreateThread(FIFO_Writer, name, &writerData[i]); - } - - /* Wait for the writers */ - while (SDL_AtomicGet(&writersRunning) > 0) { - SDL_SemWait(writersDone); - } - - /* Shut down the queue so readers exit */ - SDL_AtomicSet(&queue.active, 0); - - /* Wait for the readers */ - while (SDL_AtomicGet(&readersRunning) > 0) { - SDL_SemWait(readersDone); - } - - end = SDL_GetTicks(); - - SDL_DestroySemaphore(readersDone); - SDL_DestroySemaphore(writersDone); - - if (!lock_free) { - SDL_DestroyMutex(queue.mutex); - } - - SDL_Log("Finished in %f sec\n", (end - start) / 1000.f); - - SDL_Log("\n"); - for (i = 0; i < NUM_WRITERS; ++i) { - SDL_Log("Writer %d wrote %d events, had %d waits\n", i, EVENTS_PER_WRITER, writerData[i].waits); - } - SDL_Log("Writers wrote %d total events\n", NUM_WRITERS*EVENTS_PER_WRITER); - - /* Print a breakdown of which readers read messages from which writer */ - SDL_Log("\n"); - grand_total = 0; - for (i = 0; i < NUM_READERS; ++i) { - int total = 0; - for (j = 0; j < NUM_WRITERS; ++j) { - total += readerData[i].counters[j]; - } - grand_total += total; - SDL_Log("Reader %d read %d events, had %d waits\n", i, total, readerData[i].waits); - SDL_snprintf(textBuffer, sizeof(textBuffer), " { "); - for (j = 0; j < NUM_WRITERS; ++j) { - if (j > 0) { - len = SDL_strlen(textBuffer); - SDL_snprintf(textBuffer + len, sizeof(textBuffer) - len, ", "); - } - len = SDL_strlen(textBuffer); - SDL_snprintf(textBuffer + len, sizeof(textBuffer) - len, "%d", readerData[i].counters[j]); - } - len = SDL_strlen(textBuffer); - SDL_snprintf(textBuffer + len, sizeof(textBuffer) - len, " }\n"); - SDL_Log("%s", textBuffer); - } - SDL_Log("Readers read %d total events\n", grand_total); -} - -/* End FIFO test */ -/**************************************************************************/ - -int -main(int argc, char *argv[]) -{ - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - RunBasicTest(); - RunEpicTest(); -/* This test is really slow, so don't run it by default */ -#if 0 - RunFIFOTest(SDL_FALSE); -#endif - RunFIFOTest(SDL_TRUE); - return 0; -} - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/test/testaudiocapture.c b/SDL2-2.0.12/test/testaudiocapture.c deleted file mode 100644 index 2dfbd02..0000000 --- a/SDL2-2.0.12/test/testaudiocapture.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ -#include "SDL.h" - -#include - -#ifdef __EMSCRIPTEN__ -#include -#endif - -static SDL_Window *window = NULL; -static SDL_Renderer *renderer = NULL; -static SDL_AudioSpec spec; -static SDL_AudioDeviceID devid_in = 0; -static SDL_AudioDeviceID devid_out = 0; - -static void -loop() -{ - SDL_bool please_quit = SDL_FALSE; - SDL_Event e; - - while (SDL_PollEvent(&e)) { - if (e.type == SDL_QUIT) { - please_quit = SDL_TRUE; - } else if (e.type == SDL_KEYDOWN) { - if (e.key.keysym.sym == SDLK_ESCAPE) { - please_quit = SDL_TRUE; - } - } else if (e.type == SDL_MOUSEBUTTONDOWN) { - if (e.button.button == 1) { - SDL_PauseAudioDevice(devid_out, SDL_TRUE); - SDL_PauseAudioDevice(devid_in, SDL_FALSE); - } - } else if (e.type == SDL_MOUSEBUTTONUP) { - if (e.button.button == 1) { - SDL_PauseAudioDevice(devid_in, SDL_TRUE); - SDL_PauseAudioDevice(devid_out, SDL_FALSE); - } - } - } - - if (SDL_GetAudioDeviceStatus(devid_in) == SDL_AUDIO_PLAYING) { - SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255); - } else { - SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); - } - SDL_RenderClear(renderer); - SDL_RenderPresent(renderer); - - if (please_quit) { - /* stop playing back, quit. */ - SDL_Log("Shutting down.\n"); - SDL_PauseAudioDevice(devid_in, 1); - SDL_CloseAudioDevice(devid_in); - SDL_PauseAudioDevice(devid_out, 1); - SDL_CloseAudioDevice(devid_out); - SDL_DestroyRenderer(renderer); - SDL_DestroyWindow(window); - SDL_Quit(); - #ifdef __EMSCRIPTEN__ - emscripten_cancel_main_loop(); - #endif - exit(0); - } - - /* Note that it would be easier to just have a one-line function that - calls SDL_QueueAudio() as a capture device callback, but we're - trying to test the API, so we use SDL_DequeueAudio() here. */ - while (SDL_TRUE) { - Uint8 buf[1024]; - const Uint32 br = SDL_DequeueAudio(devid_in, buf, sizeof (buf)); - SDL_QueueAudio(devid_out, buf, br); - if (br < sizeof (buf)) { - break; - } - } -} - -int -main(int argc, char **argv) -{ - /* (argv[1] == NULL means "open default device.") */ - const char *devname = argv[1]; - SDL_AudioSpec wanted; - int devcount; - int i; - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - /* Load the SDL library */ - if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError()); - return (1); - } - - window = SDL_CreateWindow("testaudiocapture", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 320, 240, 0); - renderer = SDL_CreateRenderer(window, -1, 0); - SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); - SDL_RenderClear(renderer); - SDL_RenderPresent(renderer); - - SDL_Log("Using audio driver: %s\n", SDL_GetCurrentAudioDriver()); - - devcount = SDL_GetNumAudioDevices(SDL_TRUE); - for (i = 0; i < devcount; i++) { - SDL_Log(" Capture device #%d: '%s'\n", i, SDL_GetAudioDeviceName(i, SDL_TRUE)); - } - - SDL_zero(wanted); - wanted.freq = 44100; - wanted.format = AUDIO_F32SYS; - wanted.channels = 1; - wanted.samples = 4096; - wanted.callback = NULL; - - SDL_zero(spec); - - /* DirectSound can fail in some instances if you open the same hardware - for both capture and output and didn't open the output end first, - according to the docs, so if you're doing something like this, always - open your capture devices second in case you land in those bizarre - circumstances. */ - - SDL_Log("Opening default playback device...\n"); - devid_out = SDL_OpenAudioDevice(NULL, SDL_FALSE, &wanted, &spec, SDL_AUDIO_ALLOW_ANY_CHANGE); - if (!devid_out) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open an audio device for playback: %s!\n", SDL_GetError()); - SDL_Quit(); - exit(1); - } - - SDL_Log("Opening capture device %s%s%s...\n", - devname ? "'" : "", - devname ? devname : "[[default]]", - devname ? "'" : ""); - - devid_in = SDL_OpenAudioDevice(argv[1], SDL_TRUE, &spec, &spec, 0); - if (!devid_in) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open an audio device for capture: %s!\n", SDL_GetError()); - SDL_Quit(); - exit(1); - } - - SDL_Log("Ready! Hold down mouse or finger to record!\n"); - -#ifdef __EMSCRIPTEN__ - emscripten_set_main_loop(loop, 0, 1); -#else - while (1) { loop(); SDL_Delay(16); } -#endif - - return 0; -} - diff --git a/SDL2-2.0.12/test/testaudiohotplug.c b/SDL2-2.0.12/test/testaudiohotplug.c deleted file mode 100644 index fe97459..0000000 --- a/SDL2-2.0.12/test/testaudiohotplug.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ - -/* Program to test hotplugging of audio devices */ - -#include "SDL_config.h" - -#include -#include - -#if HAVE_SIGNAL_H -#include -#endif - -#ifdef __EMSCRIPTEN__ -#include -#endif - -#include "SDL.h" - -static SDL_AudioSpec spec; -static Uint8 *sound = NULL; /* Pointer to wave data */ -static Uint32 soundlen = 0; /* Length of wave data */ - -static int posindex = 0; -static Uint32 positions[64]; - -/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ -static void -quit(int rc) -{ - SDL_Quit(); - exit(rc); -} - -void SDLCALL -fillerup(void *_pos, Uint8 * stream, int len) -{ - Uint32 pos = *((Uint32 *) _pos); - Uint8 *waveptr; - int waveleft; - - /* Set up the pointers */ - waveptr = sound + pos; - waveleft = soundlen - pos; - - /* Go! */ - while (waveleft <= len) { - SDL_memcpy(stream, waveptr, waveleft); - stream += waveleft; - len -= waveleft; - waveptr = sound; - waveleft = soundlen; - pos = 0; - } - SDL_memcpy(stream, waveptr, len); - pos += len; - *((Uint32 *) _pos) = pos; -} - -static int done = 0; -void -poked(int sig) -{ - done = 1; -} - -static const char* -devtypestr(int iscapture) -{ - return iscapture ? "capture" : "output"; -} - -static void -iteration() -{ - SDL_Event e; - SDL_AudioDeviceID dev; - while (SDL_PollEvent(&e)) { - if (e.type == SDL_QUIT) { - done = 1; - } else if (e.type == SDL_KEYUP) { - if (e.key.keysym.sym == SDLK_ESCAPE) - done = 1; - } else if (e.type == SDL_AUDIODEVICEADDED) { - int index = e.adevice.which; - int iscapture = e.adevice.iscapture; - const char *name = SDL_GetAudioDeviceName(index, iscapture); - if (name != NULL) - SDL_Log("New %s audio device at index %u: %s\n", devtypestr(iscapture), (unsigned int) index, name); - else { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Got new %s device at index %u, but failed to get the name: %s\n", - devtypestr(iscapture), (unsigned int) index, SDL_GetError()); - continue; - } - if (!iscapture) { - positions[posindex] = 0; - spec.userdata = &positions[posindex++]; - spec.callback = fillerup; - dev = SDL_OpenAudioDevice(name, 0, &spec, NULL, 0); - if (!dev) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open '%s': %s\n", name, SDL_GetError()); - } else { - SDL_Log("Opened '%s' as %u\n", name, (unsigned int) dev); - SDL_PauseAudioDevice(dev, 0); - } - } - } else if (e.type == SDL_AUDIODEVICEREMOVED) { - dev = (SDL_AudioDeviceID) e.adevice.which; - SDL_Log("%s device %u removed.\n", devtypestr(e.adevice.iscapture), (unsigned int) dev); - SDL_CloseAudioDevice(dev); - } - } -} - -#ifdef __EMSCRIPTEN__ -void -loop() -{ - if(done) - emscripten_cancel_main_loop(); - else - iteration(); -} -#endif - -int -main(int argc, char *argv[]) -{ - int i; - char filename[4096]; - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - /* Load the SDL library */ - if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError()); - return (1); - } - - /* Some targets (Mac CoreAudio) need an event queue for audio hotplug, so make and immediately hide a window. */ - SDL_MinimizeWindow(SDL_CreateWindow("testaudiohotplug", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0)); - - if (argc > 1) { - SDL_strlcpy(filename, argv[1], sizeof(filename)); - } else { - SDL_strlcpy(filename, "sample.wav", sizeof(filename)); - } - /* Load the wave file into memory */ - if (SDL_LoadWAV(filename, &spec, &sound, &soundlen) == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", filename, SDL_GetError()); - quit(1); - } - -#if HAVE_SIGNAL_H - /* Set the signals */ -#ifdef SIGHUP - signal(SIGHUP, poked); -#endif - signal(SIGINT, poked); -#ifdef SIGQUIT - signal(SIGQUIT, poked); -#endif - signal(SIGTERM, poked); -#endif /* HAVE_SIGNAL_H */ - - /* Show the list of available drivers */ - SDL_Log("Available audio drivers:"); - for (i = 0; i < SDL_GetNumAudioDrivers(); ++i) { - SDL_Log("%i: %s", i, SDL_GetAudioDriver(i)); - } - - SDL_Log("Select a driver with the SDL_AUDIODRIVER environment variable.\n"); - SDL_Log("Using audio driver: %s\n", SDL_GetCurrentAudioDriver()); - -#ifdef __EMSCRIPTEN__ - emscripten_set_main_loop(loop, 0, 1); -#else - while (!done) { - SDL_Delay(100); - iteration(); - } -#endif - - /* Clean up on signal */ - /* Quit audio first, then free WAV. This prevents access violations in the audio threads. */ - SDL_QuitSubSystem(SDL_INIT_AUDIO); - SDL_FreeWAV(sound); - SDL_Quit(); - return (0); -} - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/test/testaudioinfo.c b/SDL2-2.0.12/test/testaudioinfo.c deleted file mode 100644 index 8f58498..0000000 --- a/SDL2-2.0.12/test/testaudioinfo.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ -#include -#include "SDL.h" - -static void -print_devices(int iscapture) -{ - const char *typestr = ((iscapture) ? "capture" : "output"); - int n = SDL_GetNumAudioDevices(iscapture); - - SDL_Log("Found %d %s device%s:\n", n, typestr, n != 1 ? "s" : ""); - - if (n == -1) - SDL_Log(" Driver can't detect specific %s devices.\n\n", typestr); - else if (n == 0) - SDL_Log(" No %s devices found.\n\n", typestr); - else { - int i; - for (i = 0; i < n; i++) { - const char *name = SDL_GetAudioDeviceName(i, iscapture); - if (name != NULL) - SDL_Log(" %d: %s\n", i, name); - else - SDL_Log(" %d Error: %s\n", i, SDL_GetError()); - } - SDL_Log("\n"); - } -} - -int -main(int argc, char **argv) -{ - int n; - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - /* Load the SDL library */ - if (SDL_Init(SDL_INIT_AUDIO) < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError()); - return (1); - } - - /* Print available audio drivers */ - n = SDL_GetNumAudioDrivers(); - if (n == 0) { - SDL_Log("No built-in audio drivers\n\n"); - } else { - int i; - SDL_Log("Built-in audio drivers:\n"); - for (i = 0; i < n; ++i) { - SDL_Log(" %d: %s\n", i, SDL_GetAudioDriver(i)); - } - SDL_Log("Select a driver with the SDL_AUDIODRIVER environment variable.\n"); - } - - SDL_Log("Using audio driver: %s\n\n", SDL_GetCurrentAudioDriver()); - - print_devices(0); - print_devices(1); - - SDL_Quit(); - return 0; -} diff --git a/SDL2-2.0.12/test/testautomation.c b/SDL2-2.0.12/test/testautomation.c deleted file mode 100644 index bc7fa52..0000000 --- a/SDL2-2.0.12/test/testautomation.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ - -#include -#include -#include - -#include "SDL.h" -#include "SDL_test.h" - -#include "testautomation_suites.h" - -static SDLTest_CommonState *state; - -/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ -static void -quit(int rc) -{ - SDLTest_CommonQuit(state); - exit(rc); -} - -int -main(int argc, char *argv[]) -{ - int result; - int testIterations = 1; - Uint64 userExecKey = 0; - char *userRunSeed = NULL; - char *filter = NULL; - int i, done; - SDL_Event event; - - /* Initialize test framework */ - state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO); - if (!state) { - return 1; - } - - /* Parse commandline */ - for (i = 1; i < argc;) { - int consumed; - - consumed = SDLTest_CommonArg(state, i); - if (consumed == 0) { - consumed = -1; - if (SDL_strcasecmp(argv[i], "--iterations") == 0) { - if (argv[i + 1]) { - testIterations = SDL_atoi(argv[i + 1]); - if (testIterations < 1) testIterations = 1; - consumed = 2; - } - } - else if (SDL_strcasecmp(argv[i], "--execKey") == 0) { - if (argv[i + 1]) { - SDL_sscanf(argv[i + 1], "%"SDL_PRIu64, (long long unsigned int *)&userExecKey); - consumed = 2; - } - } - else if (SDL_strcasecmp(argv[i], "--seed") == 0) { - if (argv[i + 1]) { - userRunSeed = SDL_strdup(argv[i + 1]); - consumed = 2; - } - } - else if (SDL_strcasecmp(argv[i], "--filter") == 0) { - if (argv[i + 1]) { - filter = SDL_strdup(argv[i + 1]); - consumed = 2; - } - } - } - if (consumed < 0) { - static const char *options[] = { "[--iterations #]", "[--execKey #]", "[--seed string]", "[--filter suite_name|test_name]", NULL }; - SDLTest_CommonLogUsage(state, argv[0], options); - quit(1); - } - - i += consumed; - } - - /* Initialize common state */ - if (!SDLTest_CommonInit(state)) { - quit(2); - } - - /* Create the windows, initialize the renderers */ - for (i = 0; i < state->num_windows; ++i) { - SDL_Renderer *renderer = state->renderers[i]; - SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF); - SDL_RenderClear(renderer); - } - - /* Call Harness */ - result = SDLTest_RunSuites(testSuites, (const char *)userRunSeed, userExecKey, (const char *)filter, testIterations); - - /* Empty event queue */ - done = 0; - for (i=0; i<100; i++) { - while (SDL_PollEvent(&event)) { - SDLTest_CommonEvent(state, &event, &done); - } - SDL_Delay(10); - } - - /* Clean up */ - SDL_free(userRunSeed); - SDL_free(filter); - - /* Shutdown everything */ - quit(result); - return(result); -} - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/test/testautomation_audio.c b/SDL2-2.0.12/test/testautomation_audio.c deleted file mode 100644 index be0f15e..0000000 --- a/SDL2-2.0.12/test/testautomation_audio.c +++ /dev/null @@ -1,1038 +0,0 @@ -/** - * Original code: automated SDL audio test written by Edgar Simo "bobbens" - * New/updated tests: aschiffler at ferzkopp dot net - */ - -/* quiet windows compiler warnings */ -#define _CRT_SECURE_NO_WARNINGS - -#include -#include - -#include "SDL.h" -#include "SDL_test.h" - -/* ================= Test Case Implementation ================== */ - -/* Fixture */ - -void -_audioSetUp(void *arg) -{ - /* Start SDL audio subsystem */ - int ret = SDL_InitSubSystem( SDL_INIT_AUDIO ); - SDLTest_AssertPass("Call to SDL_InitSubSystem(SDL_INIT_AUDIO)"); - SDLTest_AssertCheck(ret==0, "Check result from SDL_InitSubSystem(SDL_INIT_AUDIO)"); - if (ret != 0) { - SDLTest_LogError("%s", SDL_GetError()); - } -} - -void -_audioTearDown(void *arg) -{ - /* Remove a possibly created file from SDL disk writer audio driver; ignore errors */ - remove("sdlaudio.raw"); - - SDLTest_AssertPass("Cleanup of test files completed"); -} - - -/* Global counter for callback invocation */ -int _audio_testCallbackCounter; - -/* Global accumulator for total callback length */ -int _audio_testCallbackLength; - - -/* Test callback function */ -void SDLCALL _audio_testCallback(void *userdata, Uint8 *stream, int len) -{ - /* track that callback was called */ - _audio_testCallbackCounter++; - _audio_testCallbackLength += len; -} - - -/* Test case functions */ - -/** - * \brief Stop and restart audio subsystem - * - * \sa https://wiki.libsdl.org/SDL_QuitSubSystem - * \sa https://wiki.libsdl.org/SDL_InitSubSystem - */ -int audio_quitInitAudioSubSystem() -{ - /* Stop SDL audio subsystem */ - SDL_QuitSubSystem( SDL_INIT_AUDIO ); - SDLTest_AssertPass("Call to SDL_QuitSubSystem(SDL_INIT_AUDIO)"); - - /* Restart audio again */ - _audioSetUp(NULL); - - return TEST_COMPLETED; -} - -/** - * \brief Start and stop audio directly - * - * \sa https://wiki.libsdl.org/SDL_InitAudio - * \sa https://wiki.libsdl.org/SDL_QuitAudio - */ -int audio_initQuitAudio() -{ - int result; - int i, iMax; - const char* audioDriver; - - /* Stop SDL audio subsystem */ - SDL_QuitSubSystem( SDL_INIT_AUDIO ); - SDLTest_AssertPass("Call to SDL_QuitSubSystem(SDL_INIT_AUDIO)"); - - /* Loop over all available audio drivers */ - iMax = SDL_GetNumAudioDrivers(); - SDLTest_AssertPass("Call to SDL_GetNumAudioDrivers()"); - SDLTest_AssertCheck(iMax > 0, "Validate number of audio drivers; expected: >0 got: %d", iMax); - for (i = 0; i < iMax; i++) { - audioDriver = SDL_GetAudioDriver(i); - SDLTest_AssertPass("Call to SDL_GetAudioDriver(%d)", i); - SDLTest_AssertCheck(audioDriver != NULL, "Audio driver name is not NULL"); - SDLTest_AssertCheck(audioDriver[0] != '\0', "Audio driver name is not empty; got: %s", audioDriver); - - /* Call Init */ - result = SDL_AudioInit(audioDriver); - SDLTest_AssertPass("Call to SDL_AudioInit('%s')", audioDriver); - SDLTest_AssertCheck(result == 0, "Validate result value; expected: 0 got: %d", result); - - /* Call Quit */ - SDL_AudioQuit(); - SDLTest_AssertPass("Call to SDL_AudioQuit()"); - } - - /* NULL driver specification */ - audioDriver = NULL; - - /* Call Init */ - result = SDL_AudioInit(audioDriver); - SDLTest_AssertPass("Call to SDL_AudioInit(NULL)"); - SDLTest_AssertCheck(result == 0, "Validate result value; expected: 0 got: %d", result); - - /* Call Quit */ - SDL_AudioQuit(); - SDLTest_AssertPass("Call to SDL_AudioQuit()"); - - /* Restart audio again */ - _audioSetUp(NULL); - - return TEST_COMPLETED; -} - -/** - * \brief Start, open, close and stop audio - * - * \sa https://wiki.libsdl.org/SDL_InitAudio - * \sa https://wiki.libsdl.org/SDL_OpenAudio - * \sa https://wiki.libsdl.org/SDL_CloseAudio - * \sa https://wiki.libsdl.org/SDL_QuitAudio - */ -int audio_initOpenCloseQuitAudio() -{ - int result, expectedResult; - int i, iMax, j, k; - const char* audioDriver; - SDL_AudioSpec desired; - - /* Stop SDL audio subsystem */ - SDL_QuitSubSystem( SDL_INIT_AUDIO ); - SDLTest_AssertPass("Call to SDL_QuitSubSystem(SDL_INIT_AUDIO)"); - - /* Loop over all available audio drivers */ - iMax = SDL_GetNumAudioDrivers(); - SDLTest_AssertPass("Call to SDL_GetNumAudioDrivers()"); - SDLTest_AssertCheck(iMax > 0, "Validate number of audio drivers; expected: >0 got: %d", iMax); - for (i = 0; i < iMax; i++) { - audioDriver = SDL_GetAudioDriver(i); - SDLTest_AssertPass("Call to SDL_GetAudioDriver(%d)", i); - SDLTest_AssertCheck(audioDriver != NULL, "Audio driver name is not NULL"); - SDLTest_AssertCheck(audioDriver[0] != '\0', "Audio driver name is not empty; got: %s", audioDriver); - - /* Change specs */ - for (j = 0; j < 2; j++) { - - /* Call Init */ - result = SDL_AudioInit(audioDriver); - SDLTest_AssertPass("Call to SDL_AudioInit('%s')", audioDriver); - SDLTest_AssertCheck(result == 0, "Validate result value; expected: 0 got: %d", result); - - /* Set spec */ - SDL_memset(&desired, 0, sizeof(desired)); - switch (j) { - case 0: - /* Set standard desired spec */ - desired.freq = 22050; - desired.format = AUDIO_S16SYS; - desired.channels = 2; - desired.samples = 4096; - desired.callback = _audio_testCallback; - desired.userdata = NULL; - - case 1: - /* Set custom desired spec */ - desired.freq = 48000; - desired.format = AUDIO_F32SYS; - desired.channels = 2; - desired.samples = 2048; - desired.callback = _audio_testCallback; - desired.userdata = NULL; - break; - } - - /* Call Open (maybe multiple times) */ - for (k=0; k <= j; k++) { - result = SDL_OpenAudio(&desired, NULL); - SDLTest_AssertPass("Call to SDL_OpenAudio(desired_spec_%d, NULL), call %d", j, k+1); - expectedResult = (k==0) ? 0 : -1; - SDLTest_AssertCheck(result == expectedResult, "Verify return value; expected: %d, got: %d", expectedResult, result); - } - - /* Call Close (maybe multiple times) */ - for (k=0; k <= j; k++) { - SDL_CloseAudio(); - SDLTest_AssertPass("Call to SDL_CloseAudio(), call %d", k+1); - } - - /* Call Quit (maybe multiple times) */ - for (k=0; k <= j; k++) { - SDL_AudioQuit(); - SDLTest_AssertPass("Call to SDL_AudioQuit(), call %d", k+1); - } - - } /* spec loop */ - } /* driver loop */ - - /* Restart audio again */ - _audioSetUp(NULL); - - return TEST_COMPLETED; -} - -/** - * \brief Pause and unpause audio - * - * \sa https://wiki.libsdl.org/SDL_PauseAudio - */ -int audio_pauseUnpauseAudio() -{ - int result; - int i, iMax, j, k, l; - int totalDelay; - int pause_on; - int originalCounter; - const char* audioDriver; - SDL_AudioSpec desired; - - /* Stop SDL audio subsystem */ - SDL_QuitSubSystem( SDL_INIT_AUDIO ); - SDLTest_AssertPass("Call to SDL_QuitSubSystem(SDL_INIT_AUDIO)"); - - /* Loop over all available audio drivers */ - iMax = SDL_GetNumAudioDrivers(); - SDLTest_AssertPass("Call to SDL_GetNumAudioDrivers()"); - SDLTest_AssertCheck(iMax > 0, "Validate number of audio drivers; expected: >0 got: %d", iMax); - for (i = 0; i < iMax; i++) { - audioDriver = SDL_GetAudioDriver(i); - SDLTest_AssertPass("Call to SDL_GetAudioDriver(%d)", i); - SDLTest_AssertCheck(audioDriver != NULL, "Audio driver name is not NULL"); - SDLTest_AssertCheck(audioDriver[0] != '\0', "Audio driver name is not empty; got: %s", audioDriver); - - /* Change specs */ - for (j = 0; j < 2; j++) { - - /* Call Init */ - result = SDL_AudioInit(audioDriver); - SDLTest_AssertPass("Call to SDL_AudioInit('%s')", audioDriver); - SDLTest_AssertCheck(result == 0, "Validate result value; expected: 0 got: %d", result); - - /* Set spec */ - SDL_memset(&desired, 0, sizeof(desired)); - switch (j) { - case 0: - /* Set standard desired spec */ - desired.freq = 22050; - desired.format = AUDIO_S16SYS; - desired.channels = 2; - desired.samples = 4096; - desired.callback = _audio_testCallback; - desired.userdata = NULL; - - case 1: - /* Set custom desired spec */ - desired.freq = 48000; - desired.format = AUDIO_F32SYS; - desired.channels = 2; - desired.samples = 2048; - desired.callback = _audio_testCallback; - desired.userdata = NULL; - break; - } - - /* Call Open */ - result = SDL_OpenAudio(&desired, NULL); - SDLTest_AssertPass("Call to SDL_OpenAudio(desired_spec_%d, NULL)", j); - SDLTest_AssertCheck(result == 0, "Verify return value; expected: 0 got: %d", result); - - /* Start and stop audio multiple times */ - for (l=0; l<3; l++) { - SDLTest_Log("Pause/Unpause iteration: %d", l+1); - - /* Reset callback counters */ - _audio_testCallbackCounter = 0; - _audio_testCallbackLength = 0; - - /* Un-pause audio to start playing (maybe multiple times) */ - pause_on = 0; - for (k=0; k <= j; k++) { - SDL_PauseAudio(pause_on); - SDLTest_AssertPass("Call to SDL_PauseAudio(%d), call %d", pause_on, k+1); - } - - /* Wait for callback */ - totalDelay = 0; - do { - SDL_Delay(10); - totalDelay += 10; - } - while (_audio_testCallbackCounter == 0 && totalDelay < 1000); - SDLTest_AssertCheck(_audio_testCallbackCounter > 0, "Verify callback counter; expected: >0 got: %d", _audio_testCallbackCounter); - SDLTest_AssertCheck(_audio_testCallbackLength > 0, "Verify callback length; expected: >0 got: %d", _audio_testCallbackLength); - - /* Pause audio to stop playing (maybe multiple times) */ - for (k=0; k <= j; k++) { - pause_on = (k==0) ? 1 : SDLTest_RandomIntegerInRange(99, 9999); - SDL_PauseAudio(pause_on); - SDLTest_AssertPass("Call to SDL_PauseAudio(%d), call %d", pause_on, k+1); - } - - /* Ensure callback is not called again */ - originalCounter = _audio_testCallbackCounter; - SDL_Delay(totalDelay + 10); - SDLTest_AssertCheck(originalCounter == _audio_testCallbackCounter, "Verify callback counter; expected: %d, got: %d", originalCounter, _audio_testCallbackCounter); - } - - /* Call Close */ - SDL_CloseAudio(); - SDLTest_AssertPass("Call to SDL_CloseAudio()"); - - /* Call Quit */ - SDL_AudioQuit(); - SDLTest_AssertPass("Call to SDL_AudioQuit()"); - - } /* spec loop */ - } /* driver loop */ - - /* Restart audio again */ - _audioSetUp(NULL); - - return TEST_COMPLETED; -} - -/** - * \brief Enumerate and name available audio devices (output and capture). - * - * \sa https://wiki.libsdl.org/SDL_GetNumAudioDevices - * \sa https://wiki.libsdl.org/SDL_GetAudioDeviceName - */ -int audio_enumerateAndNameAudioDevices() -{ - int t, tt; - int i, n, nn; - const char *name, *nameAgain; - - /* Iterate over types: t=0 output device, t=1 input/capture device */ - for (t=0; t<2; t++) { - - /* Get number of devices. */ - n = SDL_GetNumAudioDevices(t); - SDLTest_AssertPass("Call to SDL_GetNumAudioDevices(%i)", t); - SDLTest_Log("Number of %s devices < 0, reported as %i", (t) ? "capture" : "output", n); - SDLTest_AssertCheck(n >= 0, "Validate result is >= 0, got: %i", n); - - /* Variation of non-zero type */ - if (t==1) { - tt = t + SDLTest_RandomIntegerInRange(1,10); - nn = SDL_GetNumAudioDevices(tt); - SDLTest_AssertCheck(n==nn, "Verify result from SDL_GetNumAudioDevices(%i), expected same number of audio devices %i, got %i", tt, n, nn); - nn = SDL_GetNumAudioDevices(-tt); - SDLTest_AssertCheck(n==nn, "Verify result from SDL_GetNumAudioDevices(%i), expected same number of audio devices %i, got %i", -tt, n, nn); - } - - /* List devices. */ - if (n>0) { - for (i=0; i0) && (no>nc) && (t==1)) { - i = no-1; - name = SDL_GetAudioDeviceName(i, t); - SDLTest_AssertPass("Call to SDL_GetAudioDeviceName(%i, %i)", i, t); - SDLTest_AssertCheck(name == NULL, "Check SDL_GetAudioDeviceName(%i, %i) result, expected: NULL, got: %s", i, t, (name == NULL) ? "NULL" : name); - } - } - - return TEST_COMPLETED; -} - - -/** - * \brief Checks available audio driver names. - * - * \sa https://wiki.libsdl.org/SDL_GetNumAudioDrivers - * \sa https://wiki.libsdl.org/SDL_GetAudioDriver - */ -int audio_printAudioDrivers() -{ - int i, n; - const char *name; - - /* Get number of drivers */ - n = SDL_GetNumAudioDrivers(); - SDLTest_AssertPass("Call to SDL_GetNumAudioDrivers()"); - SDLTest_AssertCheck(n>=0, "Verify number of audio drivers >= 0, got: %i", n); - - /* List drivers. */ - if (n>0) - { - for (i=0; i spec1)"); - SDLTest_AssertCheck(result == 0, "Verify result value; expected: 0, got: %i", result); - - /* Typical conversion */ - spec1.format = AUDIO_S8; - spec1.channels = 1; - spec1.freq = 22050; - spec2.format = AUDIO_S16LSB; - spec2.channels = 2; - spec2.freq = 44100; - result = SDL_BuildAudioCVT(&cvt, spec1.format, spec1.channels, spec1.freq, - spec2.format, spec2.channels, spec2.freq); - SDLTest_AssertPass("Call to SDL_BuildAudioCVT(spec1 ==> spec2)"); - SDLTest_AssertCheck(result == 1, "Verify result value; expected: 1, got: %i", result); - - /* All source conversions with random conversion targets, allow 'null' conversions */ - for (i = 0; i < _numAudioFormats; i++) { - for (j = 0; j < _numAudioChannels; j++) { - for (k = 0; k < _numAudioFrequencies; k++) { - spec1.format = _audioFormats[i]; - spec1.channels = _audioChannels[j]; - spec1.freq = _audioFrequencies[k]; - ii = SDLTest_RandomIntegerInRange(0, _numAudioFormats - 1); - jj = SDLTest_RandomIntegerInRange(0, _numAudioChannels - 1); - kk = SDLTest_RandomIntegerInRange(0, _numAudioFrequencies - 1); - spec2.format = _audioFormats[ii]; - spec2.channels = _audioChannels[jj]; - spec2.freq = _audioFrequencies[kk]; - result = SDL_BuildAudioCVT(&cvt, spec1.format, spec1.channels, spec1.freq, - spec2.format, spec2.channels, spec2.freq); - SDLTest_AssertPass("Call to SDL_BuildAudioCVT(format[%i]=%s(%i),channels[%i]=%i,freq[%i]=%i ==> format[%i]=%s(%i),channels[%i]=%i,freq[%i]=%i)", - i, _audioFormatsVerbose[i], spec1.format, j, spec1.channels, k, spec1.freq, ii, _audioFormatsVerbose[ii], spec2.format, jj, spec2.channels, kk, spec2.freq); - SDLTest_AssertCheck(result == 0 || result == 1, "Verify result value; expected: 0 or 1, got: %i", result); - if (result<0) { - SDLTest_LogError("%s", SDL_GetError()); - } else { - SDLTest_AssertCheck(cvt.len_mult > 0, "Verify that cvt.len_mult value; expected: >0, got: %i", cvt.len_mult); - } - } - } - } - - return TEST_COMPLETED; -} - -/** - * \brief Checkes calls with invalid input to SDL_BuildAudioCVT - * - * \sa https://wiki.libsdl.org/SDL_BuildAudioCVT - */ -int audio_buildAudioCVTNegative() -{ - const char *expectedError = "Parameter 'cvt' is invalid"; - const char *error; - int result; - SDL_AudioCVT cvt; - SDL_AudioSpec spec1; - SDL_AudioSpec spec2; - int i; - char message[256]; - - /* Valid format */ - spec1.format = AUDIO_S8; - spec1.channels = 1; - spec1.freq = 22050; - spec2.format = AUDIO_S16LSB; - spec2.channels = 2; - spec2.freq = 44100; - - SDL_ClearError(); - SDLTest_AssertPass("Call to SDL_ClearError()"); - - /* NULL input for CVT buffer */ - result = SDL_BuildAudioCVT((SDL_AudioCVT *)NULL, spec1.format, spec1.channels, spec1.freq, - spec2.format, spec2.channels, spec2.freq); - SDLTest_AssertPass("Call to SDL_BuildAudioCVT(NULL,...)"); - SDLTest_AssertCheck(result == -1, "Verify result value; expected: -1, got: %i", result); - error = SDL_GetError(); - SDLTest_AssertPass("Call to SDL_GetError()"); - SDLTest_AssertCheck(error != NULL, "Validate that error message was not NULL"); - if (error != NULL) { - SDLTest_AssertCheck(SDL_strcmp(error, expectedError) == 0, - "Validate error message, expected: '%s', got: '%s'", expectedError, error); - } - - /* Invalid conversions */ - for (i = 1; i < 64; i++) { - /* Valid format to start with */ - spec1.format = AUDIO_S8; - spec1.channels = 1; - spec1.freq = 22050; - spec2.format = AUDIO_S16LSB; - spec2.channels = 2; - spec2.freq = 44100; - - SDL_ClearError(); - SDLTest_AssertPass("Call to SDL_ClearError()"); - - /* Set various invalid format inputs */ - SDL_strlcpy(message, "Invalid: ", 256); - if (i & 1) { - SDL_strlcat(message, " spec1.format", 256); - spec1.format = 0; - } - if (i & 2) { - SDL_strlcat(message, " spec1.channels", 256); - spec1.channels = 0; - } - if (i & 4) { - SDL_strlcat(message, " spec1.freq", 256); - spec1.freq = 0; - } - if (i & 8) { - SDL_strlcat(message, " spec2.format", 256); - spec2.format = 0; - } - if (i & 16) { - SDL_strlcat(message, " spec2.channels", 256); - spec2.channels = 0; - } - if (i & 32) { - SDL_strlcat(message, " spec2.freq", 256); - spec2.freq = 0; - } - SDLTest_Log("%s", message); - result = SDL_BuildAudioCVT(&cvt, spec1.format, spec1.channels, spec1.freq, - spec2.format, spec2.channels, spec2.freq); - SDLTest_AssertPass("Call to SDL_BuildAudioCVT(spec1 ==> spec2)"); - SDLTest_AssertCheck(result == -1, "Verify result value; expected: -1, got: %i", result); - error = SDL_GetError(); - SDLTest_AssertPass("Call to SDL_GetError()"); - SDLTest_AssertCheck(error != NULL && error[0] != '\0', "Validate that error message was not NULL or empty"); - } - - SDL_ClearError(); - SDLTest_AssertPass("Call to SDL_ClearError()"); - - return TEST_COMPLETED; -} - -/** - * \brief Checks current audio status. - * - * \sa https://wiki.libsdl.org/SDL_GetAudioStatus - */ -int audio_getAudioStatus() -{ - SDL_AudioStatus result; - - /* Check current audio status */ - result = SDL_GetAudioStatus(); - SDLTest_AssertPass("Call to SDL_GetAudioStatus()"); - SDLTest_AssertCheck(result == SDL_AUDIO_STOPPED || result == SDL_AUDIO_PLAYING || result == SDL_AUDIO_PAUSED, - "Verify returned value; expected: STOPPED (%i) | PLAYING (%i) | PAUSED (%i), got: %i", - SDL_AUDIO_STOPPED, SDL_AUDIO_PLAYING, SDL_AUDIO_PAUSED, result); - - return TEST_COMPLETED; -} - - - -/** - * \brief Opens, checks current audio status, and closes a device. - * - * \sa https://wiki.libsdl.org/SDL_GetAudioStatus - */ -int audio_openCloseAndGetAudioStatus() -{ - SDL_AudioStatus result; - int i; - int count; - char *device; - SDL_AudioDeviceID id; - SDL_AudioSpec desired, obtained; - - /* Get number of devices. */ - count = SDL_GetNumAudioDevices(0); - SDLTest_AssertPass("Call to SDL_GetNumAudioDevices(0)"); - if (count > 0) { - for (i = 0; i < count; i++) { - /* Get device name */ - device = (char *)SDL_GetAudioDeviceName(i, 0); - SDLTest_AssertPass("SDL_GetAudioDeviceName(%i,0)", i); - SDLTest_AssertCheck(device != NULL, "Validate device name is not NULL; got: %s", (device != NULL) ? device : "NULL"); - if (device == NULL) return TEST_ABORTED; - - /* Set standard desired spec */ - desired.freq=22050; - desired.format=AUDIO_S16SYS; - desired.channels=2; - desired.samples=4096; - desired.callback=_audio_testCallback; - desired.userdata=NULL; - - /* Open device */ - id = SDL_OpenAudioDevice((const char *)device, 0, &desired, &obtained, SDL_AUDIO_ALLOW_ANY_CHANGE); - SDLTest_AssertPass("SDL_OpenAudioDevice('%s',...)", device); - SDLTest_AssertCheck(id > 1, "Validate device ID; expected: >=2, got: %i", id); - if (id > 1) { - - /* Check device audio status */ - result = SDL_GetAudioDeviceStatus(id); - SDLTest_AssertPass("Call to SDL_GetAudioDeviceStatus()"); - SDLTest_AssertCheck(result == SDL_AUDIO_STOPPED || result == SDL_AUDIO_PLAYING || result == SDL_AUDIO_PAUSED, - "Verify returned value; expected: STOPPED (%i) | PLAYING (%i) | PAUSED (%i), got: %i", - SDL_AUDIO_STOPPED, SDL_AUDIO_PLAYING, SDL_AUDIO_PAUSED, result); - - /* Close device again */ - SDL_CloseAudioDevice(id); - SDLTest_AssertPass("Call to SDL_CloseAudioDevice()"); - } - } - } else { - SDLTest_Log("No devices to test with"); - } - - return TEST_COMPLETED; -} - -/** - * \brief Locks and unlocks open audio device. - * - * \sa https://wiki.libsdl.org/SDL_LockAudioDevice - * \sa https://wiki.libsdl.org/SDL_UnlockAudioDevice - */ -int audio_lockUnlockOpenAudioDevice() -{ - int i; - int count; - char *device; - SDL_AudioDeviceID id; - SDL_AudioSpec desired, obtained; - - /* Get number of devices. */ - count = SDL_GetNumAudioDevices(0); - SDLTest_AssertPass("Call to SDL_GetNumAudioDevices(0)"); - if (count > 0) { - for (i = 0; i < count; i++) { - /* Get device name */ - device = (char *)SDL_GetAudioDeviceName(i, 0); - SDLTest_AssertPass("SDL_GetAudioDeviceName(%i,0)", i); - SDLTest_AssertCheck(device != NULL, "Validate device name is not NULL; got: %s", (device != NULL) ? device : "NULL"); - if (device == NULL) return TEST_ABORTED; - - /* Set standard desired spec */ - desired.freq=22050; - desired.format=AUDIO_S16SYS; - desired.channels=2; - desired.samples=4096; - desired.callback=_audio_testCallback; - desired.userdata=NULL; - - /* Open device */ - id = SDL_OpenAudioDevice((const char *)device, 0, &desired, &obtained, SDL_AUDIO_ALLOW_ANY_CHANGE); - SDLTest_AssertPass("SDL_OpenAudioDevice('%s',...)", device); - SDLTest_AssertCheck(id > 1, "Validate device ID; expected: >=2, got: %i", id); - if (id > 1) { - /* Lock to protect callback */ - SDL_LockAudioDevice(id); - SDLTest_AssertPass("SDL_LockAudioDevice(%i)", id); - - /* Simulate callback processing */ - SDL_Delay(10); - SDLTest_Log("Simulate callback processing - delay"); - - /* Unlock again */ - SDL_UnlockAudioDevice(id); - SDLTest_AssertPass("SDL_UnlockAudioDevice(%i)", id); - - /* Close device again */ - SDL_CloseAudioDevice(id); - SDLTest_AssertPass("Call to SDL_CloseAudioDevice()"); - } - } - } else { - SDLTest_Log("No devices to test with"); - } - - return TEST_COMPLETED; -} - - -/** - * \brief Convert audio using various conversion structures - * - * \sa https://wiki.libsdl.org/SDL_BuildAudioCVT - * \sa https://wiki.libsdl.org/SDL_ConvertAudio - */ -int audio_convertAudio() -{ - int result; - SDL_AudioCVT cvt; - SDL_AudioSpec spec1; - SDL_AudioSpec spec2; - int c; - char message[128]; - int i, ii, j, jj, k, kk, l, ll; - - /* Iterate over bitmask that determines which parameters are modified in the conversion */ - for (c = 1; c < 8; c++) { - SDL_strlcpy(message, "Changing:", 128); - if (c & 1) { - SDL_strlcat(message, " Format", 128); - } - if (c & 2) { - SDL_strlcat(message, " Channels", 128); - } - if (c & 4) { - SDL_strlcat(message, " Frequencies", 128); - } - SDLTest_Log("%s", message); - /* All source conversions with random conversion targets */ - for (i = 0; i < _numAudioFormats; i++) { - for (j = 0; j < _numAudioChannels; j++) { - for (k = 0; k < _numAudioFrequencies; k++) { - spec1.format = _audioFormats[i]; - spec1.channels = _audioChannels[j]; - spec1.freq = _audioFrequencies[k]; - - /* Ensure we have a different target format */ - do { - if (c & 1) { - ii = SDLTest_RandomIntegerInRange(0, _numAudioFormats - 1); - } else { - ii = 1; - } - if (c & 2) { - jj = SDLTest_RandomIntegerInRange(0, _numAudioChannels - 1); - } else { - jj= j; - } - if (c & 4) { - kk = SDLTest_RandomIntegerInRange(0, _numAudioFrequencies - 1); - } else { - kk = k; - } - } while ((i == ii) && (j == jj) && (k == kk)); - spec2.format = _audioFormats[ii]; - spec2.channels = _audioChannels[jj]; - spec2.freq = _audioFrequencies[kk]; - - result = SDL_BuildAudioCVT(&cvt, spec1.format, spec1.channels, spec1.freq, - spec2.format, spec2.channels, spec2.freq); - SDLTest_AssertPass("Call to SDL_BuildAudioCVT(format[%i]=%s(%i),channels[%i]=%i,freq[%i]=%i ==> format[%i]=%s(%i),channels[%i]=%i,freq[%i]=%i)", - i, _audioFormatsVerbose[i], spec1.format, j, spec1.channels, k, spec1.freq, ii, _audioFormatsVerbose[ii], spec2.format, jj, spec2.channels, kk, spec2.freq); - SDLTest_AssertCheck(result == 1, "Verify result value; expected: 1, got: %i", result); - if (result != 1) { - SDLTest_LogError("%s", SDL_GetError()); - } else { - SDLTest_AssertCheck(cvt.len_mult > 0, "Verify that cvt.len_mult value; expected: >0, got: %i", cvt.len_mult); - if (cvt.len_mult < 1) return TEST_ABORTED; - - /* Create some random data to convert */ - l = 64; - ll = l * cvt.len_mult; - SDLTest_Log("Creating dummy sample buffer of %i length (%i bytes)", l, ll); - cvt.len = l; - cvt.buf = (Uint8 *)SDL_malloc(ll); - SDLTest_AssertCheck(cvt.buf != NULL, "Check data buffer to convert is not NULL"); - if (cvt.buf == NULL) return TEST_ABORTED; - - /* Convert the data */ - result = SDL_ConvertAudio(&cvt); - SDLTest_AssertPass("Call to SDL_ConvertAudio()"); - SDLTest_AssertCheck(result == 0, "Verify result value; expected: 0; got: %i", result); - SDLTest_AssertCheck(cvt.buf != NULL, "Verify conversion buffer is not NULL"); - SDLTest_AssertCheck(cvt.len_ratio > 0.0, "Verify conversion length ratio; expected: >0; got: %f", cvt.len_ratio); - - /* Free converted buffer */ - SDL_free(cvt.buf); - cvt.buf = NULL; - } - } - } - } - } - - return TEST_COMPLETED; -} - - -/** - * \brief Opens, checks current connected status, and closes a device. - * - * \sa https://wiki.libsdl.org/SDL_AudioDeviceConnected - */ -int audio_openCloseAudioDeviceConnected() -{ - int result = -1; - int i; - int count; - char *device; - SDL_AudioDeviceID id; - SDL_AudioSpec desired, obtained; - - /* Get number of devices. */ - count = SDL_GetNumAudioDevices(0); - SDLTest_AssertPass("Call to SDL_GetNumAudioDevices(0)"); - if (count > 0) { - for (i = 0; i < count; i++) { - /* Get device name */ - device = (char *)SDL_GetAudioDeviceName(i, 0); - SDLTest_AssertPass("SDL_GetAudioDeviceName(%i,0)", i); - SDLTest_AssertCheck(device != NULL, "Validate device name is not NULL; got: %s", (device != NULL) ? device : "NULL"); - if (device == NULL) return TEST_ABORTED; - - /* Set standard desired spec */ - desired.freq=22050; - desired.format=AUDIO_S16SYS; - desired.channels=2; - desired.samples=4096; - desired.callback=_audio_testCallback; - desired.userdata=NULL; - - /* Open device */ - id = SDL_OpenAudioDevice((const char *)device, 0, &desired, &obtained, SDL_AUDIO_ALLOW_ANY_CHANGE); - SDLTest_AssertPass("SDL_OpenAudioDevice('%s',...)", device); - SDLTest_AssertCheck(id > 1, "Validate device ID; expected: >1, got: %i", id); - if (id > 1) { - -/* TODO: enable test code when function is available in SDL2 */ - -#ifdef AUDIODEVICECONNECTED_DEFINED - /* Get connected status */ - result = SDL_AudioDeviceConnected(id); - SDLTest_AssertPass("Call to SDL_AudioDeviceConnected()"); -#endif - SDLTest_AssertCheck(result == 1, "Verify returned value; expected: 1; got: %i", result); - - /* Close device again */ - SDL_CloseAudioDevice(id); - SDLTest_AssertPass("Call to SDL_CloseAudioDevice()"); - } - } - } else { - SDLTest_Log("No devices to test with"); - } - - return TEST_COMPLETED; -} - - - -/* ================= Test Case References ================== */ - -/* Audio test cases */ -static const SDLTest_TestCaseReference audioTest1 = - { (SDLTest_TestCaseFp)audio_enumerateAndNameAudioDevices, "audio_enumerateAndNameAudioDevices", "Enumerate and name available audio devices (output and capture)", TEST_ENABLED }; - -static const SDLTest_TestCaseReference audioTest2 = - { (SDLTest_TestCaseFp)audio_enumerateAndNameAudioDevicesNegativeTests, "audio_enumerateAndNameAudioDevicesNegativeTests", "Negative tests around enumeration and naming of audio devices.", TEST_ENABLED }; - -static const SDLTest_TestCaseReference audioTest3 = - { (SDLTest_TestCaseFp)audio_printAudioDrivers, "audio_printAudioDrivers", "Checks available audio driver names.", TEST_ENABLED }; - -static const SDLTest_TestCaseReference audioTest4 = - { (SDLTest_TestCaseFp)audio_printCurrentAudioDriver, "audio_printCurrentAudioDriver", "Checks current audio driver name with initialized audio.", TEST_ENABLED }; - -static const SDLTest_TestCaseReference audioTest5 = - { (SDLTest_TestCaseFp)audio_buildAudioCVT, "audio_buildAudioCVT", "Builds various audio conversion structures.", TEST_ENABLED }; - -static const SDLTest_TestCaseReference audioTest6 = - { (SDLTest_TestCaseFp)audio_buildAudioCVTNegative, "audio_buildAudioCVTNegative", "Checks calls with invalid input to SDL_BuildAudioCVT", TEST_ENABLED }; - -static const SDLTest_TestCaseReference audioTest7 = - { (SDLTest_TestCaseFp)audio_getAudioStatus, "audio_getAudioStatus", "Checks current audio status.", TEST_ENABLED }; - -static const SDLTest_TestCaseReference audioTest8 = - { (SDLTest_TestCaseFp)audio_openCloseAndGetAudioStatus, "audio_openCloseAndGetAudioStatus", "Opens and closes audio device and get audio status.", TEST_ENABLED }; - -static const SDLTest_TestCaseReference audioTest9 = - { (SDLTest_TestCaseFp)audio_lockUnlockOpenAudioDevice, "audio_lockUnlockOpenAudioDevice", "Locks and unlocks an open audio device.", TEST_ENABLED }; - -/* TODO: enable test when SDL_ConvertAudio segfaults on cygwin have been fixed. */ -/* For debugging, test case can be run manually using --filter audio_convertAudio */ - -static const SDLTest_TestCaseReference audioTest10 = - { (SDLTest_TestCaseFp)audio_convertAudio, "audio_convertAudio", "Convert audio using available formats.", TEST_DISABLED }; - -/* TODO: enable test when SDL_AudioDeviceConnected has been implemented. */ - -static const SDLTest_TestCaseReference audioTest11 = - { (SDLTest_TestCaseFp)audio_openCloseAudioDeviceConnected, "audio_openCloseAudioDeviceConnected", "Opens and closes audio device and get connected status.", TEST_DISABLED }; - -static const SDLTest_TestCaseReference audioTest12 = - { (SDLTest_TestCaseFp)audio_quitInitAudioSubSystem, "audio_quitInitAudioSubSystem", "Quit and re-init audio subsystem.", TEST_ENABLED }; - -static const SDLTest_TestCaseReference audioTest13 = - { (SDLTest_TestCaseFp)audio_initQuitAudio, "audio_initQuitAudio", "Init and quit audio drivers directly.", TEST_ENABLED }; - -static const SDLTest_TestCaseReference audioTest14 = - { (SDLTest_TestCaseFp)audio_initOpenCloseQuitAudio, "audio_initOpenCloseQuitAudio", "Cycle through init, open, close and quit with various audio specs.", TEST_ENABLED }; - -static const SDLTest_TestCaseReference audioTest15 = - { (SDLTest_TestCaseFp)audio_pauseUnpauseAudio, "audio_pauseUnpauseAudio", "Pause and Unpause audio for various audio specs while testing callback.", TEST_ENABLED }; - -/* Sequence of Audio test cases */ -static const SDLTest_TestCaseReference *audioTests[] = { - &audioTest1, &audioTest2, &audioTest3, &audioTest4, &audioTest5, &audioTest6, - &audioTest7, &audioTest8, &audioTest9, &audioTest10, &audioTest11, - &audioTest12, &audioTest13, &audioTest14, &audioTest15, NULL -}; - -/* Audio test suite (global) */ -SDLTest_TestSuiteReference audioTestSuite = { - "Audio", - _audioSetUp, - audioTests, - _audioTearDown -}; diff --git a/SDL2-2.0.12/test/testautomation_clipboard.c b/SDL2-2.0.12/test/testautomation_clipboard.c deleted file mode 100644 index 417d957..0000000 --- a/SDL2-2.0.12/test/testautomation_clipboard.c +++ /dev/null @@ -1,184 +0,0 @@ -/** - * New/updated tests: aschiffler at ferzkopp dot net - */ - -#include -#include - -#include "SDL.h" -#include "SDL_test.h" - -/* ================= Test Case Implementation ================== */ - -/* Test case functions */ - -/** - * \brief Check call to SDL_HasClipboardText - * - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_HasClipboardText - */ -int -clipboard_testHasClipboardText(void *arg) -{ - SDL_bool result; - result = SDL_HasClipboardText(); - SDLTest_AssertPass("Call to SDL_HasClipboardText succeeded"); - - return TEST_COMPLETED; -} - -/** - * \brief Check call to SDL_GetClipboardText - * - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_GetClipboardText - */ -int -clipboard_testGetClipboardText(void *arg) -{ - char *charResult; - charResult = SDL_GetClipboardText(); - SDLTest_AssertPass("Call to SDL_GetClipboardText succeeded"); - - SDL_free(charResult); - - return TEST_COMPLETED; -} - -/** - * \brief Check call to SDL_SetClipboardText - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_SetClipboardText - */ -int -clipboard_testSetClipboardText(void *arg) -{ - char *textRef = SDLTest_RandomAsciiString(); - char *text = SDL_strdup(textRef); - int result; - result = SDL_SetClipboardText((const char *)text); - SDLTest_AssertPass("Call to SDL_SetClipboardText succeeded"); - SDLTest_AssertCheck( - result == 0, - "Validate SDL_SetClipboardText result, expected 0, got %i", - result); - SDLTest_AssertCheck( - SDL_strcmp(textRef, text) == 0, - "Verify SDL_SetClipboardText did not modify input string, expected '%s', got '%s'", - textRef, text); - - /* Cleanup */ - SDL_free(textRef); - SDL_free(text); - - return TEST_COMPLETED; -} - -/** - * \brief End-to-end test of SDL_xyzClipboardText functions - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_HasClipboardText - * http://wiki.libsdl.org/moin.cgi/SDL_GetClipboardText - * http://wiki.libsdl.org/moin.cgi/SDL_SetClipboardText - */ -int -clipboard_testClipboardTextFunctions(void *arg) -{ - char *textRef = SDLTest_RandomAsciiString(); - char *text = SDL_strdup(textRef); - SDL_bool boolResult; - int intResult; - char *charResult; - - /* Clear clipboard text state */ - boolResult = SDL_HasClipboardText(); - SDLTest_AssertPass("Call to SDL_HasClipboardText succeeded"); - if (boolResult == SDL_TRUE) { - intResult = SDL_SetClipboardText((const char *)NULL); - SDLTest_AssertPass("Call to SDL_SetClipboardText(NULL) succeeded"); - SDLTest_AssertCheck( - intResult == 0, - "Verify result from SDL_SetClipboardText(NULL), expected 0, got %i", - intResult); - charResult = SDL_GetClipboardText(); - SDLTest_AssertPass("Call to SDL_GetClipboardText succeeded"); - SDL_free(charResult); - boolResult = SDL_HasClipboardText(); - SDLTest_AssertPass("Call to SDL_HasClipboardText succeeded"); - SDLTest_AssertCheck( - boolResult == SDL_FALSE, - "Verify SDL_HasClipboardText returned SDL_FALSE, got %s", - (boolResult) ? "SDL_TRUE" : "SDL_FALSE"); - } - - /* Empty clipboard */ - charResult = SDL_GetClipboardText(); - SDLTest_AssertPass("Call to SDL_GetClipboardText succeeded"); - SDLTest_AssertCheck( - charResult != NULL, - "Verify SDL_GetClipboardText did not return NULL"); - SDLTest_AssertCheck( - charResult[0] == '\0', - "Verify SDL_GetClipboardText returned string with length 0, got length %i", - (int) SDL_strlen(charResult)); - intResult = SDL_SetClipboardText((const char *)text); - SDLTest_AssertPass("Call to SDL_SetClipboardText succeeded"); - SDLTest_AssertCheck( - intResult == 0, - "Verify result from SDL_SetClipboardText(NULL), expected 0, got %i", - intResult); - SDLTest_AssertCheck( - SDL_strcmp(textRef, text) == 0, - "Verify SDL_SetClipboardText did not modify input string, expected '%s', got '%s'", - textRef, text); - boolResult = SDL_HasClipboardText(); - SDLTest_AssertPass("Call to SDL_HasClipboardText succeeded"); - SDLTest_AssertCheck( - boolResult == SDL_TRUE, - "Verify SDL_HasClipboardText returned SDL_TRUE, got %s", - (boolResult) ? "SDL_TRUE" : "SDL_FALSE"); - SDL_free(charResult); - charResult = SDL_GetClipboardText(); - SDLTest_AssertPass("Call to SDL_GetClipboardText succeeded"); - SDLTest_AssertCheck( - SDL_strcmp(textRef, charResult) == 0, - "Verify SDL_GetClipboardText returned correct string, expected '%s', got '%s'", - textRef, charResult); - - /* Cleanup */ - SDL_free(textRef); - SDL_free(text); - SDL_free(charResult); - - return TEST_COMPLETED; -} - - -/* ================= Test References ================== */ - -/* Clipboard test cases */ -static const SDLTest_TestCaseReference clipboardTest1 = - { (SDLTest_TestCaseFp)clipboard_testHasClipboardText, "clipboard_testHasClipboardText", "Check call to SDL_HasClipboardText", TEST_ENABLED }; - -static const SDLTest_TestCaseReference clipboardTest2 = - { (SDLTest_TestCaseFp)clipboard_testGetClipboardText, "clipboard_testGetClipboardText", "Check call to SDL_GetClipboardText", TEST_ENABLED }; - -static const SDLTest_TestCaseReference clipboardTest3 = - { (SDLTest_TestCaseFp)clipboard_testSetClipboardText, "clipboard_testSetClipboardText", "Check call to SDL_SetClipboardText", TEST_ENABLED }; - -static const SDLTest_TestCaseReference clipboardTest4 = - { (SDLTest_TestCaseFp)clipboard_testClipboardTextFunctions, "clipboard_testClipboardTextFunctions", "End-to-end test of SDL_xyzClipboardText functions", TEST_ENABLED }; - -/* Sequence of Clipboard test cases */ -static const SDLTest_TestCaseReference *clipboardTests[] = { - &clipboardTest1, &clipboardTest2, &clipboardTest3, &clipboardTest4, NULL -}; - -/* Clipboard test suite (global) */ -SDLTest_TestSuiteReference clipboardTestSuite = { - "Clipboard", - NULL, - clipboardTests, - NULL -}; diff --git a/SDL2-2.0.12/test/testautomation_events.c b/SDL2-2.0.12/test/testautomation_events.c deleted file mode 100644 index 09004da..0000000 --- a/SDL2-2.0.12/test/testautomation_events.c +++ /dev/null @@ -1,201 +0,0 @@ -/** - * Events test suite - */ - -#include - -#include "SDL.h" -#include "SDL_test.h" - -/* ================= Test Case Implementation ================== */ - -/* Test case functions */ - -/* Flag indicating if the userdata should be checked */ -int _userdataCheck = 0; - -/* Userdata value to check */ -int _userdataValue = 0; - -/* Flag indicating that the filter was called */ -int _eventFilterCalled = 0; - -/* Userdata values for event */ -int _userdataValue1 = 1; -int _userdataValue2 = 2; - -/* Event filter that sets some flags and optionally checks userdata */ -int SDLCALL _events_sampleNullEventFilter(void *userdata, SDL_Event *event) -{ - _eventFilterCalled = 1; - - if (_userdataCheck != 0) { - SDLTest_AssertCheck(userdata != NULL, "Check userdata pointer, expected: non-NULL, got: %s", (userdata != NULL) ? "non-NULL" : "NULL"); - if (userdata != NULL) { - SDLTest_AssertCheck(*(int *)userdata == _userdataValue, "Check userdata value, expected: %i, got: %i", _userdataValue, *(int *)userdata); - } - } - - return 0; -} - -/** - * @brief Test pumping and peeking events. - * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_PumpEvents - * @sa http://wiki.libsdl.org/moin.cgi/SDL_PollEvent - */ -int -events_pushPumpAndPollUserevent(void *arg) -{ - SDL_Event event1; - SDL_Event event2; - int result; - - /* Create user event */ - event1.type = SDL_USEREVENT; - event1.user.code = SDLTest_RandomSint32(); - event1.user.data1 = (void *)&_userdataValue1; - event1.user.data2 = (void *)&_userdataValue2; - - /* Push a user event onto the queue and force queue update */ - SDL_PushEvent(&event1); - SDLTest_AssertPass("Call to SDL_PushEvent()"); - SDL_PumpEvents(); - SDLTest_AssertPass("Call to SDL_PumpEvents()"); - - /* Poll for user event */ - result = SDL_PollEvent(&event2); - SDLTest_AssertPass("Call to SDL_PollEvent()"); - SDLTest_AssertCheck(result == 1, "Check result from SDL_PollEvent, expected: 1, got: %d", result); - - return TEST_COMPLETED; -} - - -/** - * @brief Adds and deletes an event watch function with NULL userdata - * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_AddEventWatch - * @sa http://wiki.libsdl.org/moin.cgi/SDL_DelEventWatch - * - */ -int -events_addDelEventWatch(void *arg) -{ - SDL_Event event; - - /* Create user event */ - event.type = SDL_USEREVENT; - event.user.code = SDLTest_RandomSint32(); - event.user.data1 = (void *)&_userdataValue1; - event.user.data2 = (void *)&_userdataValue2; - - /* Disable userdata check */ - _userdataCheck = 0; - - /* Reset event filter call tracker */ - _eventFilterCalled = 0; - - /* Add watch */ - SDL_AddEventWatch(_events_sampleNullEventFilter, NULL); - SDLTest_AssertPass("Call to SDL_AddEventWatch()"); - - /* Push a user event onto the queue and force queue update */ - SDL_PushEvent(&event); - SDLTest_AssertPass("Call to SDL_PushEvent()"); - SDL_PumpEvents(); - SDLTest_AssertPass("Call to SDL_PumpEvents()"); - SDLTest_AssertCheck(_eventFilterCalled == 1, "Check that event filter was called"); - - /* Delete watch */ - SDL_DelEventWatch(_events_sampleNullEventFilter, NULL); - SDLTest_AssertPass("Call to SDL_DelEventWatch()"); - - /* Push a user event onto the queue and force queue update */ - _eventFilterCalled = 0; - SDL_PushEvent(&event); - SDLTest_AssertPass("Call to SDL_PushEvent()"); - SDL_PumpEvents(); - SDLTest_AssertPass("Call to SDL_PumpEvents()"); - SDLTest_AssertCheck(_eventFilterCalled == 0, "Check that event filter was NOT called"); - - return TEST_COMPLETED; -} - -/** - * @brief Adds and deletes an event watch function with userdata - * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_AddEventWatch - * @sa http://wiki.libsdl.org/moin.cgi/SDL_DelEventWatch - * - */ -int -events_addDelEventWatchWithUserdata(void *arg) -{ - SDL_Event event; - - /* Create user event */ - event.type = SDL_USEREVENT; - event.user.code = SDLTest_RandomSint32(); - event.user.data1 = (void *)&_userdataValue1; - event.user.data2 = (void *)&_userdataValue2; - - /* Enable userdata check and set a value to check */ - _userdataCheck = 1; - _userdataValue = SDLTest_RandomIntegerInRange(-1024, 1024); - - /* Reset event filter call tracker */ - _eventFilterCalled = 0; - - /* Add watch */ - SDL_AddEventWatch(_events_sampleNullEventFilter, (void *)&_userdataValue); - SDLTest_AssertPass("Call to SDL_AddEventWatch()"); - - /* Push a user event onto the queue and force queue update */ - SDL_PushEvent(&event); - SDLTest_AssertPass("Call to SDL_PushEvent()"); - SDL_PumpEvents(); - SDLTest_AssertPass("Call to SDL_PumpEvents()"); - SDLTest_AssertCheck(_eventFilterCalled == 1, "Check that event filter was called"); - - /* Delete watch */ - SDL_DelEventWatch(_events_sampleNullEventFilter, (void *)&_userdataValue); - SDLTest_AssertPass("Call to SDL_DelEventWatch()"); - - /* Push a user event onto the queue and force queue update */ - _eventFilterCalled = 0; - SDL_PushEvent(&event); - SDLTest_AssertPass("Call to SDL_PushEvent()"); - SDL_PumpEvents(); - SDLTest_AssertPass("Call to SDL_PumpEvents()"); - SDLTest_AssertCheck(_eventFilterCalled == 0, "Check that event filter was NOT called"); - - return TEST_COMPLETED; -} - - -/* ================= Test References ================== */ - -/* Events test cases */ -static const SDLTest_TestCaseReference eventsTest1 = - { (SDLTest_TestCaseFp)events_pushPumpAndPollUserevent, "events_pushPumpAndPollUserevent", "Pushes, pumps and polls a user event", TEST_ENABLED }; - -static const SDLTest_TestCaseReference eventsTest2 = - { (SDLTest_TestCaseFp)events_addDelEventWatch, "events_addDelEventWatch", "Adds and deletes an event watch function with NULL userdata", TEST_ENABLED }; - -static const SDLTest_TestCaseReference eventsTest3 = - { (SDLTest_TestCaseFp)events_addDelEventWatchWithUserdata, "events_addDelEventWatchWithUserdata", "Adds and deletes an event watch function with userdata", TEST_ENABLED }; - -/* Sequence of Events test cases */ -static const SDLTest_TestCaseReference *eventsTests[] = { - &eventsTest1, &eventsTest2, &eventsTest3, NULL -}; - -/* Events test suite (global) */ -SDLTest_TestSuiteReference eventsTestSuite = { - "Events", - NULL, - eventsTests, - NULL -}; diff --git a/SDL2-2.0.12/test/testautomation_hints.c b/SDL2-2.0.12/test/testautomation_hints.c deleted file mode 100644 index a6beb88..0000000 --- a/SDL2-2.0.12/test/testautomation_hints.c +++ /dev/null @@ -1,168 +0,0 @@ -/** - * Hints test suite - */ - -#include - -#include "SDL.h" -#include "SDL_test.h" - - -const int _numHintsEnum = 25; -char* _HintsEnum[] = - { - SDL_HINT_ACCELEROMETER_AS_JOYSTICK, - SDL_HINT_FRAMEBUFFER_ACCELERATION, - SDL_HINT_GAMECONTROLLERCONFIG, - SDL_HINT_GRAB_KEYBOARD, - SDL_HINT_IDLE_TIMER_DISABLED, - SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, - SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK, - SDL_HINT_MOUSE_RELATIVE_MODE_WARP, - SDL_HINT_ORIENTATIONS, - SDL_HINT_RENDER_DIRECT3D_THREADSAFE, - SDL_HINT_RENDER_DRIVER, - SDL_HINT_RENDER_OPENGL_SHADERS, - SDL_HINT_RENDER_SCALE_QUALITY, - SDL_HINT_RENDER_VSYNC, - SDL_HINT_TIMER_RESOLUTION, - SDL_HINT_VIDEO_ALLOW_SCREENSAVER, - SDL_HINT_VIDEO_HIGHDPI_DISABLED, - SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES, - SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, - SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT, - SDL_HINT_VIDEO_WIN_D3DCOMPILER, - SDL_HINT_VIDEO_X11_XINERAMA, - SDL_HINT_VIDEO_X11_XRANDR, - SDL_HINT_VIDEO_X11_XVIDMODE, - SDL_HINT_XINPUT_ENABLED, - }; -char* _HintsVerbose[] = - { - "SDL_HINT_ACCELEROMETER_AS_JOYSTICK", - "SDL_HINT_FRAMEBUFFER_ACCELERATION", - "SDL_HINT_GAMECONTROLLERCONFIG", - "SDL_HINT_GRAB_KEYBOARD", - "SDL_HINT_IDLE_TIMER_DISABLED", - "SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS", - "SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK", - "SDL_HINT_MOUSE_RELATIVE_MODE_WARP", - "SDL_HINT_ORIENTATIONS", - "SDL_HINT_RENDER_DIRECT3D_THREADSAFE", - "SDL_HINT_RENDER_DRIVER", - "SDL_HINT_RENDER_OPENGL_SHADERS", - "SDL_HINT_RENDER_SCALE_QUALITY", - "SDL_HINT_RENDER_VSYNC", - "SDL_HINT_TIMER_RESOLUTION", - "SDL_HINT_VIDEO_ALLOW_SCREENSAVER", - "SDL_HINT_VIDEO_HIGHDPI_DISABLED", - "SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES", - "SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS", - "SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT", - "SDL_HINT_VIDEO_WIN_D3DCOMPILER", - "SDL_HINT_VIDEO_X11_XINERAMA", - "SDL_HINT_VIDEO_X11_XRANDR", - "SDL_HINT_VIDEO_X11_XVIDMODE", - "SDL_HINT_XINPUT_ENABLED" - }; - - -/* Test case functions */ - -/** - * @brief Call to SDL_GetHint - */ -int -hints_getHint(void *arg) -{ - char *result1; - char *result2; - int i; - - for (i=0; i<_numHintsEnum; i++) { - result1 = (char *)SDL_GetHint((char*)_HintsEnum[i]); - SDLTest_AssertPass("Call to SDL_GetHint(%s) - using define definition", (char*)_HintsEnum[i]); - result2 = (char *)SDL_GetHint((char *)_HintsVerbose[i]); - SDLTest_AssertPass("Call to SDL_GetHint(%s) - using string definition", (char*)_HintsVerbose[i]); - SDLTest_AssertCheck( - (result1 == NULL && result2 == NULL) || (SDL_strcmp(result1, result2) == 0), - "Verify returned values are equal; got: result1='%s' result2='%s", - (result1 == NULL) ? "null" : result1, - (result2 == NULL) ? "null" : result2); - } - - return TEST_COMPLETED; -} - -/** - * @brief Call to SDL_SetHint - */ -int -hints_setHint(void *arg) -{ - char *originalValue; - char *value; - char *testValue; - SDL_bool result; - int i, j; - - /* Create random values to set */ - value = SDLTest_RandomAsciiStringOfSize(10); - - for (i=0; i<_numHintsEnum; i++) { - /* Capture current value */ - originalValue = (char *)SDL_GetHint((char*)_HintsEnum[i]); - SDLTest_AssertPass("Call to SDL_GetHint(%s)", (char*)_HintsEnum[i]); - - /* Set value (twice) */ - for (j=1; j<=2; j++) { - result = SDL_SetHint((char*)_HintsEnum[i], value); - SDLTest_AssertPass("Call to SDL_SetHint(%s, %s) (iteration %i)", (char*)_HintsEnum[i], value, j); - SDLTest_AssertCheck( - result == SDL_TRUE || result == SDL_FALSE, - "Verify valid result was returned, got: %i", - (int)result); - testValue = (char *)SDL_GetHint((char*)_HintsEnum[i]); - SDLTest_AssertPass("Call to SDL_GetHint(%s) - using string definition", (char*)_HintsVerbose[i]); - SDLTest_AssertCheck( - (SDL_strcmp(value, testValue) == 0), - "Verify returned value equals set value; got: testValue='%s' value='%s", - (testValue == NULL) ? "null" : testValue, - value); - } - - /* Reset original value */ - result = SDL_SetHint((char*)_HintsEnum[i], originalValue); - SDLTest_AssertPass("Call to SDL_SetHint(%s, originalValue)", (char*)_HintsEnum[i]); - SDLTest_AssertCheck( - result == SDL_TRUE || result == SDL_FALSE, - "Verify valid result was returned, got: %i", - (int)result); - } - - SDL_free(value); - - return TEST_COMPLETED; -} - -/* ================= Test References ================== */ - -/* Hints test cases */ -static const SDLTest_TestCaseReference hintsTest1 = - { (SDLTest_TestCaseFp)hints_getHint, "hints_getHint", "Call to SDL_GetHint", TEST_ENABLED }; - -static const SDLTest_TestCaseReference hintsTest2 = - { (SDLTest_TestCaseFp)hints_setHint, "hints_setHint", "Call to SDL_SetHint", TEST_ENABLED }; - -/* Sequence of Hints test cases */ -static const SDLTest_TestCaseReference *hintsTests[] = { - &hintsTest1, &hintsTest2, NULL -}; - -/* Hints test suite (global) */ -SDLTest_TestSuiteReference hintsTestSuite = { - "Hints", - NULL, - hintsTests, - NULL -}; diff --git a/SDL2-2.0.12/test/testautomation_keyboard.c b/SDL2-2.0.12/test/testautomation_keyboard.c deleted file mode 100644 index 6f25bb7..0000000 --- a/SDL2-2.0.12/test/testautomation_keyboard.c +++ /dev/null @@ -1,713 +0,0 @@ -/** - * Keyboard test suite - */ - -#include -#include - -#include "SDL_config.h" -#include "SDL.h" -#include "SDL_test.h" - -/* ================= Test Case Implementation ================== */ - -/* Test case functions */ - -/** - * @brief Check call to SDL_GetKeyboardState with and without numkeys reference. - * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_GetKeyboardState - */ -int -keyboard_getKeyboardState(void *arg) -{ - int numkeys; - Uint8 *state; - - /* Case where numkeys pointer is NULL */ - state = (Uint8 *)SDL_GetKeyboardState(NULL); - SDLTest_AssertPass("Call to SDL_GetKeyboardState(NULL)"); - SDLTest_AssertCheck(state != NULL, "Validate that return value from SDL_GetKeyboardState is not NULL"); - - /* Case where numkeys pointer is not NULL */ - numkeys = -1; - state = (Uint8 *)SDL_GetKeyboardState(&numkeys); - SDLTest_AssertPass("Call to SDL_GetKeyboardState(&numkeys)"); - SDLTest_AssertCheck(state != NULL, "Validate that return value from SDL_GetKeyboardState is not NULL"); - SDLTest_AssertCheck(numkeys >= 0, "Validate that value of numkeys is >= 0, got: %i", numkeys); - - return TEST_COMPLETED; -} - -/** - * @brief Check call to SDL_GetKeyboardFocus - * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_GetKeyboardFocus - */ -int -keyboard_getKeyboardFocus(void *arg) -{ - SDL_Window* window; - - /* Call, but ignore return value */ - window = SDL_GetKeyboardFocus(); - SDLTest_AssertPass("Call to SDL_GetKeyboardFocus()"); - - return TEST_COMPLETED; -} - -/** - * @brief Check call to SDL_GetKeyFromName for known, unknown and invalid name. - * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_GetKeyFromName - */ -int -keyboard_getKeyFromName(void *arg) -{ - SDL_Keycode result; - - /* Case where Key is known, 1 character input */ - result = SDL_GetKeyFromName("A"); - SDLTest_AssertPass("Call to SDL_GetKeyFromName(known/single)"); - SDLTest_AssertCheck(result == SDLK_a, "Verify result from call, expected: %i, got: %i", SDLK_a, result); - - /* Case where Key is known, 2 character input */ - result = SDL_GetKeyFromName("F1"); - SDLTest_AssertPass("Call to SDL_GetKeyFromName(known/double)"); - SDLTest_AssertCheck(result == SDLK_F1, "Verify result from call, expected: %i, got: %i", SDLK_F1, result); - - /* Case where Key is known, 3 character input */ - result = SDL_GetKeyFromName("End"); - SDLTest_AssertPass("Call to SDL_GetKeyFromName(known/triple)"); - SDLTest_AssertCheck(result == SDLK_END, "Verify result from call, expected: %i, got: %i", SDLK_END, result); - - /* Case where Key is known, 4 character input */ - result = SDL_GetKeyFromName("Find"); - SDLTest_AssertPass("Call to SDL_GetKeyFromName(known/quad)"); - SDLTest_AssertCheck(result == SDLK_FIND, "Verify result from call, expected: %i, got: %i", SDLK_FIND, result); - - /* Case where Key is known, multiple character input */ - result = SDL_GetKeyFromName("AudioStop"); - SDLTest_AssertPass("Call to SDL_GetKeyFromName(known/multi)"); - SDLTest_AssertCheck(result == SDLK_AUDIOSTOP, "Verify result from call, expected: %i, got: %i", SDLK_AUDIOSTOP, result); - - /* Case where Key is unknown */ - result = SDL_GetKeyFromName("NotThere"); - SDLTest_AssertPass("Call to SDL_GetKeyFromName(unknown)"); - SDLTest_AssertCheck(result == SDLK_UNKNOWN, "Verify result from call is UNKNOWN, expected: %i, got: %i", SDLK_UNKNOWN, result); - - /* Case where input is NULL/invalid */ - result = SDL_GetKeyFromName(NULL); - SDLTest_AssertPass("Call to SDL_GetKeyFromName(NULL)"); - SDLTest_AssertCheck(result == SDLK_UNKNOWN, "Verify result from call is UNKNOWN, expected: %i, got: %i", SDLK_UNKNOWN, result); - - return TEST_COMPLETED; -} - -/* - * Local helper to check for the invalid scancode error message - */ -void -_checkInvalidScancodeError() -{ - const char *expectedError = "Parameter 'scancode' is invalid"; - const char *error; - error = SDL_GetError(); - SDLTest_AssertPass("Call to SDL_GetError()"); - SDLTest_AssertCheck(error != NULL, "Validate that error message was not NULL"); - if (error != NULL) { - SDLTest_AssertCheck(SDL_strcmp(error, expectedError) == 0, - "Validate error message, expected: '%s', got: '%s'", expectedError, error); - SDL_ClearError(); - SDLTest_AssertPass("Call to SDL_ClearError()"); - } -} - -/** - * @brief Check call to SDL_GetKeyFromScancode - * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_GetKeyFromScancode - */ -int -keyboard_getKeyFromScancode(void *arg) -{ - SDL_Keycode result; - - /* Case where input is valid */ - result = SDL_GetKeyFromScancode(SDL_SCANCODE_A); - SDLTest_AssertPass("Call to SDL_GetKeyFromScancode(valid)"); - SDLTest_AssertCheck(result == SDLK_a, "Verify result from call, expected: %i, got: %i", SDLK_a, result); - - /* Case where input is zero */ - result = SDL_GetKeyFromScancode(0); - SDLTest_AssertPass("Call to SDL_GetKeyFromScancode(0)"); - SDLTest_AssertCheck(result == SDLK_UNKNOWN, "Verify result from call is UNKNOWN, expected: %i, got: %i", SDLK_UNKNOWN, result); - - /* Clear error message */ - SDL_ClearError(); - SDLTest_AssertPass("Call to SDL_ClearError()"); - - /* Case where input is invalid (too small) */ - result = SDL_GetKeyFromScancode(-999); - SDLTest_AssertPass("Call to SDL_GetKeyFromScancode(-999)"); - SDLTest_AssertCheck(result == SDLK_UNKNOWN, "Verify result from call is UNKNOWN, expected: %i, got: %i", SDLK_UNKNOWN, result); - _checkInvalidScancodeError(); - - /* Case where input is invalid (too big) */ - result = SDL_GetKeyFromScancode(999); - SDLTest_AssertPass("Call to SDL_GetKeyFromScancode(999)"); - SDLTest_AssertCheck(result == SDLK_UNKNOWN, "Verify result from call is UNKNOWN, expected: %i, got: %i", SDLK_UNKNOWN, result); - _checkInvalidScancodeError(); - - return TEST_COMPLETED; -} - -/** - * @brief Check call to SDL_GetKeyName - * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_GetKeyName - */ -int -keyboard_getKeyName(void *arg) -{ - char *result; - char *expected; - - /* Case where key has a 1 character name */ - expected = "3"; - result = (char *)SDL_GetKeyName(SDLK_3); - SDLTest_AssertPass("Call to SDL_GetKeyName()"); - SDLTest_AssertCheck(result != NULL, "Verify result from call is not NULL"); - SDLTest_AssertCheck(SDL_strcmp(result, expected) == 0, "Verify result from call is valid, expected: %s, got: %s", expected, result); - - /* Case where key has a 2 character name */ - expected = "F1"; - result = (char *)SDL_GetKeyName(SDLK_F1); - SDLTest_AssertPass("Call to SDL_GetKeyName()"); - SDLTest_AssertCheck(result != NULL, "Verify result from call is not NULL"); - SDLTest_AssertCheck(SDL_strcmp(result, expected) == 0, "Verify result from call is valid, expected: %s, got: %s", expected, result); - - /* Case where key has a 3 character name */ - expected = "Cut"; - result = (char *)SDL_GetKeyName(SDLK_CUT); - SDLTest_AssertPass("Call to SDL_GetKeyName()"); - SDLTest_AssertCheck(result != NULL, "Verify result from call is not NULL"); - SDLTest_AssertCheck(SDL_strcmp(result, expected) == 0, "Verify result from call is valid, expected: %s, got: %s", expected, result); - - /* Case where key has a 4 character name */ - expected = "Down"; - result = (char *)SDL_GetKeyName(SDLK_DOWN); - SDLTest_AssertPass("Call to SDL_GetKeyName()"); - SDLTest_AssertCheck(result != NULL, "Verify result from call is not NULL"); - SDLTest_AssertCheck(SDL_strcmp(result, expected) == 0, "Verify result from call is valid, expected: %s, got: %s", expected, result); - - /* Case where key has a N character name */ - expected = "BrightnessUp"; - result = (char *)SDL_GetKeyName(SDLK_BRIGHTNESSUP); - SDLTest_AssertPass("Call to SDL_GetKeyName()"); - SDLTest_AssertCheck(result != NULL, "Verify result from call is not NULL"); - SDLTest_AssertCheck(SDL_strcmp(result, expected) == 0, "Verify result from call is valid, expected: %s, got: %s", expected, result); - - /* Case where key has a N character name with space */ - expected = "Keypad MemStore"; - result = (char *)SDL_GetKeyName(SDLK_KP_MEMSTORE); - SDLTest_AssertPass("Call to SDL_GetKeyName()"); - SDLTest_AssertCheck(result != NULL, "Verify result from call is not NULL"); - SDLTest_AssertCheck(SDL_strcmp(result, expected) == 0, "Verify result from call is valid, expected: %s, got: %s", expected, result); - - return TEST_COMPLETED; -} - -/** - * @brief SDL_GetScancodeName negative cases - * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_GetScancodeName - */ -int -keyboard_getScancodeNameNegative(void *arg) -{ - SDL_Scancode scancode; - char *result; - char *expected = ""; - - /* Clear error message */ - SDL_ClearError(); - SDLTest_AssertPass("Call to SDL_ClearError()"); - - /* Out-of-bounds scancode */ - scancode = (SDL_Scancode)SDL_NUM_SCANCODES; - result = (char *)SDL_GetScancodeName(scancode); - SDLTest_AssertPass("Call to SDL_GetScancodeName(%d/large)", scancode); - SDLTest_AssertCheck(result != NULL, "Verify result from call is not NULL"); - SDLTest_AssertCheck(SDL_strcmp(result, expected) == 0, "Verify result from call is valid, expected: '%s', got: '%s'", expected, result); - _checkInvalidScancodeError(); - - return TEST_COMPLETED; -} - -/** - * @brief SDL_GetKeyName negative cases - * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_GetKeyName - */ -int -keyboard_getKeyNameNegative(void *arg) -{ - SDL_Keycode keycode; - char *result; - char *expected = ""; - - /* Unknown keycode */ - keycode = SDLK_UNKNOWN; - result = (char *)SDL_GetKeyName(keycode); - SDLTest_AssertPass("Call to SDL_GetKeyName(%d/unknown)", keycode); - SDLTest_AssertCheck(result != NULL, "Verify result from call is not NULL"); - SDLTest_AssertCheck(SDL_strcmp(result, expected) == 0, "Verify result from call is valid, expected: '%s', got: '%s'", expected, result); - - /* Clear error message */ - SDL_ClearError(); - SDLTest_AssertPass("Call to SDL_ClearError()"); - - /* Negative keycode */ - keycode = (SDL_Keycode)SDLTest_RandomIntegerInRange(-255, -1); - result = (char *)SDL_GetKeyName(keycode); - SDLTest_AssertPass("Call to SDL_GetKeyName(%d/negative)", keycode); - SDLTest_AssertCheck(result != NULL, "Verify result from call is not NULL"); - SDLTest_AssertCheck(SDL_strcmp(result, expected) == 0, "Verify result from call is valid, expected: '%s', got: '%s'", expected, result); - _checkInvalidScancodeError(); - - SDL_ClearError(); - SDLTest_AssertPass("Call to SDL_ClearError()"); - - return TEST_COMPLETED; -} - -/** - * @brief Check call to SDL_GetModState and SDL_SetModState - * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_GetModState - * @sa http://wiki.libsdl.org/moin.cgi/SDL_SetModState - */ -int -keyboard_getSetModState(void *arg) -{ - SDL_Keymod result; - SDL_Keymod currentState; - SDL_Keymod newState; - SDL_Keymod allStates = - KMOD_NONE | - KMOD_LSHIFT | - KMOD_RSHIFT | - KMOD_LCTRL | - KMOD_RCTRL | - KMOD_LALT | - KMOD_RALT | - KMOD_LGUI | - KMOD_RGUI | - KMOD_NUM | - KMOD_CAPS | - KMOD_MODE | - KMOD_RESERVED; - - /* Get state, cache for later reset */ - result = SDL_GetModState(); - SDLTest_AssertPass("Call to SDL_GetModState()"); - SDLTest_AssertCheck(/*result >= 0 &&*/ result <= allStates, "Verify result from call is valid, expected: 0 <= result <= %i, got: %i", allStates, result); - currentState = result; - - /* Set random state */ - newState = SDLTest_RandomIntegerInRange(0, allStates); - SDL_SetModState(newState); - SDLTest_AssertPass("Call to SDL_SetModState(%i)", newState); - result = SDL_GetModState(); - SDLTest_AssertPass("Call to SDL_GetModState()"); - SDLTest_AssertCheck(result == newState, "Verify result from call is valid, expected: %i, got: %i", newState, result); - - /* Set zero state */ - SDL_SetModState(0); - SDLTest_AssertPass("Call to SDL_SetModState(0)"); - result = SDL_GetModState(); - SDLTest_AssertPass("Call to SDL_GetModState()"); - SDLTest_AssertCheck(result == 0, "Verify result from call is valid, expected: 0, got: %i", result); - - /* Revert back to cached current state if needed */ - if (currentState != 0) { - SDL_SetModState(currentState); - SDLTest_AssertPass("Call to SDL_SetModState(%i)", currentState); - result = SDL_GetModState(); - SDLTest_AssertPass("Call to SDL_GetModState()"); - SDLTest_AssertCheck(result == currentState, "Verify result from call is valid, expected: %i, got: %i", currentState, result); - } - - return TEST_COMPLETED; -} - - -/** - * @brief Check call to SDL_StartTextInput and SDL_StopTextInput - * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_StartTextInput - * @sa http://wiki.libsdl.org/moin.cgi/SDL_StopTextInput - */ -int -keyboard_startStopTextInput(void *arg) -{ - /* Start-Stop */ - SDL_StartTextInput(); - SDLTest_AssertPass("Call to SDL_StartTextInput()"); - SDL_StopTextInput(); - SDLTest_AssertPass("Call to SDL_StopTextInput()"); - - /* Stop-Start */ - SDL_StartTextInput(); - SDLTest_AssertPass("Call to SDL_StartTextInput()"); - - /* Start-Start */ - SDL_StartTextInput(); - SDLTest_AssertPass("Call to SDL_StartTextInput()"); - - /* Stop-Stop */ - SDL_StopTextInput(); - SDLTest_AssertPass("Call to SDL_StopTextInput()"); - SDL_StopTextInput(); - SDLTest_AssertPass("Call to SDL_StopTextInput()"); - - return TEST_COMPLETED; -} - -/* Internal function to test SDL_SetTextInputRect */ -void _testSetTextInputRect(SDL_Rect refRect) -{ - SDL_Rect testRect; - - testRect = refRect; - SDL_SetTextInputRect(&testRect); - SDLTest_AssertPass("Call to SDL_SetTextInputRect with refRect(x:%i,y:%i,w:%i,h:%i)", refRect.x, refRect.y, refRect.w, refRect.h); - SDLTest_AssertCheck( - (refRect.x == testRect.x) && (refRect.y == testRect.y) && (refRect.w == testRect.w) && (refRect.h == testRect.h), - "Check that input data was not modified, expected: x:%i,y:%i,w:%i,h:%i, got: x:%i,y:%i,w:%i,h:%i", - refRect.x, refRect.y, refRect.w, refRect.h, - testRect.x, testRect.y, testRect.w, testRect.h); -} - -/** - * @brief Check call to SDL_SetTextInputRect - * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_SetTextInputRect - */ -int -keyboard_setTextInputRect(void *arg) -{ - SDL_Rect refRect; - - /* Normal visible refRect, origin inside */ - refRect.x = SDLTest_RandomIntegerInRange(1, 50); - refRect.y = SDLTest_RandomIntegerInRange(1, 50); - refRect.w = SDLTest_RandomIntegerInRange(10, 50); - refRect.h = SDLTest_RandomIntegerInRange(10, 50); - _testSetTextInputRect(refRect); - - /* Normal visible refRect, origin 0,0 */ - refRect.x = 0; - refRect.y = 0; - refRect.w = SDLTest_RandomIntegerInRange(10, 50); - refRect.h = SDLTest_RandomIntegerInRange(10, 50); - _testSetTextInputRect(refRect); - - /* 1Pixel refRect */ - refRect.x = SDLTest_RandomIntegerInRange(10, 50); - refRect.y = SDLTest_RandomIntegerInRange(10, 50); - refRect.w = 1; - refRect.h = 1; - _testSetTextInputRect(refRect); - - /* 0pixel refRect */ - refRect.x = 1; - refRect.y = 1; - refRect.w = 1; - refRect.h = 0; - _testSetTextInputRect(refRect); - - /* 0pixel refRect */ - refRect.x = 1; - refRect.y = 1; - refRect.w = 0; - refRect.h = 1; - _testSetTextInputRect(refRect); - - /* 0pixel refRect */ - refRect.x = 1; - refRect.y = 1; - refRect.w = 0; - refRect.h = 0; - _testSetTextInputRect(refRect); - - /* 0pixel refRect */ - refRect.x = 0; - refRect.y = 0; - refRect.w = 0; - refRect.h = 0; - _testSetTextInputRect(refRect); - - /* negative refRect */ - refRect.x = SDLTest_RandomIntegerInRange(-200, -100); - refRect.y = SDLTest_RandomIntegerInRange(-200, -100); - refRect.w = 50; - refRect.h = 50; - _testSetTextInputRect(refRect); - - /* oversized refRect */ - refRect.x = SDLTest_RandomIntegerInRange(1, 50); - refRect.y = SDLTest_RandomIntegerInRange(1, 50); - refRect.w = 5000; - refRect.h = 5000; - _testSetTextInputRect(refRect); - - /* NULL refRect */ - SDL_SetTextInputRect(NULL); - SDLTest_AssertPass("Call to SDL_SetTextInputRect(NULL)"); - - return TEST_COMPLETED; -} - -/** - * @brief Check call to SDL_SetTextInputRect with invalid data - * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_SetTextInputRect - */ -int -keyboard_setTextInputRectNegative(void *arg) -{ - /* Some platforms set also an error message; prepare for checking it */ -#if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_ANDROID || SDL_VIDEO_DRIVER_COCOA - const char *expectedError = "Parameter 'rect' is invalid"; - const char *error; - - SDL_ClearError(); - SDLTest_AssertPass("Call to SDL_ClearError()"); -#endif - - /* NULL refRect */ - SDL_SetTextInputRect(NULL); - SDLTest_AssertPass("Call to SDL_SetTextInputRect(NULL)"); - - /* Some platforms set also an error message; so check it */ -#if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_ANDROID || SDL_VIDEO_DRIVER_COCOA - error = SDL_GetError(); - SDLTest_AssertPass("Call to SDL_GetError()"); - SDLTest_AssertCheck(error != NULL, "Validate that error message was not NULL"); - if (error != NULL) { - SDLTest_AssertCheck(SDL_strcmp(error, expectedError) == 0, - "Validate error message, expected: '%s', got: '%s'", expectedError, error); - } - - SDL_ClearError(); - SDLTest_AssertPass("Call to SDL_ClearError()"); -#endif - - return TEST_COMPLETED; -} - -/** - * @brief Check call to SDL_GetScancodeFromKey - * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_GetScancodeFromKey - * @sa http://wiki.libsdl.org/moin.cgi/SDL_Keycode - */ -int -keyboard_getScancodeFromKey(void *arg) -{ - SDL_Scancode scancode; - - /* Regular key */ - scancode = SDL_GetScancodeFromKey(SDLK_4); - SDLTest_AssertPass("Call to SDL_GetScancodeFromKey(SDLK_4)"); - SDLTest_AssertCheck(scancode == SDL_SCANCODE_4, "Validate return value from SDL_GetScancodeFromKey, expected: %i, got: %i", SDL_SCANCODE_4, scancode); - - /* Virtual key */ - scancode = SDL_GetScancodeFromKey(SDLK_PLUS); - SDLTest_AssertPass("Call to SDL_GetScancodeFromKey(SDLK_PLUS)"); - SDLTest_AssertCheck(scancode == 0, "Validate return value from SDL_GetScancodeFromKey, expected: 0, got: %i", scancode); - - return TEST_COMPLETED; -} - -/** - * @brief Check call to SDL_GetScancodeFromName - * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_GetScancodeFromName - * @sa http://wiki.libsdl.org/moin.cgi/SDL_Keycode - */ -int -keyboard_getScancodeFromName(void *arg) -{ - SDL_Scancode scancode; - - /* Regular key, 1 character, first name in list */ - scancode = SDL_GetScancodeFromName("A"); - SDLTest_AssertPass("Call to SDL_GetScancodeFromName('A')"); - SDLTest_AssertCheck(scancode == SDL_SCANCODE_A, "Validate return value from SDL_GetScancodeFromName, expected: %i, got: %i", SDL_SCANCODE_A, scancode); - - /* Regular key, 1 character */ - scancode = SDL_GetScancodeFromName("4"); - SDLTest_AssertPass("Call to SDL_GetScancodeFromName('4')"); - SDLTest_AssertCheck(scancode == SDL_SCANCODE_4, "Validate return value from SDL_GetScancodeFromName, expected: %i, got: %i", SDL_SCANCODE_4, scancode); - - /* Regular key, 2 characters */ - scancode = SDL_GetScancodeFromName("F1"); - SDLTest_AssertPass("Call to SDL_GetScancodeFromName('F1')"); - SDLTest_AssertCheck(scancode == SDL_SCANCODE_F1, "Validate return value from SDL_GetScancodeFromName, expected: %i, got: %i", SDL_SCANCODE_F1, scancode); - - /* Regular key, 3 characters */ - scancode = SDL_GetScancodeFromName("End"); - SDLTest_AssertPass("Call to SDL_GetScancodeFromName('End')"); - SDLTest_AssertCheck(scancode == SDL_SCANCODE_END, "Validate return value from SDL_GetScancodeFromName, expected: %i, got: %i", SDL_SCANCODE_END, scancode); - - /* Regular key, 4 characters */ - scancode = SDL_GetScancodeFromName("Find"); - SDLTest_AssertPass("Call to SDL_GetScancodeFromName('Find')"); - SDLTest_AssertCheck(scancode == SDL_SCANCODE_FIND, "Validate return value from SDL_GetScancodeFromName, expected: %i, got: %i", SDL_SCANCODE_FIND, scancode); - - /* Regular key, several characters */ - scancode = SDL_GetScancodeFromName("Backspace"); - SDLTest_AssertPass("Call to SDL_GetScancodeFromName('Backspace')"); - SDLTest_AssertCheck(scancode == SDL_SCANCODE_BACKSPACE, "Validate return value from SDL_GetScancodeFromName, expected: %i, got: %i", SDL_SCANCODE_BACKSPACE, scancode); - - /* Regular key, several characters with space */ - scancode = SDL_GetScancodeFromName("Keypad Enter"); - SDLTest_AssertPass("Call to SDL_GetScancodeFromName('Keypad Enter')"); - SDLTest_AssertCheck(scancode == SDL_SCANCODE_KP_ENTER, "Validate return value from SDL_GetScancodeFromName, expected: %i, got: %i", SDL_SCANCODE_KP_ENTER, scancode); - - /* Regular key, last name in list */ - scancode = SDL_GetScancodeFromName("Sleep"); - SDLTest_AssertPass("Call to SDL_GetScancodeFromName('Sleep')"); - SDLTest_AssertCheck(scancode == SDL_SCANCODE_SLEEP, "Validate return value from SDL_GetScancodeFromName, expected: %i, got: %i", SDL_SCANCODE_SLEEP, scancode); - - return TEST_COMPLETED; -} - -/* - * Local helper to check for the invalid scancode error message - */ -void -_checkInvalidNameError() -{ - const char *expectedError = "Parameter 'name' is invalid"; - const char *error; - error = SDL_GetError(); - SDLTest_AssertPass("Call to SDL_GetError()"); - SDLTest_AssertCheck(error != NULL, "Validate that error message was not NULL"); - if (error != NULL) { - SDLTest_AssertCheck(SDL_strcmp(error, expectedError) == 0, - "Validate error message, expected: '%s', got: '%s'", expectedError, error); - SDL_ClearError(); - SDLTest_AssertPass("Call to SDL_ClearError()"); - } -} - -/** - * @brief Check call to SDL_GetScancodeFromName with invalid data - * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_GetScancodeFromName - * @sa http://wiki.libsdl.org/moin.cgi/SDL_Keycode - */ -int -keyboard_getScancodeFromNameNegative(void *arg) -{ - char *name; - SDL_Scancode scancode; - - /* Clear error message */ - SDL_ClearError(); - SDLTest_AssertPass("Call to SDL_ClearError()"); - - /* Random string input */ - name = SDLTest_RandomAsciiStringOfSize(32); - SDLTest_Assert(name != NULL, "Check that random name is not NULL"); - if (name == NULL) { - return TEST_ABORTED; - } - scancode = SDL_GetScancodeFromName((const char *)name); - SDLTest_AssertPass("Call to SDL_GetScancodeFromName('%s')", name); - SDL_free(name); - SDLTest_AssertCheck(scancode == SDL_SCANCODE_UNKNOWN, "Validate return value from SDL_GetScancodeFromName, expected: %i, got: %i", SDL_SCANCODE_UNKNOWN, scancode); - _checkInvalidNameError(); - - /* Zero length string input */ - name = ""; - scancode = SDL_GetScancodeFromName((const char *)name); - SDLTest_AssertPass("Call to SDL_GetScancodeFromName(NULL)"); - SDLTest_AssertCheck(scancode == SDL_SCANCODE_UNKNOWN, "Validate return value from SDL_GetScancodeFromName, expected: %i, got: %i", SDL_SCANCODE_UNKNOWN, scancode); - _checkInvalidNameError(); - - /* NULL input */ - name = NULL; - scancode = SDL_GetScancodeFromName((const char *)name); - SDLTest_AssertPass("Call to SDL_GetScancodeFromName(NULL)"); - SDLTest_AssertCheck(scancode == SDL_SCANCODE_UNKNOWN, "Validate return value from SDL_GetScancodeFromName, expected: %i, got: %i", SDL_SCANCODE_UNKNOWN, scancode); - _checkInvalidNameError(); - - return TEST_COMPLETED; -} - - - -/* ================= Test References ================== */ - -/* Keyboard test cases */ -static const SDLTest_TestCaseReference keyboardTest1 = - { (SDLTest_TestCaseFp)keyboard_getKeyboardState, "keyboard_getKeyboardState", "Check call to SDL_GetKeyboardState with and without numkeys reference", TEST_ENABLED }; - -static const SDLTest_TestCaseReference keyboardTest2 = - { (SDLTest_TestCaseFp)keyboard_getKeyboardFocus, "keyboard_getKeyboardFocus", "Check call to SDL_GetKeyboardFocus", TEST_ENABLED }; - -static const SDLTest_TestCaseReference keyboardTest3 = - { (SDLTest_TestCaseFp)keyboard_getKeyFromName, "keyboard_getKeyFromName", "Check call to SDL_GetKeyFromName for known, unknown and invalid name", TEST_ENABLED }; - -static const SDLTest_TestCaseReference keyboardTest4 = - { (SDLTest_TestCaseFp)keyboard_getKeyFromScancode, "keyboard_getKeyFromScancode", "Check call to SDL_GetKeyFromScancode", TEST_ENABLED }; - -static const SDLTest_TestCaseReference keyboardTest5 = - { (SDLTest_TestCaseFp)keyboard_getKeyName, "keyboard_getKeyName", "Check call to SDL_GetKeyName", TEST_ENABLED }; - -static const SDLTest_TestCaseReference keyboardTest6 = - { (SDLTest_TestCaseFp)keyboard_getSetModState, "keyboard_getSetModState", "Check call to SDL_GetModState and SDL_SetModState", TEST_ENABLED }; - -static const SDLTest_TestCaseReference keyboardTest7 = - { (SDLTest_TestCaseFp)keyboard_startStopTextInput, "keyboard_startStopTextInput", "Check call to SDL_StartTextInput and SDL_StopTextInput", TEST_ENABLED }; - -static const SDLTest_TestCaseReference keyboardTest8 = - { (SDLTest_TestCaseFp)keyboard_setTextInputRect, "keyboard_setTextInputRect", "Check call to SDL_SetTextInputRect", TEST_ENABLED }; - -static const SDLTest_TestCaseReference keyboardTest9 = - { (SDLTest_TestCaseFp)keyboard_setTextInputRectNegative, "keyboard_setTextInputRectNegative", "Check call to SDL_SetTextInputRect with invalid data", TEST_ENABLED }; - -static const SDLTest_TestCaseReference keyboardTest10 = - { (SDLTest_TestCaseFp)keyboard_getScancodeFromKey, "keyboard_getScancodeFromKey", "Check call to SDL_GetScancodeFromKey", TEST_ENABLED }; - -static const SDLTest_TestCaseReference keyboardTest11 = - { (SDLTest_TestCaseFp)keyboard_getScancodeFromName, "keyboard_getScancodeFromName", "Check call to SDL_GetScancodeFromName", TEST_ENABLED }; - -static const SDLTest_TestCaseReference keyboardTest12 = - { (SDLTest_TestCaseFp)keyboard_getScancodeFromNameNegative, "keyboard_getScancodeFromNameNegative", "Check call to SDL_GetScancodeFromName with invalid data", TEST_ENABLED }; - -static const SDLTest_TestCaseReference keyboardTest13 = - { (SDLTest_TestCaseFp)keyboard_getKeyNameNegative, "keyboard_getKeyNameNegative", "Check call to SDL_GetKeyName with invalid data", TEST_ENABLED }; - -static const SDLTest_TestCaseReference keyboardTest14 = - { (SDLTest_TestCaseFp)keyboard_getScancodeNameNegative, "keyboard_getScancodeNameNegative", "Check call to SDL_GetScancodeName with invalid data", TEST_ENABLED }; - -/* Sequence of Keyboard test cases */ -static const SDLTest_TestCaseReference *keyboardTests[] = { - &keyboardTest1, &keyboardTest2, &keyboardTest3, &keyboardTest4, &keyboardTest5, &keyboardTest6, - &keyboardTest7, &keyboardTest8, &keyboardTest9, &keyboardTest10, &keyboardTest11, &keyboardTest12, - &keyboardTest13, &keyboardTest14, NULL -}; - -/* Keyboard test suite (global) */ -SDLTest_TestSuiteReference keyboardTestSuite = { - "Keyboard", - NULL, - keyboardTests, - NULL -}; diff --git a/SDL2-2.0.12/test/testautomation_main.c b/SDL2-2.0.12/test/testautomation_main.c deleted file mode 100644 index ae060cd..0000000 --- a/SDL2-2.0.12/test/testautomation_main.c +++ /dev/null @@ -1,157 +0,0 @@ -/** - * Automated SDL subsystems management test. - * - * Written by J�rgen Tjern� "jorgenpt" - * - * Released under Public Domain. - */ - -#include "SDL.h" -#include "SDL_test.h" - - -/* ! - * \brief Tests SDL_Init() and SDL_Quit() of Joystick and Haptic subsystems - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_Init - * http://wiki.libsdl.org/moin.cgi/SDL_Quit - */ -static int main_testInitQuitJoystickHaptic (void *arg) -{ -#if defined SDL_JOYSTICK_DISABLED || defined SDL_HAPTIC_DISABLED - return TEST_SKIPPED; -#else - int enabled_subsystems; - int initialized_subsystems = SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC; - - SDLTest_AssertCheck( SDL_Init(initialized_subsystems) == 0, "SDL_Init multiple systems." ); - - enabled_subsystems = SDL_WasInit(initialized_subsystems); - SDLTest_AssertCheck( enabled_subsystems == initialized_subsystems, "SDL_WasInit(SDL_INIT_EVERYTHING) contains all systems (%i)", enabled_subsystems ); - - SDL_Quit(); - - enabled_subsystems = SDL_WasInit(initialized_subsystems); - SDLTest_AssertCheck( enabled_subsystems == 0, "SDL_Quit should shut down everything (%i)", enabled_subsystems ); - - return TEST_COMPLETED; -#endif -} - -/* ! - * \brief Tests SDL_InitSubSystem() and SDL_QuitSubSystem() - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_Init - * http://wiki.libsdl.org/moin.cgi/SDL_Quit - */ -static int main_testInitQuitSubSystem (void *arg) -{ -#if defined SDL_JOYSTICK_DISABLED || defined SDL_HAPTIC_DISABLED || defined SDL_GAMECONTROLLER_DISABLED - return TEST_SKIPPED; -#else - int i; - int subsystems[] = { SDL_INIT_JOYSTICK, SDL_INIT_HAPTIC, SDL_INIT_GAMECONTROLLER }; - - for (i = 0; i < SDL_arraysize(subsystems); ++i) { - int initialized_system; - int subsystem = subsystems[i]; - - SDLTest_AssertCheck( (SDL_WasInit(subsystem) & subsystem) == 0, "SDL_WasInit(%x) before init should be false", subsystem ); - SDLTest_AssertCheck( SDL_InitSubSystem(subsystem) == 0, "SDL_InitSubSystem(%x)", subsystem ); - - initialized_system = SDL_WasInit(subsystem); - SDLTest_AssertCheck( (initialized_system & subsystem) != 0, "SDL_WasInit(%x) should be true (%x)", subsystem, initialized_system ); - - SDL_QuitSubSystem(subsystem); - - SDLTest_AssertCheck( (SDL_WasInit(subsystem) & subsystem) == 0, "SDL_WasInit(%x) after shutdown should be false", subsystem ); - } - - return TEST_COMPLETED; -#endif -} - -const int joy_and_controller = SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER; -static int main_testImpliedJoystickInit (void *arg) -{ -#if defined SDL_JOYSTICK_DISABLED || defined SDL_GAMECONTROLLER_DISABLED - return TEST_SKIPPED; -#else - int initialized_system; - - /* First initialize the controller */ - SDLTest_AssertCheck( (SDL_WasInit(joy_and_controller) & joy_and_controller) == 0, "SDL_WasInit() before init should be false for joystick & controller" ); - SDLTest_AssertCheck( SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) == 0, "SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER)" ); - - /* Then make sure this implicitly initialized the joystick subsystem */ - initialized_system = SDL_WasInit(joy_and_controller); - SDLTest_AssertCheck( (initialized_system & joy_and_controller) == joy_and_controller, "SDL_WasInit() should be true for joystick & controller (%x)", initialized_system ); - - /* Then quit the controller, and make sure that implicitly also quits the */ - /* joystick subsystem */ - SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER); - initialized_system = SDL_WasInit(joy_and_controller); - SDLTest_AssertCheck( (initialized_system & joy_and_controller) == 0, "SDL_WasInit() should be false for joystick & controller (%x)", initialized_system ); - - return TEST_COMPLETED; -#endif -} - -static int main_testImpliedJoystickQuit (void *arg) -{ -#if defined SDL_JOYSTICK_DISABLED || defined SDL_GAMECONTROLLER_DISABLED - return TEST_SKIPPED; -#else - int initialized_system; - - /* First initialize the controller and the joystick (explicitly) */ - SDLTest_AssertCheck( (SDL_WasInit(joy_and_controller) & joy_and_controller) == 0, "SDL_WasInit() before init should be false for joystick & controller" ); - SDLTest_AssertCheck( SDL_InitSubSystem(SDL_INIT_JOYSTICK) == 0, "SDL_InitSubSystem(SDL_INIT_JOYSTICK)" ); - SDLTest_AssertCheck( SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) == 0, "SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER)" ); - - /* Then make sure they're both initialized properly */ - initialized_system = SDL_WasInit(joy_and_controller); - SDLTest_AssertCheck( (initialized_system & joy_and_controller) == joy_and_controller, "SDL_WasInit() should be true for joystick & controller (%x)", initialized_system ); - - /* Then quit the controller, and make sure that it does NOT quit the */ - /* explicitly initialized joystick subsystem. */ - SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER); - initialized_system = SDL_WasInit(joy_and_controller); - SDLTest_AssertCheck( (initialized_system & joy_and_controller) == SDL_INIT_JOYSTICK, "SDL_WasInit() should be false for joystick & controller (%x)", initialized_system ); - - SDL_QuitSubSystem(SDL_INIT_JOYSTICK); - - return TEST_COMPLETED; -#endif -} - -static const SDLTest_TestCaseReference mainTest1 = - { (SDLTest_TestCaseFp)main_testInitQuitJoystickHaptic, "main_testInitQuitJoystickHaptic", "Tests SDL_Init/Quit of Joystick and Haptic subsystem", TEST_ENABLED}; - -static const SDLTest_TestCaseReference mainTest2 = - { (SDLTest_TestCaseFp)main_testInitQuitSubSystem, "main_testInitQuitSubSystem", "Tests SDL_InitSubSystem/QuitSubSystem", TEST_ENABLED}; - -static const SDLTest_TestCaseReference mainTest3 = - { (SDLTest_TestCaseFp)main_testImpliedJoystickInit, "main_testImpliedJoystickInit", "Tests that init for gamecontroller properly implies joystick", TEST_ENABLED}; - -static const SDLTest_TestCaseReference mainTest4 = - { (SDLTest_TestCaseFp)main_testImpliedJoystickQuit, "main_testImpliedJoystickQuit", "Tests that quit for gamecontroller doesn't quit joystick if you inited it explicitly", TEST_ENABLED}; - -/* Sequence of Main test cases */ -static const SDLTest_TestCaseReference *mainTests[] = { - &mainTest1, - &mainTest2, - &mainTest3, - &mainTest4, - NULL -}; - -/* Main test suite (global) */ -SDLTest_TestSuiteReference mainTestSuite = { - "Main", - NULL, - mainTests, - NULL -}; - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/test/testautomation_mouse.c b/SDL2-2.0.12/test/testautomation_mouse.c deleted file mode 100644 index ed30f26..0000000 --- a/SDL2-2.0.12/test/testautomation_mouse.c +++ /dev/null @@ -1,606 +0,0 @@ -/** - * Mouse test suite - */ - -#include -#include - -#include "SDL.h" -#include "SDL_test.h" - -/* ================= Test Case Implementation ================== */ - -/* Test case functions */ - -/* Helper to evaluate state returned from SDL_GetMouseState */ -int _mouseStateCheck(Uint32 state) -{ - return (state == 0) || - (state == SDL_BUTTON(SDL_BUTTON_LEFT)) || - (state == SDL_BUTTON(SDL_BUTTON_MIDDLE)) || - (state == SDL_BUTTON(SDL_BUTTON_RIGHT)) || - (state == SDL_BUTTON(SDL_BUTTON_X1)) || - (state == SDL_BUTTON(SDL_BUTTON_X2)); -} - -/** - * @brief Check call to SDL_GetMouseState - * - */ -int -mouse_getMouseState(void *arg) -{ - int x; - int y; - Uint32 state; - - /* Pump some events to update mouse state */ - SDL_PumpEvents(); - SDLTest_AssertPass("Call to SDL_PumpEvents()"); - - /* Case where x, y pointer is NULL */ - state = SDL_GetMouseState(NULL, NULL); - SDLTest_AssertPass("Call to SDL_GetMouseState(NULL, NULL)"); - SDLTest_AssertCheck(_mouseStateCheck(state), "Validate state returned from function, got: %i", state); - - /* Case where x pointer is not NULL */ - x = INT_MIN; - state = SDL_GetMouseState(&x, NULL); - SDLTest_AssertPass("Call to SDL_GetMouseState(&x, NULL)"); - SDLTest_AssertCheck(x > INT_MIN, "Validate that value of x is > INT_MIN, got: %i", x); - SDLTest_AssertCheck(_mouseStateCheck(state), "Validate state returned from function, got: %i", state); - - /* Case where y pointer is not NULL */ - y = INT_MIN; - state = SDL_GetMouseState(NULL, &y); - SDLTest_AssertPass("Call to SDL_GetMouseState(NULL, &y)"); - SDLTest_AssertCheck(y > INT_MIN, "Validate that value of y is > INT_MIN, got: %i", y); - SDLTest_AssertCheck(_mouseStateCheck(state), "Validate state returned from function, got: %i", state); - - /* Case where x and y pointer is not NULL */ - x = INT_MIN; - y = INT_MIN; - state = SDL_GetMouseState(&x, &y); - SDLTest_AssertPass("Call to SDL_GetMouseState(&x, &y)"); - SDLTest_AssertCheck(x > INT_MIN, "Validate that value of x is > INT_MIN, got: %i", x); - SDLTest_AssertCheck(y > INT_MIN, "Validate that value of y is > INT_MIN, got: %i", y); - SDLTest_AssertCheck(_mouseStateCheck(state), "Validate state returned from function, got: %i", state); - - return TEST_COMPLETED; -} - -/** - * @brief Check call to SDL_GetRelativeMouseState - * - */ -int -mouse_getRelativeMouseState(void *arg) -{ - int x; - int y; - Uint32 state; - - /* Pump some events to update mouse state */ - SDL_PumpEvents(); - SDLTest_AssertPass("Call to SDL_PumpEvents()"); - - /* Case where x, y pointer is NULL */ - state = SDL_GetRelativeMouseState(NULL, NULL); - SDLTest_AssertPass("Call to SDL_GetRelativeMouseState(NULL, NULL)"); - SDLTest_AssertCheck(_mouseStateCheck(state), "Validate state returned from function, got: %i", state); - - /* Case where x pointer is not NULL */ - x = INT_MIN; - state = SDL_GetRelativeMouseState(&x, NULL); - SDLTest_AssertPass("Call to SDL_GetRelativeMouseState(&x, NULL)"); - SDLTest_AssertCheck(x > INT_MIN, "Validate that value of x is > INT_MIN, got: %i", x); - SDLTest_AssertCheck(_mouseStateCheck(state), "Validate state returned from function, got: %i", state); - - /* Case where y pointer is not NULL */ - y = INT_MIN; - state = SDL_GetRelativeMouseState(NULL, &y); - SDLTest_AssertPass("Call to SDL_GetRelativeMouseState(NULL, &y)"); - SDLTest_AssertCheck(y > INT_MIN, "Validate that value of y is > INT_MIN, got: %i", y); - SDLTest_AssertCheck(_mouseStateCheck(state), "Validate state returned from function, got: %i", state); - - /* Case where x and y pointer is not NULL */ - x = INT_MIN; - y = INT_MIN; - state = SDL_GetRelativeMouseState(&x, &y); - SDLTest_AssertPass("Call to SDL_GetRelativeMouseState(&x, &y)"); - SDLTest_AssertCheck(x > INT_MIN, "Validate that value of x is > INT_MIN, got: %i", x); - SDLTest_AssertCheck(y > INT_MIN, "Validate that value of y is > INT_MIN, got: %i", y); - SDLTest_AssertCheck(_mouseStateCheck(state), "Validate state returned from function, got: %i", state); - - return TEST_COMPLETED; -} - - -/* XPM definition of mouse Cursor */ -static const char *_mouseArrowData[] = { - /* pixels */ - "X ", - "XX ", - "X.X ", - "X..X ", - "X...X ", - "X....X ", - "X.....X ", - "X......X ", - "X.......X ", - "X........X ", - "X.....XXXXX ", - "X..X..X ", - "X.X X..X ", - "XX X..X ", - "X X..X ", - " X..X ", - " X..X ", - " X..X ", - " XX ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " " -}; - -/* Helper that creates a new mouse cursor from an XPM */ -static SDL_Cursor *_initArrowCursor(const char *image[]) -{ - SDL_Cursor *cursor; - int i, row, col; - Uint8 data[4*32]; - Uint8 mask[4*32]; - - i = -1; - for ( row=0; row<32; ++row ) { - for ( col=0; col<32; ++col ) { - if ( col % 8 ) { - data[i] <<= 1; - mask[i] <<= 1; - } else { - ++i; - data[i] = mask[i] = 0; - } - switch (image[row][col]) { - case 'X': - data[i] |= 0x01; - mask[i] |= 0x01; - break; - case '.': - mask[i] |= 0x01; - break; - case ' ': - break; - } - } - } - - cursor = SDL_CreateCursor(data, mask, 32, 32, 0, 0); - return cursor; -} - -/** - * @brief Check call to SDL_CreateCursor and SDL_FreeCursor - * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_CreateCursor - * @sa http://wiki.libsdl.org/moin.cgi/SDL_FreeCursor - */ -int -mouse_createFreeCursor(void *arg) -{ - SDL_Cursor *cursor; - - /* Create a cursor */ - cursor = _initArrowCursor(_mouseArrowData); - SDLTest_AssertPass("Call to SDL_CreateCursor()"); - SDLTest_AssertCheck(cursor != NULL, "Validate result from SDL_CreateCursor() is not NULL"); - if (cursor == NULL) { - return TEST_ABORTED; - } - - /* Free cursor again */ - SDL_FreeCursor(cursor); - SDLTest_AssertPass("Call to SDL_FreeCursor()"); - - return TEST_COMPLETED; -} - -/** - * @brief Check call to SDL_CreateColorCursor and SDL_FreeCursor - * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_CreateColorCursor - * @sa http://wiki.libsdl.org/moin.cgi/SDL_FreeCursor - */ -int -mouse_createFreeColorCursor(void *arg) -{ - SDL_Surface *face; - SDL_Cursor *cursor; - - /* Get sample surface */ - face = SDLTest_ImageFace(); - SDLTest_AssertCheck(face != NULL, "Validate sample input image is not NULL"); - if (face == NULL) return TEST_ABORTED; - - /* Create a color cursor from surface */ - cursor = SDL_CreateColorCursor(face, 0, 0); - SDLTest_AssertPass("Call to SDL_CreateColorCursor()"); - SDLTest_AssertCheck(cursor != NULL, "Validate result from SDL_CreateColorCursor() is not NULL"); - if (cursor == NULL) { - SDL_FreeSurface(face); - return TEST_ABORTED; - } - - /* Free cursor again */ - SDL_FreeCursor(cursor); - SDLTest_AssertPass("Call to SDL_FreeCursor()"); - - /* Clean up */ - SDL_FreeSurface(face); - - return TEST_COMPLETED; -} - -/* Helper that changes cursor visibility */ -void _changeCursorVisibility(int state) -{ - int oldState; - int newState; - int result; - - oldState = SDL_ShowCursor(SDL_QUERY); - SDLTest_AssertPass("Call to SDL_ShowCursor(SDL_QUERY)"); - - result = SDL_ShowCursor(state); - SDLTest_AssertPass("Call to SDL_ShowCursor(%s)", (state == SDL_ENABLE) ? "SDL_ENABLE" : "SDL_DISABLE"); - SDLTest_AssertCheck(result == oldState, "Validate result from SDL_ShowCursor(%s), expected: %i, got: %i", - (state == SDL_ENABLE) ? "SDL_ENABLE" : "SDL_DISABLE", oldState, result); - - newState = SDL_ShowCursor(SDL_QUERY); - SDLTest_AssertPass("Call to SDL_ShowCursor(SDL_QUERY)"); - SDLTest_AssertCheck(state == newState, "Validate new state, expected: %i, got: %i", - state, newState); -} - -/** - * @brief Check call to SDL_ShowCursor - * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_ShowCursor - */ -int -mouse_showCursor(void *arg) -{ - int currentState; - - /* Get current state */ - currentState = SDL_ShowCursor(SDL_QUERY); - SDLTest_AssertPass("Call to SDL_ShowCursor(SDL_QUERY)"); - SDLTest_AssertCheck(currentState == SDL_DISABLE || currentState == SDL_ENABLE, - "Validate result is %i or %i, got: %i", SDL_DISABLE, SDL_ENABLE, currentState); - if (currentState == SDL_DISABLE) { - /* Show the cursor, then hide it again */ - _changeCursorVisibility(SDL_ENABLE); - _changeCursorVisibility(SDL_DISABLE); - } else if (currentState == SDL_ENABLE) { - /* Hide the cursor, then show it again */ - _changeCursorVisibility(SDL_DISABLE); - _changeCursorVisibility(SDL_ENABLE); - } else { - return TEST_ABORTED; - } - - return TEST_COMPLETED; -} - -/** - * @brief Check call to SDL_SetCursor - * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_SetCursor - */ -int -mouse_setCursor(void *arg) -{ - SDL_Cursor *cursor; - - /* Create a cursor */ - cursor = _initArrowCursor(_mouseArrowData); - SDLTest_AssertPass("Call to SDL_CreateCursor()"); - SDLTest_AssertCheck(cursor != NULL, "Validate result from SDL_CreateCursor() is not NULL"); - if (cursor == NULL) { - return TEST_ABORTED; - } - - /* Set the arrow cursor */ - SDL_SetCursor(cursor); - SDLTest_AssertPass("Call to SDL_SetCursor(cursor)"); - - /* Force redraw */ - SDL_SetCursor(NULL); - SDLTest_AssertPass("Call to SDL_SetCursor(NULL)"); - - /* Free cursor again */ - SDL_FreeCursor(cursor); - SDLTest_AssertPass("Call to SDL_FreeCursor()"); - - return TEST_COMPLETED; -} - -/** - * @brief Check call to SDL_GetCursor - * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_GetCursor - */ -int -mouse_getCursor(void *arg) -{ - SDL_Cursor *cursor; - - /* Get current cursor */ - cursor = SDL_GetCursor(); - SDLTest_AssertPass("Call to SDL_GetCursor()"); - SDLTest_AssertCheck(cursor != NULL, "Validate result from SDL_GetCursor() is not NULL"); - - return TEST_COMPLETED; -} - -/** - * @brief Check call to SDL_GetRelativeMouseMode and SDL_SetRelativeMouseMode - * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_GetRelativeMouseMode - * @sa http://wiki.libsdl.org/moin.cgi/SDL_SetRelativeMouseMode - */ -int -mouse_getSetRelativeMouseMode(void *arg) -{ - int result; - int i; - SDL_bool initialState; - SDL_bool currentState; - - /* Capture original state so we can revert back to it later */ - initialState = SDL_GetRelativeMouseMode(); - SDLTest_AssertPass("Call to SDL_GetRelativeMouseMode()"); - - /* Repeat twice to check D->D transition */ - for (i=0; i<2; i++) { - /* Disable - should always be supported */ - result = SDL_SetRelativeMouseMode(SDL_FALSE); - SDLTest_AssertPass("Call to SDL_SetRelativeMouseMode(FALSE)"); - SDLTest_AssertCheck(result == 0, "Validate result value from SDL_SetRelativeMouseMode, expected: 0, got: %i", result); - currentState = SDL_GetRelativeMouseMode(); - SDLTest_AssertPass("Call to SDL_GetRelativeMouseMode()"); - SDLTest_AssertCheck(currentState == SDL_FALSE, "Validate current state is FALSE, got: %i", currentState); - } - - /* Repeat twice to check D->E->E transition */ - for (i=0; i<2; i++) { - /* Enable - may not be supported */ - result = SDL_SetRelativeMouseMode(SDL_TRUE); - SDLTest_AssertPass("Call to SDL_SetRelativeMouseMode(TRUE)"); - if (result != -1) { - SDLTest_AssertCheck(result == 0, "Validate result value from SDL_SetRelativeMouseMode, expected: 0, got: %i", result); - currentState = SDL_GetRelativeMouseMode(); - SDLTest_AssertPass("Call to SDL_GetRelativeMouseMode()"); - SDLTest_AssertCheck(currentState == SDL_TRUE, "Validate current state is TRUE, got: %i", currentState); - } - } - - /* Disable to check E->D transition */ - result = SDL_SetRelativeMouseMode(SDL_FALSE); - SDLTest_AssertPass("Call to SDL_SetRelativeMouseMode(FALSE)"); - SDLTest_AssertCheck(result == 0, "Validate result value from SDL_SetRelativeMouseMode, expected: 0, got: %i", result); - currentState = SDL_GetRelativeMouseMode(); - SDLTest_AssertPass("Call to SDL_GetRelativeMouseMode()"); - SDLTest_AssertCheck(currentState == SDL_FALSE, "Validate current state is FALSE, got: %i", currentState); - - /* Revert to original state - ignore result */ - result = SDL_SetRelativeMouseMode(initialState); - - return TEST_COMPLETED; -} - -#define MOUSE_TESTWINDOW_WIDTH 320 -#define MOUSE_TESTWINDOW_HEIGHT 200 - -/** - * Creates a test window - */ -SDL_Window *_createMouseSuiteTestWindow() -{ - int posX = 100, posY = 100, width = MOUSE_TESTWINDOW_WIDTH, height = MOUSE_TESTWINDOW_HEIGHT; - SDL_Window *window; - window = SDL_CreateWindow("mouse_createMouseSuiteTestWindow", posX, posY, width, height, 0); - SDLTest_AssertPass("SDL_CreateWindow()"); - SDLTest_AssertCheck(window != NULL, "Check SDL_CreateWindow result"); - return window; -} - -/* - * Destroy test window - */ -void _destroyMouseSuiteTestWindow(SDL_Window *window) -{ - if (window != NULL) { - SDL_DestroyWindow(window); - window = NULL; - SDLTest_AssertPass("SDL_DestroyWindow()"); - } -} - -/** - * @brief Check call to SDL_WarpMouseInWindow - * - * @sa http://wiki.libsdl.org/moin.cgi/SDL_WarpMouseInWindow - */ -int -mouse_warpMouseInWindow(void *arg) -{ - const int w = MOUSE_TESTWINDOW_WIDTH, h = MOUSE_TESTWINDOW_HEIGHT; - int numPositions = 6; - int xPositions[6]; - int yPositions[6]; - int x, y, i, j; - SDL_Window *window; - - xPositions[0] = -1; - xPositions[1] = 0; - xPositions[2] = 1; - xPositions[3] = w-1; - xPositions[4] = w; - xPositions[5] = w+1; - yPositions[0] = -1; - yPositions[1] = 0; - yPositions[2] = 1; - yPositions[3] = h-1; - yPositions[4] = h; - yPositions[5] = h+1; - /* Create test window */ - window = _createMouseSuiteTestWindow(); - if (window == NULL) return TEST_ABORTED; - - /* Mouse to random position inside window */ - x = SDLTest_RandomIntegerInRange(1, w-1); - y = SDLTest_RandomIntegerInRange(1, h-1); - SDL_WarpMouseInWindow(window, x, y); - SDLTest_AssertPass("SDL_WarpMouseInWindow(...,%i,%i)", x, y); - - /* Same position again */ - SDL_WarpMouseInWindow(window, x, y); - SDLTest_AssertPass("SDL_WarpMouseInWindow(...,%i,%i)", x, y); - - /* Mouse to various boundary positions */ - for (i=0; i - -#include "SDL.h" -#include "SDL_test.h" - -/* Test case functions */ - -/* Definition of all RGB formats used to test pixel conversions */ -const int _numRGBPixelFormats = 31; -Uint32 _RGBPixelFormats[] = - { - SDL_PIXELFORMAT_INDEX1LSB, - SDL_PIXELFORMAT_INDEX1MSB, - SDL_PIXELFORMAT_INDEX4LSB, - SDL_PIXELFORMAT_INDEX4MSB, - SDL_PIXELFORMAT_INDEX8, - SDL_PIXELFORMAT_RGB332, - SDL_PIXELFORMAT_RGB444, - SDL_PIXELFORMAT_BGR444, - SDL_PIXELFORMAT_RGB555, - SDL_PIXELFORMAT_BGR555, - SDL_PIXELFORMAT_ARGB4444, - SDL_PIXELFORMAT_RGBA4444, - SDL_PIXELFORMAT_ABGR4444, - SDL_PIXELFORMAT_BGRA4444, - SDL_PIXELFORMAT_ARGB1555, - SDL_PIXELFORMAT_RGBA5551, - SDL_PIXELFORMAT_ABGR1555, - SDL_PIXELFORMAT_BGRA5551, - SDL_PIXELFORMAT_RGB565, - SDL_PIXELFORMAT_BGR565, - SDL_PIXELFORMAT_RGB24, - SDL_PIXELFORMAT_BGR24, - SDL_PIXELFORMAT_RGB888, - SDL_PIXELFORMAT_RGBX8888, - SDL_PIXELFORMAT_BGR888, - SDL_PIXELFORMAT_BGRX8888, - SDL_PIXELFORMAT_ARGB8888, - SDL_PIXELFORMAT_RGBA8888, - SDL_PIXELFORMAT_ABGR8888, - SDL_PIXELFORMAT_BGRA8888, - SDL_PIXELFORMAT_ARGB2101010 - }; -char* _RGBPixelFormatsVerbose[] = - { - "SDL_PIXELFORMAT_INDEX1LSB", - "SDL_PIXELFORMAT_INDEX1MSB", - "SDL_PIXELFORMAT_INDEX4LSB", - "SDL_PIXELFORMAT_INDEX4MSB", - "SDL_PIXELFORMAT_INDEX8", - "SDL_PIXELFORMAT_RGB332", - "SDL_PIXELFORMAT_RGB444", - "SDL_PIXELFORMAT_BGR444", - "SDL_PIXELFORMAT_RGB555", - "SDL_PIXELFORMAT_BGR555", - "SDL_PIXELFORMAT_ARGB4444", - "SDL_PIXELFORMAT_RGBA4444", - "SDL_PIXELFORMAT_ABGR4444", - "SDL_PIXELFORMAT_BGRA4444", - "SDL_PIXELFORMAT_ARGB1555", - "SDL_PIXELFORMAT_RGBA5551", - "SDL_PIXELFORMAT_ABGR1555", - "SDL_PIXELFORMAT_BGRA5551", - "SDL_PIXELFORMAT_RGB565", - "SDL_PIXELFORMAT_BGR565", - "SDL_PIXELFORMAT_RGB24", - "SDL_PIXELFORMAT_BGR24", - "SDL_PIXELFORMAT_RGB888", - "SDL_PIXELFORMAT_RGBX8888", - "SDL_PIXELFORMAT_BGR888", - "SDL_PIXELFORMAT_BGRX8888", - "SDL_PIXELFORMAT_ARGB8888", - "SDL_PIXELFORMAT_RGBA8888", - "SDL_PIXELFORMAT_ABGR8888", - "SDL_PIXELFORMAT_BGRA8888", - "SDL_PIXELFORMAT_ARGB2101010" - }; - -/* Definition of all Non-RGB formats used to test pixel conversions */ -const int _numNonRGBPixelFormats = 7; -Uint32 _nonRGBPixelFormats[] = - { - SDL_PIXELFORMAT_YV12, - SDL_PIXELFORMAT_IYUV, - SDL_PIXELFORMAT_YUY2, - SDL_PIXELFORMAT_UYVY, - SDL_PIXELFORMAT_YVYU, - SDL_PIXELFORMAT_NV12, - SDL_PIXELFORMAT_NV21 - }; -char* _nonRGBPixelFormatsVerbose[] = - { - "SDL_PIXELFORMAT_YV12", - "SDL_PIXELFORMAT_IYUV", - "SDL_PIXELFORMAT_YUY2", - "SDL_PIXELFORMAT_UYVY", - "SDL_PIXELFORMAT_YVYU", - "SDL_PIXELFORMAT_NV12", - "SDL_PIXELFORMAT_NV21" - }; - -/* Definition of some invalid formats for negative tests */ -const int _numInvalidPixelFormats = 2; -Uint32 _invalidPixelFormats[] = - { - 0xfffffffe, - 0xffffffff - }; -char* _invalidPixelFormatsVerbose[] = - { - "SDL_PIXELFORMAT_UNKNOWN", - "SDL_PIXELFORMAT_UNKNOWN" - }; - -/* Test case functions */ - -/** - * @brief Call to SDL_AllocFormat and SDL_FreeFormat - * - * @sa http://wiki.libsdl.org/moin.fcg/SDL_AllocFormat - * @sa http://wiki.libsdl.org/moin.fcg/SDL_FreeFormat - */ -int -pixels_allocFreeFormat(void *arg) -{ - const char *unknownFormat = "SDL_PIXELFORMAT_UNKNOWN"; - const char *expectedError = "Parameter 'format' is invalid"; - const char *error; - int i; - Uint32 format; - Uint32 masks; - SDL_PixelFormat* result; - - /* Blank/unknown format */ - format = 0; - SDLTest_Log("RGB Format: %s (%u)", unknownFormat, format); - - /* Allocate format */ - result = SDL_AllocFormat(format); - SDLTest_AssertPass("Call to SDL_AllocFormat()"); - SDLTest_AssertCheck(result != NULL, "Verify result is not NULL"); - if (result != NULL) { - SDLTest_AssertCheck(result->format == format, "Verify value of result.format; expected: %u, got %u", format, result->format); - SDLTest_AssertCheck(result->BitsPerPixel == 0, "Verify value of result.BitsPerPixel; expected: 0, got %u", result->BitsPerPixel); - SDLTest_AssertCheck(result->BytesPerPixel == 0, "Verify value of result.BytesPerPixel; expected: 0, got %u", result->BytesPerPixel); - masks = result->Rmask | result->Gmask | result->Bmask | result->Amask; - SDLTest_AssertCheck(masks == 0, "Verify value of result.[RGBA]mask combined; expected: 0, got %u", masks); - - /* Deallocate again */ - SDL_FreeFormat(result); - SDLTest_AssertPass("Call to SDL_FreeFormat()"); - } - - /* RGB formats */ - for (i = 0; i < _numRGBPixelFormats; i++) { - format = _RGBPixelFormats[i]; - SDLTest_Log("RGB Format: %s (%u)", _RGBPixelFormatsVerbose[i], format); - - /* Allocate format */ - result = SDL_AllocFormat(format); - SDLTest_AssertPass("Call to SDL_AllocFormat()"); - SDLTest_AssertCheck(result != NULL, "Verify result is not NULL"); - if (result != NULL) { - SDLTest_AssertCheck(result->format == format, "Verify value of result.format; expected: %u, got %u", format, result->format); - SDLTest_AssertCheck(result->BitsPerPixel > 0, "Verify value of result.BitsPerPixel; expected: >0, got %u", result->BitsPerPixel); - SDLTest_AssertCheck(result->BytesPerPixel > 0, "Verify value of result.BytesPerPixel; expected: >0, got %u", result->BytesPerPixel); - if (result->palette != NULL) { - masks = result->Rmask | result->Gmask | result->Bmask | result->Amask; - SDLTest_AssertCheck(masks > 0, "Verify value of result.[RGBA]mask combined; expected: >0, got %u", masks); - } - - /* Deallocate again */ - SDL_FreeFormat(result); - SDLTest_AssertPass("Call to SDL_FreeFormat()"); - } - } - - /* Non-RGB formats */ - for (i = 0; i < _numNonRGBPixelFormats; i++) { - format = _nonRGBPixelFormats[i]; - SDLTest_Log("non-RGB Format: %s (%u)", _nonRGBPixelFormatsVerbose[i], format); - - /* Try to allocate format */ - result = SDL_AllocFormat(format); - SDLTest_AssertPass("Call to SDL_AllocFormat()"); - SDLTest_AssertCheck(result == NULL, "Verify result is NULL"); - } - - /* Negative cases */ - - /* Invalid Formats */ - for (i = 0; i < _numInvalidPixelFormats; i++) { - SDL_ClearError(); - SDLTest_AssertPass("Call to SDL_ClearError()"); - format = _invalidPixelFormats[i]; - result = SDL_AllocFormat(format); - SDLTest_AssertPass("Call to SDL_AllocFormat(%u)", format); - SDLTest_AssertCheck(result == NULL, "Verify result is NULL"); - error = SDL_GetError(); - SDLTest_AssertPass("Call to SDL_GetError()"); - SDLTest_AssertCheck(error != NULL, "Validate that error message was not NULL"); - if (error != NULL) { - SDLTest_AssertCheck(SDL_strcmp(error, expectedError) == 0, - "Validate error message, expected: '%s', got: '%s'", expectedError, error); - } - } - - /* Invalid free pointer */ - SDL_ClearError(); - SDLTest_AssertPass("Call to SDL_ClearError()"); - SDL_FreeFormat(NULL); - SDLTest_AssertPass("Call to SDL_FreeFormat(NULL)"); - error = SDL_GetError(); - SDLTest_AssertPass("Call to SDL_GetError()"); - SDLTest_AssertCheck(error != NULL, "Validate that error message was not NULL"); - if (error != NULL) { - SDLTest_AssertCheck(SDL_strcmp(error, expectedError) == 0, - "Validate error message, expected: '%s', got: '%s'", expectedError, error); - } - - return TEST_COMPLETED; -} - -/** - * @brief Call to SDL_GetPixelFormatName - * - * @sa http://wiki.libsdl.org/moin.fcg/SDL_GetPixelFormatName - */ -int -pixels_getPixelFormatName(void *arg) -{ - const char *unknownFormat = "SDL_PIXELFORMAT_UNKNOWN"; - const char *error; - int i; - Uint32 format; - char* result; - - /* Blank/undefined format */ - format = 0; - SDLTest_Log("RGB Format: %s (%u)", unknownFormat, format); - - /* Get name of format */ - result = (char *)SDL_GetPixelFormatName(format); - SDLTest_AssertPass("Call to SDL_GetPixelFormatName()"); - SDLTest_AssertCheck(result != NULL, "Verify result is not NULL"); - if (result != NULL) { - SDLTest_AssertCheck(result[0] != '\0', "Verify result is non-empty"); - SDLTest_AssertCheck(SDL_strcmp(result, unknownFormat) == 0, - "Verify result text; expected: %s, got %s", unknownFormat, result); - } - - /* RGB formats */ - for (i = 0; i < _numRGBPixelFormats; i++) { - format = _RGBPixelFormats[i]; - SDLTest_Log("RGB Format: %s (%u)", _RGBPixelFormatsVerbose[i], format); - - /* Get name of format */ - result = (char *)SDL_GetPixelFormatName(format); - SDLTest_AssertPass("Call to SDL_GetPixelFormatName()"); - SDLTest_AssertCheck(result != NULL, "Verify result is not NULL"); - if (result != NULL) { - SDLTest_AssertCheck(result[0] != '\0', "Verify result is non-empty"); - SDLTest_AssertCheck(SDL_strcmp(result, _RGBPixelFormatsVerbose[i]) == 0, - "Verify result text; expected: %s, got %s", _RGBPixelFormatsVerbose[i], result); - } - } - - /* Non-RGB formats */ - for (i = 0; i < _numNonRGBPixelFormats; i++) { - format = _nonRGBPixelFormats[i]; - SDLTest_Log("non-RGB Format: %s (%u)", _nonRGBPixelFormatsVerbose[i], format); - - /* Get name of format */ - result = (char *)SDL_GetPixelFormatName(format); - SDLTest_AssertPass("Call to SDL_GetPixelFormatName()"); - SDLTest_AssertCheck(result != NULL, "Verify result is not NULL"); - if (result != NULL) { - SDLTest_AssertCheck(result[0] != '\0', "Verify result is non-empty"); - SDLTest_AssertCheck(SDL_strcmp(result, _nonRGBPixelFormatsVerbose[i]) == 0, - "Verify result text; expected: %s, got %s", _nonRGBPixelFormatsVerbose[i], result); - } - } - - /* Negative cases */ - - /* Invalid Formats */ - SDL_ClearError(); - SDLTest_AssertPass("Call to SDL_ClearError()"); - for (i = 0; i < _numInvalidPixelFormats; i++) { - format = _invalidPixelFormats[i]; - result = (char *)SDL_GetPixelFormatName(format); - SDLTest_AssertPass("Call to SDL_GetPixelFormatName(%u)", format); - SDLTest_AssertCheck(result != NULL, "Verify result is not NULL"); - if (result != NULL) { - SDLTest_AssertCheck(result[0] != '\0', - "Verify result is non-empty; got: %s", result); - SDLTest_AssertCheck(SDL_strcmp(result, _invalidPixelFormatsVerbose[i]) == 0, - "Validate name is UNKNOWN, expected: '%s', got: '%s'", _invalidPixelFormatsVerbose[i], result); - } - error = SDL_GetError(); - SDLTest_AssertPass("Call to SDL_GetError()"); - SDLTest_AssertCheck(error == NULL || error[0] == '\0', "Validate that error message is empty"); - } - - return TEST_COMPLETED; -} - -/** - * @brief Call to SDL_AllocPalette and SDL_FreePalette - * - * @sa http://wiki.libsdl.org/moin.fcg/SDL_AllocPalette - * @sa http://wiki.libsdl.org/moin.fcg/SDL_FreePalette - */ -int -pixels_allocFreePalette(void *arg) -{ - const char *expectedError1 = "Parameter 'ncolors' is invalid"; - const char *expectedError2 = "Parameter 'palette' is invalid"; - const char *error; - int variation; - int i; - int ncolors; - SDL_Palette* result; - - /* Allocate palette */ - for (variation = 1; variation <= 3; variation++) { - switch (variation) { - /* Just one color */ - case 1: - ncolors = 1; - break; - /* Two colors */ - case 2: - ncolors = 2; - break; - /* More than two colors */ - case 3: - ncolors = SDLTest_RandomIntegerInRange(8, 16); - break; - } - - result = SDL_AllocPalette(ncolors); - SDLTest_AssertPass("Call to SDL_AllocPalette(%d)", ncolors); - SDLTest_AssertCheck(result != NULL, "Verify result is not NULL"); - if (result != NULL) { - SDLTest_AssertCheck(result->ncolors == ncolors, "Verify value of result.ncolors; expected: %u, got %u", ncolors, result->ncolors); - if (result->ncolors > 0) { - SDLTest_AssertCheck(result->colors != NULL, "Verify value of result.colors is not NULL"); - if (result->colors != NULL) { - for(i = 0; i < result->ncolors; i++) { - SDLTest_AssertCheck(result->colors[i].r == 255, "Verify value of result.colors[%d].r; expected: 255, got %u", i, result->colors[i].r); - SDLTest_AssertCheck(result->colors[i].g == 255, "Verify value of result.colors[%d].g; expected: 255, got %u", i, result->colors[i].g); - SDLTest_AssertCheck(result->colors[i].b == 255, "Verify value of result.colors[%d].b; expected: 255, got %u", i, result->colors[i].b); - } - } - } - - /* Deallocate again */ - SDL_FreePalette(result); - SDLTest_AssertPass("Call to SDL_FreePalette()"); - } - } - - /* Negative cases */ - - /* Invalid number of colors */ - for (ncolors = 0; ncolors > -3; ncolors--) { - SDL_ClearError(); - SDLTest_AssertPass("Call to SDL_ClearError()"); - result = SDL_AllocPalette(ncolors); - SDLTest_AssertPass("Call to SDL_AllocPalette(%d)", ncolors); - SDLTest_AssertCheck(result == NULL, "Verify result is NULL"); - error = SDL_GetError(); - SDLTest_AssertPass("Call to SDL_GetError()"); - SDLTest_AssertCheck(error != NULL, "Validate that error message was not NULL"); - if (error != NULL) { - SDLTest_AssertCheck(SDL_strcmp(error, expectedError1) == 0, - "Validate error message, expected: '%s', got: '%s'", expectedError1, error); - } - } - - /* Invalid free pointer */ - SDL_ClearError(); - SDLTest_AssertPass("Call to SDL_ClearError()"); - SDL_FreePalette(NULL); - SDLTest_AssertPass("Call to SDL_FreePalette(NULL)"); - error = SDL_GetError(); - SDLTest_AssertPass("Call to SDL_GetError()"); - SDLTest_AssertCheck(error != NULL, "Validate that error message was not NULL"); - if (error != NULL) { - SDLTest_AssertCheck(SDL_strcmp(error, expectedError2) == 0, - "Validate error message, expected: '%s', got: '%s'", expectedError2, error); - } - - return TEST_COMPLETED; -} - -/** - * @brief Call to SDL_CalculateGammaRamp - * - * @sa http://wiki.libsdl.org/moin.fcg/SDL_CalculateGammaRamp - */ -int -pixels_calcGammaRamp(void *arg) -{ - const char *expectedError1 = "Parameter 'gamma' is invalid"; - const char *expectedError2 = "Parameter 'ramp' is invalid"; - const char *error; - float gamma; - Uint16 *ramp; - int variation; - int i; - int changed; - Uint16 magic = 0xbeef; - - /* Allocate temp ramp array and fill with some value */ - ramp = (Uint16 *)SDL_malloc(256 * sizeof(Uint16)); - SDLTest_AssertCheck(ramp != NULL, "Validate temp ramp array could be allocated"); - if (ramp == NULL) return TEST_ABORTED; - - /* Make call with different gamma values */ - for (variation = 0; variation < 4; variation++) { - switch (variation) { - /* gamma = 0 all black */ - case 0: - gamma = 0.0f; - break; - /* gamma = 1 identity */ - case 1: - gamma = 1.0f; - break; - /* gamma = [0.2,0.8] normal range */ - case 2: - gamma = 0.2f + 0.8f * SDLTest_RandomUnitFloat(); - break; - /* gamma = >1.1 non-standard range */ - case 3: - gamma = 1.1f + SDLTest_RandomUnitFloat(); - break; - } - - /* Make call and check that values were updated */ - for (i = 0; i < 256; i++) ramp[i] = magic; - SDL_CalculateGammaRamp(gamma, ramp); - SDLTest_AssertPass("Call to SDL_CalculateGammaRamp(%f)", gamma); - changed = 0; - for (i = 0; i < 256; i++) if (ramp[i] != magic) changed++; - SDLTest_AssertCheck(changed > 250, "Validate that ramp was calculated; expected: >250 values changed, got: %d values changed", changed); - - /* Additional value checks for some cases */ - i = SDLTest_RandomIntegerInRange(64,192); - switch (variation) { - case 0: - SDLTest_AssertCheck(ramp[i] == 0, "Validate value at position %d; expected: 0, got: %d", i, ramp[i]); - break; - case 1: - SDLTest_AssertCheck(ramp[i] == ((i << 8) | i), "Validate value at position %d; expected: %d, got: %d", i, (i << 8) | i, ramp[i]); - break; - case 2: - case 3: - SDLTest_AssertCheck(ramp[i] > 0, "Validate value at position %d; expected: >0, got: %d", i, ramp[i]); - break; - } - } - - /* Negative cases */ - SDL_ClearError(); - SDLTest_AssertPass("Call to SDL_ClearError()"); - gamma = -1; - for (i=0; i<256; i++) ramp[i] = magic; - SDL_CalculateGammaRamp(gamma, ramp); - SDLTest_AssertPass("Call to SDL_CalculateGammaRamp(%f)", gamma); - error = SDL_GetError(); - SDLTest_AssertPass("Call to SDL_GetError()"); - SDLTest_AssertCheck(error != NULL, "Validate that error message was not NULL"); - if (error != NULL) { - SDLTest_AssertCheck(SDL_strcmp(error, expectedError1) == 0, - "Validate error message, expected: '%s', got: '%s'", expectedError1, error); - } - changed = 0; - for (i = 0; i < 256; i++) if (ramp[i] != magic) changed++; - SDLTest_AssertCheck(changed ==0, "Validate that ramp unchanged; expected: 0 values changed got: %d values changed", changed); - - SDL_CalculateGammaRamp(0.5f, NULL); - SDLTest_AssertPass("Call to SDL_CalculateGammaRamp(0.5,NULL)"); - error = SDL_GetError(); - SDLTest_AssertPass("Call to SDL_GetError()"); - SDLTest_AssertCheck(error != NULL, "Validate that error message was not NULL"); - if (error != NULL) { - SDLTest_AssertCheck(SDL_strcmp(error, expectedError2) == 0, - "Validate error message, expected: '%s', got: '%s'", expectedError2, error); - } - - /* Cleanup */ - SDL_free(ramp); - - - return TEST_COMPLETED; -} - -/* ================= Test References ================== */ - -/* Pixels test cases */ -static const SDLTest_TestCaseReference pixelsTest1 = - { (SDLTest_TestCaseFp)pixels_allocFreeFormat, "pixels_allocFreeFormat", "Call to SDL_AllocFormat and SDL_FreeFormat", TEST_ENABLED }; - -static const SDLTest_TestCaseReference pixelsTest2 = - { (SDLTest_TestCaseFp)pixels_allocFreePalette, "pixels_allocFreePalette", "Call to SDL_AllocPalette and SDL_FreePalette", TEST_ENABLED }; - -static const SDLTest_TestCaseReference pixelsTest3 = - { (SDLTest_TestCaseFp)pixels_calcGammaRamp, "pixels_calcGammaRamp", "Call to SDL_CalculateGammaRamp", TEST_ENABLED }; - -static const SDLTest_TestCaseReference pixelsTest4 = - { (SDLTest_TestCaseFp)pixels_getPixelFormatName, "pixels_getPixelFormatName", "Call to SDL_GetPixelFormatName", TEST_ENABLED }; - -/* Sequence of Pixels test cases */ -static const SDLTest_TestCaseReference *pixelsTests[] = { - &pixelsTest1, &pixelsTest2, &pixelsTest3, &pixelsTest4, NULL -}; - -/* Pixels test suite (global) */ -SDLTest_TestSuiteReference pixelsTestSuite = { - "Pixels", - NULL, - pixelsTests, - NULL -}; diff --git a/SDL2-2.0.12/test/testautomation_platform.c b/SDL2-2.0.12/test/testautomation_platform.c deleted file mode 100644 index 7cc732a..0000000 --- a/SDL2-2.0.12/test/testautomation_platform.c +++ /dev/null @@ -1,584 +0,0 @@ -/** - * Original code: automated SDL platform test written by Edgar Simo "bobbens" - * Extended and updated by aschiffler at ferzkopp dot net - */ - -#include - -#include "SDL.h" -#include "SDL_test.h" - -/* ================= Test Case Implementation ================== */ - -/* Helper functions */ - -/** - * @brief Compare sizes of types. - * - * @note Watcom C flags these as Warning 201: "Unreachable code" if you just - * compare them directly, so we push it through a function to keep the - * compiler quiet. --ryan. - */ -static int _compareSizeOfType( size_t sizeoftype, size_t hardcodetype ) -{ - return sizeoftype != hardcodetype; -} - -/* Test case functions */ - -/** - * @brief Tests type sizes. - */ -int platform_testTypes(void *arg) -{ - int ret; - - ret = _compareSizeOfType( sizeof(Uint8), 1 ); - SDLTest_AssertCheck( ret == 0, "sizeof(Uint8) = %lu, expected 1", (unsigned long)sizeof(Uint8) ); - - ret = _compareSizeOfType( sizeof(Uint16), 2 ); - SDLTest_AssertCheck( ret == 0, "sizeof(Uint16) = %lu, expected 2", (unsigned long)sizeof(Uint16) ); - - ret = _compareSizeOfType( sizeof(Uint32), 4 ); - SDLTest_AssertCheck( ret == 0, "sizeof(Uint32) = %lu, expected 4", (unsigned long)sizeof(Uint32) ); - - ret = _compareSizeOfType( sizeof(Uint64), 8 ); - SDLTest_AssertCheck( ret == 0, "sizeof(Uint64) = %lu, expected 8", (unsigned long)sizeof(Uint64) ); - - return TEST_COMPLETED; -} - -/** - * @brief Tests platform endianness and SDL_SwapXY functions. - */ -int platform_testEndianessAndSwap(void *arg) -{ - int real_byteorder; - Uint16 value = 0x1234; - Uint16 value16 = 0xCDAB; - Uint16 swapped16 = 0xABCD; - Uint32 value32 = 0xEFBEADDE; - Uint32 swapped32 = 0xDEADBEEF; - - Uint64 value64, swapped64; - value64 = 0xEFBEADDE; - value64 <<= 32; - value64 |= 0xCDAB3412; - swapped64 = 0x1234ABCD; - swapped64 <<= 32; - swapped64 |= 0xDEADBEEF; - - if ((*((char *) &value) >> 4) == 0x1) { - real_byteorder = SDL_BIG_ENDIAN; - } else { - real_byteorder = SDL_LIL_ENDIAN; - } - - /* Test endianness. */ - SDLTest_AssertCheck( real_byteorder == SDL_BYTEORDER, - "Machine detected as %s endian, appears to be %s endian.", - (SDL_BYTEORDER == SDL_LIL_ENDIAN) ? "little" : "big", - (real_byteorder == SDL_LIL_ENDIAN) ? "little" : "big" ); - - /* Test 16 swap. */ - SDLTest_AssertCheck( SDL_Swap16(value16) == swapped16, - "SDL_Swap16(): 16 bit swapped: 0x%X => 0x%X", - value16, SDL_Swap16(value16) ); - - /* Test 32 swap. */ - SDLTest_AssertCheck( SDL_Swap32(value32) == swapped32, - "SDL_Swap32(): 32 bit swapped: 0x%X => 0x%X", - value32, SDL_Swap32(value32) ); - - /* Test 64 swap. */ - SDLTest_AssertCheck( SDL_Swap64(value64) == swapped64, - "SDL_Swap64(): 64 bit swapped: 0x%"SDL_PRIX64" => 0x%"SDL_PRIX64, - value64, SDL_Swap64(value64) ); - - return TEST_COMPLETED; -} - -/* ! - * \brief Tests SDL_GetXYZ() functions - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_GetPlatform - * http://wiki.libsdl.org/moin.cgi/SDL_GetCPUCount - * http://wiki.libsdl.org/moin.cgi/SDL_GetCPUCacheLineSize - * http://wiki.libsdl.org/moin.cgi/SDL_GetRevision - * http://wiki.libsdl.org/moin.cgi/SDL_GetRevisionNumber - */ -int platform_testGetFunctions (void *arg) -{ - char *platform; - char *revision; - int ret; - size_t len; - - platform = (char *)SDL_GetPlatform(); - SDLTest_AssertPass("SDL_GetPlatform()"); - SDLTest_AssertCheck(platform != NULL, "SDL_GetPlatform() != NULL"); - if (platform != NULL) { - len = SDL_strlen(platform); - SDLTest_AssertCheck(len > 0, - "SDL_GetPlatform(): expected non-empty platform, was platform: '%s', len: %i", - platform, - (int) len); - } - - ret = SDL_GetCPUCount(); - SDLTest_AssertPass("SDL_GetCPUCount()"); - SDLTest_AssertCheck(ret > 0, - "SDL_GetCPUCount(): expected count > 0, was: %i", - ret); - - ret = SDL_GetCPUCacheLineSize(); - SDLTest_AssertPass("SDL_GetCPUCacheLineSize()"); - SDLTest_AssertCheck(ret >= 0, - "SDL_GetCPUCacheLineSize(): expected size >= 0, was: %i", - ret); - - revision = (char *)SDL_GetRevision(); - SDLTest_AssertPass("SDL_GetRevision()"); - SDLTest_AssertCheck(revision != NULL, "SDL_GetRevision() != NULL"); - - ret = SDL_GetRevisionNumber(); - SDLTest_AssertPass("SDL_GetRevisionNumber()"); - - return TEST_COMPLETED; -} - -/* ! - * \brief Tests SDL_HasXYZ() functions - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_Has3DNow - * http://wiki.libsdl.org/moin.cgi/SDL_HasAltiVec - * http://wiki.libsdl.org/moin.cgi/SDL_HasMMX - * http://wiki.libsdl.org/moin.cgi/SDL_HasRDTSC - * http://wiki.libsdl.org/moin.cgi/SDL_HasSSE - * http://wiki.libsdl.org/moin.cgi/SDL_HasSSE2 - * http://wiki.libsdl.org/moin.cgi/SDL_HasSSE3 - * http://wiki.libsdl.org/moin.cgi/SDL_HasSSE41 - * http://wiki.libsdl.org/moin.cgi/SDL_HasSSE42 - * http://wiki.libsdl.org/moin.cgi/SDL_HasAVX - */ -int platform_testHasFunctions (void *arg) -{ - int ret; - - /* TODO: independently determine and compare values as well */ - - ret = SDL_HasRDTSC(); - SDLTest_AssertPass("SDL_HasRDTSC()"); - - ret = SDL_HasAltiVec(); - SDLTest_AssertPass("SDL_HasAltiVec()"); - - ret = SDL_HasMMX(); - SDLTest_AssertPass("SDL_HasMMX()"); - - ret = SDL_Has3DNow(); - SDLTest_AssertPass("SDL_Has3DNow()"); - - ret = SDL_HasSSE(); - SDLTest_AssertPass("SDL_HasSSE()"); - - ret = SDL_HasSSE2(); - SDLTest_AssertPass("SDL_HasSSE2()"); - - ret = SDL_HasSSE3(); - SDLTest_AssertPass("SDL_HasSSE3()"); - - ret = SDL_HasSSE41(); - SDLTest_AssertPass("SDL_HasSSE41()"); - - ret = SDL_HasSSE42(); - SDLTest_AssertPass("SDL_HasSSE42()"); - - ret = SDL_HasAVX(); - SDLTest_AssertPass("SDL_HasAVX()"); - - return TEST_COMPLETED; -} - -/* ! - * \brief Tests SDL_GetVersion - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_GetVersion - */ -int platform_testGetVersion(void *arg) -{ - SDL_version linked; - int major = SDL_MAJOR_VERSION; - int minor = SDL_MINOR_VERSION; - - SDL_GetVersion(&linked); - SDLTest_AssertCheck( linked.major >= major, - "SDL_GetVersion(): returned major %i (>= %i)", - linked.major, - major); - SDLTest_AssertCheck( linked.minor >= minor, - "SDL_GetVersion(): returned minor %i (>= %i)", - linked.minor, - minor); - - return TEST_COMPLETED; -} - - -/* ! - * \brief Tests SDL_VERSION macro - */ -int platform_testSDLVersion(void *arg) -{ - SDL_version compiled; - int major = SDL_MAJOR_VERSION; - int minor = SDL_MINOR_VERSION; - - SDL_VERSION(&compiled); - SDLTest_AssertCheck( compiled.major >= major, - "SDL_VERSION() returned major %i (>= %i)", - compiled.major, - major); - SDLTest_AssertCheck( compiled.minor >= minor, - "SDL_VERSION() returned minor %i (>= %i)", - compiled.minor, - minor); - - return TEST_COMPLETED; -} - - -/* ! - * \brief Tests default SDL_Init - */ -int platform_testDefaultInit(void *arg) -{ - int ret; - int subsystem; - - subsystem = SDL_WasInit(SDL_INIT_EVERYTHING); - SDLTest_AssertCheck( subsystem != 0, - "SDL_WasInit(0): returned %i, expected != 0", - subsystem); - - ret = SDL_Init(SDL_WasInit(SDL_INIT_EVERYTHING)); - SDLTest_AssertCheck( ret == 0, - "SDL_Init(0): returned %i, expected 0, error: %s", - ret, - SDL_GetError()); - - return TEST_COMPLETED; -} - -/* ! - * \brief Tests SDL_Get/Set/ClearError - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_GetError - * http://wiki.libsdl.org/moin.cgi/SDL_SetError - * http://wiki.libsdl.org/moin.cgi/SDL_ClearError - */ -int platform_testGetSetClearError(void *arg) -{ - int result; - const char *testError = "Testing"; - char *lastError; - size_t len; - - SDL_ClearError(); - SDLTest_AssertPass("SDL_ClearError()"); - - lastError = (char *)SDL_GetError(); - SDLTest_AssertPass("SDL_GetError()"); - SDLTest_AssertCheck(lastError != NULL, - "SDL_GetError() != NULL"); - if (lastError != NULL) - { - len = SDL_strlen(lastError); - SDLTest_AssertCheck(len == 0, - "SDL_GetError(): no message expected, len: %i", (int) len); - } - - result = SDL_SetError("%s", testError); - SDLTest_AssertPass("SDL_SetError()"); - SDLTest_AssertCheck(result == -1, "SDL_SetError: expected -1, got: %i", result); - lastError = (char *)SDL_GetError(); - SDLTest_AssertCheck(lastError != NULL, - "SDL_GetError() != NULL"); - if (lastError != NULL) - { - len = SDL_strlen(lastError); - SDLTest_AssertCheck(len == SDL_strlen(testError), - "SDL_GetError(): expected message len %i, was len: %i", - (int) SDL_strlen(testError), - (int) len); - SDLTest_AssertCheck(SDL_strcmp(lastError, testError) == 0, - "SDL_GetError(): expected message %s, was message: %s", - testError, - lastError); - } - - /* Clean up */ - SDL_ClearError(); - SDLTest_AssertPass("SDL_ClearError()"); - - return TEST_COMPLETED; -} - -/* ! - * \brief Tests SDL_SetError with empty input - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_SetError - */ -int platform_testSetErrorEmptyInput(void *arg) -{ - int result; - const char *testError = ""; - char *lastError; - size_t len; - - result = SDL_SetError("%s", testError); - SDLTest_AssertPass("SDL_SetError()"); - SDLTest_AssertCheck(result == -1, "SDL_SetError: expected -1, got: %i", result); - lastError = (char *)SDL_GetError(); - SDLTest_AssertCheck(lastError != NULL, - "SDL_GetError() != NULL"); - if (lastError != NULL) - { - len = SDL_strlen(lastError); - SDLTest_AssertCheck(len == SDL_strlen(testError), - "SDL_GetError(): expected message len %i, was len: %i", - (int) SDL_strlen(testError), - (int) len); - SDLTest_AssertCheck(SDL_strcmp(lastError, testError) == 0, - "SDL_GetError(): expected message '%s', was message: '%s'", - testError, - lastError); - } - - /* Clean up */ - SDL_ClearError(); - SDLTest_AssertPass("SDL_ClearError()"); - - return TEST_COMPLETED; -} - -/* ! - * \brief Tests SDL_SetError with invalid input - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_SetError - */ -int platform_testSetErrorInvalidInput(void *arg) -{ - int result; - const char *invalidError = NULL; - const char *probeError = "Testing"; - char *lastError; - size_t len; - - /* Reset */ - SDL_ClearError(); - SDLTest_AssertPass("SDL_ClearError()"); - - /* Check for no-op */ - result = SDL_SetError("%s", invalidError); - SDLTest_AssertPass("SDL_SetError()"); - SDLTest_AssertCheck(result == -1, "SDL_SetError: expected -1, got: %i", result); - lastError = (char *)SDL_GetError(); - SDLTest_AssertCheck(lastError != NULL, - "SDL_GetError() != NULL"); - if (lastError != NULL) - { - len = SDL_strlen(lastError); - SDLTest_AssertCheck(len == 0, - "SDL_GetError(): expected message len 0, was len: %i", - (int) len); - } - - /* Set */ - result = SDL_SetError("%s", probeError); - SDLTest_AssertPass("SDL_SetError('%s')", probeError); - SDLTest_AssertCheck(result == -1, "SDL_SetError: expected -1, got: %i", result); - - /* Check for no-op */ - result = SDL_SetError("%s", invalidError); - SDLTest_AssertPass("SDL_SetError(NULL)"); - SDLTest_AssertCheck(result == -1, "SDL_SetError: expected -1, got: %i", result); - lastError = (char *)SDL_GetError(); - SDLTest_AssertCheck(lastError != NULL, - "SDL_GetError() != NULL"); - if (lastError != NULL) - { - len = SDL_strlen(lastError); - SDLTest_AssertCheck(len == 0, - "SDL_GetError(): expected message len 0, was len: %i", - (int) len); - } - - /* Reset */ - SDL_ClearError(); - SDLTest_AssertPass("SDL_ClearError()"); - - /* Set and check */ - result = SDL_SetError("%s", probeError); - SDLTest_AssertPass("SDL_SetError()"); - SDLTest_AssertCheck(result == -1, "SDL_SetError: expected -1, got: %i", result); - lastError = (char *)SDL_GetError(); - SDLTest_AssertCheck(lastError != NULL, - "SDL_GetError() != NULL"); - if (lastError != NULL) - { - len = SDL_strlen(lastError); - SDLTest_AssertCheck(len == SDL_strlen(probeError), - "SDL_GetError(): expected message len %i, was len: %i", - (int) SDL_strlen(probeError), - (int) len); - SDLTest_AssertCheck(SDL_strcmp(lastError, probeError) == 0, - "SDL_GetError(): expected message '%s', was message: '%s'", - probeError, - lastError); - } - - /* Clean up */ - SDL_ClearError(); - SDLTest_AssertPass("SDL_ClearError()"); - - return TEST_COMPLETED; -} - -/* ! - * \brief Tests SDL_GetPowerInfo - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_GetPowerInfo - */ -int platform_testGetPowerInfo(void *arg) -{ - SDL_PowerState state; - SDL_PowerState stateAgain; - int secs; - int secsAgain; - int pct; - int pctAgain; - - state = SDL_GetPowerInfo(&secs, &pct); - SDLTest_AssertPass("SDL_GetPowerInfo()"); - SDLTest_AssertCheck( - state==SDL_POWERSTATE_UNKNOWN || - state==SDL_POWERSTATE_ON_BATTERY || - state==SDL_POWERSTATE_NO_BATTERY || - state==SDL_POWERSTATE_CHARGING || - state==SDL_POWERSTATE_CHARGED, - "SDL_GetPowerInfo(): state %i is one of the expected values", - (int)state); - - if (state==SDL_POWERSTATE_ON_BATTERY) - { - SDLTest_AssertCheck( - secs >= 0, - "SDL_GetPowerInfo(): on battery, secs >= 0, was: %i", - secs); - SDLTest_AssertCheck( - (pct >= 0) && (pct <= 100), - "SDL_GetPowerInfo(): on battery, pct=[0,100], was: %i", - pct); - } - - if (state==SDL_POWERSTATE_UNKNOWN || - state==SDL_POWERSTATE_NO_BATTERY) - { - SDLTest_AssertCheck( - secs == -1, - "SDL_GetPowerInfo(): no battery, secs == -1, was: %i", - secs); - SDLTest_AssertCheck( - pct == -1, - "SDL_GetPowerInfo(): no battery, pct == -1, was: %i", - pct); - } - - /* Partial return value variations */ - stateAgain = SDL_GetPowerInfo(&secsAgain, NULL); - SDLTest_AssertCheck( - state==stateAgain, - "State %i returned when only 'secs' requested", - stateAgain); - SDLTest_AssertCheck( - secs==secsAgain, - "Value %i matches when only 'secs' requested", - secsAgain); - stateAgain = SDL_GetPowerInfo(NULL, &pctAgain); - SDLTest_AssertCheck( - state==stateAgain, - "State %i returned when only 'pct' requested", - stateAgain); - SDLTest_AssertCheck( - pct==pctAgain, - "Value %i matches when only 'pct' requested", - pctAgain); - stateAgain = SDL_GetPowerInfo(NULL, NULL); - SDLTest_AssertCheck( - state==stateAgain, - "State %i returned when no value requested", - stateAgain); - - return TEST_COMPLETED; -} - -/* ================= Test References ================== */ - -/* Platform test cases */ -static const SDLTest_TestCaseReference platformTest1 = - { (SDLTest_TestCaseFp)platform_testTypes, "platform_testTypes", "Tests predefined types", TEST_ENABLED}; - -static const SDLTest_TestCaseReference platformTest2 = - { (SDLTest_TestCaseFp)platform_testEndianessAndSwap, "platform_testEndianessAndSwap", "Tests endianess and swap functions", TEST_ENABLED}; - -static const SDLTest_TestCaseReference platformTest3 = - { (SDLTest_TestCaseFp)platform_testGetFunctions, "platform_testGetFunctions", "Tests various SDL_GetXYZ functions", TEST_ENABLED}; - -static const SDLTest_TestCaseReference platformTest4 = - { (SDLTest_TestCaseFp)platform_testHasFunctions, "platform_testHasFunctions", "Tests various SDL_HasXYZ functions", TEST_ENABLED}; - -static const SDLTest_TestCaseReference platformTest5 = - { (SDLTest_TestCaseFp)platform_testGetVersion, "platform_testGetVersion", "Tests SDL_GetVersion function", TEST_ENABLED}; - -static const SDLTest_TestCaseReference platformTest6 = - { (SDLTest_TestCaseFp)platform_testSDLVersion, "platform_testSDLVersion", "Tests SDL_VERSION macro", TEST_ENABLED}; - -static const SDLTest_TestCaseReference platformTest7 = - { (SDLTest_TestCaseFp)platform_testDefaultInit, "platform_testDefaultInit", "Tests default SDL_Init", TEST_ENABLED}; - -static const SDLTest_TestCaseReference platformTest8 = - { (SDLTest_TestCaseFp)platform_testGetSetClearError, "platform_testGetSetClearError", "Tests SDL_Get/Set/ClearError", TEST_ENABLED}; - -static const SDLTest_TestCaseReference platformTest9 = - { (SDLTest_TestCaseFp)platform_testSetErrorEmptyInput, "platform_testSetErrorEmptyInput", "Tests SDL_SetError with empty input", TEST_ENABLED}; - -static const SDLTest_TestCaseReference platformTest10 = - { (SDLTest_TestCaseFp)platform_testSetErrorInvalidInput, "platform_testSetErrorInvalidInput", "Tests SDL_SetError with invalid input", TEST_ENABLED}; - -static const SDLTest_TestCaseReference platformTest11 = - { (SDLTest_TestCaseFp)platform_testGetPowerInfo, "platform_testGetPowerInfo", "Tests SDL_GetPowerInfo function", TEST_ENABLED }; - -/* Sequence of Platform test cases */ -static const SDLTest_TestCaseReference *platformTests[] = { - &platformTest1, - &platformTest2, - &platformTest3, - &platformTest4, - &platformTest5, - &platformTest6, - &platformTest7, - &platformTest8, - &platformTest9, - &platformTest10, - &platformTest11, - NULL -}; - -/* Platform test suite (global) */ -SDLTest_TestSuiteReference platformTestSuite = { - "Platform", - NULL, - platformTests, - NULL -}; diff --git a/SDL2-2.0.12/test/testautomation_rect.c b/SDL2-2.0.12/test/testautomation_rect.c deleted file mode 100644 index abf19f5..0000000 --- a/SDL2-2.0.12/test/testautomation_rect.c +++ /dev/null @@ -1,1696 +0,0 @@ -/** - * Original code: automated SDL rect test written by Edgar Simo "bobbens" - * New/updated tests: aschiffler at ferzkopp dot net - */ - -#include - -#include "SDL.h" -#include "SDL_test.h" - -/* ================= Test Case Implementation ================== */ - -/* Helper functions */ - -/* ! - * \brief Private helper to check SDL_IntersectRectAndLine results - */ -void _validateIntersectRectAndLineResults( - SDL_bool intersection, SDL_bool expectedIntersection, - SDL_Rect *rect, SDL_Rect * refRect, - int x1, int y1, int x2, int y2, - int x1Ref, int y1Ref, int x2Ref, int y2Ref) -{ - SDLTest_AssertCheck(intersection == expectedIntersection, - "Check for correct intersection result: expected %s, got %s intersecting rect (%d,%d,%d,%d) with line (%d,%d - %d,%d)", - (expectedIntersection == SDL_TRUE) ? "SDL_TRUE" : "SDL_FALSE", - (intersection == SDL_TRUE) ? "SDL_TRUE" : "SDL_FALSE", - refRect->x, refRect->y, refRect->w, refRect->h, - x1Ref, y1Ref, x2Ref, y2Ref); - SDLTest_AssertCheck(rect->x == refRect->x && rect->y == refRect->y && rect->w == refRect->w && rect->h == refRect->h, - "Check that source rectangle was not modified: got (%d,%d,%d,%d) expected (%d,%d,%d,%d)", - rect->x, rect->y, rect->w, rect->h, - refRect->x, refRect->y, refRect->w, refRect->h); - SDLTest_AssertCheck(x1 == x1Ref && y1 == y1Ref && x2 == x2Ref && y2 == y2Ref, - "Check if line was incorrectly clipped or modified: got (%d,%d - %d,%d) expected (%d,%d - %d,%d)", - x1, y1, x2, y2, - x1Ref, y1Ref, x2Ref, y2Ref); -} - -/* Test case functions */ - -/* ! - * \brief Tests SDL_IntersectRectAndLine() clipping cases - * - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_IntersectRectAndLine - */ -int -rect_testIntersectRectAndLine (void *arg) -{ - SDL_Rect refRect = { 0, 0, 32, 32 }; - SDL_Rect rect; - int x1, y1; - int x2, y2; - SDL_bool intersected; - - int xLeft = -SDLTest_RandomIntegerInRange(1, refRect.w); - int xRight = refRect.w + SDLTest_RandomIntegerInRange(1, refRect.w); - int yTop = -SDLTest_RandomIntegerInRange(1, refRect.h); - int yBottom = refRect.h + SDLTest_RandomIntegerInRange(1, refRect.h); - - x1 = xLeft; - y1 = 15; - x2 = xRight; - y2 = 15; - rect = refRect; - intersected = SDL_IntersectRectAndLine(&rect, &x1, &y1, &x2, &y2); - _validateIntersectRectAndLineResults(intersected, SDL_TRUE, &rect, &refRect, x1, y1, x2, y2, 0, 15, 31, 15); - - x1 = 15; - y1 = yTop; - x2 = 15; - y2 = yBottom; - rect = refRect; - intersected = SDL_IntersectRectAndLine(&rect, &x1, &y1, &x2, &y2); - _validateIntersectRectAndLineResults(intersected, SDL_TRUE, &rect, &refRect, x1, y1, x2, y2, 15, 0, 15, 31); - - x1 = -refRect.w; - y1 = -refRect.h; - x2 = 2*refRect.w; - y2 = 2*refRect.h; - rect = refRect; - intersected = SDL_IntersectRectAndLine(&rect, &x1, &y1, &x2, &y2); - _validateIntersectRectAndLineResults(intersected, SDL_TRUE, &rect, &refRect, x1, y1, x2, y2, 0, 0, 31, 31); - - x1 = 2*refRect.w; - y1 = 2*refRect.h; - x2 = -refRect.w; - y2 = -refRect.h; - rect = refRect; - intersected = SDL_IntersectRectAndLine(&rect, &x1, &y1, &x2, &y2); - _validateIntersectRectAndLineResults(intersected, SDL_TRUE, &rect, &refRect, x1, y1, x2, y2, 31, 31, 0, 0); - - x1 = -1; - y1 = 32; - x2 = 32; - y2 = -1; - rect = refRect; - intersected = SDL_IntersectRectAndLine(&rect, &x1, &y1, &x2, &y2); - _validateIntersectRectAndLineResults(intersected, SDL_TRUE, &rect, &refRect, x1, y1, x2, y2, 0, 31, 31, 0); - - x1 = 32; - y1 = -1; - x2 = -1; - y2 = 32; - rect = refRect; - intersected = SDL_IntersectRectAndLine(&rect, &x1, &y1, &x2, &y2); - _validateIntersectRectAndLineResults(intersected, SDL_TRUE, &rect, &refRect, x1, y1, x2, y2, 31, 0, 0, 31); - - return TEST_COMPLETED; -} - -/* ! - * \brief Tests SDL_IntersectRectAndLine() non-clipping case line inside - * - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_IntersectRectAndLine - */ -int -rect_testIntersectRectAndLineInside (void *arg) -{ - SDL_Rect refRect = { 0, 0, 32, 32 }; - SDL_Rect rect; - int x1, y1; - int x2, y2; - SDL_bool intersected; - - int xmin = refRect.x; - int xmax = refRect.x + refRect.w - 1; - int ymin = refRect.y; - int ymax = refRect.y + refRect.h - 1; - int x1Ref = SDLTest_RandomIntegerInRange(xmin + 1, xmax - 1); - int y1Ref = SDLTest_RandomIntegerInRange(ymin + 1, ymax - 1); - int x2Ref = SDLTest_RandomIntegerInRange(xmin + 1, xmax - 1); - int y2Ref = SDLTest_RandomIntegerInRange(ymin + 1, ymax - 1); - - x1 = x1Ref; - y1 = y1Ref; - x2 = x2Ref; - y2 = y2Ref; - rect = refRect; - intersected = SDL_IntersectRectAndLine(&rect, &x1, &y1, &x2, &y2); - _validateIntersectRectAndLineResults(intersected, SDL_TRUE, &rect, &refRect, x1, y1, x2, y2, x1Ref, y1Ref, x2Ref, y2Ref); - - x1 = x1Ref; - y1 = y1Ref; - x2 = xmax; - y2 = ymax; - rect = refRect; - intersected = SDL_IntersectRectAndLine(&rect, &x1, &y1, &x2, &y2); - _validateIntersectRectAndLineResults(intersected, SDL_TRUE, &rect, &refRect, x1, y1, x2, y2, x1Ref, y1Ref, xmax, ymax); - - x1 = xmin; - y1 = ymin; - x2 = x2Ref; - y2 = y2Ref; - rect = refRect; - intersected = SDL_IntersectRectAndLine(&rect, &x1, &y1, &x2, &y2); - _validateIntersectRectAndLineResults(intersected, SDL_TRUE, &rect, &refRect, x1, y1, x2, y2, xmin, ymin, x2Ref, y2Ref); - - x1 = xmin; - y1 = ymin; - x2 = xmax; - y2 = ymax; - rect = refRect; - intersected = SDL_IntersectRectAndLine(&rect, &x1, &y1, &x2, &y2); - _validateIntersectRectAndLineResults(intersected, SDL_TRUE, &rect, &refRect, x1, y1, x2, y2, xmin, ymin, xmax, ymax); - - x1 = xmin; - y1 = ymax; - x2 = xmax; - y2 = ymin; - rect = refRect; - intersected = SDL_IntersectRectAndLine(&rect, &x1, &y1, &x2, &y2); - _validateIntersectRectAndLineResults(intersected, SDL_TRUE, &rect, &refRect, x1, y1, x2, y2, xmin, ymax, xmax, ymin); - - return TEST_COMPLETED; -} - -/* ! - * \brief Tests SDL_IntersectRectAndLine() non-clipping cases outside - * - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_IntersectRectAndLine - */ -int -rect_testIntersectRectAndLineOutside (void *arg) -{ - SDL_Rect refRect = { 0, 0, 32, 32 }; - SDL_Rect rect; - int x1, y1; - int x2, y2; - SDL_bool intersected; - - int xLeft = -SDLTest_RandomIntegerInRange(1, refRect.w); - int xRight = refRect.w + SDLTest_RandomIntegerInRange(1, refRect.w); - int yTop = -SDLTest_RandomIntegerInRange(1, refRect.h); - int yBottom = refRect.h + SDLTest_RandomIntegerInRange(1, refRect.h); - - x1 = xLeft; - y1 = 0; - x2 = xLeft; - y2 = 31; - rect = refRect; - intersected = SDL_IntersectRectAndLine(&rect, &x1, &y1, &x2, &y2); - _validateIntersectRectAndLineResults(intersected, SDL_FALSE, &rect, &refRect, x1, y1, x2, y2, xLeft, 0, xLeft, 31); - - x1 = xRight; - y1 = 0; - x2 = xRight; - y2 = 31; - rect = refRect; - intersected = SDL_IntersectRectAndLine(&rect, &x1, &y1, &x2, &y2); - _validateIntersectRectAndLineResults(intersected, SDL_FALSE, &rect, &refRect, x1, y1, x2, y2, xRight, 0, xRight, 31); - - x1 = 0; - y1 = yTop; - x2 = 31; - y2 = yTop; - rect = refRect; - intersected = SDL_IntersectRectAndLine(&rect, &x1, &y1, &x2, &y2); - _validateIntersectRectAndLineResults(intersected, SDL_FALSE, &rect, &refRect, x1, y1, x2, y2, 0, yTop, 31, yTop); - - x1 = 0; - y1 = yBottom; - x2 = 31; - y2 = yBottom; - rect = refRect; - intersected = SDL_IntersectRectAndLine(&rect, &x1, &y1, &x2, &y2); - _validateIntersectRectAndLineResults(intersected, SDL_FALSE, &rect, &refRect, x1, y1, x2, y2, 0, yBottom, 31, yBottom); - - return TEST_COMPLETED; -} - -/* ! - * \brief Tests SDL_IntersectRectAndLine() with empty rectangle - * - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_IntersectRectAndLine - */ -int -rect_testIntersectRectAndLineEmpty (void *arg) -{ - SDL_Rect refRect; - SDL_Rect rect; - int x1, y1, x1Ref, y1Ref; - int x2, y2, x2Ref, y2Ref; - SDL_bool intersected; - - refRect.x = SDLTest_RandomIntegerInRange(1, 1024); - refRect.y = SDLTest_RandomIntegerInRange(1, 1024); - refRect.w = 0; - refRect.h = 0; - x1Ref = refRect.x; - y1Ref = refRect.y; - x2Ref = SDLTest_RandomIntegerInRange(1, 1024); - y2Ref = SDLTest_RandomIntegerInRange(1, 1024); - - x1 = x1Ref; - y1 = y1Ref; - x2 = x2Ref; - y2 = y2Ref; - rect = refRect; - intersected = SDL_IntersectRectAndLine(&rect, &x1, &y1, &x2, &y2); - _validateIntersectRectAndLineResults(intersected, SDL_FALSE, &rect, &refRect, x1, y1, x2, y2, x1Ref, y1Ref, x2Ref, y2Ref); - - return TEST_COMPLETED; -} - -/* ! - * \brief Negative tests against SDL_IntersectRectAndLine() with invalid parameters - * - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_IntersectRectAndLine - */ -int -rect_testIntersectRectAndLineParam (void *arg) -{ - SDL_Rect rect = { 0, 0, 32, 32 }; - int x1 = rect.w / 2; - int y1 = rect.h / 2; - int x2 = x1; - int y2 = 2 * rect.h; - SDL_bool intersected; - - intersected = SDL_IntersectRectAndLine(&rect, &x1, &y1, &x2, &y2); - SDLTest_AssertCheck(intersected == SDL_TRUE, "Check that intersection result was SDL_TRUE"); - - intersected = SDL_IntersectRectAndLine((SDL_Rect *)NULL, &x1, &y1, &x2, &y2); - SDLTest_AssertCheck(intersected == SDL_FALSE, "Check that function returns SDL_FALSE when 1st parameter is NULL"); - intersected = SDL_IntersectRectAndLine(&rect, (int *)NULL, &y1, &x2, &y2); - SDLTest_AssertCheck(intersected == SDL_FALSE, "Check that function returns SDL_FALSE when 2nd parameter is NULL"); - intersected = SDL_IntersectRectAndLine(&rect, &x1, (int *)NULL, &x2, &y2); - SDLTest_AssertCheck(intersected == SDL_FALSE, "Check that function returns SDL_FALSE when 3rd parameter is NULL"); - intersected = SDL_IntersectRectAndLine(&rect, &x1, &y1, (int *)NULL, &y2); - SDLTest_AssertCheck(intersected == SDL_FALSE, "Check that function returns SDL_FALSE when 4th parameter is NULL"); - intersected = SDL_IntersectRectAndLine(&rect, &x1, &y1, &x2, (int *)NULL); - SDLTest_AssertCheck(intersected == SDL_FALSE, "Check that function returns SDL_FALSE when 5th parameter is NULL"); - intersected = SDL_IntersectRectAndLine((SDL_Rect *)NULL, (int *)NULL, (int *)NULL, (int *)NULL, (int *)NULL); - SDLTest_AssertCheck(intersected == SDL_FALSE, "Check that function returns SDL_FALSE when all parameters are NULL"); - - return TEST_COMPLETED; -} - -/* ! - * \brief Private helper to check SDL_HasIntersection results - */ -void _validateHasIntersectionResults( - SDL_bool intersection, SDL_bool expectedIntersection, - SDL_Rect *rectA, SDL_Rect *rectB, SDL_Rect *refRectA, SDL_Rect *refRectB) -{ - SDLTest_AssertCheck(intersection == expectedIntersection, - "Check intersection result: expected %s, got %s intersecting A (%d,%d,%d,%d) with B (%d,%d,%d,%d)", - (expectedIntersection == SDL_TRUE) ? "SDL_TRUE" : "SDL_FALSE", - (intersection == SDL_TRUE) ? "SDL_TRUE" : "SDL_FALSE", - rectA->x, rectA->y, rectA->w, rectA->h, - rectB->x, rectB->y, rectB->w, rectB->h); - SDLTest_AssertCheck(rectA->x == refRectA->x && rectA->y == refRectA->y && rectA->w == refRectA->w && rectA->h == refRectA->h, - "Check that source rectangle A was not modified: got (%d,%d,%d,%d) expected (%d,%d,%d,%d)", - rectA->x, rectA->y, rectA->w, rectA->h, - refRectA->x, refRectA->y, refRectA->w, refRectA->h); - SDLTest_AssertCheck(rectB->x == refRectB->x && rectB->y == refRectB->y && rectB->w == refRectB->w && rectB->h == refRectB->h, - "Check that source rectangle B was not modified: got (%d,%d,%d,%d) expected (%d,%d,%d,%d)", - rectB->x, rectB->y, rectB->w, rectB->h, - refRectB->x, refRectB->y, refRectB->w, refRectB->h); -} - -/* ! - * \brief Private helper to check SDL_IntersectRect results - */ -void _validateIntersectRectResults( - SDL_bool intersection, SDL_bool expectedIntersection, - SDL_Rect *rectA, SDL_Rect *rectB, SDL_Rect *refRectA, SDL_Rect *refRectB, - SDL_Rect *result, SDL_Rect *expectedResult) -{ - _validateHasIntersectionResults(intersection, expectedIntersection, rectA, rectB, refRectA, refRectB); - if (result && expectedResult) { - SDLTest_AssertCheck(result->x == expectedResult->x && result->y == expectedResult->y && result->w == expectedResult->w && result->h == expectedResult->h, - "Check that intersection of rectangles A (%d,%d,%d,%d) and B (%d,%d,%d,%d) was correctly calculated, got (%d,%d,%d,%d) expected (%d,%d,%d,%d)", - rectA->x, rectA->y, rectA->w, rectA->h, - rectB->x, rectB->y, rectB->w, rectB->h, - result->x, result->y, result->w, result->h, - expectedResult->x, expectedResult->y, expectedResult->w, expectedResult->h); - } -} - -/* ! - * \brief Private helper to check SDL_UnionRect results - */ -void _validateUnionRectResults( - SDL_Rect *rectA, SDL_Rect *rectB, SDL_Rect *refRectA, SDL_Rect *refRectB, - SDL_Rect *result, SDL_Rect *expectedResult) -{ - SDLTest_AssertCheck(rectA->x == refRectA->x && rectA->y == refRectA->y && rectA->w == refRectA->w && rectA->h == refRectA->h, - "Check that source rectangle A was not modified: got (%d,%d,%d,%d) expected (%d,%d,%d,%d)", - rectA->x, rectA->y, rectA->w, rectA->h, - refRectA->x, refRectA->y, refRectA->w, refRectA->h); - SDLTest_AssertCheck(rectB->x == refRectB->x && rectB->y == refRectB->y && rectB->w == refRectB->w && rectB->h == refRectB->h, - "Check that source rectangle B was not modified: got (%d,%d,%d,%d) expected (%d,%d,%d,%d)", - rectB->x, rectB->y, rectB->w, rectB->h, - refRectB->x, refRectB->y, refRectB->w, refRectB->h); - SDLTest_AssertCheck(result->x == expectedResult->x && result->y == expectedResult->y && result->w == expectedResult->w && result->h == expectedResult->h, - "Check that union of rectangles A (%d,%d,%d,%d) and B (%d,%d,%d,%d) was correctly calculated, got (%d,%d,%d,%d) expected (%d,%d,%d,%d)", - rectA->x, rectA->y, rectA->w, rectA->h, - rectB->x, rectB->y, rectB->w, rectB->h, - result->x, result->y, result->w, result->h, - expectedResult->x, expectedResult->y, expectedResult->w, expectedResult->h); -} - -/* ! - * \brief Private helper to check SDL_RectEmpty results - */ -void _validateRectEmptyResults( - SDL_bool empty, SDL_bool expectedEmpty, - SDL_Rect *rect, SDL_Rect *refRect) -{ - SDLTest_AssertCheck(empty == expectedEmpty, - "Check for correct empty result: expected %s, got %s testing (%d,%d,%d,%d)", - (expectedEmpty == SDL_TRUE) ? "SDL_TRUE" : "SDL_FALSE", - (empty == SDL_TRUE) ? "SDL_TRUE" : "SDL_FALSE", - rect->x, rect->y, rect->w, rect->h); - SDLTest_AssertCheck(rect->x == refRect->x && rect->y == refRect->y && rect->w == refRect->w && rect->h == refRect->h, - "Check that source rectangle was not modified: got (%d,%d,%d,%d) expected (%d,%d,%d,%d)", - rect->x, rect->y, rect->w, rect->h, - refRect->x, refRect->y, refRect->w, refRect->h); -} - -/* ! - * \brief Private helper to check SDL_RectEquals results - */ -void _validateRectEqualsResults( - SDL_bool equals, SDL_bool expectedEquals, - SDL_Rect *rectA, SDL_Rect *rectB, SDL_Rect *refRectA, SDL_Rect *refRectB) -{ - SDLTest_AssertCheck(equals == expectedEquals, - "Check for correct equals result: expected %s, got %s testing (%d,%d,%d,%d) and (%d,%d,%d,%d)", - (expectedEquals == SDL_TRUE) ? "SDL_TRUE" : "SDL_FALSE", - (equals == SDL_TRUE) ? "SDL_TRUE" : "SDL_FALSE", - rectA->x, rectA->y, rectA->w, rectA->h, - rectB->x, rectB->y, rectB->w, rectB->h); - SDLTest_AssertCheck(rectA->x == refRectA->x && rectA->y == refRectA->y && rectA->w == refRectA->w && rectA->h == refRectA->h, - "Check that source rectangle A was not modified: got (%d,%d,%d,%d) expected (%d,%d,%d,%d)", - rectA->x, rectA->y, rectA->w, rectA->h, - refRectA->x, refRectA->y, refRectA->w, refRectA->h); - SDLTest_AssertCheck(rectB->x == refRectB->x && rectB->y == refRectB->y && rectB->w == refRectB->w && rectB->h == refRectB->h, - "Check that source rectangle B was not modified: got (%d,%d,%d,%d) expected (%d,%d,%d,%d)", - rectB->x, rectB->y, rectB->w, rectB->h, - refRectB->x, refRectB->y, refRectB->w, refRectB->h); -} - -/* ! - * \brief Tests SDL_IntersectRect() with B fully inside A - * - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_IntersectRect - */ -int rect_testIntersectRectInside (void *arg) -{ - SDL_Rect refRectA = { 0, 0, 32, 32 }; - SDL_Rect refRectB; - SDL_Rect rectA; - SDL_Rect rectB; - SDL_Rect result; - SDL_bool intersection; - - /* rectB fully contained in rectA */ - refRectB.x = 0; - refRectB.y = 0; - refRectB.w = SDLTest_RandomIntegerInRange(refRectA.x + 1, refRectA.x + refRectA.w - 1); - refRectB.h = SDLTest_RandomIntegerInRange(refRectA.y + 1, refRectA.y + refRectA.h - 1); - rectA = refRectA; - rectB = refRectB; - intersection = SDL_IntersectRect(&rectA, &rectB, &result); - _validateIntersectRectResults(intersection, SDL_TRUE, &rectA, &rectB, &refRectA, &refRectB, &result, &refRectB); - - return TEST_COMPLETED; -} - -/* ! - * \brief Tests SDL_IntersectRect() with B fully outside A - * - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_IntersectRect - */ -int rect_testIntersectRectOutside (void *arg) -{ - SDL_Rect refRectA = { 0, 0, 32, 32 }; - SDL_Rect refRectB; - SDL_Rect rectA; - SDL_Rect rectB; - SDL_Rect result; - SDL_bool intersection; - - /* rectB fully outside of rectA */ - refRectB.x = refRectA.x + refRectA.w + SDLTest_RandomIntegerInRange(1, 10); - refRectB.y = refRectA.y + refRectA.h + SDLTest_RandomIntegerInRange(1, 10); - refRectB.w = refRectA.w; - refRectB.h = refRectA.h; - rectA = refRectA; - rectB = refRectB; - intersection = SDL_IntersectRect(&rectA, &rectB, &result); - _validateIntersectRectResults(intersection, SDL_FALSE, &rectA, &rectB, &refRectA, &refRectB, (SDL_Rect *)NULL, (SDL_Rect *)NULL); - - return TEST_COMPLETED; -} - -/* ! - * \brief Tests SDL_IntersectRect() with B partially intersecting A - * - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_IntersectRect - */ -int rect_testIntersectRectPartial (void *arg) -{ - SDL_Rect refRectA = { 0, 0, 32, 32 }; - SDL_Rect refRectB; - SDL_Rect rectA; - SDL_Rect rectB; - SDL_Rect result; - SDL_Rect expectedResult; - SDL_bool intersection; - - /* rectB partially contained in rectA */ - refRectB.x = SDLTest_RandomIntegerInRange(refRectA.x + 1, refRectA.x + refRectA.w - 1); - refRectB.y = SDLTest_RandomIntegerInRange(refRectA.y + 1, refRectA.y + refRectA.h - 1); - refRectB.w = refRectA.w; - refRectB.h = refRectA.h; - rectA = refRectA; - rectB = refRectB; - expectedResult.x = refRectB.x; - expectedResult.y = refRectB.y; - expectedResult.w = refRectA.w - refRectB.x; - expectedResult.h = refRectA.h - refRectB.y; - intersection = SDL_IntersectRect(&rectA, &rectB, &result); - _validateIntersectRectResults(intersection, SDL_TRUE, &rectA, &rectB, &refRectA, &refRectB, &result, &expectedResult); - - /* rectB right edge */ - refRectB.x = rectA.w - 1; - refRectB.y = rectA.y; - refRectB.w = SDLTest_RandomIntegerInRange(1, refRectA.w - 1); - refRectB.h = SDLTest_RandomIntegerInRange(1, refRectA.h - 1); - rectA = refRectA; - rectB = refRectB; - expectedResult.x = refRectB.x; - expectedResult.y = refRectB.y; - expectedResult.w = 1; - expectedResult.h = refRectB.h; - intersection = SDL_IntersectRect(&rectA, &rectB, &result); - _validateIntersectRectResults(intersection, SDL_TRUE, &rectA, &rectB, &refRectA, &refRectB, &result, &expectedResult); - - /* rectB left edge */ - refRectB.x = 1 - rectA.w; - refRectB.y = rectA.y; - refRectB.w = refRectA.w; - refRectB.h = SDLTest_RandomIntegerInRange(1, refRectA.h - 1); - rectA = refRectA; - rectB = refRectB; - expectedResult.x = 0; - expectedResult.y = refRectB.y; - expectedResult.w = 1; - expectedResult.h = refRectB.h; - intersection = SDL_IntersectRect(&rectA, &rectB, &result); - _validateIntersectRectResults(intersection, SDL_TRUE, &rectA, &rectB, &refRectA, &refRectB, &result, &expectedResult); - - /* rectB bottom edge */ - refRectB.x = rectA.x; - refRectB.y = rectA.h - 1; - refRectB.w = SDLTest_RandomIntegerInRange(1, refRectA.w - 1); - refRectB.h = SDLTest_RandomIntegerInRange(1, refRectA.h - 1); - rectA = refRectA; - rectB = refRectB; - expectedResult.x = refRectB.x; - expectedResult.y = refRectB.y; - expectedResult.w = refRectB.w; - expectedResult.h = 1; - intersection = SDL_IntersectRect(&rectA, &rectB, &result); - _validateIntersectRectResults(intersection, SDL_TRUE, &rectA, &rectB, &refRectA, &refRectB, &result, &expectedResult); - - /* rectB top edge */ - refRectB.x = rectA.x; - refRectB.y = 1 - rectA.h; - refRectB.w = SDLTest_RandomIntegerInRange(1, refRectA.w - 1); - refRectB.h = rectA.h; - rectA = refRectA; - rectB = refRectB; - expectedResult.x = refRectB.x; - expectedResult.y = 0; - expectedResult.w = refRectB.w; - expectedResult.h = 1; - intersection = SDL_IntersectRect(&rectA, &rectB, &result); - _validateIntersectRectResults(intersection, SDL_TRUE, &rectA, &rectB, &refRectA, &refRectB, &result, &expectedResult); - - return TEST_COMPLETED; -} - -/* ! - * \brief Tests SDL_IntersectRect() with 1x1 pixel sized rectangles - * - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_IntersectRect - */ -int rect_testIntersectRectPoint (void *arg) -{ - SDL_Rect refRectA = { 0, 0, 1, 1 }; - SDL_Rect refRectB = { 0, 0, 1, 1 }; - SDL_Rect rectA; - SDL_Rect rectB; - SDL_Rect result; - SDL_bool intersection; - int offsetX, offsetY; - - /* intersecting pixels */ - refRectA.x = SDLTest_RandomIntegerInRange(1, 100); - refRectA.y = SDLTest_RandomIntegerInRange(1, 100); - refRectB.x = refRectA.x; - refRectB.y = refRectA.y; - rectA = refRectA; - rectB = refRectB; - intersection = SDL_IntersectRect(&rectA, &rectB, &result); - _validateIntersectRectResults(intersection, SDL_TRUE, &rectA, &rectB, &refRectA, &refRectB, &result, &refRectA); - - /* non-intersecting pixels cases */ - for (offsetX = -1; offsetX <= 1; offsetX++) { - for (offsetY = -1; offsetY <= 1; offsetY++) { - if (offsetX != 0 || offsetY != 0) { - refRectA.x = SDLTest_RandomIntegerInRange(1, 100); - refRectA.y = SDLTest_RandomIntegerInRange(1, 100); - refRectB.x = refRectA.x; - refRectB.y = refRectA.y; - refRectB.x += offsetX; - refRectB.y += offsetY; - rectA = refRectA; - rectB = refRectB; - intersection = SDL_IntersectRect(&rectA, &rectB, &result); - _validateIntersectRectResults(intersection, SDL_FALSE, &rectA, &rectB, &refRectA, &refRectB, (SDL_Rect *)NULL, (SDL_Rect *)NULL); - } - } - } - - return TEST_COMPLETED; -} - -/* ! - * \brief Tests SDL_IntersectRect() with empty rectangles - * - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_IntersectRect - */ -int rect_testIntersectRectEmpty (void *arg) -{ - SDL_Rect refRectA; - SDL_Rect refRectB; - SDL_Rect rectA; - SDL_Rect rectB; - SDL_Rect result; - SDL_bool intersection; - SDL_bool empty; - - /* Rect A empty */ - result.w = SDLTest_RandomIntegerInRange(1, 100); - result.h = SDLTest_RandomIntegerInRange(1, 100); - refRectA.x = SDLTest_RandomIntegerInRange(1, 100); - refRectA.y = SDLTest_RandomIntegerInRange(1, 100); - refRectA.w = SDLTest_RandomIntegerInRange(1, 100); - refRectA.h = SDLTest_RandomIntegerInRange(1, 100); - refRectB = refRectA; - refRectA.w = 0; - refRectA.h = 0; - rectA = refRectA; - rectB = refRectB; - intersection = SDL_IntersectRect(&rectA, &rectB, &result); - _validateIntersectRectResults(intersection, SDL_FALSE, &rectA, &rectB, &refRectA, &refRectB, (SDL_Rect *)NULL, (SDL_Rect *)NULL); - empty = (SDL_bool)SDL_RectEmpty(&result); - SDLTest_AssertCheck(empty == SDL_TRUE, "Validate result is empty Rect; got: %s", (empty == SDL_TRUE) ? "SDL_TRUE" : "SDL_FALSE"); - - /* Rect B empty */ - result.w = SDLTest_RandomIntegerInRange(1, 100); - result.h = SDLTest_RandomIntegerInRange(1, 100); - refRectA.x = SDLTest_RandomIntegerInRange(1, 100); - refRectA.y = SDLTest_RandomIntegerInRange(1, 100); - refRectA.w = SDLTest_RandomIntegerInRange(1, 100); - refRectA.h = SDLTest_RandomIntegerInRange(1, 100); - refRectB = refRectA; - refRectB.w = 0; - refRectB.h = 0; - rectA = refRectA; - rectB = refRectB; - intersection = SDL_IntersectRect(&rectA, &rectB, &result); - _validateIntersectRectResults(intersection, SDL_FALSE, &rectA, &rectB, &refRectA, &refRectB, (SDL_Rect *)NULL, (SDL_Rect *)NULL); - empty = (SDL_bool)SDL_RectEmpty(&result); - SDLTest_AssertCheck(empty == SDL_TRUE, "Validate result is empty Rect; got: %s", (empty == SDL_TRUE) ? "SDL_TRUE" : "SDL_FALSE"); - - /* Rect A and B empty */ - result.w = SDLTest_RandomIntegerInRange(1, 100); - result.h = SDLTest_RandomIntegerInRange(1, 100); - refRectA.x = SDLTest_RandomIntegerInRange(1, 100); - refRectA.y = SDLTest_RandomIntegerInRange(1, 100); - refRectA.w = SDLTest_RandomIntegerInRange(1, 100); - refRectA.h = SDLTest_RandomIntegerInRange(1, 100); - refRectB = refRectA; - refRectA.w = 0; - refRectA.h = 0; - refRectB.w = 0; - refRectB.h = 0; - rectA = refRectA; - rectB = refRectB; - intersection = SDL_IntersectRect(&rectA, &rectB, &result); - _validateIntersectRectResults(intersection, SDL_FALSE, &rectA, &rectB, &refRectA, &refRectB, (SDL_Rect *)NULL, (SDL_Rect *)NULL); - empty = (SDL_bool)SDL_RectEmpty(&result); - SDLTest_AssertCheck(empty == SDL_TRUE, "Validate result is empty Rect; got: %s", (empty == SDL_TRUE) ? "SDL_TRUE" : "SDL_FALSE"); - - return TEST_COMPLETED; -} - -/* ! - * \brief Negative tests against SDL_IntersectRect() with invalid parameters - * - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_IntersectRect - */ -int rect_testIntersectRectParam(void *arg) -{ - SDL_Rect rectA; - SDL_Rect rectB; - SDL_Rect result; - SDL_bool intersection; - - /* invalid parameter combinations */ - intersection = SDL_IntersectRect((SDL_Rect *)NULL, &rectB, &result); - SDLTest_AssertCheck(intersection == SDL_FALSE, "Check that function returns SDL_FALSE when 1st parameter is NULL"); - intersection = SDL_IntersectRect(&rectA, (SDL_Rect *)NULL, &result); - SDLTest_AssertCheck(intersection == SDL_FALSE, "Check that function returns SDL_FALSE when 2st parameter is NULL"); - intersection = SDL_IntersectRect(&rectA, &rectB, (SDL_Rect *)NULL); - SDLTest_AssertCheck(intersection == SDL_FALSE, "Check that function returns SDL_FALSE when 3st parameter is NULL"); - intersection = SDL_IntersectRect((SDL_Rect *)NULL, (SDL_Rect *)NULL, &result); - SDLTest_AssertCheck(intersection == SDL_FALSE, "Check that function returns SDL_FALSE when 1st and 2nd parameters are NULL"); - intersection = SDL_IntersectRect((SDL_Rect *)NULL, &rectB, (SDL_Rect *)NULL); - SDLTest_AssertCheck(intersection == SDL_FALSE, "Check that function returns SDL_FALSE when 1st and 3rd parameters are NULL "); - intersection = SDL_IntersectRect((SDL_Rect *)NULL, (SDL_Rect *)NULL, (SDL_Rect *)NULL); - SDLTest_AssertCheck(intersection == SDL_FALSE, "Check that function returns SDL_FALSE when all parameters are NULL"); - - return TEST_COMPLETED; -} - -/* ! - * \brief Tests SDL_HasIntersection() with B fully inside A - * - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_HasIntersection - */ -int rect_testHasIntersectionInside (void *arg) -{ - SDL_Rect refRectA = { 0, 0, 32, 32 }; - SDL_Rect refRectB; - SDL_Rect rectA; - SDL_Rect rectB; - SDL_bool intersection; - - /* rectB fully contained in rectA */ - refRectB.x = 0; - refRectB.y = 0; - refRectB.w = SDLTest_RandomIntegerInRange(refRectA.x + 1, refRectA.x + refRectA.w - 1); - refRectB.h = SDLTest_RandomIntegerInRange(refRectA.y + 1, refRectA.y + refRectA.h - 1); - rectA = refRectA; - rectB = refRectB; - intersection = SDL_HasIntersection(&rectA, &rectB); - _validateHasIntersectionResults(intersection, SDL_TRUE, &rectA, &rectB, &refRectA, &refRectB); - - return TEST_COMPLETED; -} - -/* ! - * \brief Tests SDL_HasIntersection() with B fully outside A - * - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_HasIntersection - */ -int rect_testHasIntersectionOutside (void *arg) -{ - SDL_Rect refRectA = { 0, 0, 32, 32 }; - SDL_Rect refRectB; - SDL_Rect rectA; - SDL_Rect rectB; - SDL_bool intersection; - - /* rectB fully outside of rectA */ - refRectB.x = refRectA.x + refRectA.w + SDLTest_RandomIntegerInRange(1, 10); - refRectB.y = refRectA.y + refRectA.h + SDLTest_RandomIntegerInRange(1, 10); - refRectB.w = refRectA.w; - refRectB.h = refRectA.h; - rectA = refRectA; - rectB = refRectB; - intersection = SDL_HasIntersection(&rectA, &rectB); - _validateHasIntersectionResults(intersection, SDL_FALSE, &rectA, &rectB, &refRectA, &refRectB); - - return TEST_COMPLETED; -} - -/* ! - * \brief Tests SDL_HasIntersection() with B partially intersecting A - * - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_HasIntersection - */ -int rect_testHasIntersectionPartial (void *arg) -{ - SDL_Rect refRectA = { 0, 0, 32, 32 }; - SDL_Rect refRectB; - SDL_Rect rectA; - SDL_Rect rectB; - SDL_bool intersection; - - /* rectB partially contained in rectA */ - refRectB.x = SDLTest_RandomIntegerInRange(refRectA.x + 1, refRectA.x + refRectA.w - 1); - refRectB.y = SDLTest_RandomIntegerInRange(refRectA.y + 1, refRectA.y + refRectA.h - 1); - refRectB.w = refRectA.w; - refRectB.h = refRectA.h; - rectA = refRectA; - rectB = refRectB; - intersection = SDL_HasIntersection(&rectA, &rectB); - _validateHasIntersectionResults(intersection, SDL_TRUE, &rectA, &rectB, &refRectA, &refRectB); - - /* rectB right edge */ - refRectB.x = rectA.w - 1; - refRectB.y = rectA.y; - refRectB.w = SDLTest_RandomIntegerInRange(1, refRectA.w - 1); - refRectB.h = SDLTest_RandomIntegerInRange(1, refRectA.h - 1); - rectA = refRectA; - rectB = refRectB; - intersection = SDL_HasIntersection(&rectA, &rectB); - _validateHasIntersectionResults(intersection, SDL_TRUE, &rectA, &rectB, &refRectA, &refRectB); - - /* rectB left edge */ - refRectB.x = 1 - rectA.w; - refRectB.y = rectA.y; - refRectB.w = refRectA.w; - refRectB.h = SDLTest_RandomIntegerInRange(1, refRectA.h - 1); - rectA = refRectA; - rectB = refRectB; - intersection = SDL_HasIntersection(&rectA, &rectB); - _validateHasIntersectionResults(intersection, SDL_TRUE, &rectA, &rectB, &refRectA, &refRectB); - - /* rectB bottom edge */ - refRectB.x = rectA.x; - refRectB.y = rectA.h - 1; - refRectB.w = SDLTest_RandomIntegerInRange(1, refRectA.w - 1); - refRectB.h = SDLTest_RandomIntegerInRange(1, refRectA.h - 1); - rectA = refRectA; - rectB = refRectB; - intersection = SDL_HasIntersection(&rectA, &rectB); - _validateHasIntersectionResults(intersection, SDL_TRUE, &rectA, &rectB, &refRectA, &refRectB); - - /* rectB top edge */ - refRectB.x = rectA.x; - refRectB.y = 1 - rectA.h; - refRectB.w = SDLTest_RandomIntegerInRange(1, refRectA.w - 1); - refRectB.h = rectA.h; - rectA = refRectA; - rectB = refRectB; - intersection = SDL_HasIntersection(&rectA, &rectB); - _validateHasIntersectionResults(intersection, SDL_TRUE, &rectA, &rectB, &refRectA, &refRectB); - - return TEST_COMPLETED; -} - -/* ! - * \brief Tests SDL_HasIntersection() with 1x1 pixel sized rectangles - * - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_HasIntersection - */ -int rect_testHasIntersectionPoint (void *arg) -{ - SDL_Rect refRectA = { 0, 0, 1, 1 }; - SDL_Rect refRectB = { 0, 0, 1, 1 }; - SDL_Rect rectA; - SDL_Rect rectB; - SDL_bool intersection; - int offsetX, offsetY; - - /* intersecting pixels */ - refRectA.x = SDLTest_RandomIntegerInRange(1, 100); - refRectA.y = SDLTest_RandomIntegerInRange(1, 100); - refRectB.x = refRectA.x; - refRectB.y = refRectA.y; - rectA = refRectA; - rectB = refRectB; - intersection = SDL_HasIntersection(&rectA, &rectB); - _validateHasIntersectionResults(intersection, SDL_TRUE, &rectA, &rectB, &refRectA, &refRectB); - - /* non-intersecting pixels cases */ - for (offsetX = -1; offsetX <= 1; offsetX++) { - for (offsetY = -1; offsetY <= 1; offsetY++) { - if (offsetX != 0 || offsetY != 0) { - refRectA.x = SDLTest_RandomIntegerInRange(1, 100); - refRectA.y = SDLTest_RandomIntegerInRange(1, 100); - refRectB.x = refRectA.x; - refRectB.y = refRectA.y; - refRectB.x += offsetX; - refRectB.y += offsetY; - rectA = refRectA; - rectB = refRectB; - intersection = SDL_HasIntersection(&rectA, &rectB); - _validateHasIntersectionResults(intersection, SDL_FALSE, &rectA, &rectB, &refRectA, &refRectB); - } - } - } - - return TEST_COMPLETED; -} - -/* ! - * \brief Tests SDL_HasIntersection() with empty rectangles - * - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_HasIntersection - */ -int rect_testHasIntersectionEmpty (void *arg) -{ - SDL_Rect refRectA; - SDL_Rect refRectB; - SDL_Rect rectA; - SDL_Rect rectB; - SDL_bool intersection; - - /* Rect A empty */ - refRectA.x = SDLTest_RandomIntegerInRange(1, 100); - refRectA.y = SDLTest_RandomIntegerInRange(1, 100); - refRectA.w = SDLTest_RandomIntegerInRange(1, 100); - refRectA.h = SDLTest_RandomIntegerInRange(1, 100); - refRectB = refRectA; - refRectA.w = 0; - refRectA.h = 0; - rectA = refRectA; - rectB = refRectB; - intersection = SDL_HasIntersection(&rectA, &rectB); - _validateHasIntersectionResults(intersection, SDL_FALSE, &rectA, &rectB, &refRectA, &refRectB); - - /* Rect B empty */ - refRectA.x = SDLTest_RandomIntegerInRange(1, 100); - refRectA.y = SDLTest_RandomIntegerInRange(1, 100); - refRectA.w = SDLTest_RandomIntegerInRange(1, 100); - refRectA.h = SDLTest_RandomIntegerInRange(1, 100); - refRectB = refRectA; - refRectB.w = 0; - refRectB.h = 0; - rectA = refRectA; - rectB = refRectB; - intersection = SDL_HasIntersection(&rectA, &rectB); - _validateHasIntersectionResults(intersection, SDL_FALSE, &rectA, &rectB, &refRectA, &refRectB); - - /* Rect A and B empty */ - refRectA.x = SDLTest_RandomIntegerInRange(1, 100); - refRectA.y = SDLTest_RandomIntegerInRange(1, 100); - refRectA.w = SDLTest_RandomIntegerInRange(1, 100); - refRectA.h = SDLTest_RandomIntegerInRange(1, 100); - refRectB = refRectA; - refRectA.w = 0; - refRectA.h = 0; - refRectB.w = 0; - refRectB.h = 0; - rectA = refRectA; - rectB = refRectB; - intersection = SDL_HasIntersection(&rectA, &rectB); - _validateHasIntersectionResults(intersection, SDL_FALSE, &rectA, &rectB, &refRectA, &refRectB); - - return TEST_COMPLETED; -} - -/* ! - * \brief Negative tests against SDL_HasIntersection() with invalid parameters - * - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_HasIntersection - */ -int rect_testHasIntersectionParam(void *arg) -{ - SDL_Rect rectA; - SDL_Rect rectB; - SDL_bool intersection; - - /* invalid parameter combinations */ - intersection = SDL_HasIntersection((SDL_Rect *)NULL, &rectB); - SDLTest_AssertCheck(intersection == SDL_FALSE, "Check that function returns SDL_FALSE when 1st parameter is NULL"); - intersection = SDL_HasIntersection(&rectA, (SDL_Rect *)NULL); - SDLTest_AssertCheck(intersection == SDL_FALSE, "Check that function returns SDL_FALSE when 2st parameter is NULL"); - intersection = SDL_HasIntersection((SDL_Rect *)NULL, (SDL_Rect *)NULL); - SDLTest_AssertCheck(intersection == SDL_FALSE, "Check that function returns SDL_FALSE when all parameters are NULL"); - - return TEST_COMPLETED; -} - -/* ! - * \brief Test SDL_EnclosePoints() without clipping - * - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_EnclosePoints - */ -int rect_testEnclosePoints(void *arg) -{ - const int numPoints = 16; - SDL_Point refPoints[16]; - SDL_Point points[16]; - SDL_Rect result; - SDL_bool anyEnclosed; - SDL_bool anyEnclosedNoResult; - SDL_bool expectedEnclosed = SDL_TRUE; - int newx, newy; - int minx = 0, maxx = 0, miny = 0, maxy = 0; - int i; - - /* Create input data, tracking result */ - for (i=0; i maxx) maxx = newx; - if (newy < miny) miny = newy; - if (newy > maxy) maxy = newy; - } - } - - /* Call function and validate - special case: no result requested */ - anyEnclosedNoResult = SDL_EnclosePoints((const SDL_Point *)points, numPoints, (const SDL_Rect *)NULL, (SDL_Rect *)NULL); - SDLTest_AssertCheck(expectedEnclosed==anyEnclosedNoResult, - "Check expected return value %s, got %s", - (expectedEnclosed==SDL_TRUE) ? "SDL_TRUE" : "SDL_FALSE", - (anyEnclosedNoResult==SDL_TRUE) ? "SDL_TRUE" : "SDL_FALSE"); - for (i=0; i maxx) maxx = newx; - if (newy < miny) miny = newy; - if (newy > maxy) maxy = newy; - } - } - - /* Call function and validate - special case: no result requested */ - anyEnclosedNoResult = SDL_EnclosePoints((const SDL_Point *)points, numPoints, (const SDL_Rect *)NULL, (SDL_Rect *)NULL); - SDLTest_AssertCheck(expectedEnclosed==anyEnclosedNoResult, - "Check return value %s, got %s", - (expectedEnclosed==SDL_TRUE) ? "SDL_TRUE" : "SDL_FALSE", - (anyEnclosedNoResult==SDL_TRUE) ? "SDL_TRUE" : "SDL_FALSE"); - for (i=0; i=refClip.x) && (newx<(refClip.x + refClip.w)) && - (newy>=refClip.y) && (newy<(refClip.y + refClip.h))) { - if (expectedEnclosed==SDL_FALSE) { - minx = newx; - maxx = newx; - miny = newy; - maxy = newy; - } else { - if (newx < minx) minx = newx; - if (newx > maxx) maxx = newx; - if (newy < miny) miny = newy; - if (newy > maxy) maxy = newy; - } - expectedEnclosed = SDL_TRUE; - } - } - - /* Call function and validate - special case: no result requested */ - clip = refClip; - anyEnclosedNoResult = SDL_EnclosePoints((const SDL_Point *)points, numPoints, (const SDL_Rect *)&clip, (SDL_Rect *)NULL); - SDLTest_AssertCheck(expectedEnclosed==anyEnclosedNoResult, - "Expected return value %s, got %s", - (expectedEnclosed==SDL_TRUE) ? "SDL_TRUE" : "SDL_FALSE", - (anyEnclosedNoResult==SDL_TRUE) ? "SDL_TRUE" : "SDL_FALSE"); - for (i=0; irefRectB.x) ? refRectA.x : refRectB.x; - miny = (refRectA.yrefRectB.y) ? refRectA.y : refRectB.y; - expectedResult.x = minx; - expectedResult.y = miny; - expectedResult.w = maxx - minx + 1; - expectedResult.h = maxy - miny + 1; - rectA = refRectA; - rectB = refRectB; - SDL_UnionRect(&rectA, &rectB, &result); - _validateUnionRectResults(&rectA, &rectB, &refRectA, &refRectB, &result, &expectedResult); - } - } - } - - /* Union outside overlap */ - for (dx = -1; dx < 2; dx++) { - for (dy = -1; dy < 2; dy++) { - if ((dx != 0) || (dy != 0)) { - refRectA.x=SDLTest_RandomIntegerInRange(-1024, 1024); - refRectA.y=SDLTest_RandomIntegerInRange(-1024, 1024); - refRectA.w=SDLTest_RandomIntegerInRange(256, 512); - refRectA.h=SDLTest_RandomIntegerInRange(256, 512); - refRectB.x=refRectA.x + 1 + dx*2; - refRectB.y=refRectA.y + 1 + dy*2; - refRectB.w=refRectA.w - 2; - refRectB.h=refRectA.h - 2; - expectedResult = refRectA; - if (dx == -1) expectedResult.x--; - if (dy == -1) expectedResult.y--; - if ((dx == 1) || (dx == -1)) expectedResult.w++; - if ((dy == 1) || (dy == -1)) expectedResult.h++; - rectA = refRectA; - rectB = refRectB; - SDL_UnionRect(&rectA, &rectB, &result); - _validateUnionRectResults(&rectA, &rectB, &refRectA, &refRectB, &result, &expectedResult); - } - } - } - - return TEST_COMPLETED; -} - -/* ! - * \brief Tests SDL_UnionRect() where rect A or rect B are empty - * - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_UnionRect - */ -int rect_testUnionRectEmpty(void *arg) -{ - SDL_Rect refRectA, refRectB; - SDL_Rect rectA, rectB; - SDL_Rect expectedResult; - SDL_Rect result; - - /* A empty */ - refRectA.x=SDLTest_RandomIntegerInRange(-1024, 1024); - refRectA.y=SDLTest_RandomIntegerInRange(-1024, 1024); - refRectA.w=0; - refRectA.h=0; - refRectB.x=SDLTest_RandomIntegerInRange(-1024, 1024); - refRectB.y=SDLTest_RandomIntegerInRange(-1024, 1024); - refRectB.w=SDLTest_RandomIntegerInRange(1, 1024); - refRectB.h=SDLTest_RandomIntegerInRange(1, 1024); - expectedResult = refRectB; - rectA = refRectA; - rectB = refRectB; - SDL_UnionRect(&rectA, &rectB, &result); - _validateUnionRectResults(&rectA, &rectB, &refRectA, &refRectB, &result, &expectedResult); - - /* B empty */ - refRectA.x=SDLTest_RandomIntegerInRange(-1024, 1024); - refRectA.y=SDLTest_RandomIntegerInRange(-1024, 1024); - refRectA.w=SDLTest_RandomIntegerInRange(1, 1024); - refRectA.h=SDLTest_RandomIntegerInRange(1, 1024); - refRectB.x=SDLTest_RandomIntegerInRange(-1024, 1024); - refRectB.y=SDLTest_RandomIntegerInRange(-1024, 1024); - refRectB.w=0; - refRectB.h=0; - expectedResult = refRectA; - rectA = refRectA; - rectB = refRectB; - SDL_UnionRect(&rectA, &rectB, &result); - _validateUnionRectResults(&rectA, &rectB, &refRectA, &refRectB, &result, &expectedResult); - - /* A and B empty */ - refRectA.x=SDLTest_RandomIntegerInRange(-1024, 1024); - refRectA.y=SDLTest_RandomIntegerInRange(-1024, 1024); - refRectA.w=0; - refRectA.h=0; - refRectB.x=SDLTest_RandomIntegerInRange(-1024, 1024); - refRectB.y=SDLTest_RandomIntegerInRange(-1024, 1024); - refRectB.w=0; - refRectB.h=0; - result.x=0; - result.y=0; - result.w=0; - result.h=0; - expectedResult = result; - rectA = refRectA; - rectB = refRectB; - SDL_UnionRect(&rectA, &rectB, &result); - _validateUnionRectResults(&rectA, &rectB, &refRectA, &refRectB, &result, &expectedResult); - - return TEST_COMPLETED; -} - -/* ! - * \brief Tests SDL_UnionRect() where rect B is inside rect A - * - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_UnionRect - */ -int rect_testUnionRectInside(void *arg) -{ - SDL_Rect refRectA, refRectB; - SDL_Rect rectA, rectB; - SDL_Rect expectedResult; - SDL_Rect result; - int dx, dy; - - /* Union 1x1 with itself */ - refRectA.x=SDLTest_RandomIntegerInRange(-1024, 1024); - refRectA.y=SDLTest_RandomIntegerInRange(-1024, 1024); - refRectA.w=1; - refRectA.h=1; - expectedResult = refRectA; - rectA = refRectA; - SDL_UnionRect(&rectA, &rectA, &result); - _validateUnionRectResults(&rectA, &rectA, &refRectA, &refRectA, &result, &expectedResult); - - /* Union 1x1 somewhere inside */ - refRectA.x=SDLTest_RandomIntegerInRange(-1024, 1024); - refRectA.y=SDLTest_RandomIntegerInRange(-1024, 1024); - refRectA.w=SDLTest_RandomIntegerInRange(256, 1024); - refRectA.h=SDLTest_RandomIntegerInRange(256, 1024); - refRectB.x=refRectA.x + 1 + SDLTest_RandomIntegerInRange(1, refRectA.w - 2); - refRectB.y=refRectA.y + 1 + SDLTest_RandomIntegerInRange(1, refRectA.h - 2); - refRectB.w=1; - refRectB.h=1; - expectedResult = refRectA; - rectA = refRectA; - rectB = refRectB; - SDL_UnionRect(&rectA, &rectB, &result); - _validateUnionRectResults(&rectA, &rectB, &refRectA, &refRectB, &result, &expectedResult); - - /* Union inside with edges modified */ - for (dx = -1; dx < 2; dx++) { - for (dy = -1; dy < 2; dy++) { - if ((dx != 0) || (dy != 0)) { - refRectA.x=SDLTest_RandomIntegerInRange(-1024, 1024); - refRectA.y=SDLTest_RandomIntegerInRange(-1024, 1024); - refRectA.w=SDLTest_RandomIntegerInRange(256, 1024); - refRectA.h=SDLTest_RandomIntegerInRange(256, 1024); - refRectB = refRectA; - if (dx == -1) refRectB.x++; - if ((dx == 1) || (dx == -1)) refRectB.w--; - if (dy == -1) refRectB.y++; - if ((dy == 1) || (dy == -1)) refRectB.h--; - expectedResult = refRectA; - rectA = refRectA; - rectB = refRectB; - SDL_UnionRect(&rectA, &rectB, &result); - _validateUnionRectResults(&rectA, &rectB, &refRectA, &refRectB, &result, &expectedResult); - } - } - } - - return TEST_COMPLETED; -} - -/* ! - * \brief Negative tests against SDL_UnionRect() with invalid parameters - * - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_UnionRect - */ -int rect_testUnionRectParam(void *arg) -{ - SDL_Rect rectA, rectB; - SDL_Rect result; - - /* invalid parameter combinations */ - SDL_UnionRect((SDL_Rect *)NULL, &rectB, &result); - SDLTest_AssertPass("Check that function returns when 1st parameter is NULL"); - SDL_UnionRect(&rectA, (SDL_Rect *)NULL, &result); - SDLTest_AssertPass("Check that function returns when 2nd parameter is NULL"); - SDL_UnionRect(&rectA, &rectB, (SDL_Rect *)NULL); - SDLTest_AssertPass("Check that function returns when 3rd parameter is NULL"); - SDL_UnionRect((SDL_Rect *)NULL, &rectB, (SDL_Rect *)NULL); - SDLTest_AssertPass("Check that function returns when 1st and 3rd parameter are NULL"); - SDL_UnionRect(&rectA, (SDL_Rect *)NULL, (SDL_Rect *)NULL); - SDLTest_AssertPass("Check that function returns when 2nd and 3rd parameter are NULL"); - SDL_UnionRect((SDL_Rect *)NULL, (SDL_Rect *)NULL, (SDL_Rect *)NULL); - SDLTest_AssertPass("Check that function returns when all parameters are NULL"); - - return TEST_COMPLETED; -} - -/* ! - * \brief Tests SDL_RectEmpty() with various inputs - * - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_RectEmpty - */ -int rect_testRectEmpty(void *arg) -{ - SDL_Rect refRect; - SDL_Rect rect; - SDL_bool expectedResult; - SDL_bool result; - int w, h; - - /* Non-empty case */ - refRect.x=SDLTest_RandomIntegerInRange(-1024, 1024); - refRect.y=SDLTest_RandomIntegerInRange(-1024, 1024); - refRect.w=SDLTest_RandomIntegerInRange(256, 1024); - refRect.h=SDLTest_RandomIntegerInRange(256, 1024); - expectedResult = SDL_FALSE; - rect = refRect; - result = (SDL_bool)SDL_RectEmpty((const SDL_Rect *)&rect); - _validateRectEmptyResults(result, expectedResult, &rect, &refRect); - - /* Empty case */ - for (w=-1; w<2; w++) { - for (h=-1; h<2; h++) { - if ((w != 1) || (h != 1)) { - refRect.x=SDLTest_RandomIntegerInRange(-1024, 1024); - refRect.y=SDLTest_RandomIntegerInRange(-1024, 1024); - refRect.w=w; - refRect.h=h; - expectedResult = SDL_TRUE; - rect = refRect; - result = (SDL_bool)SDL_RectEmpty((const SDL_Rect *)&rect); - _validateRectEmptyResults(result, expectedResult, &rect, &refRect); - } - } - } - - return TEST_COMPLETED; -} - -/* ! - * \brief Negative tests against SDL_RectEmpty() with invalid parameters - * - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_RectEmpty - */ -int rect_testRectEmptyParam(void *arg) -{ - SDL_bool result; - - /* invalid parameter combinations */ - result = (SDL_bool)SDL_RectEmpty((const SDL_Rect *)NULL); - SDLTest_AssertCheck(result == SDL_TRUE, "Check that function returns TRUE when 1st parameter is NULL"); - - return TEST_COMPLETED; -} - -/* ! - * \brief Tests SDL_RectEquals() with various inputs - * - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_RectEquals - */ -int rect_testRectEquals(void *arg) -{ - SDL_Rect refRectA; - SDL_Rect refRectB; - SDL_Rect rectA; - SDL_Rect rectB; - SDL_bool expectedResult; - SDL_bool result; - - /* Equals */ - refRectA.x=SDLTest_RandomIntegerInRange(-1024, 1024); - refRectA.y=SDLTest_RandomIntegerInRange(-1024, 1024); - refRectA.w=SDLTest_RandomIntegerInRange(1, 1024); - refRectA.h=SDLTest_RandomIntegerInRange(1, 1024); - refRectB = refRectA; - expectedResult = SDL_TRUE; - rectA = refRectA; - rectB = refRectB; - result = (SDL_bool)SDL_RectEquals((const SDL_Rect *)&rectA, (const SDL_Rect *)&rectB); - _validateRectEqualsResults(result, expectedResult, &rectA, &rectB, &refRectA, &refRectB); - - return TEST_COMPLETED; -} - -/* ! - * \brief Negative tests against SDL_RectEquals() with invalid parameters - * - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_RectEquals - */ -int rect_testRectEqualsParam(void *arg) -{ - SDL_Rect rectA; - SDL_Rect rectB; - SDL_bool result; - - /* data setup */ - rectA.x=SDLTest_RandomIntegerInRange(-1024, 1024); - rectA.y=SDLTest_RandomIntegerInRange(-1024, 1024); - rectA.w=SDLTest_RandomIntegerInRange(1, 1024); - rectA.h=SDLTest_RandomIntegerInRange(1, 1024); - rectB.x=SDLTest_RandomIntegerInRange(-1024, 1024); - rectB.y=SDLTest_RandomIntegerInRange(-1024, 1024); - rectB.w=SDLTest_RandomIntegerInRange(1, 1024); - rectB.h=SDLTest_RandomIntegerInRange(1, 1024); - - /* invalid parameter combinations */ - result = (SDL_bool)SDL_RectEquals((const SDL_Rect *)NULL, (const SDL_Rect *)&rectB); - SDLTest_AssertCheck(result == SDL_FALSE, "Check that function returns SDL_FALSE when 1st parameter is NULL"); - result = (SDL_bool)SDL_RectEquals((const SDL_Rect *)&rectA, (const SDL_Rect *)NULL); - SDLTest_AssertCheck(result == SDL_FALSE, "Check that function returns SDL_FALSE when 2nd parameter is NULL"); - result = (SDL_bool)SDL_RectEquals((const SDL_Rect *)NULL, (const SDL_Rect *)NULL); - SDLTest_AssertCheck(result == SDL_FALSE, "Check that function returns SDL_FALSE when 1st and 2nd parameter are NULL"); - - return TEST_COMPLETED; -} - -/* ================= Test References ================== */ - -/* Rect test cases */ - -/* SDL_IntersectRectAndLine */ -static const SDLTest_TestCaseReference rectTest1 = - { (SDLTest_TestCaseFp)rect_testIntersectRectAndLine,"rect_testIntersectRectAndLine", "Tests SDL_IntersectRectAndLine clipping cases", TEST_ENABLED }; - -static const SDLTest_TestCaseReference rectTest2 = - { (SDLTest_TestCaseFp)rect_testIntersectRectAndLineInside, "rect_testIntersectRectAndLineInside", "Tests SDL_IntersectRectAndLine with line fully contained in rect", TEST_ENABLED }; - -static const SDLTest_TestCaseReference rectTest3 = - { (SDLTest_TestCaseFp)rect_testIntersectRectAndLineOutside, "rect_testIntersectRectAndLineOutside", "Tests SDL_IntersectRectAndLine with line fully outside of rect", TEST_ENABLED }; - -static const SDLTest_TestCaseReference rectTest4 = - { (SDLTest_TestCaseFp)rect_testIntersectRectAndLineEmpty, "rect_testIntersectRectAndLineEmpty", "Tests SDL_IntersectRectAndLine with empty rectangle ", TEST_ENABLED }; - -static const SDLTest_TestCaseReference rectTest5 = - { (SDLTest_TestCaseFp)rect_testIntersectRectAndLineParam, "rect_testIntersectRectAndLineParam", "Negative tests against SDL_IntersectRectAndLine with invalid parameters", TEST_ENABLED }; - -/* SDL_IntersectRect */ -static const SDLTest_TestCaseReference rectTest6 = - { (SDLTest_TestCaseFp)rect_testIntersectRectInside, "rect_testIntersectRectInside", "Tests SDL_IntersectRect with B fully contained in A", TEST_ENABLED }; - -static const SDLTest_TestCaseReference rectTest7 = - { (SDLTest_TestCaseFp)rect_testIntersectRectOutside, "rect_testIntersectRectOutside", "Tests SDL_IntersectRect with B fully outside of A", TEST_ENABLED }; - -static const SDLTest_TestCaseReference rectTest8 = - { (SDLTest_TestCaseFp)rect_testIntersectRectPartial, "rect_testIntersectRectPartial", "Tests SDL_IntersectRect with B partially intersecting A", TEST_ENABLED }; - -static const SDLTest_TestCaseReference rectTest9 = - { (SDLTest_TestCaseFp)rect_testIntersectRectPoint, "rect_testIntersectRectPoint", "Tests SDL_IntersectRect with 1x1 sized rectangles", TEST_ENABLED }; - -static const SDLTest_TestCaseReference rectTest10 = - { (SDLTest_TestCaseFp)rect_testIntersectRectEmpty, "rect_testIntersectRectEmpty", "Tests SDL_IntersectRect with empty rectangles", TEST_ENABLED }; - -static const SDLTest_TestCaseReference rectTest11 = - { (SDLTest_TestCaseFp)rect_testIntersectRectParam, "rect_testIntersectRectParam", "Negative tests against SDL_IntersectRect with invalid parameters", TEST_ENABLED }; - -/* SDL_HasIntersection */ -static const SDLTest_TestCaseReference rectTest12 = - { (SDLTest_TestCaseFp)rect_testHasIntersectionInside, "rect_testHasIntersectionInside", "Tests SDL_HasIntersection with B fully contained in A", TEST_ENABLED }; - -static const SDLTest_TestCaseReference rectTest13 = - { (SDLTest_TestCaseFp)rect_testHasIntersectionOutside, "rect_testHasIntersectionOutside", "Tests SDL_HasIntersection with B fully outside of A", TEST_ENABLED }; - -static const SDLTest_TestCaseReference rectTest14 = - { (SDLTest_TestCaseFp)rect_testHasIntersectionPartial,"rect_testHasIntersectionPartial", "Tests SDL_HasIntersection with B partially intersecting A", TEST_ENABLED }; - -static const SDLTest_TestCaseReference rectTest15 = - { (SDLTest_TestCaseFp)rect_testHasIntersectionPoint, "rect_testHasIntersectionPoint", "Tests SDL_HasIntersection with 1x1 sized rectangles", TEST_ENABLED }; - -static const SDLTest_TestCaseReference rectTest16 = - { (SDLTest_TestCaseFp)rect_testHasIntersectionEmpty, "rect_testHasIntersectionEmpty", "Tests SDL_HasIntersection with empty rectangles", TEST_ENABLED }; - -static const SDLTest_TestCaseReference rectTest17 = - { (SDLTest_TestCaseFp)rect_testHasIntersectionParam, "rect_testHasIntersectionParam", "Negative tests against SDL_HasIntersection with invalid parameters", TEST_ENABLED }; - -/* SDL_EnclosePoints */ -static const SDLTest_TestCaseReference rectTest18 = - { (SDLTest_TestCaseFp)rect_testEnclosePoints, "rect_testEnclosePoints", "Tests SDL_EnclosePoints without clipping", TEST_ENABLED }; - -static const SDLTest_TestCaseReference rectTest19 = - { (SDLTest_TestCaseFp)rect_testEnclosePointsWithClipping, "rect_testEnclosePointsWithClipping", "Tests SDL_EnclosePoints with clipping", TEST_ENABLED }; - -static const SDLTest_TestCaseReference rectTest20 = - { (SDLTest_TestCaseFp)rect_testEnclosePointsRepeatedInput, "rect_testEnclosePointsRepeatedInput", "Tests SDL_EnclosePoints with repeated input", TEST_ENABLED }; - -static const SDLTest_TestCaseReference rectTest21 = - { (SDLTest_TestCaseFp)rect_testEnclosePointsParam, "rect_testEnclosePointsParam", "Negative tests against SDL_EnclosePoints with invalid parameters", TEST_ENABLED }; - -/* SDL_UnionRect */ -static const SDLTest_TestCaseReference rectTest22 = - { (SDLTest_TestCaseFp)rect_testUnionRectInside, "rect_testUnionRectInside", "Tests SDL_UnionRect where rect B is inside rect A", TEST_ENABLED }; - -static const SDLTest_TestCaseReference rectTest23 = - { (SDLTest_TestCaseFp)rect_testUnionRectOutside, "rect_testUnionRectOutside", "Tests SDL_UnionRect where rect B is outside rect A", TEST_ENABLED }; - -static const SDLTest_TestCaseReference rectTest24 = - { (SDLTest_TestCaseFp)rect_testUnionRectEmpty, "rect_testUnionRectEmpty", "Tests SDL_UnionRect where rect A or rect B are empty", TEST_ENABLED }; - -static const SDLTest_TestCaseReference rectTest25 = - { (SDLTest_TestCaseFp)rect_testUnionRectParam, "rect_testUnionRectParam", "Negative tests against SDL_UnionRect with invalid parameters", TEST_ENABLED }; - -/* SDL_RectEmpty */ -static const SDLTest_TestCaseReference rectTest26 = - { (SDLTest_TestCaseFp)rect_testRectEmpty, "rect_testRectEmpty", "Tests SDL_RectEmpty with various inputs", TEST_ENABLED }; - -static const SDLTest_TestCaseReference rectTest27 = - { (SDLTest_TestCaseFp)rect_testRectEmptyParam, "rect_testRectEmptyParam", "Negative tests against SDL_RectEmpty with invalid parameters", TEST_ENABLED }; - -/* SDL_RectEquals */ - -static const SDLTest_TestCaseReference rectTest28 = - { (SDLTest_TestCaseFp)rect_testRectEquals, "rect_testRectEquals", "Tests SDL_RectEquals with various inputs", TEST_ENABLED }; - -static const SDLTest_TestCaseReference rectTest29 = - { (SDLTest_TestCaseFp)rect_testRectEqualsParam, "rect_testRectEqualsParam", "Negative tests against SDL_RectEquals with invalid parameters", TEST_ENABLED }; - - -/* ! - * \brief Sequence of Rect test cases; functions that handle simple rectangles including overlaps and merges. - * - * \sa - * http://wiki.libsdl.org/moin.cgi/CategoryRect - */ -static const SDLTest_TestCaseReference *rectTests[] = { - &rectTest1, &rectTest2, &rectTest3, &rectTest4, &rectTest5, &rectTest6, &rectTest7, &rectTest8, &rectTest9, &rectTest10, &rectTest11, &rectTest12, &rectTest13, &rectTest14, - &rectTest15, &rectTest16, &rectTest17, &rectTest18, &rectTest19, &rectTest20, &rectTest21, &rectTest22, &rectTest23, &rectTest24, &rectTest25, &rectTest26, &rectTest27, - &rectTest28, &rectTest29, NULL -}; - - -/* Rect test suite (global) */ -SDLTest_TestSuiteReference rectTestSuite = { - "Rect", - NULL, - rectTests, - NULL -}; diff --git a/SDL2-2.0.12/test/testautomation_render.c b/SDL2-2.0.12/test/testautomation_render.c deleted file mode 100644 index 5a1bc9b..0000000 --- a/SDL2-2.0.12/test/testautomation_render.c +++ /dev/null @@ -1,1099 +0,0 @@ -/** - * Original code: automated SDL platform test written by Edgar Simo "bobbens" - * Extended and extensively updated by aschiffler at ferzkopp dot net - */ - -#include - -#include "SDL.h" -#include "SDL_test.h" - -/* ================= Test Case Implementation ================== */ - -#define TESTRENDER_SCREEN_W 80 -#define TESTRENDER_SCREEN_H 60 - -#define RENDER_COMPARE_FORMAT SDL_PIXELFORMAT_ARGB8888 -#define RENDER_COMPARE_AMASK 0xff000000 /**< Alpha bit mask. */ -#define RENDER_COMPARE_RMASK 0x00ff0000 /**< Red bit mask. */ -#define RENDER_COMPARE_GMASK 0x0000ff00 /**< Green bit mask. */ -#define RENDER_COMPARE_BMASK 0x000000ff /**< Blue bit mask. */ - -#define ALLOWABLE_ERROR_OPAQUE 0 -#define ALLOWABLE_ERROR_BLENDED 64 - -/* Test window and renderer */ -SDL_Window *window = NULL; -SDL_Renderer *renderer = NULL; - -/* Prototypes for helper functions */ - -static int _clearScreen (void); -static void _compare(SDL_Surface *reference, int allowable_error); -static int _hasTexAlpha(void); -static int _hasTexColor(void); -static SDL_Texture *_loadTestFace(void); -static int _hasBlendModes(void); -static int _hasDrawColor(void); -static int _isSupported(int code); - -/** - * Create software renderer for tests - */ -void InitCreateRenderer(void *arg) -{ - int posX = 100, posY = 100, width = 320, height = 240; - renderer = NULL; - window = SDL_CreateWindow("render_testCreateRenderer", posX, posY, width, height, 0); - SDLTest_AssertPass("SDL_CreateWindow()"); - SDLTest_AssertCheck(window != NULL, "Check SDL_CreateWindow result"); - if (window == NULL) { - return; - } - - renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); - SDLTest_AssertPass("SDL_CreateRenderer()"); - SDLTest_AssertCheck(renderer != 0, "Check SDL_CreateRenderer result"); - if (renderer == NULL) { - SDL_DestroyWindow(window); - return; - } -} - -/* - * Destroy renderer for tests - */ -void CleanupDestroyRenderer(void *arg) -{ - if (renderer != NULL) { - SDL_DestroyRenderer(renderer); - renderer = NULL; - SDLTest_AssertPass("SDL_DestroyRenderer()"); - } - - if (window != NULL) { - SDL_DestroyWindow(window); - window = NULL; - SDLTest_AssertPass("SDL_DestroyWindow"); - } -} - - -/** - * @brief Tests call to SDL_GetNumRenderDrivers - * - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_GetNumRenderDrivers - */ -int -render_testGetNumRenderDrivers(void *arg) -{ - int n; - n = SDL_GetNumRenderDrivers(); - SDLTest_AssertCheck(n >= 1, "Number of renderers >= 1, reported as %i", n); - return TEST_COMPLETED; -} - - -/** - * @brief Tests the SDL primitives for rendering. - * - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_SetRenderDrawColor - * http://wiki.libsdl.org/moin.cgi/SDL_RenderFillRect - * http://wiki.libsdl.org/moin.cgi/SDL_RenderDrawLine - * - */ -int render_testPrimitives (void *arg) -{ - int ret; - int x, y; - SDL_Rect rect; - SDL_Surface *referenceSurface = NULL; - int checkFailCount1; - int checkFailCount2; - - /* Clear surface. */ - _clearScreen(); - - /* Need drawcolor or just skip test. */ - SDLTest_AssertCheck(_hasDrawColor(), "_hasDrawColor"); - - /* Draw a rectangle. */ - rect.x = 40; - rect.y = 0; - rect.w = 40; - rect.h = 80; - - ret = SDL_SetRenderDrawColor(renderer, 13, 73, 200, SDL_ALPHA_OPAQUE ); - SDLTest_AssertCheck(ret == 0, "Validate result from SDL_SetRenderDrawColor, expected: 0, got: %i", ret); - - ret = SDL_RenderFillRect(renderer, &rect ); - SDLTest_AssertCheck(ret == 0, "Validate result from SDL_RenderFillRect, expected: 0, got: %i", ret); - - /* Draw a rectangle. */ - rect.x = 10; - rect.y = 10; - rect.w = 60; - rect.h = 40; - ret = SDL_SetRenderDrawColor(renderer, 200, 0, 100, SDL_ALPHA_OPAQUE ); - SDLTest_AssertCheck(ret == 0, "Validate result from SDL_SetRenderDrawColor, expected: 0, got: %i", ret); - - ret = SDL_RenderFillRect(renderer, &rect ); - SDLTest_AssertCheck(ret == 0, "Validate result from SDL_RenderFillRect, expected: 0, got: %i", ret); - - /* Draw some points like so: - * X.X.X.X.. - * .X.X.X.X. - * X.X.X.X.. */ - checkFailCount1 = 0; - checkFailCount2 = 0; - for (y=0; y<3; y++) { - for (x = y % 2; x - -#include "SDL.h" -#include "SDL_test.h" - -/* ================= Test Case Implementation ================== */ - -const char* RWopsReadTestFilename = "rwops_read"; -const char* RWopsWriteTestFilename = "rwops_write"; -const char* RWopsAlphabetFilename = "rwops_alphabet"; - -static const char RWopsHelloWorldTestString[] = "Hello World!"; -static const char RWopsHelloWorldCompString[] = "Hello World!"; -static const char RWopsAlphabetString[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - -/* Fixture */ - -void -RWopsSetUp(void *arg) -{ - size_t fileLen; - FILE *handle; - size_t writtenLen; - int result; - - /* Clean up from previous runs (if any); ignore errors */ - remove(RWopsReadTestFilename); - remove(RWopsWriteTestFilename); - remove(RWopsAlphabetFilename); - - /* Create a test file */ - handle = fopen(RWopsReadTestFilename, "w"); - SDLTest_AssertCheck(handle != NULL, "Verify creation of file '%s' returned non NULL handle", RWopsReadTestFilename); - if (handle == NULL) return; - - /* Write some known text into it */ - fileLen = SDL_strlen(RWopsHelloWorldTestString); - writtenLen = fwrite(RWopsHelloWorldTestString, 1, fileLen, handle); - SDLTest_AssertCheck(fileLen == writtenLen, "Verify number of written bytes, expected %i, got %i", (int) fileLen, (int) writtenLen); - result = fclose(handle); - SDLTest_AssertCheck(result == 0, "Verify result from fclose, expected 0, got %i", result); - - /* Create a second test file */ - handle = fopen(RWopsAlphabetFilename, "w"); - SDLTest_AssertCheck(handle != NULL, "Verify creation of file '%s' returned non NULL handle", RWopsAlphabetFilename); - if (handle == NULL) return; - - /* Write alphabet text into it */ - fileLen = SDL_strlen(RWopsAlphabetString); - writtenLen = fwrite(RWopsAlphabetString, 1, fileLen, handle); - SDLTest_AssertCheck(fileLen == writtenLen, "Verify number of written bytes, expected %i, got %i", (int) fileLen, (int) writtenLen); - result = fclose(handle); - SDLTest_AssertCheck(result == 0, "Verify result from fclose, expected 0, got %i", result); - - SDLTest_AssertPass("Creation of test file completed"); -} - -void -RWopsTearDown(void *arg) -{ - int result; - - /* Remove the created files to clean up; ignore errors for write filename */ - result = remove(RWopsReadTestFilename); - SDLTest_AssertCheck(result == 0, "Verify result from remove(%s), expected 0, got %i", RWopsReadTestFilename, result); - remove(RWopsWriteTestFilename); - result = remove(RWopsAlphabetFilename); - SDLTest_AssertCheck(result == 0, "Verify result from remove(%s), expected 0, got %i", RWopsAlphabetFilename, result); - - SDLTest_AssertPass("Cleanup of test files completed"); -} - -/** - * @brief Makes sure parameters work properly. Local helper function. - * - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_RWseek - * http://wiki.libsdl.org/moin.cgi/SDL_RWread - */ -void -_testGenericRWopsValidations(SDL_RWops *rw, int write) -{ - char buf[sizeof(RWopsHelloWorldTestString)]; - Sint64 i; - size_t s; - int seekPos = SDLTest_RandomIntegerInRange(4, 8); - - /* Clear buffer */ - SDL_zeroa(buf); - - /* Set to start. */ - i = SDL_RWseek(rw, 0, RW_SEEK_SET ); - SDLTest_AssertPass("Call to SDL_RWseek succeeded"); - SDLTest_AssertCheck(i == (Sint64)0, "Verify seek to 0 with SDL_RWseek (RW_SEEK_SET), expected 0, got %"SDL_PRIs64, i); - - /* Test write. */ - s = SDL_RWwrite(rw, RWopsHelloWorldTestString, sizeof(RWopsHelloWorldTestString)-1, 1); - SDLTest_AssertPass("Call to SDL_RWwrite succeeded"); - if (write) { - SDLTest_AssertCheck(s == (size_t)1, "Verify result of writing one byte with SDL_RWwrite, expected 1, got %i", (int) s); - } - else { - SDLTest_AssertCheck(s == (size_t)0, "Verify result of writing with SDL_RWwrite, expected: 0, got %i", (int) s); - } - - /* Test seek to random position */ - i = SDL_RWseek( rw, seekPos, RW_SEEK_SET ); - SDLTest_AssertPass("Call to SDL_RWseek succeeded"); - SDLTest_AssertCheck(i == (Sint64)seekPos, "Verify seek to %i with SDL_RWseek (RW_SEEK_SET), expected %i, got %"SDL_PRIs64, seekPos, seekPos, i); - - /* Test seek back to start */ - i = SDL_RWseek(rw, 0, RW_SEEK_SET ); - SDLTest_AssertPass("Call to SDL_RWseek succeeded"); - SDLTest_AssertCheck(i == (Sint64)0, "Verify seek to 0 with SDL_RWseek (RW_SEEK_SET), expected 0, got %"SDL_PRIs64, i); - - /* Test read */ - s = SDL_RWread( rw, buf, 1, sizeof(RWopsHelloWorldTestString)-1 ); - SDLTest_AssertPass("Call to SDL_RWread succeeded"); - SDLTest_AssertCheck( - s == (size_t)(sizeof(RWopsHelloWorldTestString)-1), - "Verify result from SDL_RWread, expected %i, got %i", - (int) (sizeof(RWopsHelloWorldTestString)-1), - (int) s); - SDLTest_AssertCheck( - SDL_memcmp(buf, RWopsHelloWorldTestString, sizeof(RWopsHelloWorldTestString)-1 ) == 0, - "Verify read bytes match expected string, expected '%s', got '%s'", RWopsHelloWorldTestString, buf); - - /* More seek tests. */ - i = SDL_RWseek( rw, -4, RW_SEEK_CUR ); - SDLTest_AssertPass("Call to SDL_RWseek(...,-4,RW_SEEK_CUR) succeeded"); - SDLTest_AssertCheck( - i == (Sint64)(sizeof(RWopsHelloWorldTestString)-5), - "Verify seek to -4 with SDL_RWseek (RW_SEEK_CUR), expected %i, got %i", - (int) (sizeof(RWopsHelloWorldTestString)-5), - (int) i); - - i = SDL_RWseek( rw, -1, RW_SEEK_END ); - SDLTest_AssertPass("Call to SDL_RWseek(...,-1,RW_SEEK_END) succeeded"); - SDLTest_AssertCheck( - i == (Sint64)(sizeof(RWopsHelloWorldTestString)-2), - "Verify seek to -1 with SDL_RWseek (RW_SEEK_END), expected %i, got %i", - (int) (sizeof(RWopsHelloWorldTestString)-2), - (int) i); - - /* Invalid whence seek */ - i = SDL_RWseek( rw, 0, 999 ); - SDLTest_AssertPass("Call to SDL_RWseek(...,0,invalid_whence) succeeded"); - SDLTest_AssertCheck( - i == (Sint64)(-1), - "Verify seek with SDL_RWseek (invalid_whence); expected: -1, got %i", - (int) i); -} - -/* ! - * Negative test for SDL_RWFromFile parameters - * - * \sa http://wiki.libsdl.org/moin.cgi/SDL_RWFromFile - * - */ -int -rwops_testParamNegative (void) -{ - SDL_RWops *rwops; - - /* These should all fail. */ - rwops = SDL_RWFromFile(NULL, NULL); - SDLTest_AssertPass("Call to SDL_RWFromFile(NULL, NULL) succeeded"); - SDLTest_AssertCheck(rwops == NULL, "Verify SDL_RWFromFile(NULL, NULL) returns NULL"); - - rwops = SDL_RWFromFile(NULL, "ab+"); - SDLTest_AssertPass("Call to SDL_RWFromFile(NULL, \"ab+\") succeeded"); - SDLTest_AssertCheck(rwops == NULL, "Verify SDL_RWFromFile(NULL, \"ab+\") returns NULL"); - - rwops = SDL_RWFromFile(NULL, "sldfkjsldkfj"); - SDLTest_AssertPass("Call to SDL_RWFromFile(NULL, \"sldfkjsldkfj\") succeeded"); - SDLTest_AssertCheck(rwops == NULL, "Verify SDL_RWFromFile(NULL, \"sldfkjsldkfj\") returns NULL"); - - rwops = SDL_RWFromFile("something", ""); - SDLTest_AssertPass("Call to SDL_RWFromFile(\"something\", \"\") succeeded"); - SDLTest_AssertCheck(rwops == NULL, "Verify SDL_RWFromFile(\"something\", \"\") returns NULL"); - - rwops = SDL_RWFromFile("something", NULL); - SDLTest_AssertPass("Call to SDL_RWFromFile(\"something\", NULL) succeeded"); - SDLTest_AssertCheck(rwops == NULL, "Verify SDL_RWFromFile(\"something\", NULL) returns NULL"); - - rwops = SDL_RWFromMem((void *)NULL, 10); - SDLTest_AssertPass("Call to SDL_RWFromMem(NULL, 10) succeeded"); - SDLTest_AssertCheck(rwops == NULL, "Verify SDL_RWFromMem(NULL, 10) returns NULL"); - - rwops = SDL_RWFromMem((void *)RWopsAlphabetString, 0); - SDLTest_AssertPass("Call to SDL_RWFromMem(data, 0) succeeded"); - SDLTest_AssertCheck(rwops == NULL, "Verify SDL_RWFromMem(data, 0) returns NULL"); - - rwops = SDL_RWFromConstMem((const void *)RWopsAlphabetString, 0); - SDLTest_AssertPass("Call to SDL_RWFromConstMem(data, 0) succeeded"); - SDLTest_AssertCheck(rwops == NULL, "Verify SDL_RWFromConstMem(data, 0) returns NULL"); - - return TEST_COMPLETED; -} - -/** - * @brief Tests opening from memory. - * - * \sa http://wiki.libsdl.org/moin.cgi/SDL_RWFromMem - * \sa http://wiki.libsdl.org/moin.cgi/SDL_RWClose - */ -int -rwops_testMem (void) -{ - char mem[sizeof(RWopsHelloWorldTestString)]; - SDL_RWops *rw; - int result; - - /* Clear buffer */ - SDL_zeroa(mem); - - /* Open */ - rw = SDL_RWFromMem(mem, sizeof(RWopsHelloWorldTestString)-1); - SDLTest_AssertPass("Call to SDL_RWFromMem() succeeded"); - SDLTest_AssertCheck(rw != NULL, "Verify opening memory with SDL_RWFromMem does not return NULL"); - - /* Bail out if NULL */ - if (rw == NULL) return TEST_ABORTED; - - /* Check type */ - SDLTest_AssertCheck(rw->type == SDL_RWOPS_MEMORY, "Verify RWops type is SDL_RWOPS_MEMORY; expected: %d, got: %d", SDL_RWOPS_MEMORY, rw->type); - - /* Run generic tests */ - _testGenericRWopsValidations(rw, 1); - - /* Close */ - result = SDL_RWclose(rw); - SDLTest_AssertPass("Call to SDL_RWclose() succeeded"); - SDLTest_AssertCheck(result == 0, "Verify result value is 0; got: %d", result); - - return TEST_COMPLETED; -} - - -/** - * @brief Tests opening from memory. - * - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_RWFromConstMem - * http://wiki.libsdl.org/moin.cgi/SDL_RWClose - */ -int -rwops_testConstMem (void) -{ - SDL_RWops *rw; - int result; - - /* Open handle */ - rw = SDL_RWFromConstMem( RWopsHelloWorldCompString, sizeof(RWopsHelloWorldCompString)-1 ); - SDLTest_AssertPass("Call to SDL_RWFromConstMem() succeeded"); - SDLTest_AssertCheck(rw != NULL, "Verify opening memory with SDL_RWFromConstMem does not return NULL"); - - /* Bail out if NULL */ - if (rw == NULL) return TEST_ABORTED; - - /* Check type */ - SDLTest_AssertCheck(rw->type == SDL_RWOPS_MEMORY_RO, "Verify RWops type is SDL_RWOPS_MEMORY_RO; expected: %d, got: %d", SDL_RWOPS_MEMORY_RO, rw->type); - - /* Run generic tests */ - _testGenericRWopsValidations( rw, 0 ); - - /* Close handle */ - result = SDL_RWclose(rw); - SDLTest_AssertPass("Call to SDL_RWclose() succeeded"); - SDLTest_AssertCheck(result == 0, "Verify result value is 0; got: %d", result); - - return TEST_COMPLETED; -} - - -/** - * @brief Tests reading from file. - * - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_RWFromFile - * http://wiki.libsdl.org/moin.cgi/SDL_RWClose - */ -int -rwops_testFileRead(void) -{ - SDL_RWops *rw; - int result; - - /* Read test. */ - rw = SDL_RWFromFile(RWopsReadTestFilename, "r"); - SDLTest_AssertPass("Call to SDL_RWFromFile(..,\"r\") succeeded"); - SDLTest_AssertCheck(rw != NULL, "Verify opening file with SDL_RWFromFile in read mode does not return NULL"); - - /* Bail out if NULL */ - if (rw == NULL) return TEST_ABORTED; - - /* Check type */ -#if defined(__ANDROID__) - SDLTest_AssertCheck( - rw->type == SDL_RWOPS_STDFILE || rw->type == SDL_RWOPS_JNIFILE, - "Verify RWops type is SDL_RWOPS_STDFILE or SDL_RWOPS_JNIFILE; expected: %d|%d, got: %d", SDL_RWOPS_STDFILE, SDL_RWOPS_JNIFILE, rw->type); -#elif defined(__WIN32__) - SDLTest_AssertCheck( - rw->type == SDL_RWOPS_WINFILE, - "Verify RWops type is SDL_RWOPS_WINFILE; expected: %d, got: %d", SDL_RWOPS_WINFILE, rw->type); -#else - SDLTest_AssertCheck( - rw->type == SDL_RWOPS_STDFILE, - "Verify RWops type is SDL_RWOPS_STDFILE; expected: %d, got: %d", SDL_RWOPS_STDFILE, rw->type); -#endif - - /* Run generic tests */ - _testGenericRWopsValidations( rw, 0 ); - - /* Close handle */ - result = SDL_RWclose(rw); - SDLTest_AssertPass("Call to SDL_RWclose() succeeded"); - SDLTest_AssertCheck(result == 0, "Verify result value is 0; got: %d", result); - - return TEST_COMPLETED; -} - -/** - * @brief Tests writing from file. - * - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_RWFromFile - * http://wiki.libsdl.org/moin.cgi/SDL_RWClose - */ -int -rwops_testFileWrite(void) -{ - SDL_RWops *rw; - int result; - - /* Write test. */ - rw = SDL_RWFromFile(RWopsWriteTestFilename, "w+"); - SDLTest_AssertPass("Call to SDL_RWFromFile(..,\"w+\") succeeded"); - SDLTest_AssertCheck(rw != NULL, "Verify opening file with SDL_RWFromFile in write mode does not return NULL"); - - /* Bail out if NULL */ - if (rw == NULL) return TEST_ABORTED; - - /* Check type */ -#if defined(__ANDROID__) - SDLTest_AssertCheck( - rw->type == SDL_RWOPS_STDFILE || rw->type == SDL_RWOPS_JNIFILE, - "Verify RWops type is SDL_RWOPS_STDFILE or SDL_RWOPS_JNIFILE; expected: %d|%d, got: %d", SDL_RWOPS_STDFILE, SDL_RWOPS_JNIFILE, rw->type); -#elif defined(__WIN32__) - SDLTest_AssertCheck( - rw->type == SDL_RWOPS_WINFILE, - "Verify RWops type is SDL_RWOPS_WINFILE; expected: %d, got: %d", SDL_RWOPS_WINFILE, rw->type); -#else - SDLTest_AssertCheck( - rw->type == SDL_RWOPS_STDFILE, - "Verify RWops type is SDL_RWOPS_STDFILE; expected: %d, got: %d", SDL_RWOPS_STDFILE, rw->type); -#endif - - /* Run generic tests */ - _testGenericRWopsValidations( rw, 1 ); - - /* Close handle */ - result = SDL_RWclose(rw); - SDLTest_AssertPass("Call to SDL_RWclose() succeeded"); - SDLTest_AssertCheck(result == 0, "Verify result value is 0; got: %d", result); - - return TEST_COMPLETED; -} - - -/** - * @brief Tests reading from file handle - * - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_RWFromFP - * http://wiki.libsdl.org/moin.cgi/SDL_RWClose - * - */ -int -rwops_testFPRead(void) -{ - FILE *fp; - SDL_RWops *rw; - int result; - - /* Run read tests. */ - fp = fopen(RWopsReadTestFilename, "r"); - SDLTest_AssertCheck(fp != NULL, "Verify handle from opening file '%s' in read mode is not NULL", RWopsReadTestFilename); - - /* Bail out if NULL */ - if (fp == NULL) return TEST_ABORTED; - - /* Open */ - rw = SDL_RWFromFP( fp, SDL_TRUE ); - SDLTest_AssertPass("Call to SDL_RWFromFP() succeeded"); - SDLTest_AssertCheck(rw != NULL, "Verify opening file with SDL_RWFromFP in read mode does not return NULL"); - - /* Bail out if NULL */ - if (rw == NULL) { - fclose(fp); - return TEST_ABORTED; - } - - /* Check type */ - SDLTest_AssertCheck( - rw->type == SDL_RWOPS_STDFILE, - "Verify RWops type is SDL_RWOPS_STDFILE; expected: %d, got: %d", SDL_RWOPS_STDFILE, rw->type); - - /* Run generic tests */ - _testGenericRWopsValidations( rw, 0 ); - - /* Close handle - does fclose() */ - result = SDL_RWclose(rw); - SDLTest_AssertPass("Call to SDL_RWclose() succeeded"); - SDLTest_AssertCheck(result == 0, "Verify result value is 0; got: %d", result); - - return TEST_COMPLETED; -} - - -/** - * @brief Tests writing to file handle - * - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_RWFromFP - * http://wiki.libsdl.org/moin.cgi/SDL_RWClose - * - */ -int -rwops_testFPWrite(void) -{ - FILE *fp; - SDL_RWops *rw; - int result; - - /* Run write tests. */ - fp = fopen(RWopsWriteTestFilename, "w+"); - SDLTest_AssertCheck(fp != NULL, "Verify handle from opening file '%s' in write mode is not NULL", RWopsWriteTestFilename); - - /* Bail out if NULL */ - if (fp == NULL) return TEST_ABORTED; - - /* Open */ - rw = SDL_RWFromFP( fp, SDL_TRUE ); - SDLTest_AssertPass("Call to SDL_RWFromFP() succeeded"); - SDLTest_AssertCheck(rw != NULL, "Verify opening file with SDL_RWFromFP in write mode does not return NULL"); - - /* Bail out if NULL */ - if (rw == NULL) { - fclose(fp); - return TEST_ABORTED; - } - - /* Check type */ - SDLTest_AssertCheck( - rw->type == SDL_RWOPS_STDFILE, - "Verify RWops type is SDL_RWOPS_STDFILE; expected: %d, got: %d", SDL_RWOPS_STDFILE, rw->type); - - /* Run generic tests */ - _testGenericRWopsValidations( rw, 1 ); - - /* Close handle - does fclose() */ - result = SDL_RWclose(rw); - SDLTest_AssertPass("Call to SDL_RWclose() succeeded"); - SDLTest_AssertCheck(result == 0, "Verify result value is 0; got: %d", result); - - return TEST_COMPLETED; -} - -/** - * @brief Tests alloc and free RW context. - * - * \sa http://wiki.libsdl.org/moin.cgi/SDL_AllocRW - * \sa http://wiki.libsdl.org/moin.cgi/SDL_FreeRW - */ -int -rwops_testAllocFree (void) -{ - /* Allocate context */ - SDL_RWops *rw = SDL_AllocRW(); - SDLTest_AssertPass("Call to SDL_AllocRW() succeeded"); - SDLTest_AssertCheck(rw != NULL, "Validate result from SDL_AllocRW() is not NULL"); - if (rw==NULL) return TEST_ABORTED; - - /* Check type */ - SDLTest_AssertCheck( - rw->type == SDL_RWOPS_UNKNOWN, - "Verify RWops type is SDL_RWOPS_UNKNOWN; expected: %d, got: %d", SDL_RWOPS_UNKNOWN, rw->type); - - /* Free context again */ - SDL_FreeRW(rw); - SDLTest_AssertPass("Call to SDL_FreeRW() succeeded"); - - return TEST_COMPLETED; -} - -/** - * @brief Compare memory and file reads - * - * \sa http://wiki.libsdl.org/moin.cgi/SDL_RWFromMem - * \sa http://wiki.libsdl.org/moin.cgi/SDL_RWFromFile - */ -int -rwops_testCompareRWFromMemWithRWFromFile(void) -{ - int slen = 26; - char buffer_file[27]; - char buffer_mem[27]; - size_t rv_file; - size_t rv_mem; - Uint64 sv_file; - Uint64 sv_mem; - SDL_RWops* rwops_file; - SDL_RWops* rwops_mem; - int size; - int result; - - - for (size=5; size<10; size++) - { - /* Terminate buffer */ - buffer_file[slen] = 0; - buffer_mem[slen] = 0; - - /* Read/seek from memory */ - rwops_mem = SDL_RWFromMem((void *)RWopsAlphabetString, slen); - SDLTest_AssertPass("Call to SDL_RWFromMem()"); - rv_mem = SDL_RWread(rwops_mem, buffer_mem, size, 6); - SDLTest_AssertPass("Call to SDL_RWread(mem, size=%d)", size); - sv_mem = SDL_RWseek(rwops_mem, 0, SEEK_END); - SDLTest_AssertPass("Call to SDL_RWseek(mem,SEEK_END)"); - result = SDL_RWclose(rwops_mem); - SDLTest_AssertPass("Call to SDL_RWclose(mem)"); - SDLTest_AssertCheck(result == 0, "Verify result value is 0; got: %d", result); - - /* Read/see from file */ - rwops_file = SDL_RWFromFile(RWopsAlphabetFilename, "r"); - SDLTest_AssertPass("Call to SDL_RWFromFile()"); - rv_file = SDL_RWread(rwops_file, buffer_file, size, 6); - SDLTest_AssertPass("Call to SDL_RWread(file, size=%d)", size); - sv_file = SDL_RWseek(rwops_file, 0, SEEK_END); - SDLTest_AssertPass("Call to SDL_RWseek(file,SEEK_END)"); - result = SDL_RWclose(rwops_file); - SDLTest_AssertPass("Call to SDL_RWclose(file)"); - SDLTest_AssertCheck(result == 0, "Verify result value is 0; got: %d", result); - - /* Compare */ - SDLTest_AssertCheck(rv_mem == rv_file, "Verify returned read blocks matches for mem and file reads; got: rv_mem=%d rv_file=%d", (int) rv_mem, (int) rv_file); - SDLTest_AssertCheck(sv_mem == sv_file, "Verify SEEK_END position matches for mem and file seeks; got: sv_mem=%d sv_file=%d", (int) sv_mem, (int) sv_file); - SDLTest_AssertCheck(buffer_mem[slen] == 0, "Verify mem buffer termination; expected: 0, got: %d", buffer_mem[slen]); - SDLTest_AssertCheck(buffer_file[slen] == 0, "Verify file buffer termination; expected: 0, got: %d", buffer_file[slen]); - SDLTest_AssertCheck( - SDL_strncmp(buffer_mem, RWopsAlphabetString, slen) == 0, - "Verify mem buffer contain alphabet string; expected: %s, got: %s", RWopsAlphabetString, buffer_mem); - SDLTest_AssertCheck( - SDL_strncmp(buffer_file, RWopsAlphabetString, slen) == 0, - "Verify file buffer contain alphabet string; expected: %s, got: %s", RWopsAlphabetString, buffer_file); - } - - return TEST_COMPLETED; -} - -/** - * @brief Tests writing and reading from file using endian aware functions. - * - * \sa - * http://wiki.libsdl.org/moin.cgi/SDL_RWFromFile - * http://wiki.libsdl.org/moin.cgi/SDL_RWClose - * http://wiki.libsdl.org/moin.cgi/SDL_ReadBE16 - * http://wiki.libsdl.org/moin.cgi/SDL_WriteBE16 - */ -int -rwops_testFileWriteReadEndian(void) -{ - SDL_RWops *rw; - Sint64 result; - int mode; - size_t objectsWritten; - Uint16 BE16value; - Uint32 BE32value; - Uint64 BE64value; - Uint16 LE16value; - Uint32 LE32value; - Uint64 LE64value; - Uint16 BE16test; - Uint32 BE32test; - Uint64 BE64test; - Uint16 LE16test; - Uint32 LE32test; - Uint64 LE64test; - int cresult; - - for (mode = 0; mode < 3; mode++) { - - /* Create test data */ - switch (mode) { - case 0: - SDLTest_Log("All 0 values"); - BE16value = 0; - BE32value = 0; - BE64value = 0; - LE16value = 0; - LE32value = 0; - LE64value = 0; - break; - case 1: - SDLTest_Log("All 1 values"); - BE16value = 1; - BE32value = 1; - BE64value = 1; - LE16value = 1; - LE32value = 1; - LE64value = 1; - break; - case 2: - SDLTest_Log("Random values"); - BE16value = SDLTest_RandomUint16(); - BE32value = SDLTest_RandomUint32(); - BE64value = SDLTest_RandomUint64(); - LE16value = SDLTest_RandomUint16(); - LE32value = SDLTest_RandomUint32(); - LE64value = SDLTest_RandomUint64(); - break; - } - - /* Write test. */ - rw = SDL_RWFromFile(RWopsWriteTestFilename, "w+"); - SDLTest_AssertPass("Call to SDL_RWFromFile(..,\"w+\")"); - SDLTest_AssertCheck(rw != NULL, "Verify opening file with SDL_RWFromFile in write mode does not return NULL"); - - /* Bail out if NULL */ - if (rw == NULL) return TEST_ABORTED; - - /* Write test data */ - objectsWritten = SDL_WriteBE16(rw, BE16value); - SDLTest_AssertPass("Call to SDL_WriteBE16()"); - SDLTest_AssertCheck(objectsWritten == 1, "Validate number of objects written, expected: 1, got: %i", (int) objectsWritten); - objectsWritten = SDL_WriteBE32(rw, BE32value); - SDLTest_AssertPass("Call to SDL_WriteBE32()"); - SDLTest_AssertCheck(objectsWritten == 1, "Validate number of objects written, expected: 1, got: %i", (int) objectsWritten); - objectsWritten = SDL_WriteBE64(rw, BE64value); - SDLTest_AssertPass("Call to SDL_WriteBE64()"); - SDLTest_AssertCheck(objectsWritten == 1, "Validate number of objects written, expected: 1, got: %i", (int) objectsWritten); - objectsWritten = SDL_WriteLE16(rw, LE16value); - SDLTest_AssertPass("Call to SDL_WriteLE16()"); - SDLTest_AssertCheck(objectsWritten == 1, "Validate number of objects written, expected: 1, got: %i", (int) objectsWritten); - objectsWritten = SDL_WriteLE32(rw, LE32value); - SDLTest_AssertPass("Call to SDL_WriteLE32()"); - SDLTest_AssertCheck(objectsWritten == 1, "Validate number of objects written, expected: 1, got: %i", (int) objectsWritten); - objectsWritten = SDL_WriteLE64(rw, LE64value); - SDLTest_AssertPass("Call to SDL_WriteLE64()"); - SDLTest_AssertCheck(objectsWritten == 1, "Validate number of objects written, expected: 1, got: %i", (int) objectsWritten); - - /* Test seek to start */ - result = SDL_RWseek( rw, 0, RW_SEEK_SET ); - SDLTest_AssertPass("Call to SDL_RWseek succeeded"); - SDLTest_AssertCheck(result == 0, "Verify result from position 0 with SDL_RWseek, expected 0, got %i", (int) result); - - /* Read test data */ - BE16test = SDL_ReadBE16(rw); - SDLTest_AssertPass("Call to SDL_ReadBE16()"); - SDLTest_AssertCheck(BE16test == BE16value, "Validate return value from SDL_ReadBE16, expected: %hu, got: %hu", BE16value, BE16test); - BE32test = SDL_ReadBE32(rw); - SDLTest_AssertPass("Call to SDL_ReadBE32()"); - SDLTest_AssertCheck(BE32test == BE32value, "Validate return value from SDL_ReadBE32, expected: %u, got: %u", BE32value, BE32test); - BE64test = SDL_ReadBE64(rw); - SDLTest_AssertPass("Call to SDL_ReadBE64()"); - SDLTest_AssertCheck(BE64test == BE64value, "Validate return value from SDL_ReadBE64, expected: %"SDL_PRIu64", got: %"SDL_PRIu64, BE64value, BE64test); - LE16test = SDL_ReadLE16(rw); - SDLTest_AssertPass("Call to SDL_ReadLE16()"); - SDLTest_AssertCheck(LE16test == LE16value, "Validate return value from SDL_ReadLE16, expected: %hu, got: %hu", LE16value, LE16test); - LE32test = SDL_ReadLE32(rw); - SDLTest_AssertPass("Call to SDL_ReadLE32()"); - SDLTest_AssertCheck(LE32test == LE32value, "Validate return value from SDL_ReadLE32, expected: %u, got: %u", LE32value, LE32test); - LE64test = SDL_ReadLE64(rw); - SDLTest_AssertPass("Call to SDL_ReadLE64()"); - SDLTest_AssertCheck(LE64test == LE64value, "Validate return value from SDL_ReadLE64, expected: %"SDL_PRIu64", got: %"SDL_PRIu64, LE64value, LE64test); - - /* Close handle */ - cresult = SDL_RWclose(rw); - SDLTest_AssertPass("Call to SDL_RWclose() succeeded"); - SDLTest_AssertCheck(cresult == 0, "Verify result value is 0; got: %d", cresult); - } - - return TEST_COMPLETED; -} - - -/* ================= Test References ================== */ - -/* RWops test cases */ -static const SDLTest_TestCaseReference rwopsTest1 = - { (SDLTest_TestCaseFp)rwops_testParamNegative, "rwops_testParamNegative", "Negative test for SDL_RWFromFile parameters", TEST_ENABLED }; - -static const SDLTest_TestCaseReference rwopsTest2 = - { (SDLTest_TestCaseFp)rwops_testMem, "rwops_testMem", "Tests opening from memory", TEST_ENABLED }; - -static const SDLTest_TestCaseReference rwopsTest3 = - { (SDLTest_TestCaseFp)rwops_testConstMem, "rwops_testConstMem", "Tests opening from (const) memory", TEST_ENABLED }; - -static const SDLTest_TestCaseReference rwopsTest4 = - { (SDLTest_TestCaseFp)rwops_testFileRead, "rwops_testFileRead", "Tests reading from a file", TEST_ENABLED }; - -static const SDLTest_TestCaseReference rwopsTest5 = - { (SDLTest_TestCaseFp)rwops_testFileWrite, "rwops_testFileWrite", "Test writing to a file", TEST_ENABLED }; - -static const SDLTest_TestCaseReference rwopsTest6 = - { (SDLTest_TestCaseFp)rwops_testFPRead, "rwops_testFPRead", "Test reading from file pointer", TEST_ENABLED }; - -static const SDLTest_TestCaseReference rwopsTest7 = - { (SDLTest_TestCaseFp)rwops_testFPWrite, "rwops_testFPWrite", "Test writing to file pointer", TEST_ENABLED }; - -static const SDLTest_TestCaseReference rwopsTest8 = - { (SDLTest_TestCaseFp)rwops_testAllocFree, "rwops_testAllocFree", "Test alloc and free of RW context", TEST_ENABLED }; - -static const SDLTest_TestCaseReference rwopsTest9 = - { (SDLTest_TestCaseFp)rwops_testFileWriteReadEndian, "rwops_testFileWriteReadEndian", "Test writing and reading via the Endian aware functions", TEST_ENABLED }; - -static const SDLTest_TestCaseReference rwopsTest10 = - { (SDLTest_TestCaseFp)rwops_testCompareRWFromMemWithRWFromFile, "rwops_testCompareRWFromMemWithRWFromFile", "Compare RWFromMem and RWFromFile RWops for read and seek", TEST_ENABLED }; - -/* Sequence of RWops test cases */ -static const SDLTest_TestCaseReference *rwopsTests[] = { - &rwopsTest1, &rwopsTest2, &rwopsTest3, &rwopsTest4, &rwopsTest5, &rwopsTest6, - &rwopsTest7, &rwopsTest8, &rwopsTest9, &rwopsTest10, NULL -}; - -/* RWops test suite (global) */ -SDLTest_TestSuiteReference rwopsTestSuite = { - "RWops", - RWopsSetUp, - rwopsTests, - RWopsTearDown -}; diff --git a/SDL2-2.0.12/test/testautomation_sdltest.c b/SDL2-2.0.12/test/testautomation_sdltest.c deleted file mode 100644 index 979756a..0000000 --- a/SDL2-2.0.12/test/testautomation_sdltest.c +++ /dev/null @@ -1,1319 +0,0 @@ -/** - * SDL_test test suite - */ - -#include -/* Visual Studio 2008 doesn't have stdint.h */ -#if defined(_MSC_VER) && _MSC_VER <= 1500 -#define UINT8_MAX _UI8_MAX -#define UINT16_MAX _UI16_MAX -#define UINT32_MAX _UI32_MAX -#define INT64_MIN _I64_MIN -#define INT64_MAX _I64_MAX -#define UINT64_MAX _UI64_MAX -#else -#include -#endif - -#include -#include -#include - -#include "SDL.h" -#include "SDL_test.h" - -/* Test case functions */ - -/* Forward declarations for internal harness functions */ -extern char *SDLTest_GenerateRunSeed(const int length); - -/** - * @brief Calls to SDLTest_GenerateRunSeed() - */ -int -sdltest_generateRunSeed(void *arg) -{ - char* result; - size_t i, l; - int j; - - for (i = 1; i <= 10; i += 3) { - result = SDLTest_GenerateRunSeed((const int)i); - SDLTest_AssertPass("Call to SDLTest_GenerateRunSeed()"); - SDLTest_AssertCheck(result != NULL, "Verify returned value is not NULL"); - if (result != NULL) { - l = SDL_strlen(result); - SDLTest_AssertCheck(l == i, "Verify length of returned value is %d, got: %d", (int) i, (int) l); - SDL_free(result); - } - } - - /* Negative cases */ - for (j = -2; j <= 0; j++) { - result = SDLTest_GenerateRunSeed((const int)j); - SDLTest_AssertPass("Call to SDLTest_GenerateRunSeed()"); - SDLTest_AssertCheck(result == NULL, "Verify returned value is not NULL"); - } - - return TEST_COMPLETED; -} - -/** - * @brief Calls to SDLTest_GetFuzzerInvocationCount() - */ -int -sdltest_getFuzzerInvocationCount(void *arg) -{ - Uint8 result; - int fuzzerCount1, fuzzerCount2; - - fuzzerCount1 = SDLTest_GetFuzzerInvocationCount(); - SDLTest_AssertPass("Call to SDLTest_GetFuzzerInvocationCount()"); - SDLTest_AssertCheck(fuzzerCount1 >= 0, "Verify returned value, expected: >=0, got: %d", fuzzerCount1); - - result = SDLTest_RandomUint8(); - SDLTest_AssertPass("Call to SDLTest_RandomUint8(), returned %d", result); - - fuzzerCount2 = SDLTest_GetFuzzerInvocationCount(); - SDLTest_AssertPass("Call to SDLTest_GetFuzzerInvocationCount()"); - SDLTest_AssertCheck(fuzzerCount2 > fuzzerCount1, "Verify returned value, expected: >%d, got: %d", fuzzerCount1, fuzzerCount2); - - return TEST_COMPLETED; -} - - -/** - * @brief Calls to random number generators - */ -int -sdltest_randomNumber(void *arg) -{ - Sint64 result; - Uint64 uresult; - double dresult; - Uint64 umax; - Sint64 min, max; - - result = (Sint64)SDLTest_RandomUint8(); - umax = (1 << 8) - 1; - SDLTest_AssertPass("Call to SDLTest_RandomUint8"); - SDLTest_AssertCheck(result >= 0 && result <= (Sint64)umax, "Verify result value, expected: [0,%"SDL_PRIu64"], got: %"SDL_PRIs64, umax, result); - - result = (Sint64)SDLTest_RandomSint8(); - min = 0 - (1 << 7); - max = (1 << 7) - 1; - SDLTest_AssertPass("Call to SDLTest_RandomSint8"); - SDLTest_AssertCheck(result >= min && result <= max, "Verify result value, expected: [%"SDL_PRIs64",%"SDL_PRIs64"], got: %"SDL_PRIs64, min, max, result); - - result = (Sint64)SDLTest_RandomUint16(); - umax = (1 << 16) - 1; - SDLTest_AssertPass("Call to SDLTest_RandomUint16"); - SDLTest_AssertCheck(result >= 0 && result <= (Sint64)umax, "Verify result value, expected: [0,%"SDL_PRIu64"], got: %"SDL_PRIs64, umax, result); - - result = (Sint64)SDLTest_RandomSint16(); - min = 0 - (1 << 15); - max = (1 << 15) - 1; - SDLTest_AssertPass("Call to SDLTest_RandomSint16"); - SDLTest_AssertCheck(result >= min && result <= max, "Verify result value, expected: [%"SDL_PRIs64",%"SDL_PRIs64"], got: %"SDL_PRIs64, min, max, result); - - result = (Sint64)SDLTest_RandomUint32(); - umax = ((Uint64)1 << 32) - 1; - SDLTest_AssertPass("Call to SDLTest_RandomUint32"); - SDLTest_AssertCheck(result >= 0 && result <= (Sint64)umax, "Verify result value, expected: [0,%"SDL_PRIu64"], got: %"SDL_PRIs64, umax, result); - - result = (Sint64)SDLTest_RandomSint32(); - min = 0 - ((Sint64)1 << 31); - max = ((Sint64)1 << 31) - 1; - SDLTest_AssertPass("Call to SDLTest_RandomSint32"); - SDLTest_AssertCheck(result >= min && result <= max, "Verify result value, expected: [%"SDL_PRIs64",%"SDL_PRIs64"], got: %"SDL_PRIs64, min, max, result); - - uresult = SDLTest_RandomUint64(); - SDLTest_AssertPass("Call to SDLTest_RandomUint64"); - - result = SDLTest_RandomSint64(); - SDLTest_AssertPass("Call to SDLTest_RandomSint64"); - - dresult = (double)SDLTest_RandomUnitFloat(); - SDLTest_AssertPass("Call to SDLTest_RandomUnitFloat"); - SDLTest_AssertCheck(dresult >= 0.0 && dresult < 1.0, "Verify result value, expected: [0.0,1.0[, got: %e", dresult); - - dresult = (double)SDLTest_RandomFloat(); - SDLTest_AssertPass("Call to SDLTest_RandomFloat"); - SDLTest_AssertCheck(dresult >= (double)(-FLT_MAX) && dresult <= (double)FLT_MAX, "Verify result value, expected: [%e,%e], got: %e", (double)(-FLT_MAX), (double)FLT_MAX, dresult); - - dresult = (double)SDLTest_RandomUnitDouble(); - SDLTest_AssertPass("Call to SDLTest_RandomUnitDouble"); - SDLTest_AssertCheck(dresult >= 0.0 && dresult < 1.0, "Verify result value, expected: [0.0,1.0[, got: %e", dresult); - - dresult = SDLTest_RandomDouble(); - SDLTest_AssertPass("Call to SDLTest_RandomDouble"); - - return TEST_COMPLETED; -} - -/* - * @brief Calls to random boundary number generators for Uint8 - */ -int -sdltest_randomBoundaryNumberUint8(void *arg) -{ - const char *expectedError = "That operation is not supported"; - char *lastError; - Uint64 uresult; - - /* Clean error messages */ - SDL_ClearError(); - SDLTest_AssertPass("SDL_ClearError()"); - - /* RandomUintXBoundaryValue(10, 10, SDL_TRUE) returns 10 */ - uresult = (Uint64)SDLTest_RandomUint8BoundaryValue(10, 10, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomUint8BoundaryValue"); - SDLTest_AssertCheck( - uresult == 10, - "Validate result value for parameters (10,10,SDL_TRUE); expected: 10, got: %"SDL_PRIs64, uresult); - - /* RandomUintXBoundaryValue(10, 11, SDL_TRUE) returns 10, 11 */ - uresult = (Uint64)SDLTest_RandomUint8BoundaryValue(10, 11, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomUint8BoundaryValue"); - SDLTest_AssertCheck( - uresult == 10 || uresult == 11, - "Validate result value for parameters (10,11,SDL_TRUE); expected: 10|11, got: %"SDL_PRIs64, uresult); - - /* RandomUintXBoundaryValue(10, 12, SDL_TRUE) returns 10, 11, 12 */ - uresult = (Uint64)SDLTest_RandomUint8BoundaryValue(10, 12, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomUint8BoundaryValue"); - SDLTest_AssertCheck( - uresult == 10 || uresult == 11 || uresult == 12, - "Validate result value for parameters (10,12,SDL_TRUE); expected: 10|11|12, got: %"SDL_PRIs64, uresult); - - /* RandomUintXBoundaryValue(10, 13, SDL_TRUE) returns 10, 11, 12, 13 */ - uresult = (Uint64)SDLTest_RandomUint8BoundaryValue(10, 13, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomUint8BoundaryValue"); - SDLTest_AssertCheck( - uresult == 10 || uresult == 11 || uresult == 12 || uresult == 13, - "Validate result value for parameters (10,13,SDL_TRUE); expected: 10|11|12|13, got: %"SDL_PRIs64, uresult); - - /* RandomUintXBoundaryValue(10, 20, SDL_TRUE) returns 10, 11, 19 or 20 */ - uresult = (Uint64)SDLTest_RandomUint8BoundaryValue(10, 20, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomUint8BoundaryValue"); - SDLTest_AssertCheck( - uresult == 10 || uresult == 11 || uresult == 19 || uresult == 20, - "Validate result value for parameters (10,20,SDL_TRUE); expected: 10|11|19|20, got: %"SDL_PRIs64, uresult); - - /* RandomUintXBoundaryValue(20, 10, SDL_TRUE) returns 10, 11, 19 or 20 */ - uresult = (Uint64)SDLTest_RandomUint8BoundaryValue(20, 10, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomUint8BoundaryValue"); - SDLTest_AssertCheck( - uresult == 10 || uresult == 11 || uresult == 19 || uresult == 20, - "Validate result value for parameters (20,10,SDL_TRUE); expected: 10|11|19|20, got: %"SDL_PRIs64, uresult); - - /* RandomUintXBoundaryValue(1, 20, SDL_FALSE) returns 0, 21 */ - uresult = (Uint64)SDLTest_RandomUint8BoundaryValue(1, 20, SDL_FALSE); - SDLTest_AssertPass("Call to SDLTest_RandomUint8BoundaryValue"); - SDLTest_AssertCheck( - uresult == 0 || uresult == 21, - "Validate result value for parameters (1,20,SDL_FALSE); expected: 0|21, got: %"SDL_PRIs64, uresult); - - /* RandomUintXBoundaryValue(0, 99, SDL_FALSE) returns 100 */ - uresult = (Uint64)SDLTest_RandomUint8BoundaryValue(0, 99, SDL_FALSE); - SDLTest_AssertPass("Call to SDLTest_RandomUint8BoundaryValue"); - SDLTest_AssertCheck( - uresult == 100, - "Validate result value for parameters (0,99,SDL_FALSE); expected: 100, got: %"SDL_PRIs64, uresult); - - /* RandomUintXBoundaryValue(1, 0xff, SDL_FALSE) returns 0 (no error) */ - uresult = (Uint64)SDLTest_RandomUint8BoundaryValue(1, 255, SDL_FALSE); - SDLTest_AssertPass("Call to SDLTest_RandomUint8BoundaryValue"); - SDLTest_AssertCheck( - uresult == 0, - "Validate result value for parameters (1,255,SDL_FALSE); expected: 0, got: %"SDL_PRIs64, uresult); - lastError = (char *)SDL_GetError(); - SDLTest_AssertPass("SDL_GetError()"); - SDLTest_AssertCheck(lastError == NULL || lastError[0] == '\0', "Validate no error message was set"); - - /* RandomUintXBoundaryValue(0, 0xfe, SDL_FALSE) returns 0xff (no error) */ - uresult = (Uint64)SDLTest_RandomUint8BoundaryValue(0, 254, SDL_FALSE); - SDLTest_AssertPass("Call to SDLTest_RandomUint8BoundaryValue"); - SDLTest_AssertCheck( - uresult == 0xff, - "Validate result value for parameters (0,254,SDL_FALSE); expected: 0xff, got: %"SDL_PRIs64, uresult); - lastError = (char *)SDL_GetError(); - SDLTest_AssertPass("SDL_GetError()"); - SDLTest_AssertCheck(lastError == NULL || lastError[0] == '\0', "Validate no error message was set"); - - /* RandomUintXBoundaryValue(0, 0xff, SDL_FALSE) returns 0 (sets error) */ - uresult = (Uint64)SDLTest_RandomUint8BoundaryValue(0, 255, SDL_FALSE); - SDLTest_AssertPass("Call to SDLTest_RandomUint8BoundaryValue"); - SDLTest_AssertCheck( - uresult == 0, - "Validate result value for parameters(0,255,SDL_FALSE); expected: 0, got: %"SDL_PRIs64, uresult); - lastError = (char *)SDL_GetError(); - SDLTest_AssertPass("SDL_GetError()"); - SDLTest_AssertCheck(lastError != NULL && SDL_strcmp(lastError, expectedError) == 0, - "SDL_GetError(): expected message '%s', was message: '%s'", - expectedError, - lastError); - - /* Clear error messages */ - SDL_ClearError(); - SDLTest_AssertPass("SDL_ClearError()"); - - return TEST_COMPLETED; -} - -/* - * @brief Calls to random boundary number generators for Uint16 - */ -int -sdltest_randomBoundaryNumberUint16(void *arg) -{ - const char *expectedError = "That operation is not supported"; - char *lastError; - Uint64 uresult; - - /* Clean error messages */ - SDL_ClearError(); - SDLTest_AssertPass("SDL_ClearError()"); - - /* RandomUintXBoundaryValue(10, 10, SDL_TRUE) returns 10 */ - uresult = (Uint64)SDLTest_RandomUint16BoundaryValue(10, 10, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomUint16BoundaryValue"); - SDLTest_AssertCheck( - uresult == 10, - "Validate result value for parameters (10,10,SDL_TRUE); expected: 10, got: %"SDL_PRIs64, uresult); - - /* RandomUintXBoundaryValue(10, 11, SDL_TRUE) returns 10, 11 */ - uresult = (Uint64)SDLTest_RandomUint16BoundaryValue(10, 11, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomUint16BoundaryValue"); - SDLTest_AssertCheck( - uresult == 10 || uresult == 11, - "Validate result value for parameters (10,11,SDL_TRUE); expected: 10|11, got: %"SDL_PRIs64, uresult); - - /* RandomUintXBoundaryValue(10, 12, SDL_TRUE) returns 10, 11, 12 */ - uresult = (Uint64)SDLTest_RandomUint16BoundaryValue(10, 12, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomUint16BoundaryValue"); - SDLTest_AssertCheck( - uresult == 10 || uresult == 11 || uresult == 12, - "Validate result value for parameters (10,12,SDL_TRUE); expected: 10|11|12, got: %"SDL_PRIs64, uresult); - - /* RandomUintXBoundaryValue(10, 13, SDL_TRUE) returns 10, 11, 12, 13 */ - uresult = (Uint64)SDLTest_RandomUint16BoundaryValue(10, 13, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomUint16BoundaryValue"); - SDLTest_AssertCheck( - uresult == 10 || uresult == 11 || uresult == 12 || uresult == 13, - "Validate result value for parameters (10,13,SDL_TRUE); expected: 10|11|12|13, got: %"SDL_PRIs64, uresult); - - /* RandomUintXBoundaryValue(10, 20, SDL_TRUE) returns 10, 11, 19 or 20 */ - uresult = (Uint64)SDLTest_RandomUint16BoundaryValue(10, 20, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomUint16BoundaryValue"); - SDLTest_AssertCheck( - uresult == 10 || uresult == 11 || uresult == 19 || uresult == 20, - "Validate result value for parameters (10,20,SDL_TRUE); expected: 10|11|19|20, got: %"SDL_PRIs64, uresult); - - /* RandomUintXBoundaryValue(20, 10, SDL_TRUE) returns 10, 11, 19 or 20 */ - uresult = (Uint64)SDLTest_RandomUint16BoundaryValue(20, 10, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomUint16BoundaryValue"); - SDLTest_AssertCheck( - uresult == 10 || uresult == 11 || uresult == 19 || uresult == 20, - "Validate result value for parameters (20,10,SDL_TRUE); expected: 10|11|19|20, got: %"SDL_PRIs64, uresult); - - /* RandomUintXBoundaryValue(1, 20, SDL_FALSE) returns 0, 21 */ - uresult = (Uint64)SDLTest_RandomUint16BoundaryValue(1, 20, SDL_FALSE); - SDLTest_AssertPass("Call to SDLTest_RandomUint16BoundaryValue"); - SDLTest_AssertCheck( - uresult == 0 || uresult == 21, - "Validate result value for parameters (1,20,SDL_FALSE); expected: 0|21, got: %"SDL_PRIs64, uresult); - - /* RandomUintXBoundaryValue(0, 99, SDL_FALSE) returns 100 */ - uresult = (Uint64)SDLTest_RandomUint16BoundaryValue(0, 99, SDL_FALSE); - SDLTest_AssertPass("Call to SDLTest_RandomUint16BoundaryValue"); - SDLTest_AssertCheck( - uresult == 100, - "Validate result value for parameters (0,99,SDL_FALSE); expected: 100, got: %"SDL_PRIs64, uresult); - - /* RandomUintXBoundaryValue(1, 0xffff, SDL_FALSE) returns 0 (no error) */ - uresult = (Uint64)SDLTest_RandomUint16BoundaryValue(1, 0xffff, SDL_FALSE); - SDLTest_AssertPass("Call to SDLTest_RandomUint16BoundaryValue"); - SDLTest_AssertCheck( - uresult == 0, - "Validate result value for parameters (1,0xffff,SDL_FALSE); expected: 0, got: %"SDL_PRIs64, uresult); - lastError = (char *)SDL_GetError(); - SDLTest_AssertPass("SDL_GetError()"); - SDLTest_AssertCheck(lastError == NULL || lastError[0] == '\0', "Validate no error message was set"); - - /* RandomUintXBoundaryValue(0, 0xfffe, SDL_FALSE) returns 0xffff (no error) */ - uresult = (Uint64)SDLTest_RandomUint16BoundaryValue(0, 0xfffe, SDL_FALSE); - SDLTest_AssertPass("Call to SDLTest_RandomUint16BoundaryValue"); - SDLTest_AssertCheck( - uresult == 0xffff, - "Validate result value for parameters (0,0xfffe,SDL_FALSE); expected: 0xffff, got: %"SDL_PRIs64, uresult); - lastError = (char *)SDL_GetError(); - SDLTest_AssertPass("SDL_GetError()"); - SDLTest_AssertCheck(lastError == NULL || lastError[0] == '\0', "Validate no error message was set"); - - /* RandomUintXBoundaryValue(0, 0xffff, SDL_FALSE) returns 0 (sets error) */ - uresult = (Uint64)SDLTest_RandomUint16BoundaryValue(0, 0xffff, SDL_FALSE); - SDLTest_AssertPass("Call to SDLTest_RandomUint16BoundaryValue"); - SDLTest_AssertCheck( - uresult == 0, - "Validate result value for parameters(0,0xffff,SDL_FALSE); expected: 0, got: %"SDL_PRIs64, uresult); - lastError = (char *)SDL_GetError(); - SDLTest_AssertPass("SDL_GetError()"); - SDLTest_AssertCheck(lastError != NULL && SDL_strcmp(lastError, expectedError) == 0, - "SDL_GetError(): expected message '%s', was message: '%s'", - expectedError, - lastError); - - /* Clear error messages */ - SDL_ClearError(); - SDLTest_AssertPass("SDL_ClearError()"); - - return TEST_COMPLETED; -} - -/* - * @brief Calls to random boundary number generators for Uint32 - */ -int -sdltest_randomBoundaryNumberUint32(void *arg) -{ - const char *expectedError = "That operation is not supported"; - char *lastError; - Uint64 uresult; - - /* Clean error messages */ - SDL_ClearError(); - SDLTest_AssertPass("SDL_ClearError()"); - - /* RandomUintXBoundaryValue(10, 10, SDL_TRUE) returns 10 */ - uresult = (Uint64)SDLTest_RandomUint32BoundaryValue(10, 10, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomUint32BoundaryValue"); - SDLTest_AssertCheck( - uresult == 10, - "Validate result value for parameters (10,10,SDL_TRUE); expected: 10, got: %"SDL_PRIs64, uresult); - - /* RandomUintXBoundaryValue(10, 11, SDL_TRUE) returns 10, 11 */ - uresult = (Uint64)SDLTest_RandomUint32BoundaryValue(10, 11, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomUint32BoundaryValue"); - SDLTest_AssertCheck( - uresult == 10 || uresult == 11, - "Validate result value for parameters (10,11,SDL_TRUE); expected: 10|11, got: %"SDL_PRIs64, uresult); - - /* RandomUintXBoundaryValue(10, 12, SDL_TRUE) returns 10, 11, 12 */ - uresult = (Uint64)SDLTest_RandomUint32BoundaryValue(10, 12, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomUint32BoundaryValue"); - SDLTest_AssertCheck( - uresult == 10 || uresult == 11 || uresult == 12, - "Validate result value for parameters (10,12,SDL_TRUE); expected: 10|11|12, got: %"SDL_PRIs64, uresult); - - /* RandomUintXBoundaryValue(10, 13, SDL_TRUE) returns 10, 11, 12, 13 */ - uresult = (Uint64)SDLTest_RandomUint32BoundaryValue(10, 13, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomUint32BoundaryValue"); - SDLTest_AssertCheck( - uresult == 10 || uresult == 11 || uresult == 12 || uresult == 13, - "Validate result value for parameters (10,13,SDL_TRUE); expected: 10|11|12|13, got: %"SDL_PRIs64, uresult); - - /* RandomUintXBoundaryValue(10, 20, SDL_TRUE) returns 10, 11, 19 or 20 */ - uresult = (Uint64)SDLTest_RandomUint32BoundaryValue(10, 20, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomUint32BoundaryValue"); - SDLTest_AssertCheck( - uresult == 10 || uresult == 11 || uresult == 19 || uresult == 20, - "Validate result value for parameters (10,20,SDL_TRUE); expected: 10|11|19|20, got: %"SDL_PRIs64, uresult); - - /* RandomUintXBoundaryValue(20, 10, SDL_TRUE) returns 10, 11, 19 or 20 */ - uresult = (Uint64)SDLTest_RandomUint32BoundaryValue(20, 10, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomUint32BoundaryValue"); - SDLTest_AssertCheck( - uresult == 10 || uresult == 11 || uresult == 19 || uresult == 20, - "Validate result value for parameters (20,10,SDL_TRUE); expected: 10|11|19|20, got: %"SDL_PRIs64, uresult); - - /* RandomUintXBoundaryValue(1, 20, SDL_FALSE) returns 0, 21 */ - uresult = (Uint64)SDLTest_RandomUint32BoundaryValue(1, 20, SDL_FALSE); - SDLTest_AssertPass("Call to SDLTest_RandomUint32BoundaryValue"); - SDLTest_AssertCheck( - uresult == 0 || uresult == 21, - "Validate result value for parameters (1,20,SDL_FALSE); expected: 0|21, got: %"SDL_PRIs64, uresult); - - /* RandomUintXBoundaryValue(0, 99, SDL_FALSE) returns 100 */ - uresult = (Uint64)SDLTest_RandomUint32BoundaryValue(0, 99, SDL_FALSE); - SDLTest_AssertPass("Call to SDLTest_RandomUint32BoundaryValue"); - SDLTest_AssertCheck( - uresult == 100, - "Validate result value for parameters (0,99,SDL_FALSE); expected: 100, got: %"SDL_PRIs64, uresult); - - /* RandomUintXBoundaryValue(1, 0xffffffff, SDL_FALSE) returns 0 (no error) */ - uresult = (Uint64)SDLTest_RandomUint32BoundaryValue(1, 0xffffffff, SDL_FALSE); - SDLTest_AssertPass("Call to SDLTest_RandomUint32BoundaryValue"); - SDLTest_AssertCheck( - uresult == 0, - "Validate result value for parameters (1,0xffffffff,SDL_FALSE); expected: 0, got: %"SDL_PRIs64, uresult); - lastError = (char *)SDL_GetError(); - SDLTest_AssertPass("SDL_GetError()"); - SDLTest_AssertCheck(lastError == NULL || lastError[0] == '\0', "Validate no error message was set"); - - /* RandomUintXBoundaryValue(0, 0xfffffffe, SDL_FALSE) returns 0xffffffff (no error) */ - uresult = (Uint64)SDLTest_RandomUint32BoundaryValue(0, 0xfffffffe, SDL_FALSE); - SDLTest_AssertPass("Call to SDLTest_RandomUint32BoundaryValue"); - SDLTest_AssertCheck( - uresult == 0xffffffff, - "Validate result value for parameters (0,0xfffffffe,SDL_FALSE); expected: 0xffffffff, got: %"SDL_PRIs64, uresult); - lastError = (char *)SDL_GetError(); - SDLTest_AssertPass("SDL_GetError()"); - SDLTest_AssertCheck(lastError == NULL || lastError[0] == '\0', "Validate no error message was set"); - - /* RandomUintXBoundaryValue(0, 0xffffffff, SDL_FALSE) returns 0 (sets error) */ - uresult = (Uint64)SDLTest_RandomUint32BoundaryValue(0, 0xffffffff, SDL_FALSE); - SDLTest_AssertPass("Call to SDLTest_RandomUint32BoundaryValue"); - SDLTest_AssertCheck( - uresult == 0, - "Validate result value for parameters(0,0xffffffff,SDL_FALSE); expected: 0, got: %"SDL_PRIs64, uresult); - lastError = (char *)SDL_GetError(); - SDLTest_AssertPass("SDL_GetError()"); - SDLTest_AssertCheck(lastError != NULL && SDL_strcmp(lastError, expectedError) == 0, - "SDL_GetError(): expected message '%s', was message: '%s'", - expectedError, - lastError); - - /* Clear error messages */ - SDL_ClearError(); - SDLTest_AssertPass("SDL_ClearError()"); - - return TEST_COMPLETED; -} - -/* - * @brief Calls to random boundary number generators for Uint64 - */ -int -sdltest_randomBoundaryNumberUint64(void *arg) -{ - const char *expectedError = "That operation is not supported"; - char *lastError; - Uint64 uresult; - - /* Clean error messages */ - SDL_ClearError(); - SDLTest_AssertPass("SDL_ClearError()"); - - /* RandomUintXBoundaryValue(10, 10, SDL_TRUE) returns 10 */ - uresult = (Uint64)SDLTest_RandomUint64BoundaryValue(10, 10, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomUint64BoundaryValue"); - SDLTest_AssertCheck( - uresult == 10, - "Validate result value for parameters (10,10,SDL_TRUE); expected: 10, got: %"SDL_PRIs64, uresult); - - /* RandomUintXBoundaryValue(10, 11, SDL_TRUE) returns 10, 11 */ - uresult = (Uint64)SDLTest_RandomUint64BoundaryValue(10, 11, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomUint64BoundaryValue"); - SDLTest_AssertCheck( - uresult == 10 || uresult == 11, - "Validate result value for parameters (10,11,SDL_TRUE); expected: 10|11, got: %"SDL_PRIs64, uresult); - - /* RandomUintXBoundaryValue(10, 12, SDL_TRUE) returns 10, 11, 12 */ - uresult = (Uint64)SDLTest_RandomUint64BoundaryValue(10, 12, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomUint64BoundaryValue"); - SDLTest_AssertCheck( - uresult == 10 || uresult == 11 || uresult == 12, - "Validate result value for parameters (10,12,SDL_TRUE); expected: 10|11|12, got: %"SDL_PRIs64, uresult); - - /* RandomUintXBoundaryValue(10, 13, SDL_TRUE) returns 10, 11, 12, 13 */ - uresult = (Uint64)SDLTest_RandomUint64BoundaryValue(10, 13, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomUint64BoundaryValue"); - SDLTest_AssertCheck( - uresult == 10 || uresult == 11 || uresult == 12 || uresult == 13, - "Validate result value for parameters (10,13,SDL_TRUE); expected: 10|11|12|13, got: %"SDL_PRIs64, uresult); - - /* RandomUintXBoundaryValue(10, 20, SDL_TRUE) returns 10, 11, 19 or 20 */ - uresult = (Uint64)SDLTest_RandomUint64BoundaryValue(10, 20, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomUint64BoundaryValue"); - SDLTest_AssertCheck( - uresult == 10 || uresult == 11 || uresult == 19 || uresult == 20, - "Validate result value for parameters (10,20,SDL_TRUE); expected: 10|11|19|20, got: %"SDL_PRIs64, uresult); - - /* RandomUintXBoundaryValue(20, 10, SDL_TRUE) returns 10, 11, 19 or 20 */ - uresult = (Uint64)SDLTest_RandomUint64BoundaryValue(20, 10, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomUint64BoundaryValue"); - SDLTest_AssertCheck( - uresult == 10 || uresult == 11 || uresult == 19 || uresult == 20, - "Validate result value for parameters (20,10,SDL_TRUE); expected: 10|11|19|20, got: %"SDL_PRIs64, uresult); - - /* RandomUintXBoundaryValue(1, 20, SDL_FALSE) returns 0, 21 */ - uresult = (Uint64)SDLTest_RandomUint64BoundaryValue(1, 20, SDL_FALSE); - SDLTest_AssertPass("Call to SDLTest_RandomUint64BoundaryValue"); - SDLTest_AssertCheck( - uresult == 0 || uresult == 21, - "Validate result value for parameters (1,20,SDL_FALSE); expected: 0|21, got: %"SDL_PRIs64, uresult); - - /* RandomUintXBoundaryValue(0, 99, SDL_FALSE) returns 100 */ - uresult = (Uint64)SDLTest_RandomUint64BoundaryValue(0, 99, SDL_FALSE); - SDLTest_AssertPass("Call to SDLTest_RandomUint64BoundaryValue"); - SDLTest_AssertCheck( - uresult == 100, - "Validate result value for parameters (0,99,SDL_FALSE); expected: 100, got: %"SDL_PRIs64, uresult); - - /* RandomUintXBoundaryValue(1, 0xffffffffffffffff, SDL_FALSE) returns 0 (no error) */ - uresult = (Uint64)SDLTest_RandomUint64BoundaryValue(1, (Uint64)0xffffffffffffffffULL, SDL_FALSE); - SDLTest_AssertPass("Call to SDLTest_RandomUint64BoundaryValue"); - SDLTest_AssertCheck( - uresult == 0, - "Validate result value for parameters (1,0xffffffffffffffff,SDL_FALSE); expected: 0, got: %"SDL_PRIs64, uresult); - lastError = (char *)SDL_GetError(); - SDLTest_AssertPass("SDL_GetError()"); - SDLTest_AssertCheck(lastError == NULL || lastError[0] == '\0', "Validate no error message was set"); - - /* RandomUintXBoundaryValue(0, 0xfffffffffffffffe, SDL_FALSE) returns 0xffffffffffffffff (no error) */ - uresult = (Uint64)SDLTest_RandomUint64BoundaryValue(0, (Uint64)0xfffffffffffffffeULL, SDL_FALSE); - SDLTest_AssertPass("Call to SDLTest_RandomUint64BoundaryValue"); - SDLTest_AssertCheck( - uresult == (Uint64)0xffffffffffffffffULL, - "Validate result value for parameters (0,0xfffffffffffffffe,SDL_FALSE); expected: 0xffffffffffffffff, got: %"SDL_PRIs64, uresult); - lastError = (char *)SDL_GetError(); - SDLTest_AssertPass("SDL_GetError()"); - SDLTest_AssertCheck(lastError == NULL || lastError[0] == '\0', "Validate no error message was set"); - - /* RandomUintXBoundaryValue(0, 0xffffffffffffffff, SDL_FALSE) returns 0 (sets error) */ - uresult = (Uint64)SDLTest_RandomUint64BoundaryValue(0, (Uint64)0xffffffffffffffffULL, SDL_FALSE); - SDLTest_AssertPass("Call to SDLTest_RandomUint64BoundaryValue"); - SDLTest_AssertCheck( - uresult == 0, - "Validate result value for parameters(0,0xffffffffffffffff,SDL_FALSE); expected: 0, got: %"SDL_PRIs64, uresult); - lastError = (char *)SDL_GetError(); - SDLTest_AssertPass("SDL_GetError()"); - SDLTest_AssertCheck(lastError != NULL && SDL_strcmp(lastError, expectedError) == 0, - "SDL_GetError(): expected message '%s', was message: '%s'", - expectedError, - lastError); - - /* Clear error messages */ - SDL_ClearError(); - SDLTest_AssertPass("SDL_ClearError()"); - - return TEST_COMPLETED; -} - -/* - * @brief Calls to random boundary number generators for Sint8 - */ -int -sdltest_randomBoundaryNumberSint8(void *arg) -{ - const char *expectedError = "That operation is not supported"; - char *lastError; - Sint64 sresult; - - /* Clean error messages */ - SDL_ClearError(); - SDLTest_AssertPass("SDL_ClearError()"); - - /* RandomSintXBoundaryValue(10, 10, SDL_TRUE) returns 10 */ - sresult = (Sint64)SDLTest_RandomSint8BoundaryValue(10, 10, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomSint8BoundaryValue"); - SDLTest_AssertCheck( - sresult == 10, - "Validate result value for parameters (10,10,SDL_TRUE); expected: 10, got: %"SDL_PRIs64, sresult); - - /* RandomSintXBoundaryValue(10, 11, SDL_TRUE) returns 10, 11 */ - sresult = (Sint64)SDLTest_RandomSint8BoundaryValue(10, 11, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomSint8BoundaryValue"); - SDLTest_AssertCheck( - sresult == 10 || sresult == 11, - "Validate result value for parameters (10,11,SDL_TRUE); expected: 10|11, got: %"SDL_PRIs64, sresult); - - /* RandomSintXBoundaryValue(10, 12, SDL_TRUE) returns 10, 11, 12 */ - sresult = (Sint64)SDLTest_RandomSint8BoundaryValue(10, 12, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomSint8BoundaryValue"); - SDLTest_AssertCheck( - sresult == 10 || sresult == 11 || sresult == 12, - "Validate result value for parameters (10,12,SDL_TRUE); expected: 10|11|12, got: %"SDL_PRIs64, sresult); - - /* RandomSintXBoundaryValue(10, 13, SDL_TRUE) returns 10, 11, 12, 13 */ - sresult = (Sint64)SDLTest_RandomSint8BoundaryValue(10, 13, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomSint8BoundaryValue"); - SDLTest_AssertCheck( - sresult == 10 || sresult == 11 || sresult == 12 || sresult == 13, - "Validate result value for parameters (10,13,SDL_TRUE); expected: 10|11|12|13, got: %"SDL_PRIs64, sresult); - - /* RandomSintXBoundaryValue(10, 20, SDL_TRUE) returns 10, 11, 19 or 20 */ - sresult = (Sint64)SDLTest_RandomSint8BoundaryValue(10, 20, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomSint8BoundaryValue"); - SDLTest_AssertCheck( - sresult == 10 || sresult == 11 || sresult == 19 || sresult == 20, - "Validate result value for parameters (10,20,SDL_TRUE); expected: 10|11|19|20, got: %"SDL_PRIs64, sresult); - - /* RandomSintXBoundaryValue(20, 10, SDL_TRUE) returns 10, 11, 19 or 20 */ - sresult = (Sint64)SDLTest_RandomSint8BoundaryValue(20, 10, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomSint8BoundaryValue"); - SDLTest_AssertCheck( - sresult == 10 || sresult == 11 || sresult == 19 || sresult == 20, - "Validate result value for parameters (20,10,SDL_TRUE); expected: 10|11|19|20, got: %"SDL_PRIs64, sresult); - - /* RandomSintXBoundaryValue(1, 20, SDL_FALSE) returns 0, 21 */ - sresult = (Sint64)SDLTest_RandomSint8BoundaryValue(1, 20, SDL_FALSE); - SDLTest_AssertPass("Call to SDLTest_RandomSint8BoundaryValue"); - SDLTest_AssertCheck( - sresult == 0 || sresult == 21, - "Validate result value for parameters (1,20,SDL_FALSE); expected: 0|21, got: %"SDL_PRIs64, sresult); - - /* RandomSintXBoundaryValue(SCHAR_MIN, 99, SDL_FALSE) returns 100 */ - sresult = (Sint64)SDLTest_RandomSint8BoundaryValue(SCHAR_MIN, 99, SDL_FALSE); - SDLTest_AssertPass("Call to SDLTest_RandomSint8BoundaryValue"); - SDLTest_AssertCheck( - sresult == 100, - "Validate result value for parameters (SCHAR_MIN,99,SDL_FALSE); expected: 100, got: %"SDL_PRIs64, sresult); - - /* RandomSintXBoundaryValue(SCHAR_MIN + 1, SCHAR_MAX, SDL_FALSE) returns SCHAR_MIN (no error) */ - sresult = (Sint64)SDLTest_RandomSint8BoundaryValue(SCHAR_MIN + 1, SCHAR_MAX, SDL_FALSE); - SDLTest_AssertPass("Call to SDLTest_RandomSint8BoundaryValue"); - SDLTest_AssertCheck( - sresult == SCHAR_MIN, - "Validate result value for parameters (SCHAR_MIN + 1,SCHAR_MAX,SDL_FALSE); expected: %d, got: %"SDL_PRIs64, SCHAR_MIN, sresult); - lastError = (char *)SDL_GetError(); - SDLTest_AssertPass("SDL_GetError()"); - SDLTest_AssertCheck(lastError == NULL || lastError[0] == '\0', "Validate no error message was set"); - - /* RandomSintXBoundaryValue(SCHAR_MIN, SCHAR_MAX - 1, SDL_FALSE) returns SCHAR_MAX (no error) */ - sresult = (Sint64)SDLTest_RandomSint8BoundaryValue(SCHAR_MIN, SCHAR_MAX -1, SDL_FALSE); - SDLTest_AssertPass("Call to SDLTest_RandomSint8BoundaryValue"); - SDLTest_AssertCheck( - sresult == SCHAR_MAX, - "Validate result value for parameters (SCHAR_MIN,SCHAR_MAX - 1,SDL_FALSE); expected: %d, got: %"SDL_PRIs64, SCHAR_MAX, sresult); - lastError = (char *)SDL_GetError(); - SDLTest_AssertPass("SDL_GetError()"); - SDLTest_AssertCheck(lastError == NULL || lastError[0] == '\0', "Validate no error message was set"); - - /* RandomSintXBoundaryValue(SCHAR_MIN, SCHAR_MAX, SDL_FALSE) returns SCHAR_MIN (sets error) */ - sresult = (Sint64)SDLTest_RandomSint8BoundaryValue(SCHAR_MIN, SCHAR_MAX, SDL_FALSE); - SDLTest_AssertPass("Call to SDLTest_RandomSint8BoundaryValue"); - SDLTest_AssertCheck( - sresult == SCHAR_MIN, - "Validate result value for parameters(SCHAR_MIN,SCHAR_MAX,SDL_FALSE); expected: %d, got: %"SDL_PRIs64, SCHAR_MIN, sresult); - lastError = (char *)SDL_GetError(); - SDLTest_AssertPass("SDL_GetError()"); - SDLTest_AssertCheck(lastError != NULL && SDL_strcmp(lastError, expectedError) == 0, - "SDL_GetError(): expected message '%s', was message: '%s'", - expectedError, - lastError); - - /* Clear error messages */ - SDL_ClearError(); - SDLTest_AssertPass("SDL_ClearError()"); - - return TEST_COMPLETED; -} - -/* - * @brief Calls to random boundary number generators for Sint16 - */ -int -sdltest_randomBoundaryNumberSint16(void *arg) -{ - const char *expectedError = "That operation is not supported"; - char *lastError; - Sint64 sresult; - - /* Clean error messages */ - SDL_ClearError(); - SDLTest_AssertPass("SDL_ClearError()"); - - /* RandomSintXBoundaryValue(10, 10, SDL_TRUE) returns 10 */ - sresult = (Sint64)SDLTest_RandomSint16BoundaryValue(10, 10, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomSint16BoundaryValue"); - SDLTest_AssertCheck( - sresult == 10, - "Validate result value for parameters (10,10,SDL_TRUE); expected: 10, got: %"SDL_PRIs64, sresult); - - /* RandomSintXBoundaryValue(10, 11, SDL_TRUE) returns 10, 11 */ - sresult = (Sint64)SDLTest_RandomSint16BoundaryValue(10, 11, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomSint16BoundaryValue"); - SDLTest_AssertCheck( - sresult == 10 || sresult == 11, - "Validate result value for parameters (10,11,SDL_TRUE); expected: 10|11, got: %"SDL_PRIs64, sresult); - - /* RandomSintXBoundaryValue(10, 12, SDL_TRUE) returns 10, 11, 12 */ - sresult = (Sint64)SDLTest_RandomSint16BoundaryValue(10, 12, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomSint16BoundaryValue"); - SDLTest_AssertCheck( - sresult == 10 || sresult == 11 || sresult == 12, - "Validate result value for parameters (10,12,SDL_TRUE); expected: 10|11|12, got: %"SDL_PRIs64, sresult); - - /* RandomSintXBoundaryValue(10, 13, SDL_TRUE) returns 10, 11, 12, 13 */ - sresult = (Sint64)SDLTest_RandomSint16BoundaryValue(10, 13, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomSint16BoundaryValue"); - SDLTest_AssertCheck( - sresult == 10 || sresult == 11 || sresult == 12 || sresult == 13, - "Validate result value for parameters (10,13,SDL_TRUE); expected: 10|11|12|13, got: %"SDL_PRIs64, sresult); - - /* RandomSintXBoundaryValue(10, 20, SDL_TRUE) returns 10, 11, 19 or 20 */ - sresult = (Sint64)SDLTest_RandomSint16BoundaryValue(10, 20, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomSint16BoundaryValue"); - SDLTest_AssertCheck( - sresult == 10 || sresult == 11 || sresult == 19 || sresult == 20, - "Validate result value for parameters (10,20,SDL_TRUE); expected: 10|11|19|20, got: %"SDL_PRIs64, sresult); - - /* RandomSintXBoundaryValue(20, 10, SDL_TRUE) returns 10, 11, 19 or 20 */ - sresult = (Sint64)SDLTest_RandomSint16BoundaryValue(20, 10, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomSint16BoundaryValue"); - SDLTest_AssertCheck( - sresult == 10 || sresult == 11 || sresult == 19 || sresult == 20, - "Validate result value for parameters (20,10,SDL_TRUE); expected: 10|11|19|20, got: %"SDL_PRIs64, sresult); - - /* RandomSintXBoundaryValue(1, 20, SDL_FALSE) returns 0, 21 */ - sresult = (Sint64)SDLTest_RandomSint16BoundaryValue(1, 20, SDL_FALSE); - SDLTest_AssertPass("Call to SDLTest_RandomSint16BoundaryValue"); - SDLTest_AssertCheck( - sresult == 0 || sresult == 21, - "Validate result value for parameters (1,20,SDL_FALSE); expected: 0|21, got: %"SDL_PRIs64, sresult); - - /* RandomSintXBoundaryValue(SHRT_MIN, 99, SDL_FALSE) returns 100 */ - sresult = (Sint64)SDLTest_RandomSint16BoundaryValue(SHRT_MIN, 99, SDL_FALSE); - SDLTest_AssertPass("Call to SDLTest_RandomSint16BoundaryValue"); - SDLTest_AssertCheck( - sresult == 100, - "Validate result value for parameters (SHRT_MIN,99,SDL_FALSE); expected: 100, got: %"SDL_PRIs64, sresult); - - /* RandomSintXBoundaryValue(SHRT_MIN + 1, SHRT_MAX, SDL_FALSE) returns SHRT_MIN (no error) */ - sresult = (Sint64)SDLTest_RandomSint16BoundaryValue(SHRT_MIN + 1, SHRT_MAX, SDL_FALSE); - SDLTest_AssertPass("Call to SDLTest_RandomSint16BoundaryValue"); - SDLTest_AssertCheck( - sresult == SHRT_MIN, - "Validate result value for parameters (SHRT_MIN+1,SHRT_MAX,SDL_FALSE); expected: %d, got: %"SDL_PRIs64, SHRT_MIN, sresult); - lastError = (char *)SDL_GetError(); - SDLTest_AssertPass("SDL_GetError()"); - SDLTest_AssertCheck(lastError == NULL || lastError[0] == '\0', "Validate no error message was set"); - - /* RandomSintXBoundaryValue(SHRT_MIN, SHRT_MAX - 1, SDL_FALSE) returns SHRT_MAX (no error) */ - sresult = (Sint64)SDLTest_RandomSint16BoundaryValue(SHRT_MIN, SHRT_MAX - 1, SDL_FALSE); - SDLTest_AssertPass("Call to SDLTest_RandomSint16BoundaryValue"); - SDLTest_AssertCheck( - sresult == SHRT_MAX, - "Validate result value for parameters (SHRT_MIN,SHRT_MAX - 1,SDL_FALSE); expected: %d, got: %"SDL_PRIs64, SHRT_MAX, sresult); - lastError = (char *)SDL_GetError(); - SDLTest_AssertPass("SDL_GetError()"); - SDLTest_AssertCheck(lastError == NULL || lastError[0] == '\0', "Validate no error message was set"); - - /* RandomSintXBoundaryValue(SHRT_MIN, SHRT_MAX, SDL_FALSE) returns 0 (sets error) */ - sresult = (Sint64)SDLTest_RandomSint16BoundaryValue(SHRT_MIN, SHRT_MAX, SDL_FALSE); - SDLTest_AssertPass("Call to SDLTest_RandomSint16BoundaryValue"); - SDLTest_AssertCheck( - sresult == SHRT_MIN, - "Validate result value for parameters(SHRT_MIN,SHRT_MAX,SDL_FALSE); expected: %d, got: %"SDL_PRIs64, SHRT_MIN, sresult); - lastError = (char *)SDL_GetError(); - SDLTest_AssertPass("SDL_GetError()"); - SDLTest_AssertCheck(lastError != NULL && SDL_strcmp(lastError, expectedError) == 0, - "SDL_GetError(): expected message '%s', was message: '%s'", - expectedError, - lastError); - - /* Clear error messages */ - SDL_ClearError(); - SDLTest_AssertPass("SDL_ClearError()"); - - return TEST_COMPLETED; -} - -/* - * @brief Calls to random boundary number generators for Sint32 - */ -int -sdltest_randomBoundaryNumberSint32(void *arg) -{ - const char *expectedError = "That operation is not supported"; - char *lastError; - Sint64 sresult; -#if ((ULONG_MAX) == (UINT_MAX)) - Sint32 long_min = LONG_MIN; - Sint32 long_max = LONG_MAX; -#else - Sint32 long_min = INT_MIN; - Sint32 long_max = INT_MAX; -#endif - - /* Clean error messages */ - SDL_ClearError(); - SDLTest_AssertPass("SDL_ClearError()"); - - /* RandomSintXBoundaryValue(10, 10, SDL_TRUE) returns 10 */ - sresult = (Sint64)SDLTest_RandomSint32BoundaryValue(10, 10, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomSint32BoundaryValue"); - SDLTest_AssertCheck( - sresult == 10, - "Validate result value for parameters (10,10,SDL_TRUE); expected: 10, got: %"SDL_PRIs64, sresult); - - /* RandomSintXBoundaryValue(10, 11, SDL_TRUE) returns 10, 11 */ - sresult = (Sint64)SDLTest_RandomSint32BoundaryValue(10, 11, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomSint32BoundaryValue"); - SDLTest_AssertCheck( - sresult == 10 || sresult == 11, - "Validate result value for parameters (10,11,SDL_TRUE); expected: 10|11, got: %"SDL_PRIs64, sresult); - - /* RandomSintXBoundaryValue(10, 12, SDL_TRUE) returns 10, 11, 12 */ - sresult = (Sint64)SDLTest_RandomSint32BoundaryValue(10, 12, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomSint32BoundaryValue"); - SDLTest_AssertCheck( - sresult == 10 || sresult == 11 || sresult == 12, - "Validate result value for parameters (10,12,SDL_TRUE); expected: 10|11|12, got: %"SDL_PRIs64, sresult); - - /* RandomSintXBoundaryValue(10, 13, SDL_TRUE) returns 10, 11, 12, 13 */ - sresult = (Sint64)SDLTest_RandomSint32BoundaryValue(10, 13, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomSint32BoundaryValue"); - SDLTest_AssertCheck( - sresult == 10 || sresult == 11 || sresult == 12 || sresult == 13, - "Validate result value for parameters (10,13,SDL_TRUE); expected: 10|11|12|13, got: %"SDL_PRIs64, sresult); - - /* RandomSintXBoundaryValue(10, 20, SDL_TRUE) returns 10, 11, 19 or 20 */ - sresult = (Sint64)SDLTest_RandomSint32BoundaryValue(10, 20, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomSint32BoundaryValue"); - SDLTest_AssertCheck( - sresult == 10 || sresult == 11 || sresult == 19 || sresult == 20, - "Validate result value for parameters (10,20,SDL_TRUE); expected: 10|11|19|20, got: %"SDL_PRIs64, sresult); - - /* RandomSintXBoundaryValue(20, 10, SDL_TRUE) returns 10, 11, 19 or 20 */ - sresult = (Sint64)SDLTest_RandomSint32BoundaryValue(20, 10, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomSint32BoundaryValue"); - SDLTest_AssertCheck( - sresult == 10 || sresult == 11 || sresult == 19 || sresult == 20, - "Validate result value for parameters (20,10,SDL_TRUE); expected: 10|11|19|20, got: %"SDL_PRIs64, sresult); - - /* RandomSintXBoundaryValue(1, 20, SDL_FALSE) returns 0, 21 */ - sresult = (Sint64)SDLTest_RandomSint32BoundaryValue(1, 20, SDL_FALSE); - SDLTest_AssertPass("Call to SDLTest_RandomSint32BoundaryValue"); - SDLTest_AssertCheck( - sresult == 0 || sresult == 21, - "Validate result value for parameters (1,20,SDL_FALSE); expected: 0|21, got: %"SDL_PRIs64, sresult); - - /* RandomSintXBoundaryValue(LONG_MIN, 99, SDL_FALSE) returns 100 */ - sresult = (Sint64)SDLTest_RandomSint32BoundaryValue(long_min, 99, SDL_FALSE); - SDLTest_AssertPass("Call to SDLTest_RandomSint32BoundaryValue"); - SDLTest_AssertCheck( - sresult == 100, - "Validate result value for parameters (LONG_MIN,99,SDL_FALSE); expected: 100, got: %"SDL_PRIs64, sresult); - - /* RandomSintXBoundaryValue(LONG_MIN + 1, LONG_MAX, SDL_FALSE) returns LONG_MIN (no error) */ - sresult = (Sint64)SDLTest_RandomSint32BoundaryValue(long_min + 1, long_max, SDL_FALSE); - SDLTest_AssertPass("Call to SDLTest_RandomSint32BoundaryValue"); - SDLTest_AssertCheck( - sresult == long_min, - "Validate result value for parameters (LONG_MIN+1,LONG_MAX,SDL_FALSE); expected: %d, got: %"SDL_PRIs64, long_min, sresult); - lastError = (char *)SDL_GetError(); - SDLTest_AssertPass("SDL_GetError()"); - SDLTest_AssertCheck(lastError == NULL || lastError[0] == '\0', "Validate no error message was set"); - - /* RandomSintXBoundaryValue(LONG_MIN, LONG_MAX - 1, SDL_FALSE) returns LONG_MAX (no error) */ - sresult = (Sint64)SDLTest_RandomSint32BoundaryValue(long_min, long_max - 1, SDL_FALSE); - SDLTest_AssertPass("Call to SDLTest_RandomSint32BoundaryValue"); - SDLTest_AssertCheck( - sresult == long_max, - "Validate result value for parameters (LONG_MIN,LONG_MAX - 1,SDL_FALSE); expected: %d, got: %"SDL_PRIs64, long_max, sresult); - lastError = (char *)SDL_GetError(); - SDLTest_AssertPass("SDL_GetError()"); - SDLTest_AssertCheck(lastError == NULL || lastError[0] == '\0', "Validate no error message was set"); - - /* RandomSintXBoundaryValue(LONG_MIN, LONG_MAX, SDL_FALSE) returns 0 (sets error) */ - sresult = (Sint64)SDLTest_RandomSint32BoundaryValue(long_min, long_max, SDL_FALSE); - SDLTest_AssertPass("Call to SDLTest_RandomSint32BoundaryValue"); - SDLTest_AssertCheck( - sresult == long_min, - "Validate result value for parameters(LONG_MIN,LONG_MAX,SDL_FALSE); expected: %d, got: %"SDL_PRIs64, long_min, sresult); - lastError = (char *)SDL_GetError(); - SDLTest_AssertPass("SDL_GetError()"); - SDLTest_AssertCheck(lastError != NULL && SDL_strcmp(lastError, expectedError) == 0, - "SDL_GetError(): expected message '%s', was message: '%s'", - expectedError, - lastError); - - /* Clear error messages */ - SDL_ClearError(); - SDLTest_AssertPass("SDL_ClearError()"); - - return TEST_COMPLETED; -} - -/* - * @brief Calls to random boundary number generators for Sint64 - */ -int -sdltest_randomBoundaryNumberSint64(void *arg) -{ - const char *expectedError = "That operation is not supported"; - char *lastError; - Sint64 sresult; - - /* Clean error messages */ - SDL_ClearError(); - SDLTest_AssertPass("SDL_ClearError()"); - - /* RandomSintXBoundaryValue(10, 10, SDL_TRUE) returns 10 */ - sresult = (Sint64)SDLTest_RandomSint64BoundaryValue(10, 10, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomSint64BoundaryValue"); - SDLTest_AssertCheck( - sresult == 10, - "Validate result value for parameters (10,10,SDL_TRUE); expected: 10, got: %"SDL_PRIs64, sresult); - - /* RandomSintXBoundaryValue(10, 11, SDL_TRUE) returns 10, 11 */ - sresult = (Sint64)SDLTest_RandomSint64BoundaryValue(10, 11, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomSint64BoundaryValue"); - SDLTest_AssertCheck( - sresult == 10 || sresult == 11, - "Validate result value for parameters (10,11,SDL_TRUE); expected: 10|11, got: %"SDL_PRIs64, sresult); - - /* RandomSintXBoundaryValue(10, 12, SDL_TRUE) returns 10, 11, 12 */ - sresult = (Sint64)SDLTest_RandomSint64BoundaryValue(10, 12, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomSint64BoundaryValue"); - SDLTest_AssertCheck( - sresult == 10 || sresult == 11 || sresult == 12, - "Validate result value for parameters (10,12,SDL_TRUE); expected: 10|11|12, got: %"SDL_PRIs64, sresult); - - /* RandomSintXBoundaryValue(10, 13, SDL_TRUE) returns 10, 11, 12, 13 */ - sresult = (Sint64)SDLTest_RandomSint64BoundaryValue(10, 13, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomSint64BoundaryValue"); - SDLTest_AssertCheck( - sresult == 10 || sresult == 11 || sresult == 12 || sresult == 13, - "Validate result value for parameters (10,13,SDL_TRUE); expected: 10|11|12|13, got: %"SDL_PRIs64, sresult); - - /* RandomSintXBoundaryValue(10, 20, SDL_TRUE) returns 10, 11, 19 or 20 */ - sresult = (Sint64)SDLTest_RandomSint64BoundaryValue(10, 20, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomSint64BoundaryValue"); - SDLTest_AssertCheck( - sresult == 10 || sresult == 11 || sresult == 19 || sresult == 20, - "Validate result value for parameters (10,20,SDL_TRUE); expected: 10|11|19|20, got: %"SDL_PRIs64, sresult); - - /* RandomSintXBoundaryValue(20, 10, SDL_TRUE) returns 10, 11, 19 or 20 */ - sresult = (Sint64)SDLTest_RandomSint64BoundaryValue(20, 10, SDL_TRUE); - SDLTest_AssertPass("Call to SDLTest_RandomSint64BoundaryValue"); - SDLTest_AssertCheck( - sresult == 10 || sresult == 11 || sresult == 19 || sresult == 20, - "Validate result value for parameters (20,10,SDL_TRUE); expected: 10|11|19|20, got: %"SDL_PRIs64, sresult); - - /* RandomSintXBoundaryValue(1, 20, SDL_FALSE) returns 0, 21 */ - sresult = (Sint64)SDLTest_RandomSint64BoundaryValue(1, 20, SDL_FALSE); - SDLTest_AssertPass("Call to SDLTest_RandomSint64BoundaryValue"); - SDLTest_AssertCheck( - sresult == 0 || sresult == 21, - "Validate result value for parameters (1,20,SDL_FALSE); expected: 0|21, got: %"SDL_PRIs64, sresult); - - /* RandomSintXBoundaryValue(LLONG_MIN, 99, SDL_FALSE) returns 100 */ - sresult = (Sint64)SDLTest_RandomSint64BoundaryValue(INT64_MIN, 99, SDL_FALSE); - SDLTest_AssertPass("Call to SDLTest_RandomSint64BoundaryValue"); - SDLTest_AssertCheck( - sresult == 100, - "Validate result value for parameters (LLONG_MIN,99,SDL_FALSE); expected: 100, got: %"SDL_PRIs64, sresult); - - /* RandomSintXBoundaryValue(LLONG_MIN + 1, LLONG_MAX, SDL_FALSE) returns LLONG_MIN (no error) */ - sresult = (Sint64)SDLTest_RandomSint64BoundaryValue(INT64_MIN + 1, INT64_MAX, SDL_FALSE); - SDLTest_AssertPass("Call to SDLTest_RandomSint64BoundaryValue"); - SDLTest_AssertCheck( - sresult == INT64_MIN, - "Validate result value for parameters (LLONG_MIN+1,LLONG_MAX,SDL_FALSE); expected: %"SDL_PRIs64", got: %"SDL_PRIs64, INT64_MIN, sresult); - lastError = (char *)SDL_GetError(); - SDLTest_AssertPass("SDL_GetError()"); - SDLTest_AssertCheck(lastError == NULL || lastError[0] == '\0', "Validate no error message was set"); - - /* RandomSintXBoundaryValue(LLONG_MIN, LLONG_MAX - 1, SDL_FALSE) returns LLONG_MAX (no error) */ - sresult = (Sint64)SDLTest_RandomSint64BoundaryValue(INT64_MIN, INT64_MAX - 1, SDL_FALSE); - SDLTest_AssertPass("Call to SDLTest_RandomSint64BoundaryValue"); - SDLTest_AssertCheck( - sresult == INT64_MAX, - "Validate result value for parameters (LLONG_MIN,LLONG_MAX - 1,SDL_FALSE); expected: %"SDL_PRIs64", got: %"SDL_PRIs64, INT64_MAX, sresult); - lastError = (char *)SDL_GetError(); - SDLTest_AssertPass("SDL_GetError()"); - SDLTest_AssertCheck(lastError == NULL || lastError[0] == '\0', "Validate no error message was set"); - - /* RandomSintXBoundaryValue(LLONG_MIN, LLONG_MAX, SDL_FALSE) returns 0 (sets error) */ - sresult = (Sint64)SDLTest_RandomSint64BoundaryValue(INT64_MIN, INT64_MAX, SDL_FALSE); - SDLTest_AssertPass("Call to SDLTest_RandomSint64BoundaryValue"); - SDLTest_AssertCheck( - sresult == INT64_MIN, - "Validate result value for parameters(LLONG_MIN,LLONG_MAX,SDL_FALSE); expected: %"SDL_PRIs64", got: %"SDL_PRIs64, INT64_MIN, sresult); - lastError = (char *)SDL_GetError(); - SDLTest_AssertPass("SDL_GetError()"); - SDLTest_AssertCheck(lastError != NULL && SDL_strcmp(lastError, expectedError) == 0, - "SDL_GetError(): expected message '%s', was message: '%s'", - expectedError, - lastError); - - /* Clear error messages */ - SDL_ClearError(); - SDLTest_AssertPass("SDL_ClearError()"); - - return TEST_COMPLETED; -} - -/** - * @brief Calls to SDLTest_RandomIntegerInRange - */ -int -sdltest_randomIntegerInRange(void *arg) -{ - Sint32 min, max; - Sint32 result; -#if ((ULONG_MAX) == (UINT_MAX)) - Sint32 long_min = LONG_MIN; - Sint32 long_max = LONG_MAX; -#else - Sint32 long_min = INT_MIN; - Sint32 long_max = INT_MAX; -#endif - - /* Standard range */ - min = (Sint32)SDLTest_RandomSint16(); - max = min + (Sint32)SDLTest_RandomUint8() + 2; - result = SDLTest_RandomIntegerInRange(min, max); - SDLTest_AssertPass("Call to SDLTest_RandomIntegerInRange(min,max)"); - SDLTest_AssertCheck(min <= result && result <= max, "Validated returned value; expected: [%d,%d], got: %d", min, max, result); - - /* One Range */ - min = (Sint32)SDLTest_RandomSint16(); - max = min + 1; - result = SDLTest_RandomIntegerInRange(min, max); - SDLTest_AssertPass("Call to SDLTest_RandomIntegerInRange(min,min+1)"); - SDLTest_AssertCheck(min <= result && result <= max, "Validated returned value; expected: [%d,%d], got: %d", min, max, result); - - /* Zero range */ - min = (Sint32)SDLTest_RandomSint16(); - max = min; - result = SDLTest_RandomIntegerInRange(min, max); - SDLTest_AssertPass("Call to SDLTest_RandomIntegerInRange(min,min)"); - SDLTest_AssertCheck(min == result, "Validated returned value; expected: %d, got: %d", min, result); - - /* Zero range at zero */ - min = 0; - max = 0; - result = SDLTest_RandomIntegerInRange(min, max); - SDLTest_AssertPass("Call to SDLTest_RandomIntegerInRange(0,0)"); - SDLTest_AssertCheck(result == 0, "Validated returned value; expected: 0, got: %d", result); - - /* Swapped min-max */ - min = (Sint32)SDLTest_RandomSint16(); - max = min + (Sint32)SDLTest_RandomUint8() + 2; - result = SDLTest_RandomIntegerInRange(max, min); - SDLTest_AssertPass("Call to SDLTest_RandomIntegerInRange(max,min)"); - SDLTest_AssertCheck(min <= result && result <= max, "Validated returned value; expected: [%d,%d], got: %d", min, max, result); - - /* Range with min at integer limit */ - min = long_min; - max = long_max + (Sint32)SDLTest_RandomSint16(); - result = SDLTest_RandomIntegerInRange(min, max); - SDLTest_AssertPass("Call to SDLTest_RandomIntegerInRange(SINT32_MIN,...)"); - SDLTest_AssertCheck(min <= result && result <= max, "Validated returned value; expected: [%d,%d], got: %d", min, max, result); - - /* Range with max at integer limit */ - min = long_min - (Sint32)SDLTest_RandomSint16(); - max = long_max; - result = SDLTest_RandomIntegerInRange(min, max); - SDLTest_AssertPass("Call to SDLTest_RandomIntegerInRange(...,SINT32_MAX)"); - SDLTest_AssertCheck(min <= result && result <= max, "Validated returned value; expected: [%d,%d], got: %d", min, max, result); - - /* Full integer range */ - min = long_min; - max = long_max; - result = SDLTest_RandomIntegerInRange(min, max); - SDLTest_AssertPass("Call to SDLTest_RandomIntegerInRange(SINT32_MIN,SINT32_MAX)"); - SDLTest_AssertCheck(min <= result && result <= max, "Validated returned value; expected: [%d,%d], got: %d", min, max, result); - - return TEST_COMPLETED; -} - -/** - * @brief Calls to SDLTest_RandomAsciiString - */ -int -sdltest_randomAsciiString(void *arg) -{ - char* result; - size_t len; - int nonAsciiCharacters; - size_t i; - - result = SDLTest_RandomAsciiString(); - SDLTest_AssertPass("Call to SDLTest_RandomAsciiString()"); - SDLTest_AssertCheck(result != NULL, "Validate that result is not NULL"); - if (result != NULL) { - len = SDL_strlen(result); - SDLTest_AssertCheck(len >= 1 && len <= 255, "Validate that result length; expected: len=[1,255], got: %d", (int) len); - nonAsciiCharacters = 0; - for (i=0; i= 1 && len <= targetLen, "Validate that result length; expected: len=[1,%d], got: %d", (int) targetLen, (int) len); - nonAsciiCharacters = 0; - for (i=0; i - -#include "SDL.h" -#include "SDL_test.h" - - -/* Test case functions */ - -/** - * @brief Call to SDL_strlcpy - */ -#undef SDL_strlcpy -int -stdlib_strlcpy(void *arg) -{ - size_t result; - char text[1024]; - const char *expected; - - result = SDL_strlcpy(text, "foo", sizeof(text)); - expected = "foo"; - SDLTest_AssertPass("Call to SDL_strlcpy(\"foo\")"); - SDLTest_AssertCheck(SDL_strcmp(text, expected) == 0, "Check text, expected: %s, got: %s", expected, text); - SDLTest_AssertCheck(result == SDL_strlen(text), "Check result value, expected: %d, got: %d", (int) SDL_strlen(text), (int) result); - - result = SDL_strlcpy(text, "foo", 2); - expected = "f"; - SDLTest_AssertPass("Call to SDL_strlcpy(\"foo\") with buffer size 2"); - SDLTest_AssertCheck(SDL_strcmp(text, expected) == 0, "Check text, expected: %s, got: %s", expected, text); - SDLTest_AssertCheck(result == 3, "Check result value, expected: 3, got: %d", (int) result); - - return TEST_COMPLETED; -} - -/** - * @brief Call to SDL_snprintf - */ -#undef SDL_snprintf -int -stdlib_snprintf(void *arg) -{ - int result; - char text[1024]; - const char *expected; - - result = SDL_snprintf(text, sizeof(text), "%s", "foo"); - expected = "foo"; - SDLTest_AssertPass("Call to SDL_snprintf(\"%%s\", \"foo\")"); - SDLTest_AssertCheck(SDL_strcmp(text, expected) == 0, "Check text, expected: %s, got: %s", expected, text); - SDLTest_AssertCheck(result == SDL_strlen(text), "Check result value, expected: %d, got: %d", (int) SDL_strlen(text), result); - - result = SDL_snprintf(text, 2, "%s", "foo"); - expected = "f"; - SDLTest_AssertPass("Call to SDL_snprintf(\"%%s\", \"foo\") with buffer size 2"); - SDLTest_AssertCheck(SDL_strcmp(text, expected) == 0, "Check text, expected: %s, got: %s", expected, text); - SDLTest_AssertCheck(result == 3, "Check result value, expected: 3, got: %d", result); - - result = SDL_snprintf(NULL, 0, "%s", "foo"); - SDLTest_AssertCheck(result == 3, "Check result value, expected: 3, got: %d", result); - - result = SDL_snprintf(text, sizeof(text), "%f", 1.0); - expected = "1.000000"; - SDLTest_AssertPass("Call to SDL_snprintf(\"%%f\", 1.0)"); - SDLTest_AssertCheck(SDL_strcmp(text, expected) == 0, "Check text, expected: %s, got: %s", expected, text); - SDLTest_AssertCheck(result == SDL_strlen(text), "Check result value, expected: %d, got: %d", (int) SDL_strlen(text), result); - - result = SDL_snprintf(text, sizeof(text), "%.f", 1.0); - expected = "1"; - SDLTest_AssertPass("Call to SDL_snprintf(\"%%.f\", 1.0)"); - SDLTest_AssertCheck(SDL_strcmp(text, expected) == 0, "Check text, expected: %s, got: %s", expected, text); - SDLTest_AssertCheck(result == SDL_strlen(text), "Check result value, expected: %d, got: %d", (int) SDL_strlen(text), result); - - result = SDL_snprintf(text, sizeof(text), "%#.f", 1.0); - expected = "1."; - SDLTest_AssertPass("Call to SDL_snprintf(\"%%#.f\", 1.0)"); - SDLTest_AssertCheck(SDL_strcmp(text, expected) == 0, "Check text, expected: %s, got: %s", expected, text); - SDLTest_AssertCheck(result == SDL_strlen(text), "Check result value, expected: %d, got: %d", (int) SDL_strlen(text), result); - - result = SDL_snprintf(text, sizeof(text), "%f", 1.0 + 1.0 / 3.0); - expected = "1.333333"; - SDLTest_AssertPass("Call to SDL_snprintf(\"%%f\", 1.0 + 1.0 / 3.0)"); - SDLTest_AssertCheck(SDL_strcmp(text, expected) == 0, "Check text, expected: %s, got: %s", expected, text); - SDLTest_AssertCheck(result == SDL_strlen(text), "Check result value, expected: %d, got: %d", (int) SDL_strlen(text), result); - - result = SDL_snprintf(text, sizeof(text), "%+f", 1.0 + 1.0 / 3.0); - expected = "+1.333333"; - SDLTest_AssertPass("Call to SDL_snprintf(\"%%+f\", 1.0 + 1.0 / 3.0)"); - SDLTest_AssertCheck(SDL_strcmp(text, expected) == 0, "Check text, expected: %s, got: %s", expected, text); - SDLTest_AssertCheck(result == SDL_strlen(text), "Check result value, expected: %d, got: %d", (int) SDL_strlen(text), result); - - result = SDL_snprintf(text, sizeof(text), "%.2f", 1.0 + 1.0 / 3.0); - expected = "1.33"; - SDLTest_AssertPass("Call to SDL_snprintf(\"%%.2f\", 1.0 + 1.0 / 3.0)"); - SDLTest_AssertCheck(SDL_strcmp(text, expected) == 0, "Check text, expected: %s, got: %s", expected, text); - SDLTest_AssertCheck(result == SDL_strlen(text), "Check result value, expected: %d, got: %d", (int) SDL_strlen(text), result); - - result = SDL_snprintf(text, sizeof(text), "%6.2f", 1.0 + 1.0 / 3.0); - expected = " 1.33"; - SDLTest_AssertPass("Call to SDL_snprintf(\"%%6.2f\", 1.0 + 1.0 / 3.0)"); - SDLTest_AssertCheck(SDL_strcmp(text, expected) == 0, "Check text, expected: '%s', got: '%s'", expected, text); - SDLTest_AssertCheck(result == SDL_strlen(text), "Check result value, expected: %d, got: %d", (int) SDL_strlen(text), result); - - result = SDL_snprintf(text, sizeof(text), "%06.2f", 1.0 + 1.0 / 3.0); - expected = "001.33"; - SDLTest_AssertPass("Call to SDL_snprintf(\"%%06.2f\", 1.0 + 1.0 / 3.0)"); - SDLTest_AssertCheck(SDL_strcmp(text, expected) == 0, "Check text, expected: '%s', got: '%s'", expected, text); - SDLTest_AssertCheck(result == SDL_strlen(text), "Check result value, expected: %d, got: %d", (int) SDL_strlen(text), result); - - result = SDL_snprintf(text, 5, "%06.2f", 1.0 + 1.0 / 3.0); - expected = "001."; - SDLTest_AssertPass("Call to SDL_snprintf(\"%%06.2f\", 1.0 + 1.0 / 3.0) with buffer size 5"); - SDLTest_AssertCheck(SDL_strcmp(text, expected) == 0, "Check text, expected: '%s', got: '%s'", expected, text); - SDLTest_AssertCheck(result == 6, "Check result value, expected: 6, got: %d", result); - - return TEST_COMPLETED; -} - -/** - * @brief Call to SDL_getenv and SDL_setenv - */ -int -stdlib_getsetenv(void *arg) -{ - const int nameLen = 16; - char name[17]; - int counter; - int result; - char * value1; - char * value2; - char * expected; - int overwrite; - char * text; - - /* Create a random name. This tests SDL_getenv, since we need to */ - /* make sure the variable is not set yet (it shouldn't). */ - do { - for(counter = 0; counter < nameLen; counter++) { - name[counter] = (char)SDLTest_RandomIntegerInRange(65, 90); - } - name[nameLen] = '\0'; - - text = SDL_getenv(name); - SDLTest_AssertPass("Call to SDL_getenv('%s')", name); - if (text != NULL) { - SDLTest_Log("Expected: NULL, Got: '%s' (%i)", text, (int) SDL_strlen(text)); - } - } while (text != NULL); - - /* Create random values to set */ - value1 = SDLTest_RandomAsciiStringOfSize(10); - value2 = SDLTest_RandomAsciiStringOfSize(10); - - /* Set value 1 without overwrite */ - overwrite = 0; - expected = value1; - result = SDL_setenv(name, value1, overwrite); - SDLTest_AssertPass("Call to SDL_setenv('%s','%s', %i)", name, value1, overwrite); - SDLTest_AssertCheck(result == 0, "Check result, expected: 0, got: %i", result); - - /* Check value */ - text = SDL_getenv(name); - SDLTest_AssertPass("Call to SDL_getenv('%s')", name); - SDLTest_AssertCheck(text != NULL, "Verify returned text is not NULL"); - if (text != NULL) { - SDLTest_AssertCheck( - SDL_strcmp(text, expected) == 0, - "Verify returned text, expected: %s, got: %s", - expected, - text); - } - - /* Set value 2 with overwrite */ - overwrite = 1; - expected = value2; - result = SDL_setenv(name, value2, overwrite); - SDLTest_AssertPass("Call to SDL_setenv('%s','%s', %i)", name, value2, overwrite); - SDLTest_AssertCheck(result == 0, "Check result, expected: 0, got: %i", result); - - /* Check value */ - text = SDL_getenv(name); - SDLTest_AssertPass("Call to SDL_getenv('%s')", name); - SDLTest_AssertCheck(text != NULL, "Verify returned text is not NULL"); - if (text != NULL) { - SDLTest_AssertCheck( - SDL_strcmp(text, expected) == 0, - "Verify returned text, expected: %s, got: %s", - expected, - text); - } - - /* Set value 1 without overwrite */ - overwrite = 0; - expected = value2; - result = SDL_setenv(name, value1, overwrite); - SDLTest_AssertPass("Call to SDL_setenv('%s','%s', %i)", name, value1, overwrite); - SDLTest_AssertCheck(result == 0, "Check result, expected: 0, got: %i", result); - - /* Check value */ - text = SDL_getenv(name); - SDLTest_AssertPass("Call to SDL_getenv('%s')", name); - SDLTest_AssertCheck(text != NULL, "Verify returned text is not NULL"); - if (text != NULL) { - SDLTest_AssertCheck( - SDL_strcmp(text, expected) == 0, - "Verify returned text, expected: %s, got: %s", - expected, - text); - } - - /* Set value 1 without overwrite */ - overwrite = 1; - expected = value1; - result = SDL_setenv(name, value1, overwrite); - SDLTest_AssertPass("Call to SDL_setenv('%s','%s', %i)", name, value1, overwrite); - SDLTest_AssertCheck(result == 0, "Check result, expected: 0, got: %i", result); - - /* Check value */ - text = SDL_getenv(name); - SDLTest_AssertPass("Call to SDL_getenv('%s')", name); - SDLTest_AssertCheck(text != NULL, "Verify returned text is not NULL"); - if (text != NULL) { - SDLTest_AssertCheck( - SDL_strcmp(text, expected) == 0, - "Verify returned text, expected: %s, got: %s", - expected, - text); - } - - /* Negative cases */ - for (overwrite=0; overwrite <= 1; overwrite++) { - result = SDL_setenv(NULL, value1, overwrite); - SDLTest_AssertPass("Call to SDL_setenv(NULL,'%s', %i)", value1, overwrite); - SDLTest_AssertCheck(result == -1, "Check result, expected: -1, got: %i", result); - result = SDL_setenv("", value1, overwrite); - SDLTest_AssertPass("Call to SDL_setenv('','%s', %i)", value1, overwrite); - SDLTest_AssertCheck(result == -1, "Check result, expected: -1, got: %i", result); - result = SDL_setenv("=", value1, overwrite); - SDLTest_AssertPass("Call to SDL_setenv('=','%s', %i)", value1, overwrite); - SDLTest_AssertCheck(result == -1, "Check result, expected: -1, got: %i", result); - result = SDL_setenv(name, NULL, overwrite); - SDLTest_AssertPass("Call to SDL_setenv('%s', NULL, %i)", name, overwrite); - SDLTest_AssertCheck(result == -1, "Check result, expected: -1, got: %i", result); - } - - /* Clean up */ - SDL_free(value1); - SDL_free(value2); - - return TEST_COMPLETED; -} - -/** - * @brief Call to SDL_sscanf - */ -#undef SDL_sscanf -int -stdlib_sscanf(void *arg) -{ - int output; - int result; - int expected_output; - int expected_result; - - expected_output = output = 123; - expected_result = -1; - result = SDL_sscanf("", "%i", &output); - SDLTest_AssertPass("Call to SDL_sscanf(\"\", \"%%i\", &output)"); - SDLTest_AssertCheck(expected_output == output, "Check output, expected: %i, got: %i", expected_output, output); - SDLTest_AssertCheck(expected_result == result, "Check return value, expected: %i, got: %i", expected_result, result); - - expected_output = output = 123; - expected_result = 0; - result = SDL_sscanf("a", "%i", &output); - SDLTest_AssertPass("Call to SDL_sscanf(\"a\", \"%%i\", &output)"); - SDLTest_AssertCheck(expected_output == output, "Check output, expected: %i, got: %i", expected_output, output); - SDLTest_AssertCheck(expected_result == result, "Check return value, expected: %i, got: %i", expected_result, result); - - output = 123; - expected_output = 2; - expected_result = 1; - result = SDL_sscanf("2", "%i", &output); - SDLTest_AssertPass("Call to SDL_sscanf(\"2\", \"%%i\", &output)"); - SDLTest_AssertCheck(expected_output == output, "Check output, expected: %i, got: %i", expected_output, output); - SDLTest_AssertCheck(expected_result == result, "Check return value, expected: %i, got: %i", expected_result, result); - - return TEST_COMPLETED; -} - -/* ================= Test References ================== */ - -/* Standard C routine test cases */ -static const SDLTest_TestCaseReference stdlibTest1 = - { (SDLTest_TestCaseFp)stdlib_strlcpy, "stdlib_strlcpy", "Call to SDL_strlcpy", TEST_ENABLED }; - -static const SDLTest_TestCaseReference stdlibTest2 = - { (SDLTest_TestCaseFp)stdlib_snprintf, "stdlib_snprintf", "Call to SDL_snprintf", TEST_ENABLED }; - -static const SDLTest_TestCaseReference stdlibTest3 = - { (SDLTest_TestCaseFp)stdlib_getsetenv, "stdlib_getsetenv", "Call to SDL_getenv and SDL_setenv", TEST_ENABLED }; - -static const SDLTest_TestCaseReference stdlibTest4 = - { (SDLTest_TestCaseFp)stdlib_sscanf, "stdlib_sscanf", "Call to SDL_sscanf", TEST_ENABLED }; - -/* Sequence of Standard C routine test cases */ -static const SDLTest_TestCaseReference *stdlibTests[] = { - &stdlibTest1, &stdlibTest2, &stdlibTest3, &stdlibTest4, NULL -}; - -/* Standard C routine test suite (global) */ -SDLTest_TestSuiteReference stdlibTestSuite = { - "Stdlib", - NULL, - stdlibTests, - NULL -}; diff --git a/SDL2-2.0.12/test/testautomation_suites.h b/SDL2-2.0.12/test/testautomation_suites.h deleted file mode 100644 index b5f921e..0000000 --- a/SDL2-2.0.12/test/testautomation_suites.h +++ /dev/null @@ -1,54 +0,0 @@ -/** - * Reference to all test suites. - * - */ - -#ifndef _testsuites_h -#define _testsuites_h - -#include "SDL_test.h" - -/* Test collections */ -extern SDLTest_TestSuiteReference audioTestSuite; -extern SDLTest_TestSuiteReference clipboardTestSuite; -extern SDLTest_TestSuiteReference eventsTestSuite; -extern SDLTest_TestSuiteReference keyboardTestSuite; -extern SDLTest_TestSuiteReference mainTestSuite; -extern SDLTest_TestSuiteReference mouseTestSuite; -extern SDLTest_TestSuiteReference pixelsTestSuite; -extern SDLTest_TestSuiteReference platformTestSuite; -extern SDLTest_TestSuiteReference rectTestSuite; -extern SDLTest_TestSuiteReference renderTestSuite; -extern SDLTest_TestSuiteReference rwopsTestSuite; -extern SDLTest_TestSuiteReference sdltestTestSuite; -extern SDLTest_TestSuiteReference stdlibTestSuite; -extern SDLTest_TestSuiteReference surfaceTestSuite; -extern SDLTest_TestSuiteReference syswmTestSuite; -extern SDLTest_TestSuiteReference timerTestSuite; -extern SDLTest_TestSuiteReference videoTestSuite; -extern SDLTest_TestSuiteReference hintsTestSuite; - -/* All test suites */ -SDLTest_TestSuiteReference *testSuites[] = { - &audioTestSuite, - &clipboardTestSuite, - &eventsTestSuite, - &keyboardTestSuite, - &mainTestSuite, - &mouseTestSuite, - &pixelsTestSuite, - &platformTestSuite, - &rectTestSuite, - &renderTestSuite, - &rwopsTestSuite, - &sdltestTestSuite, - &stdlibTestSuite, - &surfaceTestSuite, - &syswmTestSuite, - &timerTestSuite, - &videoTestSuite, - &hintsTestSuite, - NULL -}; - -#endif diff --git a/SDL2-2.0.12/test/testautomation_surface.c b/SDL2-2.0.12/test/testautomation_surface.c deleted file mode 100644 index 92c0786..0000000 --- a/SDL2-2.0.12/test/testautomation_surface.c +++ /dev/null @@ -1,648 +0,0 @@ -/** - * Original code: automated SDL surface test written by Edgar Simo "bobbens" - * Adapted/rewritten for test lib by Andreas Schiffler - */ - -/* Supress C4996 VS compiler warnings for unlink() */ -#define _CRT_SECURE_NO_DEPRECATE -#define _CRT_NONSTDC_NO_DEPRECATE - -#include -#ifndef _MSC_VER -#include -#endif -#include - -#include "SDL.h" -#include "SDL_test.h" - -#ifdef __MACOSX__ -#include /* For unlink() */ -#endif - -/* ================= Test Case Implementation ================== */ - -/* Shared test surface */ - -static SDL_Surface *referenceSurface = NULL; -static SDL_Surface *testSurface = NULL; - -/* Helper functions for the test cases */ - -#define TEST_SURFACE_WIDTH testSurface->w -#define TEST_SURFACE_HEIGHT testSurface->h - -/* Fixture */ - -/* Create a 32-bit writable surface for blitting tests */ -void -_surfaceSetUp(void *arg) -{ - int result; - SDL_BlendMode blendMode = SDL_BLENDMODE_NONE; - SDL_BlendMode currentBlendMode; - Uint32 rmask, gmask, bmask, amask; -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - rmask = 0xff000000; - gmask = 0x00ff0000; - bmask = 0x0000ff00; - amask = 0x000000ff; -#else - rmask = 0x000000ff; - gmask = 0x0000ff00; - bmask = 0x00ff0000; - amask = 0xff000000; -#endif - - referenceSurface = SDLTest_ImageBlit(); /* For size info */ - testSurface = SDL_CreateRGBSurface(SDL_SWSURFACE, referenceSurface->w, referenceSurface->h, 32, rmask, gmask, bmask, amask); - SDLTest_AssertCheck(testSurface != NULL, "Check that testSurface is not NULL"); - if (testSurface != NULL) { - /* Disable blend mode for target surface */ - result = SDL_SetSurfaceBlendMode(testSurface, blendMode); - SDLTest_AssertCheck(result == 0, "Validate result from SDL_SetSurfaceBlendMode, expected: 0, got: %i", result); - result = SDL_GetSurfaceBlendMode(testSurface, ¤tBlendMode); - SDLTest_AssertCheck(result == 0, "Validate result from SDL_GetSurfaceBlendMode, expected: 0, got: %i", result); - SDLTest_AssertCheck(currentBlendMode == blendMode, "Validate blendMode, expected: %i, got: %i", blendMode, currentBlendMode); - } -} - -void -_surfaceTearDown(void *arg) -{ - SDL_FreeSurface(referenceSurface); - referenceSurface = NULL; - SDL_FreeSurface(testSurface); - testSurface = NULL; -} - -/** - * Helper that clears the test surface - */ -void _clearTestSurface() -{ - int ret; - Uint32 color; - - /* Clear surface. */ - color = SDL_MapRGBA( testSurface->format, 0, 0, 0, 0); - SDLTest_AssertPass("Call to SDL_MapRGBA()"); - ret = SDL_FillRect( testSurface, NULL, color); - SDLTest_AssertPass("Call to SDL_FillRect()"); - SDLTest_AssertCheck(ret == 0, "Verify result from SDL_FillRect, expected: 0, got: %i", ret); -} - -/** - * Helper that blits in a specific blend mode, -1 for basic blitting, -2 for color mod, -3 for alpha mod, -4 for mixed blend modes. - */ -void _testBlitBlendMode(int mode) -{ - int ret; - int i, j, ni, nj; - SDL_Surface *face; - SDL_Rect rect; - int nmode; - SDL_BlendMode bmode; - int checkFailCount1; - int checkFailCount2; - int checkFailCount3; - int checkFailCount4; - - /* Check test surface */ - SDLTest_AssertCheck(testSurface != NULL, "Verify testSurface is not NULL"); - if (testSurface == NULL) return; - - /* Create sample surface */ - face = SDLTest_ImageFace(); - SDLTest_AssertCheck(face != NULL, "Verify face surface is not NULL"); - if (face == NULL) return; - - /* Reset alpha modulation */ - ret = SDL_SetSurfaceAlphaMod(face, 255); - SDLTest_AssertPass("Call to SDL_SetSurfaceAlphaMod()"); - SDLTest_AssertCheck(ret == 0, "Verify result from SDL_SetSurfaceAlphaMod(), expected: 0, got: %i", ret); - - /* Reset color modulation */ - ret = SDL_SetSurfaceColorMod(face, 255, 255, 255); - SDLTest_AssertPass("Call to SDL_SetSurfaceColorMod()"); - SDLTest_AssertCheck(ret == 0, "Verify result from SDL_SetSurfaceColorMod(), expected: 0, got: %i", ret); - - /* Reset color key */ - ret = SDL_SetColorKey(face, SDL_FALSE, 0); - SDLTest_AssertPass("Call to SDL_SetColorKey()"); - SDLTest_AssertCheck(ret == 0, "Verify result from SDL_SetColorKey(), expected: 0, got: %i", ret); - - /* Clear the test surface */ - _clearTestSurface(); - - /* Target rect size */ - rect.w = face->w; - rect.h = face->h; - - /* Steps to take */ - ni = testSurface->w - face->w; - nj = testSurface->h - face->h; - - /* Optionally set blend mode. */ - if (mode >= 0) { - ret = SDL_SetSurfaceBlendMode( face, (SDL_BlendMode)mode ); - SDLTest_AssertPass("Call to SDL_SetSurfaceBlendMode()"); - SDLTest_AssertCheck(ret == 0, "Verify result from SDL_SetSurfaceBlendMode(..., %i), expected: 0, got: %i", mode, ret); - } - - /* Test blend mode. */ - checkFailCount1 = 0; - checkFailCount2 = 0; - checkFailCount3 = 0; - checkFailCount4 = 0; - for (j=0; j <= nj; j+=4) { - for (i=0; i <= ni; i+=4) { - if (mode == -2) { - /* Set color mod. */ - ret = SDL_SetSurfaceColorMod( face, (255/nj)*j, (255/ni)*i, (255/nj)*j ); - if (ret != 0) checkFailCount2++; - } - else if (mode == -3) { - /* Set alpha mod. */ - ret = SDL_SetSurfaceAlphaMod( face, (255/ni)*i ); - if (ret != 0) checkFailCount3++; - } - else if (mode == -4) { - /* Crazy blending mode magic. */ - nmode = (i/4*j/4) % 4; - if (nmode==0) { - bmode = SDL_BLENDMODE_NONE; - } else if (nmode==1) { - bmode = SDL_BLENDMODE_BLEND; - } else if (nmode==2) { - bmode = SDL_BLENDMODE_ADD; - } else if (nmode==3) { - bmode = SDL_BLENDMODE_MOD; - } - ret = SDL_SetSurfaceBlendMode( face, bmode ); - if (ret != 0) checkFailCount4++; - } - - /* Blitting. */ - rect.x = i; - rect.y = j; - ret = SDL_BlitSurface( face, NULL, testSurface, &rect ); - if (ret != 0) checkFailCount1++; - } - } - SDLTest_AssertCheck(checkFailCount1 == 0, "Validate results from calls to SDL_BlitSurface, expected: 0, got: %i", checkFailCount1); - SDLTest_AssertCheck(checkFailCount2 == 0, "Validate results from calls to SDL_SetSurfaceColorMod, expected: 0, got: %i", checkFailCount2); - SDLTest_AssertCheck(checkFailCount3 == 0, "Validate results from calls to SDL_SetSurfaceAlphaMod, expected: 0, got: %i", checkFailCount3); - SDLTest_AssertCheck(checkFailCount4 == 0, "Validate results from calls to SDL_SetSurfaceBlendMode, expected: 0, got: %i", checkFailCount4); - - /* Clean up */ - SDL_FreeSurface(face); - face = NULL; -} - -/* Helper to check that a file exists */ -void -_AssertFileExist(const char *filename) -{ - struct stat st; - int ret = stat(filename, &st); - - SDLTest_AssertCheck(ret == 0, "Verify file '%s' exists", filename); -} - - -/* Test case functions */ - -/** - * @brief Tests sprite saving and loading - */ -int -surface_testSaveLoadBitmap(void *arg) -{ - int ret; - const char *sampleFilename = "testSaveLoadBitmap.bmp"; - SDL_Surface *face; - SDL_Surface *rface; - - /* Create sample surface */ - face = SDLTest_ImageFace(); - SDLTest_AssertCheck(face != NULL, "Verify face surface is not NULL"); - if (face == NULL) return TEST_ABORTED; - - /* Delete test file; ignore errors */ - unlink(sampleFilename); - - /* Save a surface */ - ret = SDL_SaveBMP(face, sampleFilename); - SDLTest_AssertPass("Call to SDL_SaveBMP()"); - SDLTest_AssertCheck(ret == 0, "Verify result from SDL_SaveBMP, expected: 0, got: %i", ret); - _AssertFileExist(sampleFilename); - - /* Load a surface */ - rface = SDL_LoadBMP(sampleFilename); - SDLTest_AssertPass("Call to SDL_LoadBMP()"); - SDLTest_AssertCheck(rface != NULL, "Verify result from SDL_LoadBMP is not NULL"); - if (rface != NULL) { - SDLTest_AssertCheck(face->w == rface->w, "Verify width of loaded surface, expected: %i, got: %i", face->w, rface->w); - SDLTest_AssertCheck(face->h == rface->h, "Verify height of loaded surface, expected: %i, got: %i", face->h, rface->h); - } - - /* Delete test file; ignore errors */ - unlink(sampleFilename); - - /* Clean up */ - SDL_FreeSurface(face); - face = NULL; - SDL_FreeSurface(rface); - rface = NULL; - - return TEST_COMPLETED; -} - -/* ! - * Tests surface conversion. - */ -int -surface_testSurfaceConversion(void *arg) -{ - SDL_Surface *rface = NULL, *face = NULL; - int ret = 0; - - /* Create sample surface */ - face = SDLTest_ImageFace(); - SDLTest_AssertCheck(face != NULL, "Verify face surface is not NULL"); - if (face == NULL) - return TEST_ABORTED; - - /* Set transparent pixel as the pixel at (0,0) */ - if (face->format->palette) { - ret = SDL_SetColorKey(face, SDL_RLEACCEL, *(Uint8 *) face->pixels); - SDLTest_AssertPass("Call to SDL_SetColorKey()"); - SDLTest_AssertCheck(ret == 0, "Verify result from SDL_SetColorKey, expected: 0, got: %i", ret); - } - - /* Convert to 32 bit to compare. */ - rface = SDL_ConvertSurface( face, testSurface->format, 0 ); - SDLTest_AssertPass("Call to SDL_ConvertSurface()"); - SDLTest_AssertCheck(rface != NULL, "Verify result from SDL_ConvertSurface is not NULL"); - - /* Compare surface. */ - ret = SDLTest_CompareSurfaces( rface, face, 0 ); - SDLTest_AssertCheck(ret == 0, "Validate result from SDLTest_CompareSurfaces, expected: 0, got: %i", ret); - - /* Clean up. */ - SDL_FreeSurface(face); - face = NULL; - SDL_FreeSurface(rface); - rface = NULL; - - return TEST_COMPLETED; -} - - -/* ! - * Tests surface conversion across all pixel formats. - */ -int -surface_testCompleteSurfaceConversion(void *arg) -{ - Uint32 pixel_formats[] = { - SDL_PIXELFORMAT_INDEX8, - SDL_PIXELFORMAT_RGB332, - SDL_PIXELFORMAT_RGB444, - SDL_PIXELFORMAT_BGR444, - SDL_PIXELFORMAT_RGB555, - SDL_PIXELFORMAT_BGR555, - SDL_PIXELFORMAT_ARGB4444, - SDL_PIXELFORMAT_RGBA4444, - SDL_PIXELFORMAT_ABGR4444, - SDL_PIXELFORMAT_BGRA4444, - SDL_PIXELFORMAT_ARGB1555, - SDL_PIXELFORMAT_RGBA5551, - SDL_PIXELFORMAT_ABGR1555, - SDL_PIXELFORMAT_BGRA5551, - SDL_PIXELFORMAT_RGB565, - SDL_PIXELFORMAT_BGR565, - SDL_PIXELFORMAT_RGB24, - SDL_PIXELFORMAT_BGR24, - SDL_PIXELFORMAT_RGB888, - SDL_PIXELFORMAT_RGBX8888, - SDL_PIXELFORMAT_BGR888, - SDL_PIXELFORMAT_BGRX8888, - SDL_PIXELFORMAT_ARGB8888, - SDL_PIXELFORMAT_RGBA8888, - SDL_PIXELFORMAT_ABGR8888, - SDL_PIXELFORMAT_BGRA8888, - SDL_PIXELFORMAT_ARGB2101010, - }; - SDL_Surface *face = NULL, *cvt1, *cvt2, *final; - SDL_PixelFormat *fmt1, *fmt2; - int i, j, ret = 0; - - /* Create sample surface */ - face = SDLTest_ImageFace(); - SDLTest_AssertCheck(face != NULL, "Verify face surface is not NULL"); - if (face == NULL) - return TEST_ABORTED; - - /* Set transparent pixel as the pixel at (0,0) */ - if (face->format->palette) { - ret = SDL_SetColorKey(face, SDL_RLEACCEL, *(Uint8 *) face->pixels); - SDLTest_AssertPass("Call to SDL_SetColorKey()"); - SDLTest_AssertCheck(ret == 0, "Verify result from SDL_SetColorKey, expected: 0, got: %i", ret); - } - - for ( i = 0; i < SDL_arraysize(pixel_formats); ++i ) { - for ( j = 0; j < SDL_arraysize(pixel_formats); ++j ) { - fmt1 = SDL_AllocFormat(pixel_formats[i]); - SDL_assert(fmt1 != NULL); - cvt1 = SDL_ConvertSurface(face, fmt1, 0); - SDL_assert(cvt1 != NULL); - - fmt2 = SDL_AllocFormat(pixel_formats[j]); - SDL_assert(fmt1 != NULL); - cvt2 = SDL_ConvertSurface(cvt1, fmt2, 0); - SDL_assert(cvt2 != NULL); - - if ( fmt1->BytesPerPixel == face->format->BytesPerPixel && - fmt2->BytesPerPixel == face->format->BytesPerPixel && - (fmt1->Amask != 0) == (face->format->Amask != 0) && - (fmt2->Amask != 0) == (face->format->Amask != 0) ) { - final = SDL_ConvertSurface( cvt2, face->format, 0 ); - SDL_assert(final != NULL); - - /* Compare surface. */ - ret = SDLTest_CompareSurfaces( face, final, 0 ); - SDLTest_AssertCheck(ret == 0, "Validate result from SDLTest_CompareSurfaces, expected: 0, got: %i", ret); - SDL_FreeSurface(final); - } - - SDL_FreeSurface(cvt1); - SDL_FreeFormat(fmt1); - SDL_FreeSurface(cvt2); - SDL_FreeFormat(fmt2); - } - } - - /* Clean up. */ - SDL_FreeSurface( face ); - - return TEST_COMPLETED; -} - - -/** - * @brief Tests sprite loading. A failure case. - */ -int -surface_testLoadFailure(void *arg) -{ - SDL_Surface *face = SDL_LoadBMP("nonexistant.bmp"); - SDLTest_AssertCheck(face == NULL, "SDL_CreateLoadBmp"); - - return TEST_COMPLETED; -} - -/** - * @brief Tests some blitting routines. - */ -int -surface_testBlit(void *arg) -{ - int ret; - SDL_Surface *compareSurface; - - /* Basic blitting */ - _testBlitBlendMode(-1); - - /* Verify result by comparing surfaces */ - compareSurface = SDLTest_ImageBlit(); - ret = SDLTest_CompareSurfaces( testSurface, compareSurface, 0 ); - SDLTest_AssertCheck(ret == 0, "Validate result from SDLTest_CompareSurfaces, expected: 0, got: %i", ret); - - /* Clean up. */ - SDL_FreeSurface(compareSurface); - - return TEST_COMPLETED; -} - -/** - * @brief Tests some blitting routines with color mod - */ -int -surface_testBlitColorMod(void *arg) -{ - int ret; - SDL_Surface *compareSurface; - - /* Basic blitting with color mod */ - _testBlitBlendMode(-2); - - /* Verify result by comparing surfaces */ - compareSurface = SDLTest_ImageBlitColor(); - ret = SDLTest_CompareSurfaces( testSurface, compareSurface, 0 ); - SDLTest_AssertCheck(ret == 0, "Validate result from SDLTest_CompareSurfaces, expected: 0, got: %i", ret); - - /* Clean up. */ - SDL_FreeSurface(compareSurface); - - return TEST_COMPLETED; -} - -/** - * @brief Tests some blitting routines with alpha mod - */ -int -surface_testBlitAlphaMod(void *arg) -{ - int ret; - SDL_Surface *compareSurface; - - /* Basic blitting with alpha mod */ - _testBlitBlendMode(-3); - - /* Verify result by comparing surfaces */ - compareSurface = SDLTest_ImageBlitAlpha(); - ret = SDLTest_CompareSurfaces( testSurface, compareSurface, 0 ); - SDLTest_AssertCheck(ret == 0, "Validate result from SDLTest_CompareSurfaces, expected: 0, got: %i", ret); - - /* Clean up. */ - SDL_FreeSurface(compareSurface); - - return TEST_COMPLETED; -} - - -/** - * @brief Tests some more blitting routines. - */ -int -surface_testBlitBlendNone(void *arg) -{ - int ret; - SDL_Surface *compareSurface; - - /* Basic blitting */ - _testBlitBlendMode(SDL_BLENDMODE_NONE); - - /* Verify result by comparing surfaces */ - compareSurface = SDLTest_ImageBlitBlendNone(); - ret = SDLTest_CompareSurfaces( testSurface, compareSurface, 0 ); - SDLTest_AssertCheck(ret == 0, "Validate result from SDLTest_CompareSurfaces, expected: 0, got: %i", ret); - - /* Clean up. */ - SDL_FreeSurface(compareSurface); - - return TEST_COMPLETED; -} - -/** - * @brief Tests some more blitting routines. - */ -int -surface_testBlitBlendBlend(void *arg) -{ - int ret; - SDL_Surface *compareSurface; - - /* Blend blitting */ - _testBlitBlendMode(SDL_BLENDMODE_BLEND); - - /* Verify result by comparing surfaces */ - compareSurface = SDLTest_ImageBlitBlend(); - ret = SDLTest_CompareSurfaces( testSurface, compareSurface, 0 ); - SDLTest_AssertCheck(ret == 0, "Validate result from SDLTest_CompareSurfaces, expected: 0, got: %i", ret); - - /* Clean up. */ - SDL_FreeSurface(compareSurface); - - return TEST_COMPLETED; -} - -/** - * @brief Tests some more blitting routines. - */ -int -surface_testBlitBlendAdd(void *arg) -{ - int ret; - SDL_Surface *compareSurface; - - /* Add blitting */ - _testBlitBlendMode(SDL_BLENDMODE_ADD); - - /* Verify result by comparing surfaces */ - compareSurface = SDLTest_ImageBlitBlendAdd(); - ret = SDLTest_CompareSurfaces( testSurface, compareSurface, 0 ); - SDLTest_AssertCheck(ret == 0, "Validate result from SDLTest_CompareSurfaces, expected: 0, got: %i", ret); - - /* Clean up. */ - SDL_FreeSurface(compareSurface); - - return TEST_COMPLETED; -} - -/** - * @brief Tests some more blitting routines. - */ -int -surface_testBlitBlendMod(void *arg) -{ - int ret; - SDL_Surface *compareSurface; - - /* Mod blitting */ - _testBlitBlendMode(SDL_BLENDMODE_MOD); - - /* Verify result by comparing surfaces */ - compareSurface = SDLTest_ImageBlitBlendMod(); - ret = SDLTest_CompareSurfaces( testSurface, compareSurface, 0 ); - SDLTest_AssertCheck(ret == 0, "Validate result from SDLTest_CompareSurfaces, expected: 0, got: %i", ret); - - /* Clean up. */ - SDL_FreeSurface(compareSurface); - - return TEST_COMPLETED; -} - -/** - * @brief Tests some more blitting routines with loop - */ -int -surface_testBlitBlendLoop(void *arg) { - - int ret; - SDL_Surface *compareSurface; - - /* All blitting modes */ - _testBlitBlendMode(-4); - - /* Verify result by comparing surfaces */ - compareSurface = SDLTest_ImageBlitBlendAll(); - ret = SDLTest_CompareSurfaces( testSurface, compareSurface, 0 ); - SDLTest_AssertCheck(ret == 0, "Validate result from SDLTest_CompareSurfaces, expected: 0, got: %i", ret); - - /* Clean up. */ - SDL_FreeSurface(compareSurface); - - return TEST_COMPLETED; - -} - -/* ================= Test References ================== */ - -/* Surface test cases */ -static const SDLTest_TestCaseReference surfaceTest1 = - { (SDLTest_TestCaseFp)surface_testSaveLoadBitmap, "surface_testSaveLoadBitmap", "Tests sprite saving and loading.", TEST_ENABLED}; - -static const SDLTest_TestCaseReference surfaceTest2 = - { (SDLTest_TestCaseFp)surface_testBlit, "surface_testBlit", "Tests basic blitting.", TEST_ENABLED}; - -static const SDLTest_TestCaseReference surfaceTest3 = - { (SDLTest_TestCaseFp)surface_testBlitBlendNone, "surface_testBlitBlendNone", "Tests blitting routines with none blending mode.", TEST_ENABLED}; - -static const SDLTest_TestCaseReference surfaceTest4 = - { (SDLTest_TestCaseFp)surface_testLoadFailure, "surface_testLoadFailure", "Tests sprite loading. A failure case.", TEST_ENABLED}; - -static const SDLTest_TestCaseReference surfaceTest5 = - { (SDLTest_TestCaseFp)surface_testSurfaceConversion, "surface_testSurfaceConversion", "Tests surface conversion.", TEST_ENABLED}; - -static const SDLTest_TestCaseReference surfaceTest6 = - { (SDLTest_TestCaseFp)surface_testCompleteSurfaceConversion, "surface_testCompleteSurfaceConversion", "Tests surface conversion across all pixel formats", TEST_ENABLED}; - -static const SDLTest_TestCaseReference surfaceTest7 = - { (SDLTest_TestCaseFp)surface_testBlitColorMod, "surface_testBlitColorMod", "Tests some blitting routines with color mod.", TEST_ENABLED}; - -static const SDLTest_TestCaseReference surfaceTest8 = - { (SDLTest_TestCaseFp)surface_testBlitAlphaMod, "surface_testBlitAlphaMod", "Tests some blitting routines with alpha mod.", TEST_ENABLED}; - -/* TODO: rewrite test case, define new test data and re-enable; current implementation fails */ -static const SDLTest_TestCaseReference surfaceTest9 = - { (SDLTest_TestCaseFp)surface_testBlitBlendLoop, "surface_testBlitBlendLoop", "Test blitting routines with various blending modes", TEST_DISABLED}; - -/* TODO: rewrite test case, define new test data and re-enable; current implementation fails */ -static const SDLTest_TestCaseReference surfaceTest10 = - { (SDLTest_TestCaseFp)surface_testBlitBlendBlend, "surface_testBlitBlendBlend", "Tests blitting routines with blend blending mode.", TEST_DISABLED}; - -/* TODO: rewrite test case, define new test data and re-enable; current implementation fails */ -static const SDLTest_TestCaseReference surfaceTest11 = - { (SDLTest_TestCaseFp)surface_testBlitBlendAdd, "surface_testBlitBlendAdd", "Tests blitting routines with add blending mode.", TEST_DISABLED}; - -static const SDLTest_TestCaseReference surfaceTest12 = - { (SDLTest_TestCaseFp)surface_testBlitBlendMod, "surface_testBlitBlendMod", "Tests blitting routines with mod blending mode.", TEST_ENABLED}; - -/* Sequence of Surface test cases */ -static const SDLTest_TestCaseReference *surfaceTests[] = { - &surfaceTest1, &surfaceTest2, &surfaceTest3, &surfaceTest4, &surfaceTest5, - &surfaceTest6, &surfaceTest7, &surfaceTest8, &surfaceTest9, &surfaceTest10, - &surfaceTest11, &surfaceTest12, NULL -}; - -/* Surface test suite (global) */ -SDLTest_TestSuiteReference surfaceTestSuite = { - "Surface", - _surfaceSetUp, - surfaceTests, - _surfaceTearDown - -}; diff --git a/SDL2-2.0.12/test/testautomation_syswm.c b/SDL2-2.0.12/test/testautomation_syswm.c deleted file mode 100644 index d9fd982..0000000 --- a/SDL2-2.0.12/test/testautomation_syswm.c +++ /dev/null @@ -1,61 +0,0 @@ -/** - * SysWM test suite - */ - -#include - -#include "SDL.h" -#include "SDL_syswm.h" -#include "SDL_test.h" - -/* Test case functions */ - -/** - * @brief Call to SDL_GetWindowWMInfo - */ -int -syswm_getWindowWMInfo(void *arg) -{ - SDL_bool result; - SDL_Window *window; - SDL_SysWMinfo info; - - window = SDL_CreateWindow("", 0, 0, 0, 0, SDL_WINDOW_HIDDEN); - SDLTest_AssertPass("Call to SDL_CreateWindow()"); - SDLTest_AssertCheck(window != NULL, "Check that value returned from SDL_CreateWindow is not NULL"); - if (window == NULL) { - return TEST_ABORTED; - } - - /* Initialize info structure with SDL version info */ - SDL_VERSION(&info.version); - - /* Make call */ - result = SDL_GetWindowWMInfo(window, &info); - SDLTest_AssertPass("Call to SDL_GetWindowWMInfo()"); - SDLTest_Log((result == SDL_TRUE) ? "Got window information" : "Couldn't get window information"); - - SDL_DestroyWindow(window); - SDLTest_AssertPass("Call to SDL_DestroyWindow()"); - - return TEST_COMPLETED; -} - -/* ================= Test References ================== */ - -/* SysWM test cases */ -static const SDLTest_TestCaseReference syswmTest1 = - { (SDLTest_TestCaseFp)syswm_getWindowWMInfo, "syswm_getWindowWMInfo", "Call to SDL_GetWindowWMInfo", TEST_ENABLED }; - -/* Sequence of SysWM test cases */ -static const SDLTest_TestCaseReference *syswmTests[] = { - &syswmTest1, NULL -}; - -/* SysWM test suite (global) */ -SDLTest_TestSuiteReference syswmTestSuite = { - "SysWM", - NULL, - syswmTests, - NULL -}; diff --git a/SDL2-2.0.12/test/testautomation_timer.c b/SDL2-2.0.12/test/testautomation_timer.c deleted file mode 100644 index a42eb37..0000000 --- a/SDL2-2.0.12/test/testautomation_timer.c +++ /dev/null @@ -1,201 +0,0 @@ -/** - * Timer test suite - */ - -#include - -#include "SDL.h" -#include "SDL_test.h" - -/* Flag indicating if the param should be checked */ -int _paramCheck = 0; - -/* Userdata value to check */ -int _paramValue = 0; - -/* Flag indicating that the callback was called */ -int _timerCallbackCalled = 0; - -/* Fixture */ - -void -_timerSetUp(void *arg) -{ - /* Start SDL timer subsystem */ - int ret = SDL_InitSubSystem( SDL_INIT_TIMER ); - SDLTest_AssertPass("Call to SDL_InitSubSystem(SDL_INIT_TIMER)"); - SDLTest_AssertCheck(ret==0, "Check result from SDL_InitSubSystem(SDL_INIT_TIMER)"); - if (ret != 0) { - SDLTest_LogError("%s", SDL_GetError()); - } -} - -/* Test case functions */ - -/** - * @brief Call to SDL_GetPerformanceCounter - */ -int -timer_getPerformanceCounter(void *arg) -{ - Uint64 result; - - result = SDL_GetPerformanceCounter(); - SDLTest_AssertPass("Call to SDL_GetPerformanceCounter()"); - SDLTest_AssertCheck(result > 0, "Check result value, expected: >0, got: %"SDL_PRIu64, result); - - return TEST_COMPLETED; -} - -/** - * @brief Call to SDL_GetPerformanceFrequency - */ -int -timer_getPerformanceFrequency(void *arg) -{ - Uint64 result; - - result = SDL_GetPerformanceFrequency(); - SDLTest_AssertPass("Call to SDL_GetPerformanceFrequency()"); - SDLTest_AssertCheck(result > 0, "Check result value, expected: >0, got: %"SDL_PRIu64, result); - - return TEST_COMPLETED; -} - -/** - * @brief Call to SDL_Delay and SDL_GetTicks - */ -int -timer_delayAndGetTicks(void *arg) -{ - const Uint32 testDelay = 100; - const Uint32 marginOfError = 25; - Uint32 result; - Uint32 result2; - Uint32 difference; - - /* Zero delay */ - SDL_Delay(0); - SDLTest_AssertPass("Call to SDL_Delay(0)"); - - /* Non-zero delay */ - SDL_Delay(1); - SDLTest_AssertPass("Call to SDL_Delay(1)"); - - SDL_Delay(SDLTest_RandomIntegerInRange(5, 15)); - SDLTest_AssertPass("Call to SDL_Delay()"); - - /* Get ticks count - should be non-zero by now */ - result = SDL_GetTicks(); - SDLTest_AssertPass("Call to SDL_GetTicks()"); - SDLTest_AssertCheck(result > 0, "Check result value, expected: >0, got: %d", result); - - /* Delay a bit longer and measure ticks and verify difference */ - SDL_Delay(testDelay); - SDLTest_AssertPass("Call to SDL_Delay(%d)", testDelay); - result2 = SDL_GetTicks(); - SDLTest_AssertPass("Call to SDL_GetTicks()"); - SDLTest_AssertCheck(result2 > 0, "Check result value, expected: >0, got: %d", result2); - difference = result2 - result; - SDLTest_AssertCheck(difference > (testDelay - marginOfError), "Check difference, expected: >%d, got: %d", testDelay - marginOfError, difference); - SDLTest_AssertCheck(difference < (testDelay + marginOfError), "Check difference, expected: <%d, got: %d", testDelay + marginOfError, difference); - - return TEST_COMPLETED; -} - -/* Test callback */ -Uint32 SDLCALL _timerTestCallback(Uint32 interval, void *param) -{ - _timerCallbackCalled = 1; - - if (_paramCheck != 0) { - SDLTest_AssertCheck(param != NULL, "Check param pointer, expected: non-NULL, got: %s", (param != NULL) ? "non-NULL" : "NULL"); - if (param != NULL) { - SDLTest_AssertCheck(*(int *)param == _paramValue, "Check param value, expected: %i, got: %i", _paramValue, *(int *)param); - } - } - - return 0; -} - -/** - * @brief Call to SDL_AddTimer and SDL_RemoveTimer - */ -int -timer_addRemoveTimer(void *arg) -{ - SDL_TimerID id; - SDL_bool result; - int param; - - /* Reset state */ - _paramCheck = 0; - _timerCallbackCalled = 0; - - /* Set timer with a long delay */ - id = SDL_AddTimer(10000, _timerTestCallback, NULL); - SDLTest_AssertPass("Call to SDL_AddTimer(10000,...)"); - SDLTest_AssertCheck(id > 0, "Check result value, expected: >0, got: %d", id); - - /* Remove timer again and check that callback was not called */ - result = SDL_RemoveTimer(id); - SDLTest_AssertPass("Call to SDL_RemoveTimer()"); - SDLTest_AssertCheck(result == SDL_TRUE, "Check result value, expected: %i, got: %i", SDL_TRUE, result); - SDLTest_AssertCheck(_timerCallbackCalled == 0, "Check callback WAS NOT called, expected: 0, got: %i", _timerCallbackCalled); - - /* Try to remove timer again (should be a NOOP) */ - result = SDL_RemoveTimer(id); - SDLTest_AssertPass("Call to SDL_RemoveTimer()"); - SDLTest_AssertCheck(result == SDL_FALSE, "Check result value, expected: %i, got: %i", SDL_FALSE, result); - - /* Reset state */ - param = SDLTest_RandomIntegerInRange(-1024, 1024); - _paramCheck = 1; - _paramValue = param; - _timerCallbackCalled = 0; - - /* Set timer with a short delay */ - id = SDL_AddTimer(10, _timerTestCallback, (void *)¶m); - SDLTest_AssertPass("Call to SDL_AddTimer(10, param)"); - SDLTest_AssertCheck(id > 0, "Check result value, expected: >0, got: %d", id); - - /* Wait to let timer trigger callback */ - SDL_Delay(100); - SDLTest_AssertPass("Call to SDL_Delay(100)"); - - /* Remove timer again and check that callback was called */ - result = SDL_RemoveTimer(id); - SDLTest_AssertPass("Call to SDL_RemoveTimer()"); - SDLTest_AssertCheck(result == SDL_FALSE, "Check result value, expected: %i, got: %i", SDL_FALSE, result); - SDLTest_AssertCheck(_timerCallbackCalled == 1, "Check callback WAS called, expected: 1, got: %i", _timerCallbackCalled); - - return TEST_COMPLETED; -} - -/* ================= Test References ================== */ - -/* Timer test cases */ -static const SDLTest_TestCaseReference timerTest1 = - { (SDLTest_TestCaseFp)timer_getPerformanceCounter, "timer_getPerformanceCounter", "Call to SDL_GetPerformanceCounter", TEST_ENABLED }; - -static const SDLTest_TestCaseReference timerTest2 = - { (SDLTest_TestCaseFp)timer_getPerformanceFrequency, "timer_getPerformanceFrequency", "Call to SDL_GetPerformanceFrequency", TEST_ENABLED }; - -static const SDLTest_TestCaseReference timerTest3 = - { (SDLTest_TestCaseFp)timer_delayAndGetTicks, "timer_delayAndGetTicks", "Call to SDL_Delay and SDL_GetTicks", TEST_ENABLED }; - -static const SDLTest_TestCaseReference timerTest4 = - { (SDLTest_TestCaseFp)timer_addRemoveTimer, "timer_addRemoveTimer", "Call to SDL_AddTimer and SDL_RemoveTimer", TEST_ENABLED }; - -/* Sequence of Timer test cases */ -static const SDLTest_TestCaseReference *timerTests[] = { - &timerTest1, &timerTest2, &timerTest3, &timerTest4, NULL -}; - -/* Timer test suite (global) */ -SDLTest_TestSuiteReference timerTestSuite = { - "Timer", - _timerSetUp, - timerTests, - NULL -}; diff --git a/SDL2-2.0.12/test/testautomation_video.c b/SDL2-2.0.12/test/testautomation_video.c deleted file mode 100644 index 7b86cfb..0000000 --- a/SDL2-2.0.12/test/testautomation_video.c +++ /dev/null @@ -1,1811 +0,0 @@ -/** - * Video test suite - */ - -#include -#include - -/* Visual Studio 2008 doesn't have stdint.h */ -#if defined(_MSC_VER) && _MSC_VER <= 1500 -#define UINT8_MAX ~(Uint8)0 -#define UINT16_MAX ~(Uint16)0 -#define UINT32_MAX ~(Uint32)0 -#define UINT64_MAX ~(Uint64)0 -#else -#include -#endif - -#include "SDL.h" -#include "SDL_test.h" - -/* Private helpers */ - -/* - * Create a test window - */ -SDL_Window *_createVideoSuiteTestWindow(const char *title) -{ - SDL_Window* window; - int x, y, w, h; - SDL_WindowFlags flags; - - /* Standard window */ - x = SDLTest_RandomIntegerInRange(1, 100); - y = SDLTest_RandomIntegerInRange(1, 100); - w = SDLTest_RandomIntegerInRange(320, 1024); - h = SDLTest_RandomIntegerInRange(320, 768); - flags = SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_BORDERLESS; - - window = SDL_CreateWindow(title, x, y, w, h, flags); - SDLTest_AssertPass("Call to SDL_CreateWindow('Title',%d,%d,%d,%d,%d)", x, y, w, h, flags); - SDLTest_AssertCheck(window != NULL, "Validate that returned window struct is not NULL"); - - return window; -} - -/* - * Destroy test window - */ -void _destroyVideoSuiteTestWindow(SDL_Window *window) -{ - if (window != NULL) { - SDL_DestroyWindow(window); - window = NULL; - SDLTest_AssertPass("Call to SDL_DestroyWindow()"); - } -} - -/* Test case functions */ - -/** - * @brief Enable and disable screensaver while checking state - */ -int -video_enableDisableScreensaver(void *arg) -{ - SDL_bool initialResult; - SDL_bool result; - - /* Get current state and proceed according to current state */ - initialResult = SDL_IsScreenSaverEnabled(); - SDLTest_AssertPass("Call to SDL_IsScreenSaverEnabled()"); - if (initialResult == SDL_TRUE) { - - /* Currently enabled: disable first, then enable again */ - - /* Disable screensaver and check */ - SDL_DisableScreenSaver(); - SDLTest_AssertPass("Call to SDL_DisableScreenSaver()"); - result = SDL_IsScreenSaverEnabled(); - SDLTest_AssertPass("Call to SDL_IsScreenSaverEnabled()"); - SDLTest_AssertCheck(result == SDL_FALSE, "Verify result from SDL_IsScreenSaverEnabled, expected: %i, got: %i", SDL_FALSE, result); - - /* Enable screensaver and check */ - SDL_EnableScreenSaver(); - SDLTest_AssertPass("Call to SDL_EnableScreenSaver()"); - result = SDL_IsScreenSaverEnabled(); - SDLTest_AssertPass("Call to SDL_IsScreenSaverEnabled()"); - SDLTest_AssertCheck(result == SDL_TRUE, "Verify result from SDL_IsScreenSaverEnabled, expected: %i, got: %i", SDL_TRUE, result); - - } else { - - /* Currently disabled: enable first, then disable again */ - - /* Enable screensaver and check */ - SDL_EnableScreenSaver(); - SDLTest_AssertPass("Call to SDL_EnableScreenSaver()"); - result = SDL_IsScreenSaverEnabled(); - SDLTest_AssertPass("Call to SDL_IsScreenSaverEnabled()"); - SDLTest_AssertCheck(result == SDL_TRUE, "Verify result from SDL_IsScreenSaverEnabled, expected: %i, got: %i", SDL_TRUE, result); - - /* Disable screensaver and check */ - SDL_DisableScreenSaver(); - SDLTest_AssertPass("Call to SDL_DisableScreenSaver()"); - result = SDL_IsScreenSaverEnabled(); - SDLTest_AssertPass("Call to SDL_IsScreenSaverEnabled()"); - SDLTest_AssertCheck(result == SDL_FALSE, "Verify result from SDL_IsScreenSaverEnabled, expected: %i, got: %i", SDL_FALSE, result); - } - - return TEST_COMPLETED; -} - -/** - * @brief Tests the functionality of the SDL_CreateWindow function using different positions - */ -int -video_createWindowVariousPositions(void *arg) -{ - SDL_Window* window; - const char* title = "video_createWindowVariousPositions Test Window"; - int x, y, w, h; - int xVariation, yVariation; - - for (xVariation = 0; xVariation < 6; xVariation++) { - for (yVariation = 0; yVariation < 6; yVariation++) { - switch(xVariation) { - case 0: - /* Zero X Position */ - x = 0; - break; - case 1: - /* Random X position inside screen */ - x = SDLTest_RandomIntegerInRange(1, 100); - break; - case 2: - /* Random X position outside screen (positive) */ - x = SDLTest_RandomIntegerInRange(10000, 11000); - break; - case 3: - /* Random X position outside screen (negative) */ - x = SDLTest_RandomIntegerInRange(-1000, -100); - break; - case 4: - /* Centered X position */ - x = SDL_WINDOWPOS_CENTERED; - break; - case 5: - /* Undefined X position */ - x = SDL_WINDOWPOS_UNDEFINED; - break; - } - - switch(yVariation) { - case 0: - /* Zero X Position */ - y = 0; - break; - case 1: - /* Random X position inside screen */ - y = SDLTest_RandomIntegerInRange(1, 100); - break; - case 2: - /* Random X position outside screen (positive) */ - y = SDLTest_RandomIntegerInRange(10000, 11000); - break; - case 3: - /* Random Y position outside screen (negative) */ - y = SDLTest_RandomIntegerInRange(-1000, -100); - break; - case 4: - /* Centered Y position */ - y = SDL_WINDOWPOS_CENTERED; - break; - case 5: - /* Undefined Y position */ - y = SDL_WINDOWPOS_UNDEFINED; - break; - } - - w = SDLTest_RandomIntegerInRange(32, 96); - h = SDLTest_RandomIntegerInRange(32, 96); - window = SDL_CreateWindow(title, x, y, w, h, SDL_WINDOW_SHOWN); - SDLTest_AssertPass("Call to SDL_CreateWindow('Title',%d,%d,%d,%d,SHOWN)", x, y, w, h); - SDLTest_AssertCheck(window != NULL, "Validate that returned window struct is not NULL"); - - /* Clean up */ - _destroyVideoSuiteTestWindow(window); - } - } - - return TEST_COMPLETED; -} - -/** - * @brief Tests the functionality of the SDL_CreateWindow function using different sizes - */ -int -video_createWindowVariousSizes(void *arg) -{ - SDL_Window* window; - const char* title = "video_createWindowVariousSizes Test Window"; - int x, y, w, h; - int wVariation, hVariation; - - x = SDLTest_RandomIntegerInRange(1, 100); - y = SDLTest_RandomIntegerInRange(1, 100); - for (wVariation = 0; wVariation < 3; wVariation++) { - for (hVariation = 0; hVariation < 3; hVariation++) { - switch(wVariation) { - case 0: - /* Width of 1 */ - w = 1; - break; - case 1: - /* Random "normal" width */ - w = SDLTest_RandomIntegerInRange(320, 1920); - break; - case 2: - /* Random "large" width */ - w = SDLTest_RandomIntegerInRange(2048, 4095); - break; - } - - switch(hVariation) { - case 0: - /* Height of 1 */ - h = 1; - break; - case 1: - /* Random "normal" height */ - h = SDLTest_RandomIntegerInRange(320, 1080); - break; - case 2: - /* Random "large" height */ - h = SDLTest_RandomIntegerInRange(2048, 4095); - break; - } - - window = SDL_CreateWindow(title, x, y, w, h, SDL_WINDOW_SHOWN); - SDLTest_AssertPass("Call to SDL_CreateWindow('Title',%d,%d,%d,%d,SHOWN)", x, y, w, h); - SDLTest_AssertCheck(window != NULL, "Validate that returned window struct is not NULL"); - - /* Clean up */ - _destroyVideoSuiteTestWindow(window); - } - } - - return TEST_COMPLETED; -} - -/** - * @brief Tests the functionality of the SDL_CreateWindow function using different flags - */ -int -video_createWindowVariousFlags(void *arg) -{ - SDL_Window* window; - const char* title = "video_createWindowVariousFlags Test Window"; - int x, y, w, h; - int fVariation; - SDL_WindowFlags flags; - - /* Standard window */ - x = SDLTest_RandomIntegerInRange(1, 100); - y = SDLTest_RandomIntegerInRange(1, 100); - w = SDLTest_RandomIntegerInRange(320, 1024); - h = SDLTest_RandomIntegerInRange(320, 768); - - for (fVariation = 0; fVariation < 13; fVariation++) { - switch(fVariation) { - case 0: - flags = SDL_WINDOW_FULLSCREEN; - /* Skip - blanks screen; comment out next line to run test */ - continue; - break; - case 1: - flags = SDL_WINDOW_FULLSCREEN_DESKTOP; - /* Skip - blanks screen; comment out next line to run test */ - continue; - break; - case 2: - flags = SDL_WINDOW_OPENGL; - break; - case 3: - flags = SDL_WINDOW_SHOWN; - break; - case 4: - flags = SDL_WINDOW_HIDDEN; - break; - case 5: - flags = SDL_WINDOW_BORDERLESS; - break; - case 6: - flags = SDL_WINDOW_RESIZABLE; - break; - case 7: - flags = SDL_WINDOW_MINIMIZED; - break; - case 8: - flags = SDL_WINDOW_MAXIMIZED; - break; - case 9: - flags = SDL_WINDOW_INPUT_GRABBED; - break; - case 10: - flags = SDL_WINDOW_INPUT_FOCUS; - break; - case 11: - flags = SDL_WINDOW_MOUSE_FOCUS; - break; - case 12: - flags = SDL_WINDOW_FOREIGN; - break; - } - - window = SDL_CreateWindow(title, x, y, w, h, flags); - SDLTest_AssertPass("Call to SDL_CreateWindow('Title',%d,%d,%d,%d,%d)", x, y, w, h, flags); - SDLTest_AssertCheck(window != NULL, "Validate that returned window struct is not NULL"); - - /* Clean up */ - _destroyVideoSuiteTestWindow(window); - } - - return TEST_COMPLETED; -} - - -/** - * @brief Tests the functionality of the SDL_GetWindowFlags function - */ -int -video_getWindowFlags(void *arg) -{ - SDL_Window* window; - const char* title = "video_getWindowFlags Test Window"; - SDL_WindowFlags flags; - Uint32 actualFlags; - - /* Reliable flag set always set in test window */ - flags = SDL_WINDOW_SHOWN; - - /* Call against new test window */ - window = _createVideoSuiteTestWindow(title); - if (window != NULL) { - actualFlags = SDL_GetWindowFlags(window); - SDLTest_AssertPass("Call to SDL_GetWindowFlags()"); - SDLTest_AssertCheck((flags & actualFlags) == flags, "Verify returned value has flags %d set, got: %d", flags, actualFlags); - } - - /* Clean up */ - _destroyVideoSuiteTestWindow(window); - - return TEST_COMPLETED; -} - -/** - * @brief Tests the functionality of the SDL_GetNumDisplayModes function - */ -int -video_getNumDisplayModes(void *arg) -{ - int result; - int displayNum; - int i; - - /* Get number of displays */ - displayNum = SDL_GetNumVideoDisplays(); - SDLTest_AssertPass("Call to SDL_GetNumVideoDisplays()"); - - /* Make call for each display */ - for (i=0; i= 1, "Validate returned value from function; expected: >=1; got: %d", result); - } - - return TEST_COMPLETED; -} - -/** - * @brief Tests negative call to SDL_GetNumDisplayModes function - */ -int -video_getNumDisplayModesNegative(void *arg) -{ - int result; - int displayNum; - int displayIndex; - - /* Get number of displays */ - displayNum = SDL_GetNumVideoDisplays(); - SDLTest_AssertPass("Call to SDL_GetNumVideoDisplays()"); - - /* Invalid boundary values */ - displayIndex = SDLTest_RandomSint32BoundaryValue(0, displayNum, SDL_FALSE); - result = SDL_GetNumDisplayModes(displayIndex); - SDLTest_AssertPass("Call to SDL_GetNumDisplayModes(%d=out-of-bounds/boundary)", displayIndex); - SDLTest_AssertCheck(result < 0, "Validate returned value from function; expected: <0; got: %d", result); - - /* Large (out-of-bounds) display index */ - displayIndex = SDLTest_RandomIntegerInRange(-2000, -1000); - result = SDL_GetNumDisplayModes(displayIndex); - SDLTest_AssertPass("Call to SDL_GetNumDisplayModes(%d=out-of-bounds/large negative)", displayIndex); - SDLTest_AssertCheck(result < 0, "Validate returned value from function; expected: <0; got: %d", result); - - displayIndex = SDLTest_RandomIntegerInRange(1000, 2000); - result = SDL_GetNumDisplayModes(displayIndex); - SDLTest_AssertPass("Call to SDL_GetNumDisplayModes(%d=out-of-bounds/large positive)", displayIndex); - SDLTest_AssertCheck(result < 0, "Validate returned value from function; expected: <0; got: %d", result); - - return TEST_COMPLETED; -} - -/** - * @brief Tests the functionality of the SDL_GetClosestDisplayMode function against current resolution - */ -int -video_getClosestDisplayModeCurrentResolution(void *arg) -{ - int result; - SDL_DisplayMode current; - SDL_DisplayMode target; - SDL_DisplayMode closest; - SDL_DisplayMode* dResult; - int displayNum; - int i; - int variation; - - /* Get number of displays */ - displayNum = SDL_GetNumVideoDisplays(); - SDLTest_AssertPass("Call to SDL_GetNumVideoDisplays()"); - - /* Make calls for each display */ - for (i=0; iw, "Verify return value matches assigned value; expected: %d, got: %d", closest.w, dResult->w); - SDLTest_AssertCheck(closest.h == dResult->h, "Verify return value matches assigned value; expected: %d, got: %d", closest.h, dResult->h); - } - } - - return TEST_COMPLETED; -} - -/** - * @brief Tests the functionality of the SDL_GetClosestDisplayMode function against random resolution - */ -int -video_getClosestDisplayModeRandomResolution(void *arg) -{ - SDL_DisplayMode target; - SDL_DisplayMode closest; - SDL_DisplayMode* dResult; - int displayNum; - int i; - int variation; - - /* Get number of displays */ - displayNum = SDL_GetNumVideoDisplays(); - SDLTest_AssertPass("Call to SDL_GetNumVideoDisplays()"); - - /* Make calls for each display */ - for (i=0; i= 0.0 && result <= 1.0, "Validate range of result value; expected: [0.0, 1.0], got: %f", result); - } - - /* Clean up */ - _destroyVideoSuiteTestWindow(window); - - return TEST_COMPLETED; -} - -/** - * @brief Tests call to SDL_GetWindowBrightness with invalid input - * -* @sa http://wiki.libsdl.org/moin.fcg/SDL_GetWindowBrightness - */ -int -video_getWindowBrightnessNegative(void *arg) -{ - const char *invalidWindowError = "Invalid window"; - char *lastError; - float result; - - /* Call against invalid window */ - result = SDL_GetWindowBrightness(NULL); - SDLTest_AssertPass("Call to SDL_GetWindowBrightness(window=NULL)"); - SDLTest_AssertCheck(result == 1.0, "Validate result value; expected: 1.0, got: %f", result); - lastError = (char *)SDL_GetError(); - SDLTest_AssertPass("SDL_GetError()"); - SDLTest_AssertCheck(lastError != NULL, "Verify error message is not NULL"); - if (lastError != NULL) { - SDLTest_AssertCheck(SDL_strcmp(lastError, invalidWindowError) == 0, - "SDL_GetError(): expected message '%s', was message: '%s'", - invalidWindowError, - lastError); - } - - return TEST_COMPLETED; -} - -/** - * @brief Tests call to SDL_GetWindowDisplayMode - * - * @sa http://wiki.libsdl.org/moin.fcg/SDL_GetWindowDisplayMode - */ -int -video_getWindowDisplayMode(void *arg) -{ - SDL_Window* window; - const char* title = "video_getWindowDisplayMode Test Window"; - SDL_DisplayMode mode; - int result; - - /* Invalidate part of the mode content so we can check values later */ - mode.w = -1; - mode.h = -1; - mode.refresh_rate = -1; - - /* Call against new test window */ - window = _createVideoSuiteTestWindow(title); - if (window != NULL) { - result = SDL_GetWindowDisplayMode(window, &mode); - SDLTest_AssertPass("Call to SDL_GetWindowDisplayMode()"); - SDLTest_AssertCheck(result == 0, "Validate result value; expected: 0, got: %d", result); - SDLTest_AssertCheck(mode.w > 0, "Validate mode.w content; expected: >0, got: %d", mode.w); - SDLTest_AssertCheck(mode.h > 0, "Validate mode.h content; expected: >0, got: %d", mode.h); - SDLTest_AssertCheck(mode.refresh_rate > 0, "Validate mode.refresh_rate content; expected: >0, got: %d", mode.refresh_rate); - } - - /* Clean up */ - _destroyVideoSuiteTestWindow(window); - - return TEST_COMPLETED; -} - -/* Helper function that checks for an 'Invalid window' error */ -void _checkInvalidWindowError() -{ - const char *invalidWindowError = "Invalid window"; - char *lastError; - - lastError = (char *)SDL_GetError(); - SDLTest_AssertPass("SDL_GetError()"); - SDLTest_AssertCheck(lastError != NULL, "Verify error message is not NULL"); - if (lastError != NULL) { - SDLTest_AssertCheck(SDL_strcmp(lastError, invalidWindowError) == 0, - "SDL_GetError(): expected message '%s', was message: '%s'", - invalidWindowError, - lastError); - SDL_ClearError(); - SDLTest_AssertPass("Call to SDL_ClearError()"); - } -} - -/** - * @brief Tests call to SDL_GetWindowDisplayMode with invalid input - * - * @sa http://wiki.libsdl.org/moin.fcg/SDL_GetWindowDisplayMode - */ -int -video_getWindowDisplayModeNegative(void *arg) -{ - const char *expectedError = "Parameter 'mode' is invalid"; - char *lastError; - SDL_Window* window; - const char* title = "video_getWindowDisplayModeNegative Test Window"; - SDL_DisplayMode mode; - int result; - - /* Call against new test window */ - window = _createVideoSuiteTestWindow(title); - if (window != NULL) { - result = SDL_GetWindowDisplayMode(window, NULL); - SDLTest_AssertPass("Call to SDL_GetWindowDisplayMode(...,mode=NULL)"); - SDLTest_AssertCheck(result == -1, "Validate result value; expected: -1, got: %d", result); - lastError = (char *)SDL_GetError(); - SDLTest_AssertPass("SDL_GetError()"); - SDLTest_AssertCheck(lastError != NULL, "Verify error message is not NULL"); - if (lastError != NULL) { - SDLTest_AssertCheck(SDL_strcmp(lastError, expectedError) == 0, - "SDL_GetError(): expected message '%s', was message: '%s'", - expectedError, - lastError); - } - } - - /* Clean up */ - _destroyVideoSuiteTestWindow(window); - - /* Call against invalid window */ - result = SDL_GetWindowDisplayMode(NULL, &mode); - SDLTest_AssertPass("Call to SDL_GetWindowDisplayMode(window=NULL,...)"); - SDLTest_AssertCheck(result == -1, "Validate result value; expected: -1, got: %d", result); - _checkInvalidWindowError(); - - return TEST_COMPLETED; -} - -/** - * @brief Tests call to SDL_GetWindowGammaRamp - * - * @sa http://wiki.libsdl.org/moin.fcg/SDL_GetWindowGammaRamp - */ -int -video_getWindowGammaRamp(void *arg) -{ - SDL_Window* window; - const char* title = "video_getWindowGammaRamp Test Window"; - Uint16 red[256]; - Uint16 green[256]; - Uint16 blue[256]; - int result; - - /* Call against new test window */ - window = _createVideoSuiteTestWindow(title); - if (window == NULL) return TEST_ABORTED; - - /* Retrieve no channel */ - result = SDL_GetWindowGammaRamp(window, NULL, NULL, NULL); - SDLTest_AssertPass("Call to SDL_GetWindowGammaRamp(all NULL)"); - SDLTest_AssertCheck(result == 0, "Validate result value; expected: 0, got: %d", result); - - /* Retrieve single channel */ - result = SDL_GetWindowGammaRamp(window, red, NULL, NULL); - SDLTest_AssertPass("Call to SDL_GetWindowGammaRamp(r)"); - SDLTest_AssertCheck(result == 0, "Validate result value; expected: 0, got: %d", result); - - result = SDL_GetWindowGammaRamp(window, NULL, green, NULL); - SDLTest_AssertPass("Call to SDL_GetWindowGammaRamp(g)"); - SDLTest_AssertCheck(result == 0, "Validate result value; expected: 0, got: %d", result); - - result = SDL_GetWindowGammaRamp(window, NULL, NULL, blue); - SDLTest_AssertPass("Call to SDL_GetWindowGammaRamp(b)"); - SDLTest_AssertCheck(result == 0, "Validate result value; expected: 0, got: %d", result); - - /* Retrieve two channels */ - result = SDL_GetWindowGammaRamp(window, red, green, NULL); - SDLTest_AssertPass("Call to SDL_GetWindowGammaRamp(r, g)"); - SDLTest_AssertCheck(result == 0, "Validate result value; expected: 0, got: %d", result); - - result = SDL_GetWindowGammaRamp(window, NULL, green, blue); - SDLTest_AssertPass("Call to SDL_GetWindowGammaRamp(g,b)"); - SDLTest_AssertCheck(result == 0, "Validate result value; expected: 0, got: %d", result); - - result = SDL_GetWindowGammaRamp(window, red, NULL, blue); - SDLTest_AssertPass("Call to SDL_GetWindowGammaRamp(r,b)"); - SDLTest_AssertCheck(result == 0, "Validate result value; expected: 0, got: %d", result); - - /* Retrieve all channels */ - result = SDL_GetWindowGammaRamp(window, red, green, blue); - SDLTest_AssertPass("Call to SDL_GetWindowGammaRamp(r,g,b)"); - SDLTest_AssertCheck(result == 0, "Validate result value; expected: 0, got: %d", result); - - /* Clean up */ - _destroyVideoSuiteTestWindow(window); - - return TEST_COMPLETED; -} - -/** - * @brief Tests call to SDL_GetWindowGammaRamp with invalid input - * -* @sa http://wiki.libsdl.org/moin.fcg/SDL_GetWindowGammaRamp - */ -int -video_getWindowGammaRampNegative(void *arg) -{ - Uint16 red[256]; - Uint16 green[256]; - Uint16 blue[256]; - int result; - - SDL_ClearError(); - SDLTest_AssertPass("Call to SDL_ClearError()"); - - /* Call against invalid window */ - result = SDL_GetWindowGammaRamp(NULL, red, green, blue); - SDLTest_AssertPass("Call to SDL_GetWindowGammaRamp(window=NULL,r,g,b)"); - SDLTest_AssertCheck(result == -1, "Validate result value; expected: -1, got: %i", result); - _checkInvalidWindowError(); - - return TEST_COMPLETED; -} - -/* Helper for setting and checking the window grab state */ -void -_setAndCheckWindowGrabState(SDL_Window* window, SDL_bool desiredState) -{ - SDL_bool currentState; - - /* Set state */ - SDL_SetWindowGrab(window, desiredState); - SDLTest_AssertPass("Call to SDL_SetWindowGrab(%s)", (desiredState == SDL_FALSE) ? "SDL_FALSE" : "SDL_TRUE"); - - /* Get and check state */ - currentState = SDL_GetWindowGrab(window); - SDLTest_AssertPass("Call to SDL_GetWindowGrab()"); - SDLTest_AssertCheck( - currentState == desiredState, - "Validate returned state; expected: %s, got: %s", - (desiredState == SDL_FALSE) ? "SDL_FALSE" : "SDL_TRUE", - (currentState == SDL_FALSE) ? "SDL_FALSE" : "SDL_TRUE"); -} - -/** - * @brief Tests call to SDL_GetWindowGrab and SDL_SetWindowGrab - * - * @sa http://wiki.libsdl.org/moin.fcg/SDL_GetWindowGrab - * @sa http://wiki.libsdl.org/moin.fcg/SDL_SetWindowGrab - */ -int -video_getSetWindowGrab(void *arg) -{ - const char* title = "video_getSetWindowGrab Test Window"; - SDL_Window* window; - SDL_bool originalState, dummyState, currentState, desiredState; - - /* Call against new test window */ - window = _createVideoSuiteTestWindow(title); - if (window == NULL) return TEST_ABORTED; - - /* Get state */ - originalState = SDL_GetWindowGrab(window); - SDLTest_AssertPass("Call to SDL_GetWindowGrab()"); - - /* F */ - _setAndCheckWindowGrabState(window, SDL_FALSE); - - /* F --> F */ - _setAndCheckWindowGrabState(window, SDL_FALSE); - - /* F --> T */ - _setAndCheckWindowGrabState(window, SDL_TRUE); - - /* T --> T */ - _setAndCheckWindowGrabState(window, SDL_TRUE); - - /* T --> F */ - _setAndCheckWindowGrabState(window, SDL_FALSE); - - /* Negative tests */ - dummyState = SDL_GetWindowGrab(NULL); - SDLTest_AssertPass("Call to SDL_GetWindowGrab(window=NULL)"); - _checkInvalidWindowError(); - - SDL_SetWindowGrab(NULL, SDL_FALSE); - SDLTest_AssertPass("Call to SDL_SetWindowGrab(window=NULL,SDL_FALSE)"); - _checkInvalidWindowError(); - - SDL_SetWindowGrab(NULL, SDL_TRUE); - SDLTest_AssertPass("Call to SDL_SetWindowGrab(window=NULL,SDL_FALSE)"); - _checkInvalidWindowError(); - - /* State should still be F */ - desiredState = SDL_FALSE; - currentState = SDL_GetWindowGrab(window); - SDLTest_AssertPass("Call to SDL_GetWindowGrab()"); - SDLTest_AssertCheck( - currentState == desiredState, - "Validate returned state; expected: %s, got: %s", - (desiredState == SDL_FALSE) ? "SDL_FALSE" : "SDL_TRUE", - (currentState == SDL_FALSE) ? "SDL_FALSE" : "SDL_TRUE"); - - /* Restore state */ - _setAndCheckWindowGrabState(window, originalState); - - /* Clean up */ - _destroyVideoSuiteTestWindow(window); - - return TEST_COMPLETED; -} - - -/** - * @brief Tests call to SDL_GetWindowID and SDL_GetWindowFromID - * - * @sa http://wiki.libsdl.org/moin.fcg/SDL_GetWindowID - * @sa http://wiki.libsdl.org/moin.fcg/SDL_SetWindowFromID - */ -int -video_getWindowId(void *arg) -{ - const char* title = "video_getWindowId Test Window"; - SDL_Window* window; - SDL_Window* result; - Uint32 id, randomId; - - /* Call against new test window */ - window = _createVideoSuiteTestWindow(title); - if (window == NULL) return TEST_ABORTED; - - /* Get ID */ - id = SDL_GetWindowID(window); - SDLTest_AssertPass("Call to SDL_GetWindowID()"); - - /* Get window from ID */ - result = SDL_GetWindowFromID(id); - SDLTest_AssertPass("Call to SDL_GetWindowID(%d)", id); - SDLTest_AssertCheck(result == window, "Verify result matches window pointer"); - - /* Get window from random large ID, no result check */ - randomId = SDLTest_RandomIntegerInRange(UINT8_MAX,UINT16_MAX); - result = SDL_GetWindowFromID(randomId); - SDLTest_AssertPass("Call to SDL_GetWindowID(%d/random_large)", randomId); - - /* Get window from 0 and Uint32 max ID, no result check */ - result = SDL_GetWindowFromID(0); - SDLTest_AssertPass("Call to SDL_GetWindowID(0)"); - result = SDL_GetWindowFromID(UINT32_MAX); - SDLTest_AssertPass("Call to SDL_GetWindowID(UINT32_MAX)"); - - /* Clean up */ - _destroyVideoSuiteTestWindow(window); - - /* Get window from ID for closed window */ - result = SDL_GetWindowFromID(id); - SDLTest_AssertPass("Call to SDL_GetWindowID(%d/closed_window)", id); - SDLTest_AssertCheck(result == NULL, "Verify result is NULL"); - - /* Negative test */ - SDL_ClearError(); - SDLTest_AssertPass("Call to SDL_ClearError()"); - id = SDL_GetWindowID(NULL); - SDLTest_AssertPass("Call to SDL_GetWindowID(window=NULL)"); - _checkInvalidWindowError(); - - return TEST_COMPLETED; -} - -/** - * @brief Tests call to SDL_GetWindowPixelFormat - * - * @sa http://wiki.libsdl.org/moin.fcg/SDL_GetWindowPixelFormat - */ -int -video_getWindowPixelFormat(void *arg) -{ - const char* title = "video_getWindowPixelFormat Test Window"; - SDL_Window* window; - Uint32 format; - - /* Call against new test window */ - window = _createVideoSuiteTestWindow(title); - if (window == NULL) return TEST_ABORTED; - - /* Get format */ - format = SDL_GetWindowPixelFormat(window); - SDLTest_AssertPass("Call to SDL_GetWindowPixelFormat()"); - SDLTest_AssertCheck(format != SDL_PIXELFORMAT_UNKNOWN, "Verify that returned format is valid; expected: != %d, got: %d", SDL_PIXELFORMAT_UNKNOWN, format); - - /* Clean up */ - _destroyVideoSuiteTestWindow(window); - - /* Negative test */ - SDL_ClearError(); - SDLTest_AssertPass("Call to SDL_ClearError()"); - format = SDL_GetWindowPixelFormat(NULL); - SDLTest_AssertPass("Call to SDL_GetWindowPixelFormat(window=NULL)"); - _checkInvalidWindowError(); - - return TEST_COMPLETED; -} - -/** - * @brief Tests call to SDL_GetWindowPosition and SDL_SetWindowPosition - * - * @sa http://wiki.libsdl.org/moin.fcg/SDL_GetWindowPosition - * @sa http://wiki.libsdl.org/moin.fcg/SDL_SetWindowPosition - */ -int -video_getSetWindowPosition(void *arg) -{ - const char* title = "video_getSetWindowPosition Test Window"; - SDL_Window* window; - int xVariation, yVariation; - int referenceX, referenceY; - int currentX, currentY; - int desiredX, desiredY; - - /* Call against new test window */ - window = _createVideoSuiteTestWindow(title); - if (window == NULL) return TEST_ABORTED; - - for (xVariation = 0; xVariation < 4; xVariation++) { - for (yVariation = 0; yVariation < 4; yVariation++) { - switch(xVariation) { - case 0: - /* Zero X Position */ - desiredX = 0; - break; - case 1: - /* Random X position inside screen */ - desiredX = SDLTest_RandomIntegerInRange(1, 100); - break; - case 2: - /* Random X position outside screen (positive) */ - desiredX = SDLTest_RandomIntegerInRange(10000, 11000); - break; - case 3: - /* Random X position outside screen (negative) */ - desiredX = SDLTest_RandomIntegerInRange(-1000, -100); - break; - } - - switch(yVariation) { - case 0: - /* Zero X Position */ - desiredY = 0; - break; - case 1: - /* Random X position inside screen */ - desiredY = SDLTest_RandomIntegerInRange(1, 100); - break; - case 2: - /* Random X position outside screen (positive) */ - desiredY = SDLTest_RandomIntegerInRange(10000, 11000); - break; - case 3: - /* Random Y position outside screen (negative) */ - desiredY = SDLTest_RandomIntegerInRange(-1000, -100); - break; - } - - /* Set position */ - SDL_SetWindowPosition(window, desiredX, desiredY); - SDLTest_AssertPass("Call to SDL_SetWindowPosition(...,%d,%d)", desiredX, desiredY); - - /* Get position */ - currentX = desiredX + 1; - currentY = desiredY + 1; - SDL_GetWindowPosition(window, ¤tX, ¤tY); - SDLTest_AssertPass("Call to SDL_GetWindowPosition()"); - SDLTest_AssertCheck(desiredX == currentX, "Verify returned X position; expected: %d, got: %d", desiredX, currentX); - SDLTest_AssertCheck(desiredY == currentY, "Verify returned Y position; expected: %d, got: %d", desiredY, currentY); - - /* Get position X */ - currentX = desiredX + 1; - SDL_GetWindowPosition(window, ¤tX, NULL); - SDLTest_AssertPass("Call to SDL_GetWindowPosition(&y=NULL)"); - SDLTest_AssertCheck(desiredX == currentX, "Verify returned X position; expected: %d, got: %d", desiredX, currentX); - - /* Get position Y */ - currentY = desiredY + 1; - SDL_GetWindowPosition(window, NULL, ¤tY); - SDLTest_AssertPass("Call to SDL_GetWindowPosition(&x=NULL)"); - SDLTest_AssertCheck(desiredY == currentY, "Verify returned Y position; expected: %d, got: %d", desiredY, currentY); - } - } - - /* Dummy call with both pointers NULL */ - SDL_GetWindowPosition(window, NULL, NULL); - SDLTest_AssertPass("Call to SDL_GetWindowPosition(&x=NULL,&y=NULL)"); - - /* Clean up */ - _destroyVideoSuiteTestWindow(window); - - /* Set some 'magic' value for later check that nothing was changed */ - referenceX = SDLTest_RandomSint32(); - referenceY = SDLTest_RandomSint32(); - currentX = referenceX; - currentY = referenceY; - desiredX = SDLTest_RandomSint32(); - desiredY = SDLTest_RandomSint32(); - - /* Negative tests */ - SDL_ClearError(); - SDLTest_AssertPass("Call to SDL_ClearError()"); - SDL_GetWindowPosition(NULL, ¤tX, ¤tY); - SDLTest_AssertPass("Call to SDL_GetWindowPosition(window=NULL)"); - SDLTest_AssertCheck( - currentX == referenceX && currentY == referenceY, - "Verify that content of X and Y pointers has not been modified; expected: %d,%d; got: %d,%d", - referenceX, referenceY, - currentX, currentY); - _checkInvalidWindowError(); - - SDL_GetWindowPosition(NULL, NULL, NULL); - SDLTest_AssertPass("Call to SDL_GetWindowPosition(NULL, NULL, NULL)"); - _checkInvalidWindowError(); - - SDL_SetWindowPosition(NULL, desiredX, desiredY); - SDLTest_AssertPass("Call to SDL_SetWindowPosition(window=NULL)"); - _checkInvalidWindowError(); - - return TEST_COMPLETED; -} - -/* Helper function that checks for an 'Invalid parameter' error */ -void _checkInvalidParameterError() -{ - const char *invalidParameterError = "Parameter"; - char *lastError; - - lastError = (char *)SDL_GetError(); - SDLTest_AssertPass("SDL_GetError()"); - SDLTest_AssertCheck(lastError != NULL, "Verify error message is not NULL"); - if (lastError != NULL) { - SDLTest_AssertCheck(SDL_strncmp(lastError, invalidParameterError, SDL_strlen(invalidParameterError)) == 0, - "SDL_GetError(): expected message starts with '%s', was message: '%s'", - invalidParameterError, - lastError); - SDL_ClearError(); - SDLTest_AssertPass("Call to SDL_ClearError()"); - } -} - -/** - * @brief Tests call to SDL_GetWindowSize and SDL_SetWindowSize - * - * @sa http://wiki.libsdl.org/moin.fcg/SDL_GetWindowSize - * @sa http://wiki.libsdl.org/moin.fcg/SDL_SetWindowSize - */ -int -video_getSetWindowSize(void *arg) -{ - const char* title = "video_getSetWindowSize Test Window"; - SDL_Window* window; - int result; - SDL_Rect display; - int maxwVariation, maxhVariation; - int wVariation, hVariation; - int referenceW, referenceH; - int currentW, currentH; - int desiredW, desiredH; - - /* Get display bounds for size range */ - result = SDL_GetDisplayBounds(0, &display); - SDLTest_AssertPass("SDL_GetDisplayBounds()"); - SDLTest_AssertCheck(result == 0, "Verify return value; expected: 0, got: %d", result); - if (result != 0) return TEST_ABORTED; - - /* Call against new test window */ - window = _createVideoSuiteTestWindow(title); - if (window == NULL) return TEST_ABORTED; - -#ifdef __WIN32__ - /* Platform clips window size to screen size */ - maxwVariation = 4; - maxhVariation = 4; -#else - /* Platform allows window size >= screen size */ - maxwVariation = 5; - maxhVariation = 5; -#endif - - for (wVariation = 0; wVariation < maxwVariation; wVariation++) { - for (hVariation = 0; hVariation < maxhVariation; hVariation++) { - switch(wVariation) { - case 0: - /* 1 Pixel Wide */ - desiredW = 1; - break; - case 1: - /* Random width inside screen */ - desiredW = SDLTest_RandomIntegerInRange(1, 100); - break; - case 2: - /* Width 1 pixel smaller than screen */ - desiredW = display.w - 1; - break; - case 3: - /* Width at screen size */ - desiredW = display.w; - break; - case 4: - /* Width 1 pixel larger than screen */ - desiredW = display.w + 1; - break; - } - - switch(hVariation) { - case 0: - /* 1 Pixel High */ - desiredH = 1; - break; - case 1: - /* Random height inside screen */ - desiredH = SDLTest_RandomIntegerInRange(1, 100); - break; - case 2: - /* Height 1 pixel smaller than screen */ - desiredH = display.h - 1; - break; - case 3: - /* Height at screen size */ - desiredH = display.h; - break; - case 4: - /* Height 1 pixel larger than screen */ - desiredH = display.h + 1; - break; - } - - /* Set size */ - SDL_SetWindowSize(window, desiredW, desiredH); - SDLTest_AssertPass("Call to SDL_SetWindowSize(...,%d,%d)", desiredW, desiredH); - - /* Get size */ - currentW = desiredW + 1; - currentH = desiredH + 1; - SDL_GetWindowSize(window, ¤tW, ¤tH); - SDLTest_AssertPass("Call to SDL_GetWindowSize()"); - SDLTest_AssertCheck(desiredW == currentW, "Verify returned width; expected: %d, got: %d", desiredW, currentW); - SDLTest_AssertCheck(desiredH == currentH, "Verify returned height; expected: %d, got: %d", desiredH, currentH); - - /* Get just width */ - currentW = desiredW + 1; - SDL_GetWindowSize(window, ¤tW, NULL); - SDLTest_AssertPass("Call to SDL_GetWindowSize(&h=NULL)"); - SDLTest_AssertCheck(desiredW == currentW, "Verify returned width; expected: %d, got: %d", desiredW, currentW); - - /* Get just height */ - currentH = desiredH + 1; - SDL_GetWindowSize(window, NULL, ¤tH); - SDLTest_AssertPass("Call to SDL_GetWindowSize(&w=NULL)"); - SDLTest_AssertCheck(desiredH == currentH, "Verify returned height; expected: %d, got: %d", desiredH, currentH); - } - } - - /* Dummy call with both pointers NULL */ - SDL_GetWindowSize(window, NULL, NULL); - SDLTest_AssertPass("Call to SDL_GetWindowSize(&w=NULL,&h=NULL)"); - - /* Negative tests for parameter input */ - SDL_ClearError(); - SDLTest_AssertPass("Call to SDL_ClearError()"); - for (desiredH = -2; desiredH < 2; desiredH++) { - for (desiredW = -2; desiredW < 2; desiredW++) { - if (desiredW <= 0 || desiredH <= 0) { - SDL_SetWindowSize(window, desiredW, desiredH); - SDLTest_AssertPass("Call to SDL_SetWindowSize(...,%d,%d)", desiredW, desiredH); - _checkInvalidParameterError(); - } - } - } - - /* Clean up */ - _destroyVideoSuiteTestWindow(window); - - /* Set some 'magic' value for later check that nothing was changed */ - referenceW = SDLTest_RandomSint32(); - referenceH = SDLTest_RandomSint32(); - currentW = referenceW; - currentH = referenceH; - desiredW = SDLTest_RandomSint32(); - desiredH = SDLTest_RandomSint32(); - - /* Negative tests for window input */ - SDL_ClearError(); - SDLTest_AssertPass("Call to SDL_ClearError()"); - SDL_GetWindowSize(NULL, ¤tW, ¤tH); - SDLTest_AssertPass("Call to SDL_GetWindowSize(window=NULL)"); - SDLTest_AssertCheck( - currentW == referenceW && currentH == referenceH, - "Verify that content of W and H pointers has not been modified; expected: %d,%d; got: %d,%d", - referenceW, referenceH, - currentW, currentH); - _checkInvalidWindowError(); - - SDL_GetWindowSize(NULL, NULL, NULL); - SDLTest_AssertPass("Call to SDL_GetWindowSize(NULL, NULL, NULL)"); - _checkInvalidWindowError(); - - SDL_SetWindowSize(NULL, desiredW, desiredH); - SDLTest_AssertPass("Call to SDL_SetWindowSize(window=NULL)"); - _checkInvalidWindowError(); - - return TEST_COMPLETED; -} - -/** - * @brief Tests call to SDL_GetWindowMinimumSize and SDL_SetWindowMinimumSize - * - */ -int -video_getSetWindowMinimumSize(void *arg) -{ - const char* title = "video_getSetWindowMinimumSize Test Window"; - SDL_Window* window; - int result; - SDL_Rect display; - int wVariation, hVariation; - int referenceW, referenceH; - int currentW, currentH; - int desiredW, desiredH; - - /* Get display bounds for size range */ - result = SDL_GetDisplayBounds(0, &display); - SDLTest_AssertPass("SDL_GetDisplayBounds()"); - SDLTest_AssertCheck(result == 0, "Verify return value; expected: 0, got: %d", result); - if (result != 0) return TEST_ABORTED; - - /* Call against new test window */ - window = _createVideoSuiteTestWindow(title); - if (window == NULL) return TEST_ABORTED; - - for (wVariation = 0; wVariation < 5; wVariation++) { - for (hVariation = 0; hVariation < 5; hVariation++) { - switch(wVariation) { - case 0: - /* 1 Pixel Wide */ - desiredW = 1; - break; - case 1: - /* Random width inside screen */ - desiredW = SDLTest_RandomIntegerInRange(2, display.w - 1); - break; - case 2: - /* Width at screen size */ - desiredW = display.w; - break; - } - - switch(hVariation) { - case 0: - /* 1 Pixel High */ - desiredH = 1; - break; - case 1: - /* Random height inside screen */ - desiredH = SDLTest_RandomIntegerInRange(2, display.h - 1); - break; - case 2: - /* Height at screen size */ - desiredH = display.h; - break; - case 4: - /* Height 1 pixel larger than screen */ - desiredH = display.h + 1; - break; - } - - /* Set size */ - SDL_SetWindowMinimumSize(window, desiredW, desiredH); - SDLTest_AssertPass("Call to SDL_SetWindowMinimumSize(...,%d,%d)", desiredW, desiredH); - - /* Get size */ - currentW = desiredW + 1; - currentH = desiredH + 1; - SDL_GetWindowMinimumSize(window, ¤tW, ¤tH); - SDLTest_AssertPass("Call to SDL_GetWindowMinimumSize()"); - SDLTest_AssertCheck(desiredW == currentW, "Verify returned width; expected: %d, got: %d", desiredW, currentW); - SDLTest_AssertCheck(desiredH == currentH, "Verify returned height; expected: %d, got: %d", desiredH, currentH); - - /* Get just width */ - currentW = desiredW + 1; - SDL_GetWindowMinimumSize(window, ¤tW, NULL); - SDLTest_AssertPass("Call to SDL_GetWindowMinimumSize(&h=NULL)"); - SDLTest_AssertCheck(desiredW == currentW, "Verify returned width; expected: %d, got: %d", desiredW, currentH); - - /* Get just height */ - currentH = desiredH + 1; - SDL_GetWindowMinimumSize(window, NULL, ¤tH); - SDLTest_AssertPass("Call to SDL_GetWindowMinimumSize(&w=NULL)"); - SDLTest_AssertCheck(desiredH == currentH, "Verify returned height; expected: %d, got: %d", desiredW, currentH); - } - } - - /* Dummy call with both pointers NULL */ - SDL_GetWindowMinimumSize(window, NULL, NULL); - SDLTest_AssertPass("Call to SDL_GetWindowMinimumSize(&w=NULL,&h=NULL)"); - - /* Negative tests for parameter input */ - SDL_ClearError(); - SDLTest_AssertPass("Call to SDL_ClearError()"); - for (desiredH = -2; desiredH < 2; desiredH++) { - for (desiredW = -2; desiredW < 2; desiredW++) { - if (desiredW <= 0 || desiredH <= 0) { - SDL_SetWindowMinimumSize(window, desiredW, desiredH); - SDLTest_AssertPass("Call to SDL_SetWindowMinimumSize(...,%d,%d)", desiredW, desiredH); - _checkInvalidParameterError(); - } - } - } - - /* Clean up */ - _destroyVideoSuiteTestWindow(window); - - /* Set some 'magic' value for later check that nothing was changed */ - referenceW = SDLTest_RandomSint32(); - referenceH = SDLTest_RandomSint32(); - currentW = referenceW; - currentH = referenceH; - desiredW = SDLTest_RandomSint32(); - desiredH = SDLTest_RandomSint32(); - - /* Negative tests for window input */ - SDL_ClearError(); - SDLTest_AssertPass("Call to SDL_ClearError()"); - SDL_GetWindowMinimumSize(NULL, ¤tW, ¤tH); - SDLTest_AssertPass("Call to SDL_GetWindowMinimumSize(window=NULL)"); - SDLTest_AssertCheck( - currentW == referenceW && currentH == referenceH, - "Verify that content of W and H pointers has not been modified; expected: %d,%d; got: %d,%d", - referenceW, referenceH, - currentW, currentH); - _checkInvalidWindowError(); - - SDL_GetWindowMinimumSize(NULL, NULL, NULL); - SDLTest_AssertPass("Call to SDL_GetWindowMinimumSize(NULL, NULL, NULL)"); - _checkInvalidWindowError(); - - SDL_SetWindowMinimumSize(NULL, desiredW, desiredH); - SDLTest_AssertPass("Call to SDL_SetWindowMinimumSize(window=NULL)"); - _checkInvalidWindowError(); - - return TEST_COMPLETED; -} - -/** - * @brief Tests call to SDL_GetWindowMaximumSize and SDL_SetWindowMaximumSize - * - */ -int -video_getSetWindowMaximumSize(void *arg) -{ - const char* title = "video_getSetWindowMaximumSize Test Window"; - SDL_Window* window; - int result; - SDL_Rect display; - int wVariation, hVariation; - int referenceW, referenceH; - int currentW, currentH; - int desiredW, desiredH; - - /* Get display bounds for size range */ - result = SDL_GetDisplayBounds(0, &display); - SDLTest_AssertPass("SDL_GetDisplayBounds()"); - SDLTest_AssertCheck(result == 0, "Verify return value; expected: 0, got: %d", result); - if (result != 0) return TEST_ABORTED; - - /* Call against new test window */ - window = _createVideoSuiteTestWindow(title); - if (window == NULL) return TEST_ABORTED; - - for (wVariation = 0; wVariation < 3; wVariation++) { - for (hVariation = 0; hVariation < 3; hVariation++) { - switch(wVariation) { - case 0: - /* 1 Pixel Wide */ - desiredW = 1; - break; - case 1: - /* Random width inside screen */ - desiredW = SDLTest_RandomIntegerInRange(2, display.w - 1); - break; - case 2: - /* Width at screen size */ - desiredW = display.w; - break; - } - - switch(hVariation) { - case 0: - /* 1 Pixel High */ - desiredH = 1; - break; - case 1: - /* Random height inside screen */ - desiredH = SDLTest_RandomIntegerInRange(2, display.h - 1); - break; - case 2: - /* Height at screen size */ - desiredH = display.h; - break; - } - - /* Set size */ - SDL_SetWindowMaximumSize(window, desiredW, desiredH); - SDLTest_AssertPass("Call to SDL_SetWindowMaximumSize(...,%d,%d)", desiredW, desiredH); - - /* Get size */ - currentW = desiredW + 1; - currentH = desiredH + 1; - SDL_GetWindowMaximumSize(window, ¤tW, ¤tH); - SDLTest_AssertPass("Call to SDL_GetWindowMaximumSize()"); - SDLTest_AssertCheck(desiredW == currentW, "Verify returned width; expected: %d, got: %d", desiredW, currentW); - SDLTest_AssertCheck(desiredH == currentH, "Verify returned height; expected: %d, got: %d", desiredH, currentH); - - /* Get just width */ - currentW = desiredW + 1; - SDL_GetWindowMaximumSize(window, ¤tW, NULL); - SDLTest_AssertPass("Call to SDL_GetWindowMaximumSize(&h=NULL)"); - SDLTest_AssertCheck(desiredW == currentW, "Verify returned width; expected: %d, got: %d", desiredW, currentH); - - /* Get just height */ - currentH = desiredH + 1; - SDL_GetWindowMaximumSize(window, NULL, ¤tH); - SDLTest_AssertPass("Call to SDL_GetWindowMaximumSize(&w=NULL)"); - SDLTest_AssertCheck(desiredH == currentH, "Verify returned height; expected: %d, got: %d", desiredW, currentH); - } - } - - /* Dummy call with both pointers NULL */ - SDL_GetWindowMaximumSize(window, NULL, NULL); - SDLTest_AssertPass("Call to SDL_GetWindowMaximumSize(&w=NULL,&h=NULL)"); - - /* Negative tests for parameter input */ - SDL_ClearError(); - SDLTest_AssertPass("Call to SDL_ClearError()"); - for (desiredH = -2; desiredH < 2; desiredH++) { - for (desiredW = -2; desiredW < 2; desiredW++) { - if (desiredW <= 0 || desiredH <= 0) { - SDL_SetWindowMaximumSize(window, desiredW, desiredH); - SDLTest_AssertPass("Call to SDL_SetWindowMaximumSize(...,%d,%d)", desiredW, desiredH); - _checkInvalidParameterError(); - } - } - } - - /* Clean up */ - _destroyVideoSuiteTestWindow(window); - - /* Set some 'magic' value for later check that nothing was changed */ - referenceW = SDLTest_RandomSint32(); - referenceH = SDLTest_RandomSint32(); - currentW = referenceW; - currentH = referenceH; - desiredW = SDLTest_RandomSint32(); - desiredH = SDLTest_RandomSint32(); - - /* Negative tests */ - SDL_ClearError(); - SDLTest_AssertPass("Call to SDL_ClearError()"); - SDL_GetWindowMaximumSize(NULL, ¤tW, ¤tH); - SDLTest_AssertPass("Call to SDL_GetWindowMaximumSize(window=NULL)"); - SDLTest_AssertCheck( - currentW == referenceW && currentH == referenceH, - "Verify that content of W and H pointers has not been modified; expected: %d,%d; got: %d,%d", - referenceW, referenceH, - currentW, currentH); - _checkInvalidWindowError(); - - SDL_GetWindowMaximumSize(NULL, NULL, NULL); - SDLTest_AssertPass("Call to SDL_GetWindowMaximumSize(NULL, NULL, NULL)"); - _checkInvalidWindowError(); - - SDL_SetWindowMaximumSize(NULL, desiredW, desiredH); - SDLTest_AssertPass("Call to SDL_SetWindowMaximumSize(window=NULL)"); - _checkInvalidWindowError(); - - return TEST_COMPLETED; -} - - -/** - * @brief Tests call to SDL_SetWindowData and SDL_GetWindowData - * - * @sa http://wiki.libsdl.org/moin.fcg/SDL_SetWindowData - * @sa http://wiki.libsdl.org/moin.fcg/SDL_GetWindowData - */ -int -video_getSetWindowData(void *arg) -{ - int returnValue = TEST_COMPLETED; - const char* title = "video_setGetWindowData Test Window"; - SDL_Window* window; - const char *referenceName = "TestName"; - const char *name = "TestName"; - const char *referenceName2 = "TestName2"; - const char *name2 = "TestName2"; - int datasize; - char *referenceUserdata = NULL; - char *userdata = NULL; - char *referenceUserdata2 = NULL; - char *userdata2 = NULL; - char *result; - int iteration; - - /* Call against new test window */ - window = _createVideoSuiteTestWindow(title); - if (window == NULL) return TEST_ABORTED; - - /* Create testdata */ - datasize = SDLTest_RandomIntegerInRange(1, 32); - referenceUserdata = SDLTest_RandomAsciiStringOfSize(datasize); - if (referenceUserdata == NULL) { - returnValue = TEST_ABORTED; - goto cleanup; - } - userdata = SDL_strdup(referenceUserdata); - if (userdata == NULL) { - returnValue = TEST_ABORTED; - goto cleanup; - } - datasize = SDLTest_RandomIntegerInRange(1, 32); - referenceUserdata2 = SDLTest_RandomAsciiStringOfSize(datasize); - if (referenceUserdata2 == NULL) { - returnValue = TEST_ABORTED; - goto cleanup; - } - userdata2 = (char *)SDL_strdup(referenceUserdata2); - if (userdata2 == NULL) { - returnValue = TEST_ABORTED; - goto cleanup; - } - - /* Get non-existent data */ - result = (char *)SDL_GetWindowData(window, name); - SDLTest_AssertPass("Call to SDL_GetWindowData(..,%s)", name); - SDLTest_AssertCheck(result == NULL, "Validate that result is NULL"); - SDLTest_AssertCheck(SDL_strcmp(referenceName, name) == 0, "Validate that name was not changed, expected: %s, got: %s", referenceName, name); - - /* Set data */ - result = (char *)SDL_SetWindowData(window, name, userdata); - SDLTest_AssertPass("Call to SDL_SetWindowData(...%s,%s)", name, userdata); - SDLTest_AssertCheck(result == NULL, "Validate that result is NULL"); - SDLTest_AssertCheck(SDL_strcmp(referenceName, name) == 0, "Validate that name was not changed, expected: %s, got: %s", referenceName, name); - SDLTest_AssertCheck(SDL_strcmp(referenceUserdata, userdata) == 0, "Validate that userdata was not changed, expected: %s, got: %s", referenceUserdata, userdata); - - /* Get data (twice) */ - for (iteration = 1; iteration <= 2; iteration++) { - result = (char *)SDL_GetWindowData(window, name); - SDLTest_AssertPass("Call to SDL_GetWindowData(..,%s) [iteration %d]", name, iteration); - SDLTest_AssertCheck(SDL_strcmp(referenceUserdata, result) == 0, "Validate that correct result was returned; expected: %s, got: %s", referenceUserdata, result); - SDLTest_AssertCheck(SDL_strcmp(referenceName, name) == 0, "Validate that name was not changed, expected: %s, got: %s", referenceName, name); - } - - /* Set data again twice */ - for (iteration = 1; iteration <= 2; iteration++) { - result = (char *)SDL_SetWindowData(window, name, userdata); - SDLTest_AssertPass("Call to SDL_SetWindowData(...%s,%s) [iteration %d]", name, userdata, iteration); - SDLTest_AssertCheck(SDL_strcmp(referenceUserdata, result) == 0, "Validate that correct result was returned; expected: %s, got: %s", referenceUserdata, result); - SDLTest_AssertCheck(SDL_strcmp(referenceName, name) == 0, "Validate that name was not changed, expected: %s, got: %s", referenceName, name); - SDLTest_AssertCheck(SDL_strcmp(referenceUserdata, userdata) == 0, "Validate that userdata was not changed, expected: %s, got: %s", referenceUserdata, userdata); - } - - /* Get data again */ - result = (char *)SDL_GetWindowData(window, name); - SDLTest_AssertPass("Call to SDL_GetWindowData(..,%s) [again]", name); - SDLTest_AssertCheck(SDL_strcmp(referenceUserdata, result) == 0, "Validate that correct result was returned; expected: %s, got: %s", referenceUserdata, result); - SDLTest_AssertCheck(SDL_strcmp(referenceName, name) == 0, "Validate that name was not changed, expected: %s, got: %s", referenceName, name); - - /* Set data with new data */ - result = (char *)SDL_SetWindowData(window, name, userdata2); - SDLTest_AssertPass("Call to SDL_SetWindowData(...%s,%s) [new userdata]", name, userdata2); - SDLTest_AssertCheck(SDL_strcmp(referenceUserdata, result) == 0, "Validate that correct result was returned; expected: %s, got: %s", referenceUserdata, result); - SDLTest_AssertCheck(SDL_strcmp(referenceName, name) == 0, "Validate that name was not changed, expected: %s, got: %s", referenceName, name); - SDLTest_AssertCheck(SDL_strcmp(referenceUserdata, userdata) == 0, "Validate that userdata was not changed, expected: %s, got: %s", referenceUserdata, userdata); - SDLTest_AssertCheck(SDL_strcmp(referenceUserdata2, userdata2) == 0, "Validate that userdata2 was not changed, expected: %s, got: %s", referenceUserdata2, userdata2); - - /* Set data with new data again */ - result = (char *)SDL_SetWindowData(window, name, userdata2); - SDLTest_AssertPass("Call to SDL_SetWindowData(...%s,%s) [new userdata again]", name, userdata2); - SDLTest_AssertCheck(SDL_strcmp(referenceUserdata2, result) == 0, "Validate that correct result was returned; expected: %s, got: %s", referenceUserdata2, result); - SDLTest_AssertCheck(SDL_strcmp(referenceName, name) == 0, "Validate that name was not changed, expected: %s, got: %s", referenceName, name); - SDLTest_AssertCheck(SDL_strcmp(referenceUserdata, userdata) == 0, "Validate that userdata was not changed, expected: %s, got: %s", referenceUserdata, userdata); - SDLTest_AssertCheck(SDL_strcmp(referenceUserdata2, userdata2) == 0, "Validate that userdata2 was not changed, expected: %s, got: %s", referenceUserdata2, userdata2); - - /* Get new data */ - result = (char *)SDL_GetWindowData(window, name); - SDLTest_AssertPass("Call to SDL_GetWindowData(..,%s)", name); - SDLTest_AssertCheck(SDL_strcmp(referenceUserdata2, result) == 0, "Validate that correct result was returned; expected: %s, got: %s", referenceUserdata2, result); - SDLTest_AssertCheck(SDL_strcmp(referenceName, name) == 0, "Validate that name was not changed, expected: %s, got: %s", referenceName, name); - - /* Set data with NULL to clear */ - result = (char *)SDL_SetWindowData(window, name, NULL); - SDLTest_AssertPass("Call to SDL_SetWindowData(...%s,NULL)", name); - SDLTest_AssertCheck(SDL_strcmp(referenceUserdata2, result) == 0, "Validate that correct result was returned; expected: %s, got: %s", referenceUserdata2, result); - SDLTest_AssertCheck(SDL_strcmp(referenceName, name) == 0, "Validate that name was not changed, expected: %s, got: %s", referenceName, name); - SDLTest_AssertCheck(SDL_strcmp(referenceUserdata, userdata) == 0, "Validate that userdata was not changed, expected: %s, got: %s", referenceUserdata, userdata); - SDLTest_AssertCheck(SDL_strcmp(referenceUserdata2, userdata2) == 0, "Validate that userdata2 was not changed, expected: %s, got: %s", referenceUserdata2, userdata2); - - /* Set data with NULL to clear again */ - result = (char *)SDL_SetWindowData(window, name, NULL); - SDLTest_AssertPass("Call to SDL_SetWindowData(...%s,NULL) [again]", name); - SDLTest_AssertCheck(result == NULL, "Validate that result is NULL"); - SDLTest_AssertCheck(SDL_strcmp(referenceName, name) == 0, "Validate that name was not changed, expected: %s, got: %s", referenceName, name); - SDLTest_AssertCheck(SDL_strcmp(referenceUserdata, userdata) == 0, "Validate that userdata was not changed, expected: %s, got: %s", referenceUserdata, userdata); - SDLTest_AssertCheck(SDL_strcmp(referenceUserdata2, userdata2) == 0, "Validate that userdata2 was not changed, expected: %s, got: %s", referenceUserdata2, userdata2); - - /* Get non-existent data */ - result = (char *)SDL_GetWindowData(window, name); - SDLTest_AssertPass("Call to SDL_GetWindowData(..,%s)", name); - SDLTest_AssertCheck(result == NULL, "Validate that result is NULL"); - SDLTest_AssertCheck(SDL_strcmp(referenceName, name) == 0, "Validate that name was not changed, expected: %s, got: %s", referenceName, name); - - /* Get non-existent data new name */ - result = (char *)SDL_GetWindowData(window, name2); - SDLTest_AssertPass("Call to SDL_GetWindowData(..,%s)", name2); - SDLTest_AssertCheck(result == NULL, "Validate that result is NULL"); - SDLTest_AssertCheck(SDL_strcmp(referenceName2, name2) == 0, "Validate that name2 was not changed, expected: %s, got: %s", referenceName2, name2); - - /* Set data (again) */ - result = (char *)SDL_SetWindowData(window, name, userdata); - SDLTest_AssertPass("Call to SDL_SetWindowData(...%s,%s) [again, after clear]", name, userdata); - SDLTest_AssertCheck(result == NULL, "Validate that result is NULL"); - SDLTest_AssertCheck(SDL_strcmp(referenceName, name) == 0, "Validate that name was not changed, expected: %s, got: %s", referenceName, name); - SDLTest_AssertCheck(SDL_strcmp(referenceUserdata, userdata) == 0, "Validate that userdata was not changed, expected: %s, got: %s", referenceUserdata, userdata); - - /* Get data (again) */ - result = (char *)SDL_GetWindowData(window, name); - SDLTest_AssertPass("Call to SDL_GetWindowData(..,%s) [again, after clear]", name); - SDLTest_AssertCheck(SDL_strcmp(referenceUserdata, result) == 0, "Validate that correct result was returned; expected: %s, got: %s", referenceUserdata, result); - SDLTest_AssertCheck(SDL_strcmp(referenceName, name) == 0, "Validate that name was not changed, expected: %s, got: %s", referenceName, name); - - /* Negative test */ - SDL_ClearError(); - SDLTest_AssertPass("Call to SDL_ClearError()"); - - /* Set with invalid window */ - result = (char *)SDL_SetWindowData(NULL, name, userdata); - SDLTest_AssertPass("Call to SDL_SetWindowData(window=NULL)"); - SDLTest_AssertCheck(result == NULL, "Validate that result is NULL"); - _checkInvalidWindowError(); - - /* Set data with NULL name, valid userdata */ - result = (char *)SDL_SetWindowData(window, NULL, userdata); - SDLTest_AssertPass("Call to SDL_SetWindowData(name=NULL)"); - SDLTest_AssertCheck(result == NULL, "Validate that result is NULL"); - _checkInvalidParameterError(); - - /* Set data with empty name, valid userdata */ - result = (char *)SDL_SetWindowData(window, "", userdata); - SDLTest_AssertPass("Call to SDL_SetWindowData(name='')"); - SDLTest_AssertCheck(result == NULL, "Validate that result is NULL"); - _checkInvalidParameterError(); - - /* Set data with NULL name, NULL userdata */ - result = (char *)SDL_SetWindowData(window, NULL, NULL); - SDLTest_AssertPass("Call to SDL_SetWindowData(name=NULL,userdata=NULL)"); - SDLTest_AssertCheck(result == NULL, "Validate that result is NULL"); - _checkInvalidParameterError(); - - /* Set data with empty name, NULL userdata */ - result = (char *)SDL_SetWindowData(window, "", NULL); - SDLTest_AssertPass("Call to SDL_SetWindowData(name='',userdata=NULL)"); - SDLTest_AssertCheck(result == NULL, "Validate that result is NULL"); - _checkInvalidParameterError(); - - /* Get with invalid window */ - result = (char *)SDL_GetWindowData(NULL, name); - SDLTest_AssertPass("Call to SDL_GetWindowData(window=NULL)"); - SDLTest_AssertCheck(result == NULL, "Validate that result is NULL"); - _checkInvalidWindowError(); - - /* Get data with NULL name */ - result = (char *)SDL_GetWindowData(window, NULL); - SDLTest_AssertPass("Call to SDL_GetWindowData(name=NULL)"); - SDLTest_AssertCheck(result == NULL, "Validate that result is NULL"); - _checkInvalidParameterError(); - - /* Get data with empty name */ - result = (char *)SDL_GetWindowData(window, ""); - SDLTest_AssertPass("Call to SDL_GetWindowData(name='')"); - SDLTest_AssertCheck(result == NULL, "Validate that result is NULL"); - _checkInvalidParameterError(); - - /* Clean up */ - _destroyVideoSuiteTestWindow(window); - - cleanup: - SDL_free(referenceUserdata); - SDL_free(referenceUserdata2); - SDL_free(userdata); - SDL_free(userdata2); - - return returnValue; -} - - -/* ================= Test References ================== */ - -/* Video test cases */ -static const SDLTest_TestCaseReference videoTest1 = - { (SDLTest_TestCaseFp)video_enableDisableScreensaver, "video_enableDisableScreensaver", "Enable and disable screenaver while checking state", TEST_ENABLED }; - -static const SDLTest_TestCaseReference videoTest2 = - { (SDLTest_TestCaseFp)video_createWindowVariousPositions, "video_createWindowVariousPositions", "Create windows at various locations", TEST_ENABLED }; - -static const SDLTest_TestCaseReference videoTest3 = - { (SDLTest_TestCaseFp)video_createWindowVariousSizes, "video_createWindowVariousSizes", "Create windows with various sizes", TEST_ENABLED }; - -static const SDLTest_TestCaseReference videoTest4 = - { (SDLTest_TestCaseFp)video_createWindowVariousFlags, "video_createWindowVariousFlags", "Create windows using various flags", TEST_ENABLED }; - -static const SDLTest_TestCaseReference videoTest5 = - { (SDLTest_TestCaseFp)video_getWindowFlags, "video_getWindowFlags", "Get window flags set during SDL_CreateWindow", TEST_ENABLED }; - -static const SDLTest_TestCaseReference videoTest6 = - { (SDLTest_TestCaseFp)video_getNumDisplayModes, "video_getNumDisplayModes", "Use SDL_GetNumDisplayModes function to get number of display modes", TEST_ENABLED }; - -static const SDLTest_TestCaseReference videoTest7 = - { (SDLTest_TestCaseFp)video_getNumDisplayModesNegative, "video_getNumDisplayModesNegative", "Negative tests for SDL_GetNumDisplayModes", TEST_ENABLED }; - -static const SDLTest_TestCaseReference videoTest8 = - { (SDLTest_TestCaseFp)video_getClosestDisplayModeCurrentResolution, "video_getClosestDisplayModeCurrentResolution", "Use function to get closes match to requested display mode for current resolution", TEST_ENABLED }; - -static const SDLTest_TestCaseReference videoTest9 = - { (SDLTest_TestCaseFp)video_getClosestDisplayModeRandomResolution, "video_getClosestDisplayModeRandomResolution", "Use function to get closes match to requested display mode for random resolution", TEST_ENABLED }; - -static const SDLTest_TestCaseReference videoTest10 = - { (SDLTest_TestCaseFp)video_getWindowBrightness, "video_getWindowBrightness", "Get window brightness", TEST_ENABLED }; - -static const SDLTest_TestCaseReference videoTest11 = - { (SDLTest_TestCaseFp)video_getWindowBrightnessNegative, "video_getWindowBrightnessNegative", "Get window brightness with invalid input", TEST_ENABLED }; - -static const SDLTest_TestCaseReference videoTest12 = - { (SDLTest_TestCaseFp)video_getWindowDisplayMode, "video_getWindowDisplayMode", "Get window display mode", TEST_ENABLED }; - -static const SDLTest_TestCaseReference videoTest13 = - { (SDLTest_TestCaseFp)video_getWindowDisplayModeNegative, "video_getWindowDisplayModeNegative", "Get window display mode with invalid input", TEST_ENABLED }; - -static const SDLTest_TestCaseReference videoTest14 = - { (SDLTest_TestCaseFp)video_getWindowGammaRamp, "video_getWindowGammaRamp", "Get window gamma ramp", TEST_ENABLED }; - -static const SDLTest_TestCaseReference videoTest15 = - { (SDLTest_TestCaseFp)video_getWindowGammaRampNegative, "video_getWindowGammaRampNegative", "Get window gamma ramp against invalid input", TEST_ENABLED }; - -static const SDLTest_TestCaseReference videoTest16 = - { (SDLTest_TestCaseFp)video_getSetWindowGrab, "video_getSetWindowGrab", "Checks SDL_GetWindowGrab and SDL_SetWindowGrab positive and negative cases", TEST_ENABLED }; - -static const SDLTest_TestCaseReference videoTest17 = - { (SDLTest_TestCaseFp)video_getWindowId, "video_getWindowId", "Checks SDL_GetWindowID and SDL_GetWindowFromID", TEST_ENABLED }; - -static const SDLTest_TestCaseReference videoTest18 = - { (SDLTest_TestCaseFp)video_getWindowPixelFormat, "video_getWindowPixelFormat", "Checks SDL_GetWindowPixelFormat", TEST_ENABLED }; - -static const SDLTest_TestCaseReference videoTest19 = - { (SDLTest_TestCaseFp)video_getSetWindowPosition, "video_getSetWindowPosition", "Checks SDL_GetWindowPosition and SDL_SetWindowPosition positive and negative cases", TEST_ENABLED }; - -static const SDLTest_TestCaseReference videoTest20 = - { (SDLTest_TestCaseFp)video_getSetWindowSize, "video_getSetWindowSize", "Checks SDL_GetWindowSize and SDL_SetWindowSize positive and negative cases", TEST_ENABLED }; - -static const SDLTest_TestCaseReference videoTest21 = - { (SDLTest_TestCaseFp)video_getSetWindowMinimumSize, "video_getSetWindowMinimumSize", "Checks SDL_GetWindowMinimumSize and SDL_SetWindowMinimumSize positive and negative cases", TEST_ENABLED }; - -static const SDLTest_TestCaseReference videoTest22 = - { (SDLTest_TestCaseFp)video_getSetWindowMaximumSize, "video_getSetWindowMaximumSize", "Checks SDL_GetWindowMaximumSize and SDL_SetWindowMaximumSize positive and negative cases", TEST_ENABLED }; - -static const SDLTest_TestCaseReference videoTest23 = - { (SDLTest_TestCaseFp)video_getSetWindowData, "video_getSetWindowData", "Checks SDL_SetWindowData and SDL_GetWindowData positive and negative cases", TEST_ENABLED }; - -/* Sequence of Video test cases */ -static const SDLTest_TestCaseReference *videoTests[] = { - &videoTest1, &videoTest2, &videoTest3, &videoTest4, &videoTest5, &videoTest6, - &videoTest7, &videoTest8, &videoTest9, &videoTest10, &videoTest11, &videoTest12, - &videoTest13, &videoTest14, &videoTest15, &videoTest16, &videoTest17, - &videoTest18, &videoTest19, &videoTest20, &videoTest21, &videoTest22, - &videoTest23, NULL -}; - -/* Video test suite (global) */ -SDLTest_TestSuiteReference videoTestSuite = { - "Video", - NULL, - videoTests, - NULL -}; diff --git a/SDL2-2.0.12/test/testbounds.c b/SDL2-2.0.12/test/testbounds.c deleted file mode 100644 index e9017e5..0000000 --- a/SDL2-2.0.12/test/testbounds.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ - -#include "SDL.h" - -int main(int argc, char **argv) -{ - int total, i; - - if (SDL_Init(SDL_INIT_VIDEO) < 0) { - SDL_Log("SDL_Init(SDL_INIT_VIDEO) failed: %s", SDL_GetError()); - return 1; - } - - total = SDL_GetNumVideoDisplays(); - for (i = 0; i < total; i++) { - SDL_Rect bounds = { -1,-1,-1,-1 }, usable = { -1,-1,-1,-1 }; - SDL_GetDisplayBounds(i, &bounds); - SDL_GetDisplayUsableBounds(i, &usable); - SDL_Log("Display #%d ('%s'): bounds={(%d,%d),%dx%d}, usable={(%d,%d),%dx%d}", - i, SDL_GetDisplayName(i), - bounds.x, bounds.y, bounds.w, bounds.h, - usable.x, usable.y, usable.w, usable.h); - } - - SDL_Quit(); - return 0; -} - -/* vi: set ts=4 sw=4 expandtab: */ - diff --git a/SDL2-2.0.12/test/testcustomcursor.c b/SDL2-2.0.12/test/testcustomcursor.c deleted file mode 100644 index 3881435..0000000 --- a/SDL2-2.0.12/test/testcustomcursor.c +++ /dev/null @@ -1,259 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ - -#include -#include - -#ifdef __EMSCRIPTEN__ -#include -#endif - -#include "SDL_test_common.h" - -/* Stolen from the mailing list */ -/* Creates a new mouse cursor from an XPM */ - - -/* XPM */ -static const char *arrow[] = { - /* width height num_colors chars_per_pixel */ - " 32 32 3 1", - /* colors */ - "X c #000000", - ". c #ffffff", - " c None", - /* pixels */ - "X ", - "XX ", - "X.X ", - "X..X ", - "X...X ", - "X....X ", - "X.....X ", - "X......X ", - "X.......X ", - "X........X ", - "X.....XXXXX ", - "X..X..X ", - "X.X X..X ", - "XX X..X ", - "X X..X ", - " X..X ", - " X..X ", - " X..X ", - " XX ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - " ", - "0,0" -}; - -static SDL_Cursor* -init_color_cursor(const char *file) -{ - SDL_Cursor *cursor = NULL; - SDL_Surface *surface = SDL_LoadBMP(file); - if (surface) { - if (surface->format->palette) { - SDL_SetColorKey(surface, 1, *(Uint8 *) surface->pixels); - } else { - switch (surface->format->BitsPerPixel) { - case 15: - SDL_SetColorKey(surface, 1, (*(Uint16 *)surface->pixels) & 0x00007FFF); - break; - case 16: - SDL_SetColorKey(surface, 1, *(Uint16 *)surface->pixels); - break; - case 24: - SDL_SetColorKey(surface, 1, (*(Uint32 *)surface->pixels) & 0x00FFFFFF); - break; - case 32: - SDL_SetColorKey(surface, 1, *(Uint32 *)surface->pixels); - break; - } - } - cursor = SDL_CreateColorCursor(surface, 0, 0); - SDL_FreeSurface(surface); - } - return cursor; -} - -static SDL_Cursor* -init_system_cursor(const char *image[]) -{ - int i, row, col; - Uint8 data[4*32]; - Uint8 mask[4*32]; - int hot_x, hot_y; - - i = -1; - for (row=0; row<32; ++row) { - for (col=0; col<32; ++col) { - if (col % 8) { - data[i] <<= 1; - mask[i] <<= 1; - } else { - ++i; - data[i] = mask[i] = 0; - } - switch (image[4+row][col]) { - case 'X': - data[i] |= 0x01; - mask[i] |= 0x01; - break; - case '.': - mask[i] |= 0x01; - break; - case ' ': - break; - } - } - } - sscanf(image[4+row], "%d,%d", &hot_x, &hot_y); - return SDL_CreateCursor(data, mask, 32, 32, hot_x, hot_y); -} - -static SDLTest_CommonState *state; -int done; -static SDL_Cursor *cursors[1+SDL_NUM_SYSTEM_CURSORS]; -static int current_cursor; -static int show_cursor; - -/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ -static void -quit(int rc) -{ - SDLTest_CommonQuit(state); - exit(rc); -} - -void -loop() -{ - int i; - SDL_Event event; - /* Check for events */ - while (SDL_PollEvent(&event)) { - SDLTest_CommonEvent(state, &event, &done); - if (event.type == SDL_MOUSEBUTTONDOWN) { - if (event.button.button == SDL_BUTTON_LEFT) { - ++current_cursor; - if (current_cursor == SDL_arraysize(cursors)) { - current_cursor = 0; - } - SDL_SetCursor(cursors[current_cursor]); - } else { - show_cursor = !show_cursor; - SDL_ShowCursor(show_cursor); - } - } - } - - for (i = 0; i < state->num_windows; ++i) { - SDL_Renderer *renderer = state->renderers[i]; - SDL_RenderClear(renderer); - SDL_RenderPresent(renderer); - } -#ifdef __EMSCRIPTEN__ - if (done) { - emscripten_cancel_main_loop(); - } -#endif -} - -int -main(int argc, char *argv[]) -{ - int i; - const char *color_cursor = NULL; - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - /* Initialize test framework */ - state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO); - if (!state) { - return 1; - } - for (i = 1; i < argc;) { - int consumed; - - consumed = SDLTest_CommonArg(state, i); - if (consumed == 0) { - color_cursor = argv[i]; - break; - } - if (consumed < 0) { - SDLTest_CommonLogUsage(state, argv[0], NULL); - quit(1); - } - i += consumed; - } - - if (!SDLTest_CommonInit(state)) { - quit(2); - } - - for (i = 0; i < state->num_windows; ++i) { - SDL_Renderer *renderer = state->renderers[i]; - SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF); - SDL_RenderClear(renderer); - } - - if (color_cursor) { - cursors[0] = init_color_cursor(color_cursor); - } else { - cursors[0] = init_system_cursor(arrow); - } - if (!cursors[0]) { - SDL_Log("Error, couldn't create cursor\n"); - quit(2); - } - for (i = 0; i < SDL_NUM_SYSTEM_CURSORS; ++i) { - cursors[1+i] = SDL_CreateSystemCursor((SDL_SystemCursor)i); - if (!cursors[1+i]) { - SDL_Log("Error, couldn't create system cursor %d\n", i); - quit(2); - } - } - SDL_SetCursor(cursors[0]); - - /* Main render loop */ - done = 0; -#ifdef __EMSCRIPTEN__ - emscripten_set_main_loop(loop, 0, 1); -#else - while (!done) { - loop(); - } -#endif - - for (i = 0; i < SDL_arraysize(cursors); ++i) { - SDL_FreeCursor(cursors[i]); - } - quit(0); - - /* keep the compiler happy ... */ - return(0); -} - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/test/testdisplayinfo.c b/SDL2-2.0.12/test/testdisplayinfo.c deleted file mode 100644 index 2a8cce1..0000000 --- a/SDL2-2.0.12/test/testdisplayinfo.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ - -/* Program to test querying of display info */ - -#include "SDL.h" - -#include -#include - -static void -print_mode(const char *prefix, const SDL_DisplayMode *mode) -{ - if (!mode) - return; - - SDL_Log("%s: fmt=%s w=%d h=%d refresh=%d\n", - prefix, SDL_GetPixelFormatName(mode->format), - mode->w, mode->h, mode->refresh_rate); -} - -int -main(int argc, char *argv[]) -{ - SDL_DisplayMode mode; - int num_displays, dpy; - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - /* Load the SDL library */ - if (SDL_Init(SDL_INIT_VIDEO) < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError()); - return 1; - } - - SDL_Log("Using video target '%s'.\n", SDL_GetCurrentVideoDriver()); - num_displays = SDL_GetNumVideoDisplays(); - - SDL_Log("See %d displays.\n", num_displays); - - for (dpy = 0; dpy < num_displays; dpy++) { - const int num_modes = SDL_GetNumDisplayModes(dpy); - SDL_Rect rect = { 0, 0, 0, 0 }; - float ddpi, hdpi, vdpi; - int m; - - SDL_GetDisplayBounds(dpy, &rect); - SDL_Log("%d: \"%s\" (%dx%d, (%d, %d)), %d modes.\n", dpy, SDL_GetDisplayName(dpy), rect.w, rect.h, rect.x, rect.y, num_modes); - - if (SDL_GetDisplayDPI(dpy, &ddpi, &hdpi, &vdpi) == -1) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, " DPI: failed to query (%s)\n", SDL_GetError()); - } else { - SDL_Log(" DPI: ddpi=%f; hdpi=%f; vdpi=%f\n", ddpi, hdpi, vdpi); - } - - if (SDL_GetCurrentDisplayMode(dpy, &mode) == -1) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, " CURRENT: failed to query (%s)\n", SDL_GetError()); - } else { - print_mode("CURRENT", &mode); - } - - if (SDL_GetDesktopDisplayMode(dpy, &mode) == -1) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, " DESKTOP: failed to query (%s)\n", SDL_GetError()); - } else { - print_mode("DESKTOP", &mode); - } - - for (m = 0; m < num_modes; m++) { - if (SDL_GetDisplayMode(dpy, m, &mode) == -1) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, " MODE %d: failed to query (%s)\n", m, SDL_GetError()); - } else { - char prefix[64]; - SDL_snprintf(prefix, sizeof (prefix), " MODE %d", m); - print_mode(prefix, &mode); - } - } - - SDL_Log("\n"); - } - - SDL_Quit(); - return 0; -} - -/* vi: set ts=4 sw=4 expandtab: */ - diff --git a/SDL2-2.0.12/test/testdraw2.c b/SDL2-2.0.12/test/testdraw2.c deleted file mode 100644 index 865b55f..0000000 --- a/SDL2-2.0.12/test/testdraw2.c +++ /dev/null @@ -1,305 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ - -/* Simple program: draw as many random objects on the screen as possible */ - -#include -#include -#include - -#ifdef __EMSCRIPTEN__ -#include -#endif - -#include "SDL_test_common.h" - -#define NUM_OBJECTS 100 - -static SDLTest_CommonState *state; -static int num_objects; -static SDL_bool cycle_color; -static SDL_bool cycle_alpha; -static int cycle_direction = 1; -static int current_alpha = 255; -static int current_color = 255; -static SDL_BlendMode blendMode = SDL_BLENDMODE_NONE; - -int done; - -void -DrawPoints(SDL_Renderer * renderer) -{ - int i; - int x, y; - SDL_Rect viewport; - - /* Query the sizes */ - SDL_RenderGetViewport(renderer, &viewport); - - for (i = 0; i < num_objects * 4; ++i) { - /* Cycle the color and alpha, if desired */ - if (cycle_color) { - current_color += cycle_direction; - if (current_color < 0) { - current_color = 0; - cycle_direction = -cycle_direction; - } - if (current_color > 255) { - current_color = 255; - cycle_direction = -cycle_direction; - } - } - if (cycle_alpha) { - current_alpha += cycle_direction; - if (current_alpha < 0) { - current_alpha = 0; - cycle_direction = -cycle_direction; - } - if (current_alpha > 255) { - current_alpha = 255; - cycle_direction = -cycle_direction; - } - } - SDL_SetRenderDrawColor(renderer, 255, (Uint8) current_color, - (Uint8) current_color, (Uint8) current_alpha); - - x = rand() % viewport.w; - y = rand() % viewport.h; - SDL_RenderDrawPoint(renderer, x, y); - } -} - -void -DrawLines(SDL_Renderer * renderer) -{ - int i; - int x1, y1, x2, y2; - SDL_Rect viewport; - - /* Query the sizes */ - SDL_RenderGetViewport(renderer, &viewport); - - for (i = 0; i < num_objects; ++i) { - /* Cycle the color and alpha, if desired */ - if (cycle_color) { - current_color += cycle_direction; - if (current_color < 0) { - current_color = 0; - cycle_direction = -cycle_direction; - } - if (current_color > 255) { - current_color = 255; - cycle_direction = -cycle_direction; - } - } - if (cycle_alpha) { - current_alpha += cycle_direction; - if (current_alpha < 0) { - current_alpha = 0; - cycle_direction = -cycle_direction; - } - if (current_alpha > 255) { - current_alpha = 255; - cycle_direction = -cycle_direction; - } - } - SDL_SetRenderDrawColor(renderer, 255, (Uint8) current_color, - (Uint8) current_color, (Uint8) current_alpha); - - if (i == 0) { - SDL_RenderDrawLine(renderer, 0, 0, viewport.w - 1, viewport.h - 1); - SDL_RenderDrawLine(renderer, 0, viewport.h - 1, viewport.w - 1, 0); - SDL_RenderDrawLine(renderer, 0, viewport.h / 2, viewport.w - 1, viewport.h / 2); - SDL_RenderDrawLine(renderer, viewport.w / 2, 0, viewport.w / 2, viewport.h - 1); - } else { - x1 = (rand() % (viewport.w*2)) - viewport.w; - x2 = (rand() % (viewport.w*2)) - viewport.w; - y1 = (rand() % (viewport.h*2)) - viewport.h; - y2 = (rand() % (viewport.h*2)) - viewport.h; - SDL_RenderDrawLine(renderer, x1, y1, x2, y2); - } - } -} - -void -DrawRects(SDL_Renderer * renderer) -{ - int i; - SDL_Rect rect; - SDL_Rect viewport; - - /* Query the sizes */ - SDL_RenderGetViewport(renderer, &viewport); - - for (i = 0; i < num_objects / 4; ++i) { - /* Cycle the color and alpha, if desired */ - if (cycle_color) { - current_color += cycle_direction; - if (current_color < 0) { - current_color = 0; - cycle_direction = -cycle_direction; - } - if (current_color > 255) { - current_color = 255; - cycle_direction = -cycle_direction; - } - } - if (cycle_alpha) { - current_alpha += cycle_direction; - if (current_alpha < 0) { - current_alpha = 0; - cycle_direction = -cycle_direction; - } - if (current_alpha > 255) { - current_alpha = 255; - cycle_direction = -cycle_direction; - } - } - SDL_SetRenderDrawColor(renderer, 255, (Uint8) current_color, - (Uint8) current_color, (Uint8) current_alpha); - - rect.w = rand() % (viewport.h / 2); - rect.h = rand() % (viewport.h / 2); - rect.x = (rand() % (viewport.w*2) - viewport.w) - (rect.w / 2); - rect.y = (rand() % (viewport.h*2) - viewport.h) - (rect.h / 2); - SDL_RenderFillRect(renderer, &rect); - } -} - -void -loop() -{ - int i; - SDL_Event event; - - /* Check for events */ - while (SDL_PollEvent(&event)) { - SDLTest_CommonEvent(state, &event, &done); - } - for (i = 0; i < state->num_windows; ++i) { - SDL_Renderer *renderer = state->renderers[i]; - if (state->windows[i] == NULL) - continue; - SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF); - SDL_RenderClear(renderer); - - DrawRects(renderer); - DrawLines(renderer); - DrawPoints(renderer); - - SDL_RenderPresent(renderer); - } -#ifdef __EMSCRIPTEN__ - if (done) { - emscripten_cancel_main_loop(); - } -#endif -} - -int -main(int argc, char *argv[]) -{ - int i; - Uint32 then, now, frames; - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - /* Initialize parameters */ - num_objects = NUM_OBJECTS; - - /* Initialize test framework */ - state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO); - if (!state) { - return 1; - } - for (i = 1; i < argc;) { - int consumed; - - consumed = SDLTest_CommonArg(state, i); - if (consumed == 0) { - consumed = -1; - if (SDL_strcasecmp(argv[i], "--blend") == 0) { - if (argv[i + 1]) { - if (SDL_strcasecmp(argv[i + 1], "none") == 0) { - blendMode = SDL_BLENDMODE_NONE; - consumed = 2; - } else if (SDL_strcasecmp(argv[i + 1], "blend") == 0) { - blendMode = SDL_BLENDMODE_BLEND; - consumed = 2; - } else if (SDL_strcasecmp(argv[i + 1], "add") == 0) { - blendMode = SDL_BLENDMODE_ADD; - consumed = 2; - } else if (SDL_strcasecmp(argv[i + 1], "mod") == 0) { - blendMode = SDL_BLENDMODE_MOD; - consumed = 2; - } - } - } else if (SDL_strcasecmp(argv[i], "--cyclecolor") == 0) { - cycle_color = SDL_TRUE; - consumed = 1; - } else if (SDL_strcasecmp(argv[i], "--cyclealpha") == 0) { - cycle_alpha = SDL_TRUE; - consumed = 1; - } else if (SDL_isdigit(*argv[i])) { - num_objects = SDL_atoi(argv[i]); - consumed = 1; - } - } - if (consumed < 0) { - static const char *options[] = { "[--blend none|blend|add|mod]", "[--cyclecolor]", "[--cyclealpha]", NULL }; - SDLTest_CommonLogUsage(state, argv[0], options); - return 1; - } - i += consumed; - } - if (!SDLTest_CommonInit(state)) { - return 2; - } - - /* Create the windows and initialize the renderers */ - for (i = 0; i < state->num_windows; ++i) { - SDL_Renderer *renderer = state->renderers[i]; - SDL_SetRenderDrawBlendMode(renderer, blendMode); - SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF); - SDL_RenderClear(renderer); - } - - srand((unsigned int)time(NULL)); - - /* Main render loop */ - frames = 0; - then = SDL_GetTicks(); - done = 0; - -#ifdef __EMSCRIPTEN__ - emscripten_set_main_loop(loop, 0, 1); -#else - while (!done) { - ++frames; - loop(); - } -#endif - - - SDLTest_CommonQuit(state); - - /* Print out some timing information */ - now = SDL_GetTicks(); - if (now > then) { - double fps = ((double) frames * 1000) / (now - then); - SDL_Log("%2.2f frames per second\n", fps); - } - return 0; -} - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/test/testdrawchessboard.c b/SDL2-2.0.12/test/testdrawchessboard.c deleted file mode 100644 index 8943e70..0000000 --- a/SDL2-2.0.12/test/testdrawchessboard.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - Copyright (C) 1997-2020 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. - - This file is created by : Nitin Jain (nitin.j4@samsung.com) -*/ - -/* Sample program: Draw a Chess Board by using SDL_CreateSoftwareRenderer API */ - -#include -#include - -#ifdef __EMSCRIPTEN__ -#include -#endif - -#include "SDL.h" - -SDL_Window *window; -SDL_Renderer *renderer; -SDL_Surface *surface; -int done; - -void -DrawChessBoard(SDL_Renderer * renderer) -{ - int row = 0,column = 0,x = 0; - SDL_Rect rect, darea; - - /* Get the Size of drawing surface */ - SDL_RenderGetViewport(renderer, &darea); - - for( ; row < 8; row++) - { - column = row%2; - x = column; - for( ; column < 4+(row%2); column++) - { - SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0xFF); - - rect.w = darea.w/8; - rect.h = darea.h/8; - rect.x = x * rect.w; - rect.y = row * rect.h; - x = x + 2; - SDL_RenderFillRect(renderer, &rect); - } - } -} - -void -loop() -{ - SDL_Event e; - while (SDL_PollEvent(&e)) { - - /* Re-create when window has been resized */ - if ((e.type == SDL_WINDOWEVENT) && (e.window.event == SDL_WINDOWEVENT_SIZE_CHANGED)) { - - SDL_DestroyRenderer(renderer); - - surface = SDL_GetWindowSurface(window); - renderer = SDL_CreateSoftwareRenderer(surface); - /* Clear the rendering surface with the specified color */ - SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF); - SDL_RenderClear(renderer); - } - - if (e.type == SDL_QUIT) { - done = 1; -#ifdef __EMSCRIPTEN__ - emscripten_cancel_main_loop(); -#endif - return; - } - - if ((e.type == SDL_KEYDOWN) && (e.key.keysym.sym == SDLK_ESCAPE)) { - done = 1; -#ifdef __EMSCRIPTEN__ - emscripten_cancel_main_loop(); -#endif - return; - } - } - - DrawChessBoard(renderer); - - /* Got everything on rendering surface, - now Update the drawing image on window screen */ - SDL_UpdateWindowSurface(window); -} - -int -main(int argc, char *argv[]) -{ - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - /* Initialize SDL */ - if(SDL_Init(SDL_INIT_VIDEO) != 0) - { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_Init fail : %s\n", SDL_GetError()); - return 1; - } - - - /* Create window and renderer for given surface */ - window = SDL_CreateWindow("Chess Board", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_RESIZABLE); - if(!window) - { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Window creation fail : %s\n",SDL_GetError()); - return 1; - } - surface = SDL_GetWindowSurface(window); - renderer = SDL_CreateSoftwareRenderer(surface); - if(!renderer) - { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Render creation for surface fail : %s\n",SDL_GetError()); - return 1; - } - - /* Clear the rendering surface with the specified color */ - SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF); - SDL_RenderClear(renderer); - - - /* Draw the Image on rendering surface */ - done = 0; -#ifdef __EMSCRIPTEN__ - emscripten_set_main_loop(loop, 0, 1); -#else - while (!done) { - loop(); - } -#endif - - SDL_Quit(); - return 0; -} - diff --git a/SDL2-2.0.12/test/testdropfile.c b/SDL2-2.0.12/test/testdropfile.c deleted file mode 100644 index 930b80f..0000000 --- a/SDL2-2.0.12/test/testdropfile.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ - -#include -#include - -#include "SDL_test_common.h" - -static SDLTest_CommonState *state; - -/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ -static void -quit(int rc) -{ - SDLTest_CommonQuit(state); - exit(rc); -} - -int -main(int argc, char *argv[]) -{ - int i, done; - SDL_Event event; - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - /* Initialize test framework */ - state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO); - if (!state) { - return 1; - } - - for (i = 1; i < argc;) { - int consumed; - - consumed = SDLTest_CommonArg(state, i); - /* needed voodoo to allow app to launch via OS X Finder */ - if (SDL_strncmp(argv[i], "-psn", 4)==0) { - consumed = 1; - } - if (consumed == 0) { - consumed = -1; - } - if (consumed < 0) { - SDLTest_CommonLogUsage(state, argv[0], NULL); - quit(1); - } - i += consumed; - } - if (!SDLTest_CommonInit(state)) { - quit(2); - } - - for (i = 0; i < state->num_windows; ++i) { - SDL_Renderer *renderer = state->renderers[i]; - SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF); - SDL_RenderClear(renderer); - SDL_RenderPresent(renderer); - } - - SDL_EventState(SDL_DROPFILE, SDL_ENABLE); - - /* Main render loop */ - done = 0; - while (!done) { - /* Check for events */ - while (SDL_PollEvent(&event)) { - if (event.type == SDL_DROPBEGIN) { - SDL_Log("Drop beginning on window %u", (unsigned int) event.drop.windowID); - } else if (event.type == SDL_DROPCOMPLETE) { - SDL_Log("Drop complete on window %u", (unsigned int) event.drop.windowID); - } else if ((event.type == SDL_DROPFILE) || (event.type == SDL_DROPTEXT)) { - const char *typestr = (event.type == SDL_DROPFILE) ? "File" : "Text"; - char *dropped_filedir = event.drop.file; - SDL_Log("%s dropped on window %u: %s", typestr, (unsigned int) event.drop.windowID, dropped_filedir); - /* Normally you'd have to do this, but this is freed in SDLTest_CommonEvent() */ - /*SDL_free(dropped_filedir);*/ - } - - SDLTest_CommonEvent(state, &event, &done); - } - } - - quit(0); - /* keep the compiler happy ... */ - return(0); -} - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/test/testerror.c b/SDL2-2.0.12/test/testerror.c deleted file mode 100644 index e638dd1..0000000 --- a/SDL2-2.0.12/test/testerror.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ - -/* Simple test of the SDL threading code and error handling */ - -#include -#include - -#include "SDL.h" - -static int alive = 0; - -/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ -static void -quit(int rc) -{ - SDL_Quit(); - exit(rc); -} - -int SDLCALL -ThreadFunc(void *data) -{ - /* Set the child thread error string */ - SDL_SetError("Thread %s (%lu) had a problem: %s", - (char *) data, SDL_ThreadID(), "nevermind"); - while (alive) { - SDL_Log("Thread '%s' is alive!\n", (char *) data); - SDL_Delay(1 * 1000); - } - SDL_Log("Child thread error string: %s\n", SDL_GetError()); - return (0); -} - -int -main(int argc, char *argv[]) -{ - SDL_Thread *thread; - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - /* Load the SDL library */ - if (SDL_Init(0) < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError()); - return (1); - } - - /* Set the error value for the main thread */ - SDL_SetError("No worries"); - - alive = 1; - thread = SDL_CreateThread(ThreadFunc, NULL, "#1"); - if (thread == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create thread: %s\n", SDL_GetError()); - quit(1); - } - SDL_Delay(5 * 1000); - SDL_Log("Waiting for thread #1\n"); - alive = 0; - SDL_WaitThread(thread, NULL); - - SDL_Log("Main thread error string: %s\n", SDL_GetError()); - - SDL_Quit(); - return (0); -} diff --git a/SDL2-2.0.12/test/testfile.c b/SDL2-2.0.12/test/testfile.c deleted file mode 100644 index b22ffa1..0000000 --- a/SDL2-2.0.12/test/testfile.c +++ /dev/null @@ -1,283 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ - -/* sanity tests on SDL_rwops.c (usefull for alternative implementations of stdio rwops) */ - -/* quiet windows compiler warnings */ -#define _CRT_NONSTDC_NO_WARNINGS - -#include - -#ifndef _MSC_VER -#include -#endif - -#include "SDL.h" - - -#include - -/* WARNING ! those 2 files will be destroyed by this test program */ - -#ifdef __IPHONEOS__ -#define FBASENAME1 "../Documents/sdldata1" /* this file will be created during tests */ -#define FBASENAME2 "../Documents/sdldata2" /* this file should not exist before starting test */ -#else -#define FBASENAME1 "sdldata1" /* this file will be created during tests */ -#define FBASENAME2 "sdldata2" /* this file should not exist before starting test */ -#endif - -#ifndef NULL -#define NULL ((void *)0) -#endif - -static void -cleanup(void) -{ - unlink(FBASENAME1); - unlink(FBASENAME2); -} - -static void -rwops_error_quit(unsigned line, SDL_RWops * rwops) -{ - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "testfile.c(%d): failed\n", line); - if (rwops) { - rwops->close(rwops); /* This calls SDL_FreeRW(rwops); */ - } - cleanup(); - exit(1); /* quit with rwops error (test failed) */ -} - -#define RWOP_ERR_QUIT(x) rwops_error_quit( __LINE__, (x) ) - - - -int -main(int argc, char *argv[]) -{ - SDL_RWops *rwops = NULL; - char test_buf[30]; - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - cleanup(); - -/* test 1 : basic argument test: all those calls to SDL_RWFromFile should fail */ - - rwops = SDL_RWFromFile(NULL, NULL); - if (rwops) - RWOP_ERR_QUIT(rwops); - rwops = SDL_RWFromFile(NULL, "ab+"); - if (rwops) - RWOP_ERR_QUIT(rwops); - rwops = SDL_RWFromFile(NULL, "sldfkjsldkfj"); - if (rwops) - RWOP_ERR_QUIT(rwops); - rwops = SDL_RWFromFile("something", ""); - if (rwops) - RWOP_ERR_QUIT(rwops); - rwops = SDL_RWFromFile("something", NULL); - if (rwops) - RWOP_ERR_QUIT(rwops); - SDL_Log("test1 OK\n"); - -/* test 2 : check that inexistent file is not successfully opened/created when required */ -/* modes : r, r+ imply that file MUST exist - modes : a, a+, w, w+ checks that it succeeds (file may not exists) - - */ - rwops = SDL_RWFromFile(FBASENAME2, "rb"); /* this file doesn't exist that call must fail */ - if (rwops) - RWOP_ERR_QUIT(rwops); - rwops = SDL_RWFromFile(FBASENAME2, "rb+"); /* this file doesn't exist that call must fail */ - if (rwops) - RWOP_ERR_QUIT(rwops); - rwops = SDL_RWFromFile(FBASENAME2, "wb"); - if (!rwops) - RWOP_ERR_QUIT(rwops); - rwops->close(rwops); - unlink(FBASENAME2); - rwops = SDL_RWFromFile(FBASENAME2, "wb+"); - if (!rwops) - RWOP_ERR_QUIT(rwops); - rwops->close(rwops); - unlink(FBASENAME2); - rwops = SDL_RWFromFile(FBASENAME2, "ab"); - if (!rwops) - RWOP_ERR_QUIT(rwops); - rwops->close(rwops); - unlink(FBASENAME2); - rwops = SDL_RWFromFile(FBASENAME2, "ab+"); - if (!rwops) - RWOP_ERR_QUIT(rwops); - rwops->close(rwops); - unlink(FBASENAME2); - SDL_Log("test2 OK\n"); - -/* test 3 : creation, writing , reading, seeking, - test : w mode, r mode, w+ mode - */ - rwops = SDL_RWFromFile(FBASENAME1, "wb"); /* write only */ - if (!rwops) - RWOP_ERR_QUIT(rwops); - if (1 != rwops->write(rwops, "1234567890", 10, 1)) - RWOP_ERR_QUIT(rwops); - if (10 != rwops->write(rwops, "1234567890", 1, 10)) - RWOP_ERR_QUIT(rwops); - if (7 != rwops->write(rwops, "1234567", 1, 7)) - RWOP_ERR_QUIT(rwops); - if (0 != rwops->seek(rwops, 0L, RW_SEEK_SET)) - RWOP_ERR_QUIT(rwops); - if (0 != rwops->read(rwops, test_buf, 1, 1)) - RWOP_ERR_QUIT(rwops); /* we are in write only mode */ - rwops->close(rwops); - - rwops = SDL_RWFromFile(FBASENAME1, "rb"); /* read mode, file must exists */ - if (!rwops) - RWOP_ERR_QUIT(rwops); - if (0 != rwops->seek(rwops, 0L, RW_SEEK_SET)) - RWOP_ERR_QUIT(rwops); - if (20 != rwops->seek(rwops, -7, RW_SEEK_END)) - RWOP_ERR_QUIT(rwops); - if (7 != rwops->read(rwops, test_buf, 1, 7)) - RWOP_ERR_QUIT(rwops); - if (SDL_memcmp(test_buf, "1234567", 7)) - RWOP_ERR_QUIT(rwops); - if (0 != rwops->read(rwops, test_buf, 1, 1)) - RWOP_ERR_QUIT(rwops); - if (0 != rwops->read(rwops, test_buf, 10, 100)) - RWOP_ERR_QUIT(rwops); - if (0 != rwops->seek(rwops, -27, RW_SEEK_CUR)) - RWOP_ERR_QUIT(rwops); - if (2 != rwops->read(rwops, test_buf, 10, 3)) - RWOP_ERR_QUIT(rwops); - if (SDL_memcmp(test_buf, "12345678901234567890", 20)) - RWOP_ERR_QUIT(rwops); - if (0 != rwops->write(rwops, test_buf, 1, 1)) - RWOP_ERR_QUIT(rwops); /* readonly mode */ - rwops->close(rwops); - -/* test 3: same with w+ mode */ - rwops = SDL_RWFromFile(FBASENAME1, "wb+"); /* write + read + truncation */ - if (!rwops) - RWOP_ERR_QUIT(rwops); - if (1 != rwops->write(rwops, "1234567890", 10, 1)) - RWOP_ERR_QUIT(rwops); - if (10 != rwops->write(rwops, "1234567890", 1, 10)) - RWOP_ERR_QUIT(rwops); - if (7 != rwops->write(rwops, "1234567", 1, 7)) - RWOP_ERR_QUIT(rwops); - if (0 != rwops->seek(rwops, 0L, RW_SEEK_SET)) - RWOP_ERR_QUIT(rwops); - if (1 != rwops->read(rwops, test_buf, 1, 1)) - RWOP_ERR_QUIT(rwops); /* we are in read/write mode */ - if (0 != rwops->seek(rwops, 0L, RW_SEEK_SET)) - RWOP_ERR_QUIT(rwops); - if (20 != rwops->seek(rwops, -7, RW_SEEK_END)) - RWOP_ERR_QUIT(rwops); - if (7 != rwops->read(rwops, test_buf, 1, 7)) - RWOP_ERR_QUIT(rwops); - if (SDL_memcmp(test_buf, "1234567", 7)) - RWOP_ERR_QUIT(rwops); - if (0 != rwops->read(rwops, test_buf, 1, 1)) - RWOP_ERR_QUIT(rwops); - if (0 != rwops->read(rwops, test_buf, 10, 100)) - RWOP_ERR_QUIT(rwops); - if (0 != rwops->seek(rwops, -27, RW_SEEK_CUR)) - RWOP_ERR_QUIT(rwops); - if (2 != rwops->read(rwops, test_buf, 10, 3)) - RWOP_ERR_QUIT(rwops); - if (SDL_memcmp(test_buf, "12345678901234567890", 20)) - RWOP_ERR_QUIT(rwops); - rwops->close(rwops); - SDL_Log("test3 OK\n"); - -/* test 4: same in r+ mode */ - rwops = SDL_RWFromFile(FBASENAME1, "rb+"); /* write + read + file must exists, no truncation */ - if (!rwops) - RWOP_ERR_QUIT(rwops); - if (1 != rwops->write(rwops, "1234567890", 10, 1)) - RWOP_ERR_QUIT(rwops); - if (10 != rwops->write(rwops, "1234567890", 1, 10)) - RWOP_ERR_QUIT(rwops); - if (7 != rwops->write(rwops, "1234567", 1, 7)) - RWOP_ERR_QUIT(rwops); - if (0 != rwops->seek(rwops, 0L, RW_SEEK_SET)) - RWOP_ERR_QUIT(rwops); - if (1 != rwops->read(rwops, test_buf, 1, 1)) - RWOP_ERR_QUIT(rwops); /* we are in read/write mode */ - if (0 != rwops->seek(rwops, 0L, RW_SEEK_SET)) - RWOP_ERR_QUIT(rwops); - if (20 != rwops->seek(rwops, -7, RW_SEEK_END)) - RWOP_ERR_QUIT(rwops); - if (7 != rwops->read(rwops, test_buf, 1, 7)) - RWOP_ERR_QUIT(rwops); - if (SDL_memcmp(test_buf, "1234567", 7)) - RWOP_ERR_QUIT(rwops); - if (0 != rwops->read(rwops, test_buf, 1, 1)) - RWOP_ERR_QUIT(rwops); - if (0 != rwops->read(rwops, test_buf, 10, 100)) - RWOP_ERR_QUIT(rwops); - if (0 != rwops->seek(rwops, -27, RW_SEEK_CUR)) - RWOP_ERR_QUIT(rwops); - if (2 != rwops->read(rwops, test_buf, 10, 3)) - RWOP_ERR_QUIT(rwops); - if (SDL_memcmp(test_buf, "12345678901234567890", 20)) - RWOP_ERR_QUIT(rwops); - rwops->close(rwops); - SDL_Log("test4 OK\n"); - -/* test5 : append mode */ - rwops = SDL_RWFromFile(FBASENAME1, "ab+"); /* write + read + append */ - if (!rwops) - RWOP_ERR_QUIT(rwops); - if (1 != rwops->write(rwops, "1234567890", 10, 1)) - RWOP_ERR_QUIT(rwops); - if (10 != rwops->write(rwops, "1234567890", 1, 10)) - RWOP_ERR_QUIT(rwops); - if (7 != rwops->write(rwops, "1234567", 1, 7)) - RWOP_ERR_QUIT(rwops); - if (0 != rwops->seek(rwops, 0L, RW_SEEK_SET)) - RWOP_ERR_QUIT(rwops); - - if (1 != rwops->read(rwops, test_buf, 1, 1)) - RWOP_ERR_QUIT(rwops); - if (0 != rwops->seek(rwops, 0L, RW_SEEK_SET)) - RWOP_ERR_QUIT(rwops); - - if (20 + 27 != rwops->seek(rwops, -7, RW_SEEK_END)) - RWOP_ERR_QUIT(rwops); - if (7 != rwops->read(rwops, test_buf, 1, 7)) - RWOP_ERR_QUIT(rwops); - if (SDL_memcmp(test_buf, "1234567", 7)) - RWOP_ERR_QUIT(rwops); - if (0 != rwops->read(rwops, test_buf, 1, 1)) - RWOP_ERR_QUIT(rwops); - if (0 != rwops->read(rwops, test_buf, 10, 100)) - RWOP_ERR_QUIT(rwops); - - if (27 != rwops->seek(rwops, -27, RW_SEEK_CUR)) - RWOP_ERR_QUIT(rwops); - - if (0 != rwops->seek(rwops, 0L, RW_SEEK_SET)) - RWOP_ERR_QUIT(rwops); - if (3 != rwops->read(rwops, test_buf, 10, 3)) - RWOP_ERR_QUIT(rwops); - if (SDL_memcmp(test_buf, "123456789012345678901234567123", 30)) - RWOP_ERR_QUIT(rwops); - rwops->close(rwops); - SDL_Log("test5 OK\n"); - cleanup(); - return 0; /* all ok */ -} diff --git a/SDL2-2.0.12/test/testfilesystem.c b/SDL2-2.0.12/test/testfilesystem.c deleted file mode 100644 index c9a82d0..0000000 --- a/SDL2-2.0.12/test/testfilesystem.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ -/* Simple test of filesystem functions. */ - -#include -#include "SDL.h" - -int -main(int argc, char *argv[]) -{ - char *base_path; - char *pref_path; - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - if (SDL_Init(0) == -1) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_Init() failed: %s\n", SDL_GetError()); - return 1; - } - - base_path = SDL_GetBasePath(); - if(base_path == NULL){ - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't find base path: %s\n", - SDL_GetError()); - } else { - SDL_Log("base path: '%s'\n", base_path); - SDL_free(base_path); - } - - pref_path = SDL_GetPrefPath("libsdl", "testfilesystem"); - if(pref_path == NULL){ - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't find pref path: %s\n", - SDL_GetError()); - } else { - SDL_Log("pref path: '%s'\n", pref_path); - SDL_free(pref_path); - } - - pref_path = SDL_GetPrefPath(NULL, "testfilesystem"); - if(pref_path == NULL){ - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't find pref path without organization: %s\n", - SDL_GetError()); - } else { - SDL_Log("pref path: '%s'\n", pref_path); - SDL_free(pref_path); - } - - SDL_Quit(); - return 0; -} diff --git a/SDL2-2.0.12/test/testgamecontroller.c b/SDL2-2.0.12/test/testgamecontroller.c deleted file mode 100644 index 6ed3105..0000000 --- a/SDL2-2.0.12/test/testgamecontroller.c +++ /dev/null @@ -1,396 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ - -/* Simple program to test the SDL game controller routines */ - -#include -#include -#include - -#include "SDL.h" - -#ifdef __EMSCRIPTEN__ -#include -#endif - -#ifndef SDL_JOYSTICK_DISABLED - -#ifdef __IPHONEOS__ -#define SCREEN_WIDTH 480 -#define SCREEN_HEIGHT 320 -#else -#define SCREEN_WIDTH 512 -#define SCREEN_HEIGHT 320 -#endif - -/* This is indexed by SDL_GameControllerButton. */ -static const struct { int x; int y; } button_positions[] = { - {387, 167}, /* A */ - {431, 132}, /* B */ - {342, 132}, /* X */ - {389, 101}, /* Y */ - {174, 132}, /* BACK */ - {233, 132}, /* GUIDE */ - {289, 132}, /* START */ - {75, 154}, /* LEFTSTICK */ - {305, 230}, /* RIGHTSTICK */ - {77, 40}, /* LEFTSHOULDER */ - {396, 36}, /* RIGHTSHOULDER */ - {154, 188}, /* DPAD_UP */ - {154, 249}, /* DPAD_DOWN */ - {116, 217}, /* DPAD_LEFT */ - {186, 217}, /* DPAD_RIGHT */ -}; - -/* This is indexed by SDL_GameControllerAxis. */ -static const struct { int x; int y; double angle; } axis_positions[] = { - {74, 153, 270.0}, /* LEFTX */ - {74, 153, 0.0}, /* LEFTY */ - {306, 231, 270.0}, /* RIGHTX */ - {306, 231, 0.0}, /* RIGHTY */ - {91, -20, 0.0}, /* TRIGGERLEFT */ - {375, -20, 0.0}, /* TRIGGERRIGHT */ -}; - -SDL_Renderer *screen = NULL; -SDL_bool retval = SDL_FALSE; -SDL_bool done = SDL_FALSE; -SDL_Texture *background, *button, *axis; - -static SDL_Texture * -LoadTexture(SDL_Renderer *renderer, const char *file, SDL_bool transparent) -{ - SDL_Surface *temp = NULL; - SDL_Texture *texture = NULL; - - temp = SDL_LoadBMP(file); - if (temp == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s", file, SDL_GetError()); - } else { - /* Set transparent pixel as the pixel at (0,0) */ - if (transparent) { - if (temp->format->BytesPerPixel == 1) { - SDL_SetColorKey(temp, SDL_TRUE, *(Uint8 *)temp->pixels); - } - } - - texture = SDL_CreateTextureFromSurface(renderer, temp); - if (!texture) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError()); - } - } - if (temp) { - SDL_FreeSurface(temp); - } - return texture; -} - -void -loop(void *arg) -{ - SDL_Event event; - int i; - SDL_GameController *gamecontroller = (SDL_GameController *)arg; - - /* blank screen, set up for drawing this frame. */ - SDL_SetRenderDrawColor(screen, 0xFF, 0xFF, 0xFF, SDL_ALPHA_OPAQUE); - SDL_RenderClear(screen); - SDL_RenderCopy(screen, background, NULL, NULL); - - while (SDL_PollEvent(&event)) { - switch (event.type) { - case SDL_CONTROLLERAXISMOTION: - SDL_Log("Controller axis %s changed to %d\n", SDL_GameControllerGetStringForAxis((SDL_GameControllerAxis)event.caxis.axis), event.caxis.value); - break; - case SDL_CONTROLLERBUTTONDOWN: - case SDL_CONTROLLERBUTTONUP: - SDL_Log("Controller button %s %s\n", SDL_GameControllerGetStringForButton((SDL_GameControllerButton)event.cbutton.button), event.cbutton.state ? "pressed" : "released"); - break; - case SDL_KEYDOWN: - if (event.key.keysym.sym != SDLK_ESCAPE) { - break; - } - /* Fall through to signal quit */ - case SDL_QUIT: - done = SDL_TRUE; - break; - default: - break; - } - } - - /* Update visual controller state */ - for (i = 0; i < SDL_CONTROLLER_BUTTON_MAX; ++i) { - if (SDL_GameControllerGetButton(gamecontroller, (SDL_GameControllerButton)i) == SDL_PRESSED) { - const SDL_Rect dst = { button_positions[i].x, button_positions[i].y, 50, 50 }; - SDL_RenderCopyEx(screen, button, NULL, &dst, 0, NULL, SDL_FLIP_NONE); - } - } - - for (i = 0; i < SDL_CONTROLLER_AXIS_MAX; ++i) { - const Sint16 deadzone = 8000; /* !!! FIXME: real deadzone */ - const Sint16 value = SDL_GameControllerGetAxis(gamecontroller, (SDL_GameControllerAxis)(i)); - if (value < -deadzone) { - const SDL_Rect dst = { axis_positions[i].x, axis_positions[i].y, 50, 50 }; - const double angle = axis_positions[i].angle; - SDL_RenderCopyEx(screen, axis, NULL, &dst, angle, NULL, SDL_FLIP_NONE); - } else if (value > deadzone) { - const SDL_Rect dst = { axis_positions[i].x, axis_positions[i].y, 50, 50 }; - const double angle = axis_positions[i].angle + 180.0; - SDL_RenderCopyEx(screen, axis, NULL, &dst, angle, NULL, SDL_FLIP_NONE); - } - } - - /* Update rumble based on trigger state */ - { - Uint16 low_frequency_rumble = SDL_GameControllerGetAxis(gamecontroller, SDL_CONTROLLER_AXIS_TRIGGERLEFT) * 2; - Uint16 high_frequency_rumble = SDL_GameControllerGetAxis(gamecontroller, SDL_CONTROLLER_AXIS_TRIGGERRIGHT) * 2; - SDL_GameControllerRumble(gamecontroller, low_frequency_rumble, high_frequency_rumble, 250); - } - - SDL_RenderPresent(screen); - - if (!SDL_GameControllerGetAttached(gamecontroller)) { - done = SDL_TRUE; - retval = SDL_TRUE; /* keep going, wait for reattach. */ - } - -#ifdef __EMSCRIPTEN__ - if (done) { - emscripten_cancel_main_loop(); - } -#endif -} - -SDL_bool -WatchGameController(SDL_GameController * gamecontroller) -{ - const char *name = SDL_GameControllerName(gamecontroller); - const char *basetitle = "Game Controller Test: "; - const size_t titlelen = SDL_strlen(basetitle) + SDL_strlen(name) + 1; - char *title = (char *)SDL_malloc(titlelen); - SDL_Window *window = NULL; - - retval = SDL_FALSE; - done = SDL_FALSE; - - if (title) { - SDL_snprintf(title, titlelen, "%s%s", basetitle, name); - } - - /* Create a window to display controller state */ - window = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, - SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, - SCREEN_HEIGHT, 0); - SDL_free(title); - title = NULL; - if (window == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create window: %s\n", SDL_GetError()); - return SDL_FALSE; - } - - screen = SDL_CreateRenderer(window, -1, 0); - if (screen == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create renderer: %s\n", SDL_GetError()); - SDL_DestroyWindow(window); - return SDL_FALSE; - } - - SDL_SetRenderDrawColor(screen, 0x00, 0x00, 0x00, SDL_ALPHA_OPAQUE); - SDL_RenderClear(screen); - SDL_RenderPresent(screen); - SDL_RaiseWindow(window); - - /* scale for platforms that don't give you the window size you asked for. */ - SDL_RenderSetLogicalSize(screen, SCREEN_WIDTH, SCREEN_HEIGHT); - - background = LoadTexture(screen, "controllermap.bmp", SDL_FALSE); - button = LoadTexture(screen, "button.bmp", SDL_TRUE); - axis = LoadTexture(screen, "axis.bmp", SDL_TRUE); - - if (!background || !button || !axis) { - SDL_DestroyRenderer(screen); - SDL_DestroyWindow(window); - return SDL_FALSE; - } - SDL_SetTextureColorMod(button, 10, 255, 21); - SDL_SetTextureColorMod(axis, 10, 255, 21); - - /* !!! FIXME: */ - /*SDL_RenderSetLogicalSize(screen, background->w, background->h);*/ - - /* Print info about the controller we are watching */ - SDL_Log("Watching controller %s\n", name ? name : "Unknown Controller"); - - /* Loop, getting controller events! */ -#ifdef __EMSCRIPTEN__ - emscripten_set_main_loop_arg(loop, gamecontroller, 0, 1); -#else - while (!done) { - loop(gamecontroller); - } -#endif - - SDL_DestroyRenderer(screen); - screen = NULL; - background = NULL; - button = NULL; - axis = NULL; - SDL_DestroyWindow(window); - return retval; -} - -int -main(int argc, char *argv[]) -{ - int i; - int nController = 0; - int retcode = 0; - char guid[64]; - SDL_GameController *gamecontroller; - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - /* Initialize SDL (Note: video is required to start event loop) */ - if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER ) < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError()); - return 1; - } - - SDL_GameControllerAddMappingsFromFile("gamecontrollerdb.txt"); - - /* Print information about the mappings */ - if (!argv[1]) { - SDL_Log("Supported mappings:\n"); - for (i = 0; i < SDL_GameControllerNumMappings(); ++i) { - char *mapping = SDL_GameControllerMappingForIndex(i); - if (mapping) { - SDL_Log("\t%s\n", mapping); - SDL_free(mapping); - } - } - SDL_Log("\n"); - } - - /* Print information about the controller */ - for (i = 0; i < SDL_NumJoysticks(); ++i) { - const char *name; - const char *description; - - SDL_JoystickGetGUIDString(SDL_JoystickGetDeviceGUID(i), - guid, sizeof (guid)); - - if ( SDL_IsGameController(i) ) - { - nController++; - name = SDL_GameControllerNameForIndex(i); - switch (SDL_GameControllerTypeForIndex(i)) { - case SDL_CONTROLLER_TYPE_XBOX360: - description = "XBox 360 Controller"; - break; - case SDL_CONTROLLER_TYPE_XBOXONE: - description = "XBox One Controller"; - break; - case SDL_CONTROLLER_TYPE_PS3: - description = "PS3 Controller"; - break; - case SDL_CONTROLLER_TYPE_PS4: - description = "PS4 Controller"; - break; - case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO: - description = "Nintendo Switch Pro Controller"; - break; - default: - description = "Game Controller"; - break; - } - } else { - name = SDL_JoystickNameForIndex(i); - description = "Joystick"; - } - SDL_Log("%s %d: %s (guid %s, VID 0x%.4x, PID 0x%.4x, player index = %d)\n", - description, i, name ? name : "Unknown", guid, - SDL_JoystickGetDeviceVendor(i), SDL_JoystickGetDeviceProduct(i), SDL_JoystickGetDevicePlayerIndex(i)); - } - SDL_Log("There are %d game controller(s) attached (%d joystick(s))\n", nController, SDL_NumJoysticks()); - - if (argv[1]) { - SDL_bool reportederror = SDL_FALSE; - SDL_bool keepGoing = SDL_TRUE; - SDL_Event event; - int device = atoi(argv[1]); - if (device >= SDL_NumJoysticks()) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "%i is an invalid joystick index.\n", device); - retcode = 1; - } else { - SDL_JoystickGetGUIDString(SDL_JoystickGetDeviceGUID(device), - guid, sizeof (guid)); - SDL_Log("Attempting to open device %i, guid %s\n", device, guid); - gamecontroller = SDL_GameControllerOpen(device); - - if (gamecontroller != NULL) { - SDL_assert(SDL_GameControllerFromInstanceID(SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(gamecontroller))) == gamecontroller); - } - - while (keepGoing) { - if (gamecontroller == NULL) { - if (!reportederror) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open gamecontroller %d: %s\n", device, SDL_GetError()); - retcode = 1; - keepGoing = SDL_FALSE; - reportederror = SDL_TRUE; - } - } else { - reportederror = SDL_FALSE; - keepGoing = WatchGameController(gamecontroller); - SDL_GameControllerClose(gamecontroller); - } - - gamecontroller = NULL; - if (keepGoing) { - SDL_Log("Waiting for attach\n"); - } - while (keepGoing) { - SDL_WaitEvent(&event); - if ((event.type == SDL_QUIT) || (event.type == SDL_FINGERDOWN) - || (event.type == SDL_MOUSEBUTTONDOWN)) { - keepGoing = SDL_FALSE; - } else if (event.type == SDL_CONTROLLERDEVICEADDED) { - gamecontroller = SDL_GameControllerOpen(event.cdevice.which); - if (gamecontroller != NULL) { - SDL_assert(SDL_GameControllerFromInstanceID(SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(gamecontroller))) == gamecontroller); - } - break; - } - } - } - } - } - - SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER); - - return retcode; -} - -#else - -int -main(int argc, char *argv[]) -{ - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL compiled without Joystick support.\n"); - return 1; -} - -#endif - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/test/testgesture.c b/SDL2-2.0.12/test/testgesture.c deleted file mode 100644 index a925e0a..0000000 --- a/SDL2-2.0.12/test/testgesture.c +++ /dev/null @@ -1,297 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ - -/* Usage: - * Spacebar to begin recording a gesture on all touches. - * s to save all touches into "./gestureSave" - * l to load all touches from "./gestureSave" - */ - -#include "SDL.h" -#include /* for exit() */ - -#ifdef __EMSCRIPTEN__ -#include -#endif - -#include "SDL_test.h" -#include "SDL_test_common.h" - -#define WIDTH 640 -#define HEIGHT 480 -#define BPP 4 - -/* MUST BE A POWER OF 2! */ -#define EVENT_BUF_SIZE 256 - -#define VERBOSE 0 - -static SDLTest_CommonState *state; -static SDL_Event events[EVENT_BUF_SIZE]; -static int eventWrite; -static int colors[7] = {0xFF,0xFF00,0xFF0000,0xFFFF00,0x00FFFF,0xFF00FF,0xFFFFFF}; -static int quitting = 0; - -typedef struct -{ - float x, y; -} Point; - -typedef struct -{ - float ang, r; - Point p; -} Knob; - -static Knob knob = { 0.0f, 0.1f, { 0.0f, 0.0f } }; - - -static void -setpix(SDL_Surface *screen, float _x, float _y, unsigned int col) -{ - Uint32 *pixmem32; - Uint32 colour; - Uint8 r, g, b; - const int x = (int)_x; - const int y = (int)_y; - float a; - - if ( (x < 0) || (x >= screen->w) || (y < 0) || (y >= screen->h) ) { - return; - } - - pixmem32 = (Uint32 *) screen->pixels + y * screen->pitch / BPP + x; - - SDL_memcpy(&colour, pixmem32, screen->format->BytesPerPixel); - - SDL_GetRGB(colour,screen->format,&r,&g,&b); - - /* r = 0;g = 0; b = 0; */ - a = (float) ((col >> 24) & 0xFF); - if (a == 0) { - a = 0xFF; /* Hack, to make things easier. */ - } - - a = (a == 0.0f) ? 1 : (a / 255.0f); - r = (Uint8) (r * (1 - a) + ((col >> 16) & 0xFF) * a); - g = (Uint8) (g * (1 - a) + ((col >> 8) & 0xFF) * a); - b = (Uint8) (b * (1 - a) + ((col >> 0) & 0xFF) * a); - colour = SDL_MapRGB(screen->format, r, g, b); - - *pixmem32 = colour; -} - -static void -drawLine(SDL_Surface *screen, float x0, float y0, float x1, float y1, unsigned int col) -{ - float t; - for (t = 0; t < 1; t += (float) (1.0f / SDL_max(SDL_fabs(x0 - x1), SDL_fabs(y0 - y1)))) { - setpix(screen, x1 + t * (x0 - x1), y1 + t * (y0 - y1), col); - } -} - -static void -drawCircle(SDL_Surface *screen, float x, float y, float r, unsigned int c) -{ - float tx,ty, xr; - for (ty = (float) -SDL_fabs(r); ty <= (float) SDL_fabs((int) r); ty++) { - xr = (float) SDL_sqrt(r * r - ty * ty); - if (r > 0) { /* r > 0 ==> filled circle */ - for(tx = -xr + 0.5f; tx <= xr - 0.5f; tx++) { - setpix(screen, x + tx, y + ty, c); - } - } else { - setpix(screen, x - xr + 0.5f, y + ty, c); - setpix(screen, x + xr - 0.5f, y + ty, c); - } - } -} - -static void -drawKnob(SDL_Surface *screen, const Knob *k) -{ - drawCircle(screen, k->p.x * screen->w, k->p.y * screen->h, k->r * screen->w, 0xFFFFFF); - drawCircle(screen, (k->p.x + k->r / 2 * SDL_cosf(k->ang)) * screen->w, - (k->p.y + k->r / 2 * SDL_sinf(k->ang)) * screen->h, k->r / 4 * screen->w, 0); -} - -static void -DrawScreen(SDL_Window *window) -{ - SDL_Surface *screen = SDL_GetWindowSurface(window); - int i; - - if (!screen) { - return; - } - - SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 75, 75, 75)); - - /* draw Touch History */ - for (i = eventWrite; i < eventWrite + EVENT_BUF_SIZE; ++i) { - const SDL_Event *event = &events[i & (EVENT_BUF_SIZE - 1)]; - const float age = (float)(i - eventWrite) / EVENT_BUF_SIZE; - float x, y; - unsigned int c, col; - - if ( (event->type == SDL_FINGERMOTION) || - (event->type == SDL_FINGERDOWN) || - (event->type == SDL_FINGERUP) ) { - x = event->tfinger.x; - y = event->tfinger.y; - - /* draw the touch: */ - c = colors[event->tfinger.fingerId % 7]; - col = ((unsigned int) (c * (0.1f + 0.85f))) | (unsigned int) (0xFF * age) << 24; - - if (event->type == SDL_FINGERMOTION) { - drawCircle(screen, x * screen->w, y * screen->h, 5, col); - } else if (event->type == SDL_FINGERDOWN) { - drawCircle(screen, x * screen->w, y * screen->h, -10, col); - } - } - } - - if (knob.p.x > 0) { - drawKnob(screen, &knob); - } - - SDL_UpdateWindowSurface(window); -} - -static void -loop(void) -{ - SDL_Event event; - SDL_RWops *stream; - int i; - - while (SDL_PollEvent(&event)) { - SDLTest_CommonEvent(state, &event, &quitting); - - /* Record _all_ events */ - events[eventWrite & (EVENT_BUF_SIZE-1)] = event; - eventWrite++; - - switch (event.type) { - case SDL_KEYDOWN: - switch (event.key.keysym.sym) { - case SDLK_i: { - for (i = 0; i < SDL_GetNumTouchDevices(); ++i) { - const SDL_TouchID id = SDL_GetTouchDevice(i); - SDL_Log("Fingers Down on device %"SDL_PRIs64": %d", id, SDL_GetNumTouchFingers(id)); - } - break; - } - - case SDLK_SPACE: - SDL_RecordGesture(-1); - break; - - case SDLK_s: - stream = SDL_RWFromFile("gestureSave", "w"); - SDL_Log("Wrote %i templates", SDL_SaveAllDollarTemplates(stream)); - SDL_RWclose(stream); - break; - - case SDLK_l: - stream = SDL_RWFromFile("gestureSave", "r"); - SDL_Log("Loaded: %i", SDL_LoadDollarTemplates(-1, stream)); - SDL_RWclose(stream); - break; - } - break; - -#if VERBOSE - case SDL_FINGERMOTION: - SDL_Log("Finger: %"SDL_PRIs64",x: %f, y: %f",event.tfinger.fingerId, - event.tfinger.x,event.tfinger.y); - break; - - case SDL_FINGERDOWN: - SDL_Log("Finger: %"SDL_PRIs64" down - x: %f, y: %f", - event.tfinger.fingerId,event.tfinger.x,event.tfinger.y); - break; - - case SDL_FINGERUP: - SDL_Log("Finger: %"SDL_PRIs64" up - x: %f, y: %f", - event.tfinger.fingerId,event.tfinger.x,event.tfinger.y); - break; -#endif - - case SDL_MULTIGESTURE: -#if VERBOSE - SDL_Log("Multi Gesture: x = %f, y = %f, dAng = %f, dR = %f", - event.mgesture.x, event.mgesture.y, - event.mgesture.dTheta, event.mgesture.dDist); - SDL_Log("MG: numDownTouch = %i",event.mgesture.numFingers); -#endif - - knob.p.x = event.mgesture.x; - knob.p.y = event.mgesture.y; - knob.ang += event.mgesture.dTheta; - knob.r += event.mgesture.dDist; - break; - - case SDL_DOLLARGESTURE: - SDL_Log("Gesture %"SDL_PRIs64" performed, error: %f", - event.dgesture.gestureId, event.dgesture.error); - break; - - case SDL_DOLLARRECORD: - SDL_Log("Recorded gesture: %"SDL_PRIs64"",event.dgesture.gestureId); - break; - } - } - - for (i = 0; i < state->num_windows; ++i) { - if (state->windows[i]) { - DrawScreen(state->windows[i]); - } - } - -#ifdef __EMSCRIPTEN__ - if (quitting) { - emscripten_cancel_main_loop(); - } -#endif -} - -int main(int argc, char* argv[]) -{ - state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO); - if (!state) { - return 1; - } - - state->window_title = "Gesture Test"; - state->window_w = WIDTH; - state->window_h = HEIGHT; - state->skip_renderer = SDL_TRUE; - - if (!SDLTest_CommonDefaultArgs(state, argc, argv) || !SDLTest_CommonInit(state)) { - SDLTest_CommonQuit(state); - return 1; - } - -#ifdef __EMSCRIPTEN__ - emscripten_set_main_loop(loop, 0, 1); -#else - while (!quitting) { - loop(); - } -#endif - - SDLTest_CommonQuit(state); - return 0; -} - diff --git a/SDL2-2.0.12/test/testgl2.c b/SDL2-2.0.12/test/testgl2.c deleted file mode 100644 index 894ff80..0000000 --- a/SDL2-2.0.12/test/testgl2.c +++ /dev/null @@ -1,440 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ -#include -#include -#include -#include - -#include "SDL_test_common.h" - -#ifdef __MACOS__ -#define HAVE_OPENGL -#endif - -#ifdef HAVE_OPENGL - -#include "SDL_opengl.h" - -typedef struct GL_Context -{ -#define SDL_PROC(ret,func,params) ret (APIENTRY *func) params; -#include "../src/render/opengl/SDL_glfuncs.h" -#undef SDL_PROC -} GL_Context; - - -/* Undefine this if you want a flat cube instead of a rainbow cube */ -#define SHADED_CUBE - -static SDLTest_CommonState *state; -static SDL_GLContext context; -static GL_Context ctx; - -static int LoadContext(GL_Context * data) -{ -#if SDL_VIDEO_DRIVER_UIKIT -#define __SDL_NOGETPROCADDR__ -#elif SDL_VIDEO_DRIVER_ANDROID -#define __SDL_NOGETPROCADDR__ -#elif SDL_VIDEO_DRIVER_PANDORA -#define __SDL_NOGETPROCADDR__ -#endif - -#if defined __SDL_NOGETPROCADDR__ -#define SDL_PROC(ret,func,params) data->func=func; -#else -#define SDL_PROC(ret,func,params) \ - do { \ - data->func = SDL_GL_GetProcAddress(#func); \ - if ( ! data->func ) { \ - return SDL_SetError("Couldn't load GL function %s: %s", #func, SDL_GetError()); \ - } \ - } while ( 0 ); -#endif /* __SDL_NOGETPROCADDR__ */ - -#include "../src/render/opengl/SDL_glfuncs.h" -#undef SDL_PROC - return 0; -} - - -/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ -static void -quit(int rc) -{ - if (context) { - /* SDL_GL_MakeCurrent(0, NULL); *//* doesn't do anything */ - SDL_GL_DeleteContext(context); - } - SDLTest_CommonQuit(state); - exit(rc); -} - -static void -Render() -{ - static float color[8][3] = { - {1.0, 1.0, 0.0}, - {1.0, 0.0, 0.0}, - {0.0, 0.0, 0.0}, - {0.0, 1.0, 0.0}, - {0.0, 1.0, 1.0}, - {1.0, 1.0, 1.0}, - {1.0, 0.0, 1.0}, - {0.0, 0.0, 1.0} - }; - static float cube[8][3] = { - {0.5, 0.5, -0.5}, - {0.5, -0.5, -0.5}, - {-0.5, -0.5, -0.5}, - {-0.5, 0.5, -0.5}, - {-0.5, 0.5, 0.5}, - {0.5, 0.5, 0.5}, - {0.5, -0.5, 0.5}, - {-0.5, -0.5, 0.5} - }; - - /* Do our drawing, too. */ - ctx.glClearColor(0.0, 0.0, 0.0, 1.0); - ctx.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - ctx.glBegin(GL_QUADS); - -#ifdef SHADED_CUBE - ctx.glColor3fv(color[0]); - ctx.glVertex3fv(cube[0]); - ctx.glColor3fv(color[1]); - ctx.glVertex3fv(cube[1]); - ctx.glColor3fv(color[2]); - ctx.glVertex3fv(cube[2]); - ctx.glColor3fv(color[3]); - ctx.glVertex3fv(cube[3]); - - ctx.glColor3fv(color[3]); - ctx.glVertex3fv(cube[3]); - ctx.glColor3fv(color[4]); - ctx.glVertex3fv(cube[4]); - ctx.glColor3fv(color[7]); - ctx.glVertex3fv(cube[7]); - ctx.glColor3fv(color[2]); - ctx.glVertex3fv(cube[2]); - - ctx.glColor3fv(color[0]); - ctx.glVertex3fv(cube[0]); - ctx.glColor3fv(color[5]); - ctx.glVertex3fv(cube[5]); - ctx.glColor3fv(color[6]); - ctx.glVertex3fv(cube[6]); - ctx.glColor3fv(color[1]); - ctx.glVertex3fv(cube[1]); - - ctx.glColor3fv(color[5]); - ctx.glVertex3fv(cube[5]); - ctx.glColor3fv(color[4]); - ctx.glVertex3fv(cube[4]); - ctx.glColor3fv(color[7]); - ctx.glVertex3fv(cube[7]); - ctx.glColor3fv(color[6]); - ctx.glVertex3fv(cube[6]); - - ctx.glColor3fv(color[5]); - ctx.glVertex3fv(cube[5]); - ctx.glColor3fv(color[0]); - ctx.glVertex3fv(cube[0]); - ctx.glColor3fv(color[3]); - ctx.glVertex3fv(cube[3]); - ctx.glColor3fv(color[4]); - ctx.glVertex3fv(cube[4]); - - ctx.glColor3fv(color[6]); - ctx.glVertex3fv(cube[6]); - ctx.glColor3fv(color[1]); - ctx.glVertex3fv(cube[1]); - ctx.glColor3fv(color[2]); - ctx.glVertex3fv(cube[2]); - ctx.glColor3fv(color[7]); - ctx.glVertex3fv(cube[7]); -#else /* flat cube */ - ctx.glColor3f(1.0, 0.0, 0.0); - ctx.glVertex3fv(cube[0]); - ctx.glVertex3fv(cube[1]); - ctx.glVertex3fv(cube[2]); - ctx.glVertex3fv(cube[3]); - - ctx.glColor3f(0.0, 1.0, 0.0); - ctx.glVertex3fv(cube[3]); - ctx.glVertex3fv(cube[4]); - ctx.glVertex3fv(cube[7]); - ctx.glVertex3fv(cube[2]); - - ctx.glColor3f(0.0, 0.0, 1.0); - ctx.glVertex3fv(cube[0]); - ctx.glVertex3fv(cube[5]); - ctx.glVertex3fv(cube[6]); - ctx.glVertex3fv(cube[1]); - - ctx.glColor3f(0.0, 1.0, 1.0); - ctx.glVertex3fv(cube[5]); - ctx.glVertex3fv(cube[4]); - ctx.glVertex3fv(cube[7]); - ctx.glVertex3fv(cube[6]); - - ctx.glColor3f(1.0, 1.0, 0.0); - ctx.glVertex3fv(cube[5]); - ctx.glVertex3fv(cube[0]); - ctx.glVertex3fv(cube[3]); - ctx.glVertex3fv(cube[4]); - - ctx.glColor3f(1.0, 0.0, 1.0); - ctx.glVertex3fv(cube[6]); - ctx.glVertex3fv(cube[1]); - ctx.glVertex3fv(cube[2]); - ctx.glVertex3fv(cube[7]); -#endif /* SHADED_CUBE */ - - ctx.glEnd(); - - ctx.glMatrixMode(GL_MODELVIEW); - ctx.glRotatef(5.0, 1.0, 1.0, 1.0); -} - -int -main(int argc, char *argv[]) -{ - int fsaa, accel; - int value; - int i, done; - SDL_DisplayMode mode; - SDL_Event event; - Uint32 then, now, frames; - int status; - int dw, dh; - int swap_interval = 0; - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - /* Initialize parameters */ - fsaa = 0; - accel = -1; - - /* Initialize test framework */ - state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO); - if (!state) { - return 1; - } - for (i = 1; i < argc;) { - int consumed; - - consumed = SDLTest_CommonArg(state, i); - if (consumed == 0) { - if (SDL_strcasecmp(argv[i], "--fsaa") == 0 && i+1 < argc) { - fsaa = atoi(argv[i+1]); - consumed = 2; - } else if (SDL_strcasecmp(argv[i], "--accel") == 0 && i+1 < argc) { - accel = atoi(argv[i+1]); - consumed = 2; - } else { - consumed = -1; - } - } - if (consumed < 0) { - static const char *options[] = { "[--fsaa n]", "[--accel n]", NULL }; - SDLTest_CommonLogUsage(state, argv[0], options); - quit(1); - } - i += consumed; - } - - /* Set OpenGL parameters */ - state->window_flags |= SDL_WINDOW_OPENGL; - state->gl_red_size = 5; - state->gl_green_size = 5; - state->gl_blue_size = 5; - state->gl_depth_size = 16; - state->gl_double_buffer = 1; - if (fsaa) { - state->gl_multisamplebuffers = 1; - state->gl_multisamplesamples = fsaa; - } - if (accel >= 0) { - state->gl_accelerated = accel; - } - - if (!SDLTest_CommonInit(state)) { - quit(2); - } - - /* Create OpenGL context */ - context = SDL_GL_CreateContext(state->windows[0]); - if (!context) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_GL_CreateContext(): %s\n", SDL_GetError()); - quit(2); - } - - /* Important: call this *after* creating the context */ - if (LoadContext(&ctx) < 0) { - SDL_Log("Could not load GL functions\n"); - quit(2); - return 0; - } - - if (state->render_flags & SDL_RENDERER_PRESENTVSYNC) { - /* try late-swap-tearing first. If not supported, try normal vsync. */ - if (SDL_GL_SetSwapInterval(-1) == 0) { - swap_interval = -1; - } else { - SDL_GL_SetSwapInterval(1); - swap_interval = 1; - } - } else { - SDL_GL_SetSwapInterval(0); /* disable vsync. */ - swap_interval = 0; - } - - SDL_GetCurrentDisplayMode(0, &mode); - SDL_Log("Screen BPP : %d\n", SDL_BITSPERPIXEL(mode.format)); - SDL_Log("Swap Interval : %d\n", SDL_GL_GetSwapInterval()); - SDL_GetWindowSize(state->windows[0], &dw, &dh); - SDL_Log("Window Size : %d,%d\n", dw, dh); - SDL_GL_GetDrawableSize(state->windows[0], &dw, &dh); - SDL_Log("Draw Size : %d,%d\n", dw, dh); - SDL_Log("\n"); - SDL_Log("Vendor : %s\n", ctx.glGetString(GL_VENDOR)); - SDL_Log("Renderer : %s\n", ctx.glGetString(GL_RENDERER)); - SDL_Log("Version : %s\n", ctx.glGetString(GL_VERSION)); - SDL_Log("Extensions : %s\n", ctx.glGetString(GL_EXTENSIONS)); - SDL_Log("\n"); - - status = SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &value); - if (!status) { - SDL_Log("SDL_GL_RED_SIZE: requested %d, got %d\n", 5, value); - } else { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_RED_SIZE: %s\n", SDL_GetError()); - } - status = SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &value); - if (!status) { - SDL_Log("SDL_GL_GREEN_SIZE: requested %d, got %d\n", 5, value); - } else { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_GREEN_SIZE: %s\n", SDL_GetError()); - } - status = SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &value); - if (!status) { - SDL_Log("SDL_GL_BLUE_SIZE: requested %d, got %d\n", 5, value); - } else { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_BLUE_SIZE: %s\n", SDL_GetError()); - } - status = SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &value); - if (!status) { - SDL_Log("SDL_GL_DEPTH_SIZE: requested %d, got %d\n", 16, value); - } else { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_DEPTH_SIZE: %s\n", SDL_GetError()); - } - if (fsaa) { - status = SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &value); - if (!status) { - SDL_Log("SDL_GL_MULTISAMPLEBUFFERS: requested 1, got %d\n", value); - } else { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_MULTISAMPLEBUFFERS: %s\n", - SDL_GetError()); - } - status = SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &value); - if (!status) { - SDL_Log("SDL_GL_MULTISAMPLESAMPLES: requested %d, got %d\n", fsaa, - value); - } else { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_MULTISAMPLESAMPLES: %s\n", - SDL_GetError()); - } - } - if (accel >= 0) { - status = SDL_GL_GetAttribute(SDL_GL_ACCELERATED_VISUAL, &value); - if (!status) { - SDL_Log("SDL_GL_ACCELERATED_VISUAL: requested %d, got %d\n", accel, - value); - } else { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_ACCELERATED_VISUAL: %s\n", - SDL_GetError()); - } - } - - /* Set rendering settings */ - ctx.glMatrixMode(GL_PROJECTION); - ctx.glLoadIdentity(); - ctx.glOrtho(-2.0, 2.0, -2.0, 2.0, -20.0, 20.0); - ctx.glMatrixMode(GL_MODELVIEW); - ctx.glLoadIdentity(); - ctx.glEnable(GL_DEPTH_TEST); - ctx.glDepthFunc(GL_LESS); - ctx.glShadeModel(GL_SMOOTH); - - /* Main render loop */ - frames = 0; - then = SDL_GetTicks(); - done = 0; - while (!done) { - SDL_bool update_swap_interval = SDL_FALSE; - - /* Check for events */ - ++frames; - while (SDL_PollEvent(&event)) { - SDLTest_CommonEvent(state, &event, &done); - if (event.type == SDL_KEYDOWN) { - if (event.key.keysym.sym == SDLK_o) { - swap_interval--; - update_swap_interval = SDL_TRUE; - } else if (event.key.keysym.sym == SDLK_p) { - swap_interval++; - update_swap_interval = SDL_TRUE; - } - } - } - - if (update_swap_interval) { - SDL_Log("Swap interval to be set to %d\n", swap_interval); - } - - for (i = 0; i < state->num_windows; ++i) { - int w, h; - if (state->windows[i] == NULL) - continue; - SDL_GL_MakeCurrent(state->windows[i], context); - if (update_swap_interval) { - SDL_GL_SetSwapInterval(swap_interval); - } - SDL_GL_GetDrawableSize(state->windows[i], &w, &h); - ctx.glViewport(0, 0, w, h); - Render(); - SDL_GL_SwapWindow(state->windows[i]); - } - } - - /* Print out some timing information */ - now = SDL_GetTicks(); - if (now > then) { - SDL_Log("%2.2f frames per second\n", - ((double) frames * 1000) / (now - then)); - } - quit(0); - return 0; -} - -#else /* HAVE_OPENGL */ - -int -main(int argc, char *argv[]) -{ - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "No OpenGL support on this system\n"); - return 1; -} - -#endif /* HAVE_OPENGL */ diff --git a/SDL2-2.0.12/test/testgles.c b/SDL2-2.0.12/test/testgles.c deleted file mode 100644 index 134b415..0000000 --- a/SDL2-2.0.12/test/testgles.c +++ /dev/null @@ -1,355 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ -#include -#include -#include -#include - -#include "SDL_test_common.h" - -#if defined(__IPHONEOS__) || defined(__ANDROID__) -#define HAVE_OPENGLES -#endif - -#ifdef HAVE_OPENGLES - -#include "SDL_opengles.h" - -static SDLTest_CommonState *state; -static SDL_GLContext *context = NULL; -static int depth = 16; - -/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ -static void -quit(int rc) -{ - int i; - - if (context != NULL) { - for (i = 0; i < state->num_windows; i++) { - if (context[i]) { - SDL_GL_DeleteContext(context[i]); - } - } - - SDL_free(context); - } - - SDLTest_CommonQuit(state); - exit(rc); -} - -static void -Render() -{ - static GLubyte color[8][4] = { {255, 0, 0, 0}, - {255, 0, 0, 255}, - {0, 255, 0, 255}, - {0, 255, 0, 255}, - {0, 255, 0, 255}, - {255, 255, 255, 255}, - {255, 0, 255, 255}, - {0, 0, 255, 255} - }; - static GLfloat cube[8][3] = { {0.5, 0.5, -0.5}, - {0.5f, -0.5f, -0.5f}, - {-0.5f, -0.5f, -0.5f}, - {-0.5f, 0.5f, -0.5f}, - {-0.5f, 0.5f, 0.5f}, - {0.5f, 0.5f, 0.5f}, - {0.5f, -0.5f, 0.5f}, - {-0.5f, -0.5f, 0.5f} - }; - static GLubyte indices[36] = { 0, 3, 4, - 4, 5, 0, - 0, 5, 6, - 6, 1, 0, - 6, 7, 2, - 2, 1, 6, - 7, 4, 3, - 3, 2, 7, - 5, 4, 7, - 7, 6, 5, - 2, 3, 1, - 3, 0, 1 - }; - - - /* Do our drawing, too. */ - glClearColor(0.0, 0.0, 0.0, 1.0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - /* Draw the cube */ - glColorPointer(4, GL_UNSIGNED_BYTE, 0, color); - glEnableClientState(GL_COLOR_ARRAY); - glVertexPointer(3, GL_FLOAT, 0, cube); - glEnableClientState(GL_VERTEX_ARRAY); - glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, indices); - - glMatrixMode(GL_MODELVIEW); - glRotatef(5.0, 1.0, 1.0, 1.0); -} - -int -main(int argc, char *argv[]) -{ - int fsaa, accel; - int value; - int i, done; - SDL_DisplayMode mode; - SDL_Event event; - Uint32 then, now, frames; - int status; - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - /* Initialize parameters */ - fsaa = 0; - accel = 0; - - /* Initialize test framework */ - state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO); - if (!state) { - return 1; - } - for (i = 1; i < argc;) { - int consumed; - - consumed = SDLTest_CommonArg(state, i); - if (consumed == 0) { - if (SDL_strcasecmp(argv[i], "--fsaa") == 0) { - ++fsaa; - consumed = 1; - } else if (SDL_strcasecmp(argv[i], "--accel") == 0) { - ++accel; - consumed = 1; - } else if (SDL_strcasecmp(argv[i], "--zdepth") == 0) { - i++; - if (!argv[i]) { - consumed = -1; - } else { - depth = SDL_atoi(argv[i]); - consumed = 1; - } - } else { - consumed = -1; - } - } - if (consumed < 0) { - static const char *options[] = { "[--fsaa]", "[--accel]", "[--zdepth %d]", NULL }; - SDLTest_CommonLogUsage(state, argv[0], options); - quit(1); - } - i += consumed; - } - - /* Set OpenGL parameters */ - state->window_flags |= SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_BORDERLESS; - state->gl_red_size = 5; - state->gl_green_size = 5; - state->gl_blue_size = 5; - state->gl_depth_size = depth; - state->gl_major_version = 1; - state->gl_minor_version = 1; - state->gl_profile_mask = SDL_GL_CONTEXT_PROFILE_ES; - if (fsaa) { - state->gl_multisamplebuffers=1; - state->gl_multisamplesamples=fsaa; - } - if (accel) { - state->gl_accelerated=1; - } - if (!SDLTest_CommonInit(state)) { - quit(2); - } - - context = (SDL_GLContext *)SDL_calloc(state->num_windows, sizeof(context)); - if (context == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Out of memory!\n"); - quit(2); - } - - /* Create OpenGL ES contexts */ - for (i = 0; i < state->num_windows; i++) { - context[i] = SDL_GL_CreateContext(state->windows[i]); - if (!context[i]) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_GL_CreateContext(): %s\n", SDL_GetError()); - quit(2); - } - } - - if (state->render_flags & SDL_RENDERER_PRESENTVSYNC) { - SDL_GL_SetSwapInterval(1); - } else { - SDL_GL_SetSwapInterval(0); - } - - SDL_GetCurrentDisplayMode(0, &mode); - SDL_Log("Screen bpp: %d\n", SDL_BITSPERPIXEL(mode.format)); - SDL_Log("\n"); - SDL_Log("Vendor : %s\n", glGetString(GL_VENDOR)); - SDL_Log("Renderer : %s\n", glGetString(GL_RENDERER)); - SDL_Log("Version : %s\n", glGetString(GL_VERSION)); - SDL_Log("Extensions : %s\n", glGetString(GL_EXTENSIONS)); - SDL_Log("\n"); - - status = SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &value); - if (!status) { - SDL_Log("SDL_GL_RED_SIZE: requested %d, got %d\n", 5, value); - } else { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_RED_SIZE: %s\n", - SDL_GetError()); - } - status = SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &value); - if (!status) { - SDL_Log("SDL_GL_GREEN_SIZE: requested %d, got %d\n", 5, value); - } else { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_GREEN_SIZE: %s\n", - SDL_GetError()); - } - status = SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &value); - if (!status) { - SDL_Log("SDL_GL_BLUE_SIZE: requested %d, got %d\n", 5, value); - } else { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_BLUE_SIZE: %s\n", - SDL_GetError()); - } - status = SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &value); - if (!status) { - SDL_Log("SDL_GL_DEPTH_SIZE: requested %d, got %d\n", depth, value); - } else { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_DEPTH_SIZE: %s\n", - SDL_GetError()); - } - if (fsaa) { - status = SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &value); - if (!status) { - SDL_Log("SDL_GL_MULTISAMPLEBUFFERS: requested 1, got %d\n", value); - } else { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_MULTISAMPLEBUFFERS: %s\n", - SDL_GetError()); - } - status = SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &value); - if (!status) { - SDL_Log("SDL_GL_MULTISAMPLESAMPLES: requested %d, got %d\n", fsaa, - value); - } else { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_MULTISAMPLESAMPLES: %s\n", - SDL_GetError()); - } - } - if (accel) { - status = SDL_GL_GetAttribute(SDL_GL_ACCELERATED_VISUAL, &value); - if (!status) { - SDL_Log("SDL_GL_ACCELERATED_VISUAL: requested 1, got %d\n", value); - } else { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to get SDL_GL_ACCELERATED_VISUAL: %s\n", - SDL_GetError()); - } - } - - /* Set rendering settings for each context */ - for (i = 0; i < state->num_windows; ++i) { - float aspectAdjust; - - status = SDL_GL_MakeCurrent(state->windows[i], context[i]); - if (status) { - SDL_Log("SDL_GL_MakeCurrent(): %s\n", SDL_GetError()); - - /* Continue for next window */ - continue; - } - - aspectAdjust = (4.0f / 3.0f) / ((float)state->window_w / state->window_h); - glViewport(0, 0, state->window_w, state->window_h); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrthof(-2.0, 2.0, -2.0 * aspectAdjust, 2.0 * aspectAdjust, -20.0, 20.0); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_LESS); - glShadeModel(GL_SMOOTH); - } - - /* Main render loop */ - frames = 0; - then = SDL_GetTicks(); - done = 0; - while (!done) { - /* Check for events */ - ++frames; - while (SDL_PollEvent(&event)) { - switch (event.type) { - case SDL_WINDOWEVENT: - switch (event.window.event) { - case SDL_WINDOWEVENT_RESIZED: - for (i = 0; i < state->num_windows; ++i) { - if (event.window.windowID == SDL_GetWindowID(state->windows[i])) { - status = SDL_GL_MakeCurrent(state->windows[i], context[i]); - if (status) { - SDL_Log("SDL_GL_MakeCurrent(): %s\n", SDL_GetError()); - break; - } - /* Change view port to the new window dimensions */ - glViewport(0, 0, event.window.data1, event.window.data2); - /* Update window content */ - Render(); - SDL_GL_SwapWindow(state->windows[i]); - break; - } - } - break; - } - } - SDLTest_CommonEvent(state, &event, &done); - } - for (i = 0; i < state->num_windows; ++i) { - if (state->windows[i] == NULL) - continue; - status = SDL_GL_MakeCurrent(state->windows[i], context[i]); - if (status) { - SDL_Log("SDL_GL_MakeCurrent(): %s\n", SDL_GetError()); - - /* Continue for next window */ - continue; - } - Render(); - SDL_GL_SwapWindow(state->windows[i]); - } - } - - /* Print out some timing information */ - now = SDL_GetTicks(); - if (now > then) { - SDL_Log("%2.2f frames per second\n", - ((double) frames * 1000) / (now - then)); - } -#if !defined(__ANDROID__) - quit(0); -#endif - return 0; -} - -#else /* HAVE_OPENGLES */ - -int -main(int argc, char *argv[]) -{ - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "No OpenGL ES support on this system\n"); - return 1; -} - -#endif /* HAVE_OPENGLES */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/test/testgles2.c b/SDL2-2.0.12/test/testgles2.c deleted file mode 100644 index 3946653..0000000 --- a/SDL2-2.0.12/test/testgles2.c +++ /dev/null @@ -1,732 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ -#include -#include -#include -#include - -#ifdef __EMSCRIPTEN__ -#include -#endif - -#include "SDL_test_common.h" - -#if defined(__IPHONEOS__) || defined(__ANDROID__) || defined(__EMSCRIPTEN__) || defined(__NACL__) \ - || defined(__WINDOWS__) || defined(__LINUX__) -#define HAVE_OPENGLES2 -#endif - -#ifdef HAVE_OPENGLES2 - -#include "SDL_opengles2.h" - -typedef struct GLES2_Context -{ -#define SDL_PROC(ret,func,params) ret (APIENTRY *func) params; -#include "../src/render/opengles2/SDL_gles2funcs.h" -#undef SDL_PROC -} GLES2_Context; - - -static SDLTest_CommonState *state; -static SDL_GLContext *context = NULL; -static int depth = 16; -static GLES2_Context ctx; - -static int LoadContext(GLES2_Context * data) -{ -#if SDL_VIDEO_DRIVER_UIKIT -#define __SDL_NOGETPROCADDR__ -#elif SDL_VIDEO_DRIVER_ANDROID -#define __SDL_NOGETPROCADDR__ -#elif SDL_VIDEO_DRIVER_PANDORA -#define __SDL_NOGETPROCADDR__ -#endif - -#if defined __SDL_NOGETPROCADDR__ -#define SDL_PROC(ret,func,params) data->func=func; -#else -#define SDL_PROC(ret,func,params) \ - do { \ - data->func = SDL_GL_GetProcAddress(#func); \ - if ( ! data->func ) { \ - return SDL_SetError("Couldn't load GLES2 function %s: %s", #func, SDL_GetError()); \ - } \ - } while ( 0 ); -#endif /* __SDL_NOGETPROCADDR__ */ - -#include "../src/render/opengles2/SDL_gles2funcs.h" -#undef SDL_PROC - return 0; -} - -/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ -static void -quit(int rc) -{ - int i; - - if (context != NULL) { - for (i = 0; i < state->num_windows; i++) { - if (context[i]) { - SDL_GL_DeleteContext(context[i]); - } - } - - SDL_free(context); - } - - SDLTest_CommonQuit(state); - exit(rc); -} - -#define GL_CHECK(x) \ - x; \ - { \ - GLenum glError = ctx.glGetError(); \ - if(glError != GL_NO_ERROR) { \ - SDL_Log("glGetError() = %i (0x%.8x) at line %i\n", glError, glError, __LINE__); \ - quit(1); \ - } \ - } - -/* - * Simulates desktop's glRotatef. The matrix is returned in column-major - * order. - */ -static void -rotate_matrix(float angle, float x, float y, float z, float *r) -{ - float radians, c, s, c1, u[3], length; - int i, j; - - radians = (float)(angle * M_PI) / 180.0f; - - c = SDL_cosf(radians); - s = SDL_sinf(radians); - - c1 = 1.0f - SDL_cosf(radians); - - length = (float)SDL_sqrt(x * x + y * y + z * z); - - u[0] = x / length; - u[1] = y / length; - u[2] = z / length; - - for (i = 0; i < 16; i++) { - r[i] = 0.0; - } - - r[15] = 1.0; - - for (i = 0; i < 3; i++) { - r[i * 4 + (i + 1) % 3] = u[(i + 2) % 3] * s; - r[i * 4 + (i + 2) % 3] = -u[(i + 1) % 3] * s; - } - - for (i = 0; i < 3; i++) { - for (j = 0; j < 3; j++) { - r[i * 4 + j] += c1 * u[i] * u[j] + (i == j ? c : 0.0f); - } - } -} - -/* - * Simulates gluPerspectiveMatrix - */ -static void -perspective_matrix(float fovy, float aspect, float znear, float zfar, float *r) -{ - int i; - float f; - - f = 1.0f/SDL_tanf(fovy * 0.5f); - - for (i = 0; i < 16; i++) { - r[i] = 0.0; - } - - r[0] = f / aspect; - r[5] = f; - r[10] = (znear + zfar) / (znear - zfar); - r[11] = -1.0f; - r[14] = (2.0f * znear * zfar) / (znear - zfar); - r[15] = 0.0f; -} - -/* - * Multiplies lhs by rhs and writes out to r. All matrices are 4x4 and column - * major. In-place multiplication is supported. - */ -static void -multiply_matrix(float *lhs, float *rhs, float *r) -{ - int i, j, k; - float tmp[16]; - - for (i = 0; i < 4; i++) { - for (j = 0; j < 4; j++) { - tmp[j * 4 + i] = 0.0; - - for (k = 0; k < 4; k++) { - tmp[j * 4 + i] += lhs[k * 4 + i] * rhs[j * 4 + k]; - } - } - } - - for (i = 0; i < 16; i++) { - r[i] = tmp[i]; - } -} - -/* - * Create shader, load in source, compile, dump debug as necessary. - * - * shader: Pointer to return created shader ID. - * source: Passed-in shader source code. - * shader_type: Passed to GL, e.g. GL_VERTEX_SHADER. - */ -void -process_shader(GLuint *shader, const char * source, GLint shader_type) -{ - GLint status = GL_FALSE; - const char *shaders[1] = { NULL }; - char buffer[1024]; - GLsizei length; - - /* Create shader and load into GL. */ - *shader = GL_CHECK(ctx.glCreateShader(shader_type)); - - shaders[0] = source; - - GL_CHECK(ctx.glShaderSource(*shader, 1, shaders, NULL)); - - /* Clean up shader source. */ - shaders[0] = NULL; - - /* Try compiling the shader. */ - GL_CHECK(ctx.glCompileShader(*shader)); - GL_CHECK(ctx.glGetShaderiv(*shader, GL_COMPILE_STATUS, &status)); - - /* Dump debug info (source and log) if compilation failed. */ - if(status != GL_TRUE) { - ctx.glGetProgramInfoLog(*shader, sizeof(buffer), &length, &buffer[0]); - buffer[length] = '\0'; - SDL_Log("Shader compilation failed: %s", buffer);fflush(stderr); - quit(-1); - } -} - -/* 3D data. Vertex range -0.5..0.5 in all axes. -* Z -0.5 is near, 0.5 is far. */ -const float _vertices[] = -{ - /* Front face. */ - /* Bottom left */ - -0.5, 0.5, -0.5, - 0.5, -0.5, -0.5, - -0.5, -0.5, -0.5, - /* Top right */ - -0.5, 0.5, -0.5, - 0.5, 0.5, -0.5, - 0.5, -0.5, -0.5, - /* Left face */ - /* Bottom left */ - -0.5, 0.5, 0.5, - -0.5, -0.5, -0.5, - -0.5, -0.5, 0.5, - /* Top right */ - -0.5, 0.5, 0.5, - -0.5, 0.5, -0.5, - -0.5, -0.5, -0.5, - /* Top face */ - /* Bottom left */ - -0.5, 0.5, 0.5, - 0.5, 0.5, -0.5, - -0.5, 0.5, -0.5, - /* Top right */ - -0.5, 0.5, 0.5, - 0.5, 0.5, 0.5, - 0.5, 0.5, -0.5, - /* Right face */ - /* Bottom left */ - 0.5, 0.5, -0.5, - 0.5, -0.5, 0.5, - 0.5, -0.5, -0.5, - /* Top right */ - 0.5, 0.5, -0.5, - 0.5, 0.5, 0.5, - 0.5, -0.5, 0.5, - /* Back face */ - /* Bottom left */ - 0.5, 0.5, 0.5, - -0.5, -0.5, 0.5, - 0.5, -0.5, 0.5, - /* Top right */ - 0.5, 0.5, 0.5, - -0.5, 0.5, 0.5, - -0.5, -0.5, 0.5, - /* Bottom face */ - /* Bottom left */ - -0.5, -0.5, -0.5, - 0.5, -0.5, 0.5, - -0.5, -0.5, 0.5, - /* Top right */ - -0.5, -0.5, -0.5, - 0.5, -0.5, -0.5, - 0.5, -0.5, 0.5, -}; - -const float _colors[] = -{ - /* Front face */ - /* Bottom left */ - 1.0, 0.0, 0.0, /* red */ - 0.0, 0.0, 1.0, /* blue */ - 0.0, 1.0, 0.0, /* green */ - /* Top right */ - 1.0, 0.0, 0.0, /* red */ - 1.0, 1.0, 0.0, /* yellow */ - 0.0, 0.0, 1.0, /* blue */ - /* Left face */ - /* Bottom left */ - 1.0, 1.0, 1.0, /* white */ - 0.0, 1.0, 0.0, /* green */ - 0.0, 1.0, 1.0, /* cyan */ - /* Top right */ - 1.0, 1.0, 1.0, /* white */ - 1.0, 0.0, 0.0, /* red */ - 0.0, 1.0, 0.0, /* green */ - /* Top face */ - /* Bottom left */ - 1.0, 1.0, 1.0, /* white */ - 1.0, 1.0, 0.0, /* yellow */ - 1.0, 0.0, 0.0, /* red */ - /* Top right */ - 1.0, 1.0, 1.0, /* white */ - 0.0, 0.0, 0.0, /* black */ - 1.0, 1.0, 0.0, /* yellow */ - /* Right face */ - /* Bottom left */ - 1.0, 1.0, 0.0, /* yellow */ - 1.0, 0.0, 1.0, /* magenta */ - 0.0, 0.0, 1.0, /* blue */ - /* Top right */ - 1.0, 1.0, 0.0, /* yellow */ - 0.0, 0.0, 0.0, /* black */ - 1.0, 0.0, 1.0, /* magenta */ - /* Back face */ - /* Bottom left */ - 0.0, 0.0, 0.0, /* black */ - 0.0, 1.0, 1.0, /* cyan */ - 1.0, 0.0, 1.0, /* magenta */ - /* Top right */ - 0.0, 0.0, 0.0, /* black */ - 1.0, 1.0, 1.0, /* white */ - 0.0, 1.0, 1.0, /* cyan */ - /* Bottom face */ - /* Bottom left */ - 0.0, 1.0, 0.0, /* green */ - 1.0, 0.0, 1.0, /* magenta */ - 0.0, 1.0, 1.0, /* cyan */ - /* Top right */ - 0.0, 1.0, 0.0, /* green */ - 0.0, 0.0, 1.0, /* blue */ - 1.0, 0.0, 1.0, /* magenta */ -}; - -const char* _shader_vert_src = -" attribute vec4 av4position; " -" attribute vec3 av3color; " -" uniform mat4 mvp; " -" varying vec3 vv3color; " -" void main() { " -" vv3color = av3color; " -" gl_Position = mvp * av4position; " -" } "; - -const char* _shader_frag_src = -" precision lowp float; " -" varying vec3 vv3color; " -" void main() { " -" gl_FragColor = vec4(vv3color, 1.0); " -" } "; - -typedef struct shader_data -{ - GLuint shader_program, shader_frag, shader_vert; - - GLint attr_position; - GLint attr_color, attr_mvp; - - int angle_x, angle_y, angle_z; - -} shader_data; - -static void -Render(unsigned int width, unsigned int height, shader_data* data) -{ - float matrix_rotate[16], matrix_modelview[16], matrix_perspective[16], matrix_mvp[16]; - - /* - * Do some rotation with Euler angles. It is not a fixed axis as - * quaterions would be, but the effect is cool. - */ - rotate_matrix((float)data->angle_x, 1.0f, 0.0f, 0.0f, matrix_modelview); - rotate_matrix((float)data->angle_y, 0.0f, 1.0f, 0.0f, matrix_rotate); - - multiply_matrix(matrix_rotate, matrix_modelview, matrix_modelview); - - rotate_matrix((float)data->angle_z, 0.0f, 1.0f, 0.0f, matrix_rotate); - - multiply_matrix(matrix_rotate, matrix_modelview, matrix_modelview); - - /* Pull the camera back from the cube */ - matrix_modelview[14] -= 2.5; - - perspective_matrix(45.0f, (float)width/height, 0.01f, 100.0f, matrix_perspective); - multiply_matrix(matrix_perspective, matrix_modelview, matrix_mvp); - - GL_CHECK(ctx.glUniformMatrix4fv(data->attr_mvp, 1, GL_FALSE, matrix_mvp)); - - data->angle_x += 3; - data->angle_y += 2; - data->angle_z += 1; - - if(data->angle_x >= 360) data->angle_x -= 360; - if(data->angle_x < 0) data->angle_x += 360; - if(data->angle_y >= 360) data->angle_y -= 360; - if(data->angle_y < 0) data->angle_y += 360; - if(data->angle_z >= 360) data->angle_z -= 360; - if(data->angle_z < 0) data->angle_z += 360; - - GL_CHECK(ctx.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)); - GL_CHECK(ctx.glDrawArrays(GL_TRIANGLES, 0, 36)); -} - -int done; -Uint32 frames; -shader_data *datas; - -void loop() -{ - SDL_Event event; - int i; - int status; - - /* Check for events */ - ++frames; - while (SDL_PollEvent(&event) && !done) { - switch (event.type) { - case SDL_WINDOWEVENT: - switch (event.window.event) { - case SDL_WINDOWEVENT_RESIZED: - for (i = 0; i < state->num_windows; ++i) { - if (event.window.windowID == SDL_GetWindowID(state->windows[i])) { - int w, h; - status = SDL_GL_MakeCurrent(state->windows[i], context[i]); - if (status) { - SDL_Log("SDL_GL_MakeCurrent(): %s\n", SDL_GetError()); - break; - } - /* Change view port to the new window dimensions */ - SDL_GL_GetDrawableSize(state->windows[i], &w, &h); - ctx.glViewport(0, 0, w, h); - state->window_w = event.window.data1; - state->window_h = event.window.data2; - /* Update window content */ - Render(event.window.data1, event.window.data2, &datas[i]); - SDL_GL_SwapWindow(state->windows[i]); - break; - } - } - break; - } - } - SDLTest_CommonEvent(state, &event, &done); - } - if (!done) { - for (i = 0; i < state->num_windows; ++i) { - status = SDL_GL_MakeCurrent(state->windows[i], context[i]); - if (status) { - SDL_Log("SDL_GL_MakeCurrent(): %s\n", SDL_GetError()); - - /* Continue for next window */ - continue; - } - Render(state->window_w, state->window_h, &datas[i]); - SDL_GL_SwapWindow(state->windows[i]); - } - } -#ifdef __EMSCRIPTEN__ - else { - emscripten_cancel_main_loop(); - } -#endif -} - -int -main(int argc, char *argv[]) -{ - int fsaa, accel; - int value; - int i; - SDL_DisplayMode mode; - Uint32 then, now; - int status; - shader_data *data; - - /* Initialize parameters */ - fsaa = 0; - accel = 0; - - /* Initialize test framework */ - state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO); - if (!state) { - return 1; - } - for (i = 1; i < argc;) { - int consumed; - - consumed = SDLTest_CommonArg(state, i); - if (consumed == 0) { - if (SDL_strcasecmp(argv[i], "--fsaa") == 0) { - ++fsaa; - consumed = 1; - } else if (SDL_strcasecmp(argv[i], "--accel") == 0) { - ++accel; - consumed = 1; - } else if (SDL_strcasecmp(argv[i], "--zdepth") == 0) { - i++; - if (!argv[i]) { - consumed = -1; - } else { - depth = SDL_atoi(argv[i]); - consumed = 1; - } - } else { - consumed = -1; - } - } - if (consumed < 0) { - static const char *options[] = { "[--fsaa]", "[--accel]", "[--zdepth %d]", NULL }; - SDLTest_CommonLogUsage(state, argv[0], options); - quit(1); - } - i += consumed; - } - - /* Set OpenGL parameters */ - state->window_flags |= SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_BORDERLESS; - state->gl_red_size = 5; - state->gl_green_size = 5; - state->gl_blue_size = 5; - state->gl_depth_size = depth; - state->gl_major_version = 2; - state->gl_minor_version = 0; - state->gl_profile_mask = SDL_GL_CONTEXT_PROFILE_ES; - - if (fsaa) { - state->gl_multisamplebuffers=1; - state->gl_multisamplesamples=fsaa; - } - if (accel) { - state->gl_accelerated=1; - } - if (!SDLTest_CommonInit(state)) { - quit(2); - return 0; - } - - context = (SDL_GLContext *)SDL_calloc(state->num_windows, sizeof(context)); - if (context == NULL) { - SDL_Log("Out of memory!\n"); - quit(2); - } - - /* Create OpenGL ES contexts */ - for (i = 0; i < state->num_windows; i++) { - context[i] = SDL_GL_CreateContext(state->windows[i]); - if (!context[i]) { - SDL_Log("SDL_GL_CreateContext(): %s\n", SDL_GetError()); - quit(2); - } - } - - /* Important: call this *after* creating the context */ - if (LoadContext(&ctx) < 0) { - SDL_Log("Could not load GLES2 functions\n"); - quit(2); - return 0; - } - - - - if (state->render_flags & SDL_RENDERER_PRESENTVSYNC) { - SDL_GL_SetSwapInterval(1); - } else { - SDL_GL_SetSwapInterval(0); - } - - SDL_GetCurrentDisplayMode(0, &mode); - SDL_Log("Screen bpp: %d\n", SDL_BITSPERPIXEL(mode.format)); - SDL_Log("\n"); - SDL_Log("Vendor : %s\n", ctx.glGetString(GL_VENDOR)); - SDL_Log("Renderer : %s\n", ctx.glGetString(GL_RENDERER)); - SDL_Log("Version : %s\n", ctx.glGetString(GL_VERSION)); - SDL_Log("Extensions : %s\n", ctx.glGetString(GL_EXTENSIONS)); - SDL_Log("\n"); - - status = SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &value); - if (!status) { - SDL_Log("SDL_GL_RED_SIZE: requested %d, got %d\n", 5, value); - } else { - SDL_Log( "Failed to get SDL_GL_RED_SIZE: %s\n", - SDL_GetError()); - } - status = SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &value); - if (!status) { - SDL_Log("SDL_GL_GREEN_SIZE: requested %d, got %d\n", 5, value); - } else { - SDL_Log( "Failed to get SDL_GL_GREEN_SIZE: %s\n", - SDL_GetError()); - } - status = SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &value); - if (!status) { - SDL_Log("SDL_GL_BLUE_SIZE: requested %d, got %d\n", 5, value); - } else { - SDL_Log( "Failed to get SDL_GL_BLUE_SIZE: %s\n", - SDL_GetError()); - } - status = SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &value); - if (!status) { - SDL_Log("SDL_GL_DEPTH_SIZE: requested %d, got %d\n", depth, value); - } else { - SDL_Log( "Failed to get SDL_GL_DEPTH_SIZE: %s\n", - SDL_GetError()); - } - if (fsaa) { - status = SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &value); - if (!status) { - SDL_Log("SDL_GL_MULTISAMPLEBUFFERS: requested 1, got %d\n", value); - } else { - SDL_Log( "Failed to get SDL_GL_MULTISAMPLEBUFFERS: %s\n", - SDL_GetError()); - } - status = SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &value); - if (!status) { - SDL_Log("SDL_GL_MULTISAMPLESAMPLES: requested %d, got %d\n", fsaa, - value); - } else { - SDL_Log( "Failed to get SDL_GL_MULTISAMPLESAMPLES: %s\n", - SDL_GetError()); - } - } - if (accel) { - status = SDL_GL_GetAttribute(SDL_GL_ACCELERATED_VISUAL, &value); - if (!status) { - SDL_Log("SDL_GL_ACCELERATED_VISUAL: requested 1, got %d\n", value); - } else { - SDL_Log( "Failed to get SDL_GL_ACCELERATED_VISUAL: %s\n", - SDL_GetError()); - } - } - - datas = (shader_data *)SDL_calloc(state->num_windows, sizeof(shader_data)); - - /* Set rendering settings for each context */ - for (i = 0; i < state->num_windows; ++i) { - - int w, h; - status = SDL_GL_MakeCurrent(state->windows[i], context[i]); - if (status) { - SDL_Log("SDL_GL_MakeCurrent(): %s\n", SDL_GetError()); - - /* Continue for next window */ - continue; - } - SDL_GL_GetDrawableSize(state->windows[i], &w, &h); - ctx.glViewport(0, 0, w, h); - - data = &datas[i]; - data->angle_x = 0; data->angle_y = 0; data->angle_z = 0; - - /* Shader Initialization */ - process_shader(&data->shader_vert, _shader_vert_src, GL_VERTEX_SHADER); - process_shader(&data->shader_frag, _shader_frag_src, GL_FRAGMENT_SHADER); - - /* Create shader_program (ready to attach shaders) */ - data->shader_program = GL_CHECK(ctx.glCreateProgram()); - - /* Attach shaders and link shader_program */ - GL_CHECK(ctx.glAttachShader(data->shader_program, data->shader_vert)); - GL_CHECK(ctx.glAttachShader(data->shader_program, data->shader_frag)); - GL_CHECK(ctx.glLinkProgram(data->shader_program)); - - /* Get attribute locations of non-fixed attributes like color and texture coordinates. */ - data->attr_position = GL_CHECK(ctx.glGetAttribLocation(data->shader_program, "av4position")); - data->attr_color = GL_CHECK(ctx.glGetAttribLocation(data->shader_program, "av3color")); - - /* Get uniform locations */ - data->attr_mvp = GL_CHECK(ctx.glGetUniformLocation(data->shader_program, "mvp")); - - GL_CHECK(ctx.glUseProgram(data->shader_program)); - - /* Enable attributes for position, color and texture coordinates etc. */ - GL_CHECK(ctx.glEnableVertexAttribArray(data->attr_position)); - GL_CHECK(ctx.glEnableVertexAttribArray(data->attr_color)); - - /* Populate attributes for position, color and texture coordinates etc. */ - GL_CHECK(ctx.glVertexAttribPointer(data->attr_position, 3, GL_FLOAT, GL_FALSE, 0, _vertices)); - GL_CHECK(ctx.glVertexAttribPointer(data->attr_color, 3, GL_FLOAT, GL_FALSE, 0, _colors)); - - GL_CHECK(ctx.glEnable(GL_CULL_FACE)); - GL_CHECK(ctx.glEnable(GL_DEPTH_TEST)); - } - - /* Main render loop */ - frames = 0; - then = SDL_GetTicks(); - done = 0; - -#ifdef __EMSCRIPTEN__ - emscripten_set_main_loop(loop, 0, 1); -#else - while (!done) { - loop(); - } -#endif - - /* Print out some timing information */ - now = SDL_GetTicks(); - if (now > then) { - SDL_Log("%2.2f frames per second\n", - ((double) frames * 1000) / (now - then)); - } -#if !defined(__ANDROID__) && !defined(__NACL__) - quit(0); -#endif - return 0; -} - -#else /* HAVE_OPENGLES2 */ - -int -main(int argc, char *argv[]) -{ - SDL_Log("No OpenGL ES support on this system\n"); - return 1; -} - -#endif /* HAVE_OPENGLES2 */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/test/testhaptic.c b/SDL2-2.0.12/test/testhaptic.c deleted file mode 100644 index 9613629..0000000 --- a/SDL2-2.0.12/test/testhaptic.c +++ /dev/null @@ -1,369 +0,0 @@ -/* -Copyright (c) 2008, Edgar Simo Serra -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of the Simple Directmedia Layer (SDL) nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* - * includes - */ -#include -#include /* strstr */ -#include /* isdigit */ - -#include "SDL.h" - -#ifndef SDL_HAPTIC_DISABLED - -static SDL_Haptic *haptic; - - -/* - * prototypes - */ -static void abort_execution(void); -static void HapticPrintSupported(SDL_Haptic * haptic); - - -/** - * @brief The entry point of this force feedback demo. - * @param[in] argc Number of arguments. - * @param[in] argv Array of argc arguments. - */ -int -main(int argc, char **argv) -{ - int i; - char *name; - int index; - SDL_HapticEffect efx[9]; - int id[9]; - int nefx; - unsigned int supported; - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - name = NULL; - index = -1; - if (argc > 1) { - name = argv[1]; - if ((strcmp(name, "--help") == 0) || (strcmp(name, "-h") == 0)) { - SDL_Log("USAGE: %s [device]\n" - "If device is a two-digit number it'll use it as an index, otherwise\n" - "it'll use it as if it were part of the device's name.\n", - argv[0]); - return 0; - } - - i = strlen(name); - if ((i < 3) && isdigit(name[0]) && ((i == 1) || isdigit(name[1]))) { - index = atoi(name); - name = NULL; - } - } - - /* Initialize the force feedbackness */ - SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_JOYSTICK | - SDL_INIT_HAPTIC); - SDL_Log("%d Haptic devices detected.\n", SDL_NumHaptics()); - if (SDL_NumHaptics() > 0) { - /* We'll just use index or the first force feedback device found */ - if (name == NULL) { - i = (index != -1) ? index : 0; - } - /* Try to find matching device */ - else { - for (i = 0; i < SDL_NumHaptics(); i++) { - if (strstr(SDL_HapticName(i), name) != NULL) - break; - } - - if (i >= SDL_NumHaptics()) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to find device matching '%s', aborting.\n", - name); - return 1; - } - } - - haptic = SDL_HapticOpen(i); - if (haptic == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to create the haptic device: %s\n", - SDL_GetError()); - return 1; - } - SDL_Log("Device: %s\n", SDL_HapticName(i)); - HapticPrintSupported(haptic); - } else { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "No Haptic devices found!\n"); - return 1; - } - - /* We only want force feedback errors. */ - SDL_ClearError(); - - /* Create effects. */ - memset(&efx, 0, sizeof(efx)); - nefx = 0; - supported = SDL_HapticQuery(haptic); - - SDL_Log("\nUploading effects\n"); - /* First we'll try a SINE effect. */ - if (supported & SDL_HAPTIC_SINE) { - SDL_Log(" effect %d: Sine Wave\n", nefx); - efx[nefx].type = SDL_HAPTIC_SINE; - efx[nefx].periodic.period = 1000; - efx[nefx].periodic.magnitude = -0x2000; /* Negative magnitude and ... */ - efx[nefx].periodic.phase = 18000; /* ... 180 degrees phase shift => cancel eachother */ - efx[nefx].periodic.length = 5000; - efx[nefx].periodic.attack_length = 1000; - efx[nefx].periodic.fade_length = 1000; - id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]); - if (id[nefx] < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError()); - abort_execution(); - } - nefx++; - } - /* Now we'll try a SAWTOOTHUP */ - if (supported & SDL_HAPTIC_SAWTOOTHUP) { - SDL_Log(" effect %d: Sawtooth Up\n", nefx); - efx[nefx].type = SDL_HAPTIC_SAWTOOTHUP; - efx[nefx].periodic.period = 500; - efx[nefx].periodic.magnitude = 0x5000; - efx[nefx].periodic.length = 5000; - efx[nefx].periodic.attack_length = 1000; - efx[nefx].periodic.fade_length = 1000; - id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]); - if (id[nefx] < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError()); - abort_execution(); - } - nefx++; - } - - /* Now the classical constant effect. */ - if (supported & SDL_HAPTIC_CONSTANT) { - SDL_Log(" effect %d: Constant Force\n", nefx); - efx[nefx].type = SDL_HAPTIC_CONSTANT; - efx[nefx].constant.direction.type = SDL_HAPTIC_POLAR; - efx[nefx].constant.direction.dir[0] = 20000; /* Force comes from the south-west. */ - efx[nefx].constant.length = 5000; - efx[nefx].constant.level = 0x6000; - efx[nefx].constant.attack_length = 1000; - efx[nefx].constant.fade_length = 1000; - id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]); - if (id[nefx] < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError()); - abort_execution(); - } - nefx++; - } - - /* The cute spring effect. */ - if (supported & SDL_HAPTIC_SPRING) { - SDL_Log(" effect %d: Condition Spring\n", nefx); - efx[nefx].type = SDL_HAPTIC_SPRING; - efx[nefx].condition.length = 5000; - for (i = 0; i < SDL_HapticNumAxes(haptic); i++) { - efx[nefx].condition.right_sat[i] = 0xFFFF; - efx[nefx].condition.left_sat[i] = 0xFFFF; - efx[nefx].condition.right_coeff[i] = 0x2000; - efx[nefx].condition.left_coeff[i] = 0x2000; - efx[nefx].condition.center[i] = 0x1000; /* Displace the center for it to move. */ - } - id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]); - if (id[nefx] < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError()); - abort_execution(); - } - nefx++; - } - /* The interesting damper effect. */ - if (supported & SDL_HAPTIC_DAMPER) { - SDL_Log(" effect %d: Condition Damper\n", nefx); - efx[nefx].type = SDL_HAPTIC_DAMPER; - efx[nefx].condition.length = 5000; - for (i = 0; i < SDL_HapticNumAxes(haptic); i++) { - efx[nefx].condition.right_sat[i] = 0xFFFF; - efx[nefx].condition.left_sat[i] = 0xFFFF; - efx[nefx].condition.right_coeff[i] = 0x2000; - efx[nefx].condition.left_coeff[i] = 0x2000; - } - id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]); - if (id[nefx] < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError()); - abort_execution(); - } - nefx++; - } - /* The pretty awesome inertia effect. */ - if (supported & SDL_HAPTIC_INERTIA) { - SDL_Log(" effect %d: Condition Inertia\n", nefx); - efx[nefx].type = SDL_HAPTIC_INERTIA; - efx[nefx].condition.length = 5000; - for (i = 0; i < SDL_HapticNumAxes(haptic); i++) { - efx[nefx].condition.right_sat[i] = 0xFFFF; - efx[nefx].condition.left_sat[i] = 0xFFFF; - efx[nefx].condition.right_coeff[i] = 0x2000; - efx[nefx].condition.left_coeff[i] = 0x2000; - efx[nefx].condition.deadband[i] = 0x1000; /* 1/16th of axis-range around the center is 'dead'. */ - } - id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]); - if (id[nefx] < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError()); - abort_execution(); - } - nefx++; - } - /* The hot friction effect. */ - if (supported & SDL_HAPTIC_FRICTION) { - SDL_Log(" effect %d: Condition Friction\n", nefx); - efx[nefx].type = SDL_HAPTIC_FRICTION; - efx[nefx].condition.length = 5000; - for (i = 0; i < SDL_HapticNumAxes(haptic); i++) { - efx[nefx].condition.right_sat[i] = 0xFFFF; - efx[nefx].condition.left_sat[i] = 0xFFFF; - efx[nefx].condition.right_coeff[i] = 0x2000; - efx[nefx].condition.left_coeff[i] = 0x2000; - } - id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]); - if (id[nefx] < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError()); - abort_execution(); - } - nefx++; - } - - /* Now we'll try a ramp effect */ - if (supported & SDL_HAPTIC_RAMP) { - SDL_Log(" effect %d: Ramp\n", nefx); - efx[nefx].type = SDL_HAPTIC_RAMP; - efx[nefx].ramp.direction.type = SDL_HAPTIC_CARTESIAN; - efx[nefx].ramp.direction.dir[0] = 1; /* Force comes from */ - efx[nefx].ramp.direction.dir[1] = -1; /* the north-east. */ - efx[nefx].ramp.length = 5000; - efx[nefx].ramp.start = 0x4000; - efx[nefx].ramp.end = -0x4000; - efx[nefx].ramp.attack_length = 1000; - efx[nefx].ramp.fade_length = 1000; - id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]); - if (id[nefx] < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError()); - abort_execution(); - } - nefx++; - } - - /* Finally we'll try a left/right effect. */ - if (supported & SDL_HAPTIC_LEFTRIGHT) { - SDL_Log(" effect %d: Left/Right\n", nefx); - efx[nefx].type = SDL_HAPTIC_LEFTRIGHT; - efx[nefx].leftright.length = 5000; - efx[nefx].leftright.large_magnitude = 0x3000; - efx[nefx].leftright.small_magnitude = 0xFFFF; - id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]); - if (id[nefx] < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError()); - abort_execution(); - } - nefx++; - } - - - SDL_Log - ("\nNow playing effects for 5 seconds each with 1 second delay between\n"); - for (i = 0; i < nefx; i++) { - SDL_Log(" Playing effect %d\n", i); - SDL_HapticRunEffect(haptic, id[i], 1); - SDL_Delay(6000); /* Effects only have length 5000 */ - } - - /* Quit */ - if (haptic != NULL) - SDL_HapticClose(haptic); - SDL_Quit(); - - return 0; -} - - -/* - * Cleans up a bit. - */ -static void -abort_execution(void) -{ - SDL_Log("\nAborting program execution.\n"); - - SDL_HapticClose(haptic); - SDL_Quit(); - - exit(1); -} - - -/* - * Displays information about the haptic device. - */ -static void -HapticPrintSupported(SDL_Haptic * haptic) -{ - unsigned int supported; - - supported = SDL_HapticQuery(haptic); - SDL_Log(" Supported effects [%d effects, %d playing]:\n", - SDL_HapticNumEffects(haptic), SDL_HapticNumEffectsPlaying(haptic)); - if (supported & SDL_HAPTIC_CONSTANT) - SDL_Log(" constant\n"); - if (supported & SDL_HAPTIC_SINE) - SDL_Log(" sine\n"); - /* !!! FIXME: put this back when we have more bits in 2.1 */ - /* if (supported & SDL_HAPTIC_SQUARE) - SDL_Log(" square\n"); */ - if (supported & SDL_HAPTIC_TRIANGLE) - SDL_Log(" triangle\n"); - if (supported & SDL_HAPTIC_SAWTOOTHUP) - SDL_Log(" sawtoothup\n"); - if (supported & SDL_HAPTIC_SAWTOOTHDOWN) - SDL_Log(" sawtoothdown\n"); - if (supported & SDL_HAPTIC_RAMP) - SDL_Log(" ramp\n"); - if (supported & SDL_HAPTIC_FRICTION) - SDL_Log(" friction\n"); - if (supported & SDL_HAPTIC_SPRING) - SDL_Log(" spring\n"); - if (supported & SDL_HAPTIC_DAMPER) - SDL_Log(" damper\n"); - if (supported & SDL_HAPTIC_INERTIA) - SDL_Log(" inertia\n"); - if (supported & SDL_HAPTIC_CUSTOM) - SDL_Log(" custom\n"); - if (supported & SDL_HAPTIC_LEFTRIGHT) - SDL_Log(" left/right\n"); - SDL_Log(" Supported capabilities:\n"); - if (supported & SDL_HAPTIC_GAIN) - SDL_Log(" gain\n"); - if (supported & SDL_HAPTIC_AUTOCENTER) - SDL_Log(" autocenter\n"); - if (supported & SDL_HAPTIC_STATUS) - SDL_Log(" status\n"); -} - -#else - -int -main(int argc, char *argv[]) -{ - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL compiled without Haptic support.\n"); - return 1; -} - -#endif diff --git a/SDL2-2.0.12/test/testhittesting.c b/SDL2-2.0.12/test/testhittesting.c deleted file mode 100644 index c5223a9..0000000 --- a/SDL2-2.0.12/test/testhittesting.c +++ /dev/null @@ -1,134 +0,0 @@ -#include -#include "SDL.h" - -/* !!! FIXME: rewrite this to be wired in to test framework. */ - -#define RESIZE_BORDER 20 - -const SDL_Rect drag_areas[] = { - { 20, 20, 100, 100 }, - { 200, 70, 100, 100 }, - { 400, 90, 100, 100 } -}; - -static const SDL_Rect *areas = drag_areas; -static int numareas = SDL_arraysize(drag_areas); - -static SDL_HitTestResult SDLCALL -hitTest(SDL_Window *window, const SDL_Point *pt, void *data) -{ - int i; - int w, h; - - for (i = 0; i < numareas; i++) { - if (SDL_PointInRect(pt, &areas[i])) { - SDL_Log("HIT-TEST: DRAGGABLE\n"); - return SDL_HITTEST_DRAGGABLE; - } - } - - SDL_GetWindowSize(window, &w, &h); - - #define REPORT_RESIZE_HIT(name) { \ - SDL_Log("HIT-TEST: RESIZE_" #name "\n"); \ - return SDL_HITTEST_RESIZE_##name; \ - } - - if (pt->x < RESIZE_BORDER && pt->y < RESIZE_BORDER) { - REPORT_RESIZE_HIT(TOPLEFT); - } else if (pt->x > RESIZE_BORDER && pt->x < w - RESIZE_BORDER && pt->y < RESIZE_BORDER) { - REPORT_RESIZE_HIT(TOP); - } else if (pt->x > w - RESIZE_BORDER && pt->y < RESIZE_BORDER) { - REPORT_RESIZE_HIT(TOPRIGHT); - } else if (pt->x > w - RESIZE_BORDER && pt->y > RESIZE_BORDER && pt->y < h - RESIZE_BORDER) { - REPORT_RESIZE_HIT(RIGHT); - } else if (pt->x > w - RESIZE_BORDER && pt->y > h - RESIZE_BORDER) { - REPORT_RESIZE_HIT(BOTTOMRIGHT); - } else if (pt->x < w - RESIZE_BORDER && pt->x > RESIZE_BORDER && pt->y > h - RESIZE_BORDER) { - REPORT_RESIZE_HIT(BOTTOM); - } else if (pt->x < RESIZE_BORDER && pt->y > h - RESIZE_BORDER) { - REPORT_RESIZE_HIT(BOTTOMLEFT); - } else if (pt->x < RESIZE_BORDER && pt->y < h - RESIZE_BORDER && pt->y > RESIZE_BORDER) { - REPORT_RESIZE_HIT(LEFT); - } - - SDL_Log("HIT-TEST: NORMAL\n"); - return SDL_HITTEST_NORMAL; -} - - -int main(int argc, char **argv) -{ - int done = 0; - SDL_Window *window; - SDL_Renderer *renderer; - - /* !!! FIXME: check for errors. */ - SDL_Init(SDL_INIT_VIDEO); - window = SDL_CreateWindow("Drag the red boxes", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, SDL_WINDOW_BORDERLESS | SDL_WINDOW_RESIZABLE); - renderer = SDL_CreateRenderer(window, -1, 0); - - if (SDL_SetWindowHitTest(window, hitTest, NULL) == -1) { - SDL_Log("Enabling hit-testing failed!\n"); - SDL_Quit(); - return 1; - } - - while (!done) - { - SDL_Event e; - int nothing_to_do = 1; - - SDL_SetRenderDrawColor(renderer, 0, 0, 127, 255); - SDL_RenderClear(renderer); - SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); - SDL_RenderFillRects(renderer, areas, SDL_arraysize(drag_areas)); - SDL_RenderPresent(renderer); - - while (SDL_PollEvent(&e)) { - nothing_to_do = 0; - - switch (e.type) - { - case SDL_MOUSEBUTTONDOWN: - SDL_Log("button down!\n"); - break; - - case SDL_MOUSEBUTTONUP: - SDL_Log("button up!\n"); - break; - - case SDL_WINDOWEVENT: - if (e.window.event == SDL_WINDOWEVENT_MOVED) { - SDL_Log("Window event moved to (%d, %d)!\n", (int) e.window.data1, (int) e.window.data2); - } - break; - - case SDL_KEYDOWN: - if (e.key.keysym.sym == SDLK_ESCAPE) { - done = 1; - } else if (e.key.keysym.sym == SDLK_x) { - if (!areas) { - areas = drag_areas; - numareas = SDL_arraysize(drag_areas); - } else { - areas = NULL; - numareas = 0; - } - } - break; - - case SDL_QUIT: - done = 1; - break; - } - } - - if (nothing_to_do) { - SDL_Delay(50); - } - } - - SDL_Quit(); - return 0; -} diff --git a/SDL2-2.0.12/test/testhotplug.c b/SDL2-2.0.12/test/testhotplug.c deleted file mode 100644 index 014c08f..0000000 --- a/SDL2-2.0.12/test/testhotplug.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ - -/* Simple program to test the SDL joystick hotplugging */ - -#include -#include -#include - -#include "SDL.h" - -#if !defined SDL_JOYSTICK_DISABLED && !defined SDL_HAPTIC_DISABLED - -int -main(int argc, char *argv[]) -{ - SDL_Joystick *joystick = NULL; - SDL_Haptic *haptic = NULL; - SDL_JoystickID instance = -1; - SDL_bool keepGoing = SDL_TRUE; - int i; - SDL_bool enable_haptic = SDL_TRUE; - Uint32 init_subsystems = SDL_INIT_VIDEO | SDL_INIT_JOYSTICK; - - for (i = 1; i < argc; ++i) { - if (SDL_strcasecmp(argv[i], "--nohaptic") == 0) { - enable_haptic = SDL_FALSE; - } - } - - if(enable_haptic) { - init_subsystems |= SDL_INIT_HAPTIC; - } - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1"); - - /* Initialize SDL (Note: video is required to start event loop) */ - if (SDL_Init(init_subsystems) < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError()); - exit(1); - } - - /* - //SDL_CreateWindow("Dummy", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 128, 128, 0); - */ - - SDL_Log("There are %d joysticks at startup\n", SDL_NumJoysticks()); - if (enable_haptic) - SDL_Log("There are %d haptic devices at startup\n", SDL_NumHaptics()); - - while(keepGoing) - { - SDL_Event event; - while(SDL_PollEvent(&event)) - { - switch(event.type) - { - case SDL_QUIT: - keepGoing = SDL_FALSE; - break; - case SDL_JOYDEVICEADDED: - if (joystick != NULL) - { - SDL_Log("Only one joystick supported by this test\n"); - } - else - { - joystick = SDL_JoystickOpen(event.jdevice.which); - instance = SDL_JoystickInstanceID(joystick); - SDL_Log("Joy Added : %d : %s\n", event.jdevice.which, SDL_JoystickName(joystick)); - if (enable_haptic) - { - if (SDL_JoystickIsHaptic(joystick)) - { - haptic = SDL_HapticOpenFromJoystick(joystick); - if (haptic) - { - SDL_Log("Joy Haptic Opened\n"); - if (SDL_HapticRumbleInit( haptic ) != 0) - { - SDL_Log("Could not init Rumble!: %s\n", SDL_GetError()); - SDL_HapticClose(haptic); - haptic = NULL; - } - } else { - SDL_Log("Joy haptic open FAILED!: %s\n", SDL_GetError()); - } - } - else - { - SDL_Log("No haptic found\n"); - } - } - } - break; - case SDL_JOYDEVICEREMOVED: - if (instance == event.jdevice.which) - { - SDL_Log("Joy Removed: %d\n", event.jdevice.which); - instance = -1; - if(enable_haptic && haptic) - { - SDL_HapticClose(haptic); - haptic = NULL; - } - SDL_JoystickClose(joystick); - joystick = NULL; - } else { - SDL_Log("Unknown joystick diconnected\n"); - } - break; - case SDL_JOYAXISMOTION: -/* -// SDL_Log("Axis Move: %d\n", event.jaxis.axis); -*/ - if (enable_haptic) - SDL_HapticRumblePlay(haptic, 0.25, 250); - break; - case SDL_JOYBUTTONDOWN: - SDL_Log("Button Press: %d\n", event.jbutton.button); - if(enable_haptic && haptic) - { - SDL_HapticRumblePlay(haptic, 0.25, 250); - } - if (event.jbutton.button == 0) { - SDL_Log("Exiting due to button press of button 0\n"); - keepGoing = SDL_FALSE; - } - break; - case SDL_JOYBUTTONUP: - SDL_Log("Button Release: %d\n", event.jbutton.button); - break; - } - } - } - - SDL_Quit(); - - return 0; -} -#else - -int -main(int argc, char *argv[]) -{ - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL compiled without Joystick and haptic support.\n"); - return 1; -} - -#endif diff --git a/SDL2-2.0.12/test/testiconv.c b/SDL2-2.0.12/test/testiconv.c deleted file mode 100644 index 41666f3..0000000 --- a/SDL2-2.0.12/test/testiconv.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ - -#include - -#include "SDL.h" - -static size_t -widelen(char *data) -{ - size_t len = 0; - Uint32 *p = (Uint32 *) data; - while (*p++) { - ++len; - } - return len; -} - -int -main(int argc, char *argv[]) -{ - const char *formats[] = { - "UTF8", - "UTF-8", - "UTF16BE", - "UTF-16BE", - "UTF16LE", - "UTF-16LE", - "UTF32BE", - "UTF-32BE", - "UTF32LE", - "UTF-32LE", - "UCS4", - "UCS-4", - }; - char buffer[BUFSIZ]; - char *ucs4; - char *test[2]; - int i; - FILE *file; - int errors = 0; - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - if (!argv[1]) { - argv[1] = "utf8.txt"; - } - file = fopen(argv[1], "rb"); - if (!file) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to open %s\n", argv[1]); - return (1); - } - - while (fgets(buffer, sizeof(buffer), file)) { - /* Convert to UCS-4 */ - size_t len; - ucs4 = - SDL_iconv_string("UCS-4", "UTF-8", buffer, - SDL_strlen(buffer) + 1); - len = (widelen(ucs4) + 1) * 4; - for (i = 0; i < SDL_arraysize(formats); ++i) { - test[0] = SDL_iconv_string(formats[i], "UCS-4", ucs4, len); - test[1] = SDL_iconv_string("UCS-4", formats[i], test[0], len); - if (!test[1] || SDL_memcmp(test[1], ucs4, len) != 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "FAIL: %s\n", formats[i]); - ++errors; - } - SDL_free(test[0]); - SDL_free(test[1]); - } - test[0] = SDL_iconv_string("UTF-8", "UCS-4", ucs4, len); - SDL_free(ucs4); - fputs(test[0], stdout); - SDL_free(test[0]); - } - fclose(file); - return (errors ? errors + 1 : 0); -} diff --git a/SDL2-2.0.12/test/testime.c b/SDL2-2.0.12/test/testime.c deleted file mode 100644 index 1a6ecde..0000000 --- a/SDL2-2.0.12/test/testime.c +++ /dev/null @@ -1,801 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ -/* A simple program to test the Input Method support in the SDL library (2.0+) - If you build without SDL_ttf, you can use the GNU Unifont hex file instead. - Download at http://unifoundry.com/unifont.html */ - -#include -#include -#include - -#include "SDL.h" -#ifdef HAVE_SDL_TTF -#include "SDL_ttf.h" -#endif - -#include "SDL_test_common.h" - -#define DEFAULT_PTSIZE 30 -#ifdef HAVE_SDL_TTF -#ifdef __MACOSX__ -#define DEFAULT_FONT "/System/Library/Fonts/华文细黑.ttf" -#elif __WIN32__ -/* Some japanese font present on at least Windows 8.1. */ -#define DEFAULT_FONT "C:\\Windows\\Fonts\\yugothic.ttf" -#else -#define DEFAULT_FONT "NoDefaultFont.ttf" -#endif -#else -#define DEFAULT_FONT "unifont-9.0.02.hex" -#endif -#define MAX_TEXT_LENGTH 256 - -static SDLTest_CommonState *state; -static SDL_Rect textRect, markedRect; -static SDL_Color lineColor = {0,0,0,255}; -static SDL_Color backColor = {255,255,255,255}; -static SDL_Color textColor = {0,0,0,255}; -static char text[MAX_TEXT_LENGTH], markedText[SDL_TEXTEDITINGEVENT_TEXT_SIZE]; -static int cursor = 0; -#ifdef HAVE_SDL_TTF -static TTF_Font *font; -#else -#define UNIFONT_MAX_CODEPOINT 0x1ffff -#define UNIFONT_NUM_GLYPHS 0x20000 -/* Using 512x512 textures that are supported everywhere. */ -#define UNIFONT_TEXTURE_WIDTH 512 -#define UNIFONT_GLYPHS_IN_ROW (UNIFONT_TEXTURE_WIDTH / 16) -#define UNIFONT_GLYPHS_IN_TEXTURE (UNIFONT_GLYPHS_IN_ROW * UNIFONT_GLYPHS_IN_ROW) -#define UNIFONT_NUM_TEXTURES ((UNIFONT_NUM_GLYPHS + UNIFONT_GLYPHS_IN_TEXTURE - 1) / UNIFONT_GLYPHS_IN_TEXTURE) -#define UNIFONT_TEXTURE_SIZE (UNIFONT_TEXTURE_WIDTH * UNIFONT_TEXTURE_WIDTH * 4) -#define UNIFONT_TEXTURE_PITCH (UNIFONT_TEXTURE_WIDTH * 4) -#define UNIFONT_DRAW_SCALE 2 -struct UnifontGlyph { - Uint8 width; - Uint8 data[32]; -} *unifontGlyph; -static SDL_Texture **unifontTexture; -static Uint8 unifontTextureLoaded[UNIFONT_NUM_TEXTURES] = {0}; - -/* Unifont loading code start */ - -static Uint8 dehex(char c) -{ - if (c >= '0' && c <= '9') - return c - '0'; - else if (c >= 'a' && c <= 'f') - return c - 'a' + 10; - else if (c >= 'A' && c <= 'F') - return c - 'A' + 10; - return 255; -} - -static Uint8 dehex2(char c1, char c2) -{ - return (dehex(c1) << 4) | dehex(c2); -} - -static Uint8 validate_hex(const char *cp, size_t len, Uint32 *np) -{ - Uint32 n = 0; - for (; len > 0; cp++, len--) - { - Uint8 c = dehex(*cp); - if (c == 255) - return 0; - n = (n << 4) | c; - } - if (np != NULL) - *np = n; - return 1; -} - -static int unifont_init(const char *fontname) -{ - Uint8 hexBuffer[65]; - Uint32 numGlyphs = 0; - int lineNumber = 1; - size_t bytesRead; - SDL_RWops *hexFile; - const size_t unifontGlyphSize = UNIFONT_NUM_GLYPHS * sizeof(struct UnifontGlyph); - const size_t unifontTextureSize = UNIFONT_NUM_TEXTURES * state->num_windows * sizeof(void *); - - /* Allocate memory for the glyph data so the file can be closed after initialization. */ - unifontGlyph = (struct UnifontGlyph *)SDL_malloc(unifontGlyphSize); - if (unifontGlyph == NULL) - { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Failed to allocate %d KiB for glyph data.\n", (int)(unifontGlyphSize + 1023) / 1024); - return -1; - } - SDL_memset(unifontGlyph, 0, unifontGlyphSize); - - /* Allocate memory for texture pointers for all renderers. */ - unifontTexture = (SDL_Texture **)SDL_malloc(unifontTextureSize); - if (unifontTexture == NULL) - { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Failed to allocate %d KiB for texture pointer data.\n", (int)(unifontTextureSize + 1023) / 1024); - return -1; - } - SDL_memset(unifontTexture, 0, unifontTextureSize); - - hexFile = SDL_RWFromFile(fontname, "rb"); - if (hexFile == NULL) - { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Failed to open font file: %s\n", fontname); - return -1; - } - - /* Read all the glyph data into memory to make it accessible later when textures are created. */ - do { - int i, codepointHexSize; - size_t bytesOverread; - Uint8 glyphWidth; - Uint32 codepoint; - - bytesRead = SDL_RWread(hexFile, hexBuffer, 1, 9); - if (numGlyphs > 0 && bytesRead == 0) - break; /* EOF */ - if ((numGlyphs == 0 && bytesRead == 0) || (numGlyphs > 0 && bytesRead < 9)) - { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Unexpected end of hex file.\n"); - return -1; - } - - /* Looking for the colon that separates the codepoint and glyph data at position 2, 4, 6 and 8. */ - if (hexBuffer[2] == ':') - codepointHexSize = 2; - else if (hexBuffer[4] == ':') - codepointHexSize = 4; - else if (hexBuffer[6] == ':') - codepointHexSize = 6; - else if (hexBuffer[8] == ':') - codepointHexSize = 8; - else - { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Could not find codepoint and glyph data separator symbol in hex file on line %d.\n", lineNumber); - return -1; - } - - if (!validate_hex((const char *)hexBuffer, codepointHexSize, &codepoint)) - { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Malformed hexadecimal number in hex file on line %d.\n", lineNumber); - return -1; - } - if (codepoint > UNIFONT_MAX_CODEPOINT) - SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "unifont: Codepoint on line %d exceeded limit of 0x%x.\n", lineNumber, UNIFONT_MAX_CODEPOINT); - - /* If there was glyph data read in the last file read, move it to the front of the buffer. */ - bytesOverread = 8 - codepointHexSize; - if (codepointHexSize < 8) - SDL_memmove(hexBuffer, hexBuffer + codepointHexSize + 1, bytesOverread); - bytesRead = SDL_RWread(hexFile, hexBuffer + bytesOverread, 1, 33 - bytesOverread); - if (bytesRead < (33 - bytesOverread)) - { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Unexpected end of hex file.\n"); - return -1; - } - if (hexBuffer[32] == '\n') - glyphWidth = 8; - else - { - glyphWidth = 16; - bytesRead = SDL_RWread(hexFile, hexBuffer + 33, 1, 32); - if (bytesRead < 32) - { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Unexpected end of hex file.\n"); - return -1; - } - } - - if (!validate_hex((const char *)hexBuffer, glyphWidth * 4, NULL)) - { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Malformed hexadecimal glyph data in hex file on line %d.\n", lineNumber); - return -1; - } - - if (codepoint <= UNIFONT_MAX_CODEPOINT) - { - if (unifontGlyph[codepoint].width > 0) - SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "unifont: Ignoring duplicate codepoint 0x%08x in hex file on line %d.\n", codepoint, lineNumber); - else - { - unifontGlyph[codepoint].width = glyphWidth; - /* Pack the hex data into a more compact form. */ - for (i = 0; i < glyphWidth * 2; i++) - unifontGlyph[codepoint].data[i] = dehex2(hexBuffer[i * 2], hexBuffer[i * 2 + 1]); - numGlyphs++; - } - } - - lineNumber++; - } while (bytesRead > 0); - - SDL_RWclose(hexFile); - SDL_Log("unifont: Loaded %u glyphs.\n", numGlyphs); - return 0; -} - -static void unifont_make_rgba(Uint8 *src, Uint8 *dst, Uint8 width) -{ - int i, j; - Uint8 *row = dst; - - for (i = 0; i < width * 2; i++) - { - Uint8 data = src[i]; - for (j = 0; j < 8; j++) - { - if (data & 0x80) - { - row[0] = textColor.r; - row[1] = textColor.g; - row[2] = textColor.b; - row[3] = textColor.a; - } - else - { - row[0] = 0; - row[1] = 0; - row[2] = 0; - row[3] = 0; - } - data <<= 1; - row += 4; - } - - if (width == 8 || (width == 16 && i % 2 == 1)) - { - dst += UNIFONT_TEXTURE_PITCH; - row = dst; - } - } -} - -static int unifont_load_texture(Uint32 textureID) -{ - int i; - Uint8 * textureRGBA; - - if (textureID >= UNIFONT_NUM_TEXTURES) - { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Tried to load out of range texture %u.\n", textureID); - return -1; - } - - textureRGBA = (Uint8 *)SDL_malloc(UNIFONT_TEXTURE_SIZE); - if (textureRGBA == NULL) - { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Failed to allocate %d MiB for a texture.\n", UNIFONT_TEXTURE_SIZE / 1024 / 1024); - return -1; - } - SDL_memset(textureRGBA, 0, UNIFONT_TEXTURE_SIZE); - - /* Copy the glyphs into memory in RGBA format. */ - for (i = 0; i < UNIFONT_GLYPHS_IN_TEXTURE; i++) - { - Uint32 codepoint = UNIFONT_GLYPHS_IN_TEXTURE * textureID + i; - if (unifontGlyph[codepoint].width > 0) - { - const Uint32 cInTex = codepoint % UNIFONT_GLYPHS_IN_TEXTURE; - const size_t offset = (cInTex / UNIFONT_GLYPHS_IN_ROW) * UNIFONT_TEXTURE_PITCH * 16 + (cInTex % UNIFONT_GLYPHS_IN_ROW) * 16 * 4; - unifont_make_rgba(unifontGlyph[codepoint].data, textureRGBA + offset, unifontGlyph[codepoint].width); - } - } - - /* Create textures and upload the RGBA data from above. */ - for (i = 0; i < state->num_windows; ++i) - { - SDL_Renderer *renderer = state->renderers[i]; - SDL_Texture *tex = unifontTexture[UNIFONT_NUM_TEXTURES * i + textureID]; - if (state->windows[i] == NULL || renderer == NULL || tex != NULL) - continue; - tex = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, UNIFONT_TEXTURE_WIDTH, UNIFONT_TEXTURE_WIDTH); - if (tex == NULL) - { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "unifont: Failed to create texture %u for renderer %d.\n", textureID, i); - return -1; - } - unifontTexture[UNIFONT_NUM_TEXTURES * i + textureID] = tex; - SDL_SetTextureBlendMode(tex, SDL_BLENDMODE_BLEND); - if (SDL_UpdateTexture(tex, NULL, textureRGBA, UNIFONT_TEXTURE_PITCH) != 0) - { - SDL_Log("unifont error: Failed to update texture %u data for renderer %d.\n", textureID, i); - } - } - - SDL_free(textureRGBA); - unifontTextureLoaded[textureID] = 1; - return 0; -} - -static Sint32 unifont_draw_glyph(Uint32 codepoint, int rendererID, SDL_Rect *dstrect) -{ - SDL_Texture *texture; - const Uint32 textureID = codepoint / UNIFONT_GLYPHS_IN_TEXTURE; - SDL_Rect srcrect; - srcrect.w = srcrect.h = 16; - if (codepoint > UNIFONT_MAX_CODEPOINT) { - return 0; - } - if (!unifontTextureLoaded[textureID]) { - if (unifont_load_texture(textureID) < 0) { - return 0; - } - } - texture = unifontTexture[UNIFONT_NUM_TEXTURES * rendererID + textureID]; - if (texture != NULL) - { - const Uint32 cInTex = codepoint % UNIFONT_GLYPHS_IN_TEXTURE; - srcrect.x = cInTex % UNIFONT_GLYPHS_IN_ROW * 16; - srcrect.y = cInTex / UNIFONT_GLYPHS_IN_ROW * 16; - SDL_RenderCopy(state->renderers[rendererID], texture, &srcrect, dstrect); - } - return unifontGlyph[codepoint].width; -} - -static void unifont_cleanup() -{ - int i, j; - for (i = 0; i < state->num_windows; ++i) - { - SDL_Renderer *renderer = state->renderers[i]; - if (state->windows[i] == NULL || renderer == NULL) - continue; - for (j = 0; j < UNIFONT_NUM_TEXTURES; j++) - { - SDL_Texture *tex = unifontTexture[UNIFONT_NUM_TEXTURES * i + j]; - if (tex != NULL) - SDL_DestroyTexture(tex); - } - } - - for (j = 0; j < UNIFONT_NUM_TEXTURES; j++) - unifontTextureLoaded[j] = 0; - - SDL_free(unifontTexture); - SDL_free(unifontGlyph); -} - -/* Unifont code end */ -#endif - -size_t utf8_length(unsigned char c) -{ - c = (unsigned char)(0xff & c); - if (c < 0x80) - return 1; - else if ((c >> 5) ==0x6) - return 2; - else if ((c >> 4) == 0xe) - return 3; - else if ((c >> 3) == 0x1e) - return 4; - else - return 0; -} - -char *utf8_next(char *p) -{ - size_t len = utf8_length(*p); - size_t i = 0; - if (!len) - return 0; - - for (; i < len; ++i) - { - ++p; - if (!*p) - return 0; - } - return p; -} - -char *utf8_advance(char *p, size_t distance) -{ - size_t i = 0; - for (; i < distance && p; ++i) - { - p = utf8_next(p); - } - return p; -} - -Uint32 utf8_decode(char *p, size_t len) -{ - Uint32 codepoint = 0; - size_t i = 0; - if (!len) - return 0; - - for (; i < len; ++i) - { - if (i == 0) - codepoint = (0xff >> len) & *p; - else - { - codepoint <<= 6; - codepoint |= 0x3f & *p; - } - if (!*p) - return 0; - p++; - } - - return codepoint; -} - -void usage() -{ - SDL_Log("usage: testime [--font fontfile]\n"); -} - -void InitInput() -{ - /* Prepare a rect for text input */ - textRect.x = textRect.y = 100; - textRect.w = DEFAULT_WINDOW_WIDTH - 2 * textRect.x; - textRect.h = 50; - - text[0] = 0; - markedRect = textRect; - markedText[0] = 0; - - SDL_StartTextInput(); -} - -void CleanupVideo() -{ - SDL_StopTextInput(); -#ifdef HAVE_SDL_TTF - TTF_CloseFont(font); - TTF_Quit(); -#else - unifont_cleanup(); -#endif -} - -void _Redraw(int rendererID) -{ - SDL_Renderer * renderer = state->renderers[rendererID]; - SDL_Rect drawnTextRect, cursorRect, underlineRect; - drawnTextRect = textRect; - drawnTextRect.w = 0; - - SDL_SetRenderDrawColor(renderer, backColor.r, backColor.g, backColor.b, backColor.a); - SDL_RenderFillRect(renderer,&textRect); - - if (*text) - { -#ifdef HAVE_SDL_TTF - SDL_Surface *textSur = TTF_RenderUTF8_Blended(font, text, textColor); - SDL_Texture *texture; - - /* Vertically center text */ - drawnTextRect.y = textRect.y + (textRect.h - textSur->h) / 2; - drawnTextRect.w = textSur->w; - drawnTextRect.h = textSur->h; - - texture = SDL_CreateTextureFromSurface(renderer,textSur); - SDL_FreeSurface(textSur); - - SDL_RenderCopy(renderer,texture,NULL,&drawnTextRect); - SDL_DestroyTexture(texture); -#else - char *utext = text; - Uint32 codepoint; - size_t len; - SDL_Rect dstrect; - - dstrect.x = textRect.x; - dstrect.y = textRect.y + (textRect.h - 16 * UNIFONT_DRAW_SCALE) / 2; - dstrect.w = 16 * UNIFONT_DRAW_SCALE; - dstrect.h = 16 * UNIFONT_DRAW_SCALE; - drawnTextRect.y = dstrect.y; - drawnTextRect.h = dstrect.h; - - while ((codepoint = utf8_decode(utext, len = utf8_length(*utext)))) - { - Sint32 advance = unifont_draw_glyph(codepoint, rendererID, &dstrect) * UNIFONT_DRAW_SCALE; - dstrect.x += advance; - drawnTextRect.w += advance; - utext += len; - } -#endif - } - - markedRect.x = textRect.x + drawnTextRect.w; - markedRect.w = textRect.w - drawnTextRect.w; - if (markedRect.w < 0) - { - /* Stop text input because we cannot hold any more characters */ - SDL_StopTextInput(); - return; - } - else - { - SDL_StartTextInput(); - } - - cursorRect = drawnTextRect; - cursorRect.x += cursorRect.w; - cursorRect.w = 2; - cursorRect.h = drawnTextRect.h; - - drawnTextRect.x += drawnTextRect.w; - drawnTextRect.w = 0; - - SDL_SetRenderDrawColor(renderer, backColor.r, backColor.g, backColor.b, backColor.a); - SDL_RenderFillRect(renderer,&markedRect); - - if (markedText[0]) - { -#ifdef HAVE_SDL_TTF - SDL_Surface *textSur; - SDL_Texture *texture; - if (cursor) - { - char *p = utf8_advance(markedText, cursor); - char c = 0; - if (!p) - p = &markedText[SDL_strlen(markedText)]; - - c = *p; - *p = 0; - TTF_SizeUTF8(font, markedText, &drawnTextRect.w, NULL); - cursorRect.x += drawnTextRect.w; - *p = c; - } - textSur = TTF_RenderUTF8_Blended(font, markedText, textColor); - /* Vertically center text */ - drawnTextRect.y = textRect.y + (textRect.h - textSur->h) / 2; - drawnTextRect.w = textSur->w; - drawnTextRect.h = textSur->h; - - texture = SDL_CreateTextureFromSurface(renderer,textSur); - SDL_FreeSurface(textSur); - - SDL_RenderCopy(renderer,texture,NULL,&drawnTextRect); - SDL_DestroyTexture(texture); -#else - int i = 0; - char *utext = markedText; - Uint32 codepoint; - size_t len; - SDL_Rect dstrect; - - dstrect.x = drawnTextRect.x; - dstrect.y = textRect.y + (textRect.h - 16 * UNIFONT_DRAW_SCALE) / 2; - dstrect.w = 16 * UNIFONT_DRAW_SCALE; - dstrect.h = 16 * UNIFONT_DRAW_SCALE; - drawnTextRect.y = dstrect.y; - drawnTextRect.h = dstrect.h; - - while ((codepoint = utf8_decode(utext, len = utf8_length(*utext)))) - { - Sint32 advance = unifont_draw_glyph(codepoint, rendererID, &dstrect) * UNIFONT_DRAW_SCALE; - dstrect.x += advance; - drawnTextRect.w += advance; - if (i < cursor) - cursorRect.x += advance; - i++; - utext += len; - } -#endif - - if (cursor > 0) - { - cursorRect.y = drawnTextRect.y; - cursorRect.h = drawnTextRect.h; - } - - underlineRect = markedRect; - underlineRect.y = drawnTextRect.y + drawnTextRect.h - 2; - underlineRect.h = 2; - underlineRect.w = drawnTextRect.w; - - SDL_SetRenderDrawColor(renderer, lineColor.r, lineColor.g, lineColor.b, lineColor.a); - SDL_RenderFillRect(renderer, &underlineRect); - } - - SDL_SetRenderDrawColor(renderer, lineColor.r, lineColor.g, lineColor.b, lineColor.a); - SDL_RenderFillRect(renderer,&cursorRect); - - SDL_SetTextInputRect(&markedRect); -} - -void Redraw() -{ - int i; - for (i = 0; i < state->num_windows; ++i) { - SDL_Renderer *renderer = state->renderers[i]; - if (state->windows[i] == NULL) - continue; - SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0); - SDL_RenderClear(renderer); - - /* Sending in the window id to let the font renderers know which one we're working with. */ - _Redraw(i); - - SDL_RenderPresent(renderer); - } -} - -int main(int argc, char *argv[]) -{ - int i, done; - SDL_Event event; - const char *fontname = DEFAULT_FONT; - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - /* Initialize test framework */ - state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO); - if (!state) { - return 1; - } - for (i = 1; i < argc;i++) { - SDLTest_CommonArg(state, i); - } - for (argc--, argv++; argc > 0; argc--, argv++) - { - if (strcmp(argv[0], "--help") == 0) { - usage(); - return 0; - } - - else if (strcmp(argv[0], "--font") == 0) - { - argc--; - argv++; - - if (argc > 0) - fontname = argv[0]; - else { - usage(); - return 0; - } - } - } - - if (!SDLTest_CommonInit(state)) { - return 2; - } - - -#ifdef HAVE_SDL_TTF - /* Initialize fonts */ - TTF_Init(); - - font = TTF_OpenFont(fontname, DEFAULT_PTSIZE); - if (! font) - { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to find font: %s\n", TTF_GetError()); - return -1; - } -#else - if (unifont_init(fontname) < 0) { - return -1; - } -#endif - - SDL_Log("Using font: %s\n", fontname); - - InitInput(); - /* Create the windows and initialize the renderers */ - for (i = 0; i < state->num_windows; ++i) { - SDL_Renderer *renderer = state->renderers[i]; - SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE); - SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF); - SDL_RenderClear(renderer); - } - Redraw(); - /* Main render loop */ - done = 0; - while (!done) { - /* Check for events */ - while (SDL_PollEvent(&event)) { - SDLTest_CommonEvent(state, &event, &done); - switch(event.type) { - case SDL_KEYDOWN: { - switch (event.key.keysym.sym) - { - case SDLK_RETURN: - text[0]=0x00; - Redraw(); - break; - case SDLK_BACKSPACE: - /* Only delete text if not in editing mode. */ - if (!markedText[0]) - { - size_t textlen = SDL_strlen(text); - - do { - if (textlen==0) - { - break; - } - if ((text[textlen-1] & 0x80) == 0x00) - { - /* One byte */ - text[textlen-1]=0x00; - break; - } - if ((text[textlen-1] & 0xC0) == 0x80) - { - /* Byte from the multibyte sequence */ - text[textlen-1]=0x00; - textlen--; - } - if ((text[textlen-1] & 0xC0) == 0xC0) - { - /* First byte of multibyte sequence */ - text[textlen-1]=0x00; - break; - } - } while(1); - - Redraw(); - } - break; - } - - if (done) - { - break; - } - - SDL_Log("Keyboard: scancode 0x%08X = %s, keycode 0x%08X = %s\n", - event.key.keysym.scancode, - SDL_GetScancodeName(event.key.keysym.scancode), - event.key.keysym.sym, SDL_GetKeyName(event.key.keysym.sym)); - break; - - case SDL_TEXTINPUT: - if (event.text.text[0] == '\0' || event.text.text[0] == '\n' || - markedRect.w < 0) - break; - - SDL_Log("Keyboard: text input \"%s\"\n", event.text.text); - - if (SDL_strlen(text) + SDL_strlen(event.text.text) < sizeof(text)) - SDL_strlcat(text, event.text.text, sizeof(text)); - - SDL_Log("text inputed: %s\n", text); - - /* After text inputed, we can clear up markedText because it */ - /* is committed */ - markedText[0] = 0; - Redraw(); - break; - - case SDL_TEXTEDITING: - SDL_Log("text editing \"%s\", selected range (%d, %d)\n", - event.edit.text, event.edit.start, event.edit.length); - - SDL_strlcpy(markedText, event.edit.text, SDL_TEXTEDITINGEVENT_TEXT_SIZE); - cursor = event.edit.start; - Redraw(); - break; - } - break; - - } - } - } - CleanupVideo(); - SDLTest_CommonQuit(state); - return 0; -} - - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/test/testintersections.c b/SDL2-2.0.12/test/testintersections.c deleted file mode 100644 index 7e06c9a..0000000 --- a/SDL2-2.0.12/test/testintersections.c +++ /dev/null @@ -1,363 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ - -/* Simple program: draw as many random objects on the screen as possible */ - -#include -#include -#include - -#ifdef __EMSCRIPTEN__ -#include -#endif - -#include "SDL_test_common.h" - -#define SWAP(typ,a,b) do{typ t=a;a=b;b=t;}while(0) -#define NUM_OBJECTS 100 - -static SDLTest_CommonState *state; -static int num_objects; -static SDL_bool cycle_color; -static SDL_bool cycle_alpha; -static int cycle_direction = 1; -static int current_alpha = 255; -static int current_color = 255; -static SDL_BlendMode blendMode = SDL_BLENDMODE_NONE; - -int mouse_begin_x = -1, mouse_begin_y = -1; -int done; - -void -DrawPoints(SDL_Renderer * renderer) -{ - int i; - int x, y; - SDL_Rect viewport; - - /* Query the sizes */ - SDL_RenderGetViewport(renderer, &viewport); - - for (i = 0; i < num_objects * 4; ++i) { - /* Cycle the color and alpha, if desired */ - if (cycle_color) { - current_color += cycle_direction; - if (current_color < 0) { - current_color = 0; - cycle_direction = -cycle_direction; - } - if (current_color > 255) { - current_color = 255; - cycle_direction = -cycle_direction; - } - } - if (cycle_alpha) { - current_alpha += cycle_direction; - if (current_alpha < 0) { - current_alpha = 0; - cycle_direction = -cycle_direction; - } - if (current_alpha > 255) { - current_alpha = 255; - cycle_direction = -cycle_direction; - } - } - SDL_SetRenderDrawColor(renderer, 255, (Uint8) current_color, - (Uint8) current_color, (Uint8) current_alpha); - - x = rand() % viewport.w; - y = rand() % viewport.h; - SDL_RenderDrawPoint(renderer, x, y); - } -} - -#define MAX_LINES 16 -int num_lines = 0; -SDL_Rect lines[MAX_LINES]; -static int -add_line(int x1, int y1, int x2, int y2) -{ - if (num_lines >= MAX_LINES) - return 0; - if ((x1 == x2) && (y1 == y2)) - return 0; - - SDL_Log("adding line (%d, %d), (%d, %d)\n", x1, y1, x2, y2); - lines[num_lines].x = x1; - lines[num_lines].y = y1; - lines[num_lines].w = x2; - lines[num_lines].h = y2; - - return ++num_lines; -} - - -void -DrawLines(SDL_Renderer * renderer) -{ - int i; - SDL_Rect viewport; - - /* Query the sizes */ - SDL_RenderGetViewport(renderer, &viewport); - - SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); - - for (i = 0; i < num_lines; ++i) { - if (i == -1) { - SDL_RenderDrawLine(renderer, 0, 0, viewport.w - 1, viewport.h - 1); - SDL_RenderDrawLine(renderer, 0, viewport.h - 1, viewport.w - 1, 0); - SDL_RenderDrawLine(renderer, 0, viewport.h / 2, viewport.w - 1, viewport.h / 2); - SDL_RenderDrawLine(renderer, viewport.w / 2, 0, viewport.w / 2, viewport.h - 1); - } else { - SDL_RenderDrawLine(renderer, lines[i].x, lines[i].y, lines[i].w, lines[i].h); - } - } -} - -#define MAX_RECTS 16 -int num_rects = 0; -SDL_Rect rects[MAX_RECTS]; -static int -add_rect(int x1, int y1, int x2, int y2) -{ - if (num_rects >= MAX_RECTS) - return 0; - if ((x1 == x2) || (y1 == y2)) - return 0; - - if (x1 > x2) - SWAP(int, x1, x2); - if (y1 > y2) - SWAP(int, y1, y2); - - SDL_Log("adding rect (%d, %d), (%d, %d) [%dx%d]\n", x1, y1, x2, y2, - x2 - x1, y2 - y1); - - rects[num_rects].x = x1; - rects[num_rects].y = y1; - rects[num_rects].w = x2 - x1; - rects[num_rects].h = y2 - y1; - - return ++num_rects; -} - -static void -DrawRects(SDL_Renderer * renderer) -{ - SDL_SetRenderDrawColor(renderer, 255, 127, 0, 255); - SDL_RenderFillRects(renderer, rects, num_rects); -} - -static void -DrawRectLineIntersections(SDL_Renderer * renderer) -{ - int i, j; - - SDL_SetRenderDrawColor(renderer, 0, 255, 55, 255); - - for (i = 0; i < num_rects; i++) - for (j = 0; j < num_lines; j++) { - int x1, y1, x2, y2; - SDL_Rect r; - - r = rects[i]; - x1 = lines[j].x; - y1 = lines[j].y; - x2 = lines[j].w; - y2 = lines[j].h; - - if (SDL_IntersectRectAndLine(&r, &x1, &y1, &x2, &y2)) { - SDL_RenderDrawLine(renderer, x1, y1, x2, y2); - } - } -} - -static void -DrawRectRectIntersections(SDL_Renderer * renderer) -{ - int i, j; - - SDL_SetRenderDrawColor(renderer, 255, 200, 0, 255); - - for (i = 0; i < num_rects; i++) - for (j = i + 1; j < num_rects; j++) { - SDL_Rect r; - if (SDL_IntersectRect(&rects[i], &rects[j], &r)) { - SDL_RenderFillRect(renderer, &r); - } - } -} - -void -loop() -{ - int i; - SDL_Event event; - - /* Check for events */ - while (SDL_PollEvent(&event)) { - SDLTest_CommonEvent(state, &event, &done); - switch (event.type) { - case SDL_MOUSEBUTTONDOWN: - mouse_begin_x = event.button.x; - mouse_begin_y = event.button.y; - break; - case SDL_MOUSEBUTTONUP: - if (event.button.button == 3) - add_line(mouse_begin_x, mouse_begin_y, event.button.x, - event.button.y); - if (event.button.button == 1) - add_rect(mouse_begin_x, mouse_begin_y, event.button.x, - event.button.y); - break; - case SDL_KEYDOWN: - switch (event.key.keysym.sym) { - case 'l': - if (event.key.keysym.mod & KMOD_SHIFT) - num_lines = 0; - else - add_line(rand() % 640, rand() % 480, rand() % 640, - rand() % 480); - break; - case 'r': - if (event.key.keysym.mod & KMOD_SHIFT) - num_rects = 0; - else - add_rect(rand() % 640, rand() % 480, rand() % 640, - rand() % 480); - break; - } - break; - default: - break; - } - } - for (i = 0; i < state->num_windows; ++i) { - SDL_Renderer *renderer = state->renderers[i]; - if (state->windows[i] == NULL) - continue; - SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF); - SDL_RenderClear(renderer); - - DrawRects(renderer); - DrawPoints(renderer); - DrawRectRectIntersections(renderer); - DrawLines(renderer); - DrawRectLineIntersections(renderer); - - SDL_RenderPresent(renderer); - } -#ifdef __EMSCRIPTEN__ - if (done) { - emscripten_cancel_main_loop(); - } -#endif -} - -int -main(int argc, char *argv[]) -{ - int i; - Uint32 then, now, frames; - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - /* Initialize parameters */ - num_objects = NUM_OBJECTS; - - /* Initialize test framework */ - state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO); - if (!state) { - return 1; - } - for (i = 1; i < argc;) { - int consumed; - - consumed = SDLTest_CommonArg(state, i); - if (consumed == 0) { - consumed = -1; - if (SDL_strcasecmp(argv[i], "--blend") == 0) { - if (argv[i + 1]) { - if (SDL_strcasecmp(argv[i + 1], "none") == 0) { - blendMode = SDL_BLENDMODE_NONE; - consumed = 2; - } else if (SDL_strcasecmp(argv[i + 1], "blend") == 0) { - blendMode = SDL_BLENDMODE_BLEND; - consumed = 2; - } else if (SDL_strcasecmp(argv[i + 1], "add") == 0) { - blendMode = SDL_BLENDMODE_ADD; - consumed = 2; - } else if (SDL_strcasecmp(argv[i + 1], "mod") == 0) { - blendMode = SDL_BLENDMODE_MOD; - consumed = 2; - } - } - } else if (SDL_strcasecmp(argv[i], "--cyclecolor") == 0) { - cycle_color = SDL_TRUE; - consumed = 1; - } else if (SDL_strcasecmp(argv[i], "--cyclealpha") == 0) { - cycle_alpha = SDL_TRUE; - consumed = 1; - } else if (SDL_isdigit(*argv[i])) { - num_objects = SDL_atoi(argv[i]); - consumed = 1; - } - } - if (consumed < 0) { - static const char *options[] = { "[--blend none|blend|add|mod]", "[--cyclecolor]", "[--cyclealpha]", NULL }; - SDLTest_CommonLogUsage(state, argv[0], options); - return 1; - } - i += consumed; - } - if (!SDLTest_CommonInit(state)) { - return 2; - } - - /* Create the windows and initialize the renderers */ - for (i = 0; i < state->num_windows; ++i) { - SDL_Renderer *renderer = state->renderers[i]; - SDL_SetRenderDrawBlendMode(renderer, blendMode); - SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF); - SDL_RenderClear(renderer); - } - - srand(time(NULL)); - - /* Main render loop */ - frames = 0; - then = SDL_GetTicks(); - done = 0; - -#ifdef __EMSCRIPTEN__ - emscripten_set_main_loop(loop, 0, 1); -#else - while (!done) { - ++frames; - loop(); - } -#endif - - SDLTest_CommonQuit(state); - - /* Print out some timing information */ - now = SDL_GetTicks(); - if (now > then) { - double fps = ((double) frames * 1000) / (now - then); - SDL_Log("%2.2f frames per second\n", fps); - } - return 0; -} - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/test/testjoystick.c b/SDL2-2.0.12/test/testjoystick.c deleted file mode 100644 index dea08bb..0000000 --- a/SDL2-2.0.12/test/testjoystick.c +++ /dev/null @@ -1,387 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ - -/* Simple program to test the SDL joystick routines */ - -#include -#include -#include - -#include "SDL.h" - -#ifdef __EMSCRIPTEN__ -#include -#endif - -#ifndef SDL_JOYSTICK_DISABLED - -#ifdef __IPHONEOS__ -#define SCREEN_WIDTH 320 -#define SCREEN_HEIGHT 480 -#else -#define SCREEN_WIDTH 640 -#define SCREEN_HEIGHT 480 -#endif - -SDL_Renderer *screen = NULL; -SDL_bool retval = SDL_FALSE; -SDL_bool done = SDL_FALSE; - -static void -DrawRect(SDL_Renderer *r, const int x, const int y, const int w, const int h) -{ - const SDL_Rect area = { x, y, w, h }; - SDL_RenderFillRect(r, &area); -} - -void -loop(void *arg) -{ - SDL_Event event; - int i; - SDL_Joystick *joystick = (SDL_Joystick *)arg; - - /* blank screen, set up for drawing this frame. */ - SDL_SetRenderDrawColor(screen, 0x0, 0x0, 0x0, SDL_ALPHA_OPAQUE); - SDL_RenderClear(screen); - - while (SDL_PollEvent(&event)) { - switch (event.type) { - - case SDL_JOYDEVICEREMOVED: - SDL_Log("Joystick device %d removed.\n", (int) event.jdevice.which); - SDL_Log("Our instance ID is %d\n", (int) SDL_JoystickInstanceID(joystick)); - break; - - case SDL_JOYAXISMOTION: - SDL_Log("Joystick %d axis %d value: %d\n", - event.jaxis.which, - event.jaxis.axis, event.jaxis.value); - break; - case SDL_JOYHATMOTION: - SDL_Log("Joystick %d hat %d value:", - event.jhat.which, event.jhat.hat); - if (event.jhat.value == SDL_HAT_CENTERED) - SDL_Log(" centered"); - if (event.jhat.value & SDL_HAT_UP) - SDL_Log(" up"); - if (event.jhat.value & SDL_HAT_RIGHT) - SDL_Log(" right"); - if (event.jhat.value & SDL_HAT_DOWN) - SDL_Log(" down"); - if (event.jhat.value & SDL_HAT_LEFT) - SDL_Log(" left"); - SDL_Log("\n"); - break; - case SDL_JOYBALLMOTION: - SDL_Log("Joystick %d ball %d delta: (%d,%d)\n", - event.jball.which, - event.jball.ball, event.jball.xrel, event.jball.yrel); - break; - case SDL_JOYBUTTONDOWN: - SDL_Log("Joystick %d button %d down\n", - event.jbutton.which, event.jbutton.button); - /* First button triggers a 0.5 second full strength rumble */ - if (event.jbutton.button == 0) { - SDL_JoystickRumble(joystick, 0xFFFF, 0xFFFF, 500); - } - break; - case SDL_JOYBUTTONUP: - SDL_Log("Joystick %d button %d up\n", - event.jbutton.which, event.jbutton.button); - break; - case SDL_KEYDOWN: - if ((event.key.keysym.sym != SDLK_ESCAPE) && - (event.key.keysym.sym != SDLK_AC_BACK)) { - break; - } - /* Fall through to signal quit */ - case SDL_FINGERDOWN: - case SDL_MOUSEBUTTONDOWN: - case SDL_QUIT: - done = SDL_TRUE; - break; - default: - break; - } - } - /* Update visual joystick state */ - SDL_SetRenderDrawColor(screen, 0x00, 0xFF, 0x00, SDL_ALPHA_OPAQUE); - for (i = 0; i < SDL_JoystickNumButtons(joystick); ++i) { - if (SDL_JoystickGetButton(joystick, i) == SDL_PRESSED) { - DrawRect(screen, (i%20) * 34, SCREEN_HEIGHT - 68 + (i/20) * 34, 32, 32); - } - } - - SDL_SetRenderDrawColor(screen, 0xFF, 0x00, 0x00, SDL_ALPHA_OPAQUE); - for (i = 0; i < SDL_JoystickNumAxes(joystick); ++i) { - /* Draw the X/Y axis */ - int x, y; - x = (((int) SDL_JoystickGetAxis(joystick, i)) + 32768); - x *= SCREEN_WIDTH; - x /= 65535; - if (x < 0) { - x = 0; - } else if (x > (SCREEN_WIDTH - 16)) { - x = SCREEN_WIDTH - 16; - } - ++i; - if (i < SDL_JoystickNumAxes(joystick)) { - y = (((int) SDL_JoystickGetAxis(joystick, i)) + 32768); - } else { - y = 32768; - } - y *= SCREEN_HEIGHT; - y /= 65535; - if (y < 0) { - y = 0; - } else if (y > (SCREEN_HEIGHT - 16)) { - y = SCREEN_HEIGHT - 16; - } - - DrawRect(screen, x, y, 16, 16); - } - - SDL_SetRenderDrawColor(screen, 0x00, 0x00, 0xFF, SDL_ALPHA_OPAQUE); - for (i = 0; i < SDL_JoystickNumHats(joystick); ++i) { - /* Derive the new position */ - int x = SCREEN_WIDTH/2; - int y = SCREEN_HEIGHT/2; - const Uint8 hat_pos = SDL_JoystickGetHat(joystick, i); - - if (hat_pos & SDL_HAT_UP) { - y = 0; - } else if (hat_pos & SDL_HAT_DOWN) { - y = SCREEN_HEIGHT-8; - } - - if (hat_pos & SDL_HAT_LEFT) { - x = 0; - } else if (hat_pos & SDL_HAT_RIGHT) { - x = SCREEN_WIDTH-8; - } - - DrawRect(screen, x, y, 8, 8); - } - - SDL_RenderPresent(screen); - - if (SDL_JoystickGetAttached( joystick ) == 0) { - done = SDL_TRUE; - retval = SDL_TRUE; /* keep going, wait for reattach. */ - } - -#ifdef __EMSCRIPTEN__ - if (done) { - emscripten_cancel_main_loop(); - } -#endif -} - -static SDL_bool -WatchJoystick(SDL_Joystick * joystick) -{ - SDL_Window *window = NULL; - const char *name = NULL; - - retval = SDL_FALSE; - done = SDL_FALSE; - - /* Create a window to display joystick axis position */ - window = SDL_CreateWindow("Joystick Test", SDL_WINDOWPOS_CENTERED, - SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, - SCREEN_HEIGHT, 0); - if (window == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create window: %s\n", SDL_GetError()); - return SDL_FALSE; - } - - screen = SDL_CreateRenderer(window, -1, 0); - if (screen == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create renderer: %s\n", SDL_GetError()); - SDL_DestroyWindow(window); - return SDL_FALSE; - } - - SDL_SetRenderDrawColor(screen, 0x00, 0x00, 0x00, SDL_ALPHA_OPAQUE); - SDL_RenderClear(screen); - SDL_RenderPresent(screen); - SDL_RaiseWindow(window); - - /* Print info about the joystick we are watching */ - name = SDL_JoystickName(joystick); - SDL_Log("Watching joystick %d: (%s)\n", SDL_JoystickInstanceID(joystick), - name ? name : "Unknown Joystick"); - SDL_Log("Joystick has %d axes, %d hats, %d balls, and %d buttons\n", - SDL_JoystickNumAxes(joystick), SDL_JoystickNumHats(joystick), - SDL_JoystickNumBalls(joystick), SDL_JoystickNumButtons(joystick)); - - /* Loop, getting joystick events! */ -#ifdef __EMSCRIPTEN__ - emscripten_set_main_loop_arg(loop, joystick, 0, 1); -#else - while (!done) { - loop(joystick); - } -#endif - - SDL_DestroyRenderer(screen); - screen = NULL; - SDL_DestroyWindow(window); - return retval; -} - -int -main(int argc, char *argv[]) -{ - const char *name, *type; - int i; - SDL_Joystick *joystick; - - SDL_SetHint(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, "0"); - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - /* Initialize SDL (Note: video is required to start event loop) */ - if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError()); - exit(1); - } - - /* Print information about the joysticks */ - SDL_Log("There are %d joysticks attached\n", SDL_NumJoysticks()); - for (i = 0; i < SDL_NumJoysticks(); ++i) { - name = SDL_JoystickNameForIndex(i); - SDL_Log("Joystick %d: %s\n", i, name ? name : "Unknown Joystick"); - joystick = SDL_JoystickOpen(i); - if (joystick == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_JoystickOpen(%d) failed: %s\n", i, - SDL_GetError()); - } else { - char guid[64]; - SDL_assert(SDL_JoystickFromInstanceID(SDL_JoystickInstanceID(joystick)) == joystick); - SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(joystick), - guid, sizeof (guid)); - switch (SDL_JoystickGetType(joystick)) { - case SDL_JOYSTICK_TYPE_GAMECONTROLLER: - type = "Game Controller"; - break; - case SDL_JOYSTICK_TYPE_WHEEL: - type = "Wheel"; - break; - case SDL_JOYSTICK_TYPE_ARCADE_STICK: - type = "Arcade Stick"; - break; - case SDL_JOYSTICK_TYPE_FLIGHT_STICK: - type = "Flight Stick"; - break; - case SDL_JOYSTICK_TYPE_DANCE_PAD: - type = "Dance Pad"; - break; - case SDL_JOYSTICK_TYPE_GUITAR: - type = "Guitar"; - break; - case SDL_JOYSTICK_TYPE_DRUM_KIT: - type = "Drum Kit"; - break; - case SDL_JOYSTICK_TYPE_ARCADE_PAD: - type = "Arcade Pad"; - break; - case SDL_JOYSTICK_TYPE_THROTTLE: - type = "Throttle"; - break; - default: - type = "Unknown"; - break; - } - SDL_Log(" type: %s\n", type); - SDL_Log(" axes: %d\n", SDL_JoystickNumAxes(joystick)); - SDL_Log(" balls: %d\n", SDL_JoystickNumBalls(joystick)); - SDL_Log(" hats: %d\n", SDL_JoystickNumHats(joystick)); - SDL_Log(" buttons: %d\n", SDL_JoystickNumButtons(joystick)); - SDL_Log("instance id: %d\n", SDL_JoystickInstanceID(joystick)); - SDL_Log(" guid: %s\n", guid); - SDL_Log(" VID/PID: 0x%.4x/0x%.4x\n", SDL_JoystickGetVendor(joystick), SDL_JoystickGetProduct(joystick)); - SDL_JoystickClose(joystick); - } - } - -#if defined(__ANDROID__) || defined(__IPHONEOS__) - if (SDL_NumJoysticks() > 0) { -#else - if (argv[1]) { -#endif - SDL_bool reportederror = SDL_FALSE; - SDL_bool keepGoing = SDL_TRUE; - SDL_Event event; - int device; -#if defined(__ANDROID__) || defined(__IPHONEOS__) - device = 0; -#else - device = atoi(argv[1]); -#endif - joystick = SDL_JoystickOpen(device); - if (joystick != NULL) { - SDL_assert(SDL_JoystickFromInstanceID(SDL_JoystickInstanceID(joystick)) == joystick); - } - - while ( keepGoing ) { - if (joystick == NULL) { - if ( !reportederror ) { - SDL_Log("Couldn't open joystick %d: %s\n", device, SDL_GetError()); - keepGoing = SDL_FALSE; - reportederror = SDL_TRUE; - } - } else { - reportederror = SDL_FALSE; - keepGoing = WatchJoystick(joystick); - SDL_JoystickClose(joystick); - } - - joystick = NULL; - if (keepGoing) { - SDL_Log("Waiting for attach\n"); - } - while (keepGoing) { - SDL_WaitEvent(&event); - if ((event.type == SDL_QUIT) || (event.type == SDL_FINGERDOWN) - || (event.type == SDL_MOUSEBUTTONDOWN)) { - keepGoing = SDL_FALSE; - } else if (event.type == SDL_JOYDEVICEADDED) { - device = event.jdevice.which; - joystick = SDL_JoystickOpen(device); - if (joystick != NULL) { - SDL_assert(SDL_JoystickFromInstanceID(SDL_JoystickInstanceID(joystick)) == joystick); - } - break; - } - } - } - } - SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK); - - return 0; -} - -#else - -int -main(int argc, char *argv[]) -{ - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL compiled without Joystick support.\n"); - return 1; -} - -#endif - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/test/testkeys.c b/SDL2-2.0.12/test/testkeys.c deleted file mode 100644 index 9d6b109..0000000 --- a/SDL2-2.0.12/test/testkeys.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ - -/* Print out all the scancodes we have, just to verify them */ - -#include -#include -#include -#include - -#include "SDL.h" - -int -main(int argc, char *argv[]) -{ - SDL_Scancode scancode; - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - if (SDL_Init(SDL_INIT_VIDEO) < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError()); - exit(1); - } - for (scancode = 0; scancode < SDL_NUM_SCANCODES; ++scancode) { - SDL_Log("Scancode #%d, \"%s\"\n", scancode, - SDL_GetScancodeName(scancode)); - } - SDL_Quit(); - return (0); -} diff --git a/SDL2-2.0.12/test/testloadso.c b/SDL2-2.0.12/test/testloadso.c deleted file mode 100644 index 2a35790..0000000 --- a/SDL2-2.0.12/test/testloadso.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ - -/* Test program to test dynamic loading with the loadso subsystem. -*/ - -#include -#include -#include - -#include "SDL.h" - -typedef int (*fntype) (const char *); - -int -main(int argc, char *argv[]) -{ - int retval = 0; - int hello = 0; - const char *libname = NULL; - const char *symname = NULL; - void *lib = NULL; - fntype fn = NULL; - - if (argc != 3) { - const char *app = argv[0]; - SDL_Log("USAGE: %s \n", app); - SDL_Log(" %s --hello \n", app); - return 1; - } - - /* Initialize SDL */ - if (SDL_Init(0) < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError()); - return 2; - } - - if (strcmp(argv[1], "--hello") == 0) { - hello = 1; - libname = argv[2]; - symname = "puts"; - } else { - libname = argv[1]; - symname = argv[2]; - } - - lib = SDL_LoadObject(libname); - if (lib == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_LoadObject('%s') failed: %s\n", - libname, SDL_GetError()); - retval = 3; - } else { - fn = (fntype) SDL_LoadFunction(lib, symname); - if (fn == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_LoadFunction('%s') failed: %s\n", - symname, SDL_GetError()); - retval = 4; - } else { - SDL_Log("Found %s in %s at %p\n", symname, libname, fn); - if (hello) { - SDL_Log("Calling function...\n"); - fflush(stdout); - fn(" HELLO, WORLD!\n"); - SDL_Log("...apparently, we survived. :)\n"); - SDL_Log("Unloading library...\n"); - fflush(stdout); - } - } - SDL_UnloadObject(lib); - } - SDL_Quit(); - return retval; -} diff --git a/SDL2-2.0.12/test/testlock.c b/SDL2-2.0.12/test/testlock.c deleted file mode 100644 index 2d35f72..0000000 --- a/SDL2-2.0.12/test/testlock.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ - -/* Test the thread and mutex locking functions - Also exercises the system's signal/thread interaction -*/ - -#include -#include -#include /* for atexit() */ - -#include "SDL.h" - -static SDL_mutex *mutex = NULL; -static SDL_threadID mainthread; -static SDL_Thread *threads[6]; -static SDL_atomic_t doterminate; - -/* - * SDL_Quit() shouldn't be used with atexit() directly because - * calling conventions may differ... - */ -static void -SDL_Quit_Wrapper(void) -{ - SDL_Quit(); -} - -void -printid(void) -{ - SDL_Log("Process %lu: exiting\n", SDL_ThreadID()); -} - -void -terminate(int sig) -{ - signal(SIGINT, terminate); - SDL_AtomicSet(&doterminate, 1); -} - -void -closemutex(int sig) -{ - SDL_threadID id = SDL_ThreadID(); - int i; - SDL_Log("Process %lu: Cleaning up...\n", id == mainthread ? 0 : id); - SDL_AtomicSet(&doterminate, 1); - for (i = 0; i < 6; ++i) - SDL_WaitThread(threads[i], NULL); - SDL_DestroyMutex(mutex); - exit(sig); -} - -int SDLCALL -Run(void *data) -{ - if (SDL_ThreadID() == mainthread) - signal(SIGTERM, closemutex); - while (!SDL_AtomicGet(&doterminate)) { - SDL_Log("Process %lu ready to work\n", SDL_ThreadID()); - if (SDL_LockMutex(mutex) < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't lock mutex: %s", SDL_GetError()); - exit(1); - } - SDL_Log("Process %lu, working!\n", SDL_ThreadID()); - SDL_Delay(1 * 1000); - SDL_Log("Process %lu, done!\n", SDL_ThreadID()); - if (SDL_UnlockMutex(mutex) < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't unlock mutex: %s", SDL_GetError()); - exit(1); - } - /* If this sleep isn't done, then threads may starve */ - SDL_Delay(10); - } - if (SDL_ThreadID() == mainthread && SDL_AtomicGet(&doterminate)) { - SDL_Log("Process %lu: raising SIGTERM\n", SDL_ThreadID()); - raise(SIGTERM); - } - return (0); -} - -int -main(int argc, char *argv[]) -{ - int i; - int maxproc = 6; - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - /* Load the SDL library */ - if (SDL_Init(0) < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "%s\n", SDL_GetError()); - exit(1); - } - atexit(SDL_Quit_Wrapper); - - SDL_AtomicSet(&doterminate, 0); - - if ((mutex = SDL_CreateMutex()) == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create mutex: %s\n", SDL_GetError()); - exit(1); - } - - mainthread = SDL_ThreadID(); - SDL_Log("Main thread: %lu\n", mainthread); - atexit(printid); - for (i = 0; i < maxproc; ++i) { - char name[64]; - SDL_snprintf(name, sizeof (name), "Worker%d", i); - if ((threads[i] = SDL_CreateThread(Run, name, NULL)) == NULL) - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create thread!\n"); - } - signal(SIGINT, terminate); - Run(NULL); - - return (0); /* Never reached */ -} diff --git a/SDL2-2.0.12/test/testmessage.c b/SDL2-2.0.12/test/testmessage.c deleted file mode 100644 index 946d458..0000000 --- a/SDL2-2.0.12/test/testmessage.c +++ /dev/null @@ -1,193 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ - -/* Simple test of the SDL MessageBox API */ - -#include -#include - -#include "SDL.h" - -/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ -static void -quit(int rc) -{ - SDL_Quit(); - exit(rc); -} - -static int SDLCALL -button_messagebox(void *eventNumber) -{ - const SDL_MessageBoxButtonData buttons[] = { - { - SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, - 0, - "OK" - },{ - SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, - 1, - "Cancel" - }, - }; - - SDL_MessageBoxData data = { - SDL_MESSAGEBOX_INFORMATION, - NULL, /* no parent window */ - "Custom MessageBox", - "This is a custom messagebox", - 2, - NULL,/* buttons */ - NULL /* Default color scheme */ - }; - - int button = -1; - int success = 0; - data.buttons = buttons; - if (eventNumber) { - data.message = "This is a custom messagebox from a background thread."; - } - - success = SDL_ShowMessageBox(&data, &button); - if (success == -1) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error Presenting MessageBox: %s\n", SDL_GetError()); - if (eventNumber) { - SDL_UserEvent event; - event.type = (intptr_t)eventNumber; - SDL_PushEvent((SDL_Event*)&event); - return 1; - } else { - quit(2); - } - } - SDL_Log("Pressed button: %d, %s\n", button, button == -1 ? "[closed]" : button == 1 ? "Cancel" : "OK"); - - if (eventNumber) { - SDL_UserEvent event; - event.type = (intptr_t)eventNumber; - SDL_PushEvent((SDL_Event*)&event); - } - - return 0; -} - -int -main(int argc, char *argv[]) -{ - int success; - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - success = SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, - "Simple MessageBox", - "This is a simple error MessageBox", - NULL); - if (success == -1) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error Presenting MessageBox: %s\n", SDL_GetError()); - quit(1); - } - - success = SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, - "Simple MessageBox", - "This is a simple MessageBox with a newline:\r\nHello world!", - NULL); - if (success == -1) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error Presenting MessageBox: %s\n", SDL_GetError()); - quit(1); - } - - /* Google says this is Traditional Chinese for "beef with broccoli" */ - success = SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, - "UTF-8 Simple MessageBox", - "Unicode text: '牛肉西蘭花' ...", - NULL); - if (success == -1) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error Presenting MessageBox: %s\n", SDL_GetError()); - quit(1); - } - - /* Google says this is Traditional Chinese for "beef with broccoli" */ - success = SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, - "UTF-8 Simple MessageBox", - "Unicode text and newline:\r\n'牛肉西蘭花'\n'牛肉西蘭花'", - NULL); - if (success == -1) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error Presenting MessageBox: %s\n", SDL_GetError()); - quit(1); - } - - /* Google says this is Traditional Chinese for "beef with broccoli" */ - success = SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, - "牛肉西蘭花", - "Unicode text in the title.", - NULL); - if (success == -1) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error Presenting MessageBox: %s\n", SDL_GetError()); - quit(1); - } - - button_messagebox(NULL); - - /* Test showing a message box from a background thread. - - On Mac OS X, the video subsystem needs to be initialized for this - to work, since the message box events are dispatched by the Cocoa - subsystem on the main thread. - */ - if (SDL_Init(SDL_INIT_VIDEO) < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL video subsystem: %s\n", SDL_GetError()); - return (1); - } - { - int status = 0; - SDL_Event event; - intptr_t eventNumber = SDL_RegisterEvents(1); - SDL_Thread* thread = SDL_CreateThread(&button_messagebox, "MessageBox", (void*)eventNumber); - - while (SDL_WaitEvent(&event)) - { - if (event.type == eventNumber) { - break; - } - } - - SDL_WaitThread(thread, &status); - - SDL_Log("Message box thread return %i\n", status); - } - - /* Test showing a message box with a parent window */ - { - SDL_Event event; - SDL_Window *window = SDL_CreateWindow("Test", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, 0); - - success = SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, - "Simple MessageBox", - "This is a simple error MessageBox with a parent window", - window); - if (success == -1) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error Presenting MessageBox: %s\n", SDL_GetError()); - quit(1); - } - - while (SDL_WaitEvent(&event)) - { - if (event.type == SDL_QUIT || event.type == SDL_KEYUP) { - break; - } - } - } - - SDL_Quit(); - return (0); -} diff --git a/SDL2-2.0.12/test/testmultiaudio.c b/SDL2-2.0.12/test/testmultiaudio.c deleted file mode 100644 index faf3d9d..0000000 --- a/SDL2-2.0.12/test/testmultiaudio.c +++ /dev/null @@ -1,199 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ -#include "SDL.h" - -#include /* for fflush() and stdout */ - -#ifdef __EMSCRIPTEN__ -#include -#endif - -static SDL_AudioSpec spec; -static Uint8 *sound = NULL; /* Pointer to wave data */ -static Uint32 soundlen = 0; /* Length of wave data */ - -typedef struct -{ - SDL_AudioDeviceID dev; - int soundpos; - SDL_atomic_t done; -} callback_data; - -callback_data cbd[64]; - -void SDLCALL -play_through_once(void *arg, Uint8 * stream, int len) -{ - callback_data *cbd = (callback_data *) arg; - Uint8 *waveptr = sound + cbd->soundpos; - int waveleft = soundlen - cbd->soundpos; - int cpy = len; - if (cpy > waveleft) - cpy = waveleft; - - SDL_memcpy(stream, waveptr, cpy); - len -= cpy; - cbd->soundpos += cpy; - if (len > 0) { - stream += cpy; - SDL_memset(stream, spec.silence, len); - SDL_AtomicSet(&cbd->done, 1); - } -} - -void -loop() -{ - if (SDL_AtomicGet(&cbd[0].done)) { -#ifdef __EMSCRIPTEN__ - emscripten_cancel_main_loop(); -#endif - SDL_PauseAudioDevice(cbd[0].dev, 1); - SDL_CloseAudioDevice(cbd[0].dev); - SDL_FreeWAV(sound); - SDL_Quit(); - } -} - -static void -test_multi_audio(int devcount) -{ - int keep_going = 1; - int i; - -#ifdef __ANDROID__ - SDL_Event event; - - /* Create a Window to get fully initialized event processing for testing pause on Android. */ - SDL_CreateWindow("testmultiaudio", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 320, 240, 0); -#endif - - if (devcount > 64) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Too many devices (%d), clamping to 64...\n", - devcount); - devcount = 64; - } - - spec.callback = play_through_once; - - for (i = 0; i < devcount; i++) { - const char *devname = SDL_GetAudioDeviceName(i, 0); - SDL_Log("playing on device #%d: ('%s')...", i, devname); - fflush(stdout); - - SDL_memset(&cbd[0], '\0', sizeof(callback_data)); - spec.userdata = &cbd[0]; - cbd[0].dev = SDL_OpenAudioDevice(devname, 0, &spec, NULL, 0); - if (cbd[0].dev == 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Open device failed: %s\n", SDL_GetError()); - } else { - SDL_PauseAudioDevice(cbd[0].dev, 0); -#ifdef __EMSCRIPTEN__ - emscripten_set_main_loop(loop, 0, 1); -#else - while (!SDL_AtomicGet(&cbd[0].done)) { - #ifdef __ANDROID__ - /* Empty queue, some application events would prevent pause. */ - while (SDL_PollEvent(&event)){} - #endif - SDL_Delay(100); - } - SDL_PauseAudioDevice(cbd[0].dev, 1); -#endif - SDL_Log("done.\n"); - SDL_CloseAudioDevice(cbd[0].dev); - } - } - - SDL_memset(cbd, '\0', sizeof(cbd)); - - SDL_Log("playing on all devices...\n"); - for (i = 0; i < devcount; i++) { - const char *devname = SDL_GetAudioDeviceName(i, 0); - spec.userdata = &cbd[i]; - cbd[i].dev = SDL_OpenAudioDevice(devname, 0, &spec, NULL, 0); - if (cbd[i].dev == 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Open device %d failed: %s\n", i, SDL_GetError()); - } - } - - for (i = 0; i < devcount; i++) { - if (cbd[i].dev) { - SDL_PauseAudioDevice(cbd[i].dev, 0); - } - } - - while (keep_going) { - keep_going = 0; - for (i = 0; i < devcount; i++) { - if ((cbd[i].dev) && (!SDL_AtomicGet(&cbd[i].done))) { - keep_going = 1; - } - } - #ifdef __ANDROID__ - /* Empty queue, some application events would prevent pause. */ - while (SDL_PollEvent(&event)){} - #endif - - SDL_Delay(100); - } - -#ifndef __EMSCRIPTEN__ - for (i = 0; i < devcount; i++) { - if (cbd[i].dev) { - SDL_PauseAudioDevice(cbd[i].dev, 1); - SDL_CloseAudioDevice(cbd[i].dev); - } - } - - SDL_Log("All done!\n"); -#endif -} - - -int -main(int argc, char **argv) -{ - int devcount = 0; - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - /* Load the SDL library */ - if (SDL_Init(SDL_INIT_AUDIO) < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError()); - return (1); - } - - SDL_Log("Using audio driver: %s\n", SDL_GetCurrentAudioDriver()); - - devcount = SDL_GetNumAudioDevices(0); - if (devcount < 1) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Don't see any specific audio devices!\n"); - } else { - if (argv[1] == NULL) { - argv[1] = "sample.wav"; - } - - /* Load the wave file into memory */ - if (SDL_LoadWAV(argv[1], &spec, &sound, &soundlen) == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", argv[1], - SDL_GetError()); - } else { - test_multi_audio(devcount); - SDL_FreeWAV(sound); - } - } - - SDL_Quit(); - return 0; -} diff --git a/SDL2-2.0.12/test/testnative.c b/SDL2-2.0.12/test/testnative.c deleted file mode 100644 index 353262b..0000000 --- a/SDL2-2.0.12/test/testnative.c +++ /dev/null @@ -1,237 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ -/* Simple program: Create a native window and attach an SDL renderer */ - -#include -#include /* for srand() */ -#include /* for time() */ - -#include "testnative.h" - -#define WINDOW_W 640 -#define WINDOW_H 480 -#define NUM_SPRITES 100 -#define MAX_SPEED 1 - -static NativeWindowFactory *factories[] = { -#ifdef TEST_NATIVE_WINDOWS - &WindowsWindowFactory, -#endif -#ifdef TEST_NATIVE_X11 - &X11WindowFactory, -#endif -#ifdef TEST_NATIVE_COCOA - &CocoaWindowFactory, -#endif - NULL -}; -static NativeWindowFactory *factory = NULL; -static void *native_window; -static SDL_Rect *positions, *velocities; - -/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ -static void -quit(int rc) -{ - SDL_VideoQuit(); - if (native_window) { - factory->DestroyNativeWindow(native_window); - } - exit(rc); -} - -SDL_Texture * -LoadSprite(SDL_Renderer *renderer, char *file) -{ - SDL_Surface *temp; - SDL_Texture *sprite; - - /* Load the sprite image */ - temp = SDL_LoadBMP(file); - if (temp == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s", file, SDL_GetError()); - return 0; - } - - /* Set transparent pixel as the pixel at (0,0) */ - if (temp->format->palette) { - SDL_SetColorKey(temp, 1, *(Uint8 *) temp->pixels); - } - - /* Create textures from the image */ - sprite = SDL_CreateTextureFromSurface(renderer, temp); - if (!sprite) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError()); - SDL_FreeSurface(temp); - return 0; - } - SDL_FreeSurface(temp); - - /* We're ready to roll. :) */ - return sprite; -} - -void -MoveSprites(SDL_Renderer * renderer, SDL_Texture * sprite) -{ - int sprite_w, sprite_h; - int i; - SDL_Rect viewport; - SDL_Rect *position, *velocity; - - /* Query the sizes */ - SDL_RenderGetViewport(renderer, &viewport); - SDL_QueryTexture(sprite, NULL, NULL, &sprite_w, &sprite_h); - - /* Draw a gray background */ - SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF); - SDL_RenderClear(renderer); - - /* Move the sprite, bounce at the wall, and draw */ - for (i = 0; i < NUM_SPRITES; ++i) { - position = &positions[i]; - velocity = &velocities[i]; - position->x += velocity->x; - if ((position->x < 0) || (position->x >= (viewport.w - sprite_w))) { - velocity->x = -velocity->x; - position->x += velocity->x; - } - position->y += velocity->y; - if ((position->y < 0) || (position->y >= (viewport.h - sprite_h))) { - velocity->y = -velocity->y; - position->y += velocity->y; - } - - /* Blit the sprite onto the screen */ - SDL_RenderCopy(renderer, sprite, NULL, position); - } - - /* Update the screen! */ - SDL_RenderPresent(renderer); -} - -int -main(int argc, char *argv[]) -{ - int i, done; - const char *driver; - SDL_Window *window; - SDL_Renderer *renderer; - SDL_Texture *sprite; - int window_w, window_h; - int sprite_w, sprite_h; - SDL_Event event; - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - if (SDL_VideoInit(NULL) < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL video: %s\n", - SDL_GetError()); - exit(1); - } - driver = SDL_GetCurrentVideoDriver(); - - /* Find a native window driver and create a native window */ - for (i = 0; factories[i]; ++i) { - if (SDL_strcmp(driver, factories[i]->tag) == 0) { - factory = factories[i]; - break; - } - } - if (!factory) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't find native window code for %s driver\n", - driver); - quit(2); - } - SDL_Log("Creating native window for %s driver\n", driver); - native_window = factory->CreateNativeWindow(WINDOW_W, WINDOW_H); - if (!native_window) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create native window\n"); - quit(3); - } - window = SDL_CreateWindowFrom(native_window); - if (!window) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create SDL window: %s\n", SDL_GetError()); - quit(4); - } - SDL_SetWindowTitle(window, "SDL Native Window Test"); - - /* Create the renderer */ - renderer = SDL_CreateRenderer(window, -1, 0); - if (!renderer) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create renderer: %s\n", SDL_GetError()); - quit(5); - } - - /* Clear the window, load the sprite and go! */ - SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF); - SDL_RenderClear(renderer); - - sprite = LoadSprite(renderer, "icon.bmp"); - if (!sprite) { - quit(6); - } - - /* Allocate memory for the sprite info */ - SDL_GetWindowSize(window, &window_w, &window_h); - SDL_QueryTexture(sprite, NULL, NULL, &sprite_w, &sprite_h); - positions = (SDL_Rect *) SDL_malloc(NUM_SPRITES * sizeof(SDL_Rect)); - velocities = (SDL_Rect *) SDL_malloc(NUM_SPRITES * sizeof(SDL_Rect)); - if (!positions || !velocities) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Out of memory!\n"); - quit(2); - } - srand(time(NULL)); - for (i = 0; i < NUM_SPRITES; ++i) { - positions[i].x = rand() % (window_w - sprite_w); - positions[i].y = rand() % (window_h - sprite_h); - positions[i].w = sprite_w; - positions[i].h = sprite_h; - velocities[i].x = 0; - velocities[i].y = 0; - while (!velocities[i].x && !velocities[i].y) { - velocities[i].x = (rand() % (MAX_SPEED * 2 + 1)) - MAX_SPEED; - velocities[i].y = (rand() % (MAX_SPEED * 2 + 1)) - MAX_SPEED; - } - } - - /* Main render loop */ - done = 0; - while (!done) { - /* Check for events */ - while (SDL_PollEvent(&event)) { - switch (event.type) { - case SDL_WINDOWEVENT: - switch (event.window.event) { - case SDL_WINDOWEVENT_EXPOSED: - SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF); - SDL_RenderClear(renderer); - break; - } - break; - case SDL_QUIT: - done = 1; - break; - default: - break; - } - } - MoveSprites(renderer, sprite); - } - - quit(0); - - return 0; /* to prevent compiler warning */ -} - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/test/testnative.h b/SDL2-2.0.12/test/testnative.h deleted file mode 100644 index 428d607..0000000 --- a/SDL2-2.0.12/test/testnative.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ - -/* Definitions for platform dependent windowing functions to test SDL - integration with native windows -*/ - -#include "SDL.h" - -/* This header includes all the necessary system headers for native windows */ -#include "SDL_syswm.h" - -typedef struct -{ - const char *tag; - void *(*CreateNativeWindow) (int w, int h); - void (*DestroyNativeWindow) (void *window); -} NativeWindowFactory; - -#ifdef SDL_VIDEO_DRIVER_WINDOWS -#define TEST_NATIVE_WINDOWS -extern NativeWindowFactory WindowsWindowFactory; -#endif - -#ifdef SDL_VIDEO_DRIVER_X11 -#define TEST_NATIVE_X11 -extern NativeWindowFactory X11WindowFactory; -#endif - -#ifdef SDL_VIDEO_DRIVER_COCOA -/* Actually, we don't really do this, since it involves adding Objective C - support to the build system, which is a little tricky. You can uncomment - it manually though and link testnativecocoa.m into the test application. -*/ -#define TEST_NATIVE_COCOA -extern NativeWindowFactory CocoaWindowFactory; -#endif diff --git a/SDL2-2.0.12/test/testnativecocoa.m b/SDL2-2.0.12/test/testnativecocoa.m deleted file mode 100644 index 030607d..0000000 --- a/SDL2-2.0.12/test/testnativecocoa.m +++ /dev/null @@ -1,51 +0,0 @@ - -#include "testnative.h" - -#ifdef TEST_NATIVE_COCOA - -#include - -static void *CreateWindowCocoa(int w, int h); -static void DestroyWindowCocoa(void *window); - -NativeWindowFactory CocoaWindowFactory = { - "cocoa", - CreateWindowCocoa, - DestroyWindowCocoa -}; - -static void *CreateWindowCocoa(int w, int h) -{ - NSAutoreleasePool *pool; - NSWindow *nswindow; - NSRect rect; - unsigned int style; - - pool = [[NSAutoreleasePool alloc] init]; - - rect.origin.x = 0; - rect.origin.y = 0; - rect.size.width = w; - rect.size.height = h; - rect.origin.y = CGDisplayPixelsHigh(kCGDirectMainDisplay) - rect.origin.y - rect.size.height; - - style = (NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask); - - nswindow = [[NSWindow alloc] initWithContentRect:rect styleMask:style backing:NSBackingStoreBuffered defer:FALSE]; - [nswindow makeKeyAndOrderFront:nil]; - - [pool release]; - - return nswindow; -} - -static void DestroyWindowCocoa(void *window) -{ - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - NSWindow *nswindow = (NSWindow *)window; - - [nswindow close]; - [pool release]; -} - -#endif diff --git a/SDL2-2.0.12/test/testnativew32.c b/SDL2-2.0.12/test/testnativew32.c deleted file mode 100644 index 62627c8..0000000 --- a/SDL2-2.0.12/test/testnativew32.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ - -#include "testnative.h" - -#ifdef TEST_NATIVE_WINDOWS - -static void *CreateWindowNative(int w, int h); -static void DestroyWindowNative(void *window); - -NativeWindowFactory WindowsWindowFactory = { - "windows", - CreateWindowNative, - DestroyWindowNative -}; - -LRESULT CALLBACK -WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch (msg) { - case WM_CLOSE: - DestroyWindow(hwnd); - break; - case WM_DESTROY: - PostQuitMessage(0); - break; - default: - return DefWindowProc(hwnd, msg, wParam, lParam); - } - return 0; -} - -static void * -CreateWindowNative(int w, int h) -{ - HWND hwnd; - WNDCLASS wc; - - wc.style = 0; - wc.lpfnWndProc = WndProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = GetModuleHandle(NULL); - wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); - wc.hCursor = LoadCursor(NULL, IDC_ARROW); - wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1); - wc.lpszMenuName = NULL; - wc.lpszClassName = "SDL Test"; - - if (!RegisterClass(&wc)) { - MessageBox(NULL, "Window Registration Failed!", "Error!", - MB_ICONEXCLAMATION | MB_OK); - return 0; - } - - hwnd = - CreateWindow("SDL Test", "", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, - CW_USEDEFAULT, w, h, NULL, NULL, GetModuleHandle(NULL), - NULL); - if (hwnd == NULL) { - MessageBox(NULL, "Window Creation Failed!", "Error!", - MB_ICONEXCLAMATION | MB_OK); - return 0; - } - - ShowWindow(hwnd, SW_SHOW); - - return hwnd; -} - -static void -DestroyWindowNative(void *window) -{ - DestroyWindow((HWND) window); -} - -#endif diff --git a/SDL2-2.0.12/test/testnativex11.c b/SDL2-2.0.12/test/testnativex11.c deleted file mode 100644 index 2a38de2..0000000 --- a/SDL2-2.0.12/test/testnativex11.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ - -#include "testnative.h" - -#ifdef TEST_NATIVE_X11 - -static void *CreateWindowX11(int w, int h); -static void DestroyWindowX11(void *window); - -NativeWindowFactory X11WindowFactory = { - "x11", - CreateWindowX11, - DestroyWindowX11 -}; - -static Display *dpy; - -static void * -CreateWindowX11(int w, int h) -{ - Window window = 0; - - dpy = XOpenDisplay(NULL); - if (dpy) { - window = - XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0, w, h, 0, 0, - 0); - XMapRaised(dpy, window); - XSync(dpy, False); - } - return (void *) window; -} - -static void -DestroyWindowX11(void *window) -{ - if (dpy) { - XDestroyWindow(dpy, (Window) window); - XCloseDisplay(dpy); - } -} - -#endif diff --git a/SDL2-2.0.12/test/testoffscreen.c b/SDL2-2.0.12/test/testoffscreen.c deleted file mode 100644 index bebbe01..0000000 --- a/SDL2-2.0.12/test/testoffscreen.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ - -/* Simple program: picks the offscreen backend and renders each frame to a bmp */ - -#include -#include -#include - -#ifdef __EMSCRIPTEN__ -#include -#endif - -#include "SDL.h" -#include "SDL_stdinc.h" -#include "SDL_opengl.h" - -static SDL_Renderer *renderer = NULL; -static SDL_Window *window = NULL; -static int done = SDL_FALSE; -static int frame_number = 0; -static int width = 640; -static int height = 480; -static int max_frames = 200; - -void -draw() -{ - SDL_Rect Rect; - - SDL_SetRenderDrawColor(renderer, 0x10, 0x9A, 0xCE, 0xFF); - SDL_RenderClear(renderer); - - /* Grow based on the frame just to show a difference per frame of the region */ - Rect.x = 0; - Rect.y = 0; - Rect.w = (frame_number * 2) % width; - Rect.h = (frame_number * 2) % height; - SDL_SetRenderDrawColor(renderer, 0xFF, 0x10, 0x21, 0xFF); - SDL_RenderFillRect(renderer, &Rect); - - SDL_RenderPresent(renderer); -} - -void -save_surface_to_bmp() -{ - SDL_Surface* surface; - Uint32 r_mask, g_mask, b_mask, a_mask; - Uint32 pixel_format; - char file[128]; - int bbp; - - pixel_format = SDL_GetWindowPixelFormat(window); - SDL_PixelFormatEnumToMasks(pixel_format, &bbp, &r_mask, &g_mask, &b_mask, &a_mask); - - surface = SDL_CreateRGBSurface(0, width, height, bbp, r_mask, g_mask, b_mask, a_mask); - SDL_RenderReadPixels(renderer, NULL, pixel_format, (void*)surface->pixels, surface->pitch); - - SDL_snprintf(file, sizeof(file), "SDL_window%d-%8.8d.bmp", - SDL_GetWindowID(window), ++frame_number); - - SDL_SaveBMP(surface, file); - SDL_FreeSurface(surface); -} - -void -loop() -{ - SDL_Event event; - - /* Check for events */ - while (SDL_PollEvent(&event)) { - switch (event.type) { - case SDL_QUIT: - done = SDL_TRUE; - break; - } - } - - draw(); - save_surface_to_bmp(); - -#ifdef __EMSCRIPTEN__ - if (done) { - emscripten_cancel_main_loop(); - } -#endif -} - -int -main(int argc, char *argv[]) -{ - Uint32 then, now, frames; - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - /* Force the offscreen renderer, if it cannot be created then fail out */ - if (SDL_VideoInit("offscreen") < 0) { - SDL_Log("Couldn't initialize the offscreen video driver: %s\n", - SDL_GetError()); - return SDL_FALSE; - } - - /* If OPENGL fails to init it will fallback to using a framebuffer for rendering */ - window = SDL_CreateWindow("Offscreen Test", - SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, - width, height, 0); - - if (!window) { - SDL_Log("Couldn't create window: %s\n", - SDL_GetError()); - return SDL_FALSE; - } - - renderer = SDL_CreateRenderer(window, -1, 0); - - if (!renderer) { - SDL_Log("Couldn't create renderer: %s\n", - SDL_GetError()); - return SDL_FALSE; - } - - SDL_RenderClear(renderer); - - srand((unsigned int)time(NULL)); - - /* Main render loop */ - frames = 0; - then = SDL_GetTicks(); - done = 0; - - SDL_Log("Rendering %i frames offscreen\n", max_frames); - -#ifdef __EMSCRIPTEN__ - emscripten_set_main_loop(loop, 0, 1); -#else - while (!done && frames < max_frames) { - ++frames; - loop(); - - /* Print out some timing information, along with remaining frames */ - if (frames % (max_frames / 10) == 0) { - now = SDL_GetTicks(); - if (now > then) { - double fps = ((double) frames * 1000) / (now - then); - SDL_Log("Frames remaining: %i rendering at %2.2f frames per second\n", max_frames - frames, fps); - } - } - } -#endif - - SDL_DestroyRenderer(renderer); - SDL_DestroyWindow(window); - SDL_Quit(); - - return 0; -} - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/test/testoverlay2.c b/SDL2-2.0.12/test/testoverlay2.c deleted file mode 100644 index ac90ba8..0000000 --- a/SDL2-2.0.12/test/testoverlay2.c +++ /dev/null @@ -1,410 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ -/******************************************************************************** - * * - * Test of the overlay used for moved pictures, test more closed to real life. * - * Running trojan moose :) Coded by Mike Gorchak. * - * * - ********************************************************************************/ - -#include - -#ifdef __EMSCRIPTEN__ -#include -#endif - -#include "SDL.h" - -#include "testyuv_cvt.h" - -#define MOOSEPIC_W 64 -#define MOOSEPIC_H 88 - -#define MOOSEFRAME_SIZE (MOOSEPIC_W * MOOSEPIC_H) -#define MOOSEFRAMES_COUNT 10 - -SDL_Color MooseColors[84] = { - {49, 49, 49, SDL_ALPHA_OPAQUE} - , {66, 24, 0, SDL_ALPHA_OPAQUE} - , {66, 33, 0, SDL_ALPHA_OPAQUE} - , {66, 66, 66, SDL_ALPHA_OPAQUE} - , - {66, 115, 49, SDL_ALPHA_OPAQUE} - , {74, 33, 0, SDL_ALPHA_OPAQUE} - , {74, 41, 16, SDL_ALPHA_OPAQUE} - , {82, 33, 8, SDL_ALPHA_OPAQUE} - , - {82, 41, 8, SDL_ALPHA_OPAQUE} - , {82, 49, 16, SDL_ALPHA_OPAQUE} - , {82, 82, 82, SDL_ALPHA_OPAQUE} - , {90, 41, 8, SDL_ALPHA_OPAQUE} - , - {90, 41, 16, SDL_ALPHA_OPAQUE} - , {90, 57, 24, SDL_ALPHA_OPAQUE} - , {99, 49, 16, SDL_ALPHA_OPAQUE} - , {99, 66, 24, SDL_ALPHA_OPAQUE} - , - {99, 66, 33, SDL_ALPHA_OPAQUE} - , {99, 74, 33, SDL_ALPHA_OPAQUE} - , {107, 57, 24, SDL_ALPHA_OPAQUE} - , {107, 82, 41, SDL_ALPHA_OPAQUE} - , - {115, 57, 33, SDL_ALPHA_OPAQUE} - , {115, 66, 33, SDL_ALPHA_OPAQUE} - , {115, 66, 41, SDL_ALPHA_OPAQUE} - , {115, 74, 0, SDL_ALPHA_OPAQUE} - , - {115, 90, 49, SDL_ALPHA_OPAQUE} - , {115, 115, 115, SDL_ALPHA_OPAQUE} - , {123, 82, 0, SDL_ALPHA_OPAQUE} - , {123, 99, 57, SDL_ALPHA_OPAQUE} - , - {132, 66, 41, SDL_ALPHA_OPAQUE} - , {132, 74, 41, SDL_ALPHA_OPAQUE} - , {132, 90, 8, SDL_ALPHA_OPAQUE} - , {132, 99, 33, SDL_ALPHA_OPAQUE} - , - {132, 99, 66, SDL_ALPHA_OPAQUE} - , {132, 107, 66, SDL_ALPHA_OPAQUE} - , {140, 74, 49, SDL_ALPHA_OPAQUE} - , {140, 99, 16, SDL_ALPHA_OPAQUE} - , - {140, 107, 74, SDL_ALPHA_OPAQUE} - , {140, 115, 74, SDL_ALPHA_OPAQUE} - , {148, 107, 24, SDL_ALPHA_OPAQUE} - , {148, 115, 82, SDL_ALPHA_OPAQUE} - , - {148, 123, 74, SDL_ALPHA_OPAQUE} - , {148, 123, 90, SDL_ALPHA_OPAQUE} - , {156, 115, 33, SDL_ALPHA_OPAQUE} - , {156, 115, 90, SDL_ALPHA_OPAQUE} - , - {156, 123, 82, SDL_ALPHA_OPAQUE} - , {156, 132, 82, SDL_ALPHA_OPAQUE} - , {156, 132, 99, SDL_ALPHA_OPAQUE} - , {156, 156, 156, SDL_ALPHA_OPAQUE} - , - {165, 123, 49, SDL_ALPHA_OPAQUE} - , {165, 123, 90, SDL_ALPHA_OPAQUE} - , {165, 132, 82, SDL_ALPHA_OPAQUE} - , {165, 132, 90, SDL_ALPHA_OPAQUE} - , - {165, 132, 99, SDL_ALPHA_OPAQUE} - , {165, 140, 90, SDL_ALPHA_OPAQUE} - , {173, 132, 57, SDL_ALPHA_OPAQUE} - , {173, 132, 99, SDL_ALPHA_OPAQUE} - , - {173, 140, 107, SDL_ALPHA_OPAQUE} - , {173, 140, 115, SDL_ALPHA_OPAQUE} - , {173, 148, 99, SDL_ALPHA_OPAQUE} - , {173, 173, 173, SDL_ALPHA_OPAQUE} - , - {181, 140, 74, SDL_ALPHA_OPAQUE} - , {181, 148, 115, SDL_ALPHA_OPAQUE} - , {181, 148, 123, SDL_ALPHA_OPAQUE} - , {181, 156, 107, SDL_ALPHA_OPAQUE} - , - {189, 148, 123, SDL_ALPHA_OPAQUE} - , {189, 156, 82, SDL_ALPHA_OPAQUE} - , {189, 156, 123, SDL_ALPHA_OPAQUE} - , {189, 156, 132, SDL_ALPHA_OPAQUE} - , - {189, 189, 189, SDL_ALPHA_OPAQUE} - , {198, 156, 123, SDL_ALPHA_OPAQUE} - , {198, 165, 132, SDL_ALPHA_OPAQUE} - , {206, 165, 99, SDL_ALPHA_OPAQUE} - , - {206, 165, 132, SDL_ALPHA_OPAQUE} - , {206, 173, 140, SDL_ALPHA_OPAQUE} - , {206, 206, 206, SDL_ALPHA_OPAQUE} - , {214, 173, 115, SDL_ALPHA_OPAQUE} - , - {214, 173, 140, SDL_ALPHA_OPAQUE} - , {222, 181, 148, SDL_ALPHA_OPAQUE} - , {222, 189, 132, SDL_ALPHA_OPAQUE} - , {222, 189, 156, SDL_ALPHA_OPAQUE} - , - {222, 222, 222, SDL_ALPHA_OPAQUE} - , {231, 198, 165, SDL_ALPHA_OPAQUE} - , {231, 231, 231, SDL_ALPHA_OPAQUE} - , {239, 206, 173, SDL_ALPHA_OPAQUE} -}; - -Uint8 MooseFrame[MOOSEFRAMES_COUNT][MOOSEFRAME_SIZE*2]; -SDL_Texture *MooseTexture; -SDL_Rect displayrect; -int window_w; -int window_h; -SDL_Window *window; -SDL_Renderer *renderer; -int paused = 0; -int i; -SDL_bool done = SDL_FALSE; -static int fpsdelay; - -/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ -static void -quit(int rc) -{ - SDL_Quit(); - exit(rc); -} - -static void -PrintUsage(char *argv0) -{ - SDL_Log("Usage: %s [arg] [arg] [arg] ...\n", argv0); - SDL_Log("\n"); - SDL_Log("Where 'arg' is any of the following options:\n"); - SDL_Log("\n"); - SDL_Log(" -fps \n"); - SDL_Log(" -nodelay\n"); - SDL_Log(" -format (one of the: YV12, IYUV, YUY2, UYVY, YVYU)\n"); - SDL_Log(" -scale (initial scale of the overlay)\n"); - SDL_Log(" -help (shows this help)\n"); - SDL_Log("\n"); - SDL_Log("Press ESC to exit, or SPACE to freeze the movie while application running.\n"); - SDL_Log("\n"); -} - -void -loop() -{ - SDL_Event event; - - while (SDL_PollEvent(&event)) { - switch (event.type) { - case SDL_WINDOWEVENT: - if (event.window.event == SDL_WINDOWEVENT_RESIZED) { - SDL_RenderSetViewport(renderer, NULL); - displayrect.w = window_w = event.window.data1; - displayrect.h = window_h = event.window.data2; - } - break; - case SDL_MOUSEBUTTONDOWN: - displayrect.x = event.button.x - window_w / 2; - displayrect.y = event.button.y - window_h / 2; - break; - case SDL_MOUSEMOTION: - if (event.motion.state) { - displayrect.x = event.motion.x - window_w / 2; - displayrect.y = event.motion.y - window_h / 2; - } - break; - case SDL_KEYDOWN: - if (event.key.keysym.sym == SDLK_SPACE) { - paused = !paused; - break; - } - if (event.key.keysym.sym != SDLK_ESCAPE) { - break; - } - case SDL_QUIT: - done = SDL_TRUE; - break; - } - } - -#ifndef __EMSCRIPTEN__ - SDL_Delay(fpsdelay); -#endif - - if (!paused) { - i = (i + 1) % MOOSEFRAMES_COUNT; - - SDL_UpdateTexture(MooseTexture, NULL, MooseFrame[i], MOOSEPIC_W); - } - SDL_RenderClear(renderer); - SDL_RenderCopy(renderer, MooseTexture, NULL, &displayrect); - SDL_RenderPresent(renderer); - -#ifdef __EMSCRIPTEN__ - if (done) { - emscripten_cancel_main_loop(); - } -#endif -} - -int -main(int argc, char **argv) -{ - Uint8 *RawMooseData; - SDL_RWops *handle; - SDL_Window *window; - int j; - int fps = 12; - int nodelay = 0; - int scale = 5; - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - if (SDL_Init(SDL_INIT_VIDEO) < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError()); - return 3; - } - - while (argc > 1) { - if (SDL_strcmp(argv[1], "-fps") == 0) { - if (argv[2]) { - fps = SDL_atoi(argv[2]); - if (fps == 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "The -fps option requires an argument [from 1 to 1000], default is 12.\n"); - quit(10); - } - if ((fps < 0) || (fps > 1000)) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "The -fps option must be in range from 1 to 1000, default is 12.\n"); - quit(10); - } - argv += 2; - argc -= 2; - } else { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "The -fps option requires an argument [from 1 to 1000], default is 12.\n"); - quit(10); - } - } else if (SDL_strcmp(argv[1], "-nodelay") == 0) { - nodelay = 1; - argv += 1; - argc -= 1; - } else if (SDL_strcmp(argv[1], "-scale") == 0) { - if (argv[2]) { - scale = SDL_atoi(argv[2]); - if (scale == 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "The -scale option requires an argument [from 1 to 50], default is 5.\n"); - quit(10); - } - if ((scale < 0) || (scale > 50)) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "The -scale option must be in range from 1 to 50, default is 5.\n"); - quit(10); - } - argv += 2; - argc -= 2; - } else { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "The -fps option requires an argument [from 1 to 1000], default is 12.\n"); - quit(10); - } - } else if ((SDL_strcmp(argv[1], "-help") == 0) - || (SDL_strcmp(argv[1], "-h") == 0)) { - PrintUsage(argv[0]); - quit(0); - } else { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unrecognized option: %s.\n", argv[1]); - quit(10); - } - break; - } - - RawMooseData = (Uint8 *) SDL_malloc(MOOSEFRAME_SIZE * MOOSEFRAMES_COUNT); - if (RawMooseData == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Can't allocate memory for movie !\n"); - quit(1); - } - - /* load the trojan moose images */ - handle = SDL_RWFromFile("moose.dat", "rb"); - if (handle == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Can't find the file moose.dat !\n"); - SDL_free(RawMooseData); - quit(2); - } - - SDL_RWread(handle, RawMooseData, MOOSEFRAME_SIZE, MOOSEFRAMES_COUNT); - - SDL_RWclose(handle); - - /* Create the window and renderer */ - window_w = MOOSEPIC_W * scale; - window_h = MOOSEPIC_H * scale; - window = SDL_CreateWindow("Happy Moose", - SDL_WINDOWPOS_UNDEFINED, - SDL_WINDOWPOS_UNDEFINED, - window_w, window_h, - SDL_WINDOW_RESIZABLE); - if (!window) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't set create window: %s\n", SDL_GetError()); - SDL_free(RawMooseData); - quit(4); - } - - renderer = SDL_CreateRenderer(window, -1, 0); - if (!renderer) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't set create renderer: %s\n", SDL_GetError()); - SDL_free(RawMooseData); - quit(4); - } - - MooseTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_YV12, SDL_TEXTUREACCESS_STREAMING, MOOSEPIC_W, MOOSEPIC_H); - if (!MooseTexture) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't set create texture: %s\n", SDL_GetError()); - SDL_free(RawMooseData); - quit(5); - } - /* Uncomment this to check vertex color with a YUV texture */ - /* SDL_SetTextureColorMod(MooseTexture, 0xff, 0x80, 0x80); */ - - for (i = 0; i < MOOSEFRAMES_COUNT; i++) { - Uint8 MooseFrameRGB[MOOSEFRAME_SIZE*3]; - Uint8 *rgb; - Uint8 *frame; - - rgb = MooseFrameRGB; - frame = RawMooseData + i * MOOSEFRAME_SIZE; - for (j = 0; j < MOOSEFRAME_SIZE; ++j) { - rgb[0] = MooseColors[frame[j]].r; - rgb[1] = MooseColors[frame[j]].g; - rgb[2] = MooseColors[frame[j]].b; - rgb += 3; - } - ConvertRGBtoYUV(SDL_PIXELFORMAT_YV12, MooseFrameRGB, MOOSEPIC_W*3, MooseFrame[i], MOOSEPIC_W, MOOSEPIC_H, - SDL_GetYUVConversionModeForResolution(MOOSEPIC_W, MOOSEPIC_H), - 0, 100); - } - - SDL_free(RawMooseData); - - /* set the start frame */ - i = 0; - if (nodelay) { - fpsdelay = 0; - } else { - fpsdelay = 1000 / fps; - } - - displayrect.x = 0; - displayrect.y = 0; - displayrect.w = window_w; - displayrect.h = window_h; - - /* Ignore key up events, they don't even get filtered */ - SDL_EventState(SDL_KEYUP, SDL_IGNORE); - - /* Loop, waiting for QUIT or RESIZE */ -#ifdef __EMSCRIPTEN__ - emscripten_set_main_loop(loop, nodelay ? 0 : fps, 1); -#else - while (!done) { - loop(); - } -#endif - - SDL_DestroyRenderer(renderer); - quit(0); - return 0; -} - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/test/testplatform.c b/SDL2-2.0.12/test/testplatform.c deleted file mode 100644 index 9431577..0000000 --- a/SDL2-2.0.12/test/testplatform.c +++ /dev/null @@ -1,442 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ - -#include - -#include "SDL.h" - -/* - * Watcom C flags these as Warning 201: "Unreachable code" if you just - * compare them directly, so we push it through a function to keep the - * compiler quiet. --ryan. - */ -static int -badsize(size_t sizeoftype, size_t hardcodetype) -{ - return sizeoftype != hardcodetype; -} - -int -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", - (unsigned int)sizeof(Uint8)); - ++error; - } - if (badsize(sizeof(Uint16), 2)) { - if (verbose) - SDL_Log("sizeof(Uint16) != 2, instead = %u\n", - (unsigned int)sizeof(Uint16)); - ++error; - } - if (badsize(sizeof(Uint32), 4)) { - if (verbose) - SDL_Log("sizeof(Uint32) != 4, instead = %u\n", - (unsigned int)sizeof(Uint32)); - ++error; - } - if (badsize(sizeof(Uint64), 8)) { - if (verbose) - SDL_Log("sizeof(Uint64) != 8, instead = %u\n", - (unsigned int)sizeof(Uint64)); - ++error; - } - if (verbose && !error) - SDL_Log("All data types are the expected size.\n"); - - return (error ? 1 : 0); -} - -int -TestEndian(SDL_bool verbose) -{ - int error = 0; - Uint16 value = 0x1234; - int real_byteorder; - Uint16 value16 = 0xCDAB; - Uint16 swapped16 = 0xABCD; - Uint32 value32 = 0xEFBEADDE; - Uint32 swapped32 = 0xDEADBEEF; - Uint64 value64, swapped64; - - value64 = 0xEFBEADDE; - value64 <<= 32; - value64 |= 0xCDAB3412; - swapped64 = 0x1234ABCD; - swapped64 <<= 32; - swapped64 |= 0xDEADBEEF; - - if (verbose) { - SDL_Log("Detected a %s endian machine.\n", - (SDL_BYTEORDER == SDL_LIL_ENDIAN) ? "little" : "big"); - } - if ((*((char *) &value) >> 4) == 0x1) { - real_byteorder = SDL_BIG_ENDIAN; - } else { - real_byteorder = SDL_LIL_ENDIAN; - } - if (real_byteorder != SDL_BYTEORDER) { - if (verbose) { - SDL_Log("Actually a %s endian machine!\n", - (real_byteorder == SDL_LIL_ENDIAN) ? "little" : "big"); - } - ++error; - } - if (verbose) { - SDL_Log("Value 16 = 0x%X, swapped = 0x%X\n", value16, - SDL_Swap16(value16)); - } - if (SDL_Swap16(value16) != swapped16) { - if (verbose) { - SDL_Log("16 bit value swapped incorrectly!\n"); - } - ++error; - } - if (verbose) { - SDL_Log("Value 32 = 0x%X, swapped = 0x%X\n", value32, - SDL_Swap32(value32)); - } - if (SDL_Swap32(value32) != swapped32) { - if (verbose) { - SDL_Log("32 bit value swapped incorrectly!\n"); - } - ++error; - } - if (verbose) { - SDL_Log("Value 64 = 0x%"SDL_PRIX64", swapped = 0x%"SDL_PRIX64"\n", value64, - SDL_Swap64(value64)); - } - if (SDL_Swap64(value64) != swapped64) { - if (verbose) { - SDL_Log("64 bit value swapped incorrectly!\n"); - } - ++error; - } - return (error ? 1 : 0); -} - -static int TST_allmul (void *a, void *b, int arg, void *result, void *expected) -{ - (*(long long *)result) = ((*(long long *)a) * (*(long long *)b)); - return (*(long long *)result) == (*(long long *)expected); -} - -static int TST_alldiv (void *a, void *b, int arg, void *result, void *expected) -{ - (*(long long *)result) = ((*(long long *)a) / (*(long long *)b)); - return (*(long long *)result) == (*(long long *)expected); -} - -static int TST_allrem (void *a, void *b, int arg, void *result, void *expected) -{ - (*(long long *)result) = ((*(long long *)a) % (*(long long *)b)); - return (*(long long *)result) == (*(long long *)expected); -} - -static int TST_ualldiv (void *a, void *b, int arg, void *result, void *expected) -{ - (*(unsigned long long *)result) = ((*(unsigned long long *)a) / (*(unsigned long long *)b)); - return (*(unsigned long long *)result) == (*(unsigned long long *)expected); -} - -static int TST_uallrem (void *a, void *b, int arg, void *result, void *expected) -{ - (*(unsigned long long *)result) = ((*(unsigned long long *)a) % (*(unsigned long long *)b)); - return (*(unsigned long long *)result) == (*(unsigned long long *)expected); -} - -static int TST_allshl (void *a, void *b, int arg, void *result, void *expected) -{ - (*(long long *)result) = (*(long long *)a) << arg; - return (*(long long *)result) == (*(long long *)expected); -} - -static int TST_aullshl (void *a, void *b, int arg, void *result, void *expected) -{ - (*(unsigned long long *)result) = (*(unsigned long long *)a) << arg; - return (*(unsigned long long *)result) == (*(unsigned long long *)expected); -} - -static int TST_allshr (void *a, void *b, int arg, void *result, void *expected) -{ - (*(long long *)result) = (*(long long *)a) >> arg; - return (*(long long *)result) == (*(long long *)expected); -} - -static int TST_aullshr (void *a, void *b, int arg, void *result, void *expected) -{ - (*(unsigned long long *)result) = (*(unsigned long long *)a) >> arg; - return (*(unsigned long long *)result) == (*(unsigned long long *)expected); -} - - -typedef int (*LL_Intrinsic)(void *a, void *b, int arg, void *result, void *expected); - -typedef struct { - const char *operation; - LL_Intrinsic routine; - unsigned long long a, b; - int arg; - unsigned long long expected_result; -} LL_Test; - -static LL_Test LL_Tests[] = -{ - /* UNDEFINED {"_allshl", &TST_allshl, 0xFFFFFFFFFFFFFFFFll, 0ll, 65, 0x0000000000000000ll}, */ - {"_allshl", &TST_allshl, 0xFFFFFFFFFFFFFFFFll, 0ll, 1, 0xFFFFFFFFFFFFFFFEll}, - {"_allshl", &TST_allshl, 0xFFFFFFFFFFFFFFFFll, 0ll, 32, 0xFFFFFFFF00000000ll}, - {"_allshl", &TST_allshl, 0xFFFFFFFFFFFFFFFFll, 0ll, 33, 0xFFFFFFFE00000000ll}, - {"_allshl", &TST_allshl, 0xFFFFFFFFFFFFFFFFll, 0ll, 0, 0xFFFFFFFFFFFFFFFFll}, - - {"_allshr", &TST_allshr, 0xAAAAAAAA55555555ll, 0ll, 63, 0xFFFFFFFFFFFFFFFFll}, - /* UNDEFINED {"_allshr", &TST_allshr, 0xFFFFFFFFFFFFFFFFll, 0ll, 65, 0xFFFFFFFFFFFFFFFFll}, */ - {"_allshr", &TST_allshr, 0xFFFFFFFFFFFFFFFFll, 0ll, 1, 0xFFFFFFFFFFFFFFFFll}, - {"_allshr", &TST_allshr, 0xFFFFFFFFFFFFFFFFll, 0ll, 32, 0xFFFFFFFFFFFFFFFFll}, - {"_allshr", &TST_allshr, 0xFFFFFFFFFFFFFFFFll, 0ll, 33, 0xFFFFFFFFFFFFFFFFll}, - {"_allshr", &TST_allshr, 0xFFFFFFFFFFFFFFFFll, 0ll, 0, 0xFFFFFFFFFFFFFFFFll}, - /* UNDEFINED {"_allshr", &TST_allshr, 0x5F5F5F5F5F5F5F5Fll, 0ll, 65, 0x0000000000000000ll}, */ - {"_allshr", &TST_allshr, 0x5F5F5F5F5F5F5F5Fll, 0ll, 1, 0x2FAFAFAFAFAFAFAFll}, - {"_allshr", &TST_allshr, 0x5F5F5F5F5F5F5F5Fll, 0ll, 32, 0x000000005F5F5F5Fll}, - {"_allshr", &TST_allshr, 0x5F5F5F5F5F5F5F5Fll, 0ll, 33, 0x000000002FAFAFAFll}, - - /* UNDEFINED {"_aullshl", &TST_aullshl, 0xFFFFFFFFFFFFFFFFll, 0ll, 65, 0x0000000000000000ll}, */ - {"_aullshl", &TST_aullshl, 0xFFFFFFFFFFFFFFFFll, 0ll, 1, 0xFFFFFFFFFFFFFFFEll}, - {"_aullshl", &TST_aullshl, 0xFFFFFFFFFFFFFFFFll, 0ll, 32, 0xFFFFFFFF00000000ll}, - {"_aullshl", &TST_aullshl, 0xFFFFFFFFFFFFFFFFll, 0ll, 33, 0xFFFFFFFE00000000ll}, - {"_aullshl", &TST_aullshl, 0xFFFFFFFFFFFFFFFFll, 0ll, 0, 0xFFFFFFFFFFFFFFFFll}, - - /* UNDEFINED {"_aullshr", &TST_aullshr, 0xFFFFFFFFFFFFFFFFll, 0ll, 65, 0x0000000000000000ll}, */ - {"_aullshr", &TST_aullshr, 0xFFFFFFFFFFFFFFFFll, 0ll, 1, 0x7FFFFFFFFFFFFFFFll}, - {"_aullshr", &TST_aullshr, 0xFFFFFFFFFFFFFFFFll, 0ll, 32, 0x00000000FFFFFFFFll}, - {"_aullshr", &TST_aullshr, 0xFFFFFFFFFFFFFFFFll, 0ll, 33, 0x000000007FFFFFFFll}, - {"_aullshr", &TST_aullshr, 0xFFFFFFFFFFFFFFFFll, 0ll, 0, 0xFFFFFFFFFFFFFFFFll}, - - {"_allmul", &TST_allmul, 0xFFFFFFFFFFFFFFFFll, 0x0000000000000000ll, 0, 0x0000000000000000ll}, - {"_allmul", &TST_allmul, 0x0000000000000000ll, 0xFFFFFFFFFFFFFFFFll, 0, 0x0000000000000000ll}, - {"_allmul", &TST_allmul, 0x000000000FFFFFFFll, 0x0000000000000001ll, 0, 0x000000000FFFFFFFll}, - {"_allmul", &TST_allmul, 0x0000000000000001ll, 0x000000000FFFFFFFll, 0, 0x000000000FFFFFFFll}, - {"_allmul", &TST_allmul, 0x000000000FFFFFFFll, 0x0000000000000010ll, 0, 0x00000000FFFFFFF0ll}, - {"_allmul", &TST_allmul, 0x0000000000000010ll, 0x000000000FFFFFFFll, 0, 0x00000000FFFFFFF0ll}, - {"_allmul", &TST_allmul, 0x000000000FFFFFFFll, 0x0000000000000100ll, 0, 0x0000000FFFFFFF00ll}, - {"_allmul", &TST_allmul, 0x0000000000000100ll, 0x000000000FFFFFFFll, 0, 0x0000000FFFFFFF00ll}, - {"_allmul", &TST_allmul, 0x000000000FFFFFFFll, 0x0000000010000000ll, 0, 0x00FFFFFFF0000000ll}, - {"_allmul", &TST_allmul, 0x0000000010000000ll, 0x000000000FFFFFFFll, 0, 0x00FFFFFFF0000000ll}, - {"_allmul", &TST_allmul, 0x000000000FFFFFFFll, 0x0000000080000000ll, 0, 0x07FFFFFF80000000ll}, - {"_allmul", &TST_allmul, 0x0000000080000000ll, 0x000000000FFFFFFFll, 0, 0x07FFFFFF80000000ll}, - {"_allmul", &TST_allmul, 0xFFFFFFFFFFFFFFFEll, 0x0000000080000000ll, 0, 0xFFFFFFFF00000000ll}, - {"_allmul", &TST_allmul, 0x0000000080000000ll, 0xFFFFFFFFFFFFFFFEll, 0, 0xFFFFFFFF00000000ll}, - {"_allmul", &TST_allmul, 0xFFFFFFFFFFFFFFFEll, 0x0000000080000008ll, 0, 0xFFFFFFFEFFFFFFF0ll}, - {"_allmul", &TST_allmul, 0x0000000080000008ll, 0xFFFFFFFFFFFFFFFEll, 0, 0xFFFFFFFEFFFFFFF0ll}, - {"_allmul", &TST_allmul, 0x00000000FFFFFFFFll, 0x00000000FFFFFFFFll, 0, 0xFFFFFFFE00000001ll}, - - {"_alldiv", &TST_alldiv, 0x0000000000000000ll, 0x0000000000000001ll, 0, 0x0000000000000000ll}, - {"_alldiv", &TST_alldiv, 0x0000000000000000ll, 0xFFFFFFFFFFFFFFFFll, 0, 0x0000000000000000ll}, - {"_alldiv", &TST_alldiv, 0x0000000000000001ll, 0xFFFFFFFFFFFFFFFFll, 0, 0xFFFFFFFFFFFFFFFFll}, - {"_alldiv", &TST_alldiv, 0xFFFFFFFFFFFFFFFFll, 0x0000000000000001ll, 0, 0xFFFFFFFFFFFFFFFFll}, - {"_alldiv", &TST_alldiv, 0x0000000000000001ll, 0xFFFFFFFFFFFFFFFFll, 0, 0xFFFFFFFFFFFFFFFFll}, - {"_alldiv", &TST_alldiv, 0x0000000000000001ll, 0x0000000000000001ll, 0, 0x0000000000000001ll}, - {"_alldiv", &TST_alldiv, 0xFFFFFFFFFFFFFFFFll, 0xFFFFFFFFFFFFFFFFll, 0, 0x0000000000000001ll}, - {"_alldiv", &TST_alldiv, 0x000000000FFFFFFFll, 0x0000000000000001ll, 0, 0x000000000FFFFFFFll}, - {"_alldiv", &TST_alldiv, 0x0000000FFFFFFFFFll, 0x0000000000000010ll, 0, 0x00000000FFFFFFFFll}, - {"_alldiv", &TST_alldiv, 0x0000000000000100ll, 0x000000000FFFFFFFll, 0, 0x0000000000000000ll}, - {"_alldiv", &TST_alldiv, 0x00FFFFFFF0000000ll, 0x0000000010000000ll, 0, 0x000000000FFFFFFFll}, - {"_alldiv", &TST_alldiv, 0x07FFFFFF80000000ll, 0x0000000080000000ll, 0, 0x000000000FFFFFFFll}, - {"_alldiv", &TST_alldiv, 0xFFFFFFFFFFFFFFFEll, 0x0000000080000000ll, 0, 0x0000000000000000ll}, - {"_alldiv", &TST_alldiv, 0xFFFFFFFEFFFFFFF0ll, 0xFFFFFFFFFFFFFFFEll, 0, 0x0000000080000008ll}, - {"_alldiv", &TST_alldiv, 0x7FFFFFFEFFFFFFF0ll, 0xFFFFFFFFFFFFFFFEll, 0, 0xC000000080000008ll}, - {"_alldiv", &TST_alldiv, 0x7FFFFFFEFFFFFFF0ll, 0x0000FFFFFFFFFFFEll, 0, 0x0000000000007FFFll}, - {"_alldiv", &TST_alldiv, 0x7FFFFFFEFFFFFFF0ll, 0x7FFFFFFEFFFFFFF0ll, 0, 0x0000000000000001ll}, - - {"_allrem", &TST_allrem, 0x0000000000000000ll, 0x0000000000000001ll, 0, 0x0000000000000000ll}, - {"_allrem", &TST_allrem, 0x0000000000000000ll, 0xFFFFFFFFFFFFFFFFll, 0, 0x0000000000000000ll}, - {"_allrem", &TST_allrem, 0x0000000000000001ll, 0xFFFFFFFFFFFFFFFFll, 0, 0x0000000000000000ll}, - {"_allrem", &TST_allrem, 0xFFFFFFFFFFFFFFFFll, 0x0000000000000001ll, 0, 0x0000000000000000ll}, - {"_allrem", &TST_allrem, 0x0000000000000001ll, 0xFFFFFFFFFFFFFFFFll, 0, 0x0000000000000000ll}, - {"_allrem", &TST_allrem, 0x0000000000000001ll, 0x0000000000000001ll, 0, 0x0000000000000000ll}, - {"_allrem", &TST_allrem, 0xFFFFFFFFFFFFFFFFll, 0xFFFFFFFFFFFFFFFFll, 0, 0x0000000000000000ll}, - {"_allrem", &TST_allrem, 0x000000000FFFFFFFll, 0x0000000000000001ll, 0, 0x0000000000000000ll}, - {"_allrem", &TST_allrem, 0x0000000FFFFFFFFFll, 0x0000000000000010ll, 0, 0x000000000000000Fll}, - {"_allrem", &TST_allrem, 0x0000000000000100ll, 0x000000000FFFFFFFll, 0, 0x0000000000000100ll}, - {"_allrem", &TST_allrem, 0x00FFFFFFF0000000ll, 0x0000000010000000ll, 0, 0x0000000000000000ll}, - {"_allrem", &TST_allrem, 0x07FFFFFF80000000ll, 0x0000000080000000ll, 0, 0x0000000000000000ll}, - {"_allrem", &TST_allrem, 0xFFFFFFFFFFFFFFFEll, 0x0000000080000000ll, 0, 0xFFFFFFFFFFFFFFFEll}, - {"_allrem", &TST_allrem, 0xFFFFFFFEFFFFFFF0ll, 0xFFFFFFFFFFFFFFFEll, 0, 0x0000000000000000ll}, - {"_allrem", &TST_allrem, 0x7FFFFFFEFFFFFFF0ll, 0xFFFFFFFFFFFFFFFEll, 0, 0x0000000000000000ll}, - {"_allrem", &TST_allrem, 0x7FFFFFFEFFFFFFF0ll, 0x0000FFFFFFFFFFFEll, 0, 0x0000FFFF0000FFEEll}, - {"_allrem", &TST_allrem, 0x7FFFFFFEFFFFFFF0ll, 0x7FFFFFFEFFFFFFF0ll, 0, 0x0000000000000000ll}, - - - {"_ualldiv", &TST_ualldiv, 0x0000000000000000ll, 0x0000000000000001ll, 0, 0x0000000000000000ll}, - {"_ualldiv", &TST_ualldiv, 0x0000000000000000ll, 0xFFFFFFFFFFFFFFFFll, 0, 0x0000000000000000ll}, - {"_ualldiv", &TST_ualldiv, 0x0000000000000001ll, 0xFFFFFFFFFFFFFFFFll, 0, 0x0000000000000000ll}, - {"_ualldiv", &TST_ualldiv, 0xFFFFFFFFFFFFFFFFll, 0x0000000000000001ll, 0, 0xFFFFFFFFFFFFFFFFll}, - {"_ualldiv", &TST_ualldiv, 0x0000000000000001ll, 0xFFFFFFFFFFFFFFFFll, 0, 0x0000000000000000ll}, - {"_ualldiv", &TST_ualldiv, 0x0000000000000001ll, 0x0000000000000001ll, 0, 0x0000000000000001ll}, - {"_ualldiv", &TST_ualldiv, 0xFFFFFFFFFFFFFFFFll, 0xFFFFFFFFFFFFFFFFll, 0, 0x0000000000000001ll}, - {"_ualldiv", &TST_ualldiv, 0x000000000FFFFFFFll, 0x0000000000000001ll, 0, 0x000000000FFFFFFFll}, - {"_ualldiv", &TST_ualldiv, 0x0000000FFFFFFFFFll, 0x0000000000000010ll, 0, 0x00000000FFFFFFFFll}, - {"_ualldiv", &TST_ualldiv, 0x0000000000000100ll, 0x000000000FFFFFFFll, 0, 0x0000000000000000ll}, - {"_ualldiv", &TST_ualldiv, 0x00FFFFFFF0000000ll, 0x0000000010000000ll, 0, 0x000000000FFFFFFFll}, - {"_ualldiv", &TST_ualldiv, 0x07FFFFFF80000000ll, 0x0000000080000000ll, 0, 0x000000000FFFFFFFll}, - {"_ualldiv", &TST_ualldiv, 0xFFFFFFFFFFFFFFFEll, 0x0000000080000000ll, 0, 0x00000001FFFFFFFFll}, - {"_ualldiv", &TST_ualldiv, 0xFFFFFFFEFFFFFFF0ll, 0xFFFFFFFFFFFFFFFEll, 0, 0x0000000000000000ll}, - {"_ualldiv", &TST_ualldiv, 0x7FFFFFFEFFFFFFF0ll, 0xFFFFFFFFFFFFFFFEll, 0, 0x0000000000000000ll}, - {"_ualldiv", &TST_ualldiv, 0x7FFFFFFEFFFFFFF0ll, 0x0000FFFFFFFFFFFEll, 0, 0x0000000000007FFFll}, - {"_ualldiv", &TST_ualldiv, 0x7FFFFFFEFFFFFFF0ll, 0x7FFFFFFEFFFFFFF0ll, 0, 0x0000000000000001ll}, - - {"_uallrem", &TST_uallrem, 0x0000000000000000ll, 0x0000000000000001ll, 0, 0x0000000000000000ll}, - {"_uallrem", &TST_uallrem, 0x0000000000000000ll, 0xFFFFFFFFFFFFFFFFll, 0, 0x0000000000000000ll}, - {"_uallrem", &TST_uallrem, 0x0000000000000001ll, 0xFFFFFFFFFFFFFFFFll, 0, 0x0000000000000001ll}, - {"_uallrem", &TST_uallrem, 0xFFFFFFFFFFFFFFFFll, 0x0000000000000001ll, 0, 0x0000000000000000ll}, - {"_uallrem", &TST_uallrem, 0x0000000000000001ll, 0xFFFFFFFFFFFFFFFFll, 0, 0x0000000000000001ll}, - {"_uallrem", &TST_uallrem, 0x0000000000000001ll, 0x0000000000000001ll, 0, 0x0000000000000000ll}, - {"_uallrem", &TST_uallrem, 0xFFFFFFFFFFFFFFFFll, 0xFFFFFFFFFFFFFFFFll, 0, 0x0000000000000000ll}, - {"_uallrem", &TST_uallrem, 0x000000000FFFFFFFll, 0x0000000000000001ll, 0, 0x0000000000000000ll}, - {"_uallrem", &TST_uallrem, 0x0000000FFFFFFFFFll, 0x0000000000000010ll, 0, 0x000000000000000Fll}, - {"_uallrem", &TST_uallrem, 0x0000000000000100ll, 0x000000000FFFFFFFll, 0, 0x0000000000000100ll}, - {"_uallrem", &TST_uallrem, 0x00FFFFFFF0000000ll, 0x0000000010000000ll, 0, 0x0000000000000000ll}, - {"_uallrem", &TST_uallrem, 0x07FFFFFF80000000ll, 0x0000000080000000ll, 0, 0x0000000000000000ll}, - {"_uallrem", &TST_uallrem, 0xFFFFFFFFFFFFFFFEll, 0x0000000080000000ll, 0, 0x000000007FFFFFFEll}, - {"_uallrem", &TST_uallrem, 0xFFFFFFFEFFFFFFF0ll, 0xFFFFFFFFFFFFFFFEll, 0, 0xFFFFFFFEFFFFFFF0ll}, - {"_uallrem", &TST_uallrem, 0x7FFFFFFEFFFFFFF0ll, 0xFFFFFFFFFFFFFFFEll, 0, 0x7FFFFFFEFFFFFFF0ll}, - {"_uallrem", &TST_uallrem, 0x7FFFFFFEFFFFFFF0ll, 0x0000FFFFFFFFFFFEll, 0, 0x0000FFFF0000FFEEll}, - {"_uallrem", &TST_uallrem, 0x7FFFFFFEFFFFFFF0ll, 0x7FFFFFFEFFFFFFF0ll, 0, 0x0000000000000000ll}, - - {NULL} -}; - -int -Test64Bit (SDL_bool verbose) -{ - LL_Test *t; - int failed = 0; - - for (t = LL_Tests; t->routine != NULL; t++) { - unsigned long long result = 0; - unsigned int *al = (unsigned int *)&t->a; - unsigned int *bl = (unsigned int *)&t->b; - unsigned int *el = (unsigned int *)&t->expected_result; - unsigned int *rl = (unsigned int *)&result; - - if (!t->routine(&t->a, &t->b, t->arg, &result, &t->expected_result)) { - if (verbose) - SDL_Log("%s(0x%08X%08X, 0x%08X%08X, %3d, produced: 0x%08X%08X, expected: 0x%08X%08X\n", - t->operation, al[1], al[0], bl[1], bl[0], t->arg, rl[1], rl[0], el[1], el[0]); - ++failed; - } - } - if (verbose && (failed == 0)) - SDL_Log("All 64bit instrinsic tests passed\n"); - return (failed ? 1 : 0); -} - -int -TestCPUInfo(SDL_bool verbose) -{ - if (verbose) { - SDL_Log("CPU count: %d\n", SDL_GetCPUCount()); - SDL_Log("CPU cache line size: %d\n", SDL_GetCPUCacheLineSize()); - SDL_Log("RDTSC %s\n", SDL_HasRDTSC()? "detected" : "not detected"); - SDL_Log("AltiVec %s\n", SDL_HasAltiVec()? "detected" : "not detected"); - SDL_Log("MMX %s\n", SDL_HasMMX()? "detected" : "not detected"); - SDL_Log("3DNow! %s\n", SDL_Has3DNow()? "detected" : "not detected"); - SDL_Log("SSE %s\n", SDL_HasSSE()? "detected" : "not detected"); - SDL_Log("SSE2 %s\n", SDL_HasSSE2()? "detected" : "not detected"); - SDL_Log("SSE3 %s\n", SDL_HasSSE3()? "detected" : "not detected"); - SDL_Log("SSE4.1 %s\n", SDL_HasSSE41()? "detected" : "not detected"); - SDL_Log("SSE4.2 %s\n", SDL_HasSSE42()? "detected" : "not detected"); - SDL_Log("AVX %s\n", SDL_HasAVX()? "detected" : "not detected"); - SDL_Log("AVX2 %s\n", SDL_HasAVX2()? "detected" : "not detected"); - SDL_Log("AVX-512F %s\n", SDL_HasAVX512F()? "detected" : "not detected"); - SDL_Log("NEON %s\n", SDL_HasNEON()? "detected" : "not detected"); - SDL_Log("System RAM %d MB\n", SDL_GetSystemRAM()); - } - return (0); -} - -int -TestAssertions(SDL_bool verbose) -{ - SDL_assert(1); - SDL_assert_release(1); - SDL_assert_paranoid(1); - SDL_assert(0 || 1); - SDL_assert_release(0 || 1); - SDL_assert_paranoid(0 || 1); - -#if 0 /* enable this to test assertion failures. */ - SDL_assert_release(1 == 2); - SDL_assert_release(5 < 4); - SDL_assert_release(0 && "This is a test"); -#endif - - { - const SDL_AssertData *item = SDL_GetAssertionReport(); - while (item) { - SDL_Log("'%s', %s (%s:%d), triggered %u times, always ignore: %s.\n", - item->condition, item->function, item->filename, - item->linenum, item->trigger_count, - item->always_ignore ? "yes" : "no"); - item = item->next; - } - } - return (0); -} - -int -main(int argc, char *argv[]) -{ - SDL_bool verbose = SDL_TRUE; - int status = 0; - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - if (argv[1] && (SDL_strcmp(argv[1], "-q") == 0)) { - verbose = SDL_FALSE; - } - if (verbose) { - SDL_Log("This system is running %s\n", SDL_GetPlatform()); - } - - status += TestTypes(verbose); - status += TestEndian(verbose); - status += Test64Bit(verbose); - status += TestCPUInfo(verbose); - status += TestAssertions(verbose); - - return status; -} diff --git a/SDL2-2.0.12/test/testpower.c b/SDL2-2.0.12/test/testpower.c deleted file mode 100644 index 841d605..0000000 --- a/SDL2-2.0.12/test/testpower.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ -/* Simple test of power subsystem. */ - -#include -#include "SDL.h" - -static void -report_power(void) -{ - int seconds, percent; - const SDL_PowerState state = SDL_GetPowerInfo(&seconds, &percent); - char *statestr = NULL; - - SDL_Log("SDL-reported power info...\n"); - switch (state) { - case SDL_POWERSTATE_UNKNOWN: - statestr = "Unknown"; - break; - case SDL_POWERSTATE_ON_BATTERY: - statestr = "On battery"; - break; - case SDL_POWERSTATE_NO_BATTERY: - statestr = "No battery"; - break; - case SDL_POWERSTATE_CHARGING: - statestr = "Charging"; - break; - case SDL_POWERSTATE_CHARGED: - statestr = "Charged"; - break; - default: - statestr = "!!API ERROR!!"; - break; - } - - SDL_Log("State: %s\n", statestr); - - if (percent == -1) { - SDL_Log("Percent left: unknown\n"); - } else { - SDL_Log("Percent left: %d%%\n", percent); - } - - if (seconds == -1) { - SDL_Log("Time left: unknown\n"); - } else { - SDL_Log("Time left: %d minutes, %d seconds\n", (int) (seconds / 60), - (int) (seconds % 60)); - } -} - - -int -main(int argc, char *argv[]) -{ - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - if (SDL_Init(0) == -1) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_Init() failed: %s\n", SDL_GetError()); - return 1; - } - - report_power(); - - SDL_Quit(); - return 0; -} - -/* end of testpower.c ... */ diff --git a/SDL2-2.0.12/test/testqsort.c b/SDL2-2.0.12/test/testqsort.c deleted file mode 100644 index 073a5c5..0000000 --- a/SDL2-2.0.12/test/testqsort.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ - -#include "SDL_test.h" - -static int -num_compare(const void *_a, const void *_b) -{ - const int a = *((const int *) _a); - const int b = *((const int *) _b); - return (a < b) ? -1 : ((a > b) ? 1 : 0); -} - -static void -test_sort(const char *desc, int *nums, const int arraylen) -{ - int i; - int prev; - - SDL_Log("test: %s arraylen=%d", desc, arraylen); - - SDL_qsort(nums, arraylen, sizeof (nums[0]), num_compare); - - prev = nums[0]; - for (i = 1; i < arraylen; i++) { - const int val = nums[i]; - if (val < prev) { - SDL_Log("sort is broken!"); - return; - } - prev = val; - } -} - -int -main(int argc, char *argv[]) -{ - static int nums[1024 * 100]; - static const int itervals[] = { SDL_arraysize(nums), 12 }; - int iteration; - SDLTest_RandomContext rndctx; - - if (argc > 1) - { - int success; - Uint64 seed = 0; - if (argv[1][0] == '0' && argv[1][1] == 'x') - success = SDL_sscanf(argv[1] + 2, "%llx", &seed); - else - success = SDL_sscanf(argv[1], "%llu", &seed); - if (!success) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Invalid seed. Use a decimal or hexadecimal number.\n"); - return 1; - } - if (seed <= ((Uint64)0xffffffff)) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Seed must be equal or greater than 0x100000000.\n"); - return 1; - } - SDLTest_RandomInit(&rndctx, (unsigned int)(seed >> 32), (unsigned int)(seed & 0xffffffff)); - } - else - { - SDLTest_RandomInitTime(&rndctx); - } - SDL_Log("Using random seed 0x%08x%08x\n", rndctx.x, rndctx.c); - - for (iteration = 0; iteration < SDL_arraysize(itervals); iteration++) { - const int arraylen = itervals[iteration]; - int i; - - for (i = 0; i < arraylen; i++) { - nums[i] = i; - } - test_sort("already sorted", nums, arraylen); - - for (i = 0; i < arraylen; i++) { - nums[i] = i; - } - nums[arraylen-1] = -1; - test_sort("already sorted except last element", nums, arraylen); - - for (i = 0; i < arraylen; i++) { - nums[i] = (arraylen-1) - i; - } - test_sort("reverse sorted", nums, arraylen); - - for (i = 0; i < arraylen; i++) { - nums[i] = SDLTest_RandomInt(&rndctx); - } - test_sort("random sorted", nums, arraylen); - } - - return 0; -} - -/* vi: set ts=4 sw=4 expandtab: */ - diff --git a/SDL2-2.0.12/test/testrelative.c b/SDL2-2.0.12/test/testrelative.c deleted file mode 100644 index 52566f7..0000000 --- a/SDL2-2.0.12/test/testrelative.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ - -/* Simple program: Test relative mouse motion */ - -#include -#include -#include - -#include "SDL_test_common.h" - -#ifdef __EMSCRIPTEN__ -#include -#endif - -static SDLTest_CommonState *state; -int i, done; -SDL_Rect rect; -SDL_Event event; - -static void -DrawRects(SDL_Renderer * renderer, SDL_Rect * rect) -{ - SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); - SDL_RenderFillRect(renderer, rect); -} - -static void -loop(){ - /* Check for events */ - while (SDL_PollEvent(&event)) { - SDLTest_CommonEvent(state, &event, &done); - switch(event.type) { - case SDL_MOUSEMOTION: - { - rect.x += event.motion.xrel; - rect.y += event.motion.yrel; - } - break; - } - } - for (i = 0; i < state->num_windows; ++i) { - SDL_Rect viewport; - SDL_Renderer *renderer = state->renderers[i]; - if (state->windows[i] == NULL) - continue; - SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF); - SDL_RenderClear(renderer); - - /* Wrap the cursor rectangle at the screen edges to keep it visible */ - SDL_RenderGetViewport(renderer, &viewport); - if (rect.x < viewport.x) rect.x += viewport.w; - if (rect.y < viewport.y) rect.y += viewport.h; - if (rect.x > viewport.x + viewport.w) rect.x -= viewport.w; - if (rect.y > viewport.y + viewport.h) rect.y -= viewport.h; - - DrawRects(renderer, &rect); - - SDL_RenderPresent(renderer); - } -#ifdef __EMSCRIPTEN__ - if (done) { - emscripten_cancel_main_loop(); - } -#endif -} - -int -main(int argc, char *argv[]) -{ - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - /* Initialize test framework */ - state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO); - if (!state) { - return 1; - } - for (i = 1; i < argc; ++i) { - SDLTest_CommonArg(state, i); - } - if (!SDLTest_CommonInit(state)) { - return 2; - } - - /* Create the windows and initialize the renderers */ - for (i = 0; i < state->num_windows; ++i) { - SDL_Renderer *renderer = state->renderers[i]; - SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE); - SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF); - SDL_RenderClear(renderer); - } - - srand((unsigned int)time(NULL)); - if(SDL_SetRelativeMouseMode(SDL_TRUE) < 0) { - return 3; - }; - - rect.x = DEFAULT_WINDOW_WIDTH / 2; - rect.y = DEFAULT_WINDOW_HEIGHT / 2; - rect.w = 10; - rect.h = 10; - /* Main render loop */ - done = 0; -#ifdef __EMSCRIPTEN__ - emscripten_set_main_loop(loop, 0, 1); -#else - while (!done) { - loop(); - } -#endif - SDLTest_CommonQuit(state); - return 0; -} - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/test/testrendercopyex.c b/SDL2-2.0.12/test/testrendercopyex.c deleted file mode 100644 index 5f51bb6..0000000 --- a/SDL2-2.0.12/test/testrendercopyex.c +++ /dev/null @@ -1,225 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ -/* Simple program: Move N sprites around on the screen as fast as possible */ - -#include -#include -#include - -#ifdef __EMSCRIPTEN__ -#include -#endif - -#include "SDL_test_common.h" - - -static SDLTest_CommonState *state; - -typedef struct { - SDL_Window *window; - SDL_Renderer *renderer; - SDL_Texture *background; - SDL_Texture *sprite; - SDL_Rect sprite_rect; - int scale_direction; -} DrawState; - -DrawState *drawstates; -int done; - -/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ -static void -quit(int rc) -{ - SDLTest_CommonQuit(state); - exit(rc); -} - -SDL_Texture * -LoadTexture(SDL_Renderer *renderer, const char *file, SDL_bool transparent) -{ - SDL_Surface *temp; - SDL_Texture *texture; - - /* Load the sprite image */ - temp = SDL_LoadBMP(file); - if (temp == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s", file, SDL_GetError()); - return NULL; - } - - /* Set transparent pixel as the pixel at (0,0) */ - if (transparent) { - if (temp->format->palette) { - SDL_SetColorKey(temp, SDL_TRUE, *(Uint8 *) temp->pixels); - } else { - switch (temp->format->BitsPerPixel) { - case 15: - SDL_SetColorKey(temp, SDL_TRUE, - (*(Uint16 *) temp->pixels) & 0x00007FFF); - break; - case 16: - SDL_SetColorKey(temp, SDL_TRUE, *(Uint16 *) temp->pixels); - break; - case 24: - SDL_SetColorKey(temp, SDL_TRUE, - (*(Uint32 *) temp->pixels) & 0x00FFFFFF); - break; - case 32: - SDL_SetColorKey(temp, SDL_TRUE, *(Uint32 *) temp->pixels); - break; - } - } - } - - /* Create textures from the image */ - texture = SDL_CreateTextureFromSurface(renderer, temp); - if (!texture) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError()); - SDL_FreeSurface(temp); - return NULL; - } - SDL_FreeSurface(temp); - - /* We're ready to roll. :) */ - return texture; -} - -void -Draw(DrawState *s) -{ - SDL_Rect viewport; - SDL_Texture *target; - SDL_Point *center=NULL; - SDL_Point origin = {0,0}; - - SDL_RenderGetViewport(s->renderer, &viewport); - - target = SDL_CreateTexture(s->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, viewport.w, viewport.h); - SDL_SetRenderTarget(s->renderer, target); - - /* Draw the background */ - SDL_RenderCopy(s->renderer, s->background, NULL, NULL); - - /* Scale and draw the sprite */ - s->sprite_rect.w += s->scale_direction; - s->sprite_rect.h += s->scale_direction; - if (s->scale_direction > 0) { - center = &origin; - if (s->sprite_rect.w >= viewport.w || s->sprite_rect.h >= viewport.h) { - s->scale_direction = -1; - } - } else { - if (s->sprite_rect.w <= 1 || s->sprite_rect.h <= 1) { - s->scale_direction = 1; - } - } - s->sprite_rect.x = (viewport.w - s->sprite_rect.w) / 2; - s->sprite_rect.y = (viewport.h - s->sprite_rect.h) / 2; - - SDL_RenderCopyEx(s->renderer, s->sprite, NULL, &s->sprite_rect, (double)s->sprite_rect.w, center, (SDL_RendererFlip)s->scale_direction); - - SDL_SetRenderTarget(s->renderer, NULL); - SDL_RenderCopy(s->renderer, target, NULL, NULL); - SDL_DestroyTexture(target); - - /* Update the screen! */ - SDL_RenderPresent(s->renderer); - /* SDL_Delay(10); */ -} - -void loop() -{ - int i; - SDL_Event event; - - /* Check for events */ - - while (SDL_PollEvent(&event)) { - SDLTest_CommonEvent(state, &event, &done); - } - for (i = 0; i < state->num_windows; ++i) { - if (state->windows[i] == NULL) - continue; - Draw(&drawstates[i]); - } -#ifdef __EMSCRIPTEN__ - if (done) { - emscripten_cancel_main_loop(); - } -#endif -} - -int -main(int argc, char *argv[]) -{ - int i; - int frames; - Uint32 then, now; - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - /* Initialize test framework */ - state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO); - if (!state) { - return 1; - } - - if (!SDLTest_CommonDefaultArgs(state, argc, argv) || !SDLTest_CommonInit(state)) { - SDLTest_CommonQuit(state); - return 1; - } - - drawstates = SDL_stack_alloc(DrawState, state->num_windows); - for (i = 0; i < state->num_windows; ++i) { - DrawState *drawstate = &drawstates[i]; - - drawstate->window = state->windows[i]; - drawstate->renderer = state->renderers[i]; - drawstate->sprite = LoadTexture(drawstate->renderer, "icon.bmp", SDL_TRUE); - drawstate->background = LoadTexture(drawstate->renderer, "sample.bmp", SDL_FALSE); - if (!drawstate->sprite || !drawstate->background) { - quit(2); - } - SDL_QueryTexture(drawstate->sprite, NULL, NULL, - &drawstate->sprite_rect.w, &drawstate->sprite_rect.h); - drawstate->scale_direction = 1; - } - - /* Main render loop */ - frames = 0; - then = SDL_GetTicks(); - done = 0; - -#ifdef __EMSCRIPTEN__ - emscripten_set_main_loop(loop, 0, 1); -#else - while (!done) { - ++frames; - loop(); - } -#endif - /* Print out some timing information */ - now = SDL_GetTicks(); - if (now > then) { - double fps = ((double) frames * 1000) / (now - then); - SDL_Log("%2.2f frames per second\n", fps); - } - - SDL_stack_free(drawstates); - - quit(0); - return 0; -} - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/test/testrendertarget.c b/SDL2-2.0.12/test/testrendertarget.c deleted file mode 100644 index 0845cbd..0000000 --- a/SDL2-2.0.12/test/testrendertarget.c +++ /dev/null @@ -1,335 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ -/* Simple program: Move N sprites around on the screen as fast as possible */ - -#include -#include -#include - -#ifdef __EMSCRIPTEN__ -#include -#endif - -#include "SDL_test_common.h" - - -static SDLTest_CommonState *state; - -typedef struct { - SDL_Window *window; - SDL_Renderer *renderer; - SDL_Texture *background; - SDL_Texture *sprite; - SDL_Rect sprite_rect; - int scale_direction; -} DrawState; - -DrawState *drawstates; -int done; -SDL_bool test_composite = SDL_FALSE; - -/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ -static void -quit(int rc) -{ - SDLTest_CommonQuit(state); - exit(rc); -} - -SDL_Texture * -LoadTexture(SDL_Renderer *renderer, char *file, SDL_bool transparent) -{ - SDL_Surface *temp; - SDL_Texture *texture; - - /* Load the sprite image */ - temp = SDL_LoadBMP(file); - if (temp == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s", file, SDL_GetError()); - return NULL; - } - - /* Set transparent pixel as the pixel at (0,0) */ - if (transparent) { - if (temp->format->palette) { - SDL_SetColorKey(temp, SDL_TRUE, *(Uint8 *) temp->pixels); - } else { - switch (temp->format->BitsPerPixel) { - case 15: - SDL_SetColorKey(temp, SDL_TRUE, - (*(Uint16 *) temp->pixels) & 0x00007FFF); - break; - case 16: - SDL_SetColorKey(temp, SDL_TRUE, *(Uint16 *) temp->pixels); - break; - case 24: - SDL_SetColorKey(temp, SDL_TRUE, - (*(Uint32 *) temp->pixels) & 0x00FFFFFF); - break; - case 32: - SDL_SetColorKey(temp, SDL_TRUE, *(Uint32 *) temp->pixels); - break; - } - } - } - - /* Create textures from the image */ - texture = SDL_CreateTextureFromSurface(renderer, temp); - if (!texture) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError()); - SDL_FreeSurface(temp); - return NULL; - } - SDL_FreeSurface(temp); - - /* We're ready to roll. :) */ - return texture; -} - -SDL_bool -DrawComposite(DrawState *s) -{ - SDL_Rect viewport, R; - SDL_Texture *target; - - static SDL_bool blend_tested = SDL_FALSE; - if (!blend_tested) { - SDL_Texture *A, *B; - Uint32 P; - - A = SDL_CreateTexture(s->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, 1, 1); - SDL_SetTextureBlendMode(A, SDL_BLENDMODE_BLEND); - - B = SDL_CreateTexture(s->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, 1, 1); - SDL_SetTextureBlendMode(B, SDL_BLENDMODE_BLEND); - - SDL_SetRenderTarget(s->renderer, A); - SDL_SetRenderDrawColor(s->renderer, 0x00, 0x00, 0x00, 0x80); - SDL_RenderFillRect(s->renderer, NULL); - - SDL_SetRenderTarget(s->renderer, B); - SDL_SetRenderDrawColor(s->renderer, 0x00, 0x00, 0x00, 0x00); - SDL_RenderFillRect(s->renderer, NULL); - SDL_RenderCopy(s->renderer, A, NULL, NULL); - SDL_RenderReadPixels(s->renderer, NULL, SDL_PIXELFORMAT_ARGB8888, &P, sizeof(P)); - - SDL_Log("Blended pixel: 0x%8.8X\n", P); - - SDL_DestroyTexture(A); - SDL_DestroyTexture(B); - blend_tested = SDL_TRUE; - } - - SDL_RenderGetViewport(s->renderer, &viewport); - - target = SDL_CreateTexture(s->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, viewport.w, viewport.h); - SDL_SetTextureBlendMode(target, SDL_BLENDMODE_BLEND); - SDL_SetRenderTarget(s->renderer, target); - - /* Draw the background. - This is solid black so when the sprite is copied to it, any per-pixel alpha will be blended through. - */ - SDL_SetRenderDrawColor(s->renderer, 0x00, 0x00, 0x00, 0x00); - SDL_RenderFillRect(s->renderer, NULL); - - /* Scale and draw the sprite */ - s->sprite_rect.w += s->scale_direction; - s->sprite_rect.h += s->scale_direction; - if (s->scale_direction > 0) { - if (s->sprite_rect.w >= viewport.w || s->sprite_rect.h >= viewport.h) { - s->scale_direction = -1; - } - } else { - if (s->sprite_rect.w <= 1 || s->sprite_rect.h <= 1) { - s->scale_direction = 1; - } - } - s->sprite_rect.x = (viewport.w - s->sprite_rect.w) / 2; - s->sprite_rect.y = (viewport.h - s->sprite_rect.h) / 2; - - SDL_RenderCopy(s->renderer, s->sprite, NULL, &s->sprite_rect); - - SDL_SetRenderTarget(s->renderer, NULL); - SDL_RenderCopy(s->renderer, s->background, NULL, NULL); - - SDL_SetRenderDrawBlendMode(s->renderer, SDL_BLENDMODE_BLEND); - SDL_SetRenderDrawColor(s->renderer, 0xff, 0x00, 0x00, 0x80); - R.x = 0; - R.y = 0; - R.w = 100; - R.h = 100; - SDL_RenderFillRect(s->renderer, &R); - SDL_SetRenderDrawBlendMode(s->renderer, SDL_BLENDMODE_NONE); - - SDL_RenderCopy(s->renderer, target, NULL, NULL); - SDL_DestroyTexture(target); - - /* Update the screen! */ - SDL_RenderPresent(s->renderer); - return SDL_TRUE; -} - -SDL_bool -Draw(DrawState *s) -{ - SDL_Rect viewport; - SDL_Texture *target; - - SDL_RenderGetViewport(s->renderer, &viewport); - - target = SDL_CreateTexture(s->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, viewport.w, viewport.h); - if (!target) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create render target texture: %s\n", SDL_GetError()); - return SDL_FALSE; - } - SDL_SetRenderTarget(s->renderer, target); - - /* Draw the background */ - SDL_RenderCopy(s->renderer, s->background, NULL, NULL); - - /* Scale and draw the sprite */ - s->sprite_rect.w += s->scale_direction; - s->sprite_rect.h += s->scale_direction; - if (s->scale_direction > 0) { - if (s->sprite_rect.w >= viewport.w || s->sprite_rect.h >= viewport.h) { - s->scale_direction = -1; - } - } else { - if (s->sprite_rect.w <= 1 || s->sprite_rect.h <= 1) { - s->scale_direction = 1; - } - } - s->sprite_rect.x = (viewport.w - s->sprite_rect.w) / 2; - s->sprite_rect.y = (viewport.h - s->sprite_rect.h) / 2; - - SDL_RenderCopy(s->renderer, s->sprite, NULL, &s->sprite_rect); - - SDL_SetRenderTarget(s->renderer, NULL); - SDL_RenderCopy(s->renderer, target, NULL, NULL); - SDL_DestroyTexture(target); - - /* Update the screen! */ - SDL_RenderPresent(s->renderer); - return SDL_TRUE; -} - -void -loop() -{ - int i; - SDL_Event event; - - /* Check for events */ - while (SDL_PollEvent(&event)) { - SDLTest_CommonEvent(state, &event, &done); - } - for (i = 0; i < state->num_windows; ++i) { - if (state->windows[i] == NULL) - continue; - if (test_composite) { - if (!DrawComposite(&drawstates[i])) done = 1; - } else { - if (!Draw(&drawstates[i])) done = 1; - } - } -#ifdef __EMSCRIPTEN__ - if (done) { - emscripten_cancel_main_loop(); - } -#endif -} - -int -main(int argc, char *argv[]) -{ - int i; - int frames; - Uint32 then, now; - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - /* Initialize test framework */ - state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO); - if (!state) { - return 1; - } - for (i = 1; i < argc;) { - int consumed; - - consumed = SDLTest_CommonArg(state, i); - if (consumed == 0) { - consumed = -1; - if (SDL_strcasecmp(argv[i], "--composite") == 0) { - test_composite = SDL_TRUE; - consumed = 1; - } - } - if (consumed < 0) { - static const char *options[] = { "[--composite]", NULL }; - SDLTest_CommonLogUsage(state, argv[0], options); - quit(1); - } - i += consumed; - } - if (!SDLTest_CommonInit(state)) { - quit(2); - } - - drawstates = SDL_stack_alloc(DrawState, state->num_windows); - for (i = 0; i < state->num_windows; ++i) { - DrawState *drawstate = &drawstates[i]; - - drawstate->window = state->windows[i]; - drawstate->renderer = state->renderers[i]; - if (test_composite) { - drawstate->sprite = LoadTexture(drawstate->renderer, "icon-alpha.bmp", SDL_TRUE); - } else { - drawstate->sprite = LoadTexture(drawstate->renderer, "icon.bmp", SDL_TRUE); - } - drawstate->background = LoadTexture(drawstate->renderer, "sample.bmp", SDL_FALSE); - if (!drawstate->sprite || !drawstate->background) { - quit(2); - } - SDL_QueryTexture(drawstate->sprite, NULL, NULL, - &drawstate->sprite_rect.w, &drawstate->sprite_rect.h); - drawstate->scale_direction = 1; - } - - /* Main render loop */ - frames = 0; - then = SDL_GetTicks(); - done = 0; - -#ifdef __EMSCRIPTEN__ - emscripten_set_main_loop(loop, 0, 1); -#else - while (!done) { - ++frames; - loop(); - } -#endif - - /* Print out some timing information */ - now = SDL_GetTicks(); - if (now > then) { - double fps = ((double) frames * 1000) / (now - then); - SDL_Log("%2.2f frames per second\n", fps); - } - - SDL_stack_free(drawstates); - - quit(0); - return 0; -} - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/test/testresample.c b/SDL2-2.0.12/test/testresample.c deleted file mode 100644 index 70585f4..0000000 --- a/SDL2-2.0.12/test/testresample.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ - -#include "SDL.h" - -int -main(int argc, char **argv) -{ - SDL_AudioSpec spec; - SDL_AudioCVT cvt; - Uint32 len = 0; - Uint8 *data = NULL; - int cvtfreq = 0; - int cvtchans = 0; - int bitsize = 0; - int blockalign = 0; - int avgbytes = 0; - SDL_RWops *io = NULL; - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - if (argc != 5) { - SDL_Log("USAGE: %s in.wav out.wav newfreq newchans\n", argv[0]); - return 1; - } - - cvtfreq = SDL_atoi(argv[3]); - cvtchans = SDL_atoi(argv[4]); - - if (SDL_Init(SDL_INIT_AUDIO) == -1) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_Init() failed: %s\n", SDL_GetError()); - return 2; - } - - if (SDL_LoadWAV(argv[1], &spec, &data, &len) == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "failed to load %s: %s\n", argv[1], SDL_GetError()); - SDL_Quit(); - return 3; - } - - if (SDL_BuildAudioCVT(&cvt, spec.format, spec.channels, spec.freq, - spec.format, cvtchans, cvtfreq) == -1) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "failed to build CVT: %s\n", SDL_GetError()); - SDL_FreeWAV(data); - SDL_Quit(); - return 4; - } - - cvt.len = len; - cvt.buf = (Uint8 *) SDL_malloc(len * cvt.len_mult); - if (cvt.buf == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Out of memory.\n"); - SDL_FreeWAV(data); - SDL_Quit(); - return 5; - } - SDL_memcpy(cvt.buf, data, len); - - if (SDL_ConvertAudio(&cvt) == -1) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Conversion failed: %s\n", SDL_GetError()); - SDL_free(cvt.buf); - SDL_FreeWAV(data); - SDL_Quit(); - return 6; - } - - /* write out a WAV header... */ - io = SDL_RWFromFile(argv[2], "wb"); - if (io == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "fopen('%s') failed: %s\n", argv[2], SDL_GetError()); - SDL_free(cvt.buf); - SDL_FreeWAV(data); - SDL_Quit(); - return 7; - } - - bitsize = SDL_AUDIO_BITSIZE(spec.format); - blockalign = (bitsize / 8) * cvtchans; - avgbytes = cvtfreq * blockalign; - - SDL_WriteLE32(io, 0x46464952); /* RIFF */ - SDL_WriteLE32(io, cvt.len_cvt + 36); - SDL_WriteLE32(io, 0x45564157); /* WAVE */ - SDL_WriteLE32(io, 0x20746D66); /* fmt */ - SDL_WriteLE32(io, 16); /* chunk size */ - SDL_WriteLE16(io, SDL_AUDIO_ISFLOAT(spec.format) ? 3 : 1); /* uncompressed */ - SDL_WriteLE16(io, cvtchans); /* channels */ - SDL_WriteLE32(io, cvtfreq); /* sample rate */ - SDL_WriteLE32(io, avgbytes); /* average bytes per second */ - SDL_WriteLE16(io, blockalign); /* block align */ - SDL_WriteLE16(io, bitsize); /* significant bits per sample */ - SDL_WriteLE32(io, 0x61746164); /* data */ - SDL_WriteLE32(io, cvt.len_cvt); /* size */ - SDL_RWwrite(io, cvt.buf, cvt.len_cvt, 1); - - if (SDL_RWclose(io) == -1) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "fclose('%s') failed: %s\n", argv[2], SDL_GetError()); - SDL_free(cvt.buf); - SDL_FreeWAV(data); - SDL_Quit(); - return 8; - } /* if */ - - SDL_free(cvt.buf); - SDL_FreeWAV(data); - SDL_Quit(); - return 0; -} /* main */ - -/* end of testresample.c ... */ diff --git a/SDL2-2.0.12/test/testrumble.c b/SDL2-2.0.12/test/testrumble.c deleted file mode 100644 index 50c7a65..0000000 --- a/SDL2-2.0.12/test/testrumble.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ -/* -Copyright (c) 2011, Edgar Simo Serra -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of the Simple Directmedia Layer (SDL) nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* - * includes - */ -#include -#include /* strstr */ -#include /* isdigit */ - -#include "SDL.h" - -#ifndef SDL_HAPTIC_DISABLED - -static SDL_Haptic *haptic; - - -/** - * @brief The entry point of this force feedback demo. - * @param[in] argc Number of arguments. - * @param[in] argv Array of argc arguments. - */ -int -main(int argc, char **argv) -{ - int i; - char *name; - int index; - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - name = NULL; - index = -1; - if (argc > 1) { - size_t l; - name = argv[1]; - if ((strcmp(name, "--help") == 0) || (strcmp(name, "-h") == 0)) { - SDL_Log("USAGE: %s [device]\n" - "If device is a two-digit number it'll use it as an index, otherwise\n" - "it'll use it as if it were part of the device's name.\n", - argv[0]); - return 0; - } - - l = SDL_strlen(name); - if ((l < 3) && SDL_isdigit(name[0]) && ((l == 1) || SDL_isdigit(name[1]))) { - index = SDL_atoi(name); - name = NULL; - } - } - - /* Initialize the force feedbackness */ - SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_JOYSTICK | - SDL_INIT_HAPTIC); - SDL_Log("%d Haptic devices detected.\n", SDL_NumHaptics()); - if (SDL_NumHaptics() > 0) { - /* We'll just use index or the first force feedback device found */ - if (name == NULL) { - i = (index != -1) ? index : 0; - } - /* Try to find matching device */ - else { - for (i = 0; i < SDL_NumHaptics(); i++) { - if (strstr(SDL_HapticName(i), name) != NULL) - break; - } - - if (i >= SDL_NumHaptics()) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to find device matching '%s', aborting.\n", - name); - return 1; - } - } - - haptic = SDL_HapticOpen(i); - if (haptic == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to create the haptic device: %s\n", - SDL_GetError()); - return 1; - } - SDL_Log("Device: %s\n", SDL_HapticName(i)); - } else { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "No Haptic devices found!\n"); - return 1; - } - - /* We only want force feedback errors. */ - SDL_ClearError(); - - if (SDL_HapticRumbleSupported(haptic) == SDL_FALSE) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Rumble not supported!\n"); - return 1; - } - if (SDL_HapticRumbleInit(haptic) != 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to initialize rumble: %s\n", SDL_GetError()); - return 1; - } - SDL_Log("Playing 2 second rumble at 0.5 magnitude.\n"); - if (SDL_HapticRumblePlay(haptic, 0.5, 5000) != 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to play rumble: %s\n", SDL_GetError() ); - return 1; - } - SDL_Delay(2000); - SDL_Log("Stopping rumble.\n"); - SDL_HapticRumbleStop(haptic); - SDL_Delay(2000); - SDL_Log("Playing 2 second rumble at 0.3 magnitude.\n"); - if (SDL_HapticRumblePlay(haptic, 0.3f, 5000) != 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to play rumble: %s\n", SDL_GetError() ); - return 1; - } - SDL_Delay(2000); - - /* Quit */ - if (haptic != NULL) - SDL_HapticClose(haptic); - SDL_Quit(); - - return 0; -} - -#else - -int -main(int argc, char *argv[]) -{ - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL compiled without Haptic support.\n"); - return 1; -} - -#endif diff --git a/SDL2-2.0.12/test/testscale.c b/SDL2-2.0.12/test/testscale.c deleted file mode 100644 index 4a603c6..0000000 --- a/SDL2-2.0.12/test/testscale.c +++ /dev/null @@ -1,216 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ -/* Simple program: Move N sprites around on the screen as fast as possible */ - -#include -#include -#include - -#ifdef __EMSCRIPTEN__ -#include -#endif - -#include "SDL_test_common.h" - -#define WINDOW_WIDTH 640 -#define WINDOW_HEIGHT 480 - -static SDLTest_CommonState *state; - -typedef struct { - SDL_Window *window; - SDL_Renderer *renderer; - SDL_Texture *background; - SDL_Texture *sprite; - SDL_Rect sprite_rect; - int scale_direction; -} DrawState; - -DrawState *drawstates; -int done; - -/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ -static void -quit(int rc) -{ - SDLTest_CommonQuit(state); - exit(rc); -} - -SDL_Texture * -LoadTexture(SDL_Renderer *renderer, char *file, SDL_bool transparent) -{ - SDL_Surface *temp; - SDL_Texture *texture; - - /* Load the sprite image */ - temp = SDL_LoadBMP(file); - if (temp == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s", file, SDL_GetError()); - return NULL; - } - - /* Set transparent pixel as the pixel at (0,0) */ - if (transparent) { - if (temp->format->palette) { - SDL_SetColorKey(temp, SDL_TRUE, *(Uint8 *) temp->pixels); - } else { - switch (temp->format->BitsPerPixel) { - case 15: - SDL_SetColorKey(temp, SDL_TRUE, - (*(Uint16 *) temp->pixels) & 0x00007FFF); - break; - case 16: - SDL_SetColorKey(temp, SDL_TRUE, *(Uint16 *) temp->pixels); - break; - case 24: - SDL_SetColorKey(temp, SDL_TRUE, - (*(Uint32 *) temp->pixels) & 0x00FFFFFF); - break; - case 32: - SDL_SetColorKey(temp, SDL_TRUE, *(Uint32 *) temp->pixels); - break; - } - } - } - - /* Create textures from the image */ - texture = SDL_CreateTextureFromSurface(renderer, temp); - if (!texture) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError()); - SDL_FreeSurface(temp); - return NULL; - } - SDL_FreeSurface(temp); - - /* We're ready to roll. :) */ - return texture; -} - -void -Draw(DrawState *s) -{ - SDL_Rect viewport; - - SDL_RenderGetViewport(s->renderer, &viewport); - - /* Draw the background */ - SDL_RenderCopy(s->renderer, s->background, NULL, NULL); - - /* Scale and draw the sprite */ - s->sprite_rect.w += s->scale_direction; - s->sprite_rect.h += s->scale_direction; - if (s->scale_direction > 0) { - if (s->sprite_rect.w >= viewport.w || s->sprite_rect.h >= viewport.h) { - s->scale_direction = -1; - } - } else { - if (s->sprite_rect.w <= 1 || s->sprite_rect.h <= 1) { - s->scale_direction = 1; - } - } - s->sprite_rect.x = (viewport.w - s->sprite_rect.w) / 2; - s->sprite_rect.y = (viewport.h - s->sprite_rect.h) / 2; - - SDL_RenderCopy(s->renderer, s->sprite, NULL, &s->sprite_rect); - - /* Update the screen! */ - SDL_RenderPresent(s->renderer); -} - -void -loop() -{ - int i; - SDL_Event event; - - /* Check for events */ - while (SDL_PollEvent(&event)) { - SDLTest_CommonEvent(state, &event, &done); - } - for (i = 0; i < state->num_windows; ++i) { - if (state->windows[i] == NULL) - continue; - Draw(&drawstates[i]); - } -#ifdef __EMSCRIPTEN__ - if (done) { - emscripten_cancel_main_loop(); - } -#endif -} - -int -main(int argc, char *argv[]) -{ - int i; - int frames; - Uint32 then, now; - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - /* Initialize test framework */ - state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO); - if (!state) { - return 1; - } - - if (!SDLTest_CommonDefaultArgs(state, argc, argv) || !SDLTest_CommonInit(state)) { - SDLTest_CommonQuit(state); - return 1; - } - - drawstates = SDL_stack_alloc(DrawState, state->num_windows); - for (i = 0; i < state->num_windows; ++i) { - DrawState *drawstate = &drawstates[i]; - - drawstate->window = state->windows[i]; - drawstate->renderer = state->renderers[i]; - drawstate->sprite = LoadTexture(drawstate->renderer, "icon.bmp", SDL_TRUE); - drawstate->background = LoadTexture(drawstate->renderer, "sample.bmp", SDL_FALSE); - if (!drawstate->sprite || !drawstate->background) { - quit(2); - } - SDL_QueryTexture(drawstate->sprite, NULL, NULL, - &drawstate->sprite_rect.w, &drawstate->sprite_rect.h); - drawstate->scale_direction = 1; - } - - /* Main render loop */ - frames = 0; - then = SDL_GetTicks(); - done = 0; - -#ifdef __EMSCRIPTEN__ - emscripten_set_main_loop(loop, 0, 1); -#else - while (!done) { - ++frames; - loop(); - } -#endif - - /* Print out some timing information */ - now = SDL_GetTicks(); - if (now > then) { - double fps = ((double) frames * 1000) / (now - then); - SDL_Log("%2.2f frames per second\n", fps); - } - - SDL_stack_free(drawstates); - - quit(0); - return 0; -} - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/test/testsem.c b/SDL2-2.0.12/test/testsem.c deleted file mode 100644 index 8a60ff1..0000000 --- a/SDL2-2.0.12/test/testsem.c +++ /dev/null @@ -1,130 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ - -/* Simple test of the SDL semaphore code */ - -#include -#include -#include - -#include "SDL.h" - -#define NUM_THREADS 10 - -static SDL_sem *sem; -int alive = 1; - -int SDLCALL -ThreadFunc(void *data) -{ - int threadnum = (int) (uintptr_t) data; - while (alive) { - SDL_SemWait(sem); - SDL_Log("Thread number %d has got the semaphore (value = %d)!\n", - threadnum, SDL_SemValue(sem)); - SDL_Delay(200); - SDL_SemPost(sem); - SDL_Log("Thread number %d has released the semaphore (value = %d)!\n", - threadnum, SDL_SemValue(sem)); - SDL_Delay(1); /* For the scheduler */ - } - SDL_Log("Thread number %d exiting.\n", threadnum); - return 0; -} - -static void -killed(int sig) -{ - alive = 0; -} - -static void -TestWaitTimeout(void) -{ - Uint32 start_ticks; - Uint32 end_ticks; - Uint32 duration; - int retval; - - sem = SDL_CreateSemaphore(0); - SDL_Log("Waiting 2 seconds on semaphore\n"); - - start_ticks = SDL_GetTicks(); - retval = SDL_SemWaitTimeout(sem, 2000); - end_ticks = SDL_GetTicks(); - - duration = end_ticks - start_ticks; - - /* Accept a little offset in the effective wait */ - if (duration > 1900 && duration < 2050) - SDL_Log("Wait done.\n"); - else - SDL_Log("Wait took %d milliseconds\n", duration); - - /* Check to make sure the return value indicates timed out */ - if (retval != SDL_MUTEX_TIMEDOUT) - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_SemWaitTimeout returned: %d; expected: %d\n", retval, SDL_MUTEX_TIMEDOUT); -} - -int -main(int argc, char **argv) -{ - SDL_Thread *threads[NUM_THREADS]; - uintptr_t i; - int init_sem; - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - if (argc < 2) { - SDL_Log("Usage: %s init_value\n", argv[0]); - return (1); - } - - /* Load the SDL library */ - if (SDL_Init(0) < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError()); - return (1); - } - signal(SIGTERM, killed); - signal(SIGINT, killed); - - init_sem = atoi(argv[1]); - sem = SDL_CreateSemaphore(init_sem); - - SDL_Log("Running %d threads, semaphore value = %d\n", NUM_THREADS, - init_sem); - /* Create all the threads */ - for (i = 0; i < NUM_THREADS; ++i) { - char name[64]; - SDL_snprintf(name, sizeof (name), "Thread%u", (unsigned int) i); - threads[i] = SDL_CreateThread(ThreadFunc, name, (void *) i); - } - - /* Wait 10 seconds */ - SDL_Delay(10 * 1000); - - /* Wait for all threads to finish */ - SDL_Log("Waiting for threads to finish\n"); - alive = 0; - for (i = 0; i < NUM_THREADS; ++i) { - SDL_WaitThread(threads[i], NULL); - } - SDL_Log("Finished waiting for threads\n"); - - SDL_DestroySemaphore(sem); - - TestWaitTimeout(); - - SDL_Quit(); - return (0); -} diff --git a/SDL2-2.0.12/test/testsensor.c b/SDL2-2.0.12/test/testsensor.c deleted file mode 100644 index c29faa2..0000000 --- a/SDL2-2.0.12/test/testsensor.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ - -/* Simple test of the SDL sensor code */ - -#include "SDL.h" - -static const char *GetSensorTypeString(SDL_SensorType type) -{ - static char unknown_type[64]; - - switch (type) - { - case SDL_SENSOR_INVALID: - return "SDL_SENSOR_INVALID"; - case SDL_SENSOR_UNKNOWN: - return "SDL_SENSOR_UNKNOWN"; - case SDL_SENSOR_ACCEL: - return "SDL_SENSOR_ACCEL"; - case SDL_SENSOR_GYRO: - return "SDL_SENSOR_GYRO"; - default: - SDL_snprintf(unknown_type, sizeof(unknown_type), "UNKNOWN (%d)", type); - return unknown_type; - } -} - -static void HandleSensorEvent(SDL_SensorEvent *event) -{ - SDL_Sensor *sensor = SDL_SensorFromInstanceID(event->which); - if (!sensor) { - SDL_Log("Couldn't get sensor for sensor event\n"); - return; - } - - switch (SDL_SensorGetType(sensor)) { - case SDL_SENSOR_ACCEL: - SDL_Log("Accelerometer update: %.2f, %.2f, %.2f\n", event->data[0], event->data[1], event->data[2]); - break; - case SDL_SENSOR_GYRO: - SDL_Log("Gyro update: %.2f, %.2f, %.2f\n", event->data[0], event->data[1], event->data[2]); - break; - default: - SDL_Log("Sensor update for sensor type %s\n", GetSensorTypeString(SDL_SensorGetType(sensor))); - break; - } -} - -int -main(int argc, char **argv) -{ - int i; - int num_sensors, num_opened; - - /* Load the SDL library */ - if (SDL_Init(SDL_INIT_SENSOR) < 0) { - SDL_Log("Couldn't initialize SDL: %s\n", SDL_GetError()); - return (1); - } - - num_sensors = SDL_NumSensors(); - num_opened = 0; - - SDL_Log("There are %d sensors available\n", num_sensors); - for (i = 0; i < num_sensors; ++i) { - SDL_Log("Sensor %d: %s, type %s, platform type %d\n", - SDL_SensorGetDeviceInstanceID(i), - SDL_SensorGetDeviceName(i), - GetSensorTypeString(SDL_SensorGetDeviceType(i)), - SDL_SensorGetDeviceNonPortableType(i)); - - if (SDL_SensorGetDeviceType(i) != SDL_SENSOR_UNKNOWN) { - SDL_Sensor *sensor = SDL_SensorOpen(i); - if (sensor == NULL) { - SDL_Log("Couldn't open sensor %d: %s\n", SDL_SensorGetDeviceInstanceID(i), SDL_GetError()); - } else { - ++num_opened; - } - } - } - SDL_Log("Opened %d sensors\n", num_opened); - - if (num_opened > 0) { - SDL_bool done = SDL_FALSE; - SDL_Event event; - - SDL_CreateWindow("Sensor Test", 0, 0, 0, 0, SDL_WINDOW_FULLSCREEN_DESKTOP); - while (!done) { - while (SDL_PollEvent(&event) > 0) { - switch (event.type) { - case SDL_SENSORUPDATE: - HandleSensorEvent(&event.sensor); - break; - case SDL_MOUSEBUTTONUP: - case SDL_KEYUP: - case SDL_QUIT: - done = SDL_TRUE; - break; - default: - break; - } - } - } - } - - SDL_Quit(); - return (0); -} diff --git a/SDL2-2.0.12/test/testshader.c b/SDL2-2.0.12/test/testshader.c deleted file mode 100644 index 45e74a6..0000000 --- a/SDL2-2.0.12/test/testshader.c +++ /dev/null @@ -1,500 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ -/* This is a simple example of using GLSL shaders with SDL */ - -#include "SDL.h" - -#ifdef HAVE_OPENGL - -#include "SDL_opengl.h" - - -static SDL_bool shaders_supported; -static int current_shader = 0; - -enum { - SHADER_COLOR, - SHADER_TEXTURE, - SHADER_TEXCOORDS, - NUM_SHADERS -}; - -typedef struct { - GLhandleARB program; - GLhandleARB vert_shader; - GLhandleARB frag_shader; - const char *vert_source; - const char *frag_source; -} ShaderData; - -static ShaderData shaders[NUM_SHADERS] = { - - /* SHADER_COLOR */ - { 0, 0, 0, - /* vertex shader */ -"varying vec4 v_color;\n" -"\n" -"void main()\n" -"{\n" -" gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n" -" v_color = gl_Color;\n" -"}", - /* fragment shader */ -"varying vec4 v_color;\n" -"\n" -"void main()\n" -"{\n" -" gl_FragColor = v_color;\n" -"}" - }, - - /* SHADER_TEXTURE */ - { 0, 0, 0, - /* vertex shader */ -"varying vec4 v_color;\n" -"varying vec2 v_texCoord;\n" -"\n" -"void main()\n" -"{\n" -" gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n" -" v_color = gl_Color;\n" -" v_texCoord = vec2(gl_MultiTexCoord0);\n" -"}", - /* fragment shader */ -"varying vec4 v_color;\n" -"varying vec2 v_texCoord;\n" -"uniform sampler2D tex0;\n" -"\n" -"void main()\n" -"{\n" -" gl_FragColor = texture2D(tex0, v_texCoord) * v_color;\n" -"}" - }, - - /* SHADER_TEXCOORDS */ - { 0, 0, 0, - /* vertex shader */ -"varying vec2 v_texCoord;\n" -"\n" -"void main()\n" -"{\n" -" gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n" -" v_texCoord = vec2(gl_MultiTexCoord0);\n" -"}", - /* fragment shader */ -"varying vec2 v_texCoord;\n" -"\n" -"void main()\n" -"{\n" -" vec4 color;\n" -" vec2 delta;\n" -" float dist;\n" -"\n" -" delta = vec2(0.5, 0.5) - v_texCoord;\n" -" dist = dot(delta, delta);\n" -"\n" -" color.r = v_texCoord.x;\n" -" color.g = v_texCoord.x * v_texCoord.y;\n" -" color.b = v_texCoord.y;\n" -" color.a = 1.0 - (dist * 4.0);\n" -" gl_FragColor = color;\n" -"}" - }, -}; - -static PFNGLATTACHOBJECTARBPROC glAttachObjectARB; -static PFNGLCOMPILESHADERARBPROC glCompileShaderARB; -static PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObjectARB; -static PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB; -static PFNGLDELETEOBJECTARBPROC glDeleteObjectARB; -static PFNGLGETINFOLOGARBPROC glGetInfoLogARB; -static PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB; -static PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB; -static PFNGLLINKPROGRAMARBPROC glLinkProgramARB; -static PFNGLSHADERSOURCEARBPROC glShaderSourceARB; -static PFNGLUNIFORM1IARBPROC glUniform1iARB; -static PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB; - -static SDL_bool CompileShader(GLhandleARB shader, const char *source) -{ - GLint status; - - glShaderSourceARB(shader, 1, &source, NULL); - glCompileShaderARB(shader); - glGetObjectParameterivARB(shader, GL_OBJECT_COMPILE_STATUS_ARB, &status); - if (status == 0) { - GLint length; - char *info; - - glGetObjectParameterivARB(shader, GL_OBJECT_INFO_LOG_LENGTH_ARB, &length); - info = SDL_stack_alloc(char, length+1); - glGetInfoLogARB(shader, length, NULL, info); - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to compile shader:\n%s\n%s", source, info); - SDL_stack_free(info); - - return SDL_FALSE; - } else { - return SDL_TRUE; - } -} - -static SDL_bool CompileShaderProgram(ShaderData *data) -{ - const int num_tmus_bound = 4; - int i; - GLint location; - - glGetError(); - - /* Create one program object to rule them all */ - data->program = glCreateProgramObjectARB(); - - /* Create the vertex shader */ - data->vert_shader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB); - if (!CompileShader(data->vert_shader, data->vert_source)) { - return SDL_FALSE; - } - - /* Create the fragment shader */ - data->frag_shader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB); - if (!CompileShader(data->frag_shader, data->frag_source)) { - return SDL_FALSE; - } - - /* ... and in the darkness bind them */ - glAttachObjectARB(data->program, data->vert_shader); - glAttachObjectARB(data->program, data->frag_shader); - glLinkProgramARB(data->program); - - /* Set up some uniform variables */ - glUseProgramObjectARB(data->program); - for (i = 0; i < num_tmus_bound; ++i) { - char tex_name[5]; - SDL_snprintf(tex_name, SDL_arraysize(tex_name), "tex%d", i); - location = glGetUniformLocationARB(data->program, tex_name); - if (location >= 0) { - glUniform1iARB(location, i); - } - } - glUseProgramObjectARB(0); - - return (glGetError() == GL_NO_ERROR) ? SDL_TRUE : SDL_FALSE; -} - -static void DestroyShaderProgram(ShaderData *data) -{ - if (shaders_supported) { - glDeleteObjectARB(data->vert_shader); - glDeleteObjectARB(data->frag_shader); - glDeleteObjectARB(data->program); - } -} - -static SDL_bool InitShaders() -{ - int i; - - /* Check for shader support */ - shaders_supported = SDL_FALSE; - if (SDL_GL_ExtensionSupported("GL_ARB_shader_objects") && - SDL_GL_ExtensionSupported("GL_ARB_shading_language_100") && - SDL_GL_ExtensionSupported("GL_ARB_vertex_shader") && - SDL_GL_ExtensionSupported("GL_ARB_fragment_shader")) { - glAttachObjectARB = (PFNGLATTACHOBJECTARBPROC) SDL_GL_GetProcAddress("glAttachObjectARB"); - glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC) SDL_GL_GetProcAddress("glCompileShaderARB"); - glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC) SDL_GL_GetProcAddress("glCreateProgramObjectARB"); - glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC) SDL_GL_GetProcAddress("glCreateShaderObjectARB"); - glDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC) SDL_GL_GetProcAddress("glDeleteObjectARB"); - glGetInfoLogARB = (PFNGLGETINFOLOGARBPROC) SDL_GL_GetProcAddress("glGetInfoLogARB"); - glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC) SDL_GL_GetProcAddress("glGetObjectParameterivARB"); - glGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC) SDL_GL_GetProcAddress("glGetUniformLocationARB"); - glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC) SDL_GL_GetProcAddress("glLinkProgramARB"); - glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC) SDL_GL_GetProcAddress("glShaderSourceARB"); - glUniform1iARB = (PFNGLUNIFORM1IARBPROC) SDL_GL_GetProcAddress("glUniform1iARB"); - glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC) SDL_GL_GetProcAddress("glUseProgramObjectARB"); - if (glAttachObjectARB && - glCompileShaderARB && - glCreateProgramObjectARB && - glCreateShaderObjectARB && - glDeleteObjectARB && - glGetInfoLogARB && - glGetObjectParameterivARB && - glGetUniformLocationARB && - glLinkProgramARB && - glShaderSourceARB && - glUniform1iARB && - glUseProgramObjectARB) { - shaders_supported = SDL_TRUE; - } - } - - if (!shaders_supported) { - return SDL_FALSE; - } - - /* Compile all the shaders */ - for (i = 0; i < NUM_SHADERS; ++i) { - if (!CompileShaderProgram(&shaders[i])) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to compile shader!\n"); - return SDL_FALSE; - } - } - - /* We're done! */ - return SDL_TRUE; -} - -static void QuitShaders() -{ - int i; - - for (i = 0; i < NUM_SHADERS; ++i) { - DestroyShaderProgram(&shaders[i]); - } -} - -/* Quick utility function for texture creation */ -static int -power_of_two(int input) -{ - int value = 1; - - while (value < input) { - value <<= 1; - } - return value; -} - -GLuint -SDL_GL_LoadTexture(SDL_Surface * surface, GLfloat * texcoord) -{ - GLuint texture; - int w, h; - SDL_Surface *image; - SDL_Rect area; - SDL_BlendMode saved_mode; - - /* Use the surface width and height expanded to powers of 2 */ - w = power_of_two(surface->w); - h = power_of_two(surface->h); - texcoord[0] = 0.0f; /* Min X */ - texcoord[1] = 0.0f; /* Min Y */ - texcoord[2] = (GLfloat) surface->w / w; /* Max X */ - texcoord[3] = (GLfloat) surface->h / h; /* Max Y */ - - image = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, -#if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */ - 0x000000FF, - 0x0000FF00, 0x00FF0000, 0xFF000000 -#else - 0xFF000000, - 0x00FF0000, 0x0000FF00, 0x000000FF -#endif - ); - if (image == NULL) { - return 0; - } - - /* Save the alpha blending attributes */ - SDL_GetSurfaceBlendMode(surface, &saved_mode); - SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_NONE); - - /* Copy the surface into the GL texture image */ - area.x = 0; - area.y = 0; - area.w = surface->w; - area.h = surface->h; - SDL_BlitSurface(surface, &area, image, &area); - - /* Restore the alpha blending attributes */ - SDL_SetSurfaceBlendMode(surface, saved_mode); - - /* Create an OpenGL texture for the image */ - glGenTextures(1, &texture); - glBindTexture(GL_TEXTURE_2D, texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_2D, - 0, - GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, image->pixels); - SDL_FreeSurface(image); /* No longer needed */ - - return texture; -} - -/* A general OpenGL initialization function. Sets all of the initial parameters. */ -void InitGL(int Width, int Height) /* We call this right after our OpenGL window is created. */ -{ - GLdouble aspect; - - glViewport(0, 0, Width, Height); - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); /* This Will Clear The Background Color To Black */ - glClearDepth(1.0); /* Enables Clearing Of The Depth Buffer */ - glDepthFunc(GL_LESS); /* The Type Of Depth Test To Do */ - glEnable(GL_DEPTH_TEST); /* Enables Depth Testing */ - glShadeModel(GL_SMOOTH); /* Enables Smooth Color Shading */ - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); /* Reset The Projection Matrix */ - - aspect = (GLdouble)Width / Height; - glOrtho(-3.0, 3.0, -3.0 / aspect, 3.0 / aspect, 0.0, 1.0); - - glMatrixMode(GL_MODELVIEW); -} - -/* The main drawing function. */ -void DrawGLScene(SDL_Window *window, GLuint texture, GLfloat * texcoord) -{ - /* Texture coordinate lookup, to make it simple */ - enum { - MINX, - MINY, - MAXX, - MAXY - }; - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* Clear The Screen And The Depth Buffer */ - glLoadIdentity(); /* Reset The View */ - - glTranslatef(-1.5f,0.0f,0.0f); /* Move Left 1.5 Units */ - - /* draw a triangle (in smooth coloring mode) */ - glBegin(GL_POLYGON); /* start drawing a polygon */ - glColor3f(1.0f,0.0f,0.0f); /* Set The Color To Red */ - glVertex3f( 0.0f, 1.0f, 0.0f); /* Top */ - glColor3f(0.0f,1.0f,0.0f); /* Set The Color To Green */ - glVertex3f( 1.0f,-1.0f, 0.0f); /* Bottom Right */ - glColor3f(0.0f,0.0f,1.0f); /* Set The Color To Blue */ - glVertex3f(-1.0f,-1.0f, 0.0f); /* Bottom Left */ - glEnd(); /* we're done with the polygon (smooth color interpolation) */ - - glTranslatef(3.0f,0.0f,0.0f); /* Move Right 3 Units */ - - /* Enable blending */ - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - /* draw a textured square (quadrilateral) */ - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, texture); - glColor3f(1.0f,1.0f,1.0f); - if (shaders_supported) { - glUseProgramObjectARB(shaders[current_shader].program); - } - - glBegin(GL_QUADS); /* start drawing a polygon (4 sided) */ - glTexCoord2f(texcoord[MINX], texcoord[MINY]); - glVertex3f(-1.0f, 1.0f, 0.0f); /* Top Left */ - glTexCoord2f(texcoord[MAXX], texcoord[MINY]); - glVertex3f( 1.0f, 1.0f, 0.0f); /* Top Right */ - glTexCoord2f(texcoord[MAXX], texcoord[MAXY]); - glVertex3f( 1.0f,-1.0f, 0.0f); /* Bottom Right */ - glTexCoord2f(texcoord[MINX], texcoord[MAXY]); - glVertex3f(-1.0f,-1.0f, 0.0f); /* Bottom Left */ - glEnd(); /* done with the polygon */ - - if (shaders_supported) { - glUseProgramObjectARB(0); - } - glDisable(GL_TEXTURE_2D); - - /* swap buffers to display, since we're double buffered. */ - SDL_GL_SwapWindow(window); -} - -int main(int argc, char **argv) -{ - int done; - SDL_Window *window; - SDL_Surface *surface; - GLuint texture; - GLfloat texcoords[4]; - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - /* Initialize SDL for video output */ - if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to initialize SDL: %s\n", SDL_GetError()); - exit(1); - } - - /* Create a 640x480 OpenGL screen */ - window = SDL_CreateWindow( "Shader Demo", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, SDL_WINDOW_OPENGL ); - if ( !window ) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to create OpenGL window: %s\n", SDL_GetError()); - SDL_Quit(); - exit(2); - } - - if ( !SDL_GL_CreateContext(window)) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to create OpenGL context: %s\n", SDL_GetError()); - SDL_Quit(); - exit(2); - } - - surface = SDL_LoadBMP("icon.bmp"); - if ( ! surface ) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to load icon.bmp: %s\n", SDL_GetError()); - SDL_Quit(); - exit(3); - } - texture = SDL_GL_LoadTexture(surface, texcoords); - SDL_FreeSurface(surface); - - /* Loop, drawing and checking events */ - InitGL(640, 480); - if (InitShaders()) { - SDL_Log("Shaders supported, press SPACE to cycle them.\n"); - } else { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Shaders not supported!\n"); - } - done = 0; - while ( ! done ) { - DrawGLScene(window, texture, texcoords); - - /* This could go in a separate function */ - { SDL_Event event; - while ( SDL_PollEvent(&event) ) { - if ( event.type == SDL_QUIT ) { - done = 1; - } - if ( event.type == SDL_KEYDOWN ) { - if ( event.key.keysym.sym == SDLK_SPACE ) { - current_shader = (current_shader + 1) % NUM_SHADERS; - } - if ( event.key.keysym.sym == SDLK_ESCAPE ) { - done = 1; - } - } - } - } - } - QuitShaders(); - SDL_Quit(); - return 1; -} - -#else /* HAVE_OPENGL */ - -int -main(int argc, char *argv[]) -{ - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "No OpenGL support on this system\n"); - return 1; -} - -#endif /* HAVE_OPENGL */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/test/testshape.c b/SDL2-2.0.12/test/testshape.c deleted file mode 100644 index 63288d4..0000000 --- a/SDL2-2.0.12/test/testshape.c +++ /dev/null @@ -1,200 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ -#include -#include -#include -#include "SDL.h" -#include "SDL_shape.h" - -#define SHAPED_WINDOW_X 150 -#define SHAPED_WINDOW_Y 150 -#define SHAPED_WINDOW_DIMENSION 640 - -typedef struct LoadedPicture { - SDL_Surface *surface; - SDL_Texture *texture; - SDL_WindowShapeMode mode; - const char* name; -} LoadedPicture; - -void render(SDL_Renderer *renderer,SDL_Texture *texture,SDL_Rect texture_dimensions) -{ - /* Clear render-target to blue. */ - SDL_SetRenderDrawColor(renderer,0x00,0x00,0xff,0xff); - SDL_RenderClear(renderer); - - /* Render the texture. */ - SDL_RenderCopy(renderer,texture,&texture_dimensions,&texture_dimensions); - - SDL_RenderPresent(renderer); -} - -int main(int argc,char** argv) -{ - Uint8 num_pictures; - LoadedPicture* pictures; - int i, j; - SDL_PixelFormat* format = NULL; - SDL_Window *window; - SDL_Renderer *renderer; - SDL_Color black = {0,0,0,0xff}; - SDL_Event event; - int should_exit = 0; - unsigned int current_picture; - int button_down; - Uint32 pixelFormat = 0; - int access = 0; - SDL_Rect texture_dimensions; - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - if(argc < 2) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_Shape requires at least one bitmap file as argument."); - exit(-1); - } - - if(SDL_VideoInit(NULL) == -1) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not initialize SDL video."); - exit(-2); - } - - num_pictures = argc - 1; - pictures = (LoadedPicture *)SDL_malloc(sizeof(LoadedPicture)*num_pictures); - if (!pictures) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not allocate memory."); - exit(1); - } - for(i=0;iformat; - if(SDL_ISPIXELFORMAT_ALPHA(format->format)) { - pictures[i].mode.mode = ShapeModeBinarizeAlpha; - pictures[i].mode.parameters.binarizationCutoff = 255; - } - else { - pictures[i].mode.mode = ShapeModeColorKey; - pictures[i].mode.parameters.colorKey = black; - } - } - - window = SDL_CreateShapedWindow("SDL_Shape test", - SHAPED_WINDOW_X, SHAPED_WINDOW_Y, - SHAPED_WINDOW_DIMENSION,SHAPED_WINDOW_DIMENSION, - 0); - SDL_SetWindowPosition(window, SHAPED_WINDOW_X, SHAPED_WINDOW_Y); - if(window == NULL) { - for(i=0;i= num_pictures) - current_picture = 0; - SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Changing to shaped bmp: %s", pictures[current_picture].name); - SDL_QueryTexture(pictures[current_picture].texture,(Uint32 *)&pixelFormat,(int *)&access,&texture_dimensions.w,&texture_dimensions.h); - SDL_SetWindowSize(window,texture_dimensions.w,texture_dimensions.h); - SDL_SetWindowShape(window,pictures[current_picture].surface,&pictures[current_picture].mode); - } - if (event.type == SDL_QUIT) { - should_exit = 1; - break; - } - } - render(renderer,pictures[current_picture].texture,texture_dimensions); - SDL_Delay(10); - } - - /* Free the textures. */ - for(i=0;i - - 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. -*/ -/* Simple program: Move N sprites around on the screen as fast as possible */ - -#include -#include -#include - -#ifdef __EMSCRIPTEN__ -#include -#endif - -#include "SDL.h" - -#define WINDOW_WIDTH 640 -#define WINDOW_HEIGHT 480 -#define NUM_SPRITES 100 -#define MAX_SPEED 1 - -static SDL_Texture *sprite; -static SDL_Rect positions[NUM_SPRITES]; -static SDL_Rect velocities[NUM_SPRITES]; -static int sprite_w, sprite_h; - -SDL_Renderer *renderer; -int done; - -/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ -static void -quit(int rc) -{ - exit(rc); -} - -int -LoadSprite(char *file, SDL_Renderer *renderer) -{ - SDL_Surface *temp; - - /* Load the sprite image */ - temp = SDL_LoadBMP(file); - if (temp == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", file, SDL_GetError()); - return (-1); - } - sprite_w = temp->w; - sprite_h = temp->h; - - /* Set transparent pixel as the pixel at (0,0) */ - if (temp->format->palette) { - SDL_SetColorKey(temp, SDL_TRUE, *(Uint8 *) temp->pixels); - } else { - switch (temp->format->BitsPerPixel) { - case 15: - SDL_SetColorKey(temp, SDL_TRUE, - (*(Uint16 *) temp->pixels) & 0x00007FFF); - break; - case 16: - SDL_SetColorKey(temp, SDL_TRUE, *(Uint16 *) temp->pixels); - break; - case 24: - SDL_SetColorKey(temp, SDL_TRUE, - (*(Uint32 *) temp->pixels) & 0x00FFFFFF); - break; - case 32: - SDL_SetColorKey(temp, SDL_TRUE, *(Uint32 *) temp->pixels); - break; - } - } - - /* Create textures from the image */ - sprite = SDL_CreateTextureFromSurface(renderer, temp); - if (!sprite) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError()); - SDL_FreeSurface(temp); - return (-1); - } - SDL_FreeSurface(temp); - - /* We're ready to roll. :) */ - return (0); -} - -void -MoveSprites(SDL_Renderer * renderer, SDL_Texture * sprite) -{ - int i; - int window_w = WINDOW_WIDTH; - int window_h = WINDOW_HEIGHT; - SDL_Rect *position, *velocity; - - /* Draw a gray background */ - SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF); - SDL_RenderClear(renderer); - - /* Move the sprite, bounce at the wall, and draw */ - for (i = 0; i < NUM_SPRITES; ++i) { - position = &positions[i]; - velocity = &velocities[i]; - position->x += velocity->x; - if ((position->x < 0) || (position->x >= (window_w - sprite_w))) { - velocity->x = -velocity->x; - position->x += velocity->x; - } - position->y += velocity->y; - if ((position->y < 0) || (position->y >= (window_h - sprite_h))) { - velocity->y = -velocity->y; - position->y += velocity->y; - } - - /* Blit the sprite onto the screen */ - SDL_RenderCopy(renderer, sprite, NULL, position); - } - - /* Update the screen! */ - SDL_RenderPresent(renderer); -} - -void loop() -{ - SDL_Event event; - - /* Check for events */ - while (SDL_PollEvent(&event)) { - if (event.type == SDL_QUIT || event.type == SDL_KEYDOWN) { - done = 1; - } - } - MoveSprites(renderer, sprite); -#ifdef __EMSCRIPTEN__ - if (done) { - emscripten_cancel_main_loop(); - } -#endif -} - -int -main(int argc, char *argv[]) -{ - SDL_Window *window; - int i; - - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - if (SDL_CreateWindowAndRenderer(WINDOW_WIDTH, WINDOW_HEIGHT, 0, &window, &renderer) < 0) { - quit(2); - } - - if (LoadSprite("icon.bmp", renderer) < 0) { - quit(2); - } - - /* Initialize the sprite positions */ - srand(time(NULL)); - for (i = 0; i < NUM_SPRITES; ++i) { - positions[i].x = rand() % (WINDOW_WIDTH - sprite_w); - positions[i].y = rand() % (WINDOW_HEIGHT - sprite_h); - positions[i].w = sprite_w; - positions[i].h = sprite_h; - velocities[i].x = 0; - velocities[i].y = 0; - while (!velocities[i].x && !velocities[i].y) { - velocities[i].x = (rand() % (MAX_SPEED * 2 + 1)) - MAX_SPEED; - velocities[i].y = (rand() % (MAX_SPEED * 2 + 1)) - MAX_SPEED; - } - } - - /* Main render loop */ - done = 0; - -#ifdef __EMSCRIPTEN__ - emscripten_set_main_loop(loop, 0, 1); -#else - while (!done) { - loop(); - } -#endif - quit(0); - - return 0; /* to prevent compiler warning */ -} - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/test/teststreaming.c b/SDL2-2.0.12/test/teststreaming.c deleted file mode 100644 index 565d5c8..0000000 --- a/SDL2-2.0.12/test/teststreaming.c +++ /dev/null @@ -1,190 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ -/******************************************************************************** - * * - * Running moose :) Coded by Mike Gorchak. * - * * - ********************************************************************************/ - -#include -#include - -#ifdef __EMSCRIPTEN__ -#include -#endif - -#include "SDL.h" - -#define MOOSEPIC_W 64 -#define MOOSEPIC_H 88 - -#define MOOSEFRAME_SIZE (MOOSEPIC_W * MOOSEPIC_H) -#define MOOSEFRAMES_COUNT 10 - -SDL_Color MooseColors[84] = { - {49, 49, 49, 255}, {66, 24, 0, 255}, {66, 33, 0, 255}, {66, 66, 66, 255}, - {66, 115, 49, 255}, {74, 33, 0, 255}, {74, 41, 16, 255}, {82, 33, 8, 255}, - {82, 41, 8, 255}, {82, 49, 16, 255}, {82, 82, 82, 255}, {90, 41, 8, 255}, - {90, 41, 16, 255}, {90, 57, 24, 255}, {99, 49, 16, 255}, {99, 66, 24, 255}, - {99, 66, 33, 255}, {99, 74, 33, 255}, {107, 57, 24, 255}, {107, 82, 41, 255}, - {115, 57, 33, 255}, {115, 66, 33, 255}, {115, 66, 41, 255}, {115, 74, 0, 255}, - {115, 90, 49, 255}, {115, 115, 115, 255}, {123, 82, 0, 255}, {123, 99, 57, 255}, - {132, 66, 41, 255}, {132, 74, 41, 255}, {132, 90, 8, 255}, {132, 99, 33, 255}, - {132, 99, 66, 255}, {132, 107, 66, 255}, {140, 74, 49, 255}, {140, 99, 16, 255}, - {140, 107, 74, 255}, {140, 115, 74, 255}, {148, 107, 24, 255}, {148, 115, 82, 255}, - {148, 123, 74, 255}, {148, 123, 90, 255}, {156, 115, 33, 255}, {156, 115, 90, 255}, - {156, 123, 82, 255}, {156, 132, 82, 255}, {156, 132, 99, 255}, {156, 156, 156, 255}, - {165, 123, 49, 255}, {165, 123, 90, 255}, {165, 132, 82, 255}, {165, 132, 90, 255}, - {165, 132, 99, 255}, {165, 140, 90, 255}, {173, 132, 57, 255}, {173, 132, 99, 255}, - {173, 140, 107, 255}, {173, 140, 115, 255}, {173, 148, 99, 255}, {173, 173, 173, 255}, - {181, 140, 74, 255}, {181, 148, 115, 255}, {181, 148, 123, 255}, {181, 156, 107, 255}, - {189, 148, 123, 255}, {189, 156, 82, 255}, {189, 156, 123, 255}, {189, 156, 132, 255}, - {189, 189, 189, 255}, {198, 156, 123, 255}, {198, 165, 132, 255}, {206, 165, 99, 255}, - {206, 165, 132, 255}, {206, 173, 140, 255}, {206, 206, 206, 255}, {214, 173, 115, 255}, - {214, 173, 140, 255}, {222, 181, 148, 255}, {222, 189, 132, 255}, {222, 189, 156, 255}, - {222, 222, 222, 255}, {231, 198, 165, 255}, {231, 231, 231, 255}, {239, 206, 173, 255} -}; - -Uint8 MooseFrames[MOOSEFRAMES_COUNT][MOOSEFRAME_SIZE]; - -SDL_Renderer *renderer; -int frame; -SDL_Texture *MooseTexture; -SDL_bool done = SDL_FALSE; - -void quit(int rc) -{ - SDL_Quit(); - exit(rc); -} - -void UpdateTexture(SDL_Texture *texture, int frame) -{ - SDL_Color *color; - Uint8 *src; - Uint32 *dst; - int row, col; - void *pixels; - int pitch; - - if (SDL_LockTexture(texture, NULL, &pixels, &pitch) < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't lock texture: %s\n", SDL_GetError()); - quit(5); - } - src = MooseFrames[frame]; - for (row = 0; row < MOOSEPIC_H; ++row) { - dst = (Uint32*)((Uint8*)pixels + row * pitch); - for (col = 0; col < MOOSEPIC_W; ++col) { - color = &MooseColors[*src++]; - *dst++ = (0xFF000000|(color->r<<16)|(color->g<<8)|color->b); - } - } - SDL_UnlockTexture(texture); -} - -void -loop() -{ - SDL_Event event; - - while (SDL_PollEvent(&event)) { - switch (event.type) { - case SDL_KEYDOWN: - if (event.key.keysym.sym == SDLK_ESCAPE) { - done = SDL_TRUE; - } - break; - case SDL_QUIT: - done = SDL_TRUE; - break; - } - } - - frame = (frame + 1) % MOOSEFRAMES_COUNT; - UpdateTexture(MooseTexture, frame); - - SDL_RenderClear(renderer); - SDL_RenderCopy(renderer, MooseTexture, NULL, NULL); - SDL_RenderPresent(renderer); - -#ifdef __EMSCRIPTEN__ - if (done) { - emscripten_cancel_main_loop(); - } -#endif -} - -int -main(int argc, char **argv) -{ - SDL_Window *window; - SDL_RWops *handle; - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - if (SDL_Init(SDL_INIT_VIDEO) < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError()); - return 1; - } - - /* load the moose images */ - handle = SDL_RWFromFile("moose.dat", "rb"); - if (handle == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Can't find the file moose.dat !\n"); - quit(2); - } - SDL_RWread(handle, MooseFrames, MOOSEFRAME_SIZE, MOOSEFRAMES_COUNT); - SDL_RWclose(handle); - - - /* Create the window and renderer */ - window = SDL_CreateWindow("Happy Moose", - SDL_WINDOWPOS_UNDEFINED, - SDL_WINDOWPOS_UNDEFINED, - MOOSEPIC_W*4, MOOSEPIC_H*4, - SDL_WINDOW_RESIZABLE); - if (!window) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't set create window: %s\n", SDL_GetError()); - quit(3); - } - - renderer = SDL_CreateRenderer(window, -1, 0); - if (!renderer) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't set create renderer: %s\n", SDL_GetError()); - quit(4); - } - - MooseTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, MOOSEPIC_W, MOOSEPIC_H); - if (!MooseTexture) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't set create texture: %s\n", SDL_GetError()); - quit(5); - } - - /* Loop, waiting for QUIT or the escape key */ - frame = 0; - -#ifdef __EMSCRIPTEN__ - emscripten_set_main_loop(loop, 0, 1); -#else - while (!done) { - loop(); - } -#endif - - SDL_DestroyRenderer(renderer); - - quit(0); - return 0; -} - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/test/testthread.c b/SDL2-2.0.12/test/testthread.c deleted file mode 100644 index 2c95a73..0000000 --- a/SDL2-2.0.12/test/testthread.c +++ /dev/null @@ -1,130 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ - -/* Simple test of the SDL threading code */ - -#include -#include -#include - -#include "SDL.h" - -static SDL_TLSID tls; -static int alive = 0; -static int testprio = 0; - -/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ -static void -quit(int rc) -{ - SDL_Quit(); - exit(rc); -} - -static const char * -getprioritystr(SDL_ThreadPriority priority) -{ - switch(priority) - { - case SDL_THREAD_PRIORITY_LOW: return "SDL_THREAD_PRIORITY_LOW"; - case SDL_THREAD_PRIORITY_NORMAL: return "SDL_THREAD_PRIORITY_NORMAL"; - case SDL_THREAD_PRIORITY_HIGH: return "SDL_THREAD_PRIORITY_HIGH"; - case SDL_THREAD_PRIORITY_TIME_CRITICAL: return "SDL_THREAD_PRIORITY_TIME_CRITICAL"; - } - - return "???"; -} - -int SDLCALL -ThreadFunc(void *data) -{ - SDL_ThreadPriority prio = SDL_THREAD_PRIORITY_NORMAL; - - SDL_TLSSet(tls, "baby thread", NULL); - SDL_Log("Started thread %s: My thread id is %lu, thread data = %s\n", - (char *) data, SDL_ThreadID(), (const char *)SDL_TLSGet(tls)); - while (alive) { - SDL_Log("Thread '%s' is alive!\n", (char *) data); - - if (testprio) { - SDL_Log("SDL_SetThreadPriority(%s):%d\n", getprioritystr(prio), SDL_SetThreadPriority(prio)); - if (++prio > SDL_THREAD_PRIORITY_TIME_CRITICAL) - prio = SDL_THREAD_PRIORITY_LOW; - } - - SDL_Delay(1 * 1000); - } - SDL_Log("Thread '%s' exiting!\n", (char *) data); - return (0); -} - -static void -killed(int sig) -{ - SDL_Log("Killed with SIGTERM, waiting 5 seconds to exit\n"); - SDL_Delay(5 * 1000); - alive = 0; - quit(0); -} - -int -main(int argc, char *argv[]) -{ - int arg = 1; - SDL_Thread *thread; - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - /* Load the SDL library */ - if (SDL_Init(0) < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError()); - return (1); - } - - while (argv[arg] && *argv[arg] == '-') { - if (SDL_strcmp(argv[arg], "--prio") == 0) { - testprio = 1; - } - ++arg; - } - - tls = SDL_TLSCreate(); - SDL_assert(tls); - SDL_TLSSet(tls, "main thread", NULL); - SDL_Log("Main thread data initially: %s\n", (const char *)SDL_TLSGet(tls)); - - alive = 1; - thread = SDL_CreateThread(ThreadFunc, "One", "#1"); - if (thread == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create thread: %s\n", SDL_GetError()); - quit(1); - } - SDL_Delay(5 * 1000); - SDL_Log("Waiting for thread #1\n"); - alive = 0; - SDL_WaitThread(thread, NULL); - - SDL_Log("Main thread data finally: %s\n", (const char *)SDL_TLSGet(tls)); - - alive = 1; - signal(SIGTERM, killed); - thread = SDL_CreateThread(ThreadFunc, "Two", "#2"); - if (thread == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create thread: %s\n", SDL_GetError()); - quit(1); - } - raise(SIGTERM); - - SDL_Quit(); /* Never reached */ - return (0); /* Never reached */ -} diff --git a/SDL2-2.0.12/test/testtimer.c b/SDL2-2.0.12/test/testtimer.c deleted file mode 100644 index 2e995e3..0000000 --- a/SDL2-2.0.12/test/testtimer.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ - -/* Test program to check the resolution of the SDL timer on the current - platform -*/ - -#include -#include - -#include "SDL.h" - -#define DEFAULT_RESOLUTION 1 - -static int ticks = 0; - -static Uint32 SDLCALL -ticktock(Uint32 interval, void *param) -{ - ++ticks; - return (interval); -} - -static Uint32 SDLCALL -callback(Uint32 interval, void *param) -{ - SDL_Log("Timer %d : param = %d\n", interval, (int) (uintptr_t) param); - return interval; -} - -int -main(int argc, char *argv[]) -{ - int i, desired; - SDL_TimerID t1, t2, t3; - Uint32 start32, now32; - Uint64 start, now; - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - if (SDL_Init(SDL_INIT_TIMER) < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError()); - return (1); - } - - /* Start the timer */ - desired = 0; - if (argv[1]) { - desired = atoi(argv[1]); - } - if (desired == 0) { - desired = DEFAULT_RESOLUTION; - } - t1 = SDL_AddTimer(desired, ticktock, NULL); - - /* Wait 10 seconds */ - SDL_Log("Waiting 10 seconds\n"); - SDL_Delay(10 * 1000); - - /* Stop the timer */ - SDL_RemoveTimer(t1); - - /* Print the results */ - if (ticks) { - SDL_Log("Timer resolution: desired = %d ms, actual = %f ms\n", - desired, (double) (10 * 1000) / ticks); - } - - /* Test multiple timers */ - SDL_Log("Testing multiple timers...\n"); - t1 = SDL_AddTimer(100, callback, (void *) 1); - if (!t1) - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,"Could not create timer 1: %s\n", SDL_GetError()); - t2 = SDL_AddTimer(50, callback, (void *) 2); - if (!t2) - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,"Could not create timer 2: %s\n", SDL_GetError()); - t3 = SDL_AddTimer(233, callback, (void *) 3); - if (!t3) - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,"Could not create timer 3: %s\n", SDL_GetError()); - - /* Wait 10 seconds */ - SDL_Log("Waiting 10 seconds\n"); - SDL_Delay(10 * 1000); - - SDL_Log("Removing timer 1 and waiting 5 more seconds\n"); - SDL_RemoveTimer(t1); - - SDL_Delay(5 * 1000); - - SDL_RemoveTimer(t2); - SDL_RemoveTimer(t3); - - start = SDL_GetPerformanceCounter(); - for (i = 0; i < 1000000; ++i) { - ticktock(0, NULL); - } - now = SDL_GetPerformanceCounter(); - SDL_Log("1 million iterations of ticktock took %f ms\n", (double)((now - start)*1000) / SDL_GetPerformanceFrequency()); - - SDL_Log("Performance counter frequency: %"SDL_PRIu64"\n", (unsigned long long) SDL_GetPerformanceFrequency()); - start32 = SDL_GetTicks(); - start = SDL_GetPerformanceCounter(); - SDL_Delay(1000); - now = SDL_GetPerformanceCounter(); - now32 = SDL_GetTicks(); - SDL_Log("Delay 1 second = %d ms in ticks, %f ms according to performance counter\n", (now32-start32), (double)((now - start)*1000) / SDL_GetPerformanceFrequency()); - - SDL_Quit(); - return (0); -} - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/test/testver.c b/SDL2-2.0.12/test/testver.c deleted file mode 100644 index 94bceae..0000000 --- a/SDL2-2.0.12/test/testver.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ - -/* Test program to compare the compile-time version of SDL with the linked - version of SDL -*/ - -#include -#include - -#include "SDL.h" -#include "SDL_revision.h" - -int -main(int argc, char *argv[]) -{ - SDL_version compiled; - SDL_version linked; - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - -#if SDL_VERSION_ATLEAST(2, 0, 0) - SDL_Log("Compiled with SDL 2.0 or newer\n"); -#else - SDL_Log("Compiled with SDL older than 2.0\n"); -#endif - SDL_VERSION(&compiled); - SDL_Log("Compiled version: %d.%d.%d.%d (%s)\n", - compiled.major, compiled.minor, compiled.patch, - SDL_REVISION_NUMBER, SDL_REVISION); - SDL_GetVersion(&linked); - SDL_Log("Linked version: %d.%d.%d.%d (%s)\n", - linked.major, linked.minor, linked.patch, - SDL_GetRevisionNumber(), SDL_GetRevision()); - SDL_Quit(); - return (0); -} diff --git a/SDL2-2.0.12/test/testviewport.c b/SDL2-2.0.12/test/testviewport.c deleted file mode 100644 index fc44fe1..0000000 --- a/SDL2-2.0.12/test/testviewport.c +++ /dev/null @@ -1,279 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ -/* Simple program: Check viewports */ - -#include -#include -#include - -#ifdef __EMSCRIPTEN__ -#include -#endif - -#include "SDL_test.h" -#include "SDL_test_common.h" - - -static SDLTest_CommonState *state; - -static SDL_Rect viewport; -static int done, j; -static SDL_bool use_target = SDL_FALSE; -#ifdef __EMSCRIPTEN__ -static Uint32 wait_start; -#endif -static SDL_Texture *sprite; -static int sprite_w, sprite_h; - -/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ -static void -quit(int rc) -{ - SDLTest_CommonQuit(state); - exit(rc); -} - -int -LoadSprite(char *file, SDL_Renderer *renderer) -{ - SDL_Surface *temp; - - /* Load the sprite image */ - temp = SDL_LoadBMP(file); - if (temp == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", file, SDL_GetError()); - return (-1); - } - sprite_w = temp->w; - sprite_h = temp->h; - - /* Set transparent pixel as the pixel at (0,0) */ - if (temp->format->palette) { - SDL_SetColorKey(temp, SDL_TRUE, *(Uint8 *) temp->pixels); - } else { - switch (temp->format->BitsPerPixel) { - case 15: - SDL_SetColorKey(temp, SDL_TRUE, - (*(Uint16 *) temp->pixels) & 0x00007FFF); - break; - case 16: - SDL_SetColorKey(temp, SDL_TRUE, *(Uint16 *) temp->pixels); - break; - case 24: - SDL_SetColorKey(temp, SDL_TRUE, - (*(Uint32 *) temp->pixels) & 0x00FFFFFF); - break; - case 32: - SDL_SetColorKey(temp, SDL_TRUE, *(Uint32 *) temp->pixels); - break; - } - } - - /* Create textures from the image */ - sprite = SDL_CreateTextureFromSurface(renderer, temp); - if (!sprite) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError()); - SDL_FreeSurface(temp); - return (-1); - } - SDL_FreeSurface(temp); - - /* We're ready to roll. :) */ - return (0); -} - -void -DrawOnViewport(SDL_Renderer * renderer, SDL_Rect viewport) -{ - SDL_Rect rect; - - /* Set the viewport */ - SDL_RenderSetViewport(renderer, &viewport); - - /* Draw a gray background */ - SDL_SetRenderDrawColor(renderer, 0x80, 0x80, 0x80, 0xFF); - SDL_RenderClear(renderer); - - /* Test inside points */ - SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0x00, 0xFF); - SDL_RenderDrawPoint(renderer, viewport.h/2 + 20, viewport.w/2); - SDL_RenderDrawPoint(renderer, viewport.h/2 - 20, viewport.w/2); - SDL_RenderDrawPoint(renderer, viewport.h/2 , viewport.w/2 - 20); - SDL_RenderDrawPoint(renderer, viewport.h/2 , viewport.w/2 + 20); - - /* Test horizontal and vertical lines */ - SDL_SetRenderDrawColor(renderer, 0x00, 0xFF, 0x00, 0xFF); - SDL_RenderDrawLine(renderer, 1, 0, viewport.w-2, 0); - SDL_RenderDrawLine(renderer, 1, viewport.h-1, viewport.w-2, viewport.h-1); - SDL_RenderDrawLine(renderer, 0, 1, 0, viewport.h-2); - SDL_RenderDrawLine(renderer, viewport.w-1, 1, viewport.w-1, viewport.h-2); - - /* Test diagonal lines */ - SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0xFF, 0xFF); - SDL_RenderDrawLine(renderer, 0, 0, viewport.w-1, viewport.h-1); - SDL_RenderDrawLine(renderer, viewport.w-1, 0, 0, viewport.h-1); - - /* Test outside points */ - SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0x00, 0xFF); - SDL_RenderDrawPoint(renderer, viewport.h/2 + viewport.h, viewport.w/2); - SDL_RenderDrawPoint(renderer, viewport.h/2 - viewport.h, viewport.w/2); - SDL_RenderDrawPoint(renderer, viewport.h/2, viewport.w/2 - viewport.w); - SDL_RenderDrawPoint(renderer, viewport.h/2, viewport.w/2 + viewport.w); - - /* Add a box at the top */ - rect.w = 8; - rect.h = 8; - rect.x = (viewport.w - rect.w) / 2; - rect.y = 0; - SDL_RenderFillRect(renderer, &rect); - - /* Add a clip rect and fill it with the sprite */ - SDL_QueryTexture(sprite, NULL, NULL, &rect.w, &rect.h); - rect.x = (viewport.w - rect.w) / 2; - rect.y = (viewport.h - rect.h) / 2; - SDL_RenderSetClipRect(renderer, &rect); - SDL_RenderCopy(renderer, sprite, NULL, &rect); - SDL_RenderSetClipRect(renderer, NULL); -} - -void -loop() -{ -#ifdef __EMSCRIPTEN__ - /* Avoid using delays */ - if(SDL_GetTicks() - wait_start < 1000) - return; - wait_start = SDL_GetTicks(); -#endif - SDL_Event event; - int i; - /* Check for events */ - while (SDL_PollEvent(&event)) { - SDLTest_CommonEvent(state, &event, &done); - } - - /* Move a viewport box in steps around the screen */ - viewport.x = j * 100; - viewport.y = viewport.x; - viewport.w = 100 + j * 50; - viewport.h = 100 + j * 50; - j = (j + 1) % 4; - SDL_Log("Current Viewport x=%i y=%i w=%i h=%i", viewport.x, viewport.y, viewport.w, viewport.h); - - for (i = 0; i < state->num_windows; ++i) { - if (state->windows[i] == NULL) - continue; - - /* Draw using viewport */ - DrawOnViewport(state->renderers[i], viewport); - - /* Update the screen! */ - if (use_target) { - SDL_SetRenderTarget(state->renderers[i], NULL); - SDL_RenderCopy(state->renderers[i], state->targets[i], NULL, NULL); - SDL_RenderPresent(state->renderers[i]); - SDL_SetRenderTarget(state->renderers[i], state->targets[i]); - } else { - SDL_RenderPresent(state->renderers[i]); - } - } - -#ifdef __EMSCRIPTEN__ - if (done) { - emscripten_cancel_main_loop(); - } -#endif -} - -int -main(int argc, char *argv[]) -{ - int i; - Uint32 then, now, frames; - - /* Initialize test framework */ - state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO); - if (!state) { - return 1; - } - - - for (i = 1; i < argc;) { - int consumed; - - consumed = SDLTest_CommonArg(state, i); - if (consumed == 0) { - consumed = -1; - if (SDL_strcasecmp(argv[i], "--target") == 0) { - use_target = SDL_TRUE; - consumed = 1; - } - } - if (consumed < 0) { - static const char *options[] = { "[--target]", NULL }; - SDLTest_CommonLogUsage(state, argv[0], options); - quit(1); - } - i += consumed; - } - if (!SDLTest_CommonInit(state)) { - quit(2); - } - - if (LoadSprite("icon.bmp", state->renderers[0]) < 0) { - quit(2); - } - - if (use_target) { - int w, h; - - for (i = 0; i < state->num_windows; ++i) { - SDL_GetWindowSize(state->windows[i], &w, &h); - state->targets[i] = SDL_CreateTexture(state->renderers[i], SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, w, h); - SDL_SetRenderTarget(state->renderers[i], state->targets[i]); - } - } - - for (i = 0; i < state->num_windows; ++i) { - SDL_Renderer *renderer = state->renderers[i]; - SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF); - SDL_RenderClear(renderer); - } - - /* Main render loop */ - frames = 0; - then = SDL_GetTicks(); - done = 0; - j = 0; - -#ifdef __EMSCRIPTEN__ - wait_start = SDL_GetTicks(); - emscripten_set_main_loop(loop, 0, 1); -#else - while (!done) { - ++frames; - loop(); - SDL_Delay(1000); - } -#endif - - /* Print out some timing information */ - now = SDL_GetTicks(); - if (now > then) { - double fps = ((double) frames * 1000) / (now - then); - SDL_Log("%2.2f frames per second\n", fps); - } - quit(0); - return 0; -} - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/test/testvulkan.c b/SDL2-2.0.12/test/testvulkan.c deleted file mode 100644 index 14e2cdf..0000000 --- a/SDL2-2.0.12/test/testvulkan.c +++ /dev/null @@ -1,1189 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ -#include -#include -#include -#include - -#include "SDL_test_common.h" - -#if defined(__ANDROID__) && defined(__ARM_EABI__) && !defined(__ARM_ARCH_7A__) - -int main(int argc, char *argv[]) -{ - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "No Vulkan support on this system\n"); - return 1; -} - -#else - -#define VK_NO_PROTOTYPES -#ifdef HAVE_VULKAN_H -#include -#else -/* SDL includes a copy for building on systems without the Vulkan SDK */ -#include "../src/video/khronos/vulkan/vulkan.h" -#endif -#include "SDL_vulkan.h" - -#ifndef UINT64_MAX /* VS2008 */ -#define UINT64_MAX 18446744073709551615 -#endif - -#define VULKAN_FUNCTIONS() \ - VULKAN_DEVICE_FUNCTION(vkAcquireNextImageKHR) \ - VULKAN_DEVICE_FUNCTION(vkAllocateCommandBuffers) \ - VULKAN_DEVICE_FUNCTION(vkBeginCommandBuffer) \ - VULKAN_DEVICE_FUNCTION(vkCmdClearColorImage) \ - VULKAN_DEVICE_FUNCTION(vkCmdPipelineBarrier) \ - VULKAN_DEVICE_FUNCTION(vkCreateCommandPool) \ - VULKAN_DEVICE_FUNCTION(vkCreateFence) \ - VULKAN_DEVICE_FUNCTION(vkCreateImageView) \ - VULKAN_DEVICE_FUNCTION(vkCreateSemaphore) \ - VULKAN_DEVICE_FUNCTION(vkCreateSwapchainKHR) \ - VULKAN_DEVICE_FUNCTION(vkDestroyCommandPool) \ - VULKAN_DEVICE_FUNCTION(vkDestroyDevice) \ - VULKAN_DEVICE_FUNCTION(vkDestroyFence) \ - VULKAN_DEVICE_FUNCTION(vkDestroyImageView) \ - VULKAN_DEVICE_FUNCTION(vkDestroySemaphore) \ - VULKAN_DEVICE_FUNCTION(vkDestroySwapchainKHR) \ - VULKAN_DEVICE_FUNCTION(vkDeviceWaitIdle) \ - VULKAN_DEVICE_FUNCTION(vkEndCommandBuffer) \ - VULKAN_DEVICE_FUNCTION(vkFreeCommandBuffers) \ - VULKAN_DEVICE_FUNCTION(vkGetDeviceQueue) \ - VULKAN_DEVICE_FUNCTION(vkGetFenceStatus) \ - VULKAN_DEVICE_FUNCTION(vkGetSwapchainImagesKHR) \ - VULKAN_DEVICE_FUNCTION(vkQueuePresentKHR) \ - VULKAN_DEVICE_FUNCTION(vkQueueSubmit) \ - VULKAN_DEVICE_FUNCTION(vkResetCommandBuffer) \ - VULKAN_DEVICE_FUNCTION(vkResetFences) \ - VULKAN_DEVICE_FUNCTION(vkWaitForFences) \ - VULKAN_GLOBAL_FUNCTION(vkCreateInstance) \ - VULKAN_GLOBAL_FUNCTION(vkEnumerateInstanceExtensionProperties) \ - VULKAN_GLOBAL_FUNCTION(vkEnumerateInstanceLayerProperties) \ - VULKAN_INSTANCE_FUNCTION(vkCreateDevice) \ - VULKAN_INSTANCE_FUNCTION(vkDestroyInstance) \ - VULKAN_INSTANCE_FUNCTION(vkDestroySurfaceKHR) \ - VULKAN_INSTANCE_FUNCTION(vkEnumerateDeviceExtensionProperties) \ - VULKAN_INSTANCE_FUNCTION(vkEnumeratePhysicalDevices) \ - VULKAN_INSTANCE_FUNCTION(vkGetDeviceProcAddr) \ - VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceFeatures) \ - VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceProperties) \ - VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceQueueFamilyProperties) \ - VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceCapabilitiesKHR) \ - VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceFormatsKHR) \ - VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfacePresentModesKHR) \ - VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceSupportKHR) - -#define VULKAN_DEVICE_FUNCTION(name) static PFN_##name name = NULL; -#define VULKAN_GLOBAL_FUNCTION(name) static PFN_##name name = NULL; -#define VULKAN_INSTANCE_FUNCTION(name) static PFN_##name name = NULL; -VULKAN_FUNCTIONS() -#undef VULKAN_DEVICE_FUNCTION -#undef VULKAN_GLOBAL_FUNCTION -#undef VULKAN_INSTANCE_FUNCTION -static PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL; - -/* Based on the headers found in - * https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers - */ -#if VK_HEADER_VERSION < 22 -enum -{ - VK_ERROR_FRAGMENTED_POOL = -12, -}; -#endif -#if VK_HEADER_VERSION < 38 -enum { - VK_ERROR_OUT_OF_POOL_MEMORY_KHR = -1000069000 -}; -#endif - -static const char *getVulkanResultString(VkResult result) -{ - switch((int)result) - { - case VK_SUCCESS: - return "VK_SUCCESS"; - case VK_NOT_READY: - return "VK_NOT_READY"; - case VK_TIMEOUT: - return "VK_TIMEOUT"; - case VK_EVENT_SET: - return "VK_EVENT_SET"; - case VK_EVENT_RESET: - return "VK_EVENT_RESET"; - case VK_INCOMPLETE: - return "VK_INCOMPLETE"; - case VK_ERROR_OUT_OF_HOST_MEMORY: - return "VK_ERROR_OUT_OF_HOST_MEMORY"; - case VK_ERROR_OUT_OF_DEVICE_MEMORY: - return "VK_ERROR_OUT_OF_DEVICE_MEMORY"; - case VK_ERROR_INITIALIZATION_FAILED: - return "VK_ERROR_INITIALIZATION_FAILED"; - case VK_ERROR_DEVICE_LOST: - return "VK_ERROR_DEVICE_LOST"; - case VK_ERROR_MEMORY_MAP_FAILED: - return "VK_ERROR_MEMORY_MAP_FAILED"; - case VK_ERROR_LAYER_NOT_PRESENT: - return "VK_ERROR_LAYER_NOT_PRESENT"; - case VK_ERROR_EXTENSION_NOT_PRESENT: - return "VK_ERROR_EXTENSION_NOT_PRESENT"; - case VK_ERROR_FEATURE_NOT_PRESENT: - return "VK_ERROR_FEATURE_NOT_PRESENT"; - case VK_ERROR_INCOMPATIBLE_DRIVER: - return "VK_ERROR_INCOMPATIBLE_DRIVER"; - case VK_ERROR_TOO_MANY_OBJECTS: - return "VK_ERROR_TOO_MANY_OBJECTS"; - case VK_ERROR_FORMAT_NOT_SUPPORTED: - return "VK_ERROR_FORMAT_NOT_SUPPORTED"; - case VK_ERROR_FRAGMENTED_POOL: - return "VK_ERROR_FRAGMENTED_POOL"; - case VK_ERROR_SURFACE_LOST_KHR: - return "VK_ERROR_SURFACE_LOST_KHR"; - case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR: - return "VK_ERROR_NATIVE_WINDOW_IN_USE_KHR"; - case VK_SUBOPTIMAL_KHR: - return "VK_SUBOPTIMAL_KHR"; - case VK_ERROR_OUT_OF_DATE_KHR: - return "VK_ERROR_OUT_OF_DATE_KHR"; - case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR: - return "VK_ERROR_INCOMPATIBLE_DISPLAY_KHR"; - case VK_ERROR_VALIDATION_FAILED_EXT: - return "VK_ERROR_VALIDATION_FAILED_EXT"; - case VK_ERROR_OUT_OF_POOL_MEMORY_KHR: - return "VK_ERROR_OUT_OF_POOL_MEMORY_KHR"; - case VK_ERROR_INVALID_SHADER_NV: - return "VK_ERROR_INVALID_SHADER_NV"; - case VK_RESULT_MAX_ENUM: - case VK_RESULT_RANGE_SIZE: - break; - } - if(result < 0) - return "VK_ERROR_"; - return "VK_"; -} - -typedef struct VulkanContext -{ - VkInstance instance; - VkDevice device; - VkSurfaceKHR surface; - VkSwapchainKHR swapchain; - VkPhysicalDeviceProperties physicalDeviceProperties; - VkPhysicalDeviceFeatures physicalDeviceFeatures; - uint32_t graphicsQueueFamilyIndex; - uint32_t presentQueueFamilyIndex; - VkPhysicalDevice physicalDevice; - VkQueue graphicsQueue; - VkQueue presentQueue; - VkSemaphore imageAvailableSemaphore; - VkSemaphore renderingFinishedSemaphore; - VkSurfaceCapabilitiesKHR surfaceCapabilities; - VkSurfaceFormatKHR *surfaceFormats; - uint32_t surfaceFormatsAllocatedCount; - uint32_t surfaceFormatsCount; - uint32_t swapchainDesiredImageCount; - VkSurfaceFormatKHR surfaceFormat; - VkExtent2D swapchainSize; - VkCommandPool commandPool; - uint32_t swapchainImageCount; - VkImage *swapchainImages; - VkCommandBuffer *commandBuffers; - VkFence *fences; -} VulkanContext; - -static SDLTest_CommonState *state; -static VulkanContext vulkanContext = {0}; - -static void shutdownVulkan(void); - -/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ -static void quit(int rc) -{ - shutdownVulkan(); - SDLTest_CommonQuit(state); - exit(rc); -} - -static void loadGlobalFunctions(void) -{ - vkGetInstanceProcAddr = SDL_Vulkan_GetVkGetInstanceProcAddr(); - if(!vkGetInstanceProcAddr) - { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "SDL_Vulkan_GetVkGetInstanceProcAddr(): %s\n", - SDL_GetError()); - quit(2); - } - -#define VULKAN_DEVICE_FUNCTION(name) -#define VULKAN_GLOBAL_FUNCTION(name) \ - name = (PFN_##name)vkGetInstanceProcAddr(VK_NULL_HANDLE, #name); \ - if(!name) \ - { \ - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, \ - "vkGetInstanceProcAddr(VK_NULL_HANDLE, \"" #name "\") failed\n"); \ - quit(2); \ - } -#define VULKAN_INSTANCE_FUNCTION(name) - VULKAN_FUNCTIONS() -#undef VULKAN_DEVICE_FUNCTION -#undef VULKAN_GLOBAL_FUNCTION -#undef VULKAN_INSTANCE_FUNCTION -} - -static void createInstance(void) -{ - VkApplicationInfo appInfo = {0}; - VkInstanceCreateInfo instanceCreateInfo = {0}; - const char **extensions = NULL; - unsigned extensionCount = 0; - VkResult result; - - - appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO; - appInfo.apiVersion = VK_API_VERSION_1_0; - instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; - instanceCreateInfo.pApplicationInfo = &appInfo; - if(!SDL_Vulkan_GetInstanceExtensions(NULL, &extensionCount, NULL)) - { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "SDL_Vulkan_GetInstanceExtensions(): %s\n", - SDL_GetError()); - quit(2); - } - extensions = SDL_malloc(sizeof(const char *) * extensionCount); - if(!extensions) - { - SDL_OutOfMemory(); - quit(2); - } - if(!SDL_Vulkan_GetInstanceExtensions(NULL, &extensionCount, extensions)) - { - SDL_free((void*)extensions); - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "SDL_Vulkan_GetInstanceExtensions(): %s\n", - SDL_GetError()); - quit(2); - } - instanceCreateInfo.enabledExtensionCount = extensionCount; - instanceCreateInfo.ppEnabledExtensionNames = extensions; - result = vkCreateInstance(&instanceCreateInfo, NULL, &vulkanContext.instance); - SDL_free((void*)extensions); - if(result != VK_SUCCESS) - { - vulkanContext.instance = VK_NULL_HANDLE; - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "vkCreateInstance(): %s\n", - getVulkanResultString(result)); - quit(2); - } -} - -static void loadInstanceFunctions(void) -{ -#define VULKAN_DEVICE_FUNCTION(name) -#define VULKAN_GLOBAL_FUNCTION(name) -#define VULKAN_INSTANCE_FUNCTION(name) \ - name = (PFN_##name)vkGetInstanceProcAddr(vulkanContext.instance, #name); \ - if(!name) \ - { \ - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, \ - "vkGetInstanceProcAddr(instance, \"" #name "\") failed\n"); \ - quit(2); \ - } - VULKAN_FUNCTIONS() -#undef VULKAN_DEVICE_FUNCTION -#undef VULKAN_GLOBAL_FUNCTION -#undef VULKAN_INSTANCE_FUNCTION -} - -static void createSurface(void) -{ - if(!SDL_Vulkan_CreateSurface(state->windows[0], - vulkanContext.instance, - &vulkanContext.surface)) - { - vulkanContext.surface = VK_NULL_HANDLE; - SDL_LogError( - SDL_LOG_CATEGORY_APPLICATION, "SDL_Vulkan_CreateSurface(): %s\n", SDL_GetError()); - quit(2); - } -} - -static void findPhysicalDevice(void) -{ - uint32_t physicalDeviceCount = 0; - VkPhysicalDevice *physicalDevices; - VkQueueFamilyProperties *queueFamiliesProperties = NULL; - uint32_t queueFamiliesPropertiesAllocatedSize = 0; - VkExtensionProperties *deviceExtensions = NULL; - uint32_t deviceExtensionsAllocatedSize = 0; - uint32_t physicalDeviceIndex; - - VkResult result = - vkEnumeratePhysicalDevices(vulkanContext.instance, &physicalDeviceCount, NULL); - if(result != VK_SUCCESS) - { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "vkEnumeratePhysicalDevices(): %s\n", - getVulkanResultString(result)); - quit(2); - } - if(physicalDeviceCount == 0) - { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "vkEnumeratePhysicalDevices(): no physical devices\n"); - quit(2); - } - physicalDevices = SDL_malloc(sizeof(VkPhysicalDevice) * physicalDeviceCount); - if(!physicalDevices) - { - SDL_OutOfMemory(); - quit(2); - } - result = - vkEnumeratePhysicalDevices(vulkanContext.instance, &physicalDeviceCount, physicalDevices); - if(result != VK_SUCCESS) - { - SDL_free(physicalDevices); - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "vkEnumeratePhysicalDevices(): %s\n", - getVulkanResultString(result)); - quit(2); - } - vulkanContext.physicalDevice = NULL; - for(physicalDeviceIndex = 0; physicalDeviceIndex < physicalDeviceCount; - physicalDeviceIndex++) - { - uint32_t queueFamiliesCount = 0; - uint32_t queueFamilyIndex; - uint32_t deviceExtensionCount = 0; - SDL_bool hasSwapchainExtension = SDL_FALSE; - uint32_t i; - - - VkPhysicalDevice physicalDevice = physicalDevices[physicalDeviceIndex]; - vkGetPhysicalDeviceProperties(physicalDevice, &vulkanContext.physicalDeviceProperties); - if(VK_VERSION_MAJOR(vulkanContext.physicalDeviceProperties.apiVersion) < 1) - continue; - vkGetPhysicalDeviceFeatures(physicalDevice, &vulkanContext.physicalDeviceFeatures); - vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamiliesCount, NULL); - if(queueFamiliesCount == 0) - continue; - if(queueFamiliesPropertiesAllocatedSize < queueFamiliesCount) - { - SDL_free(queueFamiliesProperties); - queueFamiliesPropertiesAllocatedSize = queueFamiliesCount; - queueFamiliesProperties = - SDL_malloc(sizeof(VkQueueFamilyProperties) * queueFamiliesPropertiesAllocatedSize); - if(!queueFamiliesProperties) - { - SDL_free(physicalDevices); - SDL_free(deviceExtensions); - SDL_OutOfMemory(); - quit(2); - } - } - vkGetPhysicalDeviceQueueFamilyProperties( - physicalDevice, &queueFamiliesCount, queueFamiliesProperties); - vulkanContext.graphicsQueueFamilyIndex = queueFamiliesCount; - vulkanContext.presentQueueFamilyIndex = queueFamiliesCount; - for(queueFamilyIndex = 0; queueFamilyIndex < queueFamiliesCount; - queueFamilyIndex++) - { - VkBool32 supported = 0; - - if(queueFamiliesProperties[queueFamilyIndex].queueCount == 0) - continue; - if(queueFamiliesProperties[queueFamilyIndex].queueFlags & VK_QUEUE_GRAPHICS_BIT) - vulkanContext.graphicsQueueFamilyIndex = queueFamilyIndex; - result = vkGetPhysicalDeviceSurfaceSupportKHR( - physicalDevice, queueFamilyIndex, vulkanContext.surface, &supported); - if(result != VK_SUCCESS) - { - SDL_free(physicalDevices); - SDL_free(queueFamiliesProperties); - SDL_free(deviceExtensions); - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "vkGetPhysicalDeviceSurfaceSupportKHR(): %s\n", - getVulkanResultString(result)); - quit(2); - } - if(supported) - { - vulkanContext.presentQueueFamilyIndex = queueFamilyIndex; - if(queueFamiliesProperties[queueFamilyIndex].queueFlags & VK_QUEUE_GRAPHICS_BIT) - break; // use this queue because it can present and do graphics - } - } - if(vulkanContext.graphicsQueueFamilyIndex == queueFamiliesCount) // no good queues found - continue; - if(vulkanContext.presentQueueFamilyIndex == queueFamiliesCount) // no good queues found - continue; - result = - vkEnumerateDeviceExtensionProperties(physicalDevice, NULL, &deviceExtensionCount, NULL); - if(result != VK_SUCCESS) - { - SDL_free(physicalDevices); - SDL_free(queueFamiliesProperties); - SDL_free(deviceExtensions); - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "vkEnumerateDeviceExtensionProperties(): %s\n", - getVulkanResultString(result)); - quit(2); - } - if(deviceExtensionCount == 0) - continue; - if(deviceExtensionsAllocatedSize < deviceExtensionCount) - { - SDL_free(deviceExtensions); - deviceExtensionsAllocatedSize = deviceExtensionCount; - deviceExtensions = - SDL_malloc(sizeof(VkExtensionProperties) * deviceExtensionsAllocatedSize); - if(!deviceExtensions) - { - SDL_free(physicalDevices); - SDL_free(queueFamiliesProperties); - SDL_OutOfMemory(); - quit(2); - } - } - result = vkEnumerateDeviceExtensionProperties( - physicalDevice, NULL, &deviceExtensionCount, deviceExtensions); - if(result != VK_SUCCESS) - { - SDL_free(physicalDevices); - SDL_free(queueFamiliesProperties); - SDL_free(deviceExtensions); - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "vkEnumerateDeviceExtensionProperties(): %s\n", - getVulkanResultString(result)); - quit(2); - } - for(i = 0; i < deviceExtensionCount; i++) - { - if(0 == SDL_strcmp(deviceExtensions[i].extensionName, VK_KHR_SWAPCHAIN_EXTENSION_NAME)) - { - hasSwapchainExtension = SDL_TRUE; - break; - } - } - if(!hasSwapchainExtension) - continue; - vulkanContext.physicalDevice = physicalDevice; - break; - } - SDL_free(physicalDevices); - SDL_free(queueFamiliesProperties); - SDL_free(deviceExtensions); - if(!vulkanContext.physicalDevice) - { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Vulkan: no viable physical devices found"); - quit(2); - } -} - -static void createDevice(void) -{ - VkDeviceQueueCreateInfo deviceQueueCreateInfo[1] = {0}; - static const float queuePriority[] = {1.0f}; - VkDeviceCreateInfo deviceCreateInfo = {0}; - static const char *const deviceExtensionNames[] = { - VK_KHR_SWAPCHAIN_EXTENSION_NAME, - }; - VkResult result; - - deviceQueueCreateInfo->sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; - deviceQueueCreateInfo->queueFamilyIndex = vulkanContext.graphicsQueueFamilyIndex; - deviceQueueCreateInfo->queueCount = 1; - deviceQueueCreateInfo->pQueuePriorities = &queuePriority[0]; - - deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; - deviceCreateInfo.queueCreateInfoCount = 1; - deviceCreateInfo.pQueueCreateInfos = deviceQueueCreateInfo; - deviceCreateInfo.pEnabledFeatures = NULL; - deviceCreateInfo.enabledExtensionCount = SDL_arraysize(deviceExtensionNames); - deviceCreateInfo.ppEnabledExtensionNames = deviceExtensionNames; - result = vkCreateDevice( - vulkanContext.physicalDevice, &deviceCreateInfo, NULL, &vulkanContext.device); - if(result != VK_SUCCESS) - { - vulkanContext.device = VK_NULL_HANDLE; - SDL_LogError( - SDL_LOG_CATEGORY_APPLICATION, "vkCreateDevice(): %s\n", getVulkanResultString(result)); - quit(2); - } -} - -static void loadDeviceFunctions(void) -{ -#define VULKAN_DEVICE_FUNCTION(name) \ - name = (PFN_##name)vkGetDeviceProcAddr(vulkanContext.device, #name); \ - if(!name) \ - { \ - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, \ - "vkGetDeviceProcAddr(device, \"" #name "\") failed\n"); \ - quit(2); \ - } -#define VULKAN_GLOBAL_FUNCTION(name) -#define VULKAN_INSTANCE_FUNCTION(name) - VULKAN_FUNCTIONS() -#undef VULKAN_DEVICE_FUNCTION -#undef VULKAN_GLOBAL_FUNCTION -#undef VULKAN_INSTANCE_FUNCTION -} - -#undef VULKAN_FUNCTIONS - -static void getQueues(void) -{ - vkGetDeviceQueue(vulkanContext.device, - vulkanContext.graphicsQueueFamilyIndex, - 0, - &vulkanContext.graphicsQueue); - if(vulkanContext.graphicsQueueFamilyIndex != vulkanContext.presentQueueFamilyIndex) - vkGetDeviceQueue(vulkanContext.device, - vulkanContext.presentQueueFamilyIndex, - 0, - &vulkanContext.presentQueue); - else - vulkanContext.presentQueue = vulkanContext.graphicsQueue; -} - -static void createSemaphore(VkSemaphore *semaphore) -{ - VkResult result; - - VkSemaphoreCreateInfo createInfo = {0}; - createInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; - result = vkCreateSemaphore(vulkanContext.device, &createInfo, NULL, semaphore); - if(result != VK_SUCCESS) - { - *semaphore = VK_NULL_HANDLE; - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "vkCreateSemaphore(): %s\n", - getVulkanResultString(result)); - quit(2); - } -} - -static void createSemaphores(void) -{ - createSemaphore(&vulkanContext.imageAvailableSemaphore); - createSemaphore(&vulkanContext.renderingFinishedSemaphore); -} - -static void getSurfaceCaps(void) -{ - VkResult result = vkGetPhysicalDeviceSurfaceCapabilitiesKHR( - vulkanContext.physicalDevice, vulkanContext.surface, &vulkanContext.surfaceCapabilities); - if(result != VK_SUCCESS) - { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "vkGetPhysicalDeviceSurfaceCapabilitiesKHR(): %s\n", - getVulkanResultString(result)); - quit(2); - } - - // check surface usage - if(!(vulkanContext.surfaceCapabilities.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT)) - { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "Vulkan surface doesn't support VK_IMAGE_USAGE_TRANSFER_DST_BIT\n"); - quit(2); - } -} - -static void getSurfaceFormats(void) -{ - VkResult result = vkGetPhysicalDeviceSurfaceFormatsKHR(vulkanContext.physicalDevice, - vulkanContext.surface, - &vulkanContext.surfaceFormatsCount, - NULL); - if(result != VK_SUCCESS) - { - vulkanContext.surfaceFormatsCount = 0; - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "vkGetPhysicalDeviceSurfaceFormatsKHR(): %s\n", - getVulkanResultString(result)); - quit(2); - } - if(vulkanContext.surfaceFormatsCount > vulkanContext.surfaceFormatsAllocatedCount) - { - vulkanContext.surfaceFormatsAllocatedCount = vulkanContext.surfaceFormatsCount; - SDL_free(vulkanContext.surfaceFormats); - vulkanContext.surfaceFormats = - SDL_malloc(sizeof(VkSurfaceFormatKHR) * vulkanContext.surfaceFormatsAllocatedCount); - if(!vulkanContext.surfaceFormats) - { - vulkanContext.surfaceFormatsCount = 0; - SDL_OutOfMemory(); - quit(2); - } - } - result = vkGetPhysicalDeviceSurfaceFormatsKHR(vulkanContext.physicalDevice, - vulkanContext.surface, - &vulkanContext.surfaceFormatsCount, - vulkanContext.surfaceFormats); - if(result != VK_SUCCESS) - { - vulkanContext.surfaceFormatsCount = 0; - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "vkGetPhysicalDeviceSurfaceFormatsKHR(): %s\n", - getVulkanResultString(result)); - quit(2); - } -} - -static void getSwapchainImages(void) -{ - VkResult result; - - SDL_free(vulkanContext.swapchainImages); - vulkanContext.swapchainImages = NULL; - result = vkGetSwapchainImagesKHR( - vulkanContext.device, vulkanContext.swapchain, &vulkanContext.swapchainImageCount, NULL); - if(result != VK_SUCCESS) - { - vulkanContext.swapchainImageCount = 0; - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "vkGetSwapchainImagesKHR(): %s\n", - getVulkanResultString(result)); - quit(2); - } - vulkanContext.swapchainImages = SDL_malloc(sizeof(VkImage) * vulkanContext.swapchainImageCount); - if(!vulkanContext.swapchainImages) - { - SDL_OutOfMemory(); - quit(2); - } - result = vkGetSwapchainImagesKHR(vulkanContext.device, - vulkanContext.swapchain, - &vulkanContext.swapchainImageCount, - vulkanContext.swapchainImages); - if(result != VK_SUCCESS) - { - SDL_free(vulkanContext.swapchainImages); - vulkanContext.swapchainImages = NULL; - vulkanContext.swapchainImageCount = 0; - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "vkGetSwapchainImagesKHR(): %s\n", - getVulkanResultString(result)); - quit(2); - } -} - -static SDL_bool createSwapchain(void) -{ - uint32_t i; - int w, h; - VkSwapchainCreateInfoKHR createInfo = {0}; - VkResult result; - - // pick an image count - vulkanContext.swapchainDesiredImageCount = vulkanContext.surfaceCapabilities.minImageCount + 1; - if(vulkanContext.swapchainDesiredImageCount > vulkanContext.surfaceCapabilities.maxImageCount - && vulkanContext.surfaceCapabilities.maxImageCount > 0) - vulkanContext.swapchainDesiredImageCount = vulkanContext.surfaceCapabilities.maxImageCount; - - // pick a format - if(vulkanContext.surfaceFormatsCount == 1 - && vulkanContext.surfaceFormats[0].format == VK_FORMAT_UNDEFINED) - { - // aren't any preferred formats, so we pick - vulkanContext.surfaceFormat.colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; - vulkanContext.surfaceFormat.format = VK_FORMAT_R8G8B8A8_UNORM; - } - else - { - vulkanContext.surfaceFormat = vulkanContext.surfaceFormats[0]; - for(i = 0; i < vulkanContext.surfaceFormatsCount; i++) - { - if(vulkanContext.surfaceFormats[i].format == VK_FORMAT_R8G8B8A8_UNORM) - { - vulkanContext.surfaceFormat = vulkanContext.surfaceFormats[i]; - break; - } - } - } - - // get size - SDL_Vulkan_GetDrawableSize(state->windows[0], &w, &h); - vulkanContext.swapchainSize.width = w; - vulkanContext.swapchainSize.height = h; - if(w == 0 || h == 0) - return SDL_FALSE; - - createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; - createInfo.surface = vulkanContext.surface; - createInfo.minImageCount = vulkanContext.swapchainDesiredImageCount; - createInfo.imageFormat = vulkanContext.surfaceFormat.format; - createInfo.imageColorSpace = vulkanContext.surfaceFormat.colorSpace; - createInfo.imageExtent = vulkanContext.swapchainSize; - createInfo.imageArrayLayers = 1; - createInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; - createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; - createInfo.preTransform = vulkanContext.surfaceCapabilities.currentTransform; - createInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; - createInfo.presentMode = VK_PRESENT_MODE_FIFO_KHR; - createInfo.clipped = VK_TRUE; - createInfo.oldSwapchain = vulkanContext.swapchain; - result = - vkCreateSwapchainKHR(vulkanContext.device, &createInfo, NULL, &vulkanContext.swapchain); - if(createInfo.oldSwapchain) - vkDestroySwapchainKHR(vulkanContext.device, createInfo.oldSwapchain, NULL); - if(result != VK_SUCCESS) - { - vulkanContext.swapchain = VK_NULL_HANDLE; - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "vkCreateSwapchainKHR(): %s\n", - getVulkanResultString(result)); - quit(2); - } - getSwapchainImages(); - return SDL_TRUE; -} - -static void destroySwapchain(void) -{ - if(vulkanContext.swapchain) - vkDestroySwapchainKHR(vulkanContext.device, vulkanContext.swapchain, NULL); - vulkanContext.swapchain = VK_NULL_HANDLE; - SDL_free(vulkanContext.swapchainImages); - vulkanContext.swapchainImages = NULL; -} - -static void destroyCommandBuffers(void) -{ - if(vulkanContext.commandBuffers) - vkFreeCommandBuffers(vulkanContext.device, - vulkanContext.commandPool, - vulkanContext.swapchainImageCount, - vulkanContext.commandBuffers); - SDL_free(vulkanContext.commandBuffers); - vulkanContext.commandBuffers = NULL; -} - -static void destroyCommandPool(void) -{ - if(vulkanContext.commandPool) - vkDestroyCommandPool(vulkanContext.device, vulkanContext.commandPool, NULL); - vulkanContext.commandPool = VK_NULL_HANDLE; -} - -static void createCommandPool(void) -{ - VkResult result; - - VkCommandPoolCreateInfo createInfo = {0}; - createInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; - createInfo.flags = - VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT | VK_COMMAND_POOL_CREATE_TRANSIENT_BIT; - createInfo.queueFamilyIndex = vulkanContext.graphicsQueueFamilyIndex; - result = - vkCreateCommandPool(vulkanContext.device, &createInfo, NULL, &vulkanContext.commandPool); - if(result != VK_SUCCESS) - { - vulkanContext.commandPool = VK_NULL_HANDLE; - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "vkCreateCommandPool(): %s\n", - getVulkanResultString(result)); - quit(2); - } -} - -static void createCommandBuffers(void) -{ - VkResult result; - - VkCommandBufferAllocateInfo allocateInfo = {0}; - allocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; - allocateInfo.commandPool = vulkanContext.commandPool; - allocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; - allocateInfo.commandBufferCount = vulkanContext.swapchainImageCount; - vulkanContext.commandBuffers = - SDL_malloc(sizeof(VkCommandBuffer) * vulkanContext.swapchainImageCount); - result = - vkAllocateCommandBuffers(vulkanContext.device, &allocateInfo, vulkanContext.commandBuffers); - if(result != VK_SUCCESS) - { - SDL_free(vulkanContext.commandBuffers); - vulkanContext.commandBuffers = NULL; - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "vkAllocateCommandBuffers(): %s\n", - getVulkanResultString(result)); - quit(2); - } -} - -static void createFences(void) -{ - uint32_t i; - - vulkanContext.fences = SDL_malloc(sizeof(VkFence) * vulkanContext.swapchainImageCount); - if(!vulkanContext.fences) - { - SDL_OutOfMemory(); - quit(2); - } - for(i = 0; i < vulkanContext.swapchainImageCount; i++) - { - VkResult result; - - VkFenceCreateInfo createInfo = {0}; - createInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; - createInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT; - result = - vkCreateFence(vulkanContext.device, &createInfo, NULL, &vulkanContext.fences[i]); - if(result != VK_SUCCESS) - { - for(; i > 0; i--) - { - vkDestroyFence(vulkanContext.device, vulkanContext.fences[i - 1], NULL); - } - SDL_free(vulkanContext.fences); - vulkanContext.fences = NULL; - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "vkCreateFence(): %s\n", - getVulkanResultString(result)); - quit(2); - } - } -} - -static void destroyFences(void) -{ - uint32_t i; - - if(!vulkanContext.fences) - return; - for(i = 0; i < vulkanContext.swapchainImageCount; i++) - { - vkDestroyFence(vulkanContext.device, vulkanContext.fences[i], NULL); - } - SDL_free(vulkanContext.fences); - vulkanContext.fences = NULL; -} - -static void recordPipelineImageBarrier(VkCommandBuffer commandBuffer, - VkAccessFlags sourceAccessMask, - VkAccessFlags destAccessMask, - VkImageLayout sourceLayout, - VkImageLayout destLayout, - VkImage image) -{ - VkImageMemoryBarrier barrier = {0}; - barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - barrier.srcAccessMask = sourceAccessMask; - barrier.dstAccessMask = destAccessMask; - barrier.oldLayout = sourceLayout; - barrier.newLayout = destLayout; - barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; - barrier.image = image; - barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - barrier.subresourceRange.baseMipLevel = 0; - barrier.subresourceRange.levelCount = 1; - barrier.subresourceRange.baseArrayLayer = 0; - barrier.subresourceRange.layerCount = 1; - vkCmdPipelineBarrier(commandBuffer, - VK_PIPELINE_STAGE_TRANSFER_BIT, - VK_PIPELINE_STAGE_TRANSFER_BIT, - 0, - 0, - NULL, - 0, - NULL, - 1, - &barrier); -} - -static void rerecordCommandBuffer(uint32_t frameIndex, const VkClearColorValue *clearColor) -{ - VkCommandBuffer commandBuffer = vulkanContext.commandBuffers[frameIndex]; - VkImage image = vulkanContext.swapchainImages[frameIndex]; - VkCommandBufferBeginInfo beginInfo = {0}; - VkImageSubresourceRange clearRange = {0}; - - VkResult result = vkResetCommandBuffer(commandBuffer, 0); - if(result != VK_SUCCESS) - { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "vkResetCommandBuffer(): %s\n", - getVulkanResultString(result)); - quit(2); - } - beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - beginInfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT; - result = vkBeginCommandBuffer(commandBuffer, &beginInfo); - if(result != VK_SUCCESS) - { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "vkBeginCommandBuffer(): %s\n", - getVulkanResultString(result)); - quit(2); - } - recordPipelineImageBarrier(commandBuffer, - 0, - VK_ACCESS_TRANSFER_WRITE_BIT, - VK_IMAGE_LAYOUT_UNDEFINED, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - image); - clearRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - clearRange.baseMipLevel = 0; - clearRange.levelCount = 1; - clearRange.baseArrayLayer = 0; - clearRange.layerCount = 1; - vkCmdClearColorImage( - commandBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, clearColor, 1, &clearRange); - recordPipelineImageBarrier(commandBuffer, - VK_ACCESS_TRANSFER_WRITE_BIT, - VK_ACCESS_MEMORY_READ_BIT, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, - image); - result = vkEndCommandBuffer(commandBuffer); - if(result != VK_SUCCESS) - { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "vkEndCommandBuffer(): %s\n", - getVulkanResultString(result)); - quit(2); - } -} - -static void destroySwapchainAndSwapchainSpecificStuff(SDL_bool doDestroySwapchain) -{ - destroyFences(); - destroyCommandBuffers(); - destroyCommandPool(); - if(doDestroySwapchain) - destroySwapchain(); -} - -static SDL_bool createNewSwapchainAndSwapchainSpecificStuff(void) -{ - destroySwapchainAndSwapchainSpecificStuff(SDL_FALSE); - getSurfaceCaps(); - getSurfaceFormats(); - if(!createSwapchain()) - return SDL_FALSE; - createCommandPool(); - createCommandBuffers(); - createFences(); - return SDL_TRUE; -} - -static void initVulkan(void) -{ - SDL_Vulkan_LoadLibrary(NULL); - SDL_memset(&vulkanContext, 0, sizeof(VulkanContext)); - loadGlobalFunctions(); - createInstance(); - loadInstanceFunctions(); - createSurface(); - findPhysicalDevice(); - createDevice(); - loadDeviceFunctions(); - getQueues(); - createSemaphores(); - createNewSwapchainAndSwapchainSpecificStuff(); -} - -static void shutdownVulkan(void) -{ - if(vulkanContext.device && vkDeviceWaitIdle) - vkDeviceWaitIdle(vulkanContext.device); - destroySwapchainAndSwapchainSpecificStuff(SDL_TRUE); - if(vulkanContext.imageAvailableSemaphore && vkDestroySemaphore) - vkDestroySemaphore(vulkanContext.device, vulkanContext.imageAvailableSemaphore, NULL); - if(vulkanContext.renderingFinishedSemaphore && vkDestroySemaphore) - vkDestroySemaphore(vulkanContext.device, vulkanContext.renderingFinishedSemaphore, NULL); - if(vulkanContext.device && vkDestroyDevice) - vkDestroyDevice(vulkanContext.device, NULL); - if(vulkanContext.surface && vkDestroySurfaceKHR) - vkDestroySurfaceKHR(vulkanContext.instance, vulkanContext.surface, NULL); - if(vulkanContext.instance && vkDestroyInstance) - vkDestroyInstance(vulkanContext.instance, NULL); - SDL_free(vulkanContext.surfaceFormats); - SDL_Vulkan_UnloadLibrary(); -} - -static SDL_bool render(void) -{ - uint32_t frameIndex; - VkResult result; - double currentTime; - VkClearColorValue clearColor = {0}; - VkPipelineStageFlags waitDestStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT; - VkSubmitInfo submitInfo = {0}; - VkPresentInfoKHR presentInfo = {0}; - int w, h; - - if(!vulkanContext.swapchain) - { - SDL_bool retval = createNewSwapchainAndSwapchainSpecificStuff(); - if(!retval) - SDL_Delay(100); - return retval; - } - result = vkAcquireNextImageKHR(vulkanContext.device, - vulkanContext.swapchain, - UINT64_MAX, - vulkanContext.imageAvailableSemaphore, - VK_NULL_HANDLE, - &frameIndex); - if(result == VK_ERROR_OUT_OF_DATE_KHR) - return createNewSwapchainAndSwapchainSpecificStuff(); - if(result != VK_SUBOPTIMAL_KHR && result != VK_SUCCESS) - { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "vkAcquireNextImageKHR(): %s\n", - getVulkanResultString(result)); - quit(2); - } - result = vkWaitForFences( - vulkanContext.device, 1, &vulkanContext.fences[frameIndex], VK_FALSE, UINT64_MAX); - if(result != VK_SUCCESS) - { - SDL_LogError( - SDL_LOG_CATEGORY_APPLICATION, "vkWaitForFences(): %s\n", getVulkanResultString(result)); - quit(2); - } - result = vkResetFences(vulkanContext.device, 1, &vulkanContext.fences[frameIndex]); - if(result != VK_SUCCESS) - { - SDL_LogError( - SDL_LOG_CATEGORY_APPLICATION, "vkResetFences(): %s\n", getVulkanResultString(result)); - quit(2); - } - currentTime = (double)SDL_GetPerformanceCounter() / SDL_GetPerformanceFrequency(); - clearColor.float32[0] = (float)(0.5 + 0.5 * SDL_sin(currentTime)); - clearColor.float32[1] = (float)(0.5 + 0.5 * SDL_sin(currentTime + M_PI * 2 / 3)); - clearColor.float32[2] = (float)(0.5 + 0.5 * SDL_sin(currentTime + M_PI * 4 / 3)); - clearColor.float32[3] = 1; - rerecordCommandBuffer(frameIndex, &clearColor); - submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - submitInfo.waitSemaphoreCount = 1; - submitInfo.pWaitSemaphores = &vulkanContext.imageAvailableSemaphore; - submitInfo.pWaitDstStageMask = &waitDestStageMask; - submitInfo.commandBufferCount = 1; - submitInfo.pCommandBuffers = &vulkanContext.commandBuffers[frameIndex]; - submitInfo.signalSemaphoreCount = 1; - submitInfo.pSignalSemaphores = &vulkanContext.renderingFinishedSemaphore; - result = vkQueueSubmit( - vulkanContext.graphicsQueue, 1, &submitInfo, vulkanContext.fences[frameIndex]); - if(result != VK_SUCCESS) - { - SDL_LogError( - SDL_LOG_CATEGORY_APPLICATION, "vkQueueSubmit(): %s\n", getVulkanResultString(result)); - quit(2); - } - presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; - presentInfo.waitSemaphoreCount = 1; - presentInfo.pWaitSemaphores = &vulkanContext.renderingFinishedSemaphore; - presentInfo.swapchainCount = 1; - presentInfo.pSwapchains = &vulkanContext.swapchain; - presentInfo.pImageIndices = &frameIndex; - result = vkQueuePresentKHR(vulkanContext.presentQueue, &presentInfo); - if(result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR) - { - return createNewSwapchainAndSwapchainSpecificStuff(); - } - if(result != VK_SUCCESS) - { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, - "vkQueuePresentKHR(): %s\n", - getVulkanResultString(result)); - quit(2); - } - SDL_Vulkan_GetDrawableSize(state->windows[0], &w, &h); - if(w != (int)vulkanContext.swapchainSize.width || h != (int)vulkanContext.swapchainSize.height) - { - return createNewSwapchainAndSwapchainSpecificStuff(); - } - return SDL_TRUE; -} - -int main(int argc, char *argv[]) -{ - int fsaa, accel; - int done; - SDL_DisplayMode mode; - SDL_Event event; - Uint32 then, now, frames; - int dw, dh; - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - /* Initialize parameters */ - fsaa = 0; - accel = -1; - - /* Initialize test framework */ - state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO); - if(!state) - { - return 1; - } - - /* Set Vulkan parameters */ - state->window_flags |= SDL_WINDOW_VULKAN; - state->num_windows = 1; - state->skip_renderer = 1; - - if (!SDLTest_CommonDefaultArgs(state, argc, argv) || !SDLTest_CommonInit(state)) { - SDLTest_CommonQuit(state); - return 1; - } - - SDL_GetCurrentDisplayMode(0, &mode); - SDL_Log("Screen BPP : %d\n", SDL_BITSPERPIXEL(mode.format)); - SDL_GetWindowSize(state->windows[0], &dw, &dh); - SDL_Log("Window Size : %d,%d\n", dw, dh); - SDL_Vulkan_GetDrawableSize(state->windows[0], &dw, &dh); - SDL_Log("Draw Size : %d,%d\n", dw, dh); - SDL_Log("\n"); - - initVulkan(); - - /* Main render loop */ - frames = 0; - then = SDL_GetTicks(); - done = 0; - while(!done) - { - /* Check for events */ - ++frames; - while(SDL_PollEvent(&event)) - { - SDLTest_CommonEvent(state, &event, &done); - } - - if(!done) - render(); - } - - /* Print out some timing information */ - now = SDL_GetTicks(); - if(now > then) - { - SDL_Log("%2.2f frames per second\n", ((double)frames * 1000) / (now - then)); - } - quit(0); - return 0; -} - -#endif diff --git a/SDL2-2.0.12/test/testwm2.c b/SDL2-2.0.12/test/testwm2.c deleted file mode 100644 index 2d3779b..0000000 --- a/SDL2-2.0.12/test/testwm2.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ - -#include -#include - -#ifdef __EMSCRIPTEN__ -#include -#endif - -#include "SDL_test_common.h" - -static SDLTest_CommonState *state; -int done; - -static const char *cursorNames[] = { - "arrow", - "ibeam", - "wait", - "crosshair", - "waitarrow", - "sizeNWSE", - "sizeNESW", - "sizeWE", - "sizeNS", - "sizeALL", - "NO", - "hand", -}; -int system_cursor = -1; -SDL_Cursor *cursor = NULL; - -/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ -static void -quit(int rc) -{ - SDLTest_CommonQuit(state); - exit(rc); -} - -void -loop() -{ - int i; - SDL_Event event; - /* Check for events */ - while (SDL_PollEvent(&event)) { - SDLTest_CommonEvent(state, &event, &done); - - if (event.type == SDL_WINDOWEVENT) { - if (event.window.event == SDL_WINDOWEVENT_RESIZED) { - SDL_Window *window = SDL_GetWindowFromID(event.window.windowID); - if (window) { - SDL_Log("Window %d resized to %dx%d\n", - event.window.windowID, - event.window.data1, - event.window.data2); - } - } - if (event.window.event == SDL_WINDOWEVENT_MOVED) { - SDL_Window *window = SDL_GetWindowFromID(event.window.windowID); - if (window) { - SDL_Log("Window %d moved to %d,%d (display %s)\n", - event.window.windowID, - event.window.data1, - event.window.data2, - SDL_GetDisplayName(SDL_GetWindowDisplayIndex(window))); - } - } - } - if (event.type == SDL_KEYUP) { - SDL_bool updateCursor = SDL_FALSE; - - if (event.key.keysym.sym == SDLK_LEFT) { - --system_cursor; - if (system_cursor < 0) { - system_cursor = SDL_NUM_SYSTEM_CURSORS - 1; - } - updateCursor = SDL_TRUE; - } else if (event.key.keysym.sym == SDLK_RIGHT) { - ++system_cursor; - if (system_cursor >= SDL_NUM_SYSTEM_CURSORS) { - system_cursor = 0; - } - updateCursor = SDL_TRUE; - } - if (updateCursor) { - SDL_Log("Changing cursor to \"%s\"", cursorNames[system_cursor]); - SDL_FreeCursor(cursor); - cursor = SDL_CreateSystemCursor((SDL_SystemCursor)system_cursor); - SDL_SetCursor(cursor); - } - } - } - - for (i = 0; i < state->num_windows; ++i) { - SDL_Renderer *renderer = state->renderers[i]; - SDL_RenderClear(renderer); - SDL_RenderPresent(renderer); - } -#ifdef __EMSCRIPTEN__ - if (done) { - emscripten_cancel_main_loop(); - } -#endif -} - -int -main(int argc, char *argv[]) -{ - int i; - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - SDL_assert(SDL_arraysize(cursorNames) == SDL_NUM_SYSTEM_CURSORS); - - /* Initialize test framework */ - state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO); - if (!state) { - return 1; - } - - if (!SDLTest_CommonDefaultArgs(state, argc, argv) || !SDLTest_CommonInit(state)) { - SDLTest_CommonQuit(state); - return 1; - } - - SDL_EventState(SDL_DROPFILE, SDL_ENABLE); - SDL_EventState(SDL_DROPTEXT, SDL_ENABLE); - - for (i = 0; i < state->num_windows; ++i) { - SDL_Renderer *renderer = state->renderers[i]; - SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF); - SDL_RenderClear(renderer); - } - - /* Main render loop */ - done = 0; -#ifdef __EMSCRIPTEN__ - emscripten_set_main_loop(loop, 0, 1); -#else - while (!done) { - loop(); - } -#endif - SDL_FreeCursor(cursor); - - quit(0); - /* keep the compiler happy ... */ - return(0); -} - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/test/testyuv.bmp b/SDL2-2.0.12/test/testyuv.bmp deleted file mode 100644 index af32034b6b5b858be470f9ef3bb023bc199bf96e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 739398 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ŽAD149Wj?1|X01)I4BQdAPsJ(8D&;wq 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

{o>^o9lF%RQ; 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 z�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 diff --git a/SDL2-2.0.12/test/testyuv.c b/SDL2-2.0.12/test/testyuv.c deleted file mode 100644 index 0c12b8e..0000000 --- a/SDL2-2.0.12/test/testyuv.c +++ /dev/null @@ -1,455 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ -#include -#include -#include - -#include "SDL.h" -#include "SDL_test_font.h" -#include "testyuv_cvt.h" - - -/* 422 (YUY2, etc) formats are the largest */ -#define MAX_YUV_SURFACE_SIZE(W, H, P) (H*4*(W+P+1)/2) - - -/* Return true if the YUV format is packed pixels */ -static SDL_bool is_packed_yuv_format(Uint32 format) -{ - return (format == SDL_PIXELFORMAT_YUY2 || - format == SDL_PIXELFORMAT_UYVY || - format == SDL_PIXELFORMAT_YVYU); -} - -/* Create a surface with a good pattern for verifying YUV conversion */ -static SDL_Surface *generate_test_pattern(int pattern_size) -{ - SDL_Surface *pattern = SDL_CreateRGBSurfaceWithFormat(0, pattern_size, pattern_size, 0, SDL_PIXELFORMAT_RGB24); - - if (pattern) { - int i, x, y; - Uint8 *p, c; - const int thickness = 2; /* Important so 2x2 blocks of color are the same, to avoid Cr/Cb interpolation over pixels */ - - /* R, G, B in alternating horizontal bands */ - for (y = 0; y < pattern->h; y += thickness) { - for (i = 0; i < thickness; ++i) { - p = (Uint8 *)pattern->pixels + (y + i) * pattern->pitch + ((y/thickness) % 3); - for (x = 0; x < pattern->w; ++x) { - *p = 0xFF; - p += 3; - } - } - } - - /* Black and white in alternating vertical bands */ - c = 0xFF; - for (x = 1*thickness; x < pattern->w; x += 2*thickness) { - for (i = 0; i < thickness; ++i) { - p = (Uint8 *)pattern->pixels + (x + i)*3; - for (y = 0; y < pattern->h; ++y) { - SDL_memset(p, c, 3); - p += pattern->pitch; - } - } - if (c) { - c = 0x00; - } else { - c = 0xFF; - } - } - } - return pattern; -} - -static SDL_bool verify_yuv_data(Uint32 format, const Uint8 *yuv, int yuv_pitch, SDL_Surface *surface) -{ - const int tolerance = 20; - const int size = (surface->h * surface->pitch); - Uint8 *rgb; - SDL_bool result = SDL_FALSE; - - rgb = (Uint8 *)SDL_malloc(size); - if (!rgb) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Out of memory"); - return SDL_FALSE; - } - - if (SDL_ConvertPixels(surface->w, surface->h, format, yuv, yuv_pitch, surface->format->format, rgb, surface->pitch) == 0) { - int x, y; - result = SDL_TRUE; - for (y = 0; y < surface->h; ++y) { - const Uint8 *actual = rgb + y * surface->pitch; - const Uint8 *expected = (const Uint8 *)surface->pixels + y * surface->pitch; - for (x = 0; x < surface->w; ++x) { - int deltaR = (int)actual[0] - expected[0]; - int deltaG = (int)actual[1] - expected[1]; - int deltaB = (int)actual[2] - expected[2]; - int distance = (deltaR * deltaR + deltaG * deltaG + deltaB * deltaB); - if (distance > tolerance) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Pixel at %d,%d was 0x%.2x,0x%.2x,0x%.2x, expected 0x%.2x,0x%.2x,0x%.2x, distance = %d\n", x, y, actual[0], actual[1], actual[2], expected[0], expected[1], expected[2], distance); - result = SDL_FALSE; - } - actual += 3; - expected += 3; - } - } - } else { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't convert %s to %s: %s\n", SDL_GetPixelFormatName(format), SDL_GetPixelFormatName(surface->format->format), SDL_GetError()); - } - SDL_free(rgb); - - return result; -} - -static int run_automated_tests(int pattern_size, int extra_pitch) -{ - const Uint32 formats[] = { - SDL_PIXELFORMAT_YV12, - SDL_PIXELFORMAT_IYUV, - SDL_PIXELFORMAT_NV12, - SDL_PIXELFORMAT_NV21, - SDL_PIXELFORMAT_YUY2, - SDL_PIXELFORMAT_UYVY, - SDL_PIXELFORMAT_YVYU - }; - int i, j; - SDL_Surface *pattern = generate_test_pattern(pattern_size); - const int yuv_len = MAX_YUV_SURFACE_SIZE(pattern->w, pattern->h, extra_pitch); - Uint8 *yuv1 = (Uint8 *)SDL_malloc(yuv_len); - Uint8 *yuv2 = (Uint8 *)SDL_malloc(yuv_len); - int yuv1_pitch, yuv2_pitch; - int result = -1; - - if (!pattern || !yuv1 || !yuv2) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't allocate test surfaces"); - goto done; - } - - /* Verify conversion from YUV formats */ - for (i = 0; i < SDL_arraysize(formats); ++i) { - if (!ConvertRGBtoYUV(formats[i], pattern->pixels, pattern->pitch, yuv1, pattern->w, pattern->h, SDL_GetYUVConversionModeForResolution(pattern->w, pattern->h), 0, 100)) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "ConvertRGBtoYUV() doesn't support converting to %s\n", SDL_GetPixelFormatName(formats[i])); - goto done; - } - yuv1_pitch = CalculateYUVPitch(formats[i], pattern->w); - if (!verify_yuv_data(formats[i], yuv1, yuv1_pitch, pattern)) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed conversion from %s to RGB\n", SDL_GetPixelFormatName(formats[i])); - goto done; - } - } - - /* Verify conversion to YUV formats */ - for (i = 0; i < SDL_arraysize(formats); ++i) { - yuv1_pitch = CalculateYUVPitch(formats[i], pattern->w) + extra_pitch; - if (SDL_ConvertPixels(pattern->w, pattern->h, pattern->format->format, pattern->pixels, pattern->pitch, formats[i], yuv1, yuv1_pitch) < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't convert %s to %s: %s\n", SDL_GetPixelFormatName(pattern->format->format), SDL_GetPixelFormatName(formats[i]), SDL_GetError()); - goto done; - } - if (!verify_yuv_data(formats[i], yuv1, yuv1_pitch, pattern)) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed conversion from RGB to %s\n", SDL_GetPixelFormatName(formats[i])); - goto done; - } - } - - /* Verify conversion between YUV formats */ - for (i = 0; i < SDL_arraysize(formats); ++i) { - for (j = 0; j < SDL_arraysize(formats); ++j) { - yuv1_pitch = CalculateYUVPitch(formats[i], pattern->w) + extra_pitch; - yuv2_pitch = CalculateYUVPitch(formats[j], pattern->w) + extra_pitch; - if (SDL_ConvertPixels(pattern->w, pattern->h, pattern->format->format, pattern->pixels, pattern->pitch, formats[i], yuv1, yuv1_pitch) < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't convert %s to %s: %s\n", SDL_GetPixelFormatName(pattern->format->format), SDL_GetPixelFormatName(formats[i]), SDL_GetError()); - goto done; - } - if (SDL_ConvertPixels(pattern->w, pattern->h, formats[i], yuv1, yuv1_pitch, formats[j], yuv2, yuv2_pitch) < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't convert %s to %s: %s\n", SDL_GetPixelFormatName(formats[i]), SDL_GetPixelFormatName(formats[j]), SDL_GetError()); - goto done; - } - if (!verify_yuv_data(formats[j], yuv2, yuv2_pitch, pattern)) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed conversion from %s to %s\n", SDL_GetPixelFormatName(formats[i]), SDL_GetPixelFormatName(formats[j])); - goto done; - } - } - } - - /* Verify conversion between YUV formats in-place */ - for (i = 0; i < SDL_arraysize(formats); ++i) { - for (j = 0; j < SDL_arraysize(formats); ++j) { - if (is_packed_yuv_format(formats[i]) != is_packed_yuv_format(formats[j])) { - /* Can't change plane vs packed pixel layout in-place */ - continue; - } - - yuv1_pitch = CalculateYUVPitch(formats[i], pattern->w) + extra_pitch; - yuv2_pitch = CalculateYUVPitch(formats[j], pattern->w) + extra_pitch; - if (SDL_ConvertPixels(pattern->w, pattern->h, pattern->format->format, pattern->pixels, pattern->pitch, formats[i], yuv1, yuv1_pitch) < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't convert %s to %s: %s\n", SDL_GetPixelFormatName(pattern->format->format), SDL_GetPixelFormatName(formats[i]), SDL_GetError()); - goto done; - } - if (SDL_ConvertPixels(pattern->w, pattern->h, formats[i], yuv1, yuv1_pitch, formats[j], yuv1, yuv2_pitch) < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't convert %s to %s: %s\n", SDL_GetPixelFormatName(formats[i]), SDL_GetPixelFormatName(formats[j]), SDL_GetError()); - goto done; - } - if (!verify_yuv_data(formats[j], yuv1, yuv2_pitch, pattern)) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed conversion from %s to %s\n", SDL_GetPixelFormatName(formats[i]), SDL_GetPixelFormatName(formats[j])); - goto done; - } - } - } - - - result = 0; - -done: - SDL_free(yuv1); - SDL_free(yuv2); - SDL_FreeSurface(pattern); - return result; -} - -int -main(int argc, char **argv) -{ - struct { - SDL_bool enable_intrinsics; - int pattern_size; - int extra_pitch; - } automated_test_params[] = { - /* Test: even width and height */ - { SDL_FALSE, 2, 0 }, - { SDL_FALSE, 4, 0 }, - /* Test: odd width and height */ - { SDL_FALSE, 1, 0 }, - { SDL_FALSE, 3, 0 }, - /* Test: even width and height, extra pitch */ - { SDL_FALSE, 2, 3 }, - { SDL_FALSE, 4, 3 }, - /* Test: odd width and height, extra pitch */ - { SDL_FALSE, 1, 3 }, - { SDL_FALSE, 3, 3 }, - /* Test: even width and height with intrinsics */ - { SDL_TRUE, 32, 0 }, - /* Test: odd width and height with intrinsics */ - { SDL_TRUE, 33, 0 }, - { SDL_TRUE, 37, 0 }, - /* Test: even width and height with intrinsics, extra pitch */ - { SDL_TRUE, 32, 3 }, - /* Test: odd width and height with intrinsics, extra pitch */ - { SDL_TRUE, 33, 3 }, - { SDL_TRUE, 37, 3 }, - }; - int arg = 1; - const char *filename; - SDL_Surface *original; - SDL_Surface *converted; - SDL_Window *window; - SDL_Renderer *renderer; - SDL_Texture *output[3]; - const char *titles[3] = { "ORIGINAL", "SOFTWARE", "HARDWARE" }; - char title[128]; - const char *yuv_name; - const char *yuv_mode; - Uint32 rgb_format = SDL_PIXELFORMAT_RGBX8888; - Uint32 yuv_format = SDL_PIXELFORMAT_YV12; - int current = 0; - int pitch; - Uint8 *raw_yuv; - Uint32 then, now, i, iterations = 100; - SDL_bool should_run_automated_tests = SDL_FALSE; - - while (argv[arg] && *argv[arg] == '-') { - if (SDL_strcmp(argv[arg], "--jpeg") == 0) { - SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_JPEG); - } else if (SDL_strcmp(argv[arg], "--bt601") == 0) { - SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_BT601); - } else if (SDL_strcmp(argv[arg], "--bt709") == 0) { - SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_BT709); - } else if (SDL_strcmp(argv[arg], "--auto") == 0) { - SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_AUTOMATIC); - } else if (SDL_strcmp(argv[arg], "--yv12") == 0) { - yuv_format = SDL_PIXELFORMAT_YV12; - } else if (SDL_strcmp(argv[arg], "--iyuv") == 0) { - yuv_format = SDL_PIXELFORMAT_IYUV; - } else if (SDL_strcmp(argv[arg], "--yuy2") == 0) { - yuv_format = SDL_PIXELFORMAT_YUY2; - } else if (SDL_strcmp(argv[arg], "--uyvy") == 0) { - yuv_format = SDL_PIXELFORMAT_UYVY; - } else if (SDL_strcmp(argv[arg], "--yvyu") == 0) { - yuv_format = SDL_PIXELFORMAT_YVYU; - } else if (SDL_strcmp(argv[arg], "--nv12") == 0) { - yuv_format = SDL_PIXELFORMAT_NV12; - } else if (SDL_strcmp(argv[arg], "--nv21") == 0) { - yuv_format = SDL_PIXELFORMAT_NV21; - } else if (SDL_strcmp(argv[arg], "--rgb555") == 0) { - rgb_format = SDL_PIXELFORMAT_RGB555; - } else if (SDL_strcmp(argv[arg], "--rgb565") == 0) { - rgb_format = SDL_PIXELFORMAT_RGB565; - } else if (SDL_strcmp(argv[arg], "--rgb24") == 0) { - rgb_format = SDL_PIXELFORMAT_RGB24; - } else if (SDL_strcmp(argv[arg], "--argb") == 0) { - rgb_format = SDL_PIXELFORMAT_ARGB8888; - } else if (SDL_strcmp(argv[arg], "--abgr") == 0) { - rgb_format = SDL_PIXELFORMAT_ABGR8888; - } else if (SDL_strcmp(argv[arg], "--rgba") == 0) { - rgb_format = SDL_PIXELFORMAT_RGBA8888; - } else if (SDL_strcmp(argv[arg], "--bgra") == 0) { - rgb_format = SDL_PIXELFORMAT_BGRA8888; - } else if (SDL_strcmp(argv[arg], "--automated") == 0) { - should_run_automated_tests = SDL_TRUE; - } else { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Usage: %s [--jpeg|--bt601|-bt709|--auto] [--yv12|--iyuv|--yuy2|--uyvy|--yvyu|--nv12|--nv21] [--rgb555|--rgb565|--rgb24|--argb|--abgr|--rgba|--bgra] [image_filename]\n", argv[0]); - return 1; - } - ++arg; - } - - /* Run automated tests */ - if (should_run_automated_tests) { - for (i = 0; i < SDL_arraysize(automated_test_params); ++i) { - SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Running automated test, pattern size %d, extra pitch %d, intrinsics %s\n", - automated_test_params[i].pattern_size, - automated_test_params[i].extra_pitch, - automated_test_params[i].enable_intrinsics ? "enabled" : "disabled"); - if (run_automated_tests(automated_test_params[i].pattern_size, automated_test_params[i].extra_pitch) < 0) { - return 2; - } - } - return 0; - } - - if (argv[arg]) { - filename = argv[arg]; - } else { - filename = "testyuv.bmp"; - } - original = SDL_ConvertSurfaceFormat(SDL_LoadBMP(filename), SDL_PIXELFORMAT_RGB24, 0); - if (!original) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", filename, SDL_GetError()); - return 3; - } - - raw_yuv = SDL_calloc(1, MAX_YUV_SURFACE_SIZE(original->w, original->h, 0)); - ConvertRGBtoYUV(yuv_format, original->pixels, original->pitch, raw_yuv, original->w, original->h, - SDL_GetYUVConversionModeForResolution(original->w, original->h), - 0, 100); - pitch = CalculateYUVPitch(yuv_format, original->w); - - converted = SDL_CreateRGBSurfaceWithFormat(0, original->w, original->h, 0, rgb_format); - if (!converted) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create converted surface: %s\n", SDL_GetError()); - return 3; - } - - then = SDL_GetTicks(); - for ( i = 0; i < iterations; ++i ) { - SDL_ConvertPixels(original->w, original->h, yuv_format, raw_yuv, pitch, rgb_format, converted->pixels, converted->pitch); - } - now = SDL_GetTicks(); - SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "%d iterations in %d ms, %.2fms each\n", iterations, (now - then), (float)(now - then)/iterations); - - window = SDL_CreateWindow("YUV test", - SDL_WINDOWPOS_UNDEFINED, - SDL_WINDOWPOS_UNDEFINED, - original->w, original->h, - 0); - if (!window) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create window: %s\n", SDL_GetError()); - return 4; - } - - renderer = SDL_CreateRenderer(window, -1, 0); - if (!renderer) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create renderer: %s\n", SDL_GetError()); - return 4; - } - - output[0] = SDL_CreateTextureFromSurface(renderer, original); - output[1] = SDL_CreateTextureFromSurface(renderer, converted); - output[2] = SDL_CreateTexture(renderer, yuv_format, SDL_TEXTUREACCESS_STREAMING, original->w, original->h); - if (!output[0] || !output[1] || !output[2]) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't set create texture: %s\n", SDL_GetError()); - return 5; - } - SDL_UpdateTexture(output[2], NULL, raw_yuv, pitch); - - yuv_name = SDL_GetPixelFormatName(yuv_format); - if (SDL_strncmp(yuv_name, "SDL_PIXELFORMAT_", 16) == 0) { - yuv_name += 16; - } - - switch (SDL_GetYUVConversionModeForResolution(original->w, original->h)) { - case SDL_YUV_CONVERSION_JPEG: - yuv_mode = "JPEG"; - break; - case SDL_YUV_CONVERSION_BT601: - yuv_mode = "BT.601"; - break; - case SDL_YUV_CONVERSION_BT709: - yuv_mode = "BT.709"; - break; - default: - yuv_mode = "UNKNOWN"; - break; - } - - { int done = 0; - while ( !done ) - { - SDL_Event event; - while (SDL_PollEvent(&event) > 0) { - if (event.type == SDL_QUIT) { - done = 1; - } - if (event.type == SDL_KEYDOWN) { - if (event.key.keysym.sym == SDLK_ESCAPE) { - done = 1; - } else if (event.key.keysym.sym == SDLK_LEFT) { - --current; - } else if (event.key.keysym.sym == SDLK_RIGHT) { - ++current; - } - } - if (event.type == SDL_MOUSEBUTTONDOWN) { - if (event.button.x < (original->w/2)) { - --current; - } else { - ++current; - } - } - } - - /* Handle wrapping */ - if (current < 0) { - current += SDL_arraysize(output); - } - if (current >= SDL_arraysize(output)) { - current -= SDL_arraysize(output); - } - - SDL_RenderClear(renderer); - SDL_RenderCopy(renderer, output[current], NULL, NULL); - SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF); - if (current == 0) { - SDLTest_DrawString(renderer, 4, 4, titles[current]); - } else { - SDL_snprintf(title, sizeof(title), "%s %s %s", titles[current], yuv_name, yuv_mode); - SDLTest_DrawString(renderer, 4, 4, title); - } - SDL_RenderPresent(renderer); - SDL_Delay(10); - } - } - SDL_Quit(); - return 0; -} - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/test/testyuv_cvt.c b/SDL2-2.0.12/test/testyuv_cvt.c deleted file mode 100644 index 4d856ca..0000000 --- a/SDL2-2.0.12/test/testyuv_cvt.c +++ /dev/null @@ -1,300 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ - -#include "SDL.h" - -#include "testyuv_cvt.h" - - -static float clip3(float x, float y, float z) -{ - return ((z < x) ? x : ((z > y) ? y : z)); -} - -static void RGBtoYUV(Uint8 * rgb, int *yuv, SDL_YUV_CONVERSION_MODE mode, int monochrome, int luminance) -{ - if (mode == SDL_YUV_CONVERSION_JPEG) { - /* Full range YUV */ - yuv[0] = (int)(0.299 * rgb[0] + 0.587 * rgb[1] + 0.114 * rgb[2]); - yuv[1] = (int)((rgb[2] - yuv[0]) * 0.565 + 128); - yuv[2] = (int)((rgb[0] - yuv[0]) * 0.713 + 128); - } else { - // This formula is from Microsoft's documentation: - // https://msdn.microsoft.com/en-us/library/windows/desktop/dd206750(v=vs.85).aspx - // L = Kr * R + Kb * B + (1 - Kr - Kb) * G - // Y = floor(2^(M-8) * (219*(L-Z)/S + 16) + 0.5); - // U = clip3(0, (2^M)-1, floor(2^(M-8) * (112*(B-L) / ((1-Kb)*S) + 128) + 0.5)); - // V = clip3(0, (2^M)-1, floor(2^(M-8) * (112*(R-L) / ((1-Kr)*S) + 128) + 0.5)); - float S, Z, R, G, B, L, Kr, Kb, Y, U, V; - - if (mode == SDL_YUV_CONVERSION_BT709) { - /* BT.709 */ - Kr = 0.2126f; - Kb = 0.0722f; - } else { - /* BT.601 */ - Kr = 0.299f; - Kb = 0.114f; - } - - S = 255.0f; - Z = 0.0f; - R = rgb[0]; - G = rgb[1]; - B = rgb[2]; - L = Kr * R + Kb * B + (1 - Kr - Kb) * G; - Y = (Uint8)SDL_floorf((219*(L-Z)/S + 16) + 0.5f); - U = (Uint8)clip3(0, 255, SDL_floorf((112.0f*(B-L) / ((1.0f-Kb)*S) + 128) + 0.5f)); - V = (Uint8)clip3(0, 255, SDL_floorf((112.0f*(R-L) / ((1.0f-Kr)*S) + 128) + 0.5f)); - - yuv[0] = (Uint8)Y; - yuv[1] = (Uint8)U; - yuv[2] = (Uint8)V; - } - - if (monochrome) { - yuv[1] = 128; - yuv[2] = 128; - } - - if (luminance != 100) { - yuv[0] = yuv[0] * luminance / 100; - if (yuv[0] > 255) - yuv[0] = 255; - } -} - -static void ConvertRGBtoPlanar2x2(Uint32 format, Uint8 *src, int pitch, Uint8 *out, int w, int h, SDL_YUV_CONVERSION_MODE mode, int monochrome, int luminance) -{ - int x, y; - int yuv[4][3]; - Uint8 *Y1, *Y2, *U, *V; - Uint8 *rgb1, *rgb2; - int rgb_row_advance = (pitch - w*3) + pitch; - int UV_advance; - - rgb1 = src; - rgb2 = src + pitch; - - Y1 = out; - Y2 = Y1 + w; - switch (format) { - case SDL_PIXELFORMAT_YV12: - V = (Y1 + h * w); - U = V + ((h + 1)/2)*((w + 1)/2); - UV_advance = 1; - break; - case SDL_PIXELFORMAT_IYUV: - U = (Y1 + h * w); - V = U + ((h + 1)/2)*((w + 1)/2); - UV_advance = 1; - break; - case SDL_PIXELFORMAT_NV12: - U = (Y1 + h * w); - V = U + 1; - UV_advance = 2; - break; - case SDL_PIXELFORMAT_NV21: - V = (Y1 + h * w); - U = V + 1; - UV_advance = 2; - break; - default: - SDL_assert(!"Unsupported planar YUV format"); - return; - } - - for (y = 0; y < (h - 1); y += 2) { - for (x = 0; x < (w - 1); x += 2) { - RGBtoYUV(rgb1, yuv[0], mode, monochrome, luminance); - rgb1 += 3; - *Y1++ = (Uint8)yuv[0][0]; - - RGBtoYUV(rgb1, yuv[1], mode, monochrome, luminance); - rgb1 += 3; - *Y1++ = (Uint8)yuv[1][0]; - - RGBtoYUV(rgb2, yuv[2], mode, monochrome, luminance); - rgb2 += 3; - *Y2++ = (Uint8)yuv[2][0]; - - RGBtoYUV(rgb2, yuv[3], mode, monochrome, luminance); - rgb2 += 3; - *Y2++ = (Uint8)yuv[3][0]; - - *U = (Uint8)SDL_floorf((yuv[0][1] + yuv[1][1] + yuv[2][1] + yuv[3][1])/4.0f + 0.5f); - U += UV_advance; - - *V = (Uint8)SDL_floorf((yuv[0][2] + yuv[1][2] + yuv[2][2] + yuv[3][2])/4.0f + 0.5f); - V += UV_advance; - } - /* Last column */ - if (x == (w - 1)) { - RGBtoYUV(rgb1, yuv[0], mode, monochrome, luminance); - rgb1 += 3; - *Y1++ = (Uint8)yuv[0][0]; - - RGBtoYUV(rgb2, yuv[2], mode, monochrome, luminance); - rgb2 += 3; - *Y2++ = (Uint8)yuv[2][0]; - - *U = (Uint8)SDL_floorf((yuv[0][1] + yuv[2][1])/2.0f + 0.5f); - U += UV_advance; - - *V = (Uint8)SDL_floorf((yuv[0][2] + yuv[2][2])/2.0f + 0.5f); - V += UV_advance; - } - Y1 += w; - Y2 += w; - rgb1 += rgb_row_advance; - rgb2 += rgb_row_advance; - } - /* Last row */ - if (y == (h - 1)) { - for (x = 0; x < (w - 1); x += 2) { - RGBtoYUV(rgb1, yuv[0], mode, monochrome, luminance); - rgb1 += 3; - *Y1++ = (Uint8)yuv[0][0]; - - RGBtoYUV(rgb1, yuv[1], mode, monochrome, luminance); - rgb1 += 3; - *Y1++ = (Uint8)yuv[1][0]; - - *U = (Uint8)SDL_floorf((yuv[0][1] + yuv[1][1])/2.0f + 0.5f); - U += UV_advance; - - *V = (Uint8)SDL_floorf((yuv[0][2] + yuv[1][2])/2.0f + 0.5f); - V += UV_advance; - } - /* Last column */ - if (x == (w - 1)) { - RGBtoYUV(rgb1, yuv[0], mode, monochrome, luminance); - *Y1++ = (Uint8)yuv[0][0]; - - *U = (Uint8)yuv[0][1]; - U += UV_advance; - - *V = (Uint8)yuv[0][2]; - V += UV_advance; - } - } -} - -static void ConvertRGBtoPacked4(Uint32 format, Uint8 *src, int pitch, Uint8 *out, int w, int h, SDL_YUV_CONVERSION_MODE mode, int monochrome, int luminance) -{ - int x, y; - int yuv[2][3]; - Uint8 *Y1, *Y2, *U, *V; - Uint8 *rgb; - int rgb_row_advance = (pitch - w*3); - - rgb = src; - - switch (format) { - case SDL_PIXELFORMAT_YUY2: - Y1 = out; - U = out+1; - Y2 = out+2; - V = out+3; - break; - case SDL_PIXELFORMAT_UYVY: - U = out; - Y1 = out+1; - V = out+2; - Y2 = out+3; - break; - case SDL_PIXELFORMAT_YVYU: - Y1 = out; - V = out+1; - Y2 = out+2; - U = out+3; - break; - default: - SDL_assert(!"Unsupported packed YUV format"); - return; - } - - for (y = 0; y < h; ++y) { - for (x = 0; x < (w - 1); x += 2) { - RGBtoYUV(rgb, yuv[0], mode, monochrome, luminance); - rgb += 3; - *Y1 = (Uint8)yuv[0][0]; - Y1 += 4; - - RGBtoYUV(rgb, yuv[1], mode, monochrome, luminance); - rgb += 3; - *Y2 = (Uint8)yuv[1][0]; - Y2 += 4; - - *U = (Uint8)SDL_floorf((yuv[0][1] + yuv[1][1])/2.0f + 0.5f); - U += 4; - - *V = (Uint8)SDL_floorf((yuv[0][2] + yuv[1][2])/2.0f + 0.5f); - V += 4; - } - /* Last column */ - if (x == (w - 1)) { - RGBtoYUV(rgb, yuv[0], mode, monochrome, luminance); - rgb += 3; - *Y2 = *Y1 = (Uint8)yuv[0][0]; - Y1 += 4; - Y2 += 4; - - *U = (Uint8)yuv[0][1]; - U += 4; - - *V = (Uint8)yuv[0][2]; - V += 4; - } - rgb += rgb_row_advance; - } -} - -SDL_bool ConvertRGBtoYUV(Uint32 format, Uint8 *src, int pitch, Uint8 *out, int w, int h, SDL_YUV_CONVERSION_MODE mode, int monochrome, int luminance) -{ - switch (format) - { - case SDL_PIXELFORMAT_YV12: - case SDL_PIXELFORMAT_IYUV: - case SDL_PIXELFORMAT_NV12: - case SDL_PIXELFORMAT_NV21: - ConvertRGBtoPlanar2x2(format, src, pitch, out, w, h, mode, monochrome, luminance); - return SDL_TRUE; - case SDL_PIXELFORMAT_YUY2: - case SDL_PIXELFORMAT_UYVY: - case SDL_PIXELFORMAT_YVYU: - ConvertRGBtoPacked4(format, src, pitch, out, w, h, mode, monochrome, luminance); - return SDL_TRUE; - default: - return SDL_FALSE; - } -} - -int CalculateYUVPitch(Uint32 format, int width) -{ - switch (format) - { - case SDL_PIXELFORMAT_YV12: - case SDL_PIXELFORMAT_IYUV: - case SDL_PIXELFORMAT_NV12: - case SDL_PIXELFORMAT_NV21: - return width; - case SDL_PIXELFORMAT_YUY2: - case SDL_PIXELFORMAT_UYVY: - case SDL_PIXELFORMAT_YVYU: - return 4*((width + 1)/2); - default: - return 0; - } -} - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/test/testyuv_cvt.h b/SDL2-2.0.12/test/testyuv_cvt.h deleted file mode 100644 index 3896a8d..0000000 --- a/SDL2-2.0.12/test/testyuv_cvt.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ - -/* These functions are designed for testing correctness, not for speed */ - -extern SDL_bool ConvertRGBtoYUV(Uint32 format, Uint8 *src, int pitch, Uint8 *out, int w, int h, SDL_YUV_CONVERSION_MODE mode, int monochrome, int luminance); -extern int CalculateYUVPitch(Uint32 format, int width); diff --git a/SDL2-2.0.12/test/torturethread.c b/SDL2-2.0.12/test/torturethread.c deleted file mode 100644 index 382a2ed..0000000 --- a/SDL2-2.0.12/test/torturethread.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - Copyright (C) 1997-2020 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. -*/ - -/* Simple test of the SDL threading code */ - -#include -#include -#include -#include - -#include "SDL.h" - -#define NUMTHREADS 10 - -static SDL_atomic_t time_for_threads_to_die[NUMTHREADS]; - -/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ -static void -quit(int rc) -{ - SDL_Quit(); - exit(rc); -} - -int SDLCALL -SubThreadFunc(void *data) -{ - while (!*(int volatile *) data) { - ; /* SDL_Delay(10); *//* do nothing */ - } - return 0; -} - -int SDLCALL -ThreadFunc(void *data) -{ - SDL_Thread *sub_threads[NUMTHREADS]; - int flags[NUMTHREADS]; - int i; - int tid = (int) (uintptr_t) data; - - SDL_Log("Creating Thread %d\n", tid); - - for (i = 0; i < NUMTHREADS; i++) { - char name[64]; - SDL_snprintf(name, sizeof (name), "Child%d_%d", tid, i); - flags[i] = 0; - sub_threads[i] = SDL_CreateThread(SubThreadFunc, name, &flags[i]); - } - - SDL_Log("Thread '%d' waiting for signal\n", tid); - while (SDL_AtomicGet(&time_for_threads_to_die[tid]) != 1) { - ; /* do nothing */ - } - - SDL_Log("Thread '%d' sending signals to subthreads\n", tid); - for (i = 0; i < NUMTHREADS; i++) { - flags[i] = 1; - SDL_WaitThread(sub_threads[i], NULL); - } - - SDL_Log("Thread '%d' exiting!\n", tid); - - return 0; -} - -int -main(int argc, char *argv[]) -{ - SDL_Thread *threads[NUMTHREADS]; - int i; - - /* Enable standard application logging */ - SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); - - /* Load the SDL library */ - if (SDL_Init(0) < 0) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError()); - return (1); - } - - signal(SIGSEGV, SIG_DFL); - for (i = 0; i < NUMTHREADS; i++) { - char name[64]; - SDL_snprintf(name, sizeof (name), "Parent%d", i); - SDL_AtomicSet(&time_for_threads_to_die[i], 0); - threads[i] = SDL_CreateThread(ThreadFunc, name, (void*) (uintptr_t) i); - - if (threads[i] == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create thread: %s\n", SDL_GetError()); - quit(1); - } - } - - for (i = 0; i < NUMTHREADS; i++) { - SDL_AtomicSet(&time_for_threads_to_die[i], 1); - } - - for (i = 0; i < NUMTHREADS; i++) { - SDL_WaitThread(threads[i], NULL); - } - SDL_Quit(); - return (0); -} diff --git a/SDL2-2.0.12/test/utf8.txt b/SDL2-2.0.12/test/utf8.txt deleted file mode 100644 index aab22f1..0000000 --- a/SDL2-2.0.12/test/utf8.txt +++ /dev/null @@ -1,287 +0,0 @@ -UTF-8 decoder capability and stress test ----------------------------------------- - -Markus Kuhn - 2003-02-19 - -This test file can help you examine, how your UTF-8 decoder handles -various types of correct, malformed, or otherwise interesting UTF-8 -sequences. This file is not meant to be a conformance test. It does -not prescribes any particular outcome and therefore there is no way to -"pass" or "fail" this test file, even though the texts suggests a -preferable decoder behaviour at some places. The aim is instead to -help you think about and test the behaviour of your UTF-8 on a -systematic collection of unusual inputs. Experience so far suggests -that most first-time authors of UTF-8 decoders find at least one -serious problem in their decoder by using this file. - -The test lines below cover boundary conditions, malformed UTF-8 -sequences as well as correctly encoded UTF-8 sequences of Unicode code -points that should never occur in a correct UTF-8 file. - -According to ISO 10646-1:2000, sections D.7 and 2.3c, a device -receiving UTF-8 shall interpret a "malformed sequence in the same way -that it interprets a character that is outside the adopted subset" and -"characters that are not within the adopted subset shall be indicated -to the user" by a receiving device. A quite commonly used approach in -UTF-8 decoders is to replace any malformed UTF-8 sequence by a -replacement character (U+FFFD), which looks a bit like an inverted -question mark, or a similar symbol. It might be a good idea to -visually distinguish a malformed UTF-8 sequence from a correctly -encoded Unicode character that is just not available in the current -font but otherwise fully legal, even though ISO 10646-1 doesn't -mandate this. In any case, just ignoring malformed sequences or -unavailable characters does not conform to ISO 10646, will make -debugging more difficult, and can lead to user confusion. - -Please check, whether a malformed UTF-8 sequence is (1) represented at -all, (2) represented by exactly one single replacement character (or -equivalent signal), and (3) the following quotation mark after an -illegal UTF-8 sequence is correctly displayed, i.e. proper -resynchronization takes place immageately after any malformed -sequence. This file says "THE END" in the last line, so if you don't -see that, your decoder crashed somehow before, which should always be -cause for concern. - -All lines in this file are exactly 79 characters long (plus the line -feed). In addition, all lines end with "|", except for the two test -lines 2.1.1 and 2.2.1, which contain non-printable ASCII controls -U+0000 and U+007F. If you display this file with a fixed-width font, -these "|" characters should all line up in column 79 (right margin). -This allows you to test quickly, whether your UTF-8 decoder finds the -correct number of characters in every line, that is whether each -malformed sequences is replaced by a single replacement character. - -Note that as an alternative to the notion of malformed sequence used -here, it is also a perfectly acceptable (and in some situations even -preferable) solution to represent each individual byte of a malformed -sequence by a replacement character. If you follow this strategy in -your decoder, then please ignore the "|" column. - - -Here come the tests: | - | -1 Some correct UTF-8 text | - | -(The codepoints for this test are: | - U+03BA U+1F79 U+03C3 U+03BC U+03B5 --ryan.) | - | -You should see the Greek word 'kosme': "κόσμε" | - | - | -2 Boundary condition test cases | - | -2.1 First possible sequence of a certain length | - | -(byte zero skipped...there's a null added at the end of the test. --ryan.) | - | -2.1.2 2 bytes (U-00000080): "€" | -2.1.3 3 bytes (U-00000800): "ࠀ" | -2.1.4 4 bytes (U-00010000): "𐀀" | - | -(5 and 6 byte sequences were made illegal in rfc3629. --ryan.) | -2.1.5 5 bytes (U-00200000): "" | -2.1.6 6 bytes (U-04000000): "" | - | -2.2 Last possible sequence of a certain length | - | -2.2.1 1 byte (U-0000007F): "" | -2.2.2 2 bytes (U-000007FF): "߿" | - | -(Section 5.3.2 below calls this illegal. --ryan.) | -2.2.3 3 bytes (U-0000FFFF): "￿" | - | -(5 and 6 bytes sequences, and 4 bytes sequences > 0x10FFFF were made illegal | - in rfc3629, so these next three should be replaced with a invalid | - character codepoint. --ryan.) | -2.2.4 4 bytes (U-001FFFFF): "" | -2.2.5 5 bytes (U-03FFFFFF): "" | -2.2.6 6 bytes (U-7FFFFFFF): "" | - | -2.3 Other boundary conditions | - | -2.3.1 U-0000D7FF = ed 9f bf = "퟿" | -2.3.2 U-0000E000 = ee 80 80 = "" | -2.3.3 U-0000FFFD = ef bf bd = "�" | -2.3.4 U-0010FFFF = f4 8f bf bf = "􏿿" | - | -(This one is bogus in rfc3629. --ryan.) | -2.3.5 U-00110000 = f4 90 80 80 = "" | - | -3 Malformed sequences | - | -3.1 Unexpected continuation bytes | - | -Each unexpected continuation byte should be separately signalled as a | -malformed sequence of its own. | - | -3.1.1 First continuation byte 0x80: "" | -3.1.2 Last continuation byte 0xbf: "" | - | -3.1.3 2 continuation bytes: "" | -3.1.4 3 continuation bytes: "" | -3.1.5 4 continuation bytes: "" | -3.1.6 5 continuation bytes: "" | -3.1.7 6 continuation bytes: "" | -3.1.8 7 continuation bytes: "" | - | -3.1.9 Sequence of all 64 possible continuation bytes (0x80-0xbf): | - | - " | - | - | - " | - | -3.2 Lonely start characters | - | -3.2.1 All 32 first bytes of 2-byte sequences (0xc0-0xdf), | - each followed by a space character: | - | - " | - " | - | -3.2.2 All 16 first bytes of 3-byte sequences (0xe0-0xef), | - each followed by a space character: | - | - " " | - | -3.2.3 All 8 first bytes of 4-byte sequences (0xf0-0xf7), | - each followed by a space character: | - | - " " | - | -3.2.4 All 4 first bytes of 5-byte sequences (0xf8-0xfb), | - each followed by a space character: | - | - " " | - | -3.2.5 All 2 first bytes of 6-byte sequences (0xfc-0xfd), | - each followed by a space character: | - | - " " | - | -3.3 Sequences with last continuation byte missing | - | -All bytes of an incomplete sequence should be signalled as a single | -malformed sequence, i.e., you should see only a single replacement | -character in each of the next 10 tests. (Characters as in section 2) | - | -3.3.1 2-byte sequence with last byte missing (U+0000): "" | -3.3.2 3-byte sequence with last byte missing (U+0000): "" | -3.3.3 4-byte sequence with last byte missing (U+0000): "" | -3.3.4 5-byte sequence with last byte missing (U+0000): "" | -3.3.5 6-byte sequence with last byte missing (U+0000): "" | -3.3.6 2-byte sequence with last byte missing (U-000007FF): "" | -3.3.7 3-byte sequence with last byte missing (U-0000FFFF): "" | -3.3.8 4-byte sequence with last byte missing (U-001FFFFF): "" | -3.3.9 5-byte sequence with last byte missing (U-03FFFFFF): "" | -3.3.10 6-byte sequence with last byte missing (U-7FFFFFFF): "" | - | -3.4 Concatenation of incomplete sequences | - | -All the 10 sequences of 3.3 concatenated, you should see 10 malformed | -sequences being signalled: | - | - "" | - | -3.5 Impossible bytes | - | -The following two bytes cannot appear in a correct UTF-8 string | - | -3.5.1 fe = "" | -3.5.2 ff = "" | -3.5.3 fe fe ff ff = "" | - | -4 Overlong sequences | - | -The following sequences are not malformed according to the letter of | -the Unicode 2.0 standard. However, they are longer then necessary and | -a correct UTF-8 encoder is not allowed to produce them. A "safe UTF-8 | -decoder" should reject them just like malformed sequences for two | -reasons: (1) It helps to debug applications if overlong sequences are | -not treated as valid representations of characters, because this helps | -to spot problems more quickly. (2) Overlong sequences provide | -alternative representations of characters, that could maliciously be | -used to bypass filters that check only for ASCII characters. For | -instance, a 2-byte encoded line feed (LF) would not be caught by a | -line counter that counts only 0x0a bytes, but it would still be | -processed as a line feed by an unsafe UTF-8 decoder later in the | -pipeline. From a security point of view, ASCII compatibility of UTF-8 | -sequences means also, that ASCII characters are *only* allowed to be | -represented by ASCII bytes in the range 0x00-0x7f. To ensure this | -aspect of ASCII compatibility, use only "safe UTF-8 decoders" that | -reject overlong UTF-8 sequences for which a shorter encoding exists. | - | -4.1 Examples of an overlong ASCII character | - | -With a safe UTF-8 decoder, all of the following five overlong | -representations of the ASCII character slash ("/") should be rejected | -like a malformed UTF-8 sequence, for instance by substituting it with | -a replacement character. If you see a slash below, you do not have a | -safe UTF-8 decoder! | - | -4.1.1 U+002F = c0 af = "" | -4.1.2 U+002F = e0 80 af = "" | -4.1.3 U+002F = f0 80 80 af = "" | -4.1.4 U+002F = f8 80 80 80 af = "" | -4.1.5 U+002F = fc 80 80 80 80 af = "" | - | -4.2 Maximum overlong sequences | - | -Below you see the highest Unicode value that is still resulting in an | -overlong sequence if represented with the given number of bytes. This | -is a boundary test for safe UTF-8 decoders. All five characters should | -be rejected like malformed UTF-8 sequences. | - | -4.2.1 U-0000007F = c1 bf = "" | -4.2.2 U-000007FF = e0 9f bf = "" | -4.2.3 U-0000FFFF = f0 8f bf bf = "" | -4.2.4 U-001FFFFF = f8 87 bf bf bf = "" | -4.2.5 U-03FFFFFF = fc 83 bf bf bf bf = "" | - | -4.3 Overlong representation of the NUL character | - | -The following five sequences should also be rejected like malformed | -UTF-8 sequences and should not be treated like the ASCII NUL | -character. | - | -4.3.1 U+0000 = c0 80 = "" | -4.3.2 U+0000 = e0 80 80 = "" | -4.3.3 U+0000 = f0 80 80 80 = "" | -4.3.4 U+0000 = f8 80 80 80 80 = "" | -4.3.5 U+0000 = fc 80 80 80 80 80 = "" | - | -5 Illegal code positions | - | -The following UTF-8 sequences should be rejected like malformed | -sequences, because they never represent valid ISO 10646 characters and | -a UTF-8 decoder that accepts them might introduce security problems | -comparable to overlong UTF-8 sequences. | - | -5.1 Single UTF-16 surrogates | - | -5.1.1 U+D800 = ed a0 80 = "" | -5.1.2 U+DB7F = ed ad bf = "" | -5.1.3 U+DB80 = ed ae 80 = "" | -5.1.4 U+DBFF = ed af bf = "" | -5.1.5 U+DC00 = ed b0 80 = "" | -5.1.6 U+DF80 = ed be 80 = "" | -5.1.7 U+DFFF = ed bf bf = "" | - | -5.2 Paired UTF-16 surrogates | - | -5.2.1 U+D800 U+DC00 = ed a0 80 ed b0 80 = "" | -5.2.2 U+D800 U+DFFF = ed a0 80 ed bf bf = "" | -5.2.3 U+DB7F U+DC00 = ed ad bf ed b0 80 = "" | -5.2.4 U+DB7F U+DFFF = ed ad bf ed bf bf = "" | -5.2.5 U+DB80 U+DC00 = ed ae 80 ed b0 80 = "" | -5.2.6 U+DB80 U+DFFF = ed ae 80 ed bf bf = "" | -5.2.7 U+DBFF U+DC00 = ed af bf ed b0 80 = "" | -5.2.8 U+DBFF U+DFFF = ed af bf ed bf bf = "" | - | -5.3 Other illegal code positions | - | -5.3.1 U+FFFE = ef bf be = "￾" | -5.3.2 U+FFFF = ef bf bf = "￿" | - | -THE END | - diff --git a/SDL2-2.0.12/wayland-protocols/org-kde-kwin-server-decoration-manager.xml b/SDL2-2.0.12/wayland-protocols/org-kde-kwin-server-decoration-manager.xml deleted file mode 100644 index 8bc106c..0000000 --- a/SDL2-2.0.12/wayland-protocols/org-kde-kwin-server-decoration-manager.xml +++ /dev/null @@ -1,94 +0,0 @@ - - - . - ]]> - - - This interface allows to coordinate whether the server should create - a server-side window decoration around a wl_surface representing a - shell surface (wl_shell_surface or similar). By announcing support - for this interface the server indicates that it supports server - side decorations. - - - - When a client creates a server-side decoration object it indicates - that it supports the protocol. The client is supposed to tell the - server whether it wants server-side decorations or will provide - client-side decorations. - - If the client does not create a server-side decoration object for - a surface the server interprets this as lack of support for this - protocol and considers it as client-side decorated. Nevertheless a - client-side decorated surface should use this protocol to indicate - to the server that it does not want a server-side deco. - - - - - - - - - - - - - This event is emitted directly after binding the interface. It contains - the default mode for the decoration. When a new server decoration object - is created this new object will be in the default mode until the first - request_mode is requested. - - The server may change the default mode at any time. - - - - - - - - - - - - - - - - - - - - - This event is emitted directly after the decoration is created and - represents the base decoration policy by the server. E.g. a server - which wants all surfaces to be client-side decorated will send Client, - a server which wants server-side decoration will send Server. - - The client can request a different mode through the decoration request. - The server will acknowledge this by another event with the same mode. So - even if a server prefers server-side decoration it's possible to force a - client-side decoration. - - The server may emit this event at any time. In this case the client can - again request a different mode. It's the responsibility of the server to - prevent a feedback loop. - - - - - diff --git a/SDL2-2.0.12/wayland-protocols/xdg-shell-unstable-v6.xml b/SDL2-2.0.12/wayland-protocols/xdg-shell-unstable-v6.xml deleted file mode 100644 index 1c0f924..0000000 --- a/SDL2-2.0.12/wayland-protocols/xdg-shell-unstable-v6.xml +++ /dev/null @@ -1,1044 +0,0 @@ - - - - - Copyright © 2008-2013 Kristian Høgsberg - Copyright © 2013 Rafael Antognolli - Copyright © 2013 Jasper St. Pierre - Copyright © 2010-2013 Intel Corporation - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice (including the next - paragraph) shall be included in all copies or substantial portions of the - Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - - - - - xdg_shell allows clients to turn a wl_surface into a "real window" - which can be dragged, resized, stacked, and moved around by the - user. Everything about this interface is suited towards traditional - desktop environments. - - - - - - - - - - - - - - Destroy this xdg_shell object. - - Destroying a bound xdg_shell object while there are surfaces - still alive created by this xdg_shell object instance is illegal - and will result in a protocol error. - - - - - - Create a positioner object. A positioner object is used to position - surfaces relative to some parent surface. See the interface description - and xdg_surface.get_popup for details. - - - - - - - This creates an xdg_surface for the given surface. While xdg_surface - itself is not a role, the corresponding surface may only be assigned - a role extending xdg_surface, such as xdg_toplevel or xdg_popup. - - This creates an xdg_surface for the given surface. An xdg_surface is - used as basis to define a role to a given surface, such as xdg_toplevel - or xdg_popup. It also manages functionality shared between xdg_surface - based surface roles. - - See the documentation of xdg_surface for more details about what an - xdg_surface is and how it is used. - - - - - - - - A client must respond to a ping event with a pong request or - the client may be deemed unresponsive. See xdg_shell.ping. - - - - - - - The ping event asks the client if it's still alive. Pass the - serial specified in the event back to the compositor by sending - a "pong" request back with the specified serial. See xdg_shell.ping. - - Compositors can use this to determine if the client is still - alive. It's unspecified what will happen if the client doesn't - respond to the ping request, or in what timeframe. Clients should - try to respond in a reasonable amount of time. - - A compositor is free to ping in any way it wants, but a client must - always respond to any xdg_shell object it created. - - - - - - - - The xdg_positioner provides a collection of rules for the placement of a - child surface relative to a parent surface. Rules can be defined to ensure - the child surface remains within the visible area's borders, and to - specify how the child surface changes its position, such as sliding along - an axis, or flipping around a rectangle. These positioner-created rules are - constrained by the requirement that a child surface must intersect with or - be at least partially adjacent to its parent surface. - - See the various requests for details about possible rules. - - At the time of the request, the compositor makes a copy of the rules - specified by the xdg_positioner. Thus, after the request is complete the - xdg_positioner object can be destroyed or reused; further changes to the - object will have no effect on previous usages. - - For an xdg_positioner object to be considered complete, it must have a - non-zero size set by set_size, and a non-zero anchor rectangle set by - set_anchor_rect. Passing an incomplete xdg_positioner object when - positioning a surface raises an error. - - - - - - - - - Notify the compositor that the xdg_positioner will no longer be used. - - - - - - Set the size of the surface that is to be positioned with the positioner - object. The size is in surface-local coordinates and corresponds to the - window geometry. See xdg_surface.set_window_geometry. - - If a zero or negative size is set the invalid_input error is raised. - - - - - - - - Specify the anchor rectangle within the parent surface that the child - surface will be placed relative to. The rectangle is relative to the - window geometry as defined by xdg_surface.set_window_geometry of the - parent surface. The rectangle must be at least 1x1 large. - - When the xdg_positioner object is used to position a child surface, the - anchor rectangle may not extend outside the window geometry of the - positioned child's parent surface. - - If a zero or negative size is set the invalid_input error is raised. - - - - - - - - - - - - - - - - - - Defines a set of edges for the anchor rectangle. These are used to - derive an anchor point that the child surface will be positioned - relative to. If two orthogonal edges are specified (e.g. 'top' and - 'left'), then the anchor point will be the intersection of the edges - (e.g. the top left position of the rectangle); otherwise, the derived - anchor point will be centered on the specified edge, or in the center of - the anchor rectangle if no edge is specified. - - If two parallel anchor edges are specified (e.g. 'left' and 'right'), - the invalid_input error is raised. - - - - - - - - - - - - - - - Defines in what direction a surface should be positioned, relative to - the anchor point of the parent surface. If two orthogonal gravities are - specified (e.g. 'bottom' and 'right'), then the child surface will be - placed in the specified direction; otherwise, the child surface will be - centered over the anchor point on any axis that had no gravity - specified. - - If two parallel gravities are specified (e.g. 'left' and 'right'), the - invalid_input error is raised. - - - - - - - The constraint adjustment value define ways the compositor will adjust - the position of the surface, if the unadjusted position would result - in the surface being partly constrained. - - Whether a surface is considered 'constrained' is left to the compositor - to determine. For example, the surface may be partly outside the - compositor's defined 'work area', thus necessitating the child surface's - position be adjusted until it is entirely inside the work area. - - The adjustments can be combined, according to a defined precedence: 1) - Flip, 2) Slide, 3) Resize. - - - - Don't alter the surface position even if it is constrained on some - axis, for example partially outside the edge of a monitor. - - - - - Slide the surface along the x axis until it is no longer constrained. - - First try to slide towards the direction of the gravity on the x axis - until either the edge in the opposite direction of the gravity is - unconstrained or the edge in the direction of the gravity is - constrained. - - Then try to slide towards the opposite direction of the gravity on the - x axis until either the edge in the direction of the gravity is - unconstrained or the edge in the opposite direction of the gravity is - constrained. - - - - - Slide the surface along the y axis until it is no longer constrained. - - First try to slide towards the direction of the gravity on the y axis - until either the edge in the opposite direction of the gravity is - unconstrained or the edge in the direction of the gravity is - constrained. - - Then try to slide towards the opposite direction of the gravity on the - y axis until either the edge in the direction of the gravity is - unconstrained or the edge in the opposite direction of the gravity is - constrained. - - - - - Invert the anchor and gravity on the x axis if the surface is - constrained on the x axis. For example, if the left edge of the - surface is constrained, the gravity is 'left' and the anchor is - 'left', change the gravity to 'right' and the anchor to 'right'. - - If the adjusted position also ends up being constrained, the resulting - position of the flip_x adjustment will be the one before the - adjustment. - - - - - Invert the anchor and gravity on the y axis if the surface is - constrained on the y axis. For example, if the bottom edge of the - surface is constrained, the gravity is 'bottom' and the anchor is - 'bottom', change the gravity to 'top' and the anchor to 'top'. - - If the adjusted position also ends up being constrained, the resulting - position of the flip_y adjustment will be the one before the - adjustment. - - - - - Resize the surface horizontally so that it is completely - unconstrained. - - - - - Resize the surface vertically so that it is completely unconstrained. - - - - - - - Specify how the window should be positioned if the originally intended - position caused the surface to be constrained, meaning at least - partially outside positioning boundaries set by the compositor. The - adjustment is set by constructing a bitmask describing the adjustment to - be made when the surface is constrained on that axis. - - If no bit for one axis is set, the compositor will assume that the child - surface should not change its position on that axis when constrained. - - If more than one bit for one axis is set, the order of how adjustments - are applied is specified in the corresponding adjustment descriptions. - - The default adjustment is none. - - - - - - - Specify the surface position offset relative to the position of the - anchor on the anchor rectangle and the anchor on the surface. For - example if the anchor of the anchor rectangle is at (x, y), the surface - has the gravity bottom|right, and the offset is (ox, oy), the calculated - surface position will be (x + ox, y + oy). The offset position of the - surface is the one used for constraint testing. See - set_constraint_adjustment. - - An example use case is placing a popup menu on top of a user interface - element, while aligning the user interface element of the parent surface - with some user interface element placed somewhere in the popup surface. - - - - - - - - - An interface that may be implemented by a wl_surface, for - implementations that provide a desktop-style user interface. - - It provides a base set of functionality required to construct user - interface elements requiring management by the compositor, such as - toplevel windows, menus, etc. The types of functionality are split into - xdg_surface roles. - - Creating an xdg_surface does not set the role for a wl_surface. In order - to map an xdg_surface, the client must create a role-specific object - using, e.g., get_toplevel, get_popup. The wl_surface for any given - xdg_surface can have at most one role, and may not be assigned any role - not based on xdg_surface. - - A role must be assigned before any other requests are made to the - xdg_surface object. - - The client must call wl_surface.commit on the corresponding wl_surface - for the xdg_surface state to take effect. - - Creating an xdg_surface from a wl_surface which has a buffer attached or - committed is a client error, and any attempts by a client to attach or - manipulate a buffer prior to the first xdg_surface.configure call must - also be treated as errors. - - For a surface to be mapped by the compositor, the following conditions - must be met: (1) the client has assigned a xdg_surface based role to the - surface, (2) the client has set and committed the xdg_surface state and - the role dependent state to the surface and (3) the client has committed a - buffer to the surface. - - - - - - - - - - - Destroy the xdg_surface object. An xdg_surface must only be destroyed - after its role object has been destroyed. - - - - - - This creates an xdg_toplevel object for the given xdg_surface and gives - the associated wl_surface the xdg_toplevel role. - - See the documentation of xdg_toplevel for more details about what an - xdg_toplevel is and how it is used. - - - - - - - This creates an xdg_popup object for the given xdg_surface and gives the - associated wl_surface the xdg_popup role. - - See the documentation of xdg_popup for more details about what an - xdg_popup is and how it is used. - - - - - - - - - The window geometry of a surface is its "visible bounds" from the - user's perspective. Client-side decorations often have invisible - portions like drop-shadows which should be ignored for the - purposes of aligning, placing and constraining windows. - - The window geometry is double buffered, and will be applied at the - time wl_surface.commit of the corresponding wl_surface is called. - - Once the window geometry of the surface is set, it is not possible to - unset it, and it will remain the same until set_window_geometry is - called again, even if a new subsurface or buffer is attached. - - If never set, the value is the full bounds of the surface, - including any subsurfaces. This updates dynamically on every - commit. This unset is meant for extremely simple clients. - - The arguments are given in the surface-local coordinate space of - the wl_surface associated with this xdg_surface. - - The width and height must be greater than zero. Setting an invalid size - will raise an error. When applied, the effective window geometry will be - the set window geometry clamped to the bounding rectangle of the - combined geometry of the surface of the xdg_surface and the associated - subsurfaces. - - - - - - - - - - When a configure event is received, if a client commits the - surface in response to the configure event, then the client - must make an ack_configure request sometime before the commit - request, passing along the serial of the configure event. - - For instance, for toplevel surfaces the compositor might use this - information to move a surface to the top left only when the client has - drawn itself for the maximized or fullscreen state. - - If the client receives multiple configure events before it - can respond to one, it only has to ack the last configure event. - - A client is not required to commit immediately after sending - an ack_configure request - it may even ack_configure several times - before its next surface commit. - - A client may send multiple ack_configure requests before committing, but - only the last request sent before a commit indicates which configure - event the client really is responding to. - - - - - - - The configure event marks the end of a configure sequence. A configure - sequence is a set of one or more events configuring the state of the - xdg_surface, including the final xdg_surface.configure event. - - Where applicable, xdg_surface surface roles will during a configure - sequence extend this event as a latched state sent as events before the - xdg_surface.configure event. Such events should be considered to make up - a set of atomically applied configuration states, where the - xdg_surface.configure commits the accumulated state. - - Clients should arrange their surface for the new states, and then send - an ack_configure request with the serial sent in this configure event at - some point before committing the new surface. - - If the client receives multiple configure events before it can respond - to one, it is free to discard all but the last event it received. - - - - - - - - This interface defines an xdg_surface role which allows a surface to, - among other things, set window-like properties such as maximize, - fullscreen, and minimize, set application-specific metadata like title and - id, and well as trigger user interactive operations such as interactive - resize and move. - - - - - Unmap and destroy the window. The window will be effectively - hidden from the user's point of view, and all state like - maximization, fullscreen, and so on, will be lost. - - - - - - Set the "parent" of this surface. This window should be stacked - above a parent. The parent surface must be mapped as long as this - surface is mapped. - - Parent windows should be set on dialogs, toolboxes, or other - "auxiliary" surfaces, so that the parent is raised when the dialog - is raised. - - - - - - - Set a short title for the surface. - - This string may be used to identify the surface in a task bar, - window list, or other user interface elements provided by the - compositor. - - The string must be encoded in UTF-8. - - - - - - - Set an application identifier for the surface. - - The app ID identifies the general class of applications to which - the surface belongs. The compositor can use this to group multiple - surfaces together, or to determine how to launch a new application. - - For D-Bus activatable applications, the app ID is used as the D-Bus - service name. - - The compositor shell will try to group application surfaces together - by their app ID. As a best practice, it is suggested to select app - ID's that match the basename of the application's .desktop file. - For example, "org.freedesktop.FooViewer" where the .desktop file is - "org.freedesktop.FooViewer.desktop". - - See the desktop-entry specification [0] for more details on - application identifiers and how they relate to well-known D-Bus - names and .desktop files. - - [0] http://standards.freedesktop.org/desktop-entry-spec/ - - - - - - - Clients implementing client-side decorations might want to show - a context menu when right-clicking on the decorations, giving the - user a menu that they can use to maximize or minimize the window. - - This request asks the compositor to pop up such a window menu at - the given position, relative to the local surface coordinates of - the parent surface. There are no guarantees as to what menu items - the window menu contains. - - This request must be used in response to some sort of user action - like a button press, key press, or touch down event. - - - - - - - - - - Start an interactive, user-driven move of the surface. - - This request must be used in response to some sort of user action - like a button press, key press, or touch down event. The passed - serial is used to determine the type of interactive move (touch, - pointer, etc). - - The server may ignore move requests depending on the state of - the surface (e.g. fullscreen or maximized), or if the passed serial - is no longer valid. - - If triggered, the surface will lose the focus of the device - (wl_pointer, wl_touch, etc) used for the move. It is up to the - compositor to visually indicate that the move is taking place, such as - updating a pointer cursor, during the move. There is no guarantee - that the device focus will return when the move is completed. - - - - - - - - These values are used to indicate which edge of a surface - is being dragged in a resize operation. - - - - - - - - - - - - - - - Start a user-driven, interactive resize of the surface. - - This request must be used in response to some sort of user action - like a button press, key press, or touch down event. The passed - serial is used to determine the type of interactive resize (touch, - pointer, etc). - - The server may ignore resize requests depending on the state of - the surface (e.g. fullscreen or maximized). - - If triggered, the client will receive configure events with the - "resize" state enum value and the expected sizes. See the "resize" - enum value for more details about what is required. The client - must also acknowledge configure events using "ack_configure". After - the resize is completed, the client will receive another "configure" - event without the resize state. - - If triggered, the surface also will lose the focus of the device - (wl_pointer, wl_touch, etc) used for the resize. It is up to the - compositor to visually indicate that the resize is taking place, - such as updating a pointer cursor, during the resize. There is no - guarantee that the device focus will return when the resize is - completed. - - The edges parameter specifies how the surface should be resized, - and is one of the values of the resize_edge enum. The compositor - may use this information to update the surface position for - example when dragging the top left corner. The compositor may also - use this information to adapt its behavior, e.g. choose an - appropriate cursor image. - - - - - - - - - The different state values used on the surface. This is designed for - state values like maximized, fullscreen. It is paired with the - configure event to ensure that both the client and the compositor - setting the state can be synchronized. - - States set in this way are double-buffered. They will get applied on - the next commit. - - - - The surface is maximized. The window geometry specified in the configure - event must be obeyed by the client. - - - - - The surface is fullscreen. The window geometry specified in the configure - event must be obeyed by the client. - - - - - The surface is being resized. The window geometry specified in the - configure event is a maximum; the client cannot resize beyond it. - Clients that have aspect ratio or cell sizing configuration can use - a smaller size, however. - - - - - Client window decorations should be painted as if the window is - active. Do not assume this means that the window actually has - keyboard or pointer focus. - - - - - - - Set a maximum size for the window. - - The client can specify a maximum size so that the compositor does - not try to configure the window beyond this size. - - The width and height arguments are in window geometry coordinates. - See xdg_surface.set_window_geometry. - - Values set in this way are double-buffered. They will get applied - on the next commit. - - The compositor can use this information to allow or disallow - different states like maximize or fullscreen and draw accurate - animations. - - Similarly, a tiling window manager may use this information to - place and resize client windows in a more effective way. - - The client should not rely on the compositor to obey the maximum - size. The compositor may decide to ignore the values set by the - client and request a larger size. - - If never set, or a value of zero in the request, means that the - client has no expected maximum size in the given dimension. - As a result, a client wishing to reset the maximum size - to an unspecified state can use zero for width and height in the - request. - - Requesting a maximum size to be smaller than the minimum size of - a surface is illegal and will result in a protocol error. - - The width and height must be greater than or equal to zero. Using - strictly negative values for width and height will result in a - protocol error. - - - - - - - - Set a minimum size for the window. - - The client can specify a minimum size so that the compositor does - not try to configure the window below this size. - - The width and height arguments are in window geometry coordinates. - See xdg_surface.set_window_geometry. - - Values set in this way are double-buffered. They will get applied - on the next commit. - - The compositor can use this information to allow or disallow - different states like maximize or fullscreen and draw accurate - animations. - - Similarly, a tiling window manager may use this information to - place and resize client windows in a more effective way. - - The client should not rely on the compositor to obey the minimum - size. The compositor may decide to ignore the values set by the - client and request a smaller size. - - If never set, or a value of zero in the request, means that the - client has no expected minimum size in the given dimension. - As a result, a client wishing to reset the minimum size - to an unspecified state can use zero for width and height in the - request. - - Requesting a minimum size to be larger than the maximum size of - a surface is illegal and will result in a protocol error. - - The width and height must be greater than or equal to zero. Using - strictly negative values for width and height will result in a - protocol error. - - - - - - - - Maximize the surface. - - After requesting that the surface should be maximized, the compositor - will respond by emitting a configure event with the "maximized" state - and the required window geometry. The client should then update its - content, drawing it in a maximized state, i.e. without shadow or other - decoration outside of the window geometry. The client must also - acknowledge the configure when committing the new content (see - ack_configure). - - It is up to the compositor to decide how and where to maximize the - surface, for example which output and what region of the screen should - be used. - - If the surface was already maximized, the compositor will still emit - a configure event with the "maximized" state. - - - - - - Unmaximize the surface. - - After requesting that the surface should be unmaximized, the compositor - will respond by emitting a configure event without the "maximized" - state. If available, the compositor will include the window geometry - dimensions the window had prior to being maximized in the configure - request. The client must then update its content, drawing it in a - regular state, i.e. potentially with shadow, etc. The client must also - acknowledge the configure when committing the new content (see - ack_configure). - - It is up to the compositor to position the surface after it was - unmaximized; usually the position the surface had before maximizing, if - applicable. - - If the surface was already not maximized, the compositor will still - emit a configure event without the "maximized" state. - - - - - - Make the surface fullscreen. - - You can specify an output that you would prefer to be fullscreen. - If this value is NULL, it's up to the compositor to choose which - display will be used to map this surface. - - If the surface doesn't cover the whole output, the compositor will - position the surface in the center of the output and compensate with - black borders filling the rest of the output. - - - - - - - - Request that the compositor minimize your surface. There is no - way to know if the surface is currently minimized, nor is there - any way to unset minimization on this surface. - - If you are looking to throttle redrawing when minimized, please - instead use the wl_surface.frame event for this, as this will - also work with live previews on windows in Alt-Tab, Expose or - similar compositor features. - - - - - - This configure event asks the client to resize its toplevel surface or - to change its state. The configured state should not be applied - immediately. See xdg_surface.configure for details. - - The width and height arguments specify a hint to the window - about how its surface should be resized in window geometry - coordinates. See set_window_geometry. - - If the width or height arguments are zero, it means the client - should decide its own window dimension. This may happen when the - compositor needs to configure the state of the surface but doesn't - have any information about any previous or expected dimension. - - The states listed in the event specify how the width/height - arguments should be interpreted, and possibly how it should be - drawn. - - Clients must send an ack_configure in response to this event. See - xdg_surface.configure and xdg_surface.ack_configure for details. - - - - - - - - - The close event is sent by the compositor when the user - wants the surface to be closed. This should be equivalent to - the user clicking the close button in client-side decorations, - if your application has any. - - This is only a request that the user intends to close the - window. The client may choose to ignore this request, or show - a dialog to ask the user to save their data, etc. - - - - - - - A popup surface is a short-lived, temporary surface. It can be used to - implement for example menus, popovers, tooltips and other similar user - interface concepts. - - A popup can be made to take an explicit grab. See xdg_popup.grab for - details. - - When the popup is dismissed, a popup_done event will be sent out, and at - the same time the surface will be unmapped. See the xdg_popup.popup_done - event for details. - - Explicitly destroying the xdg_popup object will also dismiss the popup and - unmap the surface. Clients that want to dismiss the popup when another - surface of their own is clicked should dismiss the popup using the destroy - request. - - The parent surface must have either the xdg_toplevel or xdg_popup surface - role. - - A newly created xdg_popup will be stacked on top of all previously created - xdg_popup surfaces associated with the same xdg_toplevel. - - The parent of an xdg_popup must be mapped (see the xdg_surface - description) before the xdg_popup itself. - - The x and y arguments passed when creating the popup object specify - where the top left of the popup should be placed, relative to the - local surface coordinates of the parent surface. See - xdg_surface.get_popup. An xdg_popup must intersect with or be at least - partially adjacent to its parent surface. - - The client must call wl_surface.commit on the corresponding wl_surface - for the xdg_popup state to take effect. - - - - - - - - - This destroys the popup. Explicitly destroying the xdg_popup - object will also dismiss the popup, and unmap the surface. - - If this xdg_popup is not the "topmost" popup, a protocol error - will be sent. - - - - - - This request makes the created popup take an explicit grab. An explicit - grab will be dismissed when the user dismisses the popup, or when the - client destroys the xdg_popup. This can be done by the user clicking - outside the surface, using the keyboard, or even locking the screen - through closing the lid or a timeout. - - If the compositor denies the grab, the popup will be immediately - dismissed. - - This request must be used in response to some sort of user action like a - button press, key press, or touch down event. The serial number of the - event should be passed as 'serial'. - - The parent of a grabbing popup must either be an xdg_toplevel surface or - another xdg_popup with an explicit grab. If the parent is another - xdg_popup it means that the popups are nested, with this popup now being - the topmost popup. - - Nested popups must be destroyed in the reverse order they were created - in, e.g. the only popup you are allowed to destroy at all times is the - topmost one. - - When compositors choose to dismiss a popup, they may dismiss every - nested grabbing popup as well. When a compositor dismisses popups, it - will follow the same dismissing order as required from the client. - - The parent of a grabbing popup must either be another xdg_popup with an - active explicit grab, or an xdg_popup or xdg_toplevel, if there are no - explicit grabs already taken. - - If the topmost grabbing popup is destroyed, the grab will be returned to - the parent of the popup, if that parent previously had an explicit grab. - - If the parent is a grabbing popup which has already been dismissed, this - popup will be immediately dismissed. If the parent is a popup that did - not take an explicit grab, an error will be raised. - - During a popup grab, the client owning the grab will receive pointer - and touch events for all their surfaces as normal (similar to an - "owner-events" grab in X11 parlance), while the top most grabbing popup - will always have keyboard focus. - - - - - - - - This event asks the popup surface to configure itself given the - configuration. The configured state should not be applied immediately. - See xdg_surface.configure for details. - - The x and y arguments represent the position the popup was placed at - given the xdg_positioner rule, relative to the upper left corner of the - window geometry of the parent surface. - - - - - - - - - - The popup_done event is sent out when a popup is dismissed by the - compositor. The client should destroy the xdg_popup object at this - point. - - - - - diff --git a/SDL2-2.0.12/Android.mk b/SDL2-2.30.5/Android.mk similarity index 86% rename from SDL2-2.0.12/Android.mk rename to SDL2-2.30.5/Android.mk index 6424655..9c9a160 100644 --- a/SDL2-2.0.12/Android.mk +++ b/SDL2-2.30.5/Android.mk @@ -20,6 +20,7 @@ LOCAL_SRC_FILES := \ $(wildcard $(LOCAL_PATH)/src/audio/*.c) \ $(wildcard $(LOCAL_PATH)/src/audio/android/*.c) \ $(wildcard $(LOCAL_PATH)/src/audio/dummy/*.c) \ + $(wildcard $(LOCAL_PATH)/src/audio/aaudio/*.c) \ $(wildcard $(LOCAL_PATH)/src/audio/openslES/*.c) \ $(LOCAL_PATH)/src/atomic/SDL_atomic.c.arm \ $(LOCAL_PATH)/src/atomic/SDL_spinlock.c.arm \ @@ -30,10 +31,17 @@ LOCAL_SRC_FILES := \ $(wildcard $(LOCAL_PATH)/src/file/*.c) \ $(wildcard $(LOCAL_PATH)/src/haptic/*.c) \ $(wildcard $(LOCAL_PATH)/src/haptic/android/*.c) \ + $(wildcard $(LOCAL_PATH)/src/hidapi/*.c) \ + $(wildcard $(LOCAL_PATH)/src/hidapi/android/*.cpp) \ $(wildcard $(LOCAL_PATH)/src/joystick/*.c) \ $(wildcard $(LOCAL_PATH)/src/joystick/android/*.c) \ $(wildcard $(LOCAL_PATH)/src/joystick/hidapi/*.c) \ + $(wildcard $(LOCAL_PATH)/src/joystick/virtual/*.c) \ $(wildcard $(LOCAL_PATH)/src/loadso/dlopen/*.c) \ + $(wildcard $(LOCAL_PATH)/src/locale/*.c) \ + $(wildcard $(LOCAL_PATH)/src/locale/android/*.c) \ + $(wildcard $(LOCAL_PATH)/src/misc/*.c) \ + $(wildcard $(LOCAL_PATH)/src/misc/android/*.c) \ $(wildcard $(LOCAL_PATH)/src/power/*.c) \ $(wildcard $(LOCAL_PATH)/src/power/android/*.c) \ $(wildcard $(LOCAL_PATH)/src/filesystem/android/*.c) \ @@ -51,13 +59,10 @@ LOCAL_SRC_FILES := \ $(wildcard $(LOCAL_PATH)/src/video/yuv2rgb/*.c) \ $(wildcard $(LOCAL_PATH)/src/test/*.c)) -LOCAL_SHARED_LIBRARIES := hidapi - LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES LOCAL_CFLAGS += \ -Wall -Wextra \ -Wdocumentation \ - -Wdocumentation-unknown-command \ -Wmissing-prototypes \ -Wunreachable-code-break \ -Wunneeded-internal-declaration \ @@ -69,13 +74,15 @@ LOCAL_CFLAGS += \ -Wstrict-prototypes \ -Wkeyword-macro \ - # Warnings we haven't fixed (yet) LOCAL_CFLAGS += -Wno-unused-parameter -Wno-sign-compare - + +LOCAL_CXXFLAGS += -std=gnu++11 LOCAL_LDLIBS := -ldl -lGLESv1_CM -lGLESv2 -lOpenSLES -llog -landroid +LOCAL_LDFLAGS := -Wl,--no-undefined + ifeq ($(NDK_DEBUG),1) cmd-strip := endif @@ -84,6 +91,7 @@ LOCAL_STATIC_LIBRARIES := cpufeatures include $(BUILD_SHARED_LIBRARY) + ########################### # # SDL static library @@ -94,11 +102,15 @@ LOCAL_MODULE := SDL2_static LOCAL_MODULE_FILENAME := libSDL2 -LOCAL_LDLIBS := +LOCAL_LDLIBS := + +LOCAL_LDFLAGS := + LOCAL_EXPORT_LDLIBS := -ldl -lGLESv1_CM -lGLESv2 -llog -landroid include $(BUILD_STATIC_LIBRARY) + ########################### # # SDL main static library @@ -115,22 +127,4 @@ LOCAL_MODULE_FILENAME := libSDL2main include $(BUILD_STATIC_LIBRARY) -########################### -# -# hidapi library -# -########################### - -include $(CLEAR_VARS) - -LOCAL_CPPFLAGS += -std=c++11 - -LOCAL_SRC_FILES := src/hidapi/android/hid.cpp - -LOCAL_MODULE := libhidapi -LOCAL_LDLIBS := -llog - -include $(BUILD_SHARED_LIBRARY) - $(call import-module,android/cpufeatures) - diff --git a/SDL2-2.0.12/BUGS.txt b/SDL2-2.30.5/BUGS.txt similarity index 58% rename from SDL2-2.0.12/BUGS.txt rename to SDL2-2.30.5/BUGS.txt index 57d953f..eb973d5 100644 --- a/SDL2-2.0.12/BUGS.txt +++ b/SDL2-2.30.5/BUGS.txt @@ -1,7 +1,7 @@ -Bugs are now managed in the SDL bug tracker, here: +Bugs are now managed in the SDL issue tracker, here: - https://bugzilla.libsdl.org/ + https://github.com/libsdl-org/SDL/issues You may report bugs there, and search to see if a given issue has already been reported, discussed, and maybe even fixed. @@ -11,6 +11,6 @@ You may also find help at the SDL forums/mailing list: https://discourse.libsdl.org/ -Bug reports are welcome here, but we really appreciate if you use Bugzilla, as - bugs discussed on the mailing list may be forgotten or missed. +Bug reports are welcome here, but we really appreciate if you use the issue + tracker, as bugs discussed on the mailing list may be forgotten or missed. diff --git a/SDL2-2.30.5/CMakeLists.txt b/SDL2-2.30.5/CMakeLists.txt new file mode 100644 index 0000000..47b3dca --- /dev/null +++ b/SDL2-2.30.5/CMakeLists.txt @@ -0,0 +1,3717 @@ +if(${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_BINARY_DIR}) + message(FATAL_ERROR "Prevented in-tree build. Please create a build directory outside of the SDL source code and run \"cmake -S ${CMAKE_SOURCE_DIR} -B .\" from there") +endif() + +# MSVC runtime library flags are selected by an abstraction. +set(CMAKE_POLICY_DEFAULT_CMP0091 NEW) + +cmake_minimum_required(VERSION 3.0.0...3.5) +project(SDL2 C CXX) + +if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR) + set(SDL2_SUBPROJECT OFF) +else() + set(SDL2_SUBPROJECT ON) +endif() + +if (HAIKU) + set(LINKER_LANGUAGE CXX) +endif() + +set(EXTRA_LIBS) +set(EXTRA_LDFLAGS) + +set(CMAKE_DEPENDS) +set(PKGCONFIG_DEPENDS) + +# This is a virtual "library" that just exists to collect up compiler and +# linker options that used to be global to this CMake project. When you +# specify it as part of a real library's target_link_libraries(), that +# library will also gain all those build options too. This is meant to +# modularize old calls to the global add_definitions and include_directories, +# etc. See https://github.com/libsdl-org/SDL/issues/4150 +add_library(sdl-build-options INTERFACE) + +if(WINDOWS_STORE) + target_compile_definitions(sdl-build-options INTERFACE "-DSDL_BUILDING_WINRT=1") + target_compile_options(sdl-build-options INTERFACE "-ZW") +endif() + +# CMake 3.0 expands the "if(${A})" in "set(OFF 1);set(A OFF);if(${A})" to "if(1)" +# CMake 3.24+ emits a warning when not set. +unset(OFF) +unset(ON) +if(POLICY CMP0054) + cmake_policy(SET CMP0054 NEW) +endif() + +# !!! FIXME: this should probably do "MACOSX_RPATH ON" as a target property +# !!! FIXME: for the SDL2 shared library (so you get an +# !!! FIXME: install_name ("soname") of "@rpath/libSDL-whatever.dylib" +# !!! FIXME: instead of "/usr/local/lib/libSDL-whatever.dylib"), but I'm +# !!! FIXME: punting for now and leaving the existing behavior. Until this +# !!! FIXME: properly resolved, this line silences a warning in CMake 3.0+. +# !!! FIXME: remove it and this comment entirely once the problem is +# !!! FIXME: properly resolved. +#cmake_policy(SET CMP0042 OLD) + +include(CheckLibraryExists) +include(CheckIncludeFiles) +include(CheckIncludeFile) +include(CheckLanguage) +include(CheckSymbolExists) +include(CheckCSourceCompiles) +include(CheckCSourceRuns) +include(CheckCCompilerFlag) +include(CheckCXXCompilerFlag) +include(CheckStructHasMember) +include(CMakeDependentOption) +include(CMakePushCheckState) +include(GNUInstallDirs) + +find_package(PkgConfig) + +list(APPEND CMAKE_MODULE_PATH "${SDL2_SOURCE_DIR}/cmake") +include(${SDL2_SOURCE_DIR}/cmake/macros.cmake) +include(${SDL2_SOURCE_DIR}/cmake/sdlchecks.cmake) +include(${SDL2_SOURCE_DIR}/cmake/sdlplatform.cmake) +include(${SDL2_SOURCE_DIR}/cmake/CheckCPUArchitecture.cmake) + +# Enable large file support on 32-bit glibc, so that we can access files +# with large inode numbers +check_symbol_exists("__GLIBC__" "stdlib.h" LIBC_IS_GLIBC) +if (LIBC_IS_GLIBC AND CMAKE_SIZEOF_VOID_P EQUAL 4) + add_definitions(-D_FILE_OFFSET_BITS=64) +endif() + +# See docs/release_checklist.md +set(SDL_MAJOR_VERSION 2) +set(SDL_MINOR_VERSION 30) +set(SDL_MICRO_VERSION 5) +set(SDL_VERSION "${SDL_MAJOR_VERSION}.${SDL_MINOR_VERSION}.${SDL_MICRO_VERSION}") + +# Set defaults preventing destination file conflicts +set(SDL_CMAKE_DEBUG_POSTFIX "d" + CACHE STRING "Name suffix for debug builds") + +mark_as_advanced(CMAKE_IMPORT_LIBRARY_SUFFIX SDL_CMAKE_DEBUG_POSTFIX) + +# Calculate a libtool-like version number +math(EXPR SDL_BINARY_AGE "${SDL_MINOR_VERSION} * 100 + ${SDL_MICRO_VERSION}") +if(SDL_MINOR_VERSION MATCHES "[02468]$") + # Stable branch, 2.24.1 -> libSDL2-2.0.so.0.2400.1 + set(SDL_INTERFACE_AGE ${SDL_MICRO_VERSION}) +else() + # Development branch, 2.23.1 -> libSDL2-2.0.so.0.2301.0 + set(SDL_INTERFACE_AGE 0) +endif() + +# Increment this if there is an incompatible change - but if that happens, +# we should rename the library from SDL2 to SDL3, at which point this would +# reset to 0 anyway. +set(LT_MAJOR "0") + +math(EXPR LT_AGE "${SDL_BINARY_AGE} - ${SDL_INTERFACE_AGE}") +math(EXPR LT_CURRENT "${LT_MAJOR} + ${LT_AGE}") +set(LT_REVISION "${SDL_INTERFACE_AGE}") +# For historical reasons, the library name redundantly includes the major +# version twice: libSDL2-2.0.so.0. +# TODO: in SDL 3, set the OUTPUT_NAME to plain SDL3, which will simplify +# it to libSDL3.so.0 +set(LT_RELEASE "2.0") +set(LT_VERSION "${LT_MAJOR}.${LT_AGE}.${LT_REVISION}") + +# The following should match the versions in the Xcode project file. +# Each version is 1 higher than you might expect, for compatibility +# with libtool: macOS ABI versioning is 1-based, unlike other platforms +# which are normally 0-based. +math(EXPR DYLIB_CURRENT_VERSION_MAJOR "${LT_MAJOR} + ${LT_AGE} + 1") +math(EXPR DYLIB_CURRENT_VERSION_MINOR "${LT_REVISION}") +set(DYLIB_CURRENT_VERSION "${DYLIB_CURRENT_VERSION_MAJOR}.${DYLIB_CURRENT_VERSION_MINOR}.0") +set(DYLIB_COMPATIBILITY_VERSION "${DYLIB_CURRENT_VERSION_MAJOR}.0.0") + +# This list holds all generated headers. +# To avoid generating them twice, these are added to a dummy target on which all sdl targets depend. +set(SDL_GENERATED_HEADERS) + +#message(STATUS "${LT_VERSION} :: ${LT_AGE} :: ${LT_REVISION} :: ${LT_CURRENT} :: ${LT_RELEASE}") + +check_cpu_architecture(x86 SDL_CPU_X86) +check_cpu_architecture(x64 SDL_CPU_X64) +check_cpu_architecture(arm32 SDL_CPU_ARM32) +check_cpu_architecture(arm64 SDL_CPU_ARM64) +check_cpu_architecture(loongarch64 SDL_CPU_LOONGARCH64) + +# Check for 64 or 32 bit +set(SIZEOF_VOIDP ${CMAKE_SIZEOF_VOID_P}) +if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(ARCH_64 TRUE) + set(PROCESSOR_ARCH "x64") +else() + set(ARCH_64 FALSE) + set(PROCESSOR_ARCH "x86") +endif() +set(LIBNAME SDL2) +if(NOT LIBTYPE) + set(LIBTYPE SHARED) +endif() + +# Get the platform +SDL_DetectCMakePlatform() + +# Don't mistake osx for unix +if(UNIX AND NOT ANDROID AND NOT APPLE AND NOT RISCOS) + set(UNIX_SYS ON) +else() + set(UNIX_SYS OFF) +endif() + +if(UNIX OR APPLE) + set(UNIX_OR_MAC_SYS ON) +else() + set(UNIX_OR_MAC_SYS OFF) +endif() + +# Emscripten pthreads work, but you need to have a non-pthread fallback build +# for systems without support. It's not currently enough to not use +# pthread functions in a pthread-build; it won't start up on unsupported +# browsers. As such, you have to explicitly enable it on Emscripten builds +# for the time being. This default with change to ON once this becomes +# commonly supported in browsers or the Emscripten teams makes a single +# binary work everywhere. +if (UNIX_OR_MAC_SYS AND NOT EMSCRIPTEN) + set(SDL_PTHREADS_ENABLED_BY_DEFAULT ON) +else() + set(SDL_PTHREADS_ENABLED_BY_DEFAULT OFF) +endif() + +if(UNIX_SYS OR ANDROID) + set(SDL_CLOCK_GETTIME_ENABLED_BY_DEFAULT ON) +else() + set(SDL_CLOCK_GETTIME_ENABLED_BY_DEFAULT OFF) +endif() + +# The hidraw support doesn't catch Xbox, PS4 and Nintendo controllers, +# so we'll just use libusb when it's available. libusb does not support iOS, +# so we default to yes on iOS. +# TODO: Windows can support libusb, the hid.c file just depends on Unix APIs +if((WINDOWS AND NOT WINDOWS_STORE) OR IOS OR TVOS OR ANDROID) + set(HIDAPI_SKIP_LIBUSB TRUE) +else() + set(HIDAPI_SKIP_LIBUSB FALSE) +endif() + +# On the other hand, *BSD specifically uses libusb only, so we make a special +# case just for them. +if(FREEBSD OR NETBSD OR OPENBSD OR BSDI) + set(HIDAPI_ONLY_LIBUSB TRUE) +else() + set(HIDAPI_ONLY_LIBUSB FALSE) +endif() + +# Compiler info +if(CMAKE_C_COMPILER_ID MATCHES "Clang|IntelLLVM") + set(USE_CLANG TRUE) + set(OPT_DEF_ASM TRUE) + # Visual Studio 2019 v16.2 added support for Clang/LLVM. + # Check if a Visual Studio project is being generated with the Clang toolset. + if(MSVC) + set(MSVC_CLANG TRUE) + endif() +elseif(CMAKE_COMPILER_IS_GNUCC) + set(USE_GCC TRUE) + set(OPT_DEF_ASM TRUE) +elseif(MSVC_VERSION GREATER 1400) # VisualStudio 8.0+ + set(OPT_DEF_ASM TRUE) + #set(CMAKE_C_FLAGS "/ZI /WX- / +elseif(CMAKE_C_COMPILER_ID MATCHES "^Intel$") + set(OPT_DEF_ASM TRUE) + set(USE_INTELCC TRUE) +elseif(CMAKE_C_COMPILER_ID MATCHES "QCC") + set(USE_QCC TRUE) +else() + set(OPT_DEF_ASM FALSE) +endif() + +if(USE_GCC OR USE_CLANG OR USE_INTELCC OR USE_QCC) + set(OPT_DEF_GCC_ATOMICS ON) +endif() + +# Default option knobs +if(UNIX OR MINGW OR MSYS OR (USE_CLANG AND NOT WINDOWS) OR VITA OR PSP OR PS2 OR N3DS) + set(OPT_DEF_LIBC ON) +endif() +if(WINDOWS OR DARWIN OR MACOSX OR IOS OR TVOS) + set(SDL_SYSTEM_ICONV_DEFAULT OFF) +else() + set(SDL_SYSTEM_ICONV_DEFAULT ON) +endif() + +if(NOT ("$ENV{CFLAGS}" STREQUAL "")) + if(CMAKE_VERSION VERSION_LESS 3.11.0) + message(WARNING "SDL's CMakeLists.txt no longer checks the CFLAGS environment.") + message(WARNING "Please use CMake's CMAKE_C_FLAGS and CMAKE_BUILD_TYPE variables directly.") + message(WARNING "Or upgrade to CMake >= 3.11.0, which respects the CFLAGS environment var.") + endif() +endif() + +# Build in parallel under Visual Studio. Not enabled by default. +if(MSVC AND NOT USE_CLANG) + target_compile_options(sdl-build-options INTERFACE "/MP") +endif() + +if(MSVC) + option(SDL_FORCE_STATIC_VCRT "Force /MT for static VC runtimes" OFF) + if(SDL_FORCE_STATIC_VCRT) + if(NOT DEFINED CMAKE_MSVC_RUNTIME_LIBRARY) + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") + endif() + foreach(flag_var + CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE + CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO) + if(${flag_var} MATCHES "/MD") + string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}") + endif() + endforeach() + endif() + + if(NOT SDL_LIBC) + # Make sure /RTC1 is disabled, otherwise it will use functions from the CRT + foreach(flag_var + CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE + CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO) + string(REGEX REPLACE "/RTC(su|[1su])" "" ${flag_var} "${${flag_var}}") + endforeach(flag_var) + endif() + + if(MSVC_CLANG) + # clang-cl treats /W4 as '-Wall -Wextra' -- we don't need -Wextra + foreach(flag_var + CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE + CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO) + string(REGEX REPLACE "/W4" "/W3" ${flag_var} "${${flag_var}}") + endforeach(flag_var) + endif() +endif() + +# Those are used for pkg-config and friends, so that the sdl2.pc, sdl2-config, +# etc. are created correctly. +set(SDL_LIBS "-lSDL2") +set(SDL_CFLAGS ) + +# When building shared lib for Windows with MinGW, +# avoid the DLL having a "lib" prefix +if(WINDOWS) + set(CMAKE_SHARED_LIBRARY_PREFIX "") +endif() + +set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -D_GNU_SOURCE=1") + +# Emscripten toolchain has a nonempty default value for this, and the checks +# in this file need to change that, so remember the original value, and +# restore back to that afterwards. For check_function_exists() to work in +# Emscripten, this value must be at its default value. +set(ORIG_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) + +if(CYGWIN) + # We build SDL on cygwin without the UNIX emulation layer + target_include_directories(sdl-build-options INTERFACE "/usr/include/mingw") + set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -mno-cygwin") + check_c_source_compiles("int main(int argc, char **argv) { return 0; }" + HAVE_GCC_NO_CYGWIN) + set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS}) + if(HAVE_GCC_NO_CYGWIN) + list(APPEND EXTRA_LDFLAGS_BUILD "-mno-cygwin") + list(APPEND SDL_LIBS "-mno-cygwin") + endif() + list(APPEND SDL_CFLAGS "-I/usr/include/mingw") +endif() + +# General includes +target_compile_definitions(sdl-build-options INTERFACE "-DUSING_GENERATED_CONFIG_H") +target_include_directories(sdl-build-options BEFORE INTERFACE "${SDL2_BINARY_DIR}/include" "${SDL2_BINARY_DIR}/include-config-$>") +# Note: The clang toolset for Visual Studio does not support the '-idirafter' option. +if(USE_GCC OR (USE_CLANG AND NOT MSVC_CLANG)) + # !!! FIXME: do we _need_ to mess with CMAKE_C_FLAGS here? + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -idirafter \"${SDL2_SOURCE_DIR}/src/video/khronos\"") +else() + target_include_directories(sdl-build-options INTERFACE "${SDL2_SOURCE_DIR}/src/video/khronos") +endif() + +# All these ENABLED_BY_DEFAULT vars will default to ON if not specified, so +# you only need to have a platform override them if they are disabling. +if(EMSCRIPTEN) + # Set up default values for the currently supported set of subsystems: + # Emscripten/Javascript does not have assembly support, a dynamic library + # loading architecture, or low-level CPU inspection. + + # SDL_THREADS_ENABLED_BY_DEFAULT now defaults to ON, but pthread support might be disabled by default. + # !!! FIXME: most of these subsystems should default to ON if there are dummy implementations to be used. + + set(OPT_DEF_ASM FALSE) + set(SDL_SHARED_ENABLED_BY_DEFAULT OFF) + set(SDL_ATOMIC_ENABLED_BY_DEFAULT OFF) + set(SDL_LOADSO_ENABLED_BY_DEFAULT OFF) + set(SDL_CPUINFO_ENABLED_BY_DEFAULT OFF) +endif() + +if(VITA OR PSP OR PS2 OR N3DS) + set(SDL_SHARED_ENABLED_BY_DEFAULT OFF) + set(SDL_LOADSO_ENABLED_BY_DEFAULT OFF) +endif() + +# When defined, respect CMake's BUILD_SHARED_LIBS setting: +set(SDL_STATIC_ENABLED_BY_DEFAULT ON) +if (NOT DEFINED SDL_SHARED_ENABLED_BY_DEFAULT) + # ...unless decided already (as for EMSCRIPTEN) + + set(SDL_SHARED_ENABLED_BY_DEFAULT OFF) + + if (NOT DEFINED BUILD_SHARED_LIBS) + # No preference? Build both, just like the AC/AM configure + set(SDL_SHARED_ENABLED_BY_DEFAULT ON) + + elseif (BUILD_SHARED_LIBS) + # In this case, we assume the user wants a shared lib and don't build + # the static one + set(SDL_SHARED_ENABLED_BY_DEFAULT ON) + set(SDL_STATIC_ENABLED_BY_DEFAULT OFF) + endif() +endif() + +if (NOT DEFINED SDL_TEST_ENABLED_BY_DEFAULT) + set(SDL_TEST_ENABLED_BY_DEFAULT ON) +endif() + +set(LONGESTOPTIONNAME 0) # set_option and friends will change this. + +set(SDL_SUBSYSTEMS + Atomic Audio Video Render Events Joystick Haptic Hidapi Power Threads Timers + File Loadso CPUinfo Filesystem Sensor Locale Misc) +foreach(_SUB ${SDL_SUBSYSTEMS}) + string(TOUPPER ${_SUB} _OPT) + if (NOT DEFINED SDL_${_OPT}_ENABLED_BY_DEFAULT) + set(SDL_${_OPT}_ENABLED_BY_DEFAULT ON) + endif() + option(SDL_${_OPT} "Enable the ${_SUB} subsystem" ${SDL_${_OPT}_ENABLED_BY_DEFAULT}) +endforeach() + +# Allow some projects to be built conditionally. +set_option(SDL2_DISABLE_SDL2MAIN "Disable building/installation of SDL2main" OFF) +set_option(SDL2_DISABLE_INSTALL "Disable installation of SDL2" ${SDL2_SUBPROJECT}) +set_option(SDL2_DISABLE_UNINSTALL "Disable uninstallation of SDL2" OFF) + +option_string(SDL_ASSERTIONS "Enable internal sanity checks (auto/disabled/release/enabled/paranoid)" "auto") +#set_option(SDL_DEPENDENCY_TRACKING "Use gcc -MMD -MT dependency tracking" ON) +set_option(SDL_ASSEMBLY "Enable assembly routines" ${OPT_DEF_ASM}) +dep_option(SDL_SSEMATH "Allow GCC to use SSE floating point math" ON "SDL_ASSEMBLY;SDL_CPU_X86 OR SDL_CPU_X64" OFF) +dep_option(SDL_SSE "Use SSE assembly routines" ON "SDL_ASSEMBLY;SDL_CPU_X86 OR SDL_CPU_X64" OFF) +dep_option(SDL_SSE2 "Use SSE2 assembly routines" ON "SDL_ASSEMBLY;SDL_CPU_X86 OR SDL_CPU_X64" OFF) +dep_option(SDL_SSE3 "Use SSE3 assembly routines" ON "SDL_ASSEMBLY;SDL_CPU_X86 OR SDL_CPU_X64" OFF) +dep_option(SDL_MMX "Use MMX assembly routines" ON "SDL_ASSEMBLY;SDL_CPU_X86 OR SDL_CPU_X64" OFF) +dep_option(SDL_3DNOW "Use 3Dnow! MMX assembly routines" ON "SDL_ASSEMBLY;SDL_CPU_X86 OR SDL_CPU_X64" OFF) +dep_option(SDL_ALTIVEC "Use Altivec assembly routines" ON "SDL_ASSEMBLY" OFF) +dep_option(SDL_ARMSIMD "Use SIMD assembly blitters on ARM" OFF "SDL_ASSEMBLY;SDL_CPU_ARM32" OFF) +dep_option(SDL_ARMNEON "Use NEON assembly blitters on ARM" OFF "SDL_ASSEMBLY;SDL_CPU_ARM32" OFF) +dep_option(SDL_LSX "Use LSX assembly routines" ON "SDL_ASSEMBLY;SDL_CPU_LOONGARCH64" OFF) +dep_option(SDL_LASX "Use LASX assembly routines" ON "SDL_ASSEMBLY;SDL_CPU_LOONGARCH64" OFF) + +set_option(SDL_LIBC "Use the system C library" ${OPT_DEF_LIBC}) +set_option(SDL_GCC_ATOMICS "Use gcc builtin atomics" ${OPT_DEF_GCC_ATOMICS}) +dep_option(SDL_DBUS "Enable D-Bus support" ON ${UNIX_SYS} OFF) +set_option(SDL_DISKAUDIO "Support the disk writer audio driver" ON) +set_option(SDL_DUMMYAUDIO "Support the dummy audio driver" ON) +set_option(SDL_DIRECTFB "Use DirectFB video driver" OFF) +dep_option(SDL_DIRECTFB_SHARED "Dynamically load directfb support" ON "SDL_DIRECTFB" OFF) +set_option(SDL_DUMMYVIDEO "Use dummy video driver" ON) +dep_option(SDL_IBUS "Enable IBus support" ON ${UNIX_SYS} OFF) +set_option(SDL_SYSTEM_ICONV "Use iconv() from system-installed libraries" ${SDL_SYSTEM_ICONV_DEFAULT}) +set_option(SDL_LIBICONV "Prefer iconv() from libiconv, if available, over libc version" OFF) +set_option(SDL_OPENGL "Include OpenGL support" ON) +set_option(SDL_OPENGLES "Include OpenGL ES support" ON) +set_option(SDL_PTHREADS "Use POSIX threads for multi-threading" ${SDL_PTHREADS_ENABLED_BY_DEFAULT}) +dep_option(SDL_PTHREADS_SEM "Use pthread semaphores" ON "SDL_PTHREADS" OFF) +dep_option(SDL_OSS "Support the OSS audio API" ON "UNIX_SYS OR RISCOS" OFF) +set_option(SDL_ALSA "Support the ALSA audio API" ${UNIX_SYS}) +dep_option(SDL_ALSA_SHARED "Dynamically load ALSA audio support" ON "SDL_ALSA" OFF) +set_option(SDL_JACK "Support the JACK audio API" ${UNIX_SYS}) +dep_option(SDL_JACK_SHARED "Dynamically load JACK audio support" ON "SDL_JACK" OFF) +set_option(SDL_ESD "Support the Enlightened Sound Daemon" ${UNIX_SYS}) +dep_option(SDL_ESD_SHARED "Dynamically load ESD audio support" ON "SDL_ESD" OFF) +set_option(SDL_PIPEWIRE "Use Pipewire audio" ${UNIX_SYS}) +dep_option(SDL_PIPEWIRE_SHARED "Dynamically load Pipewire support" ON "SDL_PIPEWIRE" OFF) +set_option(SDL_PULSEAUDIO "Use PulseAudio" ${UNIX_SYS}) +dep_option(SDL_PULSEAUDIO_SHARED "Dynamically load PulseAudio support" ON "SDL_PULSEAUDIO" OFF) +set_option(SDL_ARTS "Support the Analog Real Time Synthesizer" ${UNIX_SYS}) +dep_option(SDL_ARTS_SHARED "Dynamically load aRts audio support" ON "SDL_ARTS" OFF) +set_option(SDL_NAS "Support the NAS audio API" ${UNIX_SYS}) +dep_option(SDL_NAS_SHARED "Dynamically load NAS audio support" ON "SDL_NAS" OFF) +set_option(SDL_SNDIO "Support the sndio audio API" ${UNIX_SYS}) +dep_option(SDL_SNDIO_SHARED "Dynamically load the sndio audio API" ON "SDL_SNDIO" OFF) +set_option(SDL_FUSIONSOUND "Use FusionSound audio driver" OFF) +dep_option(SDL_FUSIONSOUND_SHARED "Dynamically load fusionsound audio support" ON "SDL_FUSIONSOUND" OFF) +set_option(SDL_LIBSAMPLERATE "Use libsamplerate for audio rate conversion" ${UNIX_SYS}) +dep_option(SDL_LIBSAMPLERATE_SHARED "Dynamically load libsamplerate" ON "SDL_LIBSAMPLERATE" OFF) +set_option(SDL_RPATH "Use an rpath when linking SDL" ${UNIX_SYS}) +set_option(SDL_CLOCK_GETTIME "Use clock_gettime() instead of gettimeofday()" ${SDL_CLOCK_GETTIME_ENABLED_BY_DEFAULT}) +set_option(SDL_X11 "Use X11 video driver" ${UNIX_SYS}) +dep_option(SDL_X11_SHARED "Dynamically load X11 support" ON "SDL_X11" OFF) +set(SDL_X11_OPTIONS Xcursor Xdbe XInput Xfixes Xrandr Xscrnsaver XShape) +foreach(_SUB ${SDL_X11_OPTIONS}) + string(TOUPPER "SDL_X11_${_SUB}" _OPT) + dep_option(${_OPT} "Enable ${_SUB} support" ON "SDL_X11" OFF) +endforeach() +set_option(SDL_WAYLAND "Use Wayland video driver" ${UNIX_SYS}) +dep_option(SDL_WAYLAND_SHARED "Dynamically load Wayland support" ON "SDL_WAYLAND" OFF) +dep_option(SDL_WAYLAND_LIBDECOR "Use client-side window decorations on Wayland" ON "SDL_WAYLAND" OFF) +dep_option(SDL_WAYLAND_LIBDECOR_SHARED "Dynamically load libdecor support" ON "SDL_WAYLAND_LIBDECOR;SDL_WAYLAND_SHARED" OFF) +dep_option(SDL_WAYLAND_QT_TOUCH "QtWayland server support for Wayland video driver" ON "SDL_WAYLAND" OFF) +set_option(SDL_RPI "Use Raspberry Pi video driver" ${UNIX_SYS}) +set_option(SDL_COCOA "Use Cocoa video driver" ${APPLE}) +set_option(SDL_DIRECTX "Use DirectX for Windows audio/video" ${WINDOWS}) +set_option(SDL_XINPUT "Use Xinput for Windows" ${WINDOWS}) +set_option(SDL_WASAPI "Use the Windows WASAPI audio driver" ${WINDOWS}) +set_option(SDL_RENDER_D3D "Enable the Direct3D render driver" ${WINDOWS}) +set_option(SDL_RENDER_METAL "Enable the Metal render driver" ${APPLE}) +set_option(SDL_VIVANTE "Use Vivante EGL video driver" ${UNIX_SYS}) +dep_option(SDL_VULKAN "Enable Vulkan support" ON "ANDROID OR APPLE OR LINUX OR WINDOWS" OFF) +set_option(SDL_METAL "Enable Metal support" ${APPLE}) +set_option(SDL_KMSDRM "Use KMS DRM video driver" ${UNIX_SYS}) +dep_option(SDL_KMSDRM_SHARED "Dynamically load KMS DRM support" ON "SDL_KMSDRM" OFF) +set_option(SDL_OFFSCREEN "Use offscreen video driver" ON) +option_string(SDL_BACKGROUNDING_SIGNAL "number to use for magic backgrounding signal or 'OFF'" OFF) +option_string(SDL_FOREGROUNDING_SIGNAL "number to use for magic foregrounding signal or 'OFF'" OFF) +set_option(SDL_HIDAPI "Enable the HIDAPI subsystem" ON) +dep_option(SDL_HIDAPI_LIBUSB "Use libusb for low level joystick drivers" OFF SDL_HIDAPI OFF) +dep_option(SDL_HIDAPI_JOYSTICK "Use HIDAPI for low level joystick drivers" ON SDL_HIDAPI OFF) +dep_option(SDL_VIRTUAL_JOYSTICK "Enable the virtual-joystick driver" ON SDL_HIDAPI OFF) +set_option(SDL_LIBUDEV "Enable libudev support" ON) +set_option(SDL_ASAN "Use AddressSanitizer to detect memory errors" OFF) +option_string(SDL_VENDOR_INFO "Vendor name and/or version to add to SDL_REVISION" "") +set_option(SDL_CCACHE "Use Ccache to speed up build" ON) + +option(SDL_WERROR "Enable -Werror" OFF) + +option(SDL_SHARED "Build a shared version of the library" ${SDL_SHARED_ENABLED_BY_DEFAULT}) +option(SDL_STATIC "Build a static version of the library" ${SDL_STATIC_ENABLED_BY_DEFAULT}) +option(SDL_TEST "Build the SDL2_test library" ${SDL_TEST_ENABLED_BY_DEFAULT}) + +dep_option(SDL_STATIC_PIC "Static version of the library should be built with Position Independent Code" "${CMAKE_POSITION_INDEPENDENT_CODE}" "SDL_STATIC" OFF) +dep_option(SDL_TESTS "Build the test directory" OFF SDL_TEST OFF) +set_option(SDL_INSTALL_TESTS "Install test-cases" OFF) + +set(HAVE_STATIC_PIC "${SDL_STATIC_PIC}") + +if(SDL_HIDAPI) + if(HIDAPI_ONLY_LIBUSB) + set(SDL_HIDAPI_LIBUSB ON CACHE BOOL "" FORCE) + elseif(HIDAPI_SKIP_LIBUSB) + set(SDL_HIDAPI_LIBUSB OFF CACHE BOOL "" FORCE) + endif() +endif() + +if(VITA) + set_option(VIDEO_VITA_PIB "Build with PSVita piglet gles2 support" OFF) + set_option(VIDEO_VITA_PVR "Build with PSVita PVR gles/gles2 support" OFF) +endif() + +# General source files +file(GLOB SOURCE_FILES + ${SDL2_SOURCE_DIR}/src/*.c + ${SDL2_SOURCE_DIR}/src/atomic/*.c + ${SDL2_SOURCE_DIR}/src/audio/*.c + ${SDL2_SOURCE_DIR}/src/cpuinfo/*.c + ${SDL2_SOURCE_DIR}/src/dynapi/*.c + ${SDL2_SOURCE_DIR}/src/events/*.c + ${SDL2_SOURCE_DIR}/src/file/*.c + ${SDL2_SOURCE_DIR}/src/joystick/*.c + ${SDL2_SOURCE_DIR}/src/haptic/*.c + ${SDL2_SOURCE_DIR}/src/hidapi/*.c + ${SDL2_SOURCE_DIR}/src/libm/*.c + ${SDL2_SOURCE_DIR}/src/locale/*.c + ${SDL2_SOURCE_DIR}/src/misc/*.c + ${SDL2_SOURCE_DIR}/src/power/*.c + ${SDL2_SOURCE_DIR}/src/render/*.c + ${SDL2_SOURCE_DIR}/src/render/*/*.c + ${SDL2_SOURCE_DIR}/src/sensor/*.c + ${SDL2_SOURCE_DIR}/src/stdlib/*.c + ${SDL2_SOURCE_DIR}/src/thread/*.c + ${SDL2_SOURCE_DIR}/src/timer/*.c + ${SDL2_SOURCE_DIR}/src/video/*.c + ${SDL2_SOURCE_DIR}/src/video/yuv2rgb/*.c) + +if(USE_INTELCC) + # warning #39: division by zero + # warning #239: floating point underflow + # warning #264: floating-point value does not fit in required floating-point type + set_property(SOURCE "${SDL2_SOURCE_DIR}/src/libm/e_exp.c" APPEND_STRING PROPERTY COMPILE_FLAGS " -wd239 -wd264") + set_property(SOURCE "${SDL2_SOURCE_DIR}/src/libm/e_log.c" APPEND_STRING PROPERTY COMPILE_FLAGS " -wd39") + set_property(SOURCE "${SDL2_SOURCE_DIR}/src/libm/e_log10.c" APPEND_STRING PROPERTY COMPILE_FLAGS " -wd39") +endif() + + +set(SDL_DEFAULT_ASSERT_LEVEL_CONFIGURED 1) +if(SDL_ASSERTIONS MATCHES "^(auto|)$") + # Do nada - use optimization settings to determine the assertion level + set(SDL_DEFAULT_ASSERT_LEVEL ) + set(SDL_DEFAULT_ASSERT_LEVEL_CONFIGURED 0) +elseif(SDL_ASSERTIONS MATCHES "^(disabled|0)$") + set(SDL_DEFAULT_ASSERT_LEVEL 0) +elseif(SDL_ASSERTIONS MATCHES "^(release|1)$") + set(SDL_DEFAULT_ASSERT_LEVEL 1) +elseif(SDL_ASSERTIONS MATCHES "^(enabled|2)$") + set(SDL_DEFAULT_ASSERT_LEVEL 2) +elseif(SDL_ASSERTIONS MATCHES "^(paranoid|3)$") + set(SDL_DEFAULT_ASSERT_LEVEL 3) +else() + message_error("unknown assertion level") +endif() +set(HAVE_ASSERTIONS ${SDL_ASSERTIONS}) + +if(NOT SDL_BACKGROUNDING_SIGNAL STREQUAL "OFF") + target_compile_definitions(sdl-build-options INTERFACE "-DSDL_BACKGROUNDING_SIGNAL=${SDL_BACKGROUNDING_SIGNAL}") +endif() + +if(NOT SDL_FOREGROUNDING_SIGNAL STREQUAL "OFF") + target_compile_definitions(sdl-build-options INTERFACE "-DSDL_FOREGROUNDING_SIGNAL=${SDL_FOREGROUNDING_SIGNAL}") +endif() + +# Compiler option evaluation +if(USE_GCC OR USE_CLANG OR USE_INTELCC OR USE_QCC) + # Check for -Wall first, so later things can override pieces of it. + # Note: clang-cl treats -Wall as -Weverything (which is very loud), + # /W3 as -Wall, and /W4 as -Wall -Wextra. So: /W3 is enough. + check_c_compiler_flag(-Wall HAVE_GCC_WALL) + if(MSVC_CLANG) + list(APPEND EXTRA_CFLAGS "/W3") + elseif(HAVE_GCC_WALL) + list(APPEND EXTRA_CFLAGS "-Wall") + if(HAIKU) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-multichar") + endif() + endif() + + check_c_compiler_flag(-Wundef HAVE_GCC_WUNDEF) + if(HAVE_GCC_WUNDEF) + list(APPEND EXTRA_CFLAGS "-Wundef") + endif() + + check_c_compiler_flag(-fno-strict-aliasing HAVE_GCC_NO_STRICT_ALIASING) + if(HAVE_GCC_NO_STRICT_ALIASING) + list(APPEND EXTRA_CFLAGS "-fno-strict-aliasing") + endif() + + check_c_compiler_flag(-Wdocumentation HAVE_GCC_WDOCUMENTATION) + if(HAVE_GCC_WDOCUMENTATION) + if(SDL_WERROR) + check_c_compiler_flag(-Werror=documentation HAVE_GCC_WERROR_DOCUMENTATION) + if(HAVE_GCC_WERROR_DOCUMENTATION) + list(APPEND EXTRA_CFLAGS "-Werror=documentation") + endif() + endif() + list(APPEND EXTRA_CFLAGS "-Wdocumentation") + endif() + + check_c_compiler_flag(-Wdocumentation-unknown-command HAVE_GCC_WDOCUMENTATION_UNKNOWN_COMMAND) + if(HAVE_GCC_WDOCUMENTATION_UNKNOWN_COMMAND) + if(SDL_WERROR) + check_c_compiler_flag(-Werror=documentation-unknown-command HAVE_GCC_WERROR_DOCUMENTATION_UNKNOWN_COMMAND) + if(HAVE_GCC_WERROR_DOCUMENTATION_UNKNOWN_COMMAND) + list(APPEND EXTRA_CFLAGS "-Werror=documentation-unknown-command") + endif() + endif() + list(APPEND EXTRA_CFLAGS "-Wdocumentation-unknown-command") + endif() + + check_c_compiler_flag(-fcomment-block-commands=threadsafety HAVE_GCC_COMMENT_BLOCK_COMMANDS) + if(HAVE_GCC_COMMENT_BLOCK_COMMANDS) + list(APPEND EXTRA_CFLAGS "-fcomment-block-commands=threadsafety") + list(APPEND EXTRA_CFLAGS "-fcomment-block-commands=deprecated") + else() + check_c_compiler_flag(/clang:-fcomment-block-commands=threadsafety HAVE_CLANG_COMMENT_BLOCK_COMMANDS) + if(HAVE_CLANG_COMMENT_BLOCK_COMMANDS) + list(APPEND EXTRA_CFLAGS "/clang:-fcomment-block-commands=threadsafety") + list(APPEND EXTRA_CFLAGS "/clang:-fcomment-block-commands=deprecated") + endif() + endif() + + check_c_compiler_flag(-Wdeclaration-after-statement HAVE_GCC_WDECLARATION_AFTER_STATEMENT) + if(HAVE_GCC_WDECLARATION_AFTER_STATEMENT) + if(SDL_WERROR) + check_c_compiler_flag(-Werror=declaration-after-statement HAVE_GCC_WERROR_DECLARATION_AFTER_STATEMENT) + if(HAVE_GCC_WERROR_DECLARATION_AFTER_STATEMENT) + list(APPEND EXTRA_CFLAGS "-Werror=declaration-after-statement") + endif() + endif() + list(APPEND EXTRA_CFLAGS "-Wdeclaration-after-statement") + endif() + + if(DEPENDENCY_TRACKING) + check_c_source_compiles(" + #if !defined(__GNUC__) || __GNUC__ < 3 + #error Dependency tracking requires GCC 3.0 or newer + #endif + int main(int argc, char **argv) { return 0; }" HAVE_DEPENDENCY_TRACKING) + endif() + + if(SDL_GCC_ATOMICS) + check_c_source_compiles("int main(int argc, char **argv) { + int a; + void *x, *y, *z; + __sync_lock_test_and_set(&a, 4); + __sync_lock_test_and_set(&x, y); + __sync_fetch_and_add(&a, 1); + __sync_bool_compare_and_swap(&a, 5, 10); + __sync_bool_compare_and_swap(&x, y, z); + return 0; }" HAVE_GCC_ATOMICS) + if(NOT HAVE_GCC_ATOMICS) + check_c_source_compiles("int main(int argc, char **argv) { + int a; + __sync_lock_test_and_set(&a, 1); + __sync_lock_release(&a); + return 0; }" HAVE_GCC_SYNC_LOCK_TEST_AND_SET) + endif() + endif() + + set(CMAKE_REQUIRED_FLAGS "-fvisibility=hidden -Werror") + check_c_source_compiles(" + #if !defined(__GNUC__) || __GNUC__ < 4 + #error SDL only uses visibility attributes in GCC 4 or newer + #endif + int main(int argc, char **argv) { return 0; }" HAVE_GCC_FVISIBILITY) + if(HAVE_GCC_FVISIBILITY) + list(APPEND EXTRA_CFLAGS "-fvisibility=hidden") + endif() + set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS}) + + check_c_compiler_flag(-Wshadow HAVE_GCC_WSHADOW) + if(HAVE_GCC_WSHADOW) + list(APPEND EXTRA_CFLAGS "-Wshadow") + endif() + + check_c_compiler_flag(-Wunused-local-typedefs HAVE_GCC_WUNUSED_LOCAL_TYPEDEFS) + if(HAVE_GCC_WUNUSED_LOCAL_TYPEDEFS) + list(APPEND EXTRA_CFLAGS "-Wno-unused-local-typedefs") + endif() + + if(APPLE) + cmake_push_check_state(RESET) + # FIXME: don't use deprecated declarations + check_c_compiler_flag(-Wno-error=deprecated-declarations HAVE_WNO_ERROR_DEPRECATED_DECLARATIONS) + if(HAVE_WNO_ERROR_DEPRECATED_DECLARATIONS) + target_compile_options(sdl-build-options INTERFACE "-Wno-error=deprecated-declarations") + endif() + cmake_pop_check_state() + + # FIXME: use generator expression instead of appending to EXTRA_LDFLAGS_BUILD + list(APPEND EXTRA_LDFLAGS_BUILD "-Wl,-compatibility_version,${DYLIB_COMPATIBILITY_VERSION}") + list(APPEND EXTRA_LDFLAGS_BUILD "-Wl,-current_version,${DYLIB_CURRENT_VERSION}") + elseif(NOT OPENBSD) + set(CMAKE_REQUIRED_FLAGS "-Wl,--no-undefined") + check_c_compiler_flag("" HAVE_NO_UNDEFINED) + set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS}) + if(HAVE_NO_UNDEFINED AND NOT (USE_CLANG AND WINDOWS)) + list(APPEND EXTRA_LDFLAGS_BUILD "-Wl,--no-undefined") + endif() + endif() + + if(MINGW) + # See if GCC's -gdwarf-4 is supported + # See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101377 for why this is needed on Windows + cmake_push_check_state(RESET) + check_c_compiler_flag("-gdwarf-4" HAVE_GDWARF_4) + if(HAVE_GDWARF_4) + set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -gdwarf-4") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -gdwarf-4") + endif() + cmake_pop_check_state() + endif() + + # Force color diagnostics when one of these conditions are met + if(DEFINED ENV{CI} OR DEFINED ENV{USE_CCACHE} OR CMAKE_GENERATOR MATCHES Ninja) + if(EMSCRIPTEN OR (USE_GCC AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.9)) + list(APPEND EXTRA_CFLAGS -fdiagnostics-color=always) + elseif(USE_CLANG AND NOT CMAKE_C_COMPILER_ID MATCHES AppleClang) + list(APPEND EXTRA_CFLAGS -fcolor-diagnostics) + endif() + endif() +endif() +if(MSVC) + target_compile_definitions(sdl-build-options INTERFACE "-D_CRT_SECURE_NO_DEPRECATE") + target_compile_definitions(sdl-build-options INTERFACE "-D_CRT_NONSTDC_NO_DEPRECATE") + target_compile_definitions(sdl-build-options INTERFACE "-D_CRT_SECURE_NO_WARNINGS") + + # CET support was added in VS 16.7 + if(MSVC_VERSION GREATER 1926 AND CMAKE_GENERATOR_PLATFORM MATCHES "Win32|x64") + list(APPEND EXTRA_LDFLAGS_BUILD "-CETCOMPAT") + endif() +endif() + +if(CMAKE_C_COMPILER_ID STREQUAL "MSVC") + # Due to a limitation of Microsoft's LTO implementation, LTO must be disabled for memcpy and memset. + # The same applies to various functions normally belonging in the C library (for x86 architecture). + set_property(SOURCE src/stdlib/SDL_mslibc.c APPEND_STRING PROPERTY COMPILE_FLAGS " /GL-") +endif() + +if(SDL_ASSEMBLY) + if(USE_GCC OR USE_CLANG OR USE_INTELCC) + # TODO: Those all seem to be quite GCC specific - needs to be + # reworked for better compiler support + set(HAVE_ASSEMBLY TRUE) + if(SDL_MMX) + set(CMAKE_REQUIRED_FLAGS "-mmmx") + check_c_source_compiles(" + #ifdef __MINGW32__ + #include <_mingw.h> + #ifdef __MINGW64_VERSION_MAJOR + #include + #else + #include + #endif + #else + #include + #endif + #ifndef __MMX__ + #error Assembler CPP flag not enabled + #endif + int main(int argc, char **argv) { return 0; }" HAVE_MMX) + if(HAVE_MMX) + list(APPEND EXTRA_CFLAGS "-mmmx") + endif() + set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS}) + endif() + + if(SDL_3DNOW) + set(CMAKE_REQUIRED_FLAGS "-m3dnow") + check_c_source_compiles(" + #include + #ifndef __3dNOW__ + #error Assembler CPP flag not enabled + #endif + int main(int argc, char **argv) { + void *p = 0; + _m_prefetch(p); + return 0; + }" HAVE_3DNOW) + if(HAVE_3DNOW) + list(APPEND EXTRA_CFLAGS "-m3dnow") + endif() + set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS}) + endif() + + if(SDL_SSE) + set(CMAKE_REQUIRED_FLAGS "-msse") + check_c_source_compiles(" + #ifdef __MINGW32__ + #include <_mingw.h> + #ifdef __MINGW64_VERSION_MAJOR + #include + #else + #include + #endif + #else + #include + #endif + #ifndef __SSE__ + #error Assembler CPP flag not enabled + #endif + int main(int argc, char **argv) { return 0; }" HAVE_SSE) + if(HAVE_SSE) + list(APPEND EXTRA_CFLAGS "-msse") + endif() + set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS}) + endif() + + if(SDL_SSE2) + set(CMAKE_REQUIRED_FLAGS "-msse2") + check_c_source_compiles(" + #ifdef __MINGW32__ + #include <_mingw.h> + #ifdef __MINGW64_VERSION_MAJOR + #include + #else + #include + #endif + #else + #include + #endif + #ifndef __SSE2__ + #error Assembler CPP flag not enabled + #endif + int main(int argc, char **argv) { return 0; }" CPU_SUPPORTS_SSE2) + if(CPU_SUPPORTS_SSE2) + set(HAVE_SSE2 TRUE) + list(APPEND EXTRA_CFLAGS "-msse2") + endif() + set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS}) + endif() + + if(SDL_SSE3) + set(CMAKE_REQUIRED_FLAGS "-msse3") + check_c_source_compiles(" + #ifdef __MINGW32__ + #include <_mingw.h> + #ifdef __MINGW64_VERSION_MAJOR + #include + #else + #include + #endif + #else + #include + #endif + #ifndef __SSE3__ + #error Assembler CPP flag not enabled + #endif + int main(int argc, char **argv) { return 0; }" CPU_SUPPORTS_SSE3) + if(CPU_SUPPORTS_SSE3) + set(HAVE_SSE3 TRUE) + list(APPEND EXTRA_CFLAGS "-msse3") + endif() + set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS}) + endif() + + if(NOT SDL_SSEMATH) + if(SDL_SSE OR SDL_SSE2 OR SDL_SSE3) + if(USE_GCC) + check_c_compiler_flag(-mfpmath=387 HAVE_FP_387) + if(HAVE_FP_387) + list(APPEND EXTRA_CFLAGS "-mfpmath=387") + endif() + endif() + endif() + else() + set(HAVE_SSEMATH TRUE) + endif() + + check_include_file("immintrin.h" HAVE_IMMINTRIN_H) + + if(SDL_ALTIVEC) + set(CMAKE_REQUIRED_FLAGS "-maltivec") + check_c_source_compiles(" + #include + vector unsigned int vzero() { + return vec_splat_u32(0); + } + int main(int argc, char **argv) { return 0; }" HAVE_ALTIVEC_H_HDR) + check_c_source_compiles(" + vector unsigned int vzero() { + return vec_splat_u32(0); + } + int main(int argc, char **argv) { return 0; }" CPU_SUPPORTS_ALTIVEC) + set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS}) + if(CPU_SUPPORTS_ALTIVEC OR HAVE_ALTIVEC_H_HDR) + set(HAVE_ALTIVEC TRUE) # if only HAVE_ALTIVEC_H_HDR is set + list(APPEND EXTRA_CFLAGS "-maltivec") + set(SDL_ALTIVEC_BLITTERS 1) + if(HAVE_ALTIVEC_H_HDR) + set(HAVE_ALTIVEC_H 1) + endif() + endif() + endif() + + if(SDL_LSX) + cmake_push_check_state() + set(CMAKE_REQUIRED_FLAGS "-mlsx") + check_c_source_compiles(" + #ifndef __loongarch_sx + #error Assembler CPP flag not enabled + #endif + int main(int argc, char **argv) { return 0; }" CPU_SUPPORTS_LSX) + check_include_file("lsxintrin.h" HAVE_LSXINTRIN_H) + cmake_pop_check_state() + + if(CPU_SUPPORTS_LSX AND HAVE_LSXINTRIN_H) + list(APPEND EXTRA_CFLAGS "-mlsx") + set(HAVE_LSX TRUE) + endif() + endif() + + if(SDL_ARMSIMD) + set(ORIG_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -x assembler-with-cpp") + check_c_source_compiles(" + .text + .arch armv6 + .object_arch armv4 + .arm + .altmacro + #ifndef __ARM_EABI__ + #error EABI is required (to be sure that calling conventions are compatible) + #endif + pld [r0] + uqadd8 r0, r0, r0 + " ARMSIMD_FOUND) + set(CMAKE_REQUIRED_FLAGS "${ORIG_CMAKE_REQUIRED_FLAGS}") + + if(ARMSIMD_FOUND) + set(HAVE_ARMSIMD TRUE) + set(SDL_ARM_SIMD_BLITTERS 1) + file(GLOB ARMSIMD_SOURCES ${SDL2_SOURCE_DIR}/src/video/arm/pixman-arm-simd*.S) + list(APPEND SOURCE_FILES ${ARMSIMD_SOURCES}) + set(WARN_ABOUT_ARM_SIMD_ASM_MIT TRUE) + endif() + endif() + + if(SDL_ARMNEON) + set(ORIG_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") + set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -x assembler-with-cpp") + check_c_source_compiles(" + .text + .fpu neon + .arch armv7a + .object_arch armv4 + .eabi_attribute 10, 0 + .arm + .altmacro + #ifndef __ARM_EABI__ + #error EABI is required (to be sure that calling conventions are compatible) + #endif + pld [r0] + vmovn.u16 d0, q0 + " ARMNEON_FOUND) + set(CMAKE_REQUIRED_FLAGS "${ORIG_CMAKE_REQUIRED_FLAGS}") + + if(ARMNEON_FOUND) + set(HAVE_ARMNEON TRUE) + set(SDL_ARM_NEON_BLITTERS 1) + file(GLOB ARMNEON_SOURCES ${SDL2_SOURCE_DIR}/src/video/arm/pixman-arm-neon*.S) + list(APPEND SOURCE_FILES ${ARMNEON_SOURCES}) + set(WARN_ABOUT_ARM_NEON_ASM_MIT TRUE) + endif() + endif() + + elseif(MSVC_VERSION GREATER 1500) + # TODO: SDL_cpuinfo.h needs to support the user's configuration wish + # for MSVC - right now it is always activated + if(NOT ARCH_64) + if(SDL_MMX) + set(HAVE_MMX TRUE) + endif() + if(SDL_3DNOW) + set(HAVE_3DNOW TRUE) + endif() + endif() + if(SDL_SSE) + set(HAVE_SSE TRUE) + endif() + if(SDL_SSE2) + set(HAVE_SSE2 TRUE) + endif() + if(SDL_SSE3) + set(HAVE_SSE3 TRUE) + endif() + check_include_file("immintrin.h" HAVE_IMMINTRIN_H) + endif() +endif() + +# TODO: Can't deactivate on FreeBSD? w/o LIBC, SDL_stdinc.h can't define +# anything. +if(SDL_LIBC) + if(WINDOWS AND NOT MINGW) + set(HAVE_LIBC TRUE) + check_include_file(stdint.h HAVE_STDINT_H) + foreach(_HEADER stdio.h string.h wchar.h ctype.h math.h limits.h) + string(TOUPPER "HAVE_${_HEADER}" _UPPER) + string(REPLACE "." "_" _HAVE_H ${_UPPER}) + set(${_HAVE_H} 1) + endforeach() + set(HAVE_SIGNAL_H 1) + foreach(_FN + malloc calloc realloc free bsearch qsort abs memset memcpy memmove memcmp + wcslen _wcsdup wcsdup wcsstr wcscmp wcsncmp _wcsicmp _wcsnicmp + strlen _strrev _strupr _strlwr strchr strrchr strstr itoa _ltoa + _ultoa strtol strtoul strtoll strtod atoi atof strcmp strncmp + _stricmp _strnicmp sscanf + acos acosf asin asinf atan atanf atan2 atan2f ceil ceilf + copysign copysignf cos cosf exp expf fabs fabsf floor floorf fmod fmodf + log logf log10 log10f lround lroundf pow powf round roundf scalbn scalbnf + sin sinf sqrt sqrtf tan tanf trunc truncf) + string(TOUPPER ${_FN} _UPPER) + set(HAVE_${_UPPER} 1) + endforeach() + set(HAVE_ALLOCA 1) + check_symbol_exists(M_PI math.h HAVE_M_PI) + target_compile_definitions(sdl-build-options INTERFACE "-D_USE_MATH_DEFINES") # needed for M_PI + set(STDC_HEADERS 1) + else() + set(HAVE_LIBC TRUE) + set(headers_to_check + ctype.h + float.h + iconv.h + inttypes.h + limits.h + malloc.h + math.h + memory.h + signal.h + stdarg.h + stddef.h + stdint.h + stdio.h + stdlib.h + string.h + strings.h + sys/types.h + wchar.h + ) + foreach(_HEADER ${headers_to_check}) + string(TOUPPER "HAVE_${_HEADER}" _UPPER) + string(REGEX REPLACE "[./]" "_" _HAVE_H ${_UPPER}) + check_include_file("${_HEADER}" ${_HAVE_H}) + endforeach() + + set(STDC_HEADER_NAMES "stddef.h;stdarg.h;stdlib.h;string.h;stdio.h;wchar.h;float.h") + check_include_files("${STDC_HEADER_NAMES}" STDC_HEADERS) + check_symbol_exists(M_PI math.h HAVE_M_PI) + # TODO: refine the mprotect check + check_c_source_compiles("#include + #include + int main(void) { return 0; }" HAVE_MPROTECT) + foreach(_FN + strtod malloc calloc realloc free getenv setenv putenv unsetenv + bsearch qsort abs bcopy memset memcpy memmove memcmp strlen strlcpy strlcat + _strrev _strupr _strlwr index rindex strchr strrchr strstr strtok_r + itoa _ltoa _uitoa _ultoa strtol strtoul _i64toa _ui64toa strtoll strtoull + atoi atof strcmp strncmp _stricmp strcasecmp _strnicmp strncasecmp strcasestr + wcscmp _wcsdup wcsdup wcslcat wcslcpy wcslen wcsncmp wcsstr + wcscasecmp _wcsicmp wcsncasecmp _wcsnicmp + sscanf vsscanf vsnprintf fopen64 fseeko fseeko64 _Exit + ) + string(TOUPPER ${_FN} _UPPER) + set(_HAVEVAR "HAVE_${_UPPER}") + check_symbol_exists("${_FN}" "${STDC_HEADER_NAMES}" ${_HAVEVAR}) + endforeach() + + check_symbol_exists(sigaction "signal.h" HAVE_SIGACTION) + check_symbol_exists(setjmp "setjmp.h" HAVE_SETJMP) + check_symbol_exists(nanosleep "time.h" HAVE_NANOSLEEP) + check_symbol_exists(sysconf "unistd.h" HAVE_SYSCONF) + check_symbol_exists(sysctlbyname "sys/types.h;sys/sysctl.h" HAVE_SYSCTLBYNAME) + check_symbol_exists(getauxval "sys/auxv.h" HAVE_GETAUXVAL) + check_symbol_exists(elf_aux_info "sys/auxv.h" HAVE_ELF_AUX_INFO) + check_symbol_exists(poll "poll.h" HAVE_POLL) + check_symbol_exists(memfd_create "sys/mman.h" HAVE_MEMFD_CREATE) + check_symbol_exists(posix_fallocate "fcntl.h" HAVE_POSIX_FALLOCATE) + + check_library_exists(m pow "" HAVE_LIBM) + if(HAVE_LIBM) + set(CMAKE_REQUIRED_LIBRARIES m) + endif() + foreach(_FN + atan atan2 atanf atan2f ceil ceilf copysign copysignf cos cosf + exp expf fabs fabsf floor floorf fmod fmodf log logf log10 log10f + lround lroundf pow powf round roundf scalbn scalbnf sin sinf sqrt + sqrtf tan tanf acos acosf asin asinf trunc truncf) + string(TOUPPER ${_FN} _UPPER) + set(_HAVEVAR "HAVE_${_UPPER}") + check_symbol_exists("${_FN}" "math.h" ${_HAVEVAR}) + endforeach() + if(HAVE_LIBM) + set(CMAKE_REQUIRED_LIBRARIES) + if(NOT VITA) + list(APPEND EXTRA_LIBS m) + endif() + endif() + + if(SDL_SYSTEM_ICONV) + check_c_source_compiles(" + #define LIBICONV_PLUG 1 /* in case libiconv header is in include path */ + #include + #include + int main(int argc, char **argv) { + return !iconv_open(NULL,NULL); + }" ICONV_IN_LIBC) + + cmake_push_check_state() + list(APPEND CMAKE_REQUIRED_LIBRARIES iconv) + check_c_source_compiles(" + #include + #include + int main(int argc, char **argv) { + return !iconv_open(NULL,NULL); + }" ICONV_IN_LIBICONV) + cmake_pop_check_state() + + if(ICONV_IN_LIBC OR ICONV_IN_LIBICONV) + set(HAVE_ICONV 1) + set(HAVE_SYSTEM_ICONV TRUE) + if(ICONV_IN_LIBICONV AND (SDL_LIBICONV OR (NOT ICONV_IN_LIBC))) + set(SDL_USE_LIBICONV 1) + set(HAVE_LIBICONV TRUE) + list(APPEND EXTRA_LIBS iconv) + endif() + endif() + endif() + + if(NOT APPLE) + check_include_file(alloca.h HAVE_ALLOCA_H) + check_symbol_exists(alloca "alloca.h" HAVE_ALLOCA1) + check_symbol_exists(alloca "stdlib.h" HAVE_ALLOCA2) + check_symbol_exists(alloca "malloc.h" HAVE_ALLOCA3) + if(HAVE_ALLOCA1 OR HAVE_ALLOCA2 OR HAVE_ALLOCA3) + set(HAVE_ALLOCA 1) + endif() + else() + set(HAVE_ALLOCA_H 1) + set(HAVE_ALLOCA 1) + endif() + + check_struct_has_member("struct sigaction" "sa_sigaction" "signal.h" HAVE_SA_SIGACTION) + endif() +else() + if(WINDOWS) + set(HAVE_STDARG_H 1) + set(HAVE_STDDEF_H 1) + check_include_file(stdint.h HAVE_STDINT_H) + + if(MSVC AND USE_CLANG) + check_c_compiler_flag("/Q_no-use-libirc" HAS_Q_NO_USE_LIBIRC ) + endif() + endif() +endif() + + +# Enable/disable various subsystems of the SDL library +foreach(_SUB ${SDL_SUBSYSTEMS}) + string(TOUPPER ${_SUB} _OPT) + if(NOT SDL_${_OPT}) + set(SDL_${_OPT}_DISABLED 1) + endif() +endforeach() +if(SDL_HAPTIC) + if(NOT SDL_JOYSTICK) + # Haptic requires some private functions from the joystick subsystem. + message_error("SDL_HAPTIC requires SDL_JOYSTICK, which is not enabled") + endif() +endif() + + +# General SDL subsystem options, valid for all platforms +if(SDL_AUDIO) + # CheckDummyAudio/CheckDiskAudio - valid for all platforms + if(SDL_DUMMYAUDIO) + set(SDL_AUDIO_DRIVER_DUMMY 1) + file(GLOB DUMMYAUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/dummy/*.c) + list(APPEND SOURCE_FILES ${DUMMYAUDIO_SOURCES}) + set(HAVE_DUMMYAUDIO TRUE) + set(HAVE_SDL_AUDIO TRUE) + endif() + if(SDL_DISKAUDIO) + set(SDL_AUDIO_DRIVER_DISK 1) + file(GLOB DISKAUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/disk/*.c) + list(APPEND SOURCE_FILES ${DISKAUDIO_SOURCES}) + set(HAVE_DISKAUDIO TRUE) + set(HAVE_SDL_AUDIO TRUE) + endif() +endif() + +if(UNIX OR APPLE) + # Relevant for Unix/Darwin only + set(DYNAPI_NEEDS_DLOPEN 1) + CheckDLOPEN() + if(SDL_LOADSO AND HAVE_DLOPEN) + set(SDL_LOADSO_DLOPEN 1) + file(GLOB DLOPEN_SOURCES ${SDL2_SOURCE_DIR}/src/loadso/dlopen/*.c) + list(APPEND SOURCE_FILES ${DLOPEN_SOURCES}) + set(HAVE_SDL_LOADSO TRUE) + endif() +endif() + +if(UNIX OR APPLE OR HAIKU OR RISCOS) + CheckO_CLOEXEC() +endif() + +if(SDL_JOYSTICK) + if(SDL_VIRTUAL_JOYSTICK) + set(HAVE_VIRTUAL_JOYSTICK TRUE) + set(SDL_JOYSTICK_VIRTUAL 1) + file(GLOB JOYSTICK_VIRTUAL_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/virtual/*.c) + list(APPEND SOURCE_FILES ${JOYSTICK_VIRTUAL_SOURCES}) + endif() +endif() + +if(SDL_VIDEO) + if(SDL_DUMMYVIDEO) + set(SDL_VIDEO_DRIVER_DUMMY 1) + file(GLOB VIDEO_DUMMY_SOURCES ${SDL2_SOURCE_DIR}/src/video/dummy/*.c) + list(APPEND SOURCE_FILES ${VIDEO_DUMMY_SOURCES}) + set(HAVE_DUMMYVIDEO TRUE) + set(HAVE_SDL_VIDEO TRUE) + endif() + if(SDL_OFFSCREEN) + set(SDL_VIDEO_DRIVER_OFFSCREEN 1) + file(GLOB VIDEO_OFFSCREEN_SOURCES ${SDL2_SOURCE_DIR}/src/video/offscreen/*.c) + list(APPEND SOURCE_FILES ${VIDEO_OFFSCREEN_SOURCES}) + set(HAVE_OFFSCREEN TRUE) + set(HAVE_SDL_VIDEO TRUE) + endif() +endif() + +# Platform-specific options and settings +if(ANDROID) + file(GLOB ANDROID_CORE_SOURCES ${SDL2_SOURCE_DIR}/src/core/android/*.c) + list(APPEND SOURCE_FILES ${ANDROID_CORE_SOURCES} ${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c) + set_property(SOURCE "${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c" APPEND_STRING PROPERTY COMPILE_FLAGS " -Wno-declaration-after-statement") + + if(SDL_MISC) + file(GLOB ANDROID_MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/android/*.c) + list(APPEND SOURCE_FILES ${ANDROID_MISC_SOURCES}) + set(HAVE_SDL_MISC TRUE) + endif() + + # SDL_spinlock.c Needs to be compiled in ARM mode. + # There seems to be no better way currently to set the ARM mode. + # see: https://issuetracker.google.com/issues/62264618 + # Another option would be to set ARM mode to all compiled files + cmake_push_check_state(RESET) + set(CMAKE_REQUIRED_FLAGS "-Werror=unused-command-line-argument") + check_c_compiler_flag(-marm HAVE_ARM_MODE) + if(HAVE_ARM_MODE) + set_property(SOURCE "${SDL2_SOURCE_DIR}/src/atomic/SDL_spinlock.c" APPEND_STRING PROPERTY COMPILE_FLAGS " -marm") + endif() + cmake_pop_check_state() + + file(GLOB ANDROID_MAIN_SOURCES ${SDL2_SOURCE_DIR}/src/main/android/*.c) + list(APPEND SDLMAIN_SOURCES ${ANDROID_MAIN_SOURCES}) + + if(SDL_AUDIO) + set(SDL_AUDIO_DRIVER_ANDROID 1) + file(GLOB ANDROID_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/android/*.c) + list(APPEND SOURCE_FILES ${ANDROID_AUDIO_SOURCES}) + + set(SDL_AUDIO_DRIVER_OPENSLES 1) + file(GLOB OPENSLES_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/openslES/*.c) + list(APPEND SOURCE_FILES ${OPENSLES_AUDIO_SOURCES}) + + list(APPEND EXTRA_LIBS ${ANDROID_DL_LIBRARY} OpenSLES) + + set(SDL_AUDIO_DRIVER_AAUDIO 1) + file(GLOB AAUDIO_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/aaudio/*.c) + list(APPEND SOURCE_FILES ${AAUDIO_AUDIO_SOURCES}) + + set(HAVE_SDL_AUDIO TRUE) + endif() + if(SDL_FILESYSTEM) + set(SDL_FILESYSTEM_ANDROID 1) + file(GLOB ANDROID_FILESYSTEM_SOURCES ${SDL2_SOURCE_DIR}/src/filesystem/android/*.c) + list(APPEND SOURCE_FILES ${ANDROID_FILESYSTEM_SOURCES}) + set(HAVE_SDL_FILESYSTEM TRUE) + endif() + if(SDL_HAPTIC) + set(SDL_HAPTIC_ANDROID 1) + file(GLOB ANDROID_HAPTIC_SOURCES ${SDL2_SOURCE_DIR}/src/haptic/android/*.c) + list(APPEND SOURCE_FILES ${ANDROID_HAPTIC_SOURCES}) + set(HAVE_SDL_HAPTIC TRUE) + endif() + if(SDL_HIDAPI) + CheckHIDAPI() + endif() + if(SDL_JOYSTICK) + set(SDL_JOYSTICK_ANDROID 1) + file(GLOB ANDROID_JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/android/*.c ${SDL2_SOURCE_DIR}/src/joystick/steam/*.c) + list(APPEND SOURCE_FILES ${ANDROID_JOYSTICK_SOURCES}) + set(HAVE_SDL_JOYSTICK TRUE) + endif() + if(SDL_LOADSO) + set(SDL_LOADSO_DLOPEN 1) + file(GLOB LOADSO_SOURCES ${SDL2_SOURCE_DIR}/src/loadso/dlopen/*.c) + list(APPEND SOURCE_FILES ${LOADSO_SOURCES}) + set(HAVE_SDL_LOADSO TRUE) + endif() + if(SDL_POWER) + set(SDL_POWER_ANDROID 1) + file(GLOB ANDROID_POWER_SOURCES ${SDL2_SOURCE_DIR}/src/power/android/*.c) + list(APPEND SOURCE_FILES ${ANDROID_POWER_SOURCES}) + set(HAVE_SDL_POWER TRUE) + endif() + if(SDL_LOCALE) + file(GLOB ANDROID_LOCALE_SOURCES ${SDL2_SOURCE_DIR}/src/locale/android/*.c) + list(APPEND SOURCE_FILES ${ANDROID_LOCALE_SOURCES}) + set(HAVE_SDL_LOCALE TRUE) + endif() + if(SDL_TIMERS) + set(SDL_TIMER_UNIX 1) + file(GLOB TIMER_SOURCES ${SDL2_SOURCE_DIR}/src/timer/unix/*.c) + list(APPEND SOURCE_FILES ${TIMER_SOURCES}) + set(HAVE_SDL_TIMERS TRUE) + endif() + if(SDL_SENSOR) + set(SDL_SENSOR_ANDROID 1) + set(HAVE_SDL_SENSORS TRUE) + file(GLOB ANDROID_SENSOR_SOURCES ${SDL2_SOURCE_DIR}/src/sensor/android/*.c) + list(APPEND SOURCE_FILES ${ANDROID_SENSOR_SOURCES}) + endif() + if(SDL_VIDEO) + set(SDL_VIDEO_DRIVER_ANDROID 1) + file(GLOB ANDROID_VIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/android/*.c) + list(APPEND SOURCE_FILES ${ANDROID_VIDEO_SOURCES}) + set(HAVE_SDL_VIDEO TRUE) + + # Core stuff + # find_library(ANDROID_DL_LIBRARY dl) + # FIXME failing dlopen https://github.com/android-ndk/ndk/issues/929 + list(APPEND EXTRA_LIBS dl log android) + target_compile_definitions(sdl-build-options INTERFACE "-DGL_GLEXT_PROTOTYPES") + + #enable gles + if(SDL_OPENGLES) + set(SDL_VIDEO_OPENGL_EGL 1) + set(HAVE_OPENGLES TRUE) + set(SDL_VIDEO_OPENGL_ES 1) + set(SDL_VIDEO_RENDER_OGL_ES 1) + set(SDL_VIDEO_OPENGL_ES2 1) + set(SDL_VIDEO_RENDER_OGL_ES2 1) + + list(APPEND EXTRA_LIBS GLESv1_CM GLESv2) + endif() + + if(SDL_VULKAN) + CHECK_C_SOURCE_COMPILES(" + #if defined(__ARM_ARCH) && __ARM_ARCH < 7 + #error Vulkan doesn't work on this configuration + #endif + int main(int argc, char **argv) { return 0; } + " VULKAN_PASSED_ANDROID_CHECKS) + if(VULKAN_PASSED_ANDROID_CHECKS) + set(SDL_VIDEO_VULKAN 1) + set(HAVE_VULKAN TRUE) + endif() + endif() + endif() + + CheckPTHREAD() + if(SDL_CLOCK_GETTIME) + set(HAVE_CLOCK_GETTIME 1) + endif() + +elseif(EMSCRIPTEN) + # Hide noisy warnings that intend to aid mostly during initial stages of porting a new + # project. Uncomment at will for verbose cross-compiling -I/../ path info. + target_compile_options(sdl-build-options INTERFACE "-Wno-warn-absolute-paths") + + if(SDL_MISC) + file(GLOB EMSRIPTEN_MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/emscripten/*.c) + list(APPEND SOURCE_FILES ${EMSRIPTEN_MISC_SOURCES}) + set(HAVE_SDL_MISC TRUE) + endif() + if(SDL_AUDIO) + set(SDL_AUDIO_DRIVER_EMSCRIPTEN 1) + file(GLOB EM_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/emscripten/*.c) + list(APPEND SOURCE_FILES ${EM_AUDIO_SOURCES}) + set(HAVE_SDL_AUDIO TRUE) + endif() + if(SDL_FILESYSTEM) + set(SDL_FILESYSTEM_EMSCRIPTEN 1) + file(GLOB EM_FILESYSTEM_SOURCES ${SDL2_SOURCE_DIR}/src/filesystem/emscripten/*.c) + list(APPEND SOURCE_FILES ${EM_FILESYSTEM_SOURCES}) + set(HAVE_SDL_FILESYSTEM TRUE) + endif() + if(SDL_JOYSTICK) + set(SDL_JOYSTICK_EMSCRIPTEN 1) + file(GLOB EM_JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/emscripten/*.c) + list(APPEND SOURCE_FILES ${EM_JOYSTICK_SOURCES}) + set(HAVE_SDL_JOYSTICK TRUE) + endif() + if(SDL_POWER) + set(SDL_POWER_EMSCRIPTEN 1) + file(GLOB EM_POWER_SOURCES ${SDL2_SOURCE_DIR}/src/power/emscripten/*.c) + list(APPEND SOURCE_FILES ${EM_POWER_SOURCES}) + set(HAVE_SDL_POWER TRUE) + endif() + if(SDL_LOCALE) + file(GLOB LOCALE_SOURCES ${SDL2_SOURCE_DIR}/src/locale/emscripten/*.c) + list(APPEND SOURCE_FILES ${LOCALE_SOURCES}) + set(HAVE_SDL_LOCALE TRUE) + endif() + if(SDL_TIMERS) + set(SDL_TIMER_UNIX 1) + file(GLOB TIMER_SOURCES ${SDL2_SOURCE_DIR}/src/timer/unix/*.c) + list(APPEND SOURCE_FILES ${TIMER_SOURCES}) + set(HAVE_SDL_TIMERS TRUE) + + if(SDL_CLOCK_GETTIME) + set(HAVE_CLOCK_GETTIME 1) + endif() + endif() + if(SDL_VIDEO) + set(SDL_VIDEO_DRIVER_EMSCRIPTEN 1) + file(GLOB EM_VIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/emscripten/*.c) + list(APPEND SOURCE_FILES ${EM_VIDEO_SOURCES}) + set(HAVE_SDL_VIDEO TRUE) + + #enable gles + if(SDL_OPENGLES) + set(SDL_VIDEO_OPENGL_EGL 1) + set(HAVE_OPENGLES TRUE) + set(SDL_VIDEO_OPENGL_ES2 1) + set(SDL_VIDEO_RENDER_OGL_ES2 1) + endif() + endif() + + CheckPTHREAD() + CheckLibUnwind() + +elseif(UNIX AND NOT APPLE AND NOT RISCOS AND NOT HAIKU) + if(SDL_AUDIO) + if(SYSV5 OR SOLARIS OR HPUX) + set(SDL_AUDIO_DRIVER_SUNAUDIO 1) + file(GLOB SUN_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/sun/*.c) + list(APPEND SOURCE_FILES ${SUN_AUDIO_SOURCES}) + set(HAVE_SDL_AUDIO TRUE) + elseif(NETBSD) + set(SDL_AUDIO_DRIVER_NETBSD 1) + file(GLOB NETBSD_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/netbsd/*.c) + list(APPEND SOURCE_FILES ${NETBSD_AUDIO_SOURCES}) + set(HAVE_SDL_AUDIO TRUE) + elseif(AIX) + set(SDL_AUDIO_DRIVER_PAUDIO 1) + file(GLOB AIX_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/paudio/*.c) + list(APPEND SOURCE_FILES ${AIX_AUDIO_SOURCES}) + set(HAVE_SDL_AUDIO TRUE) + elseif(QNX) + set(SDL_AUDIO_DRIVER_QSA 1) + file(GLOB QSA_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/qsa/*.c) + list(APPEND SOURCE_FILES ${QSA_AUDIO_SOURCES}) + list(APPEND EXTRA_LIBS asound) + set(HAVE_SDL_AUDIO TRUE) + endif() + CheckOSS() + CheckALSA() + CheckJACK() + CheckPipewire() + CheckPulseAudio() + CheckESD() + CheckARTS() + CheckNAS() + CheckSNDIO() + CheckFusionSound() + endif() + + if(SDL_VIDEO) + # Need to check for Raspberry PI first and add platform specific compiler flags, otherwise the test for GLES fails! + CheckRPI() + CheckX11() + CheckDirectFB() + # Need to check for EGL first because KMSDRM and Wayland depends on it. + CheckEGL() + CheckKMSDRM() + CheckGLX() + CheckOpenGL() + CheckOpenGLES() + CheckWayland() + CheckVivante() + # FIXME: implement CheckVulkan() + if(SDL_VULKAN) + set(SDL_VIDEO_VULKAN 1) + set(HAVE_VULKAN TRUE) + endif() + CheckQNXScreen() + endif() + + if(UNIX) + file(GLOB CORE_UNIX_SOURCES ${SDL2_SOURCE_DIR}/src/core/unix/*.c) + list(APPEND SOURCE_FILES ${CORE_UNIX_SOURCES}) + + check_c_source_compiles(" + #include + #ifndef EVIOCGNAME + #error EVIOCGNAME() ioctl not available + #endif + int main(int argc, char** argv) { return 0; }" HAVE_LINUX_INPUT_H) + + if(LINUX) + check_c_source_compiles(" + #include + #include + #include + int main(int argc, char **argv) { + struct kbentry kbe; + kbe.kb_table = KG_CTRL; + ioctl(0, KDGKBENT, &kbe); + return 0; + }" HAVE_INPUT_KD) + elseif(FREEBSD) + check_c_source_compiles(" + #include + #include + int main(int argc, char **argv) { + accentmap_t accTable; + ioctl(0, KDENABIO, 1); + return 0; + }" HAVE_INPUT_KBIO) + elseif(OPENBSD OR NETBSD) + check_c_source_compiles(" + #include + #include + #include + #include + #include + int main(int argc, char **argv) { + struct wskbd_map_data data; + ioctl(0, WSKBDIO_GETMAP, &data); + return 0; + }" HAVE_INPUT_WSCONS) + endif() + + if(HAVE_LINUX_INPUT_H) + set(SDL_INPUT_LINUXEV 1) + endif() + + if(SDL_HAPTIC AND HAVE_LINUX_INPUT_H) + set(SDL_HAPTIC_LINUX 1) + file(GLOB HAPTIC_SOURCES ${SDL2_SOURCE_DIR}/src/haptic/linux/*.c) + list(APPEND SOURCE_FILES ${HAPTIC_SOURCES}) + set(HAVE_SDL_HAPTIC TRUE) + endif() + + if(HAVE_INPUT_KD) + set(SDL_INPUT_LINUXKD 1) + endif() + + if(HAVE_INPUT_KBIO) + set(SDL_INPUT_FBSDKBIO 1) + endif() + + if(HAVE_INPUT_WSCONS) + set(SDL_INPUT_WSCONS 1) + endif() + + CheckLibUDev() + check_include_file("sys/inotify.h" HAVE_SYS_INOTIFY_H) + check_symbol_exists(inotify_init "sys/inotify.h" HAVE_INOTIFY_INIT) + check_symbol_exists(inotify_init1 "sys/inotify.h" HAVE_INOTIFY_INIT1) + + if(HAVE_SYS_INOTIFY_H AND HAVE_INOTIFY_INIT) + set(HAVE_INOTIFY 1) + endif() + + if(PKG_CONFIG_FOUND) + if(SDL_DBUS) + pkg_search_module(DBUS dbus-1 dbus) + if(DBUS_FOUND) + set(HAVE_DBUS_DBUS_H TRUE) + target_include_directories(sdl-build-options INTERFACE "${DBUS_INCLUDE_DIRS}") + # Fcitx need only dbus. + set(HAVE_FCITX TRUE) + set(HAVE_DBUS TRUE) + endif() + endif() + + if(SDL_IBUS) + pkg_search_module(IBUS ibus-1.0 ibus) + find_path(HAVE_SYS_INOTIFY_H NAMES sys/inotify.h) + if(IBUS_FOUND AND HAVE_SYS_INOTIFY_H) + set(HAVE_IBUS_IBUS_H TRUE) + target_include_directories(sdl-build-options INTERFACE "${IBUS_INCLUDE_DIRS}") + set(HAVE_IBUS TRUE) + endif() + endif() + + if (HAVE_IBUS_IBUS_H OR HAVE_FCITX) + set(SDL_USE_IME 1) + endif() + + if(FREEBSD AND NOT HAVE_INOTIFY) + pkg_search_module(INOTIFY libinotify) + if(INOTIFY_FOUND) + set(HAVE_INOTIFY 1) + target_include_directories(sdl-build-options INTERFACE "${INOTIFY_INCLUDE_DIRS}") + list(APPEND EXTRA_LIBS ${INOTIFY_LIBRARIES}) + endif() + endif() + + endif() + CheckLibUnwind() + + if(HAVE_DBUS_DBUS_H) + list(APPEND SOURCE_FILES "${SDL2_SOURCE_DIR}/src/core/linux/SDL_dbus.c") + endif() + + if(SDL_USE_IME) + list(APPEND SOURCE_FILES "${SDL2_SOURCE_DIR}/src/core/linux/SDL_ime.c") + endif() + + if(HAVE_IBUS_IBUS_H) + list(APPEND SOURCE_FILES "${SDL2_SOURCE_DIR}/src/core/linux/SDL_ibus.c") + endif() + + if(HAVE_FCITX) + list(APPEND SOURCE_FILES "${SDL2_SOURCE_DIR}/src/core/linux/SDL_fcitx.c") + endif() + + if(HAVE_LIBUDEV_H) + list(APPEND SOURCE_FILES "${SDL2_SOURCE_DIR}/src/core/linux/SDL_udev.c") + endif() + + if(HAVE_LINUX_INPUT_H) + list(APPEND SOURCE_FILES "${SDL2_SOURCE_DIR}/src/core/linux/SDL_evdev.c") + list(APPEND SOURCE_FILES "${SDL2_SOURCE_DIR}/src/core/linux/SDL_evdev_kbd.c") + endif() + + if(HAVE_INPUT_KBIO) + list(APPEND SOURCE_FILES "${SDL2_SOURCE_DIR}/src/core/freebsd/SDL_evdev_kbd_freebsd.c") + endif() + + if(HAVE_INPUT_WSCONS) + list(APPEND SOURCE_FILES "${SDL2_SOURCE_DIR}/src/core/openbsd/SDL_wscons_kbd.c") + list(APPEND SOURCE_FILES "${SDL2_SOURCE_DIR}/src/core/openbsd/SDL_wscons_mouse.c") + endif() + + # Always compiled for Linux, unconditionally: + list(APPEND SOURCE_FILES "${SDL2_SOURCE_DIR}/src/core/linux/SDL_evdev_capabilities.c") + list(APPEND SOURCE_FILES "${SDL2_SOURCE_DIR}/src/core/linux/SDL_threadprio.c") + list(APPEND SOURCE_FILES "${SDL2_SOURCE_DIR}/src/core/linux/SDL_sandbox.c") + + # src/core/unix/*.c is included in a generic if(UNIX) section, elsewhere. + endif() + + if(SDL_HIDAPI) + CheckHIDAPI() + endif() + + if(SDL_JOYSTICK) + if(FREEBSD OR NETBSD OR OPENBSD OR BSDI) + CheckUSBHID() + endif() + if((LINUX OR FREEBSD) AND HAVE_LINUX_INPUT_H AND NOT ANDROID) + set(SDL_JOYSTICK_LINUX 1) + file(GLOB JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/linux/*.c ${SDL2_SOURCE_DIR}/src/joystick/steam/*.c) + list(APPEND SOURCE_FILES ${JOYSTICK_SOURCES}) + set(HAVE_SDL_JOYSTICK TRUE) + endif() + endif() + + CheckPTHREAD() + + if(SDL_CLOCK_GETTIME) + check_library_exists(c clock_gettime "" FOUND_CLOCK_GETTIME_LIBC) + if(FOUND_CLOCK_GETTIME_LIBC) + set(HAVE_CLOCK_GETTIME 1) + else() + check_library_exists(rt clock_gettime "" FOUND_CLOCK_GETTIME_LIBRT) + if(FOUND_CLOCK_GETTIME_LIBRT) + set(HAVE_CLOCK_GETTIME 1) + list(APPEND EXTRA_LIBS rt) + endif() + endif() + endif() + + check_include_file(linux/version.h HAVE_LINUX_VERSION_H) + if(HAVE_LINUX_VERSION_H) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DHAVE_LINUX_VERSION_H") + endif() + + if(SDL_MISC) + file(GLOB MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/unix/*.c) + list(APPEND SOURCE_FILES ${MISC_SOURCES}) + set(HAVE_SDL_MISC TRUE) + endif() + + if(SDL_POWER) + if(LINUX) + set(SDL_POWER_LINUX 1) + file(GLOB POWER_SOURCES ${SDL2_SOURCE_DIR}/src/power/linux/*.c) + list(APPEND SOURCE_FILES ${POWER_SOURCES}) + set(HAVE_SDL_POWER TRUE) + endif() + endif() + + if(SDL_LOCALE) + file(GLOB LOCALE_SOURCES ${SDL2_SOURCE_DIR}/src/locale/unix/*.c) + list(APPEND SOURCE_FILES ${LOCALE_SOURCES}) + set(HAVE_SDL_LOCALE TRUE) + endif() + + if(SDL_FILESYSTEM) + set(SDL_FILESYSTEM_UNIX 1) + file(GLOB FILESYSTEM_SOURCES ${SDL2_SOURCE_DIR}/src/filesystem/unix/*.c) + list(APPEND SOURCE_FILES ${FILESYSTEM_SOURCES}) + set(HAVE_SDL_FILESYSTEM TRUE) + endif() + + if(SDL_TIMERS) + set(SDL_TIMER_UNIX 1) + file(GLOB TIMER_SOURCES ${SDL2_SOURCE_DIR}/src/timer/unix/*.c) + list(APPEND SOURCE_FILES ${TIMER_SOURCES}) + set(HAVE_SDL_TIMERS TRUE) + endif() + + set(SDL_RLD_FLAGS "") + if(SDL_RPATH AND SDL_SHARED) + if(BSDI OR FREEBSD OR LINUX OR NETBSD) + set(CMAKE_REQUIRED_FLAGS "-Wl,--enable-new-dtags") + check_c_compiler_flag("" HAVE_ENABLE_NEW_DTAGS) + set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS}) + if(HAVE_ENABLE_NEW_DTAGS) + set(SDL_RLD_FLAGS "-Wl,-rpath,\${libdir} -Wl,--enable-new-dtags") + else() + set(SDL_RLD_FLAGS "-Wl,-rpath,\${libdir}") + endif() + elseif(SOLARIS) + set(SDL_RLD_FLAGS "-R\${libdir}") + endif() + set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) + set(HAVE_RPATH TRUE) + endif() + + if(QNX) + # QNX's *printf() family generates a SIGSEGV if NULL is passed for a string + # specifier (on purpose), but SDL expects "(null)". Use the built-in + # implementation. + set(HAVE_VSNPRINTF 0) + set(USE_POSIX_SPAWN 1) + endif() +elseif(WINDOWS) + find_program(WINDRES windres) + + check_c_source_compiles(" + #include + int main(int argc, char **argv) { return 0; }" HAVE_WIN32_CC) + + file(GLOB CORE_SOURCES ${SDL2_SOURCE_DIR}/src/core/windows/*.c) + list(APPEND SOURCE_FILES ${CORE_SOURCES}) + + if(WINDOWS_STORE) + file(GLOB WINRT_SOURCE_FILES ${SDL2_SOURCE_DIR}/src/core/winrt/*.c ${SDL2_SOURCE_DIR}/src/core/winrt/*.cpp) + list(APPEND SOURCE_FILES ${WINRT_SOURCE_FILES}) + endif() + + if(MSVC AND NOT SDL_LIBC) + # Prevent codegen that would use the VC runtime libraries. + set_property(DIRECTORY . APPEND PROPERTY COMPILE_OPTIONS "/GS-;/Gs1048576") + if(NOT ARCH_64 AND NOT CMAKE_GENERATOR_PLATFORM STREQUAL "ARM") + set_property(DIRECTORY . APPEND PROPERTY COMPILE_OPTIONS "/arch:SSE") + endif() + endif() + + if(SDL_MISC) + if(WINDOWS_STORE) + file(GLOB MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/winrt/*.cpp) + else() + file(GLOB MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/windows/*.c) + endif() + list(APPEND SOURCE_FILES ${MISC_SOURCES}) + set(HAVE_SDL_MISC TRUE) + endif() + + # Check for DirectX + if(SDL_DIRECTX) + if(DEFINED MSVC_VERSION AND NOT ${MSVC_VERSION} LESS 1700) + set(USE_WINSDK_DIRECTX TRUE) + endif() + if(NOT MINGW AND NOT USE_WINSDK_DIRECTX) + if("$ENV{DXSDK_DIR}" STREQUAL "") + message_error("DIRECTX requires the \$DXSDK_DIR environment variable to be set") + endif() + set(CMAKE_REQUIRED_FLAGS "/I\"$ENV{DXSDK_DIR}\\Include\"") + endif() + + check_include_file(d3d9.h HAVE_D3D_H) + check_include_file(d3d11_1.h HAVE_D3D11_H) + check_c_source_compiles(" + #include + #include + ID3D12Device1 *device; + int main(int argc, char **argv) {return 0; } + " HAVE_D3D12_H) + check_include_file(ddraw.h HAVE_DDRAW_H) + check_include_file(dsound.h HAVE_DSOUND_H) + check_include_file(dinput.h HAVE_DINPUT_H) + if(WINDOWS_STORE OR SDL_CPU_ARM32) + set(HAVE_DINPUT_H 0) + endif() + check_include_file(dxgi.h HAVE_DXGI_H) + if(HAVE_D3D_H OR HAVE_D3D11_H OR HAVE_D3D12_H OR HAVE_DDRAW_H OR HAVE_DSOUND_H OR HAVE_DINPUT_H) + set(HAVE_DIRECTX TRUE) + if(NOT MINGW AND NOT USE_WINSDK_DIRECTX) + # TODO: change $ENV{DXSDL_DIR} to get the path from the include checks + target_link_directories(sdl-build-options INTERFACE "$$ENV{DXSDK_DIR}\\lib\\${PROCESSOR_ARCH}") + target_include_directories(sdl-build-options INTERFACE "$ENV{DXSDK_DIR}\\Include") + endif() + endif() + set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS}) + endif() + + if(SDL_XINPUT) + # xinput.h may need windows.h, but does not include it itself. + check_c_source_compiles(" + #include + #include + int main(int argc, char **argv) { return 0; }" HAVE_XINPUT_H) + check_c_source_compiles(" + #define COBJMACROS + #include + __x_ABI_CWindows_CGaming_CInput_CIGamepadStatics2 *s2; + int main(int argc, char **argv) { return 0; }" HAVE_WINDOWS_GAMING_INPUT_H) + endif() + + # headers needed elsewhere + check_include_file(tpcshrd.h HAVE_TPCSHRD_H) + check_include_file(roapi.h HAVE_ROAPI_H) + check_include_file(mmdeviceapi.h HAVE_MMDEVICEAPI_H) + check_include_file(audioclient.h HAVE_AUDIOCLIENT_H) + check_include_file(sensorsapi.h HAVE_SENSORSAPI_H) + check_include_file(shellscalingapi.h HAVE_SHELLSCALINGAPI_H) + + if(SDL_AUDIO) + if(NOT WINDOWS_STORE) + set(SDL_AUDIO_DRIVER_WINMM 1) + file(GLOB WINMM_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/winmm/*.c) + list(APPEND SOURCE_FILES ${WINMM_AUDIO_SOURCES}) + set(HAVE_SDL_AUDIO TRUE) + endif() + + if(HAVE_DSOUND_H AND NOT WINDOWS_STORE) + set(SDL_AUDIO_DRIVER_DSOUND 1) + file(GLOB DSOUND_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/directsound/*.c) + list(APPEND SOURCE_FILES ${DSOUND_AUDIO_SOURCES}) + set(HAVE_SDL_AUDIO TRUE) + endif() + + if(SDL_WASAPI AND HAVE_AUDIOCLIENT_H AND HAVE_MMDEVICEAPI_H) + set(SDL_AUDIO_DRIVER_WASAPI 1) + set(HAVE_WASAPI TRUE) + file(GLOB WASAPI_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/wasapi/*.c) + if(WINDOWS_STORE) + list(APPEND WASAPI_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/wasapi/SDL_wasapi_winrt.cpp) + endif() + list(APPEND SOURCE_FILES ${WASAPI_AUDIO_SOURCES}) + set(HAVE_SDL_AUDIO TRUE) + endif() + endif() + + if(SDL_VIDEO) + # requires SDL_LOADSO on Windows (IME, DX, etc.) + if(NOT SDL_LOADSO) + message_error("SDL_VIDEO requires SDL_LOADSO, which is not enabled") + endif() + if(WINDOWS_STORE) + set(SDL_VIDEO_DRIVER_WINRT 1) + file(GLOB WIN_VIDEO_SOURCES + ${SDL2_SOURCE_DIR}/src/video/winrt/*.c + ${SDL2_SOURCE_DIR}/src/video/winrt/*.cpp + ${SDL2_SOURCE_DIR}/src/render/direct3d11/*.cpp + ) + else() + set(SDL_VIDEO_DRIVER_WINDOWS 1) + file(GLOB WIN_VIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/windows/*.c) + endif() + list(APPEND SOURCE_FILES ${WIN_VIDEO_SOURCES}) + + if(SDL_RENDER_D3D AND HAVE_D3D_H AND NOT WINDOWS_STORE) + set(SDL_VIDEO_RENDER_D3D 1) + set(HAVE_RENDER_D3D TRUE) + endif() + if(SDL_RENDER_D3D AND HAVE_D3D11_H) + set(SDL_VIDEO_RENDER_D3D11 1) + set(HAVE_RENDER_D3D TRUE) + endif() + if(SDL_RENDER_D3D AND HAVE_D3D12_H AND NOT WINDOWS_STORE) + set(SDL_VIDEO_RENDER_D3D12 1) + set(HAVE_RENDER_D3D TRUE) + endif() + set(HAVE_SDL_VIDEO TRUE) + endif() + + if(SDL_THREADS) + set(SDL_THREAD_GENERIC_COND_SUFFIX 1) + set(SDL_THREAD_WINDOWS 1) + list(APPEND SOURCE_FILES + ${SDL2_SOURCE_DIR}/src/thread/generic/SDL_syscond.c + ${SDL2_SOURCE_DIR}/src/thread/windows/SDL_syscond_cv.c + ${SDL2_SOURCE_DIR}/src/thread/windows/SDL_sysmutex.c + ${SDL2_SOURCE_DIR}/src/thread/windows/SDL_syssem.c + ${SDL2_SOURCE_DIR}/src/thread/windows/SDL_systhread.c + ${SDL2_SOURCE_DIR}/src/thread/windows/SDL_systls.c) + set(HAVE_SDL_THREADS TRUE) + endif() + + if(SDL_SENSOR AND HAVE_SENSORSAPI_H AND NOT WINDOWS_STORE) + set(SDL_SENSOR_WINDOWS 1) + set(HAVE_SDL_SENSORS TRUE) + file(GLOB WINDOWS_SENSOR_SOURCES ${SDL2_SOURCE_DIR}/src/sensor/windows/*.c) + list(APPEND SOURCE_FILES ${WINDOWS_SENSOR_SOURCES}) + endif() + + if(SDL_POWER) + if(WINDOWS_STORE) + set(SDL_POWER_WINRT 1) + list(APPEND SOURCE_FILES ${SDL2_SOURCE_DIR}/src/power/winrt/SDL_syspower.cpp) + else() + set(SDL_POWER_WINDOWS 1) + list(APPEND SOURCE_FILES ${SDL2_SOURCE_DIR}/src/power/windows/SDL_syspower.c) + set(HAVE_SDL_POWER TRUE) + endif() + endif() + + if(SDL_LOCALE) + if(WINDOWS_STORE) + file(GLOB LOCALE_SOURCES ${SDL2_SOURCE_DIR}/src/locale/winrt/*.c) + else() + file(GLOB LOCALE_SOURCES ${SDL2_SOURCE_DIR}/src/locale/windows/*.c) + endif() + list(APPEND SOURCE_FILES ${LOCALE_SOURCES}) + set(HAVE_SDL_LOCALE TRUE) + endif() + + if(SDL_FILESYSTEM) + set(SDL_FILESYSTEM_WINDOWS 1) + if(WINDOWS_STORE) + file(GLOB FILESYSTEM_SOURCES ${SDL2_SOURCE_DIR}/src/filesystem/winrt/*.cpp) + else() + file(GLOB FILESYSTEM_SOURCES ${SDL2_SOURCE_DIR}/src/filesystem/windows/*.c) + endif() + list(APPEND SOURCE_FILES ${FILESYSTEM_SOURCES}) + set(HAVE_SDL_FILESYSTEM TRUE) + endif() + + # Libraries for Win32 native and MinGW + if(NOT WINDOWS_STORE) + list(APPEND EXTRA_LIBS kernel32 user32 gdi32 winmm imm32 ole32 oleaut32 version uuid advapi32 setupapi shell32) + endif() + + if(WINDOWS_STORE) + list(APPEND EXTRA_LIBS + -nodefaultlib:vccorlib$<$:d> + -nodefaultlib:msvcrt$<$:d> + vccorlib$<$:d>.lib + msvcrt$<$:d>.lib + ) + endif() + + if(SDL_TIMERS) + set(SDL_TIMER_WINDOWS 1) + file(GLOB TIMER_SOURCES ${SDL2_SOURCE_DIR}/src/timer/windows/*.c) + list(APPEND SOURCE_FILES ${TIMER_SOURCES}) + set(HAVE_SDL_TIMERS TRUE) + endif() + + if(SDL_LOADSO) + set(SDL_LOADSO_WINDOWS 1) + file(GLOB LOADSO_SOURCES ${SDL2_SOURCE_DIR}/src/loadso/windows/*.c) + list(APPEND SOURCE_FILES ${LOADSO_SOURCES}) + set(HAVE_SDL_LOADSO TRUE) + endif() + + file(GLOB CORE_SOURCES ${SDL2_SOURCE_DIR}/src/core/windows/*.c) + list(APPEND SOURCE_FILES ${CORE_SOURCES}) + + if(SDL_VIDEO) + if(SDL_OPENGL AND NOT WINDOWS_STORE) + set(SDL_VIDEO_OPENGL 1) + set(SDL_VIDEO_OPENGL_WGL 1) + set(SDL_VIDEO_RENDER_OGL 1) + set(HAVE_OPENGL TRUE) + endif() + + if(SDL_OPENGLES) + set(SDL_VIDEO_OPENGL_EGL 1) + set(SDL_VIDEO_OPENGL_ES2 1) + set(SDL_VIDEO_RENDER_OGL_ES2 1) + set(HAVE_OPENGLES TRUE) + endif() + + if(SDL_VULKAN) + set(SDL_VIDEO_VULKAN 1) + set(HAVE_VULKAN TRUE) + endif() + endif() + + if(SDL_HIDAPI) + CheckHIDAPI() + endif() + + if(SDL_JOYSTICK) + file(GLOB JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/windows/*.c) + list(APPEND SOURCE_FILES ${JOYSTICK_SOURCES}) + + if(NOT WINDOWS_STORE) + set(SDL_JOYSTICK_RAWINPUT 1) + endif() + if(HAVE_DINPUT_H) + set(SDL_JOYSTICK_DINPUT 1) + list(APPEND EXTRA_LIBS dinput8) + endif() + if(HAVE_XINPUT_H) + if(NOT WINDOWS_STORE) + set(SDL_JOYSTICK_XINPUT 1) + set(HAVE_XINPUT TRUE) + endif() + if(HAVE_WINDOWS_GAMING_INPUT_H) + set(SDL_JOYSTICK_WGI 1) + endif() + endif() + set(HAVE_SDL_JOYSTICK TRUE) + + if(SDL_HAPTIC) + if((HAVE_DINPUT_H OR HAVE_XINPUT_H) AND NOT WINDOWS_STORE) + file(GLOB HAPTIC_SOURCES ${SDL2_SOURCE_DIR}/src/haptic/windows/*.c) + if(HAVE_DINPUT_H) + set(SDL_HAPTIC_DINPUT 1) + endif() + if(HAVE_XINPUT_H) + set(SDL_HAPTIC_XINPUT 1) + endif() + else() + file(GLOB HAPTIC_SOURCES ${SDL2_SOURCE_DIR}/src/haptic/dummy/*.c) + set(SDL_HAPTIC_DUMMY 1) + endif() + list(APPEND SOURCE_FILES ${HAPTIC_SOURCES}) + set(HAVE_SDL_HAPTIC TRUE) + endif() + endif() + + file(GLOB VERSION_SOURCES ${SDL2_SOURCE_DIR}/src/main/windows/*.rc) + file(GLOB SDLMAIN_SOURCES ${SDL2_SOURCE_DIR}/src/main/windows/*.c) + if(MINGW OR CYGWIN) + if(NOT SDL2_DISABLE_SDL2MAIN) + list(APPEND SDL_CFLAGS "-Dmain=SDL_main") + list(INSERT SDL_LIBS 0 "-lSDL2main") + endif(NOT SDL2_DISABLE_SDL2MAIN) + list(INSERT SDL_LIBS 0 "-lmingw32" "-mwindows") + endif() + +elseif(APPLE) + # TODO: rework this all for proper MacOS X, iOS and Darwin support + + # We always need these libs on macOS at the moment. + # !!! 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(DARWIN OR MACOSX) + set(SDL_FRAMEWORK_COCOA 1) + set(SDL_FRAMEWORK_CARBON 1) + endif() + set(SDL_FRAMEWORK_FOUNDATION 1) + set(SDL_FRAMEWORK_COREVIDEO 1) + + # Requires the darwin file implementation + if(SDL_FILE) + file(GLOB EXTRA_SOURCES ${SDL2_SOURCE_DIR}/src/file/cocoa/*.m) + list(APPEND SOURCE_FILES ${EXTRA_SOURCES}) + set(HAVE_SDL_FILE TRUE) + endif() + + if(IOS OR TVOS) + file(GLOB SDLMAIN_SOURCES ${SDL2_SOURCE_DIR}/src/main/uikit/*.c) + endif() + + if(SDL_MISC) + if(IOS OR TVOS) + file(GLOB MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/ios/*.m) + else() + file(GLOB MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/macosx/*.m) + endif() + list(APPEND SOURCE_FILES ${MISC_SOURCES}) + set(HAVE_SDL_MISC TRUE) + endif() + + if(SDL_AUDIO) + set(SDL_AUDIO_DRIVER_COREAUDIO 1) + file(GLOB AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/coreaudio/*.m) + list(APPEND SOURCE_FILES ${AUDIO_SOURCES}) + set(HAVE_SDL_AUDIO TRUE) + set(SDL_FRAMEWORK_COREAUDIO 1) + set(SDL_FRAMEWORK_AUDIOTOOLBOX 1) + set(SDL_FRAMEWORK_AVFOUNDATION 1) + endif() + + if(SDL_HIDAPI) + CheckHIDAPI() + endif() + + if(SDL_JOYSTICK) + file(GLOB MFI_JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/iphoneos/*.m) + if(IOS OR TVOS) + file(GLOB JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/steam/*.c) + set(SDL_JOYSTICK_MFI 1) + if(IOS) + set(SDL_FRAMEWORK_COREMOTION 1) + endif() + set(SDL_FRAMEWORK_GAMECONTROLLER 1) + set(SDL_FRAMEWORK_COREHAPTICS 1) + else() + file(GLOB JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/darwin/*.c) + set_property(SOURCE ${MFI_JOYSTICK_SOURCES} APPEND_STRING PROPERTY COMPILE_FLAGS " -fobjc-weak") + check_objc_source_compiles(" + #include + #include + #import + #import + #if MAC_OS_X_VERSION_MIN_REQUIRED < 1080 + #error GameController framework doesn't work on this configuration + #endif + #if TARGET_CPU_X86 + #error GameController framework doesn't work on this configuration + #endif + int main() { return 0; }" HAVE_FRAMEWORK_GAMECONTROLLER) + check_objc_source_compiles(" + #include + #include + #import + #import + int main() { return 0; }" HAVE_FRAMEWORK_COREHAPTICS) + if(HAVE_FRAMEWORK_GAMECONTROLLER AND HAVE_FRAMEWORK_COREHAPTICS) + # Only enable MFI if we also have CoreHaptics to ensure rumble works + set(SDL_JOYSTICK_MFI 1) + set(SDL_FRAMEWORK_GAMECONTROLLER 1) + set(SDL_FRAMEWORK_COREHAPTICS 1) + endif() + set(SDL_JOYSTICK_IOKIT 1) + set(SDL_FRAMEWORK_IOKIT 1) + set(SDL_FRAMEWORK_FF 1) + endif() + list(APPEND SOURCE_FILES ${JOYSTICK_SOURCES} ${MFI_JOYSTICK_SOURCES}) + set(HAVE_SDL_JOYSTICK TRUE) + endif() + + if(SDL_HAPTIC) + if (IOS OR TVOS) + file(GLOB HAPTIC_SOURCES ${SDL2_SOURCE_DIR}/src/haptic/dummy/*.c) + set(SDL_HAPTIC_DUMMY 1) + else() + file(GLOB HAPTIC_SOURCES ${SDL2_SOURCE_DIR}/src/haptic/darwin/*.c) + set(SDL_HAPTIC_IOKIT 1) + set(SDL_FRAMEWORK_IOKIT 1) + set(SDL_FRAMEWORK_FF 1) + endif() + list(APPEND SOURCE_FILES ${HAPTIC_SOURCES}) + set(HAVE_SDL_HAPTIC TRUE) + endif() + + if(SDL_POWER) + if (IOS OR TVOS) + file(GLOB POWER_SOURCES ${SDL2_SOURCE_DIR}/src/power/uikit/*.m) + set(SDL_POWER_UIKIT 1) + else() + file(GLOB POWER_SOURCES ${SDL2_SOURCE_DIR}/src/power/macosx/*.c) + set(SDL_POWER_MACOSX 1) + set(SDL_FRAMEWORK_IOKIT 1) + endif() + list(APPEND SOURCE_FILES ${POWER_SOURCES}) + set(HAVE_SDL_POWER TRUE) + endif() + + if(SDL_LOCALE) + file(GLOB LOCALE_SOURCES ${SDL2_SOURCE_DIR}/src/locale/macosx/*.m) + list(APPEND SOURCE_FILES ${LOCALE_SOURCES}) + set(HAVE_SDL_LOCALE TRUE) + endif() + + if(SDL_TIMERS) + set(SDL_TIMER_UNIX 1) + file(GLOB TIMER_SOURCES ${SDL2_SOURCE_DIR}/src/timer/unix/*.c) + list(APPEND SOURCE_FILES ${TIMER_SOURCES}) + set(HAVE_SDL_TIMERS TRUE) + endif(SDL_TIMERS) + + if(SDL_FILESYSTEM) + set(SDL_FILESYSTEM_COCOA 1) + file(GLOB FILESYSTEM_SOURCES ${SDL2_SOURCE_DIR}/src/filesystem/cocoa/*.m) + list(APPEND SOURCE_FILES ${FILESYSTEM_SOURCES}) + set(HAVE_SDL_FILESYSTEM TRUE) + endif() + + if(SDL_SENSOR) + if(IOS) + set(SDL_SENSOR_COREMOTION 1) + set(HAVE_SDL_SENSORS TRUE) + file(GLOB SENSOR_SOURCES ${SDL2_SOURCE_DIR}/src/sensor/coremotion/*.m) + list(APPEND SOURCE_FILES ${SENSOR_SOURCES}) + endif() + endif() + + # iOS hack needed - http://code.google.com/p/ios-cmake/ ? + if(SDL_VIDEO) + if (IOS OR TVOS) + set(SDL_VIDEO_DRIVER_UIKIT 1) + set(SDL_FRAMEWORK_COREGRAPHICS 1) + set(SDL_FRAMEWORK_QUARTZCORE 1) + set(SDL_FRAMEWORK_UIKIT 1) + set(SDL_IPHONE_KEYBOARD 1) + set(SDL_IPHONE_LAUNCHSCREEN 1) + file(GLOB UIKITVIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/uikit/*.m) + list(APPEND SOURCE_FILES ${UIKITVIDEO_SOURCES}) + set(HAVE_SDL_VIDEO TRUE) + else() + CheckCOCOA() + if(SDL_OPENGL) + set(SDL_VIDEO_OPENGL 1) + set(SDL_VIDEO_OPENGL_CGL 1) + set(SDL_VIDEO_RENDER_OGL 1) + set(HAVE_OPENGL TRUE) + endif() + endif() + + if(SDL_OPENGLES) + if(IOS OR TVOS) + set(SDL_FRAMEWORK_OPENGLES 1) + set(SDL_VIDEO_OPENGL_ES 1) + set(SDL_VIDEO_RENDER_OGL_ES 1) + else() + set(SDL_VIDEO_OPENGL_EGL 1) + endif() + set(SDL_VIDEO_OPENGL_ES2 1) + set(SDL_VIDEO_RENDER_OGL_ES2 1) + set(HAVE_OPENGLES TRUE) + endif() + + if(SDL_VULKAN OR SDL_METAL OR SDL_RENDER_METAL) + check_objc_source_compiles(" + #include + #import + #import + + #if (!TARGET_CPU_X86_64 && !TARGET_CPU_ARM64) + #error Metal doesn't work on this configuration + #endif + int main(int argc, char **argv) { return 0; }" HAVE_FRAMEWORK_METAL) + if(HAVE_FRAMEWORK_METAL) + set(SDL_FRAMEWORK_METAL 1) + set(SDL_FRAMEWORK_QUARTZCORE 1) + if(SDL_VULKAN) + set(SDL_VIDEO_VULKAN 1) + set(HAVE_VULKAN TRUE) + endif() + if(SDL_METAL) + set(SDL_VIDEO_METAL 1) + set(HAVE_METAL TRUE) + endif() + if(SDL_RENDER_METAL) + file(GLOB RENDER_METAL_SOURCES ${SDL2_SOURCE_DIR}/src/render/metal/*.m) + list(APPEND SOURCE_FILES ${RENDER_METAL_SOURCES}) + set(SDL_VIDEO_RENDER_METAL 1) + set(HAVE_RENDER_METAL TRUE) + endif() + endif() + endif() + endif() + + # Actually load the frameworks at the end so we don't duplicate include. + if(SDL_FRAMEWORK_COREVIDEO) + list(APPEND EXTRA_LDFLAGS "-Wl,-framework,CoreVideo") + endif() + if(SDL_FRAMEWORK_COCOA) + list(APPEND EXTRA_LDFLAGS "-Wl,-framework,Cocoa") + endif() + if(SDL_FRAMEWORK_IOKIT) + list(APPEND EXTRA_LDFLAGS "-Wl,-framework,IOKit") + endif() + if(SDL_FRAMEWORK_FF) + list(APPEND EXTRA_LDFLAGS "-Wl,-framework,ForceFeedback") + endif() + if(SDL_FRAMEWORK_CARBON) + list(APPEND EXTRA_LDFLAGS "-Wl,-framework,Carbon") + endif() + if(SDL_FRAMEWORK_COREAUDIO) + list(APPEND EXTRA_LDFLAGS "-Wl,-framework,CoreAudio") + endif() + if(SDL_FRAMEWORK_AUDIOTOOLBOX) + list(APPEND EXTRA_LDFLAGS "-Wl,-framework,AudioToolbox") + endif() + if(SDL_FRAMEWORK_AVFOUNDATION) + list(APPEND EXTRA_LDFLAGS "-Wl,-framework,AVFoundation") + endif() + if(SDL_FRAMEWORK_COREBLUETOOTH) + list(APPEND EXTRA_LDFLAGS "-Wl,-framework,CoreBluetooth") + endif() + if(SDL_FRAMEWORK_COREGRAPHICS) + list(APPEND EXTRA_LDFLAGS "-Wl,-framework,CoreGraphics") + endif() + if(SDL_FRAMEWORK_COREMOTION) + list(APPEND EXTRA_LDFLAGS "-Wl,-framework,CoreMotion") + endif() + if(SDL_FRAMEWORK_FOUNDATION) + list(APPEND EXTRA_LDFLAGS "-Wl,-framework,Foundation") + endif() + if(SDL_FRAMEWORK_GAMECONTROLLER) + find_library(GAMECONTROLLER GameController) + if(GAMECONTROLLER) + list(APPEND EXTRA_LDFLAGS "-Wl,-weak_framework,GameController") + endif() + endif() + if(SDL_FRAMEWORK_METAL) + if(IOS OR TVOS) + list(APPEND EXTRA_LDFLAGS "-Wl,-framework,Metal") + else() + list(APPEND EXTRA_LDFLAGS "-Wl,-weak_framework,Metal") + endif() + endif() + if(SDL_FRAMEWORK_OPENGLES) + list(APPEND EXTRA_LDFLAGS "-Wl,-framework,OpenGLES") + endif() + if(SDL_FRAMEWORK_QUARTZCORE) + if(IOS OR TVOS) + list(APPEND EXTRA_LDFLAGS "-Wl,-framework,QuartzCore") + else() + list(APPEND EXTRA_LDFLAGS "-Wl,-weak_framework,QuartzCore") + endif() + endif() + if(SDL_FRAMEWORK_UIKIT) + list(APPEND EXTRA_LDFLAGS "-Wl,-framework,UIKit") + endif() + if(SDL_FRAMEWORK_COREHAPTICS) + find_library(COREHAPTICS CoreHaptics) + if(COREHAPTICS) + list(APPEND EXTRA_LDFLAGS "-Wl,-weak_framework,CoreHaptics") + endif() + endif() + + CheckPTHREAD() + +elseif(HAIKU) + if(SDL_AUDIO) + set(SDL_AUDIO_DRIVER_HAIKU 1) + file(GLOB HAIKU_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/haiku/*.cc) + list(APPEND SOURCE_FILES ${HAIKU_AUDIO_SOURCES}) + set(HAVE_SDL_AUDIO TRUE) + endif() + + if(SDL_JOYSTICK) + set(SDL_JOYSTICK_HAIKU 1) + file(GLOB HAIKU_JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/haiku/*.cc) + list(APPEND SOURCE_FILES ${HAIKU_JOYSTICK_SOURCES}) + set(HAVE_SDL_JOYSTICK TRUE) + endif() + + if(SDL_MISC) + file(GLOB MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/haiku/*.cc) + list(APPEND SOURCE_FILES ${MISC_SOURCES}) + set(HAVE_SDL_MISC TRUE) + endif() + + if(SDL_VIDEO) + set(SDL_VIDEO_DRIVER_HAIKU 1) + file(GLOB HAIKUVIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/haiku/*.cc) + list(APPEND SOURCE_FILES ${HAIKUVIDEO_SOURCES}) + set(HAVE_SDL_VIDEO TRUE) + + if(SDL_OPENGL) + # TODO: Use FIND_PACKAGE(OpenGL) instead + set(SDL_VIDEO_OPENGL 1) + set(SDL_VIDEO_OPENGL_HAIKU 1) + set(SDL_VIDEO_RENDER_OGL 1) + list(APPEND EXTRA_LIBS GL) + set(HAVE_OPENGL TRUE) + endif() + endif() + + if(SDL_FILESYSTEM) + set(SDL_FILESYSTEM_HAIKU 1) + file(GLOB FILESYSTEM_SOURCES ${SDL2_SOURCE_DIR}/src/filesystem/haiku/*.cc) + list(APPEND SOURCE_FILES ${FILESYSTEM_SOURCES}) + set(HAVE_SDL_FILESYSTEM TRUE) + endif() + + if(SDL_TIMERS) + set(SDL_TIMER_HAIKU 1) + file(GLOB TIMER_SOURCES ${SDL2_SOURCE_DIR}/src/timer/haiku/*.c) + list(APPEND SOURCE_FILES ${TIMER_SOURCES}) + set(HAVE_SDL_TIMERS TRUE) + endif() + + if(SDL_POWER) + set(SDL_POWER_HAIKU 1) + file(GLOB HAIKU_POWER_SOURCES ${SDL2_SOURCE_DIR}/src/power/haiku/*.c) + list(APPEND SOURCE_FILES ${HAIKU_POWER_SOURCES}) + set(HAVE_SDL_POWER TRUE) + endif() + + if(SDL_LOCALE) + file(GLOB LOCALE_SOURCES ${SDL2_SOURCE_DIR}/src/locale/haiku/*.cc) + list(APPEND SOURCE_FILES ${LOCALE_SOURCES}) + set(HAVE_SDL_LOCALE TRUE) + endif() + + file(GLOB MAIN_SOURCES ${SDL2_SOURCE_DIR}/src/main/haiku/*.cc) + list(APPEND SOURCE_FILES ${MAIN_SOURCES}) + + CheckPTHREAD() + list(APPEND EXTRA_LIBS root be media game device textencoding) + +elseif(RISCOS) + if(SDL_MISC) + file(GLOB MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/riscos/*.c) + list(APPEND SOURCE_FILES ${MISC_SOURCES}) + set(HAVE_SDL_MISC TRUE) + endif() + + if(SDL_VIDEO) + set(SDL_VIDEO_DRIVER_RISCOS 1) + file(GLOB RISCOSVIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/riscos/*.c) + list(APPEND SOURCE_FILES ${RISCOSVIDEO_SOURCES}) + set(HAVE_SDL_VIDEO TRUE) + endif() + + if(SDL_FILESYSTEM) + set(SDL_FILESYSTEM_RISCOS 1) + file(GLOB FILESYSTEM_SOURCES ${SDL2_SOURCE_DIR}/src/filesystem/riscos/*.c) + list(APPEND SOURCE_FILES ${FILESYSTEM_SOURCES}) + set(HAVE_SDL_FILESYSTEM TRUE) + endif() + + if(SDL_TIMERS) + set(SDL_TIMER_UNIX 1) + file(GLOB TIMER_SOURCES ${SDL2_SOURCE_DIR}/src/timer/unix/*.c) + list(APPEND SOURCE_FILES ${TIMER_SOURCES}) + set(HAVE_SDL_TIMERS TRUE) + + if(SDL_CLOCK_GETTIME) + set(HAVE_CLOCK_GETTIME 1) + endif() + endif() + + CheckPTHREAD() + + if(SDL_AUDIO) + CheckOSS() + endif() + +elseif(VITA) + # SDL_spinlock.c Needs to be compiled in ARM mode. + cmake_push_check_state(RESET) + set(CMAKE_REQUIRED_FLAGS "-Werror=unused-command-line-argument") + check_c_compiler_flag(-marm HAVE_ARM_MODE) + if(HAVE_ARM_MODE) + set_property(SOURCE "${SDL2_SOURCE_DIR}/src/atomic/SDL_spinlock.c" APPEND_STRING PROPERTY COMPILE_FLAGS " -marm") + endif() + cmake_pop_check_state() + + if(SDL_MISC) + file(GLOB MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/vita/*.c) + list(APPEND SOURCE_FILES ${MISC_SOURCES}) + set(HAVE_SDL_MISC TRUE) + endif() + + if(SDL_AUDIO) + set(SDL_AUDIO_DRIVER_VITA 1) + file(GLOB VITA_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/vita/*.c) + list(APPEND SOURCE_FILES ${VITA_AUDIO_SOURCES}) + set(HAVE_SDL_AUDIO TRUE) + endif() + if(SDL_FILESYSTEM) + set(SDL_FILESYSTEM_VITA 1) + file(GLOB VITA_FILESYSTEM_SOURCES ${SDL2_SOURCE_DIR}/src/filesystem/vita/*.c) + list(APPEND SOURCE_FILES ${VITA_FILESYSTEM_SOURCES}) + set(HAVE_SDL_FILESYSTEM TRUE) + endif() + if(SDL_JOYSTICK) + set(SDL_JOYSTICK_VITA 1) + file(GLOB VITA_JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/vita/*.c) + list(APPEND SOURCE_FILES ${VITA_JOYSTICK_SOURCES}) + set(HAVE_SDL_JOYSTICK TRUE) + endif() + if(SDL_POWER) + set(SDL_POWER_VITA 1) + file(GLOB VITA_POWER_SOURCES ${SDL2_SOURCE_DIR}/src/power/vita/*.c) + list(APPEND SOURCE_FILES ${VITA_POWER_SOURCES}) + set(HAVE_SDL_POWER TRUE) + endif() + if(SDL_THREADS) + set(SDL_THREAD_VITA 1) + list(APPEND SOURCE_FILES + ${SDL2_SOURCE_DIR}/src/thread/vita/SDL_sysmutex.c + ${SDL2_SOURCE_DIR}/src/thread/vita/SDL_syssem.c + ${SDL2_SOURCE_DIR}/src/thread/vita/SDL_systhread.c + ${SDL2_SOURCE_DIR}/src/thread/generic/SDL_syscond.c + ${SDL2_SOURCE_DIR}/src/thread/generic/SDL_systls.c) + set(HAVE_SDL_THREADS TRUE) + endif() + if(SDL_LOCALE) + file(GLOB LOCALE_SOURCES ${SDL2_SOURCE_DIR}/src/locale/vita/*.c) + list(APPEND SOURCE_FILES ${LOCALE_SOURCES}) + set(HAVE_SDL_LOCALE TRUE) + endif() + if(SDL_TIMERS) + set(SDL_TIMER_VITA 1) + file(GLOB TIMER_SOURCES ${SDL2_SOURCE_DIR}/src/timer/vita/*.c) + list(APPEND SOURCE_FILES ${TIMER_SOURCES}) + set(HAVE_SDL_TIMERS TRUE) + endif() + if(SDL_SENSOR) + set(SDL_SENSOR_VITA 1) + set(HAVE_SDL_SENSORS TRUE) + file(GLOB VITA_SENSOR_SOURCES ${SDL2_SOURCE_DIR}/src/sensor/vita/*.c) + list(APPEND SOURCE_FILES ${VITA_SENSOR_SOURCES}) + endif() + if(SDL_VIDEO) + set(SDL_VIDEO_DRIVER_VITA 1) + file(GLOB VITA_VIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/vita/*.c) + list(APPEND SOURCE_FILES ${VITA_VIDEO_SOURCES}) + set(HAVE_SDL_VIDEO TRUE) + + if(VIDEO_VITA_PIB) + check_include_file(pib.h HAVE_PIGS_IN_BLANKET_H) + + if(HAVE_PIGS_IN_BLANKET_H) + set(SDL_VIDEO_OPENGL_ES2 1) + list(APPEND EXTRA_LIBS + pib + libScePiglet_stub_weak + taihen_stub_weak + SceShaccCg_stub_weak + ) + set(HAVE_VIDEO_VITA_PIB ON) + set(SDL_VIDEO_VITA_PIB 1) + else() + set(HAVE_VIDEO_VITA_PIB OFF) + endif() + endif() + + if(VIDEO_VITA_PVR) + check_include_file(gpu_es4/psp2_pvr_hint.h HAVE_PVR_H) + if(HAVE_PVR_H) + target_compile_definitions(sdl-build-options INTERFACE "-D__psp2__") + set(SDL_VIDEO_OPENGL_EGL 1) + set(HAVE_OPENGLES TRUE) + set(SDL_VIDEO_OPENGL_ES 1) + set(SDL_VIDEO_RENDER_OGL_ES 1) + set(SDL_VIDEO_OPENGL_ES2 1) + set(SDL_VIDEO_RENDER_OGL_ES2 1) + + list(APPEND EXTRA_LIBS + libgpu_es4_ext_stub_weak + libIMGEGL_stub_weak + SceIme_stub + ) + + set(HAVE_VIDEO_VITA_PVR ON) + set(SDL_VIDEO_VITA_PVR 1) + + if(SDL_OPENGL) + check_include_file(gl4esinit.h HAVE_GL4ES_H) + if(HAVE_GL4ES_H) + set(HAVE_OPENGL TRUE) + set(SDL_VIDEO_OPENGL 1) + set(SDL_VIDEO_RENDER_OGL 1) + list(APPEND EXTRA_LIBS libGL_stub) + set(SDL_VIDEO_VITA_PVR_OGL 1) + endif() + endif() + + else() + set(HAVE_VIDEO_VITA_PVR OFF) + endif() + endif() + + set(SDL_VIDEO_RENDER_VITA_GXM 1) + + list(APPEND EXTRA_LIBS + SceGxm_stub + SceDisplay_stub + SceCtrl_stub + SceAppMgr_stub + SceAppUtil_stub + SceAudio_stub + SceAudioIn_stub + SceSysmodule_stub + SceDisplay_stub + SceCtrl_stub + SceIofilemgr_stub + SceCommonDialog_stub + SceTouch_stub + SceHid_stub + SceMotion_stub + ScePower_stub + SceProcessmgr_stub + m + ) + endif() + + set(HAVE_ARMSIMD TRUE) +# set(SDL_ARM_SIMD_BLITTERS 1) +# file(GLOB ARMSIMD_SOURCES ${SDL2_SOURCE_DIR}/src/video/arm/pixman-arm-simd*.S) +# list(APPEND SOURCE_FILES ${ARMSIMD_SOURCES}) + + set(HAVE_ARMNEON TRUE) +# set(SDL_ARM_NEON_BLITTERS 1) +# file(GLOB ARMNEON_SOURCES ${SDL2_SOURCE_DIR}/src/video/arm/pixman-arm-neon*.S) +# list(APPEND SOURCE_FILES ${ARMNEON_SOURCES}) + +# set_property(SOURCE ${SDL2_SOURCE_DIR}/src/video/arm/pixman-arm-simd-asm.S PROPERTY LANGUAGE C) +# set_property(SOURCE ${SDL2_SOURCE_DIR}/src/video/arm/pixman-arm-neon-asm.S PROPERTY LANGUAGE C) + + target_compile_definitions(sdl-build-options INTERFACE "-D__VITA__") + +# CheckPTHREAD() + +elseif(PSP) + file(GLOB PSP_MAIN_SOURCES ${SDL2_SOURCE_DIR}/src/main/psp/*.c) + list(APPEND SDLMAIN_SOURCES ${PSP_MAIN_SOURCES}) + + if(SDL_AUDIO) + set(SDL_AUDIO_DRIVER_PSP 1) + file(GLOB PSP_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/psp/*.c) + list(APPEND SOURCE_FILES ${PSP_AUDIO_SOURCES}) + set(HAVE_SDL_AUDIO TRUE) + endif() + if(SDL_FILESYSTEM) + set(SDL_FILESYSTEM_PSP 1) + file(GLOB PSP_FILESYSTEM_SOURCES ${SDL2_SOURCE_DIR}/src/filesystem/psp/*.c) + list(APPEND SOURCE_FILES ${PSP_FILESYSTEM_SOURCES}) + set(HAVE_SDL_FILESYSTEM TRUE) + endif() + if(SDL_JOYSTICK) + set(SDL_JOYSTICK_PSP 1) + file(GLOB PSP_JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/psp/*.c) + list(APPEND SOURCE_FILES ${PSP_JOYSTICK_SOURCES}) + set(HAVE_SDL_JOYSTICK TRUE) + endif() + if(SDL_POWER) + set(SDL_POWER_PSP 1) + file(GLOB PSP_POWER_SOURCES ${SDL2_SOURCE_DIR}/src/power/psp/*.c) + list(APPEND SOURCE_FILES ${PSP_POWER_SOURCES}) + set(HAVE_SDL_POWER TRUE) + endif() + if(SDL_THREADS) + set(SDL_THREAD_PSP 1) + file(GLOB PSP_THREAD_SOURCES + ${SDL2_SOURCE_DIR}/src/thread/generic/SDL_systls.c + ${SDL2_SOURCE_DIR}/src/thread/generic/SDL_syscond.c + ${SDL2_SOURCE_DIR}/src/thread/psp/*.c) + list(APPEND SOURCE_FILES ${PSP_THREAD_SOURCES}) + set(HAVE_SDL_THREADS TRUE) + endif() + if(SDL_TIMERS) + set(SDL_TIMER_PSP 1) + file(GLOB PSP_TIMER_SOURCES ${SDL2_SOURCE_DIR}/src/timer/psp/*.c) + list(APPEND SOURCE_FILES ${PSP_TIMER_SOURCES}) + set(HAVE_SDL_TIMERS TRUE) + endif() + if(SDL_VIDEO) + set(SDL_VIDEO_DRIVER_PSP 1) + set(SDL_VIDEO_RENDER_PSP 1) + file(GLOB PSP_VIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/psp/*.c) + list(APPEND SOURCE_FILES ${PSP_VIDEO_SOURCES}) + set(SDL_VIDEO_OPENGL 1) + set(HAVE_SDL_VIDEO TRUE) + endif() + + list(APPEND EXTRA_LIBS + GL + pspvram + pspaudio + pspvfpu + pspdisplay + pspgu + pspge + psphprm + pspctrl + psppower + ) + if(NOT SDL2_DISABLE_SDL2MAIN) + list(INSERT SDL_LIBS 0 "-lSDL2main") + endif() + +elseif(PS2) + list(APPEND EXTRA_CFLAGS "-DPS2" "-D__PS2__" "-I$ENV{PS2SDK}/ports/include" "-I$ENV{PS2DEV}/gsKit/include") + + file(GLOB PS2_MAIN_SOURCES ${SDL2_SOURCE_DIR}/src/main/ps2/*.c) + set(SDLMAIN_SOURCES ${SDLMAIN_SOURCES} ${PS2_MAIN_SOURCES}) + + if(SDL_AUDIO) + set(SDL_AUDIO_DRIVER_PS2 1) + file(GLOB PS2_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/ps2/*.c) + set(SOURCE_FILES ${SOURCE_FILES} ${PS2_AUDIO_SOURCES}) + set(HAVE_SDL_AUDIO TRUE) + endif() + if(SDL_FILESYSTEM) + set(SDL_FILESYSTEM_PS2 1) + file(GLOB PS2_FILESYSTEM_SOURCES ${SDL2_SOURCE_DIR}/src/filesystem/ps2/*.c) + list(APPEND SOURCE_FILES ${PS2_FILESYSTEM_SOURCES}) + set(HAVE_SDL_FILESYSTEM TRUE) + endif() + if(SDL_JOYSTICK) + set(SDL_JOYSTICK_PS2 1) + file(GLOB PS2_JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/ps2/*.c) + list(APPEND SOURCE_FILES ${PS2_JOYSTICK_SOURCES}) + set(HAVE_SDL_JOYSTICK TRUE) + endif() + if(SDL_THREADS) + set(SDL_THREAD_PS2 1) + file(GLOB PS2_THREAD_SOURCES + ${SDL2_SOURCE_DIR}/src/thread/generic/SDL_systls.c + ${SDL2_SOURCE_DIR}/src/thread/generic/SDL_sysmutex.c + ${SDL2_SOURCE_DIR}/src/thread/generic/SDL_syscond.c + ${SDL2_SOURCE_DIR}/src/thread/ps2/*.c) + list(APPEND SOURCE_FILES ${PS2_THREAD_SOURCES}) + set(HAVE_SDL_THREADS TRUE) + endif() + if(SDL_TIMERS) + set(SDL_TIMER_PS2 1) + file(GLOB PS2_TIMER_SOURCES ${SDL2_SOURCE_DIR}/src/timer/ps2/*.c) + list(APPEND SOURCE_FILES ${PS2_TIMER_SOURCES}) + set(HAVE_SDL_TIMERS TRUE) + endif() + if(SDL_VIDEO) + set(SDL_VIDEO_DRIVER_PS2 1) + set(SDL_VIDEO_RENDER_PS2 1) + file(GLOB PS2_VIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/ps2/*.c ${SDL2_SOURCE_DIR}/src/render/ps2/*.c) + list(APPEND SOURCE_FILES ${PS2_VIDEO_SOURCES}) + set(SDL_VIDEO_OPENGL 0) + set(HAVE_SDL_VIDEO TRUE) + endif() + + list(APPEND EXTRA_LIBS + patches + gskit + dmakit + ps2_drivers + ) + +elseif(OS2) + list(APPEND EXTRA_CFLAGS "-DOS2EMX_PLAIN_CHAR") + + file(GLOB CORE_SOURCES ${SDL2_SOURCE_DIR}/src/core/os2/*.c) + list(APPEND SOURCE_FILES ${CORE_SOURCES}) + if(NOT (HAVE_ICONV AND HAVE_ICONV_H)) + file(GLOB CORE_SOURCES ${SDL2_SOURCE_DIR}/src/core/os2/geniconv/*.c) + list(APPEND SOURCE_FILES ${CORE_SOURCES}) + endif() + + if(SDL_THREADS) + set(SDL_THREAD_OS2 1) + file(GLOB OS2_THREAD_SOURCES ${SDL2_SOURCE_DIR}/src/thread/os2/*.c) + list(APPEND SOURCE_FILES ${OS2_THREAD_SOURCES}) + set(HAVE_SDL_THREADS TRUE) + endif() + + if(SDL_TIMERS) + set(SDL_TIMER_UNIX 1) + file(GLOB OS2_TIMER_SOURCES ${SDL2_SOURCE_DIR}/src/timer/os2/*.c) + list(APPEND SOURCE_FILES ${OS2_TIMER_SOURCES}) + set(HAVE_SDL_TIMERS TRUE) + endif() + + if(SDL_LOADSO) + set(SDL_LOADSO_OS2 1) + file(GLOB OS2_LOADSO_SOURCES ${SDL2_SOURCE_DIR}/src/loadso/os2/*.c) + list(APPEND SOURCE_FILES ${OS2_LOADSO_SOURCES}) + set(HAVE_SDL_LOADSO TRUE) + endif() + + if(SDL_FILESYSTEM) + set(SDL_FILESYSTEM_OS2 1) + file(GLOB FILESYSTEM_SOURCES ${SDL2_SOURCE_DIR}/src/filesystem/os2/*.c) + list(APPEND SOURCE_FILES ${FILESYSTEM_SOURCES}) + set(HAVE_SDL_FILESYSTEM TRUE) + endif() + + if(SDL_LOCALE) + file(GLOB LOCALE_SOURCES ${SDL2_SOURCE_DIR}/src/locale/unix/*.c) + list(APPEND SOURCE_FILES ${LOCALE_SOURCES}) + set(HAVE_SDL_LOCALE TRUE) + endif() + + if(SDL_VIDEO) + set(SDL_VIDEO_DRIVER_OS2 1) + file(GLOB OS2_VIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/os2/*.c) + list(APPEND SOURCE_FILES ${OS2_VIDEO_SOURCES}) + set(HAVE_SDL_VIDEO TRUE) + endif() + + if(SDL_AUDIO) + set(SDL_AUDIO_DRIVER_OS2 1) + file(GLOB OS2_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/os2/*.c) + list(APPEND SOURCE_FILES ${OS2_AUDIO_SOURCES}) + set(HAVE_SDL_AUDIO TRUE) + list(APPEND EXTRA_LIBS mmpm2) + endif() + + if(SDL_JOYSTICK) + set(SDL_JOYSTICK_OS2 1) + file(GLOB OS2_JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/os2/*.c) + list(APPEND SOURCE_FILES ${OS2_JOYSTICK_SOURCES}) + set(HAVE_SDL_JOYSTICK TRUE) + endif() + + if(SDL_HIDAPI) + CheckHIDAPI() + endif() + +elseif(N3DS) + file(GLOB N3DS_MAIN_SOURCES ${SDL2_SOURCE_DIR}/src/main/n3ds/*.c) + set(SDLMAIN_SOURCES ${SDLMAIN_SOURCES} ${N3DS_MAIN_SOURCES}) + + if(SDL_AUDIO) + set(SDL_AUDIO_DRIVER_N3DS 1) + file(GLOB N3DS_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/n3ds/*.c) + list(APPEND SOURCE_FILES ${N3DS_AUDIO_SOURCES}) + set(HAVE_SDL_AUDIO TRUE) + endif() + + if(SDL_FILESYSTEM) + set(SDL_FILESYSTEM_N3DS 1) + file(GLOB N3DS_FILESYSTEM_SOURCES ${SDL2_SOURCE_DIR}/src/filesystem/n3ds/*.c) + list(APPEND SOURCE_FILES ${N3DS_FILESYSTEM_SOURCES}) + set(HAVE_SDL_FILESYSTEM TRUE) + endif() + + if(SDL_JOYSTICK) + set(SDL_JOYSTICK_N3DS 1) + file(GLOB N3DS_JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/n3ds/*.c) + list(APPEND SOURCE_FILES ${N3DS_JOYSTICK_SOURCES}) + set(HAVE_SDL_JOYSTICK TRUE) + endif() + + if(SDL_POWER) + set(SDL_POWER_N3DS 1) + file(GLOB N3DS_POWER_SOURCES ${SDL2_SOURCE_DIR}/src/power/n3ds/*.c) + list(APPEND SOURCE_FILES ${N3DS_POWER_SOURCES}) + set(HAVE_SDL_POWER TRUE) + endif() + + if(SDL_THREADS) + set(SDL_THREAD_N3DS 1) + file(GLOB N3DS_THREAD_SOURCES ${SDL2_SOURCE_DIR}/src/thread/n3ds/*.c) + list(APPEND SOURCE_FILES ${N3DS_THREAD_SOURCES} + ${SDL2_SOURCE_DIR}/src/thread/generic/SDL_systls.c + ${SDL2_SOURCE_DIR}/src/thread/generic/SDL_syscond.c) + set(HAVE_SDL_THREADS TRUE) + endif() + + if(SDL_TIMERS) + set(SDL_TIMER_N3DS 1) + file(GLOB N3DS_TIMER_SOURCES ${SDL2_SOURCE_DIR}/src/timer/n3ds/*.c) + list(APPEND SOURCE_FILES ${N3DS_TIMER_SOURCES}) + set(HAVE_SDL_TIMERS TRUE) + endif() + + if(SDL_SENSOR) + set(SDL_SENSOR_N3DS 1) + file(GLOB N3DS_SENSOR_SOURCES ${SDL2_SOURCE_DIR}/src/sensor/n3ds/*.c) + list(APPEND SOURCE_FILES ${N3DS_SENSOR_SOURCES}) + set(HAVE_SDL_SENSORS TRUE) + endif() + + if(SDL_VIDEO) + set(SDL_VIDEO_DRIVER_N3DS 1) + file(GLOB N3DS_VIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/n3ds/*.c) + list(APPEND SOURCE_FILES ${N3DS_VIDEO_SOURCES}) + set(HAVE_SDL_VIDEO TRUE) + endif() + + if(SDL_LOCALE) + file(GLOB N3DS_LOCALE_SOURCES ${SDL2_SOURCE_DIR}/src/locale/n3ds/*.c) + list(APPEND SOURCE_FILES ${N3DS_LOCALE_SOURCES}) + set(HAVE_SDL_LOCALE TRUE) + endif() + + # Requires the n3ds file implementation + if(SDL_FILE) + file(GLOB N3DS_FILE_SOURCES ${SDL2_SOURCE_DIR}/src/file/n3ds/*.c) + list(APPEND SOURCE_FILES ${N3DS_FILE_SOURCES}) + set(HAVE_SDL_FILE TRUE) + else() + message_error("SDL_FILE must be enabled to build on N3DS") + endif() + + if(NOT SDL2_DISABLE_SDL2MAIN) + list(INSERT SDL_LIBS 0 "-lSDL2main") + endif() + + foreach(lib ${CMAKE_C_STANDARD_LIBRARIES}) + if(lib MATCHES "^-l") + string(SUBSTRING "${lib}" 2 -1 lib) + endif() + list(APPEND EXTRA_LIBS ${lib}) + endforeach() +endif() + +if(HAVE_VULKAN AND NOT SDL_LOADSO) + message(STATUS "Vulkan support is available, but disabled because there's no loadso.") + set(HAVE_VULKAN FALSE) + set(SDL_VIDEO_VULKAN 0) +endif() + +# Platform-independent options +CheckLibSampleRate() + +# Dummies +# configure.ac does it differently: +# if not have X +# if enable_X { SDL_X_DISABLED = 1 } +# [add dummy sources] +# so it always adds a dummy, without checking, if it was actually requested. +# This leads to missing internal references on building, since the +# src/X/*.c does not get included. +if(NOT HAVE_SDL_AUDIO) + set(SDL_AUDIO_DRIVER_DUMMY 1) + file(GLOB AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/dummy/*.c) + list(APPEND SOURCE_FILES ${AUDIO_SOURCES}) +endif() +if(NOT HAVE_SDL_VIDEO) + set(SDL_VIDEO_DRIVER_DUMMY 1) + file(GLOB VIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/dummy/*.c) + list(APPEND SOURCE_FILES ${VIDEO_SOURCES}) +endif() +if(NOT HAVE_SDL_JOYSTICK) + set(SDL_JOYSTICK_DUMMY 1) + file(GLOB JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/dummy/*.c) + list(APPEND SOURCE_FILES ${JOYSTICK_SOURCES}) +endif() +if(NOT HAVE_SDL_HAPTIC) + set(SDL_HAPTIC_DUMMY 1) + file(GLOB HAPTIC_SOURCES ${SDL2_SOURCE_DIR}/src/haptic/dummy/*.c) + list(APPEND SOURCE_FILES ${HAPTIC_SOURCES}) +endif() +if(NOT HAVE_SDL_SENSORS) + set(SDL_SENSOR_DUMMY 1) + file(GLOB SENSORS_SOURCES ${SDL2_SOURCE_DIR}/src/sensor/dummy/*.c) + list(APPEND SOURCE_FILES ${SENSORS_SOURCES}) +endif() +if(NOT HAVE_SDL_LOADSO) + set(SDL_LOADSO_DUMMY 1) + file(GLOB LOADSO_SOURCES ${SDL2_SOURCE_DIR}/src/loadso/dummy/*.c) + list(APPEND SOURCE_FILES ${LOADSO_SOURCES}) +endif() +if(NOT HAVE_SDL_FILESYSTEM) + set(SDL_FILESYSTEM_DUMMY 1) + file(GLOB FILESYSTEM_SOURCES ${SDL2_SOURCE_DIR}/src/filesystem/dummy/*.c) + list(APPEND SOURCE_FILES ${FILESYSTEM_SOURCES}) +endif() +if(NOT HAVE_SDL_LOCALE) + set(SDL_LOCALE_DUMMY 1) + file(GLOB LOCALE_SOURCES ${SDL2_SOURCE_DIR}/src/locale/dummy/*.c) + list(APPEND SOURCE_FILES ${LOCALE_SOURCES}) +endif() +if(NOT HAVE_SDL_MISC) + set(SDL_MISC_DUMMY 1) + file(GLOB MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/dummy/*.c) + list(APPEND SOURCE_FILES ${MISC_SOURCES}) +endif() + +# We always need to have threads and timers around +if(NOT HAVE_SDL_THREADS) + # The emscripten platform has been carefully vetted to work without threads + if (EMSCRIPTEN) + set(SDL_THREADS_DISABLED 1) + file(GLOB THREADS_SOURCES ${SDL2_SOURCE_DIR}/src/thread/generic/*.c) + list(APPEND SOURCE_FILES ${THREADS_SOURCES}) + else() + message_error("Threads are needed by many SDL subsystems and may not be disabled") + endif() +endif() +if(NOT HAVE_SDL_TIMERS) + set(SDL_TIMER_DUMMY 1) + file(GLOB TIMER_SOURCES ${SDL2_SOURCE_DIR}/src/timer/dummy/*.c) + list(APPEND SOURCE_FILES ${TIMER_SOURCES}) +endif() + +if(NOT SDLMAIN_SOURCES) + file(GLOB SDLMAIN_SOURCES ${SDL2_SOURCE_DIR}/src/main/dummy/*.c) +endif() + +if(SDL_WERROR) + if(MSVC) + cmake_push_check_state(RESET) + check_c_compiler_flag(/WX HAVE_WX) + if(HAVE_WX) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /WX") + endif() + elseif(USE_GCC OR USE_CLANG OR USE_INTELCC) + cmake_push_check_state(RESET) + check_c_compiler_flag(-Werror HAVE_WERROR) + if(HAVE_WERROR) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror") + set(CMAKE_OBJC_FLAGS "${CMAKE_OBJC_FLAGS} -Werror") + endif() + cmake_pop_check_state() + endif() +endif() + +# Append the -MMD -MT flags +# if(DEPENDENCY_TRACKING) +# if(COMPILER_IS_GNUCC) +# set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -MMD -MT \$@") +# endif() +# endif() + +# config variables may contain generator expression, so we need to generate SDL_config.h in 2 steps: +# 1. replace all `#cmakedefine`'s and `@abc@` +configure_file("${SDL2_SOURCE_DIR}/include/SDL_config.h.cmake" + "${SDL2_BINARY_DIR}/SDL_config.h.intermediate") +# 2. Create the "include-config-${CMAKE_BUILD_TYPE}" folder (fails on older CMake versions when it does not exist) +string(TOLOWER "${CMAKE_BUILD_TYPE}" lower_build_type) +execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CURRENT_BINARY_DIR}/include-config-${lower_build_type}") +# 3. generate SDL_config in an build_type-dependent folder (which should be first in the include search path) +file(GENERATE + OUTPUT "${SDL2_BINARY_DIR}/include-config-$>/SDL2/SDL_config.h" + INPUT "${SDL2_BINARY_DIR}/SDL_config.h.intermediate") + +# Prepare the flags and remove duplicates +if(EXTRA_LDFLAGS) + list(REMOVE_DUPLICATES EXTRA_LDFLAGS) +endif() +if(EXTRA_LIBS) + list(REMOVE_DUPLICATES EXTRA_LIBS) +endif() +if(EXTRA_CFLAGS) + list(REMOVE_DUPLICATES EXTRA_CFLAGS) +endif() +listtostr(EXTRA_CFLAGS _EXTRA_CFLAGS) +set(EXTRA_CFLAGS ${_EXTRA_CFLAGS}) + +if(USE_GCC OR USE_CLANG) + string(REGEX REPLACE "(^| )-I" "\\1 -isystem" EXTRA_CFLAGS "${EXTRA_CFLAGS}") +endif() + +# Compat helpers for the configuration files + +if(EXISTS "${PROJECT_SOURCE_DIR}/VERSION.txt") + file(READ "${PROJECT_SOURCE_DIR}/VERSION.txt" SDL_SOURCE_VERSION) + string(STRIP "${SDL_SOURCE_VERSION}" SDL_SOURCE_VERSION) +endif() + +find_package(Git) +if(Git_FOUND) + execute_process(COMMAND + "${GIT_EXECUTABLE}" describe --always --tags --long + WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" + RESULT_VARIABLE GIT_REVISION_STATUS + OUTPUT_VARIABLE GIT_REVISION + ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) +else() + set(GIT_REVISION_STATUS 1) + set(GIT_REVISION "") +endif() + +if(SDL_SOURCE_VERSION) + set(SDL_REVISION "SDL-${SDL_SOURCE_VERSION}") +elseif(GIT_REVISION_STATUS EQUAL 0) + if(GIT_REVISION MATCHES "^[0-9a-f]+$") + # Just a truncated sha1, so prefix it with the version number + set(SDL_REVISION "SDL-${SDL_VERSION}-g${GIT_REVISION}") + else() + # e.g. release-2.24.0-542-g96361fc47 + set(SDL_REVISION "SDL-${GIT_REVISION}") + endif() +else() + set(SDL_REVISION "SDL-${SDL_VERSION}-no-vcs") +endif() + +configure_file("${SDL2_SOURCE_DIR}/include/SDL_revision.h.cmake" + "${SDL2_BINARY_DIR}/include/SDL2/SDL_revision.h") + +# Copy all non-generated headers to "${SDL2_BINARY_DIR}/include/SDL2" +# This is done to avoid the inclusion of a pre-generated SDL_config.h +file(GLOB SDL2_INCLUDE_FILES ${SDL2_SOURCE_DIR}/include/*.h) +set(SDL2_COPIED_INCLUDE_FILES) +foreach(_hdr IN LISTS SDL2_INCLUDE_FILES) + if(_hdr MATCHES ".*(SDL_config|SDL_revision).*") + list(REMOVE_ITEM SDL2_INCLUDE_FILES "${_hdr}") + else() + get_filename_component(_name "${_hdr}" NAME) + set(_bin_hdr "${SDL2_BINARY_DIR}/include/SDL2/${_name}") + list(APPEND SDL2_COPIED_INCLUDE_FILES "${_bin_hdr}") + add_custom_command(OUTPUT "${_bin_hdr}" + COMMAND ${CMAKE_COMMAND} -E copy_if_different "${_hdr}" "${_bin_hdr}" + DEPENDS "${_hdr}") + endif() +endforeach() +list(APPEND SDL_GENERATED_HEADERS ${SDL2_COPIED_INCLUDE_FILES}) + +if(CMAKE_STATIC_LIBRARY_PREFIX STREQUAL "" AND CMAKE_STATIC_LIBRARY_SUFFIX STREQUAL ".lib") + # Avoid conflict between the dll import library and the static library + set(sdl_static_libname "SDL2-static") +else() + set(sdl_static_libname "SDL2") +endif() + +# CMAKE_PREFIX_PATH and CMAKE_INSTALL_FULL_BINDIR can be a non-absolute path +# when a master-project does e.g. `set(CMAKE_INSTALL_PREFIX "libs/SDL2" CACHE PATH "prefix" FORCE)`. +if(NOT IS_ABSOLUTE "${CMAKE_INSTALL_PREFIX}") + set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_PREFIX}") +endif() +if(NOT IS_ABSOLUTE "${CMAKE_INSTALL_FULL_BINDIR}") + set(CMAKE_INSTALL_FULL_BINDIR "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_FULL_BINDIR}") +endif() +file(RELATIVE_PATH bin_prefix_relpath "${CMAKE_INSTALL_FULL_BINDIR}" "${CMAKE_INSTALL_PREFIX}") + +set(prefix ${CMAKE_INSTALL_PREFIX}) +set(exec_prefix "\${prefix}") +set(libdir "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}") +set(bindir "\${exec_prefix}/${CMAKE_INSTALL_BINDIR}") +set(includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}") +if(SDL_STATIC) + set(ENABLE_STATIC_TRUE "") + set(ENABLE_STATIC_FALSE "#") +else() + set(ENABLE_STATIC_TRUE "#") + set(ENABLE_STATIC_FALSE "") +endif() +if(SDL_SHARED) + set(PKGCONFIG_LIBS_PRIV " +Libs.private:") + set(ENABLE_SHARED_TRUE "") + set(ENABLE_SHARED_FALSE "#") +else() + set(PKGCONFIG_LIBS_PRIV "") + set(ENABLE_SHARED_TRUE "#") + set(ENABLE_SHARED_FALSE "") +endif() + +# Clean up the different lists +listtostr(EXTRA_LIBS _EXTRA_LIBS "-l") +set(SDL_STATIC_LIBS ${SDL_LIBS} ${EXTRA_LDFLAGS} ${_EXTRA_LIBS}) +list(REMOVE_DUPLICATES SDL_STATIC_LIBS) +listtostr(SDL_STATIC_LIBS _SDL_STATIC_LIBS) +set(SDL_STATIC_LIBS ${_SDL_STATIC_LIBS}) +listtostr(SDL_LIBS _SDL_LIBS) +set(SDL_LIBS ${_SDL_LIBS}) +listtostr(SDL_CFLAGS _SDL_CFLAGS "") +set(SDL_CFLAGS ${_SDL_CFLAGS}) +string(REGEX REPLACE "-lSDL2( |$)" "-l${sdl_static_libname} " SDL_STATIC_LIBS "${SDL_STATIC_LIBS}") +if(NOT SDL_SHARED) + string(REGEX REPLACE "-lSDL2( |$)" "-l${sdl_static_libname} " SDL_LIBS "${SDL_LIBS}") +endif() +listtostr(PKGCONFIG_DEPENDS PKGCONFIG_DEPENDS) + +if(SDL_STATIC AND SDL_SHARED AND NOT sdl_static_libname STREQUAL "SDL2") + message(STATUS "\"pkg-config --static --libs sdl2\" will return invalid information") +endif() + +# MESSAGE(STATUS "SDL_LIBS: ${SDL_LIBS}") +# MESSAGE(STATUS "SDL_STATIC_LIBS: ${SDL_STATIC_LIBS}") + +configure_file("${SDL2_SOURCE_DIR}/sdl2.pc.in" + "${SDL2_BINARY_DIR}/sdl2.pc" @ONLY) +configure_file("${SDL2_SOURCE_DIR}/sdl2-config.in" + "${SDL2_BINARY_DIR}/sdl2-config" @ONLY) +configure_file("${SDL2_SOURCE_DIR}/SDL2.spec.in" + "${SDL2_BINARY_DIR}/SDL2.spec" @ONLY) + +macro(check_add_debug_flag FLAG SUFFIX) + check_c_compiler_flag(${FLAG} HAS_C_FLAG_${SUFFIX}) + if (HAS_C_FLAG_${SUFFIX}) + set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${FLAG}") + endif() + + check_cxx_compiler_flag(${FLAG} HAS_CXX_${SUFFIX}) + if (HAS_CXX_${SUFFIX}) + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${FLAG}") + endif() +endmacro() + +macro(asan_check_add_debug_flag ASAN_FLAG) + check_add_debug_flag("-fsanitize=${ASAN_FLAG}" "${ASAN_FLAG}") + if(HAS_C_${ASAN_FLAG} OR HAS_CXX_${ASAN_FLAG}) + set(HAVE_ASAN ON) + endif() +endmacro() + +macro(asan_check_add_debug_flag2 ASAN_FLAG) + # for some sanitize flags we have to manipulate the CMAKE_REQUIRED_LIBRARIES: + # http://cmake.3232098.n2.nabble.com/CHECK-CXX-COMPILER-FLAG-doesn-t-give-correct-result-for-fsanitize-address-tp7600216p7600217.html + + set(FLAG "-fsanitize=${ASAN_FLAG}") + + set (STORED_REQLIBS ${CMAKE_REQUIRED_LIBRARIES}) + set (CMAKE_REQUIRED_LIBRARIES "${FLAG};asan") + check_c_compiler_flag (${FLAG} HAS_C_FLAG_${ASAN_FLAG}) + check_cxx_compiler_flag (${FLAG} HAS_CXX_FLAG_${ASAN_FLAG}) + set (CMAKE_REQUIRED_LIBRARIES ${STORED_REQLIBS}) + + if (HAS_C_FLAG_${ASAN_FLAG}) + set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${FLAG}") + endif() + + if (HAS_CXX_${ASAN_FLAG}) + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${FLAG}") + endif() + + if(HAS_C_${ASAN_FLAG} OR HAS_CXX_${ASAN_FLAG}) + set(HAVE_ASAN ON) + endif() +endmacro() + +# enable AddressSanitizer if supported +if (SDL_ASAN) + asan_check_add_debug_flag2("address") + asan_check_add_debug_flag("bool") + asan_check_add_debug_flag("bounds") + asan_check_add_debug_flag("enum") + asan_check_add_debug_flag("float-cast-overflow") + asan_check_add_debug_flag("float-divide-by-zero") + asan_check_add_debug_flag("nonnull-attribute") + asan_check_add_debug_flag("returns-nonnull-attribute") + asan_check_add_debug_flag("signed-integer-overflow") + asan_check_add_debug_flag("undefined") + asan_check_add_debug_flag("vla-bound") + asan_check_add_debug_flag("leak") + # The object size sanitizer has no effect on unoptimized builds on Clang, + # but causes warnings. + if((NOT USE_CLANG) OR ("${CMAKE_BUILD_TYPE}" STREQUAL "")) + asan_check_add_debug_flag("object-size") + endif() +endif() + +if(SDL_CCACHE AND NOT CMAKE_VERSION VERSION_LESS 3.4) + cmake_minimum_required(VERSION 3.4...3.5) + find_program(CCACHE_BINARY ccache) + if(CCACHE_BINARY) + set(CMAKE_C_COMPILER_LAUNCHER ${CCACHE_BINARY}) + set(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE_BINARY}) + set(CMAKE_OBJC_COMPILER_LAUNCHER ${CCACHE_BINARY}) + set(HAVE_CCACHE ON) + else() + set(HAVE_CCACHE OFF) + endif() +else() + set(HAVE_CCACHE OFF) +endif() + +if(SDL_TESTS) + set(HAVE_TESTS ON) +endif() + +# Create target that collects all all generated include files. +add_custom_target(sdl_headers_copy + DEPENDS ${SDL_GENERATED_HEADERS}) + +##### Info output ##### +message(STATUS "") +message(STATUS "SDL2 was configured with the following options:") +message(STATUS "") +message(STATUS "Platform: ${CMAKE_SYSTEM}") +message(STATUS "64-bit: ${ARCH_64}") +message(STATUS "Compiler: ${CMAKE_C_COMPILER}") +message(STATUS "Revision: ${SDL_REVISION}") +message(STATUS "") +message(STATUS "Subsystems:") +foreach(_SUB ${SDL_SUBSYSTEMS}) + string(TOUPPER ${_SUB} _OPT) + message_bool_option(${_SUB} SDL_${_OPT}) +endforeach() +message(STATUS "") +message(STATUS "Options:") +list(SORT ALLOPTIONS) +foreach(_OPT ${ALLOPTIONS}) + # Get the padding + string(LENGTH ${_OPT} _OPTLEN) + math(EXPR _PADLEN "(${LONGESTOPTIONNAME} + 1) - ${_OPTLEN}") + string(RANDOM LENGTH ${_PADLEN} ALPHABET " " _PADDING) + message_tested_option(${_OPT} ${_PADDING}) +endforeach() +if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") + message(STATUS "") + message(STATUS " CMAKE_C_FLAGS_DEBUG: ${CMAKE_C_FLAGS_DEBUG}") + message(STATUS " CMAKE_CXX_FLAGS_DEBUG: ${CMAKE_CXX_FLAGS_DEBUG}") +endif() +message(STATUS "") +message(STATUS " CFLAGS: ${CMAKE_C_FLAGS}") +message(STATUS " EXTRA_CFLAGS: ${EXTRA_CFLAGS}") +message(STATUS " EXTRA_LDFLAGS: ${EXTRA_LDFLAGS} ${EXTRA_LDFLAGS_BUILD}") +message(STATUS " EXTRA_LIBS: ${EXTRA_LIBS}") +message(STATUS "") +message(STATUS " Build Shared Library: ${SDL_SHARED}") +message(STATUS " Build Static Library: ${SDL_STATIC}") +if(SDL_STATIC) + message(STATUS " Build Static Library with Position Independent Code: ${SDL_STATIC_PIC}") +endif() +message(STATUS "") +if(UNIX) + message(STATUS "If something was not detected, although the libraries") + message(STATUS "were installed, then make sure you have set the") + message(STATUS "CFLAGS and LDFLAGS environment variables correctly.") + message(STATUS "") +endif() + +if(WARN_ABOUT_ARM_SIMD_ASM_MIT) + message(STATUS "") + message(STATUS "SDL is being built with ARM SIMD optimizations, which") + message(STATUS "uses code licensed under the MIT license. If this is a") + message(STATUS "problem, please disable that code by rerunning CMake with:") + message(STATUS "") + message(STATUS " -DSDL_ARMSIMD=OFF") +endif() + +if(WARN_ABOUT_ARM_NEON_ASM_MIT) + message(STATUS "") + message(STATUS "SDL is being built with ARM NEON optimizations, which") + message(STATUS "uses code licensed under the MIT license. If this is a") + message(STATUS "problem, please disable that code by rerunning CMake with:") + message(STATUS "") + message(STATUS " -DSDL_ARMNEON=OFF") +endif() + +# Ensure that the extra cflags are used at compile time +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} ${EXTRA_CFLAGS_BUILD}") + +if(NOT WINDOWS_STORE AND NOT SDL2_DISABLE_SDL2MAIN) + # Build SDLmain + add_library(SDL2main STATIC ${SDLMAIN_SOURCES}) + add_dependencies(SDL2main sdl_headers_copy) + # alias target for in-tree builds + add_library(SDL2::SDL2main ALIAS SDL2main) + target_include_directories(SDL2main BEFORE + PRIVATE "${SDL2_BINARY_DIR}/include" + PRIVATE "${SDL2_BINARY_DIR}/include/SDL2" + PRIVATE "${SDL2_BINARY_DIR}/include-config-$>/SDL2" + ) + target_include_directories(SDL2main PUBLIC "$" $ $) + if (WIN32) + target_link_libraries(SDL2main PRIVATE shell32) + endif() + if(MINGW OR CYGWIN) + if(CMAKE_SIZEOF_VOID_P EQUAL 4) + target_link_libraries(SDL2main PUBLIC "$<$,EXECUTABLE>:-Wl,--undefined=_WinMain@16>") + else() + target_link_libraries(SDL2main PUBLIC "$<$,EXECUTABLE>:-Wl,--undefined=WinMain>") + endif() + endif() + if (NOT ANDROID) + set_target_properties(SDL2main PROPERTIES DEBUG_POSTFIX "${SDL_CMAKE_DEBUG_POSTFIX}") + endif() + set_property(TARGET SDL2main APPEND PROPERTY COMPATIBLE_INTERFACE_STRING "SDL_VERSION") + set_property(TARGET SDL2main PROPERTY INTERFACE_SDL_VERSION "SDL2") +endif() + +if(ANDROID) + target_include_directories(sdl-build-options INTERFACE "${ANDROID_NDK}/sources/android/cpufeatures") +endif() + +if(APPLE) + cmake_push_check_state(RESET) + check_c_compiler_flag(-fobjc-arc COMPILER_SUPPORTS_FOBJC_ARC) + cmake_pop_check_state() + if(NOT COMPILER_SUPPORTS_FOBJC_ARC) + message(FATAL_ERROR "Compiler does not support -fobjc-arc: this is required on Apple platforms") + endif() + target_compile_options(sdl-build-options INTERFACE "-fobjc-arc") +endif() + +if(PS2) + target_compile_options(sdl-build-options INTERFACE "-Wno-error=declaration-after-statement") +endif() + +if(APPLE) + foreach(SOURCE_FILE ${SOURCE_FILES}) + get_filename_component(FILE_EXTENSION ${SOURCE_FILE} EXT) + if(FILE_EXTENSION STREQUAL ".m") + set_property(SOURCE ${SOURCE_FILE} APPEND_STRING PROPERTY COMPILE_FLAGS " -x objective-c") + endif() + endforeach() +endif() + +if(SDL_SHARED) + add_library(SDL2 SHARED ${SOURCE_FILES} ${VERSION_SOURCES}) + add_dependencies(SDL2 sdl_headers_copy) + # alias target for in-tree builds + add_library(SDL2::SDL2 ALIAS SDL2) + set_target_properties(SDL2 PROPERTIES POSITION_INDEPENDENT_CODE TRUE) + set_target_properties(SDL2 PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS FALSE) + if(NOT SDL_LIBC) + if(SDL_CPU_X86) + # FIXME: should be added for all architectures (missing symbols for ARM) + target_link_libraries(SDL2 PRIVATE "-nodefaultlib:MSVCRT") + endif() + if(HAS_Q_NO_USE_LIBIRC) + target_compile_options(SDL2 PRIVATE /Q_no-use-libirc) + endif() + endif() + if(APPLE) + # FIXME: Remove SOVERSION in SDL3 + set_target_properties(SDL2 PROPERTIES + MACOSX_RPATH 1 + SOVERSION 0 + OUTPUT_NAME "SDL2-${LT_RELEASE}") + elseif(UNIX AND NOT ANDROID) + set_target_properties(SDL2 PROPERTIES + VERSION ${LT_VERSION} + SOVERSION ${LT_MAJOR} + OUTPUT_NAME "SDL2-${LT_RELEASE}") + else() + if(WINDOWS OR CYGWIN) + set_target_properties(SDL2 PROPERTIES + DEFINE_SYMBOL DLL_EXPORT) + elseif(OS2) + set_target_properties(SDL2 PROPERTIES + DEFINE_SYMBOL BUILD_SDL) + endif() + set_target_properties(SDL2 PROPERTIES + VERSION ${SDL_VERSION} + SOVERSION ${LT_REVISION} + OUTPUT_NAME "SDL2") + endif() + # Note: The clang toolset for Visual Studio does not support /NODEFAULTLIB. + if(MSVC AND NOT SDL_LIBC AND NOT MSVC_CLANG AND NOT SDL_CPU_ARM32) + # Don't try to link with the default set of libraries. + if(NOT WINDOWS_STORE) + set_property(TARGET SDL2 APPEND_STRING PROPERTY LINK_FLAGS " /NODEFAULTLIB") + endif() + set_property(TARGET SDL2 APPEND_STRING PROPERTY STATIC_LIBRARY_FLAGS " /NODEFAULTLIB") + endif() + # FIXME: if CMAKE_VERSION >= 3.13, use target_link_options for EXTRA_LDFLAGS + target_link_libraries(SDL2 PRIVATE ${EXTRA_LIBS} ${EXTRA_LDFLAGS} ${EXTRA_LDFLAGS_BUILD} ${CMAKE_DEPENDS}) + target_include_directories(SDL2 PUBLIC + "$" + "$" + "$>/SDL2>" + "$" + "$" + ) + # This picks up all the compiler options and such we've accumulated up to here. + target_link_libraries(SDL2 PRIVATE $) + if(MINGW OR CYGWIN) + if(NOT CMAKE_VERSION VERSION_LESS "3.13") + target_link_options(SDL2 PRIVATE -static-libgcc) + endif() + endif() + if(NOT ANDROID) + set_target_properties(SDL2 PROPERTIES DEBUG_POSTFIX "${SDL_CMAKE_DEBUG_POSTFIX}") + endif() + # Use `Compatible Interface Properties` to allow consumers to enforce a shared/static library + set_property(TARGET SDL2 APPEND PROPERTY COMPATIBLE_INTERFACE_BOOL SDL2_SHARED) + set_property(TARGET SDL2 PROPERTY INTERFACE_SDL2_SHARED TRUE) + set_property(TARGET SDL2 APPEND PROPERTY COMPATIBLE_INTERFACE_STRING "SDL_VERSION") + set_property(TARGET SDL2 PROPERTY INTERFACE_SDL_VERSION "SDL2") +endif() + +if(SDL_STATIC) + add_library(SDL2-static STATIC ${SOURCE_FILES}) + add_dependencies(SDL2-static sdl_headers_copy) + # alias target for in-tree builds + add_library(SDL2::SDL2-static ALIAS SDL2-static) + set_target_properties(SDL2-static PROPERTIES + OUTPUT_NAME "${sdl_static_libname}" + POSITION_INDEPENDENT_CODE "${SDL_STATIC_PIC}") + target_compile_definitions(SDL2-static PRIVATE SDL_STATIC_LIB) + # TODO: Win32 platforms keep the same suffix .lib for import and static + # libraries - do we need to consider this? + target_link_libraries(SDL2-static PRIVATE ${EXTRA_LIBS} ${EXTRA_LDFLAGS} ${CMAKE_DEPENDS}) + target_include_directories(SDL2-static PUBLIC + "$" + "$" + "$>/SDL2>" + "$" + "$" + ) + # This picks up all the compiler options and such we've accumulated up to here. + target_link_libraries(SDL2-static PRIVATE $) + if(NOT ANDROID) + set_target_properties(SDL2-static PROPERTIES DEBUG_POSTFIX "${SDL_CMAKE_DEBUG_POSTFIX}") + endif() + # Use `Compatible Interface Properties` to allow consumers to enforce a shared/static library + set_property(TARGET SDL2-static APPEND PROPERTY COMPATIBLE_INTERFACE_BOOL SDL2_SHARED) + set_property(TARGET SDL2-static PROPERTY INTERFACE_SDL2_SHARED FALSE) + set_property(TARGET SDL2-static APPEND PROPERTY COMPATIBLE_INTERFACE_STRING "SDL_VERSION") + set_property(TARGET SDL2-static PROPERTY INTERFACE_SDL_VERSION "SDL2") +endif() + +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DSDL_BUILD_MAJOR_VERSION=${SDL_MAJOR_VERSION}") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DSDL_BUILD_MINOR_VERSION=${SDL_MINOR_VERSION}") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DSDL_BUILD_MICRO_VERSION=${SDL_MICRO_VERSION}") + +##### Tests ##### + +if(SDL_TEST) + file(GLOB TEST_SOURCES ${SDL2_SOURCE_DIR}/src/test/*.c) + add_library(SDL2_test STATIC ${TEST_SOURCES}) + add_dependencies(SDL2_test sdl_headers_copy) + add_library(SDL2::SDL2test ALIAS SDL2_test) + set_target_properties(SDL2_test PROPERTIES + EXPORT_NAME SDL2test) + target_include_directories(SDL2_test PUBLIC + "$" + "$" + "$>/SDL2>" + "$" + "$") + target_link_libraries(SDL2_test PRIVATE ${EXTRA_TEST_LIBS}) + target_include_directories(SDL2_test PRIVATE ${EXTRA_TEST_INCLUDES}) + set_property(TARGET SDL2_test APPEND PROPERTY COMPATIBLE_INTERFACE_STRING "SDL_VERSION") + set_property(TARGET SDL2_test PROPERTY INTERFACE_SDL_VERSION "SDL2") +endif() + +##### Installation targets ##### +if(NOT SDL2_DISABLE_INSTALL) + if(SDL_SHARED) + install(TARGETS SDL2 EXPORT SDL2Targets + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}") + if(MSVC) + SDL_install_pdb(SDL2 "${CMAKE_INSTALL_BINDIR}") + endif() + endif() + + if(NOT WINDOWS_STORE AND NOT SDL2_DISABLE_SDL2MAIN) + install(TARGETS SDL2main EXPORT SDL2mainTargets + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}") + if(MSVC) + SDL_install_pdb(SDL2main "${CMAKE_INSTALL_LIBDIR}") + endif() + endif() + + if(SDL_STATIC) + install(TARGETS SDL2-static EXPORT SDL2staticTargets + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}") + if(MSVC) + SDL_install_pdb(SDL2-static "${CMAKE_INSTALL_LIBDIR}") + endif() + endif() + + if(SDL_TEST) + install(TARGETS SDL2_test EXPORT SDL2testTargets + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}") + if(MSVC) + SDL_install_pdb(SDL2_test "${CMAKE_INSTALL_LIBDIR}") + endif() + endif() + + ##### Export files ##### + if (WINDOWS AND NOT MINGW) + set(SDL_INSTALL_CMAKEDIR_DEFAULT "cmake") + set(LICENSES_PREFIX "licenses/SDL2") + else () + set(SDL_INSTALL_CMAKEDIR_DEFAULT "${CMAKE_INSTALL_LIBDIR}/cmake/SDL2") + set(LICENSES_PREFIX "${CMAKE_INSTALL_DATAROOTDIR}/licenses/${PROJECT_NAME}") + endif () + set(SDL_INSTALL_CMAKEDIR "${SDL_INSTALL_CMAKEDIR_DEFAULT}" CACHE STRING "Location where to install SDL2Config.cmake") + + include(CMakePackageConfigHelpers) + configure_package_config_file(SDL2Config.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/SDL2Config.cmake" + PATH_VARS CMAKE_INSTALL_PREFIX CMAKE_INSTALL_FULL_BINDIR CMAKE_INSTALL_FULL_INCLUDEDIR CMAKE_INSTALL_FULL_LIBDIR + INSTALL_DESTINATION "${SDL_INSTALL_CMAKEDIR}" + ) + write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/SDL2ConfigVersion.cmake" + VERSION ${SDL_VERSION} + COMPATIBILITY AnyNewerVersion + ) + + if(SDL_SHARED) + install(EXPORT SDL2Targets + FILE SDL2Targets.cmake + NAMESPACE SDL2:: + DESTINATION "${SDL_INSTALL_CMAKEDIR}" + ) + if(ANDROID AND NOT CMAKE_VERSION VERSION_LESS 3.7) + install(EXPORT_ANDROID_MK SDL2Targets + DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/ndk-modules/SDL2") + endif() + endif() + + if(NOT WINDOWS_STORE AND NOT SDL2_DISABLE_SDL2MAIN) + install(EXPORT SDL2mainTargets + FILE SDL2mainTargets.cmake + NAMESPACE SDL2:: + DESTINATION "${SDL_INSTALL_CMAKEDIR}" + ) + if(ANDROID AND NOT CMAKE_VERSION VERSION_LESS 3.7) + install(EXPORT_ANDROID_MK SDL2mainTargets + DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/ndk-modules/SDL2main") + endif() + endif() + + if(SDL_STATIC) + install(EXPORT SDL2staticTargets + FILE SDL2staticTargets.cmake + NAMESPACE SDL2:: + DESTINATION "${SDL_INSTALL_CMAKEDIR}" + ) + if(ANDROID AND NOT CMAKE_VERSION VERSION_LESS 3.7) + install(EXPORT_ANDROID_MK SDL2staticTargets + DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/ndk-modules/SDL2-static") + endif() + endif() + + if(SDL_TEST) + install(EXPORT SDL2testTargets + FILE SDL2testTargets.cmake + NAMESPACE SDL2:: + DESTINATION "${SDL_INSTALL_CMAKEDIR}" + ) + if(ANDROID AND NOT CMAKE_VERSION VERSION_LESS 3.7) + install(EXPORT_ANDROID_MK SDL2testTargets + DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/ndk-modules/SDL2test") + endif() + endif() + + install( + FILES + ${CMAKE_CURRENT_BINARY_DIR}/SDL2Config.cmake + ${CMAKE_CURRENT_BINARY_DIR}/SDL2ConfigVersion.cmake + ${SDL2_SOURCE_DIR}/cmake/sdlfind.cmake + DESTINATION "${SDL_INSTALL_CMAKEDIR}" + COMPONENT Devel + ) + + install( + FILES + ${SDL2_INCLUDE_FILES} + "${SDL2_BINARY_DIR}/include/SDL2/SDL_revision.h" + "${SDL2_BINARY_DIR}/include-config-$>/SDL2/SDL_config.h" + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/SDL2) + + string(TOUPPER "${CMAKE_BUILD_TYPE}" UPPER_BUILD_TYPE) + if (UPPER_BUILD_TYPE MATCHES DEBUG) + set(SOPOSTFIX "${SDL_CMAKE_DEBUG_POSTFIX}") + else() + set(SOPOSTFIX "") + endif() + + install(FILES "LICENSE.txt" DESTINATION "${LICENSES_PREFIX}") + if(FREEBSD) + # FreeBSD uses ${PREFIX}/libdata/pkgconfig + install(FILES ${SDL2_BINARY_DIR}/sdl2.pc DESTINATION "libdata/pkgconfig") + else() + install(FILES ${SDL2_BINARY_DIR}/sdl2.pc + DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") + endif() + if(NOT (WINDOWS OR CYGWIN) OR MINGW) + if(SDL_SHARED) + set(SOEXT ${CMAKE_SHARED_LIBRARY_SUFFIX}) # ".so", ".dylib", etc. + get_target_property(SONAME SDL2 OUTPUT_NAME) + if(NOT ANDROID AND NOT MINGW AND NOT OS2) + install(CODE " + execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink + \"lib${SONAME}${SOPOSTFIX}${SOEXT}\" \"libSDL2${SOPOSTFIX}${SOEXT}\" + WORKING_DIRECTORY \"${SDL2_BINARY_DIR}\")") + install(FILES ${SDL2_BINARY_DIR}/libSDL2${SOPOSTFIX}${SOEXT} DESTINATION "${CMAKE_INSTALL_LIBDIR}") + endif() + endif() + install(PROGRAMS ${SDL2_BINARY_DIR}/sdl2-config DESTINATION "${CMAKE_INSTALL_BINDIR}") + # TODO: what about the .spec file? Is it only needed for RPM creation? + install(FILES "${SDL2_SOURCE_DIR}/sdl2.m4" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/aclocal") + endif() +endif() + +##### Uninstall target ##### + +if(NOT SDL2_DISABLE_UNINSTALL) + 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() +endif() + +##### Tests subproject (must appear after the install/uninstall targets) ##### + +if(SDL_TESTS) + set(HAVE_TESTS ON) + enable_testing() + add_subdirectory(test) +endif() + +##### Fix Objective C builds ##### +set(CMAKE_OBJC_FLAGS "${CMAKE_OBJC_FLAGS} ${CMAKE_C_FLAGS}") + +# Make sure SDL2::SDL2 always exists +if(TARGET SDL2::SDL2-static AND NOT TARGET SDL2::SDL2) + add_library(SDL2::SDL2 ALIAS SDL2-static) +endif() diff --git a/SDL2-2.0.12/CREDITS.txt b/SDL2-2.30.5/CREDITS.txt similarity index 100% rename from SDL2-2.0.12/CREDITS.txt rename to SDL2-2.30.5/CREDITS.txt diff --git a/SDL2-2.0.12/INSTALL.txt b/SDL2-2.30.5/INSTALL.txt similarity index 57% rename from SDL2-2.0.12/INSTALL.txt rename to SDL2-2.30.5/INSTALL.txt index 398fc11..f570cb3 100644 --- a/SDL2-2.0.12/INSTALL.txt +++ b/SDL2-2.30.5/INSTALL.txt @@ -2,16 +2,16 @@ To compile and install SDL: 1. Windows with Visual Studio: - * Read VisualC.html + * Read ./docs/README-visualc.md Windows with gcc, either native or cross-compiling: - * Read the FAQ at https://wiki.libsdl.org/moin.fcg/FAQWindows + * Read the FAQ at https://wiki.libsdl.org/FAQWindows * Run './configure; make; make install' - Mac OS X with Xcode: + macOS with Xcode: * Read docs/README-macosx.md - Mac OS X from the command line: + macOS from the command line: * Run './configure; make; make install' Linux and other UNIX systems: @@ -29,12 +29,13 @@ To compile and install SDL: 2. Look at the example programs in ./test, and check out the online documentation at https://wiki.libsdl.org/ - 3. Join the SDL developer mailing list by sending E-mail to - sdl-request@libsdl.org - and put "subscribe" in the subject of the message. + 3. Join the SDL developer discussions, sign up on + https://discourse.libsdl.org/ + and go to the development forum + https://discourse.libsdl.org/c/sdl-development/6 - Or alternatively you can use the web interface: - https://www.libsdl.org/mailing-list.php + 4. Sign up for the announcement list through the web interface: + https://www.libsdl.org/mailing-list.php That's it! Sam Lantinga diff --git a/SDL2-2.0.12/COPYING.txt b/SDL2-2.30.5/LICENSE.txt similarity index 88% rename from SDL2-2.0.12/COPYING.txt rename to SDL2-2.30.5/LICENSE.txt index f158cb4..74bb56c 100644 --- a/SDL2-2.0.12/COPYING.txt +++ b/SDL2-2.30.5/LICENSE.txt @@ -1,20 +1,18 @@ - -Simple DirectMedia Layer -Copyright (C) 1997-2020 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. - +Copyright (C) 1997-2024 Sam Lantinga + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +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. + diff --git a/SDL2-2.0.12/Makefile.in b/SDL2-2.30.5/Makefile.in similarity index 82% rename from SDL2-2.0.12/Makefile.in rename to SDL2-2.30.5/Makefile.in index 65b0fd9..27e0bbb 100644 --- a/SDL2-2.0.12/Makefile.in +++ b/SDL2-2.30.5/Makefile.in @@ -19,6 +19,7 @@ distfile = $(distdir).tar.gz @SET_MAKE@ SHELL = @SHELL@ CC = @CC@ +CXX = @CXX@ INCLUDE = @INCLUDE@ CFLAGS = @BUILD_CFLAGS@ EXTRA_CFLAGS = @EXTRA_CFLAGS@ @@ -26,9 +27,13 @@ LDFLAGS = @BUILD_LDFLAGS@ EXTRA_LDFLAGS = @EXTRA_LDFLAGS@ LIBTOOL = @LIBTOOL@ INSTALL = @INSTALL@ +FGREP = @FGREP@ AR = @AR@ RANLIB = @RANLIB@ -WINDRES = @WINDRES@ +RC = @RC@ +LINKER = @LINKER@ +LIBTOOLLINKERTAG = @LIBTOOLLINKERTAG@ +SDL_VENDOR_INFO = @SDL_VENDOR_INFO@ TARGET = libSDL2.la OBJECTS = @OBJECTS@ @@ -43,10 +48,11 @@ SDLTEST_TARGET = libSDL2_test.la SDLTEST_OBJECTS = @SDLTEST_OBJECTS@ WAYLAND_SCANNER = @WAYLAND_SCANNER@ +WAYLAND_SCANNER_CODE_MODE = @WAYLAND_SCANNER_CODE_MODE@ INSTALL_SDL2_CONFIG = @INSTALL_SDL2_CONFIG@ -SRC_DIST = *.txt acinclude Android.mk autogen.sh android-project build-scripts cmake cmake_uninstall.cmake.in configure configure.ac debian docs include Makefile.* sdl2-config.cmake.in sdl2-config-version.cmake.in sdl2-config.in sdl2.m4 sdl2.pc.in SDL2.spec.in SDL2Config.cmake src test VisualC.html VisualC VisualC-WinRT Xcode Xcode-iOS wayland-protocols +SRC_DIST = *.md *.txt acinclude Android.mk autogen.sh android-project build-scripts cmake cmake_uninstall.cmake.in configure configure.ac docs include Makefile.* mingw sdl2-config.cmake.in sdl2-config-version.cmake.in sdl2-config.in sdl2.m4 sdl2.pc.in SDL2.spec.in SDL2Config.cmake.in src test VisualC VisualC-GDK VisualC-WinRT Xcode Xcode-iOS wayland-protocols GEN_DIST = SDL2.spec ifneq ($V,1) @@ -55,6 +61,7 @@ RUN_CMD_CC = @echo " CC " $@; RUN_CMD_CXX = @echo " CXX " $@; RUN_CMD_LTLINK = @echo " LTLINK" $@; RUN_CMD_RANLIB = @echo " RANLIB" $@; +RUN_CMD_RC = @echo " RC " $@; RUN_CMD_GEN = @echo " GEN " $@; LIBTOOL += --quiet endif @@ -75,16 +82,20 @@ HDRS = \ SDL_filesystem.h \ SDL_gamecontroller.h \ SDL_gesture.h \ + SDL_guid.h \ SDL_haptic.h \ + SDL_hidapi.h \ SDL_hints.h \ SDL_joystick.h \ SDL_keyboard.h \ SDL_keycode.h \ SDL_loadso.h \ + SDL_locale.h \ SDL_log.h \ SDL_main.h \ SDL_messagebox.h \ SDL_metal.h \ + SDL_misc.h \ SDL_mouse.h \ SDL_mutex.h \ SDL_name.h \ @@ -120,7 +131,7 @@ HDRS = \ begin_code.h \ close_code.h -SDLTEST_HDRS = $(shell ls $(srcdir)/include | fgrep SDL_test) +SDLTEST_HDRS = $(shell ls $(srcdir)/include | $(FGREP) SDL_test) LT_AGE = @LT_AGE@ LT_CURRENT = @LT_CURRENT@ @@ -143,18 +154,18 @@ $(objects)/.created: touch $@ update-revision: - $(SHELL) $(auxdir)/updaterev.sh + $(SHELL) $(auxdir)/updaterev.sh --vendor "$(SDL_VENDOR_INFO)" .PHONY: all update-revision install install-bin install-hdrs install-lib install-data uninstall uninstall-bin uninstall-hdrs uninstall-lib uninstall-data clean distclean dist $(OBJECTS:.lo=.d) $(objects)/$(TARGET): $(GEN_HEADERS) $(GEN_OBJECTS) $(OBJECTS) $(VERSION_OBJECTS) - $(RUN_CMD_LTLINK)$(LIBTOOL) --tag=CC --mode=link $(CC) -o $@ $(OBJECTS) $(GEN_OBJECTS) $(VERSION_OBJECTS) $(LDFLAGS) $(EXTRA_LDFLAGS) $(LT_LDFLAGS) + $(RUN_CMD_LTLINK)$(LIBTOOL) --tag=$(LIBTOOLLINKERTAG) --mode=link $(LINKER) -o $@ $(OBJECTS) $(GEN_OBJECTS) $(VERSION_OBJECTS) $(LDFLAGS) $(EXTRA_LDFLAGS) $(LT_LDFLAGS) $(objects)/$(SDLMAIN_TARGET): $(SDLMAIN_OBJECTS) - $(RUN_CMD_LTLINK)$(LIBTOOL) --tag=CC --mode=link $(CC) -static -o $@ $(SDLMAIN_OBJECTS) -rpath $(libdir) + $(RUN_CMD_LTLINK)$(LIBTOOL) --tag=$(LIBTOOLLINKERTAG) --mode=link $(LINKER) -static -o $@ $(SDLMAIN_OBJECTS) -rpath $(libdir) $(objects)/$(SDLTEST_TARGET): $(SDLTEST_OBJECTS) - $(RUN_CMD_LTLINK)$(LIBTOOL) --tag=CC --mode=link $(CC) -static -o $@ $(SDLTEST_OBJECTS) -rpath $(libdir) + $(RUN_CMD_LTLINK)$(LIBTOOL) --tag=$(LIBTOOLLINKERTAG) --mode=link $(LINKER) -static -o $@ $(SDLTEST_OBJECTS) -rpath $(libdir) install: all install-bin install-hdrs install-lib install-data install-bin: @@ -175,7 +186,7 @@ install-hdrs: update-revision $(INSTALL) -m 644 $(srcdir)/include/SDL_revision.h $(DESTDIR)$(includedir)/SDL2/SDL_revision.h; \ fi -install-lib: $(objects) $(objects)/$(TARGET) $(objects)/$(SDLMAIN_TARGET) $(objects)/$(SDLTEST_TARGET) +install-lib: $(objects)/$(TARGET) $(objects)/$(SDLMAIN_TARGET) $(objects)/$(SDLTEST_TARGET) $(SHELL) $(auxdir)/mkinstalldirs $(DESTDIR)$(libdir) $(LIBTOOL) --mode=install $(INSTALL) $(objects)/$(TARGET) $(DESTDIR)$(libdir)/$(TARGET) $(LIBTOOL) --mode=install $(INSTALL) $(objects)/$(SDLMAIN_TARGET) $(DESTDIR)$(libdir)/$(SDLMAIN_TARGET) @@ -243,7 +254,8 @@ dist $(distfile): -name '.#*' \) \ -exec rm -f {} \; if test -f $(distdir)/test/Makefile; then (cd $(distdir)/test && make distclean); fi - (cd $(distdir); build-scripts/updaterev.sh) + # Intentionally no vendor suffix: that's a property of the build, not the source + (cd $(distdir); $(srcdir)/build-scripts/updaterev.sh --dist) tar cvf - $(distdir) | gzip --best >$(distfile) rm -rf $(distdir) diff --git a/SDL2-2.0.12/Makefile.minimal b/SDL2-2.30.5/Makefile.minimal similarity index 59% rename from SDL2-2.0.12/Makefile.minimal rename to SDL2-2.30.5/Makefile.minimal index 7f02649..f9c4b53 100644 --- a/SDL2-2.0.12/Makefile.minimal +++ b/SDL2-2.30.5/Makefile.minimal @@ -1,13 +1,16 @@ # Makefile to build the SDL library -INCLUDE = -I./include -CFLAGS = -g -O2 $(INCLUDE) +CPPFLAGS = -I./include +CFLAGS = -g -O2 AR = ar RANLIB = ranlib -TARGET = libSDL.a +TARGET = libSDL2.a +TESTTARGET = libSDL2_test.a + SOURCES = \ src/*.c \ + src/atomic/*.c \ src/audio/*.c \ src/audio/dummy/*.c \ src/cpuinfo/*.c \ @@ -15,30 +18,44 @@ SOURCES = \ src/file/*.c \ src/haptic/*.c \ src/haptic/dummy/*.c \ + src/hidapi/*.c \ src/joystick/*.c \ src/joystick/dummy/*.c \ src/loadso/dummy/*.c \ src/power/*.c \ src/filesystem/dummy/*.c \ + src/locale/*.c \ + src/locale/dummy/*.c \ + src/misc/*.c \ + src/misc/dummy/*.c \ src/render/*.c \ src/render/software/*.c \ src/sensor/*.c \ src/sensor/dummy/*.c \ src/stdlib/*.c \ + src/libm/*.c \ src/thread/*.c \ src/thread/generic/*.c \ src/timer/*.c \ src/timer/dummy/*.c \ src/video/*.c \ + src/video/yuv2rgb/*.c \ src/video/dummy/*.c \ -OBJECTS = $(shell echo $(SOURCES) | sed -e 's,\.c,\.o,g') +TSOURCES = src/test/*.c -all: $(TARGET) +OBJECTS = $(shell echo $(SOURCES) | sed -e 's,\.c,\.o,g') +TOBJECTS= $(shell echo $(TSOURCES) | sed -e 's,\.c,\.o,g') + +all: $(TARGET) $(TESTTARGET) $(TARGET): $(OBJECTS) $(AR) crv $@ $^ $(RANLIB) $@ +$(TESTTARGET): $(TOBJECTS) + $(AR) crv $@ $^ + $(RANLIB) $@ + clean: - rm -f $(TARGET) $(OBJECTS) + rm -f $(TARGET) $(TESTTARGET) $(OBJECTS) $(TOBJECTS) diff --git a/SDL2-2.30.5/Makefile.os2 b/SDL2-2.30.5/Makefile.os2 new file mode 100644 index 0000000..80f9565 --- /dev/null +++ b/SDL2-2.30.5/Makefile.os2 @@ -0,0 +1,298 @@ +# Open Watcom makefile to build SDL2.dll for OS/2: +# wmake -f Makefile.os2 +# +# If you have GNU libiconv installed (iconv2.dll), you +# can compile against it by specifying LIBICONV=1, e.g.: +# wmake -f Makefile.os2 LIBICONV=1 +# +# If you have libusb-1.0 installed (usb100.dll, libusb.h), you +# can compile hidapi joystick support against it (experimental) +# by specifying HIDAPI=1, e.g.: +# wmake -f Makefile.os2 HIDAPI=1 +# +# To error out upon warnings: wmake -f Makefile.os2 ENABLE_WERROR=1 + +LIBNAME = SDL2 +MAJOR_VERSION = 2 +MINOR_VERSION = 30 +MICRO_VERSION = 5 +VERSION = $(MAJOR_VERSION).$(MINOR_VERSION).$(MICRO_VERSION) +DESCRIPTION = Simple DirectMedia Layer 2 + +LIBICONV=0 +ICONVLIB=$(LIBICONV_LIB) + +LIBHOME = . +DLLFILE = $(LIBHOME)/$(LIBNAME).dll +LIBFILE = $(LIBHOME)/$(LIBNAME).lib +LNKFILE = $(LIBNAME).lnk + +INCPATH = -I"$(%WATCOM)/h/os2" -I"$(%WATCOM)/h" +INCPATH+= -Iinclude + +LIBM = SDL2libm.lib +TLIB = SDL2test.lib +LIBS = mmpm2.lib $(LIBM) +CFLAGS = -bt=os2 -d0 -q -bm -5s -fp5 -fpi87 -sg -oeatxhn -ei +# Debug options: +# - debug messages from OS/2 related code to stdout: +#CFLAGS+= -DOS2DEBUG +# - debug messages from OS/2 code via SDL_LogDebug(): +#CFLAGS+= -DOS2DEBUG=2 + +# max warnings: +CFLAGS+= -wx +!ifeq ENABLE_WERROR 1 +CFLAGS+= -we +!endif +# newer OpenWatcom versions enable W303 by default +CFLAGS+= -wcd=303 +# the include paths : +CFLAGS+= $(INCPATH) +CFLAGS_STATIC=$(CFLAGS) +# building dll: +CFLAGS_DLL =$(CFLAGS) +CFLAGS_DLL+= -bd +# iconv: +LIBICONV_LIB=iconv2.lib +!ifeq LIBICONV 1 +CFLAGS_DLL+= -DHAVE_ICONV=1 -DHAVE_ICONV_H=1 -DSDL_USE_LIBICONV +LIBS+= $(ICONVLIB) +!else +LIBS+= libuls.lib libconv.lib +!endif +# hidapi (libusb): +!ifeq HIDAPI 1 +CFLAGS_DLL+= -DHAVE_LIBUSB_H=1 +!endif +# building SDL itself (for DECLSPEC): +CFLAGS_DLL+= -DBUILD_SDL + +CFLAGS_DLL+= -DSDL_BUILD_MAJOR_VERSION=$(MAJOR_VERSION) +CFLAGS_DLL+= -DSDL_BUILD_MINOR_VERSION=$(MINOR_VERSION) +CFLAGS_DLL+= -DSDL_BUILD_MICRO_VERSION=$(MICRO_VERSION) + +SRCS = SDL.c SDL_assert.c SDL_error.c SDL_guid.c SDL_log.c SDL_dataqueue.c SDL_hints.c SDL_list.c SDL_utils.c +SRCS+= SDL_getenv.c SDL_iconv.c SDL_malloc.c SDL_qsort.c SDL_stdlib.c SDL_string.c SDL_strtokr.c SDL_crc16.c SDL_crc32.c +SRCS+= SDL_cpuinfo.c SDL_atomic.c SDL_spinlock.c SDL_thread.c SDL_timer.c +SRCS+= SDL_rwops.c SDL_power.c +SRCS+= SDL_audio.c SDL_audiocvt.c SDL_audiodev.c SDL_audiotypecvt.c SDL_mixer.c SDL_wave.c +SRCS+= SDL_events.c SDL_quit.c SDL_keyboard.c SDL_mouse.c SDL_windowevents.c & + SDL_clipboardevents.c SDL_dropevents.c SDL_displayevents.c SDL_gesture.c & + SDL_sensor.c SDL_touch.c +SRCS+= SDL_haptic.c SDL_hidapi.c SDL_gamecontroller.c SDL_joystick.c controller_type.c +SRCS+= SDL_render.c yuv_rgb_sse.c yuv_rgb_std.c SDL_yuv.c SDL_yuv_sw.c SDL_blendfillrect.c & + SDL_blendline.c SDL_blendpoint.c SDL_drawline.c SDL_drawpoint.c & + SDL_render_sw.c SDL_rotate.c SDL_triangle.c +SRCS+= SDL_blit.c SDL_blit_0.c SDL_blit_1.c SDL_blit_A.c SDL_blit_auto.c & + SDL_blit_copy.c SDL_blit_N.c SDL_blit_slow.c SDL_fillrect.c SDL_bmp.c & + SDL_pixels.c SDL_rect.c SDL_RLEaccel.c SDL_shape.c SDL_stretch.c & + SDL_surface.c SDL_video.c SDL_clipboard.c SDL_vulkan_utils.c SDL_egl.c + +SRCS+= SDL_syscond.c SDL_sysmutex.c SDL_syssem.c SDL_systhread.c SDL_systls.c +SRCS+= SDL_systimer.c +SRCS+= SDL_sysloadso.c +SRCS+= SDL_sysfilesystem.c +SRCS+= SDL_os2joystick.c SDL_syshaptic.c SDL_sysjoystick.c SDL_virtualjoystick.c +SRCS+= SDL_hidapijoystick.c SDL_hidapi_rumble.c SDL_hidapi_combined.c SDL_hidapi_gamecube.c SDL_hidapi_luna.c SDL_hidapi_ps3.c SDL_hidapi_ps4.c SDL_hidapi_ps5.c SDL_hidapi_shield.c SDL_hidapi_stadia.c SDL_hidapi_switch.c SDL_hidapi_wii.c SDL_hidapi_xbox360.c SDL_hidapi_xbox360w.c SDL_hidapi_xboxone.c SDL_hidapi_steam.c SDL_hidapi_steamdeck.c SDL_steam_virtual_gamepad.c +SRCS+= SDL_dummyaudio.c SDL_diskaudio.c +SRCS+= SDL_nullvideo.c SDL_nullframebuffer.c SDL_nullevents.c +SRCS+= SDL_dummysensor.c +SRCS+= SDL_locale.c SDL_syslocale.c +SRCS+= SDL_url.c SDL_sysurl.c + +SRCS+= SDL_os2.c +!ifeq LIBICONV 0 +SRCS+= geniconv.c os2cp.c os2iconv.c sys2utf8.c +!endif +SRCS+= SDL_os2audio.c +SRCS+= SDL_os2video.c SDL_os2util.c SDL_os2dive.c SDL_os2vman.c & + SDL_os2mouse.c SDL_os2messagebox.c + +SRCS+= SDL_dynapi.c + +OBJS = $(SRCS:.c=.obj) + +.extensions: +.extensions: .lib .dll .obj .c .asm + +.c: ./src;./src/dynapi;./src/audio;./src/cpuinfo;./src/events;./src/file;./src/haptic;./src/joystick;./src/power;./src/render;./src/render/software;./src/sensor;./src/stdlib;./src/thread;./src/timer;./src/video;./src/video/yuv2rgb;./src/atomic;./src/audio/disk; +.c: ./src/haptic/dummy;./src/joystick/dummy;./src/joystick/virtual;./src/audio/dummy;./src/video/dummy;./src/sensor/dummy; +.c: ./src/core/os2;./src/audio/os2;./src/loadso/os2;./src/filesystem/os2;./src/joystick/os2;./src/thread/os2;./src/timer/os2;./src/video/os2; +.c: ./src/core/os2/geniconv; +.c: ./src/locale/;./src/locale/unix;./src/misc;./src/misc/dummy;./src/joystick/hidapi;./src/hidapi + +all: $(DLLFILE) $(LIBFILE) $(TLIB) .symbolic + +build_dll: .symbolic + @echo * Compiling dll objects + +$(DLLFILE): build_dll $(OBJS) $(LIBM) $(LIBICONV_LIB) $(LNKFILE) + @echo * Linking: $@ + wlink @$(LNKFILE) + +$(LIBFILE): $(DLLFILE) + @echo * Creating LIB file: $@ + wlib -q -b -n -c -pa -s -t -zld -ii -io $* $(DLLFILE) + +.c.obj: + wcc386 $(CFLAGS_DLL) -fo=$^@ $< + +SDL_syscond.obj: "src/thread/generic/SDL_syscond.c" + wcc386 $(CFLAGS_DLL) -fo=$^@ $< +SDL_cpuinfo.obj: SDL_cpuinfo.c + wcc386 $(CFLAGS_DLL) -wcd=200 -fo=$^@ $< +SDL_wave.obj: SDL_wave.c + wcc386 $(CFLAGS_DLL) -wcd=124 -fo=$^@ $< +SDL_blendfillrect.obj: SDL_blendfillrect.c + wcc386 $(CFLAGS_DLL) -wcd=200 -fo=$^@ $< +SDL_blendline.obj: SDL_blendline.c + wcc386 $(CFLAGS_DLL) -wcd=200 -fo=$^@ $< +SDL_blendpoint.obj: SDL_blendpoint.c + wcc386 $(CFLAGS_DLL) -wcd=200 -fo=$^@ $< +SDL_RLEaccel.obj: SDL_RLEaccel.c + wcc386 $(CFLAGS_DLL) -wcd=201 -fo=$^@ $< +yuv_rgb_sse.obj: yuv_rgb_sse.c + wcc386 $(CFLAGS_DLL) -wcd=202 -fo=$^@ $< +!ifeq HIDAPI 1 +# c99 mode needed because of structs with flexible array members in libusb.h +SDL_hidapi.obj: SDL_hidapi.c + wcc386 $(CFLAGS_DLL) -za99 -fo=$^@ $< +!endif + +$(LIBICONV_LIB): "src/core/os2/iconv2.lbc" + @echo * Creating: $@ + wlib -q -b -n -c -pa -s -t -zld -ii -io $@ @$< + +# SDL2libm +MSRCS= e_atan2.c e_exp.c e_fmod.c e_log10.c e_log.c e_pow.c e_rem_pio2.c e_sqrt.c & + k_cos.c k_rem_pio2.c k_sin.c k_tan.c & + s_atan.c s_copysign.c s_cos.c s_fabs.c s_floor.c s_scalbn.c s_sin.c s_tan.c +MOBJS= $(MSRCS:.c=.obj) + +.c: ./src/libm; +e_atan2.obj: e_atan2.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +e_exp.obj: e_exp.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +e_fmod.obj: e_fmod.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +e_log10.obj: e_log10.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +e_log.obj: e_log.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +e_pow.obj: e_pow.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +e_rem_pio2.obj: e_rem_pio2.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +e_sqrt.obj: e_sqrt.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +k_cos.obj: k_cos.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +k_rem_pio2.obj: k_rem_pio2.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +k_sin.obj: k_sin.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +k_tan.obj: k_tan.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +s_atan.obj: s_atan.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +s_copysign.obj: s_copysign.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +s_cos.obj: s_cos.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +s_fabs.obj: s_fabs.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +s_floor.obj: s_floor.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +s_scalbn.obj: s_scalbn.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +s_sin.obj: s_sin.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +s_tan.obj: s_tan.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< + +build_libm: .symbolic + @echo * Compiling libm objects +$(LIBM): build_libm $(MOBJS) + @echo * Creating: $@ + wlib -q -b -n -c -pa -s -t -zld -ii -io $@ $(MOBJS) + +# SDL2test +TSRCS = SDL_test_assert.c SDL_test_common.c SDL_test_compare.c & + SDL_test_crc32.c SDL_test_font.c SDL_test_fuzzer.c SDL_test_harness.c & + SDL_test_imageBlit.c SDL_test_imageBlitBlend.c SDL_test_imageFace.c & + SDL_test_imagePrimitives.c SDL_test_imagePrimitivesBlend.c & + SDL_test_log.c SDL_test_md5.c SDL_test_random.c SDL_test_memory.c +TOBJS= $(TSRCS:.c=.obj) + +.c: ./src/test; +SDL_test_assert.obj: SDL_test_assert.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_common.obj: SDL_test_common.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_compare.obj: SDL_test_compare.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_crc32.obj: SDL_test_crc32.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_font.obj: SDL_test_font.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_fuzzer.obj: SDL_test_fuzzer.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_harness.obj: SDL_test_harness.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_imageBlit.obj: SDL_test_imageBlit.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_imageBlitBlend.obj: SDL_test_imageBlitBlend.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_imageFace.obj: SDL_test_imageFace.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_imagePrimitives.obj: SDL_test_imagePrimitives.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_imagePrimitivesBlend.obj: SDL_test_imagePrimitivesBlend.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_log.obj: SDL_test_log.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_md5.obj: SDL_test_md5.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_random.obj: SDL_test_random.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_memory.obj: SDL_test_memory.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< + +build_tlib: .symbolic + @echo * Compiling testlib objects +$(TLIB): build_tlib $(TOBJS) + @echo * Creating: $@ + wlib -q -b -n -c -pa -s -t -zld -ii -io $@ $(TOBJS) + +$(LNKFILE): + @echo * Creating linker file: $@ + @%create $@ + @%append $@ SYSTEM os2v2_dll INITINSTANCE TERMINSTANCE + @%append $@ NAME $(DLLFILE) + @for %i in ($(OBJS)) do @%append $@ FILE %i + @for %i in ($(LIBS)) do @%append $@ LIB %i + @%append $@ OPTION QUIET + @%append $@ OPTION IMPF=$(LIBHOME)/$^&.exp + @%append $@ OPTION MAP=$(LIBHOME)/$^&.map + @%append $@ OPTION DESCRIPTION '@$#libsdl org:$(VERSION)$#@$(DESCRIPTION)' + @%append $@ OPTION ELIMINATE + @%append $@ OPTION MANYAUTODATA + @%append $@ OPTION OSNAME='OS/2 and eComStation' + @%append $@ OPTION SHOWDEAD + +clean: .SYMBOLIC + @echo * Clean: $(LIBNAME) + @if exist *.obj rm *.obj + @if exist *.err rm *.err + @if exist $(LNKFILE) rm $(LNKFILE) + @if exist $(LIBM) rm $(LIBM) + @if exist $(LIBICONV_LIB) rm $(LIBICONV_LIB) + +distclean: .SYMBOLIC clean + @if exist $(LIBHOME)/*.exp rm $(LIBHOME)/*.exp + @if exist $(LIBHOME)/*.map rm $(LIBHOME)/*.map + @if exist $(LIBFILE) rm $(LIBFILE) + @if exist $(DLLFILE) rm $(DLLFILE) + @if exist $(TLIB) rm $(TLIB) diff --git a/SDL2-2.0.12/Makefile.pandora b/SDL2-2.30.5/Makefile.pandora similarity index 88% rename from SDL2-2.0.12/Makefile.pandora rename to SDL2-2.30.5/Makefile.pandora index f4cb668..fe22499 100644 --- a/SDL2-2.0.12/Makefile.pandora +++ b/SDL2-2.30.5/Makefile.pandora @@ -10,7 +10,7 @@ CFLAGS = -O3 -march=armv7-a -mcpu=cortex-a8 -mtune=cortex-a8 -mfloat-abi=softfp -mfpu=neon -ftree-vectorize -ffast-math -fomit-frame-pointer -fno-strict-aliasing -fsingle-precision-constant \ -I./include -I$(PNDSDK)/usr/include -TARGET = libSDL.a +TARGET = libSDL2.a SOURCES = ./src/*.c \ @@ -25,9 +25,14 @@ SOURCES = ./src/filesystem/unix/*.c \ ./src/haptic/*.c \ ./src/haptic/linux/*.c \ + ./src/hidapi/*.c \ ./src/joystick/*.c \ ./src/joystick/linux/*.c \ ./src/loadso/dlopen/*.c \ + ./src/locale/*.c \ + ./src/locale/unix/*.c \ + ./src/misc/*.c \ + ./src/misc/unix/*.c \ ./src/power/*.c \ ./src/sensor/*.c \ ./src/sensor/dummy/*.c \ @@ -40,11 +45,10 @@ SOURCES = ./src/timer/*.c \ ./src/timer/unix/*.c \ ./src/video/*.c \ + ./src/video/yuv2rgb/*.c \ ./src/video/dummy/*.c \ - ./src/video/pandora/SDL_pandora.o \ - ./src/video/pandora/SDL_pandora_events.o \ ./src/video/x11/*.c \ - + ./src/video/pandora/*.c OBJECTS = $(shell echo $(SOURCES) | sed -e 's,\.c,\.o,g') diff --git a/SDL2-2.30.5/Makefile.w32 b/SDL2-2.30.5/Makefile.w32 new file mode 100644 index 0000000..d7a01f1 --- /dev/null +++ b/SDL2-2.30.5/Makefile.w32 @@ -0,0 +1,283 @@ +# Open Watcom makefile to build SDL2.dll for Win32: +# wmake -f Makefile.w32 +# +# To error out upon warnings: wmake -f Makefile.w32 ENABLE_WERROR=1 + +LIBNAME = SDL2 +MAJOR_VERSION = 2 +MINOR_VERSION = 30 +MICRO_VERSION = 5 +VERSION = $(MAJOR_VERSION).$(MINOR_VERSION).$(MICRO_VERSION) + +LIBHOME = . +DLLFILE = $(LIBHOME)/$(LIBNAME).dll +LIBFILE = $(LIBHOME)/$(LIBNAME).lib +EXPFILE = $(LIBHOME)/$(LIBNAME).exp +LNKFILE = $(LIBNAME).lnk + +INCPATH = -I"$(%WATCOM)/h/nt" -I"$(%WATCOM)/h/nt/directx" -I"$(%WATCOM)/h" +INCPATH+= -Iinclude +INCPATH+= -I"src/video/khronos" + +LIBM = SDL2libm.lib +TLIB = SDL2test.lib +# user32.lib, gdi32.lib, ole32.lib and oleaut32.lib are actually +# among the default libraries in wlink.lnk for nt_dll linkage... +LIBS = user32.lib gdi32.lib winmm.lib imm32.lib ole32.lib oleaut32.lib shell32.lib setupapi.lib version.lib uuid.lib dxguid.lib $(LIBM) + +CFLAGS = -bt=nt -d0 -q -bm -5s -fp5 -fpi87 -sg -oeatxhn -ei +# max warnings: +CFLAGS+= -wx +!ifeq ENABLE_WERROR 1 +CFLAGS+= -we +!endif +# newer OpenWatcom versions enable W303 by default +CFLAGS+= -wcd=303 +# new vulkan headers result in lots of W202 warnings +CFLAGS+= -wcd=202 +# the include paths : +CFLAGS+= $(INCPATH) +CFLAGS_STATIC=$(CFLAGS) +# building dll: +CFLAGS_DLL =$(CFLAGS) +CFLAGS_DLL+= -bd +# we override the DECLSPEC define in begin_code.h, because we are using +# an exports file to remove the _cdecl '_' prefix from the symbol names +CFLAGS_DLL+= -DDECLSPEC= + +CFLAGS_DLL+= -DSDL_BUILD_MAJOR_VERSION=$(MAJOR_VERSION) +CFLAGS_DLL+= -DSDL_BUILD_MINOR_VERSION=$(MINOR_VERSION) +CFLAGS_DLL+= -DSDL_BUILD_MICRO_VERSION=$(MICRO_VERSION) + +RCFLAGS = -q -r -bt=nt $(INCPATH) + +SRCS = SDL.c SDL_assert.c SDL_error.c SDL_guid.c SDL_log.c SDL_dataqueue.c SDL_hints.c SDL_list.c SDL_utils.c +SRCS+= SDL_getenv.c SDL_iconv.c SDL_malloc.c SDL_qsort.c SDL_stdlib.c SDL_string.c SDL_strtokr.c SDL_crc16.c SDL_crc32.c +SRCS+= SDL_cpuinfo.c SDL_atomic.c SDL_spinlock.c SDL_thread.c SDL_timer.c +SRCS+= SDL_rwops.c SDL_power.c +SRCS+= SDL_audio.c SDL_audiocvt.c SDL_audiodev.c SDL_audiotypecvt.c SDL_mixer.c SDL_wave.c +SRCS+= SDL_events.c SDL_quit.c SDL_keyboard.c SDL_mouse.c SDL_windowevents.c & + SDL_clipboardevents.c SDL_dropevents.c SDL_displayevents.c SDL_gesture.c & + SDL_sensor.c SDL_touch.c +SRCS+= SDL_haptic.c SDL_hidapi.c SDL_gamecontroller.c SDL_joystick.c controller_type.c +SRCS+= SDL_render.c yuv_rgb_sse.c yuv_rgb_std.c SDL_yuv.c SDL_yuv_sw.c SDL_blendfillrect.c & + SDL_blendline.c SDL_blendpoint.c SDL_drawline.c SDL_drawpoint.c & + SDL_render_sw.c SDL_rotate.c SDL_triangle.c +SRCS+= SDL_blit.c SDL_blit_0.c SDL_blit_1.c SDL_blit_A.c SDL_blit_auto.c & + SDL_blit_copy.c SDL_blit_N.c SDL_blit_slow.c SDL_fillrect.c SDL_bmp.c & + SDL_pixels.c SDL_rect.c SDL_RLEaccel.c SDL_shape.c SDL_stretch.c & + SDL_surface.c SDL_video.c SDL_clipboard.c SDL_vulkan_utils.c SDL_egl.c + +SRCS+= SDL_syscond.c SDL_sysmutex.c SDL_syssem.c SDL_systhread.c SDL_systls.c +SRCS+= SDL_systimer.c +SRCS+= SDL_sysloadso.c +SRCS+= SDL_sysfilesystem.c +SRCS+= SDL_syshaptic.c SDL_sysjoystick.c SDL_virtualjoystick.c +SRCS+= SDL_hidapijoystick.c SDL_hidapi_rumble.c SDL_hidapi_combined.c SDL_hidapi_gamecube.c SDL_hidapi_luna.c SDL_hidapi_ps3.c SDL_hidapi_ps4.c SDL_hidapi_ps5.c SDL_hidapi_shield.c SDL_hidapi_stadia.c SDL_hidapi_switch.c SDL_hidapi_wii.c SDL_hidapi_xbox360.c SDL_hidapi_xbox360w.c SDL_hidapi_xboxone.c SDL_hidapi_steam.c SDL_hidapi_steamdeck.c +SRCS+= SDL_dummyaudio.c SDL_diskaudio.c +SRCS+= SDL_nullvideo.c SDL_nullframebuffer.c SDL_nullevents.c +SRCS+= SDL_dummysensor.c +SRCS+= SDL_locale.c SDL_syslocale.c +SRCS+= SDL_url.c SDL_sysurl.c + +SRCS+= SDL_winmm.c SDL_directsound.c SDL_wasapi.c SDL_wasapi_win32.c +SRCS+= SDL_hid.c SDL_immdevice.c SDL_windows.c SDL_xinput.c +SRCS+= SDL_dinputhaptic.c SDL_windowshaptic.c SDL_xinputhaptic.c +SRCS+= SDL_dinputjoystick.c SDL_rawinputjoystick.c SDL_windowsjoystick.c SDL_windows_gaming_input.c SDL_xinputjoystick.c +SRCS+= SDL_syspower.c +SRCS+= SDL_d3dmath.c +SRCS+= SDL_render_d3d.c SDL_shaders_d3d.c +SRCS+= SDL_render_d3d11.c SDL_shaders_d3d11.c +SRCS+= SDL_render_d3d12.c SDL_shaders_d3d12.c +SRCS+= SDL_render_gl.c SDL_shaders_gl.c +SRCS+= SDL_render_gles2.c SDL_shaders_gles2.c +SRCS+= SDL_windowssensor.c +SRCS+= SDL_syscond_cv.c +SRCS+= SDL_windowsclipboard.c SDL_windowsevents.c SDL_windowsframebuffer.c SDL_windowskeyboard.c SDL_windowsmessagebox.c SDL_windowsmodes.c SDL_windowsmouse.c SDL_windowsopengl.c SDL_windowsopengles.c SDL_windowsshape.c SDL_windowsvideo.c SDL_windowsvulkan.c SDL_windowswindow.c SDL_steam_virtual_gamepad.c + +SRCS+= SDL_dynapi.c + +RCSRCS = version.rc + +OBJS = $(SRCS:.c=.obj) +RCOBJS= $(RCSRCS:.rc=.res) + +.extensions: +.extensions: .lib .dll .obj .res .c .rc .asm + +.c: ./src;./src/dynapi;./src/audio;./src/cpuinfo;./src/events;./src/file;./src/haptic;./src/joystick;./src/power;./src/render;./src/render/software;./src/sensor;./src/stdlib;./src/thread;./src/timer;./src/video;./src/video/yuv2rgb;./src/atomic;./src/audio/disk; +.c: ./src/haptic/dummy;./src/joystick/dummy;./src/joystick/virtual;./src/audio/dummy;./src/video/dummy;./src/sensor/dummy; +.c: ./src/core/windows;./src/audio/winmm;./src/audio/directsound;./src/audio/wasapi;./src/loadso/windows;./src/filesystem/windows;./src/haptic/windows;./src/joystick/windows;./src/sensor/windows;./src/thread/windows;./src/timer/windows;./src/video/windows; +.c: ./src/locale/;./src/locale/windows;./src/misc;./src/misc/windows;./src/power/windows;./src/joystick/hidapi;./src/hidapi;./src/render/direct3d;./src/render/direct3d11;./src/render/direct3d12;./src/render/opengl;./src/render/opengles2 +.rc: ./src/main/windows + +all: $(DLLFILE) $(LIBFILE) $(TLIB) .symbolic + +build_dll: .symbolic + @echo * Compiling dll objects + +$(DLLFILE): build_dll $(OBJS) $(LIBM) $(RCOBJS) $(LNKFILE) + @echo * Linking: $@ + wlink @$(LNKFILE) + +$(LIBFILE): $(DLLFILE) + @echo * Creating LIB file: $@ + wlib -q -b -n -c -pa -s -t -zld -ii -io $* @$(EXPFILE) + +.c.obj: + wcc386 $(CFLAGS_DLL) -fo=$^@ $< + +.rc.res: + wrc $(RCFLAGS) -fo=$^@ $< + +SDL_syscond.obj: "src/thread/generic/SDL_syscond.c" + wcc386 $(CFLAGS_DLL) -fo=$^@ $< +SDL_cpuinfo.obj: SDL_cpuinfo.c + wcc386 $(CFLAGS_DLL) -wcd=200 -fo=$^@ $< +SDL_wave.obj: SDL_wave.c + wcc386 $(CFLAGS_DLL) -wcd=124 -fo=$^@ $< +SDL_blendfillrect.obj: SDL_blendfillrect.c + wcc386 $(CFLAGS_DLL) -wcd=200 -fo=$^@ $< +SDL_blendline.obj: SDL_blendline.c + wcc386 $(CFLAGS_DLL) -wcd=200 -fo=$^@ $< +SDL_blendpoint.obj: SDL_blendpoint.c + wcc386 $(CFLAGS_DLL) -wcd=200 -fo=$^@ $< +SDL_RLEaccel.obj: SDL_RLEaccel.c + wcc386 $(CFLAGS_DLL) -wcd=201 -fo=$^@ $< +SDL_malloc.obj: SDL_malloc.c + wcc386 $(CFLAGS_DLL) -wcd=201 -fo=$^@ $< + +yuv_rgb_sse.obj: yuv_rgb_sse.c + wcc386 $(CFLAGS_DLL) -wcd=202 -fo=$^@ $< + +# SDL2libm +MSRCS= e_atan2.c e_exp.c e_fmod.c e_log10.c e_log.c e_pow.c e_rem_pio2.c e_sqrt.c & + k_cos.c k_rem_pio2.c k_sin.c k_tan.c & + s_atan.c s_copysign.c s_cos.c s_fabs.c s_floor.c s_scalbn.c s_sin.c s_tan.c +MOBJS= $(MSRCS:.c=.obj) + +.c: ./src/libm; +e_atan2.obj: e_atan2.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +e_exp.obj: e_exp.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +e_fmod.obj: e_fmod.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +e_log10.obj: e_log10.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +e_log.obj: e_log.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +e_pow.obj: e_pow.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +e_rem_pio2.obj: e_rem_pio2.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +e_sqrt.obj: e_sqrt.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +k_cos.obj: k_cos.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +k_rem_pio2.obj: k_rem_pio2.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +k_sin.obj: k_sin.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +k_tan.obj: k_tan.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +s_atan.obj: s_atan.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +s_copysign.obj: s_copysign.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +s_cos.obj: s_cos.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +s_fabs.obj: s_fabs.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +s_floor.obj: s_floor.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +s_scalbn.obj: s_scalbn.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +s_sin.obj: s_sin.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +s_tan.obj: s_tan.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< + +build_libm: .symbolic + @echo * Compiling libm objects +$(LIBM): build_libm $(MOBJS) + @echo * Creating: $@ + wlib -q -b -n -c -pa -s -t -zld -ii -io $@ $(MOBJS) + +# SDL2test +TSRCS = SDL_test_assert.c SDL_test_common.c SDL_test_compare.c & + SDL_test_crc32.c SDL_test_font.c SDL_test_fuzzer.c SDL_test_harness.c & + SDL_test_imageBlit.c SDL_test_imageBlitBlend.c SDL_test_imageFace.c & + SDL_test_imagePrimitives.c SDL_test_imagePrimitivesBlend.c & + SDL_test_log.c SDL_test_md5.c SDL_test_random.c SDL_test_memory.c +TOBJS= $(TSRCS:.c=.obj) + +.c: ./src/test; +SDL_test_assert.obj: SDL_test_assert.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_common.obj: SDL_test_common.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_compare.obj: SDL_test_compare.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_crc32.obj: SDL_test_crc32.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_font.obj: SDL_test_font.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_fuzzer.obj: SDL_test_fuzzer.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_harness.obj: SDL_test_harness.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_imageBlit.obj: SDL_test_imageBlit.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_imageBlitBlend.obj: SDL_test_imageBlitBlend.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_imageFace.obj: SDL_test_imageFace.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_imagePrimitives.obj: SDL_test_imagePrimitives.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_imagePrimitivesBlend.obj: SDL_test_imagePrimitivesBlend.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_log.obj: SDL_test_log.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_md5.obj: SDL_test_md5.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_random.obj: SDL_test_random.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< +SDL_test_memory.obj: SDL_test_memory.c + wcc386 $(CFLAGS_STATIC) -fo=$^@ $< + +build_tlib: .symbolic + @echo * Compiling testlib objects +$(TLIB): build_tlib $(TOBJS) + @echo * Creating: $@ + wlib -q -b -n -c -pa -s -t -zld -ii -io $@ $(TOBJS) + +$(LNKFILE): Makefile.w32 + @echo * Creating linker file: $@ + @%create $@ + @%append $@ SYSTEM nt_dll INITINSTANCE TERMINSTANCE + @%append $@ NAME $(DLLFILE) + @for %i in ($(OBJS)) do @%append $@ FILE %i + @for %i in ($(LIBS)) do @%append $@ LIB %i + @%append $@ OPTION RESOURCE=$(RCOBJS) + @%append $@ EXPORT=src/dynapi/SDL2.exports + @%append $@ OPTION QUIET + @%append $@ OPTION IMPF=$(EXPFILE) + @%append $@ OPTION MAP=$(LIBHOME)/$^&.map + @%append $@ OPTION ELIMINATE + @%append $@ OPTION SHOWDEAD + +clean: .SYMBOLIC + @echo * Clean: $(LIBNAME) + @if exist *.obj rm *.obj + @if exist *.res rm *.res + @if exist *.err rm *.err + @if exist $(LNKFILE) rm $(LNKFILE) + @if exist $(LIBM) rm $(LIBM) + +distclean: .SYMBOLIC clean + @if exist $(LIBHOME)/*.exp rm $(LIBHOME)/*.exp + @if exist $(LIBHOME)/*.map rm $(LIBHOME)/*.map + @if exist $(LIBFILE) rm $(LIBFILE) + @if exist $(DLLFILE) rm $(DLLFILE) + @if exist $(TLIB) rm $(TLIB) diff --git a/SDL2-2.0.12/README-SDL.txt b/SDL2-2.30.5/README-SDL.txt similarity index 100% rename from SDL2-2.0.12/README-SDL.txt rename to SDL2-2.30.5/README-SDL.txt diff --git a/SDL2-2.0.12/README.txt b/SDL2-2.30.5/README.md similarity index 69% rename from SDL2-2.0.12/README.txt rename to SDL2-2.30.5/README.md index e8630c7..fa7f7ba 100644 --- a/SDL2-2.0.12/README.txt +++ b/SDL2-2.30.5/README.md @@ -1,11 +1,6 @@ - Simple DirectMedia Layer +# Simple DirectMedia Layer (SDL) Version 2.0 - (SDL) - - Version 2.0 - ---- https://www.libsdl.org/ Simple DirectMedia Layer is a cross-platform development library designed @@ -18,4 +13,5 @@ More extensive documentation is available in the docs directory, starting with README.md Enjoy! - Sam Lantinga (slouken@libsdl.org) + +Sam Lantinga (slouken@libsdl.org) diff --git a/SDL2-2.0.12/SDL2.spec b/SDL2-2.30.5/SDL2.spec similarity index 97% rename from SDL2-2.0.12/SDL2.spec rename to SDL2-2.30.5/SDL2.spec index 365774d..f91a72a 100644 --- a/SDL2-2.0.12/SDL2.spec +++ b/SDL2-2.30.5/SDL2.spec @@ -1,6 +1,6 @@ Summary: Simple DirectMedia Layer Name: SDL2 -Version: 2.0.12 +Version: 2.30.5 Release: 2 Source: http://www.libsdl.org/release/%{name}-%{version}.tar.gz URL: http://www.libsdl.org/ @@ -63,7 +63,7 @@ rm -rf $RPM_BUILD_ROOT %files %{__defattr} -%doc README*.txt COPYING.txt CREDITS.txt BUGS.txt +%doc README*.txt LICENSE.txt CREDITS.txt BUGS.txt %{_libdir}/lib*.%{__soext}.* %files devel diff --git a/SDL2-2.0.12/SDL2.spec.in b/SDL2-2.30.5/SDL2.spec.in similarity index 98% rename from SDL2-2.0.12/SDL2.spec.in rename to SDL2-2.30.5/SDL2.spec.in index eee5e5d..812d2d8 100644 --- a/SDL2-2.0.12/SDL2.spec.in +++ b/SDL2-2.30.5/SDL2.spec.in @@ -63,7 +63,7 @@ rm -rf $RPM_BUILD_ROOT %files %{__defattr} -%doc README*.txt COPYING.txt CREDITS.txt BUGS.txt +%doc README*.txt LICENSE.txt CREDITS.txt BUGS.txt %{_libdir}/lib*.%{__soext}.* %files devel diff --git a/SDL2-2.30.5/SDL2Config.cmake.in b/SDL2-2.30.5/SDL2Config.cmake.in new file mode 100644 index 0000000..cc8bcf2 --- /dev/null +++ b/SDL2-2.30.5/SDL2Config.cmake.in @@ -0,0 +1,77 @@ +# sdl2 cmake project-config input for CMakeLists.txt script + +include(FeatureSummary) +set_package_properties(SDL2 PROPERTIES + URL "https://www.libsdl.org/" + DESCRIPTION "low level access to audio, keyboard, mouse, joystick, and graphics hardware" +) + +@PACKAGE_INIT@ + +set(SDL2_FOUND TRUE) + +if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/SDL2Targets.cmake") + include("${CMAKE_CURRENT_LIST_DIR}/SDL2Targets.cmake") + set(SDL2_SDL2_FOUND TRUE) +endif() +if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/SDL2staticTargets.cmake") + if(ANDROID) + enable_language(CXX) + endif() + include("${CMAKE_CURRENT_LIST_DIR}/SDL2staticTargets.cmake") + set(SDL2_SDL2-static_FOUND TRUE) +endif() +if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/SDL2mainTargets.cmake") + include("${CMAKE_CURRENT_LIST_DIR}/SDL2mainTargets.cmake") + set(SDL2_SDL2main_FOUND TRUE) +endif() +if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/SDL2testTargets.cmake") + include("${CMAKE_CURRENT_LIST_DIR}/SDL2testTargets.cmake") + set(SDL2_SDL2test_FOUND TRUE) +endif() + + +include("${CMAKE_CURRENT_LIST_DIR}/sdlfind.cmake") + +set(SDL_ALSA @SDL_ALSA@) +set(SDL_ALSA_SHARED @SDL_ALSA_SHARED@) +if(SDL_ALSA AND NOT SDL_ALSA_SHARED AND TARGET SDL2::SDL2-static) + sdlFindALSA() +endif() +unset(SDL_ALSA) +unset(SDL_ALSA_SHARED) + + +check_required_components(SDL2) + +# Create SDL2::SDL2 alias for static-only builds +if(TARGET SDL2::SDL2-static AND NOT TARGET SDL2::SDL2) + if(CMAKE_VERSION VERSION_LESS "3.18") + # FIXME: Aliasing local targets is not supported on CMake < 3.18, so make it global. + add_library(SDL2::SDL2 INTERFACE IMPORTED) + set_target_properties(SDL2::SDL2 PROPERTIES INTERFACE_LINK_LIBRARIES "SDL2::SDL2-static") + else() + add_library(SDL2::SDL2 ALIAS SDL2::SDL2-static) + endif() +endif() + +# For compatibility with autotools sdl2-config.cmake, provide SDL2_* variables. + +set(SDL2_PREFIX "@PACKAGE_CMAKE_INSTALL_PREFIX@") +set(SDL2_EXEC_PREFIX "@PACKAGE_CMAKE_INSTALL_PREFIX@") +set(SDL2_INCLUDE_DIR "@PACKAGE_CMAKE_INSTALL_FULL_INCLUDEDIR@/SDL2") +set(SDL2_INCLUDE_DIRS "@PACKAGE_CMAKE_INSTALL_FULL_INCLUDEDIR@;@PACKAGE_CMAKE_INSTALL_FULL_INCLUDEDIR@/SDL2") +set(SDL2_BINDIR "@PACKAGE_CMAKE_INSTALL_FULL_BINDIR@") +set(SDL2_LIBDIR "@PACKAGE_CMAKE_INSTALL_FULL_LIBDIR@") +set(SDL2_LIBRARIES SDL2::SDL2) +set(SDL2_STATIC_LIBRARIES SDL2::SDL2-static) +set(SDL2_STATIC_PRIVATE_LIBS) + +set(SDL2MAIN_LIBRARY) +if(TARGET SDL2::SDL2main) + set(SDL2MAIN_LIBRARY SDL2::SDL2main) + list(INSERT SDL2_LIBRARIES 0 SDL2::SDL2main) + list(INSERT SDL2_STATIC_LIBRARIES 0 SDL2::SDL2main) +endif() + +set(SDL2TEST_LIBRARY SDL2::SDL2test) diff --git a/SDL2-2.0.12/TODO.txt b/SDL2-2.30.5/TODO.txt similarity index 88% rename from SDL2-2.0.12/TODO.txt rename to SDL2-2.30.5/TODO.txt index 89637eb..20b205f 100644 --- a/SDL2-2.0.12/TODO.txt +++ b/SDL2-2.30.5/TODO.txt @@ -1,5 +1,5 @@ Future work roadmap: - * http://wiki.libsdl.org/moin.cgi/Roadmap + * http://wiki.libsdl.org/Roadmap * Check 1.2 revisions: 3554 - Need to resolve semantics for locking keys on different platforms diff --git a/SDL2-2.30.5/VERSION.txt b/SDL2-2.30.5/VERSION.txt new file mode 100644 index 0000000..f825b2e --- /dev/null +++ b/SDL2-2.30.5/VERSION.txt @@ -0,0 +1 @@ +release-2.30.5-0-g2eef7ca47 diff --git a/SDL2-2.30.5/VisualC-GDK/SDL.sln b/SDL2-2.30.5/VisualC-GDK/SDL.sln new file mode 100644 index 0000000..2584219 --- /dev/null +++ b/SDL2-2.30.5/VisualC-GDK/SDL.sln @@ -0,0 +1,131 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.1.32414.318 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{D69D5741-611F-4E14-8541-1FEE94F50B5A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SDL2", "SDL\SDL.vcxproj", "{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SDL2main", "SDLmain\SDLmain.vcxproj", "{DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testsprite2", "tests\testsprite2\testsprite2.vcxproj", "{40FB7794-D3C3-4CFE-BCF4-A80C96635682}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SDL2test", "SDLtest\SDLtest.vcxproj", "{DA956FD3-E143-46F2-9FE5-C77BEBC56B1A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testgamecontroller", "tests\testgamecontroller\testgamecontroller.vcxproj", "{55812185-D13C-4022-9C81-32E0F4A08305}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testgdk", "tests\testgdk\testgdk.vcxproj", "{1C9A3F71-35A5-4C56-B292-F4375B3C3649}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Gaming.Desktop.x64 = Debug|Gaming.Desktop.x64 + Debug|Gaming.Xbox.Scarlett.x64 = Debug|Gaming.Xbox.Scarlett.x64 + Debug|Gaming.Xbox.XboxOne.x64 = Debug|Gaming.Xbox.XboxOne.x64 + Release|Gaming.Desktop.x64 = Release|Gaming.Desktop.x64 + Release|Gaming.Xbox.Scarlett.x64 = Release|Gaming.Xbox.Scarlett.x64 + Release|Gaming.Xbox.XboxOne.x64 = Release|Gaming.Xbox.XboxOne.x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|Gaming.Desktop.x64.ActiveCfg = Debug|Gaming.Desktop.x64 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|Gaming.Desktop.x64.Build.0 = Debug|Gaming.Desktop.x64 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|Gaming.Xbox.Scarlett.x64.ActiveCfg = Debug|Gaming.Xbox.Scarlett.x64 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|Gaming.Xbox.Scarlett.x64.Build.0 = Debug|Gaming.Xbox.Scarlett.x64 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|Gaming.Xbox.XboxOne.x64.ActiveCfg = Debug|Gaming.Xbox.XboxOne.x64 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|Gaming.Xbox.XboxOne.x64.Build.0 = Debug|Gaming.Xbox.XboxOne.x64 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|Gaming.Desktop.x64.ActiveCfg = Release|Gaming.Desktop.x64 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|Gaming.Desktop.x64.Build.0 = Release|Gaming.Desktop.x64 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|Gaming.Xbox.Scarlett.x64.ActiveCfg = Release|Gaming.Xbox.Scarlett.x64 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|Gaming.Xbox.Scarlett.x64.Build.0 = Release|Gaming.Xbox.Scarlett.x64 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|Gaming.Xbox.XboxOne.x64.ActiveCfg = Release|Gaming.Xbox.XboxOne.x64 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|Gaming.Xbox.XboxOne.x64.Build.0 = Release|Gaming.Xbox.XboxOne.x64 + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug|Gaming.Desktop.x64.ActiveCfg = Debug|Gaming.Desktop.x64 + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug|Gaming.Desktop.x64.Build.0 = Debug|Gaming.Desktop.x64 + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug|Gaming.Xbox.Scarlett.x64.ActiveCfg = Debug|Gaming.Xbox.Scarlett.x64 + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug|Gaming.Xbox.Scarlett.x64.Build.0 = Debug|Gaming.Xbox.Scarlett.x64 + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug|Gaming.Xbox.XboxOne.x64.ActiveCfg = Debug|Gaming.Xbox.XboxOne.x64 + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Debug|Gaming.Xbox.XboxOne.x64.Build.0 = Debug|Gaming.Xbox.XboxOne.x64 + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release|Gaming.Desktop.x64.ActiveCfg = Release|Gaming.Desktop.x64 + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release|Gaming.Desktop.x64.Build.0 = Release|Gaming.Desktop.x64 + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release|Gaming.Xbox.Scarlett.x64.ActiveCfg = Release|Gaming.Xbox.Scarlett.x64 + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release|Gaming.Xbox.Scarlett.x64.Build.0 = Release|Gaming.Xbox.Scarlett.x64 + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release|Gaming.Xbox.XboxOne.x64.ActiveCfg = Release|Gaming.Xbox.XboxOne.x64 + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A}.Release|Gaming.Xbox.XboxOne.x64.Build.0 = Release|Gaming.Xbox.XboxOne.x64 + {40FB7794-D3C3-4CFE-BCF4-A80C96635682}.Debug|Gaming.Desktop.x64.ActiveCfg = Debug|Gaming.Desktop.x64 + {40FB7794-D3C3-4CFE-BCF4-A80C96635682}.Debug|Gaming.Desktop.x64.Build.0 = Debug|Gaming.Desktop.x64 + {40FB7794-D3C3-4CFE-BCF4-A80C96635682}.Debug|Gaming.Desktop.x64.Deploy.0 = Debug|Gaming.Desktop.x64 + {40FB7794-D3C3-4CFE-BCF4-A80C96635682}.Debug|Gaming.Xbox.Scarlett.x64.ActiveCfg = Debug|Gaming.Xbox.Scarlett.x64 + {40FB7794-D3C3-4CFE-BCF4-A80C96635682}.Debug|Gaming.Xbox.Scarlett.x64.Build.0 = Debug|Gaming.Xbox.Scarlett.x64 + {40FB7794-D3C3-4CFE-BCF4-A80C96635682}.Debug|Gaming.Xbox.Scarlett.x64.Deploy.0 = Debug|Gaming.Xbox.Scarlett.x64 + {40FB7794-D3C3-4CFE-BCF4-A80C96635682}.Debug|Gaming.Xbox.XboxOne.x64.ActiveCfg = Debug|Gaming.Xbox.XboxOne.x64 + {40FB7794-D3C3-4CFE-BCF4-A80C96635682}.Debug|Gaming.Xbox.XboxOne.x64.Build.0 = Debug|Gaming.Xbox.XboxOne.x64 + {40FB7794-D3C3-4CFE-BCF4-A80C96635682}.Debug|Gaming.Xbox.XboxOne.x64.Deploy.0 = Debug|Gaming.Xbox.XboxOne.x64 + {40FB7794-D3C3-4CFE-BCF4-A80C96635682}.Release|Gaming.Desktop.x64.ActiveCfg = Release|Gaming.Desktop.x64 + {40FB7794-D3C3-4CFE-BCF4-A80C96635682}.Release|Gaming.Desktop.x64.Build.0 = Release|Gaming.Desktop.x64 + {40FB7794-D3C3-4CFE-BCF4-A80C96635682}.Release|Gaming.Desktop.x64.Deploy.0 = Release|Gaming.Desktop.x64 + {40FB7794-D3C3-4CFE-BCF4-A80C96635682}.Release|Gaming.Xbox.Scarlett.x64.ActiveCfg = Release|Gaming.Xbox.Scarlett.x64 + {40FB7794-D3C3-4CFE-BCF4-A80C96635682}.Release|Gaming.Xbox.Scarlett.x64.Build.0 = Release|Gaming.Xbox.Scarlett.x64 + {40FB7794-D3C3-4CFE-BCF4-A80C96635682}.Release|Gaming.Xbox.Scarlett.x64.Deploy.0 = Release|Gaming.Xbox.Scarlett.x64 + {40FB7794-D3C3-4CFE-BCF4-A80C96635682}.Release|Gaming.Xbox.XboxOne.x64.ActiveCfg = Release|Gaming.Xbox.XboxOne.x64 + {40FB7794-D3C3-4CFE-BCF4-A80C96635682}.Release|Gaming.Xbox.XboxOne.x64.Build.0 = Release|Gaming.Xbox.XboxOne.x64 + {40FB7794-D3C3-4CFE-BCF4-A80C96635682}.Release|Gaming.Xbox.XboxOne.x64.Deploy.0 = Release|Gaming.Xbox.XboxOne.x64 + {DA956FD3-E143-46F2-9FE5-C77BEBC56B1A}.Debug|Gaming.Desktop.x64.ActiveCfg = Debug|Gaming.Desktop.x64 + {DA956FD3-E143-46F2-9FE5-C77BEBC56B1A}.Debug|Gaming.Desktop.x64.Build.0 = Debug|Gaming.Desktop.x64 + {DA956FD3-E143-46F2-9FE5-C77BEBC56B1A}.Debug|Gaming.Xbox.Scarlett.x64.ActiveCfg = Debug|Gaming.Xbox.Scarlett.x64 + {DA956FD3-E143-46F2-9FE5-C77BEBC56B1A}.Debug|Gaming.Xbox.Scarlett.x64.Build.0 = Debug|Gaming.Xbox.Scarlett.x64 + {DA956FD3-E143-46F2-9FE5-C77BEBC56B1A}.Debug|Gaming.Xbox.XboxOne.x64.ActiveCfg = Debug|Gaming.Xbox.XboxOne.x64 + {DA956FD3-E143-46F2-9FE5-C77BEBC56B1A}.Debug|Gaming.Xbox.XboxOne.x64.Build.0 = Debug|Gaming.Xbox.XboxOne.x64 + {DA956FD3-E143-46F2-9FE5-C77BEBC56B1A}.Release|Gaming.Desktop.x64.ActiveCfg = Release|Gaming.Desktop.x64 + {DA956FD3-E143-46F2-9FE5-C77BEBC56B1A}.Release|Gaming.Desktop.x64.Build.0 = Release|Gaming.Desktop.x64 + {DA956FD3-E143-46F2-9FE5-C77BEBC56B1A}.Release|Gaming.Xbox.Scarlett.x64.ActiveCfg = Release|Gaming.Xbox.Scarlett.x64 + {DA956FD3-E143-46F2-9FE5-C77BEBC56B1A}.Release|Gaming.Xbox.Scarlett.x64.Build.0 = Release|Gaming.Xbox.Scarlett.x64 + {DA956FD3-E143-46F2-9FE5-C77BEBC56B1A}.Release|Gaming.Xbox.XboxOne.x64.ActiveCfg = Release|Gaming.Xbox.XboxOne.x64 + {DA956FD3-E143-46F2-9FE5-C77BEBC56B1A}.Release|Gaming.Xbox.XboxOne.x64.Build.0 = Release|Gaming.Xbox.XboxOne.x64 + {55812185-D13C-4022-9C81-32E0F4A08305}.Debug|Gaming.Desktop.x64.ActiveCfg = Debug|Gaming.Desktop.x64 + {55812185-D13C-4022-9C81-32E0F4A08305}.Debug|Gaming.Desktop.x64.Build.0 = Debug|Gaming.Desktop.x64 + {55812185-D13C-4022-9C81-32E0F4A08305}.Debug|Gaming.Desktop.x64.Deploy.0 = Debug|Gaming.Desktop.x64 + {55812185-D13C-4022-9C81-32E0F4A08305}.Debug|Gaming.Xbox.Scarlett.x64.ActiveCfg = Debug|Gaming.Xbox.Scarlett.x64 + {55812185-D13C-4022-9C81-32E0F4A08305}.Debug|Gaming.Xbox.Scarlett.x64.Build.0 = Debug|Gaming.Xbox.Scarlett.x64 + {55812185-D13C-4022-9C81-32E0F4A08305}.Debug|Gaming.Xbox.Scarlett.x64.Deploy.0 = Debug|Gaming.Xbox.Scarlett.x64 + {55812185-D13C-4022-9C81-32E0F4A08305}.Debug|Gaming.Xbox.XboxOne.x64.ActiveCfg = Debug|Gaming.Xbox.XboxOne.x64 + {55812185-D13C-4022-9C81-32E0F4A08305}.Debug|Gaming.Xbox.XboxOne.x64.Build.0 = Debug|Gaming.Xbox.XboxOne.x64 + {55812185-D13C-4022-9C81-32E0F4A08305}.Debug|Gaming.Xbox.XboxOne.x64.Deploy.0 = Debug|Gaming.Xbox.XboxOne.x64 + {55812185-D13C-4022-9C81-32E0F4A08305}.Release|Gaming.Desktop.x64.ActiveCfg = Release|Gaming.Desktop.x64 + {55812185-D13C-4022-9C81-32E0F4A08305}.Release|Gaming.Desktop.x64.Build.0 = Release|Gaming.Desktop.x64 + {55812185-D13C-4022-9C81-32E0F4A08305}.Release|Gaming.Desktop.x64.Deploy.0 = Release|Gaming.Desktop.x64 + {55812185-D13C-4022-9C81-32E0F4A08305}.Release|Gaming.Xbox.Scarlett.x64.ActiveCfg = Release|Gaming.Xbox.Scarlett.x64 + {55812185-D13C-4022-9C81-32E0F4A08305}.Release|Gaming.Xbox.Scarlett.x64.Build.0 = Release|Gaming.Xbox.Scarlett.x64 + {55812185-D13C-4022-9C81-32E0F4A08305}.Release|Gaming.Xbox.Scarlett.x64.Deploy.0 = Release|Gaming.Xbox.Scarlett.x64 + {55812185-D13C-4022-9C81-32E0F4A08305}.Release|Gaming.Xbox.XboxOne.x64.ActiveCfg = Release|Gaming.Xbox.XboxOne.x64 + {55812185-D13C-4022-9C81-32E0F4A08305}.Release|Gaming.Xbox.XboxOne.x64.Build.0 = Release|Gaming.Xbox.XboxOne.x64 + {55812185-D13C-4022-9C81-32E0F4A08305}.Release|Gaming.Xbox.XboxOne.x64.Deploy.0 = Release|Gaming.Xbox.XboxOne.x64 + {1C9A3F71-35A5-4C56-B292-F4375B3C3649}.Debug|Gaming.Desktop.x64.ActiveCfg = Debug|Gaming.Desktop.x64 + {1C9A3F71-35A5-4C56-B292-F4375B3C3649}.Debug|Gaming.Desktop.x64.Build.0 = Debug|Gaming.Desktop.x64 + {1C9A3F71-35A5-4C56-B292-F4375B3C3649}.Debug|Gaming.Desktop.x64.Deploy.0 = Debug|Gaming.Desktop.x64 + {1C9A3F71-35A5-4C56-B292-F4375B3C3649}.Debug|Gaming.Xbox.Scarlett.x64.ActiveCfg = Debug|Gaming.Xbox.Scarlett.x64 + {1C9A3F71-35A5-4C56-B292-F4375B3C3649}.Debug|Gaming.Xbox.Scarlett.x64.Build.0 = Debug|Gaming.Xbox.Scarlett.x64 + {1C9A3F71-35A5-4C56-B292-F4375B3C3649}.Debug|Gaming.Xbox.Scarlett.x64.Deploy.0 = Debug|Gaming.Xbox.Scarlett.x64 + {1C9A3F71-35A5-4C56-B292-F4375B3C3649}.Debug|Gaming.Xbox.XboxOne.x64.ActiveCfg = Debug|Gaming.Xbox.XboxOne.x64 + {1C9A3F71-35A5-4C56-B292-F4375B3C3649}.Debug|Gaming.Xbox.XboxOne.x64.Build.0 = Debug|Gaming.Xbox.XboxOne.x64 + {1C9A3F71-35A5-4C56-B292-F4375B3C3649}.Debug|Gaming.Xbox.XboxOne.x64.Deploy.0 = Debug|Gaming.Xbox.XboxOne.x64 + {1C9A3F71-35A5-4C56-B292-F4375B3C3649}.Release|Gaming.Desktop.x64.ActiveCfg = Release|Gaming.Desktop.x64 + {1C9A3F71-35A5-4C56-B292-F4375B3C3649}.Release|Gaming.Desktop.x64.Build.0 = Release|Gaming.Desktop.x64 + {1C9A3F71-35A5-4C56-B292-F4375B3C3649}.Release|Gaming.Desktop.x64.Deploy.0 = Release|Gaming.Desktop.x64 + {1C9A3F71-35A5-4C56-B292-F4375B3C3649}.Release|Gaming.Xbox.Scarlett.x64.ActiveCfg = Release|Gaming.Xbox.Scarlett.x64 + {1C9A3F71-35A5-4C56-B292-F4375B3C3649}.Release|Gaming.Xbox.Scarlett.x64.Build.0 = Release|Gaming.Xbox.Scarlett.x64 + {1C9A3F71-35A5-4C56-B292-F4375B3C3649}.Release|Gaming.Xbox.Scarlett.x64.Deploy.0 = Release|Gaming.Xbox.Scarlett.x64 + {1C9A3F71-35A5-4C56-B292-F4375B3C3649}.Release|Gaming.Xbox.XboxOne.x64.ActiveCfg = Release|Gaming.Xbox.XboxOne.x64 + {1C9A3F71-35A5-4C56-B292-F4375B3C3649}.Release|Gaming.Xbox.XboxOne.x64.Build.0 = Release|Gaming.Xbox.XboxOne.x64 + {1C9A3F71-35A5-4C56-B292-F4375B3C3649}.Release|Gaming.Xbox.XboxOne.x64.Deploy.0 = Release|Gaming.Xbox.XboxOne.x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {40FB7794-D3C3-4CFE-BCF4-A80C96635682} = {D69D5741-611F-4E14-8541-1FEE94F50B5A} + {55812185-D13C-4022-9C81-32E0F4A08305} = {D69D5741-611F-4E14-8541-1FEE94F50B5A} + {1C9A3F71-35A5-4C56-B292-F4375B3C3649} = {D69D5741-611F-4E14-8541-1FEE94F50B5A} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C320C9F2-1A8F-41D7-B02B-6338F872BCAD} + EndGlobalSection +EndGlobal diff --git a/SDL2-2.30.5/VisualC-GDK/SDL/SDL.vcxproj b/SDL2-2.30.5/VisualC-GDK/SDL/SDL.vcxproj new file mode 100644 index 0000000..2097e69 --- /dev/null +++ b/SDL2-2.30.5/VisualC-GDK/SDL/SDL.vcxproj @@ -0,0 +1,797 @@ + + + + + Debug + Gaming.Desktop.x64 + + + Debug + Gaming.Xbox.Scarlett.x64 + + + Debug + Gaming.Xbox.XboxOne.x64 + + + Release + Gaming.Desktop.x64 + + + Release + Gaming.Xbox.Scarlett.x64 + + + Release + Gaming.Xbox.XboxOne.x64 + + + + SDL2 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} + SDL + 10.0 + + + + DynamicLibrary + $(DefaultPlatformToolset) + + + DynamicLibrary + $(DefaultPlatformToolset) + + + DynamicLibrary + $(DefaultPlatformToolset) + + + DynamicLibrary + $(DefaultPlatformToolset) + + + DynamicLibrary + $(DefaultPlatformToolset) + + + DynamicLibrary + $(DefaultPlatformToolset) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + + + + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + + + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + .\Debug/SDL.tlb + + + Disabled + $(ProjectDir)/../../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + DLL_EXPORT;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + false + Level3 + OldStyle + OnlyExplicitInline + true + + + _DEBUG;%(PreprocessorDefinitions) + + + setupapi.lib;winmm.lib;imm32.lib;version.lib;xgameruntime.lib;vcruntimed.lib;msvcrtd.lib;ucrtd.lib;msvcprtd.lib;%(AdditionalDependencies) + true + Windows + true + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + .\Debug/SDL.tlb + + + Disabled + $(ProjectDir)/../../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + DLL_EXPORT;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + false + Level3 + OldStyle + OnlyExplicitInline + true + + + _DEBUG;%(PreprocessorDefinitions) + + + setupapi.lib;winmm.lib;imm32.lib;version.lib;xgameruntime.lib;d3d12_xs.lib;uuid.lib;vcruntimed.lib;msvcrtd.lib;ucrtd.lib;msvcprtd.lib;%(AdditionalDependencies) + true + Windows + true + + + $(SolutionDir)\shaders\buildshaders.bat $(SolutionDir) + + + Building shader blobs (Xbox Series) + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + .\Debug/SDL.tlb + + + Disabled + $(ProjectDir)/../../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + DLL_EXPORT;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + false + Level3 + OldStyle + OnlyExplicitInline + true + + + _DEBUG;%(PreprocessorDefinitions) + + + setupapi.lib;winmm.lib;imm32.lib;version.lib;xgameruntime.lib;d3d12_x.lib;uuid.lib;vcruntimed.lib;msvcrtd.lib;ucrtd.lib;msvcprtd.lib;%(AdditionalDependencies) + true + Windows + true + + + $(SolutionDir)\shaders\buildshaders.bat $(SolutionDir) one + + + Building shader blobs (Xbox One) + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + .\Release/SDL.tlb + + + $(ProjectDir)/../../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + DLL_EXPORT;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + false + Level3 + ProgramDatabase + OnlyExplicitInline + true + + + NDEBUG;%(PreprocessorDefinitions) + + + setupapi.lib;winmm.lib;imm32.lib;version.lib;xgameruntime.lib;vcruntime.lib;msvcrt.lib;ucrt.lib;msvcprt.lib;%(AdditionalDependencies) + true + Windows + true + true + true + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + .\Release/SDL.tlb + + + $(ProjectDir)/../../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + DLL_EXPORT;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + false + Level3 + ProgramDatabase + OnlyExplicitInline + true + + + NDEBUG;%(PreprocessorDefinitions) + + + setupapi.lib;winmm.lib;imm32.lib;version.lib;xgameruntime.lib;d3d12_xs.lib;uuid.lib;vcruntime.lib;msvcrt.lib;ucrt.lib;msvcprt.lib;%(AdditionalDependencies) + true + Windows + true + true + true + + + $(SolutionDir)\shaders\buildshaders.bat $(SolutionDir) + + + Building shader blobs (Xbox Series) + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + .\Release/SDL.tlb + + + $(ProjectDir)/../../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + DLL_EXPORT;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + false + Level3 + ProgramDatabase + OnlyExplicitInline + true + + + NDEBUG;%(PreprocessorDefinitions) + + + setupapi.lib;winmm.lib;imm32.lib;version.lib;xgameruntime.lib;d3d12_x.lib;uuid.lib;vcruntime.lib;msvcrt.lib;ucrt.lib;msvcprt.lib;%(AdditionalDependencies) + true + Windows + true + true + true + + + $(SolutionDir)\shaders\buildshaders.bat $(SolutionDir) one + + + Building shader blobs (Xbox One) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + stdcpp17 + stdcpp17 + stdcpp17 + stdcpp17 + + + + + + + + + + + + + + + + + + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + stdcpp17 + stdcpp17 + stdcpp17 + stdcpp17 + + + stdcpp17 + stdcpp17 + stdcpp17 + stdcpp17 + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + stdcpp17 + stdcpp17 + stdcpp17 + stdcpp17 + + + + stdcpp17 + stdcpp17 + stdcpp17 + stdcpp17 + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CompileAsCpp + CompileAsCpp + CompileAsCpp + CompileAsCpp + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SDL2-2.30.5/VisualC-GDK/SDL/SDL.vcxproj.filters b/SDL2-2.30.5/VisualC-GDK/SDL/SDL.vcxproj.filters new file mode 100644 index 0000000..56494d4 --- /dev/null +++ b/SDL2-2.30.5/VisualC-GDK/SDL/SDL.vcxproj.filters @@ -0,0 +1,1392 @@ + + + + + {395b3af0-33d0-411b-b153-de1676bf1ef8} + + + {5a3e3167-75be-414f-8947-a5306df372b2} + + + {546d9ed1-988e-49d3-b1a5-e5b3d19de6c1} + + + {a56247ff-5108-4960-ba6a-6814fd1554ec} + + + {8880dfad-2a06-4e84-ab6e-6583641ad2d1} + + + {2b996a7f-f3e9-4300-a97f-2c907bcd89a9} + + + {5713d682-2bc7-4da4-bcf0-262a98f142eb} + + + {5e27e19f-b3f8-4e2d-b323-b00b2040ec86} + + + {a3ab9cff-8495-4a5c-8af6-27e43199a712} + + + {377061e4-3856-4f05-b916-0d3b360df0f6} + + + {226a6643-1c65-4c7f-92aa-861313d974bb} + + + {ef859522-a7fe-4a00-a511-d6a9896adf5b} + + + {01fd2642-4493-4316-b548-fb829f4c9125} + + + {cce7558f-590a-4f0a-ac0d-e579f76e588e} + + + {7a53c9e4-d4bd-40ed-9265-1625df685121} + + + {4c7a051c-ce7c-426c-bf8c-9187827f9052} + + + {97e2f79f-311b-42ea-81b2-e801649fdd93} + + + {baf97c8c-7e90-41e5-bff8-14051b8d3956} + + + {45e50d3a-56c9-4352-b811-0c60c49a2431} + + + {9d86e0ef-d6f6-4db2-bfc5-b3529406fa8d} + + + {b35fa13c-6ed2-4680-8c56-c7d71b76ceab} + + + {61b61b31-9e26-4171-a3bb-b969f1889726} + + + {f63aa216-6ee7-4143-90d3-32be3787f276} + + + {90bee923-89df-417f-a6c3-3e260a7dd54d} + + + {4c8ad943-c2fb-4014-9ca3-041e0ad08426} + + + {e90fa293-2828-4927-8113-35bf561024a9} + + + {3d68ae70-a9ff-46cf-be69-069f0b02aca0} + + + {ebc2fca3-3c26-45e3-815e-3e0581d5e226} + + + {47c445a2-7014-4e15-9660-7c89a27dddcf} + + + {d008487d-6ed0-4251-848b-79a68e3c1459} + + + {c9e8273e-13ae-47dc-bef8-8ad8e64c9a3d} + + + {0b8e136d-56ae-47e7-9981-e863a57ac616} + + + {bf3febd3-9328-43e8-b196-0fd3be8177dd} + + + {1a62dc68-52d2-4c07-9d81-d94dfe1d0d12} + + + {e9f01b22-34b3-4380-ade6-0e96c74e9c90} + + + {f674f22f-7841-4f3a-974e-c36b2d4823fc} + + + {d7ad92de-4e55-4202-9b2b-1bd9a35fe4dc} + + + {8311d79d-9ad5-4369-99fe-b2fb2659d402} + + + {6c4dfb80-fdf9-497c-a6ff-3cd8f22efde9} + + + {4810e35c-33cb-4da2-bfaf-452da20d3c9a} + + + {2cf93f1d-81fd-4bdc-998c-5e2fa43988bc} + + + {5752b7ab-2344-4f38-95ab-b5d3bc150315} + + + {7a0eae3d-f113-4914-b926-6816d1929250} + + + {ee602cbf-96a2-4b0b-92a9-51d38a727411} + + + {a812185b-9060-4a1c-8431-be4f66894626} + + + {31c16cdf-adc4-4950-8293-28ba530f3882} + + + {add61b53-8144-47d6-bd67-3420a87c4905} + + + {e7cdcf36-b462-49c7-98b7-07ea7b3687f4} + + + {82588eef-dcaa-4f69-b2a9-e675940ce54c} + + + {560239c3-8fa1-4d23-a81a-b8408b2f7d3f} + + + {81711059-7575-4ece-9e68-333b63e992c4} + + + {1e44970f-7535-4bfb-b8a5-ea0cea0349e0} + + + {1dd91224-1176-492b-a2cb-e26153394db0} + + + {e3ecfe50-cf22-41d3-8983-2fead5164b47} + + + {5521d22f-1e52-47a6-8c52-06a3b6bdefd7} + + + {4755f3a6-49ac-46d6-86be-21f5c21f2197} + + + {f48c2b17-1bee-4fec-a7c8-24cf619abe08} + + + {3ab60a46-e18e-450a-a916-328fb8547e59} + + + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + + + + API Headers + + + API Headers + + + API Headers + + + audio + + + audio + + + audio + + + audio + + + core\windows + + + core\windows + + + core\windows + + + core\windows + + + core\windows + + + dynapi + + + dynapi + + + dynapi + + + events + + + events + + + events + + + events + + + events + + + events + + + events + + + events + + + events + + + events + + + events + + + events + + + haptic + + + haptic + + + joystick + + + joystick + + + joystick + + + joystick + + + joystick + + + joystick + + + libm + + + libm + + + hidapi\hidapi + + + locale + + + misc + + + audio\directsound + + + audio\disk + + + audio\dummy + + + audio\winmm + + + audio\wasapi + + + haptic\windows + + + haptic\windows + + + haptic\windows + + + joystick\hidapi + + + joystick\hidapi + + + joystick\windows + + + joystick\windows + + + joystick\windows + + + joystick\windows + + + joystick\virtual + + + video + + + video + + + video + + + video + + + video + + + video + + + video + + + video + + + video + + + video + + + video + + + video + + + video\dummy + + + video\dummy + + + video\dummy + + + video\yuv2rgb + + + video\yuv2rgb + + + video\yuv2rgb + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + timer + + + thread + + + thread + + + thread\windows + + + thread\windows + + + thread\generic + + + sensor + + + sensor + + + sensor\dummy + + + sensor\windows + + + render + + + render + + + render + + + render\direct3d + + + render\direct3d11 + + + render\opengl + + + render\opengl + + + render\opengles2 + + + render\opengles2 + + + render\software + + + render\software + + + render\software + + + render\software + + + render\software + + + render\software + + + render\software + + + render\software + + + render\software + + + power + + + video\khronos\vulkan + + + video\khronos\vulkan + + + video\khronos\vulkan + + + video\khronos\vulkan + + + video\khronos\vulkan + + + video\khronos\vulkan + + + video\khronos\vulkan + + + video\khronos\vulkan + + + video\khronos\vulkan + + + video\khronos\vulkan + + + video\khronos\vulkan + + + video\khronos\vulkan + + + video\khronos\vulkan + + + video\khronos\vulkan + + + video\khronos\vulkan + + + video\khronos\vulkan + + + video\khronos\vulkan + + + video\khronos\vulkan + + + video\khronos\vulkan + + + video\khronos\vulkan + + + + + + + render\direct3d12 + + + + API Headers + + + core\gdk + + + render\direct3d12 + + + + + + + + + + + + + + audio + + + audio + + + audio + + + audio + + + audio + + + audio + + + atomic + + + atomic + + + core\windows + + + core\windows + + + core\windows + + + core\windows + + + cpuinfo + + + dynapi + + + events + + + events + + + events + + + events + + + events + + + events + + + events + + + events + + + events + + + events + + + file + + + filesystem\gdk + + + haptic + + + hidapi + + + joystick + + + joystick + + + joystick + + + joystick + + + libm + + + libm + + + libm + + + libm + + + libm + + + libm + + + libm + + + libm + + + libm + + + libm + + + libm + + + libm + + + libm + + + libm + + + libm + + + libm + + + libm + + + libm + + + libm + + + libm + + + loadso\windows + + + misc + + + misc\windows + + + locale\windows + + + locale + + + audio\directsound + + + audio\disk + + + audio\dummy + + + audio\winmm + + + audio\wasapi + + + audio\wasapi + + + haptic\windows + + + haptic\windows + + + haptic\windows + + + haptic\dummy + + + joystick\dummy + + + joystick\hidapi + + + joystick\hidapi + + + joystick\hidapi + + + joystick\hidapi + + + joystick\hidapi + + + joystick\hidapi + + + joystick\hidapi + + + joystick\hidapi + + + joystick\hidapi + + + joystick\hidapi + + + joystick\hidapi + + + joystick\hidapi + + + joystick\hidapi + + + joystick\hidapi + + + joystick\hidapi + + + joystick\hidapi + + + joystick\hidapi + + + joystick\windows + + + joystick\windows + + + joystick\windows + + + joystick\windows + + + joystick\windows + + + joystick\virtual + + + video + + + video + + + video + + + video + + + video + + + video + + + video + + + video + + + video + + + video + + + video + + + video + + + video + + + video + + + video + + + video + + + video + + + video + + + video + + + video + + + video + + + video\dummy + + + video\dummy + + + video\dummy + + + video\yuv2rgb + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + timer + + + timer\windows + + + thread + + + thread\windows + + + thread\windows + + + thread\windows + + + thread\windows + + + thread\windows + + + thread\generic + + + stdlib + + + stdlib + + + stdlib + + + stdlib + + + stdlib + + + stdlib + + + stdlib + + + stdlib + + + stdlib + + + sensor + + + sensor\dummy + + + sensor\windows + + + render + + + render + + + render + + + render\direct3d + + + render\direct3d + + + render\direct3d11 + + + render\direct3d11 + + + render\opengl + + + render\opengl + + + render\opengles2 + + + render\opengles2 + + + render\software + + + render\software + + + render\software + + + render\software + + + render\software + + + render\software + + + render\software + + + render\software + + + power + + + + power\windows + + + render\direct3d12 + + + render\direct3d12 + + + stdlib + + + core\gdk + + + render\direct3d12 + + + render\direct3d12 + + + render\direct3d12 + + + + + + diff --git a/SDL2-2.30.5/VisualC-GDK/SDLmain/SDLmain.vcxproj b/SDL2-2.30.5/VisualC-GDK/SDLmain/SDLmain.vcxproj new file mode 100644 index 0000000..a2c05b1 --- /dev/null +++ b/SDL2-2.30.5/VisualC-GDK/SDLmain/SDLmain.vcxproj @@ -0,0 +1,211 @@ + + + + + Debug + Gaming.Desktop.x64 + + + Debug + Gaming.Xbox.Scarlett.x64 + + + Debug + Gaming.Xbox.XboxOne.x64 + + + Release + Gaming.Desktop.x64 + + + Release + Gaming.Xbox.Scarlett.x64 + + + Release + Gaming.Xbox.XboxOne.x64 + + + + + + + SDL2main + {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} + SDLmain + 10.0 + + + + StaticLibrary + $(DefaultPlatformToolset) + + + StaticLibrary + $(DefaultPlatformToolset) + + + StaticLibrary + $(DefaultPlatformToolset) + + + StaticLibrary + $(DefaultPlatformToolset) + + + StaticLibrary + $(DefaultPlatformToolset) + + + StaticLibrary + $(DefaultPlatformToolset) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + + + + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + + + + + + + + $(ProjectDir)/../../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + Level3 + OldStyle + true + + + + + + $(ProjectDir)/../../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + Level3 + OldStyle + true + + + + + + $(ProjectDir)/../../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + Level3 + OldStyle + true + + + + + + Disabled + $(ProjectDir)/../../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + false + Level3 + OldStyle + true + + + + + + Disabled + $(ProjectDir)/../../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + false + Level3 + OldStyle + true + + + + + + Disabled + $(ProjectDir)/../../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + false + Level3 + OldStyle + true + + + + + + \ No newline at end of file diff --git a/SDL2-2.30.5/VisualC-GDK/SDLtest/SDLtest.vcxproj b/SDL2-2.30.5/VisualC-GDK/SDLtest/SDLtest.vcxproj new file mode 100644 index 0000000..c2e9348 --- /dev/null +++ b/SDL2-2.30.5/VisualC-GDK/SDLtest/SDLtest.vcxproj @@ -0,0 +1,226 @@ + + + + + Debug + Gaming.Desktop.x64 + + + Debug + Gaming.Xbox.Scarlett.x64 + + + Debug + Gaming.Xbox.XboxOne.x64 + + + Release + Gaming.Desktop.x64 + + + Release + Gaming.Xbox.Scarlett.x64 + + + Release + Gaming.Xbox.XboxOne.x64 + + + + SDL2test + {DA956FD3-E143-46F2-9FE5-C77BEBC56B1A} + SDLtest + 10.0 + + + + StaticLibrary + $(DefaultPlatformToolset) + + + StaticLibrary + $(DefaultPlatformToolset) + + + StaticLibrary + $(DefaultPlatformToolset) + + + StaticLibrary + $(DefaultPlatformToolset) + + + StaticLibrary + $(DefaultPlatformToolset) + + + StaticLibrary + $(DefaultPlatformToolset) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + + + + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + + + + + + + + $(ProjectDir)/../../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + Level3 + OldStyle + true + + + + + + $(ProjectDir)/../../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + Level3 + OldStyle + true + + + + + + $(ProjectDir)/../../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + Level3 + OldStyle + true + + + + + + Disabled + $(ProjectDir)/../../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + false + Level3 + OldStyle + true + + + + + + Disabled + $(ProjectDir)/../../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + false + Level3 + OldStyle + true + + + + + + Disabled + $(ProjectDir)/../../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + false + Level3 + OldStyle + true + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SDL2-2.30.5/VisualC-GDK/clean.sh b/SDL2-2.30.5/VisualC-GDK/clean.sh new file mode 100644 index 0000000..235b79c --- /dev/null +++ b/SDL2-2.30.5/VisualC-GDK/clean.sh @@ -0,0 +1,7 @@ +#!/bin/sh +find . -type f \( -name '*.user' -o -name '*.sdf' -o -name '*.ncb' -o -name '*.suo' \) -print -delete +find . -type f \( -name '*.bmp' -o -name '*.wav' -o -name '*.dat' \) -print -delete +find . -depth -type d \( -name Gaming.Desktop.x64 \) -exec rm -rv {} \; +find . -depth -type d \( -name Gaming.Xbox.Scarlett.x64 \) -exec rm -rv {} \; +find . -depth -type d \( -name Gaming.Xbox.XboxOne.x64 \) -exec rm -rv {} \; +rm shaders/*.h diff --git a/SDL2-2.30.5/VisualC-GDK/logos/Logo100x100.png b/SDL2-2.30.5/VisualC-GDK/logos/Logo100x100.png new file mode 100644 index 0000000000000000000000000000000000000000..2d0333dbd273699a1513b8d2afaa40555bff986b GIT binary patch literal 10832 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 literal 0 HcmV?d00001 diff --git a/SDL2-2.30.5/VisualC-GDK/logos/Logo150x150.png b/SDL2-2.30.5/VisualC-GDK/logos/Logo150x150.png new file mode 100644 index 0000000000000000000000000000000000000000..046a8fb142c1bd3c161f5640e534c3215a348103 GIT binary patch literal 12709 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 literal 0 HcmV?d00001 diff --git a/SDL2-2.30.5/VisualC-GDK/logos/Logo44x44.png b/SDL2-2.30.5/VisualC-GDK/logos/Logo44x44.png new file mode 100644 index 0000000000000000000000000000000000000000..3ca25b565e0073f90af055eb44e449cf42aec262 GIT binary patch literal 7460 zcmV+<9oyoGP) zaB^>EX>4U6ba`-PAZ2)IW&i+q+U=TIa^$>~h2OD?UIOM}IT$V?dIw&9e}_!fY`6V~ z!%vnrhtKbB zd@h*vhvj^Jm~Hqh<7-(z{hk}aIEC?2bkR~s{`o(?cS`z+Y4Te6U!Uqo;(g&;$HVXO zbKgSuhX8(i_e=cz*UZxQaJ&P3Evx<#r_b?FemS1L-6sAtqY%H{IsQ1Kw7x?5d;IP_ z{a$-lH*|YpS`HT5GGqso7G?t+d)&>ut2zQ_sEh+FS2^^f}^4z*upkjyC!jV@_^5^JJ{a z`I7@HuC($htFE^C8f$LKXXjmZ-EH?h_B`>V0|dBJPdojLGc6dUWZ8;UYu0VpywuuF zH{WvWZMWZX=eMkVvift@e$CuJ&RY0nEk23TdF^}FINaLT5J7NKlru6Gb0FhQ8K9t} za^`!;IVy9?nIAE^luBflMaelq86$()LM%6Y%iZ_P{oTAdqWiDrE&eHUPO1BMWX>sd zKV22i75z~Xg^M{K4YKarN8v*{_2JQ9q2zj&^iffySL}%a)O2K zty@2E-kHnxvD`+v>$H5 z=01%!yL9qe)okDB8=ZSY8s0LorPON~gI}%x?Cb~R~w3bV`pVD-9;9?d|@43di z+XaYh(EC-_+?C3n`OwRD*05A-S~Z=zGANNkbAhh!HaBo${h4d2yMl?J!(rIQ+%%6u zD(*N9;fVbqLr!*rdTw2QKKtdw1GQ&l+Z`ME&GBz>4 zEXUAahm{QlIdR@5wah2<-Gb2~bBC7ZS?8HQk+aMk}gEOtbBGMH0Rdd*FB{YHwyEdVPhl0xoUceKvvR*FGTF7)%>~4e-Sem z&OLF?y1?#Lh`?#o-!*#ow7MXC@;_ePI-S3gM_$*YZ0W=?G^iY4EUKuN8;)OH#zF#Htq zTskopdeQ=uO6Z$2i-gim$yA$jVZUDEr`ksM2tZpDQ!r5bmg9+`_^iMe=Ouzc9|P*a0rsaN5zP}<<}kt-bxlaP zju2Q}0o!0Gs1?vkMRw7uQfwJ;F9W#-DRwtedXzKJiLisbz!)IoMkv!iu*3{D-Im9E zy2NH0`!^l1hAV4nh{MzwFf|It71p8JAq$QTQOgLu;1fniecS|Bq4iVqR5K8Jps~;q z!h;@R%9b-XT?rh-vR(Wd;5r$m-(+zCjY2b+Zh2yLOKe9dNS&d?>lxvIP}$&eI5yTz z6Zl!F`s?V-%O}7(^H})B)K!c0_@+TgG!f7i4NAmgp9YXd1~`adI*?ocfTauRL9M+; zq_7K#MtXU$kV1ny7QhFG(eQ;1q~L{?Co=&CNKt3MbIgf z4VO`;b_l}ASfXiGJdGfAhK0zA7cdMaL6QJT{9|3AWfpgZ3z{}X5_)9=1=^vY5-3Q- zAV0pXQc3*)=U^({&@H3(^p@e-JO7~ypJJnlDL3~l;I~SAKm6&le^iY>%i|?jhmZkg zh}bMCmA5yPXQ`f;)m{i0Ac&g9nNcn13aW|>4hgM2M`Z^4qK68LhO7+yDpX?yswl+v zvUWp5)Fwk`@$eO7M#ky7g;ojSlnnNNM2M%UcMg?h?-*c1UZ?Ylm`?+3!B`{2BR>Js zueRx7qYUT)#9ltv%djH@3r>GX-U3M2?*_Isw-f%y@hQQbtG?>=Tq(h)Ca=I(#ZSgQZ`7?YBY;WCfwVJjSmknCN({i9dPi zbGqJ_FHQNq+TG_3;{(I z-R@UmAkXYkYZV+G+L4AxROZz5!j4FdAiyX0YTFsiyMhPM2V&)!8%?*uaatUDNumpP7JK?GpsC*{2YMTK}eo%u-p1-Xby9x{#%AeNf6Q{xB??%8|NPl!+T zT97m1M)TRks6?CGA5nJPJ{?KGsBXrcHuNis4Js~In{Az7sFUlcw8Wu$E6Yrg{ooT*%Fq9Rt_O>Sh z(9z>dP8dNRp}zhbl;fIObU3_rb$fM+^)<$McHz3(sN$+=UEI&d5AA9{xD$&bmWI_BF5V z0cm@X-52f161*9JVfuj7VpvTdQwK~KUE;_pa*CVK@1J8+iX{Rc@d@d~&SN(2^Xy69 zT%~^~AF7gkVV7u}>_G8&ZnH+s9?Dp-D;tB|$05vw7_c`;w<2%RRoL2%>8mO3E=3R8 zuhJ6*x=k0JXGTIb~defD;b(#AoiZ6CRH^ za^wkG4)aB=gZq64F5RS3_(AR5qQFcZy=Z1wvod7>;k`?3KUWgEg%_aP_V>{+3!pIFALS6@pnf+@ zV?d##tcOV8_OWD?H*`u)R)y@N|8baw`9cPQz-|CSqh>*!Nk89C(H&$B#%z$lc2KmP z=7}flxGAMe4pkVq9^7@$czQIe16QV3{(AH*m$DvQjWP#5HL0Dct%xH%31g>S0l?fu zv#=tqh`-?y-yGPLkOcI>vt7g)SR?H|c3J$eXgsE=y$-wJ7IwGNji?&1{-7FAw_BPN zsNE_@8j=hIdb?sa09VW!c@4FSOYPLI~6E%b()N4&ofdLgK-uXH|g(M0@3Ro;{(# zj03=&(B^Z~+-Qi}PZRS*j1*0SsR8HKUX#?up7Ura?c$?Y1!!x2B2Xx`J0A*9Ep(~q z5FsM~3>mpk2AEQEFt|2O8#sr#qp)SzT8`PrhAV3rN_#si2bfgPJ3HMH<`w&4@U%OQ zmvcG9sIm#T-q~0MGz%r_X;cCRhvuC}$4&__(F+VeXj*G%k9bFW=rDH&3tk1Sbn?-) zA)rLa%Z^z{3%t~fS;v{z5Bp(Mgr_u~{r)J+>sF!mDSKo)fySVrzQO0EO$Isu@{nW@ zQJT0+M*TphLIwT-R)|D?L`T#hLaib5vbG|zCGZ-QQjg}qDHsB$ z9?A{46DqR-BMHQzsHp38h73>;7J{cxIeCPV(Ti9kvXNq8)t%Xm($PTBN6>Eb+S@IX zi6?{T=oy2iJJgI{Ai=FkrylLcf*x`(_<6+{*d>!FPc)I9aX>QKKf>p814EAatR3+! z>)w`8bDb)ZyTCa@aZeGzp^B;41p^WEl;GhS7x$$(wQmc^mPWmwIu~{f*=UfLgdF@& z5V{&dRn5rs)UGGhTM3+H{4C?ZdT`o(O^jE$}(EbX)WR z#fr|>-=@r{C?k}RVt^cay~~prlSmYCYd&ox&4M8)7R)>uvJfXul^I_SSI5wDqp^z4 z<#aE6hm&phr2epbWf^rA^4MWyVmGk8a%U^c>v--D06VFD1W!jMm+RkobLAsSA5(!s zq{( zwWTflv#XUdQoU!SS+(Oo4ozsZv6Lc8YOi;Wcr+|TFI#gBr@ytKU4OJ{Mw!vU;5bGB z%A(m!2tp+;v>8ez!d@AJjS=$I<<3G04^Uo<#|#j!9tUc|9?3c%Lr9p$id0!^FvqM^ z)2b%xM85;Z)7%6I*TsM9VIx>WX`-+Z_h{INW~U0Z@kG?%k~qp_#)uq1QZ&}=acEX3 zkd7K@dbEo0nz?`W+v>l%qXY=M-q6urHYy7r27vQoKSh!hXIwRLTpe%e+k^abA#3_F zz_n9;o4P;dQh#?K9z%;EQ)-ykW}%rzz!FkR8FYKL<}JVK_HO;5hd!pSAoGXUp!9V*As675YQWG+<;^Q)g5IX4%7asTeBHEj2b>WLf<;hPOWUP{N+UhvoWk1CF-D$P zGB;iCyuA|i!!1do9s&x(+F8p5%f7$ZnK{o<^XWi%);&3E}_q=R|HHAE8M@lH%ehxE37zS*$v^IP2=*DhPriY`*(eMzB3j1MmFt++O%}e`@|tuloaA~;t_)yB!1+&?D8Aug2MvO3>oR<9C3(PEVQuP z!mMbh#FNBfMb#)@$hfR<-r}s5Dy-2be_=4EEvL9nHHa7%5k~?dWK^($5-db$*GMsu zr1PkUf57o4$R(3&1B@K=C_{zh_`(0+_iWAl#JHOji~{X1w*4^#1a^UX)waKnZM%K~ z_@99*t?4hjm-m||pnw6y}Zg=!g70wLytB|w=_2;nB=MUwm6J*R(gE-u#uBI)!W z?{{Wr&+d8bcfY^i@BDrTl1L(nB$7xXiT@M)hYpGse-jU^ybmG7uww*(ue!$l&I@<| z354|>VVEfCT=AoU#`=qG-<)NT_+cRk?0a=Y!oVckc7|@Kn%V7dJ*+CrZ@hH6CTjo- zfv*8oz<5peB+vr<0r(s6G%zjUI}Q*4_5%&Tzv9Gw)ioBd0VvSoyafEw{ZnxmhJln4 z|Dl6)1iH#Xq44LXPAUD1Z4$YUuH}M_$}})P*D&mz!6}I z?q35uKOA8bg}^)@ z-SzGq@Bq*`T)+kz>p>|S_%5*1)xRbluvd#26|;Eeu`l~UJs%21HVTws0DpIlDc8^c z2AY8Nz~n3L4EtY;H(zwU_5s(Ab*uZyrrmt|XKx*AJ$~wrp-_0P0XznDBq&!1%mN+< zj$gQs%DMqp+oN4&OlWU>ow|p=)I70t!rPH>bcLbSoT0ZYKhT#j$Go7l_~IzmPfOVD zf@39|T3o?HE59x}yLvk!vFJQQzwZOS2UG$xfd#;pgt?1G5kz;o+5>tI9}{v)D)3d; zT=U}V2UeUP7%H}ajlf!9u;)Y*W@>tSPH}m=P82r*(=WH6uX|g3j}%(2|=l)_szS2-;6Jt{RYqmSiq75vb%uKyPhk6Z-7YC?NzS66TlPN zo!poQIKJu{k>EPN4m8$(GVdE6rr$W9wv%V4rg*GMDV-g{S6wrjXxa`e2R^t$rbEZU zUBEFQG1Co)7?2fctdD%cdKYSurTH12x&=31Q=Xcda<2hA0{j!Ohgs}|HuF7N2^)we zTw%RO?*di=bAe;7^lNKUBVCbUt1=<@=8~DroS2p7%k`E!((yaCT^}!gOdu1;(UI-| z=Yd`zHq?EJjJ#4nU!JMUZ?(gHl zHB|*bv&XV>P1F1Wf(A6JtrfI@w}Bo#-sAGuATU8&uw6gLif*bQH{HXM1r>zCk($#TeQQ#^DM8CJ?omp; zR=;J-$MrxWTKr7_R9-*(Vx0g)?vl;myVH zq~Q#8B0L$WX#XV#hCpLI6RKPd~B#l6lr}(J7^rhGFyoMcQXmN+y<_KKxO0mr_t$yOwwUylYg%L_8v| zTLNL5Cm)$lzBgN_bXBrp%bsVXQpG8zdE2<0%;xOu^arI>o286Io~v6o@|o^3hr;+z z6m*>JDk}8lUuT*|dh4;azG-EXJ~V_lHDgAVef-1`1_y@-hQhq}k0x%txf0v9$;!&$ zryIAKcYozJuat7yySoqEKCv`^R#9QzbjNlkpC1@HZd&FWO39t$^3o0j&h+zPOAD`V z-i%V}(-V&4U~?m;X(EKcvdoO`?!LU7oUAEAh&f&7dZy)$%PCPPGZu?EM~=4TO`cQ~ zjM;Y1z~E4NPw)A(@wwSD7PHR`}CDP>PIYTLGBv;Ftm*!%wbqq5jl zW8eM;va>RX#cUi$5{H<6t`uX=!OJzWq*w5F@IX iL=s6Pkwg-oUHli9?UpW?NmoYz0000 literal 0 HcmV?d00001 diff --git a/SDL2-2.30.5/VisualC-GDK/logos/Logo480x480.png b/SDL2-2.30.5/VisualC-GDK/logos/Logo480x480.png new file mode 100644 index 0000000000000000000000000000000000000000..11231500eb28e235b4b344ef60b4080c6bd38a52 GIT binary patch literal 28677 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 literal 0 HcmV?d00001 diff --git a/SDL2-2.0.12/test/axis.bmp b/SDL2-2.30.5/VisualC-GDK/logos/SplashScreenImage.png similarity index 58% rename from SDL2-2.0.12/test/axis.bmp rename to SDL2-2.30.5/VisualC-GDK/logos/SplashScreenImage.png index 2b3a7c8af6aa0bbefe26885523d7eb4387841606..def578f665e3ae62954bc864dd7f564641866681 100644 GIT binary patch delta 594 zcmV-Y0p|llRbufA9 zkIM=HVZ7 z{7G`jTx0k4ePezWeBoAZ$9^B!{^9~;HIBJ3;oFX^oO!hKaUHK*E&}y-w|H(J+c2i= zWd+eY?9=YY{(m5*%Ya=@@i@{;Ao6DGd+-liV?A&mvCIPo44CoCgn9sLwf}b zu*x&+N8}mC8Q7SAnYX#6ULzM6JWs^#XHagJ^)8G9Y)CK2fdK=|h*^$h9@1^Y#{1mo z18K<3t5zp^FYtH(DYMk`gjnQ&6*1~C%tw6&IkQ+Vh(T&I8?12em>$4hH;VuxzyOr-(+#82FZ8o*$bB~tz TTyt+)M&qkJSr72>Nc{*u97*TN diff --git a/SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_Colors.hlsl b/SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_Colors.hlsl new file mode 100644 index 0000000..47eff4c --- /dev/null +++ b/SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_Colors.hlsl @@ -0,0 +1,19 @@ +struct PixelShaderInput +{ + float4 pos : SV_POSITION; + float2 tex : TEXCOORD0; + float4 color : COLOR0; +}; + +#define ColorRS \ + "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \ + "DENY_DOMAIN_SHADER_ROOT_ACCESS |" \ + "DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \ + "DENY_HULL_SHADER_ROOT_ACCESS )," \ + "RootConstants(num32BitConstants=32, b0)" + +[RootSignature(ColorRS)] +float4 main(PixelShaderInput input) : SV_TARGET0 +{ + return input.color; +} \ No newline at end of file diff --git a/SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_NV12_BT601.hlsl b/SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_NV12_BT601.hlsl new file mode 100644 index 0000000..cffbc22 --- /dev/null +++ b/SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_NV12_BT601.hlsl @@ -0,0 +1,43 @@ +Texture2D theTextureY : register(t0); +Texture2D theTextureUV : register(t1); +SamplerState theSampler : register(s0); + +struct PixelShaderInput +{ + float4 pos : SV_POSITION; + float2 tex : TEXCOORD0; + float4 color : COLOR0; +}; + +#define NVRS \ + "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \ + " DENY_DOMAIN_SHADER_ROOT_ACCESS |" \ + " DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \ + " DENY_HULL_SHADER_ROOT_ACCESS )," \ + "RootConstants(num32BitConstants=32, b0),"\ + "DescriptorTable ( SRV(t0), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( SRV(t1), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( Sampler(s0), visibility = SHADER_VISIBILITY_PIXEL )" + +[RootSignature(NVRS)] +float4 main(PixelShaderInput input) : SV_TARGET +{ + const float3 offset = {-0.0627451017, -0.501960814, -0.501960814}; + const float3 Rcoeff = {1.1644, 0.0000, 1.5960}; + const float3 Gcoeff = {1.1644, -0.3918, -0.8130}; + const float3 Bcoeff = {1.1644, 2.0172, 0.0000}; + + float4 Output; + + float3 yuv; + yuv.x = theTextureY.Sample(theSampler, input.tex).r; + yuv.yz = theTextureUV.Sample(theSampler, input.tex).rg; + + yuv += offset; + Output.r = dot(yuv, Rcoeff); + Output.g = dot(yuv, Gcoeff); + Output.b = dot(yuv, Bcoeff); + Output.a = 1.0f; + + return Output * input.color; +} \ No newline at end of file diff --git a/SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_NV12_BT709.hlsl b/SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_NV12_BT709.hlsl new file mode 100644 index 0000000..81d409c --- /dev/null +++ b/SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_NV12_BT709.hlsl @@ -0,0 +1,43 @@ +Texture2D theTextureY : register(t0); +Texture2D theTextureUV : register(t1); +SamplerState theSampler : register(s0); + +struct PixelShaderInput +{ + float4 pos : SV_POSITION; + float2 tex : TEXCOORD0; + float4 color : COLOR0; +}; + +#define NVRS \ + "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \ + " DENY_DOMAIN_SHADER_ROOT_ACCESS |" \ + " DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \ + " DENY_HULL_SHADER_ROOT_ACCESS )," \ + "RootConstants(num32BitConstants=32, b0),"\ + "DescriptorTable ( SRV(t0), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( SRV(t1), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( Sampler(s0), visibility = SHADER_VISIBILITY_PIXEL )" + +[RootSignature(NVRS)] +float4 main(PixelShaderInput input) : SV_TARGET +{ + const float3 offset = {-0.0627451017, -0.501960814, -0.501960814}; + const float3 Rcoeff = {1.1644, 0.0000, 1.7927}; + const float3 Gcoeff = {1.1644, -0.2132, -0.5329}; + const float3 Bcoeff = {1.1644, 2.1124, 0.0000}; + + float4 Output; + + float3 yuv; + yuv.x = theTextureY.Sample(theSampler, input.tex).r; + yuv.yz = theTextureUV.Sample(theSampler, input.tex).rg; + + yuv += offset; + Output.r = dot(yuv, Rcoeff); + Output.g = dot(yuv, Gcoeff); + Output.b = dot(yuv, Bcoeff); + Output.a = 1.0f; + + return Output * input.color; +} \ No newline at end of file diff --git a/SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_NV12_JPEG.hlsl b/SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_NV12_JPEG.hlsl new file mode 100644 index 0000000..494bce5 --- /dev/null +++ b/SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_NV12_JPEG.hlsl @@ -0,0 +1,43 @@ +Texture2D theTextureY : register(t0); +Texture2D theTextureUV : register(t1); +SamplerState theSampler : register(s0); + +struct PixelShaderInput +{ + float4 pos : SV_POSITION; + float2 tex : TEXCOORD0; + float4 color : COLOR0; +}; + +#define NVRS \ + "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \ + " DENY_DOMAIN_SHADER_ROOT_ACCESS |" \ + " DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \ + " DENY_HULL_SHADER_ROOT_ACCESS )," \ + "RootConstants(num32BitConstants=32, b0),"\ + "DescriptorTable ( SRV(t0), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( SRV(t1), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( Sampler(s0), visibility = SHADER_VISIBILITY_PIXEL )" + +[RootSignature(NVRS)] +float4 main(PixelShaderInput input) : SV_TARGET +{ + const float3 offset = {0.0, -0.501960814, -0.501960814}; + const float3 Rcoeff = {1.0000, 0.0000, 1.4020}; + const float3 Gcoeff = {1.0000, -0.3441, -0.7141}; + const float3 Bcoeff = {1.0000, 1.7720, 0.0000}; + + float4 Output; + + float3 yuv; + yuv.x = theTextureY.Sample(theSampler, input.tex).r; + yuv.yz = theTextureUV.Sample(theSampler, input.tex).rg; + + yuv += offset; + Output.r = dot(yuv, Rcoeff); + Output.g = dot(yuv, Gcoeff); + Output.b = dot(yuv, Bcoeff); + Output.a = 1.0f; + + return Output * input.color; +} \ No newline at end of file diff --git a/SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_NV21_BT601.hlsl b/SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_NV21_BT601.hlsl new file mode 100644 index 0000000..794c763 --- /dev/null +++ b/SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_NV21_BT601.hlsl @@ -0,0 +1,43 @@ +Texture2D theTextureY : register(t0); +Texture2D theTextureUV : register(t1); +SamplerState theSampler : register(s0); + +struct PixelShaderInput +{ + float4 pos : SV_POSITION; + float2 tex : TEXCOORD0; + float4 color : COLOR0; +}; + +#define NVRS \ + "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \ + " DENY_DOMAIN_SHADER_ROOT_ACCESS |" \ + " DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \ + " DENY_HULL_SHADER_ROOT_ACCESS )," \ + "RootConstants(num32BitConstants=32, b0),"\ + "DescriptorTable ( SRV(t0), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( SRV(t1), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( Sampler(s0), visibility = SHADER_VISIBILITY_PIXEL )" + +[RootSignature(NVRS)] +float4 main(PixelShaderInput input) : SV_TARGET +{ + const float3 offset = {-0.0627451017, -0.501960814, -0.501960814}; + const float3 Rcoeff = {1.1644, 0.0000, 1.5960}; + const float3 Gcoeff = {1.1644, -0.3918, -0.8130}; + const float3 Bcoeff = {1.1644, 2.0172, 0.0000}; + + float4 Output; + + float3 yuv; + yuv.x = theTextureY.Sample(theSampler, input.tex).r; + yuv.yz = theTextureUV.Sample(theSampler, input.tex).gr; + + yuv += offset; + Output.r = dot(yuv, Rcoeff); + Output.g = dot(yuv, Gcoeff); + Output.b = dot(yuv, Bcoeff); + Output.a = 1.0f; + + return Output * input.color; +} \ No newline at end of file diff --git a/SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_NV21_BT709.hlsl b/SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_NV21_BT709.hlsl new file mode 100644 index 0000000..f5b9522 --- /dev/null +++ b/SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_NV21_BT709.hlsl @@ -0,0 +1,43 @@ +Texture2D theTextureY : register(t0); +Texture2D theTextureUV : register(t1); +SamplerState theSampler : register(s0); + +struct PixelShaderInput +{ + float4 pos : SV_POSITION; + float2 tex : TEXCOORD0; + float4 color : COLOR0; +}; + +#define NVRS \ + "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \ + " DENY_DOMAIN_SHADER_ROOT_ACCESS |" \ + " DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \ + " DENY_HULL_SHADER_ROOT_ACCESS )," \ + "RootConstants(num32BitConstants=32, b0),"\ + "DescriptorTable ( SRV(t0), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( SRV(t1), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( Sampler(s0), visibility = SHADER_VISIBILITY_PIXEL )" + +[RootSignature(NVRS)] +float4 main(PixelShaderInput input) : SV_TARGET +{ + const float3 offset = {-0.0627451017, -0.501960814, -0.501960814}; + const float3 Rcoeff = {1.1644, 0.0000, 1.7927}; + const float3 Gcoeff = {1.1644, -0.2132, -0.5329}; + const float3 Bcoeff = {1.1644, 2.1124, 0.0000}; + + float4 Output; + + float3 yuv; + yuv.x = theTextureY.Sample(theSampler, input.tex).r; + yuv.yz = theTextureUV.Sample(theSampler, input.tex).gr; + + yuv += offset; + Output.r = dot(yuv, Rcoeff); + Output.g = dot(yuv, Gcoeff); + Output.b = dot(yuv, Bcoeff); + Output.a = 1.0f; + + return Output * input.color; +} \ No newline at end of file diff --git a/SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_NV21_JPEG.hlsl b/SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_NV21_JPEG.hlsl new file mode 100644 index 0000000..1b467b4 --- /dev/null +++ b/SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_NV21_JPEG.hlsl @@ -0,0 +1,43 @@ +Texture2D theTextureY : register(t0); +Texture2D theTextureUV : register(t1); +SamplerState theSampler : register(s0); + +struct PixelShaderInput +{ + float4 pos : SV_POSITION; + float2 tex : TEXCOORD0; + float4 color : COLOR0; +}; + +#define NVRS \ + "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \ + " DENY_DOMAIN_SHADER_ROOT_ACCESS |" \ + " DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \ + " DENY_HULL_SHADER_ROOT_ACCESS )," \ + "RootConstants(num32BitConstants=32, b0),"\ + "DescriptorTable ( SRV(t0), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( SRV(t1), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( Sampler(s0), visibility = SHADER_VISIBILITY_PIXEL )" + +[RootSignature(NVRS)] +float4 main(PixelShaderInput input) : SV_TARGET +{ + const float3 offset = {0.0, -0.501960814, -0.501960814}; + const float3 Rcoeff = {1.0000, 0.0000, 1.4020}; + const float3 Gcoeff = {1.0000, -0.3441, -0.7141}; + const float3 Bcoeff = {1.0000, 1.7720, 0.0000}; + + float4 Output; + + float3 yuv; + yuv.x = theTextureY.Sample(theSampler, input.tex).r; + yuv.yz = theTextureUV.Sample(theSampler, input.tex).gr; + + yuv += offset; + Output.r = dot(yuv, Rcoeff); + Output.g = dot(yuv, Gcoeff); + Output.b = dot(yuv, Bcoeff); + Output.a = 1.0f; + + return Output * input.color; +} \ No newline at end of file diff --git a/SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_Textures.hlsl b/SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_Textures.hlsl new file mode 100644 index 0000000..0dcdf89 --- /dev/null +++ b/SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_Textures.hlsl @@ -0,0 +1,24 @@ +Texture2D theTexture : register(t0); +SamplerState theSampler : register(s0); + +struct PixelShaderInput +{ + float4 pos : SV_POSITION; + float2 tex : TEXCOORD0; + float4 color : COLOR0; +}; + +#define TextureRS \ + "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \ + " DENY_DOMAIN_SHADER_ROOT_ACCESS |" \ + " DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \ + " DENY_HULL_SHADER_ROOT_ACCESS )," \ + "RootConstants(num32BitConstants=32, b0),"\ + "DescriptorTable ( SRV(t0), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( Sampler(s0), visibility = SHADER_VISIBILITY_PIXEL )" + +[RootSignature(TextureRS)] +float4 main(PixelShaderInput input) : SV_TARGET +{ + return theTexture.Sample(theSampler, input.tex) * input.color; +} \ No newline at end of file diff --git a/SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_YUV_BT601.hlsl b/SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_YUV_BT601.hlsl new file mode 100644 index 0000000..09e5894 --- /dev/null +++ b/SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_YUV_BT601.hlsl @@ -0,0 +1,46 @@ +Texture2D theTextureY : register(t0); +Texture2D theTextureU : register(t1); +Texture2D theTextureV : register(t2); +SamplerState theSampler : register(s0); + +struct PixelShaderInput +{ + float4 pos : SV_POSITION; + float2 tex : TEXCOORD0; + float4 color : COLOR0; +}; + +#define YUVRS \ + "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \ + " DENY_DOMAIN_SHADER_ROOT_ACCESS |" \ + " DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \ + " DENY_HULL_SHADER_ROOT_ACCESS )," \ + "RootConstants(num32BitConstants=32, b0),"\ + "DescriptorTable ( SRV(t0), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( SRV(t1), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( SRV(t2), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( Sampler(s0), visibility = SHADER_VISIBILITY_PIXEL )" + +[RootSignature(YUVRS)] +float4 main(PixelShaderInput input) : SV_TARGET +{ + const float3 offset = {-0.0627451017, -0.501960814, -0.501960814}; + const float3 Rcoeff = {1.1644, 0.0000, 1.5960}; + const float3 Gcoeff = {1.1644, -0.3918, -0.8130}; + const float3 Bcoeff = {1.1644, 2.0172, 0.0000}; + + float4 Output; + + float3 yuv; + yuv.x = theTextureY.Sample(theSampler, input.tex).r; + yuv.y = theTextureU.Sample(theSampler, input.tex).r; + yuv.z = theTextureV.Sample(theSampler, input.tex).r; + + yuv += offset; + Output.r = dot(yuv, Rcoeff); + Output.g = dot(yuv, Gcoeff); + Output.b = dot(yuv, Bcoeff); + Output.a = 1.0f; + + return Output * input.color; +} \ No newline at end of file diff --git a/SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_YUV_BT709.hlsl b/SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_YUV_BT709.hlsl new file mode 100644 index 0000000..f5aa0cd --- /dev/null +++ b/SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_YUV_BT709.hlsl @@ -0,0 +1,46 @@ +Texture2D theTextureY : register(t0); +Texture2D theTextureU : register(t1); +Texture2D theTextureV : register(t2); +SamplerState theSampler : register(s0); + +struct PixelShaderInput +{ + float4 pos : SV_POSITION; + float2 tex : TEXCOORD0; + float4 color : COLOR0; +}; + +#define YUVRS \ + "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \ + " DENY_DOMAIN_SHADER_ROOT_ACCESS |" \ + " DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \ + " DENY_HULL_SHADER_ROOT_ACCESS )," \ + "RootConstants(num32BitConstants=32, b0),"\ + "DescriptorTable ( SRV(t0), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( SRV(t1), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( SRV(t2), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( Sampler(s0), visibility = SHADER_VISIBILITY_PIXEL )" + +[RootSignature(YUVRS)] +float4 main(PixelShaderInput input) : SV_TARGET +{ + const float3 offset = {-0.0627451017, -0.501960814, -0.501960814}; + const float3 Rcoeff = {1.1644, 0.0000, 1.7927}; + const float3 Gcoeff = {1.1644, -0.2132, -0.5329}; + const float3 Bcoeff = {1.1644, 2.1124, 0.0000}; + + float4 Output; + + float3 yuv; + yuv.x = theTextureY.Sample(theSampler, input.tex).r; + yuv.y = theTextureU.Sample(theSampler, input.tex).r; + yuv.z = theTextureV.Sample(theSampler, input.tex).r; + + yuv += offset; + Output.r = dot(yuv, Rcoeff); + Output.g = dot(yuv, Gcoeff); + Output.b = dot(yuv, Bcoeff); + Output.a = 1.0f; + + return Output * input.color; +} \ No newline at end of file diff --git a/SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_YUV_JPEG.hlsl b/SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_YUV_JPEG.hlsl new file mode 100644 index 0000000..84d09b8 --- /dev/null +++ b/SDL2-2.30.5/VisualC-GDK/shaders/D3D12_PixelShader_YUV_JPEG.hlsl @@ -0,0 +1,46 @@ +Texture2D theTextureY : register(t0); +Texture2D theTextureU : register(t1); +Texture2D theTextureV : register(t2); +SamplerState theSampler : register(s0); + +struct PixelShaderInput +{ + float4 pos : SV_POSITION; + float2 tex : TEXCOORD0; + float4 color : COLOR0; +}; + +#define YUVRS \ + "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \ + " DENY_DOMAIN_SHADER_ROOT_ACCESS |" \ + " DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \ + " DENY_HULL_SHADER_ROOT_ACCESS )," \ + "RootConstants(num32BitConstants=32, b0),"\ + "DescriptorTable ( SRV(t0), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( SRV(t1), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( SRV(t2), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( Sampler(s0), visibility = SHADER_VISIBILITY_PIXEL )" + +[RootSignature(YUVRS)] +float4 main(PixelShaderInput input) : SV_TARGET +{ + const float3 offset = {0.0, -0.501960814, -0.501960814}; + const float3 Rcoeff = {1.0000, 0.0000, 1.4020}; + const float3 Gcoeff = {1.0000, -0.3441, -0.7141}; + const float3 Bcoeff = {1.0000, 1.7720, 0.0000}; + + float4 Output; + + float3 yuv; + yuv.x = theTextureY.Sample(theSampler, input.tex).r; + yuv.y = theTextureU.Sample(theSampler, input.tex).r; + yuv.z = theTextureV.Sample(theSampler, input.tex).r; + + yuv += offset; + Output.r = dot(yuv, Rcoeff); + Output.g = dot(yuv, Gcoeff); + Output.b = dot(yuv, Bcoeff); + Output.a = 1.0f; + + return Output * input.color; +} \ No newline at end of file diff --git a/SDL2-2.30.5/VisualC-GDK/shaders/D3D12_VertexShader.hlsl b/SDL2-2.30.5/VisualC-GDK/shaders/D3D12_VertexShader.hlsl new file mode 100644 index 0000000..e10b488 --- /dev/null +++ b/SDL2-2.30.5/VisualC-GDK/shaders/D3D12_VertexShader.hlsl @@ -0,0 +1,95 @@ +#pragma pack_matrix( row_major ) + +struct VertexShaderConstants +{ + matrix model; + matrix projectionAndView; +}; +ConstantBuffer Constants : register(b0); + +struct VertexShaderInput +{ + float3 pos : POSITION; + float2 tex : TEXCOORD0; + float4 color : COLOR0; +}; + +struct VertexShaderOutput +{ + float4 pos : SV_POSITION; + float2 tex : TEXCOORD0; + float4 color : COLOR0; +}; + +#define ColorRS \ + "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \ + "DENY_DOMAIN_SHADER_ROOT_ACCESS |" \ + "DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \ + "DENY_HULL_SHADER_ROOT_ACCESS )," \ + "RootConstants(num32BitConstants=32, b0)" + +#define TextureRS \ + "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \ + " DENY_DOMAIN_SHADER_ROOT_ACCESS |" \ + " DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \ + " DENY_HULL_SHADER_ROOT_ACCESS )," \ + "RootConstants(num32BitConstants=32, b0),"\ + "DescriptorTable ( SRV(t0), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( Sampler(s0), visibility = SHADER_VISIBILITY_PIXEL )" + +#define YUVRS \ + "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \ + " DENY_DOMAIN_SHADER_ROOT_ACCESS |" \ + " DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \ + " DENY_HULL_SHADER_ROOT_ACCESS )," \ + "RootConstants(num32BitConstants=32, b0),"\ + "DescriptorTable ( SRV(t0), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( SRV(t1), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( SRV(t2), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( Sampler(s0), visibility = SHADER_VISIBILITY_PIXEL )" + +#define NVRS \ + "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \ + " DENY_DOMAIN_SHADER_ROOT_ACCESS |" \ + " DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \ + " DENY_HULL_SHADER_ROOT_ACCESS )," \ + "RootConstants(num32BitConstants=32, b0),"\ + "DescriptorTable ( SRV(t0), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( SRV(t1), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( Sampler(s0), visibility = SHADER_VISIBILITY_PIXEL )" + +[RootSignature(ColorRS)] +VertexShaderOutput mainColor(VertexShaderInput input) +{ + VertexShaderOutput output; + float4 pos = float4(input.pos, 1.0f); + + // Transform the vertex position into projected space. + pos = mul(pos, Constants.model); + pos = mul(pos, Constants.projectionAndView); + output.pos = pos; + + // Pass through texture coordinates and color values without transformation + output.tex = input.tex; + output.color = input.color; + + return output; +} + +[RootSignature(TextureRS)] +VertexShaderOutput mainTexture(VertexShaderInput input) +{ + return mainColor(input); +} + +[RootSignature(YUVRS)] +VertexShaderOutput mainYUV(VertexShaderInput input) +{ + return mainColor(input); +} + +[RootSignature(NVRS)] +VertexShaderOutput mainNV(VertexShaderInput input) +{ + return mainColor(input); +} \ No newline at end of file diff --git a/SDL2-2.30.5/VisualC-GDK/shaders/buildshaders.bat b/SDL2-2.30.5/VisualC-GDK/shaders/buildshaders.bat new file mode 100644 index 0000000..4447b5e --- /dev/null +++ b/SDL2-2.30.5/VisualC-GDK/shaders/buildshaders.bat @@ -0,0 +1,35 @@ +if %2.==one. goto setxboxone +rem Xbox Series compile +set XBOXDXC="%GameDKLatest%\GXDK\bin\Scarlett\DXC.exe" +set SUFFIX=_Series.h +goto startbuild + +:setxboxone +set XBOXDXC="%GameDKLatest%\GXDK\bin\XboxOne\DXC.exe" +set SUFFIX=_One.h + +:startbuild +echo Building with %XBOXDXC% +cd "%1\shaders" +rem Root Signatures +%XBOXDXC% -E ColorRS -T rootsig_1_1 -rootsig-define ColorRS -Fh D3D12_RootSig_Color%SUFFIX% -Vn D3D12_RootSig_Color D3D12_VertexShader.hlsl +%XBOXDXC% -E TextureRS -T rootsig_1_1 -rootsig-define TextureRS -Fh D3D12_RootSig_Texture%SUFFIX% -Vn D3D12_RootSig_Texture D3D12_VertexShader.hlsl +%XBOXDXC% -E YUVRS -T rootsig_1_1 -rootsig-define YUVRS -Fh D3D12_RootSig_YUV%SUFFIX% -Vn D3D12_RootSig_YUV D3D12_VertexShader.hlsl +%XBOXDXC% -E NVRS -T rootsig_1_1 -rootsig-define NVRS -Fh D3D12_RootSig_NV%SUFFIX% -Vn D3D12_RootSig_NV D3D12_VertexShader.hlsl +rem Vertex Shaders +%XBOXDXC% -E mainColor -T vs_6_0 -Fh D3D12_VertexShader_Color%SUFFIX% -Vn D3D12_VertexShader_Color D3D12_VertexShader.hlsl +%XBOXDXC% -E mainTexture -T vs_6_0 -Fh D3D12_VertexShader_Texture%SUFFIX% -Vn D3D12_VertexShader_Texture D3D12_VertexShader.hlsl +%XBOXDXC% -E mainNV -T vs_6_0 -Fh D3D12_VertexShader_NV%SUFFIX% -Vn D3D12_VertexShader_NV D3D12_VertexShader.hlsl +%XBOXDXC% -E mainYUV -T vs_6_0 -Fh D3D12_VertexShader_YUV%SUFFIX% -Vn D3D12_VertexShader_YUV D3D12_VertexShader.hlsl +rem Pixel Shaders +%XBOXDXC% -E main -T ps_6_0 -Fh D3D12_PixelShader_Colors%SUFFIX% -Vn D3D12_PixelShader_Colors D3D12_PixelShader_Colors.hlsl +%XBOXDXC% -E main -T ps_6_0 -Fh D3D12_PixelShader_NV12_BT601%SUFFIX% -Vn D3D12_PixelShader_NV12_BT601 D3D12_PixelShader_NV12_BT601.hlsl +%XBOXDXC% -E main -T ps_6_0 -Fh D3D12_PixelShader_NV12_BT709%SUFFIX% -Vn D3D12_PixelShader_NV12_BT709 D3D12_PixelShader_NV12_BT709.hlsl +%XBOXDXC% -E main -T ps_6_0 -Fh D3D12_PixelShader_NV12_JPEG%SUFFIX% -Vn D3D12_PixelShader_NV12_JPEG D3D12_PixelShader_NV12_JPEG.hlsl +%XBOXDXC% -E main -T ps_6_0 -Fh D3D12_PixelShader_NV21_BT601%SUFFIX% -Vn D3D12_PixelShader_NV21_BT601 D3D12_PixelShader_NV21_BT601.hlsl +%XBOXDXC% -E main -T ps_6_0 -Fh D3D12_PixelShader_NV21_BT709%SUFFIX% -Vn D3D12_PixelShader_NV21_BT709 D3D12_PixelShader_NV21_BT709.hlsl +%XBOXDXC% -E main -T ps_6_0 -Fh D3D12_PixelShader_NV21_JPEG%SUFFIX% -Vn D3D12_PixelShader_NV21_JPEG D3D12_PixelShader_NV21_JPEG.hlsl +%XBOXDXC% -E main -T ps_6_0 -Fh D3D12_PixelShader_Textures%SUFFIX% -Vn D3D12_PixelShader_Textures D3D12_PixelShader_Textures.hlsl +%XBOXDXC% -E main -T ps_6_0 -Fh D3D12_PixelShader_YUV_BT601%SUFFIX% -Vn D3D12_PixelShader_YUV_BT601 D3D12_PixelShader_YUV_BT601.hlsl +%XBOXDXC% -E main -T ps_6_0 -Fh D3D12_PixelShader_YUV_BT709%SUFFIX% -Vn D3D12_PixelShader_YUV_BT709 D3D12_PixelShader_YUV_BT709.hlsl +%XBOXDXC% -E main -T ps_6_0 -Fh D3D12_PixelShader_YUV_JPEG%SUFFIX% -Vn D3D12_PixelShader_YUV_JPEG D3D12_PixelShader_YUV_JPEG.hlsl \ No newline at end of file diff --git a/SDL2-2.30.5/VisualC-GDK/tests/testgamecontroller/PackageLayout.xml b/SDL2-2.30.5/VisualC-GDK/tests/testgamecontroller/PackageLayout.xml new file mode 100644 index 0000000..cda188c --- /dev/null +++ b/SDL2-2.30.5/VisualC-GDK/tests/testgamecontroller/PackageLayout.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/SDL2-2.30.5/VisualC-GDK/tests/testgamecontroller/testgamecontroller.vcxproj b/SDL2-2.30.5/VisualC-GDK/tests/testgamecontroller/testgamecontroller.vcxproj new file mode 100644 index 0000000..4732934 --- /dev/null +++ b/SDL2-2.30.5/VisualC-GDK/tests/testgamecontroller/testgamecontroller.vcxproj @@ -0,0 +1,444 @@ + + + + + Debug + Gaming.Desktop.x64 + + + Debug + Gaming.Xbox.Scarlett.x64 + + + Debug + Gaming.Xbox.XboxOne.x64 + + + Release + Gaming.Desktop.x64 + + + Release + Gaming.Xbox.Scarlett.x64 + + + Release + Gaming.Xbox.XboxOne.x64 + + + + {55812185-D13C-4022-9C81-32E0F4A08305} + testgamecontroller + 10.0 + + + + Application + $(DefaultPlatformToolset) + + + Application + $(DefaultPlatformToolset) + true + + + Application + $(DefaultPlatformToolset) + true + + + Application + $(DefaultPlatformToolset) + + + Application + $(DefaultPlatformToolset) + + + Application + $(DefaultPlatformToolset) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + + + + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + + + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + .\Release/testgamecontroller.tlb + + + $(SolutionDir)/../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Windows + xgameruntime.lib;../Microsoft.Xbox.Services.GDK.C.Thunks.lib;%(AdditionalDependencies) + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + .\Release/testgamecontroller.tlb + + + $(SolutionDir)/../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Windows + xgameruntime.lib;%(AdditionalDependencies) + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + .\Release/testgamecontroller.tlb + + + $(SolutionDir)/../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Windows + xgameruntime.lib;%(AdditionalDependencies) + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + .\Debug/testgamecontroller.tlb + + + Disabled + $(SolutionDir)/../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + Level3 + OldStyle + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + Windows + xgameruntime.lib;../Microsoft.Xbox.Services.GDK.C.Thunks.lib;%(AdditionalDependencies) + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + .\Debug/testgamecontroller.tlb + + + Disabled + $(SolutionDir)/../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + Level3 + OldStyle + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + Windows + xgameruntime.lib;%(AdditionalDependencies) + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + .\Debug/testgamecontroller.tlb + + + Disabled + $(SolutionDir)/../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + Level3 + OldStyle + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + Windows + xgameruntime.lib;%(AdditionalDependencies) + + + + + {81ce8daf-ebb2-4761-8e45-b71abcca8c68} + false + false + true + + + {da956fd3-e142-46f2-9dd5-c78bebb56b7a} + false + false + true + + + + + Copying %(Filename)%(Extension) + Copying %(Filename)%(Extension) + Copying %(Filename)%(Extension) + copy "%(FullPath)" "$(ProjectDir)\" + + copy "%(FullPath)" "$(ProjectDir)\" + + copy "%(FullPath)" "$(ProjectDir)\" + + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + Copying %(Filename)%(Extension) + Copying %(Filename)%(Extension) + Copying %(Filename)%(Extension) + copy "%(FullPath)" "$(ProjectDir)\" + + copy "%(FullPath)" "$(ProjectDir)\" + + copy "%(FullPath)" "$(ProjectDir)\" + + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + + + Copying %(Filename)%(Extension) + Copying %(Filename)%(Extension) + Copying %(Filename)%(Extension) + copy "%(FullPath)" "$(ProjectDir)\" + + copy "%(FullPath)" "$(ProjectDir)\" + + copy "%(FullPath)" "$(ProjectDir)\" + + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + Copying %(Filename)%(Extension) + Copying %(Filename)%(Extension) + Copying %(Filename)%(Extension) + copy "%(FullPath)" "$(ProjectDir)\" + + copy "%(FullPath)" "$(ProjectDir)\" + + copy "%(FullPath)" "$(ProjectDir)\" + + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + + + Copying %(Filename)%(Extension) + Copying %(Filename)%(Extension) + Copying %(Filename)%(Extension) + copy "%(FullPath)" "$(ProjectDir)\" + + copy "%(FullPath)" "$(ProjectDir)\" + + copy "%(FullPath)" "$(ProjectDir)\" + + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + Copying %(Filename)%(Extension) + Copying %(Filename)%(Extension) + Copying %(Filename)%(Extension) + copy "%(FullPath)" "$(ProjectDir)\" + + copy "%(FullPath)" "$(ProjectDir)\" + + copy "%(FullPath)" "$(ProjectDir)\" + + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + + + Copying %(Filename)%(Extension) + Copying %(Filename)%(Extension) + Copying %(Filename)%(Extension) + copy "%(FullPath)" "$(ProjectDir)\" + + copy "%(FullPath)" "$(ProjectDir)\" + + copy "%(FullPath)" "$(ProjectDir)\" + + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + Copying %(Filename)%(Extension) + Copying %(Filename)%(Extension) + Copying %(Filename)%(Extension) + copy "%(FullPath)" "$(ProjectDir)\" + + copy "%(FullPath)" "$(ProjectDir)\" + + copy "%(FullPath)" "$(ProjectDir)\" + + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + + + + + + + + + Document + true + true + true + true + + + + + + + + + + + + + + Document + true + true + true + true + + + + + Document + true + true + true + true + + + + + Document + true + true + true + true + + + + + + + + + \ No newline at end of file diff --git a/SDL2-2.30.5/VisualC-GDK/tests/testgamecontroller/testgamecontroller.vcxproj.filters b/SDL2-2.30.5/VisualC-GDK/tests/testgamecontroller/testgamecontroller.vcxproj.filters new file mode 100644 index 0000000..1124f2c --- /dev/null +++ b/SDL2-2.30.5/VisualC-GDK/tests/testgamecontroller/testgamecontroller.vcxproj.filters @@ -0,0 +1,55 @@ + + + + + + + + + + + + + logos + + + logos + + + logos + + + logos + + + wingdk + + + wingdk + + + xboxseries + + + xboxone + + + logos + + + + + + {5e858cf0-6fba-498d-b33d-11c8ecbb79c7} + + + {5790a250-283e-4f51-8f28-6a977d3c7a6c} + + + {a4d235e4-4017-4193-af62-ecb2ac249be4} + + + {e704dcb9-c83c-4c94-a139-b0f3e3f428f2} + + + \ No newline at end of file diff --git a/SDL2-2.30.5/VisualC-GDK/tests/testgamecontroller/wingdk/MicrosoftGame.config b/SDL2-2.30.5/VisualC-GDK/tests/testgamecontroller/wingdk/MicrosoftGame.config new file mode 100644 index 0000000..eb4ec4e --- /dev/null +++ b/SDL2-2.30.5/VisualC-GDK/tests/testgamecontroller/wingdk/MicrosoftGame.config @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + PleaseChangeMe + FFFFFFFF + + + \ No newline at end of file diff --git a/SDL2-2.30.5/VisualC-GDK/tests/testgamecontroller/xboxone/MicrosoftGame.config b/SDL2-2.30.5/VisualC-GDK/tests/testgamecontroller/xboxone/MicrosoftGame.config new file mode 100644 index 0000000..c18d626 --- /dev/null +++ b/SDL2-2.30.5/VisualC-GDK/tests/testgamecontroller/xboxone/MicrosoftGame.config @@ -0,0 +1,29 @@ + + + + + + + + + + + + PleaseChangeMe + FFFFFFFF + + + \ No newline at end of file diff --git a/SDL2-2.30.5/VisualC-GDK/tests/testgamecontroller/xboxseries/MicrosoftGame.config b/SDL2-2.30.5/VisualC-GDK/tests/testgamecontroller/xboxseries/MicrosoftGame.config new file mode 100644 index 0000000..53ba05d --- /dev/null +++ b/SDL2-2.30.5/VisualC-GDK/tests/testgamecontroller/xboxseries/MicrosoftGame.config @@ -0,0 +1,29 @@ + + + + + + + + + + + + PleaseChangeMe + FFFFFFFF + + + \ No newline at end of file diff --git a/SDL2-2.30.5/VisualC-GDK/tests/testgdk/PackageLayout.xml b/SDL2-2.30.5/VisualC-GDK/tests/testgdk/PackageLayout.xml new file mode 100644 index 0000000..abee981 --- /dev/null +++ b/SDL2-2.30.5/VisualC-GDK/tests/testgdk/PackageLayout.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/SDL2-2.0.12/test/testsprite2.c b/SDL2-2.30.5/VisualC-GDK/tests/testgdk/src/testgdk.cpp similarity index 54% rename from SDL2-2.0.12/test/testsprite2.c rename to SDL2-2.30.5/VisualC-GDK/tests/testgdk/src/testgdk.cpp index 4de0b4b..668baea 100644 --- a/SDL2-2.0.12/test/testsprite2.c +++ b/SDL2-2.30.5/VisualC-GDK/tests/testgdk/src/testgdk.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -9,18 +9,24 @@ including commercial applications, and to alter it and redistribute it freely. */ -/* Simple program: Move N sprites around on the screen as fast as possible */ +/* testgdk: Basic tests of using task queue/xbl (with simple drawing) in GDK. + * NOTE: As of June 2022 GDK, login will only work if MicrosoftGame.config is + * configured properly. See README-gdk.md. + */ #include #include #include -#ifdef __EMSCRIPTEN__ -#include -#endif - #include "SDL_test.h" #include "SDL_test_common.h" +#include "../src/core/windows/SDL_windows.h" + +extern "C" { +#include "../test/testutils.h" +} + +#include #define NUM_SPRITES 100 #define MAX_SPEED 1 @@ -33,93 +39,223 @@ static SDL_bool cycle_alpha; static int cycle_direction = 1; static int current_alpha = 0; static int current_color = 0; -static SDL_Rect *positions; -static SDL_Rect *velocities; static int sprite_w, sprite_h; static SDL_BlendMode blendMode = SDL_BLENDMODE_BLEND; -static Uint32 next_fps_check, frames; -static const Uint32 fps_check_delay = 5000; - -/* Number of iterations to move sprites - used for visual tests. */ -/* -1: infinite random moves (default); >=0: enables N deterministic moves */ -static int iterations = -1; int done; +static struct +{ + SDL_AudioSpec spec; + Uint8 *sound; /* Pointer to wave data */ + Uint32 soundlen; /* Length of wave data */ + int soundpos; /* Current play position */ +} wave; + +static SDL_AudioDeviceID device; + +static void +close_audio() +{ + if (device != 0) { + SDL_CloseAudioDevice(device); + device = 0; + } +} + /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ static void quit(int rc) { SDL_free(sprites); - SDL_free(positions); - SDL_free(velocities); + close_audio(); + SDL_FreeWAV(wave.sound); SDLTest_CommonQuit(state); - exit(rc); + /* If rc is 0, just let main return normally rather than calling exit. + * This allows testing of platforms where SDL_main is required and does meaningful cleanup. + */ + if (rc != 0) { + exit(rc); + } +} + +static void +open_audio() +{ + /* Initialize fillerup() variables */ + device = SDL_OpenAudioDevice(NULL, SDL_FALSE, &wave.spec, NULL, 0); + if (!device) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open audio: %s\n", SDL_GetError()); + SDL_FreeWAV(wave.sound); + quit(2); + } + + /* Let the audio run */ + SDL_PauseAudioDevice(device, SDL_FALSE); +} + +static void +reopen_audio() +{ + close_audio(); + open_audio(); +} + +void SDLCALL +fillerup(void *unused, Uint8 *stream, int len) +{ + Uint8 *waveptr; + int waveleft; + + /* Set up the pointers */ + waveptr = wave.sound + wave.soundpos; + waveleft = wave.soundlen - wave.soundpos; + + /* Go! */ + while (waveleft <= len) { + SDL_memcpy(stream, waveptr, waveleft); + stream += waveleft; + len -= waveleft; + waveptr = wave.sound; + waveleft = wave.soundlen; + wave.soundpos = 0; + } + SDL_memcpy(stream, waveptr, len); + wave.soundpos += len; +} + +void +UserLoggedIn(XUserHandle user) +{ + HRESULT hr; + char gamertag[128]; + hr = XUserGetGamertag(user, XUserGamertagComponent::UniqueModern, sizeof(gamertag), gamertag, NULL); + + if (SUCCEEDED(hr)) { + SDL_Log("User logged in: %s", gamertag); + } else { + SDL_Log("[GDK] UserLoggedIn -- XUserGetGamertag failed: 0x%08x.", hr); + } + + XUserCloseHandle(user); +} + +void +AddUserUICallback(XAsyncBlock *asyncBlock) +{ + HRESULT hr; + XUserHandle user = NULL; + + hr = XUserAddResult(asyncBlock, &user); + if (SUCCEEDED(hr)) { + uint64_t userId; + + hr = XUserGetId(user, &userId); + if (FAILED(hr)) { + /* If unable to get the user ID, it means the account is banned, etc. */ + SDL_Log("[GDK] AddUserSilentCallback -- XUserGetId failed: 0x%08x.", hr); + XUserCloseHandle(user); + + /* Per the docs, likely should call XUserResolveIssueWithUiAsync here. */ + } else { + UserLoggedIn(user); + } + } else { + SDL_Log("[GDK] AddUserUICallback -- XUserAddAsync failed: 0x%08x.", hr); + } + + delete asyncBlock; +} + +void +AddUserUI() +{ + HRESULT hr; + XAsyncBlock *asyncBlock = new XAsyncBlock; + + asyncBlock->context = NULL; + asyncBlock->queue = NULL; /* A null queue will use the global process task queue */ + asyncBlock->callback = &AddUserUICallback; + + hr = XUserAddAsync(XUserAddOptions::None, asyncBlock); + + if (FAILED(hr)) { + delete asyncBlock; + SDL_Log("[GDK] AddUserSilent -- failed: 0x%08x", hr); + } +} + +void +AddUserSilentCallback(XAsyncBlock *asyncBlock) +{ + HRESULT hr; + XUserHandle user = NULL; + + hr = XUserAddResult(asyncBlock, &user); + if (SUCCEEDED(hr)) { + uint64_t userId; + + hr = XUserGetId(user, &userId); + if (FAILED(hr)) { + /* If unable to get the user ID, it means the account is banned, etc. */ + SDL_Log("[GDK] AddUserSilentCallback -- XUserGetId failed: 0x%08x. Trying with UI.", hr); + XUserCloseHandle(user); + AddUserUI(); + } else { + UserLoggedIn(user); + } + } else { + SDL_Log("[GDK] AddUserSilentCallback -- XUserAddAsync failed: 0x%08x. Trying with UI.", hr); + AddUserUI(); + } + + delete asyncBlock; +} + +void +AddUserSilent() +{ + HRESULT hr; + XAsyncBlock *asyncBlock = new XAsyncBlock; + + asyncBlock->context = NULL; + asyncBlock->queue = NULL; /* A null queue will use the global process task queue */ + asyncBlock->callback = &AddUserSilentCallback; + + hr = XUserAddAsync(XUserAddOptions::AddDefaultUserSilently, asyncBlock); + + if (FAILED(hr)) { + delete asyncBlock; + SDL_Log("[GDK] AddUserSilent -- failed: 0x%08x", hr); + } } int LoadSprite(const char *file) { int i; - SDL_Surface *temp; - /* Load the sprite image */ - temp = SDL_LoadBMP(file); - if (temp == NULL) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s", file, SDL_GetError()); - return (-1); - } - sprite_w = temp->w; - sprite_h = temp->h; - - /* Set transparent pixel as the pixel at (0,0) */ - if (temp->format->palette) { - SDL_SetColorKey(temp, 1, *(Uint8 *) temp->pixels); - } else { - switch (temp->format->BitsPerPixel) { - case 15: - SDL_SetColorKey(temp, 1, (*(Uint16 *) temp->pixels) & 0x00007FFF); - break; - case 16: - SDL_SetColorKey(temp, 1, *(Uint16 *) temp->pixels); - break; - case 24: - SDL_SetColorKey(temp, 1, (*(Uint32 *) temp->pixels) & 0x00FFFFFF); - break; - case 32: - SDL_SetColorKey(temp, 1, *(Uint32 *) temp->pixels); - break; - } - } - - /* Create textures from the image */ for (i = 0; i < state->num_windows; ++i) { - SDL_Renderer *renderer = state->renderers[i]; - sprites[i] = SDL_CreateTextureFromSurface(renderer, temp); + /* This does the SDL_LoadBMP step repeatedly, but that's OK for test code. */ + sprites[i] = LoadTexture(state->renderers[i], file, SDL_TRUE, &sprite_w, &sprite_h); if (!sprites[i]) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError()); - SDL_FreeSurface(temp); - return (-1); + return -1; } if (SDL_SetTextureBlendMode(sprites[i], blendMode) < 0) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't set blend mode: %s\n", SDL_GetError()); - SDL_FreeSurface(temp); SDL_DestroyTexture(sprites[i]); - return (-1); + return -1; } } - SDL_FreeSurface(temp); /* We're ready to roll. :) */ - return (0); + return 0; } void -MoveSprites(SDL_Renderer * renderer, SDL_Texture * sprite) +DrawSprites(SDL_Renderer * renderer, SDL_Texture * sprite) { - int i; SDL_Rect viewport, temp; - SDL_Rect *position, *velocity; /* Query the sizes */ SDL_RenderGetViewport(renderer, &viewport); @@ -203,42 +339,6 @@ MoveSprites(SDL_Renderer * renderer, SDL_Texture * sprite) SDL_RenderDrawLine(renderer, viewport.w-sprite_w-2, sprite_h, sprite_w, viewport.h-sprite_h-2); - /* Conditionally move the sprites, bounce at the wall */ - if (iterations == -1 || iterations > 0) { - for (i = 0; i < num_sprites; ++i) { - position = &positions[i]; - velocity = &velocities[i]; - position->x += velocity->x; - if ((position->x < 0) || (position->x >= (viewport.w - sprite_w))) { - velocity->x = -velocity->x; - position->x += velocity->x; - } - position->y += velocity->y; - if ((position->y < 0) || (position->y >= (viewport.h - sprite_h))) { - velocity->y = -velocity->y; - position->y += velocity->y; - } - - } - - /* Countdown sprite-move iterations and disable color changes at iteration end - used for visual tests. */ - if (iterations > 0) { - iterations--; - if (iterations == 0) { - cycle_alpha = SDL_FALSE; - cycle_color = SDL_FALSE; - } - } - } - - /* Draw sprites */ - for (i = 0; i < num_sprites; ++i) { - position = &positions[i]; - - /* Blit the sprite onto the screen */ - SDL_RenderCopy(renderer, sprite, NULL, position); - } - /* Update the screen! */ SDL_RenderPresent(renderer); } @@ -246,50 +346,43 @@ MoveSprites(SDL_Renderer * renderer, SDL_Texture * sprite) void loop() { - Uint32 now; int i; SDL_Event event; /* Check for events */ while (SDL_PollEvent(&event)) { + if (event.type == SDL_KEYDOWN && !event.key.repeat) { + SDL_Log("Initial SDL_KEYDOWN: %s", SDL_GetScancodeName(event.key.keysym.scancode)); + } +#if defined(__XBOXONE__) || defined(__XBOXSERIES__) + /* On Xbox, ignore the keydown event because the features aren't supported */ + if (event.type != SDL_KEYDOWN) { + SDLTest_CommonEvent(state, &event, &done); + } +#else SDLTest_CommonEvent(state, &event, &done); +#endif } for (i = 0; i < state->num_windows; ++i) { - if (state->windows[i] == NULL) + if (state->windows[i] == NULL) { continue; - MoveSprites(state->renderers[i], sprites[i]); + } + DrawSprites(state->renderers[i], sprites[i]); } -#ifdef __EMSCRIPTEN__ - if (done) { - emscripten_cancel_main_loop(); - } -#endif - - frames++; - now = SDL_GetTicks(); - if (SDL_TICKS_PASSED(now, next_fps_check)) { - /* Print out some timing information */ - const Uint32 then = next_fps_check - fps_check_delay; - const double fps = ((double) frames * 1000) / (now - then); - SDL_Log("%2.2f frames per second\n", fps); - next_fps_check = now + fps_check_delay; - frames = 0; - } - } int main(int argc, char *argv[]) { int i; - Uint64 seed; const char *icon = "icon.bmp"; + char *soundname = NULL; /* Initialize parameters */ num_sprites = NUM_SPRITES; /* Initialize test framework */ - state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO); + state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO | SDL_INIT_AUDIO); if (!state) { return 1; } @@ -319,12 +412,6 @@ main(int argc, char *argv[]) consumed = 2; } } - } else if (SDL_strcasecmp(argv[i], "--iterations") == 0) { - if (argv[i + 1]) { - iterations = SDL_atoi(argv[i + 1]); - if (iterations < -1) iterations = -1; - consumed = 2; - } } else if (SDL_strcasecmp(argv[i], "--cyclecolor") == 0) { cycle_color = SDL_TRUE; consumed = 1; @@ -340,7 +427,13 @@ main(int argc, char *argv[]) } } if (consumed < 0) { - static const char *options[] = { "[--blend none|blend|add|mod]", "[--cyclecolor]", "[--cyclealpha]", "[--iterations N]", "[num_sprites]", "[icon.bmp]", NULL }; + static const char *options[] = { + "[--blend none|blend|add|mod]", + "[--cyclecolor]", + "[--cyclealpha]", + "[num_sprites]", + "[icon.bmp]", + NULL }; SDLTest_CommonLogUsage(state, argv[0], options); quit(1); } @@ -366,50 +459,44 @@ main(int argc, char *argv[]) quit(2); } - /* Allocate memory for the sprite info */ - positions = (SDL_Rect *) SDL_malloc(num_sprites * sizeof(SDL_Rect)); - velocities = (SDL_Rect *) SDL_malloc(num_sprites * sizeof(SDL_Rect)); - if (!positions || !velocities) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Out of memory!\n"); - quit(2); + soundname = GetResourceFilename(argc > 1 ? argv[1] : NULL, "sample.wav"); + + if (!soundname) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "%s\n", SDL_GetError()); + quit(1); } - /* Position sprites and set their velocities using the fuzzer */ - if (iterations >= 0) { - /* Deterministic seed - used for visual tests */ - seed = (Uint64)iterations; - } else { - /* Pseudo-random seed generated from the time */ - seed = (Uint64)time(NULL); + /* Load the wave file into memory */ + if (SDL_LoadWAV(soundname, &wave.spec, &wave.sound, &wave.soundlen) == NULL) { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", soundname, SDL_GetError()); + quit(1); } - SDLTest_FuzzerInit(seed); - for (i = 0; i < num_sprites; ++i) { - positions[i].x = SDLTest_RandomIntegerInRange(0, state->window_w - sprite_w); - positions[i].y = SDLTest_RandomIntegerInRange(0, state->window_h - sprite_h); - positions[i].w = sprite_w; - positions[i].h = sprite_h; - velocities[i].x = 0; - velocities[i].y = 0; - while (!velocities[i].x && !velocities[i].y) { - velocities[i].x = SDLTest_RandomIntegerInRange(-MAX_SPEED, MAX_SPEED); - velocities[i].y = SDLTest_RandomIntegerInRange(-MAX_SPEED, MAX_SPEED); - } + + wave.spec.callback = fillerup; + + /* Show the list of available drivers */ + SDL_Log("Available audio drivers:"); + for (i = 0; i < SDL_GetNumAudioDrivers(); ++i) { + SDL_Log("%i: %s", i, SDL_GetAudioDriver(i)); } + SDL_Log("Using audio driver: %s\n", SDL_GetCurrentAudioDriver()); + + open_audio(); + /* Main render loop */ - frames = 0; - next_fps_check = SDL_GetTicks() + fps_check_delay; done = 0; -#ifdef __EMSCRIPTEN__ - emscripten_set_main_loop(loop, 0, 1); -#else + /* Try to add the default user silently */ + AddUserSilent(); + while (!done) { loop(); } -#endif quit(0); + + SDL_free(soundname); return 0; } diff --git a/SDL2-2.30.5/VisualC-GDK/tests/testgdk/testgdk.vcxproj b/SDL2-2.30.5/VisualC-GDK/tests/testgdk/testgdk.vcxproj new file mode 100644 index 0000000..f024a89 --- /dev/null +++ b/SDL2-2.30.5/VisualC-GDK/tests/testgdk/testgdk.vcxproj @@ -0,0 +1,401 @@ + + + + + Debug + Gaming.Desktop.x64 + + + Debug + Gaming.Xbox.Scarlett.x64 + + + Debug + Gaming.Xbox.XboxOne.x64 + + + Release + Gaming.Desktop.x64 + + + Release + Gaming.Xbox.Scarlett.x64 + + + Release + Gaming.Xbox.XboxOne.x64 + + + + {1C9A3F71-35A5-4C56-B292-F4375B3C3649} + testsprite2 + 10.0 + + + + Application + $(DefaultPlatformToolset) + + + Application + $(DefaultPlatformToolset) + true + + + Application + $(DefaultPlatformToolset) + true + + + Application + $(DefaultPlatformToolset) + + + Application + $(DefaultPlatformToolset) + + + Application + $(DefaultPlatformToolset) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + + + + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + + + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + .\Release/testsprite2.tlb + + + $(SolutionDir)/../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Windows + xgameruntime.lib;../Microsoft.Xbox.Services.141.GDK.C.Thunks.lib;%(AdditionalDependencies) + + + + + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + .\Release/testsprite2.tlb + + + $(SolutionDir)/../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Windows + xgameruntime.lib;%(AdditionalDependencies) + + + + + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + .\Release/testsprite2.tlb + + + $(SolutionDir)/../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Windows + xgameruntime.lib;%(AdditionalDependencies) + + + + + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + .\Debug/testsprite2.tlb + + + Disabled + $(SolutionDir)/../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + Level3 + OldStyle + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + Windows + xgameruntime.lib;../Microsoft.Xbox.Services.141.GDK.C.Thunks.lib;%(AdditionalDependencies) + + + + + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + .\Debug/testsprite2.tlb + + + Disabled + $(SolutionDir)/../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + Level3 + OldStyle + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + Windows + xgameruntime.lib;%(AdditionalDependencies) + + + + + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + .\Debug/testsprite2.tlb + + + Disabled + $(SolutionDir)/../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + Level3 + OldStyle + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + Windows + xgameruntime.lib;%(AdditionalDependencies) + + + + + + + + + {81ce8daf-ebb2-4761-8e45-b71abcca8c68} + false + false + true + + + {da956fd3-e142-46f2-9dd5-c78bebb56b7a} + false + false + true + + + {da956fd3-e143-46f2-9fe5-c77bebc56b1a} + false + false + true + + + + + Copying %(Filename)%(Extension) + Copying %(Filename)%(Extension) + Copying %(Filename)%(Extension) + copy "%(FullPath)" "$(ProjectDir)\" +copy "%(FullPath)" "$(OutDir)\" + copy "%(FullPath)" "$(ProjectDir)\" +copy "%(FullPath)" "$(OutDir)\" + copy "%(FullPath)" "$(ProjectDir)\" +copy "%(FullPath)" "$(OutDir)\" + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + Copying %(Filename)%(Extension) + Copying %(Filename)%(Extension) + Copying %(Filename)%(Extension) + copy "%(FullPath)" "$(ProjectDir)\" +copy "%(FullPath)" "$(OutDir)\" + copy "%(FullPath)" "$(ProjectDir)\" +copy "%(FullPath)" "$(OutDir)\" + copy "%(FullPath)" "$(ProjectDir)\" +copy "%(FullPath)" "$(OutDir)\" + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + + + + + + + + + Document + true + true + true + true + + + + + Document + true + true + true + true + + + + + + + + + + + + + + Document + true + true + true + true + + + + + Document + + + + + Document + true + true + true + true + + + + + + + + + \ No newline at end of file diff --git a/SDL2-2.30.5/VisualC-GDK/tests/testgdk/testgdk.vcxproj.filters b/SDL2-2.30.5/VisualC-GDK/tests/testgdk/testgdk.vcxproj.filters new file mode 100644 index 0000000..b82a989 --- /dev/null +++ b/SDL2-2.30.5/VisualC-GDK/tests/testgdk/testgdk.vcxproj.filters @@ -0,0 +1,53 @@ + + + + + + + + + + logos + + + logos + + + logos + + + logos + + + wingdk + + + wingdk + + + xboxseries + + + + xboxone + + + logos + + + + + + {c3c871f2-c7b7-4025-8ba4-037dde717fe1} + + + {1678a80d-0ee8-4f48-bf89-9462d82dd98a} + + + {1b47b96b-507e-40ec-9c25-99b1a4d5b575} + + + {ac7aa2d5-f0f7-46eb-a548-5b6316f3b63b} + + + \ No newline at end of file diff --git a/SDL2-2.30.5/VisualC-GDK/tests/testgdk/wingdk/MicrosoftGame.config b/SDL2-2.30.5/VisualC-GDK/tests/testgdk/wingdk/MicrosoftGame.config new file mode 100644 index 0000000..afd57d6 --- /dev/null +++ b/SDL2-2.30.5/VisualC-GDK/tests/testgdk/wingdk/MicrosoftGame.config @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + PleaseChangeMe + FFFFFFFF + + + \ No newline at end of file diff --git a/SDL2-2.30.5/VisualC-GDK/tests/testgdk/xboxone/MicrosoftGame.config b/SDL2-2.30.5/VisualC-GDK/tests/testgdk/xboxone/MicrosoftGame.config new file mode 100644 index 0000000..a593bd1 --- /dev/null +++ b/SDL2-2.30.5/VisualC-GDK/tests/testgdk/xboxone/MicrosoftGame.config @@ -0,0 +1,29 @@ + + + + + + + + + + + + PleaseChangeMe + FFFFFFFF + + + \ No newline at end of file diff --git a/SDL2-2.30.5/VisualC-GDK/tests/testgdk/xboxseries/MicrosoftGame.config b/SDL2-2.30.5/VisualC-GDK/tests/testgdk/xboxseries/MicrosoftGame.config new file mode 100644 index 0000000..1ab7c17 --- /dev/null +++ b/SDL2-2.30.5/VisualC-GDK/tests/testgdk/xboxseries/MicrosoftGame.config @@ -0,0 +1,29 @@ + + + + + + + + + + + + PleaseChangeMe + FFFFFFFF + + + \ No newline at end of file diff --git a/SDL2-2.30.5/VisualC-GDK/tests/testsprite2/PackageLayout.xml b/SDL2-2.30.5/VisualC-GDK/tests/testsprite2/PackageLayout.xml new file mode 100644 index 0000000..62ca97b --- /dev/null +++ b/SDL2-2.30.5/VisualC-GDK/tests/testsprite2/PackageLayout.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/SDL2-2.30.5/VisualC-GDK/tests/testsprite2/testsprite2.vcxproj b/SDL2-2.30.5/VisualC-GDK/tests/testsprite2/testsprite2.vcxproj new file mode 100644 index 0000000..651a346 --- /dev/null +++ b/SDL2-2.30.5/VisualC-GDK/tests/testsprite2/testsprite2.vcxproj @@ -0,0 +1,395 @@ + + + + + Debug + Gaming.Desktop.x64 + + + Debug + Gaming.Xbox.Scarlett.x64 + + + Debug + Gaming.Xbox.XboxOne.x64 + + + Release + Gaming.Desktop.x64 + + + Release + Gaming.Xbox.Scarlett.x64 + + + Release + Gaming.Xbox.XboxOne.x64 + + + + {40FB7794-D3C3-4CFE-BCF4-A80C96635682} + testsprite2 + 10.0 + + + + Application + $(DefaultPlatformToolset) + + + Application + $(DefaultPlatformToolset) + true + + + Application + $(DefaultPlatformToolset) + true + + + Application + $(DefaultPlatformToolset) + + + Application + $(DefaultPlatformToolset) + + + Application + $(DefaultPlatformToolset) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + + + + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + + + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + .\Release/testsprite2.tlb + + + $(SolutionDir)/../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Windows + xgameruntime.lib;../Microsoft.Xbox.Services.141.GDK.C.Thunks.lib;%(AdditionalDependencies) + + + + + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + .\Release/testsprite2.tlb + + + $(SolutionDir)/../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Windows + xgameruntime.lib;%(AdditionalDependencies) + + + + + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + .\Release/testsprite2.tlb + + + $(SolutionDir)/../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Windows + xgameruntime.lib;%(AdditionalDependencies) + + + + + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + .\Debug/testsprite2.tlb + + + Disabled + $(SolutionDir)/../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + Level3 + OldStyle + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + Windows + xgameruntime.lib;../Microsoft.Xbox.Services.141.GDK.C.Thunks.lib;%(AdditionalDependencies) + + + + + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + .\Debug/testsprite2.tlb + + + Disabled + $(SolutionDir)/../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + Level3 + OldStyle + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + Windows + xgameruntime.lib;%(AdditionalDependencies) + + + + + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + .\Debug/testsprite2.tlb + + + Disabled + $(SolutionDir)/../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + Level3 + OldStyle + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + Windows + xgameruntime.lib;%(AdditionalDependencies) + + + + + + + + + {81ce8daf-ebb2-4761-8e45-b71abcca8c68} + false + false + true + + + {da956fd3-e142-46f2-9dd5-c78bebb56b7a} + false + false + true + + + {da956fd3-e143-46f2-9fe5-c77bebc56b1a} + false + false + true + + + + + Copying %(Filename)%(Extension) + Copying %(Filename)%(Extension) + Copying %(Filename)%(Extension) + copy "%(FullPath)" "$(ProjectDir)\" +copy "%(FullPath)" "$(OutDir)\" + copy "%(FullPath)" "$(ProjectDir)\" +copy "%(FullPath)" "$(OutDir)\" + copy "%(FullPath)" "$(ProjectDir)\" +copy "%(FullPath)" "$(OutDir)\" + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + Copying %(Filename)%(Extension) + Copying %(Filename)%(Extension) + Copying %(Filename)%(Extension) + copy "%(FullPath)" "$(ProjectDir)\" +copy "%(FullPath)" "$(OutDir)\" + copy "%(FullPath)" "$(ProjectDir)\" +copy "%(FullPath)" "$(OutDir)\" + copy "%(FullPath)" "$(ProjectDir)\" +copy "%(FullPath)" "$(OutDir)\" + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + + + + + + + + + Document + true + true + true + true + + + + + Document + true + true + true + true + + + + + + + + + + + + + + Document + true + true + true + true + + + + + true + true + true + true + + + + + + + + + \ No newline at end of file diff --git a/SDL2-2.30.5/VisualC-GDK/tests/testsprite2/testsprite2.vcxproj.filters b/SDL2-2.30.5/VisualC-GDK/tests/testsprite2/testsprite2.vcxproj.filters new file mode 100644 index 0000000..e945fe5 --- /dev/null +++ b/SDL2-2.30.5/VisualC-GDK/tests/testsprite2/testsprite2.vcxproj.filters @@ -0,0 +1,52 @@ + + + + + + + + + + logos + + + logos + + + logos + + + logos + + + wingdk + + + xboxseries + + + xboxone + + + wingdk + + + logos + + + + + + {c3c871f2-c7b7-4025-8ba4-037dde717fe1} + + + {c862dfc3-7803-4359-a31e-9dcda37e641a} + + + {1671e83d-25b3-4eb5-bed0-5c52c80f4e49} + + + {9bf62acf-6661-43f9-bde3-0de9e1db4290} + + + \ No newline at end of file diff --git a/SDL2-2.30.5/VisualC-GDK/tests/testsprite2/wingdk/MicrosoftGame.config b/SDL2-2.30.5/VisualC-GDK/tests/testsprite2/wingdk/MicrosoftGame.config new file mode 100644 index 0000000..8aa5865 --- /dev/null +++ b/SDL2-2.30.5/VisualC-GDK/tests/testsprite2/wingdk/MicrosoftGame.config @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + PleaseChangeMe + FFFFFFFF + + + \ No newline at end of file diff --git a/SDL2-2.30.5/VisualC-GDK/tests/testsprite2/xboxone/MicrosoftGame.config b/SDL2-2.30.5/VisualC-GDK/tests/testsprite2/xboxone/MicrosoftGame.config new file mode 100644 index 0000000..23ac15a --- /dev/null +++ b/SDL2-2.30.5/VisualC-GDK/tests/testsprite2/xboxone/MicrosoftGame.config @@ -0,0 +1,29 @@ + + + + + + + + + + + + PleaseChangeMe + FFFFFFFF + + + \ No newline at end of file diff --git a/SDL2-2.30.5/VisualC-GDK/tests/testsprite2/xboxseries/MicrosoftGame.config b/SDL2-2.30.5/VisualC-GDK/tests/testsprite2/xboxseries/MicrosoftGame.config new file mode 100644 index 0000000..288ee29 --- /dev/null +++ b/SDL2-2.30.5/VisualC-GDK/tests/testsprite2/xboxseries/MicrosoftGame.config @@ -0,0 +1,29 @@ + + + + + + + + + + + + PleaseChangeMe + FFFFFFFF + + + \ No newline at end of file diff --git a/SDL2-2.0.12/VisualC-WinRT/UWP_VS2015/SDL-UWP.sln b/SDL2-2.30.5/VisualC-WinRT/SDL-UWP.sln similarity index 79% rename from SDL2-2.0.12/VisualC-WinRT/UWP_VS2015/SDL-UWP.sln rename to SDL2-2.30.5/VisualC-WinRT/SDL-UWP.sln index 0a786e7..472c4f0 100644 --- a/SDL2-2.0.12/VisualC-WinRT/UWP_VS2015/SDL-UWP.sln +++ b/SDL2-2.30.5/VisualC-WinRT/SDL-UWP.sln @@ -8,21 +8,27 @@ EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|ARM = Debug|ARM + Debug|ARM64 = Debug|ARM64 Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 Release|ARM = Release|ARM + Release|ARM64 = Release|ARM64 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|ARM64.ActiveCfg = Debug|ARM64 + {89E9B32E-A86A-47C3-A948-D2B1622925CE}.Debug|ARM64.Build.0 = Debug|ARM64 {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|ARM64.ActiveCfg = Release|ARM64 + {89E9B32E-A86A-47C3-A948-D2B1622925CE}.Release|ARM64.Build.0 = Release|ARM64 {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 diff --git a/SDL2-2.30.5/VisualC-WinRT/SDL-UWP.vcxproj b/SDL2-2.30.5/VisualC-WinRT/SDL-UWP.vcxproj new file mode 100644 index 0000000..696505f --- /dev/null +++ b/SDL2-2.30.5/VisualC-WinRT/SDL-UWP.vcxproj @@ -0,0 +1,606 @@ + + + + + Debug + ARM64 + + + Debug + ARM + + + Debug + Win32 + + + Debug + x64 + + + Release + ARM + + + Release + ARM64 + + + Release + Win32 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + true + + + true + + + true + + + + + + + + + + + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + true + + + + + + + {89e9b32e-a86a-47c3-a948-d2b1622925ce} + DynamicLibrary + SDL2-UWP + SDL2 + en-US + 14.0 + true + Windows Store + 8.2 + 10.0.16299.0 + 10.0.16299.0 + 10.0 + + + + DynamicLibrary + true + v142 + + + DynamicLibrary + true + v142 + + + DynamicLibrary + true + v142 + + + DynamicLibrary + true + v142 + + + DynamicLibrary + false + true + v142 + + + DynamicLibrary + false + true + v142 + + + DynamicLibrary + false + true + v142 + + + DynamicLibrary + false + true + v142 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + false + SDL2 + + + false + false + SDL2 + + + false + false + SDL2 + + + false + false + SDL2 + + + false + false + SDL2 + + + false + false + SDL2 + + + false + false + SDL2 + + + false + false + SDL2 + + + + NotUsing + false + ..\include;%(AdditionalIncludeDirectories) + DLL_EXPORT;_CRT_SECURE_NO_WARNINGS;SDL_BUILDING_WINRT=1;%(PreprocessorDefinitions) + + + Console + false + false + /nodefaultlib:vccorlibd /nodefaultlib:msvcrtd vccorlibd.lib msvcrtd.lib %(AdditionalOptions) + + + + + NotUsing + false + ..\include;%(AdditionalIncludeDirectories) + DLL_EXPORT;_CRT_SECURE_NO_WARNINGS;SDL_BUILDING_WINRT=1;%(PreprocessorDefinitions) + + + Console + false + false + /nodefaultlib:vccorlib /nodefaultlib:msvcrt vccorlib.lib msvcrt.lib %(AdditionalOptions) + + + + + NotUsing + false + ..\include;%(AdditionalIncludeDirectories) + DLL_EXPORT;_CRT_SECURE_NO_WARNINGS;SDL_BUILDING_WINRT=1;%(PreprocessorDefinitions) + + + Console + false + false + /nodefaultlib:vccorlibd /nodefaultlib:msvcrtd vccorlibd.lib msvcrtd.lib %(AdditionalOptions) + + + + + NotUsing + false + ..\include;%(AdditionalIncludeDirectories) + DLL_EXPORT;_CRT_SECURE_NO_WARNINGS;SDL_BUILDING_WINRT=1;%(PreprocessorDefinitions) + + + Console + false + false + /nodefaultlib:vccorlib /nodefaultlib:msvcrt vccorlib.lib msvcrt.lib %(AdditionalOptions) + + + + + NotUsing + false + ..\include;%(AdditionalIncludeDirectories) + DLL_EXPORT;_CRT_SECURE_NO_WARNINGS;SDL_BUILDING_WINRT=1;%(PreprocessorDefinitions) + + + Console + false + false + /nodefaultlib:vccorlibd /nodefaultlib:msvcrtd vccorlibd.lib msvcrtd.lib %(AdditionalOptions) + + + + + NotUsing + false + ..\include;%(AdditionalIncludeDirectories) + DLL_EXPORT;_CRT_SECURE_NO_WARNINGS;SDL_BUILDING_WINRT=1;%(PreprocessorDefinitions) + + + Console + false + false + /nodefaultlib:vccorlib /nodefaultlib:msvcrt vccorlib.lib msvcrt.lib %(AdditionalOptions) + + + + + NotUsing + false + ..\include;%(AdditionalIncludeDirectories) + DLL_EXPORT;_CRT_SECURE_NO_WARNINGS;SDL_BUILDING_WINRT=1;%(PreprocessorDefinitions) + + + Console + false + false + /nodefaultlib:vccorlibd /nodefaultlib:msvcrtd vccorlibd.lib msvcrtd.lib %(AdditionalOptions) + + + + + NotUsing + false + ..\include;%(AdditionalIncludeDirectories) + DLL_EXPORT;_CRT_SECURE_NO_WARNINGS;SDL_BUILDING_WINRT=1;%(PreprocessorDefinitions) + + + Console + false + false + /nodefaultlib:vccorlib /nodefaultlib:msvcrt vccorlib.lib msvcrt.lib %(AdditionalOptions) + + + + + + diff --git a/SDL2-2.30.5/VisualC-WinRT/SDL-UWP.vcxproj.filters b/SDL2-2.30.5/VisualC-WinRT/SDL-UWP.vcxproj.filters new file mode 100644 index 0000000..0045d54 --- /dev/null +++ b/SDL2-2.30.5/VisualC-WinRT/SDL-UWP.vcxproj.filters @@ -0,0 +1,855 @@ + + + + + {fa0ff2df-c3d6-498a-96f1-1f88e7ce0da3} + + + {68e1b30b-19ed-4612-93e4-6260c5a979e5} + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Header Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Header Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Source Files + + + Source Files + + + Source Files + + + diff --git a/SDL2-2.0.12/VisualC/SDL.sln b/SDL2-2.30.5/VisualC/SDL.sln similarity index 87% rename from SDL2-2.0.12/VisualC/SDL.sln rename to SDL2-2.30.5/VisualC/SDL.sln index b30d4eb..87b2cf5 100644 --- a/SDL2-2.0.12/VisualC/SDL.sln +++ b/SDL2-2.30.5/VisualC/SDL.sln @@ -50,8 +50,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "controllermap", "tests\cont EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testvulkan", "tests\testvulkan\testvulkan.vcxproj", "{0D604DFD-AAB6-442C-9368-F91A344146AB}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testwm2", "tests\testwm2\testwm2.vcxproj", "{C4E04D18-EF76-4B42-B4C2-16A1BACDC0A5}" +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testyuv", "tests\testyuv\testyuv.vcxproj", "{40FB7794-D3C3-4CFE-BCF4-A80C97635682}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testsensor", "tests\testsensor\testsensor.vcxproj", "{C4E04D18-EF76-4B42-B4C2-16A1BACDC0A4}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testsurround", "tests\testsurround\testsurround.vcxproj", "{70B894A9-E306-49E8-ABC2-932A952A5E5F}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -252,6 +258,14 @@ Global {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 + {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A5}.Debug|Win32.ActiveCfg = Debug|Win32 + {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A5}.Debug|Win32.Build.0 = Debug|Win32 + {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A5}.Debug|x64.ActiveCfg = Debug|x64 + {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A5}.Debug|x64.Build.0 = Debug|x64 + {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A5}.Release|Win32.ActiveCfg = Release|Win32 + {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A5}.Release|Win32.Build.0 = Release|Win32 + {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A5}.Release|x64.ActiveCfg = Release|x64 + {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A5}.Release|x64.Build.0 = Release|x64 {40FB7794-D3C3-4CFE-BCF4-A80C97635682}.Debug|Win32.ActiveCfg = Debug|Win32 {40FB7794-D3C3-4CFE-BCF4-A80C97635682}.Debug|Win32.Build.0 = Debug|Win32 {40FB7794-D3C3-4CFE-BCF4-A80C97635682}.Debug|x64.ActiveCfg = Debug|x64 @@ -260,6 +274,22 @@ Global {40FB7794-D3C3-4CFE-BCF4-A80C97635682}.Release|Win32.Build.0 = Release|Win32 {40FB7794-D3C3-4CFE-BCF4-A80C97635682}.Release|x64.ActiveCfg = Release|x64 {40FB7794-D3C3-4CFE-BCF4-A80C97635682}.Release|x64.Build.0 = Release|x64 + {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A4}.Debug|Win32.ActiveCfg = Debug|Win32 + {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A4}.Debug|Win32.Build.0 = Debug|Win32 + {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A4}.Debug|x64.ActiveCfg = Debug|x64 + {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A4}.Debug|x64.Build.0 = Debug|x64 + {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A4}.Release|Win32.ActiveCfg = Release|Win32 + {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A4}.Release|Win32.Build.0 = Release|Win32 + {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A4}.Release|x64.ActiveCfg = Release|x64 + {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A4}.Release|x64.Build.0 = Release|x64 + {70B894A9-E306-49E8-ABC2-932A952A5E5F}.Debug|Win32.ActiveCfg = Debug|Win32 + {70B894A9-E306-49E8-ABC2-932A952A5E5F}.Debug|Win32.Build.0 = Debug|Win32 + {70B894A9-E306-49E8-ABC2-932A952A5E5F}.Debug|x64.ActiveCfg = Debug|x64 + {70B894A9-E306-49E8-ABC2-932A952A5E5F}.Debug|x64.Build.0 = Debug|x64 + {70B894A9-E306-49E8-ABC2-932A952A5E5F}.Release|Win32.ActiveCfg = Release|Win32 + {70B894A9-E306-49E8-ABC2-932A952A5E5F}.Release|Win32.Build.0 = Release|Win32 + {70B894A9-E306-49E8-ABC2-932A952A5E5F}.Release|x64.ActiveCfg = Release|x64 + {70B894A9-E306-49E8-ABC2-932A952A5E5F}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -286,6 +316,12 @@ Global {E9558DFE-1961-4DD4-B09B-DD0EEFD5C315} = {D69D5741-611F-4E14-8541-1FEE94F50B5A} {55812185-D13C-4022-9C81-32E0F4A08306} = {D69D5741-611F-4E14-8541-1FEE94F50B5A} {0D604DFD-AAB6-442C-9368-F91A344146AB} = {D69D5741-611F-4E14-8541-1FEE94F50B5A} + {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A5} = {D69D5741-611F-4E14-8541-1FEE94F50B5A} {40FB7794-D3C3-4CFE-BCF4-A80C97635682} = {D69D5741-611F-4E14-8541-1FEE94F50B5A} + {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A4} = {D69D5741-611F-4E14-8541-1FEE94F50B5A} + {70B894A9-E306-49E8-ABC2-932A952A5E5F} = {D69D5741-611F-4E14-8541-1FEE94F50B5A} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C320C9F2-1A8F-41D7-B02B-6338F872BCAD} EndGlobalSection EndGlobal diff --git a/SDL2-2.0.12/VisualC/SDL/SDL.vcxproj b/SDL2-2.30.5/VisualC/SDL/SDL.vcxproj similarity index 80% rename from SDL2-2.0.12/VisualC/SDL/SDL.vcxproj rename to SDL2-2.30.5/VisualC/SDL/SDL.vcxproj index 404e668..a798514 100644 --- a/SDL2-2.0.12/VisualC/SDL/SDL.vcxproj +++ b/SDL2-2.30.5/VisualC/SDL/SDL.vcxproj @@ -22,19 +22,24 @@ SDL2 {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68} SDL + 10.0 DynamicLibrary + $(DefaultPlatformToolset) DynamicLibrary + $(DefaultPlatformToolset) DynamicLibrary + $(DefaultPlatformToolset) DynamicLibrary + $(DefaultPlatformToolset) @@ -96,8 +101,7 @@ Disabled $(ProjectDir)/../../include;%(AdditionalIncludeDirectories) %(AdditionalUsingDirectories) - _DEBUG;_WINDOWS;%(PreprocessorDefinitions) - MultiThreadedDLL + DLL_EXPORT;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) false StreamingSIMDExtensions Level3 @@ -127,13 +131,13 @@ Disabled $(ProjectDir)/../../include;%(AdditionalIncludeDirectories) %(AdditionalUsingDirectories) - _DEBUG;_WINDOWS;%(PreprocessorDefinitions) - MultiThreadedDLL + DLL_EXPORT;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) false Level3 OldStyle true OnlyExplicitInline + true _DEBUG;%(PreprocessorDefinitions) @@ -160,8 +164,7 @@ $(ProjectDir)/../../include;%(AdditionalIncludeDirectories) %(AdditionalUsingDirectories) - NDEBUG;_WINDOWS;%(PreprocessorDefinitions) - MultiThreadedDLL + DLL_EXPORT;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) false StreamingSIMDExtensions Level3 @@ -192,8 +195,7 @@ $(ProjectDir)/../../include;%(AdditionalIncludeDirectories) %(AdditionalUsingDirectories) - NDEBUG;_WINDOWS;%(PreprocessorDefinitions) - MultiThreadedDLL + DLL_EXPORT;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) false Level3 ProgramDatabase @@ -233,15 +235,20 @@ + + + + + @@ -279,6 +286,7 @@ + @@ -297,6 +305,8 @@ + + @@ -304,6 +314,7 @@ + @@ -311,27 +322,40 @@ - + + + + + + + + + + + + + + + - @@ -343,22 +367,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -366,6 +421,7 @@ + @@ -375,12 +431,21 @@ + + + + + + + + + @@ -397,6 +462,8 @@ + + @@ -413,24 +480,39 @@ + - + + + + + + + + + + + + + + - + + @@ -453,9 +535,15 @@ + + + + + + @@ -473,23 +561,31 @@ + + + + + + + + @@ -533,7 +629,9 @@ - + + + diff --git a/SDL2-2.30.5/VisualC/SDL/SDL.vcxproj.filters b/SDL2-2.30.5/VisualC/SDL/SDL.vcxproj.filters new file mode 100644 index 0000000..60899f5 --- /dev/null +++ b/SDL2-2.30.5/VisualC/SDL/SDL.vcxproj.filters @@ -0,0 +1,1369 @@ + + + + + {395b3af0-33d0-411b-b153-de1676bf1ef8} + + + {5a3e3167-75be-414f-8947-a5306df372b2} + + + {546d9ed1-988e-49d3-b1a5-e5b3d19de6c1} + + + {a56247ff-5108-4960-ba6a-6814fd1554ec} + + + {8880dfad-2a06-4e84-ab6e-6583641ad2d1} + + + {2b996a7f-f3e9-4300-a97f-2c907bcd89a9} + + + {5713d682-2bc7-4da4-bcf0-262a98f142eb} + + + {5e27e19f-b3f8-4e2d-b323-b00b2040ec86} + + + {a3ab9cff-8495-4a5c-8af6-27e43199a712} + + + {377061e4-3856-4f05-b916-0d3b360df0f6} + + + {226a6643-1c65-4c7f-92aa-861313d974bb} + + + {ef859522-a7fe-4a00-a511-d6a9896adf5b} + + + {01fd2642-4493-4316-b548-fb829f4c9125} + + + {cce7558f-590a-4f0a-ac0d-e579f76e588e} + + + {7a53c9e4-d4bd-40ed-9265-1625df685121} + + + {4c7a051c-ce7c-426c-bf8c-9187827f9052} + + + {97e2f79f-311b-42ea-81b2-e801649fdd93} + + + {baf97c8c-7e90-41e5-bff8-14051b8d3956} + + + {45e50d3a-56c9-4352-b811-0c60c49a2431} + + + {9d86e0ef-d6f6-4db2-bfc5-b3529406fa8d} + + + {b35fa13c-6ed2-4680-8c56-c7d71b76ceab} + + + {61b61b31-9e26-4171-a3bb-b969f1889726} + + + {f63aa216-6ee7-4143-90d3-32be3787f276} + + + {90bee923-89df-417f-a6c3-3e260a7dd54d} + + + {4c8ad943-c2fb-4014-9ca3-041e0ad08426} + + + {e90fa293-2828-4927-8113-35bf561024a9} + + + {3d68ae70-a9ff-46cf-be69-069f0b02aca0} + + + {ebc2fca3-3c26-45e3-815e-3e0581d5e226} + + + {47c445a2-7014-4e15-9660-7c89a27dddcf} + + + {d008487d-6ed0-4251-848b-79a68e3c1459} + + + {c9e8273e-13ae-47dc-bef8-8ad8e64c9a3d} + + + {0b8e136d-56ae-47e7-9981-e863a57ac616} + + + {bf3febd3-9328-43e8-b196-0fd3be8177dd} + + + {1a62dc68-52d2-4c07-9d81-d94dfe1d0d12} + + + {e9f01b22-34b3-4380-ade6-0e96c74e9c90} + + + {f674f22f-7841-4f3a-974e-c36b2d4823fc} + + + {d7ad92de-4e55-4202-9b2b-1bd9a35fe4dc} + + + {8311d79d-9ad5-4369-99fe-b2fb2659d402} + + + {6c4dfb80-fdf9-497c-a6ff-3cd8f22efde9} + + + {4810e35c-33cb-4da2-bfaf-452da20d3c9a} + + + {2cf93f1d-81fd-4bdc-998c-5e2fa43988bc} + + + {5752b7ab-2344-4f38-95ab-b5d3bc150315} + + + {7a0eae3d-f113-4914-b926-6816d1929250} + + + {ee602cbf-96a2-4b0b-92a9-51d38a727411} + + + {a812185b-9060-4a1c-8431-be4f66894626} + + + {31c16cdf-adc4-4950-8293-28ba530f3882} + + + {add61b53-8144-47d6-bd67-3420a87c4905} + + + {e7cdcf36-b462-49c7-98b7-07ea7b3687f4} + + + {82588eef-dcaa-4f69-b2a9-e675940ce54c} + + + {560239c3-8fa1-4d23-a81a-b8408b2f7d3f} + + + {81711059-7575-4ece-9e68-333b63e992c4} + + + {1e44970f-7535-4bfb-b8a5-ea0cea0349e0} + + + {1dd91224-1176-492b-a2cb-e26153394db0} + + + {e3ecfe50-cf22-41d3-8983-2fead5164b47} + + + {5521d22f-1e52-47a6-8c52-06a3b6bdefd7} + + + {4755f3a6-49ac-46d6-86be-21f5c21f2197} + + + {f48c2b17-1bee-4fec-a7c8-24cf619abe08} + + + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + API Headers + + + + + + API Headers + + + API Headers + + + API Headers + + + audio + + + audio + + + audio + + + audio + + + core\windows + + + core\windows + + + core\windows + + + core\windows + + + core\windows + + + dynapi + + + dynapi + + + dynapi + + + events + + + events + + + events + + + events + + + events + + + events + + + events + + + events + + + events + + + events + + + events + + + events + + + haptic + + + haptic + + + joystick + + + joystick + + + joystick + + + joystick + + + joystick + + + joystick + + + libm + + + libm + + + hidapi\hidapi + + + locale + + + misc + + + audio\directsound + + + audio\disk + + + audio\dummy + + + audio\winmm + + + audio\wasapi + + + haptic\windows + + + haptic\windows + + + haptic\windows + + + joystick\hidapi + + + joystick\hidapi + + + joystick\windows + + + joystick\windows + + + joystick\windows + + + joystick\windows + + + joystick\virtual + + + video + + + video + + + video + + + video + + + video + + + video + + + video + + + video + + + video + + + video + + + video + + + video + + + video\dummy + + + video\dummy + + + video\dummy + + + video\yuv2rgb + + + video\yuv2rgb + + + video\yuv2rgb + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + timer + + + thread + + + thread + + + thread\windows + + + thread\windows + + + thread\generic + + + sensor + + + sensor + + + sensor\dummy + + + sensor\windows + + + render + + + render + + + render + + + render\direct3d + + + render\direct3d11 + + + render\opengl + + + render\opengl + + + render\opengles2 + + + render\opengles2 + + + render\software + + + render\software + + + render\software + + + render\software + + + render\software + + + render\software + + + render\software + + + render\software + + + render\software + + + power + + + video\khronos\vulkan + + + video\khronos\vulkan + + + video\khronos\vulkan + + + video\khronos\vulkan + + + video\khronos\vulkan + + + video\khronos\vulkan + + + video\khronos\vulkan + + + video\khronos\vulkan + + + video\khronos\vulkan + + + video\khronos\vulkan + + + video\khronos\vulkan + + + video\khronos\vulkan + + + video\khronos\vulkan + + + video\khronos\vulkan + + + video\khronos\vulkan + + + video\khronos\vulkan + + + video\khronos\vulkan + + + video\khronos\vulkan + + + video\khronos\vulkan + + + video\khronos\vulkan + + + + + + + render\direct3d12 + + + + + + + + + + + + + + + audio + + + audio + + + audio + + + audio + + + audio + + + audio + + + atomic + + + atomic + + + core\windows + + + core\windows + + + core\windows + + + core\windows + + + cpuinfo + + + dynapi + + + events + + + events + + + events + + + events + + + events + + + events + + + events + + + events + + + events + + + events + + + file + + + filesystem\windows + + + haptic + + + hidapi + + + joystick + + + joystick + + + joystick + + + joystick + + + libm + + + libm + + + libm + + + libm + + + libm + + + libm + + + libm + + + libm + + + libm + + + libm + + + libm + + + libm + + + libm + + + libm + + + libm + + + libm + + + libm + + + libm + + + libm + + + libm + + + loadso\windows + + + misc + + + misc\windows + + + locale\windows + + + locale + + + audio\directsound + + + audio\disk + + + audio\dummy + + + audio\winmm + + + audio\wasapi + + + audio\wasapi + + + haptic\windows + + + haptic\windows + + + haptic\windows + + + haptic\dummy + + + joystick\dummy + + + joystick\hidapi + + + joystick\hidapi + + + joystick\hidapi + + + joystick\hidapi + + + joystick\hidapi + + + joystick\hidapi + + + joystick\hidapi + + + joystick\hidapi + + + joystick\hidapi + + + joystick\hidapi + + + joystick\hidapi + + + joystick\hidapi + + + joystick\hidapi + + + joystick\hidapi + + + joystick\hidapi + + + joystick\hidapi + + + joystick\hidapi + + + joystick\windows + + + joystick\windows + + + joystick\windows + + + joystick\windows + + + joystick\windows + + + joystick\virtual + + + video + + + video + + + video + + + video + + + video + + + video + + + video + + + video + + + video + + + video + + + video + + + video + + + video + + + video + + + video + + + video + + + video + + + video + + + video + + + video + + + video + + + video\dummy + + + video\dummy + + + video\dummy + + + video\yuv2rgb + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + video\windows + + + timer + + + timer\windows + + + thread + + + thread\windows + + + thread\windows + + + thread\windows + + + thread\windows + + + thread\windows + + + thread\generic + + + stdlib + + + stdlib + + + stdlib + + + stdlib + + + stdlib + + + stdlib + + + stdlib + + + stdlib + + + stdlib + + + sensor + + + sensor\dummy + + + sensor\windows + + + render + + + render + + + render + + + render\direct3d + + + render\direct3d + + + render\direct3d11 + + + render\direct3d11 + + + render\opengl + + + render\opengl + + + render\opengles2 + + + render\opengles2 + + + render\software + + + render\software + + + render\software + + + render\software + + + render\software + + + render\software + + + render\software + + + render\software + + + power + + + + power\windows + + + render\direct3d12 + + + render\direct3d12 + + + + + + + diff --git a/SDL2-2.0.12/VisualC/SDLmain/SDLmain.vcxproj b/SDL2-2.30.5/VisualC/SDLmain/SDLmain.vcxproj similarity index 94% rename from SDL2-2.0.12/VisualC/SDLmain/SDLmain.vcxproj rename to SDL2-2.30.5/VisualC/SDLmain/SDLmain.vcxproj index 12d66b7..ad63dc6 100644 --- a/SDL2-2.0.12/VisualC/SDLmain/SDLmain.vcxproj +++ b/SDL2-2.30.5/VisualC/SDLmain/SDLmain.vcxproj @@ -22,19 +22,24 @@ SDL2main {DA956FD3-E142-46F2-9DD5-C78BEBB56B7A} SDLmain + 10.0 StaticLibrary + $(DefaultPlatformToolset) StaticLibrary + $(DefaultPlatformToolset) StaticLibrary + $(DefaultPlatformToolset) StaticLibrary + $(DefaultPlatformToolset) diff --git a/SDL2-2.0.12/VisualC/SDLtest/SDLtest.vcxproj b/SDL2-2.30.5/VisualC/SDLtest/SDLtest.vcxproj similarity index 93% rename from SDL2-2.0.12/VisualC/SDLtest/SDLtest.vcxproj rename to SDL2-2.30.5/VisualC/SDLtest/SDLtest.vcxproj index b8bff93..042baf1 100644 --- a/SDL2-2.0.12/VisualC/SDLtest/SDLtest.vcxproj +++ b/SDL2-2.30.5/VisualC/SDLtest/SDLtest.vcxproj @@ -22,19 +22,24 @@ SDL2test {DA956FD3-E143-46F2-9FE5-C77BEBC56B1A} SDLtest + 10.0 StaticLibrary + $(DefaultPlatformToolset) StaticLibrary + $(DefaultPlatformToolset) StaticLibrary + $(DefaultPlatformToolset) StaticLibrary + $(DefaultPlatformToolset) diff --git a/SDL2-2.0.12/VisualC/clean.sh b/SDL2-2.30.5/VisualC/clean.sh similarity index 100% rename from SDL2-2.0.12/VisualC/clean.sh rename to SDL2-2.30.5/VisualC/clean.sh diff --git a/SDL2-2.0.12/VisualC/tests/checkkeys/checkkeys.vcxproj b/SDL2-2.30.5/VisualC/tests/checkkeys/checkkeys.vcxproj similarity index 92% rename from SDL2-2.0.12/VisualC/tests/checkkeys/checkkeys.vcxproj rename to SDL2-2.30.5/VisualC/tests/checkkeys/checkkeys.vcxproj index 46e2577..3f06837 100644 --- a/SDL2-2.0.12/VisualC/tests/checkkeys/checkkeys.vcxproj +++ b/SDL2-2.30.5/VisualC/tests/checkkeys/checkkeys.vcxproj @@ -21,19 +21,24 @@ {26828762-C95D-4637-9CB1-7F0979523813} checkkeys + 10.0 Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) @@ -195,6 +200,12 @@ false true + + {da956fd3-e143-46f2-9fe5-c77bebc56b1a} + false + false + true + @@ -211,4 +222,4 @@ - \ No newline at end of file + diff --git a/SDL2-2.0.12/VisualC/tests/controllermap/controllermap.vcxproj b/SDL2-2.30.5/VisualC/tests/controllermap/controllermap.vcxproj similarity index 85% rename from SDL2-2.0.12/VisualC/tests/controllermap/controllermap.vcxproj rename to SDL2-2.30.5/VisualC/tests/controllermap/controllermap.vcxproj index fedaf6c..66d8ef1 100644 --- a/SDL2-2.0.12/VisualC/tests/controllermap/controllermap.vcxproj +++ b/SDL2-2.30.5/VisualC/tests/controllermap/controllermap.vcxproj @@ -21,19 +21,24 @@ {55812185-D13C-4022-9C81-32E0F4A08306} controllermap + 10.0 Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) @@ -229,27 +234,46 @@ Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" + + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + + + Copying %(Filename)%(Extension) + copy "%(FullPath)" "$(ProjectDir)\" + + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + Copying %(Filename)%(Extension) + copy "%(FullPath)" "$(ProjectDir)\" + + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + Copying %(Filename)%(Extension) + copy "%(FullPath)" "$(ProjectDir)\" + + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + Copying %(Filename)%(Extension) + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + - \ No newline at end of file + diff --git a/SDL2-2.0.12/VisualC/tests/loopwave/loopwave.vcxproj b/SDL2-2.30.5/VisualC/tests/loopwave/loopwave.vcxproj similarity index 92% rename from SDL2-2.0.12/VisualC/tests/loopwave/loopwave.vcxproj rename to SDL2-2.30.5/VisualC/tests/loopwave/loopwave.vcxproj index 182a38b..c3fbf1c 100644 --- a/SDL2-2.0.12/VisualC/tests/loopwave/loopwave.vcxproj +++ b/SDL2-2.30.5/VisualC/tests/loopwave/loopwave.vcxproj @@ -21,19 +21,24 @@ {AAAD1CB5-7ADA-47AE-85A0-08A6EC48FAFB} loopwave + 10.0 Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) @@ -198,23 +203,24 @@ + Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) @@ -222,4 +228,4 @@ - \ No newline at end of file + diff --git a/SDL2-2.0.12/VisualC/tests/testatomic/testatomic.vcxproj b/SDL2-2.30.5/VisualC/tests/testatomic/testatomic.vcxproj similarity index 93% rename from SDL2-2.0.12/VisualC/tests/testatomic/testatomic.vcxproj rename to SDL2-2.30.5/VisualC/tests/testatomic/testatomic.vcxproj index f66dee8..25e8904 100644 --- a/SDL2-2.0.12/VisualC/tests/testatomic/testatomic.vcxproj +++ b/SDL2-2.30.5/VisualC/tests/testatomic/testatomic.vcxproj @@ -21,19 +21,24 @@ {66B32F7E-5716-48D0-B5B9-D832FD052DD5} testatomic + 10.0 Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) diff --git a/SDL2-2.0.12/VisualC/tests/testautomation/testautomation.vcxproj b/SDL2-2.30.5/VisualC/tests/testautomation/testautomation.vcxproj similarity index 92% rename from SDL2-2.0.12/VisualC/tests/testautomation/testautomation.vcxproj rename to SDL2-2.30.5/VisualC/tests/testautomation/testautomation.vcxproj index e5ce6a3..b781dca 100644 --- a/SDL2-2.0.12/VisualC/tests/testautomation/testautomation.vcxproj +++ b/SDL2-2.30.5/VisualC/tests/testautomation/testautomation.vcxproj @@ -21,19 +21,24 @@ {9C7E8C03-3130-436D-A97E-E8F8ED1AC4EA} testautomation + 10.0 Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) @@ -201,9 +206,13 @@ + + + + @@ -216,6 +225,7 @@ + diff --git a/SDL2-2.0.12/VisualC/tests/testdraw2/testdraw2.vcxproj b/SDL2-2.30.5/VisualC/tests/testdraw2/testdraw2.vcxproj similarity index 93% rename from SDL2-2.0.12/VisualC/tests/testdraw2/testdraw2.vcxproj rename to SDL2-2.30.5/VisualC/tests/testdraw2/testdraw2.vcxproj index c6dd911..08adadd 100644 --- a/SDL2-2.0.12/VisualC/tests/testdraw2/testdraw2.vcxproj +++ b/SDL2-2.30.5/VisualC/tests/testdraw2/testdraw2.vcxproj @@ -21,19 +21,24 @@ {8682FE1E-0CF6-4EDD-9BB5-1733D8C8B4DF} testdraw2 + 10.0 Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) diff --git a/SDL2-2.0.12/VisualC/tests/testfile/testfile.vcxproj b/SDL2-2.30.5/VisualC/tests/testfile/testfile.vcxproj similarity index 93% rename from SDL2-2.0.12/VisualC/tests/testfile/testfile.vcxproj rename to SDL2-2.30.5/VisualC/tests/testfile/testfile.vcxproj index d4967d7..718a447 100644 --- a/SDL2-2.0.12/VisualC/tests/testfile/testfile.vcxproj +++ b/SDL2-2.30.5/VisualC/tests/testfile/testfile.vcxproj @@ -21,19 +21,24 @@ {CAE4F1D0-314F-4B10-805B-0EFD670133A0} testfile + 10.0 Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) diff --git a/SDL2-2.0.12/VisualC/tests/testgamecontroller/testgamecontroller.vcxproj b/SDL2-2.30.5/VisualC/tests/testgamecontroller/testgamecontroller.vcxproj similarity index 83% rename from SDL2-2.0.12/VisualC/tests/testgamecontroller/testgamecontroller.vcxproj rename to SDL2-2.30.5/VisualC/tests/testgamecontroller/testgamecontroller.vcxproj index 1b91b87..d3710e2 100644 --- a/SDL2-2.0.12/VisualC/tests/testgamecontroller/testgamecontroller.vcxproj +++ b/SDL2-2.30.5/VisualC/tests/testgamecontroller/testgamecontroller.vcxproj @@ -21,19 +21,24 @@ {55812185-D13C-4022-9C81-32E0F4A08305} testgamecontroller + 10.0 Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) @@ -193,63 +198,82 @@ Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" + + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + + + Copying %(Filename)%(Extension) + copy "%(FullPath)" "$(ProjectDir)\" + + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + Copying %(Filename)%(Extension) + copy "%(FullPath)" "$(ProjectDir)\" + + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + Copying %(Filename)%(Extension) + copy "%(FullPath)" "$(ProjectDir)\" + + $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + Copying %(Filename)%(Extension) + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + - \ No newline at end of file + diff --git a/SDL2-2.0.12/VisualC/tests/testgesture/testgesture.vcxproj b/SDL2-2.30.5/VisualC/tests/testgesture/testgesture.vcxproj similarity index 93% rename from SDL2-2.0.12/VisualC/tests/testgesture/testgesture.vcxproj rename to SDL2-2.30.5/VisualC/tests/testgesture/testgesture.vcxproj index dc32fd4..6230336 100644 --- a/SDL2-2.0.12/VisualC/tests/testgesture/testgesture.vcxproj +++ b/SDL2-2.30.5/VisualC/tests/testgesture/testgesture.vcxproj @@ -21,19 +21,24 @@ {79CEE57E-1BC3-4FF6-90B3-9E39763CDAFF} testgesture + 10.0 Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) diff --git a/SDL2-2.0.12/VisualC/tests/testgl2/testgl2.vcxproj b/SDL2-2.30.5/VisualC/tests/testgl2/testgl2.vcxproj similarity index 94% rename from SDL2-2.0.12/VisualC/tests/testgl2/testgl2.vcxproj rename to SDL2-2.30.5/VisualC/tests/testgl2/testgl2.vcxproj index 3e50496..4bf1382 100644 --- a/SDL2-2.0.12/VisualC/tests/testgl2/testgl2.vcxproj +++ b/SDL2-2.30.5/VisualC/tests/testgl2/testgl2.vcxproj @@ -21,19 +21,24 @@ {8B5CFB38-CCBA-40A8-AD7A-89C57B070884} testgl2 + 10.0 Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) diff --git a/SDL2-2.0.12/VisualC/tests/testgles2/testgles2.vcxproj b/SDL2-2.30.5/VisualC/tests/testgles2/testgles2.vcxproj similarity index 93% rename from SDL2-2.0.12/VisualC/tests/testgles2/testgles2.vcxproj rename to SDL2-2.30.5/VisualC/tests/testgles2/testgles2.vcxproj index f1c633a..060037c 100644 --- a/SDL2-2.0.12/VisualC/tests/testgles2/testgles2.vcxproj +++ b/SDL2-2.30.5/VisualC/tests/testgles2/testgles2.vcxproj @@ -21,19 +21,24 @@ {E9558DFE-1961-4DD4-B09B-DD0EEFD5C315} testgles2 + 10.0 Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) diff --git a/SDL2-2.0.12/VisualC/tests/testjoystick/testjoystick.vcxproj b/SDL2-2.30.5/VisualC/tests/testjoystick/testjoystick.vcxproj similarity index 93% rename from SDL2-2.0.12/VisualC/tests/testjoystick/testjoystick.vcxproj rename to SDL2-2.30.5/VisualC/tests/testjoystick/testjoystick.vcxproj index b1c909f..5edad3a 100644 --- a/SDL2-2.0.12/VisualC/tests/testjoystick/testjoystick.vcxproj +++ b/SDL2-2.30.5/VisualC/tests/testjoystick/testjoystick.vcxproj @@ -21,19 +21,24 @@ {55812185-D13C-4022-9C81-32E0F4A08304} testjoystick + 10.0 Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) diff --git a/SDL2-2.0.12/VisualC/tests/testoverlay2/testoverlay2.vcxproj b/SDL2-2.30.5/VisualC/tests/testoverlay2/testoverlay2.vcxproj similarity index 92% rename from SDL2-2.0.12/VisualC/tests/testoverlay2/testoverlay2.vcxproj rename to SDL2-2.30.5/VisualC/tests/testoverlay2/testoverlay2.vcxproj index 6879544..e412a1d 100644 --- a/SDL2-2.0.12/VisualC/tests/testoverlay2/testoverlay2.vcxproj +++ b/SDL2-2.30.5/VisualC/tests/testoverlay2/testoverlay2.vcxproj @@ -21,19 +21,24 @@ {B51E0D74-F0A2-45A2-BD2A-8B7D95B8204A} testoverlay2 + 10.0 Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) @@ -193,25 +198,26 @@ Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + diff --git a/SDL2-2.0.12/VisualC/tests/testplatform/testplatform.vcxproj b/SDL2-2.30.5/VisualC/tests/testplatform/testplatform.vcxproj similarity index 94% rename from SDL2-2.0.12/VisualC/tests/testplatform/testplatform.vcxproj rename to SDL2-2.30.5/VisualC/tests/testplatform/testplatform.vcxproj index db3b7e9..c0a7008 100644 --- a/SDL2-2.0.12/VisualC/tests/testplatform/testplatform.vcxproj +++ b/SDL2-2.30.5/VisualC/tests/testplatform/testplatform.vcxproj @@ -21,19 +21,24 @@ {26932B24-EFC6-4E3A-B277-ED653DA37968} testplatform + 10.0 Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) diff --git a/SDL2-2.0.12/VisualC/tests/testpower/testpower.vcxproj b/SDL2-2.30.5/VisualC/tests/testpower/testpower.vcxproj similarity index 93% rename from SDL2-2.0.12/VisualC/tests/testpower/testpower.vcxproj rename to SDL2-2.30.5/VisualC/tests/testpower/testpower.vcxproj index 63e0168..906d435 100644 --- a/SDL2-2.0.12/VisualC/tests/testpower/testpower.vcxproj +++ b/SDL2-2.30.5/VisualC/tests/testpower/testpower.vcxproj @@ -21,19 +21,24 @@ {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A3} testpower + 10.0 Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) diff --git a/SDL2-2.0.12/VisualC/tests/testrendertarget/testrendertarget.vcxproj b/SDL2-2.30.5/VisualC/tests/testrendertarget/testrendertarget.vcxproj similarity index 92% rename from SDL2-2.0.12/VisualC/tests/testrendertarget/testrendertarget.vcxproj rename to SDL2-2.30.5/VisualC/tests/testrendertarget/testrendertarget.vcxproj index b186ee9..e9ed5de 100644 --- a/SDL2-2.0.12/VisualC/tests/testrendertarget/testrendertarget.vcxproj +++ b/SDL2-2.30.5/VisualC/tests/testrendertarget/testrendertarget.vcxproj @@ -21,19 +21,24 @@ {2D17C1EB-1157-460E-9A99-A82BFC1F9D1E} testrendertarget + 10.0 Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) @@ -199,45 +204,46 @@ Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + - \ No newline at end of file + diff --git a/SDL2-2.0.12/VisualC/tests/testrumble/testrumble.vcxproj b/SDL2-2.30.5/VisualC/tests/testrumble/testrumble.vcxproj similarity index 93% rename from SDL2-2.0.12/VisualC/tests/testrumble/testrumble.vcxproj rename to SDL2-2.30.5/VisualC/tests/testrumble/testrumble.vcxproj index 81e6b9f..27d6170 100644 --- a/SDL2-2.0.12/VisualC/tests/testrumble/testrumble.vcxproj +++ b/SDL2-2.30.5/VisualC/tests/testrumble/testrumble.vcxproj @@ -21,19 +21,24 @@ {BFF40245-E9A6-4297-A425-A554E5D767E8} testrumble + 10.0 Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) diff --git a/SDL2-2.0.12/VisualC/tests/testscale/testscale.vcxproj b/SDL2-2.30.5/VisualC/tests/testscale/testscale.vcxproj similarity index 92% rename from SDL2-2.0.12/VisualC/tests/testscale/testscale.vcxproj rename to SDL2-2.30.5/VisualC/tests/testscale/testscale.vcxproj index 64ce50d..a42738b 100644 --- a/SDL2-2.0.12/VisualC/tests/testscale/testscale.vcxproj +++ b/SDL2-2.30.5/VisualC/tests/testscale/testscale.vcxproj @@ -21,19 +21,24 @@ {5D0930C0-7C91-4ECE-9014-7B7DDE9502E6} testscale + 10.0 Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) @@ -199,45 +204,46 @@ Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + - \ No newline at end of file + diff --git a/SDL2-2.30.5/VisualC/tests/testsensor/testsensor.vcxproj b/SDL2-2.30.5/VisualC/tests/testsensor/testsensor.vcxproj new file mode 100644 index 0000000..5afff77 --- /dev/null +++ b/SDL2-2.30.5/VisualC/tests/testsensor/testsensor.vcxproj @@ -0,0 +1,204 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A4} + testsensor + 10.0 + + + + Application + $(DefaultPlatformToolset) + + + Application + $(DefaultPlatformToolset) + + + Application + $(DefaultPlatformToolset) + + + Application + $(DefaultPlatformToolset) + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Debug/testsensor.tlb + + + Disabled + $(SolutionDir)/../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + OldStyle + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + Windows + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + X64 + .\Debug/testsensor.tlb + + + Disabled + $(SolutionDir)/../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + Level3 + OldStyle + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + Windows + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Release/testsensor.tlb + + + $(SolutionDir)/../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Windows + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + X64 + .\Release/testsensor.tlb + + + $(SolutionDir)/../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Windows + + + + + {81ce8daf-ebb2-4761-8e45-b71abcca8c68} + false + false + true + + + {da956fd3-e142-46f2-9dd5-c78bebb56b7a} + false + false + true + + + + + + + + + diff --git a/SDL2-2.0.12/VisualC/tests/testshape/testshape.vcxproj b/SDL2-2.30.5/VisualC/tests/testshape/testshape.vcxproj similarity index 93% rename from SDL2-2.0.12/VisualC/tests/testshape/testshape.vcxproj rename to SDL2-2.30.5/VisualC/tests/testshape/testshape.vcxproj index 81938c3..2be438b 100644 --- a/SDL2-2.0.12/VisualC/tests/testshape/testshape.vcxproj +++ b/SDL2-2.30.5/VisualC/tests/testshape/testshape.vcxproj @@ -21,19 +21,24 @@ {31A3E4E1-AAE9-4EF3-9B23-18D0924BE4D2} testshape + 10.0 Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) diff --git a/SDL2-2.0.12/VisualC/tests/testsprite2/testsprite2.vcxproj b/SDL2-2.30.5/VisualC/tests/testsprite2/testsprite2.vcxproj similarity index 92% rename from SDL2-2.0.12/VisualC/tests/testsprite2/testsprite2.vcxproj rename to SDL2-2.30.5/VisualC/tests/testsprite2/testsprite2.vcxproj index 7af6e1e..5ef2e11 100644 --- a/SDL2-2.0.12/VisualC/tests/testsprite2/testsprite2.vcxproj +++ b/SDL2-2.30.5/VisualC/tests/testsprite2/testsprite2.vcxproj @@ -21,19 +21,24 @@ {40FB7794-D3C3-4CFE-BCF4-A80C96635682} testsprite2 + 10.0 Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) @@ -199,27 +204,28 @@ Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) + - \ No newline at end of file + diff --git a/SDL2-2.30.5/VisualC/tests/testsurround/testsurround.vcxproj b/SDL2-2.30.5/VisualC/tests/testsurround/testsurround.vcxproj new file mode 100644 index 0000000..3286052 --- /dev/null +++ b/SDL2-2.30.5/VisualC/tests/testsurround/testsurround.vcxproj @@ -0,0 +1,210 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {70B894A9-E306-49E8-ABC2-932A952A5E5F} + testsurround + 10.0 + + + + Application + $(DefaultPlatformToolset) + + + Application + $(DefaultPlatformToolset) + + + Application + $(DefaultPlatformToolset) + + + Application + $(DefaultPlatformToolset) + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Release/testsurround.tlb + + + $(SolutionDir)/../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + .\Release/testsurround.pch + Level3 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Console + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + X64 + .\Release/testsurround.tlb + + + $(SolutionDir)/../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + + + .\Release/testsurround.pch + Level3 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Console + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Debug/testsurround.tlb + + + Disabled + $(SolutionDir)/../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + OldStyle + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + Console + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + X64 + .\Debug/testsurround.tlb + + + Disabled + $(SolutionDir)/../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + Level3 + OldStyle + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + Console + + + + + {81ce8daf-ebb2-4761-8e45-b71abcca8c68} + false + false + true + + + {da956fd3-e142-46f2-9dd5-c78bebb56b7a} + false + false + true + + + + + + + + + \ No newline at end of file diff --git a/SDL2-2.0.12/VisualC/tests/testvulkan/testvulkan.vcxproj b/SDL2-2.30.5/VisualC/tests/testvulkan/testvulkan.vcxproj similarity index 93% rename from SDL2-2.0.12/VisualC/tests/testvulkan/testvulkan.vcxproj rename to SDL2-2.30.5/VisualC/tests/testvulkan/testvulkan.vcxproj index 6cf0fdb..6e90fd0 100644 --- a/SDL2-2.0.12/VisualC/tests/testvulkan/testvulkan.vcxproj +++ b/SDL2-2.30.5/VisualC/tests/testvulkan/testvulkan.vcxproj @@ -21,19 +21,24 @@ {0D604DFD-AAB6-442C-9368-F91A344146AB} testvulkan + 10.0 Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) diff --git a/SDL2-2.30.5/VisualC/tests/testwm2/testwm2.vcxproj b/SDL2-2.30.5/VisualC/tests/testwm2/testwm2.vcxproj new file mode 100644 index 0000000..81d0902 --- /dev/null +++ b/SDL2-2.30.5/VisualC/tests/testwm2/testwm2.vcxproj @@ -0,0 +1,210 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {C4E04D18-EF76-4B42-B4C2-16A1BACDC0A5} + testwm2 + 10.0 + + + + Application + $(DefaultPlatformToolset) + + + Application + $(DefaultPlatformToolset) + + + Application + $(DefaultPlatformToolset) + + + Application + $(DefaultPlatformToolset) + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.40219.1 + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + AllRules.ruleset + + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Debug/testwm2.tlb + + + Disabled + $(SolutionDir)/../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + OldStyle + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + Windows + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + X64 + .\Debug/testwm2.tlb + + + Disabled + $(SolutionDir)/../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDebugDLL + Level3 + OldStyle + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + true + Windows + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Release/testwm2.tlb + + + $(SolutionDir)/../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Windows + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + X64 + .\Release/testwm2.tlb + + + $(SolutionDir)/../include;%(AdditionalIncludeDirectories) + %(AdditionalUsingDirectories) + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + Windows + + + + + {81ce8daf-ebb2-4761-8e45-b71abcca8c68} + false + false + true + + + {da956fd3-e142-46f2-9dd5-c78bebb56b7a} + false + false + true + + + {da956fd3-e143-46f2-9fe5-c77bebc56b1a} + false + false + true + + + + + + + + + diff --git a/SDL2-2.0.12/VisualC/tests/testyuv/testyuv.vcxproj b/SDL2-2.30.5/VisualC/tests/testyuv/testyuv.vcxproj similarity index 93% rename from SDL2-2.0.12/VisualC/tests/testyuv/testyuv.vcxproj rename to SDL2-2.30.5/VisualC/tests/testyuv/testyuv.vcxproj index c5738c6..0e9e03d 100644 --- a/SDL2-2.0.12/VisualC/tests/testyuv/testyuv.vcxproj +++ b/SDL2-2.30.5/VisualC/tests/testyuv/testyuv.vcxproj @@ -21,19 +21,24 @@ {40FB7794-D3C3-4CFE-BCF4-A80C97635682} testyuv + 10.0 Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) Application + $(DefaultPlatformToolset) @@ -199,19 +204,19 @@ Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) Copying %(Filename)%(Extension) - copy %(FullPath) $(ProjectDir)\ + copy "%(FullPath)" "$(ProjectDir)\" $(ProjectDir)\%(Filename)%(Extension);%(Outputs) diff --git a/SDL2-2.0.12/VisualC/visualtest/unittest/testquit/testquit_VS2012.vcxproj b/SDL2-2.30.5/VisualC/visualtest/unittest/testquit/testquit_VS2012.vcxproj similarity index 92% rename from SDL2-2.0.12/VisualC/visualtest/unittest/testquit/testquit_VS2012.vcxproj rename to SDL2-2.30.5/VisualC/visualtest/unittest/testquit/testquit_VS2012.vcxproj index 219b864..37fa039 100644 --- a/SDL2-2.0.12/VisualC/visualtest/unittest/testquit/testquit_VS2012.vcxproj +++ b/SDL2-2.30.5/VisualC/visualtest/unittest/testquit/testquit_VS2012.vcxproj @@ -22,28 +22,29 @@ testquit testquit {1D12C737-7C71-45CE-AE2C-AAB47B690BC8} + 10.0 Application false - v110 + $(DefaultPlatformToolset) Application false MultiByte - v110 + $(DefaultPlatformToolset) Application false - v110 + $(DefaultPlatformToolset) Application false - v110 + $(DefaultPlatformToolset) @@ -200,13 +201,13 @@ - + {da956fd3-e142-46f2-9dd5-c78bebb56b7a} - + {da956fd3-e143-46f2-9fe5-c77bebc56b1a} - + {81ce8daf-ebb2-4761-8e45-b71abcca8c68} diff --git a/SDL2-2.0.12/VisualC/visualtest/visualtest_VS2012.vcxproj b/SDL2-2.30.5/VisualC/visualtest/visualtest_VS2012.vcxproj similarity index 90% rename from SDL2-2.0.12/VisualC/visualtest/visualtest_VS2012.vcxproj rename to SDL2-2.30.5/VisualC/visualtest/visualtest_VS2012.vcxproj index 9244b6a..6ad5b61 100644 --- a/SDL2-2.0.12/VisualC/visualtest/visualtest_VS2012.vcxproj +++ b/SDL2-2.30.5/VisualC/visualtest/visualtest_VS2012.vcxproj @@ -22,28 +22,29 @@ visualtest visualtest {13DDF23A-4A8F-4AF9-9734-CC09D9157924} + 10.0 Application false - v110 + $(DefaultPlatformToolset) Application false MultiByte - v110 + $(DefaultPlatformToolset) Application false - v110 + $(DefaultPlatformToolset) Application false - v110 + $(DefaultPlatformToolset) @@ -110,6 +111,7 @@ true Windows + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;shlwapi.lib;%(AdditionalDependencies) copy "$(SolutionDir)..\test\icon.bmp" "$(ProjectDir)icon.bmp" @@ -152,6 +154,7 @@ copy /y "$(SolutionDir)..\visualtest\unittest\*.actions" "$(ProjectDir)" true Windows + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;shlwapi.lib;%(AdditionalDependencies) copy "$(SolutionDir)..\test\icon.bmp" "$(ProjectDir)icon.bmp" @@ -196,7 +199,7 @@ copy /y "$(SolutionDir)..\visualtest\unittest\*.actions" "$(ProjectDir)"true true Windows - kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;Shlwapi.lib;%(AdditionalDependencies) + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;shlwapi.lib;%(AdditionalDependencies) false @@ -241,6 +244,7 @@ copy /y "$(SolutionDir)..\visualtest\unittest\*.actions" "$(ProjectDir)"true Windows false + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;shlwapi.lib;%(AdditionalDependencies) copy "$(SolutionDir)..\test\icon.bmp" "$(ProjectDir)icon.bmp" @@ -288,13 +292,13 @@ copy /y "$(SolutionDir)..\visualtest\unittest\*.actions" "$(ProjectDir)" - + {da956fd3-e142-46f2-9dd5-c78bebb56b7a} - + {da956fd3-e143-46f2-9fe5-c77bebc56b1a} - + {81ce8daf-ebb2-4761-8e45-b71abcca8c68} diff --git a/SDL2-2.0.12/WhatsNew.txt b/SDL2-2.30.5/WhatsNew.txt similarity index 55% rename from SDL2-2.0.12/WhatsNew.txt rename to SDL2-2.30.5/WhatsNew.txt index 606b80d..90d9424 100644 --- a/SDL2-2.0.12/WhatsNew.txt +++ b/SDL2-2.30.5/WhatsNew.txt @@ -1,6 +1,366 @@ This is a list of major changes in SDL's version history. +--------------------------------------------------------------------------- +2.30.0: +--------------------------------------------------------------------------- + +General: +* Added support for 2 bits-per-pixel indexed surface formats +* Added the function SDL_GameControllerGetSteamHandle() to get the Steam API handle for a controller, if available +* Added the event SDL_CONTROLLERSTEAMHANDLEUPDATED which is sent when the Steam API handle for a controller changes. This could also change the name, VID, and PID of the controller. +* Added the environment variable SDL_LOGGING to control default log output + +macOS: +* Added the hint SDL_HINT_JOYSTICK_IOKIT to control whether the IOKit controller driver should be used +* Added the hint SDL_HINT_JOYSTICK_MFI to control whether the GCController controller driver should be used +* Added the hint SDL_HINT_RENDER_METAL_PREFER_LOW_POWER_DEVICE to choose whether high or low power GPU should be used for rendering, in the case where there are multiple GPUs available + +Xbox: +* Added the function SDL_GDKGetDefaultUser() + +--------------------------------------------------------------------------- +2.28.2: +--------------------------------------------------------------------------- + +General: +* Added the hint SDL_HINT_JOYSTICK_WGI to control whether to use Windows.Gaming.Input for controllers + + +--------------------------------------------------------------------------- +2.28.0: +--------------------------------------------------------------------------- + +General: +* Added SDL_HasWindowSurface() and SDL_DestroyWindowSurface() to switch between the window surface and rendering APIs +* Added a display event SDL_DISPLAYEVENT_MOVED which is sent when the primary monitor changes or displays change position relative to each other +* Added the hint SDL_HINT_ENABLE_SCREEN_KEYBOARD to control whether the on-screen keyboard should be shown when text input is active + + +--------------------------------------------------------------------------- +2.26.0: +--------------------------------------------------------------------------- + +General: +* Updated OpenGL headers to the latest API from The Khronos Group Inc. +* Added SDL_GetWindowSizeInPixels() to get the window size in pixels, which may differ from the window coordinate size for windows with high-DPI support +* Added simulated vsync synchronization for the software renderer +* Added the mouse position to SDL_MouseWheelEvent +* Added SDL_ResetHints() to reset all hints to their default values +* Added SDL_GetJoystickGUIDInfo() to get device information encoded in a joystick GUID +* Added the hint SDL_HINT_JOYSTICK_HIDAPI_XBOX_360 to control whether the HIDAPI driver for XBox 360 controllers should be used +* Added the hint SDL_HINT_JOYSTICK_HIDAPI_XBOX_360_PLAYER_LED to control whether the player LEDs should be lit to indicate which player is associated with an Xbox 360 controller +* Added the hint SDL_HINT_JOYSTICK_HIDAPI_XBOX_360_WIRELESS to control whether the HIDAPI driver for XBox 360 wireless controllers should be used +* Added the hint SDL_HINT_JOYSTICK_HIDAPI_XBOX_ONE to control whether the HIDAPI driver for XBox One controllers should be used +* Added the hint SDL_HINT_JOYSTICK_HIDAPI_XBOX_ONE_HOME_LED to control the brightness of the XBox One guide button LED +* Added support for PS3 controllers to the HIDAPI driver, enabled by default on macOS, controlled by the SDL_HINT_JOYSTICK_HIDAPI_PS3 hint +* Added support for Nintendo Wii controllers to the HIDAPI driver, not enabled by default, controlled by the SDL_HINT_JOYSTICK_HIDAPI_WII hint +* Added the hint SDL_HINT_JOYSTICK_HIDAPI_WII_PLAYER_LED to control whether the player LED should be lit on the Nintendo Wii controllers +* Added the hint SDL_HINT_JOYSTICK_HIDAPI_VERTICAL_JOY_CONS to control whether Nintendo Switch Joy-Con controllers will be in vertical mode when using the HIDAPI driver +* Added access to the individual left and right gyro sensors of the combined Joy-Cons controller +* Added a microsecond timestamp to SDL_SensorEvent and SDL_ControllerSensorEvent, when the hardware provides that information +* Added SDL_SensorGetDataWithTimestamp() and SDL_GameControllerGetSensorDataWithTimestamp() to retrieve the last sensor data with the associated microsecond timestamp +* Added the hint SDL_HINT_HIDAPI_IGNORE_DEVICES to have the SDL HID API ignore specific devices +* SDL_GetRevision() now includes more information about the SDL build, including the git commit hash if available + +Windows: +* Added the hint SDL_HINT_MOUSE_RELATIVE_SYSTEM_SCALE to control whether the system mouse acceleration curve is used for relative mouse motion + +macOS: +* Implemented vsync synchronization on macOS 12 + +Linux: +* Added SDL_SetPrimarySelectionText(), SDL_GetPrimarySelectionText(), and SDL_HasPrimarySelectionText() to interact with the X11 primary selection clipboard +* Added the hint SDL_HINT_VIDEO_WAYLAND_EMULATE_MOUSE_WARP to control whether mouse pointer warp emulation is enabled under Wayland + +Android: +* Enabled IME soft keyboard input +* Added version checking to make sure the SDL Java and C code are compatible + + +--------------------------------------------------------------------------- +2.24.0: +--------------------------------------------------------------------------- + +General: +* New version numbering scheme, similar to GLib and Flatpak. + * An even number in the minor version (second component) indicates a production-ready stable release such as 2.24.0, which would have been 2.0.24 under the old system. + * The patchlevel (micro version, third component) indicates a bugfix-only update: for example, 2.24.1 would be a bugfix-only release to fix bugs in 2.24.0, without adding new features. + * An odd number in the minor version indicates a prerelease such as 2.23.0. Stable distributions should not use these prereleases. + * The patchlevel indicates successive prereleases, for example 2.23.1 and 2.23.2 would be prereleases during development of the SDL 2.24.0 stable release. +* Added SDL_GetPointDisplayIndex() and SDL_GetRectDisplayIndex() to get the display associated with a point and rectangle in screen space +* Added SDL_bsearch(), SDL_crc16(), and SDL_utf8strnlen() to the stdlib routines +* Added SDL_CPUPauseInstruction() as a macro in SDL_atomic.h +* Added SDL_size_mul_overflow() and SDL_size_add_overflow() for better size overflow protection +* Added SDL_ResetHint() to reset a hint to the default value +* Added SDL_ResetKeyboard() to reset SDL's internal keyboard state, generating key up events for all currently pressed keys +* Added the hint SDL_HINT_MOUSE_RELATIVE_WARP_MOTION to control whether mouse warping generates motion events in relative mode. This hint defaults off. +* Added the hint SDL_HINT_TRACKPAD_IS_TOUCH_ONLY to control whether trackpads are treated as touch devices or mice. By default touchpads are treated as mouse input. +* The hint SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS now defaults on +* Added support for mini-gamepad mode for Nintendo Joy-Con controllers using the HIDAPI driver +* Added the hint SDL_HINT_JOYSTICK_HIDAPI_COMBINE_JOY_CONS to control whether Joy-Con controllers are automatically merged into a unified gamepad when using the HIDAPI driver. This hint defaults on. +* The hint SDL_HINT_JOYSTICK_HIDAPI_SWITCH_HOME_LED can be set to a floating point value to set the brightness of the Home LED on Nintendo Switch controllers +* Added the hint SDL_HINT_JOYSTICK_HIDAPI_JOYCON_HOME_LED to set the Home LED brightness for the Nintendo Joy-Con controllers. By default the Home LED is not modified. +* Added the hint SDL_HINT_JOYSTICK_HIDAPI_SWITCH_PLAYER_LED to control whether the player LED should be lit on the Nintendo Joy-Con controllers +* Added support for Nintendo Online classic controllers using the HIDAPI driver +* Added the hint SDL_HINT_JOYSTICK_HIDAPI_NINTENDO_CLASSIC to control whether the HIDAPI driver for Nintendo Online classic controllers should be used +* Added support for the NVIDIA Shield Controller to the HIDAPI driver, supporting rumble and battery status +* Added support for NVIDIA SHIELD controller to the HIDAPI driver, and a hint SDL_HINT_JOYSTICK_HIDAPI_SHIELD to control whether this is used +* Added functions to get the platform dependent name for a joystick or game controller: + * SDL_JoystickPathForIndex() + * SDL_JoystickPath() + * SDL_GameControllerPathForIndex() + * SDL_GameControllerPath() +* Added SDL_GameControllerGetFirmwareVersion() and SDL_JoystickGetFirmwareVersion(), currently implemented for DualSense(tm) Wireless Controllers using HIDAPI +* Added SDL_JoystickAttachVirtualEx() for extended virtual controller support +* Added joystick event SDL_JOYBATTERYUPDATED for when battery status changes +* Added SDL_GUIDToString() and SDL_GUIDFromString() to convert between SDL GUID and string +* Added SDL_HasLSX() and SDL_HasLASX() to detect LoongArch SIMD support +* Added SDL_GetOriginalMemoryFunctions() +* Added SDL_GetDefaultAudioInfo() to get the name and format of the default audio device, currently implemented for PipeWire, PulseAudio, WASAPI, and DirectSound +* Added HIDAPI driver for the NVIDIA SHIELD controller (2017 model) to enable support for battery status and rumble +* Added support for opening audio devices with 3 or 5 channels (2.1, 4.1). All channel counts from Mono to 7.1 are now supported. +* Rewrote audio channel converters used by SDL_AudioCVT, based on the channel matrix coefficients used as the default for FAudio voices +* SDL log messages are no longer limited to 4K and can be any length +* Fixed a long-standing calling convention issue with dynapi affecting OpenWatcom or OS/2 builds + +Windows: +* Added initial support for building for Windows and Xbox with Microsoft's Game Development Kit (GDK), see docs/README-gdk.md for details +* Added a D3D12 renderer implementation and SDL_RenderGetD3D12Device() to retrieve the D3D12 device associated with it +* Added the hint SDL_HINT_WINDOWS_DPI_AWARENESS to set whether the application is DPI-aware. This hint must be set before initializing the video subsystem +* Added the hint SDL_HINT_WINDOWS_DPI_SCALING to control whether the SDL coordinates are in DPI-scaled points or pixels +* Added the hint SDL_HINT_DIRECTINPUT_ENABLED to control whether the DirectInput driver should be used +* Added support for SDL_GetAudioDeviceSpec to the DirectSound backend + +Linux: +* Support for XVidMode has been removed, mode changes are only supported using the XRandR extension +* Added the hint SDL_HINT_VIDEO_WAYLAND_MODE_EMULATION to control whether to expose a set of emulated modes in addition to the native resolution modes available on Wayland +* Added the hint SDL_HINT_KMSDRM_DEVICE_INDEX to specify which KMSDRM device to use if the default is not desired +* Added the hint SDL_HINT_LINUX_DIGITAL_HATS to control whether to treat hats as digital rather than checking to see if they may be analog +* Added the hint SDL_HINT_LINUX_HAT_DEADZONES to control whether to use deadzones on analog hats + +macOS: +* Bumped minimum OS deployment version to macOS 10.9 +* Added SDL_GL_FLOATBUFFERS to allow Cocoa GL contexts to use EDR +* Added the hint SDL_HINT_MAC_OPENGL_ASYNC_DISPATCH to control whether dispatching OpenGL context updates should block the dispatching thread until the main thread finishes processing. This hint defaults to blocking, which is the safer option on modern macOS. + + +--------------------------------------------------------------------------- +2.0.22: +--------------------------------------------------------------------------- + +General: +* Added SDL_RenderGetWindow() to get the window associated with a renderer +* Added floating point rectangle functions: + * SDL_PointInFRect() + * SDL_FRectEmpty() + * SDL_FRectEquals() + * SDL_FRectEqualsEpsilon() + * SDL_HasIntersectionF() + * SDL_IntersectFRect() + * SDL_UnionFRect() + * SDL_EncloseFPoints() + * SDL_IntersectFRectAndLine() +* Added SDL_IsTextInputShown() which returns whether the IME window is currently shown +* Added SDL_ClearComposition() to dismiss the composition window without disabling IME input +* Added SDL_TEXTEDITING_EXT event for handling long composition text, and a hint SDL_HINT_IME_SUPPORT_EXTENDED_TEXT to enable it +* Added the hint SDL_HINT_MOUSE_RELATIVE_MODE_CENTER to control whether the mouse should be constrained to the whole window or the center of the window when relative mode is enabled +* The mouse is now automatically captured when mouse buttons are pressed, and the hint SDL_HINT_MOUSE_AUTO_CAPTURE allows you to control this behavior +* Added the hint SDL_HINT_VIDEO_FOREIGN_WINDOW_OPENGL to let SDL know that a foreign window will be used with OpenGL +* Added the hint SDL_HINT_VIDEO_FOREIGN_WINDOW_VULKAN to let SDL know that a foreign window will be used with Vulkan +* Added the hint SDL_HINT_QUIT_ON_LAST_WINDOW_CLOSE to specify whether an SDL_QUIT event will be delivered when the last application window is closed +* Added the hint SDL_HINT_JOYSTICK_ROG_CHAKRAM to control whether ROG Chakram mice show up as joysticks + +Windows: +* Added support for SDL_BLENDOPERATION_MINIMUM and SDL_BLENDOPERATION_MAXIMUM to the D3D9 renderer + +Linux: +* Compiling with Wayland support requires libwayland-client version 1.18.0 or later +* Added the hint SDL_HINT_X11_WINDOW_TYPE to specify the _NET_WM_WINDOW_TYPE of SDL windows +* Added the hint SDL_HINT_VIDEO_WAYLAND_PREFER_LIBDECOR to allow using libdecor with compositors that support xdg-decoration + +Android: +* Added SDL_AndroidSendMessage() to send a custom command to the SDL java activity + + +--------------------------------------------------------------------------- +2.0.20: +--------------------------------------------------------------------------- + +General: +* SDL_RenderGeometryRaw() takes a pointer to SDL_Color, not int. You can cast color data in SDL_PIXELFORMAT_RGBA32 format (SDL_PIXELFORMAT_ABGR8888 on little endian systems) for this parameter. +* Improved accuracy of horizontal and vertical line drawing when using OpenGL or OpenGLES +* Added the hint SDL_HINT_RENDER_LINE_METHOD to control the method of line drawing used, to select speed, correctness, and compatibility. + +Windows: +* Fixed size of custom cursors + +Linux: +* Fixed hotplug controller detection, broken in 2.0.18 + + +--------------------------------------------------------------------------- +2.0.18: +--------------------------------------------------------------------------- + +General: +* The SDL wiki documentation and development headers are automatically kept in sync +* Each function has information about in which version of SDL it was introduced +* SDL-specific CMake options are now prefixed with 'SDL_'. Be sure to update your CMake build scripts accordingly! +* Added the hint SDL_HINT_APP_NAME to let SDL know the name of your application for various places it might show up in system information +* Added SDL_RenderGeometry() and SDL_RenderGeometryRaw() to allow rendering of arbitrary shapes using the SDL 2D render API +* Added SDL_SetTextureUserData() and SDL_GetTextureUserData() to associate application data with an SDL texture +* Added SDL_RenderWindowToLogical() and SDL_RenderLogicalToWindow() to convert between window coordinates and logical render coordinates +* Added SDL_RenderSetVSync() to change whether a renderer present is synchronized with vblank at runtime +* Added SDL_PremultiplyAlpha() to premultiply alpha on a block of SDL_PIXELFORMAT_ARGB8888 pixels +* Added a window event SDL_WINDOWEVENT_DISPLAY_CHANGED which is sent when a window changes what display it's centered on +* Added SDL_GetWindowICCProfile() to query a window's ICC profile, and a window event SDL_WINDOWEVENT_ICCPROF_CHANGED that is sent when it changes +* Added the hint SDL_HINT_VIDEO_EGL_ALLOW_TRANSPARENCY to allow EGL windows to be transparent instead of opaque +* SDL_WaitEvent() has been redesigned to use less CPU in most cases +* Added SDL_SetWindowMouseRect() and SDL_GetWindowMouseRect() to confine the mouse cursor to an area of a window +* You can now read precise mouse wheel motion using 'preciseX' and 'preciseY' event fields +* Added SDL_GameControllerHasRumble() and SDL_GameControllerHasRumbleTriggers() to query whether a game controller supports rumble +* Added SDL_JoystickHasRumble() and SDL_JoystickHasRumbleTriggers() to query whether a joystick supports rumble +* SDL's hidapi implementation is now available as a public API in SDL_hidapi.h + +Windows: +* Improved relative mouse motion over Windows Remote Desktop +* Added the hint SDL_HINT_IME_SHOW_UI to show native UI components instead of hiding them (defaults off) + +Windows/UWP: +* WGI is used instead of XInput for better controller support in UWP apps + +Linux: +* Added the hint SDL_HINT_SCREENSAVER_INHIBIT_ACTIVITY_NAME to set the activity that's displayed by the system when the screensaver is disabled +* Added the hint SDL_HINT_LINUX_JOYSTICK_CLASSIC to control whether /dev/input/js* or /dev/input/event* are used as joystick devices +* Added the hint SDL_HINT_JOYSTICK_DEVICE to allow the user to specify devices that will be opened in addition to the normal joystick detection +* Added SDL_LinuxSetThreadPriorityAndPolicy() for more control over a thread priority on Linux + +Android: +* Added support for audio output and capture using AAudio on Android 8.1 and newer +* Steam Controller support is disabled by default, and can be enabled by setting the hint SDL_HINT_JOYSTICK_HIDAPI_STEAM to "1" before calling SDL_Init() + +Apple Arcade: +* Added SDL_GameControllerGetAppleSFSymbolsNameForButton() and SDL_GameControllerGetAppleSFSymbolsNameForAxis() to support Apple Arcade titles + +iOS: +* Added documentation that the UIApplicationSupportsIndirectInputEvents key must be set to true in your application's Info.plist in order to get real Bluetooth mouse events. +* Steam Controller support is disabled by default, and can be enabled by setting the hint SDL_HINT_JOYSTICK_HIDAPI_STEAM to "1" before calling SDL_Init() + + +--------------------------------------------------------------------------- +2.0.16: +--------------------------------------------------------------------------- +General: +* Added SDL_FlashWindow() to get a user's attention +* Added SDL_GetAudioDeviceSpec() to get the preferred audio format of a device +* Added SDL_SetWindowAlwaysOnTop() to dynamically change the SDL_WINDOW_ALWAYS_ON_TOP flag for a window +* Added SDL_SetWindowKeyboardGrab() to support grabbing the keyboard independently of the mouse +* Added SDL_SoftStretchLinear() to do bilinear scaling between 32-bit software surfaces +* Added SDL_UpdateNVTexture() to update streaming NV12/21 textures +* Added SDL_GameControllerSendEffect() and SDL_JoystickSendEffect() to allow sending custom trigger effects to the DualSense controller +* Added SDL_GameControllerGetSensorDataRate() to get the sensor data rate for PlayStation and Nintendo Switch controllers +* Added support for the Amazon Luna game controller +* Added rumble support for the Google Stadia controller using the HIDAPI driver +* Added SDL_GameControllerType constants for the Amazon Luna and Google Stadia controllers +* Added analog rumble for Nintendo Switch Pro controllers using the HIDAPI driver +* Reduced CPU usage when using SDL_WaitEvent() and SDL_WaitEventTimeout() + +Windows: +* Added SDL_SetWindowsMessageHook() to set a function that is called for all Windows messages +* Added SDL_RenderGetD3D11Device() to get the D3D11 device used by the SDL renderer + +Linux: +* Greatly improved Wayland support +* Added support for audio output and capture using Pipewire +* Added the hint SDL_HINT_AUDIO_INCLUDE_MONITORS to control whether PulseAudio recording should include monitor devices +* Added the hint SDL_HINT_AUDIO_DEVICE_STREAM_ROLE to describe the role of your application for audio control panels + +Android: +* Added SDL_AndroidShowToast() to show a lightweight notification + +iOS: +* Added support for mouse relative mode on iOS 14.1 and newer +* Added support for the Xbox Series X controller + +tvOS: +* Added support for the Xbox Series X controller + + +--------------------------------------------------------------------------- +2.0.14: +--------------------------------------------------------------------------- +General: +* Added support for PS5 DualSense and Xbox Series X controllers to the HIDAPI controller driver +* Added game controller button constants for paddles and new buttons +* Added game controller functions to get additional information: + * SDL_GameControllerGetSerial() + * SDL_GameControllerHasAxis() + * SDL_GameControllerHasButton() + * SDL_GameControllerGetNumTouchpads() + * SDL_GameControllerGetNumTouchpadFingers() + * SDL_GameControllerGetTouchpadFinger() + * SDL_GameControllerHasSensor() + * SDL_GameControllerSetSensorEnabled() + * SDL_GameControllerIsSensorEnabled() + * SDL_GameControllerGetSensorData() + * SDL_GameControllerRumbleTriggers() + * SDL_GameControllerHasLED() + * SDL_GameControllerSetLED() +* Added the hint SDL_HINT_JOYSTICK_HIDAPI_PS5 to control whether the HIDAPI driver for PS5 controllers should be used. +* Added joystick functions to get additional information: + * SDL_JoystickGetSerial() + * SDL_JoystickRumbleTriggers() + * SDL_JoystickHasLED() + * SDL_JoystickSetLED() +* Added an API to allow the application to create virtual joysticks: + * SDL_JoystickAttachVirtual() + * SDL_JoystickDetachVirtual() + * SDL_JoystickIsVirtual() + * SDL_JoystickSetVirtualAxis() + * SDL_JoystickSetVirtualButton() + * SDL_JoystickSetVirtualHat() +* Added SDL_LockSensors() and SDL_UnlockSensors() to guarantee exclusive access to the sensor list +* Added SDL_HAPTIC_STEERING_AXIS to play an effect on the steering wheel +* Added the hint SDL_HINT_MOUSE_RELATIVE_SCALING to control whether relative motion is scaled by the screen DPI or renderer logical size +* The default value for SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS is now false for better compatibility with modern window managers +* Added SDL_GetPreferredLocales() to get the application's current locale setting +* Added the hint SDL_HINT_PREFERRED_LOCALES to override your application's default locale setting +* Added SDL_OpenURL() to open a URL in the system's default browser +* Added SDL_HasSurfaceRLE() to tell whether a surface is currently using RLE encoding +* Added SDL_SIMDRealloc() to reallocate memory obtained from SDL_SIMDAlloc() +* Added SDL_GetErrorMsg() to get the last error in a thread-safe way +* Added SDL_crc32(), SDL_wcscasecmp(), SDL_wcsncasecmp(), SDL_trunc(), SDL_truncf() +* Added clearer names for RGB pixel formats, e.g. SDL_PIXELFORMAT_XRGB8888, SDL_PIXELFORMAT_XBGR8888, etc. + +Windows: +* Added the RAWINPUT controller driver to support more than 4 Xbox controllers simultaneously +* Added the hint SDL_HINT_JOYSTICK_RAWINPUT to control whether the RAWINPUT driver should be used +* Added the hint SDL_HINT_JOYSTICK_HIDAPI_CORRELATE_XINPUT to control whether XInput and WGI should be used to for complete controller functionality with the RAWINPUT driver. + +macOS: +* Added the SDL_WINDOW_METAL flag to specify that a window should be created with a Metal view +* Added SDL_Metal_GetLayer() to get the CAMetalLayer backing a Metal view +* Added SDL_Metal_GetDrawableSize() to get the size of a window's drawable, in pixels + +Linux: +* Added the hint SDL_HINT_AUDIO_DEVICE_APP_NAME to specify the name that shows up in PulseAudio for your application +* Added the hint SDL_HINT_AUDIO_DEVICE_STREAM_NAME to specify the name that shows up in PulseAudio associated with your audio stream +* Added the hint SDL_HINT_LINUX_JOYSTICK_DEADZONES to control whether HID defined dead zones should be respected on Linux +* Added the hint SDL_HINT_THREAD_PRIORITY_POLICY to specify the thread scheduler policy +* Added the hint SDL_HINT_THREAD_FORCE_REALTIME_TIME_CRITICAL to allow time critical threads to use a realtime scheduling policy + +Android: +* Added SDL_AndroidRequestPermission() to request a specific system permission +* Added the hint SDL_HINT_ANDROID_BLOCK_ON_PAUSE_PAUSEAUDIO to control whether audio will pause when the application goes intot he background + +OS/2: +* Added support for OS/2, see docs/README-os2.md for details + +Emscripten (running in a web browser): +* Added the hint SDL_HINT_EMSCRIPTEN_ASYNCIFY to control whether SDL should call emscripten_sleep internally + + --------------------------------------------------------------------------- 2.0.12: --------------------------------------------------------------------------- @@ -321,7 +681,7 @@ iOS: tvOS: * Added support for Apple TV -* Added a hint SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION to control whether he Apple TV remote's joystick axes will automatically match the rotation of the remote. +* Added a hint SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION to control whether he Apple TV remote's joystick axes will automatically match the rotation of the remote. Android: * Fixed SDL not resizing window when Android screen resolution changes @@ -466,8 +826,8 @@ Linux: * Added experimental Wayland and Mir support, disabled by default Android: -* Joystick support (minimum SDK version required to build SDL is now 12, - the required runtime version remains at 10, but on such devices joystick +* Joystick support (minimum SDK version required to build SDL is now 12, + the required runtime version remains at 10, but on such devices joystick support won't be available). * Hotplugging support for joysticks * Added a hint SDL_HINT_ACCELEROMETER_AS_JOYSTICK to control whether the accelerometer should be listed as a 3 axis joystick, which it will by default. @@ -520,7 +880,7 @@ iOS: Android: IMPORTANT: You MUST get the updated SDLActivity.java to match C code -* Moved EGL initialization to native code +* Moved EGL initialization to native code * Fixed the accelerometer axis rotation relative to the device rotation * Fixed race conditions when handling the EGL context on pause/resume * Touch devices are available for enumeration immediately after init diff --git a/SDL2-2.0.12/Xcode-iOS/Demos/Default.png b/SDL2-2.30.5/Xcode-iOS/Demos/Default.png similarity index 100% rename from SDL2-2.0.12/Xcode-iOS/Demos/Default.png rename to SDL2-2.30.5/Xcode-iOS/Demos/Default.png diff --git a/SDL2-2.0.12/Xcode-iOS/Demos/Demos.xcodeproj/project.pbxproj b/SDL2-2.30.5/Xcode-iOS/Demos/Demos.xcodeproj/project.pbxproj similarity index 50% rename from SDL2-2.0.12/Xcode-iOS/Demos/Demos.xcodeproj/project.pbxproj rename to SDL2-2.30.5/Xcode-iOS/Demos/Demos.xcodeproj/project.pbxproj index e7e793d..8fc664b 100644 --- a/SDL2-2.0.12/Xcode-iOS/Demos/Demos.xcodeproj/project.pbxproj +++ b/SDL2-2.30.5/Xcode-iOS/Demos/Demos.xcodeproj/project.pbxproj @@ -7,30 +7,19 @@ objects = { /* Begin PBXBuildFile section */ - 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */; }; - 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; - 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; - F3F7590022AC5EC7001D97F2 /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F3F758FF22AC5EC7001D97F2 /* Metal.framework */; }; - F3F7590122AC5F00001D97F2 /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F3F758FF22AC5EC7001D97F2 /* Metal.framework */; }; - F3F7590222AC5F3D001D97F2 /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F3F758FF22AC5EC7001D97F2 /* Metal.framework */; }; - F3F7590322AC5F71001D97F2 /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F3F758FF22AC5EC7001D97F2 /* Metal.framework */; }; - F3F7590422AC5F8D001D97F2 /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F3F758FF22AC5EC7001D97F2 /* Metal.framework */; }; - F3F7590522AC5FB3001D97F2 /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F3F758FF22AC5EC7001D97F2 /* Metal.framework */; }; - F3F7590622AC5FD1001D97F2 /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F3F758FF22AC5EC7001D97F2 /* Metal.framework */; }; + F3A497102555EE4800E92A8B /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F3A495992555ED0500E92A8B /* libSDL2.a */; }; + F3A4972F2555EE8A00E92A8B /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F3A495992555ED0500E92A8B /* libSDL2.a */; }; + F3A497422555EEBE00E92A8B /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F3A495992555ED0500E92A8B /* libSDL2.a */; }; + F3A497442555EECD00E92A8B /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F3A495992555ED0500E92A8B /* libSDL2.a */; }; + F3A497462555EEDF00E92A8B /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F3A4959B2555ED0500E92A8B /* libSDL2.a */; }; + F3A497492555EF0B00E92A8B /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F3A495992555ED0500E92A8B /* libSDL2.a */; }; + F3A4974B2555EF1B00E92A8B /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F3A495992555ED0500E92A8B /* libSDL2.a */; }; + F3A4974E2555EF9F00E92A8B /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F3A495992555ED0500E92A8B /* libSDL2.a */; }; FA30DEB01BBF5A8F009C397F /* common.c in Sources */ = {isa = PBXBuildFile; fileRef = FD77A0060E26BC0500F39101 /* common.c */; }; FA30DEB11BBF5A93009C397F /* happy.c in Sources */ = {isa = PBXBuildFile; fileRef = FD77A0080E26BC0500F39101 /* happy.c */; }; FA30DEB31BBF5AD7009C397F /* icon.bmp in Resources */ = {isa = PBXBuildFile; fileRef = FDB651CC0E43D19800F688B5 /* icon.bmp */; }; FA30DEB41BBF5ADD009C397F /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = FD925B180E0F276600E92347 /* Icon.png */; }; FA30DEB61BBF5AE6009C397F /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = FD787AA00E22A5CC003E8E36 /* Default.png */; }; - FA30DEB71BBF5BB8009C397F /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FA30DEAC1BBF59D9009C397F /* libSDL2.a */; }; - FA30DEC81BBF5C14009C397F /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAE0E9691BAF96A00098DFA4 /* GameController.framework */; }; - FA30DEC91BBF5C14009C397F /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDF0D7220E12D31800247964 /* AudioToolbox.framework */; }; - FA30DECA1BBF5C14009C397F /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDB96EDF0DEFC9DC00FAF19F /* QuartzCore.framework */; }; - FA30DECB1BBF5C14009C397F /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDB96ED30DEFC9C700FAF19F /* OpenGLES.framework */; }; - FA30DECC1BBF5C14009C397F /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */; }; - FA30DECD1BBF5C14009C397F /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; - FA30DECE1BBF5C14009C397F /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; - FA30DECF1BBF5C14009C397F /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDF0D71D0E12D2AB00247964 /* CoreAudio.framework */; }; FA86C0371D9765BB009CB637 /* iOS Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FA86C0361D9765BA009CB637 /* iOS Launch Screen.storyboard */; }; FA86C0381D9765BB009CB637 /* iOS Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FA86C0361D9765BA009CB637 /* iOS Launch Screen.storyboard */; }; FA86C0391D9765BB009CB637 /* iOS Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FA86C0361D9765BA009CB637 /* iOS Launch Screen.storyboard */; }; @@ -38,43 +27,6 @@ FA86C03B1D9765BB009CB637 /* iOS Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FA86C0361D9765BA009CB637 /* iOS Launch Screen.storyboard */; }; FA86C03C1D9765BB009CB637 /* iOS Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FA86C0361D9765BA009CB637 /* iOS Launch Screen.storyboard */; }; FA86C03D1D9765BB009CB637 /* iOS Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FA86C0361D9765BA009CB637 /* iOS Launch Screen.storyboard */; }; - FA8B4BA31967070A00F8EB7C /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA8B4BA21967070A00F8EB7C /* CoreMotion.framework */; }; - FA8B4BA41967071300F8EB7C /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA8B4BA21967070A00F8EB7C /* CoreMotion.framework */; }; - FA8B4BA51967071A00F8EB7C /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA8B4BA21967070A00F8EB7C /* CoreMotion.framework */; }; - FA8B4BA61967072100F8EB7C /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA8B4BA21967070A00F8EB7C /* CoreMotion.framework */; }; - FA8B4BA71967072800F8EB7C /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA8B4BA21967070A00F8EB7C /* CoreMotion.framework */; }; - FA8B4BA81967073400F8EB7C /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA8B4BA21967070A00F8EB7C /* CoreMotion.framework */; }; - FA8B4BA91967073D00F8EB7C /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA8B4BA21967070A00F8EB7C /* CoreMotion.framework */; }; - FABA34D41D8B5E5600915323 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FABA34D31D8B5E5600915323 /* AVFoundation.framework */; }; - FABA34D61D8B5E5A00915323 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FABA34D31D8B5E5600915323 /* AVFoundation.framework */; }; - FABA34D91D8B5E7B00915323 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FABA34D31D8B5E5600915323 /* AVFoundation.framework */; }; - FABA34DA1D8B5E7F00915323 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FABA34D31D8B5E5600915323 /* AVFoundation.framework */; }; - FABA34DB1D8B5E8500915323 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FABA34D31D8B5E5600915323 /* AVFoundation.framework */; }; - FABA34DC1D8B5E8900915323 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FABA34D31D8B5E5600915323 /* AVFoundation.framework */; }; - FABA34DD1D8B5E8D00915323 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FABA34D31D8B5E5600915323 /* AVFoundation.framework */; }; - FAE0E96A1BAF96A00098DFA4 /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAE0E9691BAF96A00098DFA4 /* GameController.framework */; }; - FAE0E96C1BAF96A90098DFA4 /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAE0E9691BAF96A00098DFA4 /* GameController.framework */; }; - FAE0E96D1BAF96AF0098DFA4 /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAE0E9691BAF96A00098DFA4 /* GameController.framework */; }; - FAE0E96E1BAF96B10098DFA4 /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAE0E9691BAF96A00098DFA4 /* GameController.framework */; }; - FAE0E96F1BAF96B50098DFA4 /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAE0E9691BAF96A00098DFA4 /* GameController.framework */; }; - FAE0E9701BAF96B80098DFA4 /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAE0E9691BAF96A00098DFA4 /* GameController.framework */; }; - FAE0E9711BAF96BB0098DFA4 /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAE0E9691BAF96A00098DFA4 /* GameController.framework */; }; - FD15FD690E086911003BDF25 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; - FD15FD6A0E086911003BDF25 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; - FD15FD6B0E086911003BDF25 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */; }; - FD15FD6C0E086911003BDF25 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDB96ED30DEFC9C700FAF19F /* OpenGLES.framework */; }; - FD15FD6D0E086911003BDF25 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDB96EDF0DEFC9DC00FAF19F /* QuartzCore.framework */; }; - FD1B48DD0E313255007AB34E /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FD1B489E0E313154007AB34E /* libSDL2.a */; }; - FD1B49980E313261007AB34E /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FD1B489E0E313154007AB34E /* libSDL2.a */; }; - FD1B499C0E313269007AB34E /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FD1B489E0E313154007AB34E /* libSDL2.a */; }; - FD1B499E0E31326C007AB34E /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FD1B489E0E313154007AB34E /* libSDL2.a */; }; - FD1B49A00E313270007AB34E /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FD1B489E0E313154007AB34E /* libSDL2.a */; }; - FD1B49A20E313273007AB34E /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FD1B489E0E313154007AB34E /* libSDL2.a */; }; - FD5F9CE80E0E0741008E885B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; - FD5F9CE90E0E0741008E885B /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; - FD5F9CEA0E0E0741008E885B /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */; }; - FD5F9CEB0E0E0741008E885B /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDB96ED30DEFC9C700FAF19F /* OpenGLES.framework */; }; - FD5F9CEC0E0E0741008E885B /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDB96EDF0DEFC9DC00FAF19F /* QuartzCore.framework */; }; FD77A00E0E26BC0500F39101 /* happy.c in Sources */ = {isa = PBXBuildFile; fileRef = FD77A0080E26BC0500F39101 /* happy.c */; }; FD77A0130E26BC0500F39101 /* common.c in Sources */ = {isa = PBXBuildFile; fileRef = FD77A0060E26BC0500F39101 /* common.c */; }; FD77A0160E26BC0500F39101 /* rectangles.c in Sources */ = {isa = PBXBuildFile; fileRef = FD77A00A0E26BC0500F39101 /* rectangles.c */; }; @@ -105,170 +57,104 @@ FDB651FA0E43D1F300F688B5 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = FD925B180E0F276600E92347 /* Icon.png */; }; FDB651FB0E43D1F300F688B5 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = FD787AA00E22A5CC003E8E36 /* Default.png */; }; FDB651FD0E43D1F300F688B5 /* common.c in Sources */ = {isa = PBXBuildFile; fileRef = FD77A0060E26BC0500F39101 /* common.c */; }; - FDB652000E43D1F300F688B5 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FD1B489E0E313154007AB34E /* libSDL2.a */; }; - FDB652020E43D1F300F688B5 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; - FDB652030E43D1F300F688B5 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; - FDB652040E43D1F300F688B5 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */; }; - FDB652050E43D1F300F688B5 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDB96ED30DEFC9C700FAF19F /* OpenGLES.framework */; }; - FDB652060E43D1F300F688B5 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDB96EDF0DEFC9DC00FAF19F /* QuartzCore.framework */; }; - FDB652070E43D1F300F688B5 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDF0D71D0E12D2AB00247964 /* CoreAudio.framework */; }; - FDB652080E43D1F300F688B5 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDF0D7220E12D31800247964 /* AudioToolbox.framework */; }; FDB652120E43D21A00F688B5 /* keyboard.c in Sources */ = {isa = PBXBuildFile; fileRef = FDB652110E43D21A00F688B5 /* keyboard.c */; }; FDB652C70E43E25900F688B5 /* kromasky_16x16.bmp in Resources */ = {isa = PBXBuildFile; fileRef = FDB652C60E43E25900F688B5 /* kromasky_16x16.bmp */; }; - FDB96ED40DEFC9C700FAF19F /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDB96ED30DEFC9C700FAF19F /* OpenGLES.framework */; }; - FDB96EE00DEFC9DC00FAF19F /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDB96EDF0DEFC9DC00FAF19F /* QuartzCore.framework */; }; FDC202E10E107B1200ABAC90 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = FD925B180E0F276600E92347 /* Icon.png */; }; - FDC202E60E107B1200ABAC90 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; - FDC202E70E107B1200ABAC90 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; - FDC202E80E107B1200ABAC90 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */; }; - FDC202E90E107B1200ABAC90 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDB96ED30DEFC9C700FAF19F /* OpenGLES.framework */; }; - FDC202EA0E107B1200ABAC90 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDB96EDF0DEFC9DC00FAF19F /* QuartzCore.framework */; }; FDC214870E26D78A00DDED23 /* common.c in Sources */ = {isa = PBXBuildFile; fileRef = FD77A0060E26BC0500F39101 /* common.c */; }; FDC52EC80E2843D6008D768C /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = FD925B180E0F276600E92347 /* Icon.png */; }; FDC52EC90E2843D6008D768C /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = FD787AA00E22A5CC003E8E36 /* Default.png */; }; FDC52ECF0E2843D6008D768C /* common.c in Sources */ = {isa = PBXBuildFile; fileRef = FD77A0060E26BC0500F39101 /* common.c */; }; - FDC52ED40E2843D6008D768C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; - FDC52ED50E2843D6008D768C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; - FDC52ED60E2843D6008D768C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */; }; - FDC52ED70E2843D6008D768C /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDB96ED30DEFC9C700FAF19F /* OpenGLES.framework */; }; - FDC52ED80E2843D6008D768C /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDB96EDF0DEFC9DC00FAF19F /* QuartzCore.framework */; }; - FDC52ED90E2843D6008D768C /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDF0D71D0E12D2AB00247964 /* CoreAudio.framework */; }; - FDC52EDA0E2843D6008D768C /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDF0D7220E12D31800247964 /* AudioToolbox.framework */; }; FDC52EE50E284410008D768C /* fireworks.c in Sources */ = {isa = PBXBuildFile; fileRef = FDC52EE40E284410008D768C /* fireworks.c */; }; FDF0D6960E12D05400247964 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = FD925B180E0F276600E92347 /* Icon.png */; }; - FDF0D69C0E12D05400247964 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; - FDF0D69D0E12D05400247964 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; - FDF0D69E0E12D05400247964 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */; }; - FDF0D69F0E12D05400247964 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDB96ED30DEFC9C700FAF19F /* OpenGLES.framework */; }; - FDF0D6A00E12D05400247964 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDB96EDF0DEFC9DC00FAF19F /* QuartzCore.framework */; }; - FDF0D71E0E12D2AB00247964 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDF0D71D0E12D2AB00247964 /* CoreAudio.framework */; }; - FDF0D7230E12D31800247964 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDF0D7220E12D31800247964 /* AudioToolbox.framework */; }; - FDF0D7950E12D52900247964 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDF0D71D0E12D2AB00247964 /* CoreAudio.framework */; }; - FDF0D7960E12D52900247964 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDF0D7220E12D31800247964 /* AudioToolbox.framework */; }; - FDF0D7A70E12D53200247964 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDF0D71D0E12D2AB00247964 /* CoreAudio.framework */; }; - FDF0D7A80E12D53200247964 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDF0D7220E12D31800247964 /* AudioToolbox.framework */; }; - FDF0D7A90E12D53500247964 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDF0D71D0E12D2AB00247964 /* CoreAudio.framework */; }; - FDF0D7AA0E12D53500247964 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDF0D7220E12D31800247964 /* AudioToolbox.framework */; }; - FDF0D7AB0E12D53800247964 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDF0D71D0E12D2AB00247964 /* CoreAudio.framework */; }; - FDF0D7AC0E12D53800247964 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDF0D7220E12D31800247964 /* AudioToolbox.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 049F3694130CD86800FF080F /* PBXContainerItemProxy */ = { + F3A495902555ED0500E92A8B /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = FD1B48920E313154007AB34E /* SDL.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = FD6526620DE8FCCB002AD96B; - remoteInfo = libSDL; - }; - 049F3696130CD87600FF080F /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = FD1B48920E313154007AB34E /* SDL.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = FD6526620DE8FCCB002AD96B; - remoteInfo = libSDL; - }; - 049F3698130CD87F00FF080F /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = FD1B48920E313154007AB34E /* SDL.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = FD6526620DE8FCCB002AD96B; - remoteInfo = libSDL; - }; - 049F369A130CD88800FF080F /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = FD1B48920E313154007AB34E /* SDL.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = FD6526620DE8FCCB002AD96B; - remoteInfo = libSDL; - }; - 049F369C130CD89000FF080F /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = FD1B48920E313154007AB34E /* SDL.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = FD6526620DE8FCCB002AD96B; - remoteInfo = libSDL; - }; - 049F369E130CD89800FF080F /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = FD1B48920E313154007AB34E /* SDL.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = FD6526620DE8FCCB002AD96B; - remoteInfo = libSDL; - }; - 049F36A0130CD8A000FF080F /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = FD1B48920E313154007AB34E /* SDL.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = FD6526620DE8FCCB002AD96B; - remoteInfo = libSDL; - }; - F3F758F722AC5E8F001D97F2 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = FD1B48920E313154007AB34E /* SDL.xcodeproj */; + containerPortal = F3A495802555ED0400E92A8B /* SDL.xcodeproj */; proxyType = 2; - remoteGlobalIDString = 52ED1E5C222889500061FCE0; - remoteInfo = "libSDL-iOS-dylib"; + remoteGlobalIDString = BECDF66C0761BA81005FE872; + remoteInfo = Framework; }; - F3F758F922AC5E8F001D97F2 /* PBXContainerItemProxy */ = { + F3A495922555ED0500E92A8B /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = FD1B48920E313154007AB34E /* SDL.xcodeproj */; + containerPortal = F3A495802555ED0400E92A8B /* SDL.xcodeproj */; proxyType = 2; - remoteGlobalIDString = F3E3C7572241389A007D243C; - remoteInfo = "libSDL-tvOS-dylib"; + remoteGlobalIDString = A7D88B5423E2437C00DCD162; + remoteInfo = "Framework-iOS"; }; - F3F758FB22AC5E8F001D97F2 /* PBXContainerItemProxy */ = { + F3A495942555ED0500E92A8B /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = FD1B48920E313154007AB34E /* SDL.xcodeproj */; + containerPortal = F3A495802555ED0400E92A8B /* SDL.xcodeproj */; proxyType = 2; - remoteGlobalIDString = F3E3C65222406928007D243C; - remoteInfo = "libSDLmain-iOS"; + remoteGlobalIDString = A7D88D1523E24BED00DCD162; + remoteInfo = "Framework-tvOS"; }; - F3F758FD22AC5E8F001D97F2 /* PBXContainerItemProxy */ = { + F3A495962555ED0500E92A8B /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = FD1B48920E313154007AB34E /* SDL.xcodeproj */; + containerPortal = F3A495802555ED0400E92A8B /* SDL.xcodeproj */; proxyType = 2; - remoteGlobalIDString = F3E3C75F224138AE007D243C; - remoteInfo = "libSDLmain-tvOS"; + remoteGlobalIDString = BECDF6B30761BA81005FE872; + remoteInfo = "Static Library"; }; - FA30DEAB1BBF59D9009C397F /* PBXContainerItemProxy */ = { + F3A495982555ED0500E92A8B /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = FD1B48920E313154007AB34E /* SDL.xcodeproj */; + containerPortal = F3A495802555ED0400E92A8B /* SDL.xcodeproj */; proxyType = 2; - remoteGlobalIDString = FAB598141BB5C1B100BE72C5; - remoteInfo = "libSDL-tv"; + remoteGlobalIDString = A7D88E5423E24D3B00DCD162; + remoteInfo = "Static Library-iOS"; }; - FA30DEAE1BBF5A69009C397F /* PBXContainerItemProxy */ = { + F3A4959A2555ED0500E92A8B /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = FD1B48920E313154007AB34E /* SDL.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = FAB598131BB5C1B100BE72C5; - remoteInfo = "libSDL-tv"; - }; - FD1B489D0E313154007AB34E /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = FD1B48920E313154007AB34E /* SDL.xcodeproj */; + containerPortal = F3A495802555ED0400E92A8B /* SDL.xcodeproj */; proxyType = 2; - remoteGlobalIDString = FD6526630DE8FCCB002AD96B; - remoteInfo = StaticLib; + remoteGlobalIDString = A769B23D23E259AE00872273; + remoteInfo = "Static Library-tvOS"; + }; + F3A4959C2555ED0500E92A8B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = F3A495802555ED0400E92A8B /* SDL.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = DB31407717554B71006C0E22; + remoteInfo = "Shared Library"; + }; + F3A4959E2555ED0500E92A8B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = F3A495802555ED0400E92A8B /* SDL.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = A75FCEB323E25AB700529352; + remoteInfo = "Shared Library-iOS"; + }; + F3A495A02555ED0500E92A8B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = F3A495802555ED0400E92A8B /* SDL.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = A75FD06C23E25AC700529352; + remoteInfo = "Shared Library-tvOS"; + }; + F3A495A22555ED0500E92A8B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = F3A495802555ED0400E92A8B /* SDL.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = BECDF6BE0761BA81005FE872; + remoteInfo = "Standard DMG"; + }; + F3C17D9128E4355900E1A26D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = F3A495802555ED0400E92A8B /* SDL.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = E2D187CF28A5673500D2B4F1; + remoteInfo = "xcFramework-iOS"; }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; - 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 1D6058910D05DD3D006BFB54 /* Rectangles.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Rectangles.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; - 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - F3F758FF22AC5EC7001D97F2 /* Metal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Metal.framework; path = System/Library/Frameworks/Metal.framework; sourceTree = SDKROOT; }; + F3A495802555ED0400E92A8B /* SDL.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SDL.xcodeproj; path = ../../Xcode/SDL/SDL.xcodeproj; sourceTree = ""; }; + F3C17D9F28E437C300E1A26D /* config.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = config.xcconfig; sourceTree = ""; }; FA30DE961BBF59D9009C397F /* Happy-TV.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Happy-TV.app"; sourceTree = BUILT_PRODUCTS_DIR; }; FA86C0361D9765BA009CB637 /* iOS Launch Screen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = "iOS Launch Screen.storyboard"; sourceTree = ""; }; - FA8B4BA21967070A00F8EB7C /* CoreMotion.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMotion.framework; path = System/Library/Frameworks/CoreMotion.framework; sourceTree = SDKROOT; }; - FABA34D31D8B5E5600915323 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; - FABA34D71D8B5E7700915323 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS10.0.sdk/System/Library/Frameworks/AVFoundation.framework; sourceTree = DEVELOPER_DIR; }; - FAE0E9691BAF96A00098DFA4 /* GameController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameController.framework; path = System/Library/Frameworks/GameController.framework; sourceTree = SDKROOT; }; FD15FCB20E086866003BDF25 /* Happy.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Happy.app; sourceTree = BUILT_PRODUCTS_DIR; }; - FD1B48920E313154007AB34E /* SDL.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SDL.xcodeproj; path = ../SDL/SDL.xcodeproj; sourceTree = SOURCE_ROOT; }; FD5F9BE40E0DEBEA008E885B /* Accel.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Accel.app; sourceTree = BUILT_PRODUCTS_DIR; }; FD77A0050E26BC0500F39101 /* accelerometer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = accelerometer.c; sourceTree = ""; }; FD77A0060E26BC0500F39101 /* common.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = common.c; sourceTree = ""; }; @@ -291,14 +177,10 @@ FDB6520C0E43D1F300F688B5 /* Keyboard.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Keyboard.app; sourceTree = BUILT_PRODUCTS_DIR; }; FDB652110E43D21A00F688B5 /* keyboard.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = keyboard.c; sourceTree = ""; }; FDB652C60E43E25900F688B5 /* kromasky_16x16.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = kromasky_16x16.bmp; sourceTree = ""; }; - FDB96ED30DEFC9C700FAF19F /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; }; - FDB96EDF0DEFC9DC00FAF19F /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; FDC202EE0E107B1200ABAC90 /* Touch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Touch.app; sourceTree = BUILT_PRODUCTS_DIR; }; FDC52EDE0E2843D6008D768C /* Fireworks.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Fireworks.app; sourceTree = BUILT_PRODUCTS_DIR; }; FDC52EE40E284410008D768C /* fireworks.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = fireworks.c; sourceTree = ""; }; FDF0D6A40E12D05400247964 /* Mixer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Mixer.app; sourceTree = BUILT_PRODUCTS_DIR; }; - FDF0D71D0E12D2AB00247964 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; }; - FDF0D7220E12D31800247964 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -306,18 +188,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - FD1B48DD0E313255007AB34E /* libSDL2.a in Frameworks */, - FDF0D7AC0E12D53800247964 /* AudioToolbox.framework in Frameworks */, - FABA34D41D8B5E5600915323 /* AVFoundation.framework in Frameworks */, - FDF0D7AB0E12D53800247964 /* CoreAudio.framework in Frameworks */, - 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */, - FA8B4BA31967070A00F8EB7C /* CoreMotion.framework in Frameworks */, - 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, - FAE0E96A1BAF96A00098DFA4 /* GameController.framework in Frameworks */, - F3F7590022AC5EC7001D97F2 /* Metal.framework in Frameworks */, - FDB96ED40DEFC9C700FAF19F /* OpenGLES.framework in Frameworks */, - FDB96EE00DEFC9DC00FAF19F /* QuartzCore.framework in Frameworks */, - 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + F3A497102555EE4800E92A8B /* libSDL2.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -325,15 +196,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - FA30DEB71BBF5BB8009C397F /* libSDL2.a in Frameworks */, - FA30DEC91BBF5C14009C397F /* AudioToolbox.framework in Frameworks */, - FA30DECF1BBF5C14009C397F /* CoreAudio.framework in Frameworks */, - FA30DECC1BBF5C14009C397F /* CoreGraphics.framework in Frameworks */, - FA30DECE1BBF5C14009C397F /* Foundation.framework in Frameworks */, - FA30DEC81BBF5C14009C397F /* GameController.framework in Frameworks */, - FA30DECA1BBF5C14009C397F /* QuartzCore.framework in Frameworks */, - FA30DECB1BBF5C14009C397F /* OpenGLES.framework in Frameworks */, - FA30DECD1BBF5C14009C397F /* UIKit.framework in Frameworks */, + F3A497462555EEDF00E92A8B /* libSDL2.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -341,18 +204,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - FD1B49980E313261007AB34E /* libSDL2.a in Frameworks */, - FDF0D7AA0E12D53500247964 /* AudioToolbox.framework in Frameworks */, - FABA34D61D8B5E5A00915323 /* AVFoundation.framework in Frameworks */, - FDF0D7A90E12D53500247964 /* CoreAudio.framework in Frameworks */, - FD15FD6B0E086911003BDF25 /* CoreGraphics.framework in Frameworks */, - FA8B4BA41967071300F8EB7C /* CoreMotion.framework in Frameworks */, - FD15FD690E086911003BDF25 /* Foundation.framework in Frameworks */, - FAE0E96C1BAF96A90098DFA4 /* GameController.framework in Frameworks */, - F3F7590122AC5F00001D97F2 /* Metal.framework in Frameworks */, - FD15FD6C0E086911003BDF25 /* OpenGLES.framework in Frameworks */, - FD15FD6D0E086911003BDF25 /* QuartzCore.framework in Frameworks */, - FD15FD6A0E086911003BDF25 /* UIKit.framework in Frameworks */, + F3A497442555EECD00E92A8B /* libSDL2.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -360,18 +212,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - FD1B499C0E313269007AB34E /* libSDL2.a in Frameworks */, - FDF0D7A80E12D53200247964 /* AudioToolbox.framework in Frameworks */, - FABA34D91D8B5E7B00915323 /* AVFoundation.framework in Frameworks */, - FDF0D7A70E12D53200247964 /* CoreAudio.framework in Frameworks */, - FD5F9CEA0E0E0741008E885B /* CoreGraphics.framework in Frameworks */, - FA8B4BA51967071A00F8EB7C /* CoreMotion.framework in Frameworks */, - FD5F9CE80E0E0741008E885B /* Foundation.framework in Frameworks */, - FAE0E96D1BAF96AF0098DFA4 /* GameController.framework in Frameworks */, - F3F7590222AC5F3D001D97F2 /* Metal.framework in Frameworks */, - FD5F9CEB0E0E0741008E885B /* OpenGLES.framework in Frameworks */, - FD5F9CEC0E0E0741008E885B /* QuartzCore.framework in Frameworks */, - FD5F9CE90E0E0741008E885B /* UIKit.framework in Frameworks */, + F3A4972F2555EE8A00E92A8B /* libSDL2.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -379,18 +220,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - FDB652000E43D1F300F688B5 /* libSDL2.a in Frameworks */, - FDB652080E43D1F300F688B5 /* AudioToolbox.framework in Frameworks */, - FABA34DD1D8B5E8D00915323 /* AVFoundation.framework in Frameworks */, - FDB652070E43D1F300F688B5 /* CoreAudio.framework in Frameworks */, - FDB652040E43D1F300F688B5 /* CoreGraphics.framework in Frameworks */, - FA8B4BA91967073D00F8EB7C /* CoreMotion.framework in Frameworks */, - FDB652020E43D1F300F688B5 /* Foundation.framework in Frameworks */, - FAE0E9711BAF96BB0098DFA4 /* GameController.framework in Frameworks */, - F3F7590622AC5FD1001D97F2 /* Metal.framework in Frameworks */, - FDB652050E43D1F300F688B5 /* OpenGLES.framework in Frameworks */, - FDB652060E43D1F300F688B5 /* QuartzCore.framework in Frameworks */, - FDB652030E43D1F300F688B5 /* UIKit.framework in Frameworks */, + F3A497492555EF0B00E92A8B /* libSDL2.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -398,18 +228,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - FD1B499E0E31326C007AB34E /* libSDL2.a in Frameworks */, - FDF0D7960E12D52900247964 /* AudioToolbox.framework in Frameworks */, - FABA34DA1D8B5E7F00915323 /* AVFoundation.framework in Frameworks */, - FDF0D7950E12D52900247964 /* CoreAudio.framework in Frameworks */, - FDC202E80E107B1200ABAC90 /* CoreGraphics.framework in Frameworks */, - FA8B4BA61967072100F8EB7C /* CoreMotion.framework in Frameworks */, - FDC202E60E107B1200ABAC90 /* Foundation.framework in Frameworks */, - FAE0E96E1BAF96B10098DFA4 /* GameController.framework in Frameworks */, - F3F7590322AC5F71001D97F2 /* Metal.framework in Frameworks */, - FDC202E90E107B1200ABAC90 /* OpenGLES.framework in Frameworks */, - FDC202EA0E107B1200ABAC90 /* QuartzCore.framework in Frameworks */, - FDC202E70E107B1200ABAC90 /* UIKit.framework in Frameworks */, + F3A4974E2555EF9F00E92A8B /* libSDL2.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -417,18 +236,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - FD1B49A20E313273007AB34E /* libSDL2.a in Frameworks */, - FDC52EDA0E2843D6008D768C /* AudioToolbox.framework in Frameworks */, - FABA34DC1D8B5E8900915323 /* AVFoundation.framework in Frameworks */, - FDC52ED90E2843D6008D768C /* CoreAudio.framework in Frameworks */, - FDC52ED60E2843D6008D768C /* CoreGraphics.framework in Frameworks */, - FA8B4BA81967073400F8EB7C /* CoreMotion.framework in Frameworks */, - FDC52ED40E2843D6008D768C /* Foundation.framework in Frameworks */, - FAE0E9701BAF96B80098DFA4 /* GameController.framework in Frameworks */, - F3F7590522AC5FB3001D97F2 /* Metal.framework in Frameworks */, - FDC52ED70E2843D6008D768C /* OpenGLES.framework in Frameworks */, - FDC52ED80E2843D6008D768C /* QuartzCore.framework in Frameworks */, - FDC52ED50E2843D6008D768C /* UIKit.framework in Frameworks */, + F3A497422555EEBE00E92A8B /* libSDL2.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -436,18 +244,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - FD1B49A00E313270007AB34E /* libSDL2.a in Frameworks */, - FDF0D7230E12D31800247964 /* AudioToolbox.framework in Frameworks */, - FABA34DB1D8B5E8500915323 /* AVFoundation.framework in Frameworks */, - FDF0D71E0E12D2AB00247964 /* CoreAudio.framework in Frameworks */, - FDF0D69E0E12D05400247964 /* CoreGraphics.framework in Frameworks */, - FA8B4BA71967072800F8EB7C /* CoreMotion.framework in Frameworks */, - FDF0D69C0E12D05400247964 /* Foundation.framework in Frameworks */, - FAE0E96F1BAF96B50098DFA4 /* GameController.framework in Frameworks */, - F3F7590422AC5F8D001D97F2 /* Metal.framework in Frameworks */, - FDF0D69F0E12D05400247964 /* OpenGLES.framework in Frameworks */, - FDF0D6A00E12D05400247964 /* QuartzCore.framework in Frameworks */, - FDF0D69D0E12D05400247964 /* UIKit.framework in Frameworks */, + F3A4974B2555EF1B00E92A8B /* libSDL2.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -472,11 +269,11 @@ 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { isa = PBXGroup; children = ( + F3C17D9F28E437C300E1A26D /* config.xcconfig */, + F3A495802555ED0400E92A8B /* SDL.xcodeproj */, FA86C0361D9765BA009CB637 /* iOS Launch Screen.storyboard */, - FD1B48920E313154007AB34E /* SDL.xcodeproj */, FD77A0040E26BC0500F39101 /* src */, 29B97317FDCFA39411CA2CEA /* Resources */, - 29B97323FDCFA39411CA2CEA /* Frameworks */, 19C28FACFE9D520D11CA2CBB /* Products */, ); name = CustomTemplate; @@ -488,39 +285,24 @@ FDB651C30E43D19800F688B5 /* data */, FD787AA00E22A5CC003E8E36 /* Default.png */, FD925B180E0F276600E92347 /* Icon.png */, - 8D1107310486CEB800E47090 /* Info.plist */, ); name = Resources; sourceTree = ""; }; - 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + F3A495812555ED0400E92A8B /* Products */ = { isa = PBXGroup; children = ( - F3F758FF22AC5EC7001D97F2 /* Metal.framework */, - FABA34D71D8B5E7700915323 /* AVFoundation.framework */, - FABA34D31D8B5E5600915323 /* AVFoundation.framework */, - FAE0E9691BAF96A00098DFA4 /* GameController.framework */, - FA8B4BA21967070A00F8EB7C /* CoreMotion.framework */, - FDF0D7220E12D31800247964 /* AudioToolbox.framework */, - FDB96EDF0DEFC9DC00FAF19F /* QuartzCore.framework */, - FDB96ED30DEFC9C700FAF19F /* OpenGLES.framework */, - 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */, - 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, - 1D30AB110D05D00D00671497 /* Foundation.framework */, - FDF0D71D0E12D2AB00247964 /* CoreAudio.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; - FD1B48930E313154007AB34E /* Products */ = { - isa = PBXGroup; - children = ( - FD1B489E0E313154007AB34E /* libSDL2.a */, - F3F758F822AC5E8F001D97F2 /* libSDL2.dylib */, - FA30DEAC1BBF59D9009C397F /* libSDL2.a */, - F3F758FA22AC5E8F001D97F2 /* libSDL2.dylib */, - F3F758FC22AC5E8F001D97F2 /* libSDLmain.a */, - F3F758FE22AC5E8F001D97F2 /* libSDLmain.a */, + F3A495912555ED0500E92A8B /* SDL2.framework */, + F3A495932555ED0500E92A8B /* SDL2.framework */, + F3A495952555ED0500E92A8B /* SDL2.framework */, + F3C17D9228E4355900E1A26D /* SDL2.framework */, + F3A495972555ED0500E92A8B /* libSDL2.a */, + F3A495992555ED0500E92A8B /* libSDL2.a */, + F3A4959B2555ED0500E92A8B /* libSDL2.a */, + F3A4959D2555ED0500E92A8B /* libSDL2.dylib */, + F3A4959F2555ED0500E92A8B /* libSDL2.dylib */, + F3A495A12555ED0500E92A8B /* libSDL2.dylib */, + F3A495A32555ED0500E92A8B /* SDL2 */, ); name = Products; sourceTree = ""; @@ -588,7 +370,6 @@ buildRules = ( ); dependencies = ( - 049F3695130CD86800FF080F /* PBXTargetDependency */, ); name = Rectangles; productName = SDLiPodTest; @@ -606,7 +387,6 @@ buildRules = ( ); dependencies = ( - FA30DEAF1BBF5A69009C397F /* PBXTargetDependency */, ); name = "Happy-TV"; productName = "Happy-TV"; @@ -624,7 +404,6 @@ buildRules = ( ); dependencies = ( - 049F3697130CD87600FF080F /* PBXTargetDependency */, ); name = Happy; productName = BMPTest; @@ -642,7 +421,6 @@ buildRules = ( ); dependencies = ( - 049F3699130CD87F00FF080F /* PBXTargetDependency */, ); name = Accel; productName = Accelerometer; @@ -660,7 +438,6 @@ buildRules = ( ); dependencies = ( - 049F36A1130CD8A000FF080F /* PBXTargetDependency */, ); name = Keyboard; productName = Accelerometer; @@ -678,7 +455,6 @@ buildRules = ( ); dependencies = ( - 049F369B130CD88800FF080F /* PBXTargetDependency */, ); name = Touch; productName = Accelerometer; @@ -696,7 +472,6 @@ buildRules = ( ); dependencies = ( - 049F369F130CD89800FF080F /* PBXTargetDependency */, ); name = Fireworks; productName = Accelerometer; @@ -714,7 +489,6 @@ buildRules = ( ); dependencies = ( - 049F369D130CD89000FF080F /* PBXTargetDependency */, ); name = Mixer; productName = Accelerometer; @@ -729,12 +503,32 @@ attributes = { LastUpgradeCheck = 0630; TargetAttributes = { + 1D6058900D05DD3D006BFB54 = { + DevelopmentTeam = MXGJJ98X76; + }; FA30DE951BBF59D9009C397F = { CreatedOnToolsVersion = 7.1; + DevelopmentTeam = MXGJJ98X76; + }; + FD15FCB10E086866003BDF25 = { + DevelopmentTeam = MXGJJ98X76; + }; + FD5F9BE30E0DEBEA008E885B = { + DevelopmentTeam = MXGJJ98X76; + }; + FDB651F70E43D1F300F688B5 = { + DevelopmentTeam = MXGJJ98X76; + }; + FDC202DD0E107B1200ABAC90 = { + DevelopmentTeam = MXGJJ98X76; }; FDC52EC60E2843D6008D768C = { + DevelopmentTeam = MXGJJ98X76; ProvisioningStyle = Automatic; }; + FDF0D6920E12D05400247964 = { + DevelopmentTeam = MXGJJ98X76; + }; }; }; buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Demos" */; @@ -752,65 +546,100 @@ projectDirPath = ""; projectReferences = ( { - ProductGroup = FD1B48930E313154007AB34E /* Products */; - ProjectRef = FD1B48920E313154007AB34E /* SDL.xcodeproj */; + ProductGroup = F3A495812555ED0400E92A8B /* Products */; + ProjectRef = F3A495802555ED0400E92A8B /* SDL.xcodeproj */; }, ); projectRoot = ""; targets = ( - 1D6058900D05DD3D006BFB54 /* Rectangles */, + FD5F9BE30E0DEBEA008E885B /* Accel */, + FDC52EC60E2843D6008D768C /* Fireworks */, FD15FCB10E086866003BDF25 /* Happy */, FA30DE951BBF59D9009C397F /* Happy-TV */, - FD5F9BE30E0DEBEA008E885B /* Accel */, - FDC202DD0E107B1200ABAC90 /* Touch */, - FDF0D6920E12D05400247964 /* Mixer */, - FDC52EC60E2843D6008D768C /* Fireworks */, FDB651F70E43D1F300F688B5 /* Keyboard */, + FDF0D6920E12D05400247964 /* Mixer */, + 1D6058900D05DD3D006BFB54 /* Rectangles */, + FDC202DD0E107B1200ABAC90 /* Touch */, ); }; /* End PBXProject section */ /* Begin PBXReferenceProxy section */ - F3F758F822AC5E8F001D97F2 /* libSDL2.dylib */ = { + F3A495912555ED0500E92A8B /* SDL2.framework */ = { isa = PBXReferenceProxy; - fileType = archive.ar; - path = libSDL2.dylib; - remoteRef = F3F758F722AC5E8F001D97F2 /* PBXContainerItemProxy */; + fileType = wrapper.framework; + path = SDL2.framework; + remoteRef = F3A495902555ED0500E92A8B /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - F3F758FA22AC5E8F001D97F2 /* libSDL2.dylib */ = { + F3A495932555ED0500E92A8B /* SDL2.framework */ = { isa = PBXReferenceProxy; - fileType = archive.ar; - path = libSDL2.dylib; - remoteRef = F3F758F922AC5E8F001D97F2 /* PBXContainerItemProxy */; + fileType = wrapper.framework; + path = SDL2.framework; + remoteRef = F3A495922555ED0500E92A8B /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - F3F758FC22AC5E8F001D97F2 /* libSDLmain.a */ = { + F3A495952555ED0500E92A8B /* SDL2.framework */ = { isa = PBXReferenceProxy; - fileType = archive.ar; - path = libSDLmain.a; - remoteRef = F3F758FB22AC5E8F001D97F2 /* PBXContainerItemProxy */; + fileType = wrapper.framework; + path = SDL2.framework; + remoteRef = F3A495942555ED0500E92A8B /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - F3F758FE22AC5E8F001D97F2 /* libSDLmain.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libSDLmain.a; - remoteRef = F3F758FD22AC5E8F001D97F2 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - FA30DEAC1BBF59D9009C397F /* libSDL2.a */ = { + F3A495972555ED0500E92A8B /* libSDL2.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; path = libSDL2.a; - remoteRef = FA30DEAB1BBF59D9009C397F /* PBXContainerItemProxy */; + remoteRef = F3A495962555ED0500E92A8B /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - FD1B489E0E313154007AB34E /* libSDL2.a */ = { + F3A495992555ED0500E92A8B /* libSDL2.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; path = libSDL2.a; - remoteRef = FD1B489D0E313154007AB34E /* PBXContainerItemProxy */; + remoteRef = F3A495982555ED0500E92A8B /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + F3A4959B2555ED0500E92A8B /* libSDL2.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libSDL2.a; + remoteRef = F3A4959A2555ED0500E92A8B /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + F3A4959D2555ED0500E92A8B /* libSDL2.dylib */ = { + isa = PBXReferenceProxy; + fileType = "compiled.mach-o.dylib"; + path = libSDL2.dylib; + remoteRef = F3A4959C2555ED0500E92A8B /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + F3A4959F2555ED0500E92A8B /* libSDL2.dylib */ = { + isa = PBXReferenceProxy; + fileType = "compiled.mach-o.dylib"; + path = libSDL2.dylib; + remoteRef = F3A4959E2555ED0500E92A8B /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + F3A495A12555ED0500E92A8B /* libSDL2.dylib */ = { + isa = PBXReferenceProxy; + fileType = "compiled.mach-o.dylib"; + path = libSDL2.dylib; + remoteRef = F3A495A02555ED0500E92A8B /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + F3A495A32555ED0500E92A8B /* SDL2 */ = { + isa = PBXReferenceProxy; + fileType = "compiled.mach-o.executable"; + path = SDL2; + remoteRef = F3A495A22555ED0500E92A8B /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + F3C17D9228E4355900E1A26D /* SDL2.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = SDL2.framework; + remoteRef = F3C17D9128E4355900E1A26D /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXReferenceProxy section */ @@ -984,56 +813,10 @@ }; /* End PBXSourcesBuildPhase section */ -/* Begin PBXTargetDependency section */ - 049F3695130CD86800FF080F /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = libSDL; - targetProxy = 049F3694130CD86800FF080F /* PBXContainerItemProxy */; - }; - 049F3697130CD87600FF080F /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = libSDL; - targetProxy = 049F3696130CD87600FF080F /* PBXContainerItemProxy */; - }; - 049F3699130CD87F00FF080F /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = libSDL; - targetProxy = 049F3698130CD87F00FF080F /* PBXContainerItemProxy */; - }; - 049F369B130CD88800FF080F /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = libSDL; - targetProxy = 049F369A130CD88800FF080F /* PBXContainerItemProxy */; - }; - 049F369D130CD89000FF080F /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = libSDL; - targetProxy = 049F369C130CD89000FF080F /* PBXContainerItemProxy */; - }; - 049F369F130CD89800FF080F /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = libSDL; - targetProxy = 049F369E130CD89800FF080F /* PBXContainerItemProxy */; - }; - 049F36A1130CD8A000FF080F /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = libSDL; - targetProxy = 049F36A0130CD8A000FF080F /* PBXContainerItemProxy */; - }; - FA30DEAF1BBF5A69009C397F /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = "libSDL-tv"; - targetProxy = FA30DEAE1BBF5A69009C397F /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - /* Begin XCBuildConfiguration section */ 1D6058940D05DD3E006BFB54 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - DEVELOPMENT_TEAM = ""; - INFOPLIST_FILE = Info.plist; - PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.Rectangles; PRODUCT_NAME = Rectangles; }; name = Debug; @@ -1041,78 +824,56 @@ 1D6058950D05DD3E006BFB54 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - DEVELOPMENT_TEAM = ""; - INFOPLIST_FILE = Info.plist; - PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.Rectangles; PRODUCT_NAME = Rectangles; }; name = Release; }; C01FCF4F08A954540054247B /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = F3C17D9F28E437C300E1A26D /* config.xcconfig */; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; GCC_OPTIMIZATION_LEVEL = 0; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + GENERATE_INFOPLIST_FILE = YES; HEADER_SEARCH_PATHS = ../../include; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks"; + MARKETING_VERSION = 1.0; ONLY_ACTIVE_ARCH = YES; - PRELINK_LIBS = ""; + OTHER_LDFLAGS = "$(CONFIG_FRAMEWORK_LDFLAGS)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.libsdl.$(PRODUCT_NAME)"; SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; + TVOS_DEPLOYMENT_TARGET = 9.0; }; name = Debug; }; C01FCF5008A954540054247B /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = F3C17D9F28E437C300E1A26D /* config.xcconfig */; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + GENERATE_INFOPLIST_FILE = YES; HEADER_SEARCH_PATHS = ../../include; - PRELINK_LIBS = ""; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks"; + MARKETING_VERSION = 1.0; + OTHER_LDFLAGS = "$(CONFIG_FRAMEWORK_LDFLAGS)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.libsdl.$(PRODUCT_NAME)"; SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; + TVOS_DEPLOYMENT_TARGET = 9.0; }; name = Release; }; FA30DEA71BBF59D9009C397F /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - DEVELOPMENT_TEAM = ""; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - INFOPLIST_FILE = Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - MTL_ENABLE_DEBUG_INFO = YES; - PRODUCT_BUNDLE_IDENTIFIER = "com.yourcompany.Happy-TV"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = appletvos; TARGETED_DEVICE_FAMILY = 3; @@ -1123,177 +884,94 @@ FA30DEA81BBF59D9009C397F /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DEVELOPMENT_TEAM = ""; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - INFOPLIST_FILE = Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - MTL_ENABLE_DEBUG_INFO = NO; - PRODUCT_BUNDLE_IDENTIFIER = "com.yourcompany.Happy-TV"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = appletvos; TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 9.0; - VALIDATE_PRODUCT = YES; }; name = Release; }; FD15FCB50E086866003BDF25 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - DEVELOPMENT_TEAM = ""; - GCC_DYNAMIC_NO_PIC = NO; - INFOPLIST_FILE = Info.plist; - PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.Happy; PRODUCT_NAME = Happy; - SDKROOT = iphoneos; }; name = Debug; }; FD15FCB60E086866003BDF25 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - DEVELOPMENT_TEAM = ""; - INFOPLIST_FILE = Info.plist; - PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.Happy; PRODUCT_NAME = Happy; - SDKROOT = iphoneos; }; name = Release; }; FD5F9BE70E0DEBEB008E885B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - DEVELOPMENT_TEAM = ""; - INFOPLIST_FILE = Info.plist; - PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.Accel; PRODUCT_NAME = Accel; - SDKROOT = iphoneos; }; name = Debug; }; FD5F9BE80E0DEBEB008E885B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - DEVELOPMENT_TEAM = ""; - INFOPLIST_FILE = Info.plist; - PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.Accel; PRODUCT_NAME = Accel; - SDKROOT = iphoneos; }; name = Release; }; FDB6520A0E43D1F300F688B5 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - DEVELOPMENT_TEAM = ""; - INFOPLIST_FILE = Info.plist; - PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.Keyboard; PRODUCT_NAME = Keyboard; - SDKROOT = iphoneos; }; name = Debug; }; FDB6520B0E43D1F300F688B5 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - DEVELOPMENT_TEAM = ""; - INFOPLIST_FILE = Info.plist; - PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.Keyboard; PRODUCT_NAME = Keyboard; - SDKROOT = iphoneos; }; name = Release; }; FDC202EC0E107B1200ABAC90 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - DEVELOPMENT_TEAM = ""; - INFOPLIST_FILE = Info.plist; - PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.Touch; PRODUCT_NAME = Touch; - SDKROOT = iphoneos; }; name = Debug; }; FDC202ED0E107B1200ABAC90 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - DEVELOPMENT_TEAM = ""; - INFOPLIST_FILE = Info.plist; - PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.Touch; PRODUCT_NAME = Touch; - SDKROOT = iphoneos; }; name = Release; }; FDC52EDC0E2843D6008D768C /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - DEVELOPMENT_TEAM = ""; - INFOPLIST_FILE = Info.plist; - PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.Fireworks; PRODUCT_NAME = Fireworks; - SDKROOT = iphoneos; }; name = Debug; }; FDC52EDD0E2843D6008D768C /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - DEVELOPMENT_TEAM = ""; - INFOPLIST_FILE = Info.plist; - PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.Fireworks; PRODUCT_NAME = Fireworks; - SDKROOT = iphoneos; }; name = Release; }; FDF0D6A20E12D05400247964 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - DEVELOPMENT_TEAM = ""; - INFOPLIST_FILE = Info.plist; - PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.Mixer; PRODUCT_NAME = Mixer; - SDKROOT = iphoneos; }; name = Debug; }; FDF0D6A30E12D05400247964 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - DEVELOPMENT_TEAM = ""; - INFOPLIST_FILE = Info.plist; - PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.Mixer; PRODUCT_NAME = Mixer; - SDKROOT = iphoneos; }; name = Release; }; diff --git a/SDL2-2.0.12/Xcode-iOS/Demos/Icon.png b/SDL2-2.30.5/Xcode-iOS/Demos/Icon.png similarity index 100% rename from SDL2-2.0.12/Xcode-iOS/Demos/Icon.png rename to SDL2-2.30.5/Xcode-iOS/Demos/Icon.png diff --git a/SDL2-2.0.12/Xcode-iOS/Demos/README b/SDL2-2.30.5/Xcode-iOS/Demos/README similarity index 100% rename from SDL2-2.0.12/Xcode-iOS/Demos/README rename to SDL2-2.30.5/Xcode-iOS/Demos/README diff --git a/SDL2-2.30.5/Xcode-iOS/Demos/config.xcconfig b/SDL2-2.30.5/Xcode-iOS/Demos/config.xcconfig new file mode 100644 index 0000000..5639172 --- /dev/null +++ b/SDL2-2.30.5/Xcode-iOS/Demos/config.xcconfig @@ -0,0 +1,14 @@ +// +// config.xcconfig +// SDL tests +// + +// Configuration settings file format documentation can be found at: +// https://help.apple.com/xcode/#/dev745c5c974 + +// Include any optional config for this build +#include? "build.xcconfig" + +CONFIG_FRAMEWORK_LDFLAGS[sdk=macos*] = $(inherited) -framework SDL2 -framework AudioToolbox -framework Carbon -framework Cocoa -framework CoreAudio -framework CoreHaptics -framework CoreVideo -framework ForceFeedback -framework GameController -framework IOKit -framework Metal +CONFIG_FRAMEWORK_LDFLAGS[sdk=iphone*] = $(inherited) -framework AVFoundation -framework AudioToolbox -framework CoreGraphics -framework CoreHaptics -framework CoreMotion -framework Foundation -framework GameController -framework Metal -framework OpenGLES -framework QuartzCore -framework UIKit +CONFIG_FRAMEWORK_LDFLAGS[sdk=appletv*] = $(inherited) -framework AVFoundation -framework AudioToolbox -framework CoreGraphics -framework CoreHaptics -framework Foundation -framework GameController -framework Metal -framework OpenGLES -framework QuartzCore -framework UIKit diff --git a/SDL2-2.0.12/Xcode-iOS/Demos/data/bitmapfont/kromasky_16x16.bmp b/SDL2-2.30.5/Xcode-iOS/Demos/data/bitmapfont/kromasky_16x16.bmp similarity index 100% rename from SDL2-2.0.12/Xcode-iOS/Demos/data/bitmapfont/kromasky_16x16.bmp rename to SDL2-2.30.5/Xcode-iOS/Demos/data/bitmapfont/kromasky_16x16.bmp diff --git a/SDL2-2.0.12/Xcode-iOS/Demos/data/bitmapfont/license.txt b/SDL2-2.30.5/Xcode-iOS/Demos/data/bitmapfont/license.txt similarity index 100% rename from SDL2-2.0.12/Xcode-iOS/Demos/data/bitmapfont/license.txt rename to SDL2-2.30.5/Xcode-iOS/Demos/data/bitmapfont/license.txt diff --git a/SDL2-2.0.12/Xcode-iOS/Demos/data/drums/ds_brush_snare.wav b/SDL2-2.30.5/Xcode-iOS/Demos/data/drums/ds_brush_snare.wav similarity index 100% rename from SDL2-2.0.12/Xcode-iOS/Demos/data/drums/ds_brush_snare.wav rename to SDL2-2.30.5/Xcode-iOS/Demos/data/drums/ds_brush_snare.wav diff --git a/SDL2-2.0.12/Xcode-iOS/Demos/data/drums/ds_china.wav b/SDL2-2.30.5/Xcode-iOS/Demos/data/drums/ds_china.wav similarity index 100% rename from SDL2-2.0.12/Xcode-iOS/Demos/data/drums/ds_china.wav rename to SDL2-2.30.5/Xcode-iOS/Demos/data/drums/ds_china.wav diff --git a/SDL2-2.0.12/Xcode-iOS/Demos/data/drums/ds_kick_big_amb.wav b/SDL2-2.30.5/Xcode-iOS/Demos/data/drums/ds_kick_big_amb.wav similarity index 100% rename from SDL2-2.0.12/Xcode-iOS/Demos/data/drums/ds_kick_big_amb.wav rename to SDL2-2.30.5/Xcode-iOS/Demos/data/drums/ds_kick_big_amb.wav diff --git a/SDL2-2.0.12/Xcode-iOS/Demos/data/drums/ds_loose_skin_mute.wav b/SDL2-2.30.5/Xcode-iOS/Demos/data/drums/ds_loose_skin_mute.wav similarity index 100% rename from SDL2-2.0.12/Xcode-iOS/Demos/data/drums/ds_loose_skin_mute.wav rename to SDL2-2.30.5/Xcode-iOS/Demos/data/drums/ds_loose_skin_mute.wav diff --git a/SDL2-2.0.12/Xcode-iOS/Demos/data/icon.bmp b/SDL2-2.30.5/Xcode-iOS/Demos/data/icon.bmp similarity index 100% rename from SDL2-2.0.12/Xcode-iOS/Demos/data/icon.bmp rename to SDL2-2.30.5/Xcode-iOS/Demos/data/icon.bmp diff --git a/SDL2-2.0.12/Xcode-iOS/Demos/data/ship.bmp b/SDL2-2.30.5/Xcode-iOS/Demos/data/ship.bmp similarity index 100% rename from SDL2-2.0.12/Xcode-iOS/Demos/data/ship.bmp rename to SDL2-2.30.5/Xcode-iOS/Demos/data/ship.bmp diff --git a/SDL2-2.0.12/Xcode-iOS/Demos/data/space.bmp b/SDL2-2.30.5/Xcode-iOS/Demos/data/space.bmp similarity index 100% rename from SDL2-2.0.12/Xcode-iOS/Demos/data/space.bmp rename to SDL2-2.30.5/Xcode-iOS/Demos/data/space.bmp diff --git a/SDL2-2.0.12/Xcode-iOS/Demos/data/stroke.bmp b/SDL2-2.30.5/Xcode-iOS/Demos/data/stroke.bmp similarity index 100% rename from SDL2-2.0.12/Xcode-iOS/Demos/data/stroke.bmp rename to SDL2-2.30.5/Xcode-iOS/Demos/data/stroke.bmp diff --git a/SDL2-2.0.12/Xcode-iOS/Demos/iOS Launch Screen.storyboard b/SDL2-2.30.5/Xcode-iOS/Demos/iOS Launch Screen.storyboard similarity index 100% rename from SDL2-2.0.12/Xcode-iOS/Demos/iOS Launch Screen.storyboard rename to SDL2-2.30.5/Xcode-iOS/Demos/iOS Launch Screen.storyboard diff --git a/SDL2-2.0.12/Xcode-iOS/Demos/src/accelerometer.c b/SDL2-2.30.5/Xcode-iOS/Demos/src/accelerometer.c similarity index 96% rename from SDL2-2.0.12/Xcode-iOS/Demos/src/accelerometer.c rename to SDL2-2.30.5/Xcode-iOS/Demos/src/accelerometer.c index 2cc0123..4c166a6 100644 --- a/SDL2-2.0.12/Xcode-iOS/Demos/src/accelerometer.c +++ b/SDL2-2.30.5/Xcode-iOS/Demos/src/accelerometer.c @@ -58,7 +58,7 @@ render(SDL_Renderer *renderer, int w, int h, double deltaTime) ay * SDL_IPHONE_MAX_GFORCE / SINT16_MAX * GRAVITY_CONSTANT * deltaMilliseconds; - speed = sqrt(shipData.vx * shipData.vx + shipData.vy * shipData.vy); + speed = SDL_sqrt(shipData.vx * shipData.vx + shipData.vy * shipData.vy); if (speed > 0) { /* compensate for friction */ @@ -118,7 +118,7 @@ initializeTextures(SDL_Renderer *renderer) /* load the ship */ bmp_surface = SDL_LoadBMP("ship.bmp"); - if (bmp_surface == NULL) { + if (!bmp_surface) { fatalError("could not ship.bmp"); } /* set blue to transparent on the ship */ @@ -127,7 +127,7 @@ initializeTextures(SDL_Renderer *renderer) /* create ship texture from surface */ ship = SDL_CreateTextureFromSurface(renderer, bmp_surface); - if (ship == 0) { + if (!ship) { fatalError("could not create ship texture"); } SDL_SetTextureBlendMode(ship, SDL_BLENDMODE_BLEND); @@ -140,12 +140,12 @@ initializeTextures(SDL_Renderer *renderer) /* load the space background */ bmp_surface = SDL_LoadBMP("space.bmp"); - if (bmp_surface == NULL) { + if (!bmp_surface) { fatalError("could not load space.bmp"); } /* create space texture from surface */ space = SDL_CreateTextureFromSurface(renderer, bmp_surface); - if (space == 0) { + if (!space) { fatalError("could not create space texture"); } SDL_FreeSurface(bmp_surface); @@ -179,7 +179,7 @@ main(int argc, char *argv[]) printf("There are %d joysticks available\n", SDL_NumJoysticks()); printf("Default joystick (index 0) is %s\n", SDL_JoystickName(0)); accelerometer = SDL_JoystickOpen(0); - if (accelerometer == NULL) { + if (!accelerometer) { fatalError("Could not open joystick (accelerometer)"); } printf("joystick number of axis = %d\n", diff --git a/SDL2-2.0.12/Xcode-iOS/Demos/src/common.c b/SDL2-2.30.5/Xcode-iOS/Demos/src/common.c similarity index 100% rename from SDL2-2.0.12/Xcode-iOS/Demos/src/common.c rename to SDL2-2.30.5/Xcode-iOS/Demos/src/common.c diff --git a/SDL2-2.0.12/Xcode-iOS/Demos/src/common.h b/SDL2-2.30.5/Xcode-iOS/Demos/src/common.h similarity index 100% rename from SDL2-2.0.12/Xcode-iOS/Demos/src/common.h rename to SDL2-2.30.5/Xcode-iOS/Demos/src/common.h diff --git a/SDL2-2.0.12/Xcode-iOS/Demos/src/fireworks.c b/SDL2-2.30.5/Xcode-iOS/Demos/src/fireworks.c similarity index 94% rename from SDL2-2.0.12/Xcode-iOS/Demos/src/fireworks.c rename to SDL2-2.30.5/Xcode-iOS/Demos/src/fireworks.c index 2c4f621..a9af3fb 100644 --- a/SDL2-2.0.12/Xcode-iOS/Demos/src/fireworks.c +++ b/SDL2-2.30.5/Xcode-iOS/Demos/src/fireworks.c @@ -84,14 +84,16 @@ stepParticles(double deltaTime) /* is the particle actually active, or is it marked for deletion? */ if (curr->isActive) { /* is the particle off the screen? */ - if (curr->y > screen_h) + if (curr->y > screen_h) { curr->isActive = 0; - else if (curr->y < 0) + } else if (curr->y < 0) { curr->isActive = 0; - if (curr->x > screen_w) + } + if (curr->x > screen_w) { curr->isActive = 0; - else if (curr->x < 0) + } else if (curr->x < 0) { curr->isActive = 0; + } /* step velocity, then step position */ curr->yvel += ACCEL * deltaMilliseconds; @@ -109,7 +111,7 @@ stepParticles(double deltaTime) } } else { float speed = - sqrt(curr->xvel * curr->xvel + curr->yvel * curr->yvel); + SDL_sqrt(curr->xvel * curr->xvel + curr->yvel * curr->yvel); /* if wind resistance is not powerful enough to stop us completely, then apply winde resistance, otherwise just stop us completely */ if (WIND_RESISTANCE * deltaMilliseconds < speed) { @@ -133,15 +135,17 @@ stepParticles(double deltaTime) } /* if we're a dust particle, shrink our size */ - if (curr->type == dust) + if (curr->type == dust) { curr->size -= deltaMilliseconds * 0.010f; + } } /* if we're still active, pack ourselves in the array next to the last active guy (pack the array tightly) */ - if (curr->isActive) + if (curr->isActive) { *(slot++) = *curr; + } } /* endif (curr->isActive) */ curr++; } @@ -188,21 +192,22 @@ explodeEmitter(struct particle *emitter) int i; for (i = 0; i < 200; i++) { - if (num_active_particles >= MAX_PARTICLES) + if (num_active_particles >= MAX_PARTICLES) { return; + } /* come up with a random angle and speed for new particle */ float theta = randomFloat(0, 2.0f * 3.141592); float exponent = 3.0f; - float speed = randomFloat(0.00, powf(0.17, exponent)); - speed = powf(speed, 1.0f / exponent); + float speed = randomFloat(0.00, SDL_powf(0.17, exponent)); + speed = SDL_powf(speed, 1.0f / exponent); /* select the particle at the end of our array */ struct particle *p = &particles[num_active_particles]; /* set the particles properties */ - p->xvel = speed * cos(theta); - p->yvel = speed * sin(theta); + p->xvel = speed * SDL_cos(theta); + p->yvel = speed * SDL_sin(theta); p->x = emitter->x + emitter->xvel; p->y = emitter->y + emitter->yvel; p->isActive = 1; @@ -226,8 +231,9 @@ void spawnTrailFromEmitter(struct particle *emitter) { - if (num_active_particles >= MAX_PARTICLES) + if (num_active_particles >= MAX_PARTICLES) { return; + } /* select the particle at the slot at the end of our array */ struct particle *p = &particles[num_active_particles]; @@ -262,8 +268,9 @@ void spawnEmitterParticle(GLfloat x, GLfloat y) { - if (num_active_particles >= MAX_PARTICLES) + if (num_active_particles >= MAX_PARTICLES) { return; + } /* find particle at endpoint of array */ struct particle *p = &particles[num_active_particles]; @@ -297,7 +304,7 @@ spawnEmitterParticle(GLfloat x, GLfloat y) p->y = screen_h; /* set velocity so that terminal point is (x,y) */ p->xvel = 0; - p->yvel = -sqrt(2 * ACCEL * (screen_h - y)); + p->yvel = -SDL_sqrt(2 * ACCEL * (screen_h - y)); /* set other attributes */ p->size = 10 * pointSizeScale; p->type = emitter; @@ -327,7 +334,7 @@ initializeTexture() to format passed into OpenGL */ bmp_surface = SDL_LoadBMP("stroke.bmp"); - if (bmp_surface == NULL) { + if (!bmp_surface) { fatalError("could not load stroke.bmp"); } diff --git a/SDL2-2.0.12/Xcode-iOS/Demos/src/happy.c b/SDL2-2.30.5/Xcode-iOS/Demos/src/happy.c similarity index 98% rename from SDL2-2.0.12/Xcode-iOS/Demos/src/happy.c rename to SDL2-2.30.5/Xcode-iOS/Demos/src/happy.c index 658a65f..163d346 100644 --- a/SDL2-2.0.12/Xcode-iOS/Demos/src/happy.c +++ b/SDL2-2.30.5/Xcode-iOS/Demos/src/happy.c @@ -108,7 +108,7 @@ initializeTexture(SDL_Renderer *renderer) SDL_Surface *bmp_surface; /* load the bmp */ bmp_surface = SDL_LoadBMP("icon.bmp"); - if (bmp_surface == NULL) { + if (!bmp_surface) { fatalError("could not load bmp"); } /* set white to transparent on the happyface */ @@ -117,7 +117,7 @@ initializeTexture(SDL_Renderer *renderer) /* convert RGBA surface to texture */ texture = SDL_CreateTextureFromSurface(renderer, bmp_surface); - if (texture == 0) { + if (!texture) { fatalError("could not create texture"); } SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); diff --git a/SDL2-2.0.12/Xcode-iOS/Demos/src/keyboard.c b/SDL2-2.30.5/Xcode-iOS/Demos/src/keyboard.c similarity index 99% rename from SDL2-2.0.12/Xcode-iOS/Demos/src/keyboard.c rename to SDL2-2.30.5/Xcode-iOS/Demos/src/keyboard.c index cfbe4e6..4d630ba 100644 --- a/SDL2-2.0.12/Xcode-iOS/Demos/src/keyboard.c +++ b/SDL2-2.30.5/Xcode-iOS/Demos/src/keyboard.c @@ -183,7 +183,7 @@ loadFont(void) SDL_BlitSurface(surface, NULL, converted, NULL); /* create our texture */ texture = SDL_CreateTextureFromSurface(renderer, converted); - if (texture == 0) { + if (!texture) { printf("texture creation failed: %s\n", SDL_GetError()); } else { /* set blend mode for our texture */ diff --git a/SDL2-2.0.12/Xcode-iOS/Demos/src/mixer.c b/SDL2-2.30.5/Xcode-iOS/Demos/src/mixer.c similarity index 98% rename from SDL2-2.0.12/Xcode-iOS/Demos/src/mixer.c rename to SDL2-2.30.5/Xcode-iOS/Demos/src/mixer.c index 14945ad..4c4ffba 100644 --- a/SDL2-2.0.12/Xcode-iOS/Demos/src/mixer.c +++ b/SDL2-2.30.5/Xcode-iOS/Demos/src/mixer.c @@ -111,7 +111,7 @@ loadSound(const char *file, struct sound *s) if (SDL_ConvertAudio(&cvt) == -1) { /* convert the sound */ fatalError("could not convert .wav"); } - SDL_free(s->buffer); /* free the original (unconverted) buffer */ + SDL_free(s->buffer); /* Free the original (unconverted) buffer */ s->buffer = cvt.buf; /* point sound buffer to converted buffer */ s->length = cvt.len_cvt; /* set sound buffer's new length */ } @@ -207,9 +207,9 @@ playSound(struct sound *s) break; } /* if this channel's sound is older than the oldest so far, set it to oldest */ - if (mixer.channels[i].timestamp < - mixer.channels[oldest_channel].timestamp) + if (mixer.channels[i].timestamp < mixer.channels[oldest_channel].timestamp) { oldest_channel = i; + } } /* no empty channels, take the oldest one */ diff --git a/SDL2-2.0.12/Xcode-iOS/Demos/src/rectangles.c b/SDL2-2.30.5/Xcode-iOS/Demos/src/rectangles.c similarity index 98% rename from SDL2-2.0.12/Xcode-iOS/Demos/src/rectangles.c rename to SDL2-2.30.5/Xcode-iOS/Demos/src/rectangles.c index 10f9f85..a08f997 100644 --- a/SDL2-2.0.12/Xcode-iOS/Demos/src/rectangles.c +++ b/SDL2-2.30.5/Xcode-iOS/Demos/src/rectangles.c @@ -58,7 +58,7 @@ main(int argc, char *argv[]) /* create window and renderer */ window = SDL_CreateWindow(NULL, 0, 0, 320, 480, SDL_WINDOW_ALLOW_HIGHDPI); - if (window == 0) { + if (!window) { fatalError("Could not initialize Window"); } renderer = SDL_CreateRenderer(window, -1, 0); diff --git a/SDL2-2.0.12/Xcode-iOS/Demos/src/touch.c b/SDL2-2.30.5/Xcode-iOS/Demos/src/touch.c similarity index 72% rename from SDL2-2.0.12/Xcode-iOS/Demos/src/touch.c rename to SDL2-2.30.5/Xcode-iOS/Demos/src/touch.c index 470b9d1..4b7ff95 100644 --- a/SDL2-2.0.12/Xcode-iOS/Demos/src/touch.c +++ b/SDL2-2.30.5/Xcode-iOS/Demos/src/touch.c @@ -21,7 +21,7 @@ void drawLine(SDL_Renderer *renderer, float startx, float starty, float dx, float dy) { - float distance = sqrt(dx * dx + dy * dy); /* length of line segment (pythagoras) */ + float distance = SDL_sqrt(dx * dx + dy * dy); /* length of line segment (pythagoras) */ int iterations = distance / PIXELS_PER_ITERATION + 1; /* number of brush sprites to draw for the line */ float dx_prime = dx / iterations; /* x-shift per iteration */ float dy_prime = dy / iterations; /* y-shift per iteration */ @@ -57,13 +57,13 @@ initializeTexture(SDL_Renderer *renderer) { SDL_Surface *bmp_surface; bmp_surface = SDL_LoadBMP("stroke.bmp"); - if (bmp_surface == NULL) { + if (!bmp_surface) { fatalError("could not load stroke.bmp"); } brush = SDL_CreateTextureFromSurface(renderer, bmp_surface); SDL_FreeSurface(bmp_surface); - if (brush == 0) { + if (!brush) { fatalError("could not create brush texture"); } /* additive blending -- laying strokes on top of eachother makes them brighter */ @@ -81,6 +81,7 @@ main(int argc, char *argv[]) SDL_Event event; SDL_Window *window; /* main window */ SDL_Renderer *renderer; + SDL_Texture *target; int done; /* does user want to quit? */ int w, h; @@ -100,29 +101,38 @@ main(int argc, char *argv[]) initializeTexture(renderer); /* fill canvass initially with all black */ + target = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, w, h); + SDL_SetRenderTarget(renderer, target); SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); SDL_RenderClear(renderer); - SDL_RenderPresent(renderer); + SDL_SetRenderTarget(renderer, NULL); done = 0; - while (!done && SDL_WaitEvent(&event)) { - switch (event.type) { - case SDL_QUIT: - done = 1; - break; - case SDL_MOUSEMOTION: - state = SDL_GetMouseState(&x, &y); /* get its location */ - SDL_GetRelativeMouseState(&dx, &dy); /* find how much the mouse moved */ - if (state & SDL_BUTTON_LMASK) { /* is the mouse (touch) down? */ - drawLine(renderer, x - dx, y - dy, dx, dy); /* draw line segment */ - SDL_RenderPresent(renderer); + while (!done) { + while (SDL_PollEvent(&event) == 1) { + switch (event.type) { + case SDL_QUIT: + done = 1; + break; + case SDL_MOUSEMOTION: + state = SDL_GetMouseState(&x, &y); /* get its location */ + SDL_GetRelativeMouseState(&dx, &dy); /* find how much the mouse moved */ + if (state & SDL_BUTTON_LMASK) { /* is the mouse (touch) down? */ + SDL_SetRenderTarget(renderer, target); + drawLine(renderer, x - dx, y - dy, dx, dy); /* draw line segment */ + SDL_SetRenderTarget(renderer, NULL); + } + break; } - break; } + + SDL_RenderCopy(renderer, target, NULL, NULL); + SDL_RenderPresent(renderer); } /* cleanup */ SDL_DestroyTexture(brush); + SDL_DestroyTexture(target); SDL_Quit(); return 0; diff --git a/SDL2-2.0.12/Xcode/SDL/Info-Framework.plist b/SDL2-2.30.5/Xcode/SDL/Info-Framework.plist similarity index 94% rename from SDL2-2.0.12/Xcode/SDL/Info-Framework.plist rename to SDL2-2.30.5/Xcode/SDL/Info-Framework.plist index 9828759..87d07ae 100644 --- a/SDL2-2.0.12/Xcode/SDL/Info-Framework.plist +++ b/SDL2-2.30.5/Xcode/SDL/Info-Framework.plist @@ -19,10 +19,10 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.0.12 + 2.30.5 CFBundleSignature SDLX CFBundleVersion - 2.0.12 + 2.30.5 diff --git a/SDL2-2.0.12/Xcode/SDL/SDL.xcodeproj/project.pbxproj b/SDL2-2.30.5/Xcode/SDL/SDL.xcodeproj/project.pbxproj similarity index 83% rename from SDL2-2.0.12/Xcode/SDL/SDL.xcodeproj/project.pbxproj rename to SDL2-2.30.5/Xcode/SDL/SDL.xcodeproj/project.pbxproj index 5fe7fb2..82bf8b5 100644 --- a/SDL2-2.0.12/Xcode/SDL/SDL.xcodeproj/project.pbxproj +++ b/SDL2-2.30.5/Xcode/SDL/SDL.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ @@ -12,15 +12,132 @@ 00CFA89D106B4BA100758660 /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00CFA89C106B4BA100758660 /* ForceFeedback.framework */; }; 00D0D08410675DD9004B05EF /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00D0D08310675DD9004B05EF /* CoreFoundation.framework */; }; 00D0D0D810675E46004B05EF /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 007317C10858E15000B2BC32 /* Carbon.framework */; }; + 552673EB2546054600085751 /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDABD23E28B6200529352 /* GameController.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + 552673EC2546055000085751 /* CoreHaptics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F37DC5F225350EBC0002E6F7 /* CoreHaptics.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + 557D0CFA254586CA003913E3 /* CoreHaptics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F37DC5F225350EBC0002E6F7 /* CoreHaptics.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + 557D0CFB254586D7003913E3 /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDABD23E28B6200529352 /* GameController.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + 560572062473687700B46B66 /* SDL_syslocale.m in Sources */ = {isa = PBXBuildFile; fileRef = 566E26CC246274CB00718109 /* SDL_syslocale.m */; }; + 560572072473687800B46B66 /* SDL_syslocale.m in Sources */ = {isa = PBXBuildFile; fileRef = 566E26CC246274CB00718109 /* SDL_syslocale.m */; }; + 560572092473687900B46B66 /* SDL_syslocale.m in Sources */ = {isa = PBXBuildFile; fileRef = 566E26CC246274CB00718109 /* SDL_syslocale.m */; }; + 5605720A2473687900B46B66 /* SDL_syslocale.m in Sources */ = {isa = PBXBuildFile; fileRef = 566E26CC246274CB00718109 /* SDL_syslocale.m */; }; + 5605720B2473687A00B46B66 /* SDL_syslocale.m in Sources */ = {isa = PBXBuildFile; fileRef = 566E26CC246274CB00718109 /* SDL_syslocale.m */; }; + 5605720C2473687B00B46B66 /* SDL_syslocale.m in Sources */ = {isa = PBXBuildFile; fileRef = 566E26CC246274CB00718109 /* SDL_syslocale.m */; }; + 5605720D2473687B00B46B66 /* SDL_syslocale.m in Sources */ = {isa = PBXBuildFile; fileRef = 566E26CC246274CB00718109 /* SDL_syslocale.m */; }; + 5605720E2473687C00B46B66 /* SDL_syslocale.m in Sources */ = {isa = PBXBuildFile; fileRef = 566E26CC246274CB00718109 /* SDL_syslocale.m */; }; + 5605720F2473688000B46B66 /* SDL_locale.c in Sources */ = {isa = PBXBuildFile; fileRef = 566E26CD246274CB00718109 /* SDL_locale.c */; }; + 560572102473688000B46B66 /* SDL_locale.c in Sources */ = {isa = PBXBuildFile; fileRef = 566E26CD246274CB00718109 /* SDL_locale.c */; }; + 560572112473688100B46B66 /* SDL_locale.c in Sources */ = {isa = PBXBuildFile; fileRef = 566E26CD246274CB00718109 /* SDL_locale.c */; }; + 560572122473688200B46B66 /* SDL_locale.c in Sources */ = {isa = PBXBuildFile; fileRef = 566E26CD246274CB00718109 /* SDL_locale.c */; }; + 560572132473688200B46B66 /* SDL_locale.c in Sources */ = {isa = PBXBuildFile; fileRef = 566E26CD246274CB00718109 /* SDL_locale.c */; }; + 560572142473688300B46B66 /* SDL_locale.c in Sources */ = {isa = PBXBuildFile; fileRef = 566E26CD246274CB00718109 /* SDL_locale.c */; }; + 560572152473688300B46B66 /* SDL_locale.c in Sources */ = {isa = PBXBuildFile; fileRef = 566E26CD246274CB00718109 /* SDL_locale.c */; }; + 560572162473688400B46B66 /* SDL_locale.c in Sources */ = {isa = PBXBuildFile; fileRef = 566E26CD246274CB00718109 /* SDL_locale.c */; }; + 560572172473688A00B46B66 /* SDL_syslocale.h in Headers */ = {isa = PBXBuildFile; fileRef = 566E26CE246274CC00718109 /* SDL_syslocale.h */; }; + 560572182473688B00B46B66 /* SDL_syslocale.h in Headers */ = {isa = PBXBuildFile; fileRef = 566E26CE246274CC00718109 /* SDL_syslocale.h */; }; + 560572192473688C00B46B66 /* SDL_syslocale.h in Headers */ = {isa = PBXBuildFile; fileRef = 566E26CE246274CC00718109 /* SDL_syslocale.h */; }; + 5605721A2473688C00B46B66 /* SDL_syslocale.h in Headers */ = {isa = PBXBuildFile; fileRef = 566E26CE246274CC00718109 /* SDL_syslocale.h */; }; + 5605721B2473688D00B46B66 /* SDL_syslocale.h in Headers */ = {isa = PBXBuildFile; fileRef = 566E26CE246274CC00718109 /* SDL_syslocale.h */; }; + 5605721C2473688D00B46B66 /* SDL_syslocale.h in Headers */ = {isa = PBXBuildFile; fileRef = 566E26CE246274CC00718109 /* SDL_syslocale.h */; }; + 5605721D2473688E00B46B66 /* SDL_syslocale.h in Headers */ = {isa = PBXBuildFile; fileRef = 566E26CE246274CC00718109 /* SDL_syslocale.h */; }; + 5605721E2473688F00B46B66 /* SDL_syslocale.h in Headers */ = {isa = PBXBuildFile; fileRef = 566E26CE246274CC00718109 /* SDL_syslocale.h */; }; + 5616CA4C252BB2A6005D5928 /* SDL_url.c in Sources */ = {isa = PBXBuildFile; fileRef = 5616CA49252BB2A5005D5928 /* SDL_url.c */; }; + 5616CA4D252BB2A6005D5928 /* SDL_sysurl.h in Headers */ = {isa = PBXBuildFile; fileRef = 5616CA4A252BB2A6005D5928 /* SDL_sysurl.h */; }; + 5616CA4E252BB2A6005D5928 /* SDL_sysurl.m in Sources */ = {isa = PBXBuildFile; fileRef = 5616CA4B252BB2A6005D5928 /* SDL_sysurl.m */; }; + 5616CA50252BB2BE005D5928 /* SDL_misc.h in Headers */ = {isa = PBXBuildFile; fileRef = 5616CA4F252BB2BE005D5928 /* SDL_misc.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5616CA51252BB35A005D5928 /* SDL_sysurl.h in Headers */ = {isa = PBXBuildFile; fileRef = 5616CA4A252BB2A6005D5928 /* SDL_sysurl.h */; }; + 5616CA52252BB35A005D5928 /* SDL_url.c in Sources */ = {isa = PBXBuildFile; fileRef = 5616CA49252BB2A5005D5928 /* SDL_url.c */; }; + 5616CA54252BB35B005D5928 /* SDL_sysurl.h in Headers */ = {isa = PBXBuildFile; fileRef = 5616CA4A252BB2A6005D5928 /* SDL_sysurl.h */; }; + 5616CA55252BB35B005D5928 /* SDL_url.c in Sources */ = {isa = PBXBuildFile; fileRef = 5616CA49252BB2A5005D5928 /* SDL_url.c */; }; + 5616CA57252BB35C005D5928 /* SDL_sysurl.h in Headers */ = {isa = PBXBuildFile; fileRef = 5616CA4A252BB2A6005D5928 /* SDL_sysurl.h */; }; + 5616CA58252BB35C005D5928 /* SDL_url.c in Sources */ = {isa = PBXBuildFile; fileRef = 5616CA49252BB2A5005D5928 /* SDL_url.c */; }; + 5616CA59252BB35C005D5928 /* SDL_sysurl.m in Sources */ = {isa = PBXBuildFile; fileRef = 5616CA4B252BB2A6005D5928 /* SDL_sysurl.m */; }; + 5616CA5A252BB35D005D5928 /* SDL_sysurl.h in Headers */ = {isa = PBXBuildFile; fileRef = 5616CA4A252BB2A6005D5928 /* SDL_sysurl.h */; }; + 5616CA5B252BB35D005D5928 /* SDL_url.c in Sources */ = {isa = PBXBuildFile; fileRef = 5616CA49252BB2A5005D5928 /* SDL_url.c */; }; + 5616CA5D252BB35E005D5928 /* SDL_sysurl.h in Headers */ = {isa = PBXBuildFile; fileRef = 5616CA4A252BB2A6005D5928 /* SDL_sysurl.h */; }; + 5616CA5E252BB35E005D5928 /* SDL_url.c in Sources */ = {isa = PBXBuildFile; fileRef = 5616CA49252BB2A5005D5928 /* SDL_url.c */; }; + 5616CA60252BB35E005D5928 /* SDL_sysurl.h in Headers */ = {isa = PBXBuildFile; fileRef = 5616CA4A252BB2A6005D5928 /* SDL_sysurl.h */; }; + 5616CA61252BB35E005D5928 /* SDL_url.c in Sources */ = {isa = PBXBuildFile; fileRef = 5616CA49252BB2A5005D5928 /* SDL_url.c */; }; + 5616CA62252BB35E005D5928 /* SDL_sysurl.m in Sources */ = {isa = PBXBuildFile; fileRef = 5616CA4B252BB2A6005D5928 /* SDL_sysurl.m */; }; + 5616CA63252BB35F005D5928 /* SDL_sysurl.h in Headers */ = {isa = PBXBuildFile; fileRef = 5616CA4A252BB2A6005D5928 /* SDL_sysurl.h */; }; + 5616CA64252BB35F005D5928 /* SDL_url.c in Sources */ = {isa = PBXBuildFile; fileRef = 5616CA49252BB2A5005D5928 /* SDL_url.c */; }; + 5616CA66252BB361005D5928 /* SDL_sysurl.h in Headers */ = {isa = PBXBuildFile; fileRef = 5616CA4A252BB2A6005D5928 /* SDL_sysurl.h */; }; + 5616CA67252BB361005D5928 /* SDL_url.c in Sources */ = {isa = PBXBuildFile; fileRef = 5616CA49252BB2A5005D5928 /* SDL_url.c */; }; 562C4AEA1D8F496300AF9EBE /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7381E931D8B69C300B177DD /* AudioToolbox.framework */; }; 564624361FF821C20074AC87 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 564624351FF821B80074AC87 /* QuartzCore.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; 564624381FF821DA0074AC87 /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 564624371FF821CB0074AC87 /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; 5646243B1FF822100074AC87 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 564624351FF821B80074AC87 /* QuartzCore.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; 5646243C1FF822170074AC87 /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 564624371FF821CB0074AC87 /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + 566E267A2462701100718109 /* SDL_locale.h in Headers */ = {isa = PBXBuildFile; fileRef = 566E26792462701100718109 /* SDL_locale.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 566E26CF246274CC00718109 /* SDL_syslocale.m in Sources */ = {isa = PBXBuildFile; fileRef = 566E26CC246274CB00718109 /* SDL_syslocale.m */; }; + 566E26D8246274CC00718109 /* SDL_locale.c in Sources */ = {isa = PBXBuildFile; fileRef = 566E26CD246274CB00718109 /* SDL_locale.c */; }; + 566E26E1246274CC00718109 /* SDL_syslocale.h in Headers */ = {isa = PBXBuildFile; fileRef = 566E26CE246274CC00718109 /* SDL_syslocale.h */; }; 567E2F2117C44C35005F1892 /* SDL_filesystem.h in Headers */ = {isa = PBXBuildFile; fileRef = 567E2F2017C44C35005F1892 /* SDL_filesystem.h */; settings = {ATTRIBUTES = (Public, ); }; }; 56C5237F1D8F4985001F2F30 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7381E951D8B69D600B177DD /* CoreAudio.framework */; }; 56C523811D8F498C001F2F30 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00D0D08310675DD9004B05EF /* CoreFoundation.framework */; }; 5C2EF7011FC9EF10003F5197 /* SDL_egl.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C2EF7001FC9EF0F003F5197 /* SDL_egl.h */; }; + 75E0915A241EA924004729E1 /* SDL_virtualjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = 75E09158241EA924004729E1 /* SDL_virtualjoystick.c */; }; + 75E0915B241EA924004729E1 /* SDL_virtualjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = 75E09158241EA924004729E1 /* SDL_virtualjoystick.c */; }; + 75E0915C241EA924004729E1 /* SDL_virtualjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = 75E09158241EA924004729E1 /* SDL_virtualjoystick.c */; }; + 75E0915D241EA924004729E1 /* SDL_virtualjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = 75E09158241EA924004729E1 /* SDL_virtualjoystick.c */; }; + 75E0915E241EA924004729E1 /* SDL_virtualjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = 75E09158241EA924004729E1 /* SDL_virtualjoystick.c */; }; + 75E0915F241EA924004729E1 /* SDL_virtualjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = 75E09158241EA924004729E1 /* SDL_virtualjoystick.c */; }; + 75E09160241EA924004729E1 /* SDL_virtualjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = 75E09158241EA924004729E1 /* SDL_virtualjoystick.c */; }; + 75E09161241EA924004729E1 /* SDL_virtualjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = 75E09158241EA924004729E1 /* SDL_virtualjoystick.c */; }; + 75E09162241EA924004729E1 /* SDL_virtualjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = 75E09158241EA924004729E1 /* SDL_virtualjoystick.c */; }; + 75E09163241EA924004729E1 /* SDL_virtualjoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 75E09159241EA924004729E1 /* SDL_virtualjoystick_c.h */; }; + 75E09164241EA924004729E1 /* SDL_virtualjoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 75E09159241EA924004729E1 /* SDL_virtualjoystick_c.h */; }; + 75E09165241EA924004729E1 /* SDL_virtualjoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 75E09159241EA924004729E1 /* SDL_virtualjoystick_c.h */; }; + 75E09166241EA924004729E1 /* SDL_virtualjoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 75E09159241EA924004729E1 /* SDL_virtualjoystick_c.h */; }; + 75E09167241EA924004729E1 /* SDL_virtualjoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 75E09159241EA924004729E1 /* SDL_virtualjoystick_c.h */; }; + 75E09168241EA924004729E1 /* SDL_virtualjoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 75E09159241EA924004729E1 /* SDL_virtualjoystick_c.h */; }; + 75E09169241EA924004729E1 /* SDL_virtualjoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 75E09159241EA924004729E1 /* SDL_virtualjoystick_c.h */; }; + 75E0916A241EA924004729E1 /* SDL_virtualjoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 75E09159241EA924004729E1 /* SDL_virtualjoystick_c.h */; }; + 75E0916B241EA924004729E1 /* SDL_virtualjoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 75E09159241EA924004729E1 /* SDL_virtualjoystick_c.h */; }; + 9846B07C287A9020000C35C8 /* SDL_hidapi_shield.c in Sources */ = {isa = PBXBuildFile; fileRef = 9846B07B287A9020000C35C8 /* SDL_hidapi_shield.c */; }; + 9846B07D287A9020000C35C8 /* SDL_hidapi_shield.c in Sources */ = {isa = PBXBuildFile; fileRef = 9846B07B287A9020000C35C8 /* SDL_hidapi_shield.c */; }; + 9846B07E287A9020000C35C8 /* SDL_hidapi_shield.c in Sources */ = {isa = PBXBuildFile; fileRef = 9846B07B287A9020000C35C8 /* SDL_hidapi_shield.c */; }; + 9846B07F287A9020000C35C8 /* SDL_hidapi_shield.c in Sources */ = {isa = PBXBuildFile; fileRef = 9846B07B287A9020000C35C8 /* SDL_hidapi_shield.c */; }; + 9846B080287A9020000C35C8 /* SDL_hidapi_shield.c in Sources */ = {isa = PBXBuildFile; fileRef = 9846B07B287A9020000C35C8 /* SDL_hidapi_shield.c */; }; + 9846B081287A9020000C35C8 /* SDL_hidapi_shield.c in Sources */ = {isa = PBXBuildFile; fileRef = 9846B07B287A9020000C35C8 /* SDL_hidapi_shield.c */; }; + 9846B082287A9020000C35C8 /* SDL_hidapi_shield.c in Sources */ = {isa = PBXBuildFile; fileRef = 9846B07B287A9020000C35C8 /* SDL_hidapi_shield.c */; }; + 9846B083287A9020000C35C8 /* SDL_hidapi_shield.c in Sources */ = {isa = PBXBuildFile; fileRef = 9846B07B287A9020000C35C8 /* SDL_hidapi_shield.c */; }; + 9846B084287A9020000C35C8 /* SDL_hidapi_shield.c in Sources */ = {isa = PBXBuildFile; fileRef = 9846B07B287A9020000C35C8 /* SDL_hidapi_shield.c */; }; + A1626A3E2617006A003F1973 /* SDL_triangle.c in Sources */ = {isa = PBXBuildFile; fileRef = A1626A3D2617006A003F1973 /* SDL_triangle.c */; }; + A1626A3F2617006A003F1973 /* SDL_triangle.c in Sources */ = {isa = PBXBuildFile; fileRef = A1626A3D2617006A003F1973 /* SDL_triangle.c */; }; + A1626A402617006A003F1973 /* SDL_triangle.c in Sources */ = {isa = PBXBuildFile; fileRef = A1626A3D2617006A003F1973 /* SDL_triangle.c */; }; + A1626A412617006A003F1973 /* SDL_triangle.c in Sources */ = {isa = PBXBuildFile; fileRef = A1626A3D2617006A003F1973 /* SDL_triangle.c */; }; + A1626A422617006A003F1973 /* SDL_triangle.c in Sources */ = {isa = PBXBuildFile; fileRef = A1626A3D2617006A003F1973 /* SDL_triangle.c */; }; + A1626A432617006A003F1973 /* SDL_triangle.c in Sources */ = {isa = PBXBuildFile; fileRef = A1626A3D2617006A003F1973 /* SDL_triangle.c */; }; + A1626A442617006A003F1973 /* SDL_triangle.c in Sources */ = {isa = PBXBuildFile; fileRef = A1626A3D2617006A003F1973 /* SDL_triangle.c */; }; + A1626A452617006A003F1973 /* SDL_triangle.c in Sources */ = {isa = PBXBuildFile; fileRef = A1626A3D2617006A003F1973 /* SDL_triangle.c */; }; + A1626A462617006A003F1973 /* SDL_triangle.c in Sources */ = {isa = PBXBuildFile; fileRef = A1626A3D2617006A003F1973 /* SDL_triangle.c */; }; + A1626A522617008D003F1973 /* SDL_triangle.h in Headers */ = {isa = PBXBuildFile; fileRef = A1626A512617008C003F1973 /* SDL_triangle.h */; }; + A1626A532617008D003F1973 /* SDL_triangle.h in Headers */ = {isa = PBXBuildFile; fileRef = A1626A512617008C003F1973 /* SDL_triangle.h */; }; + A1626A542617008D003F1973 /* SDL_triangle.h in Headers */ = {isa = PBXBuildFile; fileRef = A1626A512617008C003F1973 /* SDL_triangle.h */; }; + A1626A552617008D003F1973 /* SDL_triangle.h in Headers */ = {isa = PBXBuildFile; fileRef = A1626A512617008C003F1973 /* SDL_triangle.h */; }; + A1626A562617008D003F1973 /* SDL_triangle.h in Headers */ = {isa = PBXBuildFile; fileRef = A1626A512617008C003F1973 /* SDL_triangle.h */; }; + A1626A572617008D003F1973 /* SDL_triangle.h in Headers */ = {isa = PBXBuildFile; fileRef = A1626A512617008C003F1973 /* SDL_triangle.h */; }; + A1626A582617008D003F1973 /* SDL_triangle.h in Headers */ = {isa = PBXBuildFile; fileRef = A1626A512617008C003F1973 /* SDL_triangle.h */; }; + A1626A592617008D003F1973 /* SDL_triangle.h in Headers */ = {isa = PBXBuildFile; fileRef = A1626A512617008C003F1973 /* SDL_triangle.h */; }; + A1626A5A2617008D003F1973 /* SDL_triangle.h in Headers */ = {isa = PBXBuildFile; fileRef = A1626A512617008C003F1973 /* SDL_triangle.h */; }; + A1BB8B6327F6CF330057CFA8 /* SDL_list.c in Sources */ = {isa = PBXBuildFile; fileRef = A1BB8B6127F6CF320057CFA8 /* SDL_list.c */; }; + A1BB8B6427F6CF330057CFA8 /* SDL_list.c in Sources */ = {isa = PBXBuildFile; fileRef = A1BB8B6127F6CF320057CFA8 /* SDL_list.c */; }; + A1BB8B6527F6CF330057CFA8 /* SDL_list.c in Sources */ = {isa = PBXBuildFile; fileRef = A1BB8B6127F6CF320057CFA8 /* SDL_list.c */; }; + A1BB8B6627F6CF330057CFA8 /* SDL_list.c in Sources */ = {isa = PBXBuildFile; fileRef = A1BB8B6127F6CF320057CFA8 /* SDL_list.c */; }; + A1BB8B6727F6CF330057CFA8 /* SDL_list.c in Sources */ = {isa = PBXBuildFile; fileRef = A1BB8B6127F6CF320057CFA8 /* SDL_list.c */; }; + A1BB8B6827F6CF330057CFA8 /* SDL_list.c in Sources */ = {isa = PBXBuildFile; fileRef = A1BB8B6127F6CF320057CFA8 /* SDL_list.c */; }; + A1BB8B6927F6CF330057CFA8 /* SDL_list.c in Sources */ = {isa = PBXBuildFile; fileRef = A1BB8B6127F6CF320057CFA8 /* SDL_list.c */; }; + A1BB8B6A27F6CF330057CFA8 /* SDL_list.c in Sources */ = {isa = PBXBuildFile; fileRef = A1BB8B6127F6CF320057CFA8 /* SDL_list.c */; }; + A1BB8B6B27F6CF330057CFA8 /* SDL_list.c in Sources */ = {isa = PBXBuildFile; fileRef = A1BB8B6127F6CF320057CFA8 /* SDL_list.c */; }; + A1BB8B6C27F6CF330057CFA8 /* SDL_list.h in Headers */ = {isa = PBXBuildFile; fileRef = A1BB8B6227F6CF330057CFA8 /* SDL_list.h */; }; + A1BB8B6D27F6CF330057CFA8 /* SDL_list.h in Headers */ = {isa = PBXBuildFile; fileRef = A1BB8B6227F6CF330057CFA8 /* SDL_list.h */; }; + A1BB8B6E27F6CF330057CFA8 /* SDL_list.h in Headers */ = {isa = PBXBuildFile; fileRef = A1BB8B6227F6CF330057CFA8 /* SDL_list.h */; }; + A1BB8B6F27F6CF330057CFA8 /* SDL_list.h in Headers */ = {isa = PBXBuildFile; fileRef = A1BB8B6227F6CF330057CFA8 /* SDL_list.h */; }; + A1BB8B7027F6CF330057CFA8 /* SDL_list.h in Headers */ = {isa = PBXBuildFile; fileRef = A1BB8B6227F6CF330057CFA8 /* SDL_list.h */; }; + A1BB8B7127F6CF330057CFA8 /* SDL_list.h in Headers */ = {isa = PBXBuildFile; fileRef = A1BB8B6227F6CF330057CFA8 /* SDL_list.h */; }; + A1BB8B7227F6CF330057CFA8 /* SDL_list.h in Headers */ = {isa = PBXBuildFile; fileRef = A1BB8B6227F6CF330057CFA8 /* SDL_list.h */; }; + A1BB8B7327F6CF330057CFA8 /* SDL_list.h in Headers */ = {isa = PBXBuildFile; fileRef = A1BB8B6227F6CF330057CFA8 /* SDL_list.h */; }; + A1BB8B7427F6CF330057CFA8 /* SDL_list.h in Headers */ = {isa = PBXBuildFile; fileRef = A1BB8B6227F6CF330057CFA8 /* SDL_list.h */; }; A7381E961D8B69D600B177DD /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7381E951D8B69D600B177DD /* CoreAudio.framework */; }; A7381E971D8B6A0300B177DD /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7381E931D8B69C300B177DD /* AudioToolbox.framework */; }; A75FCCFD23E25AB700529352 /* SDL_shaders_metal_tvos.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8E323E2514000DCD162 /* SDL_shaders_metal_tvos.h */; }; @@ -35,7 +152,6 @@ A75FCD0723E25AB700529352 /* SDL_glfuncs.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90E23E2514000DCD162 /* SDL_glfuncs.h */; }; A75FCD0823E25AB700529352 /* SDL_atomic.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557CA1595D4D800BBD41B /* SDL_atomic.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCD0923E25AB700529352 /* SDL_rect_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60C23E2513D00DCD162 /* SDL_rect_c.h */; }; - A75FCD0A23E25AB700529352 /* SDL_x11xinput2.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71323E2513E00DCD162 /* SDL_x11xinput2.h */; }; A75FCD0B23E25AB700529352 /* SDL_shaders_metal_osx.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8E223E2514000DCD162 /* SDL_shaders_metal_osx.h */; }; A75FCD0C23E25AB700529352 /* SDL_shaders_metal_ios.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8DF23E2514000DCD162 /* SDL_shaders_metal_ios.h */; }; A75FCD0D23E25AB700529352 /* SDL_offscreenwindow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5F523E2513D00DCD162 /* SDL_offscreenwindow.h */; }; @@ -44,26 +160,21 @@ A75FCD1023E25AB700529352 /* SDL_uikitview.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A61923E2513D00DCD162 /* SDL_uikitview.h */; }; A75FCD1123E25AB700529352 /* SDL_bits.h in Headers */ = {isa = PBXBuildFile; fileRef = AADA5B8616CCAB3000107CF7 /* SDL_bits.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCD1223E25AB700529352 /* SDL_uikitappdelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62F23E2513D00DCD162 /* SDL_uikitappdelegate.h */; }; - A75FCD1323E25AB700529352 /* keyinfotable.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62823E2513D00DCD162 /* keyinfotable.h */; }; A75FCD1423E25AB700529352 /* SDL_blendmode.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557CC1595D4D800BBD41B /* SDL_blendmode.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCD1523E25AB700529352 /* SDL_dropevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A92E23E2514000DCD162 /* SDL_dropevents_c.h */; }; A75FCD1623E25AB700529352 /* SDL_haptic_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5C623E2513D00DCD162 /* SDL_haptic_c.h */; }; A75FCD1723E25AB700529352 /* SDL_clipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557CD1595D4D800BBD41B /* SDL_clipboard.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCD1823E25AB700529352 /* SDL_dataqueue.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57023E2513D00DCD162 /* SDL_dataqueue.h */; }; A75FCD1923E25AB700529352 /* SDL_error_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57523E2513D00DCD162 /* SDL_error_c.h */; }; - A75FCD1A23E25AB700529352 /* SDL_x11events.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71E23E2513E00DCD162 /* SDL_x11events.h */; }; A75FCD1B23E25AB700529352 /* SDL_config.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557CF1595D4D800BBD41B /* SDL_config.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCD1C23E25AB700529352 /* SDL_d3dmath.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8DC23E2514000DCD162 /* SDL_d3dmath.h */; }; - A75FCD1D23E25AB700529352 /* SDL_x11window.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71723E2513E00DCD162 /* SDL_x11window.h */; }; A75FCD1F23E25AB700529352 /* SDL_egl_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60423E2513D00DCD162 /* SDL_egl_c.h */; }; A75FCD2023E25AB700529352 /* SDL_copying.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D01595D4D800BBD41B /* SDL_copying.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCD2123E25AB700529352 /* yuv_rgb.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77223E2513E00DCD162 /* yuv_rgb.h */; }; A75FCD2223E25AB700529352 /* SDL_dummyaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A87123E2513F00DCD162 /* SDL_dummyaudio.h */; }; A75FCD2323E25AB700529352 /* SDL_uikitmessagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62623E2513D00DCD162 /* SDL_uikitmessagebox.h */; }; - A75FCD2423E25AB700529352 /* SDL_x11messagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A6FD23E2513E00DCD162 /* SDL_x11messagebox.h */; }; A75FCD2523E25AB700529352 /* SDL_thread_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77823E2513E00DCD162 /* SDL_thread_c.h */; }; A75FCD2623E25AB700529352 /* SDL_cocoamessagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69423E2513E00DCD162 /* SDL_cocoamessagebox.h */; }; - A75FCD2723E25AB700529352 /* SDL_x11shape.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70123E2513E00DCD162 /* SDL_x11shape.h */; }; A75FCD2823E25AB700529352 /* SDL_cpuinfo.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D11595D4D800BBD41B /* SDL_cpuinfo.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCD2923E25AB700529352 /* SDL_endian.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D21595D4D800BBD41B /* SDL_endian.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCD2A23E25AB700529352 /* SDL_error.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D31595D4D800BBD41B /* SDL_error.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -72,21 +183,18 @@ A75FCD2D23E25AB700529352 /* SDL_gamecontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = A77E6EB3167AB0A90010E40B /* SDL_gamecontroller.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCD2E23E25AB700529352 /* SDL_hidapijoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7C723E2513E00DCD162 /* SDL_hidapijoystick_c.h */; }; A75FCD3023E25AB700529352 /* SDL_pixels_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A74023E2513E00DCD162 /* SDL_pixels_c.h */; }; - A75FCD3123E25AB700529352 /* SDL_x11modes.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70F23E2513E00DCD162 /* SDL_x11modes.h */; }; A75FCD3223E25AB700529352 /* SDL_joystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7D023E2513E00DCD162 /* SDL_joystick_c.h */; }; A75FCD3323E25AB700529352 /* vk_sdk_platform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73D23E2513E00DCD162 /* vk_sdk_platform.h */; }; A75FCD3423E25AB700529352 /* blank_cursor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93223E2514000DCD162 /* blank_cursor.h */; }; A75FCD3523E25AB700529352 /* SDL_gesture.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D51595D4D800BBD41B /* SDL_gesture.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCD3623E25AB700529352 /* SDL_sysaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A89F23E2513F00DCD162 /* SDL_sysaudio.h */; }; A75FCD3723E25AB700529352 /* SDL_haptic.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D61595D4D800BBD41B /* SDL_haptic.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A75FCD3823E25AB700529352 /* SDL_sysevents.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93F23E2514000DCD162 /* SDL_sysevents.h */; }; A75FCD3923E25AB700529352 /* math_libm.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A92623E2514000DCD162 /* math_libm.h */; }; A75FCD3A23E25AB700529352 /* SDL_uikitvideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62223E2513D00DCD162 /* SDL_uikitvideo.h */; }; A75FCD3B23E25AB700529352 /* SDL_cocoamouse.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69823E2513E00DCD162 /* SDL_cocoamouse.h */; }; A75FCD3C23E25AB700529352 /* SDL_hints.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D71595D4D800BBD41B /* SDL_hints.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCD3D23E25AB700529352 /* SDL_blit_slow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A66323E2513E00DCD162 /* SDL_blit_slow.h */; }; A75FCD3E23E25AB700529352 /* SDL_yuv_sw_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8EC23E2514000DCD162 /* SDL_yuv_sw_c.h */; }; - A75FCD3F23E25AB700529352 /* SDL_x11opengl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70E23E2513E00DCD162 /* SDL_x11opengl.h */; }; A75FCD4023E25AB700529352 /* SDL_windowevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A94323E2514000DCD162 /* SDL_windowevents_c.h */; }; A75FCD4123E25AB700529352 /* SDL_joystick.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D91595D4D800BBD41B /* SDL_joystick.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCD4223E25AB700529352 /* SDL_cocoavideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69323E2513E00DCD162 /* SDL_cocoavideo.h */; }; @@ -96,16 +204,11 @@ A75FCD4623E25AB700529352 /* SDL_shaders_gl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90D23E2514000DCD162 /* SDL_shaders_gl.h */; }; A75FCD4723E25AB700529352 /* SDL_systhread_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A78423E2513E00DCD162 /* SDL_systhread_c.h */; }; A75FCD4823E25AB700529352 /* SDL_keycode.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557DB1595D4D800BBD41B /* SDL_keycode.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A75FCD4923E25AB700529352 /* SDL_x11keyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71C23E2513E00DCD162 /* SDL_x11keyboard.h */; }; A75FCD4A23E25AB700529352 /* SDL_cocoakeyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68023E2513E00DCD162 /* SDL_cocoakeyboard.h */; }; A75FCD4B23E25AB700529352 /* SDL_uikitvulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A63323E2513D00DCD162 /* SDL_uikitvulkan.h */; }; - A75FCD4C23E25AB700529352 /* SDL_x11framebuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71823E2513E00DCD162 /* SDL_x11framebuffer.h */; }; - A75FCD4D23E25AB700529352 /* SDL_x11video.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72023E2513E00DCD162 /* SDL_x11video.h */; }; - A75FCD4E23E25AB700529352 /* vulkan.hpp in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73223E2513E00DCD162 /* vulkan.hpp */; }; A75FCD4F23E25AB700529352 /* SDL_loadso.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557DC1595D4D800BBD41B /* SDL_loadso.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCD5023E25AB700529352 /* gl2ext.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72323E2513E00DCD162 /* gl2ext.h */; }; A75FCD5123E25AB700529352 /* SDL_clipboardevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93923E2514000DCD162 /* SDL_clipboardevents_c.h */; }; - A75FCD5223E25AB700529352 /* SDL_x11touch.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A6FC23E2513E00DCD162 /* SDL_x11touch.h */; }; A75FCD5323E25AB700529352 /* SDL_syshaptic_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5CF23E2513D00DCD162 /* SDL_syshaptic_c.h */; }; A75FCD5423E25AB700529352 /* SDL_hints_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8D123E2514000DCD162 /* SDL_hints_c.h */; }; A75FCD5523E25AB700529352 /* SDL_audiodev_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A87723E2513F00DCD162 /* SDL_audiodev_c.h */; }; @@ -129,9 +232,7 @@ A75FCD6723E25AB700529352 /* SDL_wave.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8A223E2513F00DCD162 /* SDL_wave.h */; }; A75FCD6823E25AB700529352 /* SDL_cocoaopengl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68D23E2513E00DCD162 /* SDL_cocoaopengl.h */; }; A75FCD6923E25AB700529352 /* yuv_rgb_sse_func.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77023E2513E00DCD162 /* yuv_rgb_sse_func.h */; }; - A75FCD6A23E25AB700529352 /* imKStoUCS.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71F23E2513E00DCD162 /* imKStoUCS.h */; }; A75FCD6B23E25AB700529352 /* SDL_offscreenevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5EE23E2513D00DCD162 /* SDL_offscreenevents_c.h */; }; - A75FCD6C23E25AB700529352 /* SDL_x11sym.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70D23E2513E00DCD162 /* SDL_x11sym.h */; }; A75FCD6D23E25AB700529352 /* SDL_coreaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8BA23E2513F00DCD162 /* SDL_coreaudio.h */; }; A75FCD6E23E25AB700529352 /* SDL_draw.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8FA23E2514000DCD162 /* SDL_draw.h */; }; A75FCD6F23E25AB700529352 /* SDL_drawline.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F723E2514000DCD162 /* SDL_drawline.h */; }; @@ -141,7 +242,6 @@ A75FCD7323E25AB700529352 /* SDL_yuv_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76A23E2513E00DCD162 /* SDL_yuv_c.h */; }; A75FCD7423E25AB700529352 /* scancodes_xfree86.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A94123E2514000DCD162 /* scancodes_xfree86.h */; }; A75FCD7523E25AB700529352 /* SDL_syspower.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7E223E2513F00DCD162 /* SDL_syspower.h */; }; - A75FCD7623E25AB700529352 /* SDL_x11clipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71D23E2513E00DCD162 /* SDL_x11clipboard.h */; }; A75FCD7723E25AB700529352 /* SDL_name.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E11595D4D800BBD41B /* SDL_name.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCD7823E25AB700529352 /* eglext.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72A23E2513E00DCD162 /* eglext.h */; }; A75FCD7923E25AB700529352 /* SDL_events_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A94223E2514000DCD162 /* SDL_events_c.h */; }; @@ -159,14 +259,12 @@ A75FCD8623E25AB700529352 /* SDL_sysjoystick.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7CF23E2513E00DCD162 /* SDL_sysjoystick.h */; }; A75FCD8723E25AB700529352 /* SDL_steamcontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7A523E2513E00DCD162 /* SDL_steamcontroller.h */; }; A75FCD8823E25AB700529352 /* scancodes_linux.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93623E2514000DCD162 /* scancodes_linux.h */; }; - A75FCD8923E25AB700529352 /* SDL_x11dyn.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71923E2513E00DCD162 /* SDL_x11dyn.h */; }; A75FCD8A23E25AB700529352 /* SDL_touch_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93723E2514000DCD162 /* SDL_touch_c.h */; }; A75FCD8B23E25AB700529352 /* SDL_gamecontrollerdb.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A79E23E2513E00DCD162 /* SDL_gamecontrollerdb.h */; }; A75FCD8C23E25AB700529352 /* SDL_cocoavulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68F23E2513E00DCD162 /* SDL_cocoavulkan.h */; }; A75FCD8D23E25AB700529352 /* gl2platform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72523E2513E00DCD162 /* gl2platform.h */; }; A75FCD8E23E25AB700529352 /* SDL_pixels.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E51595D4D800BBD41B /* SDL_pixels.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCD8F23E25AB700529352 /* vk_layer.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72D23E2513E00DCD162 /* vk_layer.h */; }; - A75FCD9023E25AB700529352 /* SDL_cocoamousetap.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68823E2513E00DCD162 /* SDL_cocoamousetap.h */; }; A75FCD9123E25AB700529352 /* vk_platform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73123E2513E00DCD162 /* vk_platform.h */; }; A75FCD9223E25AB700529352 /* SDL_cocoametalview.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68623E2513E00DCD162 /* SDL_cocoametalview.h */; }; A75FCD9323E25AB700529352 /* SDL_cocoaopengles.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69023E2513E00DCD162 /* SDL_cocoaopengles.h */; }; @@ -177,15 +275,12 @@ A75FCD9823E25AB700529352 /* SDL_rotate.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8FE23E2514000DCD162 /* SDL_rotate.h */; }; A75FCD9923E25AB700529352 /* SDL_platform.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E61595D4D800BBD41B /* SDL_platform.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCD9A23E25AB700529352 /* SDL_power.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E71595D4D800BBD41B /* SDL_power.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A75FCD9B23E25AB700529352 /* SDL_offscreenopengl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5F323E2513D00DCD162 /* SDL_offscreenopengl.h */; }; A75FCD9D23E25AB700529352 /* scancodes_darwin.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93423E2514000DCD162 /* scancodes_darwin.h */; }; A75FCD9E23E25AB700529352 /* controller_type.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7D923E2513E00DCD162 /* controller_type.h */; }; - A75FCD9F23E25AB700529352 /* SDL_x11opengles.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70323E2513E00DCD162 /* SDL_x11opengles.h */; }; A75FCDA023E25AB700529352 /* SDL_uikitclipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62123E2513D00DCD162 /* SDL_uikitclipboard.h */; }; A75FCDA123E25AB700529352 /* vulkan_xlib.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73A23E2513E00DCD162 /* vulkan_xlib.h */; }; A75FCDA223E25AB700529352 /* SDL_uikitwindow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62723E2513D00DCD162 /* SDL_uikitwindow.h */; }; A75FCDA323E25AB700529352 /* vulkan_vi.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72F23E2513E00DCD162 /* vulkan_vi.h */; }; - A75FCDA423E25AB700529352 /* vulkan_mir.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73923E2513E00DCD162 /* vulkan_mir.h */; }; A75FCDA523E25AB700529352 /* SDL_quit.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E81595D4D800BBD41B /* SDL_quit.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCDA623E25AB700529352 /* default_cursor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93323E2514000DCD162 /* default_cursor.h */; }; A75FCDA723E25AB700529352 /* SDL_render_sw_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F523E2514000DCD162 /* SDL_render_sw_c.h */; }; @@ -195,7 +290,6 @@ A75FCDAB23E25AB700529352 /* SDL_blit_copy.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76623E2513E00DCD162 /* SDL_blit_copy.h */; }; A75FCDAC23E25AB700529352 /* SDL_RLEaccel_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76723E2513E00DCD162 /* SDL_RLEaccel_c.h */; }; A75FCDAD23E25AB700529352 /* eglplatform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72B23E2513E00DCD162 /* eglplatform.h */; }; - A75FCDAE23E25AB700529352 /* edid.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71423E2513E00DCD162 /* edid.h */; }; A75FCDAF23E25AB700529352 /* SDL_revision.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557EB1595D4D800BBD41B /* SDL_revision.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCDB023E25AB700529352 /* SDL_systhread.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77723E2513E00DCD162 /* SDL_systhread.h */; }; A75FCDB123E25AB700529352 /* SDL_rwops.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557EC1595D4D800BBD41B /* SDL_rwops.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -240,7 +334,6 @@ A75FCDD923E25AB700529352 /* SDL_types.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F61595D4D800BBD41B /* SDL_types.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCDDA23E25AB700529352 /* usb_ids.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7CB23E2513E00DCD162 /* usb_ids.h */; }; A75FCDDB23E25AB700529352 /* SDL_gles2funcs.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90623E2514000DCD162 /* SDL_gles2funcs.h */; }; - A75FCDDC23E25AB700529352 /* SDL_sysjoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7CE23E2513E00DCD162 /* SDL_sysjoystick_c.h */; }; A75FCDDD23E25AB700529352 /* SDL_version.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F71595D4D800BBD41B /* SDL_version.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCDDE23E25AB700529352 /* SDL_video.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F81595D4D800BBD41B /* SDL_video.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCDDF23E25AB700529352 /* SDL_opengles2_gl2.h in Headers */ = {isa = PBXBuildFile; fileRef = AAC070F5195606770073DCDF /* SDL_opengles2_gl2.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -248,10 +341,8 @@ A75FCDE123E25AB700529352 /* SDL_sysvideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A61723E2513D00DCD162 /* SDL_sysvideo.h */; }; A75FCDE223E25AB700529352 /* SDL_opengles2_gl2platform.h in Headers */ = {isa = PBXBuildFile; fileRef = AAC070F7195606770073DCDF /* SDL_opengles2_gl2platform.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCDE323E25AB700529352 /* SDL_opengles2_gl2ext.h in Headers */ = {isa = PBXBuildFile; fileRef = AAC070F6195606770073DCDF /* SDL_opengles2_gl2ext.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A75FCDE423E25AB700529352 /* SDL_x11mouse.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71A23E2513E00DCD162 /* SDL_x11mouse.h */; }; A75FCDE523E25AB700529352 /* SDL_dynapi_overrides.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5D923E2513D00DCD162 /* SDL_dynapi_overrides.h */; }; A75FCDE623E25AB700529352 /* SDL_cocoawindow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69223E2513E00DCD162 /* SDL_cocoawindow.h */; }; - A75FCDE723E25AB700529352 /* SDL_x11vulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71523E2513E00DCD162 /* SDL_x11vulkan.h */; }; A75FCDE923E25AB700529352 /* SDL_drawline.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F123E2514000DCD162 /* SDL_drawline.c */; }; A75FCDEA23E25AB700529352 /* SDL_yuv.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A67C23E2513E00DCD162 /* SDL_yuv.c */; }; A75FCDEB23E25AB700529352 /* SDL_sysfilesystem.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7FE23E2513F00DCD162 /* SDL_sysfilesystem.m */; }; @@ -264,23 +355,19 @@ A75FCDF223E25AB700529352 /* SDL_render_metal.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8DE23E2514000DCD162 /* SDL_render_metal.m */; }; A75FCDF323E25AB700529352 /* SDL_clipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A67B23E2513E00DCD162 /* SDL_clipboard.c */; }; A75FCDF423E25AB700529352 /* SDL_cocoaevents.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68923E2513E00DCD162 /* SDL_cocoaevents.m */; }; - A75FCDF523E25AB700529352 /* SDL_x11messagebox.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71023E2513E00DCD162 /* SDL_x11messagebox.c */; }; A75FCDF623E25AB700529352 /* SDL_audiocvt.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8A123E2513F00DCD162 /* SDL_audiocvt.c */; }; A75FCDF723E25AB700529352 /* SDL_shape.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A76923E2513E00DCD162 /* SDL_shape.c */; }; A75FCDF823E25AB700529352 /* SDL_rotate.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F423E2514000DCD162 /* SDL_rotate.c */; }; A75FCDF923E25AB700529352 /* SDL_coremotionsensor.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57C23E2513D00DCD162 /* SDL_coremotionsensor.m */; }; A75FCDFA23E25AB700529352 /* SDL_touch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93E23E2514000DCD162 /* SDL_touch.c */; }; - A75FCDFB23E25AB700529352 /* SDL_x11events.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70A23E2513E00DCD162 /* SDL_x11events.c */; }; A75FCDFC23E25AB700529352 /* SDL_uikitmessagebox.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61B23E2513D00DCD162 /* SDL_uikitmessagebox.m */; }; A75FCDFD23E25AB700529352 /* SDL_thread.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A77923E2513E00DCD162 /* SDL_thread.c */; }; A75FCDFE23E25AB700529352 /* SDL_hidapi_xbox360w.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C823E2513E00DCD162 /* SDL_hidapi_xbox360w.c */; }; A75FCDFF23E25AB700529352 /* SDL_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57423E2513D00DCD162 /* SDL_atomic.c */; }; A75FCE0023E25AB700529352 /* SDL_displayevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92D23E2514000DCD162 /* SDL_displayevents.c */; }; - A75FCE0123E25AB700529352 /* SDL_cocoamousetap.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A69723E2513E00DCD162 /* SDL_cocoamousetap.m */; }; A75FCE0223E25AB700529352 /* SDL_log.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5DD23E2513D00DCD162 /* SDL_log.c */; }; A75FCE0323E25AB700529352 /* SDL_cocoaopengl.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A67F23E2513E00DCD162 /* SDL_cocoaopengl.m */; }; A75FCE0423E25AB700529352 /* SDL_offscreenframebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5F223E2513D00DCD162 /* SDL_offscreenframebuffer.c */; }; - A75FCE0523E25AB700529352 /* yuv_rgb.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A76E23E2513E00DCD162 /* yuv_rgb.c */; }; A75FCE0623E25AB700529352 /* SDL_render_gles.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A90123E2514000DCD162 /* SDL_render_gles.c */; }; A75FCE0723E25AB700529352 /* SDL_systhread.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78623E2513E00DCD162 /* SDL_systhread.c */; }; A75FCE0823E25AB700529352 /* SDL_windowevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92F23E2514000DCD162 /* SDL_windowevents.c */; }; @@ -291,14 +378,12 @@ A75FCE0D23E25AB700529352 /* SDL_systimer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5E223E2513D00DCD162 /* SDL_systimer.c */; }; A75FCE0E23E25AB700529352 /* SDL_uikitclipboard.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62A23E2513D00DCD162 /* SDL_uikitclipboard.m */; }; A75FCE0F23E25AB700529352 /* SDL_render_sw.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F923E2514000DCD162 /* SDL_render_sw.c */; }; - A75FCE1023E25AB700529352 /* SDL_x11video.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70823E2513E00DCD162 /* SDL_x11video.c */; }; A75FCE1123E25AB700529352 /* SDL_syssem.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78323E2513E00DCD162 /* SDL_syssem.c */; }; A75FCE1223E25AB700529352 /* SDL_hidapi_xbox360.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C223E2513E00DCD162 /* SDL_hidapi_xbox360.c */; }; A75FCE1323E25AB700529352 /* SDL_coreaudio.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8BB23E2513F00DCD162 /* SDL_coreaudio.m */; }; A75FCE1423E25AB700529352 /* SDL_blendline.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FB23E2514000DCD162 /* SDL_blendline.c */; }; A75FCE1523E25AB700529352 /* SDL_blit_A.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A66423E2513E00DCD162 /* SDL_blit_A.c */; }; A75FCE1623E25AB700529352 /* SDL_d3dmath.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FF23E2514000DCD162 /* SDL_d3dmath.c */; }; - A75FCE1723E25AB700529352 /* SDL_x11mouse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70423E2513E00DCD162 /* SDL_x11mouse.c */; }; A75FCE1823E25AB700529352 /* SDL_nullvideo.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60823E2513D00DCD162 /* SDL_nullvideo.c */; }; A75FCE1923E25AB700529352 /* SDL_offscreenevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5F023E2513D00DCD162 /* SDL_offscreenevents.c */; }; A75FCE1A23E25AB700529352 /* SDL_uikitview.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62923E2513D00DCD162 /* SDL_uikitview.m */; }; @@ -309,7 +394,6 @@ A75FCE1F23E25AB700529352 /* s_copysign.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91423E2514000DCD162 /* s_copysign.c */; }; A75FCE2023E25AB700529352 /* SDL_haptic.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5C523E2513D00DCD162 /* SDL_haptic.c */; }; A75FCE2123E25AB700529352 /* SDL_uikitvulkan.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62523E2513D00DCD162 /* SDL_uikitvulkan.m */; }; - A75FCE2223E25AB700529352 /* SDL_x11modes.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FE23E2513E00DCD162 /* SDL_x11modes.c */; }; A75FCE2323E25AB700529352 /* SDL_cocoametalview.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A69923E2513E00DCD162 /* SDL_cocoametalview.m */; }; A75FCE2423E25AB700529352 /* SDL_audiotypecvt.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8A023E2513F00DCD162 /* SDL_audiotypecvt.c */; }; A75FCE2523E25AB700529352 /* SDL_uikitevents.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61C23E2513D00DCD162 /* SDL_uikitevents.m */; }; @@ -339,15 +423,10 @@ A75FCE3D23E25AB700529352 /* SDL_hints.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5AB23E2513D00DCD162 /* SDL_hints.c */; }; A75FCE3E23E25AB700529352 /* SDL_hidapi_ps4.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C323E2513E00DCD162 /* SDL_hidapi_ps4.c */; }; A75FCE3F23E25AB700529352 /* SDL_pixels.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A64D23E2513D00DCD162 /* SDL_pixels.c */; }; - A75FCE4023E25AB700529352 /* SDL_x11clipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70B23E2513E00DCD162 /* SDL_x11clipboard.c */; }; A75FCE4123E25AB700529352 /* SDL_sysloadso.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A86323E2513F00DCD162 /* SDL_sysloadso.c */; }; - A75FCE4223E25AB700529352 /* SDL_x11xinput2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70223E2513E00DCD162 /* SDL_x11xinput2.c */; }; A75FCE4323E25AB700529352 /* SDL_syspower.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7EB23E2513F00DCD162 /* SDL_syspower.c */; }; - A75FCE4423E25AB700529352 /* SDL_x11touch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71123E2513E00DCD162 /* SDL_x11touch.c */; }; A75FCE4523E25AB700529352 /* SDL_iconv.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D323E2514000DCD162 /* SDL_iconv.c */; }; A75FCE4623E25AB700529352 /* s_fabs.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91523E2514000DCD162 /* s_fabs.c */; }; - A75FCE4723E25AB700529352 /* SDL_x11shape.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71623E2513E00DCD162 /* SDL_x11shape.c */; }; - A75FCE4823E25AB700529352 /* imKStoUCS.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70923E2513E00DCD162 /* imKStoUCS.c */; }; A75FCE4923E25AB700529352 /* SDL_shaders_metal.metal in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8E023E2514000DCD162 /* SDL_shaders_metal.metal */; }; A75FCE4A23E25AB700529352 /* SDL_uikitwindow.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61A23E2513D00DCD162 /* SDL_uikitwindow.m */; }; A75FCE4B23E25AB700529352 /* SDL_render.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8DB23E2514000DCD162 /* SDL_render.c */; }; @@ -362,7 +441,6 @@ A75FCE5423E25AB700529352 /* SDL_events.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93523E2514000DCD162 /* SDL_events.c */; }; A75FCE5523E25AB700529352 /* SDL_blit_0.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A66223E2513E00DCD162 /* SDL_blit_0.c */; }; A75FCE5623E25AB700529352 /* k_tan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92723E2514000DCD162 /* k_tan.c */; }; - A75FCE5723E25AB700529352 /* SDL_x11vulkan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70023E2513E00DCD162 /* SDL_x11vulkan.c */; }; A75FCE5823E25AB700529352 /* SDL_diskaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8B123E2513F00DCD162 /* SDL_diskaudio.c */; }; A75FCE5923E25AB700529352 /* SDL_egl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6B623E2513E00DCD162 /* SDL_egl.c */; }; A75FCE5A23E25AB700529352 /* SDL_RLEaccel.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61523E2513D00DCD162 /* SDL_RLEaccel.c */; }; @@ -376,10 +454,8 @@ A75FCE6323E25AB700529352 /* SDL_string.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D523E2514000DCD162 /* SDL_string.c */; }; A75FCE6423E25AB700529352 /* SDL_render_gl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A90F23E2514000DCD162 /* SDL_render_gl.c */; }; A75FCE6523E25AB700529352 /* SDL_uikitopengles.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62323E2513D00DCD162 /* SDL_uikitopengles.m */; }; - A75FCE6623E25AB700529352 /* SDL_x11opengles.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71B23E2513E00DCD162 /* SDL_x11opengles.c */; }; A75FCE6723E25AB700529352 /* SDL_cocoamodes.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68123E2513E00DCD162 /* SDL_cocoamodes.m */; }; A75FCE6823E25AB700529352 /* k_rem_pio2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91623E2514000DCD162 /* k_rem_pio2.c */; }; - A75FCE6923E25AB700529352 /* SDL_sysjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7CD23E2513E00DCD162 /* SDL_sysjoystick.c */; }; A75FCE6A23E25AB700529352 /* SDL_gesture.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A94023E2514000DCD162 /* SDL_gesture.c */; }; A75FCE6B23E25AB700529352 /* SDL_getenv.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D423E2514000DCD162 /* SDL_getenv.c */; }; A75FCE6C23E25AB700529352 /* SDL_hidapi_gamecube.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C923E2513E00DCD162 /* SDL_hidapi_gamecube.c */; }; @@ -388,7 +464,6 @@ A75FCE6F23E25AB700529352 /* SDL_surface.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61423E2513D00DCD162 /* SDL_surface.c */; }; A75FCE7023E25AB700529352 /* SDL_hidapi_xboxone.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C523E2513E00DCD162 /* SDL_hidapi_xboxone.c */; }; A75FCE7123E25AB700529352 /* SDL_blit_auto.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A63F23E2513D00DCD162 /* SDL_blit_auto.c */; }; - A75FCE7223E25AB700529352 /* SDL_x11keyboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70C23E2513E00DCD162 /* SDL_x11keyboard.c */; }; A75FCE7323E25AB700529352 /* SDL_keyboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93823E2514000DCD162 /* SDL_keyboard.c */; }; A75FCE7523E25AB700529352 /* SDL_rect.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A63423E2513D00DCD162 /* SDL_rect.c */; }; A75FCE7623E25AB700529352 /* SDL_cocoaopengles.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68223E2513E00DCD162 /* SDL_cocoaopengles.m */; }; @@ -396,7 +471,6 @@ A75FCE7823E25AB700529352 /* SDL_hidapi_switch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C623E2513E00DCD162 /* SDL_hidapi_switch.c */; }; A75FCE7923E25AB700529352 /* SDL_strtokr.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D623E2514000DCD162 /* SDL_strtokr.c */; }; A75FCE7A23E25AB700529352 /* SDL_clipboardevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93A23E2514000DCD162 /* SDL_clipboardevents.c */; }; - A75FCE7B23E25AB700529352 /* SDL_x11framebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70623E2513E00DCD162 /* SDL_x11framebuffer.c */; }; A75FCE7C23E25AB700529352 /* k_cos.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91923E2514000DCD162 /* k_cos.c */; }; A75FCE7D23E25AB700529352 /* SDL_hidapijoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C423E2513E00DCD162 /* SDL_hidapijoystick.c */; }; A75FCE7E23E25AB700529352 /* SDL_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D923E2514000DCD162 /* SDL_malloc.c */; }; @@ -412,27 +486,22 @@ A75FCE8823E25AB700529352 /* SDL_syshaptic.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5C423E2513D00DCD162 /* SDL_syshaptic.c */; }; A75FCE8923E25AB700529352 /* SDL_rwopsbundlesupport.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7DE23E2513F00DCD162 /* SDL_rwopsbundlesupport.m */; }; A75FCE8A23E25AB700529352 /* SDL_video.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60E23E2513D00DCD162 /* SDL_video.c */; }; - A75FCE8B23E25AB700529352 /* SDL_offscreenopengl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5ED23E2513D00DCD162 /* SDL_offscreenopengl.c */; }; A75FCE8C23E25AB700529352 /* SDL_uikitmetalview.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62E23E2513D00DCD162 /* SDL_uikitmetalview.m */; }; A75FCE8D23E25AB700529352 /* SDL_steamcontroller.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7A723E2513E00DCD162 /* SDL_steamcontroller.c */; }; A75FCE8E23E25AB700529352 /* SDL_shaders_gles2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A90723E2514000DCD162 /* SDL_shaders_gles2.c */; }; A75FCE8F23E25AB700529352 /* SDL_blit_1.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FA23E2513E00DCD162 /* SDL_blit_1.c */; }; - A75FCE9023E25AB700529352 /* SDL_x11dyn.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70523E2513E00DCD162 /* SDL_x11dyn.c */; }; A75FCE9123E25AB700529352 /* SDL_mouse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92A23E2514000DCD162 /* SDL_mouse.c */; }; A75FCE9223E25AB700529352 /* e_rem_pio2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91F23E2514000DCD162 /* e_rem_pio2.c */; }; A75FCE9323E25AB700529352 /* SDL_dataqueue.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92823E2514000DCD162 /* SDL_dataqueue.c */; }; A75FCE9423E25AB700529352 /* SDL_sysjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7A023E2513E00DCD162 /* SDL_sysjoystick.c */; }; A75FCE9523E25AB700529352 /* SDL_cpuinfo.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A77523E2513E00DCD162 /* SDL_cpuinfo.c */; }; A75FCE9623E25AB700529352 /* SDL_sensor.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A58223E2513D00DCD162 /* SDL_sensor.c */; }; - A75FCE9723E25AB700529352 /* SDL_x11window.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70723E2513E00DCD162 /* SDL_x11window.c */; }; A75FCE9823E25AB700529352 /* k_sin.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91723E2514000DCD162 /* k_sin.c */; }; - A75FCE9923E25AB700529352 /* edid-parse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71223E2513E00DCD162 /* edid-parse.c */; }; A75FCE9A23E25AB700529352 /* SDL_systimer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5E823E2513D00DCD162 /* SDL_systimer.c */; }; A75FCE9B23E25AB700529352 /* SDL_drawpoint.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FC23E2514000DCD162 /* SDL_drawpoint.c */; }; A75FCE9C23E25AB700529352 /* e_sqrt.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92423E2514000DCD162 /* e_sqrt.c */; }; A75FCE9D23E25AB700529352 /* SDL_cocoavideo.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68523E2513E00DCD162 /* SDL_cocoavideo.m */; }; A75FCE9F23E25AB700529352 /* SDL.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57123E2513D00DCD162 /* SDL.c */; }; - A75FCEA023E25AB700529352 /* SDL_x11opengl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FF23E2513E00DCD162 /* SDL_x11opengl.c */; }; A75FCEA123E25AB700529352 /* SDL_cocoavulkan.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68323E2513E00DCD162 /* SDL_cocoavulkan.m */; }; A75FCEA223E25AB700529352 /* SDL_uikitappdelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61E23E2513D00DCD162 /* SDL_uikitappdelegate.m */; }; A75FCEA323E25AB700529352 /* SDL_offscreenwindow.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5EF23E2513D00DCD162 /* SDL_offscreenwindow.c */; }; @@ -455,7 +524,6 @@ A75FCEC023E25AC700529352 /* SDL_glfuncs.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90E23E2514000DCD162 /* SDL_glfuncs.h */; }; A75FCEC123E25AC700529352 /* SDL_atomic.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557CA1595D4D800BBD41B /* SDL_atomic.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCEC223E25AC700529352 /* SDL_rect_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60C23E2513D00DCD162 /* SDL_rect_c.h */; }; - A75FCEC323E25AC700529352 /* SDL_x11xinput2.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71323E2513E00DCD162 /* SDL_x11xinput2.h */; }; A75FCEC423E25AC700529352 /* SDL_shaders_metal_osx.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8E223E2514000DCD162 /* SDL_shaders_metal_osx.h */; }; A75FCEC523E25AC700529352 /* SDL_shaders_metal_ios.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8DF23E2514000DCD162 /* SDL_shaders_metal_ios.h */; }; A75FCEC623E25AC700529352 /* SDL_offscreenwindow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5F523E2513D00DCD162 /* SDL_offscreenwindow.h */; }; @@ -464,26 +532,21 @@ A75FCEC923E25AC700529352 /* SDL_uikitview.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A61923E2513D00DCD162 /* SDL_uikitview.h */; }; A75FCECA23E25AC700529352 /* SDL_bits.h in Headers */ = {isa = PBXBuildFile; fileRef = AADA5B8616CCAB3000107CF7 /* SDL_bits.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCECB23E25AC700529352 /* SDL_uikitappdelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62F23E2513D00DCD162 /* SDL_uikitappdelegate.h */; }; - A75FCECC23E25AC700529352 /* keyinfotable.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62823E2513D00DCD162 /* keyinfotable.h */; }; A75FCECD23E25AC700529352 /* SDL_blendmode.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557CC1595D4D800BBD41B /* SDL_blendmode.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCECE23E25AC700529352 /* SDL_dropevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A92E23E2514000DCD162 /* SDL_dropevents_c.h */; }; A75FCECF23E25AC700529352 /* SDL_haptic_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5C623E2513D00DCD162 /* SDL_haptic_c.h */; }; A75FCED023E25AC700529352 /* SDL_clipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557CD1595D4D800BBD41B /* SDL_clipboard.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCED123E25AC700529352 /* SDL_dataqueue.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57023E2513D00DCD162 /* SDL_dataqueue.h */; }; A75FCED223E25AC700529352 /* SDL_error_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57523E2513D00DCD162 /* SDL_error_c.h */; }; - A75FCED323E25AC700529352 /* SDL_x11events.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71E23E2513E00DCD162 /* SDL_x11events.h */; }; A75FCED423E25AC700529352 /* SDL_config.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557CF1595D4D800BBD41B /* SDL_config.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCED523E25AC700529352 /* SDL_d3dmath.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8DC23E2514000DCD162 /* SDL_d3dmath.h */; }; - A75FCED623E25AC700529352 /* SDL_x11window.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71723E2513E00DCD162 /* SDL_x11window.h */; }; A75FCED823E25AC700529352 /* SDL_egl_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60423E2513D00DCD162 /* SDL_egl_c.h */; }; A75FCED923E25AC700529352 /* SDL_copying.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D01595D4D800BBD41B /* SDL_copying.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCEDA23E25AC700529352 /* yuv_rgb.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77223E2513E00DCD162 /* yuv_rgb.h */; }; A75FCEDB23E25AC700529352 /* SDL_dummyaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A87123E2513F00DCD162 /* SDL_dummyaudio.h */; }; A75FCEDC23E25AC700529352 /* SDL_uikitmessagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62623E2513D00DCD162 /* SDL_uikitmessagebox.h */; }; - A75FCEDD23E25AC700529352 /* SDL_x11messagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A6FD23E2513E00DCD162 /* SDL_x11messagebox.h */; }; A75FCEDE23E25AC700529352 /* SDL_thread_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77823E2513E00DCD162 /* SDL_thread_c.h */; }; A75FCEDF23E25AC700529352 /* SDL_cocoamessagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69423E2513E00DCD162 /* SDL_cocoamessagebox.h */; }; - A75FCEE023E25AC700529352 /* SDL_x11shape.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70123E2513E00DCD162 /* SDL_x11shape.h */; }; A75FCEE123E25AC700529352 /* SDL_cpuinfo.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D11595D4D800BBD41B /* SDL_cpuinfo.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCEE223E25AC700529352 /* SDL_endian.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D21595D4D800BBD41B /* SDL_endian.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCEE323E25AC700529352 /* SDL_error.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D31595D4D800BBD41B /* SDL_error.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -492,21 +555,18 @@ A75FCEE623E25AC700529352 /* SDL_gamecontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = A77E6EB3167AB0A90010E40B /* SDL_gamecontroller.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCEE723E25AC700529352 /* SDL_hidapijoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7C723E2513E00DCD162 /* SDL_hidapijoystick_c.h */; }; A75FCEE923E25AC700529352 /* SDL_pixels_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A74023E2513E00DCD162 /* SDL_pixels_c.h */; }; - A75FCEEA23E25AC700529352 /* SDL_x11modes.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70F23E2513E00DCD162 /* SDL_x11modes.h */; }; A75FCEEB23E25AC700529352 /* SDL_joystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7D023E2513E00DCD162 /* SDL_joystick_c.h */; }; A75FCEEC23E25AC700529352 /* vk_sdk_platform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73D23E2513E00DCD162 /* vk_sdk_platform.h */; }; A75FCEED23E25AC700529352 /* blank_cursor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93223E2514000DCD162 /* blank_cursor.h */; }; A75FCEEE23E25AC700529352 /* SDL_gesture.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D51595D4D800BBD41B /* SDL_gesture.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCEEF23E25AC700529352 /* SDL_sysaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A89F23E2513F00DCD162 /* SDL_sysaudio.h */; }; A75FCEF023E25AC700529352 /* SDL_haptic.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D61595D4D800BBD41B /* SDL_haptic.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A75FCEF123E25AC700529352 /* SDL_sysevents.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93F23E2514000DCD162 /* SDL_sysevents.h */; }; A75FCEF223E25AC700529352 /* math_libm.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A92623E2514000DCD162 /* math_libm.h */; }; A75FCEF323E25AC700529352 /* SDL_uikitvideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62223E2513D00DCD162 /* SDL_uikitvideo.h */; }; A75FCEF423E25AC700529352 /* SDL_cocoamouse.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69823E2513E00DCD162 /* SDL_cocoamouse.h */; }; A75FCEF523E25AC700529352 /* SDL_hints.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D71595D4D800BBD41B /* SDL_hints.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCEF623E25AC700529352 /* SDL_blit_slow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A66323E2513E00DCD162 /* SDL_blit_slow.h */; }; A75FCEF723E25AC700529352 /* SDL_yuv_sw_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8EC23E2514000DCD162 /* SDL_yuv_sw_c.h */; }; - A75FCEF823E25AC700529352 /* SDL_x11opengl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70E23E2513E00DCD162 /* SDL_x11opengl.h */; }; A75FCEF923E25AC700529352 /* SDL_windowevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A94323E2514000DCD162 /* SDL_windowevents_c.h */; }; A75FCEFA23E25AC700529352 /* SDL_joystick.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D91595D4D800BBD41B /* SDL_joystick.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCEFB23E25AC700529352 /* SDL_cocoavideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69323E2513E00DCD162 /* SDL_cocoavideo.h */; }; @@ -516,16 +576,11 @@ A75FCEFF23E25AC700529352 /* SDL_shaders_gl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90D23E2514000DCD162 /* SDL_shaders_gl.h */; }; A75FCF0023E25AC700529352 /* SDL_systhread_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A78423E2513E00DCD162 /* SDL_systhread_c.h */; }; A75FCF0123E25AC700529352 /* SDL_keycode.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557DB1595D4D800BBD41B /* SDL_keycode.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A75FCF0223E25AC700529352 /* SDL_x11keyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71C23E2513E00DCD162 /* SDL_x11keyboard.h */; }; A75FCF0323E25AC700529352 /* SDL_cocoakeyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68023E2513E00DCD162 /* SDL_cocoakeyboard.h */; }; A75FCF0423E25AC700529352 /* SDL_uikitvulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A63323E2513D00DCD162 /* SDL_uikitvulkan.h */; }; - A75FCF0523E25AC700529352 /* SDL_x11framebuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71823E2513E00DCD162 /* SDL_x11framebuffer.h */; }; - A75FCF0623E25AC700529352 /* SDL_x11video.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72023E2513E00DCD162 /* SDL_x11video.h */; }; - A75FCF0723E25AC700529352 /* vulkan.hpp in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73223E2513E00DCD162 /* vulkan.hpp */; }; A75FCF0823E25AC700529352 /* SDL_loadso.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557DC1595D4D800BBD41B /* SDL_loadso.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCF0923E25AC700529352 /* gl2ext.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72323E2513E00DCD162 /* gl2ext.h */; }; A75FCF0A23E25AC700529352 /* SDL_clipboardevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93923E2514000DCD162 /* SDL_clipboardevents_c.h */; }; - A75FCF0B23E25AC700529352 /* SDL_x11touch.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A6FC23E2513E00DCD162 /* SDL_x11touch.h */; }; A75FCF0C23E25AC700529352 /* SDL_syshaptic_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5CF23E2513D00DCD162 /* SDL_syshaptic_c.h */; }; A75FCF0D23E25AC700529352 /* SDL_hints_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8D123E2514000DCD162 /* SDL_hints_c.h */; }; A75FCF0E23E25AC700529352 /* SDL_audiodev_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A87723E2513F00DCD162 /* SDL_audiodev_c.h */; }; @@ -549,9 +604,7 @@ A75FCF2023E25AC700529352 /* SDL_wave.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8A223E2513F00DCD162 /* SDL_wave.h */; }; A75FCF2123E25AC700529352 /* SDL_cocoaopengl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68D23E2513E00DCD162 /* SDL_cocoaopengl.h */; }; A75FCF2223E25AC700529352 /* yuv_rgb_sse_func.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77023E2513E00DCD162 /* yuv_rgb_sse_func.h */; }; - A75FCF2323E25AC700529352 /* imKStoUCS.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71F23E2513E00DCD162 /* imKStoUCS.h */; }; A75FCF2423E25AC700529352 /* SDL_offscreenevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5EE23E2513D00DCD162 /* SDL_offscreenevents_c.h */; }; - A75FCF2523E25AC700529352 /* SDL_x11sym.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70D23E2513E00DCD162 /* SDL_x11sym.h */; }; A75FCF2623E25AC700529352 /* SDL_coreaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8BA23E2513F00DCD162 /* SDL_coreaudio.h */; }; A75FCF2723E25AC700529352 /* SDL_draw.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8FA23E2514000DCD162 /* SDL_draw.h */; }; A75FCF2823E25AC700529352 /* SDL_drawline.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F723E2514000DCD162 /* SDL_drawline.h */; }; @@ -561,7 +614,6 @@ A75FCF2C23E25AC700529352 /* SDL_yuv_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76A23E2513E00DCD162 /* SDL_yuv_c.h */; }; A75FCF2D23E25AC700529352 /* scancodes_xfree86.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A94123E2514000DCD162 /* scancodes_xfree86.h */; }; A75FCF2E23E25AC700529352 /* SDL_syspower.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7E223E2513F00DCD162 /* SDL_syspower.h */; }; - A75FCF2F23E25AC700529352 /* SDL_x11clipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71D23E2513E00DCD162 /* SDL_x11clipboard.h */; }; A75FCF3023E25AC700529352 /* SDL_name.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E11595D4D800BBD41B /* SDL_name.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCF3123E25AC700529352 /* eglext.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72A23E2513E00DCD162 /* eglext.h */; }; A75FCF3223E25AC700529352 /* SDL_events_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A94223E2514000DCD162 /* SDL_events_c.h */; }; @@ -579,14 +631,12 @@ A75FCF3F23E25AC700529352 /* SDL_sysjoystick.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7CF23E2513E00DCD162 /* SDL_sysjoystick.h */; }; A75FCF4023E25AC700529352 /* SDL_steamcontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7A523E2513E00DCD162 /* SDL_steamcontroller.h */; }; A75FCF4123E25AC700529352 /* scancodes_linux.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93623E2514000DCD162 /* scancodes_linux.h */; }; - A75FCF4223E25AC700529352 /* SDL_x11dyn.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71923E2513E00DCD162 /* SDL_x11dyn.h */; }; A75FCF4323E25AC700529352 /* SDL_touch_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93723E2514000DCD162 /* SDL_touch_c.h */; }; A75FCF4423E25AC700529352 /* SDL_gamecontrollerdb.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A79E23E2513E00DCD162 /* SDL_gamecontrollerdb.h */; }; A75FCF4523E25AC700529352 /* SDL_cocoavulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68F23E2513E00DCD162 /* SDL_cocoavulkan.h */; }; A75FCF4623E25AC700529352 /* gl2platform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72523E2513E00DCD162 /* gl2platform.h */; }; A75FCF4723E25AC700529352 /* SDL_pixels.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E51595D4D800BBD41B /* SDL_pixels.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCF4823E25AC700529352 /* vk_layer.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72D23E2513E00DCD162 /* vk_layer.h */; }; - A75FCF4923E25AC700529352 /* SDL_cocoamousetap.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68823E2513E00DCD162 /* SDL_cocoamousetap.h */; }; A75FCF4A23E25AC700529352 /* vk_platform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73123E2513E00DCD162 /* vk_platform.h */; }; A75FCF4B23E25AC700529352 /* SDL_cocoametalview.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68623E2513E00DCD162 /* SDL_cocoametalview.h */; }; A75FCF4C23E25AC700529352 /* SDL_cocoaopengles.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69023E2513E00DCD162 /* SDL_cocoaopengles.h */; }; @@ -597,15 +647,12 @@ A75FCF5123E25AC700529352 /* SDL_rotate.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8FE23E2514000DCD162 /* SDL_rotate.h */; }; A75FCF5223E25AC700529352 /* SDL_platform.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E61595D4D800BBD41B /* SDL_platform.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCF5323E25AC700529352 /* SDL_power.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E71595D4D800BBD41B /* SDL_power.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A75FCF5423E25AC700529352 /* SDL_offscreenopengl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5F323E2513D00DCD162 /* SDL_offscreenopengl.h */; }; A75FCF5623E25AC700529352 /* scancodes_darwin.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93423E2514000DCD162 /* scancodes_darwin.h */; }; A75FCF5723E25AC700529352 /* controller_type.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7D923E2513E00DCD162 /* controller_type.h */; }; - A75FCF5823E25AC700529352 /* SDL_x11opengles.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70323E2513E00DCD162 /* SDL_x11opengles.h */; }; A75FCF5923E25AC700529352 /* SDL_uikitclipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62123E2513D00DCD162 /* SDL_uikitclipboard.h */; }; A75FCF5A23E25AC700529352 /* vulkan_xlib.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73A23E2513E00DCD162 /* vulkan_xlib.h */; }; A75FCF5B23E25AC700529352 /* SDL_uikitwindow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62723E2513D00DCD162 /* SDL_uikitwindow.h */; }; A75FCF5C23E25AC700529352 /* vulkan_vi.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72F23E2513E00DCD162 /* vulkan_vi.h */; }; - A75FCF5D23E25AC700529352 /* vulkan_mir.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73923E2513E00DCD162 /* vulkan_mir.h */; }; A75FCF5E23E25AC700529352 /* SDL_quit.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E81595D4D800BBD41B /* SDL_quit.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCF5F23E25AC700529352 /* default_cursor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93323E2514000DCD162 /* default_cursor.h */; }; A75FCF6023E25AC700529352 /* SDL_render_sw_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F523E2514000DCD162 /* SDL_render_sw_c.h */; }; @@ -615,7 +662,6 @@ A75FCF6423E25AC700529352 /* SDL_blit_copy.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76623E2513E00DCD162 /* SDL_blit_copy.h */; }; A75FCF6523E25AC700529352 /* SDL_RLEaccel_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76723E2513E00DCD162 /* SDL_RLEaccel_c.h */; }; A75FCF6623E25AC700529352 /* eglplatform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72B23E2513E00DCD162 /* eglplatform.h */; }; - A75FCF6723E25AC700529352 /* edid.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71423E2513E00DCD162 /* edid.h */; }; A75FCF6823E25AC700529352 /* SDL_revision.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557EB1595D4D800BBD41B /* SDL_revision.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCF6923E25AC700529352 /* SDL_systhread.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77723E2513E00DCD162 /* SDL_systhread.h */; }; A75FCF6A23E25AC700529352 /* SDL_rwops.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557EC1595D4D800BBD41B /* SDL_rwops.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -660,7 +706,6 @@ A75FCF9223E25AC700529352 /* SDL_types.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F61595D4D800BBD41B /* SDL_types.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCF9323E25AC700529352 /* usb_ids.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7CB23E2513E00DCD162 /* usb_ids.h */; }; A75FCF9423E25AC700529352 /* SDL_gles2funcs.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90623E2514000DCD162 /* SDL_gles2funcs.h */; }; - A75FCF9523E25AC700529352 /* SDL_sysjoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7CE23E2513E00DCD162 /* SDL_sysjoystick_c.h */; }; A75FCF9623E25AC700529352 /* SDL_version.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F71595D4D800BBD41B /* SDL_version.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCF9723E25AC700529352 /* SDL_video.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F81595D4D800BBD41B /* SDL_video.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCF9823E25AC700529352 /* SDL_opengles2_gl2.h in Headers */ = {isa = PBXBuildFile; fileRef = AAC070F5195606770073DCDF /* SDL_opengles2_gl2.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -668,10 +713,8 @@ A75FCF9A23E25AC700529352 /* SDL_sysvideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A61723E2513D00DCD162 /* SDL_sysvideo.h */; }; A75FCF9B23E25AC700529352 /* SDL_opengles2_gl2platform.h in Headers */ = {isa = PBXBuildFile; fileRef = AAC070F7195606770073DCDF /* SDL_opengles2_gl2platform.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FCF9C23E25AC700529352 /* SDL_opengles2_gl2ext.h in Headers */ = {isa = PBXBuildFile; fileRef = AAC070F6195606770073DCDF /* SDL_opengles2_gl2ext.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A75FCF9D23E25AC700529352 /* SDL_x11mouse.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71A23E2513E00DCD162 /* SDL_x11mouse.h */; }; A75FCF9E23E25AC700529352 /* SDL_dynapi_overrides.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5D923E2513D00DCD162 /* SDL_dynapi_overrides.h */; }; A75FCF9F23E25AC700529352 /* SDL_cocoawindow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69223E2513E00DCD162 /* SDL_cocoawindow.h */; }; - A75FCFA023E25AC700529352 /* SDL_x11vulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71523E2513E00DCD162 /* SDL_x11vulkan.h */; }; A75FCFA223E25AC700529352 /* SDL_drawline.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F123E2514000DCD162 /* SDL_drawline.c */; }; A75FCFA323E25AC700529352 /* SDL_yuv.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A67C23E2513E00DCD162 /* SDL_yuv.c */; }; A75FCFA423E25AC700529352 /* SDL_sysfilesystem.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7FE23E2513F00DCD162 /* SDL_sysfilesystem.m */; }; @@ -684,23 +727,19 @@ A75FCFAB23E25AC700529352 /* SDL_render_metal.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8DE23E2514000DCD162 /* SDL_render_metal.m */; }; A75FCFAC23E25AC700529352 /* SDL_clipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A67B23E2513E00DCD162 /* SDL_clipboard.c */; }; A75FCFAD23E25AC700529352 /* SDL_cocoaevents.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68923E2513E00DCD162 /* SDL_cocoaevents.m */; }; - A75FCFAE23E25AC700529352 /* SDL_x11messagebox.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71023E2513E00DCD162 /* SDL_x11messagebox.c */; }; A75FCFAF23E25AC700529352 /* SDL_audiocvt.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8A123E2513F00DCD162 /* SDL_audiocvt.c */; }; A75FCFB023E25AC700529352 /* SDL_shape.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A76923E2513E00DCD162 /* SDL_shape.c */; }; A75FCFB123E25AC700529352 /* SDL_rotate.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F423E2514000DCD162 /* SDL_rotate.c */; }; A75FCFB223E25AC700529352 /* SDL_coremotionsensor.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57C23E2513D00DCD162 /* SDL_coremotionsensor.m */; }; A75FCFB323E25AC700529352 /* SDL_touch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93E23E2514000DCD162 /* SDL_touch.c */; }; - A75FCFB423E25AC700529352 /* SDL_x11events.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70A23E2513E00DCD162 /* SDL_x11events.c */; }; A75FCFB523E25AC700529352 /* SDL_uikitmessagebox.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61B23E2513D00DCD162 /* SDL_uikitmessagebox.m */; }; A75FCFB623E25AC700529352 /* SDL_thread.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A77923E2513E00DCD162 /* SDL_thread.c */; }; A75FCFB723E25AC700529352 /* SDL_hidapi_xbox360w.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C823E2513E00DCD162 /* SDL_hidapi_xbox360w.c */; }; A75FCFB823E25AC700529352 /* SDL_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57423E2513D00DCD162 /* SDL_atomic.c */; }; A75FCFB923E25AC700529352 /* SDL_displayevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92D23E2514000DCD162 /* SDL_displayevents.c */; }; - A75FCFBA23E25AC700529352 /* SDL_cocoamousetap.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A69723E2513E00DCD162 /* SDL_cocoamousetap.m */; }; A75FCFBB23E25AC700529352 /* SDL_log.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5DD23E2513D00DCD162 /* SDL_log.c */; }; A75FCFBC23E25AC700529352 /* SDL_cocoaopengl.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A67F23E2513E00DCD162 /* SDL_cocoaopengl.m */; }; A75FCFBD23E25AC700529352 /* SDL_offscreenframebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5F223E2513D00DCD162 /* SDL_offscreenframebuffer.c */; }; - A75FCFBE23E25AC700529352 /* yuv_rgb.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A76E23E2513E00DCD162 /* yuv_rgb.c */; }; A75FCFBF23E25AC700529352 /* SDL_render_gles.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A90123E2514000DCD162 /* SDL_render_gles.c */; }; A75FCFC023E25AC700529352 /* SDL_systhread.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78623E2513E00DCD162 /* SDL_systhread.c */; }; A75FCFC123E25AC700529352 /* SDL_windowevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92F23E2514000DCD162 /* SDL_windowevents.c */; }; @@ -711,14 +750,12 @@ A75FCFC623E25AC700529352 /* SDL_systimer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5E223E2513D00DCD162 /* SDL_systimer.c */; }; A75FCFC723E25AC700529352 /* SDL_uikitclipboard.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62A23E2513D00DCD162 /* SDL_uikitclipboard.m */; }; A75FCFC823E25AC700529352 /* SDL_render_sw.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F923E2514000DCD162 /* SDL_render_sw.c */; }; - A75FCFC923E25AC700529352 /* SDL_x11video.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70823E2513E00DCD162 /* SDL_x11video.c */; }; A75FCFCA23E25AC700529352 /* SDL_syssem.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78323E2513E00DCD162 /* SDL_syssem.c */; }; A75FCFCB23E25AC700529352 /* SDL_hidapi_xbox360.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C223E2513E00DCD162 /* SDL_hidapi_xbox360.c */; }; A75FCFCC23E25AC700529352 /* SDL_coreaudio.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8BB23E2513F00DCD162 /* SDL_coreaudio.m */; }; A75FCFCD23E25AC700529352 /* SDL_blendline.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FB23E2514000DCD162 /* SDL_blendline.c */; }; A75FCFCE23E25AC700529352 /* SDL_blit_A.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A66423E2513E00DCD162 /* SDL_blit_A.c */; }; A75FCFCF23E25AC700529352 /* SDL_d3dmath.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FF23E2514000DCD162 /* SDL_d3dmath.c */; }; - A75FCFD023E25AC700529352 /* SDL_x11mouse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70423E2513E00DCD162 /* SDL_x11mouse.c */; }; A75FCFD123E25AC700529352 /* SDL_nullvideo.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60823E2513D00DCD162 /* SDL_nullvideo.c */; }; A75FCFD223E25AC700529352 /* SDL_offscreenevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5F023E2513D00DCD162 /* SDL_offscreenevents.c */; }; A75FCFD323E25AC700529352 /* SDL_uikitview.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62923E2513D00DCD162 /* SDL_uikitview.m */; }; @@ -729,7 +766,6 @@ A75FCFD823E25AC700529352 /* s_copysign.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91423E2514000DCD162 /* s_copysign.c */; }; A75FCFD923E25AC700529352 /* SDL_haptic.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5C523E2513D00DCD162 /* SDL_haptic.c */; }; A75FCFDA23E25AC700529352 /* SDL_uikitvulkan.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62523E2513D00DCD162 /* SDL_uikitvulkan.m */; }; - A75FCFDB23E25AC700529352 /* SDL_x11modes.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FE23E2513E00DCD162 /* SDL_x11modes.c */; }; A75FCFDC23E25AC700529352 /* SDL_cocoametalview.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A69923E2513E00DCD162 /* SDL_cocoametalview.m */; }; A75FCFDD23E25AC700529352 /* SDL_audiotypecvt.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8A023E2513F00DCD162 /* SDL_audiotypecvt.c */; }; A75FCFDE23E25AC700529352 /* SDL_uikitevents.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61C23E2513D00DCD162 /* SDL_uikitevents.m */; }; @@ -759,15 +795,10 @@ A75FCFF623E25AC700529352 /* SDL_hints.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5AB23E2513D00DCD162 /* SDL_hints.c */; }; A75FCFF723E25AC700529352 /* SDL_hidapi_ps4.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C323E2513E00DCD162 /* SDL_hidapi_ps4.c */; }; A75FCFF823E25AC700529352 /* SDL_pixels.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A64D23E2513D00DCD162 /* SDL_pixels.c */; }; - A75FCFF923E25AC700529352 /* SDL_x11clipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70B23E2513E00DCD162 /* SDL_x11clipboard.c */; }; A75FCFFA23E25AC700529352 /* SDL_sysloadso.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A86323E2513F00DCD162 /* SDL_sysloadso.c */; }; - A75FCFFB23E25AC700529352 /* SDL_x11xinput2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70223E2513E00DCD162 /* SDL_x11xinput2.c */; }; A75FCFFC23E25AC700529352 /* SDL_syspower.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7EB23E2513F00DCD162 /* SDL_syspower.c */; }; - A75FCFFD23E25AC700529352 /* SDL_x11touch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71123E2513E00DCD162 /* SDL_x11touch.c */; }; A75FCFFE23E25AC700529352 /* SDL_iconv.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D323E2514000DCD162 /* SDL_iconv.c */; }; A75FCFFF23E25AC700529352 /* s_fabs.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91523E2514000DCD162 /* s_fabs.c */; }; - A75FD00023E25AC700529352 /* SDL_x11shape.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71623E2513E00DCD162 /* SDL_x11shape.c */; }; - A75FD00123E25AC700529352 /* imKStoUCS.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70923E2513E00DCD162 /* imKStoUCS.c */; }; A75FD00223E25AC700529352 /* SDL_shaders_metal.metal in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8E023E2514000DCD162 /* SDL_shaders_metal.metal */; }; A75FD00323E25AC700529352 /* SDL_uikitwindow.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61A23E2513D00DCD162 /* SDL_uikitwindow.m */; }; A75FD00423E25AC700529352 /* SDL_render.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8DB23E2514000DCD162 /* SDL_render.c */; }; @@ -782,7 +813,6 @@ A75FD00D23E25AC700529352 /* SDL_events.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93523E2514000DCD162 /* SDL_events.c */; }; A75FD00E23E25AC700529352 /* SDL_blit_0.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A66223E2513E00DCD162 /* SDL_blit_0.c */; }; A75FD00F23E25AC700529352 /* k_tan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92723E2514000DCD162 /* k_tan.c */; }; - A75FD01023E25AC700529352 /* SDL_x11vulkan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70023E2513E00DCD162 /* SDL_x11vulkan.c */; }; A75FD01123E25AC700529352 /* SDL_diskaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8B123E2513F00DCD162 /* SDL_diskaudio.c */; }; A75FD01223E25AC700529352 /* SDL_egl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6B623E2513E00DCD162 /* SDL_egl.c */; }; A75FD01323E25AC700529352 /* SDL_RLEaccel.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61523E2513D00DCD162 /* SDL_RLEaccel.c */; }; @@ -796,10 +826,8 @@ A75FD01C23E25AC700529352 /* SDL_string.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D523E2514000DCD162 /* SDL_string.c */; }; A75FD01D23E25AC700529352 /* SDL_render_gl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A90F23E2514000DCD162 /* SDL_render_gl.c */; }; A75FD01E23E25AC700529352 /* SDL_uikitopengles.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62323E2513D00DCD162 /* SDL_uikitopengles.m */; }; - A75FD01F23E25AC700529352 /* SDL_x11opengles.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71B23E2513E00DCD162 /* SDL_x11opengles.c */; }; A75FD02023E25AC700529352 /* SDL_cocoamodes.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68123E2513E00DCD162 /* SDL_cocoamodes.m */; }; A75FD02123E25AC700529352 /* k_rem_pio2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91623E2514000DCD162 /* k_rem_pio2.c */; }; - A75FD02223E25AC700529352 /* SDL_sysjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7CD23E2513E00DCD162 /* SDL_sysjoystick.c */; }; A75FD02323E25AC700529352 /* SDL_gesture.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A94023E2514000DCD162 /* SDL_gesture.c */; }; A75FD02423E25AC700529352 /* SDL_getenv.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D423E2514000DCD162 /* SDL_getenv.c */; }; A75FD02523E25AC700529352 /* SDL_hidapi_gamecube.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C923E2513E00DCD162 /* SDL_hidapi_gamecube.c */; }; @@ -808,7 +836,6 @@ A75FD02823E25AC700529352 /* SDL_surface.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61423E2513D00DCD162 /* SDL_surface.c */; }; A75FD02923E25AC700529352 /* SDL_hidapi_xboxone.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C523E2513E00DCD162 /* SDL_hidapi_xboxone.c */; }; A75FD02A23E25AC700529352 /* SDL_blit_auto.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A63F23E2513D00DCD162 /* SDL_blit_auto.c */; }; - A75FD02B23E25AC700529352 /* SDL_x11keyboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70C23E2513E00DCD162 /* SDL_x11keyboard.c */; }; A75FD02C23E25AC700529352 /* SDL_keyboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93823E2514000DCD162 /* SDL_keyboard.c */; }; A75FD02E23E25AC700529352 /* SDL_rect.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A63423E2513D00DCD162 /* SDL_rect.c */; }; A75FD02F23E25AC700529352 /* SDL_cocoaopengles.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68223E2513E00DCD162 /* SDL_cocoaopengles.m */; }; @@ -816,7 +843,6 @@ A75FD03123E25AC700529352 /* SDL_hidapi_switch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C623E2513E00DCD162 /* SDL_hidapi_switch.c */; }; A75FD03223E25AC700529352 /* SDL_strtokr.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D623E2514000DCD162 /* SDL_strtokr.c */; }; A75FD03323E25AC700529352 /* SDL_clipboardevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93A23E2514000DCD162 /* SDL_clipboardevents.c */; }; - A75FD03423E25AC700529352 /* SDL_x11framebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70623E2513E00DCD162 /* SDL_x11framebuffer.c */; }; A75FD03523E25AC700529352 /* k_cos.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91923E2514000DCD162 /* k_cos.c */; }; A75FD03623E25AC700529352 /* SDL_hidapijoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C423E2513E00DCD162 /* SDL_hidapijoystick.c */; }; A75FD03723E25AC700529352 /* SDL_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D923E2514000DCD162 /* SDL_malloc.c */; }; @@ -832,74 +858,42 @@ A75FD04123E25AC700529352 /* SDL_syshaptic.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5C423E2513D00DCD162 /* SDL_syshaptic.c */; }; A75FD04223E25AC700529352 /* SDL_rwopsbundlesupport.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7DE23E2513F00DCD162 /* SDL_rwopsbundlesupport.m */; }; A75FD04323E25AC700529352 /* SDL_video.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60E23E2513D00DCD162 /* SDL_video.c */; }; - A75FD04423E25AC700529352 /* SDL_offscreenopengl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5ED23E2513D00DCD162 /* SDL_offscreenopengl.c */; }; A75FD04523E25AC700529352 /* SDL_uikitmetalview.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62E23E2513D00DCD162 /* SDL_uikitmetalview.m */; }; A75FD04623E25AC700529352 /* SDL_steamcontroller.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7A723E2513E00DCD162 /* SDL_steamcontroller.c */; }; A75FD04723E25AC700529352 /* SDL_shaders_gles2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A90723E2514000DCD162 /* SDL_shaders_gles2.c */; }; A75FD04823E25AC700529352 /* SDL_blit_1.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FA23E2513E00DCD162 /* SDL_blit_1.c */; }; - A75FD04923E25AC700529352 /* SDL_x11dyn.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70523E2513E00DCD162 /* SDL_x11dyn.c */; }; A75FD04A23E25AC700529352 /* SDL_mouse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92A23E2514000DCD162 /* SDL_mouse.c */; }; A75FD04B23E25AC700529352 /* e_rem_pio2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91F23E2514000DCD162 /* e_rem_pio2.c */; }; A75FD04C23E25AC700529352 /* SDL_dataqueue.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92823E2514000DCD162 /* SDL_dataqueue.c */; }; A75FD04D23E25AC700529352 /* SDL_sysjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7A023E2513E00DCD162 /* SDL_sysjoystick.c */; }; A75FD04E23E25AC700529352 /* SDL_cpuinfo.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A77523E2513E00DCD162 /* SDL_cpuinfo.c */; }; A75FD04F23E25AC700529352 /* SDL_sensor.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A58223E2513D00DCD162 /* SDL_sensor.c */; }; - A75FD05023E25AC700529352 /* SDL_x11window.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70723E2513E00DCD162 /* SDL_x11window.c */; }; A75FD05123E25AC700529352 /* k_sin.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91723E2514000DCD162 /* k_sin.c */; }; - A75FD05223E25AC700529352 /* edid-parse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71223E2513E00DCD162 /* edid-parse.c */; }; A75FD05323E25AC700529352 /* SDL_systimer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5E823E2513D00DCD162 /* SDL_systimer.c */; }; A75FD05423E25AC700529352 /* SDL_drawpoint.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FC23E2514000DCD162 /* SDL_drawpoint.c */; }; A75FD05523E25AC700529352 /* e_sqrt.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92423E2514000DCD162 /* e_sqrt.c */; }; A75FD05623E25AC700529352 /* SDL_cocoavideo.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68523E2513E00DCD162 /* SDL_cocoavideo.m */; }; A75FD05823E25AC700529352 /* SDL.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57123E2513D00DCD162 /* SDL.c */; }; - A75FD05923E25AC700529352 /* SDL_x11opengl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FF23E2513E00DCD162 /* SDL_x11opengl.c */; }; A75FD05A23E25AC700529352 /* SDL_cocoavulkan.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68323E2513E00DCD162 /* SDL_cocoavulkan.m */; }; A75FD05B23E25AC700529352 /* SDL_uikitappdelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61E23E2513D00DCD162 /* SDL_uikitappdelegate.m */; }; A75FD05C23E25AC700529352 /* SDL_offscreenwindow.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5EF23E2513D00DCD162 /* SDL_offscreenwindow.c */; }; - A75FDAAA23E2792500529352 /* hid.m in Sources */ = {isa = PBXBuildFile; fileRef = A75FDAA523E2792500529352 /* hid.m */; }; - A75FDAAB23E2792500529352 /* hid.m in Sources */ = {isa = PBXBuildFile; fileRef = A75FDAA523E2792500529352 /* hid.m */; }; A75FDAAD23E2795C00529352 /* SDL_hidapi_steam.c in Sources */ = {isa = PBXBuildFile; fileRef = A75FDAAC23E2795C00529352 /* SDL_hidapi_steam.c */; }; A75FDAAE23E2795C00529352 /* SDL_hidapi_steam.c in Sources */ = {isa = PBXBuildFile; fileRef = A75FDAAC23E2795C00529352 /* SDL_hidapi_steam.c */; }; A75FDAAF23E2795C00529352 /* SDL_hidapi_steam.c in Sources */ = {isa = PBXBuildFile; fileRef = A75FDAAC23E2795C00529352 /* SDL_hidapi_steam.c */; }; A75FDAB023E2795C00529352 /* SDL_hidapi_steam.c in Sources */ = {isa = PBXBuildFile; fileRef = A75FDAAC23E2795C00529352 /* SDL_hidapi_steam.c */; }; A75FDAB123E2795C00529352 /* SDL_hidapi_steam.c in Sources */ = {isa = PBXBuildFile; fileRef = A75FDAAC23E2795C00529352 /* SDL_hidapi_steam.c */; }; A75FDAB223E2795C00529352 /* SDL_hidapi_steam.c in Sources */ = {isa = PBXBuildFile; fileRef = A75FDAAC23E2795C00529352 /* SDL_hidapi_steam.c */; }; - A75FDAB423E2797600529352 /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDAB323E2797600529352 /* CoreBluetooth.framework */; }; - A75FDAB623E2799700529352 /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDAB523E2799700529352 /* CoreBluetooth.framework */; }; A75FDABA23E28A7A00529352 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDAB923E28A7A00529352 /* AVFoundation.framework */; }; - A75FDABB23E28B1D00529352 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7D88BBB23E24A2F00DCD162 /* UIKit.framework */; }; - A75FDABC23E28B4000529352 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7D88BBF23E24A7700DCD162 /* OpenGLES.framework */; }; A75FDABE23E28B6200529352 /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDABD23E28B6200529352 /* GameController.framework */; }; A75FDAC023E28B8000529352 /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDABF23E28B8000529352 /* CoreMotion.framework */; }; A75FDAC223E28B9600529352 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDAC123E28B9600529352 /* CoreGraphics.framework */; }; A75FDAC423E28BA700529352 /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDAC323E28BA700529352 /* CoreBluetooth.framework */; }; - A75FDAC523E28BD800529352 /* SDL_sysjoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7AC23E2513E00DCD162 /* SDL_sysjoystick_c.h */; }; - A75FDAC623E28BD900529352 /* SDL_sysjoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7AB23E2513E00DCD162 /* SDL_sysjoystick.m */; }; - A75FDAC723E28BD900529352 /* SDL_sysjoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7AC23E2513E00DCD162 /* SDL_sysjoystick_c.h */; }; - A75FDAC823E28BD900529352 /* SDL_sysjoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7AB23E2513E00DCD162 /* SDL_sysjoystick.m */; }; - A75FDACA23E28D0200529352 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDAC923E28D0100529352 /* UIKit.framework */; }; - A75FDACC23E28D0700529352 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDACB23E28D0700529352 /* QuartzCore.framework */; }; - A75FDACE23E28D0F00529352 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDACD23E28D0F00529352 /* OpenGLES.framework */; }; - A75FDAD023E28D1300529352 /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDACF23E28D1300529352 /* Metal.framework */; }; - A75FDAD223E28D2000529352 /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDAD123E28D2000529352 /* GameController.framework */; }; - A75FDAD423E28D2E00529352 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDAD323E28D2E00529352 /* CoreVideo.framework */; }; - A75FDAD623E28D3300529352 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDAD523E28D3300529352 /* CoreGraphics.framework */; }; - A75FDAD823E28D3B00529352 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDAD723E28D3B00529352 /* CoreFoundation.framework */; }; - A75FDAD923E28D3F00529352 /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDAB523E2799700529352 /* CoreBluetooth.framework */; }; - A75FDADB23E28D4900529352 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDADA23E28D4900529352 /* CoreAudio.framework */; }; - A75FDADD23E28D5500529352 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDADC23E28D5500529352 /* AVFoundation.framework */; }; - A75FDADF23E28D6600529352 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDADE23E28D6600529352 /* AudioToolbox.framework */; }; A75FDAF623E35EC400529352 /* SDL_config_iphoneos.h in Headers */ = {isa = PBXBuildFile; fileRef = A75FDAF523E35EC400529352 /* SDL_config_iphoneos.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FDAF723E35EC400529352 /* SDL_config_iphoneos.h in Headers */ = {isa = PBXBuildFile; fileRef = A75FDAF523E35EC400529352 /* SDL_config_iphoneos.h */; settings = {ATTRIBUTES = (Public, ); }; }; A75FDAF823E35ED500529352 /* SDL_config_iphoneos.h in Headers */ = {isa = PBXBuildFile; fileRef = A75FDAF523E35EC400529352 /* SDL_config_iphoneos.h */; }; A75FDAF923E35ED500529352 /* SDL_config_iphoneos.h in Headers */ = {isa = PBXBuildFile; fileRef = A75FDAF523E35EC400529352 /* SDL_config_iphoneos.h */; }; A75FDAFA23E35ED600529352 /* SDL_config_iphoneos.h in Headers */ = {isa = PBXBuildFile; fileRef = A75FDAF523E35EC400529352 /* SDL_config_iphoneos.h */; }; A75FDAFB23E35ED700529352 /* SDL_config_iphoneos.h in Headers */ = {isa = PBXBuildFile; fileRef = A75FDAF523E35EC400529352 /* SDL_config_iphoneos.h */; }; - A75FDB5123E39D1700529352 /* hid.m in Sources */ = {isa = PBXBuildFile; fileRef = A75FDAA523E2792500529352 /* hid.m */; }; - A75FDB5223E39D1700529352 /* hid.m in Sources */ = {isa = PBXBuildFile; fileRef = A75FDAA523E2792500529352 /* hid.m */; }; - A75FDB5323E39D1C00529352 /* hid.m in Sources */ = {isa = PBXBuildFile; fileRef = A75FDAA523E2792500529352 /* hid.m */; }; - A75FDB5523E39DAC00529352 /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDAC323E28BA700529352 /* CoreBluetooth.framework */; }; - A75FDB5623E39DE900529352 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7D88BBB23E24A2F00DCD162 /* UIKit.framework */; }; A75FDB5823E39E6100529352 /* hidapi.h in Headers */ = {isa = PBXBuildFile; fileRef = A75FDB5723E39E6100529352 /* hidapi.h */; }; A75FDB5923E39E6100529352 /* hidapi.h in Headers */ = {isa = PBXBuildFile; fileRef = A75FDB5723E39E6100529352 /* hidapi.h */; }; A75FDB5A23E39E6100529352 /* hidapi.h in Headers */ = {isa = PBXBuildFile; fileRef = A75FDB5723E39E6100529352 /* hidapi.h */; }; @@ -909,38 +903,6 @@ A75FDB5E23E39E6100529352 /* hidapi.h in Headers */ = {isa = PBXBuildFile; fileRef = A75FDB5723E39E6100529352 /* hidapi.h */; }; A75FDB5F23E39E6100529352 /* hidapi.h in Headers */ = {isa = PBXBuildFile; fileRef = A75FDB5723E39E6100529352 /* hidapi.h */; }; A75FDB6023E39E6100529352 /* hidapi.h in Headers */ = {isa = PBXBuildFile; fileRef = A75FDB5723E39E6100529352 /* hidapi.h */; }; - A75FDB6123E39E6100529352 /* hidapi.h in Headers */ = {isa = PBXBuildFile; fileRef = A75FDB5723E39E6100529352 /* hidapi.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A75FDB6423E3A2C900529352 /* hidapi.h in Headers */ = {isa = PBXBuildFile; fileRef = A75FDB5723E39E6100529352 /* hidapi.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A75FDB6623E3A2C900529352 /* hid.m in Sources */ = {isa = PBXBuildFile; fileRef = A75FDAA523E2792500529352 /* hid.m */; }; - A75FDB6823E3A2C900529352 /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDAC323E28BA700529352 /* CoreBluetooth.framework */; }; - A75FDB6923E3A2C900529352 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7D88BBB23E24A2F00DCD162 /* UIKit.framework */; }; - A75FDB8223E4C74400529352 /* hidapi.h in Headers */ = {isa = PBXBuildFile; fileRef = A75FDB5723E39E6100529352 /* hidapi.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A75FDB8F23E4C80B00529352 /* SDL_hidapi.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A81423E2513F00DCD162 /* SDL_hidapi.c */; }; - A75FDB9023E4C80D00529352 /* SDL_hidapi.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A81423E2513F00DCD162 /* SDL_hidapi.c */; }; - A75FDB9323E4C8DB00529352 /* hid.c in Sources */ = {isa = PBXBuildFile; fileRef = A75FDB9223E4C8DB00529352 /* hid.c */; }; - A75FDB9423E4C91300529352 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0073179F0858DECD00B2BC32 /* IOKit.framework */; }; - A75FDB9523E4C93600529352 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00D0D08310675DD9004B05EF /* CoreFoundation.framework */; }; - A75FDB9A23E4CAEF00529352 /* hidapi.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDB8C23E4C74400529352 /* hidapi.framework */; }; - A75FDB9B23E4CAEF00529352 /* hidapi.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDB8C23E4C74400529352 /* hidapi.framework */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - A75FDB9D23E4CAFA00529352 /* hidapi.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDB4923E399AC00529352 /* hidapi.framework */; }; - A75FDB9E23E4CAFA00529352 /* hidapi.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDB4923E399AC00529352 /* hidapi.framework */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - A75FDBA023E4CAFF00529352 /* hidapi.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDB6E23E3A2C900529352 /* hidapi.framework */; }; - A75FDBA123E4CAFF00529352 /* hidapi.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDB6E23E3A2C900529352 /* hidapi.framework */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - A75FDBA823E4CB7000529352 /* LICENSE-bsd.txt in Resources */ = {isa = PBXBuildFile; fileRef = A75FDBA323E4CB6F00529352 /* LICENSE-bsd.txt */; }; - A75FDBA923E4CB7000529352 /* LICENSE-bsd.txt in Resources */ = {isa = PBXBuildFile; fileRef = A75FDBA323E4CB6F00529352 /* LICENSE-bsd.txt */; }; - A75FDBAA23E4CB7000529352 /* LICENSE-bsd.txt in Resources */ = {isa = PBXBuildFile; fileRef = A75FDBA323E4CB6F00529352 /* LICENSE-bsd.txt */; }; - A75FDBAB23E4CB7000529352 /* AUTHORS.txt in Resources */ = {isa = PBXBuildFile; fileRef = A75FDBA423E4CB6F00529352 /* AUTHORS.txt */; }; - A75FDBAC23E4CB7000529352 /* AUTHORS.txt in Resources */ = {isa = PBXBuildFile; fileRef = A75FDBA423E4CB6F00529352 /* AUTHORS.txt */; }; - A75FDBAD23E4CB7000529352 /* AUTHORS.txt in Resources */ = {isa = PBXBuildFile; fileRef = A75FDBA423E4CB6F00529352 /* AUTHORS.txt */; }; - A75FDBAE23E4CB7000529352 /* LICENSE-orig.txt in Resources */ = {isa = PBXBuildFile; fileRef = A75FDBA523E4CB6F00529352 /* LICENSE-orig.txt */; }; - A75FDBAF23E4CB7000529352 /* LICENSE-orig.txt in Resources */ = {isa = PBXBuildFile; fileRef = A75FDBA523E4CB6F00529352 /* LICENSE-orig.txt */; }; - A75FDBB023E4CB7000529352 /* LICENSE-orig.txt in Resources */ = {isa = PBXBuildFile; fileRef = A75FDBA523E4CB6F00529352 /* LICENSE-orig.txt */; }; - A75FDBB123E4CB7000529352 /* LICENSE-gpl3.txt in Resources */ = {isa = PBXBuildFile; fileRef = A75FDBA623E4CB6F00529352 /* LICENSE-gpl3.txt */; }; - A75FDBB223E4CB7000529352 /* LICENSE-gpl3.txt in Resources */ = {isa = PBXBuildFile; fileRef = A75FDBA623E4CB6F00529352 /* LICENSE-gpl3.txt */; }; - A75FDBB323E4CB7000529352 /* LICENSE-gpl3.txt in Resources */ = {isa = PBXBuildFile; fileRef = A75FDBA623E4CB6F00529352 /* LICENSE-gpl3.txt */; }; - A75FDBB423E4CB7000529352 /* LICENSE.txt in Resources */ = {isa = PBXBuildFile; fileRef = A75FDBA723E4CB6F00529352 /* LICENSE.txt */; }; - A75FDBB523E4CB7000529352 /* LICENSE.txt in Resources */ = {isa = PBXBuildFile; fileRef = A75FDBA723E4CB6F00529352 /* LICENSE.txt */; }; - A75FDBB623E4CB7000529352 /* LICENSE.txt in Resources */ = {isa = PBXBuildFile; fileRef = A75FDBA723E4CB6F00529352 /* LICENSE.txt */; }; A75FDBB723E4CBC700529352 /* License.txt in Resources */ = {isa = PBXBuildFile; fileRef = 00794D3F09D0C461003FC8A1 /* License.txt */; }; A75FDBB823E4CBC700529352 /* ReadMe.txt in Resources */ = {isa = PBXBuildFile; fileRef = F59C710300D5CB5801000001 /* ReadMe.txt */; }; A75FDBB923E4CBC700529352 /* License.txt in Resources */ = {isa = PBXBuildFile; fileRef = 00794D3F09D0C461003FC8A1 /* License.txt */; }; @@ -966,88 +928,50 @@ A75FDBD523EA380300529352 /* SDL_hidapi_rumble.c in Sources */ = {isa = PBXBuildFile; fileRef = A75FDBC423EA380300529352 /* SDL_hidapi_rumble.c */; }; A75FDBD623EA380300529352 /* SDL_hidapi_rumble.c in Sources */ = {isa = PBXBuildFile; fileRef = A75FDBC423EA380300529352 /* SDL_hidapi_rumble.c */; }; A769B08423E259AE00872273 /* SDL_shaders_metal_tvos.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8E323E2514000DCD162 /* SDL_shaders_metal_tvos.h */; }; - A769B08523E259AE00872273 /* SDL_filesystem.h in Headers */ = {isa = PBXBuildFile; fileRef = 567E2F2017C44C35005F1892 /* SDL_filesystem.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A769B08723E259AE00872273 /* begin_code.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557C71595D4D800BBD41B /* begin_code.h */; settings = {ATTRIBUTES = (Public, ); }; }; A769B08823E259AE00872273 /* SDL_uikitopengles.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A63123E2513D00DCD162 /* SDL_uikitopengles.h */; }; - A769B08923E259AE00872273 /* close_code.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557C81595D4D800BBD41B /* close_code.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A769B08A23E259AE00872273 /* SDL.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F91595D4D800BBD41B /* SDL.h */; settings = {ATTRIBUTES = (Public, ); }; }; A769B08B23E259AE00872273 /* SDL_uikitmetalview.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A61D23E2513D00DCD162 /* SDL_uikitmetalview.h */; }; - A769B08C23E259AE00872273 /* SDL_assert.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557C91595D4D800BBD41B /* SDL_assert.h */; settings = {ATTRIBUTES = (Public, ); }; }; A769B08D23E259AE00872273 /* SDL_shape_internals.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60D23E2513D00DCD162 /* SDL_shape_internals.h */; }; A769B08E23E259AE00872273 /* SDL_glfuncs.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90E23E2514000DCD162 /* SDL_glfuncs.h */; }; - A769B08F23E259AE00872273 /* SDL_atomic.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557CA1595D4D800BBD41B /* SDL_atomic.h */; settings = {ATTRIBUTES = (Public, ); }; }; A769B09023E259AE00872273 /* SDL_rect_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60C23E2513D00DCD162 /* SDL_rect_c.h */; }; - A769B09123E259AE00872273 /* SDL_x11xinput2.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71323E2513E00DCD162 /* SDL_x11xinput2.h */; }; A769B09223E259AE00872273 /* SDL_shaders_metal_osx.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8E223E2514000DCD162 /* SDL_shaders_metal_osx.h */; }; A769B09323E259AE00872273 /* SDL_shaders_metal_ios.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8DF23E2514000DCD162 /* SDL_shaders_metal_ios.h */; }; A769B09423E259AE00872273 /* SDL_offscreenwindow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5F523E2513D00DCD162 /* SDL_offscreenwindow.h */; }; - A769B09523E259AE00872273 /* SDL_audio.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557CB1595D4D800BBD41B /* SDL_audio.h */; settings = {ATTRIBUTES = (Public, ); }; }; A769B09623E259AE00872273 /* SDL_coremotionsensor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57B23E2513D00DCD162 /* SDL_coremotionsensor.h */; }; A769B09723E259AE00872273 /* SDL_uikitview.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A61923E2513D00DCD162 /* SDL_uikitview.h */; }; - A769B09823E259AE00872273 /* SDL_bits.h in Headers */ = {isa = PBXBuildFile; fileRef = AADA5B8616CCAB3000107CF7 /* SDL_bits.h */; settings = {ATTRIBUTES = (Public, ); }; }; A769B09923E259AE00872273 /* SDL_uikitappdelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62F23E2513D00DCD162 /* SDL_uikitappdelegate.h */; }; - A769B09A23E259AE00872273 /* keyinfotable.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62823E2513D00DCD162 /* keyinfotable.h */; }; - A769B09B23E259AE00872273 /* SDL_blendmode.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557CC1595D4D800BBD41B /* SDL_blendmode.h */; settings = {ATTRIBUTES = (Public, ); }; }; A769B09C23E259AE00872273 /* SDL_dropevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A92E23E2514000DCD162 /* SDL_dropevents_c.h */; }; A769B09D23E259AE00872273 /* SDL_haptic_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5C623E2513D00DCD162 /* SDL_haptic_c.h */; }; - A769B09E23E259AE00872273 /* SDL_clipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557CD1595D4D800BBD41B /* SDL_clipboard.h */; settings = {ATTRIBUTES = (Public, ); }; }; A769B09F23E259AE00872273 /* SDL_dataqueue.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57023E2513D00DCD162 /* SDL_dataqueue.h */; }; A769B0A023E259AE00872273 /* SDL_error_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57523E2513D00DCD162 /* SDL_error_c.h */; }; - A769B0A123E259AE00872273 /* SDL_x11events.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71E23E2513E00DCD162 /* SDL_x11events.h */; }; - A769B0A223E259AE00872273 /* SDL_config.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557CF1595D4D800BBD41B /* SDL_config.h */; settings = {ATTRIBUTES = (Public, ); }; }; A769B0A323E259AE00872273 /* SDL_d3dmath.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8DC23E2514000DCD162 /* SDL_d3dmath.h */; }; - A769B0A423E259AE00872273 /* SDL_x11window.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71723E2513E00DCD162 /* SDL_x11window.h */; }; A769B0A623E259AE00872273 /* SDL_egl_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60423E2513D00DCD162 /* SDL_egl_c.h */; }; - A769B0A723E259AE00872273 /* SDL_copying.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D01595D4D800BBD41B /* SDL_copying.h */; settings = {ATTRIBUTES = (Public, ); }; }; A769B0A823E259AE00872273 /* yuv_rgb.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77223E2513E00DCD162 /* yuv_rgb.h */; }; A769B0A923E259AE00872273 /* SDL_dummyaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A87123E2513F00DCD162 /* SDL_dummyaudio.h */; }; A769B0AA23E259AE00872273 /* SDL_uikitmessagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62623E2513D00DCD162 /* SDL_uikitmessagebox.h */; }; - A769B0AB23E259AE00872273 /* SDL_x11messagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A6FD23E2513E00DCD162 /* SDL_x11messagebox.h */; }; A769B0AC23E259AE00872273 /* SDL_thread_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77823E2513E00DCD162 /* SDL_thread_c.h */; }; A769B0AD23E259AE00872273 /* SDL_cocoamessagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69423E2513E00DCD162 /* SDL_cocoamessagebox.h */; }; - A769B0AE23E259AE00872273 /* SDL_x11shape.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70123E2513E00DCD162 /* SDL_x11shape.h */; }; - A769B0AF23E259AE00872273 /* SDL_cpuinfo.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D11595D4D800BBD41B /* SDL_cpuinfo.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A769B0B023E259AE00872273 /* SDL_endian.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D21595D4D800BBD41B /* SDL_endian.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A769B0B123E259AE00872273 /* SDL_error.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D31595D4D800BBD41B /* SDL_error.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A769B0B223E259AE00872273 /* SDL_events.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D41595D4D800BBD41B /* SDL_events.h */; settings = {ATTRIBUTES = (Public, ); }; }; A769B0B323E259AE00872273 /* SDL_blendfillrect.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F623E2514000DCD162 /* SDL_blendfillrect.h */; }; - A769B0B423E259AE00872273 /* SDL_gamecontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = A77E6EB3167AB0A90010E40B /* SDL_gamecontroller.h */; settings = {ATTRIBUTES = (Public, ); }; }; A769B0B523E259AE00872273 /* SDL_hidapijoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7C723E2513E00DCD162 /* SDL_hidapijoystick_c.h */; }; A769B0B623E259AE00872273 /* SDL_pixels_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A74023E2513E00DCD162 /* SDL_pixels_c.h */; }; - A769B0B723E259AE00872273 /* SDL_x11modes.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70F23E2513E00DCD162 /* SDL_x11modes.h */; }; A769B0B823E259AE00872273 /* SDL_joystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7D023E2513E00DCD162 /* SDL_joystick_c.h */; }; A769B0B923E259AE00872273 /* vk_sdk_platform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73D23E2513E00DCD162 /* vk_sdk_platform.h */; }; A769B0BA23E259AE00872273 /* blank_cursor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93223E2514000DCD162 /* blank_cursor.h */; }; - A769B0BB23E259AE00872273 /* SDL_gesture.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D51595D4D800BBD41B /* SDL_gesture.h */; settings = {ATTRIBUTES = (Public, ); }; }; A769B0BC23E259AE00872273 /* SDL_sysaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A89F23E2513F00DCD162 /* SDL_sysaudio.h */; }; - A769B0BD23E259AE00872273 /* SDL_haptic.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D61595D4D800BBD41B /* SDL_haptic.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A769B0BE23E259AE00872273 /* SDL_sysevents.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93F23E2514000DCD162 /* SDL_sysevents.h */; }; A769B0BF23E259AE00872273 /* math_libm.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A92623E2514000DCD162 /* math_libm.h */; }; A769B0C023E259AE00872273 /* SDL_uikitvideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62223E2513D00DCD162 /* SDL_uikitvideo.h */; }; A769B0C123E259AE00872273 /* SDL_cocoamouse.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69823E2513E00DCD162 /* SDL_cocoamouse.h */; }; - A769B0C223E259AE00872273 /* SDL_hints.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D71595D4D800BBD41B /* SDL_hints.h */; settings = {ATTRIBUTES = (Public, ); }; }; A769B0C323E259AE00872273 /* SDL_blit_slow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A66323E2513E00DCD162 /* SDL_blit_slow.h */; }; A769B0C423E259AE00872273 /* SDL_yuv_sw_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8EC23E2514000DCD162 /* SDL_yuv_sw_c.h */; }; - A769B0C523E259AE00872273 /* SDL_x11opengl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70E23E2513E00DCD162 /* SDL_x11opengl.h */; }; A769B0C623E259AE00872273 /* SDL_windowevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A94323E2514000DCD162 /* SDL_windowevents_c.h */; }; - A769B0C723E259AE00872273 /* SDL_joystick.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D91595D4D800BBD41B /* SDL_joystick.h */; settings = {ATTRIBUTES = (Public, ); }; }; A769B0C823E259AE00872273 /* SDL_cocoavideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69323E2513E00DCD162 /* SDL_cocoavideo.h */; }; - A769B0C923E259AE00872273 /* SDL_keyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557DA1595D4D800BBD41B /* SDL_keyboard.h */; settings = {ATTRIBUTES = (Public, ); }; }; A769B0CA23E259AE00872273 /* SDL_uikitevents.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62D23E2513D00DCD162 /* SDL_uikitevents.h */; }; A769B0CB23E259AE00872273 /* SDL_gesture_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93023E2514000DCD162 /* SDL_gesture_c.h */; }; A769B0CC23E259AE00872273 /* SDL_shaders_gl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90D23E2514000DCD162 /* SDL_shaders_gl.h */; }; A769B0CD23E259AE00872273 /* SDL_systhread_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A78423E2513E00DCD162 /* SDL_systhread_c.h */; }; - A769B0CE23E259AE00872273 /* SDL_keycode.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557DB1595D4D800BBD41B /* SDL_keycode.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A769B0CF23E259AE00872273 /* SDL_x11keyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71C23E2513E00DCD162 /* SDL_x11keyboard.h */; }; A769B0D023E259AE00872273 /* SDL_cocoakeyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68023E2513E00DCD162 /* SDL_cocoakeyboard.h */; }; A769B0D123E259AE00872273 /* SDL_uikitvulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A63323E2513D00DCD162 /* SDL_uikitvulkan.h */; }; - A769B0D223E259AE00872273 /* SDL_x11framebuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71823E2513E00DCD162 /* SDL_x11framebuffer.h */; }; - A769B0D323E259AE00872273 /* SDL_x11video.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72023E2513E00DCD162 /* SDL_x11video.h */; }; - A769B0D423E259AE00872273 /* vulkan.hpp in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73223E2513E00DCD162 /* vulkan.hpp */; }; - A769B0D523E259AE00872273 /* SDL_loadso.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557DC1595D4D800BBD41B /* SDL_loadso.h */; settings = {ATTRIBUTES = (Public, ); }; }; A769B0D623E259AE00872273 /* gl2ext.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72323E2513E00DCD162 /* gl2ext.h */; }; A769B0D723E259AE00872273 /* SDL_clipboardevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93923E2514000DCD162 /* SDL_clipboardevents_c.h */; }; - A769B0D823E259AE00872273 /* SDL_x11touch.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A6FC23E2513E00DCD162 /* SDL_x11touch.h */; }; A769B0D923E259AE00872273 /* SDL_syshaptic_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5CF23E2513D00DCD162 /* SDL_syshaptic_c.h */; }; A769B0DA23E259AE00872273 /* SDL_hints_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8D123E2514000DCD162 /* SDL_hints_c.h */; }; A769B0DB23E259AE00872273 /* SDL_audiodev_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A87723E2513F00DCD162 /* SDL_audiodev_c.h */; }; @@ -1055,7 +979,6 @@ A769B0DD23E259AE00872273 /* SDL_uikitmodes.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A61F23E2513D00DCD162 /* SDL_uikitmodes.h */; }; A769B0DE23E259AE00872273 /* egl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72923E2513E00DCD162 /* egl.h */; }; A769B0DF23E259AE00872273 /* khrplatform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72723E2513E00DCD162 /* khrplatform.h */; }; - A769B0E023E259AE00872273 /* SDL_log.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557DD1595D4D800BBD41B /* SDL_log.h */; settings = {ATTRIBUTES = (Public, ); }; }; A769B0E123E259AE00872273 /* SDL_uikitviewcontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62423E2513D00DCD162 /* SDL_uikitviewcontroller.h */; }; A769B0E223E259AE00872273 /* SDL_dummysensor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57823E2513D00DCD162 /* SDL_dummysensor.h */; }; A769B0E423E259AE00872273 /* SDL_steamcontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7A523E2513E00DCD162 /* SDL_steamcontroller.h */; }; @@ -1066,49 +989,34 @@ A769B0E923E259AE00872273 /* SDL_dynapi.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5D823E2513D00DCD162 /* SDL_dynapi.h */; }; A769B0EA23E259AE00872273 /* SDL_assert_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7F523E2513F00DCD162 /* SDL_assert_c.h */; }; A769B0EB23E259AE00872273 /* SDL_diskaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8B023E2513F00DCD162 /* SDL_diskaudio.h */; }; - A769B0EC23E259AE00872273 /* SDL_main.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557DE1595D4D800BBD41B /* SDL_main.h */; settings = {ATTRIBUTES = (Public, ); }; }; A769B0ED23E259AE00872273 /* SDL_drawpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F323E2514000DCD162 /* SDL_drawpoint.h */; }; - A769B0EE23E259AE00872273 /* SDL_opengles2_khrplatform.h in Headers */ = {isa = PBXBuildFile; fileRef = AAC070F8195606770073DCDF /* SDL_opengles2_khrplatform.h */; settings = {ATTRIBUTES = (Public, ); }; }; A769B0EF23E259AE00872273 /* SDL_wave.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8A223E2513F00DCD162 /* SDL_wave.h */; }; A769B0F023E259AE00872273 /* SDL_cocoaopengl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68D23E2513E00DCD162 /* SDL_cocoaopengl.h */; }; A769B0F123E259AE00872273 /* yuv_rgb_sse_func.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77023E2513E00DCD162 /* yuv_rgb_sse_func.h */; }; - A769B0F223E259AE00872273 /* imKStoUCS.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71F23E2513E00DCD162 /* imKStoUCS.h */; }; A769B0F323E259AE00872273 /* SDL_offscreenevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5EE23E2513D00DCD162 /* SDL_offscreenevents_c.h */; }; - A769B0F423E259AE00872273 /* SDL_x11sym.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70D23E2513E00DCD162 /* SDL_x11sym.h */; }; A769B0F523E259AE00872273 /* SDL_coreaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8BA23E2513F00DCD162 /* SDL_coreaudio.h */; }; A769B0F623E259AE00872273 /* SDL_draw.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8FA23E2514000DCD162 /* SDL_draw.h */; }; A769B0F723E259AE00872273 /* SDL_drawline.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F723E2514000DCD162 /* SDL_drawline.h */; }; - A769B0F823E259AE00872273 /* SDL_messagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = AA9FF9591637CBF9000DF050 /* SDL_messagebox.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A769B0F923E259AE00872273 /* SDL_mouse.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557DF1595D4D800BBD41B /* SDL_mouse.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A769B0FA23E259AE00872273 /* SDL_mutex.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E01595D4D800BBD41B /* SDL_mutex.h */; settings = {ATTRIBUTES = (Public, ); }; }; A769B0FB23E259AE00872273 /* SDL_yuv_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76A23E2513E00DCD162 /* SDL_yuv_c.h */; }; A769B0FC23E259AE00872273 /* scancodes_xfree86.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A94123E2514000DCD162 /* scancodes_xfree86.h */; }; A769B0FD23E259AE00872273 /* SDL_syspower.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7E223E2513F00DCD162 /* SDL_syspower.h */; }; - A769B0FE23E259AE00872273 /* SDL_x11clipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71D23E2513E00DCD162 /* SDL_x11clipboard.h */; }; - A769B0FF23E259AE00872273 /* SDL_name.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E11595D4D800BBD41B /* SDL_name.h */; settings = {ATTRIBUTES = (Public, ); }; }; A769B10023E259AE00872273 /* eglext.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72A23E2513E00DCD162 /* eglext.h */; }; A769B10123E259AE00872273 /* SDL_events_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A94223E2514000DCD162 /* SDL_events_c.h */; }; A769B10223E259AE00872273 /* math_private.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A91B23E2514000DCD162 /* math_private.h */; }; A769B10323E259AE00872273 /* vulkan_wayland.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73423E2513E00DCD162 /* vulkan_wayland.h */; }; - A769B10423E259AE00872273 /* SDL_opengl.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E21595D4D800BBD41B /* SDL_opengl.h */; settings = {ATTRIBUTES = (Public, ); }; }; A769B10523E259AE00872273 /* SDL_cocoashape.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A67E23E2513E00DCD162 /* SDL_cocoashape.h */; }; - A769B10623E259AE00872273 /* SDL_opengles.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E31595D4D800BBD41B /* SDL_opengles.h */; settings = {ATTRIBUTES = (Public, ); }; }; A769B10723E259AE00872273 /* SDL_shaders_gles2.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90523E2514000DCD162 /* SDL_shaders_gles2.h */; }; - A769B10823E259AE00872273 /* SDL_opengles2.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E41595D4D800BBD41B /* SDL_opengles2.h */; settings = {ATTRIBUTES = (Public, ); }; }; A769B10923E259AE00872273 /* SDL_glesfuncs.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90223E2514000DCD162 /* SDL_glesfuncs.h */; }; A769B10A23E259AE00872273 /* SDL_blendpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F823E2514000DCD162 /* SDL_blendpoint.h */; }; A769B10B23E259AE00872273 /* SDL_offscreenvideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5F123E2513D00DCD162 /* SDL_offscreenvideo.h */; }; A769B10C23E259AE00872273 /* SDL_nullevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60B23E2513D00DCD162 /* SDL_nullevents_c.h */; }; A769B10D23E259AE00872273 /* SDL_sysjoystick.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7CF23E2513E00DCD162 /* SDL_sysjoystick.h */; }; A769B10E23E259AE00872273 /* scancodes_linux.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93623E2514000DCD162 /* scancodes_linux.h */; }; - A769B10F23E259AE00872273 /* SDL_x11dyn.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71923E2513E00DCD162 /* SDL_x11dyn.h */; }; A769B11023E259AE00872273 /* SDL_touch_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93723E2514000DCD162 /* SDL_touch_c.h */; }; A769B11123E259AE00872273 /* SDL_gamecontrollerdb.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A79E23E2513E00DCD162 /* SDL_gamecontrollerdb.h */; }; A769B11223E259AE00872273 /* SDL_cocoavulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68F23E2513E00DCD162 /* SDL_cocoavulkan.h */; }; A769B11323E259AE00872273 /* gl2platform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72523E2513E00DCD162 /* gl2platform.h */; }; - A769B11423E259AE00872273 /* SDL_pixels.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E51595D4D800BBD41B /* SDL_pixels.h */; settings = {ATTRIBUTES = (Public, ); }; }; A769B11523E259AE00872273 /* vk_layer.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72D23E2513E00DCD162 /* vk_layer.h */; }; - A769B11723E259AE00872273 /* SDL_cocoamousetap.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68823E2513E00DCD162 /* SDL_cocoamousetap.h */; }; A769B11823E259AE00872273 /* vk_platform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73123E2513E00DCD162 /* vk_platform.h */; }; A769B11A23E259AE00872273 /* SDL_cocoametalview.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68623E2513E00DCD162 /* SDL_cocoametalview.h */; }; A769B11B23E259AE00872273 /* SDL_cocoaopengles.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69023E2513E00DCD162 /* SDL_cocoaopengles.h */; }; @@ -1117,31 +1025,19 @@ A769B11E23E259AE00872273 /* SDL_sensor_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A58123E2513D00DCD162 /* SDL_sensor_c.h */; }; A769B11F23E259AE00872273 /* SDL_sysrender.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8EE23E2514000DCD162 /* SDL_sysrender.h */; }; A769B12023E259AE00872273 /* SDL_rotate.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8FE23E2514000DCD162 /* SDL_rotate.h */; }; - A769B12123E259AE00872273 /* SDL_platform.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E61595D4D800BBD41B /* SDL_platform.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A769B12223E259AE00872273 /* SDL_power.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E71595D4D800BBD41B /* SDL_power.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A769B12323E259AE00872273 /* SDL_offscreenopengl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5F323E2513D00DCD162 /* SDL_offscreenopengl.h */; }; A769B12523E259AE00872273 /* scancodes_darwin.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93423E2514000DCD162 /* scancodes_darwin.h */; }; A769B12623E259AE00872273 /* controller_type.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7D923E2513E00DCD162 /* controller_type.h */; }; - A769B12723E259AE00872273 /* SDL_x11opengles.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70323E2513E00DCD162 /* SDL_x11opengles.h */; }; A769B12823E259AE00872273 /* SDL_uikitclipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62123E2513D00DCD162 /* SDL_uikitclipboard.h */; }; A769B12923E259AE00872273 /* vulkan_xlib.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73A23E2513E00DCD162 /* vulkan_xlib.h */; }; A769B12A23E259AE00872273 /* SDL_uikitwindow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62723E2513D00DCD162 /* SDL_uikitwindow.h */; }; A769B12B23E259AE00872273 /* vulkan_vi.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72F23E2513E00DCD162 /* vulkan_vi.h */; }; - A769B12C23E259AE00872273 /* vulkan_mir.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73923E2513E00DCD162 /* vulkan_mir.h */; }; - A769B12D23E259AE00872273 /* SDL_quit.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E81595D4D800BBD41B /* SDL_quit.h */; settings = {ATTRIBUTES = (Public, ); }; }; A769B12E23E259AE00872273 /* default_cursor.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93323E2514000DCD162 /* default_cursor.h */; }; A769B12F23E259AE00872273 /* SDL_render_sw_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F523E2514000DCD162 /* SDL_render_sw_c.h */; }; - A769B13023E259AE00872273 /* SDL_rect.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E91595D4D800BBD41B /* SDL_rect.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A769B13123E259AE00872273 /* SDL_render.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557EA1595D4D800BBD41B /* SDL_render.h */; settings = {ATTRIBUTES = (Public, ); }; }; A769B13223E259AE00872273 /* SDL_nullvideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60A23E2513D00DCD162 /* SDL_nullvideo.h */; }; A769B13323E259AE00872273 /* SDL_blit_copy.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76623E2513E00DCD162 /* SDL_blit_copy.h */; }; A769B13423E259AE00872273 /* SDL_RLEaccel_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76723E2513E00DCD162 /* SDL_RLEaccel_c.h */; }; A769B13523E259AE00872273 /* eglplatform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72B23E2513E00DCD162 /* eglplatform.h */; }; - A769B13623E259AE00872273 /* edid.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71423E2513E00DCD162 /* edid.h */; }; - A769B13723E259AE00872273 /* SDL_revision.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557EB1595D4D800BBD41B /* SDL_revision.h */; settings = {ATTRIBUTES = (Public, ); }; }; A769B13823E259AE00872273 /* SDL_systhread.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77723E2513E00DCD162 /* SDL_systhread.h */; }; - A769B13923E259AE00872273 /* SDL_rwops.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557EC1595D4D800BBD41B /* SDL_rwops.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A769B13A23E259AE00872273 /* SDL_scancode.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557ED1595D4D800BBD41B /* SDL_scancode.h */; settings = {ATTRIBUTES = (Public, ); }; }; A769B13B23E259AE00872273 /* SDL_cocoaclipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68A23E2513E00DCD162 /* SDL_cocoaclipboard.h */; }; A769B13C23E259AE00872273 /* SDL_cocoamodes.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69123E2513E00DCD162 /* SDL_cocoamodes.h */; }; A769B13D23E259AE00872273 /* SDL_uikitopenglview.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62B23E2513D00DCD162 /* SDL_uikitopenglview.h */; }; @@ -1158,43 +1054,23 @@ A769B14823E259AE00872273 /* vulkan_xcb.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73823E2513E00DCD162 /* vulkan_xcb.h */; }; A769B14923E259AE00872273 /* vulkan_ios.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73B23E2513E00DCD162 /* vulkan_ios.h */; }; A769B14A23E259AE00872273 /* SDL_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A58323E2513D00DCD162 /* SDL_internal.h */; }; - A769B14B23E259AE00872273 /* SDL_shape.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557EE1595D4D800BBD41B /* SDL_shape.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A769B14C23E259AE00872273 /* SDL_stdinc.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557EF1595D4D800BBD41B /* SDL_stdinc.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A769B14D23E259AE00872273 /* SDL_surface.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F01595D4D800BBD41B /* SDL_surface.h */; settings = {ATTRIBUTES = (Public, ); }; }; A769B14E23E259AE00872273 /* vulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73023E2513E00DCD162 /* vulkan.h */; }; A769B14F23E259AE00872273 /* SDL_keyboard_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93D23E2514000DCD162 /* SDL_keyboard_c.h */; }; - A769B15023E259AE00872273 /* SDL_system.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F11595D4D800BBD41B /* SDL_system.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A769B15123E259AE00872273 /* SDL_syswm.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F21595D4D800BBD41B /* SDL_syswm.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A769B15223E259AE00872273 /* SDL_opengl_glext.h in Headers */ = {isa = PBXBuildFile; fileRef = AAC070F4195606770073DCDF /* SDL_opengl_glext.h */; settings = {ATTRIBUTES = (Public, ); }; }; A769B15323E259AE00872273 /* SDL_mouse_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A92B23E2514000DCD162 /* SDL_mouse_c.h */; }; A769B15423E259AE00872273 /* SDL_blit_auto.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73F23E2513E00DCD162 /* SDL_blit_auto.h */; }; A769B15523E259AE00872273 /* SDL_blendline.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A8F223E2514000DCD162 /* SDL_blendline.h */; }; A769B15623E259AE00872273 /* SDL_syshaptic.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5CC23E2513D00DCD162 /* SDL_syshaptic.h */; }; A769B15723E259AE00872273 /* SDL_vulkan_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A63E23E2513D00DCD162 /* SDL_vulkan_internal.h */; }; - A769B15823E259AE00872273 /* SDL_thread.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F31595D4D800BBD41B /* SDL_thread.h */; settings = {ATTRIBUTES = (Public, ); }; }; A769B15923E259AE00872273 /* SDL_cocoaevents.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69623E2513E00DCD162 /* SDL_cocoaevents.h */; }; A769B15A23E259AE00872273 /* vk_icd.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72E23E2513E00DCD162 /* vk_icd.h */; }; A769B15B23E259AE00872273 /* SDL_nullframebuffer_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A60723E2513D00DCD162 /* SDL_nullframebuffer_c.h */; }; - A769B15C23E259AE00872273 /* SDL_timer.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F41595D4D800BBD41B /* SDL_timer.h */; settings = {ATTRIBUTES = (Public, ); }; }; A769B15D23E259AE00872273 /* SDL_dynapi_procs.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5DB23E2513D00DCD162 /* SDL_dynapi_procs.h */; }; A769B15E23E259AE00872273 /* vulkan_fuchsia.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73323E2513E00DCD162 /* vulkan_fuchsia.h */; }; - A769B15F23E259AE00872273 /* SDL_touch.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F51595D4D800BBD41B /* SDL_touch.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A769B16023E259AE00872273 /* SDL_types.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F61595D4D800BBD41B /* SDL_types.h */; settings = {ATTRIBUTES = (Public, ); }; }; A769B16123E259AE00872273 /* usb_ids.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7CB23E2513E00DCD162 /* usb_ids.h */; }; - A769B16223E259AE00872273 /* SDL_sysjoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7AC23E2513E00DCD162 /* SDL_sysjoystick_c.h */; }; A769B16323E259AE00872273 /* SDL_gles2funcs.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A90623E2514000DCD162 /* SDL_gles2funcs.h */; }; - A769B16423E259AE00872273 /* SDL_sysjoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7CE23E2513E00DCD162 /* SDL_sysjoystick_c.h */; }; - A769B16523E259AE00872273 /* SDL_version.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F71595D4D800BBD41B /* SDL_version.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A769B16623E259AE00872273 /* SDL_video.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F81595D4D800BBD41B /* SDL_video.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A769B16723E259AE00872273 /* SDL_opengles2_gl2.h in Headers */ = {isa = PBXBuildFile; fileRef = AAC070F5195606770073DCDF /* SDL_opengles2_gl2.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A769B16823E259AE00872273 /* SDL_sensor.h in Headers */ = {isa = PBXBuildFile; fileRef = F3950CD7212BC88D00F51292 /* SDL_sensor.h */; settings = {ATTRIBUTES = (Public, ); }; }; A769B16923E259AE00872273 /* SDL_sysvideo.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A61723E2513D00DCD162 /* SDL_sysvideo.h */; }; - A769B16A23E259AE00872273 /* SDL_opengles2_gl2platform.h in Headers */ = {isa = PBXBuildFile; fileRef = AAC070F7195606770073DCDF /* SDL_opengles2_gl2platform.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A769B16B23E259AE00872273 /* SDL_opengles2_gl2ext.h in Headers */ = {isa = PBXBuildFile; fileRef = AAC070F6195606770073DCDF /* SDL_opengles2_gl2ext.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A769B16C23E259AE00872273 /* SDL_x11mouse.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71A23E2513E00DCD162 /* SDL_x11mouse.h */; }; A769B16D23E259AE00872273 /* SDL_dynapi_overrides.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5D923E2513D00DCD162 /* SDL_dynapi_overrides.h */; }; A769B16E23E259AE00872273 /* SDL_cocoawindow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69223E2513E00DCD162 /* SDL_cocoawindow.h */; }; - A769B16F23E259AE00872273 /* SDL_x11vulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71523E2513E00DCD162 /* SDL_x11vulkan.h */; }; A769B17123E259AE00872273 /* SDL_drawline.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F123E2514000DCD162 /* SDL_drawline.c */; }; A769B17223E259AE00872273 /* SDL_yuv.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A67C23E2513E00DCD162 /* SDL_yuv.c */; }; A769B17323E259AE00872273 /* SDL_sysfilesystem.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7FE23E2513F00DCD162 /* SDL_sysfilesystem.m */; }; @@ -1207,23 +1083,19 @@ A769B17A23E259AE00872273 /* SDL_render_metal.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8DE23E2514000DCD162 /* SDL_render_metal.m */; }; A769B17B23E259AE00872273 /* SDL_clipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A67B23E2513E00DCD162 /* SDL_clipboard.c */; }; A769B17C23E259AE00872273 /* SDL_cocoaevents.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68923E2513E00DCD162 /* SDL_cocoaevents.m */; }; - A769B17D23E259AE00872273 /* SDL_x11messagebox.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71023E2513E00DCD162 /* SDL_x11messagebox.c */; }; A769B17E23E259AE00872273 /* SDL_audiocvt.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8A123E2513F00DCD162 /* SDL_audiocvt.c */; }; A769B17F23E259AE00872273 /* SDL_shape.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A76923E2513E00DCD162 /* SDL_shape.c */; }; A769B18023E259AE00872273 /* SDL_rotate.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F423E2514000DCD162 /* SDL_rotate.c */; }; A769B18123E259AE00872273 /* SDL_coremotionsensor.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57C23E2513D00DCD162 /* SDL_coremotionsensor.m */; }; A769B18223E259AE00872273 /* SDL_touch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93E23E2514000DCD162 /* SDL_touch.c */; }; - A769B18423E259AE00872273 /* SDL_x11events.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70A23E2513E00DCD162 /* SDL_x11events.c */; }; A769B18523E259AE00872273 /* SDL_uikitmessagebox.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61B23E2513D00DCD162 /* SDL_uikitmessagebox.m */; }; A769B18623E259AE00872273 /* SDL_thread.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A77923E2513E00DCD162 /* SDL_thread.c */; }; A769B18723E259AE00872273 /* SDL_hidapi_xbox360w.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C823E2513E00DCD162 /* SDL_hidapi_xbox360w.c */; }; A769B18823E259AE00872273 /* SDL_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57423E2513D00DCD162 /* SDL_atomic.c */; }; A769B18923E259AE00872273 /* SDL_displayevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92D23E2514000DCD162 /* SDL_displayevents.c */; }; - A769B18A23E259AE00872273 /* SDL_cocoamousetap.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A69723E2513E00DCD162 /* SDL_cocoamousetap.m */; }; A769B18B23E259AE00872273 /* SDL_log.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5DD23E2513D00DCD162 /* SDL_log.c */; }; A769B18C23E259AE00872273 /* SDL_cocoaopengl.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A67F23E2513E00DCD162 /* SDL_cocoaopengl.m */; }; A769B18D23E259AE00872273 /* SDL_offscreenframebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5F223E2513D00DCD162 /* SDL_offscreenframebuffer.c */; }; - A769B18E23E259AE00872273 /* yuv_rgb.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A76E23E2513E00DCD162 /* yuv_rgb.c */; }; A769B18F23E259AE00872273 /* SDL_render_gles.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A90123E2514000DCD162 /* SDL_render_gles.c */; }; A769B19023E259AE00872273 /* SDL_systhread.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78623E2513E00DCD162 /* SDL_systhread.c */; }; A769B19123E259AE00872273 /* SDL_windowevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92F23E2514000DCD162 /* SDL_windowevents.c */; }; @@ -1234,14 +1106,12 @@ A769B19623E259AE00872273 /* SDL_systimer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5E223E2513D00DCD162 /* SDL_systimer.c */; }; A769B19723E259AE00872273 /* SDL_uikitclipboard.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62A23E2513D00DCD162 /* SDL_uikitclipboard.m */; }; A769B19823E259AE00872273 /* SDL_render_sw.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8F923E2514000DCD162 /* SDL_render_sw.c */; }; - A769B19923E259AE00872273 /* SDL_x11video.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70823E2513E00DCD162 /* SDL_x11video.c */; }; A769B19A23E259AE00872273 /* SDL_syssem.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A78323E2513E00DCD162 /* SDL_syssem.c */; }; A769B19B23E259AE00872273 /* SDL_hidapi_xbox360.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C223E2513E00DCD162 /* SDL_hidapi_xbox360.c */; }; A769B19C23E259AE00872273 /* SDL_coreaudio.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8BB23E2513F00DCD162 /* SDL_coreaudio.m */; }; A769B19D23E259AE00872273 /* SDL_blendline.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FB23E2514000DCD162 /* SDL_blendline.c */; }; A769B19E23E259AE00872273 /* SDL_blit_A.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A66423E2513E00DCD162 /* SDL_blit_A.c */; }; A769B19F23E259AE00872273 /* SDL_d3dmath.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FF23E2514000DCD162 /* SDL_d3dmath.c */; }; - A769B1A023E259AE00872273 /* SDL_x11mouse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70423E2513E00DCD162 /* SDL_x11mouse.c */; }; A769B1A123E259AE00872273 /* SDL_nullvideo.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60823E2513D00DCD162 /* SDL_nullvideo.c */; }; A769B1A223E259AE00872273 /* SDL_offscreenevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5F023E2513D00DCD162 /* SDL_offscreenevents.c */; }; A769B1A323E259AE00872273 /* SDL_uikitview.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62923E2513D00DCD162 /* SDL_uikitview.m */; }; @@ -1252,7 +1122,6 @@ A769B1A823E259AE00872273 /* s_copysign.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91423E2514000DCD162 /* s_copysign.c */; }; A769B1A923E259AE00872273 /* SDL_haptic.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5C523E2513D00DCD162 /* SDL_haptic.c */; }; A769B1AA23E259AE00872273 /* SDL_uikitvulkan.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62523E2513D00DCD162 /* SDL_uikitvulkan.m */; }; - A769B1AB23E259AE00872273 /* SDL_x11modes.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FE23E2513E00DCD162 /* SDL_x11modes.c */; }; A769B1AC23E259AE00872273 /* SDL_cocoametalview.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A69923E2513E00DCD162 /* SDL_cocoametalview.m */; }; A769B1AD23E259AE00872273 /* SDL_audiotypecvt.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8A023E2513F00DCD162 /* SDL_audiotypecvt.c */; }; A769B1AE23E259AE00872273 /* SDL_uikitevents.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61C23E2513D00DCD162 /* SDL_uikitevents.m */; }; @@ -1283,15 +1152,10 @@ A769B1C723E259AE00872273 /* SDL_hints.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5AB23E2513D00DCD162 /* SDL_hints.c */; }; A769B1C823E259AE00872273 /* SDL_hidapi_ps4.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C323E2513E00DCD162 /* SDL_hidapi_ps4.c */; }; A769B1C923E259AE00872273 /* SDL_pixels.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A64D23E2513D00DCD162 /* SDL_pixels.c */; }; - A769B1CA23E259AE00872273 /* SDL_x11clipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70B23E2513E00DCD162 /* SDL_x11clipboard.c */; }; A769B1CB23E259AE00872273 /* SDL_sysloadso.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A86323E2513F00DCD162 /* SDL_sysloadso.c */; }; - A769B1CC23E259AE00872273 /* SDL_x11xinput2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70223E2513E00DCD162 /* SDL_x11xinput2.c */; }; A769B1CD23E259AE00872273 /* SDL_syspower.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7EB23E2513F00DCD162 /* SDL_syspower.c */; }; - A769B1CE23E259AE00872273 /* SDL_x11touch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71123E2513E00DCD162 /* SDL_x11touch.c */; }; A769B1CF23E259AE00872273 /* SDL_iconv.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D323E2514000DCD162 /* SDL_iconv.c */; }; A769B1D023E259AE00872273 /* s_fabs.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91523E2514000DCD162 /* s_fabs.c */; }; - A769B1D123E259AE00872273 /* SDL_x11shape.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71623E2513E00DCD162 /* SDL_x11shape.c */; }; - A769B1D223E259AE00872273 /* imKStoUCS.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70923E2513E00DCD162 /* imKStoUCS.c */; }; A769B1D323E259AE00872273 /* SDL_shaders_metal.metal in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8E023E2514000DCD162 /* SDL_shaders_metal.metal */; }; A769B1D423E259AE00872273 /* SDL_uikitwindow.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61A23E2513D00DCD162 /* SDL_uikitwindow.m */; }; A769B1D523E259AE00872273 /* SDL_render.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8DB23E2514000DCD162 /* SDL_render.c */; }; @@ -1306,9 +1170,7 @@ A769B1DE23E259AE00872273 /* SDL_events.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93523E2514000DCD162 /* SDL_events.c */; }; A769B1DF23E259AE00872273 /* SDL_blit_0.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A66223E2513E00DCD162 /* SDL_blit_0.c */; }; A769B1E023E259AE00872273 /* k_tan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92723E2514000DCD162 /* k_tan.c */; }; - A769B1E123E259AE00872273 /* SDL_x11vulkan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70023E2513E00DCD162 /* SDL_x11vulkan.c */; }; A769B1E223E259AE00872273 /* SDL_diskaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8B123E2513F00DCD162 /* SDL_diskaudio.c */; }; - A769B1E323E259AE00872273 /* SDL_sysjoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7AB23E2513E00DCD162 /* SDL_sysjoystick.m */; }; A769B1E423E259AE00872273 /* SDL_egl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6B623E2513E00DCD162 /* SDL_egl.c */; }; A769B1E523E259AE00872273 /* SDL_RLEaccel.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61523E2513D00DCD162 /* SDL_RLEaccel.c */; }; A769B1E723E259AE00872273 /* SDL_assert.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A94423E2514000DCD162 /* SDL_assert.c */; }; @@ -1322,10 +1184,8 @@ A769B1EF23E259AE00872273 /* SDL_string.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D523E2514000DCD162 /* SDL_string.c */; }; A769B1F023E259AE00872273 /* SDL_render_gl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A90F23E2514000DCD162 /* SDL_render_gl.c */; }; A769B1F123E259AE00872273 /* SDL_uikitopengles.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62323E2513D00DCD162 /* SDL_uikitopengles.m */; }; - A769B1F223E259AE00872273 /* SDL_x11opengles.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71B23E2513E00DCD162 /* SDL_x11opengles.c */; }; A769B1F323E259AE00872273 /* SDL_cocoamodes.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68123E2513E00DCD162 /* SDL_cocoamodes.m */; }; A769B1F423E259AE00872273 /* k_rem_pio2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91623E2514000DCD162 /* k_rem_pio2.c */; }; - A769B1F523E259AE00872273 /* SDL_sysjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7CD23E2513E00DCD162 /* SDL_sysjoystick.c */; }; A769B1F623E259AE00872273 /* SDL_gesture.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A94023E2514000DCD162 /* SDL_gesture.c */; }; A769B1F723E259AE00872273 /* SDL_getenv.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D423E2514000DCD162 /* SDL_getenv.c */; }; A769B1F823E259AE00872273 /* SDL_hidapi_gamecube.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C923E2513E00DCD162 /* SDL_hidapi_gamecube.c */; }; @@ -1334,7 +1194,6 @@ A769B1FB23E259AE00872273 /* SDL_surface.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61423E2513D00DCD162 /* SDL_surface.c */; }; A769B1FC23E259AE00872273 /* SDL_hidapi_xboxone.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C523E2513E00DCD162 /* SDL_hidapi_xboxone.c */; }; A769B1FD23E259AE00872273 /* SDL_blit_auto.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A63F23E2513D00DCD162 /* SDL_blit_auto.c */; }; - A769B1FE23E259AE00872273 /* SDL_x11keyboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70C23E2513E00DCD162 /* SDL_x11keyboard.c */; }; A769B1FF23E259AE00872273 /* SDL_keyboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93823E2514000DCD162 /* SDL_keyboard.c */; }; A769B20123E259AE00872273 /* SDL_rect.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A63423E2513D00DCD162 /* SDL_rect.c */; }; A769B20223E259AE00872273 /* SDL_cocoaopengles.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68223E2513E00DCD162 /* SDL_cocoaopengles.m */; }; @@ -1342,7 +1201,6 @@ A769B20423E259AE00872273 /* SDL_hidapi_switch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C623E2513E00DCD162 /* SDL_hidapi_switch.c */; }; A769B20523E259AE00872273 /* SDL_strtokr.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D623E2514000DCD162 /* SDL_strtokr.c */; }; A769B20623E259AE00872273 /* SDL_clipboardevents.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93A23E2514000DCD162 /* SDL_clipboardevents.c */; }; - A769B20723E259AE00872273 /* SDL_x11framebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70623E2513E00DCD162 /* SDL_x11framebuffer.c */; }; A769B20823E259AE00872273 /* k_cos.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91923E2514000DCD162 /* k_cos.c */; }; A769B20923E259AE00872273 /* SDL_hidapijoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7C423E2513E00DCD162 /* SDL_hidapijoystick.c */; }; A769B20A23E259AE00872273 /* SDL_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8D923E2514000DCD162 /* SDL_malloc.c */; }; @@ -1358,31 +1216,25 @@ A769B21423E259AE00872273 /* SDL_syshaptic.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5C423E2513D00DCD162 /* SDL_syshaptic.c */; }; A769B21523E259AE00872273 /* SDL_rwopsbundlesupport.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7DE23E2513F00DCD162 /* SDL_rwopsbundlesupport.m */; }; A769B21623E259AE00872273 /* SDL_video.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A60E23E2513D00DCD162 /* SDL_video.c */; }; - A769B21723E259AE00872273 /* SDL_offscreenopengl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5ED23E2513D00DCD162 /* SDL_offscreenopengl.c */; }; A769B21823E259AE00872273 /* SDL_uikitmetalview.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62E23E2513D00DCD162 /* SDL_uikitmetalview.m */; }; A769B21923E259AE00872273 /* SDL_shaders_gles2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A90723E2514000DCD162 /* SDL_shaders_gles2.c */; }; A769B21A23E259AE00872273 /* SDL_blit_1.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FA23E2513E00DCD162 /* SDL_blit_1.c */; }; - A769B21B23E259AE00872273 /* SDL_x11dyn.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70523E2513E00DCD162 /* SDL_x11dyn.c */; }; A769B21C23E259AE00872273 /* SDL_mouse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92A23E2514000DCD162 /* SDL_mouse.c */; }; A769B21D23E259AE00872273 /* e_rem_pio2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91F23E2514000DCD162 /* e_rem_pio2.c */; }; A769B21E23E259AE00872273 /* SDL_dataqueue.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92823E2514000DCD162 /* SDL_dataqueue.c */; }; A769B21F23E259AE00872273 /* SDL_sysjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7A023E2513E00DCD162 /* SDL_sysjoystick.c */; }; A769B22023E259AE00872273 /* SDL_cpuinfo.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A77523E2513E00DCD162 /* SDL_cpuinfo.c */; }; A769B22123E259AE00872273 /* SDL_sensor.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A58223E2513D00DCD162 /* SDL_sensor.c */; }; - A769B22223E259AE00872273 /* SDL_x11window.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70723E2513E00DCD162 /* SDL_x11window.c */; }; A769B22323E259AE00872273 /* k_sin.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A91723E2514000DCD162 /* k_sin.c */; }; - A769B22423E259AE00872273 /* edid-parse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71223E2513E00DCD162 /* edid-parse.c */; }; A769B22523E259AE00872273 /* SDL_systimer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5E823E2513D00DCD162 /* SDL_systimer.c */; }; A769B22623E259AE00872273 /* SDL_drawpoint.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A8FC23E2514000DCD162 /* SDL_drawpoint.c */; }; A769B22723E259AE00872273 /* e_sqrt.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A92423E2514000DCD162 /* e_sqrt.c */; }; A769B22823E259AE00872273 /* SDL_cocoavideo.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68523E2513E00DCD162 /* SDL_cocoavideo.m */; }; A769B22923E259AE00872273 /* SDL.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A57123E2513D00DCD162 /* SDL.c */; }; - A769B22A23E259AE00872273 /* SDL_x11opengl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FF23E2513E00DCD162 /* SDL_x11opengl.c */; }; A769B22B23E259AE00872273 /* SDL_cocoavulkan.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68323E2513E00DCD162 /* SDL_cocoavulkan.m */; }; A769B22C23E259AE00872273 /* SDL_uikitappdelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61E23E2513D00DCD162 /* SDL_uikitappdelegate.m */; }; A769B22D23E259AE00872273 /* SDL_offscreenwindow.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5EF23E2513D00DCD162 /* SDL_offscreenwindow.c */; }; A77E6EB4167AB0A90010E40B /* SDL_gamecontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = A77E6EB3167AB0A90010E40B /* SDL_gamecontroller.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A77E6EB5167AB0A90010E40B /* SDL_gamecontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = A77E6EB3167AB0A90010E40B /* SDL_gamecontroller.h */; settings = {ATTRIBUTES = (Public, ); }; }; A7D88A1623E2437C00DCD162 /* begin_code.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557C71595D4D800BBD41B /* begin_code.h */; settings = {ATTRIBUTES = (Public, ); }; }; A7D88A1823E2437C00DCD162 /* close_code.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557C81595D4D800BBD41B /* close_code.h */; settings = {ATTRIBUTES = (Public, ); }; }; A7D88A1923E2437C00DCD162 /* SDL.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F91595D4D800BBD41B /* SDL.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -1451,13 +1303,6 @@ A7D88B4D23E2437C00DCD162 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00D0D08310675DD9004B05EF /* CoreFoundation.framework */; }; A7D88B4E23E2437C00DCD162 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73671C19A540EF004122E4 /* CoreVideo.framework */; }; A7D88B5023E2437C00DCD162 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0073179F0858DECD00B2BC32 /* IOKit.framework */; }; - A7D88BBC23E24A2F00DCD162 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7D88BBB23E24A2F00DCD162 /* UIKit.framework */; }; - A7D88BBE23E24A6000DCD162 /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7D88BBD23E24A6000DCD162 /* GameController.framework */; }; - A7D88BC023E24A7700DCD162 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7D88BBF23E24A7700DCD162 /* OpenGLES.framework */; }; - A7D88BC223E24A8800DCD162 /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7D88BC123E24A8800DCD162 /* CoreMotion.framework */; }; - A7D88BC423E24A9F00DCD162 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7D88BC323E24A9F00DCD162 /* AudioToolbox.framework */; }; - A7D88BC623E24ABA00DCD162 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7D88BC523E24ABA00DCD162 /* AVFoundation.framework */; }; - A7D88BC823E24B0300DCD162 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7D88BC723E24B0200DCD162 /* CoreGraphics.framework */; }; A7D88BCC23E24BED00DCD162 /* begin_code.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557C71595D4D800BBD41B /* begin_code.h */; settings = {ATTRIBUTES = (Public, ); }; }; A7D88BCE23E24BED00DCD162 /* close_code.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557C81595D4D800BBD41B /* close_code.h */; settings = {ATTRIBUTES = (Public, ); }; }; A7D88BCF23E24BED00DCD162 /* SDL.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F91595D4D800BBD41B /* SDL.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -1520,76 +1365,11 @@ A7D88C1623E24BED00DCD162 /* SDL_version.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F71595D4D800BBD41B /* SDL_version.h */; settings = {ATTRIBUTES = (Public, ); }; }; A7D88C1723E24BED00DCD162 /* SDL_video.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F81595D4D800BBD41B /* SDL_video.h */; settings = {ATTRIBUTES = (Public, ); }; }; A7D88C1923E24BED00DCD162 /* SDL_vulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D4820431F0F10B400EDC31C /* SDL_vulkan.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D0523E24BED00DCD162 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7D88BC323E24A9F00DCD162 /* AudioToolbox.framework */; }; - A7D88D0623E24BED00DCD162 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7D88BC523E24ABA00DCD162 /* AVFoundation.framework */; }; A7D88D0723E24BED00DCD162 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7381E951D8B69D600B177DD /* CoreAudio.framework */; }; A7D88D0823E24BED00DCD162 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00D0D08310675DD9004B05EF /* CoreFoundation.framework */; }; - A7D88D0923E24BED00DCD162 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7D88BC723E24B0200DCD162 /* CoreGraphics.framework */; }; A7D88D0B23E24BED00DCD162 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73671C19A540EF004122E4 /* CoreVideo.framework */; }; - A7D88D0C23E24BED00DCD162 /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7D88BBD23E24A6000DCD162 /* GameController.framework */; }; A7D88D0E23E24BED00DCD162 /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 564624371FF821CB0074AC87 /* Metal.framework */; }; - A7D88D0F23E24BED00DCD162 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7D88BBF23E24A7700DCD162 /* OpenGLES.framework */; }; A7D88D1023E24BED00DCD162 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 564624351FF821B80074AC87 /* QuartzCore.framework */; }; - A7D88D1123E24BED00DCD162 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7D88BBB23E24A2F00DCD162 /* UIKit.framework */; }; - A7D88D1923E24D3B00DCD162 /* SDL_filesystem.h in Headers */ = {isa = PBXBuildFile; fileRef = 567E2F2017C44C35005F1892 /* SDL_filesystem.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D1A23E24D3B00DCD162 /* begin_code.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557C71595D4D800BBD41B /* begin_code.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D1B23E24D3B00DCD162 /* close_code.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557C81595D4D800BBD41B /* close_code.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D1C23E24D3B00DCD162 /* SDL.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F91595D4D800BBD41B /* SDL.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D1D23E24D3B00DCD162 /* SDL_assert.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557C91595D4D800BBD41B /* SDL_assert.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D1E23E24D3B00DCD162 /* SDL_atomic.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557CA1595D4D800BBD41B /* SDL_atomic.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D1F23E24D3B00DCD162 /* SDL_audio.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557CB1595D4D800BBD41B /* SDL_audio.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D2023E24D3B00DCD162 /* SDL_bits.h in Headers */ = {isa = PBXBuildFile; fileRef = AADA5B8616CCAB3000107CF7 /* SDL_bits.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D2123E24D3B00DCD162 /* SDL_blendmode.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557CC1595D4D800BBD41B /* SDL_blendmode.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D2223E24D3B00DCD162 /* SDL_clipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557CD1595D4D800BBD41B /* SDL_clipboard.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D2323E24D3B00DCD162 /* SDL_config.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557CF1595D4D800BBD41B /* SDL_config.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D2623E24D3B00DCD162 /* SDL_copying.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D01595D4D800BBD41B /* SDL_copying.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D2723E24D3B00DCD162 /* SDL_cpuinfo.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D11595D4D800BBD41B /* SDL_cpuinfo.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D2823E24D3B00DCD162 /* SDL_endian.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D21595D4D800BBD41B /* SDL_endian.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D2923E24D3B00DCD162 /* SDL_error.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D31595D4D800BBD41B /* SDL_error.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D2A23E24D3B00DCD162 /* SDL_events.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D41595D4D800BBD41B /* SDL_events.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D2B23E24D3B00DCD162 /* SDL_gamecontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = A77E6EB3167AB0A90010E40B /* SDL_gamecontroller.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D2C23E24D3B00DCD162 /* SDL_gesture.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D51595D4D800BBD41B /* SDL_gesture.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D2D23E24D3B00DCD162 /* SDL_haptic.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D61595D4D800BBD41B /* SDL_haptic.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D2E23E24D3B00DCD162 /* SDL_hints.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D71595D4D800BBD41B /* SDL_hints.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D2F23E24D3B00DCD162 /* SDL_joystick.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D91595D4D800BBD41B /* SDL_joystick.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D3023E24D3B00DCD162 /* SDL_keyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557DA1595D4D800BBD41B /* SDL_keyboard.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D3123E24D3B00DCD162 /* SDL_keycode.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557DB1595D4D800BBD41B /* SDL_keycode.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D3223E24D3B00DCD162 /* SDL_loadso.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557DC1595D4D800BBD41B /* SDL_loadso.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D3323E24D3B00DCD162 /* SDL_log.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557DD1595D4D800BBD41B /* SDL_log.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D3423E24D3B00DCD162 /* SDL_main.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557DE1595D4D800BBD41B /* SDL_main.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D3523E24D3B00DCD162 /* SDL_opengles2_khrplatform.h in Headers */ = {isa = PBXBuildFile; fileRef = AAC070F8195606770073DCDF /* SDL_opengles2_khrplatform.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D3623E24D3B00DCD162 /* SDL_messagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = AA9FF9591637CBF9000DF050 /* SDL_messagebox.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D3723E24D3B00DCD162 /* SDL_mouse.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557DF1595D4D800BBD41B /* SDL_mouse.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D3823E24D3B00DCD162 /* SDL_mutex.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E01595D4D800BBD41B /* SDL_mutex.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D3923E24D3B00DCD162 /* SDL_name.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E11595D4D800BBD41B /* SDL_name.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D3A23E24D3B00DCD162 /* SDL_opengl.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E21595D4D800BBD41B /* SDL_opengl.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D3B23E24D3B00DCD162 /* SDL_opengles.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E31595D4D800BBD41B /* SDL_opengles.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D3D23E24D3B00DCD162 /* SDL_opengles2.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E41595D4D800BBD41B /* SDL_opengles2.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D3E23E24D3B00DCD162 /* SDL_pixels.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E51595D4D800BBD41B /* SDL_pixels.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D3F23E24D3B00DCD162 /* SDL_platform.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E61595D4D800BBD41B /* SDL_platform.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D4023E24D3B00DCD162 /* SDL_power.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E71595D4D800BBD41B /* SDL_power.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D4123E24D3B00DCD162 /* SDL_quit.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E81595D4D800BBD41B /* SDL_quit.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D4223E24D3B00DCD162 /* SDL_rect.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E91595D4D800BBD41B /* SDL_rect.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D4323E24D3B00DCD162 /* SDL_render.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557EA1595D4D800BBD41B /* SDL_render.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D4423E24D3B00DCD162 /* SDL_revision.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557EB1595D4D800BBD41B /* SDL_revision.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D4523E24D3B00DCD162 /* SDL_rwops.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557EC1595D4D800BBD41B /* SDL_rwops.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D4623E24D3B00DCD162 /* SDL_scancode.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557ED1595D4D800BBD41B /* SDL_scancode.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D4723E24D3B00DCD162 /* SDL_shape.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557EE1595D4D800BBD41B /* SDL_shape.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D4B23E24D3B00DCD162 /* SDL_stdinc.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557EF1595D4D800BBD41B /* SDL_stdinc.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D4C23E24D3B00DCD162 /* SDL_surface.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F01595D4D800BBD41B /* SDL_surface.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D4D23E24D3B00DCD162 /* SDL_system.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F11595D4D800BBD41B /* SDL_system.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D4E23E24D3B00DCD162 /* SDL_syswm.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F21595D4D800BBD41B /* SDL_syswm.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D4F23E24D3B00DCD162 /* SDL_opengl_glext.h in Headers */ = {isa = PBXBuildFile; fileRef = AAC070F4195606770073DCDF /* SDL_opengl_glext.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D5023E24D3B00DCD162 /* SDL_thread.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F31595D4D800BBD41B /* SDL_thread.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D5223E24D3B00DCD162 /* SDL_timer.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F41595D4D800BBD41B /* SDL_timer.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D5323E24D3B00DCD162 /* SDL_touch.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F51595D4D800BBD41B /* SDL_touch.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D5423E24D3B00DCD162 /* SDL_types.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F61595D4D800BBD41B /* SDL_types.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D5523E24D3B00DCD162 /* SDL_version.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F71595D4D800BBD41B /* SDL_version.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D5623E24D3B00DCD162 /* SDL_video.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F81595D4D800BBD41B /* SDL_video.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D5D23E24D3B00DCD162 /* SDL_opengles2_gl2.h in Headers */ = {isa = PBXBuildFile; fileRef = AAC070F5195606770073DCDF /* SDL_opengles2_gl2.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D7A23E24D3B00DCD162 /* SDL_sensor.h in Headers */ = {isa = PBXBuildFile; fileRef = F3950CD7212BC88D00F51292 /* SDL_sensor.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88D8A23E24D3B00DCD162 /* SDL_opengles2_gl2platform.h in Headers */ = {isa = PBXBuildFile; fileRef = AAC070F7195606770073DCDF /* SDL_opengles2_gl2platform.h */; settings = {ATTRIBUTES = (Public, ); }; }; - A7D88DA623E24D3B00DCD162 /* SDL_opengles2_gl2ext.h in Headers */ = {isa = PBXBuildFile; fileRef = AAC070F6195606770073DCDF /* SDL_opengles2_gl2ext.h */; settings = {ATTRIBUTES = (Public, ); }; }; A7D8A94523E2514000DCD162 /* SDL_dataqueue.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57023E2513D00DCD162 /* SDL_dataqueue.h */; }; A7D8A94623E2514000DCD162 /* SDL_dataqueue.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57023E2513D00DCD162 /* SDL_dataqueue.h */; }; A7D8A94723E2514000DCD162 /* SDL_dataqueue.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A57023E2513D00DCD162 /* SDL_dataqueue.h */; }; @@ -1764,12 +1544,6 @@ A7D8AB4C23E2514100DCD162 /* SDL_systimer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5E823E2513D00DCD162 /* SDL_systimer.c */; }; A7D8AB4D23E2514100DCD162 /* SDL_systimer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5E823E2513D00DCD162 /* SDL_systimer.c */; }; A7D8AB4E23E2514100DCD162 /* SDL_systimer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5E823E2513D00DCD162 /* SDL_systimer.c */; }; - A7D8AB5523E2514100DCD162 /* SDL_offscreenopengl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5ED23E2513D00DCD162 /* SDL_offscreenopengl.c */; }; - A7D8AB5623E2514100DCD162 /* SDL_offscreenopengl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5ED23E2513D00DCD162 /* SDL_offscreenopengl.c */; }; - A7D8AB5723E2514100DCD162 /* SDL_offscreenopengl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5ED23E2513D00DCD162 /* SDL_offscreenopengl.c */; }; - A7D8AB5823E2514100DCD162 /* SDL_offscreenopengl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5ED23E2513D00DCD162 /* SDL_offscreenopengl.c */; }; - A7D8AB5923E2514100DCD162 /* SDL_offscreenopengl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5ED23E2513D00DCD162 /* SDL_offscreenopengl.c */; }; - A7D8AB5A23E2514100DCD162 /* SDL_offscreenopengl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5ED23E2513D00DCD162 /* SDL_offscreenopengl.c */; }; A7D8AB5B23E2514100DCD162 /* SDL_offscreenevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5EE23E2513D00DCD162 /* SDL_offscreenevents_c.h */; }; A7D8AB5C23E2514100DCD162 /* SDL_offscreenevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5EE23E2513D00DCD162 /* SDL_offscreenevents_c.h */; }; A7D8AB5D23E2514100DCD162 /* SDL_offscreenevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5EE23E2513D00DCD162 /* SDL_offscreenevents_c.h */; }; @@ -1800,12 +1574,6 @@ A7D8AB7623E2514100DCD162 /* SDL_offscreenframebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5F223E2513D00DCD162 /* SDL_offscreenframebuffer.c */; }; A7D8AB7723E2514100DCD162 /* SDL_offscreenframebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5F223E2513D00DCD162 /* SDL_offscreenframebuffer.c */; }; A7D8AB7823E2514100DCD162 /* SDL_offscreenframebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5F223E2513D00DCD162 /* SDL_offscreenframebuffer.c */; }; - A7D8AB7923E2514100DCD162 /* SDL_offscreenopengl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5F323E2513D00DCD162 /* SDL_offscreenopengl.h */; }; - A7D8AB7A23E2514100DCD162 /* SDL_offscreenopengl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5F323E2513D00DCD162 /* SDL_offscreenopengl.h */; }; - A7D8AB7B23E2514100DCD162 /* SDL_offscreenopengl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5F323E2513D00DCD162 /* SDL_offscreenopengl.h */; }; - A7D8AB7C23E2514100DCD162 /* SDL_offscreenopengl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5F323E2513D00DCD162 /* SDL_offscreenopengl.h */; }; - A7D8AB7D23E2514100DCD162 /* SDL_offscreenopengl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5F323E2513D00DCD162 /* SDL_offscreenopengl.h */; }; - A7D8AB7E23E2514100DCD162 /* SDL_offscreenopengl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5F323E2513D00DCD162 /* SDL_offscreenopengl.h */; }; A7D8AB7F23E2514100DCD162 /* SDL_offscreenframebuffer_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5F423E2513D00DCD162 /* SDL_offscreenframebuffer_c.h */; }; A7D8AB8023E2514100DCD162 /* SDL_offscreenframebuffer_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5F423E2513D00DCD162 /* SDL_offscreenframebuffer_c.h */; }; A7D8AB8123E2514100DCD162 /* SDL_offscreenframebuffer_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A5F423E2513D00DCD162 /* SDL_offscreenframebuffer_c.h */; }; @@ -1980,10 +1748,6 @@ A7D8AC9B23E2514100DCD162 /* SDL_uikitwindow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62723E2513D00DCD162 /* SDL_uikitwindow.h */; }; A7D8AC9D23E2514100DCD162 /* SDL_uikitwindow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62723E2513D00DCD162 /* SDL_uikitwindow.h */; }; A7D8AC9E23E2514100DCD162 /* SDL_uikitwindow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62723E2513D00DCD162 /* SDL_uikitwindow.h */; }; - A7D8ACA023E2514100DCD162 /* keyinfotable.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62823E2513D00DCD162 /* keyinfotable.h */; }; - A7D8ACA123E2514100DCD162 /* keyinfotable.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62823E2513D00DCD162 /* keyinfotable.h */; }; - A7D8ACA323E2514100DCD162 /* keyinfotable.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62823E2513D00DCD162 /* keyinfotable.h */; }; - A7D8ACA423E2514100DCD162 /* keyinfotable.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62823E2513D00DCD162 /* keyinfotable.h */; }; A7D8ACA623E2514100DCD162 /* SDL_uikitview.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62923E2513D00DCD162 /* SDL_uikitview.m */; }; A7D8ACA723E2514100DCD162 /* SDL_uikitview.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62923E2513D00DCD162 /* SDL_uikitview.m */; }; A7D8ACA923E2514100DCD162 /* SDL_uikitview.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62923E2513D00DCD162 /* SDL_uikitview.m */; }; @@ -2160,12 +1924,6 @@ A7D8AEBB23E2514100DCD162 /* SDL_cocoamouse.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68723E2513E00DCD162 /* SDL_cocoamouse.m */; }; A7D8AEBC23E2514100DCD162 /* SDL_cocoamouse.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68723E2513E00DCD162 /* SDL_cocoamouse.m */; }; A7D8AEBD23E2514100DCD162 /* SDL_cocoamouse.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68723E2513E00DCD162 /* SDL_cocoamouse.m */; }; - A7D8AEBE23E2514100DCD162 /* SDL_cocoamousetap.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68823E2513E00DCD162 /* SDL_cocoamousetap.h */; }; - A7D8AEBF23E2514100DCD162 /* SDL_cocoamousetap.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68823E2513E00DCD162 /* SDL_cocoamousetap.h */; }; - A7D8AEC023E2514100DCD162 /* SDL_cocoamousetap.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68823E2513E00DCD162 /* SDL_cocoamousetap.h */; }; - A7D8AEC123E2514100DCD162 /* SDL_cocoamousetap.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68823E2513E00DCD162 /* SDL_cocoamousetap.h */; }; - A7D8AEC223E2514100DCD162 /* SDL_cocoamousetap.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68823E2513E00DCD162 /* SDL_cocoamousetap.h */; }; - A7D8AEC323E2514100DCD162 /* SDL_cocoamousetap.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A68823E2513E00DCD162 /* SDL_cocoamousetap.h */; }; A7D8AEC423E2514100DCD162 /* SDL_cocoaevents.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68923E2513E00DCD162 /* SDL_cocoaevents.m */; }; A7D8AEC523E2514100DCD162 /* SDL_cocoaevents.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68923E2513E00DCD162 /* SDL_cocoaevents.m */; }; A7D8AEC623E2514100DCD162 /* SDL_cocoaevents.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A68923E2513E00DCD162 /* SDL_cocoaevents.m */; }; @@ -2250,12 +2008,6 @@ A7D8AF1523E2514100DCD162 /* SDL_cocoaevents.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69623E2513E00DCD162 /* SDL_cocoaevents.h */; }; A7D8AF1623E2514100DCD162 /* SDL_cocoaevents.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69623E2513E00DCD162 /* SDL_cocoaevents.h */; }; A7D8AF1723E2514100DCD162 /* SDL_cocoaevents.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69623E2513E00DCD162 /* SDL_cocoaevents.h */; }; - A7D8AF1823E2514100DCD162 /* SDL_cocoamousetap.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A69723E2513E00DCD162 /* SDL_cocoamousetap.m */; }; - A7D8AF1923E2514100DCD162 /* SDL_cocoamousetap.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A69723E2513E00DCD162 /* SDL_cocoamousetap.m */; }; - A7D8AF1A23E2514100DCD162 /* SDL_cocoamousetap.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A69723E2513E00DCD162 /* SDL_cocoamousetap.m */; }; - A7D8AF1B23E2514100DCD162 /* SDL_cocoamousetap.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A69723E2513E00DCD162 /* SDL_cocoamousetap.m */; }; - A7D8AF1C23E2514100DCD162 /* SDL_cocoamousetap.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A69723E2513E00DCD162 /* SDL_cocoamousetap.m */; }; - A7D8AF1D23E2514100DCD162 /* SDL_cocoamousetap.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A69723E2513E00DCD162 /* SDL_cocoamousetap.m */; }; A7D8AF1E23E2514100DCD162 /* SDL_cocoamouse.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69823E2513E00DCD162 /* SDL_cocoamouse.h */; }; A7D8AF1F23E2514100DCD162 /* SDL_cocoamouse.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69823E2513E00DCD162 /* SDL_cocoamouse.h */; }; A7D8AF2023E2514100DCD162 /* SDL_cocoamouse.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A69823E2513E00DCD162 /* SDL_cocoamouse.h */; }; @@ -2280,228 +2032,6 @@ A7D8B14323E2514200DCD162 /* SDL_blit_1.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FA23E2513E00DCD162 /* SDL_blit_1.c */; }; A7D8B14423E2514200DCD162 /* SDL_blit_1.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FA23E2513E00DCD162 /* SDL_blit_1.c */; }; A7D8B14523E2514200DCD162 /* SDL_blit_1.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FA23E2513E00DCD162 /* SDL_blit_1.c */; }; - A7D8B14623E2514200DCD162 /* SDL_x11touch.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A6FC23E2513E00DCD162 /* SDL_x11touch.h */; }; - A7D8B14723E2514200DCD162 /* SDL_x11touch.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A6FC23E2513E00DCD162 /* SDL_x11touch.h */; }; - A7D8B14823E2514200DCD162 /* SDL_x11touch.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A6FC23E2513E00DCD162 /* SDL_x11touch.h */; }; - A7D8B14923E2514200DCD162 /* SDL_x11touch.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A6FC23E2513E00DCD162 /* SDL_x11touch.h */; }; - A7D8B14A23E2514200DCD162 /* SDL_x11touch.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A6FC23E2513E00DCD162 /* SDL_x11touch.h */; }; - A7D8B14B23E2514200DCD162 /* SDL_x11touch.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A6FC23E2513E00DCD162 /* SDL_x11touch.h */; }; - A7D8B14C23E2514200DCD162 /* SDL_x11messagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A6FD23E2513E00DCD162 /* SDL_x11messagebox.h */; }; - A7D8B14D23E2514200DCD162 /* SDL_x11messagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A6FD23E2513E00DCD162 /* SDL_x11messagebox.h */; }; - A7D8B14E23E2514200DCD162 /* SDL_x11messagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A6FD23E2513E00DCD162 /* SDL_x11messagebox.h */; }; - A7D8B14F23E2514200DCD162 /* SDL_x11messagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A6FD23E2513E00DCD162 /* SDL_x11messagebox.h */; }; - A7D8B15023E2514200DCD162 /* SDL_x11messagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A6FD23E2513E00DCD162 /* SDL_x11messagebox.h */; }; - A7D8B15123E2514200DCD162 /* SDL_x11messagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A6FD23E2513E00DCD162 /* SDL_x11messagebox.h */; }; - A7D8B15223E2514200DCD162 /* SDL_x11modes.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FE23E2513E00DCD162 /* SDL_x11modes.c */; }; - A7D8B15323E2514200DCD162 /* SDL_x11modes.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FE23E2513E00DCD162 /* SDL_x11modes.c */; }; - A7D8B15423E2514200DCD162 /* SDL_x11modes.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FE23E2513E00DCD162 /* SDL_x11modes.c */; }; - A7D8B15523E2514200DCD162 /* SDL_x11modes.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FE23E2513E00DCD162 /* SDL_x11modes.c */; }; - A7D8B15623E2514200DCD162 /* SDL_x11modes.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FE23E2513E00DCD162 /* SDL_x11modes.c */; }; - A7D8B15723E2514200DCD162 /* SDL_x11modes.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FE23E2513E00DCD162 /* SDL_x11modes.c */; }; - A7D8B15823E2514200DCD162 /* SDL_x11opengl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FF23E2513E00DCD162 /* SDL_x11opengl.c */; }; - A7D8B15923E2514200DCD162 /* SDL_x11opengl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FF23E2513E00DCD162 /* SDL_x11opengl.c */; }; - A7D8B15A23E2514200DCD162 /* SDL_x11opengl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FF23E2513E00DCD162 /* SDL_x11opengl.c */; }; - A7D8B15B23E2514200DCD162 /* SDL_x11opengl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FF23E2513E00DCD162 /* SDL_x11opengl.c */; }; - A7D8B15C23E2514200DCD162 /* SDL_x11opengl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FF23E2513E00DCD162 /* SDL_x11opengl.c */; }; - A7D8B15D23E2514200DCD162 /* SDL_x11opengl.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A6FF23E2513E00DCD162 /* SDL_x11opengl.c */; }; - A7D8B15E23E2514200DCD162 /* SDL_x11vulkan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70023E2513E00DCD162 /* SDL_x11vulkan.c */; }; - A7D8B15F23E2514200DCD162 /* SDL_x11vulkan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70023E2513E00DCD162 /* SDL_x11vulkan.c */; }; - A7D8B16023E2514200DCD162 /* SDL_x11vulkan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70023E2513E00DCD162 /* SDL_x11vulkan.c */; }; - A7D8B16123E2514200DCD162 /* SDL_x11vulkan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70023E2513E00DCD162 /* SDL_x11vulkan.c */; }; - A7D8B16223E2514200DCD162 /* SDL_x11vulkan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70023E2513E00DCD162 /* SDL_x11vulkan.c */; }; - A7D8B16323E2514200DCD162 /* SDL_x11vulkan.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70023E2513E00DCD162 /* SDL_x11vulkan.c */; }; - A7D8B16423E2514200DCD162 /* SDL_x11shape.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70123E2513E00DCD162 /* SDL_x11shape.h */; }; - A7D8B16523E2514200DCD162 /* SDL_x11shape.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70123E2513E00DCD162 /* SDL_x11shape.h */; }; - A7D8B16623E2514200DCD162 /* SDL_x11shape.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70123E2513E00DCD162 /* SDL_x11shape.h */; }; - A7D8B16723E2514200DCD162 /* SDL_x11shape.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70123E2513E00DCD162 /* SDL_x11shape.h */; }; - A7D8B16823E2514200DCD162 /* SDL_x11shape.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70123E2513E00DCD162 /* SDL_x11shape.h */; }; - A7D8B16923E2514200DCD162 /* SDL_x11shape.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70123E2513E00DCD162 /* SDL_x11shape.h */; }; - A7D8B16A23E2514200DCD162 /* SDL_x11xinput2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70223E2513E00DCD162 /* SDL_x11xinput2.c */; }; - A7D8B16B23E2514200DCD162 /* SDL_x11xinput2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70223E2513E00DCD162 /* SDL_x11xinput2.c */; }; - A7D8B16C23E2514200DCD162 /* SDL_x11xinput2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70223E2513E00DCD162 /* SDL_x11xinput2.c */; }; - A7D8B16D23E2514200DCD162 /* SDL_x11xinput2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70223E2513E00DCD162 /* SDL_x11xinput2.c */; }; - A7D8B16E23E2514200DCD162 /* SDL_x11xinput2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70223E2513E00DCD162 /* SDL_x11xinput2.c */; }; - A7D8B16F23E2514200DCD162 /* SDL_x11xinput2.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70223E2513E00DCD162 /* SDL_x11xinput2.c */; }; - A7D8B17023E2514200DCD162 /* SDL_x11opengles.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70323E2513E00DCD162 /* SDL_x11opengles.h */; }; - A7D8B17123E2514200DCD162 /* SDL_x11opengles.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70323E2513E00DCD162 /* SDL_x11opengles.h */; }; - A7D8B17223E2514200DCD162 /* SDL_x11opengles.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70323E2513E00DCD162 /* SDL_x11opengles.h */; }; - A7D8B17323E2514200DCD162 /* SDL_x11opengles.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70323E2513E00DCD162 /* SDL_x11opengles.h */; }; - A7D8B17423E2514200DCD162 /* SDL_x11opengles.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70323E2513E00DCD162 /* SDL_x11opengles.h */; }; - A7D8B17523E2514200DCD162 /* SDL_x11opengles.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70323E2513E00DCD162 /* SDL_x11opengles.h */; }; - A7D8B17623E2514200DCD162 /* SDL_x11mouse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70423E2513E00DCD162 /* SDL_x11mouse.c */; }; - A7D8B17723E2514200DCD162 /* SDL_x11mouse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70423E2513E00DCD162 /* SDL_x11mouse.c */; }; - A7D8B17823E2514200DCD162 /* SDL_x11mouse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70423E2513E00DCD162 /* SDL_x11mouse.c */; }; - A7D8B17923E2514200DCD162 /* SDL_x11mouse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70423E2513E00DCD162 /* SDL_x11mouse.c */; }; - A7D8B17A23E2514200DCD162 /* SDL_x11mouse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70423E2513E00DCD162 /* SDL_x11mouse.c */; }; - A7D8B17B23E2514200DCD162 /* SDL_x11mouse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70423E2513E00DCD162 /* SDL_x11mouse.c */; }; - A7D8B17C23E2514200DCD162 /* SDL_x11dyn.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70523E2513E00DCD162 /* SDL_x11dyn.c */; }; - A7D8B17D23E2514200DCD162 /* SDL_x11dyn.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70523E2513E00DCD162 /* SDL_x11dyn.c */; }; - A7D8B17E23E2514200DCD162 /* SDL_x11dyn.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70523E2513E00DCD162 /* SDL_x11dyn.c */; }; - A7D8B17F23E2514200DCD162 /* SDL_x11dyn.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70523E2513E00DCD162 /* SDL_x11dyn.c */; }; - A7D8B18023E2514200DCD162 /* SDL_x11dyn.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70523E2513E00DCD162 /* SDL_x11dyn.c */; }; - A7D8B18123E2514200DCD162 /* SDL_x11dyn.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70523E2513E00DCD162 /* SDL_x11dyn.c */; }; - A7D8B18223E2514200DCD162 /* SDL_x11framebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70623E2513E00DCD162 /* SDL_x11framebuffer.c */; }; - A7D8B18323E2514200DCD162 /* SDL_x11framebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70623E2513E00DCD162 /* SDL_x11framebuffer.c */; }; - A7D8B18423E2514200DCD162 /* SDL_x11framebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70623E2513E00DCD162 /* SDL_x11framebuffer.c */; }; - A7D8B18523E2514200DCD162 /* SDL_x11framebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70623E2513E00DCD162 /* SDL_x11framebuffer.c */; }; - A7D8B18623E2514200DCD162 /* SDL_x11framebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70623E2513E00DCD162 /* SDL_x11framebuffer.c */; }; - A7D8B18723E2514200DCD162 /* SDL_x11framebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70623E2513E00DCD162 /* SDL_x11framebuffer.c */; }; - A7D8B18823E2514200DCD162 /* SDL_x11window.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70723E2513E00DCD162 /* SDL_x11window.c */; }; - A7D8B18923E2514200DCD162 /* SDL_x11window.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70723E2513E00DCD162 /* SDL_x11window.c */; }; - A7D8B18A23E2514200DCD162 /* SDL_x11window.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70723E2513E00DCD162 /* SDL_x11window.c */; }; - A7D8B18B23E2514200DCD162 /* SDL_x11window.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70723E2513E00DCD162 /* SDL_x11window.c */; }; - A7D8B18C23E2514200DCD162 /* SDL_x11window.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70723E2513E00DCD162 /* SDL_x11window.c */; }; - A7D8B18D23E2514200DCD162 /* SDL_x11window.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70723E2513E00DCD162 /* SDL_x11window.c */; }; - A7D8B18E23E2514200DCD162 /* SDL_x11video.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70823E2513E00DCD162 /* SDL_x11video.c */; }; - A7D8B18F23E2514200DCD162 /* SDL_x11video.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70823E2513E00DCD162 /* SDL_x11video.c */; }; - A7D8B19023E2514200DCD162 /* SDL_x11video.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70823E2513E00DCD162 /* SDL_x11video.c */; }; - A7D8B19123E2514200DCD162 /* SDL_x11video.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70823E2513E00DCD162 /* SDL_x11video.c */; }; - A7D8B19223E2514200DCD162 /* SDL_x11video.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70823E2513E00DCD162 /* SDL_x11video.c */; }; - A7D8B19323E2514200DCD162 /* SDL_x11video.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70823E2513E00DCD162 /* SDL_x11video.c */; }; - A7D8B19423E2514200DCD162 /* imKStoUCS.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70923E2513E00DCD162 /* imKStoUCS.c */; }; - A7D8B19523E2514200DCD162 /* imKStoUCS.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70923E2513E00DCD162 /* imKStoUCS.c */; }; - A7D8B19623E2514200DCD162 /* imKStoUCS.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70923E2513E00DCD162 /* imKStoUCS.c */; }; - A7D8B19723E2514200DCD162 /* imKStoUCS.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70923E2513E00DCD162 /* imKStoUCS.c */; }; - A7D8B19823E2514200DCD162 /* imKStoUCS.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70923E2513E00DCD162 /* imKStoUCS.c */; }; - A7D8B19923E2514200DCD162 /* imKStoUCS.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70923E2513E00DCD162 /* imKStoUCS.c */; }; - A7D8B19A23E2514200DCD162 /* SDL_x11events.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70A23E2513E00DCD162 /* SDL_x11events.c */; }; - A7D8B19B23E2514200DCD162 /* SDL_x11events.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70A23E2513E00DCD162 /* SDL_x11events.c */; }; - A7D8B19C23E2514200DCD162 /* SDL_x11events.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70A23E2513E00DCD162 /* SDL_x11events.c */; }; - A7D8B19D23E2514200DCD162 /* SDL_x11events.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70A23E2513E00DCD162 /* SDL_x11events.c */; }; - A7D8B19E23E2514200DCD162 /* SDL_x11events.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70A23E2513E00DCD162 /* SDL_x11events.c */; }; - A7D8B19F23E2514200DCD162 /* SDL_x11events.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70A23E2513E00DCD162 /* SDL_x11events.c */; }; - A7D8B1A023E2514200DCD162 /* SDL_x11clipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70B23E2513E00DCD162 /* SDL_x11clipboard.c */; }; - A7D8B1A123E2514200DCD162 /* SDL_x11clipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70B23E2513E00DCD162 /* SDL_x11clipboard.c */; }; - A7D8B1A223E2514200DCD162 /* SDL_x11clipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70B23E2513E00DCD162 /* SDL_x11clipboard.c */; }; - A7D8B1A323E2514200DCD162 /* SDL_x11clipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70B23E2513E00DCD162 /* SDL_x11clipboard.c */; }; - A7D8B1A423E2514200DCD162 /* SDL_x11clipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70B23E2513E00DCD162 /* SDL_x11clipboard.c */; }; - A7D8B1A523E2514200DCD162 /* SDL_x11clipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70B23E2513E00DCD162 /* SDL_x11clipboard.c */; }; - A7D8B1A623E2514200DCD162 /* SDL_x11keyboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70C23E2513E00DCD162 /* SDL_x11keyboard.c */; }; - A7D8B1A723E2514200DCD162 /* SDL_x11keyboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70C23E2513E00DCD162 /* SDL_x11keyboard.c */; }; - A7D8B1A823E2514200DCD162 /* SDL_x11keyboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70C23E2513E00DCD162 /* SDL_x11keyboard.c */; }; - A7D8B1A923E2514200DCD162 /* SDL_x11keyboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70C23E2513E00DCD162 /* SDL_x11keyboard.c */; }; - A7D8B1AA23E2514200DCD162 /* SDL_x11keyboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70C23E2513E00DCD162 /* SDL_x11keyboard.c */; }; - A7D8B1AB23E2514200DCD162 /* SDL_x11keyboard.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A70C23E2513E00DCD162 /* SDL_x11keyboard.c */; }; - A7D8B1AC23E2514200DCD162 /* SDL_x11sym.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70D23E2513E00DCD162 /* SDL_x11sym.h */; }; - A7D8B1AD23E2514200DCD162 /* SDL_x11sym.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70D23E2513E00DCD162 /* SDL_x11sym.h */; }; - A7D8B1AE23E2514200DCD162 /* SDL_x11sym.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70D23E2513E00DCD162 /* SDL_x11sym.h */; }; - A7D8B1AF23E2514200DCD162 /* SDL_x11sym.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70D23E2513E00DCD162 /* SDL_x11sym.h */; }; - A7D8B1B023E2514200DCD162 /* SDL_x11sym.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70D23E2513E00DCD162 /* SDL_x11sym.h */; }; - A7D8B1B123E2514200DCD162 /* SDL_x11sym.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70D23E2513E00DCD162 /* SDL_x11sym.h */; }; - A7D8B1B223E2514200DCD162 /* SDL_x11opengl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70E23E2513E00DCD162 /* SDL_x11opengl.h */; }; - A7D8B1B323E2514200DCD162 /* SDL_x11opengl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70E23E2513E00DCD162 /* SDL_x11opengl.h */; }; - A7D8B1B423E2514200DCD162 /* SDL_x11opengl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70E23E2513E00DCD162 /* SDL_x11opengl.h */; }; - A7D8B1B523E2514200DCD162 /* SDL_x11opengl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70E23E2513E00DCD162 /* SDL_x11opengl.h */; }; - A7D8B1B623E2514200DCD162 /* SDL_x11opengl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70E23E2513E00DCD162 /* SDL_x11opengl.h */; }; - A7D8B1B723E2514200DCD162 /* SDL_x11opengl.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70E23E2513E00DCD162 /* SDL_x11opengl.h */; }; - A7D8B1B823E2514200DCD162 /* SDL_x11modes.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70F23E2513E00DCD162 /* SDL_x11modes.h */; }; - A7D8B1B923E2514200DCD162 /* SDL_x11modes.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70F23E2513E00DCD162 /* SDL_x11modes.h */; }; - A7D8B1BA23E2514200DCD162 /* SDL_x11modes.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70F23E2513E00DCD162 /* SDL_x11modes.h */; }; - A7D8B1BB23E2514200DCD162 /* SDL_x11modes.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70F23E2513E00DCD162 /* SDL_x11modes.h */; }; - A7D8B1BC23E2514200DCD162 /* SDL_x11modes.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70F23E2513E00DCD162 /* SDL_x11modes.h */; }; - A7D8B1BD23E2514200DCD162 /* SDL_x11modes.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A70F23E2513E00DCD162 /* SDL_x11modes.h */; }; - A7D8B1BE23E2514200DCD162 /* SDL_x11messagebox.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71023E2513E00DCD162 /* SDL_x11messagebox.c */; }; - A7D8B1BF23E2514200DCD162 /* SDL_x11messagebox.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71023E2513E00DCD162 /* SDL_x11messagebox.c */; }; - A7D8B1C023E2514200DCD162 /* SDL_x11messagebox.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71023E2513E00DCD162 /* SDL_x11messagebox.c */; }; - A7D8B1C123E2514200DCD162 /* SDL_x11messagebox.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71023E2513E00DCD162 /* SDL_x11messagebox.c */; }; - A7D8B1C223E2514200DCD162 /* SDL_x11messagebox.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71023E2513E00DCD162 /* SDL_x11messagebox.c */; }; - A7D8B1C323E2514200DCD162 /* SDL_x11messagebox.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71023E2513E00DCD162 /* SDL_x11messagebox.c */; }; - A7D8B1C423E2514200DCD162 /* SDL_x11touch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71123E2513E00DCD162 /* SDL_x11touch.c */; }; - A7D8B1C523E2514200DCD162 /* SDL_x11touch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71123E2513E00DCD162 /* SDL_x11touch.c */; }; - A7D8B1C623E2514200DCD162 /* SDL_x11touch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71123E2513E00DCD162 /* SDL_x11touch.c */; }; - A7D8B1C723E2514200DCD162 /* SDL_x11touch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71123E2513E00DCD162 /* SDL_x11touch.c */; }; - A7D8B1C823E2514200DCD162 /* SDL_x11touch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71123E2513E00DCD162 /* SDL_x11touch.c */; }; - A7D8B1C923E2514200DCD162 /* SDL_x11touch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71123E2513E00DCD162 /* SDL_x11touch.c */; }; - A7D8B1CA23E2514200DCD162 /* edid-parse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71223E2513E00DCD162 /* edid-parse.c */; }; - A7D8B1CB23E2514200DCD162 /* edid-parse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71223E2513E00DCD162 /* edid-parse.c */; }; - A7D8B1CC23E2514200DCD162 /* edid-parse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71223E2513E00DCD162 /* edid-parse.c */; }; - A7D8B1CD23E2514200DCD162 /* edid-parse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71223E2513E00DCD162 /* edid-parse.c */; }; - A7D8B1CE23E2514200DCD162 /* edid-parse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71223E2513E00DCD162 /* edid-parse.c */; }; - A7D8B1CF23E2514200DCD162 /* edid-parse.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71223E2513E00DCD162 /* edid-parse.c */; }; - A7D8B1D023E2514200DCD162 /* SDL_x11xinput2.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71323E2513E00DCD162 /* SDL_x11xinput2.h */; }; - A7D8B1D123E2514200DCD162 /* SDL_x11xinput2.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71323E2513E00DCD162 /* SDL_x11xinput2.h */; }; - A7D8B1D223E2514200DCD162 /* SDL_x11xinput2.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71323E2513E00DCD162 /* SDL_x11xinput2.h */; }; - A7D8B1D323E2514200DCD162 /* SDL_x11xinput2.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71323E2513E00DCD162 /* SDL_x11xinput2.h */; }; - A7D8B1D423E2514200DCD162 /* SDL_x11xinput2.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71323E2513E00DCD162 /* SDL_x11xinput2.h */; }; - A7D8B1D523E2514200DCD162 /* SDL_x11xinput2.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71323E2513E00DCD162 /* SDL_x11xinput2.h */; }; - A7D8B1D623E2514200DCD162 /* edid.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71423E2513E00DCD162 /* edid.h */; }; - A7D8B1D723E2514200DCD162 /* edid.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71423E2513E00DCD162 /* edid.h */; }; - A7D8B1D823E2514200DCD162 /* edid.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71423E2513E00DCD162 /* edid.h */; }; - A7D8B1D923E2514200DCD162 /* edid.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71423E2513E00DCD162 /* edid.h */; }; - A7D8B1DA23E2514200DCD162 /* edid.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71423E2513E00DCD162 /* edid.h */; }; - A7D8B1DB23E2514200DCD162 /* edid.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71423E2513E00DCD162 /* edid.h */; }; - A7D8B1DC23E2514200DCD162 /* SDL_x11vulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71523E2513E00DCD162 /* SDL_x11vulkan.h */; }; - A7D8B1DD23E2514200DCD162 /* SDL_x11vulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71523E2513E00DCD162 /* SDL_x11vulkan.h */; }; - A7D8B1DE23E2514200DCD162 /* SDL_x11vulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71523E2513E00DCD162 /* SDL_x11vulkan.h */; }; - A7D8B1DF23E2514200DCD162 /* SDL_x11vulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71523E2513E00DCD162 /* SDL_x11vulkan.h */; }; - A7D8B1E023E2514200DCD162 /* SDL_x11vulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71523E2513E00DCD162 /* SDL_x11vulkan.h */; }; - A7D8B1E123E2514200DCD162 /* SDL_x11vulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71523E2513E00DCD162 /* SDL_x11vulkan.h */; }; - A7D8B1E223E2514200DCD162 /* SDL_x11shape.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71623E2513E00DCD162 /* SDL_x11shape.c */; }; - A7D8B1E323E2514200DCD162 /* SDL_x11shape.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71623E2513E00DCD162 /* SDL_x11shape.c */; }; - A7D8B1E423E2514200DCD162 /* SDL_x11shape.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71623E2513E00DCD162 /* SDL_x11shape.c */; }; - A7D8B1E523E2514200DCD162 /* SDL_x11shape.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71623E2513E00DCD162 /* SDL_x11shape.c */; }; - A7D8B1E623E2514200DCD162 /* SDL_x11shape.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71623E2513E00DCD162 /* SDL_x11shape.c */; }; - A7D8B1E723E2514200DCD162 /* SDL_x11shape.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71623E2513E00DCD162 /* SDL_x11shape.c */; }; - A7D8B1E823E2514200DCD162 /* SDL_x11window.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71723E2513E00DCD162 /* SDL_x11window.h */; }; - A7D8B1E923E2514200DCD162 /* SDL_x11window.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71723E2513E00DCD162 /* SDL_x11window.h */; }; - A7D8B1EA23E2514200DCD162 /* SDL_x11window.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71723E2513E00DCD162 /* SDL_x11window.h */; }; - A7D8B1EB23E2514200DCD162 /* SDL_x11window.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71723E2513E00DCD162 /* SDL_x11window.h */; }; - A7D8B1EC23E2514200DCD162 /* SDL_x11window.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71723E2513E00DCD162 /* SDL_x11window.h */; }; - A7D8B1ED23E2514200DCD162 /* SDL_x11window.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71723E2513E00DCD162 /* SDL_x11window.h */; }; - A7D8B1EE23E2514200DCD162 /* SDL_x11framebuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71823E2513E00DCD162 /* SDL_x11framebuffer.h */; }; - A7D8B1EF23E2514200DCD162 /* SDL_x11framebuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71823E2513E00DCD162 /* SDL_x11framebuffer.h */; }; - A7D8B1F023E2514200DCD162 /* SDL_x11framebuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71823E2513E00DCD162 /* SDL_x11framebuffer.h */; }; - A7D8B1F123E2514200DCD162 /* SDL_x11framebuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71823E2513E00DCD162 /* SDL_x11framebuffer.h */; }; - A7D8B1F223E2514200DCD162 /* SDL_x11framebuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71823E2513E00DCD162 /* SDL_x11framebuffer.h */; }; - A7D8B1F323E2514200DCD162 /* SDL_x11framebuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71823E2513E00DCD162 /* SDL_x11framebuffer.h */; }; - A7D8B1F423E2514200DCD162 /* SDL_x11dyn.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71923E2513E00DCD162 /* SDL_x11dyn.h */; }; - A7D8B1F523E2514200DCD162 /* SDL_x11dyn.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71923E2513E00DCD162 /* SDL_x11dyn.h */; }; - A7D8B1F623E2514200DCD162 /* SDL_x11dyn.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71923E2513E00DCD162 /* SDL_x11dyn.h */; }; - A7D8B1F723E2514200DCD162 /* SDL_x11dyn.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71923E2513E00DCD162 /* SDL_x11dyn.h */; }; - A7D8B1F823E2514200DCD162 /* SDL_x11dyn.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71923E2513E00DCD162 /* SDL_x11dyn.h */; }; - A7D8B1F923E2514200DCD162 /* SDL_x11dyn.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71923E2513E00DCD162 /* SDL_x11dyn.h */; }; - A7D8B1FA23E2514200DCD162 /* SDL_x11mouse.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71A23E2513E00DCD162 /* SDL_x11mouse.h */; }; - A7D8B1FB23E2514200DCD162 /* SDL_x11mouse.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71A23E2513E00DCD162 /* SDL_x11mouse.h */; }; - A7D8B1FC23E2514200DCD162 /* SDL_x11mouse.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71A23E2513E00DCD162 /* SDL_x11mouse.h */; }; - A7D8B1FD23E2514200DCD162 /* SDL_x11mouse.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71A23E2513E00DCD162 /* SDL_x11mouse.h */; }; - A7D8B1FE23E2514200DCD162 /* SDL_x11mouse.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71A23E2513E00DCD162 /* SDL_x11mouse.h */; }; - A7D8B1FF23E2514200DCD162 /* SDL_x11mouse.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71A23E2513E00DCD162 /* SDL_x11mouse.h */; }; - A7D8B20023E2514200DCD162 /* SDL_x11opengles.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71B23E2513E00DCD162 /* SDL_x11opengles.c */; }; - A7D8B20123E2514200DCD162 /* SDL_x11opengles.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71B23E2513E00DCD162 /* SDL_x11opengles.c */; }; - A7D8B20223E2514200DCD162 /* SDL_x11opengles.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71B23E2513E00DCD162 /* SDL_x11opengles.c */; }; - A7D8B20323E2514200DCD162 /* SDL_x11opengles.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71B23E2513E00DCD162 /* SDL_x11opengles.c */; }; - A7D8B20423E2514200DCD162 /* SDL_x11opengles.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71B23E2513E00DCD162 /* SDL_x11opengles.c */; }; - A7D8B20523E2514200DCD162 /* SDL_x11opengles.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A71B23E2513E00DCD162 /* SDL_x11opengles.c */; }; - A7D8B20623E2514200DCD162 /* SDL_x11keyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71C23E2513E00DCD162 /* SDL_x11keyboard.h */; }; - A7D8B20723E2514200DCD162 /* SDL_x11keyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71C23E2513E00DCD162 /* SDL_x11keyboard.h */; }; - A7D8B20823E2514200DCD162 /* SDL_x11keyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71C23E2513E00DCD162 /* SDL_x11keyboard.h */; }; - A7D8B20923E2514200DCD162 /* SDL_x11keyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71C23E2513E00DCD162 /* SDL_x11keyboard.h */; }; - A7D8B20A23E2514200DCD162 /* SDL_x11keyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71C23E2513E00DCD162 /* SDL_x11keyboard.h */; }; - A7D8B20B23E2514200DCD162 /* SDL_x11keyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71C23E2513E00DCD162 /* SDL_x11keyboard.h */; }; - A7D8B20C23E2514200DCD162 /* SDL_x11clipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71D23E2513E00DCD162 /* SDL_x11clipboard.h */; }; - A7D8B20D23E2514200DCD162 /* SDL_x11clipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71D23E2513E00DCD162 /* SDL_x11clipboard.h */; }; - A7D8B20E23E2514200DCD162 /* SDL_x11clipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71D23E2513E00DCD162 /* SDL_x11clipboard.h */; }; - A7D8B20F23E2514200DCD162 /* SDL_x11clipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71D23E2513E00DCD162 /* SDL_x11clipboard.h */; }; - A7D8B21023E2514200DCD162 /* SDL_x11clipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71D23E2513E00DCD162 /* SDL_x11clipboard.h */; }; - A7D8B21123E2514200DCD162 /* SDL_x11clipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71D23E2513E00DCD162 /* SDL_x11clipboard.h */; }; - A7D8B21223E2514200DCD162 /* SDL_x11events.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71E23E2513E00DCD162 /* SDL_x11events.h */; }; - A7D8B21323E2514200DCD162 /* SDL_x11events.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71E23E2513E00DCD162 /* SDL_x11events.h */; }; - A7D8B21423E2514200DCD162 /* SDL_x11events.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71E23E2513E00DCD162 /* SDL_x11events.h */; }; - A7D8B21523E2514200DCD162 /* SDL_x11events.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71E23E2513E00DCD162 /* SDL_x11events.h */; }; - A7D8B21623E2514200DCD162 /* SDL_x11events.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71E23E2513E00DCD162 /* SDL_x11events.h */; }; - A7D8B21723E2514200DCD162 /* SDL_x11events.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71E23E2513E00DCD162 /* SDL_x11events.h */; }; - A7D8B21823E2514200DCD162 /* imKStoUCS.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71F23E2513E00DCD162 /* imKStoUCS.h */; }; - A7D8B21923E2514200DCD162 /* imKStoUCS.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71F23E2513E00DCD162 /* imKStoUCS.h */; }; - A7D8B21A23E2514200DCD162 /* imKStoUCS.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71F23E2513E00DCD162 /* imKStoUCS.h */; }; - A7D8B21B23E2514200DCD162 /* imKStoUCS.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71F23E2513E00DCD162 /* imKStoUCS.h */; }; - A7D8B21C23E2514200DCD162 /* imKStoUCS.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71F23E2513E00DCD162 /* imKStoUCS.h */; }; - A7D8B21D23E2514200DCD162 /* imKStoUCS.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A71F23E2513E00DCD162 /* imKStoUCS.h */; }; - A7D8B21E23E2514200DCD162 /* SDL_x11video.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72023E2513E00DCD162 /* SDL_x11video.h */; }; - A7D8B21F23E2514200DCD162 /* SDL_x11video.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72023E2513E00DCD162 /* SDL_x11video.h */; }; - A7D8B22023E2514200DCD162 /* SDL_x11video.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72023E2513E00DCD162 /* SDL_x11video.h */; }; - A7D8B22123E2514200DCD162 /* SDL_x11video.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72023E2513E00DCD162 /* SDL_x11video.h */; }; - A7D8B22223E2514200DCD162 /* SDL_x11video.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72023E2513E00DCD162 /* SDL_x11video.h */; }; - A7D8B22323E2514200DCD162 /* SDL_x11video.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72023E2513E00DCD162 /* SDL_x11video.h */; }; A7D8B22423E2514200DCD162 /* gl2ext.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72323E2513E00DCD162 /* gl2ext.h */; }; A7D8B22523E2514200DCD162 /* gl2ext.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72323E2513E00DCD162 /* gl2ext.h */; }; A7D8B22623E2514200DCD162 /* gl2ext.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A72323E2513E00DCD162 /* gl2ext.h */; }; @@ -2574,12 +2104,6 @@ A7D8B26923E2514200DCD162 /* vk_platform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73123E2513E00DCD162 /* vk_platform.h */; }; A7D8B26A23E2514200DCD162 /* vk_platform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73123E2513E00DCD162 /* vk_platform.h */; }; A7D8B26B23E2514200DCD162 /* vk_platform.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73123E2513E00DCD162 /* vk_platform.h */; }; - A7D8B26C23E2514200DCD162 /* vulkan.hpp in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73223E2513E00DCD162 /* vulkan.hpp */; }; - A7D8B26D23E2514200DCD162 /* vulkan.hpp in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73223E2513E00DCD162 /* vulkan.hpp */; }; - A7D8B26E23E2514200DCD162 /* vulkan.hpp in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73223E2513E00DCD162 /* vulkan.hpp */; }; - A7D8B26F23E2514200DCD162 /* vulkan.hpp in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73223E2513E00DCD162 /* vulkan.hpp */; }; - A7D8B27023E2514200DCD162 /* vulkan.hpp in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73223E2513E00DCD162 /* vulkan.hpp */; }; - A7D8B27123E2514200DCD162 /* vulkan.hpp in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73223E2513E00DCD162 /* vulkan.hpp */; }; A7D8B27223E2514200DCD162 /* vulkan_fuchsia.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73323E2513E00DCD162 /* vulkan_fuchsia.h */; }; A7D8B27323E2514200DCD162 /* vulkan_fuchsia.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73323E2513E00DCD162 /* vulkan_fuchsia.h */; }; A7D8B27423E2514200DCD162 /* vulkan_fuchsia.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73323E2513E00DCD162 /* vulkan_fuchsia.h */; }; @@ -2616,12 +2140,6 @@ A7D8B29323E2514200DCD162 /* vulkan_xcb.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73823E2513E00DCD162 /* vulkan_xcb.h */; }; A7D8B29423E2514200DCD162 /* vulkan_xcb.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73823E2513E00DCD162 /* vulkan_xcb.h */; }; A7D8B29523E2514200DCD162 /* vulkan_xcb.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73823E2513E00DCD162 /* vulkan_xcb.h */; }; - A7D8B29623E2514200DCD162 /* vulkan_mir.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73923E2513E00DCD162 /* vulkan_mir.h */; }; - A7D8B29723E2514200DCD162 /* vulkan_mir.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73923E2513E00DCD162 /* vulkan_mir.h */; }; - A7D8B29823E2514200DCD162 /* vulkan_mir.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73923E2513E00DCD162 /* vulkan_mir.h */; }; - A7D8B29923E2514200DCD162 /* vulkan_mir.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73923E2513E00DCD162 /* vulkan_mir.h */; }; - A7D8B29A23E2514200DCD162 /* vulkan_mir.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73923E2513E00DCD162 /* vulkan_mir.h */; }; - A7D8B29B23E2514200DCD162 /* vulkan_mir.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73923E2513E00DCD162 /* vulkan_mir.h */; }; A7D8B29C23E2514200DCD162 /* vulkan_xlib.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73A23E2513E00DCD162 /* vulkan_xlib.h */; }; A7D8B29D23E2514200DCD162 /* vulkan_xlib.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73A23E2513E00DCD162 /* vulkan_xlib.h */; }; A7D8B29E23E2514200DCD162 /* vulkan_xlib.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A73A23E2513E00DCD162 /* vulkan_xlib.h */; }; @@ -2700,12 +2218,6 @@ A7D8B3B923E2514200DCD162 /* SDL_blit.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76B23E2513E00DCD162 /* SDL_blit.h */; }; A7D8B3BA23E2514200DCD162 /* SDL_blit.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76B23E2513E00DCD162 /* SDL_blit.h */; }; A7D8B3BB23E2514200DCD162 /* SDL_blit.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A76B23E2513E00DCD162 /* SDL_blit.h */; }; - A7D8B3BF23E2514200DCD162 /* yuv_rgb.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A76E23E2513E00DCD162 /* yuv_rgb.c */; }; - A7D8B3C023E2514200DCD162 /* yuv_rgb.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A76E23E2513E00DCD162 /* yuv_rgb.c */; }; - A7D8B3C123E2514200DCD162 /* yuv_rgb.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A76E23E2513E00DCD162 /* yuv_rgb.c */; }; - A7D8B3C223E2514200DCD162 /* yuv_rgb.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A76E23E2513E00DCD162 /* yuv_rgb.c */; }; - A7D8B3C323E2514200DCD162 /* yuv_rgb.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A76E23E2513E00DCD162 /* yuv_rgb.c */; }; - A7D8B3C423E2514200DCD162 /* yuv_rgb.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A76E23E2513E00DCD162 /* yuv_rgb.c */; }; A7D8B3C823E2514200DCD162 /* yuv_rgb_sse_func.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77023E2513E00DCD162 /* yuv_rgb_sse_func.h */; }; A7D8B3C923E2514300DCD162 /* yuv_rgb_sse_func.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77023E2513E00DCD162 /* yuv_rgb_sse_func.h */; }; A7D8B3CA23E2514300DCD162 /* yuv_rgb_sse_func.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A77023E2513E00DCD162 /* yuv_rgb_sse_func.h */; }; @@ -2820,10 +2332,6 @@ A7D8B4DF23E2514300DCD162 /* SDL_joystick.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7A923E2513E00DCD162 /* SDL_joystick.c */; }; A7D8B4E023E2514300DCD162 /* SDL_joystick.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7A923E2513E00DCD162 /* SDL_joystick.c */; }; A7D8B4E123E2514300DCD162 /* SDL_joystick.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7A923E2513E00DCD162 /* SDL_joystick.c */; }; - A7D8B4E423E2514300DCD162 /* SDL_sysjoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7AB23E2513E00DCD162 /* SDL_sysjoystick.m */; }; - A7D8B4E623E2514300DCD162 /* SDL_sysjoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7AB23E2513E00DCD162 /* SDL_sysjoystick.m */; }; - A7D8B4EA23E2514300DCD162 /* SDL_sysjoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7AC23E2513E00DCD162 /* SDL_sysjoystick_c.h */; }; - A7D8B4EC23E2514300DCD162 /* SDL_sysjoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7AC23E2513E00DCD162 /* SDL_sysjoystick_c.h */; }; A7D8B4EE23E2514300DCD162 /* SDL_gamecontroller.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7AD23E2513E00DCD162 /* SDL_gamecontroller.c */; }; A7D8B4EF23E2514300DCD162 /* SDL_gamecontroller.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7AD23E2513E00DCD162 /* SDL_gamecontroller.c */; }; A7D8B4F023E2514300DCD162 /* SDL_gamecontroller.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7AD23E2513E00DCD162 /* SDL_gamecontroller.c */; }; @@ -2884,18 +2392,6 @@ A7D8B57223E2514300DCD162 /* usb_ids.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7CB23E2513E00DCD162 /* usb_ids.h */; }; A7D8B57323E2514300DCD162 /* usb_ids.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7CB23E2513E00DCD162 /* usb_ids.h */; }; A7D8B57423E2514300DCD162 /* usb_ids.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7CB23E2513E00DCD162 /* usb_ids.h */; }; - A7D8B57523E2514300DCD162 /* SDL_sysjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7CD23E2513E00DCD162 /* SDL_sysjoystick.c */; }; - A7D8B57623E2514300DCD162 /* SDL_sysjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7CD23E2513E00DCD162 /* SDL_sysjoystick.c */; }; - A7D8B57723E2514300DCD162 /* SDL_sysjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7CD23E2513E00DCD162 /* SDL_sysjoystick.c */; }; - A7D8B57823E2514300DCD162 /* SDL_sysjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7CD23E2513E00DCD162 /* SDL_sysjoystick.c */; }; - A7D8B57923E2514300DCD162 /* SDL_sysjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7CD23E2513E00DCD162 /* SDL_sysjoystick.c */; }; - A7D8B57A23E2514300DCD162 /* SDL_sysjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7CD23E2513E00DCD162 /* SDL_sysjoystick.c */; }; - A7D8B57B23E2514300DCD162 /* SDL_sysjoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7CE23E2513E00DCD162 /* SDL_sysjoystick_c.h */; }; - A7D8B57C23E2514300DCD162 /* SDL_sysjoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7CE23E2513E00DCD162 /* SDL_sysjoystick_c.h */; }; - A7D8B57D23E2514300DCD162 /* SDL_sysjoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7CE23E2513E00DCD162 /* SDL_sysjoystick_c.h */; }; - A7D8B57E23E2514300DCD162 /* SDL_sysjoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7CE23E2513E00DCD162 /* SDL_sysjoystick_c.h */; }; - A7D8B57F23E2514300DCD162 /* SDL_sysjoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7CE23E2513E00DCD162 /* SDL_sysjoystick_c.h */; }; - A7D8B58023E2514300DCD162 /* SDL_sysjoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7CE23E2513E00DCD162 /* SDL_sysjoystick_c.h */; }; A7D8B58123E2514300DCD162 /* SDL_sysjoystick.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7CF23E2513E00DCD162 /* SDL_sysjoystick.h */; }; A7D8B58223E2514300DCD162 /* SDL_sysjoystick.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7CF23E2513E00DCD162 /* SDL_sysjoystick.h */; }; A7D8B58323E2514300DCD162 /* SDL_sysjoystick.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7CF23E2513E00DCD162 /* SDL_sysjoystick.h */; }; @@ -3622,12 +3118,6 @@ A7D8BB9023E2514500DCD162 /* SDL_touch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93E23E2514000DCD162 /* SDL_touch.c */; }; A7D8BB9123E2514500DCD162 /* SDL_touch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93E23E2514000DCD162 /* SDL_touch.c */; }; A7D8BB9223E2514500DCD162 /* SDL_touch.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A93E23E2514000DCD162 /* SDL_touch.c */; }; - A7D8BB9323E2514500DCD162 /* SDL_sysevents.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93F23E2514000DCD162 /* SDL_sysevents.h */; }; - A7D8BB9423E2514500DCD162 /* SDL_sysevents.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93F23E2514000DCD162 /* SDL_sysevents.h */; }; - A7D8BB9523E2514500DCD162 /* SDL_sysevents.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93F23E2514000DCD162 /* SDL_sysevents.h */; }; - A7D8BB9623E2514500DCD162 /* SDL_sysevents.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93F23E2514000DCD162 /* SDL_sysevents.h */; }; - A7D8BB9723E2514500DCD162 /* SDL_sysevents.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93F23E2514000DCD162 /* SDL_sysevents.h */; }; - A7D8BB9823E2514500DCD162 /* SDL_sysevents.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A93F23E2514000DCD162 /* SDL_sysevents.h */; }; A7D8BB9923E2514500DCD162 /* SDL_gesture.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A94023E2514000DCD162 /* SDL_gesture.c */; }; A7D8BB9A23E2514500DCD162 /* SDL_gesture.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A94023E2514000DCD162 /* SDL_gesture.c */; }; A7D8BB9B23E2514500DCD162 /* SDL_gesture.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A94023E2514000DCD162 /* SDL_gesture.c */; }; @@ -3658,15 +3148,12 @@ A7D8BBB423E2514500DCD162 /* SDL_assert.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A94423E2514000DCD162 /* SDL_assert.c */; }; A7D8BBB523E2514500DCD162 /* SDL_assert.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A94423E2514000DCD162 /* SDL_assert.c */; }; A7D8BBB623E2514500DCD162 /* SDL_assert.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A94423E2514000DCD162 /* SDL_assert.c */; }; - A7D8BBB723E254E400DCD162 /* SDL_sysjoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7AB23E2513E00DCD162 /* SDL_sysjoystick.m */; }; - A7D8BBB823E254E400DCD162 /* SDL_sysjoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7AC23E2513E00DCD162 /* SDL_sysjoystick_c.h */; }; A7D8BBB923E2560500DCD162 /* SDL_steamcontroller.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7A723E2513E00DCD162 /* SDL_steamcontroller.c */; }; A7D8BBBA23E2560600DCD162 /* SDL_steamcontroller.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7A723E2513E00DCD162 /* SDL_steamcontroller.c */; }; A7D8BBC523E2561500DCD162 /* SDL_steamcontroller.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A7A723E2513E00DCD162 /* SDL_steamcontroller.c */; }; A7D8BBC723E2561500DCD162 /* SDL_steamcontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7A523E2513E00DCD162 /* SDL_steamcontroller.h */; }; A7D8BBCB23E2561600DCD162 /* SDL_steamcontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7A523E2513E00DCD162 /* SDL_steamcontroller.h */; }; A7D8BBCF23E2561600DCD162 /* SDL_steamcontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A7A523E2513E00DCD162 /* SDL_steamcontroller.h */; }; - A7D8BBD123E2574800DCD162 /* keyinfotable.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62823E2513D00DCD162 /* keyinfotable.h */; }; A7D8BBD223E2574800DCD162 /* SDL_uikitappdelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62F23E2513D00DCD162 /* SDL_uikitappdelegate.h */; }; A7D8BBD323E2574800DCD162 /* SDL_uikitappdelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61E23E2513D00DCD162 /* SDL_uikitappdelegate.m */; }; A7D8BBD423E2574800DCD162 /* SDL_uikitclipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62123E2513D00DCD162 /* SDL_uikitclipboard.h */; }; @@ -3693,7 +3180,6 @@ A7D8BBE923E2574800DCD162 /* SDL_uikitvulkan.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A62523E2513D00DCD162 /* SDL_uikitvulkan.m */; }; A7D8BBEA23E2574800DCD162 /* SDL_uikitwindow.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62723E2513D00DCD162 /* SDL_uikitwindow.h */; }; A7D8BBEB23E2574800DCD162 /* SDL_uikitwindow.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61A23E2513D00DCD162 /* SDL_uikitwindow.m */; }; - A7D8BBEC23E2574800DCD162 /* keyinfotable.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62823E2513D00DCD162 /* keyinfotable.h */; }; A7D8BBED23E2574800DCD162 /* SDL_uikitappdelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62F23E2513D00DCD162 /* SDL_uikitappdelegate.h */; }; A7D8BBEE23E2574800DCD162 /* SDL_uikitappdelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61E23E2513D00DCD162 /* SDL_uikitappdelegate.m */; }; A7D8BBEF23E2574800DCD162 /* SDL_uikitclipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = A7D8A62123E2513D00DCD162 /* SDL_uikitclipboard.h */; }; @@ -3722,127 +3208,69 @@ A7D8BC0623E2574800DCD162 /* SDL_uikitwindow.m in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A61A23E2513D00DCD162 /* SDL_uikitwindow.m */; }; A7D8BC0723E2590800DCD162 /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A5B023E2513D00DCD162 /* SDL_uikit_main.c */; }; AA7557FA1595D4D800BBD41B /* begin_code.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557C71595D4D800BBD41B /* begin_code.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA7557FB1595D4D800BBD41B /* begin_code.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557C71595D4D800BBD41B /* begin_code.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA7557FC1595D4D800BBD41B /* close_code.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557C81595D4D800BBD41B /* close_code.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA7557FD1595D4D800BBD41B /* close_code.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557C81595D4D800BBD41B /* close_code.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA7557FE1595D4D800BBD41B /* SDL_assert.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557C91595D4D800BBD41B /* SDL_assert.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA7557FF1595D4D800BBD41B /* SDL_assert.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557C91595D4D800BBD41B /* SDL_assert.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA7558001595D4D800BBD41B /* SDL_atomic.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557CA1595D4D800BBD41B /* SDL_atomic.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA7558011595D4D800BBD41B /* SDL_atomic.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557CA1595D4D800BBD41B /* SDL_atomic.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA7558021595D4D800BBD41B /* SDL_audio.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557CB1595D4D800BBD41B /* SDL_audio.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA7558031595D4D800BBD41B /* SDL_audio.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557CB1595D4D800BBD41B /* SDL_audio.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA7558041595D4D800BBD41B /* SDL_blendmode.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557CC1595D4D800BBD41B /* SDL_blendmode.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA7558051595D4D800BBD41B /* SDL_blendmode.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557CC1595D4D800BBD41B /* SDL_blendmode.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA7558061595D4D800BBD41B /* SDL_clipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557CD1595D4D800BBD41B /* SDL_clipboard.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA7558071595D4D800BBD41B /* SDL_clipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557CD1595D4D800BBD41B /* SDL_clipboard.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA7558081595D4D800BBD41B /* SDL_config_macosx.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557CE1595D4D800BBD41B /* SDL_config_macosx.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA7558091595D4D800BBD41B /* SDL_config_macosx.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557CE1595D4D800BBD41B /* SDL_config_macosx.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA75580A1595D4D800BBD41B /* SDL_config.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557CF1595D4D800BBD41B /* SDL_config.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA75580B1595D4D800BBD41B /* SDL_config.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557CF1595D4D800BBD41B /* SDL_config.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA75580C1595D4D800BBD41B /* SDL_copying.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D01595D4D800BBD41B /* SDL_copying.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA75580D1595D4D800BBD41B /* SDL_copying.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D01595D4D800BBD41B /* SDL_copying.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA75580E1595D4D800BBD41B /* SDL_cpuinfo.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D11595D4D800BBD41B /* SDL_cpuinfo.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA75580F1595D4D800BBD41B /* SDL_cpuinfo.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D11595D4D800BBD41B /* SDL_cpuinfo.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA7558101595D4D800BBD41B /* SDL_endian.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D21595D4D800BBD41B /* SDL_endian.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA7558111595D4D800BBD41B /* SDL_endian.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D21595D4D800BBD41B /* SDL_endian.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA7558121595D4D800BBD41B /* SDL_error.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D31595D4D800BBD41B /* SDL_error.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA7558131595D4D800BBD41B /* SDL_error.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D31595D4D800BBD41B /* SDL_error.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA7558141595D4D800BBD41B /* SDL_events.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D41595D4D800BBD41B /* SDL_events.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA7558151595D4D800BBD41B /* SDL_events.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D41595D4D800BBD41B /* SDL_events.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA7558161595D4D800BBD41B /* SDL_gesture.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D51595D4D800BBD41B /* SDL_gesture.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA7558171595D4D800BBD41B /* SDL_gesture.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D51595D4D800BBD41B /* SDL_gesture.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA7558181595D4D800BBD41B /* SDL_haptic.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D61595D4D800BBD41B /* SDL_haptic.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA7558191595D4D800BBD41B /* SDL_haptic.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D61595D4D800BBD41B /* SDL_haptic.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA75581A1595D4D800BBD41B /* SDL_hints.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D71595D4D800BBD41B /* SDL_hints.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA75581B1595D4D800BBD41B /* SDL_hints.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D71595D4D800BBD41B /* SDL_hints.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA75581E1595D4D800BBD41B /* SDL_joystick.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D91595D4D800BBD41B /* SDL_joystick.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA75581F1595D4D800BBD41B /* SDL_joystick.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557D91595D4D800BBD41B /* SDL_joystick.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA7558201595D4D800BBD41B /* SDL_keyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557DA1595D4D800BBD41B /* SDL_keyboard.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA7558211595D4D800BBD41B /* SDL_keyboard.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557DA1595D4D800BBD41B /* SDL_keyboard.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA7558221595D4D800BBD41B /* SDL_keycode.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557DB1595D4D800BBD41B /* SDL_keycode.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA7558231595D4D800BBD41B /* SDL_keycode.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557DB1595D4D800BBD41B /* SDL_keycode.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA7558241595D4D800BBD41B /* SDL_loadso.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557DC1595D4D800BBD41B /* SDL_loadso.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA7558251595D4D800BBD41B /* SDL_loadso.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557DC1595D4D800BBD41B /* SDL_loadso.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA7558261595D4D800BBD41B /* SDL_log.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557DD1595D4D800BBD41B /* SDL_log.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA7558271595D4D800BBD41B /* SDL_log.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557DD1595D4D800BBD41B /* SDL_log.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA7558281595D4D800BBD41B /* SDL_main.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557DE1595D4D800BBD41B /* SDL_main.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA7558291595D4D800BBD41B /* SDL_main.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557DE1595D4D800BBD41B /* SDL_main.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA75582A1595D4D800BBD41B /* SDL_mouse.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557DF1595D4D800BBD41B /* SDL_mouse.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA75582B1595D4D800BBD41B /* SDL_mouse.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557DF1595D4D800BBD41B /* SDL_mouse.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA75582C1595D4D800BBD41B /* SDL_mutex.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E01595D4D800BBD41B /* SDL_mutex.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA75582D1595D4D800BBD41B /* SDL_mutex.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E01595D4D800BBD41B /* SDL_mutex.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA75582E1595D4D800BBD41B /* SDL_name.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E11595D4D800BBD41B /* SDL_name.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA75582F1595D4D800BBD41B /* SDL_name.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E11595D4D800BBD41B /* SDL_name.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA7558301595D4D800BBD41B /* SDL_opengl.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E21595D4D800BBD41B /* SDL_opengl.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA7558311595D4D800BBD41B /* SDL_opengl.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E21595D4D800BBD41B /* SDL_opengl.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA7558321595D4D800BBD41B /* SDL_opengles.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E31595D4D800BBD41B /* SDL_opengles.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA7558331595D4D800BBD41B /* SDL_opengles.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E31595D4D800BBD41B /* SDL_opengles.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA7558341595D4D800BBD41B /* SDL_opengles2.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E41595D4D800BBD41B /* SDL_opengles2.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA7558351595D4D800BBD41B /* SDL_opengles2.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E41595D4D800BBD41B /* SDL_opengles2.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA7558361595D4D800BBD41B /* SDL_pixels.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E51595D4D800BBD41B /* SDL_pixels.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA7558371595D4D800BBD41B /* SDL_pixels.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E51595D4D800BBD41B /* SDL_pixels.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA7558381595D4D800BBD41B /* SDL_platform.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E61595D4D800BBD41B /* SDL_platform.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA7558391595D4D800BBD41B /* SDL_platform.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E61595D4D800BBD41B /* SDL_platform.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA75583A1595D4D800BBD41B /* SDL_power.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E71595D4D800BBD41B /* SDL_power.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA75583B1595D4D800BBD41B /* SDL_power.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E71595D4D800BBD41B /* SDL_power.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA75583C1595D4D800BBD41B /* SDL_quit.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E81595D4D800BBD41B /* SDL_quit.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA75583D1595D4D800BBD41B /* SDL_quit.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E81595D4D800BBD41B /* SDL_quit.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA75583E1595D4D800BBD41B /* SDL_rect.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E91595D4D800BBD41B /* SDL_rect.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA75583F1595D4D800BBD41B /* SDL_rect.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557E91595D4D800BBD41B /* SDL_rect.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA7558401595D4D800BBD41B /* SDL_render.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557EA1595D4D800BBD41B /* SDL_render.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA7558411595D4D800BBD41B /* SDL_render.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557EA1595D4D800BBD41B /* SDL_render.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA7558421595D4D800BBD41B /* SDL_revision.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557EB1595D4D800BBD41B /* SDL_revision.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA7558431595D4D800BBD41B /* SDL_revision.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557EB1595D4D800BBD41B /* SDL_revision.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA7558441595D4D800BBD41B /* SDL_rwops.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557EC1595D4D800BBD41B /* SDL_rwops.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA7558451595D4D800BBD41B /* SDL_rwops.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557EC1595D4D800BBD41B /* SDL_rwops.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA7558461595D4D800BBD41B /* SDL_scancode.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557ED1595D4D800BBD41B /* SDL_scancode.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA7558471595D4D800BBD41B /* SDL_scancode.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557ED1595D4D800BBD41B /* SDL_scancode.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA7558481595D4D800BBD41B /* SDL_shape.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557EE1595D4D800BBD41B /* SDL_shape.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA7558491595D4D800BBD41B /* SDL_shape.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557EE1595D4D800BBD41B /* SDL_shape.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA75584A1595D4D800BBD41B /* SDL_stdinc.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557EF1595D4D800BBD41B /* SDL_stdinc.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA75584B1595D4D800BBD41B /* SDL_stdinc.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557EF1595D4D800BBD41B /* SDL_stdinc.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA75584C1595D4D800BBD41B /* SDL_surface.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F01595D4D800BBD41B /* SDL_surface.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA75584D1595D4D800BBD41B /* SDL_surface.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F01595D4D800BBD41B /* SDL_surface.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA75584E1595D4D800BBD41B /* SDL_system.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F11595D4D800BBD41B /* SDL_system.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA75584F1595D4D800BBD41B /* SDL_system.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F11595D4D800BBD41B /* SDL_system.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA7558501595D4D800BBD41B /* SDL_syswm.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F21595D4D800BBD41B /* SDL_syswm.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA7558511595D4D800BBD41B /* SDL_syswm.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F21595D4D800BBD41B /* SDL_syswm.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA7558521595D4D800BBD41B /* SDL_thread.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F31595D4D800BBD41B /* SDL_thread.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA7558531595D4D800BBD41B /* SDL_thread.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F31595D4D800BBD41B /* SDL_thread.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA7558541595D4D800BBD41B /* SDL_timer.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F41595D4D800BBD41B /* SDL_timer.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA7558551595D4D800BBD41B /* SDL_timer.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F41595D4D800BBD41B /* SDL_timer.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA7558561595D4D800BBD41B /* SDL_touch.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F51595D4D800BBD41B /* SDL_touch.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA7558571595D4D800BBD41B /* SDL_touch.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F51595D4D800BBD41B /* SDL_touch.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA7558581595D4D800BBD41B /* SDL_types.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F61595D4D800BBD41B /* SDL_types.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA7558591595D4D800BBD41B /* SDL_types.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F61595D4D800BBD41B /* SDL_types.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA75585A1595D4D800BBD41B /* SDL_version.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F71595D4D800BBD41B /* SDL_version.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA75585B1595D4D800BBD41B /* SDL_version.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F71595D4D800BBD41B /* SDL_version.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA75585C1595D4D800BBD41B /* SDL_video.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F81595D4D800BBD41B /* SDL_video.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA75585D1595D4D800BBD41B /* SDL_video.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F81595D4D800BBD41B /* SDL_video.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA75585E1595D4D800BBD41B /* SDL.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F91595D4D800BBD41B /* SDL.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AA75585F1595D4D800BBD41B /* SDL.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557F91595D4D800BBD41B /* SDL.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA8167541F5E727800518735 /* SDL_vulkan.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D4820431F0F10B400EDC31C /* SDL_vulkan.h */; settings = {ATTRIBUTES = (Public, ); }; }; AA9FF95A1637CBF9000DF050 /* SDL_messagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = AA9FF9591637CBF9000DF050 /* SDL_messagebox.h */; settings = {ATTRIBUTES = (Public, ); }; }; AAC070F9195606770073DCDF /* SDL_opengl_glext.h in Headers */ = {isa = PBXBuildFile; fileRef = AAC070F4195606770073DCDF /* SDL_opengl_glext.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AAC070FA195606770073DCDF /* SDL_opengl_glext.h in Headers */ = {isa = PBXBuildFile; fileRef = AAC070F4195606770073DCDF /* SDL_opengl_glext.h */; settings = {ATTRIBUTES = (Public, ); }; }; AAC070FB195606770073DCDF /* SDL_opengl_glext.h in Headers */ = {isa = PBXBuildFile; fileRef = AAC070F4195606770073DCDF /* SDL_opengl_glext.h */; settings = {ATTRIBUTES = (Public, ); }; }; AAC070FC195606770073DCDF /* SDL_opengles2_gl2.h in Headers */ = {isa = PBXBuildFile; fileRef = AAC070F5195606770073DCDF /* SDL_opengles2_gl2.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AAC070FD195606770073DCDF /* SDL_opengles2_gl2.h in Headers */ = {isa = PBXBuildFile; fileRef = AAC070F5195606770073DCDF /* SDL_opengles2_gl2.h */; settings = {ATTRIBUTES = (Public, ); }; }; AAC070FE195606770073DCDF /* SDL_opengles2_gl2.h in Headers */ = {isa = PBXBuildFile; fileRef = AAC070F5195606770073DCDF /* SDL_opengles2_gl2.h */; settings = {ATTRIBUTES = (Public, ); }; }; AAC070FF195606770073DCDF /* SDL_opengles2_gl2ext.h in Headers */ = {isa = PBXBuildFile; fileRef = AAC070F6195606770073DCDF /* SDL_opengles2_gl2ext.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AAC07100195606770073DCDF /* SDL_opengles2_gl2ext.h in Headers */ = {isa = PBXBuildFile; fileRef = AAC070F6195606770073DCDF /* SDL_opengles2_gl2ext.h */; settings = {ATTRIBUTES = (Public, ); }; }; AAC07101195606770073DCDF /* SDL_opengles2_gl2ext.h in Headers */ = {isa = PBXBuildFile; fileRef = AAC070F6195606770073DCDF /* SDL_opengles2_gl2ext.h */; settings = {ATTRIBUTES = (Public, ); }; }; AAC07102195606770073DCDF /* SDL_opengles2_gl2platform.h in Headers */ = {isa = PBXBuildFile; fileRef = AAC070F7195606770073DCDF /* SDL_opengles2_gl2platform.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AAC07103195606770073DCDF /* SDL_opengles2_gl2platform.h in Headers */ = {isa = PBXBuildFile; fileRef = AAC070F7195606770073DCDF /* SDL_opengles2_gl2platform.h */; settings = {ATTRIBUTES = (Public, ); }; }; AAC07104195606770073DCDF /* SDL_opengles2_gl2platform.h in Headers */ = {isa = PBXBuildFile; fileRef = AAC070F7195606770073DCDF /* SDL_opengles2_gl2platform.h */; settings = {ATTRIBUTES = (Public, ); }; }; AAC07105195606770073DCDF /* SDL_opengles2_khrplatform.h in Headers */ = {isa = PBXBuildFile; fileRef = AAC070F8195606770073DCDF /* SDL_opengles2_khrplatform.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AAC07106195606770073DCDF /* SDL_opengles2_khrplatform.h in Headers */ = {isa = PBXBuildFile; fileRef = AAC070F8195606770073DCDF /* SDL_opengles2_khrplatform.h */; settings = {ATTRIBUTES = (Public, ); }; }; AAC07107195606770073DCDF /* SDL_opengles2_khrplatform.h in Headers */ = {isa = PBXBuildFile; fileRef = AAC070F8195606770073DCDF /* SDL_opengles2_khrplatform.h */; settings = {ATTRIBUTES = (Public, ); }; }; AADA5B8716CCAB3000107CF7 /* SDL_bits.h in Headers */ = {isa = PBXBuildFile; fileRef = AADA5B8616CCAB3000107CF7 /* SDL_bits.h */; settings = {ATTRIBUTES = (Public, ); }; }; - AADA5B8816CCAB3000107CF7 /* SDL_bits.h in Headers */ = {isa = PBXBuildFile; fileRef = AADA5B8616CCAB3000107CF7 /* SDL_bits.h */; settings = {ATTRIBUTES = (Public, ); }; }; DB0F489317C400E6008798C5 /* SDL_messagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = AA9FF9591637CBF9000DF050 /* SDL_messagebox.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DB0F489417C400ED008798C5 /* SDL_messagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = AA9FF9591637CBF9000DF050 /* SDL_messagebox.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DB0F490B17CA57ED008798C5 /* SDL_filesystem.h in Headers */ = {isa = PBXBuildFile; fileRef = 567E2F2017C44C35005F1892 /* SDL_filesystem.h */; settings = {ATTRIBUTES = (Public, ); }; }; DB0F490C17CA57ED008798C5 /* SDL_filesystem.h in Headers */ = {isa = PBXBuildFile; fileRef = 567E2F2017C44C35005F1892 /* SDL_filesystem.h */; settings = {ATTRIBUTES = (Public, ); }; }; DB313FC817554B71006C0E22 /* begin_code.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557C71595D4D800BBD41B /* begin_code.h */; settings = {ATTRIBUTES = (Public, ); }; }; DB313FC917554B71006C0E22 /* close_code.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7557C81595D4D800BBD41B /* close_code.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -3900,9 +3328,395 @@ DB31407017554B71006C0E22 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0073179F0858DECD00B2BC32 /* IOKit.framework */; }; DB31407217554B71006C0E22 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 007317C10858E15000B2BC32 /* Carbon.framework */; }; DB31408D17554D3C006C0E22 /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00CFA89C106B4BA100758660 /* ForceFeedback.framework */; }; + F316AB852B5A02C3002EF551 /* yuv_rgb_common.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB7C2B5A02C2002EF551 /* yuv_rgb_common.h */; }; + F316AB862B5A02C3002EF551 /* yuv_rgb_common.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB7C2B5A02C2002EF551 /* yuv_rgb_common.h */; }; + F316AB872B5A02C3002EF551 /* yuv_rgb_common.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB7C2B5A02C2002EF551 /* yuv_rgb_common.h */; }; + F316AB882B5A02C3002EF551 /* yuv_rgb_common.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB7C2B5A02C2002EF551 /* yuv_rgb_common.h */; }; + F316AB892B5A02C3002EF551 /* yuv_rgb_common.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB7C2B5A02C2002EF551 /* yuv_rgb_common.h */; }; + F316AB8A2B5A02C3002EF551 /* yuv_rgb_common.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB7C2B5A02C2002EF551 /* yuv_rgb_common.h */; }; + F316AB8B2B5A02C3002EF551 /* yuv_rgb_common.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB7C2B5A02C2002EF551 /* yuv_rgb_common.h */; }; + F316AB8C2B5A02C3002EF551 /* yuv_rgb_common.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB7C2B5A02C2002EF551 /* yuv_rgb_common.h */; }; + F316AB8D2B5A02C3002EF551 /* yuv_rgb_common.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB7C2B5A02C2002EF551 /* yuv_rgb_common.h */; }; + F316AB8E2B5A02C3002EF551 /* yuv_rgb_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB7D2B5A02C2002EF551 /* yuv_rgb_internal.h */; }; + F316AB8F2B5A02C3002EF551 /* yuv_rgb_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB7D2B5A02C2002EF551 /* yuv_rgb_internal.h */; }; + F316AB902B5A02C3002EF551 /* yuv_rgb_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB7D2B5A02C2002EF551 /* yuv_rgb_internal.h */; }; + F316AB912B5A02C3002EF551 /* yuv_rgb_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB7D2B5A02C2002EF551 /* yuv_rgb_internal.h */; }; + F316AB922B5A02C3002EF551 /* yuv_rgb_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB7D2B5A02C2002EF551 /* yuv_rgb_internal.h */; }; + F316AB932B5A02C3002EF551 /* yuv_rgb_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB7D2B5A02C2002EF551 /* yuv_rgb_internal.h */; }; + F316AB942B5A02C3002EF551 /* yuv_rgb_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB7D2B5A02C2002EF551 /* yuv_rgb_internal.h */; }; + F316AB952B5A02C3002EF551 /* yuv_rgb_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB7D2B5A02C2002EF551 /* yuv_rgb_internal.h */; }; + F316AB962B5A02C3002EF551 /* yuv_rgb_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB7D2B5A02C2002EF551 /* yuv_rgb_internal.h */; }; + F316AB972B5A02C3002EF551 /* yuv_rgb_std.c in Sources */ = {isa = PBXBuildFile; fileRef = F316AB7E2B5A02C3002EF551 /* yuv_rgb_std.c */; }; + F316AB982B5A02C3002EF551 /* yuv_rgb_std.c in Sources */ = {isa = PBXBuildFile; fileRef = F316AB7E2B5A02C3002EF551 /* yuv_rgb_std.c */; }; + F316AB992B5A02C3002EF551 /* yuv_rgb_std.c in Sources */ = {isa = PBXBuildFile; fileRef = F316AB7E2B5A02C3002EF551 /* yuv_rgb_std.c */; }; + F316AB9A2B5A02C3002EF551 /* yuv_rgb_std.c in Sources */ = {isa = PBXBuildFile; fileRef = F316AB7E2B5A02C3002EF551 /* yuv_rgb_std.c */; }; + F316AB9B2B5A02C3002EF551 /* yuv_rgb_std.c in Sources */ = {isa = PBXBuildFile; fileRef = F316AB7E2B5A02C3002EF551 /* yuv_rgb_std.c */; }; + F316AB9C2B5A02C3002EF551 /* yuv_rgb_std.c in Sources */ = {isa = PBXBuildFile; fileRef = F316AB7E2B5A02C3002EF551 /* yuv_rgb_std.c */; }; + F316AB9D2B5A02C3002EF551 /* yuv_rgb_std.c in Sources */ = {isa = PBXBuildFile; fileRef = F316AB7E2B5A02C3002EF551 /* yuv_rgb_std.c */; }; + F316AB9E2B5A02C3002EF551 /* yuv_rgb_std.c in Sources */ = {isa = PBXBuildFile; fileRef = F316AB7E2B5A02C3002EF551 /* yuv_rgb_std.c */; }; + F316AB9F2B5A02C3002EF551 /* yuv_rgb_std.c in Sources */ = {isa = PBXBuildFile; fileRef = F316AB7E2B5A02C3002EF551 /* yuv_rgb_std.c */; }; + F316ABA02B5A02C3002EF551 /* yuv_rgb_sse.c in Sources */ = {isa = PBXBuildFile; fileRef = F316AB7F2B5A02C3002EF551 /* yuv_rgb_sse.c */; }; + F316ABA12B5A02C3002EF551 /* yuv_rgb_sse.c in Sources */ = {isa = PBXBuildFile; fileRef = F316AB7F2B5A02C3002EF551 /* yuv_rgb_sse.c */; }; + F316ABA22B5A02C3002EF551 /* yuv_rgb_sse.c in Sources */ = {isa = PBXBuildFile; fileRef = F316AB7F2B5A02C3002EF551 /* yuv_rgb_sse.c */; }; + F316ABA32B5A02C3002EF551 /* yuv_rgb_sse.c in Sources */ = {isa = PBXBuildFile; fileRef = F316AB7F2B5A02C3002EF551 /* yuv_rgb_sse.c */; }; + F316ABA42B5A02C3002EF551 /* yuv_rgb_sse.c in Sources */ = {isa = PBXBuildFile; fileRef = F316AB7F2B5A02C3002EF551 /* yuv_rgb_sse.c */; }; + F316ABA52B5A02C3002EF551 /* yuv_rgb_sse.c in Sources */ = {isa = PBXBuildFile; fileRef = F316AB7F2B5A02C3002EF551 /* yuv_rgb_sse.c */; }; + F316ABA62B5A02C3002EF551 /* yuv_rgb_sse.c in Sources */ = {isa = PBXBuildFile; fileRef = F316AB7F2B5A02C3002EF551 /* yuv_rgb_sse.c */; }; + F316ABA72B5A02C3002EF551 /* yuv_rgb_sse.c in Sources */ = {isa = PBXBuildFile; fileRef = F316AB7F2B5A02C3002EF551 /* yuv_rgb_sse.c */; }; + F316ABA82B5A02C3002EF551 /* yuv_rgb_sse.c in Sources */ = {isa = PBXBuildFile; fileRef = F316AB7F2B5A02C3002EF551 /* yuv_rgb_sse.c */; }; + F316ABA92B5A02C3002EF551 /* yuv_rgb_lsx.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB802B5A02C3002EF551 /* yuv_rgb_lsx.h */; }; + F316ABAA2B5A02C3002EF551 /* yuv_rgb_lsx.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB802B5A02C3002EF551 /* yuv_rgb_lsx.h */; }; + F316ABAB2B5A02C3002EF551 /* yuv_rgb_lsx.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB802B5A02C3002EF551 /* yuv_rgb_lsx.h */; }; + F316ABAC2B5A02C3002EF551 /* yuv_rgb_lsx.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB802B5A02C3002EF551 /* yuv_rgb_lsx.h */; }; + F316ABAD2B5A02C3002EF551 /* yuv_rgb_lsx.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB802B5A02C3002EF551 /* yuv_rgb_lsx.h */; }; + F316ABAE2B5A02C3002EF551 /* yuv_rgb_lsx.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB802B5A02C3002EF551 /* yuv_rgb_lsx.h */; }; + F316ABAF2B5A02C3002EF551 /* yuv_rgb_lsx.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB802B5A02C3002EF551 /* yuv_rgb_lsx.h */; }; + F316ABB02B5A02C3002EF551 /* yuv_rgb_lsx.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB802B5A02C3002EF551 /* yuv_rgb_lsx.h */; }; + F316ABB12B5A02C3002EF551 /* yuv_rgb_lsx.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB802B5A02C3002EF551 /* yuv_rgb_lsx.h */; }; + F316ABB22B5A02C3002EF551 /* yuv_rgb_lsx.c in Sources */ = {isa = PBXBuildFile; fileRef = F316AB812B5A02C3002EF551 /* yuv_rgb_lsx.c */; }; + F316ABB32B5A02C3002EF551 /* yuv_rgb_lsx.c in Sources */ = {isa = PBXBuildFile; fileRef = F316AB812B5A02C3002EF551 /* yuv_rgb_lsx.c */; }; + F316ABB42B5A02C3002EF551 /* yuv_rgb_lsx.c in Sources */ = {isa = PBXBuildFile; fileRef = F316AB812B5A02C3002EF551 /* yuv_rgb_lsx.c */; }; + F316ABB52B5A02C3002EF551 /* yuv_rgb_lsx.c in Sources */ = {isa = PBXBuildFile; fileRef = F316AB812B5A02C3002EF551 /* yuv_rgb_lsx.c */; }; + F316ABB62B5A02C3002EF551 /* yuv_rgb_lsx.c in Sources */ = {isa = PBXBuildFile; fileRef = F316AB812B5A02C3002EF551 /* yuv_rgb_lsx.c */; }; + F316ABB72B5A02C3002EF551 /* yuv_rgb_lsx.c in Sources */ = {isa = PBXBuildFile; fileRef = F316AB812B5A02C3002EF551 /* yuv_rgb_lsx.c */; }; + F316ABB82B5A02C3002EF551 /* yuv_rgb_lsx.c in Sources */ = {isa = PBXBuildFile; fileRef = F316AB812B5A02C3002EF551 /* yuv_rgb_lsx.c */; }; + F316ABB92B5A02C3002EF551 /* yuv_rgb_lsx.c in Sources */ = {isa = PBXBuildFile; fileRef = F316AB812B5A02C3002EF551 /* yuv_rgb_lsx.c */; }; + F316ABBA2B5A02C3002EF551 /* yuv_rgb_lsx.c in Sources */ = {isa = PBXBuildFile; fileRef = F316AB812B5A02C3002EF551 /* yuv_rgb_lsx.c */; }; + F316ABBB2B5A02C3002EF551 /* yuv_rgb_sse.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB822B5A02C3002EF551 /* yuv_rgb_sse.h */; }; + F316ABBC2B5A02C3002EF551 /* yuv_rgb_sse.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB822B5A02C3002EF551 /* yuv_rgb_sse.h */; }; + F316ABBD2B5A02C3002EF551 /* yuv_rgb_sse.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB822B5A02C3002EF551 /* yuv_rgb_sse.h */; }; + F316ABBE2B5A02C3002EF551 /* yuv_rgb_sse.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB822B5A02C3002EF551 /* yuv_rgb_sse.h */; }; + F316ABBF2B5A02C3002EF551 /* yuv_rgb_sse.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB822B5A02C3002EF551 /* yuv_rgb_sse.h */; }; + F316ABC02B5A02C3002EF551 /* yuv_rgb_sse.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB822B5A02C3002EF551 /* yuv_rgb_sse.h */; }; + F316ABC12B5A02C3002EF551 /* yuv_rgb_sse.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB822B5A02C3002EF551 /* yuv_rgb_sse.h */; }; + F316ABC22B5A02C3002EF551 /* yuv_rgb_sse.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB822B5A02C3002EF551 /* yuv_rgb_sse.h */; }; + F316ABC32B5A02C3002EF551 /* yuv_rgb_sse.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB822B5A02C3002EF551 /* yuv_rgb_sse.h */; }; + F316ABC42B5A02C3002EF551 /* yuv_rgb_std.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB832B5A02C3002EF551 /* yuv_rgb_std.h */; }; + F316ABC52B5A02C3002EF551 /* yuv_rgb_std.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB832B5A02C3002EF551 /* yuv_rgb_std.h */; }; + F316ABC62B5A02C3002EF551 /* yuv_rgb_std.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB832B5A02C3002EF551 /* yuv_rgb_std.h */; }; + F316ABC72B5A02C3002EF551 /* yuv_rgb_std.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB832B5A02C3002EF551 /* yuv_rgb_std.h */; }; + F316ABC82B5A02C3002EF551 /* yuv_rgb_std.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB832B5A02C3002EF551 /* yuv_rgb_std.h */; }; + F316ABC92B5A02C3002EF551 /* yuv_rgb_std.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB832B5A02C3002EF551 /* yuv_rgb_std.h */; }; + F316ABCA2B5A02C3002EF551 /* yuv_rgb_std.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB832B5A02C3002EF551 /* yuv_rgb_std.h */; }; + F316ABCB2B5A02C3002EF551 /* yuv_rgb_std.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB832B5A02C3002EF551 /* yuv_rgb_std.h */; }; + F316ABCC2B5A02C3002EF551 /* yuv_rgb_std.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB832B5A02C3002EF551 /* yuv_rgb_std.h */; }; + F316ABCD2B5A02C3002EF551 /* yuv_rgb_lsx_func.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB842B5A02C3002EF551 /* yuv_rgb_lsx_func.h */; }; + F316ABCE2B5A02C3002EF551 /* yuv_rgb_lsx_func.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB842B5A02C3002EF551 /* yuv_rgb_lsx_func.h */; }; + F316ABCF2B5A02C3002EF551 /* yuv_rgb_lsx_func.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB842B5A02C3002EF551 /* yuv_rgb_lsx_func.h */; }; + F316ABD02B5A02C3002EF551 /* yuv_rgb_lsx_func.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB842B5A02C3002EF551 /* yuv_rgb_lsx_func.h */; }; + F316ABD12B5A02C3002EF551 /* yuv_rgb_lsx_func.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB842B5A02C3002EF551 /* yuv_rgb_lsx_func.h */; }; + F316ABD22B5A02C3002EF551 /* yuv_rgb_lsx_func.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB842B5A02C3002EF551 /* yuv_rgb_lsx_func.h */; }; + F316ABD32B5A02C3002EF551 /* yuv_rgb_lsx_func.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB842B5A02C3002EF551 /* yuv_rgb_lsx_func.h */; }; + F316ABD42B5A02C3002EF551 /* yuv_rgb_lsx_func.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB842B5A02C3002EF551 /* yuv_rgb_lsx_func.h */; }; + F316ABD52B5A02C3002EF551 /* yuv_rgb_lsx_func.h in Headers */ = {isa = PBXBuildFile; fileRef = F316AB842B5A02C3002EF551 /* yuv_rgb_lsx_func.h */; }; + F31A92C828D4CB39003BFD6A /* SDL_offscreenopengles.h in Headers */ = {isa = PBXBuildFile; fileRef = F31A92C628D4CB39003BFD6A /* SDL_offscreenopengles.h */; }; + F31A92C928D4CB39003BFD6A /* SDL_offscreenopengles.h in Headers */ = {isa = PBXBuildFile; fileRef = F31A92C628D4CB39003BFD6A /* SDL_offscreenopengles.h */; }; + F31A92CA28D4CB39003BFD6A /* SDL_offscreenopengles.h in Headers */ = {isa = PBXBuildFile; fileRef = F31A92C628D4CB39003BFD6A /* SDL_offscreenopengles.h */; }; + F31A92CB28D4CB39003BFD6A /* SDL_offscreenopengles.h in Headers */ = {isa = PBXBuildFile; fileRef = F31A92C628D4CB39003BFD6A /* SDL_offscreenopengles.h */; }; + F31A92CC28D4CB39003BFD6A /* SDL_offscreenopengles.h in Headers */ = {isa = PBXBuildFile; fileRef = F31A92C628D4CB39003BFD6A /* SDL_offscreenopengles.h */; }; + F31A92CD28D4CB39003BFD6A /* SDL_offscreenopengles.h in Headers */ = {isa = PBXBuildFile; fileRef = F31A92C628D4CB39003BFD6A /* SDL_offscreenopengles.h */; }; + F31A92CE28D4CB39003BFD6A /* SDL_offscreenopengles.h in Headers */ = {isa = PBXBuildFile; fileRef = F31A92C628D4CB39003BFD6A /* SDL_offscreenopengles.h */; }; + F31A92CF28D4CB39003BFD6A /* SDL_offscreenopengles.h in Headers */ = {isa = PBXBuildFile; fileRef = F31A92C628D4CB39003BFD6A /* SDL_offscreenopengles.h */; }; + F31A92D028D4CB39003BFD6A /* SDL_offscreenopengles.h in Headers */ = {isa = PBXBuildFile; fileRef = F31A92C628D4CB39003BFD6A /* SDL_offscreenopengles.h */; }; + F31A92D128D4CB39003BFD6A /* SDL_offscreenopengles.h in Headers */ = {isa = PBXBuildFile; fileRef = F31A92C628D4CB39003BFD6A /* SDL_offscreenopengles.h */; }; + F31A92D228D4CB39003BFD6A /* SDL_offscreenopengles.c in Sources */ = {isa = PBXBuildFile; fileRef = F31A92C728D4CB39003BFD6A /* SDL_offscreenopengles.c */; }; + F31A92D328D4CB39003BFD6A /* SDL_offscreenopengles.c in Sources */ = {isa = PBXBuildFile; fileRef = F31A92C728D4CB39003BFD6A /* SDL_offscreenopengles.c */; }; + F31A92D428D4CB39003BFD6A /* SDL_offscreenopengles.c in Sources */ = {isa = PBXBuildFile; fileRef = F31A92C728D4CB39003BFD6A /* SDL_offscreenopengles.c */; }; + F31A92D528D4CB39003BFD6A /* SDL_offscreenopengles.c in Sources */ = {isa = PBXBuildFile; fileRef = F31A92C728D4CB39003BFD6A /* SDL_offscreenopengles.c */; }; + F31A92D628D4CB39003BFD6A /* SDL_offscreenopengles.c in Sources */ = {isa = PBXBuildFile; fileRef = F31A92C728D4CB39003BFD6A /* SDL_offscreenopengles.c */; }; + F31A92D728D4CB39003BFD6A /* SDL_offscreenopengles.c in Sources */ = {isa = PBXBuildFile; fileRef = F31A92C728D4CB39003BFD6A /* SDL_offscreenopengles.c */; }; + F31A92D828D4CB39003BFD6A /* SDL_offscreenopengles.c in Sources */ = {isa = PBXBuildFile; fileRef = F31A92C728D4CB39003BFD6A /* SDL_offscreenopengles.c */; }; + F31A92D928D4CB39003BFD6A /* SDL_offscreenopengles.c in Sources */ = {isa = PBXBuildFile; fileRef = F31A92C728D4CB39003BFD6A /* SDL_offscreenopengles.c */; }; + F31A92DA28D4CB39003BFD6A /* SDL_offscreenopengles.c in Sources */ = {isa = PBXBuildFile; fileRef = F31A92C728D4CB39003BFD6A /* SDL_offscreenopengles.c */; }; + F31A92DB28D4CB39003BFD6A /* SDL_offscreenopengles.c in Sources */ = {isa = PBXBuildFile; fileRef = F31A92C728D4CB39003BFD6A /* SDL_offscreenopengles.c */; }; + F32305FF28939F6400E66D30 /* SDL_hidapi_combined.c in Sources */ = {isa = PBXBuildFile; fileRef = F32305FE28939F6400E66D30 /* SDL_hidapi_combined.c */; }; + F323060028939F6400E66D30 /* SDL_hidapi_combined.c in Sources */ = {isa = PBXBuildFile; fileRef = F32305FE28939F6400E66D30 /* SDL_hidapi_combined.c */; }; + F323060128939F6400E66D30 /* SDL_hidapi_combined.c in Sources */ = {isa = PBXBuildFile; fileRef = F32305FE28939F6400E66D30 /* SDL_hidapi_combined.c */; }; + F323060228939F6400E66D30 /* SDL_hidapi_combined.c in Sources */ = {isa = PBXBuildFile; fileRef = F32305FE28939F6400E66D30 /* SDL_hidapi_combined.c */; }; + F323060328939F6400E66D30 /* SDL_hidapi_combined.c in Sources */ = {isa = PBXBuildFile; fileRef = F32305FE28939F6400E66D30 /* SDL_hidapi_combined.c */; }; + F323060428939F6400E66D30 /* SDL_hidapi_combined.c in Sources */ = {isa = PBXBuildFile; fileRef = F32305FE28939F6400E66D30 /* SDL_hidapi_combined.c */; }; + F323060528939F6400E66D30 /* SDL_hidapi_combined.c in Sources */ = {isa = PBXBuildFile; fileRef = F32305FE28939F6400E66D30 /* SDL_hidapi_combined.c */; }; + F323060628939F6400E66D30 /* SDL_hidapi_combined.c in Sources */ = {isa = PBXBuildFile; fileRef = F32305FE28939F6400E66D30 /* SDL_hidapi_combined.c */; }; + F323060728939F6400E66D30 /* SDL_hidapi_combined.c in Sources */ = {isa = PBXBuildFile; fileRef = F32305FE28939F6400E66D30 /* SDL_hidapi_combined.c */; }; + F34B9895291DEFF500AAC96E /* SDL_hidapi_steam.c in Sources */ = {isa = PBXBuildFile; fileRef = A75FDAAC23E2795C00529352 /* SDL_hidapi_steam.c */; }; + F34B9896291DEFF700AAC96E /* SDL_hidapi_steam.c in Sources */ = {isa = PBXBuildFile; fileRef = A75FDAAC23E2795C00529352 /* SDL_hidapi_steam.c */; }; + F34B9897291DEFFA00AAC96E /* SDL_hidapi_steam.c in Sources */ = {isa = PBXBuildFile; fileRef = A75FDAAC23E2795C00529352 /* SDL_hidapi_steam.c */; }; + F362B9322B33916600D30B94 /* controller_list.h in Headers */ = {isa = PBXBuildFile; fileRef = F362B91F2B33916600D30B94 /* controller_list.h */; }; + F362B9332B33916600D30B94 /* controller_list.h in Headers */ = {isa = PBXBuildFile; fileRef = F362B91F2B33916600D30B94 /* controller_list.h */; }; + F362B9342B33916600D30B94 /* controller_list.h in Headers */ = {isa = PBXBuildFile; fileRef = F362B91F2B33916600D30B94 /* controller_list.h */; }; + F362B9352B33916600D30B94 /* controller_list.h in Headers */ = {isa = PBXBuildFile; fileRef = F362B91F2B33916600D30B94 /* controller_list.h */; }; + F362B9362B33916600D30B94 /* controller_list.h in Headers */ = {isa = PBXBuildFile; fileRef = F362B91F2B33916600D30B94 /* controller_list.h */; }; + F362B9372B33916600D30B94 /* controller_list.h in Headers */ = {isa = PBXBuildFile; fileRef = F362B91F2B33916600D30B94 /* controller_list.h */; }; + F362B9382B33916600D30B94 /* controller_list.h in Headers */ = {isa = PBXBuildFile; fileRef = F362B91F2B33916600D30B94 /* controller_list.h */; }; + F362B9392B33916600D30B94 /* controller_list.h in Headers */ = {isa = PBXBuildFile; fileRef = F362B91F2B33916600D30B94 /* controller_list.h */; }; + F362B93A2B33916600D30B94 /* controller_list.h in Headers */ = {isa = PBXBuildFile; fileRef = F362B91F2B33916600D30B94 /* controller_list.h */; }; + F362B93D2B33920500D30B94 /* SDL_hidapi_steamdeck.c in Sources */ = {isa = PBXBuildFile; fileRef = F362B93B2B33920400D30B94 /* SDL_hidapi_steamdeck.c */; }; + F362B93E2B33920500D30B94 /* SDL_hidapi_steamdeck.c in Sources */ = {isa = PBXBuildFile; fileRef = F362B93B2B33920400D30B94 /* SDL_hidapi_steamdeck.c */; }; + F362B93F2B33920500D30B94 /* SDL_hidapi_steamdeck.c in Sources */ = {isa = PBXBuildFile; fileRef = F362B93B2B33920400D30B94 /* SDL_hidapi_steamdeck.c */; }; + F362B9402B33920500D30B94 /* SDL_hidapi_steamdeck.c in Sources */ = {isa = PBXBuildFile; fileRef = F362B93B2B33920400D30B94 /* SDL_hidapi_steamdeck.c */; }; + F362B9412B33920500D30B94 /* SDL_hidapi_steamdeck.c in Sources */ = {isa = PBXBuildFile; fileRef = F362B93B2B33920400D30B94 /* SDL_hidapi_steamdeck.c */; }; + F362B9422B33920500D30B94 /* SDL_hidapi_steamdeck.c in Sources */ = {isa = PBXBuildFile; fileRef = F362B93B2B33920400D30B94 /* SDL_hidapi_steamdeck.c */; }; + F362B9432B33920500D30B94 /* SDL_hidapi_steamdeck.c in Sources */ = {isa = PBXBuildFile; fileRef = F362B93B2B33920400D30B94 /* SDL_hidapi_steamdeck.c */; }; + F362B9442B33920500D30B94 /* SDL_hidapi_steamdeck.c in Sources */ = {isa = PBXBuildFile; fileRef = F362B93B2B33920400D30B94 /* SDL_hidapi_steamdeck.c */; }; + F362B9452B33920500D30B94 /* SDL_hidapi_steamdeck.c in Sources */ = {isa = PBXBuildFile; fileRef = F362B93B2B33920400D30B94 /* SDL_hidapi_steamdeck.c */; }; + F362B9462B33920500D30B94 /* SDL_hidapi_nintendo.h in Headers */ = {isa = PBXBuildFile; fileRef = F362B93C2B33920400D30B94 /* SDL_hidapi_nintendo.h */; }; + F362B9472B33920500D30B94 /* SDL_hidapi_nintendo.h in Headers */ = {isa = PBXBuildFile; fileRef = F362B93C2B33920400D30B94 /* SDL_hidapi_nintendo.h */; }; + F362B9482B33920500D30B94 /* SDL_hidapi_nintendo.h in Headers */ = {isa = PBXBuildFile; fileRef = F362B93C2B33920400D30B94 /* SDL_hidapi_nintendo.h */; }; + F362B9492B33920500D30B94 /* SDL_hidapi_nintendo.h in Headers */ = {isa = PBXBuildFile; fileRef = F362B93C2B33920400D30B94 /* SDL_hidapi_nintendo.h */; }; + F362B94A2B33920500D30B94 /* SDL_hidapi_nintendo.h in Headers */ = {isa = PBXBuildFile; fileRef = F362B93C2B33920400D30B94 /* SDL_hidapi_nintendo.h */; }; + F362B94B2B33920500D30B94 /* SDL_hidapi_nintendo.h in Headers */ = {isa = PBXBuildFile; fileRef = F362B93C2B33920400D30B94 /* SDL_hidapi_nintendo.h */; }; + F362B94C2B33920500D30B94 /* SDL_hidapi_nintendo.h in Headers */ = {isa = PBXBuildFile; fileRef = F362B93C2B33920400D30B94 /* SDL_hidapi_nintendo.h */; }; + F362B94D2B33920500D30B94 /* SDL_hidapi_nintendo.h in Headers */ = {isa = PBXBuildFile; fileRef = F362B93C2B33920400D30B94 /* SDL_hidapi_nintendo.h */; }; + F362B94E2B33920500D30B94 /* SDL_hidapi_nintendo.h in Headers */ = {isa = PBXBuildFile; fileRef = F362B93C2B33920400D30B94 /* SDL_hidapi_nintendo.h */; }; + F362B9522B33EB7300D30B94 /* SDL_steam_virtual_gamepad.h in Headers */ = {isa = PBXBuildFile; fileRef = F362B9502B33EB7300D30B94 /* SDL_steam_virtual_gamepad.h */; }; + F362B9532B33EB7300D30B94 /* SDL_steam_virtual_gamepad.h in Headers */ = {isa = PBXBuildFile; fileRef = F362B9502B33EB7300D30B94 /* SDL_steam_virtual_gamepad.h */; }; + F362B9542B33EB7300D30B94 /* SDL_steam_virtual_gamepad.h in Headers */ = {isa = PBXBuildFile; fileRef = F362B9502B33EB7300D30B94 /* SDL_steam_virtual_gamepad.h */; }; + F362B9552B33EB7300D30B94 /* SDL_steam_virtual_gamepad.h in Headers */ = {isa = PBXBuildFile; fileRef = F362B9502B33EB7300D30B94 /* SDL_steam_virtual_gamepad.h */; }; + F362B9562B33EB7300D30B94 /* SDL_steam_virtual_gamepad.h in Headers */ = {isa = PBXBuildFile; fileRef = F362B9502B33EB7300D30B94 /* SDL_steam_virtual_gamepad.h */; }; + F362B9572B33EB7300D30B94 /* SDL_steam_virtual_gamepad.h in Headers */ = {isa = PBXBuildFile; fileRef = F362B9502B33EB7300D30B94 /* SDL_steam_virtual_gamepad.h */; }; + F362B9582B33EB7300D30B94 /* SDL_steam_virtual_gamepad.h in Headers */ = {isa = PBXBuildFile; fileRef = F362B9502B33EB7300D30B94 /* SDL_steam_virtual_gamepad.h */; }; + F362B9592B33EB7300D30B94 /* SDL_steam_virtual_gamepad.h in Headers */ = {isa = PBXBuildFile; fileRef = F362B9502B33EB7300D30B94 /* SDL_steam_virtual_gamepad.h */; }; + F362B95A2B33EB7300D30B94 /* SDL_steam_virtual_gamepad.h in Headers */ = {isa = PBXBuildFile; fileRef = F362B9502B33EB7300D30B94 /* SDL_steam_virtual_gamepad.h */; }; + F362B95B2B33EB7300D30B94 /* SDL_steam_virtual_gamepad.c in Sources */ = {isa = PBXBuildFile; fileRef = F362B9512B33EB7300D30B94 /* SDL_steam_virtual_gamepad.c */; }; + F362B95C2B33EB7300D30B94 /* SDL_steam_virtual_gamepad.c in Sources */ = {isa = PBXBuildFile; fileRef = F362B9512B33EB7300D30B94 /* SDL_steam_virtual_gamepad.c */; }; + F362B95D2B33EB7300D30B94 /* SDL_steam_virtual_gamepad.c in Sources */ = {isa = PBXBuildFile; fileRef = F362B9512B33EB7300D30B94 /* SDL_steam_virtual_gamepad.c */; }; + F362B95E2B33EB7300D30B94 /* SDL_steam_virtual_gamepad.c in Sources */ = {isa = PBXBuildFile; fileRef = F362B9512B33EB7300D30B94 /* SDL_steam_virtual_gamepad.c */; }; + F362B95F2B33EB7300D30B94 /* SDL_steam_virtual_gamepad.c in Sources */ = {isa = PBXBuildFile; fileRef = F362B9512B33EB7300D30B94 /* SDL_steam_virtual_gamepad.c */; }; + F362B9602B33EB7300D30B94 /* SDL_steam_virtual_gamepad.c in Sources */ = {isa = PBXBuildFile; fileRef = F362B9512B33EB7300D30B94 /* SDL_steam_virtual_gamepad.c */; }; + F362B9612B33EB7300D30B94 /* SDL_steam_virtual_gamepad.c in Sources */ = {isa = PBXBuildFile; fileRef = F362B9512B33EB7300D30B94 /* SDL_steam_virtual_gamepad.c */; }; + F362B9622B33EB7300D30B94 /* SDL_steam_virtual_gamepad.c in Sources */ = {isa = PBXBuildFile; fileRef = F362B9512B33EB7300D30B94 /* SDL_steam_virtual_gamepad.c */; }; + F362B9632B33EB7300D30B94 /* SDL_steam_virtual_gamepad.c in Sources */ = {isa = PBXBuildFile; fileRef = F362B9512B33EB7300D30B94 /* SDL_steam_virtual_gamepad.c */; }; + F3631C6424884ACF004F28EA /* SDL_locale.h in Headers */ = {isa = PBXBuildFile; fileRef = 566E26792462701100718109 /* SDL_locale.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F3631C652488534E004F28EA /* SDL_locale.h in Headers */ = {isa = PBXBuildFile; fileRef = 566E26792462701100718109 /* SDL_locale.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F376F6192559B29300CFC0BC /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F376F6182559B29300CFC0BC /* OpenGLES.framework */; platformFilter = ios; }; + F376F61B2559B2AF00CFC0BC /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F376F61A2559B2AF00CFC0BC /* UIKit.framework */; }; + F376F6322559B31D00CFC0BC /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F376F6312559B31D00CFC0BC /* GameController.framework */; }; + F376F6332559B33D00CFC0BC /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7381E931D8B69C300B177DD /* AudioToolbox.framework */; }; + F376F63E2559B35200CFC0BC /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDABF23E28B8000529352 /* CoreMotion.framework */; }; + F376F63F2559B37300CFC0BC /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDAC123E28B9600529352 /* CoreGraphics.framework */; }; + F376F6402559B38A00CFC0BC /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDAB923E28A7A00529352 /* AVFoundation.framework */; }; + F376F6552559B4E300CFC0BC /* SDL_hidapi.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A81423E2513F00DCD162 /* SDL_hidapi.c */; }; + F376F6762559B4E500CFC0BC /* SDL_hidapi.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A81423E2513F00DCD162 /* SDL_hidapi.c */; }; + F376F68D2559B4E900CFC0BC /* SDL_hidapi.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A81423E2513F00DCD162 /* SDL_hidapi.c */; }; + F376F6D92559B59600CFC0BC /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F376F6D82559B59600CFC0BC /* AudioToolbox.framework */; }; + F376F6DB2559B5A000CFC0BC /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F376F6DA2559B5A000CFC0BC /* AVFoundation.framework */; }; + F376F6DD2559B5A900CFC0BC /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F376F6DC2559B5A900CFC0BC /* OpenGLES.framework */; }; + F376F6DF2559B5BA00CFC0BC /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F376F6DE2559B5BA00CFC0BC /* GameController.framework */; }; + F376F6EC2559B5DA00CFC0BC /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F376F6CC2559B54500CFC0BC /* UIKit.framework */; }; + F376F6F82559B5EC00CFC0BC /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F376F6F72559B5EC00CFC0BC /* CoreGraphics.framework */; }; + F376F70E2559B6B800CFC0BC /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F376F6182559B29300CFC0BC /* OpenGLES.framework */; }; + F376F70F2559B6BF00CFC0BC /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F376F61A2559B2AF00CFC0BC /* UIKit.framework */; }; + F376F71B2559B71C00CFC0BC /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F376F6D82559B59600CFC0BC /* AudioToolbox.framework */; }; + F376F71C2559B72900CFC0BC /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F376F6DA2559B5A000CFC0BC /* AVFoundation.framework */; }; + F376F71D2559B73200CFC0BC /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F376F6CC2559B54500CFC0BC /* UIKit.framework */; }; + F376F71F2559B73A00CFC0BC /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F376F71E2559B73A00CFC0BC /* QuartzCore.framework */; }; + F376F7202559B74200CFC0BC /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F376F6DC2559B5A900CFC0BC /* OpenGLES.framework */; }; + F376F7222559B74900CFC0BC /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F376F7212559B74900CFC0BC /* Metal.framework */; }; + F376F7232559B75800CFC0BC /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F376F6E02559B5CA00CFC0BC /* CoreVideo.framework */; }; + F376F7242559B76100CFC0BC /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F376F6F72559B5EC00CFC0BC /* CoreGraphics.framework */; }; + F376F7262559B76800CFC0BC /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F376F7252559B76800CFC0BC /* CoreFoundation.framework */; }; + F376F7282559B77100CFC0BC /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F376F7272559B77100CFC0BC /* CoreAudio.framework */; }; + F376F7332559B79B00CFC0BC /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F376F6DE2559B5BA00CFC0BC /* GameController.framework */; }; + F37A8E1A28405AA100C38E95 /* CMake in Resources */ = {isa = PBXBuildFile; fileRef = F37A8E1928405AA100C38E95 /* CMake */; }; + F37A8E1B28405AA100C38E95 /* CMake in Resources */ = {isa = PBXBuildFile; fileRef = F37A8E1928405AA100C38E95 /* CMake */; }; + F37A8E1C28405AA100C38E95 /* CMake in Resources */ = {isa = PBXBuildFile; fileRef = F37A8E1928405AA100C38E95 /* CMake */; }; + F37DC5F325350EBC0002E6F7 /* CoreHaptics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F37DC5F225350EBC0002E6F7 /* CoreHaptics.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + F37DC5F525350ECC0002E6F7 /* CoreHaptics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F37DC5F425350ECC0002E6F7 /* CoreHaptics.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + F3820713284F3609004DD584 /* controller_type.c in Sources */ = {isa = PBXBuildFile; fileRef = F3820712284F3609004DD584 /* controller_type.c */; }; + F3820714284F3609004DD584 /* controller_type.c in Sources */ = {isa = PBXBuildFile; fileRef = F3820712284F3609004DD584 /* controller_type.c */; }; + F3820715284F3609004DD584 /* controller_type.c in Sources */ = {isa = PBXBuildFile; fileRef = F3820712284F3609004DD584 /* controller_type.c */; }; + F3820716284F3609004DD584 /* controller_type.c in Sources */ = {isa = PBXBuildFile; fileRef = F3820712284F3609004DD584 /* controller_type.c */; }; + F3820717284F3609004DD584 /* controller_type.c in Sources */ = {isa = PBXBuildFile; fileRef = F3820712284F3609004DD584 /* controller_type.c */; }; + F3820718284F3609004DD584 /* controller_type.c in Sources */ = {isa = PBXBuildFile; fileRef = F3820712284F3609004DD584 /* controller_type.c */; }; + F3820719284F3609004DD584 /* controller_type.c in Sources */ = {isa = PBXBuildFile; fileRef = F3820712284F3609004DD584 /* controller_type.c */; }; + F382071A284F3609004DD584 /* controller_type.c in Sources */ = {isa = PBXBuildFile; fileRef = F3820712284F3609004DD584 /* controller_type.c */; }; + F382071B284F3609004DD584 /* controller_type.c in Sources */ = {isa = PBXBuildFile; fileRef = F3820712284F3609004DD584 /* controller_type.c */; }; + F382071D284F362F004DD584 /* SDL_guid.c in Sources */ = {isa = PBXBuildFile; fileRef = F382071C284F362F004DD584 /* SDL_guid.c */; }; + F382071E284F362F004DD584 /* SDL_guid.c in Sources */ = {isa = PBXBuildFile; fileRef = F382071C284F362F004DD584 /* SDL_guid.c */; }; + F382071F284F362F004DD584 /* SDL_guid.c in Sources */ = {isa = PBXBuildFile; fileRef = F382071C284F362F004DD584 /* SDL_guid.c */; }; + F3820720284F362F004DD584 /* SDL_guid.c in Sources */ = {isa = PBXBuildFile; fileRef = F382071C284F362F004DD584 /* SDL_guid.c */; }; + F3820721284F362F004DD584 /* SDL_guid.c in Sources */ = {isa = PBXBuildFile; fileRef = F382071C284F362F004DD584 /* SDL_guid.c */; }; + F3820722284F362F004DD584 /* SDL_guid.c in Sources */ = {isa = PBXBuildFile; fileRef = F382071C284F362F004DD584 /* SDL_guid.c */; }; + F3820723284F362F004DD584 /* SDL_guid.c in Sources */ = {isa = PBXBuildFile; fileRef = F382071C284F362F004DD584 /* SDL_guid.c */; }; + F3820724284F362F004DD584 /* SDL_guid.c in Sources */ = {isa = PBXBuildFile; fileRef = F382071C284F362F004DD584 /* SDL_guid.c */; }; + F3820725284F362F004DD584 /* SDL_guid.c in Sources */ = {isa = PBXBuildFile; fileRef = F382071C284F362F004DD584 /* SDL_guid.c */; }; + F3820727284F3643004DD584 /* SDL_guid.h in Headers */ = {isa = PBXBuildFile; fileRef = F3820726284F3643004DD584 /* SDL_guid.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F3820728284F3643004DD584 /* SDL_guid.h in Headers */ = {isa = PBXBuildFile; fileRef = F3820726284F3643004DD584 /* SDL_guid.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F3820729284F3643004DD584 /* SDL_guid.h in Headers */ = {isa = PBXBuildFile; fileRef = F3820726284F3643004DD584 /* SDL_guid.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F382072A284F3643004DD584 /* SDL_guid.h in Headers */ = {isa = PBXBuildFile; fileRef = F3820726284F3643004DD584 /* SDL_guid.h */; }; + F382072B284F3643004DD584 /* SDL_guid.h in Headers */ = {isa = PBXBuildFile; fileRef = F3820726284F3643004DD584 /* SDL_guid.h */; }; + F382072C284F3643004DD584 /* SDL_guid.h in Headers */ = {isa = PBXBuildFile; fileRef = F3820726284F3643004DD584 /* SDL_guid.h */; }; + F382072D284F3643004DD584 /* SDL_guid.h in Headers */ = {isa = PBXBuildFile; fileRef = F3820726284F3643004DD584 /* SDL_guid.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F382072E284F3643004DD584 /* SDL_guid.h in Headers */ = {isa = PBXBuildFile; fileRef = F3820726284F3643004DD584 /* SDL_guid.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F382072F284F3643004DD584 /* SDL_guid.h in Headers */ = {isa = PBXBuildFile; fileRef = F3820726284F3643004DD584 /* SDL_guid.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F38233852738EB8600F7F527 /* SDL_hidapi.h in Headers */ = {isa = PBXBuildFile; fileRef = F38233842738EB8600F7F527 /* SDL_hidapi.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F38233862738EB8600F7F527 /* SDL_hidapi.h in Headers */ = {isa = PBXBuildFile; fileRef = F38233842738EB8600F7F527 /* SDL_hidapi.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F38233872738EB8600F7F527 /* SDL_hidapi.h in Headers */ = {isa = PBXBuildFile; fileRef = F38233842738EB8600F7F527 /* SDL_hidapi.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F382338B2738EB8600F7F527 /* SDL_hidapi.h in Headers */ = {isa = PBXBuildFile; fileRef = F38233842738EB8600F7F527 /* SDL_hidapi.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F382338C2738EB8600F7F527 /* SDL_hidapi.h in Headers */ = {isa = PBXBuildFile; fileRef = F38233842738EB8600F7F527 /* SDL_hidapi.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F382338D2738EB8600F7F527 /* SDL_hidapi.h in Headers */ = {isa = PBXBuildFile; fileRef = F38233842738EB8600F7F527 /* SDL_hidapi.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F382338E2738EBEC00F7F527 /* SDL_hidapi.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A81423E2513F00DCD162 /* SDL_hidapi.c */; }; + F382338F2738EBEF00F7F527 /* SDL_hidapi.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A81423E2513F00DCD162 /* SDL_hidapi.c */; }; + F38233902738EBF000F7F527 /* SDL_hidapi.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A81423E2513F00DCD162 /* SDL_hidapi.c */; }; + F38233912738EBF100F7F527 /* SDL_hidapi.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A81423E2513F00DCD162 /* SDL_hidapi.c */; }; + F38233922738EBF300F7F527 /* SDL_hidapi.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A81423E2513F00DCD162 /* SDL_hidapi.c */; }; + F38233932738EBF300F7F527 /* SDL_hidapi.c in Sources */ = {isa = PBXBuildFile; fileRef = A7D8A81423E2513F00DCD162 /* SDL_hidapi.c */; }; + F38233942738EC1400F7F527 /* hid.m in Sources */ = {isa = PBXBuildFile; fileRef = A75FDAA523E2792500529352 /* hid.m */; }; + F38233952738EC1500F7F527 /* hid.m in Sources */ = {isa = PBXBuildFile; fileRef = A75FDAA523E2792500529352 /* hid.m */; }; + F38233962738EC1600F7F527 /* hid.m in Sources */ = {isa = PBXBuildFile; fileRef = A75FDAA523E2792500529352 /* hid.m */; }; + F38233972738EC1600F7F527 /* hid.m in Sources */ = {isa = PBXBuildFile; fileRef = A75FDAA523E2792500529352 /* hid.m */; }; + F38233982738EC1800F7F527 /* hid.m in Sources */ = {isa = PBXBuildFile; fileRef = A75FDAA523E2792500529352 /* hid.m */; }; + F38233992738EC1800F7F527 /* hid.m in Sources */ = {isa = PBXBuildFile; fileRef = A75FDAA523E2792500529352 /* hid.m */; }; + F382339A2738ED5600F7F527 /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A75FDAC323E28BA700529352 /* CoreBluetooth.framework */; }; + F382339C2738ED6600F7F527 /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F382339B2738ED6600F7F527 /* CoreBluetooth.framework */; }; + F382339D2738EE3F00F7F527 /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F382339B2738ED6600F7F527 /* CoreBluetooth.framework */; }; + F386F6E72884663E001840AA /* SDL_log_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F386F6E42884663E001840AA /* SDL_log_c.h */; }; + F386F6E82884663E001840AA /* SDL_log_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F386F6E42884663E001840AA /* SDL_log_c.h */; }; + F386F6E92884663E001840AA /* SDL_log_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F386F6E42884663E001840AA /* SDL_log_c.h */; }; + F386F6EA2884663E001840AA /* SDL_log_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F386F6E42884663E001840AA /* SDL_log_c.h */; }; + F386F6EB2884663E001840AA /* SDL_log_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F386F6E42884663E001840AA /* SDL_log_c.h */; }; + F386F6EC2884663E001840AA /* SDL_log_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F386F6E42884663E001840AA /* SDL_log_c.h */; }; + F386F6ED2884663E001840AA /* SDL_log_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F386F6E42884663E001840AA /* SDL_log_c.h */; }; + F386F6EE2884663E001840AA /* SDL_log_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F386F6E42884663E001840AA /* SDL_log_c.h */; }; + F386F6EF2884663E001840AA /* SDL_log_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F386F6E42884663E001840AA /* SDL_log_c.h */; }; + F386F6F02884663E001840AA /* SDL_utils_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F386F6E52884663E001840AA /* SDL_utils_c.h */; }; + F386F6F12884663E001840AA /* SDL_utils_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F386F6E52884663E001840AA /* SDL_utils_c.h */; }; + F386F6F22884663E001840AA /* SDL_utils_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F386F6E52884663E001840AA /* SDL_utils_c.h */; }; + F386F6F32884663E001840AA /* SDL_utils_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F386F6E52884663E001840AA /* SDL_utils_c.h */; }; + F386F6F42884663E001840AA /* SDL_utils_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F386F6E52884663E001840AA /* SDL_utils_c.h */; }; + F386F6F52884663E001840AA /* SDL_utils_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F386F6E52884663E001840AA /* SDL_utils_c.h */; }; + F386F6F62884663E001840AA /* SDL_utils_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F386F6E52884663E001840AA /* SDL_utils_c.h */; }; + F386F6F72884663E001840AA /* SDL_utils_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F386F6E52884663E001840AA /* SDL_utils_c.h */; }; + F386F6F82884663E001840AA /* SDL_utils_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F386F6E52884663E001840AA /* SDL_utils_c.h */; }; + F386F6F92884663E001840AA /* SDL_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = F386F6E62884663E001840AA /* SDL_utils.c */; }; + F386F6FA2884663E001840AA /* SDL_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = F386F6E62884663E001840AA /* SDL_utils.c */; }; + F386F6FB2884663E001840AA /* SDL_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = F386F6E62884663E001840AA /* SDL_utils.c */; }; + F386F6FC2884663E001840AA /* SDL_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = F386F6E62884663E001840AA /* SDL_utils.c */; }; + F386F6FD2884663E001840AA /* SDL_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = F386F6E62884663E001840AA /* SDL_utils.c */; }; + F386F6FE2884663E001840AA /* SDL_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = F386F6E62884663E001840AA /* SDL_utils.c */; }; + F386F6FF2884663E001840AA /* SDL_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = F386F6E62884663E001840AA /* SDL_utils.c */; }; + F386F7002884663E001840AA /* SDL_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = F386F6E62884663E001840AA /* SDL_utils.c */; }; + F386F7012884663E001840AA /* SDL_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = F386F6E62884663E001840AA /* SDL_utils.c */; }; + F388C95528B5F6F700661ECF /* SDL_hidapi_ps3.c in Sources */ = {isa = PBXBuildFile; fileRef = F388C95428B5F6F600661ECF /* SDL_hidapi_ps3.c */; }; + F388C95628B5F6F700661ECF /* SDL_hidapi_ps3.c in Sources */ = {isa = PBXBuildFile; fileRef = F388C95428B5F6F600661ECF /* SDL_hidapi_ps3.c */; }; + F388C95728B5F6F700661ECF /* SDL_hidapi_ps3.c in Sources */ = {isa = PBXBuildFile; fileRef = F388C95428B5F6F600661ECF /* SDL_hidapi_ps3.c */; }; + F388C95828B5F6F700661ECF /* SDL_hidapi_ps3.c in Sources */ = {isa = PBXBuildFile; fileRef = F388C95428B5F6F600661ECF /* SDL_hidapi_ps3.c */; }; + F388C95928B5F6F700661ECF /* SDL_hidapi_ps3.c in Sources */ = {isa = PBXBuildFile; fileRef = F388C95428B5F6F600661ECF /* SDL_hidapi_ps3.c */; }; + F388C95A28B5F6F700661ECF /* SDL_hidapi_ps3.c in Sources */ = {isa = PBXBuildFile; fileRef = F388C95428B5F6F600661ECF /* SDL_hidapi_ps3.c */; }; + F388C95B28B5F6F700661ECF /* SDL_hidapi_ps3.c in Sources */ = {isa = PBXBuildFile; fileRef = F388C95428B5F6F600661ECF /* SDL_hidapi_ps3.c */; }; + F388C95C28B5F6F700661ECF /* SDL_hidapi_ps3.c in Sources */ = {isa = PBXBuildFile; fileRef = F388C95428B5F6F600661ECF /* SDL_hidapi_ps3.c */; }; + F388C95D28B5F6F700661ECF /* SDL_hidapi_ps3.c in Sources */ = {isa = PBXBuildFile; fileRef = F388C95428B5F6F600661ECF /* SDL_hidapi_ps3.c */; }; + F3928194258603F1003191A7 /* SDL_misc.h in Headers */ = {isa = PBXBuildFile; fileRef = 5616CA4F252BB2BE005D5928 /* SDL_misc.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F392819F25860422003191A7 /* SDL_misc.h in Headers */ = {isa = PBXBuildFile; fileRef = 5616CA4F252BB2BE005D5928 /* SDL_misc.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F3942659253579B400B03694 /* CoreHaptics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F37DC5F225350EBC0002E6F7 /* CoreHaptics.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + F394265A253579D200B03694 /* CoreHaptics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F37DC5F425350ECC0002E6F7 /* CoreHaptics.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; F3950CD8212BC88D00F51292 /* SDL_sensor.h in Headers */ = {isa = PBXBuildFile; fileRef = F3950CD7212BC88D00F51292 /* SDL_sensor.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F3950CD9212BC88D00F51292 /* SDL_sensor.h in Headers */ = {isa = PBXBuildFile; fileRef = F3950CD7212BC88D00F51292 /* SDL_sensor.h */; settings = {ATTRIBUTES = (Public, ); }; }; F3950CDA212BC88D00F51292 /* SDL_sensor.h in Headers */ = {isa = PBXBuildFile; fileRef = F3950CD7212BC88D00F51292 /* SDL_sensor.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F395BF6525633B2400942BFF /* SDL_crc32.c in Sources */ = {isa = PBXBuildFile; fileRef = F395BF6425633B2400942BFF /* SDL_crc32.c */; }; + F395BF6625633B2400942BFF /* SDL_crc32.c in Sources */ = {isa = PBXBuildFile; fileRef = F395BF6425633B2400942BFF /* SDL_crc32.c */; }; + F395BF6725633B2400942BFF /* SDL_crc32.c in Sources */ = {isa = PBXBuildFile; fileRef = F395BF6425633B2400942BFF /* SDL_crc32.c */; }; + F395BF6825633B2400942BFF /* SDL_crc32.c in Sources */ = {isa = PBXBuildFile; fileRef = F395BF6425633B2400942BFF /* SDL_crc32.c */; }; + F395BF6925633B2400942BFF /* SDL_crc32.c in Sources */ = {isa = PBXBuildFile; fileRef = F395BF6425633B2400942BFF /* SDL_crc32.c */; }; + F395BF6A25633B2400942BFF /* SDL_crc32.c in Sources */ = {isa = PBXBuildFile; fileRef = F395BF6425633B2400942BFF /* SDL_crc32.c */; }; + F395BF6B25633B2400942BFF /* SDL_crc32.c in Sources */ = {isa = PBXBuildFile; fileRef = F395BF6425633B2400942BFF /* SDL_crc32.c */; }; + F395BF6C25633B2400942BFF /* SDL_crc32.c in Sources */ = {isa = PBXBuildFile; fileRef = F395BF6425633B2400942BFF /* SDL_crc32.c */; }; + F395BF6D25633B2400942BFF /* SDL_crc32.c in Sources */ = {isa = PBXBuildFile; fileRef = F395BF6425633B2400942BFF /* SDL_crc32.c */; }; + F395C1932569C68F00942BFF /* SDL_iokitjoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F395C1912569C68E00942BFF /* SDL_iokitjoystick_c.h */; }; + F395C1942569C68F00942BFF /* SDL_iokitjoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F395C1912569C68E00942BFF /* SDL_iokitjoystick_c.h */; }; + F395C1952569C68F00942BFF /* SDL_iokitjoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F395C1912569C68E00942BFF /* SDL_iokitjoystick_c.h */; }; + F395C1962569C68F00942BFF /* SDL_iokitjoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F395C1912569C68E00942BFF /* SDL_iokitjoystick_c.h */; }; + F395C1972569C68F00942BFF /* SDL_iokitjoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F395C1912569C68E00942BFF /* SDL_iokitjoystick_c.h */; }; + F395C1982569C68F00942BFF /* SDL_iokitjoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F395C1912569C68E00942BFF /* SDL_iokitjoystick_c.h */; }; + F395C1992569C68F00942BFF /* SDL_iokitjoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F395C1912569C68E00942BFF /* SDL_iokitjoystick_c.h */; }; + F395C19A2569C68F00942BFF /* SDL_iokitjoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F395C1912569C68E00942BFF /* SDL_iokitjoystick_c.h */; }; + F395C19B2569C68F00942BFF /* SDL_iokitjoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F395C1912569C68E00942BFF /* SDL_iokitjoystick_c.h */; }; + F395C19C2569C68F00942BFF /* SDL_iokitjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = F395C1922569C68E00942BFF /* SDL_iokitjoystick.c */; }; + F395C19D2569C68F00942BFF /* SDL_iokitjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = F395C1922569C68E00942BFF /* SDL_iokitjoystick.c */; }; + F395C19E2569C68F00942BFF /* SDL_iokitjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = F395C1922569C68E00942BFF /* SDL_iokitjoystick.c */; }; + F395C19F2569C68F00942BFF /* SDL_iokitjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = F395C1922569C68E00942BFF /* SDL_iokitjoystick.c */; }; + F395C1A02569C68F00942BFF /* SDL_iokitjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = F395C1922569C68E00942BFF /* SDL_iokitjoystick.c */; }; + F395C1A12569C68F00942BFF /* SDL_iokitjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = F395C1922569C68E00942BFF /* SDL_iokitjoystick.c */; }; + F395C1A22569C68F00942BFF /* SDL_iokitjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = F395C1922569C68E00942BFF /* SDL_iokitjoystick.c */; }; + F395C1A32569C68F00942BFF /* SDL_iokitjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = F395C1922569C68E00942BFF /* SDL_iokitjoystick.c */; }; + F395C1A42569C68F00942BFF /* SDL_iokitjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = F395C1922569C68E00942BFF /* SDL_iokitjoystick.c */; }; + F395C1B12569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; }; + F395C1B22569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; }; + F395C1B32569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; }; + F395C1B42569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; }; + F395C1B52569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; }; + F395C1B62569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; }; + F395C1B72569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; }; + F395C1B82569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; }; + F395C1B92569C6A000942BFF /* SDL_mfijoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */; }; + F395C1BA2569C6A000942BFF /* SDL_mfijoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F395C1B02569C6A000942BFF /* SDL_mfijoystick_c.h */; }; + F395C1BB2569C6A000942BFF /* SDL_mfijoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F395C1B02569C6A000942BFF /* SDL_mfijoystick_c.h */; }; + F395C1BC2569C6A000942BFF /* SDL_mfijoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F395C1B02569C6A000942BFF /* SDL_mfijoystick_c.h */; }; + F395C1BD2569C6A000942BFF /* SDL_mfijoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F395C1B02569C6A000942BFF /* SDL_mfijoystick_c.h */; }; + F395C1BE2569C6A000942BFF /* SDL_mfijoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F395C1B02569C6A000942BFF /* SDL_mfijoystick_c.h */; }; + F395C1BF2569C6A000942BFF /* SDL_mfijoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F395C1B02569C6A000942BFF /* SDL_mfijoystick_c.h */; }; + F395C1C02569C6A000942BFF /* SDL_mfijoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F395C1B02569C6A000942BFF /* SDL_mfijoystick_c.h */; }; + F395C1C12569C6A000942BFF /* SDL_mfijoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F395C1B02569C6A000942BFF /* SDL_mfijoystick_c.h */; }; + F395C1C22569C6A000942BFF /* SDL_mfijoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = F395C1B02569C6A000942BFF /* SDL_mfijoystick_c.h */; }; + F3973FA228A59BDD00B84553 /* SDL_vacopy.h in Headers */ = {isa = PBXBuildFile; fileRef = F3973FA028A59BDD00B84553 /* SDL_vacopy.h */; }; + F3973FA328A59BDD00B84553 /* SDL_vacopy.h in Headers */ = {isa = PBXBuildFile; fileRef = F3973FA028A59BDD00B84553 /* SDL_vacopy.h */; }; + F3973FA428A59BDD00B84553 /* SDL_vacopy.h in Headers */ = {isa = PBXBuildFile; fileRef = F3973FA028A59BDD00B84553 /* SDL_vacopy.h */; }; + F3973FA528A59BDD00B84553 /* SDL_vacopy.h in Headers */ = {isa = PBXBuildFile; fileRef = F3973FA028A59BDD00B84553 /* SDL_vacopy.h */; }; + F3973FA628A59BDD00B84553 /* SDL_vacopy.h in Headers */ = {isa = PBXBuildFile; fileRef = F3973FA028A59BDD00B84553 /* SDL_vacopy.h */; }; + F3973FA728A59BDD00B84553 /* SDL_vacopy.h in Headers */ = {isa = PBXBuildFile; fileRef = F3973FA028A59BDD00B84553 /* SDL_vacopy.h */; }; + F3973FA828A59BDD00B84553 /* SDL_vacopy.h in Headers */ = {isa = PBXBuildFile; fileRef = F3973FA028A59BDD00B84553 /* SDL_vacopy.h */; }; + F3973FA928A59BDD00B84553 /* SDL_vacopy.h in Headers */ = {isa = PBXBuildFile; fileRef = F3973FA028A59BDD00B84553 /* SDL_vacopy.h */; }; + F3973FAA28A59BDD00B84553 /* SDL_vacopy.h in Headers */ = {isa = PBXBuildFile; fileRef = F3973FA028A59BDD00B84553 /* SDL_vacopy.h */; }; + F3973FAB28A59BDD00B84553 /* SDL_crc16.c in Sources */ = {isa = PBXBuildFile; fileRef = F3973FA128A59BDD00B84553 /* SDL_crc16.c */; }; + F3973FAC28A59BDD00B84553 /* SDL_crc16.c in Sources */ = {isa = PBXBuildFile; fileRef = F3973FA128A59BDD00B84553 /* SDL_crc16.c */; }; + F3973FAD28A59BDD00B84553 /* SDL_crc16.c in Sources */ = {isa = PBXBuildFile; fileRef = F3973FA128A59BDD00B84553 /* SDL_crc16.c */; }; + F3973FAE28A59BDD00B84553 /* SDL_crc16.c in Sources */ = {isa = PBXBuildFile; fileRef = F3973FA128A59BDD00B84553 /* SDL_crc16.c */; }; + F3973FAF28A59BDD00B84553 /* SDL_crc16.c in Sources */ = {isa = PBXBuildFile; fileRef = F3973FA128A59BDD00B84553 /* SDL_crc16.c */; }; + F3973FB028A59BDD00B84553 /* SDL_crc16.c in Sources */ = {isa = PBXBuildFile; fileRef = F3973FA128A59BDD00B84553 /* SDL_crc16.c */; }; + F3973FB128A59BDD00B84553 /* SDL_crc16.c in Sources */ = {isa = PBXBuildFile; fileRef = F3973FA128A59BDD00B84553 /* SDL_crc16.c */; }; + F3973FB228A59BDD00B84553 /* SDL_crc16.c in Sources */ = {isa = PBXBuildFile; fileRef = F3973FA128A59BDD00B84553 /* SDL_crc16.c */; }; + F3973FB328A59BDD00B84553 /* SDL_crc16.c in Sources */ = {isa = PBXBuildFile; fileRef = F3973FA128A59BDD00B84553 /* SDL_crc16.c */; }; + F3984CD025BCC92900374F43 /* SDL_hidapi_stadia.c in Sources */ = {isa = PBXBuildFile; fileRef = F3984CCF25BCC92800374F43 /* SDL_hidapi_stadia.c */; }; + F3984CD125BCC92900374F43 /* SDL_hidapi_stadia.c in Sources */ = {isa = PBXBuildFile; fileRef = F3984CCF25BCC92800374F43 /* SDL_hidapi_stadia.c */; }; + F3984CD225BCC92900374F43 /* SDL_hidapi_stadia.c in Sources */ = {isa = PBXBuildFile; fileRef = F3984CCF25BCC92800374F43 /* SDL_hidapi_stadia.c */; }; + F3984CD325BCC92900374F43 /* SDL_hidapi_stadia.c in Sources */ = {isa = PBXBuildFile; fileRef = F3984CCF25BCC92800374F43 /* SDL_hidapi_stadia.c */; }; + F3984CD425BCC92900374F43 /* SDL_hidapi_stadia.c in Sources */ = {isa = PBXBuildFile; fileRef = F3984CCF25BCC92800374F43 /* SDL_hidapi_stadia.c */; }; + F3984CD525BCC92900374F43 /* SDL_hidapi_stadia.c in Sources */ = {isa = PBXBuildFile; fileRef = F3984CCF25BCC92800374F43 /* SDL_hidapi_stadia.c */; }; + F3984CD625BCC92900374F43 /* SDL_hidapi_stadia.c in Sources */ = {isa = PBXBuildFile; fileRef = F3984CCF25BCC92800374F43 /* SDL_hidapi_stadia.c */; }; + F3984CD725BCC92900374F43 /* SDL_hidapi_stadia.c in Sources */ = {isa = PBXBuildFile; fileRef = F3984CCF25BCC92800374F43 /* SDL_hidapi_stadia.c */; }; + F3984CD825BCC92900374F43 /* SDL_hidapi_stadia.c in Sources */ = {isa = PBXBuildFile; fileRef = F3984CCF25BCC92800374F43 /* SDL_hidapi_stadia.c */; }; + F3A4909E2554D38600E92A8B /* SDL_hidapi_ps5.c in Sources */ = {isa = PBXBuildFile; fileRef = F3A4909D2554D38500E92A8B /* SDL_hidapi_ps5.c */; }; + F3A4909F2554D38600E92A8B /* SDL_hidapi_ps5.c in Sources */ = {isa = PBXBuildFile; fileRef = F3A4909D2554D38500E92A8B /* SDL_hidapi_ps5.c */; }; + F3A490A02554D38600E92A8B /* SDL_hidapi_ps5.c in Sources */ = {isa = PBXBuildFile; fileRef = F3A4909D2554D38500E92A8B /* SDL_hidapi_ps5.c */; }; + F3A490A12554D38600E92A8B /* SDL_hidapi_ps5.c in Sources */ = {isa = PBXBuildFile; fileRef = F3A4909D2554D38500E92A8B /* SDL_hidapi_ps5.c */; }; + F3A490A22554D38600E92A8B /* SDL_hidapi_ps5.c in Sources */ = {isa = PBXBuildFile; fileRef = F3A4909D2554D38500E92A8B /* SDL_hidapi_ps5.c */; }; + F3A490A32554D38600E92A8B /* SDL_hidapi_ps5.c in Sources */ = {isa = PBXBuildFile; fileRef = F3A4909D2554D38500E92A8B /* SDL_hidapi_ps5.c */; }; + F3A490A42554D38600E92A8B /* SDL_hidapi_ps5.c in Sources */ = {isa = PBXBuildFile; fileRef = F3A4909D2554D38500E92A8B /* SDL_hidapi_ps5.c */; }; + F3A490A52554D38600E92A8B /* SDL_hidapi_ps5.c in Sources */ = {isa = PBXBuildFile; fileRef = F3A4909D2554D38500E92A8B /* SDL_hidapi_ps5.c */; }; + F3A490A62554D38600E92A8B /* SDL_hidapi_ps5.c in Sources */ = {isa = PBXBuildFile; fileRef = F3A4909D2554D38500E92A8B /* SDL_hidapi_ps5.c */; }; + F3ADAB8E2576F0B400A6B1D9 /* SDL_sysurl.m in Sources */ = {isa = PBXBuildFile; fileRef = F3ADAB8D2576F0B300A6B1D9 /* SDL_sysurl.m */; }; + F3ADAB8F2576F0B400A6B1D9 /* SDL_sysurl.m in Sources */ = {isa = PBXBuildFile; fileRef = F3ADAB8D2576F0B300A6B1D9 /* SDL_sysurl.m */; }; + F3ADAB902576F0B400A6B1D9 /* SDL_sysurl.m in Sources */ = {isa = PBXBuildFile; fileRef = F3ADAB8D2576F0B300A6B1D9 /* SDL_sysurl.m */; }; + F3ADAB912576F0B400A6B1D9 /* SDL_sysurl.m in Sources */ = {isa = PBXBuildFile; fileRef = F3ADAB8D2576F0B300A6B1D9 /* SDL_sysurl.m */; }; + F3ADAB922576F0B400A6B1D9 /* SDL_sysurl.m in Sources */ = {isa = PBXBuildFile; fileRef = F3ADAB8D2576F0B300A6B1D9 /* SDL_sysurl.m */; }; + F3ADAB932576F0B400A6B1D9 /* SDL_sysurl.m in Sources */ = {isa = PBXBuildFile; fileRef = F3ADAB8D2576F0B300A6B1D9 /* SDL_sysurl.m */; }; + F3D60A8328C16A1900788A3A /* SDL_hidapi_wii.c in Sources */ = {isa = PBXBuildFile; fileRef = F3D60A8228C16A1800788A3A /* SDL_hidapi_wii.c */; }; + F3D60A8428C16A1900788A3A /* SDL_hidapi_wii.c in Sources */ = {isa = PBXBuildFile; fileRef = F3D60A8228C16A1800788A3A /* SDL_hidapi_wii.c */; }; + F3D60A8528C16A1900788A3A /* SDL_hidapi_wii.c in Sources */ = {isa = PBXBuildFile; fileRef = F3D60A8228C16A1800788A3A /* SDL_hidapi_wii.c */; }; + F3D60A8628C16A1900788A3A /* SDL_hidapi_wii.c in Sources */ = {isa = PBXBuildFile; fileRef = F3D60A8228C16A1800788A3A /* SDL_hidapi_wii.c */; }; + F3D60A8728C16A1900788A3A /* SDL_hidapi_wii.c in Sources */ = {isa = PBXBuildFile; fileRef = F3D60A8228C16A1800788A3A /* SDL_hidapi_wii.c */; }; + F3D60A8828C16A1900788A3A /* SDL_hidapi_wii.c in Sources */ = {isa = PBXBuildFile; fileRef = F3D60A8228C16A1800788A3A /* SDL_hidapi_wii.c */; }; + F3D60A8928C16A1900788A3A /* SDL_hidapi_wii.c in Sources */ = {isa = PBXBuildFile; fileRef = F3D60A8228C16A1800788A3A /* SDL_hidapi_wii.c */; }; + F3D60A8A28C16A1900788A3A /* SDL_hidapi_wii.c in Sources */ = {isa = PBXBuildFile; fileRef = F3D60A8228C16A1800788A3A /* SDL_hidapi_wii.c */; }; + F3D60A8B28C16A1900788A3A /* SDL_hidapi_wii.c in Sources */ = {isa = PBXBuildFile; fileRef = F3D60A8228C16A1800788A3A /* SDL_hidapi_wii.c */; }; + F3F07D5A269640160074468B /* SDL_hidapi_luna.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F07D59269640160074468B /* SDL_hidapi_luna.c */; }; + F3F07D5B269640160074468B /* SDL_hidapi_luna.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F07D59269640160074468B /* SDL_hidapi_luna.c */; }; + F3F07D5C269640160074468B /* SDL_hidapi_luna.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F07D59269640160074468B /* SDL_hidapi_luna.c */; }; + F3F07D5D269640160074468B /* SDL_hidapi_luna.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F07D59269640160074468B /* SDL_hidapi_luna.c */; }; + F3F07D5E269640160074468B /* SDL_hidapi_luna.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F07D59269640160074468B /* SDL_hidapi_luna.c */; }; + F3F07D5F269640160074468B /* SDL_hidapi_luna.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F07D59269640160074468B /* SDL_hidapi_luna.c */; }; + F3F07D60269640160074468B /* SDL_hidapi_luna.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F07D59269640160074468B /* SDL_hidapi_luna.c */; }; + F3F07D61269640160074468B /* SDL_hidapi_luna.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F07D59269640160074468B /* SDL_hidapi_luna.c */; }; + F3F07D62269640160074468B /* SDL_hidapi_luna.c in Sources */ = {isa = PBXBuildFile; fileRef = F3F07D59269640160074468B /* SDL_hidapi_luna.c */; }; FA24348B21D41FFB00B8918A /* SDL_metal.h in Headers */ = {isa = PBXBuildFile; fileRef = FA24348A21D41FFB00B8918A /* SDL_metal.h */; settings = {ATTRIBUTES = (Public, ); }; }; FA73671D19A540EF004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73671C19A540EF004122E4 /* CoreVideo.framework */; }; FA73671F19A54144004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73671C19A540EF004122E4 /* CoreVideo.framework */; }; @@ -3916,13 +3730,6 @@ remoteGlobalIDString = BECDF5FE0761BA81005FE872; remoteInfo = "Framework (Upgraded)"; }; - F3190016240CA3BA00ED104F /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 0867D690FE84028FC02AAC07 /* Project object */; - proxyType = 1; - remoteGlobalIDString = A75FDB8023E4C74400529352; - remoteInfo = hidapi; - }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -3932,7 +3739,6 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( - A75FDB9B23E4CAEF00529352 /* hidapi.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -3943,7 +3749,6 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( - A75FDB9E23E4CAFA00529352 /* hidapi.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -3954,7 +3759,6 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( - A75FDBA123E4CAFF00529352 /* hidapi.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -3969,41 +3773,38 @@ 00CFA89C106B4BA100758660 /* ForceFeedback.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ForceFeedback.framework; path = System/Library/Frameworks/ForceFeedback.framework; sourceTree = SDKROOT; }; 00D0D08310675DD9004B05EF /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; }; 4D4820431F0F10B400EDC31C /* SDL_vulkan.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDL_vulkan.h; sourceTree = ""; }; + 5616CA49252BB2A5005D5928 /* SDL_url.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_url.c; sourceTree = ""; }; + 5616CA4A252BB2A6005D5928 /* SDL_sysurl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_sysurl.h; sourceTree = ""; }; + 5616CA4B252BB2A6005D5928 /* SDL_sysurl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_sysurl.m; sourceTree = ""; }; + 5616CA4F252BB2BE005D5928 /* SDL_misc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_misc.h; sourceTree = ""; }; 564624351FF821B80074AC87 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; 564624371FF821CB0074AC87 /* Metal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Metal.framework; path = System/Library/Frameworks/Metal.framework; sourceTree = SDKROOT; }; + 566E26792462701100718109 /* SDL_locale.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_locale.h; sourceTree = ""; }; + 566E26CC246274CB00718109 /* SDL_syslocale.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDL_syslocale.m; path = locale/macosx/SDL_syslocale.m; sourceTree = ""; }; + 566E26CD246274CB00718109 /* SDL_locale.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_locale.c; path = locale/SDL_locale.c; sourceTree = ""; }; + 566E26CE246274CC00718109 /* SDL_syslocale.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_syslocale.h; path = locale/SDL_syslocale.h; sourceTree = ""; }; 567E2F2017C44C35005F1892 /* SDL_filesystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_filesystem.h; sourceTree = ""; }; 5C2EF7001FC9EF0F003F5197 /* SDL_egl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_egl.h; sourceTree = ""; }; + 75E09158241EA924004729E1 /* SDL_virtualjoystick.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_virtualjoystick.c; sourceTree = ""; }; + 75E09159241EA924004729E1 /* SDL_virtualjoystick_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_virtualjoystick_c.h; sourceTree = ""; }; + 9846B07B287A9020000C35C8 /* SDL_hidapi_shield.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_hidapi_shield.c; sourceTree = ""; }; + A1626A3D2617006A003F1973 /* SDL_triangle.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_triangle.c; sourceTree = ""; }; + A1626A512617008C003F1973 /* SDL_triangle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_triangle.h; sourceTree = ""; }; + A1BB8B6127F6CF320057CFA8 /* SDL_list.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_list.c; sourceTree = ""; }; + A1BB8B6227F6CF330057CFA8 /* SDL_list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_list.h; sourceTree = ""; }; A7381E931D8B69C300B177DD /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; A7381E951D8B69D600B177DD /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; }; A75FCEB323E25AB700529352 /* libSDL2.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libSDL2.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; A75FD06C23E25AC700529352 /* libSDL2.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libSDL2.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; A75FDAA523E2792500529352 /* hid.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = hid.m; sourceTree = ""; }; A75FDAAC23E2795C00529352 /* SDL_hidapi_steam.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_hidapi_steam.c; sourceTree = ""; }; - A75FDAB323E2797600529352 /* CoreBluetooth.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreBluetooth.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.2.sdk/System/Library/Frameworks/CoreBluetooth.framework; sourceTree = DEVELOPER_DIR; }; - A75FDAB523E2799700529352 /* CoreBluetooth.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreBluetooth.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS13.2.sdk/System/Library/Frameworks/CoreBluetooth.framework; sourceTree = DEVELOPER_DIR; }; A75FDAB923E28A7A00529352 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; A75FDABD23E28B6200529352 /* GameController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameController.framework; path = System/Library/Frameworks/GameController.framework; sourceTree = SDKROOT; }; A75FDABF23E28B8000529352 /* CoreMotion.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMotion.framework; path = System/Library/Frameworks/CoreMotion.framework; sourceTree = SDKROOT; }; A75FDAC123E28B9600529352 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; A75FDAC323E28BA700529352 /* CoreBluetooth.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreBluetooth.framework; path = System/Library/Frameworks/CoreBluetooth.framework; sourceTree = SDKROOT; }; - A75FDAC923E28D0100529352 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS13.2.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; - A75FDACB23E28D0700529352 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS13.2.sdk/System/Library/Frameworks/QuartzCore.framework; sourceTree = DEVELOPER_DIR; }; - A75FDACD23E28D0F00529352 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS13.2.sdk/System/Library/Frameworks/OpenGLES.framework; sourceTree = DEVELOPER_DIR; }; - A75FDACF23E28D1300529352 /* Metal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Metal.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS13.2.sdk/System/Library/Frameworks/Metal.framework; sourceTree = DEVELOPER_DIR; }; - A75FDAD123E28D2000529352 /* GameController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameController.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS13.2.sdk/System/Library/Frameworks/GameController.framework; sourceTree = DEVELOPER_DIR; }; - A75FDAD323E28D2E00529352 /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS13.2.sdk/System/Library/Frameworks/CoreVideo.framework; sourceTree = DEVELOPER_DIR; }; - A75FDAD523E28D3300529352 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS13.2.sdk/System/Library/Frameworks/CoreGraphics.framework; sourceTree = DEVELOPER_DIR; }; - A75FDAD723E28D3B00529352 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS13.2.sdk/System/Library/Frameworks/CoreFoundation.framework; sourceTree = DEVELOPER_DIR; }; - A75FDADA23E28D4900529352 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS13.2.sdk/System/Library/Frameworks/CoreAudio.framework; sourceTree = DEVELOPER_DIR; }; - A75FDADC23E28D5500529352 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS13.2.sdk/System/Library/Frameworks/AVFoundation.framework; sourceTree = DEVELOPER_DIR; }; - A75FDADE23E28D6600529352 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS13.2.sdk/System/Library/Frameworks/AudioToolbox.framework; sourceTree = DEVELOPER_DIR; }; A75FDAF523E35EC400529352 /* SDL_config_iphoneos.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_config_iphoneos.h; sourceTree = ""; }; - A75FDB4923E399AC00529352 /* hidapi.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = hidapi.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - A75FDB4C23E399AC00529352 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; A75FDB5723E39E6100529352 /* hidapi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = hidapi.h; path = hidapi/hidapi.h; sourceTree = ""; }; - A75FDB6E23E3A2C900529352 /* hidapi.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = hidapi.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - A75FDB8C23E4C74400529352 /* hidapi.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = hidapi.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - A75FDB8D23E4C74400529352 /* hidapi-iOS copy-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "hidapi-iOS copy-Info.plist"; path = "/Users/saml/projects/SDL/Xcode/SDL/hidapi-iOS copy-Info.plist"; sourceTree = ""; }; A75FDB9223E4C8DB00529352 /* hid.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = hid.c; sourceTree = ""; }; A75FDBA323E4CB6F00529352 /* LICENSE-bsd.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "LICENSE-bsd.txt"; sourceTree = ""; }; A75FDBA423E4CB6F00529352 /* AUTHORS.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = AUTHORS.txt; sourceTree = ""; }; @@ -4015,13 +3816,6 @@ A769B23D23E259AE00872273 /* libSDL2.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSDL2.a; sourceTree = BUILT_PRODUCTS_DIR; }; A77E6EB3167AB0A90010E40B /* SDL_gamecontroller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_gamecontroller.h; sourceTree = ""; }; A7D88B5423E2437C00DCD162 /* SDL2.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SDL2.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - A7D88BBB23E24A2F00DCD162 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.2.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; - A7D88BBD23E24A6000DCD162 /* GameController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameController.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.2.sdk/System/Library/Frameworks/GameController.framework; sourceTree = DEVELOPER_DIR; }; - A7D88BBF23E24A7700DCD162 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.2.sdk/System/Library/Frameworks/OpenGLES.framework; sourceTree = DEVELOPER_DIR; }; - A7D88BC123E24A8800DCD162 /* CoreMotion.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMotion.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.2.sdk/System/Library/Frameworks/CoreMotion.framework; sourceTree = DEVELOPER_DIR; }; - A7D88BC323E24A9F00DCD162 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.2.sdk/System/Library/Frameworks/AudioToolbox.framework; sourceTree = DEVELOPER_DIR; }; - A7D88BC523E24ABA00DCD162 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.2.sdk/System/Library/Frameworks/AVFoundation.framework; sourceTree = DEVELOPER_DIR; }; - A7D88BC723E24B0200DCD162 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.2.sdk/System/Library/Frameworks/CoreGraphics.framework; sourceTree = DEVELOPER_DIR; }; A7D88D1523E24BED00DCD162 /* SDL2.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SDL2.framework; sourceTree = BUILT_PRODUCTS_DIR; }; A7D88E5423E24D3B00DCD162 /* libSDL2.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSDL2.a; sourceTree = BUILT_PRODUCTS_DIR; }; A7D8A57023E2513D00DCD162 /* SDL_dataqueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_dataqueue.h; sourceTree = ""; }; @@ -4054,13 +3848,11 @@ A7D8A5E023E2513D00DCD162 /* SDL_timer_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_timer_c.h; sourceTree = ""; }; A7D8A5E223E2513D00DCD162 /* SDL_systimer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_systimer.c; sourceTree = ""; }; A7D8A5E823E2513D00DCD162 /* SDL_systimer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_systimer.c; sourceTree = ""; }; - A7D8A5ED23E2513D00DCD162 /* SDL_offscreenopengl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_offscreenopengl.c; sourceTree = ""; }; A7D8A5EE23E2513D00DCD162 /* SDL_offscreenevents_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_offscreenevents_c.h; sourceTree = ""; }; A7D8A5EF23E2513D00DCD162 /* SDL_offscreenwindow.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_offscreenwindow.c; sourceTree = ""; }; A7D8A5F023E2513D00DCD162 /* SDL_offscreenevents.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_offscreenevents.c; sourceTree = ""; }; A7D8A5F123E2513D00DCD162 /* SDL_offscreenvideo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_offscreenvideo.h; sourceTree = ""; }; A7D8A5F223E2513D00DCD162 /* SDL_offscreenframebuffer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_offscreenframebuffer.c; sourceTree = ""; }; - A7D8A5F323E2513D00DCD162 /* SDL_offscreenopengl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_offscreenopengl.h; sourceTree = ""; }; A7D8A5F423E2513D00DCD162 /* SDL_offscreenframebuffer_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_offscreenframebuffer_c.h; sourceTree = ""; }; A7D8A5F523E2513D00DCD162 /* SDL_offscreenwindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_offscreenwindow.h; sourceTree = ""; }; A7D8A5F623E2513D00DCD162 /* SDL_offscreenvideo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_offscreenvideo.c; sourceTree = ""; }; @@ -4095,7 +3887,6 @@ A7D8A62523E2513D00DCD162 /* SDL_uikitvulkan.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_uikitvulkan.m; sourceTree = ""; }; A7D8A62623E2513D00DCD162 /* SDL_uikitmessagebox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_uikitmessagebox.h; sourceTree = ""; }; A7D8A62723E2513D00DCD162 /* SDL_uikitwindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_uikitwindow.h; sourceTree = ""; }; - A7D8A62823E2513D00DCD162 /* keyinfotable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = keyinfotable.h; sourceTree = ""; }; A7D8A62923E2513D00DCD162 /* SDL_uikitview.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_uikitview.m; sourceTree = ""; }; A7D8A62A23E2513D00DCD162 /* SDL_uikitclipboard.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_uikitclipboard.m; sourceTree = ""; }; A7D8A62B23E2513D00DCD162 /* SDL_uikitopenglview.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_uikitopenglview.h; sourceTree = ""; }; @@ -4129,7 +3920,6 @@ A7D8A68523E2513E00DCD162 /* SDL_cocoavideo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_cocoavideo.m; sourceTree = ""; }; A7D8A68623E2513E00DCD162 /* SDL_cocoametalview.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_cocoametalview.h; sourceTree = ""; }; A7D8A68723E2513E00DCD162 /* SDL_cocoamouse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_cocoamouse.m; sourceTree = ""; }; - A7D8A68823E2513E00DCD162 /* SDL_cocoamousetap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_cocoamousetap.h; sourceTree = ""; }; A7D8A68923E2513E00DCD162 /* SDL_cocoaevents.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_cocoaevents.m; sourceTree = ""; }; A7D8A68A23E2513E00DCD162 /* SDL_cocoaclipboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_cocoaclipboard.h; sourceTree = ""; }; A7D8A68B23E2513E00DCD162 /* SDL_cocoamessagebox.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_cocoamessagebox.m; sourceTree = ""; }; @@ -4144,48 +3934,10 @@ A7D8A69423E2513E00DCD162 /* SDL_cocoamessagebox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_cocoamessagebox.h; sourceTree = ""; }; A7D8A69523E2513E00DCD162 /* SDL_cocoaclipboard.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_cocoaclipboard.m; sourceTree = ""; }; A7D8A69623E2513E00DCD162 /* SDL_cocoaevents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_cocoaevents.h; sourceTree = ""; }; - A7D8A69723E2513E00DCD162 /* SDL_cocoamousetap.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_cocoamousetap.m; sourceTree = ""; }; A7D8A69823E2513E00DCD162 /* SDL_cocoamouse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_cocoamouse.h; sourceTree = ""; }; A7D8A69923E2513E00DCD162 /* SDL_cocoametalview.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_cocoametalview.m; sourceTree = ""; }; A7D8A6B623E2513E00DCD162 /* SDL_egl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_egl.c; sourceTree = ""; }; A7D8A6FA23E2513E00DCD162 /* SDL_blit_1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_blit_1.c; sourceTree = ""; }; - A7D8A6FC23E2513E00DCD162 /* SDL_x11touch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_x11touch.h; sourceTree = ""; }; - A7D8A6FD23E2513E00DCD162 /* SDL_x11messagebox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_x11messagebox.h; sourceTree = ""; }; - A7D8A6FE23E2513E00DCD162 /* SDL_x11modes.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_x11modes.c; sourceTree = ""; }; - A7D8A6FF23E2513E00DCD162 /* SDL_x11opengl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_x11opengl.c; sourceTree = ""; }; - A7D8A70023E2513E00DCD162 /* SDL_x11vulkan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_x11vulkan.c; sourceTree = ""; }; - A7D8A70123E2513E00DCD162 /* SDL_x11shape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_x11shape.h; sourceTree = ""; }; - A7D8A70223E2513E00DCD162 /* SDL_x11xinput2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_x11xinput2.c; sourceTree = ""; }; - A7D8A70323E2513E00DCD162 /* SDL_x11opengles.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_x11opengles.h; sourceTree = ""; }; - A7D8A70423E2513E00DCD162 /* SDL_x11mouse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_x11mouse.c; sourceTree = ""; }; - A7D8A70523E2513E00DCD162 /* SDL_x11dyn.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_x11dyn.c; sourceTree = ""; }; - A7D8A70623E2513E00DCD162 /* SDL_x11framebuffer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_x11framebuffer.c; sourceTree = ""; }; - A7D8A70723E2513E00DCD162 /* SDL_x11window.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_x11window.c; sourceTree = ""; }; - A7D8A70823E2513E00DCD162 /* SDL_x11video.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_x11video.c; sourceTree = ""; }; - A7D8A70923E2513E00DCD162 /* imKStoUCS.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = imKStoUCS.c; sourceTree = ""; }; - A7D8A70A23E2513E00DCD162 /* SDL_x11events.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_x11events.c; sourceTree = ""; }; - A7D8A70B23E2513E00DCD162 /* SDL_x11clipboard.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_x11clipboard.c; sourceTree = ""; }; - A7D8A70C23E2513E00DCD162 /* SDL_x11keyboard.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_x11keyboard.c; sourceTree = ""; }; - A7D8A70D23E2513E00DCD162 /* SDL_x11sym.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_x11sym.h; sourceTree = ""; }; - A7D8A70E23E2513E00DCD162 /* SDL_x11opengl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_x11opengl.h; sourceTree = ""; }; - A7D8A70F23E2513E00DCD162 /* SDL_x11modes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_x11modes.h; sourceTree = ""; }; - A7D8A71023E2513E00DCD162 /* SDL_x11messagebox.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_x11messagebox.c; sourceTree = ""; }; - A7D8A71123E2513E00DCD162 /* SDL_x11touch.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_x11touch.c; sourceTree = ""; }; - A7D8A71223E2513E00DCD162 /* edid-parse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "edid-parse.c"; sourceTree = ""; }; - A7D8A71323E2513E00DCD162 /* SDL_x11xinput2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_x11xinput2.h; sourceTree = ""; }; - A7D8A71423E2513E00DCD162 /* edid.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = edid.h; sourceTree = ""; }; - A7D8A71523E2513E00DCD162 /* SDL_x11vulkan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_x11vulkan.h; sourceTree = ""; }; - A7D8A71623E2513E00DCD162 /* SDL_x11shape.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_x11shape.c; sourceTree = ""; }; - A7D8A71723E2513E00DCD162 /* SDL_x11window.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_x11window.h; sourceTree = ""; }; - A7D8A71823E2513E00DCD162 /* SDL_x11framebuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_x11framebuffer.h; sourceTree = ""; }; - A7D8A71923E2513E00DCD162 /* SDL_x11dyn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_x11dyn.h; sourceTree = ""; }; - A7D8A71A23E2513E00DCD162 /* SDL_x11mouse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_x11mouse.h; sourceTree = ""; }; - A7D8A71B23E2513E00DCD162 /* SDL_x11opengles.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_x11opengles.c; sourceTree = ""; }; - A7D8A71C23E2513E00DCD162 /* SDL_x11keyboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_x11keyboard.h; sourceTree = ""; }; - A7D8A71D23E2513E00DCD162 /* SDL_x11clipboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_x11clipboard.h; sourceTree = ""; }; - A7D8A71E23E2513E00DCD162 /* SDL_x11events.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_x11events.h; sourceTree = ""; }; - A7D8A71F23E2513E00DCD162 /* imKStoUCS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imKStoUCS.h; sourceTree = ""; }; - A7D8A72023E2513E00DCD162 /* SDL_x11video.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_x11video.h; sourceTree = ""; }; A7D8A72323E2513E00DCD162 /* gl2ext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gl2ext.h; sourceTree = ""; }; A7D8A72423E2513E00DCD162 /* gl2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gl2.h; sourceTree = ""; }; A7D8A72523E2513E00DCD162 /* gl2platform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gl2platform.h; sourceTree = ""; }; @@ -4198,14 +3950,12 @@ A7D8A72F23E2513E00DCD162 /* vulkan_vi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vulkan_vi.h; sourceTree = ""; }; A7D8A73023E2513E00DCD162 /* vulkan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vulkan.h; sourceTree = ""; }; A7D8A73123E2513E00DCD162 /* vk_platform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vk_platform.h; sourceTree = ""; }; - A7D8A73223E2513E00DCD162 /* vulkan.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = vulkan.hpp; sourceTree = ""; }; A7D8A73323E2513E00DCD162 /* vulkan_fuchsia.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vulkan_fuchsia.h; sourceTree = ""; }; A7D8A73423E2513E00DCD162 /* vulkan_wayland.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vulkan_wayland.h; sourceTree = ""; }; A7D8A73523E2513E00DCD162 /* vulkan_win32.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vulkan_win32.h; sourceTree = ""; }; A7D8A73623E2513E00DCD162 /* vulkan_macos.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vulkan_macos.h; sourceTree = ""; }; A7D8A73723E2513E00DCD162 /* vulkan_xlib_xrandr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vulkan_xlib_xrandr.h; sourceTree = ""; }; A7D8A73823E2513E00DCD162 /* vulkan_xcb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vulkan_xcb.h; sourceTree = ""; }; - A7D8A73923E2513E00DCD162 /* vulkan_mir.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vulkan_mir.h; sourceTree = ""; }; A7D8A73A23E2513E00DCD162 /* vulkan_xlib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vulkan_xlib.h; sourceTree = ""; }; A7D8A73B23E2513E00DCD162 /* vulkan_ios.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vulkan_ios.h; sourceTree = ""; }; A7D8A73C23E2513E00DCD162 /* vulkan_core.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vulkan_core.h; sourceTree = ""; }; @@ -4219,7 +3969,6 @@ A7D8A76923E2513E00DCD162 /* SDL_shape.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_shape.c; sourceTree = ""; }; A7D8A76A23E2513E00DCD162 /* SDL_yuv_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_yuv_c.h; sourceTree = ""; }; A7D8A76B23E2513E00DCD162 /* SDL_blit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_blit.h; sourceTree = ""; }; - A7D8A76E23E2513E00DCD162 /* yuv_rgb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = yuv_rgb.c; sourceTree = ""; }; A7D8A77023E2513E00DCD162 /* yuv_rgb_sse_func.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = yuv_rgb_sse_func.h; sourceTree = ""; }; A7D8A77123E2513E00DCD162 /* yuv_rgb_std_func.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = yuv_rgb_std_func.h; sourceTree = ""; }; A7D8A77223E2513E00DCD162 /* yuv_rgb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = yuv_rgb.h; sourceTree = ""; }; @@ -4240,8 +3989,6 @@ A7D8A7A523E2513E00DCD162 /* SDL_steamcontroller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_steamcontroller.h; sourceTree = ""; }; A7D8A7A723E2513E00DCD162 /* SDL_steamcontroller.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_steamcontroller.c; sourceTree = ""; }; A7D8A7A923E2513E00DCD162 /* SDL_joystick.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_joystick.c; sourceTree = ""; }; - A7D8A7AB23E2513E00DCD162 /* SDL_sysjoystick.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_sysjoystick.m; sourceTree = ""; }; - A7D8A7AC23E2513E00DCD162 /* SDL_sysjoystick_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_sysjoystick_c.h; sourceTree = ""; }; A7D8A7AD23E2513E00DCD162 /* SDL_gamecontroller.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_gamecontroller.c; sourceTree = ""; }; A7D8A7C223E2513E00DCD162 /* SDL_hidapi_xbox360.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_hidapi_xbox360.c; sourceTree = ""; }; A7D8A7C323E2513E00DCD162 /* SDL_hidapi_ps4.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_hidapi_ps4.c; sourceTree = ""; }; @@ -4252,8 +3999,6 @@ A7D8A7C823E2513E00DCD162 /* SDL_hidapi_xbox360w.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_hidapi_xbox360w.c; sourceTree = ""; }; A7D8A7C923E2513E00DCD162 /* SDL_hidapi_gamecube.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_hidapi_gamecube.c; sourceTree = ""; }; A7D8A7CB23E2513E00DCD162 /* usb_ids.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = usb_ids.h; sourceTree = ""; }; - A7D8A7CD23E2513E00DCD162 /* SDL_sysjoystick.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_sysjoystick.c; sourceTree = ""; }; - A7D8A7CE23E2513E00DCD162 /* SDL_sysjoystick_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_sysjoystick_c.h; sourceTree = ""; }; A7D8A7CF23E2513E00DCD162 /* SDL_sysjoystick.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_sysjoystick.h; sourceTree = ""; }; A7D8A7D023E2513E00DCD162 /* SDL_joystick_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_joystick_c.h; sourceTree = ""; }; A7D8A7D923E2513E00DCD162 /* controller_type.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = controller_type.h; sourceTree = ""; }; @@ -4376,7 +4121,6 @@ A7D8A93C23E2514000DCD162 /* SDL_quit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_quit.c; sourceTree = ""; }; A7D8A93D23E2514000DCD162 /* SDL_keyboard_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_keyboard_c.h; sourceTree = ""; }; A7D8A93E23E2514000DCD162 /* SDL_touch.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_touch.c; sourceTree = ""; }; - A7D8A93F23E2514000DCD162 /* SDL_sysevents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_sysevents.h; sourceTree = ""; }; A7D8A94023E2514000DCD162 /* SDL_gesture.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_gesture.c; sourceTree = ""; }; A7D8A94123E2514000DCD162 /* scancodes_xfree86.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scancodes_xfree86.h; sourceTree = ""; }; A7D8A94223E2514000DCD162 /* SDL_events_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_events_c.h; sourceTree = ""; }; @@ -4444,7 +4188,64 @@ BECDF6B30761BA81005FE872 /* libSDL2.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSDL2.a; sourceTree = BUILT_PRODUCTS_DIR; }; BECDF6BE0761BA81005FE872 /* SDL2 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = SDL2; sourceTree = BUILT_PRODUCTS_DIR; }; DB31407717554B71006C0E22 /* libSDL2.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libSDL2.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; + E2D187CF28A5673500D2B4F1 /* SDL2.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SDL2.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + E2D187D228A5673500D2B4F1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + F316AB7C2B5A02C2002EF551 /* yuv_rgb_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = yuv_rgb_common.h; sourceTree = ""; }; + F316AB7D2B5A02C2002EF551 /* yuv_rgb_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = yuv_rgb_internal.h; sourceTree = ""; }; + F316AB7E2B5A02C3002EF551 /* yuv_rgb_std.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = yuv_rgb_std.c; sourceTree = ""; }; + F316AB7F2B5A02C3002EF551 /* yuv_rgb_sse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = yuv_rgb_sse.c; sourceTree = ""; }; + F316AB802B5A02C3002EF551 /* yuv_rgb_lsx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = yuv_rgb_lsx.h; sourceTree = ""; }; + F316AB812B5A02C3002EF551 /* yuv_rgb_lsx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = yuv_rgb_lsx.c; sourceTree = ""; }; + F316AB822B5A02C3002EF551 /* yuv_rgb_sse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = yuv_rgb_sse.h; sourceTree = ""; }; + F316AB832B5A02C3002EF551 /* yuv_rgb_std.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = yuv_rgb_std.h; sourceTree = ""; }; + F316AB842B5A02C3002EF551 /* yuv_rgb_lsx_func.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = yuv_rgb_lsx_func.h; sourceTree = ""; }; + F31A92C628D4CB39003BFD6A /* SDL_offscreenopengles.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_offscreenopengles.h; sourceTree = ""; }; + F31A92C728D4CB39003BFD6A /* SDL_offscreenopengles.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_offscreenopengles.c; sourceTree = ""; }; + F32305FE28939F6400E66D30 /* SDL_hidapi_combined.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_hidapi_combined.c; sourceTree = ""; }; + F362B91F2B33916600D30B94 /* controller_list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = controller_list.h; sourceTree = ""; }; + F362B93B2B33920400D30B94 /* SDL_hidapi_steamdeck.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_hidapi_steamdeck.c; sourceTree = ""; }; + F362B93C2B33920400D30B94 /* SDL_hidapi_nintendo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_hidapi_nintendo.h; sourceTree = ""; }; + F362B9502B33EB7300D30B94 /* SDL_steam_virtual_gamepad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_steam_virtual_gamepad.h; sourceTree = ""; }; + F362B9512B33EB7300D30B94 /* SDL_steam_virtual_gamepad.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_steam_virtual_gamepad.c; sourceTree = ""; }; + F376F6182559B29300CFC0BC /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.1.sdk/System/Library/Frameworks/OpenGLES.framework; sourceTree = DEVELOPER_DIR; }; + F376F61A2559B2AF00CFC0BC /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/iOSSupport/System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + F376F6312559B31D00CFC0BC /* GameController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameController.framework; path = System/iOSSupport/System/Library/Frameworks/GameController.framework; sourceTree = SDKROOT; }; + F376F6CC2559B54500CFC0BC /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS14.0.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; + F376F6D82559B59600CFC0BC /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS14.0.sdk/System/Library/Frameworks/AudioToolbox.framework; sourceTree = DEVELOPER_DIR; }; + F376F6DA2559B5A000CFC0BC /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS14.0.sdk/System/Library/Frameworks/AVFoundation.framework; sourceTree = DEVELOPER_DIR; }; + F376F6DC2559B5A900CFC0BC /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS14.0.sdk/System/Library/Frameworks/OpenGLES.framework; sourceTree = DEVELOPER_DIR; }; + F376F6DE2559B5BA00CFC0BC /* GameController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameController.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS14.0.sdk/System/Library/Frameworks/GameController.framework; sourceTree = DEVELOPER_DIR; }; + F376F6E02559B5CA00CFC0BC /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS14.0.sdk/System/Library/Frameworks/CoreVideo.framework; sourceTree = DEVELOPER_DIR; }; + F376F6F72559B5EC00CFC0BC /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS14.0.sdk/System/Library/Frameworks/CoreGraphics.framework; sourceTree = DEVELOPER_DIR; }; + F376F71E2559B73A00CFC0BC /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS14.0.sdk/System/Library/Frameworks/QuartzCore.framework; sourceTree = DEVELOPER_DIR; }; + F376F7212559B74900CFC0BC /* Metal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Metal.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS14.0.sdk/System/Library/Frameworks/Metal.framework; sourceTree = DEVELOPER_DIR; }; + F376F7252559B76800CFC0BC /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS14.0.sdk/System/Library/Frameworks/CoreFoundation.framework; sourceTree = DEVELOPER_DIR; }; + F376F7272559B77100CFC0BC /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS14.0.sdk/System/Library/Frameworks/CoreAudio.framework; sourceTree = DEVELOPER_DIR; }; + F37A8E1928405AA100C38E95 /* CMake */ = {isa = PBXFileReference; lastKnownFileType = folder; path = CMake; sourceTree = ""; }; + F37DC5F225350EBC0002E6F7 /* CoreHaptics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreHaptics.framework; path = System/Library/Frameworks/CoreHaptics.framework; sourceTree = SDKROOT; }; + F37DC5F425350ECC0002E6F7 /* CoreHaptics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreHaptics.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS14.0.sdk/System/Library/Frameworks/CoreHaptics.framework; sourceTree = DEVELOPER_DIR; }; + F3820712284F3609004DD584 /* controller_type.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = controller_type.c; sourceTree = ""; }; + F382071C284F362F004DD584 /* SDL_guid.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_guid.c; sourceTree = ""; }; + F3820726284F3643004DD584 /* SDL_guid.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_guid.h; sourceTree = ""; }; + F38233842738EB8600F7F527 /* SDL_hidapi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_hidapi.h; sourceTree = ""; }; + F382339B2738ED6600F7F527 /* CoreBluetooth.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreBluetooth.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS15.0.sdk/System/Library/Frameworks/CoreBluetooth.framework; sourceTree = DEVELOPER_DIR; }; + F386F6E42884663E001840AA /* SDL_log_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_log_c.h; sourceTree = ""; }; + F386F6E52884663E001840AA /* SDL_utils_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_utils_c.h; sourceTree = ""; }; + F386F6E62884663E001840AA /* SDL_utils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_utils.c; sourceTree = ""; }; + F388C95428B5F6F600661ECF /* SDL_hidapi_ps3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_hidapi_ps3.c; sourceTree = ""; }; F3950CD7212BC88D00F51292 /* SDL_sensor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_sensor.h; sourceTree = ""; }; + F395BF6425633B2400942BFF /* SDL_crc32.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_crc32.c; sourceTree = ""; }; + F395C1912569C68E00942BFF /* SDL_iokitjoystick_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_iokitjoystick_c.h; sourceTree = ""; }; + F395C1922569C68E00942BFF /* SDL_iokitjoystick.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_iokitjoystick.c; sourceTree = ""; }; + F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_mfijoystick.m; sourceTree = ""; }; + F395C1B02569C6A000942BFF /* SDL_mfijoystick_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_mfijoystick_c.h; sourceTree = ""; }; + F3973FA028A59BDD00B84553 /* SDL_vacopy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_vacopy.h; sourceTree = ""; }; + F3973FA128A59BDD00B84553 /* SDL_crc16.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_crc16.c; sourceTree = ""; }; + F3984CCF25BCC92800374F43 /* SDL_hidapi_stadia.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_hidapi_stadia.c; sourceTree = ""; }; + F3A4909D2554D38500E92A8B /* SDL_hidapi_ps5.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_hidapi_ps5.c; sourceTree = ""; }; + F3ADAB8D2576F0B300A6B1D9 /* SDL_sysurl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_sysurl.m; sourceTree = ""; }; + F3D60A8228C16A1800788A3A /* SDL_hidapi_wii.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_hidapi_wii.c; sourceTree = ""; }; + F3F07D59269640160074468B /* SDL_hidapi_luna.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_hidapi_luna.c; sourceTree = ""; }; F59C710300D5CB5801000001 /* ReadMe.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = ReadMe.txt; sourceTree = ""; }; F59C710600D5CB5801000001 /* SDL.info */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = SDL.info; sourceTree = ""; }; F5A2EF3900C6A39A01000001 /* BUGS.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = BUGS.txt; path = ../../BUGS.txt; sourceTree = SOURCE_ROOT; }; @@ -4463,14 +4264,15 @@ A75FDAC423E28BA700529352 /* CoreBluetooth.framework in Frameworks */, A75FCEAB23E25AB700529352 /* CoreFoundation.framework in Frameworks */, A75FDAC223E28B9600529352 /* CoreGraphics.framework in Frameworks */, + F3942659253579B400B03694 /* CoreHaptics.framework in Frameworks */, A75FDAC023E28B8000529352 /* CoreMotion.framework in Frameworks */, A75FCEA823E25AB700529352 /* CoreVideo.framework in Frameworks */, A75FDABE23E28B6200529352 /* GameController.framework in Frameworks */, A75FCEAA23E25AB700529352 /* IOKit.framework in Frameworks */, A75FCEA523E25AB700529352 /* Metal.framework in Frameworks */, - A75FDABC23E28B4000529352 /* OpenGLES.framework in Frameworks */, + F376F70E2559B6B800CFC0BC /* OpenGLES.framework in Frameworks */, A75FCEA623E25AB700529352 /* QuartzCore.framework in Frameworks */, - A75FDABB23E28B1D00529352 /* UIKit.framework in Frameworks */, + F376F70F2559B6BF00CFC0BC /* UIKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -4478,45 +4280,19 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - A75FDADF23E28D6600529352 /* AudioToolbox.framework in Frameworks */, - A75FDADD23E28D5500529352 /* AVFoundation.framework in Frameworks */, - A75FDADB23E28D4900529352 /* CoreAudio.framework in Frameworks */, - A75FDAD923E28D3F00529352 /* CoreBluetooth.framework in Frameworks */, - A75FDAD823E28D3B00529352 /* CoreFoundation.framework in Frameworks */, - A75FDAD623E28D3300529352 /* CoreGraphics.framework in Frameworks */, - A75FDAD423E28D2E00529352 /* CoreVideo.framework in Frameworks */, - A75FDAD223E28D2000529352 /* GameController.framework in Frameworks */, - A75FDAD023E28D1300529352 /* Metal.framework in Frameworks */, - A75FDACE23E28D0F00529352 /* OpenGLES.framework in Frameworks */, - A75FDACC23E28D0700529352 /* QuartzCore.framework in Frameworks */, - A75FDACA23E28D0200529352 /* UIKit.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - A75FDB4623E399AC00529352 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - A75FDB5523E39DAC00529352 /* CoreBluetooth.framework in Frameworks */, - A75FDB5623E39DE900529352 /* UIKit.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - A75FDB6723E3A2C900529352 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - A75FDB6823E3A2C900529352 /* CoreBluetooth.framework in Frameworks */, - A75FDB6923E3A2C900529352 /* UIKit.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - A75FDB8523E4C74400529352 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - A75FDB9523E4C93600529352 /* CoreFoundation.framework in Frameworks */, - A75FDB9423E4C91300529352 /* IOKit.framework in Frameworks */, + F376F71B2559B71C00CFC0BC /* AudioToolbox.framework in Frameworks */, + F376F71C2559B72900CFC0BC /* AVFoundation.framework in Frameworks */, + F376F7282559B77100CFC0BC /* CoreAudio.framework in Frameworks */, + F382339D2738EE3F00F7F527 /* CoreBluetooth.framework in Frameworks */, + F376F7262559B76800CFC0BC /* CoreFoundation.framework in Frameworks */, + F376F7242559B76100CFC0BC /* CoreGraphics.framework in Frameworks */, + F394265A253579D200B03694 /* CoreHaptics.framework in Frameworks */, + F376F7232559B75800CFC0BC /* CoreVideo.framework in Frameworks */, + F376F7332559B79B00CFC0BC /* GameController.framework in Frameworks */, + F376F7222559B74900CFC0BC /* Metal.framework in Frameworks */, + F376F7202559B74200CFC0BC /* OpenGLES.framework in Frameworks */, + F376F71F2559B73A00CFC0BC /* QuartzCore.framework in Frameworks */, + F376F71D2559B73200CFC0BC /* UIKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -4531,21 +4307,21 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - A7D88BC423E24A9F00DCD162 /* AudioToolbox.framework in Frameworks */, - A7D88BC623E24ABA00DCD162 /* AVFoundation.framework in Frameworks */, + F376F6332559B33D00CFC0BC /* AudioToolbox.framework in Frameworks */, + F376F6402559B38A00CFC0BC /* AVFoundation.framework in Frameworks */, A7D88B4C23E2437C00DCD162 /* CoreAudio.framework in Frameworks */, - A75FDAB423E2797600529352 /* CoreBluetooth.framework in Frameworks */, + F382339A2738ED5600F7F527 /* CoreBluetooth.framework in Frameworks */, A7D88B4D23E2437C00DCD162 /* CoreFoundation.framework in Frameworks */, - A75FDB9D23E4CAFA00529352 /* hidapi.framework in Frameworks */, - A7D88BC823E24B0300DCD162 /* CoreGraphics.framework in Frameworks */, - A7D88BC223E24A8800DCD162 /* CoreMotion.framework in Frameworks */, + F376F63F2559B37300CFC0BC /* CoreGraphics.framework in Frameworks */, + F37DC5F325350EBC0002E6F7 /* CoreHaptics.framework in Frameworks */, + F376F63E2559B35200CFC0BC /* CoreMotion.framework in Frameworks */, A7D88B4E23E2437C00DCD162 /* CoreVideo.framework in Frameworks */, - A7D88BBE23E24A6000DCD162 /* GameController.framework in Frameworks */, + F376F6322559B31D00CFC0BC /* GameController.framework in Frameworks */, A7D88B5023E2437C00DCD162 /* IOKit.framework in Frameworks */, A7D88B4723E2437C00DCD162 /* Metal.framework in Frameworks */, - A7D88BC023E24A7700DCD162 /* OpenGLES.framework in Frameworks */, + F376F6192559B29300CFC0BC /* OpenGLES.framework in Frameworks */, A7D88B4823E2437C00DCD162 /* QuartzCore.framework in Frameworks */, - A7D88BBC23E24A2F00DCD162 /* UIKit.framework in Frameworks */, + F376F61B2559B2AF00CFC0BC /* UIKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -4553,19 +4329,19 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - A7D88D0523E24BED00DCD162 /* AudioToolbox.framework in Frameworks */, - A7D88D0623E24BED00DCD162 /* AVFoundation.framework in Frameworks */, + F376F6DB2559B5A000CFC0BC /* AVFoundation.framework in Frameworks */, + F376F6D92559B59600CFC0BC /* AudioToolbox.framework in Frameworks */, A7D88D0723E24BED00DCD162 /* CoreAudio.framework in Frameworks */, - A75FDAB623E2799700529352 /* CoreBluetooth.framework in Frameworks */, + F382339C2738ED6600F7F527 /* CoreBluetooth.framework in Frameworks */, A7D88D0823E24BED00DCD162 /* CoreFoundation.framework in Frameworks */, - A7D88D0923E24BED00DCD162 /* CoreGraphics.framework in Frameworks */, + F376F6F82559B5EC00CFC0BC /* CoreGraphics.framework in Frameworks */, + F37DC5F525350ECC0002E6F7 /* CoreHaptics.framework in Frameworks */, A7D88D0B23E24BED00DCD162 /* CoreVideo.framework in Frameworks */, - A7D88D0C23E24BED00DCD162 /* GameController.framework in Frameworks */, + F376F6DF2559B5BA00CFC0BC /* GameController.framework in Frameworks */, A7D88D0E23E24BED00DCD162 /* Metal.framework in Frameworks */, - A7D88D0F23E24BED00DCD162 /* OpenGLES.framework in Frameworks */, + F376F6DD2559B5A900CFC0BC /* OpenGLES.framework in Frameworks */, A7D88D1023E24BED00DCD162 /* QuartzCore.framework in Frameworks */, - A75FDBA023E4CAFF00529352 /* hidapi.framework in Frameworks */, - A7D88D1123E24BED00DCD162 /* UIKit.framework in Frameworks */, + F376F6EC2559B5DA00CFC0BC /* UIKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -4580,10 +4356,11 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 557D0CFB254586D7003913E3 /* GameController.framework in Frameworks */, + 557D0CFA254586CA003913E3 /* CoreHaptics.framework in Frameworks */, 564624381FF821DA0074AC87 /* Metal.framework in Frameworks */, 564624361FF821C20074AC87 /* QuartzCore.framework in Frameworks */, A7381E971D8B6A0300B177DD /* AudioToolbox.framework in Frameworks */, - A75FDB9A23E4CAEF00529352 /* hidapi.framework in Frameworks */, 00D0D0D810675E46004B05EF /* Carbon.framework in Frameworks */, 007317A40858DECD00B2BC32 /* Cocoa.framework in Frameworks */, A7381E961D8B69D600B177DD /* CoreAudio.framework in Frameworks */, @@ -4605,6 +4382,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 552673EC2546055000085751 /* CoreHaptics.framework in Frameworks */, + 552673EB2546054600085751 /* GameController.framework in Frameworks */, 5646243C1FF822170074AC87 /* Metal.framework in Frameworks */, 5646243B1FF822100074AC87 /* QuartzCore.framework in Frameworks */, 56C5237F1D8F4985001F2F30 /* CoreAudio.framework in Frameworks */, @@ -4618,6 +4397,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + E2D187CC28A5673500D2B4F1 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -4644,16 +4430,20 @@ 567E2F2017C44C35005F1892 /* SDL_filesystem.h */, A77E6EB3167AB0A90010E40B /* SDL_gamecontroller.h */, AA7557D51595D4D800BBD41B /* SDL_gesture.h */, + F3820726284F3643004DD584 /* SDL_guid.h */, AA7557D61595D4D800BBD41B /* SDL_haptic.h */, + F38233842738EB8600F7F527 /* SDL_hidapi.h */, AA7557D71595D4D800BBD41B /* SDL_hints.h */, AA7557D91595D4D800BBD41B /* SDL_joystick.h */, AA7557DA1595D4D800BBD41B /* SDL_keyboard.h */, AA7557DB1595D4D800BBD41B /* SDL_keycode.h */, AA7557DC1595D4D800BBD41B /* SDL_loadso.h */, + 566E26792462701100718109 /* SDL_locale.h */, AA7557DD1595D4D800BBD41B /* SDL_log.h */, AA7557DE1595D4D800BBD41B /* SDL_main.h */, AA9FF9591637CBF9000DF050 /* SDL_messagebox.h */, FA24348A21D41FFB00B8918A /* SDL_metal.h */, + 5616CA4F252BB2BE005D5928 /* SDL_misc.h */, AA7557DF1595D4D800BBD41B /* SDL_mouse.h */, AA7557E01595D4D800BBD41B /* SDL_mutex.h */, AA7557E11595D4D800BBD41B /* SDL_name.h */, @@ -4706,9 +4496,7 @@ A769B23D23E259AE00872273 /* libSDL2.a */, A75FCEB323E25AB700529352 /* libSDL2.dylib */, A75FD06C23E25AC700529352 /* libSDL2.dylib */, - A75FDB4923E399AC00529352 /* hidapi.framework */, - A75FDB6E23E3A2C900529352 /* hidapi.framework */, - A75FDB8C23E4C74400529352 /* hidapi.framework */, + E2D187CF28A5673500D2B4F1 /* SDL2.framework */, ); name = Products; sourceTree = ""; @@ -4720,11 +4508,10 @@ F59C70FC00D5CB5801000001 /* pkg-support */, 0153844A006D81B07F000001 /* Public Headers */, 08FB77ACFE841707C02AAC07 /* Library Source */, - A75FDB4A23E399AC00529352 /* hidapi */, + E2D187D028A5673500D2B4F1 /* SDL2 */, 034768DDFF38A45A11DB9C8B /* Products */, BECDF66B0761BA81005FE872 /* Info-Framework.plist */, 564624341FF821B70074AC87 /* Frameworks */, - A75FDB8D23E4C74400529352 /* hidapi-iOS copy-Info.plist */, ); comments = "To build Universal Binaries, we have experimented with a variety of different options.\nThe complication is that we must retain compatibility with at least 10.2. \nThe Universal Binary defaults only work for > 10.3.9\n\nSo far, we have found:\ngcc 4.0.0 with Xcode 2.1 always links against libgcc_s. gcc 4.0.1 from Xcode 2.2 fixes this problem.\n\nBut gcc 4.0 will not work with < 10.3.9 because we continue to get an undefined symbol to _fprintf$LDBL128.\nSo we must use gcc 3.3 on PPC to accomplish 10.2 support. (But 4.0 is required for i386.)\n\nSetting the deployment target to 10.4 will disable prebinding, so for PPC, we set it less than 10.4 to preserve prebinding for legacy support.\n\nSetting the PPC SDKROOT to /Developers/SDKs/MacOSX10.2.8.sdk will link to 63.0.0 libSystem.B.dylib. Leaving it at current or 10.4u links to 88.1.2. However, as long as we are using gcc 3.3, it doesn't seem to matter as testing has demonstrated both will run. We have decided not to invoke the 10.2.8 SDK because it is not a default installed component with Xcode which will probably cause most people problems. However, rather than deleting the SDKROOT_ppc entry entirely, we have mapped it to 10.4u in case we decide we need to change this setting.\n\nTo use Altivec or SSE, we needed architecture specific flags:\nOTHER_CFLAGS_ppc\nOTHER_CFLAGS_i386\nOTHER_CFLAGS=$(OTHER_CFLAGS_($CURRENT_ARCH))\n\nThe general OTHER_CFLAGS needed to be manually mapped to architecture specific options because Xcode didn't do this automatically for us.\n\n\n"; indentWidth = 4; @@ -4748,7 +4535,9 @@ A7D8A79D23E2513E00DCD162 /* joystick */, A7D8A91123E2514000DCD162 /* libm */, A7D8A85D23E2513F00DCD162 /* loadso */, + 566E26CB246274AE00718109 /* locale */, A7D8A5AC23E2513D00DCD162 /* main */, + 5616CA47252BB278005D5928 /* misc */, A7D8A7DF23E2513F00DCD162 /* power */, A7D8A8DA23E2514000DCD162 /* render */, A7D8A57623E2513D00DCD162 /* sensor */, @@ -4762,44 +4551,66 @@ A7D8A57023E2513D00DCD162 /* SDL_dataqueue.h */, A7D8A57523E2513D00DCD162 /* SDL_error_c.h */, A7D8A8BF23E2513F00DCD162 /* SDL_error.c */, + F382071C284F362F004DD584 /* SDL_guid.c */, A7D8A8D123E2514000DCD162 /* SDL_hints_c.h */, A7D8A5AB23E2513D00DCD162 /* SDL_hints.c */, A7D8A58323E2513D00DCD162 /* SDL_internal.h */, + A1BB8B6127F6CF320057CFA8 /* SDL_list.c */, + A1BB8B6227F6CF330057CFA8 /* SDL_list.h */, + F386F6E42884663E001840AA /* SDL_log_c.h */, A7D8A5DD23E2513D00DCD162 /* SDL_log.c */, + F386F6E52884663E001840AA /* SDL_utils_c.h */, + F386F6E62884663E001840AA /* SDL_utils.c */, A7D8A57123E2513D00DCD162 /* SDL.c */, ); name = "Library Source"; path = ../../src; sourceTree = ""; }; + 5616CA47252BB278005D5928 /* misc */ = { + isa = PBXGroup; + children = ( + F3ADAB8C2576F08500A6B1D9 /* ios */, + 5616CA48252BB285005D5928 /* macosx */, + 5616CA4A252BB2A6005D5928 /* SDL_sysurl.h */, + 5616CA49252BB2A5005D5928 /* SDL_url.c */, + ); + path = misc; + sourceTree = ""; + }; + 5616CA48252BB285005D5928 /* macosx */ = { + isa = PBXGroup; + children = ( + 5616CA4B252BB2A6005D5928 /* SDL_sysurl.m */, + ); + path = macosx; + sourceTree = ""; + }; 564624341FF821B70074AC87 /* Frameworks */ = { isa = PBXGroup; children = ( - A75FDADE23E28D6600529352 /* AudioToolbox.framework */, - A75FDADC23E28D5500529352 /* AVFoundation.framework */, - A75FDADA23E28D4900529352 /* CoreAudio.framework */, - A75FDAD723E28D3B00529352 /* CoreFoundation.framework */, - A75FDAD523E28D3300529352 /* CoreGraphics.framework */, - A75FDAD323E28D2E00529352 /* CoreVideo.framework */, - A75FDAD123E28D2000529352 /* GameController.framework */, - A75FDACF23E28D1300529352 /* Metal.framework */, - A75FDACD23E28D0F00529352 /* OpenGLES.framework */, - A75FDACB23E28D0700529352 /* QuartzCore.framework */, - A75FDAC923E28D0100529352 /* UIKit.framework */, + F382339B2738ED6600F7F527 /* CoreBluetooth.framework */, + F376F7272559B77100CFC0BC /* CoreAudio.framework */, + F376F7252559B76800CFC0BC /* CoreFoundation.framework */, + F376F7212559B74900CFC0BC /* Metal.framework */, + F376F71E2559B73A00CFC0BC /* QuartzCore.framework */, + F376F6F72559B5EC00CFC0BC /* CoreGraphics.framework */, + F376F6E02559B5CA00CFC0BC /* CoreVideo.framework */, + F376F6DE2559B5BA00CFC0BC /* GameController.framework */, + F376F6DC2559B5A900CFC0BC /* OpenGLES.framework */, + F376F6DA2559B5A000CFC0BC /* AVFoundation.framework */, + F376F6D82559B59600CFC0BC /* AudioToolbox.framework */, + F376F6CC2559B54500CFC0BC /* UIKit.framework */, + F376F6312559B31D00CFC0BC /* GameController.framework */, + F376F61A2559B2AF00CFC0BC /* UIKit.framework */, + F376F6182559B29300CFC0BC /* OpenGLES.framework */, + F37DC5F225350EBC0002E6F7 /* CoreHaptics.framework */, + F37DC5F425350ECC0002E6F7 /* CoreHaptics.framework */, A75FDAC323E28BA700529352 /* CoreBluetooth.framework */, A75FDAC123E28B9600529352 /* CoreGraphics.framework */, A75FDABF23E28B8000529352 /* CoreMotion.framework */, A75FDABD23E28B6200529352 /* GameController.framework */, A75FDAB923E28A7A00529352 /* AVFoundation.framework */, - A75FDAB323E2797600529352 /* CoreBluetooth.framework */, - A75FDAB523E2799700529352 /* CoreBluetooth.framework */, - A7D88BC723E24B0200DCD162 /* CoreGraphics.framework */, - A7D88BC523E24ABA00DCD162 /* AVFoundation.framework */, - A7D88BC323E24A9F00DCD162 /* AudioToolbox.framework */, - A7D88BC123E24A8800DCD162 /* CoreMotion.framework */, - A7D88BBF23E24A7700DCD162 /* OpenGLES.framework */, - A7D88BBD23E24A6000DCD162 /* GameController.framework */, - A7D88BBB23E24A2F00DCD162 /* UIKit.framework */, A7381E931D8B69C300B177DD /* AudioToolbox.framework */, 007317C10858E15000B2BC32 /* Carbon.framework */, 0073179D0858DECD00B2BC32 /* Cocoa.framework */, @@ -4814,6 +4625,33 @@ name = Frameworks; sourceTree = ""; }; + 566E26CB246274AE00718109 /* locale */ = { + isa = PBXGroup; + children = ( + 566E26EA246274E800718109 /* macosx */, + 566E26CD246274CB00718109 /* SDL_locale.c */, + 566E26CE246274CC00718109 /* SDL_syslocale.h */, + ); + name = locale; + sourceTree = ""; + }; + 566E26EA246274E800718109 /* macosx */ = { + isa = PBXGroup; + children = ( + 566E26CC246274CB00718109 /* SDL_syslocale.m */, + ); + name = macosx; + sourceTree = ""; + }; + 75E09157241EA924004729E1 /* virtual */ = { + isa = PBXGroup; + children = ( + 75E09158241EA924004729E1 /* SDL_virtualjoystick.c */, + 75E09159241EA924004729E1 /* SDL_virtualjoystick_c.h */, + ); + path = virtual; + sourceTree = ""; + }; A75FDAA423E2790500529352 /* ios */ = { isa = PBXGroup; children = ( @@ -4822,14 +4660,6 @@ path = ios; sourceTree = ""; }; - A75FDB4A23E399AC00529352 /* hidapi */ = { - isa = PBXGroup; - children = ( - A75FDB4C23E399AC00529352 /* Info.plist */, - ); - path = hidapi; - sourceTree = ""; - }; A75FDB9123E4C8B800529352 /* mac */ = { isa = PBXGroup; children = ( @@ -4968,7 +4798,6 @@ A7D8A72123E2513E00DCD162 /* khronos */, A7D8A5EC23E2513D00DCD162 /* offscreen */, A7D8A61823E2513D00DCD162 /* uikit */, - A7D8A6FB23E2513E00DCD162 /* x11 */, A7D8A76C23E2513E00DCD162 /* yuv2rgb */, A7D8A66223E2513E00DCD162 /* SDL_blit_0.c */, A7D8A6FA23E2513E00DCD162 /* SDL_blit_1.c */, @@ -5014,8 +4843,8 @@ A7D8A5F023E2513D00DCD162 /* SDL_offscreenevents.c */, A7D8A5F423E2513D00DCD162 /* SDL_offscreenframebuffer_c.h */, A7D8A5F223E2513D00DCD162 /* SDL_offscreenframebuffer.c */, - A7D8A5ED23E2513D00DCD162 /* SDL_offscreenopengl.c */, - A7D8A5F323E2513D00DCD162 /* SDL_offscreenopengl.h */, + F31A92C728D4CB39003BFD6A /* SDL_offscreenopengles.c */, + F31A92C628D4CB39003BFD6A /* SDL_offscreenopengles.h */, A7D8A5F623E2513D00DCD162 /* SDL_offscreenvideo.c */, A7D8A5F123E2513D00DCD162 /* SDL_offscreenvideo.h */, A7D8A5EF23E2513D00DCD162 /* SDL_offscreenwindow.c */, @@ -5040,7 +4869,6 @@ A7D8A61823E2513D00DCD162 /* uikit */ = { isa = PBXGroup; children = ( - A7D8A62823E2513D00DCD162 /* keyinfotable.h */, A7D8A62F23E2513D00DCD162 /* SDL_uikitappdelegate.h */, A7D8A61E23E2513D00DCD162 /* SDL_uikitappdelegate.m */, A7D8A62123E2513D00DCD162 /* SDL_uikitclipboard.h */, @@ -5088,8 +4916,6 @@ A7D8A68123E2513E00DCD162 /* SDL_cocoamodes.m */, A7D8A69823E2513E00DCD162 /* SDL_cocoamouse.h */, A7D8A68723E2513E00DCD162 /* SDL_cocoamouse.m */, - A7D8A68823E2513E00DCD162 /* SDL_cocoamousetap.h */, - A7D8A69723E2513E00DCD162 /* SDL_cocoamousetap.m */, A7D8A68D23E2513E00DCD162 /* SDL_cocoaopengl.h */, A7D8A67F23E2513E00DCD162 /* SDL_cocoaopengl.m */, A7D8A69023E2513E00DCD162 /* SDL_cocoaopengles.h */, @@ -5106,50 +4932,6 @@ path = cocoa; sourceTree = ""; }; - A7D8A6FB23E2513E00DCD162 /* x11 */ = { - isa = PBXGroup; - children = ( - A7D8A71223E2513E00DCD162 /* edid-parse.c */, - A7D8A71423E2513E00DCD162 /* edid.h */, - A7D8A70923E2513E00DCD162 /* imKStoUCS.c */, - A7D8A71F23E2513E00DCD162 /* imKStoUCS.h */, - A7D8A70B23E2513E00DCD162 /* SDL_x11clipboard.c */, - A7D8A71D23E2513E00DCD162 /* SDL_x11clipboard.h */, - A7D8A70523E2513E00DCD162 /* SDL_x11dyn.c */, - A7D8A71923E2513E00DCD162 /* SDL_x11dyn.h */, - A7D8A70A23E2513E00DCD162 /* SDL_x11events.c */, - A7D8A71E23E2513E00DCD162 /* SDL_x11events.h */, - A7D8A70623E2513E00DCD162 /* SDL_x11framebuffer.c */, - A7D8A71823E2513E00DCD162 /* SDL_x11framebuffer.h */, - A7D8A70C23E2513E00DCD162 /* SDL_x11keyboard.c */, - A7D8A71C23E2513E00DCD162 /* SDL_x11keyboard.h */, - A7D8A71023E2513E00DCD162 /* SDL_x11messagebox.c */, - A7D8A6FD23E2513E00DCD162 /* SDL_x11messagebox.h */, - A7D8A6FE23E2513E00DCD162 /* SDL_x11modes.c */, - A7D8A70F23E2513E00DCD162 /* SDL_x11modes.h */, - A7D8A70423E2513E00DCD162 /* SDL_x11mouse.c */, - A7D8A71A23E2513E00DCD162 /* SDL_x11mouse.h */, - A7D8A6FF23E2513E00DCD162 /* SDL_x11opengl.c */, - A7D8A70E23E2513E00DCD162 /* SDL_x11opengl.h */, - A7D8A71B23E2513E00DCD162 /* SDL_x11opengles.c */, - A7D8A70323E2513E00DCD162 /* SDL_x11opengles.h */, - A7D8A71623E2513E00DCD162 /* SDL_x11shape.c */, - A7D8A70123E2513E00DCD162 /* SDL_x11shape.h */, - A7D8A70D23E2513E00DCD162 /* SDL_x11sym.h */, - A7D8A71123E2513E00DCD162 /* SDL_x11touch.c */, - A7D8A6FC23E2513E00DCD162 /* SDL_x11touch.h */, - A7D8A70823E2513E00DCD162 /* SDL_x11video.c */, - A7D8A72023E2513E00DCD162 /* SDL_x11video.h */, - A7D8A70023E2513E00DCD162 /* SDL_x11vulkan.c */, - A7D8A71523E2513E00DCD162 /* SDL_x11vulkan.h */, - A7D8A70723E2513E00DCD162 /* SDL_x11window.c */, - A7D8A71723E2513E00DCD162 /* SDL_x11window.h */, - A7D8A70223E2513E00DCD162 /* SDL_x11xinput2.c */, - A7D8A71323E2513E00DCD162 /* SDL_x11xinput2.h */, - ); - path = x11; - sourceTree = ""; - }; A7D8A72123E2513E00DCD162 /* khronos */ = { isa = PBXGroup; children = ( @@ -5201,7 +4983,6 @@ A7D8A73323E2513E00DCD162 /* vulkan_fuchsia.h */, A7D8A73B23E2513E00DCD162 /* vulkan_ios.h */, A7D8A73623E2513E00DCD162 /* vulkan_macos.h */, - A7D8A73923E2513E00DCD162 /* vulkan_mir.h */, A7D8A72F23E2513E00DCD162 /* vulkan_vi.h */, A7D8A73423E2513E00DCD162 /* vulkan_wayland.h */, A7D8A73523E2513E00DCD162 /* vulkan_win32.h */, @@ -5209,7 +4990,6 @@ A7D8A73723E2513E00DCD162 /* vulkan_xlib_xrandr.h */, A7D8A73A23E2513E00DCD162 /* vulkan_xlib.h */, A7D8A73023E2513E00DCD162 /* vulkan.h */, - A7D8A73223E2513E00DCD162 /* vulkan.hpp */, ); path = vulkan; sourceTree = ""; @@ -5217,9 +4997,17 @@ A7D8A76C23E2513E00DCD162 /* yuv2rgb */ = { isa = PBXGroup; children = ( + F316AB7C2B5A02C2002EF551 /* yuv_rgb_common.h */, + F316AB7D2B5A02C2002EF551 /* yuv_rgb_internal.h */, + F316AB842B5A02C3002EF551 /* yuv_rgb_lsx_func.h */, + F316AB812B5A02C3002EF551 /* yuv_rgb_lsx.c */, + F316AB802B5A02C3002EF551 /* yuv_rgb_lsx.h */, A7D8A77023E2513E00DCD162 /* yuv_rgb_sse_func.h */, + F316AB7F2B5A02C3002EF551 /* yuv_rgb_sse.c */, + F316AB822B5A02C3002EF551 /* yuv_rgb_sse.h */, A7D8A77123E2513E00DCD162 /* yuv_rgb_std_func.h */, - A7D8A76E23E2513E00DCD162 /* yuv_rgb.c */, + F316AB7E2B5A02C3002EF551 /* yuv_rgb_std.c */, + F316AB832B5A02C3002EF551 /* yuv_rgb_std.h */, A7D8A77223E2513E00DCD162 /* yuv_rgb.h */, ); path = yuv2rgb; @@ -5266,11 +5054,16 @@ A7D8A7BE23E2513E00DCD162 /* hidapi */, A7D8A7AA23E2513E00DCD162 /* iphoneos */, A7D8A7A123E2513E00DCD162 /* steam */, - A7D8A7AD23E2513E00DCD162 /* SDL_gamecontroller.c */, - A7D8A7A923E2513E00DCD162 /* SDL_joystick.c */, + 75E09157241EA924004729E1 /* virtual */, + F362B91F2B33916600D30B94 /* controller_list.h */, + F3820712284F3609004DD584 /* controller_type.c */, A7D8A7D923E2513E00DCD162 /* controller_type.h */, + A7D8A7AD23E2513E00DCD162 /* SDL_gamecontroller.c */, A7D8A79E23E2513E00DCD162 /* SDL_gamecontrollerdb.h */, A7D8A7D023E2513E00DCD162 /* SDL_joystick_c.h */, + A7D8A7A923E2513E00DCD162 /* SDL_joystick.c */, + F362B9512B33EB7300D30B94 /* SDL_steam_virtual_gamepad.c */, + F362B9502B33EB7300D30B94 /* SDL_steam_virtual_gamepad.h */, A7D8A7CF23E2513E00DCD162 /* SDL_sysjoystick.h */, A7D8A7CB23E2513E00DCD162 /* usb_ids.h */, ); @@ -5297,8 +5090,8 @@ A7D8A7AA23E2513E00DCD162 /* iphoneos */ = { isa = PBXGroup; children = ( - A7D8A7AC23E2513E00DCD162 /* SDL_sysjoystick_c.h */, - A7D8A7AB23E2513E00DCD162 /* SDL_sysjoystick.m */, + F395C1B02569C6A000942BFF /* SDL_mfijoystick_c.h */, + F395C1AF2569C6A000942BFF /* SDL_mfijoystick.m */, ); path = iphoneos; sourceTree = ""; @@ -5306,12 +5099,21 @@ A7D8A7BE23E2513E00DCD162 /* hidapi */ = { isa = PBXGroup; children = ( + F32305FE28939F6400E66D30 /* SDL_hidapi_combined.c */, A7D8A7C923E2513E00DCD162 /* SDL_hidapi_gamecube.c */, + F3F07D59269640160074468B /* SDL_hidapi_luna.c */, + F362B93C2B33920400D30B94 /* SDL_hidapi_nintendo.h */, + F388C95428B5F6F600661ECF /* SDL_hidapi_ps3.c */, A7D8A7C323E2513E00DCD162 /* SDL_hidapi_ps4.c */, + F3A4909D2554D38500E92A8B /* SDL_hidapi_ps5.c */, A75FDBC423EA380300529352 /* SDL_hidapi_rumble.c */, A75FDBC323EA380300529352 /* SDL_hidapi_rumble.h */, + 9846B07B287A9020000C35C8 /* SDL_hidapi_shield.c */, + F3984CCF25BCC92800374F43 /* SDL_hidapi_stadia.c */, A75FDAAC23E2795C00529352 /* SDL_hidapi_steam.c */, + F362B93B2B33920400D30B94 /* SDL_hidapi_steamdeck.c */, A7D8A7C623E2513E00DCD162 /* SDL_hidapi_switch.c */, + F3D60A8228C16A1800788A3A /* SDL_hidapi_wii.c */, A7D8A7C223E2513E00DCD162 /* SDL_hidapi_xbox360.c */, A7D8A7C823E2513E00DCD162 /* SDL_hidapi_xbox360w.c */, A7D8A7C523E2513E00DCD162 /* SDL_hidapi_xboxone.c */, @@ -5324,8 +5126,8 @@ A7D8A7CC23E2513E00DCD162 /* darwin */ = { isa = PBXGroup; children = ( - A7D8A7CE23E2513E00DCD162 /* SDL_sysjoystick_c.h */, - A7D8A7CD23E2513E00DCD162 /* SDL_sysjoystick.c */, + F395C1912569C68E00942BFF /* SDL_iokitjoystick_c.h */, + F395C1922569C68E00942BFF /* SDL_iokitjoystick.c */, ); path = darwin; sourceTree = ""; @@ -5492,6 +5294,8 @@ A7D8A8D223E2514000DCD162 /* stdlib */ = { isa = PBXGroup; children = ( + F3973FA128A59BDD00B84553 /* SDL_crc16.c */, + F395BF6425633B2400942BFF /* SDL_crc32.c */, A7D8A8D423E2514000DCD162 /* SDL_getenv.c */, A7D8A8D323E2514000DCD162 /* SDL_iconv.c */, A7D8A8D923E2514000DCD162 /* SDL_malloc.c */, @@ -5499,6 +5303,7 @@ A7D8A8D823E2514000DCD162 /* SDL_stdlib.c */, A7D8A8D523E2514000DCD162 /* SDL_string.c */, A7D8A8D623E2514000DCD162 /* SDL_strtokr.c */, + F3973FA028A59BDD00B84553 /* SDL_vacopy.h */, ); path = stdlib; sourceTree = ""; @@ -5536,6 +5341,8 @@ A7D8A8EF23E2514000DCD162 /* software */ = { isa = PBXGroup; children = ( + A1626A512617008C003F1973 /* SDL_triangle.h */, + A1626A3D2617006A003F1973 /* SDL_triangle.c */, A7D8A8FD23E2514000DCD162 /* SDL_blendfillrect.c */, A7D8A8F623E2514000DCD162 /* SDL_blendfillrect.h */, A7D8A8FB23E2514000DCD162 /* SDL_blendline.c */, @@ -5639,7 +5446,6 @@ A7D8A92B23E2514000DCD162 /* SDL_mouse_c.h */, A7D8A92A23E2514000DCD162 /* SDL_mouse.c */, A7D8A93C23E2514000DCD162 /* SDL_quit.c */, - A7D8A93F23E2514000DCD162 /* SDL_sysevents.h */, A7D8A93723E2514000DCD162 /* SDL_touch_c.h */, A7D8A93E23E2514000DCD162 /* SDL_touch.c */, A7D8A94323E2514000DCD162 /* SDL_windowevents_c.h */, @@ -5648,6 +5454,22 @@ path = events; sourceTree = ""; }; + E2D187D028A5673500D2B4F1 /* SDL2 */ = { + isa = PBXGroup; + children = ( + E2D187D228A5673500D2B4F1 /* Info.plist */, + ); + path = SDL2; + sourceTree = ""; + }; + F3ADAB8C2576F08500A6B1D9 /* ios */ = { + isa = PBXGroup; + children = ( + F3ADAB8D2576F0B300A6B1D9 /* SDL_sysurl.m */, + ); + path = ios; + sourceTree = ""; + }; F59C70FC00D5CB5801000001 /* pkg-support */ = { isa = PBXGroup; children = ( @@ -5660,6 +5482,7 @@ F59C710100D5CB5801000001 /* resources */ = { isa = PBXGroup; children = ( + F37A8E1928405AA100C38E95 /* CMake */, 00794D3F09D0C461003FC8A1 /* License.txt */, F59C710300D5CB5801000001 /* ReadMe.txt */, ); @@ -5680,13 +5503,15 @@ A75FCD0223E25AB700529352 /* close_code.h in Headers */, A75FCD0323E25AB700529352 /* SDL.h in Headers */, A75FCD0423E25AB700529352 /* SDL_uikitmetalview.h in Headers */, + F362B9592B33EB7300D30B94 /* SDL_steam_virtual_gamepad.h in Headers */, A75FCD0523E25AB700529352 /* SDL_assert.h in Headers */, A75FCD0623E25AB700529352 /* SDL_shape_internals.h in Headers */, A75FCD0723E25AB700529352 /* SDL_glfuncs.h in Headers */, A75FCD0823E25AB700529352 /* SDL_atomic.h in Headers */, + F386F6F72884663E001840AA /* SDL_utils_c.h in Headers */, A75FCD0923E25AB700529352 /* SDL_rect_c.h in Headers */, - A75FCD0A23E25AB700529352 /* SDL_x11xinput2.h in Headers */, A75FCD0B23E25AB700529352 /* SDL_shaders_metal_osx.h in Headers */, + F382072E284F3643004DD584 /* SDL_guid.h in Headers */, A75FCD0C23E25AB700529352 /* SDL_shaders_metal_ios.h in Headers */, A75FCD0D23E25AB700529352 /* SDL_offscreenwindow.h in Headers */, A75FCD0E23E25AB700529352 /* SDL_audio.h in Headers */, @@ -5694,26 +5519,23 @@ A75FCD1023E25AB700529352 /* SDL_uikitview.h in Headers */, A75FCD1123E25AB700529352 /* SDL_bits.h in Headers */, A75FCD1223E25AB700529352 /* SDL_uikitappdelegate.h in Headers */, - A75FCD1323E25AB700529352 /* keyinfotable.h in Headers */, A75FCD1423E25AB700529352 /* SDL_blendmode.h in Headers */, A75FCD1523E25AB700529352 /* SDL_dropevents_c.h in Headers */, A75FCD1623E25AB700529352 /* SDL_haptic_c.h in Headers */, A75FCD1723E25AB700529352 /* SDL_clipboard.h in Headers */, A75FCD1823E25AB700529352 /* SDL_dataqueue.h in Headers */, A75FCD1923E25AB700529352 /* SDL_error_c.h in Headers */, - A75FCD1A23E25AB700529352 /* SDL_x11events.h in Headers */, A75FCD1B23E25AB700529352 /* SDL_config.h in Headers */, A75FCD1C23E25AB700529352 /* SDL_d3dmath.h in Headers */, - A75FCD1D23E25AB700529352 /* SDL_x11window.h in Headers */, A75FCD1F23E25AB700529352 /* SDL_egl_c.h in Headers */, A75FCD2023E25AB700529352 /* SDL_copying.h in Headers */, A75FCD2123E25AB700529352 /* yuv_rgb.h in Headers */, A75FCD2223E25AB700529352 /* SDL_dummyaudio.h in Headers */, + F382338C2738EB8600F7F527 /* SDL_hidapi.h in Headers */, A75FCD2323E25AB700529352 /* SDL_uikitmessagebox.h in Headers */, - A75FCD2423E25AB700529352 /* SDL_x11messagebox.h in Headers */, A75FCD2523E25AB700529352 /* SDL_thread_c.h in Headers */, A75FCD2623E25AB700529352 /* SDL_cocoamessagebox.h in Headers */, - A75FCD2723E25AB700529352 /* SDL_x11shape.h in Headers */, + F31A92D028D4CB39003BFD6A /* SDL_offscreenopengles.h in Headers */, A75FCD2823E25AB700529352 /* SDL_cpuinfo.h in Headers */, A75FCD2923E25AB700529352 /* SDL_endian.h in Headers */, A75FCD2A23E25AB700529352 /* SDL_error.h in Headers */, @@ -5722,8 +5544,8 @@ A75FCD2D23E25AB700529352 /* SDL_gamecontroller.h in Headers */, A75FCD2E23E25AB700529352 /* SDL_hidapijoystick_c.h in Headers */, A75FCD3023E25AB700529352 /* SDL_pixels_c.h in Headers */, - A75FCD3123E25AB700529352 /* SDL_x11modes.h in Headers */, A75FCD3223E25AB700529352 /* SDL_joystick_c.h in Headers */, + F395C19A2569C68F00942BFF /* SDL_iokitjoystick_c.h in Headers */, A75FCD3323E25AB700529352 /* vk_sdk_platform.h in Headers */, A75FCD3423E25AB700529352 /* blank_cursor.h in Headers */, A75FDB5F23E39E6100529352 /* hidapi.h in Headers */, @@ -5731,35 +5553,32 @@ A75FDBCC23EA380300529352 /* SDL_hidapi_rumble.h in Headers */, A75FCD3623E25AB700529352 /* SDL_sysaudio.h in Headers */, A75FCD3723E25AB700529352 /* SDL_haptic.h in Headers */, - A75FDAC523E28BD800529352 /* SDL_sysjoystick_c.h in Headers */, - A75FCD3823E25AB700529352 /* SDL_sysevents.h in Headers */, A75FCD3923E25AB700529352 /* math_libm.h in Headers */, A75FCD3A23E25AB700529352 /* SDL_uikitvideo.h in Headers */, A75FCD3B23E25AB700529352 /* SDL_cocoamouse.h in Headers */, A75FCD3C23E25AB700529352 /* SDL_hints.h in Headers */, A75FCD3D23E25AB700529352 /* SDL_blit_slow.h in Headers */, A75FCD3E23E25AB700529352 /* SDL_yuv_sw_c.h in Headers */, - A75FCD3F23E25AB700529352 /* SDL_x11opengl.h in Headers */, A75FCD4023E25AB700529352 /* SDL_windowevents_c.h in Headers */, A75FCD4123E25AB700529352 /* SDL_joystick.h in Headers */, A75FCD4223E25AB700529352 /* SDL_cocoavideo.h in Headers */, + 5605721D2473688E00B46B66 /* SDL_syslocale.h in Headers */, A75FCD4323E25AB700529352 /* SDL_keyboard.h in Headers */, A75FCD4423E25AB700529352 /* SDL_uikitevents.h in Headers */, A75FCD4523E25AB700529352 /* SDL_gesture_c.h in Headers */, + F362B9392B33916600D30B94 /* controller_list.h in Headers */, A75FCD4623E25AB700529352 /* SDL_shaders_gl.h in Headers */, A75FCD4723E25AB700529352 /* SDL_systhread_c.h in Headers */, + A1BB8B7327F6CF330057CFA8 /* SDL_list.h in Headers */, A75FCD4823E25AB700529352 /* SDL_keycode.h in Headers */, - A75FCD4923E25AB700529352 /* SDL_x11keyboard.h in Headers */, + 5616CA63252BB35F005D5928 /* SDL_sysurl.h in Headers */, A75FCD4A23E25AB700529352 /* SDL_cocoakeyboard.h in Headers */, A75FCD4B23E25AB700529352 /* SDL_uikitvulkan.h in Headers */, - A75FCD4C23E25AB700529352 /* SDL_x11framebuffer.h in Headers */, - A75FCD4D23E25AB700529352 /* SDL_x11video.h in Headers */, - A75FCD4E23E25AB700529352 /* vulkan.hpp in Headers */, A75FCD4F23E25AB700529352 /* SDL_loadso.h in Headers */, A75FCD5023E25AB700529352 /* gl2ext.h in Headers */, A75FCD5123E25AB700529352 /* SDL_clipboardevents_c.h in Headers */, - A75FCD5223E25AB700529352 /* SDL_x11touch.h in Headers */, A75FCD5323E25AB700529352 /* SDL_syshaptic_c.h in Headers */, + F316ABC22B5A02C3002EF551 /* yuv_rgb_sse.h in Headers */, A75FCD5423E25AB700529352 /* SDL_hints_c.h in Headers */, A75FCD5523E25AB700529352 /* SDL_audiodev_c.h in Headers */, A75FCD5623E25AB700529352 /* SDL_audio_c.h in Headers */, @@ -5773,6 +5592,7 @@ A75FCD5E23E25AB700529352 /* yuv_rgb_std_func.h in Headers */, A75FCD5F23E25AB700529352 /* vulkan_core.h in Headers */, A75FCD6023E25AB700529352 /* SDL_syssensor.h in Headers */, + F316ABD42B5A02C3002EF551 /* yuv_rgb_lsx_func.h in Headers */, A75FCD6123E25AB700529352 /* SDL_dynapi.h in Headers */, A75FCD6223E25AB700529352 /* SDL_assert_c.h in Headers */, A75FCD6323E25AB700529352 /* SDL_diskaudio.h in Headers */, @@ -5782,9 +5602,10 @@ A75FCD6723E25AB700529352 /* SDL_wave.h in Headers */, A75FCD6823E25AB700529352 /* SDL_cocoaopengl.h in Headers */, A75FCD6923E25AB700529352 /* yuv_rgb_sse_func.h in Headers */, - A75FCD6A23E25AB700529352 /* imKStoUCS.h in Headers */, + F316ABCB2B5A02C3002EF551 /* yuv_rgb_std.h in Headers */, A75FCD6B23E25AB700529352 /* SDL_offscreenevents_c.h in Headers */, - A75FCD6C23E25AB700529352 /* SDL_x11sym.h in Headers */, + F3973FA928A59BDD00B84553 /* SDL_vacopy.h in Headers */, + A1626A592617008D003F1973 /* SDL_triangle.h in Headers */, A75FCD6D23E25AB700529352 /* SDL_coreaudio.h in Headers */, A75FCD6E23E25AB700529352 /* SDL_draw.h in Headers */, A75FCD6F23E25AB700529352 /* SDL_drawline.h in Headers */, @@ -5795,7 +5616,6 @@ A75FCD7423E25AB700529352 /* scancodes_xfree86.h in Headers */, A75FCD7523E25AB700529352 /* SDL_syspower.h in Headers */, A75FDAFA23E35ED600529352 /* SDL_config_iphoneos.h in Headers */, - A75FCD7623E25AB700529352 /* SDL_x11clipboard.h in Headers */, A75FCD7723E25AB700529352 /* SDL_name.h in Headers */, A75FCD7823E25AB700529352 /* eglext.h in Headers */, A75FCD7923E25AB700529352 /* SDL_events_c.h in Headers */, @@ -5806,6 +5626,8 @@ A75FCD7F23E25AB700529352 /* SDL_opengles.h in Headers */, A75FCD8023E25AB700529352 /* SDL_shaders_gles2.h in Headers */, A75FCD8123E25AB700529352 /* SDL_opengles2.h in Headers */, + F316AB8C2B5A02C3002EF551 /* yuv_rgb_common.h in Headers */, + F316ABB02B5A02C3002EF551 /* yuv_rgb_lsx.h in Headers */, A75FCD8223E25AB700529352 /* SDL_glesfuncs.h in Headers */, A75FCD8323E25AB700529352 /* SDL_blendpoint.h in Headers */, A75FCD8423E25AB700529352 /* SDL_offscreenvideo.h in Headers */, @@ -5813,14 +5635,12 @@ A75FCD8623E25AB700529352 /* SDL_sysjoystick.h in Headers */, A75FCD8723E25AB700529352 /* SDL_steamcontroller.h in Headers */, A75FCD8823E25AB700529352 /* scancodes_linux.h in Headers */, - A75FCD8923E25AB700529352 /* SDL_x11dyn.h in Headers */, A75FCD8A23E25AB700529352 /* SDL_touch_c.h in Headers */, A75FCD8B23E25AB700529352 /* SDL_gamecontrollerdb.h in Headers */, A75FCD8C23E25AB700529352 /* SDL_cocoavulkan.h in Headers */, A75FCD8D23E25AB700529352 /* gl2platform.h in Headers */, A75FCD8E23E25AB700529352 /* SDL_pixels.h in Headers */, A75FCD8F23E25AB700529352 /* vk_layer.h in Headers */, - A75FCD9023E25AB700529352 /* SDL_cocoamousetap.h in Headers */, A75FCD9123E25AB700529352 /* vk_platform.h in Headers */, A75FCD9223E25AB700529352 /* SDL_cocoametalview.h in Headers */, A75FCD9323E25AB700529352 /* SDL_cocoaopengles.h in Headers */, @@ -5831,15 +5651,12 @@ A75FCD9823E25AB700529352 /* SDL_rotate.h in Headers */, A75FCD9923E25AB700529352 /* SDL_platform.h in Headers */, A75FCD9A23E25AB700529352 /* SDL_power.h in Headers */, - A75FCD9B23E25AB700529352 /* SDL_offscreenopengl.h in Headers */, A75FCD9D23E25AB700529352 /* scancodes_darwin.h in Headers */, A75FCD9E23E25AB700529352 /* controller_type.h in Headers */, - A75FCD9F23E25AB700529352 /* SDL_x11opengles.h in Headers */, A75FCDA023E25AB700529352 /* SDL_uikitclipboard.h in Headers */, A75FCDA123E25AB700529352 /* vulkan_xlib.h in Headers */, A75FCDA223E25AB700529352 /* SDL_uikitwindow.h in Headers */, A75FCDA323E25AB700529352 /* vulkan_vi.h in Headers */, - A75FCDA423E25AB700529352 /* vulkan_mir.h in Headers */, A75FCDA523E25AB700529352 /* SDL_quit.h in Headers */, A75FCDA623E25AB700529352 /* default_cursor.h in Headers */, A75FCDA723E25AB700529352 /* SDL_render_sw_c.h in Headers */, @@ -5847,9 +5664,9 @@ A75FCDA923E25AB700529352 /* SDL_render.h in Headers */, A75FCDAA23E25AB700529352 /* SDL_nullvideo.h in Headers */, A75FCDAB23E25AB700529352 /* SDL_blit_copy.h in Headers */, + 75E0916A241EA924004729E1 /* SDL_virtualjoystick_c.h in Headers */, A75FCDAC23E25AB700529352 /* SDL_RLEaccel_c.h in Headers */, A75FCDAD23E25AB700529352 /* eglplatform.h in Headers */, - A75FCDAE23E25AB700529352 /* edid.h in Headers */, A75FCDAF23E25AB700529352 /* SDL_revision.h in Headers */, A75FCDB023E25AB700529352 /* SDL_systhread.h in Headers */, A75FCDB123E25AB700529352 /* SDL_rwops.h in Headers */, @@ -5879,6 +5696,7 @@ A75FCDCA23E25AB700529352 /* SDL_syswm.h in Headers */, A75FCDCB23E25AB700529352 /* SDL_opengl_glext.h in Headers */, A75FCDCC23E25AB700529352 /* SDL_mouse_c.h in Headers */, + F395C1C12569C6A000942BFF /* SDL_mfijoystick_c.h in Headers */, A75FCDCD23E25AB700529352 /* SDL_blit_auto.h in Headers */, A75FCDCE23E25AB700529352 /* SDL_blendline.h in Headers */, A75FCDCF23E25AB700529352 /* SDL_syshaptic.h in Headers */, @@ -5894,18 +5712,18 @@ A75FCDD923E25AB700529352 /* SDL_types.h in Headers */, A75FCDDA23E25AB700529352 /* usb_ids.h in Headers */, A75FCDDB23E25AB700529352 /* SDL_gles2funcs.h in Headers */, - A75FCDDC23E25AB700529352 /* SDL_sysjoystick_c.h in Headers */, A75FCDDD23E25AB700529352 /* SDL_version.h in Headers */, A75FCDDE23E25AB700529352 /* SDL_video.h in Headers */, A75FCDDF23E25AB700529352 /* SDL_opengles2_gl2.h in Headers */, A75FCDE023E25AB700529352 /* SDL_sensor.h in Headers */, + F362B94D2B33920500D30B94 /* SDL_hidapi_nintendo.h in Headers */, A75FCDE123E25AB700529352 /* SDL_sysvideo.h in Headers */, + F386F6EE2884663E001840AA /* SDL_log_c.h in Headers */, A75FCDE223E25AB700529352 /* SDL_opengles2_gl2platform.h in Headers */, A75FCDE323E25AB700529352 /* SDL_opengles2_gl2ext.h in Headers */, - A75FCDE423E25AB700529352 /* SDL_x11mouse.h in Headers */, A75FCDE523E25AB700529352 /* SDL_dynapi_overrides.h in Headers */, + F316AB952B5A02C3002EF551 /* yuv_rgb_internal.h in Headers */, A75FCDE623E25AB700529352 /* SDL_cocoawindow.h in Headers */, - A75FCDE723E25AB700529352 /* SDL_x11vulkan.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -5920,40 +5738,39 @@ A75FCEBB23E25AC700529352 /* close_code.h in Headers */, A75FCEBC23E25AC700529352 /* SDL.h in Headers */, A75FCEBD23E25AC700529352 /* SDL_uikitmetalview.h in Headers */, + F362B95A2B33EB7300D30B94 /* SDL_steam_virtual_gamepad.h in Headers */, A75FCEBE23E25AC700529352 /* SDL_assert.h in Headers */, A75FCEBF23E25AC700529352 /* SDL_shape_internals.h in Headers */, A75FCEC023E25AC700529352 /* SDL_glfuncs.h in Headers */, A75FCEC123E25AC700529352 /* SDL_atomic.h in Headers */, + F386F6F82884663E001840AA /* SDL_utils_c.h in Headers */, A75FCEC223E25AC700529352 /* SDL_rect_c.h in Headers */, - A75FCEC323E25AC700529352 /* SDL_x11xinput2.h in Headers */, A75FCEC423E25AC700529352 /* SDL_shaders_metal_osx.h in Headers */, A75FCEC523E25AC700529352 /* SDL_shaders_metal_ios.h in Headers */, A75FCEC623E25AC700529352 /* SDL_offscreenwindow.h in Headers */, A75FCEC723E25AC700529352 /* SDL_audio.h in Headers */, + F382072F284F3643004DD584 /* SDL_guid.h in Headers */, A75FCEC823E25AC700529352 /* SDL_coremotionsensor.h in Headers */, A75FCEC923E25AC700529352 /* SDL_uikitview.h in Headers */, A75FCECA23E25AC700529352 /* SDL_bits.h in Headers */, A75FCECB23E25AC700529352 /* SDL_uikitappdelegate.h in Headers */, - A75FCECC23E25AC700529352 /* keyinfotable.h in Headers */, A75FCECD23E25AC700529352 /* SDL_blendmode.h in Headers */, A75FCECE23E25AC700529352 /* SDL_dropevents_c.h in Headers */, A75FCECF23E25AC700529352 /* SDL_haptic_c.h in Headers */, A75FCED023E25AC700529352 /* SDL_clipboard.h in Headers */, A75FCED123E25AC700529352 /* SDL_dataqueue.h in Headers */, A75FCED223E25AC700529352 /* SDL_error_c.h in Headers */, - A75FCED323E25AC700529352 /* SDL_x11events.h in Headers */, A75FCED423E25AC700529352 /* SDL_config.h in Headers */, A75FCED523E25AC700529352 /* SDL_d3dmath.h in Headers */, - A75FCED623E25AC700529352 /* SDL_x11window.h in Headers */, A75FCED823E25AC700529352 /* SDL_egl_c.h in Headers */, A75FCED923E25AC700529352 /* SDL_copying.h in Headers */, A75FCEDA23E25AC700529352 /* yuv_rgb.h in Headers */, A75FCEDB23E25AC700529352 /* SDL_dummyaudio.h in Headers */, + F382338D2738EB8600F7F527 /* SDL_hidapi.h in Headers */, A75FCEDC23E25AC700529352 /* SDL_uikitmessagebox.h in Headers */, - A75FCEDD23E25AC700529352 /* SDL_x11messagebox.h in Headers */, A75FCEDE23E25AC700529352 /* SDL_thread_c.h in Headers */, A75FCEDF23E25AC700529352 /* SDL_cocoamessagebox.h in Headers */, - A75FCEE023E25AC700529352 /* SDL_x11shape.h in Headers */, + F31A92D128D4CB39003BFD6A /* SDL_offscreenopengles.h in Headers */, A75FCEE123E25AC700529352 /* SDL_cpuinfo.h in Headers */, A75FCEE223E25AC700529352 /* SDL_endian.h in Headers */, A75FCEE323E25AC700529352 /* SDL_error.h in Headers */, @@ -5962,8 +5779,8 @@ A75FCEE623E25AC700529352 /* SDL_gamecontroller.h in Headers */, A75FCEE723E25AC700529352 /* SDL_hidapijoystick_c.h in Headers */, A75FCEE923E25AC700529352 /* SDL_pixels_c.h in Headers */, - A75FCEEA23E25AC700529352 /* SDL_x11modes.h in Headers */, A75FCEEB23E25AC700529352 /* SDL_joystick_c.h in Headers */, + F395C19B2569C68F00942BFF /* SDL_iokitjoystick_c.h in Headers */, A75FCEEC23E25AC700529352 /* vk_sdk_platform.h in Headers */, A75FCEED23E25AC700529352 /* blank_cursor.h in Headers */, A75FDB6023E39E6100529352 /* hidapi.h in Headers */, @@ -5971,35 +5788,32 @@ A75FDBCD23EA380300529352 /* SDL_hidapi_rumble.h in Headers */, A75FCEEF23E25AC700529352 /* SDL_sysaudio.h in Headers */, A75FCEF023E25AC700529352 /* SDL_haptic.h in Headers */, - A75FDAC723E28BD900529352 /* SDL_sysjoystick_c.h in Headers */, - A75FCEF123E25AC700529352 /* SDL_sysevents.h in Headers */, A75FCEF223E25AC700529352 /* math_libm.h in Headers */, A75FCEF323E25AC700529352 /* SDL_uikitvideo.h in Headers */, A75FCEF423E25AC700529352 /* SDL_cocoamouse.h in Headers */, A75FCEF523E25AC700529352 /* SDL_hints.h in Headers */, A75FCEF623E25AC700529352 /* SDL_blit_slow.h in Headers */, A75FCEF723E25AC700529352 /* SDL_yuv_sw_c.h in Headers */, - A75FCEF823E25AC700529352 /* SDL_x11opengl.h in Headers */, A75FCEF923E25AC700529352 /* SDL_windowevents_c.h in Headers */, A75FCEFA23E25AC700529352 /* SDL_joystick.h in Headers */, A75FCEFB23E25AC700529352 /* SDL_cocoavideo.h in Headers */, + 5605721E2473688F00B46B66 /* SDL_syslocale.h in Headers */, A75FCEFC23E25AC700529352 /* SDL_keyboard.h in Headers */, A75FCEFD23E25AC700529352 /* SDL_uikitevents.h in Headers */, A75FCEFE23E25AC700529352 /* SDL_gesture_c.h in Headers */, + F362B93A2B33916600D30B94 /* controller_list.h in Headers */, A75FCEFF23E25AC700529352 /* SDL_shaders_gl.h in Headers */, A75FCF0023E25AC700529352 /* SDL_systhread_c.h in Headers */, + A1BB8B7427F6CF330057CFA8 /* SDL_list.h in Headers */, A75FCF0123E25AC700529352 /* SDL_keycode.h in Headers */, - A75FCF0223E25AC700529352 /* SDL_x11keyboard.h in Headers */, + 5616CA66252BB361005D5928 /* SDL_sysurl.h in Headers */, A75FCF0323E25AC700529352 /* SDL_cocoakeyboard.h in Headers */, A75FCF0423E25AC700529352 /* SDL_uikitvulkan.h in Headers */, - A75FCF0523E25AC700529352 /* SDL_x11framebuffer.h in Headers */, - A75FCF0623E25AC700529352 /* SDL_x11video.h in Headers */, - A75FCF0723E25AC700529352 /* vulkan.hpp in Headers */, A75FCF0823E25AC700529352 /* SDL_loadso.h in Headers */, A75FCF0923E25AC700529352 /* gl2ext.h in Headers */, A75FCF0A23E25AC700529352 /* SDL_clipboardevents_c.h in Headers */, - A75FCF0B23E25AC700529352 /* SDL_x11touch.h in Headers */, A75FCF0C23E25AC700529352 /* SDL_syshaptic_c.h in Headers */, + F316ABC32B5A02C3002EF551 /* yuv_rgb_sse.h in Headers */, A75FCF0D23E25AC700529352 /* SDL_hints_c.h in Headers */, A75FCF0E23E25AC700529352 /* SDL_audiodev_c.h in Headers */, A75FCF0F23E25AC700529352 /* SDL_audio_c.h in Headers */, @@ -6013,6 +5827,7 @@ A75FCF1723E25AC700529352 /* yuv_rgb_std_func.h in Headers */, A75FCF1823E25AC700529352 /* vulkan_core.h in Headers */, A75FCF1923E25AC700529352 /* SDL_syssensor.h in Headers */, + F316ABD52B5A02C3002EF551 /* yuv_rgb_lsx_func.h in Headers */, A75FCF1A23E25AC700529352 /* SDL_dynapi.h in Headers */, A75FCF1B23E25AC700529352 /* SDL_assert_c.h in Headers */, A75FCF1C23E25AC700529352 /* SDL_diskaudio.h in Headers */, @@ -6022,9 +5837,10 @@ A75FCF2023E25AC700529352 /* SDL_wave.h in Headers */, A75FCF2123E25AC700529352 /* SDL_cocoaopengl.h in Headers */, A75FCF2223E25AC700529352 /* yuv_rgb_sse_func.h in Headers */, - A75FCF2323E25AC700529352 /* imKStoUCS.h in Headers */, + F316ABCC2B5A02C3002EF551 /* yuv_rgb_std.h in Headers */, A75FCF2423E25AC700529352 /* SDL_offscreenevents_c.h in Headers */, - A75FCF2523E25AC700529352 /* SDL_x11sym.h in Headers */, + F3973FAA28A59BDD00B84553 /* SDL_vacopy.h in Headers */, + A1626A5A2617008D003F1973 /* SDL_triangle.h in Headers */, A75FCF2623E25AC700529352 /* SDL_coreaudio.h in Headers */, A75FCF2723E25AC700529352 /* SDL_draw.h in Headers */, A75FCF2823E25AC700529352 /* SDL_drawline.h in Headers */, @@ -6035,7 +5851,6 @@ A75FCF2D23E25AC700529352 /* scancodes_xfree86.h in Headers */, A75FCF2E23E25AC700529352 /* SDL_syspower.h in Headers */, A75FDAFB23E35ED700529352 /* SDL_config_iphoneos.h in Headers */, - A75FCF2F23E25AC700529352 /* SDL_x11clipboard.h in Headers */, A75FCF3023E25AC700529352 /* SDL_name.h in Headers */, A75FCF3123E25AC700529352 /* eglext.h in Headers */, A75FCF3223E25AC700529352 /* SDL_events_c.h in Headers */, @@ -6046,6 +5861,8 @@ A75FCF3823E25AC700529352 /* SDL_opengles.h in Headers */, A75FCF3923E25AC700529352 /* SDL_shaders_gles2.h in Headers */, A75FCF3A23E25AC700529352 /* SDL_opengles2.h in Headers */, + F316AB8D2B5A02C3002EF551 /* yuv_rgb_common.h in Headers */, + F316ABB12B5A02C3002EF551 /* yuv_rgb_lsx.h in Headers */, A75FCF3B23E25AC700529352 /* SDL_glesfuncs.h in Headers */, A75FCF3C23E25AC700529352 /* SDL_blendpoint.h in Headers */, A75FCF3D23E25AC700529352 /* SDL_offscreenvideo.h in Headers */, @@ -6053,14 +5870,12 @@ A75FCF3F23E25AC700529352 /* SDL_sysjoystick.h in Headers */, A75FCF4023E25AC700529352 /* SDL_steamcontroller.h in Headers */, A75FCF4123E25AC700529352 /* scancodes_linux.h in Headers */, - A75FCF4223E25AC700529352 /* SDL_x11dyn.h in Headers */, A75FCF4323E25AC700529352 /* SDL_touch_c.h in Headers */, A75FCF4423E25AC700529352 /* SDL_gamecontrollerdb.h in Headers */, A75FCF4523E25AC700529352 /* SDL_cocoavulkan.h in Headers */, A75FCF4623E25AC700529352 /* gl2platform.h in Headers */, A75FCF4723E25AC700529352 /* SDL_pixels.h in Headers */, A75FCF4823E25AC700529352 /* vk_layer.h in Headers */, - A75FCF4923E25AC700529352 /* SDL_cocoamousetap.h in Headers */, A75FCF4A23E25AC700529352 /* vk_platform.h in Headers */, A75FCF4B23E25AC700529352 /* SDL_cocoametalview.h in Headers */, A75FCF4C23E25AC700529352 /* SDL_cocoaopengles.h in Headers */, @@ -6071,15 +5886,12 @@ A75FCF5123E25AC700529352 /* SDL_rotate.h in Headers */, A75FCF5223E25AC700529352 /* SDL_platform.h in Headers */, A75FCF5323E25AC700529352 /* SDL_power.h in Headers */, - A75FCF5423E25AC700529352 /* SDL_offscreenopengl.h in Headers */, A75FCF5623E25AC700529352 /* scancodes_darwin.h in Headers */, A75FCF5723E25AC700529352 /* controller_type.h in Headers */, - A75FCF5823E25AC700529352 /* SDL_x11opengles.h in Headers */, A75FCF5923E25AC700529352 /* SDL_uikitclipboard.h in Headers */, A75FCF5A23E25AC700529352 /* vulkan_xlib.h in Headers */, A75FCF5B23E25AC700529352 /* SDL_uikitwindow.h in Headers */, A75FCF5C23E25AC700529352 /* vulkan_vi.h in Headers */, - A75FCF5D23E25AC700529352 /* vulkan_mir.h in Headers */, A75FCF5E23E25AC700529352 /* SDL_quit.h in Headers */, A75FCF5F23E25AC700529352 /* default_cursor.h in Headers */, A75FCF6023E25AC700529352 /* SDL_render_sw_c.h in Headers */, @@ -6087,9 +5899,9 @@ A75FCF6223E25AC700529352 /* SDL_render.h in Headers */, A75FCF6323E25AC700529352 /* SDL_nullvideo.h in Headers */, A75FCF6423E25AC700529352 /* SDL_blit_copy.h in Headers */, + 75E0916B241EA924004729E1 /* SDL_virtualjoystick_c.h in Headers */, A75FCF6523E25AC700529352 /* SDL_RLEaccel_c.h in Headers */, A75FCF6623E25AC700529352 /* eglplatform.h in Headers */, - A75FCF6723E25AC700529352 /* edid.h in Headers */, A75FCF6823E25AC700529352 /* SDL_revision.h in Headers */, A75FCF6923E25AC700529352 /* SDL_systhread.h in Headers */, A75FCF6A23E25AC700529352 /* SDL_rwops.h in Headers */, @@ -6119,6 +5931,7 @@ A75FCF8323E25AC700529352 /* SDL_syswm.h in Headers */, A75FCF8423E25AC700529352 /* SDL_opengl_glext.h in Headers */, A75FCF8523E25AC700529352 /* SDL_mouse_c.h in Headers */, + F395C1C22569C6A000942BFF /* SDL_mfijoystick_c.h in Headers */, A75FCF8623E25AC700529352 /* SDL_blit_auto.h in Headers */, A75FCF8723E25AC700529352 /* SDL_blendline.h in Headers */, A75FCF8823E25AC700529352 /* SDL_syshaptic.h in Headers */, @@ -6134,42 +5947,18 @@ A75FCF9223E25AC700529352 /* SDL_types.h in Headers */, A75FCF9323E25AC700529352 /* usb_ids.h in Headers */, A75FCF9423E25AC700529352 /* SDL_gles2funcs.h in Headers */, - A75FCF9523E25AC700529352 /* SDL_sysjoystick_c.h in Headers */, A75FCF9623E25AC700529352 /* SDL_version.h in Headers */, A75FCF9723E25AC700529352 /* SDL_video.h in Headers */, A75FCF9823E25AC700529352 /* SDL_opengles2_gl2.h in Headers */, A75FCF9923E25AC700529352 /* SDL_sensor.h in Headers */, + F362B94E2B33920500D30B94 /* SDL_hidapi_nintendo.h in Headers */, A75FCF9A23E25AC700529352 /* SDL_sysvideo.h in Headers */, + F386F6EF2884663E001840AA /* SDL_log_c.h in Headers */, A75FCF9B23E25AC700529352 /* SDL_opengles2_gl2platform.h in Headers */, A75FCF9C23E25AC700529352 /* SDL_opengles2_gl2ext.h in Headers */, - A75FCF9D23E25AC700529352 /* SDL_x11mouse.h in Headers */, A75FCF9E23E25AC700529352 /* SDL_dynapi_overrides.h in Headers */, + F316AB962B5A02C3002EF551 /* yuv_rgb_internal.h in Headers */, A75FCF9F23E25AC700529352 /* SDL_cocoawindow.h in Headers */, - A75FCFA023E25AC700529352 /* SDL_x11vulkan.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - A75FDB4423E399AC00529352 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - A75FDB6123E39E6100529352 /* hidapi.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - A75FDB6323E3A2C900529352 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - A75FDB6423E3A2C900529352 /* hidapi.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - A75FDB8123E4C74400529352 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - A75FDB8223E4C74400529352 /* hidapi.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -6178,90 +5967,58 @@ buildActionMask = 2147483647; files = ( A769B08423E259AE00872273 /* SDL_shaders_metal_tvos.h in Headers */, - A769B08523E259AE00872273 /* SDL_filesystem.h in Headers */, - A769B08723E259AE00872273 /* begin_code.h in Headers */, A769B08823E259AE00872273 /* SDL_uikitopengles.h in Headers */, - A769B08923E259AE00872273 /* close_code.h in Headers */, - A769B08A23E259AE00872273 /* SDL.h in Headers */, A769B08B23E259AE00872273 /* SDL_uikitmetalview.h in Headers */, - A769B08C23E259AE00872273 /* SDL_assert.h in Headers */, A769B08D23E259AE00872273 /* SDL_shape_internals.h in Headers */, A769B08E23E259AE00872273 /* SDL_glfuncs.h in Headers */, - A769B08F23E259AE00872273 /* SDL_atomic.h in Headers */, A769B09023E259AE00872273 /* SDL_rect_c.h in Headers */, - A769B09123E259AE00872273 /* SDL_x11xinput2.h in Headers */, A769B09223E259AE00872273 /* SDL_shaders_metal_osx.h in Headers */, A769B09323E259AE00872273 /* SDL_shaders_metal_ios.h in Headers */, A769B09423E259AE00872273 /* SDL_offscreenwindow.h in Headers */, - A769B09523E259AE00872273 /* SDL_audio.h in Headers */, A769B09623E259AE00872273 /* SDL_coremotionsensor.h in Headers */, A769B09723E259AE00872273 /* SDL_uikitview.h in Headers */, - A769B09823E259AE00872273 /* SDL_bits.h in Headers */, A769B09923E259AE00872273 /* SDL_uikitappdelegate.h in Headers */, - A769B09A23E259AE00872273 /* keyinfotable.h in Headers */, - A769B09B23E259AE00872273 /* SDL_blendmode.h in Headers */, A769B09C23E259AE00872273 /* SDL_dropevents_c.h in Headers */, A769B09D23E259AE00872273 /* SDL_haptic_c.h in Headers */, - A769B09E23E259AE00872273 /* SDL_clipboard.h in Headers */, A769B09F23E259AE00872273 /* SDL_dataqueue.h in Headers */, A769B0A023E259AE00872273 /* SDL_error_c.h in Headers */, - A769B0A123E259AE00872273 /* SDL_x11events.h in Headers */, - A769B0A223E259AE00872273 /* SDL_config.h in Headers */, A769B0A323E259AE00872273 /* SDL_d3dmath.h in Headers */, - A769B0A423E259AE00872273 /* SDL_x11window.h in Headers */, A769B0A623E259AE00872273 /* SDL_egl_c.h in Headers */, - A769B0A723E259AE00872273 /* SDL_copying.h in Headers */, A769B0A823E259AE00872273 /* yuv_rgb.h in Headers */, A769B0A923E259AE00872273 /* SDL_dummyaudio.h in Headers */, A769B0AA23E259AE00872273 /* SDL_uikitmessagebox.h in Headers */, - A769B0AB23E259AE00872273 /* SDL_x11messagebox.h in Headers */, A769B0AC23E259AE00872273 /* SDL_thread_c.h in Headers */, A769B0AD23E259AE00872273 /* SDL_cocoamessagebox.h in Headers */, - A769B0AE23E259AE00872273 /* SDL_x11shape.h in Headers */, - A769B0AF23E259AE00872273 /* SDL_cpuinfo.h in Headers */, - A769B0B023E259AE00872273 /* SDL_endian.h in Headers */, - A769B0B123E259AE00872273 /* SDL_error.h in Headers */, - A769B0B223E259AE00872273 /* SDL_events.h in Headers */, A769B0B323E259AE00872273 /* SDL_blendfillrect.h in Headers */, - A769B0B423E259AE00872273 /* SDL_gamecontroller.h in Headers */, A769B0B523E259AE00872273 /* SDL_hidapijoystick_c.h in Headers */, A769B0B623E259AE00872273 /* SDL_pixels_c.h in Headers */, - A769B0B723E259AE00872273 /* SDL_x11modes.h in Headers */, A769B0B823E259AE00872273 /* SDL_joystick_c.h in Headers */, + F395C1982569C68F00942BFF /* SDL_iokitjoystick_c.h in Headers */, A769B0B923E259AE00872273 /* vk_sdk_platform.h in Headers */, A769B0BA23E259AE00872273 /* blank_cursor.h in Headers */, A75FDB5D23E39E6100529352 /* hidapi.h in Headers */, - A769B0BB23E259AE00872273 /* SDL_gesture.h in Headers */, A75FDBCA23EA380300529352 /* SDL_hidapi_rumble.h in Headers */, A769B0BC23E259AE00872273 /* SDL_sysaudio.h in Headers */, - A769B0BD23E259AE00872273 /* SDL_haptic.h in Headers */, - A769B0BE23E259AE00872273 /* SDL_sysevents.h in Headers */, A769B0BF23E259AE00872273 /* math_libm.h in Headers */, A769B0C023E259AE00872273 /* SDL_uikitvideo.h in Headers */, + F316ABC02B5A02C3002EF551 /* yuv_rgb_sse.h in Headers */, A769B0C123E259AE00872273 /* SDL_cocoamouse.h in Headers */, - A769B0C223E259AE00872273 /* SDL_hints.h in Headers */, A769B0C323E259AE00872273 /* SDL_blit_slow.h in Headers */, + F3973FA728A59BDD00B84553 /* SDL_vacopy.h in Headers */, A769B0C423E259AE00872273 /* SDL_yuv_sw_c.h in Headers */, - A769B0C523E259AE00872273 /* SDL_x11opengl.h in Headers */, A769B0C623E259AE00872273 /* SDL_windowevents_c.h in Headers */, - A769B0C723E259AE00872273 /* SDL_joystick.h in Headers */, A769B0C823E259AE00872273 /* SDL_cocoavideo.h in Headers */, - A769B0C923E259AE00872273 /* SDL_keyboard.h in Headers */, + 5605721C2473688D00B46B66 /* SDL_syslocale.h in Headers */, + A1BB8B7127F6CF330057CFA8 /* SDL_list.h in Headers */, A769B0CA23E259AE00872273 /* SDL_uikitevents.h in Headers */, A769B0CB23E259AE00872273 /* SDL_gesture_c.h in Headers */, A769B0CC23E259AE00872273 /* SDL_shaders_gl.h in Headers */, A769B0CD23E259AE00872273 /* SDL_systhread_c.h in Headers */, - A769B0CE23E259AE00872273 /* SDL_keycode.h in Headers */, - A769B0CF23E259AE00872273 /* SDL_x11keyboard.h in Headers */, A769B0D023E259AE00872273 /* SDL_cocoakeyboard.h in Headers */, + 5616CA5D252BB35E005D5928 /* SDL_sysurl.h in Headers */, A769B0D123E259AE00872273 /* SDL_uikitvulkan.h in Headers */, - A769B0D223E259AE00872273 /* SDL_x11framebuffer.h in Headers */, - A769B0D323E259AE00872273 /* SDL_x11video.h in Headers */, - A769B0D423E259AE00872273 /* vulkan.hpp in Headers */, - A769B0D523E259AE00872273 /* SDL_loadso.h in Headers */, A769B0D623E259AE00872273 /* gl2ext.h in Headers */, A769B0D723E259AE00872273 /* SDL_clipboardevents_c.h in Headers */, - A769B0D823E259AE00872273 /* SDL_x11touch.h in Headers */, A769B0D923E259AE00872273 /* SDL_syshaptic_c.h in Headers */, A769B0DA23E259AE00872273 /* SDL_hints_c.h in Headers */, A769B0DB23E259AE00872273 /* SDL_audiodev_c.h in Headers */, @@ -6269,61 +6026,51 @@ A769B0DD23E259AE00872273 /* SDL_uikitmodes.h in Headers */, A769B0DE23E259AE00872273 /* egl.h in Headers */, A769B0DF23E259AE00872273 /* khrplatform.h in Headers */, - A769B0E023E259AE00872273 /* SDL_log.h in Headers */, A769B0E123E259AE00872273 /* SDL_uikitviewcontroller.h in Headers */, A769B0E223E259AE00872273 /* SDL_dummysensor.h in Headers */, A769B0E423E259AE00872273 /* SDL_steamcontroller.h in Headers */, A769B0E523E259AE00872273 /* vulkan_android.h in Headers */, A769B0E623E259AE00872273 /* yuv_rgb_std_func.h in Headers */, A769B0E723E259AE00872273 /* vulkan_core.h in Headers */, + F362B9572B33EB7300D30B94 /* SDL_steam_virtual_gamepad.h in Headers */, A769B0E823E259AE00872273 /* SDL_syssensor.h in Headers */, + F316AB8A2B5A02C3002EF551 /* yuv_rgb_common.h in Headers */, A769B0E923E259AE00872273 /* SDL_dynapi.h in Headers */, A769B0EA23E259AE00872273 /* SDL_assert_c.h in Headers */, A769B0EB23E259AE00872273 /* SDL_diskaudio.h in Headers */, - A769B0EC23E259AE00872273 /* SDL_main.h in Headers */, A769B0ED23E259AE00872273 /* SDL_drawpoint.h in Headers */, - A769B0EE23E259AE00872273 /* SDL_opengles2_khrplatform.h in Headers */, A769B0EF23E259AE00872273 /* SDL_wave.h in Headers */, A769B0F023E259AE00872273 /* SDL_cocoaopengl.h in Headers */, + F316ABC92B5A02C3002EF551 /* yuv_rgb_std.h in Headers */, + A1626A572617008D003F1973 /* SDL_triangle.h in Headers */, A769B0F123E259AE00872273 /* yuv_rgb_sse_func.h in Headers */, - A769B0F223E259AE00872273 /* imKStoUCS.h in Headers */, A769B0F323E259AE00872273 /* SDL_offscreenevents_c.h in Headers */, - A769B0F423E259AE00872273 /* SDL_x11sym.h in Headers */, A769B0F523E259AE00872273 /* SDL_coreaudio.h in Headers */, A769B0F623E259AE00872273 /* SDL_draw.h in Headers */, A769B0F723E259AE00872273 /* SDL_drawline.h in Headers */, - A769B0F823E259AE00872273 /* SDL_messagebox.h in Headers */, - A769B0F923E259AE00872273 /* SDL_mouse.h in Headers */, - A769B0FA23E259AE00872273 /* SDL_mutex.h in Headers */, A769B0FB23E259AE00872273 /* SDL_yuv_c.h in Headers */, A769B0FC23E259AE00872273 /* scancodes_xfree86.h in Headers */, A769B0FD23E259AE00872273 /* SDL_syspower.h in Headers */, A75FDAF923E35ED500529352 /* SDL_config_iphoneos.h in Headers */, - A769B0FE23E259AE00872273 /* SDL_x11clipboard.h in Headers */, - A769B0FF23E259AE00872273 /* SDL_name.h in Headers */, A769B10023E259AE00872273 /* eglext.h in Headers */, A769B10123E259AE00872273 /* SDL_events_c.h in Headers */, A769B10223E259AE00872273 /* math_private.h in Headers */, A769B10323E259AE00872273 /* vulkan_wayland.h in Headers */, - A769B10423E259AE00872273 /* SDL_opengl.h in Headers */, A769B10523E259AE00872273 /* SDL_cocoashape.h in Headers */, - A769B10623E259AE00872273 /* SDL_opengles.h in Headers */, A769B10723E259AE00872273 /* SDL_shaders_gles2.h in Headers */, - A769B10823E259AE00872273 /* SDL_opengles2.h in Headers */, A769B10923E259AE00872273 /* SDL_glesfuncs.h in Headers */, A769B10A23E259AE00872273 /* SDL_blendpoint.h in Headers */, A769B10B23E259AE00872273 /* SDL_offscreenvideo.h in Headers */, A769B10C23E259AE00872273 /* SDL_nullevents_c.h in Headers */, + F316ABD22B5A02C3002EF551 /* yuv_rgb_lsx_func.h in Headers */, A769B10D23E259AE00872273 /* SDL_sysjoystick.h in Headers */, A769B10E23E259AE00872273 /* scancodes_linux.h in Headers */, - A769B10F23E259AE00872273 /* SDL_x11dyn.h in Headers */, A769B11023E259AE00872273 /* SDL_touch_c.h in Headers */, + F362B94B2B33920500D30B94 /* SDL_hidapi_nintendo.h in Headers */, A769B11123E259AE00872273 /* SDL_gamecontrollerdb.h in Headers */, A769B11223E259AE00872273 /* SDL_cocoavulkan.h in Headers */, A769B11323E259AE00872273 /* gl2platform.h in Headers */, - A769B11423E259AE00872273 /* SDL_pixels.h in Headers */, A769B11523E259AE00872273 /* vk_layer.h in Headers */, - A769B11723E259AE00872273 /* SDL_cocoamousetap.h in Headers */, A769B11823E259AE00872273 /* vk_platform.h in Headers */, A769B11A23E259AE00872273 /* SDL_cocoametalview.h in Headers */, A769B11B23E259AE00872273 /* SDL_cocoaopengles.h in Headers */, @@ -6331,36 +6078,28 @@ A769B11D23E259AE00872273 /* vulkan_xlib_xrandr.h in Headers */, A769B11E23E259AE00872273 /* SDL_sensor_c.h in Headers */, A769B11F23E259AE00872273 /* SDL_sysrender.h in Headers */, + F316AB932B5A02C3002EF551 /* yuv_rgb_internal.h in Headers */, A769B12023E259AE00872273 /* SDL_rotate.h in Headers */, - A769B12123E259AE00872273 /* SDL_platform.h in Headers */, - A769B12223E259AE00872273 /* SDL_power.h in Headers */, - A769B12323E259AE00872273 /* SDL_offscreenopengl.h in Headers */, A769B12523E259AE00872273 /* scancodes_darwin.h in Headers */, A769B12623E259AE00872273 /* controller_type.h in Headers */, - A769B12723E259AE00872273 /* SDL_x11opengles.h in Headers */, A769B12823E259AE00872273 /* SDL_uikitclipboard.h in Headers */, A769B12923E259AE00872273 /* vulkan_xlib.h in Headers */, + F386F6F52884663E001840AA /* SDL_utils_c.h in Headers */, A769B12A23E259AE00872273 /* SDL_uikitwindow.h in Headers */, A769B12B23E259AE00872273 /* vulkan_vi.h in Headers */, - A769B12C23E259AE00872273 /* vulkan_mir.h in Headers */, - A769B12D23E259AE00872273 /* SDL_quit.h in Headers */, A769B12E23E259AE00872273 /* default_cursor.h in Headers */, A769B12F23E259AE00872273 /* SDL_render_sw_c.h in Headers */, - A769B13023E259AE00872273 /* SDL_rect.h in Headers */, - A769B13123E259AE00872273 /* SDL_render.h in Headers */, A769B13223E259AE00872273 /* SDL_nullvideo.h in Headers */, A769B13323E259AE00872273 /* SDL_blit_copy.h in Headers */, A769B13423E259AE00872273 /* SDL_RLEaccel_c.h in Headers */, + 75E09168241EA924004729E1 /* SDL_virtualjoystick_c.h in Headers */, A769B13523E259AE00872273 /* eglplatform.h in Headers */, - A769B13623E259AE00872273 /* edid.h in Headers */, - A769B13723E259AE00872273 /* SDL_revision.h in Headers */, A769B13823E259AE00872273 /* SDL_systhread.h in Headers */, - A769B13923E259AE00872273 /* SDL_rwops.h in Headers */, - A769B13A23E259AE00872273 /* SDL_scancode.h in Headers */, A769B13B23E259AE00872273 /* SDL_cocoaclipboard.h in Headers */, A769B13C23E259AE00872273 /* SDL_cocoamodes.h in Headers */, A769B13D23E259AE00872273 /* SDL_uikitopenglview.h in Headers */, A769B13E23E259AE00872273 /* vulkan_win32.h in Headers */, + F31A92CE28D4CB39003BFD6A /* SDL_offscreenopengles.h in Headers */, A769B13F23E259AE00872273 /* SDL_offscreenframebuffer_c.h in Headers */, A769B14023E259AE00872273 /* SDL_displayevents_c.h in Headers */, A769B14123E259AE00872273 /* SDL_timer_c.h in Headers */, @@ -6368,48 +6107,33 @@ A769B14323E259AE00872273 /* SDL_sysmutex_c.h in Headers */, A769B14423E259AE00872273 /* scancodes_windows.h in Headers */, A769B14523E259AE00872273 /* SDL_rwopsbundlesupport.h in Headers */, + F386F6EC2884663E001840AA /* SDL_log_c.h in Headers */, A769B14623E259AE00872273 /* SDL_syspower.h in Headers */, A769B14723E259AE00872273 /* vulkan_macos.h in Headers */, A769B14823E259AE00872273 /* vulkan_xcb.h in Headers */, + F382072C284F3643004DD584 /* SDL_guid.h in Headers */, A769B14923E259AE00872273 /* vulkan_ios.h in Headers */, A769B14A23E259AE00872273 /* SDL_internal.h in Headers */, - A769B14B23E259AE00872273 /* SDL_shape.h in Headers */, - A769B14C23E259AE00872273 /* SDL_stdinc.h in Headers */, - A769B14D23E259AE00872273 /* SDL_surface.h in Headers */, A769B14E23E259AE00872273 /* vulkan.h in Headers */, A769B14F23E259AE00872273 /* SDL_keyboard_c.h in Headers */, - A769B15023E259AE00872273 /* SDL_system.h in Headers */, - A769B15123E259AE00872273 /* SDL_syswm.h in Headers */, - A769B15223E259AE00872273 /* SDL_opengl_glext.h in Headers */, A769B15323E259AE00872273 /* SDL_mouse_c.h in Headers */, + F395C1BF2569C6A000942BFF /* SDL_mfijoystick_c.h in Headers */, A769B15423E259AE00872273 /* SDL_blit_auto.h in Headers */, A769B15523E259AE00872273 /* SDL_blendline.h in Headers */, A769B15623E259AE00872273 /* SDL_syshaptic.h in Headers */, A769B15723E259AE00872273 /* SDL_vulkan_internal.h in Headers */, - A769B15823E259AE00872273 /* SDL_thread.h in Headers */, A769B15923E259AE00872273 /* SDL_cocoaevents.h in Headers */, + F362B9372B33916600D30B94 /* controller_list.h in Headers */, A769B15A23E259AE00872273 /* vk_icd.h in Headers */, A769B15B23E259AE00872273 /* SDL_nullframebuffer_c.h in Headers */, - A769B15C23E259AE00872273 /* SDL_timer.h in Headers */, A769B15D23E259AE00872273 /* SDL_dynapi_procs.h in Headers */, A769B15E23E259AE00872273 /* vulkan_fuchsia.h in Headers */, - A769B15F23E259AE00872273 /* SDL_touch.h in Headers */, - A769B16023E259AE00872273 /* SDL_types.h in Headers */, A769B16123E259AE00872273 /* usb_ids.h in Headers */, - A769B16223E259AE00872273 /* SDL_sysjoystick_c.h in Headers */, + F316ABAE2B5A02C3002EF551 /* yuv_rgb_lsx.h in Headers */, A769B16323E259AE00872273 /* SDL_gles2funcs.h in Headers */, - A769B16423E259AE00872273 /* SDL_sysjoystick_c.h in Headers */, - A769B16523E259AE00872273 /* SDL_version.h in Headers */, - A769B16623E259AE00872273 /* SDL_video.h in Headers */, - A769B16723E259AE00872273 /* SDL_opengles2_gl2.h in Headers */, - A769B16823E259AE00872273 /* SDL_sensor.h in Headers */, A769B16923E259AE00872273 /* SDL_sysvideo.h in Headers */, - A769B16A23E259AE00872273 /* SDL_opengles2_gl2platform.h in Headers */, - A769B16B23E259AE00872273 /* SDL_opengles2_gl2ext.h in Headers */, - A769B16C23E259AE00872273 /* SDL_x11mouse.h in Headers */, A769B16D23E259AE00872273 /* SDL_dynapi_overrides.h in Headers */, A769B16E23E259AE00872273 /* SDL_cocoawindow.h in Headers */, - A769B16F23E259AE00872273 /* SDL_x11vulkan.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -6417,242 +6141,239 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - A75FDAF623E35EC400529352 /* SDL_config_iphoneos.h in Headers */, - A7D88A1623E2437C00DCD162 /* begin_code.h in Headers */, - A75FDB5923E39E6100529352 /* hidapi.h in Headers */, - A7D8B24323E2514200DCD162 /* eglext.h in Headers */, - A7D8AABD23E2514100DCD162 /* SDL_haptic_c.h in Headers */, - A7D88A1823E2437C00DCD162 /* close_code.h in Headers */, - A7D8B85B23E2514400DCD162 /* SDL_sysaudio.h in Headers */, - A7D8AB8623E2514100DCD162 /* SDL_offscreenwindow.h in Headers */, A7D88A1923E2437C00DCD162 /* SDL.h in Headers */, - A7D8AC7623E2514100DCD162 /* SDL_uikitclipboard.h in Headers */, - A7D88A1A23E2437C00DCD162 /* SDL_assert.h in Headers */, - A7D8B3B723E2514200DCD162 /* SDL_blit.h in Headers */, - A7D8B4AD23E2514300DCD162 /* SDL_gamecontrollerdb.h in Headers */, - A7D8B9F023E2514400DCD162 /* SDL_drawpoint.h in Headers */, A7D8B39F23E2514200DCD162 /* SDL_RLEaccel_c.h in Headers */, - A7D8B44123E2514300DCD162 /* SDL_sysmutex_c.h in Headers */, - A7D8BA4423E2514400DCD162 /* SDL_glesfuncs.h in Headers */, - A7D8AEDD23E2514100DCD162 /* SDL_cocoaopengl.h in Headers */, - A7D8AF0123E2514100DCD162 /* SDL_cocoavideo.h in Headers */, - A7D8B2BB23E2514200DCD162 /* SDL_blit_auto.h in Headers */, - A7D8BBAC23E2514500DCD162 /* SDL_windowevents_c.h in Headers */, - A7D8B2B523E2514200DCD162 /* vulkan_android.h in Headers */, - A7D88A1B23E2437C00DCD162 /* SDL_atomic.h in Headers */, - A7D8B9A223E2514400DCD162 /* SDL_shaders_metal_tvos.h in Headers */, - A7D8BA0E23E2514400DCD162 /* SDL_blendpoint.h in Headers */, - A7D8B3E723E2514300DCD162 /* SDL_systhread.h in Headers */, - A7D8B1B923E2514200DCD162 /* SDL_x11modes.h in Headers */, - A7D88A1D23E2437C00DCD162 /* SDL_audio.h in Headers */, - A7D8B8CD23E2514400DCD162 /* SDL_coreaudio.h in Headers */, - A7D8AC4023E2514100DCD162 /* SDL_sysvideo.h in Headers */, - A7D8AEBF23E2514100DCD162 /* SDL_cocoamousetap.h in Headers */, - A7D8B4C523E2514300DCD162 /* SDL_steamcontroller.h in Headers */, - A7D88A1E23E2437C00DCD162 /* SDL_bits.h in Headers */, - A7D8B21F23E2514200DCD162 /* SDL_x11video.h in Headers */, - A7D8B9FC23E2514400DCD162 /* SDL_render_sw_c.h in Headers */, - A7D8B14723E2514200DCD162 /* SDL_x11touch.h in Headers */, - A7D88A1F23E2437C00DCD162 /* SDL_blendmode.h in Headers */, - A7D88A2023E2437C00DCD162 /* SDL_egl.h in Headers */, - A7D88A2123E2437C00DCD162 /* SDL_clipboard.h in Headers */, - A7D8BAC223E2514500DCD162 /* math_private.h in Headers */, - A7D88A2323E2437C00DCD162 /* SDL_config.h in Headers */, - A7D8BB3A23E2514500DCD162 /* SDL_gesture_c.h in Headers */, - A7D8ACB223E2514100DCD162 /* SDL_uikitopenglview.h in Headers */, - A7D8B9CC23E2514400DCD162 /* SDL_yuv_sw_c.h in Headers */, - A7D88A2523E2437C00DCD162 /* SDL_copying.h in Headers */, - A7D8AB8023E2514100DCD162 /* SDL_offscreenframebuffer_c.h in Headers */, - A7D8AEF523E2514100DCD162 /* SDL_cocoamodes.h in Headers */, - A7D8ABFE23E2514100DCD162 /* SDL_nullevents_c.h in Headers */, - A7D8AC6A23E2514100DCD162 /* SDL_uikitmodes.h in Headers */, - A7D88A2623E2437C00DCD162 /* SDL_cpuinfo.h in Headers */, - A7D8BA5623E2514400DCD162 /* SDL_gles2funcs.h in Headers */, - A7D8B8A323E2514400DCD162 /* SDL_diskaudio.h in Headers */, - A7D8B9D823E2514400DCD162 /* SDL_sysrender.h in Headers */, - A7D8BB2223E2514500DCD162 /* scancodes_windows.h in Headers */, - A7D8ADED23E2514100DCD162 /* SDL_blit_slow.h in Headers */, - A7D8B20D23E2514200DCD162 /* SDL_x11clipboard.h in Headers */, + A7D88A1A23E2437C00DCD162 /* SDL_assert.h in Headers */, A7D8B61823E2514300DCD162 /* SDL_assert_c.h in Headers */, - A7D8BA3223E2514400DCD162 /* SDL_rotate.h in Headers */, + A7D88A1B23E2437C00DCD162 /* SDL_atomic.h in Headers */, + A7D88A1D23E2437C00DCD162 /* SDL_audio.h in Headers */, + A7D8B7A123E2514400DCD162 /* SDL_audio_c.h in Headers */, + A7D8B7B323E2514400DCD162 /* SDL_audiodev_c.h in Headers */, + A7D88A1E23E2437C00DCD162 /* SDL_bits.h in Headers */, + A7D8BA0223E2514400DCD162 /* SDL_blendfillrect.h in Headers */, + A7D8B9EA23E2514400DCD162 /* SDL_blendline.h in Headers */, + F316ABC52B5A02C3002EF551 /* yuv_rgb_std.h in Headers */, + A7D88A1F23E2437C00DCD162 /* SDL_blendmode.h in Headers */, + A7D8BA0E23E2514400DCD162 /* SDL_blendpoint.h in Headers */, + A7D8B3B723E2514200DCD162 /* SDL_blit.h in Headers */, + A7D8B2BB23E2514200DCD162 /* SDL_blit_auto.h in Headers */, + F3820728284F3643004DD584 /* SDL_guid.h in Headers */, + A7D8B39923E2514200DCD162 /* SDL_blit_copy.h in Headers */, + A7D8ADED23E2514100DCD162 /* SDL_blit_slow.h in Headers */, + A7D88A2123E2437C00DCD162 /* SDL_clipboard.h in Headers */, + A7D8BB7023E2514500DCD162 /* SDL_clipboardevents_c.h in Headers */, + A7D8AECB23E2514100DCD162 /* SDL_cocoaclipboard.h in Headers */, + A7D8AF1323E2514100DCD162 /* SDL_cocoaevents.h in Headers */, + A7D8AE8F23E2514100DCD162 /* SDL_cocoakeyboard.h in Headers */, + A7D8AF0723E2514100DCD162 /* SDL_cocoamessagebox.h in Headers */, + A7D8AEB323E2514100DCD162 /* SDL_cocoametalview.h in Headers */, + A7D8AEF523E2514100DCD162 /* SDL_cocoamodes.h in Headers */, + A7D8AF1F23E2514100DCD162 /* SDL_cocoamouse.h in Headers */, + A7D8AEDD23E2514100DCD162 /* SDL_cocoaopengl.h in Headers */, + A7D8AEEF23E2514100DCD162 /* SDL_cocoaopengles.h in Headers */, + A7D8AE8323E2514100DCD162 /* SDL_cocoashape.h in Headers */, + A7D8AF0123E2514100DCD162 /* SDL_cocoavideo.h in Headers */, + A7D8AEE923E2514100DCD162 /* SDL_cocoavulkan.h in Headers */, + A7D8AEFB23E2514100DCD162 /* SDL_cocoawindow.h in Headers */, + A7D88A2323E2437C00DCD162 /* SDL_config.h in Headers */, + A75FDAF623E35EC400529352 /* SDL_config_iphoneos.h in Headers */, + A7D88A2523E2437C00DCD162 /* SDL_copying.h in Headers */, + A7D8B8CD23E2514400DCD162 /* SDL_coreaudio.h in Headers */, + A7D8A97023E2514000DCD162 /* SDL_coremotionsensor.h in Headers */, + A7D88A2623E2437C00DCD162 /* SDL_cpuinfo.h in Headers */, + F31A92C928D4CB39003BFD6A /* SDL_offscreenopengles.h in Headers */, + A7D8B98123E2514400DCD162 /* SDL_d3dmath.h in Headers */, + A7D8A94623E2514000DCD162 /* SDL_dataqueue.h in Headers */, + A7D8B8A323E2514400DCD162 /* SDL_diskaudio.h in Headers */, + A7D8BB4023E2514500DCD162 /* SDL_displayevents_c.h in Headers */, + A7D8BA1A23E2514400DCD162 /* SDL_draw.h in Headers */, A7D8BA0823E2514400DCD162 /* SDL_drawline.h in Headers */, - A7D8B1E923E2514200DCD162 /* SDL_x11window.h in Headers */, - A7D8AB7A23E2514100DCD162 /* SDL_offscreenopengl.h in Headers */, - A7D8B1EF23E2514200DCD162 /* SDL_x11framebuffer.h in Headers */, - A7D8BB8823E2514500DCD162 /* SDL_keyboard_c.h in Headers */, - A7D88A2723E2437C00DCD162 /* SDL_endian.h in Headers */, + F316ABBC2B5A02C3002EF551 /* yuv_rgb_sse.h in Headers */, + A7D8B9F023E2514400DCD162 /* SDL_drawpoint.h in Headers */, + A7D8BB2E23E2514500DCD162 /* SDL_dropevents_c.h in Headers */, + A7D8B79523E2514400DCD162 /* SDL_dummyaudio.h in Headers */, + A7D8A96423E2514000DCD162 /* SDL_dummysensor.h in Headers */, A7D8AB0B23E2514100DCD162 /* SDL_dynapi.h in Headers */, - A7D8AB6E23E2514100DCD162 /* SDL_offscreenvideo.h in Headers */, + A7D8AB1123E2514100DCD162 /* SDL_dynapi_overrides.h in Headers */, + A7D8AB1D23E2514100DCD162 /* SDL_dynapi_procs.h in Headers */, + A7D88A2023E2437C00DCD162 /* SDL_egl.h in Headers */, + A7D8ABDA23E2514100DCD162 /* SDL_egl_c.h in Headers */, + A7D88A2723E2437C00DCD162 /* SDL_endian.h in Headers */, A7D88A2823E2437C00DCD162 /* SDL_error.h in Headers */, - A7D8ACA023E2514100DCD162 /* keyinfotable.h in Headers */, - A7D8B26123E2514200DCD162 /* vulkan.h in Headers */, + A7D8A95E23E2514000DCD162 /* SDL_error_c.h in Headers */, A7D88A2923E2437C00DCD162 /* SDL_events.h in Headers */, A7D8BBA623E2514500DCD162 /* SDL_events_c.h in Headers */, - A7D8B23D23E2514200DCD162 /* egl.h in Headers */, - A7D8ABDA23E2514100DCD162 /* SDL_egl_c.h in Headers */, - A7D8A98E23E2514000DCD162 /* SDL_sensor_c.h in Headers */, A7D88A2A23E2437C00DCD162 /* SDL_filesystem.h in Headers */, - A7D8B27F23E2514200DCD162 /* vulkan_win32.h in Headers */, A7D88A2B23E2437C00DCD162 /* SDL_gamecontroller.h in Headers */, - A7D8B79523E2514400DCD162 /* SDL_dummyaudio.h in Headers */, - A7D8B26723E2514200DCD162 /* vk_platform.h in Headers */, + A7D8B4AD23E2514300DCD162 /* SDL_gamecontrollerdb.h in Headers */, A7D88A2C23E2437C00DCD162 /* SDL_gesture.h in Headers */, + A7D8BB3A23E2514500DCD162 /* SDL_gesture_c.h in Headers */, + A7D8BA5623E2514400DCD162 /* SDL_gles2funcs.h in Headers */, + A7D8BA4423E2514400DCD162 /* SDL_glesfuncs.h in Headers */, + A7D8BA7A23E2514400DCD162 /* SDL_glfuncs.h in Headers */, A7D88A2D23E2437C00DCD162 /* SDL_haptic.h in Headers */, - A7D8BB4623E2514500DCD162 /* blank_cursor.h in Headers */, - A7D8BB5E23E2514500DCD162 /* scancodes_linux.h in Headers */, - A7D88A2E23E2437C00DCD162 /* SDL_hints.h in Headers */, - A7D8B2A323E2514200DCD162 /* vulkan_ios.h in Headers */, - A7D8ACBE23E2514100DCD162 /* SDL_uikitevents.h in Headers */, - A7D8B98123E2514400DCD162 /* SDL_d3dmath.h in Headers */, - A7D88A2F23E2437C00DCD162 /* SDL_joystick.h in Headers */, - A7D8B5B823E2514300DCD162 /* controller_type.h in Headers */, - A7D8AEEF23E2514100DCD162 /* SDL_cocoaopengles.h in Headers */, - A7D8AECB23E2514100DCD162 /* SDL_cocoaclipboard.h in Headers */, - A7D8AEFB23E2514100DCD162 /* SDL_cocoawindow.h in Headers */, - A7D88A3023E2437C00DCD162 /* SDL_keyboard.h in Headers */, - A7D8B22523E2514200DCD162 /* gl2ext.h in Headers */, - A7D8B3CF23E2514300DCD162 /* yuv_rgb_std_func.h in Headers */, - A7D88A3123E2437C00DCD162 /* SDL_sensor.h in Headers */, - A7D88A3223E2437C00DCD162 /* SDL_metal.h in Headers */, - A7D88A3323E2437C00DCD162 /* SDL_keycode.h in Headers */, - A7D8BB4023E2514500DCD162 /* SDL_displayevents_c.h in Headers */, - A7D88A3523E2437C00DCD162 /* SDL_loadso.h in Headers */, - A7D8B23123E2514200DCD162 /* gl2platform.h in Headers */, - A7D8AAD523E2514100DCD162 /* SDL_syshaptic.h in Headers */, - A7D8B57C23E2514300DCD162 /* SDL_sysjoystick_c.h in Headers */, - A7D8B1AD23E2514200DCD162 /* SDL_x11sym.h in Headers */, - A7D8B86D23E2514400DCD162 /* SDL_wave.h in Headers */, - A7D8B1FB23E2514200DCD162 /* SDL_x11mouse.h in Headers */, - A7D8B25B23E2514200DCD162 /* vulkan_vi.h in Headers */, - A7D8B14D23E2514200DCD162 /* SDL_x11messagebox.h in Headers */, - A7D88A3623E2437C00DCD162 /* SDL_log.h in Headers */, - A7D8BB4C23E2514500DCD162 /* default_cursor.h in Headers */, - A7D8AEB323E2514100DCD162 /* SDL_cocoametalview.h in Headers */, - A7D8B3D523E2514300DCD162 /* yuv_rgb.h in Headers */, - A7D8B1D123E2514200DCD162 /* SDL_x11xinput2.h in Headers */, - A7D8B25523E2514200DCD162 /* vk_icd.h in Headers */, - A7D8B2AF23E2514200DCD162 /* vk_sdk_platform.h in Headers */, - A7D8BB2E23E2514500DCD162 /* SDL_dropevents_c.h in Headers */, - A7D8B61223E2514300DCD162 /* SDL_syspower.h in Headers */, - A7D8ACE223E2514100DCD162 /* SDL_uikitvulkan.h in Headers */, - A7D8BB6423E2514500DCD162 /* SDL_touch_c.h in Headers */, - A7D8B29D23E2514200DCD162 /* vulkan_xlib.h in Headers */, - A7D8AE8323E2514100DCD162 /* SDL_cocoashape.h in Headers */, - A7D88A3823E2437C00DCD162 /* SDL_main.h in Headers */, - A7D8ABE623E2514100DCD162 /* SDL_nullframebuffer_c.h in Headers */, - A7D8AC7C23E2514100DCD162 /* SDL_uikitvideo.h in Headers */, - A7D88A3923E2437C00DCD162 /* SDL_messagebox.h in Headers */, - A7D8B28523E2514200DCD162 /* vulkan_macos.h in Headers */, - A7D88A3A23E2437C00DCD162 /* SDL_mouse.h in Headers */, - A7D88A3B23E2437C00DCD162 /* SDL_mutex.h in Headers */, - A7D8AC5E23E2514100DCD162 /* SDL_uikitmetalview.h in Headers */, - A7D8B58823E2514300DCD162 /* SDL_joystick_c.h in Headers */, - A7D88A3C23E2437C00DCD162 /* SDL_name.h in Headers */, - A7D8A97023E2514000DCD162 /* SDL_coremotionsensor.h in Headers */, + A7D8AABD23E2514100DCD162 /* SDL_haptic_c.h in Headers */, + F316AB8F2B5A02C3002EF551 /* yuv_rgb_internal.h in Headers */, A75FDBC623EA380300529352 /* SDL_hidapi_rumble.h in Headers */, - A7D8B98D23E2514400DCD162 /* SDL_shaders_metal_ios.h in Headers */, - A7D8AF1323E2514100DCD162 /* SDL_cocoaevents.h in Headers */, - A7D8BA7423E2514400DCD162 /* SDL_shaders_gl.h in Headers */, - A7D8AC4623E2514100DCD162 /* SDL_uikitview.h in Headers */, + A7D8B55823E2514300DCD162 /* SDL_hidapijoystick_c.h in Headers */, + A7D88A2E23E2437C00DCD162 /* SDL_hints.h in Headers */, + A7D8B94B23E2514400DCD162 /* SDL_hints_c.h in Headers */, + F316ABCE2B5A02C3002EF551 /* yuv_rgb_lsx_func.h in Headers */, + A7D8A99A23E2514000DCD162 /* SDL_internal.h in Headers */, + F395C1942569C68F00942BFF /* SDL_iokitjoystick_c.h in Headers */, + A7D88A2F23E2437C00DCD162 /* SDL_joystick.h in Headers */, + A7D8B58823E2514300DCD162 /* SDL_joystick_c.h in Headers */, + F316AB862B5A02C3002EF551 /* yuv_rgb_common.h in Headers */, + A7D88A3023E2437C00DCD162 /* SDL_keyboard.h in Headers */, + A7D8BB8823E2514500DCD162 /* SDL_keyboard_c.h in Headers */, + A7D88A3323E2437C00DCD162 /* SDL_keycode.h in Headers */, + A7D88A3523E2437C00DCD162 /* SDL_loadso.h in Headers */, + F3631C6424884ACF004F28EA /* SDL_locale.h in Headers */, + A7D88A3623E2437C00DCD162 /* SDL_log.h in Headers */, + A7D88A3823E2437C00DCD162 /* SDL_main.h in Headers */, + A7D88A3923E2437C00DCD162 /* SDL_messagebox.h in Headers */, + F386F6E82884663E001840AA /* SDL_log_c.h in Headers */, + A7D88A3223E2437C00DCD162 /* SDL_metal.h in Headers */, + F395C1BB2569C6A000942BFF /* SDL_mfijoystick_c.h in Headers */, + F3928194258603F1003191A7 /* SDL_misc.h in Headers */, + A7D88A3A23E2437C00DCD162 /* SDL_mouse.h in Headers */, + A7D8BB1C23E2514500DCD162 /* SDL_mouse_c.h in Headers */, + F38233862738EB8600F7F527 /* SDL_hidapi.h in Headers */, + A7D88A3B23E2437C00DCD162 /* SDL_mutex.h in Headers */, + A7D88A3C23E2437C00DCD162 /* SDL_name.h in Headers */, + A7D8ABFE23E2514100DCD162 /* SDL_nullevents_c.h in Headers */, + A7D8ABE623E2514100DCD162 /* SDL_nullframebuffer_c.h in Headers */, + A7D8ABF823E2514100DCD162 /* SDL_nullvideo.h in Headers */, + A7D8AB5C23E2514100DCD162 /* SDL_offscreenevents_c.h in Headers */, + A7D8AB8023E2514100DCD162 /* SDL_offscreenframebuffer_c.h in Headers */, + A7D8AB6E23E2514100DCD162 /* SDL_offscreenvideo.h in Headers */, + A7D8AB8623E2514100DCD162 /* SDL_offscreenwindow.h in Headers */, A7D88A3D23E2437C00DCD162 /* SDL_opengl.h in Headers */, - A7D8AC0423E2514100DCD162 /* SDL_rect_c.h in Headers */, - A7D8A97C23E2514000DCD162 /* SDL_syssensor.h in Headers */, A7D88A3E23E2437C00DCD162 /* SDL_opengl_glext.h in Headers */, A7D88A3F23E2437C00DCD162 /* SDL_opengles.h in Headers */, - A7D8B58223E2514300DCD162 /* SDL_sysjoystick.h in Headers */, A7D88A4023E2437C00DCD162 /* SDL_opengles2.h in Headers */, - A7D8A94623E2514000DCD162 /* SDL_dataqueue.h in Headers */, - A7D8B24F23E2514200DCD162 /* vk_layer.h in Headers */, A7D88A4123E2437C00DCD162 /* SDL_opengles2_gl2.h in Headers */, - A7D8BBA023E2514500DCD162 /* scancodes_xfree86.h in Headers */, - A7D8AF1F23E2514100DCD162 /* SDL_cocoamouse.h in Headers */, - A7D8AE8F23E2514100DCD162 /* SDL_cocoakeyboard.h in Headers */, - A7D8BA5023E2514400DCD162 /* SDL_shaders_gles2.h in Headers */, A7D88A4223E2437C00DCD162 /* SDL_opengles2_gl2ext.h in Headers */, - A7D8B29723E2514200DCD162 /* vulkan_mir.h in Headers */, A7D88A4323E2437C00DCD162 /* SDL_opengles2_gl2platform.h in Headers */, - A7D8BA1A23E2514400DCD162 /* SDL_draw.h in Headers */, - A7D8BB5223E2514500DCD162 /* scancodes_darwin.h in Headers */, - A7D8BB9423E2514500DCD162 /* SDL_sysevents.h in Headers */, - A7D8B7A123E2514400DCD162 /* SDL_audio_c.h in Headers */, - A7D8B17123E2514200DCD162 /* SDL_x11opengles.h in Headers */, - A7D8B29123E2514200DCD162 /* vulkan_xcb.h in Headers */, - A7D8AAE123E2514100DCD162 /* SDL_syshaptic_c.h in Headers */, - A7D8BB1C23E2514500DCD162 /* SDL_mouse_c.h in Headers */, - A7D8BA0223E2514400DCD162 /* SDL_blendfillrect.h in Headers */, - A7D8B27923E2514200DCD162 /* vulkan_wayland.h in Headers */, - A7D8B5C423E2514300DCD162 /* SDL_rwopsbundlesupport.h in Headers */, A7D88A4423E2437C00DCD162 /* SDL_opengles2_khrplatform.h in Headers */, - A7D8B23723E2514200DCD162 /* khrplatform.h in Headers */, A7D88A4523E2437C00DCD162 /* SDL_pixels.h in Headers */, - A7D8ABF823E2514100DCD162 /* SDL_nullvideo.h in Headers */, - A7D8B57023E2514300DCD162 /* usb_ids.h in Headers */, - A7D8B7B323E2514400DCD162 /* SDL_audiodev_c.h in Headers */, + A7D8B2C123E2514200DCD162 /* SDL_pixels_c.h in Headers */, A7D88A4623E2437C00DCD162 /* SDL_platform.h in Headers */, A7D88A4723E2437C00DCD162 /* SDL_power.h in Headers */, - A7D8AC9A23E2514100DCD162 /* SDL_uikitwindow.h in Headers */, A7D88A4823E2437C00DCD162 /* SDL_quit.h in Headers */, - A7D8AB1123E2514100DCD162 /* SDL_dynapi_overrides.h in Headers */, A7D88A4923E2437C00DCD162 /* SDL_rect.h in Headers */, - A7D8B27323E2514200DCD162 /* vulkan_fuchsia.h in Headers */, - A7D8B28B23E2514200DCD162 /* vulkan_xlib_xrandr.h in Headers */, - A7D8B5D623E2514300DCD162 /* SDL_syspower.h in Headers */, + A7D8AC0423E2514100DCD162 /* SDL_rect_c.h in Headers */, A7D88A4B23E2437C00DCD162 /* SDL_render.h in Headers */, - A7D8B26D23E2514200DCD162 /* vulkan.hpp in Headers */, + A7D8B9FC23E2514400DCD162 /* SDL_render_sw_c.h in Headers */, A7D88A4C23E2437C00DCD162 /* SDL_revision.h in Headers */, - A7D8AB3223E2514100DCD162 /* SDL_timer_c.h in Headers */, - A7D8B16523E2514200DCD162 /* SDL_x11shape.h in Headers */, - A7D8AB1D23E2514100DCD162 /* SDL_dynapi_procs.h in Headers */, - A7D8BB0423E2514500DCD162 /* math_libm.h in Headers */, + A7D8BA3223E2514400DCD162 /* SDL_rotate.h in Headers */, + F3973FA328A59BDD00B84553 /* SDL_vacopy.h in Headers */, A7D88A4D23E2437C00DCD162 /* SDL_rwops.h in Headers */, - A7D8B3C923E2514300DCD162 /* yuv_rgb_sse_func.h in Headers */, - A7D8AF0723E2514100DCD162 /* SDL_cocoamessagebox.h in Headers */, - A7D8B1D723E2514200DCD162 /* edid.h in Headers */, + A7D8B5C423E2514300DCD162 /* SDL_rwopsbundlesupport.h in Headers */, A7D88A4E23E2437C00DCD162 /* SDL_scancode.h in Headers */, - A7D8B39923E2514200DCD162 /* SDL_blit_copy.h in Headers */, - A7D8B22B23E2514200DCD162 /* gl2.h in Headers */, + A7D88A3123E2437C00DCD162 /* SDL_sensor.h in Headers */, + A7D8A98E23E2514000DCD162 /* SDL_sensor_c.h in Headers */, + F386F6F12884663E001840AA /* SDL_utils_c.h in Headers */, + A7D8BA7423E2514400DCD162 /* SDL_shaders_gl.h in Headers */, + A7D8BA5023E2514400DCD162 /* SDL_shaders_gles2.h in Headers */, + A1BB8B6D27F6CF330057CFA8 /* SDL_list.h in Headers */, + A7D8B98D23E2514400DCD162 /* SDL_shaders_metal_ios.h in Headers */, + A7D8B99C23E2514400DCD162 /* SDL_shaders_metal_osx.h in Headers */, + A7D8B9A223E2514400DCD162 /* SDL_shaders_metal_tvos.h in Headers */, A7D88A5023E2437C00DCD162 /* SDL_shape.h in Headers */, - A7D88A5123E2437C00DCD162 /* SDL_stdinc.h in Headers */, - A7D8ACCA23E2514100DCD162 /* SDL_uikitappdelegate.h in Headers */, - A7D8BBB823E254E400DCD162 /* SDL_sysjoystick_c.h in Headers */, - A7D8B3B123E2514200DCD162 /* SDL_yuv_c.h in Headers */, - A7D8B1F523E2514200DCD162 /* SDL_x11dyn.h in Headers */, - A7D8AC8823E2514100DCD162 /* SDL_uikitviewcontroller.h in Headers */, A7D8AC0A23E2514100DCD162 /* SDL_shape_internals.h in Headers */, - A7D8A95E23E2514000DCD162 /* SDL_error_c.h in Headers */, - A7D8B2A923E2514200DCD162 /* vulkan_core.h in Headers */, - A7D8B3ED23E2514300DCD162 /* SDL_thread_c.h in Headers */, + A7D88A5123E2437C00DCD162 /* SDL_stdinc.h in Headers */, + A7D8B4C523E2514300DCD162 /* SDL_steamcontroller.h in Headers */, A7D88A5223E2437C00DCD162 /* SDL_surface.h in Headers */, - A7D8BB7023E2514500DCD162 /* SDL_clipboardevents_c.h in Headers */, - A7D8AB5C23E2514100DCD162 /* SDL_offscreenevents_c.h in Headers */, - A7D8AEE923E2514100DCD162 /* SDL_cocoavulkan.h in Headers */, + A7D8B85B23E2514400DCD162 /* SDL_sysaudio.h in Headers */, + A7D8AAD523E2514100DCD162 /* SDL_syshaptic.h in Headers */, + A7D8AAE123E2514100DCD162 /* SDL_syshaptic_c.h in Headers */, + A7D8B58223E2514300DCD162 /* SDL_sysjoystick.h in Headers */, + 560572172473688A00B46B66 /* SDL_syslocale.h in Headers */, + A7D8B44123E2514300DCD162 /* SDL_sysmutex_c.h in Headers */, + A7D8B5D623E2514300DCD162 /* SDL_syspower.h in Headers */, + A7D8B61223E2514300DCD162 /* SDL_syspower.h in Headers */, + A7D8B9D823E2514400DCD162 /* SDL_sysrender.h in Headers */, + F362B9472B33920500D30B94 /* SDL_hidapi_nintendo.h in Headers */, + F316ABAA2B5A02C3002EF551 /* yuv_rgb_lsx.h in Headers */, + A7D8A97C23E2514000DCD162 /* SDL_syssensor.h in Headers */, A7D88A5323E2437C00DCD162 /* SDL_system.h in Headers */, - A7D8BA7A23E2514400DCD162 /* SDL_glfuncs.h in Headers */, - A7D8B2C123E2514200DCD162 /* SDL_pixels_c.h in Headers */, + A7D8B3E723E2514300DCD162 /* SDL_systhread.h in Headers */, + A7D8B42923E2514300DCD162 /* SDL_systhread_c.h in Headers */, + 5616CA51252BB35A005D5928 /* SDL_sysurl.h in Headers */, + A7D8AC4023E2514100DCD162 /* SDL_sysvideo.h in Headers */, A7D88A5423E2437C00DCD162 /* SDL_syswm.h in Headers */, A7D88A5523E2437C00DCD162 /* SDL_thread.h in Headers */, - A7D8ACD623E2514100DCD162 /* SDL_uikitopengles.h in Headers */, + A7D8B3ED23E2514300DCD162 /* SDL_thread_c.h in Headers */, A7D88A5623E2437C00DCD162 /* SDL_timer.h in Headers */, - A7D8B21323E2514200DCD162 /* SDL_x11events.h in Headers */, + A7D8AB3223E2514100DCD162 /* SDL_timer_c.h in Headers */, A7D88A5723E2437C00DCD162 /* SDL_touch.h in Headers */, - A7D8A96423E2514000DCD162 /* SDL_dummysensor.h in Headers */, + A7D8BB6423E2514500DCD162 /* SDL_touch_c.h in Headers */, A7D88A5823E2437C00DCD162 /* SDL_types.h in Headers */, - A7D8B42923E2514300DCD162 /* SDL_systhread_c.h in Headers */, - A7D8B20723E2514200DCD162 /* SDL_x11keyboard.h in Headers */, - A7D8B94B23E2514400DCD162 /* SDL_hints_c.h in Headers */, - A7D8AD1E23E2514100DCD162 /* SDL_vulkan_internal.h in Headers */, - A7D8B9EA23E2514400DCD162 /* SDL_blendline.h in Headers */, + A7D8ACCA23E2514100DCD162 /* SDL_uikitappdelegate.h in Headers */, + A7D8AC7623E2514100DCD162 /* SDL_uikitclipboard.h in Headers */, + A7D8ACBE23E2514100DCD162 /* SDL_uikitevents.h in Headers */, + A7D8AC9423E2514100DCD162 /* SDL_uikitmessagebox.h in Headers */, + A7D8AC5E23E2514100DCD162 /* SDL_uikitmetalview.h in Headers */, + A7D8AC6A23E2514100DCD162 /* SDL_uikitmodes.h in Headers */, + A7D8ACD623E2514100DCD162 /* SDL_uikitopengles.h in Headers */, + A7D8ACB223E2514100DCD162 /* SDL_uikitopenglview.h in Headers */, + A7D8AC7C23E2514100DCD162 /* SDL_uikitvideo.h in Headers */, + A7D8AC4623E2514100DCD162 /* SDL_uikitview.h in Headers */, + A7D8AC8823E2514100DCD162 /* SDL_uikitviewcontroller.h in Headers */, + A7D8ACE223E2514100DCD162 /* SDL_uikitvulkan.h in Headers */, + A7D8AC9A23E2514100DCD162 /* SDL_uikitwindow.h in Headers */, A7D88A5923E2437C00DCD162 /* SDL_version.h in Headers */, A7D88A5A23E2437C00DCD162 /* SDL_video.h in Headers */, - A7D8B24923E2514200DCD162 /* eglplatform.h in Headers */, - A7D8AC9423E2514100DCD162 /* SDL_uikitmessagebox.h in Headers */, - A7D8B1DD23E2514200DCD162 /* SDL_x11vulkan.h in Headers */, - A7D8B55823E2514300DCD162 /* SDL_hidapijoystick_c.h in Headers */, - A7D8B21923E2514200DCD162 /* imKStoUCS.h in Headers */, - A7D8B1B323E2514200DCD162 /* SDL_x11opengl.h in Headers */, + 75E09164241EA924004729E1 /* SDL_virtualjoystick_c.h in Headers */, A7D88A5C23E2437C00DCD162 /* SDL_vulkan.h in Headers */, - A7D8B99C23E2514400DCD162 /* SDL_shaders_metal_osx.h in Headers */, - A7D8A99A23E2514000DCD162 /* SDL_internal.h in Headers */, + A7D8AD1E23E2514100DCD162 /* SDL_vulkan_internal.h in Headers */, + A7D8B86D23E2514400DCD162 /* SDL_wave.h in Headers */, + A7D8BBAC23E2514500DCD162 /* SDL_windowevents_c.h in Headers */, + A7D8B3B123E2514200DCD162 /* SDL_yuv_c.h in Headers */, + A7D8B9CC23E2514400DCD162 /* SDL_yuv_sw_c.h in Headers */, + A7D88A1623E2437C00DCD162 /* begin_code.h in Headers */, + A7D8BB4623E2514500DCD162 /* blank_cursor.h in Headers */, + F362B9532B33EB7300D30B94 /* SDL_steam_virtual_gamepad.h in Headers */, + A7D88A1823E2437C00DCD162 /* close_code.h in Headers */, + A7D8B5B823E2514300DCD162 /* controller_type.h in Headers */, + A7D8BB4C23E2514500DCD162 /* default_cursor.h in Headers */, + A7D8B23D23E2514200DCD162 /* egl.h in Headers */, + A7D8B24323E2514200DCD162 /* eglext.h in Headers */, + A7D8B24923E2514200DCD162 /* eglplatform.h in Headers */, + A7D8B22B23E2514200DCD162 /* gl2.h in Headers */, + A7D8B22523E2514200DCD162 /* gl2ext.h in Headers */, + A7D8B23123E2514200DCD162 /* gl2platform.h in Headers */, + A75FDB5923E39E6100529352 /* hidapi.h in Headers */, + A7D8B23723E2514200DCD162 /* khrplatform.h in Headers */, + A7D8BB0423E2514500DCD162 /* math_libm.h in Headers */, + A7D8BAC223E2514500DCD162 /* math_private.h in Headers */, + A7D8BB5223E2514500DCD162 /* scancodes_darwin.h in Headers */, + A7D8BB5E23E2514500DCD162 /* scancodes_linux.h in Headers */, + A7D8BB2223E2514500DCD162 /* scancodes_windows.h in Headers */, + A7D8BBA023E2514500DCD162 /* scancodes_xfree86.h in Headers */, + A7D8B57023E2514300DCD162 /* usb_ids.h in Headers */, + A1626A532617008D003F1973 /* SDL_triangle.h in Headers */, + A7D8B25523E2514200DCD162 /* vk_icd.h in Headers */, + A7D8B24F23E2514200DCD162 /* vk_layer.h in Headers */, + A7D8B26723E2514200DCD162 /* vk_platform.h in Headers */, + A7D8B2AF23E2514200DCD162 /* vk_sdk_platform.h in Headers */, + A7D8B26123E2514200DCD162 /* vulkan.h in Headers */, + A7D8B2B523E2514200DCD162 /* vulkan_android.h in Headers */, + A7D8B2A923E2514200DCD162 /* vulkan_core.h in Headers */, + A7D8B27323E2514200DCD162 /* vulkan_fuchsia.h in Headers */, + A7D8B2A323E2514200DCD162 /* vulkan_ios.h in Headers */, + A7D8B28523E2514200DCD162 /* vulkan_macos.h in Headers */, + A7D8B25B23E2514200DCD162 /* vulkan_vi.h in Headers */, + A7D8B27923E2514200DCD162 /* vulkan_wayland.h in Headers */, + A7D8B27F23E2514200DCD162 /* vulkan_win32.h in Headers */, + F362B9332B33916600D30B94 /* controller_list.h in Headers */, + A7D8B29123E2514200DCD162 /* vulkan_xcb.h in Headers */, + A7D8B29D23E2514200DCD162 /* vulkan_xlib.h in Headers */, + A7D8B28B23E2514200DCD162 /* vulkan_xlib_xrandr.h in Headers */, + A7D8B3D523E2514300DCD162 /* yuv_rgb.h in Headers */, + A7D8B3C923E2514300DCD162 /* yuv_rgb_sse_func.h in Headers */, + A7D8B3CF23E2514300DCD162 /* yuv_rgb_std_func.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -6660,242 +6381,239 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - A75FDAF723E35EC400529352 /* SDL_config_iphoneos.h in Headers */, - A7D88BCC23E24BED00DCD162 /* begin_code.h in Headers */, - A75FDB5A23E39E6100529352 /* hidapi.h in Headers */, - A7D8B24423E2514200DCD162 /* eglext.h in Headers */, - A7D8AABE23E2514100DCD162 /* SDL_haptic_c.h in Headers */, - A7D88BCE23E24BED00DCD162 /* close_code.h in Headers */, - A7D8B85C23E2514400DCD162 /* SDL_sysaudio.h in Headers */, - A7D8AB8723E2514100DCD162 /* SDL_offscreenwindow.h in Headers */, A7D88BCF23E24BED00DCD162 /* SDL.h in Headers */, - A7D8AC7723E2514100DCD162 /* SDL_uikitclipboard.h in Headers */, - A7D88BD023E24BED00DCD162 /* SDL_assert.h in Headers */, - A7D8B3B823E2514200DCD162 /* SDL_blit.h in Headers */, - A7D8B4AE23E2514300DCD162 /* SDL_gamecontrollerdb.h in Headers */, - A7D8B9F123E2514400DCD162 /* SDL_drawpoint.h in Headers */, A7D8B3A023E2514200DCD162 /* SDL_RLEaccel_c.h in Headers */, - A7D8B44223E2514300DCD162 /* SDL_sysmutex_c.h in Headers */, - A7D8BA4523E2514400DCD162 /* SDL_glesfuncs.h in Headers */, - A7D8AEDE23E2514100DCD162 /* SDL_cocoaopengl.h in Headers */, - A7D8AF0223E2514100DCD162 /* SDL_cocoavideo.h in Headers */, - A7D8B2BC23E2514200DCD162 /* SDL_blit_auto.h in Headers */, - A7D8BBAD23E2514500DCD162 /* SDL_windowevents_c.h in Headers */, - A7D8B2B623E2514200DCD162 /* vulkan_android.h in Headers */, - A7D88BD123E24BED00DCD162 /* SDL_atomic.h in Headers */, - A7D8B9A323E2514400DCD162 /* SDL_shaders_metal_tvos.h in Headers */, - A7D8BA0F23E2514400DCD162 /* SDL_blendpoint.h in Headers */, - A7D8B3E823E2514300DCD162 /* SDL_systhread.h in Headers */, - A7D8B1BA23E2514200DCD162 /* SDL_x11modes.h in Headers */, - A7D88BD423E24BED00DCD162 /* SDL_audio.h in Headers */, - A7D8B8CE23E2514400DCD162 /* SDL_coreaudio.h in Headers */, - A7D8AC4123E2514100DCD162 /* SDL_sysvideo.h in Headers */, - A7D8AEC023E2514100DCD162 /* SDL_cocoamousetap.h in Headers */, - A7D8B4C623E2514300DCD162 /* SDL_steamcontroller.h in Headers */, - A7D88BD523E24BED00DCD162 /* SDL_bits.h in Headers */, - A7D8B22023E2514200DCD162 /* SDL_x11video.h in Headers */, - A7D8B9FD23E2514400DCD162 /* SDL_render_sw_c.h in Headers */, - A7D8B14823E2514200DCD162 /* SDL_x11touch.h in Headers */, - A7D88BD623E24BED00DCD162 /* SDL_blendmode.h in Headers */, - A7D88BD723E24BED00DCD162 /* SDL_egl.h in Headers */, - A7D88BD823E24BED00DCD162 /* SDL_clipboard.h in Headers */, - A7D8BAC323E2514500DCD162 /* math_private.h in Headers */, - A7D88BDA23E24BED00DCD162 /* SDL_config.h in Headers */, - A7D8BB3B23E2514500DCD162 /* SDL_gesture_c.h in Headers */, - A7D8ACB323E2514100DCD162 /* SDL_uikitopenglview.h in Headers */, - A7D8B9CD23E2514400DCD162 /* SDL_yuv_sw_c.h in Headers */, - A7D88BDC23E24BED00DCD162 /* SDL_copying.h in Headers */, - A7D8AB8123E2514100DCD162 /* SDL_offscreenframebuffer_c.h in Headers */, - A7D8AEF623E2514100DCD162 /* SDL_cocoamodes.h in Headers */, - A7D8ABFF23E2514100DCD162 /* SDL_nullevents_c.h in Headers */, - A7D8AC6B23E2514100DCD162 /* SDL_uikitmodes.h in Headers */, - A7D88BDD23E24BED00DCD162 /* SDL_cpuinfo.h in Headers */, - A7D8BA5723E2514400DCD162 /* SDL_gles2funcs.h in Headers */, - A7D8B8A423E2514400DCD162 /* SDL_diskaudio.h in Headers */, - A7D8B9D923E2514400DCD162 /* SDL_sysrender.h in Headers */, - A7D8BB2323E2514500DCD162 /* scancodes_windows.h in Headers */, - A7D8ADEE23E2514100DCD162 /* SDL_blit_slow.h in Headers */, - A7D8B20E23E2514200DCD162 /* SDL_x11clipboard.h in Headers */, + A7D88BD023E24BED00DCD162 /* SDL_assert.h in Headers */, A7D8B61923E2514300DCD162 /* SDL_assert_c.h in Headers */, - A7D8BA3323E2514400DCD162 /* SDL_rotate.h in Headers */, + A7D88BD123E24BED00DCD162 /* SDL_atomic.h in Headers */, + A7D88BD423E24BED00DCD162 /* SDL_audio.h in Headers */, + A7D8B7A223E2514400DCD162 /* SDL_audio_c.h in Headers */, + A7D8B7B423E2514400DCD162 /* SDL_audiodev_c.h in Headers */, + A7D88BD523E24BED00DCD162 /* SDL_bits.h in Headers */, + A7D8BA0323E2514400DCD162 /* SDL_blendfillrect.h in Headers */, + A7D8B9EB23E2514400DCD162 /* SDL_blendline.h in Headers */, + F316ABC62B5A02C3002EF551 /* yuv_rgb_std.h in Headers */, + A7D88BD623E24BED00DCD162 /* SDL_blendmode.h in Headers */, + A7D8BA0F23E2514400DCD162 /* SDL_blendpoint.h in Headers */, + A7D8B3B823E2514200DCD162 /* SDL_blit.h in Headers */, + A7D8B2BC23E2514200DCD162 /* SDL_blit_auto.h in Headers */, + A7D8B39A23E2514200DCD162 /* SDL_blit_copy.h in Headers */, + F3820729284F3643004DD584 /* SDL_guid.h in Headers */, + A7D8ADEE23E2514100DCD162 /* SDL_blit_slow.h in Headers */, + A7D88BD823E24BED00DCD162 /* SDL_clipboard.h in Headers */, + A7D8BB7123E2514500DCD162 /* SDL_clipboardevents_c.h in Headers */, + A7D8AECC23E2514100DCD162 /* SDL_cocoaclipboard.h in Headers */, + A7D8AF1423E2514100DCD162 /* SDL_cocoaevents.h in Headers */, + A7D8AE9023E2514100DCD162 /* SDL_cocoakeyboard.h in Headers */, + A7D8AF0823E2514100DCD162 /* SDL_cocoamessagebox.h in Headers */, + A7D8AEB423E2514100DCD162 /* SDL_cocoametalview.h in Headers */, + A7D8AEF623E2514100DCD162 /* SDL_cocoamodes.h in Headers */, + A7D8AF2023E2514100DCD162 /* SDL_cocoamouse.h in Headers */, + A7D8AEDE23E2514100DCD162 /* SDL_cocoaopengl.h in Headers */, + A7D8AEF023E2514100DCD162 /* SDL_cocoaopengles.h in Headers */, + A7D8AE8423E2514100DCD162 /* SDL_cocoashape.h in Headers */, + A7D8AF0223E2514100DCD162 /* SDL_cocoavideo.h in Headers */, + A7D8AEEA23E2514100DCD162 /* SDL_cocoavulkan.h in Headers */, + A7D8AEFC23E2514100DCD162 /* SDL_cocoawindow.h in Headers */, + A7D88BDA23E24BED00DCD162 /* SDL_config.h in Headers */, + A75FDAF723E35EC400529352 /* SDL_config_iphoneos.h in Headers */, + A7D88BDC23E24BED00DCD162 /* SDL_copying.h in Headers */, + A7D8B8CE23E2514400DCD162 /* SDL_coreaudio.h in Headers */, + A7D8A97123E2514000DCD162 /* SDL_coremotionsensor.h in Headers */, + A7D88BDD23E24BED00DCD162 /* SDL_cpuinfo.h in Headers */, + F31A92CA28D4CB39003BFD6A /* SDL_offscreenopengles.h in Headers */, + A7D8B98223E2514400DCD162 /* SDL_d3dmath.h in Headers */, + A7D8A94723E2514000DCD162 /* SDL_dataqueue.h in Headers */, + A7D8B8A423E2514400DCD162 /* SDL_diskaudio.h in Headers */, + A7D8BB4123E2514500DCD162 /* SDL_displayevents_c.h in Headers */, + A7D8BA1B23E2514400DCD162 /* SDL_draw.h in Headers */, A7D8BA0923E2514400DCD162 /* SDL_drawline.h in Headers */, - A7D8B1EA23E2514200DCD162 /* SDL_x11window.h in Headers */, - A7D8AB7B23E2514100DCD162 /* SDL_offscreenopengl.h in Headers */, - A7D8B1F023E2514200DCD162 /* SDL_x11framebuffer.h in Headers */, - A7D8BB8923E2514500DCD162 /* SDL_keyboard_c.h in Headers */, - A7D88BDE23E24BED00DCD162 /* SDL_endian.h in Headers */, + F316ABBD2B5A02C3002EF551 /* yuv_rgb_sse.h in Headers */, + A7D8B9F123E2514400DCD162 /* SDL_drawpoint.h in Headers */, + A7D8BB2F23E2514500DCD162 /* SDL_dropevents_c.h in Headers */, + A7D8B79623E2514400DCD162 /* SDL_dummyaudio.h in Headers */, + A7D8A96523E2514000DCD162 /* SDL_dummysensor.h in Headers */, A7D8AB0C23E2514100DCD162 /* SDL_dynapi.h in Headers */, - A7D8AB6F23E2514100DCD162 /* SDL_offscreenvideo.h in Headers */, + A7D8AB1223E2514100DCD162 /* SDL_dynapi_overrides.h in Headers */, + A7D8AB1E23E2514100DCD162 /* SDL_dynapi_procs.h in Headers */, + A7D88BD723E24BED00DCD162 /* SDL_egl.h in Headers */, + A7D8ABDB23E2514100DCD162 /* SDL_egl_c.h in Headers */, + A7D88BDE23E24BED00DCD162 /* SDL_endian.h in Headers */, A7D88BDF23E24BED00DCD162 /* SDL_error.h in Headers */, - A7D8ACA123E2514100DCD162 /* keyinfotable.h in Headers */, - A7D8B26223E2514200DCD162 /* vulkan.h in Headers */, + A7D8A95F23E2514000DCD162 /* SDL_error_c.h in Headers */, A7D88BE023E24BED00DCD162 /* SDL_events.h in Headers */, A7D8BBA723E2514500DCD162 /* SDL_events_c.h in Headers */, - A7D8B23E23E2514200DCD162 /* egl.h in Headers */, - A7D8ABDB23E2514100DCD162 /* SDL_egl_c.h in Headers */, - A7D8A98F23E2514000DCD162 /* SDL_sensor_c.h in Headers */, A7D88BE123E24BED00DCD162 /* SDL_filesystem.h in Headers */, - A7D8B28023E2514200DCD162 /* vulkan_win32.h in Headers */, A7D88BE223E24BED00DCD162 /* SDL_gamecontroller.h in Headers */, - A7D8B79623E2514400DCD162 /* SDL_dummyaudio.h in Headers */, - A7D8B26823E2514200DCD162 /* vk_platform.h in Headers */, + A7D8B4AE23E2514300DCD162 /* SDL_gamecontrollerdb.h in Headers */, A7D88BE323E24BED00DCD162 /* SDL_gesture.h in Headers */, + A7D8BB3B23E2514500DCD162 /* SDL_gesture_c.h in Headers */, + A7D8BA5723E2514400DCD162 /* SDL_gles2funcs.h in Headers */, + A7D8BA4523E2514400DCD162 /* SDL_glesfuncs.h in Headers */, + A7D8BA7B23E2514400DCD162 /* SDL_glfuncs.h in Headers */, A7D88BE423E24BED00DCD162 /* SDL_haptic.h in Headers */, - A7D8BB4723E2514500DCD162 /* blank_cursor.h in Headers */, - A7D8BB5F23E2514500DCD162 /* scancodes_linux.h in Headers */, - A7D88BE523E24BED00DCD162 /* SDL_hints.h in Headers */, - A7D8B2A423E2514200DCD162 /* vulkan_ios.h in Headers */, - A7D8ACBF23E2514100DCD162 /* SDL_uikitevents.h in Headers */, - A7D8B98223E2514400DCD162 /* SDL_d3dmath.h in Headers */, - A7D8B4EA23E2514300DCD162 /* SDL_sysjoystick_c.h in Headers */, - A7D88BE623E24BED00DCD162 /* SDL_joystick.h in Headers */, - A7D8B5B923E2514300DCD162 /* controller_type.h in Headers */, - A7D8AEF023E2514100DCD162 /* SDL_cocoaopengles.h in Headers */, - A7D8AECC23E2514100DCD162 /* SDL_cocoaclipboard.h in Headers */, - A7D8AEFC23E2514100DCD162 /* SDL_cocoawindow.h in Headers */, - A7D88BE723E24BED00DCD162 /* SDL_keyboard.h in Headers */, - A7D8B22623E2514200DCD162 /* gl2ext.h in Headers */, - A7D8B3D023E2514300DCD162 /* yuv_rgb_std_func.h in Headers */, - A7D88BE923E24BED00DCD162 /* SDL_sensor.h in Headers */, - A7D88BEA23E24BED00DCD162 /* SDL_metal.h in Headers */, - A7D88BEB23E24BED00DCD162 /* SDL_keycode.h in Headers */, - A7D8BB4123E2514500DCD162 /* SDL_displayevents_c.h in Headers */, - A7D88BED23E24BED00DCD162 /* SDL_loadso.h in Headers */, - A7D8B23223E2514200DCD162 /* gl2platform.h in Headers */, - A7D8AAD623E2514100DCD162 /* SDL_syshaptic.h in Headers */, - A7D8B57D23E2514300DCD162 /* SDL_sysjoystick_c.h in Headers */, - A7D8B1AE23E2514200DCD162 /* SDL_x11sym.h in Headers */, - A7D8B86E23E2514400DCD162 /* SDL_wave.h in Headers */, - A7D8B1FC23E2514200DCD162 /* SDL_x11mouse.h in Headers */, - A7D8B25C23E2514200DCD162 /* vulkan_vi.h in Headers */, - A7D8B14E23E2514200DCD162 /* SDL_x11messagebox.h in Headers */, - A7D88BEF23E24BED00DCD162 /* SDL_log.h in Headers */, - A7D8BB4D23E2514500DCD162 /* default_cursor.h in Headers */, - A7D8AEB423E2514100DCD162 /* SDL_cocoametalview.h in Headers */, - A7D8B3D623E2514300DCD162 /* yuv_rgb.h in Headers */, - A7D8B1D223E2514200DCD162 /* SDL_x11xinput2.h in Headers */, - A7D8B25623E2514200DCD162 /* vk_icd.h in Headers */, - A7D8B2B023E2514200DCD162 /* vk_sdk_platform.h in Headers */, - A7D8BB2F23E2514500DCD162 /* SDL_dropevents_c.h in Headers */, - A7D8B61323E2514300DCD162 /* SDL_syspower.h in Headers */, - A7D8ACE323E2514100DCD162 /* SDL_uikitvulkan.h in Headers */, - A7D8BB6523E2514500DCD162 /* SDL_touch_c.h in Headers */, - A7D8B29E23E2514200DCD162 /* vulkan_xlib.h in Headers */, - A7D8AE8423E2514100DCD162 /* SDL_cocoashape.h in Headers */, - A7D88BF123E24BED00DCD162 /* SDL_main.h in Headers */, - A7D8ABE723E2514100DCD162 /* SDL_nullframebuffer_c.h in Headers */, - A7D8AC7D23E2514100DCD162 /* SDL_uikitvideo.h in Headers */, - A7D88BF223E24BED00DCD162 /* SDL_messagebox.h in Headers */, - A7D8B28623E2514200DCD162 /* vulkan_macos.h in Headers */, - A7D88BF323E24BED00DCD162 /* SDL_mouse.h in Headers */, - A7D88BF423E24BED00DCD162 /* SDL_mutex.h in Headers */, - A7D8AC5F23E2514100DCD162 /* SDL_uikitmetalview.h in Headers */, - A7D8B58923E2514300DCD162 /* SDL_joystick_c.h in Headers */, - A7D88BF523E24BED00DCD162 /* SDL_name.h in Headers */, + A7D8AABE23E2514100DCD162 /* SDL_haptic_c.h in Headers */, + F316AB902B5A02C3002EF551 /* yuv_rgb_internal.h in Headers */, A75FDBC723EA380300529352 /* SDL_hidapi_rumble.h in Headers */, - A7D8A97123E2514000DCD162 /* SDL_coremotionsensor.h in Headers */, - A7D8B98E23E2514400DCD162 /* SDL_shaders_metal_ios.h in Headers */, - A7D8AF1423E2514100DCD162 /* SDL_cocoaevents.h in Headers */, - A7D8BA7523E2514400DCD162 /* SDL_shaders_gl.h in Headers */, - A7D8AC4723E2514100DCD162 /* SDL_uikitview.h in Headers */, + A7D8B55923E2514300DCD162 /* SDL_hidapijoystick_c.h in Headers */, + A7D88BE523E24BED00DCD162 /* SDL_hints.h in Headers */, + A7D8B94C23E2514400DCD162 /* SDL_hints_c.h in Headers */, + F316ABCF2B5A02C3002EF551 /* yuv_rgb_lsx_func.h in Headers */, + A7D8A99B23E2514000DCD162 /* SDL_internal.h in Headers */, + F395C1952569C68F00942BFF /* SDL_iokitjoystick_c.h in Headers */, + A7D88BE623E24BED00DCD162 /* SDL_joystick.h in Headers */, + A7D8B58923E2514300DCD162 /* SDL_joystick_c.h in Headers */, + F316AB872B5A02C3002EF551 /* yuv_rgb_common.h in Headers */, + A7D88BE723E24BED00DCD162 /* SDL_keyboard.h in Headers */, + A7D8BB8923E2514500DCD162 /* SDL_keyboard_c.h in Headers */, + A7D88BEB23E24BED00DCD162 /* SDL_keycode.h in Headers */, + A7D88BED23E24BED00DCD162 /* SDL_loadso.h in Headers */, + F3631C652488534E004F28EA /* SDL_locale.h in Headers */, + A7D88BEF23E24BED00DCD162 /* SDL_log.h in Headers */, + A7D88BF123E24BED00DCD162 /* SDL_main.h in Headers */, + A7D88BF223E24BED00DCD162 /* SDL_messagebox.h in Headers */, + F386F6E92884663E001840AA /* SDL_log_c.h in Headers */, + A7D88BEA23E24BED00DCD162 /* SDL_metal.h in Headers */, + F395C1BC2569C6A000942BFF /* SDL_mfijoystick_c.h in Headers */, + F392819F25860422003191A7 /* SDL_misc.h in Headers */, + A7D88BF323E24BED00DCD162 /* SDL_mouse.h in Headers */, + A7D8BB1D23E2514500DCD162 /* SDL_mouse_c.h in Headers */, + F38233872738EB8600F7F527 /* SDL_hidapi.h in Headers */, + A7D88BF423E24BED00DCD162 /* SDL_mutex.h in Headers */, + A7D88BF523E24BED00DCD162 /* SDL_name.h in Headers */, + A7D8ABFF23E2514100DCD162 /* SDL_nullevents_c.h in Headers */, + A7D8ABE723E2514100DCD162 /* SDL_nullframebuffer_c.h in Headers */, + A7D8ABF923E2514100DCD162 /* SDL_nullvideo.h in Headers */, + A7D8AB5D23E2514100DCD162 /* SDL_offscreenevents_c.h in Headers */, + A7D8AB8123E2514100DCD162 /* SDL_offscreenframebuffer_c.h in Headers */, + A7D8AB6F23E2514100DCD162 /* SDL_offscreenvideo.h in Headers */, + A7D8AB8723E2514100DCD162 /* SDL_offscreenwindow.h in Headers */, A7D88BF623E24BED00DCD162 /* SDL_opengl.h in Headers */, - A7D8AC0523E2514100DCD162 /* SDL_rect_c.h in Headers */, - A7D8A97D23E2514000DCD162 /* SDL_syssensor.h in Headers */, A7D88BF723E24BED00DCD162 /* SDL_opengl_glext.h in Headers */, A7D88BF823E24BED00DCD162 /* SDL_opengles.h in Headers */, - A7D8B58323E2514300DCD162 /* SDL_sysjoystick.h in Headers */, A7D88BF923E24BED00DCD162 /* SDL_opengles2.h in Headers */, - A7D8A94723E2514000DCD162 /* SDL_dataqueue.h in Headers */, - A7D8B25023E2514200DCD162 /* vk_layer.h in Headers */, A7D88BFA23E24BED00DCD162 /* SDL_opengles2_gl2.h in Headers */, - A7D8BBA123E2514500DCD162 /* scancodes_xfree86.h in Headers */, - A7D8AF2023E2514100DCD162 /* SDL_cocoamouse.h in Headers */, - A7D8AE9023E2514100DCD162 /* SDL_cocoakeyboard.h in Headers */, - A7D8BA5123E2514400DCD162 /* SDL_shaders_gles2.h in Headers */, A7D88BFB23E24BED00DCD162 /* SDL_opengles2_gl2ext.h in Headers */, - A7D8B29823E2514200DCD162 /* vulkan_mir.h in Headers */, A7D88BFC23E24BED00DCD162 /* SDL_opengles2_gl2platform.h in Headers */, - A7D8BA1B23E2514400DCD162 /* SDL_draw.h in Headers */, - A7D8BB5323E2514500DCD162 /* scancodes_darwin.h in Headers */, - A7D8BB9523E2514500DCD162 /* SDL_sysevents.h in Headers */, - A7D8B7A223E2514400DCD162 /* SDL_audio_c.h in Headers */, - A7D8B17223E2514200DCD162 /* SDL_x11opengles.h in Headers */, - A7D8B29223E2514200DCD162 /* vulkan_xcb.h in Headers */, - A7D8AAE223E2514100DCD162 /* SDL_syshaptic_c.h in Headers */, - A7D8BB1D23E2514500DCD162 /* SDL_mouse_c.h in Headers */, - A7D8BA0323E2514400DCD162 /* SDL_blendfillrect.h in Headers */, - A7D8B27A23E2514200DCD162 /* vulkan_wayland.h in Headers */, - A7D8B5C523E2514300DCD162 /* SDL_rwopsbundlesupport.h in Headers */, A7D88BFD23E24BED00DCD162 /* SDL_opengles2_khrplatform.h in Headers */, - A7D8B23823E2514200DCD162 /* khrplatform.h in Headers */, A7D88BFE23E24BED00DCD162 /* SDL_pixels.h in Headers */, - A7D8ABF923E2514100DCD162 /* SDL_nullvideo.h in Headers */, - A7D8B57123E2514300DCD162 /* usb_ids.h in Headers */, - A7D8B7B423E2514400DCD162 /* SDL_audiodev_c.h in Headers */, + A7D8B2C223E2514200DCD162 /* SDL_pixels_c.h in Headers */, A7D88BFF23E24BED00DCD162 /* SDL_platform.h in Headers */, A7D88C0023E24BED00DCD162 /* SDL_power.h in Headers */, - A7D8AC9B23E2514100DCD162 /* SDL_uikitwindow.h in Headers */, A7D88C0123E24BED00DCD162 /* SDL_quit.h in Headers */, - A7D8AB1223E2514100DCD162 /* SDL_dynapi_overrides.h in Headers */, A7D88C0223E24BED00DCD162 /* SDL_rect.h in Headers */, - A7D8B27423E2514200DCD162 /* vulkan_fuchsia.h in Headers */, - A7D8B28C23E2514200DCD162 /* vulkan_xlib_xrandr.h in Headers */, - A7D8B5D723E2514300DCD162 /* SDL_syspower.h in Headers */, + A7D8AC0523E2514100DCD162 /* SDL_rect_c.h in Headers */, A7D88C0423E24BED00DCD162 /* SDL_render.h in Headers */, - A7D8B26E23E2514200DCD162 /* vulkan.hpp in Headers */, + A7D8B9FD23E2514400DCD162 /* SDL_render_sw_c.h in Headers */, A7D88C0523E24BED00DCD162 /* SDL_revision.h in Headers */, - A7D8AB3323E2514100DCD162 /* SDL_timer_c.h in Headers */, - A7D8B16623E2514200DCD162 /* SDL_x11shape.h in Headers */, - A7D8AB1E23E2514100DCD162 /* SDL_dynapi_procs.h in Headers */, - A7D8BB0523E2514500DCD162 /* math_libm.h in Headers */, + A7D8BA3323E2514400DCD162 /* SDL_rotate.h in Headers */, + F3973FA428A59BDD00B84553 /* SDL_vacopy.h in Headers */, A7D88C0723E24BED00DCD162 /* SDL_rwops.h in Headers */, - A7D8B3CA23E2514300DCD162 /* yuv_rgb_sse_func.h in Headers */, - A7D8AF0823E2514100DCD162 /* SDL_cocoamessagebox.h in Headers */, - A7D8B1D823E2514200DCD162 /* edid.h in Headers */, + A7D8B5C523E2514300DCD162 /* SDL_rwopsbundlesupport.h in Headers */, A7D88C0823E24BED00DCD162 /* SDL_scancode.h in Headers */, - A7D8B39A23E2514200DCD162 /* SDL_blit_copy.h in Headers */, - A7D8B22C23E2514200DCD162 /* gl2.h in Headers */, + A7D88BE923E24BED00DCD162 /* SDL_sensor.h in Headers */, + A7D8A98F23E2514000DCD162 /* SDL_sensor_c.h in Headers */, + F386F6F22884663E001840AA /* SDL_utils_c.h in Headers */, + A7D8BA7523E2514400DCD162 /* SDL_shaders_gl.h in Headers */, + A7D8BA5123E2514400DCD162 /* SDL_shaders_gles2.h in Headers */, + A1BB8B6E27F6CF330057CFA8 /* SDL_list.h in Headers */, + A7D8B98E23E2514400DCD162 /* SDL_shaders_metal_ios.h in Headers */, + A7D8B99D23E2514400DCD162 /* SDL_shaders_metal_osx.h in Headers */, + A7D8B9A323E2514400DCD162 /* SDL_shaders_metal_tvos.h in Headers */, A7D88C0A23E24BED00DCD162 /* SDL_shape.h in Headers */, - A7D88C0C23E24BED00DCD162 /* SDL_stdinc.h in Headers */, - A7D8ACCB23E2514100DCD162 /* SDL_uikitappdelegate.h in Headers */, - A7D8B3B223E2514200DCD162 /* SDL_yuv_c.h in Headers */, - A7D8B1F623E2514200DCD162 /* SDL_x11dyn.h in Headers */, - A7D8AC8923E2514100DCD162 /* SDL_uikitviewcontroller.h in Headers */, A7D8AC0B23E2514100DCD162 /* SDL_shape_internals.h in Headers */, - A7D8A95F23E2514000DCD162 /* SDL_error_c.h in Headers */, - A7D8B2AA23E2514200DCD162 /* vulkan_core.h in Headers */, - A7D8B3EE23E2514300DCD162 /* SDL_thread_c.h in Headers */, + A7D88C0C23E24BED00DCD162 /* SDL_stdinc.h in Headers */, + A7D8B4C623E2514300DCD162 /* SDL_steamcontroller.h in Headers */, A7D88C0D23E24BED00DCD162 /* SDL_surface.h in Headers */, - A7D8BB7123E2514500DCD162 /* SDL_clipboardevents_c.h in Headers */, - A7D8AB5D23E2514100DCD162 /* SDL_offscreenevents_c.h in Headers */, - A7D8AEEA23E2514100DCD162 /* SDL_cocoavulkan.h in Headers */, + A7D8B85C23E2514400DCD162 /* SDL_sysaudio.h in Headers */, + A7D8AAD623E2514100DCD162 /* SDL_syshaptic.h in Headers */, + A7D8AAE223E2514100DCD162 /* SDL_syshaptic_c.h in Headers */, + A7D8B58323E2514300DCD162 /* SDL_sysjoystick.h in Headers */, + 560572182473688B00B46B66 /* SDL_syslocale.h in Headers */, + A7D8B44223E2514300DCD162 /* SDL_sysmutex_c.h in Headers */, + A7D8B5D723E2514300DCD162 /* SDL_syspower.h in Headers */, + A7D8B61323E2514300DCD162 /* SDL_syspower.h in Headers */, + A7D8B9D923E2514400DCD162 /* SDL_sysrender.h in Headers */, + F362B9482B33920500D30B94 /* SDL_hidapi_nintendo.h in Headers */, + F316ABAB2B5A02C3002EF551 /* yuv_rgb_lsx.h in Headers */, + A7D8A97D23E2514000DCD162 /* SDL_syssensor.h in Headers */, A7D88C0E23E24BED00DCD162 /* SDL_system.h in Headers */, - A7D8BA7B23E2514400DCD162 /* SDL_glfuncs.h in Headers */, - A7D8B2C223E2514200DCD162 /* SDL_pixels_c.h in Headers */, + A7D8B3E823E2514300DCD162 /* SDL_systhread.h in Headers */, + A7D8B42A23E2514300DCD162 /* SDL_systhread_c.h in Headers */, + 5616CA54252BB35B005D5928 /* SDL_sysurl.h in Headers */, + A7D8AC4123E2514100DCD162 /* SDL_sysvideo.h in Headers */, A7D88C0F23E24BED00DCD162 /* SDL_syswm.h in Headers */, A7D88C1123E24BED00DCD162 /* SDL_thread.h in Headers */, - A7D8ACD723E2514100DCD162 /* SDL_uikitopengles.h in Headers */, + A7D8B3EE23E2514300DCD162 /* SDL_thread_c.h in Headers */, A7D88C1223E24BED00DCD162 /* SDL_timer.h in Headers */, - A7D8B21423E2514200DCD162 /* SDL_x11events.h in Headers */, + A7D8AB3323E2514100DCD162 /* SDL_timer_c.h in Headers */, A7D88C1423E24BED00DCD162 /* SDL_touch.h in Headers */, - A7D8A96523E2514000DCD162 /* SDL_dummysensor.h in Headers */, + A7D8BB6523E2514500DCD162 /* SDL_touch_c.h in Headers */, A7D88C1523E24BED00DCD162 /* SDL_types.h in Headers */, - A7D8B42A23E2514300DCD162 /* SDL_systhread_c.h in Headers */, - A7D8B20823E2514200DCD162 /* SDL_x11keyboard.h in Headers */, - A7D8B94C23E2514400DCD162 /* SDL_hints_c.h in Headers */, - A7D8AD1F23E2514100DCD162 /* SDL_vulkan_internal.h in Headers */, - A7D8B9EB23E2514400DCD162 /* SDL_blendline.h in Headers */, + A7D8ACCB23E2514100DCD162 /* SDL_uikitappdelegate.h in Headers */, + A7D8AC7723E2514100DCD162 /* SDL_uikitclipboard.h in Headers */, + A7D8ACBF23E2514100DCD162 /* SDL_uikitevents.h in Headers */, + A7D8AC9523E2514100DCD162 /* SDL_uikitmessagebox.h in Headers */, + A7D8AC5F23E2514100DCD162 /* SDL_uikitmetalview.h in Headers */, + A7D8AC6B23E2514100DCD162 /* SDL_uikitmodes.h in Headers */, + A7D8ACD723E2514100DCD162 /* SDL_uikitopengles.h in Headers */, + A7D8ACB323E2514100DCD162 /* SDL_uikitopenglview.h in Headers */, + A7D8AC7D23E2514100DCD162 /* SDL_uikitvideo.h in Headers */, + A7D8AC4723E2514100DCD162 /* SDL_uikitview.h in Headers */, + A7D8AC8923E2514100DCD162 /* SDL_uikitviewcontroller.h in Headers */, + A7D8ACE323E2514100DCD162 /* SDL_uikitvulkan.h in Headers */, + A7D8AC9B23E2514100DCD162 /* SDL_uikitwindow.h in Headers */, A7D88C1623E24BED00DCD162 /* SDL_version.h in Headers */, A7D88C1723E24BED00DCD162 /* SDL_video.h in Headers */, - A7D8B24A23E2514200DCD162 /* eglplatform.h in Headers */, - A7D8AC9523E2514100DCD162 /* SDL_uikitmessagebox.h in Headers */, - A7D8B1DE23E2514200DCD162 /* SDL_x11vulkan.h in Headers */, - A7D8B55923E2514300DCD162 /* SDL_hidapijoystick_c.h in Headers */, - A7D8B21A23E2514200DCD162 /* imKStoUCS.h in Headers */, - A7D8B1B423E2514200DCD162 /* SDL_x11opengl.h in Headers */, + 75E09165241EA924004729E1 /* SDL_virtualjoystick_c.h in Headers */, A7D88C1923E24BED00DCD162 /* SDL_vulkan.h in Headers */, - A7D8B99D23E2514400DCD162 /* SDL_shaders_metal_osx.h in Headers */, - A7D8A99B23E2514000DCD162 /* SDL_internal.h in Headers */, + A7D8AD1F23E2514100DCD162 /* SDL_vulkan_internal.h in Headers */, + A7D8B86E23E2514400DCD162 /* SDL_wave.h in Headers */, + A7D8BBAD23E2514500DCD162 /* SDL_windowevents_c.h in Headers */, + A7D8B3B223E2514200DCD162 /* SDL_yuv_c.h in Headers */, + A7D8B9CD23E2514400DCD162 /* SDL_yuv_sw_c.h in Headers */, + A7D88BCC23E24BED00DCD162 /* begin_code.h in Headers */, + A7D8BB4723E2514500DCD162 /* blank_cursor.h in Headers */, + F362B9542B33EB7300D30B94 /* SDL_steam_virtual_gamepad.h in Headers */, + A7D88BCE23E24BED00DCD162 /* close_code.h in Headers */, + A7D8B5B923E2514300DCD162 /* controller_type.h in Headers */, + A7D8BB4D23E2514500DCD162 /* default_cursor.h in Headers */, + A7D8B23E23E2514200DCD162 /* egl.h in Headers */, + A7D8B24423E2514200DCD162 /* eglext.h in Headers */, + A7D8B24A23E2514200DCD162 /* eglplatform.h in Headers */, + A7D8B22C23E2514200DCD162 /* gl2.h in Headers */, + A7D8B22623E2514200DCD162 /* gl2ext.h in Headers */, + A7D8B23223E2514200DCD162 /* gl2platform.h in Headers */, + A75FDB5A23E39E6100529352 /* hidapi.h in Headers */, + A7D8B23823E2514200DCD162 /* khrplatform.h in Headers */, + A7D8BB0523E2514500DCD162 /* math_libm.h in Headers */, + A7D8BAC323E2514500DCD162 /* math_private.h in Headers */, + A7D8BB5323E2514500DCD162 /* scancodes_darwin.h in Headers */, + A7D8BB5F23E2514500DCD162 /* scancodes_linux.h in Headers */, + A7D8BB2323E2514500DCD162 /* scancodes_windows.h in Headers */, + A7D8BBA123E2514500DCD162 /* scancodes_xfree86.h in Headers */, + A7D8B57123E2514300DCD162 /* usb_ids.h in Headers */, + A1626A542617008D003F1973 /* SDL_triangle.h in Headers */, + A7D8B25623E2514200DCD162 /* vk_icd.h in Headers */, + A7D8B25023E2514200DCD162 /* vk_layer.h in Headers */, + A7D8B26823E2514200DCD162 /* vk_platform.h in Headers */, + A7D8B2B023E2514200DCD162 /* vk_sdk_platform.h in Headers */, + A7D8B26223E2514200DCD162 /* vulkan.h in Headers */, + A7D8B2B623E2514200DCD162 /* vulkan_android.h in Headers */, + A7D8B2AA23E2514200DCD162 /* vulkan_core.h in Headers */, + A7D8B27423E2514200DCD162 /* vulkan_fuchsia.h in Headers */, + A7D8B2A423E2514200DCD162 /* vulkan_ios.h in Headers */, + A7D8B28623E2514200DCD162 /* vulkan_macos.h in Headers */, + A7D8B25C23E2514200DCD162 /* vulkan_vi.h in Headers */, + A7D8B27A23E2514200DCD162 /* vulkan_wayland.h in Headers */, + A7D8B28023E2514200DCD162 /* vulkan_win32.h in Headers */, + F362B9342B33916600D30B94 /* controller_list.h in Headers */, + A7D8B29223E2514200DCD162 /* vulkan_xcb.h in Headers */, + A7D8B29E23E2514200DCD162 /* vulkan_xlib.h in Headers */, + A7D8B28C23E2514200DCD162 /* vulkan_xlib_xrandr.h in Headers */, + A7D8B3D623E2514300DCD162 /* yuv_rgb.h in Headers */, + A7D8B3CA23E2514300DCD162 /* yuv_rgb_sse_func.h in Headers */, + A7D8B3D023E2514300DCD162 /* yuv_rgb_std_func.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -6904,90 +6622,58 @@ buildActionMask = 2147483647; files = ( A7D8B9A523E2514400DCD162 /* SDL_shaders_metal_tvos.h in Headers */, - A7D88D1923E24D3B00DCD162 /* SDL_filesystem.h in Headers */, - A7D88D1A23E24D3B00DCD162 /* begin_code.h in Headers */, A7D8ACD923E2514100DCD162 /* SDL_uikitopengles.h in Headers */, - A7D88D1B23E24D3B00DCD162 /* close_code.h in Headers */, - A7D88D1C23E24D3B00DCD162 /* SDL.h in Headers */, A7D8AC6123E2514100DCD162 /* SDL_uikitmetalview.h in Headers */, - A7D88D1D23E24D3B00DCD162 /* SDL_assert.h in Headers */, A7D8AC0D23E2514100DCD162 /* SDL_shape_internals.h in Headers */, A7D8BA7D23E2514400DCD162 /* SDL_glfuncs.h in Headers */, - A7D88D1E23E24D3B00DCD162 /* SDL_atomic.h in Headers */, A7D8AC0723E2514100DCD162 /* SDL_rect_c.h in Headers */, - A7D8B1D423E2514200DCD162 /* SDL_x11xinput2.h in Headers */, A7D8B99F23E2514400DCD162 /* SDL_shaders_metal_osx.h in Headers */, A7D8B99023E2514400DCD162 /* SDL_shaders_metal_ios.h in Headers */, A7D8AB8923E2514100DCD162 /* SDL_offscreenwindow.h in Headers */, - A7D88D1F23E24D3B00DCD162 /* SDL_audio.h in Headers */, A7D8A97323E2514000DCD162 /* SDL_coremotionsensor.h in Headers */, A7D8AC4923E2514100DCD162 /* SDL_uikitview.h in Headers */, - A7D88D2023E24D3B00DCD162 /* SDL_bits.h in Headers */, A7D8ACCD23E2514100DCD162 /* SDL_uikitappdelegate.h in Headers */, - A7D8ACA323E2514100DCD162 /* keyinfotable.h in Headers */, - A7D88D2123E24D3B00DCD162 /* SDL_blendmode.h in Headers */, A7D8BB3123E2514500DCD162 /* SDL_dropevents_c.h in Headers */, A7D8AAC023E2514100DCD162 /* SDL_haptic_c.h in Headers */, - A7D88D2223E24D3B00DCD162 /* SDL_clipboard.h in Headers */, A7D8A94923E2514000DCD162 /* SDL_dataqueue.h in Headers */, A7D8A96123E2514000DCD162 /* SDL_error_c.h in Headers */, - A7D8B21623E2514200DCD162 /* SDL_x11events.h in Headers */, - A7D88D2323E24D3B00DCD162 /* SDL_config.h in Headers */, A7D8B98423E2514400DCD162 /* SDL_d3dmath.h in Headers */, - A7D8B1EC23E2514200DCD162 /* SDL_x11window.h in Headers */, A7D8ABDD23E2514100DCD162 /* SDL_egl_c.h in Headers */, - A7D88D2623E24D3B00DCD162 /* SDL_copying.h in Headers */, A7D8B3D823E2514300DCD162 /* yuv_rgb.h in Headers */, A7D8B79823E2514400DCD162 /* SDL_dummyaudio.h in Headers */, A7D8AC9723E2514100DCD162 /* SDL_uikitmessagebox.h in Headers */, - A7D8B15023E2514200DCD162 /* SDL_x11messagebox.h in Headers */, A7D8B3F023E2514300DCD162 /* SDL_thread_c.h in Headers */, A7D8AF0A23E2514100DCD162 /* SDL_cocoamessagebox.h in Headers */, - A7D8B16823E2514200DCD162 /* SDL_x11shape.h in Headers */, - A7D88D2723E24D3B00DCD162 /* SDL_cpuinfo.h in Headers */, - A7D88D2823E24D3B00DCD162 /* SDL_endian.h in Headers */, - A7D88D2923E24D3B00DCD162 /* SDL_error.h in Headers */, - A7D88D2A23E24D3B00DCD162 /* SDL_events.h in Headers */, A7D8BA0523E2514400DCD162 /* SDL_blendfillrect.h in Headers */, - A7D88D2B23E24D3B00DCD162 /* SDL_gamecontroller.h in Headers */, A7D8B55B23E2514300DCD162 /* SDL_hidapijoystick_c.h in Headers */, A7D8B2C423E2514200DCD162 /* SDL_pixels_c.h in Headers */, - A7D8B1BC23E2514200DCD162 /* SDL_x11modes.h in Headers */, A7D8B58B23E2514300DCD162 /* SDL_joystick_c.h in Headers */, + F395C1972569C68F00942BFF /* SDL_iokitjoystick_c.h in Headers */, A7D8B2B223E2514200DCD162 /* vk_sdk_platform.h in Headers */, A7D8BB4923E2514500DCD162 /* blank_cursor.h in Headers */, A75FDB5C23E39E6100529352 /* hidapi.h in Headers */, - A7D88D2C23E24D3B00DCD162 /* SDL_gesture.h in Headers */, A75FDBC923EA380300529352 /* SDL_hidapi_rumble.h in Headers */, A7D8B85E23E2514400DCD162 /* SDL_sysaudio.h in Headers */, - A7D88D2D23E24D3B00DCD162 /* SDL_haptic.h in Headers */, - A7D8BB9723E2514500DCD162 /* SDL_sysevents.h in Headers */, A7D8BB0723E2514500DCD162 /* math_libm.h in Headers */, A7D8AC7F23E2514100DCD162 /* SDL_uikitvideo.h in Headers */, + F316ABBF2B5A02C3002EF551 /* yuv_rgb_sse.h in Headers */, A7D8AF2223E2514100DCD162 /* SDL_cocoamouse.h in Headers */, - A7D88D2E23E24D3B00DCD162 /* SDL_hints.h in Headers */, A7D8ADF023E2514100DCD162 /* SDL_blit_slow.h in Headers */, + F3973FA628A59BDD00B84553 /* SDL_vacopy.h in Headers */, A7D8B9CF23E2514400DCD162 /* SDL_yuv_sw_c.h in Headers */, - A7D8B1B623E2514200DCD162 /* SDL_x11opengl.h in Headers */, A7D8BBAF23E2514500DCD162 /* SDL_windowevents_c.h in Headers */, - A7D88D2F23E24D3B00DCD162 /* SDL_joystick.h in Headers */, A7D8AF0423E2514100DCD162 /* SDL_cocoavideo.h in Headers */, - A7D88D3023E24D3B00DCD162 /* SDL_keyboard.h in Headers */, + 5605721A2473688C00B46B66 /* SDL_syslocale.h in Headers */, + A1BB8B7027F6CF330057CFA8 /* SDL_list.h in Headers */, A7D8ACC123E2514100DCD162 /* SDL_uikitevents.h in Headers */, A7D8BB3D23E2514500DCD162 /* SDL_gesture_c.h in Headers */, A7D8BA7723E2514400DCD162 /* SDL_shaders_gl.h in Headers */, A7D8B42C23E2514300DCD162 /* SDL_systhread_c.h in Headers */, - A7D88D3123E24D3B00DCD162 /* SDL_keycode.h in Headers */, - A7D8B20A23E2514200DCD162 /* SDL_x11keyboard.h in Headers */, A7D8AE9223E2514100DCD162 /* SDL_cocoakeyboard.h in Headers */, + 5616CA5A252BB35D005D5928 /* SDL_sysurl.h in Headers */, A7D8ACE523E2514100DCD162 /* SDL_uikitvulkan.h in Headers */, - A7D8B1F223E2514200DCD162 /* SDL_x11framebuffer.h in Headers */, - A7D8B22223E2514200DCD162 /* SDL_x11video.h in Headers */, - A7D8B27023E2514200DCD162 /* vulkan.hpp in Headers */, - A7D88D3223E24D3B00DCD162 /* SDL_loadso.h in Headers */, A7D8B22823E2514200DCD162 /* gl2ext.h in Headers */, A7D8BB7323E2514500DCD162 /* SDL_clipboardevents_c.h in Headers */, - A7D8B14A23E2514200DCD162 /* SDL_x11touch.h in Headers */, A7D8AAE423E2514100DCD162 /* SDL_syshaptic_c.h in Headers */, A7D8B94E23E2514400DCD162 /* SDL_hints_c.h in Headers */, A7D8B7B623E2514400DCD162 /* SDL_audiodev_c.h in Headers */, @@ -6995,61 +6681,51 @@ A7D8AC6D23E2514100DCD162 /* SDL_uikitmodes.h in Headers */, A7D8B24023E2514200DCD162 /* egl.h in Headers */, A7D8B23A23E2514200DCD162 /* khrplatform.h in Headers */, - A7D88D3323E24D3B00DCD162 /* SDL_log.h in Headers */, A7D8AC8B23E2514100DCD162 /* SDL_uikitviewcontroller.h in Headers */, A7D8A96723E2514000DCD162 /* SDL_dummysensor.h in Headers */, A7D8B4C823E2514300DCD162 /* SDL_steamcontroller.h in Headers */, A7D8B2B823E2514200DCD162 /* vulkan_android.h in Headers */, A7D8B3D223E2514300DCD162 /* yuv_rgb_std_func.h in Headers */, A7D8B2AC23E2514200DCD162 /* vulkan_core.h in Headers */, + F362B9562B33EB7300D30B94 /* SDL_steam_virtual_gamepad.h in Headers */, A7D8A97F23E2514000DCD162 /* SDL_syssensor.h in Headers */, + F316AB892B5A02C3002EF551 /* yuv_rgb_common.h in Headers */, A7D8AB0E23E2514100DCD162 /* SDL_dynapi.h in Headers */, A7D8B61B23E2514300DCD162 /* SDL_assert_c.h in Headers */, A7D8B8A623E2514400DCD162 /* SDL_diskaudio.h in Headers */, - A7D88D3423E24D3B00DCD162 /* SDL_main.h in Headers */, A7D8B9F323E2514400DCD162 /* SDL_drawpoint.h in Headers */, - A7D88D3523E24D3B00DCD162 /* SDL_opengles2_khrplatform.h in Headers */, A7D8B87023E2514400DCD162 /* SDL_wave.h in Headers */, A7D8AEE023E2514100DCD162 /* SDL_cocoaopengl.h in Headers */, + F316ABC82B5A02C3002EF551 /* yuv_rgb_std.h in Headers */, + A1626A562617008D003F1973 /* SDL_triangle.h in Headers */, A7D8B3CC23E2514300DCD162 /* yuv_rgb_sse_func.h in Headers */, - A7D8B21C23E2514200DCD162 /* imKStoUCS.h in Headers */, A7D8AB5F23E2514100DCD162 /* SDL_offscreenevents_c.h in Headers */, - A7D8B1B023E2514200DCD162 /* SDL_x11sym.h in Headers */, A7D8B8D023E2514400DCD162 /* SDL_coreaudio.h in Headers */, A7D8BA1D23E2514400DCD162 /* SDL_draw.h in Headers */, A7D8BA0B23E2514400DCD162 /* SDL_drawline.h in Headers */, - A7D88D3623E24D3B00DCD162 /* SDL_messagebox.h in Headers */, - A7D88D3723E24D3B00DCD162 /* SDL_mouse.h in Headers */, - A7D88D3823E24D3B00DCD162 /* SDL_mutex.h in Headers */, A7D8B3B423E2514200DCD162 /* SDL_yuv_c.h in Headers */, A7D8BBA323E2514500DCD162 /* scancodes_xfree86.h in Headers */, A7D8B5D923E2514300DCD162 /* SDL_syspower.h in Headers */, A75FDAF823E35ED500529352 /* SDL_config_iphoneos.h in Headers */, - A7D8B21023E2514200DCD162 /* SDL_x11clipboard.h in Headers */, - A7D88D3923E24D3B00DCD162 /* SDL_name.h in Headers */, A7D8B24623E2514200DCD162 /* eglext.h in Headers */, A7D8BBA923E2514500DCD162 /* SDL_events_c.h in Headers */, A7D8BAC523E2514500DCD162 /* math_private.h in Headers */, A7D8B27C23E2514200DCD162 /* vulkan_wayland.h in Headers */, - A7D88D3A23E24D3B00DCD162 /* SDL_opengl.h in Headers */, A7D8AE8623E2514100DCD162 /* SDL_cocoashape.h in Headers */, - A7D88D3B23E24D3B00DCD162 /* SDL_opengles.h in Headers */, A7D8BA5323E2514400DCD162 /* SDL_shaders_gles2.h in Headers */, - A7D88D3D23E24D3B00DCD162 /* SDL_opengles2.h in Headers */, A7D8BA4723E2514400DCD162 /* SDL_glesfuncs.h in Headers */, A7D8BA1123E2514400DCD162 /* SDL_blendpoint.h in Headers */, A7D8AB7123E2514100DCD162 /* SDL_offscreenvideo.h in Headers */, A7D8AC0123E2514100DCD162 /* SDL_nullevents_c.h in Headers */, + F316ABD12B5A02C3002EF551 /* yuv_rgb_lsx_func.h in Headers */, A7D8B58523E2514300DCD162 /* SDL_sysjoystick.h in Headers */, A7D8BB6123E2514500DCD162 /* scancodes_linux.h in Headers */, - A7D8B1F823E2514200DCD162 /* SDL_x11dyn.h in Headers */, A7D8BB6723E2514500DCD162 /* SDL_touch_c.h in Headers */, + F362B94A2B33920500D30B94 /* SDL_hidapi_nintendo.h in Headers */, A7D8B4B023E2514300DCD162 /* SDL_gamecontrollerdb.h in Headers */, A7D8AEEC23E2514100DCD162 /* SDL_cocoavulkan.h in Headers */, A7D8B23423E2514200DCD162 /* gl2platform.h in Headers */, - A7D88D3E23E24D3B00DCD162 /* SDL_pixels.h in Headers */, A7D8B25223E2514200DCD162 /* vk_layer.h in Headers */, - A7D8AEC223E2514100DCD162 /* SDL_cocoamousetap.h in Headers */, A7D8B26A23E2514200DCD162 /* vk_platform.h in Headers */, A7D8AEB623E2514100DCD162 /* SDL_cocoametalview.h in Headers */, A7D8AEF223E2514100DCD162 /* SDL_cocoaopengles.h in Headers */, @@ -7057,36 +6733,28 @@ A7D8B28E23E2514200DCD162 /* vulkan_xlib_xrandr.h in Headers */, A7D8A99123E2514000DCD162 /* SDL_sensor_c.h in Headers */, A7D8B9DB23E2514400DCD162 /* SDL_sysrender.h in Headers */, + F316AB922B5A02C3002EF551 /* yuv_rgb_internal.h in Headers */, A7D8BA3523E2514400DCD162 /* SDL_rotate.h in Headers */, - A7D88D3F23E24D3B00DCD162 /* SDL_platform.h in Headers */, - A7D88D4023E24D3B00DCD162 /* SDL_power.h in Headers */, - A7D8AB7D23E2514100DCD162 /* SDL_offscreenopengl.h in Headers */, A7D8BB5523E2514500DCD162 /* scancodes_darwin.h in Headers */, A7D8B5BB23E2514300DCD162 /* controller_type.h in Headers */, - A7D8B17423E2514200DCD162 /* SDL_x11opengles.h in Headers */, A7D8AC7923E2514100DCD162 /* SDL_uikitclipboard.h in Headers */, A7D8B2A023E2514200DCD162 /* vulkan_xlib.h in Headers */, + F386F6F42884663E001840AA /* SDL_utils_c.h in Headers */, A7D8AC9D23E2514100DCD162 /* SDL_uikitwindow.h in Headers */, A7D8B25E23E2514200DCD162 /* vulkan_vi.h in Headers */, - A7D8B29A23E2514200DCD162 /* vulkan_mir.h in Headers */, - A7D88D4123E24D3B00DCD162 /* SDL_quit.h in Headers */, A7D8BB4F23E2514500DCD162 /* default_cursor.h in Headers */, A7D8B9FF23E2514400DCD162 /* SDL_render_sw_c.h in Headers */, - A7D88D4223E24D3B00DCD162 /* SDL_rect.h in Headers */, - A7D88D4323E24D3B00DCD162 /* SDL_render.h in Headers */, A7D8ABFB23E2514100DCD162 /* SDL_nullvideo.h in Headers */, A7D8B39C23E2514200DCD162 /* SDL_blit_copy.h in Headers */, A7D8B3A223E2514200DCD162 /* SDL_RLEaccel_c.h in Headers */, + 75E09167241EA924004729E1 /* SDL_virtualjoystick_c.h in Headers */, A7D8B24C23E2514200DCD162 /* eglplatform.h in Headers */, - A7D8B1DA23E2514200DCD162 /* edid.h in Headers */, - A7D88D4423E24D3B00DCD162 /* SDL_revision.h in Headers */, A7D8B3EA23E2514300DCD162 /* SDL_systhread.h in Headers */, - A7D88D4523E24D3B00DCD162 /* SDL_rwops.h in Headers */, - A7D88D4623E24D3B00DCD162 /* SDL_scancode.h in Headers */, A7D8AECE23E2514100DCD162 /* SDL_cocoaclipboard.h in Headers */, A7D8AEF823E2514100DCD162 /* SDL_cocoamodes.h in Headers */, A7D8ACB523E2514100DCD162 /* SDL_uikitopenglview.h in Headers */, A7D8B28223E2514200DCD162 /* vulkan_win32.h in Headers */, + F31A92CD28D4CB39003BFD6A /* SDL_offscreenopengles.h in Headers */, A7D8AB8323E2514100DCD162 /* SDL_offscreenframebuffer_c.h in Headers */, A7D8BB4323E2514500DCD162 /* SDL_displayevents_c.h in Headers */, A7D8AB3523E2514100DCD162 /* SDL_timer_c.h in Headers */, @@ -7094,48 +6762,33 @@ A7D8B44423E2514300DCD162 /* SDL_sysmutex_c.h in Headers */, A7D8BB2523E2514500DCD162 /* scancodes_windows.h in Headers */, A7D8B5C723E2514300DCD162 /* SDL_rwopsbundlesupport.h in Headers */, + F386F6EB2884663E001840AA /* SDL_log_c.h in Headers */, A7D8B61523E2514300DCD162 /* SDL_syspower.h in Headers */, A7D8B28823E2514200DCD162 /* vulkan_macos.h in Headers */, A7D8B29423E2514200DCD162 /* vulkan_xcb.h in Headers */, + F382072B284F3643004DD584 /* SDL_guid.h in Headers */, A7D8B2A623E2514200DCD162 /* vulkan_ios.h in Headers */, A7D8A99D23E2514000DCD162 /* SDL_internal.h in Headers */, - A7D88D4723E24D3B00DCD162 /* SDL_shape.h in Headers */, - A7D88D4B23E24D3B00DCD162 /* SDL_stdinc.h in Headers */, - A7D88D4C23E24D3B00DCD162 /* SDL_surface.h in Headers */, A7D8B26423E2514200DCD162 /* vulkan.h in Headers */, A7D8BB8B23E2514500DCD162 /* SDL_keyboard_c.h in Headers */, - A7D88D4D23E24D3B00DCD162 /* SDL_system.h in Headers */, - A7D88D4E23E24D3B00DCD162 /* SDL_syswm.h in Headers */, - A7D88D4F23E24D3B00DCD162 /* SDL_opengl_glext.h in Headers */, A7D8BB1F23E2514500DCD162 /* SDL_mouse_c.h in Headers */, + F395C1BE2569C6A000942BFF /* SDL_mfijoystick_c.h in Headers */, A7D8B2BE23E2514200DCD162 /* SDL_blit_auto.h in Headers */, A7D8B9ED23E2514400DCD162 /* SDL_blendline.h in Headers */, A7D8AAD823E2514100DCD162 /* SDL_syshaptic.h in Headers */, A7D8AD2123E2514100DCD162 /* SDL_vulkan_internal.h in Headers */, - A7D88D5023E24D3B00DCD162 /* SDL_thread.h in Headers */, A7D8AF1623E2514100DCD162 /* SDL_cocoaevents.h in Headers */, + F362B9362B33916600D30B94 /* controller_list.h in Headers */, A7D8B25823E2514200DCD162 /* vk_icd.h in Headers */, A7D8ABE923E2514100DCD162 /* SDL_nullframebuffer_c.h in Headers */, - A7D88D5223E24D3B00DCD162 /* SDL_timer.h in Headers */, A7D8AB2023E2514100DCD162 /* SDL_dynapi_procs.h in Headers */, A7D8B27623E2514200DCD162 /* vulkan_fuchsia.h in Headers */, - A7D88D5323E24D3B00DCD162 /* SDL_touch.h in Headers */, - A7D88D5423E24D3B00DCD162 /* SDL_types.h in Headers */, A7D8B57323E2514300DCD162 /* usb_ids.h in Headers */, - A7D8B4EC23E2514300DCD162 /* SDL_sysjoystick_c.h in Headers */, + F316ABAD2B5A02C3002EF551 /* yuv_rgb_lsx.h in Headers */, A7D8BA5923E2514400DCD162 /* SDL_gles2funcs.h in Headers */, - A7D8B57F23E2514300DCD162 /* SDL_sysjoystick_c.h in Headers */, - A7D88D5523E24D3B00DCD162 /* SDL_version.h in Headers */, - A7D88D5623E24D3B00DCD162 /* SDL_video.h in Headers */, - A7D88D5D23E24D3B00DCD162 /* SDL_opengles2_gl2.h in Headers */, - A7D88D7A23E24D3B00DCD162 /* SDL_sensor.h in Headers */, A7D8AC4323E2514100DCD162 /* SDL_sysvideo.h in Headers */, - A7D88D8A23E24D3B00DCD162 /* SDL_opengles2_gl2platform.h in Headers */, - A7D88DA623E24D3B00DCD162 /* SDL_opengles2_gl2ext.h in Headers */, - A7D8B1FE23E2514200DCD162 /* SDL_x11mouse.h in Headers */, A7D8AB1423E2514100DCD162 /* SDL_dynapi_overrides.h in Headers */, A7D8AEFE23E2514100DCD162 /* SDL_cocoawindow.h in Headers */, - A7D8B1E023E2514200DCD162 /* SDL_x11vulkan.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -7143,241 +6796,239 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - AA7557FA1595D4D800BBD41B /* begin_code.h in Headers */, - A75FDB5823E39E6100529352 /* hidapi.h in Headers */, - A7D8B24223E2514200DCD162 /* eglext.h in Headers */, - A7D8AABC23E2514100DCD162 /* SDL_haptic_c.h in Headers */, - AA7557FC1595D4D800BBD41B /* close_code.h in Headers */, - A7D8B85A23E2514400DCD162 /* SDL_sysaudio.h in Headers */, - A7D8BBE223E2574800DCD162 /* SDL_uikitvideo.h in Headers */, - A7D8AB8523E2514100DCD162 /* SDL_offscreenwindow.h in Headers */, AA75585E1595D4D800BBD41B /* SDL.h in Headers */, - AA7557FE1595D4D800BBD41B /* SDL_assert.h in Headers */, - A7D8B3B623E2514200DCD162 /* SDL_blit.h in Headers */, - A7D8BBE023E2574800DCD162 /* SDL_uikitopenglview.h in Headers */, - A7D8B4AC23E2514300DCD162 /* SDL_gamecontrollerdb.h in Headers */, - A7D8B9EF23E2514400DCD162 /* SDL_drawpoint.h in Headers */, A7D8B39E23E2514200DCD162 /* SDL_RLEaccel_c.h in Headers */, - A7D8B44023E2514300DCD162 /* SDL_sysmutex_c.h in Headers */, - A7D8BA4323E2514400DCD162 /* SDL_glesfuncs.h in Headers */, - A7D8AEDC23E2514100DCD162 /* SDL_cocoaopengl.h in Headers */, - A7D8AF0023E2514100DCD162 /* SDL_cocoavideo.h in Headers */, - A7D8B2BA23E2514200DCD162 /* SDL_blit_auto.h in Headers */, - A7D8BBAB23E2514500DCD162 /* SDL_windowevents_c.h in Headers */, - A7D8B2B423E2514200DCD162 /* vulkan_android.h in Headers */, - AA7558001595D4D800BBD41B /* SDL_atomic.h in Headers */, - A7D8B9A123E2514400DCD162 /* SDL_shaders_metal_tvos.h in Headers */, - A7D8BA0D23E2514400DCD162 /* SDL_blendpoint.h in Headers */, - A7D8BBE423E2574800DCD162 /* SDL_uikitview.h in Headers */, - A7D8B3E623E2514300DCD162 /* SDL_systhread.h in Headers */, - A7D8B1B823E2514200DCD162 /* SDL_x11modes.h in Headers */, - AA7558021595D4D800BBD41B /* SDL_audio.h in Headers */, - A7D8B8CC23E2514400DCD162 /* SDL_coreaudio.h in Headers */, - A7D8AC3F23E2514100DCD162 /* SDL_sysvideo.h in Headers */, - A7D8AEBE23E2514100DCD162 /* SDL_cocoamousetap.h in Headers */, - AADA5B8716CCAB3000107CF7 /* SDL_bits.h in Headers */, - A7D8B21E23E2514200DCD162 /* SDL_x11video.h in Headers */, - A7D8B9FB23E2514400DCD162 /* SDL_render_sw_c.h in Headers */, - A7D8B14623E2514200DCD162 /* SDL_x11touch.h in Headers */, - AA7558041595D4D800BBD41B /* SDL_blendmode.h in Headers */, - 5C2EF7011FC9EF10003F5197 /* SDL_egl.h in Headers */, - AA7558061595D4D800BBD41B /* SDL_clipboard.h in Headers */, - A7D8BAC123E2514500DCD162 /* math_private.h in Headers */, - AA7558081595D4D800BBD41B /* SDL_config_macosx.h in Headers */, - AA75580A1595D4D800BBD41B /* SDL_config.h in Headers */, - A7D8BB3923E2514500DCD162 /* SDL_gesture_c.h in Headers */, - A7D8B9CB23E2514400DCD162 /* SDL_yuv_sw_c.h in Headers */, - AA75580C1595D4D800BBD41B /* SDL_copying.h in Headers */, - A7D8AB7F23E2514100DCD162 /* SDL_offscreenframebuffer_c.h in Headers */, - A7D8AEF423E2514100DCD162 /* SDL_cocoamodes.h in Headers */, - A7D8ABFD23E2514100DCD162 /* SDL_nullevents_c.h in Headers */, - AA75580E1595D4D800BBD41B /* SDL_cpuinfo.h in Headers */, - A7D8BA5523E2514400DCD162 /* SDL_gles2funcs.h in Headers */, - A7D8B8A223E2514400DCD162 /* SDL_diskaudio.h in Headers */, - A7D8B9D723E2514400DCD162 /* SDL_sysrender.h in Headers */, - A7D8BB2123E2514500DCD162 /* scancodes_windows.h in Headers */, - A7D8ADEC23E2514100DCD162 /* SDL_blit_slow.h in Headers */, - A7D8B20C23E2514200DCD162 /* SDL_x11clipboard.h in Headers */, + AA7557FE1595D4D800BBD41B /* SDL_assert.h in Headers */, A7D8B61723E2514300DCD162 /* SDL_assert_c.h in Headers */, - A7D8BA3123E2514400DCD162 /* SDL_rotate.h in Headers */, + AA7558001595D4D800BBD41B /* SDL_atomic.h in Headers */, + AA7558021595D4D800BBD41B /* SDL_audio.h in Headers */, + A7D8B7A023E2514400DCD162 /* SDL_audio_c.h in Headers */, + A7D8B7B223E2514400DCD162 /* SDL_audiodev_c.h in Headers */, + AADA5B8716CCAB3000107CF7 /* SDL_bits.h in Headers */, + A7D8BA0123E2514400DCD162 /* SDL_blendfillrect.h in Headers */, + A7D8B9E923E2514400DCD162 /* SDL_blendline.h in Headers */, + F316ABC42B5A02C3002EF551 /* yuv_rgb_std.h in Headers */, + AA7558041595D4D800BBD41B /* SDL_blendmode.h in Headers */, + A7D8BA0D23E2514400DCD162 /* SDL_blendpoint.h in Headers */, + A7D8B3B623E2514200DCD162 /* SDL_blit.h in Headers */, + A7D8B2BA23E2514200DCD162 /* SDL_blit_auto.h in Headers */, + A7D8B39823E2514200DCD162 /* SDL_blit_copy.h in Headers */, + A7D8ADEC23E2514100DCD162 /* SDL_blit_slow.h in Headers */, + F3820727284F3643004DD584 /* SDL_guid.h in Headers */, + AA7558061595D4D800BBD41B /* SDL_clipboard.h in Headers */, + A7D8BB6F23E2514500DCD162 /* SDL_clipboardevents_c.h in Headers */, + A7D8AECA23E2514100DCD162 /* SDL_cocoaclipboard.h in Headers */, + A7D8AF1223E2514100DCD162 /* SDL_cocoaevents.h in Headers */, + A7D8AE8E23E2514100DCD162 /* SDL_cocoakeyboard.h in Headers */, + A7D8AF0623E2514100DCD162 /* SDL_cocoamessagebox.h in Headers */, + A7D8AEB223E2514100DCD162 /* SDL_cocoametalview.h in Headers */, + A7D8AEF423E2514100DCD162 /* SDL_cocoamodes.h in Headers */, + A7D8AF1E23E2514100DCD162 /* SDL_cocoamouse.h in Headers */, + A7D8AEDC23E2514100DCD162 /* SDL_cocoaopengl.h in Headers */, + A7D8AEEE23E2514100DCD162 /* SDL_cocoaopengles.h in Headers */, + A7D8AE8223E2514100DCD162 /* SDL_cocoashape.h in Headers */, + A7D8AF0023E2514100DCD162 /* SDL_cocoavideo.h in Headers */, + A7D8AEE823E2514100DCD162 /* SDL_cocoavulkan.h in Headers */, + A7D8AEFA23E2514100DCD162 /* SDL_cocoawindow.h in Headers */, + AA75580A1595D4D800BBD41B /* SDL_config.h in Headers */, + AA7558081595D4D800BBD41B /* SDL_config_macosx.h in Headers */, + AA75580C1595D4D800BBD41B /* SDL_copying.h in Headers */, + A7D8B8CC23E2514400DCD162 /* SDL_coreaudio.h in Headers */, + A7D8A96F23E2514000DCD162 /* SDL_coremotionsensor.h in Headers */, + AA75580E1595D4D800BBD41B /* SDL_cpuinfo.h in Headers */, + F31A92C828D4CB39003BFD6A /* SDL_offscreenopengles.h in Headers */, + A7D8B98023E2514400DCD162 /* SDL_d3dmath.h in Headers */, + A7D8A94523E2514000DCD162 /* SDL_dataqueue.h in Headers */, + A7D8B8A223E2514400DCD162 /* SDL_diskaudio.h in Headers */, + A7D8BB3F23E2514500DCD162 /* SDL_displayevents_c.h in Headers */, + A7D8BA1923E2514400DCD162 /* SDL_draw.h in Headers */, A7D8BA0723E2514400DCD162 /* SDL_drawline.h in Headers */, - A7D8B1E823E2514200DCD162 /* SDL_x11window.h in Headers */, - A7D8AB7923E2514100DCD162 /* SDL_offscreenopengl.h in Headers */, - A7D8B1EE23E2514200DCD162 /* SDL_x11framebuffer.h in Headers */, - A7D8BB8723E2514500DCD162 /* SDL_keyboard_c.h in Headers */, - AA7558101595D4D800BBD41B /* SDL_endian.h in Headers */, + F316ABBB2B5A02C3002EF551 /* yuv_rgb_sse.h in Headers */, + A7D8B9EF23E2514400DCD162 /* SDL_drawpoint.h in Headers */, + A7D8BB2D23E2514500DCD162 /* SDL_dropevents_c.h in Headers */, + A7D8B79423E2514400DCD162 /* SDL_dummyaudio.h in Headers */, + A7D8A96323E2514000DCD162 /* SDL_dummysensor.h in Headers */, A7D8AB0A23E2514100DCD162 /* SDL_dynapi.h in Headers */, - A7D8AB6D23E2514100DCD162 /* SDL_offscreenvideo.h in Headers */, + A7D8AB1023E2514100DCD162 /* SDL_dynapi_overrides.h in Headers */, + A7D8AB1C23E2514100DCD162 /* SDL_dynapi_procs.h in Headers */, + 5C2EF7011FC9EF10003F5197 /* SDL_egl.h in Headers */, + A7D8ABD923E2514100DCD162 /* SDL_egl_c.h in Headers */, + AA7558101595D4D800BBD41B /* SDL_endian.h in Headers */, AA7558121595D4D800BBD41B /* SDL_error.h in Headers */, - A7D8B26023E2514200DCD162 /* vulkan.h in Headers */, + A7D8A95D23E2514000DCD162 /* SDL_error_c.h in Headers */, AA7558141595D4D800BBD41B /* SDL_events.h in Headers */, A7D8BBA523E2514500DCD162 /* SDL_events_c.h in Headers */, - A7D8BBD623E2574800DCD162 /* SDL_uikitevents.h in Headers */, - A7D8B23C23E2514200DCD162 /* egl.h in Headers */, - A7D8ABD923E2514100DCD162 /* SDL_egl_c.h in Headers */, - A7D8A98D23E2514000DCD162 /* SDL_sensor_c.h in Headers */, 567E2F2117C44C35005F1892 /* SDL_filesystem.h in Headers */, - A7D8BBDC23E2574800DCD162 /* SDL_uikitmodes.h in Headers */, - A7D8B27E23E2514200DCD162 /* vulkan_win32.h in Headers */, A77E6EB4167AB0A90010E40B /* SDL_gamecontroller.h in Headers */, - A7D8B79423E2514400DCD162 /* SDL_dummyaudio.h in Headers */, - A7D8B26623E2514200DCD162 /* vk_platform.h in Headers */, + A7D8B4AC23E2514300DCD162 /* SDL_gamecontrollerdb.h in Headers */, AA7558161595D4D800BBD41B /* SDL_gesture.h in Headers */, + A7D8BB3923E2514500DCD162 /* SDL_gesture_c.h in Headers */, + A7D8BA5523E2514400DCD162 /* SDL_gles2funcs.h in Headers */, + A7D8BA4323E2514400DCD162 /* SDL_glesfuncs.h in Headers */, + A7D8BA7923E2514400DCD162 /* SDL_glfuncs.h in Headers */, AA7558181595D4D800BBD41B /* SDL_haptic.h in Headers */, - A7D8BB4523E2514500DCD162 /* blank_cursor.h in Headers */, - A7D8BB5D23E2514500DCD162 /* scancodes_linux.h in Headers */, + A7D8AABC23E2514100DCD162 /* SDL_haptic_c.h in Headers */, + F316AB8E2B5A02C3002EF551 /* yuv_rgb_internal.h in Headers */, + A75FDBC523EA380300529352 /* SDL_hidapi_rumble.h in Headers */, + A7D8B55723E2514300DCD162 /* SDL_hidapijoystick_c.h in Headers */, AA75581A1595D4D800BBD41B /* SDL_hints.h in Headers */, - A7D8B2A223E2514200DCD162 /* vulkan_ios.h in Headers */, - A7D8B98023E2514400DCD162 /* SDL_d3dmath.h in Headers */, + A7D8B94A23E2514400DCD162 /* SDL_hints_c.h in Headers */, + F316ABCD2B5A02C3002EF551 /* yuv_rgb_lsx_func.h in Headers */, + A7D8A99923E2514000DCD162 /* SDL_internal.h in Headers */, + F395C1932569C68F00942BFF /* SDL_iokitjoystick_c.h in Headers */, AA75581E1595D4D800BBD41B /* SDL_joystick.h in Headers */, - A7D8B5B723E2514300DCD162 /* controller_type.h in Headers */, - A7D8AEEE23E2514100DCD162 /* SDL_cocoaopengles.h in Headers */, - A7D8AECA23E2514100DCD162 /* SDL_cocoaclipboard.h in Headers */, - A7D8AEFA23E2514100DCD162 /* SDL_cocoawindow.h in Headers */, - AA7558201595D4D800BBD41B /* SDL_keyboard.h in Headers */, - A7D8B22423E2514200DCD162 /* gl2ext.h in Headers */, - A7D8B3CE23E2514300DCD162 /* yuv_rgb_std_func.h in Headers */, - F3950CD8212BC88D00F51292 /* SDL_sensor.h in Headers */, - A7D8BBDE23E2574800DCD162 /* SDL_uikitopengles.h in Headers */, - FA24348B21D41FFB00B8918A /* SDL_metal.h in Headers */, - AA7558221595D4D800BBD41B /* SDL_keycode.h in Headers */, - A7D8BB3F23E2514500DCD162 /* SDL_displayevents_c.h in Headers */, - AA7558241595D4D800BBD41B /* SDL_loadso.h in Headers */, - A7D8B23023E2514200DCD162 /* gl2platform.h in Headers */, - A7D8AAD423E2514100DCD162 /* SDL_syshaptic.h in Headers */, - A7D8B57B23E2514300DCD162 /* SDL_sysjoystick_c.h in Headers */, - A7D8BBC723E2561500DCD162 /* SDL_steamcontroller.h in Headers */, - A7D8B1AC23E2514200DCD162 /* SDL_x11sym.h in Headers */, - A7D8B86C23E2514400DCD162 /* SDL_wave.h in Headers */, - A7D8B1FA23E2514200DCD162 /* SDL_x11mouse.h in Headers */, - A7D8B25A23E2514200DCD162 /* vulkan_vi.h in Headers */, - A7D8B14C23E2514200DCD162 /* SDL_x11messagebox.h in Headers */, - AA7558261595D4D800BBD41B /* SDL_log.h in Headers */, - A7D8BB4B23E2514500DCD162 /* default_cursor.h in Headers */, - A7D8AEB223E2514100DCD162 /* SDL_cocoametalview.h in Headers */, - A7D8B3D423E2514300DCD162 /* yuv_rgb.h in Headers */, - A7D8B1D023E2514200DCD162 /* SDL_x11xinput2.h in Headers */, - A7D8B25423E2514200DCD162 /* vk_icd.h in Headers */, - A7D8B2AE23E2514200DCD162 /* vk_sdk_platform.h in Headers */, - A7D8BB2D23E2514500DCD162 /* SDL_dropevents_c.h in Headers */, - A7D8BBE823E2574800DCD162 /* SDL_uikitvulkan.h in Headers */, - A7D8B61123E2514300DCD162 /* SDL_syspower.h in Headers */, - A7D8BB6323E2514500DCD162 /* SDL_touch_c.h in Headers */, - A7D8B29C23E2514200DCD162 /* vulkan_xlib.h in Headers */, - A7D8BBD123E2574800DCD162 /* keyinfotable.h in Headers */, - A7D8AE8223E2514100DCD162 /* SDL_cocoashape.h in Headers */, - AA7558281595D4D800BBD41B /* SDL_main.h in Headers */, - A7D8ABE523E2514100DCD162 /* SDL_nullframebuffer_c.h in Headers */, - AA9FF95A1637CBF9000DF050 /* SDL_messagebox.h in Headers */, - A7D8B28423E2514200DCD162 /* vulkan_macos.h in Headers */, - AA75582A1595D4D800BBD41B /* SDL_mouse.h in Headers */, - AA75582C1595D4D800BBD41B /* SDL_mutex.h in Headers */, - A7D8BBDA23E2574800DCD162 /* SDL_uikitmetalview.h in Headers */, A7D8B58723E2514300DCD162 /* SDL_joystick_c.h in Headers */, + F316AB852B5A02C3002EF551 /* yuv_rgb_common.h in Headers */, + AA7558201595D4D800BBD41B /* SDL_keyboard.h in Headers */, + A7D8BB8723E2514500DCD162 /* SDL_keyboard_c.h in Headers */, + AA7558221595D4D800BBD41B /* SDL_keycode.h in Headers */, + AA7558241595D4D800BBD41B /* SDL_loadso.h in Headers */, + 566E267A2462701100718109 /* SDL_locale.h in Headers */, + AA7558261595D4D800BBD41B /* SDL_log.h in Headers */, + AA7558281595D4D800BBD41B /* SDL_main.h in Headers */, + AA9FF95A1637CBF9000DF050 /* SDL_messagebox.h in Headers */, + F386F6E72884663E001840AA /* SDL_log_c.h in Headers */, + FA24348B21D41FFB00B8918A /* SDL_metal.h in Headers */, + F395C1BA2569C6A000942BFF /* SDL_mfijoystick_c.h in Headers */, + 5616CA50252BB2BE005D5928 /* SDL_misc.h in Headers */, + AA75582A1595D4D800BBD41B /* SDL_mouse.h in Headers */, + A7D8BB1B23E2514500DCD162 /* SDL_mouse_c.h in Headers */, + F38233852738EB8600F7F527 /* SDL_hidapi.h in Headers */, + AA75582C1595D4D800BBD41B /* SDL_mutex.h in Headers */, AA75582E1595D4D800BBD41B /* SDL_name.h in Headers */, - A7D8A96F23E2514000DCD162 /* SDL_coremotionsensor.h in Headers */, - A7D8B98C23E2514400DCD162 /* SDL_shaders_metal_ios.h in Headers */, - A7D8AF1223E2514100DCD162 /* SDL_cocoaevents.h in Headers */, - A7D8BA7323E2514400DCD162 /* SDL_shaders_gl.h in Headers */, + A7D8ABFD23E2514100DCD162 /* SDL_nullevents_c.h in Headers */, + A7D8ABE523E2514100DCD162 /* SDL_nullframebuffer_c.h in Headers */, + A7D8ABF723E2514100DCD162 /* SDL_nullvideo.h in Headers */, + A7D8AB5B23E2514100DCD162 /* SDL_offscreenevents_c.h in Headers */, + A7D8AB7F23E2514100DCD162 /* SDL_offscreenframebuffer_c.h in Headers */, + A7D8AB6D23E2514100DCD162 /* SDL_offscreenvideo.h in Headers */, + A7D8AB8523E2514100DCD162 /* SDL_offscreenwindow.h in Headers */, AA7558301595D4D800BBD41B /* SDL_opengl.h in Headers */, - A7D8AC0323E2514100DCD162 /* SDL_rect_c.h in Headers */, - A7D8A97B23E2514000DCD162 /* SDL_syssensor.h in Headers */, AAC070F9195606770073DCDF /* SDL_opengl_glext.h in Headers */, AA7558321595D4D800BBD41B /* SDL_opengles.h in Headers */, - A7D8B58123E2514300DCD162 /* SDL_sysjoystick.h in Headers */, AA7558341595D4D800BBD41B /* SDL_opengles2.h in Headers */, - A7D8A94523E2514000DCD162 /* SDL_dataqueue.h in Headers */, - A7D8B24E23E2514200DCD162 /* vk_layer.h in Headers */, AAC070FC195606770073DCDF /* SDL_opengles2_gl2.h in Headers */, - A7D8BB9F23E2514500DCD162 /* scancodes_xfree86.h in Headers */, - A7D8BBE623E2574800DCD162 /* SDL_uikitviewcontroller.h in Headers */, - A7D8AF1E23E2514100DCD162 /* SDL_cocoamouse.h in Headers */, - A7D8BBEA23E2574800DCD162 /* SDL_uikitwindow.h in Headers */, - A7D8AE8E23E2514100DCD162 /* SDL_cocoakeyboard.h in Headers */, - A7D8BA4F23E2514400DCD162 /* SDL_shaders_gles2.h in Headers */, AAC070FF195606770073DCDF /* SDL_opengles2_gl2ext.h in Headers */, - A7D8B29623E2514200DCD162 /* vulkan_mir.h in Headers */, AAC07102195606770073DCDF /* SDL_opengles2_gl2platform.h in Headers */, - A7D8BA1923E2514400DCD162 /* SDL_draw.h in Headers */, - A7D8BB5123E2514500DCD162 /* scancodes_darwin.h in Headers */, - A7D8BB9323E2514500DCD162 /* SDL_sysevents.h in Headers */, - A7D8B7A023E2514400DCD162 /* SDL_audio_c.h in Headers */, - A7D8B17023E2514200DCD162 /* SDL_x11opengles.h in Headers */, - A7D8B29023E2514200DCD162 /* vulkan_xcb.h in Headers */, - A7D8AAE023E2514100DCD162 /* SDL_syshaptic_c.h in Headers */, - A7D8BBD223E2574800DCD162 /* SDL_uikitappdelegate.h in Headers */, - A7D8BB1B23E2514500DCD162 /* SDL_mouse_c.h in Headers */, - A7D8BA0123E2514400DCD162 /* SDL_blendfillrect.h in Headers */, - A7D8B27823E2514200DCD162 /* vulkan_wayland.h in Headers */, - A7D8B5C323E2514300DCD162 /* SDL_rwopsbundlesupport.h in Headers */, AAC07105195606770073DCDF /* SDL_opengles2_khrplatform.h in Headers */, - A7D8B23623E2514200DCD162 /* khrplatform.h in Headers */, AA7558361595D4D800BBD41B /* SDL_pixels.h in Headers */, - A7D8ABF723E2514100DCD162 /* SDL_nullvideo.h in Headers */, - A7D8B56F23E2514300DCD162 /* usb_ids.h in Headers */, - A7D8B7B223E2514400DCD162 /* SDL_audiodev_c.h in Headers */, + A7D8B2C023E2514200DCD162 /* SDL_pixels_c.h in Headers */, AA7558381595D4D800BBD41B /* SDL_platform.h in Headers */, AA75583A1595D4D800BBD41B /* SDL_power.h in Headers */, AA75583C1595D4D800BBD41B /* SDL_quit.h in Headers */, - A7D8AB1023E2514100DCD162 /* SDL_dynapi_overrides.h in Headers */, AA75583E1595D4D800BBD41B /* SDL_rect.h in Headers */, - A7D8B27223E2514200DCD162 /* vulkan_fuchsia.h in Headers */, - A7D8B28A23E2514200DCD162 /* vulkan_xlib_xrandr.h in Headers */, - A7D8B5D523E2514300DCD162 /* SDL_syspower.h in Headers */, + A7D8AC0323E2514100DCD162 /* SDL_rect_c.h in Headers */, AA7558401595D4D800BBD41B /* SDL_render.h in Headers */, - A7D8B26C23E2514200DCD162 /* vulkan.hpp in Headers */, + A7D8B9FB23E2514400DCD162 /* SDL_render_sw_c.h in Headers */, AA7558421595D4D800BBD41B /* SDL_revision.h in Headers */, - A7D8AB3123E2514100DCD162 /* SDL_timer_c.h in Headers */, - A7D8B16423E2514200DCD162 /* SDL_x11shape.h in Headers */, - A7D8AB1C23E2514100DCD162 /* SDL_dynapi_procs.h in Headers */, - A7D8BB0323E2514500DCD162 /* math_libm.h in Headers */, + A7D8BA3123E2514400DCD162 /* SDL_rotate.h in Headers */, + F3973FA228A59BDD00B84553 /* SDL_vacopy.h in Headers */, AA7558441595D4D800BBD41B /* SDL_rwops.h in Headers */, - A7D8B3C823E2514200DCD162 /* yuv_rgb_sse_func.h in Headers */, - A7D8AF0623E2514100DCD162 /* SDL_cocoamessagebox.h in Headers */, - A7D8B1D623E2514200DCD162 /* edid.h in Headers */, + A7D8B5C323E2514300DCD162 /* SDL_rwopsbundlesupport.h in Headers */, AA7558461595D4D800BBD41B /* SDL_scancode.h in Headers */, - A7D8B39823E2514200DCD162 /* SDL_blit_copy.h in Headers */, - A7D8B22A23E2514200DCD162 /* gl2.h in Headers */, - A7D8BBD823E2574800DCD162 /* SDL_uikitmessagebox.h in Headers */, + F3950CD8212BC88D00F51292 /* SDL_sensor.h in Headers */, + A7D8A98D23E2514000DCD162 /* SDL_sensor_c.h in Headers */, + F386F6F02884663E001840AA /* SDL_utils_c.h in Headers */, + A7D8BA7323E2514400DCD162 /* SDL_shaders_gl.h in Headers */, + A7D8BA4F23E2514400DCD162 /* SDL_shaders_gles2.h in Headers */, + A1BB8B6C27F6CF330057CFA8 /* SDL_list.h in Headers */, + A7D8B98C23E2514400DCD162 /* SDL_shaders_metal_ios.h in Headers */, + A7D8B99B23E2514400DCD162 /* SDL_shaders_metal_osx.h in Headers */, + A7D8B9A123E2514400DCD162 /* SDL_shaders_metal_tvos.h in Headers */, AA7558481595D4D800BBD41B /* SDL_shape.h in Headers */, - AA75584A1595D4D800BBD41B /* SDL_stdinc.h in Headers */, - A7D8B3B023E2514200DCD162 /* SDL_yuv_c.h in Headers */, - A7D8B1F423E2514200DCD162 /* SDL_x11dyn.h in Headers */, A7D8AC0923E2514100DCD162 /* SDL_shape_internals.h in Headers */, - A7D8A95D23E2514000DCD162 /* SDL_error_c.h in Headers */, - A7D8B2A823E2514200DCD162 /* vulkan_core.h in Headers */, - A7D8B3EC23E2514300DCD162 /* SDL_thread_c.h in Headers */, + AA75584A1595D4D800BBD41B /* SDL_stdinc.h in Headers */, + A7D8BBC723E2561500DCD162 /* SDL_steamcontroller.h in Headers */, AA75584C1595D4D800BBD41B /* SDL_surface.h in Headers */, - A7D8BB6F23E2514500DCD162 /* SDL_clipboardevents_c.h in Headers */, - A7D8BBD423E2574800DCD162 /* SDL_uikitclipboard.h in Headers */, - A7D8AB5B23E2514100DCD162 /* SDL_offscreenevents_c.h in Headers */, - A7D8AEE823E2514100DCD162 /* SDL_cocoavulkan.h in Headers */, + A7D8B85A23E2514400DCD162 /* SDL_sysaudio.h in Headers */, + A7D8AAD423E2514100DCD162 /* SDL_syshaptic.h in Headers */, + A7D8AAE023E2514100DCD162 /* SDL_syshaptic_c.h in Headers */, + A7D8B58123E2514300DCD162 /* SDL_sysjoystick.h in Headers */, + 566E26E1246274CC00718109 /* SDL_syslocale.h in Headers */, + A7D8B44023E2514300DCD162 /* SDL_sysmutex_c.h in Headers */, + A7D8B5D523E2514300DCD162 /* SDL_syspower.h in Headers */, + A7D8B61123E2514300DCD162 /* SDL_syspower.h in Headers */, + A7D8B9D723E2514400DCD162 /* SDL_sysrender.h in Headers */, + F362B9462B33920500D30B94 /* SDL_hidapi_nintendo.h in Headers */, + F316ABA92B5A02C3002EF551 /* yuv_rgb_lsx.h in Headers */, + A7D8A97B23E2514000DCD162 /* SDL_syssensor.h in Headers */, AA75584E1595D4D800BBD41B /* SDL_system.h in Headers */, - A7D8BA7923E2514400DCD162 /* SDL_glfuncs.h in Headers */, - A7D8B2C023E2514200DCD162 /* SDL_pixels_c.h in Headers */, + A7D8B3E623E2514300DCD162 /* SDL_systhread.h in Headers */, + A7D8B42823E2514300DCD162 /* SDL_systhread_c.h in Headers */, + 5616CA4D252BB2A6005D5928 /* SDL_sysurl.h in Headers */, + A7D8AC3F23E2514100DCD162 /* SDL_sysvideo.h in Headers */, AA7558501595D4D800BBD41B /* SDL_syswm.h in Headers */, AA7558521595D4D800BBD41B /* SDL_thread.h in Headers */, + A7D8B3EC23E2514300DCD162 /* SDL_thread_c.h in Headers */, AA7558541595D4D800BBD41B /* SDL_timer.h in Headers */, - A75FDBC523EA380300529352 /* SDL_hidapi_rumble.h in Headers */, - A7D8B21223E2514200DCD162 /* SDL_x11events.h in Headers */, + A7D8AB3123E2514100DCD162 /* SDL_timer_c.h in Headers */, AA7558561595D4D800BBD41B /* SDL_touch.h in Headers */, - A7D8A96323E2514000DCD162 /* SDL_dummysensor.h in Headers */, + A7D8BB6323E2514500DCD162 /* SDL_touch_c.h in Headers */, AA7558581595D4D800BBD41B /* SDL_types.h in Headers */, - A7D8B42823E2514300DCD162 /* SDL_systhread_c.h in Headers */, - A7D8B20623E2514200DCD162 /* SDL_x11keyboard.h in Headers */, - A7D8B94A23E2514400DCD162 /* SDL_hints_c.h in Headers */, - A7D8AD1D23E2514100DCD162 /* SDL_vulkan_internal.h in Headers */, - A7D8B9E923E2514400DCD162 /* SDL_blendline.h in Headers */, + A7D8BBD223E2574800DCD162 /* SDL_uikitappdelegate.h in Headers */, + A7D8BBD423E2574800DCD162 /* SDL_uikitclipboard.h in Headers */, + A7D8BBD623E2574800DCD162 /* SDL_uikitevents.h in Headers */, + A7D8BBD823E2574800DCD162 /* SDL_uikitmessagebox.h in Headers */, + A7D8BBDA23E2574800DCD162 /* SDL_uikitmetalview.h in Headers */, + A7D8BBDC23E2574800DCD162 /* SDL_uikitmodes.h in Headers */, + A7D8BBDE23E2574800DCD162 /* SDL_uikitopengles.h in Headers */, + A7D8BBE023E2574800DCD162 /* SDL_uikitopenglview.h in Headers */, + A7D8BBE223E2574800DCD162 /* SDL_uikitvideo.h in Headers */, + A7D8BBE423E2574800DCD162 /* SDL_uikitview.h in Headers */, + A7D8BBE623E2574800DCD162 /* SDL_uikitviewcontroller.h in Headers */, + A7D8BBE823E2574800DCD162 /* SDL_uikitvulkan.h in Headers */, + A7D8BBEA23E2574800DCD162 /* SDL_uikitwindow.h in Headers */, AA75585A1595D4D800BBD41B /* SDL_version.h in Headers */, AA75585C1595D4D800BBD41B /* SDL_video.h in Headers */, - A7D8B24823E2514200DCD162 /* eglplatform.h in Headers */, - A7D8B1DC23E2514200DCD162 /* SDL_x11vulkan.h in Headers */, - A7D8B55723E2514300DCD162 /* SDL_hidapijoystick_c.h in Headers */, - A7D8B21823E2514200DCD162 /* imKStoUCS.h in Headers */, - A7D8B1B223E2514200DCD162 /* SDL_x11opengl.h in Headers */, + 75E09163241EA924004729E1 /* SDL_virtualjoystick_c.h in Headers */, AA8167541F5E727800518735 /* SDL_vulkan.h in Headers */, - A7D8B99B23E2514400DCD162 /* SDL_shaders_metal_osx.h in Headers */, - A7D8A99923E2514000DCD162 /* SDL_internal.h in Headers */, + A7D8AD1D23E2514100DCD162 /* SDL_vulkan_internal.h in Headers */, + A7D8B86C23E2514400DCD162 /* SDL_wave.h in Headers */, + A7D8BBAB23E2514500DCD162 /* SDL_windowevents_c.h in Headers */, + A7D8B3B023E2514200DCD162 /* SDL_yuv_c.h in Headers */, + A7D8B9CB23E2514400DCD162 /* SDL_yuv_sw_c.h in Headers */, + AA7557FA1595D4D800BBD41B /* begin_code.h in Headers */, + A7D8BB4523E2514500DCD162 /* blank_cursor.h in Headers */, + F362B9522B33EB7300D30B94 /* SDL_steam_virtual_gamepad.h in Headers */, + AA7557FC1595D4D800BBD41B /* close_code.h in Headers */, + A7D8B5B723E2514300DCD162 /* controller_type.h in Headers */, + A7D8BB4B23E2514500DCD162 /* default_cursor.h in Headers */, + A7D8B23C23E2514200DCD162 /* egl.h in Headers */, + A7D8B24223E2514200DCD162 /* eglext.h in Headers */, + A7D8B24823E2514200DCD162 /* eglplatform.h in Headers */, + A7D8B22A23E2514200DCD162 /* gl2.h in Headers */, + A7D8B22423E2514200DCD162 /* gl2ext.h in Headers */, + A7D8B23023E2514200DCD162 /* gl2platform.h in Headers */, + A75FDB5823E39E6100529352 /* hidapi.h in Headers */, + A7D8B23623E2514200DCD162 /* khrplatform.h in Headers */, + A7D8BB0323E2514500DCD162 /* math_libm.h in Headers */, + A7D8BAC123E2514500DCD162 /* math_private.h in Headers */, + A7D8BB5123E2514500DCD162 /* scancodes_darwin.h in Headers */, + A7D8BB5D23E2514500DCD162 /* scancodes_linux.h in Headers */, + A7D8BB2123E2514500DCD162 /* scancodes_windows.h in Headers */, + A7D8BB9F23E2514500DCD162 /* scancodes_xfree86.h in Headers */, + A7D8B56F23E2514300DCD162 /* usb_ids.h in Headers */, + A1626A522617008D003F1973 /* SDL_triangle.h in Headers */, + A7D8B25423E2514200DCD162 /* vk_icd.h in Headers */, + A7D8B24E23E2514200DCD162 /* vk_layer.h in Headers */, + A7D8B26623E2514200DCD162 /* vk_platform.h in Headers */, + A7D8B2AE23E2514200DCD162 /* vk_sdk_platform.h in Headers */, + A7D8B26023E2514200DCD162 /* vulkan.h in Headers */, + A7D8B2B423E2514200DCD162 /* vulkan_android.h in Headers */, + A7D8B2A823E2514200DCD162 /* vulkan_core.h in Headers */, + A7D8B27223E2514200DCD162 /* vulkan_fuchsia.h in Headers */, + A7D8B2A223E2514200DCD162 /* vulkan_ios.h in Headers */, + A7D8B28423E2514200DCD162 /* vulkan_macos.h in Headers */, + A7D8B25A23E2514200DCD162 /* vulkan_vi.h in Headers */, + A7D8B27823E2514200DCD162 /* vulkan_wayland.h in Headers */, + A7D8B27E23E2514200DCD162 /* vulkan_win32.h in Headers */, + F362B9322B33916600D30B94 /* controller_list.h in Headers */, + A7D8B29023E2514200DCD162 /* vulkan_xcb.h in Headers */, + A7D8B29C23E2514200DCD162 /* vulkan_xlib.h in Headers */, + A7D8B28A23E2514200DCD162 /* vulkan_xlib_xrandr.h in Headers */, + A7D8B3D423E2514300DCD162 /* yuv_rgb.h in Headers */, + A7D8B3C823E2514200DCD162 /* yuv_rgb_sse_func.h in Headers */, + A7D8B3CE23E2514300DCD162 /* yuv_rgb_std_func.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -7386,90 +7037,59 @@ buildActionMask = 2147483647; files = ( A7D8B9A423E2514400DCD162 /* SDL_shaders_metal_tvos.h in Headers */, - DB0F490B17CA57ED008798C5 /* SDL_filesystem.h in Headers */, - AA7557FB1595D4D800BBD41B /* begin_code.h in Headers */, - AA7557FD1595D4D800BBD41B /* close_code.h in Headers */, - AA75585F1595D4D800BBD41B /* SDL.h in Headers */, - AA7557FF1595D4D800BBD41B /* SDL_assert.h in Headers */, + F316ABBE2B5A02C3002EF551 /* yuv_rgb_sse.h in Headers */, A7D8AC0C23E2514100DCD162 /* SDL_shape_internals.h in Headers */, A7D8BA7C23E2514400DCD162 /* SDL_glfuncs.h in Headers */, - AA7558011595D4D800BBD41B /* SDL_atomic.h in Headers */, A7D8AC0623E2514100DCD162 /* SDL_rect_c.h in Headers */, - A7D8B1D323E2514200DCD162 /* SDL_x11xinput2.h in Headers */, + F362B9352B33916600D30B94 /* controller_list.h in Headers */, + 75E09166241EA924004729E1 /* SDL_virtualjoystick_c.h in Headers */, A7D8B99E23E2514400DCD162 /* SDL_shaders_metal_osx.h in Headers */, A7D8B98F23E2514400DCD162 /* SDL_shaders_metal_ios.h in Headers */, A7D8AB8823E2514100DCD162 /* SDL_offscreenwindow.h in Headers */, - AA7558031595D4D800BBD41B /* SDL_audio.h in Headers */, A7D8A97223E2514000DCD162 /* SDL_coremotionsensor.h in Headers */, - AADA5B8816CCAB3000107CF7 /* SDL_bits.h in Headers */, - AA7558051595D4D800BBD41B /* SDL_blendmode.h in Headers */, A7D8BB3023E2514500DCD162 /* SDL_dropevents_c.h in Headers */, A7D8AABF23E2514100DCD162 /* SDL_haptic_c.h in Headers */, - AA7558071595D4D800BBD41B /* SDL_clipboard.h in Headers */, A7D8A94823E2514000DCD162 /* SDL_dataqueue.h in Headers */, A7D8A96023E2514000DCD162 /* SDL_error_c.h in Headers */, - A7D8B21523E2514200DCD162 /* SDL_x11events.h in Headers */, - AA75580B1595D4D800BBD41B /* SDL_config.h in Headers */, A7D8B98323E2514400DCD162 /* SDL_d3dmath.h in Headers */, - A7D8B1EB23E2514200DCD162 /* SDL_x11window.h in Headers */, - AA7558091595D4D800BBD41B /* SDL_config_macosx.h in Headers */, A7D8ABDC23E2514100DCD162 /* SDL_egl_c.h in Headers */, - AA75580D1595D4D800BBD41B /* SDL_copying.h in Headers */, A7D8B3D723E2514300DCD162 /* yuv_rgb.h in Headers */, A7D8B79723E2514400DCD162 /* SDL_dummyaudio.h in Headers */, - A7D8B14F23E2514200DCD162 /* SDL_x11messagebox.h in Headers */, A7D8B3EF23E2514300DCD162 /* SDL_thread_c.h in Headers */, A7D8AF0923E2514100DCD162 /* SDL_cocoamessagebox.h in Headers */, - A7D8B16723E2514200DCD162 /* SDL_x11shape.h in Headers */, - AA75580F1595D4D800BBD41B /* SDL_cpuinfo.h in Headers */, - AA7558111595D4D800BBD41B /* SDL_endian.h in Headers */, - AA7558131595D4D800BBD41B /* SDL_error.h in Headers */, - AA7558151595D4D800BBD41B /* SDL_events.h in Headers */, A7D8BA0423E2514400DCD162 /* SDL_blendfillrect.h in Headers */, - A77E6EB5167AB0A90010E40B /* SDL_gamecontroller.h in Headers */, + F362B9552B33EB7300D30B94 /* SDL_steam_virtual_gamepad.h in Headers */, A7D8B55A23E2514300DCD162 /* SDL_hidapijoystick_c.h in Headers */, + F316ABAC2B5A02C3002EF551 /* yuv_rgb_lsx.h in Headers */, A7D8B2C323E2514200DCD162 /* SDL_pixels_c.h in Headers */, - A7D8B1BB23E2514200DCD162 /* SDL_x11modes.h in Headers */, A7D8B58A23E2514300DCD162 /* SDL_joystick_c.h in Headers */, A75FDB5B23E39E6100529352 /* hidapi.h in Headers */, + F386F6F32884663E001840AA /* SDL_utils_c.h in Headers */, A7D8B2B123E2514200DCD162 /* vk_sdk_platform.h in Headers */, A7D8BB4823E2514500DCD162 /* blank_cursor.h in Headers */, - AA7558171595D4D800BBD41B /* SDL_gesture.h in Headers */, + F395C1962569C68F00942BFF /* SDL_iokitjoystick_c.h in Headers */, A7D8B85D23E2514400DCD162 /* SDL_sysaudio.h in Headers */, - AA7558191595D4D800BBD41B /* SDL_haptic.h in Headers */, - A7D8BB9623E2514500DCD162 /* SDL_sysevents.h in Headers */, A7D8BB0623E2514500DCD162 /* math_libm.h in Headers */, A7D8AF2123E2514100DCD162 /* SDL_cocoamouse.h in Headers */, - AA75581B1595D4D800BBD41B /* SDL_hints.h in Headers */, A7D8ADEF23E2514100DCD162 /* SDL_blit_slow.h in Headers */, A7D8B9CE23E2514400DCD162 /* SDL_yuv_sw_c.h in Headers */, A7D8BBFD23E2574800DCD162 /* SDL_uikitvideo.h in Headers */, - A7D8B1B523E2514200DCD162 /* SDL_x11opengl.h in Headers */, A7D8BBAE23E2514500DCD162 /* SDL_windowevents_c.h in Headers */, - AA75581F1595D4D800BBD41B /* SDL_joystick.h in Headers */, + F316AB912B5A02C3002EF551 /* yuv_rgb_internal.h in Headers */, A7D8AF0323E2514100DCD162 /* SDL_cocoavideo.h in Headers */, - AA7558211595D4D800BBD41B /* SDL_keyboard.h in Headers */, A7D8BB3C23E2514500DCD162 /* SDL_gesture_c.h in Headers */, A7D8BBEF23E2574800DCD162 /* SDL_uikitclipboard.h in Headers */, A7D8BA7623E2514400DCD162 /* SDL_shaders_gl.h in Headers */, A7D8B42B23E2514300DCD162 /* SDL_systhread_c.h in Headers */, - AA7558231595D4D800BBD41B /* SDL_keycode.h in Headers */, - A7D8B20923E2514200DCD162 /* SDL_x11keyboard.h in Headers */, A7D8AE9123E2514100DCD162 /* SDL_cocoakeyboard.h in Headers */, - A7D8B1F123E2514200DCD162 /* SDL_x11framebuffer.h in Headers */, - A7D8B22123E2514200DCD162 /* SDL_x11video.h in Headers */, - A7D8B26F23E2514200DCD162 /* vulkan.hpp in Headers */, - AA7558251595D4D800BBD41B /* SDL_loadso.h in Headers */, A7D8B22723E2514200DCD162 /* gl2ext.h in Headers */, A7D8BB7223E2514500DCD162 /* SDL_clipboardevents_c.h in Headers */, - A7D8B14923E2514200DCD162 /* SDL_x11touch.h in Headers */, A7D8AAE323E2514100DCD162 /* SDL_syshaptic_c.h in Headers */, A7D8B94D23E2514400DCD162 /* SDL_hints_c.h in Headers */, A7D8B7B523E2514400DCD162 /* SDL_audiodev_c.h in Headers */, A7D8B7A323E2514400DCD162 /* SDL_audio_c.h in Headers */, A7D8B23F23E2514200DCD162 /* egl.h in Headers */, A7D8B23923E2514200DCD162 /* khrplatform.h in Headers */, - AA7558271595D4D800BBD41B /* SDL_log.h in Headers */, A7D8A96623E2514000DCD162 /* SDL_dummysensor.h in Headers */, A7D8B2B723E2514200DCD162 /* vulkan_android.h in Headers */, A7D8B3D123E2514300DCD162 /* yuv_rgb_std_func.h in Headers */, @@ -7478,57 +7098,45 @@ A7D8AB0D23E2514100DCD162 /* SDL_dynapi.h in Headers */, A7D8B61A23E2514300DCD162 /* SDL_assert_c.h in Headers */, A7D8B8A523E2514400DCD162 /* SDL_diskaudio.h in Headers */, - AA7558291595D4D800BBD41B /* SDL_main.h in Headers */, A7D8B9F223E2514400DCD162 /* SDL_drawpoint.h in Headers */, - AAC07106195606770073DCDF /* SDL_opengles2_khrplatform.h in Headers */, A7D8BBFB23E2574800DCD162 /* SDL_uikitopenglview.h in Headers */, A7D8B86F23E2514400DCD162 /* SDL_wave.h in Headers */, A7D8AEDF23E2514100DCD162 /* SDL_cocoaopengl.h in Headers */, A7D8B3CB23E2514300DCD162 /* yuv_rgb_sse_func.h in Headers */, - A7D8B21B23E2514200DCD162 /* imKStoUCS.h in Headers */, A7D8AB5E23E2514100DCD162 /* SDL_offscreenevents_c.h in Headers */, - A7D8B1AF23E2514200DCD162 /* SDL_x11sym.h in Headers */, + F3973FA528A59BDD00B84553 /* SDL_vacopy.h in Headers */, A7D8B8CF23E2514400DCD162 /* SDL_coreaudio.h in Headers */, A7D8BA1C23E2514400DCD162 /* SDL_draw.h in Headers */, A7D8BA0A23E2514400DCD162 /* SDL_drawline.h in Headers */, A7D8BBF723E2574800DCD162 /* SDL_uikitmodes.h in Headers */, - DB0F489417C400ED008798C5 /* SDL_messagebox.h in Headers */, - AA75582B1595D4D800BBD41B /* SDL_mouse.h in Headers */, - AA75582D1595D4D800BBD41B /* SDL_mutex.h in Headers */, + 560572192473688C00B46B66 /* SDL_syslocale.h in Headers */, A7D8B3B323E2514200DCD162 /* SDL_yuv_c.h in Headers */, A7D8BBA223E2514500DCD162 /* scancodes_xfree86.h in Headers */, A7D8B5D823E2514300DCD162 /* SDL_syspower.h in Headers */, - A7D8B20F23E2514200DCD162 /* SDL_x11clipboard.h in Headers */, - AA75582F1595D4D800BBD41B /* SDL_name.h in Headers */, A7D8BC0523E2574800DCD162 /* SDL_uikitwindow.h in Headers */, A7D8B24523E2514200DCD162 /* eglext.h in Headers */, A7D8BBF123E2574800DCD162 /* SDL_uikitevents.h in Headers */, A7D8BBFF23E2574800DCD162 /* SDL_uikitview.h in Headers */, A7D8BBA823E2514500DCD162 /* SDL_events_c.h in Headers */, + F316ABC72B5A02C3002EF551 /* yuv_rgb_std.h in Headers */, A7D8BAC423E2514500DCD162 /* math_private.h in Headers */, A7D8B27B23E2514200DCD162 /* vulkan_wayland.h in Headers */, A7D8BBF523E2574800DCD162 /* SDL_uikitmetalview.h in Headers */, - AA7558311595D4D800BBD41B /* SDL_opengl.h in Headers */, A7D8AE8523E2514100DCD162 /* SDL_cocoashape.h in Headers */, - AA7558331595D4D800BBD41B /* SDL_opengles.h in Headers */, A7D8BA5223E2514400DCD162 /* SDL_shaders_gles2.h in Headers */, - AA7558351595D4D800BBD41B /* SDL_opengles2.h in Headers */, A7D8BA4623E2514400DCD162 /* SDL_glesfuncs.h in Headers */, A7D8BA1023E2514400DCD162 /* SDL_blendpoint.h in Headers */, - A7D8BBEC23E2574800DCD162 /* keyinfotable.h in Headers */, A7D8AB7023E2514100DCD162 /* SDL_offscreenvideo.h in Headers */, A7D8AC0023E2514100DCD162 /* SDL_nullevents_c.h in Headers */, A7D8B58423E2514300DCD162 /* SDL_sysjoystick.h in Headers */, A7D8BB6023E2514500DCD162 /* scancodes_linux.h in Headers */, - A7D8B1F723E2514200DCD162 /* SDL_x11dyn.h in Headers */, A7D8BB6623E2514500DCD162 /* SDL_touch_c.h in Headers */, A7D8B4AF23E2514300DCD162 /* SDL_gamecontrollerdb.h in Headers */, A7D8AEEB23E2514100DCD162 /* SDL_cocoavulkan.h in Headers */, A7D8B23323E2514200DCD162 /* gl2platform.h in Headers */, - AA7558371595D4D800BBD41B /* SDL_pixels.h in Headers */, A7D8B25123E2514200DCD162 /* vk_layer.h in Headers */, - A7D8AEC123E2514100DCD162 /* SDL_cocoamousetap.h in Headers */, A7D8B26923E2514200DCD162 /* vk_platform.h in Headers */, + A1626A552617008D003F1973 /* SDL_triangle.h in Headers */, A7D8BBF323E2574800DCD162 /* SDL_uikitmessagebox.h in Headers */, A7D8AEB523E2514100DCD162 /* SDL_cocoametalview.h in Headers */, A7D8AEF123E2514100DCD162 /* SDL_cocoaopengles.h in Headers */, @@ -7538,33 +7146,26 @@ A7D8BC0323E2574800DCD162 /* SDL_uikitvulkan.h in Headers */, A7D8B9DA23E2514400DCD162 /* SDL_sysrender.h in Headers */, A7D8BA3423E2514400DCD162 /* SDL_rotate.h in Headers */, - AA7558391595D4D800BBD41B /* SDL_platform.h in Headers */, - AA75583B1595D4D800BBD41B /* SDL_power.h in Headers */, - A7D8AB7C23E2514100DCD162 /* SDL_offscreenopengl.h in Headers */, A7D8BBCB23E2561600DCD162 /* SDL_steamcontroller.h in Headers */, A7D8BB5423E2514500DCD162 /* scancodes_darwin.h in Headers */, A7D8B5BA23E2514300DCD162 /* controller_type.h in Headers */, - A7D8B17323E2514200DCD162 /* SDL_x11opengles.h in Headers */, A7D8B29F23E2514200DCD162 /* vulkan_xlib.h in Headers */, A7D8B25D23E2514200DCD162 /* vulkan_vi.h in Headers */, - A7D8B29923E2514200DCD162 /* vulkan_mir.h in Headers */, - AA75583D1595D4D800BBD41B /* SDL_quit.h in Headers */, + F316AB882B5A02C3002EF551 /* yuv_rgb_common.h in Headers */, + A1BB8B6F27F6CF330057CFA8 /* SDL_list.h in Headers */, A7D8BB4E23E2514500DCD162 /* default_cursor.h in Headers */, A7D8B9FE23E2514400DCD162 /* SDL_render_sw_c.h in Headers */, A7D8BBED23E2574800DCD162 /* SDL_uikitappdelegate.h in Headers */, - AA75583F1595D4D800BBD41B /* SDL_rect.h in Headers */, - AA7558411595D4D800BBD41B /* SDL_render.h in Headers */, + F362B9492B33920500D30B94 /* SDL_hidapi_nintendo.h in Headers */, A7D8BBF923E2574800DCD162 /* SDL_uikitopengles.h in Headers */, + F31A92CC28D4CB39003BFD6A /* SDL_offscreenopengles.h in Headers */, A7D8ABFA23E2514100DCD162 /* SDL_nullvideo.h in Headers */, A7D8B39B23E2514200DCD162 /* SDL_blit_copy.h in Headers */, + F386F6EA2884663E001840AA /* SDL_log_c.h in Headers */, A7D8B3A123E2514200DCD162 /* SDL_RLEaccel_c.h in Headers */, A7D8B24B23E2514200DCD162 /* eglplatform.h in Headers */, - A7D8B1D923E2514200DCD162 /* edid.h in Headers */, A7D8BC0123E2574800DCD162 /* SDL_uikitviewcontroller.h in Headers */, - AA7558431595D4D800BBD41B /* SDL_revision.h in Headers */, A7D8B3E923E2514300DCD162 /* SDL_systhread.h in Headers */, - AA7558451595D4D800BBD41B /* SDL_rwops.h in Headers */, - AA7558471595D4D800BBD41B /* SDL_scancode.h in Headers */, A7D8AECD23E2514100DCD162 /* SDL_cocoaclipboard.h in Headers */, A7D8AEF723E2514100DCD162 /* SDL_cocoamodes.h in Headers */, A7D8B28123E2514200DCD162 /* vulkan_win32.h in Headers */, @@ -7576,47 +7177,32 @@ A7D8BB2423E2514500DCD162 /* scancodes_windows.h in Headers */, A7D8B5C623E2514300DCD162 /* SDL_rwopsbundlesupport.h in Headers */, A7D8B61423E2514300DCD162 /* SDL_syspower.h in Headers */, + F316ABD02B5A02C3002EF551 /* yuv_rgb_lsx_func.h in Headers */, A7D8B28723E2514200DCD162 /* vulkan_macos.h in Headers */, A7D8B29323E2514200DCD162 /* vulkan_xcb.h in Headers */, A7D8B2A523E2514200DCD162 /* vulkan_ios.h in Headers */, A7D8A99C23E2514000DCD162 /* SDL_internal.h in Headers */, - AA7558491595D4D800BBD41B /* SDL_shape.h in Headers */, - AA75584B1595D4D800BBD41B /* SDL_stdinc.h in Headers */, - AA75584D1595D4D800BBD41B /* SDL_surface.h in Headers */, A7D8B26323E2514200DCD162 /* vulkan.h in Headers */, A7D8BB8A23E2514500DCD162 /* SDL_keyboard_c.h in Headers */, - AA75584F1595D4D800BBD41B /* SDL_system.h in Headers */, - AA7558511595D4D800BBD41B /* SDL_syswm.h in Headers */, - AAC070FA195606770073DCDF /* SDL_opengl_glext.h in Headers */, A7D8BB1E23E2514500DCD162 /* SDL_mouse_c.h in Headers */, A7D8B2BD23E2514200DCD162 /* SDL_blit_auto.h in Headers */, A7D8B9EC23E2514400DCD162 /* SDL_blendline.h in Headers */, + F395C1BD2569C6A000942BFF /* SDL_mfijoystick_c.h in Headers */, A7D8AAD723E2514100DCD162 /* SDL_syshaptic.h in Headers */, A7D8AD2023E2514100DCD162 /* SDL_vulkan_internal.h in Headers */, - AA7558531595D4D800BBD41B /* SDL_thread.h in Headers */, A7D8AF1523E2514100DCD162 /* SDL_cocoaevents.h in Headers */, A7D8B25723E2514200DCD162 /* vk_icd.h in Headers */, A7D8ABE823E2514100DCD162 /* SDL_nullframebuffer_c.h in Headers */, - AA7558551595D4D800BBD41B /* SDL_timer.h in Headers */, + F382072A284F3643004DD584 /* SDL_guid.h in Headers */, A7D8AB1F23E2514100DCD162 /* SDL_dynapi_procs.h in Headers */, A7D8B27523E2514200DCD162 /* vulkan_fuchsia.h in Headers */, - AA7558571595D4D800BBD41B /* SDL_touch.h in Headers */, - AA7558591595D4D800BBD41B /* SDL_types.h in Headers */, + 5616CA57252BB35C005D5928 /* SDL_sysurl.h in Headers */, A7D8B57223E2514300DCD162 /* usb_ids.h in Headers */, A7D8BA5823E2514400DCD162 /* SDL_gles2funcs.h in Headers */, - A7D8B57E23E2514300DCD162 /* SDL_sysjoystick_c.h in Headers */, - AA75585B1595D4D800BBD41B /* SDL_version.h in Headers */, - AA75585D1595D4D800BBD41B /* SDL_video.h in Headers */, - AAC070FD195606770073DCDF /* SDL_opengles2_gl2.h in Headers */, - F3950CD9212BC88D00F51292 /* SDL_sensor.h in Headers */, A75FDBC823EA380300529352 /* SDL_hidapi_rumble.h in Headers */, A7D8AC4223E2514100DCD162 /* SDL_sysvideo.h in Headers */, - AAC07103195606770073DCDF /* SDL_opengles2_gl2platform.h in Headers */, - AAC07100195606770073DCDF /* SDL_opengles2_gl2ext.h in Headers */, - A7D8B1FD23E2514200DCD162 /* SDL_x11mouse.h in Headers */, A7D8AB1323E2514100DCD162 /* SDL_dynapi_overrides.h in Headers */, A7D8AEFD23E2514100DCD162 /* SDL_cocoawindow.h in Headers */, - A7D8B1DF23E2514200DCD162 /* SDL_x11vulkan.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -7631,41 +7217,41 @@ DB313FC917554B71006C0E22 /* close_code.h in Headers */, DB313FF917554B71006C0E22 /* SDL.h in Headers */, A7D8AC6223E2514100DCD162 /* SDL_uikitmetalview.h in Headers */, + F362B9582B33EB7300D30B94 /* SDL_steam_virtual_gamepad.h in Headers */, DB313FCA17554B71006C0E22 /* SDL_assert.h in Headers */, A7D8AC0E23E2514100DCD162 /* SDL_shape_internals.h in Headers */, A7D8BA7E23E2514400DCD162 /* SDL_glfuncs.h in Headers */, DB313FCB17554B71006C0E22 /* SDL_atomic.h in Headers */, + F386F6F62884663E001840AA /* SDL_utils_c.h in Headers */, + 75E09169241EA924004729E1 /* SDL_virtualjoystick_c.h in Headers */, A7D8AC0823E2514100DCD162 /* SDL_rect_c.h in Headers */, - A7D8B1D523E2514200DCD162 /* SDL_x11xinput2.h in Headers */, A7D8B9A023E2514400DCD162 /* SDL_shaders_metal_osx.h in Headers */, A7D8B99123E2514400DCD162 /* SDL_shaders_metal_ios.h in Headers */, + F382072D284F3643004DD584 /* SDL_guid.h in Headers */, A7D8AB8A23E2514100DCD162 /* SDL_offscreenwindow.h in Headers */, DB313FCC17554B71006C0E22 /* SDL_audio.h in Headers */, A7D8A97423E2514000DCD162 /* SDL_coremotionsensor.h in Headers */, A7D8AC4A23E2514100DCD162 /* SDL_uikitview.h in Headers */, DB313FFC17554B71006C0E22 /* SDL_bits.h in Headers */, A7D8ACCE23E2514100DCD162 /* SDL_uikitappdelegate.h in Headers */, - A7D8ACA423E2514100DCD162 /* keyinfotable.h in Headers */, DB313FCD17554B71006C0E22 /* SDL_blendmode.h in Headers */, A7D8BB3223E2514500DCD162 /* SDL_dropevents_c.h in Headers */, A7D8AAC123E2514100DCD162 /* SDL_haptic_c.h in Headers */, DB313FCE17554B71006C0E22 /* SDL_clipboard.h in Headers */, A7D8A94A23E2514000DCD162 /* SDL_dataqueue.h in Headers */, A7D8A96223E2514000DCD162 /* SDL_error_c.h in Headers */, - A7D8B21723E2514200DCD162 /* SDL_x11events.h in Headers */, DB313FD017554B71006C0E22 /* SDL_config.h in Headers */, A7D8B98523E2514400DCD162 /* SDL_d3dmath.h in Headers */, - A7D8B1ED23E2514200DCD162 /* SDL_x11window.h in Headers */, DB313FCF17554B71006C0E22 /* SDL_config_macosx.h in Headers */, A7D8ABDE23E2514100DCD162 /* SDL_egl_c.h in Headers */, DB313FD117554B71006C0E22 /* SDL_copying.h in Headers */, + F382338B2738EB8600F7F527 /* SDL_hidapi.h in Headers */, A7D8B3D923E2514300DCD162 /* yuv_rgb.h in Headers */, A7D8B79923E2514400DCD162 /* SDL_dummyaudio.h in Headers */, A7D8AC9823E2514100DCD162 /* SDL_uikitmessagebox.h in Headers */, - A7D8B15123E2514200DCD162 /* SDL_x11messagebox.h in Headers */, + F31A92CF28D4CB39003BFD6A /* SDL_offscreenopengles.h in Headers */, A7D8B3F123E2514300DCD162 /* SDL_thread_c.h in Headers */, A7D8AF0B23E2514100DCD162 /* SDL_cocoamessagebox.h in Headers */, - A7D8B16923E2514200DCD162 /* SDL_x11shape.h in Headers */, DB313FD217554B71006C0E22 /* SDL_cpuinfo.h in Headers */, DB313FD317554B71006C0E22 /* SDL_endian.h in Headers */, DB313FD417554B71006C0E22 /* SDL_error.h in Headers */, @@ -7674,43 +7260,39 @@ A7D8BA0623E2514400DCD162 /* SDL_blendfillrect.h in Headers */, DB313FFB17554B71006C0E22 /* SDL_gamecontroller.h in Headers */, A7D8B55C23E2514300DCD162 /* SDL_hidapijoystick_c.h in Headers */, + F395C1992569C68F00942BFF /* SDL_iokitjoystick_c.h in Headers */, A7D8B2C523E2514200DCD162 /* SDL_pixels_c.h in Headers */, - A7D8B1BD23E2514200DCD162 /* SDL_x11modes.h in Headers */, A7D8B58C23E2514300DCD162 /* SDL_joystick_c.h in Headers */, A7D8B2B323E2514200DCD162 /* vk_sdk_platform.h in Headers */, A7D8BB4A23E2514500DCD162 /* blank_cursor.h in Headers */, DB313FD617554B71006C0E22 /* SDL_gesture.h in Headers */, A7D8B85F23E2514400DCD162 /* SDL_sysaudio.h in Headers */, DB313FD717554B71006C0E22 /* SDL_haptic.h in Headers */, - A7D8BB9823E2514500DCD162 /* SDL_sysevents.h in Headers */, A7D8BB0823E2514500DCD162 /* math_libm.h in Headers */, A7D8AC8023E2514100DCD162 /* SDL_uikitvideo.h in Headers */, A7D8AF2323E2514100DCD162 /* SDL_cocoamouse.h in Headers */, DB313FD817554B71006C0E22 /* SDL_hints.h in Headers */, A7D8ADF123E2514100DCD162 /* SDL_blit_slow.h in Headers */, A7D8B9D023E2514400DCD162 /* SDL_yuv_sw_c.h in Headers */, - A7D8B1B723E2514200DCD162 /* SDL_x11opengl.h in Headers */, A7D8BBB023E2514500DCD162 /* SDL_windowevents_c.h in Headers */, DB313FD917554B71006C0E22 /* SDL_joystick.h in Headers */, A7D8AF0523E2514100DCD162 /* SDL_cocoavideo.h in Headers */, DB313FDA17554B71006C0E22 /* SDL_keyboard.h in Headers */, A7D8ACC223E2514100DCD162 /* SDL_uikitevents.h in Headers */, A7D8BB3E23E2514500DCD162 /* SDL_gesture_c.h in Headers */, + F362B9382B33916600D30B94 /* controller_list.h in Headers */, A7D8BA7823E2514400DCD162 /* SDL_shaders_gl.h in Headers */, A7D8B42D23E2514300DCD162 /* SDL_systhread_c.h in Headers */, + A1BB8B7227F6CF330057CFA8 /* SDL_list.h in Headers */, DB313FDB17554B71006C0E22 /* SDL_keycode.h in Headers */, - A7D8B20B23E2514200DCD162 /* SDL_x11keyboard.h in Headers */, A7D8AE9323E2514100DCD162 /* SDL_cocoakeyboard.h in Headers */, A7D8ACE623E2514100DCD162 /* SDL_uikitvulkan.h in Headers */, - A7D8B1F323E2514200DCD162 /* SDL_x11framebuffer.h in Headers */, - A7D8B22323E2514200DCD162 /* SDL_x11video.h in Headers */, - A7D8B27123E2514200DCD162 /* vulkan.hpp in Headers */, DB313FDC17554B71006C0E22 /* SDL_loadso.h in Headers */, A7D8B22923E2514200DCD162 /* gl2ext.h in Headers */, A7D8BB7423E2514500DCD162 /* SDL_clipboardevents_c.h in Headers */, - A7D8B14B23E2514200DCD162 /* SDL_x11touch.h in Headers */, A7D8AAE523E2514100DCD162 /* SDL_syshaptic_c.h in Headers */, A7D8B94F23E2514400DCD162 /* SDL_hints_c.h in Headers */, + F316ABC12B5A02C3002EF551 /* yuv_rgb_sse.h in Headers */, A7D8B7B723E2514400DCD162 /* SDL_audiodev_c.h in Headers */, A7D8B7A523E2514400DCD162 /* SDL_audio_c.h in Headers */, A7D8AC6E23E2514100DCD162 /* SDL_uikitmodes.h in Headers */, @@ -7724,6 +7306,7 @@ A7D8B2AD23E2514200DCD162 /* vulkan_core.h in Headers */, A7D8A98023E2514000DCD162 /* SDL_syssensor.h in Headers */, A7D8AB0F23E2514100DCD162 /* SDL_dynapi.h in Headers */, + F316ABD32B5A02C3002EF551 /* yuv_rgb_lsx_func.h in Headers */, A7D8B61C23E2514300DCD162 /* SDL_assert_c.h in Headers */, A7D8B8A723E2514400DCD162 /* SDL_diskaudio.h in Headers */, DB313FDE17554B71006C0E22 /* SDL_main.h in Headers */, @@ -7732,9 +7315,11 @@ A7D8B87123E2514400DCD162 /* SDL_wave.h in Headers */, A7D8AEE123E2514100DCD162 /* SDL_cocoaopengl.h in Headers */, A7D8B3CD23E2514300DCD162 /* yuv_rgb_sse_func.h in Headers */, - A7D8B21D23E2514200DCD162 /* imKStoUCS.h in Headers */, + 5605721B2473688D00B46B66 /* SDL_syslocale.h in Headers */, + F316ABCA2B5A02C3002EF551 /* yuv_rgb_std.h in Headers */, A7D8AB6023E2514100DCD162 /* SDL_offscreenevents_c.h in Headers */, - A7D8B1B123E2514200DCD162 /* SDL_x11sym.h in Headers */, + F3973FA828A59BDD00B84553 /* SDL_vacopy.h in Headers */, + A1626A582617008D003F1973 /* SDL_triangle.h in Headers */, A7D8B8D123E2514400DCD162 /* SDL_coreaudio.h in Headers */, A7D8BA1E23E2514400DCD162 /* SDL_draw.h in Headers */, A7D8BA0C23E2514400DCD162 /* SDL_drawline.h in Headers */, @@ -7744,7 +7329,6 @@ A7D8B3B523E2514200DCD162 /* SDL_yuv_c.h in Headers */, A7D8BBA423E2514500DCD162 /* scancodes_xfree86.h in Headers */, A7D8B5DA23E2514300DCD162 /* SDL_syspower.h in Headers */, - A7D8B21123E2514200DCD162 /* SDL_x11clipboard.h in Headers */, DB313FE117554B71006C0E22 /* SDL_name.h in Headers */, A7D8B24723E2514200DCD162 /* eglext.h in Headers */, A7D8BBAA23E2514500DCD162 /* SDL_events_c.h in Headers */, @@ -7756,20 +7340,20 @@ A7D8BA5423E2514400DCD162 /* SDL_shaders_gles2.h in Headers */, DB313FE417554B71006C0E22 /* SDL_opengles2.h in Headers */, A7D8BA4823E2514400DCD162 /* SDL_glesfuncs.h in Headers */, + F316AB8B2B5A02C3002EF551 /* yuv_rgb_common.h in Headers */, + F316ABAF2B5A02C3002EF551 /* yuv_rgb_lsx.h in Headers */, A7D8BA1223E2514400DCD162 /* SDL_blendpoint.h in Headers */, A7D8AB7223E2514100DCD162 /* SDL_offscreenvideo.h in Headers */, A7D8AC0223E2514100DCD162 /* SDL_nullevents_c.h in Headers */, A7D8B58623E2514300DCD162 /* SDL_sysjoystick.h in Headers */, A7D8BBCF23E2561600DCD162 /* SDL_steamcontroller.h in Headers */, A7D8BB6223E2514500DCD162 /* scancodes_linux.h in Headers */, - A7D8B1F923E2514200DCD162 /* SDL_x11dyn.h in Headers */, A7D8BB6823E2514500DCD162 /* SDL_touch_c.h in Headers */, A7D8B4B123E2514300DCD162 /* SDL_gamecontrollerdb.h in Headers */, A7D8AEED23E2514100DCD162 /* SDL_cocoavulkan.h in Headers */, A7D8B23523E2514200DCD162 /* gl2platform.h in Headers */, DB313FE517554B71006C0E22 /* SDL_pixels.h in Headers */, A7D8B25323E2514200DCD162 /* vk_layer.h in Headers */, - A7D8AEC323E2514100DCD162 /* SDL_cocoamousetap.h in Headers */, A7D8B26B23E2514200DCD162 /* vk_platform.h in Headers */, A7D8AEB723E2514100DCD162 /* SDL_cocoametalview.h in Headers */, A7D8AEF323E2514100DCD162 /* SDL_cocoaopengles.h in Headers */, @@ -7780,15 +7364,12 @@ A7D8BA3623E2514400DCD162 /* SDL_rotate.h in Headers */, DB313FE617554B71006C0E22 /* SDL_platform.h in Headers */, DB313FE717554B71006C0E22 /* SDL_power.h in Headers */, - A7D8AB7E23E2514100DCD162 /* SDL_offscreenopengl.h in Headers */, A7D8BB5623E2514500DCD162 /* scancodes_darwin.h in Headers */, A7D8B5BC23E2514300DCD162 /* controller_type.h in Headers */, - A7D8B17523E2514200DCD162 /* SDL_x11opengles.h in Headers */, A7D8AC7A23E2514100DCD162 /* SDL_uikitclipboard.h in Headers */, A7D8B2A123E2514200DCD162 /* vulkan_xlib.h in Headers */, A7D8AC9E23E2514100DCD162 /* SDL_uikitwindow.h in Headers */, A7D8B25F23E2514200DCD162 /* vulkan_vi.h in Headers */, - A7D8B29B23E2514200DCD162 /* vulkan_mir.h in Headers */, DB313FE817554B71006C0E22 /* SDL_quit.h in Headers */, A7D8BB5023E2514500DCD162 /* default_cursor.h in Headers */, A7D8BA0023E2514400DCD162 /* SDL_render_sw_c.h in Headers */, @@ -7798,7 +7379,6 @@ A7D8B39D23E2514200DCD162 /* SDL_blit_copy.h in Headers */, A7D8B3A323E2514200DCD162 /* SDL_RLEaccel_c.h in Headers */, A7D8B24D23E2514200DCD162 /* eglplatform.h in Headers */, - A7D8B1DB23E2514200DCD162 /* edid.h in Headers */, DB313FEB17554B71006C0E22 /* SDL_revision.h in Headers */, A7D8B3EB23E2514300DCD162 /* SDL_systhread.h in Headers */, DB313FEC17554B71006C0E22 /* SDL_rwops.h in Headers */, @@ -7830,6 +7410,7 @@ A7D8BB2023E2514500DCD162 /* SDL_mouse_c.h in Headers */, A7D8B2BF23E2514200DCD162 /* SDL_blit_auto.h in Headers */, A7D8B9EE23E2514400DCD162 /* SDL_blendline.h in Headers */, + F395C1C02569C6A000942BFF /* SDL_mfijoystick_c.h in Headers */, A7D8AAD923E2514100DCD162 /* SDL_syshaptic.h in Headers */, A7D8AD2223E2514100DCD162 /* SDL_vulkan_internal.h in Headers */, DB313FF317554B71006C0E22 /* SDL_thread.h in Headers */, @@ -7841,21 +7422,30 @@ A7D8B27723E2514200DCD162 /* vulkan_fuchsia.h in Headers */, DB313FF517554B71006C0E22 /* SDL_touch.h in Headers */, DB313FF617554B71006C0E22 /* SDL_types.h in Headers */, + 5616CA60252BB35E005D5928 /* SDL_sysurl.h in Headers */, A7D8B57423E2514300DCD162 /* usb_ids.h in Headers */, A7D8BA5A23E2514400DCD162 /* SDL_gles2funcs.h in Headers */, - A7D8B58023E2514300DCD162 /* SDL_sysjoystick_c.h in Headers */, DB313FF717554B71006C0E22 /* SDL_version.h in Headers */, DB313FF817554B71006C0E22 /* SDL_video.h in Headers */, AAC070FE195606770073DCDF /* SDL_opengles2_gl2.h in Headers */, F3950CDA212BC88D00F51292 /* SDL_sensor.h in Headers */, A75FDBCB23EA380300529352 /* SDL_hidapi_rumble.h in Headers */, + F362B94C2B33920500D30B94 /* SDL_hidapi_nintendo.h in Headers */, A7D8AC4423E2514100DCD162 /* SDL_sysvideo.h in Headers */, + F386F6ED2884663E001840AA /* SDL_log_c.h in Headers */, AAC07104195606770073DCDF /* SDL_opengles2_gl2platform.h in Headers */, AAC07101195606770073DCDF /* SDL_opengles2_gl2ext.h in Headers */, - A7D8B1FF23E2514200DCD162 /* SDL_x11mouse.h in Headers */, A7D8AB1523E2514100DCD162 /* SDL_dynapi_overrides.h in Headers */, + F316AB942B5A02C3002EF551 /* yuv_rgb_internal.h in Headers */, A7D8AEFF23E2514100DCD162 /* SDL_cocoawindow.h in Headers */, - A7D8B1E123E2514200DCD162 /* SDL_x11vulkan.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E2D187CA28A5673500D2B4F1 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + F31A92CB28D4CB39003BFD6A /* SDL_offscreenopengles.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -7902,60 +7492,6 @@ productReference = A75FD06C23E25AC700529352 /* libSDL2.dylib */; productType = "com.apple.product-type.library.dynamic"; }; - A75FDB4823E399AC00529352 /* hidapi-iOS */ = { - isa = PBXNativeTarget; - buildConfigurationList = A75FDB5023E399AC00529352 /* Build configuration list for PBXNativeTarget "hidapi-iOS" */; - buildPhases = ( - A75FDB4423E399AC00529352 /* Headers */, - A75FDB4523E399AC00529352 /* Sources */, - A75FDB4623E399AC00529352 /* Frameworks */, - A75FDB4723E399AC00529352 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = "hidapi-iOS"; - productName = hidapi; - productReference = A75FDB4923E399AC00529352 /* hidapi.framework */; - productType = "com.apple.product-type.framework"; - }; - A75FDB6223E3A2C900529352 /* hidapi-tvOS */ = { - isa = PBXNativeTarget; - buildConfigurationList = A75FDB6B23E3A2C900529352 /* Build configuration list for PBXNativeTarget "hidapi-tvOS" */; - buildPhases = ( - A75FDB6323E3A2C900529352 /* Headers */, - A75FDB6523E3A2C900529352 /* Sources */, - A75FDB6723E3A2C900529352 /* Frameworks */, - A75FDB6A23E3A2C900529352 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = "hidapi-tvOS"; - productName = hidapi; - productReference = A75FDB6E23E3A2C900529352 /* hidapi.framework */; - productType = "com.apple.product-type.framework"; - }; - A75FDB8023E4C74400529352 /* hidapi */ = { - isa = PBXNativeTarget; - buildConfigurationList = A75FDB8923E4C74400529352 /* Build configuration list for PBXNativeTarget "hidapi" */; - buildPhases = ( - A75FDB8123E4C74400529352 /* Headers */, - A75FDB8323E4C74400529352 /* Sources */, - A75FDB8523E4C74400529352 /* Frameworks */, - A75FDB8823E4C74400529352 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = hidapi; - productName = hidapi; - productReference = A75FDB8C23E4C74400529352 /* hidapi.framework */; - productType = "com.apple.product-type.framework"; - }; A769B08223E259AE00872273 /* Static Library-tvOS */ = { isa = PBXNativeTarget; buildConfigurationList = A769B23A23E259AE00872273 /* Build configuration list for PBXNativeTarget "Static Library-tvOS" */; @@ -7967,7 +7503,7 @@ ); buildRules = ( ); - comments = "This produces libsdl.a, which is the static build of SDL. You will have to link to the Cocoa and OpenGL frameworks in your application."; + comments = "This produces libSDL.a, which is the static build of SDL. You will have to link to the Cocoa and OpenGL frameworks in your application."; dependencies = ( ); name = "Static Library-tvOS"; @@ -7985,6 +7521,7 @@ A7D88ABF23E2437C00DCD162 /* Sources */, A7D88B4623E2437C00DCD162 /* Frameworks */, A75FDB9F23E4CAFA00529352 /* Embed Frameworks */, + F3ED8107281DB8E600C33C5B /* Convert SDL includes to SDL Framework includes */, ); buildRules = ( ); @@ -8006,6 +7543,7 @@ A7D88C7823E24BED00DCD162 /* Sources */, A7D88D0423E24BED00DCD162 /* Frameworks */, A75FDBA223E4CAFF00529352 /* Embed Frameworks */, + F3ED8108281DB8F200C33C5B /* Convert SDL includes to SDL Framework includes */, ); buildRules = ( ); @@ -8029,7 +7567,7 @@ ); buildRules = ( ); - comments = "This produces libsdl.a, which is the static build of SDL. You will have to link to the Cocoa and OpenGL frameworks in your application."; + comments = "This produces libSDL.a, which is the static build of SDL. You will have to link to the Cocoa and OpenGL frameworks in your application."; dependencies = ( ); name = "Static Library-iOS"; @@ -8047,6 +7585,7 @@ BECDF62C0761BA81005FE872 /* Sources */, BECDF6680761BA81005FE872 /* Frameworks */, A75FDB9C23E4CAEF00529352 /* Embed Frameworks */, + F3ED8106281DB8A500C33C5B /* Convert SDL includes to SDL Framework includes */, ); buildRules = ( ); @@ -8070,7 +7609,7 @@ ); buildRules = ( ); - comments = "This produces libsdl.a, which is the static build of SDL. You will have to link to the Cocoa and OpenGL frameworks in your application."; + comments = "This produces libSDL.a, which is the static build of SDL. You will have to link to the Cocoa and OpenGL frameworks in your application."; dependencies = ( ); name = "Static Library"; @@ -8088,7 +7627,6 @@ buildRules = ( ); dependencies = ( - F3190017240CA3BA00ED104F /* PBXTargetDependency */, BECDF6C60761BA81005FE872 /* PBXTargetDependency */, ); name = "Standard DMG"; @@ -8117,6 +7655,25 @@ productReference = DB31407717554B71006C0E22 /* libSDL2.dylib */; productType = "com.apple.product-type.library.dynamic"; }; + E2D187CE28A5673500D2B4F1 /* xcFramework-iOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = E2D187D628A5673500D2B4F1 /* Build configuration list for PBXNativeTarget "xcFramework-iOS" */; + buildPhases = ( + E2D187CA28A5673500D2B4F1 /* Headers */, + E2D187CB28A5673500D2B4F1 /* Sources */, + E2D187CC28A5673500D2B4F1 /* Frameworks */, + E2D187CD28A5673500D2B4F1 /* Resources */, + E2D187E728A5685000D2B4F1 /* ShellScript */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "xcFramework-iOS"; + productName = SDL2; + productReference = E2D187CF28A5673500D2B4F1 /* SDL2.framework */; + productType = "com.apple.product-type.framework"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -8125,8 +7682,8 @@ attributes = { LastUpgradeCheck = 1130; TargetAttributes = { - A75FDB4823E399AC00529352 = { - CreatedOnToolsVersion = 11.3.1; + E2D187CE28A5673500D2B4F1 = { + CreatedOnToolsVersion = 12.4; }; }; }; @@ -8147,6 +7704,7 @@ BECDF5FE0761BA81005FE872 /* Framework */, A7D88A1423E2437C00DCD162 /* Framework-iOS */, A7D88BC923E24BED00DCD162 /* Framework-tvOS */, + E2D187CE28A5673500D2B4F1 /* xcFramework-iOS */, BECDF66D0761BA81005FE872 /* Static Library */, A7D88D1723E24D3B00DCD162 /* Static Library-iOS */, A769B08223E259AE00872273 /* Static Library-tvOS */, @@ -8154,54 +7712,16 @@ A75FCCFB23E25AB700529352 /* Shared Library-iOS */, A75FCEB423E25AC700529352 /* Shared Library-tvOS */, BECDF6BB0761BA81005FE872 /* Standard DMG */, - A75FDB8023E4C74400529352 /* hidapi */, - A75FDB4823E399AC00529352 /* hidapi-iOS */, - A75FDB6223E3A2C900529352 /* hidapi-tvOS */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ - A75FDB4723E399AC00529352 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - A75FDBB223E4CB7000529352 /* LICENSE-gpl3.txt in Resources */, - A75FDBA923E4CB7000529352 /* LICENSE-bsd.txt in Resources */, - A75FDBAC23E4CB7000529352 /* AUTHORS.txt in Resources */, - A75FDBB523E4CB7000529352 /* LICENSE.txt in Resources */, - A75FDBAF23E4CB7000529352 /* LICENSE-orig.txt in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - A75FDB6A23E3A2C900529352 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - A75FDBB323E4CB7000529352 /* LICENSE-gpl3.txt in Resources */, - A75FDBAA23E4CB7000529352 /* LICENSE-bsd.txt in Resources */, - A75FDBAD23E4CB7000529352 /* AUTHORS.txt in Resources */, - A75FDBB623E4CB7000529352 /* LICENSE.txt in Resources */, - A75FDBB023E4CB7000529352 /* LICENSE-orig.txt in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - A75FDB8823E4C74400529352 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - A75FDBB123E4CB7000529352 /* LICENSE-gpl3.txt in Resources */, - A75FDBA823E4CB7000529352 /* LICENSE-bsd.txt in Resources */, - A75FDBAB23E4CB7000529352 /* AUTHORS.txt in Resources */, - A75FDBB423E4CB7000529352 /* LICENSE.txt in Resources */, - A75FDBAE23E4CB7000529352 /* LICENSE-orig.txt in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; A7D88ABE23E2437C00DCD162 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + F37A8E1B28405AA100C38E95 /* CMake in Resources */, A75FDBBA23E4CBC700529352 /* ReadMe.txt in Resources */, A75FDBB923E4CBC700529352 /* License.txt in Resources */, ); @@ -8211,6 +7731,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + F37A8E1C28405AA100C38E95 /* CMake in Resources */, A75FDBBC23E4CBC800529352 /* ReadMe.txt in Resources */, A75FDBBB23E4CBC800529352 /* License.txt in Resources */, ); @@ -8220,11 +7741,19 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + F37A8E1A28405AA100C38E95 /* CMake in Resources */, A75FDBB823E4CBC700529352 /* ReadMe.txt in Resources */, A75FDBB723E4CBC700529352 /* License.txt in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; + E2D187CD28A5673500D2B4F1 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXRezBuildPhase section */ @@ -8282,6 +7811,77 @@ shellPath = /bin/sh; shellScript = "# Sign framework\nif [ \"$SDL_CODESIGN_IDENTITY\" != \"\" ]; then\n codesign --force --deep --sign \"$SDL_CODESIGN_IDENTITY\" $TARGET_BUILD_DIR/SDL2.framework/Versions/A || exit $?\nfi\n\n# clean up the framework, remove headers, extra files\nmkdir -p build/dmg-tmp\ncp -a $TARGET_BUILD_DIR/SDL2.framework build/dmg-tmp/\n\ncp pkg-support/resources/License.txt build/dmg-tmp\ncp pkg-support/resources/ReadMe.txt build/dmg-tmp\n\n# remove the .DS_Store files if any (we may want to provide one in the future for fancy .dmgs)\nfind build/dmg-tmp -name .DS_Store -exec rm -f \"{}\" \\;\n\n# for fancy .dmg\nmkdir -p build/dmg-tmp/.logo\ncp pkg-support/resources/SDL_DS_Store build/dmg-tmp/.DS_Store\ncp pkg-support/sdl_logo.pdf build/dmg-tmp/.logo\n\n# create the dmg\nhdiutil create -ov -fs HFS+ -volname SDL2 -srcfolder build/dmg-tmp build/SDL2.dmg\n\n# clean up\nrm -rf build/dmg-tmp\n"; }; + E2D187E728A5685000D2B4F1 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "# Build an xcframework with both device and simulator files for all platforms.\n# Adapted from an answer in\n# https://developer.apple.com/forums/thread/666335?answerId=685927022#685927022\n\nif [ \"$XCODE_VERSION_ACTUAL\" -lt 1100 ]\nthen\n\techo \"error: Building an xcframework requires Xcode 11 minimum.\"\n\texit 1\nfi\n\nSCHEME_NAME=\"Framework-iOS\"\nFRAMEWORK_NAME=\"SDL2\"\nPROJECT_NAME=\"SDL\"\n\nSIMULATOR_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-iphonesimulator.xcarchive\"\nDEVICE_ARCHIVE_PATH=\"${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-iphoneos.xcarchive\"\n\nOUTPUT_DIR=\"./Products/\"\n\n# Simulator xcarchive (arm64, i386, x86_64)\nxcodebuild archive \\\n\tONLY_ACTIVE_ARCH=NO \\\n\t-scheme ${SCHEME_NAME} \\\n\t-project \"${PROJECT_NAME}.xcodeproj\" \\\n\t-archivePath ${SIMULATOR_ARCHIVE_PATH} \\\n\t-sdk iphonesimulator \\\n\tBUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n\tSKIP_INSTALL=NO\n\n# Device xcarchive (arm64, armv7)\nxcodebuild archive \\\n\t-scheme ${SCHEME_NAME} \\\n\t-project \"${PROJECT_NAME}.xcodeproj\" \\\n\t-archivePath ${DEVICE_ARCHIVE_PATH} \\\n\t-sdk iphoneos \\\n\tBUILD_LIBRARY_FOR_DISTRIBUTION=YES \\\n\tSKIP_INSTALL=NO\n\n# Clean-up any existing instance of this xcframework from the Products directory\nrm -rf \"${OUTPUT_DIR}${FRAMEWORK_NAME}.xcframework\"\n\n# Create final xcframework\nxcodebuild -create-xcframework \\\n\t-framework \"${DEVICE_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n\t-framework \"${SIMULATOR_ARCHIVE_PATH}\"/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \\\n\t-output ${OUTPUT_DIR}/${FRAMEWORK_NAME}.xcframework\n\n# Ensure git doesn't pick up on our Products folder. \nrm -rf ${OUTPUT_DIR}/.gitignore\necho \"*\" >> ${OUTPUT_DIR}/.gitignore\n"; + }; + F3ED8106281DB8A500C33C5B /* Convert SDL includes to SDL Framework includes */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "Convert SDL includes to SDL Framework includes"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "cd \"$BUILT_PRODUCTS_DIR/$PUBLIC_HEADERS_FOLDER_PATH\"\nsed -i '' -e 's,#include \"\\(.*\\)\",#include ,' *.h\n"; + }; + F3ED8107281DB8E600C33C5B /* Convert SDL includes to SDL Framework includes */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "Convert SDL includes to SDL Framework includes"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "cd \"$BUILT_PRODUCTS_DIR/$PUBLIC_HEADERS_FOLDER_PATH\"\nsed -i '' -e 's,#include \"\\(.*\\)\",#include ,' *.h\n"; + }; + F3ED8108281DB8F200C33C5B /* Convert SDL includes to SDL Framework includes */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "Convert SDL includes to SDL Framework includes"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "cd \"$BUILT_PRODUCTS_DIR/$PUBLIC_HEADERS_FOLDER_PATH\"\nsed -i '' -e 's,#include \"\\(.*\\)\",#include ,' *.h\n"; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -8292,6 +7892,8 @@ A75FCDE923E25AB700529352 /* SDL_drawline.c in Sources */, A75FCDEA23E25AB700529352 /* SDL_yuv.c in Sources */, A75FCDEB23E25AB700529352 /* SDL_sysfilesystem.m in Sources */, + F395BF6C25633B2400942BFF /* SDL_crc32.c in Sources */, + F3A490A52554D38600E92A8B /* SDL_hidapi_ps5.c in Sources */, A75FCDEC23E25AB700529352 /* e_pow.c in Sources */, A75FCDED23E25AB700529352 /* SDL_systls.c in Sources */, A75FCDEE23E25AB700529352 /* SDL_vulkan_utils.c in Sources */, @@ -8302,24 +7904,23 @@ A75FCDF223E25AB700529352 /* SDL_render_metal.m in Sources */, A75FCDF323E25AB700529352 /* SDL_clipboard.c in Sources */, A75FCDF423E25AB700529352 /* SDL_cocoaevents.m in Sources */, - A75FCDF523E25AB700529352 /* SDL_x11messagebox.c in Sources */, A75FCDF623E25AB700529352 /* SDL_audiocvt.c in Sources */, A75FCDF723E25AB700529352 /* SDL_shape.c in Sources */, A75FCDF823E25AB700529352 /* SDL_rotate.c in Sources */, + F3973FB228A59BDD00B84553 /* SDL_crc16.c in Sources */, A75FCDF923E25AB700529352 /* SDL_coremotionsensor.m in Sources */, A75FDAB123E2795C00529352 /* SDL_hidapi_steam.c in Sources */, A75FCDFA23E25AB700529352 /* SDL_touch.c in Sources */, - A75FCDFB23E25AB700529352 /* SDL_x11events.c in Sources */, + A1626A452617006A003F1973 /* SDL_triangle.c in Sources */, A75FCDFC23E25AB700529352 /* SDL_uikitmessagebox.m in Sources */, A75FCDFD23E25AB700529352 /* SDL_thread.c in Sources */, A75FCDFE23E25AB700529352 /* SDL_hidapi_xbox360w.c in Sources */, A75FCDFF23E25AB700529352 /* SDL_atomic.c in Sources */, A75FCE0023E25AB700529352 /* SDL_displayevents.c in Sources */, - A75FCE0123E25AB700529352 /* SDL_cocoamousetap.m in Sources */, A75FCE0223E25AB700529352 /* SDL_log.c in Sources */, A75FCE0323E25AB700529352 /* SDL_cocoaopengl.m in Sources */, A75FCE0423E25AB700529352 /* SDL_offscreenframebuffer.c in Sources */, - A75FCE0523E25AB700529352 /* yuv_rgb.c in Sources */, + F323060628939F6400E66D30 /* SDL_hidapi_combined.c in Sources */, A75FCE0623E25AB700529352 /* SDL_render_gles.c in Sources */, A75FCE0723E25AB700529352 /* SDL_systhread.c in Sources */, A75FCE0823E25AB700529352 /* SDL_windowevents.c in Sources */, @@ -8330,28 +7931,31 @@ A75FCE0D23E25AB700529352 /* SDL_systimer.c in Sources */, A75FCE0E23E25AB700529352 /* SDL_uikitclipboard.m in Sources */, A75FCE0F23E25AB700529352 /* SDL_render_sw.c in Sources */, - A75FCE1023E25AB700529352 /* SDL_x11video.c in Sources */, A75FCE1123E25AB700529352 /* SDL_syssem.c in Sources */, A75FCE1223E25AB700529352 /* SDL_hidapi_xbox360.c in Sources */, A75FCE1323E25AB700529352 /* SDL_coreaudio.m in Sources */, A75FCE1423E25AB700529352 /* SDL_blendline.c in Sources */, + F38233982738EC1800F7F527 /* hid.m in Sources */, A75FCE1523E25AB700529352 /* SDL_blit_A.c in Sources */, A75FCE1623E25AB700529352 /* SDL_d3dmath.c in Sources */, - A75FCE1723E25AB700529352 /* SDL_x11mouse.c in Sources */, A75FCE1823E25AB700529352 /* SDL_nullvideo.c in Sources */, A75FCE1923E25AB700529352 /* SDL_offscreenevents.c in Sources */, A75FCE1A23E25AB700529352 /* SDL_uikitview.m in Sources */, A75FCE1B23E25AB700529352 /* SDL_nullevents.c in Sources */, + F362B9442B33920500D30B94 /* SDL_hidapi_steamdeck.c in Sources */, A75FCE1C23E25AB700529352 /* SDL_audiodev.c in Sources */, A75FCE1D23E25AB700529352 /* SDL_cocoaclipboard.m in Sources */, A75FCE1E23E25AB700529352 /* SDL_blit_slow.c in Sources */, A75FCE1F23E25AB700529352 /* s_copysign.c in Sources */, A75FCE2023E25AB700529352 /* SDL_haptic.c in Sources */, A75FCE2123E25AB700529352 /* SDL_uikitvulkan.m in Sources */, - A75FCE2223E25AB700529352 /* SDL_x11modes.c in Sources */, + F3984CD725BCC92900374F43 /* SDL_hidapi_stadia.c in Sources */, + F382071A284F3609004DD584 /* controller_type.c in Sources */, + 75E09161241EA924004729E1 /* SDL_virtualjoystick.c in Sources */, A75FCE2323E25AB700529352 /* SDL_cocoametalview.m in Sources */, A75FCE2423E25AB700529352 /* SDL_audiotypecvt.c in Sources */, A75FCE2523E25AB700529352 /* SDL_uikitevents.m in Sources */, + F3820724284F362F004DD584 /* SDL_guid.c in Sources */, A75FCE2623E25AB700529352 /* SDL_uikitmodes.m in Sources */, A75FCE2723E25AB700529352 /* SDL_blit_N.c in Sources */, A75FCE2823E25AB700529352 /* SDL_dropevents.c in Sources */, @@ -8360,7 +7964,9 @@ A75FCE2B23E25AB700529352 /* SDL_power.c in Sources */, A75FCE2C23E25AB700529352 /* SDL_cocoakeyboard.m in Sources */, A75FCE2D23E25AB700529352 /* SDL_dynapi.c in Sources */, + F388C95C28B5F6F700661ECF /* SDL_hidapi_ps3.c in Sources */, A75FCE2E23E25AB700529352 /* SDL_shaders_gl.c in Sources */, + 560572152473688300B46B66 /* SDL_locale.c in Sources */, A75FCE2F23E25AB700529352 /* e_log.c in Sources */, A75FCE3023E25AB700529352 /* SDL_cocoamessagebox.m in Sources */, A75FCE3123E25AB700529352 /* SDL_blendfillrect.c in Sources */, @@ -8368,26 +7974,26 @@ A75FCE3323E25AB700529352 /* SDL_cocoashape.m in Sources */, A75FCE3423E25AB700529352 /* SDL_cocoamouse.m in Sources */, A75FCE3523E25AB700529352 /* SDL_error.c in Sources */, + F3D60A8A28C16A1900788A3A /* SDL_hidapi_wii.c in Sources */, A75FCE3623E25AB700529352 /* SDL_blit.c in Sources */, A75FCE3723E25AB700529352 /* SDL_rwops.c in Sources */, + F38233922738EBF300F7F527 /* SDL_hidapi.c in Sources */, A75FCE3823E25AB700529352 /* SDL_uikitviewcontroller.m in Sources */, A75FCE3923E25AB700529352 /* s_cos.c in Sources */, A75FCE3A23E25AB700529352 /* SDL_yuv_sw.c in Sources */, A75FCE3B23E25AB700529352 /* SDL_wave.c in Sources */, A75FCE3C23E25AB700529352 /* s_tan.c in Sources */, A75FCE3D23E25AB700529352 /* SDL_hints.c in Sources */, + 9846B083287A9020000C35C8 /* SDL_hidapi_shield.c in Sources */, A75FCE3E23E25AB700529352 /* SDL_hidapi_ps4.c in Sources */, A75FCE3F23E25AB700529352 /* SDL_pixels.c in Sources */, - A75FCE4023E25AB700529352 /* SDL_x11clipboard.c in Sources */, A75FCE4123E25AB700529352 /* SDL_sysloadso.c in Sources */, - A75FCE4223E25AB700529352 /* SDL_x11xinput2.c in Sources */, + F31A92DA28D4CB39003BFD6A /* SDL_offscreenopengles.c in Sources */, A75FCE4323E25AB700529352 /* SDL_syspower.c in Sources */, - A75FCE4423E25AB700529352 /* SDL_x11touch.c in Sources */, A75FCE4523E25AB700529352 /* SDL_iconv.c in Sources */, A75FCE4623E25AB700529352 /* s_fabs.c in Sources */, - A75FCE4723E25AB700529352 /* SDL_x11shape.c in Sources */, - A75FCE4823E25AB700529352 /* imKStoUCS.c in Sources */, A75FCE4923E25AB700529352 /* SDL_shaders_metal.metal in Sources */, + F395C1B82569C6A000942BFF /* SDL_mfijoystick.m in Sources */, A75FCE4A23E25AB700529352 /* SDL_uikitwindow.m in Sources */, A75FCE4B23E25AB700529352 /* SDL_render.c in Sources */, A75FCE4C23E25AB700529352 /* SDL_stretch.c in Sources */, @@ -8398,10 +8004,12 @@ A75FCE5123E25AB700529352 /* e_log10.c in Sources */, A75FCE5223E25AB700529352 /* SDL_uikitopenglview.m in Sources */, A75FCE5323E25AB700529352 /* SDL_mixer.c in Sources */, + 5616CA64252BB35F005D5928 /* SDL_url.c in Sources */, A75FCE5423E25AB700529352 /* SDL_events.c in Sources */, + F316AB9E2B5A02C3002EF551 /* yuv_rgb_std.c in Sources */, + F386F7002884663E001840AA /* SDL_utils.c in Sources */, A75FCE5523E25AB700529352 /* SDL_blit_0.c in Sources */, A75FCE5623E25AB700529352 /* k_tan.c in Sources */, - A75FCE5723E25AB700529352 /* SDL_x11vulkan.c in Sources */, A75FCE5823E25AB700529352 /* SDL_diskaudio.c in Sources */, A75FCE5923E25AB700529352 /* SDL_egl.c in Sources */, A75FCE5A23E25AB700529352 /* SDL_RLEaccel.c in Sources */, @@ -8412,31 +8020,29 @@ A75FCE6023E25AB700529352 /* SDL_fillrect.c in Sources */, A75FCE6123E25AB700529352 /* SDL_nullframebuffer.c in Sources */, A75FCE6223E25AB700529352 /* SDL_dummysensor.c in Sources */, + F3ADAB922576F0B400A6B1D9 /* SDL_sysurl.m in Sources */, A75FCE6323E25AB700529352 /* SDL_string.c in Sources */, A75FCE6423E25AB700529352 /* SDL_render_gl.c in Sources */, + F316ABA72B5A02C3002EF551 /* yuv_rgb_sse.c in Sources */, A75FCE6523E25AB700529352 /* SDL_uikitopengles.m in Sources */, - A75FCE6623E25AB700529352 /* SDL_x11opengles.c in Sources */, A75FCE6723E25AB700529352 /* SDL_cocoamodes.m in Sources */, A75FCE6823E25AB700529352 /* k_rem_pio2.c in Sources */, - A75FCE6923E25AB700529352 /* SDL_sysjoystick.c in Sources */, A75FCE6A23E25AB700529352 /* SDL_gesture.c in Sources */, A75FCE6B23E25AB700529352 /* SDL_getenv.c in Sources */, A75FCE6C23E25AB700529352 /* SDL_hidapi_gamecube.c in Sources */, A75FCE6D23E25AB700529352 /* SDL_joystick.c in Sources */, A75FCE6E23E25AB700529352 /* SDL_render_gles2.c in Sources */, A75FCE6F23E25AB700529352 /* SDL_surface.c in Sources */, - A75FDAAA23E2792500529352 /* hid.m in Sources */, A75FCE7023E25AB700529352 /* SDL_hidapi_xboxone.c in Sources */, A75FCE7123E25AB700529352 /* SDL_blit_auto.c in Sources */, - A75FCE7223E25AB700529352 /* SDL_x11keyboard.c in Sources */, A75FCE7323E25AB700529352 /* SDL_keyboard.c in Sources */, A75FCE7523E25AB700529352 /* SDL_rect.c in Sources */, A75FCE7623E25AB700529352 /* SDL_cocoaopengles.m in Sources */, A75FCE7723E25AB700529352 /* SDL_qsort.c in Sources */, + 5605720D2473687B00B46B66 /* SDL_syslocale.m in Sources */, A75FCE7823E25AB700529352 /* SDL_hidapi_switch.c in Sources */, A75FCE7923E25AB700529352 /* SDL_strtokr.c in Sources */, A75FCE7A23E25AB700529352 /* SDL_clipboardevents.c in Sources */, - A75FCE7B23E25AB700529352 /* SDL_x11framebuffer.c in Sources */, A75FCE7C23E25AB700529352 /* k_cos.c in Sources */, A75FCE7D23E25AB700529352 /* SDL_hidapijoystick.c in Sources */, A75FCE7E23E25AB700529352 /* SDL_malloc.c in Sources */, @@ -8448,35 +8054,34 @@ A75FCE8423E25AB700529352 /* e_exp.c in Sources */, A75FCE8523E25AB700529352 /* SDL_quit.c in Sources */, A75FCE8623E25AB700529352 /* SDL_cocoawindow.m in Sources */, + A1BB8B6A27F6CF330057CFA8 /* SDL_list.c in Sources */, A75FCE8723E25AB700529352 /* SDL_sysmutex.c in Sources */, A75FCE8823E25AB700529352 /* SDL_syshaptic.c in Sources */, + F3F07D61269640160074468B /* SDL_hidapi_luna.c in Sources */, A75FCE8923E25AB700529352 /* SDL_rwopsbundlesupport.m in Sources */, A75FCE8A23E25AB700529352 /* SDL_video.c in Sources */, - A75FCE8B23E25AB700529352 /* SDL_offscreenopengl.c in Sources */, A75FCE8C23E25AB700529352 /* SDL_uikitmetalview.m in Sources */, A75FCE8D23E25AB700529352 /* SDL_steamcontroller.c in Sources */, A75FCE8E23E25AB700529352 /* SDL_shaders_gles2.c in Sources */, A75FCE8F23E25AB700529352 /* SDL_blit_1.c in Sources */, - A75FDAC623E28BD900529352 /* SDL_sysjoystick.m in Sources */, - A75FCE9023E25AB700529352 /* SDL_x11dyn.c in Sources */, A75FCE9123E25AB700529352 /* SDL_mouse.c in Sources */, A75FCE9223E25AB700529352 /* e_rem_pio2.c in Sources */, A75FCE9323E25AB700529352 /* SDL_dataqueue.c in Sources */, + F395C1A32569C68F00942BFF /* SDL_iokitjoystick.c in Sources */, A75FCE9423E25AB700529352 /* SDL_sysjoystick.c in Sources */, A75FCE9523E25AB700529352 /* SDL_cpuinfo.c in Sources */, A75FCE9623E25AB700529352 /* SDL_sensor.c in Sources */, - A75FCE9723E25AB700529352 /* SDL_x11window.c in Sources */, A75FCE9823E25AB700529352 /* k_sin.c in Sources */, - A75FCE9923E25AB700529352 /* edid-parse.c in Sources */, A75FCE9A23E25AB700529352 /* SDL_systimer.c in Sources */, A75FCE9B23E25AB700529352 /* SDL_drawpoint.c in Sources */, A75FCE9C23E25AB700529352 /* e_sqrt.c in Sources */, A75FCE9D23E25AB700529352 /* SDL_cocoavideo.m in Sources */, + F362B9622B33EB7300D30B94 /* SDL_steam_virtual_gamepad.c in Sources */, A75FCE9F23E25AB700529352 /* SDL.c in Sources */, - A75FCEA023E25AB700529352 /* SDL_x11opengl.c in Sources */, A75FCEA123E25AB700529352 /* SDL_cocoavulkan.m in Sources */, A75FCEA223E25AB700529352 /* SDL_uikitappdelegate.m in Sources */, A75FCEA323E25AB700529352 /* SDL_offscreenwindow.c in Sources */, + F316ABB92B5A02C3002EF551 /* yuv_rgb_lsx.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -8487,6 +8092,8 @@ A75FCFA223E25AC700529352 /* SDL_drawline.c in Sources */, A75FCFA323E25AC700529352 /* SDL_yuv.c in Sources */, A75FCFA423E25AC700529352 /* SDL_sysfilesystem.m in Sources */, + F395BF6D25633B2400942BFF /* SDL_crc32.c in Sources */, + F3A490A62554D38600E92A8B /* SDL_hidapi_ps5.c in Sources */, A75FCFA523E25AC700529352 /* e_pow.c in Sources */, A75FCFA623E25AC700529352 /* SDL_systls.c in Sources */, A75FCFA723E25AC700529352 /* SDL_vulkan_utils.c in Sources */, @@ -8497,24 +8104,23 @@ A75FCFAB23E25AC700529352 /* SDL_render_metal.m in Sources */, A75FCFAC23E25AC700529352 /* SDL_clipboard.c in Sources */, A75FCFAD23E25AC700529352 /* SDL_cocoaevents.m in Sources */, - A75FCFAE23E25AC700529352 /* SDL_x11messagebox.c in Sources */, A75FCFAF23E25AC700529352 /* SDL_audiocvt.c in Sources */, A75FCFB023E25AC700529352 /* SDL_shape.c in Sources */, A75FCFB123E25AC700529352 /* SDL_rotate.c in Sources */, + F3973FB328A59BDD00B84553 /* SDL_crc16.c in Sources */, A75FCFB223E25AC700529352 /* SDL_coremotionsensor.m in Sources */, A75FDAB223E2795C00529352 /* SDL_hidapi_steam.c in Sources */, A75FCFB323E25AC700529352 /* SDL_touch.c in Sources */, - A75FCFB423E25AC700529352 /* SDL_x11events.c in Sources */, + A1626A462617006A003F1973 /* SDL_triangle.c in Sources */, A75FCFB523E25AC700529352 /* SDL_uikitmessagebox.m in Sources */, A75FCFB623E25AC700529352 /* SDL_thread.c in Sources */, A75FCFB723E25AC700529352 /* SDL_hidapi_xbox360w.c in Sources */, A75FCFB823E25AC700529352 /* SDL_atomic.c in Sources */, A75FCFB923E25AC700529352 /* SDL_displayevents.c in Sources */, - A75FCFBA23E25AC700529352 /* SDL_cocoamousetap.m in Sources */, A75FCFBB23E25AC700529352 /* SDL_log.c in Sources */, A75FCFBC23E25AC700529352 /* SDL_cocoaopengl.m in Sources */, A75FCFBD23E25AC700529352 /* SDL_offscreenframebuffer.c in Sources */, - A75FCFBE23E25AC700529352 /* yuv_rgb.c in Sources */, + F323060728939F6400E66D30 /* SDL_hidapi_combined.c in Sources */, A75FCFBF23E25AC700529352 /* SDL_render_gles.c in Sources */, A75FCFC023E25AC700529352 /* SDL_systhread.c in Sources */, A75FCFC123E25AC700529352 /* SDL_windowevents.c in Sources */, @@ -8525,28 +8131,31 @@ A75FCFC623E25AC700529352 /* SDL_systimer.c in Sources */, A75FCFC723E25AC700529352 /* SDL_uikitclipboard.m in Sources */, A75FCFC823E25AC700529352 /* SDL_render_sw.c in Sources */, - A75FCFC923E25AC700529352 /* SDL_x11video.c in Sources */, A75FCFCA23E25AC700529352 /* SDL_syssem.c in Sources */, A75FCFCB23E25AC700529352 /* SDL_hidapi_xbox360.c in Sources */, A75FCFCC23E25AC700529352 /* SDL_coreaudio.m in Sources */, A75FCFCD23E25AC700529352 /* SDL_blendline.c in Sources */, + F38233992738EC1800F7F527 /* hid.m in Sources */, A75FCFCE23E25AC700529352 /* SDL_blit_A.c in Sources */, A75FCFCF23E25AC700529352 /* SDL_d3dmath.c in Sources */, - A75FCFD023E25AC700529352 /* SDL_x11mouse.c in Sources */, A75FCFD123E25AC700529352 /* SDL_nullvideo.c in Sources */, A75FCFD223E25AC700529352 /* SDL_offscreenevents.c in Sources */, A75FCFD323E25AC700529352 /* SDL_uikitview.m in Sources */, A75FCFD423E25AC700529352 /* SDL_nullevents.c in Sources */, + F362B9452B33920500D30B94 /* SDL_hidapi_steamdeck.c in Sources */, A75FCFD523E25AC700529352 /* SDL_audiodev.c in Sources */, A75FCFD623E25AC700529352 /* SDL_cocoaclipboard.m in Sources */, A75FCFD723E25AC700529352 /* SDL_blit_slow.c in Sources */, A75FCFD823E25AC700529352 /* s_copysign.c in Sources */, A75FCFD923E25AC700529352 /* SDL_haptic.c in Sources */, A75FCFDA23E25AC700529352 /* SDL_uikitvulkan.m in Sources */, - A75FCFDB23E25AC700529352 /* SDL_x11modes.c in Sources */, + F3984CD825BCC92900374F43 /* SDL_hidapi_stadia.c in Sources */, + F382071B284F3609004DD584 /* controller_type.c in Sources */, + 75E09162241EA924004729E1 /* SDL_virtualjoystick.c in Sources */, A75FCFDC23E25AC700529352 /* SDL_cocoametalview.m in Sources */, A75FCFDD23E25AC700529352 /* SDL_audiotypecvt.c in Sources */, A75FCFDE23E25AC700529352 /* SDL_uikitevents.m in Sources */, + F3820725284F362F004DD584 /* SDL_guid.c in Sources */, A75FCFDF23E25AC700529352 /* SDL_uikitmodes.m in Sources */, A75FCFE023E25AC700529352 /* SDL_blit_N.c in Sources */, A75FCFE123E25AC700529352 /* SDL_dropevents.c in Sources */, @@ -8555,7 +8164,9 @@ A75FCFE423E25AC700529352 /* SDL_power.c in Sources */, A75FCFE523E25AC700529352 /* SDL_cocoakeyboard.m in Sources */, A75FCFE623E25AC700529352 /* SDL_dynapi.c in Sources */, + F388C95D28B5F6F700661ECF /* SDL_hidapi_ps3.c in Sources */, A75FCFE723E25AC700529352 /* SDL_shaders_gl.c in Sources */, + 560572162473688400B46B66 /* SDL_locale.c in Sources */, A75FCFE823E25AC700529352 /* e_log.c in Sources */, A75FCFE923E25AC700529352 /* SDL_cocoamessagebox.m in Sources */, A75FCFEA23E25AC700529352 /* SDL_blendfillrect.c in Sources */, @@ -8563,26 +8174,26 @@ A75FCFEC23E25AC700529352 /* SDL_cocoashape.m in Sources */, A75FCFED23E25AC700529352 /* SDL_cocoamouse.m in Sources */, A75FCFEE23E25AC700529352 /* SDL_error.c in Sources */, + F3D60A8B28C16A1900788A3A /* SDL_hidapi_wii.c in Sources */, A75FCFEF23E25AC700529352 /* SDL_blit.c in Sources */, A75FCFF023E25AC700529352 /* SDL_rwops.c in Sources */, + F38233932738EBF300F7F527 /* SDL_hidapi.c in Sources */, A75FCFF123E25AC700529352 /* SDL_uikitviewcontroller.m in Sources */, A75FCFF223E25AC700529352 /* s_cos.c in Sources */, A75FCFF323E25AC700529352 /* SDL_yuv_sw.c in Sources */, A75FCFF423E25AC700529352 /* SDL_wave.c in Sources */, A75FCFF523E25AC700529352 /* s_tan.c in Sources */, A75FCFF623E25AC700529352 /* SDL_hints.c in Sources */, + 9846B084287A9020000C35C8 /* SDL_hidapi_shield.c in Sources */, A75FCFF723E25AC700529352 /* SDL_hidapi_ps4.c in Sources */, A75FCFF823E25AC700529352 /* SDL_pixels.c in Sources */, - A75FCFF923E25AC700529352 /* SDL_x11clipboard.c in Sources */, A75FCFFA23E25AC700529352 /* SDL_sysloadso.c in Sources */, - A75FCFFB23E25AC700529352 /* SDL_x11xinput2.c in Sources */, + F31A92DB28D4CB39003BFD6A /* SDL_offscreenopengles.c in Sources */, A75FCFFC23E25AC700529352 /* SDL_syspower.c in Sources */, - A75FCFFD23E25AC700529352 /* SDL_x11touch.c in Sources */, A75FCFFE23E25AC700529352 /* SDL_iconv.c in Sources */, A75FCFFF23E25AC700529352 /* s_fabs.c in Sources */, - A75FD00023E25AC700529352 /* SDL_x11shape.c in Sources */, - A75FD00123E25AC700529352 /* imKStoUCS.c in Sources */, A75FD00223E25AC700529352 /* SDL_shaders_metal.metal in Sources */, + F395C1B92569C6A000942BFF /* SDL_mfijoystick.m in Sources */, A75FD00323E25AC700529352 /* SDL_uikitwindow.m in Sources */, A75FD00423E25AC700529352 /* SDL_render.c in Sources */, A75FD00523E25AC700529352 /* SDL_stretch.c in Sources */, @@ -8593,10 +8204,12 @@ A75FD00A23E25AC700529352 /* e_log10.c in Sources */, A75FD00B23E25AC700529352 /* SDL_uikitopenglview.m in Sources */, A75FD00C23E25AC700529352 /* SDL_mixer.c in Sources */, + 5616CA67252BB361005D5928 /* SDL_url.c in Sources */, A75FD00D23E25AC700529352 /* SDL_events.c in Sources */, + F316AB9F2B5A02C3002EF551 /* yuv_rgb_std.c in Sources */, + F386F7012884663E001840AA /* SDL_utils.c in Sources */, A75FD00E23E25AC700529352 /* SDL_blit_0.c in Sources */, A75FD00F23E25AC700529352 /* k_tan.c in Sources */, - A75FD01023E25AC700529352 /* SDL_x11vulkan.c in Sources */, A75FD01123E25AC700529352 /* SDL_diskaudio.c in Sources */, A75FD01223E25AC700529352 /* SDL_egl.c in Sources */, A75FD01323E25AC700529352 /* SDL_RLEaccel.c in Sources */, @@ -8607,31 +8220,29 @@ A75FD01923E25AC700529352 /* SDL_fillrect.c in Sources */, A75FD01A23E25AC700529352 /* SDL_nullframebuffer.c in Sources */, A75FD01B23E25AC700529352 /* SDL_dummysensor.c in Sources */, + F3ADAB932576F0B400A6B1D9 /* SDL_sysurl.m in Sources */, A75FD01C23E25AC700529352 /* SDL_string.c in Sources */, A75FD01D23E25AC700529352 /* SDL_render_gl.c in Sources */, + F316ABA82B5A02C3002EF551 /* yuv_rgb_sse.c in Sources */, A75FD01E23E25AC700529352 /* SDL_uikitopengles.m in Sources */, - A75FD01F23E25AC700529352 /* SDL_x11opengles.c in Sources */, A75FD02023E25AC700529352 /* SDL_cocoamodes.m in Sources */, A75FD02123E25AC700529352 /* k_rem_pio2.c in Sources */, - A75FD02223E25AC700529352 /* SDL_sysjoystick.c in Sources */, A75FD02323E25AC700529352 /* SDL_gesture.c in Sources */, A75FD02423E25AC700529352 /* SDL_getenv.c in Sources */, A75FD02523E25AC700529352 /* SDL_hidapi_gamecube.c in Sources */, A75FD02623E25AC700529352 /* SDL_joystick.c in Sources */, A75FD02723E25AC700529352 /* SDL_render_gles2.c in Sources */, A75FD02823E25AC700529352 /* SDL_surface.c in Sources */, - A75FDAAB23E2792500529352 /* hid.m in Sources */, A75FD02923E25AC700529352 /* SDL_hidapi_xboxone.c in Sources */, A75FD02A23E25AC700529352 /* SDL_blit_auto.c in Sources */, - A75FD02B23E25AC700529352 /* SDL_x11keyboard.c in Sources */, A75FD02C23E25AC700529352 /* SDL_keyboard.c in Sources */, A75FD02E23E25AC700529352 /* SDL_rect.c in Sources */, A75FD02F23E25AC700529352 /* SDL_cocoaopengles.m in Sources */, A75FD03023E25AC700529352 /* SDL_qsort.c in Sources */, + 5605720E2473687C00B46B66 /* SDL_syslocale.m in Sources */, A75FD03123E25AC700529352 /* SDL_hidapi_switch.c in Sources */, A75FD03223E25AC700529352 /* SDL_strtokr.c in Sources */, A75FD03323E25AC700529352 /* SDL_clipboardevents.c in Sources */, - A75FD03423E25AC700529352 /* SDL_x11framebuffer.c in Sources */, A75FD03523E25AC700529352 /* k_cos.c in Sources */, A75FD03623E25AC700529352 /* SDL_hidapijoystick.c in Sources */, A75FD03723E25AC700529352 /* SDL_malloc.c in Sources */, @@ -8643,59 +8254,34 @@ A75FD03D23E25AC700529352 /* e_exp.c in Sources */, A75FD03E23E25AC700529352 /* SDL_quit.c in Sources */, A75FD03F23E25AC700529352 /* SDL_cocoawindow.m in Sources */, + A1BB8B6B27F6CF330057CFA8 /* SDL_list.c in Sources */, A75FD04023E25AC700529352 /* SDL_sysmutex.c in Sources */, A75FD04123E25AC700529352 /* SDL_syshaptic.c in Sources */, + F3F07D62269640160074468B /* SDL_hidapi_luna.c in Sources */, A75FD04223E25AC700529352 /* SDL_rwopsbundlesupport.m in Sources */, A75FD04323E25AC700529352 /* SDL_video.c in Sources */, - A75FD04423E25AC700529352 /* SDL_offscreenopengl.c in Sources */, A75FD04523E25AC700529352 /* SDL_uikitmetalview.m in Sources */, A75FD04623E25AC700529352 /* SDL_steamcontroller.c in Sources */, A75FD04723E25AC700529352 /* SDL_shaders_gles2.c in Sources */, A75FD04823E25AC700529352 /* SDL_blit_1.c in Sources */, - A75FDAC823E28BD900529352 /* SDL_sysjoystick.m in Sources */, - A75FD04923E25AC700529352 /* SDL_x11dyn.c in Sources */, A75FD04A23E25AC700529352 /* SDL_mouse.c in Sources */, A75FD04B23E25AC700529352 /* e_rem_pio2.c in Sources */, A75FD04C23E25AC700529352 /* SDL_dataqueue.c in Sources */, + F395C1A42569C68F00942BFF /* SDL_iokitjoystick.c in Sources */, A75FD04D23E25AC700529352 /* SDL_sysjoystick.c in Sources */, A75FD04E23E25AC700529352 /* SDL_cpuinfo.c in Sources */, A75FD04F23E25AC700529352 /* SDL_sensor.c in Sources */, - A75FD05023E25AC700529352 /* SDL_x11window.c in Sources */, A75FD05123E25AC700529352 /* k_sin.c in Sources */, - A75FD05223E25AC700529352 /* edid-parse.c in Sources */, A75FD05323E25AC700529352 /* SDL_systimer.c in Sources */, A75FD05423E25AC700529352 /* SDL_drawpoint.c in Sources */, A75FD05523E25AC700529352 /* e_sqrt.c in Sources */, A75FD05623E25AC700529352 /* SDL_cocoavideo.m in Sources */, + F362B9632B33EB7300D30B94 /* SDL_steam_virtual_gamepad.c in Sources */, A75FD05823E25AC700529352 /* SDL.c in Sources */, - A75FD05923E25AC700529352 /* SDL_x11opengl.c in Sources */, A75FD05A23E25AC700529352 /* SDL_cocoavulkan.m in Sources */, A75FD05B23E25AC700529352 /* SDL_uikitappdelegate.m in Sources */, A75FD05C23E25AC700529352 /* SDL_offscreenwindow.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - A75FDB4523E399AC00529352 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - A75FDB5323E39D1C00529352 /* hid.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - A75FDB6523E3A2C900529352 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - A75FDB6623E3A2C900529352 /* hid.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - A75FDB8323E4C74400529352 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - A75FDB9323E4C8DB00529352 /* hid.c in Sources */, + F316ABBA2B5A02C3002EF551 /* yuv_rgb_lsx.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -8716,24 +8302,22 @@ A769B17A23E259AE00872273 /* SDL_render_metal.m in Sources */, A769B17B23E259AE00872273 /* SDL_clipboard.c in Sources */, A769B17C23E259AE00872273 /* SDL_cocoaevents.m in Sources */, - A769B17D23E259AE00872273 /* SDL_x11messagebox.c in Sources */, A769B17E23E259AE00872273 /* SDL_audiocvt.c in Sources */, A769B17F23E259AE00872273 /* SDL_shape.c in Sources */, A769B18023E259AE00872273 /* SDL_rotate.c in Sources */, A769B18123E259AE00872273 /* SDL_coremotionsensor.m in Sources */, A769B18223E259AE00872273 /* SDL_touch.c in Sources */, - A769B18423E259AE00872273 /* SDL_x11events.c in Sources */, A769B18523E259AE00872273 /* SDL_uikitmessagebox.m in Sources */, A769B18623E259AE00872273 /* SDL_thread.c in Sources */, A769B18723E259AE00872273 /* SDL_hidapi_xbox360w.c in Sources */, A769B18823E259AE00872273 /* SDL_atomic.c in Sources */, A769B18923E259AE00872273 /* SDL_displayevents.c in Sources */, - A769B18A23E259AE00872273 /* SDL_cocoamousetap.m in Sources */, + F316ABA52B5A02C3002EF551 /* yuv_rgb_sse.c in Sources */, A769B18B23E259AE00872273 /* SDL_log.c in Sources */, A769B18C23E259AE00872273 /* SDL_cocoaopengl.m in Sources */, A769B18D23E259AE00872273 /* SDL_offscreenframebuffer.c in Sources */, - A769B18E23E259AE00872273 /* yuv_rgb.c in Sources */, A769B18F23E259AE00872273 /* SDL_render_gles.c in Sources */, + F362B9602B33EB7300D30B94 /* SDL_steam_virtual_gamepad.c in Sources */, A769B19023E259AE00872273 /* SDL_systhread.c in Sources */, A769B19123E259AE00872273 /* SDL_windowevents.c in Sources */, A769B19223E259AE00872273 /* s_scalbn.c in Sources */, @@ -8743,14 +8327,13 @@ A769B19623E259AE00872273 /* SDL_systimer.c in Sources */, A769B19723E259AE00872273 /* SDL_uikitclipboard.m in Sources */, A769B19823E259AE00872273 /* SDL_render_sw.c in Sources */, - A769B19923E259AE00872273 /* SDL_x11video.c in Sources */, A769B19A23E259AE00872273 /* SDL_syssem.c in Sources */, A769B19B23E259AE00872273 /* SDL_hidapi_xbox360.c in Sources */, A769B19C23E259AE00872273 /* SDL_coreaudio.m in Sources */, + F362B9422B33920500D30B94 /* SDL_hidapi_steamdeck.c in Sources */, A769B19D23E259AE00872273 /* SDL_blendline.c in Sources */, A769B19E23E259AE00872273 /* SDL_blit_A.c in Sources */, A769B19F23E259AE00872273 /* SDL_d3dmath.c in Sources */, - A769B1A023E259AE00872273 /* SDL_x11mouse.c in Sources */, A769B1A123E259AE00872273 /* SDL_nullvideo.c in Sources */, A769B1A223E259AE00872273 /* SDL_offscreenevents.c in Sources */, A769B1A323E259AE00872273 /* SDL_uikitview.m in Sources */, @@ -8761,28 +8344,33 @@ A769B1A823E259AE00872273 /* s_copysign.c in Sources */, A769B1A923E259AE00872273 /* SDL_haptic.c in Sources */, A769B1AA23E259AE00872273 /* SDL_uikitvulkan.m in Sources */, - A769B1AB23E259AE00872273 /* SDL_x11modes.c in Sources */, A769B1AC23E259AE00872273 /* SDL_cocoametalview.m in Sources */, A769B1AD23E259AE00872273 /* SDL_audiotypecvt.c in Sources */, A769B1AE23E259AE00872273 /* SDL_uikitevents.m in Sources */, + F323060428939F6400E66D30 /* SDL_hidapi_combined.c in Sources */, A769B1AF23E259AE00872273 /* SDL_uikitmodes.m in Sources */, A769B1B023E259AE00872273 /* SDL_blit_N.c in Sources */, + F3ADAB912576F0B400A6B1D9 /* SDL_sysurl.m in Sources */, A769B1B123E259AE00872273 /* SDL_dropevents.c in Sources */, A769B1B223E259AE00872273 /* e_atan2.c in Sources */, A769B1B323E259AE00872273 /* s_sin.c in Sources */, A769B1B423E259AE00872273 /* SDL_power.c in Sources */, + F386F6FE2884663E001840AA /* SDL_utils.c in Sources */, A769B1B523E259AE00872273 /* SDL_cocoakeyboard.m in Sources */, A769B1B623E259AE00872273 /* SDL_dynapi.c in Sources */, A769B1B723E259AE00872273 /* SDL_shaders_gl.c in Sources */, + F38233912738EBF100F7F527 /* SDL_hidapi.c in Sources */, A769B1B823E259AE00872273 /* e_log.c in Sources */, A769B1B923E259AE00872273 /* SDL_cocoamessagebox.m in Sources */, A769B1BA23E259AE00872273 /* SDL_blendfillrect.c in Sources */, + F3820722284F362F004DD584 /* SDL_guid.c in Sources */, A769B1BB23E259AE00872273 /* SDL_uikitvideo.m in Sources */, A769B1BC23E259AE00872273 /* SDL_cocoashape.m in Sources */, A769B1BD23E259AE00872273 /* SDL_cocoamouse.m in Sources */, A769B1BE23E259AE00872273 /* SDL_error.c in Sources */, A769B1BF23E259AE00872273 /* SDL_blit.c in Sources */, A769B1C023E259AE00872273 /* SDL_rwops.c in Sources */, + 9846B081287A9020000C35C8 /* SDL_hidapi_shield.c in Sources */, A769B1C123E259AE00872273 /* SDL_uikitviewcontroller.m in Sources */, A769B1C223E259AE00872273 /* s_cos.c in Sources */, A769B1C323E259AE00872273 /* SDL_steamcontroller.c in Sources */, @@ -8790,18 +8378,15 @@ A769B1C523E259AE00872273 /* SDL_wave.c in Sources */, A769B1C623E259AE00872273 /* s_tan.c in Sources */, A769B1C723E259AE00872273 /* SDL_hints.c in Sources */, + F3A490A32554D38600E92A8B /* SDL_hidapi_ps5.c in Sources */, A769B1C823E259AE00872273 /* SDL_hidapi_ps4.c in Sources */, A769B1C923E259AE00872273 /* SDL_pixels.c in Sources */, - A769B1CA23E259AE00872273 /* SDL_x11clipboard.c in Sources */, A769B1CB23E259AE00872273 /* SDL_sysloadso.c in Sources */, - A769B1CC23E259AE00872273 /* SDL_x11xinput2.c in Sources */, A769B1CD23E259AE00872273 /* SDL_syspower.c in Sources */, - A769B1CE23E259AE00872273 /* SDL_x11touch.c in Sources */, A769B1CF23E259AE00872273 /* SDL_iconv.c in Sources */, A769B1D023E259AE00872273 /* s_fabs.c in Sources */, - A769B1D123E259AE00872273 /* SDL_x11shape.c in Sources */, - A769B1D223E259AE00872273 /* imKStoUCS.c in Sources */, A769B1D323E259AE00872273 /* SDL_shaders_metal.metal in Sources */, + 5616CA5E252BB35E005D5928 /* SDL_url.c in Sources */, A769B1D423E259AE00872273 /* SDL_uikitwindow.m in Sources */, A769B1D523E259AE00872273 /* SDL_render.c in Sources */, A769B1D623E259AE00872273 /* SDL_stretch.c in Sources */, @@ -8815,15 +8400,16 @@ A769B1DE23E259AE00872273 /* SDL_events.c in Sources */, A769B1DF23E259AE00872273 /* SDL_blit_0.c in Sources */, A769B1E023E259AE00872273 /* k_tan.c in Sources */, - A769B1E123E259AE00872273 /* SDL_x11vulkan.c in Sources */, A769B1E223E259AE00872273 /* SDL_diskaudio.c in Sources */, - A769B1E323E259AE00872273 /* SDL_sysjoystick.m in Sources */, A769B1E423E259AE00872273 /* SDL_egl.c in Sources */, A769B1E523E259AE00872273 /* SDL_RLEaccel.c in Sources */, A769B1E723E259AE00872273 /* SDL_assert.c in Sources */, A769B1E823E259AE00872273 /* SDL_bmp.c in Sources */, + 75E0915F241EA924004729E1 /* SDL_virtualjoystick.c in Sources */, A769B1E923E259AE00872273 /* SDL_uikit_main.c in Sources */, + F3F07D5F269640160074468B /* SDL_hidapi_luna.c in Sources */, A769B1EA23E259AE00872273 /* SDL_stdlib.c in Sources */, + F316ABB72B5A02C3002EF551 /* yuv_rgb_lsx.c in Sources */, A769B1EB23E259AE00872273 /* SDL_dummyaudio.c in Sources */, A769B1EC23E259AE00872273 /* SDL_fillrect.c in Sources */, A769B1ED23E259AE00872273 /* SDL_nullframebuffer.c in Sources */, @@ -8831,29 +8417,33 @@ A769B1EF23E259AE00872273 /* SDL_string.c in Sources */, A769B1F023E259AE00872273 /* SDL_render_gl.c in Sources */, A769B1F123E259AE00872273 /* SDL_uikitopengles.m in Sources */, - A769B1F223E259AE00872273 /* SDL_x11opengles.c in Sources */, A769B1F323E259AE00872273 /* SDL_cocoamodes.m in Sources */, A769B1F423E259AE00872273 /* k_rem_pio2.c in Sources */, - A769B1F523E259AE00872273 /* SDL_sysjoystick.c in Sources */, A769B1F623E259AE00872273 /* SDL_gesture.c in Sources */, A769B1F723E259AE00872273 /* SDL_getenv.c in Sources */, A769B1F823E259AE00872273 /* SDL_hidapi_gamecube.c in Sources */, A769B1F923E259AE00872273 /* SDL_joystick.c in Sources */, A769B1FA23E259AE00872273 /* SDL_render_gles2.c in Sources */, A769B1FB23E259AE00872273 /* SDL_surface.c in Sources */, + F316AB9C2B5A02C3002EF551 /* yuv_rgb_std.c in Sources */, + F395BF6A25633B2400942BFF /* SDL_crc32.c in Sources */, A769B1FC23E259AE00872273 /* SDL_hidapi_xboxone.c in Sources */, A769B1FD23E259AE00872273 /* SDL_blit_auto.c in Sources */, - A769B1FE23E259AE00872273 /* SDL_x11keyboard.c in Sources */, A769B1FF23E259AE00872273 /* SDL_keyboard.c in Sources */, + F3973FB028A59BDD00B84553 /* SDL_crc16.c in Sources */, + F3D60A8828C16A1900788A3A /* SDL_hidapi_wii.c in Sources */, + 560572132473688200B46B66 /* SDL_locale.c in Sources */, A769B20123E259AE00872273 /* SDL_rect.c in Sources */, A769B20223E259AE00872273 /* SDL_cocoaopengles.m in Sources */, A769B20323E259AE00872273 /* SDL_qsort.c in Sources */, - A75FDB5223E39D1700529352 /* hid.m in Sources */, A769B20423E259AE00872273 /* SDL_hidapi_switch.c in Sources */, + F3984CD525BCC92900374F43 /* SDL_hidapi_stadia.c in Sources */, A769B20523E259AE00872273 /* SDL_strtokr.c in Sources */, + 5605720B2473687A00B46B66 /* SDL_syslocale.m in Sources */, + F3820718284F3609004DD584 /* controller_type.c in Sources */, A769B20623E259AE00872273 /* SDL_clipboardevents.c in Sources */, - A769B20723E259AE00872273 /* SDL_x11framebuffer.c in Sources */, A769B20823E259AE00872273 /* k_cos.c in Sources */, + F388C95A28B5F6F700661ECF /* SDL_hidapi_ps3.c in Sources */, A769B20923E259AE00872273 /* SDL_hidapijoystick.c in Sources */, A769B20A23E259AE00872273 /* SDL_malloc.c in Sources */, A769B20B23E259AE00872273 /* SDL_audio.c in Sources */, @@ -8863,34 +8453,35 @@ A769B20E23E259AE00872273 /* SDL_syscond.c in Sources */, A769B20F23E259AE00872273 /* SDL_syshaptic.c in Sources */, A769B21023E259AE00872273 /* e_exp.c in Sources */, + F395C1A12569C68F00942BFF /* SDL_iokitjoystick.c in Sources */, + A1BB8B6827F6CF330057CFA8 /* SDL_list.c in Sources */, A769B21123E259AE00872273 /* SDL_quit.c in Sources */, A769B21223E259AE00872273 /* SDL_cocoawindow.m in Sources */, A769B21323E259AE00872273 /* SDL_sysmutex.c in Sources */, A769B21423E259AE00872273 /* SDL_syshaptic.c in Sources */, A769B21523E259AE00872273 /* SDL_rwopsbundlesupport.m in Sources */, A769B21623E259AE00872273 /* SDL_video.c in Sources */, - A769B21723E259AE00872273 /* SDL_offscreenopengl.c in Sources */, + F38233972738EC1600F7F527 /* hid.m in Sources */, A769B21823E259AE00872273 /* SDL_uikitmetalview.m in Sources */, A769B21923E259AE00872273 /* SDL_shaders_gles2.c in Sources */, A769B21A23E259AE00872273 /* SDL_blit_1.c in Sources */, - A769B21B23E259AE00872273 /* SDL_x11dyn.c in Sources */, A769B21C23E259AE00872273 /* SDL_mouse.c in Sources */, A769B21D23E259AE00872273 /* e_rem_pio2.c in Sources */, A769B21E23E259AE00872273 /* SDL_dataqueue.c in Sources */, A769B21F23E259AE00872273 /* SDL_sysjoystick.c in Sources */, A769B22023E259AE00872273 /* SDL_cpuinfo.c in Sources */, A769B22123E259AE00872273 /* SDL_sensor.c in Sources */, - A769B22223E259AE00872273 /* SDL_x11window.c in Sources */, A769B22323E259AE00872273 /* k_sin.c in Sources */, - A769B22423E259AE00872273 /* edid-parse.c in Sources */, A769B22523E259AE00872273 /* SDL_systimer.c in Sources */, + F31A92D828D4CB39003BFD6A /* SDL_offscreenopengles.c in Sources */, A769B22623E259AE00872273 /* SDL_drawpoint.c in Sources */, + F395C1B62569C6A000942BFF /* SDL_mfijoystick.m in Sources */, A769B22723E259AE00872273 /* e_sqrt.c in Sources */, A769B22823E259AE00872273 /* SDL_cocoavideo.m in Sources */, A769B22923E259AE00872273 /* SDL.c in Sources */, - A769B22A23E259AE00872273 /* SDL_x11opengl.c in Sources */, A769B22B23E259AE00872273 /* SDL_cocoavulkan.m in Sources */, A769B22C23E259AE00872273 /* SDL_uikitappdelegate.m in Sources */, + A1626A432617006A003F1973 /* SDL_triangle.c in Sources */, A769B22D23E259AE00872273 /* SDL_offscreenwindow.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -8902,6 +8493,7 @@ A7D8B9E423E2514400DCD162 /* SDL_drawline.c in Sources */, A7D8AE7D23E2514100DCD162 /* SDL_yuv.c in Sources */, A7D8B63023E2514300DCD162 /* SDL_sysfilesystem.m in Sources */, + F395BF6625633B2400942BFF /* SDL_crc32.c in Sources */, A7D8BAC823E2514500DCD162 /* e_pow.c in Sources */, A7D8B41D23E2514300DCD162 /* SDL_systls.c in Sources */, A7D8AD2A23E2514100DCD162 /* SDL_vulkan_utils.c in Sources */, @@ -8910,27 +8502,26 @@ A7D8B75323E2514300DCD162 /* SDL_sysloadso.c in Sources */, A7D8B98723E2514400DCD162 /* SDL_render_metal.m in Sources */, A7D8AE7723E2514100DCD162 /* SDL_clipboard.c in Sources */, + 75E0915B241EA924004729E1 /* SDL_virtualjoystick.c in Sources */, A7D8AEC523E2514100DCD162 /* SDL_cocoaevents.m in Sources */, - A7D8B1BF23E2514200DCD162 /* SDL_x11messagebox.c in Sources */, A7D8B86723E2514400DCD162 /* SDL_audiocvt.c in Sources */, A7D8B3AB23E2514200DCD162 /* SDL_shape.c in Sources */, A7D8B9F623E2514400DCD162 /* SDL_rotate.c in Sources */, A7D8A97623E2514000DCD162 /* SDL_coremotionsensor.m in Sources */, + F3973FAC28A59BDD00B84553 /* SDL_crc16.c in Sources */, A7D8BB8E23E2514500DCD162 /* SDL_touch.c in Sources */, - A7D8B19B23E2514200DCD162 /* SDL_x11events.c in Sources */, A7D8AC5223E2514100DCD162 /* SDL_uikitmessagebox.m in Sources */, A7D8B3F323E2514300DCD162 /* SDL_thread.c in Sources */, + A1626A3F2617006A003F1973 /* SDL_triangle.c in Sources */, A7D8B55E23E2514300DCD162 /* SDL_hidapi_xbox360w.c in Sources */, A7D8A95823E2514000DCD162 /* SDL_atomic.c in Sources */, A7D8BB2823E2514500DCD162 /* SDL_displayevents.c in Sources */, - A7D8AF1923E2514100DCD162 /* SDL_cocoamousetap.m in Sources */, A7D8AB2623E2514100DCD162 /* SDL_log.c in Sources */, A7D8AE8923E2514100DCD162 /* SDL_cocoaopengl.m in Sources */, A7D8AB7423E2514100DCD162 /* SDL_offscreenframebuffer.c in Sources */, - A7D8B3C023E2514200DCD162 /* yuv_rgb.c in Sources */, A7D8BA3E23E2514400DCD162 /* SDL_render_gles.c in Sources */, - A7D8BBB723E254E400DCD162 /* SDL_sysjoystick.m in Sources */, A7D8B43523E2514300DCD162 /* SDL_systhread.c in Sources */, + F323060028939F6400E66D30 /* SDL_hidapi_combined.c in Sources */, A7D8BB3423E2514500DCD162 /* SDL_windowevents.c in Sources */, A7D8BABC23E2514400DCD162 /* s_scalbn.c in Sources */, A7D8AB2C23E2514100DCD162 /* SDL_timer.c in Sources */, @@ -8939,31 +8530,33 @@ A7D8AB3823E2514100DCD162 /* SDL_systimer.c in Sources */, A7D8ACAC23E2514100DCD162 /* SDL_uikitclipboard.m in Sources */, A7D8BA1423E2514400DCD162 /* SDL_render_sw.c in Sources */, - A7D8B18F23E2514200DCD162 /* SDL_x11video.c in Sources */, A7D8B42323E2514300DCD162 /* SDL_syssem.c in Sources */, A7D8B53A23E2514300DCD162 /* SDL_hidapi_xbox360.c in Sources */, A7D8B8D323E2514400DCD162 /* SDL_coreaudio.m in Sources */, A7D8BA2023E2514400DCD162 /* SDL_blendline.c in Sources */, A7D8ADF323E2514100DCD162 /* SDL_blit_A.c in Sources */, A7D8BA3823E2514400DCD162 /* SDL_d3dmath.c in Sources */, - A7D8B17723E2514200DCD162 /* SDL_x11mouse.c in Sources */, + F38233942738EC1400F7F527 /* hid.m in Sources */, A7D8ABEC23E2514100DCD162 /* SDL_nullvideo.c in Sources */, A7D8AB6823E2514100DCD162 /* SDL_offscreenevents.c in Sources */, A7D8ACA623E2514100DCD162 /* SDL_uikitview.m in Sources */, A7D8ABF223E2514100DCD162 /* SDL_nullevents.c in Sources */, A7D8B81923E2514400DCD162 /* SDL_audiodev.c in Sources */, A7D8AF0D23E2514100DCD162 /* SDL_cocoaclipboard.m in Sources */, + F362B93E2B33920500D30B94 /* SDL_hidapi_steamdeck.c in Sources */, A7D8ABCE23E2514100DCD162 /* SDL_blit_slow.c in Sources */, A7D8BA9823E2514400DCD162 /* s_copysign.c in Sources */, A7D8AAB723E2514100DCD162 /* SDL_haptic.c in Sources */, A7D8AC8E23E2514100DCD162 /* SDL_uikitvulkan.m in Sources */, - A7D8B15323E2514200DCD162 /* SDL_x11modes.c in Sources */, A7D8AF2523E2514100DCD162 /* SDL_cocoametalview.m in Sources */, A7D8B86123E2514400DCD162 /* SDL_audiotypecvt.c in Sources */, + F3984CD125BCC92900374F43 /* SDL_hidapi_stadia.c in Sources */, + F3820714284F3609004DD584 /* controller_type.c in Sources */, A7D8AC5823E2514100DCD162 /* SDL_uikitevents.m in Sources */, A7D8ACB823E2514100DCD162 /* SDL_uikitmodes.m in Sources */, A7D8AD3323E2514100DCD162 /* SDL_blit_N.c in Sources */, A7D8BB7C23E2514500DCD162 /* SDL_dropevents.c in Sources */, + F382071E284F362F004DD584 /* SDL_guid.c in Sources */, A7D8BACE23E2514500DCD162 /* e_atan2.c in Sources */, A7D8BA8C23E2514400DCD162 /* s_sin.c in Sources */, A7D8B5E823E2514300DCD162 /* SDL_power.c in Sources */, @@ -8972,6 +8565,7 @@ A7D8BA8623E2514400DCD162 /* SDL_shaders_gl.c in Sources */, A7D8BAF223E2514500DCD162 /* e_log.c in Sources */, A7D8AED123E2514100DCD162 /* SDL_cocoamessagebox.m in Sources */, + F388C95628B5F6F700661ECF /* SDL_hidapi_ps3.c in Sources */, A7D8BA2C23E2514400DCD162 /* SDL_blendfillrect.c in Sources */, A7D8ACDC23E2514100DCD162 /* SDL_uikitvideo.m in Sources */, A7D8AEE323E2514100DCD162 /* SDL_cocoashape.m in Sources */, @@ -8981,25 +8575,26 @@ A7D8B5BE23E2514300DCD162 /* SDL_rwops.c in Sources */, A7D8ACD023E2514100DCD162 /* SDL_uikitviewcontroller.m in Sources */, A7D8BA9223E2514400DCD162 /* s_cos.c in Sources */, + F3D60A8428C16A1900788A3A /* SDL_hidapi_wii.c in Sources */, A7D8B4D123E2514300DCD162 /* SDL_steamcontroller.c in Sources */, A7D8B9D223E2514400DCD162 /* SDL_yuv_sw.c in Sources */, + F382338E2738EBEC00F7F527 /* SDL_hidapi.c in Sources */, A7D8B76B23E2514300DCD162 /* SDL_wave.c in Sources */, A7D8BAD423E2514500DCD162 /* s_tan.c in Sources */, A7D8AA6623E2514000DCD162 /* SDL_hints.c in Sources */, A7D8B54023E2514300DCD162 /* SDL_hidapi_ps4.c in Sources */, A7D8AD6F23E2514100DCD162 /* SDL_pixels.c in Sources */, - A7D8B1A123E2514200DCD162 /* SDL_x11clipboard.c in Sources */, + 5616CA52252BB35A005D5928 /* SDL_url.c in Sources */, + 9846B07D287A9020000C35C8 /* SDL_hidapi_shield.c in Sources */, A7D8B75F23E2514300DCD162 /* SDL_sysloadso.c in Sources */, - A7D8B16B23E2514200DCD162 /* SDL_x11xinput2.c in Sources */, A7D8B5F423E2514300DCD162 /* SDL_syspower.c in Sources */, - A7D8B1C523E2514200DCD162 /* SDL_x11touch.c in Sources */, A7D8B95123E2514400DCD162 /* SDL_iconv.c in Sources */, + F31A92D328D4CB39003BFD6A /* SDL_offscreenopengles.c in Sources */, A7D8BA9E23E2514400DCD162 /* s_fabs.c in Sources */, - A7D8B1E323E2514200DCD162 /* SDL_x11shape.c in Sources */, - A7D8B19523E2514200DCD162 /* imKStoUCS.c in Sources */, A7D8B99323E2514400DCD162 /* SDL_shaders_metal.metal in Sources */, A7D8AC4C23E2514100DCD162 /* SDL_uikitwindow.m in Sources */, A7D8B97B23E2514400DCD162 /* SDL_render.c in Sources */, + F395C1B22569C6A000942BFF /* SDL_mfijoystick.m in Sources */, A7D8ABD423E2514100DCD162 /* SDL_stretch.c in Sources */, A7D8BAFE23E2514500DCD162 /* s_floor.c in Sources */, A7D8AC3A23E2514100DCD162 /* SDL_blit_copy.c in Sources */, @@ -9012,7 +8607,8 @@ A7D8ADE723E2514100DCD162 /* SDL_blit_0.c in Sources */, A7D8BB0A23E2514500DCD162 /* k_tan.c in Sources */, A75FDBCF23EA380300529352 /* SDL_hidapi_rumble.c in Sources */, - A7D8B15F23E2514200DCD162 /* SDL_x11vulkan.c in Sources */, + F316AB982B5A02C3002EF551 /* yuv_rgb_std.c in Sources */, + F386F6FA2884663E001840AA /* SDL_utils.c in Sources */, A7D8B8A923E2514400DCD162 /* SDL_diskaudio.c in Sources */, A7D8AFC123E2514200DCD162 /* SDL_egl.c in Sources */, A7D8AC3423E2514100DCD162 /* SDL_RLEaccel.c in Sources */, @@ -9025,11 +8621,11 @@ A7D8A96A23E2514000DCD162 /* SDL_dummysensor.c in Sources */, A7D8B95D23E2514400DCD162 /* SDL_string.c in Sources */, A7D8BA8023E2514400DCD162 /* SDL_render_gl.c in Sources */, + F3ADAB8E2576F0B400A6B1D9 /* SDL_sysurl.m in Sources */, A7D8AC8223E2514100DCD162 /* SDL_uikitopengles.m in Sources */, - A7D8B20123E2514200DCD162 /* SDL_x11opengles.c in Sources */, A7D8AE9523E2514100DCD162 /* SDL_cocoamodes.m in Sources */, + F316ABA12B5A02C3002EF551 /* yuv_rgb_sse.c in Sources */, A7D8BAA423E2514400DCD162 /* k_rem_pio2.c in Sources */, - A7D8B57623E2514300DCD162 /* SDL_sysjoystick.c in Sources */, A7D8BB9A23E2514500DCD162 /* SDL_gesture.c in Sources */, A7D8B95723E2514400DCD162 /* SDL_getenv.c in Sources */, A7D8B56423E2514300DCD162 /* SDL_hidapi_gamecube.c in Sources */, @@ -9038,7 +8634,6 @@ A7D8AC2E23E2514100DCD162 /* SDL_surface.c in Sources */, A7D8B54C23E2514300DCD162 /* SDL_hidapi_xboxone.c in Sources */, A7D8AD2423E2514100DCD162 /* SDL_blit_auto.c in Sources */, - A7D8B1A723E2514200DCD162 /* SDL_x11keyboard.c in Sources */, A7D8BB6A23E2514500DCD162 /* SDL_keyboard.c in Sources */, A7D8ACE823E2514100DCD162 /* SDL_rect.c in Sources */, A7D8AE9B23E2514100DCD162 /* SDL_cocoaopengles.m in Sources */, @@ -9046,7 +8641,6 @@ A7D8B55223E2514300DCD162 /* SDL_hidapi_switch.c in Sources */, A7D8B96323E2514400DCD162 /* SDL_strtokr.c in Sources */, A7D8BB7623E2514500DCD162 /* SDL_clipboardevents.c in Sources */, - A7D8B18323E2514200DCD162 /* SDL_x11framebuffer.c in Sources */, A7D8BAB623E2514400DCD162 /* k_cos.c in Sources */, A7D8B54623E2514300DCD162 /* SDL_hidapijoystick.c in Sources */, A7D8B97523E2514400DCD162 /* SDL_malloc.c in Sources */, @@ -9061,31 +8655,34 @@ A7D8B43B23E2514300DCD162 /* SDL_sysmutex.c in Sources */, A7D8AAB123E2514100DCD162 /* SDL_syshaptic.c in Sources */, A7D8B5CA23E2514300DCD162 /* SDL_rwopsbundlesupport.m in Sources */, + A1BB8B6427F6CF330057CFA8 /* SDL_list.c in Sources */, A7D8AC1023E2514100DCD162 /* SDL_video.c in Sources */, - A7D8AB5623E2514100DCD162 /* SDL_offscreenopengl.c in Sources */, + 560572062473687700B46B66 /* SDL_syslocale.m in Sources */, + F3F07D5B269640160074468B /* SDL_hidapi_luna.c in Sources */, A7D8ACC423E2514100DCD162 /* SDL_uikitmetalview.m in Sources */, A7D8BA5C23E2514400DCD162 /* SDL_shaders_gles2.c in Sources */, A7D8B14123E2514200DCD162 /* SDL_blit_1.c in Sources */, - A7D8B17D23E2514200DCD162 /* SDL_x11dyn.c in Sources */, + 5605720F2473688000B46B66 /* SDL_locale.c in Sources */, + F3A4909F2554D38600E92A8B /* SDL_hidapi_ps5.c in Sources */, A7D8BB1623E2514500DCD162 /* SDL_mouse.c in Sources */, A7D8BADA23E2514500DCD162 /* e_rem_pio2.c in Sources */, A7D8BB1023E2514500DCD162 /* SDL_dataqueue.c in Sources */, A7D8B4B323E2514300DCD162 /* SDL_sysjoystick.c in Sources */, + F395C19D2569C68F00942BFF /* SDL_iokitjoystick.c in Sources */, A7D8B3E123E2514300DCD162 /* SDL_cpuinfo.c in Sources */, A7D8A99423E2514000DCD162 /* SDL_sensor.c in Sources */, - A7D8B18923E2514200DCD162 /* SDL_x11window.c in Sources */, A75FDAAD23E2795C00529352 /* SDL_hidapi_steam.c in Sources */, A7D8BAAA23E2514400DCD162 /* k_sin.c in Sources */, - A7D8B1CB23E2514200DCD162 /* edid-parse.c in Sources */, A7D8AB4A23E2514100DCD162 /* SDL_systimer.c in Sources */, A7D8BA2623E2514400DCD162 /* SDL_drawpoint.c in Sources */, A7D8BAF823E2514500DCD162 /* e_sqrt.c in Sources */, A7D8AEAD23E2514100DCD162 /* SDL_cocoavideo.m in Sources */, + F362B95C2B33EB7300D30B94 /* SDL_steam_virtual_gamepad.c in Sources */, A7D8A94C23E2514000DCD162 /* SDL.c in Sources */, - A7D8B15923E2514200DCD162 /* SDL_x11opengl.c in Sources */, A7D8AEA123E2514100DCD162 /* SDL_cocoavulkan.m in Sources */, A7D8AC6423E2514100DCD162 /* SDL_uikitappdelegate.m in Sources */, A7D8AB6223E2514100DCD162 /* SDL_offscreenwindow.c in Sources */, + F316ABB32B5A02C3002EF551 /* yuv_rgb_lsx.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -9096,6 +8693,7 @@ A7D8B9E523E2514400DCD162 /* SDL_drawline.c in Sources */, A7D8AE7E23E2514100DCD162 /* SDL_yuv.c in Sources */, A7D8B63123E2514300DCD162 /* SDL_sysfilesystem.m in Sources */, + F395BF6725633B2400942BFF /* SDL_crc32.c in Sources */, A7D8BAC923E2514500DCD162 /* e_pow.c in Sources */, A7D8B41E23E2514300DCD162 /* SDL_systls.c in Sources */, A7D8AD2B23E2514100DCD162 /* SDL_vulkan_utils.c in Sources */, @@ -9104,26 +8702,26 @@ A7D8B75423E2514300DCD162 /* SDL_sysloadso.c in Sources */, A7D8B98823E2514400DCD162 /* SDL_render_metal.m in Sources */, A7D8AE7823E2514100DCD162 /* SDL_clipboard.c in Sources */, + 75E0915C241EA924004729E1 /* SDL_virtualjoystick.c in Sources */, A7D8AEC623E2514100DCD162 /* SDL_cocoaevents.m in Sources */, - A7D8B1C023E2514200DCD162 /* SDL_x11messagebox.c in Sources */, A7D8B86823E2514400DCD162 /* SDL_audiocvt.c in Sources */, A7D8B3AC23E2514200DCD162 /* SDL_shape.c in Sources */, A7D8B9F723E2514400DCD162 /* SDL_rotate.c in Sources */, A7D8A97723E2514000DCD162 /* SDL_coremotionsensor.m in Sources */, + F3973FAD28A59BDD00B84553 /* SDL_crc16.c in Sources */, A7D8BB8F23E2514500DCD162 /* SDL_touch.c in Sources */, - A7D8B19C23E2514200DCD162 /* SDL_x11events.c in Sources */, A7D8AC5323E2514100DCD162 /* SDL_uikitmessagebox.m in Sources */, A7D8B3F423E2514300DCD162 /* SDL_thread.c in Sources */, + A1626A402617006A003F1973 /* SDL_triangle.c in Sources */, A7D8B55F23E2514300DCD162 /* SDL_hidapi_xbox360w.c in Sources */, A7D8A95923E2514000DCD162 /* SDL_atomic.c in Sources */, A7D8BB2923E2514500DCD162 /* SDL_displayevents.c in Sources */, - A7D8AF1A23E2514100DCD162 /* SDL_cocoamousetap.m in Sources */, A7D8AB2723E2514100DCD162 /* SDL_log.c in Sources */, A7D8AE8A23E2514100DCD162 /* SDL_cocoaopengl.m in Sources */, A7D8AB7523E2514100DCD162 /* SDL_offscreenframebuffer.c in Sources */, - A7D8B3C123E2514200DCD162 /* yuv_rgb.c in Sources */, A7D8BA3F23E2514400DCD162 /* SDL_render_gles.c in Sources */, A7D8B43623E2514300DCD162 /* SDL_systhread.c in Sources */, + F323060128939F6400E66D30 /* SDL_hidapi_combined.c in Sources */, A7D8BB3523E2514500DCD162 /* SDL_windowevents.c in Sources */, A7D8BABD23E2514400DCD162 /* s_scalbn.c in Sources */, A7D8AB2D23E2514100DCD162 /* SDL_timer.c in Sources */, @@ -9132,31 +8730,33 @@ A7D8AB3923E2514100DCD162 /* SDL_systimer.c in Sources */, A7D8ACAD23E2514100DCD162 /* SDL_uikitclipboard.m in Sources */, A7D8BA1523E2514400DCD162 /* SDL_render_sw.c in Sources */, - A7D8B19023E2514200DCD162 /* SDL_x11video.c in Sources */, A7D8B42423E2514300DCD162 /* SDL_syssem.c in Sources */, A7D8B53B23E2514300DCD162 /* SDL_hidapi_xbox360.c in Sources */, A7D8B8D423E2514400DCD162 /* SDL_coreaudio.m in Sources */, A7D8BA2123E2514400DCD162 /* SDL_blendline.c in Sources */, A7D8ADF423E2514100DCD162 /* SDL_blit_A.c in Sources */, A7D8BA3923E2514400DCD162 /* SDL_d3dmath.c in Sources */, - A7D8B17823E2514200DCD162 /* SDL_x11mouse.c in Sources */, + F38233952738EC1500F7F527 /* hid.m in Sources */, A7D8ABED23E2514100DCD162 /* SDL_nullvideo.c in Sources */, A7D8AB6923E2514100DCD162 /* SDL_offscreenevents.c in Sources */, A7D8ACA723E2514100DCD162 /* SDL_uikitview.m in Sources */, A7D8ABF323E2514100DCD162 /* SDL_nullevents.c in Sources */, A7D8B81A23E2514400DCD162 /* SDL_audiodev.c in Sources */, A7D8AF0E23E2514100DCD162 /* SDL_cocoaclipboard.m in Sources */, + F362B93F2B33920500D30B94 /* SDL_hidapi_steamdeck.c in Sources */, A7D8ABCF23E2514100DCD162 /* SDL_blit_slow.c in Sources */, A7D8BA9923E2514400DCD162 /* s_copysign.c in Sources */, A7D8AAB823E2514100DCD162 /* SDL_haptic.c in Sources */, A7D8AC8F23E2514100DCD162 /* SDL_uikitvulkan.m in Sources */, - A7D8B15423E2514200DCD162 /* SDL_x11modes.c in Sources */, A7D8AF2623E2514100DCD162 /* SDL_cocoametalview.m in Sources */, A7D8B86223E2514400DCD162 /* SDL_audiotypecvt.c in Sources */, + F3984CD225BCC92900374F43 /* SDL_hidapi_stadia.c in Sources */, + F3820715284F3609004DD584 /* controller_type.c in Sources */, A7D8AC5923E2514100DCD162 /* SDL_uikitevents.m in Sources */, A7D8ACB923E2514100DCD162 /* SDL_uikitmodes.m in Sources */, A7D8AD3423E2514100DCD162 /* SDL_blit_N.c in Sources */, A7D8BB7D23E2514500DCD162 /* SDL_dropevents.c in Sources */, + F382071F284F362F004DD584 /* SDL_guid.c in Sources */, A7D8BACF23E2514500DCD162 /* e_atan2.c in Sources */, A7D8BA8D23E2514400DCD162 /* s_sin.c in Sources */, A7D8B5E923E2514300DCD162 /* SDL_power.c in Sources */, @@ -9165,6 +8765,7 @@ A7D8BA8723E2514400DCD162 /* SDL_shaders_gl.c in Sources */, A7D8BAF323E2514500DCD162 /* e_log.c in Sources */, A7D8AED223E2514100DCD162 /* SDL_cocoamessagebox.m in Sources */, + F388C95728B5F6F700661ECF /* SDL_hidapi_ps3.c in Sources */, A7D8BA2D23E2514400DCD162 /* SDL_blendfillrect.c in Sources */, A7D8ACDD23E2514100DCD162 /* SDL_uikitvideo.m in Sources */, A7D8AEE423E2514100DCD162 /* SDL_cocoashape.m in Sources */, @@ -9174,25 +8775,26 @@ A7D8B5BF23E2514300DCD162 /* SDL_rwops.c in Sources */, A7D8ACD123E2514100DCD162 /* SDL_uikitviewcontroller.m in Sources */, A7D8BA9323E2514400DCD162 /* s_cos.c in Sources */, + F3D60A8528C16A1900788A3A /* SDL_hidapi_wii.c in Sources */, A7D8B4D223E2514300DCD162 /* SDL_steamcontroller.c in Sources */, A7D8B9D323E2514400DCD162 /* SDL_yuv_sw.c in Sources */, + F382338F2738EBEF00F7F527 /* SDL_hidapi.c in Sources */, A7D8B76C23E2514300DCD162 /* SDL_wave.c in Sources */, A7D8BAD523E2514500DCD162 /* s_tan.c in Sources */, A7D8AA6723E2514000DCD162 /* SDL_hints.c in Sources */, A7D8B54123E2514300DCD162 /* SDL_hidapi_ps4.c in Sources */, A7D8AD7023E2514100DCD162 /* SDL_pixels.c in Sources */, - A7D8B1A223E2514200DCD162 /* SDL_x11clipboard.c in Sources */, + 5616CA55252BB35B005D5928 /* SDL_url.c in Sources */, + 9846B07E287A9020000C35C8 /* SDL_hidapi_shield.c in Sources */, A7D8B76023E2514300DCD162 /* SDL_sysloadso.c in Sources */, - A7D8B16C23E2514200DCD162 /* SDL_x11xinput2.c in Sources */, A7D8B5F523E2514300DCD162 /* SDL_syspower.c in Sources */, - A7D8B1C623E2514200DCD162 /* SDL_x11touch.c in Sources */, A7D8B95223E2514400DCD162 /* SDL_iconv.c in Sources */, + F31A92D428D4CB39003BFD6A /* SDL_offscreenopengles.c in Sources */, A7D8BA9F23E2514400DCD162 /* s_fabs.c in Sources */, - A7D8B1E423E2514200DCD162 /* SDL_x11shape.c in Sources */, - A7D8B19623E2514200DCD162 /* imKStoUCS.c in Sources */, A7D8B99423E2514400DCD162 /* SDL_shaders_metal.metal in Sources */, A7D8AC4D23E2514100DCD162 /* SDL_uikitwindow.m in Sources */, A7D8B97C23E2514400DCD162 /* SDL_render.c in Sources */, + F395C1B32569C6A000942BFF /* SDL_mfijoystick.m in Sources */, A7D8ABD523E2514100DCD162 /* SDL_stretch.c in Sources */, A7D8BAFF23E2514500DCD162 /* s_floor.c in Sources */, A7D8AC3B23E2514100DCD162 /* SDL_blit_copy.c in Sources */, @@ -9204,10 +8806,10 @@ A7D8BB5923E2514500DCD162 /* SDL_events.c in Sources */, A7D8ADE823E2514100DCD162 /* SDL_blit_0.c in Sources */, A7D8BB0B23E2514500DCD162 /* k_tan.c in Sources */, - A7D8B16023E2514200DCD162 /* SDL_x11vulkan.c in Sources */, A75FDBD023EA380300529352 /* SDL_hidapi_rumble.c in Sources */, + F316AB992B5A02C3002EF551 /* yuv_rgb_std.c in Sources */, + F386F6FB2884663E001840AA /* SDL_utils.c in Sources */, A7D8B8AA23E2514400DCD162 /* SDL_diskaudio.c in Sources */, - A7D8B4E423E2514300DCD162 /* SDL_sysjoystick.m in Sources */, A7D8AFC223E2514200DCD162 /* SDL_egl.c in Sources */, A7D8AC3523E2514100DCD162 /* SDL_RLEaccel.c in Sources */, A7D8BBB323E2514500DCD162 /* SDL_assert.c in Sources */, @@ -9219,11 +8821,11 @@ A7D8A96B23E2514000DCD162 /* SDL_dummysensor.c in Sources */, A7D8B95E23E2514400DCD162 /* SDL_string.c in Sources */, A7D8BA8123E2514400DCD162 /* SDL_render_gl.c in Sources */, + F3ADAB8F2576F0B400A6B1D9 /* SDL_sysurl.m in Sources */, A7D8AC8323E2514100DCD162 /* SDL_uikitopengles.m in Sources */, - A7D8B20223E2514200DCD162 /* SDL_x11opengles.c in Sources */, A7D8AE9623E2514100DCD162 /* SDL_cocoamodes.m in Sources */, + F316ABA22B5A02C3002EF551 /* yuv_rgb_sse.c in Sources */, A7D8BAA523E2514400DCD162 /* k_rem_pio2.c in Sources */, - A7D8B57723E2514300DCD162 /* SDL_sysjoystick.c in Sources */, A7D8BB9B23E2514500DCD162 /* SDL_gesture.c in Sources */, A7D8B95823E2514400DCD162 /* SDL_getenv.c in Sources */, A7D8B56523E2514300DCD162 /* SDL_hidapi_gamecube.c in Sources */, @@ -9232,7 +8834,6 @@ A7D8AC2F23E2514100DCD162 /* SDL_surface.c in Sources */, A7D8B54D23E2514300DCD162 /* SDL_hidapi_xboxone.c in Sources */, A7D8AD2523E2514100DCD162 /* SDL_blit_auto.c in Sources */, - A7D8B1A823E2514200DCD162 /* SDL_x11keyboard.c in Sources */, A7D8BB6B23E2514500DCD162 /* SDL_keyboard.c in Sources */, A7D8ACE923E2514100DCD162 /* SDL_rect.c in Sources */, A7D8AE9C23E2514100DCD162 /* SDL_cocoaopengles.m in Sources */, @@ -9240,7 +8841,6 @@ A7D8B55323E2514300DCD162 /* SDL_hidapi_switch.c in Sources */, A7D8B96423E2514400DCD162 /* SDL_strtokr.c in Sources */, A7D8BB7723E2514500DCD162 /* SDL_clipboardevents.c in Sources */, - A7D8B18423E2514200DCD162 /* SDL_x11framebuffer.c in Sources */, A7D8BAB723E2514400DCD162 /* k_cos.c in Sources */, A7D8B54723E2514300DCD162 /* SDL_hidapijoystick.c in Sources */, A7D8B97623E2514400DCD162 /* SDL_malloc.c in Sources */, @@ -9255,31 +8855,34 @@ A7D8B43C23E2514300DCD162 /* SDL_sysmutex.c in Sources */, A7D8AAB223E2514100DCD162 /* SDL_syshaptic.c in Sources */, A7D8B5CB23E2514300DCD162 /* SDL_rwopsbundlesupport.m in Sources */, + A1BB8B6527F6CF330057CFA8 /* SDL_list.c in Sources */, A7D8AC1123E2514100DCD162 /* SDL_video.c in Sources */, - A7D8AB5723E2514100DCD162 /* SDL_offscreenopengl.c in Sources */, + 560572072473687800B46B66 /* SDL_syslocale.m in Sources */, + F3F07D5C269640160074468B /* SDL_hidapi_luna.c in Sources */, A7D8ACC523E2514100DCD162 /* SDL_uikitmetalview.m in Sources */, A7D8BA5D23E2514400DCD162 /* SDL_shaders_gles2.c in Sources */, A7D8B14223E2514200DCD162 /* SDL_blit_1.c in Sources */, - A7D8B17E23E2514200DCD162 /* SDL_x11dyn.c in Sources */, + 560572102473688000B46B66 /* SDL_locale.c in Sources */, + F3A490A02554D38600E92A8B /* SDL_hidapi_ps5.c in Sources */, A7D8BB1723E2514500DCD162 /* SDL_mouse.c in Sources */, A7D8BADB23E2514500DCD162 /* e_rem_pio2.c in Sources */, A7D8BB1123E2514500DCD162 /* SDL_dataqueue.c in Sources */, A7D8B4B423E2514300DCD162 /* SDL_sysjoystick.c in Sources */, + F395C19E2569C68F00942BFF /* SDL_iokitjoystick.c in Sources */, A7D8B3E223E2514300DCD162 /* SDL_cpuinfo.c in Sources */, A7D8A99523E2514000DCD162 /* SDL_sensor.c in Sources */, - A7D8B18A23E2514200DCD162 /* SDL_x11window.c in Sources */, A75FDAAE23E2795C00529352 /* SDL_hidapi_steam.c in Sources */, A7D8BAAB23E2514400DCD162 /* k_sin.c in Sources */, - A7D8B1CC23E2514200DCD162 /* edid-parse.c in Sources */, A7D8AB4B23E2514100DCD162 /* SDL_systimer.c in Sources */, A7D8BA2723E2514400DCD162 /* SDL_drawpoint.c in Sources */, A7D8BAF923E2514500DCD162 /* e_sqrt.c in Sources */, A7D8AEAE23E2514100DCD162 /* SDL_cocoavideo.m in Sources */, + F362B95D2B33EB7300D30B94 /* SDL_steam_virtual_gamepad.c in Sources */, A7D8A94D23E2514000DCD162 /* SDL.c in Sources */, - A7D8B15A23E2514200DCD162 /* SDL_x11opengl.c in Sources */, A7D8AEA223E2514100DCD162 /* SDL_cocoavulkan.m in Sources */, A7D8AC6523E2514100DCD162 /* SDL_uikitappdelegate.m in Sources */, A7D8AB6323E2514100DCD162 /* SDL_offscreenwindow.c in Sources */, + F316ABB42B5A02C3002EF551 /* yuv_rgb_lsx.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -9300,24 +8903,22 @@ A7D8B98A23E2514400DCD162 /* SDL_render_metal.m in Sources */, A7D8AE7A23E2514100DCD162 /* SDL_clipboard.c in Sources */, A7D8AEC823E2514100DCD162 /* SDL_cocoaevents.m in Sources */, - A7D8B1C223E2514200DCD162 /* SDL_x11messagebox.c in Sources */, A7D8B86A23E2514400DCD162 /* SDL_audiocvt.c in Sources */, A7D8B3AE23E2514200DCD162 /* SDL_shape.c in Sources */, A7D8B9F923E2514400DCD162 /* SDL_rotate.c in Sources */, A7D8A97923E2514000DCD162 /* SDL_coremotionsensor.m in Sources */, A7D8BB9123E2514500DCD162 /* SDL_touch.c in Sources */, - A7D8B19E23E2514200DCD162 /* SDL_x11events.c in Sources */, A7D8AC5523E2514100DCD162 /* SDL_uikitmessagebox.m in Sources */, A7D8B3F623E2514300DCD162 /* SDL_thread.c in Sources */, A7D8B56123E2514300DCD162 /* SDL_hidapi_xbox360w.c in Sources */, A7D8A95B23E2514000DCD162 /* SDL_atomic.c in Sources */, A7D8BB2B23E2514500DCD162 /* SDL_displayevents.c in Sources */, - A7D8AF1C23E2514100DCD162 /* SDL_cocoamousetap.m in Sources */, + F316ABA42B5A02C3002EF551 /* yuv_rgb_sse.c in Sources */, A7D8AB2923E2514100DCD162 /* SDL_log.c in Sources */, A7D8AE8C23E2514100DCD162 /* SDL_cocoaopengl.m in Sources */, A7D8AB7723E2514100DCD162 /* SDL_offscreenframebuffer.c in Sources */, - A7D8B3C323E2514200DCD162 /* yuv_rgb.c in Sources */, A7D8BA4123E2514400DCD162 /* SDL_render_gles.c in Sources */, + F362B95F2B33EB7300D30B94 /* SDL_steam_virtual_gamepad.c in Sources */, A7D8B43823E2514300DCD162 /* SDL_systhread.c in Sources */, A7D8BB3723E2514500DCD162 /* SDL_windowevents.c in Sources */, A7D8BABF23E2514400DCD162 /* s_scalbn.c in Sources */, @@ -9327,14 +8928,13 @@ A7D8AB3B23E2514100DCD162 /* SDL_systimer.c in Sources */, A7D8ACAF23E2514100DCD162 /* SDL_uikitclipboard.m in Sources */, A7D8BA1723E2514400DCD162 /* SDL_render_sw.c in Sources */, - A7D8B19223E2514200DCD162 /* SDL_x11video.c in Sources */, A7D8B42623E2514300DCD162 /* SDL_syssem.c in Sources */, A7D8B53D23E2514300DCD162 /* SDL_hidapi_xbox360.c in Sources */, A7D8B8D623E2514400DCD162 /* SDL_coreaudio.m in Sources */, + F362B9412B33920500D30B94 /* SDL_hidapi_steamdeck.c in Sources */, A7D8BA2323E2514400DCD162 /* SDL_blendline.c in Sources */, A7D8ADF623E2514100DCD162 /* SDL_blit_A.c in Sources */, A7D8BA3B23E2514400DCD162 /* SDL_d3dmath.c in Sources */, - A7D8B17A23E2514200DCD162 /* SDL_x11mouse.c in Sources */, A7D8ABEF23E2514100DCD162 /* SDL_nullvideo.c in Sources */, A7D8AB6B23E2514100DCD162 /* SDL_offscreenevents.c in Sources */, A7D8ACA923E2514100DCD162 /* SDL_uikitview.m in Sources */, @@ -9345,28 +8945,33 @@ A7D8BA9B23E2514400DCD162 /* s_copysign.c in Sources */, A7D8AABA23E2514100DCD162 /* SDL_haptic.c in Sources */, A7D8AC9123E2514100DCD162 /* SDL_uikitvulkan.m in Sources */, - A7D8B15623E2514200DCD162 /* SDL_x11modes.c in Sources */, A7D8AF2823E2514100DCD162 /* SDL_cocoametalview.m in Sources */, A7D8B86423E2514400DCD162 /* SDL_audiotypecvt.c in Sources */, A7D8AC5B23E2514100DCD162 /* SDL_uikitevents.m in Sources */, + F323060328939F6400E66D30 /* SDL_hidapi_combined.c in Sources */, A7D8ACBB23E2514100DCD162 /* SDL_uikitmodes.m in Sources */, A7D8AD3623E2514100DCD162 /* SDL_blit_N.c in Sources */, + F3ADAB902576F0B400A6B1D9 /* SDL_sysurl.m in Sources */, A7D8BB7F23E2514500DCD162 /* SDL_dropevents.c in Sources */, A7D8BAD123E2514500DCD162 /* e_atan2.c in Sources */, A7D8BA8F23E2514400DCD162 /* s_sin.c in Sources */, A7D8B5EB23E2514300DCD162 /* SDL_power.c in Sources */, + F386F6FD2884663E001840AA /* SDL_utils.c in Sources */, A7D8AEDA23E2514100DCD162 /* SDL_cocoakeyboard.m in Sources */, A7D8AB1A23E2514100DCD162 /* SDL_dynapi.c in Sources */, A7D8BA8923E2514400DCD162 /* SDL_shaders_gl.c in Sources */, + F38233902738EBF000F7F527 /* SDL_hidapi.c in Sources */, A7D8BAF523E2514500DCD162 /* e_log.c in Sources */, A7D8AED423E2514100DCD162 /* SDL_cocoamessagebox.m in Sources */, A7D8BA2F23E2514400DCD162 /* SDL_blendfillrect.c in Sources */, + F3820721284F362F004DD584 /* SDL_guid.c in Sources */, A7D8ACDF23E2514100DCD162 /* SDL_uikitvideo.m in Sources */, A7D8AEE623E2514100DCD162 /* SDL_cocoashape.m in Sources */, A7D8AEBC23E2514100DCD162 /* SDL_cocoamouse.m in Sources */, A7D8B8E823E2514400DCD162 /* SDL_error.c in Sources */, A7D8AD6C23E2514100DCD162 /* SDL_blit.c in Sources */, A7D8B5C123E2514300DCD162 /* SDL_rwops.c in Sources */, + 9846B080287A9020000C35C8 /* SDL_hidapi_shield.c in Sources */, A7D8ACD323E2514100DCD162 /* SDL_uikitviewcontroller.m in Sources */, A7D8BA9523E2514400DCD162 /* s_cos.c in Sources */, A7D8B4D423E2514300DCD162 /* SDL_steamcontroller.c in Sources */, @@ -9374,18 +8979,15 @@ A7D8B76E23E2514300DCD162 /* SDL_wave.c in Sources */, A7D8BAD723E2514500DCD162 /* s_tan.c in Sources */, A7D8AA6923E2514000DCD162 /* SDL_hints.c in Sources */, + F3A490A22554D38600E92A8B /* SDL_hidapi_ps5.c in Sources */, A7D8B54323E2514300DCD162 /* SDL_hidapi_ps4.c in Sources */, A7D8AD7223E2514100DCD162 /* SDL_pixels.c in Sources */, - A7D8B1A423E2514200DCD162 /* SDL_x11clipboard.c in Sources */, A7D8B76223E2514300DCD162 /* SDL_sysloadso.c in Sources */, - A7D8B16E23E2514200DCD162 /* SDL_x11xinput2.c in Sources */, A7D8B5F723E2514300DCD162 /* SDL_syspower.c in Sources */, - A7D8B1C823E2514200DCD162 /* SDL_x11touch.c in Sources */, A7D8B95423E2514400DCD162 /* SDL_iconv.c in Sources */, A7D8BAA123E2514400DCD162 /* s_fabs.c in Sources */, - A7D8B1E623E2514200DCD162 /* SDL_x11shape.c in Sources */, - A7D8B19823E2514200DCD162 /* imKStoUCS.c in Sources */, A7D8B99623E2514400DCD162 /* SDL_shaders_metal.metal in Sources */, + 5616CA5B252BB35D005D5928 /* SDL_url.c in Sources */, A7D8AC4F23E2514100DCD162 /* SDL_uikitwindow.m in Sources */, A7D8B97E23E2514400DCD162 /* SDL_render.c in Sources */, A7D8ABD723E2514100DCD162 /* SDL_stretch.c in Sources */, @@ -9399,15 +9001,16 @@ A7D8BB5B23E2514500DCD162 /* SDL_events.c in Sources */, A7D8ADEA23E2514100DCD162 /* SDL_blit_0.c in Sources */, A7D8BB0D23E2514500DCD162 /* k_tan.c in Sources */, - A7D8B16223E2514200DCD162 /* SDL_x11vulkan.c in Sources */, A7D8B8AC23E2514400DCD162 /* SDL_diskaudio.c in Sources */, - A7D8B4E623E2514300DCD162 /* SDL_sysjoystick.m in Sources */, A7D8AFC423E2514200DCD162 /* SDL_egl.c in Sources */, A7D8AC3723E2514100DCD162 /* SDL_RLEaccel.c in Sources */, A7D8BBB523E2514500DCD162 /* SDL_assert.c in Sources */, A7D8B3DE23E2514300DCD162 /* SDL_bmp.c in Sources */, + 75E0915E241EA924004729E1 /* SDL_virtualjoystick.c in Sources */, A7D8BC0723E2590800DCD162 /* SDL_uikit_main.c in Sources */, + F3F07D5E269640160074468B /* SDL_hidapi_luna.c in Sources */, A7D8B97223E2514400DCD162 /* SDL_stdlib.c in Sources */, + F316ABB62B5A02C3002EF551 /* yuv_rgb_lsx.c in Sources */, A7D8B79E23E2514400DCD162 /* SDL_dummyaudio.c in Sources */, A7D8B3A823E2514200DCD162 /* SDL_fillrect.c in Sources */, A7D8ABE323E2514100DCD162 /* SDL_nullframebuffer.c in Sources */, @@ -9415,29 +9018,33 @@ A7D8B96023E2514400DCD162 /* SDL_string.c in Sources */, A7D8BA8323E2514400DCD162 /* SDL_render_gl.c in Sources */, A7D8AC8523E2514100DCD162 /* SDL_uikitopengles.m in Sources */, - A7D8B20423E2514200DCD162 /* SDL_x11opengles.c in Sources */, A7D8AE9823E2514100DCD162 /* SDL_cocoamodes.m in Sources */, A7D8BAA723E2514400DCD162 /* k_rem_pio2.c in Sources */, - A7D8B57923E2514300DCD162 /* SDL_sysjoystick.c in Sources */, A7D8BB9D23E2514500DCD162 /* SDL_gesture.c in Sources */, A7D8B95A23E2514400DCD162 /* SDL_getenv.c in Sources */, A7D8B56723E2514300DCD162 /* SDL_hidapi_gamecube.c in Sources */, A7D8B4E023E2514300DCD162 /* SDL_joystick.c in Sources */, A7D8BA4D23E2514400DCD162 /* SDL_render_gles2.c in Sources */, A7D8AC3123E2514100DCD162 /* SDL_surface.c in Sources */, + F316AB9B2B5A02C3002EF551 /* yuv_rgb_std.c in Sources */, + F395BF6925633B2400942BFF /* SDL_crc32.c in Sources */, A7D8B54F23E2514300DCD162 /* SDL_hidapi_xboxone.c in Sources */, A7D8AD2723E2514100DCD162 /* SDL_blit_auto.c in Sources */, - A7D8B1AA23E2514200DCD162 /* SDL_x11keyboard.c in Sources */, A7D8BB6D23E2514500DCD162 /* SDL_keyboard.c in Sources */, + F3973FAF28A59BDD00B84553 /* SDL_crc16.c in Sources */, + F3D60A8728C16A1900788A3A /* SDL_hidapi_wii.c in Sources */, + 560572122473688200B46B66 /* SDL_locale.c in Sources */, A7D8ACEB23E2514100DCD162 /* SDL_rect.c in Sources */, A7D8AE9E23E2514100DCD162 /* SDL_cocoaopengles.m in Sources */, A7D8B96C23E2514400DCD162 /* SDL_qsort.c in Sources */, - A75FDB5123E39D1700529352 /* hid.m in Sources */, A7D8B55523E2514300DCD162 /* SDL_hidapi_switch.c in Sources */, + F3984CD425BCC92900374F43 /* SDL_hidapi_stadia.c in Sources */, A7D8B96623E2514400DCD162 /* SDL_strtokr.c in Sources */, + 560572092473687900B46B66 /* SDL_syslocale.m in Sources */, + F3820717284F3609004DD584 /* controller_type.c in Sources */, A7D8BB7923E2514500DCD162 /* SDL_clipboardevents.c in Sources */, - A7D8B18623E2514200DCD162 /* SDL_x11framebuffer.c in Sources */, A7D8BAB923E2514400DCD162 /* k_cos.c in Sources */, + F388C95928B5F6F700661ECF /* SDL_hidapi_ps3.c in Sources */, A7D8B54923E2514300DCD162 /* SDL_hidapijoystick.c in Sources */, A7D8B97823E2514400DCD162 /* SDL_malloc.c in Sources */, A7D8B8CA23E2514400DCD162 /* SDL_audio.c in Sources */, @@ -9447,34 +9054,35 @@ A7D8B43223E2514300DCD162 /* SDL_syscond.c in Sources */, A7D8AADE23E2514100DCD162 /* SDL_syshaptic.c in Sources */, A7D8BAE923E2514500DCD162 /* e_exp.c in Sources */, + F395C1A02569C68F00942BFF /* SDL_iokitjoystick.c in Sources */, + A1BB8B6727F6CF330057CFA8 /* SDL_list.c in Sources */, A7D8BB8523E2514500DCD162 /* SDL_quit.c in Sources */, A7D8AEAA23E2514100DCD162 /* SDL_cocoawindow.m in Sources */, A7D8B43E23E2514300DCD162 /* SDL_sysmutex.c in Sources */, A7D8AAB423E2514100DCD162 /* SDL_syshaptic.c in Sources */, A7D8B5CD23E2514300DCD162 /* SDL_rwopsbundlesupport.m in Sources */, A7D8AC1323E2514100DCD162 /* SDL_video.c in Sources */, - A7D8AB5923E2514100DCD162 /* SDL_offscreenopengl.c in Sources */, + F38233962738EC1600F7F527 /* hid.m in Sources */, A7D8ACC723E2514100DCD162 /* SDL_uikitmetalview.m in Sources */, A7D8BA5F23E2514400DCD162 /* SDL_shaders_gles2.c in Sources */, A7D8B14423E2514200DCD162 /* SDL_blit_1.c in Sources */, - A7D8B18023E2514200DCD162 /* SDL_x11dyn.c in Sources */, A7D8BB1923E2514500DCD162 /* SDL_mouse.c in Sources */, A7D8BADD23E2514500DCD162 /* e_rem_pio2.c in Sources */, A7D8BB1323E2514500DCD162 /* SDL_dataqueue.c in Sources */, A7D8B4B623E2514300DCD162 /* SDL_sysjoystick.c in Sources */, A7D8B3E423E2514300DCD162 /* SDL_cpuinfo.c in Sources */, A7D8A99723E2514000DCD162 /* SDL_sensor.c in Sources */, - A7D8B18C23E2514200DCD162 /* SDL_x11window.c in Sources */, A7D8BAAD23E2514400DCD162 /* k_sin.c in Sources */, - A7D8B1CE23E2514200DCD162 /* edid-parse.c in Sources */, A7D8AB4D23E2514100DCD162 /* SDL_systimer.c in Sources */, + F31A92D728D4CB39003BFD6A /* SDL_offscreenopengles.c in Sources */, A7D8BA2923E2514400DCD162 /* SDL_drawpoint.c in Sources */, + F395C1B52569C6A000942BFF /* SDL_mfijoystick.m in Sources */, A7D8BAFB23E2514500DCD162 /* e_sqrt.c in Sources */, A7D8AEB023E2514100DCD162 /* SDL_cocoavideo.m in Sources */, A7D8A94F23E2514000DCD162 /* SDL.c in Sources */, - A7D8B15C23E2514200DCD162 /* SDL_x11opengl.c in Sources */, A7D8AEA423E2514100DCD162 /* SDL_cocoavulkan.m in Sources */, A7D8AC6723E2514100DCD162 /* SDL_uikitappdelegate.m in Sources */, + A1626A422617006A003F1973 /* SDL_triangle.c in Sources */, A7D8AB6523E2514100DCD162 /* SDL_offscreenwindow.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -9488,43 +9096,46 @@ A7D8B62F23E2514300DCD162 /* SDL_sysfilesystem.m in Sources */, A7D8BAC723E2514500DCD162 /* e_pow.c in Sources */, A7D8B41C23E2514300DCD162 /* SDL_systls.c in Sources */, + 9846B07C287A9020000C35C8 /* SDL_hidapi_shield.c in Sources */, A7D8BBD923E2574800DCD162 /* SDL_uikitmessagebox.m in Sources */, A7D8AD2923E2514100DCD162 /* SDL_vulkan_utils.c in Sources */, A7D8A95123E2514000DCD162 /* SDL_spinlock.c in Sources */, + F34B9895291DEFF500AAC96E /* SDL_hidapi_steam.c in Sources */, A7D8BAAF23E2514400DCD162 /* s_atan.c in Sources */, A7D8B75223E2514300DCD162 /* SDL_sysloadso.c in Sources */, A7D8BBE123E2574800DCD162 /* SDL_uikitopenglview.m in Sources */, A7D8B98623E2514400DCD162 /* SDL_render_metal.m in Sources */, A7D8AE7623E2514100DCD162 /* SDL_clipboard.c in Sources */, A7D8AEC423E2514100DCD162 /* SDL_cocoaevents.m in Sources */, - A7D8B1BE23E2514200DCD162 /* SDL_x11messagebox.c in Sources */, A7D8B86623E2514400DCD162 /* SDL_audiocvt.c in Sources */, A7D8B3AA23E2514200DCD162 /* SDL_shape.c in Sources */, A7D8B9F523E2514400DCD162 /* SDL_rotate.c in Sources */, A7D8BBE323E2574800DCD162 /* SDL_uikitvideo.m in Sources */, + 5616CA4E252BB2A6005D5928 /* SDL_sysurl.m in Sources */, A7D8A97523E2514000DCD162 /* SDL_coremotionsensor.m in Sources */, + F382071D284F362F004DD584 /* SDL_guid.c in Sources */, A7D8BB8D23E2514500DCD162 /* SDL_touch.c in Sources */, - A7D8B19A23E2514200DCD162 /* SDL_x11events.c in Sources */, + F31A92D228D4CB39003BFD6A /* SDL_offscreenopengles.c in Sources */, + A1626A3E2617006A003F1973 /* SDL_triangle.c in Sources */, A7D8B3F223E2514300DCD162 /* SDL_thread.c in Sources */, A7D8B55D23E2514300DCD162 /* SDL_hidapi_xbox360w.c in Sources */, A7D8A95723E2514000DCD162 /* SDL_atomic.c in Sources */, A75FDBCE23EA380300529352 /* SDL_hidapi_rumble.c in Sources */, A7D8BB2723E2514500DCD162 /* SDL_displayevents.c in Sources */, - A7D8AF1823E2514100DCD162 /* SDL_cocoamousetap.m in Sources */, A7D8AB2523E2514100DCD162 /* SDL_log.c in Sources */, A7D8AE8823E2514100DCD162 /* SDL_cocoaopengl.m in Sources */, A7D8AB7323E2514100DCD162 /* SDL_offscreenframebuffer.c in Sources */, - A7D8B3BF23E2514200DCD162 /* yuv_rgb.c in Sources */, A7D8BA3D23E2514400DCD162 /* SDL_render_gles.c in Sources */, A7D8B43423E2514300DCD162 /* SDL_systhread.c in Sources */, A7D8BB3323E2514500DCD162 /* SDL_windowevents.c in Sources */, A7D8BABB23E2514400DCD162 /* s_scalbn.c in Sources */, + F3973FAB28A59BDD00B84553 /* SDL_crc16.c in Sources */, A7D8AB2B23E2514100DCD162 /* SDL_timer.c in Sources */, + F3D60A8328C16A1900788A3A /* SDL_hidapi_wii.c in Sources */, A7D8B9DD23E2514400DCD162 /* SDL_blendpoint.c in Sources */, A7D8B4EE23E2514300DCD162 /* SDL_gamecontroller.c in Sources */, A7D8AB3723E2514100DCD162 /* SDL_systimer.c in Sources */, A7D8BA1323E2514400DCD162 /* SDL_render_sw.c in Sources */, - A7D8B18E23E2514200DCD162 /* SDL_x11video.c in Sources */, A7D8B42223E2514300DCD162 /* SDL_syssem.c in Sources */, A7D8B53923E2514300DCD162 /* SDL_hidapi_xbox360.c in Sources */, A7D8B8D223E2514400DCD162 /* SDL_coreaudio.m in Sources */, @@ -9533,7 +9144,7 @@ A7D8ADF223E2514100DCD162 /* SDL_blit_A.c in Sources */, A7D8BBDD23E2574800DCD162 /* SDL_uikitmodes.m in Sources */, A7D8BA3723E2514400DCD162 /* SDL_d3dmath.c in Sources */, - A7D8B17623E2514200DCD162 /* SDL_x11mouse.c in Sources */, + 75E0915A241EA924004729E1 /* SDL_virtualjoystick.c in Sources */, A7D8ABEB23E2514100DCD162 /* SDL_nullvideo.c in Sources */, A7D8AB6723E2514100DCD162 /* SDL_offscreenevents.c in Sources */, A7D8ABF123E2514100DCD162 /* SDL_nullevents.c in Sources */, @@ -9542,23 +9153,28 @@ A7D8BBE523E2574800DCD162 /* SDL_uikitview.m in Sources */, A7D8BBE923E2574800DCD162 /* SDL_uikitvulkan.m in Sources */, A7D8ABCD23E2514100DCD162 /* SDL_blit_slow.c in Sources */, + F362B93D2B33920500D30B94 /* SDL_hidapi_steamdeck.c in Sources */, A7D8BA9723E2514400DCD162 /* s_copysign.c in Sources */, + F3984CD025BCC92900374F43 /* SDL_hidapi_stadia.c in Sources */, A7D8AAB623E2514100DCD162 /* SDL_haptic.c in Sources */, - A7D8B15223E2514200DCD162 /* SDL_x11modes.c in Sources */, A7D8AF2423E2514100DCD162 /* SDL_cocoametalview.m in Sources */, A7D8B86023E2514400DCD162 /* SDL_audiotypecvt.c in Sources */, A7D8BBC523E2561500DCD162 /* SDL_steamcontroller.c in Sources */, A7D8AD3223E2514100DCD162 /* SDL_blit_N.c in Sources */, A7D8BB7B23E2514500DCD162 /* SDL_dropevents.c in Sources */, + F362B95B2B33EB7300D30B94 /* SDL_steam_virtual_gamepad.c in Sources */, + F316AB972B5A02C3002EF551 /* yuv_rgb_std.c in Sources */, A7D8BACD23E2514500DCD162 /* e_atan2.c in Sources */, A7D8BA8B23E2514400DCD162 /* s_sin.c in Sources */, A7D8BBEB23E2574800DCD162 /* SDL_uikitwindow.m in Sources */, + F395BF6525633B2400942BFF /* SDL_crc32.c in Sources */, A7D8B5E723E2514300DCD162 /* SDL_power.c in Sources */, A7D8AED623E2514100DCD162 /* SDL_cocoakeyboard.m in Sources */, A7D8AB1623E2514100DCD162 /* SDL_dynapi.c in Sources */, A7D8BA8523E2514400DCD162 /* SDL_shaders_gl.c in Sources */, A7D8BAF123E2514500DCD162 /* e_log.c in Sources */, A7D8AED023E2514100DCD162 /* SDL_cocoamessagebox.m in Sources */, + F376F6552559B4E300CFC0BC /* SDL_hidapi.c in Sources */, A7D8BA2B23E2514400DCD162 /* SDL_blendfillrect.c in Sources */, A7D8AEE223E2514100DCD162 /* SDL_cocoashape.m in Sources */, A7D8BBD323E2574800DCD162 /* SDL_uikitappdelegate.m in Sources */, @@ -9569,20 +9185,17 @@ A7D8BA9123E2514400DCD162 /* s_cos.c in Sources */, A7D8B9D123E2514400DCD162 /* SDL_yuv_sw.c in Sources */, A7D8B76A23E2514300DCD162 /* SDL_wave.c in Sources */, + 5616CA4C252BB2A6005D5928 /* SDL_url.c in Sources */, A7D8BAD323E2514500DCD162 /* s_tan.c in Sources */, A7D8AA6523E2514000DCD162 /* SDL_hints.c in Sources */, A7D8B53F23E2514300DCD162 /* SDL_hidapi_ps4.c in Sources */, A7D8AD6E23E2514100DCD162 /* SDL_pixels.c in Sources */, - A7D8B1A023E2514200DCD162 /* SDL_x11clipboard.c in Sources */, A7D8B75E23E2514300DCD162 /* SDL_sysloadso.c in Sources */, A7D8BBD723E2574800DCD162 /* SDL_uikitevents.m in Sources */, - A7D8B16A23E2514200DCD162 /* SDL_x11xinput2.c in Sources */, A7D8B5F323E2514300DCD162 /* SDL_syspower.c in Sources */, - A7D8B1C423E2514200DCD162 /* SDL_x11touch.c in Sources */, A7D8B95023E2514400DCD162 /* SDL_iconv.c in Sources */, A7D8BA9D23E2514400DCD162 /* s_fabs.c in Sources */, - A7D8B1E223E2514200DCD162 /* SDL_x11shape.c in Sources */, - A7D8B19423E2514200DCD162 /* imKStoUCS.c in Sources */, + F395C1B12569C6A000942BFF /* SDL_mfijoystick.m in Sources */, A7D8B99223E2514400DCD162 /* SDL_shaders_metal.metal in Sources */, A7D8B97A23E2514400DCD162 /* SDL_render.c in Sources */, A7D8ABD323E2514100DCD162 /* SDL_stretch.c in Sources */, @@ -9595,24 +9208,23 @@ A7D8BB5723E2514500DCD162 /* SDL_events.c in Sources */, A7D8ADE623E2514100DCD162 /* SDL_blit_0.c in Sources */, A7D8BB0923E2514500DCD162 /* k_tan.c in Sources */, - A7D8B15E23E2514200DCD162 /* SDL_x11vulkan.c in Sources */, A7D8B8A823E2514400DCD162 /* SDL_diskaudio.c in Sources */, + 566E26CF246274CC00718109 /* SDL_syslocale.m in Sources */, A7D8AFC023E2514200DCD162 /* SDL_egl.c in Sources */, A7D8AC3323E2514100DCD162 /* SDL_RLEaccel.c in Sources */, A7D8BBB123E2514500DCD162 /* SDL_assert.c in Sources */, A7D8B3DA23E2514300DCD162 /* SDL_bmp.c in Sources */, A7D8B96E23E2514400DCD162 /* SDL_stdlib.c in Sources */, A7D8BBDF23E2574800DCD162 /* SDL_uikitopengles.m in Sources */, + F32305FF28939F6400E66D30 /* SDL_hidapi_combined.c in Sources */, A7D8B79A23E2514400DCD162 /* SDL_dummyaudio.c in Sources */, A7D8B3A423E2514200DCD162 /* SDL_fillrect.c in Sources */, A7D8ABDF23E2514100DCD162 /* SDL_nullframebuffer.c in Sources */, A7D8A96923E2514000DCD162 /* SDL_dummysensor.c in Sources */, A7D8B95C23E2514400DCD162 /* SDL_string.c in Sources */, A7D8BA7F23E2514400DCD162 /* SDL_render_gl.c in Sources */, - A7D8B20023E2514200DCD162 /* SDL_x11opengles.c in Sources */, A7D8AE9423E2514100DCD162 /* SDL_cocoamodes.m in Sources */, A7D8BAA323E2514400DCD162 /* k_rem_pio2.c in Sources */, - A7D8B57523E2514300DCD162 /* SDL_sysjoystick.c in Sources */, A7D8BB9923E2514500DCD162 /* SDL_gesture.c in Sources */, A7D8B95623E2514400DCD162 /* SDL_getenv.c in Sources */, A7D8B56323E2514300DCD162 /* SDL_hidapi_gamecube.c in Sources */, @@ -9621,20 +9233,23 @@ A7D8AC2D23E2514100DCD162 /* SDL_surface.c in Sources */, A7D8B54B23E2514300DCD162 /* SDL_hidapi_xboxone.c in Sources */, A7D8AD2323E2514100DCD162 /* SDL_blit_auto.c in Sources */, - A7D8B1A623E2514200DCD162 /* SDL_x11keyboard.c in Sources */, + F3A4909E2554D38600E92A8B /* SDL_hidapi_ps5.c in Sources */, A7D8BB6923E2514500DCD162 /* SDL_keyboard.c in Sources */, A7D8ACE723E2514100DCD162 /* SDL_rect.c in Sources */, A7D8AE9A23E2514100DCD162 /* SDL_cocoaopengles.m in Sources */, + F316ABB22B5A02C3002EF551 /* yuv_rgb_lsx.c in Sources */, A7D8B96823E2514400DCD162 /* SDL_qsort.c in Sources */, A7D8B55123E2514300DCD162 /* SDL_hidapi_switch.c in Sources */, A7D8B96223E2514400DCD162 /* SDL_strtokr.c in Sources */, + F316ABA02B5A02C3002EF551 /* yuv_rgb_sse.c in Sources */, A7D8BB7523E2514500DCD162 /* SDL_clipboardevents.c in Sources */, - A7D8B18223E2514200DCD162 /* SDL_x11framebuffer.c in Sources */, + A1BB8B6327F6CF330057CFA8 /* SDL_list.c in Sources */, A7D8BAB523E2514400DCD162 /* k_cos.c in Sources */, A7D8B54523E2514300DCD162 /* SDL_hidapijoystick.c in Sources */, A7D8B97423E2514400DCD162 /* SDL_malloc.c in Sources */, A7D8B8C623E2514400DCD162 /* SDL_audio.c in Sources */, A7D8B61D23E2514300DCD162 /* SDL_sysfilesystem.c in Sources */, + F3820713284F3609004DD584 /* controller_type.c in Sources */, A7D8AB8B23E2514100DCD162 /* SDL_offscreenvideo.c in Sources */, A7D8B42E23E2514300DCD162 /* SDL_syscond.c in Sources */, A7D8AADA23E2514100DCD162 /* SDL_syshaptic.c in Sources */, @@ -9643,31 +9258,31 @@ A7D8AEA623E2514100DCD162 /* SDL_cocoawindow.m in Sources */, A7D8B43A23E2514300DCD162 /* SDL_sysmutex.c in Sources */, A7D8AAB023E2514100DCD162 /* SDL_syshaptic.c in Sources */, + F3F07D5A269640160074468B /* SDL_hidapi_luna.c in Sources */, A7D8BBD523E2574800DCD162 /* SDL_uikitclipboard.m in Sources */, A7D8B5C923E2514300DCD162 /* SDL_rwopsbundlesupport.m in Sources */, + F386F6F92884663E001840AA /* SDL_utils.c in Sources */, A7D8AC0F23E2514100DCD162 /* SDL_video.c in Sources */, - A7D8AB5523E2514100DCD162 /* SDL_offscreenopengl.c in Sources */, A7D8BA5B23E2514400DCD162 /* SDL_shaders_gles2.c in Sources */, A7D8B14023E2514200DCD162 /* SDL_blit_1.c in Sources */, A7D8BBDB23E2574800DCD162 /* SDL_uikitmetalview.m in Sources */, - A7D8B17C23E2514200DCD162 /* SDL_x11dyn.c in Sources */, A7D8BB1523E2514500DCD162 /* SDL_mouse.c in Sources */, A7D8BAD923E2514500DCD162 /* e_rem_pio2.c in Sources */, A7D8BB0F23E2514500DCD162 /* SDL_dataqueue.c in Sources */, + F395C19C2569C68F00942BFF /* SDL_iokitjoystick.c in Sources */, A7D8B4B223E2514300DCD162 /* SDL_sysjoystick.c in Sources */, A7D8B3E023E2514300DCD162 /* SDL_cpuinfo.c in Sources */, A7D8A99323E2514000DCD162 /* SDL_sensor.c in Sources */, - A7D8B18823E2514200DCD162 /* SDL_x11window.c in Sources */, A7D8BAA923E2514400DCD162 /* k_sin.c in Sources */, - A7D8B1CA23E2514200DCD162 /* edid-parse.c in Sources */, A7D8AB4923E2514100DCD162 /* SDL_systimer.c in Sources */, A7D8BA2523E2514400DCD162 /* SDL_drawpoint.c in Sources */, + F388C95528B5F6F700661ECF /* SDL_hidapi_ps3.c in Sources */, A7D8BAF723E2514500DCD162 /* e_sqrt.c in Sources */, A7D8AEAC23E2514100DCD162 /* SDL_cocoavideo.m in Sources */, A7D8A94B23E2514000DCD162 /* SDL.c in Sources */, - A7D8B15823E2514200DCD162 /* SDL_x11opengl.c in Sources */, A7D8AEA023E2514100DCD162 /* SDL_cocoavulkan.m in Sources */, A7D8AB6123E2514100DCD162 /* SDL_offscreenwindow.c in Sources */, + 566E26D8246274CC00718109 /* SDL_locale.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -9680,43 +9295,48 @@ A7D8AE7F23E2514100DCD162 /* SDL_yuv.c in Sources */, A7D8B63223E2514300DCD162 /* SDL_sysfilesystem.m in Sources */, A7D8BACA23E2514500DCD162 /* e_pow.c in Sources */, + 9846B07F287A9020000C35C8 /* SDL_hidapi_shield.c in Sources */, A7D8B41F23E2514300DCD162 /* SDL_systls.c in Sources */, A7D8AD2C23E2514100DCD162 /* SDL_vulkan_utils.c in Sources */, A7D8A95423E2514000DCD162 /* SDL_spinlock.c in Sources */, + F34B9896291DEFF700AAC96E /* SDL_hidapi_steam.c in Sources */, A7D8BAB223E2514400DCD162 /* s_atan.c in Sources */, + F3A490A12554D38600E92A8B /* SDL_hidapi_ps5.c in Sources */, A7D8B75523E2514300DCD162 /* SDL_sysloadso.c in Sources */, A7D8B98923E2514400DCD162 /* SDL_render_metal.m in Sources */, A7D8AE7923E2514100DCD162 /* SDL_clipboard.c in Sources */, A7D8AEC723E2514100DCD162 /* SDL_cocoaevents.m in Sources */, - A7D8B1C123E2514200DCD162 /* SDL_x11messagebox.c in Sources */, A7D8B86923E2514400DCD162 /* SDL_audiocvt.c in Sources */, A7D8B3AD23E2514200DCD162 /* SDL_shape.c in Sources */, A7D8B9F823E2514400DCD162 /* SDL_rotate.c in Sources */, A7D8A97823E2514000DCD162 /* SDL_coremotionsensor.m in Sources */, A7D8BB9023E2514500DCD162 /* SDL_touch.c in Sources */, - A7D8B19D23E2514200DCD162 /* SDL_x11events.c in Sources */, A7D8B3F523E2514300DCD162 /* SDL_thread.c in Sources */, + F3820720284F362F004DD584 /* SDL_guid.c in Sources */, A7D8B56023E2514300DCD162 /* SDL_hidapi_xbox360w.c in Sources */, + F31A92D628D4CB39003BFD6A /* SDL_offscreenopengles.c in Sources */, + A1626A412617006A003F1973 /* SDL_triangle.c in Sources */, + 5616CA59252BB35C005D5928 /* SDL_sysurl.m in Sources */, A7D8A95A23E2514000DCD162 /* SDL_atomic.c in Sources */, A75FDBD123EA380300529352 /* SDL_hidapi_rumble.c in Sources */, A7D8BB2A23E2514500DCD162 /* SDL_displayevents.c in Sources */, A7D8BBFC23E2574800DCD162 /* SDL_uikitopenglview.m in Sources */, - A7D8AF1B23E2514100DCD162 /* SDL_cocoamousetap.m in Sources */, A7D8AB2823E2514100DCD162 /* SDL_log.c in Sources */, A7D8BC0223E2574800DCD162 /* SDL_uikitviewcontroller.m in Sources */, A7D8AE8B23E2514100DCD162 /* SDL_cocoaopengl.m in Sources */, A7D8AB7623E2514100DCD162 /* SDL_offscreenframebuffer.c in Sources */, - A7D8B3C223E2514200DCD162 /* yuv_rgb.c in Sources */, + 5616CA58252BB35C005D5928 /* SDL_url.c in Sources */, A7D8BA4023E2514400DCD162 /* SDL_render_gles.c in Sources */, A7D8B43723E2514300DCD162 /* SDL_systhread.c in Sources */, + F3973FAE28A59BDD00B84553 /* SDL_crc16.c in Sources */, A7D8BB3623E2514500DCD162 /* SDL_windowevents.c in Sources */, + F3D60A8628C16A1900788A3A /* SDL_hidapi_wii.c in Sources */, A7D8BABE23E2514400DCD162 /* s_scalbn.c in Sources */, A7D8AB2E23E2514100DCD162 /* SDL_timer.c in Sources */, A7D8B9E023E2514400DCD162 /* SDL_blendpoint.c in Sources */, A7D8B4F123E2514300DCD162 /* SDL_gamecontroller.c in Sources */, A7D8AB3A23E2514100DCD162 /* SDL_systimer.c in Sources */, A7D8BA1623E2514400DCD162 /* SDL_render_sw.c in Sources */, - A7D8B19123E2514200DCD162 /* SDL_x11video.c in Sources */, A7D8B42523E2514300DCD162 /* SDL_syssem.c in Sources */, A7D8B53C23E2514300DCD162 /* SDL_hidapi_xbox360.c in Sources */, A7D8B8D523E2514400DCD162 /* SDL_coreaudio.m in Sources */, @@ -9724,7 +9344,6 @@ A7D8BC0623E2574800DCD162 /* SDL_uikitwindow.m in Sources */, A7D8ADF523E2514100DCD162 /* SDL_blit_A.c in Sources */, A7D8BA3A23E2514400DCD162 /* SDL_d3dmath.c in Sources */, - A7D8B17923E2514200DCD162 /* SDL_x11mouse.c in Sources */, A7D8ABEE23E2514100DCD162 /* SDL_nullvideo.c in Sources */, A7D8AB6A23E2514100DCD162 /* SDL_offscreenevents.c in Sources */, A7D8ABF423E2514100DCD162 /* SDL_nullevents.c in Sources */, @@ -9733,7 +9352,8 @@ A7D8ABD023E2514100DCD162 /* SDL_blit_slow.c in Sources */, A7D8BA9A23E2514400DCD162 /* s_copysign.c in Sources */, A7D8AAB923E2514100DCD162 /* SDL_haptic.c in Sources */, - A7D8B15523E2514200DCD162 /* SDL_x11modes.c in Sources */, + F362B9402B33920500D30B94 /* SDL_hidapi_steamdeck.c in Sources */, + F3984CD325BCC92900374F43 /* SDL_hidapi_stadia.c in Sources */, A7D8AF2723E2514100DCD162 /* SDL_cocoametalview.m in Sources */, A7D8B86323E2514400DCD162 /* SDL_audiotypecvt.c in Sources */, A7D8AD3523E2514100DCD162 /* SDL_blit_N.c in Sources */, @@ -9741,15 +9361,19 @@ A7D8BBFA23E2574800DCD162 /* SDL_uikitopengles.m in Sources */, A7D8BAD023E2514500DCD162 /* e_atan2.c in Sources */, A7D8BA8E23E2514400DCD162 /* s_sin.c in Sources */, + F362B95E2B33EB7300D30B94 /* SDL_steam_virtual_gamepad.c in Sources */, + F316AB9A2B5A02C3002EF551 /* yuv_rgb_std.c in Sources */, A7D8B5EA23E2514300DCD162 /* SDL_power.c in Sources */, A7D8AED923E2514100DCD162 /* SDL_cocoakeyboard.m in Sources */, A7D8AB1923E2514100DCD162 /* SDL_dynapi.c in Sources */, + F395BF6825633B2400942BFF /* SDL_crc32.c in Sources */, A7D8BA8823E2514400DCD162 /* SDL_shaders_gl.c in Sources */, A7D8BAF423E2514500DCD162 /* e_log.c in Sources */, A7D8AED323E2514100DCD162 /* SDL_cocoamessagebox.m in Sources */, A7D8BA2E23E2514400DCD162 /* SDL_blendfillrect.c in Sources */, A7D8AEE523E2514100DCD162 /* SDL_cocoashape.m in Sources */, A7D8AEBB23E2514100DCD162 /* SDL_cocoamouse.m in Sources */, + F376F6762559B4E500CFC0BC /* SDL_hidapi.c in Sources */, A7D8B8E723E2514400DCD162 /* SDL_error.c in Sources */, A7D8AD6B23E2514100DCD162 /* SDL_blit.c in Sources */, A7D8B5C023E2514300DCD162 /* SDL_rwops.c in Sources */, @@ -9761,18 +9385,15 @@ A7D8AA6823E2514000DCD162 /* SDL_hints.c in Sources */, A7D8B54223E2514300DCD162 /* SDL_hidapi_ps4.c in Sources */, A7D8AD7123E2514100DCD162 /* SDL_pixels.c in Sources */, - A7D8B1A323E2514200DCD162 /* SDL_x11clipboard.c in Sources */, A7D8B76123E2514300DCD162 /* SDL_sysloadso.c in Sources */, - A7D8B16D23E2514200DCD162 /* SDL_x11xinput2.c in Sources */, A7D8B5F623E2514300DCD162 /* SDL_syspower.c in Sources */, - A7D8B1C723E2514200DCD162 /* SDL_x11touch.c in Sources */, A7D8B95323E2514400DCD162 /* SDL_iconv.c in Sources */, + 560572112473688100B46B66 /* SDL_locale.c in Sources */, A7D8BAA023E2514400DCD162 /* s_fabs.c in Sources */, - A7D8B1E523E2514200DCD162 /* SDL_x11shape.c in Sources */, A7D8BC0423E2574800DCD162 /* SDL_uikitvulkan.m in Sources */, - A7D8B19723E2514200DCD162 /* imKStoUCS.c in Sources */, A7D8B99523E2514400DCD162 /* SDL_shaders_metal.metal in Sources */, A7D8B97D23E2514400DCD162 /* SDL_render.c in Sources */, + F395C1B42569C6A000942BFF /* SDL_mfijoystick.m in Sources */, A7D8ABD623E2514100DCD162 /* SDL_stretch.c in Sources */, A7D8BB0023E2514500DCD162 /* s_floor.c in Sources */, A7D8AC3C23E2514100DCD162 /* SDL_blit_copy.c in Sources */, @@ -9785,7 +9406,6 @@ A7D8ADE923E2514100DCD162 /* SDL_blit_0.c in Sources */, A7D8BB0C23E2514500DCD162 /* k_tan.c in Sources */, A7D8BBF223E2574800DCD162 /* SDL_uikitevents.m in Sources */, - A7D8B16123E2514200DCD162 /* SDL_x11vulkan.c in Sources */, A7D8BBB923E2560500DCD162 /* SDL_steamcontroller.c in Sources */, A7D8B8AB23E2514400DCD162 /* SDL_diskaudio.c in Sources */, A7D8AFC323E2514200DCD162 /* SDL_egl.c in Sources */, @@ -9795,15 +9415,14 @@ A7D8B97123E2514400DCD162 /* SDL_stdlib.c in Sources */, A7D8B79D23E2514400DCD162 /* SDL_dummyaudio.c in Sources */, A7D8B3A723E2514200DCD162 /* SDL_fillrect.c in Sources */, + F323060228939F6400E66D30 /* SDL_hidapi_combined.c in Sources */, + 75E0915D241EA924004729E1 /* SDL_virtualjoystick.c in Sources */, A7D8ABE223E2514100DCD162 /* SDL_nullframebuffer.c in Sources */, A7D8A96C23E2514000DCD162 /* SDL_dummysensor.c in Sources */, A7D8B95F23E2514400DCD162 /* SDL_string.c in Sources */, A7D8BA8223E2514400DCD162 /* SDL_render_gl.c in Sources */, - A7D8B20323E2514200DCD162 /* SDL_x11opengles.c in Sources */, A7D8AE9723E2514100DCD162 /* SDL_cocoamodes.m in Sources */, A7D8BAA623E2514400DCD162 /* k_rem_pio2.c in Sources */, - A75FDB9023E4C80D00529352 /* SDL_hidapi.c in Sources */, - A7D8B57823E2514300DCD162 /* SDL_sysjoystick.c in Sources */, A7D8BB9C23E2514500DCD162 /* SDL_gesture.c in Sources */, A7D8B95923E2514400DCD162 /* SDL_getenv.c in Sources */, A7D8B56623E2514300DCD162 /* SDL_hidapi_gamecube.c in Sources */, @@ -9812,22 +9431,24 @@ A7D8AC3023E2514100DCD162 /* SDL_surface.c in Sources */, A7D8B54E23E2514300DCD162 /* SDL_hidapi_xboxone.c in Sources */, A7D8AD2623E2514100DCD162 /* SDL_blit_auto.c in Sources */, - A7D8B1A923E2514200DCD162 /* SDL_x11keyboard.c in Sources */, A7D8BB6C23E2514500DCD162 /* SDL_keyboard.c in Sources */, A7D8ACEA23E2514100DCD162 /* SDL_rect.c in Sources */, A7D8BC0023E2574800DCD162 /* SDL_uikitview.m in Sources */, A7D8AE9D23E2514100DCD162 /* SDL_cocoaopengles.m in Sources */, A7D8B96B23E2514400DCD162 /* SDL_qsort.c in Sources */, + F316ABB52B5A02C3002EF551 /* yuv_rgb_lsx.c in Sources */, A7D8B55423E2514300DCD162 /* SDL_hidapi_switch.c in Sources */, A7D8B96523E2514400DCD162 /* SDL_strtokr.c in Sources */, A7D8BB7823E2514500DCD162 /* SDL_clipboardevents.c in Sources */, - A7D8B18523E2514200DCD162 /* SDL_x11framebuffer.c in Sources */, + F316ABA32B5A02C3002EF551 /* yuv_rgb_sse.c in Sources */, A7D8BAB823E2514400DCD162 /* k_cos.c in Sources */, + A1BB8B6627F6CF330057CFA8 /* SDL_list.c in Sources */, A7D8B54823E2514300DCD162 /* SDL_hidapijoystick.c in Sources */, A7D8B97723E2514400DCD162 /* SDL_malloc.c in Sources */, A7D8BBF023E2574800DCD162 /* SDL_uikitclipboard.m in Sources */, A7D8B8C923E2514400DCD162 /* SDL_audio.c in Sources */, A7D8B62023E2514300DCD162 /* SDL_sysfilesystem.c in Sources */, + F3820716284F3609004DD584 /* controller_type.c in Sources */, A7D8AB8E23E2514100DCD162 /* SDL_offscreenvideo.c in Sources */, A7D8B43123E2514300DCD162 /* SDL_syscond.c in Sources */, A7D8AADD23E2514100DCD162 /* SDL_syshaptic.c in Sources */, @@ -9836,28 +9457,28 @@ A7D8BB8423E2514500DCD162 /* SDL_quit.c in Sources */, A7D8AEA923E2514100DCD162 /* SDL_cocoawindow.m in Sources */, A7D8B43D23E2514300DCD162 /* SDL_sysmutex.c in Sources */, + F3F07D5D269640160074468B /* SDL_hidapi_luna.c in Sources */, A7D8AAB323E2514100DCD162 /* SDL_syshaptic.c in Sources */, A7D8B5CC23E2514300DCD162 /* SDL_rwopsbundlesupport.m in Sources */, + F386F6FC2884663E001840AA /* SDL_utils.c in Sources */, A7D8AC1223E2514100DCD162 /* SDL_video.c in Sources */, - A7D8AB5823E2514100DCD162 /* SDL_offscreenopengl.c in Sources */, A7D8BA5E23E2514400DCD162 /* SDL_shaders_gles2.c in Sources */, + 5605720A2473687900B46B66 /* SDL_syslocale.m in Sources */, A7D8B14323E2514200DCD162 /* SDL_blit_1.c in Sources */, - A7D8B17F23E2514200DCD162 /* SDL_x11dyn.c in Sources */, A7D8BB1823E2514500DCD162 /* SDL_mouse.c in Sources */, A7D8BADC23E2514500DCD162 /* e_rem_pio2.c in Sources */, A7D8BB1223E2514500DCD162 /* SDL_dataqueue.c in Sources */, A7D8B4B523E2514300DCD162 /* SDL_sysjoystick.c in Sources */, + F395C19F2569C68F00942BFF /* SDL_iokitjoystick.c in Sources */, A7D8B3E323E2514300DCD162 /* SDL_cpuinfo.c in Sources */, A7D8A99623E2514000DCD162 /* SDL_sensor.c in Sources */, - A7D8B18B23E2514200DCD162 /* SDL_x11window.c in Sources */, A7D8BAAC23E2514400DCD162 /* k_sin.c in Sources */, - A7D8B1CD23E2514200DCD162 /* edid-parse.c in Sources */, A7D8AB4C23E2514100DCD162 /* SDL_systimer.c in Sources */, A7D8BA2823E2514400DCD162 /* SDL_drawpoint.c in Sources */, + F388C95828B5F6F700661ECF /* SDL_hidapi_ps3.c in Sources */, A7D8BAFA23E2514500DCD162 /* e_sqrt.c in Sources */, A7D8AEAF23E2514100DCD162 /* SDL_cocoavideo.m in Sources */, A7D8A94E23E2514000DCD162 /* SDL.c in Sources */, - A7D8B15B23E2514200DCD162 /* SDL_x11opengl.c in Sources */, A7D8BBF823E2574800DCD162 /* SDL_uikitmodes.m in Sources */, A7D8AEA323E2514100DCD162 /* SDL_cocoavulkan.m in Sources */, A7D8AB6423E2514100DCD162 /* SDL_offscreenwindow.c in Sources */, @@ -9873,49 +9494,53 @@ A7D8B63423E2514300DCD162 /* SDL_sysfilesystem.m in Sources */, A7D8BACC23E2514500DCD162 /* e_pow.c in Sources */, A7D8B42123E2514300DCD162 /* SDL_systls.c in Sources */, + 9846B082287A9020000C35C8 /* SDL_hidapi_shield.c in Sources */, A7D8AD2E23E2514100DCD162 /* SDL_vulkan_utils.c in Sources */, A7D8A95623E2514000DCD162 /* SDL_spinlock.c in Sources */, A7D8BAB423E2514400DCD162 /* s_atan.c in Sources */, + F34B9897291DEFFA00AAC96E /* SDL_hidapi_steam.c in Sources */, A7D8B75723E2514300DCD162 /* SDL_sysloadso.c in Sources */, + F3A490A42554D38600E92A8B /* SDL_hidapi_ps5.c in Sources */, A7D8B98B23E2514400DCD162 /* SDL_render_metal.m in Sources */, A7D8AE7B23E2514100DCD162 /* SDL_clipboard.c in Sources */, A7D8AEC923E2514100DCD162 /* SDL_cocoaevents.m in Sources */, - A7D8B1C323E2514200DCD162 /* SDL_x11messagebox.c in Sources */, A7D8B86B23E2514400DCD162 /* SDL_audiocvt.c in Sources */, A7D8B3AF23E2514200DCD162 /* SDL_shape.c in Sources */, A7D8B9FA23E2514400DCD162 /* SDL_rotate.c in Sources */, A7D8A97A23E2514000DCD162 /* SDL_coremotionsensor.m in Sources */, A7D8BB9223E2514500DCD162 /* SDL_touch.c in Sources */, - A7D8B19F23E2514200DCD162 /* SDL_x11events.c in Sources */, A7D8AC5623E2514100DCD162 /* SDL_uikitmessagebox.m in Sources */, A7D8B3F723E2514300DCD162 /* SDL_thread.c in Sources */, + F3820723284F362F004DD584 /* SDL_guid.c in Sources */, A7D8B56223E2514300DCD162 /* SDL_hidapi_xbox360w.c in Sources */, + F31A92D928D4CB39003BFD6A /* SDL_offscreenopengles.c in Sources */, + A1626A442617006A003F1973 /* SDL_triangle.c in Sources */, + 5616CA62252BB35E005D5928 /* SDL_sysurl.m in Sources */, A7D8A95C23E2514000DCD162 /* SDL_atomic.c in Sources */, A75FDBD423EA380300529352 /* SDL_hidapi_rumble.c in Sources */, A7D8BB2C23E2514500DCD162 /* SDL_displayevents.c in Sources */, - A7D8AF1D23E2514100DCD162 /* SDL_cocoamousetap.m in Sources */, A7D8AB2A23E2514100DCD162 /* SDL_log.c in Sources */, A7D8AE8D23E2514100DCD162 /* SDL_cocoaopengl.m in Sources */, A7D8AB7823E2514100DCD162 /* SDL_offscreenframebuffer.c in Sources */, - A7D8B3C423E2514200DCD162 /* yuv_rgb.c in Sources */, A7D8BA4223E2514400DCD162 /* SDL_render_gles.c in Sources */, + 5616CA61252BB35E005D5928 /* SDL_url.c in Sources */, A7D8B43923E2514300DCD162 /* SDL_systhread.c in Sources */, A7D8BB3823E2514500DCD162 /* SDL_windowevents.c in Sources */, A7D8BAC023E2514500DCD162 /* s_scalbn.c in Sources */, + F3973FB128A59BDD00B84553 /* SDL_crc16.c in Sources */, A7D8AB3023E2514100DCD162 /* SDL_timer.c in Sources */, + F3D60A8928C16A1900788A3A /* SDL_hidapi_wii.c in Sources */, A7D8B9E223E2514400DCD162 /* SDL_blendpoint.c in Sources */, A7D8B4F323E2514300DCD162 /* SDL_gamecontroller.c in Sources */, A7D8AB3C23E2514100DCD162 /* SDL_systimer.c in Sources */, A7D8ACB023E2514100DCD162 /* SDL_uikitclipboard.m in Sources */, A7D8BA1823E2514400DCD162 /* SDL_render_sw.c in Sources */, - A7D8B19323E2514200DCD162 /* SDL_x11video.c in Sources */, A7D8B42723E2514300DCD162 /* SDL_syssem.c in Sources */, A7D8B53E23E2514300DCD162 /* SDL_hidapi_xbox360.c in Sources */, A7D8B8D723E2514400DCD162 /* SDL_coreaudio.m in Sources */, A7D8BA2423E2514400DCD162 /* SDL_blendline.c in Sources */, A7D8ADF723E2514100DCD162 /* SDL_blit_A.c in Sources */, A7D8BA3C23E2514400DCD162 /* SDL_d3dmath.c in Sources */, - A7D8B17B23E2514200DCD162 /* SDL_x11mouse.c in Sources */, A7D8ABF023E2514100DCD162 /* SDL_nullvideo.c in Sources */, A7D8AB6C23E2514100DCD162 /* SDL_offscreenevents.c in Sources */, A7D8ACAA23E2514100DCD162 /* SDL_uikitview.m in Sources */, @@ -9926,7 +9551,8 @@ A7D8BA9C23E2514400DCD162 /* s_copysign.c in Sources */, A7D8AABB23E2514100DCD162 /* SDL_haptic.c in Sources */, A7D8AC9223E2514100DCD162 /* SDL_uikitvulkan.m in Sources */, - A7D8B15723E2514200DCD162 /* SDL_x11modes.c in Sources */, + F362B9432B33920500D30B94 /* SDL_hidapi_steamdeck.c in Sources */, + F3984CD625BCC92900374F43 /* SDL_hidapi_stadia.c in Sources */, A7D8AF2923E2514100DCD162 /* SDL_cocoametalview.m in Sources */, A7D8B86523E2514400DCD162 /* SDL_audiotypecvt.c in Sources */, A7D8AC5C23E2514100DCD162 /* SDL_uikitevents.m in Sources */, @@ -9934,15 +9560,19 @@ A7D8AD3723E2514100DCD162 /* SDL_blit_N.c in Sources */, A7D8BB8023E2514500DCD162 /* SDL_dropevents.c in Sources */, A7D8BAD223E2514500DCD162 /* e_atan2.c in Sources */, + F362B9612B33EB7300D30B94 /* SDL_steam_virtual_gamepad.c in Sources */, + F316AB9D2B5A02C3002EF551 /* yuv_rgb_std.c in Sources */, A7D8BA9023E2514400DCD162 /* s_sin.c in Sources */, A7D8B5EC23E2514300DCD162 /* SDL_power.c in Sources */, A7D8AEDB23E2514100DCD162 /* SDL_cocoakeyboard.m in Sources */, + F395BF6B25633B2400942BFF /* SDL_crc32.c in Sources */, A7D8AB1B23E2514100DCD162 /* SDL_dynapi.c in Sources */, A7D8BA8A23E2514400DCD162 /* SDL_shaders_gl.c in Sources */, A7D8BAF623E2514500DCD162 /* e_log.c in Sources */, A7D8AED523E2514100DCD162 /* SDL_cocoamessagebox.m in Sources */, A7D8BA3023E2514400DCD162 /* SDL_blendfillrect.c in Sources */, A7D8ACE023E2514100DCD162 /* SDL_uikitvideo.m in Sources */, + F376F68D2559B4E900CFC0BC /* SDL_hidapi.c in Sources */, A7D8AEE723E2514100DCD162 /* SDL_cocoashape.m in Sources */, A7D8AEBD23E2514100DCD162 /* SDL_cocoamouse.m in Sources */, A7D8B8E923E2514400DCD162 /* SDL_error.c in Sources */, @@ -9956,16 +9586,13 @@ A7D8AA6A23E2514000DCD162 /* SDL_hints.c in Sources */, A7D8B54423E2514300DCD162 /* SDL_hidapi_ps4.c in Sources */, A7D8AD7323E2514100DCD162 /* SDL_pixels.c in Sources */, - A7D8B1A523E2514200DCD162 /* SDL_x11clipboard.c in Sources */, A7D8B76323E2514300DCD162 /* SDL_sysloadso.c in Sources */, - A7D8B16F23E2514200DCD162 /* SDL_x11xinput2.c in Sources */, A7D8B5F823E2514300DCD162 /* SDL_syspower.c in Sources */, - A7D8B1C923E2514200DCD162 /* SDL_x11touch.c in Sources */, + 560572142473688300B46B66 /* SDL_locale.c in Sources */, A7D8B95523E2514400DCD162 /* SDL_iconv.c in Sources */, A7D8BAA223E2514400DCD162 /* s_fabs.c in Sources */, - A7D8B1E723E2514200DCD162 /* SDL_x11shape.c in Sources */, - A7D8B19923E2514200DCD162 /* imKStoUCS.c in Sources */, A7D8B99723E2514400DCD162 /* SDL_shaders_metal.metal in Sources */, + F395C1B72569C6A000942BFF /* SDL_mfijoystick.m in Sources */, A7D8AC5023E2514100DCD162 /* SDL_uikitwindow.m in Sources */, A7D8B97F23E2514400DCD162 /* SDL_render.c in Sources */, A7D8ABD823E2514100DCD162 /* SDL_stretch.c in Sources */, @@ -9979,7 +9606,6 @@ A7D8BB5C23E2514500DCD162 /* SDL_events.c in Sources */, A7D8ADEB23E2514100DCD162 /* SDL_blit_0.c in Sources */, A7D8BB0E23E2514500DCD162 /* k_tan.c in Sources */, - A7D8B16323E2514200DCD162 /* SDL_x11vulkan.c in Sources */, A7D8B8AD23E2514400DCD162 /* SDL_diskaudio.c in Sources */, A7D8AFC523E2514200DCD162 /* SDL_egl.c in Sources */, A7D8AC3823E2514100DCD162 /* SDL_RLEaccel.c in Sources */, @@ -9988,16 +9614,15 @@ A7D8B97323E2514400DCD162 /* SDL_stdlib.c in Sources */, A7D8B79F23E2514400DCD162 /* SDL_dummyaudio.c in Sources */, A7D8B3A923E2514200DCD162 /* SDL_fillrect.c in Sources */, + F323060528939F6400E66D30 /* SDL_hidapi_combined.c in Sources */, + 75E09160241EA924004729E1 /* SDL_virtualjoystick.c in Sources */, A7D8ABE423E2514100DCD162 /* SDL_nullframebuffer.c in Sources */, A7D8A96E23E2514000DCD162 /* SDL_dummysensor.c in Sources */, A7D8B96123E2514400DCD162 /* SDL_string.c in Sources */, A7D8BA8423E2514400DCD162 /* SDL_render_gl.c in Sources */, A7D8AC8623E2514100DCD162 /* SDL_uikitopengles.m in Sources */, - A7D8B20523E2514200DCD162 /* SDL_x11opengles.c in Sources */, A7D8AE9923E2514100DCD162 /* SDL_cocoamodes.m in Sources */, - A75FDB8F23E4C80B00529352 /* SDL_hidapi.c in Sources */, A7D8BAA823E2514400DCD162 /* k_rem_pio2.c in Sources */, - A7D8B57A23E2514300DCD162 /* SDL_sysjoystick.c in Sources */, A7D8BB9E23E2514500DCD162 /* SDL_gesture.c in Sources */, A7D8B95B23E2514400DCD162 /* SDL_getenv.c in Sources */, A7D8B56823E2514300DCD162 /* SDL_hidapi_gamecube.c in Sources */, @@ -10006,21 +9631,23 @@ A7D8AC3223E2514100DCD162 /* SDL_surface.c in Sources */, A7D8B55023E2514300DCD162 /* SDL_hidapi_xboxone.c in Sources */, A7D8AD2823E2514100DCD162 /* SDL_blit_auto.c in Sources */, - A7D8B1AB23E2514200DCD162 /* SDL_x11keyboard.c in Sources */, A7D8BB6E23E2514500DCD162 /* SDL_keyboard.c in Sources */, A7D8ACEC23E2514100DCD162 /* SDL_rect.c in Sources */, A7D8AE9F23E2514100DCD162 /* SDL_cocoaopengles.m in Sources */, A7D8B96D23E2514400DCD162 /* SDL_qsort.c in Sources */, + F316ABB82B5A02C3002EF551 /* yuv_rgb_lsx.c in Sources */, A7D8B55623E2514300DCD162 /* SDL_hidapi_switch.c in Sources */, A7D8B96723E2514400DCD162 /* SDL_strtokr.c in Sources */, A7D8BB7A23E2514500DCD162 /* SDL_clipboardevents.c in Sources */, - A7D8B18723E2514200DCD162 /* SDL_x11framebuffer.c in Sources */, + F316ABA62B5A02C3002EF551 /* yuv_rgb_sse.c in Sources */, A7D8BABA23E2514400DCD162 /* k_cos.c in Sources */, + A1BB8B6927F6CF330057CFA8 /* SDL_list.c in Sources */, A7D8B54A23E2514300DCD162 /* SDL_hidapijoystick.c in Sources */, A7D8B97923E2514400DCD162 /* SDL_malloc.c in Sources */, A7D8B8CB23E2514400DCD162 /* SDL_audio.c in Sources */, A7D8B62223E2514300DCD162 /* SDL_sysfilesystem.c in Sources */, A7D8AB9023E2514100DCD162 /* SDL_offscreenvideo.c in Sources */, + F3820719284F3609004DD584 /* controller_type.c in Sources */, A7D8B43323E2514300DCD162 /* SDL_syscond.c in Sources */, A7D8AADF23E2514100DCD162 /* SDL_syshaptic.c in Sources */, A7D8BAEA23E2514500DCD162 /* e_exp.c in Sources */, @@ -10029,34 +9656,42 @@ A7D8B43F23E2514300DCD162 /* SDL_sysmutex.c in Sources */, A7D8AAB523E2514100DCD162 /* SDL_syshaptic.c in Sources */, A7D8B5CE23E2514300DCD162 /* SDL_rwopsbundlesupport.m in Sources */, + F3F07D60269640160074468B /* SDL_hidapi_luna.c in Sources */, A7D8AC1423E2514100DCD162 /* SDL_video.c in Sources */, - A7D8AB5A23E2514100DCD162 /* SDL_offscreenopengl.c in Sources */, + F386F6FF2884663E001840AA /* SDL_utils.c in Sources */, A7D8ACC823E2514100DCD162 /* SDL_uikitmetalview.m in Sources */, A7D8BBBA23E2560600DCD162 /* SDL_steamcontroller.c in Sources */, A7D8BA6023E2514400DCD162 /* SDL_shaders_gles2.c in Sources */, + 5605720C2473687B00B46B66 /* SDL_syslocale.m in Sources */, A7D8B14523E2514200DCD162 /* SDL_blit_1.c in Sources */, - A7D8B18123E2514200DCD162 /* SDL_x11dyn.c in Sources */, A7D8BB1A23E2514500DCD162 /* SDL_mouse.c in Sources */, A7D8BADE23E2514500DCD162 /* e_rem_pio2.c in Sources */, A7D8BB1423E2514500DCD162 /* SDL_dataqueue.c in Sources */, A7D8B4B723E2514300DCD162 /* SDL_sysjoystick.c in Sources */, + F395C1A22569C68F00942BFF /* SDL_iokitjoystick.c in Sources */, A7D8B3E523E2514300DCD162 /* SDL_cpuinfo.c in Sources */, A7D8A99823E2514000DCD162 /* SDL_sensor.c in Sources */, - A7D8B18D23E2514200DCD162 /* SDL_x11window.c in Sources */, A7D8BAAE23E2514400DCD162 /* k_sin.c in Sources */, - A7D8B1CF23E2514200DCD162 /* edid-parse.c in Sources */, A7D8AB4E23E2514100DCD162 /* SDL_systimer.c in Sources */, A7D8BA2A23E2514400DCD162 /* SDL_drawpoint.c in Sources */, + F388C95B28B5F6F700661ECF /* SDL_hidapi_ps3.c in Sources */, A7D8BAFC23E2514500DCD162 /* e_sqrt.c in Sources */, A7D8AEB123E2514100DCD162 /* SDL_cocoavideo.m in Sources */, A7D8A95023E2514000DCD162 /* SDL.c in Sources */, - A7D8B15D23E2514200DCD162 /* SDL_x11opengl.c in Sources */, A7D8AEA523E2514100DCD162 /* SDL_cocoavulkan.m in Sources */, A7D8AC6823E2514100DCD162 /* SDL_uikitappdelegate.m in Sources */, A7D8AB6623E2514100DCD162 /* SDL_offscreenwindow.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; + E2D187CB28A5673500D2B4F1 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F31A92D528D4CB39003BFD6A /* SDL_offscreenopengles.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ @@ -10065,11 +9700,6 @@ target = BECDF5FE0761BA81005FE872 /* Framework */; targetProxy = BECDF6C50761BA81005FE872 /* PBXContainerItemProxy */; }; - F3190017240CA3BA00ED104F /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = A75FDB8023E4C74400529352 /* hidapi */; - targetProxy = F3190016240CA3BA00ED104F /* PBXContainerItemProxy */; - }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ @@ -10078,6 +9708,7 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; 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; @@ -10097,8 +9728,8 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEPLOYMENT_POSTPROCESSING = YES; - DYLIB_COMPATIBILITY_VERSION = 1.0.0; - DYLIB_CURRENT_VERSION = 12.0.0; + DYLIB_COMPATIBILITY_VERSION = 3001.0.0; + DYLIB_CURRENT_VERSION = 3001.5.0; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_ALTIVEC_EXTENSIONS = YES; @@ -10121,9 +9752,13 @@ ../../src/hidapi/hidapi, ); INFOPLIST_FILE = "Info-Framework.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.6; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = 10.11; PRODUCT_BUNDLE_IDENTIFIER = org.libsdl.SDL2; PRODUCT_NAME = SDL2; STRIP_STYLE = "non-global"; @@ -10135,8 +9770,8 @@ isa = XCBuildConfiguration; buildSettings = { CLANG_LINK_OBJC_RUNTIME = NO; + MARKETING_VERSION = 2.30.5; OTHER_LDFLAGS = "-liconv"; - SKIP_INSTALL = YES; }; name = Release; }; @@ -10159,6 +9794,7 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; 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; @@ -10177,8 +9813,8 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; DEBUG_INFORMATION_FORMAT = dwarf; - DYLIB_COMPATIBILITY_VERSION = 1.0.0; - DYLIB_CURRENT_VERSION = 12.0.0; + DYLIB_COMPATIBILITY_VERSION = 3001.0.0; + DYLIB_CURRENT_VERSION = 3001.5.0; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; @@ -10201,10 +9837,14 @@ ../../src/hidapi/hidapi, ); INFOPLIST_FILE = "Info-Framework.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.6; - ONLY_ACTIVE_ARCH = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = 10.11; + ONLY_ACTIVE_ARCH = NO; PRODUCT_BUNDLE_IDENTIFIER = org.libsdl.SDL2; PRODUCT_NAME = SDL2; STRIP_INSTALLED_PRODUCT = NO; @@ -10216,8 +9856,8 @@ isa = XCBuildConfiguration; buildSettings = { CLANG_LINK_OBJC_RUNTIME = NO; + MARKETING_VERSION = 2.30.5; OTHER_LDFLAGS = "-liconv"; - SKIP_INSTALL = YES; }; name = Debug; }; @@ -10240,10 +9880,14 @@ buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; EXECUTABLE_PREFIX = lib; - GCC_PREPROCESSOR_DEFINITIONS = "IOS_DYLIB=1"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)/System/iOSSupport/System/Library/Frameworks", + ); GCC_SYMBOLS_PRIVATE_EXTERN = YES; INSTALL_PATH = "@rpath"; SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2,6"; }; name = Debug; }; @@ -10252,10 +9896,14 @@ buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; EXECUTABLE_PREFIX = lib; - GCC_PREPROCESSOR_DEFINITIONS = "IOS_DYLIB=1"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)/System/iOSSupport/System/Library/Frameworks", + ); GCC_SYMBOLS_PRIVATE_EXTERN = YES; INSTALL_PATH = "@rpath"; SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2,6"; }; name = Release; }; @@ -10264,7 +9912,6 @@ buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; EXECUTABLE_PREFIX = lib; - GCC_PREPROCESSOR_DEFINITIONS = "IOS_DYLIB=1"; GCC_SYMBOLS_PRIVATE_EXTERN = YES; INSTALL_PATH = "@rpath"; SDKROOT = appletvos; @@ -10276,109 +9923,12 @@ buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; EXECUTABLE_PREFIX = lib; - GCC_PREPROCESSOR_DEFINITIONS = "IOS_DYLIB=1"; GCC_SYMBOLS_PRIVATE_EXTERN = YES; INSTALL_PATH = "@rpath"; SDKROOT = appletvos; }; name = Release; }; - A75FDB4E23E399AC00529352 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CURRENT_PROJECT_VERSION = 1.0; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - GCC_PREPROCESSOR_DEFINITIONS = "HID_API_EXPORT=\"__attribute__ ((visibility(\\\"default\\\")))\""; - INFOPLIST_FILE = hidapi/Info.plist; - PRODUCT_BUNDLE_IDENTIFIER = org.libsdl.hidapi; - PRODUCT_NAME = hidapi; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - A75FDB4F23E399AC00529352 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CURRENT_PROJECT_VERSION = 1.0; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - GCC_PREPROCESSOR_DEFINITIONS = "HID_API_EXPORT=\"__attribute__ ((visibility(\\\"default\\\")))\""; - INFOPLIST_FILE = hidapi/Info.plist; - PRODUCT_BUNDLE_IDENTIFIER = org.libsdl.hidapi; - PRODUCT_NAME = hidapi; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Release; - }; - A75FDB6C23E3A2C900529352 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CURRENT_PROJECT_VERSION = 1.0; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - GCC_PREPROCESSOR_DEFINITIONS = "HID_API_EXPORT=\"__attribute__ ((visibility(\\\"default\\\")))\""; - INFOPLIST_FILE = hidapi/Info.plist; - PRODUCT_BUNDLE_IDENTIFIER = org.libsdl.hidapi; - PRODUCT_NAME = hidapi; - SDKROOT = appletvos; - }; - name = Debug; - }; - A75FDB6D23E3A2C900529352 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CURRENT_PROJECT_VERSION = 1.0; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - GCC_PREPROCESSOR_DEFINITIONS = "HID_API_EXPORT=\"__attribute__ ((visibility(\\\"default\\\")))\""; - INFOPLIST_FILE = hidapi/Info.plist; - PRODUCT_BUNDLE_IDENTIFIER = org.libsdl.hidapi; - PRODUCT_NAME = hidapi; - SDKROOT = appletvos; - }; - name = Release; - }; - A75FDB8A23E4C74400529352 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_OBJC_ARC = YES; - CURRENT_PROJECT_VERSION = 1.0; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - GCC_PREPROCESSOR_DEFINITIONS = "HID_API_EXPORT=\"__attribute__ ((visibility(\\\"default\\\")))\""; - INFOPLIST_FILE = hidapi/Info.plist; - PRODUCT_BUNDLE_IDENTIFIER = org.libsdl.hidapi; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - }; - name = Debug; - }; - A75FDB8B23E4C74400529352 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_OBJC_ARC = YES; - CURRENT_PROJECT_VERSION = 1.0; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - GCC_PREPROCESSOR_DEFINITIONS = "HID_API_EXPORT=\"__attribute__ ((visibility(\\\"default\\\")))\""; - INFOPLIST_FILE = hidapi/Info.plist; - PRODUCT_BUNDLE_IDENTIFIER = org.libsdl.hidapi; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - }; - name = Release; - }; A769B23B23E259AE00872273 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -10406,10 +9956,13 @@ buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; CLANG_LINK_OBJC_RUNTIME = NO; - GCC_PREPROCESSOR_DEFINITIONS = "IOS_DYLIB=1"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)/System/iOSSupport/System/Library/Frameworks", + ); OTHER_LDFLAGS = "-liconv"; SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; + TARGETED_DEVICE_FAMILY = "1,2,6"; }; name = Debug; }; @@ -10418,10 +9971,13 @@ buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; CLANG_LINK_OBJC_RUNTIME = NO; - GCC_PREPROCESSOR_DEFINITIONS = "IOS_DYLIB=1"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)/System/iOSSupport/System/Library/Frameworks", + ); OTHER_LDFLAGS = "-liconv"; SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; + TARGETED_DEVICE_FAMILY = "1,2,6"; }; name = Release; }; @@ -10430,7 +9986,6 @@ buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; CLANG_LINK_OBJC_RUNTIME = NO; - GCC_PREPROCESSOR_DEFINITIONS = "IOS_DYLIB=1"; OTHER_LDFLAGS = "-liconv"; SDKROOT = appletvos; }; @@ -10441,7 +9996,6 @@ buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; CLANG_LINK_OBJC_RUNTIME = NO; - GCC_PREPROCESSOR_DEFINITIONS = "IOS_DYLIB=1"; OTHER_LDFLAGS = "-liconv"; SDKROOT = appletvos; }; @@ -10452,6 +10006,7 @@ buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; CLANG_LINK_OBJC_RUNTIME = NO; + GCC_PREPROCESSOR_DEFINITIONS = GLES_SILENCE_DEPRECATION; GCC_SYMBOLS_PRIVATE_EXTERN = YES; SKIP_INSTALL = YES; SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; @@ -10463,6 +10018,7 @@ buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; CLANG_LINK_OBJC_RUNTIME = NO; + GCC_PREPROCESSOR_DEFINITIONS = GLES_SILENCE_DEPRECATION; GCC_SYMBOLS_PRIVATE_EXTERN = YES; SKIP_INSTALL = YES; SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; @@ -10487,6 +10043,107 @@ }; name = Release; }; + E2D187D428A5673500D2B4F1 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = YES; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 3001.0.0; + DYLIB_CURRENT_VERSION = 3001.5.0; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + INFOPLIST_FILE = SDL2/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + OTHER_LDFLAGS = "-liconv"; + PRODUCT_BUNDLE_IDENTIFIER = ""; + PRODUCT_NAME = SDL2; + SDKROOT = iphoneos; + SKIP_INSTALL = NO; + SUPPORTS_MACCATALYST = NO; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + E2D187D528A5673500D2B4F1 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = YES; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = ""; + DYLIB_COMPATIBILITY_VERSION = 3001.0.0; + DYLIB_CURRENT_VERSION = 3001.5.0; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_NS_ASSERTIONS = NO; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + INFOPLIST_FILE = SDL2/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + OTHER_LDFLAGS = "-liconv"; + PRODUCT_BUNDLE_IDENTIFIER = ""; + PRODUCT_NAME = SDL2; + SDKROOT = iphoneos; + SKIP_INSTALL = NO; + SUPPORTS_MACCATALYST = NO; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = NO; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -10544,33 +10201,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; - A75FDB5023E399AC00529352 /* Build configuration list for PBXNativeTarget "hidapi-iOS" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - A75FDB4E23E399AC00529352 /* Debug */, - A75FDB4F23E399AC00529352 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Debug; - }; - A75FDB6B23E3A2C900529352 /* Build configuration list for PBXNativeTarget "hidapi-tvOS" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - A75FDB6C23E3A2C900529352 /* Debug */, - A75FDB6D23E3A2C900529352 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Debug; - }; - A75FDB8923E4C74400529352 /* Build configuration list for PBXNativeTarget "hidapi" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - A75FDB8A23E4C74400529352 /* Debug */, - A75FDB8B23E4C74400529352 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Debug; - }; A769B23A23E259AE00872273 /* Build configuration list for PBXNativeTarget "Static Library-tvOS" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -10616,6 +10246,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; + E2D187D628A5673500D2B4F1 /* Build configuration list for PBXNativeTarget "xcFramework-iOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E2D187D428A5673500D2B4F1 /* Debug */, + E2D187D528A5673500D2B4F1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; /* End XCConfigurationList section */ }; rootObject = 0867D690FE84028FC02AAC07 /* Project object */; diff --git a/SDL2-2.0.12/Xcode/SDL/SDL.xcodeproj/xcshareddata/xcschemes/Framework-iOS.xcscheme b/SDL2-2.30.5/Xcode/SDL/SDL.xcodeproj/xcshareddata/xcschemes/Framework-iOS.xcscheme similarity index 100% rename from SDL2-2.0.12/Xcode/SDL/SDL.xcodeproj/xcshareddata/xcschemes/Framework-iOS.xcscheme rename to SDL2-2.30.5/Xcode/SDL/SDL.xcodeproj/xcshareddata/xcschemes/Framework-iOS.xcscheme diff --git a/SDL2-2.0.12/Xcode/SDL/SDL.xcodeproj/xcshareddata/xcschemes/Framework.xcscheme b/SDL2-2.30.5/Xcode/SDL/SDL.xcodeproj/xcshareddata/xcschemes/xcFramework-iOS.xcscheme similarity index 90% rename from SDL2-2.0.12/Xcode/SDL/SDL.xcodeproj/xcshareddata/xcschemes/Framework.xcscheme rename to SDL2-2.30.5/Xcode/SDL/SDL.xcodeproj/xcshareddata/xcschemes/xcFramework-iOS.xcscheme index 29a9ff6..82b4643 100644 --- a/SDL2-2.0.12/Xcode/SDL/SDL.xcodeproj/xcshareddata/xcschemes/Framework.xcscheme +++ b/SDL2-2.30.5/Xcode/SDL/SDL.xcodeproj/xcshareddata/xcschemes/xcFramework-iOS.xcscheme @@ -14,9 +14,9 @@ buildForAnalyzing = "YES"> @@ -50,9 +50,9 @@ diff --git a/SDL2-2.0.12/Xcode/SDL/hidapi/Info.plist b/SDL2-2.30.5/Xcode/SDL/SDL2/Info.plist similarity index 94% rename from SDL2-2.0.12/Xcode/SDL/hidapi/Info.plist rename to SDL2-2.30.5/Xcode/SDL/SDL2/Info.plist index 145b17a..9bcb244 100644 --- a/SDL2-2.0.12/Xcode/SDL/hidapi/Info.plist +++ b/SDL2-2.30.5/Xcode/SDL/SDL2/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType $(PRODUCT_BUNDLE_PACKAGE_TYPE) CFBundleShortVersionString - $(CURRENT_PROJECT_VERSION) + 1.0 CFBundleVersion $(CURRENT_PROJECT_VERSION) diff --git a/SDL2-2.0.12/Xcode/SDL/pkg-support/SDL.info b/SDL2-2.30.5/Xcode/SDL/pkg-support/SDL.info similarity index 94% rename from SDL2-2.0.12/Xcode/SDL/pkg-support/SDL.info rename to SDL2-2.30.5/Xcode/SDL/pkg-support/SDL.info index f08facd..ee03b71 100644 --- a/SDL2-2.0.12/Xcode/SDL/pkg-support/SDL.info +++ b/SDL2-2.30.5/Xcode/SDL/pkg-support/SDL.info @@ -1,4 +1,4 @@ -Title SDL 2.0.0 +Title SDL 2.30.5 Version 1 Description SDL Library for Mac OS X (http://www.libsdl.org) DefaultLocation /Library/Frameworks diff --git a/SDL2-2.0.12/Xcode/SDL/pkg-support/resources/License.txt b/SDL2-2.30.5/Xcode/SDL/pkg-support/resources/License.txt similarity index 93% rename from SDL2-2.0.12/Xcode/SDL/pkg-support/resources/License.txt rename to SDL2-2.30.5/Xcode/SDL/pkg-support/resources/License.txt index 9bbafca..42f3736 100644 --- a/SDL2-2.0.12/Xcode/SDL/pkg-support/resources/License.txt +++ b/SDL2-2.30.5/Xcode/SDL/pkg-support/resources/License.txt @@ -1,6 +1,6 @@ Simple DirectMedia Layer -Copyright (C) 1997-2020 Sam Lantinga +Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/Xcode/SDL/pkg-support/resources/ReadMe.txt b/SDL2-2.30.5/Xcode/SDL/pkg-support/resources/ReadMe.txt similarity index 69% rename from SDL2-2.0.12/Xcode/SDL/pkg-support/resources/ReadMe.txt rename to SDL2-2.30.5/Xcode/SDL/pkg-support/resources/ReadMe.txt index 40ac3a1..9f49591 100644 --- a/SDL2-2.0.12/Xcode/SDL/pkg-support/resources/ReadMe.txt +++ b/SDL2-2.30.5/Xcode/SDL/pkg-support/resources/ReadMe.txt @@ -18,7 +18,19 @@ To Install: Copy the SDL2.framework to /Library/Frameworks You may alternatively install it in /Library/Frameworks -if your access privileges are not high enough. +if your access privileges are not high enough. + + +Use in CMake projects: +SDL2.framework can be used in CMake projects using the following pattern: +``` +find_package(SDL2 REQUIRED COMPONENTS SDL2) +add_executable(my_game ${MY_SOURCES}) +target_link_libraries(my_game PRIVATE SDL2::SDL2) +``` +If SDL2.framework is installed in a non-standard location, +please refer to the following link for ways to configure CMake: +https://cmake.org/cmake/help/latest/command/find_package.html#config-mode-search-procedure Additional References: diff --git a/SDL2-2.0.12/Xcode/SDL/pkg-support/resources/SDL_DS_Store b/SDL2-2.30.5/Xcode/SDL/pkg-support/resources/SDL_DS_Store similarity index 100% rename from SDL2-2.0.12/Xcode/SDL/pkg-support/resources/SDL_DS_Store rename to SDL2-2.30.5/Xcode/SDL/pkg-support/resources/SDL_DS_Store diff --git a/SDL2-2.0.12/Xcode/SDL/pkg-support/sdl_logo.pdf b/SDL2-2.30.5/Xcode/SDL/pkg-support/sdl_logo.pdf similarity index 100% rename from SDL2-2.0.12/Xcode/SDL/pkg-support/sdl_logo.pdf rename to SDL2-2.30.5/Xcode/SDL/pkg-support/sdl_logo.pdf diff --git a/SDL2-2.0.12/Xcode/SDLTest/SDLTest.xcodeproj/project.pbxproj b/SDL2-2.30.5/Xcode/SDLTest/SDLTest.xcodeproj/project.pbxproj similarity index 51% rename from SDL2-2.0.12/Xcode/SDLTest/SDLTest.xcodeproj/project.pbxproj rename to SDL2-2.30.5/Xcode/SDLTest/SDLTest.xcodeproj/project.pbxproj index 8c524cc..543d100 100644 --- a/SDL2-2.0.12/Xcode/SDLTest/SDLTest.xcodeproj/project.pbxproj +++ b/SDL2-2.30.5/Xcode/SDLTest/SDLTest.xcodeproj/project.pbxproj @@ -63,348 +63,31 @@ /* End PBXAggregateTarget section */ /* Begin PBXBuildFile section */ - 001794D01073667700F5D044 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; - 001794D11073667B00F5D044 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; - 001794D41073668800F5D044 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; - 001794D51073668D00F5D044 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; - 001794D61073669200F5D044 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; - 001794D71073669700F5D044 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; - 001794D91073669E00F5D044 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; - 001794DB107366A700F5D044 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; - 001794DC107366AC00F5D044 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; - 001794DE107366B900F5D044 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; - 001794DF107366BD00F5D044 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; - 001794E0107366C100F5D044 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; - 001794E5107366D900F5D044 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; - 0017957C10741F7900F5D044 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; - 0017957D10741F7900F5D044 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - 0017957E10741F7900F5D044 /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - 0017957F10741F7900F5D044 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - 0017958010741F7900F5D044 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - 0017958110741F7900F5D044 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - 0017958310741F7900F5D044 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - 0017958410741F7900F5D044 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - 0017958510741F7900F5D044 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; 001795901074216E00F5D044 /* testatomic.c in Sources */ = {isa = PBXBuildFile; fileRef = 0017958F1074216E00F5D044 /* testatomic.c */; }; - 0017959D107421BF00F5D044 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; - 0017959E107421BF00F5D044 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - 0017959F107421BF00F5D044 /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - 001795A0107421BF00F5D044 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - 001795A1107421BF00F5D044 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - 001795A2107421BF00F5D044 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - 001795A4107421BF00F5D044 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - 001795A5107421BF00F5D044 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - 001795A6107421BF00F5D044 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; 001795B11074222D00F5D044 /* testaudioinfo.c in Sources */ = {isa = PBXBuildFile; fileRef = 001795B01074222D00F5D044 /* testaudioinfo.c */; }; - 0017971110742F3200F5D044 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; - 0017971210742F3200F5D044 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - 0017971310742F3200F5D044 /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - 0017971410742F3200F5D044 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - 0017971510742F3200F5D044 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - 0017971610742F3200F5D044 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - 0017971810742F3200F5D044 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - 0017971910742F3200F5D044 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - 0017971A10742F3200F5D044 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; 0017972810742FB900F5D044 /* testgl2.c in Sources */ = {isa = PBXBuildFile; fileRef = 0017972710742FB900F5D044 /* testgl2.c */; }; - 00179738107430D600F5D044 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; - 00179739107430D600F5D044 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - 0017973A107430D600F5D044 /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - 0017973B107430D600F5D044 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - 0017973C107430D600F5D044 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - 0017973D107430D600F5D044 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - 0017973F107430D600F5D044 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - 00179740107430D600F5D044 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - 00179741107430D600F5D044 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; 0017974F1074315700F5D044 /* testhaptic.c in Sources */ = {isa = PBXBuildFile; fileRef = 0017974E1074315700F5D044 /* testhaptic.c */; }; - 0017975E107431B300F5D044 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; - 0017975F107431B300F5D044 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - 00179760107431B300F5D044 /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - 00179761107431B300F5D044 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - 00179762107431B300F5D044 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - 00179763107431B300F5D044 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - 00179765107431B300F5D044 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - 00179766107431B300F5D044 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - 00179767107431B300F5D044 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; 001797721074320D00F5D044 /* testdraw2.c in Sources */ = {isa = PBXBuildFile; fileRef = 001797711074320D00F5D044 /* testdraw2.c */; }; - 0017977E107432AE00F5D044 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; - 0017977F107432AE00F5D044 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - 00179780107432AE00F5D044 /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - 00179781107432AE00F5D044 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - 00179782107432AE00F5D044 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - 00179783107432AE00F5D044 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - 00179785107432AE00F5D044 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - 00179786107432AE00F5D044 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - 00179787107432AE00F5D044 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; 00179792107432FA00F5D044 /* testime.c in Sources */ = {isa = PBXBuildFile; fileRef = 00179791107432FA00F5D044 /* testime.c */; }; - 0017979E1074334C00F5D044 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; - 0017979F1074334C00F5D044 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - 001797A01074334C00F5D044 /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - 001797A11074334C00F5D044 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - 001797A21074334C00F5D044 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - 001797A31074334C00F5D044 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - 001797A51074334C00F5D044 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - 001797A61074334C00F5D044 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - 001797A71074334C00F5D044 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; 001797B41074339C00F5D044 /* testintersections.c in Sources */ = {isa = PBXBuildFile; fileRef = 001797B31074339C00F5D044 /* testintersections.c */; }; - 001797C0107433C600F5D044 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; - 001797C1107433C600F5D044 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - 001797C2107433C600F5D044 /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - 001797C3107433C600F5D044 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - 001797C4107433C600F5D044 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - 001797C5107433C600F5D044 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - 001797C7107433C600F5D044 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - 001797C8107433C600F5D044 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - 001797C9107433C600F5D044 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; 001797D41074343E00F5D044 /* testloadso.c in Sources */ = {isa = PBXBuildFile; fileRef = 001797D31074343E00F5D044 /* testloadso.c */; }; - 001798021074355200F5D044 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; - 001798031074355200F5D044 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - 001798041074355200F5D044 /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - 001798051074355200F5D044 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - 001798061074355200F5D044 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - 001798071074355200F5D044 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - 001798091074355200F5D044 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - 0017980A1074355200F5D044 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - 0017980B1074355200F5D044 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; 001798161074359B00F5D044 /* testmultiaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = 001798151074359B00F5D044 /* testmultiaudio.c */; }; 0017987F1074392D00F5D044 /* testnative.c in Sources */ = {isa = PBXBuildFile; fileRef = 0017985A107436ED00F5D044 /* testnative.c */; }; 001798801074392D00F5D044 /* testnativecocoa.m in Sources */ = {isa = PBXBuildFile; fileRef = 0017985C107436ED00F5D044 /* testnativecocoa.m */; }; - 001798811074392D00F5D044 /* testnativex11.c in Sources */ = {isa = PBXBuildFile; fileRef = 00179872107438D000F5D044 /* testnativex11.c */; }; - 001798841074392D00F5D044 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; - 001798851074392D00F5D044 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - 001798861074392D00F5D044 /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - 001798871074392D00F5D044 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - 001798881074392D00F5D044 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - 001798891074392D00F5D044 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - 0017988B1074392D00F5D044 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - 0017988C1074392D00F5D044 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - 0017988D1074392D00F5D044 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; - 001798A5107439DF00F5D044 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; - 001798A6107439DF00F5D044 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - 001798A7107439DF00F5D044 /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - 001798A8107439DF00F5D044 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - 001798A9107439DF00F5D044 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - 001798AA107439DF00F5D044 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - 001798AC107439DF00F5D044 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - 001798AD107439DF00F5D044 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - 001798AE107439DF00F5D044 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; 001798BA10743A4900F5D044 /* testpower.c in Sources */ = {isa = PBXBuildFile; fileRef = 001798B910743A4900F5D044 /* testpower.c */; }; - 001798E210743BEC00F5D044 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; - 001798E310743BEC00F5D044 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - 001798E410743BEC00F5D044 /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - 001798E510743BEC00F5D044 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - 001798E610743BEC00F5D044 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - 001798E710743BEC00F5D044 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - 001798E910743BEC00F5D044 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - 001798EA10743BEC00F5D044 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - 001798EB10743BEC00F5D044 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; 001798FA10743E9200F5D044 /* testresample.c in Sources */ = {isa = PBXBuildFile; fileRef = 001798F910743E9200F5D044 /* testresample.c */; }; - 0017990610743F1000F5D044 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; - 0017990710743F1000F5D044 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - 0017990810743F1000F5D044 /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - 0017990910743F1000F5D044 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - 0017990A10743F1000F5D044 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - 0017990B10743F1000F5D044 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - 0017990D10743F1000F5D044 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - 0017990E10743F1000F5D044 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - 0017990F10743F1000F5D044 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; 0017991A10743F5300F5D044 /* testsprite2.c in Sources */ = {isa = PBXBuildFile; fileRef = 0017991910743F5300F5D044 /* testsprite2.c */; }; - 0017992810743FB700F5D044 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; - 0017992910743FB700F5D044 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - 0017992A10743FB700F5D044 /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - 0017992B10743FB700F5D044 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - 0017992C10743FB700F5D044 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - 0017992D10743FB700F5D044 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - 0017992F10743FB700F5D044 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - 0017993010743FB700F5D044 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - 0017993110743FB700F5D044 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; 0017993C10743FEF00F5D044 /* testwm2.c in Sources */ = {isa = PBXBuildFile; fileRef = 0017993B10743FEF00F5D044 /* testwm2.c */; }; - 002A863010730405007319AE /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; - 002A864110730546007319AE /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - 002A864210730546007319AE /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - 002A864310730546007319AE /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - 002A864D10730546007319AE /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - 002A864E10730546007319AE /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - 002A864F10730546007319AE /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - 002A865310730547007319AE /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - 002A865410730547007319AE /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - 002A865510730547007319AE /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - 002A866210730547007319AE /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - 002A866310730547007319AE /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - 002A866410730547007319AE /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - 002A866B10730548007319AE /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - 002A866C10730548007319AE /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - 002A866D10730548007319AE /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - 002A866E10730548007319AE /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - 002A866F10730548007319AE /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - 002A867010730548007319AE /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - 002A867410730548007319AE /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - 002A867510730548007319AE /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - 002A867610730548007319AE /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - 002A867710730548007319AE /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - 002A867810730548007319AE /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - 002A867910730549007319AE /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - 002A867A10730549007319AE /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - 002A867B10730549007319AE /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - 002A867C10730549007319AE /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - 002A868010730549007319AE /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - 002A868110730549007319AE /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - 002A868210730549007319AE /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - 002A868610730549007319AE /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - 002A868710730549007319AE /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - 002A868810730549007319AE /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - 002A868910730549007319AE /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - 002A868A10730549007319AE /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - 002A868B1073054A007319AE /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - 002A868F1073054A007319AE /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - 002A86901073054A007319AE /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - 002A86911073054A007319AE /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - 002A86951073054A007319AE /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - 002A86961073054A007319AE /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - 002A86971073054A007319AE /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - 002A86981073054A007319AE /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - 002A86991073054A007319AE /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - 002A869A1073054A007319AE /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - 002A86A310730593007319AE /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - 002A86A410730593007319AE /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - 002A86AB10730594007319AE /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - 002A86AC10730594007319AE /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - 002A86AF10730594007319AE /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - 002A86B010730594007319AE /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - 002A86B910730594007319AE /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - 002A86BA10730594007319AE /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - 002A86BF10730595007319AE /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - 002A86C010730595007319AE /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - 002A86C110730595007319AE /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - 002A86C210730595007319AE /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - 002A86C510730595007319AE /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - 002A86C610730595007319AE /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - 002A86C710730595007319AE /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - 002A86C810730595007319AE /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - 002A86C910730595007319AE /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - 002A86CA10730595007319AE /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - 002A86CD10730595007319AE /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - 002A86CE10730596007319AE /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - 002A86D110730596007319AE /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - 002A86D210730596007319AE /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - 002A86D310730596007319AE /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - 002A86D410730596007319AE /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - 002A86D710730596007319AE /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - 002A86D810730596007319AE /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - 002A86DB10730596007319AE /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - 002A86DC10730596007319AE /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - 002A86DD10730596007319AE /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - 002A86DE10730596007319AE /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - 002A871610730623007319AE /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - 002A871A10730623007319AE /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - 002A871C10730623007319AE /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - 002A872110730624007319AE /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - 002A872410730624007319AE /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - 002A872510730624007319AE /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - 002A872710730624007319AE /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - 002A872810730624007319AE /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - 002A872910730624007319AE /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - 002A872B10730624007319AE /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - 002A872D10730624007319AE /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - 002A872E10730624007319AE /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - 002A873010730625007319AE /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - 002A873210730625007319AE /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - 002A873310730625007319AE /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - 002A873B10730675007319AE /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - 002A873F10730675007319AE /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - 002A874110730676007319AE /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - 002A874610730676007319AE /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - 002A874910730676007319AE /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - 002A874A10730676007319AE /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - 002A874C10730676007319AE /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - 002A874D10730677007319AE /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - 002A874E10730677007319AE /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - 002A875010730677007319AE /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - 002A875210730677007319AE /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - 002A875310730677007319AE /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - 002A875510730677007319AE /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - 002A875710730678007319AE /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - 002A875810730678007319AE /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - 002A875E10730745007319AE /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; - 002F33AA09CA188600EBEB88 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; - 002F33AF09CA188600EBEB88 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; - 002F33B009CA188600EBEB88 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; - 002F33B209CA188600EBEB88 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; - 002F33B509CA188600EBEB88 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; - 002F33B609CA188600EBEB88 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; - 002F33B709CA188600EBEB88 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; - 002F33B809CA188600EBEB88 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; - 002F33BC09CA188600EBEB88 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; - 002F33BF09CA188600EBEB88 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; - 002F33C109CA188600EBEB88 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; - 002F340B09CA1BFF00EBEB88 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; 002F341809CA1C5B00EBEB88 /* testfile.c in Sources */ = {isa = PBXBuildFile; fileRef = 002F341709CA1C5B00EBEB88 /* testfile.c */; }; - 002F342A09CA1F0300EBEB88 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; 002F343709CA1F6F00EBEB88 /* testiconv.c in Sources */ = {isa = PBXBuildFile; fileRef = 002F343609CA1F6F00EBEB88 /* testiconv.c */; }; - 002F344609CA1FB300EBEB88 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; 002F345409CA202000EBEB88 /* testoverlay2.c in Sources */ = {isa = PBXBuildFile; fileRef = 002F345209CA201C00EBEB88 /* testoverlay2.c */; }; - 002F346309CA204F00EBEB88 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; 002F347009CA20A600EBEB88 /* testplatform.c in Sources */ = {isa = PBXBuildFile; fileRef = 002F346F09CA20A600EBEB88 /* testplatform.c */; }; 00794E6609D20865003FC8A1 /* sample.wav in CopyFiles */ = {isa = PBXBuildFile; fileRef = 00794E6209D20839003FC8A1 /* sample.wav */; }; 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 */; }; - 66E88E5C203B733D0004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E5D203B73530004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E5E203B74490004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E5F203B74860004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E60203B74C20004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E61203B74CC0004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E62203B74D50004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E63203B74DC0004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E64203B74E50004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E65203B74EC0004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E66203B75140004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E67203B751D0004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E68203B75250004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E69203B75390004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E6A203B75450004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E6B203B754C0004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E6C203B75540004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E6D203B755B0004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E6E203B75620004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E6F203B756A0004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E70203B75710004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E71203B75780004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E72203B757F0004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E73203B758C0004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E74203B75AF0004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E75203B75B90004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E76203B75BF0004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E77203B75C70004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E78203B75CE0004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E79203B75D50004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E7A203B75DE0004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E7B203B75E40004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E7C203B75EB0004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E7D203B75F30004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E7E203B75F90004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E7F203B76000004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E80203B76060004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E81203B760D0004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E82203B76140004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E83203B761D0004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E84203B76230004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E85203B762D0004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E86203B76340004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E87203B763B0004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E88203B76420004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - 66E88E89203B764A0004D44E /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66E88E5B203B733C0004D44E /* Metal.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; 66E88E8B203B778F0004D44E /* testyuv_cvt.c in Sources */ = {isa = PBXBuildFile; fileRef = 66E88E8A203B778F0004D44E /* testyuv_cvt.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 */; }; - BBFC08C3164C6862003E6A99 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - BBFC08C4164C6862003E6A99 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - BBFC08C5164C6862003E6A99 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - BBFC08C7164C6862003E6A99 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - BBFC08C8164C6862003E6A99 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - BBFC08C9164C6862003E6A99 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; BBFC08D0164C6876003E6A99 /* testgamecontroller.c in Sources */ = {isa = PBXBuildFile; fileRef = BBFC088E164C6820003E6A99 /* testgamecontroller.c */; }; BEC566B10761D90300A33029 /* checkkeys.c in Sources */ = {isa = PBXBuildFile; fileRef = 092D6D10FFB30A2C7F000001 /* checkkeys.c */; }; BEC566CB0761D90300A33029 /* loopwave.c in Sources */ = {isa = PBXBuildFile; fileRef = 083E4872006D84C97F000001 /* loopwave.c */; }; @@ -417,35 +100,8 @@ BEC567930761D90500A33029 /* testtimer.c in Sources */ = {isa = PBXBuildFile; fileRef = 083E4880006D86A17F000001 /* testtimer.c */; }; BEC567AD0761D90500A33029 /* testver.c in Sources */ = {isa = PBXBuildFile; fileRef = 083E4882006D86A17F000001 /* testver.c */; }; BEC567F00761D90600A33029 /* torturethread.c in Sources */ = {isa = PBXBuildFile; fileRef = 083E4887006D86A17F000001 /* torturethread.c */; }; - DB0F48DD17CA51E5008798C5 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; - DB0F48DE17CA51E5008798C5 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - DB0F48DF17CA51E5008798C5 /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - DB0F48E017CA51E5008798C5 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - DB0F48E117CA51E5008798C5 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - DB0F48E217CA51E5008798C5 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - DB0F48E417CA51E5008798C5 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - DB0F48E517CA51E5008798C5 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - DB0F48E617CA51E5008798C5 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; DB0F48EE17CA51F8008798C5 /* testdrawchessboard.c in Sources */ = {isa = PBXBuildFile; fileRef = DB0F48D717CA51D2008798C5 /* testdrawchessboard.c */; }; - DB0F48F317CA5212008798C5 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; - DB0F48F417CA5212008798C5 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - DB0F48F517CA5212008798C5 /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - DB0F48F617CA5212008798C5 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - DB0F48F717CA5212008798C5 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - DB0F48F817CA5212008798C5 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - DB0F48FA17CA5212008798C5 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - DB0F48FB17CA5212008798C5 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - DB0F48FC17CA5212008798C5 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; DB0F490317CA5225008798C5 /* testfilesystem.c in Sources */ = {isa = PBXBuildFile; fileRef = DB0F48D817CA51D2008798C5 /* testfilesystem.c */; }; - DB166D7116A1CFB200A1396C /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - DB166D7216A1CFB200A1396C /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - DB166D7316A1CFB200A1396C /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - DB166D7416A1CFB200A1396C /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; - DB166D7516A1CFB200A1396C /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - DB166D7616A1CFB200A1396C /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - DB166D7716A1CFB200A1396C /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - DB166D7816A1CFB200A1396C /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - DB166D7A16A1CFD500A1396C /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; DB166D9316A1D1A500A1396C /* SDL_test_assert.c in Sources */ = {isa = PBXBuildFile; fileRef = DB166D8416A1D1A500A1396C /* SDL_test_assert.c */; }; DB166D9416A1D1A500A1396C /* SDL_test_common.c in Sources */ = {isa = PBXBuildFile; fileRef = DB166D8516A1D1A500A1396C /* SDL_test_common.c */; }; DB166D9516A1D1A500A1396C /* SDL_test_compare.c in Sources */ = {isa = PBXBuildFile; fileRef = DB166D8616A1D1A500A1396C /* SDL_test_compare.c */; }; @@ -468,200 +124,203 @@ DB166DAA16A1D27700A1396C /* libSDL_test.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DB166D7F16A1D12400A1396C /* libSDL_test.a */; }; DB166DAB16A1D27C00A1396C /* libSDL_test.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DB166D7F16A1D12400A1396C /* libSDL_test.a */; }; DB166DAC16A1D29000A1396C /* libSDL_test.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DB166D7F16A1D12400A1396C /* libSDL_test.a */; }; - DB166DB116A1D2F600A1396C /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; - DB166DB216A1D2F600A1396C /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - DB166DB316A1D2F600A1396C /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - DB166DB416A1D2F600A1396C /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - DB166DB516A1D2F600A1396C /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - DB166DB616A1D2F600A1396C /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - DB166DB816A1D2F600A1396C /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - DB166DB916A1D2F600A1396C /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - DB166DBA16A1D2F600A1396C /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; DB166DC116A1D31E00A1396C /* testgesture.c in Sources */ = {isa = PBXBuildFile; fileRef = DB166CBB16A1C74100A1396C /* testgesture.c */; }; - DB166DC816A1D36A00A1396C /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; - DB166DC916A1D36A00A1396C /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - DB166DCA16A1D36A00A1396C /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - DB166DCB16A1D36A00A1396C /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - DB166DCC16A1D36A00A1396C /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - DB166DCD16A1D36A00A1396C /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - DB166DCF16A1D36A00A1396C /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - DB166DD016A1D36A00A1396C /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - DB166DD116A1D36A00A1396C /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; DB166DD716A1D37800A1396C /* testmessage.c in Sources */ = {isa = PBXBuildFile; fileRef = DB166CBD16A1C74100A1396C /* testmessage.c */; }; DB166DDB16A1D42F00A1396C /* icon.bmp in CopyFiles */ = {isa = PBXBuildFile; fileRef = 00794E5D09D20839003FC8A1 /* icon.bmp */; }; - DB166DE016A1D50C00A1396C /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; - DB166DE116A1D50C00A1396C /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - DB166DE216A1D50C00A1396C /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - DB166DE316A1D50C00A1396C /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - DB166DE416A1D50C00A1396C /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - DB166DE516A1D50C00A1396C /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - DB166DE716A1D50C00A1396C /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - DB166DE816A1D50C00A1396C /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - DB166DE916A1D50C00A1396C /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; DB166DEA16A1D50C00A1396C /* libSDL_test.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DB166D7F16A1D12400A1396C /* libSDL_test.a */; }; DB166DF016A1D52500A1396C /* testrelative.c in Sources */ = {isa = PBXBuildFile; fileRef = DB166CBF16A1C74100A1396C /* testrelative.c */; }; - DB166DF716A1D57C00A1396C /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; - DB166DF816A1D57C00A1396C /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - DB166DF916A1D57C00A1396C /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - DB166DFA16A1D57C00A1396C /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - DB166DFB16A1D57C00A1396C /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - DB166DFC16A1D57C00A1396C /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - DB166DFE16A1D57C00A1396C /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - DB166DFF16A1D57C00A1396C /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - DB166E0016A1D57C00A1396C /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; DB166E0116A1D57C00A1396C /* libSDL_test.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DB166D7F16A1D12400A1396C /* libSDL_test.a */; }; DB166E0716A1D59400A1396C /* testrendercopyex.c in Sources */ = {isa = PBXBuildFile; fileRef = DB166CC016A1C74100A1396C /* testrendercopyex.c */; }; - DB166E0E16A1D5AD00A1396C /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; - DB166E0F16A1D5AD00A1396C /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - DB166E1016A1D5AD00A1396C /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - DB166E1116A1D5AD00A1396C /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - DB166E1216A1D5AD00A1396C /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - DB166E1316A1D5AD00A1396C /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - DB166E1516A1D5AD00A1396C /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - DB166E1616A1D5AD00A1396C /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - DB166E1716A1D5AD00A1396C /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; DB166E1816A1D5AD00A1396C /* libSDL_test.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DB166D7F16A1D12400A1396C /* libSDL_test.a */; }; DB166E1E16A1D5C300A1396C /* testrendertarget.c in Sources */ = {isa = PBXBuildFile; fileRef = DB166CC116A1C74100A1396C /* testrendertarget.c */; }; DB166E2216A1D5EC00A1396C /* sample.bmp in CopyFiles */ = {isa = PBXBuildFile; fileRef = 00794E6109D20839003FC8A1 /* sample.bmp */; }; DB166E2316A1D60B00A1396C /* icon.bmp in CopyFiles */ = {isa = PBXBuildFile; fileRef = 00794E5D09D20839003FC8A1 /* icon.bmp */; }; DB166E2516A1D61900A1396C /* icon.bmp in CopyFiles */ = {isa = PBXBuildFile; fileRef = 00794E5D09D20839003FC8A1 /* icon.bmp */; }; DB166E2616A1D61900A1396C /* sample.bmp in CopyFiles */ = {isa = PBXBuildFile; fileRef = 00794E6109D20839003FC8A1 /* sample.bmp */; }; - DB166E2B16A1D64D00A1396C /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; - DB166E2C16A1D64D00A1396C /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - DB166E2D16A1D64D00A1396C /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - DB166E2E16A1D64D00A1396C /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - DB166E2F16A1D64D00A1396C /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - DB166E3016A1D64D00A1396C /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - DB166E3216A1D64D00A1396C /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - DB166E3316A1D64D00A1396C /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - DB166E3416A1D64D00A1396C /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; DB166E3C16A1D66500A1396C /* testrumble.c in Sources */ = {isa = PBXBuildFile; fileRef = DB166CC216A1C74100A1396C /* testrumble.c */; }; - DB166E4116A1D69000A1396C /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; - DB166E4216A1D69000A1396C /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - DB166E4316A1D69000A1396C /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - DB166E4416A1D69000A1396C /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - DB166E4516A1D69000A1396C /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - DB166E4616A1D69000A1396C /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - DB166E4816A1D69000A1396C /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - DB166E4916A1D69000A1396C /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - DB166E4A16A1D69000A1396C /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; DB166E4B16A1D69000A1396C /* libSDL_test.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DB166D7F16A1D12400A1396C /* libSDL_test.a */; }; DB166E4D16A1D69000A1396C /* icon.bmp in CopyFiles */ = {isa = PBXBuildFile; fileRef = 00794E5D09D20839003FC8A1 /* icon.bmp */; }; DB166E4E16A1D69000A1396C /* sample.bmp in CopyFiles */ = {isa = PBXBuildFile; fileRef = 00794E6109D20839003FC8A1 /* sample.bmp */; }; DB166E5416A1D6A300A1396C /* testscale.c in Sources */ = {isa = PBXBuildFile; fileRef = DB166CC316A1C74100A1396C /* testscale.c */; }; - DB166E5B16A1D6F300A1396C /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; - DB166E5C16A1D6F300A1396C /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - DB166E5D16A1D6F300A1396C /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - DB166E5E16A1D6F300A1396C /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - DB166E5F16A1D6F300A1396C /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - DB166E6016A1D6F300A1396C /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - DB166E6216A1D6F300A1396C /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - DB166E6316A1D6F300A1396C /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - DB166E6416A1D6F300A1396C /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; DB166E6A16A1D70C00A1396C /* testshader.c in Sources */ = {isa = PBXBuildFile; fileRef = DB166CC416A1C74100A1396C /* testshader.c */; }; - DB166E7116A1D78400A1396C /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; - DB166E7216A1D78400A1396C /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - DB166E7316A1D78400A1396C /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - DB166E7416A1D78400A1396C /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - DB166E7516A1D78400A1396C /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - DB166E7616A1D78400A1396C /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - DB166E7816A1D78400A1396C /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - DB166E7916A1D78400A1396C /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - DB166E7A16A1D78400A1396C /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; - DB166E8416A1D78C00A1396C /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; - DB166E8516A1D78C00A1396C /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - DB166E8616A1D78C00A1396C /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - DB166E8716A1D78C00A1396C /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - DB166E8816A1D78C00A1396C /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - DB166E8916A1D78C00A1396C /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - DB166E8B16A1D78C00A1396C /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - DB166E8C16A1D78C00A1396C /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - DB166E8D16A1D78C00A1396C /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; DB166E9316A1D7BC00A1396C /* testspriteminimal.c in Sources */ = {isa = PBXBuildFile; fileRef = DB166CC516A1C74100A1396C /* testspriteminimal.c */; }; DB166E9416A1D7C700A1396C /* teststreaming.c in Sources */ = {isa = PBXBuildFile; fileRef = DB166CC616A1C74100A1396C /* teststreaming.c */; }; DB166E9A16A1D7F700A1396C /* moose.dat in CopyFiles */ = {isa = PBXBuildFile; fileRef = 00794E5E09D20839003FC8A1 /* moose.dat */; }; DB166E9C16A1D80900A1396C /* icon.bmp in CopyFiles */ = {isa = PBXBuildFile; fileRef = 00794E5D09D20839003FC8A1 /* icon.bmp */; }; DB166ED016A1D88100A1396C /* shapes in CopyFiles */ = {isa = PBXBuildFile; fileRef = DB166ECF16A1D87000A1396C /* shapes */; }; - DB445EEA18184B7000B306B0 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; - DB445EEB18184B7000B306B0 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - DB445EEC18184B7000B306B0 /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - DB445EED18184B7000B306B0 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - DB445EEE18184B7000B306B0 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - DB445EEF18184B7000B306B0 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - DB445EF118184B7000B306B0 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - DB445EF218184B7000B306B0 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - DB445EF318184B7000B306B0 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; DB445EF418184B7000B306B0 /* libSDL_test.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DB166D7F16A1D12400A1396C /* libSDL_test.a */; }; DB445EFB18184BB600B306B0 /* testdropfile.c in Sources */ = {isa = PBXBuildFile; fileRef = DB445EFA18184BB600B306B0 /* testdropfile.c */; }; - DB89957118A19ABA0092407C /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; - DB89957218A19ABA0092407C /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - DB89957318A19ABA0092407C /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - DB89957418A19ABA0092407C /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - DB89957518A19ABA0092407C /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - DB89957618A19ABA0092407C /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - DB89957818A19ABA0092407C /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - DB89957918A19ABA0092407C /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; - DB89957A18A19ABA0092407C /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; DB89958418A19B130092407C /* testhotplug.c in Sources */ = {isa = PBXBuildFile; fileRef = DB89958318A19B130092407C /* testhotplug.c */; }; - DBEC54DD1A1A81C3005B1EAB /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - DBEC54DE1A1A81C3005B1EAB /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002F33A709CA188600EBEB88 /* Cocoa.framework */; }; - DBEC54DF1A1A81C3005B1EAB /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA645093FFD41000C53B3 /* libSDL2.a */; }; - DBEC54E01A1A81C3005B1EAB /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863B10730545007319AE /* CoreAudio.framework */; }; - DBEC54E11A1A81C3005B1EAB /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863C10730545007319AE /* ForceFeedback.framework */; }; - DBEC54E21A1A81C3005B1EAB /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A863D10730545007319AE /* IOKit.framework */; }; - DBEC54E31A1A81C3005B1EAB /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A869F10730593007319AE /* AudioToolbox.framework */; }; - DBEC54E41A1A81C3005B1EAB /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A86A010730593007319AE /* CoreFoundation.framework */; }; - DBEC54E51A1A81C3005B1EAB /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A871410730623007319AE /* AudioUnit.framework */; }; - DBEC54E61A1A81C3005B1EAB /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 002A873910730675007319AE /* Carbon.framework */; }; DBEC54EB1A1A8205005B1EAB /* controllermap.c in Sources */ = {isa = PBXBuildFile; fileRef = DBEC54D11A1A811D005B1EAB /* controllermap.c */; }; DBEC54ED1A1A828A005B1EAB /* axis.bmp in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBEC54D61A1A8145005B1EAB /* axis.bmp */; }; DBEC54EE1A1A828D005B1EAB /* button.bmp in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBEC54D71A1A8145005B1EAB /* button.bmp */; }; DBEC54EF1A1A828F005B1EAB /* controllermap.bmp in CopyFiles */ = {isa = PBXBuildFile; fileRef = DBEC54D81A1A8145005B1EAB /* controllermap.bmp */; }; - FA73672319A54A90004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73672819A54AB6004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73672919A54AB9004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73672A19A54AC0004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73672B19A54AC2004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73672C19A54AC5004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73672D19A54AC7004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73672E19A54ACA004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73672F19A54ACC004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73673019A54AD0004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73673119A54AD3004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73673219A54AD5004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73673319A54AD8004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73673419A54ADB004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73673519A54ADE004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73673619A54AE1004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73673719A54AE3004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73673819A54AE6004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73673919A54AE8004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73673A19A54AEB004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73673B19A54AED004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73673C19A54AF0004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73673D19A54AF3004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73673E19A54AF6004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73673F19A54AF8004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73674019A54AFB004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73674119A54AFE004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73674219A54B01004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73674319A54B04004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73674419A54B06004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73674519A54B09004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73674619A54B0B004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73674719A54B0F004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73674819A54B13004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73674919A54B16004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73674A19A54B19004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73674B19A54B1B004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73674C19A54B1F004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73674D19A54B22004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73674E19A54B25004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73674F19A54B28004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73675019A54B2B004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73675119A54B2F004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73675219A54B32004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; - FA73675319A54B35004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73672219A54A90004122E4 /* CoreVideo.framework */; }; + F3A249DB2B389C7A00A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A249DC2B389C7A00A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A249DE2B389CCA00A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A249DF2B389CCA00A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A249E12B389CDB00A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A249E22B389CDB00A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A249E42B389CE700A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A249E52B389CE700A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A249E72B389CF000A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A249E82B389CF000A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A249EA2B389CFB00A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A249EB2B389CFB00A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A249ED2B389D0900A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A249EE2B389D0900A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A249F02B389D3100A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A249F12B389D3100A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A249F32B389D3B00A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A249F42B389D3B00A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A249F62B389D4400A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A249F72B389D4400A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A249F92B389D5200A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A249FA2B389D5200A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A249FC2B389D5B00A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A249FD2B389D5B00A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A249FF2B389D6600A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A24A002B389D6600A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A24A022B389D6F00A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A24A032B389D6F00A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A24A052B389D7C00A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A24A062B389D7C00A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A24A082B389D8A00A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A24A092B389D8A00A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A24A0B2B389D9B00A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A24A0C2B389D9B00A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A24A0E2B389DA800A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A24A0F2B389DA800A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A24A112B389DB400A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A24A122B389DB400A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A24A142B389DC000A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A24A152B389DC000A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A24A172B389DCA00A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A24A182B389DCA00A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A24A1A2B389DD600A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A24A1B2B389DD600A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A24A1D2B389DE100A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A24A1E2B389DE100A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A24A202B389DEB00A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A24A212B389DEB00A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A24A232B389DF500A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A24A242B389DF500A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A24A262B389DFF00A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A24A272B389DFF00A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A24A292B389E0900A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A24A2A2B389E0900A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A24A2C2B389E1400A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A24A2D2B389E1400A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A24A302B389E2800A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A24A312B389E2800A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A24A332B389E3200A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A24A342B389E3200A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A24A362B389E4F00A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A24A372B389E4F00A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A24A392B389E5D00A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A24A3A2B389E5D00A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A24A3C2B389E6600A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A24A3D2B389E6600A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A24A3F2B389E7200A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A24A402B389E7200A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A24A422B389E7C00A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A24A432B389E7C00A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A24A452B389E8700A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A24A462B389E8700A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A24A482B389E9100A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A24A492B389E9100A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A24A4B2B389E9C00A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A24A4C2B389E9C00A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A24A4E2B389EA500A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A24A4F2B389EA500A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A24A512B389EB600A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A24A522B389EB600A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A24A542B389EC200A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A24A552B389EC200A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A24A572B389ECD00A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A24A582B389ECD00A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A24A5A2B389ED800A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A24A5B2B389ED800A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A24A5D2B389EE200A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A24A5E2B389EE200A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A24A602B389EED00A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A24A612B389EED00A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A24A632B389EF900A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A24A642B389EF900A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3A24A662B389F0400A5162D /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; }; + F3A24A672B389F0400A5162D /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 003FA643093FFD41000C53B3 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + F3C17C6B28E4022A00E1A26D /* libSDL_test.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DB166D7F16A1D12400A1396C /* libSDL_test.a */; }; + F3C17C7428E40AF000E1A26D /* testutils.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17C7328E40ADE00E1A26D /* testutils.c */; }; + F3C17C7628E40BA200E1A26D /* controllermap_back.bmp in CopyFiles */ = {isa = PBXBuildFile; fileRef = F3C17C7528E40B6B00E1A26D /* controllermap_back.bmp */; }; + F3C17C7728E40BC800E1A26D /* testutils.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17C7328E40ADE00E1A26D /* testutils.c */; }; + F3C17C7928E40C6E00E1A26D /* testutils.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17C7328E40ADE00E1A26D /* testutils.c */; }; + F3C17C7A28E40CA600E1A26D /* libSDL_test.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DB166D7F16A1D12400A1396C /* libSDL_test.a */; }; + F3C17C7B28E40D4E00E1A26D /* testutils.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17C7328E40ADE00E1A26D /* testutils.c */; }; + F3C17C7C28E40D7400E1A26D /* testutils.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17C7328E40ADE00E1A26D /* testutils.c */; }; + F3C17C7D28E40F9D00E1A26D /* testutils.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17C7328E40ADE00E1A26D /* testutils.c */; }; + F3C17C7E28E40FDD00E1A26D /* testutils.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17C7328E40ADE00E1A26D /* testutils.c */; }; + F3C17C7F28E4101000E1A26D /* testutils.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17C7328E40ADE00E1A26D /* testutils.c */; }; + F3C17C8028E410A400E1A26D /* testutils.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17C7328E40ADE00E1A26D /* testutils.c */; }; + F3C17C8128E410C900E1A26D /* testutils.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17C7328E40ADE00E1A26D /* testutils.c */; }; + F3C17C8228E4112900E1A26D /* testutils.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17C7328E40ADE00E1A26D /* testutils.c */; }; + F3C17C8328E4124400E1A26D /* testutils.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17C7328E40ADE00E1A26D /* testutils.c */; }; + F3C17C8428E4126400E1A26D /* testutils.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17C7328E40ADE00E1A26D /* testutils.c */; }; + F3C17C8528E4127D00E1A26D /* testutils.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17C7328E40ADE00E1A26D /* testutils.c */; }; + F3C17CEB28E4177600E1A26D /* testgeometry.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CD628E416AC00E1A26D /* testgeometry.c */; }; + F3C17CEC28E417EB00E1A26D /* testutils.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17C7328E40ADE00E1A26D /* testutils.c */; }; + F3C17CED28E417F400E1A26D /* libSDL_test.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DB166D7F16A1D12400A1396C /* libSDL_test.a */; }; + F3C17CEE28E4184700E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17CEF28E41D5800E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17CFC28E41E9800E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17CFD28E41EA100E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17CFE28E41EAC00E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17CFF28E41EB000E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17D0028E41EB400E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17D0128E41EB800E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17D0228E41EBC00E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17D0328E41EC500E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17D0428E41EC800E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17D0528E41ECB00E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17D0628E41ECF00E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17D0728E41ED300E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17D0828E41EDB00E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17D0928E41EE100E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17D0A28E41EE700E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17D0B28E41EEB00E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17D0C28E41EF000E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17D0D28E41EF400E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17D0E28E41EF900E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17D0F28E41EFE00E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17D1028E41F0200E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17D1128E41F0600E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17D1228E41F0A00E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17D1328E41F0D00E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17D1428E41F1100E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17D1528E41F1F00E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17D1628E41F2400E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17D1728E41F2800E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17D1828E41F2C00E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17D1928E41F3100E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17D1A28E41F3500E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17D1B28E41F3800E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17D1C28E41F3C00E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17D1D28E41F4000E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17D1E28E41F4500E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17D1F28E41F4800E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17D2028E41F4D00E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17D2228E41F5F00E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17D2328E41F6200E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17D2428E41F6600E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17D2528E41F6A00E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17D2628E41F6E00E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17D2728E41FD800E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17D2828E41FDC00E1A26D /* SDL_uikit_main.c in Sources */ = {isa = PBXBuildFile; fileRef = F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */; }; + F3C17D3928E424B800E1A26D /* sample.wav in Resources */ = {isa = PBXBuildFile; fileRef = 00794E6209D20839003FC8A1 /* sample.wav */; }; + F3C17D3B28E4252900E1A26D /* icon.bmp in Resources */ = {isa = PBXBuildFile; fileRef = 00794E5D09D20839003FC8A1 /* icon.bmp */; }; + F3C17D3C28E4277D00E1A26D /* axis.bmp in Resources */ = {isa = PBXBuildFile; fileRef = DBEC54D61A1A8145005B1EAB /* axis.bmp */; }; + F3C17D3D28E4277D00E1A26D /* button.bmp in Resources */ = {isa = PBXBuildFile; fileRef = DBEC54D71A1A8145005B1EAB /* button.bmp */; }; + F3C17D3E28E4277D00E1A26D /* controllermap_back.bmp in Resources */ = {isa = PBXBuildFile; fileRef = F3C17C7528E40B6B00E1A26D /* controllermap_back.bmp */; }; + F3C17D3F28E4277D00E1A26D /* controllermap.bmp in Resources */ = {isa = PBXBuildFile; fileRef = DBEC54D81A1A8145005B1EAB /* controllermap.bmp */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -994,6 +653,55 @@ remoteGlobalIDString = DB31407717554B71006C0E22; remoteInfo = "Shared Library"; }; + F3C17C5C28E3FB2900E1A26D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 003FA63A093FFD41000C53B3 /* SDL.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = A7D88B5423E2437C00DCD162; + remoteInfo = "Framework-iOS"; + }; + F3C17C5E28E3FB2900E1A26D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 003FA63A093FFD41000C53B3 /* SDL.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = A7D88D1523E24BED00DCD162; + remoteInfo = "Framework-tvOS"; + }; + F3C17C6028E3FB2900E1A26D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 003FA63A093FFD41000C53B3 /* SDL.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = E2D187CF28A5673500D2B4F1; + remoteInfo = "xcFramework-iOS"; + }; + F3C17C6228E3FB2900E1A26D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 003FA63A093FFD41000C53B3 /* SDL.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = A7D88E5423E24D3B00DCD162; + remoteInfo = "Static Library-iOS"; + }; + F3C17C6428E3FB2900E1A26D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 003FA63A093FFD41000C53B3 /* SDL.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = A769B23D23E259AE00872273; + remoteInfo = "Static Library-tvOS"; + }; + F3C17C6628E3FB2900E1A26D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 003FA63A093FFD41000C53B3 /* SDL.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = A75FCEB323E25AB700529352; + remoteInfo = "Shared Library-iOS"; + }; + F3C17C6828E3FB2900E1A26D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 003FA63A093FFD41000C53B3 /* SDL.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = A75FD06C23E25AC700529352; + remoteInfo = "Shared Library-tvOS"; + }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -1001,7 +709,7 @@ isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; - dstSubfolderSpec = 16; + dstSubfolderSpec = 7; files = ( 00794E6609D20865003FC8A1 /* sample.wav in CopyFiles */, ); @@ -1011,7 +719,7 @@ isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; - dstSubfolderSpec = 16; + dstSubfolderSpec = 7; files = ( 00794EF009D23739003FC8A1 /* utf8.txt in CopyFiles */, ); @@ -1021,35 +729,17 @@ isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; - dstSubfolderSpec = 16; + dstSubfolderSpec = 7; files = ( 00794EF709D237DE003FC8A1 /* moose.dat in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 0; }; - DB0F48E717CA51E5008798C5 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 16; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - DB0F48FD17CA5212008798C5 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 16; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; DB166DDA16A1D40F00A1396C /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; - dstSubfolderSpec = 16; + dstSubfolderSpec = 7; files = ( DB166DDB16A1D42F00A1396C /* icon.bmp in CopyFiles */, ); @@ -1059,7 +749,7 @@ isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; - dstSubfolderSpec = 16; + dstSubfolderSpec = 7; files = ( DB166E2316A1D60B00A1396C /* icon.bmp in CopyFiles */, DB166E2216A1D5EC00A1396C /* sample.bmp in CopyFiles */, @@ -1070,7 +760,7 @@ isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; - dstSubfolderSpec = 16; + dstSubfolderSpec = 7; files = ( DB166E2516A1D61900A1396C /* icon.bmp in CopyFiles */, DB166E2616A1D61900A1396C /* sample.bmp in CopyFiles */, @@ -1081,7 +771,7 @@ isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; - dstSubfolderSpec = 16; + dstSubfolderSpec = 7; files = ( DB166E4D16A1D69000A1396C /* icon.bmp in CopyFiles */, DB166E4E16A1D69000A1396C /* sample.bmp in CopyFiles */, @@ -1092,7 +782,7 @@ isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; - dstSubfolderSpec = 16; + dstSubfolderSpec = 7; files = ( DB166E9A16A1D7F700A1396C /* moose.dat in CopyFiles */, ); @@ -1102,7 +792,7 @@ isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; - dstSubfolderSpec = 16; + dstSubfolderSpec = 7; files = ( DB166E9C16A1D80900A1396C /* icon.bmp in CopyFiles */, ); @@ -1112,7 +802,7 @@ isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; - dstSubfolderSpec = 16; + dstSubfolderSpec = 7; files = ( DB166ED016A1D88100A1396C /* shapes in CopyFiles */, ); @@ -1122,63 +812,573 @@ isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; - dstSubfolderSpec = 16; + dstSubfolderSpec = 7; files = ( DBEC54ED1A1A828A005B1EAB /* axis.bmp in CopyFiles */, DBEC54EE1A1A828D005B1EAB /* button.bmp in CopyFiles */, DBEC54EF1A1A828F005B1EAB /* controllermap.bmp in CopyFiles */, + F3C17C7628E40BA200E1A26D /* controllermap_back.bmp in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 0; }; + F3A249DD2B389C7A00A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A249DC2B389C7A00A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A249E02B389CCA00A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A249DF2B389CCA00A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A249E32B389CDB00A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A249E22B389CDB00A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A249E62B389CE700A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A249E52B389CE700A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A249E92B389CF000A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A249E82B389CF000A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A249EC2B389CFB00A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A249EB2B389CFB00A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A249EF2B389D0900A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A249EE2B389D0900A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A249F22B389D3100A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A249F12B389D3100A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A249F52B389D3B00A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A249F42B389D3B00A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A249F82B389D4400A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A249F72B389D4400A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A249FB2B389D5200A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A249FA2B389D5200A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A249FE2B389D5B00A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A249FD2B389D5B00A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A24A012B389D6600A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A24A002B389D6600A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A24A042B389D6F00A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A24A032B389D6F00A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A24A072B389D7C00A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A24A062B389D7C00A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A24A0A2B389D8A00A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A24A092B389D8A00A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A24A0D2B389D9B00A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A24A0C2B389D9B00A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A24A102B389DA800A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A24A0F2B389DA800A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A24A132B389DB400A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A24A122B389DB400A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A24A162B389DC000A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A24A152B389DC000A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A24A192B389DCA00A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A24A182B389DCA00A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A24A1C2B389DD600A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A24A1B2B389DD600A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A24A1F2B389DE100A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A24A1E2B389DE100A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A24A222B389DEB00A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A24A212B389DEB00A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A24A252B389DF500A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A24A242B389DF500A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A24A282B389E0000A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A24A272B389DFF00A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A24A2B2B389E0900A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A24A2A2B389E0900A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A24A2E2B389E1500A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A24A2D2B389E1400A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A24A322B389E2800A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A24A312B389E2800A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A24A352B389E3200A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A24A342B389E3200A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A24A382B389E4F00A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A24A372B389E4F00A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A24A3B2B389E5D00A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A24A3A2B389E5D00A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A24A3E2B389E6600A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A24A3D2B389E6600A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A24A412B389E7200A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A24A402B389E7200A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A24A442B389E7C00A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A24A432B389E7C00A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A24A472B389E8700A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A24A462B389E8700A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A24A4A2B389E9100A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A24A492B389E9100A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A24A4D2B389E9C00A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A24A4C2B389E9C00A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A24A502B389EA600A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A24A4F2B389EA500A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A24A532B389EB600A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A24A522B389EB600A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A24A562B389EC200A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A24A552B389EC200A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A24A592B389ECD00A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A24A582B389ECD00A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A24A5C2B389ED800A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A24A5B2B389ED800A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A24A5F2B389EE200A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A24A5E2B389EE200A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A24A622B389EED00A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A24A612B389EED00A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A24A652B389EF900A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A24A642B389EF900A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + F3A24A682B389F0400A5162D /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + F3A24A672B389F0400A5162D /* SDL2.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - 0017958C10741F7900F5D044 /* testatomic */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testatomic; sourceTree = BUILT_PRODUCTS_DIR; }; + 0017958C10741F7900F5D044 /* testatomic.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testatomic.app; sourceTree = BUILT_PRODUCTS_DIR; }; 0017958F1074216E00F5D044 /* testatomic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testatomic.c; sourceTree = ""; }; - 001795AD107421BF00F5D044 /* testaudioinfo */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testaudioinfo; sourceTree = BUILT_PRODUCTS_DIR; }; + 001795AD107421BF00F5D044 /* testaudioinfo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testaudioinfo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 001795B01074222D00F5D044 /* testaudioinfo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testaudioinfo.c; sourceTree = ""; }; - 0017972110742F3200F5D044 /* testgl2 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testgl2; sourceTree = BUILT_PRODUCTS_DIR; }; + 0017972110742F3200F5D044 /* testgl2.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testgl2.app; sourceTree = BUILT_PRODUCTS_DIR; }; 0017972710742FB900F5D044 /* testgl2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testgl2.c; sourceTree = ""; }; - 00179748107430D600F5D044 /* testhaptic */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testhaptic; sourceTree = BUILT_PRODUCTS_DIR; }; + 00179748107430D600F5D044 /* testhaptic.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testhaptic.app; sourceTree = BUILT_PRODUCTS_DIR; }; 0017974E1074315700F5D044 /* testhaptic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testhaptic.c; sourceTree = ""; }; - 0017976E107431B300F5D044 /* testdraw2 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testdraw2; sourceTree = BUILT_PRODUCTS_DIR; }; + 0017976E107431B300F5D044 /* testdraw2.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testdraw2.app; sourceTree = BUILT_PRODUCTS_DIR; }; 001797711074320D00F5D044 /* testdraw2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testdraw2.c; sourceTree = ""; }; - 0017978E107432AE00F5D044 /* testime */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testime; sourceTree = BUILT_PRODUCTS_DIR; }; + 0017978E107432AE00F5D044 /* testime.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testime.app; sourceTree = BUILT_PRODUCTS_DIR; }; 00179791107432FA00F5D044 /* testime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testime.c; sourceTree = ""; }; - 001797AE1074334C00F5D044 /* testintersections */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testintersections; sourceTree = BUILT_PRODUCTS_DIR; }; + 001797AE1074334C00F5D044 /* testintersections.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testintersections.app; sourceTree = BUILT_PRODUCTS_DIR; }; 001797B31074339C00F5D044 /* testintersections.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testintersections.c; sourceTree = ""; }; - 001797D0107433C600F5D044 /* testloadso */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testloadso; sourceTree = BUILT_PRODUCTS_DIR; }; + 001797D0107433C600F5D044 /* testloadso.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testloadso.app; sourceTree = BUILT_PRODUCTS_DIR; }; 001797D31074343E00F5D044 /* testloadso.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testloadso.c; sourceTree = ""; }; - 001798121074355200F5D044 /* testmultiaudio */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testmultiaudio; sourceTree = BUILT_PRODUCTS_DIR; }; + 001798121074355200F5D044 /* testmultiaudio.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testmultiaudio.app; sourceTree = BUILT_PRODUCTS_DIR; }; 001798151074359B00F5D044 /* testmultiaudio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testmultiaudio.c; sourceTree = ""; }; 0017985A107436ED00F5D044 /* testnative.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testnative.c; sourceTree = ""; }; 0017985B107436ED00F5D044 /* testnative.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = testnative.h; sourceTree = ""; }; 0017985C107436ED00F5D044 /* testnativecocoa.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = testnativecocoa.m; sourceTree = ""; }; 00179872107438D000F5D044 /* testnativex11.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testnativex11.c; sourceTree = ""; }; - 001798941074392D00F5D044 /* testnative */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testnative; sourceTree = BUILT_PRODUCTS_DIR; }; - 001798B5107439DF00F5D044 /* testpower */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testpower; sourceTree = BUILT_PRODUCTS_DIR; }; + 001798941074392D00F5D044 /* testnative.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testnative.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 001798B5107439DF00F5D044 /* testpower.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testpower.app; sourceTree = BUILT_PRODUCTS_DIR; }; 001798B910743A4900F5D044 /* testpower.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testpower.c; sourceTree = ""; }; - 001798F210743BEC00F5D044 /* testresample */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testresample; sourceTree = BUILT_PRODUCTS_DIR; }; + 001798F210743BEC00F5D044 /* testresample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testresample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 001798F910743E9200F5D044 /* testresample.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testresample.c; sourceTree = ""; }; - 0017991610743F1000F5D044 /* testsprite2 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testsprite2; sourceTree = BUILT_PRODUCTS_DIR; }; + 0017991610743F1000F5D044 /* testsprite2.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testsprite2.app; sourceTree = BUILT_PRODUCTS_DIR; }; 0017991910743F5300F5D044 /* testsprite2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testsprite2.c; sourceTree = ""; }; - 0017993810743FB700F5D044 /* testwm2 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testwm2; sourceTree = BUILT_PRODUCTS_DIR; }; + 0017993810743FB700F5D044 /* testwm2.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testwm2.app; sourceTree = BUILT_PRODUCTS_DIR; }; 0017993B10743FEF00F5D044 /* testwm2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testwm2.c; sourceTree = ""; }; - 002A863B10730545007319AE /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = /System/Library/Frameworks/CoreAudio.framework; sourceTree = ""; }; - 002A863C10730545007319AE /* ForceFeedback.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ForceFeedback.framework; path = /System/Library/Frameworks/ForceFeedback.framework; sourceTree = ""; }; - 002A863D10730545007319AE /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /System/Library/Frameworks/IOKit.framework; sourceTree = ""; }; - 002A869F10730593007319AE /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = /System/Library/Frameworks/AudioToolbox.framework; sourceTree = ""; }; - 002A86A010730593007319AE /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = ""; }; - 002A871410730623007319AE /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = /System/Library/Frameworks/AudioUnit.framework; sourceTree = ""; }; - 002A873910730675007319AE /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = ""; }; - 002F33A709CA188600EBEB88 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; - 002F341209CA1BFF00EBEB88 /* testfile */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testfile; sourceTree = BUILT_PRODUCTS_DIR; }; + 002F341209CA1BFF00EBEB88 /* testfile.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testfile.app; sourceTree = BUILT_PRODUCTS_DIR; }; 002F341709CA1C5B00EBEB88 /* testfile.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = testfile.c; sourceTree = ""; }; - 002F343109CA1F0300EBEB88 /* testiconv */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testiconv; sourceTree = BUILT_PRODUCTS_DIR; }; + 002F343109CA1F0300EBEB88 /* testiconv.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testiconv.app; sourceTree = BUILT_PRODUCTS_DIR; }; 002F343609CA1F6F00EBEB88 /* testiconv.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = testiconv.c; sourceTree = ""; }; - 002F344D09CA1FB300EBEB88 /* testoverlay2 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testoverlay2; sourceTree = BUILT_PRODUCTS_DIR; }; + 002F344D09CA1FB300EBEB88 /* testoverlay2.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testoverlay2.app; sourceTree = BUILT_PRODUCTS_DIR; }; 002F345209CA201C00EBEB88 /* testoverlay2.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = testoverlay2.c; sourceTree = ""; }; - 002F346A09CA204F00EBEB88 /* testplatform */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testplatform; sourceTree = BUILT_PRODUCTS_DIR; }; + 002F346A09CA204F00EBEB88 /* testplatform.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testplatform.app; sourceTree = BUILT_PRODUCTS_DIR; }; 002F346F09CA20A600EBEB88 /* testplatform.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = testplatform.c; sourceTree = ""; }; 003FA63A093FFD41000C53B3 /* SDL.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SDL.xcodeproj; path = ../SDL/SDL.xcodeproj; sourceTree = SOURCE_ROOT; }; 00794E5D09D20839003FC8A1 /* icon.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = icon.bmp; sourceTree = ""; }; @@ -1198,28 +1398,27 @@ 092D6D62FFB312AA7F000001 /* testjoystick.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = testjoystick.c; sourceTree = ""; }; 092D6D6CFFB313437F000001 /* testkeys.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = testkeys.c; sourceTree = ""; }; 092D6D75FFB313BB7F000001 /* testlock.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = testlock.c; sourceTree = ""; }; - 4537749212091504002F0F45 /* testshape */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testshape; sourceTree = BUILT_PRODUCTS_DIR; }; + 4537749212091504002F0F45 /* testshape.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testshape.app; sourceTree = BUILT_PRODUCTS_DIR; }; 453774A4120915E3002F0F45 /* testshape.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testshape.c; sourceTree = ""; }; - 66E88E5B203B733C0004D44E /* Metal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Metal.framework; path = System/Library/Frameworks/Metal.framework; sourceTree = SDKROOT; }; 66E88E8A203B778F0004D44E /* testyuv_cvt.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = testyuv_cvt.c; sourceTree = ""; }; AAF02FF41F90089800B9A9FB /* SDL_test_memory.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_test_memory.c; sourceTree = ""; }; BBFC088E164C6820003E6A99 /* testgamecontroller.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = 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; }; - BEC566D10761D90300A33029 /* loopwave */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = loopwave; sourceTree = BUILT_PRODUCTS_DIR; }; - BEC567060761D90400A33029 /* testerror */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testerror; sourceTree = BUILT_PRODUCTS_DIR; }; - BEC5672E0761D90400A33029 /* testthread */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testthread; sourceTree = BUILT_PRODUCTS_DIR; }; - BEC5673B0761D90400A33029 /* testjoystick */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testjoystick; sourceTree = BUILT_PRODUCTS_DIR; }; - BEC567480761D90400A33029 /* testkeys */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testkeys; sourceTree = BUILT_PRODUCTS_DIR; }; - BEC567550761D90400A33029 /* testlock */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testlock; sourceTree = BUILT_PRODUCTS_DIR; }; - BEC5677D0761D90500A33029 /* testsem */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testsem; sourceTree = BUILT_PRODUCTS_DIR; }; - BEC567980761D90500A33029 /* testtimer */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testtimer; sourceTree = BUILT_PRODUCTS_DIR; }; - BEC567B20761D90500A33029 /* testversion */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testversion; sourceTree = BUILT_PRODUCTS_DIR; }; - BEC567F50761D90600A33029 /* torturethread */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = torturethread; sourceTree = BUILT_PRODUCTS_DIR; }; + BBFC08CD164C6862003E6A99 /* testgamecontroller.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testgamecontroller.app; sourceTree = BUILT_PRODUCTS_DIR; }; + BEC566B60761D90300A33029 /* checkkeys.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = checkkeys.app; sourceTree = BUILT_PRODUCTS_DIR; }; + BEC566D10761D90300A33029 /* loopwave.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = loopwave.app; sourceTree = BUILT_PRODUCTS_DIR; }; + BEC567060761D90400A33029 /* testerror.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testerror.app; sourceTree = BUILT_PRODUCTS_DIR; }; + BEC5672E0761D90400A33029 /* testthread.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testthread.app; sourceTree = BUILT_PRODUCTS_DIR; }; + BEC5673B0761D90400A33029 /* testjoystick.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testjoystick.app; sourceTree = BUILT_PRODUCTS_DIR; }; + BEC567480761D90400A33029 /* testkeys.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testkeys.app; sourceTree = BUILT_PRODUCTS_DIR; }; + BEC567550761D90400A33029 /* testlock.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testlock.app; sourceTree = BUILT_PRODUCTS_DIR; }; + BEC5677D0761D90500A33029 /* testsem.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testsem.app; sourceTree = BUILT_PRODUCTS_DIR; }; + BEC567980761D90500A33029 /* testtimer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testtimer.app; sourceTree = BUILT_PRODUCTS_DIR; }; + BEC567B20761D90500A33029 /* testversion.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testversion.app; sourceTree = BUILT_PRODUCTS_DIR; }; + BEC567F50761D90600A33029 /* torturethread.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = torturethread.app; sourceTree = BUILT_PRODUCTS_DIR; }; DB0F48D717CA51D2008798C5 /* testdrawchessboard.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = testdrawchessboard.c; sourceTree = ""; }; DB0F48D817CA51D2008798C5 /* testfilesystem.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = testfilesystem.c; sourceTree = ""; }; - DB0F48EC17CA51E5008798C5 /* testdrawchessboard */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testdrawchessboard; sourceTree = BUILT_PRODUCTS_DIR; }; - DB0F490117CA5212008798C5 /* testfilesystem */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testfilesystem; sourceTree = BUILT_PRODUCTS_DIR; }; + DB0F48EC17CA51E5008798C5 /* testdrawchessboard.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testdrawchessboard.app; sourceTree = BUILT_PRODUCTS_DIR; }; + DB0F490117CA5212008798C5 /* testfilesystem.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testfilesystem.app; sourceTree = BUILT_PRODUCTS_DIR; }; DB166CBB16A1C74100A1396C /* testgesture.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = testgesture.c; sourceTree = ""; }; DB166CBC16A1C74100A1396C /* testgles.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = testgles.c; sourceTree = ""; }; DB166CBD16A1C74100A1396C /* testmessage.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = testmessage.c; sourceTree = ""; }; @@ -1247,28 +1446,34 @@ DB166D9016A1D1A500A1396C /* SDL_test_log.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_test_log.c; sourceTree = ""; }; DB166D9116A1D1A500A1396C /* SDL_test_md5.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_test_md5.c; sourceTree = ""; }; DB166D9216A1D1A500A1396C /* SDL_test_random.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_test_random.c; sourceTree = ""; }; - DB166DBF16A1D2F600A1396C /* testgesture */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testgesture; sourceTree = BUILT_PRODUCTS_DIR; }; - DB166DD516A1D36A00A1396C /* testmessage */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testmessage; sourceTree = BUILT_PRODUCTS_DIR; }; - DB166DEE16A1D50C00A1396C /* testrelative */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testrelative; sourceTree = BUILT_PRODUCTS_DIR; }; - DB166E0516A1D57C00A1396C /* testrendercopyex */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testrendercopyex; sourceTree = BUILT_PRODUCTS_DIR; }; - DB166E1C16A1D5AD00A1396C /* testrendertarget */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testrendertarget; sourceTree = BUILT_PRODUCTS_DIR; }; - DB166E3816A1D64D00A1396C /* testrumble */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testrumble; sourceTree = BUILT_PRODUCTS_DIR; }; - DB166E5216A1D69000A1396C /* testscale */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testscale; sourceTree = BUILT_PRODUCTS_DIR; }; - DB166E6816A1D6F300A1396C /* testshader */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testshader; sourceTree = BUILT_PRODUCTS_DIR; }; - DB166E7E16A1D78400A1396C /* testspriteminimal */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testspriteminimal; sourceTree = BUILT_PRODUCTS_DIR; }; - DB166E9116A1D78C00A1396C /* teststreaming */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = teststreaming; sourceTree = BUILT_PRODUCTS_DIR; }; + DB166DBF16A1D2F600A1396C /* testgesture.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testgesture.app; sourceTree = BUILT_PRODUCTS_DIR; }; + DB166DD516A1D36A00A1396C /* testmessage.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testmessage.app; sourceTree = BUILT_PRODUCTS_DIR; }; + DB166DEE16A1D50C00A1396C /* testrelative.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testrelative.app; sourceTree = BUILT_PRODUCTS_DIR; }; + DB166E0516A1D57C00A1396C /* testrendercopyex.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testrendercopyex.app; sourceTree = BUILT_PRODUCTS_DIR; }; + DB166E1C16A1D5AD00A1396C /* testrendertarget.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testrendertarget.app; sourceTree = BUILT_PRODUCTS_DIR; }; + DB166E3816A1D64D00A1396C /* testrumble.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testrumble.app; sourceTree = BUILT_PRODUCTS_DIR; }; + DB166E5216A1D69000A1396C /* testscale.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testscale.app; sourceTree = BUILT_PRODUCTS_DIR; }; + DB166E6816A1D6F300A1396C /* testshader.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testshader.app; sourceTree = BUILT_PRODUCTS_DIR; }; + DB166E7E16A1D78400A1396C /* testspriteminimal.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testspriteminimal.app; sourceTree = BUILT_PRODUCTS_DIR; }; + DB166E9116A1D78C00A1396C /* teststreaming.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = teststreaming.app; sourceTree = BUILT_PRODUCTS_DIR; }; DB166ECF16A1D87000A1396C /* shapes */ = {isa = PBXFileReference; lastKnownFileType = folder; path = shapes; sourceTree = ""; }; DB445EF818184B7000B306B0 /* testdropfile.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testdropfile.app; sourceTree = BUILT_PRODUCTS_DIR; }; DB445EFA18184BB600B306B0 /* testdropfile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testdropfile.c; sourceTree = ""; }; - DB89957E18A19ABA0092407C /* testhotplug */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testhotplug; sourceTree = BUILT_PRODUCTS_DIR; }; + DB89957E18A19ABA0092407C /* testhotplug.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testhotplug.app; sourceTree = BUILT_PRODUCTS_DIR; }; DB89958318A19B130092407C /* testhotplug.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testhotplug.c; sourceTree = ""; }; DBBC552C182831D700F3CA8D /* TestDropFile-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "TestDropFile-Info.plist"; sourceTree = SOURCE_ROOT; }; DBEC54D11A1A811D005B1EAB /* controllermap.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = controllermap.c; sourceTree = ""; }; DBEC54D61A1A8145005B1EAB /* axis.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = axis.bmp; sourceTree = ""; }; DBEC54D71A1A8145005B1EAB /* button.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = button.bmp; sourceTree = ""; }; DBEC54D81A1A8145005B1EAB /* controllermap.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = controllermap.bmp; sourceTree = ""; }; - DBEC54EA1A1A81C3005B1EAB /* controllermap */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = controllermap; sourceTree = BUILT_PRODUCTS_DIR; }; - FA73672219A54A90004122E4 /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = /System/Library/Frameworks/CoreVideo.framework; sourceTree = ""; }; + DBEC54EA1A1A81C3005B1EAB /* controllermap.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = controllermap.app; sourceTree = BUILT_PRODUCTS_DIR; }; + F3A24A2F2B389E1D00A5162D /* testoverlay2-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = "testoverlay2-Info.plist"; sourceTree = ""; }; + F3C17C6A28E3FD4400E1A26D /* config.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = config.xcconfig; sourceTree = ""; }; + F3C17C7328E40ADE00E1A26D /* testutils.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = testutils.c; sourceTree = ""; }; + F3C17C7528E40B6B00E1A26D /* controllermap_back.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; path = controllermap_back.bmp; sourceTree = ""; }; + F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_uikit_main.c; path = ../src/main/uikit/SDL_uikit_main.c; sourceTree = ""; }; + F3C17CD628E416AC00E1A26D /* testgeometry.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testgeometry.c; sourceTree = ""; }; + F3C17CDC28E416CF00E1A26D /* testgeometry.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testgeometry.app; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -1276,17 +1481,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E5F203B74860004D44E /* Metal.framework in Frameworks */, - FA73672919A54AB9004122E4 /* CoreVideo.framework in Frameworks */, - 0017957C10741F7900F5D044 /* Cocoa.framework in Frameworks */, - 0017957D10741F7900F5D044 /* CoreAudio.framework in Frameworks */, - 0017957E10741F7900F5D044 /* ForceFeedback.framework in Frameworks */, - 0017957F10741F7900F5D044 /* IOKit.framework in Frameworks */, - 0017958010741F7900F5D044 /* AudioToolbox.framework in Frameworks */, - 0017958110741F7900F5D044 /* CoreFoundation.framework in Frameworks */, - 0017958310741F7900F5D044 /* AudioUnit.framework in Frameworks */, - 0017958410741F7900F5D044 /* Carbon.framework in Frameworks */, - 0017958510741F7900F5D044 /* libSDL2.a in Frameworks */, + F3A249E72B389CF000A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1294,17 +1489,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E89203B764A0004D44E /* Metal.framework in Frameworks */, - FA73672A19A54AC0004122E4 /* CoreVideo.framework in Frameworks */, - 0017959D107421BF00F5D044 /* Cocoa.framework in Frameworks */, - 0017959E107421BF00F5D044 /* CoreAudio.framework in Frameworks */, - 0017959F107421BF00F5D044 /* ForceFeedback.framework in Frameworks */, - 001795A0107421BF00F5D044 /* IOKit.framework in Frameworks */, - 001795A1107421BF00F5D044 /* AudioToolbox.framework in Frameworks */, - 001795A2107421BF00F5D044 /* CoreFoundation.framework in Frameworks */, - 001795A4107421BF00F5D044 /* AudioUnit.framework in Frameworks */, - 001795A5107421BF00F5D044 /* Carbon.framework in Frameworks */, - 001795A6107421BF00F5D044 /* libSDL2.a in Frameworks */, + F3A249EA2B389CFB00A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1312,18 +1497,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E80203B76060004D44E /* Metal.framework in Frameworks */, - FA73673319A54AD8004122E4 /* CoreVideo.framework in Frameworks */, - 0017971110742F3200F5D044 /* Cocoa.framework in Frameworks */, - 0017971210742F3200F5D044 /* CoreAudio.framework in Frameworks */, - 0017971310742F3200F5D044 /* ForceFeedback.framework in Frameworks */, - 0017971410742F3200F5D044 /* IOKit.framework in Frameworks */, - 0017971510742F3200F5D044 /* AudioToolbox.framework in Frameworks */, - 0017971610742F3200F5D044 /* CoreFoundation.framework in Frameworks */, - 0017971810742F3200F5D044 /* AudioUnit.framework in Frameworks */, - 0017971910742F3200F5D044 /* Carbon.framework in Frameworks */, - 0017971A10742F3200F5D044 /* libSDL2.a in Frameworks */, DB166DA316A1D1FA00A1396C /* libSDL_test.a in Frameworks */, + F3A24A082B389D8A00A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1331,17 +1506,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E7F203B76000004D44E /* Metal.framework in Frameworks */, - FA73673419A54ADB004122E4 /* CoreVideo.framework in Frameworks */, - 00179738107430D600F5D044 /* Cocoa.framework in Frameworks */, - 00179739107430D600F5D044 /* CoreAudio.framework in Frameworks */, - 0017973A107430D600F5D044 /* ForceFeedback.framework in Frameworks */, - 0017973B107430D600F5D044 /* IOKit.framework in Frameworks */, - 0017973C107430D600F5D044 /* AudioToolbox.framework in Frameworks */, - 0017973D107430D600F5D044 /* CoreFoundation.framework in Frameworks */, - 0017973F107430D600F5D044 /* AudioUnit.framework in Frameworks */, - 00179740107430D600F5D044 /* Carbon.framework in Frameworks */, - 00179741107430D600F5D044 /* libSDL2.a in Frameworks */, + F3A24A0B2B389D9B00A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1349,18 +1514,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E88203B76420004D44E /* Metal.framework in Frameworks */, - FA73672B19A54AC2004122E4 /* CoreVideo.framework in Frameworks */, - 0017975E107431B300F5D044 /* Cocoa.framework in Frameworks */, - 0017975F107431B300F5D044 /* CoreAudio.framework in Frameworks */, - 00179760107431B300F5D044 /* ForceFeedback.framework in Frameworks */, - 00179761107431B300F5D044 /* IOKit.framework in Frameworks */, - 00179762107431B300F5D044 /* AudioToolbox.framework in Frameworks */, - 00179763107431B300F5D044 /* CoreFoundation.framework in Frameworks */, - 00179765107431B300F5D044 /* AudioUnit.framework in Frameworks */, - 00179766107431B300F5D044 /* Carbon.framework in Frameworks */, - 00179767107431B300F5D044 /* libSDL2.a in Frameworks */, DB166DA216A1D1E900A1396C /* libSDL_test.a in Frameworks */, + F3A249ED2B389D0900A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1368,18 +1523,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E7C203B75EB0004D44E /* Metal.framework in Frameworks */, - FA73673719A54AE3004122E4 /* CoreVideo.framework in Frameworks */, - 0017977E107432AE00F5D044 /* Cocoa.framework in Frameworks */, - 0017977F107432AE00F5D044 /* CoreAudio.framework in Frameworks */, - 00179780107432AE00F5D044 /* ForceFeedback.framework in Frameworks */, - 00179781107432AE00F5D044 /* IOKit.framework in Frameworks */, - 00179782107432AE00F5D044 /* AudioToolbox.framework in Frameworks */, - 00179783107432AE00F5D044 /* CoreFoundation.framework in Frameworks */, - 00179785107432AE00F5D044 /* AudioUnit.framework in Frameworks */, - 00179786107432AE00F5D044 /* Carbon.framework in Frameworks */, - 00179787107432AE00F5D044 /* libSDL2.a in Frameworks */, DB166DA716A1D24D00A1396C /* libSDL_test.a in Frameworks */, + F3A24A142B389DC000A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1387,18 +1532,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E7B203B75E40004D44E /* Metal.framework in Frameworks */, - FA73673819A54AE6004122E4 /* CoreVideo.framework in Frameworks */, - 0017979E1074334C00F5D044 /* Cocoa.framework in Frameworks */, - 0017979F1074334C00F5D044 /* CoreAudio.framework in Frameworks */, - 001797A01074334C00F5D044 /* ForceFeedback.framework in Frameworks */, - 001797A11074334C00F5D044 /* IOKit.framework in Frameworks */, - 001797A21074334C00F5D044 /* AudioToolbox.framework in Frameworks */, - 001797A31074334C00F5D044 /* CoreFoundation.framework in Frameworks */, - 001797A51074334C00F5D044 /* AudioUnit.framework in Frameworks */, - 001797A61074334C00F5D044 /* Carbon.framework in Frameworks */, - 001797A71074334C00F5D044 /* libSDL2.a in Frameworks */, DB166DAA16A1D27700A1396C /* libSDL_test.a in Frameworks */, + F3A24A172B389DCA00A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1406,17 +1541,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E78203B75CE0004D44E /* Metal.framework in Frameworks */, - FA73673B19A54AED004122E4 /* CoreVideo.framework in Frameworks */, - 001797C0107433C600F5D044 /* Cocoa.framework in Frameworks */, - 001797C1107433C600F5D044 /* CoreAudio.framework in Frameworks */, - 001797C2107433C600F5D044 /* ForceFeedback.framework in Frameworks */, - 001797C3107433C600F5D044 /* IOKit.framework in Frameworks */, - 001797C4107433C600F5D044 /* AudioToolbox.framework in Frameworks */, - 001797C5107433C600F5D044 /* CoreFoundation.framework in Frameworks */, - 001797C7107433C600F5D044 /* AudioUnit.framework in Frameworks */, - 001797C8107433C600F5D044 /* Carbon.framework in Frameworks */, - 001797C9107433C600F5D044 /* libSDL2.a in Frameworks */, + F3A24A202B389DEB00A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1424,17 +1549,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E75203B75B90004D44E /* Metal.framework in Frameworks */, - FA73673E19A54AF6004122E4 /* CoreVideo.framework in Frameworks */, - 001798021074355200F5D044 /* Cocoa.framework in Frameworks */, - 001798031074355200F5D044 /* CoreAudio.framework in Frameworks */, - 001798041074355200F5D044 /* ForceFeedback.framework in Frameworks */, - 001798051074355200F5D044 /* IOKit.framework in Frameworks */, - 001798061074355200F5D044 /* AudioToolbox.framework in Frameworks */, - 001798071074355200F5D044 /* CoreFoundation.framework in Frameworks */, - 001798091074355200F5D044 /* AudioUnit.framework in Frameworks */, - 0017980A1074355200F5D044 /* Carbon.framework in Frameworks */, - 0017980B1074355200F5D044 /* libSDL2.a in Frameworks */, + F3A24A292B389E0900A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1442,17 +1557,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E74203B75AF0004D44E /* Metal.framework in Frameworks */, - FA73673F19A54AF8004122E4 /* CoreVideo.framework in Frameworks */, - 001798841074392D00F5D044 /* Cocoa.framework in Frameworks */, - 001798851074392D00F5D044 /* CoreAudio.framework in Frameworks */, - 001798861074392D00F5D044 /* ForceFeedback.framework in Frameworks */, - 001798871074392D00F5D044 /* IOKit.framework in Frameworks */, - 001798881074392D00F5D044 /* AudioToolbox.framework in Frameworks */, - 001798891074392D00F5D044 /* CoreFoundation.framework in Frameworks */, - 0017988B1074392D00F5D044 /* AudioUnit.framework in Frameworks */, - 0017988C1074392D00F5D044 /* Carbon.framework in Frameworks */, - 0017988D1074392D00F5D044 /* libSDL2.a in Frameworks */, + F3A24A2C2B389E1400A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1460,17 +1565,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E71203B75780004D44E /* Metal.framework in Frameworks */, - FA73674219A54B01004122E4 /* CoreVideo.framework in Frameworks */, - 001798A5107439DF00F5D044 /* Cocoa.framework in Frameworks */, - 001798A6107439DF00F5D044 /* CoreAudio.framework in Frameworks */, - 001798A7107439DF00F5D044 /* ForceFeedback.framework in Frameworks */, - 001798A8107439DF00F5D044 /* IOKit.framework in Frameworks */, - 001798A9107439DF00F5D044 /* AudioToolbox.framework in Frameworks */, - 001798AA107439DF00F5D044 /* CoreFoundation.framework in Frameworks */, - 001798AC107439DF00F5D044 /* AudioUnit.framework in Frameworks */, - 001798AD107439DF00F5D044 /* Carbon.framework in Frameworks */, - 001798AE107439DF00F5D044 /* libSDL2.a in Frameworks */, + F3A24A362B389E4F00A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1478,17 +1573,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E6D203B755B0004D44E /* Metal.framework in Frameworks */, - FA73674619A54B0B004122E4 /* CoreVideo.framework in Frameworks */, - 001798E210743BEC00F5D044 /* Cocoa.framework in Frameworks */, - 001798E310743BEC00F5D044 /* CoreAudio.framework in Frameworks */, - 001798E410743BEC00F5D044 /* ForceFeedback.framework in Frameworks */, - 001798E510743BEC00F5D044 /* IOKit.framework in Frameworks */, - 001798E610743BEC00F5D044 /* AudioToolbox.framework in Frameworks */, - 001798E710743BEC00F5D044 /* CoreFoundation.framework in Frameworks */, - 001798E910743BEC00F5D044 /* AudioUnit.framework in Frameworks */, - 001798EA10743BEC00F5D044 /* Carbon.framework in Frameworks */, - 001798EB10743BEC00F5D044 /* libSDL2.a in Frameworks */, + F3A24A422B389E7C00A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1496,18 +1581,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E67203B751D0004D44E /* Metal.framework in Frameworks */, - FA73674C19A54B1F004122E4 /* CoreVideo.framework in Frameworks */, - 0017990610743F1000F5D044 /* Cocoa.framework in Frameworks */, - 0017990710743F1000F5D044 /* CoreAudio.framework in Frameworks */, - 0017990810743F1000F5D044 /* ForceFeedback.framework in Frameworks */, - 0017990910743F1000F5D044 /* IOKit.framework in Frameworks */, - 0017990A10743F1000F5D044 /* AudioToolbox.framework in Frameworks */, - 0017990B10743F1000F5D044 /* CoreFoundation.framework in Frameworks */, - 0017990D10743F1000F5D044 /* AudioUnit.framework in Frameworks */, - 0017990E10743F1000F5D044 /* Carbon.framework in Frameworks */, - 0017990F10743F1000F5D044 /* libSDL2.a in Frameworks */, DB166DAB16A1D27C00A1396C /* libSDL_test.a in Frameworks */, + F3A249DB2B389C7A00A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1515,18 +1590,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E61203B74CC0004D44E /* Metal.framework in Frameworks */, - FA73675219A54B32004122E4 /* CoreVideo.framework in Frameworks */, - 0017992810743FB700F5D044 /* Cocoa.framework in Frameworks */, - 0017992910743FB700F5D044 /* CoreAudio.framework in Frameworks */, - 0017992A10743FB700F5D044 /* ForceFeedback.framework in Frameworks */, - 0017992B10743FB700F5D044 /* IOKit.framework in Frameworks */, - 0017992C10743FB700F5D044 /* AudioToolbox.framework in Frameworks */, - 0017992D10743FB700F5D044 /* CoreFoundation.framework in Frameworks */, - 0017992F10743FB700F5D044 /* AudioUnit.framework in Frameworks */, - 0017993010743FB700F5D044 /* Carbon.framework in Frameworks */, - 0017993110743FB700F5D044 /* libSDL2.a in Frameworks */, DB166DAC16A1D29000A1396C /* libSDL_test.a in Frameworks */, + F3A24A632B389EF900A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1534,17 +1599,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E84203B76230004D44E /* Metal.framework in Frameworks */, - FA73672F19A54ACC004122E4 /* CoreVideo.framework in Frameworks */, - 002F340B09CA1BFF00EBEB88 /* Cocoa.framework in Frameworks */, - 002A866B10730548007319AE /* CoreAudio.framework in Frameworks */, - 002A866C10730548007319AE /* ForceFeedback.framework in Frameworks */, - 002A866D10730548007319AE /* IOKit.framework in Frameworks */, - 002A86BF10730595007319AE /* AudioToolbox.framework in Frameworks */, - 002A86C010730595007319AE /* CoreFoundation.framework in Frameworks */, - 002A872410730624007319AE /* AudioUnit.framework in Frameworks */, - 002A874910730676007319AE /* Carbon.framework in Frameworks */, - 001794D11073667B00F5D044 /* libSDL2.a in Frameworks */, + F3A249F92B389D5200A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1552,17 +1607,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E7D203B75F30004D44E /* Metal.framework in Frameworks */, - FA73673619A54AE1004122E4 /* CoreVideo.framework in Frameworks */, - 002F342A09CA1F0300EBEB88 /* Cocoa.framework in Frameworks */, - 002A866210730547007319AE /* CoreAudio.framework in Frameworks */, - 002A866310730547007319AE /* ForceFeedback.framework in Frameworks */, - 002A866410730547007319AE /* IOKit.framework in Frameworks */, - 002A86B910730594007319AE /* AudioToolbox.framework in Frameworks */, - 002A86BA10730594007319AE /* CoreFoundation.framework in Frameworks */, - 002A872110730624007319AE /* AudioUnit.framework in Frameworks */, - 002A874610730676007319AE /* Carbon.framework in Frameworks */, - 001794D41073668800F5D044 /* libSDL2.a in Frameworks */, + F3A24A112B389DB400A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1570,17 +1615,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E73203B758C0004D44E /* Metal.framework in Frameworks */, - FA73674019A54AFB004122E4 /* CoreVideo.framework in Frameworks */, - 002F344609CA1FB300EBEB88 /* Cocoa.framework in Frameworks */, - 002A868010730549007319AE /* CoreAudio.framework in Frameworks */, - 002A868110730549007319AE /* ForceFeedback.framework in Frameworks */, - 002A868210730549007319AE /* IOKit.framework in Frameworks */, - 002A86CD10730595007319AE /* AudioToolbox.framework in Frameworks */, - 002A86CE10730596007319AE /* CoreFoundation.framework in Frameworks */, - 002A872B10730624007319AE /* AudioUnit.framework in Frameworks */, - 002A875010730677007319AE /* Carbon.framework in Frameworks */, - 001794D91073669E00F5D044 /* libSDL2.a in Frameworks */, + F3A24A302B389E2800A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1588,17 +1623,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E72203B757F0004D44E /* Metal.framework in Frameworks */, - FA73674119A54AFE004122E4 /* CoreVideo.framework in Frameworks */, - 002F346309CA204F00EBEB88 /* Cocoa.framework in Frameworks */, - 002A868610730549007319AE /* CoreAudio.framework in Frameworks */, - 002A868710730549007319AE /* ForceFeedback.framework in Frameworks */, - 002A868810730549007319AE /* IOKit.framework in Frameworks */, - 002A86D110730596007319AE /* AudioToolbox.framework in Frameworks */, - 002A86D210730596007319AE /* CoreFoundation.framework in Frameworks */, - 002A872D10730624007319AE /* AudioUnit.framework in Frameworks */, - 002A875210730677007319AE /* Carbon.framework in Frameworks */, - 001794DB107366A700F5D044 /* libSDL2.a in Frameworks */, + F3A24A332B389E3200A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1606,18 +1631,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E68203B75250004D44E /* Metal.framework in Frameworks */, - FA73674B19A54B1B004122E4 /* CoreVideo.framework in Frameworks */, - DB166D7116A1CFB200A1396C /* AudioToolbox.framework in Frameworks */, - DB166D7216A1CFB200A1396C /* AudioUnit.framework in Frameworks */, - DB166D7316A1CFB200A1396C /* Carbon.framework in Frameworks */, - DB166D7416A1CFB200A1396C /* Cocoa.framework in Frameworks */, - DB166D7516A1CFB200A1396C /* CoreAudio.framework in Frameworks */, - DB166D7616A1CFB200A1396C /* CoreFoundation.framework in Frameworks */, - DB166D7716A1CFB200A1396C /* ForceFeedback.framework in Frameworks */, - DB166D7816A1CFB200A1396C /* IOKit.framework in Frameworks */, - DB166D7A16A1CFD500A1396C /* libSDL2.a in Frameworks */, DB166DA416A1D21700A1396C /* libSDL_test.a in Frameworks */, + F3A24A512B389EB600A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1625,17 +1640,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E82203B76140004D44E /* Metal.framework in Frameworks */, - FA73673119A54AD3004122E4 /* CoreVideo.framework in Frameworks */, - BBFC08C0164C6862003E6A99 /* Cocoa.framework in Frameworks */, - BBFC08C1164C6862003E6A99 /* CoreAudio.framework in Frameworks */, - BBFC08C2164C6862003E6A99 /* ForceFeedback.framework in Frameworks */, - BBFC08C3164C6862003E6A99 /* IOKit.framework in Frameworks */, - BBFC08C4164C6862003E6A99 /* AudioToolbox.framework in Frameworks */, - BBFC08C5164C6862003E6A99 /* CoreFoundation.framework in Frameworks */, - BBFC08C7164C6862003E6A99 /* AudioUnit.framework in Frameworks */, - BBFC08C8164C6862003E6A99 /* Carbon.framework in Frameworks */, - BBFC08C9164C6862003E6A99 /* libSDL2.a in Frameworks */, + F3A249FF2B389D6600A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1643,17 +1648,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E5C203B733D0004D44E /* Metal.framework in Frameworks */, - FA73672319A54A90004122E4 /* CoreVideo.framework in Frameworks */, - 002F33C109CA188600EBEB88 /* Cocoa.framework in Frameworks */, - 002A863010730405007319AE /* libSDL2.a in Frameworks */, - 002A864D10730546007319AE /* CoreAudio.framework in Frameworks */, - 002A864E10730546007319AE /* ForceFeedback.framework in Frameworks */, - 002A864F10730546007319AE /* IOKit.framework in Frameworks */, - 002A86AB10730594007319AE /* AudioToolbox.framework in Frameworks */, - 002A86AC10730594007319AE /* CoreFoundation.framework in Frameworks */, - 002A871A10730623007319AE /* AudioUnit.framework in Frameworks */, - 002A873F10730675007319AE /* Carbon.framework in Frameworks */, + F3C17C6B28E4022A00E1A26D /* libSDL_test.a in Frameworks */, + F3A249DE2B389CCA00A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1661,17 +1657,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E5E203B74490004D44E /* Metal.framework in Frameworks */, - FA73672819A54AB6004122E4 /* CoreVideo.framework in Frameworks */, - 002F33BF09CA188600EBEB88 /* Cocoa.framework in Frameworks */, - 002A865310730547007319AE /* CoreAudio.framework in Frameworks */, - 002A865410730547007319AE /* ForceFeedback.framework in Frameworks */, - 002A865510730547007319AE /* IOKit.framework in Frameworks */, - 002A86AF10730594007319AE /* AudioToolbox.framework in Frameworks */, - 002A86B010730594007319AE /* CoreFoundation.framework in Frameworks */, - 002A871C10730623007319AE /* AudioUnit.framework in Frameworks */, - 002A874110730676007319AE /* Carbon.framework in Frameworks */, - 002A875E10730745007319AE /* libSDL2.a in Frameworks */, + F3A249E42B389CE700A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1679,17 +1665,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E85203B762D0004D44E /* Metal.framework in Frameworks */, - FA73672E19A54ACA004122E4 /* CoreVideo.framework in Frameworks */, - 002F33BC09CA188600EBEB88 /* Cocoa.framework in Frameworks */, - 002A866E10730548007319AE /* CoreAudio.framework in Frameworks */, - 002A866F10730548007319AE /* ForceFeedback.framework in Frameworks */, - 002A867010730548007319AE /* IOKit.framework in Frameworks */, - 002A86C110730595007319AE /* AudioToolbox.framework in Frameworks */, - 002A86C210730595007319AE /* CoreFoundation.framework in Frameworks */, - 002A872510730624007319AE /* AudioUnit.framework in Frameworks */, - 002A874A10730676007319AE /* Carbon.framework in Frameworks */, - 001794D01073667700F5D044 /* libSDL2.a in Frameworks */, + F3A249F62B389D4400A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1697,17 +1673,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E64203B74E50004D44E /* Metal.framework in Frameworks */, - FA73674F19A54B28004122E4 /* CoreVideo.framework in Frameworks */, - 002F33B809CA188600EBEB88 /* Cocoa.framework in Frameworks */, - 002A868F1073054A007319AE /* CoreAudio.framework in Frameworks */, - 002A86901073054A007319AE /* ForceFeedback.framework in Frameworks */, - 002A86911073054A007319AE /* IOKit.framework in Frameworks */, - 002A86D710730596007319AE /* AudioToolbox.framework in Frameworks */, - 002A86D810730596007319AE /* CoreFoundation.framework in Frameworks */, - 002A873010730625007319AE /* AudioUnit.framework in Frameworks */, - 002A875510730677007319AE /* Carbon.framework in Frameworks */, - 001794DE107366B900F5D044 /* libSDL2.a in Frameworks */, + F3A24A5A2B389ED800A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1715,17 +1681,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E7A203B75DE0004D44E /* Metal.framework in Frameworks */, - FA73673919A54AE8004122E4 /* CoreVideo.framework in Frameworks */, - 002F33B709CA188600EBEB88 /* Cocoa.framework in Frameworks */, - 002A867410730548007319AE /* CoreAudio.framework in Frameworks */, - 002A867510730548007319AE /* ForceFeedback.framework in Frameworks */, - 002A867610730548007319AE /* IOKit.framework in Frameworks */, - 002A86C510730595007319AE /* AudioToolbox.framework in Frameworks */, - 002A86C610730595007319AE /* CoreFoundation.framework in Frameworks */, - 002A872710730624007319AE /* AudioUnit.framework in Frameworks */, - 002A874C10730676007319AE /* Carbon.framework in Frameworks */, - 001794D51073668D00F5D044 /* libSDL2.a in Frameworks */, + F3A24A1A2B389DD600A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1733,17 +1689,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E79203B75D50004D44E /* Metal.framework in Frameworks */, - FA73673A19A54AEB004122E4 /* CoreVideo.framework in Frameworks */, - 002F33B509CA188600EBEB88 /* Cocoa.framework in Frameworks */, - 002A867710730548007319AE /* CoreAudio.framework in Frameworks */, - 002A867810730548007319AE /* ForceFeedback.framework in Frameworks */, - 002A867910730549007319AE /* IOKit.framework in Frameworks */, - 002A86C710730595007319AE /* AudioToolbox.framework in Frameworks */, - 002A86C810730595007319AE /* CoreFoundation.framework in Frameworks */, - 002A872810730624007319AE /* AudioUnit.framework in Frameworks */, - 002A874D10730677007319AE /* Carbon.framework in Frameworks */, - 001794D61073669200F5D044 /* libSDL2.a in Frameworks */, + F3A24A1D2B389DE100A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1751,17 +1697,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E77203B75C70004D44E /* Metal.framework in Frameworks */, - FA73673C19A54AF0004122E4 /* CoreVideo.framework in Frameworks */, - 002F33B609CA188600EBEB88 /* Cocoa.framework in Frameworks */, - 002A867A10730549007319AE /* CoreAudio.framework in Frameworks */, - 002A867B10730549007319AE /* ForceFeedback.framework in Frameworks */, - 002A867C10730549007319AE /* IOKit.framework in Frameworks */, - 002A86C910730595007319AE /* AudioToolbox.framework in Frameworks */, - 002A86CA10730595007319AE /* CoreFoundation.framework in Frameworks */, - 002A872910730624007319AE /* AudioUnit.framework in Frameworks */, - 002A874E10730677007319AE /* Carbon.framework in Frameworks */, - 001794D71073669700F5D044 /* libSDL2.a in Frameworks */, + F3A24A232B389DF500A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1769,17 +1705,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E6A203B75450004D44E /* Metal.framework in Frameworks */, - FA73674919A54B16004122E4 /* CoreVideo.framework in Frameworks */, - 002F33B209CA188600EBEB88 /* Cocoa.framework in Frameworks */, - 002A868910730549007319AE /* CoreAudio.framework in Frameworks */, - 002A868A10730549007319AE /* ForceFeedback.framework in Frameworks */, - 002A868B1073054A007319AE /* IOKit.framework in Frameworks */, - 002A86D310730596007319AE /* AudioToolbox.framework in Frameworks */, - 002A86D410730596007319AE /* CoreFoundation.framework in Frameworks */, - 002A872E10730624007319AE /* AudioUnit.framework in Frameworks */, - 002A875310730677007319AE /* Carbon.framework in Frameworks */, - 001794DC107366AC00F5D044 /* libSDL2.a in Frameworks */, + F3A24A4B2B389E9C00A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1787,17 +1713,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E63203B74DC0004D44E /* Metal.framework in Frameworks */, - FA73675019A54B2B004122E4 /* CoreVideo.framework in Frameworks */, - 002F33B009CA188600EBEB88 /* Cocoa.framework in Frameworks */, - 002A86981073054A007319AE /* CoreAudio.framework in Frameworks */, - 002A86991073054A007319AE /* ForceFeedback.framework in Frameworks */, - 002A869A1073054A007319AE /* IOKit.framework in Frameworks */, - 002A86DD10730596007319AE /* AudioToolbox.framework in Frameworks */, - 002A86DE10730596007319AE /* CoreFoundation.framework in Frameworks */, - 002A873310730625007319AE /* AudioUnit.framework in Frameworks */, - 002A875810730678007319AE /* Carbon.framework in Frameworks */, - 001794DF107366BD00F5D044 /* libSDL2.a in Frameworks */, + F3A24A5D2B389EE200A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1805,17 +1721,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E62203B74D50004D44E /* Metal.framework in Frameworks */, - FA73675119A54B2F004122E4 /* CoreVideo.framework in Frameworks */, - 002F33AF09CA188600EBEB88 /* Cocoa.framework in Frameworks */, - 002A86951073054A007319AE /* CoreAudio.framework in Frameworks */, - 002A86961073054A007319AE /* ForceFeedback.framework in Frameworks */, - 002A86971073054A007319AE /* IOKit.framework in Frameworks */, - 002A86DB10730596007319AE /* AudioToolbox.framework in Frameworks */, - 002A86DC10730596007319AE /* CoreFoundation.framework in Frameworks */, - 002A873210730625007319AE /* AudioUnit.framework in Frameworks */, - 002A875710730678007319AE /* Carbon.framework in Frameworks */, - 001794E0107366C100F5D044 /* libSDL2.a in Frameworks */, + F3A24A602B389EED00A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1823,17 +1729,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E60203B74C20004D44E /* Metal.framework in Frameworks */, - FA73675319A54B35004122E4 /* CoreVideo.framework in Frameworks */, - 002F33AA09CA188600EBEB88 /* Cocoa.framework in Frameworks */, - 002A864110730546007319AE /* CoreAudio.framework in Frameworks */, - 002A864210730546007319AE /* ForceFeedback.framework in Frameworks */, - 002A864310730546007319AE /* IOKit.framework in Frameworks */, - 002A86A310730593007319AE /* AudioToolbox.framework in Frameworks */, - 002A86A410730593007319AE /* CoreFoundation.framework in Frameworks */, - 002A871610730623007319AE /* AudioUnit.framework in Frameworks */, - 002A873B10730675007319AE /* Carbon.framework in Frameworks */, - 001794E5107366D900F5D044 /* libSDL2.a in Frameworks */, + F3A24A662B389F0400A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1841,17 +1737,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E87203B763B0004D44E /* Metal.framework in Frameworks */, - FA73672C19A54AC5004122E4 /* CoreVideo.framework in Frameworks */, - DB0F48DD17CA51E5008798C5 /* Cocoa.framework in Frameworks */, - DB0F48DE17CA51E5008798C5 /* CoreAudio.framework in Frameworks */, - DB0F48DF17CA51E5008798C5 /* ForceFeedback.framework in Frameworks */, - DB0F48E017CA51E5008798C5 /* IOKit.framework in Frameworks */, - DB0F48E117CA51E5008798C5 /* AudioToolbox.framework in Frameworks */, - DB0F48E217CA51E5008798C5 /* CoreFoundation.framework in Frameworks */, - DB0F48E417CA51E5008798C5 /* AudioUnit.framework in Frameworks */, - DB0F48E517CA51E5008798C5 /* Carbon.framework in Frameworks */, - DB0F48E617CA51E5008798C5 /* libSDL2.a in Frameworks */, + F3A249F02B389D3100A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1859,17 +1745,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E83203B761D0004D44E /* Metal.framework in Frameworks */, - FA73673019A54AD0004122E4 /* CoreVideo.framework in Frameworks */, - DB0F48F317CA5212008798C5 /* Cocoa.framework in Frameworks */, - DB0F48F417CA5212008798C5 /* CoreAudio.framework in Frameworks */, - DB0F48F517CA5212008798C5 /* ForceFeedback.framework in Frameworks */, - DB0F48F617CA5212008798C5 /* IOKit.framework in Frameworks */, - DB0F48F717CA5212008798C5 /* AudioToolbox.framework in Frameworks */, - DB0F48F817CA5212008798C5 /* CoreFoundation.framework in Frameworks */, - DB0F48FA17CA5212008798C5 /* AudioUnit.framework in Frameworks */, - DB0F48FB17CA5212008798C5 /* Carbon.framework in Frameworks */, - DB0F48FC17CA5212008798C5 /* libSDL2.a in Frameworks */, + F3A249FC2B389D5B00A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1884,17 +1760,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E81203B760D0004D44E /* Metal.framework in Frameworks */, - FA73673219A54AD5004122E4 /* CoreVideo.framework in Frameworks */, - DB166DB116A1D2F600A1396C /* Cocoa.framework in Frameworks */, - DB166DB216A1D2F600A1396C /* CoreAudio.framework in Frameworks */, - DB166DB316A1D2F600A1396C /* ForceFeedback.framework in Frameworks */, - DB166DB416A1D2F600A1396C /* IOKit.framework in Frameworks */, - DB166DB516A1D2F600A1396C /* AudioToolbox.framework in Frameworks */, - DB166DB616A1D2F600A1396C /* CoreFoundation.framework in Frameworks */, - DB166DB816A1D2F600A1396C /* AudioUnit.framework in Frameworks */, - DB166DB916A1D2F600A1396C /* Carbon.framework in Frameworks */, - DB166DBA16A1D2F600A1396C /* libSDL2.a in Frameworks */, + F3C17C7A28E40CA600E1A26D /* libSDL_test.a in Frameworks */, + F3A24A052B389D7C00A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1902,17 +1769,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E76203B75BF0004D44E /* Metal.framework in Frameworks */, - FA73673D19A54AF3004122E4 /* CoreVideo.framework in Frameworks */, - DB166DC816A1D36A00A1396C /* Cocoa.framework in Frameworks */, - DB166DC916A1D36A00A1396C /* CoreAudio.framework in Frameworks */, - DB166DCA16A1D36A00A1396C /* ForceFeedback.framework in Frameworks */, - DB166DCB16A1D36A00A1396C /* IOKit.framework in Frameworks */, - DB166DCC16A1D36A00A1396C /* AudioToolbox.framework in Frameworks */, - DB166DCD16A1D36A00A1396C /* CoreFoundation.framework in Frameworks */, - DB166DCF16A1D36A00A1396C /* AudioUnit.framework in Frameworks */, - DB166DD016A1D36A00A1396C /* Carbon.framework in Frameworks */, - DB166DD116A1D36A00A1396C /* libSDL2.a in Frameworks */, + F3A24A262B389DFF00A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1920,18 +1777,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E70203B75710004D44E /* Metal.framework in Frameworks */, - FA73674319A54B04004122E4 /* CoreVideo.framework in Frameworks */, - DB166DE016A1D50C00A1396C /* Cocoa.framework in Frameworks */, - DB166DE116A1D50C00A1396C /* CoreAudio.framework in Frameworks */, - DB166DE216A1D50C00A1396C /* ForceFeedback.framework in Frameworks */, - DB166DE316A1D50C00A1396C /* IOKit.framework in Frameworks */, - DB166DE416A1D50C00A1396C /* AudioToolbox.framework in Frameworks */, - DB166DE516A1D50C00A1396C /* CoreFoundation.framework in Frameworks */, - DB166DE716A1D50C00A1396C /* AudioUnit.framework in Frameworks */, - DB166DE816A1D50C00A1396C /* Carbon.framework in Frameworks */, - DB166DE916A1D50C00A1396C /* libSDL2.a in Frameworks */, DB166DEA16A1D50C00A1396C /* libSDL_test.a in Frameworks */, + F3A24A392B389E5D00A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1939,18 +1786,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E6F203B756A0004D44E /* Metal.framework in Frameworks */, - FA73674419A54B06004122E4 /* CoreVideo.framework in Frameworks */, - DB166DF716A1D57C00A1396C /* Cocoa.framework in Frameworks */, - DB166DF816A1D57C00A1396C /* CoreAudio.framework in Frameworks */, - DB166DF916A1D57C00A1396C /* ForceFeedback.framework in Frameworks */, - DB166DFA16A1D57C00A1396C /* IOKit.framework in Frameworks */, - DB166DFB16A1D57C00A1396C /* AudioToolbox.framework in Frameworks */, - DB166DFC16A1D57C00A1396C /* CoreFoundation.framework in Frameworks */, - DB166DFE16A1D57C00A1396C /* AudioUnit.framework in Frameworks */, - DB166DFF16A1D57C00A1396C /* Carbon.framework in Frameworks */, - DB166E0016A1D57C00A1396C /* libSDL2.a in Frameworks */, DB166E0116A1D57C00A1396C /* libSDL_test.a in Frameworks */, + F3A24A3C2B389E6600A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1958,18 +1795,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E6E203B75620004D44E /* Metal.framework in Frameworks */, - FA73674519A54B09004122E4 /* CoreVideo.framework in Frameworks */, - DB166E0E16A1D5AD00A1396C /* Cocoa.framework in Frameworks */, - DB166E0F16A1D5AD00A1396C /* CoreAudio.framework in Frameworks */, - DB166E1016A1D5AD00A1396C /* ForceFeedback.framework in Frameworks */, - DB166E1116A1D5AD00A1396C /* IOKit.framework in Frameworks */, - DB166E1216A1D5AD00A1396C /* AudioToolbox.framework in Frameworks */, - DB166E1316A1D5AD00A1396C /* CoreFoundation.framework in Frameworks */, - DB166E1516A1D5AD00A1396C /* AudioUnit.framework in Frameworks */, - DB166E1616A1D5AD00A1396C /* Carbon.framework in Frameworks */, - DB166E1716A1D5AD00A1396C /* libSDL2.a in Frameworks */, DB166E1816A1D5AD00A1396C /* libSDL_test.a in Frameworks */, + F3A24A3F2B389E7200A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1977,17 +1804,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E6C203B75540004D44E /* Metal.framework in Frameworks */, - FA73674719A54B0F004122E4 /* CoreVideo.framework in Frameworks */, - DB166E2B16A1D64D00A1396C /* Cocoa.framework in Frameworks */, - DB166E2C16A1D64D00A1396C /* CoreAudio.framework in Frameworks */, - DB166E2D16A1D64D00A1396C /* ForceFeedback.framework in Frameworks */, - DB166E2E16A1D64D00A1396C /* IOKit.framework in Frameworks */, - DB166E2F16A1D64D00A1396C /* AudioToolbox.framework in Frameworks */, - DB166E3016A1D64D00A1396C /* CoreFoundation.framework in Frameworks */, - DB166E3216A1D64D00A1396C /* AudioUnit.framework in Frameworks */, - DB166E3316A1D64D00A1396C /* Carbon.framework in Frameworks */, - DB166E3416A1D64D00A1396C /* libSDL2.a in Frameworks */, + F3A24A452B389E8700A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1995,18 +1812,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E6B203B754C0004D44E /* Metal.framework in Frameworks */, - FA73674819A54B13004122E4 /* CoreVideo.framework in Frameworks */, - DB166E4116A1D69000A1396C /* Cocoa.framework in Frameworks */, - DB166E4216A1D69000A1396C /* CoreAudio.framework in Frameworks */, - DB166E4316A1D69000A1396C /* ForceFeedback.framework in Frameworks */, - DB166E4416A1D69000A1396C /* IOKit.framework in Frameworks */, - DB166E4516A1D69000A1396C /* AudioToolbox.framework in Frameworks */, - DB166E4616A1D69000A1396C /* CoreFoundation.framework in Frameworks */, - DB166E4816A1D69000A1396C /* AudioUnit.framework in Frameworks */, - DB166E4916A1D69000A1396C /* Carbon.framework in Frameworks */, - DB166E4A16A1D69000A1396C /* libSDL2.a in Frameworks */, DB166E4B16A1D69000A1396C /* libSDL_test.a in Frameworks */, + F3A24A482B389E9100A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2014,17 +1821,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E69203B75390004D44E /* Metal.framework in Frameworks */, - FA73674A19A54B19004122E4 /* CoreVideo.framework in Frameworks */, - DB166E5B16A1D6F300A1396C /* Cocoa.framework in Frameworks */, - DB166E5C16A1D6F300A1396C /* CoreAudio.framework in Frameworks */, - DB166E5D16A1D6F300A1396C /* ForceFeedback.framework in Frameworks */, - DB166E5E16A1D6F300A1396C /* IOKit.framework in Frameworks */, - DB166E5F16A1D6F300A1396C /* AudioToolbox.framework in Frameworks */, - DB166E6016A1D6F300A1396C /* CoreFoundation.framework in Frameworks */, - DB166E6216A1D6F300A1396C /* AudioUnit.framework in Frameworks */, - DB166E6316A1D6F300A1396C /* Carbon.framework in Frameworks */, - DB166E6416A1D6F300A1396C /* libSDL2.a in Frameworks */, + F3A24A4E2B389EA500A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2032,17 +1829,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E66203B75140004D44E /* Metal.framework in Frameworks */, - FA73674D19A54B22004122E4 /* CoreVideo.framework in Frameworks */, - DB166E7116A1D78400A1396C /* Cocoa.framework in Frameworks */, - DB166E7216A1D78400A1396C /* CoreAudio.framework in Frameworks */, - DB166E7316A1D78400A1396C /* ForceFeedback.framework in Frameworks */, - DB166E7416A1D78400A1396C /* IOKit.framework in Frameworks */, - DB166E7516A1D78400A1396C /* AudioToolbox.framework in Frameworks */, - DB166E7616A1D78400A1396C /* CoreFoundation.framework in Frameworks */, - DB166E7816A1D78400A1396C /* AudioUnit.framework in Frameworks */, - DB166E7916A1D78400A1396C /* Carbon.framework in Frameworks */, - DB166E7A16A1D78400A1396C /* libSDL2.a in Frameworks */, + F3A24A542B389EC200A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2050,17 +1837,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E65203B74EC0004D44E /* Metal.framework in Frameworks */, - FA73674E19A54B25004122E4 /* CoreVideo.framework in Frameworks */, - DB166E8416A1D78C00A1396C /* Cocoa.framework in Frameworks */, - DB166E8516A1D78C00A1396C /* CoreAudio.framework in Frameworks */, - DB166E8616A1D78C00A1396C /* ForceFeedback.framework in Frameworks */, - DB166E8716A1D78C00A1396C /* IOKit.framework in Frameworks */, - DB166E8816A1D78C00A1396C /* AudioToolbox.framework in Frameworks */, - DB166E8916A1D78C00A1396C /* CoreFoundation.framework in Frameworks */, - DB166E8B16A1D78C00A1396C /* AudioUnit.framework in Frameworks */, - DB166E8C16A1D78C00A1396C /* Carbon.framework in Frameworks */, - DB166E8D16A1D78C00A1396C /* libSDL2.a in Frameworks */, + F3A24A572B389ECD00A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2068,18 +1845,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E86203B76340004D44E /* Metal.framework in Frameworks */, - FA73672D19A54AC7004122E4 /* CoreVideo.framework in Frameworks */, - DB445EEA18184B7000B306B0 /* Cocoa.framework in Frameworks */, - DB445EEB18184B7000B306B0 /* CoreAudio.framework in Frameworks */, - DB445EEC18184B7000B306B0 /* ForceFeedback.framework in Frameworks */, - DB445EED18184B7000B306B0 /* IOKit.framework in Frameworks */, - DB445EEE18184B7000B306B0 /* AudioToolbox.framework in Frameworks */, - DB445EEF18184B7000B306B0 /* CoreFoundation.framework in Frameworks */, - DB445EF118184B7000B306B0 /* AudioUnit.framework in Frameworks */, - DB445EF218184B7000B306B0 /* Carbon.framework in Frameworks */, - DB445EF318184B7000B306B0 /* libSDL2.a in Frameworks */, DB445EF418184B7000B306B0 /* libSDL_test.a in Frameworks */, + F3A249F32B389D3B00A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2087,17 +1854,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E7E203B75F90004D44E /* Metal.framework in Frameworks */, - FA73673519A54ADE004122E4 /* CoreVideo.framework in Frameworks */, - DB89957118A19ABA0092407C /* Cocoa.framework in Frameworks */, - DB89957218A19ABA0092407C /* CoreAudio.framework in Frameworks */, - DB89957318A19ABA0092407C /* ForceFeedback.framework in Frameworks */, - DB89957418A19ABA0092407C /* IOKit.framework in Frameworks */, - DB89957518A19ABA0092407C /* AudioToolbox.framework in Frameworks */, - DB89957618A19ABA0092407C /* CoreFoundation.framework in Frameworks */, - DB89957818A19ABA0092407C /* AudioUnit.framework in Frameworks */, - DB89957918A19ABA0092407C /* Carbon.framework in Frameworks */, - DB89957A18A19ABA0092407C /* libSDL2.a in Frameworks */, + F3A24A0E2B389DA800A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2105,46 +1862,36 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 66E88E5D203B73530004D44E /* Metal.framework in Frameworks */, - DBEC54DD1A1A81C3005B1EAB /* CoreVideo.framework in Frameworks */, - DBEC54DE1A1A81C3005B1EAB /* Cocoa.framework in Frameworks */, - DBEC54DF1A1A81C3005B1EAB /* libSDL2.a in Frameworks */, - DBEC54E01A1A81C3005B1EAB /* CoreAudio.framework in Frameworks */, - DBEC54E11A1A81C3005B1EAB /* ForceFeedback.framework in Frameworks */, - DBEC54E21A1A81C3005B1EAB /* IOKit.framework in Frameworks */, - DBEC54E31A1A81C3005B1EAB /* AudioToolbox.framework in Frameworks */, - DBEC54E41A1A81C3005B1EAB /* CoreFoundation.framework in Frameworks */, - DBEC54E51A1A81C3005B1EAB /* AudioUnit.framework in Frameworks */, - DBEC54E61A1A81C3005B1EAB /* Carbon.framework in Frameworks */, + F3A249E12B389CDB00A5162D /* SDL2.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F3C17CD928E416CF00E1A26D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + F3C17CED28E417F400E1A26D /* libSDL_test.a in Frameworks */, + F3A24A022B389D6F00A5162D /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 002F33A209CA183B00EBEB88 /* Linked Frameworks */ = { - isa = PBXGroup; - children = ( - FA73672219A54A90004122E4 /* CoreVideo.framework */, - 002A869F10730593007319AE /* AudioToolbox.framework */, - 002A871410730623007319AE /* AudioUnit.framework */, - 002A873910730675007319AE /* Carbon.framework */, - 002F33A709CA188600EBEB88 /* Cocoa.framework */, - 002A863B10730545007319AE /* CoreAudio.framework */, - 002A86A010730593007319AE /* CoreFoundation.framework */, - 002A863C10730545007319AE /* ForceFeedback.framework */, - 002A863D10730545007319AE /* IOKit.framework */, - ); - name = "Linked Frameworks"; - sourceTree = ""; - }; 003FA63B093FFD41000C53B3 /* Products */ = { isa = PBXGroup; children = ( 003FA643093FFD41000C53B3 /* SDL2.framework */, + F3C17C5D28E3FB2900E1A26D /* SDL2.framework */, + F3C17C5F28E3FB2900E1A26D /* SDL2.framework */, + F3C17C6128E3FB2900E1A26D /* SDL2.framework */, 003FA645093FFD41000C53B3 /* libSDL2.a */, + F3C17C6328E3FB2900E1A26D /* libSDL2.a */, + F3C17C6528E3FB2900E1A26D /* libSDL2.a */, DB1D40D717B3F30D00D74CFC /* libSDL2.dylib */, - 003FA649093FFD41000C53B3 /* Standard DMG */, + F3C17C6728E3FB2900E1A26D /* libSDL2.dylib */, + F3C17C6928E3FB2900E1A26D /* libSDL2.dylib */, + 003FA649093FFD41000C53B3 /* SDL2 */, ); name = Products; sourceTree = ""; @@ -2154,6 +1901,7 @@ children = ( DBEC54D61A1A8145005B1EAB /* axis.bmp */, DBEC54D71A1A8145005B1EAB /* button.bmp */, + F3C17C7528E40B6B00E1A26D /* controllermap_back.bmp */, DBEC54D81A1A8145005B1EAB /* controllermap.bmp */, 00794E5D09D20839003FC8A1 /* icon.bmp */, 00794E5E09D20839003FC8A1 /* moose.dat */, @@ -2171,13 +1919,14 @@ 08FB7794FE84155DC02AAC07 /* SDLTest */ = { isa = PBXGroup; children = ( + F3A24A2F2B389E1D00A5162D /* testoverlay2-Info.plist */, + F3C17C6A28E3FD4400E1A26D /* config.xcconfig */, 003FA63A093FFD41000C53B3 /* SDL.xcodeproj */, 08FB7795FE84155DC02AAC07 /* Source */, DB166D8316A1D17E00A1396C /* SDL_Test */, - 002F33A209CA183B00EBEB88 /* Linked Frameworks */, 00794E4609D207B4003FC8A1 /* Resources */, 1AB674ADFE9D54B511CA2CBB /* Products */, - 66E88E56203B733C0004D44E /* Frameworks */, + F3A249CF2B389C7A00A5162D /* Frameworks */, ); comments = "I made these tests link against our \"default\" framework which includes X11 stuff. If you didn't install the X11 headers with Xcode, you might have problems building the SDL.framework (which is a dependency). You can swap the dependencies around to get around this, or you can modify the default SDL.framework target to not include X11 stuff. (Go into its target build options and remove all the Preprocessor macros.)\n\n\n\nWe are sort of in a half-way state at the moment. Going \"all-the-way\" means we copy the SDL.framework inside the app bundle so we can run the test without the step of the user \"installing\" the framework. But there is an oversight/bug in Xcode that doesn't correctly find the location of the framework when in an embedded/nested Xcode project. We could probably try to hack this with a shell script that checks multiple directories for existence, but this is messier and more work than I prefer, so I rather just wait for Apple to fix this. In the meantime...\n\nThe \"All\" target will build the SDL framework from the Xcode project. The other targets do not have this dependency set (for flexibility reasons in case we make changes). If you have not built the framework, you will probably be unable to link. You will either need to build the framework, or you need to add \"-framework SDL\" to the link options and make sure you have the SDL.framework installed somewhere where it can be seen (like /Library/Frameworks...I think we already set this one up.) \n\nTo run though, you should have a copy of the SDL.framework in /Library/Frameworks or ~/Library/Frameworks.\n\n\n\n\ntestgl and testdyngl need -DHAVE_OPENGL\ntestgl needs to link against OpenGL.framework\n\n"; name = SDLTest; @@ -2186,6 +1935,7 @@ 08FB7795FE84155DC02AAC07 /* Source */ = { isa = PBXGroup; children = ( + F3C17CAC28E414F100E1A26D /* SDL_uikit_main.c */, 092D6D10FFB30A2C7F000001 /* checkkeys.c */, DBEC54D11A1A811D005B1EAB /* controllermap.c */, 083E4872006D84C97F000001 /* loopwave.c */, @@ -2198,6 +1948,7 @@ 002F341709CA1C5B00EBEB88 /* testfile.c */, DB0F48D817CA51D2008798C5 /* testfilesystem.c */, BBFC088E164C6820003E6A99 /* testgamecontroller.c */, + F3C17CD628E416AC00E1A26D /* testgeometry.c */, DB166CBB16A1C74100A1396C /* testgesture.c */, 0017972710742FB900F5D044 /* testgl2.c */, DB166CBC16A1C74100A1396C /* testgles.c */, @@ -2217,7 +1968,6 @@ 0017985C107436ED00F5D044 /* testnativecocoa.m */, 00179872107438D000F5D044 /* testnativex11.c */, 002F345209CA201C00EBEB88 /* testoverlay2.c */, - 66E88E8A203B778F0004D44E /* testyuv_cvt.c */, 002F346F09CA20A600EBEB88 /* testplatform.c */, 001798B910743A4900F5D044 /* testpower.c */, DB166CBF16A1C74100A1396C /* testrelative.c */, @@ -2234,8 +1984,10 @@ DB166CC616A1C74100A1396C /* teststreaming.c */, 092D6D58FFB311A97F000001 /* testthread.c */, 083E4880006D86A17F000001 /* testtimer.c */, + F3C17C7328E40ADE00E1A26D /* testutils.c */, 083E4882006D86A17F000001 /* testver.c */, 0017993B10743FEF00F5D044 /* testwm2.c */, + 66E88E8A203B778F0004D44E /* testyuv_cvt.c */, 083E4887006D86A17F000001 /* torturethread.c */, ); name = Source; @@ -2245,65 +1997,58 @@ 1AB674ADFE9D54B511CA2CBB /* Products */ = { isa = PBXGroup; children = ( - BEC566B60761D90300A33029 /* checkkeys */, - BEC566D10761D90300A33029 /* loopwave */, - BEC567060761D90400A33029 /* testerror */, - BEC5672E0761D90400A33029 /* testthread */, - BEC5673B0761D90400A33029 /* testjoystick */, - BEC567480761D90400A33029 /* testkeys */, - BEC567550761D90400A33029 /* testlock */, - BEC5677D0761D90500A33029 /* testsem */, - BEC567980761D90500A33029 /* testtimer */, - BEC567B20761D90500A33029 /* testversion */, - BEC567F50761D90600A33029 /* torturethread */, - 002F341209CA1BFF00EBEB88 /* testfile */, - 002F343109CA1F0300EBEB88 /* testiconv */, - 002F344D09CA1FB300EBEB88 /* testoverlay2 */, - 002F346A09CA204F00EBEB88 /* testplatform */, - 0017958C10741F7900F5D044 /* testatomic */, - 001795AD107421BF00F5D044 /* testaudioinfo */, - 0017972110742F3200F5D044 /* testgl2 */, - 00179748107430D600F5D044 /* testhaptic */, - 0017976E107431B300F5D044 /* testdraw2 */, - 0017978E107432AE00F5D044 /* testime */, - 001797AE1074334C00F5D044 /* testintersections */, - 001797D0107433C600F5D044 /* testloadso */, - 001798121074355200F5D044 /* testmultiaudio */, - 001798941074392D00F5D044 /* testnative */, - 001798B5107439DF00F5D044 /* testpower */, - 001798F210743BEC00F5D044 /* testresample */, - 0017991610743F1000F5D044 /* testsprite2 */, - 0017993810743FB700F5D044 /* testwm2 */, - 4537749212091504002F0F45 /* testshape */, - BBFC08CD164C6862003E6A99 /* testgamecontroller */, + BEC566B60761D90300A33029 /* checkkeys.app */, + BEC566D10761D90300A33029 /* loopwave.app */, + BEC567060761D90400A33029 /* testerror.app */, + BEC5672E0761D90400A33029 /* testthread.app */, + BEC5673B0761D90400A33029 /* testjoystick.app */, + BEC567480761D90400A33029 /* testkeys.app */, + BEC567550761D90400A33029 /* testlock.app */, + BEC5677D0761D90500A33029 /* testsem.app */, + BEC567980761D90500A33029 /* testtimer.app */, + BEC567B20761D90500A33029 /* testversion.app */, + BEC567F50761D90600A33029 /* torturethread.app */, + 002F341209CA1BFF00EBEB88 /* testfile.app */, + 002F343109CA1F0300EBEB88 /* testiconv.app */, + 002F344D09CA1FB300EBEB88 /* testoverlay2.app */, + 002F346A09CA204F00EBEB88 /* testplatform.app */, + 0017958C10741F7900F5D044 /* testatomic.app */, + 001795AD107421BF00F5D044 /* testaudioinfo.app */, + 0017972110742F3200F5D044 /* testgl2.app */, + 00179748107430D600F5D044 /* testhaptic.app */, + 0017976E107431B300F5D044 /* testdraw2.app */, + 0017978E107432AE00F5D044 /* testime.app */, + 001797AE1074334C00F5D044 /* testintersections.app */, + 001797D0107433C600F5D044 /* testloadso.app */, + 001798121074355200F5D044 /* testmultiaudio.app */, + 001798941074392D00F5D044 /* testnative.app */, + 001798B5107439DF00F5D044 /* testpower.app */, + 001798F210743BEC00F5D044 /* testresample.app */, + 0017991610743F1000F5D044 /* testsprite2.app */, + 0017993810743FB700F5D044 /* testwm2.app */, + 4537749212091504002F0F45 /* testshape.app */, + BBFC08CD164C6862003E6A99 /* testgamecontroller.app */, DB166D7F16A1D12400A1396C /* libSDL_test.a */, - DB166DBF16A1D2F600A1396C /* testgesture */, - DB166DD516A1D36A00A1396C /* testmessage */, - DB166DEE16A1D50C00A1396C /* testrelative */, - DB166E0516A1D57C00A1396C /* testrendercopyex */, - DB166E1C16A1D5AD00A1396C /* testrendertarget */, - DB166E3816A1D64D00A1396C /* testrumble */, - DB166E5216A1D69000A1396C /* testscale */, - DB166E6816A1D6F300A1396C /* testshader */, - DB166E7E16A1D78400A1396C /* testspriteminimal */, - DB166E9116A1D78C00A1396C /* teststreaming */, - DB0F48EC17CA51E5008798C5 /* testdrawchessboard */, - DB0F490117CA5212008798C5 /* testfilesystem */, - DB89957E18A19ABA0092407C /* testhotplug */, + DB166DBF16A1D2F600A1396C /* testgesture.app */, + DB166DD516A1D36A00A1396C /* testmessage.app */, + DB166DEE16A1D50C00A1396C /* testrelative.app */, + DB166E0516A1D57C00A1396C /* testrendercopyex.app */, + DB166E1C16A1D5AD00A1396C /* testrendertarget.app */, + DB166E3816A1D64D00A1396C /* testrumble.app */, + DB166E5216A1D69000A1396C /* testscale.app */, + DB166E6816A1D6F300A1396C /* testshader.app */, + DB166E7E16A1D78400A1396C /* testspriteminimal.app */, + DB166E9116A1D78C00A1396C /* teststreaming.app */, + DB0F48EC17CA51E5008798C5 /* testdrawchessboard.app */, + DB0F490117CA5212008798C5 /* testfilesystem.app */, + DB89957E18A19ABA0092407C /* testhotplug.app */, DB445EF818184B7000B306B0 /* testdropfile.app */, - DBEC54EA1A1A81C3005B1EAB /* controllermap */, + DBEC54EA1A1A81C3005B1EAB /* controllermap.app */, + F3C17CDC28E416CF00E1A26D /* testgeometry.app */, ); name = Products; sourceTree = ""; }; - 66E88E56203B733C0004D44E /* Frameworks */ = { - isa = PBXGroup; - children = ( - 66E88E5B203B733C0004D44E /* Metal.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; DB166D8316A1D17E00A1396C /* SDL_Test */ = { isa = PBXGroup; children = ( @@ -2328,6 +2073,13 @@ path = ../../src/test; sourceTree = ""; }; + F3A249CF2B389C7A00A5162D /* Frameworks */ = { + isa = PBXGroup; + children = ( + ); + name = Frameworks; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -2347,6 +2099,7 @@ buildPhases = ( 0017957910741F7900F5D044 /* Sources */, 0017957A10741F7900F5D044 /* Frameworks */, + F3A249E92B389CF000A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -2354,8 +2107,8 @@ ); name = testatomic; productName = testalpha; - productReference = 0017958C10741F7900F5D044 /* testatomic */; - productType = "com.apple.product-type.tool"; + productReference = 0017958C10741F7900F5D044 /* testatomic.app */; + productType = "com.apple.product-type.application"; }; 00179595107421BF00F5D044 /* testaudioinfo */ = { isa = PBXNativeTarget; @@ -2363,6 +2116,7 @@ buildPhases = ( 0017959A107421BF00F5D044 /* Sources */, 0017959B107421BF00F5D044 /* Frameworks */, + F3A249EC2B389CFB00A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -2370,8 +2124,8 @@ ); name = testaudioinfo; productName = testalpha; - productReference = 001795AD107421BF00F5D044 /* testaudioinfo */; - productType = "com.apple.product-type.tool"; + productReference = 001795AD107421BF00F5D044 /* testaudioinfo.app */; + productType = "com.apple.product-type.application"; }; 0017970910742F3200F5D044 /* testgl2 */ = { isa = PBXNativeTarget; @@ -2379,6 +2133,7 @@ buildPhases = ( 0017970E10742F3200F5D044 /* Sources */, 0017970F10742F3200F5D044 /* Frameworks */, + F3A24A0A2B389D8A00A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -2386,8 +2141,8 @@ ); name = testgl2; productName = testalpha; - productReference = 0017972110742F3200F5D044 /* testgl2 */; - productType = "com.apple.product-type.tool"; + productReference = 0017972110742F3200F5D044 /* testgl2.app */; + productType = "com.apple.product-type.application"; }; 00179730107430D600F5D044 /* testhaptic */ = { isa = PBXNativeTarget; @@ -2395,6 +2150,7 @@ buildPhases = ( 00179735107430D600F5D044 /* Sources */, 00179736107430D600F5D044 /* Frameworks */, + F3A24A0D2B389D9B00A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -2402,8 +2158,8 @@ ); name = testhaptic; productName = testalpha; - productReference = 00179748107430D600F5D044 /* testhaptic */; - productType = "com.apple.product-type.tool"; + productReference = 00179748107430D600F5D044 /* testhaptic.app */; + productType = "com.apple.product-type.application"; }; 00179756107431B300F5D044 /* testdraw2 */ = { isa = PBXNativeTarget; @@ -2411,6 +2167,7 @@ buildPhases = ( 0017975B107431B300F5D044 /* Sources */, 0017975C107431B300F5D044 /* Frameworks */, + F3A249EF2B389D0900A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -2418,8 +2175,8 @@ ); name = testdraw2; productName = testalpha; - productReference = 0017976E107431B300F5D044 /* testdraw2 */; - productType = "com.apple.product-type.tool"; + productReference = 0017976E107431B300F5D044 /* testdraw2.app */; + productType = "com.apple.product-type.application"; }; 00179776107432AE00F5D044 /* testime */ = { isa = PBXNativeTarget; @@ -2427,6 +2184,7 @@ buildPhases = ( 0017977B107432AE00F5D044 /* Sources */, 0017977C107432AE00F5D044 /* Frameworks */, + F3A24A162B389DC000A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -2434,8 +2192,8 @@ ); name = testime; productName = testalpha; - productReference = 0017978E107432AE00F5D044 /* testime */; - productType = "com.apple.product-type.tool"; + productReference = 0017978E107432AE00F5D044 /* testime.app */; + productType = "com.apple.product-type.application"; }; 001797961074334C00F5D044 /* testintersections */ = { isa = PBXNativeTarget; @@ -2443,6 +2201,7 @@ buildPhases = ( 0017979B1074334C00F5D044 /* Sources */, 0017979C1074334C00F5D044 /* Frameworks */, + F3A24A192B389DCA00A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -2450,8 +2209,8 @@ ); name = testintersections; productName = testalpha; - productReference = 001797AE1074334C00F5D044 /* testintersections */; - productType = "com.apple.product-type.tool"; + productReference = 001797AE1074334C00F5D044 /* testintersections.app */; + productType = "com.apple.product-type.application"; }; 001797B8107433C600F5D044 /* testloadso */ = { isa = PBXNativeTarget; @@ -2459,6 +2218,7 @@ buildPhases = ( 001797BD107433C600F5D044 /* Sources */, 001797BE107433C600F5D044 /* Frameworks */, + F3A24A222B389DEB00A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -2466,8 +2226,8 @@ ); name = testloadso; productName = testalpha; - productReference = 001797D0107433C600F5D044 /* testloadso */; - productType = "com.apple.product-type.tool"; + productReference = 001797D0107433C600F5D044 /* testloadso.app */; + productType = "com.apple.product-type.application"; }; 001797FA1074355200F5D044 /* testmultiaudio */ = { isa = PBXNativeTarget; @@ -2475,6 +2235,8 @@ buildPhases = ( 001797FF1074355200F5D044 /* Sources */, 001798001074355200F5D044 /* Frameworks */, + F3C17D3828E424B100E1A26D /* Resources */, + F3A24A2B2B389E0900A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -2482,8 +2244,8 @@ ); name = testmultiaudio; productName = testalpha; - productReference = 001798121074355200F5D044 /* testmultiaudio */; - productType = "com.apple.product-type.tool"; + productReference = 001798121074355200F5D044 /* testmultiaudio.app */; + productType = "com.apple.product-type.application"; }; 001798781074392D00F5D044 /* testnative */ = { isa = PBXNativeTarget; @@ -2492,6 +2254,7 @@ 0017987E1074392D00F5D044 /* Sources */, 001798821074392D00F5D044 /* Frameworks */, DB166DDA16A1D40F00A1396C /* CopyFiles */, + F3A24A2E2B389E1500A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -2499,8 +2262,8 @@ ); name = testnative; productName = testalpha; - productReference = 001798941074392D00F5D044 /* testnative */; - productType = "com.apple.product-type.tool"; + productReference = 001798941074392D00F5D044 /* testnative.app */; + productType = "com.apple.product-type.application"; }; 0017989D107439DF00F5D044 /* testpower */ = { isa = PBXNativeTarget; @@ -2508,6 +2271,7 @@ buildPhases = ( 001798A2107439DF00F5D044 /* Sources */, 001798A3107439DF00F5D044 /* Frameworks */, + F3A24A382B389E4F00A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -2515,8 +2279,8 @@ ); name = testpower; productName = testalpha; - productReference = 001798B5107439DF00F5D044 /* testpower */; - productType = "com.apple.product-type.tool"; + productReference = 001798B5107439DF00F5D044 /* testpower.app */; + productType = "com.apple.product-type.application"; }; 001798DA10743BEC00F5D044 /* testresample */ = { isa = PBXNativeTarget; @@ -2524,6 +2288,7 @@ buildPhases = ( 001798DF10743BEC00F5D044 /* Sources */, 001798E010743BEC00F5D044 /* Frameworks */, + F3A24A442B389E7C00A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -2531,8 +2296,8 @@ ); name = testresample; productName = testalpha; - productReference = 001798F210743BEC00F5D044 /* testresample */; - productType = "com.apple.product-type.tool"; + productReference = 001798F210743BEC00F5D044 /* testresample.app */; + productType = "com.apple.product-type.application"; }; 001798FE10743F1000F5D044 /* testsprite2 */ = { isa = PBXNativeTarget; @@ -2540,6 +2305,8 @@ buildPhases = ( 0017990310743F1000F5D044 /* Sources */, 0017990410743F1000F5D044 /* Frameworks */, + F3C17D3A28E4252200E1A26D /* Resources */, + F3A249DD2B389C7A00A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -2547,8 +2314,8 @@ ); name = testsprite2; productName = testalpha; - productReference = 0017991610743F1000F5D044 /* testsprite2 */; - productType = "com.apple.product-type.tool"; + productReference = 0017991610743F1000F5D044 /* testsprite2.app */; + productType = "com.apple.product-type.application"; }; 0017992010743FB700F5D044 /* testwm2 */ = { isa = PBXNativeTarget; @@ -2556,6 +2323,7 @@ buildPhases = ( 0017992510743FB700F5D044 /* Sources */, 0017992610743FB700F5D044 /* Frameworks */, + F3A24A652B389EF900A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -2563,8 +2331,8 @@ ); name = testwm2; productName = testalpha; - productReference = 0017993810743FB700F5D044 /* testwm2 */; - productType = "com.apple.product-type.tool"; + productReference = 0017993810743FB700F5D044 /* testwm2.app */; + productType = "com.apple.product-type.application"; }; 002F340109CA1BFF00EBEB88 /* testfile */ = { isa = PBXNativeTarget; @@ -2572,6 +2340,7 @@ buildPhases = ( 002F340709CA1BFF00EBEB88 /* Sources */, 002F340809CA1BFF00EBEB88 /* Frameworks */, + F3A249FB2B389D5200A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -2579,8 +2348,8 @@ ); name = testfile; productName = testalpha; - productReference = 002F341209CA1BFF00EBEB88 /* testfile */; - productType = "com.apple.product-type.tool"; + productReference = 002F341209CA1BFF00EBEB88 /* testfile.app */; + productType = "com.apple.product-type.application"; }; 002F342009CA1F0300EBEB88 /* testiconv */ = { isa = PBXNativeTarget; @@ -2589,6 +2358,7 @@ 002F342609CA1F0300EBEB88 /* Sources */, 002F342709CA1F0300EBEB88 /* Frameworks */, 00794EEC09D2371F003FC8A1 /* CopyFiles */, + F3A24A132B389DB400A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -2596,8 +2366,8 @@ ); name = testiconv; productName = testalpha; - productReference = 002F343109CA1F0300EBEB88 /* testiconv */; - productType = "com.apple.product-type.tool"; + productReference = 002F343109CA1F0300EBEB88 /* testiconv.app */; + productType = "com.apple.product-type.application"; }; 002F343C09CA1FB300EBEB88 /* testoverlay2 */ = { isa = PBXNativeTarget; @@ -2606,6 +2376,7 @@ 002F344209CA1FB300EBEB88 /* Sources */, 002F344309CA1FB300EBEB88 /* Frameworks */, 00794EF409D237C7003FC8A1 /* CopyFiles */, + F3A24A322B389E2800A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -2613,8 +2384,8 @@ ); name = testoverlay2; productName = testalpha; - productReference = 002F344D09CA1FB300EBEB88 /* testoverlay2 */; - productType = "com.apple.product-type.tool"; + productReference = 002F344D09CA1FB300EBEB88 /* testoverlay2.app */; + productType = "com.apple.product-type.application"; }; 002F345909CA204F00EBEB88 /* testplatform */ = { isa = PBXNativeTarget; @@ -2622,6 +2393,7 @@ buildPhases = ( 002F345F09CA204F00EBEB88 /* Sources */, 002F346009CA204F00EBEB88 /* Frameworks */, + F3A24A352B389E3200A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -2629,8 +2401,8 @@ ); name = testplatform; productName = testalpha; - productReference = 002F346A09CA204F00EBEB88 /* testplatform */; - productType = "com.apple.product-type.tool"; + productReference = 002F346A09CA204F00EBEB88 /* testplatform.app */; + productType = "com.apple.product-type.application"; }; 4537749112091504002F0F45 /* testshape */ = { isa = PBXNativeTarget; @@ -2639,6 +2411,7 @@ 4537748F12091504002F0F45 /* Sources */, 4537749012091504002F0F45 /* Frameworks */, DB166ECE16A1D85400A1396C /* CopyFiles */, + F3A24A532B389EB600A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -2646,8 +2419,8 @@ ); name = testshape; productName = testshape; - productReference = 4537749212091504002F0F45 /* testshape */; - productType = "com.apple.product-type.tool"; + productReference = 4537749212091504002F0F45 /* testshape.app */; + productType = "com.apple.product-type.application"; }; BBFC08B7164C6862003E6A99 /* testgamecontroller */ = { isa = PBXNativeTarget; @@ -2655,6 +2428,8 @@ buildPhases = ( BBFC08BC164C6862003E6A99 /* Sources */, BBFC08BE164C6862003E6A99 /* Frameworks */, + F3C17D3528E4242100E1A26D /* Resources */, + F3A24A012B389D6600A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -2662,8 +2437,8 @@ ); name = testgamecontroller; productName = testjoystick; - productReference = BBFC08CD164C6862003E6A99 /* testgamecontroller */; - productType = "com.apple.product-type.tool"; + productReference = BBFC08CD164C6862003E6A99 /* testgamecontroller.app */; + productType = "com.apple.product-type.application"; }; BEC566AB0761D90300A33029 /* checkkeys */ = { isa = PBXNativeTarget; @@ -2671,6 +2446,7 @@ buildPhases = ( BEC566B00761D90300A33029 /* Sources */, BEC566B20761D90300A33029 /* Frameworks */, + F3A249E02B389CCA00A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -2678,8 +2454,8 @@ ); name = checkkeys; productName = checkkeys; - productReference = BEC566B60761D90300A33029 /* checkkeys */; - productType = "com.apple.product-type.tool"; + productReference = BEC566B60761D90300A33029 /* checkkeys.app */; + productType = "com.apple.product-type.application"; }; BEC566C50761D90300A33029 /* loopwave */ = { isa = PBXNativeTarget; @@ -2688,6 +2464,7 @@ BEC566CA0761D90300A33029 /* Sources */, BEC566CC0761D90300A33029 /* Frameworks */, 00794E6409D2084F003FC8A1 /* CopyFiles */, + F3A249E62B389CE700A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -2695,8 +2472,8 @@ ); name = loopwave; productName = loopwave; - productReference = BEC566D10761D90300A33029 /* loopwave */; - productType = "com.apple.product-type.tool"; + productReference = BEC566D10761D90300A33029 /* loopwave.app */; + productType = "com.apple.product-type.application"; }; BEC566FB0761D90300A33029 /* testerror */ = { isa = PBXNativeTarget; @@ -2704,6 +2481,7 @@ buildPhases = ( BEC567000761D90300A33029 /* Sources */, BEC567020761D90300A33029 /* Frameworks */, + F3A249F82B389D4400A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -2711,8 +2489,8 @@ ); name = testerror; productName = testerror; - productReference = BEC567060761D90400A33029 /* testerror */; - productType = "com.apple.product-type.tool"; + productReference = BEC567060761D90400A33029 /* testerror.app */; + productType = "com.apple.product-type.application"; }; BEC567230761D90400A33029 /* testthread */ = { isa = PBXNativeTarget; @@ -2720,6 +2498,7 @@ buildPhases = ( BEC567280761D90400A33029 /* Sources */, BEC5672A0761D90400A33029 /* Frameworks */, + F3A24A5C2B389ED800A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -2727,8 +2506,8 @@ ); name = testthread; productName = testthread; - productReference = BEC5672E0761D90400A33029 /* testthread */; - productType = "com.apple.product-type.tool"; + productReference = BEC5672E0761D90400A33029 /* testthread.app */; + productType = "com.apple.product-type.application"; }; BEC567300761D90400A33029 /* testjoystick */ = { isa = PBXNativeTarget; @@ -2736,6 +2515,7 @@ buildPhases = ( BEC567350761D90400A33029 /* Sources */, BEC567370761D90400A33029 /* Frameworks */, + F3A24A1C2B389DD600A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -2743,8 +2523,8 @@ ); name = testjoystick; productName = testjoystick; - productReference = BEC5673B0761D90400A33029 /* testjoystick */; - productType = "com.apple.product-type.tool"; + productReference = BEC5673B0761D90400A33029 /* testjoystick.app */; + productType = "com.apple.product-type.application"; }; BEC5673D0761D90400A33029 /* testkeys */ = { isa = PBXNativeTarget; @@ -2752,6 +2532,7 @@ buildPhases = ( BEC567420761D90400A33029 /* Sources */, BEC567440761D90400A33029 /* Frameworks */, + F3A24A1F2B389DE100A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -2759,8 +2540,8 @@ ); name = testkeys; productName = testkeys; - productReference = BEC567480761D90400A33029 /* testkeys */; - productType = "com.apple.product-type.tool"; + productReference = BEC567480761D90400A33029 /* testkeys.app */; + productType = "com.apple.product-type.application"; }; BEC5674A0761D90400A33029 /* testlock */ = { isa = PBXNativeTarget; @@ -2768,6 +2549,7 @@ buildPhases = ( BEC5674F0761D90400A33029 /* Sources */, BEC567510761D90400A33029 /* Frameworks */, + F3A24A252B389DF500A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -2775,8 +2557,8 @@ ); name = testlock; productName = testlock; - productReference = BEC567550761D90400A33029 /* testlock */; - productType = "com.apple.product-type.tool"; + productReference = BEC567550761D90400A33029 /* testlock.app */; + productType = "com.apple.product-type.application"; }; BEC567720761D90500A33029 /* testsem */ = { isa = PBXNativeTarget; @@ -2784,6 +2566,7 @@ buildPhases = ( BEC567770761D90500A33029 /* Sources */, BEC567790761D90500A33029 /* Frameworks */, + F3A24A4D2B389E9C00A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -2791,8 +2574,8 @@ ); name = testsem; productName = testsem; - productReference = BEC5677D0761D90500A33029 /* testsem */; - productType = "com.apple.product-type.tool"; + productReference = BEC5677D0761D90500A33029 /* testsem.app */; + productType = "com.apple.product-type.application"; }; BEC5678D0761D90500A33029 /* testtimer */ = { isa = PBXNativeTarget; @@ -2800,6 +2583,7 @@ buildPhases = ( BEC567920761D90500A33029 /* Sources */, BEC567940761D90500A33029 /* Frameworks */, + F3A24A5F2B389EE200A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -2807,8 +2591,8 @@ ); name = testtimer; productName = testtimer; - productReference = BEC567980761D90500A33029 /* testtimer */; - productType = "com.apple.product-type.tool"; + productReference = BEC567980761D90500A33029 /* testtimer.app */; + productType = "com.apple.product-type.application"; }; BEC567A70761D90500A33029 /* testversion */ = { isa = PBXNativeTarget; @@ -2816,6 +2600,7 @@ buildPhases = ( BEC567AC0761D90500A33029 /* Sources */, BEC567AE0761D90500A33029 /* Frameworks */, + F3A24A622B389EED00A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -2823,8 +2608,8 @@ ); name = testversion; productName = testversion; - productReference = BEC567B20761D90500A33029 /* testversion */; - productType = "com.apple.product-type.tool"; + productReference = BEC567B20761D90500A33029 /* testversion.app */; + productType = "com.apple.product-type.application"; }; BEC567EA0761D90600A33029 /* torturethread */ = { isa = PBXNativeTarget; @@ -2832,6 +2617,7 @@ buildPhases = ( BEC567EF0761D90600A33029 /* Sources */, BEC567F10761D90600A33029 /* Frameworks */, + F3A24A682B389F0400A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -2839,8 +2625,8 @@ ); name = torturethread; productName = torturethread; - productReference = BEC567F50761D90600A33029 /* torturethread */; - productType = "com.apple.product-type.tool"; + productReference = BEC567F50761D90600A33029 /* torturethread.app */; + productType = "com.apple.product-type.application"; }; DB0F48D917CA51E5008798C5 /* testdrawchessboard */ = { isa = PBXNativeTarget; @@ -2848,7 +2634,7 @@ buildPhases = ( DB0F48DA17CA51E5008798C5 /* Sources */, DB0F48DC17CA51E5008798C5 /* Frameworks */, - DB0F48E717CA51E5008798C5 /* CopyFiles */, + F3A249F22B389D3100A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -2856,8 +2642,8 @@ ); name = testdrawchessboard; productName = testalpha; - productReference = DB0F48EC17CA51E5008798C5 /* testdrawchessboard */; - productType = "com.apple.product-type.tool"; + productReference = DB0F48EC17CA51E5008798C5 /* testdrawchessboard.app */; + productType = "com.apple.product-type.application"; }; DB0F48EF17CA5212008798C5 /* testfilesystem */ = { isa = PBXNativeTarget; @@ -2865,7 +2651,7 @@ buildPhases = ( DB0F48F017CA5212008798C5 /* Sources */, DB0F48F217CA5212008798C5 /* Frameworks */, - DB0F48FD17CA5212008798C5 /* CopyFiles */, + F3A249FE2B389D5B00A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -2873,8 +2659,8 @@ ); name = testfilesystem; productName = testalpha; - productReference = DB0F490117CA5212008798C5 /* testfilesystem */; - productType = "com.apple.product-type.tool"; + productReference = DB0F490117CA5212008798C5 /* testfilesystem.app */; + productType = "com.apple.product-type.application"; }; DB166D7E16A1D12400A1396C /* SDL_test */ = { isa = PBXNativeTarget; @@ -2899,6 +2685,7 @@ buildPhases = ( DB166DAE16A1D2F600A1396C /* Sources */, DB166DB016A1D2F600A1396C /* Frameworks */, + F3A24A072B389D7C00A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -2906,8 +2693,8 @@ ); name = testgesture; productName = testalpha; - productReference = DB166DBF16A1D2F600A1396C /* testgesture */; - productType = "com.apple.product-type.tool"; + productReference = DB166DBF16A1D2F600A1396C /* testgesture.app */; + productType = "com.apple.product-type.application"; }; DB166DC416A1D36A00A1396C /* testmessage */ = { isa = PBXNativeTarget; @@ -2915,6 +2702,7 @@ buildPhases = ( DB166DC516A1D36A00A1396C /* Sources */, DB166DC716A1D36A00A1396C /* Frameworks */, + F3A24A282B389E0000A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -2922,8 +2710,8 @@ ); name = testmessage; productName = testalpha; - productReference = DB166DD516A1D36A00A1396C /* testmessage */; - productType = "com.apple.product-type.tool"; + productReference = DB166DD516A1D36A00A1396C /* testmessage.app */; + productType = "com.apple.product-type.application"; }; DB166DDC16A1D50C00A1396C /* testrelative */ = { isa = PBXNativeTarget; @@ -2931,6 +2719,7 @@ buildPhases = ( DB166DDD16A1D50C00A1396C /* Sources */, DB166DDF16A1D50C00A1396C /* Frameworks */, + F3A24A3B2B389E5D00A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -2938,8 +2727,8 @@ ); name = testrelative; productName = testalpha; - productReference = DB166DEE16A1D50C00A1396C /* testrelative */; - productType = "com.apple.product-type.tool"; + productReference = DB166DEE16A1D50C00A1396C /* testrelative.app */; + productType = "com.apple.product-type.application"; }; DB166DF316A1D57C00A1396C /* testrendercopyex */ = { isa = PBXNativeTarget; @@ -2948,6 +2737,7 @@ DB166DF416A1D57C00A1396C /* Sources */, DB166DF616A1D57C00A1396C /* Frameworks */, DB166E2116A1D5DF00A1396C /* CopyFiles */, + F3A24A3E2B389E6600A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -2955,8 +2745,8 @@ ); name = testrendercopyex; productName = testalpha; - productReference = DB166E0516A1D57C00A1396C /* testrendercopyex */; - productType = "com.apple.product-type.tool"; + productReference = DB166E0516A1D57C00A1396C /* testrendercopyex.app */; + productType = "com.apple.product-type.application"; }; DB166E0A16A1D5AD00A1396C /* testrendertarget */ = { isa = PBXNativeTarget; @@ -2965,6 +2755,7 @@ DB166E0B16A1D5AD00A1396C /* Sources */, DB166E0D16A1D5AD00A1396C /* Frameworks */, DB166E2416A1D61000A1396C /* CopyFiles */, + F3A24A412B389E7200A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -2972,8 +2763,8 @@ ); name = testrendertarget; productName = testalpha; - productReference = DB166E1C16A1D5AD00A1396C /* testrendertarget */; - productType = "com.apple.product-type.tool"; + productReference = DB166E1C16A1D5AD00A1396C /* testrendertarget.app */; + productType = "com.apple.product-type.application"; }; DB166E2716A1D64D00A1396C /* testrumble */ = { isa = PBXNativeTarget; @@ -2981,6 +2772,7 @@ buildPhases = ( DB166E2816A1D64D00A1396C /* Sources */, DB166E2A16A1D64D00A1396C /* Frameworks */, + F3A24A472B389E8700A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -2988,8 +2780,8 @@ ); name = testrumble; productName = testalpha; - productReference = DB166E3816A1D64D00A1396C /* testrumble */; - productType = "com.apple.product-type.tool"; + productReference = DB166E3816A1D64D00A1396C /* testrumble.app */; + productType = "com.apple.product-type.application"; }; DB166E3D16A1D69000A1396C /* testscale */ = { isa = PBXNativeTarget; @@ -2998,6 +2790,7 @@ DB166E3E16A1D69000A1396C /* Sources */, DB166E4016A1D69000A1396C /* Frameworks */, DB166E4C16A1D69000A1396C /* CopyFiles */, + F3A24A4A2B389E9100A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -3005,8 +2798,8 @@ ); name = testscale; productName = testalpha; - productReference = DB166E5216A1D69000A1396C /* testscale */; - productType = "com.apple.product-type.tool"; + productReference = DB166E5216A1D69000A1396C /* testscale.app */; + productType = "com.apple.product-type.application"; }; DB166E5716A1D6F300A1396C /* testshader */ = { isa = PBXNativeTarget; @@ -3014,6 +2807,7 @@ buildPhases = ( DB166E5816A1D6F300A1396C /* Sources */, DB166E5A16A1D6F300A1396C /* Frameworks */, + F3A24A502B389EA600A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -3021,8 +2815,8 @@ ); name = testshader; productName = testsem; - productReference = DB166E6816A1D6F300A1396C /* testshader */; - productType = "com.apple.product-type.tool"; + productReference = DB166E6816A1D6F300A1396C /* testshader.app */; + productType = "com.apple.product-type.application"; }; DB166E6D16A1D78400A1396C /* testspriteminimal */ = { isa = PBXNativeTarget; @@ -3031,6 +2825,7 @@ DB166E6E16A1D78400A1396C /* Sources */, DB166E7016A1D78400A1396C /* Frameworks */, DB166E9B16A1D7FC00A1396C /* CopyFiles */, + F3A24A562B389EC200A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -3038,8 +2833,8 @@ ); name = testspriteminimal; productName = testspriteminimal; - productReference = DB166E7E16A1D78400A1396C /* testspriteminimal */; - productType = "com.apple.product-type.tool"; + productReference = DB166E7E16A1D78400A1396C /* testspriteminimal.app */; + productType = "com.apple.product-type.application"; }; DB166E8016A1D78C00A1396C /* teststreaming */ = { isa = PBXNativeTarget; @@ -3048,6 +2843,7 @@ DB166E8116A1D78C00A1396C /* Sources */, DB166E8316A1D78C00A1396C /* Frameworks */, DB166E9916A1D7EE00A1396C /* CopyFiles */, + F3A24A592B389ECD00A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -3055,8 +2851,8 @@ ); name = teststreaming; productName = teststreaming; - productReference = DB166E9116A1D78C00A1396C /* teststreaming */; - productType = "com.apple.product-type.tool"; + productReference = DB166E9116A1D78C00A1396C /* teststreaming.app */; + productType = "com.apple.product-type.application"; }; DB445EE618184B7000B306B0 /* testdropfile */ = { isa = PBXNativeTarget; @@ -3064,6 +2860,7 @@ buildPhases = ( DB445EE718184B7000B306B0 /* Sources */, DB445EE918184B7000B306B0 /* Frameworks */, + F3A249F52B389D3B00A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -3080,6 +2877,7 @@ buildPhases = ( DB89956E18A19ABA0092407C /* Sources */, DB89957018A19ABA0092407C /* Frameworks */, + F3A24A102B389DA800A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -3087,8 +2885,8 @@ ); name = testhotplug; productName = testalpha; - productReference = DB89957E18A19ABA0092407C /* testhotplug */; - productType = "com.apple.product-type.tool"; + productReference = DB89957E18A19ABA0092407C /* testhotplug.app */; + productType = "com.apple.product-type.application"; }; DBEC54D91A1A81C3005B1EAB /* controllermap */ = { isa = PBXNativeTarget; @@ -3097,6 +2895,7 @@ DBEC54DA1A1A81C3005B1EAB /* Sources */, DBEC54DC1A1A81C3005B1EAB /* Frameworks */, DBEC54EC1A1A827C005B1EAB /* CopyFiles */, + F3A249E32B389CDB00A5162D /* Embed Frameworks */, ); buildRules = ( ); @@ -3104,8 +2903,25 @@ ); name = controllermap; productName = checkkeys; - productReference = DBEC54EA1A1A81C3005B1EAB /* controllermap */; - productType = "com.apple.product-type.tool"; + productReference = DBEC54EA1A1A81C3005B1EAB /* controllermap.app */; + productType = "com.apple.product-type.application"; + }; + F3C17CDB28E416CF00E1A26D /* testgeometry */ = { + isa = PBXNativeTarget; + buildConfigurationList = F3C17CE828E416D000E1A26D /* Build configuration list for PBXNativeTarget "testgeometry" */; + buildPhases = ( + F3C17CD828E416CF00E1A26D /* Sources */, + F3C17CD928E416CF00E1A26D /* Frameworks */, + F3A24A042B389D6F00A5162D /* Embed Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = testgeometry; + productName = testgeometry; + productReference = F3C17CDC28E416CF00E1A26D /* testgeometry.app */; + productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ @@ -3113,7 +2929,158 @@ 08FB7793FE84155DC02AAC07 /* Project object */ = { isa = PBXProject; attributes = { + LastSwiftUpdateCheck = 1400; LastUpgradeCheck = 0420; + TargetAttributes = { + 0017957410741F7900F5D044 = { + DevelopmentTeam = EH385AYQ6F; + }; + 00179595107421BF00F5D044 = { + DevelopmentTeam = EH385AYQ6F; + }; + 0017970910742F3200F5D044 = { + DevelopmentTeam = EH385AYQ6F; + }; + 00179730107430D600F5D044 = { + DevelopmentTeam = EH385AYQ6F; + }; + 00179756107431B300F5D044 = { + DevelopmentTeam = EH385AYQ6F; + }; + 00179776107432AE00F5D044 = { + DevelopmentTeam = EH385AYQ6F; + }; + 001797961074334C00F5D044 = { + DevelopmentTeam = EH385AYQ6F; + }; + 001797B8107433C600F5D044 = { + DevelopmentTeam = EH385AYQ6F; + }; + 001797FA1074355200F5D044 = { + DevelopmentTeam = EH385AYQ6F; + }; + 001798781074392D00F5D044 = { + DevelopmentTeam = EH385AYQ6F; + }; + 0017989D107439DF00F5D044 = { + DevelopmentTeam = EH385AYQ6F; + }; + 001798DA10743BEC00F5D044 = { + DevelopmentTeam = EH385AYQ6F; + }; + 001798FE10743F1000F5D044 = { + DevelopmentTeam = EH385AYQ6F; + }; + 0017992010743FB700F5D044 = { + DevelopmentTeam = EH385AYQ6F; + }; + 002F340109CA1BFF00EBEB88 = { + DevelopmentTeam = EH385AYQ6F; + }; + 002F342009CA1F0300EBEB88 = { + DevelopmentTeam = EH385AYQ6F; + }; + 002F343C09CA1FB300EBEB88 = { + DevelopmentTeam = EH385AYQ6F; + }; + 002F345909CA204F00EBEB88 = { + DevelopmentTeam = EH385AYQ6F; + }; + 4537749112091504002F0F45 = { + DevelopmentTeam = EH385AYQ6F; + }; + BBFC08B7164C6862003E6A99 = { + DevelopmentTeam = EH385AYQ6F; + }; + BEC566920761D90300A33029 = { + DevelopmentTeam = EH385AYQ6F; + }; + BEC566AB0761D90300A33029 = { + DevelopmentTeam = EH385AYQ6F; + }; + BEC566C50761D90300A33029 = { + DevelopmentTeam = EH385AYQ6F; + }; + BEC566FB0761D90300A33029 = { + DevelopmentTeam = EH385AYQ6F; + }; + BEC567230761D90400A33029 = { + DevelopmentTeam = EH385AYQ6F; + }; + BEC567300761D90400A33029 = { + DevelopmentTeam = EH385AYQ6F; + }; + BEC5673D0761D90400A33029 = { + DevelopmentTeam = EH385AYQ6F; + }; + BEC5674A0761D90400A33029 = { + DevelopmentTeam = EH385AYQ6F; + }; + BEC567720761D90500A33029 = { + DevelopmentTeam = EH385AYQ6F; + }; + BEC5678D0761D90500A33029 = { + DevelopmentTeam = EH385AYQ6F; + }; + BEC567A70761D90500A33029 = { + DevelopmentTeam = EH385AYQ6F; + }; + BEC567EA0761D90600A33029 = { + DevelopmentTeam = EH385AYQ6F; + }; + DB0F48D917CA51E5008798C5 = { + DevelopmentTeam = EH385AYQ6F; + }; + DB0F48EF17CA5212008798C5 = { + DevelopmentTeam = EH385AYQ6F; + }; + DB166D7E16A1D12400A1396C = { + DevelopmentTeam = EH385AYQ6F; + }; + DB166DAD16A1D2F600A1396C = { + DevelopmentTeam = EH385AYQ6F; + }; + DB166DC416A1D36A00A1396C = { + DevelopmentTeam = EH385AYQ6F; + }; + DB166DDC16A1D50C00A1396C = { + DevelopmentTeam = EH385AYQ6F; + }; + DB166DF316A1D57C00A1396C = { + DevelopmentTeam = EH385AYQ6F; + }; + DB166E0A16A1D5AD00A1396C = { + DevelopmentTeam = EH385AYQ6F; + }; + DB166E2716A1D64D00A1396C = { + DevelopmentTeam = EH385AYQ6F; + }; + DB166E3D16A1D69000A1396C = { + DevelopmentTeam = EH385AYQ6F; + }; + DB166E5716A1D6F300A1396C = { + DevelopmentTeam = EH385AYQ6F; + }; + DB166E6D16A1D78400A1396C = { + DevelopmentTeam = EH385AYQ6F; + }; + DB166E8016A1D78C00A1396C = { + DevelopmentTeam = EH385AYQ6F; + }; + DB445EE618184B7000B306B0 = { + DevelopmentTeam = EH385AYQ6F; + }; + DB89956D18A19ABA0092407C = { + DevelopmentTeam = EH385AYQ6F; + }; + DBEC54D91A1A81C3005B1EAB = { + DevelopmentTeam = EH385AYQ6F; + }; + F3C17CDB28E416CF00E1A26D = { + CreatedOnToolsVersion = 14.0.1; + DevelopmentTeam = EH385AYQ6F; + }; + }; }; buildConfigurationList = 001B5A0C08BDB826006539E9 /* Build configuration list for PBXProject "SDLTest" */; compatibilityVersion = "Xcode 3.2"; @@ -3125,6 +3092,7 @@ French, German, en, + Base, ); mainGroup = 08FB7794FE84155DC02AAC07 /* SDLTest */; projectDirPath = ""; @@ -3150,6 +3118,7 @@ 002F340109CA1BFF00EBEB88 /* testfile */, DB0F48EF17CA5212008798C5 /* testfilesystem */, BBFC08B7164C6862003E6A99 /* testgamecontroller */, + F3C17CDB28E416CF00E1A26D /* testgeometry */, DB166DAD16A1D2F600A1396C /* testgesture */, 0017970910742F3200F5D044 /* testgl2 */, 00179730107430D600F5D044 /* testhaptic */, @@ -3203,10 +3172,10 @@ remoteRef = 003FA644093FFD41000C53B3 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - 003FA649093FFD41000C53B3 /* Standard DMG */ = { + 003FA649093FFD41000C53B3 /* SDL2 */ = { isa = PBXReferenceProxy; fileType = "compiled.mach-o.executable"; - path = "Standard DMG"; + path = SDL2; remoteRef = 003FA648093FFD41000C53B3 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -3217,13 +3186,93 @@ remoteRef = DB1D40D617B3F30D00D74CFC /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; + F3C17C5D28E3FB2900E1A26D /* SDL2.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = SDL2.framework; + remoteRef = F3C17C5C28E3FB2900E1A26D /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + F3C17C5F28E3FB2900E1A26D /* SDL2.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = SDL2.framework; + remoteRef = F3C17C5E28E3FB2900E1A26D /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + F3C17C6128E3FB2900E1A26D /* SDL2.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = SDL2.framework; + remoteRef = F3C17C6028E3FB2900E1A26D /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + F3C17C6328E3FB2900E1A26D /* libSDL2.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libSDL2.a; + remoteRef = F3C17C6228E3FB2900E1A26D /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + F3C17C6528E3FB2900E1A26D /* libSDL2.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libSDL2.a; + remoteRef = F3C17C6428E3FB2900E1A26D /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + F3C17C6728E3FB2900E1A26D /* libSDL2.dylib */ = { + isa = PBXReferenceProxy; + fileType = "compiled.mach-o.dylib"; + path = libSDL2.dylib; + remoteRef = F3C17C6628E3FB2900E1A26D /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + F3C17C6928E3FB2900E1A26D /* libSDL2.dylib */ = { + isa = PBXReferenceProxy; + fileType = "compiled.mach-o.dylib"; + path = libSDL2.dylib; + remoteRef = F3C17C6828E3FB2900E1A26D /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; /* End PBXReferenceProxy section */ +/* Begin PBXResourcesBuildPhase section */ + F3C17D3528E4242100E1A26D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F3C17D3C28E4277D00E1A26D /* axis.bmp in Resources */, + F3C17D3D28E4277D00E1A26D /* button.bmp in Resources */, + F3C17D3E28E4277D00E1A26D /* controllermap_back.bmp in Resources */, + F3C17D3F28E4277D00E1A26D /* controllermap.bmp in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F3C17D3828E424B100E1A26D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F3C17D3928E424B800E1A26D /* sample.wav in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F3C17D3A28E4252200E1A26D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F3C17D3B28E4252900E1A26D /* icon.bmp in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + /* Begin PBXSourcesBuildPhase section */ 0017957910741F7900F5D044 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17CFF28E41EB000E1A26D /* SDL_uikit_main.c in Sources */, 001795901074216E00F5D044 /* testatomic.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3232,6 +3281,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17D0028E41EB400E1A26D /* SDL_uikit_main.c in Sources */, 001795B11074222D00F5D044 /* testaudioinfo.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3240,6 +3290,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17D0928E41EE100E1A26D /* SDL_uikit_main.c in Sources */, 0017972810742FB900F5D044 /* testgl2.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3248,6 +3299,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17D0A28E41EE700E1A26D /* SDL_uikit_main.c in Sources */, 0017974F1074315700F5D044 /* testhaptic.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3256,6 +3308,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17D0128E41EB800E1A26D /* SDL_uikit_main.c in Sources */, 001797721074320D00F5D044 /* testdraw2.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3264,7 +3317,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17D0D28E41EF400E1A26D /* SDL_uikit_main.c in Sources */, 00179792107432FA00F5D044 /* testime.c in Sources */, + F3C17C7C28E40D7400E1A26D /* testutils.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3272,6 +3327,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17D0E28E41EF900E1A26D /* SDL_uikit_main.c in Sources */, 001797B41074339C00F5D044 /* testintersections.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3280,6 +3336,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17D1128E41F0600E1A26D /* SDL_uikit_main.c in Sources */, 001797D41074343E00F5D044 /* testloadso.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3288,7 +3345,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17D1428E41F1100E1A26D /* SDL_uikit_main.c in Sources */, 001798161074359B00F5D044 /* testmultiaudio.c in Sources */, + F3C17C7D28E40F9D00E1A26D /* testutils.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3298,7 +3357,7 @@ files = ( 0017987F1074392D00F5D044 /* testnative.c in Sources */, 001798801074392D00F5D044 /* testnativecocoa.m in Sources */, - 001798811074392D00F5D044 /* testnativex11.c in Sources */, + F3C17C7E28E40FDD00E1A26D /* testutils.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3306,6 +3365,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17D1728E41F2800E1A26D /* SDL_uikit_main.c in Sources */, 001798BA10743A4900F5D044 /* testpower.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3314,6 +3374,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17D1B28E41F3800E1A26D /* SDL_uikit_main.c in Sources */, 001798FA10743E9200F5D044 /* testresample.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3322,7 +3383,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17CEF28E41D5800E1A26D /* SDL_uikit_main.c in Sources */, 0017991A10743F5300F5D044 /* testsprite2.c in Sources */, + F3C17C8328E4124400E1A26D /* testutils.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3330,6 +3393,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17D2728E41FD800E1A26D /* SDL_uikit_main.c in Sources */, 0017993C10743FEF00F5D044 /* testwm2.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3338,6 +3402,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17D0528E41ECB00E1A26D /* SDL_uikit_main.c in Sources */, 002F341809CA1C5B00EBEB88 /* testfile.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3346,7 +3411,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17D0C28E41EF000E1A26D /* SDL_uikit_main.c in Sources */, 002F343709CA1F6F00EBEB88 /* testiconv.c in Sources */, + F3C17C7B28E40D4E00E1A26D /* testutils.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3354,8 +3421,10 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17D1528E41F1F00E1A26D /* SDL_uikit_main.c in Sources */, 002F345409CA202000EBEB88 /* testoverlay2.c in Sources */, 66E88E8B203B778F0004D44E /* testyuv_cvt.c in Sources */, + F3C17C7F28E4101000E1A26D /* testutils.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3363,6 +3432,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17D1628E41F2400E1A26D /* SDL_uikit_main.c in Sources */, 002F347009CA20A600EBEB88 /* testplatform.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3371,6 +3441,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17D2028E41F4D00E1A26D /* SDL_uikit_main.c in Sources */, 453774A5120915E3002F0F45 /* testshape.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3379,7 +3450,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17D0728E41ED300E1A26D /* SDL_uikit_main.c in Sources */, BBFC08D0164C6876003E6A99 /* testgamecontroller.c in Sources */, + F3C17C7928E40C6E00E1A26D /* testutils.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3387,6 +3460,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17CFC28E41E9800E1A26D /* SDL_uikit_main.c in Sources */, BEC566B10761D90300A33029 /* checkkeys.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3395,7 +3469,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17CFE28E41EAC00E1A26D /* SDL_uikit_main.c in Sources */, BEC566CB0761D90300A33029 /* loopwave.c in Sources */, + F3C17C7728E40BC800E1A26D /* testutils.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3403,6 +3479,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17D0428E41EC800E1A26D /* SDL_uikit_main.c in Sources */, BEC567010761D90300A33029 /* testerror.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3411,6 +3488,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17D2428E41F6600E1A26D /* SDL_uikit_main.c in Sources */, BEC567290761D90400A33029 /* testthread.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3419,6 +3497,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17D0F28E41EFE00E1A26D /* SDL_uikit_main.c in Sources */, BEC567360761D90400A33029 /* testjoystick.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3427,6 +3506,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17D1028E41F0200E1A26D /* SDL_uikit_main.c in Sources */, BEC567430761D90400A33029 /* testkeys.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3435,6 +3515,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17D1228E41F0A00E1A26D /* SDL_uikit_main.c in Sources */, BEC567500761D90400A33029 /* testlock.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3443,6 +3524,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17D1E28E41F4500E1A26D /* SDL_uikit_main.c in Sources */, BEC567780761D90500A33029 /* testsem.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3451,6 +3533,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17D2528E41F6A00E1A26D /* SDL_uikit_main.c in Sources */, BEC567930761D90500A33029 /* testtimer.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3459,6 +3542,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17D2628E41F6E00E1A26D /* SDL_uikit_main.c in Sources */, BEC567AD0761D90500A33029 /* testver.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3467,6 +3551,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17D2828E41FDC00E1A26D /* SDL_uikit_main.c in Sources */, BEC567F00761D90600A33029 /* torturethread.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3475,6 +3560,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17D0228E41EBC00E1A26D /* SDL_uikit_main.c in Sources */, DB0F48EE17CA51F8008798C5 /* testdrawchessboard.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3483,6 +3569,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17D0628E41ECF00E1A26D /* SDL_uikit_main.c in Sources */, DB0F490317CA5225008798C5 /* testfilesystem.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3514,6 +3601,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17D0828E41EDB00E1A26D /* SDL_uikit_main.c in Sources */, DB166DC116A1D31E00A1396C /* testgesture.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3522,6 +3610,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17D1328E41F0D00E1A26D /* SDL_uikit_main.c in Sources */, DB166DD716A1D37800A1396C /* testmessage.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3530,6 +3619,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17D1828E41F2C00E1A26D /* SDL_uikit_main.c in Sources */, DB166DF016A1D52500A1396C /* testrelative.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3538,7 +3628,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17D1928E41F3100E1A26D /* SDL_uikit_main.c in Sources */, DB166E0716A1D59400A1396C /* testrendercopyex.c in Sources */, + F3C17C8028E410A400E1A26D /* testutils.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3546,7 +3638,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17D1A28E41F3500E1A26D /* SDL_uikit_main.c in Sources */, DB166E1E16A1D5C300A1396C /* testrendertarget.c in Sources */, + F3C17C8128E410C900E1A26D /* testutils.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3554,6 +3648,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17D1C28E41F3C00E1A26D /* SDL_uikit_main.c in Sources */, DB166E3C16A1D66500A1396C /* testrumble.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3562,7 +3657,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17D1D28E41F4000E1A26D /* SDL_uikit_main.c in Sources */, DB166E5416A1D6A300A1396C /* testscale.c in Sources */, + F3C17C8228E4112900E1A26D /* testutils.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3570,6 +3667,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17D1F28E41F4800E1A26D /* SDL_uikit_main.c in Sources */, DB166E6A16A1D70C00A1396C /* testshader.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3578,7 +3676,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17D2228E41F5F00E1A26D /* SDL_uikit_main.c in Sources */, DB166E9316A1D7BC00A1396C /* testspriteminimal.c in Sources */, + F3C17C8428E4126400E1A26D /* testutils.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3586,7 +3686,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17D2328E41F6200E1A26D /* SDL_uikit_main.c in Sources */, DB166E9416A1D7C700A1396C /* teststreaming.c in Sources */, + F3C17C8528E4127D00E1A26D /* testutils.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3594,6 +3696,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17D0328E41EC500E1A26D /* SDL_uikit_main.c in Sources */, DB445EFB18184BB600B306B0 /* testdropfile.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3602,6 +3705,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17D0B28E41EEB00E1A26D /* SDL_uikit_main.c in Sources */, DB89958418A19B130092407C /* testhotplug.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -3610,7 +3714,19 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + F3C17CFD28E41EA100E1A26D /* SDL_uikit_main.c in Sources */, DBEC54EB1A1A8205005B1EAB /* controllermap.c in Sources */, + F3C17C7428E40AF000E1A26D /* testutils.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F3C17CD828E416CF00E1A26D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F3C17CEE28E4184700E1A26D /* SDL_uikit_main.c in Sources */, + F3C17CEB28E4177600E1A26D /* testgeometry.c in Sources */, + F3C17CEC28E417EB00E1A26D /* testutils.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3868,6 +3984,7 @@ buildSettings = { GCC_PREPROCESSOR_DEFINITIONS = HAVE_OPENGL; PRODUCT_NAME = testgl2; + SUPPORTED_PLATFORMS = macosx; }; name = Debug; }; @@ -3876,6 +3993,7 @@ buildSettings = { GCC_PREPROCESSOR_DEFINITIONS = HAVE_OPENGL; PRODUCT_NAME = testgl2; + SUPPORTED_PLATFORMS = macosx; }; name = Release; }; @@ -3966,18 +4084,16 @@ 001798911074392D00F5D044 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - LIBRARY_SEARCH_PATHS = /usr/X11/lib; - OTHER_LDFLAGS = "-lX11"; PRODUCT_NAME = testnative; + SUPPORTED_PLATFORMS = macosx; }; name = Debug; }; 001798921074392D00F5D044 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - LIBRARY_SEARCH_PATHS = /usr/X11/lib; - OTHER_LDFLAGS = "-lX11"; PRODUCT_NAME = testnative; + SUPPORTED_PLATFORMS = macosx; }; name = Release; }; @@ -4039,16 +4155,29 @@ }; 002A85B21073008E007319AE /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = F3C17C6A28E3FD4400E1A26D /* config.xcconfig */; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(SRCROOT)/../SDL/build/$(CONFIGURATION)", - "$(HOME)/Library/Frameworks", - /Library/Frameworks, - ); + ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; GCC_OPTIMIZATION_LEVEL = 0; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + GENERATE_INFOPLIST_FILE = YES; HEADER_SEARCH_PATHS = ../../include; - MACOSX_DEPLOYMENT_TARGET = 10.6; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks"; + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.9; + MARKETING_VERSION = 1.0; + ONLY_ACTIVE_ARCH = YES; + OTHER_LDFLAGS = "$(CONFIG_FRAMEWORK_LDFLAGS)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.libsdl.$(PRODUCT_NAME)"; + SUPPORTED_PLATFORMS = "macosx iphonesimulator iphoneos appletvsimulator appletvos"; + SUPPORTS_MACCATALYST = YES; + TVOS_DEPLOYMENT_TARGET = 9.0; }; name = Debug; }; @@ -4118,6 +4247,8 @@ 002A85C51073008E007319AE /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + INFOPLIST_FILE = "testoverlay2-Info.plist"; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; PRODUCT_NAME = testoverlay2; }; name = Debug; @@ -4166,16 +4297,26 @@ }; 002A85D41073009D007319AE /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = F3C17C6A28E3FD4400E1A26D /* config.xcconfig */; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(SRCROOT)/../SDL/build/$(CONFIGURATION)", - "$(HOME)/Library/Frameworks", - /Library/Frameworks, - ); - GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEPLOYMENT_POSTPROCESSING = YES; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + GENERATE_INFOPLIST_FILE = YES; HEADER_SEARCH_PATHS = ../../include; - MACOSX_DEPLOYMENT_TARGET = 10.6; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks"; + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.9; + MARKETING_VERSION = 1.0; + OTHER_LDFLAGS = "$(CONFIG_FRAMEWORK_LDFLAGS)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.libsdl.$(PRODUCT_NAME)"; + SUPPORTED_PLATFORMS = "macosx iphonesimulator iphoneos appletvsimulator appletvos"; + SUPPORTS_MACCATALYST = YES; + TVOS_DEPLOYMENT_TARGET = 9.0; }; name = Release; }; @@ -4245,6 +4386,8 @@ 002A85E71073009D007319AE /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + INFOPLIST_FILE = "testoverlay2-Info.plist"; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; PRODUCT_NAME = testoverlay2; }; name = Release; @@ -4350,16 +4493,22 @@ DB166D8116A1D12400A1396C /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES; EXECUTABLE_PREFIX = lib; PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "watchsimulator watchos macosx iphonesimulator iphoneos driverkit appletvsimulator appletvos"; + SUPPORTS_MACCATALYST = YES; }; name = Debug; }; DB166D8216A1D12400A1396C /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES; EXECUTABLE_PREFIX = lib; PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "watchsimulator watchos macosx iphonesimulator iphoneos driverkit appletvsimulator appletvos"; + SUPPORTS_MACCATALYST = YES; }; name = Release; }; @@ -4547,6 +4696,20 @@ }; name = Release; }; + F3C17CE928E416D000E1A26D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + F3C17CEA28E416D000E1A26D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -4991,6 +5154,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Debug; }; + F3C17CE828E416D000E1A26D /* Build configuration list for PBXNativeTarget "testgeometry" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F3C17CE928E416D000E1A26D /* Debug */, + F3C17CEA28E416D000E1A26D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Debug; + }; /* End XCConfigurationList section */ }; rootObject = 08FB7793FE84155DC02AAC07 /* Project object */; diff --git a/SDL2-2.0.12/Xcode/SDLTest/TestDropFile-Info.plist b/SDL2-2.30.5/Xcode/SDLTest/TestDropFile-Info.plist similarity index 97% rename from SDL2-2.0.12/Xcode/SDLTest/TestDropFile-Info.plist rename to SDL2-2.30.5/Xcode/SDLTest/TestDropFile-Info.plist index 03e46b3..c9f6cb8 100644 --- a/SDL2-2.0.12/Xcode/SDLTest/TestDropFile-Info.plist +++ b/SDL2-2.30.5/Xcode/SDLTest/TestDropFile-Info.plist @@ -30,6 +30,6 @@ CFBundleVersion 1.0 LSMinimumSystemVersion - 10.6 + 10.7 diff --git a/SDL2-2.30.5/Xcode/SDLTest/config.xcconfig b/SDL2-2.30.5/Xcode/SDLTest/config.xcconfig new file mode 100644 index 0000000..a73eec4 --- /dev/null +++ b/SDL2-2.30.5/Xcode/SDLTest/config.xcconfig @@ -0,0 +1,14 @@ +// +// config.xcconfig +// SDL tests +// + +// Configuration settings file format documentation can be found at: +// https://help.apple.com/xcode/#/dev745c5c974 + +// Include any optional config for this build +#include? "build.xcconfig" + +CONFIG_FRAMEWORK_LDFLAGS[sdk=macos*] = $(inherited) -framework SDL2 -framework AudioToolbox -framework Carbon -framework Cocoa -framework CoreAudio -framework CoreHaptics -framework CoreVideo -framework ForceFeedback -framework GameController -framework IOKit -framework Metal +CONFIG_FRAMEWORK_LDFLAGS[sdk=iphone*] = $(inherited) -framework SDL2 -framework AVFoundation -framework AudioToolbox -framework CoreGraphics -framework CoreHaptics -framework CoreMotion -framework Foundation -framework GameController -framework Metal -framework OpenGLES -framework QuartzCore -framework UIKit +CONFIG_FRAMEWORK_LDFLAGS[sdk=appletv*] = $(inherited) -framework SDL2 -framework AVFoundation -framework AudioToolbox -framework CoreGraphics -framework CoreHaptics -framework Foundation -framework GameController -framework Metal -framework OpenGLES -framework QuartzCore -framework UIKit diff --git a/SDL2-2.0.12/Xcode/XcodeDocSet/Doxyfile b/SDL2-2.30.5/Xcode/XcodeDocSet/Doxyfile similarity index 100% rename from SDL2-2.0.12/Xcode/XcodeDocSet/Doxyfile rename to SDL2-2.30.5/Xcode/XcodeDocSet/Doxyfile diff --git a/SDL2-2.0.12/acinclude/ac_check_define.m4 b/SDL2-2.30.5/acinclude/ac_check_define.m4 similarity index 77% rename from SDL2-2.0.12/acinclude/ac_check_define.m4 rename to SDL2-2.30.5/acinclude/ac_check_define.m4 index 64de801..d0e4c0c 100644 --- a/SDL2-2.0.12/acinclude/ac_check_define.m4 +++ b/SDL2-2.30.5/acinclude/ac_check_define.m4 @@ -1,4 +1,4 @@ -AC_DEFUN([AC_CHECK_DEFINE],[dnl +AC_DEFUN([AC_CHECK_DEFINE],[AC_REQUIRE([AC_PROG_CPP])dnl AC_CACHE_CHECK(for $1 in $2, ac_cv_define_$1, AC_EGREP_CPP([YES_IS_DEFINED], [ #include <$2> @@ -11,4 +11,4 @@ YES_IS_DEFINED AC_DEFINE([HAVE_$1],[],[Added by AC_CHECK_DEFINE]) fi ])dnl -AC_DEFINE([HAVE_$1],[],[Added by AC_CHECK_DEFINE]) + diff --git a/SDL2-2.0.12/acinclude/alsa.m4 b/SDL2-2.30.5/acinclude/alsa.m4 similarity index 94% rename from SDL2-2.0.12/acinclude/alsa.m4 rename to SDL2-2.30.5/acinclude/alsa.m4 index d818e70..1a276a2 100644 --- a/SDL2-2.0.12/acinclude/alsa.m4 +++ b/SDL2-2.30.5/acinclude/alsa.m4 @@ -1,4 +1,3 @@ -############################################################################## dnl Configure Paths for Alsa dnl Some modifications by Richard Boulton dnl Christopher Lansdown @@ -7,12 +6,13 @@ dnl Last modification: alsa.m4,v 1.23 2004/01/16 18:14:22 tiwai Exp dnl AM_PATH_ALSA([MINIMUM-VERSION [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) dnl Test for libasound, and define ALSA_CFLAGS and ALSA_LIBS as appropriate. dnl enables arguments --with-alsa-prefix= -dnl --with-alsa-enc-prefix= +dnl --with-alsa-inc-prefix= dnl --disable-alsatest dnl dnl For backwards compatibility, if ACTION_IF_NOT_FOUND is not specified, dnl and the alsa libraries are not found, a fatal AC_MSG_ERROR() will result. dnl + AC_DEFUN([AM_PATH_ALSA], [dnl Save the original CFLAGS, LDFLAGS, and LIBS alsa_save_CFLAGS="$CFLAGS" @@ -62,7 +62,7 @@ LIBS="$ALSA_LIBS $LIBS" AC_MSG_RESULT($ALSA_LIBS) dnl Check for a working version of libasound that is of the right version. -min_alsa_version=ifelse([$1], ,0.1.1,$1) +min_alsa_version=ifelse([$1], ,0.1.1, $1) AC_MSG_CHECKING(for libasound headers version >= $min_alsa_version) no_alsa="" alsa_min_major_version=`echo $min_alsa_version | \ @@ -72,11 +72,10 @@ no_alsa="" alsa_min_micro_version=`echo $min_alsa_version | \ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` -AC_LANG_SAVE -AC_LANG_C -AC_TRY_COMPILE([ +AC_LANG_PUSH([C]) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include -], [ +]], [[ /* ensure backward compatibility */ #if !defined(SND_LIB_MAJOR) && defined(SOUNDLIB_VERSION_MAJOR) #define SND_LIB_MAJOR SOUNDLIB_VERSION_MAJOR @@ -108,13 +107,13 @@ AC_TRY_COMPILE([ # endif # endif exit(0); -], +]])], [AC_MSG_RESULT(found.)], [AC_MSG_RESULT(not present.) ifelse([$3], , [AC_MSG_ERROR(Sufficiently new version of libasound not found.)]) alsa_found=no] ) -AC_LANG_RESTORE +AC_LANG_POP([C]) dnl Now that we know that we have the right version, let's see if we have the library and not just the headers. if test "x$enable_alsatest" = "xyes"; then diff --git a/SDL2-2.0.12/acinclude/ax_check_compiler_flags.m4 b/SDL2-2.30.5/acinclude/ax_check_compiler_flags.m4 similarity index 100% rename from SDL2-2.0.12/acinclude/ax_check_compiler_flags.m4 rename to SDL2-2.30.5/acinclude/ax_check_compiler_flags.m4 diff --git a/SDL2-2.30.5/acinclude/ax_compute_relative_paths.m4 b/SDL2-2.30.5/acinclude/ax_compute_relative_paths.m4 new file mode 100644 index 0000000..1024707 --- /dev/null +++ b/SDL2-2.30.5/acinclude/ax_compute_relative_paths.m4 @@ -0,0 +1,173 @@ +# ============================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_compute_relative_paths.html +# ============================================================================== +# +# SYNOPSIS +# +# AX_COMPUTE_RELATIVE_PATHS(PATH_LIST) +# +# DESCRIPTION +# +# PATH_LIST is a space-separated list of colon-separated triplets of the +# form 'FROM:TO:RESULT'. This function iterates over these triplets and +# set $RESULT to the relative path from $FROM to $TO. Note that $FROM and +# $TO needs to be absolute filenames for this macro to success. +# +# For instance, +# +# first=/usr/local/bin +# second=/usr/local/share +# AX_COMPUTE_RELATIVE_PATHS([first:second:fs second:first:sf]) +# # $fs is set to ../share +# # $sf is set to ../bin +# +# $FROM and $TO are both eval'ed recursively and normalized, this means +# that you can call this macro with autoconf's dirnames like `prefix' or +# `datadir'. For example: +# +# AX_COMPUTE_RELATIVE_PATHS([bindir:datadir:bin_to_data]) +# +# AX_COMPUTE_RELATIVE_PATHS should also works with DOS filenames. +# +# You may want to use this macro in order to make your package +# relocatable. Instead of hardcoding $datadir into your programs just +# encode $bin_to_data and try to determine $bindir at run-time. +# +# This macro requires AX_NORMALIZE_PATH and AX_RECURSIVE_EVAL. +# +# LICENSE +# +# Copyright (c) 2008 Alexandre Duret-Lutz +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 12 + +AU_ALIAS([ADL_COMPUTE_RELATIVE_PATHS], [AX_COMPUTE_RELATIVE_PATHS]) +AC_DEFUN([AX_COMPUTE_RELATIVE_PATHS], +[for _lcl_i in $1; do + _lcl_from=\[$]`echo "[$]_lcl_i" | sed 's,:.*$,,'` + _lcl_to=\[$]`echo "[$]_lcl_i" | sed 's,^[[^:]]*:,,' | sed 's,:[[^:]]*$,,'` + _lcl_result_var=`echo "[$]_lcl_i" | sed 's,^.*:,,'` + AX_RECURSIVE_EVAL([[$]_lcl_from], [_lcl_from]) + AX_RECURSIVE_EVAL([[$]_lcl_to], [_lcl_to]) + _lcl_notation="$_lcl_from$_lcl_to" + AX_NORMALIZE_PATH([_lcl_from],['/']) + AX_NORMALIZE_PATH([_lcl_to],['/']) + AX_COMPUTE_RELATIVE_PATH([_lcl_from], [_lcl_to], [_lcl_result_tmp]) + AX_NORMALIZE_PATH([_lcl_result_tmp],["[$]_lcl_notation"]) + eval $_lcl_result_var='[$]_lcl_result_tmp' +done]) + +## Note: +## ***** +## The following helper macros are too fragile to be used out +## of AX_COMPUTE_RELATIVE_PATHS (mainly because they assume that +## paths are normalized), that's why I'm keeping them in the same file. +## Still, some of them maybe worth to reuse. + +dnl AX_COMPUTE_RELATIVE_PATH(FROM, TO, RESULT) +dnl =========================================== +dnl Compute the relative path to go from $FROM to $TO and set the value +dnl of $RESULT to that value. This function work on raw filenames +dnl (for instead it will considerate /usr//local and /usr/local as +dnl two distinct paths), you should really use AX_COMPUTE_RELATIVE_PATHS +dnl instead to have the paths sanitized automatically. +dnl +dnl For instance: +dnl first_dir=/somewhere/on/my/disk/bin +dnl second_dir=/somewhere/on/another/disk/share +dnl AX_COMPUTE_RELATIVE_PATH(first_dir, second_dir, first_to_second) +dnl will set $first_to_second to '../../../another/disk/share'. +AC_DEFUN([AX_COMPUTE_RELATIVE_PATH], +[AX_COMPUTE_COMMON_PATH([$1], [$2], [_lcl_common_prefix]) +AX_COMPUTE_BACK_PATH([$1], [_lcl_common_prefix], [_lcl_first_rel]) +AX_COMPUTE_SUFFIX_PATH([$2], [_lcl_common_prefix], [_lcl_second_suffix]) +$3="[$]_lcl_first_rel[$]_lcl_second_suffix"]) + +dnl AX_COMPUTE_COMMON_PATH(LEFT, RIGHT, RESULT) +dnl ============================================ +dnl Compute the common path to $LEFT and $RIGHT and set the result to $RESULT. +dnl +dnl For instance: +dnl first_path=/somewhere/on/my/disk/bin +dnl second_path=/somewhere/on/another/disk/share +dnl AX_COMPUTE_COMMON_PATH(first_path, second_path, common_path) +dnl will set $common_path to '/somewhere/on'. +AC_DEFUN([AX_COMPUTE_COMMON_PATH], +[$3='' +_lcl_second_prefix_match='' +while test "[$]_lcl_second_prefix_match" != 0; do + _lcl_first_prefix=`expr "x[$]$1" : "x\([$]$3/*[[^/]]*\)"` + _lcl_second_prefix_match=`expr "x[$]$2" : "x[$]_lcl_first_prefix"` + if test "[$]_lcl_second_prefix_match" != 0; then + if test "[$]_lcl_first_prefix" != "[$]$3"; then + $3="[$]_lcl_first_prefix" + else + _lcl_second_prefix_match=0 + fi + fi +done]) + +dnl AX_COMPUTE_SUFFIX_PATH(PATH, SUBPATH, RESULT) +dnl ============================================== +dnl Subtract $SUBPATH from $PATH, and set the resulting suffix +dnl (or the empty string if $SUBPATH is not a subpath of $PATH) +dnl to $RESULT. +dnl +dnl For instance: +dnl first_path=/somewhere/on/my/disk/bin +dnl second_path=/somewhere/on +dnl AX_COMPUTE_SUFFIX_PATH(first_path, second_path, common_path) +dnl will set $common_path to '/my/disk/bin'. +AC_DEFUN([AX_COMPUTE_SUFFIX_PATH], +[$3=`expr "x[$]$1" : "x[$]$2/*\(.*\)"`]) + +dnl AX_COMPUTE_BACK_PATH(PATH, SUBPATH, RESULT) +dnl ============================================ +dnl Compute the relative path to go from $PATH to $SUBPATH, knowing that +dnl $SUBPATH is a subpath of $PATH (any other words, only repeated '../' +dnl should be needed to move from $PATH to $SUBPATH) and set the value +dnl of $RESULT to that value. If $SUBPATH is not a subpath of PATH, +dnl set $RESULT to the empty string. +dnl +dnl For instance: +dnl first_path=/somewhere/on/my/disk/bin +dnl second_path=/somewhere/on +dnl AX_COMPUTE_BACK_PATH(first_path, second_path, back_path) +dnl will set $back_path to '../../../'. +AC_DEFUN([AX_COMPUTE_BACK_PATH], +[AX_COMPUTE_SUFFIX_PATH([$1], [$2], [_lcl_first_suffix]) +$3='' +_lcl_tmp='xxx' +while test "[$]_lcl_tmp" != ''; do + _lcl_tmp=`expr "x[$]_lcl_first_suffix" : "x[[^/]]*/*\(.*\)"` + if test "[$]_lcl_first_suffix" != ''; then + _lcl_first_suffix="[$]_lcl_tmp" + $3="../[$]$3" + fi +done]) diff --git a/SDL2-2.0.12/acinclude/ax_gcc_archflag.m4 b/SDL2-2.30.5/acinclude/ax_gcc_archflag.m4 similarity index 100% rename from SDL2-2.0.12/acinclude/ax_gcc_archflag.m4 rename to SDL2-2.30.5/acinclude/ax_gcc_archflag.m4 diff --git a/SDL2-2.0.12/acinclude/ax_gcc_x86_cpuid.m4 b/SDL2-2.30.5/acinclude/ax_gcc_x86_cpuid.m4 similarity index 100% rename from SDL2-2.0.12/acinclude/ax_gcc_x86_cpuid.m4 rename to SDL2-2.30.5/acinclude/ax_gcc_x86_cpuid.m4 diff --git a/SDL2-2.30.5/acinclude/ax_normalize_path.m4 b/SDL2-2.30.5/acinclude/ax_normalize_path.m4 new file mode 100644 index 0000000..b789a93 --- /dev/null +++ b/SDL2-2.30.5/acinclude/ax_normalize_path.m4 @@ -0,0 +1,115 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_normalize_path.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_NORMALIZE_PATH(VARNAME, [REFERENCE_STRING]) +# +# DESCRIPTION +# +# Perform some cleanups on the value of $VARNAME (interpreted as a path): +# +# - empty paths are changed to '.' +# - trailing slashes are removed +# - repeated slashes are squeezed except a leading doubled slash '//' +# (which might indicate a networked disk on some OS). +# +# REFERENCE_STRING is used to turn '/' into '\' and vice-versa: if +# REFERENCE_STRING contains some backslashes, all slashes and backslashes +# are turned into backslashes, otherwise they are all turned into slashes. +# +# This makes processing of DOS filenames quite easier, because you can +# turn a filename to the Unix notation, make your processing, and turn it +# back to original notation. +# +# filename='A:\FOO\\BAR\' +# old_filename="$filename" +# # Switch to the unix notation +# AX_NORMALIZE_PATH([filename], ["/"]) +# # now we have $filename = 'A:/FOO/BAR' and we can process it as if +# # it was a Unix path. For instance let's say that you want +# # to append '/subpath': +# filename="$filename/subpath" +# # finally switch back to the original notation +# AX_NORMALIZE_PATH([filename], ["$old_filename"]) +# # now $filename equals to 'A:\FOO\BAR\subpath' +# +# One good reason to make all path processing with the unix convention is +# that backslashes have a special meaning in many cases. For instance +# +# expr 'A:\FOO' : 'A:\Foo' +# +# will return 0 because the second argument is a regex in which +# backslashes have to be backslashed. In other words, to have the two +# strings to match you should write this instead: +# +# expr 'A:\Foo' : 'A:\\Foo' +# +# Such behavior makes DOS filenames extremely unpleasant to work with. So +# temporary turn your paths to the Unix notation, and revert them to the +# original notation after the processing. See the macro +# AX_COMPUTE_RELATIVE_PATHS for a concrete example of this. +# +# REFERENCE_STRING defaults to $VARIABLE, this means that slashes will be +# converted to backslashes if $VARIABLE already contains some backslashes +# (see $thirddir below). +# +# firstdir='/usr/local//share' +# seconddir='C:\Program Files\\' +# thirddir='C:\home/usr/' +# AX_NORMALIZE_PATH([firstdir]) +# AX_NORMALIZE_PATH([seconddir]) +# AX_NORMALIZE_PATH([thirddir]) +# # $firstdir = '/usr/local/share' +# # $seconddir = 'C:\Program Files' +# # $thirddir = 'C:\home\usr' +# +# LICENSE +# +# Copyright (c) 2008 Alexandre Duret-Lutz +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 8 + +AU_ALIAS([ADL_NORMALIZE_PATH], [AX_NORMALIZE_PATH]) +AC_DEFUN([AX_NORMALIZE_PATH], +[case ":[$]$1:" in +# change empty paths to '.' + ::) $1='.' ;; +# strip trailing slashes + :*[[\\/]]:) $1=`echo "[$]$1" | sed 's,[[\\/]]*[$],,'` ;; + :*:) ;; +esac +# squeeze repeated slashes +case ifelse($2,,"[$]$1",$2) in +# if the path contains any backslashes, turn slashes into backslashes + *\\*) $1=`echo "[$]$1" | sed 's,\(.\)[[\\/]][[\\/]]*,\1\\\\,g'` ;; +# if the path contains slashes, also turn backslashes into slashes + *) $1=`echo "[$]$1" | sed 's,\(.\)[[\\/]][[\\/]]*,\1/,g'` ;; +esac]) diff --git a/SDL2-2.30.5/acinclude/ax_recursive_eval.m4 b/SDL2-2.30.5/acinclude/ax_recursive_eval.m4 new file mode 100644 index 0000000..0625aca --- /dev/null +++ b/SDL2-2.30.5/acinclude/ax_recursive_eval.m4 @@ -0,0 +1,56 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_recursive_eval.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_RECURSIVE_EVAL(VALUE, RESULT) +# +# DESCRIPTION +# +# Interpolate the VALUE in loop until it doesn't change, and set the +# result to $RESULT. WARNING: It's easy to get an infinite loop with some +# unsane input. +# +# LICENSE +# +# Copyright (c) 2008 Alexandre Duret-Lutz +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 1 + +AC_DEFUN([AX_RECURSIVE_EVAL], +[_lcl_receval="$1" +$2=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix" + test "x$exec_prefix" = xNONE && exec_prefix="${prefix}" + _lcl_receval_old='' + while test "[$]_lcl_receval_old" != "[$]_lcl_receval"; do + _lcl_receval_old="[$]_lcl_receval" + eval _lcl_receval="\"[$]_lcl_receval\"" + done + echo "[$]_lcl_receval")`]) diff --git a/SDL2-2.0.12/acinclude/esd.m4 b/SDL2-2.30.5/acinclude/esd.m4 similarity index 75% rename from SDL2-2.0.12/acinclude/esd.m4 rename to SDL2-2.30.5/acinclude/esd.m4 index 58d64a9..bd4b848 100644 --- a/SDL2-2.0.12/acinclude/esd.m4 +++ b/SDL2-2.30.5/acinclude/esd.m4 @@ -1,7 +1,3 @@ -############################################################################## -# -# --- esd.m4 --- -# # Configure paths for ESD # Manish Singh 98-9-30 # stolen back from Frank Belew @@ -12,7 +8,7 @@ dnl AM_PATH_ESD([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) dnl Test for ESD, and define ESD_CFLAGS and ESD_LIBS dnl AC_DEFUN([AM_PATH_ESD], -[dnl +[dnl dnl Get the cflags and libraries from the esd-config script dnl AC_ARG_WITH(esd-prefix,[ --with-esd-prefix=PFX Prefix where ESD is installed (optional)], @@ -52,6 +48,7 @@ AC_ARG_ENABLE(esdtest, [ --disable-esdtest Do not try to compile and run esd_micro_version=`$ESD_CONFIG $esd_config_args --version | \ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` if test "x$enable_esdtest" = "xyes" ; then + AC_LANG_PUSH([C]) ac_save_CFLAGS="$CFLAGS" ac_save_LIBS="$LIBS" CFLAGS="$CFLAGS $ESD_CFLAGS" @@ -61,38 +58,19 @@ dnl Now check if the installed ESD is sufficiently new. (Also sanity dnl checks the results of esd-config to some extent dnl rm -f conf.esdtest - AC_TRY_RUN([ + AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include #include -#include #include -char* -my_strdup (char *str) -{ - char *new_str; - - if (str) - { - new_str = malloc ((strlen (str) + 1) * sizeof(char)); - strcpy (new_str, str); - } - else - new_str = NULL; - - return new_str; -} - -int main () +int main (void) { int major, minor, micro; - char *tmp_version; + FILE *fp = fopen("conf.esdtest", "w"); - system ("touch conf.esdtest"); + if (fp) fclose(fp); - /* HP/UX 9 (%@#!) writes to sscanf strings */ - tmp_version = my_strdup("$min_esd_version"); - if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { + if (sscanf("$min_esd_version", "%d.%d.%d", &major, &minor, µ) != 3) { printf("%s, bad version string\n", "$min_esd_version"); exit(1); } @@ -114,22 +92,23 @@ int main () return 1; } } - -],, no_esd=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) +]])], [], [no_esd=yes], [echo $ac_n "cross compiling; assumed OK... $ac_c"]) CFLAGS="$ac_save_CFLAGS" LIBS="$ac_save_LIBS" + AC_LANG_POP([C]) fi fi if test "x$no_esd" = x ; then AC_MSG_RESULT(yes) - ifelse([$2], , :, [$2]) + ifelse([$2], , :, [$2]) else AC_MSG_RESULT(no) if test "$ESD_CONFIG" = "no" ; then - echo "*** The esd-config script installed by ESD could not be found" - echo "*** If ESD was installed in PREFIX, make sure PREFIX/bin is in" - echo "*** your path, or set the ESD_CONFIG environment variable to the" - echo "*** full path to esd-config." +dnl echo "*** The esd-config script installed by ESD could not be found" +dnl echo "*** If ESD was installed in PREFIX, make sure PREFIX/bin is in" +dnl echo "*** your path, or set the ESD_CONFIG environment variable to the" +dnl echo "*** full path to esd-config." + : else if test -f conf.esdtest ; then : @@ -137,10 +116,11 @@ int main () echo "*** Could not run ESD test program, checking why..." CFLAGS="$CFLAGS $ESD_CFLAGS" LIBS="$LIBS $ESD_LIBS" - AC_TRY_LINK([ + AC_LANG_PUSH([C]) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include #include -], [ return 0; ], +]], [[ return 0; ]])], [ echo "*** The test program compiled, but did not run. This usually means" echo "*** that the run-time linker is not finding ESD or finding the wrong" echo "*** version of ESD. If it is not finding ESD, you'll need to set your" @@ -156,6 +136,7 @@ int main () echo "*** may want to edit the esd-config script: $ESD_CONFIG" ]) CFLAGS="$ac_save_CFLAGS" LIBS="$ac_save_LIBS" + AC_LANG_POP([C]) fi fi ESD_CFLAGS="" @@ -166,3 +147,27 @@ int main () AC_SUBST(ESD_LIBS) rm -f conf.esdtest ]) + +dnl AM_ESD_SUPPORTS_MULTIPLE_RECORD([ACTION-IF-SUPPORTS [, ACTION-IF-NOT-SUPPORTS]]) +dnl Test, whether esd supports multiple recording clients (version >=0.2.21) +dnl +AC_DEFUN([AM_ESD_SUPPORTS_MULTIPLE_RECORD], +[dnl + AC_MSG_NOTICE([whether installed esd version supports multiple recording clients]) + ac_save_ESD_CFLAGS="$ESD_CFLAGS" + ac_save_ESD_LIBS="$ESD_LIBS" + AM_PATH_ESD(0.2.21, + ifelse([$1], , [ + AM_CONDITIONAL(ESD_SUPPORTS_MULTIPLE_RECORD, true) + AC_DEFINE(ESD_SUPPORTS_MULTIPLE_RECORD, 1, + [Define if you have esound with support of multiple recording clients.])], + [$1]), + ifelse([$2], , [AM_CONDITIONAL(ESD_SUPPORTS_MULTIPLE_RECORD, false)], [$2]) + if test "x$ac_save_ESD_CFLAGS" != x ; then + ESD_CFLAGS="$ac_save_ESD_CFLAGS" + fi + if test "x$ac_save_ESD_LIBS" != x ; then + ESD_LIBS="$ac_save_ESD_LIBS" + fi + ) +]) diff --git a/SDL2-2.0.12/acinclude/libtool.m4 b/SDL2-2.30.5/acinclude/libtool.m4 similarity index 71% rename from SDL2-2.0.12/acinclude/libtool.m4 rename to SDL2-2.30.5/acinclude/libtool.m4 index b8ba032..5afe55e 100644 --- a/SDL2-2.0.12/acinclude/libtool.m4 +++ b/SDL2-2.30.5/acinclude/libtool.m4 @@ -1,10 +1,6 @@ -############################################################################## -# Based on libtool-2.4.2 # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, -# 2006, 2007, 2008, 2009, 2010, 2011 Free Software -# Foundation, Inc. +# Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is free software; the Free Software Foundation gives @@ -12,36 +8,30 @@ # modifications, as long as this notice is preserved. m4_define([_LT_COPYING], [dnl -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, -# 2006, 2007, 2008, 2009, 2010, 2011 Free Software -# Foundation, Inc. -# Written by Gordon Matzigkeit, 1996 +# Copyright (C) 2014 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of of the License, or +# (at your option) any later version. # -# This file is part of GNU Libtool. +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program or library that is built +# using GNU Libtool, you may include this file under the same +# distribution terms that you use for the rest of that program. # -# GNU Libtool is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# As a special exception to the GNU General Public License, -# if you distribute this file as part of a program or library that -# is built using GNU Libtool, you may include this file under the -# same distribution terms that you use for the rest of that program. -# -# GNU Libtool is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of +# GNU Libtool is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with GNU Libtool; see the file COPYING. If not, a copy -# can be downloaded from http://www.gnu.org/licenses/gpl.html, or -# obtained by writing to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# along with this program. If not, see . ]) -# serial 57 LT_INIT +# serial 58 LT_INIT # LT_PREREQ(VERSION) @@ -69,7 +59,7 @@ esac # LT_INIT([OPTIONS]) # ------------------ AC_DEFUN([LT_INIT], -[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT +[AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl AC_BEFORE([$0], [LT_LANG])dnl AC_BEFORE([$0], [LT_OUTPUT])dnl @@ -93,7 +83,7 @@ dnl Parse OPTIONS _LT_SET_OPTIONS([$0], [$1]) # This can be used to rebuild libtool when needed -LIBTOOL_DEPS="$ltmain" +LIBTOOL_DEPS=$ltmain # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' @@ -113,26 +103,43 @@ dnl AC_DEFUN([AC_PROG_LIBTOOL], []) dnl AC_DEFUN([AM_PROG_LIBTOOL], []) +# _LT_PREPARE_CC_BASENAME +# ----------------------- +m4_defun([_LT_PREPARE_CC_BASENAME], [ +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +func_cc_basename () +{ + for cc_temp in @S|@*""; do + case $cc_temp in + compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; + distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; + \-*) ;; + *) break;; + esac + done + func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +} +])# _LT_PREPARE_CC_BASENAME + + # _LT_CC_BASENAME(CC) # ------------------- -# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +# It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME, +# but that macro is also expanded into generated libtool script, which +# arranges for $SED and $ECHO to be set by different means. m4_defun([_LT_CC_BASENAME], -[for cc_temp in $1""; do - case $cc_temp in - compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; - distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; - \-*) ;; - *) break;; - esac -done -cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +[m4_require([_LT_PREPARE_CC_BASENAME])dnl +AC_REQUIRE([_LT_DECL_SED])dnl +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl +func_cc_basename $1 +cc_basename=$func_cc_basename_result ]) # _LT_FILEUTILS_DEFAULTS # ---------------------- # It is okay to use these file commands and assume they have been set -# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. +# sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'. m4_defun([_LT_FILEUTILS_DEFAULTS], [: ${CP="cp -f"} : ${MV="mv -f"} @@ -179,15 +186,16 @@ m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_WITH_SYSROOT])dnl +m4_require([_LT_CMD_TRUNCATE])dnl _LT_CONFIG_LIBTOOL_INIT([ -# See if we are running on zsh, and set the options which allow our +# See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes INIT. -if test -n "\${ZSH_VERSION+set}" ; then +if test -n "\${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi ]) -if test -n "${ZSH_VERSION+set}" ; then +if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi @@ -200,7 +208,7 @@ aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. - if test "X${COLLECT_NAMES+set}" != Xset; then + if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi @@ -211,14 +219,14 @@ esac ofile=libtool can_build_shared=yes -# All known linkers require a `.a' archive for static linking (except MSVC, -# which needs '.lib'). +# All known linkers require a '.a' archive for static linking (except MSVC and +# ICC, which need '.lib'). libext=a -with_gnu_ld="$lt_cv_prog_gnu_ld" +with_gnu_ld=$lt_cv_prog_gnu_ld -old_CC="$CC" -old_CFLAGS="$CFLAGS" +old_CC=$CC +old_CFLAGS=$CFLAGS # Set sane defaults for various variables test -z "$CC" && CC=cc @@ -271,14 +279,14 @@ no_glob_subst='s/\*/\\\*/g' # _LT_PROG_LTMAIN # --------------- -# Note that this code is called both from `configure', and `config.status' +# Note that this code is called both from 'configure', and 'config.status' # now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, -# `config.status' has no value for ac_aux_dir unless we are using Automake, +# 'config.status' has no value for ac_aux_dir unless we are using Automake, # so we pass a copy along to make sure it has a sensible value anyway. m4_defun([_LT_PROG_LTMAIN], [m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl _LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) -ltmain="$ac_aux_dir/ltmain.sh" +ltmain=$ac_aux_dir/ltmain.sh ])# _LT_PROG_LTMAIN @@ -288,7 +296,7 @@ ltmain="$ac_aux_dir/ltmain.sh" # So that we can recreate a full libtool script including additional # tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS -# in macros and then make a single call at the end using the `libtool' +# in macros and then make a single call at the end using the 'libtool' # label. @@ -423,8 +431,8 @@ m4_define([_lt_decl_all_varnames], # _LT_CONFIG_STATUS_DECLARE([VARNAME]) # ------------------------------------ -# Quote a variable value, and forward it to `config.status' so that its -# declaration there will have the same value as in `configure'. VARNAME +# Quote a variable value, and forward it to 'config.status' so that its +# declaration there will have the same value as in 'configure'. VARNAME # must have a single quote delimited value for this to work. m4_define([_LT_CONFIG_STATUS_DECLARE], [$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) @@ -448,7 +456,7 @@ m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], # Output comment and list of tags supported by the script m4_defun([_LT_LIBTOOL_TAGS], [_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl -available_tags="_LT_TAGS"dnl +available_tags='_LT_TAGS'dnl ]) @@ -476,7 +484,7 @@ m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl # _LT_LIBTOOL_CONFIG_VARS # ----------------------- # Produce commented declarations of non-tagged libtool config variables -# suitable for insertion in the LIBTOOL CONFIG section of the `libtool' +# suitable for insertion in the LIBTOOL CONFIG section of the 'libtool' # script. Tagged libtool config variables (even for the LIBTOOL CONFIG # section) are produced by _LT_LIBTOOL_TAG_VARS. m4_defun([_LT_LIBTOOL_CONFIG_VARS], @@ -502,8 +510,8 @@ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) # Send accumulated output to $CONFIG_STATUS. Thanks to the lists of # variables for single and double quote escaping we saved from calls # to _LT_DECL, we can put quote escaped variables declarations -# into `config.status', and then the shell code to quote escape them in -# for loops in `config.status'. Finally, any additional code accumulated +# into 'config.status', and then the shell code to quote escape them in +# for loops in 'config.status'. Finally, any additional code accumulated # from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. m4_defun([_LT_CONFIG_COMMANDS], [AC_PROVIDE_IFELSE([LT_OUTPUT], @@ -549,7 +557,7 @@ for var in lt_decl_all_varnames([[ \ ]], lt_decl_quote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" @@ -562,7 +570,7 @@ for var in lt_decl_all_varnames([[ \ ]], lt_decl_dquote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" @@ -578,7 +586,7 @@ _LT_OUTPUT_LIBTOOL_INIT # Generate a child script FILE with all initialization necessary to # reuse the environment learned by the parent script, and make the # file executable. If COMMENT is supplied, it is inserted after the -# `#!' sequence but before initialization text begins. After this +# '#!' sequence but before initialization text begins. After this # macro, additional text can be appended to FILE to form the body of # the child script. The macro ends with non-zero status if the # file could not be fully written (such as if the disk is full). @@ -600,7 +608,7 @@ AS_SHELL_SANITIZE _AS_PREPARE exec AS_MESSAGE_FD>&1 _ASEOF -test $lt_write_fail = 0 && chmod +x $1[]dnl +test 0 = "$lt_write_fail" && chmod +x $1[]dnl m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT # LT_OUTPUT @@ -623,7 +631,7 @@ exec AS_MESSAGE_LOG_FD>>config.log } >&AS_MESSAGE_LOG_FD lt_cl_help="\ -\`$as_me' creates a local libtool stub from the current configuration, +'$as_me' creates a local libtool stub from the current configuration, for use in further configure time tests before the real libtool is generated. @@ -645,7 +653,7 @@ Copyright (C) 2011 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation gives unlimited permision to copy, distribute and modify it." -while test $[#] != 0 +while test 0 != $[#] do case $[1] in --version | --v* | -V ) @@ -658,10 +666,10 @@ do lt_cl_silent=: ;; -*) AC_MSG_ERROR([unrecognized option: $[1] -Try \`$[0] --help' for more information.]) ;; +Try '$[0] --help' for more information.]) ;; *) AC_MSG_ERROR([unrecognized argument: $[1] -Try \`$[0] --help' for more information.]) ;; +Try '$[0] --help' for more information.]) ;; esac shift done @@ -687,7 +695,7 @@ chmod +x "$CONFIG_LT" # open by configure. Here we exec the FD to /dev/null, effectively closing # config.log, so it can be properly (re)opened and appended to by config.lt. lt_cl_success=: -test "$silent" = yes && +test yes = "$silent" && lt_config_lt_args="$lt_config_lt_args --quiet" exec AS_MESSAGE_LOG_FD>/dev/null $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false @@ -707,32 +715,47 @@ m4_defun([_LT_CONFIG], _LT_CONFIG_SAVE_COMMANDS([ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl m4_if(_LT_TAG, [C], [ - # See if we are running on zsh, and set the options which allow our + # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes. - if test -n "${ZSH_VERSION+set}" ; then + if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi - cfgfile="${ofile}T" + cfgfile=${ofile}T trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL - -# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. -# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Generated automatically by $as_me ($PACKAGE) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. -# + +# Provide generalized library-building support services. +# Written by Gordon Matzigkeit, 1996 + _LT_COPYING _LT_LIBTOOL_TAGS +# Configured defaults for sys_lib_dlsearch_path munging. +: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} + # ### BEGIN LIBTOOL CONFIG _LT_LIBTOOL_CONFIG_VARS _LT_LIBTOOL_TAG_VARS # ### END LIBTOOL CONFIG +_LT_EOF + + cat <<'_LT_EOF' >> "$cfgfile" + +# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE + +_LT_PREPARE_MUNGE_PATH_LIST +_LT_PREPARE_CC_BASENAME + +# ### END FUNCTIONS SHARED WITH CONFIGURE + _LT_EOF case $host_os in @@ -741,7 +764,7 @@ _LT_EOF # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. -if test "X${COLLECT_NAMES+set}" != Xset; then +if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi @@ -758,8 +781,6 @@ _LT_EOF sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) - _LT_PROG_REPLACE_SHELLFNS - mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" @@ -777,7 +798,6 @@ _LT_EOF [m4_if([$1], [], [ PACKAGE='$PACKAGE' VERSION='$VERSION' - TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile'], []) ])dnl /_LT_CONFIG_SAVE_COMMANDS @@ -976,7 +996,7 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], [lt_cv_apple_cc_single_mod=no - if test -z "${LT_MULTI_MODULE}"; then + if test -z "$LT_MULTI_MODULE"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the @@ -994,7 +1014,7 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ cat conftest.err >&AS_MESSAGE_LOG_FD # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. - elif test -f libconftest.dylib && test $_lt_result -eq 0; then + elif test -f libconftest.dylib && test 0 = "$_lt_result"; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&AS_MESSAGE_LOG_FD @@ -1012,7 +1032,7 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [lt_cv_ld_exported_symbols_list=yes], [lt_cv_ld_exported_symbols_list=no]) - LDFLAGS="$save_LDFLAGS" + LDFLAGS=$save_LDFLAGS ]) AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], @@ -1034,7 +1054,7 @@ _LT_EOF _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD - elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then + elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then lt_cv_ld_force_load=yes else cat conftest.err >&AS_MESSAGE_LOG_FD @@ -1044,32 +1064,27 @@ _LT_EOF ]) case $host_os in rhapsody* | darwin1.[[012]]) - _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; - darwin*) # darwin 5.x on - # if running on 10.5 or later, the deployment target defaults - # to the OS version, if on x86, and 10.4, the deployment - # target defaults to 10.4. Don't you love it? - case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in - 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; - 10.[[012]]*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; - 10.*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + darwin*) + case $MACOSX_DEPLOYMENT_TARGET,$host in + 10.[[012]],*|,*powerpc*-darwin[[5-8]]*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + *) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; esac - if test "$lt_cv_apple_cc_single_mod" = "yes"; then + if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi - if test "$lt_cv_ld_exported_symbols_list" = "yes"; then - _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + if test yes = "$lt_cv_ld_exported_symbols_list"; then + _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' else - _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' fi - if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then + if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= @@ -1089,29 +1104,29 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES], _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported - if test "$lt_cv_ld_force_load" = "yes"; then - _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + if test yes = "$lt_cv_ld_force_load"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) else _LT_TAGVAR(whole_archive_flag_spec, $1)='' fi _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" + _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined case $cc_basename in - ifort*) _lt_dar_can_shared=yes ;; + ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac - if test "$_lt_dar_can_shared" = "yes"; then + if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all - _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" - _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" - _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" - _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" m4_if([$1], [CXX], -[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then - _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" - _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" +[ if test yes != "$lt_cv_apple_cc_single_mod"; then + _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" fi ],[]) else @@ -1131,7 +1146,7 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES], # Allow to override them for all tags through lt_cv_aix_libpath. m4_defun([_LT_SYS_MODULE_PATH_AIX], [m4_require([_LT_DECL_SED])dnl -if test "${lt_cv_aix_libpath+set}" = set; then +if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], @@ -1149,7 +1164,7 @@ else _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi],[]) if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then - _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib" + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib fi ]) aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) @@ -1169,8 +1184,8 @@ m4_define([_LT_SHELL_INIT], # ----------------------- # Find how we can fake an echo command that does not interpret backslash. # In particular, with Autoconf 2.60 or later we add some code to the start -# of the generated configure script which will find a shell with a builtin -# printf (which we can use as an echo command). +# of the generated configure script that will find a shell with a builtin +# printf (that we can use as an echo command). m4_defun([_LT_PROG_ECHO_BACKSLASH], [ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO @@ -1198,10 +1213,10 @@ fi # Invoke $ECHO with all args, space-separated. func_echo_all () { - $ECHO "$*" + $ECHO "$*" } -case "$ECHO" in +case $ECHO in printf*) AC_MSG_RESULT([printf]) ;; print*) AC_MSG_RESULT([print -r]) ;; *) AC_MSG_RESULT([cat]) ;; @@ -1227,16 +1242,17 @@ _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) AC_DEFUN([_LT_WITH_SYSROOT], [AC_MSG_CHECKING([for sysroot]) AC_ARG_WITH([sysroot], -[ --with-sysroot[=DIR] Search for dependent libraries within DIR - (or the compiler's sysroot if not specified).], +[AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@], + [Search for dependent libraries within DIR (or the compiler's sysroot + if not specified).])], [], [with_sysroot=no]) dnl lt_sysroot will always be passed unquoted. We quote it here dnl in case the user passed a directory name. lt_sysroot= -case ${with_sysroot} in #( +case $with_sysroot in #( yes) - if test "$GCC" = yes; then + if test yes = "$GCC"; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( @@ -1246,14 +1262,14 @@ case ${with_sysroot} in #( no|'') ;; #( *) - AC_MSG_RESULT([${with_sysroot}]) + AC_MSG_RESULT([$with_sysroot]) AC_MSG_ERROR([The sysroot must be an absolute path.]) ;; esac AC_MSG_RESULT([${lt_sysroot:-no}]) _LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl -[dependent libraries, and in which our libraries should be installed.])]) +[dependent libraries, and where our libraries should be installed.])]) # _LT_ENABLE_LOCK # --------------- @@ -1261,31 +1277,33 @@ m4_defun([_LT_ENABLE_LOCK], [AC_ARG_ENABLE([libtool-lock], [AS_HELP_STRING([--disable-libtool-lock], [avoid locking (might break parallel builds)])]) -test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes +test no = "$enable_libtool_lock" || enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) - # Find out which ABI we are using. + # Find out what ABI is being produced by ac_compile, and set mode + # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) - HPUX_IA64_MODE="32" + HPUX_IA64_MODE=32 ;; *ELF-64*) - HPUX_IA64_MODE="64" + HPUX_IA64_MODE=64 ;; esac fi rm -rf conftest* ;; *-*-irix6*) - # Find out which ABI we are using. + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then - if test "$lt_cv_prog_gnu_ld" = yes; then + if test yes = "$lt_cv_prog_gnu_ld"; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" @@ -1314,9 +1332,46 @@ ia64-*-hpux*) rm -rf conftest* ;; -x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ -s390*-*linux*|s390*-*tpf*|sparc*-*linux*) - # Find out which ABI we are using. +mips64*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + emul=elf + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + emul="${emul}32" + ;; + *64-bit*) + emul="${emul}64" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *MSB*) + emul="${emul}btsmip" + ;; + *LSB*) + emul="${emul}ltsmip" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *N32*) + emul="${emul}n32" + ;; + esac + LD="${LD-ld} -m $emul" + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*|x86_64-gnu*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. Note that the listed cases only cover the + # situations where additional linker options are needed (such as when + # doing 32-bit compilation for a host where ld defaults to 64-bit, or + # vice versa); the common cases where no linker options are needed do + # not appear in the list. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in @@ -1325,10 +1380,20 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; - x86_64-*linux*) - LD="${LD-ld} -m elf_i386" + x86_64-*linux*|x86_64-gnu*) + case `/usr/bin/file conftest.o` in + *x86-64*) + LD="${LD-ld} -m elf32_x86_64" + ;; + *) + LD="${LD-ld} -m elf_i386" + ;; + esac ;; - ppc64-*linux*|powerpc64-*linux*) + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) @@ -1344,13 +1409,13 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; - x86_64-*linux*) + x86_64-*linux*|x86_64-gnu*) LD="${LD-ld} -m elf_x86_64" ;; - powerpc64le-*linux*) + powerpcle-*linux*|powerpc64le-*linux*) LD="${LD-ld} -m elf64lppc" ;; - powerpc64-*linux*) + powerpc-*linux*|powerpc64-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) @@ -1368,19 +1433,20 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. - SAVE_CFLAGS="$CFLAGS" + SAVE_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -belf" AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, [AC_LANG_PUSH(C) AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) AC_LANG_POP]) - if test x"$lt_cv_cc_needs_belf" != x"yes"; then + if test yes != "$lt_cv_cc_needs_belf"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf - CFLAGS="$SAVE_CFLAGS" + CFLAGS=$SAVE_CFLAGS fi ;; *-*solaris*) - # Find out which ABI we are using. + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in @@ -1388,7 +1454,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) case $lt_cv_prog_gnu_ld in yes*) case $host in - i?86-*-solaris*) + i?86-*-solaris*|x86_64-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) @@ -1397,7 +1463,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then - LD="${LD-ld}_sol2" + LD=${LD-ld}_sol2 fi ;; *) @@ -1413,7 +1479,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) ;; esac -need_locks="$enable_libtool_lock" +need_locks=$enable_libtool_lock ])# _LT_ENABLE_LOCK @@ -1432,11 +1498,11 @@ AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], [echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([lt_ar_try]) - if test "$ac_status" -eq 0; then + if test 0 -eq "$ac_status"; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a AC_TRY_EVAL([lt_ar_try]) - if test "$ac_status" -ne 0; then + if test 0 -ne "$ac_status"; then lt_cv_ar_at_file=@ fi fi @@ -1444,7 +1510,7 @@ AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], ]) ]) -if test "x$lt_cv_ar_at_file" = xno; then +if test no = "$lt_cv_ar_at_file"; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file @@ -1474,15 +1540,8 @@ old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then - case $host_os in - openbsd*) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" - ;; - *) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" - ;; - esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in @@ -1511,7 +1570,7 @@ AC_CACHE_CHECK([$1], [$2], [$2=no m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) echo "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="$3" + lt_compiler_flag="$3" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins @@ -1538,7 +1597,7 @@ AC_CACHE_CHECK([$1], [$2], $RM conftest* ]) -if test x"[$]$2" = xyes; then +if test yes = "[$]$2"; then m4_if([$5], , :, [$5]) else m4_if([$6], , :, [$6]) @@ -1560,7 +1619,7 @@ AC_DEFUN([_LT_LINKER_OPTION], m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no - save_LDFLAGS="$LDFLAGS" + save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $3" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then @@ -1579,10 +1638,10 @@ AC_CACHE_CHECK([$1], [$2], fi fi $RM -r conftest* - LDFLAGS="$save_LDFLAGS" + LDFLAGS=$save_LDFLAGS ]) -if test x"[$]$2" = xyes; then +if test yes = "[$]$2"; then m4_if([$4], , :, [$4]) else m4_if([$5], , :, [$5]) @@ -1603,7 +1662,7 @@ AC_DEFUN([LT_CMD_MAX_LEN], AC_MSG_CHECKING([the maximum length of command line arguments]) AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl i=0 - teststring="ABCD" + teststring=ABCD case $build_os in msdosdjgpp*) @@ -1621,7 +1680,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl lt_cv_sys_max_cmd_len=-1; ;; - cygwin* | mingw* | cegcc*) + cygwin* | mingw* | windows* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, @@ -1643,7 +1702,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl lt_cv_sys_max_cmd_len=8192; ;; - netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + bitrig* | darwin* | dragonfly* | freebsd* | midnightbsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` @@ -1693,22 +1752,23 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` - if test -n "$lt_cv_sys_max_cmd_len"; then + if test -n "$lt_cv_sys_max_cmd_len" && \ + test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. - for i in 1 2 3 4 5 6 7 8 ; do + for i in 1 2 3 4 5 6 7 8; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. - while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ + while { test X`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && - test $i != 17 # 1/2 MB should be enough + test 17 != "$i" # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring @@ -1724,7 +1784,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl ;; esac ]) -if test -n $lt_cv_sys_max_cmd_len ; then +if test -n "$lt_cv_sys_max_cmd_len"; then AC_MSG_RESULT($lt_cv_sys_max_cmd_len) else AC_MSG_RESULT(none) @@ -1752,7 +1812,7 @@ m4_defun([_LT_HEADER_DLFCN], # ---------------------------------------------------------------- m4_defun([_LT_TRY_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl -if test "$cross_compiling" = yes; then : +if test yes = "$cross_compiling"; then : [$4] else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 @@ -1799,9 +1859,9 @@ else # endif #endif -/* When -fvisbility=hidden is used, assume the code has been annotated +/* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ -#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif @@ -1827,7 +1887,7 @@ int main () return status; }] _LT_EOF - if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then + if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null lt_status=$? case x$lt_status in @@ -1848,7 +1908,7 @@ rm -fr conftest* # ------------------ AC_DEFUN([LT_SYS_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl -if test "x$enable_dlopen" != xyes; then +if test yes != "$enable_dlopen"; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown @@ -1858,44 +1918,52 @@ else case $host_os in beos*) - lt_cv_dlopen="load_add_on" + lt_cv_dlopen=load_add_on lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; - mingw* | pw32* | cegcc*) - lt_cv_dlopen="LoadLibrary" + mingw* | windows* | pw32* | cegcc*) + lt_cv_dlopen=LoadLibrary lt_cv_dlopen_libs= ;; cygwin*) - lt_cv_dlopen="dlopen" + lt_cv_dlopen=dlopen lt_cv_dlopen_libs= ;; darwin*) - # if libdl is installed we need to link against it + # if libdl is installed we need to link against it AC_CHECK_LIB([dl], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ - lt_cv_dlopen="dyld" + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[ + lt_cv_dlopen=dyld lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ]) ;; + tpf*) + # Don't try to run any link tests for TPF. We know it's impossible + # because TPF is a cross-compiler, and we know how we open DSOs. + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + lt_cv_dlopen_self=no + ;; + *) AC_CHECK_FUNC([shl_load], - [lt_cv_dlopen="shl_load"], + [lt_cv_dlopen=shl_load], [AC_CHECK_LIB([dld], [shl_load], - [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], + [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld], [AC_CHECK_FUNC([dlopen], - [lt_cv_dlopen="dlopen"], + [lt_cv_dlopen=dlopen], [AC_CHECK_LIB([dl], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl], [AC_CHECK_LIB([svld], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld], [AC_CHECK_LIB([dld], [dld_link], - [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) + [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld]) ]) ]) ]) @@ -1904,21 +1972,21 @@ else ;; esac - if test "x$lt_cv_dlopen" != xno; then - enable_dlopen=yes - else + if test no = "$lt_cv_dlopen"; then enable_dlopen=no + else + enable_dlopen=yes fi case $lt_cv_dlopen in dlopen) - save_CPPFLAGS="$CPPFLAGS" - test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + save_CPPFLAGS=$CPPFLAGS + test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - save_LDFLAGS="$LDFLAGS" + save_LDFLAGS=$LDFLAGS wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - save_LIBS="$LIBS" + save_LIBS=$LIBS LIBS="$lt_cv_dlopen_libs $LIBS" AC_CACHE_CHECK([whether a program can dlopen itself], @@ -1928,7 +1996,7 @@ else lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ]) - if test "x$lt_cv_dlopen_self" = xyes; then + if test yes = "$lt_cv_dlopen_self"; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" AC_CACHE_CHECK([whether a statically linked program can dlopen itself], lt_cv_dlopen_self_static, [dnl @@ -1938,9 +2006,9 @@ else ]) fi - CPPFLAGS="$save_CPPFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" + CPPFLAGS=$save_CPPFLAGS + LDFLAGS=$save_LDFLAGS + LIBS=$save_LIBS ;; esac @@ -2032,8 +2100,8 @@ m4_defun([_LT_COMPILER_FILE_LOCKS], m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_COMPILER_C_O([$1]) -hard_links="nottested" -if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then +hard_links=nottested +if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user AC_MSG_CHECKING([if we can lock with hard links]) hard_links=yes @@ -2043,8 +2111,8 @@ if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no AC_MSG_RESULT([$hard_links]) - if test "$hard_links" = no; then - AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) + if test no = "$hard_links"; then + AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe]) need_locks=warn fi else @@ -2071,8 +2139,8 @@ objdir=$lt_cv_objdir _LT_DECL([], [objdir], [0], [The name of the directory that contains temporary libtool files])dnl m4_pattern_allow([LT_OBJDIR])dnl -AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", - [Define to the sub-directory in which libtool stores uninstalled libraries.]) +AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/", + [Define to the sub-directory where libtool stores uninstalled libraries.]) ])# _LT_CHECK_OBJDIR @@ -2084,15 +2152,15 @@ m4_defun([_LT_LINKER_HARDCODE_LIBPATH], _LT_TAGVAR(hardcode_action, $1)= if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || test -n "$_LT_TAGVAR(runpath_var, $1)" || - test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then + test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then # We can hardcode non-existent directories. - if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && + if test no != "$_LT_TAGVAR(hardcode_direct, $1)" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one - ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && - test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" && + test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then # Linking always hardcodes the temporary library directory. _LT_TAGVAR(hardcode_action, $1)=relink else @@ -2106,12 +2174,12 @@ else fi AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) -if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || - test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then +if test relink = "$_LT_TAGVAR(hardcode_action, $1)" || + test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then # Fast installation is not supported enable_fast_install=no -elif test "$shlibpath_overrides_runpath" = yes || - test "$enable_shared" = no; then +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi @@ -2127,32 +2195,82 @@ m4_defun([_LT_CMD_STRIPLIB], striplib= old_striplib= AC_MSG_CHECKING([whether stripping libraries is possible]) -if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - AC_MSG_RESULT([yes]) +if test -z "$STRIP"; then + AC_MSG_RESULT([no]) else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP" ; then + if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + old_striplib="$STRIP --strip-debug" + striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) + else + case $host_os in + darwin*) + # FIXME - insert some real tests, host_os isn't really good enough striplib="$STRIP -x" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) - else + ;; + freebsd*) + if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then + old_striplib="$STRIP --strip-debug" + striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + ;; + *) AC_MSG_RESULT([no]) - fi - ;; - *) - AC_MSG_RESULT([no]) - ;; - esac + ;; + esac + fi fi _LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) _LT_DECL([], [striplib], [1]) ])# _LT_CMD_STRIPLIB +# _LT_PREPARE_MUNGE_PATH_LIST +# --------------------------- +# Make sure func_munge_path_list() is defined correctly. +m4_defun([_LT_PREPARE_MUNGE_PATH_LIST], +[[# func_munge_path_list VARIABLE PATH +# ----------------------------------- +# VARIABLE is name of variable containing _space_ separated list of +# directories to be munged by the contents of PATH, which is string +# having a format: +# "DIR[:DIR]:" +# string "DIR[ DIR]" will be prepended to VARIABLE +# ":DIR[:DIR]" +# string "DIR[ DIR]" will be appended to VARIABLE +# "DIRP[:DIRP]::[DIRA:]DIRA" +# string "DIRP[ DIRP]" will be prepended to VARIABLE and string +# "DIRA[ DIRA]" will be appended to VARIABLE +# "DIR[:DIR]" +# VARIABLE will be replaced by "DIR[ DIR]" +func_munge_path_list () +{ + case x@S|@2 in + x) + ;; + *:) + eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\" + ;; + x:*) + eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\" + ;; + *::*) + eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" + eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\" + ;; + *) + eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\" + ;; + esac +} +]])# _LT_PREPARE_PATH_LIST + + # _LT_SYS_DYNAMIC_LINKER([TAG]) # ----------------------------- # PORTME Fill in your ld.so characteristics @@ -2163,17 +2281,18 @@ m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_OBJDUMP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl AC_MSG_CHECKING([dynamic linker characteristics]) m4_if([$1], [], [ -if test "$GCC" = yes; then +if test yes = "$GCC"; then case $host_os in - darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; - *) lt_awk_arg="/^libraries:/" ;; + darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; + *) lt_awk_arg='/^libraries:/' ;; esac case $host_os in - mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;; - *) lt_sed_strip_eq="s,=/,/,g" ;; + mingw* | windows* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;; + *) lt_sed_strip_eq='s|=/|/|g' ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in @@ -2192,8 +2311,8 @@ if test "$GCC" = yes; then # and add multilib dir if necessary... lt_tmp_lt_search_path_spec= lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` - # ...but if some path already ends with the multilib dir we assume - # that all is fine and trust -print-search-dirs as is (GCC 4.2 or newer). + # ...but if some path component already ends with the multilib dir we assume + # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). case "$lt_multi_os_dir; $lt_search_path_spec " in "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) lt_multi_os_dir= @@ -2208,16 +2327,16 @@ if test "$GCC" = yes; then fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' -BEGIN {RS=" "; FS="/|\n";} { - lt_foo=""; - lt_count=0; +BEGIN {RS = " "; FS = "/|\n";} { + lt_foo = ""; + lt_count = 0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { - lt_foo="/" $lt_i lt_foo; + lt_foo = "/" $lt_i lt_foo; } else { lt_count--; } @@ -2230,8 +2349,8 @@ BEGIN {RS=" "; FS="/|\n";} { # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in - mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ - $SED 's,/\([[A-Za-z]]:\),\1,g'` ;; + mingw* | windows* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else @@ -2240,7 +2359,7 @@ fi]) library_names_spec= libname_spec='lib$name' soname_spec= -shrext_cmds=".so" +shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= @@ -2257,14 +2376,17 @@ hardcode_into_libs=no # flags to be left without arguments need_version=unknown +AC_ARG_VAR([LT_SYS_LIBRARY_PATH], +[User-defined run-time library search path.]) + case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. - soname_spec='${libname}${release}${shared_ext}$major' + soname_spec='$libname$release$shared_ext$major' ;; aix[[4-9]]*) @@ -2272,41 +2394,91 @@ aix[[4-9]]*) need_lib_prefix=no need_version=no hardcode_into_libs=yes - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 - library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with - # the line `#! .'. This would cause the generated library to - # depend on `.', always an invalid library. This was fixed in + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[[01]] | aix4.[[01]].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' - echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac - # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # Using Import Files as archive members, it is possible to support + # filename-based versioning of shared library archives on AIX. While + # this would work for both with and without runtime linking, it will + # prevent static linking of such archives. So we do filename-based + # shared library versioning with .so extension only, which is used + # when both runtime linking and shared linking is enabled. + # Unfortunately, runtime linking may impact performance, so we do + # not want this to be the default eventually. Also, we use the + # versioned .so libs for executables only if there is the -brtl + # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. + # To allow for filename-based versioning support, we need to create + # libNAME.so.V as an archive file, containing: + # *) an Import File, referring to the versioned filename of the + # archive as well as the shared archive member, telling the + # bitwidth (32 or 64) of that shared object, and providing the + # list of exported symbols of that shared object, eventually + # decorated with the 'weak' keyword + # *) the shared object with the F_LOADONLY flag set, to really avoid + # it being seen by the linker. + # At run time we better use the real file rather than another symlink, + # but for link time we create the symlink libNAME.so -> libNAME.so.V + + case $with_aix_soname,$aix_use_runtimelinking in + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. - if test "$aix_use_runtimelinking" = yes; then + aix,yes) # traditional libtool + dynamic_linker='AIX unversionable lib.so' # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - else + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + aix,no) # traditional AIX only + dynamic_linker='AIX lib.a[(]lib.so.V[)]' # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. - library_names_spec='${libname}${release}.a $libname.a' - soname_spec='${libname}${release}${shared_ext}$major' - fi + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + ;; + svr4,*) # full svr4 only + dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,yes) # both, prefer svr4 + dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # unpreferred sharedlib libNAME.a needs extra handling + postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' + postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,no) # both, prefer aix + dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]" + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling + postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' + postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' + ;; + esac shlibpath_var=LIBPATH fi ;; @@ -2316,18 +2488,18 @@ amigaos*) powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) - library_names_spec='${libname}${shared_ext}' + library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; @@ -2335,8 +2507,8 @@ beos*) bsdi[[45]]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" @@ -2346,9 +2518,9 @@ bsdi[[45]]*) # libtool to hard-code these into programs ;; -cygwin* | mingw* | pw32* | cegcc*) +cygwin* | mingw* | windows* | pw32* | cegcc*) version_type=windows - shrext_cmds=".dll" + shrext_cmds=.dll need_version=no need_lib_prefix=no @@ -2357,8 +2529,8 @@ cygwin* | mingw* | pw32* | cegcc*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ @@ -2374,32 +2546,32 @@ cygwin* | mingw* | pw32* | cegcc*) case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' - #soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - soname_spec='`echo ${libname} | sed -e 's/^lib//'`${shared_ext}' + #soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + soname_spec='`echo $libname | sed -e 's/^lib//'`$shared_ext' # SDL customization m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) ;; - mingw* | cegcc*) + mingw* | windows* | cegcc*) # MinGW DLLs use traditional 'lib' prefix - #soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - soname_spec='`echo ${libname} | $SED -e 's/^lib//'`${shared_ext}' + #soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + soname_spec='`echo $libname | $SED -e 's/^lib//'`$shared_ext' # SDL customization ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; - *,cl*) - # Native MSVC + *,cl* | *,icl*) + # Native MSVC or ICC libname_spec='$name' - soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - library_names_spec='${libname}.dll.lib' + soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' case $build_os in - mingw*) + mingw* | windows*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' @@ -2423,7 +2595,7 @@ m4_if([$1], [],[ sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) - sys_lib_search_path_spec="$LIB" + sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` @@ -2436,8 +2608,8 @@ m4_if([$1], [],[ esac # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' @@ -2449,8 +2621,8 @@ m4_if([$1], [],[ ;; *) - # Assume MSVC wrapper - library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' + # Assume MSVC and ICC wrapper + library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac @@ -2463,8 +2635,8 @@ darwin* | rhapsody*) version_type=darwin need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' - soname_spec='${libname}${release}${major}$shared_ext' + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' @@ -2477,12 +2649,12 @@ dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; -freebsd* | dragonfly*) +freebsd* | dragonfly* | midnightbsd*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then @@ -2496,12 +2668,13 @@ freebsd* | dragonfly*) version_type=freebsd-$objformat case $version_type in freebsd-elf*) - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' need_version=no need_lib_prefix=no ;; freebsd-*) - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac @@ -2526,26 +2699,15 @@ freebsd* | dragonfly*) esac ;; -gnu*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH - shlibpath_overrides_runpath=yes + shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; @@ -2563,14 +2725,15 @@ hpux9* | hpux10* | hpux11*) dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - if test "X$HPUX_IA64_MODE" = X32; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' @@ -2578,8 +2741,8 @@ hpux9* | hpux10* | hpux11*) dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; @@ -2588,8 +2751,8 @@ hpux9* | hpux10* | hpux11*) dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... @@ -2602,8 +2765,8 @@ interix[[3-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no @@ -2614,7 +2777,7 @@ irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) - if test "$lt_cv_prog_gnu_ld" = yes; then + if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix @@ -2622,8 +2785,8 @@ irix5* | irix6* | nonstopux*) esac need_lib_prefix=no need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= @@ -2642,8 +2805,8 @@ irix5* | irix6* | nonstopux*) esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; @@ -2652,13 +2815,33 @@ linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + ;; + # This must be glibc/ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu) +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no @@ -2683,10 +2866,18 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu) # before this can be enabled. hardcode_into_libs=yes - # Append ld.so.conf contents to the search path + # Add ABI-specific directories to the system library path. + sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" + + # Ideally, we could use ldconfig to report *all* directores which are + # searched for libraries, however this is still not possible. Aside from not + # being certain /sbin/ldconfig is available, command + # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, + # even though it is searched at run-time. Try to do the best guess by + # appending ld.so.conf contents (and includes) to the search path. if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` - sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on @@ -2703,12 +2894,12 @@ netbsd*) need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH @@ -2718,7 +2909,7 @@ netbsd*) newsos6) version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; @@ -2727,58 +2918,70 @@ newsos6) version_type=qnx need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; -openbsd*) +openbsd* | bitrig*) version_type=sunos - sys_lib_dlsearch_path_spec="/usr/lib" + sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no - # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. - case $host_os in - openbsd3.3 | openbsd3.3.*) need_version=yes ;; - *) need_version=no ;; - esac - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no + else + need_version=yes + fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - case $host_os in - openbsd2.[[89]] | openbsd2.[[89]].*) - shlibpath_overrides_runpath=no - ;; - *) - shlibpath_overrides_runpath=yes - ;; - esac - else - shlibpath_overrides_runpath=yes - fi + shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' - shrext_cmds=".dll" + shrext_cmds=.dll need_lib_prefix=no - library_names_spec='$libname${shared_ext} $libname.a' + # OS/2 can only load a DLL with a base name of 8 characters or less. +# SDL customization: removed versioning support. +# version_type=windows +# need_version=no +# soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; +# v=$($ECHO $release$versuffix | tr -d .-); +# n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); +# $ECHO $n$v`$shared_ext' + soname_spec='`test -n "$os2dllname" && libname=$os2dllname; $ECHO $libname | cut -b -8 | tr . _`$shared_ext' + library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' - shlibpath_var=LIBPATH + shlibpath_var=BEGINLIBPATH + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) @@ -2789,8 +2992,8 @@ solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes @@ -2800,11 +3003,11 @@ solaris*) sunos4*) version_type=sunos - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes - if test "$with_gnu_ld" = yes; then + if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes @@ -2812,8 +3015,8 @@ sunos4*) sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) @@ -2834,24 +3037,24 @@ sysv4 | sysv4.3*) ;; sysv4*MP*) - if test -d /usr/nec ;then + if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' - soname_spec='$libname${shared_ext}.$major' + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - version_type=freebsd-elf + version_type=sco need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes - if test "$with_gnu_ld" = yes; then + if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' @@ -2869,7 +3072,7 @@ tpf*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes @@ -2877,8 +3080,8 @@ tpf*) uts4*) version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; @@ -2887,20 +3090,30 @@ uts4*) ;; esac AC_MSG_RESULT([$dynamic_linker]) -test "$dynamic_linker" = no && can_build_shared=no +test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then +if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi -if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then - sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi -if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then - sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" + +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi +# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... +configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec + +# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code +func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" + +# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool +configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH + _LT_DECL([], [variables_saved_for_relink], [1], [Variables whose values should be saved in libtool wrapper scripts and restored at link time]) @@ -2933,39 +3146,41 @@ _LT_DECL([], [hardcode_into_libs], [0], [Whether we should hardcode library paths into libraries]) _LT_DECL([], [sys_lib_search_path_spec], [2], [Compile-time system search path for libraries]) -_LT_DECL([], [sys_lib_dlsearch_path_spec], [2], - [Run-time system search path for libraries]) +_LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2], + [Detected run-time system search path for libraries]) +_LT_DECL([], [configure_time_lt_sys_library_path], [2], + [Explicit LT_SYS_LIBRARY_PATH set during ./configure time]) ])# _LT_SYS_DYNAMIC_LINKER # _LT_PATH_TOOL_PREFIX(TOOL) # -------------------------- -# find a file program which can recognize shared library +# find a file program that can recognize shared library AC_DEFUN([_LT_PATH_TOOL_PREFIX], [m4_require([_LT_DECL_EGREP])dnl AC_MSG_CHECKING([for $1]) AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, [case $MAGIC_CMD in [[\\/*] | ?:[\\/]*]) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) - lt_save_MAGIC_CMD="$MAGIC_CMD" - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR dnl $ac_dummy forces splitting on constant user-supplied paths. dnl POSIX.2 word splitting is done only on the output of word expansions, dnl not every word. This closes a longstanding sh security hole. ac_dummy="m4_if([$2], , $PATH, [$2])" for ac_dir in $ac_dummy; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$1; then - lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -f "$ac_dir/$1"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"$1" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` - MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : @@ -2988,11 +3203,11 @@ _LT_EOF break fi done - IFS="$lt_save_ifs" - MAGIC_CMD="$lt_save_MAGIC_CMD" + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac]) -MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then AC_MSG_RESULT($MAGIC_CMD) else @@ -3010,7 +3225,7 @@ dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) # _LT_PATH_MAGIC # -------------- -# find a file program which can recognize a shared library +# find a file program that can recognize a shared library m4_defun([_LT_PATH_MAGIC], [_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) if test -z "$lt_cv_path_MAGIC_CMD"; then @@ -3037,16 +3252,16 @@ m4_require([_LT_PROG_ECHO_BACKSLASH])dnl AC_ARG_WITH([gnu-ld], [AS_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])], - [test "$withval" = no || with_gnu_ld=yes], + [test no = "$withval" || with_gnu_ld=yes], [with_gnu_ld=no])dnl ac_prog=ld -if test "$GCC" = yes; then +if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw + *-*-mingw* | *-*-windows*) + # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; @@ -3060,7 +3275,7 @@ if test "$GCC" = yes; then while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done - test -z "$LD" && LD="$ac_prog" + test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. @@ -3071,37 +3286,37 @@ if test "$GCC" = yes; then with_gnu_ld=unknown ;; esac -elif test "$with_gnu_ld" = yes; then +elif test yes = "$with_gnu_ld"; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(lt_cv_path_LD, [if test -z "$LD"; then - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - lt_cv_path_LD="$ac_dir/$ac_prog" + lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 conftest.i +cat conftest.i conftest.i >conftest2.i +: ${lt_DD:=$DD} +AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd], +[if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: +fi]) +rm -f conftest.i conftest2.i conftest.out]) +])# _LT_PATH_DD + + +# _LT_CMD_TRUNCATE +# ---------------- +# find command to truncate a binary pipe +m4_defun([_LT_CMD_TRUNCATE], +[m4_require([_LT_PATH_DD]) +AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin], +[printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +lt_cv_truncate_bin= +if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" +fi +rm -f conftest.i conftest2.i conftest.out +test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"]) +_LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1], + [Command to truncate a binary pipe]) +])# _LT_CMD_TRUNCATE + + # _LT_CHECK_MAGIC_METHOD # ---------------------- # how to check for library dependencies @@ -3187,13 +3439,13 @@ lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. -# `unknown' -- same as none, but documents that we really don't know. +# 'unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path -# which responds to the $file_magic_cmd with a given extended regex. -# If you have `file' or equivalent on your system and you're not sure -# whether `pass_all' will *always* work, you probably want this one. +# that responds to the $file_magic_cmd with a given extended regex. +# If you have 'file' or equivalent on your system and you're not sure +# whether 'pass_all' will *always* work, you probably want this one. case $host_os in aix[[4-9]]*) @@ -3214,15 +3466,14 @@ cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' - lt_cv_deplibs_check_method=pass_all + lt_cv_deplibs_check_method=pass_all # SDL customization ;; -mingw* | pw32*) +mingw* | windows* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. - # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. - if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then + if ( file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else @@ -3230,7 +3481,7 @@ mingw* | pw32*) lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi - lt_cv_deplibs_check_method=pass_all + lt_cv_deplibs_check_method=pass_all # SDL customization ;; cegcc*) @@ -3243,7 +3494,7 @@ darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; -freebsd* | dragonfly*) +freebsd* | dragonfly* | midnightbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) @@ -3259,10 +3510,6 @@ freebsd* | dragonfly*) fi ;; -gnu*) - lt_cv_deplibs_check_method=pass_all - ;; - haiku*) lt_cv_deplibs_check_method=pass_all ;; @@ -3301,7 +3548,7 @@ irix5* | irix6* | nonstopux*) ;; # This must be glibc/ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu) +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; @@ -3323,8 +3570,8 @@ newos6*) lt_cv_deplibs_check_method=pass_all ;; -openbsd*) - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then +openbsd* | bitrig*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' @@ -3377,6 +3624,9 @@ sysv4 | sysv4.3*) tpf*) lt_cv_deplibs_check_method=pass_all ;; +os2*) + lt_cv_deplibs_check_method=pass_all + ;; esac ]) @@ -3384,7 +3634,7 @@ file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in - mingw* | pw32*) + mingw* | windows* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else @@ -3417,33 +3667,38 @@ AC_DEFUN([LT_PATH_NM], AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, [if test -n "$NM"; then # Let the user override the test. - lt_cv_path_NM="$NM" + lt_cv_path_NM=$NM else - lt_nm_to_check="${ac_tool_prefix}nm" + lt_nm_to_check=${ac_tool_prefix}nm if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. - tmp_nm="$ac_dir/$lt_tmp_nm" - if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + tmp_nm=$ac_dir/$lt_tmp_nm + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then # Check to see if the nm accepts a BSD-compat flag. - # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # Adding the 'sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file - case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in - */dev/null* | *'Invalid file or object type'*) + # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty + case $build_os in + mingw* | windows*) lt_bad_file=conftest.nm/nofile ;; + *) lt_bad_file=/dev/null ;; + esac + case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in + *$lt_bad_file* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" - break + break 2 ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" - break + break 2 ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but @@ -3454,21 +3709,21 @@ else esac fi done - IFS="$lt_save_ifs" + IFS=$lt_save_ifs done : ${lt_cv_path_NM=no} fi]) -if test "$lt_cv_path_NM" != "no"; then - NM="$lt_cv_path_NM" +if test no != "$lt_cv_path_NM"; then + NM=$lt_cv_path_NM else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) - case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in + case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in *COFF*) - DUMPBIN="$DUMPBIN -symbols" + DUMPBIN="$DUMPBIN -symbols -headers" ;; *) DUMPBIN=: @@ -3476,8 +3731,8 @@ else esac fi AC_SUBST([DUMPBIN]) - if test "$DUMPBIN" != ":"; then - NM="$DUMPBIN" + if test : != "$DUMPBIN"; then + NM=$DUMPBIN fi fi test -z "$NM" && NM=nm @@ -3522,9 +3777,9 @@ lt_cv_sharedlib_from_linklib_cmd, [lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in -cygwin* | mingw* | pw32* | cegcc*) - # two different shell functions defined in ltmain.sh - # decide which to use based on capabilities of $DLLTOOL +cygwin* | mingw* | windows* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh; + # decide which one to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib @@ -3536,7 +3791,7 @@ cygwin* | mingw* | pw32* | cegcc*) ;; *) # fallback: assume linklib IS sharedlib - lt_cv_sharedlib_from_linklib_cmd="$ECHO" + lt_cv_sharedlib_from_linklib_cmd=$ECHO ;; esac ]) @@ -3563,13 +3818,28 @@ AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool lt_cv_path_mainfest_tool=yes fi rm -f conftest*]) -if test "x$lt_cv_path_mainfest_tool" != xyes; then +if test yes != "$lt_cv_path_mainfest_tool"; then MANIFEST_TOOL=: fi _LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl ])# _LT_PATH_MANIFEST_TOOL +# _LT_DLL_DEF_P([FILE]) +# --------------------- +# True iff FILE is a Windows DLL '.def' file. +# Keep in sync with func_dll_def_p in the libtool script +AC_DEFUN([_LT_DLL_DEF_P], +[dnl + test DEF = "`$SED -n dnl + -e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace + -e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments + -e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl + -e q dnl Only consider the first "real" line + $1`" dnl +])# _LT_DLL_DEF_P + + # LT_LIB_M # -------- # check for math library @@ -3577,15 +3847,15 @@ AC_DEFUN([LT_LIB_M], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in -*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) +*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-mingw* | *-*-pw32* | *-*-darwin*) # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) - AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw) AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ;; *) - AC_CHECK_LIB(m, cos, LIBM="-lm") + AC_CHECK_LIB(m, cos, LIBM=-lm) ;; esac AC_SUBST([LIBM]) @@ -3604,7 +3874,7 @@ m4_defun([_LT_COMPILER_NO_RTTI], _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= -if test "$GCC" = yes; then +if test yes = "$GCC"; then case $cc_basename in nvcc*) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; @@ -3652,11 +3922,11 @@ case $host_os in aix*) symcode='[[BCDT]]' ;; -cygwin* | mingw* | pw32* | cegcc*) +cygwin* | mingw* | windows* | pw32* | cegcc*) symcode='[[ABCDGISTW]]' ;; hpux*) - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then symcode='[[ABCDEGRST]]' fi ;; @@ -3667,7 +3937,7 @@ osf*) symcode='[[BCDEGQRST]]' ;; solaris*) - symcode='[[BDRT]]' + symcode='[[BCDRT]]' ;; sco3.2v5*) symcode='[[DT]]' @@ -3689,19 +3959,49 @@ case `$NM -V 2>&1` in symcode='[[ABCDGIRSTW]]' ;; esac +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Gets list of data symbols to import. + lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" + # Adjust the below global symbol transforms to fixup imported variables. + lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" + lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" + lt_c_name_lib_hook="\ + -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ + -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" +else + # Disable hooks by default. + lt_cv_sys_global_symbol_to_import= + lt_cdecl_hook= + lt_c_name_hook= + lt_c_name_lib_hook= +fi + # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. -lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" +lt_cv_sys_global_symbol_to_cdecl="sed -n"\ +$lt_cdecl_hook\ +" -e 's/^T .* \(.*\)$/extern int \1();/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address -lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ +$lt_c_name_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" + +# Transform an extracted symbol line into symbol name with lib prefix and +# symbol address. +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ +$lt_c_name_lib_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in -mingw*) +mingw* | windows*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac @@ -3714,21 +4014,24 @@ for ac_symprfx in "" "_"; do # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then - # Fake it for dumpbin and say T for any non-static function - # and D for any global variable. - # Also find C++ and __fastcall symbols from MSVC++, + # Fake it for dumpbin and say T for any non-static function, + # D for any global variable and I for any imported variable. + # Also find C++ and __fastcall symbols from MSVC++ or ICC, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ +" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ +" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ -" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ -" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ -" s[1]~/^[@?]/{print s[1], s[1]; next};"\ -" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ +" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ +" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx]" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" @@ -3768,11 +4071,11 @@ _LT_EOF if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ -#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) -/* DATA imports from DLLs on WIN32 con't be const, because runtime +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT@&t@_DLSYM_CONST -#elif defined(__osf__) +#elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT@&t@_DLSYM_CONST #else @@ -3798,7 +4101,7 @@ lt__PROGRAM__LTX_preloaded_symbols[[]] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF - $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; @@ -3818,9 +4121,9 @@ _LT_EOF mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS - LIBS="conftstm.$ac_objext" + LIBS=conftstm.$ac_objext CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" - if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then + if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS @@ -3841,7 +4144,7 @@ _LT_EOF rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. - if test "$pipe_works" = yes; then + if test yes = "$pipe_works"; then break else lt_cv_sys_global_symbol_pipe= @@ -3868,12 +4171,16 @@ _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], [Take the output of nm and produce a listing of raw symbols and C names]) _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], [Transform the output of nm in a proper C declaration]) +_LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1], + [Transform the output of nm into a list of symbols to manually relocate]) _LT_DECL([global_symbol_to_c_name_address], [lt_cv_sys_global_symbol_to_c_name_address], [1], [Transform the output of nm in a C name address pair]) _LT_DECL([global_symbol_to_c_name_address_lib_prefix], [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], [Transform the output of nm in a C name address pair when lib prefix is needed]) +_LT_DECL([nm_interface], [lt_cv_nm_interface], [1], + [The name lister interface]) _LT_DECL([], [nm_file_list_spec], [1], [Specify filename containing input files for $NM]) ]) # _LT_CMD_GLOBAL_SYMBOLS @@ -3889,17 +4196,18 @@ _LT_TAGVAR(lt_prog_compiler_static, $1)= m4_if([$1], [CXX], [ # C++ specific cases for pic, static, wl, etc. - if test "$GXX" = yes; then + if test yes = "$GXX"; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; amigaos*) @@ -3910,8 +4218,8 @@ m4_if([$1], [CXX], [ ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac @@ -3920,13 +4228,18 @@ m4_if([$1], [CXX], [ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; - mingw* | cygwin* | os2* | pw32* | cegcc*) + mingw* | windows* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + case $host_os in + os2*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' + ;; + esac ;; darwin* | rhapsody*) # PIC is the default on this platform @@ -3976,7 +4289,7 @@ m4_if([$1], [CXX], [ case $host_os in aix[[4-9]]*) # All AIX code is PIC. - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else @@ -3991,7 +4304,7 @@ m4_if([$1], [CXX], [ ;; esac ;; - mingw* | cygwin* | os2* | pw32* | cegcc*) + mingw* | windows* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], @@ -4010,21 +4323,21 @@ m4_if([$1], [CXX], [ ;; esac ;; - freebsd* | dragonfly*) + freebsd* | dragonfly* | midnightbsd*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' - if test "$host_cpu" != ia64; then + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' + if test ia64 != "$host_cpu"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' fi ;; aCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default @@ -4053,7 +4366,7 @@ m4_if([$1], [CXX], [ ;; esac ;; - linux* | k*bsd*-gnu | kopensolaris*-gnu) + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # KAI C++ Compiler @@ -4061,7 +4374,7 @@ m4_if([$1], [CXX], [ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; ecpc* ) - # old Intel C++ for x86_64 which still supported -KPIC. + # old Intel C++ for x86_64, which still supported -KPIC. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' @@ -4206,17 +4519,18 @@ m4_if([$1], [CXX], [ fi ], [ - if test "$GCC" = yes; then + if test yes = "$GCC"; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; amigaos*) @@ -4227,8 +4541,8 @@ m4_if([$1], [CXX], [ ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac @@ -4238,13 +4552,18 @@ m4_if([$1], [CXX], [ # PIC is the default for these OSes. ;; - mingw* | cygwin* | pw32* | os2* | cegcc*) + mingw* | windows* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + case $host_os in + os2*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' + ;; + esac ;; darwin* | rhapsody*) @@ -4315,7 +4634,7 @@ m4_if([$1], [CXX], [ case $host_os in aix*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else @@ -4323,11 +4642,30 @@ m4_if([$1], [CXX], [ fi ;; - mingw* | cygwin* | pw32* | os2* | cegcc*) + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + case $cc_basename in + nagfor*) + # NAG Fortran compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + + mingw* | windows* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + case $host_os in + os2*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' + ;; + esac ;; hpux9* | hpux10* | hpux11*) @@ -4343,7 +4681,7 @@ m4_if([$1], [CXX], [ ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? - _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) @@ -4352,9 +4690,9 @@ m4_if([$1], [CXX], [ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; - linux* | k*bsd*-gnu | kopensolaris*-gnu) + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in - # old Intel for x86_64 which still supported -KPIC. + # old Intel for x86_64, which still supported -KPIC. ecc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' @@ -4379,6 +4717,12 @@ m4_if([$1], [CXX], [ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) @@ -4476,7 +4820,7 @@ m4_if([$1], [CXX], [ ;; sysv4*MP*) - if test -d /usr/nec ;then + if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi @@ -4505,7 +4849,7 @@ m4_if([$1], [CXX], [ fi ]) case $host_os in - # For platforms which do not support PIC, -DPIC is meaningless: + # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; @@ -4571,21 +4915,25 @@ m4_if([$1], [CXX], [ case $host_os in aix[[4-9]]*) # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - # Also, AIX nm treats weak defined symbols like other global defined - # symbols, whereas GNU nm marks them as "W". + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi ;; pw32*) - _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" + _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds ;; - cygwin* | mingw* | cegcc*) + cygwin* | mingw* | windows* | cegcc*) case $cc_basename in - cl*) + cl* | icl*) _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) @@ -4627,9 +4975,9 @@ m4_if([$1], [CXX], [ # included in the symbol list _LT_TAGVAR(include_expsyms, $1)= # exclude_expsyms can be an extended regexp of symbols to exclude - # it will be wrapped by ` (' and `)$', so one must not match beginning or - # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', - # as well as any symbol that contains `d'. + # it will be wrapped by ' (' and ')$', so one must not match beginning or + # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', + # as well as any symbol that contains 'd'. _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if @@ -4641,19 +4989,19 @@ dnl Note also adjust exclude_expsyms for C++ above. extract_expsyms_cmds= case $host_os in - cygwin* | mingw* | pw32* | cegcc*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time + cygwin* | mingw* | windows* | pw32* | cegcc*) + # FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - if test "$GCC" != yes; then + # Microsoft Visual C++ or Intel C++ Compiler. + if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) - # we just hope/assume this is gcc and not c89 (= MSVC++) + # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC) with_gnu_ld=yes ;; - openbsd*) + openbsd* | bitrig*) with_gnu_ld=no ;; esac @@ -4663,7 +5011,7 @@ dnl Note also adjust exclude_expsyms for C++ above. # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no - if test "$with_gnu_ld" = yes; then + if test yes = "$with_gnu_ld"; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility @@ -4685,24 +5033,24 @@ dnl Note also adjust exclude_expsyms for C++ above. esac fi - if test "$lt_use_gnu_ld_interface" = yes; then + if test yes = "$lt_use_gnu_ld_interface"; then # If archive_cmds runs LD, not CC, wlarc should be empty - wlarc='${wl}' + wlarc='$wl' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then - _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no - case `$LD -v 2>&1` in + case `$LD -v | $SED -e 's/([[^)]]\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... @@ -4715,7 +5063,7 @@ dnl Note also adjust exclude_expsyms for C++ above. case $host_os in aix[[3-9]]*) # On AIX/PPC, the GNU linker is very broken - if test "$host_cpu" != ia64; then + if test ia64 != "$host_cpu"; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 @@ -4734,7 +5082,7 @@ _LT_EOF case $host_cpu in powerpc) # see comment about AmigaOS4 .so support - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) @@ -4750,17 +5098,17 @@ _LT_EOF _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME - _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; - cygwin* | mingw* | pw32* | cegcc*) + cygwin* | mingw* | windows* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes @@ -4768,61 +5116,90 @@ _LT_EOF _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; haiku*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + shrext_cmds=.dll + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + ;; + interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no - if test "$host_os" = linux-dietlibc; then + if test linux-dietlibc = "$host_os"; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ - && test "$tmp_diet" = no + && test no = "$tmp_diet" then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; @@ -4833,42 +5210,47 @@ _LT_EOF lf95*) # Lahey Fortran 8.1 _LT_TAGVAR(whole_archive_flag_spec, $1)= tmp_sharedflag='--shared' ;; + nagfor*) # NAGFOR 5.3 + tmp_sharedflag='-Wl,-shared' ;; xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac - _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then + if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi case $cc_basename in + tcc*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic' + ;; xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then + if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac @@ -4882,8 +5264,8 @@ _LT_EOF _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' fi ;; @@ -4901,8 +5283,8 @@ _LT_EOF _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi @@ -4914,7 +5296,7 @@ _LT_EOF _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 -*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify @@ -4929,9 +5311,9 @@ _LT_EOF # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi @@ -4948,15 +5330,15 @@ _LT_EOF *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac - if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then + if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then runpath_var= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= @@ -4972,7 +5354,7 @@ _LT_EOF # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. _LT_TAGVAR(hardcode_minus_L, $1)=yes - if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. _LT_TAGVAR(hardcode_direct, $1)=unsupported @@ -4980,34 +5362,57 @@ _LT_EOF ;; aix[[4-9]]*) - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' - no_entry_flag="" + no_entry_flag= else # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - # Also, AIX nm treats weak defined symbols like other global - # defined symbols, whereas GNU nm marks them as "W". + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else - _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do - if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then aix_use_runtimelinking=yes break fi done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi ;; esac @@ -5026,13 +5431,21 @@ _LT_EOF _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + _LT_TAGVAR(file_list_spec, $1)='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # traditional, no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + ;; + esac - if test "$GCC" = yes; then + if test yes = "$GCC"; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` + collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then @@ -5051,61 +5464,80 @@ _LT_EOF ;; esac shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' + if test yes = "$aix_use_runtimelinking"; then + shared_flag="$shared_flag "'$wl-G' fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' else # not using gcc - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' else - shared_flag='${wl}-bM:SRE' + shared_flag='$wl-bM:SRE' fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' fi fi - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. _LT_TAGVAR(always_export_symbols, $1)=yes - if test "$aix_use_runtimelinking" = yes; then + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else - if test "$host_cpu" = ia64; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + if test ia64 = "$host_cpu"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' - if test "$with_gnu_ld" = yes; then + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' + if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - # This is similar to how AIX traditionally builds its shared libraries. - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' fi fi ;; @@ -5114,7 +5546,7 @@ _LT_EOF case $host_cpu in powerpc) # see comment about AmigaOS4 .so support - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) @@ -5129,14 +5561,14 @@ _LT_EOF _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ;; - cygwin* | mingw* | pw32* | cegcc*) + cygwin* | mingw* | windows* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. + # Microsoft Visual C++ or Intel C++ Compiler. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in - cl*) - # Native MSVC + cl* | icl*) + # Native MSVC or ICC _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes @@ -5144,16 +5576,17 @@ _LT_EOF # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" + shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. - _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; - else - sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; - fi~ - $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ - linknames=' + _LT_TAGVAR(archive_cmds, $1)='$CC -Fe $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -Fe $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes @@ -5162,27 +5595,27 @@ _LT_EOF # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ - lt_tool_outputfile="@TOOL_OUTPUT@"~ - case $lt_outputfile in - *.exe|*.EXE) ;; - *) - lt_outputfile="$lt_outputfile.exe" - lt_tool_outputfile="$lt_tool_outputfile.exe" - ;; - esac~ - if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then - $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; - $RM "$lt_outputfile.manifest"; - fi' + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' ;; *) - # Assume MSVC wrapper + # Assume MSVC and ICC wrapper _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" + shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. @@ -5224,7 +5657,7 @@ _LT_EOF ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | dragonfly*) + freebsd* | dragonfly* | midnightbsd*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes @@ -5232,33 +5665,33 @@ _LT_EOF ;; hpux9*) - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ;; hpux10*) - if test "$GCC" = yes && test "$with_gnu_ld" = no; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + if test yes,no = "$GCC,$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi - if test "$with_gnu_ld" = no; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes @@ -5266,25 +5699,25 @@ _LT_EOF ;; hpux11*) - if test "$GCC" = yes && test "$with_gnu_ld" = no; then + if test yes,no = "$GCC,$with_gnu_ld"; then case $host_cpu in hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) m4_if($1, [], [ @@ -5292,14 +5725,14 @@ _LT_EOF # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) _LT_LINKER_OPTION([if $CC understands -b], _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], - [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], - [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) + [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) ;; esac fi - if test "$with_gnu_ld" = no; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in @@ -5310,7 +5743,7 @@ _LT_EOF *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. @@ -5321,16 +5754,16 @@ _LT_EOF ;; irix5* | irix6* | nonstopux*) - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], [lt_cv_irix_exported_symbol], - [save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + [save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" AC_LINK_IFELSE( [AC_LANG_SOURCE( [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], @@ -5343,21 +5776,31 @@ _LT_EOF end]])])], [lt_cv_irix_exported_symbol=yes], [lt_cv_irix_exported_symbol=no]) - LDFLAGS="$save_LDFLAGS"]) - if test "$lt_cv_irix_exported_symbol" = yes; then - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' + LDFLAGS=$save_LDFLAGS]) + if test yes = "$lt_cv_irix_exported_symbol"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' fi else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes _LT_TAGVAR(link_all_deplibs, $1)=yes ;; + linux*) + case $cc_basename in + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + _LT_TAGVAR(ld_shlibs, $1)=yes + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out @@ -5372,7 +5815,7 @@ _LT_EOF newsos6) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; @@ -5380,27 +5823,19 @@ _LT_EOF *nto* | *qnx*) ;; - openbsd*) + openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' else - case $host_os in - openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) - _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - ;; - *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - ;; - esac + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' fi else _LT_TAGVAR(ld_shlibs, $1)=no @@ -5411,33 +5846,54 @@ _LT_EOF _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported - _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' - _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + shrext_cmds=.dll + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' ;; osf3*) - if test "$GCC" = yes; then - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + if test yes = "$GCC"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag - if test "$GCC" = yes; then - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + if test yes = "$GCC"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ - $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' @@ -5448,24 +5904,24 @@ _LT_EOF solaris*) _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' - if test "$GCC" = yes; then - wlarc='${wl}' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + if test yes = "$GCC"; then + wlarc='$wl' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' - _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) - wlarc='${wl}' - _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + wlarc='$wl' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi @@ -5475,11 +5931,11 @@ _LT_EOF solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, - # but understands `-z linker_flag'. GCC discards it without `$wl', + # but understands '-z linker_flag'. GCC discards it without '$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) - if test "$GCC" = yes; then - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + if test yes = "$GCC"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' else _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' fi @@ -5489,10 +5945,10 @@ _LT_EOF ;; sunos4*) - if test "x$host_vendor" = xsequent; then + if test sequent = "$host_vendor"; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi @@ -5541,43 +5997,43 @@ _LT_EOF ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) - # Note: We can NOT use -z defs as we might desire, because we do not + # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' runpath_var='LD_RUN_PATH' - if test "$GCC" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; @@ -5592,17 +6048,17 @@ _LT_EOF ;; esac - if test x$host_vendor = xsni; then + if test sni = "$host_vendor"; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym' ;; esac fi fi ]) AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) -test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no +test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no _LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld @@ -5619,7 +6075,7 @@ x|xyes) # Assume -lc should be added _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - if test "$enable_shared" = yes && test "$GCC" = yes; then + if test yes,yes = "$GCC,$enable_shared"; then case $_LT_TAGVAR(archive_cmds, $1) in *'~'*) # FIXME: we may have to deal with multi-command sequences. @@ -5699,12 +6155,12 @@ _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], _LT_TAGDECL([], [hardcode_libdir_separator], [1], [Whether we need a single "-rpath" flag with a separated argument]) _LT_TAGDECL([], [hardcode_direct], [0], - [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_direct_absolute], [0], - [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes + [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes DIR into the resulting binary and the resulting library dependency is - "absolute", i.e impossible to change by setting ${shlibpath_var} if the + "absolute", i.e impossible to change by setting $shlibpath_var if the library is relocated]) _LT_TAGDECL([], [hardcode_minus_L], [0], [Set to "yes" if using the -LDIR flag during linking hardcodes DIR @@ -5745,10 +6201,10 @@ dnl [Compiler flag to generate thread safe objects]) # ------------------------ # Ensure that the configuration variables for a C compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write -# the compiler configuration to `libtool'. +# the compiler configuration to 'libtool'. m4_defun([_LT_LANG_C_CONFIG], [m4_require([_LT_DECL_EGREP])dnl -lt_save_CC="$CC" +lt_save_CC=$CC AC_LANG_PUSH(C) # Source file extension for C test sources. @@ -5788,18 +6244,18 @@ if test -n "$compiler"; then LT_SYS_DLOPEN_SELF _LT_CMD_STRIPLIB - # Report which library types will actually be built + # Report what library types will actually be built AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) - test "$can_build_shared" = "no" && enable_shared=no + test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) - test "$enable_shared" = yes && enable_static=no + test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' @@ -5807,8 +6263,12 @@ if test -n "$compiler"; then ;; aix[[4-9]]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac fi ;; esac @@ -5816,13 +6276,13 @@ if test -n "$compiler"; then AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes + test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_CONFIG($1) fi AC_LANG_POP -CC="$lt_save_CC" +CC=$lt_save_CC ])# _LT_LANG_C_CONFIG @@ -5830,14 +6290,14 @@ CC="$lt_save_CC" # -------------------------- # Ensure that the configuration variables for a C++ compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write -# the compiler configuration to `libtool'. +# the compiler configuration to 'libtool'. m4_defun([_LT_LANG_CXX_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl -if test -n "$CXX" && ( test "X$CXX" != "Xno" && - ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || - (test "X$CXX" != "Xg++"))) ; then +if test -n "$CXX" && ( test no != "$CXX" && + ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || + (test g++ != "$CXX"))); then AC_PROG_CXXCPP else _lt_caught_CXX_error=yes @@ -5879,7 +6339,7 @@ _LT_TAGVAR(objext, $1)=$objext # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. -if test "$_lt_caught_CXX_error" != yes; then +if test yes != "$_lt_caught_CXX_error"; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" @@ -5921,35 +6381,35 @@ if test "$_lt_caught_CXX_error" != yes; then if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately - if test "$GXX" = yes; then + if test yes = "$GXX"; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' else _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= fi - if test "$GXX" = yes; then + if test yes = "$GXX"; then # Set up default GNU C++ configuration LT_PATH_LD # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. - if test "$with_gnu_ld" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + if test yes = "$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) - wlarc='${wl}' + wlarc='$wl' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then - _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi @@ -5968,7 +6428,7 @@ if test "$_lt_caught_CXX_error" != yes; then # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "[[-]]L"' else GXX=no @@ -5985,18 +6445,30 @@ if test "$_lt_caught_CXX_error" != yes; then _LT_TAGVAR(ld_shlibs, $1)=no ;; aix[[4-9]]*) - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' - no_entry_flag="" + no_entry_flag= else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do case $ld_flag in @@ -6006,6 +6478,13 @@ if test "$_lt_caught_CXX_error" != yes; then ;; esac done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi ;; esac @@ -6024,13 +6503,21 @@ if test "$_lt_caught_CXX_error" != yes; then _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' + _LT_TAGVAR(file_list_spec, $1)='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + ;; + esac - if test "$GXX" = yes; then + if test yes = "$GXX"; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` + collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then @@ -6048,64 +6535,84 @@ if test "$_lt_caught_CXX_error" != yes; then fi esac shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' + if test yes = "$aix_use_runtimelinking"; then + shared_flag=$shared_flag' $wl-G' fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' else # not using gcc - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' else - shared_flag='${wl}-bM:SRE' + shared_flag='$wl-bM:SRE' fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' fi fi - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. _LT_TAGVAR(always_export_symbols, $1)=yes - if test "$aix_use_runtimelinking" = yes; then + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # The "-G" linker flag allows undefined symbols. + _LT_TAGVAR(no_undefined_flag, $1)='-bernotok' # Determine the default libpath from the value encoded in an empty # executable. _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else - if test "$host_cpu" = ia64; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + if test ia64 = "$host_cpu"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. - _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' - if test "$with_gnu_ld" = yes; then + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' + if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes - # This is similar to how AIX traditionally builds its shared - # libraries. - _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared + # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' fi fi ;; @@ -6115,7 +6622,7 @@ if test "$_lt_caught_CXX_error" != yes; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME - _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi @@ -6130,10 +6637,10 @@ if test "$_lt_caught_CXX_error" != yes; then esac ;; - cygwin* | mingw* | pw32* | cegcc*) + cygwin* | mingw* | windows* | pw32* | cegcc*) case $GXX,$cc_basename in - ,cl* | no,cl*) - # Native MSVC + ,cl* | no,cl* | ,icl* | no,icl*) + # Native MSVC or ICC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' @@ -6143,57 +6650,58 @@ if test "$_lt_caught_CXX_error" != yes; then # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" + shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. - _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; - else - $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; - fi~ - $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ - linknames=' + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ - lt_tool_outputfile="@TOOL_OUTPUT@"~ - case $lt_outputfile in - *.exe|*.EXE) ;; - *) - lt_outputfile="$lt_outputfile.exe" - lt_tool_outputfile="$lt_tool_outputfile.exe" - ;; - esac~ - func_to_tool_file "$lt_outputfile"~ - if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then - $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; - $RM "$lt_outputfile.manifest"; - fi' + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi @@ -6204,6 +6712,35 @@ if test "$_lt_caught_CXX_error" != yes; then _LT_DARWIN_LINKER_FEATURES($1) ;; + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + shrext_cmds=.dll + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + ;; + dgux*) case $cc_basename in ec++*) @@ -6232,24 +6769,21 @@ if test "$_lt_caught_CXX_error" != yes; then _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; - freebsd* | dragonfly*) + freebsd* | dragonfly* | midnightbsd*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_TAGVAR(ld_shlibs, $1)=yes ;; - gnu*) - ;; - haiku*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; hpux9*) - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default @@ -6261,7 +6795,7 @@ if test "$_lt_caught_CXX_error" != yes; then _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. @@ -6270,11 +6804,11 @@ if test "$_lt_caught_CXX_error" != yes; then # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "[[-]]L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) - if test "$GXX" = yes; then - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + if test yes = "$GXX"; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no @@ -6284,15 +6818,15 @@ if test "$_lt_caught_CXX_error" != yes; then ;; hpux10*|hpux11*) - if test $with_gnu_ld = no; then - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) ;; *) - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' ;; esac fi @@ -6318,13 +6852,13 @@ if test "$_lt_caught_CXX_error" != yes; then aCC*) case $host_cpu in hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) - _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists @@ -6335,20 +6869,20 @@ if test "$_lt_caught_CXX_error" != yes; then # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "[[-]]L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) - if test "$GXX" = yes; then - if test $with_gnu_ld = no; then + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then case $host_cpu in hppa*64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi @@ -6363,22 +6897,22 @@ if test "$_lt_caught_CXX_error" != yes; then interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is @@ -6387,22 +6921,22 @@ if test "$_lt_caught_CXX_error" != yes; then _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) - if test "$GXX" = yes; then - if test "$with_gnu_ld" = no; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' fi fi _LT_TAGVAR(link_all_deplibs, $1)=yes ;; esac - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes ;; - linux* | k*bsd*-gnu | kopensolaris*-gnu) + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler @@ -6410,8 +6944,8 @@ if test "$_lt_caught_CXX_error" != yes; then # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. - _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. @@ -6420,10 +6954,10 @@ if test "$_lt_caught_CXX_error" != yes; then # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. @@ -6437,59 +6971,59 @@ if test "$_lt_caught_CXX_error" != yes; then # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac - _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(archive_cmds_need_lc, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ - compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ - $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ - $RANLIB $oldlib' + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ - $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ - $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' ;; cxx*) # Compaq C++ - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' @@ -6503,18 +7037,18 @@ if test "$_lt_caught_CXX_error" != yes; then # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi ;; *) @@ -6522,10 +7056,10 @@ if test "$_lt_caught_CXX_error" != yes; then *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' - _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes # Not sure whether something based on @@ -6583,22 +7117,17 @@ if test "$_lt_caught_CXX_error" != yes; then _LT_TAGVAR(ld_shlibs, $1)=yes ;; - openbsd2*) - # C++ shared libraries are fairly broken - _LT_TAGVAR(ld_shlibs, $1)=no - ;; - - openbsd*) + openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else @@ -6614,9 +7143,9 @@ if test "$_lt_caught_CXX_error" != yes; then # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. - _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Archives containing C++ object files must be created using @@ -6634,17 +7163,17 @@ if test "$_lt_caught_CXX_error" != yes; then cxx*) case $host in osf3*) - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ;; *) _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' - _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ - echo "-hidden">> $lib.exp~ - $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ - $RM $lib.exp' + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ + $RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ;; esac @@ -6659,27 +7188,27 @@ if test "$_lt_caught_CXX_error" != yes; then # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + if test yes,no = "$GXX,$with_gnu_ld"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' case $host in osf3*) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; esac - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "[[-]]L"' else # FIXME: insert proper C++ library support @@ -6719,9 +7248,9 @@ if test "$_lt_caught_CXX_error" != yes; then # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' - _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no @@ -6729,7 +7258,7 @@ if test "$_lt_caught_CXX_error" != yes; then solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, - # but understands `-z linker_flag'. + # but understands '-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; @@ -6746,42 +7275,42 @@ if test "$_lt_caught_CXX_error" != yes; then ;; gcx*) # Green Hills C++ Compiler - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' + if test yes,no = "$GXX,$with_gnu_ld"; then + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then - _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "[[-]]L"' else - # g++ 2.7 appears to require `-G' NOT `-shared' on this + # g++ 2.7 appears to require '-G' NOT '-shared' on this # platform. - _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "[[-]]L"' fi - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) - _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' ;; esac fi @@ -6790,52 +7319,52 @@ if test "$_lt_caught_CXX_error" != yes; then ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) - # Note: We can NOT use -z defs as we might desire, because we do not + # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. - _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' - _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes - _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) - _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ - '"$_LT_TAGVAR(old_archive_cmds, $1)" + '"$_LT_TAGVAR(old_archive_cmds, $1)" _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ - '"$_LT_TAGVAR(reload_cmds, $1)" + '"$_LT_TAGVAR(reload_cmds, $1)" ;; *) - _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; @@ -6866,10 +7395,10 @@ if test "$_lt_caught_CXX_error" != yes; then esac AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) - test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no - _LT_TAGVAR(GCC, $1)="$GXX" - _LT_TAGVAR(LD, $1)="$LD" + _LT_TAGVAR(GCC, $1)=$GXX + _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change @@ -6896,7 +7425,7 @@ if test "$_lt_caught_CXX_error" != yes; then lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld -fi # test "$_lt_caught_CXX_error" != yes +fi # test yes != "$_lt_caught_CXX_error" AC_LANG_POP ])# _LT_LANG_CXX_CONFIG @@ -6918,13 +7447,14 @@ AC_REQUIRE([_LT_DECL_SED]) AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) func_stripname_cnf () { - case ${2} in - .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; - *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; + case @S|@2 in + .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;; + *) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;; esac } # func_stripname_cnf ])# _LT_FUNC_STRIPNAME_CNF + # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) # --------------------------------- # Figure out "hidden" library dependencies from verbose @@ -7008,13 +7538,14 @@ if AC_TRY_EVAL(ac_compile); then pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do - case ${prev}${p} in + case $prev$p in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. - if test $p = "-L" || - test $p = "-R"; then + if test x-L = "x$p" || + test x-R = "x$p" || + test x-l = "x$p"; then prev=$p continue fi @@ -7030,16 +7561,16 @@ if AC_TRY_EVAL(ac_compile); then case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac - if test "$pre_test_object_deps_done" = no; then - case ${prev} in + if test no = "$pre_test_object_deps_done"; then + case $prev in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then - _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" + _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p else - _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" + _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p" fi ;; # The "-l" case would never come before the object being @@ -7047,9 +7578,9 @@ if AC_TRY_EVAL(ac_compile); then esac else if test -z "$_LT_TAGVAR(postdeps, $1)"; then - _LT_TAGVAR(postdeps, $1)="${prev}${p}" + _LT_TAGVAR(postdeps, $1)=$prev$p else - _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" + _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p" fi fi prev= @@ -7064,15 +7595,15 @@ if AC_TRY_EVAL(ac_compile); then continue fi - if test "$pre_test_object_deps_done" = no; then + if test no = "$pre_test_object_deps_done"; then if test -z "$_LT_TAGVAR(predep_objects, $1)"; then - _LT_TAGVAR(predep_objects, $1)="$p" + _LT_TAGVAR(predep_objects, $1)=$p else _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" fi else if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then - _LT_TAGVAR(postdep_objects, $1)="$p" + _LT_TAGVAR(postdep_objects, $1)=$p else _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" fi @@ -7103,51 +7634,6 @@ interix[[3-9]]*) _LT_TAGVAR(postdep_objects,$1)= _LT_TAGVAR(postdeps,$1)= ;; - -linux*) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C++ 5.9 - - # The more standards-conforming stlport4 library is - # incompatible with the Cstd library. Avoid specifying - # it if it's in CXXFLAGS. Ignore libCrun as - # -library=stlport4 depends on it. - case " $CXX $CXXFLAGS " in - *" -library=stlport4 "*) - solaris_use_stlport4=yes - ;; - esac - - if test "$solaris_use_stlport4" != yes; then - _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' - fi - ;; - esac - ;; - -solaris*) - case $cc_basename in - CC* | sunCC*) - # The more standards-conforming stlport4 library is - # incompatible with the Cstd library. Avoid specifying - # it if it's in CXXFLAGS. Ignore libCrun as - # -library=stlport4 depends on it. - case " $CXX $CXXFLAGS " in - *" -library=stlport4 "*) - solaris_use_stlport4=yes - ;; - esac - - # Adding this requires a known-good setup of shared libraries for - # Sun compiler versions before 5.6, else PIC objects from an old - # archive will be linked into the output, leading to subtle bugs. - if test "$solaris_use_stlport4" != yes; then - _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' - fi - ;; - esac - ;; esac ]) @@ -7156,7 +7642,7 @@ case " $_LT_TAGVAR(postdeps, $1) " in esac _LT_TAGVAR(compiler_lib_search_dirs, $1)= if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then - _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` + _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'` fi _LT_TAGDECL([], [compiler_lib_search_dirs], [1], [The directories searched by this compiler when creating a shared library]) @@ -7176,10 +7662,10 @@ _LT_TAGDECL([], [compiler_lib_search_path], [1], # -------------------------- # Ensure that the configuration variables for a Fortran 77 compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. +# to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_F77_CONFIG], [AC_LANG_PUSH(Fortran 77) -if test -z "$F77" || test "X$F77" = "Xno"; then +if test -z "$F77" || test no = "$F77"; then _lt_disable_F77=yes fi @@ -7216,7 +7702,7 @@ _LT_TAGVAR(objext, $1)=$objext # the F77 compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. -if test "$_lt_disable_F77" != yes; then +if test yes != "$_lt_disable_F77"; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t @@ -7238,7 +7724,7 @@ if test "$_lt_disable_F77" != yes; then _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. - lt_save_CC="$CC" + lt_save_CC=$CC lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${F77-"f77"} @@ -7252,21 +7738,25 @@ if test "$_lt_disable_F77" != yes; then AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) - test "$can_build_shared" = "no" && enable_shared=no + test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) - test "$enable_shared" = yes && enable_static=no + test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac fi ;; esac @@ -7274,11 +7764,11 @@ if test "$_lt_disable_F77" != yes; then AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes + test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) - _LT_TAGVAR(GCC, $1)="$G77" - _LT_TAGVAR(LD, $1)="$LD" + _LT_TAGVAR(GCC, $1)=$G77 + _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change @@ -7295,9 +7785,9 @@ if test "$_lt_disable_F77" != yes; then fi # test -n "$compiler" GCC=$lt_save_GCC - CC="$lt_save_CC" - CFLAGS="$lt_save_CFLAGS" -fi # test "$_lt_disable_F77" != yes + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS +fi # test yes != "$_lt_disable_F77" AC_LANG_POP ])# _LT_LANG_F77_CONFIG @@ -7307,11 +7797,11 @@ AC_LANG_POP # ------------------------- # Ensure that the configuration variables for a Fortran compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. +# to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_FC_CONFIG], [AC_LANG_PUSH(Fortran) -if test -z "$FC" || test "X$FC" = "Xno"; then +if test -z "$FC" || test no = "$FC"; then _lt_disable_FC=yes fi @@ -7348,7 +7838,7 @@ _LT_TAGVAR(objext, $1)=$objext # the FC compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. -if test "$_lt_disable_FC" != yes; then +if test yes != "$_lt_disable_FC"; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t @@ -7370,7 +7860,7 @@ if test "$_lt_disable_FC" != yes; then _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. - lt_save_CC="$CC" + lt_save_CC=$CC lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${FC-"f95"} @@ -7386,21 +7876,25 @@ if test "$_lt_disable_FC" != yes; then AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) - test "$can_build_shared" = "no" && enable_shared=no + test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) - test "$enable_shared" = yes && enable_static=no + test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac fi ;; esac @@ -7408,11 +7902,11 @@ if test "$_lt_disable_FC" != yes; then AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes + test yes = "$enable_shared" || enable_static=yes AC_MSG_RESULT([$enable_static]) - _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" - _LT_TAGVAR(LD, $1)="$LD" + _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu + _LT_TAGVAR(LD, $1)=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change @@ -7432,7 +7926,7 @@ if test "$_lt_disable_FC" != yes; then GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS -fi # test "$_lt_disable_FC" != yes +fi # test yes != "$_lt_disable_FC" AC_LANG_POP ])# _LT_LANG_FC_CONFIG @@ -7442,7 +7936,7 @@ AC_LANG_POP # -------------------------- # Ensure that the configuration variables for the GNU Java Compiler compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. +# to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_GCJ_CONFIG], [AC_REQUIRE([LT_PROG_GCJ])dnl AC_LANG_SAVE @@ -7476,7 +7970,7 @@ CC=${GCJ-"gcj"} CFLAGS=$GCJFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC -_LT_TAGVAR(LD, $1)="$LD" +_LT_TAGVAR(LD, $1)=$LD _LT_CC_BASENAME([$compiler]) # GCJ did not exist at the time GCC didn't implicitly link libc in. @@ -7513,7 +8007,7 @@ CFLAGS=$lt_save_CFLAGS # -------------------------- # Ensure that the configuration variables for the GNU Go compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. +# to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_GO_CONFIG], [AC_REQUIRE([LT_PROG_GO])dnl AC_LANG_SAVE @@ -7547,7 +8041,7 @@ CC=${GOC-"gccgo"} CFLAGS=$GOFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC -_LT_TAGVAR(LD, $1)="$LD" +_LT_TAGVAR(LD, $1)=$LD _LT_CC_BASENAME([$compiler]) # Go did not exist at the time GCC didn't implicitly link libc in. @@ -7584,7 +8078,7 @@ CFLAGS=$lt_save_CFLAGS # ------------------------- # Ensure that the configuration variables for the Windows resource compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. +# to write the compiler configuration to 'libtool'. m4_defun([_LT_LANG_RC_CONFIG], [AC_REQUIRE([LT_PROG_RC])dnl AC_LANG_SAVE @@ -7600,7 +8094,7 @@ _LT_TAGVAR(objext, $1)=$objext lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' # Code to be used in simple link tests -lt_simple_link_test_code="$lt_simple_compile_test_code" +lt_simple_link_test_code=$lt_simple_compile_test_code # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER @@ -7610,7 +8104,7 @@ _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. -lt_save_CC="$CC" +lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC= @@ -7639,7 +8133,7 @@ AC_DEFUN([LT_PROG_GCJ], [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], [AC_CHECK_TOOL(GCJ, gcj,) - test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" + test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2" AC_SUBST(GCJFLAGS)])])[]dnl ]) @@ -7750,7 +8244,7 @@ lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris # along with /bin/sed that truncates output. for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do - test ! -f $lt_ac_sed && continue + test ! -f "$lt_ac_sed" && continue cat /dev/null > conftest.in lt_ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >conftest.in @@ -7767,9 +8261,9 @@ for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break cmp -s conftest.out conftest.nl || break # 10000 chars as input seems more than enough - test $lt_ac_count -gt 10 && break + test 10 -lt "$lt_ac_count" && break lt_ac_count=`expr $lt_ac_count + 1` - if test $lt_ac_count -gt $lt_ac_max; then + if test "$lt_ac_count" -gt "$lt_ac_max"; then lt_ac_max=$lt_ac_count lt_cv_path_SED=$lt_ac_sed fi @@ -7793,27 +8287,7 @@ dnl AC_DEFUN([LT_AC_PROG_SED], []) # Find out whether the shell is Bourne or XSI compatible, # or has some other useful features. m4_defun([_LT_CHECK_SHELL_FEATURES], -[AC_MSG_CHECKING([whether the shell understands some XSI constructs]) -# Try some XSI features -xsi_shell=no -( _lt_dummy="a/b/c" - test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ - = c,a/b,b/c, \ - && eval 'test $(( 1 + 1 )) -eq 2 \ - && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ - && xsi_shell=yes -AC_MSG_RESULT([$xsi_shell]) -_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) - -AC_MSG_CHECKING([whether the shell understands "+="]) -lt_shell_append=no -( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ - >/dev/null 2>&1 \ - && lt_shell_append=yes -AC_MSG_RESULT([$lt_shell_append]) -_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) - -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then +[if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false @@ -7837,102 +8311,9 @@ _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl ])# _LT_CHECK_SHELL_FEATURES -# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY) -# ------------------------------------------------------ -# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and -# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY. -m4_defun([_LT_PROG_FUNCTION_REPLACE], -[dnl { -sed -e '/^$1 ()$/,/^} # $1 /c\ -$1 ()\ -{\ -m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1]) -} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: -]) - - -# _LT_PROG_REPLACE_SHELLFNS -# ------------------------- -# Replace existing portable implementations of several shell functions with -# equivalent extended shell implementations where those features are available.. -m4_defun([_LT_PROG_REPLACE_SHELLFNS], -[if test x"$xsi_shell" = xyes; then - _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl - case ${1} in - */*) func_dirname_result="${1%/*}${2}" ;; - * ) func_dirname_result="${3}" ;; - esac]) - - _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl - func_basename_result="${1##*/}"]) - - _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl - case ${1} in - */*) func_dirname_result="${1%/*}${2}" ;; - * ) func_dirname_result="${3}" ;; - esac - func_basename_result="${1##*/}"]) - - _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl - # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are - # positional parameters, so assign one to ordinary parameter first. - func_stripname_result=${3} - func_stripname_result=${func_stripname_result#"${1}"} - func_stripname_result=${func_stripname_result%"${2}"}]) - - _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl - func_split_long_opt_name=${1%%=*} - func_split_long_opt_arg=${1#*=}]) - - _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl - func_split_short_opt_arg=${1#??} - func_split_short_opt_name=${1%"$func_split_short_opt_arg"}]) - - _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl - case ${1} in - *.lo) func_lo2o_result=${1%.lo}.${objext} ;; - *) func_lo2o_result=${1} ;; - esac]) - - _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo]) - - _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))]) - - _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}]) -fi - -if test x"$lt_shell_append" = xyes; then - _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"]) - - _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl - func_quote_for_eval "${2}" -dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \ - eval "${1}+=\\\\ \\$func_quote_for_eval_result"]) - - # Save a `func_append' function call where possible by direct use of '+=' - sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") - test 0 -eq $? || _lt_function_replace_fail=: -else - # Save a `func_append' function call even when '+=' is not available - sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") - test 0 -eq $? || _lt_function_replace_fail=: -fi - -if test x"$_lt_function_replace_fail" = x":"; then - AC_MSG_WARN([Unable to substitute extended shell functions in $ofile]) -fi -]) - # _LT_PATH_CONVERSION_FUNCTIONS # ----------------------------- -# Determine which file name conversion functions should be used by +# Determine what file name conversion functions should be used by # func_to_host_file (and, implicitly, by func_to_host_path). These are needed # for certain cross-compile configurations and native mingw. m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], @@ -7943,7 +8324,7 @@ AC_CACHE_VAL(lt_cv_to_host_file_cmd, [case $host in *-*-mingw* ) case $build in - *-*-mingw* ) # actually msys + *-*-mingw* | *-*-windows* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) @@ -7956,7 +8337,7 @@ AC_CACHE_VAL(lt_cv_to_host_file_cmd, ;; *-*-cygwin* ) case $build in - *-*-mingw* ) # actually msys + *-*-mingw* | *-*-windows* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) @@ -7982,9 +8363,9 @@ AC_CACHE_VAL(lt_cv_to_tool_file_cmd, [#assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in - *-*-mingw* ) + *-*-mingw* | *-*-windows* ) case $build in - *-*-mingw* ) # actually msys + *-*-mingw* | *-*-windows* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac diff --git a/SDL2-2.0.12/acinclude/ltoptions.m4 b/SDL2-2.30.5/acinclude/ltoptions.m4 similarity index 73% rename from SDL2-2.0.12/acinclude/ltoptions.m4 rename to SDL2-2.30.5/acinclude/ltoptions.m4 index 5d9acd8..7d7e688 100644 --- a/SDL2-2.0.12/acinclude/ltoptions.m4 +++ b/SDL2-2.30.5/acinclude/ltoptions.m4 @@ -1,14 +1,14 @@ # Helper functions for option handling. -*- Autoconf -*- # -# Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, -# Inc. +# Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software +# Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. -# serial 7 ltoptions.m4 +# serial 8 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) @@ -29,7 +29,7 @@ m4_define([_LT_SET_OPTION], [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), _LT_MANGLE_DEFUN([$1], [$2]), - [m4_warning([Unknown $1 option `$2'])])[]dnl + [m4_warning([Unknown $1 option '$2'])])[]dnl ]) @@ -75,13 +75,15 @@ m4_if([$1],[LT_INIT],[ dnl dnl If no reference was made to various pairs of opposing options, then dnl we run the default mode handler for the pair. For example, if neither - dnl `shared' nor `disable-shared' was passed, we enable building of shared + dnl 'shared' nor 'disable-shared' was passed, we enable building of shared dnl archives by default: _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], - [_LT_ENABLE_FAST_INSTALL]) + [_LT_ENABLE_FAST_INSTALL]) + _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4], + [_LT_WITH_AIX_SONAME([aix])]) ]) ])# _LT_SET_OPTIONS @@ -112,7 +114,7 @@ AU_DEFUN([AC_LIBTOOL_DLOPEN], [_LT_SET_OPTION([LT_INIT], [dlopen]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you -put the `dlopen' option into LT_INIT's first parameter.]) +put the 'dlopen' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: @@ -126,7 +128,7 @@ LT_OPTION_DEFINE([LT_INIT], [win32-dll], [enable_win32_dll=yes case $host in -*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) +*-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-cegcc*) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) @@ -148,7 +150,7 @@ AU_DEFUN([AC_LIBTOOL_WIN32_DLL], _LT_SET_OPTION([LT_INIT], [win32-dll]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you -put the `win32-dll' option into LT_INIT's first parameter.]) +put the 'win32-dll' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: @@ -157,9 +159,9 @@ dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) # _LT_ENABLE_SHARED([DEFAULT]) # ---------------------------- -# implement the --enable-shared flag, and supports the `shared' and -# `disable-shared' LT_INIT options. -# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +# implement the --enable-shared flag, and supports the 'shared' and +# 'disable-shared' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_SHARED], [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([shared], @@ -172,14 +174,14 @@ AC_ARG_ENABLE([shared], *) enable_shared=no # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_shared=yes fi done - IFS="$lt_save_ifs" + IFS=$lt_save_ifs ;; esac], [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) @@ -211,9 +213,9 @@ dnl AC_DEFUN([AM_DISABLE_SHARED], []) # _LT_ENABLE_STATIC([DEFAULT]) # ---------------------------- -# implement the --enable-static flag, and support the `static' and -# `disable-static' LT_INIT options. -# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +# implement the --enable-static flag, and support the 'static' and +# 'disable-static' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_STATIC], [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([static], @@ -226,14 +228,14 @@ AC_ARG_ENABLE([static], *) enable_static=no # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_static=yes fi done - IFS="$lt_save_ifs" + IFS=$lt_save_ifs ;; esac], [enable_static=]_LT_ENABLE_STATIC_DEFAULT) @@ -265,9 +267,9 @@ dnl AC_DEFUN([AM_DISABLE_STATIC], []) # _LT_ENABLE_FAST_INSTALL([DEFAULT]) # ---------------------------------- -# implement the --enable-fast-install flag, and support the `fast-install' -# and `disable-fast-install' LT_INIT options. -# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +# implement the --enable-fast-install flag, and support the 'fast-install' +# and 'disable-fast-install' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. m4_define([_LT_ENABLE_FAST_INSTALL], [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([fast-install], @@ -280,14 +282,14 @@ AC_ARG_ENABLE([fast-install], *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done - IFS="$lt_save_ifs" + IFS=$lt_save_ifs ;; esac], [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) @@ -304,14 +306,14 @@ AU_DEFUN([AC_ENABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put -the `fast-install' option into LT_INIT's first parameter.]) +the 'fast-install' option into LT_INIT's first parameter.]) ]) AU_DEFUN([AC_DISABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put -the `disable-fast-install' option into LT_INIT's first parameter.]) +the 'disable-fast-install' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: @@ -319,11 +321,64 @@ dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) +# _LT_WITH_AIX_SONAME([DEFAULT]) +# ---------------------------------- +# implement the --with-aix-soname flag, and support the `aix-soname=aix' +# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT +# is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'. +m4_define([_LT_WITH_AIX_SONAME], +[m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl +shared_archive_member_spec= +case $host,$enable_shared in +power*-*-aix[[5-9]]*,yes) + AC_MSG_CHECKING([which variant of shared library versioning to provide]) + AC_ARG_WITH([aix-soname], + [AS_HELP_STRING([--with-aix-soname=aix|svr4|both], + [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])], + [case $withval in + aix|svr4|both) + ;; + *) + AC_MSG_ERROR([Unknown argument to --with-aix-soname]) + ;; + esac + lt_cv_with_aix_soname=$with_aix_soname], + [AC_CACHE_VAL([lt_cv_with_aix_soname], + [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT) + with_aix_soname=$lt_cv_with_aix_soname]) + AC_MSG_RESULT([$with_aix_soname]) + if test aix != "$with_aix_soname"; then + # For the AIX way of multilib, we name the shared archive member + # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', + # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. + # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, + # the AIX toolchain works better with OBJECT_MODE set (default 32). + if test 64 = "${OBJECT_MODE-32}"; then + shared_archive_member_spec=shr_64 + else + shared_archive_member_spec=shr + fi + fi + ;; +*) + with_aix_soname=aix + ;; +esac + +_LT_DECL([], [shared_archive_member_spec], [0], + [Shared archive member basename, for filename based shared library versioning on AIX])dnl +])# _LT_WITH_AIX_SONAME + +LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])]) +LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])]) +LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])]) + + # _LT_WITH_PIC([MODE]) # -------------------- -# implement the --with-pic flag, and support the `pic-only' and `no-pic' +# implement the --with-pic flag, and support the 'pic-only' and 'no-pic' # LT_INIT options. -# MODE is either `yes' or `no'. If omitted, it defaults to `both'. +# MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], @@ -334,19 +389,17 @@ m4_define([_LT_WITH_PIC], *) pic_mode=default # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for lt_pkg in $withval; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done - IFS="$lt_save_ifs" + IFS=$lt_save_ifs ;; esac], - [pic_mode=default]) - -test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) + [pic_mode=m4_default([$1], [default])]) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC @@ -359,7 +412,7 @@ AU_DEFUN([AC_LIBTOOL_PICMODE], [_LT_SET_OPTION([LT_INIT], [pic-only]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you -put the `pic-only' option into LT_INIT's first parameter.]) +put the 'pic-only' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: diff --git a/SDL2-2.0.12/acinclude/ltsugar.m4 b/SDL2-2.30.5/acinclude/ltsugar.m4 similarity index 95% rename from SDL2-2.0.12/acinclude/ltsugar.m4 rename to SDL2-2.30.5/acinclude/ltsugar.m4 index 9000a05..48bc934 100644 --- a/SDL2-2.0.12/acinclude/ltsugar.m4 +++ b/SDL2-2.30.5/acinclude/ltsugar.m4 @@ -1,6 +1,7 @@ # ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # -# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. +# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software +# Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives @@ -33,7 +34,7 @@ m4_define([_lt_join], # ------------ # Manipulate m4 lists. # These macros are necessary as long as will still need to support -# Autoconf-2.59 which quotes differently. +# Autoconf-2.59, which quotes differently. m4_define([lt_car], [[$1]]) m4_define([lt_cdr], [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], @@ -44,7 +45,7 @@ m4_define([lt_unquote], $1) # lt_append(MACRO-NAME, STRING, [SEPARATOR]) # ------------------------------------------ -# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. +# Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'. # Note that neither SEPARATOR nor STRING are expanded; they are appended # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). # No SEPARATOR is output if MACRO-NAME was previously undefined (different diff --git a/SDL2-2.0.12/acinclude/ltversion.m4 b/SDL2-2.30.5/acinclude/ltversion.m4 similarity index 68% rename from SDL2-2.0.12/acinclude/ltversion.m4 rename to SDL2-2.30.5/acinclude/ltversion.m4 index 07a8602..fa04b52 100644 --- a/SDL2-2.0.12/acinclude/ltversion.m4 +++ b/SDL2-2.30.5/acinclude/ltversion.m4 @@ -1,6 +1,6 @@ # ltversion.m4 -- version numbers -*- Autoconf -*- # -# Copyright (C) 2004 Free Software Foundation, Inc. +# Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004 # # This file is free software; the Free Software Foundation gives @@ -9,15 +9,15 @@ # @configure_input@ -# serial 3337 ltversion.m4 +# serial 4179 ltversion.m4 # This file is part of GNU Libtool -m4_define([LT_PACKAGE_VERSION], [2.4.2]) -m4_define([LT_PACKAGE_REVISION], [1.3337]) +m4_define([LT_PACKAGE_VERSION], [2.4.6]) +m4_define([LT_PACKAGE_REVISION], [2.4.6]) AC_DEFUN([LTVERSION_VERSION], -[macro_version='2.4.2' -macro_revision='1.3337' +[macro_version='2.4.6' +macro_revision='2.4.6' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) diff --git a/SDL2-2.0.12/acinclude/lt~obsolete.m4 b/SDL2-2.30.5/acinclude/lt~obsolete.m4 similarity index 98% rename from SDL2-2.0.12/acinclude/lt~obsolete.m4 rename to SDL2-2.30.5/acinclude/lt~obsolete.m4 index c573da9..c6b26f8 100644 --- a/SDL2-2.0.12/acinclude/lt~obsolete.m4 +++ b/SDL2-2.30.5/acinclude/lt~obsolete.m4 @@ -1,6 +1,7 @@ # lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # -# Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. +# Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software +# Foundation, Inc. # Written by Scott James Remnant, 2004. # # This file is free software; the Free Software Foundation gives @@ -11,7 +12,7 @@ # These exist entirely to fool aclocal when bootstrapping libtool. # -# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) +# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN), # which have later been changed to m4_define as they aren't part of the # exported API, or moved to Autoconf or Automake where they belong. # @@ -25,7 +26,7 @@ # included after everything else. This provides aclocal with the # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything # because those macros already exist, or will be overwritten later. -# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. +# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. # # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. # Yes, that means every name once taken will need to remain here until diff --git a/SDL2-2.30.5/acinclude/pkg.m4 b/SDL2-2.30.5/acinclude/pkg.m4 new file mode 100644 index 0000000..13a8890 --- /dev/null +++ b/SDL2-2.30.5/acinclude/pkg.m4 @@ -0,0 +1,275 @@ +# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +# serial 12 (pkg-config-0.29.2) + +dnl Copyright © 2004 Scott James Remnant . +dnl Copyright © 2012-2015 Dan Nicholson +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 2 of the License, or +dnl (at your option) any later version. +dnl +dnl This program is distributed in the hope that it will be useful, but +dnl WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +dnl 02111-1307, USA. +dnl +dnl As a special exception to the GNU General Public License, if you +dnl distribute this file as part of a program that contains a +dnl configuration script generated by Autoconf, you may include it under +dnl the same distribution terms that you use for the rest of that +dnl program. + +dnl PKG_PREREQ(MIN-VERSION) +dnl ----------------------- +dnl Since: 0.29 +dnl +dnl Verify that the version of the pkg-config macros are at least +dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's +dnl installed version of pkg-config, this checks the developer's version +dnl of pkg.m4 when generating configure. +dnl +dnl To ensure that this macro is defined, also add: +dnl m4_ifndef([PKG_PREREQ], +dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])]) +dnl +dnl See the "Since" comment for each macro you use to see what version +dnl of the macros you require. +m4_defun([PKG_PREREQ], +[m4_define([PKG_MACROS_VERSION], [0.29.2]) +m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, + [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) +])dnl PKG_PREREQ + +dnl PKG_PROG_PKG_CONFIG([MIN-VERSION]) +dnl ---------------------------------- +dnl Since: 0.16 +dnl +dnl Search for the pkg-config tool and set the PKG_CONFIG variable to +dnl first found in the path. Checks that the version of pkg-config found +dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is +dnl used since that's the first version where most current features of +dnl pkg-config existed. +AC_DEFUN([PKG_PROG_PKG_CONFIG], +[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) +m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) +m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) +AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) +AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) +AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=m4_default([$1], [0.9.0]) + AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + PKG_CONFIG="" + fi +fi[]dnl +])dnl PKG_PROG_PKG_CONFIG + +dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +dnl ------------------------------------------------------------------- +dnl Since: 0.18 +dnl +dnl Check to see whether a particular set of modules exists. Similar to +dnl PKG_CHECK_MODULES(), but does not set variables or print errors. +dnl +dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +dnl only at the first occurence in configure.ac, so if the first place +dnl it's called might be skipped (such as if it is within an "if", you +dnl have to call PKG_CHECK_EXISTS manually +AC_DEFUN([PKG_CHECK_EXISTS], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +if test -n "$PKG_CONFIG" && \ + AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then + m4_default([$2], [:]) +m4_ifvaln([$3], [else + $3])dnl +fi]) + +dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) +dnl --------------------------------------------- +dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting +dnl pkg_failed based on the result. +m4_define([_PKG_CONFIG], +[if test -n "$$1"; then + pkg_cv_[]$1="$$1" + elif test -n "$PKG_CONFIG"; then + PKG_CHECK_EXISTS([$3], + [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes ], + [pkg_failed=yes]) + else + pkg_failed=untried +fi[]dnl +])dnl _PKG_CONFIG + +dnl _PKG_SHORT_ERRORS_SUPPORTED +dnl --------------------------- +dnl Internal check to see if pkg-config supports short errors. +AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi[]dnl +])dnl _PKG_SHORT_ERRORS_SUPPORTED + + +dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +dnl [ACTION-IF-NOT-FOUND]) +dnl -------------------------------------------------------------- +dnl Since: 0.4.0 +dnl +dnl Note that if there is a possibility the first call to +dnl PKG_CHECK_MODULES might not happen, you should be sure to include an +dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac +AC_DEFUN([PKG_CHECK_MODULES], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl +AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl + +pkg_failed=no +AC_MSG_CHECKING([for $2]) + +_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) +_PKG_CONFIG([$1][_LIBS], [libs], [$2]) + +m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS +and $1[]_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details.]) + +if test $pkg_failed = yes; then + AC_MSG_RESULT([no]) + _PKG_SHORT_ERRORS_SUPPORTED + if test $_pkg_short_errors_supported = yes; then + $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` + else + $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD + + m4_default([$4], [AC_MSG_ERROR( +[Package requirements ($2) were not met: + +$$1_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +_PKG_TEXT])[]dnl + ]) +elif test $pkg_failed = untried; then + AC_MSG_RESULT([no]) + m4_default([$4], [AC_MSG_FAILURE( +[The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +_PKG_TEXT + +To get pkg-config, see .])[]dnl + ]) +else + $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS + $1[]_LIBS=$pkg_cv_[]$1[]_LIBS + AC_MSG_RESULT([yes]) + $3 +fi[]dnl +])dnl PKG_CHECK_MODULES + + +dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +dnl [ACTION-IF-NOT-FOUND]) +dnl --------------------------------------------------------------------- +dnl Since: 0.29 +dnl +dnl Checks for existence of MODULES and gathers its build flags with +dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags +dnl and VARIABLE-PREFIX_LIBS from --libs. +dnl +dnl Note that if there is a possibility the first call to +dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to +dnl include an explicit call to PKG_PROG_PKG_CONFIG in your +dnl configure.ac. +AC_DEFUN([PKG_CHECK_MODULES_STATIC], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +_save_PKG_CONFIG=$PKG_CONFIG +PKG_CONFIG="$PKG_CONFIG --static" +PKG_CHECK_MODULES($@) +PKG_CONFIG=$_save_PKG_CONFIG[]dnl +])dnl PKG_CHECK_MODULES_STATIC + + +dnl PKG_INSTALLDIR([DIRECTORY]) +dnl ------------------------- +dnl Since: 0.27 +dnl +dnl Substitutes the variable pkgconfigdir as the location where a module +dnl should install pkg-config .pc files. By default the directory is +dnl $libdir/pkgconfig, but the default can be changed by passing +dnl DIRECTORY. The user can override through the --with-pkgconfigdir +dnl parameter. +AC_DEFUN([PKG_INSTALLDIR], +[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) +m4_pushdef([pkg_description], + [pkg-config installation directory @<:@]pkg_default[@:>@]) +AC_ARG_WITH([pkgconfigdir], + [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, + [with_pkgconfigdir=]pkg_default) +AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) +m4_popdef([pkg_default]) +m4_popdef([pkg_description]) +])dnl PKG_INSTALLDIR + + +dnl PKG_NOARCH_INSTALLDIR([DIRECTORY]) +dnl -------------------------------- +dnl Since: 0.27 +dnl +dnl Substitutes the variable noarch_pkgconfigdir as the location where a +dnl module should install arch-independent pkg-config .pc files. By +dnl default the directory is $datadir/pkgconfig, but the default can be +dnl changed by passing DIRECTORY. The user can override through the +dnl --with-noarch-pkgconfigdir parameter. +AC_DEFUN([PKG_NOARCH_INSTALLDIR], +[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) +m4_pushdef([pkg_description], + [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) +AC_ARG_WITH([noarch-pkgconfigdir], + [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, + [with_noarch_pkgconfigdir=]pkg_default) +AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) +m4_popdef([pkg_default]) +m4_popdef([pkg_description]) +])dnl PKG_NOARCH_INSTALLDIR + + +dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, +dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +dnl ------------------------------------------- +dnl Since: 0.28 +dnl +dnl Retrieves the value of the pkg-config variable for the given module. +AC_DEFUN([PKG_CHECK_VAR], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl + +_PKG_CONFIG([$1], [variable="][$3]["], [$2]) +AS_VAR_COPY([$1], [pkg_cv_][$1]) + +AS_VAR_IF([$1], [""], [$5], [$4])dnl +])dnl PKG_CHECK_VAR diff --git a/SDL2-2.0.12/android-project/app/build.gradle b/SDL2-2.30.5/android-project/app/build.gradle similarity index 78% rename from SDL2-2.0.12/android-project/app/build.gradle rename to SDL2-2.30.5/android-project/app/build.gradle index bf3c35d..c604361 100644 --- a/SDL2-2.0.12/android-project/app/build.gradle +++ b/SDL2-2.30.5/android-project/app/build.gradle @@ -8,22 +8,22 @@ else { } android { - compileSdkVersion 26 + if (buildAsApplication) { + namespace "org.libsdl.app" + } + compileSdkVersion 34 defaultConfig { - if (buildAsApplication) { - applicationId "org.libsdl.app" - } - minSdkVersion 16 - targetSdkVersion 26 + minSdkVersion 19 + targetSdkVersion 34 versionCode 1 versionName "1.0" externalNativeBuild { ndkBuild { - arguments "APP_PLATFORM=android-16" + arguments "APP_PLATFORM=android-19" abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64' } // cmake { - // arguments "-DANDROID_APP_PLATFORM=android-16", "-DANDROID_STL=c++_static" + // arguments "-DANDROID_APP_PLATFORM=android-19", "-DANDROID_STL=c++_static" // // abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64' // abiFilters 'arm64-v8a' // } @@ -35,6 +35,10 @@ android { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } + applicationVariants.all { variant -> + tasks["merge${variant.name.capitalize()}Assets"] + .dependsOn("externalNativeBuild${variant.name.capitalize()}") + } if (!project.hasProperty('EXCLUDE_NATIVE_LIBS')) { sourceSets.main { jniLibs.srcDir 'libs' @@ -49,10 +53,10 @@ android { } } - lintOptions { + lint { abortOnError false } - + if (buildAsLibrary) { libraryVariants.all { variant -> variant.outputs.each { output -> diff --git a/SDL2-2.0.12/android-project/app/jni/Android.mk b/SDL2-2.30.5/android-project/app/jni/Android.mk similarity index 100% rename from SDL2-2.0.12/android-project/app/jni/Android.mk rename to SDL2-2.30.5/android-project/app/jni/Android.mk diff --git a/SDL2-2.0.12/android-project/app/jni/Application.mk b/SDL2-2.30.5/android-project/app/jni/Application.mk similarity index 100% rename from SDL2-2.0.12/android-project/app/jni/Application.mk rename to SDL2-2.30.5/android-project/app/jni/Application.mk diff --git a/SDL2-2.0.12/android-project/app/jni/CMakeLists.txt b/SDL2-2.30.5/android-project/app/jni/CMakeLists.txt similarity index 100% rename from SDL2-2.0.12/android-project/app/jni/CMakeLists.txt rename to SDL2-2.30.5/android-project/app/jni/CMakeLists.txt diff --git a/SDL2-2.0.12/android-project/app/jni/src/Android.mk b/SDL2-2.30.5/android-project/app/jni/src/Android.mk similarity index 82% rename from SDL2-2.0.12/android-project/app/jni/src/Android.mk rename to SDL2-2.30.5/android-project/app/jni/src/Android.mk index 1adcb6e..04e006a 100644 --- a/SDL2-2.0.12/android-project/app/jni/src/Android.mk +++ b/SDL2-2.30.5/android-project/app/jni/src/Android.mk @@ -13,6 +13,6 @@ LOCAL_SRC_FILES := YourSourceHere.c LOCAL_SHARED_LIBRARIES := SDL2 -LOCAL_LDLIBS := -lGLESv1_CM -lGLESv2 -llog +LOCAL_LDLIBS := -lGLESv1_CM -lGLESv2 -lOpenSLES -llog -landroid include $(BUILD_SHARED_LIBRARY) diff --git a/SDL2-2.0.12/android-project/app/jni/src/CMakeLists.txt b/SDL2-2.30.5/android-project/app/jni/src/CMakeLists.txt similarity index 100% rename from SDL2-2.0.12/android-project/app/jni/src/CMakeLists.txt rename to SDL2-2.30.5/android-project/app/jni/src/CMakeLists.txt diff --git a/SDL2-2.0.12/android-project/app/proguard-rules.pro b/SDL2-2.30.5/android-project/app/proguard-rules.pro similarity index 100% rename from SDL2-2.0.12/android-project/app/proguard-rules.pro rename to SDL2-2.30.5/android-project/app/proguard-rules.pro diff --git a/SDL2-2.0.12/android-project/app/src/main/AndroidManifest.xml b/SDL2-2.30.5/android-project/app/src/main/AndroidManifest.xml similarity index 74% rename from SDL2-2.0.12/android-project/app/src/main/AndroidManifest.xml rename to SDL2-2.30.5/android-project/app/src/main/AndroidManifest.xml index 9bcd6e8..5157374 100644 --- a/SDL2-2.0.12/android-project/app/src/main/AndroidManifest.xml +++ b/SDL2-2.30.5/android-project/app/src/main/AndroidManifest.xml @@ -3,7 +3,6 @@ com.gamemaker.game --> @@ -38,10 +37,14 @@ android:name="android.hardware.microphone" android:required="false" /> --> - - + + + - + + + + @@ -59,7 +62,7 @@ + + + - - diff --git a/SDL2-2.0.12/android-project/build.gradle b/SDL2-2.30.5/android-project/build.gradle similarity index 80% rename from SDL2-2.0.12/android-project/build.gradle rename to SDL2-2.30.5/android-project/build.gradle index f6f90b2..2c911c6 100644 --- a/SDL2-2.0.12/android-project/build.gradle +++ b/SDL2-2.30.5/android-project/build.gradle @@ -2,11 +2,11 @@ buildscript { repositories { - jcenter() + mavenCentral() google() } dependencies { - classpath 'com.android.tools.build:gradle:3.2.0' + classpath 'com.android.tools.build:gradle:8.1.1' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files @@ -15,7 +15,7 @@ buildscript { allprojects { repositories { - jcenter() + mavenCentral() google() } } diff --git a/SDL2-2.0.12/android-project/gradle.properties b/SDL2-2.30.5/android-project/gradle.properties similarity index 100% rename from SDL2-2.0.12/android-project/gradle.properties rename to SDL2-2.30.5/android-project/gradle.properties diff --git a/SDL2-2.30.5/android-project/gradle/wrapper/gradle-wrapper.jar b/SDL2-2.30.5/android-project/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..2b338a935b508eb6286ed4b84a91176ee5fb93c5 GIT binary patch literal 54213 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 W0pC&I?SueJAtDe^1>pYz0sTMJrJ5N4 literal 0 HcmV?d00001 diff --git a/SDL2-2.0.12/android-project/gradle/wrapper/gradle-wrapper.properties b/SDL2-2.30.5/android-project/gradle/wrapper/gradle-wrapper.properties similarity index 79% rename from SDL2-2.0.12/android-project/gradle/wrapper/gradle-wrapper.properties rename to SDL2-2.30.5/android-project/gradle/wrapper/gradle-wrapper.properties index f9b3be2..5b9d759 100644 --- a/SDL2-2.0.12/android-project/gradle/wrapper/gradle-wrapper.properties +++ b/SDL2-2.30.5/android-project/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Mon Oct 23 13:51:26 PDT 2017 +#Thu Nov 11 18:20:34 PST 2021 distributionBase=GRADLE_USER_HOME +distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip +zipStoreBase=GRADLE_USER_HOME diff --git a/SDL2-2.0.12/android-project/gradlew b/SDL2-2.30.5/android-project/gradlew similarity index 96% rename from SDL2-2.0.12/android-project/gradlew rename to SDL2-2.30.5/android-project/gradlew index 9d82f78..3427607 100644 --- a/SDL2-2.0.12/android-project/gradlew +++ b/SDL2-2.30.5/android-project/gradlew @@ -126,8 +126,8 @@ if $cygwin ; then # Now convert the arguments - kludge to limit ourselves to /bin/sh i=0 for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + CHECK=`echo "$arg"|grep -E -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|grep -E -c "^-"` ### Determine if an option if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` diff --git a/SDL2-2.0.12/android-project/gradlew.bat b/SDL2-2.30.5/android-project/gradlew.bat similarity index 100% rename from SDL2-2.0.12/android-project/gradlew.bat rename to SDL2-2.30.5/android-project/gradlew.bat diff --git a/SDL2-2.0.12/android-project/settings.gradle b/SDL2-2.30.5/android-project/settings.gradle similarity index 100% rename from SDL2-2.0.12/android-project/settings.gradle rename to SDL2-2.30.5/android-project/settings.gradle diff --git a/SDL2-2.0.12/autogen.sh b/SDL2-2.30.5/autogen.sh similarity index 51% rename from SDL2-2.0.12/autogen.sh rename to SDL2-2.30.5/autogen.sh index 9edfb8a..dffcf41 100644 --- a/SDL2-2.0.12/autogen.sh +++ b/SDL2-2.30.5/autogen.sh @@ -1,5 +1,7 @@ #!/bin/sh -# + +set -e + echo "Generating build information using autoconf" echo "This may take a while ..." @@ -9,15 +11,11 @@ cd "$srcdir" # Regenerate configuration files cat acinclude/* >aclocal.m4 -found=false -for autoconf in autoconf autoconf259 autoconf-2.59 -do if which $autoconf >/dev/null 2>&1; then $autoconf && found=true; break; fi -done -if test x$found = xfalse; then - echo "Couldn't find autoconf, aborting" - exit 1 -fi + +"${AUTOCONF:-autoconf}" +rm aclocal.m4 +rm -rf autom4te.cache + (cd test; sh autogen.sh) -# Run configure for this platform echo "Now you are ready to run ./configure" diff --git a/SDL2-2.30.5/build-scripts/android-prefab.sh b/SDL2-2.30.5/build-scripts/android-prefab.sh new file mode 100644 index 0000000..aef588e --- /dev/null +++ b/SDL2-2.30.5/build-scripts/android-prefab.sh @@ -0,0 +1,351 @@ +#!/bin/bash + +set -e + +if ! [ "x$ANDROID_NDK_HOME" != "x" -a -d "$ANDROID_NDK_HOME" ]; then + echo "ANDROID_NDK_HOME environment variable is not set" + exit 1 +fi + +if ! [ "x$ANDROID_HOME" != "x" -a -d "$ANDROID_HOME" ]; then + echo "ANDROID_HOME environment variable is not set" + exit 1 +fi + +if [ "x$ANDROID_API" = "x" ]; then + ANDROID_API="$(ls "$ANDROID_HOME/platforms" | grep -E "^android-[0-9]+$" | sed 's/android-//' | sort -n -r | head -1)" + if [ "x$ANDROID_API" = "x" ]; then + echo "No Android platform found in $ANDROID_HOME/platforms" + exit 1 + fi +else + if ! [ -d "$ANDROID_HOME/platforms/android-$ANDROID_API" ]; then + echo "Android api version $ANDROID_API is not available ($ANDROID_HOME/platforms/android-$ANDROID_API does not exist)" >2 + exit 1 + fi +fi + +android_platformdir="$ANDROID_HOME/platforms/android-$ANDROID_API" + +echo "Building for android api version $ANDROID_API" +echo "android_platformdir=$android_platformdir" + +scriptdir=$(cd -P -- "$(dirname -- "$0")" && printf '%s\n' "$(pwd -P)") +sdl_root=$(cd -P -- "$(dirname -- "$0")/.." && printf '%s\n' "$(pwd -P)") + +build_root="${sdl_root}/build-android-prefab" + +android_abis="armeabi-v7a arm64-v8a x86 x86_64" +android_api=19 +android_ndk=21 +android_stl="c++_shared" + +sdl_major=$(sed -ne 's/^#define SDL_MAJOR_VERSION *//p' "${sdl_root}/include/SDL_version.h") +sdl_minor=$(sed -ne 's/^#define SDL_MINOR_VERSION *//p' "${sdl_root}/include/SDL_version.h") +sdl_patch=$(sed -ne 's/^#define SDL_PATCHLEVEL *//p' "${sdl_root}/include/SDL_version.h") +sdl_version="${sdl_major}.${sdl_minor}.${sdl_patch}" +echo "Building Android prefab package for SDL version $sdl_version" + +prefabhome="${build_root}/prefab-${sdl_version}" +rm -rf "$prefabhome" +mkdir -p "${prefabhome}" + +build_cmake_projects() { + for android_abi in $android_abis; do + echo "Configuring CMake project for $android_abi" + cmake -S "$sdl_root" -B "${build_root}/build_${android_abi}" \ + -DCMAKE_TOOLCHAIN_FILE="$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake" \ + -DANDROID_PLATFORM=${android_platform} \ + -DANDROID_ABI=${android_abi} \ + -DSDL_SHARED=ON \ + -DSDL_STATIC=ON \ + -DSDL_STATIC_PIC=ON \ + -DSDL_TEST=ON \ + -DSDL2_DISABLE_SDL2MAIN=OFF \ + -DSDL2_DISABLE_INSTALL=OFF \ + -DCMAKE_INSTALL_PREFIX="${build_root}/build_${android_abi}/prefix" \ + -DCMAKE_INSTALL_INCLUDEDIR=include \ + -DCMAKE_INSTALL_LIBDIR=lib \ + -DCMAKE_BUILD_TYPE=Release \ + -GNinja + + rm -rf "${build_root}/build_${android_abi}/prefix" + + echo "Building CMake project for $android_abi" + cmake --build "${build_root}/build_${android_abi}" + + echo "Installing CMake project for $android_abi" + cmake --install "${build_root}/build_${android_abi}" + done +} + +classes_sources_jar_path="${prefabhome}/classes-sources.jar" +classes_jar_path="${prefabhome}/classes.jar" +compile_java() { + classes_sources_root="${prefabhome}/classes-sources" + + rm -rf "${classes_sources_root}" + mkdir -p "${classes_sources_root}/META-INF" + + echo "Copying LICENSE.txt to java build folder" + cp "$sdl_root/LICENSE.txt" "${classes_sources_root}/META-INF" + + echo "Copy JAVA sources to java build folder" + cp -r "$sdl_root/android-project/app/src/main/java/org" "${classes_sources_root}" + + java_sourceslist_path="${prefabhome}/java_sources.txt" + pushd "${classes_sources_root}" + echo "Collecting sources for classes-sources.jar" + find "." -name "*.java" >"${java_sourceslist_path}" + find "META-INF" -name "*" >>"${java_sourceslist_path}" + + echo "Creating classes-sources.jar" + jar -cf "${classes_sources_jar_path}" "@${java_sourceslist_path}" + popd + + classes_root="${prefabhome}/classes" + mkdir -p "${classes_root}/META-INF" + cp "$sdl_root/LICENSE.txt" "${classes_root}/META-INF" + java_sourceslist_path="${prefabhome}/java_sources.txt" + + echo "Collecting sources for classes.jar" + find "$sdl_root/android-project/app/src/main/java" -name "*.java" >"${java_sourceslist_path}" + + echo "Compiling classes" + javac -encoding utf-8 -classpath "$android_platformdir/android.jar" -d "${classes_root}" "@${java_sourceslist_path}" + + java_classeslist_path="${prefabhome}/java_classes.txt" + pushd "${classes_root}" + find "." -name "*.class" >"${java_classeslist_path}" + find "META-INF" -name "*" >>"${java_classeslist_path}" + echo "Creating classes.jar" + jar -cf "${classes_jar_path}" "@${java_classeslist_path}" + popd +} + +pom_filename="SDL${sdl_major}-${sdl_version}.pom" +pom_filepath="${prefabhome}/${pom_filename}" +create_pom_xml() { + echo "Creating ${pom_filename}" + cat >"${pom_filepath}" < + 4.0.0 + org.libsdl.android + SDL${sdl_major} + ${sdl_version} + aar + SDL${sdl_major} + The AAR for SDL${sdl_major} + https://libsdl.org/ + + + zlib License + https://github.com/libsdl-org/SDL/blob/main/LICENSE.txt + repo + + + + scm:git:https://github.com/libsdl-org/SDL + https://github.com/libsdl-org/SDL + + +EOF +} + +create_aar_androidmanifest() { + echo "Creating AndroidManifest.xml" + cat >"${aar_root}/AndroidManifest.xml" < + + +EOF +} + +echo "Creating AAR root directory" +aar_root="${prefabhome}/SDL${sdl_major}-${sdl_version}" +mkdir -p "${aar_root}" + +aar_metainfdir_path=${aar_root}/META-INF +mkdir -p "${aar_metainfdir_path}" +cp "${sdl_root}/LICENSE.txt" "${aar_metainfdir_path}" + +prefabworkdir="${aar_root}/prefab" +mkdir -p "${prefabworkdir}" + +cat >"${prefabworkdir}/prefab.json" <"${sdl_moduleworkdir}/module.json" <"${abi_sdllibdir}/abi.json" <"${sdl_moduleworkdir}/module.json" <"${abi_sdllibdir}/abi.json" <"${sdl_moduleworkdir}/module.json" <"${abi_sdllibdir}/abi.json" <"${sdl_moduleworkdir}/module.json" <"${abi_sdllibdir}/abi.json" </dev/null ; + mv "${aar_filename}" "${prefabhome}" +popd + +maven_filename="SDL${sdl_major}-${sdl_version}.zip" + +pushd "${prefabhome}" + zip_filename="SDL${sdl_major}-${sdl_version}.zip" + zip "${maven_filename}" "${aar_filename}" "${pom_filename}" 2>/dev/null; + zip -Tv "${zip_filename}" 2>/dev/null; +popd + +echo "Prefab zip is ready at ${prefabhome}/${aar_filename}" +echo "Maven archive is ready at ${prefabhome}/${zip_filename}" diff --git a/SDL2-2.0.12/build-scripts/androidbuild.sh b/SDL2-2.30.5/build-scripts/androidbuild.sh similarity index 100% rename from SDL2-2.0.12/build-scripts/androidbuild.sh rename to SDL2-2.30.5/build-scripts/androidbuild.sh diff --git a/SDL2-2.0.12/build-scripts/androidbuildlibs.sh b/SDL2-2.30.5/build-scripts/androidbuildlibs.sh similarity index 68% rename from SDL2-2.0.12/build-scripts/androidbuildlibs.sh rename to SDL2-2.30.5/build-scripts/androidbuildlibs.sh index 3e57b47..0ee583a 100644 --- a/SDL2-2.0.12/build-scripts/androidbuildlibs.sh +++ b/SDL2-2.30.5/build-scripts/androidbuildlibs.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # # Build the Android libraries without needing a project # (AndroidManifest.xml, jni/{Application,Android}.mk, etc.) @@ -33,22 +33,21 @@ lib= ndk_args= # Allow an external caller to specify locations. -for arg in $* -do - if [ "${arg:0:8}" == "NDK_OUT=" ]; then - obj=${arg#NDK_OUT=} - elif [ "${arg:0:13}" == "NDK_LIBS_OUT=" ]; then - lib=${arg#NDK_LIBS_OUT=} - else - ndk_args="$ndk_args $arg" - fi +for arg in $*; do + if [ "${arg:0:8}" == "NDK_OUT=" ]; then + obj=${arg#NDK_OUT=} + elif [ "${arg:0:13}" == "NDK_LIBS_OUT=" ]; then + lib=${arg#NDK_LIBS_OUT=} + else + ndk_args="$ndk_args $arg" + fi done if [ -z $obj ]; then - obj=$buildandroid/obj + obj=$buildandroid/obj fi if [ -z $lib ]; then - lib=$buildandroid/lib + lib=$buildandroid/lib fi for dir in $build $buildandroid $obj $lib; do @@ -64,11 +63,11 @@ done # ndk-build makefile segments that use them, e.g., default-application.mk. # For consistency, pass all values on the command line. ndk-build \ - NDK_PROJECT_PATH=null \ - NDK_OUT=$obj \ - NDK_LIBS_OUT=$lib \ - APP_BUILD_SCRIPT=Android.mk \ - APP_ABI="armeabi-v7a arm64-v8a x86 x86_64" \ - APP_PLATFORM=android-16 \ - APP_MODULES="SDL2 SDL2_main" \ - $ndk_args + NDK_PROJECT_PATH=null \ + NDK_OUT=$obj \ + NDK_LIBS_OUT=$lib \ + APP_BUILD_SCRIPT=Android.mk \ + APP_ABI="armeabi-v7a arm64-v8a x86 x86_64" \ + APP_PLATFORM=android-16 \ + APP_MODULES="SDL2 SDL2_main" \ + $ndk_args diff --git a/SDL2-2.0.12/build-scripts/checker-buildbot.sh b/SDL2-2.30.5/build-scripts/checker-buildbot.sh similarity index 56% rename from SDL2-2.0.12/build-scripts/checker-buildbot.sh rename to SDL2-2.30.5/build-scripts/checker-buildbot.sh index cc16a50..be89fd7 100644 --- a/SDL2-2.0.12/build-scripts/checker-buildbot.sh +++ b/SDL2-2.30.5/build-scripts/checker-buildbot.sh @@ -5,51 +5,10 @@ # back to the buildmaster. You might find it useful too. # Install Clang (you already have it on Mac OS X, apt-get install clang -# on Ubuntu, etc), -# or download checker at http://clang-analyzer.llvm.org/ and unpack it in -# /usr/local ... update CHECKERDIR as appropriate. +# on Ubuntu, etc), and make sure scan-build is in your $PATH. FINALDIR="$1" -CHECKERDIR="/usr/local/checker-279" -if [ ! -d "$CHECKERDIR" ]; then - echo "$CHECKERDIR not found. Trying /usr/share/clang ..." 1>&2 - CHECKERDIR="/usr/share/clang/scan-build" -fi - -if [ ! -d "$CHECKERDIR" ]; then - echo "$CHECKERDIR not found. Giving up." 1>&2 - exit 1 -fi - -if [ -z "$MAKE" ]; then - OSTYPE=`uname -s` - if [ "$OSTYPE" == "Linux" ]; then - NCPU=`cat /proc/cpuinfo |grep vendor_id |wc -l` - let NCPU=$NCPU+1 - elif [ "$OSTYPE" = "Darwin" ]; then - NCPU=`sysctl -n hw.ncpu` - elif [ "$OSTYPE" = "SunOS" ]; then - NCPU=`/usr/sbin/psrinfo |wc -l |sed -e 's/^ *//g;s/ *$//g'` - else - NCPU=1 - fi - - if [ -z "$NCPU" ]; then - NCPU=1 - elif [ "$NCPU" = "0" ]; then - NCPU=1 - fi - - MAKE="make -j$NCPU" -fi - -echo "\$MAKE is '$MAKE'" - -# Unset $MAKE so submakes don't use it. -MAKECOMMAND="$MAKE" -unset MAKE - set -x set -e @@ -68,13 +27,13 @@ cd checker-buildbot # The -Wno-liblto is new since our checker-279 upgrade, I think; checker otherwise warns "libLTO.dylib relative to clang installed dir not found" # You might want to do this for CMake-backed builds instead... -PATH="$CHECKERDIR/bin:$PATH" scan-build -o analysis cmake -Wno-dev -DSDL_STATIC=OFF -DCMAKE_BUILD_TYPE=Debug -DASSERTIONS=enabled -DCMAKE_C_FLAGS="-Wno-deprecated-declarations" -DCMAKE_SHARED_LINKER_FLAGS="-Wno-liblto" .. +scan-build -o analysis cmake -G Ninja -Wno-dev -DSDL_STATIC=OFF -DCMAKE_BUILD_TYPE=Debug -DSDL_ASSERTIONS=enabled -DCMAKE_C_FLAGS="-Wno-deprecated-declarations" -DCMAKE_SHARED_LINKER_FLAGS="-Wno-liblto" .. # ...or run configure without the scan-build wrapper... #CC="$CHECKERDIR/libexec/ccc-analyzer" CFLAGS="-O0 -Wno-deprecated-declarations" LDFLAGS="-Wno-liblto" ../configure --enable-assertions=enabled rm -rf analysis -PATH="$CHECKERDIR/bin:$PATH" scan-build -o analysis $MAKECOMMAND +scan-build -o analysis ninja if [ `ls -A analysis |wc -l` == 0 ] ; then mkdir analysis/zarro diff --git a/SDL2-2.0.12/build-scripts/g++-fat.sh b/SDL2-2.30.5/build-scripts/clang++-fat.sh similarity index 50% rename from SDL2-2.0.12/build-scripts/g++-fat.sh rename to SDL2-2.30.5/build-scripts/clang++-fat.sh index 0dbe990..41fdf1c 100644 --- a/SDL2-2.0.12/build-scripts/g++-fat.sh +++ b/SDL2-2.30.5/build-scripts/clang++-fat.sh @@ -2,35 +2,36 @@ # # Build Universal binaries on Mac OS X, thanks Ryan! # -# Usage: ./configure CXX="sh g++-fat.sh" && make && rm -rf x86 x64 +# Usage: ./configure CXX="sh clang++-fat.sh" && make && rm -rf arm64 x64 DEVELOPER="`xcode-select -print-path`/Platforms/MacOSX.platform/Developer" -# Intel 32-bit compiler flags (10.6 runtime compatibility) -GCC_COMPILE_X86="g++ -arch i386 -mmacosx-version-min=10.6 \ +# Intel 64-bit compiler flags (10.7 runtime compatibility) +CLANG_COMPILE_X64="clang++ -arch x86_64 -mmacosx-version-min=10.7 \ -I/usr/local/include" -GCC_LINK_X86="-mmacosx-version-min=10.6" +CLANG_LINK_X64="-mmacosx-version-min=10.7" -# Intel 64-bit compiler flags (10.6 runtime compatibility) -GCC_COMPILE_X64="g++ -arch x86_64 -mmacosx-version-min=10.6 \ +# ARM 64-bit compiler flags (11.0 runtime compatibility) +CLANG_COMPILE_ARM64="clang++ -arch arm64 -mmacosx-version-min=11.0 \ -I/usr/local/include" -GCC_LINK_X64="-mmacosx-version-min=10.6" +CLANG_LINK_ARM64="-mmacosx-version-min=11.0" -# Output both PowerPC and Intel object files + +# Output both Intel and ARM object files args="$*" compile=yes link=yes while test x$1 != x; do case $1 in - --version) exec g++ $1;; - -v) exec g++ $1;; - -V) exec g++ $1;; - -print-prog-name=*) exec g++ $1;; - -print-search-dirs) exec g++ $1;; - -E) GCC_COMPILE_X86="$GCC_COMPILE_X86 -E" - GCC_COMPILE_X64="$GCC_COMPILE_X64 -E" + --version) exec clang++ $1;; + -v) exec clang++ $1;; + -V) exec clang++ $1;; + -print-prog-name=*) exec clang++ $1;; + -print-search-dirs) exec clang++ $1;; + -E) CLANG_COMPILE_ARM64="$CLANG_COMPILE_ARM64 -E" + CLANG_COMPILE_X64="$CLANG_COMPILE_X64 -E" compile=no; link=no;; -c) link=no;; -o) output=$2;; @@ -39,8 +40,8 @@ while test x$1 != x; do shift done if test x$link = xyes; then - GCC_COMPILE_X86="$GCC_COMPILE_X86 $GCC_LINK_X86" - GCC_COMPILE_X64="$GCC_COMPILE_X64 $GCC_LINK_X64" + CLANG_COMPILE_ARM64="$CLANG_COMPILE_ARM64 $CLANG_LINK_ARM64" + CLANG_COMPILE_X64="$CLANG_COMPILE_X64 $CLANG_LINK_X64" fi if test x"$output" = x; then if test x$link = xyes; then @@ -50,9 +51,9 @@ if test x"$output" = x; then fi fi -# Compile X86 32-bit +# Compile ARM 64-bit if test x"$output" != x; then - dir=x86/`dirname $output` + dir=arm64/`dirname $output` if test -d $dir; then : else @@ -61,19 +62,19 @@ if test x"$output" != x; then fi set -- $args while test x$1 != x; do - if test -f "x86/$1" && test "$1" != "$output"; then - x86_args="$x86_args x86/$1" + if test -f "arm64/$1" && test "$1" != "$output"; then + arm64_args="$arm64_args arm64/$1" else - x86_args="$x86_args $1" + arm64_args="$arm64_args $1" fi shift done -$GCC_COMPILE_X86 $x86_args || exit $? +$CLANG_COMPILE_ARM64 $arm64_args || exit $? if test x"$output" != x; then - cp $output x86/$output + cp $output arm64/$output fi -# Compile X86 32-bit +# Compile Intel 64-bit if test x"$output" != x; then dir=x64/`dirname $output` if test -d $dir; then @@ -91,11 +92,11 @@ while test x$1 != x; do fi shift done -$GCC_COMPILE_X64 $x64_args || exit $? +$CLANG_COMPILE_X64 $x64_args || exit $? if test x"$output" != x; then cp $output x64/$output fi if test x"$output" != x; then - lipo -create -o $output x86/$output x64/$output + lipo -create -o $output arm64/$output x64/$output fi diff --git a/SDL2-2.0.12/build-scripts/gcc-fat.sh b/SDL2-2.30.5/build-scripts/clang-fat.sh similarity index 50% rename from SDL2-2.0.12/build-scripts/gcc-fat.sh rename to SDL2-2.30.5/build-scripts/clang-fat.sh index 65f759d..088bf5c 100644 --- a/SDL2-2.0.12/build-scripts/gcc-fat.sh +++ b/SDL2-2.30.5/build-scripts/clang-fat.sh @@ -2,36 +2,37 @@ # # Build Universal binaries on Mac OS X, thanks Ryan! # -# Usage: ./configure CC="sh gcc-fat.sh" && make && rm -rf x86 x64 +# Usage: ./configure CC="sh clang-fat.sh" && make && rm -rf arm64 x64 DEVELOPER="`xcode-select -print-path`/Platforms/MacOSX.platform/Developer" -# Intel 32-bit compiler flags (10.6 runtime compatibility) -GCC_COMPILE_X86="gcc -arch i386 -mmacosx-version-min=10.6 \ +# Intel 64-bit compiler flags (10.9 runtime compatibility) +CLANG_COMPILE_X64="clang -arch x86_64 -mmacosx-version-min=10.9 \ +-DMAC_OS_X_VERSION_MIN_REQUIRED=1070 \ -I/usr/local/include" -GCC_LINK_X86="-mmacosx-version-min=10.6" +CLANG_LINK_X64="-mmacosx-version-min=10.9" -# Intel 64-bit compiler flags (10.6 runtime compatibility) -GCC_COMPILE_X64="gcc -arch x86_64 -mmacosx-version-min=10.6 \ --DMAC_OS_X_VERSION_MIN_REQUIRED=1060 \ +# ARM 64-bit compiler flags (11.0 runtime compatibility) +CLANG_COMPILE_ARM64="clang -arch arm64 -mmacosx-version-min=11.0 \ -I/usr/local/include" -GCC_LINK_X64="-mmacosx-version-min=10.6" +CLANG_LINK_ARM64="-mmacosx-version-min=11.0" -# Output both PowerPC and Intel object files + +# Output both Intel and ARM object files args="$*" compile=yes link=yes while test x$1 != x; do case $1 in - --version) exec gcc $1;; - -v) exec gcc $1;; - -V) exec gcc $1;; - -print-prog-name=*) exec gcc $1;; - -print-search-dirs) exec gcc $1;; - -E) GCC_COMPILE_X86="$GCC_COMPILE_X86 -E" - GCC_COMPILE_X64="$GCC_COMPILE_X64 -E" + --version) exec clang $1;; + -v) exec clang $1;; + -V) exec clang $1;; + -print-prog-name=*) exec clang $1;; + -print-search-dirs) exec clang $1;; + -E) CLANG_COMPILE_X64="$CLANG_COMPILE_X64 -E" + CLANG_COMPILE_ARM64="$CLANG_COMPILE_ARM64 -E" compile=no; link=no;; -c) link=no;; -o) output=$2;; @@ -40,8 +41,8 @@ while test x$1 != x; do shift done if test x$link = xyes; then - GCC_COMPILE_X86="$GCC_COMPILE_X86 $GCC_LINK_X86" - GCC_COMPILE_X64="$GCC_COMPILE_X64 $GCC_LINK_X64" + CLANG_COMPILE_X64="$CLANG_COMPILE_X64 $CLANG_LINK_X64" + CLANG_COMPILE_ARM64="$CLANG_COMPILE_ARM64 $CLANG_LINK_ARM64" fi if test x"$output" = x; then if test x$link = xyes; then @@ -51,30 +52,7 @@ if test x"$output" = x; then fi fi -# Compile X86 32-bit -if test x"$output" != x; then - dir=x86/`dirname $output` - if test -d $dir; then - : - else - mkdir -p $dir - fi -fi -set -- $args -while test x$1 != x; do - if test -f "x86/$1" && test "$1" != "$output"; then - x86_args="$x86_args x86/$1" - else - x86_args="$x86_args $1" - fi - shift -done -$GCC_COMPILE_X86 $x86_args || exit $? -if test x"$output" != x; then - cp $output x86/$output -fi - -# Compile X86 32-bit +# Compile Intel 64-bit if test x"$output" != x; then dir=x64/`dirname $output` if test -d $dir; then @@ -92,11 +70,36 @@ while test x$1 != x; do fi shift done -$GCC_COMPILE_X64 $x64_args || exit $? +$CLANG_COMPILE_X64 $x64_args || exit $? if test x"$output" != x; then cp $output x64/$output fi +# Compile ARM 64-bit if test x"$output" != x; then - lipo -create -o $output x86/$output x64/$output + dir=arm64/`dirname $output` + if test -d $dir; then + : + else + mkdir -p $dir + fi fi +set -- $args +while test x$1 != x; do + if test -f "arm64/$1" && test "$1" != "$output"; then + arm64_args="$arm64_args arm64/$1" + else + arm64_args="$arm64_args $1" + fi + shift +done +$CLANG_COMPILE_ARM64 $arm64_args || exit $? +if test x"$output" != x; then + cp $output arm64/$output +fi + + +if test x"$output" != x; then + lipo -create -o $output arm64/$output x64/$output +fi + diff --git a/SDL2-2.30.5/build-scripts/clang-format-src.sh b/SDL2-2.30.5/build-scripts/clang-format-src.sh new file mode 100644 index 0000000..c4af9a5 --- /dev/null +++ b/SDL2-2.30.5/build-scripts/clang-format-src.sh @@ -0,0 +1,32 @@ +#!/bin/sh + +cd "$(dirname $0)/../src" + +echo "Running clang-format in $(pwd)" + +find . -regex '.*\.[chm]p*' -exec clang-format -i {} \; + +# Revert third-party code +git checkout \ + events/imKStoUCS.* \ + hidapi \ + joystick/controller_type.c \ + joystick/controller_type.h \ + joystick/hidapi/steam/controller_constants.h \ + joystick/hidapi/steam/controller_structs.h \ + libm \ + stdlib/SDL_malloc.c \ + stdlib/SDL_qsort.c \ + stdlib/SDL_strtokr.c \ + video/arm \ + video/khronos \ + video/x11/edid-parse.c \ + video/yuv2rgb +clang-format -i hidapi/SDL_hidapi.c + +# Revert generated code +git checkout dynapi/SDL_dynapi_overrides.h +git checkout dynapi/SDL_dynapi_procs.h +git checkout render/metal/SDL_shaders_metal_*.h + +echo "clang-format complete!" diff --git a/SDL2-2.30.5/build-scripts/codechecker-buildbot.sh b/SDL2-2.30.5/build-scripts/codechecker-buildbot.sh new file mode 100644 index 0000000..76b7853 --- /dev/null +++ b/SDL2-2.30.5/build-scripts/codechecker-buildbot.sh @@ -0,0 +1,59 @@ +#!/bin/bash + +# This is a script used by some Buildbot build workers to push the project +# through Clang's static analyzer and prepare the output to be uploaded +# back to the buildmaster. You might find it useful too. + +# Install Clang (you already have it on macOS, apt-get install clang +# on Ubuntu, etc), install CMake, and pip3 install codechecker. + +FINALDIR="$1" + +set -x +set -e + +cd `dirname "$0"` +cd .. + +rm -rf codechecker-buildbot +if [ ! -z "$FINALDIR" ]; then + rm -rf "$FINALDIR" +fi + +mkdir codechecker-buildbot +cd codechecker-buildbot + +# We turn off deprecated declarations, because we don't care about these warnings during static analysis. +cmake -Wno-dev -DSDL_STATIC=OFF -DCMAKE_BUILD_TYPE=Debug -DSDL_ASSERTIONS=enabled -DCMAKE_C_FLAGS="-Wno-deprecated-declarations" -DCMAKE_EXPORT_COMPILE_COMMANDS=1 .. + +# CMake on macOS adds "-arch arm64" or whatever is appropriate, but this confuses CodeChecker, so strip it out. +perl -w -pi -e 's/\-arch\s+.*?\s+//g;' compile_commands.json + +rm -rf ../analysis +CodeChecker analyze compile_commands.json -o ./reports + +# "parse" returns 2 if there was a static analysis issue to report, but this +# does not signify an error in the parsing (that would be error code 1). Turn +# off the abort-on-error flag. +set +e +CodeChecker parse ./reports -e html -o ../analysis +set -e + +cd .. +chmod -R a+r analysis +chmod -R go-w analysis +find analysis -type d -exec chmod a+x {} \; +if [ -x /usr/bin/xattr ]; then find analysis -exec /usr/bin/xattr -d com.apple.quarantine {} \; 2>/dev/null ; fi + +if [ ! -z "$FINALDIR" ]; then + mv analysis "$FINALDIR" +else + FINALDIR=analysis +fi + +rm -rf codechecker-buildbot + +echo "Done. Final output is in '$FINALDIR' ..." + +# end of codechecker-buildbot.sh ... + diff --git a/SDL2-2.30.5/build-scripts/config.guess b/SDL2-2.30.5/build-scripts/config.guess new file mode 100644 index 0000000..f6d217a --- /dev/null +++ b/SDL2-2.30.5/build-scripts/config.guess @@ -0,0 +1,1812 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright 1992-2024 Free Software Foundation, Inc. + +# shellcheck disable=SC2006,SC2268 # see below for rationale + +timestamp='2024-01-01' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). +# +# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. +# +# You can get the latest version of this script from: +# https://git.savannah.gnu.org/cgit/config.git/plain/config.guess +# +# Please send patches to . + + +# The "shellcheck disable" line above the timestamp inhibits complaints +# about features and limitations of the classic Bourne shell that were +# superseded or lifted in POSIX. However, this script identifies a wide +# variety of pre-POSIX systems that do not have POSIX shells at all, and +# even some reasonably current systems (Solaris 10 as case-in-point) still +# have a pre-POSIX /bin/sh. + + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system '$me' is run on. + +Options: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright 1992-2024 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try '$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +# Just in case it came from the environment. +GUESS= + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, 'CC_FOR_BUILD' used to be named 'HOST_CC'. We still +# use 'HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +tmp= +# shellcheck disable=SC2172 +trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15 + +set_cc_for_build() { + # prevent multiple calls if $tmp is already set + test "$tmp" && return 0 + : "${TMPDIR=/tmp}" + # shellcheck disable=SC2039,SC3028 + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } + dummy=$tmp/dummy + case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in + ,,) echo "int x;" > "$dummy.c" + for driver in cc gcc c89 c99 ; do + if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then + CC_FOR_BUILD=$driver + break + fi + done + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; + esac +} + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if test -f /.attbin/uname ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +case $UNAME_SYSTEM in +Linux|GNU|GNU/*) + LIBC=unknown + + set_cc_for_build + cat <<-EOF > "$dummy.c" + #if defined(__ANDROID__) + LIBC=android + #else + #include + #if defined(__UCLIBC__) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc + #elif defined(__GLIBC__) + LIBC=gnu + #elif defined(__LLVM_LIBC__) + LIBC=llvm + #else + #include + /* First heuristic to detect musl libc. */ + #ifdef __DEFINED_va_list + LIBC=musl + #endif + #endif + #endif + EOF + cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` + eval "$cc_set_libc" + + # Second heuristic to detect musl libc. + if [ "$LIBC" = unknown ] && + command -v ldd >/dev/null && + ldd --version 2>&1 | grep -q ^musl; then + LIBC=musl + fi + + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + if [ "$LIBC" = unknown ]; then + LIBC=gnu + fi + ;; +esac + +# Note: order is significant - the case branches are not exclusive. + +case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ + /sbin/sysctl -n hw.machine_arch 2>/dev/null || \ + /usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \ + echo unknown)` + case $UNAME_MACHINE_ARCH in + aarch64eb) machine=aarch64_be-unknown ;; + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + earmv*) + arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` + endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` + machine=${arch}${endian}-unknown + ;; + *) machine=$UNAME_MACHINE_ARCH-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently (or will in the future) and ABI. + case $UNAME_MACHINE_ARCH in + earm*) + os=netbsdelf + ;; + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # Determine ABI tags. + case $UNAME_MACHINE_ARCH in + earm*) + expr='s/^earmv[0-9]/-eabi/;s/eb$//' + abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case $UNAME_VERSION in + Debian*) + release='-gnu' + ;; + *) + release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + GUESS=$machine-${os}${release}${abi-} + ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + GUESS=$UNAME_MACHINE_ARCH-unknown-bitrig$UNAME_RELEASE + ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + GUESS=$UNAME_MACHINE_ARCH-unknown-openbsd$UNAME_RELEASE + ;; + *:SecBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/SecBSD.//'` + GUESS=$UNAME_MACHINE_ARCH-unknown-secbsd$UNAME_RELEASE + ;; + *:LibertyBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` + GUESS=$UNAME_MACHINE_ARCH-unknown-libertybsd$UNAME_RELEASE + ;; + *:MidnightBSD:*:*) + GUESS=$UNAME_MACHINE-unknown-midnightbsd$UNAME_RELEASE + ;; + *:ekkoBSD:*:*) + GUESS=$UNAME_MACHINE-unknown-ekkobsd$UNAME_RELEASE + ;; + *:SolidBSD:*:*) + GUESS=$UNAME_MACHINE-unknown-solidbsd$UNAME_RELEASE + ;; + *:OS108:*:*) + GUESS=$UNAME_MACHINE-unknown-os108_$UNAME_RELEASE + ;; + macppc:MirBSD:*:*) + GUESS=powerpc-unknown-mirbsd$UNAME_RELEASE + ;; + *:MirBSD:*:*) + GUESS=$UNAME_MACHINE-unknown-mirbsd$UNAME_RELEASE + ;; + *:Sortix:*:*) + GUESS=$UNAME_MACHINE-unknown-sortix + ;; + *:Twizzler:*:*) + GUESS=$UNAME_MACHINE-unknown-twizzler + ;; + *:Redox:*:*) + GUESS=$UNAME_MACHINE-unknown-redox + ;; + mips:OSF1:*.*) + GUESS=mips-dec-osf1 + ;; + alpha:OSF1:*:*) + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + trap '' 0 + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case $ALPHA_CPU_TYPE in + "EV4 (21064)") + UNAME_MACHINE=alpha ;; + "EV4.5 (21064)") + UNAME_MACHINE=alpha ;; + "LCA4 (21066/21068)") + UNAME_MACHINE=alpha ;; + "EV5 (21164)") + UNAME_MACHINE=alphaev5 ;; + "EV5.6 (21164A)") + UNAME_MACHINE=alphaev56 ;; + "EV5.6 (21164PC)") + UNAME_MACHINE=alphapca56 ;; + "EV5.7 (21164PC)") + UNAME_MACHINE=alphapca57 ;; + "EV6 (21264)") + UNAME_MACHINE=alphaev6 ;; + "EV6.7 (21264A)") + UNAME_MACHINE=alphaev67 ;; + "EV6.8CB (21264C)") + UNAME_MACHINE=alphaev68 ;; + "EV6.8AL (21264B)") + UNAME_MACHINE=alphaev68 ;; + "EV6.8CX (21264D)") + UNAME_MACHINE=alphaev68 ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE=alphaev69 ;; + "EV7 (21364)") + UNAME_MACHINE=alphaev7 ;; + "EV7.9 (21364A)") + UNAME_MACHINE=alphaev79 ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + OSF_REL=`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + GUESS=$UNAME_MACHINE-dec-osf$OSF_REL + ;; + Amiga*:UNIX_System_V:4.0:*) + GUESS=m68k-unknown-sysv4 + ;; + *:[Aa]miga[Oo][Ss]:*:*) + GUESS=$UNAME_MACHINE-unknown-amigaos + ;; + *:[Mm]orph[Oo][Ss]:*:*) + GUESS=$UNAME_MACHINE-unknown-morphos + ;; + *:OS/390:*:*) + GUESS=i370-ibm-openedition + ;; + *:z/VM:*:*) + GUESS=s390-ibm-zvmoe + ;; + *:OS400:*:*) + GUESS=powerpc-ibm-os400 + ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + GUESS=arm-acorn-riscix$UNAME_RELEASE + ;; + arm*:riscos:*:*|arm*:RISCOS:*:*) + GUESS=arm-unknown-riscos + ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + GUESS=hppa1.1-hitachi-hiuxmpp + ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + case `(/bin/universe) 2>/dev/null` in + att) GUESS=pyramid-pyramid-sysv3 ;; + *) GUESS=pyramid-pyramid-bsd ;; + esac + ;; + NILE*:*:*:dcosx) + GUESS=pyramid-pyramid-svr4 + ;; + DRS?6000:unix:4.0:6*) + GUESS=sparc-icl-nx6 + ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) GUESS=sparc-icl-nx7 ;; + esac + ;; + s390x:SunOS:*:*) + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=$UNAME_MACHINE-ibm-solaris2$SUN_REL + ;; + sun4H:SunOS:5.*:*) + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=sparc-hal-solaris2$SUN_REL + ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=sparc-sun-solaris2$SUN_REL + ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + GUESS=i386-pc-auroraux$UNAME_RELEASE + ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + set_cc_for_build + SUN_ARCH=i386 + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if test "$CC_FOR_BUILD" != no_compiler_found; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -m64 -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH=x86_64 + fi + fi + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=$SUN_ARCH-pc-solaris2$SUN_REL + ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=sparc-sun-solaris3$SUN_REL + ;; + sun4*:SunOS:*:*) + case `/usr/bin/arch -k` in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like '4.1.3-JL'. + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'` + GUESS=sparc-sun-sunos$SUN_REL + ;; + sun3*:SunOS:*:*) + GUESS=m68k-sun-sunos$UNAME_RELEASE + ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 + case `/bin/arch` in + sun3) + GUESS=m68k-sun-sunos$UNAME_RELEASE + ;; + sun4) + GUESS=sparc-sun-sunos$UNAME_RELEASE + ;; + esac + ;; + aushp:SunOS:*:*) + GUESS=sparc-auspex-sunos$UNAME_RELEASE + ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + GUESS=m68k-atari-mint$UNAME_RELEASE + ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + GUESS=m68k-atari-mint$UNAME_RELEASE + ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + GUESS=m68k-atari-mint$UNAME_RELEASE + ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + GUESS=m68k-milan-mint$UNAME_RELEASE + ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + GUESS=m68k-hades-mint$UNAME_RELEASE + ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + GUESS=m68k-unknown-mint$UNAME_RELEASE + ;; + m68k:machten:*:*) + GUESS=m68k-apple-machten$UNAME_RELEASE + ;; + powerpc:machten:*:*) + GUESS=powerpc-apple-machten$UNAME_RELEASE + ;; + RISC*:Mach:*:*) + GUESS=mips-dec-mach_bsd4.3 + ;; + RISC*:ULTRIX:*:*) + GUESS=mips-dec-ultrix$UNAME_RELEASE + ;; + VAX*:ULTRIX*:*:*) + GUESS=vax-dec-ultrix$UNAME_RELEASE + ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + GUESS=clipper-intergraph-clix$UNAME_RELEASE + ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && + dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`"$dummy" "$dummyarg"` && + { echo "$SYSTEM_NAME"; exit; } + GUESS=mips-mips-riscos$UNAME_RELEASE + ;; + Motorola:PowerMAX_OS:*:*) + GUESS=powerpc-motorola-powermax + ;; + Motorola:*:4.3:PL8-*) + GUESS=powerpc-harris-powermax + ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + GUESS=powerpc-harris-powermax + ;; + Night_Hawk:Power_UNIX:*:*) + GUESS=powerpc-harris-powerunix + ;; + m88k:CX/UX:7*:*) + GUESS=m88k-harris-cxux7 + ;; + m88k:*:4*:R4*) + GUESS=m88k-motorola-sysv4 + ;; + m88k:*:3*:R3*) + GUESS=m88k-motorola-sysv3 + ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110 + then + if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \ + test "$TARGET_BINARY_INTERFACE"x = x + then + GUESS=m88k-dg-dgux$UNAME_RELEASE + else + GUESS=m88k-dg-dguxbcs$UNAME_RELEASE + fi + else + GUESS=i586-dg-dgux$UNAME_RELEASE + fi + ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + GUESS=m88k-dolphin-sysv3 + ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + GUESS=m88k-motorola-sysv3 + ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + GUESS=m88k-tektronix-sysv3 + ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + GUESS=m68k-tektronix-bsd + ;; + *:IRIX*:*:*) + IRIX_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/g'` + GUESS=mips-sgi-irix$IRIX_REL + ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + GUESS=romp-ibm-aix # uname -m gives an 8 hex-code CPU id + ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + GUESS=i386-ibm-aix + ;; + ia64:AIX:*:*) + if test -x /usr/bin/oslevel ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=$UNAME_VERSION.$UNAME_RELEASE + fi + GUESS=$UNAME_MACHINE-ibm-aix$IBM_REV + ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` + then + GUESS=$SYSTEM_NAME + else + GUESS=rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + GUESS=rs6000-ibm-aix3.2.4 + else + GUESS=rs6000-ibm-aix3.2 + fi + ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if test -x /usr/bin/lslpp ; then + IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | \ + awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` + else + IBM_REV=$UNAME_VERSION.$UNAME_RELEASE + fi + GUESS=$IBM_ARCH-ibm-aix$IBM_REV + ;; + *:AIX:*:*) + GUESS=rs6000-ibm-aix + ;; + ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) + GUESS=romp-ibm-bsd4.4 + ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + GUESS=romp-ibm-bsd$UNAME_RELEASE # 4.3 with uname added to + ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + GUESS=rs6000-bull-bosx + ;; + DPX/2?00:B.O.S.:*:*) + GUESS=m68k-bull-sysv3 + ;; + 9000/[34]??:4.3bsd:1.*:*) + GUESS=m68k-hp-bsd + ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + GUESS=m68k-hp-bsd4.4 + ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` + case $UNAME_MACHINE in + 9000/31?) HP_ARCH=m68000 ;; + 9000/[34]??) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if test -x /usr/bin/getconf; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case $sc_cpu_version in + 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 + 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case $sc_kernel_bits in + 32) HP_ARCH=hppa2.0n ;; + 64) HP_ARCH=hppa2.0w ;; + '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 + esac ;; + esac + fi + if test "$HP_ARCH" = ""; then + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if test "$HP_ARCH" = hppa2.0w + then + set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH=hppa2.0w + else + HP_ARCH=hppa64 + fi + fi + GUESS=$HP_ARCH-hp-hpux$HPUX_REV + ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` + GUESS=ia64-hp-hpux$HPUX_REV + ;; + 3050*:HI-UX:*:*) + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && + { echo "$SYSTEM_NAME"; exit; } + GUESS=unknown-hitachi-hiuxwe2 + ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) + GUESS=hppa1.1-hp-bsd + ;; + 9000/8??:4.3bsd:*:*) + GUESS=hppa1.0-hp-bsd + ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + GUESS=hppa1.0-hp-mpeix + ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) + GUESS=hppa1.1-hp-osf + ;; + hp8??:OSF1:*:*) + GUESS=hppa1.0-hp-osf + ;; + i*86:OSF1:*:*) + if test -x /usr/sbin/sysversion ; then + GUESS=$UNAME_MACHINE-unknown-osf1mk + else + GUESS=$UNAME_MACHINE-unknown-osf1 + fi + ;; + parisc*:Lites*:*:*) + GUESS=hppa1.1-hp-lites + ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + GUESS=c1-convex-bsd + ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + GUESS=c34-convex-bsd + ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + GUESS=c38-convex-bsd + ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + GUESS=c4-convex-bsd + ;; + CRAY*Y-MP:*:*:*) + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=ymp-cray-unicos$CRAY_REL + ;; + CRAY*[A-Z]90:*:*:*) + echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=t90-cray-unicos$CRAY_REL + ;; + CRAY*T3E:*:*:*) + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=alphaev5-cray-unicosmk$CRAY_REL + ;; + CRAY*SV1:*:*:*) + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=sv1-cray-unicos$CRAY_REL + ;; + *:UNICOS/mp:*:*) + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=craynv-cray-unicosmp$CRAY_REL + ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` + GUESS=${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} + ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` + GUESS=sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} + ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + GUESS=$UNAME_MACHINE-pc-bsdi$UNAME_RELEASE + ;; + sparc*:BSD/OS:*:*) + GUESS=sparc-unknown-bsdi$UNAME_RELEASE + ;; + *:BSD/OS:*:*) + GUESS=$UNAME_MACHINE-unknown-bsdi$UNAME_RELEASE + ;; + arm:FreeBSD:*:*) + UNAME_PROCESSOR=`uname -p` + set_cc_for_build + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabi + else + FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabihf + fi + ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`uname -p` + case $UNAME_PROCESSOR in + amd64) + UNAME_PROCESSOR=x86_64 ;; + i386) + UNAME_PROCESSOR=i586 ;; + esac + FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL + ;; + i*:CYGWIN*:*) + GUESS=$UNAME_MACHINE-pc-cygwin + ;; + *:MINGW64*:*) + GUESS=$UNAME_MACHINE-pc-mingw64 + ;; + *:MINGW*:*) + GUESS=$UNAME_MACHINE-pc-mingw32 + ;; + *:MSYS*:*) + GUESS=$UNAME_MACHINE-pc-msys + ;; + i*:PW*:*) + GUESS=$UNAME_MACHINE-pc-pw32 + ;; + *:SerenityOS:*:*) + GUESS=$UNAME_MACHINE-pc-serenity + ;; + *:Interix*:*) + case $UNAME_MACHINE in + x86) + GUESS=i586-pc-interix$UNAME_RELEASE + ;; + authenticamd | genuineintel | EM64T) + GUESS=x86_64-unknown-interix$UNAME_RELEASE + ;; + IA64) + GUESS=ia64-unknown-interix$UNAME_RELEASE + ;; + esac ;; + i*:UWIN*:*) + GUESS=$UNAME_MACHINE-pc-uwin + ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + GUESS=x86_64-pc-cygwin + ;; + prep*:SunOS:5.*:*) + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=powerpcle-unknown-solaris2$SUN_REL + ;; + *:GNU:*:*) + # the GNU system + GNU_ARCH=`echo "$UNAME_MACHINE" | sed -e 's,[-/].*$,,'` + GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's,/.*$,,'` + GUESS=$GNU_ARCH-unknown-$LIBC$GNU_REL + ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + GNU_SYS=`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"` + GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC + ;; + x86_64:[Mm]anagarm:*:*|i?86:[Mm]anagarm:*:*) + GUESS="$UNAME_MACHINE-pc-managarm-mlibc" + ;; + *:[Mm]anagarm:*:*) + GUESS="$UNAME_MACHINE-unknown-managarm-mlibc" + ;; + *:Minix:*:*) + GUESS=$UNAME_MACHINE-unknown-minix + ;; + aarch64:Linux:*:*) + set_cc_for_build + CPU=$UNAME_MACHINE + LIBCABI=$LIBC + if test "$CC_FOR_BUILD" != no_compiler_found; then + ABI=64 + sed 's/^ //' << EOF > "$dummy.c" + #ifdef __ARM_EABI__ + #ifdef __ARM_PCS_VFP + ABI=eabihf + #else + ABI=eabi + #endif + #endif +EOF + cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'` + eval "$cc_set_abi" + case $ABI in + eabi | eabihf) CPU=armv8l; LIBCABI=$LIBC$ABI ;; + esac + fi + GUESS=$CPU-unknown-linux-$LIBCABI + ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC=gnulibc1 ; fi + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + arc:Linux:*:* | arceb:Linux:*:* | arc32:Linux:*:* | arc64:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + arm*:Linux:*:*) + set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabi + else + GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabihf + fi + fi + ;; + avr32*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + cris:Linux:*:*) + GUESS=$UNAME_MACHINE-axis-linux-$LIBC + ;; + crisv32:Linux:*:*) + GUESS=$UNAME_MACHINE-axis-linux-$LIBC + ;; + e2k:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + frv:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + hexagon:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + i*86:Linux:*:*) + GUESS=$UNAME_MACHINE-pc-linux-$LIBC + ;; + ia64:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + k1om:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + kvx:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + kvx:cos:*:*) + GUESS=$UNAME_MACHINE-unknown-cos + ;; + kvx:mbr:*:*) + GUESS=$UNAME_MACHINE-unknown-mbr + ;; + loongarch32:Linux:*:* | loongarch64:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + m32r*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + m68*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + mips:Linux:*:* | mips64:Linux:*:*) + set_cc_for_build + IS_GLIBC=0 + test x"${LIBC}" = xgnu && IS_GLIBC=1 + sed 's/^ //' << EOF > "$dummy.c" + #undef CPU + #undef mips + #undef mipsel + #undef mips64 + #undef mips64el + #if ${IS_GLIBC} && defined(_ABI64) + LIBCABI=gnuabi64 + #else + #if ${IS_GLIBC} && defined(_ABIN32) + LIBCABI=gnuabin32 + #else + LIBCABI=${LIBC} + #endif + #endif + + #if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa64r6 + #else + #if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa32r6 + #else + #if defined(__mips64) + CPU=mips64 + #else + CPU=mips + #endif + #endif + #endif + + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + MIPS_ENDIAN=el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + MIPS_ENDIAN= + #else + MIPS_ENDIAN= + #endif + #endif +EOF + cc_set_vars=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'` + eval "$cc_set_vars" + test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; } + ;; + mips64el:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + openrisc*:Linux:*:*) + GUESS=or1k-unknown-linux-$LIBC + ;; + or32:Linux:*:* | or1k*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + padre:Linux:*:*) + GUESS=sparc-unknown-linux-$LIBC + ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + GUESS=hppa64-unknown-linux-$LIBC + ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) GUESS=hppa1.1-unknown-linux-$LIBC ;; + PA8*) GUESS=hppa2.0-unknown-linux-$LIBC ;; + *) GUESS=hppa-unknown-linux-$LIBC ;; + esac + ;; + ppc64:Linux:*:*) + GUESS=powerpc64-unknown-linux-$LIBC + ;; + ppc:Linux:*:*) + GUESS=powerpc-unknown-linux-$LIBC + ;; + ppc64le:Linux:*:*) + GUESS=powerpc64le-unknown-linux-$LIBC + ;; + ppcle:Linux:*:*) + GUESS=powerpcle-unknown-linux-$LIBC + ;; + riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + s390:Linux:*:* | s390x:Linux:*:*) + GUESS=$UNAME_MACHINE-ibm-linux-$LIBC + ;; + sh64*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + sh*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + tile*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + vax:Linux:*:*) + GUESS=$UNAME_MACHINE-dec-linux-$LIBC + ;; + x86_64:Linux:*:*) + set_cc_for_build + CPU=$UNAME_MACHINE + LIBCABI=$LIBC + if test "$CC_FOR_BUILD" != no_compiler_found; then + ABI=64 + sed 's/^ //' << EOF > "$dummy.c" + #ifdef __i386__ + ABI=x86 + #else + #ifdef __ILP32__ + ABI=x32 + #endif + #endif +EOF + cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'` + eval "$cc_set_abi" + case $ABI in + x86) CPU=i686 ;; + x32) LIBCABI=${LIBC}x32 ;; + esac + fi + GUESS=$CPU-pc-linux-$LIBCABI + ;; + xtensa*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + GUESS=i386-sequent-sysv4 + ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION + ;; + i*86:OS/2:*:*) + # If we were able to find 'uname', then EMX Unix compatibility + # is probably installed. + GUESS=$UNAME_MACHINE-pc-os2-emx + ;; + i*86:XTS-300:*:STOP) + GUESS=$UNAME_MACHINE-unknown-stop + ;; + i*86:atheos:*:*) + GUESS=$UNAME_MACHINE-unknown-atheos + ;; + i*86:syllable:*:*) + GUESS=$UNAME_MACHINE-pc-syllable + ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + GUESS=i386-unknown-lynxos$UNAME_RELEASE + ;; + i*86:*DOS:*:*) + GUESS=$UNAME_MACHINE-pc-msdosdjgpp + ;; + i*86:*:4.*:*) + UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + GUESS=$UNAME_MACHINE-univel-sysv$UNAME_REL + else + GUESS=$UNAME_MACHINE-pc-sysv$UNAME_REL + fi + ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + GUESS=$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + GUESS=$UNAME_MACHINE-pc-sco$UNAME_REL + else + GUESS=$UNAME_MACHINE-pc-sysv32 + fi + ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configure will decide that + # this is a cross-build. + GUESS=i586-pc-msdosdjgpp + ;; + Intel:Mach:3*:*) + GUESS=i386-pc-mach3 + ;; + paragon:*:*:*) + GUESS=i860-intel-osf1 + ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + GUESS=i860-stardent-sysv$UNAME_RELEASE # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + GUESS=i860-unknown-sysv$UNAME_RELEASE # Unknown i860-SVR4 + fi + ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + GUESS=m68010-convergent-sysv + ;; + mc68k:UNIX:SYSTEM5:3.51m) + GUESS=m68k-convergent-sysv + ;; + M680?0:D-NIX:5.3:*) + GUESS=m68k-diab-dnix + ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + GUESS=m68k-unknown-lynxos$UNAME_RELEASE + ;; + mc68030:UNIX_System_V:4.*:*) + GUESS=m68k-atari-sysv4 + ;; + TSUNAMI:LynxOS:2.*:*) + GUESS=sparc-unknown-lynxos$UNAME_RELEASE + ;; + rs6000:LynxOS:2.*:*) + GUESS=rs6000-unknown-lynxos$UNAME_RELEASE + ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + GUESS=powerpc-unknown-lynxos$UNAME_RELEASE + ;; + SM[BE]S:UNIX_SV:*:*) + GUESS=mips-dde-sysv$UNAME_RELEASE + ;; + RM*:ReliantUNIX-*:*:*) + GUESS=mips-sni-sysv4 + ;; + RM*:SINIX-*:*:*) + GUESS=mips-sni-sysv4 + ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + GUESS=$UNAME_MACHINE-sni-sysv4 + else + GUESS=ns32k-sni-sysv + fi + ;; + PENTIUM:*:4.0*:*) # Unisys 'ClearPath HMP IX 4000' SVR4/MP effort + # says + GUESS=i586-unisys-sysv4 + ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + GUESS=hppa1.1-stratus-sysv4 + ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + GUESS=i860-stratus-sysv4 + ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + GUESS=$UNAME_MACHINE-stratus-vos + ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + GUESS=hppa1.1-stratus-vos + ;; + mc68*:A/UX:*:*) + GUESS=m68k-apple-aux$UNAME_RELEASE + ;; + news*:NEWS-OS:6*:*) + GUESS=mips-sony-newsos6 + ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if test -d /usr/nec; then + GUESS=mips-nec-sysv$UNAME_RELEASE + else + GUESS=mips-unknown-sysv$UNAME_RELEASE + fi + ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + GUESS=powerpc-be-beos + ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + GUESS=powerpc-apple-beos + ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + GUESS=i586-pc-beos + ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + GUESS=i586-pc-haiku + ;; + ppc:Haiku:*:*) # Haiku running on Apple PowerPC + GUESS=powerpc-apple-haiku + ;; + *:Haiku:*:*) # Haiku modern gcc (not bound by BeOS compat) + GUESS=$UNAME_MACHINE-unknown-haiku + ;; + SX-4:SUPER-UX:*:*) + GUESS=sx4-nec-superux$UNAME_RELEASE + ;; + SX-5:SUPER-UX:*:*) + GUESS=sx5-nec-superux$UNAME_RELEASE + ;; + SX-6:SUPER-UX:*:*) + GUESS=sx6-nec-superux$UNAME_RELEASE + ;; + SX-7:SUPER-UX:*:*) + GUESS=sx7-nec-superux$UNAME_RELEASE + ;; + SX-8:SUPER-UX:*:*) + GUESS=sx8-nec-superux$UNAME_RELEASE + ;; + SX-8R:SUPER-UX:*:*) + GUESS=sx8r-nec-superux$UNAME_RELEASE + ;; + SX-ACE:SUPER-UX:*:*) + GUESS=sxace-nec-superux$UNAME_RELEASE + ;; + Power*:Rhapsody:*:*) + GUESS=powerpc-apple-rhapsody$UNAME_RELEASE + ;; + *:Rhapsody:*:*) + GUESS=$UNAME_MACHINE-apple-rhapsody$UNAME_RELEASE + ;; + arm64:Darwin:*:*) + GUESS=aarch64-apple-darwin$UNAME_RELEASE + ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` + case $UNAME_PROCESSOR in + unknown) UNAME_PROCESSOR=powerpc ;; + esac + if command -v xcode-select > /dev/null 2> /dev/null && \ + ! xcode-select --print-path > /dev/null 2> /dev/null ; then + # Avoid executing cc if there is no toolchain installed as + # cc will be a stub that puts up a graphical alert + # prompting the user to install developer tools. + CC_FOR_BUILD=no_compiler_found + else + set_cc_for_build + fi + if test "$CC_FOR_BUILD" != no_compiler_found; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc + if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_PPC >/dev/null + then + UNAME_PROCESSOR=powerpc + fi + elif test "$UNAME_PROCESSOR" = i386 ; then + # uname -m returns i386 or x86_64 + UNAME_PROCESSOR=$UNAME_MACHINE + fi + GUESS=$UNAME_PROCESSOR-apple-darwin$UNAME_RELEASE + ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = x86; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + GUESS=$UNAME_PROCESSOR-$UNAME_MACHINE-nto-qnx$UNAME_RELEASE + ;; + *:QNX:*:4*) + GUESS=i386-pc-qnx + ;; + NEO-*:NONSTOP_KERNEL:*:*) + GUESS=neo-tandem-nsk$UNAME_RELEASE + ;; + NSE-*:NONSTOP_KERNEL:*:*) + GUESS=nse-tandem-nsk$UNAME_RELEASE + ;; + NSR-*:NONSTOP_KERNEL:*:*) + GUESS=nsr-tandem-nsk$UNAME_RELEASE + ;; + NSV-*:NONSTOP_KERNEL:*:*) + GUESS=nsv-tandem-nsk$UNAME_RELEASE + ;; + NSX-*:NONSTOP_KERNEL:*:*) + GUESS=nsx-tandem-nsk$UNAME_RELEASE + ;; + *:NonStop-UX:*:*) + GUESS=mips-compaq-nonstopux + ;; + BS2000:POSIX*:*:*) + GUESS=bs2000-siemens-sysv + ;; + DS/*:UNIX_System_V:*:*) + GUESS=$UNAME_MACHINE-$UNAME_SYSTEM-$UNAME_RELEASE + ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "${cputype-}" = 386; then + UNAME_MACHINE=i386 + elif test "x${cputype-}" != x; then + UNAME_MACHINE=$cputype + fi + GUESS=$UNAME_MACHINE-unknown-plan9 + ;; + *:TOPS-10:*:*) + GUESS=pdp10-unknown-tops10 + ;; + *:TENEX:*:*) + GUESS=pdp10-unknown-tenex + ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + GUESS=pdp10-dec-tops20 + ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + GUESS=pdp10-xkl-tops20 + ;; + *:TOPS-20:*:*) + GUESS=pdp10-unknown-tops20 + ;; + *:ITS:*:*) + GUESS=pdp10-unknown-its + ;; + SEI:*:*:SEIUX) + GUESS=mips-sei-seiux$UNAME_RELEASE + ;; + *:DragonFly:*:*) + DRAGONFLY_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_MACHINE-unknown-dragonfly$DRAGONFLY_REL + ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case $UNAME_MACHINE in + A*) GUESS=alpha-dec-vms ;; + I*) GUESS=ia64-dec-vms ;; + V*) GUESS=vax-dec-vms ;; + esac ;; + *:XENIX:*:SysV) + GUESS=i386-pc-xenix + ;; + i*86:skyos:*:*) + SKYOS_REL=`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'` + GUESS=$UNAME_MACHINE-pc-skyos$SKYOS_REL + ;; + i*86:rdos:*:*) + GUESS=$UNAME_MACHINE-pc-rdos + ;; + i*86:Fiwix:*:*) + GUESS=$UNAME_MACHINE-pc-fiwix + ;; + *:AROS:*:*) + GUESS=$UNAME_MACHINE-unknown-aros + ;; + x86_64:VMkernel:*:*) + GUESS=$UNAME_MACHINE-unknown-esx + ;; + amd64:Isilon\ OneFS:*:*) + GUESS=x86_64-unknown-onefs + ;; + *:Unleashed:*:*) + GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE + ;; + *:Ironclad:*:*) + GUESS=$UNAME_MACHINE-unknown-ironclad + ;; +esac + +# Do we have a guess based on uname results? +if test "x$GUESS" != x; then + echo "$GUESS" + exit +fi + +# No uname command or uname output not recognized. +set_cc_for_build +cat > "$dummy.c" < +#include +#endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#include +#if defined(_SIZE_T_) || defined(SIGLOST) +#include +#endif +#endif +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); +#endif + +#if defined (vax) +#if !defined (ultrix) +#include +#if defined (BSD) +#if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +#else +#if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#endif +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#else +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname un; + uname (&un); + printf ("vax-dec-ultrix%s\n", un.release); exit (0); +#else + printf ("vax-dec-ultrix\n"); exit (0); +#endif +#endif +#endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname *un; + uname (&un); + printf ("mips-dec-ultrix%s\n", un.release); exit (0); +#else + printf ("mips-dec-ultrix\n"); exit (0); +#endif +#endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`"$dummy"` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. +test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; } + +echo "$0: unable to guess system type" >&2 + +case $UNAME_MACHINE:$UNAME_SYSTEM in + mips:Linux | mips64:Linux) + # If we got here on MIPS GNU/Linux, output extra information. + cat >&2 <&2 <&2 </dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = "$UNAME_MACHINE" +UNAME_RELEASE = "$UNAME_RELEASE" +UNAME_SYSTEM = "$UNAME_SYSTEM" +UNAME_VERSION = "$UNAME_VERSION" +EOF +fi + +exit 1 + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/SDL2-2.30.5/build-scripts/config.sub b/SDL2-2.30.5/build-scripts/config.sub new file mode 100644 index 0000000..2c6a07a --- /dev/null +++ b/SDL2-2.30.5/build-scripts/config.sub @@ -0,0 +1,1971 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright 1992-2024 Free Software Foundation, Inc. + +# shellcheck disable=SC2006,SC2268 # see below for rationale + +timestamp='2024-01-01' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). + + +# Please send patches to . +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# https://git.savannah.gnu.org/cgit/config.git/plain/config.sub + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +# The "shellcheck disable" line above the timestamp inhibits complaints +# about features and limitations of the classic Bourne shell that were +# superseded or lifted in POSIX. However, this script identifies a wide +# variety of pre-POSIX systems that do not have POSIX shells at all, and +# even some reasonably current systems (Solaris 10 as case-in-point) still +# have a pre-POSIX /bin/sh. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS + +Canonicalize a configuration name. + +Options: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright 1992-2024 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try '$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo "$1" + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Split fields of configuration type +# shellcheck disable=SC2162 +saved_IFS=$IFS +IFS="-" read field1 field2 field3 field4 <&2 + exit 1 + ;; + *-*-*-*) + basic_machine=$field1-$field2 + basic_os=$field3-$field4 + ;; + *-*-*) + # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two + # parts + maybe_os=$field2-$field3 + case $maybe_os in + nto-qnx* | linux-* | uclinux-uclibc* \ + | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \ + | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \ + | storm-chaos* | os2-emx* | rtmk-nova* | managarm-* \ + | windows-* ) + basic_machine=$field1 + basic_os=$maybe_os + ;; + android-linux) + basic_machine=$field1-unknown + basic_os=linux-android + ;; + *) + basic_machine=$field1-$field2 + basic_os=$field3 + ;; + esac + ;; + *-*) + # A lone config we happen to match not fitting any pattern + case $field1-$field2 in + decstation-3100) + basic_machine=mips-dec + basic_os= + ;; + *-*) + # Second component is usually, but not always the OS + case $field2 in + # Prevent following clause from handling this valid os + sun*os*) + basic_machine=$field1 + basic_os=$field2 + ;; + zephyr*) + basic_machine=$field1-unknown + basic_os=$field2 + ;; + # Manufacturers + dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \ + | att* | 7300* | 3300* | delta* | motorola* | sun[234]* \ + | unicom* | ibm* | next | hp | isi* | apollo | altos* \ + | convergent* | ncr* | news | 32* | 3600* | 3100* \ + | hitachi* | c[123]* | convex* | sun | crds | omron* | dg \ + | ultra | tti* | harris | dolphin | highlevel | gould \ + | cbm | ns | masscomp | apple | axis | knuth | cray \ + | microblaze* | sim | cisco \ + | oki | wec | wrs | winbond) + basic_machine=$field1-$field2 + basic_os= + ;; + *) + basic_machine=$field1 + basic_os=$field2 + ;; + esac + ;; + esac + ;; + *) + # Convert single-component short-hands not valid as part of + # multi-component configurations. + case $field1 in + 386bsd) + basic_machine=i386-pc + basic_os=bsd + ;; + a29khif) + basic_machine=a29k-amd + basic_os=udi + ;; + adobe68k) + basic_machine=m68010-adobe + basic_os=scout + ;; + alliant) + basic_machine=fx80-alliant + basic_os= + ;; + altos | altos3068) + basic_machine=m68k-altos + basic_os= + ;; + am29k) + basic_machine=a29k-none + basic_os=bsd + ;; + amdahl) + basic_machine=580-amdahl + basic_os=sysv + ;; + amiga) + basic_machine=m68k-unknown + basic_os= + ;; + amigaos | amigados) + basic_machine=m68k-unknown + basic_os=amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + basic_os=sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + basic_os=sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + basic_os=bsd + ;; + aros) + basic_machine=i386-pc + basic_os=aros + ;; + aux) + basic_machine=m68k-apple + basic_os=aux + ;; + balance) + basic_machine=ns32k-sequent + basic_os=dynix + ;; + blackfin) + basic_machine=bfin-unknown + basic_os=linux + ;; + cegcc) + basic_machine=arm-unknown + basic_os=cegcc + ;; + convex-c1) + basic_machine=c1-convex + basic_os=bsd + ;; + convex-c2) + basic_machine=c2-convex + basic_os=bsd + ;; + convex-c32) + basic_machine=c32-convex + basic_os=bsd + ;; + convex-c34) + basic_machine=c34-convex + basic_os=bsd + ;; + convex-c38) + basic_machine=c38-convex + basic_os=bsd + ;; + cray) + basic_machine=j90-cray + basic_os=unicos + ;; + crds | unos) + basic_machine=m68k-crds + basic_os= + ;; + da30) + basic_machine=m68k-da30 + basic_os= + ;; + decstation | pmax | pmin | dec3100 | decstatn) + basic_machine=mips-dec + basic_os= + ;; + delta88) + basic_machine=m88k-motorola + basic_os=sysv3 + ;; + dicos) + basic_machine=i686-pc + basic_os=dicos + ;; + djgpp) + basic_machine=i586-pc + basic_os=msdosdjgpp + ;; + ebmon29k) + basic_machine=a29k-amd + basic_os=ebmon + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + basic_os=ose + ;; + gmicro) + basic_machine=tron-gmicro + basic_os=sysv + ;; + go32) + basic_machine=i386-pc + basic_os=go32 + ;; + h8300hms) + basic_machine=h8300-hitachi + basic_os=hms + ;; + h8300xray) + basic_machine=h8300-hitachi + basic_os=xray + ;; + h8500hms) + basic_machine=h8500-hitachi + basic_os=hms + ;; + harris) + basic_machine=m88k-harris + basic_os=sysv3 + ;; + hp300 | hp300hpux) + basic_machine=m68k-hp + basic_os=hpux + ;; + hp300bsd) + basic_machine=m68k-hp + basic_os=bsd + ;; + hppaosf) + basic_machine=hppa1.1-hp + basic_os=osf + ;; + hppro) + basic_machine=hppa1.1-hp + basic_os=proelf + ;; + i386mach) + basic_machine=i386-mach + basic_os=mach + ;; + isi68 | isi) + basic_machine=m68k-isi + basic_os=sysv + ;; + m68knommu) + basic_machine=m68k-unknown + basic_os=linux + ;; + magnum | m3230) + basic_machine=mips-mips + basic_os=sysv + ;; + merlin) + basic_machine=ns32k-utek + basic_os=sysv + ;; + mingw64) + basic_machine=x86_64-pc + basic_os=mingw64 + ;; + mingw32) + basic_machine=i686-pc + basic_os=mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + basic_os=mingw32ce + ;; + monitor) + basic_machine=m68k-rom68k + basic_os=coff + ;; + morphos) + basic_machine=powerpc-unknown + basic_os=morphos + ;; + moxiebox) + basic_machine=moxie-unknown + basic_os=moxiebox + ;; + msdos) + basic_machine=i386-pc + basic_os=msdos + ;; + msys) + basic_machine=i686-pc + basic_os=msys + ;; + mvs) + basic_machine=i370-ibm + basic_os=mvs + ;; + nacl) + basic_machine=le32-unknown + basic_os=nacl + ;; + ncr3000) + basic_machine=i486-ncr + basic_os=sysv4 + ;; + netbsd386) + basic_machine=i386-pc + basic_os=netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + basic_os=linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + basic_os=newsos + ;; + news1000) + basic_machine=m68030-sony + basic_os=newsos + ;; + necv70) + basic_machine=v70-nec + basic_os=sysv + ;; + nh3000) + basic_machine=m68k-harris + basic_os=cxux + ;; + nh[45]000) + basic_machine=m88k-harris + basic_os=cxux + ;; + nindy960) + basic_machine=i960-intel + basic_os=nindy + ;; + mon960) + basic_machine=i960-intel + basic_os=mon960 + ;; + nonstopux) + basic_machine=mips-compaq + basic_os=nonstopux + ;; + os400) + basic_machine=powerpc-ibm + basic_os=os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + basic_os=ose + ;; + os68k) + basic_machine=m68k-none + basic_os=os68k + ;; + paragon) + basic_machine=i860-intel + basic_os=osf + ;; + parisc) + basic_machine=hppa-unknown + basic_os=linux + ;; + psp) + basic_machine=mipsallegrexel-sony + basic_os=psp + ;; + pw32) + basic_machine=i586-unknown + basic_os=pw32 + ;; + rdos | rdos64) + basic_machine=x86_64-pc + basic_os=rdos + ;; + rdos32) + basic_machine=i386-pc + basic_os=rdos + ;; + rom68k) + basic_machine=m68k-rom68k + basic_os=coff + ;; + sa29200) + basic_machine=a29k-amd + basic_os=udi + ;; + sei) + basic_machine=mips-sei + basic_os=seiux + ;; + sequent) + basic_machine=i386-sequent + basic_os= + ;; + sps7) + basic_machine=m68k-bull + basic_os=sysv2 + ;; + st2000) + basic_machine=m68k-tandem + basic_os= + ;; + stratus) + basic_machine=i860-stratus + basic_os=sysv4 + ;; + sun2) + basic_machine=m68000-sun + basic_os= + ;; + sun2os3) + basic_machine=m68000-sun + basic_os=sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + basic_os=sunos4 + ;; + sun3) + basic_machine=m68k-sun + basic_os= + ;; + sun3os3) + basic_machine=m68k-sun + basic_os=sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + basic_os=sunos4 + ;; + sun4) + basic_machine=sparc-sun + basic_os= + ;; + sun4os3) + basic_machine=sparc-sun + basic_os=sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + basic_os=sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + basic_os=solaris2 + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + basic_os= + ;; + sv1) + basic_machine=sv1-cray + basic_os=unicos + ;; + symmetry) + basic_machine=i386-sequent + basic_os=dynix + ;; + t3e) + basic_machine=alphaev5-cray + basic_os=unicos + ;; + t90) + basic_machine=t90-cray + basic_os=unicos + ;; + toad1) + basic_machine=pdp10-xkl + basic_os=tops20 + ;; + tpf) + basic_machine=s390x-ibm + basic_os=tpf + ;; + udi29k) + basic_machine=a29k-amd + basic_os=udi + ;; + ultra3) + basic_machine=a29k-nyu + basic_os=sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + basic_os=none + ;; + vaxv) + basic_machine=vax-dec + basic_os=sysv + ;; + vms) + basic_machine=vax-dec + basic_os=vms + ;; + vsta) + basic_machine=i386-pc + basic_os=vsta + ;; + vxworks960) + basic_machine=i960-wrs + basic_os=vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + basic_os=vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + basic_os=vxworks + ;; + xbox) + basic_machine=i686-pc + basic_os=mingw32 + ;; + ymp) + basic_machine=ymp-cray + basic_os=unicos + ;; + *) + basic_machine=$1 + basic_os= + ;; + esac + ;; +esac + +# Decode 1-component or ad-hoc basic machines +case $basic_machine in + # Here we handle the default manufacturer of certain CPU types. It is in + # some cases the only manufacturer, in others, it is the most popular. + w89k) + cpu=hppa1.1 + vendor=winbond + ;; + op50n) + cpu=hppa1.1 + vendor=oki + ;; + op60c) + cpu=hppa1.1 + vendor=oki + ;; + ibm*) + cpu=i370 + vendor=ibm + ;; + orion105) + cpu=clipper + vendor=highlevel + ;; + mac | mpw | mac-mpw) + cpu=m68k + vendor=apple + ;; + pmac | pmac-mpw) + cpu=powerpc + vendor=apple + ;; + + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + cpu=m68000 + vendor=att + ;; + 3b*) + cpu=we32k + vendor=att + ;; + bluegene*) + cpu=powerpc + vendor=ibm + basic_os=cnk + ;; + decsystem10* | dec10*) + cpu=pdp10 + vendor=dec + basic_os=tops10 + ;; + decsystem20* | dec20*) + cpu=pdp10 + vendor=dec + basic_os=tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + cpu=m68k + vendor=motorola + ;; + dpx2*) + cpu=m68k + vendor=bull + basic_os=sysv3 + ;; + encore | umax | mmax) + cpu=ns32k + vendor=encore + ;; + elxsi) + cpu=elxsi + vendor=elxsi + basic_os=${basic_os:-bsd} + ;; + fx2800) + cpu=i860 + vendor=alliant + ;; + genix) + cpu=ns32k + vendor=ns + ;; + h3050r* | hiux*) + cpu=hppa1.1 + vendor=hitachi + basic_os=hiuxwe2 + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + cpu=hppa1.0 + vendor=hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + cpu=m68000 + vendor=hp + ;; + hp9k3[2-9][0-9]) + cpu=m68k + vendor=hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + cpu=hppa1.0 + vendor=hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + cpu=hppa1.1 + vendor=hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + cpu=hppa1.1 + vendor=hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + cpu=hppa1.1 + vendor=hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + cpu=hppa1.1 + vendor=hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + cpu=hppa1.0 + vendor=hp + ;; + i*86v32) + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=sysv32 + ;; + i*86v4*) + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=sysv4 + ;; + i*86v) + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=sysv + ;; + i*86sol2) + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=solaris2 + ;; + j90 | j90-cray) + cpu=j90 + vendor=cray + basic_os=${basic_os:-unicos} + ;; + iris | iris4d) + cpu=mips + vendor=sgi + case $basic_os in + irix*) + ;; + *) + basic_os=irix4 + ;; + esac + ;; + miniframe) + cpu=m68000 + vendor=convergent + ;; + *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*) + cpu=m68k + vendor=atari + basic_os=mint + ;; + news-3600 | risc-news) + cpu=mips + vendor=sony + basic_os=newsos + ;; + next | m*-next) + cpu=m68k + vendor=next + case $basic_os in + openstep*) + ;; + nextstep*) + ;; + ns2*) + basic_os=nextstep2 + ;; + *) + basic_os=nextstep3 + ;; + esac + ;; + np1) + cpu=np1 + vendor=gould + ;; + op50n-* | op60c-*) + cpu=hppa1.1 + vendor=oki + basic_os=proelf + ;; + pa-hitachi) + cpu=hppa1.1 + vendor=hitachi + basic_os=hiuxwe2 + ;; + pbd) + cpu=sparc + vendor=tti + ;; + pbb) + cpu=m68k + vendor=tti + ;; + pc532) + cpu=ns32k + vendor=pc532 + ;; + pn) + cpu=pn + vendor=gould + ;; + power) + cpu=power + vendor=ibm + ;; + ps2) + cpu=i386 + vendor=ibm + ;; + rm[46]00) + cpu=mips + vendor=siemens + ;; + rtpc | rtpc-*) + cpu=romp + vendor=ibm + ;; + sde) + cpu=mipsisa32 + vendor=sde + basic_os=${basic_os:-elf} + ;; + simso-wrs) + cpu=sparclite + vendor=wrs + basic_os=vxworks + ;; + tower | tower-32) + cpu=m68k + vendor=ncr + ;; + vpp*|vx|vx-*) + cpu=f301 + vendor=fujitsu + ;; + w65) + cpu=w65 + vendor=wdc + ;; + w89k-*) + cpu=hppa1.1 + vendor=winbond + basic_os=proelf + ;; + none) + cpu=none + vendor=none + ;; + leon|leon[3-9]) + cpu=sparc + vendor=$basic_machine + ;; + leon-*|leon[3-9]-*) + cpu=sparc + vendor=`echo "$basic_machine" | sed 's/-.*//'` + ;; + + *-*) + # shellcheck disable=SC2162 + saved_IFS=$IFS + IFS="-" read cpu vendor <&2 + exit 1 + ;; + esac + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $vendor in + digital*) + vendor=dec + ;; + commodore*) + vendor=cbm + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if test x"$basic_os" != x +then + +# First recognize some ad-hoc cases, or perhaps split kernel-os, or else just +# set os. +obj= +case $basic_os in + gnu/linux*) + kernel=linux + os=`echo "$basic_os" | sed -e 's|gnu/linux|gnu|'` + ;; + os2-emx) + kernel=os2 + os=`echo "$basic_os" | sed -e 's|os2-emx|emx|'` + ;; + nto-qnx*) + kernel=nto + os=`echo "$basic_os" | sed -e 's|nto-qnx|qnx|'` + ;; + *-*) + # shellcheck disable=SC2162 + saved_IFS=$IFS + IFS="-" read kernel os <&2 + fi + ;; + *) + echo "Invalid configuration '$1': OS '$os' not recognized" 1>&2 + exit 1 + ;; +esac + +case $obj in + aout* | coff* | elf* | pe*) + ;; + '') + # empty is fine + ;; + *) + echo "Invalid configuration '$1': Machine code format '$obj' not recognized" 1>&2 + exit 1 + ;; +esac + +# Here we handle the constraint that a (synthetic) cpu and os are +# valid only in combination with each other and nowhere else. +case $cpu-$os in + # The "javascript-unknown-ghcjs" triple is used by GHC; we + # accept it here in order to tolerate that, but reject any + # variations. + javascript-ghcjs) + ;; + javascript-* | *-ghcjs) + echo "Invalid configuration '$1': cpu '$cpu' is not valid with os '$os$obj'" 1>&2 + exit 1 + ;; +esac + +# As a final step for OS-related things, validate the OS-kernel combination +# (given a valid OS), if there is a kernel. +case $kernel-$os-$obj in + linux-gnu*- | linux-android*- | linux-dietlibc*- | linux-llvm*- \ + | linux-mlibc*- | linux-musl*- | linux-newlib*- \ + | linux-relibc*- | linux-uclibc*- ) + ;; + uclinux-uclibc*- ) + ;; + managarm-mlibc*- | managarm-kernel*- ) + ;; + windows*-msvc*-) + ;; + -dietlibc*- | -llvm*- | -mlibc*- | -musl*- | -newlib*- | -relibc*- \ + | -uclibc*- ) + # These are just libc implementations, not actual OSes, and thus + # require a kernel. + echo "Invalid configuration '$1': libc '$os' needs explicit kernel." 1>&2 + exit 1 + ;; + -kernel*- ) + echo "Invalid configuration '$1': '$os' needs explicit kernel." 1>&2 + exit 1 + ;; + *-kernel*- ) + echo "Invalid configuration '$1': '$kernel' does not support '$os'." 1>&2 + exit 1 + ;; + *-msvc*- ) + echo "Invalid configuration '$1': '$os' needs 'windows'." 1>&2 + exit 1 + ;; + kfreebsd*-gnu*- | kopensolaris*-gnu*-) + ;; + vxworks-simlinux- | vxworks-simwindows- | vxworks-spe-) + ;; + nto-qnx*-) + ;; + os2-emx-) + ;; + *-eabi*- | *-gnueabi*-) + ;; + none--*) + # None (no kernel, i.e. freestanding / bare metal), + # can be paired with an machine code file format + ;; + -*-) + # Blank kernel with real OS is always fine. + ;; + --*) + # Blank kernel and OS with real machine code file format is always fine. + ;; + *-*-*) + echo "Invalid configuration '$1': Kernel '$kernel' not known to work with OS '$os'." 1>&2 + exit 1 + ;; +esac + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +case $vendor in + unknown) + case $cpu-$os in + *-riscix*) + vendor=acorn + ;; + *-sunos*) + vendor=sun + ;; + *-cnk* | *-aix*) + vendor=ibm + ;; + *-beos*) + vendor=be + ;; + *-hpux*) + vendor=hp + ;; + *-mpeix*) + vendor=hp + ;; + *-hiux*) + vendor=hitachi + ;; + *-unos*) + vendor=crds + ;; + *-dgux*) + vendor=dg + ;; + *-luna*) + vendor=omron + ;; + *-genix*) + vendor=ns + ;; + *-clix*) + vendor=intergraph + ;; + *-mvs* | *-opened*) + vendor=ibm + ;; + *-os400*) + vendor=ibm + ;; + s390-* | s390x-*) + vendor=ibm + ;; + *-ptx*) + vendor=sequent + ;; + *-tpf*) + vendor=ibm + ;; + *-vxsim* | *-vxworks* | *-windiss*) + vendor=wrs + ;; + *-aux*) + vendor=apple + ;; + *-hms*) + vendor=hitachi + ;; + *-mpw* | *-macos*) + vendor=apple + ;; + *-*mint | *-mint[0-9]* | *-*MiNT | *-MiNT[0-9]*) + vendor=atari + ;; + *-vos*) + vendor=stratus + ;; + esac + ;; +esac + +echo "$cpu-$vendor${kernel:+-$kernel}${os:+-$os}${obj:+-$obj}" +exit + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/SDL2-2.0.12/build-scripts/emscripten-buildbot.sh b/SDL2-2.30.5/build-scripts/emscripten-buildbot.sh similarity index 81% rename from SDL2-2.0.12/build-scripts/emscripten-buildbot.sh rename to SDL2-2.30.5/build-scripts/emscripten-buildbot.sh index 65b43e8..8538c45 100644 --- a/SDL2-2.0.12/build-scripts/emscripten-buildbot.sh +++ b/SDL2-2.30.5/build-scripts/emscripten-buildbot.sh @@ -1,7 +1,7 @@ #!/bin/bash if [ -z "$SDKDIR" ]; then - SDKDIR="/emsdk_portable" + SDKDIR="/emsdk" fi ENVSCRIPT="$SDKDIR/emsdk_env.sh" @@ -55,7 +55,7 @@ mkdir buildbot pushd buildbot echo "Configuring..." -emconfigure ../configure --host=asmjs-unknown-emscripten --disable-assembly --disable-threads --disable-cpuinfo CFLAGS="-O2 -Wno-warn-absolute-paths -Wdeclaration-after-statement -Werror=declaration-after-statement" --prefix="$PWD/emscripten-sdl2-installed" || exit $? +emconfigure ../configure --host=wasm32-unknown-emscripten --disable-assembly --disable-threads --disable-cpuinfo CFLAGS="-s USE_SDL=0 -O2 -Wno-warn-absolute-paths -Wdeclaration-after-statement -Werror=declaration-after-statement" --prefix="$PWD/emscripten-sdl2-installed" || exit $? echo "Building..." emmake $MAKE || exit $? @@ -67,9 +67,8 @@ emmake $MAKE install || exit $? perl -w -pi -e "s#$PWD/emscripten-sdl2-installed#/usr/local#g;" ./emscripten-sdl2-installed/lib/libSDL2.la ./emscripten-sdl2-installed/lib/pkgconfig/sdl2.pc ./emscripten-sdl2-installed/bin/sdl2-config mkdir -p ./usr mv ./emscripten-sdl2-installed ./usr/local +tar -cJvvf $TARBALL usr popd -tar -cJvvf $TARBALL -C buildbot usr -rm -rf buildbot exit 0 diff --git a/SDL2-2.30.5/build-scripts/fnsince.pl b/SDL2-2.30.5/build-scripts/fnsince.pl new file mode 100644 index 0000000..d49fa54 --- /dev/null +++ b/SDL2-2.30.5/build-scripts/fnsince.pl @@ -0,0 +1,188 @@ +#!/usr/bin/perl -w + +use warnings; +use strict; +use File::Basename; +use Cwd qw(abs_path); + +my $wikipath = undef; +foreach (@ARGV) { + $wikipath = abs_path($_), next if not defined $wikipath; +} + +chdir(dirname(__FILE__)); +chdir('..'); + +my @unsorted_releases = (); +open(PIPEFH, '-|', 'git tag -l') or die "Failed to read git release tags: $!\n"; + +while () { + chomp; + if (/\Arelease\-(.*?)\Z/) { + # After 2.24.x, ignore anything that isn't a x.y.0 release. + # We moved to bugfix-only point releases there, so make sure new APIs + # are assigned to the next minor version and ignore the patch versions. + my $ver = $1; + my @versplit = split /\./, $ver; + next if (scalar(@versplit) > 2) && (($versplit[0] > 2) || (($versplit[0] == 2) && ($versplit[1] >= 24))) && ($versplit[2] != 0); + + # Consider this release version. + push @unsorted_releases, $ver; + } + +} +close(PIPEFH); + +#print("\n\nUNSORTED\n"); +#foreach (@unsorted_releases) { +# print "$_\n"; +#} + +my @releases = sort { + my @asplit = split /\./, $a; + my @bsplit = split /\./, $b; + my $rc; + for (my $i = 0; $i < scalar(@asplit); $i++) { + return 1 if (scalar(@bsplit) <= $i); # a is "2.0.1" and b is "2.0", or whatever. + my $aseg = $asplit[$i]; + my $bseg = $bsplit[$i]; + $rc = int($aseg) <=> int($bseg); + return $rc if ($rc != 0); # found the difference. + } + return 0; # still here? They matched completely?! +} @unsorted_releases; + +# this happens to work for how SDL versions things at the moment. +my $current_release = $releases[-1]; +my $next_release; + +if ($current_release eq '2.0.22') { # Hack for our jump from 2.0.22 to 2.24.0... + $next_release = '2.24.0'; +} else { + my @current_release_segments = split /\./, $current_release; + @current_release_segments[1] = '' . ($current_release_segments[1] + 2); + $next_release = join('.', @current_release_segments); +} + +#print("\n\nSORTED\n"); +#foreach (@releases) { +# print "$_\n"; +#} +#print("\nCURRENT RELEASE: $current_release\n"); +#print("NEXT RELEASE: $next_release\n\n"); + +push @releases, 'HEAD'; + +my %funcs = (); +foreach my $release (@releases) { + #print("Checking $release...\n"); + next if ($release eq '2.0.0') || ($release eq '2.0.1'); # no dynapi before 2.0.2 + my $assigned_release = ($release eq '2.0.2') ? '2.0.0' : $release; # assume everything in 2.0.2--first with dynapi--was there since 2.0.0. We'll fix it up later. + my $tag = ($release eq 'HEAD') ? $release : "release-$release"; + my $blobname = "$tag:src/dynapi/SDL_dynapi_overrides.h"; + open(PIPEFH, '-|', "git show '$blobname'") or die "Failed to read git blob '$blobname': $!\n"; + while () { + chomp; + if (/\A\#define\s+(SDL_.*?)\s+SDL_.*?_REAL\Z/) { + my $fn = $1; + $funcs{$fn} = $assigned_release if not defined $funcs{$fn}; + } + } + close(PIPEFH); +} + +# Fixup the handful of functions that were added in 2.0.1 and 2.0.2 that we +# didn't have dynapi revision data about... +$funcs{'SDL_GetSystemRAM'} = '2.0.1'; +$funcs{'SDL_GetBasePath'} = '2.0.1'; +$funcs{'SDL_GetPrefPath'} = '2.0.1'; +$funcs{'SDL_UpdateYUVTexture'} = '2.0.1'; +$funcs{'SDL_GL_GetDrawableSize'} = '2.0.1'; +$funcs{'SDL_Direct3D9GetAdapterIndex'} = '2.0.1'; +$funcs{'SDL_RenderGetD3D9Device'} = '2.0.1'; + +$funcs{'SDL_RegisterApp'} = '2.0.2'; +$funcs{'SDL_UnregisterApp'} = '2.0.2'; +$funcs{'SDL_GetAssertionHandler'} = '2.0.2'; +$funcs{'SDL_GetDefaultAssertionHandler'} = '2.0.2'; +$funcs{'SDL_AtomicAdd'} = '2.0.2'; +$funcs{'SDL_AtomicGet'} = '2.0.2'; +$funcs{'SDL_AtomicGetPtr'} = '2.0.2'; +$funcs{'SDL_AtomicSet'} = '2.0.2'; +$funcs{'SDL_AtomicSetPtr'} = '2.0.2'; +$funcs{'SDL_HasAVX'} = '2.0.2'; +$funcs{'SDL_GameControllerAddMappingsFromRW'} = '2.0.2'; +$funcs{'SDL_acos'} = '2.0.2'; +$funcs{'SDL_asin'} = '2.0.2'; +$funcs{'SDL_vsscanf'} = '2.0.2'; +$funcs{'SDL_DetachThread'} = '2.0.2'; +$funcs{'SDL_GL_ResetAttributes'} = '2.0.2'; +$funcs{'SDL_DXGIGetOutputInfo'} = '2.0.2'; + +# these are incorrect in the dynapi header, because we forgot to add them +# until a later release, but are available in the older release. +$funcs{'SDL_WinRTGetFSPathUNICODE'} = '2.0.3'; +$funcs{'SDL_WinRTGetFSPathUTF8'} = '2.0.3'; +$funcs{'SDL_WinRTRunApp'} = '2.0.3'; + +if (not defined $wikipath) { + foreach my $release (@releases) { + foreach my $fn (sort keys %funcs) { + print("$fn: $funcs{$fn}\n") if $funcs{$fn} eq $release; + } + } +} else { + if (defined $wikipath) { + chdir($wikipath); + foreach my $fn (keys %funcs) { + my $revision = $funcs{$fn}; + $revision = $next_release if $revision eq 'HEAD'; + my $fname = "$fn.mediawiki"; + if ( ! -f $fname ) { + #print STDERR "No such file: $fname\n"; + next; + } + + my @lines = (); + open(FH, '<', $fname) or die("Can't open $fname for read: $!\n"); + my $added = 0; + while () { + chomp; + if ((/\A\-\-\-\-/) && (!$added)) { + push @lines, "== Version =="; + push @lines, ""; + push @lines, "This function is available since SDL $revision."; + push @lines, ""; + $added = 1; + } + push @lines, $_; + next if not /\A\=\=\s+Version\s+\=\=/; + $added = 1; + push @lines, ""; + push @lines, "This function is available since SDL $revision."; + push @lines, ""; + while () { + chomp; + next if not (/\A\=\=\s+/ || /\A\-\-\-\-/); + push @lines, $_; + last; + } + } + close(FH); + + if (!$added) { + push @lines, "== Version =="; + push @lines, ""; + push @lines, "This function is available since SDL $revision."; + push @lines, ""; + } + + open(FH, '>', $fname) or die("Can't open $fname for write: $!\n"); + foreach (@lines) { + print FH "$_\n"; + } + close(FH); + } + } +} + diff --git a/SDL2-2.30.5/build-scripts/gen_audio_channel_conversion.c b/SDL2-2.30.5/build-scripts/gen_audio_channel_conversion.c new file mode 100644 index 0000000..5d5841d --- /dev/null +++ b/SDL2-2.30.5/build-scripts/gen_audio_channel_conversion.c @@ -0,0 +1,450 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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 + +/* + +Built with: + +gcc -o genchancvt build-scripts/gen_audio_channel_conversion.c -lm && ./genchancvt > src/audio/SDL_audio_channel_converters.h + +*/ + +#define NUM_CHANNELS 8 + +static const char *layout_names[NUM_CHANNELS] = { + "Mono", "Stereo", "2.1", "Quad", "4.1", "5.1", "6.1", "7.1" +}; + +static const char *channel_names[NUM_CHANNELS][NUM_CHANNELS] = { + /* mono */ { "FC" }, + /* stereo */ { "FL", "FR" }, + /* 2.1 */ { "FL", "FR", "LFE" }, + /* quad */ { "FL", "FR", "BL", "BR" }, + /* 4.1 */ { "FL", "FR", "LFE", "BL", "BR" }, + /* 5.1 */ { "FL", "FR", "FC", "LFE", "BL", "BR" }, + /* 6.1 */ { "FL", "FR", "FC", "LFE", "BC", "SL", "SR" }, + /* 7.1 */ { "FL", "FR", "FC", "LFE", "BL", "BR", "SL", "SR" }, +}; + + +/* + * This table is from FAudio: + * + * https://raw.githubusercontent.com/FNA-XNA/FAudio/master/src/matrix_defaults.inl + */ +static const float channel_conversion_matrix[8][8][64] = { +{ + /* 1 x 1 */ + { 1.000000000f }, + /* 1 x 2 */ + { 1.000000000f, 1.000000000f }, + /* 1 x 3 */ + { 1.000000000f, 1.000000000f, 0.000000000f }, + /* 1 x 4 */ + { 1.000000000f, 1.000000000f, 0.000000000f, 0.000000000f }, + /* 1 x 5 */ + { 1.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }, + /* 1 x 6 */ + { 1.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }, + /* 1 x 7 */ + { 1.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }, + /* 1 x 8 */ + { 1.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f } +}, +{ + /* 2 x 1 */ + { 0.500000000f, 0.500000000f }, + /* 2 x 2 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 1.000000000f }, + /* 2 x 3 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f }, + /* 2 x 4 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }, + /* 2 x 5 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }, + /* 2 x 6 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }, + /* 2 x 7 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }, + /* 2 x 8 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f } +}, +{ + /* 3 x 1 */ + { 0.333333343f, 0.333333343f, 0.333333343f }, + /* 3 x 2 */ + { 0.800000012f, 0.000000000f, 0.200000003f, 0.000000000f, 0.800000012f, 0.200000003f }, + /* 3 x 3 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f }, + /* 3 x 4 */ + { 0.888888896f, 0.000000000f, 0.111111112f, 0.000000000f, 0.888888896f, 0.111111112f, 0.000000000f, 0.000000000f, 0.111111112f, 0.000000000f, 0.000000000f, 0.111111112f }, + /* 3 x 5 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }, + /* 3 x 6 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }, + /* 3 x 7 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }, + /* 3 x 8 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f } +}, +{ + /* 4 x 1 */ + { 0.250000000f, 0.250000000f, 0.250000000f, 0.250000000f }, + /* 4 x 2 */ + { 0.421000004f, 0.000000000f, 0.358999997f, 0.219999999f, 0.000000000f, 0.421000004f, 0.219999999f, 0.358999997f }, + /* 4 x 3 */ + { 0.421000004f, 0.000000000f, 0.358999997f, 0.219999999f, 0.000000000f, 0.421000004f, 0.219999999f, 0.358999997f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }, + /* 4 x 4 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f }, + /* 4 x 5 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f }, + /* 4 x 6 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f }, + /* 4 x 7 */ + { 0.939999998f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.939999998f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.500000000f, 0.500000000f, 0.000000000f, 0.000000000f, 0.796000004f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.796000004f }, + /* 4 x 8 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f } +}, +{ + /* 5 x 1 */ + { 0.200000003f, 0.200000003f, 0.200000003f, 0.200000003f, 0.200000003f }, + /* 5 x 2 */ + { 0.374222219f, 0.000000000f, 0.111111112f, 0.319111109f, 0.195555553f, 0.000000000f, 0.374222219f, 0.111111112f, 0.195555553f, 0.319111109f }, + /* 5 x 3 */ + { 0.421000004f, 0.000000000f, 0.000000000f, 0.358999997f, 0.219999999f, 0.000000000f, 0.421000004f, 0.000000000f, 0.219999999f, 0.358999997f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f }, + /* 5 x 4 */ + { 0.941176474f, 0.000000000f, 0.058823530f, 0.000000000f, 0.000000000f, 0.000000000f, 0.941176474f, 0.058823530f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.058823530f, 0.941176474f, 0.000000000f, 0.000000000f, 0.000000000f, 0.058823530f, 0.000000000f, 0.941176474f }, + /* 5 x 5 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f }, + /* 5 x 6 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f }, + /* 5 x 7 */ + { 0.939999998f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.939999998f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.500000000f, 0.500000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.796000004f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.796000004f }, + /* 5 x 8 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f } +}, +{ + /* 6 x 1 */ + { 0.166666672f, 0.166666672f, 0.166666672f, 0.166666672f, 0.166666672f, 0.166666672f }, + /* 6 x 2 */ + { 0.294545442f, 0.000000000f, 0.208181813f, 0.090909094f, 0.251818180f, 0.154545456f, 0.000000000f, 0.294545442f, 0.208181813f, 0.090909094f, 0.154545456f, 0.251818180f }, + /* 6 x 3 */ + { 0.324000001f, 0.000000000f, 0.229000002f, 0.000000000f, 0.277000010f, 0.170000002f, 0.000000000f, 0.324000001f, 0.229000002f, 0.000000000f, 0.170000002f, 0.277000010f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f }, + /* 6 x 4 */ + { 0.558095276f, 0.000000000f, 0.394285709f, 0.047619049f, 0.000000000f, 0.000000000f, 0.000000000f, 0.558095276f, 0.394285709f, 0.047619049f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.047619049f, 0.558095276f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.047619049f, 0.000000000f, 0.558095276f }, + /* 6 x 5 */ + { 0.586000025f, 0.000000000f, 0.414000005f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.586000025f, 0.414000005f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.586000025f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.586000025f }, + /* 6 x 6 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f }, + /* 6 x 7 */ + { 0.939999998f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.939999998f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.939999998f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.500000000f, 0.500000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.796000004f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.796000004f }, + /* 6 x 8 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f } +}, +{ + /* 7 x 1 */ + { 0.143142849f, 0.143142849f, 0.143142849f, 0.142857149f, 0.143142849f, 0.143142849f, 0.143142849f }, + /* 7 x 2 */ + { 0.247384623f, 0.000000000f, 0.174461529f, 0.076923080f, 0.174461529f, 0.226153851f, 0.100615382f, 0.000000000f, 0.247384623f, 0.174461529f, 0.076923080f, 0.174461529f, 0.100615382f, 0.226153851f }, + /* 7 x 3 */ + { 0.268000007f, 0.000000000f, 0.188999996f, 0.000000000f, 0.188999996f, 0.245000005f, 0.108999997f, 0.000000000f, 0.268000007f, 0.188999996f, 0.000000000f, 0.188999996f, 0.108999997f, 0.245000005f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }, + /* 7 x 4 */ + { 0.463679999f, 0.000000000f, 0.327360004f, 0.040000003f, 0.000000000f, 0.168960005f, 0.000000000f, 0.000000000f, 0.463679999f, 0.327360004f, 0.040000003f, 0.000000000f, 0.000000000f, 0.168960005f, 0.000000000f, 0.000000000f, 0.000000000f, 0.040000003f, 0.327360004f, 0.431039989f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.040000003f, 0.327360004f, 0.000000000f, 0.431039989f }, + /* 7 x 5 */ + { 0.483000010f, 0.000000000f, 0.340999991f, 0.000000000f, 0.000000000f, 0.175999999f, 0.000000000f, 0.000000000f, 0.483000010f, 0.340999991f, 0.000000000f, 0.000000000f, 0.000000000f, 0.175999999f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.340999991f, 0.449000001f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.340999991f, 0.000000000f, 0.449000001f }, + /* 7 x 6 */ + { 0.611000001f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.223000005f, 0.000000000f, 0.000000000f, 0.611000001f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.223000005f, 0.000000000f, 0.000000000f, 0.611000001f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.432000011f, 0.568000019f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.432000011f, 0.000000000f, 0.568000019f }, + /* 7 x 7 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f }, + /* 7 x 8 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.707000017f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.707000017f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f } +}, +{ + /* 8 x 1 */ + { 0.125125006f, 0.125125006f, 0.125125006f, 0.125000000f, 0.125125006f, 0.125125006f, 0.125125006f, 0.125125006f }, + /* 8 x 2 */ + { 0.211866662f, 0.000000000f, 0.150266662f, 0.066666670f, 0.181066677f, 0.111066669f, 0.194133341f, 0.085866667f, 0.000000000f, 0.211866662f, 0.150266662f, 0.066666670f, 0.111066669f, 0.181066677f, 0.085866667f, 0.194133341f }, + /* 8 x 3 */ + { 0.226999998f, 0.000000000f, 0.160999998f, 0.000000000f, 0.194000006f, 0.119000003f, 0.208000004f, 0.092000000f, 0.000000000f, 0.226999998f, 0.160999998f, 0.000000000f, 0.119000003f, 0.194000006f, 0.092000000f, 0.208000004f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f }, + /* 8 x 4 */ + { 0.466344833f, 0.000000000f, 0.329241365f, 0.034482758f, 0.000000000f, 0.000000000f, 0.169931039f, 0.000000000f, 0.000000000f, 0.466344833f, 0.329241365f, 0.034482758f, 0.000000000f, 0.000000000f, 0.000000000f, 0.169931039f, 0.000000000f, 0.000000000f, 0.000000000f, 0.034482758f, 0.466344833f, 0.000000000f, 0.433517247f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.034482758f, 0.000000000f, 0.466344833f, 0.000000000f, 0.433517247f }, + /* 8 x 5 */ + { 0.483000010f, 0.000000000f, 0.340999991f, 0.000000000f, 0.000000000f, 0.000000000f, 0.175999999f, 0.000000000f, 0.000000000f, 0.483000010f, 0.340999991f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.175999999f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.483000010f, 0.000000000f, 0.449000001f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.483000010f, 0.000000000f, 0.449000001f }, + /* 8 x 6 */ + { 0.518000007f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.188999996f, 0.000000000f, 0.000000000f, 0.518000007f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.188999996f, 0.000000000f, 0.000000000f, 0.518000007f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.518000007f, 0.000000000f, 0.481999993f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.518000007f, 0.000000000f, 0.481999993f }, + /* 8 x 7 */ + { 0.541000009f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.541000009f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.541000009f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.287999988f, 0.287999988f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.458999991f, 0.000000000f, 0.541000009f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.458999991f, 0.000000000f, 0.541000009f }, + /* 8 x 8 */ + { 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 0.000000000f, 1.000000000f } +} +}; + +static char *remove_dots(const char *str) /* this is NOT robust. */ +{ + static char retval1[32]; + static char retval2[32]; + static int idx = 0; + char *retval = (idx++ & 1) ? retval1 : retval2; + char *ptr = retval; + while (*str) { + if (*str != '.') { + *(ptr++) = *str; + } + str++; + } + *ptr = '\0'; + return retval; +} + +static char *lowercase(const char *str) /* this is NOT robust. */ +{ + static char retval1[32]; + static char retval2[32]; + static int idx = 0; + char *retval = (idx++ & 1) ? retval1 : retval2; + char *ptr = retval; + while (*str) { + const char ch = *(str++); + *(ptr++) = ((ch >= 'A') && (ch <= 'Z')) ? (ch - ('A' - 'a')) : ch; + } + *ptr = '\0'; + return retval; +} + +static void write_converter(const int fromchans, const int tochans) +{ + const char *fromstr = layout_names[fromchans-1]; + const char *tostr = layout_names[tochans-1]; + const float *cvtmatrix = channel_conversion_matrix[fromchans-1][tochans-1]; + const float *fptr; + const int convert_backwards = (tochans > fromchans); + int input_channel_used[NUM_CHANNELS]; + int i, j; + + if (tochans == fromchans) { + return; /* nothing to convert, don't generate a converter. */ + } + + for (i = 0; i < fromchans; i++) { + input_channel_used[i] = 0; + } + + fptr = cvtmatrix; + for (j = 0; j < tochans; j++) { + for (i = 0; i < fromchans; i++) { + #if 0 + printf("to=%d, from=%d, coeff=%f\n", j, i, *fptr); + #endif + if (*(fptr++) != 0.0f) { + input_channel_used[i]++; + } + } + } + + printf("static void SDLCALL\n" + "SDL_Convert%sTo%s(SDL_AudioCVT *cvt, SDL_AudioFormat format)\n" + "{\n", remove_dots(fromstr), remove_dots(tostr)); + + if (convert_backwards) { /* must convert backwards when growing the output in-place. */ + printf(" float *dst = ((float *) (cvt->buf + ((cvt->len_cvt / %d) * %d))) - %d;\n", fromchans, tochans, tochans); + printf(" const float *src = ((const float *) (cvt->buf + cvt->len_cvt)) - %d;\n", fromchans); + } else { + printf(" float *dst = (float *) cvt->buf;\n"); + printf(" const float *src = dst;\n"); + } + + printf(" int i;\n" + "\n" + " LOG_DEBUG_CONVERT(\"%s\", \"%s\");\n" + " SDL_assert(format == AUDIO_F32SYS);\n" + "\n", lowercase(fromstr), lowercase(tostr)); + + if (convert_backwards) { + printf(" /* convert backwards, since output is growing in-place. */\n"); + printf(" for (i = cvt->len_cvt / (sizeof (float) * %d); i; i--, src -= %d, dst -= %d) {\n", fromchans, fromchans, tochans); + fptr = cvtmatrix; + for (i = 0; i < fromchans; i++) { + if (input_channel_used[i] > 1) { /* don't read it from src more than once. */ + printf(" const float src%s = src[%d];\n", channel_names[fromchans-1][i], i); + } + } + + for (j = tochans - 1; j >= 0; j--) { + int has_input = 0; + fptr = cvtmatrix + (fromchans * j); + printf(" dst[%d] /* %s */ =", j, channel_names[tochans-1][j]); + for (i = fromchans - 1; i >= 0; i--) { + const float coefficient = fptr[i]; + char srcname[32]; + if (coefficient == 0.0f) { + continue; + } else if (input_channel_used[i] > 1) { + snprintf(srcname, sizeof (srcname), "src%s", channel_names[fromchans-1][i]); + } else { + snprintf(srcname, sizeof (srcname), "src[%d]", i); + } + + if (has_input) { + printf(" +"); + } + + has_input = 1; + + if (coefficient == 1.0f) { + printf(" %s", srcname); + } else { + printf(" (%s * %.9ff)", srcname, coefficient); + } + } + + if (!has_input) { + printf(" 0.0f"); + } + + printf(";\n"); + } + + printf(" }\n"); + } else { + printf(" for (i = cvt->len_cvt / (sizeof (float) * %d); i; i--, src += %d, dst += %d) {\n", fromchans, fromchans, tochans); + + fptr = cvtmatrix; + for (i = 0; i < fromchans; i++) { + if (input_channel_used[i] > 1) { /* don't read it from src more than once. */ + printf(" const float src%s = src[%d];\n", channel_names[fromchans-1][i], i); + } + } + + for (j = 0; j < tochans; j++) { + int has_input = 0; + fptr = cvtmatrix + (fromchans * j); + printf(" dst[%d] /* %s */ =", j, channel_names[tochans-1][j]); + for (i = 0; i < fromchans; i++) { + const float coefficient = fptr[i]; + char srcname[32]; + if (coefficient == 0.0f) { + continue; + } else if (input_channel_used[i] > 1) { + snprintf(srcname, sizeof (srcname), "src%s", channel_names[fromchans-1][i]); + } else { + snprintf(srcname, sizeof (srcname), "src[%d]", i); + } + + if (has_input) { + printf(" +"); + } + + has_input = 1; + + if (coefficient == 1.0f) { + printf(" %s", srcname); + } else { + printf(" (%s * %.9ff)", srcname, coefficient); + } + } + + if (!has_input) { + printf(" 0.0f"); + } + + printf(";\n"); + } + printf(" }\n"); + } + + printf("\n"); + + if ((fromchans > 1) && (tochans > 1)) { + printf(" cvt->len_cvt = (cvt->len_cvt / %d) * %d;\n", fromchans, tochans); + } else if (tochans == 1) { + printf(" cvt->len_cvt = cvt->len_cvt / %d;\n", fromchans); + } else /* if (fromchans == 1) */ { + printf(" cvt->len_cvt = cvt->len_cvt * %d;\n", tochans); + } + + printf(" if (cvt->filters[++cvt->filter_index]) {\n" + " cvt->filters[cvt->filter_index] (cvt, format);\n" + " }\n" + "}\n\n"); +} + +int main(void) +{ + int ini, outi; + + printf( + "/*\n" + " Simple DirectMedia Layer\n" + " Copyright (C) 1997-2024 Sam Lantinga \n" + "\n" + " This software is provided 'as-is', without any express or implied\n" + " warranty. In no event will the authors be held liable for any damages\n" + " arising from the use of this software.\n" + "\n" + " Permission is granted to anyone to use this software for any purpose,\n" + " including commercial applications, and to alter it and redistribute it\n" + " freely, subject to the following restrictions:\n" + "\n" + " 1. The origin of this software must not be misrepresented; you must not\n" + " claim that you wrote the original software. If you use this software\n" + " in a product, an acknowledgment in the product documentation would be\n" + " appreciated but is not required.\n" + " 2. Altered source versions must be plainly marked as such, and must not be\n" + " misrepresented as being the original software.\n" + " 3. This notice may not be removed or altered from any source distribution.\n" + "*/\n" + "\n" + "/* DO NOT EDIT, THIS FILE WAS GENERATED BY build-scripts/gen_audio_channel_conversion.c */\n" + "\n" + ); + + for (ini = 1; ini <= NUM_CHANNELS; ini++) { + for (outi = 1; outi <= NUM_CHANNELS; outi++) { + write_converter(ini, outi); + } + } + + printf("static const SDL_AudioFilter channel_converters[%d][%d] = { /* [from][to] */\n", NUM_CHANNELS, NUM_CHANNELS); + for (ini = 1; ini <= NUM_CHANNELS; ini++) { + const char *comma = ""; + printf(" {"); + for (outi = 1; outi <= NUM_CHANNELS; outi++) { + const char *fromstr = layout_names[ini-1]; + const char *tostr = layout_names[outi-1]; + if (ini == outi) { + printf("%s NULL", comma); + } else { + printf("%s SDL_Convert%sTo%s", comma, remove_dots(fromstr), remove_dots(tostr)); + } + comma = ","; + } + printf(" }%s\n", (ini == NUM_CHANNELS) ? "" : ","); + } + + printf("};\n\n"); + printf("/* vi: set ts=4 sw=4 expandtab: */\n\n"); + + return 0; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/build-scripts/gen_audio_resampler_filter.c b/SDL2-2.30.5/build-scripts/gen_audio_resampler_filter.c new file mode 100644 index 0000000..22b7437 --- /dev/null +++ b/SDL2-2.30.5/build-scripts/gen_audio_resampler_filter.c @@ -0,0 +1,163 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +/* + +Built with: + +gcc -o genfilter build-scripts/gen_audio_resampler_filter.c -lm && ./genfilter > src/audio/SDL_audio_resampler_filter.h + + */ + +/* + SDL's resampler uses a "bandlimited interpolation" algorithm: + https://ccrma.stanford.edu/~jos/resample/ + + This code pre-generates the kaiser tables so we don't have to do this at + run time, at a cost of about 20 kilobytes of static data in SDL. This code + used to be part of SDL itself and generated the tables on the first use, + but that was expensive to produce on platforms without floating point + hardware. +*/ + +#include +#include + +#define RESAMPLER_ZERO_CROSSINGS 5 +#define RESAMPLER_BITS_PER_SAMPLE 16 +#define RESAMPLER_SAMPLES_PER_ZERO_CROSSING (1 << ((RESAMPLER_BITS_PER_SAMPLE / 2) + 1)) +#define RESAMPLER_FILTER_SIZE ((RESAMPLER_SAMPLES_PER_ZERO_CROSSING * RESAMPLER_ZERO_CROSSINGS) + 1) + +/* This is a "modified" bessel function, so you can't use POSIX j0() */ +static double +bessel(const double x) +{ + const double xdiv2 = x / 2.0; + double i0 = 1.0f; + double f = 1.0f; + int i = 1; + + while (1) { + const double diff = pow(xdiv2, i * 2) / pow(f, 2); + if (diff < 1.0e-21f) { + break; + } + i0 += diff; + i++; + f *= (double) i; + } + + return i0; +} + +/* build kaiser table with cardinal sine applied to it, and array of differences between elements. */ +static void +kaiser_and_sinc(float *table, float *diffs, const int tablelen, const double beta) +{ + const int lenm1 = tablelen - 1; + const int lenm1div2 = lenm1 / 2; + const double bessel_beta = bessel(beta); + int i; + + table[0] = 1.0f; + for (i = 1; i < tablelen; i++) { + const double kaiser = bessel(beta * sqrt(1.0 - pow(((i - lenm1) / 2.0) / lenm1div2, 2.0))) / bessel_beta; + table[tablelen - i] = (float) kaiser; + } + + for (i = 1; i < tablelen; i++) { + const float x = (((float) i) / ((float) RESAMPLER_SAMPLES_PER_ZERO_CROSSING)) * ((float) M_PI); + table[i] *= sinf(x) / x; + diffs[i - 1] = table[i] - table[i - 1]; + } + diffs[lenm1] = 0.0f; +} + + +static float ResamplerFilter[RESAMPLER_FILTER_SIZE]; +static float ResamplerFilterDifference[RESAMPLER_FILTER_SIZE]; + +static void +PrepareResampleFilter(void) +{ + /* if dB > 50, beta=(0.1102 * (dB - 8.7)), according to Matlab. */ + const double dB = 80.0; + const double beta = 0.1102 * (dB - 8.7); + kaiser_and_sinc(ResamplerFilter, ResamplerFilterDifference, RESAMPLER_FILTER_SIZE, beta); +} + +int main(void) +{ + int i; + + PrepareResampleFilter(); + + printf( + "/*\n" + " Simple DirectMedia Layer\n" + " Copyright (C) 1997-2024 Sam Lantinga \n" + "\n" + " This software is provided 'as-is', without any express or implied\n" + " warranty. In no event will the authors be held liable for any damages\n" + " arising from the use of this software.\n" + "\n" + " Permission is granted to anyone to use this software for any purpose,\n" + " including commercial applications, and to alter it and redistribute it\n" + " freely, subject to the following restrictions:\n" + "\n" + " 1. The origin of this software must not be misrepresented; you must not\n" + " claim that you wrote the original software. If you use this software\n" + " in a product, an acknowledgment in the product documentation would be\n" + " appreciated but is not required.\n" + " 2. Altered source versions must be plainly marked as such, and must not be\n" + " misrepresented as being the original software.\n" + " 3. This notice may not be removed or altered from any source distribution.\n" + "*/\n" + "\n" + "/* DO NOT EDIT, THIS FILE WAS GENERATED BY build-scripts/gen_audio_resampler_filter.c */\n" + "\n" + "#define RESAMPLER_ZERO_CROSSINGS %d\n" + "#define RESAMPLER_BITS_PER_SAMPLE %d\n" + "#define RESAMPLER_SAMPLES_PER_ZERO_CROSSING (1 << ((RESAMPLER_BITS_PER_SAMPLE / 2) + 1))\n" + "#define RESAMPLER_FILTER_SIZE ((RESAMPLER_SAMPLES_PER_ZERO_CROSSING * RESAMPLER_ZERO_CROSSINGS) + 1)\n" + "\n", RESAMPLER_ZERO_CROSSINGS, RESAMPLER_BITS_PER_SAMPLE + ); + + printf("static const float ResamplerFilter[RESAMPLER_FILTER_SIZE] = {\n"); + printf(" %.9ff", ResamplerFilter[0]); + for (i = 0; i < RESAMPLER_FILTER_SIZE-1; i++) { + printf("%s%.9ff", ((i % 5) == 4) ? ",\n " : ", ", ResamplerFilter[i+1]); + } + printf("\n};\n\n"); + + printf("static const float ResamplerFilterDifference[RESAMPLER_FILTER_SIZE] = {\n"); + printf(" %.9ff", ResamplerFilterDifference[0]); + for (i = 0; i < RESAMPLER_FILTER_SIZE-1; i++) { + printf("%s%.9ff", ((i % 5) == 4) ? ",\n " : ", ", ResamplerFilterDifference[i+1]); + } + printf("\n};\n\n"); + printf("/* vi: set ts=4 sw=4 expandtab: */\n\n"); + + return 0; +} + +/* vi: set ts=4 sw=4 expandtab: */ + diff --git a/SDL2-2.30.5/build-scripts/git-pre-push-hook.pl b/SDL2-2.30.5/build-scripts/git-pre-push-hook.pl new file mode 100644 index 0000000..ff84dff --- /dev/null +++ b/SDL2-2.30.5/build-scripts/git-pre-push-hook.pl @@ -0,0 +1,80 @@ +#!/usr/bin/perl -w + +# To use this script: symlink it to .git/hooks/pre-push, then "git push" +# +# This script is called by "git push" after it has checked the remote status, +# but before anything has been pushed. If this script exits with a non-zero +# status nothing will be pushed. +# +# This hook is called with the following parameters: +# +# $1 -- Name of the remote to which the push is being done +# $2 -- URL to which the push is being done +# +# If pushing without using a named remote those arguments will be equal. +# +# Information about the commits which are being pushed is supplied as lines to +# the standard input in the form: +# +# + +use warnings; +use strict; + +my $remote = $ARGV[0]; +my $url = $ARGV[1]; + +#print("remote: $remote\n"); +#print("url: $url\n"); + +$url =~ s/\.git$//; # change myorg/myproject.git to myorg/myproject +$url =~ s#^git\@github\.com\:#https://github.com/#i; +my $commiturl = $url =~ /\Ahttps?:\/\/github.com\// ? "$url/commit/" : ''; + +my $z40 = '0000000000000000000000000000000000000000'; +my $reported = 0; + +while () { + chomp; + my ($local_ref, $local_sha, $remote_ref, $remote_sha) = split / /; + #print("local_ref: $local_ref\n"); + #print("local_sha: $local_sha\n"); + #print("remote_ref: $remote_ref\n"); + #print("remote_sha: $remote_sha\n"); + + my $range = ''; + if ($remote_sha eq $z40) { # New branch, examine all commits + $range = $local_sha; + } else { # Update to existing branch, examine new commits + $range = "$remote_sha..$local_sha"; + } + + my $gitcmd = "git log --reverse --oneline --no-abbrev-commit '$range'"; + open(GITPIPE, '-|', $gitcmd) or die("\n\n$0: Failed to run '$gitcmd': $!\n\nAbort push!\n\n"); + while () { + chomp; + if (/\A([a-fA-F0-9]+)\s+(.*?)\Z/) { + my $hash = $1; + my $msg = $2; + + if (!$reported) { + print("\nCommits expected to be pushed:\n"); + $reported = 1; + } + + #print("hash: $hash\n"); + #print("msg: $msg\n"); + + print("$commiturl$hash -- $msg\n"); + } else { + die("$0: Unexpected output from '$gitcmd'!\n\nAbort push!\n\n"); + } + } + die("\n\n$0: Failing exit code from running '$gitcmd'!\n\nAbort push!\n\n") if !close(GITPIPE); +} + +print("\n") if $reported; + +exit(0); # Let the push go forward. + +# vi: set ts=4 sw=4 expandtab: diff --git a/SDL2-2.0.12/build-scripts/install-sh b/SDL2-2.30.5/build-scripts/install-sh similarity index 54% rename from SDL2-2.0.12/build-scripts/install-sh rename to SDL2-2.30.5/build-scripts/install-sh index 377bb86..ec298b5 100644 --- a/SDL2-2.0.12/build-scripts/install-sh +++ b/SDL2-2.30.5/build-scripts/install-sh @@ -1,7 +1,7 @@ #!/bin/sh # install - install a program, script, or datafile -scriptversion=2011-11-20.07; # UTC +scriptversion=2020-11-14.01; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the @@ -41,19 +41,15 @@ scriptversion=2011-11-20.07; # UTC # This script is compatible with the BSD install script, but was written # from scratch. +tab=' ' nl=' ' -IFS=" "" $nl" +IFS=" $tab$nl" -# set DOITPROG to echo to test this script +# Set DOITPROG to "echo" to test this script. -# Don't use :- since 4.3BSD and earlier shells don't like it. doit=${DOITPROG-} -if test -z "$doit"; then - doit_exec=exec -else - doit_exec=$doit -fi +doit_exec=${doit:-exec} # Put in absolute file names if you don't have them in your path; # or use environment vars. @@ -68,22 +64,16 @@ mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} -posix_glob='?' -initialize_posix_glob=' - test "$posix_glob" != "?" || { - if (set -f) 2>/dev/null; then - posix_glob= - else - posix_glob=: - fi - } -' - posix_mkdir= # Desired mode of installed file. mode=0755 +# Create dirs (including intermediate dirs) using mode 755. +# This is like GNU 'install' as of coreutils 8.32 (2020). +mkdir_umask=22 + +backupsuffix= chgrpcmd= chmodcmd=$chmodprog chowncmd= @@ -97,7 +87,7 @@ dir_arg= dst_arg= copy_on_change=false -no_target_directory= +is_target_a_directory=possibly usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE @@ -114,18 +104,28 @@ Options: --version display version info and exit. -c (ignored) - -C install only if different (preserve the last data modification time) + -C install only if different (preserve data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. + -p pass -p to $cpprog. -s $stripprog installed files. + -S SUFFIX attempt to back up existing files, with suffix SUFFIX. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG + +By default, rm is invoked with -f; when overridden with RMPROG, +it's up to you to specify -f if you want it. + +If -S is not specified, no backups are attempted. + +Email bug reports to bug-automake@gnu.org. +Automake home page: https://www.gnu.org/software/automake/ " while test $# -ne 0; do @@ -137,46 +137,62 @@ while test $# -ne 0; do -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" - shift;; + shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 - case $mode in - *' '* | *' '* | *' -'* | *'*'* | *'?'* | *'['*) - echo "$0: invalid mode: $mode" >&2 - exit 1;; - esac - shift;; + case $mode in + *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; -o) chowncmd="$chownprog $2" - shift;; + shift;; + + -p) cpprog="$cpprog -p";; -s) stripcmd=$stripprog;; - -t) dst_arg=$2 - # Protect names problematic for 'test' and other utilities. - case $dst_arg in - -* | [=\(\)!]) dst_arg=./$dst_arg;; - esac - shift;; + -S) backupsuffix="$2" + shift;; - -T) no_target_directory=true;; + -t) + is_target_a_directory=always + dst_arg=$2 + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; + + -T) is_target_a_directory=never;; --version) echo "$0 $scriptversion"; exit $?;; - --) shift - break;; + --) shift + break;; - -*) echo "$0: invalid option: $1" >&2 - exit 1;; + -*) echo "$0: invalid option: $1" >&2 + exit 1;; *) break;; esac shift done +# We allow the use of options -d and -T together, by making -d +# take the precedence; this is for compatibility with GNU install. + +if test -n "$dir_arg"; then + if test -n "$dst_arg"; then + echo "$0: target directory not allowed when installing a directory." >&2 + exit 1 + fi +fi + if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. @@ -207,6 +223,15 @@ if test $# -eq 0; then exit 0 fi +if test -z "$dir_arg"; then + if test $# -gt 1 || test "$is_target_a_directory" = always; then + if test ! -d "$dst_arg"; then + echo "$0: $dst_arg: Is not a directory." >&2 + exit 1 + fi + fi +fi + if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 @@ -223,16 +248,16 @@ if test -z "$dir_arg"; then *[0-7]) if test -z "$stripcmd"; then - u_plus_rw= + u_plus_rw= else - u_plus_rw='% 200' + u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then - u_plus_rw= + u_plus_rw= else - u_plus_rw=,u+rw + u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac @@ -250,6 +275,10 @@ do dstdir=$dst test -d "$dstdir" dstdir_status=$? + # Don't chown directories that already exist. + if test $dstdir_status = 0; then + chowncmd="" + fi else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command @@ -266,178 +295,148 @@ do fi dst=$dst_arg - # If destination is a directory, append the input filename; won't work - # if double slashes aren't ignored. + # If destination is a directory, append the input filename. if test -d "$dst"; then - if test -n "$no_target_directory"; then - echo "$0: $dst_arg: Is a directory" >&2 - exit 1 + if test "$is_target_a_directory" = never; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 fi dstdir=$dst - dst=$dstdir/`basename "$src"` + dstbase=`basename "$src"` + case $dst in + */) dst=$dst$dstbase;; + *) dst=$dst/$dstbase;; + esac dstdir_status=0 else - # Prefer dirname, but fall back on a substitute if dirname fails. - dstdir=` - (dirname "$dst") 2>/dev/null || - expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$dst" : 'X\(//\)[^/]' \| \ - X"$dst" : 'X\(//\)$' \| \ - X"$dst" : 'X\(/\)' \| . 2>/dev/null || - echo X"$dst" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q' - ` - + dstdir=`dirname "$dst"` test -d "$dstdir" dstdir_status=$? fi fi + case $dstdir in + */) dstdirslash=$dstdir;; + *) dstdirslash=$dstdir/;; + esac + obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') - # Create intermediate dirs using mode 755 as modified by the umask. - # This is like FreeBSD 'install' as of 1997-10-28. - umask=`umask` - case $stripcmd.$umask in - # Optimize common cases. - *[2367][2367]) mkdir_umask=$umask;; - .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi - *[0-7]) - mkdir_umask=`expr $umask + 22 \ - - $umask % 100 % 40 + $umask % 20 \ - - $umask % 10 % 4 + $umask % 2 - `;; - *) mkdir_umask=$umask,go-w;; - esac + posix_mkdir=false + # The $RANDOM variable is not portable (e.g., dash). Use it + # here however when possible just to lower collision chance. + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ - # With -d, create the new directory with the user-specified mode. - # Otherwise, rely on $mkdir_umask. - if test -n "$dir_arg"; then - mkdir_mode=-m$mode + trap ' + ret=$? + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null + exit $ret + ' 0 + + # Because "mkdir -p" follows existing symlinks and we likely work + # directly in world-writeable /tmp, make sure that the '$tmpdir' + # directory is successfully created first before we actually test + # 'mkdir -p'. + if (umask $mkdir_umask && + $mkdirprog $mkdir_mode "$tmpdir" && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + test_tmpdir="$tmpdir/a" + ls_ld_tmpdir=`ls -ld "$test_tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" else - mkdir_mode= + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null fi - - posix_mkdir=false - case $umask in - *[123567][0-7][0-7]) - # POSIX mkdir -p sets u+wx bits regardless of umask, which - # is incompatible with FreeBSD 'install' when (umask & 300) != 0. - ;; - *) - tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ - trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 - - if (umask $mkdir_umask && - exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 - then - if test -z "$dir_arg" || { - # Check for POSIX incompatibilities with -m. - # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or - # other-writable bit of parent directory when it shouldn't. - # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. - ls_ld_tmpdir=`ls -ld "$tmpdir"` - case $ls_ld_tmpdir in - d????-?r-*) different_mode=700;; - d????-?--*) different_mode=755;; - *) false;; - esac && - $mkdirprog -m$different_mode -p -- "$tmpdir" && { - ls_ld_tmpdir_1=`ls -ld "$tmpdir"` - test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" - } - } - then posix_mkdir=: - fi - rmdir "$tmpdir/d" "$tmpdir" - else - # Remove any dirs left behind by ancient mkdir implementations. - rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null - fi - trap '' 0;; - esac;; + trap '' 0;; esac if $posix_mkdir && ( - umask $mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else - # The umask is ridiculous, or mkdir does not conform to POSIX, + # mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in - /*) prefix='/';; - [-=\(\)!]*) prefix='./';; - *) prefix='';; + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; esac - eval "$initialize_posix_glob" - oIFS=$IFS IFS=/ - $posix_glob set -f + set -f set fnord $dstdir shift - $posix_glob set +f + set +f IFS=$oIFS prefixes= for d do - test X"$d" = X && continue + test X"$d" = X && continue - prefix=$prefix$d - if test -d "$prefix"; then - prefixes= - else - if $posix_mkdir; then - (umask=$mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break - # Don't fail if two instances are running concurrently. - test -d "$prefix" || exit 1 - else - case $prefix in - *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; - *) qprefix=$prefix;; - esac - prefixes="$prefixes '$qprefix'" - fi - fi - prefix=$prefix/ + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ done if test -n "$prefixes"; then - # Don't fail if two instances are running concurrently. - (umask $mkdir_umask && - eval "\$doit_exec \$mkdirprog $prefixes") || - test -d "$dstdir" || exit 1 - obsolete_mkdir_used=true + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true fi fi fi @@ -450,14 +449,25 @@ do else # Make a couple of temp file names in the proper directory. - dsttmp=$dstdir/_inst.$$_ - rmtmp=$dstdir/_rm.$$_ + dsttmp=${dstdirslash}_inst.$$_ + rmtmp=${dstdirslash}_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. - (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + (umask $cp_umask && + { test -z "$stripcmd" || { + # Create $dsttmp read-write so that cp doesn't create it read-only, + # which would cause strip to fail. + if test -z "$doit"; then + : >"$dsttmp" # No need to fork-exec 'touch'. + else + $doit touch "$dsttmp" + fi + } + } && + $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # @@ -472,20 +482,24 @@ do # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && - old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && - new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && - - eval "$initialize_posix_glob" && - $posix_glob set -f && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && - $posix_glob set +f && - + set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else + # If $backupsuffix is set, and the file being installed + # already exists, attempt a backup. Don't worry if it fails, + # e.g., if mv doesn't support -f. + if test -n "$backupsuffix" && test -f "$dst"; then + $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null + fi + # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || @@ -493,24 +507,24 @@ do # to itself, or perhaps because mv is so ancient that it does not # support -f. { - # Now remove or move aside any old file at destination location. - # We try this two ways since rm can't unlink itself on some - # systems and the destination file might be busy for other - # reasons. In this case, the final cleanup might fail but the new - # file should still install successfully. - { - test ! -f "$dst" || - $doit $rmcmd -f "$dst" 2>/dev/null || - { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && - { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } - } || - { echo "$0: cannot unlink or rename $dst" >&2 - (exit 1); exit 1 - } - } && + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && - # Now rename the file to the real destination. - $doit $mvcmd "$dsttmp" "$dst" + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 @@ -519,9 +533,9 @@ do done # Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" +# time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: diff --git a/SDL2-2.0.12/build-scripts/ltmain.sh b/SDL2-2.30.5/build-scripts/ltmain.sh similarity index 64% rename from SDL2-2.0.12/build-scripts/ltmain.sh rename to SDL2-2.30.5/build-scripts/ltmain.sh index 6635343..7be7193 100644 --- a/SDL2-2.0.12/build-scripts/ltmain.sh +++ b/SDL2-2.30.5/build-scripts/ltmain.sh @@ -1,9 +1,12 @@ +#! /bin/sh +## DO NOT EDIT - This file generated from ./build-aux/ltmain.in +## by inline-source v2014-01-03.01 -# libtool (GNU libtool) 2.4.2 +# libtool (GNU libtool) 2.4.6 +# Provide generalized library-building support services. # Written by Gordon Matzigkeit , 1996 -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, -# 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. +# Copyright (C) 1996-2015 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. @@ -23,430 +26,998 @@ # General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with GNU Libtool; see the file COPYING. If not, a copy -# can be downloaded from http://www.gnu.org/licenses/gpl.html, -# or obtained by writing to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# along with this program. If not, see . -# Usage: $progname [OPTION]... [MODE-ARG]... -# -# Provide generalized library-building support services. -# -# --config show all configuration variables -# --debug enable verbose shell tracing -# -n, --dry-run display commands without modifying any files -# --features display basic configuration information and exit -# --mode=MODE use operation mode MODE -# --preserve-dup-deps don't remove duplicate dependency libraries -# --quiet, --silent don't print informational messages -# --no-quiet, --no-silent -# print informational messages (default) -# --no-warn don't display warning messages -# --tag=TAG use configuration variables from tag TAG -# -v, --verbose print more informational messages than default -# --no-verbose don't print the extra informational messages -# --version print version information -# -h, --help, --help-all print short, long, or detailed help message -# -# MODE must be one of the following: -# -# clean remove files from the build directory -# compile compile a source file into a libtool object -# execute automatically set library path, then run a program -# finish complete the installation of libtool libraries -# install install libraries or executables -# link create a library or an executable -# uninstall remove libraries from an installed directory -# -# MODE-ARGS vary depending on the MODE. When passed as first option, -# `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that. -# Try `$progname --help --mode=MODE' for a more detailed description of MODE. -# -# When reporting a bug, please describe a test case to reproduce it and -# include the following information: -# -# host-triplet: $host -# shell: $SHELL -# compiler: $LTCC -# compiler flags: $LTCFLAGS -# linker: $LD (gnu? $with_gnu_ld) -# $progname: (GNU libtool) 2.4.2 -# automake: $automake_version -# autoconf: $autoconf_version -# -# Report bugs to . -# GNU libtool home page: . -# General help using GNU software: . PROGRAM=libtool PACKAGE=libtool -VERSION=2.4.2 -TIMESTAMP="" -package_revision=1.3337 +VERSION=2.4.6 +package_revision=2.4.6 -# Be Bourne compatible -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + +## ------ ## +## Usage. ## +## ------ ## + +# Run './libtool --help' for help with using this script from the +# command line. + + +## ------------------------------- ## +## User overridable command paths. ## +## ------------------------------- ## + +# After configure completes, it has a better idea of some of the +# shell tools we need than the defaults used by the functions shared +# with bootstrap, so set those here where they can still be over- +# ridden by the user, but otherwise take precedence. + +: ${AUTOCONF="autoconf"} +: ${AUTOMAKE="automake"} + + +## -------------------------- ## +## Source external libraries. ## +## -------------------------- ## + +# Much of our low-level functionality needs to be sourced from external +# libraries, which are installed to $pkgauxdir. + +# Set a version string for this script. +scriptversion=2015-01-20.17; # UTC + +# General shell script boiler plate, and helper functions. +# Written by Gary V. Vaughan, 2004 + +# Copyright (C) 2004-2015 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. + +# As a special exception to the GNU General Public License, if you distribute +# this file as part of a program or library that is built using GNU Libtool, +# you may include this file under the same distribution terms that you use +# for the rest of that program. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Please report bugs or propose patches to gary@gnu.org. + + +## ------ ## +## Usage. ## +## ------ ## + +# Evaluate this file near the top of your script to gain access to +# the functions and variables defined here: +# +# . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh +# +# If you need to override any of the default environment variable +# settings, do that before evaluating this file. + + +## -------------------- ## +## Shell normalisation. ## +## -------------------- ## + +# Some shells need a little help to be as Bourne compatible as possible. +# Before doing anything else, make sure all that help has been provided! + +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else - case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac + case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi -BIN_SH=xpg4; export BIN_SH # for Tru64 -DUALCASE=1; export DUALCASE # for MKS sh -# A function that is used when there is no print builtin or printf. -func_fallback_echo () -{ - eval 'cat <<_LTECHO_EOF -$1 -_LTECHO_EOF' -} - -# NLS nuisances: We save the old values to restore during execute mode. -lt_user_locale= -lt_safe_locale= -for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES +# NLS nuisances: We save the old values in case they are required later. +_G_user_locale= +_G_safe_locale= +for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do - eval "if test \"\${$lt_var+set}\" = set; then - save_$lt_var=\$$lt_var - $lt_var=C - export $lt_var - lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" - lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" + eval "if test set = \"\${$_G_var+set}\"; then + save_$_G_var=\$$_G_var + $_G_var=C + export $_G_var + _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\" + _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\" fi" done -LC_ALL=C -LANGUAGE=C -export LANGUAGE LC_ALL -$lt_unset CDPATH +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH +# Make sure IFS has a sensible default +sp=' ' +nl=' +' +IFS="$sp $nl" + +# There are apparently some retarded systems that use ';' as a PATH separator! +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + + +## ------------------------- ## +## Locate command utilities. ## +## ------------------------- ## + + +# func_executable_p FILE +# ---------------------- +# Check that FILE is an executable regular file. +func_executable_p () +{ + test -f "$1" && test -x "$1" +} + + +# func_path_progs PROGS_LIST CHECK_FUNC [PATH] +# -------------------------------------------- +# Search for either a program that responds to --version with output +# containing "GNU", or else returned by CHECK_FUNC otherwise, by +# trying all the directories in PATH with each of the elements of +# PROGS_LIST. +# +# CHECK_FUNC should accept the path to a candidate program, and +# set $func_check_prog_result if it truncates its output less than +# $_G_path_prog_max characters. +func_path_progs () +{ + _G_progs_list=$1 + _G_check_func=$2 + _G_PATH=${3-"$PATH"} + + _G_path_prog_max=0 + _G_path_prog_found=false + _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:} + for _G_dir in $_G_PATH; do + IFS=$_G_save_IFS + test -z "$_G_dir" && _G_dir=. + for _G_prog_name in $_G_progs_list; do + for _exeext in '' .EXE; do + _G_path_prog=$_G_dir/$_G_prog_name$_exeext + func_executable_p "$_G_path_prog" || continue + case `"$_G_path_prog" --version 2>&1` in + *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;; + *) $_G_check_func $_G_path_prog + func_path_progs_result=$func_check_prog_result + ;; + esac + $_G_path_prog_found && break 3 + done + done + done + IFS=$_G_save_IFS + test -z "$func_path_progs_result" && { + echo "no acceptable sed could be found in \$PATH" >&2 + exit 1 + } +} + + +# We want to be able to use the functions in this file before configure +# has figured out where the best binaries are kept, which means we have +# to search for them ourselves - except when the results are already set +# where we skip the searches. + +# Unless the user overrides by setting SED, search the path for either GNU +# sed, or the sed that truncates its output the least. +test -z "$SED" && { + _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for _G_i in 1 2 3 4 5 6 7; do + _G_sed_script=$_G_sed_script$nl$_G_sed_script + done + echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed + _G_sed_script= + + func_check_prog_sed () + { + _G_path_prog=$1 + + _G_count=0 + printf 0123456789 >conftest.in + while : + do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo '' >> conftest.nl + "$_G_path_prog" -f conftest.sed conftest.out 2>/dev/null || break + diff conftest.out conftest.nl >/dev/null 2>&1 || break + _G_count=`expr $_G_count + 1` + if test "$_G_count" -gt "$_G_path_prog_max"; then + # Best one so far, save it but keep looking for a better one + func_check_prog_result=$_G_path_prog + _G_path_prog_max=$_G_count + fi + # 10*(2^10) chars as input seems more than enough + test 10 -lt "$_G_count" && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out + } + + func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin + rm -f conftest.sed + SED=$func_path_progs_result +} + + +# Unless the user overrides by setting GREP, search the path for either GNU +# grep, or the grep that truncates its output the least. +test -z "$GREP" && { + func_check_prog_grep () + { + _G_path_prog=$1 + + _G_count=0 + _G_path_prog_max=0 + printf 0123456789 >conftest.in + while : + do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo 'GREP' >> conftest.nl + "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' conftest.out 2>/dev/null || break + diff conftest.out conftest.nl >/dev/null 2>&1 || break + _G_count=`expr $_G_count + 1` + if test "$_G_count" -gt "$_G_path_prog_max"; then + # Best one so far, save it but keep looking for a better one + func_check_prog_result=$_G_path_prog + _G_path_prog_max=$_G_count + fi + # 10*(2^10) chars as input seems more than enough + test 10 -lt "$_G_count" && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out + } + + func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin + GREP=$func_path_progs_result +} + + +## ------------------------------- ## +## User overridable command paths. ## +## ------------------------------- ## + +# All uppercase variable names are used for environment variables. These +# variables can be overridden by the user before calling a script that +# uses them if a suitable command of that name is not already available +# in the command search PATH. + +: ${CP="cp -f"} +: ${ECHO="printf %s\n"} +: ${EGREP="$GREP -E"} +: ${FGREP="$GREP -F"} +: ${LN_S="ln -s"} +: ${MAKE="make"} +: ${MKDIR="mkdir"} +: ${MV="mv -f"} +: ${RM="rm -f"} +: ${SHELL="${CONFIG_SHELL-/bin/sh}"} + + +## -------------------- ## +## Useful sed snippets. ## +## -------------------- ## + +sed_dirname='s|/[^/]*$||' +sed_basename='s|^.*/||' + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='s|\([`"$\\]\)|\\\1|g' + +# Same as above, but do not quote variable references. +sed_double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution that turns a string into a regex matching for the +# string literally. +sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g' + +# Sed substitution that converts a w32 file name or path +# that contains forward slashes, into one that contains +# (escaped) backslashes. A very naive implementation. +sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' + +# Re-'\' parameter expansions in output of sed_double_quote_subst that +# were '\'-ed in input to the same. If an odd number of '\' preceded a +# '$' in input to sed_double_quote_subst, that '$' was protected from +# expansion. Since each input '\' is now two '\'s, look for any number +# of runs of four '\'s followed by two '\'s and then a '$'. '\' that '$'. +_G_bs='\\' +_G_bs2='\\\\' +_G_bs4='\\\\\\\\' +_G_dollar='\$' +sed_double_backslash="\ + s/$_G_bs4/&\\ +/g + s/^$_G_bs2$_G_dollar/$_G_bs&/ + s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g + s/\n//g" + + +## ----------------- ## +## Global variables. ## +## ----------------- ## + +# Except for the global variables explicitly listed below, the following +# functions in the '^func_' namespace, and the '^require_' namespace +# variables initialised in the 'Resource management' section, sourcing +# this file will not pollute your global namespace with anything +# else. There's no portable way to scope variables in Bourne shell +# though, so actually running these functions will sometimes place +# results into a variable named after the function, and often use +# temporary variables in the '^_G_' namespace. If you are careful to +# avoid using those namespaces casually in your sourcing script, things +# should continue to work as you expect. And, of course, you can freely +# overwrite any of the functions or variables defined here before +# calling anything to customize them. + +EXIT_SUCCESS=0 +EXIT_FAILURE=1 +EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. +EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. + +# Allow overriding, eg assuming that you follow the convention of +# putting '$debug_cmd' at the start of all your functions, you can get +# bash to show function call trace with: +# +# debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name +debug_cmd=${debug_cmd-":"} +exit_cmd=: + +# By convention, finish your script with: +# +# exit $exit_status +# +# so that you can set exit_status to non-zero if you want to indicate +# something went wrong during execution without actually bailing out at +# the point of failure. +exit_status=$EXIT_SUCCESS # Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh # is ksh but when the shell is invoked as "sh" and the current value of # the _XPG environment variable is not equal to 1 (one), the special # positional parameter $0, within a function call, is the name of the # function. -progpath="$0" +progpath=$0 + +# The name of this program. +progname=`$ECHO "$progpath" |$SED "$sed_basename"` + +# Make sure we have an absolute progpath for reexecution: +case $progpath in + [\\/]*|[A-Za-z]:\\*) ;; + *[\\/]*) + progdir=`$ECHO "$progpath" |$SED "$sed_dirname"` + progdir=`cd "$progdir" && pwd` + progpath=$progdir/$progname + ;; + *) + _G_IFS=$IFS + IFS=${PATH_SEPARATOR-:} + for progdir in $PATH; do + IFS=$_G_IFS + test -x "$progdir/$progname" && break + done + IFS=$_G_IFS + test -n "$progdir" || progdir=`pwd` + progpath=$progdir/$progname + ;; +esac +## ----------------- ## +## Standard options. ## +## ----------------- ## -: ${CP="cp -f"} -test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'} -: ${MAKE="make"} -: ${MKDIR="mkdir"} -: ${MV="mv -f"} -: ${RM="rm -f"} -: ${SHELL="${CONFIG_SHELL-/bin/sh}"} -: ${Xsed="$SED -e 1s/^X//"} +# The following options affect the operation of the functions defined +# below, and should be set appropriately depending on run-time para- +# meters passed on the command line. -# Global variables: -EXIT_SUCCESS=0 -EXIT_FAILURE=1 -EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. -EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. +opt_dry_run=false +opt_quiet=false +opt_verbose=false -exit_status=$EXIT_SUCCESS +# Categories 'all' and 'none' are always available. Append any others +# you will pass as the first argument to func_warning from your own +# code. +warning_categories= -# Make sure IFS has a sensible default -lt_nl=' -' -IFS=" $lt_nl" +# By default, display warnings according to 'opt_warning_types'. Set +# 'warning_func' to ':' to elide all warnings, or func_fatal_error to +# treat the next displayed warning as a fatal error. +warning_func=func_warn_and_continue -dirname="s,/[^/]*$,," -basename="s,^.*/,," +# Set to 'all' to display all warnings, 'none' to suppress all +# warnings, or a space delimited list of some subset of +# 'warning_categories' to display only the listed warnings. +opt_warning_types=all -# func_dirname file append nondir_replacement + +## -------------------- ## +## Resource management. ## +## -------------------- ## + +# This section contains definitions for functions that each ensure a +# particular resource (a file, or a non-empty configuration variable for +# example) is available, and if appropriate to extract default values +# from pertinent package files. Call them using their associated +# 'require_*' variable to ensure that they are executed, at most, once. +# +# It's entirely deliberate that calling these functions can set +# variables that don't obey the namespace limitations obeyed by the rest +# of this file, in order that that they be as useful as possible to +# callers. + + +# require_term_colors +# ------------------- +# Allow display of bold text on terminals that support it. +require_term_colors=func_require_term_colors +func_require_term_colors () +{ + $debug_cmd + + test -t 1 && { + # COLORTERM and USE_ANSI_COLORS environment variables take + # precedence, because most terminfo databases neglect to describe + # whether color sequences are supported. + test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"} + + if test 1 = "$USE_ANSI_COLORS"; then + # Standard ANSI escape sequences + tc_reset='' + tc_bold=''; tc_standout='' + tc_red=''; tc_green='' + tc_blue=''; tc_cyan='' + else + # Otherwise trust the terminfo database after all. + test -n "`tput sgr0 2>/dev/null`" && { + tc_reset=`tput sgr0` + test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold` + tc_standout=$tc_bold + test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso` + test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1` + test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2` + test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4` + test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5` + } + fi + } + + require_term_colors=: +} + + +## ----------------- ## +## Function library. ## +## ----------------- ## + +# This section contains a variety of useful functions to call in your +# scripts. Take note of the portable wrappers for features provided by +# some modern shells, which will fall back to slower equivalents on +# less featureful shells. + + +# func_append VAR VALUE +# --------------------- +# Append VALUE onto the existing contents of VAR. + + # We should try to minimise forks, especially on Windows where they are + # unreasonably slow, so skip the feature probes when bash or zsh are + # being used: + if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then + : ${_G_HAVE_ARITH_OP="yes"} + : ${_G_HAVE_XSI_OPS="yes"} + # The += operator was introduced in bash 3.1 + case $BASH_VERSION in + [12].* | 3.0 | 3.0*) ;; + *) + : ${_G_HAVE_PLUSEQ_OP="yes"} + ;; + esac + fi + + # _G_HAVE_PLUSEQ_OP + # Can be empty, in which case the shell is probed, "yes" if += is + # useable or anything else if it does not work. + test -z "$_G_HAVE_PLUSEQ_OP" \ + && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \ + && _G_HAVE_PLUSEQ_OP=yes + +if test yes = "$_G_HAVE_PLUSEQ_OP" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_append () + { + $debug_cmd + + eval "$1+=\$2" + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_append () + { + $debug_cmd + + eval "$1=\$$1\$2" + } +fi + + +# func_append_quoted VAR VALUE +# ---------------------------- +# Quote VALUE and append to the end of shell variable VAR, separated +# by a space. +if test yes = "$_G_HAVE_PLUSEQ_OP"; then + eval 'func_append_quoted () + { + $debug_cmd + + func_quote_for_eval "$2" + eval "$1+=\\ \$func_quote_for_eval_result" + }' +else + func_append_quoted () + { + $debug_cmd + + func_quote_for_eval "$2" + eval "$1=\$$1\\ \$func_quote_for_eval_result" + } +fi + + +# func_append_uniq VAR VALUE +# -------------------------- +# Append unique VALUE onto the existing contents of VAR, assuming +# entries are delimited by the first character of VALUE. For example: +# +# func_append_uniq options " --another-option option-argument" +# +# will only append to $options if " --another-option option-argument " +# is not already present somewhere in $options already (note spaces at +# each end implied by leading space in second argument). +func_append_uniq () +{ + $debug_cmd + + eval _G_current_value='`$ECHO $'$1'`' + _G_delim=`expr "$2" : '\(.\)'` + + case $_G_delim$_G_current_value$_G_delim in + *"$2$_G_delim"*) ;; + *) func_append "$@" ;; + esac +} + + +# func_arith TERM... +# ------------------ +# Set func_arith_result to the result of evaluating TERMs. + test -z "$_G_HAVE_ARITH_OP" \ + && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \ + && _G_HAVE_ARITH_OP=yes + +if test yes = "$_G_HAVE_ARITH_OP"; then + eval 'func_arith () + { + $debug_cmd + + func_arith_result=$(( $* )) + }' +else + func_arith () + { + $debug_cmd + + func_arith_result=`expr "$@"` + } +fi + + +# func_basename FILE +# ------------------ +# Set func_basename_result to FILE with everything up to and including +# the last / stripped. +if test yes = "$_G_HAVE_XSI_OPS"; then + # If this shell supports suffix pattern removal, then use it to avoid + # forking. Hide the definitions single quotes in case the shell chokes + # on unsupported syntax... + _b='func_basename_result=${1##*/}' + _d='case $1 in + */*) func_dirname_result=${1%/*}$2 ;; + * ) func_dirname_result=$3 ;; + esac' + +else + # ...otherwise fall back to using sed. + _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`' + _d='func_dirname_result=`$ECHO "$1" |$SED "$sed_dirname"` + if test "X$func_dirname_result" = "X$1"; then + func_dirname_result=$3 + else + func_append func_dirname_result "$2" + fi' +fi + +eval 'func_basename () +{ + $debug_cmd + + '"$_b"' +}' + + +# func_dirname FILE APPEND NONDIR_REPLACEMENT +# ------------------------------------------- # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. -func_dirname () +eval 'func_dirname () { - func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` - if test "X$func_dirname_result" = "X${1}"; then - func_dirname_result="${3}" - else - func_dirname_result="$func_dirname_result${2}" - fi -} # func_dirname may be replaced by extended shell implementation + $debug_cmd + + '"$_d"' +}' -# func_basename file -func_basename () -{ - func_basename_result=`$ECHO "${1}" | $SED "$basename"` -} # func_basename may be replaced by extended shell implementation - - -# func_dirname_and_basename file append nondir_replacement -# perform func_basename and func_dirname in a single function +# func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT +# -------------------------------------------------------- +# Perform func_basename and func_dirname in a single function # call: # dirname: Compute the dirname of FILE. If nonempty, # add APPEND to the result, otherwise set result # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. -# value returned in "$func_basename_result" -# Implementation must be kept synchronized with func_dirname -# and func_basename. For efficiency, we do not delegate to -# those functions but instead duplicate the functionality here. -func_dirname_and_basename () +# value retuned in "$func_basename_result" +# For efficiency, we do not delegate to the functions above but instead +# duplicate the functionality here. +eval 'func_dirname_and_basename () { - # Extract subdirectory from the argument. - func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"` - if test "X$func_dirname_result" = "X${1}"; then - func_dirname_result="${3}" - else - func_dirname_result="$func_dirname_result${2}" + $debug_cmd + + '"$_b"' + '"$_d"' +}' + + +# func_echo ARG... +# ---------------- +# Echo program name prefixed message. +func_echo () +{ + $debug_cmd + + _G_message=$* + + func_echo_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_IFS + $ECHO "$progname: $_G_line" + done + IFS=$func_echo_IFS +} + + +# func_echo_all ARG... +# -------------------- +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + + +# func_echo_infix_1 INFIX ARG... +# ------------------------------ +# Echo program name, followed by INFIX on the first line, with any +# additional lines not showing INFIX. +func_echo_infix_1 () +{ + $debug_cmd + + $require_term_colors + + _G_infix=$1; shift + _G_indent=$_G_infix + _G_prefix="$progname: $_G_infix: " + _G_message=$* + + # Strip color escape sequences before counting printable length + for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan" + do + test -n "$_G_tc" && { + _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"` + _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"` + } + done + _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`" " ## exclude from sc_prohibit_nested_quotes + + func_echo_infix_1_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_infix_1_IFS + $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2 + _G_prefix=$_G_indent + done + IFS=$func_echo_infix_1_IFS +} + + +# func_error ARG... +# ----------------- +# Echo program name prefixed message to standard error. +func_error () +{ + $debug_cmd + + $require_term_colors + + func_echo_infix_1 " $tc_standout${tc_red}error$tc_reset" "$*" >&2 +} + + +# func_fatal_error ARG... +# ----------------------- +# Echo program name prefixed message to standard error, and exit. +func_fatal_error () +{ + $debug_cmd + + func_error "$*" + exit $EXIT_FAILURE +} + + +# func_grep EXPRESSION FILENAME +# ----------------------------- +# Check whether EXPRESSION matches any line of FILENAME, without output. +func_grep () +{ + $debug_cmd + + $GREP "$1" "$2" >/dev/null 2>&1 +} + + +# func_len STRING +# --------------- +# Set func_len_result to the length of STRING. STRING may not +# start with a hyphen. + test -z "$_G_HAVE_XSI_OPS" \ + && (eval 'x=a/b/c; + test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ + && _G_HAVE_XSI_OPS=yes + +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_len () + { + $debug_cmd + + func_len_result=${#1} + }' +else + func_len () + { + $debug_cmd + + func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` + } +fi + + +# func_mkdir_p DIRECTORY-PATH +# --------------------------- +# Make sure the entire path to DIRECTORY-PATH is available. +func_mkdir_p () +{ + $debug_cmd + + _G_directory_path=$1 + _G_dir_list= + + if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then + + # Protect directory names starting with '-' + case $_G_directory_path in + -*) _G_directory_path=./$_G_directory_path ;; + esac + + # While some portion of DIR does not yet exist... + while test ! -d "$_G_directory_path"; do + # ...make a list in topmost first order. Use a colon delimited + # list incase some portion of path contains whitespace. + _G_dir_list=$_G_directory_path:$_G_dir_list + + # If the last portion added has no slash in it, the list is done + case $_G_directory_path in */*) ;; *) break ;; esac + + # ...otherwise throw away the child directory and loop + _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"` + done + _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'` + + func_mkdir_p_IFS=$IFS; IFS=: + for _G_dir in $_G_dir_list; do + IFS=$func_mkdir_p_IFS + # mkdir can fail with a 'File exist' error if two processes + # try to create one of the directories concurrently. Don't + # stop in that case! + $MKDIR "$_G_dir" 2>/dev/null || : + done + IFS=$func_mkdir_p_IFS + + # Bail out if we (or some other process) failed to create a directory. + test -d "$_G_directory_path" || \ + func_fatal_error "Failed to create '$1'" fi - func_basename_result=`$ECHO "${1}" | $SED -e "$basename"` -} # func_dirname_and_basename may be replaced by extended shell implementation +} -# func_stripname prefix suffix name -# strip PREFIX and SUFFIX off of NAME. -# PREFIX and SUFFIX must not contain globbing or regex special -# characters, hashes, percent signs, but SUFFIX may contain a leading -# dot (in which case that matches only a dot). -# func_strip_suffix prefix name -func_stripname () +# func_mktempdir [BASENAME] +# ------------------------- +# Make a temporary directory that won't clash with other running +# libtool processes, and avoids race conditions if possible. If +# given, BASENAME is the basename for that directory. +func_mktempdir () { - case ${2} in - .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; - *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; - esac -} # func_stripname may be replaced by extended shell implementation + $debug_cmd + _G_template=${TMPDIR-/tmp}/${1-$progname} + + if test : = "$opt_dry_run"; then + # Return a directory name, but don't create it in dry-run mode + _G_tmpdir=$_G_template-$$ + else + + # If mktemp works, use that first and foremost + _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null` + + if test ! -d "$_G_tmpdir"; then + # Failing that, at least try and use $RANDOM to avoid a race + _G_tmpdir=$_G_template-${RANDOM-0}$$ + + func_mktempdir_umask=`umask` + umask 0077 + $MKDIR "$_G_tmpdir" + umask $func_mktempdir_umask + fi + + # If we're not in dry-run mode, bomb out on failure + test -d "$_G_tmpdir" || \ + func_fatal_error "cannot create temporary directory '$_G_tmpdir'" + fi + + $ECHO "$_G_tmpdir" +} -# These SED scripts presuppose an absolute path with a trailing slash. -pathcar='s,^/\([^/]*\).*$,\1,' -pathcdr='s,^/[^/]*,,' -removedotparts=':dotsl - s@/\./@/@g - t dotsl - s,/\.$,/,' -collapseslashes='s@/\{1,\}@/@g' -finalslash='s,/*$,/,' # func_normal_abspath PATH +# ------------------------ # Remove doubled-up and trailing slashes, "." path components, # and cancel out any ".." path components in PATH after making # it an absolute path. -# value returned in "$func_normal_abspath_result" func_normal_abspath () { - # Start from root dir and reassemble the path. - func_normal_abspath_result= - func_normal_abspath_tpath=$1 - func_normal_abspath_altnamespace= - case $func_normal_abspath_tpath in - "") - # Empty path, that just means $cwd. - func_stripname '' '/' "`pwd`" - func_normal_abspath_result=$func_stripname_result - return - ;; - # The next three entries are used to spot a run of precisely - # two leading slashes without using negated character classes; - # we take advantage of case's first-match behaviour. - ///*) - # Unusual form of absolute path, do nothing. - ;; - //*) - # Not necessarily an ordinary path; POSIX reserves leading '//' - # and for example Cygwin uses it to access remote file shares - # over CIFS/SMB, so we conserve a leading double slash if found. - func_normal_abspath_altnamespace=/ - ;; - /*) - # Absolute path, do nothing. - ;; - *) - # Relative path, prepend $cwd. - func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath - ;; - esac - # Cancel out all the simple stuff to save iterations. We also want - # the path to end with a slash for ease of parsing, so make sure - # there is one (and only one) here. - func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ - -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"` - while :; do - # Processed it all yet? - if test "$func_normal_abspath_tpath" = / ; then - # If we ascended to the root using ".." the result may be empty now. - if test -z "$func_normal_abspath_result" ; then - func_normal_abspath_result=/ - fi - break - fi - func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ - -e "$pathcar"` - func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ - -e "$pathcdr"` - # Figure out what to do with it - case $func_normal_abspath_tcomponent in + $debug_cmd + + # These SED scripts presuppose an absolute path with a trailing slash. + _G_pathcar='s|^/\([^/]*\).*$|\1|' + _G_pathcdr='s|^/[^/]*||' + _G_removedotparts=':dotsl + s|/\./|/|g + t dotsl + s|/\.$|/|' + _G_collapseslashes='s|/\{1,\}|/|g' + _G_finalslash='s|/*$|/|' + + # Start from root dir and reassemble the path. + func_normal_abspath_result= + func_normal_abspath_tpath=$1 + func_normal_abspath_altnamespace= + case $func_normal_abspath_tpath in "") - # Trailing empty path component, ignore it. - ;; - ..) - # Parent dir; strip last assembled component from result. - func_dirname "$func_normal_abspath_result" - func_normal_abspath_result=$func_dirname_result - ;; - *) - # Actual path component, append it. - func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent - ;; - esac - done - # Restore leading double-slash if one was found on entry. - func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result -} - -# func_relative_path SRCDIR DSTDIR -# generates a relative path from SRCDIR to DSTDIR, with a trailing -# slash if non-empty, suitable for immediately appending a filename -# without needing to append a separator. -# value returned in "$func_relative_path_result" -func_relative_path () -{ - func_relative_path_result= - func_normal_abspath "$1" - func_relative_path_tlibdir=$func_normal_abspath_result - func_normal_abspath "$2" - func_relative_path_tbindir=$func_normal_abspath_result - - # Ascend the tree starting from libdir - while :; do - # check if we have found a prefix of bindir - case $func_relative_path_tbindir in - $func_relative_path_tlibdir) - # found an exact match - func_relative_path_tcancelled= - break + # Empty path, that just means $cwd. + func_stripname '' '/' "`pwd`" + func_normal_abspath_result=$func_stripname_result + return ;; - $func_relative_path_tlibdir*) - # found a matching prefix - func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" - func_relative_path_tcancelled=$func_stripname_result - if test -z "$func_relative_path_result"; then - func_relative_path_result=. - fi - break + # The next three entries are used to spot a run of precisely + # two leading slashes without using negated character classes; + # we take advantage of case's first-match behaviour. + ///*) + # Unusual form of absolute path, do nothing. + ;; + //*) + # Not necessarily an ordinary path; POSIX reserves leading '//' + # and for example Cygwin uses it to access remote file shares + # over CIFS/SMB, so we conserve a leading double slash if found. + func_normal_abspath_altnamespace=/ + ;; + /*) + # Absolute path, do nothing. ;; *) - func_dirname $func_relative_path_tlibdir - func_relative_path_tlibdir=${func_dirname_result} - if test "x$func_relative_path_tlibdir" = x ; then - # Have to descend all the way to the root! - func_relative_path_result=../$func_relative_path_result - func_relative_path_tcancelled=$func_relative_path_tbindir - break - fi - func_relative_path_result=../$func_relative_path_result + # Relative path, prepend $cwd. + func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath ;; esac - done - # Now calculate path; take care to avoid doubling-up slashes. - func_stripname '' '/' "$func_relative_path_result" - func_relative_path_result=$func_stripname_result - func_stripname '/' '/' "$func_relative_path_tcancelled" - if test "x$func_stripname_result" != x ; then - func_relative_path_result=${func_relative_path_result}/${func_stripname_result} - fi - - # Normalisation. If bindir is libdir, return empty string, - # else relative path ending with a slash; either way, target - # file name can be directly appended. - if test ! -z "$func_relative_path_result"; then - func_stripname './' '' "$func_relative_path_result/" - func_relative_path_result=$func_stripname_result - fi + # Cancel out all the simple stuff to save iterations. We also want + # the path to end with a slash for ease of parsing, so make sure + # there is one (and only one) here. + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"` + while :; do + # Processed it all yet? + if test / = "$func_normal_abspath_tpath"; then + # If we ascended to the root using ".." the result may be empty now. + if test -z "$func_normal_abspath_result"; then + func_normal_abspath_result=/ + fi + break + fi + func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_pathcar"` + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_pathcdr"` + # Figure out what to do with it + case $func_normal_abspath_tcomponent in + "") + # Trailing empty path component, ignore it. + ;; + ..) + # Parent dir; strip last assembled component from result. + func_dirname "$func_normal_abspath_result" + func_normal_abspath_result=$func_dirname_result + ;; + *) + # Actual path component, append it. + func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent" + ;; + esac + done + # Restore leading double-slash if one was found on entry. + func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result } -# The name of this program: -func_dirname_and_basename "$progpath" -progname=$func_basename_result -# Make sure we have an absolute path for reexecution: -case $progpath in - [\\/]*|[A-Za-z]:\\*) ;; - *[\\/]*) - progdir=$func_dirname_result - progdir=`cd "$progdir" && pwd` - progpath="$progdir/$progname" - ;; - *) - save_IFS="$IFS" - IFS=${PATH_SEPARATOR-:} - for progdir in $PATH; do - IFS="$save_IFS" - test -x "$progdir/$progname" && break - done - IFS="$save_IFS" - test -n "$progdir" || progdir=`pwd` - progpath="$progdir/$progname" - ;; -esac - -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -Xsed="${SED}"' -e 1s/^X//' -sed_quote_subst='s/\([`"$\\]\)/\\\1/g' - -# Same as above, but do not quote variable references. -double_quote_subst='s/\(["`\\]\)/\\\1/g' - -# Sed substitution that turns a string into a regex matching for the -# string literally. -sed_make_literal_regex='s,[].[^$\\*\/],\\&,g' - -# Sed substitution that converts a w32 file name or path -# which contains forward slashes, into one that contains -# (escaped) backslashes. A very naive implementation. -lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' - -# Re-`\' parameter expansions in output of double_quote_subst that were -# `\'-ed in input to the same. If an odd number of `\' preceded a '$' -# in input to double_quote_subst, that '$' was protected from expansion. -# Since each input `\' is now two `\'s, look for any number of runs of -# four `\'s followed by two `\'s and then a '$'. `\' that '$'. -bs='\\' -bs2='\\\\' -bs4='\\\\\\\\' -dollar='\$' -sed_double_backslash="\ - s/$bs4/&\\ -/g - s/^$bs2$dollar/$bs&/ - s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g - s/\n//g" - -# Standard options: -opt_dry_run=false -opt_help=false -opt_quiet=false -opt_verbose=false -opt_warning=: - -# func_echo arg... -# Echo program name prefixed message, along with the current mode -# name if it has been set yet. -func_echo () +# func_notquiet ARG... +# -------------------- +# Echo program name prefixed message only when not in quiet mode. +func_notquiet () { - $ECHO "$progname: ${opt_mode+$opt_mode: }$*" -} + $debug_cmd -# func_verbose arg... -# Echo program name prefixed message in verbose mode only. -func_verbose () -{ - $opt_verbose && func_echo ${1+"$@"} + $opt_quiet || func_echo ${1+"$@"} # A bug in bash halts the script if the last line of a function # fails when set -e is in force, so we need another command to @@ -454,450 +1025,1113 @@ func_verbose () : } -# func_echo_all arg... -# Invoke $ECHO with all args, space-separated. -func_echo_all () -{ - $ECHO "$*" -} -# func_error arg... -# Echo program name prefixed message to standard error. -func_error () +# func_relative_path SRCDIR DSTDIR +# -------------------------------- +# Set func_relative_path_result to the relative path from SRCDIR to DSTDIR. +func_relative_path () { - $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2 -} + $debug_cmd -# func_warning arg... -# Echo program name prefixed warning message to standard error. -func_warning () -{ - $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2 + func_relative_path_result= + func_normal_abspath "$1" + func_relative_path_tlibdir=$func_normal_abspath_result + func_normal_abspath "$2" + func_relative_path_tbindir=$func_normal_abspath_result + + # Ascend the tree starting from libdir + while :; do + # check if we have found a prefix of bindir + case $func_relative_path_tbindir in + $func_relative_path_tlibdir) + # found an exact match + func_relative_path_tcancelled= + break + ;; + $func_relative_path_tlibdir*) + # found a matching prefix + func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" + func_relative_path_tcancelled=$func_stripname_result + if test -z "$func_relative_path_result"; then + func_relative_path_result=. + fi + break + ;; + *) + func_dirname $func_relative_path_tlibdir + func_relative_path_tlibdir=$func_dirname_result + if test -z "$func_relative_path_tlibdir"; then + # Have to descend all the way to the root! + func_relative_path_result=../$func_relative_path_result + func_relative_path_tcancelled=$func_relative_path_tbindir + break + fi + func_relative_path_result=../$func_relative_path_result + ;; + esac + done + + # Now calculate path; take care to avoid doubling-up slashes. + func_stripname '' '/' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + func_stripname '/' '/' "$func_relative_path_tcancelled" + if test -n "$func_stripname_result"; then + func_append func_relative_path_result "/$func_stripname_result" + fi + + # Normalisation. If bindir is libdir, return '.' else relative path. + if test -n "$func_relative_path_result"; then + func_stripname './' '' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + fi + + test -n "$func_relative_path_result" || func_relative_path_result=. - # bash bug again: : } -# func_fatal_error arg... -# Echo program name prefixed message to standard error, and exit. -func_fatal_error () -{ - func_error ${1+"$@"} - exit $EXIT_FAILURE -} -# func_fatal_help arg... -# Echo program name prefixed message to standard error, followed by -# a help hint, and exit. -func_fatal_help () -{ - func_error ${1+"$@"} - func_fatal_error "$help" -} -help="Try \`$progname --help' for more information." ## default - - -# func_grep expression filename -# Check whether EXPRESSION matches any line of FILENAME, without output. -func_grep () -{ - $GREP "$1" "$2" >/dev/null 2>&1 -} - - -# func_mkdir_p directory-path -# Make sure the entire path to DIRECTORY-PATH is available. -func_mkdir_p () -{ - my_directory_path="$1" - my_dir_list= - - if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then - - # Protect directory names starting with `-' - case $my_directory_path in - -*) my_directory_path="./$my_directory_path" ;; - esac - - # While some portion of DIR does not yet exist... - while test ! -d "$my_directory_path"; do - # ...make a list in topmost first order. Use a colon delimited - # list incase some portion of path contains whitespace. - my_dir_list="$my_directory_path:$my_dir_list" - - # If the last portion added has no slash in it, the list is done - case $my_directory_path in */*) ;; *) break ;; esac - - # ...otherwise throw away the child directory and loop - my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"` - done - my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'` - - save_mkdir_p_IFS="$IFS"; IFS=':' - for my_dir in $my_dir_list; do - IFS="$save_mkdir_p_IFS" - # mkdir can fail with a `File exist' error if two processes - # try to create one of the directories concurrently. Don't - # stop in that case! - $MKDIR "$my_dir" 2>/dev/null || : - done - IFS="$save_mkdir_p_IFS" - - # Bail out if we (or some other process) failed to create a directory. - test -d "$my_directory_path" || \ - func_fatal_error "Failed to create \`$1'" - fi -} - - -# func_mktempdir [string] -# Make a temporary directory that won't clash with other running -# libtool processes, and avoids race conditions if possible. If -# given, STRING is the basename for that directory. -func_mktempdir () -{ - my_template="${TMPDIR-/tmp}/${1-$progname}" - - if test "$opt_dry_run" = ":"; then - # Return a directory name, but don't create it in dry-run mode - my_tmpdir="${my_template}-$$" - else - - # If mktemp works, use that first and foremost - my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` - - if test ! -d "$my_tmpdir"; then - # Failing that, at least try and use $RANDOM to avoid a race - my_tmpdir="${my_template}-${RANDOM-0}$$" - - save_mktempdir_umask=`umask` - umask 0077 - $MKDIR "$my_tmpdir" - umask $save_mktempdir_umask - fi - - # If we're not in dry-run mode, bomb out on failure - test -d "$my_tmpdir" || \ - func_fatal_error "cannot create temporary directory \`$my_tmpdir'" - fi - - $ECHO "$my_tmpdir" -} - - -# func_quote_for_eval arg -# Aesthetically quote ARG to be evaled later. -# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT -# is double-quoted, suitable for a subsequent eval, whereas -# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters -# which are still active within double quotes backslashified. +# func_quote_for_eval ARG... +# -------------------------- +# Aesthetically quote ARGs to be evaled later. +# This function returns two values: +# i) func_quote_for_eval_result +# double-quoted, suitable for a subsequent eval +# ii) func_quote_for_eval_unquoted_result +# has all characters that are still active within double +# quotes backslashified. func_quote_for_eval () { - case $1 in - *[\\\`\"\$]*) - func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;; - *) - func_quote_for_eval_unquoted_result="$1" ;; - esac + $debug_cmd - case $func_quote_for_eval_unquoted_result in - # Double-quote args containing shell metacharacters to delay - # word splitting, command substitution and and variable - # expansion for a subsequent eval. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" - ;; - *) - func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" - esac + func_quote_for_eval_unquoted_result= + func_quote_for_eval_result= + while test 0 -lt $#; do + case $1 in + *[\\\`\"\$]*) + _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;; + *) + _G_unquoted_arg=$1 ;; + esac + if test -n "$func_quote_for_eval_unquoted_result"; then + func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg" + else + func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg" + fi + + case $_G_unquoted_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting, command substitution and variable expansion + # for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + _G_quoted_arg=\"$_G_unquoted_arg\" + ;; + *) + _G_quoted_arg=$_G_unquoted_arg + ;; + esac + + if test -n "$func_quote_for_eval_result"; then + func_append func_quote_for_eval_result " $_G_quoted_arg" + else + func_append func_quote_for_eval_result "$_G_quoted_arg" + fi + shift + done } -# func_quote_for_expand arg +# func_quote_for_expand ARG +# ------------------------- # Aesthetically quote ARG to be evaled later; same as above, # but do not quote variable references. func_quote_for_expand () { + $debug_cmd + case $1 in *[\\\`\"]*) - my_arg=`$ECHO "$1" | $SED \ - -e "$double_quote_subst" -e "$sed_double_backslash"` ;; + _G_arg=`$ECHO "$1" | $SED \ + -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;; *) - my_arg="$1" ;; + _G_arg=$1 ;; esac - case $my_arg in + case $_G_arg in # Double-quote args containing shell metacharacters to delay # word splitting and command substitution for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - my_arg="\"$my_arg\"" + _G_arg=\"$_G_arg\" ;; esac - func_quote_for_expand_result="$my_arg" + func_quote_for_expand_result=$_G_arg } -# func_show_eval cmd [fail_exp] -# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is +# func_stripname PREFIX SUFFIX NAME +# --------------------------------- +# strip PREFIX and SUFFIX from NAME, and store in func_stripname_result. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_stripname () + { + $debug_cmd + + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary variable first. + func_stripname_result=$3 + func_stripname_result=${func_stripname_result#"$1"} + func_stripname_result=${func_stripname_result%"$2"} + }' +else + func_stripname () + { + $debug_cmd + + case $2 in + .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;; + *) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;; + esac + } +fi + + +# func_show_eval CMD [FAIL_EXP] +# ----------------------------- +# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. func_show_eval () { - my_cmd="$1" - my_fail_exp="${2-:}" + $debug_cmd - ${opt_silent-false} || { - func_quote_for_expand "$my_cmd" - eval "func_echo $func_quote_for_expand_result" - } + _G_cmd=$1 + _G_fail_exp=${2-':'} - if ${opt_dry_run-false}; then :; else - eval "$my_cmd" - my_status=$? - if test "$my_status" -eq 0; then :; else - eval "(exit $my_status); $my_fail_exp" + func_quote_for_expand "$_G_cmd" + eval "func_notquiet $func_quote_for_expand_result" + + $opt_dry_run || { + eval "$_G_cmd" + _G_status=$? + if test 0 -ne "$_G_status"; then + eval "(exit $_G_status); $_G_fail_exp" fi - fi + } } -# func_show_eval_locale cmd [fail_exp] -# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is +# func_show_eval_locale CMD [FAIL_EXP] +# ------------------------------------ +# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. Use the saved locale for evaluation. func_show_eval_locale () { - my_cmd="$1" - my_fail_exp="${2-:}" + $debug_cmd - ${opt_silent-false} || { - func_quote_for_expand "$my_cmd" + _G_cmd=$1 + _G_fail_exp=${2-':'} + + $opt_quiet || { + func_quote_for_expand "$_G_cmd" eval "func_echo $func_quote_for_expand_result" } - if ${opt_dry_run-false}; then :; else - eval "$lt_user_locale - $my_cmd" - my_status=$? - eval "$lt_safe_locale" - if test "$my_status" -eq 0; then :; else - eval "(exit $my_status); $my_fail_exp" + $opt_dry_run || { + eval "$_G_user_locale + $_G_cmd" + _G_status=$? + eval "$_G_safe_locale" + if test 0 -ne "$_G_status"; then + eval "(exit $_G_status); $_G_fail_exp" fi - fi + } } + # func_tr_sh +# ---------- # Turn $1 into a string suitable for a shell variable name. # Result is stored in $func_tr_sh_result. All characters # not in the set a-zA-Z0-9_ are replaced with '_'. Further, # if $1 begins with a digit, a '_' is prepended as well. func_tr_sh () { - case $1 in - [0-9]* | *[!a-zA-Z0-9_]*) - func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'` - ;; - * ) - func_tr_sh_result=$1 - ;; - esac + $debug_cmd + + case $1 in + [0-9]* | *[!a-zA-Z0-9_]*) + func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'` + ;; + * ) + func_tr_sh_result=$1 + ;; + esac } -# func_version -# Echo version message to standard output and exit. -func_version () +# func_verbose ARG... +# ------------------- +# Echo program name prefixed message in verbose mode only. +func_verbose () { - $opt_debug + $debug_cmd - $SED -n '/(C)/!b go - :more - /\./!{ - N - s/\n# / / - b more - } - :go - /^# '$PROGRAM' (GNU /,/# warranty; / { - s/^# // - s/^# *$// - s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ - p - }' < "$progpath" - exit $? + $opt_verbose && func_echo "$*" + + : } -# func_usage -# Echo short help message to standard output and exit. -func_usage () + +# func_warn_and_continue ARG... +# ----------------------------- +# Echo program name prefixed warning message to standard error. +func_warn_and_continue () { - $opt_debug + $debug_cmd - $SED -n '/^# Usage:/,/^# *.*--help/ { - s/^# // - s/^# *$// - s/\$progname/'$progname'/ - p - }' < "$progpath" - echo - $ECHO "run \`$progname --help | more' for full usage" - exit $? + $require_term_colors + + func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2 } -# func_help [NOEXIT] -# Echo long help message to standard output and exit, -# unless 'noexit' is passed as argument. + +# func_warning CATEGORY ARG... +# ---------------------------- +# Echo program name prefixed warning message to standard error. Warning +# messages can be filtered according to CATEGORY, where this function +# elides messages where CATEGORY is not listed in the global variable +# 'opt_warning_types'. +func_warning () +{ + $debug_cmd + + # CATEGORY must be in the warning_categories list! + case " $warning_categories " in + *" $1 "*) ;; + *) func_internal_error "invalid warning category '$1'" ;; + esac + + _G_category=$1 + shift + + case " $opt_warning_types " in + *" $_G_category "*) $warning_func ${1+"$@"} ;; + esac +} + + +# func_sort_ver VER1 VER2 +# ----------------------- +# 'sort -V' is not generally available. +# Note this deviates from the version comparison in automake +# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a +# but this should suffice as we won't be specifying old +# version formats or redundant trailing .0 in bootstrap.conf. +# If we did want full compatibility then we should probably +# use m4_version_compare from autoconf. +func_sort_ver () +{ + $debug_cmd + + printf '%s\n%s\n' "$1" "$2" \ + | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n +} + +# func_lt_ver PREV CURR +# --------------------- +# Return true if PREV and CURR are in the correct order according to +# func_sort_ver, otherwise false. Use it like this: +# +# func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..." +func_lt_ver () +{ + $debug_cmd + + test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q` +} + + +# Local variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" +# time-stamp-time-zone: "UTC" +# End: +#! /bin/sh + +# Set a version string for this script. +scriptversion=2014-01-07.03; # UTC + +# A portable, pluggable option parser for Bourne shell. +# Written by Gary V. Vaughan, 2010 + +# Copyright (C) 2010-2015 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Please report bugs or propose patches to gary@gnu.org. + + +## ------ ## +## Usage. ## +## ------ ## + +# This file is a library for parsing options in your shell scripts along +# with assorted other useful supporting features that you can make use +# of too. +# +# For the simplest scripts you might need only: +# +# #!/bin/sh +# . relative/path/to/funclib.sh +# . relative/path/to/options-parser +# scriptversion=1.0 +# func_options ${1+"$@"} +# eval set dummy "$func_options_result"; shift +# ...rest of your script... +# +# In order for the '--version' option to work, you will need to have a +# suitably formatted comment like the one at the top of this file +# starting with '# Written by ' and ending with '# warranty; '. +# +# For '-h' and '--help' to work, you will also need a one line +# description of your script's purpose in a comment directly above the +# '# Written by ' line, like the one at the top of this file. +# +# The default options also support '--debug', which will turn on shell +# execution tracing (see the comment above debug_cmd below for another +# use), and '--verbose' and the func_verbose function to allow your script +# to display verbose messages only when your user has specified +# '--verbose'. +# +# After sourcing this file, you can plug processing for additional +# options by amending the variables from the 'Configuration' section +# below, and following the instructions in the 'Option parsing' +# section further down. + +## -------------- ## +## Configuration. ## +## -------------- ## + +# You should override these variables in your script after sourcing this +# file so that they reflect the customisations you have added to the +# option parser. + +# The usage line for option parsing errors and the start of '-h' and +# '--help' output messages. You can embed shell variables for delayed +# expansion at the time the message is displayed, but you will need to +# quote other shell meta-characters carefully to prevent them being +# expanded when the contents are evaled. +usage='$progpath [OPTION]...' + +# Short help message in response to '-h' and '--help'. Add to this or +# override it after sourcing this library to reflect the full set of +# options your script accepts. +usage_message="\ + --debug enable verbose shell tracing + -W, --warnings=CATEGORY + report the warnings falling in CATEGORY [all] + -v, --verbose verbosely report processing + --version print version information and exit + -h, --help print short or long help message and exit +" + +# Additional text appended to 'usage_message' in response to '--help'. +long_help_message=" +Warning categories include: + 'all' show all warnings + 'none' turn off all the warnings + 'error' warnings are treated as fatal errors" + +# Help message printed before fatal option parsing errors. +fatal_help="Try '\$progname --help' for more information." + + + +## ------------------------- ## +## Hook function management. ## +## ------------------------- ## + +# This section contains functions for adding, removing, and running hooks +# to the main code. A hook is just a named list of of function, that can +# be run in order later on. + +# func_hookable FUNC_NAME +# ----------------------- +# Declare that FUNC_NAME will run hooks added with +# 'func_add_hook FUNC_NAME ...'. +func_hookable () +{ + $debug_cmd + + func_append hookable_fns " $1" +} + + +# func_add_hook FUNC_NAME HOOK_FUNC +# --------------------------------- +# Request that FUNC_NAME call HOOK_FUNC before it returns. FUNC_NAME must +# first have been declared "hookable" by a call to 'func_hookable'. +func_add_hook () +{ + $debug_cmd + + case " $hookable_fns " in + *" $1 "*) ;; + *) func_fatal_error "'$1' does not accept hook functions." ;; + esac + + eval func_append ${1}_hooks '" $2"' +} + + +# func_remove_hook FUNC_NAME HOOK_FUNC +# ------------------------------------ +# Remove HOOK_FUNC from the list of functions called by FUNC_NAME. +func_remove_hook () +{ + $debug_cmd + + eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`' +} + + +# func_run_hooks FUNC_NAME [ARG]... +# --------------------------------- +# Run all hook functions registered to FUNC_NAME. +# It is assumed that the list of hook functions contains nothing more +# than a whitespace-delimited list of legal shell function names, and +# no effort is wasted trying to catch shell meta-characters or preserve +# whitespace. +func_run_hooks () +{ + $debug_cmd + + case " $hookable_fns " in + *" $1 "*) ;; + *) func_fatal_error "'$1' does not support hook funcions.n" ;; + esac + + eval _G_hook_fns=\$$1_hooks; shift + + for _G_hook in $_G_hook_fns; do + eval $_G_hook '"$@"' + + # store returned options list back into positional + # parameters for next 'cmd' execution. + eval _G_hook_result=\$${_G_hook}_result + eval set dummy "$_G_hook_result"; shift + done + + func_quote_for_eval ${1+"$@"} + func_run_hooks_result=$func_quote_for_eval_result +} + + + +## --------------- ## +## Option parsing. ## +## --------------- ## + +# In order to add your own option parsing hooks, you must accept the +# full positional parameter list in your hook function, remove any +# options that you action, and then pass back the remaining unprocessed +# options in '_result', escaped suitably for +# 'eval'. Like this: +# +# my_options_prep () +# { +# $debug_cmd +# +# # Extend the existing usage message. +# usage_message=$usage_message' +# -s, --silent don'\''t print informational messages +# ' +# +# func_quote_for_eval ${1+"$@"} +# my_options_prep_result=$func_quote_for_eval_result +# } +# func_add_hook func_options_prep my_options_prep +# +# +# my_silent_option () +# { +# $debug_cmd +# +# # Note that for efficiency, we parse as many options as we can +# # recognise in a loop before passing the remainder back to the +# # caller on the first unrecognised argument we encounter. +# while test $# -gt 0; do +# opt=$1; shift +# case $opt in +# --silent|-s) opt_silent=: ;; +# # Separate non-argument short options: +# -s*) func_split_short_opt "$_G_opt" +# set dummy "$func_split_short_opt_name" \ +# "-$func_split_short_opt_arg" ${1+"$@"} +# shift +# ;; +# *) set dummy "$_G_opt" "$*"; shift; break ;; +# esac +# done +# +# func_quote_for_eval ${1+"$@"} +# my_silent_option_result=$func_quote_for_eval_result +# } +# func_add_hook func_parse_options my_silent_option +# +# +# my_option_validation () +# { +# $debug_cmd +# +# $opt_silent && $opt_verbose && func_fatal_help "\ +# '--silent' and '--verbose' options are mutually exclusive." +# +# func_quote_for_eval ${1+"$@"} +# my_option_validation_result=$func_quote_for_eval_result +# } +# func_add_hook func_validate_options my_option_validation +# +# You'll alse need to manually amend $usage_message to reflect the extra +# options you parse. It's preferable to append if you can, so that +# multiple option parsing hooks can be added safely. + + +# func_options [ARG]... +# --------------------- +# All the functions called inside func_options are hookable. See the +# individual implementations for details. +func_hookable func_options +func_options () +{ + $debug_cmd + + func_options_prep ${1+"$@"} + eval func_parse_options \ + ${func_options_prep_result+"$func_options_prep_result"} + eval func_validate_options \ + ${func_parse_options_result+"$func_parse_options_result"} + + eval func_run_hooks func_options \ + ${func_validate_options_result+"$func_validate_options_result"} + + # save modified positional parameters for caller + func_options_result=$func_run_hooks_result +} + + +# func_options_prep [ARG]... +# -------------------------- +# All initialisations required before starting the option parse loop. +# Note that when calling hook functions, we pass through the list of +# positional parameters. If a hook function modifies that list, and +# needs to propogate that back to rest of this script, then the complete +# modified list must be put in 'func_run_hooks_result' before +# returning. +func_hookable func_options_prep +func_options_prep () +{ + $debug_cmd + + # Option defaults: + opt_verbose=false + opt_warning_types= + + func_run_hooks func_options_prep ${1+"$@"} + + # save modified positional parameters for caller + func_options_prep_result=$func_run_hooks_result +} + + +# func_parse_options [ARG]... +# --------------------------- +# The main option parsing loop. +func_hookable func_parse_options +func_parse_options () +{ + $debug_cmd + + func_parse_options_result= + + # this just eases exit handling + while test $# -gt 0; do + # Defer to hook functions for initial option parsing, so they + # get priority in the event of reusing an option name. + func_run_hooks func_parse_options ${1+"$@"} + + # Adjust func_parse_options positional parameters to match + eval set dummy "$func_run_hooks_result"; shift + + # Break out of the loop if we already parsed every option. + test $# -gt 0 || break + + _G_opt=$1 + shift + case $_G_opt in + --debug|-x) debug_cmd='set -x' + func_echo "enabling shell trace mode" + $debug_cmd + ;; + + --no-warnings|--no-warning|--no-warn) + set dummy --warnings none ${1+"$@"} + shift + ;; + + --warnings|--warning|-W) + test $# = 0 && func_missing_arg $_G_opt && break + case " $warning_categories $1" in + *" $1 "*) + # trailing space prevents matching last $1 above + func_append_uniq opt_warning_types " $1" + ;; + *all) + opt_warning_types=$warning_categories + ;; + *none) + opt_warning_types=none + warning_func=: + ;; + *error) + opt_warning_types=$warning_categories + warning_func=func_fatal_error + ;; + *) + func_fatal_error \ + "unsupported warning category: '$1'" + ;; + esac + shift + ;; + + --verbose|-v) opt_verbose=: ;; + --version) func_version ;; + -\?|-h) func_usage ;; + --help) func_help ;; + + # Separate optargs to long options (plugins may need this): + --*=*) func_split_equals "$_G_opt" + set dummy "$func_split_equals_lhs" \ + "$func_split_equals_rhs" ${1+"$@"} + shift + ;; + + # Separate optargs to short options: + -W*) + func_split_short_opt "$_G_opt" + set dummy "$func_split_short_opt_name" \ + "$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + # Separate non-argument short options: + -\?*|-h*|-v*|-x*) + func_split_short_opt "$_G_opt" + set dummy "$func_split_short_opt_name" \ + "-$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + --) break ;; + -*) func_fatal_help "unrecognised option: '$_G_opt'" ;; + *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; + esac + done + + # save modified positional parameters for caller + func_quote_for_eval ${1+"$@"} + func_parse_options_result=$func_quote_for_eval_result +} + + +# func_validate_options [ARG]... +# ------------------------------ +# Perform any sanity checks on option settings and/or unconsumed +# arguments. +func_hookable func_validate_options +func_validate_options () +{ + $debug_cmd + + # Display all warnings if -W was not given. + test -n "$opt_warning_types" || opt_warning_types=" $warning_categories" + + func_run_hooks func_validate_options ${1+"$@"} + + # Bail if the options were screwed! + $exit_cmd $EXIT_FAILURE + + # save modified positional parameters for caller + func_validate_options_result=$func_run_hooks_result +} + + + +## ----------------- ## +## Helper functions. ## +## ----------------- ## + +# This section contains the helper functions used by the rest of the +# hookable option parser framework in ascii-betical order. + + +# func_fatal_help ARG... +# ---------------------- +# Echo program name prefixed message to standard error, followed by +# a help hint, and exit. +func_fatal_help () +{ + $debug_cmd + + eval \$ECHO \""Usage: $usage"\" + eval \$ECHO \""$fatal_help"\" + func_error ${1+"$@"} + exit $EXIT_FAILURE +} + + +# func_help +# --------- +# Echo long help message to standard output and exit. func_help () { - $opt_debug + $debug_cmd - $SED -n '/^# Usage:/,/# Report bugs to/ { - :print - s/^# // - s/^# *$// - s*\$progname*'$progname'* - s*\$host*'"$host"'* - s*\$SHELL*'"$SHELL"'* - s*\$LTCC*'"$LTCC"'* - s*\$LTCFLAGS*'"$LTCFLAGS"'* - s*\$LD*'"$LD"'* - s/\$with_gnu_ld/'"$with_gnu_ld"'/ - s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/ - s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/ - p - d - } - /^# .* home page:/b print - /^# General help using/b print - ' < "$progpath" - ret=$? - if test -z "$1"; then - exit $ret - fi + func_usage_message + $ECHO "$long_help_message" + exit 0 } -# func_missing_arg argname + +# func_missing_arg ARGNAME +# ------------------------ # Echo program name prefixed message to standard error and set global # exit_cmd. func_missing_arg () { - $opt_debug + $debug_cmd - func_error "missing argument for $1." + func_error "Missing argument for '$1'." exit_cmd=exit } -# func_split_short_opt shortopt +# func_split_equals STRING +# ------------------------ +# Set func_split_equals_lhs and func_split_equals_rhs shell variables after +# splitting STRING at the '=' sign. +test -z "$_G_HAVE_XSI_OPS" \ + && (eval 'x=a/b/c; + test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ + && _G_HAVE_XSI_OPS=yes + +if test yes = "$_G_HAVE_XSI_OPS" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_split_equals () + { + $debug_cmd + + func_split_equals_lhs=${1%%=*} + func_split_equals_rhs=${1#*=} + test "x$func_split_equals_lhs" = "x$1" \ + && func_split_equals_rhs= + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_split_equals () + { + $debug_cmd + + func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'` + func_split_equals_rhs= + test "x$func_split_equals_lhs" = "x$1" \ + || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'` + } +fi #func_split_equals + + +# func_split_short_opt SHORTOPT +# ----------------------------- # Set func_split_short_opt_name and func_split_short_opt_arg shell # variables after splitting SHORTOPT after the 2nd character. -func_split_short_opt () +if test yes = "$_G_HAVE_XSI_OPS" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_split_short_opt () + { + $debug_cmd + + func_split_short_opt_arg=${1#??} + func_split_short_opt_name=${1%"$func_split_short_opt_arg"} + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_split_short_opt () + { + $debug_cmd + + func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'` + func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'` + } +fi #func_split_short_opt + + +# func_usage +# ---------- +# Echo short help message to standard output and exit. +func_usage () { - my_sed_short_opt='1s/^\(..\).*$/\1/;q' - my_sed_short_rest='1s/^..\(.*\)$/\1/;q' + $debug_cmd - func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"` - func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"` -} # func_split_short_opt may be replaced by extended shell implementation + func_usage_message + $ECHO "Run '$progname --help |${PAGER-more}' for full usage" + exit 0 +} -# func_split_long_opt longopt -# Set func_split_long_opt_name and func_split_long_opt_arg shell -# variables after splitting LONGOPT at the `=' sign. -func_split_long_opt () +# func_usage_message +# ------------------ +# Echo short help message to standard output. +func_usage_message () { - my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q' - my_sed_long_arg='1s/^--[^=]*=//' + $debug_cmd - func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"` - func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"` -} # func_split_long_opt may be replaced by extended shell implementation - -exit_cmd=: + eval \$ECHO \""Usage: $usage"\" + echo + $SED -n 's|^# || + /^Written by/{ + x;p;x + } + h + /^Written by/q' < "$progpath" + echo + eval \$ECHO \""$usage_message"\" +} - - - -magic="%%%MAGIC variable%%%" -magic_exe="%%%MAGIC EXE variable%%%" - -# Global variables. -nonopt= -preserve_args= -lo2o="s/\\.lo\$/.${objext}/" -o2lo="s/\\.${objext}\$/.lo/" -extracted_archives= -extracted_serial=0 - -# If this variable is set in any of the actions, the command in it -# will be execed at the end. This prevents here-documents from being -# left over by shells. -exec_cmd= - -# func_append var value -# Append VALUE to the end of shell variable VAR. -func_append () +# func_version +# ------------ +# Echo version message to standard output and exit. +func_version () { - eval "${1}=\$${1}\${2}" -} # func_append may be replaced by extended shell implementation + $debug_cmd -# func_append_quoted var value -# Quote VALUE and append to the end of shell variable VAR, separated -# by a space. -func_append_quoted () + printf '%s\n' "$progname $scriptversion" + $SED -n ' + /(C)/!b go + :more + /\./!{ + N + s|\n# | | + b more + } + :go + /^# Written by /,/# warranty; / { + s|^# || + s|^# *$|| + s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2| + p + } + /^# Written by / { + s|^# || + p + } + /^warranty; /q' < "$progpath" + + exit $? +} + + +# Local variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" +# time-stamp-time-zone: "UTC" +# End: + +# Set a version string. +scriptversion='(GNU libtool) 2.4.6' + + +# func_echo ARG... +# ---------------- +# Libtool also displays the current mode in messages, so override +# funclib.sh func_echo with this custom definition. +func_echo () { - func_quote_for_eval "${2}" - eval "${1}=\$${1}\\ \$func_quote_for_eval_result" -} # func_append_quoted may be replaced by extended shell implementation + $debug_cmd + + _G_message=$* + + func_echo_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_IFS + $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line" + done + IFS=$func_echo_IFS +} -# func_arith arithmetic-term... -func_arith () +# func_warning ARG... +# ------------------- +# Libtool warnings are not categorized, so override funclib.sh +# func_warning with this simpler definition. +func_warning () { - func_arith_result=`expr "${@}"` -} # func_arith may be replaced by extended shell implementation + $debug_cmd + + $warning_func ${1+"$@"} +} -# func_len string -# STRING may not start with a hyphen. -func_len () +## ---------------- ## +## Options parsing. ## +## ---------------- ## + +# Hook in the functions to make sure our own options are parsed during +# the option parsing loop. + +usage='$progpath [OPTION]... [MODE-ARG]...' + +# Short help message in response to '-h'. +usage_message="Options: + --config show all configuration variables + --debug enable verbose shell tracing + -n, --dry-run display commands without modifying any files + --features display basic configuration information and exit + --mode=MODE use operation mode MODE + --no-warnings equivalent to '-Wnone' + --preserve-dup-deps don't remove duplicate dependency libraries + --quiet, --silent don't print informational messages + --tag=TAG use configuration variables from tag TAG + -v, --verbose print more informational messages than default + --version print version information + -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] + -h, --help, --help-all print short, long, or detailed help message +" + +# Additional text appended to 'usage_message' in response to '--help'. +func_help () { - func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len` -} # func_len may be replaced by extended shell implementation + $debug_cmd + + func_usage_message + $ECHO "$long_help_message + +MODE must be one of the following: + + clean remove files from the build directory + compile compile a source file into a libtool object + execute automatically set library path, then run a program + finish complete the installation of libtool libraries + install install libraries or executables + link create a library or an executable + uninstall remove libraries from an installed directory + +MODE-ARGS vary depending on the MODE. When passed as first option, +'--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that. +Try '$progname --help --mode=MODE' for a more detailed description of MODE. + +When reporting a bug, please describe a test case to reproduce it and +include the following information: + + host-triplet: $host + shell: $SHELL + compiler: $LTCC + compiler flags: $LTCFLAGS + linker: $LD (gnu? $with_gnu_ld) + version: $progname (GNU libtool) 2.4.6 + automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q` + autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q` + +Report bugs to . +GNU libtool home page: . +General help using GNU software: ." + exit 0 +} -# func_lo2o object -func_lo2o () -{ - func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` -} # func_lo2o may be replaced by extended shell implementation +# func_lo2o OBJECT-NAME +# --------------------- +# Transform OBJECT-NAME from a '.lo' suffix to the platform specific +# object suffix. + +lo2o=s/\\.lo\$/.$objext/ +o2lo=s/\\.$objext\$/.lo/ + +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_lo2o () + { + case $1 in + *.lo) func_lo2o_result=${1%.lo}.$objext ;; + * ) func_lo2o_result=$1 ;; + esac + }' + + # func_xform LIBOBJ-OR-SOURCE + # --------------------------- + # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise) + # suffix to a '.lo' libtool-object suffix. + eval 'func_xform () + { + func_xform_result=${1%.*}.lo + }' +else + # ...otherwise fall back to using sed. + func_lo2o () + { + func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"` + } + + func_xform () + { + func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'` + } +fi -# func_xform libobj-or-source -func_xform () -{ - func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` -} # func_xform may be replaced by extended shell implementation - - -# func_fatal_configuration arg... +# func_fatal_configuration ARG... +# ------------------------------- # Echo program name prefixed message to standard error, followed by # a configuration failure hint, and exit. func_fatal_configuration () { - func_error ${1+"$@"} - func_error "See the $PACKAGE documentation for more information." - func_fatal_error "Fatal configuration error." + func_fatal_error ${1+"$@"} \ + "See the $PACKAGE documentation for more information." \ + "Fatal configuration error." } # func_config +# ----------- # Display the configuration for all the tags in this script. func_config () { @@ -915,17 +2149,19 @@ func_config () exit $? } + # func_features +# ------------- # Display the features supported by this script. func_features () { echo "host: $host" - if test "$build_libtool_libs" = yes; then + if test yes = "$build_libtool_libs"; then echo "enable shared libraries" else echo "disable shared libraries" fi - if test "$build_old_libs" = yes; then + if test yes = "$build_old_libs"; then echo "enable static libraries" else echo "disable static libraries" @@ -934,314 +2170,350 @@ func_features () exit $? } -# func_enable_tag tagname + +# func_enable_tag TAGNAME +# ----------------------- # Verify that TAGNAME is valid, and either flag an error and exit, or # enable the TAGNAME tag. We also add TAGNAME to the global $taglist # variable here. func_enable_tag () { - # Global variable: - tagname="$1" + # Global variable: + tagname=$1 - re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" - re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" - sed_extractcf="/$re_begincf/,/$re_endcf/p" + re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" + re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" + sed_extractcf=/$re_begincf/,/$re_endcf/p - # Validate tagname. - case $tagname in - *[!-_A-Za-z0-9,/]*) - func_fatal_error "invalid tag name: $tagname" - ;; - esac + # Validate tagname. + case $tagname in + *[!-_A-Za-z0-9,/]*) + func_fatal_error "invalid tag name: $tagname" + ;; + esac - # Don't test for the "default" C tag, as we know it's - # there but not specially marked. - case $tagname in - CC) ;; + # Don't test for the "default" C tag, as we know it's + # there but not specially marked. + case $tagname in + CC) ;; *) - if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then - taglist="$taglist $tagname" + if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then + taglist="$taglist $tagname" - # Evaluate the configuration. Be careful to quote the path - # and the sed script, to avoid splitting on whitespace, but - # also don't use non-portable quotes within backquotes within - # quotes we have to do it in 2 steps: - extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` - eval "$extractedcf" - else - func_error "ignoring unknown tag $tagname" - fi - ;; - esac + # Evaluate the configuration. Be careful to quote the path + # and the sed script, to avoid splitting on whitespace, but + # also don't use non-portable quotes within backquotes within + # quotes we have to do it in 2 steps: + extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` + eval "$extractedcf" + else + func_error "ignoring unknown tag $tagname" + fi + ;; + esac } + # func_check_version_match +# ------------------------ # Ensure that we are using m4 macros, and libtool script from the same # release of libtool. func_check_version_match () { - if test "$package_revision" != "$macro_revision"; then - if test "$VERSION" != "$macro_version"; then - if test -z "$macro_version"; then - cat >&2 <<_LT_EOF + if test "$package_revision" != "$macro_revision"; then + if test "$VERSION" != "$macro_version"; then + if test -z "$macro_version"; then + cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from an older release. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF - else - cat >&2 <<_LT_EOF + else + cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from $PACKAGE $macro_version. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF - fi - else - cat >&2 <<_LT_EOF + fi + else + cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, $progname: but the definition of this LT_INIT comes from revision $macro_revision. $progname: You should recreate aclocal.m4 with macros from revision $package_revision $progname: of $PACKAGE $VERSION and run autoconf again. _LT_EOF - fi + fi - exit $EXIT_MISMATCH - fi + exit $EXIT_MISMATCH + fi } -# Shorthand for --mode=foo, only valid as the first argument -case $1 in -clean|clea|cle|cl) - shift; set dummy --mode clean ${1+"$@"}; shift - ;; -compile|compil|compi|comp|com|co|c) - shift; set dummy --mode compile ${1+"$@"}; shift - ;; -execute|execut|execu|exec|exe|ex|e) - shift; set dummy --mode execute ${1+"$@"}; shift - ;; -finish|finis|fini|fin|fi|f) - shift; set dummy --mode finish ${1+"$@"}; shift - ;; -install|instal|insta|inst|ins|in|i) - shift; set dummy --mode install ${1+"$@"}; shift - ;; -link|lin|li|l) - shift; set dummy --mode link ${1+"$@"}; shift - ;; -uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) - shift; set dummy --mode uninstall ${1+"$@"}; shift - ;; -esac - - - -# Option defaults: -opt_debug=: -opt_dry_run=false -opt_config=false -opt_preserve_dup_deps=false -opt_features=false -opt_finish=false -opt_help=false -opt_help_all=false -opt_silent=: -opt_warning=: -opt_verbose=: -opt_silent=false -opt_verbose=false - - -# Parse options once, thoroughly. This comes as soon as possible in the -# script to make things like `--version' happen as quickly as we can. +# libtool_options_prep [ARG]... +# ----------------------------- +# Preparation for options parsed by libtool. +libtool_options_prep () { - # this just eases exit handling - while test $# -gt 0; do - opt="$1" - shift - case $opt in - --debug|-x) opt_debug='set -x' - func_echo "enabling shell trace mode" - $opt_debug - ;; - --dry-run|--dryrun|-n) - opt_dry_run=: - ;; - --config) - opt_config=: -func_config - ;; - --dlopen|-dlopen) - optarg="$1" - opt_dlopen="${opt_dlopen+$opt_dlopen -}$optarg" - shift - ;; - --preserve-dup-deps) - opt_preserve_dup_deps=: - ;; - --features) - opt_features=: -func_features - ;; - --finish) - opt_finish=: -set dummy --mode finish ${1+"$@"}; shift - ;; - --help) - opt_help=: - ;; - --help-all) - opt_help_all=: -opt_help=': help-all' - ;; - --mode) - test $# = 0 && func_missing_arg $opt && break - optarg="$1" - opt_mode="$optarg" -case $optarg in - # Valid mode arguments: - clean|compile|execute|finish|install|link|relink|uninstall) ;; + $debug_mode - # Catch anything else as an error - *) func_error "invalid argument for $opt" - exit_cmd=exit - break - ;; -esac - shift - ;; - --no-silent|--no-quiet) - opt_silent=false -func_append preserve_args " $opt" - ;; - --no-warning|--no-warn) - opt_warning=false -func_append preserve_args " $opt" - ;; - --no-verbose) - opt_verbose=false -func_append preserve_args " $opt" - ;; - --silent|--quiet) - opt_silent=: -func_append preserve_args " $opt" - opt_verbose=false - ;; - --verbose|-v) - opt_verbose=: -func_append preserve_args " $opt" -opt_silent=false - ;; - --tag) - test $# = 0 && func_missing_arg $opt && break - optarg="$1" - opt_tag="$optarg" -func_append preserve_args " $opt $optarg" -func_enable_tag "$optarg" - shift - ;; + # Option defaults: + opt_config=false + opt_dlopen= + opt_dry_run=false + opt_help=false + opt_mode= + opt_preserve_dup_deps=false + opt_quiet=false - -\?|-h) func_usage ;; - --help) func_help ;; - --version) func_version ;; + nonopt= + preserve_args= - # Separate optargs to long options: - --*=*) - func_split_long_opt "$opt" - set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"} - shift - ;; - - # Separate non-argument short options: - -\?*|-h*|-n*|-v*) - func_split_short_opt "$opt" - set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"} - shift - ;; - - --) break ;; - -*) func_fatal_help "unrecognized option \`$opt'" ;; - *) set dummy "$opt" ${1+"$@"}; shift; break ;; + # Shorthand for --mode=foo, only valid as the first argument + case $1 in + clean|clea|cle|cl) + shift; set dummy --mode clean ${1+"$@"}; shift + ;; + compile|compil|compi|comp|com|co|c) + shift; set dummy --mode compile ${1+"$@"}; shift + ;; + execute|execut|execu|exec|exe|ex|e) + shift; set dummy --mode execute ${1+"$@"}; shift + ;; + finish|finis|fini|fin|fi|f) + shift; set dummy --mode finish ${1+"$@"}; shift + ;; + install|instal|insta|inst|ins|in|i) + shift; set dummy --mode install ${1+"$@"}; shift + ;; + link|lin|li|l) + shift; set dummy --mode link ${1+"$@"}; shift + ;; + uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) + shift; set dummy --mode uninstall ${1+"$@"}; shift + ;; esac - done - # Validate options: - - # save first non-option argument - if test "$#" -gt 0; then - nonopt="$opt" - shift - fi - - # preserve --debug - test "$opt_debug" = : || func_append preserve_args " --debug" - - case $host in - *cygwin* | *mingw* | *pw32* | *cegcc*) - # don't eliminate duplications in $postdeps and $predeps - opt_duplicate_compiler_generated_deps=: - ;; - *) - opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps - ;; - esac - - $opt_help || { - # Sanity checks first: - func_check_version_match - - if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then - func_fatal_configuration "not configured to build any kind of library" - fi - - # Darwin sucks - eval std_shrext=\"$shrext_cmds\" - - # Only execute mode is allowed to have -dlopen flags. - if test -n "$opt_dlopen" && test "$opt_mode" != execute; then - func_error "unrecognized option \`-dlopen'" - $ECHO "$help" 1>&2 - exit $EXIT_FAILURE - fi - - # Change the help message to a mode-specific one. - generic_help="$help" - help="Try \`$progname --help --mode=$opt_mode' for more information." - } - - - # Bail if the options were screwed - $exit_cmd $EXIT_FAILURE + # Pass back the list of options. + func_quote_for_eval ${1+"$@"} + libtool_options_prep_result=$func_quote_for_eval_result } +func_add_hook func_options_prep libtool_options_prep +# libtool_parse_options [ARG]... +# --------------------------------- +# Provide handling for libtool specific options. +libtool_parse_options () +{ + $debug_cmd + + # Perform our own loop to consume as many options as possible in + # each iteration. + while test $# -gt 0; do + _G_opt=$1 + shift + case $_G_opt in + --dry-run|--dryrun|-n) + opt_dry_run=: + ;; + + --config) func_config ;; + + --dlopen|-dlopen) + opt_dlopen="${opt_dlopen+$opt_dlopen +}$1" + shift + ;; + + --preserve-dup-deps) + opt_preserve_dup_deps=: ;; + + --features) func_features ;; + + --finish) set dummy --mode finish ${1+"$@"}; shift ;; + + --help) opt_help=: ;; + + --help-all) opt_help=': help-all' ;; + + --mode) test $# = 0 && func_missing_arg $_G_opt && break + opt_mode=$1 + case $1 in + # Valid mode arguments: + clean|compile|execute|finish|install|link|relink|uninstall) ;; + + # Catch anything else as an error + *) func_error "invalid argument for $_G_opt" + exit_cmd=exit + break + ;; + esac + shift + ;; + + --no-silent|--no-quiet) + opt_quiet=false + func_append preserve_args " $_G_opt" + ;; + + --no-warnings|--no-warning|--no-warn) + opt_warning=false + func_append preserve_args " $_G_opt" + ;; + + --no-verbose) + opt_verbose=false + func_append preserve_args " $_G_opt" + ;; + + --silent|--quiet) + opt_quiet=: + opt_verbose=false + func_append preserve_args " $_G_opt" + ;; + + --tag) test $# = 0 && func_missing_arg $_G_opt && break + opt_tag=$1 + func_append preserve_args " $_G_opt $1" + func_enable_tag "$1" + shift + ;; + + --verbose|-v) opt_quiet=false + opt_verbose=: + func_append preserve_args " $_G_opt" + ;; + + # An option not handled by this hook function: + *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; + esac + done + + + # save modified positional parameters for caller + func_quote_for_eval ${1+"$@"} + libtool_parse_options_result=$func_quote_for_eval_result +} +func_add_hook func_parse_options libtool_parse_options + + + +# libtool_validate_options [ARG]... +# --------------------------------- +# Perform any sanity checks on option settings and/or unconsumed +# arguments. +libtool_validate_options () +{ + # save first non-option argument + if test 0 -lt $#; then + nonopt=$1 + shift + fi + + # preserve --debug + test : = "$debug_cmd" || func_append preserve_args " --debug" + + case $host in + # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452 + # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788 + *cygwin* | *mingw* | *windows* | *pw32* | *cegcc* | *solaris2* | *os2*) + # don't eliminate duplications in $postdeps and $predeps + opt_duplicate_compiler_generated_deps=: + ;; + *) + opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps + ;; + esac + + $opt_help || { + # Sanity checks first: + func_check_version_match + + test yes != "$build_libtool_libs" \ + && test yes != "$build_old_libs" \ + && func_fatal_configuration "not configured to build any kind of library" + + # Darwin sucks + eval std_shrext=\"$shrext_cmds\" + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$opt_dlopen" && test execute != "$opt_mode"; then + func_error "unrecognized option '-dlopen'" + $ECHO "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Change the help message to a mode-specific one. + generic_help=$help + help="Try '$progname --help --mode=$opt_mode' for more information." + } + + # Pass back the unparsed argument list + func_quote_for_eval ${1+"$@"} + libtool_validate_options_result=$func_quote_for_eval_result +} +func_add_hook func_validate_options libtool_validate_options + + +# Process options as early as possible so that --help and --version +# can return quickly. +func_options ${1+"$@"} +eval set dummy "$func_options_result"; shift + ## ----------- ## ## Main. ## ## ----------- ## +magic='%%%MAGIC variable%%%' +magic_exe='%%%MAGIC EXE variable%%%' + +# Global variables. +extracted_archives= +extracted_serial=0 + +# If this variable is set in any of the actions, the command in it +# will be execed at the end. This prevents here-documents from being +# left over by shells. +exec_cmd= + + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' +} + +# func_generated_by_libtool +# True iff stdin has been generated by Libtool. This function is only +# a basic sanity check; it will hardly flush out determined imposters. +func_generated_by_libtool_p () +{ + $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 +} + # func_lalib_p file -# True iff FILE is a libtool `.la' library or `.lo' object file. +# True iff FILE is a libtool '.la' library or '.lo' object file. # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_lalib_p () { test -f "$1" && - $SED -e 4q "$1" 2>/dev/null \ - | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 + $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p } # func_lalib_unsafe_p file -# True iff FILE is a libtool `.la' library or `.lo' object file. +# True iff FILE is a libtool '.la' library or '.lo' object file. # This function implements the same check as func_lalib_p without # resorting to external programs. To this end, it redirects stdin and # closes it afterwards, without saving the original file descriptor. # As a safety measure, use it only where a negative result would be -# fatal anyway. Works if `file' does not exist. +# fatal anyway. Works if 'file' does not exist. func_lalib_unsafe_p () { lalib_p=no @@ -1249,13 +2521,13 @@ func_lalib_unsafe_p () for lalib_p_l in 1 2 3 4 do read lalib_p_line - case "$lalib_p_line" in + case $lalib_p_line in \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; esac done exec 0<&5 5<&- fi - test "$lalib_p" = yes + test yes = "$lalib_p" } # func_ltwrapper_script_p file @@ -1264,7 +2536,8 @@ func_lalib_unsafe_p () # determined imposters. func_ltwrapper_script_p () { - func_lalib_p "$1" + test -f "$1" && + $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p } # func_ltwrapper_executable_p file @@ -1289,7 +2562,7 @@ func_ltwrapper_scriptname () { func_dirname_and_basename "$1" "" "." func_stripname '' '.exe' "$func_basename_result" - func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" + func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper } # func_ltwrapper_p file @@ -1308,11 +2581,13 @@ func_ltwrapper_p () # FAIL_CMD may read-access the current command in variable CMD! func_execute_cmds () { - $opt_debug + $debug_cmd + save_ifs=$IFS; IFS='~' for cmd in $1; do - IFS=$save_ifs + IFS=$sp$nl eval cmd=\"$cmd\" + IFS=$save_ifs func_show_eval "$cmd" "${2-:}" done IFS=$save_ifs @@ -1324,10 +2599,11 @@ func_execute_cmds () # Note that it is not necessary on cygwin/mingw to append a dot to # FILE even if both FILE and FILE.exe exist: automatic-append-.exe # behavior happens only for exec(3), not for open(2)! Also, sourcing -# `FILE.' does not work on cygwin managed mounts. +# 'FILE.' does not work on cygwin managed mounts. func_source () { - $opt_debug + $debug_cmd + case $1 in */* | *\\*) . "$1" ;; *) . "./$1" ;; @@ -1354,10 +2630,10 @@ func_resolve_sysroot () # store the result into func_replace_sysroot_result. func_replace_sysroot () { - case "$lt_sysroot:$1" in + case $lt_sysroot:$1 in ?*:"$lt_sysroot"*) func_stripname "$lt_sysroot" '' "$1" - func_replace_sysroot_result="=$func_stripname_result" + func_replace_sysroot_result='='$func_stripname_result ;; *) # Including no sysroot. @@ -1374,7 +2650,8 @@ func_replace_sysroot () # arg is usually of the form 'gcc ...' func_infer_tag () { - $opt_debug + $debug_cmd + if test -n "$available_tags" && test -z "$tagname"; then CC_quoted= for arg in $CC; do @@ -1393,7 +2670,7 @@ func_infer_tag () for z in $available_tags; do if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then # Evaluate the configuration. - eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" CC_quoted= for arg in $CC; do # Double-quote args containing other shell metacharacters. @@ -1418,7 +2695,7 @@ func_infer_tag () # line option must be used. if test -z "$tagname"; then func_echo "unable to infer tagged configuration" - func_fatal_error "specify a tag with \`--tag'" + func_fatal_error "specify a tag with '--tag'" # else # func_verbose "using $tagname tagged configuration" fi @@ -1434,15 +2711,15 @@ func_infer_tag () # but don't create it if we're doing a dry run. func_write_libtool_object () { - write_libobj=${1} - if test "$build_libtool_libs" = yes; then - write_lobj=\'${2}\' + write_libobj=$1 + if test yes = "$build_libtool_libs"; then + write_lobj=\'$2\' else write_lobj=none fi - if test "$build_old_libs" = yes; then - write_oldobj=\'${3}\' + if test yes = "$build_old_libs"; then + write_oldobj=\'$3\' else write_oldobj=none fi @@ -1450,7 +2727,7 @@ func_write_libtool_object () $opt_dry_run || { cat >${write_libobj}T </dev/null` - if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then + if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | - $SED -e "$lt_sed_naive_backslashify"` + $SED -e "$sed_naive_backslashify"` else func_convert_core_file_wine_to_w32_result= fi @@ -1504,9 +2782,10 @@ func_convert_core_file_wine_to_w32 () # func_convert_core_path_wine_to_w32 ARG # Helper function used by path conversion functions when $build is *nix, and -# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly -# configured wine environment available, with the winepath program in $build's -# $PATH. Assumes ARG has no leading or trailing path separator characters. +# $host is mingw, windows, cygwin, or some other w32 environment. Relies on a +# correctly configured wine environment available, with the winepath program +# in $build's $PATH. Assumes ARG has no leading or trailing path separator +# characters. # # ARG is path to be converted from $build format to win32. # Result is available in $func_convert_core_path_wine_to_w32_result. @@ -1514,18 +2793,19 @@ func_convert_core_file_wine_to_w32 () # are convertible, then the result may be empty. func_convert_core_path_wine_to_w32 () { - $opt_debug + $debug_cmd + # unfortunately, winepath doesn't convert paths, only file names - func_convert_core_path_wine_to_w32_result="" + func_convert_core_path_wine_to_w32_result= if test -n "$1"; then oldIFS=$IFS IFS=: for func_convert_core_path_wine_to_w32_f in $1; do IFS=$oldIFS func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" - if test -n "$func_convert_core_file_wine_to_w32_result" ; then + if test -n "$func_convert_core_file_wine_to_w32_result"; then if test -z "$func_convert_core_path_wine_to_w32_result"; then - func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result" + func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result else func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" fi @@ -1554,7 +2834,8 @@ func_convert_core_path_wine_to_w32 () # environment variable; do not put it in $PATH. func_cygpath () { - $opt_debug + $debug_cmd + if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` if test "$?" -ne 0; then @@ -1563,7 +2844,7 @@ func_cygpath () fi else func_cygpath_result= - func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'" + func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'" fi } #end: func_cygpath @@ -1574,10 +2855,11 @@ func_cygpath () # result in func_convert_core_msys_to_w32_result. func_convert_core_msys_to_w32 () { - $opt_debug + $debug_cmd + # awkward: cmd appends spaces to result func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | - $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"` + $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"` } #end: func_convert_core_msys_to_w32 @@ -1588,13 +2870,14 @@ func_convert_core_msys_to_w32 () # func_to_host_file_result to ARG1). func_convert_file_check () { - $opt_debug - if test -z "$2" && test -n "$1" ; then + $debug_cmd + + if test -z "$2" && test -n "$1"; then func_error "Could not determine host file name corresponding to" - func_error " \`$1'" + func_error " '$1'" func_error "Continuing, but uninstalled executables may not work." # Fallback: - func_to_host_file_result="$1" + func_to_host_file_result=$1 fi } # end func_convert_file_check @@ -1606,10 +2889,11 @@ func_convert_file_check () # func_to_host_file_result to a simplistic fallback value (see below). func_convert_path_check () { - $opt_debug + $debug_cmd + if test -z "$4" && test -n "$3"; then func_error "Could not determine the host path corresponding to" - func_error " \`$3'" + func_error " '$3'" func_error "Continuing, but uninstalled executables may not work." # Fallback. This is a deliberately simplistic "conversion" and # should not be "improved". See libtool.info. @@ -1618,7 +2902,7 @@ func_convert_path_check () func_to_host_path_result=`echo "$3" | $SED -e "$lt_replace_pathsep_chars"` else - func_to_host_path_result="$3" + func_to_host_path_result=$3 fi fi } @@ -1630,9 +2914,10 @@ func_convert_path_check () # and appending REPL if ORIG matches BACKPAT. func_convert_path_front_back_pathsep () { - $opt_debug + $debug_cmd + case $4 in - $1 ) func_to_host_path_result="$3$func_to_host_path_result" + $1 ) func_to_host_path_result=$3$func_to_host_path_result ;; esac case $4 in @@ -1646,7 +2931,7 @@ func_convert_path_front_back_pathsep () ################################################## # $build to $host FILE NAME CONVERSION FUNCTIONS # ################################################## -# invoked via `$to_host_file_cmd ARG' +# invoked via '$to_host_file_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # Result will be available in $func_to_host_file_result. @@ -1657,7 +2942,8 @@ func_convert_path_front_back_pathsep () # in func_to_host_file_result. func_to_host_file () { - $opt_debug + $debug_cmd + $to_host_file_cmd "$1" } # end func_to_host_file @@ -1669,7 +2955,8 @@ func_to_host_file () # in (the comma separated) LAZY, no conversion takes place. func_to_tool_file () { - $opt_debug + $debug_cmd + case ,$2, in *,"$to_tool_file_cmd",*) func_to_tool_file_result=$1 @@ -1687,7 +2974,7 @@ func_to_tool_file () # Copy ARG to func_to_host_file_result. func_convert_file_noop () { - func_to_host_file_result="$1" + func_to_host_file_result=$1 } # end func_convert_file_noop @@ -1698,11 +2985,12 @@ func_convert_file_noop () # func_to_host_file_result. func_convert_file_msys_to_w32 () { - $opt_debug - func_to_host_file_result="$1" + $debug_cmd + + func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_msys_to_w32 "$1" - func_to_host_file_result="$func_convert_core_msys_to_w32_result" + func_to_host_file_result=$func_convert_core_msys_to_w32_result fi func_convert_file_check "$1" "$func_to_host_file_result" } @@ -1714,8 +3002,9 @@ func_convert_file_msys_to_w32 () # func_to_host_file_result. func_convert_file_cygwin_to_w32 () { - $opt_debug - func_to_host_file_result="$1" + $debug_cmd + + func_to_host_file_result=$1 if test -n "$1"; then # because $build is cygwin, we call "the" cygpath in $PATH; no need to use # LT_CYGPATH in this case. @@ -1731,11 +3020,12 @@ func_convert_file_cygwin_to_w32 () # and a working winepath. Returns result in func_to_host_file_result. func_convert_file_nix_to_w32 () { - $opt_debug - func_to_host_file_result="$1" + $debug_cmd + + func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_file_wine_to_w32 "$1" - func_to_host_file_result="$func_convert_core_file_wine_to_w32_result" + func_to_host_file_result=$func_convert_core_file_wine_to_w32_result fi func_convert_file_check "$1" "$func_to_host_file_result" } @@ -1747,12 +3037,13 @@ func_convert_file_nix_to_w32 () # Returns result in func_to_host_file_result. func_convert_file_msys_to_cygwin () { - $opt_debug - func_to_host_file_result="$1" + $debug_cmd + + func_to_host_file_result=$1 if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_cygpath -u "$func_convert_core_msys_to_w32_result" - func_to_host_file_result="$func_cygpath_result" + func_to_host_file_result=$func_cygpath_result fi func_convert_file_check "$1" "$func_to_host_file_result" } @@ -1765,13 +3056,14 @@ func_convert_file_msys_to_cygwin () # in func_to_host_file_result. func_convert_file_nix_to_cygwin () { - $opt_debug - func_to_host_file_result="$1" + $debug_cmd + + func_to_host_file_result=$1 if test -n "$1"; then # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. func_convert_core_file_wine_to_w32 "$1" func_cygpath -u "$func_convert_core_file_wine_to_w32_result" - func_to_host_file_result="$func_cygpath_result" + func_to_host_file_result=$func_cygpath_result fi func_convert_file_check "$1" "$func_to_host_file_result" } @@ -1781,7 +3073,7 @@ func_convert_file_nix_to_cygwin () ############################################# # $build to $host PATH CONVERSION FUNCTIONS # ############################################# -# invoked via `$to_host_path_cmd ARG' +# invoked via '$to_host_path_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # The result will be available in $func_to_host_path_result. @@ -1805,10 +3097,11 @@ func_convert_file_nix_to_cygwin () to_host_path_cmd= func_init_to_host_path_cmd () { - $opt_debug + $debug_cmd + if test -z "$to_host_path_cmd"; then func_stripname 'func_convert_file_' '' "$to_host_file_cmd" - to_host_path_cmd="func_convert_path_${func_stripname_result}" + to_host_path_cmd=func_convert_path_$func_stripname_result fi } @@ -1818,7 +3111,8 @@ func_init_to_host_path_cmd () # in func_to_host_path_result. func_to_host_path () { - $opt_debug + $debug_cmd + func_init_to_host_path_cmd $to_host_path_cmd "$1" } @@ -1829,7 +3123,7 @@ func_to_host_path () # Copy ARG to func_to_host_path_result. func_convert_path_noop () { - func_to_host_path_result="$1" + func_to_host_path_result=$1 } # end func_convert_path_noop @@ -1840,8 +3134,9 @@ func_convert_path_noop () # func_to_host_path_result. func_convert_path_msys_to_w32 () { - $opt_debug - func_to_host_path_result="$1" + $debug_cmd + + func_to_host_path_result=$1 if test -n "$1"; then # Remove leading and trailing path separator characters from ARG. MSYS # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; @@ -1849,7 +3144,7 @@ func_convert_path_msys_to_w32 () func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" - func_to_host_path_result="$func_convert_core_msys_to_w32_result" + func_to_host_path_result=$func_convert_core_msys_to_w32_result func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" @@ -1863,8 +3158,9 @@ func_convert_path_msys_to_w32 () # func_to_host_file_result. func_convert_path_cygwin_to_w32 () { - $opt_debug - func_to_host_path_result="$1" + $debug_cmd + + func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" @@ -1883,14 +3179,15 @@ func_convert_path_cygwin_to_w32 () # a working winepath. Returns result in func_to_host_file_result. func_convert_path_nix_to_w32 () { - $opt_debug - func_to_host_path_result="$1" + $debug_cmd + + func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" - func_to_host_path_result="$func_convert_core_path_wine_to_w32_result" + func_to_host_path_result=$func_convert_core_path_wine_to_w32_result func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" @@ -1904,15 +3201,16 @@ func_convert_path_nix_to_w32 () # Returns result in func_to_host_file_result. func_convert_path_msys_to_cygwin () { - $opt_debug - func_to_host_path_result="$1" + $debug_cmd + + func_to_host_path_result=$1 if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_msys_to_w32_result" - func_to_host_path_result="$func_cygpath_result" + func_to_host_path_result=$func_cygpath_result func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" @@ -1927,8 +3225,9 @@ func_convert_path_msys_to_cygwin () # func_to_host_file_result. func_convert_path_nix_to_cygwin () { - $opt_debug - func_to_host_path_result="$1" + $debug_cmd + + func_to_host_path_result=$1 if test -n "$1"; then # Remove leading and trailing path separator characters from # ARG. msys behavior is inconsistent here, cygpath turns them @@ -1937,7 +3236,7 @@ func_convert_path_nix_to_cygwin () func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" - func_to_host_path_result="$func_cygpath_result" + func_to_host_path_result=$func_cygpath_result func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" @@ -1946,13 +3245,31 @@ func_convert_path_nix_to_cygwin () # end func_convert_path_nix_to_cygwin +# func_dll_def_p FILE +# True iff FILE is a Windows DLL '.def' file. +# Keep in sync with _LT_DLL_DEF_P in libtool.m4 +func_dll_def_p () +{ + $debug_cmd + + func_dll_def_p_tmp=`$SED -n \ + -e 's/^[ ]*//' \ + -e '/^\(;.*\)*$/d' \ + -e 's/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p' \ + -e q \ + "$1"` + test DEF = "$func_dll_def_p_tmp" +} + + # func_mode_compile arg... func_mode_compile () { - $opt_debug + $debug_cmd + # Get the compilation command and the source file. base_compile= - srcfile="$nonopt" # always keep a non-empty value in "srcfile" + srcfile=$nonopt # always keep a non-empty value in "srcfile" suppress_opt=yes suppress_output= arg_mode=normal @@ -1965,12 +3282,12 @@ func_mode_compile () case $arg_mode in arg ) # do not "continue". Instead, add this to base_compile - lastarg="$arg" + lastarg=$arg arg_mode=normal ;; target ) - libobj="$arg" + libobj=$arg arg_mode=normal continue ;; @@ -1980,7 +3297,7 @@ func_mode_compile () case $arg in -o) test -n "$libobj" && \ - func_fatal_error "you cannot specify \`-o' more than once" + func_fatal_error "you cannot specify '-o' more than once" arg_mode=target continue ;; @@ -2009,12 +3326,12 @@ func_mode_compile () func_stripname '-Wc,' '' "$arg" args=$func_stripname_result lastarg= - save_ifs="$IFS"; IFS=',' + save_ifs=$IFS; IFS=, for arg in $args; do - IFS="$save_ifs" + IFS=$save_ifs func_append_quoted lastarg "$arg" done - IFS="$save_ifs" + IFS=$save_ifs func_stripname ' ' '' "$lastarg" lastarg=$func_stripname_result @@ -2027,8 +3344,8 @@ func_mode_compile () # Accept the current argument as the source file. # The previous "srcfile" becomes the current argument. # - lastarg="$srcfile" - srcfile="$arg" + lastarg=$srcfile + srcfile=$arg ;; esac # case $arg ;; @@ -2043,13 +3360,13 @@ func_mode_compile () func_fatal_error "you must specify an argument for -Xcompile" ;; target) - func_fatal_error "you must specify a target with \`-o'" + func_fatal_error "you must specify a target with '-o'" ;; *) # Get the name of the library object. test -z "$libobj" && { func_basename "$srcfile" - libobj="$func_basename_result" + libobj=$func_basename_result } ;; esac @@ -2069,7 +3386,7 @@ func_mode_compile () case $libobj in *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; *) - func_fatal_error "cannot determine name of library object from \`$libobj'" + func_fatal_error "cannot determine name of library object from '$libobj'" ;; esac @@ -2078,8 +3395,8 @@ func_mode_compile () for arg in $later; do case $arg in -shared) - test "$build_libtool_libs" != yes && \ - func_fatal_configuration "can not build a shared library" + test yes = "$build_libtool_libs" \ + || func_fatal_configuration "cannot build a shared library" build_old_libs=no continue ;; @@ -2105,17 +3422,17 @@ func_mode_compile () func_quote_for_eval "$libobj" test "X$libobj" != "X$func_quote_for_eval_result" \ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ - && func_warning "libobj name \`$libobj' may not contain shell special characters." + && func_warning "libobj name '$libobj' may not contain shell special characters." func_dirname_and_basename "$obj" "/" "" - objname="$func_basename_result" - xdir="$func_dirname_result" - lobj=${xdir}$objdir/$objname + objname=$func_basename_result + xdir=$func_dirname_result + lobj=$xdir$objdir/$objname test -z "$base_compile" && \ func_fatal_help "you must specify a compilation command" # Delete any leftover library objects. - if test "$build_old_libs" = yes; then + if test yes = "$build_old_libs"; then removelist="$obj $lobj $libobj ${libobj}T" else removelist="$lobj $libobj ${libobj}T" @@ -2123,20 +3440,20 @@ func_mode_compile () # On Cygwin there's no "real" PIC flag so we must build both object types case $host_os in - cygwin* | mingw* | pw32* | os2* | cegcc*) + cygwin* | mingw* | windows* | pw32* | os2* | cegcc*) pic_mode=default ;; esac - if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then + if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then # non-PIC code in shared libraries is not supported pic_mode=default fi # Calculate the filename of the output object if compiler does # not support -o with -c - if test "$compiler_c_o" = no; then - output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext} - lockfile="$output_obj.lock" + if test no = "$compiler_c_o"; then + output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext + lockfile=$output_obj.lock else output_obj= need_locks=no @@ -2145,12 +3462,12 @@ func_mode_compile () # Lock this critical section if it is needed # We use this script file to make the link, it avoids creating a new file - if test "$need_locks" = yes; then + if test yes = "$need_locks"; then until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done - elif test "$need_locks" = warn; then + elif test warn = "$need_locks"; then if test -f "$lockfile"; then $ECHO "\ *** ERROR, $lockfile exists and contains: @@ -2158,7 +3475,7 @@ func_mode_compile () This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you +your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." @@ -2180,11 +3497,11 @@ compiler." qsrcfile=$func_quote_for_eval_result # Only build a PIC object if we are building libtool libraries. - if test "$build_libtool_libs" = yes; then + if test yes = "$build_libtool_libs"; then # Without this assignment, base_compile gets emptied. fbsd_hideous_sh_bug=$base_compile - if test "$pic_mode" != no; then + if test no != "$pic_mode"; then command="$base_compile $qsrcfile $pic_flag" else # Don't build PIC code @@ -2201,7 +3518,7 @@ compiler." func_show_eval_locale "$command" \ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' - if test "$need_locks" = warn && + if test warn = "$need_locks" && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: @@ -2212,7 +3529,7 @@ $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you +your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." @@ -2228,20 +3545,20 @@ compiler." fi # Allow error messages only from the first compilation. - if test "$suppress_opt" = yes; then + if test yes = "$suppress_opt"; then suppress_output=' >/dev/null 2>&1' fi fi # Only build a position-dependent object if we build old libraries. - if test "$build_old_libs" = yes; then - if test "$pic_mode" != yes; then + if test yes = "$build_old_libs"; then + if test yes != "$pic_mode"; then # Don't build PIC code command="$base_compile $qsrcfile$pie_flag" else command="$base_compile $qsrcfile $pic_flag" fi - if test "$compiler_c_o" = yes; then + if test yes = "$compiler_c_o"; then func_append command " -o $obj" fi @@ -2250,7 +3567,7 @@ compiler." func_show_eval_locale "$command" \ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' - if test "$need_locks" = warn && + if test warn = "$need_locks" && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: @@ -2261,7 +3578,7 @@ $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you +your compiler does not support '-c' and '-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." @@ -2281,7 +3598,7 @@ compiler." func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" # Unlock the critical section if it was locked - if test "$need_locks" != no; then + if test no != "$need_locks"; then removelist=$lockfile $RM "$lockfile" fi @@ -2291,7 +3608,7 @@ compiler." } $opt_help || { - test "$opt_mode" = compile && func_mode_compile ${1+"$@"} + test compile = "$opt_mode" && func_mode_compile ${1+"$@"} } func_mode_help () @@ -2311,7 +3628,7 @@ func_mode_help () Remove files from the build directory. RM is the name of the program to use to delete files associated with each FILE -(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed to RM. If FILE is a libtool library, object or program, all the files associated @@ -2330,16 +3647,17 @@ This mode accepts the following additional options: -no-suppress do not suppress compiler output for multiple passes -prefer-pic try to build PIC objects only -prefer-non-pic try to build non-PIC objects only - -shared do not build a \`.o' file suitable for static linking - -static only build a \`.o' file suitable for static linking - -Wc,FLAG pass FLAG directly to the compiler + -shared do not build a '.o' file suitable for static linking + -static only build a '.o' file suitable for static linking + -Wc,FLAG + -Xcompiler FLAG pass FLAG directly to the compiler -COMPILE-COMMAND is a command to be used in creating a \`standard' object file +COMPILE-COMMAND is a command to be used in creating a 'standard' object file from the given SOURCEFILE. The output file name is determined by removing the directory component from -SOURCEFILE, then substituting the C source code suffix \`.c' with the -library object suffix, \`.lo'." +SOURCEFILE, then substituting the C source code suffix '.c' with the +library object suffix, '.lo'." ;; execute) @@ -2352,7 +3670,7 @@ This mode accepts the following additional options: -dlopen FILE add the directory containing FILE to the library path -This mode sets the library path environment variable according to \`-dlopen' +This mode sets the library path environment variable according to '-dlopen' flags. If any of the ARGS are libtool executable wrappers, then they are translated @@ -2371,7 +3689,7 @@ Complete the installation of libtool libraries. Each LIBDIR is a directory that contains libtool libraries. The commands that this mode executes may require superuser privileges. Use -the \`--dry-run' option if you just want to see what would be executed." +the '--dry-run' option if you just want to see what would be executed." ;; install) @@ -2381,7 +3699,7 @@ the \`--dry-run' option if you just want to see what would be executed." Install executables or libraries. INSTALL-COMMAND is the installation command. The first component should be -either the \`install' or \`cp' program. +either the 'install' or 'cp' program. The following components of INSTALL-COMMAND are treated specially: @@ -2407,7 +3725,7 @@ The following components of LINK-COMMAND are treated specially: -avoid-version do not add a version suffix if possible -bindir BINDIR specify path to binaries directory (for systems where libraries must be found in the PATH setting at runtime) - -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlopen FILE '-dlpreopen' FILE if it cannot be dlopened at runtime -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) -export-symbols SYMFILE @@ -2421,7 +3739,8 @@ The following components of LINK-COMMAND are treated specially: -no-install link a not-installable executable -no-undefined declare that a library does not refer to external symbols -o OUTPUT-FILE create OUTPUT-FILE from the specified objects - -objectlist FILE Use a list of object files found in FILE to specify objects + -objectlist FILE use a list of object files found in FILE to specify objects + -os2dllname NAME force a short DLL name on OS/2 (no effect on other OSes) -precious-files-regex REGEX don't remove output files matching REGEX -release RELEASE specify package release information @@ -2437,24 +3756,26 @@ The following components of LINK-COMMAND are treated specially: -weak LIBNAME declare that the target provides the LIBNAME interface -Wc,FLAG -Xcompiler FLAG pass linker-specific FLAG directly to the compiler + -Wa,FLAG + -Xassembler FLAG pass linker-specific FLAG directly to the assembler -Wl,FLAG -Xlinker FLAG pass linker-specific FLAG directly to the linker -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) -All other options (arguments beginning with \`-') are ignored. +All other options (arguments beginning with '-') are ignored. -Every other argument is treated as a filename. Files ending in \`.la' are +Every other argument is treated as a filename. Files ending in '.la' are treated as uninstalled libtool libraries, other files are standard or library object files. -If the OUTPUT-FILE ends in \`.la', then a libtool library is created, -only library objects (\`.lo' files) may be specified, and \`-rpath' is +If the OUTPUT-FILE ends in '.la', then a libtool library is created, +only library objects ('.lo' files) may be specified, and '-rpath' is required, except when creating a convenience library. -If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created -using \`ar' and \`ranlib', or on Windows using \`lib'. +If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created +using 'ar' and 'ranlib', or on Windows using 'lib'. -If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file +If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file is created, otherwise an executable program is created." ;; @@ -2465,7 +3786,7 @@ is created, otherwise an executable program is created." Remove libraries from an installation directory. RM is the name of the program to use to delete files associated with each FILE -(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +(typically '/bin/rm'). RM-OPTIONS are options (such as '-f') to be passed to RM. If FILE is a libtool library, all the files associated with it are deleted. @@ -2473,17 +3794,17 @@ Otherwise, only FILE itself is deleted using RM." ;; *) - func_fatal_help "invalid operation mode \`$opt_mode'" + func_fatal_help "invalid operation mode '$opt_mode'" ;; esac echo - $ECHO "Try \`$progname --help' for more information about other modes." + $ECHO "Try '$progname --help' for more information about other modes." } # Now that we've collected a possible --mode arg, show help if necessary if $opt_help; then - if test "$opt_help" = :; then + if test : = "$opt_help"; then func_mode_help else { @@ -2491,7 +3812,7 @@ if $opt_help; then for opt_mode in compile link execute install finish uninstall clean; do func_mode_help done - } | sed -n '1p; 2,$s/^Usage:/ or: /p' + } | $SED -n '1p; 2,$s/^Usage:/ or: /p' { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do @@ -2499,7 +3820,7 @@ if $opt_help; then func_mode_help done } | - sed '1d + $SED '1d /^When reporting/,/^Report/{ H d @@ -2516,16 +3837,17 @@ fi # func_mode_execute arg... func_mode_execute () { - $opt_debug + $debug_cmd + # The first argument is the command name. - cmd="$nonopt" + cmd=$nonopt test -z "$cmd" && \ func_fatal_help "you must specify a COMMAND" # Handle -dlopen flags immediately. for file in $opt_dlopen; do test -f "$file" \ - || func_fatal_help "\`$file' is not a file" + || func_fatal_help "'$file' is not a file" dir= case $file in @@ -2535,7 +3857,7 @@ func_mode_execute () # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ - || func_fatal_help "\`$lib' is not a valid libtool archive" + || func_fatal_help "'$lib' is not a valid libtool archive" # Read the libtool library. dlname= @@ -2546,18 +3868,18 @@ func_mode_execute () if test -z "$dlname"; then # Warn if it was a shared library. test -n "$library_names" && \ - func_warning "\`$file' was not linked with \`-export-dynamic'" + func_warning "'$file' was not linked with '-export-dynamic'" continue fi func_dirname "$file" "" "." - dir="$func_dirname_result" + dir=$func_dirname_result if test -f "$dir/$objdir/$dlname"; then func_append dir "/$objdir" else if test ! -f "$dir/$dlname"; then - func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" + func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'" fi fi ;; @@ -2565,18 +3887,18 @@ func_mode_execute () *.lo) # Just add the directory containing the .lo file. func_dirname "$file" "" "." - dir="$func_dirname_result" + dir=$func_dirname_result ;; *) - func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" + func_warning "'-dlopen' is ignored for non-libtool libraries and objects" continue ;; esac # Get the absolute pathname. absdir=`cd "$dir" && pwd` - test -n "$absdir" && dir="$absdir" + test -n "$absdir" && dir=$absdir # Now add the directory to shlibpath_var. if eval "test -z \"\$$shlibpath_var\""; then @@ -2588,7 +3910,7 @@ func_mode_execute () # This variable tells wrapper scripts just to set shlibpath_var # rather than running their programs. - libtool_execute_magic="$magic" + libtool_execute_magic=$magic # Check if any of the arguments is a wrapper script. args= @@ -2601,12 +3923,12 @@ func_mode_execute () if func_ltwrapper_script_p "$file"; then func_source "$file" # Transform arg to wrapped name. - file="$progdir/$program" + file=$progdir/$program elif func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" func_source "$func_ltwrapper_scriptname_result" # Transform arg to wrapped name. - file="$progdir/$program" + file=$progdir/$program fi ;; esac @@ -2614,7 +3936,15 @@ func_mode_execute () func_append_quoted args "$file" done - if test "X$opt_dry_run" = Xfalse; then + if $opt_dry_run; then + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" + echo "export $shlibpath_var" + fi + $ECHO "$cmd$args" + exit $EXIT_SUCCESS + else if test -n "$shlibpath_var"; then # Export the shlibpath_var. eval "export $shlibpath_var" @@ -2631,25 +3961,18 @@ func_mode_execute () done # Now prepare to actually exec the command. - exec_cmd="\$cmd$args" - else - # Display what would be done. - if test -n "$shlibpath_var"; then - eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" - echo "export $shlibpath_var" - fi - $ECHO "$cmd$args" - exit $EXIT_SUCCESS + exec_cmd=\$cmd$args fi } -test "$opt_mode" = execute && func_mode_execute ${1+"$@"} +test execute = "$opt_mode" && func_mode_execute ${1+"$@"} # func_mode_finish arg... func_mode_finish () { - $opt_debug + $debug_cmd + libs= libdirs= admincmds= @@ -2663,11 +3986,11 @@ func_mode_finish () if func_lalib_unsafe_p "$opt"; then func_append libs " $opt" else - func_warning "\`$opt' is not a valid libtool archive" + func_warning "'$opt' is not a valid libtool archive" fi else - func_fatal_error "invalid argument \`$opt'" + func_fatal_error "invalid argument '$opt'" fi done @@ -2682,12 +4005,12 @@ func_mode_finish () # Remove sysroot references if $opt_dry_run; then for lib in $libs; do - echo "removing references to $lt_sysroot and \`=' prefixes from $lib" + echo "removing references to $lt_sysroot and '=' prefixes from $lib" done else tmpdir=`func_mktempdir` for lib in $libs; do - sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ + $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ > $tmpdir/tmp-la mv -f $tmpdir/tmp-la $lib done @@ -2712,7 +4035,7 @@ func_mode_finish () fi # Exit here if they wanted silent mode. - $opt_silent && exit $EXIT_SUCCESS + $opt_quiet && exit $EXIT_SUCCESS if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then echo "----------------------------------------------------------------------" @@ -2723,27 +4046,27 @@ func_mode_finish () echo echo "If you ever happen to want to link against installed libraries" echo "in a given directory, LIBDIR, you must either use libtool, and" - echo "specify the full pathname of the library, or use the \`-LLIBDIR'" + echo "specify the full pathname of the library, or use the '-LLIBDIR'" echo "flag during linking and do at least one of the following:" if test -n "$shlibpath_var"; then - echo " - add LIBDIR to the \`$shlibpath_var' environment variable" + echo " - add LIBDIR to the '$shlibpath_var' environment variable" echo " during execution" fi if test -n "$runpath_var"; then - echo " - add LIBDIR to the \`$runpath_var' environment variable" + echo " - add LIBDIR to the '$runpath_var' environment variable" echo " during linking" fi if test -n "$hardcode_libdir_flag_spec"; then libdir=LIBDIR eval flag=\"$hardcode_libdir_flag_spec\" - $ECHO " - use the \`$flag' linker flag" + $ECHO " - use the '$flag' linker flag" fi if test -n "$admincmds"; then $ECHO " - have your system administrator run these commands:$admincmds" fi if test -f /etc/ld.so.conf; then - echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + echo " - have your system administrator add LIBDIR to '/etc/ld.so.conf'" fi echo @@ -2762,18 +4085,20 @@ func_mode_finish () exit $EXIT_SUCCESS } -test "$opt_mode" = finish && func_mode_finish ${1+"$@"} +test finish = "$opt_mode" && func_mode_finish ${1+"$@"} # func_mode_install arg... func_mode_install () { - $opt_debug + $debug_cmd + # There may be an optional sh(1) argument at the beginning of # install_prog (especially on Windows NT). - if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || + if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" || # Allow the use of GNU shtool's install command. - case $nonopt in *shtool*) :;; *) false;; esac; then + case $nonopt in *shtool*) :;; *) false;; esac + then # Aesthetically quote it. func_quote_for_eval "$nonopt" install_prog="$func_quote_for_eval_result " @@ -2800,7 +4125,7 @@ func_mode_install () opts= prev= install_type= - isdir=no + isdir=false stripme= no_mode=: for arg @@ -2813,7 +4138,7 @@ func_mode_install () fi case $arg in - -d) isdir=yes ;; + -d) isdir=: ;; -f) if $install_cp; then :; else prev=$arg @@ -2831,7 +4156,7 @@ func_mode_install () *) # If the previous option needed an argument, then skip it. if test -n "$prev"; then - if test "x$prev" = x-m && test -n "$install_override_mode"; then + if test X-m = "X$prev" && test -n "$install_override_mode"; then arg2=$install_override_mode no_mode=false fi @@ -2856,7 +4181,7 @@ func_mode_install () func_fatal_help "you must specify an install program" test -n "$prev" && \ - func_fatal_help "the \`$prev' option requires an argument" + func_fatal_help "the '$prev' option requires an argument" if test -n "$install_override_mode" && $no_mode; then if $install_cp; then :; else @@ -2878,19 +4203,19 @@ func_mode_install () dest=$func_stripname_result # Check to see that the destination is a directory. - test -d "$dest" && isdir=yes - if test "$isdir" = yes; then - destdir="$dest" + test -d "$dest" && isdir=: + if $isdir; then + destdir=$dest destname= else func_dirname_and_basename "$dest" "" "." - destdir="$func_dirname_result" - destname="$func_basename_result" + destdir=$func_dirname_result + destname=$func_basename_result # Not a directory, so check to see that there is only one file specified. set dummy $files; shift test "$#" -gt 1 && \ - func_fatal_help "\`$dest' is not a directory" + func_fatal_help "'$dest' is not a directory" fi case $destdir in [\\/]* | [A-Za-z]:[\\/]*) ;; @@ -2899,7 +4224,7 @@ func_mode_install () case $file in *.lo) ;; *) - func_fatal_help "\`$destdir' must be an absolute directory name" + func_fatal_help "'$destdir' must be an absolute directory name" ;; esac done @@ -2908,7 +4233,7 @@ func_mode_install () # This variable tells wrapper scripts just to set variables rather # than running their programs. - libtool_install_magic="$magic" + libtool_install_magic=$magic staticlibs= future_libdirs= @@ -2928,7 +4253,7 @@ func_mode_install () # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ - || func_fatal_help "\`$file' is not a valid libtool archive" + || func_fatal_help "'$file' is not a valid libtool archive" library_names= old_library= @@ -2950,7 +4275,7 @@ func_mode_install () fi func_dirname "$file" "/" "" - dir="$func_dirname_result" + dir=$func_dirname_result func_append dir "$objdir" if test -n "$relink_command"; then @@ -2964,7 +4289,7 @@ func_mode_install () # are installed into $libdir/../bin (currently, that works fine) # but it's something to keep an eye on. test "$inst_prefix_dir" = "$destdir" && \ - func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" + func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir" if test -n "$inst_prefix_dir"; then # Stick the inst_prefix_dir data into the link command. @@ -2973,29 +4298,36 @@ func_mode_install () relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` fi - func_warning "relinking \`$file'" + func_warning "relinking '$file'" func_show_eval "$relink_command" \ - 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' + 'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"' fi # See the names of the shared library. set dummy $library_names; shift if test -n "$1"; then - realname="$1" + realname=$1 shift - srcname="$realname" - test -n "$relink_command" && srcname="$realname"T + srcname=$realname + test -n "$relink_command" && srcname=${realname}T # Install the shared library and build the symlinks. func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ 'exit $?' - tstripme="$stripme" + tstripme=$stripme case $host_os in - cygwin* | mingw* | pw32* | cegcc*) + cygwin* | mingw* | windows* | pw32* | cegcc*) case $realname in *.dll.a) - tstripme="" + tstripme= + ;; + esac + ;; + os2*) + case $realname in + *_dll.a) + tstripme= ;; esac ;; @@ -3006,7 +4338,7 @@ func_mode_install () if test "$#" -gt 0; then # Delete the old symlinks, and create new ones. - # Try `ln -sf' first, because the `ln' binary might depend on + # Try 'ln -sf' first, because the 'ln' binary might depend on # the symlink we replace! Solaris /bin/ln does not understand -f, # so we also need to try rm && ln -s. for linkname @@ -3017,14 +4349,14 @@ func_mode_install () fi # Do each command in the postinstall commands. - lib="$destdir/$realname" + lib=$destdir/$realname func_execute_cmds "$postinstall_cmds" 'exit $?' fi # Install the pseudo-library for information purposes. func_basename "$file" - name="$func_basename_result" - instname="$dir/$name"i + name=$func_basename_result + instname=$dir/${name}i func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' # Maybe install the static library, too. @@ -3036,11 +4368,11 @@ func_mode_install () # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then - destfile="$destdir/$destname" + destfile=$destdir/$destname else func_basename "$file" - destfile="$func_basename_result" - destfile="$destdir/$destfile" + destfile=$func_basename_result + destfile=$destdir/$destfile fi # Deduce the name of the destination old-style object file. @@ -3050,11 +4382,11 @@ func_mode_install () staticdest=$func_lo2o_result ;; *.$objext) - staticdest="$destfile" + staticdest=$destfile destfile= ;; *) - func_fatal_help "cannot copy a libtool object to \`$destfile'" + func_fatal_help "cannot copy a libtool object to '$destfile'" ;; esac @@ -3063,7 +4395,7 @@ func_mode_install () func_show_eval "$install_prog $file $destfile" 'exit $?' # Install the old object if enabled. - if test "$build_old_libs" = yes; then + if test yes = "$build_old_libs"; then # Deduce the name of the old-style object file. func_lo2o "$file" staticobj=$func_lo2o_result @@ -3075,30 +4407,30 @@ func_mode_install () *) # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then - destfile="$destdir/$destname" + destfile=$destdir/$destname else func_basename "$file" - destfile="$func_basename_result" - destfile="$destdir/$destfile" + destfile=$func_basename_result + destfile=$destdir/$destfile fi # If the file is missing, and there is a .exe on the end, strip it # because it is most likely a libtool script we actually want to # install - stripped_ext="" + stripped_ext= case $file in *.exe) if test ! -f "$file"; then func_stripname '' '.exe' "$file" file=$func_stripname_result - stripped_ext=".exe" + stripped_ext=.exe fi ;; esac # Do a test to see if this is really a libtool program. case $host in - *cygwin* | *mingw*) + *cygwin* | *mingw* | *windows*) if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" wrapper=$func_ltwrapper_scriptname_result @@ -3119,19 +4451,19 @@ func_mode_install () # Check the variables that should have been set. test -z "$generated_by_libtool_version" && \ - func_fatal_error "invalid libtool wrapper script \`$wrapper'" + func_fatal_error "invalid libtool wrapper script '$wrapper'" - finalize=yes + finalize=: for lib in $notinst_deplibs; do # Check to see that each library is installed. libdir= if test -f "$lib"; then func_source "$lib" fi - libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test + libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'` if test -n "$libdir" && test ! -f "$libfile"; then - func_warning "\`$lib' has not been installed in \`$libdir'" - finalize=no + func_warning "'$lib' has not been installed in '$libdir'" + finalize=false fi done @@ -3139,29 +4471,29 @@ func_mode_install () func_source "$wrapper" outputname= - if test "$fast_install" = no && test -n "$relink_command"; then + if test no = "$fast_install" && test -n "$relink_command"; then $opt_dry_run || { - if test "$finalize" = yes; then + if $finalize; then tmpdir=`func_mktempdir` func_basename "$file$stripped_ext" - file="$func_basename_result" - outputname="$tmpdir/$file" + file=$func_basename_result + outputname=$tmpdir/$file # Replace the output file specification. relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` - $opt_silent || { + $opt_quiet || { func_quote_for_expand "$relink_command" eval "func_echo $func_quote_for_expand_result" } if eval "$relink_command"; then : else - func_error "error: relink \`$file' with the above command before installing it" + func_error "error: relink '$file' with the above command before installing it" $opt_dry_run || ${RM}r "$tmpdir" continue fi - file="$outputname" + file=$outputname else - func_warning "cannot relink \`$file'" + func_warning "cannot relink '$file'" fi } else @@ -3198,10 +4530,10 @@ func_mode_install () for file in $staticlibs; do func_basename "$file" - name="$func_basename_result" + name=$func_basename_result # Set up the ranlib parameters. - oldlib="$destdir/$name" + oldlib=$destdir/$name func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result @@ -3216,18 +4548,18 @@ func_mode_install () done test -n "$future_libdirs" && \ - func_warning "remember to run \`$progname --finish$future_libdirs'" + func_warning "remember to run '$progname --finish$future_libdirs'" if test -n "$current_libdirs"; then # Maybe just do a dry run. $opt_dry_run && current_libdirs=" -n$current_libdirs" - exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' + exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs' else exit $EXIT_SUCCESS fi } -test "$opt_mode" = install && func_mode_install ${1+"$@"} +test install = "$opt_mode" && func_mode_install ${1+"$@"} # func_generate_dlsyms outputname originator pic_p @@ -3235,16 +4567,17 @@ test "$opt_mode" = install && func_mode_install ${1+"$@"} # a dlpreopen symbol table. func_generate_dlsyms () { - $opt_debug - my_outputname="$1" - my_originator="$2" - my_pic_p="${3-no}" - my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` + $debug_cmd + + my_outputname=$1 + my_originator=$2 + my_pic_p=${3-false} + my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'` my_dlsyms= - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then if test -n "$NM" && test -n "$global_symbol_pipe"; then - my_dlsyms="${my_outputname}S.c" + my_dlsyms=${my_outputname}S.c else func_error "not configured to extract global symbols from dlpreopened files" fi @@ -3255,7 +4588,7 @@ func_generate_dlsyms () "") ;; *.c) # Discover the nlist of each of the dlfiles. - nlist="$output_objdir/${my_outputname}.nm" + nlist=$output_objdir/$my_outputname.nm func_show_eval "$RM $nlist ${nlist}S ${nlist}T" @@ -3263,34 +4596,36 @@ func_generate_dlsyms () func_verbose "creating $output_objdir/$my_dlsyms" $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ -/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ -/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ +/* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */ +/* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */ #ifdef __cplusplus extern \"C\" { #endif -#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) +#if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) #pragma GCC diagnostic ignored \"-Wstrict-prototypes\" #endif /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ -#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST -#elif defined(__osf__) +#elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif +#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) + /* External symbol declarations for the compiler. */\ " - if test "$dlself" = yes; then - func_verbose "generating symbol list for \`$output'" + if test yes = "$dlself"; then + func_verbose "generating symbol list for '$output'" $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" @@ -3298,7 +4633,7 @@ extern \"C\" { progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` for progfile in $progfiles; do func_to_tool_file "$progfile" func_convert_file_msys_to_w32 - func_verbose "extracting global C symbols from \`$func_to_tool_file_result'" + func_verbose "extracting global C symbols from '$func_to_tool_file_result'" $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" done @@ -3318,12 +4653,12 @@ extern \"C\" { # Prepare the list of exported symbols if test -z "$export_symbols"; then - export_symbols="$output_objdir/$outputname.exp" + export_symbols=$output_objdir/$outputname.exp $opt_dry_run || { $RM $export_symbols - eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' case $host in - *cygwin* | *mingw* | *cegcc* ) + *cygwin* | *mingw* | *windows* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' ;; @@ -3331,11 +4666,11 @@ extern \"C\" { } else $opt_dry_run || { - eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' + eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' case $host in - *cygwin* | *mingw* | *cegcc* ) + *cygwin* | *mingw* | *windows* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' ;; @@ -3345,22 +4680,22 @@ extern \"C\" { fi for dlprefile in $dlprefiles; do - func_verbose "extracting global C symbols from \`$dlprefile'" + func_verbose "extracting global C symbols from '$dlprefile'" func_basename "$dlprefile" - name="$func_basename_result" + name=$func_basename_result case $host in - *cygwin* | *mingw* | *cegcc* ) + *cygwin* | *mingw* | *windows* | *cegcc* ) # if an import library, we need to obtain dlname if func_win32_import_lib_p "$dlprefile"; then func_tr_sh "$dlprefile" eval "curr_lafile=\$libfile_$func_tr_sh_result" - dlprefile_dlbasename="" + dlprefile_dlbasename= if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then # Use subshell, to avoid clobbering current variable values dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` - if test -n "$dlprefile_dlname" ; then + if test -n "$dlprefile_dlname"; then func_basename "$dlprefile_dlname" - dlprefile_dlbasename="$func_basename_result" + dlprefile_dlbasename=$func_basename_result else # no lafile. user explicitly requested -dlpreopen . $sharedlib_from_linklib_cmd "$dlprefile" @@ -3368,7 +4703,7 @@ extern \"C\" { fi fi $opt_dry_run || { - if test -n "$dlprefile_dlbasename" ; then + if test -n "$dlprefile_dlbasename"; then eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' else func_warning "Could not compute DLL name from $name" @@ -3424,6 +4759,11 @@ extern \"C\" { echo '/* NONE */' >> "$output_objdir/$my_dlsyms" fi + func_show_eval '$RM "${nlist}I"' + if test -n "$global_symbol_to_import"; then + eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I' + fi + echo >> "$output_objdir/$my_dlsyms" "\ /* The mapping between symbol names and symbols. */ @@ -3432,11 +4772,30 @@ typedef struct { void *address; } lt_dlsymlist; extern LT_DLSYM_CONST lt_dlsymlist -lt_${my_prefix}_LTX_preloaded_symbols[]; +lt_${my_prefix}_LTX_preloaded_symbols[];\ +" + + if test -s "$nlist"I; then + echo >> "$output_objdir/$my_dlsyms" "\ +static void lt_syminit(void) +{ + LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols; + for (; symbol->name; ++symbol) + {" + $SED 's/.*/ if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms" + echo >> "$output_objdir/$my_dlsyms" "\ + } +}" + fi + echo >> "$output_objdir/$my_dlsyms" "\ LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[] = -{\ - { \"$my_originator\", (void *) 0 }," +{ {\"$my_originator\", (void *) 0}," + + if test -s "$nlist"I; then + echo >> "$output_objdir/$my_dlsyms" "\ + {\"@INIT@\", (void *) <_syminit}," + fi case $need_lib_prefix in no) @@ -3478,9 +4837,7 @@ static const void *lt_preloaded_setup() { *-*-hpux*) pic_flag_for_symtable=" $pic_flag" ;; *) - if test "X$my_pic_p" != Xno; then - pic_flag_for_symtable=" $pic_flag" - fi + $my_pic_p && pic_flag_for_symtable=" $pic_flag" ;; esac ;; @@ -3497,12 +4854,12 @@ static const void *lt_preloaded_setup() { func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' # Clean up the generated files. - func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' + func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"' # Transform the symbol file into the correct name. - symfileobj="$output_objdir/${my_outputname}S.$objext" + symfileobj=$output_objdir/${my_outputname}S.$objext case $host in - *cygwin* | *mingw* | *cegcc* ) + *cygwin* | *mingw* | *windows* | *cegcc* ) if test -f "$output_objdir/$my_outputname.def"; then compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` @@ -3518,7 +4875,7 @@ static const void *lt_preloaded_setup() { esac ;; *) - func_fatal_error "unknown suffix for \`$my_dlsyms'" + func_fatal_error "unknown suffix for '$my_dlsyms'" ;; esac else @@ -3532,6 +4889,32 @@ static const void *lt_preloaded_setup() { fi } +# func_cygming_gnu_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is a GNU/binutils-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_gnu_implib_p () +{ + $debug_cmd + + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` + test -n "$func_cygming_gnu_implib_tmp" +} + +# func_cygming_ms_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is an MS-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_ms_implib_p () +{ + $debug_cmd + + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` + test -n "$func_cygming_ms_implib_tmp" +} + # func_win32_libid arg # return the library type of file 'arg' # @@ -3541,8 +4924,9 @@ static const void *lt_preloaded_setup() { # Despite the name, also deal with 64 bit binaries. func_win32_libid () { - $opt_debug - win32_libid_type="unknown" + $debug_cmd + + win32_libid_type=unknown win32_fileres=`file -L $1 2>/dev/null` case $win32_fileres in *ar\ archive\ import\ library*) # definitely import @@ -3552,16 +4936,29 @@ func_win32_libid () # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then - func_to_tool_file "$1" func_convert_file_msys_to_w32 - win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | - $SED -n -e ' + case $nm_interface in + "MS dumpbin") + if func_cygming_ms_implib_p "$1" || + func_cygming_gnu_implib_p "$1" + then + win32_nmres=import + else + win32_nmres= + fi + ;; + *) + func_to_tool_file "$1" func_convert_file_msys_to_w32 + win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | + $SED -n -e ' 1,100{ / I /{ - s,.*,import, + s|.*|import| p q } }'` + ;; + esac case $win32_nmres in import*) win32_libid_type="x86 archive import";; *) win32_libid_type="x86 archive static";; @@ -3593,7 +4990,8 @@ func_win32_libid () # $sharedlib_from_linklib_result func_cygming_dll_for_implib () { - $opt_debug + $debug_cmd + sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` } @@ -3610,7 +5008,8 @@ func_cygming_dll_for_implib () # specified import library. func_cygming_dll_for_implib_fallback_core () { - $opt_debug + $debug_cmd + match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` $OBJDUMP -s --section "$1" "$2" 2>/dev/null | $SED '/^Contents of section '"$match_literal"':/{ @@ -3646,8 +5045,8 @@ func_cygming_dll_for_implib_fallback_core () /./p' | # we now have a list, one entry per line, of the stringified # contents of the appropriate section of all members of the - # archive which possess that section. Heuristic: eliminate - # all those which have a first or second character that is + # archive that possess that section. Heuristic: eliminate + # all those that have a first or second character that is # a '.' (that is, objdump's representation of an unprintable # character.) This should work for all archives with less than # 0x302f exports -- but will fail for DLLs whose name actually @@ -3658,30 +5057,6 @@ func_cygming_dll_for_implib_fallback_core () $SED -e '/^\./d;/^.\./d;q' } -# func_cygming_gnu_implib_p ARG -# This predicate returns with zero status (TRUE) if -# ARG is a GNU/binutils-style import library. Returns -# with nonzero status (FALSE) otherwise. -func_cygming_gnu_implib_p () -{ - $opt_debug - func_to_tool_file "$1" func_convert_file_msys_to_w32 - func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` - test -n "$func_cygming_gnu_implib_tmp" -} - -# func_cygming_ms_implib_p ARG -# This predicate returns with zero status (TRUE) if -# ARG is an MS-style import library. Returns -# with nonzero status (FALSE) otherwise. -func_cygming_ms_implib_p () -{ - $opt_debug - func_to_tool_file "$1" func_convert_file_msys_to_w32 - func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` - test -n "$func_cygming_ms_implib_tmp" -} - # func_cygming_dll_for_implib_fallback ARG # Platform-specific function to extract the # name of the DLL associated with the specified @@ -3695,16 +5070,17 @@ func_cygming_ms_implib_p () # $sharedlib_from_linklib_result func_cygming_dll_for_implib_fallback () { - $opt_debug - if func_cygming_gnu_implib_p "$1" ; then + $debug_cmd + + if func_cygming_gnu_implib_p "$1"; then # binutils import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` - elif func_cygming_ms_implib_p "$1" ; then + elif func_cygming_ms_implib_p "$1"; then # ms-generated import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` else # unknown - sharedlib_from_linklib_result="" + sharedlib_from_linklib_result= fi } @@ -3712,10 +5088,11 @@ func_cygming_dll_for_implib_fallback () # func_extract_an_archive dir oldlib func_extract_an_archive () { - $opt_debug - f_ex_an_ar_dir="$1"; shift - f_ex_an_ar_oldlib="$1" - if test "$lock_old_archive_extraction" = yes; then + $debug_cmd + + f_ex_an_ar_dir=$1; shift + f_ex_an_ar_oldlib=$1 + if test yes = "$lock_old_archive_extraction"; then lockfile=$f_ex_an_ar_oldlib.lock until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" @@ -3724,7 +5101,7 @@ func_extract_an_archive () fi func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ 'stat=$?; rm -f "$lockfile"; exit $stat' - if test "$lock_old_archive_extraction" = yes; then + if test yes = "$lock_old_archive_extraction"; then $opt_dry_run || rm -f "$lockfile" fi if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then @@ -3738,22 +5115,23 @@ func_extract_an_archive () # func_extract_archives gentop oldlib ... func_extract_archives () { - $opt_debug - my_gentop="$1"; shift + $debug_cmd + + my_gentop=$1; shift my_oldlibs=${1+"$@"} - my_oldobjs="" - my_xlib="" - my_xabs="" - my_xdir="" + my_oldobjs= + my_xlib= + my_xabs= + my_xdir= for my_xlib in $my_oldlibs; do # Extract the objects. case $my_xlib in - [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; + [\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;; *) my_xabs=`pwd`"/$my_xlib" ;; esac func_basename "$my_xlib" - my_xlib="$func_basename_result" + my_xlib=$func_basename_result my_xlib_u=$my_xlib while :; do case " $extracted_archives " in @@ -3765,7 +5143,7 @@ func_extract_archives () esac done extracted_archives="$extracted_archives $my_xlib_u" - my_xdir="$my_gentop/$my_xlib_u" + my_xdir=$my_gentop/$my_xlib_u func_mkdir_p "$my_xdir" @@ -3778,22 +5156,23 @@ func_extract_archives () cd $my_xdir || exit $? darwin_archive=$my_xabs darwin_curdir=`pwd` - darwin_base_archive=`basename "$darwin_archive"` + func_basename "$darwin_archive" + darwin_base_archive=$func_basename_result darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` if test -n "$darwin_arches"; then darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` darwin_arch= func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" - for darwin_arch in $darwin_arches ; do - func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" - $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" - cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" - func_extract_an_archive "`pwd`" "${darwin_base_archive}" + for darwin_arch in $darwin_arches; do + func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch" + $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive" + cd "unfat-$$/$darwin_base_archive-$darwin_arch" + func_extract_an_archive "`pwd`" "$darwin_base_archive" cd "$darwin_curdir" - $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" + $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" done # $darwin_arches ## Okay now we've a bunch of thin objects, gotta fatten them up :) - darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` + darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$sed_basename" | sort -u` darwin_file= darwin_files= for darwin_file in $darwin_filelist; do @@ -3815,7 +5194,7 @@ func_extract_archives () my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` done - func_extract_archives_result="$my_oldobjs" + func_extract_archives_result=$my_oldobjs } @@ -3823,15 +5202,15 @@ func_extract_archives () # # Emit a libtool wrapper script on stdout. # Don't directly open a file because we may want to -# incorporate the script contents within a cygwin/mingw +# incorporate the script contents within a cygwin/mingw/windows # wrapper executable. Must ONLY be called from within # func_mode_link because it depends on a number of variables # set therein. # # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR # variable will take. If 'yes', then the emitted script -# will assume that the directory in which it is stored is -# the $objdir directory. This is a cygwin/mingw-specific +# will assume that the directory where it is stored is +# the $objdir directory. This is a cygwin/mingw/windows-specific # behavior. func_emit_wrapper () { @@ -3841,7 +5220,7 @@ func_emit_wrapper () #! $SHELL # $output - temporary wrapper script for $objdir/$outputname -# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# Generated by $PROGRAM (GNU $PACKAGE) $VERSION # # The $output program cannot be directly executed until all the libtool # libraries that it depends on are installed. @@ -3898,9 +5277,9 @@ _LTECHO_EOF' # Very basic option parsing. These options are (a) specific to # the libtool wrapper, (b) are identical between the wrapper -# /script/ and the wrapper /executable/ which is used only on +# /script/ and the wrapper /executable/ that is used only on # windows platforms, and (c) all begin with the string "--lt-" -# (application programs are unlikely to have options which match +# (application programs are unlikely to have options that match # this pattern). # # There are only two supported options: --lt-debug and @@ -3933,7 +5312,7 @@ func_parse_lt_options () # Print the debug banner immediately: if test -n \"\$lt_option_debug\"; then - echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2 + echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2 fi } @@ -3944,7 +5323,7 @@ func_lt_dump_args () lt_dump_args_N=1; for lt_arg do - \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\" + \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\" lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` done } @@ -3955,10 +5334,10 @@ func_exec_program_core () " case $host in # Backslashes separate directories on plain windows - *-*-mingw | *-*-os2* | *-cegcc*) + *-*-mingw* | *-*-windows* | *-*-os2* | *-cegcc*) $ECHO "\ if test -n \"\$lt_option_debug\"; then - \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2 + \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} @@ -3968,7 +5347,7 @@ func_exec_program_core () *) $ECHO "\ if test -n \"\$lt_option_debug\"; then - \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2 + \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir/\$program\" \${1+\"\$@\"} @@ -4023,7 +5402,7 @@ func_exec_program () file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` done - # Usually 'no', except on cygwin/mingw when embedded into + # Usually 'no', except on cygwin/mingw/windows when embedded into # the cwrapper. WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then @@ -4043,13 +5422,13 @@ func_exec_program () test -n \"\$absdir\" && thisdir=\"\$absdir\" " - if test "$fast_install" = yes; then + if test yes = "$fast_install"; then $ECHO "\ program=lt-'$outputname'$exeext progdir=\"\$thisdir/$objdir\" if test ! -f \"\$progdir/\$program\" || - { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\ test \"X\$file\" != \"X\$progdir/\$program\"; }; then file=\"\$\$-\$program\" @@ -4066,7 +5445,7 @@ func_exec_program () if test -n \"\$relink_command\"; then if relink_command_output=\`eval \$relink_command 2>&1\`; then : else - $ECHO \"\$relink_command_output\" >&2 + \$ECHO \"\$relink_command_output\" >&2 $RM \"\$progdir/\$file\" exit 1 fi @@ -4101,7 +5480,7 @@ func_exec_program () fi # Export our shlibpath_var if we have one. - if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then $ECHO "\ # Add our own library path to $shlibpath_var $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" @@ -4121,7 +5500,7 @@ func_exec_program () fi else # The program doesn't exist. - \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 + \$ECHO \"\$0: error: '\$progdir/\$program' does not exist\" 1>&2 \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 exit 1 @@ -4140,7 +5519,7 @@ func_emit_cwrapperexe_src () cat < #include +#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) + /* declarations of non-ANSI functions */ -#if defined(__MINGW32__) +#if defined __MINGW32__ # ifdef __STRICT_ANSI__ -int _putenv (const char *); +_CRTIMP int __cdecl _putenv (const char *); # endif -#elif defined(__CYGWIN__) +#elif defined __CYGWIN__ # ifdef __STRICT_ANSI__ char *realpath (const char *, char *); int putenv (char *); int setenv (const char *, const char *, int); # endif -/* #elif defined (other platforms) ... */ +/* #elif defined other_platform || defined ... */ #endif /* portability defines, excluding path handling macros */ -#if defined(_MSC_VER) +#if defined _MSC_VER # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv # define S_IXUSR _S_IEXEC -# ifndef _INTPTR_T_DEFINED -# define _INTPTR_T_DEFINED -# define intptr_t int -# endif -#elif defined(__MINGW32__) +#elif defined __MINGW32__ # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv -#elif defined(__CYGWIN__) +#elif defined __CYGWIN__ # define HAVE_SETENV # define FOPEN_WB "wb" -/* #elif defined (other platforms) ... */ +/* #elif defined other platforms ... */ #endif -#if defined(PATH_MAX) +#if defined PATH_MAX # define LT_PATHMAX PATH_MAX -#elif defined(MAXPATHLEN) +#elif defined MAXPATHLEN # define LT_PATHMAX MAXPATHLEN #else # define LT_PATHMAX 1024 @@ -4234,8 +5611,8 @@ int setenv (const char *, const char *, int); # define PATH_SEPARATOR ':' #endif -#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ - defined (__OS2__) +#if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \ + defined __OS2__ # define HAVE_DOS_BASED_FILE_SYSTEM # define FOPEN_WB "wb" # ifndef DIR_SEPARATOR_2 @@ -4268,10 +5645,10 @@ int setenv (const char *, const char *, int); #define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) #define XFREE(stale) do { \ - if (stale) { free ((void *) stale); stale = 0; } \ + if (stale) { free (stale); stale = 0; } \ } while (0) -#if defined(LT_DEBUGWRAPPER) +#if defined LT_DEBUGWRAPPER static int lt_debug = 1; #else static int lt_debug = 0; @@ -4300,11 +5677,16 @@ void lt_dump_script (FILE *f); EOF cat < 0) && IS_PATH_SEPARATOR (new_value[len-1])) + size_t len = strlen (new_value); + while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1])) { - new_value[len-1] = '\0'; + new_value[--len] = '\0'; } lt_setenv (name, new_value); XFREE (new_value); @@ -4939,7 +6321,7 @@ lt_update_lib_path (const char *name, const char *value) EOF case $host_os in - mingw*) + mingw* | windows*) cat <<"EOF" /* Prepares an argument vector before calling spawn(). @@ -5082,31 +6464,53 @@ EOF # True if ARG is an import lib, as indicated by $file_magic_cmd func_win32_import_lib_p () { - $opt_debug + $debug_cmd + case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in *import*) : ;; *) false ;; esac } +# func_suncc_cstd_abi +# !!ONLY CALL THIS FOR SUN CC AFTER $compile_command IS FULLY EXPANDED!! +# Several compiler flags select an ABI that is incompatible with the +# Cstd library. Avoid specifying it if any are in CXXFLAGS. +func_suncc_cstd_abi () +{ + $debug_cmd + + case " $compile_command " in + *" -compat=g "*|*\ -std=c++[0-9][0-9]\ *|*" -library=stdcxx4 "*|*" -library=stlport4 "*) + suncc_use_cstd_abi=no + ;; + *) + suncc_use_cstd_abi=yes + ;; + esac +} + # func_mode_link arg... func_mode_link () { - $opt_debug + $debug_cmd + case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + *-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-os2* | *-cegcc*) # It is impossible to link a dll without this setting, and # we shouldn't force the makefile maintainer to figure out - # which system we are compiling for in order to pass an extra + # what system we are compiling for in order to pass an extra # flag for every libtool invocation. - # allow_undefined=no + # SDL customization: SDL code doesn't have any undefined symbols + allow_undefined=no # FIXME: Unfortunately, there are problems with the above when trying - # to make a dll which has undefined symbols, in which case not + # to make a dll that has undefined symbols, in which case not # even a static library is built. For now, we need to specify # -no-undefined on the libtool link line when we can be certain # that all symbols are satisfied, otherwise we get a static library. - allow_undefined=yes + # SDL customization: SDL code doesn't have any undefined symbols + # allow_undefined=yes ;; *) allow_undefined=yes @@ -5146,10 +6550,11 @@ func_mode_link () module=no no_install=no objs= + os2dllname= non_pic_objects= precious_files_regex= prefer_static_libs=no - preload=no + preload=false prev= prevarg= release= @@ -5161,7 +6566,7 @@ func_mode_link () vinfo= vinfo_number=no weak_libs= - single_module="${wl}-single_module" + single_module=$wl-single_module func_infer_tag $base_compile # We need to know -static, to get the right output filenames. @@ -5169,15 +6574,15 @@ func_mode_link () do case $arg in -shared) - test "$build_libtool_libs" != yes && \ - func_fatal_configuration "can not build a shared library" + test yes != "$build_libtool_libs" \ + && func_fatal_configuration "cannot build a shared library" build_old_libs=no break ;; -all-static | -static | -static-libtool-libs) case $arg in -all-static) - if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then + if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then func_warning "complete static linking is impossible in this configuration" fi if test -n "$link_static_flag"; then @@ -5210,7 +6615,7 @@ func_mode_link () # Go through the arguments, transforming them on the way. while test "$#" -gt 0; do - arg="$1" + arg=$1 shift func_quote_for_eval "$arg" qarg=$func_quote_for_eval_unquoted_result @@ -5227,21 +6632,21 @@ func_mode_link () case $prev in bindir) - bindir="$arg" + bindir=$arg prev= continue ;; dlfiles|dlprefiles) - if test "$preload" = no; then + $preload || { # Add the symbol object into the linking commands. func_append compile_command " @SYMFILE@" func_append finalize_command " @SYMFILE@" - preload=yes - fi + preload=: + } case $arg in *.la | *.lo) ;; # We handle these cases below. force) - if test "$dlself" = no; then + if test no = "$dlself"; then dlself=needless export_dynamic=yes fi @@ -5249,9 +6654,9 @@ func_mode_link () continue ;; self) - if test "$prev" = dlprefiles; then + if test dlprefiles = "$prev"; then dlself=yes - elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then dlself=yes else dlself=needless @@ -5261,7 +6666,7 @@ func_mode_link () continue ;; *) - if test "$prev" = dlfiles; then + if test dlfiles = "$prev"; then func_append dlfiles " $arg" else func_append dlprefiles " $arg" @@ -5272,14 +6677,14 @@ func_mode_link () esac ;; expsyms) - export_symbols="$arg" + export_symbols=$arg test -f "$arg" \ - || func_fatal_error "symbol file \`$arg' does not exist" + || func_fatal_error "symbol file '$arg' does not exist" prev= continue ;; expsyms_regex) - export_symbols_regex="$arg" + export_symbols_regex=$arg prev= continue ;; @@ -5297,7 +6702,13 @@ func_mode_link () continue ;; inst_prefix) - inst_prefix_dir="$arg" + inst_prefix_dir=$arg + prev= + continue + ;; + mllvm) + # Clang does not use LLVM to link, so we can simply discard any + # '-mllvm $arg' options when doing the link step. prev= continue ;; @@ -5321,21 +6732,21 @@ func_mode_link () if test -z "$pic_object" || test -z "$non_pic_object" || - test "$pic_object" = none && - test "$non_pic_object" = none; then - func_fatal_error "cannot find name of object for \`$arg'" + test none = "$pic_object" && + test none = "$non_pic_object"; then + func_fatal_error "cannot find name of object for '$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" - xdir="$func_dirname_result" + xdir=$func_dirname_result - if test "$pic_object" != none; then + if test none != "$pic_object"; then # Prepend the subdirectory the object is found in. - pic_object="$xdir$pic_object" + pic_object=$xdir$pic_object - if test "$prev" = dlfiles; then - if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + if test dlfiles = "$prev"; then + if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then func_append dlfiles " $pic_object" prev= continue @@ -5346,7 +6757,7 @@ func_mode_link () fi # CHECK ME: I think I busted this. -Ossama - if test "$prev" = dlprefiles; then + if test dlprefiles = "$prev"; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= @@ -5354,23 +6765,23 @@ func_mode_link () # A PIC object. func_append libobjs " $pic_object" - arg="$pic_object" + arg=$pic_object fi # Non-PIC object. - if test "$non_pic_object" != none; then + if test none != "$non_pic_object"; then # Prepend the subdirectory the object is found in. - non_pic_object="$xdir$non_pic_object" + non_pic_object=$xdir$non_pic_object # A standard non-PIC object func_append non_pic_objects " $non_pic_object" - if test -z "$pic_object" || test "$pic_object" = none ; then - arg="$non_pic_object" + if test -z "$pic_object" || test none = "$pic_object"; then + arg=$non_pic_object fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. - non_pic_object="$pic_object" + non_pic_object=$pic_object func_append non_pic_objects " $non_pic_object" fi else @@ -5378,7 +6789,7 @@ func_mode_link () if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" - xdir="$func_dirname_result" + xdir=$func_dirname_result func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result @@ -5386,24 +6797,29 @@ func_mode_link () func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else - func_fatal_error "\`$arg' is not a valid libtool object" + func_fatal_error "'$arg' is not a valid libtool object" fi fi done else - func_fatal_error "link input file \`$arg' does not exist" + func_fatal_error "link input file '$arg' does not exist" fi arg=$save_arg prev= continue ;; + os2dllname) + os2dllname=$arg + prev= + continue + ;; precious_regex) - precious_files_regex="$arg" + precious_files_regex=$arg prev= continue ;; release) - release="-$arg" + release=-$arg prev= continue ;; @@ -5415,7 +6831,7 @@ func_mode_link () func_fatal_error "only absolute run-paths are allowed" ;; esac - if test "$prev" = rpath; then + if test rpath = "$prev"; then case "$rpath " in *" $arg "*) ;; *) func_append rpath " $arg" ;; @@ -5430,7 +6846,7 @@ func_mode_link () continue ;; shrext) - shrext_cmds="$arg" + shrext_cmds=$arg prev= continue ;; @@ -5439,6 +6855,13 @@ func_mode_link () prev= continue ;; + xassembler) + func_append compiler_flags " -Xassembler $qarg" + prev= + func_append compile_command " -Xassembler $qarg" + func_append finalize_command " -Xassembler $qarg" + continue + ;; xcclinker) func_append linker_flags " $qarg" func_append compiler_flags " $qarg" @@ -5470,7 +6893,7 @@ func_mode_link () esac fi # test -n "$prev" - prevarg="$arg" + prevarg=$arg case $arg in -all-static) @@ -5484,7 +6907,7 @@ func_mode_link () -allow-undefined) # FIXME: remove this flag sometime in the future. - func_fatal_error "\`-allow-undefined' must not be used because it is the default" + func_fatal_error "'-allow-undefined' must not be used because it is the default" ;; -avoid-version) @@ -5516,7 +6939,7 @@ func_mode_link () if test -n "$export_symbols" || test -n "$export_symbols_regex"; then func_fatal_error "more than one -exported-symbols argument is not allowed" fi - if test "X$arg" = "X-export-symbols"; then + if test X-export-symbols = "X$arg"; then prev=expsyms else prev=expsyms_regex @@ -5550,9 +6973,9 @@ func_mode_link () func_stripname "-L" '' "$arg" if test -z "$func_stripname_result"; then if test "$#" -gt 0; then - func_fatal_error "require no space between \`-L' and \`$1'" + func_fatal_error "require no space between '-L' and '$1'" else - func_fatal_error "need path for \`-L' option" + func_fatal_error "need path for '-L' option" fi fi func_resolve_sysroot "$func_stripname_result" @@ -5563,8 +6986,8 @@ func_mode_link () *) absdir=`cd "$dir" && pwd` test -z "$absdir" && \ - func_fatal_error "cannot determine absolute directory name of \`$dir'" - dir="$absdir" + func_fatal_error "cannot determine absolute directory name of '$dir'" + dir=$absdir ;; esac case "$deplibs " in @@ -5581,7 +7004,7 @@ func_mode_link () ;; esac case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + *-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` case :$dllsearchpath: in *":$dir:"*) ;; @@ -5599,19 +7022,19 @@ func_mode_link () ;; -l*) - if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then + if test X-lc = "X$arg" || test X-lm = "X$arg"; then case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) + *-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) # These systems don't actually have a C or math library (as such) continue ;; *-*-os2*) # These systems don't actually have a C library (as such) - test "X$arg" = "X-lc" && continue + test X-lc = "X$arg" && continue ;; - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig* | *-*-midnightbsd*) # Do not include libc due to us having libc/libc_r. - test "X$arg" = "X-lc" && continue + test X-lc = "X$arg" && continue ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C and math libraries are in the System framework @@ -5620,16 +7043,16 @@ func_mode_link () ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype - test "X$arg" = "X-lc" && continue + test X-lc = "X$arg" && continue ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work - test "X$arg" = "X-lc" && continue + test X-lc = "X$arg" && continue ;; esac - elif test "X$arg" = "X-lc_r"; then + elif test X-lc_r = "X$arg"; then case $host in - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig* | *-*-midnightbsd*) # Do not include libc_r directly, use -pthread flag. continue ;; @@ -5639,6 +7062,11 @@ func_mode_link () continue ;; + -mllvm) + prev=mllvm + continue + ;; + -module) module=yes continue @@ -5654,8 +7082,20 @@ func_mode_link () prev=xcompiler continue ;; - - -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + # Solaris ld rejects as of 11.4. Refer to Oracle bug 22985199. + -pthread) + case $host in + *solaris2*) ;; + *) + case "$new_inherited_linker_flags " in + *" $arg "*) ;; + * ) func_append new_inherited_linker_flags " $arg" ;; + esac + ;; + esac + continue + ;; + -mt|-mthreads|-kthread|-Kthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) func_append compiler_flags " $arg" func_append compile_command " $arg" @@ -5668,7 +7108,7 @@ func_mode_link () ;; -multi_module) - single_module="${wl}-multi_module" + single_module=$wl-multi_module continue ;; @@ -5679,11 +7119,11 @@ func_mode_link () -no-install) case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) + *-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) # The PATH hackery in wrapper scripts is required on Windows # and Darwin in order for the loader to find any dlls it needs. - func_warning "\`-no-install' is ignored for $host" - func_warning "assuming \`-no-fast-install' instead" + func_warning "'-no-install' is ignored for $host" + func_warning "assuming '-no-fast-install' instead" fast_install=no ;; *) no_install=yes ;; @@ -5701,6 +7141,11 @@ func_mode_link () continue ;; + -os2dllname) + prev=os2dllname + continue + ;; + -o) prev=output ;; -precious-files-regex) @@ -5788,14 +7233,14 @@ func_mode_link () func_stripname '-Wc,' '' "$arg" args=$func_stripname_result arg= - save_ifs="$IFS"; IFS=',' + save_ifs=$IFS; IFS=, for flag in $args; do - IFS="$save_ifs" + IFS=$save_ifs func_quote_for_eval "$flag" func_append arg " $func_quote_for_eval_result" func_append compiler_flags " $func_quote_for_eval_result" done - IFS="$save_ifs" + IFS=$save_ifs func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; @@ -5804,19 +7249,24 @@ func_mode_link () func_stripname '-Wl,' '' "$arg" args=$func_stripname_result arg= - save_ifs="$IFS"; IFS=',' + save_ifs=$IFS; IFS=, for flag in $args; do - IFS="$save_ifs" + IFS=$save_ifs func_quote_for_eval "$flag" func_append arg " $wl$func_quote_for_eval_result" func_append compiler_flags " $wl$func_quote_for_eval_result" func_append linker_flags " $func_quote_for_eval_result" done - IFS="$save_ifs" + IFS=$save_ifs func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; + -Xassembler) + prev=xassembler + continue + ;; + -Xcompiler) prev=xcompiler continue @@ -5835,7 +7285,7 @@ func_mode_link () # -msg_* for osf cc -msg_*) func_quote_for_eval "$arg" - arg="$func_quote_for_eval_result" + arg=$func_quote_for_eval_result ;; # Flags to be passed through unchanged, with rationale: @@ -5847,25 +7297,64 @@ func_mode_link () # -m*, -t[45]*, -txscale* architecture-specific flags for GCC # -F/path path to uninstalled frameworks, gcc on darwin # -p, -pg, --coverage, -fprofile-* profiling flags for GCC + # -fstack-protector* stack protector flags for GCC # @file GCC response files # -tp=* Portland pgcc target processor selection # --sysroot=* for sysroot support - # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization + # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization + # -specs=* GCC specs files + # -stdlib=* select c++ std lib with clang + # -fdiagnostics-color* simply affects output + # -frecord-gcc-switches used to verify flags were respected + # -fsanitize=* Clang/GCC memory and address sanitizer + # -fno-sanitize* Clang/GCC memory and address sanitizer + # -shared-libsan Link with shared sanitizer runtimes (Clang) + # -static-libsan Link with static sanitizer runtimes (Clang) + # -fuse-ld=* Linker select flags for GCC + # -rtlib=* select c runtime lib with clang + # --unwindlib=* select unwinder library with clang + # -f{file|debug|macro|profile}-prefix-map=* needed for lto linking + # -Wa,* Pass flags directly to the assembler + # -Werror, -Werror=* Report (specified) warnings as errors -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ - -O*|-flto*|-fwhopr*|-fuse-linker-plugin) + -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*| \ + -stdlib=*|-rtlib=*|--unwindlib=*| \ + -specs=*|-fsanitize=*|-fno-sanitize*|-shared-libsan|-static-libsan| \ + -ffile-prefix-map=*|-fdebug-prefix-map=*|-fmacro-prefix-map=*|-fprofile-prefix-map=*| \ + -fdiagnostics-color*|-frecord-gcc-switches| \ + -fuse-ld=*|-Wa,*|-Werror|-Werror=*) func_quote_for_eval "$arg" - arg="$func_quote_for_eval_result" + arg=$func_quote_for_eval_result func_append compile_command " $arg" func_append finalize_command " $arg" func_append compiler_flags " $arg" continue ;; + -Z*) + if test os2 = "`expr $host : '.*\(os2\)'`"; then + # OS/2 uses -Zxxx to specify OS/2-specific options + compiler_flags="$compiler_flags $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + case $arg in + -Zlinker | -Zstack) + prev=xcompiler + ;; + esac + continue + else + # Otherwise treat like 'Some other compiler flag' below + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + fi + ;; + # Some other compiler flag. -* | +*) func_quote_for_eval "$arg" - arg="$func_quote_for_eval_result" + arg=$func_quote_for_eval_result ;; *.$objext) @@ -5886,21 +7375,21 @@ func_mode_link () if test -z "$pic_object" || test -z "$non_pic_object" || - test "$pic_object" = none && - test "$non_pic_object" = none; then - func_fatal_error "cannot find name of object for \`$arg'" + test none = "$pic_object" && + test none = "$non_pic_object"; then + func_fatal_error "cannot find name of object for '$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" - xdir="$func_dirname_result" + xdir=$func_dirname_result - if test "$pic_object" != none; then + test none = "$pic_object" || { # Prepend the subdirectory the object is found in. - pic_object="$xdir$pic_object" + pic_object=$xdir$pic_object - if test "$prev" = dlfiles; then - if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then + if test dlfiles = "$prev"; then + if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then func_append dlfiles " $pic_object" prev= continue @@ -5911,7 +7400,7 @@ func_mode_link () fi # CHECK ME: I think I busted this. -Ossama - if test "$prev" = dlprefiles; then + if test dlprefiles = "$prev"; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= @@ -5919,23 +7408,23 @@ func_mode_link () # A PIC object. func_append libobjs " $pic_object" - arg="$pic_object" - fi + arg=$pic_object + } # Non-PIC object. - if test "$non_pic_object" != none; then + if test none != "$non_pic_object"; then # Prepend the subdirectory the object is found in. - non_pic_object="$xdir$non_pic_object" + non_pic_object=$xdir$non_pic_object # A standard non-PIC object func_append non_pic_objects " $non_pic_object" - if test -z "$pic_object" || test "$pic_object" = none ; then - arg="$non_pic_object" + if test -z "$pic_object" || test none = "$pic_object"; then + arg=$non_pic_object fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. - non_pic_object="$pic_object" + non_pic_object=$pic_object func_append non_pic_objects " $non_pic_object" fi else @@ -5943,7 +7432,7 @@ func_mode_link () if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" - xdir="$func_dirname_result" + xdir=$func_dirname_result func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result @@ -5951,7 +7440,7 @@ func_mode_link () func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else - func_fatal_error "\`$arg' is not a valid libtool object" + func_fatal_error "'$arg' is not a valid libtool object" fi fi ;; @@ -5967,11 +7456,11 @@ func_mode_link () # A libtool-controlled library. func_resolve_sysroot "$arg" - if test "$prev" = dlfiles; then + if test dlfiles = "$prev"; then # This library was specified with -dlopen. func_append dlfiles " $func_resolve_sysroot_result" prev= - elif test "$prev" = dlprefiles; then + elif test dlprefiles = "$prev"; then # The library was specified with -dlpreopen. func_append dlprefiles " $func_resolve_sysroot_result" prev= @@ -5986,7 +7475,7 @@ func_mode_link () # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. func_quote_for_eval "$arg" - arg="$func_quote_for_eval_result" + arg=$func_quote_for_eval_result ;; esac # arg @@ -5998,9 +7487,9 @@ func_mode_link () done # argument parsing loop test -n "$prev" && \ - func_fatal_help "the \`$prevarg' option requires an argument" + func_fatal_help "the '$prevarg' option requires an argument" - if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then eval arg=\"$export_dynamic_flag_spec\" func_append compile_command " $arg" func_append finalize_command " $arg" @@ -6009,20 +7498,23 @@ func_mode_link () oldlibs= # calculate the name of the file, without its directory func_basename "$output" - outputname="$func_basename_result" - libobjs_save="$libobjs" + outputname=$func_basename_result + libobjs_save=$libobjs if test -n "$shlibpath_var"; then # get the directories listed in $shlibpath_var - eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\` + eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\` else shlib_search_path= fi eval sys_lib_search_path=\"$sys_lib_search_path_spec\" eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + # Definition is injected by LT_CONFIG during libtool generation. + func_munge_path_list sys_lib_dlsearch_path "$LT_SYS_LIBRARY_PATH" + func_dirname "$output" "/" "" - output_objdir="$func_dirname_result$objdir" + output_objdir=$func_dirname_result$objdir func_to_tool_file "$output_objdir/" tool_output_objdir=$func_to_tool_file_result # Create the object directory. @@ -6045,7 +7537,7 @@ func_mode_link () # Find all interdependent deplibs by searching for libraries # that are linked more than once (e.g. -la -lb -la) for deplib in $deplibs; do - if $opt_preserve_dup_deps ; then + if $opt_preserve_dup_deps; then case "$libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac @@ -6053,7 +7545,7 @@ func_mode_link () func_append libs " $deplib" done - if test "$linkmode" = lib; then + if test lib = "$linkmode"; then libs="$predeps $libs $compiler_lib_search_path $postdeps" # Compute libraries that are listed more than once in $predeps @@ -6085,7 +7577,7 @@ func_mode_link () case $file in *.la) ;; *) - func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" + func_fatal_help "libraries can '-dlopen' only libtool libraries: $file" ;; esac done @@ -6093,7 +7585,7 @@ func_mode_link () prog) compile_deplibs= finalize_deplibs= - alldeplibs=no + alldeplibs=false newdlfiles= newdlprefiles= passes="conv scan dlopen dlpreopen link" @@ -6105,29 +7597,29 @@ func_mode_link () for pass in $passes; do # The preopen pass in lib mode reverses $deplibs; put it back here # so that -L comes before libs that need it for instance... - if test "$linkmode,$pass" = "lib,link"; then + if test lib,link = "$linkmode,$pass"; then ## FIXME: Find the place where the list is rebuilt in the wrong ## order, and fix it there properly tmp_deplibs= for deplib in $deplibs; do tmp_deplibs="$deplib $tmp_deplibs" done - deplibs="$tmp_deplibs" + deplibs=$tmp_deplibs fi - if test "$linkmode,$pass" = "lib,link" || - test "$linkmode,$pass" = "prog,scan"; then - libs="$deplibs" + if test lib,link = "$linkmode,$pass" || + test prog,scan = "$linkmode,$pass"; then + libs=$deplibs deplibs= fi - if test "$linkmode" = prog; then + if test prog = "$linkmode"; then case $pass in - dlopen) libs="$dlfiles" ;; - dlpreopen) libs="$dlprefiles" ;; + dlopen) libs=$dlfiles ;; + dlpreopen) libs=$dlprefiles ;; link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; esac fi - if test "$linkmode,$pass" = "lib,dlpreopen"; then + if test lib,dlpreopen = "$linkmode,$pass"; then # Collect and forward deplibs of preopened libtool libs for lib in $dlprefiles; do # Ignore non-libtool-libs @@ -6148,26 +7640,26 @@ func_mode_link () esac done done - libs="$dlprefiles" + libs=$dlprefiles fi - if test "$pass" = dlopen; then + if test dlopen = "$pass"; then # Collect dlpreopened libraries - save_deplibs="$deplibs" + save_deplibs=$deplibs deplibs= fi for deplib in $libs; do lib= - found=no + found=false case $deplib in -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) - if test "$linkmode,$pass" = "prog,link"; then + if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append compiler_flags " $deplib" - if test "$linkmode" = lib ; then + if test lib = "$linkmode"; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; @@ -6177,13 +7669,13 @@ func_mode_link () continue ;; -l*) - if test "$linkmode" != lib && test "$linkmode" != prog; then - func_warning "\`-l' is ignored for archives/objects" + if test lib != "$linkmode" && test prog != "$linkmode"; then + func_warning "'-l' is ignored for archives/objects" continue fi func_stripname '-l' '' "$deplib" name=$func_stripname_result - if test "$linkmode" = lib; then + if test lib = "$linkmode"; then searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" else searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" @@ -6191,31 +7683,22 @@ func_mode_link () for searchdir in $searchdirs; do for search_ext in .la $std_shrext .so .a; do # Search the libtool library - lib="$searchdir/lib${name}${search_ext}" + lib=$searchdir/lib$name$search_ext if test -f "$lib"; then - if test "$search_ext" = ".la"; then - found=yes + if test .la = "$search_ext"; then + found=: else - found=no + found=false fi break 2 fi done done - if test "$found" != yes; then - # deplib doesn't seem to be a libtool library - if test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - deplibs="$deplib $deplibs" - test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" - fi - continue - else # deplib is a libtool library + if $found; then + # deplib is a libtool library # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, # We need to do some special things here, and not later. - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + if test yes = "$allow_libtool_libs_with_static_runtimes"; then case " $predeps $postdeps " in *" $deplib "*) if func_lalib_p "$lib"; then @@ -6223,19 +7706,19 @@ func_mode_link () old_library= func_source "$lib" for l in $old_library $library_names; do - ll="$l" + ll=$l done - if test "X$ll" = "X$old_library" ; then # only static version available - found=no + if test "X$ll" = "X$old_library"; then # only static version available + found=false func_dirname "$lib" "" "." - ladir="$func_dirname_result" + ladir=$func_dirname_result lib=$ladir/$old_library - if test "$linkmode,$pass" = "prog,link"; then + if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" - test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" + test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" fi continue fi @@ -6244,15 +7727,25 @@ func_mode_link () *) ;; esac fi + else + # deplib doesn't seem to be a libtool library + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" + fi + continue fi ;; # -l *.ltframework) - if test "$linkmode,$pass" = "prog,link"; then + if test prog,link = "$linkmode,$pass"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" - if test "$linkmode" = lib ; then + if test lib = "$linkmode"; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; @@ -6265,18 +7758,18 @@ func_mode_link () case $linkmode in lib) deplibs="$deplib $deplibs" - test "$pass" = conv && continue + test conv = "$pass" && continue newdependency_libs="$deplib $newdependency_libs" func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; prog) - if test "$pass" = conv; then + if test conv = "$pass"; then deplibs="$deplib $deplibs" continue fi - if test "$pass" = scan; then + if test scan = "$pass"; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" @@ -6287,13 +7780,13 @@ func_mode_link () func_append newlib_search_path " $func_resolve_sysroot_result" ;; *) - func_warning "\`-L' is ignored for archives/objects" + func_warning "'-L' is ignored for archives/objects" ;; esac # linkmode continue ;; # -L -R*) - if test "$pass" = link; then + if test link = "$pass"; then func_stripname '-R' '' "$deplib" func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result @@ -6311,7 +7804,7 @@ func_mode_link () lib=$func_resolve_sysroot_result ;; *.$libext) - if test "$pass" = conv; then + if test conv = "$pass"; then deplibs="$deplib $deplibs" continue fi @@ -6322,21 +7815,26 @@ func_mode_link () case " $dlpreconveniencelibs " in *" $deplib "*) ;; *) - valid_a_lib=no + valid_a_lib=false case $deplibs_check_method in match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ | $EGREP "$match_pattern_regex" > /dev/null; then - valid_a_lib=yes + valid_a_lib=: fi ;; pass_all) - valid_a_lib=yes + valid_a_lib=: ;; esac - if test "$valid_a_lib" != yes; then + if $valid_a_lib; then + echo + $ECHO "*** Warning: Linking the shared library $output against the" + $ECHO "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + else echo $ECHO "*** Warning: Trying to link with static lib archive $deplib." echo "*** I have the capability to make that library automatically link in when" @@ -6344,18 +7842,13 @@ func_mode_link () echo "*** shared version of the library, which you do not appear to have" echo "*** because the file extensions .$libext of this argument makes me believe" echo "*** that it is just a static archive that I should not use here." - else - echo - $ECHO "*** Warning: Linking the shared library $output against the" - $ECHO "*** static library $deplib is not portable!" - deplibs="$deplib $deplibs" fi ;; esac continue ;; prog) - if test "$pass" != link; then + if test link != "$pass"; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" @@ -6366,10 +7859,10 @@ func_mode_link () esac # linkmode ;; # *.$libext *.lo | *.$objext) - if test "$pass" = conv; then + if test conv = "$pass"; then deplibs="$deplib $deplibs" - elif test "$linkmode" = prog; then - if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then + elif test prog = "$linkmode"; then + if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then # If there is no dlopen support or we're linking statically, # we need to preload. func_append newdlprefiles " $deplib" @@ -6382,22 +7875,20 @@ func_mode_link () continue ;; %DEPLIBS%) - alldeplibs=yes + alldeplibs=: continue ;; esac # case $deplib - if test "$found" = yes || test -f "$lib"; then : - else - func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" - fi + $found || test -f "$lib" \ + || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'" # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$lib" \ - || func_fatal_error "\`$lib' is not a valid libtool archive" + || func_fatal_error "'$lib' is not a valid libtool archive" func_dirname "$lib" "" "." - ladir="$func_dirname_result" + ladir=$func_dirname_result dlname= dlopen= @@ -6427,30 +7918,30 @@ func_mode_link () done fi dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - if test "$linkmode,$pass" = "lib,link" || - test "$linkmode,$pass" = "prog,scan" || - { test "$linkmode" != prog && test "$linkmode" != lib; }; then + if test lib,link = "$linkmode,$pass" || + test prog,scan = "$linkmode,$pass" || + { test prog != "$linkmode" && test lib != "$linkmode"; }; then test -n "$dlopen" && func_append dlfiles " $dlopen" test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" fi - if test "$pass" = conv; then + if test conv = "$pass"; then # Only check for convenience libraries deplibs="$lib $deplibs" if test -z "$libdir"; then if test -z "$old_library"; then - func_fatal_error "cannot find name of link library for \`$lib'" + func_fatal_error "cannot find name of link library for '$lib'" fi # It is a libtool convenience library, so add in its objects. func_append convenience " $ladir/$objdir/$old_library" func_append old_convenience " $ladir/$objdir/$old_library" - elif test "$linkmode" != prog && test "$linkmode" != lib; then - func_fatal_error "\`$lib' is not a convenience library" + elif test prog != "$linkmode" && test lib != "$linkmode"; then + func_fatal_error "'$lib' is not a convenience library" fi tmp_libs= for deplib in $dependency_libs; do deplibs="$deplib $deplibs" - if $opt_preserve_dup_deps ; then + if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac @@ -6464,26 +7955,26 @@ func_mode_link () # Get the name of the library we link against. linklib= if test -n "$old_library" && - { test "$prefer_static_libs" = yes || - test "$prefer_static_libs,$installed" = "built,no"; }; then + { test yes = "$prefer_static_libs" || + test built,no = "$prefer_static_libs,$installed"; }; then linklib=$old_library else for l in $old_library $library_names; do - linklib="$l" + linklib=$l done fi if test -z "$linklib"; then - func_fatal_error "cannot find name of link library for \`$lib'" + func_fatal_error "cannot find name of link library for '$lib'" fi # This library was specified with -dlopen. - if test "$pass" = dlopen; then - if test -z "$libdir"; then - func_fatal_error "cannot -dlopen a convenience library: \`$lib'" - fi + if test dlopen = "$pass"; then + test -z "$libdir" \ + && func_fatal_error "cannot -dlopen a convenience library: '$lib'" if test -z "$dlname" || - test "$dlopen_support" != yes || - test "$build_libtool_libs" = no; then + test yes != "$dlopen_support" || + test no = "$build_libtool_libs" + then # If there is no dlname, no dlopen support or we're linking # statically, we need to preload. We also need to preload any # dependent libraries so libltdl's deplib preloader doesn't @@ -6497,40 +7988,40 @@ func_mode_link () # We need an absolute path. case $ladir in - [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;; *) abs_ladir=`cd "$ladir" && pwd` if test -z "$abs_ladir"; then - func_warning "cannot determine absolute directory name of \`$ladir'" + func_warning "cannot determine absolute directory name of '$ladir'" func_warning "passing it literally to the linker, although it might fail" - abs_ladir="$ladir" + abs_ladir=$ladir fi ;; esac func_basename "$lib" - laname="$func_basename_result" + laname=$func_basename_result # Find the relevant object directory and library name. - if test "X$installed" = Xyes; then + if test yes = "$installed"; then if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then - func_warning "library \`$lib' was moved." - dir="$ladir" - absdir="$abs_ladir" - libdir="$abs_ladir" + func_warning "library '$lib' was moved." + dir=$ladir + absdir=$abs_ladir + libdir=$abs_ladir else - dir="$lt_sysroot$libdir" - absdir="$lt_sysroot$libdir" + dir=$lt_sysroot$libdir + absdir=$lt_sysroot$libdir fi - test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes + test yes = "$hardcode_automatic" && avoidtemprpath=yes else if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then - dir="$ladir" - absdir="$abs_ladir" + dir=$ladir + absdir=$abs_ladir # Remove this search path later func_append notinst_path " $abs_ladir" else - dir="$ladir/$objdir" - absdir="$abs_ladir/$objdir" + dir=$ladir/$objdir + absdir=$abs_ladir/$objdir # Remove this search path later func_append notinst_path " $abs_ladir" fi @@ -6539,13 +8030,13 @@ func_mode_link () name=$func_stripname_result # This library was specified with -dlpreopen. - if test "$pass" = dlpreopen; then - if test -z "$libdir" && test "$linkmode" = prog; then - func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" + if test dlpreopen = "$pass"; then + if test -z "$libdir" && test prog = "$linkmode"; then + func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'" fi - case "$host" in + case $host in # special handling for platforms with PE-DLLs. - *cygwin* | *mingw* | *cegcc* ) + *cygwin* | *mingw* | *windows* | *cegcc* ) # Linker will automatically link against shared library if both # static and shared are present. Therefore, ensure we extract # symbols from the import library if a shared library is present @@ -6587,9 +8078,9 @@ func_mode_link () if test -z "$libdir"; then # Link the convenience library - if test "$linkmode" = lib; then + if test lib = "$linkmode"; then deplibs="$dir/$old_library $deplibs" - elif test "$linkmode,$pass" = "prog,link"; then + elif test prog,link = "$linkmode,$pass"; then compile_deplibs="$dir/$old_library $compile_deplibs" finalize_deplibs="$dir/$old_library $finalize_deplibs" else @@ -6599,14 +8090,14 @@ func_mode_link () fi - if test "$linkmode" = prog && test "$pass" != link; then + if test prog = "$linkmode" && test link != "$pass"; then func_append newlib_search_path " $ladir" deplibs="$lib $deplibs" - linkalldeplibs=no - if test "$link_all_deplibs" != no || test -z "$library_names" || - test "$build_libtool_libs" = no; then - linkalldeplibs=yes + linkalldeplibs=false + if test no != "$link_all_deplibs" || test -z "$library_names" || + test no = "$build_libtool_libs"; then + linkalldeplibs=: fi tmp_libs= @@ -6618,14 +8109,14 @@ func_mode_link () ;; esac # Need to link against all dependency_libs? - if test "$linkalldeplibs" = yes; then + if $linkalldeplibs; then deplibs="$deplib $deplibs" else # Need to hardcode shared library paths # or/and link against static libraries newdependency_libs="$deplib $newdependency_libs" fi - if $opt_preserve_dup_deps ; then + if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac @@ -6635,15 +8126,15 @@ func_mode_link () continue fi # $linkmode = prog... - if test "$linkmode,$pass" = "prog,link"; then + if test prog,link = "$linkmode,$pass"; then if test -n "$library_names" && - { { test "$prefer_static_libs" = no || - test "$prefer_static_libs,$installed" = "built,yes"; } || + { { test no = "$prefer_static_libs" || + test built,yes = "$prefer_static_libs,$installed"; } || test -z "$old_library"; }; then # We need to hardcode the library path - if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then + if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then # Make sure the rpath contains only unique directories. - case "$temp_rpath:" in + case $temp_rpath: in *"$absdir:"*) ;; *) func_append temp_rpath "$absdir:" ;; esac @@ -6672,9 +8163,9 @@ func_mode_link () esac fi # $linkmode,$pass = prog,link... - if test "$alldeplibs" = yes && - { test "$deplibs_check_method" = pass_all || - { test "$build_libtool_libs" = yes && + if $alldeplibs && + { test pass_all = "$deplibs_check_method" || + { test yes = "$build_libtool_libs" && test -n "$library_names"; }; }; then # We only need to search for static libraries continue @@ -6683,19 +8174,19 @@ func_mode_link () link_static=no # Whether the deplib will be linked statically use_static_libs=$prefer_static_libs - if test "$use_static_libs" = built && test "$installed" = yes; then + if test built = "$use_static_libs" && test yes = "$installed"; then use_static_libs=no fi if test -n "$library_names" && - { test "$use_static_libs" = no || test -z "$old_library"; }; then + { test no = "$use_static_libs" || test -z "$old_library"; }; then case $host in - *cygwin* | *mingw* | *cegcc*) + *cygwin* | *mingw* | *windows* | *cegcc* | *os2*) # No point in relinking DLLs because paths are not encoded func_append notinst_deplibs " $lib" need_relink=no ;; *) - if test "$installed" = no; then + if test no = "$installed"; then func_append notinst_deplibs " $lib" need_relink=yes fi @@ -6705,24 +8196,24 @@ func_mode_link () # Warn about portability, can't link against -module's on some # systems (darwin). Don't bleat about dlopened modules though! - dlopenmodule="" + dlopenmodule= for dlpremoduletest in $dlprefiles; do if test "X$dlpremoduletest" = "X$lib"; then - dlopenmodule="$dlpremoduletest" + dlopenmodule=$dlpremoduletest break fi done - if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then + if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then echo - if test "$linkmode" = prog; then + if test prog = "$linkmode"; then $ECHO "*** Warning: Linking the executable $output against the loadable module" else $ECHO "*** Warning: Linking the shared library $output against the loadable module" fi $ECHO "*** $linklib is not portable!" fi - if test "$linkmode" = lib && - test "$hardcode_into_libs" = yes; then + if test lib = "$linkmode" && + test yes = "$hardcode_into_libs"; then # Hardcode the library path. # Skip directories that are in the system default run-time # search path. @@ -6750,43 +8241,43 @@ func_mode_link () # figure out the soname set dummy $library_names shift - realname="$1" + realname=$1 shift libname=`eval "\\$ECHO \"$libname_spec\""` # use dlname if we got it. it's perfectly good, no? if test -n "$dlname"; then - soname="$dlname" + soname=$dlname elif test -n "$soname_spec"; then # bleh windows case $host in - *cygwin* | mingw* | *cegcc*) + *cygwin* | mingw* | *windows* | *cegcc*) # | *os2* # SDL customization: removed OS/2 versioning support. func_arith $current - $age major=$func_arith_result - versuffix="-$major" + versuffix=-$major ;; esac eval soname=\"$soname_spec\" else - soname="$realname" + soname=$realname fi # Make a new name for the extract_expsyms_cmds to use - soroot="$soname" + soroot=$soname func_basename "$soroot" - soname="$func_basename_result" + soname=$func_basename_result func_stripname 'lib' '.dll' "$soname" newlib=libimp-$func_stripname_result.a # If the library has no export list, then create one now if test -f "$output_objdir/$soname-def"; then : else - func_verbose "extracting exported symbol list from \`$soname'" + func_verbose "extracting exported symbol list from '$soname'" func_execute_cmds "$extract_expsyms_cmds" 'exit $?' fi # Create $newlib if test -f "$output_objdir/$newlib"; then :; else - func_verbose "generating import library for \`$soname'" + func_verbose "generating import library for '$soname'" func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' fi # make sure the library variables are pointing to the new library @@ -6794,58 +8285,58 @@ func_mode_link () linklib=$newlib fi # test -n "$old_archive_from_expsyms_cmds" - if test "$linkmode" = prog || test "$opt_mode" != relink; then + if test prog = "$linkmode" || test relink != "$opt_mode"; then add_shlibpath= add_dir= add= lib_linked=yes case $hardcode_action in immediate | unsupported) - if test "$hardcode_direct" = no; then - add="$dir/$linklib" + if test no = "$hardcode_direct"; then + add=$dir/$linklib case $host in - *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; - *-*-sysv4*uw2*) add_dir="-L$dir" ;; + *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;; + *-*-sysv4*uw2*) add_dir=-L$dir ;; *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ - *-*-unixware7*) add_dir="-L$dir" ;; + *-*-unixware7*) add_dir=-L$dir ;; *-*-darwin* ) - # if the lib is a (non-dlopened) module then we can not + # if the lib is a (non-dlopened) module then we cannot # link against it, someone is ignoring the earlier warnings if /usr/bin/file -L $add 2> /dev/null | - $GREP ": [^:]* bundle" >/dev/null ; then + $GREP ": [^:]* bundle" >/dev/null; then if test "X$dlopenmodule" != "X$lib"; then $ECHO "*** Warning: lib $linklib is a module, not a shared library" - if test -z "$old_library" ; then + if test -z "$old_library"; then echo echo "*** And there doesn't seem to be a static archive available" echo "*** The link will probably fail, sorry" else - add="$dir/$old_library" + add=$dir/$old_library fi elif test -n "$old_library"; then - add="$dir/$old_library" + add=$dir/$old_library fi fi esac - elif test "$hardcode_minus_L" = no; then + elif test no = "$hardcode_minus_L"; then case $host in - *-*-sunos*) add_shlibpath="$dir" ;; + *-*-sunos*) add_shlibpath=$dir ;; esac - add_dir="-L$dir" - add="-l$name" - elif test "$hardcode_shlibpath_var" = no; then - add_shlibpath="$dir" - add="-l$name" + add_dir=-L$dir + add=-l$name + elif test no = "$hardcode_shlibpath_var"; then + add_shlibpath=$dir + add=-l$name else lib_linked=no fi ;; relink) - if test "$hardcode_direct" = yes && - test "$hardcode_direct_absolute" = no; then - add="$dir/$linklib" - elif test "$hardcode_minus_L" = yes; then - add_dir="-L$absdir" + if test yes = "$hardcode_direct" && + test no = "$hardcode_direct_absolute"; then + add=$dir/$linklib + elif test yes = "$hardcode_minus_L"; then + add_dir=-L$absdir # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in @@ -6854,10 +8345,10 @@ func_mode_link () ;; esac fi - add="-l$name" - elif test "$hardcode_shlibpath_var" = yes; then - add_shlibpath="$dir" - add="-l$name" + add=-l$name + elif test yes = "$hardcode_shlibpath_var"; then + add_shlibpath=$dir + add=-l$name else lib_linked=no fi @@ -6865,7 +8356,7 @@ func_mode_link () *) lib_linked=no ;; esac - if test "$lib_linked" != yes; then + if test yes != "$lib_linked"; then func_fatal_configuration "unsupported hardcode properties" fi @@ -6875,15 +8366,15 @@ func_mode_link () *) func_append compile_shlibpath "$add_shlibpath:" ;; esac fi - if test "$linkmode" = prog; then + if test prog = "$linkmode"; then test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" test -n "$add" && compile_deplibs="$add $compile_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" - if test "$hardcode_direct" != yes && - test "$hardcode_minus_L" != yes && - test "$hardcode_shlibpath_var" = yes; then + if test yes != "$hardcode_direct" && + test yes != "$hardcode_minus_L" && + test yes = "$hardcode_shlibpath_var"; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; @@ -6892,33 +8383,33 @@ func_mode_link () fi fi - if test "$linkmode" = prog || test "$opt_mode" = relink; then + if test prog = "$linkmode" || test relink = "$opt_mode"; then add_shlibpath= add_dir= add= # Finalize command for both is simple: just hardcode it. - if test "$hardcode_direct" = yes && - test "$hardcode_direct_absolute" = no; then - add="$libdir/$linklib" - elif test "$hardcode_minus_L" = yes; then - add_dir="-L$libdir" - add="-l$name" - elif test "$hardcode_shlibpath_var" = yes; then + if test yes = "$hardcode_direct" && + test no = "$hardcode_direct_absolute"; then + add=$libdir/$linklib + elif test yes = "$hardcode_minus_L"; then + add_dir=-L$libdir + add=-l$name + elif test yes = "$hardcode_shlibpath_var"; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac - add="-l$name" - elif test "$hardcode_automatic" = yes; then + add=-l$name + elif test yes = "$hardcode_automatic"; then if test -n "$inst_prefix_dir" && - test -f "$inst_prefix_dir$libdir/$linklib" ; then - add="$inst_prefix_dir$libdir/$linklib" + test -f "$inst_prefix_dir$libdir/$linklib"; then + add=$inst_prefix_dir$libdir/$linklib else - add="$libdir/$linklib" + add=$libdir/$linklib fi else # We cannot seem to hardcode it, guess we'll fake it. - add_dir="-L$libdir" + add_dir=-L$libdir # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in @@ -6927,10 +8418,10 @@ func_mode_link () ;; esac fi - add="-l$name" + add=-l$name fi - if test "$linkmode" = prog; then + if test prog = "$linkmode"; then test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" test -n "$add" && finalize_deplibs="$add $finalize_deplibs" else @@ -6938,43 +8429,43 @@ func_mode_link () test -n "$add" && deplibs="$add $deplibs" fi fi - elif test "$linkmode" = prog; then + elif test prog = "$linkmode"; then # Here we assume that one of hardcode_direct or hardcode_minus_L # is not unsupported. This is valid on all known static and # shared platforms. - if test "$hardcode_direct" != unsupported; then - test -n "$old_library" && linklib="$old_library" + if test unsupported != "$hardcode_direct"; then + test -n "$old_library" && linklib=$old_library compile_deplibs="$dir/$linklib $compile_deplibs" finalize_deplibs="$dir/$linklib $finalize_deplibs" else compile_deplibs="-l$name -L$dir $compile_deplibs" finalize_deplibs="-l$name -L$dir $finalize_deplibs" fi - elif test "$build_libtool_libs" = yes; then + elif test yes = "$build_libtool_libs"; then # Not a shared library - if test "$deplibs_check_method" != pass_all; then + if test pass_all != "$deplibs_check_method"; then # We're trying link a shared library against a static one # but the system doesn't support it. # Just print a warning and add the library to dependency_libs so # that the program can be linked against the static library. echo - $ECHO "*** Warning: This system can not link to static lib archive $lib." + $ECHO "*** Warning: This system cannot link to static lib archive $lib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have." - if test "$module" = yes; then + if test yes = "$module"; then echo "*** But as you try to build a module library, libtool will still create " echo "*** a static module, that should work as long as the dlopening application" echo "*** is linked with the -dlopen flag to resolve symbols at runtime." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" - echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** lists from a program, using 'nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." - echo "*** \`nm' from GNU binutils and a full rebuild may help." + echo "*** 'nm' from GNU binutils and a full rebuild may help." fi - if test "$build_old_libs" = no; then + if test no = "$build_old_libs"; then build_libtool_libs=module build_old_libs=yes else @@ -6987,11 +8478,11 @@ func_mode_link () fi fi # link shared/static library? - if test "$linkmode" = lib; then + if test lib = "$linkmode"; then if test -n "$dependency_libs" && - { test "$hardcode_into_libs" != yes || - test "$build_old_libs" = yes || - test "$link_static" = yes; }; then + { test yes != "$hardcode_into_libs" || + test yes = "$build_old_libs" || + test yes = "$link_static"; }; then # Extract -R from dependency_libs temp_deplibs= for libdir in $dependency_libs; do @@ -7005,12 +8496,12 @@ func_mode_link () *) func_append temp_deplibs " $libdir";; esac done - dependency_libs="$temp_deplibs" + dependency_libs=$temp_deplibs fi func_append newlib_search_path " $absdir" # Link against this library - test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs" # ... and its dependency_libs tmp_libs= for deplib in $dependency_libs; do @@ -7020,7 +8511,7 @@ func_mode_link () func_resolve_sysroot "$func_stripname_result";; *) func_resolve_sysroot "$deplib" ;; esac - if $opt_preserve_dup_deps ; then + if $opt_preserve_dup_deps; then case "$tmp_libs " in *" $func_resolve_sysroot_result "*) func_append specialdeplibs " $func_resolve_sysroot_result" ;; @@ -7029,12 +8520,12 @@ func_mode_link () func_append tmp_libs " $func_resolve_sysroot_result" done - if test "$link_all_deplibs" != no; then + if test no != "$link_all_deplibs"; then # Add the search paths of all dependency libraries for deplib in $dependency_libs; do path= case $deplib in - -L*) path="$deplib" ;; + -L*) path=$deplib ;; *.la) func_resolve_sysroot "$deplib" deplib=$func_resolve_sysroot_result @@ -7042,12 +8533,12 @@ func_mode_link () dir=$func_dirname_result # We need an absolute path. case $dir in - [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; + [\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then - func_warning "cannot determine absolute directory name of \`$dir'" - absdir="$dir" + func_warning "cannot determine absolute directory name of '$dir'" + absdir=$dir fi ;; esac @@ -7055,35 +8546,35 @@ func_mode_link () case $host in *-*-darwin*) depdepl= - eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` - if test -n "$deplibrary_names" ; then - for tmp in $deplibrary_names ; do + eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names"; then + for tmp in $deplibrary_names; do depdepl=$tmp done - if test -f "$absdir/$objdir/$depdepl" ; then - depdepl="$absdir/$objdir/$depdepl" - darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + if test -f "$absdir/$objdir/$depdepl"; then + depdepl=$absdir/$objdir/$depdepl + darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` if test -z "$darwin_install_name"; then - darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + darwin_install_name=`$OTOOL64 -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` fi - func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" - func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}" + func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl" + func_append linker_flags " -dylib_file $darwin_install_name:$depdepl" path= fi fi ;; *) - path="-L$absdir/$objdir" + path=-L$absdir/$objdir ;; esac else - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` test -z "$libdir" && \ - func_fatal_error "\`$deplib' is not a valid libtool archive" + func_fatal_error "'$deplib' is not a valid libtool archive" test "$absdir" != "$libdir" && \ - func_warning "\`$deplib' seems to be moved" + func_warning "'$deplib' seems to be moved" - path="-L$absdir" + path=-L$absdir fi ;; esac @@ -7095,23 +8586,23 @@ func_mode_link () fi # link_all_deplibs != no fi # linkmode = lib done # for deplib in $libs - if test "$pass" = link; then - if test "$linkmode" = "prog"; then + if test link = "$pass"; then + if test prog = "$linkmode"; then compile_deplibs="$new_inherited_linker_flags $compile_deplibs" finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" else compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` fi fi - dependency_libs="$newdependency_libs" - if test "$pass" = dlpreopen; then + dependency_libs=$newdependency_libs + if test dlpreopen = "$pass"; then # Link the dlpreopened libraries before other libraries for deplib in $save_deplibs; do deplibs="$deplib $deplibs" done fi - if test "$pass" != dlopen; then - if test "$pass" != conv; then + if test dlopen != "$pass"; then + test conv = "$pass" || { # Make sure lib_search_path contains only unique directories. lib_search_path= for dir in $newlib_search_path; do @@ -7121,12 +8612,12 @@ func_mode_link () esac done newlib_search_path= - fi + } - if test "$linkmode,$pass" != "prog,link"; then - vars="deplibs" - else + if test prog,link = "$linkmode,$pass"; then vars="compile_deplibs finalize_deplibs" + else + vars=deplibs fi for var in $vars dependency_libs; do # Add libraries to $var in reverse order @@ -7184,62 +8675,93 @@ func_mode_link () eval $var=\"$tmp_libs\" done # for var fi + + # Add Sun CC postdeps if required: + test CXX = "$tagname" && { + case $host_os in + linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C++ 5.9 + func_suncc_cstd_abi + + if test no != "$suncc_use_cstd_abi"; then + func_append postdeps ' -library=Cstd -library=Crun' + fi + ;; + esac + ;; + + solaris*) + func_cc_basename "$CC" + case $func_cc_basename_result in + CC* | sunCC*) + func_suncc_cstd_abi + + if test no != "$suncc_use_cstd_abi"; then + func_append postdeps ' -library=Cstd -library=Crun' + fi + ;; + esac + ;; + esac + } + # Last step: remove runtime libs from dependency_libs # (they stay in deplibs) tmp_libs= - for i in $dependency_libs ; do + for i in $dependency_libs; do case " $predeps $postdeps $compiler_lib_search_path " in *" $i "*) - i="" + i= ;; esac - if test -n "$i" ; then + if test -n "$i"; then func_append tmp_libs " $i" fi done dependency_libs=$tmp_libs done # for pass - if test "$linkmode" = prog; then - dlfiles="$newdlfiles" + if test prog = "$linkmode"; then + dlfiles=$newdlfiles fi - if test "$linkmode" = prog || test "$linkmode" = lib; then - dlprefiles="$newdlprefiles" + if test prog = "$linkmode" || test lib = "$linkmode"; then + dlprefiles=$newdlprefiles fi case $linkmode in oldlib) - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - func_warning "\`-dlopen' is ignored for archives" + if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then + func_warning "'-dlopen' is ignored for archives" fi case " $deplibs" in *\ -l* | *\ -L*) - func_warning "\`-l' and \`-L' are ignored for archives" ;; + func_warning "'-l' and '-L' are ignored for archives" ;; esac test -n "$rpath" && \ - func_warning "\`-rpath' is ignored for archives" + func_warning "'-rpath' is ignored for archives" test -n "$xrpath" && \ - func_warning "\`-R' is ignored for archives" + func_warning "'-R' is ignored for archives" test -n "$vinfo" && \ - func_warning "\`-version-info/-version-number' is ignored for archives" + func_warning "'-version-info/-version-number' is ignored for archives" test -n "$release" && \ - func_warning "\`-release' is ignored for archives" + func_warning "'-release' is ignored for archives" test -n "$export_symbols$export_symbols_regex" && \ - func_warning "\`-export-symbols' is ignored for archives" + func_warning "'-export-symbols' is ignored for archives" # Now set the variables for building old libraries. build_libtool_libs=no - oldlibs="$output" + oldlibs=$output func_append objs "$old_deplibs" ;; lib) - # Make sure we only generate libraries of the form `libNAME.la'. + # Make sure we only generate libraries of the form 'libNAME.la'. case $outputname in lib*) func_stripname 'lib' '.la' "$outputname" @@ -7248,10 +8770,10 @@ func_mode_link () eval libname=\"$libname_spec\" ;; *) - test "$module" = no && \ - func_fatal_help "libtool library \`$output' must begin with \`lib'" + test no = "$module" \ + && func_fatal_help "libtool library '$output' must begin with 'lib'" - if test "$need_lib_prefix" != no; then + if test no != "$need_lib_prefix"; then # Add the "lib" prefix for modules if required func_stripname '' '.la' "$outputname" name=$func_stripname_result @@ -7265,8 +8787,8 @@ func_mode_link () esac if test -n "$objs"; then - if test "$deplibs_check_method" != pass_all; then - func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" + if test pass_all != "$deplibs_check_method"; then + func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs" else echo $ECHO "*** Warning: Linking the shared library $output against the non-libtool" @@ -7275,21 +8797,21 @@ func_mode_link () fi fi - test "$dlself" != no && \ - func_warning "\`-dlopen self' is ignored for libtool libraries" + test no = "$dlself" \ + || func_warning "'-dlopen self' is ignored for libtool libraries" set dummy $rpath shift - test "$#" -gt 1 && \ - func_warning "ignoring multiple \`-rpath's for a libtool library" + test 1 -lt "$#" \ + && func_warning "ignoring multiple '-rpath's for a libtool library" - install_libdir="$1" + install_libdir=$1 oldlibs= if test -z "$rpath"; then - if test "$build_libtool_libs" = yes; then + if test yes = "$build_libtool_libs"; then # Building a libtool convenience library. - # Some compilers have problems with a `.al' extension so + # Some compilers have problems with a '.al' extension so # convenience libraries should have the same extension an # archive normally would. oldlibs="$output_objdir/$libname.$libext $oldlibs" @@ -7298,20 +8820,20 @@ func_mode_link () fi test -n "$vinfo" && \ - func_warning "\`-version-info/-version-number' is ignored for convenience libraries" + func_warning "'-version-info/-version-number' is ignored for convenience libraries" test -n "$release" && \ - func_warning "\`-release' is ignored for convenience libraries" + func_warning "'-release' is ignored for convenience libraries" else # Parse the version information argument. - save_ifs="$IFS"; IFS=':' + save_ifs=$IFS; IFS=: set dummy $vinfo 0 0 0 shift - IFS="$save_ifs" + IFS=$save_ifs test -n "$7" && \ - func_fatal_help "too many parameters to \`-version-info'" + func_fatal_help "too many parameters to '-version-info'" # convert absolute version numbers to libtool ages # this retains compatibility with .la files and attempts @@ -7319,42 +8841,42 @@ func_mode_link () case $vinfo_number in yes) - number_major="$1" - number_minor="$2" - number_revision="$3" + number_major=$1 + number_minor=$2 + number_revision=$3 # # There are really only two kinds -- those that # use the current revision as the major version # and those that subtract age and use age as # a minor version. But, then there is irix - # which has an extra 1 added just for fun + # that has an extra 1 added just for fun # case $version_type in # correct linux to gnu/linux during the next big refactor - darwin|linux|osf|windows|none) + darwin|freebsd-elf|linux|midnightbsd-elf|osf|windows|none) func_arith $number_major + $number_minor current=$func_arith_result - age="$number_minor" - revision="$number_revision" + age=$number_minor + revision=$number_revision ;; - freebsd-aout|freebsd-elf|qnx|sunos) - current="$number_major" - revision="$number_minor" - age="0" + freebsd-aout|qnx|sco|sunos) + current=$number_major + revision=$number_minor + age=0 ;; irix|nonstopux) func_arith $number_major + $number_minor current=$func_arith_result - age="$number_minor" - revision="$number_minor" + age=$number_minor + revision=$number_minor lt_irix_increment=no ;; esac ;; no) - current="$1" - revision="$2" - age="$3" + current=$1 + revision=$2 + age=$3 ;; esac @@ -7362,30 +8884,30 @@ func_mode_link () case $current in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) - func_error "CURRENT \`$current' must be a nonnegative integer" - func_fatal_error "\`$vinfo' is not valid version information" + func_error "CURRENT '$current' must be a nonnegative integer" + func_fatal_error "'$vinfo' is not valid version information" ;; esac case $revision in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) - func_error "REVISION \`$revision' must be a nonnegative integer" - func_fatal_error "\`$vinfo' is not valid version information" + func_error "REVISION '$revision' must be a nonnegative integer" + func_fatal_error "'$vinfo' is not valid version information" ;; esac case $age in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) - func_error "AGE \`$age' must be a nonnegative integer" - func_fatal_error "\`$vinfo' is not valid version information" + func_error "AGE '$age' must be a nonnegative integer" + func_fatal_error "'$vinfo' is not valid version information" ;; esac if test "$age" -gt "$current"; then - func_error "AGE \`$age' is greater than the current interface number \`$current'" - func_fatal_error "\`$vinfo' is not valid version information" + func_error "AGE '$age' is greater than the current interface number '$current'" + func_fatal_error "'$vinfo' is not valid version information" fi # Calculate the version variables. @@ -7400,26 +8922,36 @@ func_mode_link () # verstring for coding it into the library header func_arith $current - $age major=.$func_arith_result - versuffix="$major.$age.$revision" + versuffix=$major.$age.$revision # Darwin ld doesn't like 0 for these options... func_arith $current + 1 minor_current=$func_arith_result - xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" + xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + # On Darwin other compilers + case $CC in + nagfor*) + verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" + ;; + *) + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + esac ;; freebsd-aout) - major=".$current" - versuffix=".$current.$revision"; + major=.$current + versuffix=.$current.$revision ;; - freebsd-elf) - major=".$current" - versuffix=".$current" + freebsd-elf | midnightbsd-elf) + func_arith $current - $age + major=.$func_arith_result + versuffix=$major.$age.$revision ;; irix | nonstopux) - if test "X$lt_irix_increment" = "Xno"; then + if test no = "$lt_irix_increment"; then func_arith $current - $age else func_arith $current - $age + 1 @@ -7430,69 +8962,74 @@ func_mode_link () nonstopux) verstring_prefix=nonstopux ;; *) verstring_prefix=sgi ;; esac - verstring="$verstring_prefix$major.$revision" + verstring=$verstring_prefix$major.$revision # Add in all the interfaces that we are compatible with. loop=$revision - while test "$loop" -ne 0; do + while test 0 -ne "$loop"; do func_arith $revision - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result - verstring="$verstring_prefix$major.$iface:$verstring" + verstring=$verstring_prefix$major.$iface:$verstring done - # Before this point, $major must not contain `.'. + # Before this point, $major must not contain '.'. major=.$major - versuffix="$major.$revision" + versuffix=$major.$revision ;; linux) # correct to gnu/linux during the next big refactor func_arith $current - $age major=.$func_arith_result - versuffix="$major.$age.$revision" + versuffix=$major.$age.$revision ;; osf) func_arith $current - $age major=.$func_arith_result - versuffix=".$current.$age.$revision" - verstring="$current.$age.$revision" + versuffix=.$current.$age.$revision + verstring=$current.$age.$revision # Add in all the interfaces that we are compatible with. loop=$age - while test "$loop" -ne 0; do + while test 0 -ne "$loop"; do func_arith $current - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result - verstring="$verstring:${iface}.0" + verstring=$verstring:$iface.0 done # Make executables depend on our current version. - func_append verstring ":${current}.0" + func_append verstring ":$current.0" ;; qnx) - major=".$current" - versuffix=".$current" + major=.$current + versuffix=.$current + ;; + + sco) + major=.$current + versuffix=.$current ;; sunos) - major=".$current" - versuffix=".$current.$revision" + major=.$current + versuffix=.$current.$revision ;; windows) # Use '-' rather than '.', since we only want one - # extension on DOS 8.3 filesystems. + # extension on DOS 8.3 file systems. func_arith $current - $age major=$func_arith_result - versuffix="-$major" + versuffix=-$major ;; *) - func_fatal_configuration "unknown library version type \`$version_type'" + func_fatal_configuration "unknown library version type '$version_type'" ;; esac @@ -7506,42 +9043,45 @@ func_mode_link () verstring= ;; *) - verstring="0.0" + verstring=0.0 ;; esac - if test "$need_version" = no; then + if test no = "$need_version"; then versuffix= else - versuffix=".0.0" + versuffix=.0.0 fi fi # Remove version info from name if versioning should be avoided - if test "$avoid_version" = yes && test "$need_version" = no; then + if test yes,no = "$avoid_version,$need_version"; then major= versuffix= - verstring="" + verstring= fi # Check to see if the archive will have undefined symbols. - if test "$allow_undefined" = yes; then - if test "$allow_undefined_flag" = unsupported; then - func_warning "undefined symbols not allowed in $host shared libraries" - build_libtool_libs=no - build_old_libs=yes + if test yes = "$allow_undefined"; then + if test unsupported = "$allow_undefined_flag"; then + if test yes = "$build_old_libs"; then + func_warning "undefined symbols not allowed in $host shared libraries; building static only" + build_libtool_libs=no + else + func_fatal_error "can't build $host shared library unless -no-undefined is specified" + fi fi else # Don't allow undefined symbols. - allow_undefined_flag="$no_undefined_flag" + allow_undefined_flag=$no_undefined_flag fi fi - func_generate_dlsyms "$libname" "$libname" "yes" + func_generate_dlsyms "$libname" "$libname" : func_append libobjs " $symfileobj" - test "X$libobjs" = "X " && libobjs= + test " " = "$libobjs" && libobjs= - if test "$opt_mode" != relink; then + if test relink != "$opt_mode"; then # Remove our outputs, but don't remove object files since they # may have been created when compiling PIC objects. removelist= @@ -7550,8 +9090,8 @@ func_mode_link () case $p in *.$objext | *.gcno) ;; - $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) - if test "X$precious_files_regex" != "X"; then + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*) + if test -n "$precious_files_regex"; then if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 then continue @@ -7567,11 +9107,11 @@ func_mode_link () fi # Now set the variables for building old libraries. - if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then func_append oldlibs " $output_objdir/$libname.$libext" # Transform .lo files to .o files. - oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP` + oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP` fi # Eliminate all temporary directories. @@ -7592,13 +9132,13 @@ func_mode_link () *) func_append finalize_rpath " $libdir" ;; esac done - if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then + if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then dependency_libs="$temp_xrpath $dependency_libs" fi fi # Make sure dlfiles contains only unique files that won't be dlpreopened - old_dlfiles="$dlfiles" + old_dlfiles=$dlfiles dlfiles= for lib in $old_dlfiles; do case " $dlprefiles $dlfiles " in @@ -7608,7 +9148,7 @@ func_mode_link () done # Make sure dlprefiles contains only unique files - old_dlprefiles="$dlprefiles" + old_dlprefiles=$dlprefiles dlprefiles= for lib in $old_dlprefiles; do case "$dlprefiles " in @@ -7617,10 +9157,10 @@ func_mode_link () esac done - if test "$build_libtool_libs" = yes; then + if test yes = "$build_libtool_libs"; then if test -n "$rpath"; then case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) + *-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) # these systems don't actually have a c library (as such)! ;; *-*-rhapsody* | *-*-darwin1.[012]) @@ -7630,7 +9170,7 @@ func_mode_link () *-*-netbsd*) # Don't link with libc until the a.out ld.so is fixed. ;; - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-midnightbsd*) # Do not include libc due to us having libc/libc_r. ;; *-*-sco3.2v5* | *-*-sco5v6*) @@ -7641,7 +9181,7 @@ func_mode_link () ;; *) # Add libc to deplibs on all other systems if necessary. - if test "$build_libtool_need_lc" = "yes"; then + if test yes = "$build_libtool_need_lc"; then func_append deplibs " -lc" fi ;; @@ -7657,9 +9197,9 @@ func_mode_link () # I'm not sure if I'm treating the release correctly. I think # release should show up in the -l (ie -lgmp5) so we don't want to # add it in twice. Is that correct? - release="" - versuffix="" - major="" + release= + versuffix= + major= newdeplibs= droppeddeps=no case $deplibs_check_method in @@ -7688,20 +9228,20 @@ EOF -l*) func_stripname -l '' "$i" name=$func_stripname_result - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + if test yes = "$allow_libtool_libs_with_static_runtimes"; then case " $predeps $postdeps " in *" $i "*) func_append newdeplibs " $i" - i="" + i= ;; esac fi - if test -n "$i" ; then + if test -n "$i"; then libname=`eval "\\$ECHO \"$libname_spec\""` deplib_matches=`eval "\\$ECHO \"$library_names_spec\""` set dummy $deplib_matches; shift deplib_match=$1 - if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then + if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0; then func_append newdeplibs " $i" else droppeddeps=yes @@ -7731,20 +9271,20 @@ EOF $opt_dry_run || $RM conftest if $LTCC $LTCFLAGS -o conftest conftest.c $i; then ldd_output=`ldd conftest` - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + if test yes = "$allow_libtool_libs_with_static_runtimes"; then case " $predeps $postdeps " in *" $i "*) func_append newdeplibs " $i" - i="" + i= ;; esac fi - if test -n "$i" ; then + if test -n "$i"; then libname=`eval "\\$ECHO \"$libname_spec\""` deplib_matches=`eval "\\$ECHO \"$library_names_spec\""` set dummy $deplib_matches; shift deplib_match=$1 - if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then + if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0; then func_append newdeplibs " $i" else droppeddeps=yes @@ -7781,24 +9321,24 @@ EOF -l*) func_stripname -l '' "$a_deplib" name=$func_stripname_result - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + if test yes = "$allow_libtool_libs_with_static_runtimes"; then case " $predeps $postdeps " in *" $a_deplib "*) func_append newdeplibs " $a_deplib" - a_deplib="" + a_deplib= ;; esac fi - if test -n "$a_deplib" ; then + if test -n "$a_deplib"; then libname=`eval "\\$ECHO \"$libname_spec\""` if test -n "$file_magic_glob"; then libnameglob=`func_echo_all "$libname" | $SED -e $file_magic_glob` else libnameglob=$libname fi - test "$want_nocaseglob" = yes && nocaseglob=`shopt -p nocaseglob` + test yes = "$want_nocaseglob" && nocaseglob=`shopt -p nocaseglob` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do - if test "$want_nocaseglob" = yes; then + if test yes = "$want_nocaseglob"; then shopt -s nocaseglob potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` $nocaseglob @@ -7816,25 +9356,25 @@ EOF # We might still enter an endless loop, since a link # loop can be closed while we follow links, # but so what? - potlib="$potent_lib" + potlib=$potent_lib while test -h "$potlib" 2>/dev/null; do - potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` + potliblink=`ls -ld $potlib | $SED 's/.* -> //'` case $potliblink in - [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; - *) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";; + [\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;; + *) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";; esac done if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | $SED -e 10q | $EGREP "$file_magic_regex" > /dev/null; then func_append newdeplibs " $a_deplib" - a_deplib="" + a_deplib= break 2 fi done done fi - if test -n "$a_deplib" ; then + if test -n "$a_deplib"; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." @@ -7842,7 +9382,7 @@ EOF echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" - if test -z "$potlib" ; then + if test -z "$potlib"; then $ECHO "*** with $libname but no candidates were found. (...for file magic test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" @@ -7865,30 +9405,30 @@ EOF -l*) func_stripname -l '' "$a_deplib" name=$func_stripname_result - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then + if test yes = "$allow_libtool_libs_with_static_runtimes"; then case " $predeps $postdeps " in *" $a_deplib "*) func_append newdeplibs " $a_deplib" - a_deplib="" + a_deplib= ;; esac fi - if test -n "$a_deplib" ; then + if test -n "$a_deplib"; then libname=`eval "\\$ECHO \"$libname_spec\""` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do potential_libs=`ls $i/$libname[.-]* 2>/dev/null` for potent_lib in $potential_libs; do - potlib="$potent_lib" # see symlink-check above in file_magic test + potlib=$potent_lib # see symlink-check above in file_magic test if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ $EGREP "$match_pattern_regex" > /dev/null; then func_append newdeplibs " $a_deplib" - a_deplib="" + a_deplib= break 2 fi done done fi - if test -n "$a_deplib" ; then + if test -n "$a_deplib"; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." @@ -7896,7 +9436,7 @@ EOF echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" - if test -z "$potlib" ; then + if test -z "$potlib"; then $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" @@ -7912,18 +9452,18 @@ EOF done # Gone through all deplibs. ;; none | unknown | *) - newdeplibs="" + newdeplibs= tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then - for i in $predeps $postdeps ; do + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + for i in $predeps $postdeps; do # can't use Xsed below, because $i might contain '/' - tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"` + tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"` done fi case $tmp_deplibs in *[!\ \ ]*) echo - if test "X$deplibs_check_method" = "Xnone"; then + if test none = "$deplibs_check_method"; then echo "*** Warning: inter-library dependencies are not supported in this platform." else echo "*** Warning: inter-library dependencies are not known to be supported." @@ -7947,8 +9487,8 @@ EOF ;; esac - if test "$droppeddeps" = yes; then - if test "$module" = yes; then + if test yes = "$droppeddeps"; then + if test yes = "$module"; then echo echo "*** Warning: libtool could not satisfy all declared inter-library" $ECHO "*** dependencies of module $libname. Therefore, libtool will create" @@ -7957,12 +9497,12 @@ EOF if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" - echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** lists from a program, using 'nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." - echo "*** \`nm' from GNU binutils and a full rebuild may help." + echo "*** 'nm' from GNU binutils and a full rebuild may help." fi - if test "$build_old_libs" = no; then - oldlibs="$output_objdir/$libname.$libext" + if test no = "$build_old_libs"; then + oldlibs=$output_objdir/$libname.$libext build_libtool_libs=module build_old_libs=yes else @@ -7973,14 +9513,14 @@ EOF echo "*** automatically added whenever a program is linked with this library" echo "*** or is declared to -dlopen it." - if test "$allow_undefined" = no; then + if test no = "$allow_undefined"; then echo echo "*** Since this library must not contain undefined symbols," echo "*** because either the platform does not support them or" echo "*** it was explicitly requested with -no-undefined," echo "*** libtool will only create a static version of it." - if test "$build_old_libs" = no; then - oldlibs="$output_objdir/$libname.$libext" + if test no = "$build_old_libs"; then + oldlibs=$output_objdir/$libname.$libext build_libtool_libs=module build_old_libs=yes else @@ -8026,7 +9566,7 @@ EOF *) func_append new_libs " $deplib" ;; esac done - deplibs="$new_libs" + deplibs=$new_libs # All the library-specific variables (install_libdir is set above). library_names= @@ -8034,25 +9574,25 @@ EOF dlname= # Test again, we may have decided not to build it any more - if test "$build_libtool_libs" = yes; then - # Remove ${wl} instances when linking with ld. + if test yes = "$build_libtool_libs"; then + # Remove $wl instances when linking with ld. # FIXME: should test the right _cmds variable. case $archive_cmds in *\$LD\ *) wl= ;; esac - if test "$hardcode_into_libs" = yes; then + if test yes = "$hardcode_into_libs"; then # Hardcode the library paths hardcode_libdirs= dep_rpath= - rpath="$finalize_rpath" - test "$opt_mode" != relink && rpath="$compile_rpath$rpath" + rpath=$finalize_rpath + test relink = "$opt_mode" || rpath=$compile_rpath$rpath for libdir in $rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then func_replace_sysroot "$libdir" libdir=$func_replace_sysroot_result if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" + hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in @@ -8077,7 +9617,7 @@ EOF # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" + libdir=$hardcode_libdirs eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" fi if test -n "$runpath_var" && test -n "$perm_rpath"; then @@ -8091,8 +9631,8 @@ EOF test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" fi - shlibpath="$finalize_shlibpath" - test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath" + shlibpath=$finalize_shlibpath + test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath if test -n "$shlibpath"; then eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" fi @@ -8102,19 +9642,19 @@ EOF eval library_names=\"$library_names_spec\" set dummy $library_names shift - realname="$1" + realname=$1 shift if test -n "$soname_spec"; then eval soname=\"$soname_spec\" else - soname="$realname" + soname=$realname fi if test -z "$dlname"; then dlname=$soname fi - lib="$output_objdir/$realname" + lib=$output_objdir/$realname linknames= for link do @@ -8128,40 +9668,40 @@ EOF delfiles= if test -n "$export_symbols" && test -n "$include_expsyms"; then $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" - export_symbols="$output_objdir/$libname.uexp" + export_symbols=$output_objdir/$libname.uexp func_append delfiles " $export_symbols" fi orig_export_symbols= case $host_os in - cygwin* | mingw* | cegcc*) + cygwin* | mingw* | windows* | cegcc*) if test -n "$export_symbols" && test -z "$export_symbols_regex"; then # exporting using user supplied symfile - if test "x`$SED 1q $export_symbols`" != xEXPORTS; then + func_dll_def_p "$export_symbols" || { # and it's NOT already a .def file. Must figure out # which of the given symbols are data symbols and tag # them as such. So, trigger use of export_symbols_cmds. # export_symbols gets reassigned inside the "prepare # the list of exported symbols" if statement, so the # include_expsyms logic still works. - orig_export_symbols="$export_symbols" + orig_export_symbols=$export_symbols export_symbols= always_export_symbols=yes - fi + } fi ;; esac # Prepare the list of exported symbols if test -z "$export_symbols"; then - if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then - func_verbose "generating symbol list for \`$libname.la'" - export_symbols="$output_objdir/$libname.exp" + if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then + func_verbose "generating symbol list for '$libname.la'" + export_symbols=$output_objdir/$libname.exp $opt_dry_run || $RM $export_symbols cmds=$export_symbols_cmds - save_ifs="$IFS"; IFS='~' + save_ifs=$IFS; IFS='~' for cmd1 in $cmds; do - IFS="$save_ifs" + IFS=$save_ifs # Take the normal branch if the nm_file_list_spec branch # doesn't work or if tool conversion is not needed. case $nm_file_list_spec~$to_tool_file_cmd in @@ -8175,7 +9715,7 @@ EOF try_normal_branch=no ;; esac - if test "$try_normal_branch" = yes \ + if test yes = "$try_normal_branch" \ && { test "$len" -lt "$max_cmd_len" \ || test "$max_cmd_len" -le -1; } then @@ -8186,7 +9726,7 @@ EOF output_la=$func_basename_result save_libobjs=$libobjs save_output=$output - output=${output_objdir}/${output_la}.nm + output=$output_objdir/$output_la.nm func_to_tool_file "$output" libobjs=$nm_file_list_spec$func_to_tool_file_result func_append delfiles " $output" @@ -8209,8 +9749,8 @@ EOF break fi done - IFS="$save_ifs" - if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then + IFS=$save_ifs + if test -n "$export_symbols_regex" && test : != "$skipped_export"; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi @@ -8218,16 +9758,16 @@ EOF fi if test -n "$export_symbols" && test -n "$include_expsyms"; then - tmp_export_symbols="$export_symbols" - test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + tmp_export_symbols=$export_symbols + test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi - if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then + if test : != "$skipped_export" && test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. - func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + func_verbose "filter symbol list for '$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of - # 's' commands which not all seds can handle. GNU sed should be fine + # 's' commands, which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. @@ -8246,11 +9786,11 @@ EOF ;; esac done - deplibs="$tmp_deplibs" + deplibs=$tmp_deplibs if test -n "$convenience"; then if test -n "$whole_archive_flag_spec" && - test "$compiler_needs_object" = yes && + test yes = "$compiler_needs_object" && test -z "$libobjs"; then # extract the archives, so we have objects to list. # TODO: could optimize this to just extract one archive. @@ -8261,7 +9801,7 @@ EOF eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= else - gentop="$output_objdir/${outputname}x" + gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $convenience @@ -8270,18 +9810,18 @@ EOF fi fi - if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" func_append linker_flags " $flag" fi # Make a backup of the uninstalled library when relinking - if test "$opt_mode" = relink; then + if test relink = "$opt_mode"; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? fi # Do each of the archive commands. - if test "$module" = yes && test -n "$module_cmds" ; then + if test yes = "$module" && test -n "$module_cmds"; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then eval test_cmds=\"$module_expsym_cmds\" cmds=$module_expsym_cmds @@ -8299,7 +9839,7 @@ EOF fi fi - if test "X$skipped_export" != "X:" && + if test : != "$skipped_export" && func_len " $test_cmds" && len=$func_len_result && test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then @@ -8332,8 +9872,8 @@ EOF last_robj= k=1 - if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then - output=${output_objdir}/${output_la}.lnkscript + if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then + output=$output_objdir/$output_la.lnkscript func_verbose "creating GNU ld script: $output" echo 'INPUT (' > $output for obj in $save_libobjs @@ -8345,14 +9885,14 @@ EOF func_append delfiles " $output" func_to_tool_file "$output" output=$func_to_tool_file_result - elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then - output=${output_objdir}/${output_la}.lnk + elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then + output=$output_objdir/$output_la.lnk func_verbose "creating linker input file list: $output" : > $output set x $save_libobjs shift firstobj= - if test "$compiler_needs_object" = yes; then + if test yes = "$compiler_needs_object"; then firstobj="$1 " shift fi @@ -8367,7 +9907,7 @@ EOF else if test -n "$save_libobjs"; then func_verbose "creating reloadable object files..." - output=$output_objdir/$output_la-${k}.$objext + output=$output_objdir/$output_la-$k.$objext eval test_cmds=\"$reload_cmds\" func_len " $test_cmds" len0=$func_len_result @@ -8379,13 +9919,13 @@ EOF func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result - if test "X$objlist" = X || + if test -z "$objlist" || test "$len" -lt "$max_cmd_len"; then func_append objlist " $obj" else # The command $test_cmds is almost too long, add a # command to the queue. - if test "$k" -eq 1 ; then + if test 1 -eq "$k"; then # The first file doesn't have a previous command to add. reload_objs=$objlist eval concat_cmds=\"$reload_cmds\" @@ -8395,10 +9935,10 @@ EOF reload_objs="$objlist $last_robj" eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" fi - last_robj=$output_objdir/$output_la-${k}.$objext + last_robj=$output_objdir/$output_la-$k.$objext func_arith $k + 1 k=$func_arith_result - output=$output_objdir/$output_la-${k}.$objext + output=$output_objdir/$output_la-$k.$objext objlist=" $obj" func_len " $last_robj" func_arith $len0 + $func_len_result @@ -8410,9 +9950,9 @@ EOF # files will link in the last one created. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ reload_objs="$objlist $last_robj" - eval concat_cmds=\"\${concat_cmds}$reload_cmds\" + eval concat_cmds=\"\$concat_cmds$reload_cmds\" if test -n "$last_robj"; then - eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi func_append delfiles " $output" @@ -8420,9 +9960,9 @@ EOF output= fi - if ${skipped_export-false}; then - func_verbose "generating symbol list for \`$libname.la'" - export_symbols="$output_objdir/$libname.exp" + ${skipped_export-false} && { + func_verbose "generating symbol list for '$libname.la'" + export_symbols=$output_objdir/$libname.exp $opt_dry_run || $RM $export_symbols libobjs=$output # Append the command to create the export file. @@ -8431,16 +9971,16 @@ EOF if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi - fi + } test -n "$save_libobjs" && func_verbose "creating a temporary reloadable object file: $output" # Loop through the commands generated above and execute them. - save_ifs="$IFS"; IFS='~' + save_ifs=$IFS; IFS='~' for cmd in $concat_cmds; do - IFS="$save_ifs" - $opt_silent || { + IFS=$save_ifs + $opt_quiet || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } @@ -8448,7 +9988,7 @@ EOF lt_exit=$? # Restore the uninstalled library and exit - if test "$opt_mode" = relink; then + if test relink = "$opt_mode"; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) @@ -8457,7 +9997,7 @@ EOF exit $lt_exit } done - IFS="$save_ifs" + IFS=$save_ifs if test -n "$export_symbols_regex" && ${skipped_export-false}; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' @@ -8465,18 +10005,18 @@ EOF fi fi - if ${skipped_export-false}; then + ${skipped_export-false} && { if test -n "$export_symbols" && test -n "$include_expsyms"; then - tmp_export_symbols="$export_symbols" - test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" + tmp_export_symbols=$export_symbols + test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. - func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" + func_verbose "filter symbol list for '$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of - # 's' commands which not all seds can handle. GNU sed should be fine + # 's' commands, which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. @@ -8485,7 +10025,7 @@ EOF export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi - fi + } libobjs=$output # Restore the value of output. @@ -8499,7 +10039,7 @@ EOF # value of $libobjs for piecewise linking. # Do each of the archive commands. - if test "$module" = yes && test -n "$module_cmds" ; then + if test yes = "$module" && test -n "$module_cmds"; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then cmds=$module_expsym_cmds else @@ -8521,7 +10061,7 @@ EOF # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then - gentop="$output_objdir/${outputname}x" + gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $dlprefiles @@ -8529,11 +10069,12 @@ EOF test "X$libobjs" = "X " && libobjs= fi - save_ifs="$IFS"; IFS='~' + save_ifs=$IFS; IFS='~' for cmd in $cmds; do - IFS="$save_ifs" + IFS=$sp$nl eval cmd=\"$cmd\" - $opt_silent || { + IFS=$save_ifs + $opt_quiet || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } @@ -8541,7 +10082,7 @@ EOF lt_exit=$? # Restore the uninstalled library and exit - if test "$opt_mode" = relink; then + if test relink = "$opt_mode"; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) @@ -8550,10 +10091,10 @@ EOF exit $lt_exit } done - IFS="$save_ifs" + IFS=$save_ifs # Restore the uninstalled library and exit - if test "$opt_mode" = relink; then + if test relink = "$opt_mode"; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? if test -n "$convenience"; then @@ -8573,39 +10114,39 @@ EOF done # If -module or -export-dynamic was specified, set the dlname. - if test "$module" = yes || test "$export_dynamic" = yes; then + if test yes = "$module" || test yes = "$export_dynamic"; then # On all known operating systems, these are identical. - dlname="$soname" + dlname=$soname fi fi ;; obj) - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - func_warning "\`-dlopen' is ignored for objects" + if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then + func_warning "'-dlopen' is ignored for objects" fi case " $deplibs" in *\ -l* | *\ -L*) - func_warning "\`-l' and \`-L' are ignored for objects" ;; + func_warning "'-l' and '-L' are ignored for objects" ;; esac test -n "$rpath" && \ - func_warning "\`-rpath' is ignored for objects" + func_warning "'-rpath' is ignored for objects" test -n "$xrpath" && \ - func_warning "\`-R' is ignored for objects" + func_warning "'-R' is ignored for objects" test -n "$vinfo" && \ - func_warning "\`-version-info' is ignored for objects" + func_warning "'-version-info' is ignored for objects" test -n "$release" && \ - func_warning "\`-release' is ignored for objects" + func_warning "'-release' is ignored for objects" case $output in *.lo) test -n "$objs$old_deplibs" && \ - func_fatal_error "cannot build library object \`$output' from non-libtool objects" + func_fatal_error "cannot build library object '$output' from non-libtool objects" libobj=$output func_lo2o "$libobj" @@ -8613,7 +10154,7 @@ EOF ;; *) libobj= - obj="$output" + obj=$output ;; esac @@ -8626,17 +10167,19 @@ EOF # the extraction. reload_conv_objs= gentop= - # reload_cmds runs $LD directly, so let us get rid of - # -Wl from whole_archive_flag_spec and hope we can get by with - # turning comma into space.. - wl= - + # if reload_cmds runs $LD directly, get rid of -Wl from + # whole_archive_flag_spec and hope we can get by with turning comma + # into space. + case $reload_cmds in + *\$LD[\ \$]*) wl= ;; + esac if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" - reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` + test -n "$wl" || tmp_whole_archive_flags=`$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` + reload_conv_objs=$reload_objs\ $tmp_whole_archive_flags else - gentop="$output_objdir/${obj}x" + gentop=$output_objdir/${obj}x func_append generated " $gentop" func_extract_archives $gentop $convenience @@ -8645,12 +10188,12 @@ EOF fi # If we're not building shared, we need to use non_pic_objs - test "$build_libtool_libs" != yes && libobjs="$non_pic_objects" + test yes = "$build_libtool_libs" || libobjs=$non_pic_objects # Create the old-style object. - reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test + reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs - output="$obj" + output=$obj func_execute_cmds "$reload_cmds" 'exit $?' # Exit if we aren't doing a library object file. @@ -8662,7 +10205,7 @@ EOF exit $EXIT_SUCCESS fi - if test "$build_libtool_libs" != yes; then + test yes = "$build_libtool_libs" || { if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi @@ -8672,12 +10215,12 @@ EOF # $show "echo timestamp > $libobj" # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? exit $EXIT_SUCCESS - fi + } - if test -n "$pic_flag" || test "$pic_mode" != default; then + if test -n "$pic_flag" || test default != "$pic_mode"; then # Only do commands if we really have different PIC objects. reload_objs="$libobjs $reload_conv_objs" - output="$libobj" + output=$libobj func_execute_cmds "$reload_cmds" 'exit $?' fi @@ -8694,16 +10237,14 @@ EOF output=$func_stripname_result.exe;; esac test -n "$vinfo" && \ - func_warning "\`-version-info' is ignored for programs" + func_warning "'-version-info' is ignored for programs" test -n "$release" && \ - func_warning "\`-release' is ignored for programs" + func_warning "'-release' is ignored for programs" - test "$preload" = yes \ - && test "$dlopen_support" = unknown \ - && test "$dlopen_self" = unknown \ - && test "$dlopen_self_static" = unknown && \ - func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." + $preload \ + && test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \ + && func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support." case $host in *-*-rhapsody* | *-*-darwin1.[012]) @@ -8717,11 +10258,11 @@ EOF *-*-darwin*) # Don't allow lazy linking, it breaks C++ global constructors # But is supposedly fixed on 10.4 or later (yay!). - if test "$tagname" = CXX ; then + if test CXX = "$tagname"; then case ${MACOSX_DEPLOYMENT_TARGET-10.0} in 10.[0123]) - func_append compile_command " ${wl}-bind_at_load" - func_append finalize_command " ${wl}-bind_at_load" + func_append compile_command " $wl-bind_at_load" + func_append finalize_command " $wl-bind_at_load" ;; esac fi @@ -8757,7 +10298,7 @@ EOF *) func_append new_libs " $deplib" ;; esac done - compile_deplibs="$new_libs" + compile_deplibs=$new_libs func_append compile_command " $compile_deplibs" @@ -8781,7 +10322,7 @@ EOF if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" + hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in @@ -8803,8 +10344,8 @@ EOF esac fi case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) - testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` + *-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'` case :$dllsearchpath: in *":$libdir:"*) ;; ::) dllsearchpath=$libdir;; @@ -8821,10 +10362,10 @@ EOF # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" + libdir=$hardcode_libdirs eval rpath=\" $hardcode_libdir_flag_spec\" fi - compile_rpath="$rpath" + compile_rpath=$rpath rpath= hardcode_libdirs= @@ -8832,7 +10373,7 @@ EOF if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" + hardcode_libdirs=$libdir else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in @@ -8857,45 +10398,43 @@ EOF # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" + libdir=$hardcode_libdirs eval rpath=\" $hardcode_libdir_flag_spec\" fi - finalize_rpath="$rpath" + finalize_rpath=$rpath - if test -n "$libobjs" && test "$build_old_libs" = yes; then + if test -n "$libobjs" && test yes = "$build_old_libs"; then # Transform all the library objects into standard objects. compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` fi - func_generate_dlsyms "$outputname" "@PROGRAM@" "no" + func_generate_dlsyms "$outputname" "@PROGRAM@" false # template prelinking step if test -n "$prelink_cmds"; then func_execute_cmds "$prelink_cmds" 'exit $?' fi - wrappers_required=yes + wrappers_required=: case $host in *cegcc* | *mingw32ce*) # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. - wrappers_required=no + wrappers_required=false ;; - *cygwin* | *mingw* ) - if test "$build_libtool_libs" != yes; then - wrappers_required=no - fi + *cygwin* | *mingw* | *windows* ) + test yes = "$build_libtool_libs" || wrappers_required=false ;; *) - if test "$need_relink" = no || test "$build_libtool_libs" != yes; then - wrappers_required=no + if test no = "$need_relink" || test yes != "$build_libtool_libs"; then + wrappers_required=false fi ;; esac - if test "$wrappers_required" = no; then + $wrappers_required || { # Replace the output file specification. compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` - link_command="$compile_command$compile_rpath" + link_command=$compile_command$compile_rpath # We have no uninstalled library dependencies, so finalize right now. exit_status=0 @@ -8908,12 +10447,12 @@ EOF fi # Delete the generated files. - if test -f "$output_objdir/${outputname}S.${objext}"; then - func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' + if test -f "$output_objdir/${outputname}S.$objext"; then + func_show_eval '$RM "$output_objdir/${outputname}S.$objext"' fi exit $exit_status - fi + } if test -n "$compile_shlibpath$finalize_shlibpath"; then compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" @@ -8943,9 +10482,9 @@ EOF fi fi - if test "$no_install" = yes; then + if test yes = "$no_install"; then # We don't need to create a wrapper script. - link_command="$compile_var$compile_command$compile_rpath" + link_command=$compile_var$compile_command$compile_rpath # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` # Delete the old output file. @@ -8962,27 +10501,28 @@ EOF exit $EXIT_SUCCESS fi - if test "$hardcode_action" = relink; then - # Fast installation is not supported - link_command="$compile_var$compile_command$compile_rpath" - relink_command="$finalize_var$finalize_command$finalize_rpath" + case $hardcode_action,$fast_install in + relink,*) + # Fast installation is not supported + link_command=$compile_var$compile_command$compile_rpath + relink_command=$finalize_var$finalize_command$finalize_rpath - func_warning "this platform does not like uninstalled shared libraries" - func_warning "\`$output' will be relinked during installation" - else - if test "$fast_install" != no; then - link_command="$finalize_var$compile_command$finalize_rpath" - if test "$fast_install" = yes; then - relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` - else - # fast_install is set to needless - relink_command= - fi - else - link_command="$compile_var$compile_command$compile_rpath" - relink_command="$finalize_var$finalize_command$finalize_rpath" - fi - fi + func_warning "this platform does not like uninstalled shared libraries" + func_warning "'$output' will be relinked during installation" + ;; + *,yes) + link_command=$finalize_var$compile_command$finalize_rpath + relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` + ;; + *,no) + link_command=$compile_var$compile_command$compile_rpath + relink_command=$finalize_var$finalize_command$finalize_rpath + ;; + *,needless) + link_command=$finalize_var$compile_command$finalize_rpath + relink_command= + ;; + esac # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` @@ -9035,12 +10575,12 @@ EOF *) exeext= ;; esac case $host in - *cygwin* | *mingw* ) + *cygwin* | *mingw* | windows* ) func_dirname_and_basename "$output" "" "." output_name=$func_basename_result output_path=$func_dirname_result - cwrappersource="$output_path/$objdir/lt-$output_name.c" - cwrapper="$output_path/$output_name.exe" + cwrappersource=$output_path/$objdir/lt-$output_name.c + cwrapper=$output_path/$output_name.exe $RM $cwrappersource $cwrapper trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 @@ -9061,7 +10601,7 @@ EOF trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 $opt_dry_run || { # note: this script will not be executed, so do not chmod. - if test "x$build" = "x$host" ; then + if test "x$build" = "x$host"; then $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result else func_emit_wrapper no > $func_ltwrapper_scriptname_result @@ -9084,25 +10624,27 @@ EOF # See if we need to build an old-fashioned archive. for oldlib in $oldlibs; do - if test "$build_libtool_libs" = convenience; then - oldobjs="$libobjs_save $symfileobj" - addlibs="$convenience" - build_libtool_libs=no - else - if test "$build_libtool_libs" = module; then - oldobjs="$libobjs_save" + case $build_libtool_libs in + convenience) + oldobjs="$libobjs_save $symfileobj" + addlibs=$convenience build_libtool_libs=no - else + ;; + module) + oldobjs=$libobjs_save + addlibs=$old_convenience + build_libtool_libs=no + ;; + *) oldobjs="$old_deplibs $non_pic_objects" - if test "$preload" = yes && test -f "$symfileobj"; then - func_append oldobjs " $symfileobj" - fi - fi - addlibs="$old_convenience" - fi + $preload && test -f "$symfileobj" \ + && func_append oldobjs " $symfileobj" + addlibs=$old_convenience + ;; + esac if test -n "$addlibs"; then - gentop="$output_objdir/${outputname}x" + gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $addlibs @@ -9110,13 +10652,13 @@ EOF fi # Do each command in the archive commands. - if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then cmds=$old_archive_from_new_cmds else # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then - gentop="$output_objdir/${outputname}x" + gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_extract_archives $gentop $dlprefiles @@ -9137,7 +10679,7 @@ EOF : else echo "copying selected object files to avoid basename conflicts..." - gentop="$output_objdir/${outputname}x" + gentop=$output_objdir/${outputname}x func_append generated " $gentop" func_mkdir_p "$gentop" save_oldobjs=$oldobjs @@ -9146,7 +10688,7 @@ EOF for obj in $save_oldobjs do func_basename "$obj" - objbase="$func_basename_result" + objbase=$func_basename_result case " $oldobjs " in " ") oldobjs=$obj ;; *[\ /]"$objbase "*) @@ -9215,18 +10757,18 @@ EOF else # the above command should be used before it gets too long oldobjs=$objlist - if test "$obj" = "$last_oldobj" ; then + if test "$obj" = "$last_oldobj"; then RANLIB=$save_RANLIB fi test -z "$concat_cmds" || concat_cmds=$concat_cmds~ - eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" + eval concat_cmds=\"\$concat_cmds$old_archive_cmds\" objlist= len=$len0 fi done RANLIB=$save_RANLIB oldobjs=$objlist - if test "X$oldobjs" = "X" ; then + if test -z "$oldobjs"; then eval cmds=\"\$concat_cmds\" else eval cmds=\"\$concat_cmds~\$old_archive_cmds\" @@ -9243,7 +10785,7 @@ EOF case $output in *.la) old_library= - test "$build_old_libs" = yes && old_library="$libname.$libext" + test yes = "$build_old_libs" && old_library=$libname.$libext func_verbose "creating $output" # Preserve any variables that may affect compiler behavior @@ -9258,31 +10800,31 @@ EOF fi done # Quote the link command for shipping. - relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` - if test "$hardcode_automatic" = yes ; then + if test yes = "$hardcode_automatic"; then relink_command= fi # Only create the output if not a dry run. $opt_dry_run || { for installed in no yes; do - if test "$installed" = yes; then + if test yes = "$installed"; then if test -z "$install_libdir"; then break fi - output="$output_objdir/$outputname"i + output=$output_objdir/${outputname}i # Replace all uninstalled libtool libraries with the installed ones newdependency_libs= for deplib in $dependency_libs; do case $deplib in *.la) func_basename "$deplib" - name="$func_basename_result" + name=$func_basename_result func_resolve_sysroot "$deplib" - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` test -z "$libdir" && \ - func_fatal_error "\`$deplib' is not a valid libtool archive" + func_fatal_error "'$deplib' is not a valid libtool archive" func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" ;; -L*) @@ -9298,23 +10840,23 @@ EOF *) func_append newdependency_libs " $deplib" ;; esac done - dependency_libs="$newdependency_libs" + dependency_libs=$newdependency_libs newdlfiles= for lib in $dlfiles; do case $lib in *.la) func_basename "$lib" - name="$func_basename_result" - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + name=$func_basename_result + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ - func_fatal_error "\`$lib' is not a valid libtool archive" + func_fatal_error "'$lib' is not a valid libtool archive" func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" ;; *) func_append newdlfiles " $lib" ;; esac done - dlfiles="$newdlfiles" + dlfiles=$newdlfiles newdlprefiles= for lib in $dlprefiles; do case $lib in @@ -9324,34 +10866,34 @@ EOF # didn't already link the preopened objects directly into # the library: func_basename "$lib" - name="$func_basename_result" - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + name=$func_basename_result + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ - func_fatal_error "\`$lib' is not a valid libtool archive" + func_fatal_error "'$lib' is not a valid libtool archive" func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" ;; esac done - dlprefiles="$newdlprefiles" + dlprefiles=$newdlprefiles else newdlfiles= for lib in $dlfiles; do case $lib in - [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlfiles " $abs" done - dlfiles="$newdlfiles" + dlfiles=$newdlfiles newdlprefiles= for lib in $dlprefiles; do case $lib in - [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; + [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlprefiles " $abs" done - dlprefiles="$newdlprefiles" + dlprefiles=$newdlprefiles fi $RM $output # place dlname in correct position for cygwin @@ -9365,12 +10907,11 @@ EOF # tests/bindir.at for full details. tdlname=$dlname case $host,$output,$installed,$module,$dlname in - *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *windows*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) # If a -bindir argument was supplied, place the dll there. - if test "x$bindir" != x ; - then + if test -n "$bindir"; then func_relative_path "$install_libdir" "$bindir" - tdlname=$func_relative_path_result$dlname + tdlname=$func_relative_path_result/$dlname else # Otherwise fall back on heuristic. tdlname=../bin/$dlname @@ -9379,7 +10920,7 @@ EOF esac $ECHO > $output "\ # $outputname - a libtool library file -# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION +# Generated by $PROGRAM (GNU $PACKAGE) $VERSION # # Please DO NOT delete this file! # It is necessary for linking the library. @@ -9393,7 +10934,7 @@ library_names='$library_names' # The name of the static archive. old_library='$old_library' -# Linker flags that can not go in dependency_libs. +# Linker flags that cannot go in dependency_libs. inherited_linker_flags='$new_inherited_linker_flags' # Libraries that this one depends upon. @@ -9419,7 +10960,7 @@ dlpreopen='$dlprefiles' # Directory that this library needs to be installed in: libdir='$install_libdir'" - if test "$installed" = no && test "$need_relink" = yes; then + if test no,yes = "$installed,$need_relink"; then $ECHO >> $output "\ relink_command=\"$relink_command\"" fi @@ -9434,27 +10975,29 @@ relink_command=\"$relink_command\"" exit $EXIT_SUCCESS } -{ test "$opt_mode" = link || test "$opt_mode" = relink; } && - func_mode_link ${1+"$@"} +if test link = "$opt_mode" || test relink = "$opt_mode"; then + func_mode_link ${1+"$@"} +fi # func_mode_uninstall arg... func_mode_uninstall () { - $opt_debug - RM="$nonopt" + $debug_cmd + + RM=$nonopt files= - rmforce= + rmforce=false exit_status=0 # This variable tells wrapper scripts just to set variables rather # than running their programs. - libtool_install_magic="$magic" + libtool_install_magic=$magic for arg do case $arg in - -f) func_append RM " $arg"; rmforce=yes ;; + -f) func_append RM " $arg"; rmforce=: ;; -*) func_append RM " $arg" ;; *) func_append files " $arg" ;; esac @@ -9467,18 +11010,18 @@ func_mode_uninstall () for file in $files; do func_dirname "$file" "" "." - dir="$func_dirname_result" - if test "X$dir" = X.; then - odir="$objdir" + dir=$func_dirname_result + if test . = "$dir"; then + odir=$objdir else - odir="$dir/$objdir" + odir=$dir/$objdir fi func_basename "$file" - name="$func_basename_result" - test "$opt_mode" = uninstall && odir="$dir" + name=$func_basename_result + test uninstall = "$opt_mode" && odir=$dir # Remember odir for removal later, being careful to avoid duplicates - if test "$opt_mode" = clean; then + if test clean = "$opt_mode"; then case " $rmdirs " in *" $odir "*) ;; *) func_append rmdirs " $odir" ;; @@ -9493,11 +11036,11 @@ func_mode_uninstall () elif test -d "$file"; then exit_status=1 continue - elif test "$rmforce" = yes; then + elif $rmforce; then continue fi - rmfiles="$file" + rmfiles=$file case $name in *.la) @@ -9511,7 +11054,7 @@ func_mode_uninstall () done test -n "$old_library" && func_append rmfiles " $odir/$old_library" - case "$opt_mode" in + case $opt_mode in clean) case " $library_names " in *" $dlname "*) ;; @@ -9522,12 +11065,12 @@ func_mode_uninstall () uninstall) if test -n "$library_names"; then # Do each command in the postuninstall commands. - func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1' fi if test -n "$old_library"; then # Do each command in the old_postuninstall commands. - func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' + func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1' fi # FIXME: should reinstall the best remaining shared library. ;; @@ -9543,21 +11086,19 @@ func_mode_uninstall () func_source $dir/$name # Add PIC object to the list of files to remove. - if test -n "$pic_object" && - test "$pic_object" != none; then + if test -n "$pic_object" && test none != "$pic_object"; then func_append rmfiles " $dir/$pic_object" fi # Add non-PIC object to the list of files to remove. - if test -n "$non_pic_object" && - test "$non_pic_object" != none; then + if test -n "$non_pic_object" && test none != "$non_pic_object"; then func_append rmfiles " $dir/$non_pic_object" fi fi ;; *) - if test "$opt_mode" = clean ; then + if test clean = "$opt_mode"; then noexename=$name case $file in *.exe) @@ -9584,12 +11125,12 @@ func_mode_uninstall () # note $name still contains .exe if it was in $file originally # as does the version of $file that was added into $rmfiles - func_append rmfiles " $odir/$name $odir/${name}S.${objext}" - if test "$fast_install" = yes && test -n "$relink_command"; then + func_append rmfiles " $odir/$name $odir/${name}S.$objext" + if test yes = "$fast_install" && test -n "$relink_command"; then func_append rmfiles " $odir/lt-$name" fi - if test "X$noexename" != "X$name" ; then - func_append rmfiles " $odir/lt-${noexename}.c" + if test "X$noexename" != "X$name"; then + func_append rmfiles " $odir/lt-$noexename.c" fi fi fi @@ -9598,7 +11139,7 @@ func_mode_uninstall () func_show_eval "$RM $rmfiles" 'exit_status=1' done - # Try to remove the ${objdir}s in the directories where we deleted files + # Try to remove the $objdir's in the directories where we deleted files for dir in $rmdirs; do if test -d "$dir"; then func_show_eval "rmdir $dir >/dev/null 2>&1" @@ -9608,16 +11149,17 @@ func_mode_uninstall () exit $exit_status } -{ test "$opt_mode" = uninstall || test "$opt_mode" = clean; } && - func_mode_uninstall ${1+"$@"} +if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then + func_mode_uninstall ${1+"$@"} +fi test -z "$opt_mode" && { - help="$generic_help" + help=$generic_help func_fatal_help "you must specify a MODE" } test -z "$exec_cmd" && \ - func_fatal_help "invalid operation mode \`$opt_mode'" + func_fatal_help "invalid operation mode '$opt_mode'" if test -n "$exec_cmd"; then eval exec "$exec_cmd" @@ -9628,7 +11170,7 @@ exit $exit_status # The TAGs below are defined such that we never get into a situation -# in which we disable both kinds of libraries. Given conflicting +# where we disable both kinds of libraries. Given conflicting # choices, we go for a static library, that is the most portable, # since we can't tell whether shared libraries were disabled because # the user asked for that or because the platform doesn't support @@ -9651,5 +11193,3 @@ build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` # mode:shell-script # sh-indentation:2 # End: -# vi:sw=2 - diff --git a/SDL2-2.0.12/build-scripts/mkinstalldirs b/SDL2-2.30.5/build-scripts/mkinstalldirs similarity index 91% rename from SDL2-2.0.12/build-scripts/mkinstalldirs rename to SDL2-2.30.5/build-scripts/mkinstalldirs index 55d537f..c364f3d 100644 --- a/SDL2-2.0.12/build-scripts/mkinstalldirs +++ b/SDL2-2.30.5/build-scripts/mkinstalldirs @@ -1,7 +1,7 @@ #! /bin/sh # mkinstalldirs --- make directory hierarchy -scriptversion=2009-04-28.21; # UTC +scriptversion=2020-07-26.22; # UTC # Original author: Noah Friedman # Created: 1993-05-16 @@ -92,6 +92,8 @@ case $dirmode in *) if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 && test ! -d ./--version; then + echo "umask 22" + umask 22 echo "mkdir -m $dirmode -p -- $*" exec mkdir -m "$dirmode" -p -- "$@" else @@ -104,6 +106,9 @@ case $dirmode in ;; esac +echo "umask 22" +umask 22 + for file do case $file in @@ -132,21 +137,16 @@ do if test ! -d "$pathcomp"; then errstatus=$lasterr - else - if test ! -z "$dirmode"; then - echo "chmod $dirmode $pathcomp" - lasterr= - chmod "$dirmode" "$pathcomp" || lasterr=$? - - if test ! -z "$lasterr"; then - errstatus=$lasterr - fi - fi fi fi pathcomp=$pathcomp/ done + + if test ! -z "$dirmode"; then + echo "chmod $dirmode $file" + chmod "$dirmode" "$file" || errstatus=$? + fi done exit $errstatus @@ -154,9 +154,9 @@ exit $errstatus # Local Variables: # mode: shell-script # sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" +# time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: diff --git a/SDL2-2.0.12/build-scripts/nacl-buildbot.sh b/SDL2-2.30.5/build-scripts/nacl-buildbot.sh similarity index 100% rename from SDL2-2.0.12/build-scripts/nacl-buildbot.sh rename to SDL2-2.30.5/build-scripts/nacl-buildbot.sh diff --git a/SDL2-2.0.12/build-scripts/naclbuild.sh b/SDL2-2.30.5/build-scripts/naclbuild.sh similarity index 100% rename from SDL2-2.0.12/build-scripts/naclbuild.sh rename to SDL2-2.30.5/build-scripts/naclbuild.sh diff --git a/SDL2-2.0.12/build-scripts/raspberrypi-buildbot.sh b/SDL2-2.30.5/build-scripts/raspberrypi-buildbot.sh similarity index 95% rename from SDL2-2.0.12/build-scripts/raspberrypi-buildbot.sh rename to SDL2-2.30.5/build-scripts/raspberrypi-buildbot.sh index 85124bc..9486198 100644 --- a/SDL2-2.0.12/build-scripts/raspberrypi-buildbot.sh +++ b/SDL2-2.30.5/build-scripts/raspberrypi-buildbot.sh @@ -28,7 +28,7 @@ if [ "x$MAKE" == "x" ]; then MAKE="make -j$NCPU" fi -BUILDBOTDIR="raspberrypi-buildbot" +BUILDBOTDIR="buildbot" PARENTDIR="$PWD" set -e @@ -49,10 +49,8 @@ $MAKE install perl -w -pi -e "s#$PWD/rpi-sdl2-installed#/usr/local#g;" ./rpi-sdl2-installed/lib/libSDL2.la ./rpi-sdl2-installed/lib/pkgconfig/sdl2.pc ./rpi-sdl2-installed/bin/sdl2-config mkdir -p ./usr mv ./rpi-sdl2-installed ./usr/local - +tar -cJvvf $TARBALL usr popd -tar -cJvvf $TARBALL -C $BUILDBOTDIR usr -rm -rf $BUILDBOTDIR set +x echo "All done. Final installable is in $TARBALL ..."; diff --git a/SDL2-2.30.5/build-scripts/showrev.sh b/SDL2-2.30.5/build-scripts/showrev.sh new file mode 100644 index 0000000..a061df4 --- /dev/null +++ b/SDL2-2.30.5/build-scripts/showrev.sh @@ -0,0 +1,48 @@ +#!/bin/sh +# +# Print the current source revision, if available + +SDL_ROOT=$(dirname $0)/.. +cd $SDL_ROOT + +if [ -e ./VERSION.txt ]; then + cat ./VERSION.txt + exit 0 +fi + +major=$(sed -ne 's/^#define SDL_MAJOR_VERSION *//p' include/SDL_version.h) +minor=$(sed -ne 's/^#define SDL_MINOR_VERSION *//p' include/SDL_version.h) +micro=$(sed -ne 's/^#define SDL_PATCHLEVEL *//p' include/SDL_version.h) +version="${major}.${minor}.${micro}" + +if [ -x "$(command -v git)" ]; then + rev="$(git describe --tags --long 2>/dev/null)" + if [ -n "$rev" ]; then + # e.g. release-2.24.0-542-g96361fc47 + # or release-2.24.1-5-g36b987dab + # or prerelease-2.23.2-0-gcb46e1b3f + echo "$rev" + exit 0 + fi + + rev="$(git describe --always --tags --long 2>/dev/null)" + if [ -n "$rev" ]; then + # Just a truncated sha1, e.g. 96361fc47. + # Turn it into e.g. 2.25.0-g96361fc47 + echo "${version}-g${rev}" + exit 0 + fi +fi + +if [ -x "$(command -v p4)" ]; then + rev="$(p4 changes -m1 ./...\#have 2>/dev/null| awk '{print $2}')" + if [ $? = 0 ]; then + # e.g. 2.25.0-p7511446 + echo "${version}-p${rev}" + exit 0 + fi +fi + +# best we can do +echo "${version}-no-vcs" +exit 0 diff --git a/SDL2-2.0.12/build-scripts/strip_fPIC.sh b/SDL2-2.30.5/build-scripts/strip_fPIC.sh similarity index 100% rename from SDL2-2.0.12/build-scripts/strip_fPIC.sh rename to SDL2-2.30.5/build-scripts/strip_fPIC.sh diff --git a/SDL2-2.30.5/build-scripts/test-versioning.sh b/SDL2-2.30.5/build-scripts/test-versioning.sh new file mode 100644 index 0000000..ed77715 --- /dev/null +++ b/SDL2-2.30.5/build-scripts/test-versioning.sh @@ -0,0 +1,213 @@ +#!/bin/sh +# Copyright 2022 Collabora Ltd. +# SPDX-License-Identifier: Zlib + +set -eu + +cd `dirname $0`/.. + +ref_major=$(sed -ne 's/^#define SDL_MAJOR_VERSION *//p' include/SDL_version.h) +ref_minor=$(sed -ne 's/^#define SDL_MINOR_VERSION *//p' include/SDL_version.h) +ref_micro=$(sed -ne 's/^#define SDL_PATCHLEVEL *//p' include/SDL_version.h) +ref_version="${ref_major}.${ref_minor}.${ref_micro}" + +tests=0 +failed=0 + +ok () { + tests=$(( tests + 1 )) + echo "ok - $*" +} + +not_ok () { + tests=$(( tests + 1 )) + echo "not ok - $*" + failed=1 +} + +major=$(sed -ne 's/^SDL_MAJOR_VERSION=//p' configure.ac) +minor=$(sed -ne 's/^SDL_MINOR_VERSION=//p' configure.ac) +micro=$(sed -ne 's/^SDL_MICRO_VERSION=//p' configure.ac) +version="${major}.${minor}.${micro}" + +if [ "$ref_version" = "$version" ]; then + ok "configure.ac $version" +else + not_ok "configure.ac $version disagrees with SDL_version.h $ref_version" +fi + +major=$(sed -ne 's/^SDL_MAJOR_VERSION=//p' configure) +minor=$(sed -ne 's/^SDL_MINOR_VERSION=//p' configure) +micro=$(sed -ne 's/^SDL_MICRO_VERSION=//p' configure) +version="${major}.${minor}.${micro}" + +if [ "$ref_version" = "$version" ]; then + ok "configure $version" +else + not_ok "configure $version disagrees with SDL_version.h $ref_version" +fi + +major=$(sed -ne 's/^set(SDL_MAJOR_VERSION \([0-9]*\))$/\1/p' CMakeLists.txt) +minor=$(sed -ne 's/^set(SDL_MINOR_VERSION \([0-9]*\))$/\1/p' CMakeLists.txt) +micro=$(sed -ne 's/^set(SDL_MICRO_VERSION \([0-9]*\))$/\1/p' CMakeLists.txt) +version="${major}.${minor}.${micro}" + +if [ "$ref_version" = "$version" ]; then + ok "CMakeLists.txt $version" +else + not_ok "CMakeLists.txt $version disagrees with SDL_version.h $ref_version" +fi + +major=$(sed -ne 's/.*SDL_MAJOR_VERSION = \([0-9]*\);/\1/p' android-project/app/src/main/java/org/libsdl/app/SDLActivity.java) +minor=$(sed -ne 's/.*SDL_MINOR_VERSION = \([0-9]*\);/\1/p' android-project/app/src/main/java/org/libsdl/app/SDLActivity.java) +micro=$(sed -ne 's/.*SDL_MICRO_VERSION = \([0-9]*\);/\1/p' android-project/app/src/main/java/org/libsdl/app/SDLActivity.java) +version="${major}.${minor}.${micro}" + +if [ "$ref_version" = "$version" ]; then + ok "SDLActivity.java $version" +else + not_ok "android-project/app/src/main/java/org/libsdl/app/SDLActivity.java $version disagrees with SDL_version.h $ref_version" +fi + +major=$(sed -ne 's/^MAJOR_VERSION *= *//p' Makefile.os2) +minor=$(sed -ne 's/^MINOR_VERSION *= *//p' Makefile.os2) +micro=$(sed -ne 's/^MICRO_VERSION *= *//p' Makefile.os2) +version="${major}.${minor}.${micro}" + +if [ "$ref_version" = "$version" ]; then + ok "Makefile.os2 $version" +else + not_ok "Makefile.os2 $version disagrees with SDL_version.h $ref_version" +fi + +major=$(sed -ne 's/^MAJOR_VERSION *= *//p' Makefile.w32) +minor=$(sed -ne 's/^MINOR_VERSION *= *//p' Makefile.w32) +micro=$(sed -ne 's/^MICRO_VERSION *= *//p' Makefile.w32) +version="${major}.${minor}.${micro}" + +if [ "$ref_version" = "$version" ]; then + ok "Makefile.w32 $version" +else + not_ok "Makefile.w32 $version disagrees with SDL_version.h $ref_version" +fi + +tuple=$(sed -ne 's/^ *FILEVERSION *//p' src/main/windows/version.rc | tr -d '\r') +ref_tuple="${ref_major},${ref_minor},${ref_micro},0" + +if [ "$ref_tuple" = "$tuple" ]; then + ok "version.rc FILEVERSION $tuple" +else + not_ok "version.rc FILEVERSION $tuple disagrees with SDL_version.h $ref_tuple" +fi + +tuple=$(sed -ne 's/^ *PRODUCTVERSION *//p' src/main/windows/version.rc | tr -d '\r') + +if [ "$ref_tuple" = "$tuple" ]; then + ok "version.rc PRODUCTVERSION $tuple" +else + not_ok "version.rc PRODUCTVERSION $tuple disagrees with SDL_version.h $ref_tuple" +fi + +tuple=$(sed -Ene 's/^ *VALUE "FileVersion", "([0-9, ]*)\\0"\r?$/\1/p' src/main/windows/version.rc | tr -d '\r') +ref_tuple="${ref_major}, ${ref_minor}, ${ref_micro}, 0" + +if [ "$ref_tuple" = "$tuple" ]; then + ok "version.rc FileVersion $tuple" +else + not_ok "version.rc FileVersion $tuple disagrees with SDL_version.h $ref_tuple" +fi + +tuple=$(sed -Ene 's/^ *VALUE "ProductVersion", "([0-9, ]*)\\0"\r?$/\1/p' src/main/windows/version.rc | tr -d '\r') + +if [ "$ref_tuple" = "$tuple" ]; then + ok "version.rc ProductVersion $tuple" +else + not_ok "version.rc ProductVersion $tuple disagrees with SDL_version.h $ref_tuple" +fi + +version=$(sed -Ene '/CFBundleShortVersionString/,+1 s/.*(.*)<\/string>.*/\1/p' Xcode/SDL/Info-Framework.plist) + +if [ "$ref_version" = "$version" ]; then + ok "Info-Framework.plist CFBundleShortVersionString $version" +else + not_ok "Info-Framework.plist CFBundleShortVersionString $version disagrees with SDL_version.h $ref_version" +fi + +version=$(sed -Ene '/CFBundleVersion/,+1 s/.*(.*)<\/string>.*/\1/p' Xcode/SDL/Info-Framework.plist) + +if [ "$ref_version" = "$version" ]; then + ok "Info-Framework.plist CFBundleVersion $version" +else + not_ok "Info-Framework.plist CFBundleVersion $version disagrees with SDL_version.h $ref_version" +fi + +version=$(sed -Ene 's/Title SDL (.*)/\1/p' Xcode/SDL/pkg-support/SDL.info) + +if [ "$ref_version" = "$version" ]; then + ok "SDL.info Title $version" +else + not_ok "SDL.info Title $version disagrees with SDL_version.h $ref_version" +fi + +marketing=$(sed -Ene 's/.*MARKETING_VERSION = (.*);/\1/p' Xcode/SDL/SDL.xcodeproj/project.pbxproj) + +ref="$ref_version +$ref_version" + +if [ "$ref" = "$marketing" ]; then + ok "project.pbxproj MARKETING_VERSION is consistent" +else + not_ok "project.pbxproj MARKETING_VERSION is inconsistent, expected $ref, got $marketing" +fi + +# For simplicity this assumes we'll never break ABI before SDL 3. +dylib_compat=$(sed -Ene 's/.*DYLIB_COMPATIBILITY_VERSION = (.*);$/\1/p' Xcode/SDL/SDL.xcodeproj/project.pbxproj) + +case "$ref_minor" in + (*[02468]) + major="$(( ref_minor * 100 + 1 ))" + minor="0" + ;; + (*) + major="$(( ref_minor * 100 + ref_micro + 1 ))" + minor="0" + ;; +esac + +ref="${major}.${minor}.0 +${major}.${minor}.0 +${major}.${minor}.0 +${major}.${minor}.0" + +if [ "$ref" = "$dylib_compat" ]; then + ok "project.pbxproj DYLIB_COMPATIBILITY_VERSION is consistent" +else + not_ok "project.pbxproj DYLIB_COMPATIBILITY_VERSION is inconsistent, expected $ref, got $dylib_compat" +fi + +dylib_cur=$(sed -Ene 's/.*DYLIB_CURRENT_VERSION = (.*);$/\1/p' Xcode/SDL/SDL.xcodeproj/project.pbxproj) + +case "$ref_minor" in + (*[02468]) + major="$(( ref_minor * 100 + 1 ))" + minor="$ref_micro" + ;; + (*) + major="$(( ref_minor * 100 + ref_micro + 1 ))" + minor="0" + ;; +esac + +ref="${major}.${minor}.0 +${major}.${minor}.0 +${major}.${minor}.0 +${major}.${minor}.0" + +if [ "$ref" = "$dylib_cur" ]; then + ok "project.pbxproj DYLIB_CURRENT_VERSION is consistent" +else + not_ok "project.pbxproj DYLIB_CURRENT_VERSION is inconsistent, expected $ref, got $dylib_cur" +fi + +echo "1..$tests" +exit "$failed" diff --git a/SDL2-2.30.5/build-scripts/update-copyright.sh b/SDL2-2.30.5/build-scripts/update-copyright.sh new file mode 100644 index 0000000..9bb46ea --- /dev/null +++ b/SDL2-2.30.5/build-scripts/update-copyright.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +if [ "$SED" = "" ]; then + if type gsed >/dev/null; then + SED=gsed + else + SED=sed + fi +fi + +find . -type f \ +| grep -v \.git \ +| while read file; do \ + LC_ALL=C $SED -b -i "s/\(.*Copyright.*\)[0-9]\{4\}\( *Sam Lantinga\)/\1`date +%Y`\2/" "$file"; \ +done diff --git a/SDL2-2.30.5/build-scripts/update-version.sh b/SDL2-2.30.5/build-scripts/update-version.sh new file mode 100644 index 0000000..9b25c2a --- /dev/null +++ b/SDL2-2.30.5/build-scripts/update-version.sh @@ -0,0 +1,96 @@ +#!/bin/sh + +#set -x + +cd `dirname $0`/.. + +ARGSOKAY=1 +if [ -z $1 ]; then + ARGSOKAY=0 +fi +if [ -z $2 ]; then + ARGSOKAY=0 +fi +if [ -z $3 ]; then + ARGSOKAY=0 +fi + +if [ "x$ARGSOKAY" = "x0" ]; then + echo "USAGE: $0 " 1>&2 + exit 1 +fi + +MAJOR="$1" +MINOR="$2" +PATCH="$3" +NEWVERSION="$MAJOR.$MINOR.$PATCH" + +echo "Updating version to '$NEWVERSION' ..." + +# !!! FIXME: This first one is a kinda scary search/replace that might fail later if another X.Y.Z version is added to the file. +perl -w -pi -e 's/(\)\d+\.\d+\.\d+/${1}'$NEWVERSION'/;' Xcode/SDL/Info-Framework.plist + +perl -w -pi -e 's/(Title SDL )\d+\.\d+\.\d+/${1}'$NEWVERSION'/;' Xcode/SDL/pkg-support/SDL.info + +perl -w -pi -e 's/(MARKETING_VERSION\s*=\s*)\d+\.\d+\.\d+/${1}'$NEWVERSION'/;' Xcode/SDL/SDL.xcodeproj/project.pbxproj + +DYVER=`expr $MINOR \* 100 + 1` +perl -w -pi -e 's/(DYLIB_CURRENT_VERSION\s*=\s*)\d+\.\d+\.\d+/${1}'$DYVER'.0.0/;' Xcode/SDL/SDL.xcodeproj/project.pbxproj + +# Set compat to major.minor.0 by default. +perl -w -pi -e 's/(DYLIB_COMPATIBILITY_VERSION\s*=\s*)\d+\.\d+\.\d+/${1}'$DYVER'.0.0/;' Xcode/SDL/SDL.xcodeproj/project.pbxproj + +# non-zero patch? +if [ "x$PATCH" != "x0" ]; then + if [ `expr $MINOR % 2` = "0" ]; then + # If patch is not zero, but minor is even, it's a bugfix release. + perl -w -pi -e 's/(DYLIB_CURRENT_VERSION\s*=\s*)\d+\.\d+\.\d+/${1}'$DYVER'.'$PATCH'.0/;' Xcode/SDL/SDL.xcodeproj/project.pbxproj + + else + # If patch is not zero, but minor is odd, it's a development prerelease. + DYVER=`expr $MINOR \* 100 + $PATCH + 1` + perl -w -pi -e 's/(DYLIB_CURRENT_VERSION\s*=\s*)\d+\.\d+\.\d+/${1}'$DYVER'.0.0/;' Xcode/SDL/SDL.xcodeproj/project.pbxproj + perl -w -pi -e 's/(DYLIB_COMPATIBILITY_VERSION\s*=\s*)\d+\.\d+\.\d+/${1}'$DYVER'.0.0/;' Xcode/SDL/SDL.xcodeproj/project.pbxproj + fi +fi + +perl -w -pi -e 's/\A(SDL_MAJOR_VERSION=)\d+/${1}'$MAJOR'/;' configure.ac +perl -w -pi -e 's/\A(SDL_MINOR_VERSION=)\d+/${1}'$MINOR'/;' configure.ac +perl -w -pi -e 's/\A(SDL_MICRO_VERSION=)\d+/${1}'$PATCH'/;' configure.ac + +perl -w -pi -e 's/\A(set\(SDL_MAJOR_VERSION\s+)\d+/${1}'$MAJOR'/;' CMakeLists.txt +perl -w -pi -e 's/\A(set\(SDL_MINOR_VERSION\s+)\d+/${1}'$MINOR'/;' CMakeLists.txt +perl -w -pi -e 's/\A(set\(SDL_MICRO_VERSION\s+)\d+/${1}'$PATCH'/;' CMakeLists.txt + +perl -w -pi -e 's/\A(.* SDL_MAJOR_VERSION = )\d+/${1}'$MAJOR'/;' android-project/app/src/main/java/org/libsdl/app/SDLActivity.java +perl -w -pi -e 's/\A(.* SDL_MINOR_VERSION = )\d+/${1}'$MINOR'/;' android-project/app/src/main/java/org/libsdl/app/SDLActivity.java +perl -w -pi -e 's/\A(.* SDL_MICRO_VERSION = )\d+/${1}'$PATCH'/;' android-project/app/src/main/java/org/libsdl/app/SDLActivity.java + +perl -w -pi -e 's/\A(MAJOR_VERSION\s*=\s*)\d+/${1}'$MAJOR'/;' Makefile.os2 +perl -w -pi -e 's/\A(MINOR_VERSION\s*=\s*)\d+/${1}'$MINOR'/;' Makefile.os2 +perl -w -pi -e 's/\A(MICRO_VERSION\s*=\s*)\d+/${1}'$PATCH'/;' Makefile.os2 + +perl -w -pi -e 's/\A(MAJOR_VERSION\s*=\s*)\d+/${1}'$MAJOR'/;' Makefile.w32 +perl -w -pi -e 's/\A(MINOR_VERSION\s*=\s*)\d+/${1}'$MINOR'/;' Makefile.w32 +perl -w -pi -e 's/\A(MICRO_VERSION\s*=\s*)\d+/${1}'$PATCH'/;' Makefile.w32 + +perl -w -pi -e 's/(\#define SDL_MAJOR_VERSION\s+)\d+/${1}'$MAJOR'/;' include/SDL_version.h +perl -w -pi -e 's/(\#define SDL_MINOR_VERSION\s+)\d+/${1}'$MINOR'/;' include/SDL_version.h +perl -w -pi -e 's/(\#define SDL_PATCHLEVEL\s+)\d+/${1}'$PATCH'/;' include/SDL_version.h + +perl -w -pi -e 's/(FILEVERSION\s+)\d+,\d+,\d+/${1}'$MAJOR','$MINOR','$PATCH'/;' src/main/windows/version.rc +perl -w -pi -e 's/(PRODUCTVERSION\s+)\d+,\d+,\d+/${1}'$MAJOR','$MINOR','$PATCH'/;' src/main/windows/version.rc +perl -w -pi -e 's/(VALUE "FileVersion", ")\d+, \d+, \d+/${1}'$MAJOR', '$MINOR', '$PATCH'/;' src/main/windows/version.rc +perl -w -pi -e 's/(VALUE "ProductVersion", ")\d+, \d+, \d+/${1}'$MAJOR', '$MINOR', '$PATCH'/;' src/main/windows/version.rc + +echo "Regenerating configure script with new version..." +./autogen.sh |grep -v 'Now you are ready to run ./configure' + +echo "Running build-scripts/test-versioning.sh to verify changes..." +./build-scripts/test-versioning.sh + +echo "All done." +echo "Run 'git diff' and make sure this looks correct, before 'git commit'." + +exit 0 + diff --git a/SDL2-2.30.5/build-scripts/updaterev.sh b/SDL2-2.30.5/build-scripts/updaterev.sh new file mode 100644 index 0000000..cc86382 --- /dev/null +++ b/SDL2-2.30.5/build-scripts/updaterev.sh @@ -0,0 +1,49 @@ +#!/bin/sh +# +# Generate a header file with the current source revision + +outdir=`pwd` +cd `dirname $0` +srcdir=.. +header=$outdir/include/SDL_revision.h +dist= +vendor= + +while [ "$#" -gt 0 ]; do + case "$1" in + (--dist) + dist=yes + shift + ;; + (--vendor) + vendor="$2" + shift 2 + ;; + (*) + echo "$0: Unknown option: $1" >&2 + exit 2 + ;; + esac +done + +rev=`sh showrev.sh 2>/dev/null` +if [ "$rev" != "" ]; then + if [ -n "$dist" ]; then + echo "$rev" > "$outdir/VERSION.txt" + fi + echo "/* Generated by updaterev.sh, do not edit */" >"$header.new" + if [ -n "$vendor" ]; then + echo "#define SDL_VENDOR_INFO \"$vendor\"" >>"$header.new" + fi + echo "#ifdef SDL_VENDOR_INFO" >>"$header.new" + echo "#define SDL_REVISION \"SDL-$rev (\" SDL_VENDOR_INFO \")\"" >>"$header.new" + echo "#else" >>"$header.new" + echo "#define SDL_REVISION \"SDL-$rev\"" >>"$header.new" + echo "#endif" >>"$header.new" + echo "#define SDL_REVISION_NUMBER 0" >>"$header.new" + if diff $header $header.new >/dev/null 2>&1; then + rm "$header.new" + else + mv "$header.new" "$header" + fi +fi diff --git a/SDL2-2.30.5/build-scripts/wikiheaders.pl b/SDL2-2.30.5/build-scripts/wikiheaders.pl new file mode 100644 index 0000000..bf26d64 --- /dev/null +++ b/SDL2-2.30.5/build-scripts/wikiheaders.pl @@ -0,0 +1,1656 @@ +#!/usr/bin/perl -w + +use warnings; +use strict; +use Text::Wrap; + +$Text::Wrap::huge = 'overflow'; + +my $projectfullname = 'Simple Directmedia Layer'; +my $projectshortname = 'SDL'; +my $wikisubdir = ''; +my $incsubdir = 'include'; +my $readmesubdir = undef; +my $apiprefixregex = undef; +my $versionfname = 'include/SDL_version.h'; +my $versionmajorregex = '\A\#define\s+SDL_MAJOR_VERSION\s+(\d+)\Z'; +my $versionminorregex = '\A\#define\s+SDL_MINOR_VERSION\s+(\d+)\Z'; +my $versionpatchregex = '\A\#define\s+SDL_PATCHLEVEL\s+(\d+)\Z'; +my $mainincludefname = 'SDL.h'; +my $selectheaderregex = '\ASDL.*?\.h\Z'; +my $projecturl = 'https://libsdl.org/'; +my $wikiurl = 'https://wiki.libsdl.org'; +my $bugreporturl = 'https://github.com/libsdl-org/sdlwiki/issues/new'; +my $srcpath = undef; +my $wikipath = undef; +my $wikireadmesubdir = 'README'; +my $warn_about_missing = 0; +my $copy_direction = 0; +my $optionsfname = undef; +my $wikipreamble = undef; +my $changeformat = undef; + +foreach (@ARGV) { + $warn_about_missing = 1, next if $_ eq '--warn-about-missing'; + $copy_direction = 1, next if $_ eq '--copy-to-headers'; + $copy_direction = 1, next if $_ eq '--copy-to-header'; + $copy_direction = -1, next if $_ eq '--copy-to-wiki'; + $copy_direction = -2, next if $_ eq '--copy-to-manpages'; + if (/\A--options=(.*)\Z/) { + $optionsfname = $1; + next; + } elsif (/\A--changeformat=(.*)\Z/) { + $changeformat = $1; + next; + } + $srcpath = $_, next if not defined $srcpath; + $wikipath = $_, next if not defined $wikipath; +} + +my $default_optionsfname = '.wikiheaders-options'; +$default_optionsfname = "$srcpath/$default_optionsfname" if defined $srcpath; + +if ((not defined $optionsfname) && (-f $default_optionsfname)) { + $optionsfname = $default_optionsfname; +} + +if (defined $optionsfname) { + open OPTIONS, '<', $optionsfname or die("Failed to open options file '$optionsfname': $!\n"); + while () { + chomp; + if (/\A(.*?)\=(.*)\Z/) { + my $key = $1; + my $val = $2; + $key =~ s/\A\s+//; + $key =~ s/\s+\Z//; + $val =~ s/\A\s+//; + $val =~ s/\s+\Z//; + $warn_about_missing = int($val), next if $key eq 'warn_about_missing'; + $srcpath = $val, next if $key eq 'srcpath'; + $wikipath = $val, next if $key eq 'wikipath'; + $apiprefixregex = $val, next if $key eq 'apiprefixregex'; + $projectfullname = $val, next if $key eq 'projectfullname'; + $projectshortname = $val, next if $key eq 'projectshortname'; + $wikisubdir = $val, next if $key eq 'wikisubdir'; + $incsubdir = $val, next if $key eq 'incsubdir'; + $readmesubdir = $val, next if $key eq 'readmesubdir'; + $versionmajorregex = $val, next if $key eq 'versionmajorregex'; + $versionminorregex = $val, next if $key eq 'versionminorregex'; + $versionpatchregex = $val, next if $key eq 'versionpatchregex'; + $versionfname = $val, next if $key eq 'versionfname'; + $mainincludefname = $val, next if $key eq 'mainincludefname'; + $selectheaderregex = $val, next if $key eq 'selectheaderregex'; + $projecturl = $val, next if $key eq 'projecturl'; + $wikiurl = $val, next if $key eq 'wikiurl'; + $bugreporturl = $val, next if $key eq 'bugreporturl'; + $wikipreamble = $val, next if $key eq 'wikipreamble'; + } + } + close(OPTIONS); +} + +my $wordwrap_mode = 'mediawiki'; +sub wordwrap_atom { # don't call this directly. + my $str = shift; + my $retval = ''; + + # wordwrap but leave links intact, even if they overflow. + if ($wordwrap_mode eq 'mediawiki') { + while ($str =~ s/(.*?)\s*(\[https?\:\/\/.*?\s+.*?\])\s*//ms) { + $retval .= fill('', '', $1); # wrap it. + $retval .= "\n$2\n"; # don't wrap it. + } + } elsif ($wordwrap_mode eq 'md') { + while ($str =~ s/(.*?)\s*(\[.*?\]\(https?\:\/\/.*?\))\s*//ms) { + $retval .= fill('', '', $1); # wrap it. + $retval .= "\n$2\n"; # don't wrap it. + } + } + + return $retval . fill('', '', $str); +} + +sub wordwrap_with_bullet_indent { # don't call this directly. + my $bullet = shift; + my $str = shift; + my $retval = ''; + + #print("WORDWRAP BULLET ('$bullet'):\n\n$str\n\n"); + + # You _can't_ (at least with Pandoc) have a bullet item with a newline in + # MediaWiki, so _remove_ wrapping! + if ($wordwrap_mode eq 'mediawiki') { + $retval = "$bullet$str"; + $retval =~ s/\n/ /gms; + $retval =~ s/\s+$//gms; + #print("WORDWRAP BULLET DONE:\n\n$retval\n\n"); + return "$retval\n"; + } + + my $bulletlen = length($bullet); + + # wrap it and then indent each line to be under the bullet. + $Text::Wrap::columns -= $bulletlen; + my @wrappedlines = split /\n/, wordwrap_atom($str); + $Text::Wrap::columns += $bulletlen; + + my $prefix = $bullet; + my $usual_prefix = ' ' x $bulletlen; + + foreach (@wrappedlines) { + s/\s*\Z//; + $retval .= "$prefix$_\n"; + $prefix = $usual_prefix; + } + + return $retval; +} + +sub wordwrap_one_paragraph { # don't call this directly. + my $retval = ''; + my $p = shift; + #print "\n\n\nPARAGRAPH: [$p]\n\n\n"; + if ($p =~ s/\A([\*\-] )//) { # bullet list, starts with "* " or "- ". + my $bullet = $1; + my $item = ''; + my @items = split /\n/, $p; + foreach (@items) { + if (s/\A([\*\-] )//) { + $retval .= wordwrap_with_bullet_indent($bullet, $item); + $item = ''; + } + s/\A\s*//; + $item .= "$_\n"; # accumulate lines until we hit the end or another bullet. + } + if ($item ne '') { + $retval .= wordwrap_with_bullet_indent($bullet, $item); + } + } else { + $retval = wordwrap_atom($p) . "\n"; + } + + return $retval; +} + +sub wordwrap_paragraphs { # don't call this directly. + my $str = shift; + my $retval = ''; + my @paragraphs = split /\n\n/, $str; + foreach (@paragraphs) { + next if $_ eq ''; + $retval .= wordwrap_one_paragraph($_); + $retval .= "\n"; + } + return $retval; +} + +my $wordwrap_default_columns = 76; +sub wordwrap { + my $str = shift; + my $columns = shift; + + $columns = $wordwrap_default_columns if not defined $columns; + $columns += $wordwrap_default_columns if $columns < 0; + $Text::Wrap::columns = $columns; + + my $retval = ''; + + #print("\n\nWORDWRAP:\n\n$str\n\n\n"); + + $str =~ s/\A\n+//ms; + + while ($str =~ s/(.*?)(\`\`\`.*?\`\`\`|\)//ms) { + #print("\n\nWORDWRAP BLOCK:\n\n$1\n\n ===\n\n$2\n\n\n"); + $retval .= wordwrap_paragraphs($1); # wrap it. + $retval .= "$2\n\n"; # don't wrap it. + } + + $retval .= wordwrap_paragraphs($str); # wrap what's left. + $retval =~ s/\n+\Z//ms; + + #print("\n\nWORDWRAP DONE:\n\n$retval\n\n\n"); + return $retval; +} + +# This assumes you're moving from Markdown (in the Doxygen data) to Wiki, which +# is why the 'md' section is so sparse. +sub wikify_chunk { + my $wikitype = shift; + my $str = shift; + my $codelang = shift; + my $code = shift; + + #print("\n\nWIKIFY CHUNK:\n\n$str\n\n\n"); + + if ($wikitype eq 'mediawiki') { + # convert `code` things first, so they aren't mistaken for other markdown items. + my $codedstr = ''; + while ($str =~ s/\A(.*?)\`(.*?)\`//ms) { + my $codeblock = $2; + $codedstr .= wikify_chunk($wikitype, $1, undef, undef); + if (defined $apiprefixregex) { + # Convert obvious API things to wikilinks, even inside `code` blocks. + $codeblock =~ s/\b($apiprefixregex[a-zA-Z0-9_]+)/[[$1]]/gms; + } + $codedstr .= "$codeblock"; + } + + # Convert obvious API things to wikilinks. + if (defined $apiprefixregex) { + $str =~ s/\b($apiprefixregex[a-zA-Z0-9_]+)/[[$1]]/gms; + } + + # Make some Markdown things into MediaWiki... + + # links + $str =~ s/\[(.*?)\]\((https?\:\/\/.*?)\)/\[$2 $1\]/g; + + # bold+italic + $str =~ s/\*\*\*(.*?)\*\*\*/'''''$1'''''/gms; + + # bold + $str =~ s/\*\*(.*?)\*\*/'''$1'''/gms; + + # italic + $str =~ s/\*(.*?)\*/''$1''/gms; + + # bullets + $str =~ s/^\- /* /gm; + + $str = $codedstr . $str; + + if (defined $code) { + $str .= "$code<\/syntaxhighlight>"; + } + } elsif ($wikitype eq 'md') { + # convert `code` things first, so they aren't mistaken for other markdown items. + my $codedstr = ''; + while ($str =~ s/\A(.*?)(\`.*?\`)//ms) { + my $codeblock = $2; + $codedstr .= wikify_chunk($wikitype, $1, undef, undef); + if (defined $apiprefixregex) { + # Convert obvious API things to wikilinks, even inside `code` blocks, + # BUT ONLY IF the entire code block is the API thing, + # So something like "just call `SDL_Whatever`" will become + # "just call [`SDL_Whatever`](SDL_Whatever)", but + # "just call `SDL_Whatever(7)`" will not. It's just the safest + # way to do this without resorting to wrapping things in html tags. + $codeblock =~ s/\A\`($apiprefixregex[a-zA-Z0-9_]+)\`\Z/[`$1`]($1)/gms; + } + $codedstr .= $codeblock; + } + + # Convert obvious API things to wikilinks. + if (defined $apiprefixregex) { + $str =~ s/\b($apiprefixregex[a-zA-Z0-9_]+)/[$1]($1)/gms; + } + + $str = $codedstr . $str; + + if (defined $code) { + $str .= "```$codelang$code```"; + } + } + + #print("\n\nWIKIFY CHUNK DONE:\n\n$str\n\n\n"); + + return $str; +} + +sub wikify { + my $wikitype = shift; + my $str = shift; + my $retval = ''; + + #print("WIKIFY WHOLE:\n\n$str\n\n\n"); + + while ($str =~ s/\A(.*?)\`\`\`(c\+\+|c)(.*?)\`\`\`//ms) { + $retval .= wikify_chunk($wikitype, $1, $2, $3); + } + $retval .= wikify_chunk($wikitype, $str, undef, undef); + + #print("WIKIFY WHOLE DONE:\n\n$retval\n\n\n"); + + return $retval; +} + + +my $dewikify_mode = 'md'; +my $dewikify_manpage_code_indent = 1; + +sub dewikify_chunk { + my $wikitype = shift; + my $str = shift; + my $codelang = shift; + my $code = shift; + + #print("\n\nDEWIKIFY CHUNK:\n\n$str\n\n\n"); + + if ($dewikify_mode eq 'md') { + if ($wikitype eq 'mediawiki') { + # Doxygen supports Markdown (and it just simply looks better than MediaWiki + # when looking at the raw headers), so do some conversions here as necessary. + + # Dump obvious wikilinks. + if (defined $apiprefixregex) { + $str =~ s/\[\[($apiprefixregex[a-zA-Z0-9_]+)\]\]/$1/gms; + } + + # links + $str =~ s/\[(https?\:\/\/.*?)\s+(.*?)\]/\[$2\]\($1\)/g; + + # is also popular. :/ + $str =~ s/\(.*?)<\/code>/`$1`/gms; + + # bold+italic + $str =~ s/'''''(.*?)'''''/***$1***/gms; + + # bold + $str =~ s/'''(.*?)'''/**$1**/gms; + + # italic + $str =~ s/''(.*?)''/*$1*/gms; + + # bullets + $str =~ s/^\* /- /gm; + } elsif ($wikitype eq 'md') { + # Dump obvious wikilinks. The rest can just passthrough. + if (defined $apiprefixregex) { + $str =~ s/\[(\`?$apiprefixregex[a-zA-Z0-9_]+\`?)\]\($apiprefixregex[a-zA-Z0-9_]+\)/$1/gms; + } + } + + if (defined $code) { + $str .= "```$codelang$code```"; + } + } elsif ($dewikify_mode eq 'manpage') { + $str =~ s/\./\\[char46]/gms; # make sure these can't become control codes. + if ($wikitype eq 'mediawiki') { + # Dump obvious wikilinks. + if (defined $apiprefixregex) { + $str =~ s/\s*\[\[($apiprefixregex[a-zA-Z0-9_]+)\]\]\s*/\n.BR $1\n/gms; + } + + # links + $str =~ s/\[(https?\:\/\/.*?)\s+(.*?)\]/\n.URL "$1" "$2"\n/g; + + # is also popular. :/ + $str =~ s/\s*\(.*?)<\/code>\s*/\n.BR $1\n/gms; + + # bold+italic + $str =~ s/\s*'''''(.*?)'''''\s*/\n.BI $1\n/gms; + + # bold + $str =~ s/\s*'''(.*?)'''\s*/\n.B $1\n/gms; + + # italic + $str =~ s/\s*''(.*?)''\s*/\n.I $1\n/gms; + + # bullets + $str =~ s/^\* /\n\\\(bu /gm; + } elsif ($wikitype eq 'md') { + # Dump obvious wikilinks. + if (defined $apiprefixregex) { + $str =~ s/\[(\`?$apiprefixregex[a-zA-Z0-9_]+\`?)\]\($apiprefixregex[a-zA-Z0-9_]+\)/\n.BR $1\n/gms; + } + + # links + $str =~ s/\[(.*?)]\((https?\:\/\/.*?)\)/\n.URL "$2" "$1"\n/g; + + # is also popular. :/ + $str =~ s/\s*\`(.*?)\`\s*/\n.BR $1\n/gms; + + # bold+italic + $str =~ s/\s*\*\*\*(.*?)\*\*\*\s*/\n.BI $1\n/gms; + + # bold + $str =~ s/\s*\*\*(.*?)\*\*\s*/\n.B $1\n/gms; + + # italic + $str =~ s/\s*\*(.*?)\*\s*/\n.I $1\n/gms; + + # bullets + $str =~ s/^\- /\n\\\(bu /gm; + + } else { + die("Unexpected wikitype when converting to manpages\n"); # !!! FIXME: need to handle Markdown wiki pages. + } + + if (defined $code) { + $code =~ s/\A\n+//gms; + $code =~ s/\n+\Z//gms; + if ($dewikify_manpage_code_indent) { + $str .= "\n.IP\n" + } else { + $str .= "\n.PP\n" + } + $str .= ".EX\n$code\n.EE\n.PP\n"; + } + } else { + die("Unexpected dewikify_mode\n"); + } + + #print("\n\nDEWIKIFY CHUNK DONE:\n\n$str\n\n\n"); + + return $str; +} + +sub dewikify { + my $wikitype = shift; + my $str = shift; + return '' if not defined $str; + + #print("DEWIKIFY WHOLE:\n\n$str\n\n\n"); + + $str =~ s/\A[\s\n]*\= .*? \=\s*?\n+//ms; + $str =~ s/\A[\s\n]*\=\= .*? \=\=\s*?\n+//ms; + + my $retval = ''; + while ($str =~ s/\A(.*?)(.*?)<\/syntaxhighlight\>//ms) { + $retval .= dewikify_chunk($wikitype, $1, $2, $3); + } + $retval .= dewikify_chunk($wikitype, $str, undef, undef); + + #print("DEWIKIFY WHOLE DONE:\n\n$retval\n\n\n"); + + return $retval; +} + +sub filecopy { + my $src = shift; + my $dst = shift; + my $endline = shift; + $endline = "\n" if not defined $endline; + + open(COPYIN, '<', $src) or die("Failed to open '$src' for reading: $!\n"); + open(COPYOUT, '>', $dst) or die("Failed to open '$dst' for writing: $!\n"); + while () { + chomp; + s/[ \t\r\n]*\Z//; + print COPYOUT "$_$endline"; + } + close(COPYOUT); + close(COPYIN); +} + +sub usage { + die("USAGE: $0 [--copy-to-headers|--copy-to-wiki|--copy-to-manpages] [--warn-about-missing]\n\n"); +} + +usage() if not defined $srcpath; +usage() if not defined $wikipath; +#usage() if $copy_direction == 0; + +my @standard_wiki_sections = ( + 'Draft', + '[Brief]', + 'Deprecated', + 'Syntax', + 'Function Parameters', + 'Return Value', + 'Remarks', + 'Thread Safety', + 'Version', + 'Code Examples', + 'Related Functions' +); + +# Sections that only ever exist in the wiki and shouldn't be deleted when +# not found in the headers. +my %only_wiki_sections = ( # The ones don't mean anything, I just need to check for key existence. + 'Draft', 1, + 'Code Examples', 1 +); + + +my %headers = (); # $headers{"SDL_audio.h"} -> reference to an array of all lines of text in SDL_audio.h. +my %headerfuncs = (); # $headerfuncs{"SDL_OpenAudio"} -> string of header documentation for SDL_OpenAudio, with comment '*' bits stripped from the start. Newlines embedded! +my %headerdecls = (); +my %headerfuncslocation = (); # $headerfuncslocation{"SDL_OpenAudio"} -> name of header holding SDL_OpenAudio define ("SDL_audio.h" in this case). +my %headerfuncschunk = (); # $headerfuncschunk{"SDL_OpenAudio"} -> offset in array in %headers that should be replaced for this function. +my %headerfuncshasdoxygen = (); # $headerfuncschunk{"SDL_OpenAudio"} -> 1 if there was no existing doxygen for this function. + +my $incpath = "$srcpath"; +$incpath .= "/$incsubdir" if $incsubdir ne ''; + +my $wikireadmepath = "$wikipath/$wikireadmesubdir"; +my $readmepath = undef; +if (defined $readmesubdir) { + $readmepath = "$srcpath/$readmesubdir"; +} + +opendir(DH, $incpath) or die("Can't opendir '$incpath': $!\n"); +while (my $d = readdir(DH)) { + my $dent = $d; + next if not $dent =~ /$selectheaderregex/; # just selected headers. + open(FH, '<', "$incpath/$dent") or die("Can't open '$incpath/$dent': $!\n"); + + my @contents = (); + + while () { + chomp; + my $decl; + my @templines; + my $str; + my $has_doxygen = 1; + if (/\A\s*extern\s+(SDL_DEPRECATED\s+|)DECLSPEC/) { # a function declaration without a doxygen comment? + @templines = (); + $decl = $_; + $str = ''; + $has_doxygen = 0; + } elsif (not /\A\/\*\*\s*\Z/) { # not doxygen comment start? + push @contents, $_; + next; + } else { # Start of a doxygen comment, parse it out. + @templines = ( $_ ); + while () { + chomp; + push @templines, $_; + last if /\A\s*\*\/\Z/; + if (s/\A\s*\*\s*\`\`\`/```/) { # this is a hack, but a lot of other code relies on the whitespace being trimmed, but we can't trim it in code blocks... + $str .= "$_\n"; + while () { + chomp; + push @templines, $_; + s/\A\s*\*\s?//; + if (s/\A\s*\`\`\`/```/) { + $str .= "$_\n"; + last; + } else { + $str .= "$_\n"; + } + } + } else { + s/\A\s*\*\s*//; + $str .= "$_\n"; + } + } + + $decl = ; + $decl = '' if not defined $decl; + chomp($decl); + if (not $decl =~ /\A\s*extern\s+(SDL_DEPRECATED\s+|)DECLSPEC/) { + #print "Found doxygen but no function sig:\n$str\n\n"; + foreach (@templines) { + push @contents, $_; + } + push @contents, $decl; + next; + } + } + + my @decllines = ( $decl ); + + if (not $decl =~ /\)\s*;/) { + while () { + chomp; + push @decllines, $_; + s/\A\s+//; + s/\s+\Z//; + $decl .= " $_"; + last if /\)\s*;/; + } + } + + $decl =~ s/\s+\);\Z/);/; + $decl =~ s/\s+\Z//; + #print("DECL: [$decl]\n"); + + my $fn = ''; + if ($decl =~ /\A\s*extern\s+(SDL_DEPRECATED\s+|)DECLSPEC\s+(const\s+|)(unsigned\s+|)(.*?)\s*(\*?)\s*SDLCALL\s+(.*?)\s*\((.*?)\);/) { + $fn = $6; + #$decl =~ s/\A\s*extern\s+DECLSPEC\s+(.*?)\s+SDLCALL/$1/; + } else { + #print "Found doxygen but no function sig:\n$str\n\n"; + foreach (@templines) { + push @contents, $_; + } + foreach (@decllines) { + push @contents, $_; + } + next; + } + + $decl = ''; # build this with the line breaks, since it looks better for syntax highlighting. + foreach (@decllines) { + if ($decl eq '') { + $decl = $_; + $decl =~ s/\Aextern\s+(SDL_DEPRECATED\s+|)DECLSPEC\s+(.*?)\s+(\*?)SDLCALL\s+/$2$3 /; + } else { + my $trimmed = $_; + # !!! FIXME: trim space for SDL_DEPRECATED if it was used, too. + $trimmed =~ s/\A\s{24}//; # 24 for shrinking to match the removed "extern DECLSPEC SDLCALL " + $decl .= $trimmed; + } + $decl .= "\n"; + } + + #print("$fn:\n$str\n\n"); + + # There might be multiple declarations of a function due to #ifdefs, + # and only one of them will have documentation. If we hit an + # undocumented one before, delete the placeholder line we left for + # it so it doesn't accumulate a new blank line on each run. + my $skipfn = 0; + if (defined $headerfuncshasdoxygen{$fn}) { + if ($headerfuncshasdoxygen{$fn} == 0) { # An undocumented declaration already exists, nuke its placeholder line. + delete $contents[$headerfuncschunk{$fn}]; # delete DOES NOT RENUMBER existing elements! + } else { # documented function already existed? + $skipfn = 1; # don't add this copy to the list of functions. + if ($has_doxygen) { + print STDERR "WARNING: Function '$fn' appears to be documented in multiple locations. Only keeping the first one we saw!\n"; + } + push @contents, join("\n", @decllines); # just put the existing declation in as-is. + } + } + + if (!$skipfn) { + $headerfuncs{$fn} = $str; + $headerdecls{$fn} = $decl; + $headerfuncslocation{$fn} = $dent; + $headerfuncschunk{$fn} = scalar(@contents); + $headerfuncshasdoxygen{$fn} = $has_doxygen; + push @contents, join("\n", @templines); + push @contents, join("\n", @decllines); + } + + } + close(FH); + + $headers{$dent} = \@contents; +} +closedir(DH); + + +# !!! FIXME: we need to parse enums and typedefs and structs and defines and and and and and... +# !!! FIXME: (but functions are good enough for now.) + +my %wikitypes = (); # contains string of wiki page extension, like $wikitypes{"SDL_OpenAudio"} == 'mediawiki' +my %wikifuncs = (); # contains references to hash of strings, each string being the full contents of a section of a wiki page, like $wikifuncs{"SDL_OpenAudio"}{"Remarks"}. +my %wikisectionorder = (); # contains references to array, each array item being a key to a wikipage section in the correct order, like $wikisectionorder{"SDL_OpenAudio"}[2] == 'Remarks' +opendir(DH, $wikipath) or die("Can't opendir '$wikipath': $!\n"); +while (my $d = readdir(DH)) { + my $dent = $d; + my $type = ''; + if ($dent =~ /\.(md|mediawiki)\Z/) { + $type = $1; + } else { + next; # only dealing with wiki pages. + } + + my $fn = $dent; + $fn =~ s/\..*\Z//; + + # Ignore FrontPage. + next if $fn eq 'FrontPage'; + + # Ignore "Category*" pages. + next if ($fn =~ /\ACategory/); + + open(FH, '<', "$wikipath/$dent") or die("Can't open '$wikipath/$dent': $!\n"); + + my $current_section = '[start]'; + my @section_order = ( $current_section ); + my %sections = (); + $sections{$current_section} = ''; + + my $firstline = 1; + + while () { + chomp; + my $orig = $_; + s/\A\s*//; + s/\s*\Z//; + + if ($type eq 'mediawiki') { + if (defined($wikipreamble) && $firstline && /\A\=\=\=\=\=\= (.*?) \=\=\=\=\=\=\Z/ && ($1 eq $wikipreamble)) { + $firstline = 0; # skip this. + next; + } elsif (/\A\= (.*?) \=\Z/) { + $firstline = 0; + $current_section = ($1 eq $fn) ? '[Brief]' : $1; + die("Doubly-defined section '$current_section' in '$dent'!\n") if defined $sections{$current_section}; + push @section_order, $current_section; + $sections{$current_section} = ''; + } elsif (/\A\=\= (.*?) \=\=\Z/) { + $firstline = 0; + $current_section = ($1 eq $fn) ? '[Brief]' : $1; + die("Doubly-defined section '$current_section' in '$dent'!\n") if defined $sections{$current_section}; + push @section_order, $current_section; + $sections{$current_section} = ''; + next; + } elsif (/\A\-\-\-\-\Z/) { + $firstline = 0; + $current_section = '[footer]'; + die("Doubly-defined section '$current_section' in '$dent'!\n") if defined $sections{$current_section}; + push @section_order, $current_section; + $sections{$current_section} = ''; + next; + } + } elsif ($type eq 'md') { + if (defined($wikipreamble) && $firstline && /\A\#\#\#\#\#\# (.*?)\Z/ && ($1 eq $wikipreamble)) { + $firstline = 0; # skip this. + next; + } elsif (/\A\#+ (.*?)\Z/) { + $firstline = 0; + $current_section = ($1 eq $fn) ? '[Brief]' : $1; + die("Doubly-defined section '$current_section' in '$dent'!\n") if defined $sections{$current_section}; + push @section_order, $current_section; + $sections{$current_section} = ''; + next; + } elsif (/\A\-\-\-\-\Z/) { + $firstline = 0; + $current_section = '[footer]'; + die("Doubly-defined section '$current_section' in '$dent'!\n") if defined $sections{$current_section}; + push @section_order, $current_section; + $sections{$current_section} = ''; + next; + } + } else { + die("Unexpected wiki file type. Fixme!\n"); + } + + if ($firstline) { + $firstline = ($_ ne ''); + } + if (!$firstline) { + $sections{$current_section} .= "$orig\n"; + } + } + close(FH); + + foreach (keys %sections) { + $sections{$_} =~ s/\A\n+//; + $sections{$_} =~ s/\n+\Z//; + $sections{$_} .= "\n"; + } + + if (0) { + foreach (@section_order) { + print("$fn SECTION '$_':\n"); + print($sections{$_}); + print("\n\n"); + } + } + + $wikitypes{$fn} = $type; + $wikifuncs{$fn} = \%sections; + $wikisectionorder{$fn} = \@section_order; +} +closedir(DH); + + +if ($warn_about_missing) { + foreach (keys %wikifuncs) { + my $fn = $_; + if (not defined $headerfuncs{$fn}) { + print("WARNING: $fn defined in the wiki but not the headers!\n"); + } + } + + foreach (keys %headerfuncs) { + my $fn = $_; + if (not defined $wikifuncs{$fn}) { + print("WARNING: $fn defined in the headers but not the wiki!\n"); + } + } +} + +if ($copy_direction == 1) { # --copy-to-headers + my %changed_headers = (); + + $dewikify_mode = 'md'; + $wordwrap_mode = 'md'; # the headers use Markdown format. + + foreach (keys %headerfuncs) { + my $fn = $_; + next if not defined $wikifuncs{$fn}; # don't have a page for that function, skip it. + my $wikitype = $wikitypes{$fn}; + my $sectionsref = $wikifuncs{$fn}; + my $remarks = $sectionsref->{'Remarks'}; + my $params = $sectionsref->{'Function Parameters'}; + my $returns = $sectionsref->{'Return Value'}; + my $threadsafety = $sectionsref->{'Thread Safety'}; + my $version = $sectionsref->{'Version'}; + my $related = $sectionsref->{'Related Functions'}; + my $deprecated = $sectionsref->{'Deprecated'}; + my $brief = $sectionsref->{'[Brief]'}; + my $addblank = 0; + my $str = ''; + + $headerfuncshasdoxygen{$fn} = 1; # Added/changed doxygen for this header. + + $brief = dewikify($wikitype, $brief); + $brief =~ s/\A(.*?\.) /$1\n/; # \brief should only be one sentence, delimited by a period+space. Split if necessary. + my @briefsplit = split /\n/, $brief; + $brief = shift @briefsplit; + + if (defined $remarks) { + $remarks = join("\n", @briefsplit) . dewikify($wikitype, $remarks); + } + + if (defined $brief) { + $str .= "\n" if $addblank; $addblank = 1; + $str .= wordwrap($brief) . "\n"; + } + + if (defined $remarks) { + $str .= "\n" if $addblank; $addblank = 1; + $str .= wordwrap($remarks) . "\n"; + } + + if (defined $deprecated) { + # !!! FIXME: lots of code duplication in all of these. + $str .= "\n" if $addblank; $addblank = 1; + my $v = dewikify($wikitype, $deprecated); + my $whitespacelen = length("\\deprecated") + 1; + my $whitespace = ' ' x $whitespacelen; + $v = wordwrap($v, -$whitespacelen); + my @desclines = split /\n/, $v; + my $firstline = shift @desclines; + $str .= "\\deprecated $firstline\n"; + foreach (@desclines) { + $str .= "${whitespace}$_\n"; + } + } + + if (defined $params) { + $str .= "\n" if $addblank; $addblank = (defined $returns) ? 0 : 1; + my @lines = split /\n/, dewikify($wikitype, $params); + if ($wikitype eq 'mediawiki') { + die("Unexpected data parsing MediaWiki table") if (shift @lines ne '{|'); # Dump the '{|' start + while (scalar(@lines) >= 3) { + my $name = shift @lines; + my $desc = shift @lines; + my $terminator = shift @lines; # the '|-' or '|}' line. + last if ($terminator ne '|-') and ($terminator ne '|}'); # we seem to have run out of table. + $name =~ s/\A\|\s*//; + $name =~ s/\A\*\*(.*?)\*\*/$1/; + $name =~ s/\A\'\'\'(.*?)\'\'\'/$1/; + $desc =~ s/\A\|\s*//; + #print STDERR "FN: $fn NAME: $name DESC: $desc TERM: $terminator\n"; + my $whitespacelen = length($name) + 8; + my $whitespace = ' ' x $whitespacelen; + $desc = wordwrap($desc, -$whitespacelen); + my @desclines = split /\n/, $desc; + my $firstline = shift @desclines; + $str .= "\\param $name $firstline\n"; + foreach (@desclines) { + $str .= "${whitespace}$_\n"; + } + } + } elsif ($wikitype eq 'md') { + my $l; + $l = shift @lines; + die("Unexpected data parsing Markdown table") if (not $l =~ /\A\s*\|\s*\|\s*\|\s*\Z/); + $l = shift @lines; + die("Unexpected data parsing Markdown table") if (not $l =~ /\A\s*\|\s*\-*\s*\|\s*\-*\s*\|\s*\Z/); + while (scalar(@lines) >= 1) { + $l = shift @lines; + if ($l =~ /\A\s*\|\s*(.*?)\s*\|\s*(.*?)\s*\|\s*\Z/) { + my $name = $1; + my $desc = $2; + $name =~ s/\A\*\*(.*?)\*\*/$1/; + $name =~ s/\A\'\'\'(.*?)\'\'\'/$1/; + #print STDERR "FN: $fn NAME: $name DESC: $desc\n"; + my $whitespacelen = length($name) + 8; + my $whitespace = ' ' x $whitespacelen; + $desc = wordwrap($desc, -$whitespacelen); + my @desclines = split /\n/, $desc; + my $firstline = shift @desclines; + $str .= "\\param $name $firstline\n"; + foreach (@desclines) { + $str .= "${whitespace}$_\n"; + } + } else { + last; # we seem to have run out of table. + } + } + } else { + die("write me"); + } + } + + if (defined $returns) { + $str .= "\n" if $addblank; $addblank = 1; + my $r = dewikify($wikitype, $returns); + my $retstr = "\\returns"; + if ($r =~ s/\AReturn(s?) //) { + $retstr = "\\return$1"; + } + + my $whitespacelen = length($retstr) + 1; + my $whitespace = ' ' x $whitespacelen; + $r = wordwrap($r, -$whitespacelen); + my @desclines = split /\n/, $r; + my $firstline = shift @desclines; + $str .= "$retstr $firstline\n"; + foreach (@desclines) { + $str .= "${whitespace}$_\n"; + } + } + + if (defined $threadsafety) { + # !!! FIXME: lots of code duplication in all of these. + $str .= "\n" if $addblank; $addblank = 1; + my $v = dewikify($wikitype, $threadsafety); + my $whitespacelen = length("\\threadsafety") + 1; + my $whitespace = ' ' x $whitespacelen; + $v = wordwrap($v, -$whitespacelen); + my @desclines = split /\n/, $v; + my $firstline = shift @desclines; + $str .= "\\threadsafety $firstline\n"; + foreach (@desclines) { + $str .= "${whitespace}$_\n"; + } + } + + if (defined $version) { + # !!! FIXME: lots of code duplication in all of these. + $str .= "\n" if $addblank; $addblank = 1; + my $v = dewikify($wikitype, $version); + my $whitespacelen = length("\\since") + 1; + my $whitespace = ' ' x $whitespacelen; + $v = wordwrap($v, -$whitespacelen); + my @desclines = split /\n/, $v; + my $firstline = shift @desclines; + $str .= "\\since $firstline\n"; + foreach (@desclines) { + $str .= "${whitespace}$_\n"; + } + } + + if (defined $related) { + # !!! FIXME: lots of code duplication in all of these. + $str .= "\n" if $addblank; $addblank = 1; + my $v = dewikify($wikitype, $related); + my @desclines = split /\n/, $v; + foreach (@desclines) { + s/\A(\:|\* )//; + s/\(\)\Z//; # Convert "SDL_Func()" to "SDL_Func" + s/\[\[(.*?)\]\]/$1/; # in case some wikilinks remain. + s/\[(.*?)\]\(.*?\)/$1/; # in case some wikilinks remain. + s/\A\/*//; + $str .= "\\sa $_\n"; + } + } + + my $header = $headerfuncslocation{$fn}; + my $contentsref = $headers{$header}; + my $chunk = $headerfuncschunk{$fn}; + + my @lines = split /\n/, $str; + + my $addnewline = (($chunk > 0) && ($$contentsref[$chunk-1] ne '')) ? "\n" : ''; + + my $output = "$addnewline/**\n"; + foreach (@lines) { + chomp; + s/\s*\Z//; + if ($_ eq '') { + $output .= " *\n"; + } else { + $output .= " * $_\n"; + } + } + $output .= " */"; + + #print("$fn:\n$output\n\n"); + + $$contentsref[$chunk] = $output; + #$$contentsref[$chunk+1] = $headerdecls{$fn}; + + $changed_headers{$header} = 1; + } + + foreach (keys %changed_headers) { + my $header = $_; + + # this is kinda inefficient, but oh well. + my @removelines = (); + foreach (keys %headerfuncslocation) { + my $fn = $_; + next if $headerfuncshasdoxygen{$fn}; + next if $headerfuncslocation{$fn} ne $header; + # the index of the blank line we put before the function declaration in case we needed to replace it with new content from the wiki. + push @removelines, $headerfuncschunk{$fn}; + } + + my $contentsref = $headers{$header}; + foreach (@removelines) { + delete $$contentsref[$_]; # delete DOES NOT RENUMBER existing elements! + } + + my $path = "$incpath/$header.tmp"; + open(FH, '>', $path) or die("Can't open '$path': $!\n"); + foreach (@$contentsref) { + print FH "$_\n" if defined $_; + } + close(FH); + rename($path, "$incpath/$header") or die("Can't rename '$path' to '$incpath/$header': $!\n"); + } + + if (defined $readmepath) { + if ( -d $wikireadmepath ) { + mkdir($readmepath); # just in case + opendir(DH, $wikireadmepath) or die("Can't opendir '$wikireadmepath': $!\n"); + while (readdir(DH)) { + my $dent = $_; + if ($dent =~ /\A(.*?)\.md\Z/) { # we only bridge Markdown files here. + next if $1 eq 'FrontPage'; + filecopy("$wikireadmepath/$dent", "$readmepath/README-$dent", "\r\n"); + } + } + closedir(DH); + } + } +} elsif ($copy_direction == -1) { # --copy-to-wiki + + if (defined $changeformat) { + $dewikify_mode = $changeformat; + $wordwrap_mode = $changeformat; + } + + foreach (keys %headerfuncs) { + my $fn = $_; + next if not $headerfuncshasdoxygen{$fn}; + my $origwikitype = defined $wikitypes{$fn} ? $wikitypes{$fn} : 'md'; # default to MarkDown for new stuff. + my $wikitype = (defined $changeformat) ? $changeformat : $origwikitype; + die("Unexpected wikitype '$wikitype'\n") if (($wikitype ne 'mediawiki') and ($wikitype ne 'md') and ($wikitype ne 'manpage')); + + #print("$fn\n"); next; + + $wordwrap_mode = $wikitype; + + my $raw = $headerfuncs{$fn}; # raw doxygen text with comment characters stripped from start/end and start of each line. + next if not defined $raw; + $raw =~ s/\A\s*\\brief\s+//; # Technically we don't need \brief (please turn on JAVADOC_AUTOBRIEF if you use Doxygen), so just in case one is present, strip it. + + my @doxygenlines = split /\n/, $raw; + my $brief = ''; + while (@doxygenlines) { + last if $doxygenlines[0] =~ /\A\\/; # some sort of doxygen command, assume we're past the general remarks. + last if $doxygenlines[0] =~ /\A\s*\Z/; # blank line? End of paragraph, done. + my $l = shift @doxygenlines; + chomp($l); + $l =~ s/\A\s*//; + $l =~ s/\s*\Z//; + $brief .= "$l "; + } + + $brief =~ s/\A(.*?\.) /$1\n\n/; # \brief should only be one sentence, delimited by a period+space. Split if necessary. + my @briefsplit = split /\n/, $brief; + $brief = wikify($wikitype, shift @briefsplit) . "\n"; + @doxygenlines = (@briefsplit, @doxygenlines); + + my $remarks = ''; + # !!! FIXME: wordwrap and wikify might handle this, now. + while (@doxygenlines) { + last if $doxygenlines[0] =~ /\A\\/; # some sort of doxygen command, assume we're past the general remarks. + my $l = shift @doxygenlines; + if ($l =~ /\A\`\`\`/) { # syntax highlighting, don't reformat. + $remarks .= "$l\n"; + while ((@doxygenlines) && (not $l =~ /\`\`\`\Z/)) { + $l = shift @doxygenlines; + $remarks .= "$l\n"; + } + } else { + $l =~ s/\A\s*//; + $l =~ s/\s*\Z//; + $remarks .= "$l\n"; + } + } + + #print("REMARKS:\n\n $remarks\n\n"); + + $remarks = wordwrap(wikify($wikitype, $remarks)); + $remarks =~ s/\A\s*//; + $remarks =~ s/\s*\Z//; + + my $decl = $headerdecls{$fn}; + #$decl =~ s/\*\s+SDLCALL/ *SDLCALL/; # Try to make "void * Function" become "void *Function" + #$decl =~ s/\A\s*extern\s+(SDL_DEPRECATED\s+|)DECLSPEC\s+(.*?)\s+(\*?)SDLCALL/$2$3/; + + my $syntax = ''; + if ($wikitype eq 'mediawiki') { + $syntax = "\n$decl\n"; + } elsif ($wikitype eq 'md') { + $syntax = "```c\n$decl\n```\n"; + } else { die("Expected wikitype '$wikitype'\n"); } + + my %sections = (); + $sections{'[Brief]'} = $brief; # include this section even if blank so we get a title line. + $sections{'Remarks'} = "$remarks\n" if $remarks ne ''; + $sections{'Syntax'} = $syntax; + + my @params = (); # have to parse these and build up the wiki tables after, since Markdown needs to know the length of the largest string. :/ + + while (@doxygenlines) { + my $l = shift @doxygenlines; + if ($l =~ /\A\\param\s+(.*?)\s+(.*)\Z/) { + my $arg = $1; + my $desc = $2; + while (@doxygenlines) { + my $subline = $doxygenlines[0]; + $subline =~ s/\A\s*//; + last if $subline =~ /\A\\/; # some sort of doxygen command, assume we're past this thing. + shift @doxygenlines; # dump this line from the array; we're using it. + if ($subline eq '') { # empty line, make sure it keeps the newline char. + $desc .= "\n"; + } else { + $desc .= " $subline"; + } + } + + $desc =~ s/[\s\n]+\Z//ms; + + # We need to know the length of the longest string to make Markdown tables, so we just store these off until everything is parsed. + push @params, $arg; + push @params, $desc; + } elsif ($l =~ /\A\\r(eturns?)\s+(.*)\Z/) { + my $retstr = "R$1"; # "Return" or "Returns" + my $desc = $2; + while (@doxygenlines) { + my $subline = $doxygenlines[0]; + $subline =~ s/\A\s*//; + last if $subline =~ /\A\\/; # some sort of doxygen command, assume we're past this thing. + shift @doxygenlines; # dump this line from the array; we're using it. + if ($subline eq '') { # empty line, make sure it keeps the newline char. + $desc .= "\n"; + } else { + $desc .= " $subline"; + } + } + $desc =~ s/[\s\n]+\Z//ms; + $sections{'Return Value'} = wordwrap("$retstr " . wikify($wikitype, $desc)) . "\n"; + } elsif ($l =~ /\A\\deprecated\s+(.*)\Z/) { + my $desc = $1; + while (@doxygenlines) { + my $subline = $doxygenlines[0]; + $subline =~ s/\A\s*//; + last if $subline =~ /\A\\/; # some sort of doxygen command, assume we're past this thing. + shift @doxygenlines; # dump this line from the array; we're using it. + if ($subline eq '') { # empty line, make sure it keeps the newline char. + $desc .= "\n"; + } else { + $desc .= " $subline"; + } + } + $desc =~ s/[\s\n]+\Z//ms; + $sections{'Deprecated'} = wordwrap(wikify($wikitype, $desc)) . "\n"; + } elsif ($l =~ /\A\\since\s+(.*)\Z/) { + my $desc = $1; + while (@doxygenlines) { + my $subline = $doxygenlines[0]; + $subline =~ s/\A\s*//; + last if $subline =~ /\A\\/; # some sort of doxygen command, assume we're past this thing. + shift @doxygenlines; # dump this line from the array; we're using it. + if ($subline eq '') { # empty line, make sure it keeps the newline char. + $desc .= "\n"; + } else { + $desc .= " $subline"; + } + } + $desc =~ s/[\s\n]+\Z//ms; + $sections{'Version'} = wordwrap(wikify($wikitype, $desc)) . "\n"; + } elsif ($l =~ /\A\\threadsafety\s+(.*)\Z/) { + my $desc = $1; + while (@doxygenlines) { + my $subline = $doxygenlines[0]; + $subline =~ s/\A\s*//; + last if $subline =~ /\A\\/; # some sort of doxygen command, assume we're past this thing. + shift @doxygenlines; # dump this line from the array; we're using it. + if ($subline eq '') { # empty line, make sure it keeps the newline char. + $desc .= "\n"; + } else { + $desc .= " $subline"; + } + } + $desc =~ s/[\s\n]+\Z//ms; + $sections{'Thread Safety'} = wordwrap(wikify($wikitype, $desc)) . "\n"; + } elsif ($l =~ /\A\\sa\s+(.*)\Z/) { + my $sa = $1; + $sa =~ s/\(\)\Z//; # Convert "SDL_Func()" to "SDL_Func" + $sections{'Related Functions'} = '' if not defined $sections{'Related Functions'}; + if ($wikitype eq 'mediawiki') { + $sections{'Related Functions'} .= ":[[$sa]]\n"; + } elsif ($wikitype eq 'md') { + $sections{'Related Functions'} .= "* [$sa]($sa)\n"; + } else { die("Expected wikitype '$wikitype'\n"); } + } + } + + # Make sure this ends with a double-newline. + $sections{'Related Functions'} .= "\n" if defined $sections{'Related Functions'}; + + # We can build the wiki table now that we have all the data. + if (scalar(@params) > 0) { + my $str = ''; + if ($wikitype eq 'mediawiki') { + while (scalar(@params) > 0) { + my $arg = shift @params; + my $desc = wikify($wikitype, shift @params); + $str .= ($str eq '') ? "{|\n" : "|-\n"; + $str .= "|'''$arg'''\n"; + $str .= "|$desc\n"; + } + $str .= "|}\n"; + } elsif ($wikitype eq 'md') { + my $longest_arg = 0; + my $longest_desc = 0; + my $which = 0; + foreach (@params) { + if ($which == 0) { + my $len = length($_) + 4; + $longest_arg = $len if ($len > $longest_arg); + $which = 1; + } else { + my $len = length(wikify($wikitype, $_)); + $longest_desc = $len if ($len > $longest_desc); + $which = 0; + } + } + + # Markdown tables are sort of obnoxious. + $str .= '| ' . (' ' x ($longest_arg+4)) . ' | ' . (' ' x $longest_desc) . " |\n"; + $str .= '| ' . ('-' x ($longest_arg+4)) . ' | ' . ('-' x $longest_desc) . " |\n"; + + while (@params) { + my $arg = shift @params; + my $desc = wikify($wikitype, shift @params); + $str .= "| **$arg** " . (' ' x ($longest_arg - length($arg))) . "| $desc" . (' ' x ($longest_desc - length($desc))) . " |\n"; + } + } else { + die("Unexpected wikitype!\n"); # should have checked this elsewhere. + } + $sections{'Function Parameters'} = $str; + } + + my $path = "$wikipath/$_.${wikitype}.tmp"; + open(FH, '>', $path) or die("Can't open '$path': $!\n"); + + my $sectionsref = $wikifuncs{$fn}; + + foreach (@standard_wiki_sections) { + # drop sections we either replaced or removed from the original wiki's contents. + if (not defined $only_wiki_sections{$_}) { + delete($$sectionsref{$_}); + } + } + + my $wikisectionorderref = $wikisectionorder{$fn}; + + # Make sure there's a footer in the wiki that puts this function in CategoryAPI... + if (not $$sectionsref{'[footer]'}) { + $$sectionsref{'[footer]'} = ''; + push @$wikisectionorderref, '[footer]'; + } + + # If changing format, convert things that otherwise are passed through unmolested. + if (defined $changeformat) { + if (($dewikify_mode eq 'md') and ($origwikitype eq 'mediawiki')) { + $$sectionsref{'[footer]'} =~ s/\[\[(Category[a-zA-Z0-9_]+)\]\]/[$1]($1)/g; + } elsif (($dewikify_mode eq 'mediawiki') and ($origwikitype eq 'md')) { + $$sectionsref{'[footer]'} =~ s/\[(Category[a-zA-Z0-9_]+)\]\(.*?\)/[[$1]]/g; + } + + foreach (keys %only_wiki_sections) { + my $sect = $_; + if (defined $$sectionsref{$sect}) { + $$sectionsref{$sect} = wikify($wikitype, dewikify($origwikitype, $$sectionsref{$sect})); + } + } + } + + # !!! FIXME: This won't be CategoryAPI if we eventually handle things other than functions. + my $footer = $$sectionsref{'[footer]'}; + + if ($wikitype eq 'mediawiki') { + $footer =~ s/\[\[CategoryAPI\]\],?\s*//g; + $footer = '[[CategoryAPI]]' . (($footer eq '') ? "\n" : ", $footer"); + } elsif ($wikitype eq 'md') { + $footer =~ s/\[CategoryAPI\]\(CategoryAPI\),?\s*//g; + $footer = '[CategoryAPI](CategoryAPI)' . (($footer eq '') ? '' : ', ') . $footer; + } else { die("Unexpected wikitype '$wikitype'\n"); } + $$sectionsref{'[footer]'} = $footer; + + if (defined $wikipreamble) { + my $wikified_preamble = wikify($wikitype, $wikipreamble); + if ($wikitype eq 'mediawiki') { + print FH "====== $wikified_preamble ======\n"; + } elsif ($wikitype eq 'md') { + print FH "###### $wikified_preamble\n"; + } else { die("Unexpected wikitype '$wikitype'\n"); } + } + + my $prevsectstr = ''; + my @ordered_sections = (@standard_wiki_sections, defined $wikisectionorderref ? @$wikisectionorderref : ()); # this copies the arrays into one. + foreach (@ordered_sections) { + my $sect = $_; + next if $sect eq '[start]'; + next if (not defined $sections{$sect} and not defined $$sectionsref{$sect}); + my $section = defined $sections{$sect} ? $sections{$sect} : $$sectionsref{$sect}; + if ($sect eq '[footer]') { + # Make sure previous section ends with two newlines. + if (substr($prevsectstr, -1) ne "\n") { + print FH "\n\n"; + } elsif (substr($prevsectstr, -2) ne "\n\n") { + print FH "\n"; + } + print FH "----\n"; # It's the same in Markdown and MediaWiki. + } elsif ($sect eq '[Brief]') { + if ($wikitype eq 'mediawiki') { + print FH "= $fn =\n\n"; + } elsif ($wikitype eq 'md') { + print FH "# $fn\n\n"; + } else { die("Unexpected wikitype '$wikitype'\n"); } + } else { + if ($wikitype eq 'mediawiki') { + print FH "\n== $sect ==\n\n"; + } elsif ($wikitype eq 'md') { + print FH "\n## $sect\n\n"; + } else { die("Unexpected wikitype '$wikitype'\n"); } + } + + my $sectstr = defined $sections{$sect} ? $sections{$sect} : $$sectionsref{$sect}; + print FH $sectstr; + + $prevsectstr = $sectstr; + + # make sure these don't show up twice. + delete($sections{$sect}); + delete($$sectionsref{$sect}); + } + + print FH "\n\n"; + close(FH); + + if (defined $changeformat and ($origwikitype ne $wikitype)) { + system("cd '$wikipath' ; git mv '$_.${origwikitype}' '$_.${wikitype}'"); + unlink("$wikipath/$_.${origwikitype}"); + } + + rename($path, "$wikipath/$_.${wikitype}") or die("Can't rename '$path' to '$wikipath/$_.${wikitype}': $!\n"); + } + + if (defined $readmepath) { + if ( -d $readmepath ) { + mkdir($wikireadmepath); # just in case + opendir(DH, $readmepath) or die("Can't opendir '$readmepath': $!\n"); + while (my $d = readdir(DH)) { + my $dent = $d; + if ($dent =~ /\AREADME\-(.*?\.md)\Z/) { # we only bridge Markdown files here. + my $wikifname = $1; + next if $wikifname eq 'FrontPage.md'; + filecopy("$readmepath/$dent", "$wikireadmepath/$wikifname", "\n"); + } + } + closedir(DH); + + my @pages = (); + opendir(DH, $wikireadmepath) or die("Can't opendir '$wikireadmepath': $!\n"); + while (my $d = readdir(DH)) { + my $dent = $d; + if ($dent =~ /\A(.*?)\.(mediawiki|md)\Z/) { + my $wikiname = $1; + next if $wikiname eq 'FrontPage'; + push @pages, $wikiname; + } + } + closedir(DH); + + open(FH, '>', "$wikireadmepath/FrontPage.md") or die("Can't open '$wikireadmepath/FrontPage.md': $!\n"); + print FH "# All READMEs available here\n\n"; + foreach (sort @pages) { + my $wikiname = $_; + print FH "- [$wikiname]($wikiname)\n"; + } + close(FH); + } + } + +} elsif ($copy_direction == -2) { # --copy-to-manpages + # This only takes from the wiki data, since it has sections we omit from the headers, like code examples. + + my $manpath = "$srcpath/man"; + mkdir($manpath); + $manpath .= "/man3"; + mkdir($manpath); + + $dewikify_mode = 'manpage'; + $wordwrap_mode = 'manpage'; + + my $introtxt = ''; + if (0) { + open(FH, '<', "$srcpath/LICENSE.txt") or die("Can't open '$srcpath/LICENSE.txt': $!\n"); + while () { + chomp; + $introtxt .= ".\\\" $_\n"; + } + close(FH); + } + + my $gitrev = `cd "$srcpath" ; git rev-list HEAD~..`; + chomp($gitrev); + + # !!! FIXME + open(FH, '<', "$srcpath/$versionfname") or die("Can't open '$srcpath/$versionfname': $!\n"); + my $majorver = 0; + my $minorver = 0; + my $patchver = 0; + while () { + chomp; + if (/$versionmajorregex/) { + $majorver = int($1); + } elsif (/$versionminorregex/) { + $minorver = int($1); + } elsif (/$versionpatchregex/) { + $patchver = int($1); + } + } + close(FH); + my $fullversion = "$majorver.$minorver.$patchver"; + + foreach (keys %headerfuncs) { + my $fn = $_; + next if not defined $wikifuncs{$fn}; # don't have a page for that function, skip it. + my $wikitype = $wikitypes{$fn}; + my $sectionsref = $wikifuncs{$fn}; + my $remarks = $sectionsref->{'Remarks'}; + my $params = $sectionsref->{'Function Parameters'}; + my $returns = $sectionsref->{'Return Value'}; + my $version = $sectionsref->{'Version'}; + my $threadsafety = $sectionsref->{'Thread Safety'}; + my $related = $sectionsref->{'Related Functions'}; + my $examples = $sectionsref->{'Code Examples'}; + my $deprecated = $sectionsref->{'Deprecated'}; + my $brief = $sectionsref->{'[Brief]'}; + my $decl = $headerdecls{$fn}; + my $str = ''; + + $brief = "$brief"; + $brief =~ s/\A[\s\n]*\= .*? \=\s*?\n+//ms; + $brief =~ s/\A[\s\n]*\=\= .*? \=\=\s*?\n+//ms; + $brief =~ s/\A(.*?\.) /$1\n/; # \brief should only be one sentence, delimited by a period+space. Split if necessary. + my @briefsplit = split /\n/, $brief; + $brief = shift @briefsplit; + $brief = dewikify($wikitype, $brief); + + if (defined $remarks) { + $remarks = dewikify($wikitype, join("\n", @briefsplit) . $remarks); + } + + $str .= $introtxt; + + $str .= ".\\\" This manpage content is licensed under Creative Commons\n"; + $str .= ".\\\" Attribution 4.0 International (CC BY 4.0)\n"; + $str .= ".\\\" https://creativecommons.org/licenses/by/4.0/\n"; + $str .= ".\\\" This manpage was generated from ${projectshortname}'s wiki page for $fn:\n"; + $str .= ".\\\" $wikiurl/$fn\n"; + $str .= ".\\\" Generated with SDL/build-scripts/wikiheaders.pl\n"; + $str .= ".\\\" revision $gitrev\n" if $gitrev ne ''; + $str .= ".\\\" Please report issues in this manpage's content at:\n"; + $str .= ".\\\" $bugreporturl\n"; + $str .= ".\\\" Please report issues in the generation of this manpage from the wiki at:\n"; + $str .= ".\\\" https://github.com/libsdl-org/SDL/issues/new?title=Misgenerated%20manpage%20for%20$fn\n"; + $str .= ".\\\" $projectshortname can be found at $projecturl\n"; + + # Define a .URL macro. The "www.tmac" thing decides if we're using GNU roff (which has a .URL macro already), and if so, overrides the macro we just created. + # This wizadry is from https://web.archive.org/web/20060102165607/http://people.debian.org/~branden/talks/wtfm/wtfm.pdf + $str .= ".de URL\n"; + $str .= '\\$2 \(laURL: \\$1 \(ra\\$3' . "\n"; + $str .= "..\n"; + $str .= '.if \n[.g] .mso www.tmac' . "\n"; + + $str .= ".TH $fn 3 \"$projectshortname $fullversion\" \"$projectfullname\" \"$projectshortname$majorver FUNCTIONS\"\n"; + $str .= ".SH NAME\n"; + + $str .= "$fn"; + $str .= " \\- $brief" if (defined $brief); + $str .= "\n"; + + $str .= ".SH SYNOPSIS\n"; + $str .= ".nf\n"; + $str .= ".B #include \\(dq$mainincludefname\\(dq\n"; + $str .= ".PP\n"; + + my @decllines = split /\n/, $decl; + foreach (@decllines) { + $str .= ".BI \"$_\n"; + } + $str .= ".fi\n"; + + if (defined $remarks) { + $str .= ".SH DESCRIPTION\n"; + $str .= $remarks . "\n"; + } + + if (defined $deprecated) { + $str .= ".SH DEPRECATED\n"; + $str .= dewikify($wikitype, $deprecated) . "\n"; + } + + if (defined $params) { + $str .= ".SH FUNCTION PARAMETERS\n"; + my @lines = split /\n/, $params; + if ($wikitype eq 'mediawiki') { + die("Unexpected data parsing MediaWiki table") if (shift @lines ne '{|'); # Dump the '{|' start + while (scalar(@lines) >= 3) { + my $name = shift @lines; + my $desc = shift @lines; + my $terminator = shift @lines; # the '|-' or '|}' line. + last if ($terminator ne '|-') and ($terminator ne '|}'); # we seem to have run out of table. + $name =~ s/\A\|\s*//; + $name =~ s/\A\*\*(.*?)\*\*/$1/; + $name =~ s/\A\'\'\'(.*?)\'\'\'/$1/; + $desc =~ s/\A\|\s*//; + $desc = dewikify($wikitype, $desc); + #print STDERR "FN: $fn NAME: $name DESC: $desc TERM: $terminator\n"; + + $str .= ".TP\n"; + $str .= ".I $name\n"; + $str .= "$desc\n"; + } + } elsif ($wikitype eq 'md') { + my $l; + $l = shift @lines; + die("Unexpected data parsing Markdown table") if (not $l =~ /\A\s*\|\s*\|\s*\|\s*\Z/); + $l = shift @lines; + die("Unexpected data parsing Markdown table") if (not $l =~ /\A\s*\|\s*\-*\s*\|\s*\-*\s*\|\s*\Z/); + while (scalar(@lines) >= 1) { + $l = shift @lines; + if ($l =~ /\A\s*\|\s*(.*?)\s*\|\s*(.*?)\s*\|\s*\Z/) { + my $name = $1; + my $desc = $2; + $name =~ s/\A\*\*(.*?)\*\*/$1/; + $name =~ s/\A\'\'\'(.*?)\'\'\'/$1/; + $desc = dewikify($wikitype, $desc); + + $str .= ".TP\n"; + $str .= ".I $name\n"; + $str .= "$desc\n"; + } else { + last; # we seem to have run out of table. + } + } + } else { + die("write me"); + } + } + + if (defined $returns) { + $str .= ".SH RETURN VALUE\n"; + $str .= dewikify($wikitype, $returns) . "\n"; + } + + if (defined $examples) { + $str .= ".SH CODE EXAMPLES\n"; + $dewikify_manpage_code_indent = 0; + $str .= dewikify($wikitype, $examples) . "\n"; + $dewikify_manpage_code_indent = 1; + } + + if (defined $threadsafety) { + $str .= ".SH THREAD SAFETY\n"; + $str .= dewikify($wikitype, $threadsafety) . "\n"; + } + + if (defined $version) { + $str .= ".SH AVAILABILITY\n"; + $str .= dewikify($wikitype, $version) . "\n"; + } + + if (defined $related) { + $str .= ".SH SEE ALSO\n"; + # !!! FIXME: lots of code duplication in all of these. + my $v = dewikify($wikitype, $related); + my @desclines = split /\n/, $v; + my $nextstr = ''; + foreach (@desclines) { + s/\A(\:|\* )//; + s/\(\)\Z//; # Convert "SDL_Func()" to "SDL_Func" + s/\[\[(.*?)\]\]/$1/; # in case some wikilinks remain. + s/\[(.*?)\]\(.*?\)/$1/; # in case some wikilinks remain. + s/\A\*\s*\Z//; + s/\A\/*//; + s/\A\.BR\s+//; # dewikify added this, but we want to handle it. + s/\A\.I\s+//; # dewikify added this, but we want to handle it. + s/\A\s+//; + s/\s+\Z//; + next if $_ eq ''; + $str .= "$nextstr.BR $_ (3)"; + $nextstr = ",\n"; + } + $str .= "\n"; + } + + if (0) { + $str .= ".SH COPYRIGHT\n"; + $str .= "This manpage is licensed under\n"; + $str .= ".UR https://creativecommons.org/licenses/by/4.0/\n"; + $str .= "Creative Commons Attribution 4.0 International (CC BY 4.0)\n"; + $str .= ".UE\n"; + $str .= ".PP\n"; + $str .= "This manpage was generated from\n"; + $str .= ".UR $wikiurl/$fn\n"; + $str .= "${projectshortname}'s wiki\n"; + $str .= ".UE\n"; + $str .= "using SDL/build-scripts/wikiheaders.pl"; + $str .= " revision $gitrev" if $gitrev ne ''; + $str .= ".\n"; + $str .= "Please report issues in this manpage at\n"; + $str .= ".UR $bugreporturl\n"; + $str .= "our bugtracker!\n"; + $str .= ".UE\n"; + } + + my $path = "$manpath/$_.3.tmp"; + open(FH, '>', $path) or die("Can't open '$path': $!\n"); + print FH $str; + close(FH); + rename($path, "$manpath/$_.3") or die("Can't rename '$path' to '$manpath/$_.3': $!\n"); + } +} + +# end of wikiheaders.pl ... + diff --git a/SDL2-2.30.5/build-scripts/windows-buildbot-zipper.bat b/SDL2-2.30.5/build-scripts/windows-buildbot-zipper.bat new file mode 100644 index 0000000..5bbc465 --- /dev/null +++ b/SDL2-2.30.5/build-scripts/windows-buildbot-zipper.bat @@ -0,0 +1,28 @@ +@echo off +rem just a helper batch file for collecting up files and zipping them. +rem usage: windows-buildbot-zipper.bat +rem must be run from root of SDL source tree. + +IF EXIST %2\%1\Release GOTO okaydir +echo Please run from root of source tree after doing a Release build. +GOTO done + +:okaydir +erase /q /f /s zipper +IF EXIST zipper GOTO zippermade +mkdir zipper +:zippermade +mkdir zipper\SDL +mkdir zipper\SDL\include +mkdir zipper\SDL\lib +copy include\*.h include\ +copy %2\%1\Release\SDL2.dll zipper\SDL\lib\ +copy %2\%1\Release\SDL2.lib zipper\SDL\lib\ +copy %2\%1\Release\SDL2main.lib zipper\SDL\lib\ +cd zipper +zip -9r ..\%3 SDL +cd .. +erase /q /f /s zipper + +:done + diff --git a/SDL2-2.30.5/cmake/test/CMakeLists.txt b/SDL2-2.30.5/cmake/test/CMakeLists.txt new file mode 100644 index 0000000..388e86c --- /dev/null +++ b/SDL2-2.30.5/cmake/test/CMakeLists.txt @@ -0,0 +1,124 @@ +# This cmake build script is meant for verifying the various CMake configuration script. + +cmake_minimum_required(VERSION 3.12) +project(sdl_test LANGUAGES C) + +include(GenerateExportHeader) + +if(ANDROID) + macro(add_executable NAME) + set(args ${ARGN}) + list(REMOVE_ITEM args WIN32) + add_library(${NAME} SHARED ${args}) + unset(args) + endmacro() +endif() + +cmake_policy(SET CMP0074 NEW) + +# Override CMAKE_FIND_ROOT_PATH_MODE to allow search for SDL2 outside of sysroot +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE NEVER) + +include(FeatureSummary) + +option(TEST_SHARED "Test linking to shared SDL2 library" ON) +add_feature_info("TEST_SHARED" TEST_SHARED "Test linking with shared library") + +option(TEST_STATIC "Test linking to static SDL2 library" ON) +add_feature_info("TEST_STATIC" TEST_STATIC "Test linking with static library") + +if(TEST_SHARED) + find_package(SDL2 REQUIRED CONFIG COMPONENTS SDL2) + if(EMSCRIPTEN OR (WIN32 AND NOT WINDOWS_STORE)) + find_package(SDL2 REQUIRED CONFIG COMPONENTS SDL2main) + endif() + add_executable(gui-shared WIN32 main_gui.c) + if(TARGET SDL2::SDL2main) + target_link_libraries(gui-shared PRIVATE SDL2::SDL2main) + endif() + target_link_libraries(gui-shared PRIVATE SDL2::SDL2) + if(WIN32) + add_custom_command(TARGET gui-shared POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different "$" "$" + ) + endif() + + add_library(sharedlib-shared SHARED main_lib.c) + target_link_libraries(sharedlib-shared PRIVATE SDL2::SDL2) + generate_export_header(sharedlib-shared EXPORT_MACRO_NAME MYLIBRARY_EXPORT) + target_compile_definitions(sharedlib-shared PRIVATE "EXPORT_HEADER=\"${CMAKE_CURRENT_BINARY_DIR}/sharedlib-shared_export.h\"") + set_target_properties(sharedlib-shared PROPERTIES C_VISIBILITY_PRESET "hidden") + + add_executable(gui-shared-vars WIN32 main_gui.c) + target_link_libraries(gui-shared-vars PRIVATE ${SDL2_LIBRARIES}) + target_include_directories(gui-shared-vars PRIVATE ${SDL2_INCLUDE_DIRS}) + + add_executable(cli-shared main_cli.c) + target_link_libraries(cli-shared PRIVATE SDL2::SDL2) + if(WIN32) + add_custom_command(TARGET cli-shared POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different "$" "$" + ) + endif() + + # SDL2_LIBRARIES does not support creating a cli SDL2 application + # (it is possible that SDL2main is a stub, but we don't know for sure) + if(NOT TARGET SDL2::SDL2main) + add_executable(cli-shared-vars main_cli.c) + target_link_libraries(cli-shared-vars PRIVATE ${SDL2_LIBRARIES}) + target_include_directories(cli-shared-vars PRIVATE ${SDL2_INCLUDE_DIRS}) + endif() + + add_library(sharedlib-shared-vars SHARED main_lib.c) + target_link_libraries(sharedlib-shared-vars PRIVATE ${SDL2_LIBRARIES}) + target_include_directories(sharedlib-shared-vars PRIVATE ${SDL2_INCLUDE_DIRS}) + generate_export_header(sharedlib-shared-vars EXPORT_MACRO_NAME MYLIBRARY_EXPORT) + target_compile_definitions(sharedlib-shared-vars PRIVATE "EXPORT_HEADER=\"${CMAKE_CURRENT_BINARY_DIR}/sharedlib-shared-vars_export.h\"") + set_target_properties(sharedlib-shared-vars PROPERTIES C_VISIBILITY_PRESET "hidden") +endif() + +if(TEST_STATIC) + find_package(SDL2 REQUIRED CONFIG COMPONENTS SDL2-static) + if(EMSCRIPTEN OR (WIN32 AND NOT WINDOWS_STORE)) + find_package(SDL2 REQUIRED CONFIG COMPONENTS SDL2main) + endif() + add_executable(gui-static WIN32 main_gui.c) + if(TARGET SDL2::SDL2main) + target_link_libraries(gui-static PRIVATE SDL2::SDL2main) + endif() + target_link_libraries(gui-static PRIVATE SDL2::SDL2-static) + + option(SDL_STATIC_PIC "SDL static library has been built with PIC") + if(SDL_STATIC_PIC OR WIN32) + add_library(sharedlib-static SHARED main_lib.c) + target_link_libraries(sharedlib-static PRIVATE SDL2::SDL2-static) + generate_export_header(sharedlib-static EXPORT_MACRO_NAME MYLIBRARY_EXPORT) + target_compile_definitions(sharedlib-static PRIVATE "EXPORT_HEADER=\"${CMAKE_CURRENT_BINARY_DIR}/sharedlib-static_export.h\"") + set_target_properties(sharedlib-static PROPERTIES C_VISIBILITY_PRESET "hidden") + endif() + + add_executable(gui-static-vars WIN32 main_gui.c) + target_link_libraries(gui-static-vars PRIVATE ${SDL2MAIN_LIBRARY} ${SDL2_STATIC_LIBRARIES}) + target_include_directories(gui-static-vars PRIVATE ${SDL2_INCLUDE_DIRS}) + + add_executable(cli-static main_cli.c) + target_link_libraries(cli-static PRIVATE SDL2::SDL2-static) + + # SDL2_LIBRARIES does not support creating a cli SDL2 application (when SDL2::SDL2main is available) + # (it is possible that SDL2main is a stub, but we don't know for sure) + if(NOT TARGET SDL2::SDL2main) + add_executable(cli-static-vars main_cli.c) + target_link_libraries(cli-static-vars PRIVATE ${SDL2_STATIC_LIBRARIES}) + target_include_directories(cli-static-vars PRIVATE ${SDL2_INCLUDE_DIRS}) + endif() +endif() + +message(STATUS "SDL2_PREFIX: ${SDL2_PREFIX}") +message(STATUS "SDL2_INCLUDE_DIR: ${SDL2_INCLUDE_DIR}") +message(STATUS "SDL2_INCLUDE_DIRS: ${SDL2_INCLUDE_DIRS}") +message(STATUS "SDL2_LIBRARIES: ${SDL2_LIBRARIES}") +message(STATUS "SDL2_STATIC_LIBRARIES: ${SDL2_STATIC_LIBRARIES}") +message(STATUS "SDL2MAIN_LIBRARY: ${SDL2MAIN_LIBRARY}") +message(STATUS "SDL2TEST_LIBRARY: ${SDL2TEST_LIBRARY}") + +feature_summary(WHAT ALL) diff --git a/SDL2-2.30.5/cmake/test/jni/Android.mk b/SDL2-2.30.5/cmake/test/jni/Android.mk new file mode 100644 index 0000000..c4956d6 --- /dev/null +++ b/SDL2-2.30.5/cmake/test/jni/Android.mk @@ -0,0 +1,11 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := main_gui_androidmk +LOCAL_SRC_FILES := ../main_gui.c +LOCAL_SHARED_LIBRARIES += SDL2 +include $(BUILD_SHARED_LIBRARY) + +$(call import-module,SDL2main) +$(call import-module,SDL2) diff --git a/SDL2-2.30.5/cmake/test/main_cli.c b/SDL2-2.30.5/cmake/test/main_cli.c new file mode 100644 index 0000000..f6b0836 --- /dev/null +++ b/SDL2-2.30.5/cmake/test/main_cli.c @@ -0,0 +1,14 @@ +#define SDL_MAIN_HANDLED +#include "SDL.h" +#include + +int main(int argc, char *argv[]) { + SDL_SetMainReady(); + if (SDL_Init(0) < 0) { + fprintf(stderr, "could not initialize sdl2: %s\n", SDL_GetError()); + return 1; + } + SDL_Delay(100); + SDL_Quit(); + return 0; +} diff --git a/SDL2-2.30.5/cmake/test/main_gui.c b/SDL2-2.30.5/cmake/test/main_gui.c new file mode 100644 index 0000000..ca2d92e --- /dev/null +++ b/SDL2-2.30.5/cmake/test/main_gui.c @@ -0,0 +1,28 @@ +#include "SDL.h" +#include + +int main(int argc, char *argv[]) { + SDL_Window *window = NULL; + SDL_Surface *screenSurface = NULL; + if (SDL_Init(SDL_INIT_VIDEO) < 0) { + fprintf(stderr, "could not initialize sdl2: %s\n", SDL_GetError()); + return 1; + } + window = SDL_CreateWindow( + "hello_sdl2", + SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, + 640, 480, + SDL_WINDOW_SHOWN + ); + if (!window) { + fprintf(stderr, "could not create window: %s\n", SDL_GetError()); + return 1; + } + screenSurface = SDL_GetWindowSurface(window); + SDL_FillRect(screenSurface, NULL, SDL_MapRGB(screenSurface->format, 0xff, 0xff, 0xff)); + SDL_UpdateWindowSurface(window); + SDL_Delay(100); + SDL_DestroyWindow(window); + SDL_Quit(); + return 0; +} diff --git a/SDL2-2.30.5/cmake/test/main_lib.c b/SDL2-2.30.5/cmake/test/main_lib.c new file mode 100644 index 0000000..9801ed5 --- /dev/null +++ b/SDL2-2.30.5/cmake/test/main_lib.c @@ -0,0 +1,33 @@ +#include "SDL.h" +#include + +#include EXPORT_HEADER + +#if defined(_WIN32) +#include +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { + return TRUE; +} +#endif + +int MYLIBRARY_EXPORT mylibrary_init(void); +void MYLIBRARY_EXPORT mylibrary_quit(void); +int MYLIBRARY_EXPORT mylibrary_work(void); + +int mylibrary_init(void) { + SDL_SetMainReady(); + if (SDL_Init(0) < 0) { + fprintf(stderr, "could not initialize sdl2: %s\n", SDL_GetError()); + return 1; + } + return 0; +} + +void mylibrary_quit(void) { + SDL_Quit(); +} + +int mylibrary_work(void) { + SDL_Delay(100); + return 0; +} diff --git a/SDL2-2.30.5/cmake/test/test_pkgconfig.sh b/SDL2-2.30.5/cmake/test/test_pkgconfig.sh new file mode 100644 index 0000000..500cd09 --- /dev/null +++ b/SDL2-2.30.5/cmake/test/test_pkgconfig.sh @@ -0,0 +1,51 @@ +#!/bin/sh + +if test "x$CC" = "x"; then + CC=cc +fi + +machine="$($CC -dumpmachine)" +case "$machine" in + *mingw* ) + EXEPREFIX="" + EXESUFFIX=".exe" + ;; + *android* ) + EXEPREFIX="lib" + EXESUFFIX=".so" + LDFLAGS="$LDFLAGS -shared" + ;; + * ) + EXEPREFIX="" + EXESUFFIX="" + ;; +esac + +set -e + +# Get the canonical path of the folder containing this script +testdir=$(cd -P -- "$(dirname -- "$0")" && printf '%s\n' "$(pwd -P)") +SDL_CFLAGS="$( pkg-config sdl2 --cflags )" +SDL_LDFLAGS="$( pkg-config sdl2 --libs )" +SDL_STATIC_LDFLAGS="$( pkg-config sdl2 --libs --static )" + +compile_cmd="$CC -c "$testdir/main_gui.c" -o main_gui_pkgconfig.c.o $SDL_CFLAGS $CFLAGS" +link_cmd="$CC main_gui_pkgconfig.c.o -o ${EXEPREFIX}main_gui_pkgconfig${EXESUFFIX} $SDL_LDFLAGS $LDFLAGS" +static_link_cmd="$CC main_gui_pkgconfig.c.o -o ${EXEPREFIX}main_gui_pkgconfig_static${EXESUFFIX} $SDL_STATIC_LDFLAGS $LDFLAGS" + +echo "-- CC: $CC" +echo "-- CFLAGS: $CFLAGS" +echo "-- LDFLASG: $LDFLAGS" +echo "-- SDL_CFLAGS: $SDL_CFLAGS" +echo "-- SDL_LDFLAGS: $SDL_LDFLAGS" +echo "-- SDL_STATIC_LDFLAGS: $SDL_STATIC_LDFLAGS" + +echo "-- COMPILE: $compile_cmd" +echo "-- LINK: $link_cmd" +echo "-- STATIC_LINK: $static_link_cmd" + +set -x + +$compile_cmd +$link_cmd +$static_link_cmd diff --git a/SDL2-2.30.5/cmake/test/test_sdlconfig.sh b/SDL2-2.30.5/cmake/test/test_sdlconfig.sh new file mode 100644 index 0000000..fa41dbb --- /dev/null +++ b/SDL2-2.30.5/cmake/test/test_sdlconfig.sh @@ -0,0 +1,51 @@ +#!/bin/sh + +if test "x$CC" = "x"; then + CC=cc +fi + +machine="$($CC -dumpmachine)" +case "$machine" in + *mingw* ) + EXEPREFIX="" + EXESUFFIX=".exe" + ;; + *android* ) + EXEPREFIX="lib" + EXESUFFIX=".so" + LDFLAGS="$LDFLAGS -shared" + ;; + * ) + EXEPREFIX="" + EXESUFFIX="" + ;; +esac + +set -e + +# Get the canonical path of the folder containing this script +testdir=$(cd -P -- "$(dirname -- "$0")" && printf '%s\n' "$(pwd -P)") +SDL_CFLAGS="$( sdl2-config --cflags )" +SDL_LDFLAGS="$( sdl2-config --libs )" +SDL_STATIC_LDFLAGS="$( sdl2-config --static-libs )" + +compile_cmd="$CC -c "$testdir/main_gui.c" -o main_gui_sdlconfig.c.o $CFLAGS $SDL_CFLAGS" +link_cmd="$CC main_gui_sdlconfig.c.o -o ${EXEPREFIX}main_gui_sdlconfig${EXESUFFIX} $SDL_LDFLAGS $LDFLAGS" +static_link_cmd="$CC main_gui_sdlconfig.c.o -o ${EXEPREFIX}main_gui_sdlconfig_static${EXESUFFIX} $SDL_STATIC_LDFLAGS $LDFLAGS" + +echo "-- CC: $CC" +echo "-- CFLAGS: $CFLAGS" +echo "-- LDFLAGS: $LDFLAGS" +echo "-- SDL_CFLAGS: $SDL_CFLAGS" +echo "-- SDL_LDFLAGS: $SDL_LDFLAGS" +echo "-- SDL_STATIC_LDFLAGS: $SDL_STATIC_LDFLAGS" + +echo "-- COMPILE: $compile_cmd" +echo "-- LINK: $link_cmd" +echo "-- STATIC_LINK: $static_link_cmd" + +set -x + +$compile_cmd +$link_cmd +$static_link_cmd diff --git a/SDL2-2.0.12/cmake_uninstall.cmake.in b/SDL2-2.30.5/cmake_uninstall.cmake.in similarity index 100% rename from SDL2-2.0.12/cmake_uninstall.cmake.in rename to SDL2-2.30.5/cmake_uninstall.cmake.in diff --git a/SDL2-2.0.12/configure b/SDL2-2.30.5/configure similarity index 56% rename from SDL2-2.0.12/configure rename to SDL2-2.30.5/configure index 9c46ffe..c12fef7 100644 --- a/SDL2-2.0.12/configure +++ b/SDL2-2.30.5/configure @@ -1,9 +1,10 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69. +# Generated by GNU Autoconf 2.71. # # -# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation, +# Inc. # # # This configure script is free software; the Free Software Foundation @@ -14,14 +15,16 @@ # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : +as_nop=: +if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 +then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST -else +else $as_nop case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( @@ -31,46 +34,46 @@ esac fi + +# Reset variables that may have inherited troublesome values from +# the environment. + +# IFS needs to be set, to space, tab, and newline, in precisely that order. +# (If _AS_PATH_WALK were called with IFS unset, it would have the +# side effect of setting IFS to empty, thus disabling word splitting.) +# Quoting is to prevent editors from complaining about space-tab. as_nl=' ' export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi +IFS=" "" $as_nl" + +PS1='$ ' +PS2='> ' +PS4='+ ' + +# Ensure predictable behavior from utilities with locale-dependent output. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# We cannot yet rely on "unset" to work, but we need these variables +# to be unset--not just set to an empty or harmless value--now, to +# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct +# also avoids known problems related to "unset" and subshell syntax +# in other old shells (e.g. bash 2.01 and pdksh 5.2.14). +for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH +do eval test \${$as_var+y} \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done + +# Ensure that fds 0, 1, and 2 are open. +if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi +if (exec 3>&2) ; then :; else exec 2>/dev/null; fi # The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then +if ${PATH_SEPARATOR+false} :; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || @@ -79,13 +82,6 @@ if test "${PATH_SEPARATOR+set}" != set; then fi -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( @@ -94,8 +90,12 @@ case $0 in #(( for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + test -r "$as_dir$0" && as_myself=$as_dir$0 && break done IFS=$as_save_IFS @@ -107,30 +107,10 @@ if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. @@ -152,20 +132,22 @@ esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. -$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 -as_fn_exit 255 +printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then - as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + as_bourne_compatible="as_nop=: +if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 +then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST -else +else \$as_nop case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( @@ -185,12 +167,15 @@ as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } -if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : +if ( set x; as_fn_ret_success y && test x = \"\$1\" ) +then : -else +else \$as_nop exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 +blah=\$(echo \$(echo blah)) +test x\"\$blah\" = xblah || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO @@ -205,30 +190,38 @@ test -x / || exit 1" test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" - if (eval "$as_required") 2>/dev/null; then : + if (eval "$as_required") 2>/dev/null +then : as_have_required=yes -else +else $as_nop as_have_required=no fi - if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null +then : -else +else $as_nop as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. - as_shell=$as_dir/$as_base + as_shell=$as_dir$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + as_run=a "$as_shell" -c "$as_bourne_compatible""$as_required" 2>/dev/null +then : CONFIG_SHELL=$as_shell as_have_required=yes - if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + if as_run=a "$as_shell" -c "$as_bourne_compatible""$as_suggested" 2>/dev/null +then : break 2 fi fi @@ -236,14 +229,21 @@ fi esac as_found=false done -$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : - CONFIG_SHELL=$SHELL as_have_required=yes -fi; } IFS=$as_save_IFS +if $as_found +then : + +else $as_nop + if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null +then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi +fi - if test "x$CONFIG_SHELL" != x; then : + if test "x$CONFIG_SHELL" != x +then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also @@ -261,18 +261,19 @@ esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. -$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi - if test x$as_have_required = xno; then : - $as_echo "$0: This script requires a shell more modern than all" - $as_echo "$0: the shells that I found on your system." - if test x${ZSH_VERSION+set} = xset ; then - $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" - $as_echo "$0: be upgraded to zsh 4.3.4 or later." + if test x$as_have_required = xno +then : + printf "%s\n" "$0: This script requires a shell more modern than all" + printf "%s\n" "$0: the shells that I found on your system." + if test ${ZSH_VERSION+y} ; then + printf "%s\n" "$0: In particular, zsh $ZSH_VERSION has bugs and should" + printf "%s\n" "$0: be upgraded to zsh 4.3.4 or later." else - $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, + printf "%s\n" "$0: Please tell bug-autoconf@gnu.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." @@ -299,6 +300,7 @@ as_fn_unset () } as_unset=as_fn_unset + # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. @@ -316,6 +318,14 @@ as_fn_exit () as_fn_set_status $1 exit $1 } # as_fn_exit +# as_fn_nop +# --------- +# Do nothing but, unlike ":", preserve the value of $?. +as_fn_nop () +{ + return $? +} +as_nop=as_fn_nop # as_fn_mkdir_p # ------------- @@ -330,7 +340,7 @@ as_fn_mkdir_p () as_dirs= while :; do case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" @@ -339,7 +349,7 @@ $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | +printf "%s\n" X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q @@ -378,12 +388,13 @@ as_fn_executable_p () # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null +then : eval 'as_fn_append () { eval $1+=\$2 }' -else +else $as_nop as_fn_append () { eval $1=\$$1\$2 @@ -395,18 +406,27 @@ fi # as_fn_append # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null +then : eval 'as_fn_arith () { as_val=$(( $* )) }' -else +else $as_nop as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith +# as_fn_nop +# --------- +# Do nothing but, unlike ":", preserve the value of $?. +as_fn_nop () +{ + return $? +} +as_nop=as_fn_nop # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- @@ -418,9 +438,9 @@ as_fn_error () as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi - $as_echo "$as_me: error: $2" >&2 + printf "%s\n" "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error @@ -447,7 +467,7 @@ as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | +printf "%s\n" X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q @@ -491,7 +511,7 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + { printf "%s\n" "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall @@ -505,6 +525,10 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits exit } + +# Determine whether it's possible to make 'echo' print without a newline. +# These variables are no longer used directly by Autoconf, but are AC_SUBSTed +# for compatibility with existing Makefiles. ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) @@ -518,6 +542,13 @@ case `echo -n x` in #((((( ECHO_N='-n';; esac +# For backward compatibility with old third-party macros, we provide +# the shell variables $as_echo and $as_echo_n. New code should use +# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. +as_echo='printf %s\n' +as_echo_n='printf %s' + + rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file @@ -585,51 +616,49 @@ MFLAGS= MAKEFLAGS= # Identity of this package. -PACKAGE_NAME= -PACKAGE_TARNAME= -PACKAGE_VERSION= -PACKAGE_STRING= -PACKAGE_BUGREPORT= -PACKAGE_URL= +PACKAGE_NAME='' +PACKAGE_TARNAME='' +PACKAGE_VERSION='' +PACKAGE_STRING='' +PACKAGE_BUGREPORT='' +PACKAGE_URL='' -ac_unique_file="README.txt" +ac_unique_file="src/SDL.c" # Factoring default headers for most tests. ac_includes_default="\ -#include -#ifdef HAVE_SYS_TYPES_H -# include +#include +#ifdef HAVE_STDIO_H +# include #endif -#ifdef HAVE_SYS_STAT_H -# include -#endif -#ifdef STDC_HEADERS +#ifdef HAVE_STDLIB_H # include -# include -#else -# ifdef HAVE_STDLIB_H -# include -# endif #endif #ifdef HAVE_STRING_H -# if !defined STDC_HEADERS && defined HAVE_MEMORY_H -# include -# endif # include #endif -#ifdef HAVE_STRINGS_H -# include -#endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif #ifdef HAVE_UNISTD_H # include #endif" +ac_header_c_list= ac_subst_vars='LTLIBOBJS +LIBOBJS +WAYLAND_SCANNER_CODE_MODE WAYLAND_SCANNER EXTRA_LDFLAGS BUILD_LDFLAGS @@ -647,15 +676,18 @@ ENABLE_STATIC_FALSE ENABLE_STATIC_TRUE ENABLE_SHARED_FALSE ENABLE_SHARED_TRUE +PKGCONFIG_LIBS_PRIV +PKGCONFIG_DEPENDS SDL_RLD_FLAGS SDL_STATIC_LIBS SDL_LIBS SDL_CFLAGS +bin_prefix_relpath +cmake_prefix_relpath +SDL_VENDOR_INFO INSTALL_SDL2_CONFIG LIBUSB_LIBS LIBUSB_CFLAGS -FCITX_LIBS -FCITX_CFLAGS IBUS_LIBS IBUS_CFLAGS DBUS_LIBS @@ -673,25 +705,32 @@ X_CFLAGS XMKMF RPI_LIBS RPI_CFLAGS +DECOR_LIBS +DECOR_CFLAGS FUSIONSOUND_LIBS FUSIONSOUND_CFLAGS +SNDIO_LIBS +SNDIO_CFLAGS ARTSCONFIG PULSEAUDIO_LIBS PULSEAUDIO_CFLAGS +PIPEWIRE_LIBS +PIPEWIRE_CFLAGS +ESD_CONFIG ESD_LIBS ESD_CFLAGS -ESD_CONFIG JACK_LIBS JACK_CFLAGS ALSA_LIBS ALSA_CFLAGS -POW_LIB -LIBOBJS ALLOCA +CPP +LIBTOOLLINKERTAG +LINKER +SORT PKG_CONFIG_LIBDIR PKG_CONFIG_PATH PKG_CONFIG -WINDRES SET_MAKE INSTALL_DATA INSTALL_SCRIPT @@ -704,7 +743,8 @@ LT_AGE LT_REVISION LT_CURRENT LT_RELEASE -CPP +RC +LT_SYS_LIBRARY_PATH OTOOL64 OTOOL LIPO @@ -769,6 +809,7 @@ infodir docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -795,12 +836,16 @@ enable_shared enable_static with_pic enable_fast_install +with_aix_soname with_gnu_ld with_sysroot enable_libtool_lock +enable_largefile enable_assertions enable_dependency_tracking enable_libc +enable_system_iconv +enable_libiconv enable_gcc_atomics enable_atomic enable_audio @@ -809,12 +854,14 @@ enable_render enable_events enable_joystick enable_haptic +enable_hidapi enable_sensor enable_power enable_filesystem -enable_threads enable_timers enable_file +enable_misc +enable_locale enable_loadso enable_cpuinfo enable_assembly @@ -825,6 +872,7 @@ enable_sse enable_sse2 enable_sse3 enable_altivec +enable_lsx enable_oss enable_alsa with_alsa_prefix @@ -838,6 +886,8 @@ with_esd_prefix with_esd_exec_prefix enable_esdtest enable_esd_shared +enable_pipewire +enable_pipewire_shared enable_pulseaudio enable_pulseaudio_shared enable_arts @@ -854,21 +904,23 @@ enable_libsamplerate enable_libsamplerate_shared enable_arm_simd enable_arm_neon +enable_werror enable_video_wayland enable_video_wayland_qt_touch enable_wayland_shared +enable_libdecor +enable_libdecor_shared enable_video_rpi enable_video_x11 with_x enable_x11_shared enable_video_x11_xcursor enable_video_x11_xdbe -enable_video_x11_xinerama enable_video_x11_xinput +enable_video_x11_xfixes enable_video_x11_xrandr enable_video_x11_scrnsaver enable_video_x11_xshape -enable_video_x11_vm enable_video_vivante enable_video_cocoa enable_video_metal @@ -878,6 +930,7 @@ enable_directfb_shared enable_video_kmsdrm enable_kmsdrm_shared enable_video_dummy +enable_video_offscreen enable_video_opengl enable_video_opengles enable_video_opengles1 @@ -888,19 +941,22 @@ enable_dbus enable_ime enable_ibus enable_fcitx -enable_input_tslib +enable_joystick_mfi enable_pthreads enable_pthread_sem enable_directx +enable_xinput enable_wasapi -enable_sdl_dlopen -enable_hidapi +enable_hidapi_joystick +enable_hidapi_libusb enable_clock_gettime enable_rpath enable_backgrounding_signal enable_foregrounding_signal +enable_joystick_virtual enable_render_d3d enable_sdl2_config +enable_vendor_info ' ac_precious_vars='build_alias host_alias @@ -910,7 +966,7 @@ CFLAGS LDFLAGS LIBS CPPFLAGS -CPP +LT_SYS_LIBRARY_PATH CXX CXXFLAGS CCC @@ -918,12 +974,21 @@ CXXCPP PKG_CONFIG PKG_CONFIG_PATH PKG_CONFIG_LIBDIR +CPP JACK_CFLAGS JACK_LIBS +ESD_CFLAGS +ESD_LIBS +PIPEWIRE_CFLAGS +PIPEWIRE_LIBS PULSEAUDIO_CFLAGS PULSEAUDIO_LIBS +SNDIO_CFLAGS +SNDIO_LIBS FUSIONSOUND_CFLAGS FUSIONSOUND_LIBS +DECOR_CFLAGS +DECOR_LIBS RPI_CFLAGS RPI_LIBS XMKMF @@ -937,8 +1002,6 @@ DBUS_CFLAGS DBUS_LIBS IBUS_CFLAGS IBUS_LIBS -FCITX_CFLAGS -FCITX_LIBS LIBUSB_CFLAGS LIBUSB_LIBS' @@ -979,6 +1042,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}' @@ -1008,8 +1072,6 @@ do *) ac_optarg=yes ;; esac - # Accept the important Cygnus configure options, so we can diagnose typos. - case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; @@ -1050,9 +1112,9 @@ do ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" + as_fn_error $? "invalid feature name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" @@ -1076,9 +1138,9 @@ do ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" + as_fn_error $? "invalid feature name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" @@ -1231,6 +1293,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=* \ @@ -1280,9 +1351,9 @@ do ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" + as_fn_error $? "invalid package name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" @@ -1296,9 +1367,9 @@ do ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" + as_fn_error $? "invalid package name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" @@ -1342,9 +1413,9 @@ Try \`$0 --help' for more information" *) # FIXME: should be removed in autoconf 3.0. - $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + printf "%s\n" "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && - $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + printf "%s\n" "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; @@ -1360,7 +1431,7 @@ if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; - *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + *) printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi @@ -1368,7 +1439,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. @@ -1424,7 +1495,7 @@ $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_myself" | +printf "%s\n" X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q @@ -1521,6 +1592,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] @@ -1561,147 +1633,172 @@ Optional Features: --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) + --disable-largefile omit support for large files --enable-assertions Enable internal sanity checks (auto/disabled/release/enabled/paranoid) - [[default=auto]] + [default=auto] --enable-dependency-tracking - Use gcc -MMD -MT dependency tracking [[default=yes]] - --enable-libc Use the system C library [[default=yes]] - --enable-gcc-atomics Use gcc builtin atomics [[default=yes]] - --enable-atomic Enable the atomic operations subsystem - [[default=yes]] - --enable-audio Enable the audio subsystem [[default=yes]] - --enable-video Enable the video subsystem [[default=yes]] - --enable-render Enable the render subsystem [[default=yes]] - --enable-events Enable the events subsystem [[default=yes]] - --enable-joystick Enable the joystick subsystem [[default=yes]] + Use gcc -MMD -MT dependency tracking [default=yes] + --enable-libc Use the system C library [default=yes] + --enable-system-iconv Use iconv() from system-installed libraries + [default=no for windows, yes for others] + --enable-libiconv Prefer iconv() from libiconv, if available, over + libc version [default=no] + --enable-gcc-atomics Use gcc builtin atomics [default=yes] + --enable-atomic Enable the atomic operations subsystem [default=yes] + --enable-audio Enable the audio subsystem [default=yes] + --enable-video Enable the video subsystem [default=yes] + --enable-render Enable the render subsystem [default=yes] + --enable-events Enable the events subsystem [default=yes] + --enable-joystick Enable the joystick subsystem [default=yes] --enable-haptic Enable the haptic (force feedback) subsystem - [[default=yes]] - --enable-sensor Enable the sensor subsystem [[default=yes]] - --enable-power Enable the power subsystem [[default=yes]] - --enable-filesystem Enable the filesystem subsystem [[default=yes]] - --enable-threads Enable the threading subsystem [[default=yes]] - --enable-timers Enable the timer subsystem [[default=yes]] - --enable-file Enable the file subsystem [[default=yes]] + [default=yes] + --enable-hidapi Enable the HIDAPI subsystem [default=yes] + --enable-sensor Enable the sensor subsystem [default=yes] + --enable-power Enable the power subsystem [default=yes] + --enable-filesystem Enable the filesystem subsystem [default=yes] + --enable-timers Enable the timer subsystem [default=yes] + --enable-file Enable the file subsystem [default=yes] + --enable-misc Enable the misc subsystem [default=yes] + --enable-locale Enable the locale subsystem [default=yes] --enable-loadso Enable the shared object loading subsystem - [[default=yes]] - --enable-cpuinfo Enable the cpuinfo subsystem [[default=yes]] - --enable-assembly Enable assembly routines [[default=yes]] + [default=yes] + --enable-cpuinfo Enable the cpuinfo subsystem [default=yes] + --enable-assembly Enable assembly routines [default=yes] --enable-ssemath Allow GCC to use SSE floating point math - [[default=maybe]] - --enable-mmx use MMX assembly routines [[default=yes]] - --enable-3dnow use 3DNow! assembly routines [[default=yes]] - --enable-sse use SSE assembly routines [[default=yes]] - --enable-sse2 use SSE2 assembly routines [[default=maybe]] - --enable-sse3 use SSE3 assembly routines [[default=maybe]] - --enable-altivec use Altivec assembly routines [[default=yes]] - --enable-oss support the OSS audio API [[default=maybe]] - --enable-alsa support the ALSA audio API [[default=yes]] + [default=maybe] + --enable-mmx use MMX assembly routines [default=yes] + --enable-3dnow use 3DNow! assembly routines [default=yes] + --enable-sse use SSE assembly routines [default=yes] + --enable-sse2 use SSE2 assembly routines [default=maybe] + --enable-sse3 use SSE3 assembly routines [default=maybe] + --enable-altivec use Altivec assembly routines [default=yes] + --enable-lsx use LSX assembly routines [default=yes] + --enable-oss support the OSS audio API [default=maybe] + --enable-alsa support the ALSA audio API [default=yes] --disable-alsatest Do not try to compile and run a test Alsa program - --enable-alsa-shared dynamically load ALSA audio support [[default=yes]] - --enable-jack use JACK audio [[default=yes]] - --enable-jack-shared dynamically load JACK audio support [[default=yes]] - --enable-esd support the Enlightened Sound Daemon [[default=yes]] + --enable-alsa-shared dynamically load ALSA audio support [default=yes] + --enable-jack use JACK audio [default=yes] + --enable-jack-shared dynamically load JACK audio support [default=yes] + --enable-esd support the Enlightened Sound Daemon [default=yes] --disable-esdtest Do not try to compile and run a test ESD program - --enable-esd-shared dynamically load ESD audio support [[default=yes]] - --enable-pulseaudio use PulseAudio [[default=yes]] + --enable-esd-shared dynamically load ESD audio support [default=yes] + --enable-pipewire use Pipewire audio [default=yes] + --enable-pipewire-shared + dynamically load Pipewire support [default=yes] + --enable-pulseaudio use PulseAudio [default=yes] --enable-pulseaudio-shared - dynamically load PulseAudio support [[default=yes]] + dynamically load PulseAudio support [default=yes] --enable-arts support the Analog Real Time Synthesizer - [[default=yes]] - --enable-arts-shared dynamically load aRts audio support [[default=yes]] - --enable-nas support the NAS audio API [[default=yes]] - --enable-nas-shared dynamically load NAS audio support [[default=yes]] - --enable-sndio support the sndio audio API [[default=yes]] - --enable-sndio-shared dynamically load sndio audio support [[default=yes]] - --enable-fusionsound use FusionSound audio driver [[default=no]] + [default=yes] + --enable-arts-shared dynamically load aRts audio support [default=yes] + --enable-nas support the NAS audio API [default=yes] + --enable-nas-shared dynamically load NAS audio support [default=yes] + --enable-sndio support the sndio audio API [default=yes] + --enable-sndio-shared dynamically load sndio audio support [default=yes] + --enable-fusionsound use FusionSound audio driver [default=no] --enable-fusionsound-shared dynamically load fusionsound audio support - [[default=yes]] - --enable-diskaudio support the disk writer audio driver [[default=yes]] - --enable-dummyaudio support the dummy audio driver [[default=yes]] + [default=yes] + --enable-diskaudio support the disk writer audio driver [default=yes] + --enable-dummyaudio support the dummy audio driver [default=yes] --enable-libsamplerate use libsamplerate for audio rate conversion - [[default=yes]] + [default=yes] --enable-libsamplerate-shared - dynamically load libsamplerate [[default=yes]] - --enable-arm-simd use SIMD assembly blitters on ARM [[default=yes]] - --enable-arm-neon use NEON assembly blitters on ARM [[default=no]] - --enable-video-wayland use Wayland video driver [[default=yes]] + dynamically load libsamplerate [default=yes] + --enable-arm-simd use SIMD assembly blitters on ARM [default=no] + --enable-arm-neon use NEON assembly blitters on ARM [default=no] + --enable-werror treat warnings as errors [default=no] + --enable-video-wayland use Wayland video driver [default=yes] --enable-video-wayland-qt-touch QtWayland server support for Wayland video driver - [[default=yes]] - --enable-wayland-shared dynamically load Wayland support [[default=maybe]] - --enable-video-rpi use Raspberry Pi video driver [[default=yes]] - --enable-video-x11 use X11 video driver [[default=yes]] - --enable-x11-shared dynamically load X11 support [[default=maybe]] + [default=yes] + --enable-wayland-shared dynamically load Wayland support [default=maybe] + --enable-libdecor use libdecor for Wayland client-side decorations + [default=yes] + --enable-libdecor-shared + dynamically load libdecor [default=yes] + --enable-video-rpi use Raspberry Pi 2/3 video driver [default=yes] + --enable-video-x11 use X11 video driver [default=maybe] + --enable-x11-shared dynamically load X11 support [default=maybe] --enable-video-x11-xcursor - enable X11 Xcursor support [[default=yes]] - --enable-video-x11-xdbe enable X11 Xdbe support [[default=yes]] - --enable-video-x11-xinerama - enable X11 Xinerama support [[default=yes]] + enable X11 Xcursor support [default=yes] + --enable-video-x11-xdbe enable X11 Xdbe support [default=yes] --enable-video-x11-xinput enable X11 XInput extension for manymouse, tablets, - etc [[default=yes]] + etc [default=yes] + --enable-video-x11-xfixes + enable X11 Xfixes support [default=yes] --enable-video-x11-xrandr enable X11 Xrandr extension for fullscreen - [[default=yes]] + [default=yes] --enable-video-x11-scrnsaver - enable X11 screensaver extension [[default=yes]] + enable X11 screensaver extension [default=yes] --enable-video-x11-xshape - enable X11 XShape support [[default=yes]] - --enable-video-x11-vm use X11 VM extension for fullscreen [[default=yes]] - --enable-video-vivante use Vivante EGL video driver [[default=yes]] - --enable-video-cocoa use Cocoa video driver [[default=yes]] - --enable-video-metal include Metal support [[default=yes]] - --enable-render-metal enable the Metal render driver [[default=yes]] - --enable-video-directfb use DirectFB video driver [[default=no]] + enable X11 XShape support [default=yes] + --enable-video-vivante use Vivante EGL video driver [default=yes] + --enable-video-cocoa use Cocoa video driver [default=yes] + --enable-video-metal include Metal support [default=yes] + --enable-render-metal enable the Metal render driver [default=yes] + --enable-video-directfb use DirectFB video driver [default=no] --enable-directfb-shared - dynamically load directfb support [[default=yes]] - --enable-video-kmsdrm use KMSDRM video driver [[default=no]] - --enable-kmsdrm-shared dynamically load kmsdrm support [[default=yes]] - --enable-video-dummy use dummy video driver [[default=yes]] - --enable-video-opengl include OpenGL support [[default=yes]] - --enable-video-opengles include OpenGL ES support [[default=yes]] + dynamically load directfb support [default=yes] + --enable-video-kmsdrm use KMSDRM video driver [default=yes] + --enable-kmsdrm-shared dynamically load kmsdrm support [default=yes] + --enable-video-dummy use dummy video driver [default=yes] + --enable-video-offscreen + use offscreen video driver [default=yes] + --enable-video-opengl include OpenGL support [default=yes] + --enable-video-opengles include OpenGL ES support [default=yes] --enable-video-opengles1 - include OpenGL ES 1.1 support [[default=yes]] + include OpenGL ES 1.1 support [default=yes] --enable-video-opengles2 - include OpenGL ES 2.0 support [[default=yes]] - --enable-video-vulkan include Vulkan support [[default=yes]] - --enable-libudev enable libudev support [[default=yes]] - --enable-dbus enable D-Bus support [[default=yes]] - --enable-ime enable IME support [[default=yes]] - --enable-ibus enable IBus support [[default=yes]] - --enable-fcitx enable fcitx support [[default=yes]] - --enable-input-tslib use the Touchscreen library for input - [[default=yes]] + include OpenGL ES 2.0 support [default=yes] + --enable-video-vulkan include Vulkan support [default=yes] + --enable-libudev enable libudev support [default=yes] + --enable-dbus enable D-Bus support [default=yes] + --enable-ime enable IME support [default=yes] + --enable-ibus enable IBus support [default=yes] + --enable-fcitx enable fcitx support [default=yes] + --enable-joystick-mfi include macOS MFI joystick support [default=yes] --enable-pthreads use POSIX threads for multi-threading - [[default=yes]] - --enable-pthread-sem use pthread semaphores [[default=yes]] - --enable-directx use DirectX for Windows audio/video [[default=yes]] - --enable-wasapi use the Windows WASAPI audio driver [[default=yes]] - --enable-sdl-dlopen use dlopen for shared object loading [[default=yes]] - --enable-hidapi use HIDAPI for low level joystick drivers - [[default=no]] + [default=maybe] + --enable-pthread-sem use pthread semaphores [default=maybe] + --enable-directx use DirectX for Windows audio/video [default=yes] + --enable-xinput use Xinput for Windows [default=yes] + --enable-wasapi use the Windows WASAPI audio driver [default=yes] + --enable-hidapi-joystick + use HIDAPI for low level joystick drivers + [default=yes] + --enable-hidapi-libusb use libusb for low level joystick drivers + [default=maybe] --enable-clock_gettime use clock_gettime() instead of gettimeofday() on - UNIX [[default=yes]] - --enable-rpath use an rpath when linking SDL [[default=yes]] + UNIX [default=yes] + --enable-rpath use an rpath when linking SDL [default=yes] --enable-backgrounding-signal number to use for magic backgrounding signal or 'no' - [[default=no]] + [default=no] --enable-foregrounding-signal number to use for magic foregrounding signal or 'no' - [[default=no]] - --enable-render-d3d enable the Direct3D render driver [[default=yes]] + [default=no] + --enable-joystick-virtual + enable virtual joystick APIs [default=yes] + --enable-render-d3d enable the Direct3D render driver [default=yes] --enable-sdl2-config Install sdl2-config [default=yes] + --enable-vendor-info=STRING + Add vendor info to SDL_REVISION Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use both] + --with-aix-soname=aix|svr4|both + shared library versioning (aka "SONAME") variant to + provide on AIX, [default=aix]. --with-gnu-ld assume the C compiler uses GNU ld [default=no] - --with-sysroot=DIR Search for dependent libraries within DIR - (or the compiler's sysroot if not specified). + --with-sysroot[=DIR] Search for dependent libraries within DIR (or the + compiler's sysroot if not specified). --with-alsa-prefix=PFX Prefix where Alsa library is installed(optional) --with-alsa-inc-prefix=PFX Prefix where include libraries are (optional) --with-esd-prefix=PFX Prefix where ESD is installed (optional) @@ -1716,7 +1813,8 @@ Some influential environment variables: LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory - CPP C preprocessor + LT_SYS_LIBRARY_PATH + User-defined run-time library search path. CXX C++ compiler command CXXFLAGS C++ compiler flags CXXCPP C++ preprocessor @@ -1725,16 +1823,29 @@ Some influential environment variables: directories to add to pkg-config's search path PKG_CONFIG_LIBDIR path overriding pkg-config's built-in search path + CPP C preprocessor JACK_CFLAGS C compiler flags for JACK, overriding pkg-config JACK_LIBS linker flags for JACK, overriding pkg-config + ESD_CFLAGS C compiler flags for ESD, overriding pkg-config + ESD_LIBS linker flags for ESD, overriding pkg-config + PIPEWIRE_CFLAGS + C compiler flags for PIPEWIRE, overriding pkg-config + PIPEWIRE_LIBS + linker flags for PIPEWIRE, overriding pkg-config PULSEAUDIO_CFLAGS C compiler flags for PULSEAUDIO, overriding pkg-config PULSEAUDIO_LIBS linker flags for PULSEAUDIO, overriding pkg-config + SNDIO_CFLAGS + C compiler flags for SNDIO, overriding pkg-config + SNDIO_LIBS linker flags for SNDIO, overriding pkg-config FUSIONSOUND_CFLAGS C compiler flags for FUSIONSOUND, overriding pkg-config FUSIONSOUND_LIBS linker flags for FUSIONSOUND, overriding pkg-config + DECOR_CFLAGS + C compiler flags for DECOR, overriding pkg-config + DECOR_LIBS linker flags for DECOR, overriding pkg-config RPI_CFLAGS C compiler flags for RPI, overriding pkg-config RPI_LIBS linker flags for RPI, overriding pkg-config XMKMF Path to xmkmf, Makefile generator for X Window System @@ -1752,9 +1863,6 @@ Some influential environment variables: DBUS_LIBS linker flags for DBUS, overriding pkg-config IBUS_CFLAGS C compiler flags for IBUS, overriding pkg-config IBUS_LIBS linker flags for IBUS, overriding pkg-config - FCITX_CFLAGS - C compiler flags for FCITX, overriding pkg-config - FCITX_LIBS linker flags for FCITX, overriding pkg-config LIBUSB_CFLAGS C compiler flags for LIBUSB, overriding pkg-config LIBUSB_LIBS linker flags for LIBUSB, overriding pkg-config @@ -1778,9 +1886,9 @@ if test "$ac_init_help" = "recursive"; then case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; @@ -1808,7 +1916,8 @@ esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } - # Check for guested configure. + # Check for configure.gnu first; this name is used for a wrapper for + # Metaconfig's "Configure" on case-insensitive file systems. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive @@ -1816,7 +1925,7 @@ ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix echo && $SHELL "$ac_srcdir/configure" --help=recursive else - $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + printf "%s\n" "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done @@ -1826,9 +1935,9 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF configure -generated by GNU Autoconf 2.69 +generated by GNU Autoconf 2.71 -Copyright (C) 2012 Free Software Foundation, Inc. +Copyright (C) 2021 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF @@ -1845,14 +1954,14 @@ fi ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext + rm -f conftest.$ac_objext conftest.beam if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 +printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then @@ -1860,14 +1969,15 @@ $as_echo "$ac_try_echo"; } >&5 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest.$ac_objext; then : + } && test -s conftest.$ac_objext +then : ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 +else $as_nop + printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 @@ -1883,14 +1993,14 @@ fi ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext conftest$ac_exeext + rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 +printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then @@ -1898,17 +2008,18 @@ $as_echo "$ac_try_echo"; } >&5 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext - }; then : + } +then : ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 +else $as_nop + printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 @@ -1930,120 +2041,44 @@ fi ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +printf %s "checking for $2... " >&6; } +if eval test \${$3+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : eval "$3=yes" -else +else $as_nop eval "$3=no" fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile -# ac_fn_c_try_cpp LINENO -# ---------------------- -# Try to preprocess conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_cpp () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } > conftest.i && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_cpp - -# ac_fn_c_try_run LINENO -# ---------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes -# that executables *can* be run. -ac_fn_c_try_run () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then : - ac_retval=0 -else - $as_echo "$as_me: program exited with status $ac_status" >&5 - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=$ac_status -fi - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_run - # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +printf %s "checking for $2... " >&6; } +if eval test \${$3+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. @@ -2051,16 +2086,9 @@ else #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $2 (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif + which can conflict with char $2 (); below. */ +#include #undef $2 /* Override any GCC internal prototype to avoid an error. @@ -2078,24 +2106,25 @@ choke me #endif int -main () +main (void) { return $2 (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : eval "$3=yes" -else +else $as_nop eval "$3=no" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func @@ -2106,14 +2135,14 @@ $as_echo "$ac_res" >&6; } ac_fn_cxx_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext + rm -f conftest.$ac_objext conftest.beam if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 +printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then @@ -2121,14 +2150,15 @@ $as_echo "$ac_try_echo"; } >&5 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err - } && test -s conftest.$ac_objext; then : + } && test -s conftest.$ac_objext +then : ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 +else $as_nop + printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 @@ -2150,7 +2180,7 @@ case "(($ac_try" in *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 +printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then @@ -2158,14 +2188,15 @@ $as_echo "$ac_try_echo"; } >&5 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err - }; then : + } +then : ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 +else $as_nop + printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 @@ -2181,14 +2212,14 @@ fi ac_fn_cxx_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext conftest$ac_exeext + rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 +printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then @@ -2196,17 +2227,18 @@ $as_echo "$ac_try_echo"; } >&5 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext - }; then : + } +then : ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 +else $as_nop + printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 @@ -2221,93 +2253,6 @@ fi } # ac_fn_cxx_try_link -# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES -# ------------------------------------------------------- -# Tests whether HEADER exists, giving a warning if it cannot be compiled using -# the include files in INCLUDES and setting the cache variable VAR -# accordingly. -ac_fn_c_check_header_mongrel () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if eval \${$3+:} false; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -else - # Is the header compilable? -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 -$as_echo_n "checking $2 usability... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -#include <$2> -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_header_compiler=yes -else - ac_header_compiler=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 -$as_echo "$ac_header_compiler" >&6; } - -# Is the header present? -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 -$as_echo_n "checking $2 presence... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <$2> -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - ac_header_preproc=yes -else - ac_header_preproc=no -fi -rm -f conftest.err conftest.i conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 -$as_echo "$ac_header_preproc" >&6; } - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( - yes:no: ) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 -$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 -$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} - ;; - no:yes:* ) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 -$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 -$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 -$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 -$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 -$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} - ;; -esac - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - eval "$3=\$ac_header_compiler" -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_header_mongrel - # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache @@ -2315,17 +2260,18 @@ fi ac_fn_c_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +printf %s "checking for $2... " >&6; } +if eval test \${$3+y} +then : + printf %s "(cached) " >&6 +else $as_nop eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int -main () +main (void) { if (sizeof ($2)) return 0; @@ -2333,12 +2279,13 @@ if (sizeof ($2)) return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int -main () +main (void) { if (sizeof (($2))) return 0; @@ -2346,22 +2293,104 @@ if (sizeof (($2))) return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : -else +else $as_nop eval "$3=yes" fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_type +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + } +then : + ac_retval=0 +else $as_nop + printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to run conftest.$ac_ext, and return whether this succeeded. Assumes that +# executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; } +then : + ac_retval=0 +else $as_nop + printf "%s\n" "$as_me: program exited with status $ac_status" >&5 + printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + # ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES # ---------------------------------------------------- # Tries to find if the field MEMBER exists in type AGGR, after including @@ -2369,16 +2398,17 @@ $as_echo "$ac_res" >&6; } ac_fn_c_check_member () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5 -$as_echo_n "checking for $2.$3... " >&6; } -if eval \${$4+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5 +printf %s "checking for $2.$3... " >&6; } +if eval test \${$4+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $5 int -main () +main (void) { static $2 ac_aggr; if (ac_aggr.$3) @@ -2387,14 +2417,15 @@ return 0; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : eval "$4=yes" -else +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $5 int -main () +main (void) { static $2 ac_aggr; if (sizeof ac_aggr.$3) @@ -2403,29 +2434,102 @@ return 0; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : eval "$4=yes" -else +else $as_nop eval "$4=no" fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi eval ac_res=\$$4 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_member + +# ac_fn_check_decl LINENO SYMBOL VAR INCLUDES EXTRA-OPTIONS FLAG-VAR +# ------------------------------------------------------------------ +# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR +# accordingly. Pass EXTRA-OPTIONS to the compiler, using FLAG-VAR. +ac_fn_check_decl () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + as_decl_name=`echo $2|sed 's/ *(.*//'` + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 +printf %s "checking whether $as_decl_name is declared... " >&6; } +if eval test \${$3+y} +then : + printf %s "(cached) " >&6 +else $as_nop + as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` + eval ac_save_FLAGS=\$$6 + as_fn_append $6 " $5" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main (void) +{ +#ifndef $as_decl_name +#ifdef __cplusplus + (void) $as_decl_use; +#else + (void) $as_decl_name; +#endif +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + eval "$3=yes" +else $as_nop + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + eval $6=\$ac_save_FLAGS + +fi +eval ac_res=\$$3 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_check_decl +ac_configure_args_raw= +for ac_arg +do + case $ac_arg in + *\'*) + ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append ac_configure_args_raw " '$ac_arg'" +done + +case $ac_configure_args_raw in + *$as_nl*) + ac_safe_unquote= ;; + *) + ac_unsafe_z='|&;<>()$`\\"*?[ '' ' # This string ends in space, tab. + ac_unsafe_a="$ac_unsafe_z#~" + ac_safe_unquote="s/ '\\([^$ac_unsafe_a][^$ac_unsafe_z]*\\)'/ \\1/g" + ac_configure_args_raw=` printf "%s\n" "$ac_configure_args_raw" | sed "$ac_safe_unquote"`;; +esac + cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by $as_me, which was -generated by GNU Autoconf 2.69. Invocation command line was +generated by GNU Autoconf 2.71. Invocation command line was - $ $0 $@ + $ $0$ac_configure_args_raw _ACEOF exec 5>>config.log @@ -2458,8 +2562,12 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - $as_echo "PATH: $as_dir" + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + printf "%s\n" "PATH: $as_dir" done IFS=$as_save_IFS @@ -2494,7 +2602,7 @@ do | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) - ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; @@ -2529,11 +2637,13 @@ done # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? + # Sanitize IFS. + IFS=" "" $as_nl" # Save into config.log some information that might help in debugging. { echo - $as_echo "## ---------------- ## + printf "%s\n" "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo @@ -2544,8 +2654,8 @@ trap 'exit_status=$? case $ac_val in #( *${as_nl}*) case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( @@ -2569,7 +2679,7 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; ) echo - $as_echo "## ----------------- ## + printf "%s\n" "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo @@ -2577,14 +2687,14 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; do eval ac_val=\$$ac_var case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac - $as_echo "$ac_var='\''$ac_val'\''" + printf "%s\n" "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then - $as_echo "## ------------------- ## + printf "%s\n" "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo @@ -2592,15 +2702,15 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; do eval ac_val=\$$ac_var case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac - $as_echo "$ac_var='\''$ac_val'\''" + printf "%s\n" "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then - $as_echo "## ----------- ## + printf "%s\n" "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo @@ -2608,8 +2718,8 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; echo fi test "$ac_signal" != 0 && - $as_echo "$as_me: caught signal $ac_signal" - $as_echo "$as_me: exit $exit_status" + printf "%s\n" "$as_me: caught signal $ac_signal" + printf "%s\n" "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && @@ -2623,63 +2733,48 @@ ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h -$as_echo "/* confdefs.h */" > confdefs.h +printf "%s\n" "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. -cat >>confdefs.h <<_ACEOF -#define PACKAGE_NAME "$PACKAGE_NAME" -_ACEOF +printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h -cat >>confdefs.h <<_ACEOF -#define PACKAGE_TARNAME "$PACKAGE_TARNAME" -_ACEOF +printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h -cat >>confdefs.h <<_ACEOF -#define PACKAGE_VERSION "$PACKAGE_VERSION" -_ACEOF +printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h -cat >>confdefs.h <<_ACEOF -#define PACKAGE_STRING "$PACKAGE_STRING" -_ACEOF +printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h -cat >>confdefs.h <<_ACEOF -#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" -_ACEOF +printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h -cat >>confdefs.h <<_ACEOF -#define PACKAGE_URL "$PACKAGE_URL" -_ACEOF +printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. -ac_site_file1=NONE -ac_site_file2=NONE if test -n "$CONFIG_SITE"; then - # We do not want a PATH search for config.site. - case $CONFIG_SITE in #(( - -*) ac_site_file1=./$CONFIG_SITE;; - */*) ac_site_file1=$CONFIG_SITE;; - *) ac_site_file1=./$CONFIG_SITE;; - esac + ac_site_files="$CONFIG_SITE" elif test "x$prefix" != xNONE; then - ac_site_file1=$prefix/share/config.site - ac_site_file2=$prefix/etc/config.site + ac_site_files="$prefix/share/config.site $prefix/etc/config.site" else - ac_site_file1=$ac_default_prefix/share/config.site - ac_site_file2=$ac_default_prefix/etc/config.site + ac_site_files="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi -for ac_site_file in "$ac_site_file1" "$ac_site_file2" + +for ac_site_file in $ac_site_files do - test "x$ac_site_file" = xNONE && continue - if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 -$as_echo "$as_me: loading site script $ac_site_file" >&6;} + case $ac_site_file in #( + */*) : + ;; #( + *) : + ac_site_file=./$ac_site_file ;; +esac + if test -f "$ac_site_file" && test -r "$ac_site_file"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ - || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi @@ -2689,19 +2784,650 @@ if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 -$as_echo "$as_me: loading cache $cache_file" >&6;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +printf "%s\n" "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else - { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 -$as_echo "$as_me: creating cache $cache_file" >&6;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +printf "%s\n" "$as_me: creating cache $cache_file" >&6;} >$cache_file fi +# Test code for whether the C compiler supports C89 (global declarations) +ac_c_conftest_c89_globals=' +/* Does the compiler advertise C89 conformance? + Do not test the value of __STDC__, because some compilers set it to 0 + while being otherwise adequately conformant. */ +#if !defined __STDC__ +# error "Compiler does not advertise C89 conformance" +#endif + +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7 src/conf.sh. */ +struct buf { int x; }; +struct buf * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not \xHH hex character constants. + These do not provoke an error unfortunately, instead are silently treated + as an "x". The following induces an error, until -std is added to get + proper ANSI mode. Curiously \x00 != x always comes out true, for an + array size at least. It is necessary to write \x00 == 0 to get something + that is true only with -std. */ +int osf4_cc_array ['\''\x00'\'' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) '\''x'\'' +int xlc6_cc_array[FOO(a) == '\''x'\'' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, int *(*)(struct buf *, struct stat *, int), + int, int);' + +# Test code for whether the C compiler supports C89 (body of main). +ac_c_conftest_c89_main=' +ok |= (argc == 0 || f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]); +' + +# Test code for whether the C compiler supports C99 (global declarations) +ac_c_conftest_c99_globals=' +// Does the compiler advertise C99 conformance? +#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L +# error "Compiler does not advertise C99 conformance" +#endif + +#include +extern int puts (const char *); +extern int printf (const char *, ...); +extern int dprintf (int, const char *, ...); +extern void *malloc (size_t); + +// Check varargs macros. These examples are taken from C99 6.10.3.5. +// dprintf is used instead of fprintf to avoid needing to declare +// FILE and stderr. +#define debug(...) dprintf (2, __VA_ARGS__) +#define showlist(...) puts (#__VA_ARGS__) +#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) +static void +test_varargs_macros (void) +{ + int x = 1234; + int y = 5678; + debug ("Flag"); + debug ("X = %d\n", x); + showlist (The first, second, and third items.); + report (x>y, "x is %d but y is %d", x, y); +} + +// Check long long types. +#define BIG64 18446744073709551615ull +#define BIG32 4294967295ul +#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) +#if !BIG_OK + #error "your preprocessor is broken" +#endif +#if BIG_OK +#else + #error "your preprocessor is broken" +#endif +static long long int bignum = -9223372036854775807LL; +static unsigned long long int ubignum = BIG64; + +struct incomplete_array +{ + int datasize; + double data[]; +}; + +struct named_init { + int number; + const wchar_t *name; + double average; +}; + +typedef const char *ccp; + +static inline int +test_restrict (ccp restrict text) +{ + // See if C++-style comments work. + // Iterate through items via the restricted pointer. + // Also check for declarations in for loops. + for (unsigned int i = 0; *(text+i) != '\''\0'\''; ++i) + continue; + return 0; +} + +// Check varargs and va_copy. +static bool +test_varargs (const char *format, ...) +{ + va_list args; + va_start (args, format); + va_list args_copy; + va_copy (args_copy, args); + + const char *str = ""; + int number = 0; + float fnumber = 0; + + while (*format) + { + switch (*format++) + { + case '\''s'\'': // string + str = va_arg (args_copy, const char *); + break; + case '\''d'\'': // int + number = va_arg (args_copy, int); + break; + case '\''f'\'': // float + fnumber = va_arg (args_copy, double); + break; + default: + break; + } + } + va_end (args_copy); + va_end (args); + + return *str && number && fnumber; +} +' + +# Test code for whether the C compiler supports C99 (body of main). +ac_c_conftest_c99_main=' + // Check bool. + _Bool success = false; + success |= (argc != 0); + + // Check restrict. + if (test_restrict ("String literal") == 0) + success = true; + char *restrict newvar = "Another string"; + + // Check varargs. + success &= test_varargs ("s, d'\'' f .", "string", 65, 34.234); + test_varargs_macros (); + + // Check flexible array members. + struct incomplete_array *ia = + malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); + ia->datasize = 10; + for (int i = 0; i < ia->datasize; ++i) + ia->data[i] = i * 1.234; + + // Check named initializers. + struct named_init ni = { + .number = 34, + .name = L"Test wide string", + .average = 543.34343, + }; + + ni.number = 58; + + int dynamic_array[ni.number]; + dynamic_array[0] = argv[0][0]; + dynamic_array[ni.number - 1] = 543; + + // work around unused variable warnings + ok |= (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == '\''x'\'' + || dynamic_array[ni.number - 1] != 543); +' + +# Test code for whether the C compiler supports C11 (global declarations) +ac_c_conftest_c11_globals=' +// Does the compiler advertise C11 conformance? +#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112L +# error "Compiler does not advertise C11 conformance" +#endif + +// Check _Alignas. +char _Alignas (double) aligned_as_double; +char _Alignas (0) no_special_alignment; +extern char aligned_as_int; +char _Alignas (0) _Alignas (int) aligned_as_int; + +// Check _Alignof. +enum +{ + int_alignment = _Alignof (int), + int_array_alignment = _Alignof (int[100]), + char_alignment = _Alignof (char) +}; +_Static_assert (0 < -_Alignof (int), "_Alignof is signed"); + +// Check _Noreturn. +int _Noreturn does_not_return (void) { for (;;) continue; } + +// Check _Static_assert. +struct test_static_assert +{ + int x; + _Static_assert (sizeof (int) <= sizeof (long int), + "_Static_assert does not work in struct"); + long int y; +}; + +// Check UTF-8 literals. +#define u8 syntax error! +char const utf8_literal[] = u8"happens to be ASCII" "another string"; + +// Check duplicate typedefs. +typedef long *long_ptr; +typedef long int *long_ptr; +typedef long_ptr long_ptr; + +// Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1. +struct anonymous +{ + union { + struct { int i; int j; }; + struct { int k; long int l; } w; + }; + int m; +} v1; +' + +# Test code for whether the C compiler supports C11 (body of main). +ac_c_conftest_c11_main=' + _Static_assert ((offsetof (struct anonymous, i) + == offsetof (struct anonymous, w.k)), + "Anonymous union alignment botch"); + v1.i = 2; + v1.w.k = 5; + ok |= v1.i != 5; +' + +# Test code for whether the C compiler supports C11 (complete). +ac_c_conftest_c11_program="${ac_c_conftest_c89_globals} +${ac_c_conftest_c99_globals} +${ac_c_conftest_c11_globals} + +int +main (int argc, char **argv) +{ + int ok = 0; + ${ac_c_conftest_c89_main} + ${ac_c_conftest_c99_main} + ${ac_c_conftest_c11_main} + return ok; +} +" + +# Test code for whether the C compiler supports C99 (complete). +ac_c_conftest_c99_program="${ac_c_conftest_c89_globals} +${ac_c_conftest_c99_globals} + +int +main (int argc, char **argv) +{ + int ok = 0; + ${ac_c_conftest_c89_main} + ${ac_c_conftest_c99_main} + return ok; +} +" + +# Test code for whether the C compiler supports C89 (complete). +ac_c_conftest_c89_program="${ac_c_conftest_c89_globals} + +int +main (int argc, char **argv) +{ + int ok = 0; + ${ac_c_conftest_c89_main} + return ok; +} +" + +as_fn_append ac_header_c_list " stdio.h stdio_h HAVE_STDIO_H" +as_fn_append ac_header_c_list " stdlib.h stdlib_h HAVE_STDLIB_H" +as_fn_append ac_header_c_list " string.h string_h HAVE_STRING_H" +as_fn_append ac_header_c_list " inttypes.h inttypes_h HAVE_INTTYPES_H" +as_fn_append ac_header_c_list " stdint.h stdint_h HAVE_STDINT_H" +as_fn_append ac_header_c_list " strings.h strings_h HAVE_STRINGS_H" +as_fn_append ac_header_c_list " sys/stat.h sys_stat_h HAVE_SYS_STAT_H" +as_fn_append ac_header_c_list " sys/types.h sys_types_h HAVE_SYS_TYPES_H" +as_fn_append ac_header_c_list " unistd.h unistd_h HAVE_UNISTD_H" +# Test code for whether the C++ compiler supports C++98 (global declarations) +ac_cxx_conftest_cxx98_globals=' +// Does the compiler advertise C++98 conformance? +#if !defined __cplusplus || __cplusplus < 199711L +# error "Compiler does not advertise C++98 conformance" +#endif + +// These inclusions are to reject old compilers that +// lack the unsuffixed header files. +#include +#include + +// and are *not* freestanding headers in C++98. +extern void assert (int); +namespace std { + extern int strcmp (const char *, const char *); +} + +// Namespaces, exceptions, and templates were all added after "C++ 2.0". +using std::exception; +using std::strcmp; + +namespace { + +void test_exception_syntax() +{ + try { + throw "test"; + } catch (const char *s) { + // Extra parentheses suppress a warning when building autoconf itself, + // due to lint rules shared with more typical C programs. + assert (!(strcmp) (s, "test")); + } +} + +template struct test_template +{ + T const val; + explicit test_template(T t) : val(t) {} + template T add(U u) { return static_cast(u) + val; } +}; + +} // anonymous namespace +' + +# Test code for whether the C++ compiler supports C++98 (body of main) +ac_cxx_conftest_cxx98_main=' + assert (argc); + assert (! argv[0]); +{ + test_exception_syntax (); + test_template tt (2.0); + assert (tt.add (4) == 6.0); + assert (true && !false); +} +' + +# Test code for whether the C++ compiler supports C++11 (global declarations) +ac_cxx_conftest_cxx11_globals=' +// Does the compiler advertise C++ 2011 conformance? +#if !defined __cplusplus || __cplusplus < 201103L +# error "Compiler does not advertise C++11 conformance" +#endif + +namespace cxx11test +{ + constexpr int get_val() { return 20; } + + struct testinit + { + int i; + double d; + }; + + class delegate + { + public: + delegate(int n) : n(n) {} + delegate(): delegate(2354) {} + + virtual int getval() { return this->n; }; + protected: + int n; + }; + + class overridden : public delegate + { + public: + overridden(int n): delegate(n) {} + virtual int getval() override final { return this->n * 2; } + }; + + class nocopy + { + public: + nocopy(int i): i(i) {} + nocopy() = default; + nocopy(const nocopy&) = delete; + nocopy & operator=(const nocopy&) = delete; + private: + int i; + }; + + // for testing lambda expressions + template Ret eval(Fn f, Ret v) + { + return f(v); + } + + // for testing variadic templates and trailing return types + template auto sum(V first) -> V + { + return first; + } + template auto sum(V first, Args... rest) -> V + { + return first + sum(rest...); + } +} +' + +# Test code for whether the C++ compiler supports C++11 (body of main) +ac_cxx_conftest_cxx11_main=' +{ + // Test auto and decltype + auto a1 = 6538; + auto a2 = 48573953.4; + auto a3 = "String literal"; + + int total = 0; + for (auto i = a3; *i; ++i) { total += *i; } + + decltype(a2) a4 = 34895.034; +} +{ + // Test constexpr + short sa[cxx11test::get_val()] = { 0 }; +} +{ + // Test initializer lists + cxx11test::testinit il = { 4323, 435234.23544 }; +} +{ + // Test range-based for + int array[] = {9, 7, 13, 15, 4, 18, 12, 10, 5, 3, + 14, 19, 17, 8, 6, 20, 16, 2, 11, 1}; + for (auto &x : array) { x += 23; } +} +{ + // Test lambda expressions + using cxx11test::eval; + assert (eval ([](int x) { return x*2; }, 21) == 42); + double d = 2.0; + assert (eval ([&](double x) { return d += x; }, 3.0) == 5.0); + assert (d == 5.0); + assert (eval ([=](double x) mutable { return d += x; }, 4.0) == 9.0); + assert (d == 5.0); +} +{ + // Test use of variadic templates + using cxx11test::sum; + auto a = sum(1); + auto b = sum(1, 2); + auto c = sum(1.0, 2.0, 3.0); +} +{ + // Test constructor delegation + cxx11test::delegate d1; + cxx11test::delegate d2(); + cxx11test::delegate d3(45); +} +{ + // Test override and final + cxx11test::overridden o1(55464); +} +{ + // Test nullptr + char *c = nullptr; +} +{ + // Test template brackets + test_template<::test_template> v(test_template(12)); +} +{ + // Unicode literals + char const *utf8 = u8"UTF-8 string \u2500"; + char16_t const *utf16 = u"UTF-8 string \u2500"; + char32_t const *utf32 = U"UTF-32 string \u2500"; +} +' + +# Test code for whether the C compiler supports C++11 (complete). +ac_cxx_conftest_cxx11_program="${ac_cxx_conftest_cxx98_globals} +${ac_cxx_conftest_cxx11_globals} + +int +main (int argc, char **argv) +{ + int ok = 0; + ${ac_cxx_conftest_cxx98_main} + ${ac_cxx_conftest_cxx11_main} + return ok; +} +" + +# Test code for whether the C compiler supports C++98 (complete). +ac_cxx_conftest_cxx98_program="${ac_cxx_conftest_cxx98_globals} +int +main (int argc, char **argv) +{ + int ok = 0; + ${ac_cxx_conftest_cxx98_main} + return ok; +} +" + + +# Auxiliary files required by this configure script. +ac_aux_files="install-sh config.guess config.sub ltmain.sh" + +# Locations in which to look for auxiliary files. +ac_aux_dir_candidates="${srcdir}/build-scripts" + +# Search for a directory containing all of the required auxiliary files, +# $ac_aux_files, from the $PATH-style list $ac_aux_dir_candidates. +# If we don't find one directory that contains all the files we need, +# we report the set of missing files from the *first* directory in +# $ac_aux_dir_candidates and give up. +ac_missing_aux_files="" +ac_first_candidate=: +printf "%s\n" "$as_me:${as_lineno-$LINENO}: looking for aux files: $ac_aux_files" >&5 +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in $ac_aux_dir_candidates +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + as_found=: + + printf "%s\n" "$as_me:${as_lineno-$LINENO}: trying $as_dir" >&5 + ac_aux_dir_found=yes + ac_install_sh= + for ac_aux in $ac_aux_files + do + # As a special case, if "install-sh" is required, that requirement + # can be satisfied by any of "install-sh", "install.sh", or "shtool", + # and $ac_install_sh is set appropriately for whichever one is found. + if test x"$ac_aux" = x"install-sh" + then + if test -f "${as_dir}install-sh"; then + printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install-sh found" >&5 + ac_install_sh="${as_dir}install-sh -c" + elif test -f "${as_dir}install.sh"; then + printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install.sh found" >&5 + ac_install_sh="${as_dir}install.sh -c" + elif test -f "${as_dir}shtool"; then + printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}shtool found" >&5 + ac_install_sh="${as_dir}shtool install -c" + else + ac_aux_dir_found=no + if $ac_first_candidate; then + ac_missing_aux_files="${ac_missing_aux_files} install-sh" + else + break + fi + fi + else + if test -f "${as_dir}${ac_aux}"; then + printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}${ac_aux} found" >&5 + else + ac_aux_dir_found=no + if $ac_first_candidate; then + ac_missing_aux_files="${ac_missing_aux_files} ${ac_aux}" + else + break + fi + fi + fi + done + if test "$ac_aux_dir_found" = yes; then + ac_aux_dir="$as_dir" + break + fi + ac_first_candidate=false + + as_found=false +done +IFS=$as_save_IFS +if $as_found +then : + +else $as_nop + as_fn_error $? "cannot find required auxiliary files:$ac_missing_aux_files" "$LINENO" 5 +fi + + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +if test -f "${ac_aux_dir}config.guess"; then + ac_config_guess="$SHELL ${ac_aux_dir}config.guess" +fi +if test -f "${ac_aux_dir}config.sub"; then + ac_config_sub="$SHELL ${ac_aux_dir}config.sub" +fi +if test -f "$ac_aux_dir/configure"; then + ac_configure="$SHELL ${ac_aux_dir}configure" +fi + # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false @@ -2712,12 +3438,12 @@ for ac_var in $ac_precious_vars; do eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +printf "%s\n" "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +printf "%s\n" "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) @@ -2726,24 +3452,24 @@ $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 -$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +printf "%s\n" "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else - { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 -$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +printf "%s\n" "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi - { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 -$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 -$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +printf "%s\n" "$as_me: former value: \`$ac_old_val'" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +printf "%s\n" "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in - *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *\'*) ac_arg=$ac_var=`printf "%s\n" "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in @@ -2753,11 +3479,12 @@ $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi done if $ac_cache_corrupted; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 -$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} - as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`${MAKE-make} distclean' and/or \`rm $cache_file' + and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## @@ -2770,58 +3497,30 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $ ac_compiler_gnu=$ac_cv_c_compiler_gnu + ac_config_headers="$ac_config_headers include/SDL_config.h" -ac_aux_dir= -for ac_dir in build-scripts "$srcdir"/build-scripts; do - if test -f "$ac_dir/install-sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f "$ac_dir/install.sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - elif test -f "$ac_dir/shtool"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/shtool install -c" - break - fi -done -if test -z "$ac_aux_dir"; then - as_fn_error $? "cannot find install-sh, install.sh, or shtool in build-scripts \"$srcdir\"/build-scripts" "$LINENO" 5 -fi - -# These three variables are undocumented and unsupported, -# and are intended to be withdrawn in a future Autoconf release. -# They can cause serious problems if a builder's source tree is in a directory -# whose full name contains unusual characters. -ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. -ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. -ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. - orig_CFLAGS="$CFLAGS" -# -# Making releases: -# Edit include/SDL_version.h and change the version, then: -# SDL_MICRO_VERSION += 1; -# SDL_INTERFACE_AGE += 1; -# SDL_BINARY_AGE += 1; -# if any functions have been added, set SDL_INTERFACE_AGE to 0. -# if backwards compatibility has been broken, -# set SDL_BINARY_AGE and SDL_INTERFACE_AGE to 0. -# +# See docs/release_checklist.md SDL_MAJOR_VERSION=2 -SDL_MINOR_VERSION=0 -SDL_MICRO_VERSION=12 -SDL_INTERFACE_AGE=0 -SDL_BINARY_AGE=12 +SDL_MINOR_VERSION=30 +SDL_MICRO_VERSION=5 SDL_VERSION=$SDL_MAJOR_VERSION.$SDL_MINOR_VERSION.$SDL_MICRO_VERSION +SDL_BINARY_AGE=`expr $SDL_MINOR_VERSION \* 100 + $SDL_MICRO_VERSION` +case "$SDL_MINOR_VERSION" in #( + *[02468]) : + SDL_INTERFACE_AGE="$SDL_MICRO_VERSION" ;; #( + *) : + SDL_INTERFACE_AGE=0 ;; #( + *) : + ;; +esac + @@ -2830,16 +3529,18 @@ SDL_VERSION=$SDL_MAJOR_VERSION.$SDL_MINOR_VERSION.$SDL_MICRO_VERSION # libtool versioning + + case `pwd` in *\ * | *\ *) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 -$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 +printf "%s\n" "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; esac -macro_version='2.4.2' -macro_revision='1.3337' +macro_version='2.4.6' +macro_revision='2.4.6' @@ -2853,28 +3554,32 @@ macro_revision='1.3337' -ltmain="$ac_aux_dir/ltmain.sh" -# Make sure we can run config.sub. -$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || - as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 +ltmain=$ac_aux_dir/ltmain.sh -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 -$as_echo_n "checking build system type... " >&6; } -if ${ac_cv_build+:} false; then : - $as_echo_n "(cached) " >&6 -else + + + # Make sure we can run config.sub. +$SHELL "${ac_aux_dir}config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL ${ac_aux_dir}config.sub" "$LINENO" 5 + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +printf %s "checking build system type... " >&6; } +if test ${ac_cv_build+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_build_alias=$build_alias test "x$ac_build_alias" = x && - ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` + ac_build_alias=`$SHELL "${ac_aux_dir}config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 -ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || - as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 +ac_cv_build=`$SHELL "${ac_aux_dir}config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $ac_build_alias failed" "$LINENO" 5 fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 -$as_echo "$ac_cv_build" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +printf "%s\n" "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; @@ -2893,21 +3598,22 @@ IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 -$as_echo_n "checking host system type... " >&6; } -if ${ac_cv_host+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +printf %s "checking host system type... " >&6; } +if test ${ac_cv_host+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else - ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || - as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 + ac_cv_host=`$SHELL "${ac_aux_dir}config.sub" $host_alias` || + as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $host_alias failed" "$LINENO" 5 fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 -$as_echo "$ac_cv_host" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +printf "%s\n" "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; @@ -2947,8 +3653,8 @@ ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 -$as_echo_n "checking how to print strings... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 +printf %s "checking how to print strings... " >&6; } # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then @@ -2973,13 +3679,13 @@ func_echo_all () $ECHO "" } -case "$ECHO" in - printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 -$as_echo "printf" >&6; } ;; - print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 -$as_echo "print -r" >&6; } ;; - *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 -$as_echo "cat" >&6; } ;; +case $ECHO in + printf*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: printf" >&5 +printf "%s\n" "printf" >&6; } ;; + print*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 +printf "%s\n" "print -r" >&6; } ;; + *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: cat" >&5 +printf "%s\n" "cat" >&6; } ;; esac @@ -2992,6 +3698,15 @@ esac + + + + + + + + + @@ -3003,11 +3718,12 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else @@ -3015,11 +3731,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -3030,11 +3750,11 @@ fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -3043,11 +3763,12 @@ if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else @@ -3055,11 +3776,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -3070,11 +3795,11 @@ fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +printf "%s\n" "$ac_ct_CC" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi if test "x$ac_ct_CC" = x; then @@ -3082,8 +3807,8 @@ fi else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC @@ -3096,11 +3821,12 @@ if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else @@ -3108,11 +3834,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -3123,11 +3853,11 @@ fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -3136,11 +3866,12 @@ fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else @@ -3149,15 +3880,19 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + if test "$as_dir$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -3173,18 +3908,18 @@ if test $ac_prog_rejected = yes; then # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift - ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + ac_cv_prog_CC="$as_dir$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -3195,11 +3930,12 @@ if test -z "$CC"; then do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else @@ -3207,11 +3943,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -3222,11 +3962,11 @@ fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -3239,11 +3979,12 @@ if test -z "$CC"; then do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else @@ -3251,11 +3992,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -3266,11 +4011,11 @@ fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +printf "%s\n" "$ac_ct_CC" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -3282,8 +4027,8 @@ done else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC @@ -3291,25 +4036,129 @@ esac fi fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args. +set dummy ${ac_tool_prefix}clang; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}clang" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi -test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "clang", so it can be a program name with args. +set dummy clang; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="clang" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +printf "%s\n" "$ac_ct_CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +fi + + +test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. -$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 -for ac_option in --version -v -V -qversion; do +for ac_option in --version -v -V -qversion -version; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 +printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then @@ -3319,7 +4168,7 @@ $as_echo "$ac_try_echo"; } >&5 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done @@ -3327,7 +4176,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { ; @@ -3339,9 +4188,9 @@ ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 -$as_echo_n "checking whether the C compiler works... " >&6; } -ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +printf %s "checking whether the C compiler works... " >&6; } +ac_link_default=`printf "%s\n" "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" @@ -3362,11 +4211,12 @@ case "(($ac_try" in *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 +printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, @@ -3383,7 +4233,7 @@ do # certainly right. break;; *.* ) - if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + if test ${ac_cv_exeext+y} && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi @@ -3399,44 +4249,46 @@ do done test "$ac_cv_exeext" = no && ac_cv_exeext= -else +else $as_nop ac_file='' fi -if test -z "$ac_file"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -$as_echo "$as_me: failed program was:" >&5 +if test -z "$ac_file" +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 -$as_echo_n "checking for C compiler default output file name... " >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 -$as_echo "$ac_file" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +printf %s "checking for C compiler default output file name... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +printf "%s\n" "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 -$as_echo_n "checking for suffix of executables... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +printf %s "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 +printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with @@ -3450,15 +4302,15 @@ for ac_file in conftest.exe conftest conftest.*; do * ) break;; esac done -else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +else $as_nop + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 -$as_echo "$ac_cv_exeext" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +printf "%s\n" "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext @@ -3467,7 +4319,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int -main () +main (void) { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; @@ -3479,8 +4331,8 @@ _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 -$as_echo_n "checking whether we are cross compiling... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +printf %s "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in @@ -3488,10 +4340,10 @@ case "(($ac_try" in *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 +printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in @@ -3499,39 +4351,40 @@ $as_echo "$ac_try_echo"; } >&5 *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 +printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot run C compiled programs. + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 -$as_echo "$cross_compiling" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +printf "%s\n" "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 -$as_echo_n "checking for suffix of object files... " >&6; } -if ${ac_cv_objext+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +printf %s "checking for suffix of object files... " >&6; } +if test ${ac_cv_objext+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { ; @@ -3545,11 +4398,12 @@ case "(($ac_try" in *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 +printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in @@ -3558,31 +4412,32 @@ $as_echo "$ac_try_echo"; } >&5 break;; esac done -else - $as_echo "$as_me: failed program was:" >&5 +else $as_nop + printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 -$as_echo "$ac_cv_objext" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +printf "%s\n" "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 -$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } -if ${ac_cv_c_compiler_gnu+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5 +printf %s "checking whether the compiler supports GNU C... " >&6; } +if test ${ac_cv_c_compiler_gnu+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { #ifndef __GNUC__ choke me @@ -3592,29 +4447,33 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_compiler_gnu=yes -else +else $as_nop ac_compiler_gnu=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 -$as_echo "$ac_cv_c_compiler_gnu" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; } +ac_compiler_gnu=$ac_cv_c_compiler_gnu + if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi -ac_test_CFLAGS=${CFLAGS+set} +ac_test_CFLAGS=${CFLAGS+y} ac_save_CFLAGS=$CFLAGS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 -$as_echo_n "checking whether $CC accepts -g... " >&6; } -if ${ac_cv_prog_cc_g+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +printf %s "checking whether $CC accepts -g... " >&6; } +if test ${ac_cv_prog_cc_g+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no @@ -3623,57 +4482,60 @@ else /* end confdefs.h. */ int -main () +main (void) { ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_cv_prog_cc_g=yes -else +else $as_nop CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : -else +else $as_nop ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_cv_prog_cc_g=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 -$as_echo "$ac_cv_prog_cc_g" >&6; } -if test "$ac_test_CFLAGS" = set; then +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +printf "%s\n" "$ac_cv_prog_cc_g" >&6; } +if test $ac_test_CFLAGS; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then @@ -3688,94 +4550,144 @@ else CFLAGS= fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 -$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } -if ${ac_cv_prog_cc_c89+:} false; then : - $as_echo_n "(cached) " >&6 -else +ac_prog_cc_stdc=no +if test x$ac_prog_cc_stdc = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5 +printf %s "checking for $CC option to enable C11 features... " >&6; } +if test ${ac_cv_prog_cc_c11+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_prog_cc_c11=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_c_conftest_c11_program +_ACEOF +for ac_arg in '' -std=gnu11 +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_prog_cc_c11=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam + test "x$ac_cv_prog_cc_c11" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC +fi + +if test "x$ac_cv_prog_cc_c11" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else $as_nop + if test "x$ac_cv_prog_cc_c11" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5 +printf "%s\n" "$ac_cv_prog_cc_c11" >&6; } + CC="$CC $ac_cv_prog_cc_c11" +fi + ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11 + ac_prog_cc_stdc=c11 +fi +fi +if test x$ac_prog_cc_stdc = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5 +printf %s "checking for $CC option to enable C99 features... " >&6; } +if test ${ac_cv_prog_cc_c99+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_prog_cc_c99=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_c_conftest_c99_program +_ACEOF +for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99= +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_prog_cc_c99=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam + test "x$ac_cv_prog_cc_c99" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC +fi + +if test "x$ac_cv_prog_cc_c99" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else $as_nop + if test "x$ac_cv_prog_cc_c99" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 +printf "%s\n" "$ac_cv_prog_cc_c99" >&6; } + CC="$CC $ac_cv_prog_cc_c99" +fi + ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99 + ac_prog_cc_stdc=c99 +fi +fi +if test x$ac_prog_cc_stdc = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5 +printf %s "checking for $CC option to enable C89 features... " >&6; } +if test ${ac_cv_prog_cc_c89+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include -#include -struct stat; -/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ -struct buf { int x; }; -FILE * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; -{ - return p[i]; -} -static char *f (char * (*g) (char **, int), char **p, ...) -{ - char *s; - va_list v; - va_start (v,p); - s = g (p, va_arg (v,int)); - va_end (v); - return s; -} - -/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has - function prototypes and stuff, but not '\xHH' hex character constants. - These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std is added to get - proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an - array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std. */ -int osf4_cc_array ['\x00' == 0 ? 1 : -1]; - -/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters - inside strings and character constants. */ -#define FOO(x) 'x' -int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; - -int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);}; -int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); -int argc; -char **argv; -int -main () -{ -return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; - ; - return 0; -} +$ac_c_conftest_c89_program _ACEOF -for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ - -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" - if ac_fn_c_try_compile "$LINENO"; then : + if ac_fn_c_try_compile "$LINENO" +then : ac_cv_prog_cc_c89=$ac_arg fi -rm -f core conftest.err conftest.$ac_objext +rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC - fi -# AC_CACHE_VAL -case "x$ac_cv_prog_cc_c89" in - x) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 -$as_echo "none needed" >&6; } ;; - xno) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 -$as_echo "unsupported" >&6; } ;; - *) - CC="$CC $ac_cv_prog_cc_c89" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 -$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; -esac -if test "x$ac_cv_prog_cc_c89" != xno; then : +if test "x$ac_cv_prog_cc_c89" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else $as_nop + if test "x$ac_cv_prog_cc_c89" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +printf "%s\n" "$ac_cv_prog_cc_c89" >&6; } + CC="$CC $ac_cv_prog_cc_c89" +fi + ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89 + ac_prog_cc_stdc=c89 +fi fi ac_ext=c @@ -3784,11 +4696,12 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 -$as_echo_n "checking for a sed that does not truncate output... " >&6; } -if ${ac_cv_path_SED+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +printf %s "checking for a sed that does not truncate output... " >&6; } +if test ${ac_cv_path_SED+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" @@ -3802,10 +4715,15 @@ else for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in sed gsed; do + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_prog in sed gsed + do for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + ac_path_SED="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_SED" || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED @@ -3814,13 +4732,13 @@ case `"$ac_path_SED" --version 2>&1` in ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; *) ac_count=0 - $as_echo_n 0123456789 >"conftest.in" + printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" - $as_echo '' >> "conftest.nl" + printf "%s\n" '' >> "conftest.nl" "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val @@ -3848,8 +4766,8 @@ else fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 -$as_echo "$ac_cv_path_SED" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +printf "%s\n" "$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed @@ -3866,11 +4784,12 @@ Xsed="$SED -e 1s/^X//" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 -$as_echo_n "checking for grep that handles long lines and -e... " >&6; } -if ${ac_cv_path_GREP+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +printf %s "checking for grep that handles long lines and -e... " >&6; } +if test ${ac_cv_path_GREP+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST @@ -3878,10 +4797,15 @@ else for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in grep ggrep; do + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_prog in grep ggrep + do for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + ac_path_GREP="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP @@ -3890,13 +4814,13 @@ case `"$ac_path_GREP" --version 2>&1` in ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 - $as_echo_n 0123456789 >"conftest.in" + printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" - $as_echo 'GREP' >> "conftest.nl" + printf "%s\n" 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val @@ -3924,16 +4848,17 @@ else fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 -$as_echo "$ac_cv_path_GREP" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +printf "%s\n" "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 -$as_echo_n "checking for egrep... " >&6; } -if ${ac_cv_path_EGREP+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +printf %s "checking for egrep... " >&6; } +if test ${ac_cv_path_EGREP+y} +then : + printf %s "(cached) " >&6 +else $as_nop if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else @@ -3944,10 +4869,15 @@ else for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in egrep; do + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_prog in egrep + do for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + ac_path_EGREP="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP @@ -3956,13 +4886,13 @@ case `"$ac_path_EGREP" --version 2>&1` in ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 - $as_echo_n 0123456789 >"conftest.in" + printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" - $as_echo 'EGREP' >> "conftest.nl" + printf "%s\n" 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val @@ -3991,16 +4921,17 @@ fi fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 -$as_echo "$ac_cv_path_EGREP" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +printf "%s\n" "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 -$as_echo_n "checking for fgrep... " >&6; } -if ${ac_cv_path_FGREP+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 +printf %s "checking for fgrep... " >&6; } +if test ${ac_cv_path_FGREP+y} +then : + printf %s "(cached) " >&6 +else $as_nop if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 then ac_cv_path_FGREP="$GREP -F" else @@ -4011,10 +4942,15 @@ else for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in fgrep; do + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_prog in fgrep + do for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" + ac_path_FGREP="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_FGREP" || continue # Check for GNU ac_path_FGREP and select it if it is found. # Check for GNU $ac_path_FGREP @@ -4023,13 +4959,13 @@ case `"$ac_path_FGREP" --version 2>&1` in ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; *) ac_count=0 - $as_echo_n 0123456789 >"conftest.in" + printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" - $as_echo 'FGREP' >> "conftest.nl" + printf "%s\n" 'FGREP' >> "conftest.nl" "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val @@ -4058,8 +4994,8 @@ fi fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 -$as_echo "$ac_cv_path_FGREP" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 +printf "%s\n" "$ac_cv_path_FGREP" >&6; } FGREP="$ac_cv_path_FGREP" @@ -4084,20 +5020,21 @@ test -z "$GREP" && GREP=grep # Check whether --with-gnu-ld was given. -if test "${with_gnu_ld+set}" = set; then : - withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes -else +if test ${with_gnu_ld+y} +then : + withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes +else $as_nop with_gnu_ld=no fi ac_prog=ld -if test "$GCC" = yes; then +if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 -$as_echo_n "checking for ld used by $CC... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +printf %s "checking for ld used by $CC... " >&6; } case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw + *-*-mingw* | *-*-windows*) + # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; @@ -4111,7 +5048,7 @@ $as_echo_n "checking for ld used by $CC... " >&6; } while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done - test -z "$LD" && LD="$ac_prog" + test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. @@ -4122,56 +5059,58 @@ $as_echo_n "checking for ld used by $CC... " >&6; } with_gnu_ld=unknown ;; esac -elif test "$with_gnu_ld" = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 -$as_echo_n "checking for GNU ld... " >&6; } +elif test yes = "$with_gnu_ld"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +printf %s "checking for GNU ld... " >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 -$as_echo_n "checking for non-GNU ld... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +printf %s "checking for non-GNU ld... " >&6; } fi -if ${lt_cv_path_LD+:} false; then : - $as_echo_n "(cached) " >&6 -else +if test ${lt_cv_path_LD+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -z "$LD"; then - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - lt_cv_path_LD="$ac_dir/$ac_prog" + lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 -$as_echo "$LD" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 +printf "%s\n" "$LD" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 -$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } -if ${lt_cv_prog_gnu_ld+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +printf %s "checking if the linker ($LD) is GNU ld... " >&6; } +if test ${lt_cv_prog_gnu_ld+y} +then : + printf %s "(cached) " >&6 +else $as_nop # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &1 &5 -$as_echo "$lt_cv_prog_gnu_ld" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5 +printf "%s\n" "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld @@ -4194,40 +5133,46 @@ with_gnu_ld=$lt_cv_prog_gnu_ld -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 -$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } -if ${lt_cv_path_NM+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 +printf %s "checking for BSD- or MS-compatible name lister (nm)... " >&6; } +if test ${lt_cv_path_NM+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$NM"; then # Let the user override the test. - lt_cv_path_NM="$NM" + lt_cv_path_NM=$NM else - lt_nm_to_check="${ac_tool_prefix}nm" + lt_nm_to_check=${ac_tool_prefix}nm if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. - tmp_nm="$ac_dir/$lt_tmp_nm" - if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + tmp_nm=$ac_dir/$lt_tmp_nm + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then # Check to see if the nm accepts a BSD-compat flag. - # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # Adding the 'sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file - case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in - */dev/null* | *'Invalid file or object type'*) + # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty + case $build_os in + mingw* | windows*) lt_bad_file=conftest.nm/nofile ;; + *) lt_bad_file=/dev/null ;; + esac + case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in + *$lt_bad_file* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" - break + break 2 ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" - break + break 2 ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but @@ -4238,15 +5183,15 @@ else esac fi done - IFS="$lt_save_ifs" + IFS=$lt_save_ifs done : ${lt_cv_path_NM=no} fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 -$as_echo "$lt_cv_path_NM" >&6; } -if test "$lt_cv_path_NM" != "no"; then - NM="$lt_cv_path_NM" +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 +printf "%s\n" "$lt_cv_path_NM" >&6; } +if test no != "$lt_cv_path_NM"; then + NM=$lt_cv_path_NM else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : @@ -4257,11 +5202,12 @@ else do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_DUMPBIN+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_DUMPBIN+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$DUMPBIN"; then ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. else @@ -4269,11 +5215,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -4284,11 +5234,11 @@ fi fi DUMPBIN=$ac_cv_prog_DUMPBIN if test -n "$DUMPBIN"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 -$as_echo "$DUMPBIN" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 +printf "%s\n" "$DUMPBIN" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -4301,11 +5251,12 @@ if test -z "$DUMPBIN"; then do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_DUMPBIN+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$ac_ct_DUMPBIN"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. else @@ -4313,11 +5264,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -4328,11 +5283,11 @@ fi fi ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN if test -n "$ac_ct_DUMPBIN"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 -$as_echo "$ac_ct_DUMPBIN" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 +printf "%s\n" "$ac_ct_DUMPBIN" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -4344,17 +5299,17 @@ done else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DUMPBIN=$ac_ct_DUMPBIN fi fi - case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in + case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in *COFF*) - DUMPBIN="$DUMPBIN -symbols" + DUMPBIN="$DUMPBIN -symbols -headers" ;; *) DUMPBIN=: @@ -4362,8 +5317,8 @@ fi esac fi - if test "$DUMPBIN" != ":"; then - NM="$DUMPBIN" + if test : != "$DUMPBIN"; then + NM=$DUMPBIN fi fi test -z "$NM" && NM=nm @@ -4373,11 +5328,12 @@ test -z "$NM" && NM=nm -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 -$as_echo_n "checking the name lister ($NM) interface... " >&6; } -if ${lt_cv_nm_interface+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 +printf %s "checking the name lister ($NM) interface... " >&6; } +if test ${lt_cv_nm_interface+y} +then : + printf %s "(cached) " >&6 +else $as_nop lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) @@ -4393,28 +5349,29 @@ else fi rm -f conftest* fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 -$as_echo "$lt_cv_nm_interface" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 +printf "%s\n" "$lt_cv_nm_interface" >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 -$as_echo_n "checking whether ln -s works... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +printf %s "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 -$as_echo "no, using $LN_S" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +printf "%s\n" "no, using $LN_S" >&6; } fi # find the maximum length of command line arguments -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 -$as_echo_n "checking the maximum length of command line arguments... " >&6; } -if ${lt_cv_sys_max_cmd_len+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 +printf %s "checking the maximum length of command line arguments... " >&6; } +if test ${lt_cv_sys_max_cmd_len+y} +then : + printf %s "(cached) " >&6 +else $as_nop i=0 - teststring="ABCD" + teststring=ABCD case $build_os in msdosdjgpp*) @@ -4432,7 +5389,7 @@ else lt_cv_sys_max_cmd_len=-1; ;; - cygwin* | mingw* | cegcc*) + cygwin* | mingw* | windows* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, @@ -4454,7 +5411,7 @@ else lt_cv_sys_max_cmd_len=8192; ;; - netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + bitrig* | darwin* | dragonfly* | freebsd* | midnightbsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` @@ -4504,22 +5461,23 @@ else ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` - if test -n "$lt_cv_sys_max_cmd_len"; then + if test -n "$lt_cv_sys_max_cmd_len" && \ + test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. - for i in 1 2 3 4 5 6 7 8 ; do + for i in 1 2 3 4 5 6 7 8; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. - while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ + while { test X`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && - test $i != 17 # 1/2 MB should be enough + test 17 != "$i" # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring @@ -4537,12 +5495,12 @@ else fi -if test -n $lt_cv_sys_max_cmd_len ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 -$as_echo "$lt_cv_sys_max_cmd_len" >&6; } +if test -n "$lt_cv_sys_max_cmd_len"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 +printf "%s\n" "$lt_cv_sys_max_cmd_len" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 -$as_echo "none" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5 +printf "%s\n" "none" >&6; } fi max_cmd_len=$lt_cv_sys_max_cmd_len @@ -4555,30 +5513,6 @@ max_cmd_len=$lt_cv_sys_max_cmd_len : ${MV="mv -f"} : ${RM="rm -f"} -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 -$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } -# Try some XSI features -xsi_shell=no -( _lt_dummy="a/b/c" - test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ - = c,a/b,b/c, \ - && eval 'test $(( 1 + 1 )) -eq 2 \ - && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ - && xsi_shell=yes -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 -$as_echo "$xsi_shell" >&6; } - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 -$as_echo_n "checking whether the shell understands \"+=\"... " >&6; } -lt_shell_append=no -( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ - >/dev/null 2>&1 \ - && lt_shell_append=yes -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 -$as_echo "$lt_shell_append" >&6; } - - if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else @@ -4610,15 +5544,16 @@ esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 -$as_echo_n "checking how to convert $build file names to $host format... " >&6; } -if ${lt_cv_to_host_file_cmd+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 +printf %s "checking how to convert $build file names to $host format... " >&6; } +if test ${lt_cv_to_host_file_cmd+y} +then : + printf %s "(cached) " >&6 +else $as_nop case $host in *-*-mingw* ) case $build in - *-*-mingw* ) # actually msys + *-*-mingw* | *-*-windows* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) @@ -4631,7 +5566,7 @@ else ;; *-*-cygwin* ) case $build in - *-*-mingw* ) # actually msys + *-*-mingw* | *-*-windows* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) @@ -4650,24 +5585,25 @@ esac fi to_host_file_cmd=$lt_cv_to_host_file_cmd -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 -$as_echo "$lt_cv_to_host_file_cmd" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 +printf "%s\n" "$lt_cv_to_host_file_cmd" >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 -$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } -if ${lt_cv_to_tool_file_cmd+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 +printf %s "checking how to convert $build file names to toolchain format... " >&6; } +if test ${lt_cv_to_tool_file_cmd+y} +then : + printf %s "(cached) " >&6 +else $as_nop #assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in - *-*-mingw* ) + *-*-mingw* | *-*-windows* ) case $build in - *-*-mingw* ) # actually msys + *-*-mingw* | *-*-windows* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac @@ -4677,22 +5613,23 @@ esac fi to_tool_file_cmd=$lt_cv_to_tool_file_cmd -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 -$as_echo "$lt_cv_to_tool_file_cmd" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 +printf "%s\n" "$lt_cv_to_tool_file_cmd" >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 -$as_echo_n "checking for $LD option to reload object files... " >&6; } -if ${lt_cv_ld_reload_flag+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 +printf %s "checking for $LD option to reload object files... " >&6; } +if test ${lt_cv_ld_reload_flag+y} +then : + printf %s "(cached) " >&6 +else $as_nop lt_cv_ld_reload_flag='-r' fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 -$as_echo "$lt_cv_ld_reload_flag" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 +printf "%s\n" "$lt_cv_ld_reload_flag" >&6; } reload_flag=$lt_cv_ld_reload_flag case $reload_flag in "" | " "*) ;; @@ -4700,14 +5637,14 @@ case $reload_flag in esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in - cygwin* | mingw* | pw32* | cegcc*) - if test "$GCC" != yes; then + cygwin* | mingw* | windows* | pw32* | cegcc*) + if test yes != "$GCC"; then reload_cmds=false fi ;; darwin*) - if test "$GCC" = yes; then - reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' + if test yes = "$GCC"; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs' else reload_cmds='$LD$reload_flag -o $output$reload_objs' fi @@ -4725,11 +5662,12 @@ esac if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_OBJDUMP+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_OBJDUMP+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else @@ -4737,11 +5675,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -4752,11 +5694,11 @@ fi fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 -$as_echo "$OBJDUMP" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +printf "%s\n" "$OBJDUMP" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -4765,11 +5707,12 @@ if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_OBJDUMP+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else @@ -4777,11 +5720,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OBJDUMP="objdump" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -4792,11 +5739,11 @@ fi fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 -$as_echo "$ac_ct_OBJDUMP" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +printf "%s\n" "$ac_ct_OBJDUMP" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then @@ -4804,8 +5751,8 @@ fi else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP @@ -4821,24 +5768,25 @@ test -z "$OBJDUMP" && OBJDUMP=objdump -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 -$as_echo_n "checking how to recognize dependent libraries... " >&6; } -if ${lt_cv_deplibs_check_method+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 +printf %s "checking how to recognize dependent libraries... " >&6; } +if test ${lt_cv_deplibs_check_method+y} +then : + printf %s "(cached) " >&6 +else $as_nop lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. -# `unknown' -- same as none, but documents that we really don't know. +# 'unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path -# which responds to the $file_magic_cmd with a given extended regex. -# If you have `file' or equivalent on your system and you're not sure -# whether `pass_all' will *always* work, you probably want this one. +# that responds to the $file_magic_cmd with a given extended regex. +# If you have 'file' or equivalent on your system and you're not sure +# whether 'pass_all' will *always* work, you probably want this one. case $host_os in aix[4-9]*) @@ -4859,15 +5807,14 @@ cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' - lt_cv_deplibs_check_method=pass_all + lt_cv_deplibs_check_method=pass_all # SDL customization ;; -mingw* | pw32*) +mingw* | windows* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. - # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. - if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then + if ( file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else @@ -4875,7 +5822,7 @@ mingw* | pw32*) lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi - lt_cv_deplibs_check_method=pass_all + lt_cv_deplibs_check_method=pass_all # SDL customization ;; cegcc*) @@ -4888,7 +5835,7 @@ darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; -freebsd* | dragonfly*) +freebsd* | dragonfly* | midnightbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) @@ -4904,10 +5851,6 @@ freebsd* | dragonfly*) fi ;; -gnu*) - lt_cv_deplibs_check_method=pass_all - ;; - haiku*) lt_cv_deplibs_check_method=pass_all ;; @@ -4946,7 +5889,7 @@ irix5* | irix6* | nonstopux*) ;; # This must be glibc/ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu) +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; @@ -4968,8 +5911,8 @@ newos6*) lt_cv_deplibs_check_method=pass_all ;; -openbsd*) - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then +openbsd* | bitrig*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' @@ -5022,17 +5965,20 @@ sysv4 | sysv4.3*) tpf*) lt_cv_deplibs_check_method=pass_all ;; +os2*) + lt_cv_deplibs_check_method=pass_all + ;; esac fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 -$as_echo "$lt_cv_deplibs_check_method" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 +printf "%s\n" "$lt_cv_deplibs_check_method" >&6; } file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in - mingw* | pw32*) + mingw* | windows* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else @@ -5070,11 +6016,12 @@ test -z "$deplibs_check_method" && deplibs_check_method=unknown if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. set dummy ${ac_tool_prefix}dlltool; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_DLLTOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_DLLTOOL+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else @@ -5082,11 +6029,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -5097,11 +6048,11 @@ fi fi DLLTOOL=$ac_cv_prog_DLLTOOL if test -n "$DLLTOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 -$as_echo "$DLLTOOL" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 +printf "%s\n" "$DLLTOOL" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -5110,11 +6061,12 @@ if test -z "$ac_cv_prog_DLLTOOL"; then ac_ct_DLLTOOL=$DLLTOOL # Extract the first word of "dlltool", so it can be a program name with args. set dummy dlltool; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_DLLTOOL+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$ac_ct_DLLTOOL"; then ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. else @@ -5122,11 +6074,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -5137,11 +6093,11 @@ fi fi ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL if test -n "$ac_ct_DLLTOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 -$as_echo "$ac_ct_DLLTOOL" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 +printf "%s\n" "$ac_ct_DLLTOOL" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi if test "x$ac_ct_DLLTOOL" = x; then @@ -5149,8 +6105,8 @@ fi else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DLLTOOL=$ac_ct_DLLTOOL @@ -5167,17 +6123,18 @@ test -z "$DLLTOOL" && DLLTOOL=dlltool -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 -$as_echo_n "checking how to associate runtime and link libraries... " >&6; } -if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 +printf %s "checking how to associate runtime and link libraries... " >&6; } +if test ${lt_cv_sharedlib_from_linklib_cmd+y} +then : + printf %s "(cached) " >&6 +else $as_nop lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in -cygwin* | mingw* | pw32* | cegcc*) - # two different shell functions defined in ltmain.sh - # decide which to use based on capabilities of $DLLTOOL +cygwin* | mingw* | windows* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh; + # decide which one to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib @@ -5189,13 +6146,13 @@ cygwin* | mingw* | pw32* | cegcc*) ;; *) # fallback: assume linklib IS sharedlib - lt_cv_sharedlib_from_linklib_cmd="$ECHO" + lt_cv_sharedlib_from_linklib_cmd=$ECHO ;; esac fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 -$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 +printf "%s\n" "$lt_cv_sharedlib_from_linklib_cmd" >&6; } sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO @@ -5211,11 +6168,12 @@ if test -n "$ac_tool_prefix"; then do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_AR+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_AR+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else @@ -5223,11 +6181,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -5238,11 +6200,11 @@ fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 -$as_echo "$AR" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +printf "%s\n" "$AR" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -5255,11 +6217,12 @@ if test -z "$AR"; then do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_AR+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_AR+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else @@ -5267,11 +6230,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -5282,11 +6249,11 @@ fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 -$as_echo "$ac_ct_AR" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +printf "%s\n" "$ac_ct_AR" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -5298,8 +6265,8 @@ done else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR @@ -5319,53 +6286,55 @@ fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 -$as_echo_n "checking for archiver @FILE support... " >&6; } -if ${lt_cv_ar_at_file+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 +printf %s "checking for archiver @FILE support... " >&6; } +if test ${lt_cv_ar_at_file+y} +then : + printf %s "(cached) " >&6 +else $as_nop lt_cv_ar_at_file=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } - if test "$ac_status" -eq 0; then + if test 0 -eq "$ac_status"; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } - if test "$ac_status" -ne 0; then + if test 0 -ne "$ac_status"; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 -$as_echo "$lt_cv_ar_at_file" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 +printf "%s\n" "$lt_cv_ar_at_file" >&6; } -if test "x$lt_cv_ar_at_file" = xno; then +if test no = "$lt_cv_ar_at_file"; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file @@ -5380,11 +6349,12 @@ fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_STRIP+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else @@ -5392,11 +6362,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -5407,11 +6381,11 @@ fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 -$as_echo "$STRIP" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +printf "%s\n" "$STRIP" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -5420,11 +6394,12 @@ if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_STRIP+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else @@ -5432,11 +6407,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -5447,11 +6426,11 @@ fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 -$as_echo "$ac_ct_STRIP" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +printf "%s\n" "$ac_ct_STRIP" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then @@ -5459,8 +6438,8 @@ fi else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP @@ -5479,11 +6458,12 @@ test -z "$STRIP" && STRIP=: if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_RANLIB+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_RANLIB+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else @@ -5491,11 +6471,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -5506,11 +6490,11 @@ fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 -$as_echo "$RANLIB" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +printf "%s\n" "$RANLIB" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -5519,11 +6503,12 @@ if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_RANLIB+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else @@ -5531,11 +6516,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -5546,11 +6535,11 @@ fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 -$as_echo "$ac_ct_RANLIB" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +printf "%s\n" "$ac_ct_RANLIB" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then @@ -5558,8 +6547,8 @@ fi else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB @@ -5581,15 +6570,8 @@ old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then - case $host_os in - openbsd*) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" - ;; - *) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" - ;; - esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in @@ -5623,11 +6605,12 @@ for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_AWK+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_AWK+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else @@ -5635,11 +6618,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -5650,11 +6637,11 @@ fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 -$as_echo "$AWK" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +printf "%s\n" "$AWK" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -5690,11 +6677,12 @@ compiler=$CC # Check for command to grab the raw symbol name followed by C symbol from nm. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 -$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } -if ${lt_cv_sys_global_symbol_pipe+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 +printf %s "checking command to parse $NM output from $compiler object... " >&6; } +if test ${lt_cv_sys_global_symbol_pipe+y} +then : + printf %s "(cached) " >&6 +else $as_nop # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] @@ -5710,11 +6698,11 @@ case $host_os in aix*) symcode='[BCDT]' ;; -cygwin* | mingw* | pw32* | cegcc*) +cygwin* | mingw* | windows* | pw32* | cegcc*) symcode='[ABCDGISTW]' ;; hpux*) - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then symcode='[ABCDEGRST]' fi ;; @@ -5725,7 +6713,7 @@ osf*) symcode='[BCDEGQRST]' ;; solaris*) - symcode='[BDRT]' + symcode='[BCDRT]' ;; sco3.2v5*) symcode='[DT]' @@ -5747,19 +6735,49 @@ case `$NM -V 2>&1` in symcode='[ABCDGIRSTW]' ;; esac +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Gets list of data symbols to import. + lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" + # Adjust the below global symbol transforms to fixup imported variables. + lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" + lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" + lt_c_name_lib_hook="\ + -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ + -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" +else + # Disable hooks by default. + lt_cv_sys_global_symbol_to_import= + lt_cdecl_hook= + lt_c_name_hook= + lt_c_name_lib_hook= +fi + # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. -lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" +lt_cv_sys_global_symbol_to_cdecl="sed -n"\ +$lt_cdecl_hook\ +" -e 's/^T .* \(.*\)$/extern int \1();/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address -lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" +lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ +$lt_c_name_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" + +# Transform an extracted symbol line into symbol name with lib prefix and +# symbol address. +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ +$lt_c_name_lib_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in -mingw*) +mingw* | windows*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac @@ -5772,21 +6790,24 @@ for ac_symprfx in "" "_"; do # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then - # Fake it for dumpbin and say T for any non-static function - # and D for any global variable. - # Also find C++ and __fastcall symbols from MSVC++, + # Fake it for dumpbin and say T for any non-static function, + # D for any global variable and I for any imported variable. + # Also find C++ and __fastcall symbols from MSVC++ or ICC, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK '"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ +" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ +" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ -" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ -" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ -" s[1]~/^[@?]/{print s[1], s[1]; next};"\ -" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ +" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ +" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ +" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" @@ -5813,14 +6834,14 @@ _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Now try to grab the symbols. nlist=conftest.nm if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then @@ -5834,11 +6855,11 @@ _LT_EOF if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ -#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) -/* DATA imports from DLLs on WIN32 con't be const, because runtime +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST -#elif defined(__osf__) +#elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else @@ -5864,7 +6885,7 @@ lt__PROGRAM__LTX_preloaded_symbols[] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF - $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; @@ -5884,13 +6905,13 @@ _LT_EOF mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS - LIBS="conftstm.$ac_objext" + LIBS=conftstm.$ac_objext CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s conftest${ac_exeext}; then + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest$ac_exeext; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS @@ -5911,7 +6932,7 @@ _LT_EOF rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. - if test "$pipe_works" = yes; then + if test yes = "$pipe_works"; then break else lt_cv_sys_global_symbol_pipe= @@ -5924,11 +6945,11 @@ if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 -$as_echo "failed" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: failed" >&5 +printf "%s\n" "failed" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 -$as_echo "ok" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +printf "%s\n" "ok" >&6; } fi # Response file support. @@ -5964,21 +6985,32 @@ fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 -$as_echo_n "checking for sysroot... " >&6; } + + + + + + + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 +printf %s "checking for sysroot... " >&6; } # Check whether --with-sysroot was given. -if test "${with_sysroot+set}" = set; then : +if test ${with_sysroot+y} +then : withval=$with_sysroot; -else +else $as_nop with_sysroot=no fi lt_sysroot= -case ${with_sysroot} in #( +case $with_sysroot in #( yes) - if test "$GCC" = yes; then + if test yes = "$GCC"; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( @@ -5988,57 +7020,147 @@ case ${with_sysroot} in #( no|'') ;; #( *) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5 -$as_echo "${with_sysroot}" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5 +printf "%s\n" "$with_sysroot" >&6; } as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 ;; esac - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 -$as_echo "${lt_sysroot:-no}" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 +printf "%s\n" "${lt_sysroot:-no}" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5 +printf %s "checking for a working dd... " >&6; } +if test ${ac_cv_path_lt_DD+y} +then : + printf %s "(cached) " >&6 +else $as_nop + printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +: ${lt_DD:=$DD} +if test -z "$lt_DD"; then + ac_path_lt_DD_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_prog in dd + do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_lt_DD="$as_dir$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_lt_DD" || continue +if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: +fi + $ac_path_lt_DD_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_lt_DD"; then + : + fi +else + ac_cv_path_lt_DD=$lt_DD +fi + +rm -f conftest.i conftest2.i conftest.out +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5 +printf "%s\n" "$ac_cv_path_lt_DD" >&6; } + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5 +printf %s "checking how to truncate binary pipes... " >&6; } +if test ${lt_cv_truncate_bin+y} +then : + printf %s "(cached) " >&6 +else $as_nop + printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +lt_cv_truncate_bin= +if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" +fi +rm -f conftest.i conftest2.i conftest.out +test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q" +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5 +printf "%s\n" "$lt_cv_truncate_bin" >&6; } + + + + + + + +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +func_cc_basename () +{ + for cc_temp in $*""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac + done + func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +} + # Check whether --enable-libtool-lock was given. -if test "${enable_libtool_lock+set}" = set; then : +if test ${enable_libtool_lock+y} +then : enableval=$enable_libtool_lock; fi -test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes +test no = "$enable_libtool_lock" || enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) - # Find out which ABI we are using. + # Find out what ABI is being produced by ac_compile, and set mode + # options accordingly. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) - HPUX_IA64_MODE="32" + HPUX_IA64_MODE=32 ;; *ELF-64*) - HPUX_IA64_MODE="64" + HPUX_IA64_MODE=64 ;; esac fi rm -rf conftest* ;; *-*-irix6*) - # Find out which ABI we are using. + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - if test "$lt_cv_prog_gnu_ld" = yes; then + if test yes = "$lt_cv_prog_gnu_ld"; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" @@ -6067,14 +7189,55 @@ ia64-*-hpux*) rm -rf conftest* ;; -x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ -s390*-*linux*|s390*-*tpf*|sparc*-*linux*) - # Find out which ABI we are using. +mips64*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + emul=elf + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + emul="${emul}32" + ;; + *64-bit*) + emul="${emul}64" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *MSB*) + emul="${emul}btsmip" + ;; + *LSB*) + emul="${emul}ltsmip" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *N32*) + emul="${emul}n32" + ;; + esac + LD="${LD-ld} -m $emul" + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*|x86_64-gnu*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. Note that the listed cases only cover the + # situations where additional linker options are needed (such as when + # doing 32-bit compilation for a host where ld defaults to 64-bit, or + # vice versa); the common cases where no linker options are needed do + # not appear in the list. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *32-bit*) @@ -6082,10 +7245,20 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; - x86_64-*linux*) - LD="${LD-ld} -m elf_i386" + x86_64-*linux*|x86_64-gnu*) + case `/usr/bin/file conftest.o` in + *x86-64*) + LD="${LD-ld} -m elf32_x86_64" + ;; + *) + LD="${LD-ld} -m elf_i386" + ;; + esac ;; - ppc64-*linux*|powerpc64-*linux*) + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) @@ -6101,13 +7274,13 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; - x86_64-*linux*) + x86_64-*linux*|x86_64-gnu*) LD="${LD-ld} -m elf_x86_64" ;; - powerpc64le-*linux*) + powerpcle-*linux*|powerpc64le-*linux*) LD="${LD-ld} -m elf64lppc" ;; - powerpc64-*linux*) + powerpc-*linux*|powerpc64-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) @@ -6125,13 +7298,14 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. - SAVE_CFLAGS="$CFLAGS" + SAVE_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -belf" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 -$as_echo_n "checking whether the C compiler needs -belf... " >&6; } -if ${lt_cv_cc_needs_belf+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 +printf %s "checking whether the C compiler needs -belf... " >&6; } +if test ${lt_cv_cc_needs_belf+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -6142,19 +7316,20 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu /* end confdefs.h. */ int -main () +main (void) { ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : lt_cv_cc_needs_belf=yes -else +else $as_nop lt_cv_cc_needs_belf=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' @@ -6163,27 +7338,28 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $ ac_compiler_gnu=$ac_cv_c_compiler_gnu fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 -$as_echo "$lt_cv_cc_needs_belf" >&6; } - if test x"$lt_cv_cc_needs_belf" != x"yes"; then +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 +printf "%s\n" "$lt_cv_cc_needs_belf" >&6; } + if test yes != "$lt_cv_cc_needs_belf"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf - CFLAGS="$SAVE_CFLAGS" + CFLAGS=$SAVE_CFLAGS fi ;; *-*solaris*) - # Find out which ABI we are using. + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in - i?86-*-solaris*) + i?86-*-solaris*|x86_64-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) @@ -6192,7 +7368,7 @@ $as_echo "$lt_cv_cc_needs_belf" >&6; } esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then - LD="${LD-ld}_sol2" + LD=${LD-ld}_sol2 fi ;; *) @@ -6208,16 +7384,17 @@ $as_echo "$lt_cv_cc_needs_belf" >&6; } ;; esac -need_locks="$enable_libtool_lock" +need_locks=$enable_libtool_lock if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. set dummy ${ac_tool_prefix}mt; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_MANIFEST_TOOL+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$MANIFEST_TOOL"; then ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. else @@ -6225,11 +7402,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -6240,11 +7421,11 @@ fi fi MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL if test -n "$MANIFEST_TOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 -$as_echo "$MANIFEST_TOOL" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 +printf "%s\n" "$MANIFEST_TOOL" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -6253,11 +7434,12 @@ if test -z "$ac_cv_prog_MANIFEST_TOOL"; then ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL # Extract the first word of "mt", so it can be a program name with args. set dummy mt; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_MANIFEST_TOOL+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$ac_ct_MANIFEST_TOOL"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. else @@ -6265,11 +7447,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -6280,11 +7466,11 @@ fi fi ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL if test -n "$ac_ct_MANIFEST_TOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 -$as_echo "$ac_ct_MANIFEST_TOOL" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 +printf "%s\n" "$ac_ct_MANIFEST_TOOL" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi if test "x$ac_ct_MANIFEST_TOOL" = x; then @@ -6292,8 +7478,8 @@ fi else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL @@ -6303,11 +7489,12 @@ else fi test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 -$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } -if ${lt_cv_path_mainfest_tool+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 +printf %s "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } +if test ${lt_cv_path_mainfest_tool+y} +then : + printf %s "(cached) " >&6 +else $as_nop lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out @@ -6317,9 +7504,9 @@ else fi rm -f conftest* fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 -$as_echo "$lt_cv_path_mainfest_tool" >&6; } -if test "x$lt_cv_path_mainfest_tool" != xyes; then +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 +printf "%s\n" "$lt_cv_path_mainfest_tool" >&6; } +if test yes != "$lt_cv_path_mainfest_tool"; then MANIFEST_TOOL=: fi @@ -6333,11 +7520,12 @@ fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_DSYMUTIL+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_DSYMUTIL+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$DSYMUTIL"; then ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. else @@ -6345,11 +7533,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -6360,11 +7552,11 @@ fi fi DSYMUTIL=$ac_cv_prog_DSYMUTIL if test -n "$DSYMUTIL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 -$as_echo "$DSYMUTIL" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 +printf "%s\n" "$DSYMUTIL" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -6373,11 +7565,12 @@ if test -z "$ac_cv_prog_DSYMUTIL"; then ac_ct_DSYMUTIL=$DSYMUTIL # Extract the first word of "dsymutil", so it can be a program name with args. set dummy dsymutil; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_DSYMUTIL+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$ac_ct_DSYMUTIL"; then ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. else @@ -6385,11 +7578,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -6400,11 +7597,11 @@ fi fi ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL if test -n "$ac_ct_DSYMUTIL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 -$as_echo "$ac_ct_DSYMUTIL" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 +printf "%s\n" "$ac_ct_DSYMUTIL" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi if test "x$ac_ct_DSYMUTIL" = x; then @@ -6412,8 +7609,8 @@ fi else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DSYMUTIL=$ac_ct_DSYMUTIL @@ -6425,11 +7622,12 @@ fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. set dummy ${ac_tool_prefix}nmedit; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_NMEDIT+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_NMEDIT+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$NMEDIT"; then ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. else @@ -6437,11 +7635,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -6452,11 +7654,11 @@ fi fi NMEDIT=$ac_cv_prog_NMEDIT if test -n "$NMEDIT"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 -$as_echo "$NMEDIT" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 +printf "%s\n" "$NMEDIT" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -6465,11 +7667,12 @@ if test -z "$ac_cv_prog_NMEDIT"; then ac_ct_NMEDIT=$NMEDIT # Extract the first word of "nmedit", so it can be a program name with args. set dummy nmedit; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_NMEDIT+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$ac_ct_NMEDIT"; then ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. else @@ -6477,11 +7680,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_NMEDIT="nmedit" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -6492,11 +7699,11 @@ fi fi ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT if test -n "$ac_ct_NMEDIT"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 -$as_echo "$ac_ct_NMEDIT" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 +printf "%s\n" "$ac_ct_NMEDIT" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi if test "x$ac_ct_NMEDIT" = x; then @@ -6504,8 +7711,8 @@ fi else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac NMEDIT=$ac_ct_NMEDIT @@ -6517,11 +7724,12 @@ fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. set dummy ${ac_tool_prefix}lipo; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_LIPO+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_LIPO+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$LIPO"; then ac_cv_prog_LIPO="$LIPO" # Let the user override the test. else @@ -6529,11 +7737,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_LIPO="${ac_tool_prefix}lipo" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -6544,11 +7756,11 @@ fi fi LIPO=$ac_cv_prog_LIPO if test -n "$LIPO"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 -$as_echo "$LIPO" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 +printf "%s\n" "$LIPO" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -6557,11 +7769,12 @@ if test -z "$ac_cv_prog_LIPO"; then ac_ct_LIPO=$LIPO # Extract the first word of "lipo", so it can be a program name with args. set dummy lipo; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_LIPO+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_LIPO+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$ac_ct_LIPO"; then ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. else @@ -6569,11 +7782,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_LIPO="lipo" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -6584,11 +7801,11 @@ fi fi ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO if test -n "$ac_ct_LIPO"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 -$as_echo "$ac_ct_LIPO" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 +printf "%s\n" "$ac_ct_LIPO" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi if test "x$ac_ct_LIPO" = x; then @@ -6596,8 +7813,8 @@ fi else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac LIPO=$ac_ct_LIPO @@ -6609,11 +7826,12 @@ fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. set dummy ${ac_tool_prefix}otool; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_OTOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_OTOOL+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$OTOOL"; then ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. else @@ -6621,11 +7839,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL="${ac_tool_prefix}otool" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -6636,11 +7858,11 @@ fi fi OTOOL=$ac_cv_prog_OTOOL if test -n "$OTOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 -$as_echo "$OTOOL" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 +printf "%s\n" "$OTOOL" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -6649,11 +7871,12 @@ if test -z "$ac_cv_prog_OTOOL"; then ac_ct_OTOOL=$OTOOL # Extract the first word of "otool", so it can be a program name with args. set dummy otool; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_OTOOL+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$ac_ct_OTOOL"; then ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. else @@ -6661,11 +7884,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL="otool" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -6676,11 +7903,11 @@ fi fi ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL if test -n "$ac_ct_OTOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 -$as_echo "$ac_ct_OTOOL" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 +printf "%s\n" "$ac_ct_OTOOL" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi if test "x$ac_ct_OTOOL" = x; then @@ -6688,8 +7915,8 @@ fi else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL=$ac_ct_OTOOL @@ -6701,11 +7928,12 @@ fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. set dummy ${ac_tool_prefix}otool64; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_OTOOL64+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_OTOOL64+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$OTOOL64"; then ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. else @@ -6713,11 +7941,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -6728,11 +7960,11 @@ fi fi OTOOL64=$ac_cv_prog_OTOOL64 if test -n "$OTOOL64"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 -$as_echo "$OTOOL64" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 +printf "%s\n" "$OTOOL64" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -6741,11 +7973,12 @@ if test -z "$ac_cv_prog_OTOOL64"; then ac_ct_OTOOL64=$OTOOL64 # Extract the first word of "otool64", so it can be a program name with args. set dummy otool64; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_OTOOL64+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$ac_ct_OTOOL64"; then ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. else @@ -6753,11 +7986,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL64="otool64" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -6768,11 +8005,11 @@ fi fi ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 if test -n "$ac_ct_OTOOL64"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 -$as_echo "$ac_ct_OTOOL64" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 +printf "%s\n" "$ac_ct_OTOOL64" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi if test "x$ac_ct_OTOOL64" = x; then @@ -6780,8 +8017,8 @@ fi else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL64=$ac_ct_OTOOL64 @@ -6816,13 +8053,14 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 -$as_echo_n "checking for -single_module linker flag... " >&6; } -if ${lt_cv_apple_cc_single_mod+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 +printf %s "checking for -single_module linker flag... " >&6; } +if test ${lt_cv_apple_cc_single_mod+y} +then : + printf %s "(cached) " >&6 +else $as_nop lt_cv_apple_cc_single_mod=no - if test -z "${LT_MULTI_MODULE}"; then + if test -z "$LT_MULTI_MODULE"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the @@ -6840,7 +8078,7 @@ else cat conftest.err >&5 # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. - elif test -f libconftest.dylib && test $_lt_result -eq 0; then + elif test -f libconftest.dylib && test 0 = "$_lt_result"; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&5 @@ -6849,14 +8087,15 @@ else rm -f conftest.* fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 -$as_echo "$lt_cv_apple_cc_single_mod" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 +printf "%s\n" "$lt_cv_apple_cc_single_mod" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 -$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } -if ${lt_cv_ld_exported_symbols_list+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 +printf %s "checking for -exported_symbols_list linker flag... " >&6; } +if test ${lt_cv_ld_exported_symbols_list+y} +then : + printf %s "(cached) " >&6 +else $as_nop lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym @@ -6865,31 +8104,33 @@ else /* end confdefs.h. */ int -main () +main (void) { ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : lt_cv_ld_exported_symbols_list=yes -else +else $as_nop lt_cv_ld_exported_symbols_list=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext - LDFLAGS="$save_LDFLAGS" + LDFLAGS=$save_LDFLAGS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 -$as_echo "$lt_cv_ld_exported_symbols_list" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 +printf "%s\n" "$lt_cv_ld_exported_symbols_list" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 -$as_echo_n "checking for -force_load linker flag... " >&6; } -if ${lt_cv_ld_force_load+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 +printf %s "checking for -force_load linker flag... " >&6; } +if test ${lt_cv_ld_force_load+y} +then : + printf %s "(cached) " >&6 +else $as_nop lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} @@ -6908,7 +8149,7 @@ _LT_EOF _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&5 - elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then + elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then lt_cv_ld_force_load=yes else cat conftest.err >&5 @@ -6917,36 +8158,31 @@ _LT_EOF rm -rf conftest.dSYM fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 -$as_echo "$lt_cv_ld_force_load" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 +printf "%s\n" "$lt_cv_ld_force_load" >&6; } case $host_os in rhapsody* | darwin1.[012]) - _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; - darwin*) # darwin 5.x on - # if running on 10.5 or later, the deployment target defaults - # to the OS version, if on x86, and 10.4, the deployment - # target defaults to 10.4. Don't you love it? - case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in - 10.0,*86*-darwin8*|10.0,*-darwin[91]*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; - 10.[012]*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; - 10.*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + darwin*) + case $MACOSX_DEPLOYMENT_TARGET,$host in + 10.[012],*|,*powerpc*-darwin[5-8]*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + *) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; esac - if test "$lt_cv_apple_cc_single_mod" = "yes"; then + if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi - if test "$lt_cv_ld_exported_symbols_list" = "yes"; then - _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + if test yes = "$lt_cv_ld_exported_symbols_list"; then + _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' else - _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' fi - if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then + if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= @@ -6954,285 +8190,77 @@ $as_echo "$lt_cv_ld_force_load" >&6; } ;; esac -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 -$as_echo_n "checking how to run the C preprocessor... " >&6; } -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then - if ${ac_cv_prog_CPP+:} false; then : - $as_echo_n "(cached) " >&6 -else - # Double quotes because CPP needs to be expanded - for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" - do - ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.i conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - break -fi - - done - ac_cv_prog_CPP=$CPP - -fi - CPP=$ac_cv_prog_CPP -else - ac_cv_prog_CPP=$CPP -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 -$as_echo "$CPP" >&6; } -ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.i conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - -else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details" "$LINENO" 5; } -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 -$as_echo_n "checking for ANSI C header files... " >&6; } -if ${ac_cv_header_stdc+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#include -#include - -int -main () +# func_munge_path_list VARIABLE PATH +# ----------------------------------- +# VARIABLE is name of variable containing _space_ separated list of +# directories to be munged by the contents of PATH, which is string +# having a format: +# "DIR[:DIR]:" +# string "DIR[ DIR]" will be prepended to VARIABLE +# ":DIR[:DIR]" +# string "DIR[ DIR]" will be appended to VARIABLE +# "DIRP[:DIRP]::[DIRA:]DIRA" +# string "DIRP[ DIRP]" will be prepended to VARIABLE and string +# "DIRA[ DIRA]" will be appended to VARIABLE +# "DIR[:DIR]" +# VARIABLE will be replaced by "DIR[ DIR]" +func_munge_path_list () { - - ; - return 0; + case x$2 in + x) + ;; + *:) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" + ;; + x:*) + eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" + ;; + *::*) + eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" + eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" + ;; + *) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" + ;; + esac } -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_header_stdc=yes -else - ac_cv_header_stdc=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -if test $ac_cv_header_stdc = yes; then - # SunOS 4.x string.h does not declare mem*, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "memchr" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "free" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; then : - : -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#if ((' ' & 0x0FF) == 0x020) -# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#else -# define ISLOWER(c) \ - (('a' <= (c) && (c) <= 'i') \ - || ('j' <= (c) && (c) <= 'r') \ - || ('s' <= (c) && (c) <= 'z')) -# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) -#endif - -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) -int -main () -{ - int i; - for (i = 0; i < 256; i++) - if (XOR (islower (i), ISLOWER (i)) - || toupper (i) != TOUPPER (i)) - return 2; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - -else - ac_cv_header_stdc=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 -$as_echo "$ac_cv_header_stdc" >&6; } -if test $ac_cv_header_stdc = yes; then - -$as_echo "#define STDC_HEADERS 1" >>confdefs.h - -fi - -# On IRIX 5.3, sys/types and inttypes.h are conflicting. -for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ - inttypes.h stdint.h unistd.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default -" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi +ac_header= ac_cache= +for ac_item in $ac_header_c_list +do + if test $ac_cache; then + ac_fn_c_check_header_compile "$LINENO" $ac_header ac_cv_header_$ac_cache "$ac_includes_default" + if eval test \"x\$ac_cv_header_$ac_cache\" = xyes; then + printf "%s\n" "#define $ac_item 1" >> confdefs.h + fi + ac_header= ac_cache= + elif test $ac_header; then + ac_cache=$ac_item + else + ac_header=$ac_item + fi done -for ac_header in dlfcn.h -do : - ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default -" -if test "x$ac_cv_header_dlfcn_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_DLFCN_H 1 -_ACEOF + + + + + + +if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes +then : + +printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h fi +ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default +" +if test "x$ac_cv_header_dlfcn_h" = xyes +then : + printf "%s\n" "#define HAVE_DLFCN_H 1" >>confdefs.h -done +fi @@ -7242,15 +8270,16 @@ done enable_win32_dll=yes case $host in -*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) +*-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-cegcc*) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. set dummy ${ac_tool_prefix}as; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_AS+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_AS+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$AS"; then ac_cv_prog_AS="$AS" # Let the user override the test. else @@ -7258,11 +8287,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_AS="${ac_tool_prefix}as" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -7273,11 +8306,11 @@ fi fi AS=$ac_cv_prog_AS if test -n "$AS"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AS" >&5 -$as_echo "$AS" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AS" >&5 +printf "%s\n" "$AS" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -7286,11 +8319,12 @@ if test -z "$ac_cv_prog_AS"; then ac_ct_AS=$AS # Extract the first word of "as", so it can be a program name with args. set dummy as; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_AS+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_AS+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$ac_ct_AS"; then ac_cv_prog_ac_ct_AS="$ac_ct_AS" # Let the user override the test. else @@ -7298,11 +8332,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AS="as" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -7313,11 +8351,11 @@ fi fi ac_ct_AS=$ac_cv_prog_ac_ct_AS if test -n "$ac_ct_AS"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AS" >&5 -$as_echo "$ac_ct_AS" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AS" >&5 +printf "%s\n" "$ac_ct_AS" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi if test "x$ac_ct_AS" = x; then @@ -7325,8 +8363,8 @@ fi else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AS=$ac_ct_AS @@ -7338,11 +8376,12 @@ fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. set dummy ${ac_tool_prefix}dlltool; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_DLLTOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_DLLTOOL+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else @@ -7350,11 +8389,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -7365,11 +8408,11 @@ fi fi DLLTOOL=$ac_cv_prog_DLLTOOL if test -n "$DLLTOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 -$as_echo "$DLLTOOL" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 +printf "%s\n" "$DLLTOOL" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -7378,11 +8421,12 @@ if test -z "$ac_cv_prog_DLLTOOL"; then ac_ct_DLLTOOL=$DLLTOOL # Extract the first word of "dlltool", so it can be a program name with args. set dummy dlltool; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_DLLTOOL+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$ac_ct_DLLTOOL"; then ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. else @@ -7390,11 +8434,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -7405,11 +8453,11 @@ fi fi ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL if test -n "$ac_ct_DLLTOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 -$as_echo "$ac_ct_DLLTOOL" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 +printf "%s\n" "$ac_ct_DLLTOOL" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi if test "x$ac_ct_DLLTOOL" = x; then @@ -7417,8 +8465,8 @@ fi else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DLLTOOL=$ac_ct_DLLTOOL @@ -7430,11 +8478,12 @@ fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_OBJDUMP+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_OBJDUMP+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else @@ -7442,11 +8491,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -7457,11 +8510,11 @@ fi fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 -$as_echo "$OBJDUMP" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +printf "%s\n" "$OBJDUMP" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -7470,11 +8523,12 @@ if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_OBJDUMP+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else @@ -7482,11 +8536,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OBJDUMP="objdump" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -7497,11 +8555,11 @@ fi fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 -$as_echo "$ac_ct_OBJDUMP" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +printf "%s\n" "$ac_ct_OBJDUMP" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then @@ -7509,8 +8567,8 @@ fi else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP @@ -7547,7 +8605,8 @@ test -z "$OBJDUMP" && OBJDUMP=objdump # Check whether --enable-shared was given. -if test "${enable_shared+set}" = set; then : +if test ${enable_shared+y} +then : enableval=$enable_shared; p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; @@ -7555,17 +8614,17 @@ if test "${enable_shared+set}" = set; then : *) enable_shared=no # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_shared=yes fi done - IFS="$lt_save_ifs" + IFS=$lt_save_ifs ;; esac -else +else $as_nop enable_shared=yes fi @@ -7578,7 +8637,8 @@ fi # Check whether --enable-static was given. -if test "${enable_static+set}" = set; then : +if test ${enable_static+y} +then : enableval=$enable_static; p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; @@ -7586,17 +8646,17 @@ if test "${enable_static+set}" = set; then : *) enable_static=no # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_static=yes fi done - IFS="$lt_save_ifs" + IFS=$lt_save_ifs ;; esac -else +else $as_nop enable_static=yes fi @@ -7610,30 +8670,29 @@ fi # Check whether --with-pic was given. -if test "${with_pic+set}" = set; then : +if test ${with_pic+y} +then : withval=$with_pic; lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for lt_pkg in $withval; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done - IFS="$lt_save_ifs" + IFS=$lt_save_ifs ;; esac -else +else $as_nop pic_mode=default fi -test -z "$pic_mode" && pic_mode=default - @@ -7641,7 +8700,8 @@ test -z "$pic_mode" && pic_mode=default # Check whether --enable-fast-install was given. -if test "${enable_fast_install+set}" = set; then : +if test ${enable_fast_install+y} +then : enableval=$enable_fast_install; p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; @@ -7649,17 +8709,17 @@ if test "${enable_fast_install+set}" = set; then : *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done - IFS="$lt_save_ifs" + IFS=$lt_save_ifs ;; esac -else +else $as_nop enable_fast_install=yes fi @@ -7670,11 +8730,65 @@ fi + shared_archive_member_spec= +case $host,$enable_shared in +power*-*-aix[5-9]*,yes) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5 +printf %s "checking which variant of shared library versioning to provide... " >&6; } + +# Check whether --with-aix-soname was given. +if test ${with_aix_soname+y} +then : + withval=$with_aix_soname; case $withval in + aix|svr4|both) + ;; + *) + as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5 + ;; + esac + lt_cv_with_aix_soname=$with_aix_soname +else $as_nop + if test ${lt_cv_with_aix_soname+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_with_aix_soname=aix +fi + + with_aix_soname=$lt_cv_with_aix_soname +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5 +printf "%s\n" "$with_aix_soname" >&6; } + if test aix != "$with_aix_soname"; then + # For the AIX way of multilib, we name the shared archive member + # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', + # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. + # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, + # the AIX toolchain works better with OBJECT_MODE set (default 32). + if test 64 = "${OBJECT_MODE-32}"; then + shared_archive_member_spec=shr_64 + else + shared_archive_member_spec=shr + fi + fi + ;; +*) + with_aix_soname=aix + ;; +esac + + + + + + + # This can be used to rebuild libtool when needed -LIBTOOL_DEPS="$ltmain" +LIBTOOL_DEPS=$ltmain # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' @@ -7723,15 +8837,16 @@ test -z "$LN_S" && LN_S="ln -s" -if test -n "${ZSH_VERSION+set}" ; then +if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 -$as_echo_n "checking for objdir... " >&6; } -if ${lt_cv_objdir+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 +printf %s "checking for objdir... " >&6; } +if test ${lt_cv_objdir+y} +then : + printf %s "(cached) " >&6 +else $as_nop rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then @@ -7742,17 +8857,15 @@ else fi rmdir .libs 2>/dev/null fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 -$as_echo "$lt_cv_objdir" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 +printf "%s\n" "$lt_cv_objdir" >&6; } objdir=$lt_cv_objdir -cat >>confdefs.h <<_ACEOF -#define LT_OBJDIR "$lt_cv_objdir/" -_ACEOF +printf "%s\n" "#define LT_OBJDIR \"$lt_cv_objdir/\"" >>confdefs.h @@ -7762,7 +8875,7 @@ aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. - if test "X${COLLECT_NAMES+set}" != Xset; then + if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi @@ -7773,14 +8886,14 @@ esac ofile=libtool can_build_shared=yes -# All known linkers require a `.a' archive for static linking (except MSVC, -# which needs '.lib'). +# All known linkers require a '.a' archive for static linking (except MSVC and +# ICC, which need '.lib'). libext=a -with_gnu_ld="$lt_cv_prog_gnu_ld" +with_gnu_ld=$lt_cv_prog_gnu_ld -old_CC="$CC" -old_CFLAGS="$CFLAGS" +old_CC=$CC +old_CFLAGS=$CFLAGS # Set sane defaults for various variables test -z "$CC" && CC=cc @@ -7789,15 +8902,8 @@ test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o -for cc_temp in $compiler""; do - case $cc_temp in - compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; - distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; - \-*) ;; - *) break;; - esac -done -cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +func_cc_basename $compiler +cc_basename=$func_cc_basename_result # Only perform the check for file, if the check method requires it @@ -7805,29 +8911,30 @@ test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 -$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } -if ${lt_cv_path_MAGIC_CMD+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 +printf %s "checking for ${ac_tool_prefix}file... " >&6; } +if test ${lt_cv_path_MAGIC_CMD+y} +then : + printf %s "(cached) " >&6 +else $as_nop case $MAGIC_CMD in [\\/*] | ?:[\\/]*) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) - lt_save_MAGIC_CMD="$MAGIC_CMD" - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/${ac_tool_prefix}file; then - lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" + if test -f "$ac_dir/${ac_tool_prefix}file"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` - MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : @@ -7850,19 +8957,19 @@ _LT_EOF break fi done - IFS="$lt_save_ifs" - MAGIC_CMD="$lt_save_MAGIC_CMD" + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac fi -MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 -$as_echo "$MAGIC_CMD" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +printf "%s\n" "$MAGIC_CMD" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -7871,29 +8978,30 @@ fi if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 -$as_echo_n "checking for file... " >&6; } -if ${lt_cv_path_MAGIC_CMD+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for file" >&5 +printf %s "checking for file... " >&6; } +if test ${lt_cv_path_MAGIC_CMD+y} +then : + printf %s "(cached) " >&6 +else $as_nop case $MAGIC_CMD in [\\/*] | ?:[\\/]*) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) - lt_save_MAGIC_CMD="$MAGIC_CMD" - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/file; then - lt_cv_path_MAGIC_CMD="$ac_dir/file" + if test -f "$ac_dir/file"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` - MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : @@ -7916,19 +9024,19 @@ _LT_EOF break fi done - IFS="$lt_save_ifs" - MAGIC_CMD="$lt_save_MAGIC_CMD" + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac fi -MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 -$as_echo "$MAGIC_CMD" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +printf "%s\n" "$MAGIC_CMD" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -7943,7 +9051,7 @@ esac # Use C for the default configuration in the libtool script -lt_save_CC="$CC" +lt_save_CC=$CC ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -8005,7 +9113,7 @@ if test -n "$compiler"; then lt_prog_compiler_no_builtin_flag= -if test "$GCC" = yes; then +if test yes = "$GCC"; then case $cc_basename in nvcc*) lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; @@ -8013,15 +9121,16 @@ if test "$GCC" = yes; then lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; esac - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 -$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } -if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +printf %s "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +if test ${lt_cv_prog_compiler_rtti_exceptions+y} +then : + printf %s "(cached) " >&6 +else $as_nop lt_cv_prog_compiler_rtti_exceptions=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="-fno-rtti -fno-exceptions" + lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins @@ -8048,10 +9157,10 @@ else $RM conftest* fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 -$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +printf "%s\n" "$lt_cv_prog_compiler_rtti_exceptions" >&6; } -if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then +if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" else : @@ -8069,17 +9178,18 @@ lt_prog_compiler_pic= lt_prog_compiler_static= - if test "$GCC" = yes; then + if test yes = "$GCC"; then lt_prog_compiler_wl='-Wl,' lt_prog_compiler_static='-static' case $host_os in aix*) # All AIX code is PIC. - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' fi + lt_prog_compiler_pic='-fPIC' ;; amigaos*) @@ -8090,8 +9200,8 @@ lt_prog_compiler_static= ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' ;; esac @@ -8101,12 +9211,17 @@ lt_prog_compiler_static= # PIC is the default for these OSes. ;; - mingw* | cygwin* | pw32* | os2* | cegcc*) + mingw* | windows* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static='$wl-static' + ;; + esac ;; darwin* | rhapsody*) @@ -8177,7 +9292,7 @@ lt_prog_compiler_static= case $host_os in aix*) lt_prog_compiler_wl='-Wl,' - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' else @@ -8185,10 +9300,29 @@ lt_prog_compiler_static= fi ;; - mingw* | cygwin* | pw32* | os2* | cegcc*) + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + case $cc_basename in + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + + mingw* | windows* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static='$wl-static' + ;; + esac ;; hpux9* | hpux10* | hpux11*) @@ -8204,7 +9338,7 @@ lt_prog_compiler_static= ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? - lt_prog_compiler_static='${wl}-a ${wl}archive' + lt_prog_compiler_static='$wl-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) @@ -8213,9 +9347,9 @@ lt_prog_compiler_static= lt_prog_compiler_static='-non_shared' ;; - linux* | k*bsd*-gnu | kopensolaris*-gnu) + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in - # old Intel for x86_64 which still supported -KPIC. + # old Intel for x86_64, which still supported -KPIC. ecc*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' @@ -8240,6 +9374,12 @@ lt_prog_compiler_static= lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) @@ -8337,7 +9477,7 @@ lt_prog_compiler_static= ;; sysv4*MP*) - if test -d /usr/nec ;then + if test -d /usr/nec; then lt_prog_compiler_pic='-Kconform_pic' lt_prog_compiler_static='-Bstatic' fi @@ -8366,7 +9506,7 @@ lt_prog_compiler_static= fi case $host_os in - # For platforms which do not support PIC, -DPIC is meaningless: + # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic= ;; @@ -8375,30 +9515,32 @@ case $host_os in ;; esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 -$as_echo_n "checking for $compiler option to produce PIC... " >&6; } -if ${lt_cv_prog_compiler_pic+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +printf %s "checking for $compiler option to produce PIC... " >&6; } +if test ${lt_cv_prog_compiler_pic+y} +then : + printf %s "(cached) " >&6 +else $as_nop lt_cv_prog_compiler_pic=$lt_prog_compiler_pic fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 -$as_echo "$lt_cv_prog_compiler_pic" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 +printf "%s\n" "$lt_cv_prog_compiler_pic" >&6; } lt_prog_compiler_pic=$lt_cv_prog_compiler_pic # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 -$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } -if ${lt_cv_prog_compiler_pic_works+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +printf %s "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } +if test ${lt_cv_prog_compiler_pic_works+y} +then : + printf %s "(cached) " >&6 +else $as_nop lt_cv_prog_compiler_pic_works=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="$lt_prog_compiler_pic -DPIC" + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins @@ -8425,10 +9567,10 @@ else $RM conftest* fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 -$as_echo "$lt_cv_prog_compiler_pic_works" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 +printf "%s\n" "$lt_cv_prog_compiler_pic_works" >&6; } -if test x"$lt_cv_prog_compiler_pic_works" = xyes; then +if test yes = "$lt_cv_prog_compiler_pic_works"; then case $lt_prog_compiler_pic in "" | " "*) ;; *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; @@ -8454,13 +9596,14 @@ fi # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 -$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } -if ${lt_cv_prog_compiler_static_works+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +printf %s "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if test ${lt_cv_prog_compiler_static_works+y} +then : + printf %s "(cached) " >&6 +else $as_nop lt_cv_prog_compiler_static_works=no - save_LDFLAGS="$LDFLAGS" + save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then @@ -8479,13 +9622,13 @@ else fi fi $RM -r conftest* - LDFLAGS="$save_LDFLAGS" + LDFLAGS=$save_LDFLAGS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 -$as_echo "$lt_cv_prog_compiler_static_works" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 +printf "%s\n" "$lt_cv_prog_compiler_static_works" >&6; } -if test x"$lt_cv_prog_compiler_static_works" = xyes; then +if test yes = "$lt_cv_prog_compiler_static_works"; then : else lt_prog_compiler_static= @@ -8497,11 +9640,12 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 -$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } -if ${lt_cv_prog_compiler_c_o+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if test ${lt_cv_prog_compiler_c_o+y} +then : + printf %s "(cached) " >&6 +else $as_nop lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest @@ -8544,19 +9688,20 @@ else $RM conftest* fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 -$as_echo "$lt_cv_prog_compiler_c_o" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +printf "%s\n" "$lt_cv_prog_compiler_c_o" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 -$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } -if ${lt_cv_prog_compiler_c_o+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if test ${lt_cv_prog_compiler_c_o+y} +then : + printf %s "(cached) " >&6 +else $as_nop lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest @@ -8599,28 +9744,28 @@ else $RM conftest* fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 -$as_echo "$lt_cv_prog_compiler_c_o" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +printf "%s\n" "$lt_cv_prog_compiler_c_o" >&6; } -hard_links="nottested" -if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then +hard_links=nottested +if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 -$as_echo_n "checking if we can lock with hard links... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +printf %s "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 -$as_echo "$hard_links" >&6; } - if test "$hard_links" = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 -$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +printf "%s\n" "$hard_links" >&6; } + if test no = "$hard_links"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 +printf "%s\n" "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} need_locks=warn fi else @@ -8632,8 +9777,8 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 -$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +printf %s "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } runpath_var= allow_undefined_flag= @@ -8663,9 +9808,9 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie # included in the symbol list include_expsyms= # exclude_expsyms can be an extended regexp of symbols to exclude - # it will be wrapped by ` (' and `)$', so one must not match beginning or - # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', - # as well as any symbol that contains `d'. + # it will be wrapped by ' (' and ')$', so one must not match beginning or + # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', + # as well as any symbol that contains 'd'. exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if @@ -8676,19 +9821,19 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie extract_expsyms_cmds= case $host_os in - cygwin* | mingw* | pw32* | cegcc*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time + cygwin* | mingw* | windows* | pw32* | cegcc*) + # FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - if test "$GCC" != yes; then + # Microsoft Visual C++ or Intel C++ Compiler. + if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) - # we just hope/assume this is gcc and not c89 (= MSVC++) + # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC) with_gnu_ld=yes ;; - openbsd*) + openbsd* | bitrig*) with_gnu_ld=no ;; esac @@ -8698,7 +9843,7 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no - if test "$with_gnu_ld" = yes; then + if test yes = "$with_gnu_ld"; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility @@ -8720,24 +9865,24 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie esac fi - if test "$lt_use_gnu_ld_interface" = yes; then + if test yes = "$lt_use_gnu_ld_interface"; then # If archive_cmds runs LD, not CC, wlarc should be empty - wlarc='${wl}' + wlarc='$wl' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - export_dynamic_flag_spec='${wl}--export-dynamic' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + export_dynamic_flag_spec='$wl--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then - whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else whole_archive_flag_spec= fi supports_anon_versioning=no - case `$LD -v 2>&1` in + case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... @@ -8750,7 +9895,7 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie case $host_os in aix[3-9]*) # On AIX/PPC, the GNU linker is very broken - if test "$host_cpu" != ia64; then + if test ia64 != "$host_cpu"; then ld_shlibs=no cat <<_LT_EOF 1>&2 @@ -8769,7 +9914,7 @@ _LT_EOF case $host_cpu in powerpc) # see comment about AmigaOS4 .so support - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) @@ -8785,17 +9930,17 @@ _LT_EOF allow_undefined_flag=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME - archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else ld_shlibs=no fi ;; - cygwin* | mingw* | pw32* | cegcc*) + cygwin* | mingw* | windows* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' - export_dynamic_flag_spec='${wl}--export-all-symbols' + export_dynamic_flag_spec='$wl--export-all-symbols' allow_undefined_flag=unsupported always_export_symbols=no enable_shared_with_static_runtimes=yes @@ -8803,61 +9948,90 @@ _LT_EOF exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs=no fi ;; haiku*) - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' link_all_deplibs=yes ;; + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + shrext_cmds=.dll + archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + enable_shared_with_static_runtimes=yes + file_list_spec='@' + ;; + interix[3-9]*) hardcode_direct=no hardcode_shlibpath_var=no - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - export_dynamic_flag_spec='${wl}-E' + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + export_dynamic_flag_spec='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no - if test "$host_os" = linux-dietlibc; then + if test linux-dietlibc = "$host_os"; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ - && test "$tmp_diet" = no + && test no = "$tmp_diet" then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler - whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers - whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; @@ -8868,42 +10042,47 @@ _LT_EOF lf95*) # Lahey Fortran 8.1 whole_archive_flag_spec= tmp_sharedflag='--shared' ;; + nagfor*) # NAGFOR 5.3 + tmp_sharedflag='-Wl,-shared' ;; xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 - whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 - whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac - archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then + if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi case $cc_basename in + tcc*) + export_dynamic_flag_spec='-rdynamic' + ;; xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then + if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac @@ -8917,8 +10096,8 @@ _LT_EOF archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' fi ;; @@ -8936,8 +10115,8 @@ _LT_EOF _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi @@ -8949,7 +10128,7 @@ _LT_EOF ld_shlibs=no cat <<_LT_EOF 1>&2 -*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify @@ -8964,9 +10143,9 @@ _LT_EOF # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi @@ -8983,15 +10162,15 @@ _LT_EOF *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac - if test "$ld_shlibs" = no; then + if test no = "$ld_shlibs"; then runpath_var= hardcode_libdir_flag_spec= export_dynamic_flag_spec= @@ -9007,7 +10186,7 @@ _LT_EOF # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes - if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported @@ -9015,34 +10194,57 @@ _LT_EOF ;; aix[4-9]*) - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' - no_entry_flag="" + no_entry_flag= else # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - # Also, AIX nm treats weak defined symbols like other global - # defined symbols, whereas GNU nm marks them as "W". + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then - export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else - export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do - if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then aix_use_runtimelinking=yes break fi done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi ;; esac @@ -9061,13 +10263,21 @@ _LT_EOF hardcode_direct_absolute=yes hardcode_libdir_separator=':' link_all_deplibs=yes - file_list_spec='${wl}-f,' + file_list_spec='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # traditional, no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + hardcode_direct=no + hardcode_direct_absolute=no + ;; + esac - if test "$GCC" = yes; then + if test yes = "$GCC"; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` + collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then @@ -9086,52 +10296,61 @@ _LT_EOF ;; esac shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' + if test yes = "$aix_use_runtimelinking"; then + shared_flag="$shared_flag "'$wl-G' fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' else # not using gcc - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' else - shared_flag='${wl}-bM:SRE' + shared_flag='$wl-bM:SRE' fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' fi fi - export_dynamic_flag_spec='${wl}-bexpall' + export_dynamic_flag_spec='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols=yes - if test "$aix_use_runtimelinking" = yes; then + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag='-berok' # Determine the default libpath from the value encoded in an # empty executable. - if test "${lt_cv_aix_libpath+set}" = set; then + if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else - if ${lt_cv_aix_libpath_+:} false; then : - $as_echo_n "(cached) " >&6 -else + if test ${lt_cv_aix_libpath_+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { @@ -9146,10 +10365,10 @@ if ac_fn_c_try_link "$LINENO"; then : lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then - lt_cv_aix_libpath_="/usr/lib:/lib" + lt_cv_aix_libpath_=/usr/lib:/lib fi fi @@ -9157,34 +10376,36 @@ fi aix_libpath=$lt_cv_aix_libpath_ fi - hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" - archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else - if test "$host_cpu" = ia64; then - hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + if test ia64 = "$host_cpu"; then + hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib' allow_undefined_flag="-z nodefs" - archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. - if test "${lt_cv_aix_libpath+set}" = set; then + if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else - if ${lt_cv_aix_libpath_+:} false; then : - $as_echo_n "(cached) " >&6 -else + if test ${lt_cv_aix_libpath_+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { @@ -9199,10 +10420,10 @@ if ac_fn_c_try_link "$LINENO"; then : lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then - lt_cv_aix_libpath_="/usr/lib:/lib" + lt_cv_aix_libpath_=/usr/lib:/lib fi fi @@ -9210,21 +10431,33 @@ fi aix_libpath=$lt_cv_aix_libpath_ fi - hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. - no_undefined_flag=' ${wl}-bernotok' - allow_undefined_flag=' ${wl}-berok' - if test "$with_gnu_ld" = yes; then + no_undefined_flag=' $wl-bernotok' + allow_undefined_flag=' $wl-berok' + if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. - whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec='$convenience' fi archive_cmds_need_lc=yes - # This is similar to how AIX traditionally builds its shared libraries. - archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + archive_expsym_cmds="$archive_expsym_cmds"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d' fi fi ;; @@ -9233,7 +10466,7 @@ fi case $host_cpu in powerpc) # see comment about AmigaOS4 .so support - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) @@ -9248,14 +10481,14 @@ fi export_dynamic_flag_spec=-rdynamic ;; - cygwin* | mingw* | pw32* | cegcc*) + cygwin* | mingw* | windows* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. + # Microsoft Visual C++ or Intel C++ Compiler. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in - cl*) - # Native MSVC + cl* | icl*) + # Native MSVC or ICC hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported always_export_symbols=yes @@ -9263,16 +10496,17 @@ fi # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" + shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. - archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' - archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; - else - sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; - fi~ - $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ - linknames=' + archive_cmds='$CC -Fe $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -Fe $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, )='true' enable_shared_with_static_runtimes=yes @@ -9281,27 +10515,27 @@ fi # Don't use ranlib old_postinstall_cmds='chmod 644 $oldlib' postlink_cmds='lt_outputfile="@OUTPUT@"~ - lt_tool_outputfile="@TOOL_OUTPUT@"~ - case $lt_outputfile in - *.exe|*.EXE) ;; - *) - lt_outputfile="$lt_outputfile.exe" - lt_tool_outputfile="$lt_tool_outputfile.exe" - ;; - esac~ - if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then - $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; - $RM "$lt_outputfile.manifest"; - fi' + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' ;; *) - # Assume MSVC wrapper + # Assume MSVC and ICC wrapper hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" + shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. @@ -9320,24 +10554,24 @@ fi hardcode_direct=no hardcode_automatic=yes hardcode_shlibpath_var=unsupported - if test "$lt_cv_ld_force_load" = "yes"; then - whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + if test yes = "$lt_cv_ld_force_load"; then + whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec='' fi link_all_deplibs=yes - allow_undefined_flag="$_lt_dar_allow_undefined" + allow_undefined_flag=$_lt_dar_allow_undefined case $cc_basename in - ifort*) _lt_dar_can_shared=yes ;; + ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac - if test "$_lt_dar_can_shared" = "yes"; then + if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all - archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" - module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" - archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" - module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" else ld_shlibs=no @@ -9371,7 +10605,7 @@ fi ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | dragonfly*) + freebsd* | dragonfly* | midnightbsd*) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes @@ -9379,33 +10613,33 @@ fi ;; hpux9*) - if test "$GCC" = yes; then - archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + if test yes = "$GCC"; then + archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else - archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' fi - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes - export_dynamic_flag_spec='${wl}-E' + export_dynamic_flag_spec='$wl-E' ;; hpux10*) - if test "$GCC" = yes && test "$with_gnu_ld" = no; then - archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + if test yes,no = "$GCC,$with_gnu_ld"; then + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi - if test "$with_gnu_ld" = no; then - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: hardcode_direct=yes hardcode_direct_absolute=yes - export_dynamic_flag_spec='${wl}-E' + export_dynamic_flag_spec='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes @@ -9413,37 +10647,38 @@ fi ;; hpux11*) - if test "$GCC" = yes && test "$with_gnu_ld" = no; then + if test yes,no = "$GCC,$with_gnu_ld"; then case $host_cpu in hppa*64*) - archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) - archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) - archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) - archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) - archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 -$as_echo_n "checking if $CC understands -b... " >&6; } -if ${lt_cv_prog_compiler__b+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 +printf %s "checking if $CC understands -b... " >&6; } +if test ${lt_cv_prog_compiler__b+y} +then : + printf %s "(cached) " >&6 +else $as_nop lt_cv_prog_compiler__b=no - save_LDFLAGS="$LDFLAGS" + save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -b" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then @@ -9462,14 +10697,14 @@ else fi fi $RM -r conftest* - LDFLAGS="$save_LDFLAGS" + LDFLAGS=$save_LDFLAGS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 -$as_echo "$lt_cv_prog_compiler__b" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 +printf "%s\n" "$lt_cv_prog_compiler__b" >&6; } -if test x"$lt_cv_prog_compiler__b" = xyes; then - archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' +if test yes = "$lt_cv_prog_compiler__b"; then + archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi @@ -9477,8 +10712,8 @@ fi ;; esac fi - if test "$with_gnu_ld" = no; then - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: case $host_cpu in @@ -9489,7 +10724,7 @@ fi *) hardcode_direct=yes hardcode_direct_absolute=yes - export_dynamic_flag_spec='${wl}-E' + export_dynamic_flag_spec='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. @@ -9500,48 +10735,60 @@ fi ;; irix5* | irix6* | nonstopux*) - if test "$GCC" = yes; then - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + if test yes = "$GCC"; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 -$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } -if ${lt_cv_irix_exported_symbol+:} false; then : - $as_echo_n "(cached) " >&6 -else - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 +printf %s "checking whether the $host_os linker accepts -exported_symbol... " >&6; } +if test ${lt_cv_irix_exported_symbol+y} +then : + printf %s "(cached) " >&6 +else $as_nop + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int foo (void) { return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : lt_cv_irix_exported_symbol=yes -else +else $as_nop lt_cv_irix_exported_symbol=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext - LDFLAGS="$save_LDFLAGS" + LDFLAGS=$save_LDFLAGS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 -$as_echo "$lt_cv_irix_exported_symbol" >&6; } - if test "$lt_cv_irix_exported_symbol" = yes; then - archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 +printf "%s\n" "$lt_cv_irix_exported_symbol" >&6; } + if test yes = "$lt_cv_irix_exported_symbol"; then + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' fi else - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' fi archive_cmds_need_lc='no' - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: inherit_rpath=yes link_all_deplibs=yes ;; + linux*) + case $cc_basename in + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + ld_shlibs=yes + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out @@ -9556,7 +10803,7 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; } newsos6) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: hardcode_shlibpath_var=no ;; @@ -9564,27 +10811,19 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; } *nto* | *qnx*) ;; - openbsd*) + openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then hardcode_direct=yes hardcode_shlibpath_var=no hardcode_direct_absolute=yes - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - export_dynamic_flag_spec='${wl}-E' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + export_dynamic_flag_spec='$wl-E' else - case $host_os in - openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec='-R$libdir' - ;; - *) - archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - ;; - esac + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='$wl-rpath,$libdir' fi else ld_shlibs=no @@ -9595,33 +10834,54 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; } hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported - archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' - old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + shrext_cmds=.dll + archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + enable_shared_with_static_runtimes=yes + file_list_spec='@' ;; osf3*) - if test "$GCC" = yes; then - allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + if test yes = "$GCC"; then + allow_undefined_flag=' $wl-expect_unresolved $wl\*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else allow_undefined_flag=' -expect_unresolved \*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' fi archive_cmds_need_lc='no' - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag - if test "$GCC" = yes; then - allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + if test yes = "$GCC"; then + allow_undefined_flag=' $wl-expect_unresolved $wl\*' + archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' else allow_undefined_flag=' -expect_unresolved \*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ - $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' + $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' @@ -9632,24 +10892,24 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; } solaris*) no_undefined_flag=' -z defs' - if test "$GCC" = yes; then - wlarc='${wl}' - archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + if test yes = "$GCC"; then + wlarc='$wl' + archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' - archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) - wlarc='${wl}' - archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' + wlarc='$wl' + archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi @@ -9659,11 +10919,11 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; } solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, - # but understands `-z linker_flag'. GCC discards it without `$wl', + # but understands '-z linker_flag'. GCC discards it without '$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) - if test "$GCC" = yes; then - whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + if test yes = "$GCC"; then + whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' else whole_archive_flag_spec='-z allextract$convenience -z defaultextract' fi @@ -9673,10 +10933,10 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; } ;; sunos4*) - if test "x$host_vendor" = xsequent; then + if test sequent = "$host_vendor"; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. - archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi @@ -9725,43 +10985,43 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; } ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) - no_undefined_flag='${wl}-z,text' + no_undefined_flag='$wl-z,text' archive_cmds_need_lc=no hardcode_shlibpath_var=no runpath_var='LD_RUN_PATH' - if test "$GCC" = yes; then - archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + if test yes = "$GCC"; then + archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else - archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) - # Note: We can NOT use -z defs as we might desire, because we do not + # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. - no_undefined_flag='${wl}-z,text' - allow_undefined_flag='${wl}-z,nodefs' + no_undefined_flag='$wl-z,text' + allow_undefined_flag='$wl-z,nodefs' archive_cmds_need_lc=no hardcode_shlibpath_var=no - hardcode_libdir_flag_spec='${wl}-R,$libdir' + hardcode_libdir_flag_spec='$wl-R,$libdir' hardcode_libdir_separator=':' link_all_deplibs=yes - export_dynamic_flag_spec='${wl}-Bexport' + export_dynamic_flag_spec='$wl-Bexport' runpath_var='LD_RUN_PATH' - if test "$GCC" = yes; then - archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + if test yes = "$GCC"; then + archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else - archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; @@ -9776,18 +11036,18 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; } ;; esac - if test x$host_vendor = xsni; then + if test sni = "$host_vendor"; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - export_dynamic_flag_spec='${wl}-Blargedynsym' + export_dynamic_flag_spec='$wl-Blargedynsym' ;; esac fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 -$as_echo "$ld_shlibs" >&6; } -test "$ld_shlibs" = no && can_build_shared=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 +printf "%s\n" "$ld_shlibs" >&6; } +test no = "$ld_shlibs" && can_build_shared=no with_gnu_ld=$with_gnu_ld @@ -9813,7 +11073,7 @@ x|xyes) # Assume -lc should be added archive_cmds_need_lc=yes - if test "$enable_shared" = yes && test "$GCC" = yes; then + if test yes,yes = "$GCC,$enable_shared"; then case $archive_cmds in *'~'*) # FIXME: we may have to deal with multi-command sequences. @@ -9822,18 +11082,19 @@ x|xyes) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 -$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } -if ${lt_cv_archive_cmds_need_lc+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +printf %s "checking whether -lc should be explicitly linked in... " >&6; } +if test ${lt_cv_archive_cmds_need_lc+y} +then : + printf %s "(cached) " >&6 +else $as_nop $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest @@ -9851,7 +11112,7 @@ else if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc=no @@ -9865,8 +11126,8 @@ else $RM conftest* fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 -$as_echo "$lt_cv_archive_cmds_need_lc" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 +printf "%s\n" "$lt_cv_archive_cmds_need_lc" >&6; } archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc ;; esac @@ -10025,17 +11286,17 @@ esac - { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 -$as_echo_n "checking dynamic linker characteristics... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +printf %s "checking dynamic linker characteristics... " >&6; } -if test "$GCC" = yes; then +if test yes = "$GCC"; then case $host_os in - darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; - *) lt_awk_arg="/^libraries:/" ;; + darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; + *) lt_awk_arg='/^libraries:/' ;; esac case $host_os in - mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; - *) lt_sed_strip_eq="s,=/,/,g" ;; + mingw* | windows* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;; + *) lt_sed_strip_eq='s|=/|/|g' ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in @@ -10054,8 +11315,8 @@ if test "$GCC" = yes; then # and add multilib dir if necessary... lt_tmp_lt_search_path_spec= lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` - # ...but if some path already ends with the multilib dir we assume - # that all is fine and trust -print-search-dirs as is (GCC 4.2 or newer). + # ...but if some path component already ends with the multilib dir we assume + # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). case "$lt_multi_os_dir; $lt_search_path_spec " in "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) lt_multi_os_dir= @@ -10070,16 +11331,16 @@ if test "$GCC" = yes; then fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' -BEGIN {RS=" "; FS="/|\n";} { - lt_foo=""; - lt_count=0; +BEGIN {RS = " "; FS = "/|\n";} { + lt_foo = ""; + lt_count = 0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { - lt_foo="/" $lt_i lt_foo; + lt_foo = "/" $lt_i lt_foo; } else { lt_count--; } @@ -10092,8 +11353,8 @@ BEGIN {RS=" "; FS="/|\n";} { # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in - mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ - $SED 's,/\([A-Za-z]:\),\1,g'` ;; + mingw* | windows* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's|/\([A-Za-z]:\)|\1|g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else @@ -10102,7 +11363,7 @@ fi library_names_spec= libname_spec='lib$name' soname_spec= -shrext_cmds=".so" +shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= @@ -10119,14 +11380,16 @@ hardcode_into_libs=no # flags to be left without arguments need_version=unknown + + case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. - soname_spec='${libname}${release}${shared_ext}$major' + soname_spec='$libname$release$shared_ext$major' ;; aix[4-9]*) @@ -10134,41 +11397,91 @@ aix[4-9]*) need_lib_prefix=no need_version=no hardcode_into_libs=yes - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 - library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with - # the line `#! .'. This would cause the generated library to - # depend on `.', always an invalid library. This was fixed in + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' - echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac - # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # Using Import Files as archive members, it is possible to support + # filename-based versioning of shared library archives on AIX. While + # this would work for both with and without runtime linking, it will + # prevent static linking of such archives. So we do filename-based + # shared library versioning with .so extension only, which is used + # when both runtime linking and shared linking is enabled. + # Unfortunately, runtime linking may impact performance, so we do + # not want this to be the default eventually. Also, we use the + # versioned .so libs for executables only if there is the -brtl + # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. + # To allow for filename-based versioning support, we need to create + # libNAME.so.V as an archive file, containing: + # *) an Import File, referring to the versioned filename of the + # archive as well as the shared archive member, telling the + # bitwidth (32 or 64) of that shared object, and providing the + # list of exported symbols of that shared object, eventually + # decorated with the 'weak' keyword + # *) the shared object with the F_LOADONLY flag set, to really avoid + # it being seen by the linker. + # At run time we better use the real file rather than another symlink, + # but for link time we create the symlink libNAME.so -> libNAME.so.V + + case $with_aix_soname,$aix_use_runtimelinking in + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. - if test "$aix_use_runtimelinking" = yes; then + aix,yes) # traditional libtool + dynamic_linker='AIX unversionable lib.so' # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - else + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + aix,no) # traditional AIX only + dynamic_linker='AIX lib.a(lib.so.V)' # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. - library_names_spec='${libname}${release}.a $libname.a' - soname_spec='${libname}${release}${shared_ext}$major' - fi + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + ;; + svr4,*) # full svr4 only + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,yes) # both, prefer svr4 + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # unpreferred sharedlib libNAME.a needs extra handling + postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' + postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,no) # both, prefer aix + dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling + postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' + postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' + ;; + esac shlibpath_var=LIBPATH fi ;; @@ -10178,18 +11491,18 @@ amigaos*) powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) - library_names_spec='${libname}${shared_ext}' + library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; @@ -10197,8 +11510,8 @@ beos*) bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" @@ -10208,9 +11521,9 @@ bsdi[45]*) # libtool to hard-code these into programs ;; -cygwin* | mingw* | pw32* | cegcc*) +cygwin* | mingw* | windows* | pw32* | cegcc*) version_type=windows - shrext_cmds=".dll" + shrext_cmds=.dll need_version=no need_lib_prefix=no @@ -10219,8 +11532,8 @@ cygwin* | mingw* | pw32* | cegcc*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ @@ -10236,32 +11549,32 @@ cygwin* | mingw* | pw32* | cegcc*) case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' - #soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - soname_spec='`echo ${libname} | sed -e 's/^lib//'`${shared_ext}' + #soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + soname_spec='`echo $libname | sed -e 's/^lib//'`$shared_ext' # SDL customization sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ;; - mingw* | cegcc*) + mingw* | windows* | cegcc*) # MinGW DLLs use traditional 'lib' prefix - #soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - soname_spec='`echo ${libname} | $SED -e 's/^lib//'`${shared_ext}' + #soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + soname_spec='`echo $libname | $SED -e 's/^lib//'`$shared_ext' # SDL customization ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; - *,cl*) - # Native MSVC + *,cl* | *,icl*) + # Native MSVC or ICC libname_spec='$name' - soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - library_names_spec='${libname}.dll.lib' + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' case $build_os in - mingw*) + mingw* | windows*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' @@ -10285,7 +11598,7 @@ cygwin* | mingw* | pw32* | cegcc*) sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) - sys_lib_search_path_spec="$LIB" + sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` @@ -10298,8 +11611,8 @@ cygwin* | mingw* | pw32* | cegcc*) esac # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' @@ -10311,8 +11624,8 @@ cygwin* | mingw* | pw32* | cegcc*) ;; *) - # Assume MSVC wrapper - library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + # Assume MSVC and ICC wrapper + library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac @@ -10325,8 +11638,8 @@ darwin* | rhapsody*) version_type=darwin need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' - soname_spec='${libname}${release}${major}$shared_ext' + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' @@ -10339,12 +11652,12 @@ dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; -freebsd* | dragonfly*) +freebsd* | dragonfly* | midnightbsd*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then @@ -10358,12 +11671,13 @@ freebsd* | dragonfly*) version_type=freebsd-$objformat case $version_type in freebsd-elf*) - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' need_version=no need_lib_prefix=no ;; freebsd-*) - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac @@ -10388,26 +11702,15 @@ freebsd* | dragonfly*) esac ;; -gnu*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH - shlibpath_overrides_runpath=yes + shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; @@ -10425,14 +11728,15 @@ hpux9* | hpux10* | hpux11*) dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - if test "X$HPUX_IA64_MODE" = X32; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' @@ -10440,8 +11744,8 @@ hpux9* | hpux10* | hpux11*) dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; @@ -10450,8 +11754,8 @@ hpux9* | hpux10* | hpux11*) dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... @@ -10464,8 +11768,8 @@ interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no @@ -10476,7 +11780,7 @@ irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) - if test "$lt_cv_prog_gnu_ld" = yes; then + if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix @@ -10484,8 +11788,8 @@ irix5* | irix6* | nonstopux*) esac need_lib_prefix=no need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= @@ -10504,8 +11808,8 @@ irix5* | irix6* | nonstopux*) esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; @@ -10514,21 +11818,42 @@ linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + hardcode_libdir_flag_spec='-L$libdir' + ;; + # This must be glibc/ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu) +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH - if ${lt_cv_shlibpath_overrides_runpath+:} false; then : - $as_echo_n "(cached) " >&6 -else + if test ${lt_cv_shlibpath_overrides_runpath+y} +then : + printf %s "(cached) " >&6 +else $as_nop lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir @@ -10538,19 +11863,21 @@ else /* end confdefs.h. */ int -main () +main (void) { ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : +if ac_fn_c_try_link "$LINENO" +then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null +then : lt_cv_shlibpath_overrides_runpath=yes fi fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir @@ -10564,10 +11891,18 @@ fi # before this can be enabled. hardcode_into_libs=yes - # Append ld.so.conf contents to the search path + # Add ABI-specific directories to the system library path. + sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" + + # Ideally, we could use ldconfig to report *all* directores which are + # searched for libraries, however this is still not possible. Aside from not + # being certain /sbin/ldconfig is available, command + # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, + # even though it is searched at run-time. Try to do the best guess by + # appending ld.so.conf contents (and includes) to the search path. if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` - sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on @@ -10584,12 +11919,12 @@ netbsd*) need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH @@ -10599,7 +11934,7 @@ netbsd*) newsos6) version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; @@ -10608,58 +11943,70 @@ newsos6) version_type=qnx need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; -openbsd*) +openbsd* | bitrig*) version_type=sunos - sys_lib_dlsearch_path_spec="/usr/lib" + sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no - # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. - case $host_os in - openbsd3.3 | openbsd3.3.*) need_version=yes ;; - *) need_version=no ;; - esac - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no + else + need_version=yes + fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - case $host_os in - openbsd2.[89] | openbsd2.[89].*) - shlibpath_overrides_runpath=no - ;; - *) - shlibpath_overrides_runpath=yes - ;; - esac - else - shlibpath_overrides_runpath=yes - fi + shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' - shrext_cmds=".dll" + shrext_cmds=.dll need_lib_prefix=no - library_names_spec='$libname${shared_ext} $libname.a' + # OS/2 can only load a DLL with a base name of 8 characters or less. +# SDL customization: removed versioning support. +# version_type=windows +# need_version=no +# soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; +# v=$($ECHO $release$versuffix | tr -d .-); +# n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); +# $ECHO $n$v`$shared_ext' + soname_spec='`test -n "$os2dllname" && libname=$os2dllname; $ECHO $libname | cut -b -8 | tr . _`$shared_ext' + library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' - shlibpath_var=LIBPATH + shlibpath_var=BEGINLIBPATH + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) @@ -10670,8 +12017,8 @@ solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes @@ -10681,11 +12028,11 @@ solaris*) sunos4*) version_type=sunos - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes - if test "$with_gnu_ld" = yes; then + if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes @@ -10693,8 +12040,8 @@ sunos4*) sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) @@ -10715,24 +12062,24 @@ sysv4 | sysv4.3*) ;; sysv4*MP*) - if test -d /usr/nec ;then + if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' - soname_spec='$libname${shared_ext}.$major' + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - version_type=freebsd-elf + version_type=sco need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes - if test "$with_gnu_ld" = yes; then + if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' @@ -10750,7 +12097,7 @@ tpf*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes @@ -10758,8 +12105,8 @@ tpf*) uts4*) version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; @@ -10767,25 +12114,31 @@ uts4*) dynamic_linker=no ;; esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 -$as_echo "$dynamic_linker" >&6; } -test "$dynamic_linker" = no && can_build_shared=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +printf "%s\n" "$dynamic_linker" >&6; } +test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then +if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi -if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then - sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" -fi -if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then - sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec +fi +# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... +configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec +# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code +func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" +# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool +configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH @@ -10874,20 +12227,29 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 -$as_echo_n "checking how to hardcode library paths into programs... " >&6; } + + + + + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +printf %s "checking how to hardcode library paths into programs... " >&6; } hardcode_action= if test -n "$hardcode_libdir_flag_spec" || test -n "$runpath_var" || - test "X$hardcode_automatic" = "Xyes" ; then + test yes = "$hardcode_automatic"; then # We can hardcode non-existent directories. - if test "$hardcode_direct" != no && + if test no != "$hardcode_direct" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one - ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && - test "$hardcode_minus_L" != no; then + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" && + test no != "$hardcode_minus_L"; then # Linking always hardcodes the temporary library directory. hardcode_action=relink else @@ -10899,15 +12261,15 @@ else # directories. hardcode_action=unsupported fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 -$as_echo "$hardcode_action" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 +printf "%s\n" "$hardcode_action" >&6; } -if test "$hardcode_action" = relink || - test "$inherit_rpath" = yes; then +if test relink = "$hardcode_action" || + test yes = "$inherit_rpath"; then # Fast installation is not supported enable_fast_install=no -elif test "$shlibpath_overrides_runpath" = yes || - test "$enable_shared" = no; then +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi @@ -10917,7 +12279,7 @@ fi - if test "x$enable_dlopen" != xyes; then + if test yes != "$enable_dlopen"; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown @@ -10927,28 +12289,29 @@ else case $host_os in beos*) - lt_cv_dlopen="load_add_on" + lt_cv_dlopen=load_add_on lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; - mingw* | pw32* | cegcc*) - lt_cv_dlopen="LoadLibrary" + mingw* | windows* | pw32* | cegcc*) + lt_cv_dlopen=LoadLibrary lt_cv_dlopen_libs= ;; cygwin*) - lt_cv_dlopen="dlopen" + lt_cv_dlopen=dlopen lt_cv_dlopen_libs= ;; darwin*) - # if libdl is installed we need to link against it - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 -$as_echo_n "checking for dlopen in -ldl... " >&6; } -if ${ac_cv_lib_dl_dlopen+:} false; then : - $as_echo_n "(cached) " >&6 -else + # if libdl is installed we need to link against it + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +printf %s "checking for dlopen in -ldl... " >&6; } +if test ${ac_cv_lib_dl_dlopen+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -10957,34 +12320,33 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char dlopen (); int -main () +main (void) { return dlopen (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_dl_dlopen=yes -else +else $as_nop ac_cv_lib_dl_dlopen=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 -$as_echo "$ac_cv_lib_dl_dlopen" >&6; } -if test "x$ac_cv_lib_dl_dlopen" = xyes; then : - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +printf "%s\n" "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes +then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl +else $as_nop - lt_cv_dlopen="dyld" + lt_cv_dlopen=dyld lt_cv_dlopen_libs= lt_cv_dlopen_self=yes @@ -10992,16 +12354,26 @@ fi ;; + tpf*) + # Don't try to run any link tests for TPF. We know it's impossible + # because TPF is a cross-compiler, and we know how we open DSOs. + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + lt_cv_dlopen_self=no + ;; + *) ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" -if test "x$ac_cv_func_shl_load" = xyes; then : - lt_cv_dlopen="shl_load" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 -$as_echo_n "checking for shl_load in -ldld... " >&6; } -if ${ac_cv_lib_dld_shl_load+:} false; then : - $as_echo_n "(cached) " >&6 -else +if test "x$ac_cv_func_shl_load" = xyes +then : + lt_cv_dlopen=shl_load +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 +printf %s "checking for shl_load in -ldld... " >&6; } +if test ${ac_cv_lib_dld_shl_load+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -11010,41 +12382,42 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char shl_load (); int -main () +main (void) { return shl_load (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_dld_shl_load=yes -else +else $as_nop ac_cv_lib_dld_shl_load=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 -$as_echo "$ac_cv_lib_dld_shl_load" >&6; } -if test "x$ac_cv_lib_dld_shl_load" = xyes; then : - lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 +printf "%s\n" "$ac_cv_lib_dld_shl_load" >&6; } +if test "x$ac_cv_lib_dld_shl_load" = xyes +then : + lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld +else $as_nop ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" -if test "x$ac_cv_func_dlopen" = xyes; then : - lt_cv_dlopen="dlopen" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 -$as_echo_n "checking for dlopen in -ldl... " >&6; } -if ${ac_cv_lib_dl_dlopen+:} false; then : - $as_echo_n "(cached) " >&6 -else +if test "x$ac_cv_func_dlopen" = xyes +then : + lt_cv_dlopen=dlopen +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +printf %s "checking for dlopen in -ldl... " >&6; } +if test ${ac_cv_lib_dl_dlopen+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -11053,37 +12426,37 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char dlopen (); int -main () +main (void) { return dlopen (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_dl_dlopen=yes -else +else $as_nop ac_cv_lib_dl_dlopen=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 -$as_echo "$ac_cv_lib_dl_dlopen" >&6; } -if test "x$ac_cv_lib_dl_dlopen" = xyes; then : - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 -$as_echo_n "checking for dlopen in -lsvld... " >&6; } -if ${ac_cv_lib_svld_dlopen+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +printf "%s\n" "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes +then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 +printf %s "checking for dlopen in -lsvld... " >&6; } +if test ${ac_cv_lib_svld_dlopen+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -11092,37 +12465,37 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char dlopen (); int -main () +main (void) { return dlopen (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_svld_dlopen=yes -else +else $as_nop ac_cv_lib_svld_dlopen=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 -$as_echo "$ac_cv_lib_svld_dlopen" >&6; } -if test "x$ac_cv_lib_svld_dlopen" = xyes; then : - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 -$as_echo_n "checking for dld_link in -ldld... " >&6; } -if ${ac_cv_lib_dld_dld_link+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 +printf "%s\n" "$ac_cv_lib_svld_dlopen" >&6; } +if test "x$ac_cv_lib_svld_dlopen" = xyes +then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 +printf %s "checking for dld_link in -ldld... " >&6; } +if test ${ac_cv_lib_dld_dld_link+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -11131,31 +12504,30 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char dld_link (); int -main () +main (void) { return dld_link (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_dld_dld_link=yes -else +else $as_nop ac_cv_lib_dld_dld_link=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 -$as_echo "$ac_cv_lib_dld_dld_link" >&6; } -if test "x$ac_cv_lib_dld_dld_link" = xyes; then : - lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 +printf "%s\n" "$ac_cv_lib_dld_dld_link" >&6; } +if test "x$ac_cv_lib_dld_dld_link" = xyes +then : + lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld fi @@ -11176,29 +12548,30 @@ fi ;; esac - if test "x$lt_cv_dlopen" != xno; then - enable_dlopen=yes - else + if test no = "$lt_cv_dlopen"; then enable_dlopen=no + else + enable_dlopen=yes fi case $lt_cv_dlopen in dlopen) - save_CPPFLAGS="$CPPFLAGS" - test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + save_CPPFLAGS=$CPPFLAGS + test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - save_LDFLAGS="$LDFLAGS" + save_LDFLAGS=$LDFLAGS wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - save_LIBS="$LIBS" + save_LIBS=$LIBS LIBS="$lt_cv_dlopen_libs $LIBS" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 -$as_echo_n "checking whether a program can dlopen itself... " >&6; } -if ${lt_cv_dlopen_self+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 +printf %s "checking whether a program can dlopen itself... " >&6; } +if test ${lt_cv_dlopen_self+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test yes = "$cross_compiling"; then : lt_cv_dlopen_self=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 @@ -11245,9 +12618,9 @@ else # endif #endif -/* When -fvisbility=hidden is used, assume the code has been annotated +/* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ -#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif @@ -11276,8 +12649,8 @@ _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in @@ -11294,17 +12667,18 @@ rm -fr conftest* fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 -$as_echo "$lt_cv_dlopen_self" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 +printf "%s\n" "$lt_cv_dlopen_self" >&6; } - if test "x$lt_cv_dlopen_self" = xyes; then + if test yes = "$lt_cv_dlopen_self"; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 -$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } -if ${lt_cv_dlopen_self_static+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 +printf %s "checking whether a statically linked program can dlopen itself... " >&6; } +if test ${lt_cv_dlopen_self_static+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test yes = "$cross_compiling"; then : lt_cv_dlopen_self_static=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 @@ -11351,9 +12725,9 @@ else # endif #endif -/* When -fvisbility=hidden is used, assume the code has been annotated +/* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ -#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif @@ -11382,8 +12756,8 @@ _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in @@ -11400,13 +12774,13 @@ rm -fr conftest* fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 -$as_echo "$lt_cv_dlopen_self_static" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 +printf "%s\n" "$lt_cv_dlopen_self_static" >&6; } fi - CPPFLAGS="$save_CPPFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" + CPPFLAGS=$save_CPPFLAGS + LDFLAGS=$save_LDFLAGS + LIBS=$save_LIBS ;; esac @@ -11439,32 +12813,43 @@ fi striplib= old_striplib= -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 -$as_echo_n "checking whether stripping libraries is possible... " >&6; } -if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 +printf %s "checking whether stripping libraries is possible... " >&6; } +if test -z "$STRIP"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP" ; then + if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + old_striplib="$STRIP --strip-debug" + striplib="$STRIP --strip-unneeded" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + else + case $host_os in + darwin*) + # FIXME - insert some real tests, host_os isn't really good enough striplib="$STRIP -x" old_striplib="$STRIP -S" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - fi - ;; - *) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - ;; - esac + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + ;; + freebsd*) + if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then + old_striplib="$STRIP --strip-debug" + striplib="$STRIP --strip-unneeded" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + fi + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + ;; + esac + fi fi @@ -11478,21 +12863,21 @@ fi - # Report which library types will actually be built - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 -$as_echo_n "checking if libtool supports shared libraries... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 -$as_echo "$can_build_shared" >&6; } + # Report what library types will actually be built + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 +printf %s "checking if libtool supports shared libraries... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 +printf "%s\n" "$can_build_shared" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 -$as_echo_n "checking whether to build shared libraries... " >&6; } - test "$can_build_shared" = "no" && enable_shared=no + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 +printf %s "checking whether to build shared libraries... " >&6; } + test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) - test "$enable_shared" = yes && enable_static=no + test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' @@ -11500,20 +12885,24 @@ $as_echo_n "checking whether to build shared libraries... " >&6; } ;; aix[4-9]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac fi ;; esac - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 -$as_echo "$enable_shared" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 +printf "%s\n" "$enable_shared" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 -$as_echo_n "checking whether to build static libraries... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 +printf %s "checking whether to build static libraries... " >&6; } # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 -$as_echo "$enable_static" >&6; } + test yes = "$enable_shared" || enable_static=yes + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 +printf "%s\n" "$enable_static" >&6; } @@ -11525,7 +12914,7 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu -CC="$lt_save_CC" +CC=$lt_save_CC @@ -11549,11 +12938,198 @@ CC="$lt_save_CC" # Only expand once: +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}windres", so it can be a program name with args. +set dummy ${ac_tool_prefix}windres; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_RC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$RC"; then + ac_cv_prog_RC="$RC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_RC="${ac_tool_prefix}windres" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS -LT_RELEASE=$SDL_MAJOR_VERSION.$SDL_MINOR_VERSION -LT_CURRENT=`expr $SDL_MICRO_VERSION - $SDL_INTERFACE_AGE` -LT_REVISION=$SDL_INTERFACE_AGE +fi +fi +RC=$ac_cv_prog_RC +if test -n "$RC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RC" >&5 +printf "%s\n" "$RC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RC"; then + ac_ct_RC=$RC + # Extract the first word of "windres", so it can be a program name with args. +set dummy windres; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_RC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_RC"; then + ac_cv_prog_ac_ct_RC="$ac_ct_RC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RC="windres" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RC=$ac_cv_prog_ac_ct_RC +if test -n "$ac_ct_RC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RC" >&5 +printf "%s\n" "$ac_ct_RC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_RC" = x; then + RC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RC=$ac_ct_RC + fi +else + RC="$ac_cv_prog_RC" +fi + + + + +# Source file extension for RC test sources. +ac_ext=rc + +# Object file extension for compiled RC test sources. +objext=o +objext_RC=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' + +# Code to be used in simple link tests +lt_simple_link_test_code=$lt_simple_compile_test_code + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC= +CC=${RC-"windres"} +CFLAGS= +compiler=$CC +compiler_RC=$CC +func_cc_basename $compiler +cc_basename=$func_cc_basename_result + +lt_cv_prog_compiler_c_o_RC=yes + +if test -n "$compiler"; then + : + + + +fi + +GCC=$lt_save_GCC +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS + + +# For historical reasons, the library name redundantly includes the major +# version twice: libSDL2-2.0.so.0. +# TODO: in SDL 3, stop using -release, which will simplify it to libSDL3.so.0 +LT_RELEASE=2.0 +# Increment this if there is an incompatible change - but if that happens, +# we should rename the library from SDL2 to SDL3, at which point this would +# reset to 0 anyway. +LT_MAJOR=0 LT_AGE=`expr $SDL_BINARY_AGE - $SDL_INTERFACE_AGE` +LT_CURRENT=`expr $LT_MAJOR + $LT_AGE` +LT_REVISION=$SDL_INTERFACE_AGE @@ -11562,6 +13138,52 @@ LT_AGE=`expr $SDL_BINARY_AGE - $SDL_INTERFACE_AGE` +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_AWK+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +printf "%s\n" "$AWK" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$AWK" && break +done ac_ext=c ac_cpp='$CPP $CPPFLAGS' @@ -11571,11 +13193,12 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else @@ -11583,11 +13206,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -11598,11 +13225,11 @@ fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -11611,11 +13238,12 @@ if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else @@ -11623,11 +13251,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -11638,11 +13270,11 @@ fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +printf "%s\n" "$ac_ct_CC" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi if test "x$ac_ct_CC" = x; then @@ -11650,8 +13282,8 @@ fi else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC @@ -11664,11 +13296,12 @@ if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else @@ -11676,11 +13309,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -11691,11 +13328,11 @@ fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -11704,11 +13341,12 @@ fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else @@ -11717,15 +13355,19 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + if test "$as_dir$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -11741,18 +13383,18 @@ if test $ac_prog_rejected = yes; then # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift - ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + ac_cv_prog_CC="$as_dir$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -11763,11 +13405,12 @@ if test -z "$CC"; then do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else @@ -11775,11 +13418,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -11790,11 +13437,11 @@ fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -11807,11 +13454,12 @@ if test -z "$CC"; then do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else @@ -11819,11 +13467,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -11834,11 +13486,11 @@ fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +printf "%s\n" "$ac_ct_CC" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -11850,8 +13502,8 @@ done else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC @@ -11859,25 +13511,129 @@ esac fi fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args. +set dummy ${ac_tool_prefix}clang; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}clang" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi -test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "clang", so it can be a program name with args. +set dummy clang; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="clang" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +printf "%s\n" "$ac_ct_CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +fi + + +test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. -$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 -for ac_option in --version -v -V -qversion; do +for ac_option in --version -v -V -qversion -version; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 +printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then @@ -11887,20 +13643,21 @@ $as_echo "$ac_try_echo"; } >&5 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 -$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } -if ${ac_cv_c_compiler_gnu+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5 +printf %s "checking whether the compiler supports GNU C... " >&6; } +if test ${ac_cv_c_compiler_gnu+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { #ifndef __GNUC__ choke me @@ -11910,29 +13667,33 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_compiler_gnu=yes -else +else $as_nop ac_compiler_gnu=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 -$as_echo "$ac_cv_c_compiler_gnu" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; } +ac_compiler_gnu=$ac_cv_c_compiler_gnu + if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi -ac_test_CFLAGS=${CFLAGS+set} +ac_test_CFLAGS=${CFLAGS+y} ac_save_CFLAGS=$CFLAGS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 -$as_echo_n "checking whether $CC accepts -g... " >&6; } -if ${ac_cv_prog_cc_g+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +printf %s "checking whether $CC accepts -g... " >&6; } +if test ${ac_cv_prog_cc_g+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no @@ -11941,57 +13702,60 @@ else /* end confdefs.h. */ int -main () +main (void) { ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_cv_prog_cc_g=yes -else +else $as_nop CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : -else +else $as_nop ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_cv_prog_cc_g=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 -$as_echo "$ac_cv_prog_cc_g" >&6; } -if test "$ac_test_CFLAGS" = set; then +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +printf "%s\n" "$ac_cv_prog_cc_g" >&6; } +if test $ac_test_CFLAGS; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then @@ -12006,94 +13770,144 @@ else CFLAGS= fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 -$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } -if ${ac_cv_prog_cc_c89+:} false; then : - $as_echo_n "(cached) " >&6 -else +ac_prog_cc_stdc=no +if test x$ac_prog_cc_stdc = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5 +printf %s "checking for $CC option to enable C11 features... " >&6; } +if test ${ac_cv_prog_cc_c11+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_prog_cc_c11=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_c_conftest_c11_program +_ACEOF +for ac_arg in '' -std=gnu11 +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_prog_cc_c11=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam + test "x$ac_cv_prog_cc_c11" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC +fi + +if test "x$ac_cv_prog_cc_c11" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else $as_nop + if test "x$ac_cv_prog_cc_c11" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5 +printf "%s\n" "$ac_cv_prog_cc_c11" >&6; } + CC="$CC $ac_cv_prog_cc_c11" +fi + ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11 + ac_prog_cc_stdc=c11 +fi +fi +if test x$ac_prog_cc_stdc = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5 +printf %s "checking for $CC option to enable C99 features... " >&6; } +if test ${ac_cv_prog_cc_c99+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_prog_cc_c99=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_c_conftest_c99_program +_ACEOF +for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99= +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_prog_cc_c99=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam + test "x$ac_cv_prog_cc_c99" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC +fi + +if test "x$ac_cv_prog_cc_c99" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else $as_nop + if test "x$ac_cv_prog_cc_c99" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 +printf "%s\n" "$ac_cv_prog_cc_c99" >&6; } + CC="$CC $ac_cv_prog_cc_c99" +fi + ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99 + ac_prog_cc_stdc=c99 +fi +fi +if test x$ac_prog_cc_stdc = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5 +printf %s "checking for $CC option to enable C89 features... " >&6; } +if test ${ac_cv_prog_cc_c89+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include -#include -struct stat; -/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ -struct buf { int x; }; -FILE * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; -{ - return p[i]; -} -static char *f (char * (*g) (char **, int), char **p, ...) -{ - char *s; - va_list v; - va_start (v,p); - s = g (p, va_arg (v,int)); - va_end (v); - return s; -} - -/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has - function prototypes and stuff, but not '\xHH' hex character constants. - These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std is added to get - proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an - array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std. */ -int osf4_cc_array ['\x00' == 0 ? 1 : -1]; - -/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters - inside strings and character constants. */ -#define FOO(x) 'x' -int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; - -int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);}; -int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); -int argc; -char **argv; -int -main () -{ -return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; - ; - return 0; -} +$ac_c_conftest_c89_program _ACEOF -for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ - -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" - if ac_fn_c_try_compile "$LINENO"; then : + if ac_fn_c_try_compile "$LINENO" +then : ac_cv_prog_cc_c89=$ac_arg fi -rm -f core conftest.err conftest.$ac_objext +rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC - fi -# AC_CACHE_VAL -case "x$ac_cv_prog_cc_c89" in - x) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 -$as_echo "none needed" >&6; } ;; - xno) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 -$as_echo "unsupported" >&6; } ;; - *) - CC="$CC $ac_cv_prog_cc_c89" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 -$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; -esac -if test "x$ac_cv_prog_cc_c89" != xno; then : +if test "x$ac_cv_prog_cc_c89" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else $as_nop + if test "x$ac_cv_prog_cc_c89" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +printf "%s\n" "$ac_cv_prog_cc_c89" >&6; } + CC="$CC $ac_cv_prog_cc_c89" +fi + ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89 + ac_prog_cc_stdc=c89 +fi fi ac_ext=c @@ -12102,6 +13916,12 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -12112,15 +13932,16 @@ if test -z "$CXX"; then CXX=$CCC else if test -n "$ac_tool_prefix"; then - for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC clang++ do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else @@ -12128,11 +13949,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -12143,11 +13968,11 @@ fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 -$as_echo "$CXX" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +printf "%s\n" "$CXX" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -12156,15 +13981,16 @@ fi fi if test -z "$CXX"; then ac_ct_CXX=$CXX - for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC clang++ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else @@ -12172,11 +13998,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CXX="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -12187,11 +14017,11 @@ fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 -$as_echo "$ac_ct_CXX" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +printf "%s\n" "$ac_ct_CXX" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -12203,8 +14033,8 @@ done else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX @@ -12214,7 +14044,7 @@ fi fi fi # Provide some information about the compiler. -$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 +printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do @@ -12224,7 +14054,7 @@ case "(($ac_try" in *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 +printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then @@ -12234,20 +14064,21 @@ $as_echo "$ac_try_echo"; } >&5 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 -$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } -if ${ac_cv_cxx_compiler_gnu+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C++" >&5 +printf %s "checking whether the compiler supports GNU C++... " >&6; } +if test ${ac_cv_cxx_compiler_gnu+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { #ifndef __GNUC__ choke me @@ -12257,29 +14088,33 @@ main () return 0; } _ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : +if ac_fn_cxx_try_compile "$LINENO" +then : ac_compiler_gnu=yes -else +else $as_nop ac_compiler_gnu=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 -$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 +printf "%s\n" "$ac_cv_cxx_compiler_gnu" >&6; } +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + if test $ac_compiler_gnu = yes; then GXX=yes else GXX= fi -ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_test_CXXFLAGS=${CXXFLAGS+y} ac_save_CXXFLAGS=$CXXFLAGS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 -$as_echo_n "checking whether $CXX accepts -g... " >&6; } -if ${ac_cv_prog_cxx_g+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 +printf %s "checking whether $CXX accepts -g... " >&6; } +if test ${ac_cv_prog_cxx_g+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no @@ -12288,57 +14123,60 @@ else /* end confdefs.h. */ int -main () +main (void) { ; return 0; } _ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : +if ac_fn_cxx_try_compile "$LINENO" +then : ac_cv_prog_cxx_g=yes -else +else $as_nop CXXFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { ; return 0; } _ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : +if ac_fn_cxx_try_compile "$LINENO" +then : -else +else $as_nop ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { ; return 0; } _ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : +if ac_fn_cxx_try_compile "$LINENO" +then : ac_cv_prog_cxx_g=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 -$as_echo "$ac_cv_prog_cxx_g" >&6; } -if test "$ac_test_CXXFLAGS" = set; then +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 +printf "%s\n" "$ac_cv_prog_cxx_g" >&6; } +if test $ac_test_CXXFLAGS; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then @@ -12353,6 +14191,100 @@ else CXXFLAGS= fi fi +ac_prog_cxx_stdcxx=no +if test x$ac_prog_cxx_stdcxx = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++11 features" >&5 +printf %s "checking for $CXX option to enable C++11 features... " >&6; } +if test ${ac_cv_prog_cxx_11+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_prog_cxx_11=no +ac_save_CXX=$CXX +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_cxx_conftest_cxx11_program +_ACEOF +for ac_arg in '' -std=gnu++11 -std=gnu++0x -std=c++11 -std=c++0x -qlanglvl=extended0x -AA +do + CXX="$ac_save_CXX $ac_arg" + if ac_fn_cxx_try_compile "$LINENO" +then : + ac_cv_prog_cxx_cxx11=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam + test "x$ac_cv_prog_cxx_cxx11" != "xno" && break +done +rm -f conftest.$ac_ext +CXX=$ac_save_CXX +fi + +if test "x$ac_cv_prog_cxx_cxx11" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else $as_nop + if test "x$ac_cv_prog_cxx_cxx11" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx11" >&5 +printf "%s\n" "$ac_cv_prog_cxx_cxx11" >&6; } + CXX="$CXX $ac_cv_prog_cxx_cxx11" +fi + ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx11 + ac_prog_cxx_stdcxx=cxx11 +fi +fi +if test x$ac_prog_cxx_stdcxx = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++98 features" >&5 +printf %s "checking for $CXX option to enable C++98 features... " >&6; } +if test ${ac_cv_prog_cxx_98+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_prog_cxx_98=no +ac_save_CXX=$CXX +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_cxx_conftest_cxx98_program +_ACEOF +for ac_arg in '' -std=gnu++98 -std=c++98 -qlanglvl=extended -AA +do + CXX="$ac_save_CXX $ac_arg" + if ac_fn_cxx_try_compile "$LINENO" +then : + ac_cv_prog_cxx_cxx98=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam + test "x$ac_cv_prog_cxx_cxx98" != "xno" && break +done +rm -f conftest.$ac_ext +CXX=$ac_save_CXX +fi + +if test "x$ac_cv_prog_cxx_cxx98" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else $as_nop + if test "x$ac_cv_prog_cxx_cxx98" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx98" >&5 +printf "%s\n" "$ac_cv_prog_cxx_cxx98" >&6; } + CXX="$CXX $ac_cv_prog_cxx_cxx98" +fi + ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx98 + ac_prog_cxx_stdcxx=cxx98 +fi +fi + ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -12363,50 +14295,46 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu func_stripname_cnf () { - case ${2} in - .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; - *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; + case $2 in + .*) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%\\\\$2\$%%"`;; + *) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%$2\$%%"`;; esac } # func_stripname_cnf - if test -n "$CXX" && ( test "X$CXX" != "Xno" && - ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || - (test "X$CXX" != "Xg++"))) ; then + if test -n "$CXX" && ( test no != "$CXX" && + ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || + (test g++ != "$CXX"))); then ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 -$as_echo_n "checking how to run the C++ preprocessor... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 +printf %s "checking how to run the C++ preprocessor... " >&6; } if test -z "$CXXCPP"; then - if ${ac_cv_prog_CXXCPP+:} false; then : - $as_echo_n "(cached) " >&6 -else - # Double quotes because CXXCPP needs to be expanded - for CXXCPP in "$CXX -E" "/lib/cpp" + if test ${ac_cv_prog_CXXCPP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + # Double quotes because $CXX needs to be expanded + for CXXCPP in "$CXX -E" cpp /lib/cpp do ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif +#include Syntax error _ACEOF -if ac_fn_cxx_try_cpp "$LINENO"; then : +if ac_fn_cxx_try_cpp "$LINENO" +then : -else +else $as_nop # Broken: fails on valid input. continue fi @@ -12418,10 +14346,11 @@ rm -f conftest.err conftest.i conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF -if ac_fn_cxx_try_cpp "$LINENO"; then : +if ac_fn_cxx_try_cpp "$LINENO" +then : # Broken: success on invalid input. continue -else +else $as_nop # Passes both tests. ac_preproc_ok=: break @@ -12431,7 +14360,8 @@ rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : +if $ac_preproc_ok +then : break fi @@ -12443,29 +14373,24 @@ fi else ac_cv_prog_CXXCPP=$CXXCPP fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 -$as_echo "$CXXCPP" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 +printf "%s\n" "$CXXCPP" >&6; } ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif +#include Syntax error _ACEOF -if ac_fn_cxx_try_cpp "$LINENO"; then : +if ac_fn_cxx_try_cpp "$LINENO" +then : -else +else $as_nop # Broken: fails on valid input. continue fi @@ -12477,10 +14402,11 @@ rm -f conftest.err conftest.i conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF -if ac_fn_cxx_try_cpp "$LINENO"; then : +if ac_fn_cxx_try_cpp "$LINENO" +then : # Broken: success on invalid input. continue -else +else $as_nop # Passes both tests. ac_preproc_ok=: break @@ -12490,11 +14416,12 @@ rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : +if $ac_preproc_ok +then : -else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +else $as_nop + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi @@ -12550,7 +14477,7 @@ objext_CXX=$objext # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. -if test "$_lt_caught_CXX_error" != yes; then +if test yes != "$_lt_caught_CXX_error"; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" @@ -12611,46 +14538,40 @@ $RM -r conftest* CFLAGS=$CXXFLAGS compiler=$CC compiler_CXX=$CC - for cc_temp in $compiler""; do - case $cc_temp in - compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; - distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; - \-*) ;; - *) break;; - esac -done -cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` + func_cc_basename $compiler +cc_basename=$func_cc_basename_result if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately - if test "$GXX" = yes; then + if test yes = "$GXX"; then lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' else lt_prog_compiler_no_builtin_flag_CXX= fi - if test "$GXX" = yes; then + if test yes = "$GXX"; then # Set up default GNU C++ configuration # Check whether --with-gnu-ld was given. -if test "${with_gnu_ld+set}" = set; then : - withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes -else +if test ${with_gnu_ld+y} +then : + withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes +else $as_nop with_gnu_ld=no fi ac_prog=ld -if test "$GCC" = yes; then +if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 -$as_echo_n "checking for ld used by $CC... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +printf %s "checking for ld used by $CC... " >&6; } case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw + *-*-mingw* | *-*-windows*) + # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; @@ -12664,7 +14585,7 @@ $as_echo_n "checking for ld used by $CC... " >&6; } while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done - test -z "$LD" && LD="$ac_prog" + test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. @@ -12675,56 +14596,58 @@ $as_echo_n "checking for ld used by $CC... " >&6; } with_gnu_ld=unknown ;; esac -elif test "$with_gnu_ld" = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 -$as_echo_n "checking for GNU ld... " >&6; } +elif test yes = "$with_gnu_ld"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +printf %s "checking for GNU ld... " >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 -$as_echo_n "checking for non-GNU ld... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +printf %s "checking for non-GNU ld... " >&6; } fi -if ${lt_cv_path_LD+:} false; then : - $as_echo_n "(cached) " >&6 -else +if test ${lt_cv_path_LD+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -z "$LD"; then - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do - IFS="$lt_save_ifs" + IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - lt_cv_path_LD="$ac_dir/$ac_prog" + lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 -$as_echo "$LD" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 +printf "%s\n" "$LD" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 -$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } -if ${lt_cv_prog_gnu_ld+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +printf %s "checking if the linker ($LD) is GNU ld... " >&6; } +if test ${lt_cv_prog_gnu_ld+y} +then : + printf %s "(cached) " >&6 +else $as_nop # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &1 &5 -$as_echo "$lt_cv_prog_gnu_ld" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5 +printf "%s\n" "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld @@ -12747,22 +14670,22 @@ with_gnu_ld=$lt_cv_prog_gnu_ld # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. - if test "$with_gnu_ld" = yes; then - archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + if test yes = "$with_gnu_ld"; then + archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' - hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' - export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) - wlarc='${wl}' + wlarc='$wl' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then - whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else whole_archive_flag_spec_CXX= fi @@ -12781,7 +14704,7 @@ with_gnu_ld=$lt_cv_prog_gnu_ld # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "[-]L"' else GXX=no @@ -12790,8 +14713,8 @@ with_gnu_ld=$lt_cv_prog_gnu_ld fi # PORTME: fill in a description of your system's C++ link characteristics - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 -$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +printf %s "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } ld_shlibs_CXX=yes case $host_os in aix3*) @@ -12799,18 +14722,30 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie ld_shlibs_CXX=no ;; aix[4-9]*) - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' - no_entry_flag="" + no_entry_flag= else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do case $ld_flag in @@ -12820,6 +14755,13 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie ;; esac done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi ;; esac @@ -12838,13 +14780,21 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie hardcode_direct_absolute_CXX=yes hardcode_libdir_separator_CXX=':' link_all_deplibs_CXX=yes - file_list_spec_CXX='${wl}-f,' + file_list_spec_CXX='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + hardcode_direct_CXX=no + hardcode_direct_absolute_CXX=no + ;; + esac - if test "$GXX" = yes; then + if test yes = "$GXX"; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` + collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then @@ -12862,53 +14812,63 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie fi esac shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' + if test yes = "$aix_use_runtimelinking"; then + shared_flag=$shared_flag' $wl-G' fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' else # not using gcc - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' else - shared_flag='${wl}-bM:SRE' + shared_flag='$wl-bM:SRE' fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' fi fi - export_dynamic_flag_spec_CXX='${wl}-bexpall' + export_dynamic_flag_spec_CXX='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. always_export_symbols_CXX=yes - if test "$aix_use_runtimelinking" = yes; then + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. - allow_undefined_flag_CXX='-berok' + # The "-G" linker flag allows undefined symbols. + no_undefined_flag_CXX='-bernotok' # Determine the default libpath from the value encoded in an empty # executable. - if test "${lt_cv_aix_libpath+set}" = set; then + if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else - if ${lt_cv_aix_libpath__CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else + if test ${lt_cv_aix_libpath__CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { ; return 0; } _ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : +if ac_fn_cxx_try_link "$LINENO" +then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { @@ -12923,10 +14883,10 @@ if ac_fn_cxx_try_link "$LINENO"; then : lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath__CXX"; then - lt_cv_aix_libpath__CXX="/usr/lib:/lib" + lt_cv_aix_libpath__CXX=/usr/lib:/lib fi fi @@ -12934,35 +14894,37 @@ fi aix_libpath=$lt_cv_aix_libpath__CXX fi - hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" + hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath" - archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else - if test "$host_cpu" = ia64; then - hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib' + if test ia64 = "$host_cpu"; then + hardcode_libdir_flag_spec_CXX='$wl-R $libdir:/usr/lib:/lib' allow_undefined_flag_CXX="-z nodefs" - archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. - if test "${lt_cv_aix_libpath+set}" = set; then + if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else - if ${lt_cv_aix_libpath__CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else + if test ${lt_cv_aix_libpath__CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { ; return 0; } _ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : +if ac_fn_cxx_try_link "$LINENO" +then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { @@ -12977,10 +14939,10 @@ if ac_fn_cxx_try_link "$LINENO"; then : lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath__CXX"; then - lt_cv_aix_libpath__CXX="/usr/lib:/lib" + lt_cv_aix_libpath__CXX=/usr/lib:/lib fi fi @@ -12988,22 +14950,34 @@ fi aix_libpath=$lt_cv_aix_libpath__CXX fi - hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" + hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. - no_undefined_flag_CXX=' ${wl}-bernotok' - allow_undefined_flag_CXX=' ${wl}-berok' - if test "$with_gnu_ld" = yes; then + no_undefined_flag_CXX=' $wl-bernotok' + allow_undefined_flag_CXX=' $wl-berok' + if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. - whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec_CXX='$convenience' fi archive_cmds_need_lc_CXX=yes - # This is similar to how AIX traditionally builds its shared - # libraries. - archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + archive_expsym_cmds_CXX='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared + # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. + archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$RM -r $output_objdir/$realname.d' fi fi ;; @@ -13013,7 +14987,7 @@ fi allow_undefined_flag_CXX=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME - archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else ld_shlibs_CXX=no fi @@ -13028,10 +15002,10 @@ fi esac ;; - cygwin* | mingw* | pw32* | cegcc*) + cygwin* | mingw* | windows* | pw32* | cegcc*) case $GXX,$cc_basename in - ,cl* | no,cl*) - # Native MSVC + ,cl* | no,cl* | ,icl* | no,icl*) + # Native MSVC or ICC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec_CXX=' ' @@ -13041,57 +15015,58 @@ fi # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" + shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. - archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' - archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; - else - $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; - fi~ - $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ - linknames=' + archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true' enable_shared_with_static_runtimes_CXX=yes # Don't use ranlib old_postinstall_cmds_CXX='chmod 644 $oldlib' postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~ - lt_tool_outputfile="@TOOL_OUTPUT@"~ - case $lt_outputfile in - *.exe|*.EXE) ;; - *) - lt_outputfile="$lt_outputfile.exe" - lt_tool_outputfile="$lt_tool_outputfile.exe" - ;; - esac~ - func_to_tool_file "$lt_outputfile"~ - if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then - $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; - $RM "$lt_outputfile.manifest"; - fi' + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec_CXX='-L$libdir' - export_dynamic_flag_spec_CXX='${wl}--export-all-symbols' + export_dynamic_flag_spec_CXX='$wl--export-all-symbols' allow_undefined_flag_CXX=unsupported always_export_symbols_CXX=no enable_shared_with_static_runtimes_CXX=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs_CXX=no fi @@ -13105,27 +15080,27 @@ fi hardcode_direct_CXX=no hardcode_automatic_CXX=yes hardcode_shlibpath_var_CXX=unsupported - if test "$lt_cv_ld_force_load" = "yes"; then - whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + if test yes = "$lt_cv_ld_force_load"; then + whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec_CXX='' fi link_all_deplibs_CXX=yes - allow_undefined_flag_CXX="$_lt_dar_allow_undefined" + allow_undefined_flag_CXX=$_lt_dar_allow_undefined case $cc_basename in - ifort*) _lt_dar_can_shared=yes ;; + ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac - if test "$_lt_dar_can_shared" = "yes"; then + if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all - archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" - module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" - archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" - module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - if test "$lt_cv_apple_cc_single_mod" != "yes"; then - archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" - archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" + archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + module_expsym_cmds_CXX="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + if test yes != "$lt_cv_apple_cc_single_mod"; then + archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" + archive_expsym_cmds_CXX="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" fi else @@ -13134,6 +15109,35 @@ fi ;; + os2*) + hardcode_libdir_flag_spec_CXX='-L$libdir' + hardcode_minus_L_CXX=yes + allow_undefined_flag_CXX=unsupported + shrext_cmds=.dll + archive_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + archive_expsym_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + old_archive_from_new_cmds_CXX='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + enable_shared_with_static_runtimes_CXX=yes + file_list_spec_CXX='@' + ;; + dgux*) case $cc_basename in ec++*) @@ -13162,24 +15166,21 @@ fi archive_cmds_need_lc_CXX=no ;; - freebsd* | dragonfly*) + freebsd* | dragonfly* | midnightbsd*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions ld_shlibs_CXX=yes ;; - gnu*) - ;; - haiku*) - archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' link_all_deplibs_CXX=yes ;; hpux9*) - hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir' hardcode_libdir_separator_CXX=: - export_dynamic_flag_spec_CXX='${wl}-E' + export_dynamic_flag_spec_CXX='$wl-E' hardcode_direct_CXX=yes hardcode_minus_L_CXX=yes # Not in the search PATH, # but as the default @@ -13191,7 +15192,7 @@ fi ld_shlibs_CXX=no ;; aCC*) - archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. @@ -13200,11 +15201,11 @@ fi # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "[-]L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) - if test "$GXX" = yes; then - archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + if test yes = "$GXX"; then + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support ld_shlibs_CXX=no @@ -13214,15 +15215,15 @@ fi ;; hpux10*|hpux11*) - if test $with_gnu_ld = no; then - hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir' hardcode_libdir_separator_CXX=: case $host_cpu in hppa*64*|ia64*) ;; *) - export_dynamic_flag_spec_CXX='${wl}-E' + export_dynamic_flag_spec_CXX='$wl-E' ;; esac fi @@ -13248,13 +15249,13 @@ fi aCC*) case $host_cpu in hppa*64*) - archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_cmds_CXX='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) - archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) - archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists @@ -13265,20 +15266,20 @@ fi # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "[-]L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) - if test "$GXX" = yes; then - if test $with_gnu_ld = no; then + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then case $host_cpu in hppa*64*) - archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_cmds_CXX='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) - archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) - archive_cmds_CXX='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi @@ -13293,22 +15294,22 @@ fi interix[3-9]*) hardcode_direct_CXX=no hardcode_shlibpath_var_CXX=no - hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' - export_dynamic_flag_spec_CXX='${wl}-E' + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + export_dynamic_flag_spec_CXX='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. - archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_CXX='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ - archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is @@ -13317,22 +15318,22 @@ fi old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) - if test "$GXX" = yes; then - if test "$with_gnu_ld" = no; then - archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else - archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' fi fi link_all_deplibs_CXX=yes ;; esac - hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' hardcode_libdir_separator_CXX=: inherit_rpath_CXX=yes ;; - linux* | k*bsd*-gnu | kopensolaris*-gnu) + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler @@ -13340,8 +15341,8 @@ fi # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. - archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. @@ -13350,10 +15351,10 @@ fi # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' - hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' - export_dynamic_flag_spec_CXX='${wl}--export-dynamic' + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. @@ -13367,59 +15368,59 @@ fi # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) - archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac - archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac archive_cmds_need_lc_CXX=no - hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' - export_dynamic_flag_spec_CXX='${wl}--export-dynamic' - whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [1-5].* | *pgcpp\ [1-5].*) prelink_cmds_CXX='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ - compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' old_archive_cmds_CXX='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ - $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ - $RANLIB $oldlib' + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' archive_cmds_CXX='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ - $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='tpldir=Template.dir~ - rm -rf $tpldir~ - $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ - $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols - archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' - archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac - hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' - export_dynamic_flag_spec_CXX='${wl}--export-dynamic' - whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + hardcode_libdir_flag_spec_CXX='$wl--rpath $wl$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + whole_archive_flag_spec_CXX='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' ;; cxx*) # Compaq C++ - archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec_CXX='-rpath $libdir' @@ -13433,18 +15434,18 @@ fi # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld - hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' - export_dynamic_flag_spec_CXX='${wl}--export-dynamic' - archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' + export_dynamic_flag_spec_CXX='$wl--export-dynamic' + archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + if test yes = "$supports_anon_versioning"; then archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi ;; *) @@ -13452,10 +15453,10 @@ fi *Sun\ C*) # Sun C++ 5.9 no_undefined_flag_CXX=' -zdefs' - archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' - archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' hardcode_libdir_flag_spec_CXX='-R$libdir' - whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' + whole_archive_flag_spec_CXX='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object_CXX=yes # Not sure whether something based on @@ -13513,22 +15514,17 @@ fi ld_shlibs_CXX=yes ;; - openbsd2*) - # C++ shared libraries are fairly broken - ld_shlibs_CXX=no - ;; - - openbsd*) + openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then hardcode_direct_CXX=yes hardcode_shlibpath_var_CXX=no hardcode_direct_absolute_CXX=yes archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' - hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' - export_dynamic_flag_spec_CXX='${wl}-E' - whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' + export_dynamic_flag_spec_CXX='$wl-E' + whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else @@ -13544,9 +15540,9 @@ fi # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. - archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' - hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' hardcode_libdir_separator_CXX=: # Archives containing C++ object files must be created using @@ -13564,17 +15560,17 @@ fi cxx*) case $host in osf3*) - allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' - hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*' + archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' ;; *) allow_undefined_flag_CXX=' -expect_unresolved \*' - archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' + archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ - echo "-hidden">> $lib.exp~ - $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ - $RM $lib.exp' + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ + $RM $lib.exp' hardcode_libdir_flag_spec_CXX='-rpath $libdir' ;; esac @@ -13589,27 +15585,27 @@ fi # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' + if test yes,no = "$GXX,$with_gnu_ld"; then + allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*' case $host in osf3*) - archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + archive_cmds_CXX='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; *) - archive_cmds_CXX='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; esac - hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' + hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "[-]L"' else # FIXME: insert proper C++ library support @@ -13649,9 +15645,9 @@ fi # Sun C++ 4.2, 5.x and Centerline C++ archive_cmds_need_lc_CXX=yes no_undefined_flag_CXX=' -zdefs' - archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' hardcode_libdir_flag_spec_CXX='-R$libdir' hardcode_shlibpath_var_CXX=no @@ -13659,7 +15655,7 @@ fi solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, - # but understands `-z linker_flag'. + # but understands '-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' ;; @@ -13676,42 +15672,42 @@ fi ;; gcx*) # Green Hills C++ Compiler - archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker - if test "$GXX" = yes && test "$with_gnu_ld" = no; then - no_undefined_flag_CXX=' ${wl}-z ${wl}defs' + if test yes,no = "$GXX,$with_gnu_ld"; then + no_undefined_flag_CXX=' $wl-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then - archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "[-]L"' else - # g++ 2.7 appears to require `-G' NOT `-shared' on this + # g++ 2.7 appears to require '-G' NOT '-shared' on this # platform. - archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + archive_cmds_CXX='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "[-]L"' fi - hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir' + hardcode_libdir_flag_spec_CXX='$wl-R $wl$libdir' case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) - whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + whole_archive_flag_spec_CXX='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' ;; esac fi @@ -13720,52 +15716,52 @@ fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) - no_undefined_flag_CXX='${wl}-z,text' + no_undefined_flag_CXX='$wl-z,text' archive_cmds_need_lc_CXX=no hardcode_shlibpath_var_CXX=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) - archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) - archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) - # Note: We can NOT use -z defs as we might desire, because we do not + # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. - no_undefined_flag_CXX='${wl}-z,text' - allow_undefined_flag_CXX='${wl}-z,nodefs' + no_undefined_flag_CXX='$wl-z,text' + allow_undefined_flag_CXX='$wl-z,nodefs' archive_cmds_need_lc_CXX=no hardcode_shlibpath_var_CXX=no - hardcode_libdir_flag_spec_CXX='${wl}-R,$libdir' + hardcode_libdir_flag_spec_CXX='$wl-R,$libdir' hardcode_libdir_separator_CXX=':' link_all_deplibs_CXX=yes - export_dynamic_flag_spec_CXX='${wl}-Bexport' + export_dynamic_flag_spec_CXX='$wl-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) - archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~ - '"$old_archive_cmds_CXX" + '"$old_archive_cmds_CXX" reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~ - '"$reload_cmds_CXX" + '"$reload_cmds_CXX" ;; *) - archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; @@ -13795,12 +15791,12 @@ fi ;; esac - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 -$as_echo "$ld_shlibs_CXX" >&6; } - test "$ld_shlibs_CXX" = no && can_build_shared=no + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +printf "%s\n" "$ld_shlibs_CXX" >&6; } + test no = "$ld_shlibs_CXX" && can_build_shared=no - GCC_CXX="$GXX" - LD_CXX="$LD" + GCC_CXX=$GXX + LD_CXX=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change @@ -13834,7 +15830,7 @@ esac if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Parse the compiler output and extract the necessary # objects, libraries and library flags. @@ -13844,13 +15840,14 @@ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do - case ${prev}${p} in + case $prev$p in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. - if test $p = "-L" || - test $p = "-R"; then + if test x-L = "x$p" || + test x-R = "x$p" || + test x-l = "x$p"; then prev=$p continue fi @@ -13866,16 +15863,16 @@ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac - if test "$pre_test_object_deps_done" = no; then - case ${prev} in + if test no = "$pre_test_object_deps_done"; then + case $prev in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$compiler_lib_search_path_CXX"; then - compiler_lib_search_path_CXX="${prev}${p}" + compiler_lib_search_path_CXX=$prev$p else - compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}" + compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} $prev$p" fi ;; # The "-l" case would never come before the object being @@ -13883,9 +15880,9 @@ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 esac else if test -z "$postdeps_CXX"; then - postdeps_CXX="${prev}${p}" + postdeps_CXX=$prev$p else - postdeps_CXX="${postdeps_CXX} ${prev}${p}" + postdeps_CXX="${postdeps_CXX} $prev$p" fi fi prev= @@ -13900,15 +15897,15 @@ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 continue fi - if test "$pre_test_object_deps_done" = no; then + if test no = "$pre_test_object_deps_done"; then if test -z "$predep_objects_CXX"; then - predep_objects_CXX="$p" + predep_objects_CXX=$p else predep_objects_CXX="$predep_objects_CXX $p" fi else if test -z "$postdep_objects_CXX"; then - postdep_objects_CXX="$p" + postdep_objects_CXX=$p else postdep_objects_CXX="$postdep_objects_CXX $p" fi @@ -13938,51 +15935,6 @@ interix[3-9]*) postdep_objects_CXX= postdeps_CXX= ;; - -linux*) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C++ 5.9 - - # The more standards-conforming stlport4 library is - # incompatible with the Cstd library. Avoid specifying - # it if it's in CXXFLAGS. Ignore libCrun as - # -library=stlport4 depends on it. - case " $CXX $CXXFLAGS " in - *" -library=stlport4 "*) - solaris_use_stlport4=yes - ;; - esac - - if test "$solaris_use_stlport4" != yes; then - postdeps_CXX='-library=Cstd -library=Crun' - fi - ;; - esac - ;; - -solaris*) - case $cc_basename in - CC* | sunCC*) - # The more standards-conforming stlport4 library is - # incompatible with the Cstd library. Avoid specifying - # it if it's in CXXFLAGS. Ignore libCrun as - # -library=stlport4 depends on it. - case " $CXX $CXXFLAGS " in - *" -library=stlport4 "*) - solaris_use_stlport4=yes - ;; - esac - - # Adding this requires a known-good setup of shared libraries for - # Sun compiler versions before 5.6, else PIC objects from an old - # archive will be linked into the output, leading to subtle bugs. - if test "$solaris_use_stlport4" != yes; then - postdeps_CXX='-library=Cstd -library=Crun' - fi - ;; - esac - ;; esac @@ -13991,7 +15943,7 @@ case " $postdeps_CXX " in esac compiler_lib_search_dirs_CXX= if test -n "${compiler_lib_search_path_CXX}"; then - compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` + compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | $SED -e 's! -L! !g' -e 's!^ !!'` fi @@ -14030,17 +15982,18 @@ lt_prog_compiler_static_CXX= # C++ specific cases for pic, static, wl, etc. - if test "$GXX" = yes; then + if test yes = "$GXX"; then lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='-static' case $host_os in aix*) # All AIX code is PIC. - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_CXX='-Bstatic' fi + lt_prog_compiler_pic_CXX='-fPIC' ;; amigaos*) @@ -14051,8 +16004,8 @@ lt_prog_compiler_static_CXX= ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' ;; esac @@ -14061,12 +16014,17 @@ lt_prog_compiler_static_CXX= beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; - mingw* | cygwin* | os2* | pw32* | cegcc*) + mingw* | windows* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic_CXX='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static_CXX='$wl-static' + ;; + esac ;; darwin* | rhapsody*) # PIC is the default on this platform @@ -14116,7 +16074,7 @@ lt_prog_compiler_static_CXX= case $host_os in aix[4-9]*) # All AIX code is PIC. - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_CXX='-Bstatic' else @@ -14131,7 +16089,7 @@ lt_prog_compiler_static_CXX= ;; esac ;; - mingw* | cygwin* | os2* | pw32* | cegcc*) + mingw* | windows* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic_CXX='-DDLL_EXPORT' @@ -14149,21 +16107,21 @@ lt_prog_compiler_static_CXX= ;; esac ;; - freebsd* | dragonfly*) + freebsd* | dragonfly* | midnightbsd*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' - lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' - if test "$host_cpu" != ia64; then + lt_prog_compiler_static_CXX='$wl-a ${wl}archive' + if test ia64 != "$host_cpu"; then lt_prog_compiler_pic_CXX='+Z' fi ;; aCC*) lt_prog_compiler_wl_CXX='-Wl,' - lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' + lt_prog_compiler_static_CXX='$wl-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default @@ -14192,7 +16150,7 @@ lt_prog_compiler_static_CXX= ;; esac ;; - linux* | k*bsd*-gnu | kopensolaris*-gnu) + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # KAI C++ Compiler @@ -14200,7 +16158,7 @@ lt_prog_compiler_static_CXX= lt_prog_compiler_pic_CXX='-fPIC' ;; ecpc* ) - # old Intel C++ for x86_64 which still supported -KPIC. + # old Intel C++ for x86_64, which still supported -KPIC. lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-static' @@ -14345,7 +16303,7 @@ lt_prog_compiler_static_CXX= fi case $host_os in - # For platforms which do not support PIC, -DPIC is meaningless: + # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic_CXX= ;; @@ -14354,30 +16312,32 @@ case $host_os in ;; esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 -$as_echo_n "checking for $compiler option to produce PIC... " >&6; } -if ${lt_cv_prog_compiler_pic_CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +printf %s "checking for $compiler option to produce PIC... " >&6; } +if test ${lt_cv_prog_compiler_pic_CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5 -$as_echo "$lt_cv_prog_compiler_pic_CXX" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5 +printf "%s\n" "$lt_cv_prog_compiler_pic_CXX" >&6; } lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic_CXX"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 -$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } -if ${lt_cv_prog_compiler_pic_works_CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 +printf %s "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } +if test ${lt_cv_prog_compiler_pic_works_CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop lt_cv_prog_compiler_pic_works_CXX=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" + lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins @@ -14404,10 +16364,10 @@ else $RM conftest* fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 -$as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 +printf "%s\n" "$lt_cv_prog_compiler_pic_works_CXX" >&6; } -if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; then +if test yes = "$lt_cv_prog_compiler_pic_works_CXX"; then case $lt_prog_compiler_pic_CXX in "" | " "*) ;; *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; @@ -14427,13 +16387,14 @@ fi # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 -$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } -if ${lt_cv_prog_compiler_static_works_CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +printf %s "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if test ${lt_cv_prog_compiler_static_works_CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop lt_cv_prog_compiler_static_works_CXX=no - save_LDFLAGS="$LDFLAGS" + save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then @@ -14452,13 +16413,13 @@ else fi fi $RM -r conftest* - LDFLAGS="$save_LDFLAGS" + LDFLAGS=$save_LDFLAGS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 -$as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 +printf "%s\n" "$lt_cv_prog_compiler_static_works_CXX" >&6; } -if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then +if test yes = "$lt_cv_prog_compiler_static_works_CXX"; then : else lt_prog_compiler_static_CXX= @@ -14467,11 +16428,12 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 -$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } -if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if test ${lt_cv_prog_compiler_c_o_CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop lt_cv_prog_compiler_c_o_CXX=no $RM -r conftest 2>/dev/null mkdir conftest @@ -14514,16 +16476,17 @@ else $RM conftest* fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 -$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +printf "%s\n" "$lt_cv_prog_compiler_c_o_CXX" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 -$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } -if ${lt_cv_prog_compiler_c_o_CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if test ${lt_cv_prog_compiler_c_o_CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop lt_cv_prog_compiler_c_o_CXX=no $RM -r conftest 2>/dev/null mkdir conftest @@ -14566,28 +16529,28 @@ else $RM conftest* fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 -$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 +printf "%s\n" "$lt_cv_prog_compiler_c_o_CXX" >&6; } -hard_links="nottested" -if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then +hard_links=nottested +if test no = "$lt_cv_prog_compiler_c_o_CXX" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 -$as_echo_n "checking if we can lock with hard links... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +printf %s "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 -$as_echo "$hard_links" >&6; } - if test "$hard_links" = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 -$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +printf "%s\n" "$hard_links" >&6; } + if test no = "$hard_links"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 +printf "%s\n" "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} need_locks=warn fi else @@ -14596,29 +16559,33 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 -$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +printf %s "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' case $host_os in aix[4-9]*) # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - # Also, AIX nm treats weak defined symbols like other global defined - # symbols, whereas GNU nm marks them as "W". + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then - export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else - export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' + export_symbols_cmds_CXX='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi ;; pw32*) - export_symbols_cmds_CXX="$ltdll_cmds" + export_symbols_cmds_CXX=$ltdll_cmds ;; - cygwin* | mingw* | cegcc*) + cygwin* | mingw* | windows* | cegcc*) case $cc_basename in - cl*) + cl* | icl*) exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) @@ -14632,9 +16599,9 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie ;; esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 -$as_echo "$ld_shlibs_CXX" >&6; } -test "$ld_shlibs_CXX" = no && can_build_shared=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 +printf "%s\n" "$ld_shlibs_CXX" >&6; } +test no = "$ld_shlibs_CXX" && can_build_shared=no with_gnu_ld_CXX=$with_gnu_ld @@ -14651,7 +16618,7 @@ x|xyes) # Assume -lc should be added archive_cmds_need_lc_CXX=yes - if test "$enable_shared" = yes && test "$GCC" = yes; then + if test yes,yes = "$GCC,$enable_shared"; then case $archive_cmds_CXX in *'~'*) # FIXME: we may have to deal with multi-command sequences. @@ -14660,18 +16627,19 @@ x|xyes) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 -$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } -if ${lt_cv_archive_cmds_need_lc_CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +printf %s "checking whether -lc should be explicitly linked in... " >&6; } +if test ${lt_cv_archive_cmds_need_lc_CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest @@ -14689,7 +16657,7 @@ else if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc_CXX=no @@ -14703,8 +16671,8 @@ else $RM conftest* fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5 -$as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5 +printf "%s\n" "$lt_cv_archive_cmds_need_lc_CXX" >&6; } archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX ;; esac @@ -14773,13 +16741,13 @@ esac - { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 -$as_echo_n "checking dynamic linker characteristics... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +printf %s "checking dynamic linker characteristics... " >&6; } library_names_spec= libname_spec='lib$name' soname_spec= -shrext_cmds=".so" +shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= @@ -14796,14 +16764,16 @@ hardcode_into_libs=no # flags to be left without arguments need_version=unknown + + case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. - soname_spec='${libname}${release}${shared_ext}$major' + soname_spec='$libname$release$shared_ext$major' ;; aix[4-9]*) @@ -14811,41 +16781,91 @@ aix[4-9]*) need_lib_prefix=no need_version=no hardcode_into_libs=yes - if test "$host_cpu" = ia64; then + if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 - library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with - # the line `#! .'. This would cause the generated library to - # depend on `.', always an invalid library. This was fixed in + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' - echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac - # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # Using Import Files as archive members, it is possible to support + # filename-based versioning of shared library archives on AIX. While + # this would work for both with and without runtime linking, it will + # prevent static linking of such archives. So we do filename-based + # shared library versioning with .so extension only, which is used + # when both runtime linking and shared linking is enabled. + # Unfortunately, runtime linking may impact performance, so we do + # not want this to be the default eventually. Also, we use the + # versioned .so libs for executables only if there is the -brtl + # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. + # To allow for filename-based versioning support, we need to create + # libNAME.so.V as an archive file, containing: + # *) an Import File, referring to the versioned filename of the + # archive as well as the shared archive member, telling the + # bitwidth (32 or 64) of that shared object, and providing the + # list of exported symbols of that shared object, eventually + # decorated with the 'weak' keyword + # *) the shared object with the F_LOADONLY flag set, to really avoid + # it being seen by the linker. + # At run time we better use the real file rather than another symlink, + # but for link time we create the symlink libNAME.so -> libNAME.so.V + + case $with_aix_soname,$aix_use_runtimelinking in + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. - if test "$aix_use_runtimelinking" = yes; then + aix,yes) # traditional libtool + dynamic_linker='AIX unversionable lib.so' # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - else + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + aix,no) # traditional AIX only + dynamic_linker='AIX lib.a(lib.so.V)' # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. - library_names_spec='${libname}${release}.a $libname.a' - soname_spec='${libname}${release}${shared_ext}$major' - fi + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + ;; + svr4,*) # full svr4 only + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,yes) # both, prefer svr4 + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # unpreferred sharedlib libNAME.a needs extra handling + postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' + postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,no) # both, prefer aix + dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling + postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' + postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' + ;; + esac shlibpath_var=LIBPATH fi ;; @@ -14855,18 +16875,18 @@ amigaos*) powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) - library_names_spec='${libname}${shared_ext}' + library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; @@ -14874,8 +16894,8 @@ beos*) bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" @@ -14885,9 +16905,9 @@ bsdi[45]*) # libtool to hard-code these into programs ;; -cygwin* | mingw* | pw32* | cegcc*) +cygwin* | mingw* | windows* | pw32* | cegcc*) version_type=windows - shrext_cmds=".dll" + shrext_cmds=.dll need_version=no need_lib_prefix=no @@ -14896,8 +16916,8 @@ cygwin* | mingw* | pw32* | cegcc*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ @@ -14913,31 +16933,31 @@ cygwin* | mingw* | pw32* | cegcc*) case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' - #soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - soname_spec='`echo ${libname} | sed -e 's/^lib//'`${shared_ext}' + #soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + soname_spec='`echo $libname | sed -e 's/^lib//'`$shared_ext' # SDL customization ;; - mingw* | cegcc*) + mingw* | windows* | cegcc*) # MinGW DLLs use traditional 'lib' prefix - #soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' - soname_spec='`echo ${libname} | $SED -e 's/^lib//'`${shared_ext}' + #soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + soname_spec='`echo $libname | $SED -e 's/^lib//'`$shared_ext' # SDL customization ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; - *,cl*) - # Native MSVC + *,cl* | *,icl*) + # Native MSVC or ICC libname_spec='$name' - soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - library_names_spec='${libname}.dll.lib' + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' case $build_os in - mingw*) + mingw* | windows*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' @@ -14961,7 +16981,7 @@ cygwin* | mingw* | pw32* | cegcc*) sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) - sys_lib_search_path_spec="$LIB" + sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` @@ -14974,8 +16994,8 @@ cygwin* | mingw* | pw32* | cegcc*) esac # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' @@ -14987,8 +17007,8 @@ cygwin* | mingw* | pw32* | cegcc*) ;; *) - # Assume MSVC wrapper - library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' + # Assume MSVC and ICC wrapper + library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac @@ -15001,8 +17021,8 @@ darwin* | rhapsody*) version_type=darwin need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' - soname_spec='${libname}${release}${major}$shared_ext' + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' @@ -15014,12 +17034,12 @@ dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; -freebsd* | dragonfly*) +freebsd* | dragonfly* | midnightbsd*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then @@ -15033,12 +17053,13 @@ freebsd* | dragonfly*) version_type=freebsd-$objformat case $version_type in freebsd-elf*) - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' need_version=no need_lib_prefix=no ;; freebsd-*) - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac @@ -15063,26 +17084,15 @@ freebsd* | dragonfly*) esac ;; -gnu*) - version_type=linux # correct to gnu/linux during the next big refactor - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH - shlibpath_overrides_runpath=yes + shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; @@ -15100,14 +17110,15 @@ hpux9* | hpux10* | hpux11*) dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - if test "X$HPUX_IA64_MODE" = X32; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' @@ -15115,8 +17126,8 @@ hpux9* | hpux10* | hpux11*) dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; @@ -15125,8 +17136,8 @@ hpux9* | hpux10* | hpux11*) dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... @@ -15139,8 +17150,8 @@ interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no @@ -15151,7 +17162,7 @@ irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) - if test "$lt_cv_prog_gnu_ld" = yes; then + if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix @@ -15159,8 +17170,8 @@ irix5* | irix6* | nonstopux*) esac need_lib_prefix=no need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= @@ -15179,8 +17190,8 @@ irix5* | irix6* | nonstopux*) esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; @@ -15189,21 +17200,42 @@ linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + hardcode_libdir_flag_spec_CXX='-L$libdir' + ;; + # This must be glibc/ELF. -linux* | k*bsd*-gnu | kopensolaris*-gnu) +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH - if ${lt_cv_shlibpath_overrides_runpath+:} false; then : - $as_echo_n "(cached) " >&6 -else + if test ${lt_cv_shlibpath_overrides_runpath+y} +then : + printf %s "(cached) " >&6 +else $as_nop lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir @@ -15213,19 +17245,21 @@ else /* end confdefs.h. */ int -main () +main (void) { ; return 0; } _ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : +if ac_fn_cxx_try_link "$LINENO" +then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null +then : lt_cv_shlibpath_overrides_runpath=yes fi fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir @@ -15239,10 +17273,18 @@ fi # before this can be enabled. hardcode_into_libs=yes - # Append ld.so.conf contents to the search path + # Add ABI-specific directories to the system library path. + sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" + + # Ideally, we could use ldconfig to report *all* directores which are + # searched for libraries, however this is still not possible. Aside from not + # being certain /sbin/ldconfig is available, command + # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, + # even though it is searched at run-time. Try to do the best guess by + # appending ld.so.conf contents (and includes) to the search path. if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` - sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on @@ -15259,12 +17301,12 @@ netbsd*) need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH @@ -15274,7 +17316,7 @@ netbsd*) newsos6) version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; @@ -15283,58 +17325,70 @@ newsos6) version_type=qnx need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; -openbsd*) +openbsd* | bitrig*) version_type=sunos - sys_lib_dlsearch_path_spec="/usr/lib" + sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no - # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. - case $host_os in - openbsd3.3 | openbsd3.3.*) need_version=yes ;; - *) need_version=no ;; - esac - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no + else + need_version=yes + fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - case $host_os in - openbsd2.[89] | openbsd2.[89].*) - shlibpath_overrides_runpath=no - ;; - *) - shlibpath_overrides_runpath=yes - ;; - esac - else - shlibpath_overrides_runpath=yes - fi + shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' - shrext_cmds=".dll" + shrext_cmds=.dll need_lib_prefix=no - library_names_spec='$libname${shared_ext} $libname.a' + # OS/2 can only load a DLL with a base name of 8 characters or less. +# SDL customization: removed versioning support. +# version_type=windows +# need_version=no +# soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; +# v=$($ECHO $release$versuffix | tr -d .-); +# n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); +# $ECHO $n$v`$shared_ext' + soname_spec='`test -n "$os2dllname" && libname=$os2dllname; $ECHO $libname | cut -b -8 | tr . _`$shared_ext' + library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' - shlibpath_var=LIBPATH + shlibpath_var=BEGINLIBPATH + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) @@ -15345,8 +17399,8 @@ solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes @@ -15356,11 +17410,11 @@ solaris*) sunos4*) version_type=sunos - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes - if test "$with_gnu_ld" = yes; then + if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes @@ -15368,8 +17422,8 @@ sunos4*) sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) @@ -15390,24 +17444,24 @@ sysv4 | sysv4.3*) ;; sysv4*MP*) - if test -d /usr/nec ;then + if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' - soname_spec='$libname${shared_ext}.$major' + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - version_type=freebsd-elf + version_type=sco need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes - if test "$with_gnu_ld" = yes; then + if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' @@ -15425,7 +17479,7 @@ tpf*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes @@ -15433,8 +17487,8 @@ tpf*) uts4*) version_type=linux # correct to gnu/linux during the next big refactor - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; @@ -15442,22 +17496,31 @@ uts4*) dynamic_linker=no ;; esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 -$as_echo "$dynamic_linker" >&6; } -test "$dynamic_linker" = no && can_build_shared=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +printf "%s\n" "$dynamic_linker" >&6; } +test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then +if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi -if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then - sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" -fi -if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then - sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec +fi + +# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... +configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec + +# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code +func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" + +# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool +configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH @@ -15495,20 +17558,23 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 -$as_echo_n "checking how to hardcode library paths into programs... " >&6; } + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +printf %s "checking how to hardcode library paths into programs... " >&6; } hardcode_action_CXX= if test -n "$hardcode_libdir_flag_spec_CXX" || test -n "$runpath_var_CXX" || - test "X$hardcode_automatic_CXX" = "Xyes" ; then + test yes = "$hardcode_automatic_CXX"; then # We can hardcode non-existent directories. - if test "$hardcode_direct_CXX" != no && + if test no != "$hardcode_direct_CXX" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one - ## test "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" != no && - test "$hardcode_minus_L_CXX" != no; then + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" && + test no != "$hardcode_minus_L_CXX"; then # Linking always hardcodes the temporary library directory. hardcode_action_CXX=relink else @@ -15520,15 +17586,15 @@ else # directories. hardcode_action_CXX=unsupported fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 -$as_echo "$hardcode_action_CXX" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 +printf "%s\n" "$hardcode_action_CXX" >&6; } -if test "$hardcode_action_CXX" = relink || - test "$inherit_rpath_CXX" = yes; then +if test relink = "$hardcode_action_CXX" || + test yes = "$inherit_rpath_CXX"; then # Fast installation is not supported enable_fast_install=no -elif test "$shlibpath_overrides_runpath" = yes || - test "$enable_shared" = no; then +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi @@ -15551,7 +17617,7 @@ fi lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld -fi # test "$_lt_caught_CXX_error" != yes +fi # test yes != "$_lt_caught_CXX_error" ac_ext=c ac_cpp='$CPP $CPPFLAGS' @@ -15560,7 +17626,154 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $ ac_compiler_gnu=$ac_cv_c_compiler_gnu -# Find a good install program. We prefer a C program (faster), +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +printf %s "checking for egrep... " >&6; } +if test ${ac_cv_path_EGREP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_prog in egrep + do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + printf %s 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + printf "%s\n" 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +printf "%s\n" "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 +printf %s "checking for fgrep... " >&6; } +if test ${ac_cv_path_FGREP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 + then ac_cv_path_FGREP="$GREP -F" + else + if test -z "$FGREP"; then + ac_path_FGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_prog in fgrep + do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_FGREP="$as_dir$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_FGREP" || continue +# Check for GNU ac_path_FGREP and select it if it is found. + # Check for GNU $ac_path_FGREP +case `"$ac_path_FGREP" --version 2>&1` in +*GNU*) + ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; +*) + ac_count=0 + printf %s 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + printf "%s\n" 'FGREP' >> "conftest.nl" + "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_FGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_FGREP="$ac_path_FGREP" + ac_path_FGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_FGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_FGREP"; then + as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_FGREP=$FGREP +fi + + fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 +printf "%s\n" "$ac_cv_path_FGREP" >&6; } + FGREP="$ac_cv_path_FGREP" + + + + # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install @@ -15574,20 +17787,25 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 -$as_echo_n "checking for a BSD-compatible install... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +printf %s "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then -if ${ac_cv_path_install+:} false; then : - $as_echo_n "(cached) " >&6 -else +if test ${ac_cv_path_install+y} +then : + printf %s "(cached) " >&6 +else $as_nop as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - # Account for people who put trailing slashes in PATH elements. -case $as_dir/ in #(( - ./ | .// | /[cC]/* | \ + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + # Account for fact that we put trailing slashes in our PATH walk. +case $as_dir in #(( + ./ | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; @@ -15597,13 +17815,13 @@ case $as_dir/ in #(( # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext"; then if test $ac_prog = install && - grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + grep dspmsg "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && - grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + grep pwplus "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else @@ -15611,12 +17829,12 @@ case $as_dir/ in #(( echo one > conftest.one echo two > conftest.two mkdir conftest.dir - if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + if "$as_dir$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir/" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then - ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + ac_cv_path_install="$as_dir$ac_prog$ac_exec_ext -c" break 3 fi fi @@ -15632,7 +17850,7 @@ IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi - if test "${ac_cv_path_install+set}" = set; then + if test ${ac_cv_path_install+y}; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a @@ -15642,8 +17860,8 @@ fi INSTALL=$ac_install_sh fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 -$as_echo "$INSTALL" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +printf "%s\n" "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. @@ -15653,13 +17871,14 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 -$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +printf %s "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} -ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` -if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : - $as_echo_n "(cached) " >&6 -else +ac_make=`printf "%s\n" "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval test \${ac_cv_prog_make_${ac_make}_set+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @@ -15675,106 +17894,15 @@ esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } SET_MAKE= else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}windres", so it can be a program name with args. -set dummy ${ac_tool_prefix}windres; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_WINDRES+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$WINDRES"; then - ac_cv_prog_WINDRES="$WINDRES" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_WINDRES="${ac_tool_prefix}windres" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -WINDRES=$ac_cv_prog_WINDRES -if test -n "$WINDRES"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WINDRES" >&5 -$as_echo "$WINDRES" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_WINDRES"; then - ac_ct_WINDRES=$WINDRES - # Extract the first word of "windres", so it can be a program name with args. -set dummy windres; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_WINDRES+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_WINDRES"; then - ac_cv_prog_ac_ct_WINDRES="$ac_ct_WINDRES" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_WINDRES="windres" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_WINDRES=$ac_cv_prog_ac_ct_WINDRES -if test -n "$ac_ct_WINDRES"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_WINDRES" >&5 -$as_echo "$ac_ct_WINDRES" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_WINDRES" = x; then - WINDRES=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - WINDRES=$ac_ct_WINDRES - fi -else - WINDRES="$ac_cv_prog_WINDRES" -fi @@ -15786,11 +17914,12 @@ if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_PKG_CONFIG+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_PKG_CONFIG+y} +then : + printf %s "(cached) " >&6 +else $as_nop case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. @@ -15800,11 +17929,15 @@ else for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_PKG_CONFIG="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -15816,11 +17949,11 @@ esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 -$as_echo "$PKG_CONFIG" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +printf "%s\n" "$PKG_CONFIG" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -15829,11 +17962,12 @@ if test -z "$ac_cv_path_PKG_CONFIG"; then ac_pt_PKG_CONFIG=$PKG_CONFIG # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_ac_pt_PKG_CONFIG+y} +then : + printf %s "(cached) " >&6 +else $as_nop case $ac_pt_PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. @@ -15843,11 +17977,15 @@ else for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_PKG_CONFIG="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -15859,11 +17997,11 @@ esac fi ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG if test -n "$ac_pt_PKG_CONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 -$as_echo "$ac_pt_PKG_CONFIG" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 +printf "%s\n" "$ac_pt_PKG_CONFIG" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi if test "x$ac_pt_PKG_CONFIG" = x; then @@ -15871,8 +18009,8 @@ fi else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac PKG_CONFIG=$ac_pt_PKG_CONFIG @@ -15884,20 +18022,283 @@ fi fi if test -n "$PKG_CONFIG"; then _pkg_min_version=0.9.0 - { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 -$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 +printf %s "checking pkg-config is at least version $_pkg_min_version... " >&6; } if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } PKG_CONFIG="" fi fi +if test -z "$AWK" ; then + as_fn_error $? "*** awk not found, aborting" "$LINENO" 5 +fi + +for ac_prog in gsort sort +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_SORT+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$SORT"; then + ac_cv_prog_SORT="$SORT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_SORT="$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +SORT=$ac_cv_prog_SORT +if test -n "$SORT"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $SORT" >&5 +printf "%s\n" "$SORT" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + test -n "$SORT" && break +done +test -n "$SORT" || SORT="false" + +if ! "$SORT" -V /dev/null +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: sort(1) that supports the -V option is required to find dynamic libraries" >&5 +printf "%s\n" "$as_me: WARNING: sort(1) that supports the -V option is required to find dynamic libraries" >&2;} +fi + +# Check whether --enable-largefile was given. +if test ${enable_largefile+y} +then : + enableval=$enable_largefile; +fi + +if test "$enable_largefile" != no; then + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5 +printf %s "checking for special C compiler options needed for large files... " >&6; } +if test ${ac_cv_sys_largefile_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_sys_largefile_CC=no + if test "$GCC" != yes; then + ac_save_CC=$CC + while :; do + # IRIX 6.2 and later do not support large files by default, + # so use the C compiler's -n32 option if that helps. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main (void) +{ + + ; + return 0; +} +_ACEOF + if ac_fn_c_try_compile "$LINENO" +then : + break +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam + CC="$CC -n32" + if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_sys_largefile_CC=' -n32'; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam + break + done + CC=$ac_save_CC + rm -f conftest.$ac_ext + fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5 +printf "%s\n" "$ac_cv_sys_largefile_CC" >&6; } + if test "$ac_cv_sys_largefile_CC" != no; then + CC=$CC$ac_cv_sys_largefile_CC + fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5 +printf %s "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; } +if test ${ac_cv_sys_file_offset_bits+y} +then : + printf %s "(cached) " >&6 +else $as_nop + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_sys_file_offset_bits=no; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define _FILE_OFFSET_BITS 64 +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_sys_file_offset_bits=64; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ac_cv_sys_file_offset_bits=unknown + break +done +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5 +printf "%s\n" "$ac_cv_sys_file_offset_bits" >&6; } +case $ac_cv_sys_file_offset_bits in #( + no | unknown) ;; + *) +printf "%s\n" "#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits" >>confdefs.h +;; +esac +rm -rf conftest* + if test $ac_cv_sys_file_offset_bits = unknown; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5 +printf %s "checking for _LARGE_FILES value needed for large files... " >&6; } +if test ${ac_cv_sys_large_files+y} +then : + printf %s "(cached) " >&6 +else $as_nop + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_sys_large_files=no; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define _LARGE_FILES 1 +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_sys_large_files=1; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ac_cv_sys_large_files=unknown + break +done +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5 +printf "%s\n" "$ac_cv_sys_large_files" >&6; } +case $ac_cv_sys_large_files in #( + no | unknown) ;; + *) +printf "%s\n" "#define _LARGE_FILES $ac_cv_sys_large_files" >>confdefs.h +;; +esac +rm -rf conftest* + fi +fi + + case "$host" in - *-*-mingw32*) + *-*-mingw*) # Except on msys, where make can't handle full pathnames (bug 1972) ;; *) @@ -15905,12 +18306,34 @@ case "$host" in ;; esac -INCLUDE="-I$srcdir/include -idirafter $srcdir/src/video/khronos" +INCLUDE="-I$srcdir/include" + +case "$host" in + *-*-nto-qnx*) + ;; + *) + INCLUDE="$INCLUDE -idirafter $srcdir/src/video/khronos" + ;; +esac + +case "$host" in + *-*-haiku*) + LINKER='$(CXX)' + LIBTOOLLINKERTAG='CXX' + ;; + *) + LINKER='$(CC)' + LIBTOOLLINKERTAG='CC' + ;; +esac + + + if test x$srcdir != x.; then INCLUDE="-Iinclude $INCLUDE" -elif test -d .hg; then +elif test -d .git; then as_fn_error $? " -*** When building from Mercurial you should configure and build in a +*** When building from a git clone you should configure and build in a separate directory so you don't clobber SDL_config.h, SDL_revision.h " "$LINENO" 5 fi @@ -15921,31 +18344,28 @@ case "$host" in # We build SDL on cygwin without the UNIX emulation layer save_CFLAGS="$CFLAGS" have_no_cygwin=no - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GCC -mno-cygwin option" >&5 -$as_echo_n "checking for GCC -mno-cygwin option... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GCC -mno-cygwin option" >&5 +printf %s "checking for GCC -mno-cygwin option... " >&6; } CFLAGS="$save_CFLAGS -mno-cygwin" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - int -main () +main (void) { - ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - have_no_cygwin=yes - +if ac_fn_c_try_compile "$LINENO" +then : + have_no_cygwin=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_no_cygwin" >&5 -$as_echo "$have_no_cygwin" >&6; } +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_no_cygwin" >&5 +printf "%s\n" "$have_no_cygwin" >&6; } CFLAGS="$save_CFLAGS" if test x$have_no_cygwin = xyes; then @@ -15992,8 +18412,8 @@ base_libdir=`echo \${libdir} | sed 's/.*\/\(.*\)/\1/; q'` find_lib() { - gcc_bin_path=`$CC -print-search-dirs 2>/dev/null | fgrep programs: | sed 's/[^=]*=\(.*\)/\1/' | sed 's/:/ /g'` - gcc_lib_path=`$CC -print-search-dirs 2>/dev/null | fgrep libraries: | sed 's/[^=]*=\(.*\)/\1/' | sed 's/:/ /g'` + gcc_bin_path=`$CC -print-search-dirs 2>/dev/null | $FGREP programs: | sed 's/[^=]*=\(.*\)/\1/' | sed 's/:/ /g'` + gcc_lib_path=`$CC -print-search-dirs 2>/dev/null | $FGREP libraries: | sed 's/[^=]*=\(.*\)/\1/' | sed 's/:/ /g'` env_lib_path=`echo $LIBS $LDFLAGS $* | sed 's/-L[ ]*//g'` if test "$cross_compiling" = yes; then host_lib_path="" @@ -16001,15 +18421,7 @@ find_lib() host_lib_path="/usr/$base_libdir /usr/local/$base_libdir" fi for path in $env_lib_path $gcc_bin_path $gcc_lib_path $host_lib_path; do - lib=`ls -- $path/$1 2>/dev/null | sed -e '/\.so\..*\./d' -e 's,.*/,,' | sort | tail -1` - if test x$lib != x; then - echo $lib - return - fi - done - # Try again, this time allowing more than one version digit after the .so - for path in $env_lib_path $gcc_bin_path $gcc_lib_path $host_lib_path; do - lib=`ls -- $path/$1 2>/dev/null | sed -e 's,.*/,,' | sort | tail -1` + lib=`ls -- $path/$1 2>/dev/null | sed 's,.*/,,' | "$SORT" -V -r | $AWK 'BEGIN{FS="."}{ print NF, $0 }' | "$SORT" -n -s | sed 's,[0-9]* ,,' | head -1` if test x$lib != x; then echo $lib return @@ -16017,16 +18429,17 @@ find_lib() done } -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 -$as_echo_n "checking for an ANSI C-conforming const... " >&6; } -if ${ac_cv_c_const+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 +printf %s "checking for an ANSI C-conforming const... " >&6; } +if test ${ac_cv_c_const+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { #ifndef __cplusplus @@ -16039,7 +18452,7 @@ main () /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; - /* AIX XL C 1.02.0.0 rejects this. + /* IBM XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ @@ -16067,7 +18480,7 @@ main () iptr p = 0; ++p; } - { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying + { /* IBM XL C 1.02.0.0 rejects this sort of thing, saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; } bx; struct s *b = &bx; b->j = 5; @@ -16083,47 +18496,50 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_cv_c_const=yes -else +else $as_nop ac_cv_c_const=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 -$as_echo "$ac_cv_c_const" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 +printf "%s\n" "$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then -$as_echo "#define const /**/" >>confdefs.h +printf "%s\n" "#define const /**/" >>confdefs.h fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 -$as_echo_n "checking for inline... " >&6; } -if ${ac_cv_c_inline+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 +printf %s "checking for inline... " >&6; } +if test ${ac_cv_c_inline+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __cplusplus typedef int foo_t; -static $ac_kw foo_t static_foo () {return 0; } -$ac_kw foo_t foo () {return 0; } +static $ac_kw foo_t static_foo (void) {return 0; } +$ac_kw foo_t foo (void) {return 0; } #endif _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_cv_c_inline=$ac_kw fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext test "$ac_cv_c_inline" != no && break done fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 -$as_echo "$ac_cv_c_inline" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 +printf "%s\n" "$ac_cv_c_inline" >&6; } case $ac_cv_c_inline in inline | yes) ;; @@ -16140,16 +18556,17 @@ _ACEOF ;; esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working volatile" >&5 -$as_echo_n "checking for working volatile... " >&6; } -if ${ac_cv_c_volatile+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for working volatile" >&5 +printf %s "checking for working volatile... " >&6; } +if test ${ac_cv_c_volatile+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { volatile int x; @@ -16159,26 +18576,28 @@ return !x && !y; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_cv_c_volatile=yes -else +else $as_nop ac_cv_c_volatile=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_volatile" >&5 -$as_echo "$ac_cv_c_volatile" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_volatile" >&5 +printf "%s\n" "$ac_cv_c_volatile" >&6; } if test $ac_cv_c_volatile = no; then -$as_echo "#define volatile /**/" >>confdefs.h +printf "%s\n" "#define volatile /**/" >>confdefs.h fi # Check whether --enable-assertions was given. -if test "${enable_assertions+set}" = set; then : +if test ${enable_assertions+y} +then : enableval=$enable_assertions; -else +else $as_nop enable_assertions=auto fi @@ -16187,22 +18606,22 @@ case "$enable_assertions" in ;; disabled) -$as_echo "#define SDL_DEFAULT_ASSERT_LEVEL 0" >>confdefs.h +printf "%s\n" "#define SDL_DEFAULT_ASSERT_LEVEL 0" >>confdefs.h ;; release) -$as_echo "#define SDL_DEFAULT_ASSERT_LEVEL 1" >>confdefs.h +printf "%s\n" "#define SDL_DEFAULT_ASSERT_LEVEL 1" >>confdefs.h ;; enabled) -$as_echo "#define SDL_DEFAULT_ASSERT_LEVEL 2" >>confdefs.h +printf "%s\n" "#define SDL_DEFAULT_ASSERT_LEVEL 2" >>confdefs.h ;; paranoid) -$as_echo "#define SDL_DEFAULT_ASSERT_LEVEL 3" >>confdefs.h +printf "%s\n" "#define SDL_DEFAULT_ASSERT_LEVEL 3" >>confdefs.h ;; *) @@ -16210,17 +18629,20 @@ $as_echo "#define SDL_DEFAULT_ASSERT_LEVEL 3" >>confdefs.h ;; esac +EXTRA_CFLAGS="$EXTRA_CFLAGS -DSDL_BUILD_MAJOR_VERSION=$SDL_MAJOR_VERSION -DSDL_BUILD_MINOR_VERSION=$SDL_MINOR_VERSION -DSDL_BUILD_MICRO_VERSION=$SDL_MICRO_VERSION" + # Check whether --enable-dependency-tracking was given. -if test "${enable_dependency_tracking+set}" = set; then : +if test ${enable_dependency_tracking+y} +then : enableval=$enable_dependency_tracking; -else +else $as_nop enable_dependency_tracking=yes fi if test x$enable_dependency_tracking = xyes; then have_gcc_mmd_mt=no - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GCC -MMD -MT option" >&5 -$as_echo_n "checking for GCC -MMD -MT option... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GCC -MMD -MT option" >&5 +printf %s "checking for GCC -MMD -MT option... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -16229,67 +18651,63 @@ $as_echo_n "checking for GCC -MMD -MT option... " >&6; } #endif int -main () +main (void) { - ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - have_gcc_mmd_mt=yes - +if ac_fn_c_try_compile "$LINENO" +then : + have_gcc_mmd_mt=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_gcc_mmd_mt" >&5 -$as_echo "$have_gcc_mmd_mt" >&6; } +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_gcc_mmd_mt" >&5 +printf "%s\n" "$have_gcc_mmd_mt" >&6; } if test x$have_gcc_mmd_mt = xyes; then DEPENDENCY_TRACKING_OPTIONS="-MMD -MT \$@" fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for linker option --no-undefined" >&5 -$as_echo_n "checking for linker option --no-undefined... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for linker option --no-undefined" >&5 +printf %s "checking for linker option --no-undefined... " >&6; } have_no_undefined=no case "$host" in - *-*-openbsd*) + *-*-openbsd*) ;; - *) save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -Wl,--no-undefined" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - int -main () +main (void) { - ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : have_no_undefined=yes - EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,--no-undefined" + BUILD_LDFLAGS="$BUILD_LDFLAGS -Wl,--no-undefined" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" ;; esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_no_undefined" >&5 -$as_echo "$have_no_undefined" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_no_undefined" >&5 +printf "%s\n" "$have_no_undefined" >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for linker option --dynamicbase" >&5 -$as_echo_n "checking for linker option --dynamicbase... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for linker option --dynamicbase" >&5 +printf %s "checking for linker option --dynamicbase... " >&6; } have_dynamicbase=no case "$host" in *) @@ -16298,32 +18716,31 @@ case "$host" in cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - int -main () +main (void) { - ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : have_dynamicbase=yes EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,--dynamicbase" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" ;; esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_dynamicbase" >&5 -$as_echo "$have_dynamicbase" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_dynamicbase" >&5 +printf "%s\n" "$have_dynamicbase" >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for linker option --nxcompat" >&5 -$as_echo_n "checking for linker option --nxcompat... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for linker option --nxcompat" >&5 +printf %s "checking for linker option --nxcompat... " >&6; } have_nxcompat=no case "$host" in *) @@ -16332,32 +18749,31 @@ case "$host" in cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - int -main () +main (void) { - ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : have_nxcompat=yes EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,--nxcompat" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" ;; esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_nxcompat" >&5 -$as_echo "$have_nxcompat" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_nxcompat" >&5 +printf "%s\n" "$have_nxcompat" >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for linker option --high-entropy-va" >&5 -$as_echo_n "checking for linker option --high-entropy-va... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for linker option --high-entropy-va" >&5 +printf %s "checking for linker option --high-entropy-va... " >&6; } have_high_entropy_va=no case "$host" in *) @@ -16366,187 +18782,329 @@ case "$host" in cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - int -main () +main (void) { - ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : have_high_entropy_va=yes EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,--high-entropy-va" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" ;; esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_high_entropy_va" >&5 -$as_echo "$have_high_entropy_va" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_high_entropy_va" >&5 +printf "%s\n" "$have_high_entropy_va" >&6; } # Check whether --enable-libc was given. -if test "${enable_libc+set}" = set; then : +if test ${enable_libc+y} +then : enableval=$enable_libc; -else +else $as_nop enable_libc=yes fi + +enable_system_iconv_default=yes +case "$host" in + *-*-cygwin*|*-*-mingw*|*-*-darwin*|*-ios-*) + enable_system_iconv_default=no + ;; +esac +# Check whether --enable-system-iconv was given. +if test ${enable_system_iconv+y} +then : + enableval=$enable_system_iconv; +else $as_nop + enable_system_iconv=$enable_system_iconv_default +fi + +# Check whether --enable-libiconv was given. +if test ${enable_libiconv+y} +then : + enableval=$enable_libiconv; +else $as_nop + enable_libiconv=no +fi + + if test x$enable_libc = xyes; then -$as_echo "#define HAVE_LIBC 1" >>confdefs.h +printf "%s\n" "#define HAVE_LIBC 1" >>confdefs.h - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 -$as_echo_n "checking for ANSI C header files... " >&6; } -if ${ac_cv_header_stdc+:} false; then : - $as_echo_n "(cached) " >&6 -else + + ac_fn_c_check_header_compile "$LINENO" "sys/types.h" "ac_cv_header_sys_types_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_types_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_TYPES_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "stdio.h" "ac_cv_header_stdio_h" "$ac_includes_default" +if test "x$ac_cv_header_stdio_h" = xyes +then : + printf "%s\n" "#define HAVE_STDIO_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default" +if test "x$ac_cv_header_stdlib_h" = xyes +then : + printf "%s\n" "#define HAVE_STDLIB_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "stddef.h" "ac_cv_header_stddef_h" "$ac_includes_default" +if test "x$ac_cv_header_stddef_h" = xyes +then : + printf "%s\n" "#define HAVE_STDDEF_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "stdarg.h" "ac_cv_header_stdarg_h" "$ac_includes_default" +if test "x$ac_cv_header_stdarg_h" = xyes +then : + printf "%s\n" "#define HAVE_STDARG_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "malloc.h" "ac_cv_header_malloc_h" "$ac_includes_default" +if test "x$ac_cv_header_malloc_h" = xyes +then : + printf "%s\n" "#define HAVE_MALLOC_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "memory.h" "ac_cv_header_memory_h" "$ac_includes_default" +if test "x$ac_cv_header_memory_h" = xyes +then : + printf "%s\n" "#define HAVE_MEMORY_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "string.h" "ac_cv_header_string_h" "$ac_includes_default" +if test "x$ac_cv_header_string_h" = xyes +then : + printf "%s\n" "#define HAVE_STRING_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "strings.h" "ac_cv_header_strings_h" "$ac_includes_default" +if test "x$ac_cv_header_strings_h" = xyes +then : + printf "%s\n" "#define HAVE_STRINGS_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "wchar.h" "ac_cv_header_wchar_h" "$ac_includes_default" +if test "x$ac_cv_header_wchar_h" = xyes +then : + printf "%s\n" "#define HAVE_WCHAR_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "inttypes.h" "ac_cv_header_inttypes_h" "$ac_includes_default" +if test "x$ac_cv_header_inttypes_h" = xyes +then : + printf "%s\n" "#define HAVE_INTTYPES_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "stdint.h" "ac_cv_header_stdint_h" "$ac_includes_default" +if test "x$ac_cv_header_stdint_h" = xyes +then : + printf "%s\n" "#define HAVE_STDINT_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "limits.h" "ac_cv_header_limits_h" "$ac_includes_default" +if test "x$ac_cv_header_limits_h" = xyes +then : + printf "%s\n" "#define HAVE_LIMITS_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "ctype.h" "ac_cv_header_ctype_h" "$ac_includes_default" +if test "x$ac_cv_header_ctype_h" = xyes +then : + printf "%s\n" "#define HAVE_CTYPE_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "math.h" "ac_cv_header_math_h" "$ac_includes_default" +if test "x$ac_cv_header_math_h" = xyes +then : + printf "%s\n" "#define HAVE_MATH_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "float.h" "ac_cv_header_float_h" "$ac_includes_default" +if test "x$ac_cv_header_float_h" = xyes +then : + printf "%s\n" "#define HAVE_FLOAT_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "iconv.h" "ac_cv_header_iconv_h" "$ac_includes_default" +if test "x$ac_cv_header_iconv_h" = xyes +then : + printf "%s\n" "#define HAVE_ICONV_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "signal.h" "ac_cv_header_signal_h" "$ac_includes_default" +if test "x$ac_cv_header_signal_h" = xyes +then : + printf "%s\n" "#define HAVE_SIGNAL_H 1" >>confdefs.h + +fi + + + ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" +if test "x$ac_cv_type_size_t" = xyes +then : + +else $as_nop + +printf "%s\n" "#define size_t unsigned int" >>confdefs.h + +fi + + + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +printf %s "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test ${ac_cv_prog_CPP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + # Double quotes because $CC needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" cpp /lib/cpp + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include -#include -#include -#include - -int -main () -{ - - ; - return 0; -} +#include + Syntax error _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_header_stdc=yes -else - ac_cv_header_stdc=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +if ac_fn_c_try_cpp "$LINENO" +then : -if test $ac_cv_header_stdc = yes; then - # SunOS 4.x string.h does not declare mem*, contrary to ANSI. +else $as_nop + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include - +#include _ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "memchr" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "free" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; then : - : -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#if ((' ' & 0x0FF) == 0x020) -# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#else -# define ISLOWER(c) \ - (('a' <= (c) && (c) <= 'i') \ - || ('j' <= (c) && (c) <= 'r') \ - || ('s' <= (c) && (c) <= 'z')) -# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) -#endif - -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) -int -main () -{ - int i; - for (i = 0; i < 256; i++) - if (XOR (islower (i), ISLOWER (i)) - || toupper (i) != TOUPPER (i)) - return 2; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - -else - ac_cv_header_stdc=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 -$as_echo "$ac_cv_header_stdc" >&6; } -if test $ac_cv_header_stdc = yes; then - -$as_echo "#define STDC_HEADERS 1" >>confdefs.h - -fi - - for ac_header in sys/types.h stdio.h stdlib.h stddef.h stdarg.h malloc.h memory.h string.h strings.h wchar.h inttypes.h stdint.h limits.h ctype.h math.h float.h iconv.h signal.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - +if ac_fn_c_try_cpp "$LINENO" +then : + # Broken: success on invalid input. +continue +else $as_nop + # Passes both tests. +ac_preproc_ok=: +break fi +rm -f conftest.err conftest.i conftest.$ac_ext done - - - ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" -if test "x$ac_cv_type_size_t" = xyes; then : - -else - -cat >>confdefs.h <<_ACEOF -#define size_t unsigned int -_ACEOF - +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok +then : + break fi + done + ac_cv_prog_CPP=$CPP - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for M_PI in math.h" >&5 -$as_echo_n "checking for M_PI in math.h... " >&6; } -if ${ac_cv_define_M_PI+:} false; then : - $as_echo_n "(cached) " >&6 +fi + CPP=$ac_cv_prog_CPP else + ac_cv_prog_CPP=$CPP +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +printf "%s\n" "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ +#include + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO" +then : + +else $as_nop + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO" +then : + # Broken: success on invalid input. +continue +else $as_nop + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok +then : + +else $as_nop + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for M_PI in math.h" >&5 +printf %s "checking for M_PI in math.h... " >&6; } +if test ${ac_cv_define_M_PI+y} +then : + printf %s "(cached) " >&6 +else $as_nop + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ #include #ifdef M_PI @@ -16555,40 +19113,38 @@ YES_IS_DEFINED _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "YES_IS_DEFINED" >/dev/null 2>&1; then : + $EGREP "YES_IS_DEFINED" >/dev/null 2>&1 +then : ac_cv_define_M_PI=yes -else +else $as_nop ac_cv_define_M_PI=no fi -rm -f conftest* +rm -rf conftest* fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_define_M_PI" >&5 -$as_echo "$ac_cv_define_M_PI" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_define_M_PI" >&5 +printf "%s\n" "$ac_cv_define_M_PI" >&6; } if test "$ac_cv_define_M_PI" = "yes" ; then -$as_echo "#define HAVE_M_PI /**/" >>confdefs.h +printf "%s\n" "#define HAVE_M_PI /**/" >>confdefs.h fi - case "$host" in - *-*-cygwin* | *-*-mingw32*) - ;; - *) - # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works + # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5 -$as_echo_n "checking for working alloca.h... " >&6; } -if ${ac_cv_working_alloca_h+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5 +printf %s "checking for working alloca.h... " >&6; } +if test ${ac_cv_working_alloca_h+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int -main () +main (void) { char *p = (char *) alloca (2 * sizeof (int)); if (p) return 0; @@ -16596,52 +19152,52 @@ char *p = (char *) alloca (2 * sizeof (int)); return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_working_alloca_h=yes -else +else $as_nop ac_cv_working_alloca_h=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_alloca_h" >&5 -$as_echo "$ac_cv_working_alloca_h" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_alloca_h" >&5 +printf "%s\n" "$ac_cv_working_alloca_h" >&6; } if test $ac_cv_working_alloca_h = yes; then -$as_echo "#define HAVE_ALLOCA_H 1" >>confdefs.h +printf "%s\n" "#define HAVE_ALLOCA_H 1" >>confdefs.h fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for alloca" >&5 -$as_echo_n "checking for alloca... " >&6; } -if ${ac_cv_func_alloca_works+:} false; then : - $as_echo_n "(cached) " >&6 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for alloca" >&5 +printf %s "checking for alloca... " >&6; } +if test ${ac_cv_func_alloca_works+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test $ac_cv_working_alloca_h = yes; then + ac_cv_func_alloca_works=yes else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#ifdef __GNUC__ -# define alloca __builtin_alloca -#else -# ifdef _MSC_VER +#include +#include +#ifndef alloca +# ifdef __GNUC__ +# define alloca __builtin_alloca +# elif defined _MSC_VER # include # define alloca _alloca # else -# ifdef HAVE_ALLOCA_H -# include -# else -# ifdef _AIX - #pragma alloca -# else -# ifndef alloca /* predefined by HP cc +Olibcalls */ -void *alloca (size_t); -# endif -# endif +# ifdef __cplusplus +extern "C" # endif +void *alloca (size_t); # endif #endif int -main () +main (void) { char *p = (char *) alloca (1); if (p) return 0; @@ -16649,20 +19205,22 @@ char *p = (char *) alloca (1); return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_func_alloca_works=yes -else +else $as_nop ac_cv_func_alloca_works=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_alloca_works" >&5 -$as_echo "$ac_cv_func_alloca_works" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_alloca_works" >&5 +printf "%s\n" "$ac_cv_func_alloca_works" >&6; } +fi if test $ac_cv_func_alloca_works = yes; then -$as_echo "#define HAVE_ALLOCA 1" >>confdefs.h +printf "%s\n" "#define HAVE_ALLOCA 1" >>confdefs.h else # The SVR3 libPW and SVR4 libucb both contain incompatible functions @@ -16672,58 +19230,19 @@ else ALLOCA=\${LIBOBJDIR}alloca.$ac_objext -$as_echo "#define C_ALLOCA 1" >>confdefs.h +printf "%s\n" "#define C_ALLOCA 1" >>confdefs.h -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether \`alloca.c' needs Cray hooks" >&5 -$as_echo_n "checking whether \`alloca.c' needs Cray hooks... " >&6; } -if ${ac_cv_os_cray+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#if defined CRAY && ! defined CRAY2 -webecray -#else -wenotbecray -#endif - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "webecray" >/dev/null 2>&1; then : - ac_cv_os_cray=yes -else - ac_cv_os_cray=no -fi -rm -f conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_os_cray" >&5 -$as_echo "$ac_cv_os_cray" >&6; } -if test $ac_cv_os_cray = yes; then - for ac_func in _getb67 GETB67 getb67; 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" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : - -cat >>confdefs.h <<_ACEOF -#define CRAY_STACKSEG_END $ac_func -_ACEOF - - break -fi - - done -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking stack direction for C alloca" >&5 -$as_echo_n "checking stack direction for C alloca... " >&6; } -if ${ac_cv_c_stack_direction+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking stack direction for C alloca" >&5 +printf %s "checking stack direction for C alloca... " >&6; } +if test ${ac_cv_c_stack_direction+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test "$cross_compiling" = yes +then : ac_cv_c_stack_direction=0 -else +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default @@ -16744,9 +19263,10 @@ main (int argc, char **argv) return find_stack_direction (0, argc + !argv + 20) < 0; } _ACEOF -if ac_fn_c_try_run "$LINENO"; then : +if ac_fn_c_try_run "$LINENO" +then : ac_cv_c_stack_direction=1 -else +else $as_nop ac_cv_c_stack_direction=-1 fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -16754,205 +19274,17 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_stack_direction" >&5 -$as_echo "$ac_cv_c_stack_direction" >&6; } -cat >>confdefs.h <<_ACEOF -#define STACK_DIRECTION $ac_cv_c_stack_direction -_ACEOF +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_stack_direction" >&5 +printf "%s\n" "$ac_cv_c_stack_direction" >&6; } +printf "%s\n" "#define STACK_DIRECTION $ac_cv_c_stack_direction" >>confdefs.h fi - ;; - esac - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working memcmp" >&5 -$as_echo_n "checking for working memcmp... " >&6; } -if ${ac_cv_func_memcmp_working+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - ac_cv_func_memcmp_working=no -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ - - /* Some versions of memcmp are not 8-bit clean. */ - char c0 = '\100', c1 = '\200', c2 = '\201'; - if (memcmp(&c0, &c2, 1) >= 0 || memcmp(&c1, &c2, 1) >= 0) - return 1; - - /* The Next x86 OpenStep bug shows up only when comparing 16 bytes - or more and with at least one buffer not starting on a 4-byte boundary. - William Lewis provided this test program. */ - { - char foo[21]; - char bar[21]; - int i; - for (i = 0; i < 4; i++) - { - char *a = foo + i; - char *b = bar + i; - strcpy (a, "--------01111111"); - strcpy (b, "--------10000000"); - if (memcmp (a, b, 16) >= 0) - return 1; - } - return 0; - } - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_cv_func_memcmp_working=yes -else - ac_cv_func_memcmp_working=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_memcmp_working" >&5 -$as_echo "$ac_cv_func_memcmp_working" >&6; } -test $ac_cv_func_memcmp_working = no && case " $LIBOBJS " in - *" memcmp.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS memcmp.$ac_objext" - ;; -esac - - - if test x$ac_cv_func_memcmp_working = xyes; then - -$as_echo "#define HAVE_MEMCMP 1" >>confdefs.h - - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working strtod" >&5 -$as_echo_n "checking for working strtod... " >&6; } -if ${ac_cv_func_strtod+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - ac_cv_func_strtod=no -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -$ac_includes_default -#ifndef strtod -double strtod (); -#endif -int -main() -{ - { - /* Some versions of Linux strtod mis-parse strings with leading '+'. */ - char *string = " +69"; - char *term; - double value; - value = strtod (string, &term); - if (value != 69 || term != (string + 4)) - return 1; - } - - { - /* Under Solaris 2.4, strtod returns the wrong value for the - terminating character under some conditions. */ - char *string = "NaN"; - char *term; - strtod (string, &term); - if (term != string && *(term - 1) == 0) - return 1; - } - return 0; -} - -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_cv_func_strtod=yes -else - ac_cv_func_strtod=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_strtod" >&5 -$as_echo "$ac_cv_func_strtod" >&6; } -if test $ac_cv_func_strtod = no; then - case " $LIBOBJS " in - *" strtod.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS strtod.$ac_objext" - ;; -esac - -ac_fn_c_check_func "$LINENO" "pow" "ac_cv_func_pow" -if test "x$ac_cv_func_pow" = xyes; then : - -fi - -if test $ac_cv_func_pow = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pow in -lm" >&5 -$as_echo_n "checking for pow in -lm... " >&6; } -if ${ac_cv_lib_m_pow+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lm $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char pow (); -int -main () -{ -return pow (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_m_pow=yes -else - ac_cv_lib_m_pow=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_pow" >&5 -$as_echo "$ac_cv_lib_m_pow" >&6; } -if test "x$ac_cv_lib_m_pow" = xyes; then : - POW_LIB=-lm -else - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot find library containing definition of pow" >&5 -$as_echo "$as_me: WARNING: cannot find library containing definition of pow" >&2;} -fi - -fi - -fi - - if test x$ac_cv_func_strtod = xyes; then - -$as_echo "#define HAVE_STRTOD 1" >>confdefs.h - - fi ac_fn_c_check_func "$LINENO" "mprotect" "ac_cv_func_mprotect" -if test "x$ac_cv_func_mprotect" = xyes; then : +if test "x$ac_cv_func_mprotect" = xyes +then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -16960,42 +19292,488 @@ if test "x$ac_cv_func_mprotect" = xyes; then : #include int -main () +main (void) { - ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : -$as_echo "#define HAVE_MPROTECT 1" >>confdefs.h +printf "%s\n" "#define HAVE_MPROTECT 1" >>confdefs.h fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi - for ac_func in malloc calloc realloc free getenv setenv putenv unsetenv qsort abs bcopy memset memcpy memmove wcslen wcslcpy wcslcat wcsdup wcsstr wcscmp wcsncmp strlen strlcpy strlcat _strrev _strupr _strlwr strchr strrchr strstr strtok_r 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 _Exit -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" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF + ac_fn_c_check_func "$LINENO" "malloc" "ac_cv_func_malloc" +if test "x$ac_cv_func_malloc" = xyes +then : + printf "%s\n" "#define HAVE_MALLOC 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "calloc" "ac_cv_func_calloc" +if test "x$ac_cv_func_calloc" = xyes +then : + printf "%s\n" "#define HAVE_CALLOC 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "realloc" "ac_cv_func_realloc" +if test "x$ac_cv_func_realloc" = xyes +then : + printf "%s\n" "#define HAVE_REALLOC 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "free" "ac_cv_func_free" +if test "x$ac_cv_func_free" = xyes +then : + printf "%s\n" "#define HAVE_FREE 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "getenv" "ac_cv_func_getenv" +if test "x$ac_cv_func_getenv" = xyes +then : + printf "%s\n" "#define HAVE_GETENV 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "setenv" "ac_cv_func_setenv" +if test "x$ac_cv_func_setenv" = xyes +then : + printf "%s\n" "#define HAVE_SETENV 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "putenv" "ac_cv_func_putenv" +if test "x$ac_cv_func_putenv" = xyes +then : + printf "%s\n" "#define HAVE_PUTENV 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "unsetenv" "ac_cv_func_unsetenv" +if test "x$ac_cv_func_unsetenv" = xyes +then : + printf "%s\n" "#define HAVE_UNSETENV 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "bsearch" "ac_cv_func_bsearch" +if test "x$ac_cv_func_bsearch" = xyes +then : + printf "%s\n" "#define HAVE_BSEARCH 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "qsort" "ac_cv_func_qsort" +if test "x$ac_cv_func_qsort" = xyes +then : + printf "%s\n" "#define HAVE_QSORT 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "abs" "ac_cv_func_abs" +if test "x$ac_cv_func_abs" = xyes +then : + printf "%s\n" "#define HAVE_ABS 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "bcopy" "ac_cv_func_bcopy" +if test "x$ac_cv_func_bcopy" = xyes +then : + printf "%s\n" "#define HAVE_BCOPY 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "memset" "ac_cv_func_memset" +if test "x$ac_cv_func_memset" = xyes +then : + printf "%s\n" "#define HAVE_MEMSET 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "memcmp" "ac_cv_func_memcmp" +if test "x$ac_cv_func_memcmp" = xyes +then : + printf "%s\n" "#define HAVE_MEMCMP 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "memcpy" "ac_cv_func_memcpy" +if test "x$ac_cv_func_memcpy" = xyes +then : + printf "%s\n" "#define HAVE_MEMCPY 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "memmove" "ac_cv_func_memmove" +if test "x$ac_cv_func_memmove" = xyes +then : + printf "%s\n" "#define HAVE_MEMMOVE 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "wcslen" "ac_cv_func_wcslen" +if test "x$ac_cv_func_wcslen" = xyes +then : + printf "%s\n" "#define HAVE_WCSLEN 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "wcslcpy" "ac_cv_func_wcslcpy" +if test "x$ac_cv_func_wcslcpy" = xyes +then : + printf "%s\n" "#define HAVE_WCSLCPY 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "wcslcat" "ac_cv_func_wcslcat" +if test "x$ac_cv_func_wcslcat" = xyes +then : + printf "%s\n" "#define HAVE_WCSLCAT 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "_wcsdup" "ac_cv_func__wcsdup" +if test "x$ac_cv_func__wcsdup" = xyes +then : + printf "%s\n" "#define HAVE__WCSDUP 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "wcsdup" "ac_cv_func_wcsdup" +if test "x$ac_cv_func_wcsdup" = xyes +then : + printf "%s\n" "#define HAVE_WCSDUP 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "wcsstr" "ac_cv_func_wcsstr" +if test "x$ac_cv_func_wcsstr" = xyes +then : + printf "%s\n" "#define HAVE_WCSSTR 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "wcscmp" "ac_cv_func_wcscmp" +if test "x$ac_cv_func_wcscmp" = xyes +then : + printf "%s\n" "#define HAVE_WCSCMP 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "wcsncmp" "ac_cv_func_wcsncmp" +if test "x$ac_cv_func_wcsncmp" = xyes +then : + printf "%s\n" "#define HAVE_WCSNCMP 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "wcscasecmp" "ac_cv_func_wcscasecmp" +if test "x$ac_cv_func_wcscasecmp" = xyes +then : + printf "%s\n" "#define HAVE_WCSCASECMP 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "_wcsicmp" "ac_cv_func__wcsicmp" +if test "x$ac_cv_func__wcsicmp" = xyes +then : + printf "%s\n" "#define HAVE__WCSICMP 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "wcsncasecmp" "ac_cv_func_wcsncasecmp" +if test "x$ac_cv_func_wcsncasecmp" = xyes +then : + printf "%s\n" "#define HAVE_WCSNCASECMP 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "_wcsnicmp" "ac_cv_func__wcsnicmp" +if test "x$ac_cv_func__wcsnicmp" = xyes +then : + printf "%s\n" "#define HAVE__WCSNICMP 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "strlen" "ac_cv_func_strlen" +if test "x$ac_cv_func_strlen" = xyes +then : + printf "%s\n" "#define HAVE_STRLEN 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "strlcpy" "ac_cv_func_strlcpy" +if test "x$ac_cv_func_strlcpy" = xyes +then : + printf "%s\n" "#define HAVE_STRLCPY 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "strlcat" "ac_cv_func_strlcat" +if test "x$ac_cv_func_strlcat" = xyes +then : + printf "%s\n" "#define HAVE_STRLCAT 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "_strrev" "ac_cv_func__strrev" +if test "x$ac_cv_func__strrev" = xyes +then : + printf "%s\n" "#define HAVE__STRREV 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "_strupr" "ac_cv_func__strupr" +if test "x$ac_cv_func__strupr" = xyes +then : + printf "%s\n" "#define HAVE__STRUPR 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "_strlwr" "ac_cv_func__strlwr" +if test "x$ac_cv_func__strlwr" = xyes +then : + printf "%s\n" "#define HAVE__STRLWR 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "index" "ac_cv_func_index" +if test "x$ac_cv_func_index" = xyes +then : + printf "%s\n" "#define HAVE_INDEX 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "rindex" "ac_cv_func_rindex" +if test "x$ac_cv_func_rindex" = xyes +then : + printf "%s\n" "#define HAVE_RINDEX 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "strchr" "ac_cv_func_strchr" +if test "x$ac_cv_func_strchr" = xyes +then : + printf "%s\n" "#define HAVE_STRCHR 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "strrchr" "ac_cv_func_strrchr" +if test "x$ac_cv_func_strrchr" = xyes +then : + printf "%s\n" "#define HAVE_STRRCHR 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "strstr" "ac_cv_func_strstr" +if test "x$ac_cv_func_strstr" = xyes +then : + printf "%s\n" "#define HAVE_STRSTR 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "strtok_r" "ac_cv_func_strtok_r" +if test "x$ac_cv_func_strtok_r" = xyes +then : + printf "%s\n" "#define HAVE_STRTOK_R 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "itoa" "ac_cv_func_itoa" +if test "x$ac_cv_func_itoa" = xyes +then : + printf "%s\n" "#define HAVE_ITOA 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "_ltoa" "ac_cv_func__ltoa" +if test "x$ac_cv_func__ltoa" = xyes +then : + printf "%s\n" "#define HAVE__LTOA 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "_uitoa" "ac_cv_func__uitoa" +if test "x$ac_cv_func__uitoa" = xyes +then : + printf "%s\n" "#define HAVE__UITOA 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "_ultoa" "ac_cv_func__ultoa" +if test "x$ac_cv_func__ultoa" = xyes +then : + printf "%s\n" "#define HAVE__ULTOA 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "strtod" "ac_cv_func_strtod" +if test "x$ac_cv_func_strtod" = xyes +then : + printf "%s\n" "#define HAVE_STRTOD 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "strtol" "ac_cv_func_strtol" +if test "x$ac_cv_func_strtol" = xyes +then : + printf "%s\n" "#define HAVE_STRTOL 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "strtoul" "ac_cv_func_strtoul" +if test "x$ac_cv_func_strtoul" = xyes +then : + printf "%s\n" "#define HAVE_STRTOUL 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "_i64toa" "ac_cv_func__i64toa" +if test "x$ac_cv_func__i64toa" = xyes +then : + printf "%s\n" "#define HAVE__I64TOA 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "_ui64toa" "ac_cv_func__ui64toa" +if test "x$ac_cv_func__ui64toa" = xyes +then : + printf "%s\n" "#define HAVE__UI64TOA 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "strtoll" "ac_cv_func_strtoll" +if test "x$ac_cv_func_strtoll" = xyes +then : + printf "%s\n" "#define HAVE_STRTOLL 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "strtoull" "ac_cv_func_strtoull" +if test "x$ac_cv_func_strtoull" = xyes +then : + printf "%s\n" "#define HAVE_STRTOULL 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "atoi" "ac_cv_func_atoi" +if test "x$ac_cv_func_atoi" = xyes +then : + printf "%s\n" "#define HAVE_ATOI 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "atof" "ac_cv_func_atof" +if test "x$ac_cv_func_atof" = xyes +then : + printf "%s\n" "#define HAVE_ATOF 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "strcmp" "ac_cv_func_strcmp" +if test "x$ac_cv_func_strcmp" = xyes +then : + printf "%s\n" "#define HAVE_STRCMP 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "strncmp" "ac_cv_func_strncmp" +if test "x$ac_cv_func_strncmp" = xyes +then : + printf "%s\n" "#define HAVE_STRNCMP 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "_stricmp" "ac_cv_func__stricmp" +if test "x$ac_cv_func__stricmp" = xyes +then : + printf "%s\n" "#define HAVE__STRICMP 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "strcasecmp" "ac_cv_func_strcasecmp" +if test "x$ac_cv_func_strcasecmp" = xyes +then : + printf "%s\n" "#define HAVE_STRCASECMP 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "_strnicmp" "ac_cv_func__strnicmp" +if test "x$ac_cv_func__strnicmp" = xyes +then : + printf "%s\n" "#define HAVE__STRNICMP 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "strncasecmp" "ac_cv_func_strncasecmp" +if test "x$ac_cv_func_strncasecmp" = xyes +then : + printf "%s\n" "#define HAVE_STRNCASECMP 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "strcasestr" "ac_cv_func_strcasestr" +if test "x$ac_cv_func_strcasestr" = xyes +then : + printf "%s\n" "#define HAVE_STRCASESTR 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "vsscanf" "ac_cv_func_vsscanf" +if test "x$ac_cv_func_vsscanf" = xyes +then : + printf "%s\n" "#define HAVE_VSSCANF 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "vsnprintf" "ac_cv_func_vsnprintf" +if test "x$ac_cv_func_vsnprintf" = xyes +then : + printf "%s\n" "#define HAVE_VSNPRINTF 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "fopen64" "ac_cv_func_fopen64" +if test "x$ac_cv_func_fopen64" = xyes +then : + printf "%s\n" "#define HAVE_FOPEN64 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "fseeko" "ac_cv_func_fseeko" +if test "x$ac_cv_func_fseeko" = xyes +then : + printf "%s\n" "#define HAVE_FSEEKO 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "fseeko64" "ac_cv_func_fseeko64" +if test "x$ac_cv_func_fseeko64" = xyes +then : + printf "%s\n" "#define HAVE_FSEEKO64 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "sigaction" "ac_cv_func_sigaction" +if test "x$ac_cv_func_sigaction" = xyes +then : + printf "%s\n" "#define HAVE_SIGACTION 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "setjmp" "ac_cv_func_setjmp" +if test "x$ac_cv_func_setjmp" = xyes +then : + printf "%s\n" "#define HAVE_SETJMP 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "nanosleep" "ac_cv_func_nanosleep" +if test "x$ac_cv_func_nanosleep" = xyes +then : + printf "%s\n" "#define HAVE_NANOSLEEP 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "sysconf" "ac_cv_func_sysconf" +if test "x$ac_cv_func_sysconf" = xyes +then : + printf "%s\n" "#define HAVE_SYSCONF 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "sysctlbyname" "ac_cv_func_sysctlbyname" +if test "x$ac_cv_func_sysctlbyname" = xyes +then : + printf "%s\n" "#define HAVE_SYSCTLBYNAME 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "getauxval" "ac_cv_func_getauxval" +if test "x$ac_cv_func_getauxval" = xyes +then : + printf "%s\n" "#define HAVE_GETAUXVAL 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "elf_aux_info" "ac_cv_func_elf_aux_info" +if test "x$ac_cv_func_elf_aux_info" = xyes +then : + printf "%s\n" "#define HAVE_ELF_AUX_INFO 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "poll" "ac_cv_func_poll" +if test "x$ac_cv_func_poll" = xyes +then : + printf "%s\n" "#define HAVE_POLL 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "memfd_create" "ac_cv_func_memfd_create" +if test "x$ac_cv_func_memfd_create" = xyes +then : + printf "%s\n" "#define HAVE_MEMFD_CREATE 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "posix_fallocate" "ac_cv_func_posix_fallocate" +if test "x$ac_cv_func_posix_fallocate" = xyes +then : + printf "%s\n" "#define HAVE_POSIX_FALLOCATE 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "_Exit" "ac_cv_func__Exit" +if test "x$ac_cv_func__Exit" = xyes +then : + printf "%s\n" "#define HAVE__EXIT 1" >>confdefs.h fi -done - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pow in -lm" >&5 -$as_echo_n "checking for pow in -lm... " >&6; } -if ${ac_cv_lib_m_pow+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pow in -lm" >&5 +printf %s "checking for pow in -lm... " >&6; } +if test ${ac_cv_lib_m_pow+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -17004,139 +19782,410 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char pow (); int -main () +main (void) { return pow (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_m_pow=yes -else +else $as_nop ac_cv_lib_m_pow=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_pow" >&5 -$as_echo "$ac_cv_lib_m_pow" >&6; } -if test "x$ac_cv_lib_m_pow" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_pow" >&5 +printf "%s\n" "$ac_cv_lib_m_pow" >&6; } +if test "x$ac_cv_lib_m_pow" = xyes +then : LIBS="$LIBS -lm"; EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lm" fi - for ac_func in acos acosf asin asinf atan atanf atan2 atan2f ceil ceilf copysign copysignf cos cosf exp expf fabs fabsf floor floorf fmod fmodf log logf log10 log10f pow powf scalbn scalbnf sin sinf sqrt sqrtf tan tanf -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" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF + ac_fn_c_check_func "$LINENO" "acos" "ac_cv_func_acos" +if test "x$ac_cv_func_acos" = xyes +then : + printf "%s\n" "#define HAVE_ACOS 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "acosf" "ac_cv_func_acosf" +if test "x$ac_cv_func_acosf" = xyes +then : + printf "%s\n" "#define HAVE_ACOSF 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "asin" "ac_cv_func_asin" +if test "x$ac_cv_func_asin" = xyes +then : + printf "%s\n" "#define HAVE_ASIN 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "asinf" "ac_cv_func_asinf" +if test "x$ac_cv_func_asinf" = xyes +then : + printf "%s\n" "#define HAVE_ASINF 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "atan" "ac_cv_func_atan" +if test "x$ac_cv_func_atan" = xyes +then : + printf "%s\n" "#define HAVE_ATAN 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "atanf" "ac_cv_func_atanf" +if test "x$ac_cv_func_atanf" = xyes +then : + printf "%s\n" "#define HAVE_ATANF 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "atan2" "ac_cv_func_atan2" +if test "x$ac_cv_func_atan2" = xyes +then : + printf "%s\n" "#define HAVE_ATAN2 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "atan2f" "ac_cv_func_atan2f" +if test "x$ac_cv_func_atan2f" = xyes +then : + printf "%s\n" "#define HAVE_ATAN2F 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "ceil" "ac_cv_func_ceil" +if test "x$ac_cv_func_ceil" = xyes +then : + printf "%s\n" "#define HAVE_CEIL 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "ceilf" "ac_cv_func_ceilf" +if test "x$ac_cv_func_ceilf" = xyes +then : + printf "%s\n" "#define HAVE_CEILF 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "copysign" "ac_cv_func_copysign" +if test "x$ac_cv_func_copysign" = xyes +then : + printf "%s\n" "#define HAVE_COPYSIGN 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "copysignf" "ac_cv_func_copysignf" +if test "x$ac_cv_func_copysignf" = xyes +then : + printf "%s\n" "#define HAVE_COPYSIGNF 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "cos" "ac_cv_func_cos" +if test "x$ac_cv_func_cos" = xyes +then : + printf "%s\n" "#define HAVE_COS 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "cosf" "ac_cv_func_cosf" +if test "x$ac_cv_func_cosf" = xyes +then : + printf "%s\n" "#define HAVE_COSF 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "exp" "ac_cv_func_exp" +if test "x$ac_cv_func_exp" = xyes +then : + printf "%s\n" "#define HAVE_EXP 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "expf" "ac_cv_func_expf" +if test "x$ac_cv_func_expf" = xyes +then : + printf "%s\n" "#define HAVE_EXPF 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "fabs" "ac_cv_func_fabs" +if test "x$ac_cv_func_fabs" = xyes +then : + printf "%s\n" "#define HAVE_FABS 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "fabsf" "ac_cv_func_fabsf" +if test "x$ac_cv_func_fabsf" = xyes +then : + printf "%s\n" "#define HAVE_FABSF 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "floor" "ac_cv_func_floor" +if test "x$ac_cv_func_floor" = xyes +then : + printf "%s\n" "#define HAVE_FLOOR 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "floorf" "ac_cv_func_floorf" +if test "x$ac_cv_func_floorf" = xyes +then : + printf "%s\n" "#define HAVE_FLOORF 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "trunc" "ac_cv_func_trunc" +if test "x$ac_cv_func_trunc" = xyes +then : + printf "%s\n" "#define HAVE_TRUNC 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "truncf" "ac_cv_func_truncf" +if test "x$ac_cv_func_truncf" = xyes +then : + printf "%s\n" "#define HAVE_TRUNCF 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "fmod" "ac_cv_func_fmod" +if test "x$ac_cv_func_fmod" = xyes +then : + printf "%s\n" "#define HAVE_FMOD 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "fmodf" "ac_cv_func_fmodf" +if test "x$ac_cv_func_fmodf" = xyes +then : + printf "%s\n" "#define HAVE_FMODF 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "log" "ac_cv_func_log" +if test "x$ac_cv_func_log" = xyes +then : + printf "%s\n" "#define HAVE_LOG 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "logf" "ac_cv_func_logf" +if test "x$ac_cv_func_logf" = xyes +then : + printf "%s\n" "#define HAVE_LOGF 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "log10" "ac_cv_func_log10" +if test "x$ac_cv_func_log10" = xyes +then : + printf "%s\n" "#define HAVE_LOG10 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "log10f" "ac_cv_func_log10f" +if test "x$ac_cv_func_log10f" = xyes +then : + printf "%s\n" "#define HAVE_LOG10F 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "lround" "ac_cv_func_lround" +if test "x$ac_cv_func_lround" = xyes +then : + printf "%s\n" "#define HAVE_LROUND 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "lroundf" "ac_cv_func_lroundf" +if test "x$ac_cv_func_lroundf" = xyes +then : + printf "%s\n" "#define HAVE_LROUNDF 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "pow" "ac_cv_func_pow" +if test "x$ac_cv_func_pow" = xyes +then : + printf "%s\n" "#define HAVE_POW 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "powf" "ac_cv_func_powf" +if test "x$ac_cv_func_powf" = xyes +then : + printf "%s\n" "#define HAVE_POWF 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "round" "ac_cv_func_round" +if test "x$ac_cv_func_round" = xyes +then : + printf "%s\n" "#define HAVE_ROUND 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "roundf" "ac_cv_func_roundf" +if test "x$ac_cv_func_roundf" = xyes +then : + printf "%s\n" "#define HAVE_ROUNDF 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "scalbn" "ac_cv_func_scalbn" +if test "x$ac_cv_func_scalbn" = xyes +then : + printf "%s\n" "#define HAVE_SCALBN 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "scalbnf" "ac_cv_func_scalbnf" +if test "x$ac_cv_func_scalbnf" = xyes +then : + printf "%s\n" "#define HAVE_SCALBNF 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "sin" "ac_cv_func_sin" +if test "x$ac_cv_func_sin" = xyes +then : + printf "%s\n" "#define HAVE_SIN 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "sinf" "ac_cv_func_sinf" +if test "x$ac_cv_func_sinf" = xyes +then : + printf "%s\n" "#define HAVE_SINF 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "sqrt" "ac_cv_func_sqrt" +if test "x$ac_cv_func_sqrt" = xyes +then : + printf "%s\n" "#define HAVE_SQRT 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "sqrtf" "ac_cv_func_sqrtf" +if test "x$ac_cv_func_sqrtf" = xyes +then : + printf "%s\n" "#define HAVE_SQRTF 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "tan" "ac_cv_func_tan" +if test "x$ac_cv_func_tan" = xyes +then : + printf "%s\n" "#define HAVE_TAN 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "tanf" "ac_cv_func_tanf" +if test "x$ac_cv_func_tanf" = xyes +then : + printf "%s\n" "#define HAVE_TANF 1" >>confdefs.h fi -done - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv_open in -liconv" >&5 -$as_echo_n "checking for iconv_open in -liconv... " >&6; } -if ${ac_cv_lib_iconv_iconv_open+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-liconv $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext + if test x$enable_system_iconv = xyes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for iconv in libc" >&5 +printf %s "checking for iconv in libc... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char iconv_open (); + #define LIBICONV_PLUG 1 /* in case libiconv header is in include path */ + #include + #include + int -main () +main (void) { -return iconv_open (); + + iconv_open(NULL,NULL); + ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_iconv_iconv_open=yes -else - ac_cv_lib_iconv_iconv_open=no +if ac_fn_c_try_link "$LINENO" +then : + have_libc_iconv=yes +else $as_nop + have_libc_iconv=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_iconv_iconv_open" >&5 -$as_echo "$ac_cv_lib_iconv_iconv_open" >&6; } -if test "x$ac_cv_lib_iconv_iconv_open" = xyes; then : - LIBS="$LIBS -liconv"; EXTRA_LDFLAGS="$EXTRA_LDFLAGS -liconv" -fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_libc_iconv" >&5 +printf "%s\n" "$have_libc_iconv" >&6; } - for ac_func in iconv -do : - ac_fn_c_check_func "$LINENO" "iconv" "ac_cv_func_iconv" -if test "x$ac_cv_func_iconv" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_ICONV 1 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for iconv in libiconv" >&5 +printf %s "checking for iconv in libiconv... " >&6; } + save_LIBS="$LIBS" + LIBS="$LIBS -liconv" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + #include + +int +main (void) +{ + + iconv_open(NULL,NULL); + + ; + return 0; +} _ACEOF - +if ac_fn_c_try_link "$LINENO" +then : + have_libiconv=yes +else $as_nop + have_libiconv=no fi -done +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + LIBS="$save_LIBS" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_libiconv" >&5 +printf "%s\n" "$have_libiconv" >&6; } + if test x$have_libc_iconv = xyes || test x$have_libiconv = xyes; then + +printf "%s\n" "#define HAVE_ICONV 1" >>confdefs.h + + + if test x$have_libiconv = xyes; then + if test x$have_libc_iconv != xyes; then + use_libiconv=yes + elif test x$enable_libiconv = xyes; then + use_libiconv=yes + fi + fi + if test x$use_libiconv = xyes; then + +printf "%s\n" "#define SDL_USE_LIBICONV 1" >>confdefs.h + + EXTRA_LDFLAGS="$EXTRA_LDFLAGS -liconv" + echo "-- Using iconv from libiconv" + else + echo "-- Using iconv from libc" + fi + fi + fi ac_fn_c_check_member "$LINENO" "struct sigaction" "sa_sigaction" "ac_cv_member_struct_sigaction_sa_sigaction" "#include " -if test "x$ac_cv_member_struct_sigaction_sa_sigaction" = xyes; then : +if test "x$ac_cv_member_struct_sigaction_sa_sigaction" = xyes +then : -$as_echo "#define HAVE_SA_SIGACTION 1" >>confdefs.h +printf "%s\n" "#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 + ac_fn_c_check_header_compile "$LINENO" "libunwind.h" "ac_cv_header_libunwind_h" "$ac_includes_default" +if test "x$ac_cv_header_libunwind_h" = xyes +then : + printf "%s\n" "#define HAVE_LIBUNWIND_H 1" >>confdefs.h fi -done - fi # Check whether --enable-gcc-atomics was given. -if test "${enable_gcc_atomics+set}" = set; then : +if test ${enable_gcc_atomics+y} +then : enableval=$enable_gcc_atomics; -else +else $as_nop enable_gcc_atomics=yes fi if test x$enable_gcc_atomics = xyes; then have_gcc_atomics=no - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GCC builtin atomic operations" >&5 -$as_echo_n "checking for GCC builtin atomic operations... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GCC builtin atomic operations" >&5 +printf %s "checking for GCC builtin atomic operations... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - int -main () +main (void) { int a; @@ -17151,28 +20200,26 @@ main () return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - - have_gcc_atomics=yes - +if ac_fn_c_try_link "$LINENO" +then : + have_gcc_atomics=yes fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_gcc_atomics" >&5 -$as_echo "$have_gcc_atomics" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_gcc_atomics" >&5 +printf "%s\n" "$have_gcc_atomics" >&6; } if test x$have_gcc_atomics = xyes; then -$as_echo "#define HAVE_GCC_ATOMICS 1" >>confdefs.h +printf "%s\n" "#define HAVE_GCC_ATOMICS 1" >>confdefs.h else # See if we have the minimum operation needed for GCC atomics cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - int -main () +main (void) { int a; @@ -17183,16 +20230,15 @@ main () return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - - have_gcc_sync_lock_test_and_set=yes - +if ac_fn_c_try_link "$LINENO" +then : + have_gcc_sync_lock_test_and_set=yes fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext if test x$have_gcc_sync_lock_test_and_set = xyes; then -$as_echo "#define HAVE_GCC_SYNC_LOCK_TEST_AND_SET 1" >>confdefs.h +printf "%s\n" "#define HAVE_GCC_SYNC_LOCK_TEST_AND_SET 1" >>confdefs.h fi fi @@ -17207,8 +20253,10 @@ SOURCES="$SOURCES $srcdir/src/dynapi/*.c" SOURCES="$SOURCES $srcdir/src/events/*.c" SOURCES="$SOURCES $srcdir/src/file/*.c" SOURCES="$SOURCES $srcdir/src/haptic/*.c" +SOURCES="$SOURCES $srcdir/src/hidapi/*.c" SOURCES="$SOURCES $srcdir/src/joystick/*.c" SOURCES="$SOURCES $srcdir/src/libm/*.c" +SOURCES="$SOURCES $srcdir/src/misc/*.c" SOURCES="$SOURCES $srcdir/src/power/*.c" #SOURCES="$SOURCES $srcdir/src/filesystem/*.c" SOURCES="$SOURCES $srcdir/src/render/*.c" @@ -17219,232 +20267,296 @@ SOURCES="$SOURCES $srcdir/src/thread/*.c" SOURCES="$SOURCES $srcdir/src/timer/*.c" SOURCES="$SOURCES $srcdir/src/video/*.c" SOURCES="$SOURCES $srcdir/src/video/yuv2rgb/*.c" +SOURCES="$SOURCES $srcdir/src/locale/*.c" +case "$host" in + *-*-emscripten*) + default_atomic=no + ;; + *) + default_atomic=yes + ;; +esac + # Check whether --enable-atomic was given. -if test "${enable_atomic+set}" = set; then : +if test ${enable_atomic+y} +then : enableval=$enable_atomic; -else - enable_atomic=yes +else $as_nop + enable_atomic=$default_atomic fi if test x$enable_atomic != xyes; then -$as_echo "#define SDL_ATOMIC_DISABLED 1" >>confdefs.h +printf "%s\n" "#define SDL_ATOMIC_DISABLED 1" >>confdefs.h else SUMMARY_modules="${SUMMARY_modules} atomic" fi # Check whether --enable-audio was given. -if test "${enable_audio+set}" = set; then : +if test ${enable_audio+y} +then : enableval=$enable_audio; -else +else $as_nop enable_audio=yes fi if test x$enable_audio != xyes; then -$as_echo "#define SDL_AUDIO_DISABLED 1" >>confdefs.h +printf "%s\n" "#define SDL_AUDIO_DISABLED 1" >>confdefs.h else SUMMARY_modules="${SUMMARY_modules} audio" fi # Check whether --enable-video was given. -if test "${enable_video+set}" = set; then : +if test ${enable_video+y} +then : enableval=$enable_video; -else +else $as_nop enable_video=yes fi if test x$enable_video != xyes; then -$as_echo "#define SDL_VIDEO_DISABLED 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_DISABLED 1" >>confdefs.h else SUMMARY_modules="${SUMMARY_modules} video" fi # Check whether --enable-render was given. -if test "${enable_render+set}" = set; then : +if test ${enable_render+y} +then : enableval=$enable_render; -else +else $as_nop enable_render=yes fi if test x$enable_render != xyes; then -$as_echo "#define SDL_RENDER_DISABLED 1" >>confdefs.h +printf "%s\n" "#define SDL_RENDER_DISABLED 1" >>confdefs.h else SUMMARY_modules="${SUMMARY_modules} render" fi # Check whether --enable-events was given. -if test "${enable_events+set}" = set; then : +if test ${enable_events+y} +then : enableval=$enable_events; -else +else $as_nop enable_events=yes fi if test x$enable_events != xyes; then -$as_echo "#define SDL_EVENTS_DISABLED 1" >>confdefs.h +printf "%s\n" "#define SDL_EVENTS_DISABLED 1" >>confdefs.h else SUMMARY_modules="${SUMMARY_modules} events" fi # Check whether --enable-joystick was given. -if test "${enable_joystick+set}" = set; then : +if test ${enable_joystick+y} +then : enableval=$enable_joystick; -else +else $as_nop enable_joystick=yes fi if test x$enable_joystick != xyes; then -$as_echo "#define SDL_JOYSTICK_DISABLED 1" >>confdefs.h +printf "%s\n" "#define SDL_JOYSTICK_DISABLED 1" >>confdefs.h else SUMMARY_modules="${SUMMARY_modules} joystick" fi # Check whether --enable-haptic was given. -if test "${enable_haptic+set}" = set; then : +if test ${enable_haptic+y} +then : enableval=$enable_haptic; -else +else $as_nop enable_haptic=yes fi if test x$enable_haptic != xyes; then -$as_echo "#define SDL_HAPTIC_DISABLED 1" >>confdefs.h +printf "%s\n" "#define SDL_HAPTIC_DISABLED 1" >>confdefs.h else SUMMARY_modules="${SUMMARY_modules} haptic" fi -# Check whether --enable-sensor was given. -if test "${enable_sensor+set}" = set; then : - enableval=$enable_sensor; +# Check whether --enable-hidapi was given. +if test ${enable_hidapi+y} +then : + enableval=$enable_hidapi; +else $as_nop + enable_hidapi=yes +fi + +if test x$enable_hidapi != xyes; then + +printf "%s\n" "#define SDL_HIDAPI_DISABLED 1" >>confdefs.h + else + SUMMARY_modules="${SUMMARY_modules} hidapi" +fi +# Check whether --enable-sensor was given. +if test ${enable_sensor+y} +then : + enableval=$enable_sensor; +else $as_nop enable_sensor=yes fi if test x$enable_sensor != xyes; then -$as_echo "#define SDL_SENSOR_DISABLED 1" >>confdefs.h +printf "%s\n" "#define SDL_SENSOR_DISABLED 1" >>confdefs.h else SUMMARY_modules="${SUMMARY_modules} sensor" fi # Check whether --enable-power was given. -if test "${enable_power+set}" = set; then : +if test ${enable_power+y} +then : enableval=$enable_power; -else +else $as_nop enable_power=yes fi if test x$enable_power != xyes; then -$as_echo "#define SDL_POWER_DISABLED 1" >>confdefs.h +printf "%s\n" "#define SDL_POWER_DISABLED 1" >>confdefs.h else SUMMARY_modules="${SUMMARY_modules} power" fi # Check whether --enable-filesystem was given. -if test "${enable_filesystem+set}" = set; then : +if test ${enable_filesystem+y} +then : enableval=$enable_filesystem; -else +else $as_nop enable_filesystem=yes fi if test x$enable_filesystem != xyes; then -$as_echo "#define SDL_FILESYSTEM_DISABLED 1" >>confdefs.h +printf "%s\n" "#define SDL_FILESYSTEM_DISABLED 1" >>confdefs.h else SUMMARY_modules="${SUMMARY_modules} filesystem" fi -# Check whether --enable-threads was given. -if test "${enable_threads+set}" = set; then : - enableval=$enable_threads; -else - enable_threads=yes -fi - +# Many subsystems depend on threads, so leave them enabled by default +#AC_ARG_ENABLE(threads, +#[AS_HELP_STRING([--enable-threads], [Enable the threading subsystem [default=yes]])], +# , enable_threads=yes) +enable_threads=yes if test x$enable_threads != xyes; then -$as_echo "#define SDL_THREADS_DISABLED 1" >>confdefs.h +printf "%s\n" "#define SDL_THREADS_DISABLED 1" >>confdefs.h else SUMMARY_modules="${SUMMARY_modules} threads" fi # Check whether --enable-timers was given. -if test "${enable_timers+set}" = set; then : +if test ${enable_timers+y} +then : enableval=$enable_timers; -else +else $as_nop enable_timers=yes fi if test x$enable_timers != xyes; then -$as_echo "#define SDL_TIMERS_DISABLED 1" >>confdefs.h +printf "%s\n" "#define SDL_TIMERS_DISABLED 1" >>confdefs.h else SUMMARY_modules="${SUMMARY_modules} timers" fi # Check whether --enable-file was given. -if test "${enable_file+set}" = set; then : +if test ${enable_file+y} +then : enableval=$enable_file; -else +else $as_nop enable_file=yes fi if test x$enable_file != xyes; then -$as_echo "#define SDL_FILE_DISABLED 1" >>confdefs.h +printf "%s\n" "#define SDL_FILE_DISABLED 1" >>confdefs.h else SUMMARY_modules="${SUMMARY_modules} file" fi -# Check whether --enable-loadso was given. -if test "${enable_loadso+set}" = set; then : - enableval=$enable_loadso; +# Check whether --enable-misc was given. +if test ${enable_misc+y} +then : + enableval=$enable_misc; +else $as_nop + enable_misc=yes +fi + +if test x$enable_misc != xyes; then + +printf "%s\n" "#define SDL_MISC_DISABLED 1" >>confdefs.h + else + SUMMARY_modules="${SUMMARY_modules} misc" +fi +# Check whether --enable-locale was given. +if test ${enable_locale+y} +then : + enableval=$enable_locale; +else $as_nop + enable_locale=yes +fi + +if test x$enable_locale != xyes; then + +printf "%s\n" "#define SDL_LOCALE_DISABLED 1" >>confdefs.h + +else + SUMMARY_modules="${SUMMARY_modules} locale" +fi +# Check whether --enable-loadso was given. +if test ${enable_loadso+y} +then : + enableval=$enable_loadso; +else $as_nop enable_loadso=yes fi if test x$enable_loadso != xyes; then -$as_echo "#define SDL_LOADSO_DISABLED 1" >>confdefs.h +printf "%s\n" "#define SDL_LOADSO_DISABLED 1" >>confdefs.h else SUMMARY_modules="${SUMMARY_modules} loadso" fi # Check whether --enable-cpuinfo was given. -if test "${enable_cpuinfo+set}" = set; then : +if test ${enable_cpuinfo+y} +then : enableval=$enable_cpuinfo; -else +else $as_nop enable_cpuinfo=yes fi if test x$enable_cpuinfo != xyes; then -$as_echo "#define SDL_CPUINFO_DISABLED 1" >>confdefs.h +printf "%s\n" "#define SDL_CPUINFO_DISABLED 1" >>confdefs.h else SUMMARY_modules="${SUMMARY_modules} cpuinfo" fi # Check whether --enable-assembly was given. -if test "${enable_assembly+set}" = set; then : +if test ${enable_assembly+y} +then : enableval=$enable_assembly; -else +else $as_nop enable_assembly=yes fi if test x$enable_assembly = xyes; then SUMMARY_modules="${SUMMARY_modules} assembly" - -$as_echo "#define SDL_ASSEMBLY_ROUTINES 1" >>confdefs.h - - # Make sure that we don't generate floating point code that would # cause illegal instruction exceptions on older processors case "$host" in @@ -17461,9 +20573,10 @@ $as_echo "#define SDL_ASSEMBLY_ROUTINES 1" >>confdefs.h ;; esac # Check whether --enable-ssemath was given. -if test "${enable_ssemath+set}" = set; then : +if test ${enable_ssemath+y} +then : enableval=$enable_ssemath; -else +else $as_nop enable_ssemath=$default_ssemath fi @@ -17473,18 +20586,19 @@ fi fi fi - # Check whether --enable-mmx was given. -if test "${enable_mmx+set}" = set; then : + # Check whether --enable-mmx was given. +if test ${enable_mmx+y} +then : enableval=$enable_mmx; -else +else $as_nop enable_mmx=yes fi if test x$enable_mmx = xyes; then save_CFLAGS="$CFLAGS" have_gcc_mmx=no - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GCC -mmmx option" >&5 -$as_echo_n "checking for GCC -mmmx option... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GCC -mmmx option" >&5 +printf %s "checking for GCC -mmmx option... " >&6; } mmx_CFLAGS="-mmmx" CFLAGS="$save_CFLAGS $mmx_CFLAGS" @@ -17506,22 +20620,20 @@ $as_echo_n "checking for GCC -mmmx option... " >&6; } #endif int -main () +main (void) { - ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - have_gcc_mmx=yes - +if ac_fn_c_try_compile "$LINENO" +then : + have_gcc_mmx=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_gcc_mmx" >&5 -$as_echo "$have_gcc_mmx" >&6; } +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_gcc_mmx" >&5 +printf "%s\n" "$have_gcc_mmx" >&6; } CFLAGS="$save_CFLAGS" if test x$have_gcc_mmx = xyes; then @@ -17531,17 +20643,18 @@ $as_echo "$have_gcc_mmx" >&6; } fi # Check whether --enable-3dnow was given. -if test "${enable_3dnow+set}" = set; then : +if test ${enable_3dnow+y} +then : enableval=$enable_3dnow; -else +else $as_nop enable_3dnow=yes fi if test x$enable_3dnow = xyes; then save_CFLAGS="$CFLAGS" have_gcc_3dnow=no - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GCC -m3dnow option" >&5 -$as_echo_n "checking for GCC -m3dnow option... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GCC -m3dnow option" >&5 +printf %s "checking for GCC -m3dnow option... " >&6; } amd3dnow_CFLAGS="-m3dnow" CFLAGS="$save_CFLAGS $amd3dnow_CFLAGS" @@ -17554,7 +20667,7 @@ $as_echo_n "checking for GCC -m3dnow option... " >&6; } #endif int -main () +main (void) { void *p = 0; @@ -17564,15 +20677,14 @@ main () return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - - have_gcc_3dnow=yes - +if ac_fn_c_try_link "$LINENO" +then : + have_gcc_3dnow=yes fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_gcc_3dnow" >&5 -$as_echo "$have_gcc_3dnow" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_gcc_3dnow" >&5 +printf "%s\n" "$have_gcc_3dnow" >&6; } CFLAGS="$save_CFLAGS" if test x$have_gcc_3dnow = xyes; then @@ -17582,17 +20694,18 @@ $as_echo "$have_gcc_3dnow" >&6; } fi # Check whether --enable-sse was given. -if test "${enable_sse+set}" = set; then : +if test ${enable_sse+y} +then : enableval=$enable_sse; -else +else $as_nop enable_sse=yes fi if test x$enable_sse = xyes; then save_CFLAGS="$CFLAGS" have_gcc_sse=no - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GCC -msse option" >&5 -$as_echo_n "checking for GCC -msse option... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GCC -msse option" >&5 +printf %s "checking for GCC -msse option... " >&6; } sse_CFLAGS="-msse" CFLAGS="$save_CFLAGS $sse_CFLAGS" @@ -17614,22 +20727,20 @@ $as_echo_n "checking for GCC -msse option... " >&6; } #endif int -main () +main (void) { - ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - have_gcc_sse=yes - +if ac_fn_c_try_compile "$LINENO" +then : + have_gcc_sse=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_gcc_sse" >&5 -$as_echo "$have_gcc_sse" >&6; } +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_gcc_sse" >&5 +printf "%s\n" "$have_gcc_sse" >&6; } CFLAGS="$save_CFLAGS" if test x$have_gcc_sse = xyes; then @@ -17639,17 +20750,18 @@ $as_echo "$have_gcc_sse" >&6; } fi # Check whether --enable-sse2 was given. -if test "${enable_sse2+set}" = set; then : +if test ${enable_sse2+y} +then : enableval=$enable_sse2; -else +else $as_nop enable_sse2=$default_ssemath fi if test x$enable_sse2 = xyes; then save_CFLAGS="$CFLAGS" have_gcc_sse2=no - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GCC -msse2 option" >&5 -$as_echo_n "checking for GCC -msse2 option... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GCC -msse2 option" >&5 +printf %s "checking for GCC -msse2 option... " >&6; } sse2_CFLAGS="-msse2" CFLAGS="$save_CFLAGS $sse2_CFLAGS" @@ -17671,22 +20783,20 @@ $as_echo_n "checking for GCC -msse2 option... " >&6; } #endif int -main () +main (void) { - ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - have_gcc_sse2=yes - +if ac_fn_c_try_compile "$LINENO" +then : + have_gcc_sse2=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_gcc_sse2" >&5 -$as_echo "$have_gcc_sse2" >&6; } +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_gcc_sse2" >&5 +printf "%s\n" "$have_gcc_sse2" >&6; } CFLAGS="$save_CFLAGS" if test x$have_gcc_sse2 = xyes; then @@ -17696,17 +20806,18 @@ $as_echo "$have_gcc_sse2" >&6; } fi # Check whether --enable-sse3 was given. -if test "${enable_sse3+set}" = set; then : +if test ${enable_sse3+y} +then : enableval=$enable_sse3; -else +else $as_nop enable_sse3=$default_ssemath fi if test x$enable_sse3 = xyes; then save_CFLAGS="$CFLAGS" have_gcc_sse3=no - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GCC -msse3 option" >&5 -$as_echo_n "checking for GCC -msse3 option... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GCC -msse3 option" >&5 +printf %s "checking for GCC -msse3 option... " >&6; } sse3_CFLAGS="-msse3" CFLAGS="$save_CFLAGS $sse3_CFLAGS" @@ -17728,22 +20839,20 @@ $as_echo_n "checking for GCC -msse3 option... " >&6; } #endif int -main () +main (void) { - ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - have_gcc_sse3=yes - +if ac_fn_c_try_compile "$LINENO" +then : + have_gcc_sse3=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_gcc_sse3" >&5 -$as_echo "$have_gcc_sse3" >&6; } +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_gcc_sse3" >&5 +printf "%s\n" "$have_gcc_sse3" >&6; } CFLAGS="$save_CFLAGS" if test x$have_gcc_sse3 = xyes; then @@ -17752,24 +20861,39 @@ $as_echo "$have_gcc_sse3" >&6; } fi fi - ac_fn_c_check_header_mongrel "$LINENO" "immintrin.h" "ac_cv_header_immintrin_h" "$ac_includes_default" -if test "x$ac_cv_header_immintrin_h" = xyes; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for immintrin.h" >&5 +printf %s "checking for immintrin.h... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : have_immintrin_h_hdr=yes -else +else $as_nop have_immintrin_h_hdr=no fi - - +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_immintrin_h_hdr" >&5 +printf "%s\n" "$have_immintrin_h_hdr" >&6; } if test x$have_immintrin_h_hdr = xyes; then -$as_echo "#define HAVE_IMMINTRIN_H 1" >>confdefs.h +printf "%s\n" "#define HAVE_IMMINTRIN_H 1" >>confdefs.h fi # Check whether --enable-altivec was given. -if test "${enable_altivec+set}" = set; then : +if test ${enable_altivec+y} +then : enableval=$enable_altivec; -else +else $as_nop enable_altivec=yes fi @@ -17780,8 +20904,8 @@ fi altivec_CFLAGS="-maltivec" CFLAGS="$save_CFLAGS $altivec_CFLAGS" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Altivec with GCC altivec.h and -maltivec option" >&5 -$as_echo_n "checking for Altivec with GCC altivec.h and -maltivec option... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Altivec with GCC altivec.h and -maltivec option" >&5 +printf %s "checking for Altivec with GCC altivec.h and -maltivec option... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -17791,27 +20915,27 @@ $as_echo_n "checking for Altivec with GCC altivec.h and -maltivec option... " >& } int -main () +main (void) { - ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : have_gcc_altivec=yes have_altivec_h_hdr=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_gcc_altivec" >&5 -$as_echo "$have_gcc_altivec" >&6; } +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_gcc_altivec" >&5 +printf "%s\n" "$have_gcc_altivec" >&6; } if test x$have_gcc_altivec = xno; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Altivec with GCC -maltivec option" >&5 -$as_echo_n "checking for Altivec with GCC -maltivec option... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Altivec with GCC -maltivec option" >&5 +printf %s "checking for Altivec with GCC -maltivec option... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -17820,27 +20944,25 @@ $as_echo_n "checking for Altivec with GCC -maltivec option... " >&6; } } int -main () +main (void) { - ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - have_gcc_altivec=yes - +if ac_fn_c_try_compile "$LINENO" +then : + have_gcc_altivec=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_gcc_altivec" >&5 -$as_echo "$have_gcc_altivec" >&6; } +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_gcc_altivec" >&5 +printf "%s\n" "$have_gcc_altivec" >&6; } fi if test x$have_gcc_altivec = xno; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Altivec with GCC altivec.h and -faltivec option" >&5 -$as_echo_n "checking for Altivec with GCC altivec.h and -faltivec option... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Altivec with GCC altivec.h and -faltivec option" >&5 +printf %s "checking for Altivec with GCC altivec.h and -faltivec option... " >&6; } altivec_CFLAGS="-faltivec" CFLAGS="$save_CFLAGS $altivec_CFLAGS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -17852,28 +20974,28 @@ $as_echo_n "checking for Altivec with GCC altivec.h and -faltivec option... " >& } int -main () +main (void) { - ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : have_gcc_altivec=yes have_altivec_h_hdr=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_gcc_altivec" >&5 -$as_echo "$have_gcc_altivec" >&6; } +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_gcc_altivec" >&5 +printf "%s\n" "$have_gcc_altivec" >&6; } fi if test x$have_gcc_altivec = xno; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Altivec with GCC -faltivec option" >&5 -$as_echo_n "checking for Altivec with GCC -faltivec option... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Altivec with GCC -faltivec option" >&5 +printf %s "checking for Altivec with GCC -faltivec option... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -17882,32 +21004,30 @@ $as_echo_n "checking for Altivec with GCC -faltivec option... " >&6; } } int -main () +main (void) { - ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - have_gcc_altivec=yes - +if ac_fn_c_try_compile "$LINENO" +then : + have_gcc_altivec=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_gcc_altivec" >&5 -$as_echo "$have_gcc_altivec" >&6; } +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_gcc_altivec" >&5 +printf "%s\n" "$have_gcc_altivec" >&6; } fi CFLAGS="$save_CFLAGS" if test x$have_gcc_altivec = xyes; then -$as_echo "#define SDL_ALTIVEC_BLITTERS 1" >>confdefs.h +printf "%s\n" "#define SDL_ALTIVEC_BLITTERS 1" >>confdefs.h if test x$have_altivec_h_hdr = xyes; then -$as_echo "#define HAVE_ALTIVEC_H 1" >>confdefs.h +printf "%s\n" "#define HAVE_ALTIVEC_H 1" >>confdefs.h fi EXTRA_CFLAGS="$EXTRA_CFLAGS $altivec_CFLAGS" @@ -17916,30 +21036,97 @@ $as_echo "#define HAVE_ALTIVEC_H 1" >>confdefs.h fi fi + # Check whether --enable-lsx was given. +if test ${enable_lsx+y} +then : + enableval=$enable_lsx; +else $as_nop + enable_lsx=yes +fi + + if test x$enable_lsx = xyes; then + save_CFLAGS="$CFLAGS" + have_gcc_lsx=no + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GCC -mlsx option" >&5 +printf %s "checking for GCC -mlsx option... " >&6; } + lsx_CFLAGS="-mlsx" + CFLAGS="$save_CFLAGS $lsx_CFLAGS" + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #ifndef __loongarch_sx + #error Assembler CPP flag not enabled + #endif + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + have_gcc_lsx=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_gcc_lsx" >&5 +printf "%s\n" "$have_gcc_lsx" >&6; } + CFLAGS="$save_CFLAGS" + + if test x$have_gcc_lsx = xyes; then + EXTRA_CFLAGS="$EXTRA_CFLAGS $lsx_CFLAGS" + SUMMARY_math="${SUMMARY_math} lsx" + fi + fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for lsxintrin.h" >&5 +printf %s "checking for lsxintrin.h... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + have_lsxintrin_h_hdr=yes +else $as_nop + have_lsxintrin_h_hdr=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_lsxintrin_h_hdr" >&5 +printf "%s\n" "$have_lsxintrin_h_hdr" >&6; } + if test x$have_lsxintrin_h_hdr = xyes; then + +printf "%s\n" "#define HAVE_LSXINTRIN_H 1" >>confdefs.h + + fi + CheckOSS() { # Check whether --enable-oss was given. -if test "${enable_oss+set}" = set; then : +if test ${enable_oss+y} +then : enableval=$enable_oss; -else +else $as_nop enable_oss=maybe fi - - # OpenBSD "has" OSS, but it's not really for app use. They want you to - # use sndio instead. So on there, we default to disabled. You can force - # it on if you really want, though. if test x$enable_oss = xmaybe; then enable_oss=yes - case "$host" in - *-*-openbsd*) - enable_oss=no;; - esac fi if test x$enable_audio = xyes -a x$enable_oss = xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OSS audio support" >&5 -$as_echo_n "checking for OSS audio support... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for OSS audio support" >&5 +printf %s "checking for OSS audio support... " >&6; } have_oss=no if test x$have_oss != xyes; then cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -17948,7 +21135,7 @@ $as_echo_n "checking for OSS audio support... " >&6; } #include int -main () +main (void) { int arg = SNDCTL_DSP_SETFRAGMENT; @@ -17957,52 +21144,25 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - have_oss=yes - +if ac_fn_c_try_compile "$LINENO" +then : + have_oss=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi - if test x$have_oss != xyes; then - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - #include - -int -main () -{ - - int arg = SNDCTL_DSP_SETFRAGMENT; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - have_oss=yes - -$as_echo "#define SDL_AUDIO_DRIVER_OSS_SOUNDCARD_H 1" >>confdefs.h - - -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_oss" >&5 -$as_echo "$have_oss" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_oss" >&5 +printf "%s\n" "$have_oss" >&6; } if test x$have_oss = xyes; then SUMMARY_audio="${SUMMARY_audio} oss" -$as_echo "#define SDL_AUDIO_DRIVER_OSS 1" >>confdefs.h +printf "%s\n" "#define SDL_AUDIO_DRIVER_OSS 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/audio/dsp/*.c" have_audio=yes # We may need to link with ossaudio emulation library case "$host" in - *-*-openbsd*|*-*-netbsd*) + *-*-netbsd*) EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lossaudio";; esac fi @@ -18012,9 +21172,10 @@ $as_echo "#define SDL_AUDIO_DRIVER_OSS 1" >>confdefs.h CheckALSA() { # Check whether --enable-alsa was given. -if test "${enable_alsa+set}" = set; then : +if test ${enable_alsa+y} +then : enableval=$enable_alsa; -else +else $as_nop enable_alsa=yes fi @@ -18026,41 +21187,44 @@ alsa_found=yes # Check whether --with-alsa-prefix was given. -if test "${with_alsa_prefix+set}" = set; then : +if test ${with_alsa_prefix+y} +then : withval=$with_alsa_prefix; alsa_prefix="$withval" -else +else $as_nop alsa_prefix="" fi # Check whether --with-alsa-inc-prefix was given. -if test "${with_alsa_inc_prefix+set}" = set; then : +if test ${with_alsa_inc_prefix+y} +then : withval=$with_alsa_inc_prefix; alsa_inc_prefix="$withval" -else +else $as_nop alsa_inc_prefix="" fi # Check whether --enable-alsatest was given. -if test "${enable_alsatest+set}" = set; then : +if test ${enable_alsatest+y} +then : enableval=$enable_alsatest; enable_alsatest="$enableval" -else +else $as_nop enable_alsatest=yes fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ALSA CFLAGS" >&5 -$as_echo_n "checking for ALSA CFLAGS... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ALSA CFLAGS" >&5 +printf %s "checking for ALSA CFLAGS... " >&6; } if test "$alsa_inc_prefix" != "" ; then ALSA_CFLAGS="$ALSA_CFLAGS -I$alsa_inc_prefix" CFLAGS="$CFLAGS -I$alsa_inc_prefix" fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ALSA_CFLAGS" >&5 -$as_echo "$ALSA_CFLAGS" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ALSA_CFLAGS" >&5 +printf "%s\n" "$ALSA_CFLAGS" >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ALSA LDFLAGS" >&5 -$as_echo_n "checking for ALSA LDFLAGS... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ALSA LDFLAGS" >&5 +printf %s "checking for ALSA LDFLAGS... " >&6; } if test "$alsa_prefix" != "" ; then ALSA_LIBS="$ALSA_LIBS -L$alsa_prefix" LDFLAGS="$LDFLAGS $ALSA_LIBS" @@ -18072,12 +21236,12 @@ LIBS=`echo $LIBS | sed 's/-ldl//'` LIBS=`echo $LIBS | sed 's/-lpthread//'` LIBS=`echo $LIBS | sed 's/ //'` LIBS="$ALSA_LIBS $LIBS" -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ALSA_LIBS" >&5 -$as_echo "$ALSA_LIBS" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ALSA_LIBS" >&5 +printf "%s\n" "$ALSA_LIBS" >&6; } min_alsa_version=1.0.11 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libasound headers version >= $min_alsa_version" >&5 -$as_echo_n "checking for libasound headers version >= $min_alsa_version... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libasound headers version >= $min_alsa_version" >&5 +printf %s "checking for libasound headers version >= $min_alsa_version... " >&6; } no_alsa="" alsa_min_major_version=`echo $min_alsa_version | \ sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\1/'` @@ -18086,7 +21250,6 @@ no_alsa="" alsa_min_micro_version=`echo $min_alsa_version | \ sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\3/'` - ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -18099,7 +21262,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext #include int -main () +main (void) { /* ensure backward compatibility */ @@ -18138,17 +21301,18 @@ exit(0); return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: found." >&5 -$as_echo "found." >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: not present." >&5 -$as_echo "not present." >&6; } +if ac_fn_c_try_compile "$LINENO" +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found." >&5 +printf "%s\n" "found." >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: not present." >&5 +printf "%s\n" "not present." >&6; } alsa_found=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -18157,11 +21321,12 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu if test "x$enable_alsatest" = "xyes"; then -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for snd_ctl_open in -lasound" >&5 -$as_echo_n "checking for snd_ctl_open in -lasound... " >&6; } -if ${ac_cv_lib_asound_snd_ctl_open+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for snd_ctl_open in -lasound" >&5 +printf %s "checking for snd_ctl_open in -lasound... " >&6; } +if test ${ac_cv_lib_asound_snd_ctl_open+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lasound $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -18170,37 +21335,34 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char snd_ctl_open (); int -main () +main (void) { return snd_ctl_open (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_asound_snd_ctl_open=yes -else +else $as_nop ac_cv_lib_asound_snd_ctl_open=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_asound_snd_ctl_open" >&5 -$as_echo "$ac_cv_lib_asound_snd_ctl_open" >&6; } -if test "x$ac_cv_lib_asound_snd_ctl_open" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBASOUND 1 -_ACEOF +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_asound_snd_ctl_open" >&5 +printf "%s\n" "$ac_cv_lib_asound_snd_ctl_open" >&6; } +if test "x$ac_cv_lib_asound_snd_ctl_open" = xyes +then : + printf "%s\n" "#define HAVE_LIBASOUND 1" >>confdefs.h LIBS="-lasound $LIBS" -else +else $as_nop alsa_found=no @@ -18232,31 +21394,30 @@ fi LIBS="$alsa_save_LIBS" if test x$have_alsa = xyes; then # Check whether --enable-alsa-shared was given. -if test "${enable_alsa_shared+set}" = set; then : +if test ${enable_alsa_shared+y} +then : enableval=$enable_alsa_shared; -else +else $as_nop enable_alsa_shared=yes fi alsa_lib=`find_lib "libasound.so.*" "$ALSA_LIBS" | sed 's/.*\/\(.*\)/\1/; q'` -$as_echo "#define SDL_AUDIO_DRIVER_ALSA 1" >>confdefs.h +printf "%s\n" "#define SDL_AUDIO_DRIVER_ALSA 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/audio/alsa/*.c" EXTRA_CFLAGS="$EXTRA_CFLAGS $ALSA_CFLAGS" if test x$have_loadso != xyes && \ test x$enable_alsa_shared = xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: You must have SDL_LoadObject() support for dynamic ALSA loading" >&5 -$as_echo "$as_me: WARNING: You must have SDL_LoadObject() support for dynamic ALSA loading" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: You must have SDL_LoadObject() support for dynamic ALSA loading" >&5 +printf "%s\n" "$as_me: WARNING: You must have SDL_LoadObject() support for dynamic ALSA loading" >&2;} fi if test x$have_loadso = xyes && \ test x$enable_alsa_shared = xyes && test x$alsa_lib != x; then echo "-- dynamic libasound -> $alsa_lib" -cat >>confdefs.h <<_ACEOF -#define SDL_AUDIO_DRIVER_ALSA_DYNAMIC "$alsa_lib" -_ACEOF +printf "%s\n" "#define SDL_AUDIO_DRIVER_ALSA_DYNAMIC \"$alsa_lib\"" >>confdefs.h SUMMARY_audio="${SUMMARY_audio} alsa(dynamic)" else @@ -18271,28 +21432,30 @@ _ACEOF CheckJACK() { # Check whether --enable-jack was given. -if test "${enable_jack+set}" = set; then : +if test ${enable_jack+y} +then : enableval=$enable_jack; -else +else $as_nop enable_jack=yes fi if test x$enable_audio = xyes -a x$enable_jack = xyes; then pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for JACK" >&5 -$as_echo_n "checking for JACK... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for jack >= 0.125" >&5 +printf %s "checking for jack >= 0.125... " >&6; } if test -n "$JACK_CFLAGS"; then pkg_cv_JACK_CFLAGS="$JACK_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"jack >= 0.125\""; } >&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"jack >= 0.125\""; } >&5 ($PKG_CONFIG --exists --print-errors "jack >= 0.125") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_JACK_CFLAGS=`$PKG_CONFIG --cflags "jack >= 0.125" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi @@ -18303,12 +21466,13 @@ if test -n "$JACK_LIBS"; then pkg_cv_JACK_LIBS="$JACK_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"jack >= 0.125\""; } >&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"jack >= 0.125\""; } >&5 ($PKG_CONFIG --exists --print-errors "jack >= 0.125") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_JACK_LIBS=`$PKG_CONFIG --libs "jack >= 0.125" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi @@ -18319,8 +21483,8 @@ fi if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes @@ -18328,53 +21492,52 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - JACK_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "jack >= 0.125" 2>&1` + JACK_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "jack >= 0.125" 2>&1` else - JACK_PKG_ERRORS=`$PKG_CONFIG --print-errors "jack >= 0.125" 2>&1` + JACK_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "jack >= 0.125" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$JACK_PKG_ERRORS" >&5 audio_jack=no elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } audio_jack=no else JACK_CFLAGS=$pkg_cv_JACK_CFLAGS JACK_LIBS=$pkg_cv_JACK_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } audio_jack=yes fi if test x$audio_jack = xyes; then # Check whether --enable-jack-shared was given. -if test "${enable_jack_shared+set}" = set; then : +if test ${enable_jack_shared+y} +then : enableval=$enable_jack_shared; -else +else $as_nop enable_jack_shared=yes fi jack_lib=`find_lib "libjack.so.*" "$JACK_LIBS" | sed 's/.*\/\(.*\)/\1/; q'` -$as_echo "#define SDL_AUDIO_DRIVER_JACK 1" >>confdefs.h +printf "%s\n" "#define SDL_AUDIO_DRIVER_JACK 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/audio/jack/*.c" EXTRA_CFLAGS="$EXTRA_CFLAGS $JACK_CFLAGS" if test x$have_loadso != xyes && \ test x$enable_jack_shared = xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: You must have SDL_LoadObject() support for dynamic JACK audio loading" >&5 -$as_echo "$as_me: WARNING: You must have SDL_LoadObject() support for dynamic JACK audio loading" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: You must have SDL_LoadObject() support for dynamic JACK audio loading" >&5 +printf "%s\n" "$as_me: WARNING: You must have SDL_LoadObject() support for dynamic JACK audio loading" >&2;} fi if test x$have_loadso = xyes && \ test x$enable_jack_shared = xyes && test x$jack_lib != x; then echo "-- dynamic libjack -> $jack_lib" -cat >>confdefs.h <<_ACEOF -#define SDL_AUDIO_DRIVER_JACK_DYNAMIC "$jack_lib" -_ACEOF +printf "%s\n" "#define SDL_AUDIO_DRIVER_JACK_DYNAMIC \"$jack_lib\"" >>confdefs.h SUMMARY_audio="${SUMMARY_audio} jack(dynamic)" @@ -18397,33 +21560,109 @@ _ACEOF CheckESD() { # Check whether --enable-esd was given. -if test "${enable_esd+set}" = set; then : +if test ${enable_esd+y} +then : enableval=$enable_esd; -else +else $as_nop enable_esd=yes fi if test x$enable_audio = xyes -a x$enable_esd = xyes; then -# Check whether --with-esd-prefix was given. -if test "${with_esd_prefix+set}" = set; then : - withval=$with_esd_prefix; esd_prefix="$withval" +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for esound >= 0.2.8" >&5 +printf %s "checking for esound >= 0.2.8... " >&6; } + +if test -n "$ESD_CFLAGS"; then + pkg_cv_ESD_CFLAGS="$ESD_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"esound >= 0.2.8\""; } >&5 + ($PKG_CONFIG --exists --print-errors "esound >= 0.2.8") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_ESD_CFLAGS=`$PKG_CONFIG --cflags "esound >= 0.2.8" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$ESD_LIBS"; then + pkg_cv_ESD_LIBS="$ESD_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"esound >= 0.2.8\""; } >&5 + ($PKG_CONFIG --exists --print-errors "esound >= 0.2.8") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_ESD_LIBS=`$PKG_CONFIG --libs "esound >= 0.2.8" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + ESD_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "esound >= 0.2.8" 2>&1` + else + ESD_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "esound >= 0.2.8" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$ESD_PKG_ERRORS" >&5 + + have_esd=no +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + have_esd=no +else + ESD_CFLAGS=$pkg_cv_ESD_CFLAGS + ESD_LIBS=$pkg_cv_ESD_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + have_esd=yes +fi + if test x$have_esd = xno; then + +# Check whether --with-esd-prefix was given. +if test ${with_esd_prefix+y} +then : + withval=$with_esd_prefix; esd_prefix="$withval" +else $as_nop esd_prefix="" fi # Check whether --with-esd-exec-prefix was given. -if test "${with_esd_exec_prefix+set}" = set; then : +if test ${with_esd_exec_prefix+y} +then : withval=$with_esd_exec_prefix; esd_exec_prefix="$withval" -else +else $as_nop esd_exec_prefix="" fi # Check whether --enable-esdtest was given. -if test "${enable_esdtest+set}" = set; then : +if test ${enable_esdtest+y} +then : enableval=$enable_esdtest; -else +else $as_nop enable_esdtest=yes fi @@ -18443,11 +21682,12 @@ fi # Extract the first word of "esd-config", so it can be a program name with args. set dummy esd-config; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_ESD_CONFIG+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_ESD_CONFIG+y} +then : + printf %s "(cached) " >&6 +else $as_nop case $ESD_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_ESD_CONFIG="$ESD_CONFIG" # Let the user override the test with a path. @@ -18457,11 +21697,15 @@ else for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_ESD_CONFIG="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_ESD_CONFIG="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -18474,17 +21718,17 @@ esac fi ESD_CONFIG=$ac_cv_path_ESD_CONFIG if test -n "$ESD_CONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ESD_CONFIG" >&5 -$as_echo "$ESD_CONFIG" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ESD_CONFIG" >&5 +printf "%s\n" "$ESD_CONFIG" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi min_esd_version=0.2.8 - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ESD - version >= $min_esd_version" >&5 -$as_echo_n "checking for ESD - version >= $min_esd_version... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ESD - version >= $min_esd_version" >&5 +printf %s "checking for ESD - version >= $min_esd_version... " >&6; } no_esd="" if test "$ESD_CONFIG" = "no" ; then no_esd=yes @@ -18499,48 +21743,36 @@ $as_echo_n "checking for ESD - version >= $min_esd_version... " >&6; } esd_micro_version=`$ESD_CONFIG $esd_config_args --version | \ sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\3/'` if test "x$enable_esdtest" = "xyes" ; then + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + ac_save_CFLAGS="$CFLAGS" ac_save_LIBS="$LIBS" CFLAGS="$CFLAGS $ESD_CFLAGS" LIBS="$LIBS $ESD_LIBS" rm -f conf.esdtest - if test "$cross_compiling" = yes; then : + if test "$cross_compiling" = yes +then : echo $ac_n "cross compiling; assumed OK... $ac_c" -else +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include -#include #include -char* -my_strdup (char *str) -{ - char *new_str; - - if (str) - { - new_str = malloc ((strlen (str) + 1) * sizeof(char)); - strcpy (new_str, str); - } - else - new_str = NULL; - - return new_str; -} - -int main () +int main (void) { int major, minor, micro; - char *tmp_version; + FILE *fp = fopen("conf.esdtest", "w"); - system ("touch conf.esdtest"); + if (fp) fclose(fp); - /* HP/UX 9 (%@#!) writes to sscanf strings */ - tmp_version = my_strdup("$min_esd_version"); - if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { + if (sscanf("$min_esd_version", "%d.%d.%d", &major, &minor, µ) != 3) { printf("%s, bad version string\n", "$min_esd_version"); exit(1); } @@ -18563,11 +21795,11 @@ int main () } } - _ACEOF -if ac_fn_c_try_run "$LINENO"; then : +if ac_fn_c_try_run "$LINENO" +then : -else +else $as_nop no_esd=yes fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -18576,20 +21808,23 @@ fi CFLAGS="$ac_save_CFLAGS" LIBS="$ac_save_LIBS" + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + fi fi if test "x$no_esd" = x ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } have_esd=yes else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } if test "$ESD_CONFIG" = "no" ; then - echo "*** The esd-config script installed by ESD could not be found" - echo "*** If ESD was installed in PREFIX, make sure PREFIX/bin is in" - echo "*** your path, or set the ESD_CONFIG environment variable to the" - echo "*** full path to esd-config." + : else if test -f conf.esdtest ; then : @@ -18597,6 +21832,12 @@ $as_echo "no" >&6; } echo "*** Could not run ESD test program, checking why..." CFLAGS="$CFLAGS $ESD_CFLAGS" LIBS="$LIBS $ESD_LIBS" + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -18604,14 +21845,15 @@ $as_echo "no" >&6; } #include int -main () +main (void) { return 0; ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : echo "*** The test program compiled, but did not run. This usually means" echo "*** that the run-time linker is not finding ESD or finding the wrong" echo "*** version of ESD. If it is not finding ESD, you'll need to set your" @@ -18621,16 +21863,22 @@ if ac_fn_c_try_link "$LINENO"; then : echo "***" echo "*** If you have an old version installed, it is best to remove it, although" echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH" -else +else $as_nop echo "*** The test program failed to compile or link. See the file config.log for the" echo "*** exact error that occured. This usually means ESD was incorrectly installed" echo "*** or that you have moved ESD since it was installed. In the latter case, you" echo "*** may want to edit the esd-config script: $ESD_CONFIG" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext CFLAGS="$ac_save_CFLAGS" LIBS="$ac_save_LIBS" + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + fi fi ESD_CFLAGS="" @@ -18641,33 +21889,33 @@ rm -f core conftest.err conftest.$ac_objext \ rm -f conf.esdtest + fi if test x$have_esd = xyes; then # Check whether --enable-esd-shared was given. -if test "${enable_esd_shared+set}" = set; then : +if test ${enable_esd_shared+y} +then : enableval=$enable_esd_shared; -else +else $as_nop enable_esd_shared=yes fi esd_lib=`find_lib "libesd.so.*" "$ESD_LIBS" | sed 's/.*\/\(.*\)/\1/; q'` -$as_echo "#define SDL_AUDIO_DRIVER_ESD 1" >>confdefs.h +printf "%s\n" "#define SDL_AUDIO_DRIVER_ESD 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/audio/esd/*.c" EXTRA_CFLAGS="$EXTRA_CFLAGS $ESD_CFLAGS" if test x$have_loadso != xyes && \ test x$enable_esd_shared = xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: You must have SDL_LoadObject() support for dynamic ESD loading" >&5 -$as_echo "$as_me: WARNING: You must have SDL_LoadObject() support for dynamic ESD loading" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: You must have SDL_LoadObject() support for dynamic ESD loading" >&5 +printf "%s\n" "$as_me: WARNING: You must have SDL_LoadObject() support for dynamic ESD loading" >&2;} fi if test x$have_loadso = xyes && \ test x$enable_esd_shared = xyes && test x$esd_lib != x; then echo "-- dynamic libesd -> $esd_lib" -cat >>confdefs.h <<_ACEOF -#define SDL_AUDIO_DRIVER_ESD_DYNAMIC "$esd_lib" -_ACEOF +printf "%s\n" "#define SDL_AUDIO_DRIVER_ESD_DYNAMIC \"$esd_lib\"" >>confdefs.h SUMMARY_audio="${SUMMARY_audio} esd(dynamic)" else @@ -18679,47 +21927,50 @@ _ACEOF fi } -CheckPulseAudio() +CheckPipewire() { - # Check whether --enable-pulseaudio was given. -if test "${enable_pulseaudio+set}" = set; then : - enableval=$enable_pulseaudio; -else - enable_pulseaudio=yes + # Check whether --enable-pipewire was given. +if test ${enable_pipewire+y} +then : + enableval=$enable_pipewire; +else $as_nop + enable_pipewire=yes fi - if test x$enable_audio = xyes -a x$enable_pulseaudio = xyes; then + if test x$enable_audio = xyes -a x$enable_pipewire = xyes; then pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for PULSEAUDIO" >&5 -$as_echo_n "checking for PULSEAUDIO... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libpipewire-0.3 >= 0.3.20" >&5 +printf %s "checking for libpipewire-0.3 >= 0.3.20... " >&6; } -if test -n "$PULSEAUDIO_CFLAGS"; then - pkg_cv_PULSEAUDIO_CFLAGS="$PULSEAUDIO_CFLAGS" +if test -n "$PIPEWIRE_CFLAGS"; then + pkg_cv_PIPEWIRE_CFLAGS="$PIPEWIRE_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libpulse-simple >= 0.9\""; } >&5 - ($PKG_CONFIG --exists --print-errors "libpulse-simple >= 0.9") 2>&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libpipewire-0.3 >= 0.3.20\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libpipewire-0.3 >= 0.3.20") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_PULSEAUDIO_CFLAGS=`$PKG_CONFIG --cflags "libpulse-simple >= 0.9" 2>/dev/null` + pkg_cv_PIPEWIRE_CFLAGS=`$PKG_CONFIG --cflags "libpipewire-0.3 >= 0.3.20" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi -if test -n "$PULSEAUDIO_LIBS"; then - pkg_cv_PULSEAUDIO_LIBS="$PULSEAUDIO_LIBS" +if test -n "$PIPEWIRE_LIBS"; then + pkg_cv_PIPEWIRE_LIBS="$PIPEWIRE_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libpulse-simple >= 0.9\""; } >&5 - ($PKG_CONFIG --exists --print-errors "libpulse-simple >= 0.9") 2>&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libpipewire-0.3 >= 0.3.20\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libpipewire-0.3 >= 0.3.20") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_PULSEAUDIO_LIBS=`$PKG_CONFIG --libs "libpulse-simple >= 0.9" 2>/dev/null` + pkg_cv_PIPEWIRE_LIBS=`$PKG_CONFIG --libs "libpipewire-0.3 >= 0.3.20" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi @@ -18730,8 +21981,8 @@ fi if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes @@ -18739,53 +21990,172 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - PULSEAUDIO_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "libpulse-simple >= 0.9" 2>&1` + PIPEWIRE_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libpipewire-0.3 >= 0.3.20" 2>&1` else - PULSEAUDIO_PKG_ERRORS=`$PKG_CONFIG --print-errors "libpulse-simple >= 0.9" 2>&1` + PIPEWIRE_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libpipewire-0.3 >= 0.3.20" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$PIPEWIRE_PKG_ERRORS" >&5 + + audio_pipewire=no +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + audio_pipewire=no +else + PIPEWIRE_CFLAGS=$pkg_cv_PIPEWIRE_CFLAGS + PIPEWIRE_LIBS=$pkg_cv_PIPEWIRE_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + audio_pipewire=yes +fi + + if test x$audio_pipewire = xyes; then + # Check whether --enable-pipewire-shared was given. +if test ${enable_pipewire_shared+y} +then : + enableval=$enable_pipewire_shared; +else $as_nop + enable_pipewire_shared=yes +fi + + pipewire_lib=`find_lib "libpipewire-0.3.so.*" "$PIPEWIRE_LIBS" | sed 's/.*\/\(.*\)/\1/; q'` + + +printf "%s\n" "#define SDL_AUDIO_DRIVER_PIPEWIRE 1" >>confdefs.h + + SOURCES="$SOURCES $srcdir/src/audio/pipewire/*.c" + EXTRA_CFLAGS="$EXTRA_CFLAGS $PIPEWIRE_CFLAGS" + if test x$have_loadso != xyes && \ + test x$enable_pipewire_shared = xyes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: You must have SDL_LoadObject() support for dynamic Pipewire loading" >&5 +printf "%s\n" "$as_me: WARNING: You must have SDL_LoadObject() support for dynamic Pipewire loading" >&2;} + fi + if test x$have_loadso = xyes && \ + test x$enable_pipewire_shared = xyes && test x$pipewire_lib != x; then + echo "-- dynamic libpipewire-0.3 -> $pipewire_lib" + +printf "%s\n" "#define SDL_AUDIO_DRIVER_PIPEWIRE_DYNAMIC \"$pipewire_lib\"" >>confdefs.h + + SUMMARY_audio="${SUMMARY_audio} pipewire(dynamic)" + else + EXTRA_LDFLAGS="$EXTRA_LDFLAGS $PIPEWIRE_LIBS" + SUMMARY_audio="${SUMMARY_audio} pipewire" + fi + have_audio=yes + fi + fi +} + +CheckPulseAudio() +{ + # Check whether --enable-pulseaudio was given. +if test ${enable_pulseaudio+y} +then : + enableval=$enable_pulseaudio; +else $as_nop + enable_pulseaudio=yes +fi + + if test x$enable_audio = xyes -a x$enable_pulseaudio = xyes; then + +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libpulse >= 0.9.15" >&5 +printf %s "checking for libpulse >= 0.9.15... " >&6; } + +if test -n "$PULSEAUDIO_CFLAGS"; then + pkg_cv_PULSEAUDIO_CFLAGS="$PULSEAUDIO_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libpulse >= 0.9.15\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libpulse >= 0.9.15") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_PULSEAUDIO_CFLAGS=`$PKG_CONFIG --cflags "libpulse >= 0.9.15" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$PULSEAUDIO_LIBS"; then + pkg_cv_PULSEAUDIO_LIBS="$PULSEAUDIO_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libpulse >= 0.9.15\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libpulse >= 0.9.15") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_PULSEAUDIO_LIBS=`$PKG_CONFIG --libs "libpulse >= 0.9.15" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + PULSEAUDIO_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libpulse >= 0.9.15" 2>&1` + else + PULSEAUDIO_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libpulse >= 0.9.15" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$PULSEAUDIO_PKG_ERRORS" >&5 audio_pulseaudio=no elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } audio_pulseaudio=no else PULSEAUDIO_CFLAGS=$pkg_cv_PULSEAUDIO_CFLAGS PULSEAUDIO_LIBS=$pkg_cv_PULSEAUDIO_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } audio_pulseaudio=yes fi if test x$audio_pulseaudio = xyes; then # Check whether --enable-pulseaudio-shared was given. -if test "${enable_pulseaudio_shared+set}" = set; then : +if test ${enable_pulseaudio_shared+y} +then : enableval=$enable_pulseaudio_shared; -else +else $as_nop enable_pulseaudio_shared=yes fi - pulseaudio_lib=`find_lib "libpulse-simple.so.*" "$PULSEAUDIO_LIBS" | sed 's/.*\/\(.*\)/\1/; q'` + pulseaudio_lib=`find_lib "libpulse.so.*" "$PULSEAUDIO_LIBS" | sed 's/.*\/\(.*\)/\1/; q'` -$as_echo "#define SDL_AUDIO_DRIVER_PULSEAUDIO 1" >>confdefs.h +printf "%s\n" "#define SDL_AUDIO_DRIVER_PULSEAUDIO 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/audio/pulseaudio/*.c" EXTRA_CFLAGS="$EXTRA_CFLAGS $PULSEAUDIO_CFLAGS" if test x$have_loadso != xyes && \ test x$enable_pulseaudio_shared = xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: You must have SDL_LoadObject() support for dynamic PulseAudio loading" >&5 -$as_echo "$as_me: WARNING: You must have SDL_LoadObject() support for dynamic PulseAudio loading" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: You must have SDL_LoadObject() support for dynamic PulseAudio loading" >&5 +printf "%s\n" "$as_me: WARNING: You must have SDL_LoadObject() support for dynamic PulseAudio loading" >&2;} fi if test x$have_loadso = xyes && \ test x$enable_pulseaudio_shared = xyes && test x$pulseaudio_lib != x; then - echo "-- dynamic libpulse-simple -> $pulseaudio_lib" + echo "-- dynamic libpulse -> $pulseaudio_lib" -cat >>confdefs.h <<_ACEOF -#define SDL_AUDIO_DRIVER_PULSEAUDIO_DYNAMIC "$pulseaudio_lib" -_ACEOF +printf "%s\n" "#define SDL_AUDIO_DRIVER_PULSEAUDIO_DYNAMIC \"$pulseaudio_lib\"" >>confdefs.h SUMMARY_audio="${SUMMARY_audio} pulse(dynamic)" @@ -18808,20 +22178,22 @@ _ACEOF CheckARTSC() { # Check whether --enable-arts was given. -if test "${enable_arts+set}" = set; then : +if test ${enable_arts+y} +then : enableval=$enable_arts; -else +else $as_nop enable_arts=yes fi if test x$enable_audio = xyes -a x$enable_arts = xyes; then # Extract the first word of "artsc-config", so it can be a program name with args. set dummy artsc-config; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_ARTSCONFIG+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_ARTSCONFIG+y} +then : + printf %s "(cached) " >&6 +else $as_nop case $ARTSCONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_ARTSCONFIG="$ARTSCONFIG" # Let the user override the test with a path. @@ -18831,11 +22203,15 @@ else for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_ARTSCONFIG="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_ARTSCONFIG="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -18847,11 +22223,11 @@ esac fi ARTSCONFIG=$ac_cv_path_ARTSCONFIG if test -n "$ARTSCONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ARTSCONFIG" >&5 -$as_echo "$ARTSCONFIG" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ARTSCONFIG" >&5 +printf "%s\n" "$ARTSCONFIG" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -18860,8 +22236,8 @@ fi else ARTS_CFLAGS=`$ARTSCONFIG --cflags` ARTS_LIBS=`$ARTSCONFIG --libs` - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for aRts development environment" >&5 -$as_echo_n "checking for aRts development environment... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for aRts development environment" >&5 +printf %s "checking for aRts development environment... " >&6; } audio_arts=no save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $ARTS_CFLAGS" @@ -18871,7 +22247,7 @@ $as_echo_n "checking for aRts development environment... " >&6; } #include int -main () +main (void) { arts_stream_t stream; @@ -18880,42 +22256,40 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - audio_arts=yes - +if ac_fn_c_try_compile "$LINENO" +then : + audio_arts=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext CFLAGS="$save_CFLAGS" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $audio_arts" >&5 -$as_echo "$audio_arts" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $audio_arts" >&5 +printf "%s\n" "$audio_arts" >&6; } if test x$audio_arts = xyes; then # Check whether --enable-arts-shared was given. -if test "${enable_arts_shared+set}" = set; then : +if test ${enable_arts_shared+y} +then : enableval=$enable_arts_shared; -else +else $as_nop enable_arts_shared=yes fi arts_lib=`find_lib "libartsc.so.*" "$ARTS_LIBS" | sed 's/.*\/\(.*\)/\1/; q'` -$as_echo "#define SDL_AUDIO_DRIVER_ARTS 1" >>confdefs.h +printf "%s\n" "#define SDL_AUDIO_DRIVER_ARTS 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/audio/arts/*.c" EXTRA_CFLAGS="$EXTRA_CFLAGS $ARTS_CFLAGS" if test x$have_loadso != xyes && \ test x$enable_arts_shared = xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: You must have SDL_LoadObject() support for dynamic ARTS loading" >&5 -$as_echo "$as_me: WARNING: You must have SDL_LoadObject() support for dynamic ARTS loading" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: You must have SDL_LoadObject() support for dynamic ARTS loading" >&5 +printf "%s\n" "$as_me: WARNING: You must have SDL_LoadObject() support for dynamic ARTS loading" >&2;} fi if test x$have_loadso = xyes && \ test x$enable_arts_shared = xyes && test x$arts_lib != x; then echo "-- dynamic libartsc -> $arts_lib" -cat >>confdefs.h <<_ACEOF -#define SDL_AUDIO_DRIVER_ARTS_DYNAMIC "$arts_lib" -_ACEOF +printf "%s\n" "#define SDL_AUDIO_DRIVER_ARTS_DYNAMIC \"$arts_lib\"" >>confdefs.h SUMMARY_audio="${SUMMARY_audio} arts(dynamic)" else @@ -18931,24 +22305,26 @@ _ACEOF CheckNAS() { # Check whether --enable-nas was given. -if test "${enable_nas+set}" = set; then : +if test ${enable_nas+y} +then : enableval=$enable_nas; -else +else $as_nop enable_nas=yes fi if test x$enable_audio = xyes -a x$enable_nas = xyes; then - ac_fn_c_check_header_mongrel "$LINENO" "audio/audiolib.h" "ac_cv_header_audio_audiolib_h" "$ac_includes_default" -if test "x$ac_cv_header_audio_audiolib_h" = xyes; then : + ac_fn_c_check_header_compile "$LINENO" "audio/audiolib.h" "ac_cv_header_audio_audiolib_h" "$ac_includes_default" +if test "x$ac_cv_header_audio_audiolib_h" = xyes +then : have_nas_hdr=yes fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for AuOpenServer in -laudio" >&5 -$as_echo_n "checking for AuOpenServer in -laudio... " >&6; } -if ${ac_cv_lib_audio_AuOpenServer+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for AuOpenServer in -laudio" >&5 +printf %s "checking for AuOpenServer in -laudio... " >&6; } +if test ${ac_cv_lib_audio_AuOpenServer+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-laudio $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -18957,36 +22333,35 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char AuOpenServer (); int -main () +main (void) { return AuOpenServer (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_audio_AuOpenServer=yes -else +else $as_nop ac_cv_lib_audio_AuOpenServer=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_audio_AuOpenServer" >&5 -$as_echo "$ac_cv_lib_audio_AuOpenServer" >&6; } -if test "x$ac_cv_lib_audio_AuOpenServer" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_audio_AuOpenServer" >&5 +printf "%s\n" "$ac_cv_lib_audio_AuOpenServer" >&6; } +if test "x$ac_cv_lib_audio_AuOpenServer" = xyes +then : have_nas_lib=yes fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for NAS audio support" >&5 -$as_echo_n "checking for NAS audio support... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for NAS audio support" >&5 +printf %s "checking for NAS audio support... " >&6; } have_nas=no if test x$have_nas_hdr = xyes -a x$have_nas_lib = xyes; then @@ -19000,14 +22375,15 @@ $as_echo_n "checking for NAS audio support... " >&6; } fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_nas" >&5 -$as_echo "$have_nas" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_nas" >&5 +printf "%s\n" "$have_nas" >&6; } if test x$have_nas = xyes; then # Check whether --enable-nas-shared was given. -if test "${enable_nas_shared+set}" = set; then : +if test ${enable_nas_shared+y} +then : enableval=$enable_nas_shared; -else +else $as_nop enable_nas_shared=yes fi @@ -19015,16 +22391,14 @@ fi if test x$have_loadso != xyes && \ test x$enable_nas_shared = xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: You must have SDL_LoadObject() support for dynamic NAS loading" >&5 -$as_echo "$as_me: WARNING: You must have SDL_LoadObject() support for dynamic NAS loading" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: You must have SDL_LoadObject() support for dynamic NAS loading" >&5 +printf "%s\n" "$as_me: WARNING: You must have SDL_LoadObject() support for dynamic NAS loading" >&2;} fi if test x$have_loadso = xyes && \ test x$enable_nas_shared = xyes && test x$nas_lib != x; then echo "-- dynamic libaudio -> $nas_lib" -cat >>confdefs.h <<_ACEOF -#define SDL_AUDIO_DRIVER_NAS_DYNAMIC "$nas_lib" -_ACEOF +printf "%s\n" "#define SDL_AUDIO_DRIVER_NAS_DYNAMIC \"$nas_lib\"" >>confdefs.h SUMMARY_audio="${SUMMARY_audio} nas(dynamic)" else @@ -19033,7 +22407,7 @@ _ACEOF fi -$as_echo "#define SDL_AUDIO_DRIVER_NAS 1" >>confdefs.h +printf "%s\n" "#define SDL_AUDIO_DRIVER_NAS 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/audio/nas/*.c" EXTRA_CFLAGS="$EXTRA_CFLAGS $NAS_CFLAGS" @@ -19045,77 +22419,92 @@ $as_echo "#define SDL_AUDIO_DRIVER_NAS 1" >>confdefs.h CheckSNDIO() { # Check whether --enable-sndio was given. -if test "${enable_sndio+set}" = set; then : +if test ${enable_sndio+y} +then : enableval=$enable_sndio; -else +else $as_nop enable_sndio=yes fi if test x$enable_audio = xyes -a x$enable_sndio = xyes; then - ac_fn_c_check_header_mongrel "$LINENO" "sndio.h" "ac_cv_header_sndio_h" "$ac_includes_default" -if test "x$ac_cv_header_sndio_h" = xyes; then : - have_sndio_hdr=yes -fi +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sndio" >&5 +printf %s "checking for sndio... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sio_open in -lsndio" >&5 -$as_echo_n "checking for sio_open in -lsndio... " >&6; } -if ${ac_cv_lib_sndio_sio_open+:} false; then : - $as_echo_n "(cached) " >&6 +if test -n "$SNDIO_CFLAGS"; then + pkg_cv_SNDIO_CFLAGS="$SNDIO_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sndio\""; } >&5 + ($PKG_CONFIG --exists --print-errors "sndio") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_SNDIO_CFLAGS=`$PKG_CONFIG --cflags "sndio" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lsndio $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char sio_open (); -int -main () -{ -return sio_open (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_sndio_sio_open=yes + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$SNDIO_LIBS"; then + pkg_cv_SNDIO_LIBS="$SNDIO_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sndio\""; } >&5 + ($PKG_CONFIG --exists --print-errors "sndio") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_SNDIO_LIBS=`$PKG_CONFIG --libs "sndio" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else - ac_cv_lib_sndio_sio_open=no + pkg_failed=yes fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sndio_sio_open" >&5 -$as_echo "$ac_cv_lib_sndio_sio_open" >&6; } -if test "x$ac_cv_lib_sndio_sio_open" = xyes; then : - have_sndio_lib=yes + else + pkg_failed=untried fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sndio audio support" >&5 -$as_echo_n "checking for sndio audio support... " >&6; } - have_sndio=no - if test x$have_sndio_hdr = xyes -a x$have_sndio_lib = xyes; then - have_sndio=yes - SNDIO_LIBS="-lsndio" +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + SNDIO_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "sndio" 2>&1` + else + SNDIO_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "sndio" 2>&1` fi + # Put the nasty error message in config.log where it belongs + echo "$SNDIO_PKG_ERRORS" >&5 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_sndio" >&5 -$as_echo "$have_sndio" >&6; } - - if test x$have_sndio = xyes; then - # Check whether --enable-sndio-shared was given. -if test "${enable_sndio_shared+set}" = set; then : - enableval=$enable_sndio_shared; + audio_sndio=no +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + audio_sndio=no else + SNDIO_CFLAGS=$pkg_cv_SNDIO_CFLAGS + SNDIO_LIBS=$pkg_cv_SNDIO_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + audio_sndio=yes +fi + + if test x$audio_sndio = xyes; then + # Check whether --enable-sndio-shared was given. +if test ${enable_sndio_shared+y} +then : + enableval=$enable_sndio_shared; +else $as_nop enable_sndio_shared=yes fi @@ -19123,16 +22512,14 @@ fi if test x$have_loadso != xyes && \ test x$enable_sndio_shared = xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: You must have SDL_LoadObject() support for dynamic sndio loading" >&5 -$as_echo "$as_me: WARNING: You must have SDL_LoadObject() support for dynamic sndio loading" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: You must have SDL_LoadObject() support for dynamic sndio loading" >&5 +printf "%s\n" "$as_me: WARNING: You must have SDL_LoadObject() support for dynamic sndio loading" >&2;} fi if test x$have_loadso = xyes && \ test x$enable_sndio_shared = xyes && test x$sndio_lib != x; then echo "-- dynamic libsndio -> $sndio_lib" -cat >>confdefs.h <<_ACEOF -#define SDL_AUDIO_DRIVER_SNDIO_DYNAMIC "$sndio_lib" -_ACEOF +printf "%s\n" "#define SDL_AUDIO_DRIVER_SNDIO_DYNAMIC \"$sndio_lib\"" >>confdefs.h SUMMARY_audio="${SUMMARY_audio} sndio(dynamic)" else @@ -19141,7 +22528,7 @@ _ACEOF fi -$as_echo "#define SDL_AUDIO_DRIVER_SNDIO 1" >>confdefs.h +printf "%s\n" "#define SDL_AUDIO_DRIVER_SNDIO 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/audio/sndio/*.c" EXTRA_CFLAGS="$EXTRA_CFLAGS $SNDIO_CFLAGS" @@ -19153,28 +22540,30 @@ $as_echo "#define SDL_AUDIO_DRIVER_SNDIO 1" >>confdefs.h CheckFusionSound() { # Check whether --enable-fusionsound was given. -if test "${enable_fusionsound+set}" = set; then : +if test ${enable_fusionsound+y} +then : enableval=$enable_fusionsound; -else +else $as_nop enable_fusionsound=no fi if test x$enable_audio = xyes -a x$enable_fusionsound = xyes; then pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for FUSIONSOUND" >&5 -$as_echo_n "checking for FUSIONSOUND... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for fusionsound >= 1.1.1" >&5 +printf %s "checking for fusionsound >= 1.1.1... " >&6; } if test -n "$FUSIONSOUND_CFLAGS"; then pkg_cv_FUSIONSOUND_CFLAGS="$FUSIONSOUND_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"fusionsound >= 1.1.1\""; } >&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"fusionsound >= 1.1.1\""; } >&5 ($PKG_CONFIG --exists --print-errors "fusionsound >= 1.1.1") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_FUSIONSOUND_CFLAGS=`$PKG_CONFIG --cflags "fusionsound >= 1.1.1" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi @@ -19185,12 +22574,13 @@ if test -n "$FUSIONSOUND_LIBS"; then pkg_cv_FUSIONSOUND_LIBS="$FUSIONSOUND_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"fusionsound >= 1.1.1\""; } >&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"fusionsound >= 1.1.1\""; } >&5 ($PKG_CONFIG --exists --print-errors "fusionsound >= 1.1.1") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_FUSIONSOUND_LIBS=`$PKG_CONFIG --libs "fusionsound >= 1.1.1" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi @@ -19201,8 +22591,8 @@ fi if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes @@ -19210,54 +22600,53 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - FUSIONSOUND_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "fusionsound >= 1.1.1" 2>&1` + FUSIONSOUND_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "fusionsound >= 1.1.1" 2>&1` else - FUSIONSOUND_PKG_ERRORS=`$PKG_CONFIG --print-errors "fusionsound >= 1.1.1" 2>&1` + FUSIONSOUND_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "fusionsound >= 1.1.1" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$FUSIONSOUND_PKG_ERRORS" >&5 fusionsound=no elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fusionsound=no else FUSIONSOUND_CFLAGS=$pkg_cv_FUSIONSOUND_CFLAGS FUSIONSOUND_LIBS=$pkg_cv_FUSIONSOUND_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } fusionsound=yes fi if test x$fusionsound = xyes; then -$as_echo "#define SDL_AUDIO_DRIVER_FUSIONSOUND 1" >>confdefs.h +printf "%s\n" "#define SDL_AUDIO_DRIVER_FUSIONSOUND 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/audio/fusionsound/*.c" EXTRA_CFLAGS="$EXTRA_CFLAGS $FUSIONSOUND_CFLAGS" # Check whether --enable-fusionsound-shared was given. -if test "${enable_fusionsound_shared+set}" = set; then : +if test ${enable_fusionsound_shared+y} +then : enableval=$enable_fusionsound_shared; -else +else $as_nop enable_fusionsound_shared=yes fi fusionsound_shared=no - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for FusionSound dynamic loading support" >&5 -$as_echo_n "checking for FusionSound dynamic loading support... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for FusionSound dynamic loading support" >&5 +printf %s "checking for FusionSound dynamic loading support... " >&6; } if test x$have_loadso != xyes && \ test x$enable_fusionsound_shared = xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: You must have SDL_LoadObject() support for dynamic fusionsound loading" >&5 -$as_echo "$as_me: WARNING: You must have SDL_LoadObject() support for dynamic fusionsound loading" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: You must have SDL_LoadObject() support for dynamic fusionsound loading" >&5 +printf "%s\n" "$as_me: WARNING: You must have SDL_LoadObject() support for dynamic fusionsound loading" >&2;} fi if test x$have_loadso = xyes && \ test x$enable_fusionsound_shared = xyes; then -cat >>confdefs.h <<_ACEOF -#define SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC "libfusionsound.so" -_ACEOF +printf "%s\n" "#define SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC \"libfusionsound.so\"" >>confdefs.h fusionsound_shared=yes SUMMARY_audio="${SUMMARY_audio} fusionsound(dynamic)" @@ -19265,8 +22654,8 @@ _ACEOF EXTRA_LDFLAGS="$EXTRA_LDFLAGS $FUSIONSOUND_LIBS" SUMMARY_audio="${SUMMARY_audio} fusionsound" fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $fusionsound_shared" >&5 -$as_echo "$fusionsound_shared" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $fusionsound_shared" >&5 +printf "%s\n" "$fusionsound_shared" >&6; } have_audio=yes fi @@ -19276,66 +22665,72 @@ $as_echo "$fusionsound_shared" >&6; } CheckDiskAudio() { # Check whether --enable-diskaudio was given. -if test "${enable_diskaudio+set}" = set; then : +if test ${enable_diskaudio+y} +then : enableval=$enable_diskaudio; -else +else $as_nop enable_diskaudio=yes fi if test x$enable_audio = xyes -a x$enable_diskaudio = xyes; then -$as_echo "#define SDL_AUDIO_DRIVER_DISK 1" >>confdefs.h +printf "%s\n" "#define SDL_AUDIO_DRIVER_DISK 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/audio/disk/*.c" SUMMARY_audio="${SUMMARY_audio} disk" + have_audio=yes fi } CheckDummyAudio() { # Check whether --enable-dummyaudio was given. -if test "${enable_dummyaudio+set}" = set; then : +if test ${enable_dummyaudio+y} +then : enableval=$enable_dummyaudio; -else +else $as_nop enable_dummyaudio=yes fi if test x$enable_audio = xyes -a x$enable_dummyaudio = xyes; then -$as_echo "#define SDL_AUDIO_DRIVER_DUMMY 1" >>confdefs.h +printf "%s\n" "#define SDL_AUDIO_DRIVER_DUMMY 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/audio/dummy/*.c" SUMMARY_audio="${SUMMARY_audio} dummy" + have_audio=yes fi } CheckLibSampleRate() { # Check whether --enable-libsamplerate was given. -if test "${enable_libsamplerate+set}" = set; then : +if test ${enable_libsamplerate+y} +then : enableval=$enable_libsamplerate; -else +else $as_nop enable_libsamplerate=yes fi if test x$enable_libsamplerate = xyes; then - ac_fn_c_check_header_mongrel "$LINENO" "samplerate.h" "ac_cv_header_samplerate_h" "$ac_includes_default" -if test "x$ac_cv_header_samplerate_h" = xyes; then : + ac_fn_c_check_header_compile "$LINENO" "samplerate.h" "ac_cv_header_samplerate_h" "$ac_includes_default" +if test "x$ac_cv_header_samplerate_h" = xyes +then : have_samplerate_h_hdr=yes -else +else $as_nop have_samplerate_h_hdr=no fi - if test x$have_samplerate_h_hdr = xyes; then -$as_echo "#define HAVE_LIBSAMPLERATE_H 1" >>confdefs.h +printf "%s\n" "#define HAVE_LIBSAMPLERATE_H 1" >>confdefs.h # Check whether --enable-libsamplerate-shared was given. -if test "${enable_libsamplerate_shared+set}" = set; then : +if test ${enable_libsamplerate_shared+y} +then : enableval=$enable_libsamplerate_shared; -else +else $as_nop enable_libsamplerate_shared=yes fi @@ -19344,16 +22739,14 @@ fi if test x$have_loadso != xyes && \ test x$enable_libsamplerate_shared = xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: You must have SDL_LoadObject() support for dynamic libsamplerate loading" >&5 -$as_echo "$as_me: WARNING: You must have SDL_LoadObject() support for dynamic libsamplerate loading" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: You must have SDL_LoadObject() support for dynamic libsamplerate loading" >&5 +printf "%s\n" "$as_me: WARNING: You must have SDL_LoadObject() support for dynamic libsamplerate loading" >&2;} fi if test x$have_loadso = xyes && \ test x$enable_libsamplerate_shared = xyes && test x$samplerate_lib != x; then echo "-- dynamic libsamplerate -> $samplerate_lib" -cat >>confdefs.h <<_ACEOF -#define SDL_LIBSAMPLERATE_DYNAMIC "$samplerate_lib" -_ACEOF +printf "%s\n" "#define SDL_LIBSAMPLERATE_DYNAMIC \"$samplerate_lib\"" >>confdefs.h else EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lsamplerate" @@ -19365,10 +22758,11 @@ _ACEOF CheckARM() { # Check whether --enable-arm-simd was given. -if test "${enable_arm_simd+set}" = set; then : +if test ${enable_arm_simd+y} +then : enableval=$enable_arm_simd; enable_arm_simd=$enableval -else - enable_arm_simd=yes +else $as_nop + enable_arm_simd=no fi if test x$enable_video = xyes -a x$enable_assembly = xyes -a x$enable_arm_simd = xyes; then @@ -19376,8 +22770,8 @@ fi have_arm_simd=no CFLAGS="-x assembler-with-cpp $CFLAGS" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ARM SIMD" >&5 -$as_echo_n "checking for ARM SIMD... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ARM SIMD" >&5 +printf %s "checking for ARM SIMD... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -19393,17 +22787,19 @@ $as_echo_n "checking for ARM SIMD... " >&6; } uqadd8 r0, r0, r0 _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : have_arm_simd=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_arm_simd" >&5 -$as_echo "$have_arm_simd" >&6; } +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_arm_simd" >&5 +printf "%s\n" "$have_arm_simd" >&6; } CFLAGS="$save_CFLAGS" if test x$have_arm_simd = xyes; then - $as_echo "#define SDL_ARM_SIMD_BLITTERS 1" >>confdefs.h + +printf "%s\n" "#define SDL_ARM_SIMD_BLITTERS 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/video/arm/pixman-arm-simd*.S" WARN_ABOUT_ARM_SIMD_ASM_MIT="yes" @@ -19414,9 +22810,10 @@ $as_echo "$have_arm_simd" >&6; } CheckNEON() { # Check whether --enable-arm-neon was given. -if test "${enable_arm_neon+set}" = set; then : +if test ${enable_arm_neon+y} +then : enableval=$enable_arm_neon; enable_arm_neon=$enableval -else +else $as_nop enable_arm_neon=no fi @@ -19425,8 +22822,8 @@ fi have_arm_neon=no CFLAGS="-x assembler-with-cpp $CFLAGS" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ARM NEON" >&5 -$as_echo_n "checking for ARM NEON... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ARM NEON" >&5 +printf %s "checking for ARM NEON... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -19444,17 +22841,18 @@ $as_echo_n "checking for ARM NEON... " >&6; } vmovn.u16 d0, q0 _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : have_arm_neon=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_arm_neon" >&5 -$as_echo "$have_arm_neon" >&6; } - +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_arm_neon" >&5 +printf "%s\n" "$have_arm_neon" >&6; } CFLAGS="$save_CFLAGS" if test x$have_arm_neon = xyes; then - $as_echo "#define SDL_ARM_NEON_BLITTERS 1" >>confdefs.h + +printf "%s\n" "#define SDL_ARM_NEON_BLITTERS 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/video/arm/pixman-arm-neon*.S" WARN_ABOUT_ARM_NEON_ASM_MIT="yes" @@ -19462,10 +22860,80 @@ $as_echo "$have_arm_neon" >&6; } fi } +CheckObjectiveCARC() +{ + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for clang -fobjc-arc option" >&5 +printf %s "checking for clang -fobjc-arc option... " >&6; } + have_clang_objc_arc=no + + save_CFLAGS="$CFLAGS" + CFLAGS="$save_CFLAGS -fobjc-arc" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + int x = 0; + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + have_clang_objc_arc=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_clang_objc_arc" >&5 +printf "%s\n" "$have_clang_objc_arc" >&6; } + CFLAGS="$save_CFLAGS" + + if test x$have_clang_objc_arc = xyes; then + EXTRA_CFLAGS="$EXTRA_CFLAGS -fobjc-arc" + fi +} + +CheckGDwarf4() +{ + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GCC -gdwarf-4 option" >&5 +printf %s "checking for GCC -gdwarf-4 option... " >&6; } + have_gcc_gdwarf4=no + + save_CFLAGS="$CFLAGS" + CFLAGS="$save_CFLAGS -gdwarf-4" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + int x = 0; + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + have_gcc_gdwarf4=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_gcc_gdwarf4" >&5 +printf "%s\n" "$have_gcc_gdwarf4" >&6; } + CFLAGS="$save_CFLAGS" + + if test x$have_gcc_gdwarf4 = xyes; then + EXTRA_CFLAGS="$EXTRA_CFLAGS -gdwarf-4" + fi +} + CheckVisibilityHidden() { - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GCC -fvisibility=hidden option" >&5 -$as_echo_n "checking for GCC -fvisibility=hidden option... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GCC -fvisibility=hidden option" >&5 +printf %s "checking for GCC -fvisibility=hidden option... " >&6; } have_gcc_fvisibility=no visibility_CFLAGS="-fvisibility=hidden" @@ -19479,22 +22947,20 @@ $as_echo_n "checking for GCC -fvisibility=hidden option... " >&6; } #endif int -main () +main (void) { - ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - have_gcc_fvisibility=yes - +if ac_fn_c_try_compile "$LINENO" +then : + have_gcc_fvisibility=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_gcc_fvisibility" >&5 -$as_echo "$have_gcc_fvisibility" >&6; } +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_gcc_fvisibility" >&5 +printf "%s\n" "$have_gcc_fvisibility" >&6; } CFLAGS="$save_CFLAGS" if test x$have_gcc_fvisibility = xyes; then @@ -19504,8 +22970,8 @@ $as_echo "$have_gcc_fvisibility" >&6; } CheckNoStrictAliasing() { - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GCC -fno-strict-aliasing option" >&5 -$as_echo_n "checking for GCC -fno-strict-aliasing option... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GCC -fno-strict-aliasing option" >&5 +printf %s "checking for GCC -fno-strict-aliasing option... " >&6; } have_gcc_no_strict_aliasing=no save_CFLAGS="$CFLAGS" @@ -19516,22 +22982,20 @@ $as_echo_n "checking for GCC -fno-strict-aliasing option... " >&6; } int x = 0; int -main () +main (void) { - ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - have_gcc_no_strict_aliasing=yes - +if ac_fn_c_try_compile "$LINENO" +then : + have_gcc_no_strict_aliasing=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_gcc_no_strict_aliasing" >&5 -$as_echo "$have_gcc_no_strict_aliasing" >&6; } +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_gcc_no_strict_aliasing" >&5 +printf "%s\n" "$have_gcc_no_strict_aliasing" >&6; } CFLAGS="$save_CFLAGS" if test x$have_gcc_no_strict_aliasing = xyes; then @@ -19539,47 +23003,90 @@ $as_echo "$have_gcc_no_strict_aliasing" >&6; } fi } -CheckStackBoundary() +CheckWerror() { - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GCC -mpreferred-stack-boundary option" >&5 -$as_echo_n "checking for GCC -mpreferred-stack-boundary option... " >&6; } - have_gcc_preferred_stack_boundary=no + # Check whether --enable-werror was given. +if test ${enable_werror+y} +then : + enableval=$enable_werror; enable_werror=$enableval +else $as_nop + enable_werror=no +fi + + if test x$enable_werror = xyes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GCC -Werror option" >&5 +printf %s "checking for GCC -Werror option... " >&6; } + have_gcc_werror=no + + save_CFLAGS="$CFLAGS" + CFLAGS="$save_CFLAGS -Werror" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + int x = 0; + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + have_gcc_werror=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_gcc_werror" >&5 +printf "%s\n" "$have_gcc_werror" >&6; } + CFLAGS="$save_CFLAGS" + + if test x$have_gcc_werror = xyes; then + EXTRA_CFLAGS="$EXTRA_CFLAGS -Werror" + fi + fi +} + +CheckNoErrorDeprecatedDeclarationsWerror() +{ + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GCC -Wno-error=deprecated-declarations option" >&5 +printf %s "checking for GCC -Wno-error=deprecated-declarations option... " >&6; } + have_gcc_no_werror_deprecated_declarations=no save_CFLAGS="$CFLAGS" - CFLAGS="$save_CFLAGS -mpreferred-stack-boundary=2" + CFLAGS="$save_CFLAGS -Wno-error=deprecated-declarations" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int x = 0; int -main () +main (void) { - ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - have_gcc_preferred_stack_boundary=yes - +if ac_fn_c_try_compile "$LINENO" +then : + have_gcc_no_werror_deprecated_declarations=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_gcc_preferred_stack_boundary" >&5 -$as_echo "$have_gcc_preferred_stack_boundary" >&6; } +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_gcc_werror" >&5 +printf "%s\n" "$have_gcc_werror" >&6; } CFLAGS="$save_CFLAGS" - if test x$have_gcc_preferred_stack_boundary = xyes; then - EXTRA_CFLAGS="$EXTRA_CFLAGS -mpreferred-stack-boundary=2" + if test x$have_gcc_no_werror_deprecated_declarations = xyes; then + EXTRA_CFLAGS="$EXTRA_CFLAGS -Wno-error=deprecated-declarations" fi } CheckDeclarationAfterStatement() { - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GCC -Wdeclaration-after-statement option" >&5 -$as_echo_n "checking for GCC -Wdeclaration-after-statement option... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GCC -Wdeclaration-after-statement option" >&5 +printf %s "checking for GCC -Wdeclaration-after-statement option... " >&6; } have_gcc_declaration_after_statement=no save_CFLAGS="$CFLAGS" @@ -19590,22 +23097,20 @@ $as_echo_n "checking for GCC -Wdeclaration-after-statement option... " >&6; } int x = 0; int -main () +main (void) { - ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - have_gcc_declaration_after_statement=yes - +if ac_fn_c_try_compile "$LINENO" +then : + have_gcc_declaration_after_statement=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_gcc_declaration_after_statement" >&5 -$as_echo "$have_gcc_declaration_after_statement" >&6; } +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_gcc_declaration_after_statement" >&5 +printf "%s\n" "$have_gcc_declaration_after_statement" >&6; } CFLAGS="$save_CFLAGS" if test x$have_gcc_declaration_after_statement = xyes; then @@ -19615,8 +23120,8 @@ $as_echo "$have_gcc_declaration_after_statement" >&6; } CheckWarnAll() { - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GCC -Wall option" >&5 -$as_echo_n "checking for GCC -Wall option... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GCC -Wall option" >&5 +printf %s "checking for GCC -Wall option... " >&6; } have_gcc_Wall=no save_CFLAGS="$CFLAGS" @@ -19627,84 +23132,125 @@ $as_echo_n "checking for GCC -Wall option... " >&6; } int x = 0; int -main () +main (void) { - ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - have_gcc_Wall=yes - +if ac_fn_c_try_compile "$LINENO" +then : + have_gcc_Wall=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_gcc_Wall" >&5 -$as_echo "$have_gcc_Wall" >&6; } +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_gcc_Wall" >&5 +printf "%s\n" "$have_gcc_Wall" >&6; } CFLAGS="$save_CFLAGS" if test x$have_gcc_Wall = xyes; then EXTRA_CFLAGS="$EXTRA_CFLAGS -Wall" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for necessary GCC -Wno-multichar option" >&5 -$as_echo_n "checking for necessary GCC -Wno-multichar option... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for necessary GCC -Wno-multichar option" >&5 +printf %s "checking for necessary GCC -Wno-multichar option... " >&6; } need_gcc_Wno_multichar=no case "$host" in *-*-haiku*) need_gcc_Wno_multichar=yes ;; esac - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $need_gcc_Wno_multichar" >&5 -$as_echo "$need_gcc_Wno_multichar" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $need_gcc_Wno_multichar" >&5 +printf "%s\n" "$need_gcc_Wno_multichar" >&6; } if test x$need_gcc_Wno_multichar = xyes; then EXTRA_CFLAGS="$EXTRA_CFLAGS -Wno-multichar" fi fi } +CheckUnusedLocalTypedefs() +{ + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GCC -Wunused-local-typedefs option" >&5 +printf %s "checking for GCC -Wunused-local-typedefs option... " >&6; } + have_gcc_unused_local_typedefs=no + + save_CFLAGS="$CFLAGS" + CFLAGS="$save_CFLAGS -Wunused-local-typedefs" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + int x = 0; + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + have_gcc_unused_local_typedefs=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_gcc_unused_local_typedefs" >&5 +printf "%s\n" "$have_gcc_unused_local_typedefs" >&6; } + CFLAGS="$save_CFLAGS" + + if test x$have_gcc_unused_local_typedefs = xyes; then + EXTRA_CFLAGS="$EXTRA_CFLAGS -Wno-unused-local-typedefs" + fi +} + CheckWayland() { # Check whether --enable-video-wayland was given. -if test "${enable_video_wayland+set}" = set; then : +if test ${enable_video_wayland+y} +then : enableval=$enable_video_wayland; -else +else $as_nop enable_video_wayland=yes fi # Check whether --enable-video-wayland-qt-touch was given. -if test "${enable_video_wayland_qt_touch+set}" = set; then : +if test ${enable_video_wayland_qt_touch+y} +then : enableval=$enable_video_wayland_qt_touch; -else +else $as_nop enable_video_wayland_qt_touch=yes fi if test x$enable_video = xyes -a x$enable_video_wayland = xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Wayland support" >&5 -$as_echo_n "checking for Wayland support... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Wayland support" >&5 +printf %s "checking for Wayland support... " >&6; } video_wayland=no if test x$video_opengl_egl = xyes && \ test x$video_opengles_v2 = xyes; then - if $PKG_CONFIG --exists wayland-client wayland-scanner wayland-protocols wayland-egl wayland-cursor egl xkbcommon ; then + if $PKG_CONFIG --exists 'wayland-client >= 1.18' wayland-scanner wayland-egl wayland-cursor egl 'xkbcommon >= 0.5.0'; then WAYLAND_CFLAGS=`$PKG_CONFIG --cflags wayland-client wayland-egl wayland-cursor xkbcommon` WAYLAND_LIBS=`$PKG_CONFIG --libs wayland-client wayland-egl wayland-cursor xkbcommon` WAYLAND_SCANNER=`$PKG_CONFIG --variable=wayland_scanner wayland-scanner` + if $PKG_CONFIG --exists 'wayland-scanner >= 1.15' +then : + WAYLAND_SCANNER_CODE_MODE=private-code +else $as_nop + WAYLAND_SCANNER_CODE_MODE=code +fi video_wayland=yes fi fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $video_wayland" >&5 -$as_echo "$video_wayland" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $video_wayland" >&5 +printf "%s\n" "$video_wayland" >&6; } if test x$video_wayland = xyes; then -$as_echo "#define SDL_VIDEO_DRIVER_WAYLAND 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_DRIVER_WAYLAND 1" >>confdefs.h if test x$enable_video_wayland_qt_touch = xyes; then -$as_echo "#define SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH 1" >>confdefs.h fi @@ -19712,19 +23258,21 @@ $as_echo "#define SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH 1" >>confdefs.h SOURCES="$SOURCES $WAYLAND_SOURCES" EXTRA_CFLAGS="$EXTRA_CFLAGS $WAYLAND_CFLAGS -I\$(gen)" # Check whether --enable-wayland-shared was given. -if test "${enable_wayland_shared+set}" = set; then : +if test ${enable_wayland_shared+y} +then : enableval=$enable_wayland_shared; -else +else $as_nop enable_wayland_shared=maybe fi - case "$host" in + case "$host" in *) wayland_client_lib=`find_lib "libwayland-client.so.*" "$WAYLAND_LIBS" | sed 's/.*\/\(.*\)/\1/; q'` wayland_egl_lib=`find_lib "libwayland-egl.so.*" "$WAYLAND_LIBS" | sed 's/.*\/\(.*\)/\1/; q'` if test x$wayland_egl_lib = x; then - wayland_egl_lib=`find_lib "mesa-egl/libwayland-egl.so.*" "$WAYLAND_LIBS" | sed 's/.*\/\(.*\)/\1/; q'` + # This works in Ubuntu 13.10, maybe others + wayland_egl_lib=`find_lib "mesa-egl/libwayland-egl.so.*" "$WAYLAND_LIBS" | sed 's/.*\/\(.*\)/\1/; q'` fi wayland_cursor_lib=`find_lib "libwayland-cursor.so.*" "$WAYLAND_LIBS" | sed 's/.*\/\(.*\)/\1/; q'` xkbcommon_lib=`find_lib "libxkbcommon.so.*" "$WAYLAND_LIBS" | sed 's/.*\/\(.*\)/\1/; q'` @@ -19736,8 +23284,8 @@ fi fi if test x$have_loadso != xyes && \ test x$enable_wayland_shared = xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: You must have SDL_LoadObject() support for dynamic Wayland loading" >&5 -$as_echo "$as_me: WARNING: You must have SDL_LoadObject() support for dynamic Wayland loading" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: You must have SDL_LoadObject() support for dynamic Wayland loading" >&5 +printf "%s\n" "$as_me: WARNING: You must have SDL_LoadObject() support for dynamic Wayland loading" >&2;} enable_wayland_shared=no fi if test x$have_loadso = xyes && \ @@ -19751,24 +23299,16 @@ $as_echo "$as_me: WARNING: You must have SDL_LoadObject() support for dynamic Wa echo "-- dynamic libwayland-cursor -> $wayland_cursor_lib" echo "-- dynamic libxkbcommon -> $xkbcommon_lib" -cat >>confdefs.h <<_ACEOF -#define SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC "$wayland_client_lib" -_ACEOF +printf "%s\n" "#define SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC \"$wayland_client_lib\"" >>confdefs.h -cat >>confdefs.h <<_ACEOF -#define SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL "$wayland_egl_lib" -_ACEOF +printf "%s\n" "#define SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL \"$wayland_egl_lib\"" >>confdefs.h -cat >>confdefs.h <<_ACEOF -#define SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR "$wayland_cursor_lib" -_ACEOF +printf "%s\n" "#define SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR \"$wayland_cursor_lib\"" >>confdefs.h -cat >>confdefs.h <<_ACEOF -#define SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON "$xkbcommon_lib" -_ACEOF +printf "%s\n" "#define SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON \"$xkbcommon_lib\"" >>confdefs.h SUMMARY_video="${SUMMARY_video} wayland(dynamic)" else @@ -19777,11 +23317,243 @@ _ACEOF SUMMARY_video="${SUMMARY_video} wayland" fi have_video=yes + + # Check whether --enable-libdecor was given. +if test ${enable_libdecor+y} +then : + enableval=$enable_libdecor; +else $as_nop + enable_libdecor=yes +fi + + if test x$enable_libdecor = xyes; then + +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libdecor-0" >&5 +printf %s "checking for libdecor-0... " >&6; } + +if test -n "$DECOR_CFLAGS"; then + pkg_cv_DECOR_CFLAGS="$DECOR_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libdecor-0\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libdecor-0") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_DECOR_CFLAGS=`$PKG_CONFIG --cflags "libdecor-0" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$DECOR_LIBS"; then + pkg_cv_DECOR_LIBS="$DECOR_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libdecor-0\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libdecor-0") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_DECOR_LIBS=`$PKG_CONFIG --libs "libdecor-0" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + DECOR_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libdecor-0" 2>&1` + else + DECOR_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libdecor-0" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$DECOR_PKG_ERRORS" >&5 + + video_libdecor=no +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + video_libdecor=no +else + DECOR_CFLAGS=$pkg_cv_DECOR_CFLAGS + DECOR_LIBS=$pkg_cv_DECOR_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + video_libdecor=yes +fi + if test x$video_libdecor = xyes; then + EXTRA_CFLAGS="$EXTRA_CFLAGS $DECOR_CFLAGS" + +printf "%s\n" "#define HAVE_LIBDECOR_H 1" >>confdefs.h + + + # Check whether --enable-libdecor-shared was given. +if test ${enable_libdecor_shared+y} +then : + enableval=$enable_libdecor_shared; +else $as_nop + enable_libdecor_shared=yes +fi + + + decor_lib=`find_lib "libdecor-0.so.*" "$DECOR_LIBS" | sed 's/.*\/\(.*\)/\1/; q'` + + if test x$enable_wayland_shared != xyes; then + enable_libdecor_shared=no + fi + if test x$have_loadso != xyes && \ + test x$enable_libdecor_shared = xyes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: You must have SDL_LoadObject() support for dynamic libdecor loading" >&5 +printf "%s\n" "$as_me: WARNING: You must have SDL_LoadObject() support for dynamic libdecor loading" >&2;} + fi + if test x$have_loadso = xyes && \ + test x$enable_libdecor_shared = xyes && test x$decor_lib != x; then + echo "-- dynamic libdecor -> $decor_lib" + +printf "%s\n" "#define SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR \"$decor_lib\"" >>confdefs.h + + else + EXTRA_LDFLAGS="$EXTRA_LDFLAGS $DECOR_LIBS" + fi + + saved_cflags=$CFLAGS + CFLAGS="$CFLAGS $DECOR_CFLAGS" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC options needed to detect all undeclared functions" >&5 +printf %s "checking for $CC options needed to detect all undeclared functions... " >&6; } +if test ${ac_cv_c_undeclared_builtin_options+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_save_CFLAGS=$CFLAGS + ac_cv_c_undeclared_builtin_options='cannot detect' + for ac_arg in '' -fno-builtin; do + CFLAGS="$ac_save_CFLAGS $ac_arg" + # This test program should *not* compile successfully. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ +(void) strchr; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + +else $as_nop + # This test program should compile successfully. + # No library function is consistently available on + # freestanding implementations, so test against a dummy + # declaration. Include always-available headers on the + # off chance that they somehow elicit warnings. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include +extern void ac_decl (int, char *); + +int +main (void) +{ +(void) ac_decl (0, (char *) 0); + (void) ac_decl; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + if test x"$ac_arg" = x +then : + ac_cv_c_undeclared_builtin_options='none needed' +else $as_nop + ac_cv_c_undeclared_builtin_options=$ac_arg +fi + break +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + done + CFLAGS=$ac_save_CFLAGS + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_undeclared_builtin_options" >&5 +printf "%s\n" "$ac_cv_c_undeclared_builtin_options" >&6; } + case $ac_cv_c_undeclared_builtin_options in #( + 'cannot detect') : + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot make $CC report undeclared builtins +See \`config.log' for more details" "$LINENO" 5; } ;; #( + 'none needed') : + ac_c_undeclared_builtin_options='' ;; #( + *) : + ac_c_undeclared_builtin_options=$ac_cv_c_undeclared_builtin_options ;; +esac + +ac_fn_check_decl "$LINENO" "libdecor_frame_get_min_content_size" "ac_cv_have_decl_libdecor_frame_get_min_content_size" "#include +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_libdecor_frame_get_min_content_size" = xyes +then : + ac_have_decl=1 +else $as_nop + ac_have_decl=0 +fi +printf "%s\n" "#define HAVE_DECL_LIBDECOR_FRAME_GET_MIN_CONTENT_SIZE $ac_have_decl" >>confdefs.h +if test $ac_have_decl = 1 +then : + libdecor_get_min_max=yes +fi +ac_fn_check_decl "$LINENO" "libdecor_frame_get_max_content_size" "ac_cv_have_decl_libdecor_frame_get_max_content_size" "#include +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_libdecor_frame_get_max_content_size" = xyes +then : + ac_have_decl=1 +else $as_nop + ac_have_decl=0 +fi +printf "%s\n" "#define HAVE_DECL_LIBDECOR_FRAME_GET_MAX_CONTENT_SIZE $ac_have_decl" >>confdefs.h +if test $ac_have_decl = 1 +then : + libdecor_get_min_max=yes +fi + + if test x$libdecor_get_min_max = xyes; then + +printf "%s\n" "#define SDL_HAVE_LIBDECOR_GET_MIN_MAX 1" >>confdefs.h + + fi + CFLAGS="$saved_cflags" + fi + fi fi fi } - CheckNativeClient() { cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -19792,33 +23564,33 @@ CheckNativeClient() #endif int -main () +main (void) { - ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : -$as_echo "#define SDL_VIDEO_DRIVER_NACL 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_DRIVER_NACL 1" >>confdefs.h -$as_echo "#define SDL_AUDIO_DRIVER_NACL 1" >>confdefs.h +printf "%s\n" "#define SDL_AUDIO_DRIVER_NACL 1" >>confdefs.h -$as_echo "#define HAVE_POW 1" >>confdefs.h +printf "%s\n" "#define HAVE_POW 1" >>confdefs.h -$as_echo "#define HAVE_OPENGLES2 1" >>confdefs.h +printf "%s\n" "#define HAVE_OPENGLES2 1" >>confdefs.h -$as_echo "#define SDL_VIDEO_OPENGL_ES2 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_OPENGL_ES2 1" >>confdefs.h -$as_echo "#define SDL_VIDEO_RENDER_OGL_ES2 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_RENDER_OGL_ES2 1" >>confdefs.h SDL_LIBS="-lppapi_simple -lppapi_gles2 $SDL_LIBS" @@ -19826,39 +23598,42 @@ $as_echo "#define SDL_VIDEO_RENDER_OGL_ES2 1" >>confdefs.h SDLMAIN_SOURCES="$srcdir/src/main/nacl/*.c" SOURCES="$SOURCES $srcdir/src/audio/nacl/*.c" SUMMARY_audio="${SUMMARY_audio} nacl" + have_audio=yes SOURCES="$SOURCES $srcdir/src/video/nacl/*.c" SUMMARY_video="${SUMMARY_video} nacl opengles2" + have_video=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext } - CheckRPI() { # Check whether --enable-video-rpi was given. -if test "${enable_video_rpi+set}" = set; then : +if test ${enable_video_rpi+y} +then : enableval=$enable_video_rpi; -else +else $as_nop enable_video_rpi=yes fi if test x$enable_video = xyes -a x$enable_video_rpi = xyes; then pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for RPI" >&5 -$as_echo_n "checking for RPI... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for bcm_host brcmegl" >&5 +printf %s "checking for bcm_host brcmegl... " >&6; } if test -n "$RPI_CFLAGS"; then pkg_cv_RPI_CFLAGS="$RPI_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"bcm_host brcmegl\""; } >&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"bcm_host brcmegl\""; } >&5 ($PKG_CONFIG --exists --print-errors "bcm_host brcmegl") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_RPI_CFLAGS=`$PKG_CONFIG --cflags "bcm_host brcmegl" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi @@ -19869,12 +23644,13 @@ if test -n "$RPI_LIBS"; then pkg_cv_RPI_LIBS="$RPI_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"bcm_host brcmegl\""; } >&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"bcm_host brcmegl\""; } >&5 ($PKG_CONFIG --exists --print-errors "bcm_host brcmegl") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_RPI_LIBS=`$PKG_CONFIG --libs "bcm_host brcmegl" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi @@ -19885,8 +23661,8 @@ fi if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes @@ -19894,23 +23670,23 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - RPI_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "bcm_host brcmegl" 2>&1` + RPI_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "bcm_host brcmegl" 2>&1` else - RPI_PKG_ERRORS=`$PKG_CONFIG --print-errors "bcm_host brcmegl" 2>&1` + RPI_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "bcm_host brcmegl" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$RPI_PKG_ERRORS" >&5 video_rpi=no elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } video_rpi=no else RPI_CFLAGS=$pkg_cv_RPI_CFLAGS RPI_LIBS=$pkg_cv_RPI_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } video_rpi=yes fi @@ -19930,33 +23706,34 @@ fi # Add the Raspberry Pi compiler flags and libraries CFLAGS="$CFLAGS $RPI_CFLAGS"; LIBS="$LIBS $RPI_LIBS" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Raspberry Pi" >&5 -$as_echo_n "checking for Raspberry Pi... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Raspberry Pi 2/3" >&5 +printf %s "checking for Raspberry Pi 2/3... " >&6; } have_video_rpi=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include + #include int -main () +main (void) { + EGL_DISPMANX_WINDOW_T window; bcm_host_init(); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - - have_video_rpi=yes - +if ac_fn_c_try_link "$LINENO" +then : + have_video_rpi=yes fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_video_rpi" >&5 -$as_echo "$have_video_rpi" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_video_rpi" >&5 +printf "%s\n" "$have_video_rpi" >&6; } # Restore the compiler flags and libraries CFLAGS="$ac_save_cflags"; LIBS="$ac_save_libs" @@ -19968,9 +23745,10 @@ $as_echo "$have_video_rpi" >&6; } EXTRA_LDFLAGS="$EXTRA_LDFLAGS $RPI_LIBS" SOURCES="$SOURCES $srcdir/src/video/raspberry/*.c" -$as_echo "#define SDL_VIDEO_DRIVER_RPI 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_DRIVER_RPI 1" >>confdefs.h SUMMARY_video="${SUMMARY_video} rpi" + have_video=yes fi fi } @@ -19978,12 +23756,20 @@ $as_echo "#define SDL_VIDEO_DRIVER_RPI 1" >>confdefs.h CheckX11() { # Check whether --enable-video-x11 was given. -if test "${enable_video_x11+set}" = set; then : +if test ${enable_video_x11+y} +then : enableval=$enable_video_x11; -else - enable_video_x11=yes +else $as_nop + + enable_video_x11=yes + case "$host" in + *-*-darwin*|*-ios-*) + enable_video_x11=no + ;; + esac fi + if test x$enable_video = xyes -a x$enable_video_x11 = xyes; then case "$host" in *-*-darwin*) @@ -19997,12 +23783,13 @@ fi fi ;; esac - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for X" >&5 -$as_echo_n "checking for X... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for X" >&5 +printf %s "checking for X... " >&6; } # Check whether --with-x was given. -if test "${with_x+set}" = set; then : +if test ${with_x+y} +then : withval=$with_x; fi @@ -20013,12 +23800,41 @@ if test "x$with_x" = xno; then else case $x_includes,$x_libraries in #( *\'*) as_fn_error $? "cannot use X directory names containing '" "$LINENO" 5;; #( - *,NONE | NONE,*) if ${ac_cv_have_x+:} false; then : - $as_echo_n "(cached) " >&6 -else + *,NONE | NONE,*) if test ${ac_cv_have_x+y} +then : + printf %s "(cached) " >&6 +else $as_nop # One or both of the vars are not set, and there is no cached value. -ac_x_includes=no ac_x_libraries=no -rm -f -r conftest.dir +ac_x_includes=no +ac_x_libraries=no +# Do we need to do anything special at all? +ac_save_LIBS=$LIBS +LIBS="-lX11 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ +XrmInitialize () + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + # We can compile and link X programs with no special options. + ac_x_includes= + ac_x_libraries= +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS="$ac_save_LIBS" +# If that didn't work, only try xmkmf and file system searches +# for native compilation. +if test x"$ac_x_includes" = xno && test "$cross_compiling" = no +then : + rm -f -r conftest.dir if mkdir conftest.dir; then cd conftest.dir cat >Imakefile <<'_ACEOF' @@ -20057,7 +23873,7 @@ _ACEOF rm -f -r conftest.dir fi -# Standard set of common directories for X headers. + # Standard set of common directories for X headers. # Check X11 before X11Rn because it is often a symlink to the current release. ac_x_header_dirs=' /usr/X11/include @@ -20084,6 +23900,8 @@ ac_x_header_dirs=' /usr/local/include/X11R5 /usr/local/include/X11R4 +/opt/X11/include + /usr/X386/include /usr/x386/include /usr/XFree86/include/X11 @@ -20105,10 +23923,11 @@ if test "$ac_x_includes" = no; then /* end confdefs.h. */ #include _ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : +if ac_fn_c_try_cpp "$LINENO" +then : # We can compile using X headers with no special include directory. ac_x_includes= -else +else $as_nop for ac_dir in $ac_x_header_dirs; do if test -r "$ac_dir/X11/Xlib.h"; then ac_x_includes=$ac_dir @@ -20129,20 +23948,21 @@ if test "$ac_x_libraries" = no; then /* end confdefs.h. */ #include int -main () +main (void) { XrmInitialize () ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : LIBS=$ac_save_LIBS # We can link X programs with no special library path. ac_x_libraries= -else +else $as_nop LIBS=$ac_save_LIBS -for ac_dir in `$as_echo "$ac_x_includes $ac_x_header_dirs" | sed s/include/lib/g` +for ac_dir in `printf "%s\n" "$ac_x_includes $ac_x_header_dirs" | sed s/include/lib/g` do # Don't even attempt the hair of trying to link an X program! for ac_extension in a so sl dylib la dll; do @@ -20153,19 +23973,21 @@ do done done fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi # $ac_x_libraries = no +fi +# Record the results. case $ac_x_includes,$ac_x_libraries in #( - no,* | *,no | *\'*) + no,* | *,no | *\'*) : # Didn't find X, or a directory has "'" in its name. - ac_cv_have_x="have_x=no";; #( - *) + ac_cv_have_x="have_x=no" ;; #( + *) : # Record where we found X for the cache. ac_cv_have_x="have_x=yes\ ac_x_includes='$ac_x_includes'\ - ac_x_libraries='$ac_x_libraries'" + ac_x_libraries='$ac_x_libraries'" ;; esac fi ;; #( @@ -20175,8 +23997,8 @@ fi fi # $with_x != no if test "$have_x" != yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_x" >&5 -$as_echo "$have_x" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_x" >&5 +printf "%s\n" "$have_x" >&6; } no_x=yes else # If each of the values was on the command line, it overrides each guess. @@ -20186,14 +24008,14 @@ else ac_cv_have_x="have_x=yes\ ac_x_includes='$x_includes'\ ac_x_libraries='$x_libraries'" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: libraries $x_libraries, headers $x_includes" >&5 -$as_echo "libraries $x_libraries, headers $x_includes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: libraries $x_libraries, headers $x_includes" >&5 +printf "%s\n" "libraries $x_libraries, headers $x_includes" >&6; } fi if test "$no_x" = yes; then # Not all programs may use this symbol, but it does not hurt to define it. -$as_echo "#define X_DISPLAY_MISSING 1" >>confdefs.h +printf "%s\n" "#define X_DISPLAY_MISSING 1" >>confdefs.h X_CFLAGS= X_PRE_LIBS= X_LIBS= X_EXTRA_LIBS= else @@ -20206,8 +24028,8 @@ else X_LIBS="$X_LIBS -L$x_libraries" # For Solaris; some versions of Sun CC require a space after -R and # others require no space. Words are not sufficient . . . . - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -R must be followed by a space" >&5 -$as_echo_n "checking whether -R must be followed by a space... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether -R must be followed by a space" >&5 +printf %s "checking whether -R must be followed by a space... " >&6; } ac_xsave_LIBS=$LIBS; LIBS="$LIBS -R$x_libraries" ac_xsave_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes @@ -20215,42 +24037,44 @@ $as_echo_n "checking whether -R must be followed by a space... " >&6; } /* end confdefs.h. */ int -main () +main (void) { ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } +if ac_fn_c_try_link "$LINENO" +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } X_LIBS="$X_LIBS -R$x_libraries" -else +else $as_nop LIBS="$ac_xsave_LIBS -R $x_libraries" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } +if ac_fn_c_try_link "$LINENO" +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } X_LIBS="$X_LIBS -R $x_libraries" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: neither works" >&5 -$as_echo "neither works" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: neither works" >&5 +printf "%s\n" "neither works" >&6; } fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext ac_c_werror_flag=$ac_xsave_c_werror_flag LIBS=$ac_xsave_LIBS @@ -20273,26 +24097,25 @@ rm -f core conftest.err conftest.$ac_objext \ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char XOpenDisplay (); int -main () +main (void) { return XOpenDisplay (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet" >&5 -$as_echo_n "checking for dnet_ntoa in -ldnet... " >&6; } -if ${ac_cv_lib_dnet_dnet_ntoa+:} false; then : - $as_echo_n "(cached) " >&6 -else +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet" >&5 +printf %s "checking for dnet_ntoa in -ldnet... " >&6; } +if test ${ac_cv_lib_dnet_dnet_ntoa+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-ldnet $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -20301,39 +24124,39 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char dnet_ntoa (); int -main () +main (void) { return dnet_ntoa (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_dnet_dnet_ntoa=yes -else +else $as_nop ac_cv_lib_dnet_dnet_ntoa=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_dnet_ntoa" >&5 -$as_echo "$ac_cv_lib_dnet_dnet_ntoa" >&6; } -if test "x$ac_cv_lib_dnet_dnet_ntoa" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_dnet_ntoa" >&5 +printf "%s\n" "$ac_cv_lib_dnet_dnet_ntoa" >&6; } +if test "x$ac_cv_lib_dnet_dnet_ntoa" = xyes +then : X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet" fi if test $ac_cv_lib_dnet_dnet_ntoa = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet_stub" >&5 -$as_echo_n "checking for dnet_ntoa in -ldnet_stub... " >&6; } -if ${ac_cv_lib_dnet_stub_dnet_ntoa+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dnet_ntoa in -ldnet_stub" >&5 +printf %s "checking for dnet_ntoa in -ldnet_stub... " >&6; } +if test ${ac_cv_lib_dnet_stub_dnet_ntoa+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-ldnet_stub $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -20342,36 +24165,35 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char dnet_ntoa (); int -main () +main (void) { return dnet_ntoa (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_dnet_stub_dnet_ntoa=yes -else +else $as_nop ac_cv_lib_dnet_stub_dnet_ntoa=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_stub_dnet_ntoa" >&5 -$as_echo "$ac_cv_lib_dnet_stub_dnet_ntoa" >&6; } -if test "x$ac_cv_lib_dnet_stub_dnet_ntoa" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dnet_stub_dnet_ntoa" >&5 +printf "%s\n" "$ac_cv_lib_dnet_stub_dnet_ntoa" >&6; } +if test "x$ac_cv_lib_dnet_stub_dnet_ntoa" = xyes +then : X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub" fi fi fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS="$ac_xsave_LIBS" @@ -20384,16 +24206,18 @@ rm -f core conftest.err conftest.$ac_objext \ # The functions gethostbyname, getservbyname, and inet_addr are # in -lbsd on LynxOS 3.0.1/i386, according to Lars Hecking. ac_fn_c_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname" -if test "x$ac_cv_func_gethostbyname" = xyes; then : +if test "x$ac_cv_func_gethostbyname" = xyes +then : fi if test $ac_cv_func_gethostbyname = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5 -$as_echo_n "checking for gethostbyname in -lnsl... " >&6; } -if ${ac_cv_lib_nsl_gethostbyname+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5 +printf %s "checking for gethostbyname in -lnsl... " >&6; } +if test ${ac_cv_lib_nsl_gethostbyname+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lnsl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -20402,39 +24226,39 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char gethostbyname (); int -main () +main (void) { return gethostbyname (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_nsl_gethostbyname=yes -else +else $as_nop ac_cv_lib_nsl_gethostbyname=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5 -$as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; } -if test "x$ac_cv_lib_nsl_gethostbyname" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5 +printf "%s\n" "$ac_cv_lib_nsl_gethostbyname" >&6; } +if test "x$ac_cv_lib_nsl_gethostbyname" = xyes +then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl" fi if test $ac_cv_lib_nsl_gethostbyname = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lbsd" >&5 -$as_echo_n "checking for gethostbyname in -lbsd... " >&6; } -if ${ac_cv_lib_bsd_gethostbyname+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lbsd" >&5 +printf %s "checking for gethostbyname in -lbsd... " >&6; } +if test ${ac_cv_lib_bsd_gethostbyname+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lbsd $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -20443,30 +24267,29 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char gethostbyname (); int -main () +main (void) { return gethostbyname (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_bsd_gethostbyname=yes -else +else $as_nop ac_cv_lib_bsd_gethostbyname=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_gethostbyname" >&5 -$as_echo "$ac_cv_lib_bsd_gethostbyname" >&6; } -if test "x$ac_cv_lib_bsd_gethostbyname" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_gethostbyname" >&5 +printf "%s\n" "$ac_cv_lib_bsd_gethostbyname" >&6; } +if test "x$ac_cv_lib_bsd_gethostbyname" = xyes +then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lbsd" fi @@ -20481,16 +24304,18 @@ fi # must be given before -lnsl if both are needed. We assume that # if connect needs -lnsl, so does gethostbyname. ac_fn_c_check_func "$LINENO" "connect" "ac_cv_func_connect" -if test "x$ac_cv_func_connect" = xyes; then : +if test "x$ac_cv_func_connect" = xyes +then : fi if test $ac_cv_func_connect = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for connect in -lsocket" >&5 -$as_echo_n "checking for connect in -lsocket... " >&6; } -if ${ac_cv_lib_socket_connect+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for connect in -lsocket" >&5 +printf %s "checking for connect in -lsocket... " >&6; } +if test ${ac_cv_lib_socket_connect+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lsocket $X_EXTRA_LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -20499,30 +24324,29 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char connect (); int -main () +main (void) { return connect (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_socket_connect=yes -else +else $as_nop ac_cv_lib_socket_connect=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_connect" >&5 -$as_echo "$ac_cv_lib_socket_connect" >&6; } -if test "x$ac_cv_lib_socket_connect" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_connect" >&5 +printf "%s\n" "$ac_cv_lib_socket_connect" >&6; } +if test "x$ac_cv_lib_socket_connect" = xyes +then : X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS" fi @@ -20530,16 +24354,18 @@ fi # Guillermo Gomez says -lposix is necessary on A/UX. ac_fn_c_check_func "$LINENO" "remove" "ac_cv_func_remove" -if test "x$ac_cv_func_remove" = xyes; then : +if test "x$ac_cv_func_remove" = xyes +then : fi if test $ac_cv_func_remove = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for remove in -lposix" >&5 -$as_echo_n "checking for remove in -lposix... " >&6; } -if ${ac_cv_lib_posix_remove+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for remove in -lposix" >&5 +printf %s "checking for remove in -lposix... " >&6; } +if test ${ac_cv_lib_posix_remove+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lposix $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -20548,30 +24374,29 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char remove (); int -main () +main (void) { return remove (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_posix_remove=yes -else +else $as_nop ac_cv_lib_posix_remove=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_posix_remove" >&5 -$as_echo "$ac_cv_lib_posix_remove" >&6; } -if test "x$ac_cv_lib_posix_remove" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_posix_remove" >&5 +printf "%s\n" "$ac_cv_lib_posix_remove" >&6; } +if test "x$ac_cv_lib_posix_remove" = xyes +then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix" fi @@ -20579,16 +24404,18 @@ fi # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay. ac_fn_c_check_func "$LINENO" "shmat" "ac_cv_func_shmat" -if test "x$ac_cv_func_shmat" = xyes; then : +if test "x$ac_cv_func_shmat" = xyes +then : fi if test $ac_cv_func_shmat = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shmat in -lipc" >&5 -$as_echo_n "checking for shmat in -lipc... " >&6; } -if ${ac_cv_lib_ipc_shmat+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for shmat in -lipc" >&5 +printf %s "checking for shmat in -lipc... " >&6; } +if test ${ac_cv_lib_ipc_shmat+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lipc $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -20597,30 +24424,29 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char shmat (); int -main () +main (void) { return shmat (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_ipc_shmat=yes -else +else $as_nop ac_cv_lib_ipc_shmat=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ipc_shmat" >&5 -$as_echo "$ac_cv_lib_ipc_shmat" >&6; } -if test "x$ac_cv_lib_ipc_shmat" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ipc_shmat" >&5 +printf "%s\n" "$ac_cv_lib_ipc_shmat" >&6; } +if test "x$ac_cv_lib_ipc_shmat" = xyes +then : X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc" fi @@ -20636,11 +24462,12 @@ fi # These have to be linked with before -lX11, unlike the other # libraries we check for below, so use a different variable. # John Interrante, Karl Berry - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for IceConnectionNumber in -lICE" >&5 -$as_echo_n "checking for IceConnectionNumber in -lICE... " >&6; } -if ${ac_cv_lib_ICE_IceConnectionNumber+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for IceConnectionNumber in -lICE" >&5 +printf %s "checking for IceConnectionNumber in -lICE... " >&6; } +if test ${ac_cv_lib_ICE_IceConnectionNumber+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lICE $X_EXTRA_LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -20649,30 +24476,29 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char IceConnectionNumber (); int -main () +main (void) { return IceConnectionNumber (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_ICE_IceConnectionNumber=yes -else +else $as_nop ac_cv_lib_ICE_IceConnectionNumber=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ICE_IceConnectionNumber" >&5 -$as_echo "$ac_cv_lib_ICE_IceConnectionNumber" >&6; } -if test "x$ac_cv_lib_ICE_IceConnectionNumber" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ICE_IceConnectionNumber" >&5 +printf "%s\n" "$ac_cv_lib_ICE_IceConnectionNumber" >&6; } +if test "x$ac_cv_lib_ICE_IceConnectionNumber" = xyes +then : X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE" fi @@ -20682,9 +24508,10 @@ fi if test x$have_x = xyes; then # Check whether --enable-x11-shared was given. -if test "${enable_x11_shared+set}" = set; then : +if test ${enable_x11_shared+y} +then : enableval=$enable_x11_shared; -else +else $as_nop enable_x11_shared=maybe fi @@ -20695,34 +24522,31 @@ fi x11_lib='/opt/X11/lib/libX11.6.dylib' x11ext_lib='/opt/X11/lib/libXext.6.dylib' xcursor_lib='/opt/X11/lib/libXcursor.1.dylib' - xinerama_lib='/opt/X11/lib/libXinerama.1.dylib' xinput_lib='/opt/X11/lib/libXi.6.dylib' + xfixes_lib='/opt/X11/lib/libXfixes.3.dylib' xrandr_lib='/opt/X11/lib/libXrandr.2.dylib' xrender_lib='/opt/X11/lib/libXrender.1.dylib' xss_lib='/opt/X11/lib/libXss.1.dylib' - xvidmode_lib='/opt/X11/lib/libXxf86vm.1.dylib' ;; *-*-openbsd*) x11_lib='libX11.so' x11ext_lib='libXext.so' xcursor_lib='libXcursor.so' - xinerama_lib='libXinerama.so' xinput_lib='libXi.so' + xfixes_lib='libXfixes.so' xrandr_lib='libXrandr.so' xrender_lib='libXrender.so' xss_lib='libXss.so' - xvidmode_lib='libXxf86vm.so' ;; *) x11_lib=`find_lib "libX11.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'` x11ext_lib=`find_lib "libXext.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'` xcursor_lib=`find_lib "libXcursor.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'` - xinerama_lib=`find_lib "libXinerama.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'` xinput_lib=`find_lib "libXi.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'` + xfixes_lib=`find_lib "libXfixes.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'` xrandr_lib=`find_lib "libXrandr.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'` xrender_lib=`find_lib "libXrender.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'` xss_lib=`find_lib "libXss.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'` - xvidmode_lib=`find_lib "libXxf86vm.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'` ;; esac @@ -20736,13 +24560,13 @@ fi #include " -if test "x$ac_cv_header_X11_extensions_Xext_h" = xyes; then : +if test "x$ac_cv_header_X11_extensions_Xext_h" = xyes +then : have_xext_h_hdr=yes -else +else $as_nop have_xext_h_hdr=no fi - if test x$have_xext_h_hdr != xyes; then as_fn_error $? " *** Missing Xext.h, maybe you need to install the libxext-dev package? @@ -20750,7 +24574,7 @@ fi fi -$as_echo "#define SDL_VIDEO_DRIVER_X11 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_DRIVER_X11 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/video/x11/*.c" EXTRA_CFLAGS="$EXTRA_CFLAGS $X_CFLAGS" @@ -20763,8 +24587,8 @@ $as_echo "#define SDL_VIDEO_DRIVER_X11 1" >>confdefs.h fi if test x$have_loadso != xyes && \ test x$enable_x11_shared = xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: You must have SDL_LoadObject() support for dynamic X11 loading" >&5 -$as_echo "$as_me: WARNING: You must have SDL_LoadObject() support for dynamic X11 loading" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: You must have SDL_LoadObject() support for dynamic X11 loading" >&5 +printf "%s\n" "$as_me: WARNING: You must have SDL_LoadObject() support for dynamic X11 loading" >&2;} enable_x11_shared=no fi if test x$have_loadso = xyes && \ @@ -20772,14 +24596,10 @@ $as_echo "$as_me: WARNING: You must have SDL_LoadObject() support for dynamic X1 echo "-- dynamic libX11 -> $x11_lib" echo "-- dynamic libX11ext -> $x11ext_lib" -cat >>confdefs.h <<_ACEOF -#define SDL_VIDEO_DRIVER_X11_DYNAMIC "$x11_lib" -_ACEOF +printf "%s\n" "#define SDL_VIDEO_DRIVER_X11_DYNAMIC \"$x11_lib\"" >>confdefs.h -cat >>confdefs.h <<_ACEOF -#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT "$x11ext_lib" -_ACEOF +printf "%s\n" "#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT \"$x11ext_lib\"" >>confdefs.h SUMMARY_video="${SUMMARY_video} x11(dynamic)" else @@ -20789,41 +24609,8 @@ _ACEOF fi have_video=yes - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for const parameter to XextAddDisplay" >&5 -$as_echo_n "checking for const parameter to XextAddDisplay... " >&6; } - have_const_param_XextAddDisplay=no - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - #include - #include - #include - #include - extern XExtDisplayInfo* XextAddDisplay(XExtensionInfo* a,Display* b,_Xconst char* c,XExtensionHooks* d,int e,XPointer f); - -int -main () -{ - - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - have_const_param_XextAddDisplay=yes - -$as_echo "#define SDL_VIDEO_DRIVER_X11_CONST_PARAM_XEXTADDDISPLAY 1" >>confdefs.h - - -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_const_param_XextAddDisplay" >&5 -$as_echo "$have_const_param_XextAddDisplay" >&6; } - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XGenericEvent" >&5 -$as_echo_n "checking for XGenericEvent... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for XGenericEvent" >&5 +printf %s "checking for XGenericEvent... " >&6; } have_XGenericEvent=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -20831,7 +24618,7 @@ $as_echo_n "checking for XGenericEvent... " >&6; } #include int -main () +main (void) { Display *display; @@ -20845,23 +24632,25 @@ XFreeEventData(display, cookie); return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : have_XGenericEvent=yes -$as_echo "#define SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS 1" >>confdefs.h fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_XGenericEvent" >&5 -$as_echo "$have_XGenericEvent" >&6; } +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_XGenericEvent" >&5 +printf "%s\n" "$have_XGenericEvent" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XkbKeycodeToKeysym in -lX11" >&5 -$as_echo_n "checking for XkbKeycodeToKeysym in -lX11... " >&6; } -if ${ac_cv_lib_X11_XkbKeycodeToKeysym+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for XkbKeycodeToKeysym in -lX11" >&5 +printf %s "checking for XkbKeycodeToKeysym in -lX11... " >&6; } +if test ${ac_cv_lib_X11_XkbKeycodeToKeysym+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lX11 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -20870,40 +24659,40 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char XkbKeycodeToKeysym (); int -main () +main (void) { return XkbKeycodeToKeysym (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_X11_XkbKeycodeToKeysym=yes -else +else $as_nop ac_cv_lib_X11_XkbKeycodeToKeysym=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_X11_XkbKeycodeToKeysym" >&5 -$as_echo "$ac_cv_lib_X11_XkbKeycodeToKeysym" >&6; } -if test "x$ac_cv_lib_X11_XkbKeycodeToKeysym" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_X11_XkbKeycodeToKeysym" >&5 +printf "%s\n" "$ac_cv_lib_X11_XkbKeycodeToKeysym" >&6; } +if test "x$ac_cv_lib_X11_XkbKeycodeToKeysym" = xyes +then : -$as_echo "#define SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM 1" >>confdefs.h fi # Check whether --enable-video-x11-xcursor was given. -if test "${enable_video_x11_xcursor+set}" = set; then : +if test ${enable_video_x11_xcursor+y} +then : enableval=$enable_video_x11_xcursor; -else +else $as_nop enable_video_x11_xcursor=yes fi @@ -20912,28 +24701,27 @@ fi ac_fn_c_check_header_compile "$LINENO" "X11/Xcursor/Xcursor.h" "ac_cv_header_X11_Xcursor_Xcursor_h" "#include " -if test "x$ac_cv_header_X11_Xcursor_Xcursor_h" = xyes; then : +if test "x$ac_cv_header_X11_Xcursor_Xcursor_h" = xyes +then : have_xcursor_h_hdr=yes -else +else $as_nop have_xcursor_h_hdr=no fi - if test x$have_xcursor_h_hdr = xyes; then if test x$enable_x11_shared = xyes && test x$xcursor_lib != x ; then echo "-- dynamic libXcursor -> $xcursor_lib" -cat >>confdefs.h <<_ACEOF -#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR "$xcursor_lib" -_ACEOF +printf "%s\n" "#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR \"$xcursor_lib\"" >>confdefs.h definitely_enable_video_x11_xcursor=yes else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XcursorImageCreate in -lXcursor" >&5 -$as_echo_n "checking for XcursorImageCreate in -lXcursor... " >&6; } -if ${ac_cv_lib_Xcursor_XcursorImageCreate+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for XcursorImageCreate in -lXcursor" >&5 +printf %s "checking for XcursorImageCreate in -lXcursor... " >&6; } +if test ${ac_cv_lib_Xcursor_XcursorImageCreate+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lXcursor $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -20942,30 +24730,29 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char XcursorImageCreate (); int -main () +main (void) { return XcursorImageCreate (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_Xcursor_XcursorImageCreate=yes -else +else $as_nop ac_cv_lib_Xcursor_XcursorImageCreate=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xcursor_XcursorImageCreate" >&5 -$as_echo "$ac_cv_lib_Xcursor_XcursorImageCreate" >&6; } -if test "x$ac_cv_lib_Xcursor_XcursorImageCreate" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xcursor_XcursorImageCreate" >&5 +printf "%s\n" "$ac_cv_lib_Xcursor_XcursorImageCreate" >&6; } +if test "x$ac_cv_lib_Xcursor_XcursorImageCreate" = xyes +then : have_xcursor_lib=yes fi @@ -20978,14 +24765,15 @@ fi fi if test x$definitely_enable_video_x11_xcursor = xyes; then -$as_echo "#define SDL_VIDEO_DRIVER_X11_XCURSOR 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_DRIVER_X11_XCURSOR 1" >>confdefs.h SUMMARY_video_x11="${SUMMARY_video_x11} xcursor" fi # Check whether --enable-video-x11-xdbe was given. -if test "${enable_video_x11_xdbe+set}" = set; then : +if test ${enable_video_x11_xdbe+y} +then : enableval=$enable_video_x11_xdbe; -else +else $as_nop enable_video_x11_xdbe=yes fi @@ -20993,106 +24781,25 @@ fi ac_fn_c_check_header_compile "$LINENO" "X11/extensions/Xdbe.h" "ac_cv_header_X11_extensions_Xdbe_h" "#include " -if test "x$ac_cv_header_X11_extensions_Xdbe_h" = xyes; then : +if test "x$ac_cv_header_X11_extensions_Xdbe_h" = xyes +then : have_dbe_h_hdr=yes -else +else $as_nop have_dbe_h_hdr=no fi - if test x$have_dbe_h_hdr = xyes; then -$as_echo "#define SDL_VIDEO_DRIVER_X11_XDBE 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_DRIVER_X11_XDBE 1" >>confdefs.h SUMMARY_video_x11="${SUMMARY_video_x11} xdbe" fi fi - # Check whether --enable-video-x11-xinerama was given. -if test "${enable_video_x11_xinerama+set}" = set; then : - enableval=$enable_video_x11_xinerama; -else - enable_video_x11_xinerama=yes -fi - - if test x$enable_video_x11_xinerama = xyes; then - definitely_enable_video_x11_xinerama=no - ac_fn_c_check_header_compile "$LINENO" "X11/extensions/Xinerama.h" "ac_cv_header_X11_extensions_Xinerama_h" "#include - -" -if test "x$ac_cv_header_X11_extensions_Xinerama_h" = xyes; then : - have_xinerama_h_hdr=yes -else - have_xinerama_h_hdr=no -fi - - - if test x$have_xinerama_h_hdr = xyes; then - if test x$enable_x11_shared = xyes && test x$xinerama_lib != x ; then - echo "-- dynamic libXinerama -> $xinerama_lib" - -cat >>confdefs.h <<_ACEOF -#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA "$xinerama_lib" -_ACEOF - - definitely_enable_video_x11_xinerama=yes - else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XineramaQueryExtension in -lXinerama" >&5 -$as_echo_n "checking for XineramaQueryExtension in -lXinerama... " >&6; } -if ${ac_cv_lib_Xinerama_XineramaQueryExtension+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lXinerama $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char XineramaQueryExtension (); -int -main () -{ -return XineramaQueryExtension (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_Xinerama_XineramaQueryExtension=yes -else - ac_cv_lib_Xinerama_XineramaQueryExtension=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xinerama_XineramaQueryExtension" >&5 -$as_echo "$ac_cv_lib_Xinerama_XineramaQueryExtension" >&6; } -if test "x$ac_cv_lib_Xinerama_XineramaQueryExtension" = xyes; then : - have_xinerama_lib=yes -fi - - if test x$have_xinerama_lib = xyes ; then - EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lXinerama" - definitely_enable_video_x11_xinerama=yes - fi - fi - fi - fi - if test x$definitely_enable_video_x11_xinerama = xyes; then - -$as_echo "#define SDL_VIDEO_DRIVER_X11_XINERAMA 1" >>confdefs.h - - SUMMARY_video_x11="${SUMMARY_video_x11} xinerama" - fi # Check whether --enable-video-x11-xinput was given. -if test "${enable_video_x11_xinput+set}" = set; then : +if test ${enable_video_x11_xinput+y} +then : enableval=$enable_video_x11_xinput; -else +else $as_nop enable_video_x11_xinput=yes fi @@ -21101,28 +24808,27 @@ fi ac_fn_c_check_header_compile "$LINENO" "X11/extensions/XInput2.h" "ac_cv_header_X11_extensions_XInput2_h" "#include " -if test "x$ac_cv_header_X11_extensions_XInput2_h" = xyes; then : +if test "x$ac_cv_header_X11_extensions_XInput2_h" = xyes +then : have_xinput_h_hdr=yes -else +else $as_nop have_xinput_h_hdr=no fi - if test x$have_xinput_h_hdr = xyes; then if test x$enable_x11_shared = xyes && test x$xinput_lib != x ; then echo "-- dynamic libXi -> $xinput_lib" -cat >>confdefs.h <<_ACEOF -#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2 "$xinput_lib" -_ACEOF +printf "%s\n" "#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2 \"$xinput_lib\"" >>confdefs.h definitely_enable_video_x11_xinput=yes else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XOpenDevice in -lXi" >&5 -$as_echo_n "checking for XOpenDevice in -lXi... " >&6; } -if ${ac_cv_lib_Xi_XOpenDevice+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for XOpenDevice in -lXi" >&5 +printf %s "checking for XOpenDevice in -lXi... " >&6; } +if test ${ac_cv_lib_Xi_XOpenDevice+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lXi $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -21131,30 +24837,29 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char XOpenDevice (); int -main () +main (void) { return XOpenDevice (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_Xi_XOpenDevice=yes -else +else $as_nop ac_cv_lib_Xi_XOpenDevice=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xi_XOpenDevice" >&5 -$as_echo "$ac_cv_lib_Xi_XOpenDevice" >&6; } -if test "x$ac_cv_lib_Xi_XOpenDevice" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xi_XOpenDevice" >&5 +printf "%s\n" "$ac_cv_lib_Xi_XOpenDevice" >&6; } +if test "x$ac_cv_lib_Xi_XOpenDevice" = xyes +then : have_xinput_lib=yes fi @@ -21168,10 +24873,10 @@ fi if test x$definitely_enable_video_x11_xinput = xyes; then SUMMARY_video_x11="${SUMMARY_video_x11} xinput2" -$as_echo "#define SDL_VIDEO_DRIVER_X11_XINPUT2 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_DRIVER_X11_XINPUT2 1" >>confdefs.h - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for xinput2 multitouch" >&5 -$as_echo_n "checking for xinput2 multitouch... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for xinput2 multitouch" >&5 +printf %s "checking for xinput2 multitouch... " >&6; } have_xinput2_multitouch=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -21181,7 +24886,7 @@ $as_echo_n "checking for xinput2 multitouch... " >&6; } #include int -main () +main (void) { int event_type = XI_TouchBegin; @@ -21191,27 +24896,128 @@ XITouchClassInfo *t; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : have_xinput2_multitouch=yes - $as_echo "#define SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH 1" >>confdefs.h + +printf "%s\n" "#define SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH 1" >>confdefs.h SUMMARY_video_x11="${SUMMARY_video_x11} xinput2_multitouch" fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_xinput2_multitouch" >&5 -$as_echo "$have_xinput2_multitouch" >&6; } +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_xinput2_multitouch" >&5 +printf "%s\n" "$have_xinput2_multitouch" >&6; } + fi + # Check whether --enable-video-x11-xfixes was given. +if test ${enable_video_x11_xfixes+y} +then : + enableval=$enable_video_x11_xfixes; +else $as_nop + enable_video_x11_xfixes=yes +fi + + if test x$enable_video_x11_xfixes = xyes; then + definitely_enable_video_x11_xfixes=no + # check along with XInput2.h because we use Xfixes with XIBarrierReleasePointer + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for X11/extensions/Xfixes.h" >&5 +printf %s "checking for X11/extensions/Xfixes.h... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + #include + #include + #include +int +main (void) +{ +BarrierEventID b; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + have_xfixes_h_hdr=yes +else $as_nop + have_xfixes_h_hdr=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_xfixes_h_hdr" >&5 +printf "%s\n" "$have_xfixes_h_hdr" >&6; } + if test x$have_xfixes_h_hdr = xyes; then + if test x$enable_x11_shared = xyes && test x$xfixes_lib != x ; then + echo "-- dynamic libXfixes -> $xfixes_lib" + +printf "%s\n" "#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XFIXES \"$xfixes_lib\"" >>confdefs.h + + definitely_enable_video_x11_xfixes=yes + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for XFixesCreatePointerBarrier in -lXfixes" >&5 +printf %s "checking for XFixesCreatePointerBarrier in -lXfixes... " >&6; } +if test ${ac_cv_lib_Xfixes_XFixesCreatePointerBarrier+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lXfixes $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char XFixesCreatePointerBarrier (); +int +main (void) +{ +return XFixesCreatePointerBarrier (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_Xfixes_XFixesCreatePointerBarrier=yes +else $as_nop + ac_cv_lib_Xfixes_XFixesCreatePointerBarrier=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xfixes_XFixesCreatePointerBarrier" >&5 +printf "%s\n" "$ac_cv_lib_Xfixes_XFixesCreatePointerBarrier" >&6; } +if test "x$ac_cv_lib_Xfixes_XFixesCreatePointerBarrier" = xyes +then : + have_xfixes_lib=yes +fi + + if test x$have_xfixes_lib = xyes ; then + EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lXfixes" + definitely_enable_video_x11_xfixes=yes + fi + fi + fi + fi + if test x$definitely_enable_video_x11_xfixes = xyes; then + +printf "%s\n" "#define SDL_VIDEO_DRIVER_X11_XFIXES 1" >>confdefs.h + + SUMMARY_video_x11="${SUMMARY_video_x11} xfixes" fi # Check whether --enable-video-x11-xrandr was given. -if test "${enable_video_x11_xrandr+set}" = set; then : +if test ${enable_video_x11_xrandr+y} +then : enableval=$enable_video_x11_xrandr; -else +else $as_nop enable_video_x11_xrandr=yes fi if test x$enable_video_x11_xrandr = xyes; then - definitely_enable_video_x11_xrandr=no + definitely_enable_video_x11_xrandr=no have_xrandr_h_hdr=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -21220,7 +25026,7 @@ fi #include int -main () +main (void) { XRRScreenResources *res = NULL; @@ -21229,27 +25035,25 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - have_xrandr_h_hdr=yes - +if ac_fn_c_try_compile "$LINENO" +then : + have_xrandr_h_hdr=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext if test x$have_xrandr_h_hdr = xyes; then if test x$enable_x11_shared = xyes && test x$xrandr_lib != x ; then echo "-- dynamic libXrandr -> $xrandr_lib" -cat >>confdefs.h <<_ACEOF -#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR "$xrandr_lib" -_ACEOF +printf "%s\n" "#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR \"$xrandr_lib\"" >>confdefs.h definitely_enable_video_x11_xrandr=yes else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XRRQueryExtension in -lXrandr" >&5 -$as_echo_n "checking for XRRQueryExtension in -lXrandr... " >&6; } -if ${ac_cv_lib_Xrandr_XRRQueryExtension+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for XRRQueryExtension in -lXrandr" >&5 +printf %s "checking for XRRQueryExtension in -lXrandr... " >&6; } +if test ${ac_cv_lib_Xrandr_XRRQueryExtension+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lXrandr $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -21258,30 +25062,29 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char XRRQueryExtension (); int -main () +main (void) { return XRRQueryExtension (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_Xrandr_XRRQueryExtension=yes -else +else $as_nop ac_cv_lib_Xrandr_XRRQueryExtension=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xrandr_XRRQueryExtension" >&5 -$as_echo "$ac_cv_lib_Xrandr_XRRQueryExtension" >&6; } -if test "x$ac_cv_lib_Xrandr_XRRQueryExtension" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xrandr_XRRQueryExtension" >&5 +printf "%s\n" "$ac_cv_lib_Xrandr_XRRQueryExtension" >&6; } +if test "x$ac_cv_lib_Xrandr_XRRQueryExtension" = xyes +then : have_xrandr_lib=yes fi @@ -21294,14 +25097,15 @@ fi fi if test x$definitely_enable_video_x11_xrandr = xyes; then -$as_echo "#define SDL_VIDEO_DRIVER_X11_XRANDR 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_DRIVER_X11_XRANDR 1" >>confdefs.h SUMMARY_video_x11="${SUMMARY_video_x11} xrandr" fi # Check whether --enable-video-x11-scrnsaver was given. -if test "${enable_video_x11_scrnsaver+set}" = set; then : +if test ${enable_video_x11_scrnsaver+y} +then : enableval=$enable_video_x11_scrnsaver; -else +else $as_nop enable_video_x11_scrnsaver=yes fi @@ -21309,28 +25113,27 @@ fi ac_fn_c_check_header_compile "$LINENO" "X11/extensions/scrnsaver.h" "ac_cv_header_X11_extensions_scrnsaver_h" "#include " -if test "x$ac_cv_header_X11_extensions_scrnsaver_h" = xyes; then : +if test "x$ac_cv_header_X11_extensions_scrnsaver_h" = xyes +then : have_scrnsaver_h_hdr=yes -else +else $as_nop have_scrnsaver_h_hdr=no fi - if test x$have_scrnsaver_h_hdr = xyes; then if test x$enable_x11_shared = xyes && test x$xss_lib != x ; then echo "-- dynamic libXss -> $xss_lib" -cat >>confdefs.h <<_ACEOF -#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS "$xss_lib" -_ACEOF +printf "%s\n" "#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS \"$xss_lib\"" >>confdefs.h definitely_enable_video_x11_scrnsaver=yes else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XScreenSaverSuspend in -lXss" >&5 -$as_echo_n "checking for XScreenSaverSuspend in -lXss... " >&6; } -if ${ac_cv_lib_Xss_XScreenSaverSuspend+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for XScreenSaverSuspend in -lXss" >&5 +printf %s "checking for XScreenSaverSuspend in -lXss... " >&6; } +if test ${ac_cv_lib_Xss_XScreenSaverSuspend+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lXss $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -21339,30 +25142,29 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char XScreenSaverSuspend (); int -main () +main (void) { return XScreenSaverSuspend (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_Xss_XScreenSaverSuspend=yes -else +else $as_nop ac_cv_lib_Xss_XScreenSaverSuspend=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xss_XScreenSaverSuspend" >&5 -$as_echo "$ac_cv_lib_Xss_XScreenSaverSuspend" >&6; } -if test "x$ac_cv_lib_Xss_XScreenSaverSuspend" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xss_XScreenSaverSuspend" >&5 +printf "%s\n" "$ac_cv_lib_Xss_XScreenSaverSuspend" >&6; } +if test "x$ac_cv_lib_Xss_XScreenSaverSuspend" = xyes +then : have_xss_lib=yes fi @@ -21375,14 +25177,15 @@ fi fi if test x$definitely_enable_video_x11_scrnsaver = xyes; then -$as_echo "#define SDL_VIDEO_DRIVER_X11_XSCRNSAVER 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_DRIVER_X11_XSCRNSAVER 1" >>confdefs.h SUMMARY_video_x11="${SUMMARY_video_x11} xscrnsaver" fi # Check whether --enable-video-x11-xshape was given. -if test "${enable_video_x11_xshape+set}" = set; then : +if test ${enable_video_x11_xshape+y} +then : enableval=$enable_video_x11_xshape; -else +else $as_nop enable_video_x11_xshape=yes fi @@ -21390,104 +25193,23 @@ fi ac_fn_c_check_header_compile "$LINENO" "X11/extensions/shape.h" "ac_cv_header_X11_extensions_shape_h" "#include " -if test "x$ac_cv_header_X11_extensions_shape_h" = xyes; then : +if test "x$ac_cv_header_X11_extensions_shape_h" = xyes +then : have_shape_h_hdr=yes -else +else $as_nop have_shape_h_hdr=no fi - if test x$have_shape_h_hdr = xyes; then -$as_echo "#define SDL_VIDEO_DRIVER_X11_XSHAPE 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_DRIVER_X11_XSHAPE 1" >>confdefs.h SUMMARY_video_x11="${SUMMARY_video_x11} xshape" fi fi - # Check whether --enable-video-x11-vm was given. -if test "${enable_video_x11_vm+set}" = set; then : - enableval=$enable_video_x11_vm; -else - enable_video_x11_vm=yes -fi - - if test x$enable_video_x11_vm = xyes; then - definitely_enable_video_x11_vm=no - ac_fn_c_check_header_compile "$LINENO" "X11/extensions/xf86vmode.h" "ac_cv_header_X11_extensions_xf86vmode_h" "#include - -" -if test "x$ac_cv_header_X11_extensions_xf86vmode_h" = xyes; then : - have_vm_h_hdr=yes -else - have_vm_h_hdr=no -fi - - - if test x$have_vm_h_hdr = xyes; then - if test x$enable_x11_shared = xyes && test x$xvidmode_lib != x ; then - echo "-- dynamic libXxf86vm -> $xvidmode_lib" - -cat >>confdefs.h <<_ACEOF -#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE "$xvidmode_lib" -_ACEOF - - definitely_enable_video_x11_vm=yes - else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XF86VidModeQueryVersion in -lXxf86vm" >&5 -$as_echo_n "checking for XF86VidModeQueryVersion in -lXxf86vm... " >&6; } -if ${ac_cv_lib_Xxf86vm_XF86VidModeQueryVersion+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lXxf86vm $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char XF86VidModeQueryVersion (); -int -main () -{ -return XF86VidModeQueryVersion (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_Xxf86vm_XF86VidModeQueryVersion=yes -else - ac_cv_lib_Xxf86vm_XF86VidModeQueryVersion=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_Xxf86vm_XF86VidModeQueryVersion" >&5 -$as_echo "$ac_cv_lib_Xxf86vm_XF86VidModeQueryVersion" >&6; } -if test "x$ac_cv_lib_Xxf86vm_XF86VidModeQueryVersion" = xyes; then : - have_vm_lib=yes -fi - - if test x$have_vm_lib = xyes ; then - EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lXxf86vm" - definitely_enable_video_x11_vm=yes - fi - fi - fi - fi - if test x$definitely_enable_video_x11_vm = xyes; then - -$as_echo "#define SDL_VIDEO_DRIVER_X11_XVIDMODE 1" >>confdefs.h - - SUMMARY_video_x11="${SUMMARY_video_x11} xvidmode" - fi fi - else + fi + if test x$have_x != xyes; then # Prevent Mesa from including X11 headers EXTRA_CFLAGS="$EXTRA_CFLAGS -DMESA_EGL_NO_X11_HEADERS -DEGL_NO_X11" fi @@ -21496,15 +25218,16 @@ $as_echo "#define SDL_VIDEO_DRIVER_X11_XVIDMODE 1" >>confdefs.h CheckVivanteVideo() { # Check whether --enable-video-vivante was given. -if test "${enable_video_vivante+set}" = set; then : +if test ${enable_video_vivante+y} +then : enableval=$enable_video_vivante; -else +else $as_nop enable_video_vivante=yes fi if test x$enable_video = xyes -a x$enable_video_vivante = xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Vivante VDK API" >&5 -$as_echo_n "checking for Vivante VDK API... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Vivante VDK API" >&5 +printf %s "checking for Vivante VDK API... " >&6; } have_vivante_vdk=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -21514,25 +25237,23 @@ $as_echo_n "checking for Vivante VDK API... " >&6; } #include int -main () +main (void) { - ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - have_vivante_vdk=yes - +if ac_fn_c_try_compile "$LINENO" +then : + have_vivante_vdk=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_vivante_vdk" >&5 -$as_echo "$have_vivante_vdk" >&6; } +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_vivante_vdk" >&5 +printf "%s\n" "$have_vivante_vdk" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Vivante FB API" >&5 -$as_echo_n "checking for Vivante FB API... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Vivante FB API" >&5 +printf %s "checking for Vivante FB API... " >&6; } have_vivante_egl=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -21542,31 +25263,29 @@ $as_echo_n "checking for Vivante FB API... " >&6; } #include int -main () +main (void) { - ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - have_vivante_egl=yes - +if ac_fn_c_try_compile "$LINENO" +then : + have_vivante_egl=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_vivante_egl" >&5 -$as_echo "$have_vivante_egl" >&6; } +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_vivante_egl" >&5 +printf "%s\n" "$have_vivante_egl" >&6; } if test x$have_vivante_vdk = xyes -o x$have_vivante_egl = xyes; then -$as_echo "#define SDL_VIDEO_DRIVER_VIVANTE 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_DRIVER_VIVANTE 1" >>confdefs.h EXTRA_CFLAGS="$EXTRA_CFLAGS -DLINUX -DEGL_API_FB" if test x$have_vivante_vdk = xyes; then -$as_echo "#define SDL_VIDEO_DRIVER_VIVANTE_VDK 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_DRIVER_VIVANTE_VDK 1" >>confdefs.h EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lVDK" fi @@ -21581,7 +25300,7 @@ CheckHaikuVideo() { if test x$enable_video = xyes; then -$as_echo "#define SDL_VIDEO_DRIVER_HAIKU 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_DRIVER_HAIKU 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/video/haiku/*.cc" have_video=yes @@ -21592,17 +25311,18 @@ $as_echo "#define SDL_VIDEO_DRIVER_HAIKU 1" >>confdefs.h CheckCOCOA() { # Check whether --enable-video-cocoa was given. -if test "${enable_video_cocoa+set}" = set; then : +if test ${enable_video_cocoa+y} +then : enableval=$enable_video_cocoa; -else +else $as_nop enable_video_cocoa=yes fi if test x$enable_video = xyes -a x$enable_video_cocoa = xyes; then save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -x objective-c" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Cocoa framework" >&5 -$as_echo_n "checking for Cocoa framework... " >&6; } + CFLAGS="$CFLAGS -x objective-c" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Cocoa framework" >&5 +printf %s "checking for Cocoa framework... " >&6; } have_cocoa=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -21610,26 +25330,24 @@ $as_echo_n "checking for Cocoa framework... " >&6; } #import int -main () +main (void) { - ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - have_cocoa=yes - +if ac_fn_c_try_compile "$LINENO" +then : + have_cocoa=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_cocoa" >&5 -$as_echo "$have_cocoa" >&6; } +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_cocoa" >&5 +printf "%s\n" "$have_cocoa" >&6; } CFLAGS="$save_CFLAGS" if test x$have_cocoa = xyes; then -$as_echo "#define SDL_VIDEO_DRIVER_COCOA 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_DRIVER_COCOA 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/video/cocoa/*.m" SUMMARY_video="${SUMMARY_video} cocoa" @@ -21641,24 +25359,26 @@ $as_echo "#define SDL_VIDEO_DRIVER_COCOA 1" >>confdefs.h CheckMETAL() { # Check whether --enable-video-metal was given. -if test "${enable_video_metal+set}" = set; then : +if test ${enable_video_metal+y} +then : enableval=$enable_video_metal; -else +else $as_nop enable_video_metal=yes fi # Check whether --enable-render-metal was given. -if test "${enable_render_metal+set}" = set; then : +if test ${enable_render_metal+y} +then : enableval=$enable_render_metal; -else +else $as_nop enable_render_metal=yes fi if test x$enable_video = xyes -a x$enable_video_metal = xyes; then save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -x objective-c" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Metal framework" >&5 -$as_echo_n "checking for Metal framework... " >&6; } + CFLAGS="$CFLAGS -x objective-c" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Metal framework" >&5 +printf %s "checking for Metal framework... " >&6; } have_metal=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -21667,35 +25387,33 @@ $as_echo_n "checking for Metal framework... " >&6; } #import #import - #if !TARGET_CPU_X86_64 + #if TARGET_CPU_X86 #error Metal doesn't work on this configuration #endif int -main () +main (void) { - ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - have_metal=yes - +if ac_fn_c_try_compile "$LINENO" +then : + have_metal=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext CFLAGS="$save_CFLAGS" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_metal" >&5 -$as_echo "$have_metal" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_metal" >&5 +printf "%s\n" "$have_metal" >&6; } if test x$have_metal = xyes; then -$as_echo "#define SDL_VIDEO_METAL 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_METAL 1" >>confdefs.h if test x$enable_render = xyes -a x$enable_render_metal = xyes; then -$as_echo "#define SDL_VIDEO_RENDER_METAL 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_RENDER_METAL 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/render/metal/*.m" fi @@ -21707,32 +25425,33 @@ $as_echo "#define SDL_VIDEO_RENDER_METAL 1" >>confdefs.h fi } - CheckDirectFB() { # Check whether --enable-video-directfb was given. -if test "${enable_video_directfb+set}" = set; then : +if test ${enable_video_directfb+y} +then : enableval=$enable_video_directfb; -else +else $as_nop enable_video_directfb=no fi if test x$enable_video = xyes -a x$enable_video_directfb = xyes; then pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for DIRECTFB" >&5 -$as_echo_n "checking for DIRECTFB... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for directfb >= 1.0.0" >&5 +printf %s "checking for directfb >= 1.0.0... " >&6; } if test -n "$DIRECTFB_CFLAGS"; then pkg_cv_DIRECTFB_CFLAGS="$DIRECTFB_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"directfb >= 1.0.0\""; } >&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"directfb >= 1.0.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "directfb >= 1.0.0") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_DIRECTFB_CFLAGS=`$PKG_CONFIG --cflags "directfb >= 1.0.0" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi @@ -21743,12 +25462,13 @@ if test -n "$DIRECTFB_LIBS"; then pkg_cv_DIRECTFB_LIBS="$DIRECTFB_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"directfb >= 1.0.0\""; } >&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"directfb >= 1.0.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "directfb >= 1.0.0") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_DIRECTFB_LIBS=`$PKG_CONFIG --libs "directfb >= 1.0.0" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi @@ -21759,8 +25479,8 @@ fi if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes @@ -21768,23 +25488,23 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - DIRECTFB_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "directfb >= 1.0.0" 2>&1` + DIRECTFB_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "directfb >= 1.0.0" 2>&1` else - DIRECTFB_PKG_ERRORS=`$PKG_CONFIG --print-errors "directfb >= 1.0.0" 2>&1` + DIRECTFB_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "directfb >= 1.0.0" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$DIRECTFB_PKG_ERRORS" >&5 video_directfb=no elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } video_directfb=no else DIRECTFB_CFLAGS=$pkg_cv_DIRECTFB_CFLAGS DIRECTFB_LIBS=$pkg_cv_DIRECTFB_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } video_directfb=yes fi @@ -21792,64 +25512,56 @@ fi # SuSE 11.1 installs directfb-config without directfb-devel save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $DIRECTFB_CFLAGS" - ac_fn_c_check_header_mongrel "$LINENO" "directfb.h" "ac_cv_header_directfb_h" "$ac_includes_default" -if test "x$ac_cv_header_directfb_h" = xyes; then : + ac_fn_c_check_header_compile "$LINENO" "directfb.h" "ac_cv_header_directfb_h" "$ac_includes_default" +if test "x$ac_cv_header_directfb_h" = xyes +then : have_directfb_hdr=yes -else +else $as_nop have_directfb_hdr=no fi - CPPFLAGS="$save_CPPFLAGS" video_directfb=$have_directfb_hdr fi if test x$video_directfb = xyes; then # Check whether --enable-directfb-shared was given. -if test "${enable_directfb_shared+set}" = set; then : +if test ${enable_directfb_shared+y} +then : enableval=$enable_directfb_shared; -else +else $as_nop enable_directfb_shared=yes fi -$as_echo "#define SDL_VIDEO_DRIVER_DIRECTFB 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_DRIVER_DIRECTFB 1" >>confdefs.h -$as_echo "#define SDL_VIDEO_RENDER_DIRECTFB 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_RENDER_DIRECTFB 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/video/directfb/*.c" EXTRA_CFLAGS="$EXTRA_CFLAGS $DIRECTFB_CFLAGS" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for directfb dynamic loading support" >&5 -$as_echo_n "checking for directfb dynamic loading support... " >&6; } directfb_shared=no - directfb_lib=`find_lib "libdirectfb*.so.*" "$DIRECTFB_LIBS"` - # | sed 's/.*\/\(.*\)/\1/; q'`] -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \"directfb $directfb_lib\"" >&5 -$as_echo "$as_me: WARNING: \"directfb $directfb_lib\"" >&2;} + directfb_lib=`find_lib "libdirectfb*.so.*" "$DIRECTFB_LIBS" | sed 's/.*\/\(.*\)/\1/; q'` if test x$have_loadso != xyes && \ test x$enable_directfb_shared = xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: You must have SDL_LoadObject() support for dynamic directfb loading" >&5 -$as_echo "$as_me: WARNING: You must have SDL_LoadObject() support for dynamic directfb loading" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: You must have SDL_LoadObject() support for dynamic directfb loading" >&5 +printf "%s\n" "$as_me: WARNING: You must have SDL_LoadObject() support for dynamic directfb loading" >&2;} fi if test x$have_loadso = xyes && \ test x$enable_directfb_shared = xyes && test x$directfb_lib != x; then directfb_shared=yes - echo "-- $directfb_lib_spec -> $directfb_lib" + echo "-- dynamic libdirectfb -> $directfb_lib" -cat >>confdefs.h <<_ACEOF -#define SDL_VIDEO_DRIVER_DIRECTFB_DYNAMIC "$directfb_lib" -_ACEOF +printf "%s\n" "#define SDL_VIDEO_DRIVER_DIRECTFB_DYNAMIC \"$directfb_lib\"" >>confdefs.h SUMMARY_video="${SUMMARY_video} directfb(dynamic)" else EXTRA_LDFLAGS="$EXTRA_LDFLAGS $DIRECTFB_LIBS" SUMMARY_video="${SUMMARY_video} directfb" fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $directfb_shared" >&5 -$as_echo "$directfb_shared" >&6; } SDL_CFLAGS="$SDL_CFLAGS $DIRECTFB_CFLAGS" have_video=yes fi @@ -21859,31 +25571,36 @@ $as_echo "$directfb_shared" >&6; } CheckKMSDRM() { # Check whether --enable-video-kmsdrm was given. -if test "${enable_video_kmsdrm+set}" = set; then : +if test ${enable_video_kmsdrm+y} +then : enableval=$enable_video_kmsdrm; -else - enable_video_kmsdrm=no +else $as_nop + enable_video_kmsdrm=yes fi - if test x$enable_video = xyes -a x$enable_video_kmsdrm = xyes; then + if test x$enable_video = xyes && \ + test x$enable_video_kmsdrm = xyes && \ + test x$video_opengl_egl = xyes; then + video_kmsdrm=no pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBDRM" >&5 -$as_echo_n "checking for LIBDRM... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libdrm >= 1.4.82" >&5 +printf %s "checking for libdrm >= 1.4.82... " >&6; } if test -n "$LIBDRM_CFLAGS"; then pkg_cv_LIBDRM_CFLAGS="$LIBDRM_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libdrm >= 2.4.46\""; } >&5 - ($PKG_CONFIG --exists --print-errors "libdrm >= 2.4.46") 2>&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libdrm >= 1.4.82\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libdrm >= 1.4.82") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_LIBDRM_CFLAGS=`$PKG_CONFIG --cflags "libdrm >= 2.4.46" 2>/dev/null` + pkg_cv_LIBDRM_CFLAGS=`$PKG_CONFIG --cflags "libdrm >= 1.4.82" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi @@ -21894,12 +25611,13 @@ if test -n "$LIBDRM_LIBS"; then pkg_cv_LIBDRM_LIBS="$LIBDRM_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libdrm >= 2.4.46\""; } >&5 - ($PKG_CONFIG --exists --print-errors "libdrm >= 2.4.46") 2>&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libdrm >= 1.4.82\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libdrm >= 1.4.82") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_LIBDRM_LIBS=`$PKG_CONFIG --libs "libdrm >= 2.4.46" 2>/dev/null` + pkg_cv_LIBDRM_LIBS=`$PKG_CONFIG --libs "libdrm >= 1.4.82" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi @@ -21910,8 +25628,8 @@ fi if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes @@ -21919,40 +25637,41 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - LIBDRM_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "libdrm >= 2.4.46" 2>&1` + LIBDRM_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libdrm >= 1.4.82" 2>&1` else - LIBDRM_PKG_ERRORS=`$PKG_CONFIG --print-errors "libdrm >= 2.4.46" 2>&1` + LIBDRM_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libdrm >= 1.4.82" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$LIBDRM_PKG_ERRORS" >&5 libdrm_avail=no elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } libdrm_avail=no else LIBDRM_CFLAGS=$pkg_cv_LIBDRM_CFLAGS LIBDRM_LIBS=$pkg_cv_LIBDRM_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } libdrm_avail=yes fi pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBGBM" >&5 -$as_echo_n "checking for LIBGBM... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gbm >= 11.1.0" >&5 +printf %s "checking for gbm >= 11.1.0... " >&6; } if test -n "$LIBGBM_CFLAGS"; then pkg_cv_LIBGBM_CFLAGS="$LIBGBM_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gbm >= 9.0.0\""; } >&5 - ($PKG_CONFIG --exists --print-errors "gbm >= 9.0.0") 2>&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gbm >= 11.1.0\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gbm >= 11.1.0") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_LIBGBM_CFLAGS=`$PKG_CONFIG --cflags "gbm >= 9.0.0" 2>/dev/null` + pkg_cv_LIBGBM_CFLAGS=`$PKG_CONFIG --cflags "gbm >= 11.1.0" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi @@ -21963,12 +25682,13 @@ if test -n "$LIBGBM_LIBS"; then pkg_cv_LIBGBM_LIBS="$LIBGBM_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gbm >= 9.0.0\""; } >&5 - ($PKG_CONFIG --exists --print-errors "gbm >= 9.0.0") 2>&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gbm >= 11.1.0\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gbm >= 11.1.0") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_LIBGBM_LIBS=`$PKG_CONFIG --libs "gbm >= 9.0.0" 2>/dev/null` + pkg_cv_LIBGBM_LIBS=`$PKG_CONFIG --libs "gbm >= 11.1.0" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi @@ -21979,8 +25699,8 @@ fi if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes @@ -21988,23 +25708,23 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - LIBGBM_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "gbm >= 9.0.0" 2>&1` + LIBGBM_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gbm >= 11.1.0" 2>&1` else - LIBGBM_PKG_ERRORS=`$PKG_CONFIG --print-errors "gbm >= 9.0.0" 2>&1` + LIBGBM_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gbm >= 11.1.0" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$LIBGBM_PKG_ERRORS" >&5 libgbm_avail=no elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } libgbm_avail=no else LIBGBM_CFLAGS=$pkg_cv_LIBGBM_CFLAGS LIBGBM_LIBS=$pkg_cv_LIBGBM_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } libgbm_avail=yes fi @@ -22014,54 +25734,53 @@ fi if test x$video_kmsdrm = xyes; then # Check whether --enable-kmsdrm-shared was given. -if test "${enable_kmsdrm_shared+set}" = set; then : +if test ${enable_kmsdrm_shared+y} +then : enableval=$enable_kmsdrm_shared; -else +else $as_nop enable_kmsdrm_shared=yes fi -$as_echo "#define SDL_VIDEO_DRIVER_KMSDRM 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_DRIVER_KMSDRM 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/video/kmsdrm/*.c" EXTRA_CFLAGS="$EXTRA_CFLAGS $LIBDRM_CFLAGS $LIBGBM_CFLAGS" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for kmsdrm dynamic loading support" >&5 -$as_echo_n "checking for kmsdrm dynamic loading support... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for kmsdrm dynamic loading support" >&5 +printf %s "checking for kmsdrm dynamic loading support... " >&6; } kmsdrm_shared=no - drm_lib=`find_lib "libdrm.so.*" "$DRM_LIBS"` - gbm_lib=`find_lib "libgbm.so.*" "$DRM_LIBS"` + drm_lib=`find_lib "libdrm.so.*" "$LIBDRM_LIBS"` + gbm_lib=`find_lib "libgbm.so.*" "$LIBGBM_LIBS"` if test x$have_loadso != xyes && \ test x$enable_kmsdrm_shared = xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: You must have SDL_LoadObject() support for dynamic kmsdrm loading" >&5 -$as_echo "$as_me: WARNING: You must have SDL_LoadObject() support for dynamic kmsdrm loading" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: You must have SDL_LoadObject() support for dynamic kmsdrm loading" >&5 +printf "%s\n" "$as_me: WARNING: You must have SDL_LoadObject() support for dynamic kmsdrm loading" >&2;} fi if test x$have_loadso = xyes && \ test x$enable_kmsdrm_shared = xyes && test x$drm_lib != x && test x$gbm_lib != x; then kmsdrm_shared=yes -cat >>confdefs.h <<_ACEOF -#define SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC "$drm_lib" -_ACEOF +printf "%s\n" "#define SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC \"$drm_lib\"" >>confdefs.h -cat >>confdefs.h <<_ACEOF -#define SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC_GBM "$gbm_lib" -_ACEOF +printf "%s\n" "#define SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC_GBM \"$gbm_lib\"" >>confdefs.h -cat >>confdefs.h <<_ACEOF -#define HAVE_KMSDRM_SHARED "TRUE" -_ACEOF +printf "%s\n" "#define HAVE_KMSDRM_SHARED \"TRUE\"" >>confdefs.h SUMMARY_video="${SUMMARY_video} kmsdrm(dynamic)" else EXTRA_LDFLAGS="$EXTRA_LDFLAGS $LIBDRM_LIBS $LIBGBM_LIBS" SUMMARY_video="${SUMMARY_video} kmsdrm" fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $kmsdrm_shared" >&5 -$as_echo "$kmsdrm_shared" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $kmsdrm_shared" >&5 +printf "%s\n" "$kmsdrm_shared" >&6; } + if test x$kmsdrm_shared = xyes; then + echo "-- dynamic libdrm -> $drm_lib" + echo "-- dynamic libgbm -> $gbm_lib" + fi have_video=yes fi fi @@ -22070,15 +25789,16 @@ $as_echo "$kmsdrm_shared" >&6; } CheckDummyVideo() { # Check whether --enable-video-dummy was given. -if test "${enable_video_dummy+set}" = set; then : +if test ${enable_video_dummy+y} +then : enableval=$enable_video_dummy; -else +else $as_nop enable_video_dummy=yes fi if test x$enable_video_dummy = xyes; then -$as_echo "#define SDL_VIDEO_DRIVER_DUMMY 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_DRIVER_DUMMY 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/video/dummy/*.c" have_video=yes @@ -22086,11 +25806,31 @@ $as_echo "#define SDL_VIDEO_DRIVER_DUMMY 1" >>confdefs.h fi } +CheckOffscreenVideo() +{ + # Check whether --enable-video-offscreen was given. +if test ${enable_video_offscreen+y} +then : + enableval=$enable_video_offscreen; +else $as_nop + enable_video_offscreen=yes +fi + + if test x$enable_video_offscreen = xyes; then + +printf "%s\n" "#define SDL_VIDEO_DRIVER_OFFSCREEN 1" >>confdefs.h + + SOURCES="$SOURCES $srcdir/src/video/offscreen/*.c" + have_video=yes + SUMMARY_video="${SUMMARY_video} offscreen" + fi +} + CheckQNXVideo() { if test x$enable_video = xyes; then -$as_echo "#define SDL_VIDEO_DRIVER_QNX 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_DRIVER_QNX 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/video/qnx/*.c" have_video=yes @@ -22103,7 +25843,7 @@ CheckQNXAudio() { if test x$enable_audio = xyes; then -$as_echo "#define SDL_AUDIO_DRIVER_QSA 1" >>confdefs.h +printf "%s\n" "#define SDL_AUDIO_DRIVER_QSA 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/audio/qsa/*.c" have_audio=yes @@ -22113,84 +25853,81 @@ $as_echo "#define SDL_AUDIO_DRIVER_QSA 1" >>confdefs.h } # Check whether --enable-video-opengl was given. -if test "${enable_video_opengl+set}" = set; then : +if test ${enable_video_opengl+y} +then : enableval=$enable_video_opengl; -else +else $as_nop enable_video_opengl=yes fi -CheckOpenGLX11() +CheckGLX() { if test x$enable_video = xyes -a x$enable_video_opengl = xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OpenGL (GLX) support" >&5 -$as_echo_n "checking for OpenGL (GLX) support... " >&6; } - video_opengl=no + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GLX support" >&5 +printf %s "checking for GLX support... " >&6; } + video_opengl_glx=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - #include #include int -main () +main (void) { - ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - video_opengl=yes - +if ac_fn_c_try_compile "$LINENO" +then : + video_opengl_glx=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $video_opengl" >&5 -$as_echo "$video_opengl" >&6; } - if test x$video_opengl = xyes; then +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $video_opengl_glx" >&5 +printf "%s\n" "$video_opengl_glx" >&6; } + if test x$video_opengl_glx = xyes; then -$as_echo "#define SDL_VIDEO_OPENGL 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_OPENGL 1" >>confdefs.h -$as_echo "#define SDL_VIDEO_OPENGL_GLX 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_OPENGL_GLX 1" >>confdefs.h - -$as_echo "#define SDL_VIDEO_RENDER_OGL 1" >>confdefs.h - - SUMMARY_video="${SUMMARY_video} opengl" fi fi } # Check whether --enable-video-opengles was given. -if test "${enable_video_opengles+set}" = set; then : +if test ${enable_video_opengles+y} +then : enableval=$enable_video_opengles; -else +else $as_nop enable_video_opengles=yes fi # Check whether --enable-video-opengles1 was given. -if test "${enable_video_opengles1+set}" = set; then : +if test ${enable_video_opengles1+y} +then : enableval=$enable_video_opengles1; -else +else $as_nop enable_video_opengles1=yes fi # Check whether --enable-video-opengles2 was given. -if test "${enable_video_opengles2+set}" = set; then : +if test ${enable_video_opengles2+y} +then : enableval=$enable_video_opengles2; -else +else $as_nop enable_video_opengles2=yes fi -CheckOpenGLESX11() +CheckEGL() { - if test x$enable_video = xyes -a x$enable_video_opengles = xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for EGL support" >&5 -$as_echo_n "checking for EGL support... " >&6; } + if test x$enable_video = xyes -a x$enable_video_opengl = xyes || test x$enable_video = xyes -a x$enable_video_opengles = xyes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for EGL support" >&5 +printf %s "checking for EGL support... " >&6; } video_opengl_egl=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -22198,35 +25935,78 @@ $as_echo_n "checking for EGL support... " >&6; } #define LINUX #define EGL_API_FB #define MESA_EGL_NO_X11_HEADERS + #define EGL_NO_X11 #include #include int -main () +main (void) { - ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - video_opengl_egl=yes - +if ac_fn_c_try_compile "$LINENO" +then : + video_opengl_egl=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $video_opengl_egl" >&5 -$as_echo "$video_opengl_egl" >&6; } +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $video_opengl_egl" >&5 +printf "%s\n" "$video_opengl_egl" >&6; } if test x$video_opengl_egl = xyes; then -$as_echo "#define SDL_VIDEO_OPENGL_EGL 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_OPENGL_EGL 1" >>confdefs.h fi + fi +} +CheckOpenGL() +{ + if test x$enable_video = xyes -a x$enable_video_opengl = xyes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for OpenGL headers" >&5 +printf %s "checking for OpenGL headers... " >&6; } + video_opengl=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + #include + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + video_opengl=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $video_opengl" >&5 +printf "%s\n" "$video_opengl" >&6; } + if test x$video_opengl = xyes; then + +printf "%s\n" "#define SDL_VIDEO_OPENGL 1" >>confdefs.h + + +printf "%s\n" "#define SDL_VIDEO_RENDER_OGL 1" >>confdefs.h + + SUMMARY_video="${SUMMARY_video} opengl" + fi + fi +} + +CheckOpenGLES() +{ + if test x$enable_video = xyes -a x$enable_video_opengles = xyes; then if test x$enable_video_opengles1 = xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OpenGL ES v1 headers" >&5 -$as_echo_n "checking for OpenGL ES v1 headers... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for OpenGL ES v1 headers" >&5 +printf %s "checking for OpenGL ES v1 headers... " >&6; } video_opengles_v1=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -22235,36 +26015,34 @@ $as_echo_n "checking for OpenGL ES v1 headers... " >&6; } #include int -main () +main (void) { - ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - video_opengles_v1=yes - +if ac_fn_c_try_compile "$LINENO" +then : + video_opengles_v1=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $video_opengles_v1" >&5 -$as_echo "$video_opengles_v1" >&6; } +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $video_opengles_v1" >&5 +printf "%s\n" "$video_opengles_v1" >&6; } if test x$video_opengles_v1 = xyes; then -$as_echo "#define SDL_VIDEO_OPENGL_ES 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_OPENGL_ES 1" >>confdefs.h -$as_echo "#define SDL_VIDEO_RENDER_OGL_ES 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_RENDER_OGL_ES 1" >>confdefs.h SUMMARY_video="${SUMMARY_video} opengl_es1" fi fi if test x$enable_video_opengles2 = xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OpenGL ES v2 headers" >&5 -$as_echo_n "checking for OpenGL ES v2 headers... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for OpenGL ES v2 headers" >&5 +printf %s "checking for OpenGL ES v2 headers... " >&6; } video_opengles_v2=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -22273,28 +26051,26 @@ $as_echo_n "checking for OpenGL ES v2 headers... " >&6; } #include int -main () +main (void) { - ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - video_opengles_v2=yes - +if ac_fn_c_try_compile "$LINENO" +then : + video_opengles_v2=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $video_opengles_v2" >&5 -$as_echo "$video_opengles_v2" >&6; } +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $video_opengles_v2" >&5 +printf "%s\n" "$video_opengles_v2" >&6; } if test x$video_opengles_v2 = xyes; then -$as_echo "#define SDL_VIDEO_OPENGL_ES2 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_OPENGL_ES2 1" >>confdefs.h -$as_echo "#define SDL_VIDEO_RENDER_OGL_ES2 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_RENDER_OGL_ES2 1" >>confdefs.h SUMMARY_video="${SUMMARY_video} opengl_es2" fi @@ -22306,13 +26082,13 @@ CheckWINDOWSGL() { if test x$enable_video = xyes -a x$enable_video_opengl = xyes; then -$as_echo "#define SDL_VIDEO_OPENGL 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_OPENGL 1" >>confdefs.h -$as_echo "#define SDL_VIDEO_OPENGL_WGL 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_OPENGL_WGL 1" >>confdefs.h -$as_echo "#define SDL_VIDEO_RENDER_OGL 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_RENDER_OGL 1" >>confdefs.h SUMMARY_video="${SUMMARY_video} opengl" fi @@ -22322,8 +26098,8 @@ CheckWINDOWSGLES() { if test x$enable_video = xyes -a x$enable_video_opengles = xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for EGL support" >&5 -$as_echo_n "checking for EGL support... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for EGL support" >&5 +printf %s "checking for EGL support... " >&6; } video_opengl_egl=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -22331,34 +26107,32 @@ $as_echo_n "checking for EGL support... " >&6; } #include int -main () +main (void) { - ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - video_opengl_egl=yes - +if ac_fn_c_try_compile "$LINENO" +then : + video_opengl_egl=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $video_opengl_egl" >&5 -$as_echo "$video_opengl_egl" >&6; } +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $video_opengl_egl" >&5 +printf "%s\n" "$video_opengl_egl" >&6; } if test x$video_opengl_egl = xyes; then -$as_echo "#define SDL_VIDEO_OPENGL 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_OPENGL 1" >>confdefs.h -$as_echo "#define SDL_VIDEO_OPENGL_EGL 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_OPENGL_EGL 1" >>confdefs.h SUMMARY_video="${SUMMARY_video} opengl_es1" fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OpenGL ES v2 headers" >&5 -$as_echo_n "checking for OpenGL ES v2 headers... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for OpenGL ES v2 headers" >&5 +printf %s "checking for OpenGL ES v2 headers... " >&6; } video_opengles_v2=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -22367,31 +26141,29 @@ $as_echo_n "checking for OpenGL ES v2 headers... " >&6; } #include int -main () +main (void) { - ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - video_opengles_v2=yes - +if ac_fn_c_try_compile "$LINENO" +then : + video_opengles_v2=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $video_opengles_v2" >&5 -$as_echo "$video_opengles_v2" >&6; } +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $video_opengles_v2" >&5 +printf "%s\n" "$video_opengles_v2" >&6; } if test x$video_opengles_v2 = xyes; then -$as_echo "#define SDL_VIDEO_OPENGL 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_OPENGL 1" >>confdefs.h -$as_echo "#define SDL_VIDEO_OPENGL_ES2 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_OPENGL_ES2 1" >>confdefs.h -$as_echo "#define SDL_VIDEO_RENDER_OGL_ES2 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_RENDER_OGL_ES2 1" >>confdefs.h SUMMARY_video="${SUMMARY_video} opengl_es2" fi @@ -22402,13 +26174,13 @@ CheckHaikuGL() { if test x$enable_video = xyes -a x$enable_video_opengl = xyes; then -$as_echo "#define SDL_VIDEO_OPENGL 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_OPENGL 1" >>confdefs.h -$as_echo "#define SDL_VIDEO_OPENGL_HAIKU 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_OPENGL_HAIKU 1" >>confdefs.h -$as_echo "#define SDL_VIDEO_RENDER_OGL 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_RENDER_OGL 1" >>confdefs.h EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lGL" SUMMARY_video="${SUMMARY_video} opengl" @@ -22419,13 +26191,13 @@ CheckMacGL() { if test x$enable_video = xyes -a x$enable_video_opengl = xyes; then -$as_echo "#define SDL_VIDEO_OPENGL 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_OPENGL 1" >>confdefs.h -$as_echo "#define SDL_VIDEO_OPENGL_CGL 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_OPENGL_CGL 1" >>confdefs.h -$as_echo "#define SDL_VIDEO_RENDER_OGL 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_RENDER_OGL 1" >>confdefs.h SUMMARY_video="${SUMMARY_video} opengl" fi @@ -22436,14 +26208,14 @@ CheckMacGLES() if test x$enable_video = xyes -a x$enable_video_opengles = xyes; then video_opengl_egl=yes -$as_echo "#define SDL_VIDEO_OPENGL_EGL 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_OPENGL_EGL 1" >>confdefs.h video_opengles_v2=yes -$as_echo "#define SDL_VIDEO_OPENGL_ES2 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_OPENGL_ES2 1" >>confdefs.h -$as_echo "#define SDL_VIDEO_RENDER_OGL_ES2 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_RENDER_OGL_ES2 1" >>confdefs.h SUMMARY_video="${SUMMARY_video} opengl_es2" fi @@ -22452,8 +26224,8 @@ $as_echo "#define SDL_VIDEO_RENDER_OGL_ES2 1" >>confdefs.h CheckEmscriptenGLES() { if test x$enable_video = xyes -a x$enable_video_opengles = xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for EGL support" >&5 -$as_echo_n "checking for EGL support... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for EGL support" >&5 +printf %s "checking for EGL support... " >&6; } video_opengl_egl=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -22461,30 +26233,28 @@ $as_echo_n "checking for EGL support... " >&6; } #include int -main () +main (void) { - ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - video_opengl_egl=yes - +if ac_fn_c_try_compile "$LINENO" +then : + video_opengl_egl=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $video_opengl_egl" >&5 -$as_echo "$video_opengl_egl" >&6; } +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $video_opengl_egl" >&5 +printf "%s\n" "$video_opengl_egl" >&6; } if test x$video_opengl_egl = xyes; then -$as_echo "#define SDL_VIDEO_OPENGL_EGL 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_OPENGL_EGL 1" >>confdefs.h fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OpenGL ES v2 headers" >&5 -$as_echo_n "checking for OpenGL ES v2 headers... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for OpenGL ES v2 headers" >&5 +printf %s "checking for OpenGL ES v2 headers... " >&6; } video_opengles_v2=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -22493,28 +26263,26 @@ $as_echo_n "checking for OpenGL ES v2 headers... " >&6; } #include int -main () +main (void) { - ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - video_opengles_v2=yes - +if ac_fn_c_try_compile "$LINENO" +then : + video_opengles_v2=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $video_opengles_v2" >&5 -$as_echo "$video_opengles_v2" >&6; } +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $video_opengles_v2" >&5 +printf "%s\n" "$video_opengles_v2" >&6; } if test x$video_opengles_v2 = xyes; then -$as_echo "#define SDL_VIDEO_OPENGL_ES2 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_OPENGL_ES2 1" >>confdefs.h -$as_echo "#define SDL_VIDEO_RENDER_OGL_ES2 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_RENDER_OGL_ES2 1" >>confdefs.h SUMMARY_video="${SUMMARY_video} opengl_es2" fi @@ -22522,9 +26290,10 @@ $as_echo "#define SDL_VIDEO_RENDER_OGL_ES2 1" >>confdefs.h } # Check whether --enable-video-vulkan was given. -if test "${enable_video_vulkan+set}" = set; then : +if test ${enable_video_vulkan+y} +then : enableval=$enable_video_vulkan; -else +else $as_nop enable_video_vulkan=yes fi @@ -22542,27 +26311,24 @@ CheckVulkan() #endif int -main () +main (void) { - ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - -else - - enable_video_vulkan=no +if ac_fn_c_try_compile "$LINENO" +then : +else $as_nop + enable_video_vulkan=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; *-*-darwin*) save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -x objective-c" + CFLAGS="$CFLAGS -x objective-c" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -22570,28 +26336,25 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include - #if !TARGET_CPU_X86_64 + #if TARGET_CPU_X86 #error Vulkan doesn't work on this configuration #endif int -main () +main (void) { - ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - -else - - enable_video_vulkan=no +if ac_fn_c_try_compile "$LINENO" +then : +else $as_nop + enable_video_vulkan=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext CFLAGS="$save_CFLAGS" ;; *) @@ -22600,13 +26363,18 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test x$enable_video_vulkan = xno; then # For reasons I am totally unable to see, I get an undefined macro error if # I put this in the AC_TRY_COMPILE. - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Vulkan does not work on this configuration." >&5 -$as_echo "$as_me: WARNING: Vulkan does not work on this configuration." >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Vulkan does not work on this configuration." >&5 +printf "%s\n" "$as_me: WARNING: Vulkan does not work on this configuration." >&2;} fi fi + if test x$have_loadso != xyes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Vulkan support is available, but disabled because there's no loadso." >&5 +printf "%s\n" "$as_me: WARNING: Vulkan support is available, but disabled because there's no loadso." >&2;} + enable_video_vulkan=no + fi if test x$enable_video_vulkan = xyes; then -$as_echo "#define SDL_VIDEO_VULKAN 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_VULKAN 1" >>confdefs.h SUMMARY_video="${SUMMARY_video} vulkan" fi @@ -22614,8 +26382,16 @@ $as_echo "#define SDL_VIDEO_VULKAN 1" >>confdefs.h CheckInputEvents() { - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Linux 2.4 unified input interface" >&5 -$as_echo_n "checking for Linux 2.4 unified input interface... " >&6; } + ac_fn_c_check_header_compile "$LINENO" "linux/input.h" "ac_cv_header_linux_input_h" "$ac_includes_default" +if test "x$ac_cv_header_linux_input_h" = xyes +then : + printf "%s\n" "#define HAVE_LINUX_INPUT_H 1" >>confdefs.h + +fi + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Linux 2.4 unified input interface" >&5 +printf %s "checking for Linux 2.4 unified input interface... " >&6; } use_input_events=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -22623,7 +26399,7 @@ $as_echo_n "checking for Linux 2.4 unified input interface... " >&6; } #include int -main () +main (void) { #ifndef EVIOCGNAME @@ -22634,17 +26410,16 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - use_input_events=yes - +if ac_fn_c_try_compile "$LINENO" +then : + use_input_events=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $use_input_events" >&5 -$as_echo "$use_input_events" >&6; } +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $use_input_events" >&5 +printf "%s\n" "$use_input_events" >&6; } if test x$use_input_events = xyes; then -$as_echo "#define SDL_INPUT_LINUXEV 1" >>confdefs.h +printf "%s\n" "#define SDL_INPUT_LINUXEV 1" >>confdefs.h SUMMARY_input="${SUMMARY_input} linuxev" fi @@ -22652,18 +26427,18 @@ $as_echo "#define SDL_INPUT_LINUXEV 1" >>confdefs.h CheckInputKD() { - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Linux kd.h" >&5 -$as_echo_n "checking for Linux kd.h... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Linux kd.h" >&5 +printf %s "checking for Linux kd.h... " >&6; } use_input_kd=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include + #include int -main () +main (void) { struct kbentry kbe; @@ -22674,52 +26449,127 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - use_input_kd=yes - +if ac_fn_c_try_compile "$LINENO" +then : + use_input_kd=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $use_input_kd" >&5 -$as_echo "$use_input_kd" >&6; } +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $use_input_kd" >&5 +printf "%s\n" "$use_input_kd" >&6; } if test x$use_input_kd = xyes; then -$as_echo "#define SDL_INPUT_LINUXKD 1" >>confdefs.h +printf "%s\n" "#define SDL_INPUT_LINUXKD 1" >>confdefs.h SUMMARY_input="${SUMMARY_input} linuxkd" fi } +CheckInputKBIO() +{ + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for FreeBSD kbio.h" >&5 +printf %s "checking for FreeBSD kbio.h... " >&6; } + use_input_kbio=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + #include + +int +main (void) +{ + + accentmap_t accTable; + ioctl(0, KDENABIO, 1); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + use_input_kbio=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $use_input_kbio" >&5 +printf "%s\n" "$use_input_kbio" >&6; } + if test x$use_input_kbio = xyes; then + +printf "%s\n" "#define SDL_INPUT_FBSDKBIO 1" >>confdefs.h + + SUMMARY_input="${SUMMARY_input} fbsdkbio" + fi +} + +CheckInputWSCONS() +{ + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for OpenBSD wscons" >&5 +printf %s "checking for OpenBSD wscons... " >&6; } + use_input_wscons=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + #include + #include + #include + #include + +int +main (void) +{ + + struct wskbd_map_data data; + ioctl(0, WSKBDIO_GETMAP, &data); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + use_input_wscons=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $use_input_wscons" >&5 +printf "%s\n" "$use_input_wscons" >&6; } + if test x$use_input_wscons = xyes; then + +printf "%s\n" "#define SDL_INPUT_WSCONS 1" >>confdefs.h + + SUMMARY_input="${SUMMARY_input} wscons" + fi +} + CheckLibUDev() { # Check whether --enable-libudev was given. -if test "${enable_libudev+set}" = set; then : +if test ${enable_libudev+y} +then : enableval=$enable_libudev; -else +else $as_nop enable_libudev=yes fi if test x$enable_libudev = xyes; then - ac_fn_c_check_header_mongrel "$LINENO" "libudev.h" "ac_cv_header_libudev_h" "$ac_includes_default" -if test "x$ac_cv_header_libudev_h" = xyes; then : + ac_fn_c_check_header_compile "$LINENO" "libudev.h" "ac_cv_header_libudev_h" "$ac_includes_default" +if test "x$ac_cv_header_libudev_h" = xyes +then : have_libudev_h_hdr=yes -else +else $as_nop have_libudev_h_hdr=no fi - if test x$have_libudev_h_hdr = xyes; then -$as_echo "#define HAVE_LIBUDEV_H 1" >>confdefs.h +printf "%s\n" "#define HAVE_LIBUDEV_H 1" >>confdefs.h udev_lib=`find_lib "libudev.so.*" "" | sed 's/.*\/\(.*\)/\1/; q'` if test x$udev_lib != x; then echo "-- dynamic udev -> $udev_lib" -cat >>confdefs.h <<_ACEOF -#define SDL_UDEV_DYNAMIC "$udev_lib" -_ACEOF +printf "%s\n" "#define SDL_UDEV_DYNAMIC \"$udev_lib\"" >>confdefs.h fi fi @@ -22729,28 +26579,30 @@ _ACEOF CheckDBus() { # Check whether --enable-dbus was given. -if test "${enable_dbus+set}" = set; then : +if test ${enable_dbus+y} +then : enableval=$enable_dbus; -else +else $as_nop enable_dbus=yes fi if test x$enable_dbus = xyes; then pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for DBUS" >&5 -$as_echo_n "checking for DBUS... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dbus-1" >&5 +printf %s "checking for dbus-1... " >&6; } if test -n "$DBUS_CFLAGS"; then pkg_cv_DBUS_CFLAGS="$DBUS_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"dbus-1\""; } >&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"dbus-1\""; } >&5 ($PKG_CONFIG --exists --print-errors "dbus-1") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_DBUS_CFLAGS=`$PKG_CONFIG --cflags "dbus-1" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi @@ -22761,12 +26613,13 @@ if test -n "$DBUS_LIBS"; then pkg_cv_DBUS_LIBS="$DBUS_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"dbus-1\""; } >&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"dbus-1\""; } >&5 ($PKG_CONFIG --exists --print-errors "dbus-1") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_DBUS_LIBS=`$PKG_CONFIG --libs "dbus-1" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi @@ -22777,8 +26630,8 @@ fi if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes @@ -22786,39 +26639,39 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - DBUS_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "dbus-1" 2>&1` + DBUS_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "dbus-1" 2>&1` else - DBUS_PKG_ERRORS=`$PKG_CONFIG --print-errors "dbus-1" 2>&1` + DBUS_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "dbus-1" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$DBUS_PKG_ERRORS" >&5 have_dbus=no elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } have_dbus=no else DBUS_CFLAGS=$pkg_cv_DBUS_CFLAGS DBUS_LIBS=$pkg_cv_DBUS_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } have_dbus=yes fi - save_CFLAGS="$CFLAGS" - CFLAGS="$save_CFLAGS $DBUS_CFLAGS" - ac_fn_c_check_header_mongrel "$LINENO" "dbus/dbus.h" "ac_cv_header_dbus_dbus_h" "$ac_includes_default" -if test "x$ac_cv_header_dbus_dbus_h" = xyes; then : + save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$save_CPPFLAGS $DBUS_CFLAGS" + ac_fn_c_check_header_compile "$LINENO" "dbus/dbus.h" "ac_cv_header_dbus_dbus_h" "$ac_includes_default" +if test "x$ac_cv_header_dbus_dbus_h" = xyes +then : have_dbus_dbus_h_hdr=yes -else +else $as_nop have_dbus_dbus_h_hdr=no fi - - CFLAGS="$save_CFLAGS" + CPPFLAGS="$save_CPPFLAGS" if test x$have_dbus_dbus_h_hdr = xyes; then -$as_echo "#define HAVE_DBUS_DBUS_H 1" >>confdefs.h +printf "%s\n" "#define HAVE_DBUS_DBUS_H 1" >>confdefs.h EXTRA_CFLAGS="$EXTRA_CFLAGS $DBUS_CFLAGS" SOURCES="$SOURCES $srcdir/src/core/linux/SDL_dbus.c" @@ -22829,45 +26682,96 @@ $as_echo "#define HAVE_DBUS_DBUS_H 1" >>confdefs.h CheckIME() { # Check whether --enable-ime was given. -if test "${enable_ime+set}" = set; then : +if test ${enable_ime+y} +then : enableval=$enable_ime; -else +else $as_nop enable_ime=yes fi if test x$enable_ime = xyes; then -$as_echo "#define SDL_USE_IME 1" >>confdefs.h +printf "%s\n" "#define SDL_USE_IME 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/core/linux/SDL_ime.c" fi } +CheckInotify() +{ + save_LIBS="$LIBS" + case "$host" in + *-*-freebsd*|*-*dragonfly*) LIBS="$LIBS -linotify" + ;; + esac + for ac_header in sys/inotify.h +do : + ac_fn_c_check_header_compile "$LINENO" "sys/inotify.h" "ac_cv_header_sys_inotify_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_inotify_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_INOTIFY_H 1" >>confdefs.h + have_inotify_inotify_h_hdr=yes +fi + +done + + for ac_func in inotify_init +do : + ac_fn_c_check_func "$LINENO" "inotify_init" "ac_cv_func_inotify_init" +if test "x$ac_cv_func_inotify_init" = xyes +then : + printf "%s\n" "#define HAVE_INOTIFY_INIT 1" >>confdefs.h + have_inotify=yes +fi + +done + ac_fn_c_check_func "$LINENO" "inotify_init1" "ac_cv_func_inotify_init1" +if test "x$ac_cv_func_inotify_init1" = xyes +then : + printf "%s\n" "#define HAVE_INOTIFY_INIT1 1" >>confdefs.h + +fi + + if test x$have_inotify_inotify_h_hdr = xyes -a x$have_inotify = xyes; then + +printf "%s\n" "#define HAVE_INOTIFY 1" >>confdefs.h + + case "$host" in + *-*-freebsd*|*-*-dragonfly*) + EXTRA_LDFLAGS="$EXTRA_LDFLAGS -linotify" + ;; + esac + fi + LIBS="$save_LIBS" +} + CheckIBus() { # Check whether --enable-ibus was given. -if test "${enable_ibus+set}" = set; then : +if test ${enable_ibus+y} +then : enableval=$enable_ibus; -else +else $as_nop enable_ibus=yes fi if test x$enable_ibus = xyes; then pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for IBUS" >&5 -$as_echo_n "checking for IBUS... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ibus-1.0" >&5 +printf %s "checking for ibus-1.0... " >&6; } if test -n "$IBUS_CFLAGS"; then pkg_cv_IBUS_CFLAGS="$IBUS_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ibus-1.0\""; } >&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ibus-1.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "ibus-1.0") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_IBUS_CFLAGS=`$PKG_CONFIG --cflags "ibus-1.0" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi @@ -22878,12 +26782,13 @@ if test -n "$IBUS_LIBS"; then pkg_cv_IBUS_LIBS="$IBUS_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ibus-1.0\""; } >&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ibus-1.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "ibus-1.0") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_IBUS_LIBS=`$PKG_CONFIG --libs "ibus-1.0" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi @@ -22894,8 +26799,8 @@ fi if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes @@ -22903,60 +26808,52 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - IBUS_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "ibus-1.0" 2>&1` + IBUS_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "ibus-1.0" 2>&1` else - IBUS_PKG_ERRORS=`$PKG_CONFIG --print-errors "ibus-1.0" 2>&1` + IBUS_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "ibus-1.0" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$IBUS_PKG_ERRORS" >&5 have_ibus=no elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } have_ibus=no else IBUS_CFLAGS=$pkg_cv_IBUS_CFLAGS IBUS_LIBS=$pkg_cv_IBUS_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } have_ibus=yes fi - save_CFLAGS="$CFLAGS" - CFLAGS="$save_CFLAGS $IBUS_CFLAGS" - ac_fn_c_check_header_mongrel "$LINENO" "ibus-1.0/ibus.h" "ac_cv_header_ibus_1_0_ibus_h" "$ac_includes_default" -if test "x$ac_cv_header_ibus_1_0_ibus_h" = xyes; then : + save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$save_CPPFLAGS $IBUS_CFLAGS" + ac_fn_c_check_header_compile "$LINENO" "ibus-1.0/ibus.h" "ac_cv_header_ibus_1_0_ibus_h" "$ac_includes_default" +if test "x$ac_cv_header_ibus_1_0_ibus_h" = xyes +then : have_ibus_ibus_h_hdr=yes -else +else $as_nop have_ibus_ibus_h_hdr=no fi - - ac_fn_c_check_header_mongrel "$LINENO" "sys/inotify.h" "ac_cv_header_sys_inotify_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_inotify_h" = xyes; then : - have_inotify_inotify_h_hdr=yes -else - have_inotify_inotify_h_hdr=no -fi - - - CFLAGS="$save_CFLAGS" + CPPFLAGS="$save_CPPFLAGS" if test x$have_ibus_ibus_h_hdr = xyes; then if test x$enable_ime != xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: IME support is required for IBus." >&5 -$as_echo "$as_me: WARNING: IME support is required for IBus." >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: IME support is required for IBus." >&5 +printf "%s\n" "$as_me: WARNING: IME support is required for IBus." >&2;} have_ibus_ibus_h_hdr=no elif test x$enable_dbus != xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: DBus support is required for IBus." >&5 -$as_echo "$as_me: WARNING: DBus support is required for IBus." >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: DBus support is required for IBus." >&5 +printf "%s\n" "$as_me: WARNING: DBus support is required for IBus." >&2;} have_ibus_ibus_h_hdr=no elif test x$have_inotify_inotify_h_hdr != xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: INotify support is required for IBus." >&5 -$as_echo "$as_me: WARNING: INotify support is required for IBus." >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: INotify support is required for IBus." >&5 +printf "%s\n" "$as_me: WARNING: INotify support is required for IBus." >&2;} have_ibus_ibus_h_hdr=no else -$as_echo "#define HAVE_IBUS_IBUS_H 1" >>confdefs.h +printf "%s\n" "#define HAVE_IBUS_IBUS_H 1" >>confdefs.h EXTRA_CFLAGS="$EXTRA_CFLAGS $IBUS_CFLAGS" SOURCES="$SOURCES $srcdir/src/core/linux/SDL_ibus.c" @@ -22968,173 +26865,134 @@ $as_echo "#define HAVE_IBUS_IBUS_H 1" >>confdefs.h CheckFcitx() { # Check whether --enable-fcitx was given. -if test "${enable_fcitx+set}" = set; then : +if test ${enable_fcitx+y} +then : enableval=$enable_fcitx; -else +else $as_nop enable_fcitx=yes fi if test x$enable_fcitx = xyes; then - -pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for FCITX" >&5 -$as_echo_n "checking for FCITX... " >&6; } - -if test -n "$FCITX_CFLAGS"; then - pkg_cv_FCITX_CFLAGS="$FCITX_CFLAGS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"fcitx\""; } >&5 - ($PKG_CONFIG --exists --print-errors "fcitx") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_FCITX_CFLAGS=`$PKG_CONFIG --cflags "fcitx" 2>/dev/null` -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi -if test -n "$FCITX_LIBS"; then - pkg_cv_FCITX_LIBS="$FCITX_LIBS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"fcitx\""; } >&5 - ($PKG_CONFIG --exists --print-errors "fcitx") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_FCITX_LIBS=`$PKG_CONFIG --libs "fcitx" 2>/dev/null` -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi - - - -if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi - if test $_pkg_short_errors_supported = yes; then - FCITX_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "fcitx" 2>&1` + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for fcitx support" >&5 +printf %s "checking for fcitx support... " >&6; } + have_fcitx=no + if test x$enable_ime != xyes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: IME support is required for fcitx." >&5 +printf "%s\n" "$as_me: WARNING: IME support is required for fcitx." >&2;} + elif test x$have_dbus_dbus_h_hdr != xyes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: DBus support is required for fcitx." >&5 +printf "%s\n" "$as_me: WARNING: DBus support is required for fcitx." >&2;} else - FCITX_PKG_ERRORS=`$PKG_CONFIG --print-errors "fcitx" 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$FCITX_PKG_ERRORS" >&5 - - have_fcitx=no -elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - have_fcitx=no -else - FCITX_CFLAGS=$pkg_cv_FCITX_CFLAGS - FCITX_LIBS=$pkg_cv_FCITX_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - have_fcitx=yes -fi - CFLAGS="$CFLAGS $FCITX_CFLAGS" - ac_fn_c_check_header_mongrel "$LINENO" "fcitx/frontend.h" "ac_cv_header_fcitx_frontend_h" "$ac_includes_default" -if test "x$ac_cv_header_fcitx_frontend_h" = xyes; then : - have_fcitx_frontend_h_hdr=yes -else - have_fcitx_frontend_h_hdr=no -fi - - - CFLAGS="$save_CFLAGS" - if test x$have_fcitx_frontend_h_hdr = xyes; then - if test x$enable_ime != xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: IME support is required for fcitx." >&5 -$as_echo "$as_me: WARNING: IME support is required for fcitx." >&2;} - have_fcitx_frontend_h_hdr=no - elif test x$enable_dbus != xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: DBus support is required for fcitx." >&5 -$as_echo "$as_me: WARNING: DBus support is required for fcitx." >&2;} - have_fcitx_frontend_h_hdr=no - else - -$as_echo "#define HAVE_FCITX_FRONTEND_H 1" >>confdefs.h - - EXTRA_CFLAGS="$EXTRA_CFLAGS $FCITX_CFLAGS" - SOURCES="$SOURCES $srcdir/src/core/linux/SDL_fcitx.c" - fi + have_fcitx=yes + +printf "%s\n" "#define HAVE_FCITX 1" >>confdefs.h + + SOURCES="$SOURCES $srcdir/src/core/linux/SDL_fcitx.c" fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_fcitx" >&5 +printf "%s\n" "$have_fcitx" >&6; } fi } -CheckTslib() +CheckJoystickMFI() { - # Check whether --enable-input-tslib was given. -if test "${enable_input_tslib+set}" = set; then : - enableval=$enable_input_tslib; -else - enable_input_tslib=yes + # Check whether --enable-joystick-mfi was given. +if test ${enable_joystick_mfi+y} +then : + enableval=$enable_joystick_mfi; +else $as_nop + enable_joystick_mfi=yes fi - if test x$enable_input_tslib = xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Touchscreen library support" >&5 -$as_echo_n "checking for Touchscreen library support... " >&6; } - enable_input_tslib=no + + if test x$enable_joystick_mfi = xyes; then + save_CFLAGS="$CFLAGS" + save_LDFLAGS="$LDFLAGS" + CFLAGS="$CFLAGS -x objective-c -fobjc-weak" + LDFLAGS="$LDFLAGS -Wl,-weak_framework,CoreHaptics -Wl,-weak_framework,GameController" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GameController framework" >&5 +printf %s "checking for GameController framework... " >&6; } + enable_joystick_mfi=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - #include "tslib.h" + #include + #include + #import int -main () +main (void) { + #if MAC_OS_X_VERSION_MIN_REQUIRED < 1080 + #error GameController framework doesn't work on this configuration + #endif + #if TARGET_CPU_X86 + #error GameController framework doesn't work on this configuration + #endif ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - enable_input_tslib=yes - +if ac_fn_c_try_link "$LINENO" +then : + enable_joystick_mfi=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_input_tslib" >&5 -$as_echo "$enable_input_tslib" >&6; } - if test x$enable_input_tslib = xyes; then +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + CFLAGS="$save_CFLAGS" + LDFLAGS="$save_LDFLAGS" -$as_echo "#define SDL_INPUT_TSLIB 1" >>confdefs.h + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_joystick_mfi" >&5 +printf "%s\n" "$enable_joystick_mfi" >&6; } + if test x$enable_joystick_mfi = xyes; then - EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lts" - SUMMARY_input="${SUMMARY_input} ts" +printf "%s\n" "#define SDL_JOYSTICK_MFI 1" >>confdefs.h + + EXTRA_CFLAGS="$EXTRA_CFLAGS -fobjc-weak -Wno-unused-command-line-argument" + EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-weak_framework,CoreHaptics -Wl,-weak_framework,GameController" fi fi } CheckPTHREAD() { - # Check whether --enable-pthreads was given. -if test "${enable_pthreads+set}" = set; then : + + + case "$host" in + *-*-emscripten*) + enable_pthreads_default=no + ;; + *) + enable_pthreads_default=yes + ;; + esac + + # Check whether --enable-pthreads was given. +if test ${enable_pthreads+y} +then : enableval=$enable_pthreads; -else - enable_pthreads=yes +else $as_nop + enable_pthreads=maybe fi - # Check whether --enable-pthread-sem was given. -if test "${enable_pthread_sem+set}" = set; then : + # Check whether --enable-pthread-sem was given. +if test ${enable_pthread_sem+y} +then : enableval=$enable_pthread_sem; -else - enable_pthread_sem=yes +else $as_nop + enable_pthread_sem=maybe fi + + if test x$enable_pthreads = xmaybe; then + enable_pthreads=$enable_pthreads_default + fi + if test x$enable_pthread_sem = xmaybe; then + enable_pthread_sem=$enable_pthreads + fi + case "$host" in *-*-android*) pthread_cflags="-D_REENTRANT -D_THREAD_SAFE" @@ -23163,7 +27021,7 @@ fi ;; *-*-openbsd*) pthread_cflags="-D_REENTRANT" - pthread_lib="-pthread" + pthread_lib="-lpthread" ;; *-*-solaris2.9) # From Solaris 9+, posix4's preferred name is rt. @@ -23200,6 +27058,10 @@ fi pthread_cflags="-D_REENTRANT" pthread_lib="" ;; + *-*-emscripten*) + pthread_cflags="-D_REENTRANT -pthread" + pthread_lib="-pthread" + ;; *) pthread_cflags="-D_REENTRANT" pthread_lib="-lpthread" @@ -23211,8 +27073,8 @@ fi # Add the pthread compiler flags and libraries CFLAGS="$CFLAGS $pthread_cflags"; LIBS="$LIBS $pthread_lib" # Check to see if we have pthread support on this system - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthreads" >&5 -$as_echo_n "checking for pthreads... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pthreads" >&5 +printf %s "checking for pthreads... " >&6; } use_pthreads=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -23220,7 +27082,7 @@ $as_echo_n "checking for pthreads... " >&6; } #include int -main () +main (void) { pthread_attr_t type; @@ -23230,22 +27092,21 @@ main () return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - - use_pthreads=yes - +if ac_fn_c_try_link "$LINENO" +then : + use_pthreads=yes fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $use_pthreads" >&5 -$as_echo "$use_pthreads" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $use_pthreads" >&5 +printf "%s\n" "$use_pthreads" >&6; } # Restore the compiler flags and libraries CFLAGS="$ac_save_cflags"; LIBS="$ac_save_libs" # Do futher testing if we have pthread support... if test x$use_pthreads = xyes; then -$as_echo "#define SDL_THREAD_PTHREAD 1" >>confdefs.h +printf "%s\n" "#define SDL_THREAD_PTHREAD 1" >>confdefs.h EXTRA_CFLAGS="$EXTRA_CFLAGS $pthread_cflags" EXTRA_LDFLAGS="$EXTRA_LDFLAGS $pthread_lib" @@ -23257,8 +27118,8 @@ $as_echo "#define SDL_THREAD_PTHREAD 1" >>confdefs.h CFLAGS="$CFLAGS $pthread_cflags"; LIBS="$LIBS $pthread_lib" # Check to see if recursive mutexes are available - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for recursive mutexes" >&5 -$as_echo_n "checking for recursive mutexes... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for recursive mutexes" >&5 +printf %s "checking for recursive mutexes... " >&6; } has_recursive_mutexes=no if test x$has_recursive_mutexes = xno; then cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -23268,7 +27129,7 @@ $as_echo_n "checking for recursive mutexes... " >&6; } #include int -main () +main (void) { pthread_mutexattr_t attr; @@ -23278,15 +27139,16 @@ main () return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : has_recursive_mutexes=yes -$as_echo "#define SDL_THREAD_PTHREAD_RECURSIVE_MUTEX 1" >>confdefs.h +printf "%s\n" "#define SDL_THREAD_PTHREAD_RECURSIVE_MUTEX 1" >>confdefs.h fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi if test x$has_recursive_mutexes = xno; then @@ -23297,7 +27159,7 @@ rm -f core conftest.err conftest.$ac_objext \ #include int -main () +main (void) { pthread_mutexattr_t attr; @@ -23307,24 +27169,25 @@ main () return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : has_recursive_mutexes=yes -$as_echo "#define SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP 1" >>confdefs.h +printf "%s\n" "#define SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP 1" >>confdefs.h fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $has_recursive_mutexes" >&5 -$as_echo "$has_recursive_mutexes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $has_recursive_mutexes" >&5 +printf "%s\n" "$has_recursive_mutexes" >&6; } # Check to see if pthread semaphore support is missing if test x$enable_pthread_sem = xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread semaphores" >&5 -$as_echo_n "checking for pthread semaphores... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pthread semaphores" >&5 +printf %s "checking for pthread semaphores... " >&6; } have_pthread_sem=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -23333,26 +27196,24 @@ $as_echo_n "checking for pthread semaphores... " >&6; } #include int -main () +main (void) { - ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - have_pthread_sem=yes - +if ac_fn_c_try_compile "$LINENO" +then : + have_pthread_sem=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_pthread_sem" >&5 -$as_echo "$have_pthread_sem" >&6; } +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_pthread_sem" >&5 +printf "%s\n" "$have_pthread_sem" >&6; } fi if test x$have_pthread_sem = xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sem_timedwait" >&5 -$as_echo_n "checking for sem_timedwait... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sem_timedwait" >&5 +printf %s "checking for sem_timedwait... " >&6; } have_sem_timedwait=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -23361,7 +27222,7 @@ $as_echo_n "checking for sem_timedwait... " >&6; } #include int -main () +main (void) { sem_timedwait(NULL, NULL); @@ -23370,109 +27231,106 @@ main () return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : have_sem_timedwait=yes -$as_echo "#define HAVE_SEM_TIMEDWAIT 1" >>confdefs.h +printf "%s\n" "#define HAVE_SEM_TIMEDWAIT 1" >>confdefs.h fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_sem_timedwait" >&5 -$as_echo "$have_sem_timedwait" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_sem_timedwait" >&5 +printf "%s\n" "$have_sem_timedwait" >&6; } fi ac_fn_c_check_header_compile "$LINENO" "pthread_np.h" "ac_cv_header_pthread_np_h" " #include " -if test "x$ac_cv_header_pthread_np_h" = xyes; then : +if test "x$ac_cv_header_pthread_np_h" = xyes +then : have_pthread_np_h=yes -else +else $as_nop have_pthread_np_h=no fi - if test x$have_pthread_np_h = xyes; then -$as_echo "#define HAVE_PTHREAD_NP_H 1" >>confdefs.h +printf "%s\n" "#define HAVE_PTHREAD_NP_H 1" >>confdefs.h fi # Check to see if pthread naming is available - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_setname_np" >&5 -$as_echo_n "checking for pthread_setname_np... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pthread_setname_np" >&5 +printf %s "checking for pthread_setname_np... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char pthread_setname_np (); int -main () +main (void) { return pthread_setname_np (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : has_pthread_setname_np=yes -$as_echo "#define HAVE_PTHREAD_SETNAME_NP 1" >>confdefs.h +printf "%s\n" "#define HAVE_PTHREAD_SETNAME_NP 1" >>confdefs.h -else +else $as_nop has_pthread_setname_np=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $has_pthread_setname_np" >&5 -$as_echo "$has_pthread_setname_np" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $has_pthread_setname_np" >&5 +printf "%s\n" "$has_pthread_setname_np" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_set_name_np" >&5 -$as_echo_n "checking for pthread_set_name_np... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pthread_set_name_np" >&5 +printf %s "checking for pthread_set_name_np... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char pthread_set_name_np (); int -main () +main (void) { return pthread_set_name_np (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : has_pthread_set_name_np=yes -$as_echo "#define HAVE_PTHREAD_SET_NAME_NP 1" >>confdefs.h +printf "%s\n" "#define HAVE_PTHREAD_SET_NAME_NP 1" >>confdefs.h -else +else $as_nop has_pthread_set_name_np=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $has_pthread_set_name_np" >&5 -$as_echo "$has_pthread_set_name_np" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $has_pthread_set_name_np" >&5 +printf "%s\n" "$has_pthread_set_name_np" >&6; } # Restore the compiler flags and libraries CFLAGS="$ac_save_cflags"; LIBS="$ac_save_libs" @@ -23506,8 +27364,8 @@ $as_echo "$has_pthread_set_name_np" >&6; } CheckWINDOWS() { - { $as_echo "$as_me:${as_lineno-$LINENO}: checking Windows compiler" >&5 -$as_echo_n "checking Windows compiler... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking Windows compiler" >&5 +printf %s "checking Windows compiler... " >&6; } have_win32_gcc=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -23515,30 +27373,28 @@ $as_echo_n "checking Windows compiler... " >&6; } #include int -main () +main (void) { - ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - have_win32_gcc=yes - +if ac_fn_c_try_compile "$LINENO" +then : + have_win32_gcc=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_win32_gcc" >&5 -$as_echo "$have_win32_gcc" >&6; } +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_win32_gcc" >&5 +printf "%s\n" "$have_win32_gcc" >&6; } if test x$have_win32_gcc != xyes; then as_fn_error $? " *** Your compiler ($CC) does not produce Windows executables! " "$LINENO" 5 fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking Windows CE" >&5 -$as_echo_n "checking Windows CE... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking Windows CE" >&5 +printf %s "checking Windows CE... " >&6; } have_wince=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -23548,15 +27404,15 @@ $as_echo_n "checking Windows CE... " >&6; } #endif int -main () +main (void) { - ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : have_wince=yes as_fn_error $? " @@ -23564,138 +27420,169 @@ if ac_fn_c_try_compile "$LINENO"; then : " "$LINENO" 5 fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_wince" >&5 -$as_echo "$have_wince" >&6; } +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_wince" >&5 +printf "%s\n" "$have_wince" >&6; } - # This fixes Windows stack alignment with newer GCC - CheckStackBoundary + # headers needed elsewhere + ac_fn_c_check_header_compile "$LINENO" "tpcshrd.h" "ac_cv_header_tpcshrd_h" "$ac_includes_default" +if test "x$ac_cv_header_tpcshrd_h" = xyes +then : + have_tpcshrd_h=yes +fi + + if test x$have_tpcshrd_h = xyes; then + +printf "%s\n" "#define HAVE_TPCSHRD_H 1" >>confdefs.h + + fi + ac_fn_c_check_header_compile "$LINENO" "roapi.h" "ac_cv_header_roapi_h" "$ac_includes_default" +if test "x$ac_cv_header_roapi_h" = xyes +then : + have_roapi_h=yes +fi + + if test x$have_roapi_h = xyes; then + +printf "%s\n" "#define HAVE_ROAPI_H 1" >>confdefs.h + + fi + ac_fn_c_check_header_compile "$LINENO" "shellscalingapi.h" "ac_cv_header_shellscalingapi_h" "$ac_includes_default" +if test "x$ac_cv_header_shellscalingapi_h" = xyes +then : + have_shellscalingapi_h=yes +fi + + if test x$shellscalingapi_h = xyes; then + +printf "%s\n" "#define HAVE_SHELLSCALINGAPI_H 1" >>confdefs.h + + fi +} + +CheckOS2() +{ + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking OS/2 compiler" >&5 +printf %s "checking OS/2 compiler... " >&6; } + have_os2_gcc=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + have_os2_gcc=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_os2_gcc" >&5 +printf "%s\n" "$have_os2_gcc" >&6; } + if test x$have_os2_gcc != xyes; then + as_fn_error $? " +*** Your compiler ($CC) does not produce OS/2 executables! + " "$LINENO" 5 + fi } CheckDIRECTX() { # Check whether --enable-directx was given. -if test "${enable_directx+set}" = set; then : +if test ${enable_directx+y} +then : enableval=$enable_directx; -else +else $as_nop enable_directx=yes fi if test x$enable_directx = xyes; then - ac_fn_c_check_header_mongrel "$LINENO" "d3d9.h" "ac_cv_header_d3d9_h" "$ac_includes_default" -if test "x$ac_cv_header_d3d9_h" = xyes; then : + ac_fn_c_check_header_compile "$LINENO" "d3d9.h" "ac_cv_header_d3d9_h" "$ac_includes_default" +if test "x$ac_cv_header_d3d9_h" = xyes +then : have_d3d=yes fi - - ac_fn_c_check_header_mongrel "$LINENO" "d3d11_1.h" "ac_cv_header_d3d11_1_h" "$ac_includes_default" -if test "x$ac_cv_header_d3d11_1_h" = xyes; then : + ac_fn_c_check_header_compile "$LINENO" "d3d11_1.h" "ac_cv_header_d3d11_1_h" "$ac_includes_default" +if test "x$ac_cv_header_d3d11_1_h" = xyes +then : have_d3d11=yes fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for compatible d3d12 headers" >&5 +printf %s "checking for compatible d3d12 headers... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ - ac_fn_c_check_header_mongrel "$LINENO" "ddraw.h" "ac_cv_header_ddraw_h" "$ac_includes_default" -if test "x$ac_cv_header_ddraw_h" = xyes; then : +#include +#include +ID3D12Device1 *device; + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + have_d3d12=yes +else $as_nop + have_d3d12=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_d3d12" >&5 +printf "%s\n" "$have_d3d12" >&6; } + + ac_fn_c_check_header_compile "$LINENO" "ddraw.h" "ac_cv_header_ddraw_h" "$ac_includes_default" +if test "x$ac_cv_header_ddraw_h" = xyes +then : have_ddraw=yes fi - - ac_fn_c_check_header_mongrel "$LINENO" "dsound.h" "ac_cv_header_dsound_h" "$ac_includes_default" -if test "x$ac_cv_header_dsound_h" = xyes; then : + ac_fn_c_check_header_compile "$LINENO" "dsound.h" "ac_cv_header_dsound_h" "$ac_includes_default" +if test "x$ac_cv_header_dsound_h" = xyes +then : have_dsound=yes fi - - ac_fn_c_check_header_mongrel "$LINENO" "dinput.h" "ac_cv_header_dinput_h" "$ac_includes_default" -if test "x$ac_cv_header_dinput_h" = xyes; then : + ac_fn_c_check_header_compile "$LINENO" "dinput.h" "ac_cv_header_dinput_h" "$ac_includes_default" +if test "x$ac_cv_header_dinput_h" = xyes +then : have_dinput=yes fi - - ac_fn_c_check_header_mongrel "$LINENO" "dxgi.h" "ac_cv_header_dxgi_h" "$ac_includes_default" -if test "x$ac_cv_header_dxgi_h" = xyes; then : + ac_fn_c_check_header_compile "$LINENO" "dxgi.h" "ac_cv_header_dxgi_h" "$ac_includes_default" +if test "x$ac_cv_header_dxgi_h" = xyes +then : have_dxgi=yes fi - ac_fn_c_check_header_mongrel "$LINENO" "xinput.h" "ac_cv_header_xinput_h" "$ac_includes_default" -if test "x$ac_cv_header_xinput_h" = xyes; then : - have_xinput=yes -fi - - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#include -#include -XINPUT_GAMEPAD_EX x1; - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - have_xinput_gamepadex=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#include -#include -XINPUT_STATE_EX s1; - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - have_xinput_stateex=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - if test x$have_ddraw = xyes; then -$as_echo "#define HAVE_DDRAW_H 1" >>confdefs.h +printf "%s\n" "#define HAVE_DDRAW_H 1" >>confdefs.h fi if test x$have_dinput = xyes; then -$as_echo "#define HAVE_DINPUT_H 1" >>confdefs.h +printf "%s\n" "#define HAVE_DINPUT_H 1" >>confdefs.h fi if test x$have_dsound = xyes; then -$as_echo "#define HAVE_DSOUND_H 1" >>confdefs.h +printf "%s\n" "#define HAVE_DSOUND_H 1" >>confdefs.h fi if test x$have_dxgi = xyes; then -$as_echo "#define HAVE_DXGI_H 1" >>confdefs.h - - fi - if test x$have_xinput = xyes; then - -$as_echo "#define HAVE_XINPUT_H 1" >>confdefs.h - - fi - if test x$have_xinput_gamepadex = xyes; then - -$as_echo "#define HAVE_XINPUT_GAMEPAD_EX 1" >>confdefs.h - - fi - if test x$have_xinput_stateex = xyes; then - -$as_echo "#define HAVE_XINPUT_STATE_EX 1" >>confdefs.h +printf "%s\n" "#define HAVE_DXGI_H 1" >>confdefs.h fi @@ -23708,33 +27595,91 @@ $as_echo "#define HAVE_XINPUT_STATE_EX 1" >>confdefs.h esac fi - ac_fn_c_check_header_mongrel "$LINENO" "mmdeviceapi.h" "ac_cv_header_mmdeviceapi_h" "$ac_includes_default" -if test "x$ac_cv_header_mmdeviceapi_h" = xyes; then : + # Check whether --enable-xinput was given. +if test ${enable_xinput+y} +then : + enableval=$enable_xinput; +else $as_nop + enable_xinput=yes +fi + + if test x$enable_xinput = xyes; then + ac_fn_c_check_header_compile "$LINENO" "xinput.h" "ac_cv_header_xinput_h" "$ac_includes_default" +if test "x$ac_cv_header_xinput_h" = xyes +then : + have_xinput=yes +fi + + if test x$have_xinput = xyes; then + +printf "%s\n" "#define HAVE_XINPUT_H 1" >>confdefs.h + + fi + fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for windows.gaming.input.h" >&5 +printf %s "checking for windows.gaming.input.h... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define COBJMACROS +#include +__x_ABI_CWindows_CGaming_CInput_CIGamepadStatics2 *s2; + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + have_wgi=yes +else $as_nop + have_wgi=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_wgi" >&5 +printf "%s\n" "$have_wgi" >&6; } + + if test x$have_wgi = xyes; then + +printf "%s\n" "#define HAVE_WINDOWS_GAMING_INPUT_H 1" >>confdefs.h + + fi + + ac_fn_c_check_header_compile "$LINENO" "mmdeviceapi.h" "ac_cv_header_mmdeviceapi_h" "$ac_includes_default" +if test "x$ac_cv_header_mmdeviceapi_h" = xyes +then : have_wasapi=yes fi - if test x$have_wasapi = xyes; then - $as_echo "#define HAVE_MMDEVICEAPI_H 1" >>confdefs.h + +printf "%s\n" "#define HAVE_MMDEVICEAPI_H 1" >>confdefs.h fi - ac_fn_c_check_header_mongrel "$LINENO" "audioclient.h" "ac_cv_header_audioclient_h" "$ac_includes_default" -if test "x$ac_cv_header_audioclient_h" = xyes; then : + ac_fn_c_check_header_compile "$LINENO" "audioclient.h" "ac_cv_header_audioclient_h" "$ac_includes_default" +if test "x$ac_cv_header_audioclient_h" = xyes +then : -else +else $as_nop have_wasapi=no fi - if test x$have_wasapi = xyes; then - $as_echo "#define HAVE_AUDIOCLIENT_H 1" >>confdefs.h + +printf "%s\n" "#define HAVE_AUDIOCLIENT_H 1" >>confdefs.h fi # Check whether --enable-wasapi was given. -if test "${enable_wasapi+set}" = set; then : +if test ${enable_wasapi+y} +then : enableval=$enable_wasapi; -else +else $as_nop enable_wasapi=yes fi @@ -23742,48 +27687,26 @@ fi CheckDLOPEN() { - # Check whether --enable-sdl-dlopen was given. -if test "${enable_sdl_dlopen+set}" = set; then : - enableval=$enable_sdl_dlopen; -else - enable_sdl_dlopen=yes + +printf "%s\n" "#define DYNAPI_NEEDS_DLOPEN 1" >>confdefs.h + + + ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default" +if test "x$ac_cv_header_dlfcn_h" = xyes +then : + have_dlfcn_h=yes +else $as_nop + have_dlfcn_h=no fi - if test x$enable_sdl_dlopen = xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen" >&5 -$as_echo_n "checking for dlopen... " >&6; } - have_dlopen=no - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - #include - -int -main () -{ - - void *handle = dlopen("", RTLD_NOW); - const char *loaderror = (char *) dlerror(); - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - have_dlopen=yes - -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_dlopen" >&5 -$as_echo "$have_dlopen" >&6; } - - if test x$have_dlopen = xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lc" >&5 -$as_echo_n "checking for dlopen in -lc... " >&6; } -if ${ac_cv_lib_c_dlopen+:} false; then : - $as_echo_n "(cached) " >&6 -else + have_dlopen=no + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lc" >&5 +printf %s "checking for dlopen in -lc... " >&6; } +if test ${ac_cv_lib_c_dlopen+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lc $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -23792,37 +27715,37 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char dlopen (); int -main () +main (void) { return dlopen (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_c_dlopen=yes -else +else $as_nop ac_cv_lib_c_dlopen=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_dlopen" >&5 -$as_echo "$ac_cv_lib_c_dlopen" >&6; } -if test "x$ac_cv_lib_c_dlopen" = xyes; then : - EXTRA_LDFLAGS="$EXTRA_LDFLAGS" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 -$as_echo_n "checking for dlopen in -ldl... " >&6; } -if ${ac_cv_lib_dl_dlopen+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_dlopen" >&5 +printf "%s\n" "$ac_cv_lib_c_dlopen" >&6; } +if test "x$ac_cv_lib_c_dlopen" = xyes +then : + have_dlopen=yes +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +printf %s "checking for dlopen in -ldl... " >&6; } +if test ${ac_cv_lib_dl_dlopen+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -23831,95 +27754,98 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char dlopen (); int -main () +main (void) { return dlopen (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_dl_dlopen=yes -else +else $as_nop ac_cv_lib_dl_dlopen=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 -$as_echo "$ac_cv_lib_dl_dlopen" >&6; } -if test "x$ac_cv_lib_dl_dlopen" = xyes; then : - EXTRA_LDFLAGS="$EXTRA_LDFLAGS -ldl" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lltdl" >&5 -$as_echo_n "checking for dlopen in -lltdl... " >&6; } -if ${ac_cv_lib_ltdl_dlopen+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lltdl $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +printf "%s\n" "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes +then : + have_dlopen=yes; EXTRA_LDFLAGS="$EXTRA_LDFLAGS -ldl" +fi + +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen" >&5 +printf %s "checking for dlopen... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_dlopen" >&5 +printf "%s\n" "$have_dlopen" >&6; } + + if test x$have_dlfcn_h = xyes -a x$have_dlopen = xyes; then + +printf "%s\n" "#define HAVE_DLOPEN 1" >>confdefs.h + + if test x$enable_loadso = xyes; then + +printf "%s\n" "#define SDL_LOADSO_DLOPEN 1" >>confdefs.h + + SOURCES="$SOURCES $srcdir/src/loadso/dlopen/*.c" + have_loadso=yes + fi + fi +} + +CheckO_CLOEXEC() +{ + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for O_CLOEXEC" >&5 +printf %s "checking for O_CLOEXEC... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dlopen (); +#include +int flag = O_CLOEXEC; + int -main () +main (void) { -return dlopen (); + ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_ltdl_dlopen=yes -else - ac_cv_lib_ltdl_dlopen=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ltdl_dlopen" >&5 -$as_echo "$ac_cv_lib_ltdl_dlopen" >&6; } -if test "x$ac_cv_lib_ltdl_dlopen" = xyes; then : - EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lltdl" +if ac_fn_c_try_compile "$LINENO" +then : + have_o_cloexec=yes +else $as_nop + have_o_cloexec=no fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_o_cloexec" >&5 +printf "%s\n" "$have_o_cloexec" >&6; } + if test $have_o_cloexec = yes; then -fi +printf "%s\n" "#define HAVE_O_CLOEXEC 1" >>confdefs.h -fi - - -$as_echo "#define SDL_LOADSO_DLOPEN 1" >>confdefs.h - - SOURCES="$SOURCES $srcdir/src/loadso/dlopen/*.c" - have_loadso=yes - fi fi } CheckUSBHID() { case "$host" in - *-*-*bsd*) + *-*-*bsd*|*-*-dragonfly*) if test x$enable_joystick = xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for hid_init in -lusbhid" >&5 -$as_echo_n "checking for hid_init in -lusbhid... " >&6; } -if ${ac_cv_lib_usbhid_hid_init+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for hid_init in -lusbhid" >&5 +printf %s "checking for hid_init in -lusbhid... " >&6; } +if test ${ac_cv_lib_usbhid_hid_init+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lusbhid $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -23928,65 +27854,65 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char hid_init (); int -main () +main (void) { return hid_init (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_usbhid_hid_init=yes -else +else $as_nop ac_cv_lib_usbhid_hid_init=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_usbhid_hid_init" >&5 -$as_echo "$ac_cv_lib_usbhid_hid_init" >&6; } -if test "x$ac_cv_lib_usbhid_hid_init" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_usbhid_hid_init" >&5 +printf "%s\n" "$ac_cv_lib_usbhid_hid_init" >&6; } +if test "x$ac_cv_lib_usbhid_hid_init" = xyes +then : have_libusbhid=yes fi if test x$have_libusbhid = xyes; then - ac_fn_c_check_header_mongrel "$LINENO" "usbhid.h" "ac_cv_header_usbhid_h" "$ac_includes_default" -if test "x$ac_cv_header_usbhid_h" = xyes; then : + ac_fn_c_check_header_compile "$LINENO" "usbhid.h" "ac_cv_header_usbhid_h" "$ac_includes_default" +if test "x$ac_cv_header_usbhid_h" = xyes +then : USB_CFLAGS="-DHAVE_USBHID_H" fi - - ac_fn_c_check_header_mongrel "$LINENO" "libusbhid.h" "ac_cv_header_libusbhid_h" "$ac_includes_default" -if test "x$ac_cv_header_libusbhid_h" = xyes; then : + ac_fn_c_check_header_compile "$LINENO" "libusbhid.h" "ac_cv_header_libusbhid_h" "$ac_includes_default" +if test "x$ac_cv_header_libusbhid_h" = xyes +then : USB_CFLAGS="-DHAVE_LIBUSBHID_H" fi - USB_LIBS="$USB_LIBS -lusbhid" else - ac_fn_c_check_header_mongrel "$LINENO" "usb.h" "ac_cv_header_usb_h" "$ac_includes_default" -if test "x$ac_cv_header_usb_h" = xyes; then : + ac_fn_c_check_header_compile "$LINENO" "usb.h" "ac_cv_header_usb_h" "$ac_includes_default" +if test "x$ac_cv_header_usb_h" = xyes +then : USB_CFLAGS="-DHAVE_USB_H" fi - - ac_fn_c_check_header_mongrel "$LINENO" "libusb.h" "ac_cv_header_libusb_h" "$ac_includes_default" -if test "x$ac_cv_header_libusb_h" = xyes; then : + ac_fn_c_check_header_compile "$LINENO" "libusb.h" "ac_cv_header_libusb_h" "$ac_includes_default" +if test "x$ac_cv_header_libusb_h" = xyes +then : USB_CFLAGS="-DHAVE_LIBUSB_H" fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for hid_init in -lusb" >&5 -$as_echo_n "checking for hid_init in -lusb... " >&6; } -if ${ac_cv_lib_usb_hid_init+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for hid_init in -lusb" >&5 +printf %s "checking for hid_init in -lusb... " >&6; } +if test ${ac_cv_lib_usb_hid_init+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lusb $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -23995,30 +27921,29 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char hid_init (); int -main () +main (void) { return hid_init (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_usb_hid_init=yes -else +else $as_nop ac_cv_lib_usb_hid_init=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_usb_hid_init" >&5 -$as_echo "$ac_cv_lib_usb_hid_init" >&6; } -if test "x$ac_cv_lib_usb_hid_init" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_usb_hid_init" >&5 +printf "%s\n" "$ac_cv_lib_usb_hid_init" >&6; } +if test "x$ac_cv_lib_usb_hid_init" = xyes +then : USB_LIBS="$USB_LIBS -lusb" fi @@ -24027,8 +27952,8 @@ fi save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $USB_CFLAGS" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for usbhid" >&5 -$as_echo_n "checking for usbhid... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for usbhid" >&5 +printf %s "checking for usbhid... " >&6; } have_usbhid=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -24038,8 +27963,8 @@ $as_echo_n "checking for usbhid... " >&6; } #include #endif #ifdef __DragonFly__ - # include - # include + # include + # include #else # include # include @@ -24053,7 +27978,7 @@ $as_echo_n "checking for usbhid... " >&6; } #endif int -main () +main (void) { struct report_desc *repdesc; @@ -24064,18 +27989,17 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - have_usbhid=yes - +if ac_fn_c_try_compile "$LINENO" +then : + have_usbhid=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_usbhid" >&5 -$as_echo "$have_usbhid" >&6; } +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_usbhid" >&5 +printf "%s\n" "$have_usbhid" >&6; } if test x$have_usbhid = xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ucr_data member of usb_ctl_report" >&5 -$as_echo_n "checking for ucr_data member of usb_ctl_report... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ucr_data member of usb_ctl_report" >&5 +printf %s "checking for ucr_data member of usb_ctl_report... " >&6; } have_usbhid_ucr_data=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -24085,8 +28009,8 @@ $as_echo_n "checking for ucr_data member of usb_ctl_report... " >&6; } #include #endif #ifdef __DragonFly__ - # include - # include + # include + # include #else # include # include @@ -24100,7 +28024,7 @@ $as_echo_n "checking for ucr_data member of usb_ctl_report... " >&6; } #endif int -main () +main (void) { struct usb_ctl_report buf; @@ -24110,20 +28034,19 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - have_usbhid_ucr_data=yes - +if ac_fn_c_try_compile "$LINENO" +then : + have_usbhid_ucr_data=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext if test x$have_usbhid_ucr_data = xyes; then USB_CFLAGS="$USB_CFLAGS -DUSBHID_UCR_DATA" fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_usbhid_ucr_data" >&5 -$as_echo "$have_usbhid_ucr_data" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_usbhid_ucr_data" >&5 +printf "%s\n" "$have_usbhid_ucr_data" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for new usbhid API" >&5 -$as_echo_n "checking for new usbhid API... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for new usbhid API" >&5 +printf %s "checking for new usbhid API... " >&6; } have_usbhid_new=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -24133,8 +28056,8 @@ $as_echo_n "checking for new usbhid API... " >&6; } #include #endif #ifdef __DragonFly__ - #include - #include + #include + #include #else #include #include @@ -24148,7 +28071,7 @@ $as_echo_n "checking for new usbhid API... " >&6; } #endif int -main () +main (void) { report_desc_t d; @@ -24158,20 +28081,19 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - have_usbhid_new=yes - +if ac_fn_c_try_compile "$LINENO" +then : + have_usbhid_new=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext if test x$have_usbhid_new = xyes; then USB_CFLAGS="$USB_CFLAGS -DUSBHID_NEW" fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_usbhid_new" >&5 -$as_echo "$have_usbhid_new" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_usbhid_new" >&5 +printf "%s\n" "$have_usbhid_new" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct joystick in machine/joystick.h" >&5 -$as_echo_n "checking for struct joystick in machine/joystick.h... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for struct joystick in machine/joystick.h" >&5 +printf %s "checking for struct joystick in machine/joystick.h... " >&6; } have_machine_joystick=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -24179,7 +28101,7 @@ $as_echo_n "checking for struct joystick in machine/joystick.h... " >&6; } #include int -main () +main (void) { struct joystick t; @@ -24188,28 +28110,28 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - have_machine_joystick=yes - +if ac_fn_c_try_compile "$LINENO" +then : + have_machine_joystick=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext if test x$have_machine_joystick = xyes; then -$as_echo "#define SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H 1" >>confdefs.h +printf "%s\n" "#define SDL_HAVE_MACHINE_JOYSTICK_H 1" >>confdefs.h fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_machine_joystick" >&5 -$as_echo "$have_machine_joystick" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_machine_joystick" >&5 +printf "%s\n" "$have_machine_joystick" >&6; } -$as_echo "#define SDL_JOYSTICK_USBHID 1" >>confdefs.h +printf "%s\n" "#define SDL_JOYSTICK_USBHID 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/joystick/bsd/*.c" EXTRA_CFLAGS="$EXTRA_CFLAGS $USB_CFLAGS" EXTRA_LDFLAGS="$EXTRA_LDFLAGS $USB_LIBS" have_joystick=yes fi + CFLAGS="$save_CFLAGS" fi ;; @@ -24218,45 +28140,57 @@ $as_echo "#define SDL_JOYSTICK_USBHID 1" >>confdefs.h CheckHIDAPI() { - # The hidraw support doesn't catch Xbox, PS4 and Nintendo controllers, - # so we'll just use libusb when it's available. - case "$host" in - # libusb does not support iOS - arm*-apple-darwin* | *-ios-* ) - skiplibusb=yes - ;; - # On the other hand, *BSD specifically uses libusb only - *-*-*bsd* ) - onlylibusb=yes - ;; - esac - - # Check whether --enable-hidapi was given. -if test "${enable_hidapi+set}" = set; then : - enableval=$enable_hidapi; -else - enable_hidapi=no + # Check whether --enable-hidapi-joystick was given. +if test ${enable_hidapi_joystick+y} +then : + enableval=$enable_hidapi_joystick; +else $as_nop + enable_hidapi_joystick=yes fi - if test x$enable_joystick = xyes -a x$enable_hidapi = xyes; then - if test x$skiplibusb = xyes; then - hidapi_support=yes - else + # Check whether --enable-hidapi-libusb was given. +if test ${enable_hidapi_libusb+y} +then : + enableval=$enable_hidapi_libusb; +else $as_nop + enable_hidapi_libusb=maybe +fi + + + if test x$enable_hidapi = xyes; then + case "$host" in + # libusb does not support iOS + *-ios-* ) + enable_hidapi_libusb=no + ;; + # On the other hand, *BSD specifically uses libusb only + *-*-*bsd* ) + enable_hidapi_libusb=yes + require_hidapi_libusb=yes + ;; + *-*-os2* ) + enable_hidapi_libusb=yes + ;; + esac + + hidapi_support=yes + if test x$enable_hidapi_libusb = xyes; then pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBUSB" >&5 -$as_echo_n "checking for LIBUSB... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libusb-1.0" >&5 +printf %s "checking for libusb-1.0... " >&6; } if test -n "$LIBUSB_CFLAGS"; then pkg_cv_LIBUSB_CFLAGS="$LIBUSB_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libusb-1.0\""; } >&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libusb-1.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "libusb-1.0") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_LIBUSB_CFLAGS=`$PKG_CONFIG --cflags "libusb-1.0" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi @@ -24267,12 +28201,13 @@ if test -n "$LIBUSB_LIBS"; then pkg_cv_LIBUSB_LIBS="$LIBUSB_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libusb-1.0\""; } >&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libusb-1.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "libusb-1.0") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_LIBUSB_LIBS=`$PKG_CONFIG --libs "libusb-1.0" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi @@ -24283,8 +28218,8 @@ fi if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes @@ -24292,60 +28227,52 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - LIBUSB_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "libusb-1.0" 2>&1` + LIBUSB_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libusb-1.0" 2>&1` else - LIBUSB_PKG_ERRORS=`$PKG_CONFIG --print-errors "libusb-1.0" 2>&1` + LIBUSB_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libusb-1.0" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$LIBUSB_PKG_ERRORS" >&5 have_libusb=no elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } have_libusb=no else LIBUSB_CFLAGS=$pkg_cv_LIBUSB_CFLAGS LIBUSB_LIBS=$pkg_cv_LIBUSB_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } have_libusb=yes fi - save_CFLAGS="$CFLAGS" - CFLAGS="$save_CFLAGS $LIBUSB_CFLAGS" - ac_fn_c_check_header_mongrel "$LINENO" "libusb.h" "ac_cv_header_libusb_h" "$ac_includes_default" -if test "x$ac_cv_header_libusb_h" = xyes; then : + save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$save_CPPFLAGS $LIBUSB_CFLAGS" + ac_fn_c_check_header_compile "$LINENO" "libusb.h" "ac_cv_header_libusb_h" "$ac_includes_default" +if test "x$ac_cv_header_libusb_h" = xyes +then : have_libusb_h=yes +else $as_nop + have_libusb_h=no fi - - CFLAGS="$save_CFLAGS" - if test x$have_libusb_h = xyes; then - hidapi_support=yes - elif test x$onlylibusb = xyes; then + CPPFLAGS="$save_CPPFLAGS" + if test x$have_libusb_h = xno && test x$require_hidapi_libusb = xyes; then hidapi_support=no - else - hidapi_support=yes fi fi if test x$hidapi_support = xyes; then - -$as_echo "#define SDL_JOYSTICK_HIDAPI 1" >>confdefs.h - - EXTRA_CFLAGS="$EXTRA_CFLAGS -I$srcdir/src/hidapi/hidapi" - SOURCES="$SOURCES $srcdir/src/joystick/hidapi/*.c" - SOURCES="$SOURCES $srcdir/src/hidapi/SDL_hidapi.c" - if test x$have_libusb_h = xyes; then + printf "%s\n" "#define HAVE_LIBUSB 1" >>confdefs.h + EXTRA_CFLAGS="$EXTRA_CFLAGS $LIBUSB_CFLAGS" - if test x$onlylibusb = xyes; then - SOURCES="$SOURCES $srcdir/src/hidapi/libusb/hid.c" + if test x$require_hidapi_libusb = xyes; then EXTRA_LDFLAGS="$EXTRA_LDFLAGS $LIBUSB_LIBS" else if test x$have_loadso != xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: You must have SDL_LoadObject() support for dynamic libusb loading" >&5 -$as_echo "$as_me: WARNING: You must have SDL_LoadObject() support for dynamic libusb loading" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: You must have SDL_LoadObject() support for dynamic libusb loading" >&5 +printf "%s\n" "$as_me: WARNING: You must have SDL_LoadObject() support for dynamic libusb loading" >&2;} fi # libusb is loaded dynamically, so don't add it to LDFLAGS libusb_lib="" @@ -24353,90 +28280,54 @@ $as_echo "$as_me: WARNING: You must have SDL_LoadObject() support for dynamic li *-*-darwin* ) libusb_lib="libusb-1.0.0.dylib" ;; - *-*-cygwin* | *-*-mingw32* ) + *-*-cygwin* | *-*-mingw* ) libusb_lib="libusb-1.0.dll" ;; + *-*-os2* ) + libusb_lib="usb100.dll" + ;; esac if test x$libusb_lib = x; then libusb_lib=`find_lib "libusb-1.0.so.*" "" | sed 's/.*\/\(.*\)/\1/; q'` fi -cat >>confdefs.h <<_ACEOF -#define SDL_LIBUSB_DYNAMIC "$libusb_lib" -_ACEOF +printf "%s\n" "#define SDL_LIBUSB_DYNAMIC \"$libusb_lib\"" >>confdefs.h fi fi fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for hidapi support" >&5 -$as_echo_n "checking for hidapi support... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hidapi_support" >&5 -$as_echo "$hidapi_support" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for hidapi joystick support" >&5 +printf %s "checking for hidapi joystick support... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hidapi_support" >&5 +printf "%s\n" "$hidapi_support" >&6; } + fi + + if test x$enable_joystick = xyes -a x$hidapi_support = xyes -a x$enable_hidapi_joystick = xyes; then + +printf "%s\n" "#define SDL_JOYSTICK_HIDAPI 1" >>confdefs.h + + SOURCES="$SOURCES $srcdir/src/joystick/hidapi/*.c" fi } CheckClockGettime() { # Check whether --enable-clock_gettime was given. -if test "${enable_clock_gettime+set}" = set; then : +if test ${enable_clock_gettime+y} +then : enableval=$enable_clock_gettime; -else +else $as_nop enable_clock_gettime=yes fi if test x$enable_clock_gettime = xyes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_gettime in -lrt" >&5 -$as_echo_n "checking for clock_gettime in -lrt... " >&6; } -if ${ac_cv_lib_rt_clock_gettime+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lrt $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char clock_gettime (); -int -main () -{ -return clock_gettime (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_rt_clock_gettime=yes -else - ac_cv_lib_rt_clock_gettime=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_clock_gettime" >&5 -$as_echo "$ac_cv_lib_rt_clock_gettime" >&6; } -if test "x$ac_cv_lib_rt_clock_gettime" = xyes; then : - have_clock_gettime=yes -fi - - if test x$have_clock_gettime = xyes; then - -$as_echo "#define HAVE_CLOCK_GETTIME 1" >>confdefs.h - - EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lrt" - else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_gettime in -lc" >&5 -$as_echo_n "checking for clock_gettime in -lc... " >&6; } -if ${ac_cv_lib_c_clock_gettime+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for clock_gettime in -lc" >&5 +printf %s "checking for clock_gettime in -lc... " >&6; } +if test ${ac_cv_lib_c_clock_gettime+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lc $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -24445,38 +28336,82 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char clock_gettime (); int -main () +main (void) { return clock_gettime (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_c_clock_gettime=yes -else +else $as_nop ac_cv_lib_c_clock_gettime=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_clock_gettime" >&5 -$as_echo "$ac_cv_lib_c_clock_gettime" >&6; } -if test "x$ac_cv_lib_c_clock_gettime" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_clock_gettime" >&5 +printf "%s\n" "$ac_cv_lib_c_clock_gettime" >&6; } +if test "x$ac_cv_lib_c_clock_gettime" = xyes +then : + have_clock_gettime=yes +fi + + if test x$have_clock_gettime = xyes; then + +printf "%s\n" "#define HAVE_CLOCK_GETTIME 1" >>confdefs.h + + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for clock_gettime in -lrt" >&5 +printf %s "checking for clock_gettime in -lrt... " >&6; } +if test ${ac_cv_lib_rt_clock_gettime+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lrt $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char clock_gettime (); +int +main (void) +{ +return clock_gettime (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_rt_clock_gettime=yes +else $as_nop + ac_cv_lib_rt_clock_gettime=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_clock_gettime" >&5 +printf "%s\n" "$ac_cv_lib_rt_clock_gettime" >&6; } +if test "x$ac_cv_lib_rt_clock_gettime" = xyes +then : have_clock_gettime=yes fi if test x$have_clock_gettime = xyes; then + EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lrt" -$as_echo "#define HAVE_CLOCK_GETTIME 1" >>confdefs.h +printf "%s\n" "#define HAVE_CLOCK_GETTIME 1" >>confdefs.h - EXTRA_LDFLAGS="$EXTRA_LDFLAGS" fi fi fi @@ -24484,12 +28419,12 @@ $as_echo "#define HAVE_CLOCK_GETTIME 1" >>confdefs.h CheckLinuxVersion() { - ac_fn_c_check_header_mongrel "$LINENO" "linux/version.h" "ac_cv_header_linux_version_h" "$ac_includes_default" -if test "x$ac_cv_header_linux_version_h" = xyes; then : + ac_fn_c_check_header_compile "$LINENO" "linux/version.h" "ac_cv_header_linux_version_h" "$ac_includes_default" +if test "x$ac_cv_header_linux_version_h" = xyes +then : have_linux_version_h=yes fi - if test x$have_linux_version_h = xyes; then EXTRA_CFLAGS="$EXTRA_CFLAGS -DHAVE_LINUX_VERSION_H" fi @@ -24498,9 +28433,10 @@ fi CheckRPATH() { # Check whether --enable-rpath was given. -if test "${enable_rpath+set}" = set; then : +if test ${enable_rpath+y} +then : enableval=$enable_rpath; -else +else $as_nop enable_rpath=yes fi @@ -24509,9 +28445,10 @@ fi CheckEventSignals() { # Check whether --enable-backgrounding-signal was given. -if test "${enable_backgrounding_signal+set}" = set; then : +if test ${enable_backgrounding_signal+y} +then : enableval=$enable_backgrounding_signal; -else +else $as_nop enable_backgrounding_signal=no fi @@ -24520,9 +28457,10 @@ fi fi # Check whether --enable-foregrounding-signal was given. -if test "${enable_foregrounding_signal+set}" = set; then : +if test ${enable_foregrounding_signal+y} +then : enableval=$enable_foregrounding_signal; -else +else $as_nop enable_foregrounding_signal=no fi @@ -24531,13 +28469,33 @@ fi fi } +CheckVirtualJoystick() +{ + # Check whether --enable-joystick-virtual was given. +if test ${enable_joystick_virtual+y} +then : + enableval=$enable_joystick_virtual; +else $as_nop + enable_joystick_virtual=yes +fi + if test x$enable_joystick = xyes -a x$enable_joystick_virtual = xyes; then + +printf "%s\n" "#define SDL_JOYSTICK_VIRTUAL 1" >>confdefs.h + + SOURCES="$SOURCES $srcdir/src/joystick/virtual/*.c" + have_joystick_virtual=yes + fi +} CheckWarnAll +CheckUnusedLocalTypedefs CheckNoStrictAliasing CheckEventSignals +have_locale=no + case "$host" in *-*-linux*|*-*-uclinux*|*-*-gnu*|*-*-k*bsd*-gnu|*-*-bsdi*|*-*-freebsd*|*-*-dragonfly*|*-*-netbsd*|*-*-openbsd*|*-*-sysv5*|*-*-solaris*|*-*-hpux*|*-*-aix*|*-*-minix*|*-*-nto*) case "$host" in @@ -24550,12 +28508,13 @@ case "$host" in EXTRA_CFLAGS="$EXTRA_CFLAGS $ANDROID_CFLAGS" EXTRA_LDFLAGS="$EXTRA_LDFLAGS -ldl -lGLESv1_CM -lGLESv2 -llog -landroid" SDLMAIN_SOURCES="$srcdir/src/main/android/*.c" - if test x$enable_video = xyes; then SOURCES="$SOURCES $srcdir/src/core/android/*.c $srcdir/src/video/android/*.c" - # FIXME: confdefs? Not AC_DEFINE? - $as_echo "#define SDL_VIDEO_DRIVER_ANDROID 1" >>confdefs.h + +printf "%s\n" "#define SDL_VIDEO_DRIVER_ANDROID 1" >>confdefs.h + SUMMARY_video="${SUMMARY_video} android" + have_video=yes fi ;; *-*-linux*) ARCH=linux ;; @@ -24579,15 +28538,19 @@ case "$host" in ;; esac CheckVisibilityHidden + CheckWerror CheckDeclarationAfterStatement CheckDummyVideo + CheckOffscreenVideo CheckDiskAudio CheckDummyAudio CheckDLOPEN CheckARM CheckNEON + CheckO_CLOEXEC CheckOSS CheckALSA + CheckPipewire CheckPulseAudio CheckJACK CheckARTSC @@ -24600,23 +28563,32 @@ case "$host" in CheckRPI CheckX11 CheckDirectFB + # Need to check for EGL first because KMSDRM and Wayland depends on it. + CheckEGL CheckKMSDRM - CheckOpenGLX11 - CheckOpenGLESX11 + CheckGLX + CheckOpenGL + CheckOpenGLES CheckVulkan CheckWayland CheckInputEvents CheckLibUDev CheckDBus CheckIME + CheckInotify CheckIBus CheckFcitx case $ARCH in linux) CheckInputKD ;; + freebsd) + CheckInputKBIO + ;; + openbsd|netbsd) + CheckInputWSCONS + ;; esac - CheckTslib CheckUSBHID CheckHIDAPI CheckPTHREAD @@ -24625,12 +28597,22 @@ case "$host" in CheckRPATH CheckVivanteVideo + # Set up files for the misc library + if test x$enable_misc = xyes; then + SOURCES="$SOURCES $srcdir/src/misc/unix/*.c" + have_misc=yes + fi + # Set up files for the locale library + if test x$enable_locale = xyes; then + SOURCES="$SOURCES $srcdir/src/locale/unix/*.c" + have_locale=yes + fi # Set up files for the audio library if test x$enable_audio = xyes; then case $ARCH in sysv5|solaris|hpux) -$as_echo "#define SDL_AUDIO_DRIVER_SUNAUDIO 1" >>confdefs.h +printf "%s\n" "#define SDL_AUDIO_DRIVER_SUNAUDIO 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/audio/sun/*.c" SUMMARY_audio="${SUMMARY_audio} sun" @@ -24638,7 +28620,7 @@ $as_echo "#define SDL_AUDIO_DRIVER_SUNAUDIO 1" >>confdefs.h ;; netbsd) # Don't use this on OpenBSD, it's busted. -$as_echo "#define SDL_AUDIO_DRIVER_NETBSD 1" >>confdefs.h +printf "%s\n" "#define SDL_AUDIO_DRIVER_NETBSD 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/audio/netbsd/*.c" SUMMARY_audio="${SUMMARY_audio} netbsd" @@ -24646,7 +28628,7 @@ $as_echo "#define SDL_AUDIO_DRIVER_NETBSD 1" >>confdefs.h ;; aix) -$as_echo "#define SDL_AUDIO_DRIVER_PAUDIO 1" >>confdefs.h +printf "%s\n" "#define SDL_AUDIO_DRIVER_PAUDIO 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/audio/paudio/*.c" SUMMARY_audio="${SUMMARY_audio} paudio" @@ -24654,10 +28636,23 @@ $as_echo "#define SDL_AUDIO_DRIVER_PAUDIO 1" >>confdefs.h ;; android) -$as_echo "#define SDL_AUDIO_DRIVER_ANDROID 1" >>confdefs.h +printf "%s\n" "#define SDL_AUDIO_DRIVER_ANDROID 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/audio/android/*.c" SUMMARY_audio="${SUMMARY_audio} android" + + +printf "%s\n" "#define SDL_AUDIO_DRIVER_OPENSLES 1" >>confdefs.h + + SOURCES="$SOURCES $srcdir/src/audio/openslES/*.c" + SUMMARY_audio="${SUMMARY_audio} openslES" + + +printf "%s\n" "#define SDL_AUDIO_DRIVER_AAUDIO 1" >>confdefs.h + + SOURCES="$SOURCES $srcdir/src/audio/aaudio/*.c" + SUMMARY_audio="${SUMMARY_audio} aaudio" + have_audio=yes ;; nto) @@ -24669,16 +28664,28 @@ $as_echo "#define SDL_AUDIO_DRIVER_ANDROID 1" >>confdefs.h if test x$enable_joystick = xyes; then case $ARCH in linux) + if test "x$ac_cv_header_linux_input_h" = xyes; then -$as_echo "#define SDL_JOYSTICK_LINUX 1" >>confdefs.h +printf "%s\n" "#define SDL_JOYSTICK_LINUX 1" >>confdefs.h - SOURCES="$SOURCES $srcdir/src/joystick/linux/*.c" - SOURCES="$SOURCES $srcdir/src/joystick/steam/*.c" - have_joystick=yes + SOURCES="$SOURCES $srcdir/src/joystick/linux/*.c" + SOURCES="$SOURCES $srcdir/src/joystick/steam/*.c" + have_joystick=yes + fi + ;; + freebsd) + if test x$use_input_events = xyes -a x$ac_cv_header_linux_input_h = xyes; then + +printf "%s\n" "#define SDL_JOYSTICK_LINUX 1" >>confdefs.h + + SOURCES="$SOURCES $srcdir/src/joystick/linux/*.c" + SOURCES="$SOURCES $srcdir/src/joystick/steam/*.c" + have_joystick=yes + fi ;; android) -$as_echo "#define SDL_JOYSTICK_ANDROID 1" >>confdefs.h +printf "%s\n" "#define SDL_JOYSTICK_ANDROID 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/joystick/android/*.c" SOURCES="$SOURCES $srcdir/src/joystick/steam/*.c" @@ -24689,10 +28696,10 @@ $as_echo "#define SDL_JOYSTICK_ANDROID 1" >>confdefs.h # Set up files for the haptic library if test x$enable_haptic = xyes; then case $ARCH in - linux) + linux|freebsd) if test x$use_input_events = xyes; then -$as_echo "#define SDL_HAPTIC_LINUX 1" >>confdefs.h +printf "%s\n" "#define SDL_HAPTIC_LINUX 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/haptic/linux/*.c" have_haptic=yes @@ -24700,7 +28707,7 @@ $as_echo "#define SDL_HAPTIC_LINUX 1" >>confdefs.h ;; android) -$as_echo "#define SDL_HAPTIC_ANDROID 1" >>confdefs.h +printf "%s\n" "#define SDL_HAPTIC_ANDROID 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/haptic/android/*.c" have_haptic=yes @@ -24712,7 +28719,7 @@ $as_echo "#define SDL_HAPTIC_ANDROID 1" >>confdefs.h case $ARCH in android) -$as_echo "#define SDL_SENSOR_ANDROID 1" >>confdefs.h +printf "%s\n" "#define SDL_SENSOR_ANDROID 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/sensor/android/*.c" have_sensor=yes @@ -24724,14 +28731,14 @@ $as_echo "#define SDL_SENSOR_ANDROID 1" >>confdefs.h case $ARCH in linux) -$as_echo "#define SDL_POWER_LINUX 1" >>confdefs.h +printf "%s\n" "#define SDL_POWER_LINUX 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/power/linux/*.c" have_power=yes ;; android) -$as_echo "#define SDL_POWER_ANDROID 1" >>confdefs.h +printf "%s\n" "#define SDL_POWER_ANDROID 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/power/android/*.c" have_power=yes @@ -24743,14 +28750,14 @@ $as_echo "#define SDL_POWER_ANDROID 1" >>confdefs.h case $ARCH in android) -$as_echo "#define SDL_FILESYSTEM_ANDROID 1" >>confdefs.h +printf "%s\n" "#define SDL_FILESYSTEM_ANDROID 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/filesystem/android/*.c" have_filesystem=yes ;; *) -$as_echo "#define SDL_FILESYSTEM_UNIX 1" >>confdefs.h +printf "%s\n" "#define SDL_FILESYSTEM_UNIX 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/filesystem/unix/*.c" have_filesystem=yes @@ -24760,7 +28767,7 @@ $as_echo "#define SDL_FILESYSTEM_UNIX 1" >>confdefs.h # Set up files for the timer library if test x$enable_timers = xyes; then -$as_echo "#define SDL_TIMER_UNIX 1" >>confdefs.h +printf "%s\n" "#define SDL_TIMER_UNIX 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/timer/unix/*.c" have_timers=yes @@ -24771,13 +28778,22 @@ $as_echo "#define SDL_TIMER_UNIX 1" >>confdefs.h fi # Set up files for evdev input if test x$use_input_events = xyes; then - SOURCES="$SOURCES $srcdir/src/core/linux/SDL_evdev*.c" + SOURCES="$SOURCES $srcdir/src/core/linux/SDL_evdev.c" + SOURCES="$SOURCES $srcdir/src/core/linux/SDL_evdev_kbd.c" + SOURCES="$SOURCES $srcdir/src/core/freebsd/SDL_evdev_kbd_freebsd.c" + fi + # Set up files for wscons input + if test x$use_input_wscons = xyes; then + SOURCES="$SOURCES $srcdir/src/core/openbsd/SDL_wscons_kbd.c" + SOURCES="$SOURCES $srcdir/src/core/openbsd/SDL_wscons_mouse.c" fi # Set up other core UNIX files + SOURCES="$SOURCES $srcdir/src/core/linux/SDL_evdev_capabilities.c" SOURCES="$SOURCES $srcdir/src/core/linux/SDL_threadprio.c" + SOURCES="$SOURCES $srcdir/src/core/linux/SDL_sandbox.c" SOURCES="$SOURCES $srcdir/src/core/unix/*.c" ;; - *-*-cygwin* | *-*-mingw32*) + *-*-cygwin* | *-*-mingw*) ARCH=win32 if test "$build" != "$host"; then # cross-compiling # Default cross-compile location @@ -24788,8 +28804,14 @@ $as_echo "#define SDL_TIMER_UNIX 1" >>confdefs.h ac_default_prefix=$BUILD_PREFIX fi fi + if test x$enable_loadso = xyes; then + have_loadso=yes + fi + CheckGDwarf4 + CheckWerror CheckDeclarationAfterStatement CheckDummyVideo + CheckOffscreenVideo CheckDiskAudio CheckDummyAudio CheckWINDOWS @@ -24801,51 +28823,67 @@ $as_echo "#define SDL_TIMER_UNIX 1" >>confdefs.h # Set up the core platform files SOURCES="$SOURCES $srcdir/src/core/windows/*.c" - + # Set up files for the misc library + if test x$enable_misc = xyes; then + SOURCES="$SOURCES $srcdir/src/misc/windows/*.c" + have_misc=yes + fi + # Use the Windows locale APIs. + if test x$enable_locale = xyes; then + SOURCES="$SOURCES $srcdir/src/locale/windows/*.c" + have_locale=yes + fi # Set up files for the video library if test x$enable_video = xyes; then -$as_echo "#define SDL_VIDEO_DRIVER_WINDOWS 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_DRIVER_WINDOWS 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/video/windows/*.c" have_video=yes # Check whether --enable-render-d3d was given. -if test "${enable_render_d3d+set}" = set; then : +if test ${enable_render_d3d+y} +then : enableval=$enable_render_d3d; -else +else $as_nop enable_render_d3d=yes fi if test x$enable_render_d3d = xyes -a x$have_d3d = xyes; then -$as_echo "#define SDL_VIDEO_RENDER_D3D 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_RENDER_D3D 1" >>confdefs.h SUMMARY_video="${SUMMARY_video} d3d9" fi if test x$enable_render_d3d = xyes -a x$have_d3d11 = xyes; then -$as_echo "#define SDL_VIDEO_RENDER_D3D11 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_RENDER_D3D11 1" >>confdefs.h SUMMARY_video="${SUMMARY_video} d3d11" fi + if test x$enable_render_d3d = xyes -a x$have_d3d12 = xyes; then + +printf "%s\n" "#define SDL_VIDEO_RENDER_D3D12 1" >>confdefs.h + + SUMMARY_video="${SUMMARY_video} d3d12" + fi fi # Set up files for the audio library if test x$enable_audio = xyes; then -$as_echo "#define SDL_AUDIO_DRIVER_WINMM 1" >>confdefs.h +printf "%s\n" "#define SDL_AUDIO_DRIVER_WINMM 1" >>confdefs.h SUMMARY_audio="${SUMMARY_audio} winmm" SOURCES="$SOURCES $srcdir/src/audio/winmm/*.c" if test x$have_dsound = xyes; then -$as_echo "#define SDL_AUDIO_DRIVER_DSOUND 1" >>confdefs.h +printf "%s\n" "#define SDL_AUDIO_DRIVER_DSOUND 1" >>confdefs.h SUMMARY_audio="${SUMMARY_audio} directsound" SOURCES="$SOURCES $srcdir/src/audio/directsound/*.c" fi if test x$have_wasapi = xyes -a x$enable_wasapi = xyes; then -$as_echo "#define SDL_AUDIO_DRIVER_WASAPI 1" >>confdefs.h +printf "%s\n" "#define SDL_AUDIO_DRIVER_WASAPI 1" >>confdefs.h SUMMARY_audio="${SUMMARY_audio} wasapi" SOURCES="$SOURCES $srcdir/src/audio/wasapi/*.c" @@ -24854,22 +28892,26 @@ $as_echo "#define SDL_AUDIO_DRIVER_WASAPI 1" >>confdefs.h fi # Set up files for the joystick library if test x$enable_joystick = xyes; then - if test x$have_dinput = xyes -o x$have_xinput = xyes; then + +printf "%s\n" "#define SDL_JOYSTICK_RAWINPUT 1" >>confdefs.h + + if test x$have_dinput = xyes -o x$have_xinput = xyes -o x$have_wgi = xyes; then if test x$have_xinput = xyes; then -$as_echo "#define SDL_JOYSTICK_XINPUT 1" >>confdefs.h +printf "%s\n" "#define SDL_JOYSTICK_XINPUT 1" >>confdefs.h + + fi + if test x$have_wgi = xyes; then + +printf "%s\n" "#define SDL_JOYSTICK_WGI 1" >>confdefs.h fi if test x$have_dinput = xyes; then -$as_echo "#define SDL_JOYSTICK_DINPUT 1" >>confdefs.h +printf "%s\n" "#define SDL_JOYSTICK_DINPUT 1" >>confdefs.h EXTRA_LDFLAGS="$EXTRA_LDFLAGS -ldinput8 -ldxguid -ldxerr8" fi - else - -$as_echo "#define SDL_JOYSTICK_WINMM 1" >>confdefs.h - fi SOURCES="$SOURCES $srcdir/src/joystick/windows/*.c" have_joystick=yes @@ -24878,28 +28920,51 @@ $as_echo "#define SDL_JOYSTICK_WINMM 1" >>confdefs.h if test x$have_dinput = xyes -o x$have_xinput = xyes; then if test x$have_xinput = xyes; then -$as_echo "#define SDL_HAPTIC_XINPUT 1" >>confdefs.h +printf "%s\n" "#define SDL_HAPTIC_XINPUT 1" >>confdefs.h fi if test x$have_dinput = xyes; then -$as_echo "#define SDL_HAPTIC_DINPUT 1" >>confdefs.h +printf "%s\n" "#define SDL_HAPTIC_DINPUT 1" >>confdefs.h fi SOURCES="$SOURCES $srcdir/src/haptic/windows/*.c" have_haptic=yes fi fi + # Set up files for the sensor library + ac_fn_c_check_header_compile "$LINENO" "sensorsapi.h" "ac_cv_header_sensorsapi_h" "$ac_includes_default" +if test "x$ac_cv_header_sensorsapi_h" = xyes +then : + have_winsensors=yes +else $as_nop + have_winsensors=no +fi + + if test x$have_winsensors = xyes; then + +printf "%s\n" "#define HAVE_SENSORSAPI_H 1" >>confdefs.h + + fi + if test x$enable_sensor = xyes -a x$have_winsensors = xyes; then + +printf "%s\n" "#define SDL_SENSOR_WINDOWS 1" >>confdefs.h + + SOURCES="$SOURCES $srcdir/src/sensor/windows/*.c" + have_sensor=yes + fi + # Set up files for the power library if test x$enable_power = xyes; then -$as_echo "#define SDL_POWER_WINDOWS 1" >>confdefs.h +printf "%s\n" "#define SDL_POWER_WINDOWS 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/power/windows/SDL_syspower.c" have_power=yes fi + # Set up files for the filesystem library if test x$enable_filesystem = xyes; then -$as_echo "#define SDL_FILESYSTEM_WINDOWS 1" >>confdefs.h +printf "%s\n" "#define SDL_FILESYSTEM_WINDOWS 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/filesystem/windows/SDL_sysfilesystem.c" have_filesystem=yes @@ -24907,7 +28972,10 @@ $as_echo "#define SDL_FILESYSTEM_WINDOWS 1" >>confdefs.h # Set up files for the thread library if test x$enable_threads = xyes; then -$as_echo "#define SDL_THREAD_WINDOWS 1" >>confdefs.h +printf "%s\n" "#define SDL_THREAD_GENERIC_COND_SUFFIX 1" >>confdefs.h + + +printf "%s\n" "#define SDL_THREAD_WINDOWS 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/thread/windows/*.c" SOURCES="$SOURCES $srcdir/src/thread/generic/SDL_syscond.c" @@ -24916,7 +28984,7 @@ $as_echo "#define SDL_THREAD_WINDOWS 1" >>confdefs.h # Set up files for the timer library if test x$enable_timers = xyes; then -$as_echo "#define SDL_TIMER_WINDOWS 1" >>confdefs.h +printf "%s\n" "#define SDL_TIMER_WINDOWS 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/timer/windows/*.c" have_timers=yes @@ -24924,10 +28992,9 @@ $as_echo "#define SDL_TIMER_WINDOWS 1" >>confdefs.h # Set up files for the shared object loading library if test x$enable_loadso = xyes; then -$as_echo "#define SDL_LOADSO_WINDOWS 1" >>confdefs.h +printf "%s\n" "#define SDL_LOADSO_WINDOWS 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/loadso/windows/*.c" - have_loadso=yes fi # Set up the system libraries we need if test -f /lib/w32api/libuuid.a; then @@ -24935,7 +29002,8 @@ $as_echo "#define SDL_LOADSO_WINDOWS 1" >>confdefs.h else LIBUUID=-luuid fi - EXTRA_LDFLAGS="$EXTRA_LDFLAGS -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lsetupapi -lversion $LIBUUID -static-libgcc" + EXTRA_LDFLAGS="$EXTRA_LDFLAGS -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lsetupapi -lversion $LIBUUID" + BUILD_LDFLAGS="$BUILD_LDFLAGS -Wc,-static-libgcc" # The Windows platform requires special setup VERSION_SOURCES="$srcdir/src/main/windows/*.rc" SDLMAIN_SOURCES="$srcdir/src/main/windows/*.c" @@ -24944,11 +29012,12 @@ $as_echo "#define SDL_LOADSO_WINDOWS 1" >>confdefs.h # Check to see if this is a mingw or cygwin build have_mingw32= - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lmingw32" >&5 -$as_echo_n "checking for main in -lmingw32... " >&6; } -if ${ac_cv_lib_mingw32_main+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for main in -lmingw32" >&5 +printf %s "checking for main in -lmingw32... " >&6; } +if test ${ac_cv_lib_mingw32_main+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lmingw32 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -24956,25 +29025,27 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext int -main () +main (void) { return main (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_mingw32_main=yes -else +else $as_nop ac_cv_lib_mingw32_main=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_mingw32_main" >&5 -$as_echo "$ac_cv_lib_mingw32_main" >&6; } -if test "x$ac_cv_lib_mingw32_main" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_mingw32_main" >&5 +printf "%s\n" "$ac_cv_lib_mingw32_main" >&6; } +if test "x$ac_cv_lib_mingw32_main" = xyes +then : have_mingw32=yes fi @@ -24984,20 +29055,20 @@ fi SDL_LIBS="-lcygwin $SDL_LIBS" fi ;; - - *-*-beos*) + *-*-beos*) as_fn_error $? " *** BeOS support has been removed as of SDL 2.0.2. " "$LINENO" 5 ;; - *-*-haiku*) ARCH=haiku ac_default_prefix=/boot/system CheckDummyVideo + CheckOffscreenVideo CheckDiskAudio CheckDummyAudio CheckDLOPEN + CheckO_CLOEXEC CheckHaikuVideo CheckHaikuGL CheckPTHREAD @@ -25005,7 +29076,7 @@ fi # Set up files for the audio library if test x$enable_audio = xyes; then -$as_echo "#define SDL_AUDIO_DRIVER_HAIKU 1" >>confdefs.h +printf "%s\n" "#define SDL_AUDIO_DRIVER_HAIKU 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/audio/haiku/*.cc" SUMMARY_audio="${SUMMARY_audio} haiku" @@ -25014,7 +29085,7 @@ $as_echo "#define SDL_AUDIO_DRIVER_HAIKU 1" >>confdefs.h # Set up files for the joystick library if test x$enable_joystick = xyes; then -$as_echo "#define SDL_JOYSTICK_HAIKU 1" >>confdefs.h +printf "%s\n" "#define SDL_JOYSTICK_HAIKU 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/joystick/haiku/*.cc" have_joystick=yes @@ -25022,7 +29093,7 @@ $as_echo "#define SDL_JOYSTICK_HAIKU 1" >>confdefs.h # Set up files for the timer library if test x$enable_timers = xyes; then -$as_echo "#define SDL_TIMER_HAIKU 1" >>confdefs.h +printf "%s\n" "#define SDL_TIMER_HAIKU 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/timer/haiku/*.c" have_timers=yes @@ -25030,7 +29101,7 @@ $as_echo "#define SDL_TIMER_HAIKU 1" >>confdefs.h # Set up files for the system power library if test x$enable_power = xyes; then -$as_echo "#define SDL_POWER_HAIKU 1" >>confdefs.h +printf "%s\n" "#define SDL_POWER_HAIKU 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/power/haiku/*.c" have_power=yes @@ -25038,57 +29109,56 @@ $as_echo "#define SDL_POWER_HAIKU 1" >>confdefs.h # Set up files for the system filesystem library if test x$enable_filesystem = xyes; then -$as_echo "#define SDL_FILESYSTEM_HAIKU 1" >>confdefs.h +printf "%s\n" "#define SDL_FILESYSTEM_HAIKU 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/filesystem/haiku/*.cc" have_filesystem=yes fi + # Set up files for the misc library + if test x$enable_misc = xyes; then + SOURCES="$SOURCES $srcdir/src/misc/haiku/*.cc" + have_misc=yes + fi + # Set up files for the locale library + if test x$enable_locale = xyes; then + SOURCES="$SOURCES $srcdir/src/locale/haiku/*.cc" + have_locale=yes + fi # The Haiku platform requires special setup. SOURCES="$srcdir/src/main/haiku/*.cc $SOURCES" EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lroot -lbe -lmedia -lgame -ldevice -ltextencoding" - # Haiku's x86 spins use libstdc++.r4.so (for binary compat?), but - # other spins, like x86-64, use a more standard "libstdc++.so.*" - as_ac_File=`$as_echo "ac_cv_file_"/boot/system/lib/libstdc++.r4.so"" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for \"/boot/system/lib/libstdc++.r4.so\"" >&5 -$as_echo_n "checking for \"/boot/system/lib/libstdc++.r4.so\"... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r ""/boot/system/lib/libstdc++.r4.so""; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lstdc++.r4" -else - EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lstdc++" -fi - ;; - arm*-apple-darwin*|*-ios-*) + *-ios-*) ARCH=ios CheckVisibilityHidden + CheckWerror + CheckNoErrorDeprecatedDeclarationsWerror CheckDeclarationAfterStatement CheckDummyVideo + CheckOffscreenVideo CheckDiskAudio CheckDummyAudio CheckDLOPEN + CheckO_CLOEXEC CheckMETAL CheckVulkan CheckPTHREAD + # Set up files for the misc library + if test x$enable_misc = xyes; then + SOURCES="$SOURCES $srcdir/src/misc/ios/*.m" + have_misc=yes + fi + # Set up files for the locale library + if test x$enable_locale = xyes; then + SOURCES="$SOURCES $srcdir/src/locale/macosx/*.m" + have_locale=yes + fi # Set up files for the audio library if test x$enable_audio = xyes; then -$as_echo "#define SDL_AUDIO_DRIVER_COREAUDIO 1" >>confdefs.h +printf "%s\n" "#define SDL_AUDIO_DRIVER_COREAUDIO 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/audio/coreaudio/*.m" SUMMARY_audio="${SUMMARY_audio} coreaudio" @@ -25097,11 +29167,14 @@ $as_echo "#define SDL_AUDIO_DRIVER_COREAUDIO 1" >>confdefs.h # Set up files for the joystick library if test x$enable_joystick = xyes; then -$as_echo "#define SDL_JOYSTICK_MFI 1" >>confdefs.h +printf "%s\n" "#define SDL_JOYSTICK_MFI 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/joystick/iphoneos/*.m" SOURCES="$SOURCES $srcdir/src/joystick/steam/*.c" have_joystick=yes + else + # Need this code for accelerometer as joystick support + SOURCES="$SOURCES $srcdir/src/joystick/iphoneos/*.m" fi # Set up files for the haptic library #if test x$enable_haptic = xyes; then @@ -25112,7 +29185,7 @@ $as_echo "#define SDL_JOYSTICK_MFI 1" >>confdefs.h # Set up files for the sensor library if test x$enable_sensor = xyes; then -$as_echo "#define SDL_SENSOR_COREMOTION 1" >>confdefs.h +printf "%s\n" "#define SDL_SENSOR_COREMOTION 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/sensor/coremotion/*.m" have_sensor=yes @@ -25120,7 +29193,7 @@ $as_echo "#define SDL_SENSOR_COREMOTION 1" >>confdefs.h # Set up files for the power library if test x$enable_power = xyes; then -$as_echo "#define SDL_POWER_UIKIT 1" >>confdefs.h +printf "%s\n" "#define SDL_POWER_UIKIT 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/power/uikit/*.m" have_power=yes @@ -25133,14 +29206,14 @@ $as_echo "#define SDL_POWER_UIKIT 1" >>confdefs.h # Set up additional files for the file library if test x$enable_file = xyes; then -$as_echo "#define SDL_FILESYSTEM_COCOA 1" >>confdefs.h +printf "%s\n" "#define SDL_FILESYSTEM_COCOA 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/file/cocoa/*.m" fi # Set up files for the timer library if test x$enable_timers = xyes; then -$as_echo "#define SDL_TIMER_UNIX 1" >>confdefs.h +printf "%s\n" "#define SDL_TIMER_UNIX 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/timer/unix/*.c" have_timers=yes @@ -25149,22 +29222,28 @@ $as_echo "#define SDL_TIMER_UNIX 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/core/unix/*.c" # The iOS platform requires special setup. -$as_echo "#define SDL_VIDEO_DRIVER_UIKIT 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_DRIVER_UIKIT 1" >>confdefs.h -$as_echo "#define SDL_VIDEO_OPENGL_ES2 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_OPENGL_ES2 1" >>confdefs.h -$as_echo "#define SDL_VIDEO_OPENGL_ES 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_OPENGL_ES 1" >>confdefs.h -$as_echo "#define SDL_VIDEO_RENDER_OGL_ES 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_RENDER_OGL_ES 1" >>confdefs.h -$as_echo "#define SDL_VIDEO_RENDER_OGL_ES2 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_RENDER_OGL_ES2 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/video/uikit/*.m" - EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lm -liconv -lobjc" + SUMMARY_video="${SUMMARY_video} uikit" + have_video=yes + EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lm" + if test x$enable_system_iconv = xyes; then + EXTRA_LDFLAGS="$EXTRA_LDFLAGS -liconv" + fi + EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lobjc" EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,AVFoundation" EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,AudioToolbox" EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,CoreAudio" @@ -25190,26 +29269,42 @@ $as_echo "#define SDL_VIDEO_RENDER_OGL_ES2 1" >>confdefs.h EXTRA_CFLAGS="$EXTRA_CFLAGS -DTARGET_API_MAC_CARBON" EXTRA_CFLAGS="$EXTRA_CFLAGS -DTARGET_API_MAC_OSX" + CheckObjectiveCARC CheckVisibilityHidden + CheckWerror + CheckNoErrorDeprecatedDeclarationsWerror CheckDeclarationAfterStatement CheckDummyVideo + CheckOffscreenVideo CheckDiskAudio CheckDummyAudio CheckDLOPEN + CheckO_CLOEXEC CheckCOCOA CheckMETAL CheckX11 CheckMacGL CheckMacGLES - CheckOpenGLX11 + CheckGLX + CheckOpenGL CheckVulkan CheckPTHREAD CheckHIDAPI + # Set up files for the misc library + if test x$enable_misc = xyes; then + SOURCES="$SOURCES $srcdir/src/misc/macosx/*.m" + have_misc=yes + fi + # Set up files for the locale library + if test x$enable_locale = xyes; then + SOURCES="$SOURCES $srcdir/src/locale/macosx/*.m" + have_locale=yes + fi # Set up files for the audio library if test x$enable_audio = xyes; then -$as_echo "#define SDL_AUDIO_DRIVER_COREAUDIO 1" >>confdefs.h +printf "%s\n" "#define SDL_AUDIO_DRIVER_COREAUDIO 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/audio/coreaudio/*.m" EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,CoreAudio -Wl,-framework,AudioToolbox" @@ -25219,15 +29314,17 @@ $as_echo "#define SDL_AUDIO_DRIVER_COREAUDIO 1" >>confdefs.h # Set up files for the joystick library if test x$enable_joystick = xyes; then -$as_echo "#define SDL_JOYSTICK_IOKIT 1" >>confdefs.h +printf "%s\n" "#define SDL_JOYSTICK_IOKIT 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/joystick/darwin/*.c" + SOURCES="$SOURCES $srcdir/src/joystick/iphoneos/*.m" + CheckJoystickMFI have_joystick=yes fi # Set up files for the haptic library if test x$enable_haptic = xyes; then -$as_echo "#define SDL_HAPTIC_IOKIT 1" >>confdefs.h +printf "%s\n" "#define SDL_HAPTIC_IOKIT 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/haptic/darwin/*.c" EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,ForceFeedback" @@ -25236,7 +29333,7 @@ $as_echo "#define SDL_HAPTIC_IOKIT 1" >>confdefs.h # Set up files for the power library if test x$enable_power = xyes; then -$as_echo "#define SDL_POWER_MACOSX 1" >>confdefs.h +printf "%s\n" "#define SDL_POWER_MACOSX 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/power/macosx/*.c" have_power=yes @@ -25244,7 +29341,7 @@ $as_echo "#define SDL_POWER_MACOSX 1" >>confdefs.h # Set up files for the filesystem library if test x$enable_filesystem = xyes; then -$as_echo "#define SDL_FILESYSTEM_COCOA 1" >>confdefs.h +printf "%s\n" "#define SDL_FILESYSTEM_COCOA 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/filesystem/cocoa/*.m" have_filesystem=yes @@ -25252,7 +29349,7 @@ $as_echo "#define SDL_FILESYSTEM_COCOA 1" >>confdefs.h # Set up files for the timer library if test x$enable_timers = xyes; then -$as_echo "#define SDL_TIMER_UNIX 1" >>confdefs.h +printf "%s\n" "#define SDL_TIMER_UNIX 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/timer/unix/*.c" have_timers=yes @@ -25279,13 +29376,15 @@ $as_echo "#define SDL_TIMER_UNIX 1" >>confdefs.h CheckNativeClient CheckDummyAudio CheckDummyVideo + CheckOffscreenVideo CheckInputEvents CheckPTHREAD + CheckO_CLOEXEC # Set up files for the timer library if test x$enable_timers = xyes; then -$as_echo "#define SDL_TIMER_UNIX 1" >>confdefs.h +printf "%s\n" "#define SDL_TIMER_UNIX 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/timer/unix/*.c" have_timers=yes @@ -25293,7 +29392,7 @@ $as_echo "#define SDL_TIMER_UNIX 1" >>confdefs.h if test x$enable_filesystem = xyes; then -$as_echo "#define SDL_FILESYSTEM_NACL 1" >>confdefs.h +printf "%s\n" "#define SDL_FILESYSTEM_NACL 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/filesystem/nacl/*.c" have_filesystem=yes @@ -25302,7 +29401,7 @@ $as_echo "#define SDL_FILESYSTEM_NACL 1" >>confdefs.h *-*-emscripten* ) if test x$enable_video = xyes; then -$as_echo "#define SDL_VIDEO_DRIVER_EMSCRIPTEN 1" >>confdefs.h +printf "%s\n" "#define SDL_VIDEO_DRIVER_EMSCRIPTEN 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/video/emscripten/*.c" have_video=yes @@ -25311,7 +29410,7 @@ $as_echo "#define SDL_VIDEO_DRIVER_EMSCRIPTEN 1" >>confdefs.h if test x$enable_audio = xyes; then -$as_echo "#define SDL_AUDIO_DRIVER_EMSCRIPTEN 1" >>confdefs.h +printf "%s\n" "#define SDL_AUDIO_DRIVER_EMSCRIPTEN 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/audio/emscripten/*.c" have_audio=yes @@ -25319,27 +29418,36 @@ $as_echo "#define SDL_AUDIO_DRIVER_EMSCRIPTEN 1" >>confdefs.h fi CheckVisibilityHidden + CheckWerror CheckDeclarationAfterStatement CheckDummyVideo + CheckOffscreenVideo CheckDiskAudio CheckDummyAudio + CheckPTHREAD CheckDLOPEN CheckClockGettime CheckEmscriptenGLES + # Set up files for the misc library + if test x$enable_misc = xyes; then + SOURCES="$SOURCES $srcdir/src/misc/emscripten/*.c" + have_misc=yes + fi + # Set up files for the power library if test x$enable_power = xyes; then -$as_echo "#define SDL_POWER_EMSCRIPTEN 1" >>confdefs.h +printf "%s\n" "#define SDL_POWER_EMSCRIPTEN 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/power/emscripten/*.c" have_power=yes fi - # Set up files for the power library + # Set up files for the joystick library if test x$enable_joystick = xyes; then -$as_echo "#define SDL_JOYSTICK_EMSCRIPTEN 1" >>confdefs.h +printf "%s\n" "#define SDL_JOYSTICK_EMSCRIPTEN 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/joystick/emscripten/*.c" have_joystick=yes @@ -25348,7 +29456,7 @@ $as_echo "#define SDL_JOYSTICK_EMSCRIPTEN 1" >>confdefs.h # Set up files for the filesystem library if test x$enable_filesystem = xyes; then -$as_echo "#define SDL_FILESYSTEM_EMSCRIPTEN 1" >>confdefs.h +printf "%s\n" "#define SDL_FILESYSTEM_EMSCRIPTEN 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/filesystem/emscripten/*.c" have_filesystem=yes @@ -25356,33 +29464,157 @@ $as_echo "#define SDL_FILESYSTEM_EMSCRIPTEN 1" >>confdefs.h # Set up files for the timer library if test x$enable_timers = xyes; then -$as_echo "#define SDL_TIMER_UNIX 1" >>confdefs.h +printf "%s\n" "#define SDL_TIMER_UNIX 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/timer/unix/*.c" have_timers=yes fi + # Set up files for the locale library + if test x$enable_locale = xyes; then + SOURCES="$SOURCES $srcdir/src/locale/emscripten/*.c" + have_locale=yes + fi ;; *-*-riscos*) ARCH=riscos CheckVisibilityHidden + CheckWerror CheckDeclarationAfterStatement CheckDummyVideo + CheckOffscreenVideo CheckDiskAudio CheckDummyAudio CheckDLOPEN + CheckO_CLOEXEC CheckOSS CheckPTHREAD CheckClockGettime + # Set up files for the misc library + if test x$enable_misc = xyes; then + SOURCES="$SOURCES $srcdir/src/misc/riscos/*.c" + have_misc=yes + fi + # Set up files for the video library + if test x$enable_video = xyes; then + +printf "%s\n" "#define SDL_VIDEO_DRIVER_RISCOS 1" >>confdefs.h + + SOURCES="$SOURCES $srcdir/src/video/riscos/*.c" + have_video=yes + SUMMARY_video="${SUMMARY_video} riscos" + fi + # Set up files for the filesystem library + if test x$enable_filesystem = xyes; then + +printf "%s\n" "#define SDL_FILESYSTEM_RISCOS 1" >>confdefs.h + + SOURCES="$SOURCES $srcdir/src/filesystem/riscos/*.c" + have_filesystem=yes + fi # Set up files for the timer library if test x$enable_timers = xyes; then -$as_echo "#define SDL_TIMER_UNIX 1" >>confdefs.h +printf "%s\n" "#define SDL_TIMER_UNIX 1" >>confdefs.h SOURCES="$SOURCES $srcdir/src/timer/unix/*.c" have_timers=yes fi ;; + *-*-os2*) + ARCH=os2 + if test "$build" != "$host"; then # cross-compiling + # Default cross-compile location + ac_default_prefix=/@unixroot/usr/local/cross-tools/$host + else + # Look for the location of the tools and install there + if test "$BUILD_PREFIX" != ""; then + ac_default_prefix=$BUILD_PREFIX + fi + fi + enable_static=no # disable static builds + EXTRA_CFLAGS="$EXTRA_CFLAGS -DBUILD_SDL -DOS2EMX_PLAIN_CHAR" + CheckOS2 + CheckWerror + CheckDeclarationAfterStatement + CheckDummyVideo + CheckDiskAudio + CheckDummyAudio + CheckHIDAPI + + # Set up the core platform files + SOURCES="$SOURCES $srcdir/src/core/os2/*.c" + if test x$enable_system_iconv = xyes; then + if test x$ac_cv_func_iconv != xyes -o x$ac_cv_header_iconv_h != xyes; then + SOURCES="$SOURCES $srcdir/src/core/os2/geniconv/*.c" + fi + fi + # Use the Unix locale APIs. + if test x$enable_locale = xyes; then + SOURCES="$SOURCES $srcdir/src/locale/unix/*.c" + have_locale=yes + fi + # Set up files for the video library + if test x$enable_video = xyes; then + +printf "%s\n" "#define SDL_VIDEO_DRIVER_OS2 1" >>confdefs.h + + SOURCES="$SOURCES $srcdir/src/video/os2/*.c" + have_video=yes + SUMMARY_video="${SUMMARY_video} OS/2" + fi + # Set up files for the audio library + if test x$enable_audio = xyes; then + +printf "%s\n" "#define SDL_AUDIO_DRIVER_OS2 1" >>confdefs.h + + SOURCES="$SOURCES $srcdir/src/audio/os2/*.c" + have_audio=yes + SUMMARY_audio="${SUMMARY_audio} OS/2" + EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lmmpm2" + fi + # Set up files for the thread library + if test x$enable_threads = xyes; then + +printf "%s\n" "#define SDL_THREAD_OS2 1" >>confdefs.h + + SOURCES="$SOURCES $srcdir/src/thread/os2/*.c" + SOURCES="$SOURCES $srcdir/src/thread/generic/SDL_syscond.c" + have_threads=yes + fi + # Set up files for the timer library + if test x$enable_timers = xyes; then + +printf "%s\n" "#define SDL_TIMER_OS2 1" >>confdefs.h + + SOURCES="$SOURCES $srcdir/src/timer/os2/*.c" + have_timers=yes + fi + # Set up files for the shared object loading library + if test x$enable_loadso = xyes; then + +printf "%s\n" "#define SDL_LOADSO_OS2 1" >>confdefs.h + + SOURCES="$SOURCES $srcdir/src/loadso/os2/*.c" + have_loadso=yes + fi + # Set up files for the filesystem library + if test x$enable_filesystem = xyes; then + +printf "%s\n" "#define SDL_FILESYSTEM_OS2 1" >>confdefs.h + + SOURCES="$SOURCES $srcdir/src/filesystem/os2/*.c" + have_filesystem=yes + fi + # Set up files for the joystick library + if test x$enable_joystick = xyes; then + +printf "%s\n" "#define SDL_JOYSTICK_OS2 1" >>confdefs.h + + SOURCES="$SOURCES $srcdir/src/joystick/os2/*.c" + have_joystick=yes + fi + ;; *) as_fn_error $? " *** Unsupported host: Please add to configure.ac @@ -25390,36 +29622,86 @@ $as_echo "#define SDL_TIMER_UNIX 1" >>confdefs.h ;; esac +CheckVirtualJoystick + # Check whether to install sdl2-config -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to install sdl2-config" >&5 -$as_echo_n "checking whether to install sdl2-config... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to install sdl2-config" >&5 +printf %s "checking whether to install sdl2-config... " >&6; } # Check whether --enable-sdl2-config was given. -if test "${enable_sdl2_config+set}" = set; then : +if test ${enable_sdl2_config+y} +then : enableval=$enable_sdl2_config; case "${enableval}" in yes) enable_sdl2_config="TRUE" ;; no) enable_sdl2_config="FALSE" ;; *) as_fn_error $? "bad value '${enableval}' for --enable-sdl2-config" "$LINENO" 5 ;; esac -else +else $as_nop enable_sdl2_config="TRUE" fi if test "$enable_sdl2_config" = "TRUE"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi INSTALL_SDL2_CONFIG=$enable_sdl2_config +# Check whether --enable-vendor-info was given. +if test ${enable_vendor_info+y} +then : + enableval=$enable_vendor_info; enable_vendor_info="$enableval" +else $as_nop + enable_vendor_info= +fi + +if test "$enable_vendor_info" = no +then : + enable_vendor_info= +fi +SDL_VENDOR_INFO=$enable_vendor_info + + # Verify that we have all the platform specific files we need +if test x$have_audio != xyes; then + if test x$enable_audio = xyes; then + +printf "%s\n" "#define SDL_AUDIO_DRIVER_DUMMY 1" >>confdefs.h + + fi + SOURCES="$SOURCES $srcdir/src/audio/dummy/*.c" +fi +if test x$have_video != xyes; then + if test x$enable_video = xyes; then + +printf "%s\n" "#define SDL_VIDEO_DRIVER_DUMMY 1" >>confdefs.h + + fi + SOURCES="$SOURCES $srcdir/src/video/dummy/*.c" +fi +if test x$have_misc != xyes; then + if test x$enable_misc = xyes; then + +printf "%s\n" "#define SDL_MISC_DUMMY 1" >>confdefs.h + + fi + SOURCES="$SOURCES $srcdir/src/misc/dummy/*.c" +fi +if test x$have_locale != xyes; then + if test x$enable_locale = xyes; then + +printf "%s\n" "#define SDL_LOCALE_DUMMY 1" >>confdefs.h + + fi + SOURCES="$SOURCES $srcdir/src/locale/dummy/*.c" +fi if test x$have_joystick != xyes; then if test x$enable_joystick = xyes; then -$as_echo "#define SDL_JOYSTICK_DUMMY 1" >>confdefs.h +printf "%s\n" "#define SDL_JOYSTICK_DUMMY 1" >>confdefs.h fi SOURCES="$SOURCES $srcdir/src/joystick/dummy/*.c" @@ -25427,7 +29709,7 @@ fi if test x$have_haptic != xyes; then if test x$enable_haptic = xyes; then -$as_echo "#define SDL_HAPTIC_DUMMY 1" >>confdefs.h +printf "%s\n" "#define SDL_HAPTIC_DUMMY 1" >>confdefs.h fi SOURCES="$SOURCES $srcdir/src/haptic/dummy/*.c" @@ -25435,7 +29717,7 @@ fi if test x$have_sensor != xyes; then if test x$enable_sensor = xyes; then -$as_echo "#define SDL_SENSOR_DUMMY 1" >>confdefs.h +printf "%s\n" "#define SDL_SENSOR_DUMMY 1" >>confdefs.h fi SOURCES="$SOURCES $srcdir/src/sensor/dummy/*.c" @@ -25443,7 +29725,7 @@ fi if test x$have_threads != xyes; then if test x$enable_threads = xyes; then -$as_echo "#define SDL_THREADS_DISABLED 1" >>confdefs.h +printf "%s\n" "#define SDL_THREADS_DISABLED 1" >>confdefs.h fi SOURCES="$SOURCES $srcdir/src/thread/generic/*.c" @@ -25451,7 +29733,7 @@ fi if test x$have_timers != xyes; then if test x$enable_timers = xyes; then -$as_echo "#define SDL_TIMERS_DISABLED 1" >>confdefs.h +printf "%s\n" "#define SDL_TIMER_DUMMY 1" >>confdefs.h fi SOURCES="$SOURCES $srcdir/src/timer/dummy/*.c" @@ -25459,7 +29741,7 @@ fi if test x$have_filesystem != xyes; then if test x$enable_filesystem = xyes; then -$as_echo "#define SDL_FILESYSTEM_DISABLED 1" >>confdefs.h +printf "%s\n" "#define SDL_FILESYSTEM_DUMMY 1" >>confdefs.h fi SOURCES="$SOURCES $srcdir/src/filesystem/dummy/*.c" @@ -25467,7 +29749,7 @@ fi if test x$have_loadso != xyes; then if test x$enable_loadso = xyes; then -$as_echo "#define SDL_LOADSO_DISABLED 1" >>confdefs.h +printf "%s\n" "#define SDL_LOADSO_DUMMY 1" >>confdefs.h fi SOURCES="$SOURCES $srcdir/src/loadso/dummy/*.c" @@ -25478,27 +29760,28 @@ fi SDLTEST_SOURCES="$srcdir/src/test/*.c" if test x$video_wayland = xyes; then - WAYLAND_PROTOCOLS=`cd $srcdir/wayland-protocols ; for p in *.xml ; do echo -n "\$p" |sed 's,\\.xml\$, ,g' ; done` - WAYLAND_PROTOCOLS_SOURCES=`for p in $WAYLAND_PROTOCOLS ; do echo -n "\\$(gen)/\$p-protocol.c " ; done` - WAYLAND_PROTOCOLS_HEADERS=`for p in $WAYLAND_PROTOCOLS ; do echo -n "\\$(gen)/\$p-client-protocol.h " ; done` + WAYLAND_PROTOCOLS=`cd $srcdir/wayland-protocols ; for p in *.xml ; do printf '%s' "\$p" |sed 's,\\.xml\$, ,g' ; done` + WAYLAND_PROTOCOLS_SOURCES=`for p in $WAYLAND_PROTOCOLS ; do printf '%s' "\\$(gen)/\$p-protocol.c " ; done` + WAYLAND_PROTOCOLS_HEADERS=`for p in $WAYLAND_PROTOCOLS ; do printf '%s' "\\$(gen)/\$p-client-protocol.h " ; done` GEN_SOURCES="$GEN_SOURCES $WAYLAND_PROTOCOLS_SOURCES" GEN_HEADERS="$GEN_HEADERS $WAYLAND_PROTOCOLS_HEADERS" WAYLAND_PROTOCOLS_DEPENDS=`for p in $WAYLAND_PROTOCOLS ; do\ echo ;\ - echo "\\$(gen)/\$p-client-protocol.h: \\$(srcdir)/wayland-protocols/\$p.xml" ;\ - echo " @\\$(SHELL) \\$(auxdir)/mkinstalldirs \\$(gen)" ;\ - echo " \\$(RUN_CMD_GEN)\\$(WAYLAND_SCANNER) client-header \\$< \\$@" ;\ + printf '%s\n' "\\$(gen)/\$p-client-protocol.h: \\$(srcdir)/wayland-protocols/\$p.xml" ;\ + printf '%s\n' " @\\$(SHELL) \\$(auxdir)/mkinstalldirs \\$(gen)" ;\ + printf '%s\n' " \\$(RUN_CMD_GEN)\\$(WAYLAND_SCANNER) client-header \\$< \\$@" ;\ echo ;\ - echo "\\$(gen)/\$p-protocol.c: \\$(srcdir)/wayland-protocols/\$p.xml" ;\ - echo " @\\$(SHELL) \\$(auxdir)/mkinstalldirs \\$(gen)" ;\ - echo " \\$(RUN_CMD_GEN)\\$(WAYLAND_SCANNER) code \\$< \\$@" ;\ + printf '%s\n' "\\$(gen)/\$p-protocol.c: \\$(srcdir)/wayland-protocols/\$p.xml" ;\ + printf '%s\n' " @\\$(SHELL) \\$(auxdir)/mkinstalldirs \\$(gen)" ;\ + printf '%s\n' " \\$(RUN_CMD_GEN)\\$(WAYLAND_SCANNER) \\$(WAYLAND_SCANNER_CODE_MODE) \\$< \\$@" ;\ echo ;\ - echo "\\$(objects)/\$p-protocol.lo: \\$(gen)/\$p-protocol.c \\$(gen)/\$p-client-protocol.h" ;\ - echo " \\$(RUN_CMD_CC)\\$(LIBTOOL) --tag=CC --mode=compile \\$(CC) \\$(CFLAGS) \\$(EXTRA_CFLAGS) $DEPENDENCY_TRACKING_OPTIONS -c \\$< -o \\$@" ;\ + printf '%s\n' "\\$(objects)/\$p-protocol.lo: \\$(gen)/\$p-protocol.c \\$(gen)/\$p-client-protocol.h" ;\ + printf '%s\n' " @\\$(SHELL) \\$(auxdir)/mkinstalldirs \\$(objects)" ;\ + printf '%s\n' " \\$(RUN_CMD_CC)\\$(LIBTOOL) --tag=CC --mode=compile \\$(CC) \\$(CFLAGS) \\$(EXTRA_CFLAGS) $DEPENDENCY_TRACKING_OPTIONS -c \\$< -o \\$@" ;\ done ;\ echo ;\ - for s in $WAYLAND_SOURCES ; do echo -n "\$s:" ; for p in $WAYLAND_PROTOCOLS ; do echo -n " \\$(gen)/\$p-client-protocol.h" ; done ; echo ; done ; echo` + for s in $WAYLAND_SOURCES ; do printf '%s' "\$s:" ; printf ' \$(gen)/%s-client-protocol.h' $WAYLAND_PROTOCOLS ; echo ; done ; echo` fi OBJECTS=`echo $SOURCES` @@ -25514,10 +29797,10 @@ GEN_OBJECTS=`echo "$GEN_SOURCES" | sed 's,[^ ]*/\([^ ]*\)\.c,$(objects)/\1.lo,g' VERSION_OBJECTS=`echo $VERSION_SOURCES` VERSION_DEPENDS=`echo $VERSION_SOURCES` -VERSION_OBJECTS=`echo "$VERSION_OBJECTS" | sed 's,[^ ]*/\([^ ]*\)\.rc,$(objects)/\1.o,g'` +VERSION_OBJECTS=`echo "$VERSION_OBJECTS" | sed 's,[^ ]*/\([^ ]*\)\.rc,$(objects)/\1.lo,g'` VERSION_DEPENDS=`echo "$VERSION_DEPENDS" | sed "s,\\([^ ]*\\)/\\([^ ]*\\)\\.rc,\\\\ -\\$(objects)/\\2.o: \\1/\\2.rc \\$(objects)/.created\\\\ - \\$(WINDRES) \\$< \\$@,g"` +\\$(objects)/\\2.lo: \\1/\\2.rc \\$(objects)/.created\\\\ + \\$(RUN_CMD_RC)\\$(LIBTOOL) --mode=compile --tag=RC \\$(RC) -i \\$< -o \\$@,g"` SDLMAIN_OBJECTS=`echo $SDLMAIN_SOURCES` SDLMAIN_DEPENDS=`echo $SDLMAIN_SOURCES` @@ -25535,39 +29818,38 @@ SDLTEST_DEPENDS=`echo "$SDLTEST_DEPENDS" | sed "s,\\([^ ]*\\)/\\([^ ]*\\)\\.c,\\ # Set runtime shared library paths as needed -if test "x$enable_rpath" = "xyes"; then +if test "x$enable_rpath" = "xyes" -a "x$enable_shared" = "xyes"; then if test $ARCH = bsdi -o $ARCH = freebsd -o $ARCH = linux -o $ARCH = netbsd; then SDL_RLD_FLAGS="-Wl,-rpath,\${libdir}" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for linker option --enable-new-dtags" >&5 -$as_echo_n "checking for linker option --enable-new-dtags... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for linker option --enable-new-dtags" >&5 +printf %s "checking for linker option --enable-new-dtags... " >&6; } have_enable_new_dtags=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -Wl,--enable-new-dtags" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - int -main () +main (void) { - ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : have_enable_new_dtags=yes SDL_RLD_FLAGS="$SDL_RLD_FLAGS -Wl,--enable-new-dtags" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_enable_new_dtags" >&5 -$as_echo "$have_enable_new_dtags" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_enable_new_dtags" >&5 +printf "%s\n" "$have_enable_new_dtags" >&6; } fi if test $ARCH = solaris; then SDL_RLD_FLAGS="-R\${libdir}" @@ -25576,16 +29858,117 @@ else SDL_RLD_FLAGS="" fi -SDL_STATIC_LIBS="$SDL_LIBS $EXTRA_LDFLAGS" +SDL_STATIC_LIBS="$EXTRA_LDFLAGS" + +pkg_cmakedir='$libdir/cmake/SDL2' +for _lcl_i in pkg_cmakedir:prefix:cmake_prefix_relpath bindir:prefix:bin_prefix_relpath; do + _lcl_from=\$`echo "$_lcl_i" | sed 's,:.*$,,'` + _lcl_to=\$`echo "$_lcl_i" | sed 's,^[^:]*:,,' | sed 's,:[^:]*$,,'` + _lcl_result_var=`echo "$_lcl_i" | sed 's,^.*:,,'` + _lcl_receval="$_lcl_from" +_lcl_from=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix" + test "x$exec_prefix" = xNONE && exec_prefix="${prefix}" + _lcl_receval_old='' + while test "$_lcl_receval_old" != "$_lcl_receval"; do + _lcl_receval_old="$_lcl_receval" + eval _lcl_receval="\"$_lcl_receval\"" + done + echo "$_lcl_receval")` + _lcl_receval="$_lcl_to" +_lcl_to=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix" + test "x$exec_prefix" = xNONE && exec_prefix="${prefix}" + _lcl_receval_old='' + while test "$_lcl_receval_old" != "$_lcl_receval"; do + _lcl_receval_old="$_lcl_receval" + eval _lcl_receval="\"$_lcl_receval\"" + done + echo "$_lcl_receval")` + _lcl_notation="$_lcl_from$_lcl_to" + case ":$_lcl_from:" in +# change empty paths to '.' + ::) _lcl_from='.' ;; +# strip trailing slashes + :*[\\/]:) _lcl_from=`echo "$_lcl_from" | sed 's,[\\/]*$,,'` ;; + :*:) ;; +esac +# squeeze repeated slashes +case '/' in +# if the path contains any backslashes, turn slashes into backslashes + *\\*) _lcl_from=`echo "$_lcl_from" | sed 's,\(.\)[\\/][\\/]*,\1\\\\,g'` ;; +# if the path contains slashes, also turn backslashes into slashes + *) _lcl_from=`echo "$_lcl_from" | sed 's,\(.\)[\\/][\\/]*,\1/,g'` ;; +esac + case ":$_lcl_to:" in +# change empty paths to '.' + ::) _lcl_to='.' ;; +# strip trailing slashes + :*[\\/]:) _lcl_to=`echo "$_lcl_to" | sed 's,[\\/]*$,,'` ;; + :*:) ;; +esac +# squeeze repeated slashes +case '/' in +# if the path contains any backslashes, turn slashes into backslashes + *\\*) _lcl_to=`echo "$_lcl_to" | sed 's,\(.\)[\\/][\\/]*,\1\\\\,g'` ;; +# if the path contains slashes, also turn backslashes into slashes + *) _lcl_to=`echo "$_lcl_to" | sed 's,\(.\)[\\/][\\/]*,\1/,g'` ;; +esac + _lcl_common_prefix='' +_lcl_second_prefix_match='' +while test "$_lcl_second_prefix_match" != 0; do + _lcl_first_prefix=`expr "x$_lcl_from" : "x\($_lcl_common_prefix/*[^/]*\)"` + _lcl_second_prefix_match=`expr "x$_lcl_to" : "x$_lcl_first_prefix"` + if test "$_lcl_second_prefix_match" != 0; then + if test "$_lcl_first_prefix" != "$_lcl_common_prefix"; then + _lcl_common_prefix="$_lcl_first_prefix" + else + _lcl_second_prefix_match=0 + fi + fi +done +_lcl_first_suffix=`expr "x$_lcl_from" : "x$_lcl_common_prefix/*\(.*\)"` +_lcl_first_rel='' +_lcl_tmp='xxx' +while test "$_lcl_tmp" != ''; do + _lcl_tmp=`expr "x$_lcl_first_suffix" : "x[^/]*/*\(.*\)"` + if test "$_lcl_first_suffix" != ''; then + _lcl_first_suffix="$_lcl_tmp" + _lcl_first_rel="../$_lcl_first_rel" + fi +done +_lcl_second_suffix=`expr "x$_lcl_to" : "x$_lcl_common_prefix/*\(.*\)"` +_lcl_result_tmp="$_lcl_first_rel$_lcl_second_suffix" + case ":$_lcl_result_tmp:" in +# change empty paths to '.' + ::) _lcl_result_tmp='.' ;; +# strip trailing slashes + :*[\\/]:) _lcl_result_tmp=`echo "$_lcl_result_tmp" | sed 's,[\\/]*$,,'` ;; + :*:) ;; +esac +# squeeze repeated slashes +case "$_lcl_notation" in +# if the path contains any backslashes, turn slashes into backslashes + *\\*) _lcl_result_tmp=`echo "$_lcl_result_tmp" | sed 's,\(.\)[\\/][\\/]*,\1\\\\,g'` ;; +# if the path contains slashes, also turn backslashes into slashes + *) _lcl_result_tmp=`echo "$_lcl_result_tmp" | sed 's,\(.\)[\\/][\\/]*,\1/,g'` ;; +esac + eval $_lcl_result_var='$_lcl_result_tmp' +done + + +PKGCONFIG_DEPENDS="" + if test x$enable_shared = xyes; then + PKGCONFIG_LIBS_PRIV=" +Libs.private:" ENABLE_SHARED_TRUE= ENABLE_SHARED_FALSE="#" else + PKGCONFIG_LIBS_PRIV= ENABLE_SHARED_TRUE="#" ENABLE_SHARED_FALSE= fi @@ -25615,6 +29998,7 @@ fi + cat >Makefile.rules <<__EOF__ @@ -25650,6 +30034,11 @@ if test x$have_x = xyes; then SUMMARY="${SUMMARY}X11 libraries :${SUMMARY_video_x11}\n" fi SUMMARY="${SUMMARY}Input drivers :${SUMMARY_input}\n" +if test x$have_joystick_virtual = xyes; then + SUMMARY="${SUMMARY}Enable virtual joystick APIs : YES\n" +else + SUMMARY="${SUMMARY}Enable virtual joystick APIs : NO\n" +fi if test x$have_samplerate_h_hdr = xyes; then SUMMARY="${SUMMARY}Using libsamplerate : YES\n" else @@ -25675,7 +30064,7 @@ if test x$have_ibus_ibus_h_hdr = xyes; then else SUMMARY="${SUMMARY}Using ibus : NO\n" fi -if test x$have_fcitx_frontend_h_hdr = xyes; then +if test x$have_fcitx = xyes; then SUMMARY="${SUMMARY}Using fcitx : YES\n" else SUMMARY="${SUMMARY}Using fcitx : NO\n" @@ -25688,7 +30077,6 @@ if test x$WARN_ABOUT_ARM_SIMD_ASM_MIT = xyes; then SUMMARY="${SUMMARY}configure script with:\n" SUMMARY="${SUMMARY}\n --disable-arm-simd\n" fi - if test x$WARN_ABOUT_ARM_NEON_ASM_MIT = xyes; then SUMMARY="${SUMMARY}\nSDL is being built with ARM NEON optimizations, which\n" SUMMARY="${SUMMARY}uses code licensed under the MIT license. If this is a\n" @@ -25727,8 +30115,8 @@ _ACEOF case $ac_val in #( *${as_nl}*) case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( @@ -25758,15 +30146,15 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; /^ac_cv_env_/b end t clear :clear - s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + s/^\([^=]*\)=\(.*[{}].*\)$/test ${\1+y} || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 -$as_echo "$as_me: updating cache $cache_file" >&6;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +printf "%s\n" "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else @@ -25780,8 +30168,8 @@ $as_echo "$as_me: updating cache $cache_file" >&6;} fi fi else - { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 -$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +printf "%s\n" "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache @@ -25798,7 +30186,7 @@ U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' - ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + ac_i=`printf "%s\n" "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" @@ -25814,8 +30202,8 @@ LTLIBOBJS=$ac_ltlibobjs ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" -{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 -$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +printf "%s\n" "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL @@ -25838,14 +30226,16 @@ cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : +as_nop=: +if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 +then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST -else +else $as_nop case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( @@ -25855,46 +30245,46 @@ esac fi + +# Reset variables that may have inherited troublesome values from +# the environment. + +# IFS needs to be set, to space, tab, and newline, in precisely that order. +# (If _AS_PATH_WALK were called with IFS unset, it would have the +# side effect of setting IFS to empty, thus disabling word splitting.) +# Quoting is to prevent editors from complaining about space-tab. as_nl=' ' export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi +IFS=" "" $as_nl" + +PS1='$ ' +PS2='> ' +PS4='+ ' + +# Ensure predictable behavior from utilities with locale-dependent output. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# We cannot yet rely on "unset" to work, but we need these variables +# to be unset--not just set to an empty or harmless value--now, to +# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct +# also avoids known problems related to "unset" and subshell syntax +# in other old shells (e.g. bash 2.01 and pdksh 5.2.14). +for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH +do eval test \${$as_var+y} \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done + +# Ensure that fds 0, 1, and 2 are open. +if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi +if (exec 3>&2) ; then :; else exec 2>/dev/null; fi # The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then +if ${PATH_SEPARATOR+false} :; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || @@ -25903,13 +30293,6 @@ if test "${PATH_SEPARATOR+set}" != set; then fi -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( @@ -25918,8 +30301,12 @@ case $0 in #(( for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + test -r "$as_dir$0" && as_myself=$as_dir$0 && break done IFS=$as_save_IFS @@ -25931,30 +30318,10 @@ if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] @@ -25967,13 +30334,14 @@ as_fn_error () as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi - $as_echo "$as_me: error: $2" >&2 + printf "%s\n" "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error + # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. @@ -26000,18 +30368,20 @@ as_fn_unset () { eval $1=; unset $1;} } as_unset=as_fn_unset + # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null +then : eval 'as_fn_append () { eval $1+=\$2 }' -else +else $as_nop as_fn_append () { eval $1=\$$1\$2 @@ -26023,12 +30393,13 @@ fi # as_fn_append # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null +then : eval 'as_fn_arith () { as_val=$(( $* )) }' -else +else $as_nop as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` @@ -26059,7 +30430,7 @@ as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | +printf "%s\n" X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q @@ -26081,6 +30452,10 @@ as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits + +# Determine whether it's possible to make 'echo' print without a newline. +# These variables are no longer used directly by Autoconf, but are AC_SUBSTed +# for compatibility with existing Makefiles. ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) @@ -26094,6 +30469,12 @@ case `echo -n x` in #((((( ECHO_N='-n';; esac +# For backward compatibility with old third-party macros, we provide +# the shell variables $as_echo and $as_echo_n. New code should use +# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. +as_echo='printf %s\n' +as_echo_n='printf %s' + rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file @@ -26135,7 +30516,7 @@ as_fn_mkdir_p () as_dirs= while :; do case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" @@ -26144,7 +30525,7 @@ $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | +printf "%s\n" X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q @@ -26207,7 +30588,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # values after options handling. ac_log=" This file was extended by $as_me, which was -generated by GNU Autoconf 2.69. Invocation command line was +generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -26269,14 +30650,16 @@ $config_commands Report bugs to the package provider." _ACEOF +ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"` +ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\''/g"` cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ config.status -configured by $0, generated by GNU Autoconf 2.69, +configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" -Copyright (C) 2012 Free Software Foundation, Inc. +Copyright (C) 2021 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." @@ -26315,15 +30698,15 @@ do -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) - $as_echo "$ac_cs_version"; exit ;; + printf "%s\n" "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) - $as_echo "$ac_cs_config"; exit ;; + printf "%s\n" "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" @@ -26331,7 +30714,7 @@ do --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; @@ -26340,7 +30723,7 @@ do as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) - $as_echo "$ac_cs_usage"; exit ;; + printf "%s\n" "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; @@ -26368,7 +30751,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift - \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + \printf "%s\n" "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" @@ -26382,7 +30765,7 @@ exec 5>>config.log sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX - $as_echo "$ac_log" + printf "%s\n" "$ac_log" } >&5 _ACEOF @@ -26408,6 +30791,7 @@ enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' +shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`' SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' @@ -26455,10 +30839,13 @@ compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' +lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`' nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' +lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`' objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' @@ -26523,7 +30910,8 @@ finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' -sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' +configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`' +configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`' hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' @@ -26536,53 +30924,101 @@ postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`' predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`' postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`' compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`' +LD_RC='`$ECHO "$LD_RC" | $SED "$delay_single_quote_subst"`' LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`' +reload_flag_RC='`$ECHO "$reload_flag_RC" | $SED "$delay_single_quote_subst"`' reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`' +reload_cmds_RC='`$ECHO "$reload_cmds_RC" | $SED "$delay_single_quote_subst"`' reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_cmds_RC='`$ECHO "$old_archive_cmds_RC" | $SED "$delay_single_quote_subst"`' old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' +compiler_RC='`$ECHO "$compiler_RC" | $SED "$delay_single_quote_subst"`' compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`' +GCC_RC='`$ECHO "$GCC_RC" | $SED "$delay_single_quote_subst"`' GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag_RC='`$ECHO "$lt_prog_compiler_no_builtin_flag_RC" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic_RC='`$ECHO "$lt_prog_compiler_pic_RC" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl_RC='`$ECHO "$lt_prog_compiler_wl_RC" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static_RC='`$ECHO "$lt_prog_compiler_static_RC" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o_RC='`$ECHO "$lt_cv_prog_compiler_c_o_RC" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc_RC='`$ECHO "$archive_cmds_need_lc_RC" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes_RC='`$ECHO "$enable_shared_with_static_runtimes_RC" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec_RC='`$ECHO "$export_dynamic_flag_spec_RC" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec_RC='`$ECHO "$whole_archive_flag_spec_RC" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +compiler_needs_object_RC='`$ECHO "$compiler_needs_object_RC" | $SED "$delay_single_quote_subst"`' compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds_RC='`$ECHO "$old_archive_from_new_cmds_RC" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds_RC='`$ECHO "$old_archive_from_expsyms_cmds_RC" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`' +archive_cmds_RC='`$ECHO "$archive_cmds_RC" | $SED "$delay_single_quote_subst"`' archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds_RC='`$ECHO "$archive_expsym_cmds_RC" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' +module_cmds_RC='`$ECHO "$module_cmds_RC" | $SED "$delay_single_quote_subst"`' module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds_RC='`$ECHO "$module_expsym_cmds_RC" | $SED "$delay_single_quote_subst"`' module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' +with_gnu_ld_RC='`$ECHO "$with_gnu_ld_RC" | $SED "$delay_single_quote_subst"`' with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag_RC='`$ECHO "$allow_undefined_flag_RC" | $SED "$delay_single_quote_subst"`' allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' +no_undefined_flag_RC='`$ECHO "$no_undefined_flag_RC" | $SED "$delay_single_quote_subst"`' no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec_RC='`$ECHO "$hardcode_libdir_flag_spec_RC" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator_RC='`$ECHO "$hardcode_libdir_separator_RC" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_direct_RC='`$ECHO "$hardcode_direct_RC" | $SED "$delay_single_quote_subst"`' hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute_RC='`$ECHO "$hardcode_direct_absolute_RC" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L_RC='`$ECHO "$hardcode_minus_L_RC" | $SED "$delay_single_quote_subst"`' hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var_RC='`$ECHO "$hardcode_shlibpath_var_RC" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_automatic_RC='`$ECHO "$hardcode_automatic_RC" | $SED "$delay_single_quote_subst"`' hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`' +inherit_rpath_RC='`$ECHO "$inherit_rpath_RC" | $SED "$delay_single_quote_subst"`' inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`' +link_all_deplibs_RC='`$ECHO "$link_all_deplibs_RC" | $SED "$delay_single_quote_subst"`' link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`' +always_export_symbols_RC='`$ECHO "$always_export_symbols_RC" | $SED "$delay_single_quote_subst"`' always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds_RC='`$ECHO "$export_symbols_cmds_RC" | $SED "$delay_single_quote_subst"`' export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`' +exclude_expsyms_RC='`$ECHO "$exclude_expsyms_RC" | $SED "$delay_single_quote_subst"`' exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`' +include_expsyms_RC='`$ECHO "$include_expsyms_RC" | $SED "$delay_single_quote_subst"`' include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`' +prelink_cmds_RC='`$ECHO "$prelink_cmds_RC" | $SED "$delay_single_quote_subst"`' prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`' +postlink_cmds_RC='`$ECHO "$postlink_cmds_RC" | $SED "$delay_single_quote_subst"`' postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`' +file_list_spec_RC='`$ECHO "$file_list_spec_RC" | $SED "$delay_single_quote_subst"`' file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`' +hardcode_action_RC='`$ECHO "$hardcode_action_RC" | $SED "$delay_single_quote_subst"`' hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_dirs_RC='`$ECHO "$compiler_lib_search_dirs_RC" | $SED "$delay_single_quote_subst"`' compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`' +predep_objects_RC='`$ECHO "$predep_objects_RC" | $SED "$delay_single_quote_subst"`' predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`' +postdep_objects_RC='`$ECHO "$postdep_objects_RC" | $SED "$delay_single_quote_subst"`' postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`' +predeps_RC='`$ECHO "$predeps_RC" | $SED "$delay_single_quote_subst"`' predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`' +postdeps_RC='`$ECHO "$postdeps_RC" | $SED "$delay_single_quote_subst"`' postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`' +compiler_lib_search_path_RC='`$ECHO "$compiler_lib_search_path_RC" | $SED "$delay_single_quote_subst"`' compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`' LTCC='$LTCC' @@ -26629,9 +31065,12 @@ CFLAGS \ compiler \ lt_cv_sys_global_symbol_pipe \ lt_cv_sys_global_symbol_to_cdecl \ +lt_cv_sys_global_symbol_to_import \ lt_cv_sys_global_symbol_to_c_name_address \ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ +lt_cv_nm_interface \ nm_file_list_spec \ +lt_cv_truncate_bin \ lt_prog_compiler_no_builtin_flag \ lt_prog_compiler_pic \ lt_prog_compiler_wl \ @@ -26670,34 +31109,59 @@ postdep_objects \ predeps \ postdeps \ compiler_lib_search_path \ +LD_RC \ LD_CXX \ +reload_flag_RC \ reload_flag_CXX \ +compiler_RC \ compiler_CXX \ +lt_prog_compiler_no_builtin_flag_RC \ lt_prog_compiler_no_builtin_flag_CXX \ +lt_prog_compiler_pic_RC \ lt_prog_compiler_pic_CXX \ +lt_prog_compiler_wl_RC \ lt_prog_compiler_wl_CXX \ +lt_prog_compiler_static_RC \ lt_prog_compiler_static_CXX \ +lt_cv_prog_compiler_c_o_RC \ lt_cv_prog_compiler_c_o_CXX \ +export_dynamic_flag_spec_RC \ export_dynamic_flag_spec_CXX \ +whole_archive_flag_spec_RC \ whole_archive_flag_spec_CXX \ +compiler_needs_object_RC \ compiler_needs_object_CXX \ +with_gnu_ld_RC \ with_gnu_ld_CXX \ +allow_undefined_flag_RC \ allow_undefined_flag_CXX \ +no_undefined_flag_RC \ no_undefined_flag_CXX \ +hardcode_libdir_flag_spec_RC \ hardcode_libdir_flag_spec_CXX \ +hardcode_libdir_separator_RC \ hardcode_libdir_separator_CXX \ +exclude_expsyms_RC \ exclude_expsyms_CXX \ +include_expsyms_RC \ include_expsyms_CXX \ +file_list_spec_RC \ file_list_spec_CXX \ +compiler_lib_search_dirs_RC \ compiler_lib_search_dirs_CXX \ +predep_objects_RC \ predep_objects_CXX \ +postdep_objects_RC \ postdep_objects_CXX \ +predeps_RC \ predeps_CXX \ +postdeps_RC \ postdeps_CXX \ +compiler_lib_search_path_RC \ compiler_lib_search_path_CXX; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" @@ -26724,21 +31188,33 @@ postinstall_cmds \ postuninstall_cmds \ finish_cmds \ sys_lib_search_path_spec \ -sys_lib_dlsearch_path_spec \ +configure_time_dlsearch_path \ +configure_time_lt_sys_library_path \ +reload_cmds_RC \ reload_cmds_CXX \ +old_archive_cmds_RC \ old_archive_cmds_CXX \ +old_archive_from_new_cmds_RC \ old_archive_from_new_cmds_CXX \ +old_archive_from_expsyms_cmds_RC \ old_archive_from_expsyms_cmds_CXX \ +archive_cmds_RC \ archive_cmds_CXX \ +archive_expsym_cmds_RC \ archive_expsym_cmds_CXX \ +module_cmds_RC \ module_cmds_CXX \ +module_expsym_cmds_RC \ module_expsym_cmds_CXX \ +export_symbols_cmds_RC \ export_symbols_cmds_CXX \ +prelink_cmds_RC \ prelink_cmds_CXX \ +postlink_cmds_RC \ postlink_cmds_CXX; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" @@ -26747,19 +31223,16 @@ postlink_cmds_CXX; do done ac_aux_dir='$ac_aux_dir' -xsi_shell='$xsi_shell' -lt_shell_append='$lt_shell_append' -# See if we are running on zsh, and set the options which allow our +# See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes INIT. -if test -n "\${ZSH_VERSION+set}" ; then +if test -n "\${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi PACKAGE='$PACKAGE' VERSION='$VERSION' - TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile' @@ -26767,6 +31240,8 @@ fi + + SUMMARY="$SUMMARY" _ACEOF @@ -26798,9 +31273,9 @@ done # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then - test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files - test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers - test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands + test ${CONFIG_FILES+y} || CONFIG_FILES=$config_files + test ${CONFIG_HEADERS+y} || CONFIG_HEADERS=$config_headers + test ${CONFIG_COMMANDS+y} || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree @@ -27136,7 +31611,7 @@ do esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac - case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + case $ac_f in *\'*) ac_f=`printf "%s\n" "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done @@ -27144,17 +31619,17 @@ do # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` - $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" - { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 -$as_echo "$as_me: creating $ac_file" >&6;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +printf "%s\n" "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) - ac_sed_conf_input=`$as_echo "$configure_input" | + ac_sed_conf_input=`printf "%s\n" "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac @@ -27171,7 +31646,7 @@ $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$ac_file" | +printf "%s\n" X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q @@ -27195,9 +31670,9 @@ $as_echo X"$ac_file" | case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; @@ -27254,8 +31729,8 @@ ac_sed_dataroot=' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 -$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +printf "%s\n" "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' @@ -27298,9 +31773,9 @@ test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 -$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +printf "%s\n" "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" @@ -27316,27 +31791,27 @@ which seems to be undefined. Please make sure it is defined" >&2;} # if test x"$ac_file" != x-; then { - $as_echo "/* $configure_input */" \ + printf "%s\n" "/* $configure_input */" >&1 \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then - { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 -$as_echo "$as_me: $ac_file is unchanged" >&6;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +printf "%s\n" "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else - $as_echo "/* $configure_input */" \ + printf "%s\n" "/* $configure_input */" >&1 \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi ;; - :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 -$as_echo "$as_me: executing $ac_file commands" >&6;} + :C) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +printf "%s\n" "$as_me: executing $ac_file commands" >&6;} ;; esac @@ -27344,55 +31819,53 @@ $as_echo "$as_me: executing $ac_file commands" >&6;} case $ac_file$ac_mode in "libtool":C) - # See if we are running on zsh, and set the options which allow our + # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes. - if test -n "${ZSH_VERSION+set}" ; then + if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi - cfgfile="${ofile}T" + cfgfile=${ofile}T trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL - -# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. -# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION +# Generated automatically by $as_me ($PACKAGE) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. + +# Provide generalized library-building support services. +# Written by Gordon Matzigkeit, 1996 + +# Copyright (C) 2014 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# GNU Libtool is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of of the License, or +# (at your option) any later version. # -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, -# 2006, 2007, 2008, 2009, 2010, 2011 Free Software -# Foundation, Inc. -# Written by Gordon Matzigkeit, 1996 +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program or library that is built +# using GNU Libtool, you may include this file under the same +# distribution terms that you use for the rest of that program. # -# This file is part of GNU Libtool. -# -# GNU Libtool is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# As a special exception to the GNU General Public License, -# if you distribute this file as part of a program or library that -# is built using GNU Libtool, you may include this file under the -# same distribution terms that you use for the rest of that program. -# -# GNU Libtool is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of +# GNU Libtool is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with GNU Libtool; see the file COPYING. If not, a copy -# can be downloaded from http://www.gnu.org/licenses/gpl.html, or -# obtained by writing to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# along with this program. If not, see . # The names of the tagged configurations supported by this script. -available_tags="CXX " +available_tags='RC CXX ' + +# Configured defaults for sys_lib_dlsearch_path munging. +: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} # ### BEGIN LIBTOOL CONFIG @@ -27421,6 +31894,9 @@ pic_mode=$pic_mode # Whether or not to optimize for fast installation. fast_install=$enable_fast_install +# Shared archive member basename,for filename based shared library versioning on AIX. +shared_archive_member_spec=$shared_archive_member_spec + # Shell to use when invoking shell scripts. SHELL=$lt_SHELL @@ -27532,18 +32008,27 @@ global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration. global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl +# Transform the output of nm into a list of symbols to manually relocate. +global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import + # Transform the output of nm in a C name address pair. global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # Transform the output of nm in a C name address pair when lib prefix is needed. global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix +# The name lister interface. +nm_interface=$lt_lt_cv_nm_interface + # Specify filename containing input files for \$NM. nm_file_list_spec=$lt_nm_file_list_spec -# The root where to search for dependent libraries,and in which our libraries should be installed. +# The root where to search for dependent libraries,and where our libraries should be installed. lt_sysroot=$lt_sysroot +# Command to truncate a binary pipe. +lt_truncate_bin=$lt_lt_cv_truncate_bin + # The name of the directory that contains temporary libtool files. objdir=$objdir @@ -27634,8 +32119,11 @@ hardcode_into_libs=$hardcode_into_libs # Compile-time system search path for libraries. sys_lib_search_path_spec=$lt_sys_lib_search_path_spec -# Run-time system search path for libraries. -sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec +# Detected run-time system search path for libraries. +sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path + +# Explicit LT_SYS_LIBRARY_PATH set during ./configure time. +configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path # Whether dlopen is supported. dlopen_support=$enable_dlopen @@ -27728,13 +32216,13 @@ hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator -# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct -# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary and the resulting library dependency is -# "absolute",i.e impossible to change by setting \${shlibpath_var} if the +# "absolute",i.e impossible to change by setting \$shlibpath_var if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute @@ -27798,6 +32286,65 @@ compiler_lib_search_path=$lt_compiler_lib_search_path # ### END LIBTOOL CONFIG +_LT_EOF + + cat <<'_LT_EOF' >> "$cfgfile" + +# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE + +# func_munge_path_list VARIABLE PATH +# ----------------------------------- +# VARIABLE is name of variable containing _space_ separated list of +# directories to be munged by the contents of PATH, which is string +# having a format: +# "DIR[:DIR]:" +# string "DIR[ DIR]" will be prepended to VARIABLE +# ":DIR[:DIR]" +# string "DIR[ DIR]" will be appended to VARIABLE +# "DIRP[:DIRP]::[DIRA:]DIRA" +# string "DIRP[ DIRP]" will be prepended to VARIABLE and string +# "DIRA[ DIRA]" will be appended to VARIABLE +# "DIR[:DIR]" +# VARIABLE will be replaced by "DIR[ DIR]" +func_munge_path_list () +{ + case x$2 in + x) + ;; + *:) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" + ;; + x:*) + eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" + ;; + *::*) + eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" + eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" + ;; + *) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" + ;; + esac +} + + +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +func_cc_basename () +{ + for cc_temp in $*""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac + done + func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +} + + +# ### END FUNCTIONS SHARED WITH CONFIGURE + _LT_EOF case $host_os in @@ -27806,7 +32353,7 @@ _LT_EOF # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. -if test "X${COLLECT_NAMES+set}" != Xset; then +if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi @@ -27815,7 +32362,8 @@ _LT_EOF esac -ltmain="$ac_aux_dir/ltmain.sh" + +ltmain=$ac_aux_dir/ltmain.sh # We use sed instead of cat because bash on DJGPP gets confused if @@ -27825,170 +32373,164 @@ ltmain="$ac_aux_dir/ltmain.sh" sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) - if test x"$xsi_shell" = xyes; then - sed -e '/^func_dirname ()$/,/^} # func_dirname /c\ -func_dirname ()\ -{\ -\ case ${1} in\ -\ */*) func_dirname_result="${1%/*}${2}" ;;\ -\ * ) func_dirname_result="${3}" ;;\ -\ esac\ -} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_basename ()$/,/^} # func_basename /c\ -func_basename ()\ -{\ -\ func_basename_result="${1##*/}"\ -} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\ -func_dirname_and_basename ()\ -{\ -\ case ${1} in\ -\ */*) func_dirname_result="${1%/*}${2}" ;;\ -\ * ) func_dirname_result="${3}" ;;\ -\ esac\ -\ func_basename_result="${1##*/}"\ -} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_stripname ()$/,/^} # func_stripname /c\ -func_stripname ()\ -{\ -\ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\ -\ # positional parameters, so assign one to ordinary parameter first.\ -\ func_stripname_result=${3}\ -\ func_stripname_result=${func_stripname_result#"${1}"}\ -\ func_stripname_result=${func_stripname_result%"${2}"}\ -} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\ -func_split_long_opt ()\ -{\ -\ func_split_long_opt_name=${1%%=*}\ -\ func_split_long_opt_arg=${1#*=}\ -} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\ -func_split_short_opt ()\ -{\ -\ func_split_short_opt_arg=${1#??}\ -\ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\ -} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\ -func_lo2o ()\ -{\ -\ case ${1} in\ -\ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\ -\ *) func_lo2o_result=${1} ;;\ -\ esac\ -} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_xform ()$/,/^} # func_xform /c\ -func_xform ()\ -{\ - func_xform_result=${1%.*}.lo\ -} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_arith ()$/,/^} # func_arith /c\ -func_arith ()\ -{\ - func_arith_result=$(( $* ))\ -} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_len ()$/,/^} # func_len /c\ -func_len ()\ -{\ - func_len_result=${#1}\ -} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - -fi - -if test x"$lt_shell_append" = xyes; then - sed -e '/^func_append ()$/,/^} # func_append /c\ -func_append ()\ -{\ - eval "${1}+=\\${2}"\ -} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\ -func_append_quoted ()\ -{\ -\ func_quote_for_eval "${2}"\ -\ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\ -} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - # Save a `func_append' function call where possible by direct use of '+=' - sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") - test 0 -eq $? || _lt_function_replace_fail=: -else - # Save a `func_append' function call even when '+=' is not available - sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") - test 0 -eq $? || _lt_function_replace_fail=: -fi - -if test x"$_lt_function_replace_fail" = x":"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5 -$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;} -fi - - mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" + cat <<_LT_EOF >> "$ofile" + +# ### BEGIN LIBTOOL TAG CONFIG: RC + +# The linker used to build libraries. +LD=$lt_LD_RC + +# How to create reloadable object files. +reload_flag=$lt_reload_flag_RC +reload_cmds=$lt_reload_cmds_RC + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds_RC + +# A language specific compiler. +CC=$lt_compiler_RC + +# Is the compiler the GNU compiler? +with_gcc=$GCC_RC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_RC + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic_RC + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl_RC + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static_RC + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o_RC + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc_RC + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_RC + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_RC + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec_RC + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object_RC + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_RC + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_RC + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds_RC +archive_expsym_cmds=$lt_archive_expsym_cmds_RC + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds_RC +module_expsym_cmds=$lt_module_expsym_cmds_RC + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld_RC + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag_RC + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag_RC + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_RC + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator_RC + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct_RC + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \$shlibpath_var if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute_RC + +# Set to "yes" if using the -LDIR flag during linking hardcodes DIR +# into the resulting binary. +hardcode_minus_L=$hardcode_minus_L_RC + +# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR +# into the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var_RC + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic_RC + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath_RC + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs_RC + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols_RC + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds_RC + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms_RC + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms_RC + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds_RC + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds_RC + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec_RC + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action_RC + +# The directories searched by this compiler when creating a shared library. +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_RC + +# Dependencies to place before and after the objects being linked to +# create a shared library. +predep_objects=$lt_predep_objects_RC +postdep_objects=$lt_postdep_objects_RC +predeps=$lt_predeps_RC +postdeps=$lt_postdeps_RC + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_compiler_lib_search_path_RC + +# ### END LIBTOOL TAG CONFIG: RC +_LT_EOF + + cat <<_LT_EOF >> "$ofile" # ### BEGIN LIBTOOL TAG CONFIG: CXX @@ -28070,13 +32612,13 @@ hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX -# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct_CXX -# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary and the resulting library dependency is -# "absolute",i.e impossible to change by setting \${shlibpath_var} if the +# "absolute",i.e impossible to change by setting \$shlibpath_var if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute_CXX @@ -28143,7 +32685,7 @@ _LT_EOF ;; "sdl2_config":C) chmod a+x sdl2-config ;; - "summary":C) echo -en "$SUMMARY" ;; + "summary":C) printf "$SUMMARY" ;; esac done # for ac_tag @@ -28178,7 +32720,8 @@ if test "$no_create" != yes; then $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 -$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi + diff --git a/SDL2-2.0.12/configure.ac b/SDL2-2.30.5/configure.ac similarity index 68% rename from SDL2-2.0.12/configure.ac rename to SDL2-2.30.5/configure.ac index 19361a4..907d1d0 100644 --- a/SDL2-2.0.12/configure.ac +++ b/SDL2-2.30.5/configure.ac @@ -1,30 +1,30 @@ dnl Process this file with autoconf to produce a configure script. -AC_INIT(README.txt) -AC_CONFIG_HEADER(include/SDL_config.h) -AC_CONFIG_AUX_DIR(build-scripts) +AC_PREREQ([2.65]) +AC_INIT +AC_CONFIG_SRCDIR([src/SDL.c]) +AC_CONFIG_HEADERS([include/SDL_config.h]) +AC_CONFIG_AUX_DIR([build-scripts]) AC_CONFIG_MACRO_DIR([acinclude]) dnl Save the CFLAGS to see whether they were passed in or generated orig_CFLAGS="$CFLAGS" dnl Set various version strings - taken gratefully from the GTk sources -# -# Making releases: -# Edit include/SDL_version.h and change the version, then: -# SDL_MICRO_VERSION += 1; -# SDL_INTERFACE_AGE += 1; -# SDL_BINARY_AGE += 1; -# if any functions have been added, set SDL_INTERFACE_AGE to 0. -# if backwards compatibility has been broken, -# set SDL_BINARY_AGE and SDL_INTERFACE_AGE to 0. -# +# See docs/release_checklist.md SDL_MAJOR_VERSION=2 -SDL_MINOR_VERSION=0 -SDL_MICRO_VERSION=12 -SDL_INTERFACE_AGE=0 -SDL_BINARY_AGE=12 +SDL_MINOR_VERSION=30 +SDL_MICRO_VERSION=5 SDL_VERSION=$SDL_MAJOR_VERSION.$SDL_MINOR_VERSION.$SDL_MICRO_VERSION +SDL_BINARY_AGE=`expr $SDL_MINOR_VERSION \* 100 + $SDL_MICRO_VERSION` +AS_CASE(["$SDL_MINOR_VERSION"], + [*@<:@02468@:>@], + dnl Stable branch, 2.24.1 -> libSDL2-2.0.so.0.2400.1 + [SDL_INTERFACE_AGE="$SDL_MICRO_VERSION"], + [*], + dnl Development branch, 2.23.1 -> libSDL2-2.0.so.0.2301.0 + [SDL_INTERFACE_AGE=0]) + AC_SUBST(SDL_MAJOR_VERSION) AC_SUBST(SDL_MINOR_VERSION) AC_SUBST(SDL_MICRO_VERSION) @@ -34,11 +34,19 @@ AC_SUBST(SDL_VERSION) # libtool versioning LT_INIT([win32-dll]) +LT_LANG([Windows Resource]) -LT_RELEASE=$SDL_MAJOR_VERSION.$SDL_MINOR_VERSION -LT_CURRENT=`expr $SDL_MICRO_VERSION - $SDL_INTERFACE_AGE` -LT_REVISION=$SDL_INTERFACE_AGE +# For historical reasons, the library name redundantly includes the major +# version twice: libSDL2-2.0.so.0. +# TODO: in SDL 3, stop using -release, which will simplify it to libSDL3.so.0 +LT_RELEASE=2.0 +# Increment this if there is an incompatible change - but if that happens, +# we should rename the library from SDL2 to SDL3, at which point this would +# reset to 0 anyway. +LT_MAJOR=0 LT_AGE=`expr $SDL_BINARY_AGE - $SDL_INTERFACE_AGE` +LT_CURRENT=`expr $LT_MAJOR + $LT_AGE` +LT_REVISION=$SDL_INTERFACE_AGE m4_pattern_allow([^LT_]) AC_SUBST(LT_RELEASE) @@ -50,17 +58,28 @@ dnl Detect the canonical build and host environments dnl AC_CANONICAL_HOST dnl Check for tools -AC_PROG_LIBTOOL +AC_PROG_AWK AC_PROG_CC AC_PROG_CXX +AC_PROG_EGREP +AC_PROG_FGREP AC_PROG_INSTALL AC_PROG_MAKE_SET -AC_CHECK_TOOL(WINDRES, [windres], [:]) PKG_PROG_PKG_CONFIG +if [ test -z "$AWK" ]; then + AC_MSG_ERROR([*** awk not found, aborting]) +fi + +AC_CHECK_PROGS([SORT], [gsort sort], [false]) +AS_IF([! "$SORT" -V /dev/null], [AC_MSG_WARN([sort(1) that supports the -V option is required to find dynamic libraries])]) + +dnl 64-bit file offsets if possible unless --disable-largefile is specified +AC_SYS_LARGEFILE + dnl Make sure that srcdir is a full pathname case "$host" in - *-*-mingw32*) + *-*-mingw*) # Except on msys, where make can't handle full pathnames (bug 1972) ;; *) @@ -69,12 +88,36 @@ case "$host" in esac dnl Set up the compiler and linker flags -INCLUDE="-I$srcdir/include -idirafter $srcdir/src/video/khronos" +INCLUDE="-I$srcdir/include" + +dnl Don't use our khronos headers on QNX. +case "$host" in + *-*-nto-qnx*) + ;; + *) + INCLUDE="$INCLUDE -idirafter $srcdir/src/video/khronos" + ;; +esac + +dnl use CXX for linker on Haiku +case "$host" in + *-*-haiku*) + LINKER='$(CXX)' + LIBTOOLLINKERTAG='CXX' + ;; + *) + LINKER='$(CC)' + LIBTOOLLINKERTAG='CC' + ;; +esac +AC_SUBST(LINKER) +AC_SUBST(LIBTOOLLINKERTAG) + if test x$srcdir != x.; then INCLUDE="-Iinclude $INCLUDE" -elif test -d .hg; then +elif test -d .git; then AC_MSG_ERROR([ -*** When building from Mercurial you should configure and build in a +*** When building from a git clone you should configure and build in a separate directory so you don't clobber SDL_config.h, SDL_revision.h ]) fi @@ -88,11 +131,7 @@ case "$host" in AC_MSG_CHECKING(for GCC -mno-cygwin option) CFLAGS="$save_CFLAGS -mno-cygwin" - AC_TRY_COMPILE([ - ],[ - ],[ - have_no_cygwin=yes - ]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[])], [have_no_cygwin=yes],[]) AC_MSG_RESULT($have_no_cygwin) CFLAGS="$save_CFLAGS" @@ -142,8 +181,8 @@ base_libdir=`echo \${libdir} | sed 's/.*\/\(.*\)/\1/; q'` dnl Function to find a library in the compiler search path find_lib() { - gcc_bin_path=[`$CC -print-search-dirs 2>/dev/null | fgrep programs: | sed 's/[^=]*=\(.*\)/\1/' | sed 's/:/ /g'`] - gcc_lib_path=[`$CC -print-search-dirs 2>/dev/null | fgrep libraries: | sed 's/[^=]*=\(.*\)/\1/' | sed 's/:/ /g'`] + gcc_bin_path=[`$CC -print-search-dirs 2>/dev/null | $FGREP programs: | sed 's/[^=]*=\(.*\)/\1/' | sed 's/:/ /g'`] + gcc_lib_path=[`$CC -print-search-dirs 2>/dev/null | $FGREP libraries: | sed 's/[^=]*=\(.*\)/\1/' | sed 's/:/ /g'`] env_lib_path=[`echo $LIBS $LDFLAGS $* | sed 's/-L[ ]*//g'`] if test "$cross_compiling" = yes; then host_lib_path="" @@ -151,15 +190,7 @@ find_lib() host_lib_path="/usr/$base_libdir /usr/local/$base_libdir" fi for path in $env_lib_path $gcc_bin_path $gcc_lib_path $host_lib_path; do - lib=[`ls -- $path/$1 2>/dev/null | sed -e '/\.so\..*\./d' -e 's,.*/,,' | sort | tail -1`] - if test x$lib != x; then - echo $lib - return - fi - done - # Try again, this time allowing more than one version digit after the .so - for path in $env_lib_path $gcc_bin_path $gcc_lib_path $host_lib_path; do - lib=[`ls -- $path/$1 2>/dev/null | sed -e 's,.*/,,' | sort | tail -1`] + lib=[`ls -- $path/$1 2>/dev/null | sed 's,.*/,,' | "$SORT" -V -r | $AWK 'BEGIN{FS="."}{ print NF, $0 }' | "$SORT" -n -s | sed 's,[0-9]* ,,' | head -1`] if test x$lib != x; then echo $lib return @@ -174,8 +205,8 @@ AC_C_VOLATILE dnl See whether we want assertions for debugging/sanity checking SDL itself. AC_ARG_ENABLE(assertions, -AS_HELP_STRING([--enable-assertions], - [Enable internal sanity checks (auto/disabled/release/enabled/paranoid) [[default=auto]]]), +[AS_HELP_STRING([--enable-assertions], + [Enable internal sanity checks (auto/disabled/release/enabled/paranoid) [default=auto]])], , enable_assertions=auto) case "$enable_assertions" in auto) # Use optimization settings to determine assertion level @@ -197,22 +228,22 @@ case "$enable_assertions" in ;; esac +dnl For use in static assertions +EXTRA_CFLAGS="$EXTRA_CFLAGS -DSDL_BUILD_MAJOR_VERSION=$SDL_MAJOR_VERSION -DSDL_BUILD_MINOR_VERSION=$SDL_MINOR_VERSION -DSDL_BUILD_MICRO_VERSION=$SDL_MICRO_VERSION" + dnl See whether we can use gcc style dependency tracking AC_ARG_ENABLE(dependency-tracking, -AS_HELP_STRING([--enable-dependency-tracking], - [Use gcc -MMD -MT dependency tracking [[default=yes]]]), +[AS_HELP_STRING([--enable-dependency-tracking], + [Use gcc -MMD -MT dependency tracking [default=yes]])], , enable_dependency_tracking=yes) if test x$enable_dependency_tracking = xyes; then have_gcc_mmd_mt=no AC_MSG_CHECKING(for GCC -MMD -MT option) - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #if !defined(__GNUC__) || __GNUC__ < 3 #error Dependency tracking requires GCC 3.0 or newer #endif - ],[ - ],[ - have_gcc_mmd_mt=yes - ]) + ]],[])], [have_gcc_mmd_mt=yes],[]) AC_MSG_RESULT($have_gcc_mmd_mt) if test x$have_gcc_mmd_mt = xyes; then @@ -223,19 +254,16 @@ fi AC_MSG_CHECKING(for linker option --no-undefined) have_no_undefined=no case "$host" in - dnl Skip this on platforms where it is just simply busted. +dnl Skip this on platforms where it is just simply busted. *-*-openbsd*) ;; - *) save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -Wl,--no-undefined" - AC_TRY_LINK([ - ],[ - ],[ + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [ have_no_undefined=yes - EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,--no-undefined" - ]) + BUILD_LDFLAGS="$BUILD_LDFLAGS -Wl,--no-undefined" + ],[]) LDFLAGS="$save_LDFLAGS" ;; esac @@ -247,12 +275,10 @@ case "$host" in *) save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -Wl,--dynamicbase" - AC_TRY_LINK([ - ],[ - ],[ + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [ have_dynamicbase=yes EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,--dynamicbase" - ]) + ],[]) LDFLAGS="$save_LDFLAGS" ;; esac @@ -264,12 +290,10 @@ case "$host" in *) save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -Wl,--nxcompat" - AC_TRY_LINK([ - ],[ - ],[ + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [ have_nxcompat=yes EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,--nxcompat" - ]) + ],[]) LDFLAGS="$save_LDFLAGS" ;; esac @@ -281,12 +305,10 @@ case "$host" in *) save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -Wl,--high-entropy-va" - AC_TRY_LINK([ - ],[ - ],[ + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [ have_high_entropy_va=yes EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,--high-entropy-va" - ]) + ],[]) LDFLAGS="$save_LDFLAGS" ;; esac @@ -294,58 +316,100 @@ AC_MSG_RESULT($have_high_entropy_va) dnl See whether we are allowed to use the system C library AC_ARG_ENABLE(libc, -AS_HELP_STRING([--enable-libc], [Use the system C library [[default=yes]]]), +[AS_HELP_STRING([--enable-libc], [Use the system C library [default=yes]])], , enable_libc=yes) + +dnl See whether we are allowed to use system iconv +enable_system_iconv_default=yes +case "$host" in + *-*-cygwin*|*-*-mingw*|*-*-darwin*|*-ios-*) + enable_system_iconv_default=no + ;; +esac +AC_ARG_ENABLE(system-iconv, +[AS_HELP_STRING([--enable-system-iconv], [Use iconv() from system-installed libraries [default=no for windows, yes for others]])], + , enable_system_iconv=$enable_system_iconv_default) +dnl See whether we prefer libiconv over libc +AC_ARG_ENABLE(libiconv, +[AS_HELP_STRING([--enable-libiconv], [Prefer iconv() from libiconv, if available, over libc version [default=no]])], + , enable_libiconv=no) + if test x$enable_libc = xyes; then AC_DEFINE(HAVE_LIBC, 1, [ ]) - dnl Check for C library headers - AC_HEADER_STDC +dnl Check for C library headers +dnl AC_CHECK_INCLUDES_DEFAULT is an autoconf-2.7x thing where AC_HEADER_STDC is deprecated. + m4_ifdef([AC_CHECK_INCLUDES_DEFAULT], [AC_CHECK_INCLUDES_DEFAULT], [AC_HEADER_STDC]) AC_CHECK_HEADERS(sys/types.h stdio.h stdlib.h stddef.h stdarg.h malloc.h memory.h string.h strings.h wchar.h inttypes.h stdint.h limits.h ctype.h math.h float.h iconv.h signal.h) - dnl Check for typedefs, structures, etc. +dnl Check for typedefs, structures, etc. AC_TYPE_SIZE_T - dnl Check for defines +dnl Check for defines AC_CHECK_DEFINE(M_PI, math.h) - dnl Checks for library functions. - case "$host" in - *-*-cygwin* | *-*-mingw32*) - ;; - *) - AC_FUNC_ALLOCA - ;; - esac + AC_FUNC_ALLOCA - AC_FUNC_MEMCMP - if test x$ac_cv_func_memcmp_working = xyes; then - AC_DEFINE(HAVE_MEMCMP, 1, [ ]) - fi - AC_FUNC_STRTOD - if test x$ac_cv_func_strtod = xyes; then - AC_DEFINE(HAVE_STRTOD, 1, [ ]) - fi +dnl Checks for library functions. AC_CHECK_FUNC(mprotect, - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include - ],[ - ],[ + ]],[])], [ AC_DEFINE(HAVE_MPROTECT, 1, [ ]) - ]), + ],[]), ) - AC_CHECK_FUNCS(malloc calloc realloc free getenv setenv putenv unsetenv qsort abs bcopy memset memcpy memmove wcslen wcslcpy wcslcat wcsdup wcsstr wcscmp wcsncmp strlen strlcpy strlcat _strrev _strupr _strlwr strchr strrchr strstr strtok_r 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 _Exit) + AC_CHECK_FUNCS(malloc calloc realloc free getenv setenv putenv unsetenv bsearch qsort abs bcopy memset memcmp memcpy memmove wcslen wcslcpy wcslcat _wcsdup wcsdup wcsstr wcscmp wcsncmp wcscasecmp _wcsicmp wcsncasecmp _wcsnicmp strlen strlcpy strlcat _strrev _strupr _strlwr index rindex strchr strrchr strstr strtok_r itoa _ltoa _uitoa _ultoa strtod strtol strtoul _i64toa _ui64toa strtoll strtoull atoi atof strcmp strncmp _stricmp strcasecmp _strnicmp strncasecmp strcasestr vsscanf vsnprintf fopen64 fseeko fseeko64 sigaction setjmp nanosleep sysconf sysctlbyname getauxval elf_aux_info poll memfd_create posix_fallocate _Exit) AC_CHECK_LIB(m, pow, [LIBS="$LIBS -lm"; EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lm"]) - AC_CHECK_FUNCS(acos acosf asin asinf atan atanf atan2 atan2f ceil ceilf copysign copysignf cos cosf exp expf fabs fabsf floor floorf fmod fmodf log logf log10 log10f pow powf scalbn scalbnf sin sinf sqrt sqrtf tan tanf) + AC_CHECK_FUNCS(acos acosf asin asinf atan atanf atan2 atan2f ceil ceilf copysign copysignf cos cosf exp expf fabs fabsf floor floorf trunc truncf fmod fmodf log logf log10 log10f lround lroundf pow powf round roundf scalbn scalbnf sin sinf sqrt sqrtf tan tanf) - AC_CHECK_LIB(iconv, iconv_open, [LIBS="$LIBS -liconv"; EXTRA_LDFLAGS="$EXTRA_LDFLAGS -liconv"]) - AC_CHECK_FUNCS(iconv) + if test x$enable_system_iconv = xyes; then + AC_MSG_CHECKING(for iconv in libc) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + #define LIBICONV_PLUG 1 /* in case libiconv header is in include path */ + #include + #include + ]],[[ + iconv_open(NULL,NULL); + ]])], [have_libc_iconv=yes],[have_libc_iconv=no]) + AC_MSG_RESULT($have_libc_iconv) + + AC_MSG_CHECKING(for iconv in libiconv) + save_LIBS="$LIBS" + LIBS="$LIBS -liconv" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + #include + #include + ]],[[ + iconv_open(NULL,NULL); + ]])], [have_libiconv=yes],[have_libiconv=no]) + LIBS="$save_LIBS" + AC_MSG_RESULT($have_libiconv) + + if test x$have_libc_iconv = xyes || test x$have_libiconv = xyes; then + AC_DEFINE(HAVE_ICONV,1,[ ]) + + if test x$have_libiconv = xyes; then + if test x$have_libc_iconv != xyes; then + use_libiconv=yes + elif test x$enable_libiconv = xyes; then + use_libiconv=yes + fi + fi + if test x$use_libiconv = xyes; then + AC_DEFINE(SDL_USE_LIBICONV,1,[ ]) + EXTRA_LDFLAGS="$EXTRA_LDFLAGS -liconv" + echo "-- Using iconv from libiconv" + else + echo "-- Using iconv from libc" + fi + fi + fi AC_CHECK_MEMBER(struct sigaction.sa_sigaction,[AC_DEFINE([HAVE_SA_SIGACTION], 1, [ ])], ,[#include ]) - dnl Check for additional non-standard headers +dnl Check for additional non-standard headers AC_CHECK_HEADERS(libunwind.h) fi @@ -353,14 +417,13 @@ dnl AC_CHECK_SIZEOF(void*) dnl See whether we can use gcc atomic operations on this architecture AC_ARG_ENABLE(gcc-atomics, -AS_HELP_STRING([--enable-gcc-atomics], - [Use gcc builtin atomics [[default=yes]]]), +[AS_HELP_STRING([--enable-gcc-atomics], + [Use gcc builtin atomics [default=yes]])], , enable_gcc_atomics=yes) if test x$enable_gcc_atomics = xyes; then have_gcc_atomics=no AC_MSG_CHECKING(for GCC builtin atomic operations) - AC_TRY_LINK([ - ],[ + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[[ int a; void *x, *y, *z; __sync_lock_test_and_set(&a, 4); @@ -368,23 +431,19 @@ if test x$enable_gcc_atomics = xyes; then __sync_fetch_and_add(&a, 1); __sync_bool_compare_and_swap(&a, 5, 10); __sync_bool_compare_and_swap(&x, y, z); - ],[ - have_gcc_atomics=yes - ]) + ]])], + [have_gcc_atomics=yes],[]) AC_MSG_RESULT($have_gcc_atomics) if test x$have_gcc_atomics = xyes; then AC_DEFINE(HAVE_GCC_ATOMICS, 1, [ ]) else # See if we have the minimum operation needed for GCC atomics - AC_TRY_LINK([ - ],[ + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[[ int a; __sync_lock_test_and_set(&a, 1); __sync_lock_release(&a); - ],[ - have_gcc_sync_lock_test_and_set=yes - ]) + ]])], [have_gcc_sync_lock_test_and_set=yes],[]) if test x$have_gcc_sync_lock_test_and_set = xyes; then AC_DEFINE(HAVE_GCC_SYNC_LOCK_TEST_AND_SET, 1, [ ]) fi @@ -400,8 +459,10 @@ SOURCES="$SOURCES $srcdir/src/dynapi/*.c" SOURCES="$SOURCES $srcdir/src/events/*.c" SOURCES="$SOURCES $srcdir/src/file/*.c" SOURCES="$SOURCES $srcdir/src/haptic/*.c" +SOURCES="$SOURCES $srcdir/src/hidapi/*.c" SOURCES="$SOURCES $srcdir/src/joystick/*.c" SOURCES="$SOURCES $srcdir/src/libm/*.c" +SOURCES="$SOURCES $srcdir/src/misc/*.c" SOURCES="$SOURCES $srcdir/src/power/*.c" #SOURCES="$SOURCES $srcdir/src/filesystem/*.c" SOURCES="$SOURCES $srcdir/src/render/*.c" @@ -412,19 +473,29 @@ SOURCES="$SOURCES $srcdir/src/thread/*.c" SOURCES="$SOURCES $srcdir/src/timer/*.c" SOURCES="$SOURCES $srcdir/src/video/*.c" SOURCES="$SOURCES $srcdir/src/video/yuv2rgb/*.c" +SOURCES="$SOURCES $srcdir/src/locale/*.c" dnl Enable/disable various subsystems of the SDL library +case "$host" in + *-*-emscripten*) + default_atomic=no + ;; + *) + default_atomic=yes + ;; +esac + AC_ARG_ENABLE(atomic, -AS_HELP_STRING([--enable-atomic], [Enable the atomic operations subsystem [[default=yes]]]), - , enable_atomic=yes) +[AS_HELP_STRING([--enable-atomic], [Enable the atomic operations subsystem [default=yes]])], + , enable_atomic=$default_atomic) if test x$enable_atomic != xyes; then AC_DEFINE(SDL_ATOMIC_DISABLED, 1, [ ]) else SUMMARY_modules="${SUMMARY_modules} atomic" fi AC_ARG_ENABLE(audio, -AS_HELP_STRING([--enable-audio], [Enable the audio subsystem [[default=yes]]]), +[AS_HELP_STRING([--enable-audio], [Enable the audio subsystem [default=yes]])], , enable_audio=yes) if test x$enable_audio != xyes; then AC_DEFINE(SDL_AUDIO_DISABLED, 1, [ ]) @@ -432,7 +503,7 @@ else SUMMARY_modules="${SUMMARY_modules} audio" fi AC_ARG_ENABLE(video, -AS_HELP_STRING([--enable-video], [Enable the video subsystem [[default=yes]]]), +[AS_HELP_STRING([--enable-video], [Enable the video subsystem [default=yes]])], , enable_video=yes) if test x$enable_video != xyes; then AC_DEFINE(SDL_VIDEO_DISABLED, 1, [ ]) @@ -440,7 +511,7 @@ else SUMMARY_modules="${SUMMARY_modules} video" fi AC_ARG_ENABLE(render, -AS_HELP_STRING([--enable-render], [Enable the render subsystem [[default=yes]]]), +[AS_HELP_STRING([--enable-render], [Enable the render subsystem [default=yes]])], , enable_render=yes) if test x$enable_render != xyes; then AC_DEFINE(SDL_RENDER_DISABLED, 1, [ ]) @@ -448,7 +519,7 @@ else SUMMARY_modules="${SUMMARY_modules} render" fi AC_ARG_ENABLE(events, -AS_HELP_STRING([--enable-events], [Enable the events subsystem [[default=yes]]]), +[AS_HELP_STRING([--enable-events], [Enable the events subsystem [default=yes]])], , enable_events=yes) if test x$enable_events != xyes; then AC_DEFINE(SDL_EVENTS_DISABLED, 1, [ ]) @@ -456,7 +527,7 @@ else SUMMARY_modules="${SUMMARY_modules} events" fi AC_ARG_ENABLE(joystick, -AS_HELP_STRING([--enable-joystick], [Enable the joystick subsystem [[default=yes]]]), +[AS_HELP_STRING([--enable-joystick], [Enable the joystick subsystem [default=yes]])], , enable_joystick=yes) if test x$enable_joystick != xyes; then AC_DEFINE(SDL_JOYSTICK_DISABLED, 1, [ ]) @@ -464,15 +535,23 @@ else SUMMARY_modules="${SUMMARY_modules} joystick" fi AC_ARG_ENABLE(haptic, -AS_HELP_STRING([--enable-haptic], [Enable the haptic (force feedback) subsystem [[default=yes]]]), +[AS_HELP_STRING([--enable-haptic], [Enable the haptic (force feedback) subsystem [default=yes]])], , enable_haptic=yes) if test x$enable_haptic != xyes; then AC_DEFINE(SDL_HAPTIC_DISABLED, 1, [ ]) else SUMMARY_modules="${SUMMARY_modules} haptic" fi +AC_ARG_ENABLE(hidapi, +[AS_HELP_STRING([--enable-hidapi], [Enable the HIDAPI subsystem [default=yes]])], + , enable_hidapi=yes) +if test x$enable_hidapi != xyes; then + AC_DEFINE(SDL_HIDAPI_DISABLED, 1, [ ]) +else + SUMMARY_modules="${SUMMARY_modules} hidapi" +fi AC_ARG_ENABLE(sensor, -AS_HELP_STRING([--enable-sensor], [Enable the sensor subsystem [[default=yes]]]), +[AS_HELP_STRING([--enable-sensor], [Enable the sensor subsystem [default=yes]])], , enable_sensor=yes) if test x$enable_sensor != xyes; then AC_DEFINE(SDL_SENSOR_DISABLED, 1, [ ]) @@ -480,7 +559,7 @@ else SUMMARY_modules="${SUMMARY_modules} sensor" fi AC_ARG_ENABLE(power, -AS_HELP_STRING([--enable-power], [Enable the power subsystem [[default=yes]]]), +[AS_HELP_STRING([--enable-power], [Enable the power subsystem [default=yes]])], , enable_power=yes) if test x$enable_power != xyes; then AC_DEFINE(SDL_POWER_DISABLED, 1, [ ]) @@ -488,23 +567,25 @@ else SUMMARY_modules="${SUMMARY_modules} power" fi AC_ARG_ENABLE(filesystem, -AS_HELP_STRING([--enable-filesystem], [Enable the filesystem subsystem [[default=yes]]]), +[AS_HELP_STRING([--enable-filesystem], [Enable the filesystem subsystem [default=yes]])], , enable_filesystem=yes) if test x$enable_filesystem != xyes; then AC_DEFINE(SDL_FILESYSTEM_DISABLED, 1, [ ]) else SUMMARY_modules="${SUMMARY_modules} filesystem" fi -AC_ARG_ENABLE(threads, -AS_HELP_STRING([--enable-threads], [Enable the threading subsystem [[default=yes]]]), - , enable_threads=yes) +# Many subsystems depend on threads, so leave them enabled by default +#AC_ARG_ENABLE(threads, +#[AS_HELP_STRING([--enable-threads], [Enable the threading subsystem [default=yes]])], +# , enable_threads=yes) +enable_threads=yes if test x$enable_threads != xyes; then AC_DEFINE(SDL_THREADS_DISABLED, 1, [ ]) else SUMMARY_modules="${SUMMARY_modules} threads" fi AC_ARG_ENABLE(timers, -AS_HELP_STRING([--enable-timers], [Enable the timer subsystem [[default=yes]]]), +[AS_HELP_STRING([--enable-timers], [Enable the timer subsystem [default=yes]])], , enable_timers=yes) if test x$enable_timers != xyes; then AC_DEFINE(SDL_TIMERS_DISABLED, 1, [ ]) @@ -512,15 +593,31 @@ else SUMMARY_modules="${SUMMARY_modules} timers" fi AC_ARG_ENABLE(file, -AS_HELP_STRING([--enable-file], [Enable the file subsystem [[default=yes]]]), +[AS_HELP_STRING([--enable-file], [Enable the file subsystem [default=yes]])], , enable_file=yes) if test x$enable_file != xyes; then AC_DEFINE(SDL_FILE_DISABLED, 1, [ ]) else SUMMARY_modules="${SUMMARY_modules} file" fi +AC_ARG_ENABLE(misc, +[AS_HELP_STRING([--enable-misc], [Enable the misc subsystem [default=yes]])], + , enable_misc=yes) +if test x$enable_misc != xyes; then + AC_DEFINE(SDL_MISC_DISABLED, 1, [ ]) +else + SUMMARY_modules="${SUMMARY_modules} misc" +fi +AC_ARG_ENABLE(locale, +[AS_HELP_STRING([--enable-locale], [Enable the locale subsystem [default=yes]])], + , enable_locale=yes) +if test x$enable_locale != xyes; then + AC_DEFINE(SDL_LOCALE_DISABLED, 1, [ ]) +else + SUMMARY_modules="${SUMMARY_modules} locale" +fi AC_ARG_ENABLE(loadso, -AS_HELP_STRING([--enable-loadso], [Enable the shared object loading subsystem [[default=yes]]]), +[AS_HELP_STRING([--enable-loadso], [Enable the shared object loading subsystem [default=yes]])], , enable_loadso=yes) if test x$enable_loadso != xyes; then AC_DEFINE(SDL_LOADSO_DISABLED, 1, [ ]) @@ -528,7 +625,7 @@ else SUMMARY_modules="${SUMMARY_modules} loadso" fi AC_ARG_ENABLE(cpuinfo, -AS_HELP_STRING([--enable-cpuinfo], [Enable the cpuinfo subsystem [[default=yes]]]), +[AS_HELP_STRING([--enable-cpuinfo], [Enable the cpuinfo subsystem [default=yes]])], , enable_cpuinfo=yes) if test x$enable_cpuinfo != xyes; then AC_DEFINE(SDL_CPUINFO_DISABLED, 1, [ ]) @@ -536,13 +633,11 @@ else SUMMARY_modules="${SUMMARY_modules} cpuinfo" fi AC_ARG_ENABLE(assembly, -AS_HELP_STRING([--enable-assembly], [Enable assembly routines [[default=yes]]]), +[AS_HELP_STRING([--enable-assembly], [Enable assembly routines [default=yes]])], , enable_assembly=yes) if test x$enable_assembly = xyes; then SUMMARY_modules="${SUMMARY_modules} assembly" - AC_DEFINE(SDL_ASSEMBLY_ROUTINES, 1, [ ]) - # Make sure that we don't generate floating point code that would # cause illegal instruction exceptions on older processors case "$host" in @@ -559,7 +654,7 @@ if test x$enable_assembly = xyes; then ;; esac AC_ARG_ENABLE(ssemath, -AS_HELP_STRING([--enable-ssemath], [Allow GCC to use SSE floating point math [[default=maybe]]]), +[AS_HELP_STRING([--enable-ssemath], [Allow GCC to use SSE floating point math [default=maybe]])], , enable_ssemath=$default_ssemath) if test x$enable_ssemath = xno; then if test x$have_gcc_sse = xyes -o x$have_gcc_sse2 = xyes -o x$have_gcc_sse3 = xyes; then @@ -567,9 +662,9 @@ AS_HELP_STRING([--enable-ssemath], [Allow GCC to use SSE floating point math [[d fi fi - dnl Check for various instruction support +dnl Check for various instruction support AC_ARG_ENABLE(mmx, -AS_HELP_STRING([--enable-mmx], [use MMX assembly routines [[default=yes]]]), +[AS_HELP_STRING([--enable-mmx], [use MMX assembly routines [default=yes]])], , enable_mmx=yes) if test x$enable_mmx = xyes; then save_CFLAGS="$CFLAGS" @@ -578,7 +673,7 @@ AS_HELP_STRING([--enable-mmx], [use MMX assembly routines [[default=yes]]]), mmx_CFLAGS="-mmmx" CFLAGS="$save_CFLAGS $mmx_CFLAGS" - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #ifdef __MINGW32__ #include <_mingw.h> #ifdef __MINGW64_VERSION_MAJOR @@ -592,10 +687,7 @@ AS_HELP_STRING([--enable-mmx], [use MMX assembly routines [[default=yes]]]), #ifndef __MMX__ #error Assembler CPP flag not enabled #endif - ],[ - ],[ - have_gcc_mmx=yes - ]) + ]],[])], [have_gcc_mmx=yes],[]) AC_MSG_RESULT($have_gcc_mmx) CFLAGS="$save_CFLAGS" @@ -606,7 +698,7 @@ AS_HELP_STRING([--enable-mmx], [use MMX assembly routines [[default=yes]]]), fi AC_ARG_ENABLE(3dnow, -AS_HELP_STRING([--enable-3dnow], [use 3DNow! assembly routines [[default=yes]]]), +[AS_HELP_STRING([--enable-3dnow], [use 3DNow! assembly routines [default=yes]])], , enable_3dnow=yes) if test x$enable_3dnow = xyes; then save_CFLAGS="$CFLAGS" @@ -615,17 +707,16 @@ AS_HELP_STRING([--enable-3dnow], [use 3DNow! assembly routines [[default=yes]]]) amd3dnow_CFLAGS="-m3dnow" CFLAGS="$save_CFLAGS $amd3dnow_CFLAGS" - AC_TRY_LINK([ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include #ifndef __3dNOW__ #error Assembler CPP flag not enabled #endif - ],[ + ]], [[ void *p = 0; _m_prefetch(p); - ],[ - have_gcc_3dnow=yes - ]) + ]])], + [have_gcc_3dnow=yes],[]) AC_MSG_RESULT($have_gcc_3dnow) CFLAGS="$save_CFLAGS" @@ -636,7 +727,7 @@ AS_HELP_STRING([--enable-3dnow], [use 3DNow! assembly routines [[default=yes]]]) fi AC_ARG_ENABLE(sse, -AS_HELP_STRING([--enable-sse], [use SSE assembly routines [[default=yes]]]), +[AS_HELP_STRING([--enable-sse], [use SSE assembly routines [default=yes]])], , enable_sse=yes) if test x$enable_sse = xyes; then save_CFLAGS="$CFLAGS" @@ -645,7 +736,7 @@ AS_HELP_STRING([--enable-sse], [use SSE assembly routines [[default=yes]]]), sse_CFLAGS="-msse" CFLAGS="$save_CFLAGS $sse_CFLAGS" - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #ifdef __MINGW32__ #include <_mingw.h> #ifdef __MINGW64_VERSION_MAJOR @@ -659,10 +750,7 @@ AS_HELP_STRING([--enable-sse], [use SSE assembly routines [[default=yes]]]), #ifndef __SSE__ #error Assembler CPP flag not enabled #endif - ],[ - ],[ - have_gcc_sse=yes - ]) + ]],[])], [have_gcc_sse=yes],[]) AC_MSG_RESULT($have_gcc_sse) CFLAGS="$save_CFLAGS" @@ -673,7 +761,7 @@ AS_HELP_STRING([--enable-sse], [use SSE assembly routines [[default=yes]]]), fi AC_ARG_ENABLE(sse2, -AS_HELP_STRING([--enable-sse2], [use SSE2 assembly routines [[default=maybe]]]), +[AS_HELP_STRING([--enable-sse2], [use SSE2 assembly routines [default=maybe]])], , enable_sse2=$default_ssemath) if test x$enable_sse2 = xyes; then save_CFLAGS="$CFLAGS" @@ -682,7 +770,7 @@ AS_HELP_STRING([--enable-sse2], [use SSE2 assembly routines [[default=maybe]]]), sse2_CFLAGS="-msse2" CFLAGS="$save_CFLAGS $sse2_CFLAGS" - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #ifdef __MINGW32__ #include <_mingw.h> #ifdef __MINGW64_VERSION_MAJOR @@ -696,10 +784,7 @@ AS_HELP_STRING([--enable-sse2], [use SSE2 assembly routines [[default=maybe]]]), #ifndef __SSE2__ #error Assembler CPP flag not enabled #endif - ],[ - ],[ - have_gcc_sse2=yes - ]) + ]],[])], [have_gcc_sse2=yes],[]) AC_MSG_RESULT($have_gcc_sse2) CFLAGS="$save_CFLAGS" @@ -710,7 +795,7 @@ AS_HELP_STRING([--enable-sse2], [use SSE2 assembly routines [[default=maybe]]]), fi AC_ARG_ENABLE(sse3, -AS_HELP_STRING([--enable-sse3], [use SSE3 assembly routines [[default=maybe]]]), +[AS_HELP_STRING([--enable-sse3], [use SSE3 assembly routines [default=maybe]])], , enable_sse3=$default_ssemath) if test x$enable_sse3 = xyes; then save_CFLAGS="$CFLAGS" @@ -719,7 +804,7 @@ AS_HELP_STRING([--enable-sse3], [use SSE3 assembly routines [[default=maybe]]]), sse3_CFLAGS="-msse3" CFLAGS="$save_CFLAGS $sse3_CFLAGS" - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #ifdef __MINGW32__ #include <_mingw.h> #ifdef __MINGW64_VERSION_MAJOR @@ -733,10 +818,7 @@ AS_HELP_STRING([--enable-sse3], [use SSE3 assembly routines [[default=maybe]]]), #ifndef __SSE2__ #error Assembler CPP flag not enabled #endif - ],[ - ],[ - have_gcc_sse3=yes - ]) + ]],[])], [have_gcc_sse3=yes],[]) AC_MSG_RESULT($have_gcc_sse3) CFLAGS="$save_CFLAGS" @@ -746,15 +828,16 @@ AS_HELP_STRING([--enable-sse3], [use SSE3 assembly routines [[default=maybe]]]), fi fi - AC_CHECK_HEADER(immintrin.h, - have_immintrin_h_hdr=yes, - have_immintrin_h_hdr=no) + AC_MSG_CHECKING(for immintrin.h) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]])], + [have_immintrin_h_hdr=yes],[have_immintrin_h_hdr=no]) + AC_MSG_RESULT($have_immintrin_h_hdr) if test x$have_immintrin_h_hdr = xyes; then AC_DEFINE(HAVE_IMMINTRIN_H, 1, [ ]) fi AC_ARG_ENABLE(altivec, -AS_HELP_STRING([--enable-altivec], [use Altivec assembly routines [[default=yes]]]), +[AS_HELP_STRING([--enable-altivec], [use Altivec assembly routines [default=yes]])], , enable_altivec=yes) if test x$enable_altivec = xyes; then save_CFLAGS="$CFLAGS" @@ -764,28 +847,24 @@ AS_HELP_STRING([--enable-altivec], [use Altivec assembly routines [[default=yes] CFLAGS="$save_CFLAGS $altivec_CFLAGS" AC_MSG_CHECKING(for Altivec with GCC altivec.h and -maltivec option) - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include vector unsigned int vzero() { return vec_splat_u32(0); } - ],[ - ],[ + ]],[])], [ have_gcc_altivec=yes have_altivec_h_hdr=yes - ]) + ],[]) AC_MSG_RESULT($have_gcc_altivec) if test x$have_gcc_altivec = xno; then AC_MSG_CHECKING(for Altivec with GCC -maltivec option) - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ vector unsigned int vzero() { return vec_splat_u32(0); } - ],[ - ],[ - have_gcc_altivec=yes - ]) + ]],[])], [have_gcc_altivec=yes],[]) AC_MSG_RESULT($have_gcc_altivec) fi @@ -793,29 +872,25 @@ AS_HELP_STRING([--enable-altivec], [use Altivec assembly routines [[default=yes] AC_MSG_CHECKING(for Altivec with GCC altivec.h and -faltivec option) altivec_CFLAGS="-faltivec" CFLAGS="$save_CFLAGS $altivec_CFLAGS" - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include vector unsigned int vzero() { return vec_splat_u32(0); } - ],[ - ],[ + ]],[])], [ have_gcc_altivec=yes have_altivec_h_hdr=yes - ]) + ],[]) AC_MSG_RESULT($have_gcc_altivec) fi if test x$have_gcc_altivec = xno; then AC_MSG_CHECKING(for Altivec with GCC -faltivec option) - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ vector unsigned int vzero() { return vec_splat_u32(0); } - ],[ - ],[ - have_gcc_altivec=yes - ]) + ]],[])], [have_gcc_altivec=yes],[]) AC_MSG_RESULT($have_gcc_altivec) fi CFLAGS="$save_CFLAGS" @@ -831,45 +906,57 @@ AS_HELP_STRING([--enable-altivec], [use Altivec assembly routines [[default=yes] fi fi + AC_ARG_ENABLE(lsx, +[AS_HELP_STRING([--enable-lsx], [use LSX assembly routines [default=yes]])], + , enable_lsx=yes) + if test x$enable_lsx = xyes; then + save_CFLAGS="$CFLAGS" + have_gcc_lsx=no + AC_MSG_CHECKING(for GCC -mlsx option) + lsx_CFLAGS="-mlsx" + CFLAGS="$save_CFLAGS $lsx_CFLAGS" + + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #ifndef __loongarch_sx + #error Assembler CPP flag not enabled + #endif + ]], [])], [have_gcc_lsx=yes], []) + AC_MSG_RESULT($have_gcc_lsx) + CFLAGS="$save_CFLAGS" + + if test x$have_gcc_lsx = xyes; then + EXTRA_CFLAGS="$EXTRA_CFLAGS $lsx_CFLAGS" + SUMMARY_math="${SUMMARY_math} lsx" + fi + fi + + AC_MSG_CHECKING(for lsxintrin.h) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]])], + [have_lsxintrin_h_hdr=yes],[have_lsxintrin_h_hdr=no]) + AC_MSG_RESULT($have_lsxintrin_h_hdr) + if test x$have_lsxintrin_h_hdr = xyes; then + AC_DEFINE(HAVE_LSXINTRIN_H, 1, [ ]) + fi + dnl See if the OSS audio interface is supported CheckOSS() { AC_ARG_ENABLE(oss, -AS_HELP_STRING([--enable-oss], [support the OSS audio API [[default=maybe]]]), +[AS_HELP_STRING([--enable-oss], [support the OSS audio API [default=maybe]])], , enable_oss=maybe) - - # OpenBSD "has" OSS, but it's not really for app use. They want you to - # use sndio instead. So on there, we default to disabled. You can force - # it on if you really want, though. if test x$enable_oss = xmaybe; then enable_oss=yes - case "$host" in - *-*-openbsd*) - enable_oss=no;; - esac fi if test x$enable_audio = xyes -a x$enable_oss = xyes; then AC_MSG_CHECKING(for OSS audio support) have_oss=no if test x$have_oss != xyes; then - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include - ],[ + ]], [[ int arg = SNDCTL_DSP_SETFRAGMENT; - ],[ - have_oss=yes - ]) - fi - if test x$have_oss != xyes; then - AC_TRY_COMPILE([ - #include - ],[ - int arg = SNDCTL_DSP_SETFRAGMENT; - ],[ - have_oss=yes - AC_DEFINE(SDL_AUDIO_DRIVER_OSS_SOUNDCARD_H, 1, [ ]) - ]) + ]])], [have_oss=yes],[]) fi AC_MSG_RESULT($have_oss) if test x$have_oss = xyes; then @@ -880,7 +967,7 @@ AS_HELP_STRING([--enable-oss], [support the OSS audio API [[default=maybe]]]), # We may need to link with ossaudio emulation library case "$host" in - *-*-openbsd*|*-*-netbsd*) + *-*-netbsd*) EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lossaudio";; esac fi @@ -891,7 +978,7 @@ dnl See if the ALSA audio interface is supported CheckALSA() { AC_ARG_ENABLE(alsa, -AS_HELP_STRING([--enable-alsa], [support the ALSA audio API [[default=yes]]]), +[AS_HELP_STRING([--enable-alsa], [support the ALSA audio API [default=yes]])], , enable_alsa=yes) if test x$enable_audio = xyes -a x$enable_alsa = xyes; then AM_PATH_ALSA(1.0.11, have_alsa=yes, have_alsa=no) @@ -901,7 +988,7 @@ AS_HELP_STRING([--enable-alsa], [support the ALSA audio API [[default=yes]]]), LIBS="$alsa_save_LIBS" if test x$have_alsa = xyes; then AC_ARG_ENABLE(alsa-shared, -AS_HELP_STRING([--enable-alsa-shared], [dynamically load ALSA audio support [[default=yes]]]), +[AS_HELP_STRING([--enable-alsa-shared], [dynamically load ALSA audio support [default=yes]])], , enable_alsa_shared=yes) alsa_lib=[`find_lib "libasound.so.*" "$ALSA_LIBS" | sed 's/.*\/\(.*\)/\1/; q'`] @@ -930,14 +1017,14 @@ dnl Find JACK Audio CheckJACK() { AC_ARG_ENABLE(jack, -AS_HELP_STRING([--enable-jack], [use JACK audio [[default=yes]]]), +[AS_HELP_STRING([--enable-jack], [use JACK audio [default=yes]])], , enable_jack=yes) if test x$enable_audio = xyes -a x$enable_jack = xyes; then PKG_CHECK_MODULES([JACK], [jack >= 0.125], audio_jack=yes, audio_jack=no) if test x$audio_jack = xyes; then AC_ARG_ENABLE(jack-shared, -AS_HELP_STRING([--enable-jack-shared], [dynamically load JACK audio support [[default=yes]]]), +[AS_HELP_STRING([--enable-jack-shared], [dynamically load JACK audio support [default=yes]])], , enable_jack_shared=yes) jack_lib=[`find_lib "libjack.so.*" "$JACK_LIBS" | sed 's/.*\/\(.*\)/\1/; q'`] @@ -974,13 +1061,16 @@ dnl Find the ESD includes and libraries CheckESD() { AC_ARG_ENABLE(esd, -AS_HELP_STRING([--enable-esd], [support the Enlightened Sound Daemon [[default=yes]]]), +[AS_HELP_STRING([--enable-esd], [support the Enlightened Sound Daemon [default=yes]])], , enable_esd=yes) if test x$enable_audio = xyes -a x$enable_esd = xyes; then - AM_PATH_ESD(0.2.8, have_esd=yes, have_esd=no) + PKG_CHECK_MODULES([ESD], [esound >= 0.2.8], have_esd=yes, have_esd=no) + if test x$have_esd = xno; then + AM_PATH_ESD(0.2.8, have_esd=yes, have_esd=no) + fi if test x$have_esd = xyes; then AC_ARG_ENABLE(esd-shared, -AS_HELP_STRING([--enable-esd-shared], [dynamically load ESD audio support [[default=yes]]]), +[AS_HELP_STRING([--enable-esd-shared], [dynamically load ESD audio support [default=yes]])], , enable_esd_shared=yes) esd_lib=[`find_lib "libesd.so.*" "$ESD_LIBS" | sed 's/.*\/\(.*\)/\1/; q'`] @@ -1005,20 +1095,56 @@ AS_HELP_STRING([--enable-esd-shared], [dynamically load ESD audio support [[defa fi } +dnl Find Pipewire +CheckPipewire() +{ + AC_ARG_ENABLE(pipewire, +[AS_HELP_STRING([--enable-pipewire], [use Pipewire audio [default=yes]])], + , enable_pipewire=yes) + if test x$enable_audio = xyes -a x$enable_pipewire = xyes; then + PKG_CHECK_MODULES([PIPEWIRE], [libpipewire-0.3 >= 0.3.20], audio_pipewire=yes, audio_pipewire=no) + + if test x$audio_pipewire = xyes; then + AC_ARG_ENABLE(pipewire-shared, +[AS_HELP_STRING([--enable-pipewire-shared], [dynamically load Pipewire support [default=yes]])], + , enable_pipewire_shared=yes) + pipewire_lib=[`find_lib "libpipewire-0.3.so.*" "$PIPEWIRE_LIBS" | sed 's/.*\/\(.*\)/\1/; q'`] + + AC_DEFINE(SDL_AUDIO_DRIVER_PIPEWIRE, 1, [ ]) + SOURCES="$SOURCES $srcdir/src/audio/pipewire/*.c" + EXTRA_CFLAGS="$EXTRA_CFLAGS $PIPEWIRE_CFLAGS" + if test x$have_loadso != xyes && \ + test x$enable_pipewire_shared = xyes; then + AC_MSG_WARN([You must have SDL_LoadObject() support for dynamic Pipewire loading]) + fi + if test x$have_loadso = xyes && \ + test x$enable_pipewire_shared = xyes && test x$pipewire_lib != x; then + echo "-- dynamic libpipewire-0.3 -> $pipewire_lib" + AC_DEFINE_UNQUOTED(SDL_AUDIO_DRIVER_PIPEWIRE_DYNAMIC, "$pipewire_lib", [ ]) + SUMMARY_audio="${SUMMARY_audio} pipewire(dynamic)" + else + EXTRA_LDFLAGS="$EXTRA_LDFLAGS $PIPEWIRE_LIBS" + SUMMARY_audio="${SUMMARY_audio} pipewire" + fi + have_audio=yes + fi + fi +} + dnl Find PulseAudio CheckPulseAudio() { AC_ARG_ENABLE(pulseaudio, -AS_HELP_STRING([--enable-pulseaudio], [use PulseAudio [[default=yes]]]), +[AS_HELP_STRING([--enable-pulseaudio], [use PulseAudio [default=yes]])], , enable_pulseaudio=yes) if test x$enable_audio = xyes -a x$enable_pulseaudio = xyes; then - PKG_CHECK_MODULES([PULSEAUDIO], [libpulse-simple >= 0.9], audio_pulseaudio=yes, audio_pulseaudio=no) + PKG_CHECK_MODULES([PULSEAUDIO], [libpulse >= 0.9.15], audio_pulseaudio=yes, audio_pulseaudio=no) if test x$audio_pulseaudio = xyes; then AC_ARG_ENABLE(pulseaudio-shared, -AS_HELP_STRING([--enable-pulseaudio-shared], [dynamically load PulseAudio support [[default=yes]]]), +[AS_HELP_STRING([--enable-pulseaudio-shared], [dynamically load PulseAudio support [default=yes]])], , enable_pulseaudio_shared=yes) - pulseaudio_lib=[`find_lib "libpulse-simple.so.*" "$PULSEAUDIO_LIBS" | sed 's/.*\/\(.*\)/\1/; q'`] + pulseaudio_lib=[`find_lib "libpulse.so.*" "$PULSEAUDIO_LIBS" | sed 's/.*\/\(.*\)/\1/; q'`] AC_DEFINE(SDL_AUDIO_DRIVER_PULSEAUDIO, 1, [ ]) SOURCES="$SOURCES $srcdir/src/audio/pulseaudio/*.c" @@ -1029,7 +1155,7 @@ AS_HELP_STRING([--enable-pulseaudio-shared], [dynamically load PulseAudio suppor fi if test x$have_loadso = xyes && \ test x$enable_pulseaudio_shared = xyes && test x$pulseaudio_lib != x; then - echo "-- dynamic libpulse-simple -> $pulseaudio_lib" + echo "-- dynamic libpulse -> $pulseaudio_lib" AC_DEFINE_UNQUOTED(SDL_AUDIO_DRIVER_PULSEAUDIO_DYNAMIC, "$pulseaudio_lib", [ ]) SUMMARY_audio="${SUMMARY_audio} pulse(dynamic)" @@ -1052,7 +1178,7 @@ AS_HELP_STRING([--enable-pulseaudio-shared], [dynamically load PulseAudio suppor CheckARTSC() { AC_ARG_ENABLE(arts, -AS_HELP_STRING([--enable-arts], [support the Analog Real Time Synthesizer [[default=yes]]]), +[AS_HELP_STRING([--enable-arts], [support the Analog Real Time Synthesizer [default=yes]])], , enable_arts=yes) if test x$enable_audio = xyes -a x$enable_arts = xyes; then AC_PATH_PROG(ARTSCONFIG, artsc-config) @@ -1065,18 +1191,16 @@ AS_HELP_STRING([--enable-arts], [support the Analog Real Time Synthesizer [[defa audio_arts=no save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $ARTS_CFLAGS" - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include - ],[ + ]], [[ arts_stream_t stream; - ],[ - audio_arts=yes - ]) + ]])], [audio_arts=yes],[]) CFLAGS="$save_CFLAGS" AC_MSG_RESULT($audio_arts) if test x$audio_arts = xyes; then AC_ARG_ENABLE(arts-shared, -AS_HELP_STRING([--enable-arts-shared], [dynamically load aRts audio support [[default=yes]]]), +[AS_HELP_STRING([--enable-arts-shared], [dynamically load aRts audio support [default=yes]])], , enable_arts_shared=yes) arts_lib=[`find_lib "libartsc.so.*" "$ARTS_LIBS" | sed 's/.*\/\(.*\)/\1/; q'`] @@ -1106,7 +1230,7 @@ dnl See if the NAS audio interface is supported CheckNAS() { AC_ARG_ENABLE(nas, -AS_HELP_STRING([--enable-nas], [support the NAS audio API [[default=yes]]]), +[AS_HELP_STRING([--enable-nas], [support the NAS audio API [default=yes]])], , enable_nas=yes) if test x$enable_audio = xyes -a x$enable_nas = xyes; then AC_CHECK_HEADER(audio/audiolib.h, have_nas_hdr=yes) @@ -1130,7 +1254,7 @@ AS_HELP_STRING([--enable-nas], [support the NAS audio API [[default=yes]]]), if test x$have_nas = xyes; then AC_ARG_ENABLE(nas-shared, -AS_HELP_STRING([--enable-nas-shared], [dynamically load NAS audio support [[default=yes]]]), +[AS_HELP_STRING([--enable-nas-shared], [dynamically load NAS audio support [default=yes]])], , enable_nas_shared=yes) nas_lib=[`find_lib "libaudio.so.*" "$NAS_LIBS" | sed 's/.*\/\(.*\)/\1/; q'`] @@ -1160,25 +1284,14 @@ dnl See if the sndio audio interface is supported CheckSNDIO() { AC_ARG_ENABLE(sndio, -AS_HELP_STRING([--enable-sndio], [support the sndio audio API [[default=yes]]]), +[AS_HELP_STRING([--enable-sndio], [support the sndio audio API [default=yes]])], , enable_sndio=yes) if test x$enable_audio = xyes -a x$enable_sndio = xyes; then - AC_CHECK_HEADER(sndio.h, have_sndio_hdr=yes) - AC_CHECK_LIB(sndio, sio_open, have_sndio_lib=yes) + PKG_CHECK_MODULES([SNDIO], [sndio], audio_sndio=yes, audio_sndio=no) - AC_MSG_CHECKING(for sndio audio support) - have_sndio=no - - if test x$have_sndio_hdr = xyes -a x$have_sndio_lib = xyes; then - have_sndio=yes - SNDIO_LIBS="-lsndio" - fi - - AC_MSG_RESULT($have_sndio) - - if test x$have_sndio = xyes; then + if test x$audio_sndio = xyes; then AC_ARG_ENABLE(sndio-shared, -AS_HELP_STRING([--enable-sndio-shared], [dynamically load sndio audio support [[default=yes]]]), +[AS_HELP_STRING([--enable-sndio-shared], [dynamically load sndio audio support [default=yes]])], , enable_sndio_shared=yes) sndio_lib=[`find_lib "libsndio.so.*" "$SNDIO_LIBS" | sed 's/.*\/\(.*\)/\1/; q'`] @@ -1208,7 +1321,7 @@ dnl Find FusionSound CheckFusionSound() { AC_ARG_ENABLE(fusionsound, -AS_HELP_STRING([--enable-fusionsound], [use FusionSound audio driver [[default=no]]]), +[AS_HELP_STRING([--enable-fusionsound], [use FusionSound audio driver [default=no]])], , enable_fusionsound=no) if test x$enable_audio = xyes -a x$enable_fusionsound = xyes; then PKG_CHECK_MODULES([FUSIONSOUND], [fusionsound >= 1.1.1], fusionsound=yes, fusionsound=no) @@ -1217,9 +1330,9 @@ AS_HELP_STRING([--enable-fusionsound], [use FusionSound audio driver [[default=n AC_DEFINE(SDL_AUDIO_DRIVER_FUSIONSOUND, 1, [ ]) SOURCES="$SOURCES $srcdir/src/audio/fusionsound/*.c" EXTRA_CFLAGS="$EXTRA_CFLAGS $FUSIONSOUND_CFLAGS" - + AC_ARG_ENABLE(fusionsound-shared, -AS_HELP_STRING([--enable-fusionsound-shared], [dynamically load fusionsound audio support [[default=yes]]]), +[AS_HELP_STRING([--enable-fusionsound-shared], [dynamically load fusionsound audio support [default=yes]])], , enable_fusionsound_shared=yes) fusionsound_shared=no AC_MSG_CHECKING(for FusionSound dynamic loading support) @@ -1237,7 +1350,7 @@ AS_HELP_STRING([--enable-fusionsound-shared], [dynamically load fusionsound audi SUMMARY_audio="${SUMMARY_audio} fusionsound" fi AC_MSG_RESULT($fusionsound_shared) - + have_audio=yes fi fi @@ -1247,12 +1360,13 @@ dnl rcg07142001 See if the user wants the disk writer audio driver... CheckDiskAudio() { AC_ARG_ENABLE(diskaudio, -AS_HELP_STRING([--enable-diskaudio], [support the disk writer audio driver [[default=yes]]]), +[AS_HELP_STRING([--enable-diskaudio], [support the disk writer audio driver [default=yes]])], , enable_diskaudio=yes) if test x$enable_audio = xyes -a x$enable_diskaudio = xyes; then AC_DEFINE(SDL_AUDIO_DRIVER_DISK, 1, [ ]) SOURCES="$SOURCES $srcdir/src/audio/disk/*.c" SUMMARY_audio="${SUMMARY_audio} disk" + have_audio=yes fi } @@ -1260,12 +1374,13 @@ dnl rcg03142006 See if the user wants the dummy audio driver... CheckDummyAudio() { AC_ARG_ENABLE(dummyaudio, -AS_HELP_STRING([--enable-dummyaudio], [support the dummy audio driver [[default=yes]]]), +[AS_HELP_STRING([--enable-dummyaudio], [support the dummy audio driver [default=yes]])], , enable_dummyaudio=yes) if test x$enable_audio = xyes -a x$enable_dummyaudio = xyes; then AC_DEFINE(SDL_AUDIO_DRIVER_DUMMY, 1, [ ]) SOURCES="$SOURCES $srcdir/src/audio/dummy/*.c" SUMMARY_audio="${SUMMARY_audio} dummy" + have_audio=yes fi } @@ -1273,7 +1388,7 @@ dnl See if libsamplerate is available CheckLibSampleRate() { AC_ARG_ENABLE(libsamplerate, -AS_HELP_STRING([--enable-libsamplerate], [use libsamplerate for audio rate conversion [[default=yes]]]), +[AS_HELP_STRING([--enable-libsamplerate], [use libsamplerate for audio rate conversion [default=yes]])], , enable_libsamplerate=yes) if test x$enable_libsamplerate = xyes; then AC_CHECK_HEADER(samplerate.h, @@ -1283,7 +1398,7 @@ AS_HELP_STRING([--enable-libsamplerate], [use libsamplerate for audio rate conve AC_DEFINE(HAVE_LIBSAMPLERATE_H, 1, [ ]) AC_ARG_ENABLE(libsamplerate-shared, -AS_HELP_STRING([--enable-libsamplerate-shared], [dynamically load libsamplerate [[default=yes]]]), +[AS_HELP_STRING([--enable-libsamplerate-shared], [dynamically load libsamplerate [default=yes]])], , enable_libsamplerate_shared=yes) samplerate_lib=[`find_lib "libsamplerate.so.*" "" | sed 's/.*\/\(.*\)/\1/; q'`] @@ -1307,13 +1422,13 @@ dnl Check for ARM instruction support using gas syntax CheckARM() { AC_ARG_ENABLE(arm-simd, -AC_HELP_STRING([--enable-arm-simd], [use SIMD assembly blitters on ARM [[default=yes]]]), - enable_arm_simd=$enableval, enable_arm_simd=yes) +[AS_HELP_STRING([--enable-arm-simd], [use SIMD assembly blitters on ARM [default=no]])], + enable_arm_simd=$enableval, enable_arm_simd=no) if test x$enable_video = xyes -a x$enable_assembly = xyes -a x$enable_arm_simd = xyes; then save_CFLAGS="$CFLAGS" have_arm_simd=no CFLAGS="-x assembler-with-cpp $CFLAGS" - + AC_MSG_CHECKING(for ARM SIMD) AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ .text @@ -1328,12 +1443,11 @@ AC_HELP_STRING([--enable-arm-simd], [use SIMD assembly blitters on ARM [[default uqadd8 r0, r0, r0 ]])], have_arm_simd=yes) AC_MSG_RESULT($have_arm_simd) - + CFLAGS="$save_CFLAGS" - + if test x$have_arm_simd = xyes; then - AC_DEFINE(SDL_ARM_SIMD_BLITTERS) -dnl SOURCES="$SOURCES $srcdir/src/video/arm/pixman-arm-simd*.c" + AC_DEFINE(SDL_ARM_SIMD_BLITTERS, 1, [ ]) SOURCES="$SOURCES $srcdir/src/video/arm/pixman-arm-simd*.S" WARN_ABOUT_ARM_SIMD_ASM_MIT="yes" fi @@ -1344,13 +1458,13 @@ dnl Check for ARM NEON instruction support using gas syntax CheckNEON() { AC_ARG_ENABLE(arm-neon, -AC_HELP_STRING([--enable-arm-neon], [use NEON assembly blitters on ARM [[default=no]]]), +[AS_HELP_STRING([--enable-arm-neon], [use NEON assembly blitters on ARM [default=no]])], enable_arm_neon=$enableval, enable_arm_neon=no) if test x$enable_video = xyes -a x$enable_assembly = xyes -a x$enable_arm_neon = xyes; then save_CFLAGS="$CFLAGS" have_arm_neon=no CFLAGS="-x assembler-with-cpp $CFLAGS" - + AC_MSG_CHECKING(for ARM NEON) AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ .text @@ -1367,18 +1481,56 @@ AC_HELP_STRING([--enable-arm-neon], [use NEON assembly blitters on ARM [[default vmovn.u16 d0, q0 ]])], have_arm_neon=yes) AC_MSG_RESULT($have_arm_neon) - CFLAGS="$save_CFLAGS" - + if test x$have_arm_neon = xyes; then - AC_DEFINE(SDL_ARM_NEON_BLITTERS) -dnl SOURCES="$SOURCES $srcdir/src/video/arm/pixman-arm-neon*.c" + AC_DEFINE(SDL_ARM_NEON_BLITTERS, 1, [ ]) SOURCES="$SOURCES $srcdir/src/video/arm/pixman-arm-neon*.S" WARN_ABOUT_ARM_NEON_ASM_MIT="yes" fi fi } +dnl See if clang's -fobjc-arc supported. +dnl Reference: https://github.com/libsdl-org/SDL/pull/5632 +CheckObjectiveCARC() +{ + AC_MSG_CHECKING(for clang -fobjc-arc option) + have_clang_objc_arc=no + + save_CFLAGS="$CFLAGS" + CFLAGS="$save_CFLAGS -fobjc-arc" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + int x = 0; + ]],[])], [have_clang_objc_arc=yes],[]) + AC_MSG_RESULT($have_clang_objc_arc) + CFLAGS="$save_CFLAGS" + + if test x$have_clang_objc_arc = xyes; then + EXTRA_CFLAGS="$EXTRA_CFLAGS -fobjc-arc" + fi +} + +dnl See if GCC's -gdwarf-4 is supported +dnl See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101377 for why this is needed on Windows +CheckGDwarf4() +{ + AC_MSG_CHECKING(for GCC -gdwarf-4 option) + have_gcc_gdwarf4=no + + save_CFLAGS="$CFLAGS" + CFLAGS="$save_CFLAGS -gdwarf-4" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + int x = 0; + ]],[])], [have_gcc_gdwarf4=yes],[]) + AC_MSG_RESULT($have_gcc_gdwarf4) + CFLAGS="$save_CFLAGS" + + if test x$have_gcc_gdwarf4 = xyes; then + EXTRA_CFLAGS="$EXTRA_CFLAGS -gdwarf-4" + fi +} + dnl See if GCC's -fvisibility=hidden is supported (gcc4 and later, usually). dnl Details of this flag are here: http://gcc.gnu.org/wiki/Visibility CheckVisibilityHidden() @@ -1389,14 +1541,11 @@ CheckVisibilityHidden() visibility_CFLAGS="-fvisibility=hidden" save_CFLAGS="$CFLAGS" CFLAGS="$save_CFLAGS $visibility_CFLAGS -Werror" - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #if !defined(__GNUC__) || __GNUC__ < 4 #error SDL only uses visibility attributes in GCC 4 or newer #endif - ],[ - ],[ - have_gcc_fvisibility=yes - ]) + ]],[])], [have_gcc_fvisibility=yes],[]) AC_MSG_RESULT($have_gcc_fvisibility) CFLAGS="$save_CFLAGS" @@ -1414,12 +1563,9 @@ CheckNoStrictAliasing() save_CFLAGS="$CFLAGS" CFLAGS="$save_CFLAGS -fno-strict-aliasing" - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ int x = 0; - ],[ - ],[ - have_gcc_no_strict_aliasing=yes - ]) + ]],[])], [have_gcc_no_strict_aliasing=yes],[]) AC_MSG_RESULT($have_gcc_no_strict_aliasing) CFLAGS="$save_CFLAGS" @@ -1428,26 +1574,46 @@ CheckNoStrictAliasing() fi } -dnl See if GCC's -mpreferred-stack-boundary is supported. -dnl Reference: http://bugzilla.libsdl.org/show_bug.cgi?id=1296 -CheckStackBoundary() +dnl See if GCC's -Werror is supported. +CheckWerror() { - AC_MSG_CHECKING(for GCC -mpreferred-stack-boundary option) - have_gcc_preferred_stack_boundary=no + AC_ARG_ENABLE(werror, +[AS_HELP_STRING([--enable-werror], [treat warnings as errors [default=no]])], + enable_werror=$enableval, enable_werror=no) + if test x$enable_werror = xyes; then + AC_MSG_CHECKING(for GCC -Werror option) + have_gcc_werror=no + + save_CFLAGS="$CFLAGS" + CFLAGS="$save_CFLAGS -Werror" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + int x = 0; + ]],[])], [have_gcc_werror=yes],[]) + AC_MSG_RESULT($have_gcc_werror) + CFLAGS="$save_CFLAGS" + + if test x$have_gcc_werror = xyes; then + EXTRA_CFLAGS="$EXTRA_CFLAGS -Werror" + fi + fi +} + +dnl See if GCC's -Wno-error=deprecated-declarations is supported. +CheckNoErrorDeprecatedDeclarationsWerror() +{ + AC_MSG_CHECKING(for GCC -Wno-error=deprecated-declarations option) + have_gcc_no_werror_deprecated_declarations=no save_CFLAGS="$CFLAGS" - CFLAGS="$save_CFLAGS -mpreferred-stack-boundary=2" - AC_TRY_COMPILE([ + CFLAGS="$save_CFLAGS -Wno-error=deprecated-declarations" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ int x = 0; - ],[ - ],[ - have_gcc_preferred_stack_boundary=yes - ]) - AC_MSG_RESULT($have_gcc_preferred_stack_boundary) + ]],[])], [have_gcc_no_werror_deprecated_declarations=yes],[]) + AC_MSG_RESULT($have_gcc_werror) CFLAGS="$save_CFLAGS" - if test x$have_gcc_preferred_stack_boundary = xyes; then - EXTRA_CFLAGS="$EXTRA_CFLAGS -mpreferred-stack-boundary=2" + if test x$have_gcc_no_werror_deprecated_declarations = xyes; then + EXTRA_CFLAGS="$EXTRA_CFLAGS -Wno-error=deprecated-declarations" fi } @@ -1461,12 +1627,9 @@ CheckDeclarationAfterStatement() save_CFLAGS="$CFLAGS" CFLAGS="$save_CFLAGS -Wdeclaration-after-statement -Werror=declaration-after-statement" - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ int x = 0; - ],[ - ],[ - have_gcc_declaration_after_statement=yes - ]) + ]],[])], [have_gcc_declaration_after_statement=yes],[]) AC_MSG_RESULT($have_gcc_declaration_after_statement) CFLAGS="$save_CFLAGS" @@ -1483,19 +1646,16 @@ CheckWarnAll() save_CFLAGS="$CFLAGS" CFLAGS="$save_CFLAGS -Wall" - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ int x = 0; - ],[ - ],[ - have_gcc_Wall=yes - ]) + ]],[])], [have_gcc_Wall=yes],[]) AC_MSG_RESULT($have_gcc_Wall) CFLAGS="$save_CFLAGS" if test x$have_gcc_Wall = xyes; then EXTRA_CFLAGS="$EXTRA_CFLAGS -Wall" - dnl Haiku headers use multicharacter constants all over the place. Ignore these warnings when using -Wall. +dnl Haiku headers use multicharacter constants all over the place. Ignore these warnings when using -Wall. AC_MSG_CHECKING(for necessary GCC -Wno-multichar option) need_gcc_Wno_multichar=no case "$host" in @@ -1510,15 +1670,36 @@ CheckWarnAll() fi } +dnl See if GCC's -Wunused-local-typedefs is supported and disable it +dnl because it triggers on gcc 4.8.4 for compile time asserts inside +dnl of functions. +CheckUnusedLocalTypedefs() +{ + AC_MSG_CHECKING(for GCC -Wunused-local-typedefs option) + have_gcc_unused_local_typedefs=no + + save_CFLAGS="$CFLAGS" + CFLAGS="$save_CFLAGS -Wunused-local-typedefs" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + int x = 0; + ]],[])], [have_gcc_unused_local_typedefs=yes],[]) + AC_MSG_RESULT($have_gcc_unused_local_typedefs) + CFLAGS="$save_CFLAGS" + + if test x$have_gcc_unused_local_typedefs = xyes; then + EXTRA_CFLAGS="$EXTRA_CFLAGS -Wno-unused-local-typedefs" + fi +} + dnl Check for Wayland CheckWayland() { AC_ARG_ENABLE(video-wayland, -AS_HELP_STRING([--enable-video-wayland], [use Wayland video driver [[default=yes]]]), +[AS_HELP_STRING([--enable-video-wayland], [use Wayland video driver [default=yes]])], ,enable_video_wayland=yes) AC_ARG_ENABLE(video-wayland-qt-touch, -AS_HELP_STRING([--enable-video-wayland-qt-touch], [QtWayland server support for Wayland video driver [[default=yes]]]), +[AS_HELP_STRING([--enable-video-wayland-qt-touch], [QtWayland server support for Wayland video driver [default=yes]])], ,enable_video_wayland_qt_touch=yes) if test x$enable_video = xyes -a x$enable_video_wayland = xyes; then @@ -1526,10 +1707,13 @@ AS_HELP_STRING([--enable-video-wayland-qt-touch], [QtWayland server support for video_wayland=no if test x$video_opengl_egl = xyes && \ test x$video_opengles_v2 = xyes; then - if $PKG_CONFIG --exists wayland-client wayland-scanner wayland-protocols wayland-egl wayland-cursor egl xkbcommon ; then + if $PKG_CONFIG --exists 'wayland-client >= 1.18' wayland-scanner wayland-egl wayland-cursor egl 'xkbcommon >= 0.5.0'; then WAYLAND_CFLAGS=`$PKG_CONFIG --cflags wayland-client wayland-egl wayland-cursor xkbcommon` WAYLAND_LIBS=`$PKG_CONFIG --libs wayland-client wayland-egl wayland-cursor xkbcommon` WAYLAND_SCANNER=`$PKG_CONFIG --variable=wayland_scanner wayland-scanner` + AS_IF([$PKG_CONFIG --exists 'wayland-scanner >= 1.15'], + [WAYLAND_SCANNER_CODE_MODE=private-code], + [WAYLAND_SCANNER_CODE_MODE=code]) video_wayland=yes fi fi @@ -1545,16 +1729,16 @@ AS_HELP_STRING([--enable-video-wayland-qt-touch], [QtWayland server support for SOURCES="$SOURCES $WAYLAND_SOURCES" EXTRA_CFLAGS="$EXTRA_CFLAGS $WAYLAND_CFLAGS -I\$(gen)" AC_ARG_ENABLE(wayland-shared, -AS_HELP_STRING([--enable-wayland-shared], [dynamically load Wayland support [[default=maybe]]]), +[AS_HELP_STRING([--enable-wayland-shared], [dynamically load Wayland support [default=maybe]])], , enable_wayland_shared=maybe) - dnl FIXME: Do BSD and OS X need special cases? +dnl FIXME: Do BSD and OS X need special cases? case "$host" in *) wayland_client_lib=[`find_lib "libwayland-client.so.*" "$WAYLAND_LIBS" | sed 's/.*\/\(.*\)/\1/; q'`] wayland_egl_lib=[`find_lib "libwayland-egl.so.*" "$WAYLAND_LIBS" | sed 's/.*\/\(.*\)/\1/; q'`] if test x$wayland_egl_lib = x; then - dnl This works in Ubuntu 13.10, maybe others + # This works in Ubuntu 13.10, maybe others wayland_egl_lib=[`find_lib "mesa-egl/libwayland-egl.so.*" "$WAYLAND_LIBS" | sed 's/.*\/\(.*\)/\1/; q'`] fi wayland_cursor_lib=[`find_lib "libwayland-cursor.so.*" "$WAYLAND_LIBS" | sed 's/.*\/\(.*\)/\1/; q'`] @@ -1591,20 +1775,57 @@ AS_HELP_STRING([--enable-wayland-shared], [dynamically load Wayland support [[de SUMMARY_video="${SUMMARY_video} wayland" fi have_video=yes + +dnl See if libdecor is available + AC_ARG_ENABLE(libdecor, +[AS_HELP_STRING([--enable-libdecor], [use libdecor for Wayland client-side decorations [default=yes]])],, enable_libdecor=yes) + if test x$enable_libdecor = xyes; then + PKG_CHECK_MODULES([DECOR], [libdecor-0], video_libdecor=yes, video_libdecor=no) + if test x$video_libdecor = xyes; then + EXTRA_CFLAGS="$EXTRA_CFLAGS $DECOR_CFLAGS" + AC_DEFINE(HAVE_LIBDECOR_H, 1, [ ]) + + AC_ARG_ENABLE(libdecor-shared, +[AS_HELP_STRING([--enable-libdecor-shared], [dynamically load libdecor [default=yes]])],, enable_libdecor_shared=yes) + + decor_lib=[`find_lib "libdecor-0.so.*" "$DECOR_LIBS" | sed 's/.*\/\(.*\)/\1/; q'`] + + if test x$enable_wayland_shared != xyes; then + enable_libdecor_shared=no + fi + if test x$have_loadso != xyes && \ + test x$enable_libdecor_shared = xyes; then + AC_MSG_WARN([You must have SDL_LoadObject() support for dynamic libdecor loading]) + fi + if test x$have_loadso = xyes && \ + test x$enable_libdecor_shared = xyes && test x$decor_lib != x; then + echo "-- dynamic libdecor -> $decor_lib" + AC_DEFINE_UNQUOTED(SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR, "$decor_lib", [ ]) + else + EXTRA_LDFLAGS="$EXTRA_LDFLAGS $DECOR_LIBS" + fi + + saved_cflags=$CFLAGS + CFLAGS="$CFLAGS $DECOR_CFLAGS" + AC_CHECK_DECLS([libdecor_frame_get_min_content_size, libdecor_frame_get_max_content_size], [libdecor_get_min_max=yes], [ ], [[#include ]]) + if test x$libdecor_get_min_max = xyes; then + AC_DEFINE(SDL_HAVE_LIBDECOR_GET_MIN_MAX, 1, [ ]) + fi + CFLAGS="$saved_cflags" + fi + fi fi fi } - dnl Check for Native Client stuff CheckNativeClient() { - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #if !defined(__native_client__) #error "NO NACL" #endif - ],[ - ],[ + ]],[])], [ AC_DEFINE(SDL_VIDEO_DRIVER_NACL, 1, [ ]) AC_DEFINE(SDL_AUDIO_DRIVER_NACL, 1, [ ]) AC_DEFINE(HAVE_POW, 1, [ ]) @@ -1617,16 +1838,17 @@ CheckNativeClient() SDLMAIN_SOURCES="$srcdir/src/main/nacl/*.c" SOURCES="$SOURCES $srcdir/src/audio/nacl/*.c" SUMMARY_audio="${SUMMARY_audio} nacl" + have_audio=yes SOURCES="$SOURCES $srcdir/src/video/nacl/*.c" SUMMARY_video="${SUMMARY_video} nacl opengles2" - ]) + have_video=yes + ],[]) } - CheckRPI() { AC_ARG_ENABLE(video-rpi, -AS_HELP_STRING([--enable-video-rpi], [use Raspberry Pi video driver [[default=yes]]]), +[AS_HELP_STRING([--enable-video-rpi], [use Raspberry Pi 2/3 video driver [default=yes]])], , enable_video_rpi=yes) if test x$enable_video = xyes -a x$enable_video_rpi = xyes; then PKG_CHECK_MODULES([RPI], [bcm_host brcmegl], video_rpi=yes, video_rpi=no) @@ -1647,21 +1869,20 @@ AS_HELP_STRING([--enable-video-rpi], [use Raspberry Pi video driver [[default=ye # Add the Raspberry Pi compiler flags and libraries CFLAGS="$CFLAGS $RPI_CFLAGS"; LIBS="$LIBS $RPI_LIBS" - AC_MSG_CHECKING(for Raspberry Pi) + AC_MSG_CHECKING(for Raspberry Pi 2/3) have_video_rpi=no - AC_TRY_LINK([ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include - ],[ + #include + ]], [[ + EGL_DISPMANX_WINDOW_T window; bcm_host_init(); - ],[ - have_video_rpi=yes - ],[ - ]) + ]])], [have_video_rpi=yes],[]) AC_MSG_RESULT($have_video_rpi) # Restore the compiler flags and libraries CFLAGS="$ac_save_cflags"; LIBS="$ac_save_libs" - + if test x$have_video_rpi = xyes; then CFLAGS="$CFLAGS $RPI_CFLAGS" SDL_CFLAGS="$SDL_CFLAGS $RPI_CFLAGS" @@ -1670,6 +1891,7 @@ AS_HELP_STRING([--enable-video-rpi], [use Raspberry Pi video driver [[default=ye SOURCES="$SOURCES $srcdir/src/video/raspberry/*.c" AC_DEFINE(SDL_VIDEO_DRIVER_RPI, 1, [ ]) SUMMARY_video="${SUMMARY_video} rpi" + have_video=yes fi fi } @@ -1678,8 +1900,15 @@ dnl Find the X11 include and library directories CheckX11() { AC_ARG_ENABLE(video-x11, -AS_HELP_STRING([--enable-video-x11], [use X11 video driver [[default=yes]]]), - , enable_video_x11=yes) +[AS_HELP_STRING([--enable-video-x11], [use X11 video driver [default=maybe]])], + ,[ + enable_video_x11=yes + case "$host" in + *-*-darwin*|*-ios-*) + enable_video_x11=no + ;; + esac]) + if test x$enable_video = xyes -a x$enable_video_x11 = xyes; then case "$host" in *-*-darwin*) @@ -1697,7 +1926,7 @@ AS_HELP_STRING([--enable-video-x11], [use X11 video driver [[default=yes]]]), AC_PATH_XTRA if test x$have_x = xyes; then AC_ARG_ENABLE(x11-shared, -AS_HELP_STRING([--enable-x11-shared], [dynamically load X11 support [[default=maybe]]]), +[AS_HELP_STRING([--enable-x11-shared], [dynamically load X11 support [default=maybe]])], , enable_x11_shared=maybe) case "$host" in @@ -1706,34 +1935,31 @@ AS_HELP_STRING([--enable-x11-shared], [dynamically load X11 support [[default=ma x11_lib='/opt/X11/lib/libX11.6.dylib' x11ext_lib='/opt/X11/lib/libXext.6.dylib' xcursor_lib='/opt/X11/lib/libXcursor.1.dylib' - xinerama_lib='/opt/X11/lib/libXinerama.1.dylib' xinput_lib='/opt/X11/lib/libXi.6.dylib' + xfixes_lib='/opt/X11/lib/libXfixes.3.dylib' xrandr_lib='/opt/X11/lib/libXrandr.2.dylib' xrender_lib='/opt/X11/lib/libXrender.1.dylib' xss_lib='/opt/X11/lib/libXss.1.dylib' - xvidmode_lib='/opt/X11/lib/libXxf86vm.1.dylib' ;; *-*-openbsd*) x11_lib='libX11.so' x11ext_lib='libXext.so' xcursor_lib='libXcursor.so' - xinerama_lib='libXinerama.so' xinput_lib='libXi.so' + xfixes_lib='libXfixes.so' xrandr_lib='libXrandr.so' xrender_lib='libXrender.so' xss_lib='libXss.so' - xvidmode_lib='libXxf86vm.so' ;; *) x11_lib=[`find_lib "libX11.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'`] x11ext_lib=[`find_lib "libXext.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'`] xcursor_lib=[`find_lib "libXcursor.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'`] - xinerama_lib=[`find_lib "libXinerama.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'`] xinput_lib=[`find_lib "libXi.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'`] + xfixes_lib=[`find_lib "libXfixes.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'`] xrandr_lib=[`find_lib "libXrandr.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'`] xrender_lib=[`find_lib "libXrender.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'`] xss_lib=[`find_lib "libXss.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'`] - xvidmode_lib=[`find_lib "libXxf86vm.so.*" "$X_LIBS -L/usr/X11/$base_libdir -L/usr/X11R6/$base_libdir" | sed 's/.*\/\(.*\)/\1/; q'`] ;; esac @@ -1784,43 +2010,27 @@ AS_HELP_STRING([--enable-x11-shared], [dynamically load X11 support [[default=ma fi have_video=yes - AC_MSG_CHECKING(for const parameter to XextAddDisplay) - have_const_param_XextAddDisplay=no - AC_TRY_COMPILE([ - #include - #include - #include - #include - extern XExtDisplayInfo* XextAddDisplay(XExtensionInfo* a,Display* b,_Xconst char* c,XExtensionHooks* d,int e,XPointer f); - ],[ - ],[ - have_const_param_XextAddDisplay=yes - AC_DEFINE([SDL_VIDEO_DRIVER_X11_CONST_PARAM_XEXTADDDISPLAY], 1, [ ]) - ]) - AC_MSG_RESULT($have_const_param_XextAddDisplay) - - dnl AC_CHECK_LIB(X11, XGetEventData, AC_DEFINE(SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS, 1, [Have XGenericEvent])) AC_MSG_CHECKING([for XGenericEvent]) have_XGenericEvent=no - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include - ],[ + ]], [[ Display *display; XEvent event; XGenericEventCookie *cookie = &event.xcookie; XNextEvent(display, &event); XGetEventData(display, cookie); XFreeEventData(display, cookie); - ],[ + ]])], [ have_XGenericEvent=yes AC_DEFINE([SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS], 1, [ ]) - ]) + ],[]) AC_MSG_RESULT($have_XGenericEvent) AC_CHECK_LIB(X11, XkbKeycodeToKeysym, AC_DEFINE(SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM, 1, [Have XkbKeycodeToKeysym])) AC_ARG_ENABLE(video-x11-xcursor, -AS_HELP_STRING([--enable-video-x11-xcursor], [enable X11 Xcursor support [[default=yes]]]), +[AS_HELP_STRING([--enable-video-x11-xcursor], [enable X11 Xcursor support [default=yes]])], , enable_video_x11_xcursor=yes) if test x$enable_video_x11_xcursor = xyes; then definitely_enable_video_x11_xcursor=no @@ -1848,7 +2058,7 @@ AS_HELP_STRING([--enable-video-x11-xcursor], [enable X11 Xcursor support [[defau SUMMARY_video_x11="${SUMMARY_video_x11} xcursor" fi AC_ARG_ENABLE(video-x11-xdbe, -AS_HELP_STRING([--enable-video-x11-xdbe], [enable X11 Xdbe support [[default=yes]]]), +[AS_HELP_STRING([--enable-video-x11-xdbe], [enable X11 Xdbe support [default=yes]])], , enable_video_x11_xdbe=yes) if test x$enable_video_x11_xdbe = xyes; then AC_CHECK_HEADER(X11/extensions/Xdbe.h, @@ -1861,36 +2071,8 @@ AS_HELP_STRING([--enable-video-x11-xdbe], [enable X11 Xdbe support [[default=yes SUMMARY_video_x11="${SUMMARY_video_x11} xdbe" fi fi - AC_ARG_ENABLE(video-x11-xinerama, -AS_HELP_STRING([--enable-video-x11-xinerama], [enable X11 Xinerama support [[default=yes]]]), - , enable_video_x11_xinerama=yes) - if test x$enable_video_x11_xinerama = xyes; then - definitely_enable_video_x11_xinerama=no - AC_CHECK_HEADER(X11/extensions/Xinerama.h, - have_xinerama_h_hdr=yes, - have_xinerama_h_hdr=no, - [#include - ]) - if test x$have_xinerama_h_hdr = xyes; then - if test x$enable_x11_shared = xyes && test x$xinerama_lib != x ; then - echo "-- dynamic libXinerama -> $xinerama_lib" - AC_DEFINE_UNQUOTED(SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA, "$xinerama_lib", [ ]) - definitely_enable_video_x11_xinerama=yes - else - AC_CHECK_LIB(Xinerama, XineramaQueryExtension, have_xinerama_lib=yes) - if test x$have_xinerama_lib = xyes ; then - EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lXinerama" - definitely_enable_video_x11_xinerama=yes - fi - fi - fi - fi - if test x$definitely_enable_video_x11_xinerama = xyes; then - AC_DEFINE(SDL_VIDEO_DRIVER_X11_XINERAMA, 1, [ ]) - SUMMARY_video_x11="${SUMMARY_video_x11} xinerama" - fi AC_ARG_ENABLE(video-x11-xinput, -AS_HELP_STRING([--enable-video-x11-xinput], [enable X11 XInput extension for manymouse, tablets, etc [[default=yes]]]), +[AS_HELP_STRING([--enable-video-x11-xinput], [enable X11 XInput extension for manymouse, tablets, etc [default=yes]])], , enable_video_x11_xinput=yes) if test x$enable_video_x11_xinput = xyes; then definitely_enable_video_x11_xinput=no @@ -1918,35 +2100,67 @@ AS_HELP_STRING([--enable-video-x11-xinput], [enable X11 XInput extension for man AC_DEFINE(SDL_VIDEO_DRIVER_X11_XINPUT2, 1, [ ]) AC_MSG_CHECKING(for xinput2 multitouch) have_xinput2_multitouch=no - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include #include - ],[ + ]], [[ int event_type = XI_TouchBegin; XITouchClassInfo *t; - ],[ + ]])], [ have_xinput2_multitouch=yes - AC_DEFINE([SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH], 1, []) + AC_DEFINE([SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH], 1, [ ]) SUMMARY_video_x11="${SUMMARY_video_x11} xinput2_multitouch" - ]) + ],[]) AC_MSG_RESULT($have_xinput2_multitouch) fi + AC_ARG_ENABLE(video-x11-xfixes, +[AS_HELP_STRING([--enable-video-x11-xfixes], [enable X11 Xfixes support [default=yes]])], + , enable_video_x11_xfixes=yes) + if test x$enable_video_x11_xfixes = xyes; then + definitely_enable_video_x11_xfixes=no + # check along with XInput2.h because we use Xfixes with XIBarrierReleasePointer + AC_MSG_CHECKING(for X11/extensions/Xfixes.h) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #include + #include + #include + #include ]], + [BarrierEventID b;])], + [have_xfixes_h_hdr=yes], + [have_xfixes_h_hdr=no]) + AC_MSG_RESULT($have_xfixes_h_hdr) + if test x$have_xfixes_h_hdr = xyes; then + if test x$enable_x11_shared = xyes && test x$xfixes_lib != x ; then + echo "-- dynamic libXfixes -> $xfixes_lib" + AC_DEFINE_UNQUOTED(SDL_VIDEO_DRIVER_X11_DYNAMIC_XFIXES, "$xfixes_lib", [ ]) + definitely_enable_video_x11_xfixes=yes + else + AC_CHECK_LIB(Xfixes, XFixesCreatePointerBarrier, have_xfixes_lib=yes) + if test x$have_xfixes_lib = xyes ; then + EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lXfixes" + definitely_enable_video_x11_xfixes=yes + fi + fi + fi + fi + if test x$definitely_enable_video_x11_xfixes = xyes; then + AC_DEFINE(SDL_VIDEO_DRIVER_X11_XFIXES, 1, [ ]) + SUMMARY_video_x11="${SUMMARY_video_x11} xfixes" + fi AC_ARG_ENABLE(video-x11-xrandr, -AS_HELP_STRING([--enable-video-x11-xrandr], [enable X11 Xrandr extension for fullscreen [[default=yes]]]), +[AS_HELP_STRING([--enable-video-x11-xrandr], [enable X11 Xrandr extension for fullscreen [default=yes]])], , enable_video_x11_xrandr=yes) if test x$enable_video_x11_xrandr = xyes; then - dnl XRRScreenResources is only present in Xrandr >= 1.2, we use that as a test. +dnl XRRScreenResources is only present in Xrandr >= 1.2, we use that as a test. definitely_enable_video_x11_xrandr=no have_xrandr_h_hdr=no - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include - ],[ + ]], [[ XRRScreenResources *res = NULL; - ],[ - have_xrandr_h_hdr=yes - ]) + ]])], [have_xrandr_h_hdr=yes],[]) if test x$have_xrandr_h_hdr = xyes; then if test x$enable_x11_shared = xyes && test x$xrandr_lib != x ; then echo "-- dynamic libXrandr -> $xrandr_lib" @@ -1966,7 +2180,7 @@ AS_HELP_STRING([--enable-video-x11-xrandr], [enable X11 Xrandr extension for ful SUMMARY_video_x11="${SUMMARY_video_x11} xrandr" fi AC_ARG_ENABLE(video-x11-scrnsaver, -AS_HELP_STRING([--enable-video-x11-scrnsaver], [enable X11 screensaver extension [[default=yes]]]), +[AS_HELP_STRING([--enable-video-x11-scrnsaver], [enable X11 screensaver extension [default=yes]])], , enable_video_x11_scrnsaver=yes) if test x$enable_video_x11_scrnsaver = xyes; then AC_CHECK_HEADER(X11/extensions/scrnsaver.h, @@ -1993,7 +2207,7 @@ AS_HELP_STRING([--enable-video-x11-scrnsaver], [enable X11 screensaver extension SUMMARY_video_x11="${SUMMARY_video_x11} xscrnsaver" fi AC_ARG_ENABLE(video-x11-xshape, -AS_HELP_STRING([--enable-video-x11-xshape], [enable X11 XShape support [[default=yes]]]), +[AS_HELP_STRING([--enable-video-x11-xshape], [enable X11 XShape support [default=yes]])], , enable_video_x11_xshape=yes) if test x$enable_video_x11_xshape = xyes; then AC_CHECK_HEADER(X11/extensions/shape.h, @@ -2006,36 +2220,9 @@ AS_HELP_STRING([--enable-video-x11-xshape], [enable X11 XShape support [[default SUMMARY_video_x11="${SUMMARY_video_x11} xshape" fi fi - AC_ARG_ENABLE(video-x11-vm, -AS_HELP_STRING([--enable-video-x11-vm], [use X11 VM extension for fullscreen [[default=yes]]]), - , enable_video_x11_vm=yes) - if test x$enable_video_x11_vm = xyes; then - definitely_enable_video_x11_vm=no - AC_CHECK_HEADER(X11/extensions/xf86vmode.h, - have_vm_h_hdr=yes, - have_vm_h_hdr=no, - [#include - ]) - if test x$have_vm_h_hdr = xyes; then - if test x$enable_x11_shared = xyes && test x$xvidmode_lib != x ; then - echo "-- dynamic libXxf86vm -> $xvidmode_lib" - AC_DEFINE_UNQUOTED(SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE, "$xvidmode_lib", [ ]) - definitely_enable_video_x11_vm=yes - else - AC_CHECK_LIB(Xxf86vm, XF86VidModeQueryVersion, have_vm_lib=yes) - if test x$have_vm_lib = xyes ; then - EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lXxf86vm" - definitely_enable_video_x11_vm=yes - fi - fi - fi - fi - if test x$definitely_enable_video_x11_vm = xyes; then - AC_DEFINE(SDL_VIDEO_DRIVER_X11_XVIDMODE, 1, [ ]) - SUMMARY_video_x11="${SUMMARY_video_x11} xvidmode" - fi fi - else + fi + if test x$have_x != xyes; then # Prevent Mesa from including X11 headers EXTRA_CFLAGS="$EXTRA_CFLAGS -DMESA_EGL_NO_X11_HEADERS -DEGL_NO_X11" fi @@ -2045,31 +2232,25 @@ dnl Set up the Vivante video driver if enabled CheckVivanteVideo() { AC_ARG_ENABLE(video-vivante, -AS_HELP_STRING([--enable-video-vivante], [use Vivante EGL video driver [[default=yes]]]), +[AS_HELP_STRING([--enable-video-vivante], [use Vivante EGL video driver [default=yes]])], , enable_video_vivante=yes) if test x$enable_video = xyes -a x$enable_video_vivante = xyes; then AC_MSG_CHECKING(for Vivante VDK API) have_vivante_vdk=no - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #define LINUX #define EGL_API_FB #include - ],[ - ],[ - have_vivante_vdk=yes - ]) + ]],[])], [have_vivante_vdk=yes],[]) AC_MSG_RESULT($have_vivante_vdk) AC_MSG_CHECKING(for Vivante FB API) have_vivante_egl=no - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #define LINUX #define EGL_API_FB #include - ],[ - ],[ - have_vivante_egl=yes - ]) + ]],[])], [have_vivante_egl=yes],[]) AC_MSG_RESULT($have_vivante_egl) if test x$have_vivante_vdk = xyes -o x$have_vivante_egl = xyes; then @@ -2101,20 +2282,17 @@ dnl Set up the Cocoa video driver for Mac OS X (but not Darwin) CheckCOCOA() { AC_ARG_ENABLE(video-cocoa, -AS_HELP_STRING([--enable-video-cocoa], [use Cocoa video driver [[default=yes]]]), +[AS_HELP_STRING([--enable-video-cocoa], [use Cocoa video driver [default=yes]])], , enable_video_cocoa=yes) if test x$enable_video = xyes -a x$enable_video_cocoa = xyes; then save_CFLAGS="$CFLAGS" - dnl Work around that we don't have Objective-C support in autoconf +dnl Work around that we don't have Objective-C support in autoconf CFLAGS="$CFLAGS -x objective-c" AC_MSG_CHECKING(for Cocoa framework) have_cocoa=no - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #import - ],[ - ],[ - have_cocoa=yes - ]) + ]],[])], [have_cocoa=yes],[]) AC_MSG_RESULT($have_cocoa) CFLAGS="$save_CFLAGS" if test x$have_cocoa = xyes; then @@ -2129,29 +2307,26 @@ AS_HELP_STRING([--enable-video-cocoa], [use Cocoa video driver [[default=yes]]]) CheckMETAL() { AC_ARG_ENABLE(video-metal, -AC_HELP_STRING([--enable-video-metal], [include Metal support [[default=yes]]]), +[AS_HELP_STRING([--enable-video-metal], [include Metal support [default=yes]])], , enable_video_metal=yes) AC_ARG_ENABLE(render-metal, -AS_HELP_STRING([--enable-render-metal], [enable the Metal render driver [[default=yes]]]), +[AS_HELP_STRING([--enable-render-metal], [enable the Metal render driver [default=yes]])], , enable_render_metal=yes) if test x$enable_video = xyes -a x$enable_video_metal = xyes; then save_CFLAGS="$CFLAGS" - dnl Work around that we don't have Objective-C support in autoconf +dnl Work around that we don't have Objective-C support in autoconf CFLAGS="$CFLAGS -x objective-c" AC_MSG_CHECKING(for Metal framework) have_metal=no - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #import #import #import - #if !TARGET_CPU_X86_64 + #if TARGET_CPU_X86 #error Metal doesn't work on this configuration #endif - ],[ - ],[ - have_metal=yes - ]) + ]],[])], [have_metal=yes],[]) CFLAGS="$save_CFLAGS" AC_MSG_RESULT($have_metal) if test x$have_metal = xyes; then @@ -2168,12 +2343,11 @@ AS_HELP_STRING([--enable-render-metal], [enable the Metal render driver [[defaul fi } - dnl Find DirectFB CheckDirectFB() { AC_ARG_ENABLE(video-directfb, -AS_HELP_STRING([--enable-video-directfb], [use DirectFB video driver [[default=no]]]), +[AS_HELP_STRING([--enable-video-directfb], [use DirectFB video driver [default=no]])], , enable_video_directfb=no) if test x$enable_video = xyes -a x$enable_video_directfb = xyes; then PKG_CHECK_MODULES([DIRECTFB], [directfb >= 1.0.0], video_directfb=yes, video_directfb=no) @@ -2189,7 +2363,7 @@ AS_HELP_STRING([--enable-video-directfb], [use DirectFB video driver [[default=n if test x$video_directfb = xyes; then AC_ARG_ENABLE(directfb-shared, -AS_HELP_STRING([--enable-directfb-shared], [dynamically load directfb support [[default=yes]]]), +[AS_HELP_STRING([--enable-directfb-shared], [dynamically load directfb support [default=yes]])], , enable_directfb_shared=yes) AC_DEFINE(SDL_VIDEO_DRIVER_DIRECTFB, 1, [ ]) @@ -2197,11 +2371,8 @@ AS_HELP_STRING([--enable-directfb-shared], [dynamically load directfb support [[ SOURCES="$SOURCES $srcdir/src/video/directfb/*.c" EXTRA_CFLAGS="$EXTRA_CFLAGS $DIRECTFB_CFLAGS" - AC_MSG_CHECKING(for directfb dynamic loading support) directfb_shared=no - directfb_lib=[`find_lib "libdirectfb*.so.*" "$DIRECTFB_LIBS"`] - # | sed 's/.*\/\(.*\)/\1/; q'`] -AC_MSG_WARN("directfb $directfb_lib") + directfb_lib=[`find_lib "libdirectfb*.so.*" "$DIRECTFB_LIBS" | sed 's/.*\/\(.*\)/\1/; q'`] if test x$have_loadso != xyes && \ test x$enable_directfb_shared = xyes; then AC_MSG_WARN([You must have SDL_LoadObject() support for dynamic directfb loading]) @@ -2209,14 +2380,13 @@ AC_MSG_WARN("directfb $directfb_lib") if test x$have_loadso = xyes && \ test x$enable_directfb_shared = xyes && test x$directfb_lib != x; then directfb_shared=yes - echo "-- $directfb_lib_spec -> $directfb_lib" + echo "-- dynamic libdirectfb -> $directfb_lib" AC_DEFINE_UNQUOTED(SDL_VIDEO_DRIVER_DIRECTFB_DYNAMIC, "$directfb_lib", [ ]) SUMMARY_video="${SUMMARY_video} directfb(dynamic)" else EXTRA_LDFLAGS="$EXTRA_LDFLAGS $DIRECTFB_LIBS" SUMMARY_video="${SUMMARY_video} directfb" fi - AC_MSG_RESULT($directfb_shared) SDL_CFLAGS="$SDL_CFLAGS $DIRECTFB_CFLAGS" have_video=yes fi @@ -2227,14 +2397,17 @@ dnl Find KMSDRM CheckKMSDRM() { AC_ARG_ENABLE(video-kmsdrm, -AS_HELP_STRING([--enable-video-kmsdrm], [use KMSDRM video driver [[default=no]]]), - , enable_video_kmsdrm=no) +[AS_HELP_STRING([--enable-video-kmsdrm], [use KMSDRM video driver [default=yes]])], + , enable_video_kmsdrm=yes) + + if test x$enable_video = xyes && \ + test x$enable_video_kmsdrm = xyes && \ + test x$video_opengl_egl = xyes; then - if test x$enable_video = xyes -a x$enable_video_kmsdrm = xyes; then video_kmsdrm=no - PKG_CHECK_MODULES([LIBDRM], [libdrm >= 2.4.46], libdrm_avail=yes, libdrm_avail=no) - PKG_CHECK_MODULES([LIBGBM], [gbm >= 9.0.0], libgbm_avail=yes, libgbm_avail=no) + PKG_CHECK_MODULES([LIBDRM], [libdrm >= 1.4.82], libdrm_avail=yes, libdrm_avail=no) + PKG_CHECK_MODULES([LIBGBM], [gbm >= 11.1.0], libgbm_avail=yes, libgbm_avail=no) if test x$libdrm_avail = xyes -a x$libgbm_avail = xyes; then video_kmsdrm=yes @@ -2242,7 +2415,7 @@ AS_HELP_STRING([--enable-video-kmsdrm], [use KMSDRM video driver [[default=no]]] if test x$video_kmsdrm = xyes; then AC_ARG_ENABLE(kmsdrm-shared, -AS_HELP_STRING([--enable-kmsdrm-shared], [dynamically load kmsdrm support [[default=yes]]]), +[AS_HELP_STRING([--enable-kmsdrm-shared], [dynamically load kmsdrm support [default=yes]])], , enable_kmsdrm_shared=yes) AC_DEFINE(SDL_VIDEO_DRIVER_KMSDRM, 1, [ ]) @@ -2251,8 +2424,8 @@ AS_HELP_STRING([--enable-kmsdrm-shared], [dynamically load kmsdrm support [[defa AC_MSG_CHECKING(for kmsdrm dynamic loading support) kmsdrm_shared=no - drm_lib=[`find_lib "libdrm.so.*" "$DRM_LIBS"`] - gbm_lib=[`find_lib "libgbm.so.*" "$DRM_LIBS"`] + drm_lib=[`find_lib "libdrm.so.*" "$LIBDRM_LIBS"`] + gbm_lib=[`find_lib "libgbm.so.*" "$LIBGBM_LIBS"`] if test x$have_loadso != xyes && \ test x$enable_kmsdrm_shared = xyes; then AC_MSG_WARN([You must have SDL_LoadObject() support for dynamic kmsdrm loading]) @@ -2269,6 +2442,10 @@ AS_HELP_STRING([--enable-kmsdrm-shared], [dynamically load kmsdrm support [[defa SUMMARY_video="${SUMMARY_video} kmsdrm" fi AC_MSG_RESULT($kmsdrm_shared) + if test x$kmsdrm_shared = xyes; then + echo "-- dynamic libdrm -> $drm_lib" + echo "-- dynamic libgbm -> $gbm_lib" + fi have_video=yes fi fi @@ -2278,7 +2455,7 @@ dnl rcg04172001 Set up the Null video driver. CheckDummyVideo() { AC_ARG_ENABLE(video-dummy, -AS_HELP_STRING([--enable-video-dummy], [use dummy video driver [[default=yes]]]), +[AS_HELP_STRING([--enable-video-dummy], [use dummy video driver [default=yes]])], , enable_video_dummy=yes) if test x$enable_video_dummy = xyes; then AC_DEFINE(SDL_VIDEO_DRIVER_DUMMY, 1, [ ]) @@ -2288,6 +2465,19 @@ AS_HELP_STRING([--enable-video-dummy], [use dummy video driver [[default=yes]]]) fi } +CheckOffscreenVideo() +{ + AC_ARG_ENABLE(video-offscreen, +[AS_HELP_STRING([--enable-video-offscreen], [use offscreen video driver [default=yes]])], + , enable_video_offscreen=yes) + if test x$enable_video_offscreen = xyes; then + AC_DEFINE(SDL_VIDEO_DRIVER_OFFSCREEN, 1, [ ]) + SOURCES="$SOURCES $srcdir/src/video/offscreen/*.c" + have_video=yes + SUMMARY_video="${SUMMARY_video} offscreen" + fi +} + dnl Set up the QNX video driver if enabled CheckQNXVideo() { @@ -2314,74 +2504,88 @@ CheckQNXAudio() dnl Check to see if OpenGL support is desired AC_ARG_ENABLE(video-opengl, -AS_HELP_STRING([--enable-video-opengl], [include OpenGL support [[default=yes]]]), +[AS_HELP_STRING([--enable-video-opengl], [include OpenGL support [default=yes]])], , enable_video_opengl=yes) -dnl Find OpenGL -CheckOpenGLX11() +dnl Find GLX +CheckGLX() { if test x$enable_video = xyes -a x$enable_video_opengl = xyes; then - AC_MSG_CHECKING(for OpenGL (GLX) support) - video_opengl=no - AC_TRY_COMPILE([ - #include + AC_MSG_CHECKING(for GLX support) + video_opengl_glx=no + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include - ],[ - ],[ - video_opengl=yes - ]) - AC_MSG_RESULT($video_opengl) - if test x$video_opengl = xyes; then + ]],[])], [video_opengl_glx=yes],[]) + AC_MSG_RESULT($video_opengl_glx) + if test x$video_opengl_glx = xyes; then AC_DEFINE(SDL_VIDEO_OPENGL, 1, [ ]) AC_DEFINE(SDL_VIDEO_OPENGL_GLX, 1, [ ]) - AC_DEFINE(SDL_VIDEO_RENDER_OGL, 1, [ ]) - SUMMARY_video="${SUMMARY_video} opengl" fi fi } dnl Check to see if OpenGL ES support is desired AC_ARG_ENABLE(video-opengles, -AS_HELP_STRING([--enable-video-opengles], [include OpenGL ES support [[default=yes]]]), +[AS_HELP_STRING([--enable-video-opengles], [include OpenGL ES support [default=yes]])], , enable_video_opengles=yes) AC_ARG_ENABLE(video-opengles1, -AS_HELP_STRING([--enable-video-opengles1], [include OpenGL ES 1.1 support [[default=yes]]]), +[AS_HELP_STRING([--enable-video-opengles1], [include OpenGL ES 1.1 support [default=yes]])], , enable_video_opengles1=yes) AC_ARG_ENABLE(video-opengles2, -AS_HELP_STRING([--enable-video-opengles2], [include OpenGL ES 2.0 support [[default=yes]]]), +[AS_HELP_STRING([--enable-video-opengles2], [include OpenGL ES 2.0 support [default=yes]])], , enable_video_opengles2=yes) -dnl Find OpenGL ES -CheckOpenGLESX11() +dnl Find EGL +CheckEGL() { - if test x$enable_video = xyes -a x$enable_video_opengles = xyes; then + if test x$enable_video = xyes -a x$enable_video_opengl = xyes || test x$enable_video = xyes -a x$enable_video_opengles = xyes; then AC_MSG_CHECKING(for EGL support) video_opengl_egl=no - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #define LINUX #define EGL_API_FB #define MESA_EGL_NO_X11_HEADERS + #define EGL_NO_X11 #include #include - ],[ - ],[ - video_opengl_egl=yes - ]) + ]],[])], [video_opengl_egl=yes],[]) AC_MSG_RESULT($video_opengl_egl) if test x$video_opengl_egl = xyes; then AC_DEFINE(SDL_VIDEO_OPENGL_EGL, 1, [ ]) fi - + fi +} + +dnl Find OpenGL +CheckOpenGL() +{ + if test x$enable_video = xyes -a x$enable_video_opengl = xyes; then + AC_MSG_CHECKING(for OpenGL headers) + video_opengl=no + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #include + #include + ]],[])], [video_opengl=yes],[]) + AC_MSG_RESULT($video_opengl) + if test x$video_opengl = xyes; then + AC_DEFINE(SDL_VIDEO_OPENGL, 1, [ ]) + AC_DEFINE(SDL_VIDEO_RENDER_OGL, 1, [ ]) + SUMMARY_video="${SUMMARY_video} opengl" + fi + fi +} + +dnl Find OpenGL ES +CheckOpenGLES() +{ + if test x$enable_video = xyes -a x$enable_video_opengles = xyes; then if test x$enable_video_opengles1 = xyes; then AC_MSG_CHECKING(for OpenGL ES v1 headers) video_opengles_v1=no - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include - ],[ - ],[ - video_opengles_v1=yes - ]) + ]],[])], [video_opengles_v1=yes],[]) AC_MSG_RESULT($video_opengles_v1) if test x$video_opengles_v1 = xyes; then AC_DEFINE(SDL_VIDEO_OPENGL_ES, 1, [ ]) @@ -2389,17 +2593,14 @@ CheckOpenGLESX11() SUMMARY_video="${SUMMARY_video} opengl_es1" fi fi - + if test x$enable_video_opengles2 = xyes; then AC_MSG_CHECKING(for OpenGL ES v2 headers) video_opengles_v2=no - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include - ],[ - ],[ - video_opengles_v2=yes - ]) + ]],[])], [video_opengles_v2=yes],[]) AC_MSG_RESULT($video_opengles_v2) if test x$video_opengles_v2 = xyes; then AC_DEFINE(SDL_VIDEO_OPENGL_ES2, 1, [ ]) @@ -2428,28 +2629,22 @@ CheckWINDOWSGLES() AC_MSG_CHECKING(for EGL support) video_opengl_egl=no - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include - ],[ - ],[ - video_opengl_egl=yes - ]) + ]],[])], [video_opengl_egl=yes],[]) AC_MSG_RESULT($video_opengl_egl) if test x$video_opengl_egl = xyes; then AC_DEFINE(SDL_VIDEO_OPENGL, 1, [ ]) AC_DEFINE(SDL_VIDEO_OPENGL_EGL, 1, [ ]) SUMMARY_video="${SUMMARY_video} opengl_es1" fi - + AC_MSG_CHECKING(for OpenGL ES v2 headers) video_opengles_v2=no - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include - ],[ - ],[ - video_opengles_v2=yes - ]) + ]],[])], [video_opengles_v2=yes],[]) AC_MSG_RESULT($video_opengles_v2) if test x$video_opengles_v2 = xyes; then AC_DEFINE(SDL_VIDEO_OPENGL, 1, [ ]) @@ -2501,12 +2696,9 @@ CheckEmscriptenGLES() if test x$enable_video = xyes -a x$enable_video_opengles = xyes; then AC_MSG_CHECKING(for EGL support) video_opengl_egl=no - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include - ],[ - ],[ - video_opengl_egl=yes - ]) + ]],[])], [video_opengl_egl=yes],[]) AC_MSG_RESULT($video_opengl_egl) if test x$video_opengl_egl = xyes; then AC_DEFINE(SDL_VIDEO_OPENGL_EGL, 1, [ ]) @@ -2514,13 +2706,10 @@ CheckEmscriptenGLES() AC_MSG_CHECKING(for OpenGL ES v2 headers) video_opengles_v2=no - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include - ],[ - ],[ - video_opengles_v2=yes - ]) + ]],[])], [video_opengles_v2=yes],[]) AC_MSG_RESULT($video_opengles_v2) if test x$video_opengles_v2 = xyes; then AC_DEFINE(SDL_VIDEO_OPENGL_ES2, 1, [ ]) @@ -2532,7 +2721,7 @@ CheckEmscriptenGLES() dnl Check to see if Vulkan support is desired AC_ARG_ENABLE(video-vulkan, -AS_HELP_STRING([--enable-video-vulkan], [include Vulkan support [[default=yes]]]), +[AS_HELP_STRING([--enable-video-vulkan], [include Vulkan support [default=yes]])], , enable_video_vulkan=yes) dnl Find Vulkan Header @@ -2541,33 +2730,25 @@ CheckVulkan() if test x$enable_video = xyes -a x$enable_video_vulkan = xyes; then case "$host" in *-*-android*) - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #if defined(__ARM_ARCH) && __ARM_ARCH < 7 #error Vulkan doesn't work on this configuration #endif - ],[ - ],[ - ],[ - enable_video_vulkan=no - ]) + ]],[])], [],[enable_video_vulkan=no]) ;; *-*-darwin*) save_CFLAGS="$CFLAGS" - dnl Work around that we don't have Objective-C support in autoconf +dnl Work around that we don't have Objective-C support in autoconf CFLAGS="$CFLAGS -x objective-c" - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include #include - #if !TARGET_CPU_X86_64 + #if TARGET_CPU_X86 #error Vulkan doesn't work on this configuration #endif - ],[ - ],[ - ],[ - enable_video_vulkan=no - ]) + ]],[])], [],[enable_video_vulkan=no]) CFLAGS="$save_CFLAGS" ;; *) @@ -2579,6 +2760,10 @@ CheckVulkan() AC_MSG_WARN([Vulkan does not work on this configuration.]) fi fi + if test x$have_loadso != xyes; then + AC_MSG_WARN([Vulkan support is available, but disabled because there's no loadso.]) + enable_video_vulkan=no + fi if test x$enable_video_vulkan = xyes; then AC_DEFINE(SDL_VIDEO_VULKAN, 1, [ ]) SUMMARY_video="${SUMMARY_video} vulkan" @@ -2588,18 +2773,18 @@ CheckVulkan() dnl See if we can use the new unified event interface in Linux 2.4 CheckInputEvents() { - dnl Check for Linux 2.4 unified input event interface support +dnl Check for Linux 2.4 unified input event interface support + AC_CHECK_HEADERS(linux/input.h) + AC_MSG_CHECKING(for Linux 2.4 unified input interface) use_input_events=no - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include - ],[ + ]], [[ #ifndef EVIOCGNAME #error EVIOCGNAME() ioctl not available #endif - ],[ - use_input_events=yes - ]) + ]])], [use_input_events=yes],[]) AC_MSG_RESULT($use_input_events) if test x$use_input_events = xyes; then AC_DEFINE(SDL_INPUT_LINUXEV, 1, [ ]) @@ -2610,19 +2795,17 @@ CheckInputEvents() dnl See if we can use the kernel kd.h header CheckInputKD() { - AC_MSG_CHECKING(for Linux kd.h) use_input_kd=no - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include - ],[ + #include + ]], [[ struct kbentry kbe; kbe.kb_table = KG_CTRL; ioctl(0, KDGKBENT, &kbe); - ],[ - use_input_kd=yes - ]) + ]])], [use_input_kd=yes],[]) AC_MSG_RESULT($use_input_kd) if test x$use_input_kd = xyes; then AC_DEFINE(SDL_INPUT_LINUXKD, 1, [ ]) @@ -2630,11 +2813,52 @@ CheckInputKD() fi } +dnl See if we can use the FreeBSD kernel kbio.h header +CheckInputKBIO() +{ + AC_MSG_CHECKING(for FreeBSD kbio.h) + use_input_kbio=no + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #include + #include + ]], [[ + accentmap_t accTable; + ioctl(0, KDENABIO, 1); + ]])], [use_input_kbio=yes],[]) + AC_MSG_RESULT($use_input_kbio) + if test x$use_input_kbio = xyes; then + AC_DEFINE(SDL_INPUT_FBSDKBIO, 1, [ ]) + SUMMARY_input="${SUMMARY_input} fbsdkbio" + fi +} + +dnl See if we can use the wscons input driver +CheckInputWSCONS() +{ + AC_MSG_CHECKING(for OpenBSD wscons) + use_input_wscons=no + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #include + #include + #include + #include + #include + ]], [[ + struct wskbd_map_data data; + ioctl(0, WSKBDIO_GETMAP, &data); + ]])], [use_input_wscons=yes],[]) + AC_MSG_RESULT($use_input_wscons) + if test x$use_input_wscons = xyes; then + AC_DEFINE(SDL_INPUT_WSCONS, 1, [ ]) + SUMMARY_input="${SUMMARY_input} wscons" + fi +} + dnl See if the platform offers libudev for device enumeration and hotplugging. CheckLibUDev() { AC_ARG_ENABLE(libudev, -AS_HELP_STRING([--enable-libudev], [enable libudev support [[default=yes]]]), +[AS_HELP_STRING([--enable-libudev], [enable libudev support [default=yes]])], , enable_libudev=yes) if test x$enable_libudev = xyes; then AC_CHECK_HEADER(libudev.h, @@ -2656,16 +2880,16 @@ dnl See if the platform offers libdbus for various IPC techniques. CheckDBus() { AC_ARG_ENABLE(dbus, -AS_HELP_STRING([--enable-dbus], [enable D-Bus support [[default=yes]]]), +[AS_HELP_STRING([--enable-dbus], [enable D-Bus support [default=yes]])], , enable_dbus=yes) if test x$enable_dbus = xyes; then PKG_CHECK_MODULES([DBUS], [dbus-1], have_dbus=yes, have_dbus=no) - save_CFLAGS="$CFLAGS" - CFLAGS="$save_CFLAGS $DBUS_CFLAGS" + save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$save_CPPFLAGS $DBUS_CFLAGS" AC_CHECK_HEADER(dbus/dbus.h, have_dbus_dbus_h_hdr=yes, have_dbus_dbus_h_hdr=no) - CFLAGS="$save_CFLAGS" + CPPFLAGS="$save_CPPFLAGS" if test x$have_dbus_dbus_h_hdr = xyes; then AC_DEFINE(HAVE_DBUS_DBUS_H, 1, [ ]) EXTRA_CFLAGS="$EXTRA_CFLAGS $DBUS_CFLAGS" @@ -2678,7 +2902,7 @@ dnl See if the platform wanna IME support. CheckIME() { AC_ARG_ENABLE(ime, -AS_HELP_STRING([--enable-ime], [enable IME support [[default=yes]]]), +[AS_HELP_STRING([--enable-ime], [enable IME support [default=yes]])], , enable_ime=yes) if test x$enable_ime = xyes; then AC_DEFINE(SDL_USE_IME, 1, [ ]) @@ -2686,23 +2910,42 @@ AS_HELP_STRING([--enable-ime], [enable IME support [[default=yes]]]), fi } +dnl Check inotify presense +CheckInotify() +{ + save_LIBS="$LIBS" + case "$host" in + *-*-freebsd*|*-*dragonfly*) LIBS="$LIBS -linotify" + ;; + esac + AC_CHECK_HEADERS(sys/inotify.h, [have_inotify_inotify_h_hdr=yes]) + AC_CHECK_FUNCS(inotify_init, [have_inotify=yes]) + AC_CHECK_FUNCS(inotify_init1) + if test x$have_inotify_inotify_h_hdr = xyes -a x$have_inotify = xyes; then + AC_DEFINE(HAVE_INOTIFY, 1, [ ]) + case "$host" in + *-*-freebsd*|*-*-dragonfly*) + EXTRA_LDFLAGS="$EXTRA_LDFLAGS -linotify" + ;; + esac + fi + LIBS="$save_LIBS" +} + dnl See if the platform has libibus IME support. CheckIBus() { AC_ARG_ENABLE(ibus, -AS_HELP_STRING([--enable-ibus], [enable IBus support [[default=yes]]]), +[AS_HELP_STRING([--enable-ibus], [enable IBus support [default=yes]])], , enable_ibus=yes) if test x$enable_ibus = xyes; then PKG_CHECK_MODULES([IBUS], [ibus-1.0], have_ibus=yes, have_ibus=no) - save_CFLAGS="$CFLAGS" - CFLAGS="$save_CFLAGS $IBUS_CFLAGS" + save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$save_CPPFLAGS $IBUS_CFLAGS" AC_CHECK_HEADER(ibus-1.0/ibus.h, have_ibus_ibus_h_hdr=yes, have_ibus_ibus_h_hdr=no) - AC_CHECK_HEADER(sys/inotify.h, - have_inotify_inotify_h_hdr=yes, - have_inotify_inotify_h_hdr=no) - CFLAGS="$save_CFLAGS" + CPPFLAGS="$save_CPPFLAGS" if test x$have_ibus_ibus_h_hdr = xyes; then if test x$enable_ime != xyes; then AC_MSG_WARN([IME support is required for IBus.]) @@ -2726,51 +2969,59 @@ dnl See if the platform has fcitx IME support. CheckFcitx() { AC_ARG_ENABLE(fcitx, -AS_HELP_STRING([--enable-fcitx], [enable fcitx support [[default=yes]]]), +[AS_HELP_STRING([--enable-fcitx], [enable fcitx support [default=yes]])], , enable_fcitx=yes) if test x$enable_fcitx = xyes; then - PKG_CHECK_MODULES([FCITX], [fcitx], have_fcitx=yes, have_fcitx=no) - CFLAGS="$CFLAGS $FCITX_CFLAGS" - AC_CHECK_HEADER(fcitx/frontend.h, - have_fcitx_frontend_h_hdr=yes, - have_fcitx_frontend_h_hdr=no) - CFLAGS="$save_CFLAGS" - if test x$have_fcitx_frontend_h_hdr = xyes; then - if test x$enable_ime != xyes; then - AC_MSG_WARN([IME support is required for fcitx.]) - have_fcitx_frontend_h_hdr=no - elif test x$enable_dbus != xyes; then - AC_MSG_WARN([DBus support is required for fcitx.]) - have_fcitx_frontend_h_hdr=no - else - AC_DEFINE(HAVE_FCITX_FRONTEND_H, 1, [ ]) - EXTRA_CFLAGS="$EXTRA_CFLAGS $FCITX_CFLAGS" - SOURCES="$SOURCES $srcdir/src/core/linux/SDL_fcitx.c" - fi + AC_MSG_CHECKING(for fcitx support) + have_fcitx=no + if test x$enable_ime != xyes; then + AC_MSG_WARN([IME support is required for fcitx.]) + elif test x$have_dbus_dbus_h_hdr != xyes; then + AC_MSG_WARN([DBus support is required for fcitx.]) + else + have_fcitx=yes + AC_DEFINE(HAVE_FCITX, 1, [ ]) + SOURCES="$SOURCES $srcdir/src/core/linux/SDL_fcitx.c" fi + AC_MSG_RESULT($have_fcitx) fi } -dnl See if we can use the Touchscreen input library -CheckTslib() +dnl Check to see if GameController framework support is desired +CheckJoystickMFI() { - AC_ARG_ENABLE(input-tslib, -AS_HELP_STRING([--enable-input-tslib], [use the Touchscreen library for input [[default=yes]]]), - , enable_input_tslib=yes) - if test x$enable_input_tslib = xyes; then - AC_MSG_CHECKING(for Touchscreen library support) - enable_input_tslib=no - AC_TRY_COMPILE([ - #include "tslib.h" - ],[ - ],[ - enable_input_tslib=yes - ]) - AC_MSG_RESULT($enable_input_tslib) - if test x$enable_input_tslib = xyes; then - AC_DEFINE(SDL_INPUT_TSLIB, 1, [ ]) - EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lts" - SUMMARY_input="${SUMMARY_input} ts" + AC_ARG_ENABLE(joystick-mfi, +[AS_HELP_STRING([--enable-joystick-mfi], [include macOS MFI joystick support [default=yes]])], + , enable_joystick_mfi=yes) + + if test x$enable_joystick_mfi = xyes; then + save_CFLAGS="$CFLAGS" + save_LDFLAGS="$LDFLAGS" +dnl Work around that we don't have Objective-C support in autoconf + CFLAGS="$CFLAGS -x objective-c -fobjc-weak" + LDFLAGS="$LDFLAGS -Wl,-weak_framework,CoreHaptics -Wl,-weak_framework,GameController" + AC_MSG_CHECKING(for GameController framework) + enable_joystick_mfi=no + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + #include + #include + #import + ]], [[ + #if MAC_OS_X_VERSION_MIN_REQUIRED < 1080 + #error GameController framework doesn't work on this configuration + #endif + #if TARGET_CPU_X86 + #error GameController framework doesn't work on this configuration + #endif + ]])], [enable_joystick_mfi=yes],[]) + CFLAGS="$save_CFLAGS" + LDFLAGS="$save_LDFLAGS" + + AC_MSG_RESULT($enable_joystick_mfi) + if test x$enable_joystick_mfi = xyes; then + AC_DEFINE(SDL_JOYSTICK_MFI, 1, [ ]) + EXTRA_CFLAGS="$EXTRA_CFLAGS -fobjc-weak -Wno-unused-command-line-argument" + EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-weak_framework,CoreHaptics -Wl,-weak_framework,GameController" fi fi } @@ -2778,14 +3029,40 @@ AS_HELP_STRING([--enable-input-tslib], [use the Touchscreen library for input [[ dnl See what type of thread model to use on Linux and Solaris CheckPTHREAD() { - dnl Check for pthread support +dnl Check for pthread support + +dnl Emscripten pthreads work, but you need to have a non-pthread fallback build +dnl for systems without support. It's not currently enough to not use +dnl pthread functions in a pthread-build; it won't start up on unsupported +dnl browsers. As such, you have to explicitly enable it on Emscripten builds +dnl for the time being. This default with change to ON once this becomes +dnl commonly supported in browsers or the Emscripten teams makes a single +dnl binary work everywhere. + + case "$host" in + *-*-emscripten*) + enable_pthreads_default=no + ;; + *) + enable_pthreads_default=yes + ;; + esac + AC_ARG_ENABLE(pthreads, -AS_HELP_STRING([--enable-pthreads], [use POSIX threads for multi-threading [[default=yes]]]), - , enable_pthreads=yes) - dnl This is used on Linux for glibc binary compatibility (Doh!) +[AS_HELP_STRING([--enable-pthreads], [use POSIX threads for multi-threading [default=maybe]])], + , enable_pthreads=maybe) +dnl This is used on Linux for glibc binary compatibility (Doh!) AC_ARG_ENABLE(pthread-sem, -AS_HELP_STRING([--enable-pthread-sem], [use pthread semaphores [[default=yes]]]), - , enable_pthread_sem=yes) +[AS_HELP_STRING([--enable-pthread-sem], [use pthread semaphores [default=maybe]])], + , enable_pthread_sem=maybe) + + if test x$enable_pthreads = xmaybe; then + enable_pthreads=$enable_pthreads_default + fi + if test x$enable_pthread_sem = xmaybe; then + enable_pthread_sem=$enable_pthreads + fi + case "$host" in *-*-android*) pthread_cflags="-D_REENTRANT -D_THREAD_SAFE" @@ -2814,7 +3091,7 @@ AS_HELP_STRING([--enable-pthread-sem], [use pthread semaphores [[default=yes]]]) ;; *-*-openbsd*) pthread_cflags="-D_REENTRANT" - pthread_lib="-pthread" + pthread_lib="-lpthread" ;; *-*-solaris2.9) # From Solaris 9+, posix4's preferred name is rt. @@ -2851,6 +3128,10 @@ AS_HELP_STRING([--enable-pthread-sem], [use pthread semaphores [[default=yes]]]) pthread_cflags="-D_REENTRANT" pthread_lib="" ;; + *-*-emscripten*) + pthread_cflags="-D_REENTRANT -pthread" + pthread_lib="-pthread" + ;; *) pthread_cflags="-D_REENTRANT" pthread_lib="-lpthread" @@ -2864,14 +3145,12 @@ AS_HELP_STRING([--enable-pthread-sem], [use pthread semaphores [[default=yes]]]) # Check to see if we have pthread support on this system AC_MSG_CHECKING(for pthreads) use_pthreads=no - AC_TRY_LINK([ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include - ],[ + ]], [[ pthread_attr_t type; pthread_attr_init(&type); - ],[ - use_pthreads=yes - ]) + ]])], [use_pthreads=yes],[]) AC_MSG_RESULT($use_pthreads) # Restore the compiler flags and libraries CFLAGS="$ac_save_cflags"; LIBS="$ac_save_libs" @@ -2892,28 +3171,28 @@ AS_HELP_STRING([--enable-pthread-sem], [use pthread semaphores [[default=yes]]]) AC_MSG_CHECKING(for recursive mutexes) has_recursive_mutexes=no if test x$has_recursive_mutexes = xno; then - AC_TRY_LINK([ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #define _GNU_SOURCE 1 #include - ],[ + ]], [[ pthread_mutexattr_t attr; pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); - ],[ + ]])], [ has_recursive_mutexes=yes AC_DEFINE(SDL_THREAD_PTHREAD_RECURSIVE_MUTEX, 1, [ ]) - ]) + ],[]) fi if test x$has_recursive_mutexes = xno; then - AC_TRY_LINK([ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #define _GNU_SOURCE 1 #include - ],[ + ]], [[ pthread_mutexattr_t attr; pthread_mutexattr_setkind_np(&attr, PTHREAD_MUTEX_RECURSIVE_NP); - ],[ + ]])],[ has_recursive_mutexes=yes AC_DEFINE(SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP, 1, [ ]) - ]) + ],[]) fi AC_MSG_RESULT($has_recursive_mutexes) @@ -2921,27 +3200,24 @@ AS_HELP_STRING([--enable-pthread-sem], [use pthread semaphores [[default=yes]]]) if test x$enable_pthread_sem = xyes; then AC_MSG_CHECKING(for pthread semaphores) have_pthread_sem=no - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include - ],[ - ],[ - have_pthread_sem=yes - ]) + ]],[])], [have_pthread_sem=yes],[]) AC_MSG_RESULT($have_pthread_sem) fi if test x$have_pthread_sem = xyes; then AC_MSG_CHECKING(for sem_timedwait) have_sem_timedwait=no - AC_TRY_LINK([ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include #include - ],[ + ]], [[ sem_timedwait(NULL, NULL); - ],[ + ]])], [ have_sem_timedwait=yes AC_DEFINE([HAVE_SEM_TIMEDWAIT], 1, [ ]) - ]) + ],[]) AC_MSG_RESULT($have_sem_timedwait) fi @@ -3004,12 +3280,9 @@ CheckWINDOWS() { AC_MSG_CHECKING(Windows compiler) have_win32_gcc=no - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include - ],[ - ],[ - have_win32_gcc=yes - ]) + ]],[])], [have_win32_gcc=yes],[]) AC_MSG_RESULT($have_win32_gcc) if test x$have_win32_gcc != xyes; then AC_MSG_ERROR([ @@ -3019,47 +3292,69 @@ CheckWINDOWS() AC_MSG_CHECKING(Windows CE) have_wince=no - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #if !defined(_WIN32_WCE) && !defined(__MINGW32CE__) #error This is not Windows CE #endif - ],[ - ],[ + ]],[])], [ have_wince=yes AC_MSG_ERROR([ *** Sorry, Windows CE is no longer supported. ]) - ]) + ],[]) AC_MSG_RESULT($have_wince) - # This fixes Windows stack alignment with newer GCC - CheckStackBoundary + # headers needed elsewhere + AC_CHECK_HEADER(tpcshrd.h,have_tpcshrd_h=yes) + if test x$have_tpcshrd_h = xyes; then + AC_DEFINE(HAVE_TPCSHRD_H, 1, [ ]) + fi + AC_CHECK_HEADER(roapi.h,have_roapi_h=yes) + if test x$have_roapi_h = xyes; then + AC_DEFINE(HAVE_ROAPI_H, 1, [ ]) + fi + AC_CHECK_HEADER(shellscalingapi.h,have_shellscalingapi_h=yes) + if test x$shellscalingapi_h = xyes; then + AC_DEFINE(HAVE_SHELLSCALINGAPI_H, 1, [ ]) + fi +} + +dnl Determine whether the compiler can produce OS/2 executables +CheckOS2() +{ + AC_MSG_CHECKING(OS/2 compiler) + have_os2_gcc=no + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], + [])],[have_os2_gcc=yes],[]) + AC_MSG_RESULT($have_os2_gcc) + if test x$have_os2_gcc != xyes; then + AC_MSG_ERROR([ +*** Your compiler ($CC) does not produce OS/2 executables! + ]) + fi } dnl Find the DirectX includes and libraries CheckDIRECTX() { AC_ARG_ENABLE(directx, -AS_HELP_STRING([--enable-directx], [use DirectX for Windows audio/video [[default=yes]]]), - , enable_directx=yes) +[AS_HELP_STRING([--enable-directx], [use DirectX for Windows audio/video [default=yes]])], + , enable_directx=yes) if test x$enable_directx = xyes; then AC_CHECK_HEADER(d3d9.h, have_d3d=yes) AC_CHECK_HEADER(d3d11_1.h, have_d3d11=yes) + AC_MSG_CHECKING(for compatible d3d12 headers) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#include +ID3D12Device1 *device; + ]])], [have_d3d12=yes],[have_d3d12=no]) + AC_MSG_RESULT($have_d3d12) + AC_CHECK_HEADER(ddraw.h, have_ddraw=yes) AC_CHECK_HEADER(dsound.h, have_dsound=yes) AC_CHECK_HEADER(dinput.h, have_dinput=yes) AC_CHECK_HEADER(dxgi.h, have_dxgi=yes) - AC_CHECK_HEADER(xinput.h, have_xinput=yes) - AC_TRY_COMPILE([ -#include -#include -XINPUT_GAMEPAD_EX x1; - ],[],[have_xinput_gamepadex=yes]) - AC_TRY_COMPILE([ -#include -#include -XINPUT_STATE_EX s1; - ],[],[have_xinput_stateex=yes]) if test x$have_ddraw = xyes; then AC_DEFINE(HAVE_DDRAW_H, 1, [ ]) @@ -3073,15 +3368,6 @@ XINPUT_STATE_EX s1; if test x$have_dxgi = xyes; then AC_DEFINE(HAVE_DXGI_H, 1, [ ]) fi - if test x$have_xinput = xyes; then - AC_DEFINE(HAVE_XINPUT_H, 1, [ ]) - fi - if test x$have_xinput_gamepadex = xyes; then - AC_DEFINE(HAVE_XINPUT_GAMEPAD_EX, 1, [ ]) - fi - if test x$have_xinput_stateex = xyes; then - AC_DEFINE(HAVE_XINPUT_STATE_EX, 1, [ ]) - fi # FIXME: latest Cygwin finds dinput headers, but we die on other win32 headers. # FIXME: ...so force it off for now. @@ -3092,47 +3378,76 @@ XINPUT_STATE_EX s1; esac fi + AC_ARG_ENABLE(xinput, +[AS_HELP_STRING([--enable-xinput], [use Xinput for Windows [default=yes]])], + , enable_xinput=yes) + if test x$enable_xinput = xyes; then + AC_CHECK_HEADER(xinput.h, have_xinput=yes) + if test x$have_xinput = xyes; then + AC_DEFINE(HAVE_XINPUT_H, 1, [ ]) + fi + fi + + AC_MSG_CHECKING(for windows.gaming.input.h) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#define COBJMACROS +#include +__x_ABI_CWindows_CGaming_CInput_CIGamepadStatics2 *s2; + ]],[])], [have_wgi=yes],[have_wgi=no]) + AC_MSG_RESULT($have_wgi) + + if test x$have_wgi = xyes; then + AC_DEFINE(HAVE_WINDOWS_GAMING_INPUT_H, 1, [ ]) + fi + AC_CHECK_HEADER(mmdeviceapi.h, have_wasapi=yes) if test x$have_wasapi = xyes; then - AC_DEFINE(HAVE_MMDEVICEAPI_H,1,[]) + AC_DEFINE(HAVE_MMDEVICEAPI_H, 1, [ ]) fi AC_CHECK_HEADER(audioclient.h,,have_wasapi=no) if test x$have_wasapi = xyes; then - AC_DEFINE(HAVE_AUDIOCLIENT_H,1,[]) + AC_DEFINE(HAVE_AUDIOCLIENT_H, 1, [ ]) fi AC_ARG_ENABLE(wasapi, -AS_HELP_STRING([--enable-wasapi], [use the Windows WASAPI audio driver [[default=yes]]]), +[AS_HELP_STRING([--enable-wasapi], [use the Windows WASAPI audio driver [default=yes]])], , enable_wasapi=yes) } dnl Check for the dlfcn.h interface for dynamically loading objects +dnl NOTE: CheckDLOPEN is called only for relevant platforms CheckDLOPEN() { - AC_ARG_ENABLE(sdl-dlopen, -AS_HELP_STRING([--enable-sdl-dlopen], [use dlopen for shared object loading [[default=yes]]]), - , enable_sdl_dlopen=yes) - if test x$enable_sdl_dlopen = xyes; then - AC_MSG_CHECKING(for dlopen) - have_dlopen=no - AC_TRY_COMPILE([ - #include - ],[ - void *handle = dlopen("", RTLD_NOW); - const char *loaderror = (char *) dlerror(); - ],[ - have_dlopen=yes - ]) - AC_MSG_RESULT($have_dlopen) + AC_DEFINE(DYNAPI_NEEDS_DLOPEN, 1, [ ]) - if test x$have_dlopen = xyes; then - AC_CHECK_LIB(c, dlopen, EXTRA_LDFLAGS="$EXTRA_LDFLAGS", - AC_CHECK_LIB(dl, dlopen, EXTRA_LDFLAGS="$EXTRA_LDFLAGS -ldl", - AC_CHECK_LIB(ltdl, dlopen, EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lltdl"))) - AC_DEFINE(SDL_LOADSO_DLOPEN, 1, [ ]) - SOURCES="$SOURCES $srcdir/src/loadso/dlopen/*.c" - have_loadso=yes - fi + AC_CHECK_HEADER(dlfcn.h,have_dlfcn_h=yes,have_dlfcn_h=no) + + have_dlopen=no + AC_CHECK_LIB(c, dlopen, have_dlopen=yes, + AC_CHECK_LIB(dl, dlopen, [have_dlopen=yes; EXTRA_LDFLAGS="$EXTRA_LDFLAGS -ldl"])) + AC_MSG_CHECKING(for dlopen) + AC_MSG_RESULT($have_dlopen) + + if test x$have_dlfcn_h = xyes -a x$have_dlopen = xyes; then + AC_DEFINE(HAVE_DLOPEN, 1, [ ]) + if test x$enable_loadso = xyes; then + AC_DEFINE(SDL_LOADSO_DLOPEN, 1, [ ]) + SOURCES="$SOURCES $srcdir/src/loadso/dlopen/*.c" + have_loadso=yes + fi + fi +} + +CheckO_CLOEXEC() +{ + AC_MSG_CHECKING(for O_CLOEXEC) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +int flag = O_CLOEXEC; + ]],[])], [have_o_cloexec=yes],[have_o_cloexec=no]) + AC_MSG_RESULT($have_o_cloexec) + if test $have_o_cloexec = yes; then + AC_DEFINE(HAVE_O_CLOEXEC, 1, [ ]) fi } @@ -3140,7 +3455,7 @@ dnl Check for the usbhid(3) library on *BSD CheckUSBHID() { case "$host" in - *-*-*bsd*) + *-*-*bsd*|*-*-dragonfly*) if test x$enable_joystick = xyes; then AC_CHECK_LIB(usbhid, hid_init, have_libusbhid=yes) if test x$have_libusbhid = xyes; then @@ -3152,20 +3467,20 @@ CheckUSBHID() AC_CHECK_HEADER(libusb.h, [USB_CFLAGS="-DHAVE_LIBUSB_H"]) AC_CHECK_LIB(usb, hid_init, [USB_LIBS="$USB_LIBS -lusb"]) fi - + save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $USB_CFLAGS" AC_MSG_CHECKING(for usbhid) have_usbhid=no - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #if defined(HAVE_USB_H) #include #endif #ifdef __DragonFly__ - # include - # include + # include + # include #else # include # include @@ -3177,26 +3492,24 @@ CheckUSBHID() #elif defined(HAVE_LIBUSBHID_H) #include #endif - ],[ + ]], [[ struct report_desc *repdesc; struct usb_ctl_report *repbuf; hid_kind_t hidkind; - ],[ - have_usbhid=yes - ]) + ]])], [have_usbhid=yes],[]) AC_MSG_RESULT($have_usbhid) if test x$have_usbhid = xyes; then AC_MSG_CHECKING(for ucr_data member of usb_ctl_report) have_usbhid_ucr_data=no - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #if defined(HAVE_USB_H) #include #endif #ifdef __DragonFly__ - # include - # include + # include + # include #else # include # include @@ -3208,27 +3521,25 @@ CheckUSBHID() #elif defined(HAVE_LIBUSBHID_H) #include #endif - ],[ + ]], [[ struct usb_ctl_report buf; if (buf.ucr_data) { } - ],[ - have_usbhid_ucr_data=yes - ]) + ]])], [have_usbhid_ucr_data=yes],[]) if test x$have_usbhid_ucr_data = xyes; then USB_CFLAGS="$USB_CFLAGS -DUSBHID_UCR_DATA" fi AC_MSG_RESULT($have_usbhid_ucr_data) - + AC_MSG_CHECKING(for new usbhid API) have_usbhid_new=no - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #if defined(HAVE_USB_H) #include #endif #ifdef __DragonFly__ - #include - #include + #include + #include #else #include #include @@ -3240,12 +3551,10 @@ CheckUSBHID() #elif defined(HAVE_LIBUSBHID_H) #include #endif - ],[ + ]], [[ report_desc_t d; hid_start_parse(d, 1, 1); - ],[ - have_usbhid_new=yes - ]) + ]])], [have_usbhid_new=yes],[]) if test x$have_usbhid_new = xyes; then USB_CFLAGS="$USB_CFLAGS -DUSBHID_NEW" fi @@ -3253,15 +3562,13 @@ CheckUSBHID() AC_MSG_CHECKING(for struct joystick in machine/joystick.h) have_machine_joystick=no - AC_TRY_COMPILE([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include - ],[ + ]], [[ struct joystick t; - ],[ - have_machine_joystick=yes - ]) + ]])], [have_machine_joystick=yes],[]) if test x$have_machine_joystick = xyes; then - AC_DEFINE(SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H, 1, [ ]) + AC_DEFINE(SDL_HAVE_MACHINE_JOYSTICK_H, 1, [ ]) fi AC_MSG_RESULT($have_machine_joystick) @@ -3271,6 +3578,7 @@ CheckUSBHID() EXTRA_LDFLAGS="$EXTRA_LDFLAGS $USB_LIBS" have_joystick=yes fi + CFLAGS="$save_CFLAGS" fi ;; @@ -3280,50 +3588,46 @@ CheckUSBHID() dnl Check for HIDAPI joystick drivers CheckHIDAPI() { - # The hidraw support doesn't catch Xbox, PS4 and Nintendo controllers, - # so we'll just use libusb when it's available. - case "$host" in - # libusb does not support iOS - arm*-apple-darwin* | *-ios-* ) - skiplibusb=yes - ;; - # On the other hand, *BSD specifically uses libusb only - *-*-*bsd* ) - onlylibusb=yes - ;; - esac + AC_ARG_ENABLE(hidapi-joystick, +[AS_HELP_STRING([--enable-hidapi-joystick], [use HIDAPI for low level joystick drivers [default=yes]])], + , enable_hidapi_joystick=yes) + AC_ARG_ENABLE(hidapi-libusb, +[AS_HELP_STRING([--enable-hidapi-libusb], [use libusb for low level joystick drivers [default=maybe]])], + , enable_hidapi_libusb=maybe) - AC_ARG_ENABLE(hidapi, -AS_HELP_STRING([--enable-hidapi], [use HIDAPI for low level joystick drivers [[default=no]]]), - , enable_hidapi=no) - if test x$enable_joystick = xyes -a x$enable_hidapi = xyes; then - if test x$skiplibusb = xyes; then - hidapi_support=yes - else + if test x$enable_hidapi = xyes; then + case "$host" in + # libusb does not support iOS + *-ios-* ) + enable_hidapi_libusb=no + ;; + # On the other hand, *BSD specifically uses libusb only + *-*-*bsd* ) + enable_hidapi_libusb=yes + require_hidapi_libusb=yes + ;; + *-*-os2* ) + enable_hidapi_libusb=yes + ;; + esac + + hidapi_support=yes + if test x$enable_hidapi_libusb = xyes; then PKG_CHECK_MODULES([LIBUSB], [libusb-1.0], have_libusb=yes, have_libusb=no) - save_CFLAGS="$CFLAGS" - CFLAGS="$save_CFLAGS $LIBUSB_CFLAGS" - AC_CHECK_HEADER(libusb.h, have_libusb_h=yes) - CFLAGS="$save_CFLAGS" - if test x$have_libusb_h = xyes; then - hidapi_support=yes - elif test x$onlylibusb = xyes; then + save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$save_CPPFLAGS $LIBUSB_CFLAGS" + AC_CHECK_HEADER(libusb.h, have_libusb_h=yes, have_libusb_h=no) + CPPFLAGS="$save_CPPFLAGS" + if test x$have_libusb_h = xno && test x$require_hidapi_libusb = xyes; then hidapi_support=no - else - hidapi_support=yes fi fi if test x$hidapi_support = xyes; then - AC_DEFINE(SDL_JOYSTICK_HIDAPI, 1, [ ]) - EXTRA_CFLAGS="$EXTRA_CFLAGS -I$srcdir/src/hidapi/hidapi" - SOURCES="$SOURCES $srcdir/src/joystick/hidapi/*.c" - SOURCES="$SOURCES $srcdir/src/hidapi/SDL_hidapi.c" - if test x$have_libusb_h = xyes; then + AC_DEFINE(HAVE_LIBUSB) EXTRA_CFLAGS="$EXTRA_CFLAGS $LIBUSB_CFLAGS" - if test x$onlylibusb = xyes; then - SOURCES="$SOURCES $srcdir/src/hidapi/libusb/hid.c" + if test x$require_hidapi_libusb = xyes; then EXTRA_LDFLAGS="$EXTRA_LDFLAGS $LIBUSB_LIBS" else if test x$have_loadso != xyes; then @@ -3335,9 +3639,12 @@ AS_HELP_STRING([--enable-hidapi], [use HIDAPI for low level joystick drivers [[d *-*-darwin* ) libusb_lib="libusb-1.0.0.dylib" ;; - *-*-cygwin* | *-*-mingw32* ) + *-*-cygwin* | *-*-mingw* ) libusb_lib="libusb-1.0.dll" ;; + *-*-os2* ) + libusb_lib="usb100.dll" + ;; esac if test x$libusb_lib = x; then libusb_lib=[`find_lib "libusb-1.0.so.*" "" | sed 's/.*\/\(.*\)/\1/; q'`] @@ -3347,27 +3654,31 @@ AS_HELP_STRING([--enable-hidapi], [use HIDAPI for low level joystick drivers [[d fi fi - AC_MSG_CHECKING(for hidapi support) + AC_MSG_CHECKING(for hidapi joystick support) AC_MSG_RESULT($hidapi_support) fi + + if test x$enable_joystick = xyes -a x$hidapi_support = xyes -a x$enable_hidapi_joystick = xyes; then + AC_DEFINE(SDL_JOYSTICK_HIDAPI, 1, [ ]) + SOURCES="$SOURCES $srcdir/src/joystick/hidapi/*.c" + fi } dnl Check for clock_gettime() CheckClockGettime() { AC_ARG_ENABLE(clock_gettime, -AS_HELP_STRING([--enable-clock_gettime], [use clock_gettime() instead of gettimeofday() on UNIX [[default=yes]]]), +[AS_HELP_STRING([--enable-clock_gettime], [use clock_gettime() instead of gettimeofday() on UNIX [default=yes]])], , enable_clock_gettime=yes) if test x$enable_clock_gettime = xyes; then - AC_CHECK_LIB(rt, clock_gettime, have_clock_gettime=yes) + AC_CHECK_LIB(c, clock_gettime, have_clock_gettime=yes) if test x$have_clock_gettime = xyes; then - AC_DEFINE(HAVE_CLOCK_GETTIME, 1, [ ]) - EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lrt" + AC_DEFINE(HAVE_CLOCK_GETTIME, 1, [ ]) else - AC_CHECK_LIB(c, clock_gettime, have_clock_gettime=yes) + AC_CHECK_LIB(rt, clock_gettime, have_clock_gettime=yes) if test x$have_clock_gettime = xyes; then - AC_DEFINE(HAVE_CLOCK_GETTIME, 1, [ ]) - EXTRA_LDFLAGS="$EXTRA_LDFLAGS" + EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lrt" + AC_DEFINE(HAVE_CLOCK_GETTIME, 1, [ ]) fi fi fi @@ -3386,7 +3697,7 @@ dnl Check if we want to use RPATH CheckRPATH() { AC_ARG_ENABLE(rpath, -AS_HELP_STRING([--enable-rpath], [use an rpath when linking SDL [[default=yes]]]), +[AS_HELP_STRING([--enable-rpath], [use an rpath when linking SDL [default=yes]])], , enable_rpath=yes) } @@ -3396,29 +3707,43 @@ dnl environment, etc, but most people don't need this. CheckEventSignals() { AC_ARG_ENABLE(backgrounding-signal, -AS_HELP_STRING([--enable-backgrounding-signal], [number to use for magic backgrounding signal or 'no' [[default=no]]]), +[AS_HELP_STRING([--enable-backgrounding-signal], [number to use for magic backgrounding signal or 'no' [default=no]])], , enable_backgrounding_signal=no) if test x$enable_backgrounding_signal != xno; then EXTRA_CFLAGS="$EXTRA_CFLAGS -DSDL_BACKGROUNDING_SIGNAL=$enable_backgrounding_signal" fi AC_ARG_ENABLE(foregrounding-signal, -AS_HELP_STRING([--enable-foregrounding-signal], [number to use for magic foregrounding signal or 'no' [[default=no]]]), +[AS_HELP_STRING([--enable-foregrounding-signal], [number to use for magic foregrounding signal or 'no' [default=no]])], , enable_foregrounding_signal=no) if test x$enable_foregrounding_signal != xno; then EXTRA_CFLAGS="$EXTRA_CFLAGS -DSDL_FOREGROUNDING_SIGNAL=$enable_foregrounding_signal" fi } - +dnl Set up the Virtual joystick driver. +CheckVirtualJoystick() +{ + AC_ARG_ENABLE(joystick-virtual, +[AS_HELP_STRING([--enable-joystick-virtual], [enable virtual joystick APIs [default=yes]])], + , enable_joystick_virtual=yes) + if test x$enable_joystick = xyes -a x$enable_joystick_virtual = xyes; then + AC_DEFINE(SDL_JOYSTICK_VIRTUAL, 1, [ ]) + SOURCES="$SOURCES $srcdir/src/joystick/virtual/*.c" + have_joystick_virtual=yes + fi +} dnl Do this on all platforms, before everything else (other things might want to override it). CheckWarnAll +CheckUnusedLocalTypedefs CheckNoStrictAliasing dnl Do this for every platform, but for some it doesn't mean anything, but better to catch it here anyhow. CheckEventSignals +have_locale=no + dnl Set up the configuration based on the host platform! case "$host" in *-*-linux*|*-*-uclinux*|*-*-gnu*|*-*-k*bsd*-gnu|*-*-bsdi*|*-*-freebsd*|*-*-dragonfly*|*-*-netbsd*|*-*-openbsd*|*-*-sysv5*|*-*-solaris*|*-*-hpux*|*-*-aix*|*-*-minix*|*-*-nto*) @@ -3432,12 +3757,11 @@ case "$host" in EXTRA_CFLAGS="$EXTRA_CFLAGS $ANDROID_CFLAGS" EXTRA_LDFLAGS="$EXTRA_LDFLAGS -ldl -lGLESv1_CM -lGLESv2 -llog -landroid" SDLMAIN_SOURCES="$srcdir/src/main/android/*.c" - if test x$enable_video = xyes; then SOURCES="$SOURCES $srcdir/src/core/android/*.c $srcdir/src/video/android/*.c" - # FIXME: confdefs? Not AC_DEFINE? - $as_echo "#define SDL_VIDEO_DRIVER_ANDROID 1" >>confdefs.h + AC_DEFINE(SDL_VIDEO_DRIVER_ANDROID, 1, [ ]) SUMMARY_video="${SUMMARY_video} android" + have_video=yes fi ;; *-*-linux*) ARCH=linux ;; @@ -3461,15 +3785,19 @@ case "$host" in ;; esac CheckVisibilityHidden + CheckWerror CheckDeclarationAfterStatement CheckDummyVideo + CheckOffscreenVideo CheckDiskAudio CheckDummyAudio CheckDLOPEN CheckARM CheckNEON + CheckO_CLOEXEC CheckOSS CheckALSA + CheckPipewire CheckPulseAudio CheckJACK CheckARTSC @@ -3482,23 +3810,32 @@ case "$host" in CheckRPI CheckX11 CheckDirectFB + # Need to check for EGL first because KMSDRM and Wayland depends on it. + CheckEGL CheckKMSDRM - CheckOpenGLX11 - CheckOpenGLESX11 + CheckGLX + CheckOpenGL + CheckOpenGLES CheckVulkan CheckWayland CheckInputEvents CheckLibUDev CheckDBus CheckIME + CheckInotify CheckIBus CheckFcitx case $ARCH in linux) CheckInputKD ;; + freebsd) + CheckInputKBIO + ;; + openbsd|netbsd) + CheckInputWSCONS + ;; esac - CheckTslib CheckUSBHID CheckHIDAPI CheckPTHREAD @@ -3507,6 +3844,16 @@ case "$host" in CheckRPATH CheckVivanteVideo + # Set up files for the misc library + if test x$enable_misc = xyes; then + SOURCES="$SOURCES $srcdir/src/misc/unix/*.c" + have_misc=yes + fi + # Set up files for the locale library + if test x$enable_locale = xyes; then + SOURCES="$SOURCES $srcdir/src/locale/unix/*.c" + have_locale=yes + fi # Set up files for the audio library if test x$enable_audio = xyes; then case $ARCH in @@ -3532,6 +3879,15 @@ case "$host" in AC_DEFINE(SDL_AUDIO_DRIVER_ANDROID, 1, [ ]) SOURCES="$SOURCES $srcdir/src/audio/android/*.c" SUMMARY_audio="${SUMMARY_audio} android" + + AC_DEFINE(SDL_AUDIO_DRIVER_OPENSLES, 1, [ ]) + SOURCES="$SOURCES $srcdir/src/audio/openslES/*.c" + SUMMARY_audio="${SUMMARY_audio} openslES" + + AC_DEFINE(SDL_AUDIO_DRIVER_AAUDIO, 1, [ ]) + SOURCES="$SOURCES $srcdir/src/audio/aaudio/*.c" + SUMMARY_audio="${SUMMARY_audio} aaudio" + have_audio=yes ;; nto) @@ -3543,10 +3899,20 @@ case "$host" in if test x$enable_joystick = xyes; then case $ARCH 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 + if test "x$ac_cv_header_linux_input_h" = xyes; then + AC_DEFINE(SDL_JOYSTICK_LINUX, 1, [ ]) + SOURCES="$SOURCES $srcdir/src/joystick/linux/*.c" + SOURCES="$SOURCES $srcdir/src/joystick/steam/*.c" + have_joystick=yes + fi + ;; + freebsd) + if test x$use_input_events = xyes -a x$ac_cv_header_linux_input_h = xyes; then + AC_DEFINE(SDL_JOYSTICK_LINUX, 1, [ ]) + SOURCES="$SOURCES $srcdir/src/joystick/linux/*.c" + SOURCES="$SOURCES $srcdir/src/joystick/steam/*.c" + have_joystick=yes + fi ;; android) AC_DEFINE(SDL_JOYSTICK_ANDROID, 1, [ ]) @@ -3559,7 +3925,7 @@ case "$host" in # Set up files for the haptic library if test x$enable_haptic = xyes; then case $ARCH in - linux) + linux|freebsd) if test x$use_input_events = xyes; then AC_DEFINE(SDL_HAPTIC_LINUX, 1, [ ]) SOURCES="$SOURCES $srcdir/src/haptic/linux/*.c" @@ -3621,17 +3987,26 @@ case "$host" in fi # Set up files for udev hotplugging support if test x$enable_libudev = xyes && test x$have_libudev_h_hdr = xyes; then - SOURCES="$SOURCES $srcdir/src/core/linux/SDL_udev.c" + SOURCES="$SOURCES $srcdir/src/core/linux/SDL_udev.c" fi # Set up files for evdev input if test x$use_input_events = xyes; then - SOURCES="$SOURCES $srcdir/src/core/linux/SDL_evdev*.c" - fi + SOURCES="$SOURCES $srcdir/src/core/linux/SDL_evdev.c" + SOURCES="$SOURCES $srcdir/src/core/linux/SDL_evdev_kbd.c" + SOURCES="$SOURCES $srcdir/src/core/freebsd/SDL_evdev_kbd_freebsd.c" + fi + # Set up files for wscons input + if test x$use_input_wscons = xyes; then + SOURCES="$SOURCES $srcdir/src/core/openbsd/SDL_wscons_kbd.c" + SOURCES="$SOURCES $srcdir/src/core/openbsd/SDL_wscons_mouse.c" + fi # Set up other core UNIX files + SOURCES="$SOURCES $srcdir/src/core/linux/SDL_evdev_capabilities.c" SOURCES="$SOURCES $srcdir/src/core/linux/SDL_threadprio.c" + SOURCES="$SOURCES $srcdir/src/core/linux/SDL_sandbox.c" SOURCES="$SOURCES $srcdir/src/core/unix/*.c" ;; - *-*-cygwin* | *-*-mingw32*) + *-*-cygwin* | *-*-mingw*) ARCH=win32 if test "$build" != "$host"; then # cross-compiling # Default cross-compile location @@ -3642,8 +4017,14 @@ case "$host" in ac_default_prefix=$BUILD_PREFIX fi fi + if test x$enable_loadso = xyes; then + have_loadso=yes + fi + CheckGDwarf4 + CheckWerror CheckDeclarationAfterStatement CheckDummyVideo + CheckOffscreenVideo CheckDiskAudio CheckDummyAudio CheckWINDOWS @@ -3655,14 +4036,23 @@ case "$host" in # Set up the core platform files SOURCES="$SOURCES $srcdir/src/core/windows/*.c" - + # Set up files for the misc library + if test x$enable_misc = xyes; then + SOURCES="$SOURCES $srcdir/src/misc/windows/*.c" + have_misc=yes + fi + # Use the Windows locale APIs. + if test x$enable_locale = xyes; then + SOURCES="$SOURCES $srcdir/src/locale/windows/*.c" + have_locale=yes + fi # Set up files for the video library if test x$enable_video = xyes; then AC_DEFINE(SDL_VIDEO_DRIVER_WINDOWS, 1, [ ]) SOURCES="$SOURCES $srcdir/src/video/windows/*.c" have_video=yes AC_ARG_ENABLE(render-d3d, -AS_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[default=yes]]]), +[AS_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [default=yes]])], , enable_render_d3d=yes) if test x$enable_render_d3d = xyes -a x$have_d3d = xyes; then AC_DEFINE(SDL_VIDEO_RENDER_D3D, 1, [ ]) @@ -3672,6 +4062,10 @@ AS_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau AC_DEFINE(SDL_VIDEO_RENDER_D3D11, 1, [ ]) SUMMARY_video="${SUMMARY_video} d3d11" fi + if test x$enable_render_d3d = xyes -a x$have_d3d12 = xyes; then + AC_DEFINE(SDL_VIDEO_RENDER_D3D12, 1, [ ]) + SUMMARY_video="${SUMMARY_video} d3d12" + fi fi # Set up files for the audio library if test x$enable_audio = xyes; then @@ -3692,16 +4086,18 @@ AS_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau fi # Set up files for the joystick library if test x$enable_joystick = xyes; then - if test x$have_dinput = xyes -o x$have_xinput = xyes; then + AC_DEFINE(SDL_JOYSTICK_RAWINPUT, 1, [ ]) + if test x$have_dinput = xyes -o x$have_xinput = xyes -o x$have_wgi = xyes; then if test x$have_xinput = xyes; then AC_DEFINE(SDL_JOYSTICK_XINPUT, 1, [ ]) fi + if test x$have_wgi = xyes; then + AC_DEFINE(SDL_JOYSTICK_WGI, 1, [ ]) + fi if test x$have_dinput = xyes; then AC_DEFINE(SDL_JOYSTICK_DINPUT, 1, [ ]) EXTRA_LDFLAGS="$EXTRA_LDFLAGS -ldinput8 -ldxguid -ldxerr8" fi - else - AC_DEFINE(SDL_JOYSTICK_WINMM, 1, [ ]) fi SOURCES="$SOURCES $srcdir/src/joystick/windows/*.c" have_joystick=yes @@ -3718,11 +4114,23 @@ AS_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau have_haptic=yes fi fi + # Set up files for the sensor library + AC_CHECK_HEADER(sensorsapi.h,have_winsensors=yes,have_winsensors=no) + if test x$have_winsensors = xyes; then + AC_DEFINE(HAVE_SENSORSAPI_H, 1, [ ]) + fi + if test x$enable_sensor = xyes -a x$have_winsensors = xyes; then + AC_DEFINE(SDL_SENSOR_WINDOWS, 1, [ ]) + SOURCES="$SOURCES $srcdir/src/sensor/windows/*.c" + have_sensor=yes + fi + # Set up files for the power library if test x$enable_power = xyes; then AC_DEFINE(SDL_POWER_WINDOWS, 1, [ ]) SOURCES="$SOURCES $srcdir/src/power/windows/SDL_syspower.c" have_power=yes fi + # Set up files for the filesystem library if test x$enable_filesystem = xyes; then AC_DEFINE(SDL_FILESYSTEM_WINDOWS, 1, [ ]) SOURCES="$SOURCES $srcdir/src/filesystem/windows/SDL_sysfilesystem.c" @@ -3730,6 +4138,7 @@ AS_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau fi # Set up files for the thread library if test x$enable_threads = xyes; then + AC_DEFINE(SDL_THREAD_GENERIC_COND_SUFFIX, 1, [ ]) AC_DEFINE(SDL_THREAD_WINDOWS, 1, [ ]) SOURCES="$SOURCES $srcdir/src/thread/windows/*.c" SOURCES="$SOURCES $srcdir/src/thread/generic/SDL_syscond.c" @@ -3745,7 +4154,6 @@ AS_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau if test x$enable_loadso = xyes; then AC_DEFINE(SDL_LOADSO_WINDOWS, 1, [ ]) SOURCES="$SOURCES $srcdir/src/loadso/windows/*.c" - have_loadso=yes fi # Set up the system libraries we need if test -f /lib/w32api/libuuid.a; then @@ -3753,7 +4161,8 @@ AS_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau else LIBUUID=-luuid fi - EXTRA_LDFLAGS="$EXTRA_LDFLAGS -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lsetupapi -lversion $LIBUUID -static-libgcc" + EXTRA_LDFLAGS="$EXTRA_LDFLAGS -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lsetupapi -lversion $LIBUUID" + BUILD_LDFLAGS="$BUILD_LDFLAGS -Wc,-static-libgcc" # The Windows platform requires special setup VERSION_SOURCES="$srcdir/src/main/windows/*.rc" SDLMAIN_SOURCES="$srcdir/src/main/windows/*.c" @@ -3769,21 +4178,21 @@ AS_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau SDL_LIBS="-lcygwin $SDL_LIBS" fi ;; - - dnl BeOS support removed after SDL 2.0.1. Haiku still works. --ryan. +dnl BeOS support removed after SDL 2.0.1. Haiku still works. --ryan. *-*-beos*) AC_MSG_ERROR([ *** BeOS support has been removed as of SDL 2.0.2. ]) ;; - *-*-haiku*) ARCH=haiku ac_default_prefix=/boot/system CheckDummyVideo + CheckOffscreenVideo CheckDiskAudio CheckDummyAudio CheckDLOPEN + CheckO_CLOEXEC CheckHaikuVideo CheckHaikuGL CheckPTHREAD @@ -3819,26 +4228,47 @@ AS_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau SOURCES="$SOURCES $srcdir/src/filesystem/haiku/*.cc" have_filesystem=yes fi + # Set up files for the misc library + if test x$enable_misc = xyes; then + SOURCES="$SOURCES $srcdir/src/misc/haiku/*.cc" + have_misc=yes + fi + # Set up files for the locale library + if test x$enable_locale = xyes; then + SOURCES="$SOURCES $srcdir/src/locale/haiku/*.cc" + have_locale=yes + fi # The Haiku platform requires special setup. SOURCES="$srcdir/src/main/haiku/*.cc $SOURCES" EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lroot -lbe -lmedia -lgame -ldevice -ltextencoding" - # Haiku's x86 spins use libstdc++.r4.so (for binary compat?), but - # other spins, like x86-64, use a more standard "libstdc++.so.*" - AC_CHECK_FILE("/boot/system/lib/libstdc++.r4.so", EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lstdc++.r4", EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lstdc++") ;; - arm*-apple-darwin*|*-ios-*) + *-ios-*) ARCH=ios CheckVisibilityHidden + CheckWerror + CheckNoErrorDeprecatedDeclarationsWerror CheckDeclarationAfterStatement CheckDummyVideo + CheckOffscreenVideo CheckDiskAudio CheckDummyAudio CheckDLOPEN + CheckO_CLOEXEC CheckMETAL CheckVulkan CheckPTHREAD + # Set up files for the misc library + if test x$enable_misc = xyes; then + SOURCES="$SOURCES $srcdir/src/misc/ios/*.m" + have_misc=yes + fi + # Set up files for the locale library + if test x$enable_locale = xyes; then + SOURCES="$SOURCES $srcdir/src/locale/macosx/*.m" + have_locale=yes + fi # Set up files for the audio library if test x$enable_audio = xyes; then AC_DEFINE(SDL_AUDIO_DRIVER_COREAUDIO, 1, [ ]) @@ -3852,6 +4282,9 @@ AS_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau SOURCES="$SOURCES $srcdir/src/joystick/iphoneos/*.m" SOURCES="$SOURCES $srcdir/src/joystick/steam/*.c" have_joystick=yes + else + # Need this code for accelerometer as joystick support + SOURCES="$SOURCES $srcdir/src/joystick/iphoneos/*.m" fi # Set up files for the haptic library #if test x$enable_haptic = xyes; then @@ -3896,7 +4329,13 @@ AS_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau AC_DEFINE(SDL_VIDEO_RENDER_OGL_ES, 1, [ ]) AC_DEFINE(SDL_VIDEO_RENDER_OGL_ES2, 1, [ ]) SOURCES="$SOURCES $srcdir/src/video/uikit/*.m" - EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lm -liconv -lobjc" + SUMMARY_video="${SUMMARY_video} uikit" + have_video=yes + EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lm" + if test x$enable_system_iconv = xyes; then + EXTRA_LDFLAGS="$EXTRA_LDFLAGS -liconv" + fi + EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lobjc" EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,AVFoundation" EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,AudioToolbox" EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,CoreAudio" @@ -3922,22 +4361,38 @@ AS_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau EXTRA_CFLAGS="$EXTRA_CFLAGS -DTARGET_API_MAC_CARBON" EXTRA_CFLAGS="$EXTRA_CFLAGS -DTARGET_API_MAC_OSX" + CheckObjectiveCARC CheckVisibilityHidden + CheckWerror + CheckNoErrorDeprecatedDeclarationsWerror CheckDeclarationAfterStatement CheckDummyVideo + CheckOffscreenVideo CheckDiskAudio CheckDummyAudio CheckDLOPEN + CheckO_CLOEXEC CheckCOCOA CheckMETAL CheckX11 CheckMacGL CheckMacGLES - CheckOpenGLX11 + CheckGLX + CheckOpenGL CheckVulkan CheckPTHREAD CheckHIDAPI + # Set up files for the misc library + if test x$enable_misc = xyes; then + SOURCES="$SOURCES $srcdir/src/misc/macosx/*.m" + have_misc=yes + fi + # Set up files for the locale library + if test x$enable_locale = xyes; then + SOURCES="$SOURCES $srcdir/src/locale/macosx/*.m" + have_locale=yes + fi # Set up files for the audio library if test x$enable_audio = xyes; then AC_DEFINE(SDL_AUDIO_DRIVER_COREAUDIO, 1, [ ]) @@ -3950,6 +4405,8 @@ AS_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau if test x$enable_joystick = xyes; then AC_DEFINE(SDL_JOYSTICK_IOKIT, 1, [ ]) SOURCES="$SOURCES $srcdir/src/joystick/darwin/*.c" + SOURCES="$SOURCES $srcdir/src/joystick/iphoneos/*.m" + CheckJoystickMFI have_joystick=yes fi # Set up files for the haptic library @@ -3999,8 +4456,10 @@ AS_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau CheckNativeClient CheckDummyAudio CheckDummyVideo + CheckOffscreenVideo CheckInputEvents CheckPTHREAD + CheckO_CLOEXEC # Set up files for the timer library if test x$enable_timers = xyes; then @@ -4008,7 +4467,7 @@ AS_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau SOURCES="$SOURCES $srcdir/src/timer/unix/*.c" have_timers=yes fi - + if test x$enable_filesystem = xyes; then AC_DEFINE(SDL_FILESYSTEM_NACL, 1, [ ]) SOURCES="$SOURCES $srcdir/src/filesystem/nacl/*.c" @@ -4031,22 +4490,31 @@ AS_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau fi CheckVisibilityHidden + CheckWerror CheckDeclarationAfterStatement CheckDummyVideo + CheckOffscreenVideo CheckDiskAudio CheckDummyAudio + CheckPTHREAD CheckDLOPEN CheckClockGettime CheckEmscriptenGLES + # Set up files for the misc library + if test x$enable_misc = xyes; then + SOURCES="$SOURCES $srcdir/src/misc/emscripten/*.c" + have_misc=yes + fi + # Set up files for the power library if test x$enable_power = xyes; then AC_DEFINE(SDL_POWER_EMSCRIPTEN, 1, [ ]) SOURCES="$SOURCES $srcdir/src/power/emscripten/*.c" have_power=yes fi - - # Set up files for the power library + + # Set up files for the joystick library if test x$enable_joystick = xyes; then AC_DEFINE(SDL_JOYSTICK_EMSCRIPTEN, 1, [ ]) SOURCES="$SOURCES $srcdir/src/joystick/emscripten/*.c" @@ -4065,19 +4533,45 @@ AS_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau SOURCES="$SOURCES $srcdir/src/timer/unix/*.c" have_timers=yes fi + # Set up files for the locale library + if test x$enable_locale = xyes; then + SOURCES="$SOURCES $srcdir/src/locale/emscripten/*.c" + have_locale=yes + fi ;; *-*-riscos*) ARCH=riscos CheckVisibilityHidden + CheckWerror CheckDeclarationAfterStatement CheckDummyVideo + CheckOffscreenVideo CheckDiskAudio CheckDummyAudio CheckDLOPEN + CheckO_CLOEXEC CheckOSS CheckPTHREAD CheckClockGettime + # Set up files for the misc library + if test x$enable_misc = xyes; then + SOURCES="$SOURCES $srcdir/src/misc/riscos/*.c" + have_misc=yes + fi + # Set up files for the video library + if test x$enable_video = xyes; then + AC_DEFINE(SDL_VIDEO_DRIVER_RISCOS, 1, [ ]) + SOURCES="$SOURCES $srcdir/src/video/riscos/*.c" + have_video=yes + SUMMARY_video="${SUMMARY_video} riscos" + fi + # Set up files for the filesystem library + if test x$enable_filesystem = xyes; then + AC_DEFINE(SDL_FILESYSTEM_RISCOS, 1, [ ]) + SOURCES="$SOURCES $srcdir/src/filesystem/riscos/*.c" + have_filesystem=yes + fi # Set up files for the timer library if test x$enable_timers = xyes; then AC_DEFINE(SDL_TIMER_UNIX, 1, [ ]) @@ -4085,6 +4579,86 @@ AS_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau have_timers=yes fi ;; + *-*-os2*) + ARCH=os2 + if test "$build" != "$host"; then # cross-compiling + # Default cross-compile location + ac_default_prefix=/@unixroot/usr/local/cross-tools/$host + else + # Look for the location of the tools and install there + if test "$BUILD_PREFIX" != ""; then + ac_default_prefix=$BUILD_PREFIX + fi + fi + enable_static=no # disable static builds + EXTRA_CFLAGS="$EXTRA_CFLAGS -DBUILD_SDL -DOS2EMX_PLAIN_CHAR" + CheckOS2 + CheckWerror + CheckDeclarationAfterStatement + CheckDummyVideo + CheckDiskAudio + CheckDummyAudio + CheckHIDAPI + + # Set up the core platform files + SOURCES="$SOURCES $srcdir/src/core/os2/*.c" + if test x$enable_system_iconv = xyes; then + if test x$ac_cv_func_iconv != xyes -o x$ac_cv_header_iconv_h != xyes; then + SOURCES="$SOURCES $srcdir/src/core/os2/geniconv/*.c" + fi + fi + # Use the Unix locale APIs. + if test x$enable_locale = xyes; then + SOURCES="$SOURCES $srcdir/src/locale/unix/*.c" + have_locale=yes + fi + # Set up files for the video library + if test x$enable_video = xyes; then + AC_DEFINE(SDL_VIDEO_DRIVER_OS2, 1, [ ]) + SOURCES="$SOURCES $srcdir/src/video/os2/*.c" + have_video=yes + SUMMARY_video="${SUMMARY_video} OS/2" + fi + # Set up files for the audio library + if test x$enable_audio = xyes; then + AC_DEFINE(SDL_AUDIO_DRIVER_OS2, 1, [ ]) + SOURCES="$SOURCES $srcdir/src/audio/os2/*.c" + have_audio=yes + SUMMARY_audio="${SUMMARY_audio} OS/2" + EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lmmpm2" + fi + # Set up files for the thread library + if test x$enable_threads = xyes; then + AC_DEFINE(SDL_THREAD_OS2, 1, [ ]) + SOURCES="$SOURCES $srcdir/src/thread/os2/*.c" + SOURCES="$SOURCES $srcdir/src/thread/generic/SDL_syscond.c" + have_threads=yes + fi + # Set up files for the timer library + if test x$enable_timers = xyes; then + AC_DEFINE(SDL_TIMER_OS2, 1, [ ]) + SOURCES="$SOURCES $srcdir/src/timer/os2/*.c" + have_timers=yes + fi + # Set up files for the shared object loading library + if test x$enable_loadso = xyes; then + AC_DEFINE(SDL_LOADSO_OS2, 1, [ ]) + SOURCES="$SOURCES $srcdir/src/loadso/os2/*.c" + have_loadso=yes + fi + # Set up files for the filesystem library + if test x$enable_filesystem = xyes; then + AC_DEFINE(SDL_FILESYSTEM_OS2, 1, [ ]) + SOURCES="$SOURCES $srcdir/src/filesystem/os2/*.c" + have_filesystem=yes + fi + # Set up files for the joystick library + if test x$enable_joystick = xyes; then + AC_DEFINE(SDL_JOYSTICK_OS2, 1, [ ]) + SOURCES="$SOURCES $srcdir/src/joystick/os2/*.c" + have_joystick=yes + fi + ;; *) AC_MSG_ERROR([ *** Unsupported host: Please add to configure.ac @@ -4092,10 +4666,13 @@ AS_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau ;; esac +dnl Permit use of virtual joystick APIs on any platform (subject to configure options) +CheckVirtualJoystick + # Check whether to install sdl2-config AC_MSG_CHECKING(whether to install sdl2-config) AC_ARG_ENABLE([sdl2-config], - AS_HELP_STRING([--enable-sdl2-config], [Install sdl2-config [default=yes]]), + [AS_HELP_STRING([--enable-sdl2-config],[Install sdl2-config [default=yes]])], [case "${enableval}" in yes) enable_sdl2_config="TRUE" ;; no) enable_sdl2_config="FALSE" ;; @@ -4108,8 +4685,38 @@ else fi AC_SUBST([INSTALL_SDL2_CONFIG], [$enable_sdl2_config]) +AC_ARG_ENABLE([vendor-info], + [AS_HELP_STRING([--enable-vendor-info=STRING], [Add vendor info to SDL_REVISION])], + [enable_vendor_info="$enableval"], [enable_vendor_info=]) +AS_IF([test "$enable_vendor_info" = no], [enable_vendor_info=]) +AC_SUBST([SDL_VENDOR_INFO], [$enable_vendor_info]) + # Verify that we have all the platform specific files we need +if test x$have_audio != xyes; then + if test x$enable_audio = xyes; then + AC_DEFINE(SDL_AUDIO_DRIVER_DUMMY, 1, [ ]) + fi + SOURCES="$SOURCES $srcdir/src/audio/dummy/*.c" +fi +if test x$have_video != xyes; then + if test x$enable_video = xyes; then + AC_DEFINE(SDL_VIDEO_DRIVER_DUMMY, 1, [ ]) + fi + SOURCES="$SOURCES $srcdir/src/video/dummy/*.c" +fi +if test x$have_misc != xyes; then + if test x$enable_misc = xyes; then + AC_DEFINE(SDL_MISC_DUMMY, 1, [ ]) + fi + SOURCES="$SOURCES $srcdir/src/misc/dummy/*.c" +fi +if test x$have_locale != xyes; then + if test x$enable_locale = xyes; then + AC_DEFINE(SDL_LOCALE_DUMMY, 1, [ ]) + fi + SOURCES="$SOURCES $srcdir/src/locale/dummy/*.c" +fi if test x$have_joystick != xyes; then if test x$enable_joystick = xyes; then AC_DEFINE(SDL_JOYSTICK_DUMMY, 1, [ ]) @@ -4136,19 +4743,19 @@ if test x$have_threads != xyes; then fi if test x$have_timers != xyes; then if test x$enable_timers = xyes; then - AC_DEFINE(SDL_TIMERS_DISABLED, 1, [ ]) + AC_DEFINE(SDL_TIMER_DUMMY, 1, [ ]) fi SOURCES="$SOURCES $srcdir/src/timer/dummy/*.c" fi if test x$have_filesystem != xyes; then if test x$enable_filesystem = xyes; then - AC_DEFINE(SDL_FILESYSTEM_DISABLED, 1, [ ]) + AC_DEFINE(SDL_FILESYSTEM_DUMMY, 1, [ ]) fi SOURCES="$SOURCES $srcdir/src/filesystem/dummy/*.c" fi if test x$have_loadso != xyes; then if test x$enable_loadso = xyes; then - AC_DEFINE(SDL_LOADSO_DISABLED, 1, [ ]) + AC_DEFINE(SDL_LOADSO_DUMMY, 1, [ ]) fi SOURCES="$SOURCES $srcdir/src/loadso/dummy/*.c" fi @@ -4158,27 +4765,28 @@ fi SDLTEST_SOURCES="$srcdir/src/test/*.c" if test x$video_wayland = xyes; then - WAYLAND_PROTOCOLS=`cd $srcdir/wayland-protocols ; for p in *.xml ; do echo -n "\$p" |sed 's,\\.xml\$, ,g' ; done` - WAYLAND_PROTOCOLS_SOURCES=`for p in $WAYLAND_PROTOCOLS ; do echo -n "\\$(gen)/\$p-protocol.c " ; done` - WAYLAND_PROTOCOLS_HEADERS=`for p in $WAYLAND_PROTOCOLS ; do echo -n "\\$(gen)/\$p-client-protocol.h " ; done` + WAYLAND_PROTOCOLS=`cd $srcdir/wayland-protocols ; for p in *.xml ; do printf '%s' "\$p" |sed 's,\\.xml\$, ,g' ; done` + WAYLAND_PROTOCOLS_SOURCES=`for p in $WAYLAND_PROTOCOLS ; do printf '%s' "\\$(gen)/\$p-protocol.c " ; done` + WAYLAND_PROTOCOLS_HEADERS=`for p in $WAYLAND_PROTOCOLS ; do printf '%s' "\\$(gen)/\$p-client-protocol.h " ; done` GEN_SOURCES="$GEN_SOURCES $WAYLAND_PROTOCOLS_SOURCES" GEN_HEADERS="$GEN_HEADERS $WAYLAND_PROTOCOLS_HEADERS" WAYLAND_PROTOCOLS_DEPENDS=`for p in $WAYLAND_PROTOCOLS ; do\ echo ;\ - echo "\\$(gen)/\$p-client-protocol.h: \\$(srcdir)/wayland-protocols/\$p.xml" ;\ - echo " @\\$(SHELL) \\$(auxdir)/mkinstalldirs \\$(gen)" ;\ - echo " \\$(RUN_CMD_GEN)\\$(WAYLAND_SCANNER) client-header \\$< \\$@" ;\ + printf '%s\n' "\\$(gen)/\$p-client-protocol.h: \\$(srcdir)/wayland-protocols/\$p.xml" ;\ + printf '%s\n' " @\\$(SHELL) \\$(auxdir)/mkinstalldirs \\$(gen)" ;\ + printf '%s\n' " \\$(RUN_CMD_GEN)\\$(WAYLAND_SCANNER) client-header \\$< \\$@" ;\ echo ;\ - echo "\\$(gen)/\$p-protocol.c: \\$(srcdir)/wayland-protocols/\$p.xml" ;\ - echo " @\\$(SHELL) \\$(auxdir)/mkinstalldirs \\$(gen)" ;\ - echo " \\$(RUN_CMD_GEN)\\$(WAYLAND_SCANNER) code \\$< \\$@" ;\ + printf '%s\n' "\\$(gen)/\$p-protocol.c: \\$(srcdir)/wayland-protocols/\$p.xml" ;\ + printf '%s\n' " @\\$(SHELL) \\$(auxdir)/mkinstalldirs \\$(gen)" ;\ + printf '%s\n' " \\$(RUN_CMD_GEN)\\$(WAYLAND_SCANNER) \\$(WAYLAND_SCANNER_CODE_MODE) \\$< \\$@" ;\ echo ;\ - echo "\\$(objects)/\$p-protocol.lo: \\$(gen)/\$p-protocol.c \\$(gen)/\$p-client-protocol.h" ;\ - echo " \\$(RUN_CMD_CC)\\$(LIBTOOL) --tag=CC --mode=compile \\$(CC) \\$(CFLAGS) \\$(EXTRA_CFLAGS) $DEPENDENCY_TRACKING_OPTIONS -c \\$< -o \\$@" ;\ + printf '%s\n' "\\$(objects)/\$p-protocol.lo: \\$(gen)/\$p-protocol.c \\$(gen)/\$p-client-protocol.h" ;\ + printf '%s\n' " @\\$(SHELL) \\$(auxdir)/mkinstalldirs \\$(objects)" ;\ + printf '%s\n' " \\$(RUN_CMD_CC)\\$(LIBTOOL) --tag=CC --mode=compile \\$(CC) \\$(CFLAGS) \\$(EXTRA_CFLAGS) $DEPENDENCY_TRACKING_OPTIONS -c \\$< -o \\$@" ;\ done ;\ echo ;\ - for s in $WAYLAND_SOURCES ; do echo -n "\$s:" ; for p in $WAYLAND_PROTOCOLS ; do echo -n " \\$(gen)/\$p-client-protocol.h" ; done ; echo ; done ; echo` + for s in $WAYLAND_SOURCES ; do printf '%s' "\$s:" ; printf ' \$(gen)/%s-client-protocol.h' $WAYLAND_PROTOCOLS ; echo ; done ; echo` fi OBJECTS=`echo $SOURCES` @@ -4194,10 +4802,10 @@ GEN_OBJECTS=`echo "$GEN_SOURCES" | sed 's,[[^ ]]*/\([[^ ]]*\)\.c,$(objects)/\1.l VERSION_OBJECTS=`echo $VERSION_SOURCES` VERSION_DEPENDS=`echo $VERSION_SOURCES` -VERSION_OBJECTS=`echo "$VERSION_OBJECTS" | sed 's,[[^ ]]*/\([[^ ]]*\)\.rc,$(objects)/\1.o,g'` +VERSION_OBJECTS=`echo "$VERSION_OBJECTS" | sed 's,[[^ ]]*/\([[^ ]]*\)\.rc,$(objects)/\1.lo,g'` VERSION_DEPENDS=`echo "$VERSION_DEPENDS" | sed "s,\\([[^ ]]*\\)/\\([[^ ]]*\\)\\.rc,\\\\ -\\$(objects)/\\2.o: \\1/\\2.rc \\$(objects)/.created\\\\ - \\$(WINDRES) \\$< \\$@,g"` +\\$(objects)/\\2.lo: \\1/\\2.rc \\$(objects)/.created\\\\ + \\$(RUN_CMD_RC)\\$(LIBTOOL) --mode=compile --tag=RC \\$(RC) -i \\$< -o \\$@,g"` SDLMAIN_OBJECTS=`echo $SDLMAIN_SOURCES` SDLMAIN_DEPENDS=`echo $SDLMAIN_SOURCES` @@ -4215,7 +4823,7 @@ SDLTEST_DEPENDS=`echo "$SDLTEST_DEPENDS" | sed "s,\\([[^ ]]*\\)/\\([[^ ]]*\\)\\. # Set runtime shared library paths as needed -if test "x$enable_rpath" = "xyes"; then +if test "x$enable_rpath" = "xyes" -a "x$enable_shared" = "xyes"; then if test $ARCH = bsdi -o $ARCH = freebsd -o $ARCH = linux -o $ARCH = netbsd; then SDL_RLD_FLAGS="-Wl,-rpath,\${libdir}" @@ -4223,12 +4831,10 @@ if test "x$enable_rpath" = "xyes"; then have_enable_new_dtags=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -Wl,--enable-new-dtags" - AC_TRY_LINK([ - ],[ - ],[ + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [ have_enable_new_dtags=yes SDL_RLD_FLAGS="$SDL_RLD_FLAGS -Wl,--enable-new-dtags" - ]) + ],[]) LDFLAGS="$save_LDFLAGS" AC_MSG_RESULT($have_enable_new_dtags) fi @@ -4239,17 +4845,29 @@ else SDL_RLD_FLAGS="" fi -SDL_STATIC_LIBS="$SDL_LIBS $EXTRA_LDFLAGS" +SDL_STATIC_LIBS="$EXTRA_LDFLAGS" + +dnl Calculate the location of the prefix, relative to the cmake folder +dnl Calculate the location of the prefix, relative to bindir +pkg_cmakedir='$libdir/cmake/SDL2' +AX_COMPUTE_RELATIVE_PATHS([pkg_cmakedir:prefix:cmake_prefix_relpath bindir:prefix:bin_prefix_relpath]) +AC_SUBST([cmake_prefix_relpath]) +AC_SUBST([bin_prefix_relpath]) dnl Expand the cflags and libraries needed by apps using SDL AC_SUBST(SDL_CFLAGS) AC_SUBST(SDL_LIBS) AC_SUBST(SDL_STATIC_LIBS) AC_SUBST(SDL_RLD_FLAGS) +PKGCONFIG_DEPENDS="" +AC_SUBST(PKGCONFIG_DEPENDS) if test x$enable_shared = xyes; then + PKGCONFIG_LIBS_PRIV=" +Libs.private:" ENABLE_SHARED_TRUE= ENABLE_SHARED_FALSE="#" else + PKGCONFIG_LIBS_PRIV= ENABLE_SHARED_TRUE="#" ENABLE_SHARED_FALSE= fi @@ -4260,6 +4878,7 @@ else ENABLE_STATIC_TRUE="#" ENABLE_STATIC_FALSE= fi +AC_SUBST(PKGCONFIG_LIBS_PRIV) AC_SUBST(ENABLE_SHARED_TRUE) AC_SUBST(ENABLE_SHARED_FALSE) AC_SUBST(ENABLE_STATIC_TRUE) @@ -4278,8 +4897,8 @@ AC_SUBST(BUILD_CFLAGS) AC_SUBST(EXTRA_CFLAGS) AC_SUBST(BUILD_LDFLAGS) AC_SUBST(EXTRA_LDFLAGS) -AC_SUBST(WINDRES) AC_SUBST(WAYLAND_SCANNER) +AC_SUBST(WAYLAND_SCANNER_CODE_MODE) cat >Makefile.rules <<__EOF__ @@ -4315,6 +4934,11 @@ if test x$have_x = xyes; then SUMMARY="${SUMMARY}X11 libraries :${SUMMARY_video_x11}\n" fi SUMMARY="${SUMMARY}Input drivers :${SUMMARY_input}\n" +if test x$have_joystick_virtual = xyes; then + SUMMARY="${SUMMARY}Enable virtual joystick APIs : YES\n" +else + SUMMARY="${SUMMARY}Enable virtual joystick APIs : NO\n" +fi if test x$have_samplerate_h_hdr = xyes; then SUMMARY="${SUMMARY}Using libsamplerate : YES\n" else @@ -4340,7 +4964,7 @@ if test x$have_ibus_ibus_h_hdr = xyes; then else SUMMARY="${SUMMARY}Using ibus : NO\n" fi -if test x$have_fcitx_frontend_h_hdr = xyes; then +if test x$have_fcitx = xyes; then SUMMARY="${SUMMARY}Using fcitx : YES\n" else SUMMARY="${SUMMARY}Using fcitx : NO\n" @@ -4353,7 +4977,6 @@ if test x$WARN_ABOUT_ARM_SIMD_ASM_MIT = xyes; then SUMMARY="${SUMMARY}configure script with:\n" SUMMARY="${SUMMARY}\n --disable-arm-simd\n" fi - if test x$WARN_ABOUT_ARM_NEON_ASM_MIT = xyes; then SUMMARY="${SUMMARY}\nSDL is being built with ARM NEON optimizations, which\n" SUMMARY="${SUMMARY}uses code licensed under the MIT license. If this is a\n" @@ -4362,6 +4985,6 @@ if test x$WARN_ABOUT_ARM_NEON_ASM_MIT = xyes; then SUMMARY="${SUMMARY}\n --disable-arm-neon\n" fi -AC_CONFIG_COMMANDS([summary], [echo -en "$SUMMARY"], [SUMMARY="$SUMMARY"]) +AC_CONFIG_COMMANDS([summary], [printf "$SUMMARY"], [SUMMARY="$SUMMARY"]) AC_OUTPUT diff --git a/SDL2-2.30.5/docs/CONTRIBUTING.md b/SDL2-2.30.5/docs/CONTRIBUTING.md new file mode 100644 index 0000000..969ce8b --- /dev/null +++ b/SDL2-2.30.5/docs/CONTRIBUTING.md @@ -0,0 +1,97 @@ +# Contributing to SDL + +We appreciate your interest in contributing to SDL, this document will describe how to report bugs, contribute code or ideas or edit documentation. + +**Table Of Contents** + +- [Filing a GitHub issue](#filing-a-github-issue) + - [Reporting a bug](#reporting-a-bug) + - [Suggesting enhancements](#suggesting-enhancements) +- [Contributing code](#contributing-code) + - [Forking the project](#forking-the-project) + - [Following the style guide](#following-the-style-guide) + - [Running the tests](#running-the-tests) + - [Opening a pull request](#opening-a-pull-request) +- [Contributing to the documentation](#contributing-to-the-documentation) + - [Editing a function documentation](#editing-a-function-documentation) + - [Editing the wiki](#editing-the-wiki) + +## Filing a GitHub issue + +### Reporting a bug + +If you think you have found a bug and would like to report it, here are the steps you should take: + +- Before opening a new issue, ensure your bug has not already been reported on the [GitHub Issues page](https://github.com/libsdl-org/SDL/issues). +- On the issue tracker, click on [New Issue](https://github.com/libsdl-org/SDL/issues/new). +- Include details about your environment, such as your Operating System and SDL version. +- If possible, provide a small example that reproduces your bug. + +### Suggesting enhancements + +If you want to suggest changes for the project, here are the steps you should take: + +- Check if the suggestion has already been made on: + - the [issue tracker](https://github.com/libsdl-org/SDL/issues); + - the [discourse forum](https://discourse.libsdl.org/); + - or if a [pull request](https://github.com/libsdl-org/SDL/pulls) already exists. +- On the issue tracker, click on [New Issue](https://github.com/libsdl-org/SDL/issues/new). +- Describe what change you would like to happen. + +## Contributing code + +This section will cover how the process of forking the project, making a change and opening a pull request. + +### Forking the project + +The first step consists in making a fork of the project, this is only necessary for the first contribution. + +Head over to https://github.com/libsdl-org/SDL and click on the `Fork` button in the top right corner of your screen, you may leave the fields unchanged and click `Create Fork`. + +You will be redirected to your fork of the repository, click the green `Code` button and copy the git clone link. + +If you had already forked the repository, you may update it from the web page using the `Fetch upstream` button. + +### Following the style guide + +Code formatting is done using a custom `.clang-format` file, you can learn more about how to run it [here](https://clang.llvm.org/docs/ClangFormat.html). + +Some legacy code may not be formatted, as such avoid formatting the whole file at once and only format around your changes. + +For your commit message to be properly displayed on GitHub, it should contain: + +- A short description of the commit of 50 characters or less on the first line. +- If necessary, add a blank line followed by a long description, each line should be 72 characters or less. + +For example: + +``` +Fix crash in SDL_FooBar. + +This addresses the issue #123456 by making sure Foo was successful +before calling Bar. +``` + +### Running the tests + +Tests allow you to verify if your changes did not break any behaviour, here are the steps to follow: + +- Before pushing, run the `testautomation` suite on your machine, there should be no more failing tests after your change than before. +- After pushing to your fork, Continuous Integration (GitHub Actions) will ensure compilation and tests still pass on other systems. + +### Opening a pull request + +- Head over to your fork's GitHub page. +- Click on the `Contribute` button and `Open Pull Request`. +- Fill out the pull request template. +- If any changes are requested, you can add new commits to your fork and they will be automatically added to the pull request. + +## Contributing to the documentation + +### Editing a function documentation + +The wiki documentation for API functions is synchronised from the headers' doxygen comments. As such, all modifications to syntax; function parameters; return value; version; related functions should be done in the header directly. + +### Editing the wiki + +Other changes to the wiki should done directly from https://wiki.libsdl.org/ diff --git a/SDL2-2.0.12/docs/README-android.md b/SDL2-2.30.5/docs/README-android.md similarity index 80% rename from SDL2-2.0.12/docs/README-android.md rename to SDL2-2.30.5/docs/README-android.md index fbd9f99..b886f06 100644 --- a/SDL2-2.0.12/docs/README-android.md +++ b/SDL2-2.30.5/docs/README-android.md @@ -10,27 +10,25 @@ If you are using the older ant build process, it is no longer officially supported, but you can use the "android-project-ant" directory as a template. -================================================================================ - Requirements +Requirements ================================================================================ -Android SDK (version 26 or later) +Android SDK (version 34 or later) https://developer.android.com/sdk/index.html Android NDK r15c or later https://developer.android.com/tools/sdk/ndk/index.html -Minimum API level supported by SDL: 16 (Android 4.1) +Minimum API level supported by SDL: 19 (Android 4.4) -================================================================================ - How the port works +How the port works ================================================================================ - Android applications are Java-based, optionally with parts written in C -- As SDL apps are C-based, we use a small Java shim that uses JNI to talk to +- As SDL apps are C-based, we use a small Java shim that uses JNI to talk to the SDL library -- This means that your application C code must be placed inside an Android +- This means that your application C code must be placed inside an Android Java project, along with some C support code that communicates with Java - This eventually produces a standard Android .apk package @@ -42,8 +40,7 @@ dispatches to native functions implemented in the SDL library: src/core/android/SDL_android.c -================================================================================ - Building an app +Building an app ================================================================================ For simple projects you can use the script located at build-scripts/androidbuild.sh @@ -71,14 +68,22 @@ Finally, a word of caution: re running androidbuild.sh wipes any changes you may done in the build directory for the app! -For more complex projects, follow these instructions: - -1. Copy the android-project directory wherever you want to keep your projects - and rename it to the name of your project. -2. Move or symlink this SDL directory into the "/app/jni" directory -3. Edit "/app/jni/src/Android.mk" to include your source files -4a. If you want to use Android Studio, simply open your directory and start building. +For more complex projects, follow these instructions: + +1. Get the source code for SDL and copy the 'android-project' directory located at SDL/android-project to a suitable location. Also make sure to rename it to your project name (In these examples: YOURPROJECT). + + (The 'android-project' directory can basically be seen as a sort of starting point for the android-port of your project. It contains the glue code between the Android Java 'frontend' and the SDL code 'backend'. It also contains some standard behaviour, like how events should be handled, which you will be able to change.) + +2. Move or [symlink](https://en.wikipedia.org/wiki/Symbolic_link) the SDL directory into the "YOURPROJECT/app/jni" directory + +(This is needed as the source of SDL has to be compiled by the Android compiler) + +3. Edit "YOURPROJECT/app/jni/src/Android.mk" to include your source files. + +(They should be separated by spaces after the "LOCAL_SRC_FILES := " declaration) + +4a. If you want to use Android Studio, simply open your 'YOURPROJECT' directory and start building. 4b. If you want to build manually, run './gradlew installDebug' in the project directory. This compiles the .java, creates an .apk with the native code embedded, and installs it on any connected Android device @@ -86,9 +91,9 @@ For more complex projects, follow these instructions: If you already have a project that uses CMake, the instructions change somewhat: 1. Do points 1 and 2 from the instruction above. -2. Edit "/app/build.gradle" to comment out or remove sections containing ndk-build +2. Edit "YOURPROJECT/app/build.gradle" to comment out or remove sections containing ndk-build and uncomment the cmake sections. Add arguments to the CMake invocation as needed. -3. Edit "/app/jni/CMakeLists.txt" to include your project (it defaults to +3. Edit "YOURPROJECT/app/jni/CMakeLists.txt" to include your project (it defaults to adding the "src" subdirectory). Note that you'll have SDL2, SDL2main and SDL2-static as targets in your project, so you should have "target_link_libraries(yourgame SDL2 SDL2main)" in your CMakeLists.txt file. Also be aware that you should use add_library() instead of @@ -120,8 +125,7 @@ Here's an explanation of the files in the Android project, so you can customize src/main/java/org/libsdl/app/SDLActivity.java - the Java class handling the initialization and binding to SDL. Be very careful changing this, as the SDL library relies on this implementation. You should instead subclass this for your application. -================================================================================ - Customizing your application name +Customizing your application name ================================================================================ To customize your application name, edit AndroidManifest.xml and replace @@ -136,23 +140,22 @@ Here's an example of a minimal class file: --- MyGame.java -------------------------- package com.gamemaker.game; - - import org.libsdl.app.SDLActivity; - + + import org.libsdl.app.SDLActivity; + /** - * A sample wrapper class that just calls SDLActivity - */ - + * A sample wrapper class that just calls SDLActivity + */ + public class MyGame extends SDLActivity { } - + ------------------------------------------ Then replace "SDLActivity" in AndroidManifest.xml with the name of your class, .e.g. "MyGame" -================================================================================ - Customizing your application icon +Customizing your application icon ================================================================================ Conceptually changing your icon is just replacing the "ic_launcher.png" files in @@ -160,8 +163,7 @@ the drawable directories under the res directory. There are several directories for different screen sizes. -================================================================================ - Loading assets +Loading assets ================================================================================ Any files you put in the "app/src/main/assets" directory of your project @@ -185,12 +187,11 @@ may want to keep this fact in mind when building your APK, specially when large files are involved. For more information on which extensions get compressed by default and how to disable this behaviour, see for example: - + http://ponystyle.com/blog/2010/03/26/dealing-with-asset-compression-in-android-apps/ -================================================================================ - Pause / Resume behaviour +Pause / Resume behaviour ================================================================================ If SDL_HINT_ANDROID_BLOCK_ON_PAUSE hint is set (the default), @@ -205,13 +206,40 @@ app can continue to operate as it was. However, there's a chance (on older hardware, or on systems under heavy load), where the GL context can not be restored. In that case you have to listen for -a specific message, (which is not yet implemented!) and restore your textures -manually or quit the app (which is actually the kind of behaviour you'll see -under iOS, if the OS can not restore your GL context it will just kill your app) +a specific message (SDL_RENDER_DEVICE_RESET) and restore your textures +manually or quit the app. +You should not use the SDL renderer API while the app going in background: +- SDL_APP_WILLENTERBACKGROUND: + after you read this message, GL context gets backed-up and you should not + use the SDL renderer API. + When this event is received, you have to set the render target to NULL, if you're using it. + (eg call SDL_SetRenderTarget(renderer, NULL)) + +- SDL_APP_DIDENTERFOREGROUND: + GL context is restored, and the SDL renderer API is available (unless you + receive SDL_RENDER_DEVICE_RESET). + +Mouse / Touch events ================================================================================ - Threads and the Java VM + +In some case, SDL generates synthetic mouse (resp. touch) events for touch +(resp. mouse) devices. +To enable/disable this behavior, see SDL_hints.h: +- SDL_HINT_TOUCH_MOUSE_EVENTS +- SDL_HINT_MOUSE_TOUCH_EVENTS + +Misc +================================================================================ + +For some device, it appears to works better setting explicitly GL attributes +before creating a window: + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); + +Threads and the Java VM ================================================================================ For a quick tour on how Linux native threads interoperate with the Java VM, take @@ -226,8 +254,17 @@ your thread automatically anyway (when you make an SDL call), but it'll never detach it. -================================================================================ - Using STL +If you ever want to use JNI in a native thread (created by "SDL_CreateThread()"), +it won't be able to find your java class and method because of the java class loader +which is different for native threads, than for java threads (eg your "main()"). + +the work-around is to find class/method, in you "main()" thread, and to use them +in your native thread. + +see: +https://developer.android.com/training/articles/perf-jni#faq:-why-didnt-findclass-find-my-class + +Using STL ================================================================================ You can use STL in your project by creating an Application.mk file in the jni @@ -239,8 +276,7 @@ For more information go here: https://developer.android.com/ndk/guides/cpp-support -================================================================================ - Using the emulator +Using the emulator ================================================================================ There are some good tips and tricks for getting the most out of the @@ -252,8 +288,7 @@ Notice that this software emulator is incredibly slow and needs a lot of disk sp Using a real device works better. -================================================================================ - Troubleshooting +Troubleshooting ================================================================================ You can see if adb can see any devices with the following command: @@ -323,7 +358,7 @@ I get output from addr2line showing that it's in the quit function, in testsprit You can add logging to your code to help show what's happening: #include - + __android_log_print(ANDROID_LOG_INFO, "foo", "Something happened! x = %d", x); If you need to build without optimization turned on, you can create a file called @@ -332,8 +367,7 @@ If you need to build without optimization turned on, you can create a file calle APP_OPTIM := debug -================================================================================ - Memory debugging +Memory debugging ================================================================================ The best (and slowest) way to debug memory issues on Android is valgrind. @@ -384,8 +418,7 @@ When you're done instrumenting with valgrind, you can disable the wrapper: adb shell setprop wrap.org.libsdl.app "" -================================================================================ - Graphics debugging +Graphics debugging ================================================================================ If you are developing on a compatible Tegra-based tablet, NVidia provides @@ -398,18 +431,16 @@ The Tegra Graphics Debugger is available from NVidia here: https://developer.nvidia.com/tegra-graphics-debugger -================================================================================ - Why is API level 16 the minimum required? +Why is API level 19 the minimum required? ================================================================================ -The latest NDK toolchain doesn't support targeting earlier than API level 16. -As of this writing, according to https://developer.android.com/about/dashboards/index.html -about 99% of the Android devices accessing Google Play support API level 16 or -higher (January 2018). +The latest NDK toolchain doesn't support targeting earlier than API level 19. +As of this writing, according to https://www.composables.com/tools/distribution-chart +about 99.7% of the Android devices accessing Google Play support API level 19 or +higher (August 2023). -================================================================================ - A note regarding the use of the "dirty rectangles" rendering technique +A note regarding the use of the "dirty rectangles" rendering technique ================================================================================ If your app uses a variation of the "dirty rectangles" rendering technique, @@ -417,7 +448,7 @@ where you only update a portion of the screen on each frame, you may notice a variety of visual glitches on Android, that are not present on other platforms. This is caused by SDL's use of EGL as the support system to handle OpenGL ES/ES2 contexts, in particular the use of the eglSwapBuffers function. As stated in the -documentation for the function "The contents of ancillary buffers are always +documentation for the function "The contents of ancillary buffers are always undefined after calling eglSwapBuffers". Setting the EGL_SWAP_BEHAVIOR attribute of the surface to EGL_BUFFER_PRESERVED is not possible for SDL as it requires EGL 1.4, available only on the API level @@ -427,8 +458,7 @@ screen each frame. Reference: http://www.khronos.org/registry/egl/specs/EGLTechNote0001.html -================================================================================ - Ending your application +Ending your application ================================================================================ Two legitimate ways: @@ -437,7 +467,7 @@ Two legitimate ways: Activity by calling Activity.finish(). - Android OS can decide to terminate your application by calling onDestroy() -(see Activity life cycle). Your application will receive a SDL_QUIT event you +(see Activity life cycle). Your application will receive a SDL_QUIT event you can handle to save things and quit. Don't call exit() as it stops the activity badly. @@ -445,8 +475,7 @@ Don't call exit() as it stops the activity badly. NB: "Back button" can be handled as a SDL_KEYDOWN/UP events, with Keycode SDLK_AC_BACK, for any purpose. -================================================================================ - Known issues +Known issues ================================================================================ - The number of buttons reported for each joystick is hardcoded to be 36, which diff --git a/SDL2-2.30.5/docs/README-cmake.md b/SDL2-2.30.5/docs/README-cmake.md new file mode 100644 index 0000000..cfd4066 --- /dev/null +++ b/SDL2-2.30.5/docs/README-cmake.md @@ -0,0 +1,163 @@ +# CMake + +(www.cmake.org) + +SDL's build system was traditionally based on autotools. Over time, this +approach has suffered from several issues across the different supported +platforms. +To solve these problems, a new build system based on CMake was introduced. +It is developed in parallel to the legacy autotools build system, so users +can experiment with it without complication. + +The CMake build system is supported on the following platforms: + +* FreeBSD +* Linux +* Microsoft Visual C +* MinGW and Msys +* macOS, iOS, and tvOS, with support for XCode +* Android +* Emscripten +* RiscOS +* Playstation Vita + +## Building SDL + +Assuming the source for SDL is located at `~/sdl` +```sh +cd ~ +mkdir build +cd build +cmake ~/sdl +cmake --build . +``` + +This will build the static and dynamic versions of SDL in the `~/build` directory. +Installation can be done using: + +```sh +cmake --install . # '--install' requires CMake 3.15, or newer +``` + +## Including SDL in your project + +SDL can be included in your project in 2 major ways: +- using a system SDL library, provided by your (*nix) distribution or a package manager +- using a vendored SDL library: this is SDL copied or symlinked in a subfolder. + +The following CMake script supports both, depending on the value of `MYGAME_VENDORED`. + +```cmake +cmake_minimum_required(VERSION 3.5) +project(mygame) + +# Create an option to switch between a system sdl library and a vendored sdl library +option(MYGAME_VENDORED "Use vendored libraries" OFF) + +if(MYGAME_VENDORED) + add_subdirectory(vendored/sdl EXCLUDE_FROM_ALL) +else() + # 1. Look for a SDL2 package, 2. look for the SDL2 component and 3. fail if none can be found + find_package(SDL2 REQUIRED CONFIG REQUIRED COMPONENTS SDL2) + + # 1. Look for a SDL2 package, 2. Look for the SDL2maincomponent and 3. DO NOT fail when SDL2main is not available + find_package(SDL2 REQUIRED CONFIG COMPONENTS SDL2main) +endif() + +# Create your game executable target as usual +add_executable(mygame WIN32 mygame.c) + +# SDL2::SDL2main may or may not be available. It is e.g. required by Windows GUI applications +if(TARGET SDL2::SDL2main) + # It has an implicit dependency on SDL2 functions, so it MUST be added before SDL2::SDL2 (or SDL2::SDL2-static) + target_link_libraries(mygame PRIVATE SDL2::SDL2main) +endif() + +# Link to the actual SDL2 library. SDL2::SDL2 is the shared SDL library, SDL2::SDL2-static is the static SDL libarary. +target_link_libraries(mygame PRIVATE SDL2::SDL2) +``` + +### A system SDL library + +For CMake to find SDL, it must be installed in [a default location CMake is looking for](https://cmake.org/cmake/help/latest/command/find_package.html#config-mode-search-procedure). + +The following components are available, to be used as an argument of `find_package`. + +| Component name | Description | +|----------------|--------------------------------------------------------------------------------------------| +| SDL2 | The SDL2 shared library, available through the `SDL2::SDL2` target [^SDL_TARGET_EXCEPTION] | +| SDL2-static | The SDL2 static library, available through the `SDL2::SDL2-static` target | +| SDL2main | The SDL2main static library, available through the `SDL2::SDL2main` target | +| SDL2test | The SDL2test static library, available through the `SDL2::SDL2test` target | + +### Using a vendored SDL + +This only requires a copy of SDL in a subdirectory. + +## CMake configuration options for platforms + +### iOS/tvOS + +CMake 3.14+ natively includes support for iOS and tvOS. SDL binaries may be built +using Xcode or Make, possibly among other build-systems. + +When using a recent version of CMake (3.14+), it should be possible to: + +- build SDL for iOS, both static and dynamic +- build SDL test apps (as iOS/tvOS .app bundles) +- generate a working SDL_config.h for iOS (using SDL_config.h.cmake as a basis) + +To use, set the following CMake variables when running CMake's configuration stage: + +- `CMAKE_SYSTEM_NAME=` (either `iOS` or `tvOS`) +- `CMAKE_OSX_SYSROOT=` (examples: `iphoneos`, `iphonesimulator`, `iphoneos12.4`, `/full/path/to/iPhoneOS.sdk`, + `appletvos`, `appletvsimulator`, `appletvos12.4`, `/full/path/to/AppleTVOS.sdk`, etc.) +- `CMAKE_OSX_ARCHITECTURES=` (example: "arm64;armv7s;x86_64") + + +#### Examples + +- for iOS-Simulator, using the latest, installed SDK: + + ```bash + cmake ~/sdl -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_SYSROOT=iphonesimulator -DCMAKE_OSX_ARCHITECTURES=x86_64 + ``` + +- for iOS-Device, using the latest, installed SDK, 64-bit only + + ```bash + cmake ~/sdl -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_SYSROOT=iphoneos -DCMAKE_OSX_ARCHITECTURES=arm64 + ``` + +- for iOS-Device, using the latest, installed SDK, mixed 32/64 bit + + ```cmake + cmake ~/sdl -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_SYSROOT=iphoneos -DCMAKE_OSX_ARCHITECTURES="arm64;armv7s" + ``` + +- for iOS-Device, using a specific SDK revision (iOS 12.4, in this example): + + ```cmake + cmake ~/sdl -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_SYSROOT=iphoneos12.4 -DCMAKE_OSX_ARCHITECTURES=arm64 + ``` + +- for iOS-Simulator, using the latest, installed SDK, and building SDL test apps (as .app bundles): + + ```cmake + cmake ~/sdl -DSDL_TESTS=1 -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_SYSROOT=iphonesimulator -DCMAKE_OSX_ARCHITECTURES=x86_64 + ``` + +- for tvOS-Simulator, using the latest, installed SDK: + + ```cmake + cmake ~/sdl -DCMAKE_SYSTEM_NAME=tvOS -DCMAKE_OSX_SYSROOT=appletvsimulator -DCMAKE_OSX_ARCHITECTURES=x86_64 + ``` + +- for tvOS-Device, using the latest, installed SDK: + + ```cmake + cmake ~/sdl -DCMAKE_SYSTEM_NAME=tvOS -DCMAKE_OSX_SYSROOT=appletvos -DCMAKE_OSX_ARCHITECTURES=arm64` + ``` + + +[^SDL_TARGET_EXCEPTION]: `SDL2::SDL2` can be an ALIAS to a static `SDL2::SDL2-static` target for multiple reasons. diff --git a/SDL2-2.0.12/docs/README-directfb.md b/SDL2-2.30.5/docs/README-directfb.md similarity index 76% rename from SDL2-2.0.12/docs/README-directfb.md rename to SDL2-2.30.5/docs/README-directfb.md index eeac428..bbc6e99 100644 --- a/SDL2-2.0.12/docs/README-directfb.md +++ b/SDL2-2.30.5/docs/README-directfb.md @@ -12,40 +12,47 @@ Supports: What you need: * DirectFB 1.0.1, 1.2.x, 1.3.0 -* Kernel-Framebuffer support: required: vesafb, radeonfb .... +* Kernel-Framebuffer support: required: vesafb, radeonfb .... * Mesa 7.0.x - optional for OpenGL -/etc/directfbrc - -This file should contain the following lines to make +The `/etc/directfbrc` file should contain the following lines to make your joystick work and avoid crashes: ------------------------- + +``` disable-module=joystick disable-module=cle266 disable-module=cyber5k no-linux-input-grab ------------------------- +``` To disable to use x11 backend when DISPLAY variable is found use +``` export SDL_DIRECTFB_X11_CHECK=0 +``` To disable the use of linux input devices, i.e. multimice/multikeyboard support, use +``` export SDL_DIRECTFB_LINUX_INPUT=0 +``` To use hardware accelerated YUV-overlays for YUV-textures, use: +``` export SDL_DIRECTFB_YUV_DIRECT=1 +``` -This is disabled by default. It will only support one +This is disabled by default. It will only support one YUV texture, namely the first. Every other YUV texture will be rendered in software. In addition, you may use (directfb-1.2.x) +``` export SDL_DIRECTFB_YUV_UNDERLAY=1 +``` to make the YUV texture an underlay. This will make the cursor to be shown. @@ -54,14 +61,18 @@ Simple Window Manager ===================== The driver has support for a very, very basic window manager you may -want to use when running with "wm=default". Use +want to use when running with `wm=default`. Use +``` export SDL_DIRECTFB_WM=1 +``` to enable basic window borders. In order to have the window title rendered, you need to have the following font installed: +``` /usr/share/fonts/truetype/freefont/FreeSans.ttf +``` OpenGL Support ============== @@ -71,21 +82,25 @@ works at least on all directfb supported platforms. As of this writing 20100802 you need to pull Mesa from git and do the following: ------------------------- +``` git clone git://anongit.freedesktop.org/git/mesa/mesa -cd mesa +cd mesa git checkout 2c9fdaf7292423c157fc79b5ce43f0f199dd753a ------------------------- +``` -Edit configs/linux-directfb so that the Directories-section looks like ------------------------- +Edit `configs/linux-directfb` so that the Directories-section looks like this: + +``` # Directories -SRC_DIRS = mesa glu +SRC_DIRS = mesa glu GLU_DIRS = sgi DRIVER_DIRS = directfb -PROGRAM_DIRS = ------------------------- +PROGRAM_DIRS = +``` +Then do the following: + +``` make linux-directfb make @@ -95,13 +110,14 @@ sudo make install INSTALL_DIR=/usr/local/dfb_GL cd src/mesa/drivers/directfb make sudo make install INSTALL_DIR=/usr/local/dfb_GL ------------------------- +``` To run the SDL - testprograms: +``` export SDL_VIDEODRIVER=directfb export LD_LIBRARY_PATH=/usr/local/dfb_GL/lib export LD_PRELOAD=/usr/local/dfb_GL/libGL.so.7 ./testgl - +``` diff --git a/SDL2-2.0.12/docs/README-dynapi.md b/SDL2-2.30.5/docs/README-dynapi.md similarity index 77% rename from SDL2-2.0.12/docs/README-dynapi.md rename to SDL2-2.30.5/docs/README-dynapi.md index 40b44db..76b868c 100644 --- a/SDL2-2.0.12/docs/README-dynapi.md +++ b/SDL2-2.30.5/docs/README-dynapi.md @@ -1,33 +1,32 @@ -Dynamic API -================================================================================ -Originally posted by Ryan at: - https://plus.google.com/103391075724026391227/posts/TB8UfnDYu4U +# Dynamic API + +Originally posted on Ryan's Google+ account. Background: -- The Steam Runtime has (at least in theory) a really kick-ass build of SDL2, - but developers are shipping their own SDL2 with individual Steam games. - These games might stop getting updates, but a newer SDL2 might be needed later. - Certainly we'll always be fixing bugs in SDL, even if a new video target isn't +- The Steam Runtime has (at least in theory) a really kick-ass build of SDL2, + but developers are shipping their own SDL2 with individual Steam games. + These games might stop getting updates, but a newer SDL2 might be needed later. + Certainly we'll always be fixing bugs in SDL, even if a new video target isn't ever needed, and these fixes won't make it to a game shipping its own SDL. -- Even if we replace the SDL2 in those games with a compatible one, that is to - say, edit a developer's Steam depot (yuck!), there are developers that are - statically linking SDL2 that we can't do this for. We can't even force the +- Even if we replace the SDL2 in those games with a compatible one, that is to + say, edit a developer's Steam depot (yuck!), there are developers that are + statically linking SDL2 that we can't do this for. We can't even force the dynamic loader to ignore their SDL2 in this case, of course. - If you don't ship an SDL2 with the game in some form, people that disabled the - Steam Runtime, or just tried to run the game from the command line instead of + Steam Runtime, or just tried to run the game from the command line instead of Steam might find themselves unable to run the game, due to a missing dependency. - If you want to ship on non-Steam platforms like GOG or Humble Bundle, or target - generic Linux boxes that may or may not have SDL2 installed, you have to ship - the library or risk a total failure to launch. So now, you might have to have - a non-Steam build plus a Steam build (that is, one with and one without SDL2 - included), which is inconvenient if you could have had one universal build + generic Linux boxes that may or may not have SDL2 installed, you have to ship + the library or risk a total failure to launch. So now, you might have to have + a non-Steam build plus a Steam build (that is, one with and one without SDL2 + included), which is inconvenient if you could have had one universal build that works everywhere. -- We like the zlib license, but the biggest complaint from the open source - community about the license change is the static linking. The LGPL forced this +- We like the zlib license, but the biggest complaint from the open source + community about the license change is the static linking. The LGPL forced this as a legal, not technical issue, but zlib doesn't care. Even those that aren't - concerned about the GNU freedoms found themselves solving the same problems: - swapping in a newer SDL to an older game often times can save the day. + concerned about the GNU freedoms found themselves solving the same problems: + swapping in a newer SDL to an older game often times can save the day. Static linking stops this dead. So here's what we did: @@ -35,96 +34,105 @@ So here's what we did: SDL now has, internally, a table of function pointers. So, this is what SDL_Init now looks like: - UInt32 SDL_Init(Uint32 flags) - { - return jump_table.SDL_Init(flags); - } +```c +Uint32 SDL_Init(Uint32 flags) +{ + return jump_table.SDL_Init(flags); +} +``` Except that is all done with a bunch of macro magic so we don't have to maintain every one of these. What is jump_table.SDL_init()? Eventually, that's a function pointer of the real -SDL_Init() that you've been calling all this time. But at startup, it looks more +SDL_Init() that you've been calling all this time. But at startup, it looks more like this: - Uint32 SDL_Init_DEFAULT(Uint32 flags) - { - SDL_InitDynamicAPI(); - return jump_table.SDL_Init(flags); - } +```c +Uint32 SDL_Init_DEFAULT(Uint32 flags) +{ + SDL_InitDynamicAPI(); + return jump_table.SDL_Init(flags); +} +``` -SDL_InitDynamicAPI() fills in jump_table with all the actual SDL function -pointers, which means that this _DEFAULT function never gets called again. +SDL_InitDynamicAPI() fills in jump_table with all the actual SDL function +pointers, which means that this `_DEFAULT` function never gets called again. First call to any SDL function sets the whole thing up. So you might be asking, what was the value in that? Isn't this what the operating -system's dynamic loader was supposed to do for us? Yes, but now we've got this +system's dynamic loader was supposed to do for us? Yes, but now we've got this level of indirection, we can do things like this: - export SDL_DYNAMIC_API=/my/actual/libSDL-2.0.so.0 - ./MyGameThatIsStaticallyLinkedToSDL2 +```bash +export SDL_DYNAMIC_API=/my/actual/libSDL-2.0.so.0 +./MyGameThatIsStaticallyLinkedToSDL2 +``` -And now, this game that is statically linked to SDL, can still be overridden -with a newer, or better, SDL. The statically linked one will only be used as +And now, this game that is statically linked to SDL, can still be overridden +with a newer, or better, SDL. The statically linked one will only be used as far as calling into the jump table in this case. But in cases where no override -is desired, the statically linked version will provide its own jump table, +is desired, the statically linked version will provide its own jump table, and everyone is happy. So now: -- Developers can statically link SDL, and users can still replace it. +- Developers can statically link SDL, and users can still replace it. (We'd still rather you ship a shared library, though!) -- Developers can ship an SDL with their game, Valve can override it for, say, - new features on SteamOS, or distros can override it for their own needs, +- Developers can ship an SDL with their game, Valve can override it for, say, + new features on SteamOS, or distros can override it for their own needs, but it'll also just work in the default case. -- Developers can ship the same package to everyone (Humble Bundle, GOG, etc), +- Developers can ship the same package to everyone (Humble Bundle, GOG, etc), and it'll do the right thing. -- End users (and Valve) can update a game's SDL in almost any case, +- End users (and Valve) can update a game's SDL in almost any case, to keep abandoned games running on newer platforms. -- Everyone develops with SDL exactly as they have been doing all along. +- Everyone develops with SDL exactly as they have been doing all along. Same headers, same ABI. Just get the latest version to enable this magic. A little more about SDL_InitDynamicAPI(): -Internally, InitAPI does some locking to make sure everything waits until a -single thread initializes everything (although even SDL_CreateThread() goes +Internally, InitAPI does some locking to make sure everything waits until a +single thread initializes everything (although even SDL_CreateThread() goes through here before spinning a thread, too), and then decides if it should use -an external SDL library. If not, it sets up the jump table using the current +an external SDL library. If not, it sets up the jump table using the current SDL's function pointers (which might be statically linked into a program, or in -a shared library of its own). If so, it loads that library and looks for and +a shared library of its own). If so, it loads that library and looks for and calls a single function: - SInt32 SDL_DYNAPI_entry(Uint32 version, void *table, Uint32 tablesize); +```c +Sint32 SDL_DYNAPI_entry(Uint32 version, void *table, Uint32 tablesize); +``` That function takes a version number (more on that in a moment), the address of -the jump table, and the size, in bytes, of the table. -Now, we've got policy here: this table's layout never changes; new stuff gets -added to the end. Therefore SDL_DYNAPI_entry() knows that it can provide all +the jump table, and the size, in bytes, of the table. +Now, we've got policy here: this table's layout never changes; new stuff gets +added to the end. Therefore SDL_DYNAPI_entry() knows that it can provide all the needed functions if tablesize <= sizeof its own jump table. If tablesize is bigger (say, SDL 2.0.4 is trying to load SDL 2.0.3), then we know to abort, but if it's smaller, we know we can provide the entire API that the caller needs. -The version variable is a failsafe switch. -Right now it's always 1. This number changes when there are major API changes -(so we know if the tablesize might be smaller, or entries in it have changed). -Right now SDL_DYNAPI_entry gives up if the version doesn't match, but it's not -inconceivable to have a small dispatch library that only supplies this one +The version variable is a failsafe switch. +Right now it's always 1. This number changes when there are major API changes +(so we know if the tablesize might be smaller, or entries in it have changed). +Right now SDL_DYNAPI_entry gives up if the version doesn't match, but it's not +inconceivable to have a small dispatch library that only supplies this one function and loads different, otherwise-incompatible SDL libraries and has the -right one initialize the jump table based on the version. For something that -must generically catch lots of different versions of SDL over time, like the +right one initialize the jump table based on the version. For something that +must generically catch lots of different versions of SDL over time, like the Steam Client, this isn't a bad option. Finally, I'm sure some people are reading this and thinking, -"I don't want that overhead in my project!" -To which I would point out that the extra function call through the jump table -probably wouldn't even show up in a profile, but lucky you: this can all be -disabled. You can build SDL without this if you absolutely must, but we would -encourage you not to do that. However, on heavily locked down platforms like +"I don't want that overhead in my project!" + +To which I would point out that the extra function call through the jump table +probably wouldn't even show up in a profile, but lucky you: this can all be +disabled. You can build SDL without this if you absolutely must, but we would +encourage you not to do that. However, on heavily locked down platforms like iOS, or maybe when debugging, it makes sense to disable it. The way this is -designed in SDL, you just have to change one #define, and the entire system -vaporizes out, and SDL functions exactly like it always did. Most of it is -macro magic, so the system is contained to one C file and a few headers. -However, this is on by default and you have to edit a header file to turn it -off. Our hopes is that if we make it easy to disable, but not too easy, -everyone will ultimately be able to get what they want, but we've gently +designed in SDL, you just have to change one #define, and the entire system +vaporizes out, and SDL functions exactly like it always did. Most of it is +macro magic, so the system is contained to one C file and a few headers. +However, this is on by default and you have to edit a header file to turn it +off. Our hopes is that if we make it easy to disable, but not too easy, +everyone will ultimately be able to get what they want, but we've gently nudged everyone towards what we think is the best solution. diff --git a/SDL2-2.30.5/docs/README-emscripten.md b/SDL2-2.30.5/docs/README-emscripten.md new file mode 100644 index 0000000..1a13eb1 --- /dev/null +++ b/SDL2-2.30.5/docs/README-emscripten.md @@ -0,0 +1,374 @@ +# Emscripten + +## The state of things + +(As of September 2023, but things move quickly and we don't update this +document often.) + +In modern times, all the browsers you probably care about (Chrome, Firefox, +Edge, and Safari, on Windows, macOS, Linux, iOS and Android), support some +reasonable base configurations: + +- WebAssembly (don't bother with asm.js any more) +- WebGL (which will look like OpenGL ES 2 or 3 to your app). +- Threads (see caveats, though!) +- Game controllers +- Autoupdating (so you can assume they have a recent version of the browser) + +All this to say we're at the point where you don't have to make a lot of +concessions to get even a fairly complex SDL-based game up and running. + + +## RTFM + +This document is a quick rundown of some high-level details. The +documentation at [emscripten.org](https://emscripten.org/) is vast +and extremely detailed for a wide variety of topics, and you should at +least skim through it at some point. + + +## Porting your app to Emscripten + +Many many things just need some simple adjustments and they'll compile +like any other C/C++ code, as long as SDL was handling the platform-specific +work for your program. + +First, you probably need this in at least one of your source files: + +```c +#ifdef __EMSCRIPTEN__ +#include +#endif +``` + +Second: assembly language code has to go. Replace it with C. You can even use +[x86 SIMD intrinsic functions in Emscripten](https://emscripten.org/docs/porting/simd.html)! + +Third: Middleware has to go. If you have a third-party library you link +against, you either need an Emscripten port of it, or the source code to it +to compile yourself, or you need to remove it. + +Fourth: You still start in a function called main(), but you need to get out of +it and into a function that gets called repeatedly, and returns quickly, +called a mainloop. + +Somewhere in your program, you probably have something that looks like a more +complicated version of this: + +```c +void main(void) +{ + initialize_the_game(); + while (game_is_still_running) { + check_for_new_input(); + think_about_stuff(); + draw_the_next_frame(); + } + deinitialize_the_game(); +} +``` + +This will not work on Emscripten, because the main thread needs to be free +to do stuff and can't sit in this loop forever. So Emscripten lets you set up +a [mainloop](https://emscripten.org/docs/porting/emscripten-runtime-environment.html#browser-main-loop). + +```c +static void mainloop(void) /* this will run often, possibly at the monitor's refresh rate */ +{ + if (!game_is_still_running) { + deinitialize_the_game(); + #ifdef __EMSCRIPTEN__ + emscripten_cancel_main_loop(); /* this should "kill" the app. */ + #else + exit(0); + #endif + } + + check_for_new_input(); + think_about_stuff(); + draw_the_next_frame(); +} + +void main(void) +{ + initialize_the_game(); + #ifdef __EMSCRIPTEN__ + emscripten_set_main_loop(mainloop, 0, 1); + #else + while (1) { mainloop(); } + #endif +} +``` + +Basically, `emscripten_set_main_loop(mainloop, 0, 1);` says "run +`mainloop` over and over until I end the program." The function will +run, and return, freeing the main thread for other tasks, and then +run again when it's time. The `1` parameter does some magic to make +your main() function end immediately; this is useful because you +don't want any shutdown code that might be sitting below this code +to actually run if main() were to continue on, since we're just +getting started. + +There's a lot of little details that are beyond the scope of this +document, but that's the biggest intial set of hurdles to porting +your app to the web. + + +## Do you need threads? + +If you plan to use threads, they work on all major browsers now. HOWEVER, +they bring with them a lot of careful considerations. Rendering _must_ +be done on the main thread. This is a general guideline for many +platforms, but a hard requirement on the web. + +Many other things also must happen on the main thread; often times SDL +and Emscripten make efforts to "proxy" work to the main thread that +must be there, but you have to be careful (and read more detailed +documentation than this for the finer points). + +Even when using threads, your main thread needs to set an Emscripten +mainloop that runs quickly and returns, or things will fail to work +correctly. + +You should definitely read [Emscripten's pthreads docs](https://emscripten.org/docs/porting/pthreads.html) +for all the finer points. Mostly SDL's thread API will work as expected, +but is built on pthreads, so it shares the same little incompatibilities +that are documented there, such as where you can use a mutex, and when +a thread will start running, etc. + + +IMPORTANT: You have to decide to either build something that uses +threads or something that doesn't; you can't have one build +that works everywhere. This is an Emscripten (or maybe WebAssembly? +Or just web browsers in general?) limitation. If you aren't using +threads, it's easier to not enable them at all, at build time. + +If you use threads, you _have to_ run from a web server that has +[COOP/COEP headers set correctly](https://web.dev/why-coop-coep/) +or your program will fail to start at all. + +If building with threads, `__EMSCRIPTEN_PTHREADS__` will be defined +for checking with the C preprocessor, so you can build something +different depending on what sort of build you're compiling. + + +## Audio + +Audio works as expected at the API level, but not exactly like other +platforms. + +You'll only see a single default audio device. Audio capture also works; +if the browser pops up a prompt to ask for permission to access the +microphone, the SDL_OpenAudioDevice call will succeed and start producing +silence at a regular interval. Once the user approves the request, real +audio data will flow. If the user denies it, the app is not informed and +will just continue to receive silence. + +Modern web browsers will not permit web pages to produce sound before the +user has interacted with them (clicked or tapped on them, usually); this is +for several reasons, not the least of which being that no one likes when a +random browser tab suddenly starts making noise and the user has to scramble +to figure out which and silence it. + +SDL will allow you to open the audio device for playback in this +circumstance, and your audio callback will fire, but SDL will throw the audio +data away until the user interacts with the page. This helps apps that depend +on the audio callback to make progress, and also keeps audio playback in sync +once the app is finally allowed to make noise. + +There are two reasonable ways to deal with the silence at the app level: +if you are writing some sort of media player thing, where the user expects +there to be a volume control when you mouseover the canvas, just default +that control to a muted state; if the user clicks on the control to unmute +it, on this first click, open the audio device. This allows the media to +play at start, and the user can reasonably opt-in to listening. + +Many games do not have this sort of UI, and are more rigid about starting +audio along with everything else at the start of the process. For these, your +best bet is to write a little Javascript that puts up a "Click here to play!" +UI, and upon the user clicking, remove that UI and then call the Emscripten +app's main() function. As far as the application knows, the audio device was +available to be opened as soon as the program started, and since this magic +happens in a little Javascript, you don't have to change your C/C++ code at +all to make it happen. + +Please see the discussion at https://github.com/libsdl-org/SDL/issues/6385 +for some Javascript code to steal for this approach. + + +## Rendering + +If you use SDL's 2D render API, it will use GLES2 internally, which +Emscripten will turn into WebGL calls. You can also use OpenGL ES 2 +directly by creating a GL context and drawing into it. + +Calling SDL_RenderPresent (or SDL_GL_SwapWindow) will not actually +present anything on the screen until your return from your mainloop +function. + + +## Building SDL/emscripten + +First: do you _really_ need to build SDL from source? + +If you aren't developing SDL itself, have a desire to mess with its source +code, or need something on the bleeding edge, don't build SDL. Just use +Emscripten's packaged version! + +Compile and link your app with `-sUSE_SDL=2` and it'll use a build of +SDL packaged with Emscripten. This comes from the same source code and +fixes the Emscripten project makes to SDL are generally merged into SDL's +revision control, so often this is much easier for app developers. + +`-sUSE_SDL=1` will select Emscripten's JavaScript reimplementation of SDL +1.2 instead; if you need SDL 1.2, this might be fine, but we generally +recommend you don't use SDL 1.2 in modern times. + + +If you want to build SDL, though... + +SDL currently requires at least Emscripten 3.1.35 to build. Newer versions +are likely to work, as well. + + +Build: + +This works on Linux/Unix and macOS. Please send comments about Windows. + +Make sure you've [installed emsdk](https://emscripten.org/docs/getting_started/downloads.html) +first, and run `source emsdk_env.sh` at the command line so it finds the +tools. + +(These configure options might be overkill, but this has worked for me.) + +```bash +cd SDL +mkdir build +cd build +emconfigure ../configure --host=wasm32-unknown-emscripten --disable-pthreads --disable-assembly --disable-cpuinfo CFLAGS="-sUSE_SDL=0 -O3" +emmake make -j4 +``` + +If you want to build with thread support, something like this works: + +```bash +emconfigure ../configure --host=wasm32-unknown-emscripten --enable-pthreads --disable-assembly --disable-cpuinfo CFLAGS="-sUSE_SDL=0 -O3 -pthread" LDFLAGS="-pthread" +``` + +Or with cmake: + +```bash +mkdir build +cd build +emcmake cmake .. +emmake make -j4 +``` + +To build one of the tests: + +```bash +cd test/ +emcc -O2 --js-opts 0 -g4 testdraw2.c -I../include ../build/.libs/libSDL2.a ../build/libSDL2_test.a -o a.html +``` + +## Building your app + +You need to compile with `emcc` instead of `gcc` or `clang` or whatever, but +mostly it uses the same command line arguments as Clang. + +Link against the SDL/build/.libs/libSDL2.a file you generated by building SDL, +link with `-sUSE_SDL=2` to use Emscripten's prepackaged SDL2 build. + +Usually you would produce a binary like this: + +```bash +gcc -o mygame mygame.c # or whatever +``` + +But for Emscripten, you want to output something else: + +```bash +emcc -o index.html mygame.c +``` + +This will produce several files...support Javascript and WebAssembly (.wasm) +files. The `-o index.html` will produce a simple HTML page that loads and +runs your app. You will (probably) eventually want to replace or customize +that file and do `-o index.js` instead to just build the code pieces. + +If you're working on a program of any serious size, you'll likely need to +link with `-sALLOW_MEMORY_GROWTH=1 -sMAXIMUM_MEMORY=1gb` to get access +to more memory. If using pthreads, you'll need the `-sMAXIMUM_MEMORY=1gb` +or the app will fail to start on iOS browsers, but this might be a bug that +goes away in the future. + + +## Data files + +Your game probably has data files. Here's how to access them. + +Filesystem access works like a Unix filesystem; you have a single directory +tree, possibly interpolated from several mounted locations, no drive letters, +'/' for a path separator. You can access them with standard file APIs like +open() or fopen() or SDL_RWops. You can read or write from the filesystem. + +By default, you probably have a "MEMFS" filesystem (all files are stored in +memory, but access to them is immediate and doesn't need to block). There are +other options, like "IDBFS" (files are stored in a local database, so they +don't need to be in RAM all the time and they can persist between runs of the +program, but access is not synchronous). You can mix and match these file +systems, mounting a MEMFS filesystem at one place and idbfs elsewhere, etc, +but that's beyond the scope of this document. Please refer to Emscripten's +[page on the topic](https://emscripten.org/docs/porting/files/file_systems_overview.html) +for more info. + +The _easiest_ (but not the best) way to get at your data files is to embed +them in the app itself. Emscripten's linker has support for automating this. + +```bash +emcc -o index.html loopwave.c --embed-file=../test/sample.wav@/sounds/sample.wav +``` + +This will pack ../test/sample.wav in your app, and make it available at +"/sounds/sample.wav" at runtime. Emscripten makes sure this data is available +before your main() function runs, and since it's in MEMFS, you can just +read it like you do on other platforms. `--embed-file` can also accept a +directory to pack an entire tree, and you can specify the argument multiple +times to pack unrelated things into the final installation. + +Note that this is absolutely the best approach if you have a few small +files to include and shouldn't worry about the issue further. However, if you +have hundreds of megabytes and/or thousands of files, this is not so great, +since the user will download it all every time they load your page, and it +all has to live in memory at runtime. + +[Emscripten's documentation on the matter](https://emscripten.org/docs/porting/files/packaging_files.html) +gives other options and details, and is worth a read. + + +## Debugging + +Debugging web apps is a mixed bag. You should compile and link with +`-gsource-map`, which embeds a ton of source-level debugging information into +the build, and make sure _the app source code is available on the web server_, +which is often a scary proposition for various reasons. + +When you debug from the browser's tools and hit a breakpoint, you can step +through the actual C/C++ source code, though, which can be nice. + +If you try debugging in Firefox and it doesn't work well for no apparent +reason, try Chrome, and vice-versa. These tools are still relatively new, +and improving all the time. + +SDL_Log() (or even plain old printf) will write to the Javascript console, +and honestly I find printf-style debugging to be easier than setting up a build +for proper debugging, so use whatever tools work best for you. + + +## Questions? + +Please give us feedback on this document at [the SDL bug tracker](https://github.com/libsdl-org/SDL/issues). +If something is wrong or unclear, we want to know! + + + diff --git a/SDL2-2.30.5/docs/README-gdk.md b/SDL2-2.30.5/docs/README-gdk.md new file mode 100644 index 0000000..6718a61 --- /dev/null +++ b/SDL2-2.30.5/docs/README-gdk.md @@ -0,0 +1,176 @@ +GDK +===== + +This port allows SDL applications to run via Microsoft's Game Development Kit (GDK). + +Windows (GDK) and Xbox One/Xbox Series (GDKX) are both supported and all the required code is included in this public SDL release. However, only licensed Xbox developers have access to the GDKX libraries which will allow you to build the Xbox targets. + + +Requirements +------------ + +* Microsoft Visual Studio 2022 (in theory, it should also work in 2017 or 2019, but this has not been tested) +* Microsoft GDK June 2022 or newer (public release [here](https://github.com/microsoft/GDK/releases/tag/June_2022)) +* For Xbox, you will need the corresponding GDKX version (licensed developers only) +* To publish a package or successfully authenticate a user, you will need to create an app id/configure services in Partner Center. However, for local testing purposes (without authenticating on Xbox Live), the identifiers used by the GDK test programs in the included solution will work. + + +Windows GDK Status +------ + +The Windows GDK port supports the full set of Win32 APIs, renderers, controllers, input devices, etc., as the normal Windows x64 build of SDL. + +* Additionally, the GDK port adds the following: + * Compile-time platform detection for SDL programs. The `__GDK__` is `#define`d on every GDK platform, and the `__WINGDK__` is `#define`d on Windows GDK, specifically. (This distinction exists because other GDK platforms support a smaller subset of functionality. This allows you to mark code for "any" GDK separate from Windows GDK.) + * GDK-specific setup: + * Initializing/uninitializing the game runtime, and initializing Xbox Live services + * Creating a global task queue and setting it as the default for the process. When running any async operations, passing in `NULL` as the task queue will make the task get added to the global task queue. + + * An implementation on `WinMain` that performs the above GDK setup (you should link against SDL2main.lib, as in Windows x64). If you are unable to do this, you can instead manually call `SDL_GDKRunApp` from your entry point, passing in your `SDL_main` function and `NULL` as the parameters. + * Global task queue callbacks are dispatched during `SDL_PumpEvents` (which is also called internally if using `SDL_PollEvent`). + * You can get the handle of the global task queue through `SDL_GDKGetTaskQueue`, if needed. When done with the queue, be sure to use `XTaskQueueCloseHandle` to decrement the reference count (otherwise it will cause a resource leak). + +* Single-player games have some additional features available: + * Call `SDL_GDKGetDefaultUser` to get the default XUserHandle pointer. + * `SDL_GetPrefPath` still works, but only for single-player titles. + + These functions mostly wrap around async APIs, and thus should be treated as synchronous alternatives. Also note that the single-player functions return on any OS errors, so be sure to validate the return values! + +* What doesn't work: + * Compilation with anything other than through the included Visual C++ solution file + +## VisualC-GDK Solution + +The included `VisualC-GDK/SDL.sln` solution includes the following targets for the Gaming.Desktop.x64 configuration: + +* SDL2 (DLL) - This is the typical SDL2.dll, but for Gaming.Desktop.x64. +* SDL2main (lib) - This contains a drop-in implementation of `WinMain` that is used as the entry point for GDK programs. +* tests/testgamecontroller - Standard SDL test program demonstrating controller functionality. +* tests/testgdk - GDK-specific test program that demonstrates using the global task queue to login a user into Xbox Live. + *NOTE*: As of the June 2022 GDK, you cannot test user logins without a valid Title ID and MSAAppId. You will need to manually change the identifiers in the `MicrosoftGame.config` to your valid IDs from Partner Center if you wish to test this. +* tests/testsprite2 - Standard SDL test program demonstrating sprite drawing functionality. + +If you set one of the test programs as a startup project, you can run it directly from Visual Studio. + +Windows GDK Setup, Detailed Steps +--------------------- + +These steps assume you already have a game using SDL that runs on Windows x64 along with a corresponding Visual Studio solution file for the x64 version. If you don't have this, it's easiest to use one of the test program vcxproj files in the `VisualC-GDK` directory as a starting point, though you will still need to do most of the steps below. + +### 1. Add a Gaming.Desktop.x64 Configuration ### + +In your game's existing Visual Studio Solution, go to Build > Configuration Manager. From the "Active solution platform" drop-down select "New...". From the drop-down list, select Gaming.Desktop.x64 and copy the settings from the x64 configuration. + +### 2. Build SDL2 and SDL2main for GDK ### + +Open `VisualC-GDK/SDL.sln` in Visual Studio, you need to build the SDL2 and SDL2main targets for the Gaming.Desktop.x64 platform (Release is recommended). You will need to copy/keep track of the `SDL2.dll`, `XCurl.dll` (which is output by Gaming.Desktop.x64), `SDL2.lib`, and `SDL2main.lib` output files for your game project. + +*Alternatively*, you could setup your solution file to instead reference the SDL2/SDL2main project file targets from the SDL source, and add those projects as a dependency. This would mean that SDL2 and SDL2main would both be built when your game is built. + +### 3. Configuring Project Settings ### + +While the Gaming.Desktop.x64 configuration sets most of the required settings, there are some additional items to configure for your game project under the Gaming.Desktop.x64 Configuration: + +* Under C/C++ > General > Additional Include Directories, make sure the `SDL/include` path is referenced +* Under Linker > General > Additional Library Directories, make sure to reference the path where the newly-built SDL2.lib and SDL2main.lib are +* Under Linker > Input > Additional Dependencies, you need the following: + * `SDL2.lib` + * `SDL2main.lib` (unless not using) + * `xgameruntime.lib` + * `../Microsoft.Xbox.Services.141.GDK.C.Thunks.lib` +* Note that in general, the GDK libraries depend on the MSVC C/C++ runtime, so there is no way to remove this dependency from a GDK program that links against GDK. + +### 4. Setting up SDL_main ### + +Rather than using your own implementation of `WinMain`, it's recommended that you instead `#include "SDL_main.h"` and declare a standard main function. If you are unable to do this, you can instead manually call `SDL_GDKRunApp` from your entry point, passing in your `SDL_main` function and `NULL` as the parameters. + +### 5. Required DLLs ### + +The game will not launch in the debugger unless required DLLs are included in the directory that contains the game's .exe file. You need to make sure that the following files are copied into the directory: + +* Your SDL2.dll +* "$(Console_GRDKExtLibRoot)Xbox.Services.API.C\DesignTime\CommonConfiguration\Neutral\Lib\Release\Microsoft.Xbox.Services.141.GDK.C.Thunks.dll" +* XCurl.dll + +You can either copy these in a post-build step, or you can add the dlls into the project and set its Configuration Properties > General > Item type to "Copy file," which will also copy them into the output directory. + +### 6. Setting up MicrosoftGame.config ### + +You can copy `VisualC-GDK/tests/testgdk/MicrosoftGame.config` and use that as a starting point in your project. Minimally, you will want to change the Executable Name attribute, the DefaultDisplayName, and the Description. + +This file must be copied into the same directory as the game's .exe file. As with the DLLs, you can either use a post-build step or the "Copy file" item type. + +For basic testing, you do not need to change anything else in `MicrosoftGame.config`. However, if you want to test any Xbox Live services (such as logging in users) _or_ publish a package, you will need to setup a Game app on Partner Center. + +Then, you need to set the following values to the values from Partner Center: + +* Identity tag - Name and Publisher attributes +* TitleId +* MSAAppId + +### 7. Adding Required Logos + +Several logo PNG files are required to be able to launch the game, even from the debugger. You can use the sample logos provided in `VisualC-GDK/logos`. As with the other files, they must be copied into the same directory as the game's .exe file. + + +### 8. Copying any Data Files ### + +When debugging GDK games, there is no way to specify a working directory. Therefore, any required game data must also be copied into the output directory, likely in a post-build step. + + +### 9. Build and Run from Visual Studio ### + +At this point, you should be able to build and run your game from the Visual Studio Debugger. If you get any linker errors, make sure you double-check that you referenced all the required libs. + +If you are testing Xbox Live functionality, it's likely you will need to change to the Sandbox for your title. To do this: + +1. Run "Desktop VS 2022 Gaming Command Prompt" from the Start Menu +2. Switch the sandbox name with: + `XblPCSandbox SANDBOX.#` +3. (To switch back to the retail sandbox): + `XblPCSandbox RETAIL` + +### 10. Packaging and Installing Locally + +You can use one of the test program's `PackageLayout.xml` as a starting point. Minimally, you will need to change the exe to the correct name and also reference any required game data. As with the other data files, it's easiest if you have this copy to the output directory, although it's not a requirement as you can specify relative paths to files. + +To create the package: + +1. Run "Desktop VS 2022 Gaming Command Prompt" from the Start Menu +2. `cd` to the directory containing the `PackageLayout.xml` with the correct paths (if you use the local path as in the sample package layout, this would be from your .exe output directory) +3. `mkdir Package` to create an output directory +4. To package the file into the `Package` directory, use: + `makepkg pack /f PackageLayout.xml /lt /d . /nogameos /pc /pd Package` +5. To install the package, use: + `wdapp install PACKAGENAME.msixvc` +6. Once the package is installed, you can run it from the start menu. +7. As with when running from Visual Studio, if you need to test any Xbox Live functionality you must switch to the correct sandbox. + +Xbox GDKX Setup +--------------------- +In general, the same process in the Windows GDK instructions work. There are just a few additional notes: +* For Xbox One consoles, use the Gaming.Xbox.XboxOne.x64 target +* For Xbox Series consoles, use the Gaming.Xbox.Scarlett.x64 target +* The Xbox One target sets the `__XBOXONE__` define and the Xbox Series target sets the `__XBOXSERIES__` define +* You don't need to link against the Xbox.Services Thunks lib nor include that dll in your package (it doesn't exist for Xbox) +* The shader blobs for Xbox are created in a pre-build step for the Xbox targets, rather than included in the source (due to NDA and version compatability reasons) +* To create a package, use: + `makepkg pack /f PackageLayout.xml /lt /d . /pd Package` +* To install the package, use: + `xbapp install [PACKAGE].xvc` +* For some reason, if you make changes that require SDL2.dll to build, and you are running through the debugger (instead of a package), you have to rebuild your .exe target for the debugger to recognize the dll has changed and needs to be transferred to the console again +* While there are successful releases of Xbox titles using this port, it is not as extensively tested as other targets + +Troubleshooting +--------------- + +#### Xbox Live Login does not work + +As of June 2022 GDK, you must have a valid Title Id and MSAAppId in order to test Xbox Live functionality such as user login. Make sure these are set correctly in the `MicrosoftGame.config`. This means that even testgdk will not let you login without setting these properties to valid values. + +Furthermore, confirm that your PC is set to the correct sandbox. + + +#### "The current user has already installed an unpackaged version of this app. A packaged version cannot replace this." error when installing + +Prior to June 2022 GDK, running from the Visual Studio debugger would still locally register the app (and it would appear on the start menu). To fix this, you have to uninstall it (it's simplest to right click on it from the start menu to uninstall it). diff --git a/SDL2-2.0.12/docs/README-gesture.md b/SDL2-2.30.5/docs/README-gesture.md similarity index 95% rename from SDL2-2.0.12/docs/README-gesture.md rename to SDL2-2.30.5/docs/README-gesture.md index 7e9f95b..69a66ad 100644 --- a/SDL2-2.0.12/docs/README-gesture.md +++ b/SDL2-2.30.5/docs/README-gesture.md @@ -2,7 +2,7 @@ Dollar Gestures =========================================================================== SDL provides an implementation of the $1 gesture recognition system. This allows for recording, saving, loading, and performing single stroke gestures. -Gestures can be performed with any number of fingers (the centroid of the fingers must follow the path of the gesture), but the number of fingers must be constant (a finger cannot go down in the middle of a gesture). The path of a gesture is considered the path from the time when the final finger went down, to the first time any finger comes up. +Gestures can be performed with any number of fingers (the centroid of the fingers must follow the path of the gesture), but the number of fingers must be constant (a finger cannot go down in the middle of a gesture). The path of a gesture is considered the path from the time when the final finger went down, to the first time any finger comes up. Dollar gestures are assigned an Id based on a hash function. This is guaranteed to remain constant for a given gesture. There is a (small) chance that two different gestures will be assigned the same ID. In this case, simply re-recording one of the gestures should result in a different ID. @@ -42,7 +42,7 @@ Both functions return the number of gestures successfully saved. Loading: -------- -To load templates from a file, call SDL_LoadDollarTemplates(touchId,src) where touchId is the id of the touch to load to (or -1 to load to all touch devices), and src is an SDL_RWops pointer to a gesture save file. +To load templates from a file, call SDL_LoadDollarTemplates(touchId,src) where touchId is the id of the touch to load to (or -1 to load to all touch devices), and src is an SDL_RWops pointer to a gesture save file. SDL_LoadDollarTemplates returns the number of templates successfully loaded. @@ -51,7 +51,7 @@ SDL_LoadDollarTemplates returns the number of templates successfully loaded. =========================================================================== Multi Gestures =========================================================================== -SDL provides simple support for pinch/rotate/swipe gestures. +SDL provides simple support for pinch/rotate/swipe gestures. Every time a finger is moved an SDL_MULTIGESTURE event is sent with the following fields: * event.mgesture.touchId - the Id of the touch on which the gesture was performed. diff --git a/SDL2-2.30.5/docs/README-git.md b/SDL2-2.30.5/docs/README-git.md new file mode 100644 index 0000000..fd12fd9 --- /dev/null +++ b/SDL2-2.30.5/docs/README-git.md @@ -0,0 +1,19 @@ +git +========= + +The latest development version of SDL is available via git. +Git allows you to get up-to-the-minute fixes and enhancements; +as a developer works on a source tree, you can use "git" to mirror that +source tree instead of waiting for an official release. Please look +at the Git website ( https://git-scm.com/ ) for more +information on using git, where you can also download software for +macOS, Windows, and Unix systems. + + git clone https://github.com/libsdl-org/SDL + +If you are building SDL via configure, you will need to run autogen.sh +before running configure. + +There is a web interface to the Git repository at: + http://github.com/libsdl-org/SDL/ + diff --git a/SDL2-2.30.5/docs/README-hg.md b/SDL2-2.30.5/docs/README-hg.md new file mode 100644 index 0000000..1b39017 --- /dev/null +++ b/SDL2-2.30.5/docs/README-hg.md @@ -0,0 +1,4 @@ +We are no longer hosted in Mercurial. Please see README-git.md for details. + +Thanks! + diff --git a/SDL2-2.0.12/docs/README-ios.md b/SDL2-2.30.5/docs/README-ios.md similarity index 68% rename from SDL2-2.0.12/docs/README-ios.md rename to SDL2-2.30.5/docs/README-ios.md index bf34fe4..94c24b5 100644 --- a/SDL2-2.0.12/docs/README-ios.md +++ b/SDL2-2.30.5/docs/README-ios.md @@ -1,65 +1,36 @@ iOS ====== -============================================================================== -Building the Simple DirectMedia Layer for iOS 5.1+ +Building the Simple DirectMedia Layer for iOS 9.0+ ============================================================================== -Requirements: Mac OS X 10.8 or later and the iOS 7+ SDK. +Requirements: Mac OS X 10.9 or later and the iOS 9.0 or newer SDK. Instructions: -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: - Build SDL as a statically linked library -- testsdl: - Build a test program (there are known test failures which are fine) -- Template: - Package a project template together with the SDL for iPhone static libraries and copies of the SDL headers. The template includes proper references to the SDL library and headers, skeleton code for a basic SDL program, and placeholder graphics for the application icon and startup screen. +1. Open SDL.xcodeproj (located in Xcode/SDL) in Xcode. +2. Select your desired target, and hit build. -============================================================================== -Build SDL for iOS from the command line -============================================================================== - -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". -"include" contains a copy of the SDL headers that you'll need for your project, -make sure to configure XCode to look for headers there. -"lib" contains find two files, libSDL2.a and libSDL2main.a, you have to add both -to your XCode project. These libraries contain three architectures in them, -armv6 for legacy devices, armv7, and i386 (for the simulator). -By default, iosbuild.sh will autodetect the SDK version you have installed using -xcodebuild -showsdks, and build for iOS >= 3.0, you can override this behaviour -by setting the MIN_OS_VERSION variable, ie: - -MIN_OS_VERSION=4.2 ./iosbuild.sh - -============================================================================== Using the Simple DirectMedia Layer for iOS ============================================================================== -FIXME: This needs to be updated for the latest methods +1. Run Xcode and create a new project using the iOS Game template, selecting the Objective C language and Metal game technology. +2. In the main view, delete all files except for Assets and LaunchScreen +3. Right click the project in the main view, select "Add Files...", and add the SDL project, Xcode/SDL/SDL.xcodeproj +4. Select the project in the main view, go to the "Info" tab and under "Custom iOS Target Properties" remove the line "Main storyboard file base name" +5. Select the project in the main view, go to the "Build Settings" tab, select "All", and edit "Header Search Path" and drag over the SDL "Public Headers" folder from the left +6. Select the project in the main view, go to the "Build Phases" tab, select "Link Binary With Libraries", and add SDL2.framework from "Framework-iOS" +7. Select the project in the main view, go to the "General" tab, scroll down to "Frameworks, Libraries, and Embedded Content", and select "Embed & Sign" for the SDL library. +8. In the main view, expand SDL -> Library Source -> main -> uikit and drag SDL_uikit_main.c into your game files +9. Add the source files that you would normally have for an SDL program, making sure to have #include "SDL.h" at the top of the file containing your main() function. +10. Add any assets that your application needs. +11. Enjoy! -Here is the easiest method: -1. Build the SDL library (libSDL2.a) and the iPhone SDL Application template. -2. Install the iPhone SDL Application template by copying it to one of Xcode's template directories. I recommend creating a directory called "SDL" in "/Developer/Platforms/iOS.platform/Developer/Library/Xcode/Project Templates/" and placing it there. -3. Start a new project using the template. The project should be immediately ready for use with SDL. -Here is a more manual method: -1. Create a new iOS view based application. -2. Build the SDL static library (libSDL2.a) for iOS and include them in your project. Xcode will ignore the library that is not currently of the correct architecture, hence your app will work both on iOS and in the iOS Simulator. -3. Include the SDL header files in your project. -4. Remove the ApplicationDelegate.h and ApplicationDelegate.m files -- SDL for iOS provides its own UIApplicationDelegate. Remove MainWindow.xib -- SDL for iOS produces its user interface programmatically. -5. Delete the contents of main.m and program your app as a regular SDL program instead. You may replace main.m with your own main.c, but you must tell Xcode not to use the project prefix file, as it includes Objective-C code. +TODO: Add information regarding App Store requirements such as icons, etc. + -============================================================================== Notes -- Retina / High-DPI and window sizes ============================================================================== @@ -88,7 +59,7 @@ orthographic projection matrix using the size in screen coordinates (SDL_GetWindowSize()) can be used in order to display content at the same scale no matter whether a Retina device is used or not. -============================================================================== + Notes -- Application events ============================================================================== @@ -140,18 +111,17 @@ e.g. return 1; } } - + int main(int argc, char *argv[]) { SDL_SetEventFilter(HandleAppEvents, NULL); - + ... run your main loop - + return 0; } - -============================================================================== + Notes -- Accelerometer as Joystick ============================================================================== @@ -159,7 +129,7 @@ SDL for iPhone supports polling the built in accelerometer as a joystick device. The main thing to note when using the accelerometer with SDL is that while the iPhone natively reports accelerometer as floating point values in units of g-force, SDL_JoystickGetAxis() reports joystick values as signed integers. Hence, in order to convert between the two, some clamping and scaling is necessary on the part of the iPhone SDL joystick driver. To convert SDL_JoystickGetAxis() reported values BACK to units of g-force, simply multiply the values by SDL_IPHONE_MAX_GFORCE / 0x7FFF. -============================================================================== + Notes -- OpenGL ES ============================================================================== @@ -179,7 +149,7 @@ OpenGL ES on iOS doesn't use the traditional system-framebuffer setup provided i The above objects can be obtained via SDL_GetWindowWMInfo() (in SDL_syswm.h). -============================================================================== + Notes -- Keyboard ============================================================================== @@ -195,7 +165,12 @@ SDL_bool SDL_IsTextInputActive() -- returns whether or not text events are enabled (and the onscreen keyboard is visible) +Notes -- Mouse ============================================================================== + +iOS now supports Bluetooth mice on iPad, but by default will provide the mouse input as touch. In order for SDL to see the real mouse events, you should set the key UIApplicationSupportsIndirectInputEvents to true in your Info.plist + + Notes -- Reading and Writing files ============================================================================== @@ -210,12 +185,44 @@ Once your application is installed its directory tree looks like: Preferences/ tmp/ -When your SDL based iPhone application starts up, it sets the working directory to the main bundle (MySDLApp Home/MySDLApp.app), where your application resources are stored. You cannot write to this directory. Instead, I advise you to write document files to "../Documents/" and preferences to "../Library/Preferences". +When your SDL based iPhone application starts up, it sets the working directory to the main bundle (MySDLApp Home/MySDLApp.app), where your application resources are stored. You cannot write to this directory. Instead, I advise you to write document files to "../Documents/" and preferences to "../Library/Preferences". More information on this subject is available here: http://developer.apple.com/library/ios/#documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/Introduction/Introduction.html + +Notes -- xcFramework ============================================================================== + +The SDL.xcodeproj file now includes a target to build SDL2.xcframework. An xcframework is a new (Xcode 11) uber-framework which can handle any combination of processor type and target OS platform. + +In the past, iOS devices were always an ARM variant processor, and the simulator was always i386 or x86_64, and thus libraries could be combined into a single framework for both simulator and device. With the introduction of the Apple Silicon ARM-based machines, regular frameworks would collide as CPU type was no longer sufficient to differentiate the platform. So Apple created the new xcframework library package. + +The xcframework target builds into a Products directory alongside the SDL.xcodeproj file, as SDL2.xcframework. This can be brought in to any iOS project and will function properly for both simulator and device, no matter their CPUs. Note that Intel Macs cannot cross-compile for Apple Silicon Macs. If you need AS compatibility, perform this build on an Apple Silicon Mac. + +This target requires Xcode 11 or later. The target will simply fail to build if attempted on older Xcodes. + +In addition, on Apple platforms, main() cannot be in a dynamically loaded library. This means that iOS apps which used the statically-linked libSDL2.lib and now link with the xcframwork will need to define their own main() to call SDL_UIKitRunApp(), like this: + +#ifndef SDL_MAIN_HANDLED +#ifdef main +#undef main +#endif + +int +main(int argc, char *argv[]) +{ + return SDL_UIKitRunApp(argc, argv, SDL_main); +} +#endif /* !SDL_MAIN_HANDLED */ + +Using an xcFramework is similar to using a regular framework. However, issues have been seen with the build system not seeing the headers in the xcFramework. To remedy this, add the path to the xcFramework in your app's target ==> Build Settings ==> Framework Search Paths and mark it recursive (this is critical). Also critical is to remove "*.framework" from Build Settings ==> Sub-Directories to Exclude in Recursive Searches. Clean the build folder, and on your next build the build system should be able to see any of these in your code, as expected: + +#include "SDL_main.h" +#include +#include + + Notes -- iPhone SDL limitations ============================================================================== @@ -228,8 +235,24 @@ Textures: Loading Shared Objects: This is disabled by default since it seems to break the terms of the iOS SDK agreement for iOS versions prior to iOS 8. It can be re-enabled in SDL_config_iphoneos.h. + +Notes -- CoreBluetooth.framework ============================================================================== -Game Center + +SDL_JOYSTICK_HIDAPI is disabled by default. It can give you access to a lot +more game controller devices, but it requires permission from the user before +your app will be able to talk to the Bluetooth hardware. "Made For iOS" +branded controllers do not need this as we don't have to speak to them +directly with raw bluetooth, so many apps can live without this. + +You'll need to link with CoreBluetooth.framework and add something like this +to your Info.plist: + +NSBluetoothPeripheralUsageDescription +MyApp would like to remain connected to nearby bluetooth Game Controllers and Game Pads even when you're not using the app. + + +Game Center ============================================================================== Game Center integration might require that you break up your main loop in order to yield control back to the system. In other words, instead of running an endless main loop, you run each frame in a callback function, using: @@ -245,15 +268,15 @@ e.g. { ... do event handling, frame logic and rendering ... } - + int main(int argc, char *argv[]) { ... initialize game ... - - #if __IPHONEOS__ + + #ifdef __IPHONEOS__ // Initialize the Game Center for scoring and matchmaking InitGameCenter(); - + // Set up the game to run in the window animation callback on iOS // so that Game Center and so forth works correctly. SDL_iPhoneSetAnimationCallback(window, 1, ShowFrame, NULL); @@ -266,11 +289,11 @@ e.g. return 0; } -============================================================================== + Deploying to older versions of iOS ============================================================================== -SDL supports deploying to older versions of iOS than are supported by the latest version of Xcode, all the way back to iOS 6.1 +SDL supports deploying to older versions of iOS than are supported by the latest version of Xcode, all the way back to iOS 8.0 In order to do that you need to download an older version of Xcode: https://developer.apple.com/download/more/?name=Xcode diff --git a/SDL2-2.30.5/docs/README-kmsbsd.md b/SDL2-2.30.5/docs/README-kmsbsd.md new file mode 100644 index 0000000..1aad380 --- /dev/null +++ b/SDL2-2.30.5/docs/README-kmsbsd.md @@ -0,0 +1,27 @@ +KMSDRM on *BSD +================================================== + +KMSDRM is supported on FreeBSD and OpenBSD. DragonFlyBSD works but requires being a root user. NetBSD isn't supported yet because the application will crash when creating the KMSDRM screen. + +WSCONS support has been brought back, but only as an input backend. It will not be brought back as a video backend to ease maintenance. + +OpenBSD note: Note that the video backend assumes that the user has read/write permissions to the /dev/drm* devices. + + +SDL2 WSCONS input backend features +=================================================== +1. It is keymap-aware; it will work properly with different keymaps. +2. It has mouse support. +3. Accent input is supported. +4. Compose keys are supported. +5. AltGr and Meta Shift keys work as intended. + +Partially working or no input on OpenBSD/NetBSD. +================================================== + +The WSCONS input backend needs read/write access to the /dev/wskbd* devices, without which it will not work properly. /dev/wsmouse must also be read/write accessible, otherwise mouse input will not work. + +Partially working or no input on FreeBSD. +================================================== + +The evdev devices are only accessible to the root user by default. Edit devfs rules to allow access to such devices. The /dev/kbd* devices are also only accessible to the root user by default. Edit devfs rules to allow access to such devices. diff --git a/SDL2-2.0.12/docs/README-linux.md b/SDL2-2.30.5/docs/README-linux.md similarity index 52% rename from SDL2-2.0.12/docs/README-linux.md rename to SDL2-2.30.5/docs/README-linux.md index 10f80b9..83339bc 100644 --- a/SDL2-2.0.12/docs/README-linux.md +++ b/SDL2-2.30.5/docs/README-linux.md @@ -3,85 +3,94 @@ Linux By default SDL will only link against glibc, the rest of the features will be enabled dynamically at runtime depending on the available features on the target -system. So, for example if you built SDL with Xinerama support and the target -system does not have the Xinerama libraries installed, it will be disabled -at runtime, and you won't get a missing library error, at least with the +system. So, for example if you built SDL with XRandR support and the target +system does not have the XRandR libraries installed, it will be disabled +at runtime, and you won't get a missing library error, at least with the default configuration parameters. -================================================================================ Build Dependencies -================================================================================ - -Ubuntu 13.04, all available features enabled: +-------------------------------------------------------------------------------- -sudo apt-get install build-essential mercurial make cmake autoconf automake \ -libtool libasound2-dev libpulse-dev libaudio-dev libx11-dev libxext-dev \ -libxrandr-dev libxcursor-dev libxi-dev libxinerama-dev libxxf86vm-dev \ -libxss-dev libgl1-mesa-dev libesd0-dev libdbus-1-dev libudev-dev \ -libgles1-mesa-dev libgles2-mesa-dev libegl1-mesa-dev libibus-1.0-dev \ -fcitx-libs-dev libsamplerate0-dev libsndio-dev +Ubuntu 18.04, all available features enabled: -Ubuntu 16.04+ can also add "libwayland-dev libxkbcommon-dev wayland-protocols" -to that command line for Wayland support. + sudo apt-get install build-essential git make autoconf automake libtool \ + pkg-config cmake ninja-build gnome-desktop-testing libasound2-dev libpulse-dev \ + libaudio-dev libjack-dev libsndio-dev libsamplerate0-dev libx11-dev libxext-dev \ + libxrandr-dev libxcursor-dev libxfixes-dev libxi-dev libxss-dev libwayland-dev \ + libxkbcommon-dev libdrm-dev libgbm-dev libgl1-mesa-dev libgles2-mesa-dev \ + libegl1-mesa-dev libdbus-1-dev libibus-1.0-dev libudev-dev fcitx-libs-dev + +Ubuntu 22.04+ can also add `libpipewire-0.3-dev libdecor-0-dev` to that command line. + +Fedora 35, all available features enabled: + + sudo yum install gcc git-core make cmake autoconf automake libtool \ + alsa-lib-devel pulseaudio-libs-devel nas-devel pipewire-devel \ + libX11-devel libXext-devel libXrandr-devel libXcursor-devel libXfixes-devel \ + libXi-devel libXScrnSaver-devel dbus-devel ibus-devel fcitx-devel \ + systemd-devel mesa-libGL-devel libxkbcommon-devel mesa-libGLES-devel \ + mesa-libEGL-devel vulkan-devel wayland-devel wayland-protocols-devel \ + libdrm-devel mesa-libgbm-devel libusb-devel libdecor-devel \ + libsamplerate-devel pipewire-jack-audio-connection-kit-devel \ NOTES: -- This includes all the audio targets except arts, because Ubuntu pulled the - artsc0-dev package, but in theory SDL still supports it. -- libsamplerate0-dev lets SDL optionally link to libresamplerate at runtime - for higher-quality audio resampling. SDL will work without it if the library - is missing, so it's safe to build in support even if the end user doesn't - have this library installed. +- This includes all the audio targets except arts and esd, because Ubuntu + (and/or Debian) pulled their packages, but in theory SDL still supports them. + The sndio audio target is also unavailable on Fedora. +- libsamplerate0-dev lets SDL optionally link to libresamplerate at runtime + for higher-quality audio resampling. SDL will work without it if the library + is missing, so it's safe to build in support even if the end user doesn't + have this library installed. - DirectFB isn't included because the configure script (currently) fails to find - it at all. You can do "sudo apt-get install libdirectfb-dev" and fix the + it at all. You can do "sudo apt-get install libdirectfb-dev" and fix the configure script to include DirectFB support. Send patches. :) -================================================================================ Joystick does not work -================================================================================ +-------------------------------------------------------------------------------- If you compiled or are using a version of SDL with udev support (and you should!) there's a few issues that may cause SDL to fail to detect your joystick. To debug this, start by installing the evtest utility. On Ubuntu/Debian: sudo apt-get install evtest - + Then run: - + sudo evtest - + You'll hopefully see your joystick listed along with a name like "/dev/input/eventXX" Now run: - + cat /dev/input/event/XX If you get a permission error, you need to set a udev rule to change the mode of -your device (see below) - +your device (see below) + Also, try: - + sudo udevadm info --query=all --name=input/eventXX - + If you see a line stating ID_INPUT_JOYSTICK=1, great, if you don't see it, you need to set up an udev rule to force this variable. -A combined rule for the Saitek Pro Flight Rudder Pedals to fix both issues looks +A combined rule for the Saitek Pro Flight Rudder Pedals to fix both issues looks like: - - SUBSYSTEM=="input", ATTRS{idProduct}=="0763", ATTRS{idVendor}=="06a3", MODE="0666", ENV{ID_INPUT_JOYSTICK}="1" - SUBSYSTEM=="input", ATTRS{idProduct}=="0764", ATTRS{idVendor}=="06a3", MODE="0666", ENV{ID_INPUT_JOYSTICK}="1" - + + SUBSYSTEM=="input", ATTRS{idProduct}=="0763", ATTRS{idVendor}=="06a3", MODE="0666", ENV{ID_INPUT_JOYSTICK}="1" + SUBSYSTEM=="input", ATTRS{idProduct}=="0764", ATTRS{idVendor}=="06a3", MODE="0666", ENV{ID_INPUT_JOYSTICK}="1" + You can set up similar rules for your device by changing the values listed in idProduct and idVendor. To obtain these values, try: - + sudo udevadm info -a --name=input/eventXX | grep idVendor sudo udevadm info -a --name=input/eventXX | grep idProduct - -If multiple values come up for each of these, the one you want is the first one of each. + +If multiple values come up for each of these, the one you want is the first one of each. On other systems which ship with an older udev (such as CentOS), you may need to set up a rule such as: - + SUBSYSTEM=="input", ENV{ID_CLASS}=="joystick", ENV{ID_INPUT_JOYSTICK}="1" diff --git a/SDL2-2.30.5/docs/README-macos.md b/SDL2-2.30.5/docs/README-macos.md new file mode 100644 index 0000000..634d456 --- /dev/null +++ b/SDL2-2.30.5/docs/README-macos.md @@ -0,0 +1,285 @@ +# Mac OS X (aka macOS). + +These instructions are for people using Apple's Mac OS X (pronounced +"ten"), which in newer versions is just referred to as "macOS". + +From the developer's point of view, macOS is a sort of hybrid Mac and +Unix system, and you have the option of using either traditional +command line tools or Apple's IDE Xcode. + +# Command Line Build + +To build SDL using the command line, use the standard configure and make +process: + +```bash +mkdir build +cd build +../configure +make +sudo make install +``` + +CMake is also known to work, although it continues to be a work in progress: + +```bash +mkdir build +cd build +cmake -DCMAKE_BUILD_TYPE=Release .. +make +sudo make install +``` + + +You can also build SDL as a Universal library (a single binary for both +64-bit Intel and ARM architectures), by using the build-scripts/clang-fat.sh +script. + +```bash +mkdir build +cd build +CC=$PWD/../build-scripts/clang-fat.sh ../configure +make +sudo make install +``` + +This script builds SDL with 10.9 ABI compatibility on 64-bit Intel and 11.0 +ABI compatibility on ARM64 architectures. For best compatibility you +should compile your application the same way. + +Please note that building SDL requires at least Xcode 6 and the 10.9 SDK. +PowerPC support for macOS has been officially dropped as of SDL 2.0.2. +32-bit Intel and macOS 10.8 runtime support has been officially dropped as +of SDL 2.24.0. + +To use the library once it's built, you essential have two possibilities: +use the traditional autoconf/automake/make method, or use Xcode. + + +# Caveats for using SDL with Mac OS X + +If you register your own NSApplicationDelegate (using [NSApp setDelegate:]), +SDL will not register its own. This means that SDL will not terminate using +SDL_Quit if it receives a termination request, it will terminate like a +normal app, and it will not send a SDL_DROPFILE when you request to open a +file with the app. To solve these issues, put the following code in your +NSApplicationDelegate implementation: + + +```objc +- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender +{ + if (SDL_GetEventState(SDL_QUIT) == SDL_ENABLE) { + SDL_Event event; + event.type = SDL_QUIT; + SDL_PushEvent(&event); + } + + return NSTerminateCancel; +} + +- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename +{ + if (SDL_GetEventState(SDL_DROPFILE) == SDL_ENABLE) { + SDL_Event event; + event.type = SDL_DROPFILE; + event.drop.file = SDL_strdup([filename UTF8String]); + return (SDL_PushEvent(&event) > 0); + } + + return NO; +} +``` + +# Using the Simple DirectMedia Layer with a traditional Makefile + +An existing autoconf/automake build system for your SDL app has good chances +to work almost unchanged on macOS. However, to produce a "real" Mac binary +that you can distribute to users, you need to put the generated binary into a +so called "bundle", which is basically a fancy folder with a name like +"MyCoolGame.app". + +To get this build automatically, add something like the following rule to +your Makefile.am: + +```make +bundle_contents = APP_NAME.app/Contents +APP_NAME_bundle: EXE_NAME + mkdir -p $(bundle_contents)/MacOS + mkdir -p $(bundle_contents)/Resources + echo "APPL????" > $(bundle_contents)/PkgInfo + $(INSTALL_PROGRAM) $< $(bundle_contents)/MacOS/ +``` + +You should replace `EXE_NAME` with the name of the executable. `APP_NAME` is +what will be visible to the user in the Finder. Usually it will be the same +as `EXE_NAME` but capitalized. E.g. if `EXE_NAME` is "testgame" then `APP_NAME` +usually is "TestGame". You might also want to use `@PACKAGE@` to use the +package name as specified in your configure.ac file. + +If your project builds more than one application, you will have to do a bit +more. For each of your target applications, you need a separate rule. + +If you want the created bundles to be installed, you may want to add this +rule to your Makefile.am: + +```make +install-exec-hook: APP_NAME_bundle + rm -rf $(DESTDIR)$(prefix)/Applications/APP_NAME.app + mkdir -p $(DESTDIR)$(prefix)/Applications/ + cp -r $< /$(DESTDIR)$(prefix)Applications/ +``` + +This rule takes the Bundle created by the rule from step 3 and installs them +into "$(DESTDIR)$(prefix)/Applications/". + +Again, if you want to install multiple applications, you will have to augment +the make rule accordingly. + +But beware! That is only part of the story! With the above, you end up with +a barebones .app bundle, which is double-clickable from the Finder. But +there are some more things you should do before shipping your product... + +1. The bundle right now probably is dynamically linked against SDL. That + means that when you copy it to another computer, *it will not run*, + unless you also install SDL on that other computer. A good solution + for this dilemma is to static link against SDL. On OS X, you can + achieve that by linking against the libraries listed by + + ```bash + sdl-config --static-libs + ``` + + instead of those listed by + + ```bash + sdl-config --libs + ``` + + Depending on how exactly SDL is integrated into your build systems, the + way to achieve that varies, so I won't describe it here in detail + +2. Add an 'Info.plist' to your application. That is a special XML file which + contains some meta-information about your application (like some copyright + information, the version of your app, the name of an optional icon file, + and other things). Part of that information is displayed by the Finder + when you click on the .app, or if you look at the "Get Info" window. + More information about Info.plist files can be found on Apple's homepage. + + +As a final remark, let me add that I use some of the techniques (and some +variations of them) in [Exult](https://github.com/exult/exult) and +[ScummVM](https://github.com/scummvm/scummvm); both are available in source on +the net, so feel free to take a peek at them for inspiration! + + +# Using the Simple DirectMedia Layer with Xcode + +These instructions are for using Apple's Xcode IDE to build SDL applications. + +## First steps + +The first thing to do is to unpack the Xcode.tar.gz archive in the +top level SDL directory (where the Xcode.tar.gz archive resides). +Because Stuffit Expander will unpack the archive into a subdirectory, +you should unpack the archive manually from the command line: + +```bash +cd [path_to_SDL_source] +tar zxf Xcode.tar.gz +``` + +This will create a new folder called Xcode, which you can browse +normally from the Finder. + +## Building the Framework + +The SDL Library is packaged as a framework bundle, an organized +relocatable folder hierarchy of executable code, interface headers, +and additional resources. For practical purposes, you can think of a +framework as a more user and system-friendly shared library, whose library +file behaves more or less like a standard UNIX shared library. + +To build the framework, simply open the framework project and build it. +By default, the framework bundle "SDL.framework" is installed in +/Library/Frameworks. Therefore, the testers and project stationary expect +it to be located there. However, it will function the same in any of the +following locations: + +* ~/Library/Frameworks +* /Local/Library/Frameworks +* /System/Library/Frameworks + +## Build Options + +There are two "Build Styles" (See the "Targets" tab) for SDL. +"Deployment" should be used if you aren't tweaking the SDL library. +"Development" should be used to debug SDL apps or the library itself. + +## Building the Testers + +Open the SDLTest project and build away! + +## Using the Project Stationary + +Copy the stationary to the indicated folders to access it from +the "New Project" and "Add target" menus. What could be easier? + +## Setting up a new project by hand + +Some of you won't want to use the Stationary so I'll give some tips: + +(this is accurate as of Xcode 12.5.) + +* Click "File" -> "New" -> "Project... +* Choose "macOS" and then "App" from the "Application" section. +* Fill out the options in the next window. User interface is "XIB" and + Language is "Objective-C". +* Remove "main.m" from your project +* Remove "MainMenu.xib" from your project +* Remove "AppDelegates.*" from your project +* Add "\$(HOME)/Library/Frameworks/SDL.framework/Headers" to include path +* Add "\$(HOME)/Library/Frameworks" to the frameworks search path +* Add "-framework SDL -framework Foundation -framework AppKit" to "OTHER_LDFLAGS" +* Add your files +* Clean and build + +## Building from command line + +Use `xcode-build` in the same directory as your .pbxproj file + +## Running your app + +You can send command line args to your app by either invoking it from +the command line (in *.app/Contents/MacOS) or by entering them in the +Executables" panel of the target settings. + +# Implementation Notes + +Some things that may be of interest about how it all works... + +## Working directory + +In SDL 1.2, the working directory of your SDL app is by default set to its +parent, but this is no longer the case in SDL 2.0. SDL2 does change the +working directory, which means it'll be whatever the command line prompt +that launched the program was using, or if launched by double-clicking in +the finger, it will be "/", the _root of the filesystem_. Plan accordingly! +You can use SDL_GetBasePath() to find where the program is running from and +chdir() there directly. + + +## You have a Cocoa App! + +Your SDL app is essentially a Cocoa application. When your app +starts up and the libraries finish loading, a Cocoa procedure is called, +which sets up the working directory and calls your main() method. +You are free to modify your Cocoa app with generally no consequence +to SDL. You cannot, however, easily change the SDL window itself. +Functionality may be added in the future to help this. + +# Bug reports + +Bugs are tracked at [the GitHub issue tracker](https://github.com/libsdl-org/SDL/issues/). +Please feel free to report bugs there! + diff --git a/SDL2-2.30.5/docs/README-n3ds.md b/SDL2-2.30.5/docs/README-n3ds.md new file mode 100644 index 0000000..e9e7c7d --- /dev/null +++ b/SDL2-2.30.5/docs/README-n3ds.md @@ -0,0 +1,28 @@ +# Nintendo 3DS + +SDL port for the Nintendo 3DS [Homebrew toolchain](https://devkitpro.org/) contributed by: + +- [Pierre Wendling](https://github.com/FtZPetruska) + +Credits to: + +- The awesome people who ported SDL to other homebrew platforms. +- The Devkitpro team for making all the tools necessary to achieve this. + +## Building + +To build for the Nintendo 3DS, make sure you have devkitARM and cmake installed and run: + +```bash +cmake -S. -Bbuild -DCMAKE_TOOLCHAIN_FILE="$DEVKITPRO/cmake/3DS.cmake" -DCMAKE_BUILD_TYPE=Release +cmake --build build +cmake --install build +``` + +## Notes + +- Currently only software rendering is supported. +- SDL2main should be used to ensure ROMFS is enabled. +- By default, the extra L2 cache and higher clock speeds of the New 2/3DS lineup are enabled. If you wish to turn it off, use `osSetSpeedupEnable(false)` in your main function. +- `SDL_GetBasePath` returns the romfs root instead of the executable's directory. +- The Nintendo 3DS uses a cooperative threading model on a single core, meaning a thread will never yield unless done manually through the `SDL_Delay` functions, or blocking waits (`SDL_LockMutex`, `SDL_SemWait`, `SDL_CondWait`, `SDL_WaitThread`). To avoid starving other threads, `SDL_SemTryWait` and `SDL_SemWaitTimeout` will yield if they fail to acquire the semaphore, see https://github.com/libsdl-org/SDL/pull/6776 for more information. diff --git a/SDL2-2.0.12/docs/README-nacl.md b/SDL2-2.30.5/docs/README-nacl.md similarity index 89% rename from SDL2-2.0.12/docs/README-nacl.md rename to SDL2-2.30.5/docs/README-nacl.md index 53ada33..5b05f39 100644 --- a/SDL2-2.0.12/docs/README-nacl.md +++ b/SDL2-2.30.5/docs/README-nacl.md @@ -1,13 +1,13 @@ Native Client ================================================================================ -Requirements: +Requirements: -* Native Client SDK (https://developer.chrome.com/native-client), +* Native Client SDK (https://developer.chrome.com/native-client), (tested with Pepper version 33 or higher). The SDL backend for Chrome's Native Client has been tested only with the PNaCl -toolchain, which generates binaries designed to run on ARM and x86_32/64 +toolchain, which generates binaries designed to run on ARM and x86_32/64 platforms. This does not mean it won't work with the other toolchains! ================================================================================ @@ -17,15 +17,15 @@ Building SDL for NaCl Set up the right environment variables (see naclbuild.sh), then configure SDL with: configure --host=pnacl --prefix some/install/destination - -Then "make". -As an example of how to create a deployable app a Makefile project is provided -in test/nacl/Makefile, which includes some monkey patching of the common.mk file -provided by NaCl, without which linking properly to SDL won't work (the search -path can't be modified externally, so the linker won't find SDL's binaries unless +Then "make". + +As an example of how to create a deployable app a Makefile project is provided +in test/nacl/Makefile, which includes some monkey patching of the common.mk file +provided by NaCl, without which linking properly to SDL won't work (the search +path can't be modified externally, so the linker won't find SDL's binaries unless you dump them into the SDK path, which is inconvenient). -Also provided in test/nacl is the required support file, such as index.html, +Also provided in test/nacl is the required support file, such as index.html, manifest.json, etc. SDL apps for NaCl run on a worker thread using the ppapi_simple infrastructure. This allows for blocking calls on all the relevant systems (OpenGL ES, filesystem), @@ -38,20 +38,20 @@ Running tests ================================================================================ Due to the nature of NaCl programs, building and running SDL tests is not as -straightforward as one would hope. The script naclbuild.sh in build-scripts -automates the process and should serve as a guide for users of SDL trying to build +straightforward as one would hope. The script naclbuild.sh in build-scripts +automates the process and should serve as a guide for users of SDL trying to build their own applications. Basic usage: - + ./naclbuild.sh path/to/pepper/toolchain (i.e. ~/naclsdk/pepper_35) - + This will build testgles2.c by default. If you want to build a different test, for example testrendercopyex.c: - + SOURCES=~/sdl/SDL/test/testrendercopyex.c ./naclbuild.sh ~/naclsdk/pepper_35 - + Once the build finishes, you have to serve the contents with a web server (the script will give you instructions on how to do that with Python). @@ -60,28 +60,28 @@ RWops and nacl_io ================================================================================ SDL_RWops work transparently with nacl_io. Two functions control the mount points: - - int mount(const char* source, const char* target, - const char* filesystemtype, + + int mount(const char* source, const char* target, + const char* filesystemtype, unsigned long mountflags, const void *data); int umount(const char *target); - - For convenience, SDL will by default mount an httpfs tree at / before calling + + For convenience, SDL will by default mount an httpfs tree at / before calling the app's main function. Such setting can be overridden by calling: - + umount("/"); And then mounting a different filesystem at / It's important to consider that the asynchronous nature of file operations on a browser is hidden from the application, effectively providing the developer with -a set of blocking file operations just like you get in a regular desktop -environment, which eases the job of porting to Native Client, but also introduces -a set of challenges of its own, in particular when big file sizes and slow +a set of blocking file operations just like you get in a regular desktop +environment, which eases the job of porting to Native Client, but also introduces +a set of challenges of its own, in particular when big file sizes and slow connections are involved. For more information on how nacl_io and mount points work, see: - + https://developer.chrome.com/native-client/devguide/coding/nacl_io https://src.chromium.org/chrome/trunk/src/native_client_sdk/src/libraries/nacl_io/nacl_io.h diff --git a/SDL2-2.30.5/docs/README-ngage.md b/SDL2-2.30.5/docs/README-ngage.md new file mode 100644 index 0000000..e480965 --- /dev/null +++ b/SDL2-2.30.5/docs/README-ngage.md @@ -0,0 +1,44 @@ +Nokia N-Gage +============ + +SDL2 port for Symbian S60v1 and v2 with a main focus on the Nokia N-Gage +(Classic and QD) by [Michael Fitzmayer](https://github.com/mupfdev). + +Compiling +--------- + +SDL is part of the [N-Gage SDK.](https://github.com/ngagesdk) project. +The library is included in the +[toolchain](https://github.com/ngagesdk/ngage-toolchain) as a +sub-module. + +A complete example project based on SDL2 can be found in the GitHub +account of the SDK: [Wordle](https://github.com/ngagesdk/wordle). + +Current level of implementation +------------------------------- + +The video driver currently provides full screen video support with +keyboard input. + +At the moment only the software renderer works. + +Audio is not yet implemented. + +Acknowledgements +---------------- + +Thanks to Hannu Viitala, Kimmo Kinnunen and Markus Mertama for the +valuable insight into Symbian programming. Without the SDL 1.2 port +which was specially developed for CDoom (Doom for the Nokia 9210), this +adaptation would not have been possible. + +I would like to thank my friends +[Razvan](https://twitter.com/bewarerazvan) and [Dan +Whelan](https://danwhelan.ie/), for their continuous support. Without +you and the [N-Gage community](https://discord.gg/dbUzqJ26vs), I would +have lost my patience long ago. + +Last but not least, I would like to thank the development team of +[EKA2L1](https://12z1.com/) (an experimental Symbian OS emulator). Your +patience and support in troubleshooting helped me a lot. diff --git a/SDL2-2.30.5/docs/README-os2.md b/SDL2-2.30.5/docs/README-os2.md new file mode 100644 index 0000000..6870ee3 --- /dev/null +++ b/SDL2-2.30.5/docs/README-os2.md @@ -0,0 +1,92 @@ +Simple DirectMedia Layer 2 for OS/2 & eComStation +================================================================================ +SDL port for OS/2, authored by Andrey Vasilkin , 2016 + + +OpenGL not supported by this port. + +Additional optional environment variables: + +SDL_AUDIO_SHARE + Values: 0 or 1, default is 0 + Initializes the device as shareable or exclusively acquired. + +SDL_VIDEODRIVER + Values: DIVE or VMAN, default is DIVE + Use video subsystem: Direct interface video extensions (DIVE) or + Video Manager (VMAN). + +You may significantly increase video output speed with OS4 kernel and patched +files vman.dll and dive.dll or with latest versions of ACPI support and video +driver Panorama. + +Latest versions of OS/4 kernel: + http://gus.biysk.ru/os4/ + (Info: https://www.os2world.com/wiki/index.php/Phoenix_OS/4) + +Patched files vman.dll and dive.dll: + http://gus.biysk.ru/os4/test/pached_dll/PATCHED_DLL.RAR + + +Compiling: +---------- + +Open Watcom 1.9 or newer is tested. For the new Open Watcom V2 fork, see: +https://github.com/open-watcom/ and https://open-watcom.github.io +WATCOM environment variable must to be set to the Open Watcom install +directory. To compile, run: wmake -f Makefile.os2 + + +Installing: +----------- + +- eComStation: + + If you have previously installed SDL2, make a Backup copy of SDL2.dll + located in D:\ecs\dll (where D: is disk on which installed eComStation). + Stop all programs running with SDL2. Copy SDL2.dll to D:\ecs\dll + +- OS/2: + + Copy SDL2.dll to any directory on your LIBPATH. If you have a previous + version installed, close all SDL2 applications before replacing the old + copy. Also make sure that any other older versions of DLLs are removed + from your system. + + +Joysticks in SDL2: +------------------ + +The joystick code in SDL2 is a direct forward-port from the SDL-1.2 version. +Here is the original documentation from SDL-1.2: + +The Joystick detection only works for standard joysticks (2 buttons, 2 axes +and the like). Therefore, if you use a non-standard joystick, you should +specify its features in the SDL_OS2_JOYSTICK environment variable in a batch +file or CONFIG.SYS, so SDL applications can provide full capability to your +device. The syntax is: + +SET SDL_OS2_JOYSTICK=[JOYSTICK_NAME] [AXES] [BUTTONS] [HATS] [BALLS] + +So, it you have a Gravis GamePad with 4 axes, 2 buttons, 2 hats and 0 balls, +the line should be: + +SET SDL_OS2_JOYSTICK=Gravis_GamePad 4 2 2 0 + +If you want to add spaces in your joystick name, just surround it with +quotes or double-quotes: + +SET SDL_OS2_JOYSTICK='Gravis GamePad' 4 2 2 0 + +or + +SET SDL_OS2_JOYSTICK="Gravis GamePad" 4 2 2 0 + + Note however that Balls and Hats are not supported under OS/2, and the +value will be ignored... but it is wise to define these correctly because +in the future those can be supported. + + Also the number of buttons is limited to 2 when using two joysticks, +4 when using one joystick with 4 axes, 6 when using a joystick with 3 axes +and 8 when using a joystick with 2 axes. Notice however these are limitations +of the Joystick Port hardware, not OS/2. diff --git a/SDL2-2.0.12/docs/README-pandora.md b/SDL2-2.30.5/docs/README-pandora.md similarity index 96% rename from SDL2-2.0.12/docs/README-pandora.md rename to SDL2-2.30.5/docs/README-pandora.md index a027763..68ea774 100644 --- a/SDL2-2.0.12/docs/README-pandora.md +++ b/SDL2-2.30.5/docs/README-pandora.md @@ -1,4 +1,4 @@ -Pandora +Pandora ===================================================================== ( http://openpandora.org/ ) diff --git a/SDL2-2.0.12/docs/README-platforms.md b/SDL2-2.30.5/docs/README-platforms.md similarity index 100% rename from SDL2-2.0.12/docs/README-platforms.md rename to SDL2-2.30.5/docs/README-platforms.md diff --git a/SDL2-2.0.12/docs/README-porting.md b/SDL2-2.30.5/docs/README-porting.md similarity index 100% rename from SDL2-2.0.12/docs/README-porting.md rename to SDL2-2.30.5/docs/README-porting.md diff --git a/SDL2-2.30.5/docs/README-ps2.md b/SDL2-2.30.5/docs/README-ps2.md new file mode 100644 index 0000000..f422da9 --- /dev/null +++ b/SDL2-2.30.5/docs/README-ps2.md @@ -0,0 +1,51 @@ +PS2 +====== +SDL2 port for the Sony Playstation 2 contributed by: +- Francisco Javier Trujillo Mata + + +Credit to + - The guys that ported SDL to PSP & Vita because I'm taking them as reference. + - David G. F. for helping me with several issues and tests. + +## Building +To build SDL2 library for the PS2, make sure you have the latest PS2Dev status and run: +```bash +cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=$PS2DEV/ps2sdk/ps2dev.cmake +cmake --build build +cmake --install build +``` + +## Hints +The PS2 port has a special Hint for having a dynamic VSYNC. The Hint is `SDL_HINT_PS2_DYNAMIC_VSYNC`. +If you enabled the dynamic vsync having as well `SDL_RENDERER_PRESENTVSYNC` enabled, then if the app is not able to run at 60 FPS, automatically the `vsync` will be disabled having a better performance, instead of droping FPS to 30. + +## Notes +If you trying to debug a SDL app through [ps2client](https://github.com/ps2dev/ps2client) you need to avoid the IOP reset, otherwise you will lose the conection with your computer. +So to avoid the reset of the IOP CPU, you need to call to the macro `SDL_PS2_SKIP_IOP_RESET();`. +It could be something similar as: +```c +..... + +SDL_PS2_SKIP_IOP_RESET(); + +int main(int argc, char *argv[]) +{ +..... +``` +For a release binary is recommendable to reset the IOP always. + +Remember to do a clean compilation everytime you enable or disable the `SDL_PS2_SKIP_IOP_RESET` otherwise the change won't be reflected. + +## Getting PS2 Dev +[Installing PS2 Dev](https://github.com/ps2dev/ps2dev) + +## Running on PCSX2 Emulator +[PCSX2](https://github.com/PCSX2/pcsx2) + +[More PCSX2 information](https://pcsx2.net/) + +## To Do +- PS2 Screen Keyboard +- Dialogs +- Others diff --git a/SDL2-2.30.5/docs/README-psp.md b/SDL2-2.30.5/docs/README-psp.md new file mode 100644 index 0000000..96ecd76 --- /dev/null +++ b/SDL2-2.30.5/docs/README-psp.md @@ -0,0 +1,36 @@ +PSP +====== +SDL2 port for the Sony PSP contributed by: +- Captian Lex +- Francisco Javier Trujillo Mata +- Wouter Wijsman + + +Credit to + Marcus R.Brown,Jim Paris,Matthew H for the original SDL 1.2 for PSP + Geecko for his PSP GU lib "Glib2d" + +## Building +To build SDL2 library for the PSP, make sure you have the latest PSPDev status and run: +```bash +cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=$PSPDEV/psp/share/pspdev.cmake +cmake --build build +cmake --install build +``` + + +## Getting PSP Dev +[Installing PSP Dev](https://github.com/pspdev/pspdev) + +## Running on PPSSPP Emulator +[PPSSPP](https://github.com/hrydgard/ppsspp) + +[Build Instructions](https://github.com/hrydgard/ppsspp/wiki/Build-instructions) + + +## Compiling a HelloWorld +[PSP Hello World](https://psp-dev.org/doku.php?id=tutorial:hello_world) + +## To Do +- PSP Screen Keyboard +- Dialogs diff --git a/SDL2-2.0.12/docs/README-raspberrypi.md b/SDL2-2.30.5/docs/README-raspberrypi.md similarity index 70% rename from SDL2-2.0.12/docs/README-raspberrypi.md rename to SDL2-2.30.5/docs/README-raspberrypi.md index 5e23ad5..7f9bfb1 100644 --- a/SDL2-2.0.12/docs/README-raspberrypi.md +++ b/SDL2-2.30.5/docs/README-raspberrypi.md @@ -1,13 +1,12 @@ Raspberry Pi -================================================================================ +============ Requirements: Raspbian (other Linux distros may work as well). -================================================================================ - Features -================================================================================ +Features +-------- * Works without X11 * Hardware accelerated OpenGL ES 2.x @@ -16,30 +15,28 @@ Raspbian (other Linux distros may work as well). * Hotplugging of input devices via UDEV -================================================================================ - Raspbian Build Dependencies -================================================================================ +Raspbian Build Dependencies +--------------------------- sudo apt-get install libudev-dev libasound2-dev libdbus-1-dev -You also need the VideoCore binary stuff that ships in /opt/vc for EGL and +You also need the VideoCore binary stuff that ships in /opt/vc for EGL and OpenGL ES 2.x, it usually comes pre-installed, but in any case: - + sudo apt-get install libraspberrypi0 libraspberrypi-bin libraspberrypi-dev -================================================================================ - NEON -================================================================================ +NEON +---- If your Pi has NEON support, make sure you add -mfpu=neon to your CFLAGS so that SDL will select some otherwise-disabled highly-optimized code. The original Pi units don't have NEON, the Pi2 probably does, and the Pi3 definitely does. -================================================================================ - Cross compiling from x86 Linux -================================================================================ + +Cross compiling from x86 Linux +------------------------------ To cross compile SDL for Raspbian from your desktop machine, you'll need a Raspbian system root and the cross compilation tools. We'll assume these tools @@ -48,7 +45,7 @@ will be placed in /opt/rpi-tools sudo git clone --depth 1 https://github.com/raspberrypi/tools /opt/rpi-tools You'll also need a Raspbian binary image. -Get it from: http://downloads.raspberrypi.org/raspbian_latest +Get it from: http://downloads.raspberrypi.org/raspbian_latest After unzipping, you'll get file with a name like: "-wheezy-raspbian.img" Let's assume the sysroot will be built in /opt/rpi-sysroot. @@ -66,14 +63,14 @@ Now, before chrooting into the ARM sysroot, you'll need to apply a workaround, edit $SYSROOT/etc/ld.so.preload and comment out all lines in it. sudo chroot $SYSROOT - apt-get install libudev-dev libasound2-dev libdbus-1-dev libraspberrypi0 libraspberrypi-bin libraspberrypi-dev libx11-dev libxext-dev libxrandr-dev libxcursor-dev libxi-dev libxinerama-dev libxxf86vm-dev libxss-dev + apt-get install libudev-dev libasound2-dev libdbus-1-dev libraspberrypi0 libraspberrypi-bin libraspberrypi-dev libx11-dev libxext-dev libxrandr-dev libxcursor-dev libxi-dev libxss-dev exit sudo umount $SYSROOT/dev sudo umount $SYSROOT/proc sudo umount $SYSROOT/sys sudo umount /mnt - -There's one more fix required, as the libdl.so symlink uses an absolute path + +There's one more fix required, as the libdl.so symlink uses an absolute path which doesn't quite work in our setup. sudo rm -rf $SYSROOT/usr/lib/arm-linux-gnueabihf/libdl.so @@ -89,14 +86,13 @@ The final step is compiling SDL itself. make install To be able to deploy this to /usr/local in the Raspbian system you need to fix up a few paths: - - perl -w -pi -e "s#$PWD/rpi-sdl2-installed#/usr/local#g;" ./rpi-sdl2-installed/lib/libSDL2.la ./rpi-sdl2-installed/lib/pkgconfig/sdl2.pc ./rpi-sdl2-installed/bin/sdl2-config - -================================================================================ - Apps don't work or poor video/audio performance -================================================================================ -If you get sound problems, buffer underruns, etc, run "sudo rpi-update" to + perl -w -pi -e "s#$PWD/rpi-sdl2-installed#/usr/local#g;" ./rpi-sdl2-installed/lib/libSDL2.la ./rpi-sdl2-installed/lib/pkgconfig/sdl2.pc ./rpi-sdl2-installed/bin/sdl2-config + +Apps don't work or poor video/audio performance +----------------------------------------------- + +If you get sound problems, buffer underruns, etc, run "sudo rpi-update" to update the RPi's firmware. Note that doing so will fix these problems, but it will also render the CMA - Dynamic Memory Split functionality useless. @@ -105,38 +101,35 @@ low in general, specially if a 1080p TV is hooked up. See here how to configure this setting: http://elinux.org/RPiconfig -Using a fixed gpu_mem=128 is the best option (specially if you updated the +Using a fixed gpu_mem=128 is the best option (specially if you updated the firmware, using CMA probably won't work, at least it's the current case). -================================================================================ - No input -================================================================================ +No input +-------- Make sure you belong to the "input" group. sudo usermod -aG input `whoami` -================================================================================ - No HDMI Audio -================================================================================ +No HDMI Audio +------------- If you notice that ALSA works but there's no audio over HDMI, try adding: - + hdmi_drive=2 - + to your config.txt file and reboot. Reference: http://www.raspberrypi.org/phpBB3/viewtopic.php?t=5062 -================================================================================ - Text Input API support -================================================================================ +Text Input API support +---------------------- The Text Input API is supported, with translation of scan codes done via the kernel symbol tables. For this to work, SDL needs access to a valid console. If you notice there's no SDL_TEXTINPUT message being emitted, double check that your app has read access to one of the following: - + * /proc/self/fd/0 * /dev/tty * /dev/tty[0...6] @@ -144,29 +137,29 @@ your app has read access to one of the following: * /dev/console This is usually not a problem if you run from the physical terminal (as opposed -to running from a pseudo terminal, such as via SSH). If running from a PTS, a +to running from a pseudo terminal, such as via SSH). If running from a PTS, a quick workaround is to run your app as root or add yourself to the tty group, then re-login to the system. sudo usermod -aG tty `whoami` - + The keyboard layout used by SDL is the same as the one the kernel uses. To configure the layout on Raspbian: - + sudo dpkg-reconfigure keyboard-configuration - + To configure the locale, which controls which keys are interpreted as letters, this determining the CAPS LOCK behavior: sudo dpkg-reconfigure locales -================================================================================ - OpenGL problems -================================================================================ -If you have desktop OpenGL headers installed at build time in your RPi or cross -compilation environment, support for it will be built in. However, the chipset -does not actually have support for it, which causes issues in certain SDL apps +OpenGL problems +--------------- + +If you have desktop OpenGL headers installed at build time in your RPi or cross +compilation environment, support for it will be built in. However, the chipset +does not actually have support for it, which causes issues in certain SDL apps since the presence of OpenGL support supersedes the ES/ES2 variants. The workaround is to disable OpenGL at configuration time: @@ -177,12 +170,11 @@ environment variable: export SDL_RENDER_DRIVER=opengles2 -================================================================================ - Notes -================================================================================ +Notes +----- * When launching apps remotely (via SSH), SDL can prevent local keystrokes from leaking into the console only if it has root privileges. Launching apps locally does not suffer from this issue. - + diff --git a/SDL2-2.30.5/docs/README-riscos.md b/SDL2-2.30.5/docs/README-riscos.md new file mode 100644 index 0000000..e4e056b --- /dev/null +++ b/SDL2-2.30.5/docs/README-riscos.md @@ -0,0 +1,41 @@ +RISC OS +======= + +Requirements: + +* RISC OS 3.5 or later. +* [SharedUnixLibrary](http://www.riscos.info/packages/LibraryDetails.html#SharedUnixLibraryarm). +* [DigitalRenderer](http://www.riscos.info/packages/LibraryDetails.html#DRendererarm), for audio support. +* [Iconv](http://www.netsurf-browser.org/projects/iconv/), for `SDL_iconv` and related functions. + + +Compiling: +---------- + +Currently, SDL2 for RISC OS only supports compiling with GCCSDK under Linux. Both the autoconf and CMake build systems are supported. + +The following commands can be used to build SDL2 for RISC OS using autoconf: + + ./configure --host=arm-unknown-riscos --prefix=$GCCSDK_INSTALL_ENV --disable-gcc-atomics + make + make install + +The following commands can be used to build SDL2 for RISC OS using CMake: + + cmake -Bbuild-riscos -DCMAKE_TOOLCHAIN_FILE=$GCCSDK_INSTALL_ENV/toolchain-riscos.cmake -DRISCOS=ON -DCMAKE_INSTALL_PREFIX=$GCCSDK_INSTALL_ENV -DCMAKE_BUILD_TYPE=Release -DSDL_GCC_ATOMICS=OFF + cmake --build build-riscos + cmake --build build-riscos --target install + + +Current level of implementation +------------------------------- + +The video driver currently provides full screen video support with keyboard and mouse input. Windowed mode is not yet supported, but is planned in the future. Only software rendering is supported. + +The filesystem APIs return either Unix-style paths or RISC OS-style paths based on the value of the `__riscosify_control` symbol, as is standard for UnixLib functions. + +The audio, loadso, thread and timer APIs are currently provided by UnixLib. + +GCC atomics are currently broken on some platforms, meaning it's currently necessary to compile with `--disable-gcc-atomics` using autotools or `-DSDL_GCC_ATOMICS=OFF` using CMake. + +The joystick, locale and power APIs are not yet implemented. diff --git a/SDL2-2.0.12/docs/README-touch.md b/SDL2-2.30.5/docs/README-touch.md similarity index 97% rename from SDL2-2.0.12/docs/README-touch.md rename to SDL2-2.30.5/docs/README-touch.md index 09188b8..66c1b2b 100644 --- a/SDL2-2.0.12/docs/README-touch.md +++ b/SDL2-2.30.5/docs/README-touch.md @@ -8,7 +8,7 @@ The linux touch system is currently based off event streams, and proc/bus/device Mac: The Mac and iPhone APIs are pretty. If your touch device supports them then you'll be fine. If it doesn't, then there isn't much we can do. -iPhone: +iPhone: Works out of box. Windows: diff --git a/SDL2-2.30.5/docs/README-versions.md b/SDL2-2.30.5/docs/README-versions.md new file mode 100644 index 0000000..d54bf40 --- /dev/null +++ b/SDL2-2.30.5/docs/README-versions.md @@ -0,0 +1,60 @@ +# Versioning + +## Since 2.23.0 + +SDL follows an "odd/even" versioning policy, similar to GLib, GTK, Flatpak +and older versions of the Linux kernel: + +* The major version (first part) increases when backwards compatibility + is broken, which will happen infrequently. + +* If the minor version (second part) is divisible by 2 + (for example 2.24.x, 2.26.x), this indicates a version of SDL that + is believed to be stable and suitable for production use. + + * In stable releases, the patchlevel or micro version (third part) + indicates bugfix releases. Bugfix releases should not add or + remove ABI, so the ".0" release (for example 2.24.0) should be + forwards-compatible with all the bugfix releases from the + same cycle (for example 2.24.1). + + * The minor version increases when new API or ABI is added, or when + other significant changes are made. Newer minor versions are + backwards-compatible, but not fully forwards-compatible. + For example, programs built against SDL 2.24.x should work fine + with SDL 2.26.x, but programs built against SDL 2.26.x will not + necessarily work with 2.24.x. + +* If the minor version (second part) is not divisible by 2 + (for example 2.23.x, 2.25.x), this indicates a development prerelease + of SDL that is not suitable for stable software distributions. + Use with caution. + + * The patchlevel or micro version (third part) increases with + each prerelease. + + * Each prerelease might add new API and/or ABI. + + * Prereleases are backwards-compatible with older stable branches. + For example, 2.25.x will be backwards-compatible with 2.24.x. + + * Prereleases are not guaranteed to be backwards-compatible with + each other. For example, new API or ABI added in 2.25.1 + might be removed or changed in 2.25.2. + If this would be a problem for you, please do not use prereleases. + + * Only upgrade to a prerelease if you can guarantee that you will + promptly upgrade to the stable release that follows it. + For example, do not upgrade to 2.23.x unless you will be able to + upgrade to 2.24.0 when it becomes available. + + * Software distributions that have a freeze policy (in particular Linux + distributions with a release cycle, such as Debian and Fedora) + should usually only package stable releases, and not prereleases. + +## Before 2.23.0 + +Older versions of SDL followed a similar policy, but instead of the +odd/even rule applying to the minor version, it applied to the patchlevel +(micro version, third part). For example, 2.0.22 was a stable release +and 2.0.21 was a prerelease. diff --git a/SDL2-2.30.5/docs/README-visualc.md b/SDL2-2.30.5/docs/README-visualc.md new file mode 100644 index 0000000..fd34b35 --- /dev/null +++ b/SDL2-2.30.5/docs/README-visualc.md @@ -0,0 +1,114 @@ +Using SDL with Microsoft Visual C++ +=================================== + +### by Lion Kimbro with additions by James Turk + +You can either use the precompiled libraries from the [SDL](https://www.libsdl.org/download.php) web site, or you can build SDL +yourself. + +### Building SDL + +0. To build SDL, your machine must, at a minimum, have the DirectX9.0c SDK installed. It may or may not be retrievable from +the [Microsoft](https://www.microsoft.com) website, so you might need to locate it [online](https://duckduckgo.com/?q=directx9.0c+sdk+download&t=h_&ia=web). +_Editor's note: I've been able to successfully build SDL using Visual Studio 2019 **without** the DX9.0c SDK_ + +1. Open the Visual Studio solution file at `./VisualC/SDL.sln`. + +2. Your IDE will likely prompt you to upgrade this solution file to whatever later version of the IDE you're using. In the `Retarget Projects` dialog, +all of the affected project files should be checked allowing you to use the latest `Windows SDK Version` you have installed, along with +the `Platform Toolset`. + +If you choose *NOT* to upgrade to use the latest `Windows SDK Version` or `Platform Toolset`, then you'll need the `Visual Studio 2010 Platform Toolset`. + +3. Build the `.dll` and `.lib` files by right clicking on each project in turn (Projects are listed in the _Workspace_ +panel in the _FileView_ tab), and selecting `Build`. + +You may get a few warnings, but you should not get any errors. + +Later, we will refer to the following `.lib` and `.dll` files that have just been generated: + +- `./VisualC/Win32/Debug/SDL2.dll` or `./VisualC/Win32/Release/SDL2.dll` +- `./VisualC/Win32/Debug/SDL2.lib` or `./VisualC/Win32/Release/SDL2.lib` +- `./VisualC/Win32/Debug/SDL2main.lib` or `./VisualC/Win32/Release/SDL2main.lib` + +_Note for the `x64` versions, just replace `Win32` in the path with `x64`_ + +### Creating a Project with SDL + +- Create a project as a `Win32 Application`. + +- Create a C++ file for your project. + +- Set the C runtime to `Multi-threaded DLL` in the menu: +`Project|Settings|C/C++ tab|Code Generation|Runtime Library `. + +- Add the SDL `include` directory to your list of includes in the menu: +`Project|Settings|C/C++ tab|Preprocessor|Additional include directories ` + +*VC7 Specific: Instead of doing this, I find it easier to add the +include and library directories to the list that VC7 keeps. Do this by +selecting Tools|Options|Projects|VC++ Directories and under the "Show +Directories For:" dropbox select "Include Files", and click the "New +Directory Icon" and add the [SDLROOT]\\include directory (e.g. If you +installed to c:\\SDL\\ add c:\\SDL\\include). Proceed to change the +dropbox selection to "Library Files" and add [SDLROOT]\\lib.* + +The "include directory" I am referring to is the `./include` folder. + +Now we're going to use the files that we had created earlier in the *Build SDL* step. + +Copy the following file into your Project directory: + +- `SDL2.dll` + +Add the following files to your project (It is not necessary to copy them to your project directory): + +- `SDL2.lib` +- `SDL2main.lib` + +To add them to your project, right click on your project, and select +`Add files to project`. + +**Instead of adding the files to your project, it is more desirable to add them to the linker options: Project|Properties|Linker|Command Line +and type the names of the libraries to link with in the "Additional Options:" box. Note: This must be done for each build configuration +(e.g. Release,Debug).** + +### Hello SDL2 + +Here's a sample SDL snippet to verify everything is setup in your IDE: + +``` + #include "SDL.h" + + int main( int argc, char* argv[] ) + { + const int WIDTH = 640; + const int HEIGHT = 480; + SDL_Window* window = NULL; + SDL_Renderer* renderer = NULL; + + SDL_Init(SDL_INIT_VIDEO); + window = SDL_CreateWindow("SDL2 Test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WIDTH, HEIGHT, SDL_WINDOW_SHOWN); + renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); + + SDL_DestroyRenderer(renderer); + SDL_DestroyWindow(window); + SDL_Quit(); + return 0; + } + ``` + +### That's it! + +I hope that this document has helped you get through the most difficult part of using the SDL: installing it. +Suggestions for improvements should be posted to the [Github Issues](https://github.com/libsdl-org/SDL/issues). + +### Credits + +Thanks to [Paulus Esterhazy](mailto:pesterhazy@gmx.net), for the work on VC++ port. + +This document was originally called "VisualC.txt", and was written by [Sam Lantinga](mailto:slouken@libsdl.org). + +Later, it was converted to HTML and expanded into the document that you see today by [Lion Kimbro](mailto:snowlion@sprynet.com). + +Minor Fixes and Visual C++ 7 Information (In Green) was added by [James Turk](mailto:james@conceptofzero.net) diff --git a/SDL2-2.30.5/docs/README-vita.md b/SDL2-2.30.5/docs/README-vita.md new file mode 100644 index 0000000..3dbaf1c --- /dev/null +++ b/SDL2-2.30.5/docs/README-vita.md @@ -0,0 +1,33 @@ +PS Vita +======= +SDL port for the Sony Playstation Vita and Sony Playstation TV + +Credit to +* xerpi, cpasjuste and rsn8887 for initial (vita2d) port +* vitasdk/dolcesdk devs +* CBPS discord (Namely Graphene and SonicMastr) + +Building +-------- +To build for the PSVita, make sure you have vitasdk and cmake installed and run: +``` + cmake -S. -Bbuild -DCMAKE_TOOLCHAIN_FILE=${VITASDK}/share/vita.toolchain.cmake -DCMAKE_BUILD_TYPE=Release + cmake --build build + cmake --install build +``` + + +Notes +----- +* gles1/gles2 support and renderers are disabled by default and can be enabled by configuring with `-DVIDEO_VITA_PVR=ON` + These renderers support 720p and 1080i resolutions. These can be specified with: + `SDL_setenv("VITA_RESOLUTION", "720", 1);` and `SDL_setenv("VITA_RESOLUTION", "1080", 1);` +* Desktop GL 1.X and 2.X support and renderers are also disabled by default and also can be enabled with `-DVIDEO_VITA_PVR=ON` as long as gl4es4vita is present in your SDK. + They support the same resolutions as the gles1/gles2 backends and require specifying `SDL_setenv("VITA_PVR_OGL", "1", 1);` + anytime before video subsystem initialization. +* gles2 support via PIB is disabled by default and can be enabled by configuring with `-DVIDEO_VITA_PIB=ON` +* By default SDL emits mouse events for touch events on every touchscreen. + Vita has two touchscreens, so it's recommended to use `SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0");` and handle touch events instead. + Individual touchscreens can be disabled with: + `SDL_setenv("VITA_DISABLE_TOUCH_FRONT", "1", 1);` and `SDL_setenv("VITA_DISABLE_TOUCH_BACK", "1", 1);` +* Support for L2/R2/R3/R3 buttons, haptic feedback and gamepad led only available on PSTV, or when using external ds4 gamepad on vita. diff --git a/SDL2-2.0.12/docs/README-wince.md b/SDL2-2.30.5/docs/README-wince.md similarity index 100% rename from SDL2-2.0.12/docs/README-wince.md rename to SDL2-2.30.5/docs/README-wince.md diff --git a/SDL2-2.30.5/docs/README-windows.md b/SDL2-2.30.5/docs/README-windows.md new file mode 100644 index 0000000..cd29c1f --- /dev/null +++ b/SDL2-2.30.5/docs/README-windows.md @@ -0,0 +1,58 @@ +# Windows + +## LLVM and Intel C++ compiler support + +SDL will build with the Visual Studio project files with LLVM-based compilers, such as the Intel oneAPI C++ +compiler, but you'll have to manually add the "-msse3" command line option +to at least the SDL_audiocvt.c source file, and possibly others. This may +not be necessary if you build SDL with CMake instead of the included Visual +Studio solution. + +Details are here: https://github.com/libsdl-org/SDL/issues/5186 + + +## OpenGL ES 2.x support + +SDL has support for OpenGL ES 2.x under Windows via two alternative +implementations. + +The most straightforward method consists in running your app in a system with +a graphic card paired with a relatively recent (as of November of 2013) driver +which supports the WGL_EXT_create_context_es2_profile extension. Vendors known +to ship said extension on Windows currently include nVidia and Intel. + +The other method involves using the +[ANGLE library](https://code.google.com/p/angleproject/). If an OpenGL ES 2.x +context is requested and no WGL_EXT_create_context_es2_profile extension is +found, SDL will try to load the libEGL.dll library provided by ANGLE. + +To obtain the ANGLE binaries, you can either compile from source from +https://chromium.googlesource.com/angle/angle or copy the relevant binaries +from a recent Chrome/Chromium install for Windows. The files you need are: + +- libEGL.dll +- libGLESv2.dll +- d3dcompiler_46.dll (supports Windows Vista or later, better shader + compiler) *or* d3dcompiler_43.dll (supports Windows XP or later) + +If you compile ANGLE from source, you can configure it so it does not need the +d3dcompiler_* DLL at all (for details on this, see their documentation). +However, by default SDL will try to preload the d3dcompiler_46.dll to +comply with ANGLE's requirements. If you wish SDL to preload +d3dcompiler_43.dll (to support Windows XP) or to skip this step at all, you +can use the SDL_HINT_VIDEO_WIN_D3DCOMPILER hint (see SDL_hints.h for more +details). + +Known Bugs: + +- SDL_GL_SetSwapInterval is currently a no op when using ANGLE. It appears + that there's a bug in the library which prevents the window contents from + refreshing if this is set to anything other than the default value. + +## Vulkan Surface Support + +Support for creating Vulkan surfaces is configured on by default. To disable +it change the value of `SDL_VIDEO_VULKAN` to 0 in `SDL_config_windows.h`. You +must install the [Vulkan SDK](https://www.lunarg.com/vulkan-sdk/) in order to +use Vulkan graphics in your application. + diff --git a/SDL2-2.0.12/docs/README-winrt.md b/SDL2-2.30.5/docs/README-winrt.md similarity index 81% rename from SDL2-2.0.12/docs/README-winrt.md rename to SDL2-2.30.5/docs/README-winrt.md index 73ef372..f4a9117 100644 --- a/SDL2-2.0.12/docs/README-winrt.md +++ b/SDL2-2.30.5/docs/README-winrt.md @@ -5,49 +5,23 @@ This port allows SDL applications to run on Microsoft's platforms that require use of "Windows Runtime", aka. "WinRT", APIs. Microsoft may, in some cases, refer to them as either "Windows Store", or for Windows 10, "UWP" apps. -Some of the operating systems that include WinRT, are: - -* Windows 10, via its Universal Windows Platform (UWP) APIs -* Windows 8.x -* Windows RT 8.x (aka. Windows 8.x for ARM processors) -* Windows Phone 8.x +In the past, SDL has supported Windows RT 8.x, Windows Phone, etc, but in +modern times this port is focused on UWP apps, which run on Windows 10, +and modern Xbox consoles. Requirements ------------ -* Microsoft Visual C++ (aka Visual Studio), either 2017, 2015, 2013, or 2012 +* Microsoft Visual C++ (aka Visual Studio) 2019. - Free, "Community" or "Express" editions may be used, so long as they - include support for either "Windows Store" or "Windows Phone" apps. + include support for either "Windows Store" or "Windows Phone" apps. "Express" versions marked as supporting "Windows Desktop" development typically do not include support for creating WinRT apps, to note. (The "Community" editions of Visual C++ do, however, support both desktop/Win32 and WinRT development). - - Visual Studio 2017 can be used, however it is recommended that you install - the Visual C++ 2015 build tools. These build tools can be installed - using VS 2017's installer. Be sure to also install the workload for - "Universal Windows Platform development", its optional component, the - "C++ Universal Windows Platform tools", and for UWP / Windows 10 - development, the "Windows 10 SDK (10.0.10240.0)". Please note that - targeting UWP / Windows 10 apps from development machine(s) running - earlier versions of Windows, such as Windows 7, is not always supported - by Visual Studio, and you may get error(s) when attempting to do so. - - Visual C++ 2012 can only build apps that target versions 8.0 of Windows, - or Windows Phone. 8.0-targeted apps will run on devices running 8.1 - editions of Windows, however they will not be able to take advantage of - 8.1-specific features. - - Visual C++ 2013 cannot create app projects that target Windows 8.0. - Visual C++ 2013 Update 4, can create app projects for Windows Phone 8.0, - Windows Phone 8.1, and Windows 8.1, but not Windows 8.0. An optional - Visual Studio add-in, "Tools for Maintaining Store apps for Windows 8", - allows Visual C++ 2013 to load and build Windows 8.0 projects that were - created with Visual C++ 2012, so long as Visual C++ 2012 is installed - on the same machine. More details on targeting different versions of - Windows can found at the following web pages: - - [Develop apps by using Visual Studio 2013](http://msdn.microsoft.com/en-us/library/windows/apps/br211384.aspx) - - [To add the Tools for Maintaining Store apps for Windows 8](http://msdn.microsoft.com/en-us/library/windows/apps/dn263114.aspx#AddMaintenanceTools) * A valid Microsoft account - This requirement is not imposed by SDL, but - rather by Microsoft's Visual C++ toolchain. This is required to launch or + rather by Microsoft's Visual C++ toolchain. This is required to launch or debug apps. @@ -57,7 +31,7 @@ Status Here is a rough list of what works, and what doesn't: * What works: - * compilation via Visual C++ 2012 through 2015 + * compilation via Visual C++ 2019. * compile-time platform detection for SDL programs. The C/C++ #define, `__WINRT__`, will be set to 1 (by SDL) when compiling for WinRT. * GPU-accelerated 2D rendering, via SDL_Renderer. @@ -70,8 +44,8 @@ Here is a rough list of what works, and what doesn't: SDL_GetPerformanceFrequency(), etc.) * file I/O via SDL_RWops * mouse input (unsupported on Windows Phone) - * audio, via SDL's WASAPI backend (if you want to record, your app must - have "Microphone" capabilities enabled in its manifest, and the user must + * audio, via SDL's WASAPI backend (if you want to record, your app must + have "Microphone" capabilities enabled in its manifest, and the user must not have blocked access. Otherwise, capture devices will fail to work, presenting as a device disconnect shortly after opening it.) * .DLL file loading. Libraries *MUST* be packaged inside applications. Loading @@ -81,7 +55,7 @@ Here is a rough list of what works, and what doesn't: SDL_GameController APIs, and is backed by Microsoft's XInput API. Please note, however, that Windows limits game-controller support in UWP apps to, "Xbox compatible controllers" (many controllers that work in Win32 apps, - do not work in UWP, due to restrictions in UWP itself.) + do not work in UWP, due to restrictions in UWP itself.) * multi-touch input * app events. SDL_APP_WILLENTER* and SDL_APP_DIDENTER* events get sent out as appropriate. @@ -225,7 +199,7 @@ libraries such that, when the app is built: 1. each library gets built for the appropriate CPU architecture(s) and WinRT platform(s). -2. each library's output, such as .dll files, get copied to the app's build +2. each library's output, such as .dll files, get copied to the app's build output. To set this up for SDL/WinRT, you'll need to run through the following steps: @@ -234,13 +208,8 @@ To set this up for SDL/WinRT, you'll need to run through the following steps: "Solution Explorer") 2. right click on your app's solution. 3. navigate to "Add", then to "Existing Project..." -4. find SDL/WinRT's Visual C++ project file and open it. Different project - files exist for different WinRT platforms. All of them are in SDL's - source distribution, in the following directories: - * `VisualC-WinRT/UWP_VS2015/` - for Windows 10 / UWP apps - * `VisualC-WinRT/WinPhone81_VS2013/` - for Windows Phone 8.1 apps - * `VisualC-WinRT/WinRT80_VS2012/` - for Windows 8.0 apps - * `VisualC-WinRT/WinRT81_VS2013/` - for Windows 8.1 apps +4. find SDL/WinRT's Visual C++ project file and open it, in the `VisualC-WinRT` + directory. 5. once the project has been added, right-click on your app's project and select, "References..." 6. click on the button titled, "Add New Reference..." @@ -276,12 +245,12 @@ To change these settings: 7. edit the "Additional Include Directories" setting, and add a path to SDL's "include" directory 8. **Optional: to enable compilation of C code:** change the setting for - "Consume Windows Runtime Extension" from "Yes (/ZW)" to "No". If you're - working with a completely C++ based project, this step can usually be + "Consume Windows Runtime Extension" from "Yes (/ZW)" to "No". If you're + working with a completely C++ based project, this step can usually be omitted. -9. **Optional: to disable precompiled headers (which can produce - 'stdafx.h'-related build errors, if setup incorrectly:** in the left-hand - list, select "Precompiled Headers", then change the setting for "Precompiled +9. **Optional: to disable precompiled headers (which can produce + 'stdafx.h'-related build errors, if setup incorrectly:** in the left-hand + list, select "Precompiled Headers", then change the setting for "Precompiled Header" from "Use (/Yu)" to "Not Using Precompiled Headers". 10. close the dialog, saving settings, by clicking the "OK" button @@ -298,7 +267,7 @@ A few files should be included directly in your app's MSVC project, specifically To include these files for C/C++ projects: -1. right-click on your project (again, in Visual C++'s Solution Explorer), +1. right-click on your project (again, in Visual C++'s Solution Explorer), navigate to "Add", then choose "Existing Item...". 2. navigate to the directory containing SDL's source code, then into its subdirectory, 'src/main/winrt/'. Select, then add, the following files: @@ -313,8 +282,8 @@ To include these files for C/C++ projects: 7. change the setting for "Consume Windows Runtime Extension" to "Yes (/ZW)". 8. click the OK button. This will close the dialog. -**NOTE: C++/CX compilation is currently required in at least one file of your -app's project. This is to make sure that Visual C++'s linker builds a 'Windows +**NOTE: C++/CX compilation is currently required in at least one file of your +app's project. This is to make sure that Visual C++'s linker builds a 'Windows Metadata' file (.winmd) for your app. Not doing so can lead to build errors.** For non-C++ projects, you will need to call SDL_WinRTRunApp from your language's @@ -324,104 +293,107 @@ first block in your Visual Studio project file. ### 6. Add app code and assets ### -At this point, you can add in SDL-specific source code. Be sure to include a -C-style main function (ie: `int main(int argc, char *argv[])`). From there you -should be able to create a single `SDL_Window` (WinRT apps can only have one -window, at present), as well as an `SDL_Renderer`. Direct3D will be used to -draw content. Events are received via SDL's usual event functions -(`SDL_PollEvent`, etc.) If you have a set of existing source files and assets, -you can start adding them to the project now. If not, or if you would like to -make sure that you're setup correctly, some short and simple sample code is +At this point, you can add in SDL-specific source code. Be sure to include a +C-style main function (ie: `int main(int argc, char *argv[])`). From there you +should be able to create a single `SDL_Window` (WinRT apps can only have one +window, at present), as well as an `SDL_Renderer`. Direct3D will be used to +draw content. Events are received via SDL's usual event functions +(`SDL_PollEvent`, etc.) If you have a set of existing source files and assets, +you can start adding them to the project now. If not, or if you would like to +make sure that you're setup correctly, some short and simple sample code is provided below. #### 6.A. ... when creating a new app #### -If you are creating a new app (rather than porting an existing SDL-based app), -or if you would just like a simple app to test SDL/WinRT with before trying to -get existing code working, some working SDL/WinRT code is provided below. To +If you are creating a new app (rather than porting an existing SDL-based app), +or if you would just like a simple app to test SDL/WinRT with before trying to +get existing code working, some working SDL/WinRT code is provided below. To set this up: 1. right click on your app's project 2. select Add, then New Item. An "Add New Item" dialog will show up. 3. from the left-hand list, choose "Visual C++" 4. from the middle/main list, choose "C++ File (.cpp)" -5. near the bottom of the dialog, next to "Name:", type in a name for your +5. near the bottom of the dialog, next to "Name:", type in a name for your source file, such as, "main.cpp". -6. click on the Add button. This will close the dialog, add the new file to +6. click on the Add button. This will close the dialog, add the new file to your project, and open the file in Visual C++'s text editor. 7. Copy and paste the following code into the new file, then save it. +```c +#include - #include - - int main(int argc, char **argv) - { - SDL_DisplayMode mode; - SDL_Window * window = NULL; - SDL_Renderer * renderer = NULL; - SDL_Event evt; - - if (SDL_Init(SDL_INIT_VIDEO) != 0) { - return 1; - } - - if (SDL_GetCurrentDisplayMode(0, &mode) != 0) { - return 1; - } - - if (SDL_CreateWindowAndRenderer(mode.w, mode.h, SDL_WINDOW_FULLSCREEN, &window, &renderer) != 0) { - return 1; - } - - while (1) { - while (SDL_PollEvent(&evt)) { - } - - SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255); - SDL_RenderClear(renderer); - SDL_RenderPresent(renderer); - } +int main(int argc, char **argv) +{ + SDL_DisplayMode mode; + SDL_Window * window = NULL; + SDL_Renderer * renderer = NULL; + SDL_Event evt; + SDL_bool keep_going = SDL_TRUE; + + if (SDL_Init(SDL_INIT_VIDEO) != 0) { + return 1; + } else if (SDL_GetCurrentDisplayMode(0, &mode) != 0) { + return 1; + } else if (SDL_CreateWindowAndRenderer(mode.w, mode.h, SDL_WINDOW_FULLSCREEN, &window, &renderer) != 0) { + return 1; } + while (keep_going) { + while (SDL_PollEvent(&evt)) { + if ((evt.type == SDL_KEYDOWN) && (evt.key.keysym.sym == SDLK_ESCAPE)) { + keep_going = SDL_FALSE; + } + } + + SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255); + SDL_RenderClear(renderer); + SDL_RenderPresent(renderer); + } + + SDL_Quit(); + return 0; +} +``` #### 6.B. Adding code and assets #### -If you have existing code and assets that you'd like to add, you should be able +If you have existing code and assets that you'd like to add, you should be able to add them now. The process for adding a set of files is as such. 1. right click on the app's project 2. select Add, then click on "New Item..." -3. open any source, header, or asset files as appropriate. Support for C and +3. open any source, header, or asset files as appropriate. Support for C and C++ is available. -Do note that WinRT only supports a subset of the APIs that are available to -Win32-based apps. Many portions of the Win32 API and the C runtime are not +Do note that WinRT only supports a subset of the APIs that are available to +Win32-based apps. Many portions of the Win32 API and the C runtime are not available. -A list of unsupported C APIs can be found at +A list of unsupported C APIs can be found at -General information on using the C runtime in WinRT can be found at +General information on using the C runtime in WinRT can be found at -A list of supported Win32 APIs for WinRT apps can be found at -. To note, -the list of supported Win32 APIs for Windows Phone 8.0 is different. -That list can be found at +A list of supported Win32 APIs for WinRT apps can be found at +. To note, +the list of supported Win32 APIs for Windows Phone 8.0 is different. +That list can be found at ### 7. Build and run your app ### -Your app project should now be setup, and you should be ready to build your app. -To run it on the local machine, open the Debug menu and choose "Start -Debugging". This will build your app, then run your app full-screen. To switch -out of your app, press the Windows key. Alternatively, you can choose to run -your app in a window. To do this, before building and running your app, find -the drop-down menu in Visual C++'s toolbar that says, "Local Machine". Expand -this by clicking on the arrow on the right side of the list, then click on -Simulator. Once you do that, any time you build and run the app, the app will +Your app project should now be setup, and you should be ready to build your app. +To run it on the local machine, open the Debug menu and choose "Start +Debugging". This will build your app, then run your app full-screen. To switch +out of your app, press the Windows key. Alternatively, you can choose to run +your app in a window. To do this, before building and running your app, find +the drop-down menu in Visual C++'s toolbar that says, "Local Machine". Expand +this by clicking on the arrow on the right side of the list, then click on +Simulator. Once you do that, any time you build and run the app, the app will launch in window, rather than full-screen. @@ -434,37 +406,37 @@ Windows 8.x that ran primarily on ARM-based tablet computers. To build and run the app on ARM-based, "Windows RT" devices, you'll need to: -- install Microsoft's "Remote Debugger" on the device. Visual C++ installs and +- install Microsoft's "Remote Debugger" on the device. Visual C++ installs and debugs ARM-based apps via IP networks. -- change a few options on the development machine, both to make sure it builds - for ARM (rather than x86 or x64), and to make sure it knows how to find the +- change a few options on the development machine, both to make sure it builds + for ARM (rather than x86 or x64), and to make sure it knows how to find the Windows RT device (on the network). -Microsoft's Remote Debugger can be found at -. Please note -that separate versions of this debugger exist for different versions of Visual +Microsoft's Remote Debugger can be found at +. Please note +that separate versions of this debugger exist for different versions of Visual C++, one each for MSVC 2015, 2013, and 2012. To setup Visual C++ to launch your app on an ARM device: -1. make sure the Remote Debugger is running on your ARM device, and that it's on +1. make sure the Remote Debugger is running on your ARM device, and that it's on the same IP network as your development machine. -2. from Visual C++'s toolbar, find a drop-down menu that says, "Win32". Click +2. from Visual C++'s toolbar, find a drop-down menu that says, "Win32". Click it, then change the value to "ARM". -3. make sure Visual C++ knows the hostname or IP address of the ARM device. To +3. make sure Visual C++ knows the hostname or IP address of the ARM device. To do this: 1. open the app project's properties 2. select "Debugging" - 3. next to "Machine Name", enter the hostname or IP address of the ARM + 3. next to "Machine Name", enter the hostname or IP address of the ARM device 4. if, and only if, you've turned off authentication in the Remote Debugger, then change the setting for "Require Authentication" to No 5. click "OK" -4. build and run the app (from Visual C++). The first time you do this, a - prompt will show up on the ARM device, asking for a Microsoft Account. You - do, unfortunately, need to log in here, and will need to follow the - subsequent registration steps in order to launch the app. After you do so, - if the app didn't already launch, try relaunching it again from within Visual +4. build and run the app (from Visual C++). The first time you do this, a + prompt will show up on the ARM device, asking for a Microsoft Account. You + do, unfortunately, need to log in here, and will need to follow the + subsequent registration steps in order to launch the app. After you do so, + if the app didn't already launch, try relaunching it again from within Visual C++. diff --git a/SDL2-2.0.12/docs/README.md b/SDL2-2.30.5/docs/README.md similarity index 72% rename from SDL2-2.0.12/docs/README.md rename to SDL2-2.30.5/docs/README.md index 7e2c151..6813f75 100644 --- a/SDL2-2.0.12/docs/README.md +++ b/SDL2-2.30.5/docs/README.md @@ -1,12 +1,6 @@ -Simple DirectMedia Layer {#mainpage} -======================== +# Simple DirectMedia Layer - (SDL) - - Version 2.0 - ---- -http://www.libsdl.org/ +https://www.libsdl.org/ Simple DirectMedia Layer is a cross-platform development library designed to provide low level access to audio, keyboard, mouse, joystick, and graphics @@ -14,14 +8,14 @@ hardware via OpenGL and Direct3D. It is used by video playback software, emulators, and popular games including Valve's award winning catalog and many Humble Bundle games. -SDL officially supports Windows, Mac OS X, Linux, iOS, and Android. +SDL officially supports Windows, macOS, Linux, iOS, and Android. Support for other platforms may be found in the source code. SDL is written in C, works natively with C++, and there are bindings available for several other languages, including C# and Python. This library is distributed under the zlib license, which can be found -in the file "COPYING.txt". +in the file "LICENSE.txt". The best way to learn how to use SDL is to check out the header files in the "include" subdirectory and the programs in the "test" subdirectory. @@ -34,30 +28,36 @@ More documentation and FAQs are available online at [the wiki](http://wiki.libsd - [DirectFB](README-directfb.md) - [DynAPI](README-dynapi.md) - [Emscripten](README-emscripten.md) +- [GDK](README-gdk.md) - [Gesture](README-gesture.md) -- [Mercurial](README-hg.md) +- [Git](README-git.md) - [iOS](README-ios.md) - [Linux](README-linux.md) -- [OS X](README-macosx.md) +- [macOS](README-macos.md) +- [OS/2](README-os2.md) - [Native Client](README-nacl.md) - [Pandora](README-pandora.md) - [Supported Platforms](README-platforms.md) - [Porting information](README-porting.md) - [PSP](README-psp.md) +- [PS2](README-ps2.md) - [Raspberry Pi](README-raspberrypi.md) - [Touch](README-touch.md) +- [Versions](README-versions.md) - [WinCE](README-wince.md) - [Windows](README-windows.md) - [WinRT](README-winrt.md) +- [PSVita](README-vita.md) +- [Nokia N-Gage](README-ngage.md) If you need help with the library, or just want to discuss SDL related -issues, you can join the [developers mailing list](http://www.libsdl.org/mailing-list.php) +issues, you can join the [SDL Discourse](https://discourse.libsdl.org/), +which can be used as a web forum or a mailing list, at your preference. If you want to report bugs or contribute patches, please submit them to -[bugzilla](https://bugzilla.libsdl.org/) +[our bug tracker](https://github.com/libsdl-org/SDL/issues) Enjoy! Sam Lantinga - diff --git a/SDL2-2.0.12/docs/doxyfile b/SDL2-2.30.5/docs/doxyfile similarity index 99% rename from SDL2-2.0.12/docs/doxyfile rename to SDL2-2.30.5/docs/doxyfile index baf1c98..7b80a3a 100644 --- a/SDL2-2.0.12/docs/doxyfile +++ b/SDL2-2.30.5/docs/doxyfile @@ -640,6 +640,7 @@ EXCLUDE = ../include/SDL_opengles2_gl2ext.h \ ../include/SDL_opengles.h \ ../include/SDL_opengl.h \ ../include/SDL_egl.h \ + ./release_checklist.md \ # The EXCLUDE_SYMLINKS tag can be used select whether or not files or diff --git a/SDL2-2.30.5/docs/release_checklist.md b/SDL2-2.30.5/docs/release_checklist.md new file mode 100644 index 0000000..37d8b6d --- /dev/null +++ b/SDL2-2.30.5/docs/release_checklist.md @@ -0,0 +1,49 @@ +# Release checklist + +When changing the version, run `build-scripts/update-version.sh X Y Z`, +where `X Y Z` are the major version, minor version, and patch level. So +`2 28 1` means "change the version to 2.28.1". This script does much of the +mechanical work. + + +## New feature release + +* Update `WhatsNew.txt` + +* Bump version number to 2.EVEN.0: + + * `./build-scripts/update-version.sh 2 EVEN 0` + +* Do the release + +* Update the website file include/header.inc.php to reflect the new version + +## New bugfix release + +* Check that no new API/ABI was added + + * If it was, do a new feature release (see above) instead + +* Bump version number from 2.Y.Z to 2.Y.(Z+1) (Y is even) + + * `./build-scripts/update-version.sh 2 Y Z+1` + +* Do the release + +* Update the website file include/header.inc.php to reflect the new version + +## After a feature release + +* Create a branch like `release-2.24.x` + +* Bump version number to 2.ODD.0 for next development branch + + * `./build-scripts/update-version.sh 2 ODD 0` + +## New development prerelease + +* Bump version number from 2.Y.Z to 2.Y.(Z+1) (Y is odd) + + * `./build-scripts/update-version.sh 2 Y Z+1` + +* Do the release diff --git a/SDL2-2.30.5/include/SDL.h b/SDL2-2.30.5/include/SDL.h new file mode 100644 index 0000000..20c903b --- /dev/null +++ b/SDL2-2.30.5/include/SDL.h @@ -0,0 +1,233 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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.h + * + * Main include header for the SDL library + */ + + +#ifndef SDL_h_ +#define SDL_h_ + +#include "SDL_main.h" +#include "SDL_stdinc.h" +#include "SDL_assert.h" +#include "SDL_atomic.h" +#include "SDL_audio.h" +#include "SDL_clipboard.h" +#include "SDL_cpuinfo.h" +#include "SDL_endian.h" +#include "SDL_error.h" +#include "SDL_events.h" +#include "SDL_filesystem.h" +#include "SDL_gamecontroller.h" +#include "SDL_guid.h" +#include "SDL_haptic.h" +#include "SDL_hidapi.h" +#include "SDL_hints.h" +#include "SDL_joystick.h" +#include "SDL_loadso.h" +#include "SDL_log.h" +#include "SDL_messagebox.h" +#include "SDL_metal.h" +#include "SDL_mutex.h" +#include "SDL_power.h" +#include "SDL_render.h" +#include "SDL_rwops.h" +#include "SDL_sensor.h" +#include "SDL_shape.h" +#include "SDL_system.h" +#include "SDL_thread.h" +#include "SDL_timer.h" +#include "SDL_version.h" +#include "SDL_video.h" +#include "SDL_locale.h" +#include "SDL_misc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* As of version 0.5, SDL is loaded dynamically into the application */ + +/** + * \name SDL_INIT_* + * + * These are the flags which may be passed to SDL_Init(). You should + * specify the subsystems which you will be using in your application. + */ +/* @{ */ +#define SDL_INIT_TIMER 0x00000001u +#define SDL_INIT_AUDIO 0x00000010u +#define SDL_INIT_VIDEO 0x00000020u /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */ +#define SDL_INIT_JOYSTICK 0x00000200u /**< SDL_INIT_JOYSTICK implies SDL_INIT_EVENTS */ +#define SDL_INIT_HAPTIC 0x00001000u +#define SDL_INIT_GAMECONTROLLER 0x00002000u /**< SDL_INIT_GAMECONTROLLER implies SDL_INIT_JOYSTICK */ +#define SDL_INIT_EVENTS 0x00004000u +#define SDL_INIT_SENSOR 0x00008000u +#define SDL_INIT_NOPARACHUTE 0x00100000u /**< compatibility; this flag is ignored. */ +#define SDL_INIT_EVERYTHING ( \ + SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_EVENTS | \ + SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER | SDL_INIT_SENSOR \ + ) +/* @} */ + +/** + * Initialize the SDL library. + * + * SDL_Init() simply forwards to calling SDL_InitSubSystem(). Therefore, the + * two may be used interchangeably. Though for readability of your code + * SDL_InitSubSystem() might be preferred. + * + * The file I/O (for example: SDL_RWFromFile) and threading (SDL_CreateThread) + * subsystems are initialized by default. Message boxes + * (SDL_ShowSimpleMessageBox) also attempt to work without initializing the + * video subsystem, in hopes of being useful in showing an error dialog when + * SDL_Init fails. You must specifically initialize other subsystems if you + * use them in your application. + * + * Logging (such as SDL_Log) works without initialization, too. + * + * `flags` may be any of the following OR'd together: + * + * - `SDL_INIT_TIMER`: timer subsystem + * - `SDL_INIT_AUDIO`: audio subsystem + * - `SDL_INIT_VIDEO`: video subsystem; automatically initializes the events + * subsystem + * - `SDL_INIT_JOYSTICK`: joystick subsystem; automatically initializes the + * events subsystem + * - `SDL_INIT_HAPTIC`: haptic (force feedback) subsystem + * - `SDL_INIT_GAMECONTROLLER`: controller subsystem; automatically + * initializes the joystick subsystem + * - `SDL_INIT_EVENTS`: events subsystem + * - `SDL_INIT_EVERYTHING`: all of the above subsystems + * - `SDL_INIT_NOPARACHUTE`: compatibility; this flag is ignored + * + * Subsystem initialization is ref-counted, you must call SDL_QuitSubSystem() + * for each SDL_InitSubSystem() to correctly shutdown a subsystem manually (or + * call SDL_Quit() to force shutdown). If a subsystem is already loaded then + * this call will increase the ref-count and return. + * + * \param flags subsystem initialization flags + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_InitSubSystem + * \sa SDL_Quit + * \sa SDL_SetMainReady + * \sa SDL_WasInit + */ +extern DECLSPEC int SDLCALL SDL_Init(Uint32 flags); + +/** + * Compatibility function to initialize the SDL library. + * + * In SDL2, this function and SDL_Init() are interchangeable. + * + * \param flags any of the flags used by SDL_Init(); see SDL_Init for details. + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Init + * \sa SDL_Quit + * \sa SDL_QuitSubSystem + */ +extern DECLSPEC int SDLCALL SDL_InitSubSystem(Uint32 flags); + +/** + * Shut down specific SDL subsystems. + * + * If you start a subsystem using a call to that subsystem's init function + * (for example SDL_VideoInit()) instead of SDL_Init() or SDL_InitSubSystem(), + * SDL_QuitSubSystem() and SDL_WasInit() will not work. You will need to use + * that subsystem's quit function (SDL_VideoQuit()) directly instead. But + * generally, you should not be using those functions directly anyhow; use + * SDL_Init() instead. + * + * You still need to call SDL_Quit() even if you close all open subsystems + * with SDL_QuitSubSystem(). + * + * \param flags any of the flags used by SDL_Init(); see SDL_Init for details. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_InitSubSystem + * \sa SDL_Quit + */ +extern DECLSPEC void SDLCALL SDL_QuitSubSystem(Uint32 flags); + +/** + * Get a mask of the specified subsystems which are currently initialized. + * + * \param flags any of the flags used by SDL_Init(); see SDL_Init for details. + * \returns a mask of all initialized subsystems if `flags` is 0, otherwise it + * returns the initialization status of the specified subsystems. + * + * The return value does not include SDL_INIT_NOPARACHUTE. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Init + * \sa SDL_InitSubSystem + */ +extern DECLSPEC Uint32 SDLCALL SDL_WasInit(Uint32 flags); + +/** + * Clean up all initialized subsystems. + * + * You should call this function even if you have already shutdown each + * initialized subsystem with SDL_QuitSubSystem(). It is safe to call this + * function even in the case of errors in initialization. + * + * If you start a subsystem using a call to that subsystem's init function + * (for example SDL_VideoInit()) instead of SDL_Init() or SDL_InitSubSystem(), + * then you must use that subsystem's quit function (SDL_VideoQuit()) to shut + * it down before calling SDL_Quit(). But generally, you should not be using + * those functions directly anyhow; use SDL_Init() instead. + * + * You can use this function with atexit() to ensure that it is run when your + * application is shutdown, but it is not wise to do this from a library or + * other dynamically loaded code. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Init + * \sa SDL_QuitSubSystem + */ +extern DECLSPEC void SDLCALL SDL_Quit(void); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/include/SDL_assert.h b/SDL2-2.30.5/include/SDL_assert.h similarity index 61% rename from SDL2-2.0.12/include/SDL_assert.h rename to SDL2-2.30.5/include/SDL_assert.h index 21bdad9..a396d4e 100644 --- a/SDL2-2.0.12/include/SDL_assert.h +++ b/SDL2-2.30.5/include/SDL_assert.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -22,7 +22,7 @@ #ifndef SDL_assert_h_ #define SDL_assert_h_ -#include "SDL_config.h" +#include "SDL_stdinc.h" #include "begin_code.h" /* Set up for C function definitions, even when using C++ */ @@ -51,8 +51,16 @@ assert can have unique static variables associated with it. /* Don't include intrin.h here because it contains C++ code */ extern void __cdecl __debugbreak(void); #define SDL_TriggerBreakpoint() __debugbreak() +#elif _SDL_HAS_BUILTIN(__builtin_debugtrap) + #define SDL_TriggerBreakpoint() __builtin_debugtrap() #elif ( (!defined(__NACL__)) && ((defined(__GNUC__) || defined(__clang__)) && (defined(__i386__) || defined(__x86_64__))) ) #define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "int $3\n\t" ) +#elif (defined(__GNUC__) || defined(__clang__)) && defined(__riscv) + #define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "ebreak\n\t" ) +#elif ( defined(__APPLE__) && (defined(__arm64__) || defined(__aarch64__)) ) /* this might work on other ARM targets, but this is a known quantity... */ + #define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "brk #22\n\t" ) +#elif defined(__APPLE__) && defined(__arm__) + #define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "bkpt #22\n\t" ) #elif defined(__386__) && defined(__WATCOMC__) #define SDL_TriggerBreakpoint() { _asm { int 0x03 } } #elif defined(HAVE_SIGNAL_H) && !defined(__WATCOMC__) @@ -65,7 +73,7 @@ assert can have unique static variables associated with it. #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 supports __func__ as a standard. */ # define SDL_FUNCTION __func__ -#elif ((__GNUC__ >= 2) || defined(_MSC_VER) || defined (__WATCOMC__)) +#elif ((defined(__GNUC__) && (__GNUC__ >= 2)) || defined(_MSC_VER) || defined (__WATCOMC__)) # define SDL_FUNCTION __FUNCTION__ #else # define SDL_FUNCTION "???" @@ -119,12 +127,10 @@ typedef struct SDL_AssertData const struct SDL_AssertData *next; } SDL_AssertData; -#if (SDL_ASSERT_LEVEL > 0) - /* Never call this directly. Use the SDL_assert* macros. */ extern DECLSPEC SDL_AssertState SDLCALL SDL_ReportAssertion(SDL_AssertData *, - const char *, - const char *, int) + const char *, + const char *, int) #if defined(__clang__) #if __has_feature(attribute_analyzer_noreturn) /* this tells Clang's static analysis that we're a custom assert function, @@ -145,9 +151,7 @@ extern DECLSPEC SDL_AssertState SDLCALL SDL_ReportAssertion(SDL_AssertData *, #define SDL_enabled_assert(condition) \ do { \ while ( !(condition) ) { \ - static struct SDL_AssertData sdl_assert_data = { \ - 0, 0, #condition, 0, 0, 0, 0 \ - }; \ + static struct SDL_AssertData sdl_assert_data = { 0, 0, #condition, 0, 0, 0, 0 }; \ const SDL_AssertState sdl_assert_state = SDL_ReportAssertion(&sdl_assert_data, SDL_FUNCTION, SDL_FILE, SDL_LINE); \ if (sdl_assert_state == SDL_ASSERTION_RETRY) { \ continue; /* go again. */ \ @@ -158,8 +162,6 @@ extern DECLSPEC SDL_AssertState SDLCALL SDL_ReportAssertion(SDL_AssertData *, } \ } while (SDL_NULL_WHILE_LOOP_CONDITION) -#endif /* enabled assertions support code */ - /* Enable various levels of assertions. */ #if SDL_ASSERT_LEVEL == 0 /* assertions disabled */ # define SDL_assert(condition) SDL_disabled_assert(condition) @@ -185,92 +187,121 @@ extern DECLSPEC SDL_AssertState SDLCALL SDL_ReportAssertion(SDL_AssertData *, #define SDL_assert_always(condition) SDL_enabled_assert(condition) +/** + * A callback that fires when an SDL assertion fails. + * + * \param data a pointer to the SDL_AssertData structure corresponding to the + * current assertion + * \param userdata what was passed as `userdata` to SDL_SetAssertionHandler() + * \returns an SDL_AssertState value indicating how to handle the failure. + */ typedef SDL_AssertState (SDLCALL *SDL_AssertionHandler)( const SDL_AssertData* data, void* userdata); /** - * \brief Set an application-defined assertion handler. + * Set an application-defined assertion handler. * - * This allows an app to show its own assertion UI and/or force the - * response to an assertion failure. If the app doesn't provide this, SDL - * will try to do the right thing, popping up a system-specific GUI dialog, - * and probably minimizing any fullscreen windows. + * This function allows an application to show its own assertion UI and/or + * force the response to an assertion failure. If the application doesn't + * provide this, SDL will try to do the right thing, popping up a + * system-specific GUI dialog, and probably minimizing any fullscreen windows. * - * This callback may fire from any thread, but it runs wrapped in a mutex, so - * it will only fire from one thread at a time. + * This callback may fire from any thread, but it runs wrapped in a mutex, so + * it will only fire from one thread at a time. * - * Setting the callback to NULL restores SDL's original internal handler. + * This callback is NOT reset to SDL's internal handler upon SDL_Quit()! * - * This callback is NOT reset to SDL's internal handler upon SDL_Quit()! + * \param handler the SDL_AssertionHandler function to call when an assertion + * fails or NULL for the default handler + * \param userdata a pointer that is passed to `handler` * - * Return SDL_AssertState value of how to handle the assertion failure. + * \since This function is available since SDL 2.0.0. * - * \param handler Callback function, called when an assertion fails. - * \param userdata A pointer passed to the callback as-is. + * \sa SDL_GetAssertionHandler */ extern DECLSPEC void SDLCALL SDL_SetAssertionHandler( SDL_AssertionHandler handler, void *userdata); /** - * \brief Get the default assertion handler. + * Get the default assertion handler. * - * This returns the function pointer that is called by default when an - * assertion is triggered. This is an internal function provided by SDL, - * that is used for assertions when SDL_SetAssertionHandler() hasn't been - * used to provide a different function. + * This returns the function pointer that is called by default when an + * assertion is triggered. This is an internal function provided by SDL, that + * is used for assertions when SDL_SetAssertionHandler() hasn't been used to + * provide a different function. * - * \return The default SDL_AssertionHandler that is called when an assert triggers. + * \returns the default SDL_AssertionHandler that is called when an assert + * triggers. + * + * \since This function is available since SDL 2.0.2. + * + * \sa SDL_GetAssertionHandler */ extern DECLSPEC SDL_AssertionHandler SDLCALL SDL_GetDefaultAssertionHandler(void); /** - * \brief Get the current assertion handler. + * Get the current assertion handler. * - * This returns the function pointer that is called when an assertion is - * triggered. This is either the value last passed to - * SDL_SetAssertionHandler(), or if no application-specified function is - * set, is equivalent to calling SDL_GetDefaultAssertionHandler(). + * This returns the function pointer that is called when an assertion is + * triggered. This is either the value last passed to + * SDL_SetAssertionHandler(), or if no application-specified function is set, + * is equivalent to calling SDL_GetDefaultAssertionHandler(). * - * \param puserdata Pointer to a void*, which will store the "userdata" - * pointer that was passed to SDL_SetAssertionHandler(). - * This value will always be NULL for the default handler. - * If you don't care about this data, it is safe to pass - * a NULL pointer to this function to ignore it. - * \return The SDL_AssertionHandler that is called when an assert triggers. + * The parameter `puserdata` is a pointer to a void*, which will store the + * "userdata" pointer that was passed to SDL_SetAssertionHandler(). This value + * will always be NULL for the default handler. If you don't care about this + * data, it is safe to pass a NULL pointer to this function to ignore it. + * + * \param puserdata pointer which is filled with the "userdata" pointer that + * was passed to SDL_SetAssertionHandler() + * \returns the SDL_AssertionHandler that is called when an assert triggers. + * + * \since This function is available since SDL 2.0.2. + * + * \sa SDL_SetAssertionHandler */ extern DECLSPEC SDL_AssertionHandler SDLCALL SDL_GetAssertionHandler(void **puserdata); /** - * \brief Get a list of all assertion failures. + * Get a list of all assertion failures. * - * Get all assertions triggered since last call to SDL_ResetAssertionReport(), - * or the start of the program. + * This function gets all assertions triggered since the last call to + * SDL_ResetAssertionReport(), or the start of the program. * - * The proper way to examine this data looks something like this: + * The proper way to examine this data looks something like this: * - * - * const SDL_AssertData *item = SDL_GetAssertionReport(); - * while (item) { - * printf("'%s', %s (%s:%d), triggered %u times, always ignore: %s.\\n", - * item->condition, item->function, item->filename, - * item->linenum, item->trigger_count, - * item->always_ignore ? "yes" : "no"); - * item = item->next; - * } - * + * ```c + * const SDL_AssertData *item = SDL_GetAssertionReport(); + * while (item) { + * printf("'%s', %s (%s:%d), triggered %u times, always ignore: %s.\\n", + * item->condition, item->function, item->filename, + * item->linenum, item->trigger_count, + * item->always_ignore ? "yes" : "no"); + * item = item->next; + * } + * ``` * - * \return List of all assertions. - * \sa SDL_ResetAssertionReport + * \returns a list of all failed assertions or NULL if the list is empty. This + * memory should not be modified or freed by the application. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ResetAssertionReport */ extern DECLSPEC const SDL_AssertData * SDLCALL SDL_GetAssertionReport(void); /** - * \brief Reset the list of all assertion failures. + * Clear the list of all assertion failures. * - * Reset list of all assertions triggered. + * This function will clear the list of all assertions triggered up to that + * point. Immediately following this call, SDL_GetAssertionReport will return + * no items. In addition, any previously-triggered assertions will be reset to + * a trigger_count of zero, and their always_ignore state will be false. * - * \sa SDL_GetAssertionReport + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetAssertionReport */ extern DECLSPEC void SDLCALL SDL_ResetAssertionReport(void); diff --git a/SDL2-2.0.12/include/SDL_atomic.h b/SDL2-2.30.5/include/SDL_atomic.h similarity index 61% rename from SDL2-2.0.12/include/SDL_atomic.h rename to SDL2-2.30.5/include/SDL_atomic.h index e99f1bc..1fa18f4 100644 --- a/SDL2-2.0.12/include/SDL_atomic.h +++ b/SDL2-2.30.5/include/SDL_atomic.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -89,25 +89,51 @@ extern "C" { typedef int SDL_SpinLock; /** - * \brief Try to lock a spin lock by setting it to a non-zero value. + * Try to lock a spin lock by setting it to a non-zero value. * - * \param lock Points to the lock. + * ***Please note that spinlocks are dangerous if you don't know what you're + * doing. Please be careful using any sort of spinlock!*** * - * \return SDL_TRUE if the lock succeeded, SDL_FALSE if the lock is already held. + * \param lock a pointer to a lock variable + * \returns SDL_TRUE if the lock succeeded, SDL_FALSE if the lock is already + * held. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AtomicLock + * \sa SDL_AtomicUnlock */ extern DECLSPEC SDL_bool SDLCALL SDL_AtomicTryLock(SDL_SpinLock *lock); /** - * \brief Lock a spin lock by setting it to a non-zero value. + * Lock a spin lock by setting it to a non-zero value. * - * \param lock Points to the lock. + * ***Please note that spinlocks are dangerous if you don't know what you're + * doing. Please be careful using any sort of spinlock!*** + * + * \param lock a pointer to a lock variable + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AtomicTryLock + * \sa SDL_AtomicUnlock */ extern DECLSPEC void SDLCALL SDL_AtomicLock(SDL_SpinLock *lock); /** - * \brief Unlock a spin lock by setting it to 0. Always returns immediately + * Unlock a spin lock by setting it to 0. * - * \param lock Points to the lock. + * Always returns immediately. + * + * ***Please note that spinlocks are dangerous if you don't know what you're + * doing. Please be careful using any sort of spinlock!*** + * + * \param lock a pointer to a lock variable + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AtomicLock + * \sa SDL_AtomicTryLock */ extern DECLSPEC void SDLCALL SDL_AtomicUnlock(SDL_SpinLock *lock); @@ -126,7 +152,7 @@ void _ReadWriteBarrier(void); /* This is correct for all CPUs when using GCC or Solaris Studio 12.1+. */ #define SDL_CompilerBarrier() __asm__ __volatile__ ("" : : : "memory") #elif defined(__WATCOMC__) -extern _inline void SDL_CompilerBarrier (void); +extern __inline void SDL_CompilerBarrier(void); #pragma aux SDL_CompilerBarrier = "" parm [] modify exact []; #else #define SDL_CompilerBarrier() \ @@ -137,20 +163,22 @@ extern _inline void SDL_CompilerBarrier (void); * Memory barriers are designed to prevent reads and writes from being * reordered by the compiler and being seen out of order on multi-core CPUs. * - * A typical pattern would be for thread A to write some data and a flag, - * and for thread B to read the flag and get the data. In this case you - * would insert a release barrier between writing the data and the flag, + * A typical pattern would be for thread A to write some data and a flag, and + * for thread B to read the flag and get the data. In this case you would + * insert a release barrier between writing the data and the flag, * guaranteeing that the data write completes no later than the flag is - * written, and you would insert an acquire barrier between reading the - * flag and reading the data, to ensure that all the reads associated - * with the flag have completed. + * written, and you would insert an acquire barrier between reading the flag + * and reading the data, to ensure that all the reads associated with the flag + * have completed. * - * In this pattern you should always see a release barrier paired with - * an acquire barrier and you should gate the data reads/writes with a - * single flag variable. + * In this pattern you should always see a release barrier paired with an + * acquire barrier and you should gate the data reads/writes with a single + * flag variable. * * For more information on these semantics, take a look at the blog post: * http://preshing.com/20120913/acquire-and-release-semantics + * + * \since This function is available since SDL 2.0.6. */ extern DECLSPEC void SDLCALL SDL_MemoryBarrierReleaseFunction(void); extern DECLSPEC void SDLCALL SDL_MemoryBarrierAcquireFunction(void); @@ -181,7 +209,7 @@ typedef void (*SDL_KernelMemoryBarrierFunc)(); #if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) || defined(__ARM_ARCH_8A__) #define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("dmb ish" : : : "memory") #define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("dmb ish" : : : "memory") -#elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6T2__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_5TE__) +#elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6T2__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) #ifdef __thumb__ /* The mcr instruction isn't available in thumb mode, use real functions */ #define SDL_MEMORY_BARRIER_USES_FUNCTION @@ -209,6 +237,25 @@ typedef void (*SDL_KernelMemoryBarrierFunc)(); #endif #endif +/* "REP NOP" is PAUSE, coded for tools that don't know it by that name. */ +#if (defined(__GNUC__) || defined(__clang__)) && (defined(__i386__) || defined(__x86_64__)) + #define SDL_CPUPauseInstruction() __asm__ __volatile__("pause\n") /* Some assemblers can't do REP NOP, so go with PAUSE. */ +#elif (defined(__arm__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7) || defined(__aarch64__) + #define SDL_CPUPauseInstruction() __asm__ __volatile__("yield" ::: "memory") +#elif (defined(__powerpc__) || defined(__powerpc64__)) + #define SDL_CPUPauseInstruction() __asm__ __volatile__("or 27,27,27"); +#elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) + #define SDL_CPUPauseInstruction() _mm_pause() /* this is actually "rep nop" and not a SIMD instruction. No inline asm in MSVC x86-64! */ +#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64)) + #define SDL_CPUPauseInstruction() __yield() +#elif defined(__WATCOMC__) && defined(__386__) + extern __inline void SDL_CPUPauseInstruction(void); + #pragma aux SDL_CPUPauseInstruction = ".686p" ".xmm2" "pause" +#else + #define SDL_CPUPauseInstruction() +#endif + + /** * \brief A type representing an atomic integer value. It is a struct * so people don't accidentally use numeric operations on it. @@ -216,32 +263,73 @@ typedef void (*SDL_KernelMemoryBarrierFunc)(); typedef struct { int value; } SDL_atomic_t; /** - * \brief Set an atomic variable to a new value if it is currently an old value. + * Set an atomic variable to a new value if it is currently an old value. * - * \return SDL_TRUE if the atomic variable was set, SDL_FALSE otherwise. + * ***Note: If you don't know what this function is for, you shouldn't use + * it!*** * - * \note If you don't know what this function is for, you shouldn't use it! -*/ + * \param a a pointer to an SDL_atomic_t variable to be modified + * \param oldval the old value + * \param newval the new value + * \returns SDL_TRUE if the atomic variable was set, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AtomicCASPtr + * \sa SDL_AtomicGet + * \sa SDL_AtomicSet + */ extern DECLSPEC SDL_bool SDLCALL SDL_AtomicCAS(SDL_atomic_t *a, int oldval, int newval); /** - * \brief Set an atomic variable to a value. + * Set an atomic variable to a value. * - * \return The previous value of the atomic variable. + * This function also acts as a full memory barrier. + * + * ***Note: If you don't know what this function is for, you shouldn't use + * it!*** + * + * \param a a pointer to an SDL_atomic_t variable to be modified + * \param v the desired value + * \returns the previous value of the atomic variable. + * + * \since This function is available since SDL 2.0.2. + * + * \sa SDL_AtomicGet */ extern DECLSPEC int SDLCALL SDL_AtomicSet(SDL_atomic_t *a, int v); /** - * \brief Get the value of an atomic variable + * Get the value of an atomic variable. + * + * ***Note: If you don't know what this function is for, you shouldn't use + * it!*** + * + * \param a a pointer to an SDL_atomic_t variable + * \returns the current value of an atomic variable. + * + * \since This function is available since SDL 2.0.2. + * + * \sa SDL_AtomicSet */ extern DECLSPEC int SDLCALL SDL_AtomicGet(SDL_atomic_t *a); /** - * \brief Add to an atomic variable. + * Add to an atomic variable. * - * \return The previous value of the atomic variable. + * This function also acts as a full memory barrier. * - * \note This same style can be used for any number operation + * ***Note: If you don't know what this function is for, you shouldn't use + * it!*** + * + * \param a a pointer to an SDL_atomic_t variable to be modified + * \param v the desired value to add + * \returns the previous value of the atomic variable. + * + * \since This function is available since SDL 2.0.2. + * + * \sa SDL_AtomicDecRef + * \sa SDL_AtomicIncRef */ extern DECLSPEC int SDLCALL SDL_AtomicAdd(SDL_atomic_t *a, int v); @@ -263,23 +351,54 @@ extern DECLSPEC int SDLCALL SDL_AtomicAdd(SDL_atomic_t *a, int v); #endif /** - * \brief Set a pointer to a new value if it is currently an old value. + * Set a pointer to a new value if it is currently an old value. * - * \return SDL_TRUE if the pointer was set, SDL_FALSE otherwise. + * ***Note: If you don't know what this function is for, you shouldn't use + * it!*** * - * \note If you don't know what this function is for, you shouldn't use it! -*/ + * \param a a pointer to a pointer + * \param oldval the old pointer value + * \param newval the new pointer value + * \returns SDL_TRUE if the pointer was set, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AtomicCAS + * \sa SDL_AtomicGetPtr + * \sa SDL_AtomicSetPtr + */ extern DECLSPEC SDL_bool SDLCALL SDL_AtomicCASPtr(void **a, void *oldval, void *newval); /** - * \brief Set a pointer to a value atomically. + * Set a pointer to a value atomically. * - * \return The previous value of the pointer. + * ***Note: If you don't know what this function is for, you shouldn't use + * it!*** + * + * \param a a pointer to a pointer + * \param v the desired pointer value + * \returns the previous value of the pointer. + * + * \since This function is available since SDL 2.0.2. + * + * \sa SDL_AtomicCASPtr + * \sa SDL_AtomicGetPtr */ extern DECLSPEC void* SDLCALL SDL_AtomicSetPtr(void **a, void* v); /** - * \brief Get the value of a pointer atomically. + * Get the value of a pointer atomically. + * + * ***Note: If you don't know what this function is for, you shouldn't use + * it!*** + * + * \param a a pointer to a pointer + * \returns the current value of a pointer. + * + * \since This function is available since SDL 2.0.2. + * + * \sa SDL_AtomicCASPtr + * \sa SDL_AtomicSetPtr */ extern DECLSPEC void* SDLCALL SDL_AtomicGetPtr(void **a); diff --git a/SDL2-2.30.5/include/SDL_audio.h b/SDL2-2.30.5/include/SDL_audio.h new file mode 100644 index 0000000..bd8e7ab --- /dev/null +++ b/SDL2-2.30.5/include/SDL_audio.h @@ -0,0 +1,1500 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +/* !!! FIXME: several functions in here need Doxygen comments. */ + +/** + * \file SDL_audio.h + * + * Access to the raw audio mixing buffer for the SDL library. + */ + +#ifndef SDL_audio_h_ +#define SDL_audio_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_endian.h" +#include "SDL_mutex.h" +#include "SDL_thread.h" +#include "SDL_rwops.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Audio format flags. + * + * These are what the 16 bits in SDL_AudioFormat currently mean... + * (Unspecified bits are always zero). + * + * \verbatim + ++-----------------------sample is signed if set + || + || ++-----------sample is bigendian if set + || || + || || ++---sample is float if set + || || || + || || || +---sample bit size---+ + || || || | | + 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 + \endverbatim + * + * There are macros in SDL 2.0 and later to query these bits. + */ +typedef Uint16 SDL_AudioFormat; + +/** + * \name Audio flags + */ +/* @{ */ + +#define SDL_AUDIO_MASK_BITSIZE (0xFF) +#define SDL_AUDIO_MASK_DATATYPE (1<<8) +#define SDL_AUDIO_MASK_ENDIAN (1<<12) +#define SDL_AUDIO_MASK_SIGNED (1<<15) +#define SDL_AUDIO_BITSIZE(x) (x & SDL_AUDIO_MASK_BITSIZE) +#define SDL_AUDIO_ISFLOAT(x) (x & SDL_AUDIO_MASK_DATATYPE) +#define SDL_AUDIO_ISBIGENDIAN(x) (x & SDL_AUDIO_MASK_ENDIAN) +#define SDL_AUDIO_ISSIGNED(x) (x & SDL_AUDIO_MASK_SIGNED) +#define SDL_AUDIO_ISINT(x) (!SDL_AUDIO_ISFLOAT(x)) +#define SDL_AUDIO_ISLITTLEENDIAN(x) (!SDL_AUDIO_ISBIGENDIAN(x)) +#define SDL_AUDIO_ISUNSIGNED(x) (!SDL_AUDIO_ISSIGNED(x)) + +/** + * \name Audio format flags + * + * Defaults to LSB byte order. + */ +/* @{ */ +#define AUDIO_U8 0x0008 /**< Unsigned 8-bit samples */ +#define AUDIO_S8 0x8008 /**< Signed 8-bit samples */ +#define AUDIO_U16LSB 0x0010 /**< Unsigned 16-bit samples */ +#define AUDIO_S16LSB 0x8010 /**< Signed 16-bit samples */ +#define AUDIO_U16MSB 0x1010 /**< As above, but big-endian byte order */ +#define AUDIO_S16MSB 0x9010 /**< As above, but big-endian byte order */ +#define AUDIO_U16 AUDIO_U16LSB +#define AUDIO_S16 AUDIO_S16LSB +/* @} */ + +/** + * \name int32 support + */ +/* @{ */ +#define AUDIO_S32LSB 0x8020 /**< 32-bit integer samples */ +#define AUDIO_S32MSB 0x9020 /**< As above, but big-endian byte order */ +#define AUDIO_S32 AUDIO_S32LSB +/* @} */ + +/** + * \name float32 support + */ +/* @{ */ +#define AUDIO_F32LSB 0x8120 /**< 32-bit floating point samples */ +#define AUDIO_F32MSB 0x9120 /**< As above, but big-endian byte order */ +#define AUDIO_F32 AUDIO_F32LSB +/* @} */ + +/** + * \name Native audio byte ordering + */ +/* @{ */ +#if SDL_BYTEORDER == SDL_LIL_ENDIAN +#define AUDIO_U16SYS AUDIO_U16LSB +#define AUDIO_S16SYS AUDIO_S16LSB +#define AUDIO_S32SYS AUDIO_S32LSB +#define AUDIO_F32SYS AUDIO_F32LSB +#else +#define AUDIO_U16SYS AUDIO_U16MSB +#define AUDIO_S16SYS AUDIO_S16MSB +#define AUDIO_S32SYS AUDIO_S32MSB +#define AUDIO_F32SYS AUDIO_F32MSB +#endif +/* @} */ + +/** + * \name Allow change flags + * + * Which audio format changes are allowed when opening a device. + */ +/* @{ */ +#define SDL_AUDIO_ALLOW_FREQUENCY_CHANGE 0x00000001 +#define SDL_AUDIO_ALLOW_FORMAT_CHANGE 0x00000002 +#define SDL_AUDIO_ALLOW_CHANNELS_CHANGE 0x00000004 +#define SDL_AUDIO_ALLOW_SAMPLES_CHANGE 0x00000008 +#define SDL_AUDIO_ALLOW_ANY_CHANGE (SDL_AUDIO_ALLOW_FREQUENCY_CHANGE|SDL_AUDIO_ALLOW_FORMAT_CHANGE|SDL_AUDIO_ALLOW_CHANNELS_CHANGE|SDL_AUDIO_ALLOW_SAMPLES_CHANGE) +/* @} */ + +/* @} *//* Audio flags */ + +/** + * This function is called when the audio device needs more data. + * + * \param userdata An application-specific parameter saved in + * the SDL_AudioSpec structure + * \param stream A pointer to the audio data buffer. + * \param len The length of that buffer in bytes. + * + * Once the callback returns, the buffer will no longer be valid. + * Stereo samples are stored in a LRLRLR ordering. + * + * You can choose to avoid callbacks and use SDL_QueueAudio() instead, if + * you like. Just open your audio device with a NULL callback. + */ +typedef void (SDLCALL * SDL_AudioCallback) (void *userdata, Uint8 * stream, + int len); + +/** + * 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 LFE BL BR (4.1 surround) + * 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 +{ + int freq; /**< DSP frequency -- samples per second */ + SDL_AudioFormat format; /**< Audio data format */ + Uint8 channels; /**< Number of channels: 1 mono, 2 stereo */ + Uint8 silence; /**< Audio buffer silence value (calculated) */ + Uint16 samples; /**< Audio buffer size in sample FRAMES (total samples divided by channel count) */ + Uint16 padding; /**< Necessary for some compile environments */ + Uint32 size; /**< Audio buffer size in bytes (calculated) */ + SDL_AudioCallback callback; /**< Callback that feeds the audio device (NULL to use SDL_QueueAudio()). */ + void *userdata; /**< Userdata passed to callback (ignored for NULL callbacks). */ +} SDL_AudioSpec; + + +struct SDL_AudioCVT; +typedef void (SDLCALL * SDL_AudioFilter) (struct SDL_AudioCVT * cvt, + SDL_AudioFormat format); + +/** + * \brief Upper limit of filters in SDL_AudioCVT + * + * The maximum number of SDL_AudioFilter functions in SDL_AudioCVT is + * currently limited to 9. The SDL_AudioCVT.filters array has 10 pointers, + * one of which is the terminating NULL pointer. + */ +#define SDL_AUDIOCVT_MAX_FILTERS 9 + +/** + * \struct SDL_AudioCVT + * \brief A structure to hold a set of audio conversion filters and buffers. + * + * Note that various parts of the conversion pipeline can take advantage + * of SIMD operations (like SSE2, for example). SDL_AudioCVT doesn't require + * you to pass it aligned data, but can possibly run much faster if you + * set both its (buf) field to a pointer that is aligned to 16 bytes, and its + * (len) field to something that's a multiple of 16, if possible. + */ +#if defined(__GNUC__) && !defined(__CHERI_PURE_CAPABILITY__) +/* This structure is 84 bytes on 32-bit architectures, make sure GCC doesn't + pad it out to 88 bytes to guarantee ABI compatibility between compilers. + This is not a concern on CHERI architectures, where pointers must be stored + at aligned locations otherwise they will become invalid, and thus structs + containing pointers cannot be packed without giving a warning or error. + vvv + The next time we rev the ABI, make sure to size the ints and add padding. +*/ +#define SDL_AUDIOCVT_PACKED __attribute__((packed)) +#else +#define SDL_AUDIOCVT_PACKED +#endif +/* */ +typedef struct SDL_AudioCVT +{ + int needed; /**< Set to 1 if conversion possible */ + SDL_AudioFormat src_format; /**< Source audio format */ + SDL_AudioFormat dst_format; /**< Target audio format */ + double rate_incr; /**< Rate conversion increment */ + Uint8 *buf; /**< Buffer to hold entire audio data */ + int len; /**< Length of original audio buffer */ + int len_cvt; /**< Length of converted audio buffer */ + int len_mult; /**< buffer must be len*len_mult big */ + double len_ratio; /**< Given len, final size is len*len_ratio */ + SDL_AudioFilter filters[SDL_AUDIOCVT_MAX_FILTERS + 1]; /**< NULL-terminated list of filter functions */ + int filter_index; /**< Current audio conversion function */ +} SDL_AUDIOCVT_PACKED SDL_AudioCVT; + + +/* Function prototypes */ + +/** + * \name Driver discovery functions + * + * These functions return the list of built in audio drivers, in the + * order that they are normally initialized by default. + */ +/* @{ */ + +/** + * Use this function to get the number of built-in audio drivers. + * + * This function returns a hardcoded number. This never returns a negative + * value; if there are no drivers compiled into this build of SDL, this + * function returns zero. The presence of a driver in this list does not mean + * it will function, it just means SDL is capable of interacting with that + * interface. For example, a build of SDL might have esound support, but if + * there's no esound server available, SDL's esound driver would fail if used. + * + * By default, SDL tries all drivers, in its preferred order, until one is + * found to be usable. + * + * \returns the number of built-in audio drivers. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetAudioDriver + */ +extern DECLSPEC int SDLCALL SDL_GetNumAudioDrivers(void); + +/** + * Use this function to get the name of a built in audio driver. + * + * The list of audio drivers is given in the order that they are normally + * initialized by default; the drivers that seem more reasonable to choose + * first (as far as the SDL developers believe) are earlier in the list. + * + * The names of drivers are all simple, low-ASCII identifiers, like "alsa", + * "coreaudio" or "xaudio2". These never have Unicode characters, and are not + * meant to be proper names. + * + * \param index the index of the audio driver; the value ranges from 0 to + * SDL_GetNumAudioDrivers() - 1 + * \returns the name of the audio driver at the requested index, or NULL if an + * invalid index was specified. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetNumAudioDrivers + */ +extern DECLSPEC const char *SDLCALL SDL_GetAudioDriver(int index); +/* @} */ + +/** + * \name Initialization and cleanup + * + * \internal These functions are used internally, and should not be used unless + * you have a specific need to specify the audio driver you want to + * use. You should normally use SDL_Init() or SDL_InitSubSystem(). + */ +/* @{ */ + +/** + * Use this function to initialize a particular audio driver. + * + * This function is used internally, and should not be used unless you have a + * specific need to designate the audio driver you want to use. You should + * normally use SDL_Init() or SDL_InitSubSystem(). + * + * \param driver_name the name of the desired audio driver + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AudioQuit + */ +extern DECLSPEC int SDLCALL SDL_AudioInit(const char *driver_name); + +/** + * Use this function to shut down audio if you initialized it with + * SDL_AudioInit(). + * + * This function is used internally, and should not be used unless you have a + * specific need to specify the audio driver you want to use. You should + * normally use SDL_Quit() or SDL_QuitSubSystem(). + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AudioInit + */ +extern DECLSPEC void SDLCALL SDL_AudioQuit(void); +/* @} */ + +/** + * Get the name of the current audio driver. + * + * The returned string points to internal static memory and thus never becomes + * invalid, even if you quit the audio subsystem and initialize a new driver + * (although such a case would return a different static string from another + * call to this function, of course). As such, you should not modify or free + * the returned string. + * + * \returns the name of the current audio driver or NULL if no driver has been + * initialized. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AudioInit + */ +extern DECLSPEC const char *SDLCALL SDL_GetCurrentAudioDriver(void); + +/** + * This function is a legacy means of opening the audio device. + * + * This function remains for compatibility with SDL 1.2, but also because it's + * slightly easier to use than the new functions in SDL 2.0. The new, more + * powerful, and preferred way to do this is SDL_OpenAudioDevice(). + * + * This function is roughly equivalent to: + * + * ```c + * SDL_OpenAudioDevice(NULL, 0, desired, obtained, SDL_AUDIO_ALLOW_ANY_CHANGE); + * ``` + * + * With two notable exceptions: + * + * - If `obtained` is NULL, we use `desired` (and allow no changes), which + * means desired will be modified to have the correct values for silence, + * etc, and SDL will convert any differences between your app's specific + * request and the hardware behind the scenes. + * - The return value is always success or failure, and not a device ID, which + * means you can only have one device open at a time with this function. + * + * \param desired an SDL_AudioSpec structure representing the desired output + * format. Please refer to the SDL_OpenAudioDevice + * documentation for details on how to prepare this structure. + * \param obtained an SDL_AudioSpec structure filled in with the actual + * parameters, or NULL. + * \returns 0 if successful, placing the actual hardware parameters in the + * structure pointed to by `obtained`. + * + * If `obtained` is NULL, the audio data passed to the callback + * function will be guaranteed to be in the requested format, and + * will be automatically converted to the actual hardware audio + * format if necessary. If `obtained` is NULL, `desired` will have + * fields modified. + * + * This function returns a negative error code on failure to open the + * audio device or failure to set up the audio thread; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CloseAudio + * \sa SDL_LockAudio + * \sa SDL_PauseAudio + * \sa SDL_UnlockAudio + */ +extern DECLSPEC int SDLCALL SDL_OpenAudio(SDL_AudioSpec * desired, + SDL_AudioSpec * obtained); + +/** + * SDL Audio Device IDs. + * + * A successful call to SDL_OpenAudio() is always device id 1, and legacy + * SDL audio APIs assume you want this device ID. SDL_OpenAudioDevice() calls + * always returns devices >= 2 on success. The legacy calls are good both + * for backwards compatibility and when you don't care about multiple, + * specific, or capture devices. + */ +typedef Uint32 SDL_AudioDeviceID; + +/** + * Get the number of built-in audio devices. + * + * This function is only valid after successfully initializing the audio + * subsystem. + * + * Note that audio capture support is not implemented as of SDL 2.0.4, so the + * `iscapture` parameter is for future expansion and should always be zero for + * now. + * + * This function will return -1 if an explicit list of devices can't be + * determined. Returning -1 is not an error. For example, if SDL is set up to + * talk to a remote audio server, it can't list every one available on the + * Internet, but it will still allow a specific host to be specified in + * SDL_OpenAudioDevice(). + * + * In many common cases, when this function returns a value <= 0, it can still + * successfully open the default device (NULL for first argument of + * SDL_OpenAudioDevice()). + * + * This function may trigger a complete redetect of available hardware. It + * should not be called for each iteration of a loop, but rather once at the + * start of a loop: + * + * ```c + * // Don't do this: + * for (int i = 0; i < SDL_GetNumAudioDevices(0); i++) + * + * // do this instead: + * const int count = SDL_GetNumAudioDevices(0); + * for (int i = 0; i < count; ++i) { do_something_here(); } + * ``` + * + * \param iscapture zero to request playback devices, non-zero to request + * recording devices + * \returns the number of available devices exposed by the current driver or + * -1 if an explicit list of devices can't be determined. A return + * value of -1 does not necessarily mean an error condition. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetAudioDeviceName + * \sa SDL_OpenAudioDevice + */ +extern DECLSPEC int SDLCALL SDL_GetNumAudioDevices(int iscapture); + +/** + * Get the human-readable name of a specific audio device. + * + * This function is only valid after successfully initializing the audio + * subsystem. The values returned by this function reflect the latest call to + * SDL_GetNumAudioDevices(); re-call that function to redetect available + * hardware. + * + * The string returned by this function is UTF-8 encoded, read-only, and + * managed internally. You are not to free it. If you need to keep the string + * for any length of time, you should make your own copy of it, as it will be + * invalid next time any of several other SDL functions are called. + * + * \param index the index of the audio device; valid values range from 0 to + * SDL_GetNumAudioDevices() - 1 + * \param iscapture non-zero to query the list of recording devices, zero to + * query the list of output devices. + * \returns the name of the audio device at the requested index, or NULL on + * error. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetNumAudioDevices + * \sa SDL_GetDefaultAudioInfo + */ +extern DECLSPEC const char *SDLCALL SDL_GetAudioDeviceName(int index, + int iscapture); + +/** + * Get the preferred audio format of a specific audio device. + * + * This function is only valid after a successfully initializing the audio + * subsystem. The values returned by this function reflect the latest call to + * SDL_GetNumAudioDevices(); re-call that function to redetect available + * hardware. + * + * `spec` will be filled with the sample rate, sample format, and channel + * count. + * + * \param index the index of the audio device; valid values range from 0 to + * SDL_GetNumAudioDevices() - 1 + * \param iscapture non-zero to query the list of recording devices, zero to + * query the list of output devices. + * \param spec The SDL_AudioSpec to be initialized by this function. + * \returns 0 on success, nonzero on error + * + * \since This function is available since SDL 2.0.16. + * + * \sa SDL_GetNumAudioDevices + * \sa SDL_GetDefaultAudioInfo + */ +extern DECLSPEC int SDLCALL SDL_GetAudioDeviceSpec(int index, + int iscapture, + SDL_AudioSpec *spec); + + +/** + * Get the name and preferred format of the default audio device. + * + * Some (but not all!) platforms have an isolated mechanism to get information + * about the "default" device. This can actually be a completely different + * device that's not in the list you get from SDL_GetAudioDeviceSpec(). It can + * even be a network address! (This is discussed in SDL_OpenAudioDevice().) + * + * As a result, this call is not guaranteed to be performant, as it can query + * the sound server directly every time, unlike the other query functions. You + * should call this function sparingly! + * + * `spec` will be filled with the sample rate, sample format, and channel + * count, if a default device exists on the system. If `name` is provided, + * will be filled with either a dynamically-allocated UTF-8 string or NULL. + * + * \param name A pointer to be filled with the name of the default device (can + * be NULL). Please call SDL_free() when you are done with this + * pointer! + * \param spec The SDL_AudioSpec to be initialized by this function. + * \param iscapture non-zero to query the default recording device, zero to + * query the default output device. + * \returns 0 on success, nonzero on error + * + * \since This function is available since SDL 2.24.0. + * + * \sa SDL_GetAudioDeviceName + * \sa SDL_GetAudioDeviceSpec + * \sa SDL_OpenAudioDevice + */ +extern DECLSPEC int SDLCALL SDL_GetDefaultAudioInfo(char **name, + SDL_AudioSpec *spec, + int iscapture); + + +/** + * Open a specific audio device. + * + * SDL_OpenAudio(), unlike this function, always acts on device ID 1. As such, + * this function will never return a 1 so as not to conflict with the legacy + * function. + * + * Please note that SDL 2.0 before 2.0.5 did not support recording; as such, + * this function would fail if `iscapture` was not zero. Starting with SDL + * 2.0.5, recording is implemented and this value can be non-zero. + * + * Passing in a `device` name of NULL requests the most reasonable default + * (and is equivalent to what SDL_OpenAudio() does to choose a device). The + * `device` name is a UTF-8 string reported by SDL_GetAudioDeviceName(), but + * some drivers allow arbitrary and driver-specific strings, such as a + * hostname/IP address for a remote audio server, or a filename in the + * diskaudio driver. + * + * An opened audio device starts out paused, and should be enabled for playing + * by calling SDL_PauseAudioDevice(devid, 0) when you are ready for your audio + * callback function to be called. Since the audio driver may modify the + * requested size of the audio buffer, you should allocate any local mixing + * buffers after you open the audio device. + * + * The audio callback runs in a separate thread in most cases; you can prevent + * race conditions between your callback and other threads without fully + * pausing playback with SDL_LockAudioDevice(). For more information about the + * callback, see SDL_AudioSpec. + * + * Managing the audio spec via 'desired' and 'obtained': + * + * When filling in the desired audio spec structure: + * + * - `desired->freq` should be the frequency in sample-frames-per-second (Hz). + * - `desired->format` should be the audio format (`AUDIO_S16SYS`, etc). + * - `desired->samples` is the desired size of the audio buffer, in _sample + * frames_ (with stereo output, two samples--left and right--would make a + * single sample frame). This number should be a power of two, and may be + * adjusted by the audio driver to a value more suitable for the hardware. + * Good values seem to range between 512 and 8096 inclusive, depending on + * the application and CPU speed. Smaller values reduce latency, but can + * lead to underflow if the application is doing heavy processing and cannot + * fill the audio buffer in time. Note that the number of sample frames is + * directly related to time by the following formula: `ms = + * (sampleframes*1000)/freq` + * - `desired->size` is the size in _bytes_ of the audio buffer, and is + * calculated by SDL_OpenAudioDevice(). You don't initialize this. + * - `desired->silence` is the value used to set the buffer to silence, and is + * calculated by SDL_OpenAudioDevice(). You don't initialize this. + * - `desired->callback` should be set to a function that will be called when + * the audio device is ready for more data. It is passed a pointer to the + * audio buffer, and the length in bytes of the audio buffer. This function + * usually runs in a separate thread, and so you should protect data + * structures that it accesses by calling SDL_LockAudioDevice() and + * SDL_UnlockAudioDevice() in your code. Alternately, you may pass a NULL + * pointer here, and call SDL_QueueAudio() with some frequency, to queue + * more audio samples to be played (or for capture devices, call + * SDL_DequeueAudio() with some frequency, to obtain audio samples). + * - `desired->userdata` is passed as the first parameter to your callback + * function. If you passed a NULL callback, this value is ignored. + * + * `allowed_changes` can have the following flags OR'd together: + * + * - `SDL_AUDIO_ALLOW_FREQUENCY_CHANGE` + * - `SDL_AUDIO_ALLOW_FORMAT_CHANGE` + * - `SDL_AUDIO_ALLOW_CHANNELS_CHANGE` + * - `SDL_AUDIO_ALLOW_SAMPLES_CHANGE` + * - `SDL_AUDIO_ALLOW_ANY_CHANGE` + * + * These flags specify how SDL should behave when a device cannot offer a + * specific feature. If the application requests a feature that the hardware + * doesn't offer, SDL will always try to get the closest equivalent. + * + * For example, if you ask for float32 audio format, but the sound card only + * supports int16, SDL will set the hardware to int16. If you had set + * SDL_AUDIO_ALLOW_FORMAT_CHANGE, SDL will change the format in the `obtained` + * structure. If that flag was *not* set, SDL will prepare to convert your + * callback's float32 audio to int16 before feeding it to the hardware and + * will keep the originally requested format in the `obtained` structure. + * + * The resulting audio specs, varying depending on hardware and on what + * changes were allowed, will then be written back to `obtained`. + * + * If your application can only handle one specific data format, pass a zero + * for `allowed_changes` and let SDL transparently handle any differences. + * + * \param device a UTF-8 string reported by SDL_GetAudioDeviceName() or a + * driver-specific name as appropriate. NULL requests the most + * reasonable default device. + * \param iscapture non-zero to specify a device should be opened for + * recording, not playback + * \param desired an SDL_AudioSpec structure representing the desired output + * format; see SDL_OpenAudio() for more information + * \param obtained an SDL_AudioSpec structure filled in with the actual output + * format; see SDL_OpenAudio() for more information + * \param allowed_changes 0, or one or more flags OR'd together + * \returns a valid device ID that is > 0 on success or 0 on failure; call + * SDL_GetError() for more information. + * + * For compatibility with SDL 1.2, this will never return 1, since + * SDL reserves that ID for the legacy SDL_OpenAudio() function. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CloseAudioDevice + * \sa SDL_GetAudioDeviceName + * \sa SDL_LockAudioDevice + * \sa SDL_OpenAudio + * \sa SDL_PauseAudioDevice + * \sa SDL_UnlockAudioDevice + */ +extern DECLSPEC SDL_AudioDeviceID SDLCALL SDL_OpenAudioDevice( + const char *device, + int iscapture, + const SDL_AudioSpec *desired, + SDL_AudioSpec *obtained, + int allowed_changes); + + + +/** + * \name Audio state + * + * Get the current audio state. + */ +/* @{ */ +typedef enum +{ + SDL_AUDIO_STOPPED = 0, + SDL_AUDIO_PLAYING, + SDL_AUDIO_PAUSED +} SDL_AudioStatus; + +/** + * This function is a legacy means of querying the audio device. + * + * New programs might want to use SDL_GetAudioDeviceStatus() instead. This + * function is equivalent to calling... + * + * ```c + * SDL_GetAudioDeviceStatus(1); + * ``` + * + * ...and is only useful if you used the legacy SDL_OpenAudio() function. + * + * \returns the SDL_AudioStatus of the audio device opened by SDL_OpenAudio(). + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetAudioDeviceStatus + */ +extern DECLSPEC SDL_AudioStatus SDLCALL SDL_GetAudioStatus(void); + +/** + * Use this function to get the current audio state of an audio device. + * + * \param dev the ID of an audio device previously opened with + * SDL_OpenAudioDevice() + * \returns the SDL_AudioStatus of the specified audio device. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_PauseAudioDevice + */ +extern DECLSPEC SDL_AudioStatus SDLCALL SDL_GetAudioDeviceStatus(SDL_AudioDeviceID dev); +/* @} *//* Audio State */ + +/** + * \name Pause audio functions + * + * These functions pause and unpause the audio callback processing. + * They should be called with a parameter of 0 after opening the audio + * device to start playing sound. This is so you can safely initialize + * data for your callback function after opening the audio device. + * Silence will be written to the audio device during the pause. + */ +/* @{ */ + +/** + * This function is a legacy means of pausing the audio device. + * + * New programs might want to use SDL_PauseAudioDevice() instead. This + * function is equivalent to calling... + * + * ```c + * SDL_PauseAudioDevice(1, pause_on); + * ``` + * + * ...and is only useful if you used the legacy SDL_OpenAudio() function. + * + * \param pause_on non-zero to pause, 0 to unpause + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetAudioStatus + * \sa SDL_PauseAudioDevice + */ +extern DECLSPEC void SDLCALL SDL_PauseAudio(int pause_on); + +/** + * Use this function to pause and unpause audio playback on a specified + * device. + * + * This function pauses and unpauses the audio callback processing for a given + * device. Newly-opened audio devices start in the paused state, so you must + * call this function with **pause_on**=0 after opening the specified audio + * device to start playing sound. This allows you to safely initialize data + * for your callback function after opening the audio device. Silence will be + * written to the audio device while paused, and the audio callback is + * guaranteed to not be called. Pausing one device does not prevent other + * unpaused devices from running their callbacks. + * + * Pausing state does not stack; even if you pause a device several times, a + * single unpause will start the device playing again, and vice versa. This is + * different from how SDL_LockAudioDevice() works. + * + * If you just need to protect a few variables from race conditions vs your + * callback, you shouldn't pause the audio device, as it will lead to dropouts + * in the audio playback. Instead, you should use SDL_LockAudioDevice(). + * + * \param dev a device opened by SDL_OpenAudioDevice() + * \param pause_on non-zero to pause, 0 to unpause + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LockAudioDevice + */ +extern DECLSPEC void SDLCALL SDL_PauseAudioDevice(SDL_AudioDeviceID dev, + int pause_on); +/* @} *//* Pause audio functions */ + +/** + * Load the audio data of a WAVE file into memory. + * + * Loading a WAVE file requires `src`, `spec`, `audio_buf` and `audio_len` to + * be valid pointers. The entire data portion of the file is then loaded into + * memory and decoded if necessary. + * + * If `freesrc` is non-zero, the data source gets automatically closed and + * freed before the function returns. + * + * Supported formats are RIFF WAVE files with the formats PCM (8, 16, 24, and + * 32 bits), IEEE Float (32 bits), Microsoft ADPCM and IMA ADPCM (4 bits), and + * A-law and mu-law (8 bits). Other formats are currently unsupported and + * cause an error. + * + * If this function succeeds, the pointer returned by it is equal to `spec` + * and the pointer to the audio data allocated by the function is written to + * `audio_buf` and its length in bytes to `audio_len`. The SDL_AudioSpec + * members `freq`, `channels`, and `format` are set to the values of the audio + * data in the buffer. The `samples` member is set to a sane default and all + * others are set to zero. + * + * It's necessary to use SDL_FreeWAV() to free the audio data returned in + * `audio_buf` when it is no longer used. + * + * Because of the underspecification of the .WAV format, there are many + * problematic files in the wild that cause issues with strict decoders. To + * provide compatibility with these files, this decoder is lenient in regards + * to the truncation of the file, the fact chunk, and the size of the RIFF + * chunk. The hints `SDL_HINT_WAVE_RIFF_CHUNK_SIZE`, + * `SDL_HINT_WAVE_TRUNCATION`, and `SDL_HINT_WAVE_FACT_CHUNK` can be used to + * tune the behavior of the loading process. + * + * Any file that is invalid (due to truncation, corruption, or wrong values in + * the headers), too big, or unsupported causes an error. Additionally, any + * critical I/O error from the data source will terminate the loading process + * with an error. The function returns NULL on error and in all cases (with + * the exception of `src` being NULL), an appropriate error message will be + * set. + * + * It is required that the data source supports seeking. + * + * Example: + * + * ```c + * SDL_LoadWAV_RW(SDL_RWFromFile("sample.wav", "rb"), 1, &spec, &buf, &len); + * ``` + * + * Note that the SDL_LoadWAV macro does this same thing for you, but in a less + * messy way: + * + * ```c + * SDL_LoadWAV("sample.wav", &spec, &buf, &len); + * ``` + * + * \param src The data source for the WAVE data + * \param freesrc If non-zero, SDL will _always_ free the data source + * \param spec An SDL_AudioSpec that will be filled in with the wave file's + * format details + * \param audio_buf A pointer filled with the audio data, allocated by the + * function. + * \param audio_len A pointer filled with the length of the audio data buffer + * in bytes + * \returns This function, if successfully called, returns `spec`, which will + * be filled with the audio data format of the wave source data. + * `audio_buf` will be filled with a pointer to an allocated buffer + * containing the audio data, and `audio_len` is filled with the + * length of that audio buffer in bytes. + * + * This function returns NULL if the .WAV file cannot be opened, uses + * an unknown data format, or is corrupt; call SDL_GetError() for + * more information. + * + * When the application is done with the data returned in + * `audio_buf`, it should call SDL_FreeWAV() to dispose of it. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_FreeWAV + * \sa SDL_LoadWAV + */ +extern DECLSPEC SDL_AudioSpec *SDLCALL SDL_LoadWAV_RW(SDL_RWops * src, + int freesrc, + SDL_AudioSpec * spec, + Uint8 ** audio_buf, + Uint32 * audio_len); + +/** + * Loads a WAV from a file. + * Compatibility convenience function. + */ +#define SDL_LoadWAV(file, spec, audio_buf, audio_len) \ + SDL_LoadWAV_RW(SDL_RWFromFile(file, "rb"),1, spec,audio_buf,audio_len) + +/** + * Free data previously allocated with SDL_LoadWAV() or SDL_LoadWAV_RW(). + * + * After a WAVE file has been opened with SDL_LoadWAV() or SDL_LoadWAV_RW() + * its data can eventually be freed with SDL_FreeWAV(). It is safe to call + * this function with a NULL pointer. + * + * \param audio_buf a pointer to the buffer created by SDL_LoadWAV() or + * SDL_LoadWAV_RW() + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LoadWAV + * \sa SDL_LoadWAV_RW + */ +extern DECLSPEC void SDLCALL SDL_FreeWAV(Uint8 * audio_buf); + +/** + * Initialize an SDL_AudioCVT structure for conversion. + * + * Before an SDL_AudioCVT structure can be used to convert audio data it must + * be initialized with source and destination information. + * + * This function will zero out every field of the SDL_AudioCVT, so it must be + * called before the application fills in the final buffer information. + * + * Once this function has returned successfully, and reported that a + * conversion is necessary, the application fills in the rest of the fields in + * SDL_AudioCVT, now that it knows how large a buffer it needs to allocate, + * and then can call SDL_ConvertAudio() to complete the conversion. + * + * \param cvt an SDL_AudioCVT structure filled in with audio conversion + * information + * \param src_format the source format of the audio data; for more info see + * SDL_AudioFormat + * \param src_channels the number of channels in the source + * \param src_rate the frequency (sample-frames-per-second) of the source + * \param dst_format the destination format of the audio data; for more info + * see SDL_AudioFormat + * \param dst_channels the number of channels in the destination + * \param dst_rate the frequency (sample-frames-per-second) of the destination + * \returns 1 if the audio filter is prepared, 0 if no conversion is needed, + * or a negative error code on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ConvertAudio + */ +extern DECLSPEC int SDLCALL SDL_BuildAudioCVT(SDL_AudioCVT * cvt, + SDL_AudioFormat src_format, + Uint8 src_channels, + int src_rate, + SDL_AudioFormat dst_format, + Uint8 dst_channels, + int dst_rate); + +/** + * Convert audio data to a desired audio format. + * + * This function does the actual audio data conversion, after the application + * has called SDL_BuildAudioCVT() to prepare the conversion information and + * then filled in the buffer details. + * + * Once the application has initialized the `cvt` structure using + * SDL_BuildAudioCVT(), allocated an audio buffer and filled it with audio + * data in the source format, this function will convert the buffer, in-place, + * to the desired format. + * + * The data conversion may go through several passes; any given pass may + * possibly temporarily increase the size of the data. For example, SDL might + * expand 16-bit data to 32 bits before resampling to a lower frequency, + * shrinking the data size after having grown it briefly. Since the supplied + * buffer will be both the source and destination, converting as necessary + * in-place, the application must allocate a buffer that will fully contain + * the data during its largest conversion pass. After SDL_BuildAudioCVT() + * returns, the application should set the `cvt->len` field to the size, in + * bytes, of the source data, and allocate a buffer that is `cvt->len * + * cvt->len_mult` bytes long for the `buf` field. + * + * The source data should be copied into this buffer before the call to + * SDL_ConvertAudio(). Upon successful return, this buffer will contain the + * converted audio, and `cvt->len_cvt` will be the size of the converted data, + * in bytes. Any bytes in the buffer past `cvt->len_cvt` are undefined once + * this function returns. + * + * \param cvt an SDL_AudioCVT structure that was previously set up by + * SDL_BuildAudioCVT(). + * \returns 0 if the conversion was completed successfully or a negative error + * code on failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_BuildAudioCVT + */ +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 + * \returns 0 on success, or -1 on error. + * + * \since This function is available since SDL 2.0.7. + * + * \sa SDL_AudioStreamPut + * \sa SDL_AudioStreamGet + * \sa SDL_AudioStreamAvailable + * \sa SDL_AudioStreamFlush + * \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 len The number of bytes to write to the stream + * \returns 0 on success, or -1 on error. + * + * \since This function is available since SDL 2.0.7. + * + * \sa SDL_NewAudioStream + * \sa SDL_AudioStreamGet + * \sa SDL_AudioStreamAvailable + * \sa SDL_AudioStreamFlush + * \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 + * \returns the number of bytes read from the stream, or -1 on error + * + * \since This function is available since SDL 2.0.7. + * + * \sa SDL_NewAudioStream + * \sa SDL_AudioStreamPut + * \sa SDL_AudioStreamAvailable + * \sa SDL_AudioStreamFlush + * \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. + * + * 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. + * + * \since This function is available since SDL 2.0.7. + * + * \sa SDL_NewAudioStream + * \sa SDL_AudioStreamPut + * \sa SDL_AudioStreamGet + * \sa SDL_AudioStreamFlush + * \sa SDL_AudioStreamClear + * \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. + * + * \since This function is available since SDL 2.0.7. + * + * \sa SDL_NewAudioStream + * \sa SDL_AudioStreamPut + * \sa SDL_AudioStreamGet + * \sa SDL_AudioStreamAvailable + * \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 + * + * \since This function is available since SDL 2.0.7. + * + * \sa SDL_NewAudioStream + * \sa SDL_AudioStreamPut + * \sa SDL_AudioStreamGet + * \sa SDL_AudioStreamAvailable + * \sa SDL_AudioStreamFlush + * \sa SDL_FreeAudioStream + */ +extern DECLSPEC void SDLCALL SDL_AudioStreamClear(SDL_AudioStream *stream); + +/** + * Free an audio stream + * + * \since This function is available since SDL 2.0.7. + * + * \sa SDL_NewAudioStream + * \sa SDL_AudioStreamPut + * \sa SDL_AudioStreamGet + * \sa SDL_AudioStreamAvailable + * \sa SDL_AudioStreamFlush + * \sa SDL_AudioStreamClear + */ +extern DECLSPEC void SDLCALL SDL_FreeAudioStream(SDL_AudioStream *stream); + +#define SDL_MIX_MAXVOLUME 128 + +/** + * This function is a legacy means of mixing audio. + * + * This function is equivalent to calling... + * + * ```c + * SDL_MixAudioFormat(dst, src, format, len, volume); + * ``` + * + * ...where `format` is the obtained format of the audio device from the + * legacy SDL_OpenAudio() function. + * + * \param dst the destination for the mixed audio + * \param src the source audio buffer to be mixed + * \param len the length of the audio buffer in bytes + * \param volume ranges from 0 - 128, and should be set to SDL_MIX_MAXVOLUME + * for full audio volume + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_MixAudioFormat + */ +extern DECLSPEC void SDLCALL SDL_MixAudio(Uint8 * dst, const Uint8 * src, + Uint32 len, int volume); + +/** + * Mix audio data in a specified format. + * + * This takes an audio buffer `src` of `len` bytes of `format` data and mixes + * it into `dst`, performing addition, volume adjustment, and overflow + * clipping. The buffer pointed to by `dst` must also be `len` bytes of + * `format` data. + * + * This is provided for convenience -- you can mix your own audio data. + * + * Do not use this function for mixing together more than two streams of + * sample data. The output from repeated application of this function may be + * distorted by clipping, because there is no accumulator with greater range + * than the input (not to mention this being an inefficient way of doing it). + * + * It is a common misconception that this function is required to write audio + * data to an output stream in an audio callback. While you can do that, + * SDL_MixAudioFormat() is really only needed when you're mixing a single + * audio stream with a volume adjustment. + * + * \param dst the destination for the mixed audio + * \param src the source audio buffer to be mixed + * \param format the SDL_AudioFormat structure representing the desired audio + * format + * \param len the length of the audio buffer in bytes + * \param volume ranges from 0 - 128, and should be set to SDL_MIX_MAXVOLUME + * for full audio volume + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC void SDLCALL SDL_MixAudioFormat(Uint8 * dst, + const Uint8 * src, + SDL_AudioFormat format, + Uint32 len, int volume); + +/** + * Queue more audio on non-callback devices. + * + * If you are looking to retrieve queued audio from a non-callback capture + * device, you want SDL_DequeueAudio() instead. SDL_QueueAudio() will return + * -1 to signify an error if you use it with capture devices. + * + * SDL offers two ways to feed audio to the device: you can either supply a + * callback that SDL triggers with some frequency to obtain more audio (pull + * method), or you can supply no callback, and then SDL will expect you to + * supply data at regular intervals (push method) with this function. + * + * There are no limits on the amount of data you can queue, short of + * exhaustion of address space. Queued data will drain to the device as + * necessary without further intervention from you. If the device needs audio + * but there is not enough queued, it will play silence to make up the + * difference. This means you will have skips in your audio playback if you + * aren't routinely queueing sufficient data. + * + * This function copies the supplied data, so you are safe to free it when the + * function returns. This function is thread-safe, but queueing to the same + * device from two threads at once does not promise which buffer will be + * queued first. + * + * You may not queue audio on a device that is using an application-supplied + * callback; doing so returns an error. You have to use the audio callback or + * queue audio with this function, but not both. + * + * You should not call SDL_LockAudio() on the device before queueing; SDL + * handles locking internally for this function. + * + * Note that SDL2 does not support planar audio. You will need to resample + * from planar audio formats into a non-planar one (see SDL_AudioFormat) + * before queuing audio. + * + * \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 + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.4. + * + * \sa SDL_ClearQueuedAudio + * \sa SDL_GetQueuedAudioSize + */ +extern DECLSPEC int SDLCALL SDL_QueueAudio(SDL_AudioDeviceID dev, const void *data, Uint32 len); + +/** + * Dequeue more audio on non-callback devices. + * + * If you are looking to queue audio for output on a non-callback playback + * device, you want SDL_QueueAudio() instead. SDL_DequeueAudio() will always + * return 0 if you use it with playback devices. + * + * SDL offers two ways to retrieve audio from a capture device: you can either + * supply a callback that SDL triggers with some frequency as the device + * records more audio data, (push method), or you can supply no callback, and + * then SDL will expect you to retrieve data at regular intervals (pull + * method) with this function. + * + * There are no limits on the amount of data you can queue, short of + * exhaustion of address space. Data from the device will keep queuing as + * necessary without further intervention from you. This means you will + * eventually run out of memory if you aren't routinely dequeueing data. + * + * Capture devices will not queue data when paused; if you are expecting to + * not need captured audio for some length of time, use SDL_PauseAudioDevice() + * to stop the capture device from queueing more data. This can be useful + * during, say, level loading times. When unpaused, capture devices will start + * queueing data from that point, having flushed any capturable data available + * while paused. + * + * This function is thread-safe, but dequeueing from the same device from two + * threads at once does not promise which thread will dequeue data first. + * + * You may not dequeue audio from a device that is using an + * application-supplied callback; doing so returns an error. You have to use + * the audio callback, or dequeue audio with this function, but not both. + * + * You should not call SDL_LockAudio() on the device before dequeueing; SDL + * handles locking internally for this function. + * + * \param dev the device ID from which we will dequeue audio + * \param data a pointer into where audio data should be copied + * \param len the number of bytes (not samples!) to which (data) points + * \returns the number of bytes dequeued, which could be less than requested; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.5. + * + * \sa SDL_ClearQueuedAudio + * \sa SDL_GetQueuedAudioSize + */ +extern DECLSPEC Uint32 SDLCALL SDL_DequeueAudio(SDL_AudioDeviceID dev, void *data, Uint32 len); + +/** + * Get the number of bytes of still-queued audio. + * + * For playback devices: this is the number of bytes that have been queued for + * playback with SDL_QueueAudio(), but have not yet been sent to the hardware. + * + * Once we've sent it to the hardware, this function can not decide the exact + * byte boundary of what has been played. It's possible that we just gave the + * hardware several kilobytes right before you called this function, but it + * hasn't played any of it yet, or maybe half of it, etc. + * + * For capture devices, this is the number of bytes that have been captured by + * the device and are waiting for you to dequeue. This number may grow at any + * time, so this only informs of the lower-bound of available data. + * + * You may not queue or dequeue audio on a device that is using an + * application-supplied callback; calling this function on such a device + * always returns 0. You have to use the audio callback or queue audio, but + * not both. + * + * You should not call SDL_LockAudio() on the device before querying; SDL + * handles locking internally for this function. + * + * \param dev the device ID of which we will query queued audio size + * \returns the number of bytes (not samples!) of queued audio. + * + * \since This function is available since SDL 2.0.4. + * + * \sa SDL_ClearQueuedAudio + * \sa SDL_QueueAudio + * \sa SDL_DequeueAudio + */ +extern DECLSPEC Uint32 SDLCALL SDL_GetQueuedAudioSize(SDL_AudioDeviceID dev); + +/** + * Drop any queued audio data waiting to be sent to the hardware. + * + * Immediately after this call, SDL_GetQueuedAudioSize() will return 0. For + * output devices, the hardware will start playing silence if more audio isn't + * queued. For capture devices, the hardware will start filling the empty + * queue with new data if the capture device isn't paused. + * + * This will not prevent playback of queued audio that's already been sent to + * the hardware, as we can not undo that, so expect there to be some fraction + * of a second of audio that might still be heard. This can be useful if you + * want to, say, drop any pending music or any unprocessed microphone input + * during a level change in your game. + * + * You may not queue or dequeue audio on a device that is using an + * application-supplied callback; calling this function on such a device + * always returns 0. You have to use the audio callback or queue audio, but + * not both. + * + * You should not call SDL_LockAudio() on the device before clearing the + * queue; SDL handles locking internally for this function. + * + * This function always succeeds and thus returns void. + * + * \param dev the device ID of which to clear the audio queue + * + * \since This function is available since SDL 2.0.4. + * + * \sa SDL_GetQueuedAudioSize + * \sa SDL_QueueAudio + * \sa SDL_DequeueAudio + */ +extern DECLSPEC void SDLCALL SDL_ClearQueuedAudio(SDL_AudioDeviceID dev); + + +/** + * \name Audio lock functions + * + * The lock manipulated by these functions protects the callback function. + * During a SDL_LockAudio()/SDL_UnlockAudio() pair, you can be guaranteed that + * the callback function is not running. Do not call these from the callback + * function or you will cause deadlock. + */ +/* @{ */ + +/** + * This function is a legacy means of locking the audio device. + * + * New programs might want to use SDL_LockAudioDevice() instead. This function + * is equivalent to calling... + * + * ```c + * SDL_LockAudioDevice(1); + * ``` + * + * ...and is only useful if you used the legacy SDL_OpenAudio() function. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LockAudioDevice + * \sa SDL_UnlockAudio + * \sa SDL_UnlockAudioDevice + */ +extern DECLSPEC void SDLCALL SDL_LockAudio(void); + +/** + * Use this function to lock out the audio callback function for a specified + * device. + * + * The lock manipulated by these functions protects the audio callback + * function specified in SDL_OpenAudioDevice(). During a + * SDL_LockAudioDevice()/SDL_UnlockAudioDevice() pair, you can be guaranteed + * that the callback function for that device is not running, even if the + * device is not paused. While a device is locked, any other unpaused, + * unlocked devices may still run their callbacks. + * + * Calling this function from inside your audio callback is unnecessary. SDL + * obtains this lock before calling your function, and releases it when the + * function returns. + * + * You should not hold the lock longer than absolutely necessary. If you hold + * it too long, you'll experience dropouts in your audio playback. Ideally, + * your application locks the device, sets a few variables and unlocks again. + * Do not do heavy work while holding the lock for a device. + * + * It is safe to lock the audio device multiple times, as long as you unlock + * it an equivalent number of times. The callback will not run until the + * device has been unlocked completely in this way. If your application fails + * to unlock the device appropriately, your callback will never run, you might + * hear repeating bursts of audio, and SDL_CloseAudioDevice() will probably + * deadlock. + * + * Internally, the audio device lock is a mutex; if you lock from two threads + * at once, not only will you block the audio callback, you'll block the other + * thread. + * + * \param dev the ID of the device to be locked + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_UnlockAudioDevice + */ +extern DECLSPEC void SDLCALL SDL_LockAudioDevice(SDL_AudioDeviceID dev); + +/** + * This function is a legacy means of unlocking the audio device. + * + * New programs might want to use SDL_UnlockAudioDevice() instead. This + * function is equivalent to calling... + * + * ```c + * SDL_UnlockAudioDevice(1); + * ``` + * + * ...and is only useful if you used the legacy SDL_OpenAudio() function. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LockAudio + * \sa SDL_UnlockAudioDevice + */ +extern DECLSPEC void SDLCALL SDL_UnlockAudio(void); + +/** + * Use this function to unlock the audio callback function for a specified + * device. + * + * This function should be paired with a previous SDL_LockAudioDevice() call. + * + * \param dev the ID of the device to be unlocked + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LockAudioDevice + */ +extern DECLSPEC void SDLCALL SDL_UnlockAudioDevice(SDL_AudioDeviceID dev); +/* @} *//* Audio lock functions */ + +/** + * This function is a legacy means of closing the audio device. + * + * This function is equivalent to calling... + * + * ```c + * SDL_CloseAudioDevice(1); + * ``` + * + * ...and is only useful if you used the legacy SDL_OpenAudio() function. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_OpenAudio + */ +extern DECLSPEC void SDLCALL SDL_CloseAudio(void); + +/** + * Use this function to shut down audio processing and close the audio device. + * + * The application should close open audio devices once they are no longer + * needed. Calling this function will wait until the device's audio callback + * is not running, release the audio hardware and then clean up internal + * state. No further audio will play from this device once this function + * returns. + * + * This function may block briefly while pending audio data is played by the + * hardware, so that applications don't drop the last buffer of data they + * supplied. + * + * The device ID is invalid as soon as the device is closed, and is eligible + * for reuse in a new SDL_OpenAudioDevice() call immediately. + * + * \param dev an audio device previously opened with SDL_OpenAudioDevice() + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_OpenAudioDevice + */ +extern DECLSPEC void SDLCALL SDL_CloseAudioDevice(SDL_AudioDeviceID dev); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_audio_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/include/SDL_bits.h b/SDL2-2.30.5/include/SDL_bits.h similarity index 88% rename from SDL2-2.0.12/include/SDL_bits.h rename to SDL2-2.30.5/include/SDL_bits.h index db150ed..83e8a78 100644 --- a/SDL2-2.0.12/include/SDL_bits.h +++ b/SDL2-2.30.5/include/SDL_bits.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -45,13 +45,12 @@ extern "C" { * with 0. This operation can also be stated as "count leading zeroes" and * "log base 2". * - * \return Index of the most significant bit, or -1 if the value is 0. + * \return the index of the most significant bit, or -1 if the value is 0. */ #if defined(__WATCOMC__) && defined(__386__) -extern _inline int _SDL_clz_watcom (Uint32); -#pragma aux _SDL_clz_watcom = \ +extern __inline int _SDL_bsr_watcom(Uint32); +#pragma aux _SDL_bsr_watcom = \ "bsr eax, eax" \ - "xor eax, 31" \ parm [eax] nomemory \ value [eax] \ modify exact [eax] nomemory; @@ -72,7 +71,13 @@ SDL_MostSignificantBitIndex32(Uint32 x) if (x == 0) { return -1; } - return 31 - _SDL_clz_watcom(x); + return _SDL_bsr_watcom(x); +#elif defined(_MSC_VER) + unsigned long index; + if (_BitScanReverse(&index, x)) { + return index; + } + return -1; #else /* Based off of Bit Twiddling Hacks by Sean Eron Anderson * , released in the public domain. diff --git a/SDL2-2.30.5/include/SDL_blendmode.h b/SDL2-2.30.5/include/SDL_blendmode.h new file mode 100644 index 0000000..09d0147 --- /dev/null +++ b/SDL2-2.30.5/include/SDL_blendmode.h @@ -0,0 +1,198 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_blendmode.h + * + * Header file declaring the SDL_BlendMode enumeration + */ + +#ifndef SDL_blendmode_h_ +#define SDL_blendmode_h_ + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief The blend mode used in SDL_RenderCopy() and drawing operations. + */ +typedef enum +{ + SDL_BLENDMODE_NONE = 0x00000000, /**< no blending + dstRGBA = srcRGBA */ + SDL_BLENDMODE_BLEND = 0x00000001, /**< alpha blending + dstRGB = (srcRGB * srcA) + (dstRGB * (1-srcA)) + dstA = srcA + (dstA * (1-srcA)) */ + SDL_BLENDMODE_ADD = 0x00000002, /**< additive blending + dstRGB = (srcRGB * srcA) + dstRGB + dstA = dstA */ + SDL_BLENDMODE_MOD = 0x00000004, /**< color modulate + dstRGB = srcRGB * dstRGB + dstA = dstA */ + SDL_BLENDMODE_MUL = 0x00000008, /**< color multiply + dstRGB = (srcRGB * dstRGB) + (dstRGB * (1-srcA)) + dstA = dstA */ + SDL_BLENDMODE_INVALID = 0x7FFFFFFF + + /* Additional custom blend modes can be returned by SDL_ComposeCustomBlendMode() */ + +} SDL_BlendMode; + +/** + * \brief The blend operation used when combining source and destination pixel components + */ +typedef enum +{ + SDL_BLENDOPERATION_ADD = 0x1, /**< dst + src: supported by all renderers */ + SDL_BLENDOPERATION_SUBTRACT = 0x2, /**< src - dst : supported by D3D9, D3D11, OpenGL, OpenGLES */ + SDL_BLENDOPERATION_REV_SUBTRACT = 0x3, /**< dst - src : supported by D3D9, D3D11, OpenGL, OpenGLES */ + SDL_BLENDOPERATION_MINIMUM = 0x4, /**< min(dst, src) : supported by D3D9, D3D11 */ + SDL_BLENDOPERATION_MAXIMUM = 0x5 /**< max(dst, src) : supported by D3D9, D3D11 */ +} SDL_BlendOperation; + +/** + * \brief The normalized factor used to multiply pixel components + */ +typedef enum +{ + SDL_BLENDFACTOR_ZERO = 0x1, /**< 0, 0, 0, 0 */ + SDL_BLENDFACTOR_ONE = 0x2, /**< 1, 1, 1, 1 */ + SDL_BLENDFACTOR_SRC_COLOR = 0x3, /**< srcR, srcG, srcB, srcA */ + SDL_BLENDFACTOR_ONE_MINUS_SRC_COLOR = 0x4, /**< 1-srcR, 1-srcG, 1-srcB, 1-srcA */ + SDL_BLENDFACTOR_SRC_ALPHA = 0x5, /**< srcA, srcA, srcA, srcA */ + SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA = 0x6, /**< 1-srcA, 1-srcA, 1-srcA, 1-srcA */ + SDL_BLENDFACTOR_DST_COLOR = 0x7, /**< dstR, dstG, dstB, dstA */ + SDL_BLENDFACTOR_ONE_MINUS_DST_COLOR = 0x8, /**< 1-dstR, 1-dstG, 1-dstB, 1-dstA */ + SDL_BLENDFACTOR_DST_ALPHA = 0x9, /**< dstA, dstA, dstA, dstA */ + SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA = 0xA /**< 1-dstA, 1-dstA, 1-dstA, 1-dstA */ +} SDL_BlendFactor; + +/** + * Compose a custom blend mode for renderers. + * + * The functions SDL_SetRenderDrawBlendMode and SDL_SetTextureBlendMode accept + * the SDL_BlendMode returned by this function if the renderer supports it. + * + * A blend mode controls how the pixels from a drawing operation (source) get + * combined with the pixels from the render target (destination). First, the + * components of the source and destination pixels get multiplied with their + * blend factors. Then, the blend operation takes the two products and + * calculates the result that will get stored in the render target. + * + * Expressed in pseudocode, it would look like this: + * + * ```c + * dstRGB = colorOperation(srcRGB * srcColorFactor, dstRGB * dstColorFactor); + * dstA = alphaOperation(srcA * srcAlphaFactor, dstA * dstAlphaFactor); + * ``` + * + * Where the functions `colorOperation(src, dst)` and `alphaOperation(src, + * dst)` can return one of the following: + * + * - `src + dst` + * - `src - dst` + * - `dst - src` + * - `min(src, dst)` + * - `max(src, dst)` + * + * The red, green, and blue components are always multiplied with the first, + * second, and third components of the SDL_BlendFactor, respectively. The + * fourth component is not used. + * + * The alpha component is always multiplied with the fourth component of the + * SDL_BlendFactor. The other components are not used in the alpha + * calculation. + * + * Support for these blend modes varies for each renderer. To check if a + * specific SDL_BlendMode is supported, create a renderer and pass it to + * either SDL_SetRenderDrawBlendMode or SDL_SetTextureBlendMode. They will + * return with an error if the blend mode is not supported. + * + * This list describes the support of custom blend modes for each renderer in + * SDL 2.0.6. All renderers support the four blend modes listed in the + * SDL_BlendMode enumeration. + * + * - **direct3d**: Supports all operations with all factors. However, some + * factors produce unexpected results with `SDL_BLENDOPERATION_MINIMUM` and + * `SDL_BLENDOPERATION_MAXIMUM`. + * - **direct3d11**: Same as Direct3D 9. + * - **opengl**: Supports the `SDL_BLENDOPERATION_ADD` operation with all + * factors. OpenGL versions 1.1, 1.2, and 1.3 do not work correctly with SDL + * 2.0.6. + * - **opengles**: Supports the `SDL_BLENDOPERATION_ADD` operation with all + * factors. Color and alpha factors need to be the same. OpenGL ES 1 + * implementation specific: May also support `SDL_BLENDOPERATION_SUBTRACT` + * and `SDL_BLENDOPERATION_REV_SUBTRACT`. May support color and alpha + * operations being different from each other. May support color and alpha + * factors being different from each other. + * - **opengles2**: Supports the `SDL_BLENDOPERATION_ADD`, + * `SDL_BLENDOPERATION_SUBTRACT`, `SDL_BLENDOPERATION_REV_SUBTRACT` + * operations with all factors. + * - **psp**: No custom blend mode support. + * - **software**: No custom blend mode support. + * + * Some renderers do not provide an alpha component for the default render + * target. The `SDL_BLENDFACTOR_DST_ALPHA` and + * `SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA` factors do not have an effect in this + * case. + * + * \param srcColorFactor the SDL_BlendFactor applied to the red, green, and + * blue components of the source pixels + * \param dstColorFactor the SDL_BlendFactor applied to the red, green, and + * blue components of the destination pixels + * \param colorOperation the SDL_BlendOperation used to combine the red, + * green, and blue components of the source and + * destination pixels + * \param srcAlphaFactor the SDL_BlendFactor applied to the alpha component of + * the source pixels + * \param dstAlphaFactor the SDL_BlendFactor applied to the alpha component of + * the destination pixels + * \param alphaOperation the SDL_BlendOperation used to combine the alpha + * component of the source and destination pixels + * \returns an SDL_BlendMode that represents the chosen factors and + * operations. + * + * \since This function is available since SDL 2.0.6. + * + * \sa SDL_SetRenderDrawBlendMode + * \sa SDL_GetRenderDrawBlendMode + * \sa SDL_SetTextureBlendMode + * \sa SDL_GetTextureBlendMode + */ +extern DECLSPEC SDL_BlendMode SDLCALL SDL_ComposeCustomBlendMode(SDL_BlendFactor srcColorFactor, + SDL_BlendFactor dstColorFactor, + SDL_BlendOperation colorOperation, + SDL_BlendFactor srcAlphaFactor, + SDL_BlendFactor dstAlphaFactor, + SDL_BlendOperation alphaOperation); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_blendmode_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/include/SDL_clipboard.h b/SDL2-2.30.5/include/SDL_clipboard.h new file mode 100644 index 0000000..bd4b044 --- /dev/null +++ b/SDL2-2.30.5/include/SDL_clipboard.h @@ -0,0 +1,141 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_clipboard.h + * + * Include file for SDL clipboard handling + */ + +#ifndef SDL_clipboard_h_ +#define SDL_clipboard_h_ + +#include "SDL_stdinc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Function prototypes */ + +/** + * Put UTF-8 text into the clipboard. + * + * \param text the text to store in the clipboard + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetClipboardText + * \sa SDL_HasClipboardText + */ +extern DECLSPEC int SDLCALL SDL_SetClipboardText(const char *text); + +/** + * Get UTF-8 text from the clipboard, which must be freed with SDL_free(). + * + * This functions returns empty string if there was not enough memory left for + * a copy of the clipboard's content. + * + * \returns the clipboard text on success or an empty string on failure; call + * SDL_GetError() for more information. Caller must call SDL_free() + * on the returned pointer when done with it (even if there was an + * error). + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HasClipboardText + * \sa SDL_SetClipboardText + */ +extern DECLSPEC char * SDLCALL SDL_GetClipboardText(void); + +/** + * Query whether the clipboard exists and contains a non-empty text string. + * + * \returns SDL_TRUE if the clipboard has text, or SDL_FALSE if it does not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetClipboardText + * \sa SDL_SetClipboardText + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasClipboardText(void); + +/** + * Put UTF-8 text into the primary selection. + * + * \param text the text to store in the primary selection + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.26.0. + * + * \sa SDL_GetPrimarySelectionText + * \sa SDL_HasPrimarySelectionText + */ +extern DECLSPEC int SDLCALL SDL_SetPrimarySelectionText(const char *text); + +/** + * Get UTF-8 text from the primary selection, which must be freed with + * SDL_free(). + * + * This functions returns empty string if there was not enough memory left for + * a copy of the primary selection's content. + * + * \returns the primary selection text on success or an empty string on + * failure; call SDL_GetError() for more information. Caller must + * call SDL_free() on the returned pointer when done with it (even if + * there was an error). + * + * \since This function is available since SDL 2.26.0. + * + * \sa SDL_HasPrimarySelectionText + * \sa SDL_SetPrimarySelectionText + */ +extern DECLSPEC char * SDLCALL SDL_GetPrimarySelectionText(void); + +/** + * Query whether the primary selection exists and contains a non-empty text + * string. + * + * \returns SDL_TRUE if the primary selection has text, or SDL_FALSE if it + * does not. + * + * \since This function is available since SDL 2.26.0. + * + * \sa SDL_GetPrimarySelectionText + * \sa SDL_SetPrimarySelectionText + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasPrimarySelectionText(void); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_clipboard_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/include/SDL_config.h b/SDL2-2.30.5/include/SDL_config.h similarity index 83% rename from SDL2-2.0.12/include/SDL_config.h rename to SDL2-2.30.5/include/SDL_config.h index 3937dbc..49605b1 100644 --- a/SDL2-2.0.12/include/SDL_config.h +++ b/SDL2-2.30.5/include/SDL_config.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -33,16 +33,22 @@ #include "SDL_config_windows.h" #elif defined(__WINRT__) #include "SDL_config_winrt.h" +#elif defined(__WINGDK__) +#include "SDL_config_wingdk.h" +#elif defined(__XBOXONE__) || defined(__XBOXSERIES__) +#include "SDL_config_xbox.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" #elif defined(__OS2__) #include "SDL_config_os2.h" +#elif defined(__EMSCRIPTEN__) +#include "SDL_config_emscripten.h" +#elif defined(__NGAGE__) +#include "SDL_config_ngage.h" #else /* This is a minimal configuration just to get SDL running on new platforms. */ #include "SDL_config_minimal.h" diff --git a/SDL2-2.0.12/include/SDL_config.h.in b/SDL2-2.30.5/include/SDL_config.h.in similarity index 82% rename from SDL2-2.0.12/include/SDL_config.h.in rename to SDL2-2.30.5/include/SDL_config.h.in index f769e3c..f5dd166 100644 --- a/SDL2-2.0.12/include/SDL_config.h.in +++ b/SDL2-2.30.5/include/SDL_config.h.in @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -33,7 +33,7 @@ /* Make sure that this isn't included by Visual C++ */ #ifdef _MSC_VER -#error You should run hg revert SDL_config.h +#error You should run git checkout -f include/SDL_config.h #endif /* C language features */ @@ -42,17 +42,18 @@ #undef volatile /* C datatypes */ -#ifdef __LP64__ +#if defined(__LP64__) || defined(_LP64) || defined(_WIN64) #define SIZEOF_VOIDP 8 #else #define SIZEOF_VOIDP 4 #endif + #undef HAVE_GCC_ATOMICS #undef HAVE_GCC_SYNC_LOCK_TEST_AND_SET /* Comment this if you want to build without any C library requirements */ #undef HAVE_LIBC -#if HAVE_LIBC +#ifdef HAVE_LIBC /* Useful headers */ #undef STDC_HEADERS @@ -74,10 +75,12 @@ #undef HAVE_STRING_H #undef HAVE_SYS_TYPES_H #undef HAVE_WCHAR_H +#undef HAVE_LINUX_INPUT_H #undef HAVE_PTHREAD_NP_H #undef HAVE_LIBUNWIND_H /* C library functions */ +#undef HAVE_DLOPEN #undef HAVE_MALLOC #undef HAVE_CALLOC #undef HAVE_REALLOC @@ -90,6 +93,7 @@ #undef HAVE_UNSETENV #endif #undef HAVE_QSORT +#undef HAVE_BSEARCH #undef HAVE_ABS #undef HAVE_BCOPY #undef HAVE_MEMSET @@ -99,10 +103,15 @@ #undef HAVE_WCSLEN #undef HAVE_WCSLCPY #undef HAVE_WCSLCAT +#undef HAVE__WCSDUP #undef HAVE_WCSDUP #undef HAVE_WCSSTR #undef HAVE_WCSCMP #undef HAVE_WCSNCMP +#undef HAVE_WCSCASECMP +#undef HAVE__WCSICMP +#undef HAVE_WCSNCASECMP +#undef HAVE__WCSNICMP #undef HAVE_STRLEN #undef HAVE_STRLCPY #undef HAVE_STRLCAT @@ -115,7 +124,6 @@ #undef HAVE_STRRCHR #undef HAVE_STRSTR #undef HAVE_STRTOK_R -#undef HAVE_STRTOK_S #undef HAVE_ITOA #undef HAVE__LTOA #undef HAVE__UITOA @@ -135,6 +143,7 @@ #undef HAVE_STRCASECMP #undef HAVE__STRNICMP #undef HAVE_STRNCASECMP +#undef HAVE_STRCASESTR #undef HAVE_SSCANF #undef HAVE_VSSCANF #undef HAVE_SNPRINTF @@ -166,8 +175,12 @@ #undef HAVE_LOGF #undef HAVE_LOG10 #undef HAVE_LOG10F +#undef HAVE_LROUND +#undef HAVE_LROUNDF #undef HAVE_POW #undef HAVE_POWF +#undef HAVE_ROUND +#undef HAVE_ROUNDF #undef HAVE_SCALBN #undef HAVE_SCALBNF #undef HAVE_SIN @@ -176,6 +189,8 @@ #undef HAVE_SQRTF #undef HAVE_TAN #undef HAVE_TANF +#undef HAVE_TRUNC +#undef HAVE_TRUNCF #undef HAVE_FOPEN64 #undef HAVE_FSEEKO #undef HAVE_FSEEKO64 @@ -189,11 +204,15 @@ #undef HAVE_GETPAGESIZE #undef HAVE_MPROTECT #undef HAVE_ICONV +#undef SDL_USE_LIBICONV #undef HAVE_PTHREAD_SETNAME_NP #undef HAVE_PTHREAD_SET_NAME_NP #undef HAVE_SEM_TIMEDWAIT #undef HAVE_GETAUXVAL +#undef HAVE_ELF_AUX_INFO #undef HAVE_POLL +#undef HAVE_MEMFD_CREATE +#undef HAVE_POSIX_FALLOCATE #undef HAVE__EXIT #else @@ -202,23 +221,36 @@ #define HAVE_STDINT_H 1 #endif /* HAVE_LIBC */ +#undef HAVE_O_CLOEXEC #undef HAVE_ALTIVEC_H #undef HAVE_DBUS_DBUS_H -#undef HAVE_FCITX_FRONTEND_H +#undef HAVE_FCITX +#undef HAVE_SYS_INOTIFY_H +#undef HAVE_INOTIFY_INIT +#undef HAVE_INOTIFY_INIT1 +#undef HAVE_INOTIFY #undef HAVE_IBUS_IBUS_H #undef HAVE_IMMINTRIN_H -#undef HAVE_LIBSAMPLERATE_H #undef HAVE_LIBUDEV_H +#undef HAVE_LIBUSB +#undef HAVE_LIBSAMPLERATE_H +#undef HAVE_LIBDECOR_H +#undef HAVE_LSXINTRIN_H +#undef HAVE_LASXINTRIN_H #undef HAVE_DDRAW_H #undef HAVE_DINPUT_H #undef HAVE_DSOUND_H #undef HAVE_DXGI_H +#undef HAVE_WINDOWS_GAMING_INPUT_H #undef HAVE_XINPUT_H + #undef HAVE_MMDEVICEAPI_H #undef HAVE_AUDIOCLIENT_H -#undef HAVE_XINPUT_GAMEPAD_EX -#undef HAVE_XINPUT_STATE_EX +#undef HAVE_TPCSHRD_H +#undef HAVE_SENSORSAPI_H +#undef HAVE_ROAPI_H +#undef HAVE_SHELLSCALINGAPI_H /* SDL internal assertion support */ #undef SDL_DEFAULT_ASSERT_LEVEL @@ -231,6 +263,7 @@ #undef SDL_FILE_DISABLED #undef SDL_JOYSTICK_DISABLED #undef SDL_HAPTIC_DISABLED +#undef SDL_HIDAPI_DISABLED #undef SDL_SENSOR_DISABLED #undef SDL_LOADSO_DISABLED #undef SDL_RENDER_DISABLED @@ -239,8 +272,11 @@ #undef SDL_VIDEO_DISABLED #undef SDL_POWER_DISABLED #undef SDL_FILESYSTEM_DISABLED +#undef SDL_LOCALE_DISABLED +#undef SDL_MISC_DISABLED /* Enable various audio drivers */ +#undef SDL_AUDIO_DRIVER_AAUDIO #undef SDL_AUDIO_DRIVER_ALSA #undef SDL_AUDIO_DRIVER_ALSA_DYNAMIC #undef SDL_AUDIO_DRIVER_ANDROID @@ -262,9 +298,11 @@ #undef SDL_AUDIO_DRIVER_NAS #undef SDL_AUDIO_DRIVER_NAS_DYNAMIC #undef SDL_AUDIO_DRIVER_NETBSD +#undef SDL_AUDIO_DRIVER_OPENSLES #undef SDL_AUDIO_DRIVER_OSS -#undef SDL_AUDIO_DRIVER_OSS_SOUNDCARD_H #undef SDL_AUDIO_DRIVER_PAUDIO +#undef SDL_AUDIO_DRIVER_PIPEWIRE +#undef SDL_AUDIO_DRIVER_PIPEWIRE_DYNAMIC #undef SDL_AUDIO_DRIVER_PULSEAUDIO #undef SDL_AUDIO_DRIVER_PULSEAUDIO_DYNAMIC #undef SDL_AUDIO_DRIVER_QSA @@ -273,23 +311,29 @@ #undef SDL_AUDIO_DRIVER_SUNAUDIO #undef SDL_AUDIO_DRIVER_WASAPI #undef SDL_AUDIO_DRIVER_WINMM +#undef SDL_AUDIO_DRIVER_OS2 /* Enable various input drivers */ #undef SDL_INPUT_LINUXEV +#undef SDL_INPUT_FBSDKBIO #undef SDL_INPUT_LINUXKD -#undef SDL_INPUT_TSLIB +#undef SDL_INPUT_WSCONS #undef SDL_JOYSTICK_HAIKU #undef SDL_JOYSTICK_DINPUT +#undef SDL_JOYSTICK_WGI #undef SDL_JOYSTICK_XINPUT #undef SDL_JOYSTICK_DUMMY #undef SDL_JOYSTICK_IOKIT +#undef SDL_JOYSTICK_MFI #undef SDL_JOYSTICK_LINUX #undef SDL_JOYSTICK_ANDROID -#undef SDL_JOYSTICK_WINMM +#undef SDL_JOYSTICK_OS2 #undef SDL_JOYSTICK_USBHID -#undef SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H +#undef SDL_HAVE_MACHINE_JOYSTICK_H #undef SDL_JOYSTICK_HIDAPI +#undef SDL_JOYSTICK_RAWINPUT #undef SDL_JOYSTICK_EMSCRIPTEN +#undef SDL_JOYSTICK_VIRTUAL #undef SDL_HAPTIC_DUMMY #undef SDL_HAPTIC_ANDROID #undef SDL_HAPTIC_LINUX @@ -299,6 +343,8 @@ /* Enable various sensor drivers */ #undef SDL_SENSOR_ANDROID +#undef SDL_SENSOR_COREMOTION +#undef SDL_SENSOR_WINDOWS #undef SDL_SENSOR_DUMMY /* Enable various shared object loading systems */ @@ -306,18 +352,22 @@ #undef SDL_LOADSO_DUMMY #undef SDL_LOADSO_LDG #undef SDL_LOADSO_WINDOWS +#undef SDL_LOADSO_OS2 /* Enable various threading systems */ +#undef SDL_THREAD_GENERIC_COND_SUFFIX #undef SDL_THREAD_PTHREAD #undef SDL_THREAD_PTHREAD_RECURSIVE_MUTEX #undef SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP #undef SDL_THREAD_WINDOWS +#undef SDL_THREAD_OS2 /* Enable various timer systems */ #undef SDL_TIMER_HAIKU #undef SDL_TIMER_DUMMY #undef SDL_TIMER_UNIX #undef SDL_TIMER_WINDOWS +#undef SDL_TIMER_OS2 /* Enable various video drivers */ #undef SDL_VIDEO_DRIVER_HAIKU @@ -332,6 +382,7 @@ #undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL #undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR #undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON +#undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR #undef SDL_VIDEO_DRIVER_X11 #undef SDL_VIDEO_DRIVER_RPI #undef SDL_VIDEO_DRIVER_KMSDRM @@ -339,33 +390,34 @@ #undef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC_GBM #undef SDL_VIDEO_DRIVER_ANDROID #undef SDL_VIDEO_DRIVER_EMSCRIPTEN +#undef SDL_VIDEO_DRIVER_OFFSCREEN #undef SDL_VIDEO_DRIVER_X11_DYNAMIC #undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT #undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR -#undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA #undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2 +#undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XFIXES #undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR #undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS -#undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE #undef SDL_VIDEO_DRIVER_X11_XCURSOR #undef SDL_VIDEO_DRIVER_X11_XDBE -#undef SDL_VIDEO_DRIVER_X11_XINERAMA #undef SDL_VIDEO_DRIVER_X11_XINPUT2 #undef SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH +#undef SDL_VIDEO_DRIVER_X11_XFIXES #undef SDL_VIDEO_DRIVER_X11_XRANDR #undef SDL_VIDEO_DRIVER_X11_XSCRNSAVER #undef SDL_VIDEO_DRIVER_X11_XSHAPE -#undef SDL_VIDEO_DRIVER_X11_XVIDMODE #undef SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS -#undef SDL_VIDEO_DRIVER_X11_CONST_PARAM_XEXTADDDISPLAY #undef SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM #undef SDL_VIDEO_DRIVER_NACL #undef SDL_VIDEO_DRIVER_VIVANTE #undef SDL_VIDEO_DRIVER_VIVANTE_VDK +#undef SDL_VIDEO_DRIVER_OS2 #undef SDL_VIDEO_DRIVER_QNX +#undef SDL_VIDEO_DRIVER_RISCOS #undef SDL_VIDEO_RENDER_D3D #undef SDL_VIDEO_RENDER_D3D11 +#undef SDL_VIDEO_RENDER_D3D12 #undef SDL_VIDEO_RENDER_OGL #undef SDL_VIDEO_RENDER_OGL_ES #undef SDL_VIDEO_RENDER_OGL_ES2 @@ -400,21 +452,34 @@ #undef SDL_POWER_HARDWIRED /* Enable system filesystem support */ +#undef SDL_FILESYSTEM_ANDROID #undef SDL_FILESYSTEM_HAIKU #undef SDL_FILESYSTEM_COCOA #undef SDL_FILESYSTEM_DUMMY +#undef SDL_FILESYSTEM_RISCOS #undef SDL_FILESYSTEM_UNIX #undef SDL_FILESYSTEM_WINDOWS #undef SDL_FILESYSTEM_NACL -#undef SDL_FILESYSTEM_ANDROID #undef SDL_FILESYSTEM_EMSCRIPTEN +#undef SDL_FILESYSTEM_OS2 +#undef SDL_FILESYSTEM_VITA +#undef SDL_FILESYSTEM_PSP +#undef SDL_FILESYSTEM_PS2 + +/* Enable misc subsystem */ +#undef SDL_MISC_DUMMY + +/* Enable locale subsystem */ +#undef SDL_LOCALE_DUMMY /* Enable assembly routines */ -#undef SDL_ASSEMBLY_ROUTINES #undef SDL_ALTIVEC_BLITTERS #undef SDL_ARM_SIMD_BLITTERS #undef SDL_ARM_NEON_BLITTERS +/* Whether SDL_DYNAMIC_API needs dlopen() */ +#undef DYNAPI_NEEDS_DLOPEN + /* Enable ime support */ #undef SDL_USE_IME @@ -427,4 +492,7 @@ /* Enable dynamic libsamplerate support */ #undef SDL_LIBSAMPLERATE_DYNAMIC +/* Libdecor get min/max content size functions */ +#undef SDL_HAVE_LIBDECOR_GET_MIN_MAX + #endif /* SDL_config_h_ */ diff --git a/SDL2-2.0.12/include/SDL_config_android.h b/SDL2-2.30.5/include/SDL_config_android.h similarity index 90% rename from SDL2-2.0.12/include/SDL_config_android.h rename to SDL2-2.30.5/include/SDL_config_android.h index d057e17..00ffef8 100644 --- a/SDL2-2.0.12/include/SDL_config_android.h +++ b/SDL2-2.30.5/include/SDL_config_android.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -48,6 +48,7 @@ #define HAVE_SYS_TYPES_H 1 /* C library functions */ +#define HAVE_DLOPEN 1 #define HAVE_MALLOC 1 #define HAVE_CALLOC 1 #define HAVE_REALLOC 1 @@ -59,6 +60,7 @@ #define HAVE_SETENV 1 #define HAVE_UNSETENV 1 #define HAVE_QSORT 1 +#define HAVE_BSEARCH 1 #define HAVE_ABS 1 #define HAVE_BCOPY 1 #define HAVE_MEMSET 1 @@ -83,6 +85,7 @@ #define HAVE_STRNCMP 1 #define HAVE_STRCASECMP 1 #define HAVE_STRNCASECMP 1 +#define HAVE_STRCASESTR 1 #define HAVE_VSSCANF 1 #define HAVE_VSNPRINTF 1 #define HAVE_ACOS 1 @@ -111,8 +114,12 @@ #define HAVE_LOGF 1 #define HAVE_LOG10 1 #define HAVE_LOG10F 1 +#define HAVE_LROUND 1 +#define HAVE_LROUNDF 1 #define HAVE_POW 1 #define HAVE_POWF 1 +#define HAVE_ROUND 1 +#define HAVE_ROUNDF 1 #define HAVE_SCALBN 1 #define HAVE_SCALBNF 1 #define HAVE_SIN 1 @@ -121,23 +128,31 @@ #define HAVE_SQRTF 1 #define HAVE_TAN 1 #define HAVE_TANF 1 +#define HAVE_TRUNC 1 +#define HAVE_TRUNCF 1 #define HAVE_SIGACTION 1 #define HAVE_SETJMP 1 #define HAVE_NANOSLEEP 1 #define HAVE_SYSCONF 1 #define HAVE_CLOCK_GETTIME 1 +#ifdef __LP64__ +#define SIZEOF_VOIDP 8 +#else #define SIZEOF_VOIDP 4 +#endif /* Enable various audio drivers */ #define SDL_AUDIO_DRIVER_ANDROID 1 #define SDL_AUDIO_DRIVER_OPENSLES 1 +#define SDL_AUDIO_DRIVER_AAUDIO 1 #define SDL_AUDIO_DRIVER_DUMMY 1 /* Enable various input drivers */ #define SDL_JOYSTICK_ANDROID 1 -#define SDL_JOYSTICK_HIDAPI 1 -#define SDL_HAPTIC_ANDROID 1 +#define SDL_JOYSTICK_HIDAPI 1 +#define SDL_JOYSTICK_VIRTUAL 1 +#define SDL_HAPTIC_ANDROID 1 /* Enable sensor driver */ #define SDL_SENSOR_ANDROID 1 diff --git a/SDL2-2.30.5/include/SDL_config_emscripten.h b/SDL2-2.30.5/include/SDL_config_emscripten.h new file mode 100644 index 0000000..637cdae --- /dev/null +++ b/SDL2-2.30.5/include/SDL_config_emscripten.h @@ -0,0 +1,218 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#ifndef _SDL_config_emscripten_h_ +#define _SDL_config_emscripten_h_ + +#include "SDL_platform.h" + +/** + * \file SDL_config_emscripten.h + * + * This is a configuration that can be used to build SDL for Emscripten. + */ + +#ifdef __LP64__ +#define SIZEOF_VOIDP 8 +#else +#define SIZEOF_VOIDP 4 +#endif +#define HAVE_GCC_ATOMICS 1 + +/* Useful headers */ +#define STDC_HEADERS 1 +#define HAVE_ALLOCA_H 1 +#define HAVE_CTYPE_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 + +/* C library functions */ +#define HAVE_DLOPEN 1 +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +#define HAVE_GETENV 1 +#define HAVE_SETENV 1 +#define HAVE_PUTENV 1 +#define HAVE_UNSETENV 1 +#define HAVE_QSORT 1 +#define HAVE_BSEARCH 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 +#define HAVE_WCSDUP 1 +#define HAVE_WCSSTR 1 +#define HAVE_WCSCMP 1 +#define HAVE_WCSNCMP 1 +#define HAVE_WCSCASECMP 1 +#define HAVE_WCSNCASECMP 1 +#define HAVE_STRLEN 1 +#define HAVE_STRLCPY 1 +#define HAVE_STRLCAT 1 +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +#define HAVE_STRTOK_R 1 +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +#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 +#define HAVE_STRCASECMP 1 +#define HAVE_STRNCASECMP 1 +#define HAVE_SSCANF 1 +#define HAVE_VSSCANF 1 +#define HAVE_VSNPRINTF 1 +#define HAVE_M_PI 1 +#define HAVE_ACOS 1 +#define HAVE_ACOSF 1 +#define HAVE_ASIN 1 +#define HAVE_ASINF 1 +#define HAVE_ATAN 1 +#define HAVE_ATANF 1 +#define HAVE_ATAN2 1 +#define HAVE_ATAN2F 1 +#define HAVE_CEIL 1 +#define HAVE_CEILF 1 +#define HAVE_COPYSIGN 1 +#define HAVE_COPYSIGNF 1 +#define HAVE_COS 1 +#define HAVE_COSF 1 +#define HAVE_EXP 1 +#define HAVE_EXPF 1 +#define HAVE_FABS 1 +#define HAVE_FABSF 1 +#define HAVE_FLOOR 1 +#define HAVE_FLOORF 1 +#define HAVE_FMOD 1 +#define HAVE_FMODF 1 +#define HAVE_LOG 1 +#define HAVE_LOGF 1 +#define HAVE_LOG10 1 +#define HAVE_LOG10F 1 +#define HAVE_LROUND 1 +#define HAVE_LROUNDF 1 +#define HAVE_POW 1 +#define HAVE_POWF 1 +#define HAVE_ROUND 1 +#define HAVE_ROUNDF 1 +#define HAVE_SCALBN 1 +#define HAVE_SCALBNF 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_TRUNC 1 +#define HAVE_TRUNCF 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 +#define HAVE_CLOCK_GETTIME 1 +/* #undef HAVE_GETPAGESIZE */ +#define HAVE_MPROTECT 1 +#define HAVE_ICONV 1 + +/* SDL internal assertion support */ +/* #undef SDL_DEFAULT_ASSERT_LEVEL */ + +#define SDL_CPUINFO_DISABLED 1 +#define SDL_HAPTIC_DISABLED 1 +#define SDL_HIDAPI_DISABLED 1 +#ifndef __EMSCRIPTEN_PTHREADS__ +#define SDL_THREADS_DISABLED 1 +#endif + +/* Enable various audio drivers */ +#define SDL_AUDIO_DRIVER_DISK 1 +#define SDL_AUDIO_DRIVER_DUMMY 1 +#define SDL_AUDIO_DRIVER_EMSCRIPTEN 1 + +/* Enable various input drivers */ +#define SDL_JOYSTICK_EMSCRIPTEN 1 + +/* Enable various sensor drivers */ +#define SDL_SENSOR_DUMMY 1 + +/* Enable various shared object loading systems */ +#define SDL_LOADSO_DLOPEN 1 + +/* Enable various threading systems */ +#ifdef __EMSCRIPTEN_PTHREADS__ +#define SDL_THREAD_PTHREAD 1 +#define SDL_THREAD_PTHREAD_RECURSIVE_MUTEX 1 +#endif + +/* Enable various timer systems */ +#define SDL_TIMER_UNIX 1 + +/* Enable various video drivers */ +#define SDL_VIDEO_DRIVER_EMSCRIPTEN 1 + +#define SDL_VIDEO_RENDER_OGL_ES2 1 + +/* Enable OpenGL support */ +/* #undef SDL_VIDEO_OPENGL */ +/* #undef SDL_VIDEO_OPENGL_ES */ +#define SDL_VIDEO_OPENGL_ES2 1 +/* #undef SDL_VIDEO_OPENGL_BGL */ +/* #undef SDL_VIDEO_OPENGL_CGL */ +/* #undef SDL_VIDEO_OPENGL_GLX */ +/* #undef SDL_VIDEO_OPENGL_WGL */ +#define SDL_VIDEO_OPENGL_EGL 1 +/* #undef SDL_VIDEO_OPENGL_OSMESA */ +/* #undef SDL_VIDEO_OPENGL_OSMESA_DYNAMIC */ + +/* Enable system power support */ +#define SDL_POWER_EMSCRIPTEN 1 + +/* Enable system filesystem support */ +#define SDL_FILESYSTEM_EMSCRIPTEN 1 + +#endif /* _SDL_config_emscripten_h_ */ diff --git a/SDL2-2.0.12/include/SDL_config_iphoneos.h b/SDL2-2.30.5/include/SDL_config_iphoneos.h similarity index 85% rename from SDL2-2.0.12/include/SDL_config_iphoneos.h rename to SDL2-2.30.5/include/SDL_config_iphoneos.h index 38929a8..2743901 100644 --- a/SDL2-2.0.12/include/SDL_config_iphoneos.h +++ b/SDL2-2.30.5/include/SDL_config_iphoneos.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -48,6 +48,7 @@ /* #undef HAVE_LIBUNWIND_H */ /* C library functions */ +#define HAVE_DLOPEN 1 #define HAVE_MALLOC 1 #define HAVE_CALLOC 1 #define HAVE_REALLOC 1 @@ -59,6 +60,7 @@ #define HAVE_SETENV 1 #define HAVE_UNSETENV 1 #define HAVE_QSORT 1 +#define HAVE_BSEARCH 1 #define HAVE_ABS 1 #define HAVE_BCOPY 1 #define HAVE_MEMSET 1 @@ -83,6 +85,7 @@ #define HAVE_STRNCMP 1 #define HAVE_STRCASECMP 1 #define HAVE_STRNCASECMP 1 +#define HAVE_STRCASESTR 1 #define HAVE_VSSCANF 1 #define HAVE_VSNPRINTF 1 #define HAVE_M_PI 1 @@ -112,8 +115,12 @@ #define HAVE_LOGF 1 #define HAVE_LOG10 1 #define HAVE_LOG10F 1 +#define HAVE_LROUND 1 +#define HAVE_LROUNDF 1 #define HAVE_POW 1 #define HAVE_POWF 1 +#define HAVE_ROUND 1 +#define HAVE_ROUNDF 1 #define HAVE_SCALBN 1 #define HAVE_SCALBNF 1 #define HAVE_SIN 1 @@ -122,11 +129,14 @@ #define HAVE_SQRTF 1 #define HAVE_TAN 1 #define HAVE_TANF 1 +#define HAVE_TRUNC 1 +#define HAVE_TRUNCF 1 #define HAVE_SIGACTION 1 #define HAVE_SETJMP 1 #define HAVE_NANOSLEEP 1 #define HAVE_SYSCONF 1 #define HAVE_SYSCTLBYNAME 1 +#define HAVE_O_CLOEXEC 1 /* enable iPhone version of Core Audio driver */ #define SDL_AUDIO_DRIVER_COREAUDIO 1 @@ -136,9 +146,11 @@ /* Enable the stub haptic driver (src/haptic/dummy/\*.c) */ #define SDL_HAPTIC_DUMMY 1 -/* Enable MFi joystick support */ +/* Enable joystick support */ +/* Only enable HIDAPI support if you want to support Steam Controllers on iOS and tvOS */ +/*#define SDL_JOYSTICK_HIDAPI 1*/ #define SDL_JOYSTICK_MFI 1 -#define SDL_JOYSTICK_HIDAPI 1 +#define SDL_JOYSTICK_VIRTUAL 1 #ifdef __TVOS__ #define SDL_SENSOR_DUMMY 1 @@ -162,13 +174,17 @@ #define SDL_VIDEO_DRIVER_DUMMY 1 /* Enable OpenGL ES */ +#if !TARGET_OS_MACCATALYST #define SDL_VIDEO_OPENGL_ES2 1 #define SDL_VIDEO_OPENGL_ES 1 #define SDL_VIDEO_RENDER_OGL_ES 1 #define SDL_VIDEO_RENDER_OGL_ES2 1 +#endif -/* Metal supported on 64-bit devices running iOS 8.0 and tvOS 9.0 and newer */ -#if !TARGET_OS_SIMULATOR && !TARGET_CPU_ARM && ((__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 90000)) +/* Metal supported on 64-bit devices running iOS 8.0 and tvOS 9.0 and newer + Also supported in simulator from iOS 13.0 and tvOS 13.0 + */ +#if (TARGET_OS_SIMULATOR && ((__IPHONE_OS_VERSION_MIN_REQUIRED >= 130000) || (__TV_OS_VERSION_MIN_REQUIRED >= 130000))) || (!TARGET_CPU_ARM && ((__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 90000))) #define SDL_PLATFORM_SUPPORTS_METAL 1 #else #define SDL_PLATFORM_SUPPORTS_METAL 0 @@ -195,11 +211,6 @@ /* enable iOS extended launch screen */ #define SDL_IPHONE_LAUNCHSCREEN 1 -/* Set max recognized G-force from accelerometer - See src/joystick/uikit/SDL_sysjoystick.m for notes on why this is needed - */ -#define SDL_IPHONE_MAX_GFORCE 5.0 - /* enable filesystem support */ #define SDL_FILESYSTEM_COCOA 1 diff --git a/SDL2-2.0.12/include/SDL_config_macosx.h b/SDL2-2.30.5/include/SDL_config_macosx.h similarity index 89% rename from SDL2-2.0.12/include/SDL_config_macosx.h rename to SDL2-2.30.5/include/SDL_config_macosx.h index 1141345..2db760a 100644 --- a/SDL2-2.0.12/include/SDL_config_macosx.h +++ b/SDL2-2.30.5/include/SDL_config_macosx.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -52,6 +52,7 @@ #define HAVE_LIBUNWIND_H 1 /* C library functions */ +#define HAVE_DLOPEN 1 #define HAVE_MALLOC 1 #define HAVE_CALLOC 1 #define HAVE_REALLOC 1 @@ -62,6 +63,7 @@ #define HAVE_PUTENV 1 #define HAVE_UNSETENV 1 #define HAVE_QSORT 1 +#define HAVE_BSEARCH 1 #define HAVE_ABS 1 #define HAVE_BCOPY 1 #define HAVE_MEMSET 1 @@ -86,6 +88,7 @@ #define HAVE_STRNCMP 1 #define HAVE_STRCASECMP 1 #define HAVE_STRNCASECMP 1 +#define HAVE_STRCASESTR 1 #define HAVE_VSSCANF 1 #define HAVE_VSNPRINTF 1 #define HAVE_M_PI 1 @@ -115,8 +118,12 @@ #define HAVE_LOGF 1 #define HAVE_LOG10 1 #define HAVE_LOG10F 1 +#define HAVE_LROUND 1 +#define HAVE_LROUNDF 1 #define HAVE_POW 1 #define HAVE_POWF 1 +#define HAVE_ROUND 1 +#define HAVE_ROUNDF 1 #define HAVE_SCALBN 1 #define HAVE_SCALBNF 1 #define HAVE_SIN 1 @@ -125,12 +132,24 @@ #define HAVE_SQRTF 1 #define HAVE_TAN 1 #define HAVE_TANF 1 +#define HAVE_TRUNC 1 +#define HAVE_TRUNCF 1 #define HAVE_SIGACTION 1 #define HAVE_SETJMP 1 #define HAVE_NANOSLEEP 1 #define HAVE_SYSCONF 1 #define HAVE_SYSCTLBYNAME 1 +#if defined(__has_include) && (defined(__i386__) || defined(__x86_64)) +# if __has_include() +# define HAVE_IMMINTRIN_H 1 +# endif +#endif + +#if (MAC_OS_X_VERSION_MAX_ALLOWED >= 1070) +#define HAVE_O_CLOEXEC 1 +#endif + #define HAVE_GCC_ATOMICS 1 /* Enable various audio drivers */ @@ -139,10 +158,16 @@ #define SDL_AUDIO_DRIVER_DUMMY 1 /* Enable various input drivers */ +#define SDL_JOYSTICK_HIDAPI 1 #define SDL_JOYSTICK_IOKIT 1 -#define SDL_JOYSTICK_HIDAPI 1 +#define SDL_JOYSTICK_VIRTUAL 1 #define SDL_HAPTIC_IOKIT 1 +/* The MFI controller support requires ARC Objective C runtime */ +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1080 && !defined(__i386__) +#define SDL_JOYSTICK_MFI 1 +#endif + /* Enable the dummy sensor driver */ #define SDL_SENSOR_DUMMY 1 @@ -162,17 +187,13 @@ #undef SDL_VIDEO_DRIVER_X11 #define SDL_VIDEO_DRIVER_X11_DYNAMIC "/opt/X11/lib/libX11.6.dylib" #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT "/opt/X11/lib/libXext.6.dylib" -#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA "/opt/X11/lib/libXinerama.1.dylib" #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2 "/opt/X11/lib/libXi.6.dylib" #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR "/opt/X11/lib/libXrandr.2.dylib" #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS "/opt/X11/lib/libXss.1.dylib" -#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE "/opt/X11/lib/libXxf86vm.1.dylib" #define SDL_VIDEO_DRIVER_X11_XDBE 1 -#define SDL_VIDEO_DRIVER_X11_XINERAMA 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_HAS_XKBKEYCODETOKEYSYM 1 #ifdef MAC_OS_X_VERSION_10_8 @@ -183,7 +204,6 @@ */ #define SDL_VIDEO_DRIVER_X11_XINPUT2 1 #define SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS 1 -#define SDL_VIDEO_DRIVER_X11_CONST_PARAM_XEXTADDDISPLAY 1 #endif #ifndef SDL_VIDEO_RENDER_OGL @@ -195,7 +215,7 @@ #endif /* Metal only supported on 64-bit architectures with 10.11+ */ -#if TARGET_CPU_X86_64 && (MAC_OS_X_VERSION_MAX_ALLOWED >= 101100) +#if TARGET_RT_64_BIT && (MAC_OS_X_VERSION_MAX_ALLOWED >= 101100) #define SDL_PLATFORM_SUPPORTS_METAL 1 #else #define SDL_PLATFORM_SUPPORTS_METAL 0 @@ -250,7 +270,6 @@ #define SDL_FILESYSTEM_COCOA 1 /* Enable assembly routines */ -#define SDL_ASSEMBLY_ROUTINES 1 #ifdef __ppc__ #define SDL_ALTIVEC_BLITTERS 1 #endif diff --git a/SDL2-2.0.12/include/SDL_config_minimal.h b/SDL2-2.30.5/include/SDL_config_minimal.h similarity index 78% rename from SDL2-2.0.12/include/SDL_config_minimal.h rename to SDL2-2.30.5/include/SDL_config_minimal.h index b9c3958..ceedda2 100644 --- a/SDL2-2.0.12/include/SDL_config_minimal.h +++ b/SDL2-2.30.5/include/SDL_config_minimal.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -34,22 +34,29 @@ #define HAVE_STDARG_H 1 #define HAVE_STDDEF_H 1 +#if !defined(HAVE_STDINT_H) && !defined(_STDINT_H_) /* Most everything except Visual Studio 2008 and earlier has stdint.h now */ #if defined(_MSC_VER) && (_MSC_VER < 1600) -/* Here are some reasonable defaults */ -typedef unsigned int size_t; -typedef signed char int8_t; -typedef unsigned char uint8_t; -typedef signed short int16_t; -typedef unsigned short uint16_t; -typedef signed int int32_t; -typedef unsigned int uint32_t; -typedef signed long long int64_t; -typedef unsigned long long uint64_t; -typedef unsigned long uintptr_t; +typedef signed __int8 int8_t; +typedef unsigned __int8 uint8_t; +typedef signed __int16 int16_t; +typedef unsigned __int16 uint16_t; +typedef signed __int32 int32_t; +typedef unsigned __int32 uint32_t; +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; +#ifndef _UINTPTR_T_DEFINED +#ifdef _WIN64 +typedef unsigned __int64 uintptr_t; +#else +typedef unsigned int uintptr_t; +#endif +#define _UINTPTR_T_DEFINED +#endif #else #define HAVE_STDINT_H 1 #endif /* Visual Studio 2008 */ +#endif /* !_STDINT_H_ && !HAVE_STDINT_H */ #ifdef __GNUC__ #define HAVE_GCC_SYNC_LOCK_TEST_AND_SET 1 @@ -64,6 +71,9 @@ typedef unsigned long uintptr_t; /* Enable the stub haptic driver (src/haptic/dummy/\*.c) */ #define SDL_HAPTIC_DISABLED 1 +/* Enable the stub HIDAPI */ +#define SDL_HIDAPI_DISABLED 1 + /* Enable the stub sensor driver (src/sensor/dummy/\*.c) */ #define SDL_SENSOR_DISABLED 1 diff --git a/SDL2-2.30.5/include/SDL_config_ngage.h b/SDL2-2.30.5/include/SDL_config_ngage.h new file mode 100644 index 0000000..61c26c2 --- /dev/null +++ b/SDL2-2.30.5/include/SDL_config_ngage.h @@ -0,0 +1,89 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#ifndef SDL_config_ngage_h_ +#define SDL_config_ngage_h_ +#define SDL_config_h_ + +#include "SDL_platform.h" + +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef signed short int16_t; +typedef unsigned short uint16_t; +typedef signed int int32_t; +typedef unsigned int uint32_t; +typedef signed long long int64_t; +typedef unsigned long long uint64_t; +typedef unsigned long uintptr_t; + +#define HAVE_STDARG_H 1 +#define HAVE_STDDEF_H 1 +#define HAVE_STDIO_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_MATH_H 1 +#define HAVE_CEIL 1 +#define HAVE_COPYSIGN 1 +#define HAVE_COS 1 +#define HAVE_EXP 1 +#define HAVE_FABS 1 +#define HAVE_FLOOR 1 +#define HAVE_LOG 1 +#define HAVE_LOG10 1 +#define HAVE_SCALBN 1 +#define HAVE_SIN 1 +#define HAVE_SQRT 1 +#define HAVE_TAN 1 +#define HAVE_MALLOC 1 +#define SDL_MAIN_NEEDED 1 +#define LACKS_SYS_MMAN_H 1 + +/* Enable the N-Gage thread support (src/thread/ngage/\*.c) */ +#define SDL_THREAD_NGAGE 1 + +/* Enable the N-Gage timer support (src/timer/ngage/\*.c) */ +#define SDL_TIMER_NGAGE 1 + +/* Enable the N-Gage video driver (src/video/ngage/\*.c) */ +#define SDL_VIDEO_DRIVER_NGAGE 1 + +/* Enable the dummy audio driver (src/audio/dummy/\*.c) */ +#define SDL_AUDIO_DRIVER_DUMMY 1 + +/* Enable the stub joystick driver (src/joystick/dummy/\*.c) */ +#define SDL_JOYSTICK_DISABLED 1 + +/* Enable the stub haptic driver (src/haptic/dummy/\*.c) */ +#define SDL_HAPTIC_DISABLED 1 + +/* Enable the stub HIDAPI */ +#define SDL_HIDAPI_DISABLED 1 + +/* Enable the stub sensor driver (src/sensor/dummy/\*.c) */ +#define SDL_SENSOR_DISABLED 1 + +/* Enable the stub shared object loader (src/loadso/dummy/\*.c) */ +#define SDL_LOADSO_DISABLED 1 + +/* Enable the dummy filesystem driver (src/filesystem/dummy/\*.c) */ +#define SDL_FILESYSTEM_DUMMY 1 + +#endif /* SDL_config_ngage_h_ */ diff --git a/SDL2-2.0.12/include/SDL_config_os2.h b/SDL2-2.30.5/include/SDL_config_os2.h similarity index 76% rename from SDL2-2.0.12/include/SDL_config_os2.h rename to SDL2-2.30.5/include/SDL_config_os2.h index f5799dc..b2b061d 100644 --- a/SDL2-2.0.12/include/SDL_config_os2.h +++ b/SDL2-2.30.5/include/SDL_config_os2.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -25,57 +25,72 @@ #include "SDL_platform.h" +#define SIZEOF_VOIDP 4 + #define SDL_AUDIO_DRIVER_DUMMY 1 #define SDL_AUDIO_DRIVER_DISK 1 +#define SDL_AUDIO_DRIVER_OS2 1 #define SDL_POWER_DISABLED 1 -#define SDL_JOYSTICK_DISABLED 1 #define SDL_HAPTIC_DISABLED 1 -/*#undef SDL_JOYSTICK_HIDAPI */ #define SDL_SENSOR_DUMMY 1 #define SDL_VIDEO_DRIVER_DUMMY 1 +#define SDL_VIDEO_DRIVER_OS2 1 +#define SDL_JOYSTICK_OS2 1 +#ifndef HAVE_LIBUSB_H /* see Makefile */ +#define SDL_HIDAPI_DISABLED 1 +/*#undef SDL_JOYSTICK_HIDAPI */ +#else +#define SDL_JOYSTICK_HIDAPI 1 +#define HAVE_LIBUSB 1 +/* dynamically loaded libusb-1.0 dll: */ +#define SDL_LIBUSB_DYNAMIC "usb100.dll" +#endif +#define SDL_JOYSTICK_VIRTUAL 1 /* Enable OpenGL support */ /* #undef SDL_VIDEO_OPENGL */ -/* Enable Vulkan support */ -/* #undef SDL_VIDEO_VULKAN */ +#define SDL_THREAD_OS2 1 +#define SDL_LOADSO_OS2 1 +#define SDL_TIMER_OS2 1 +#define SDL_FILESYSTEM_OS2 1 -#define SDL_LOADSO_DISABLED 1 -#define SDL_THREADS_DISABLED 1 -#define SDL_TIMERS_DISABLED 1 -#define SDL_FILESYSTEM_DUMMY 1 - -/* Enable assembly routines */ -#define SDL_ASSEMBLY_ROUTINES 1 - -/* #undef HAVE_LIBSAMPLERATE_H */ +/* use libsamplerate for audio rate conversion. */ +/*#define HAVE_LIBSAMPLERATE_H 1 */ /* Enable dynamic libsamplerate support */ -/* #undef SDL_LIBSAMPLERATE_DYNAMIC */ +#define SDL_LIBSAMPLERATE_DYNAMIC "SAMPRATE.DLL" #define HAVE_LIBC 1 +#define HAVE_STDARG_H 1 +#define HAVE_STDDEF_H 1 +#define HAVE_STDINT_H 1 + #define HAVE_SYS_TYPES_H 1 #define HAVE_STDIO_H 1 #define STDC_HEADERS 1 #define HAVE_STDLIB_H 1 -#define HAVE_STDARG_H 1 -#define HAVE_STDDEF_H 1 #define HAVE_MALLOC_H 1 #define HAVE_MEMORY_H 1 #define HAVE_STRING_H 1 #define HAVE_STRINGS_H 1 #define HAVE_WCHAR_H 1 #define HAVE_INTTYPES_H 1 -#define HAVE_STDINT_H 1 #define HAVE_LIMITS_H 1 #define HAVE_CTYPE_H 1 #define HAVE_MATH_H 1 #define HAVE_FLOAT_H 1 #define HAVE_SIGNAL_H 1 +#if 0 /* see Makefile */ +#define HAVE_ICONV 1 +#define HAVE_ICONV_H 1 +#endif + +/* #undef HAVE_DLOPEN */ #define HAVE_MALLOC 1 #define HAVE_CALLOC 1 #define HAVE_REALLOC 1 @@ -88,25 +103,36 @@ #define HAVE_GETENV 1 #define HAVE_SETENV 1 #define HAVE_PUTENV 1 +/* OpenWatcom requires specific calling conventions for qsort and bsearch */ +#ifndef __WATCOMC__ #define HAVE_QSORT 1 +#define HAVE_BSEARCH 1 +#endif #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_WCSCMP 1 +#define HAVE__WCSICMP 1 +#define HAVE__WCSNICMP 1 #define HAVE_WCSLEN 1 #define HAVE_WCSLCPY 1 #define HAVE_WCSLCAT 1 +/* #undef HAVE_WCSDUP */ +#define HAVE__WCSDUP 1 +#define HAVE_WCSSTR 1 #define HAVE_WCSCMP 1 +#define HAVE_WCSNCMP 1 #define HAVE_STRLEN 1 #define HAVE_STRLCPY 1 #define HAVE_STRLCAT 1 #define HAVE__STRREV 1 #define HAVE__STRUPR 1 #define HAVE__STRLWR 1 -#define HAVE_INDEX 1 -#define HAVE_RINDEX 1 +/* #undef HAVE_INDEX */ +/* #undef HAVE_RINDEX */ #define HAVE_STRCHR 1 #define HAVE_STRRCHR 1 #define HAVE_STRSTR 1 @@ -123,14 +149,6 @@ #define HAVE_STRTOD 1 #define HAVE_ATOI 1 #define HAVE_ATOF 1 -#define HAVE_WCSLEN 1 -#define HAVE_WCSLCPY 1 -#define HAVE_WCSLCAT 1 -/* #define HAVE_WCSDUP 1 */ -/* #define wcsdup _wcsdup */ -#define HAVE_WCSSTR 1 -#define HAVE_WCSCMP 1 -#define HAVE_WCSNCMP 1 #define HAVE_STRCMP 1 #define HAVE_STRNCMP 1 #define HAVE_STRICMP 1 @@ -176,5 +194,11 @@ /* #undef HAVE_SQRTF */ #define HAVE_TAN 1 /* #undef HAVE_TANF */ +/* #undef HAVE_TRUNC */ +/* #undef HAVE_TRUNCF */ +/* #undef HAVE_LROUND */ +/* #undef HAVE_LROUNDF */ +/* #undef HAVE_ROUND */ +/* #undef HAVE_ROUNDF */ #endif /* SDL_config_os2_h_ */ diff --git a/SDL2-2.0.12/include/SDL_config_pandora.h b/SDL2-2.30.5/include/SDL_config_pandora.h similarity index 92% rename from SDL2-2.0.12/include/SDL_config_pandora.h rename to SDL2-2.30.5/include/SDL_config_pandora.h index bdc64c9..27b858d 100644 --- a/SDL2-2.0.12/include/SDL_config_pandora.h +++ b/SDL2-2.30.5/include/SDL_config_pandora.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -54,6 +54,7 @@ #define HAVE_STRING_H 1 #define HAVE_SYS_TYPES_H 1 +#define HAVE_DLOPEN 1 #define HAVE_MALLOC 1 #define HAVE_CALLOC 1 #define HAVE_REALLOC 1 @@ -64,6 +65,7 @@ #define HAVE_PUTENV 1 #define HAVE_UNSETENV 1 #define HAVE_QSORT 1 +#define HAVE_BSEARCH 1 #define HAVE_ABS 1 #define HAVE_BCOPY 1 #define HAVE_MEMSET 1 @@ -95,6 +97,10 @@ #define HAVE_FLOOR 1 #define HAVE_LOG 1 #define HAVE_LOG10 1 +#define HAVE_LROUND 1 +#define HAVE_LROUNDF 1 +#define HAVE_ROUND 1 +#define HAVE_ROUNDF 1 #define HAVE_SCALBN 1 #define HAVE_SIN 1 #define HAVE_SINF 1 @@ -102,6 +108,8 @@ #define HAVE_SQRTF 1 #define HAVE_TAN 1 #define HAVE_TANF 1 +#define HAVE_TRUNC 1 +#define HAVE_TRUNCF 1 #define HAVE_SIGACTION 1 #define HAVE_SETJMP 1 #define HAVE_NANOSLEEP 1 @@ -110,8 +118,8 @@ #define SDL_AUDIO_DRIVER_OSS 1 #define SDL_INPUT_LINUXEV 1 -#define SDL_INPUT_TSLIB 1 #define SDL_JOYSTICK_LINUX 1 +#define SDL_JOYSTICK_VIRTUAL 1 #define SDL_HAPTIC_LINUX 1 #define SDL_SENSOR_DUMMY 1 diff --git a/SDL2-2.30.5/include/SDL_config_windows.h b/SDL2-2.30.5/include/SDL_config_windows.h new file mode 100644 index 0000000..aae52eb --- /dev/null +++ b/SDL2-2.30.5/include/SDL_config_windows.h @@ -0,0 +1,333 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#ifndef SDL_config_windows_h_ +#define SDL_config_windows_h_ +#define SDL_config_h_ + +#include "SDL_platform.h" + +/* winsdkver.h defines _WIN32_MAXVER for SDK version detection. It is present since at least the Windows 7 SDK, + * but out of caution we'll only use it if the compiler supports __has_include() to confirm its presence. + * If your compiler doesn't support __has_include() but you have winsdkver.h, define HAVE_WINSDKVER_H. */ +#if !defined(HAVE_WINSDKVER_H) && defined(__has_include) +#if __has_include() +#define HAVE_WINSDKVER_H 1 +#endif +#endif + +#ifdef HAVE_WINSDKVER_H +#include +#endif + +/* sdkddkver.h defines more specific SDK version numbers. This is needed because older versions of the + * Windows 10 SDK have broken declarations for the C API for DirectX 12. */ +#if !defined(HAVE_SDKDDKVER_H) && defined(__has_include) +#if __has_include() +#define HAVE_SDKDDKVER_H 1 +#endif +#endif + +#ifdef HAVE_SDKDDKVER_H +#include +#endif + +/* This is a set of defines to configure the SDL features */ + +#if !defined(HAVE_STDINT_H) && !defined(_STDINT_H_) +/* Most everything except Visual Studio 2008 and earlier has stdint.h now */ +#if defined(_MSC_VER) && (_MSC_VER < 1600) +typedef signed __int8 int8_t; +typedef unsigned __int8 uint8_t; +typedef signed __int16 int16_t; +typedef unsigned __int16 uint16_t; +typedef signed __int32 int32_t; +typedef unsigned __int32 uint32_t; +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; +#ifndef _UINTPTR_T_DEFINED +#ifdef _WIN64 +typedef unsigned __int64 uintptr_t; +#else +typedef unsigned int uintptr_t; +#endif +#define _UINTPTR_T_DEFINED +#endif +#else +#define HAVE_STDINT_H 1 +#endif /* Visual Studio 2008 */ +#endif /* !_STDINT_H_ && !HAVE_STDINT_H */ + +#ifdef _WIN64 +# define SIZEOF_VOIDP 8 +#else +# define SIZEOF_VOIDP 4 +#endif + +#ifdef __clang__ +# define HAVE_GCC_ATOMICS 1 +#endif + +#define HAVE_DDRAW_H 1 +#define HAVE_DINPUT_H 1 +#define HAVE_DSOUND_H 1 +#ifndef __WATCOMC__ +#define HAVE_DXGI_H 1 +#define HAVE_XINPUT_H 1 +#if defined(_WIN32_MAXVER) && _WIN32_MAXVER >= 0x0A00 /* Windows 10 SDK */ +#define HAVE_WINDOWS_GAMING_INPUT_H 1 +#endif +#if defined(_WIN32_MAXVER) && _WIN32_MAXVER >= 0x0602 /* Windows 8 SDK */ +#define HAVE_D3D11_H 1 +#define HAVE_ROAPI_H 1 +#endif +#if defined(__has_include) +#if __has_include() && __has_include() +#define HAVE_D3D12_H 1 +#endif +#endif +#if defined(_WIN32_MAXVER) && _WIN32_MAXVER >= 0x0603 /* Windows 8.1 SDK */ +#define HAVE_SHELLSCALINGAPI_H 1 +#endif +#define HAVE_MMDEVICEAPI_H 1 +#define HAVE_AUDIOCLIENT_H 1 +#define HAVE_TPCSHRD_H 1 +#define HAVE_SENSORSAPI_H 1 +#endif +#if (defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64)) && (defined(_MSC_VER) && _MSC_VER >= 1600) +#define HAVE_IMMINTRIN_H 1 +#elif defined(__has_include) && (defined(__i386__) || defined(__x86_64)) +# if __has_include() +# define HAVE_IMMINTRIN_H 1 +# endif +#endif + +/* This is disabled by default to avoid C runtime dependencies and manifest requirements */ +#ifdef HAVE_LIBC +/* Useful headers */ +#define STDC_HEADERS 1 +#define HAVE_CTYPE_H 1 +#define HAVE_FLOAT_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_MATH_H 1 +#define HAVE_SIGNAL_H 1 +#define HAVE_STDIO_H 1 +#define HAVE_STRING_H 1 + +/* C library functions */ +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +/* OpenWatcom requires specific calling conventions for qsort and bsearch */ +#ifndef __WATCOMC__ +#define HAVE_QSORT 1 +#define HAVE_BSEARCH 1 +#endif +#define HAVE_ABS 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_MEMCMP 1 +#define HAVE_STRLEN 1 +#define HAVE__STRREV 1 +/* These functions have security warnings, so we won't use them */ +/* #undef HAVE__STRUPR */ +/* #undef HAVE__STRLWR */ +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +/* #undef HAVE_STRTOK_R */ +/* These functions have security warnings, so we won't use them */ +/* #undef HAVE__LTOA */ +/* #undef HAVE__ULTOA */ +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +#define HAVE_STRTOD 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE__STRICMP 1 +#define HAVE__STRNICMP 1 +#define HAVE__WCSICMP 1 +#define HAVE__WCSNICMP 1 +#define HAVE__WCSDUP 1 +#define HAVE_ACOS 1 +#define HAVE_ASIN 1 +#define HAVE_ATAN 1 +#define HAVE_ATAN2 1 +#define HAVE_CEIL 1 +#define HAVE_COS 1 +#define HAVE_EXP 1 +#define HAVE_FABS 1 +#define HAVE_FLOOR 1 +#define HAVE_FMOD 1 +#define HAVE_LOG 1 +#define HAVE_LOG10 1 +#define HAVE_POW 1 +#define HAVE_SIN 1 +#define HAVE_SQRT 1 +#define HAVE_TAN 1 +#ifndef __WATCOMC__ +#define HAVE_ACOSF 1 +#define HAVE_ASINF 1 +#define HAVE_ATANF 1 +#define HAVE_ATAN2F 1 +#define HAVE_CEILF 1 +#define HAVE__COPYSIGN 1 +#define HAVE_COSF 1 +#define HAVE_EXPF 1 +#define HAVE_FABSF 1 +#define HAVE_FLOORF 1 +#define HAVE_FMODF 1 +#define HAVE_LOGF 1 +#define HAVE_LOG10F 1 +#define HAVE_POWF 1 +#define HAVE_SINF 1 +#define HAVE_SQRTF 1 +#define HAVE_TANF 1 +#endif +#if defined(_MSC_VER) +/* These functions were added with the VC++ 2013 C runtime library */ +#if _MSC_VER >= 1800 +#define HAVE_STRTOLL 1 +#define HAVE_STRTOULL 1 +#define HAVE_VSSCANF 1 +#define HAVE_LROUND 1 +#define HAVE_LROUNDF 1 +#define HAVE_ROUND 1 +#define HAVE_ROUNDF 1 +#define HAVE_SCALBN 1 +#define HAVE_SCALBNF 1 +#define HAVE_TRUNC 1 +#define HAVE_TRUNCF 1 +#endif +/* This function is available with at least the VC++ 2008 C runtime library */ +#if _MSC_VER >= 1400 +#define HAVE__FSEEKI64 1 +#endif +#ifdef _USE_MATH_DEFINES +#define HAVE_M_PI 1 +#endif +#elif defined(__WATCOMC__) +#define HAVE__FSEEKI64 1 +#define HAVE_STRTOLL 1 +#define HAVE_STRTOULL 1 +#define HAVE_VSSCANF 1 +#define HAVE_ROUND 1 +#define HAVE_SCALBN 1 +#define HAVE_TRUNC 1 +#else +#define HAVE_M_PI 1 +#endif +#else +#define HAVE_STDARG_H 1 +#define HAVE_STDDEF_H 1 +#endif + +/* Enable various audio drivers */ +#if defined(HAVE_MMDEVICEAPI_H) && defined(HAVE_AUDIOCLIENT_H) +#define SDL_AUDIO_DRIVER_WASAPI 1 +#endif +#define SDL_AUDIO_DRIVER_DSOUND 1 +#define SDL_AUDIO_DRIVER_WINMM 1 +#define SDL_AUDIO_DRIVER_DISK 1 +#define SDL_AUDIO_DRIVER_DUMMY 1 + +/* Enable various input drivers */ +#define SDL_JOYSTICK_DINPUT 1 +#define SDL_JOYSTICK_HIDAPI 1 +#ifndef __WINRT__ +#define SDL_JOYSTICK_RAWINPUT 1 +#endif +#define SDL_JOYSTICK_VIRTUAL 1 +#ifdef HAVE_WINDOWS_GAMING_INPUT_H +#define SDL_JOYSTICK_WGI 1 +#endif +#define SDL_JOYSTICK_XINPUT 1 +#define SDL_HAPTIC_DINPUT 1 +#define SDL_HAPTIC_XINPUT 1 + +/* Enable the sensor driver */ +#ifdef HAVE_SENSORSAPI_H +#define SDL_SENSOR_WINDOWS 1 +#else +#define SDL_SENSOR_DUMMY 1 +#endif + +/* Enable various shared object loading systems */ +#define SDL_LOADSO_WINDOWS 1 + +/* Enable various threading systems */ +#define SDL_THREAD_GENERIC_COND_SUFFIX 1 +#define SDL_THREAD_WINDOWS 1 + +/* Enable various timer systems */ +#define SDL_TIMER_WINDOWS 1 + +/* Enable various video drivers */ +#define SDL_VIDEO_DRIVER_DUMMY 1 +#define SDL_VIDEO_DRIVER_WINDOWS 1 + +#ifndef SDL_VIDEO_RENDER_D3D +#define SDL_VIDEO_RENDER_D3D 1 +#endif +#if !defined(SDL_VIDEO_RENDER_D3D11) && defined(HAVE_D3D11_H) +#define SDL_VIDEO_RENDER_D3D11 1 +#endif +#if !defined(SDL_VIDEO_RENDER_D3D12) && defined(HAVE_D3D12_H) +#define SDL_VIDEO_RENDER_D3D12 1 +#endif + +/* Enable OpenGL support */ +#ifndef SDL_VIDEO_OPENGL +#define SDL_VIDEO_OPENGL 1 +#endif +#ifndef SDL_VIDEO_OPENGL_WGL +#define SDL_VIDEO_OPENGL_WGL 1 +#endif +#ifndef SDL_VIDEO_RENDER_OGL +#define SDL_VIDEO_RENDER_OGL 1 +#endif +#ifndef SDL_VIDEO_RENDER_OGL_ES2 +#define SDL_VIDEO_RENDER_OGL_ES2 1 +#endif +#ifndef SDL_VIDEO_OPENGL_ES2 +#define SDL_VIDEO_OPENGL_ES2 1 +#endif +#ifndef SDL_VIDEO_OPENGL_EGL +#define SDL_VIDEO_OPENGL_EGL 1 +#endif + +/* Enable Vulkan support */ +#define SDL_VIDEO_VULKAN 1 + +/* Enable system power support */ +#define SDL_POWER_WINDOWS 1 + +/* Enable filesystem support */ +#define SDL_FILESYSTEM_WINDOWS 1 + +#endif /* SDL_config_windows_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/include/SDL_config_windows.h b/SDL2-2.30.5/include/SDL_config_wingdk.h similarity index 70% rename from SDL2-2.0.12/include/SDL_config_windows.h rename to SDL2-2.30.5/include/SDL_config_wingdk.h index f269bfc..c2a63b5 100644 --- a/SDL2-2.0.12/include/SDL_config_windows.h +++ b/SDL2-2.30.5/include/SDL_config_wingdk.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -19,71 +19,44 @@ 3. This notice may not be removed or altered from any source distribution. */ -#ifndef SDL_config_windows_h_ -#define SDL_config_windows_h_ +#ifndef SDL_config_wingdk_h_ +#define SDL_config_wingdk_h_ #define SDL_config_h_ #include "SDL_platform.h" -/* This is a set of defines to configure the SDL features */ +/* Windows GDK does not need Windows SDK version checks because it requires + * a recent version of the Windows 10 SDK. */ -#if !defined(_STDINT_H_) && (!defined(HAVE_STDINT_H) || !_HAVE_STDINT_H) -#if defined(__GNUC__) || defined(__DMC__) || defined(__WATCOMC__) -#define HAVE_STDINT_H 1 -#elif defined(_MSC_VER) -typedef signed __int8 int8_t; -typedef unsigned __int8 uint8_t; -typedef signed __int16 int16_t; -typedef unsigned __int16 uint16_t; -typedef signed __int32 int32_t; -typedef unsigned __int32 uint32_t; -typedef signed __int64 int64_t; -typedef unsigned __int64 uint64_t; -#ifndef _UINTPTR_T_DEFINED -#ifdef _WIN64 -typedef unsigned __int64 uintptr_t; -#else -typedef unsigned int uintptr_t; -#endif -#define _UINTPTR_T_DEFINED -#endif -/* Older Visual C++ headers don't have the Win64-compatible typedefs... */ -#if ((_MSC_VER <= 1200) && (!defined(DWORD_PTR))) -#define DWORD_PTR DWORD -#endif -#if ((_MSC_VER <= 1200) && (!defined(LONG_PTR))) -#define LONG_PTR LONG -#endif -#else /* !__GNUC__ && !_MSC_VER */ -typedef signed char int8_t; -typedef unsigned char uint8_t; -typedef signed short int16_t; -typedef unsigned short uint16_t; -typedef signed int int32_t; -typedef unsigned int uint32_t; -typedef signed long long int64_t; -typedef unsigned long long uint64_t; -#ifndef _SIZE_T_DEFINED_ -#define _SIZE_T_DEFINED_ -typedef unsigned int size_t; -#endif -typedef unsigned int uintptr_t; -#endif /* __GNUC__ || _MSC_VER */ -#endif /* !_STDINT_H_ && !HAVE_STDINT_H */ - -#ifdef _WIN64 +/* GDK only supports 64-bit */ # define SIZEOF_VOIDP 8 -#else -# define SIZEOF_VOIDP 4 + +#ifdef __clang__ +# define HAVE_GCC_ATOMICS 1 #endif #define HAVE_DDRAW_H 1 #define HAVE_DINPUT_H 1 #define HAVE_DSOUND_H 1 +/* No SDK version checks needed for these because the SDK has to be new. */ #define HAVE_DXGI_H 1 #define HAVE_XINPUT_H 1 +#define HAVE_WINDOWS_GAMING_INPUT_H 1 +#define HAVE_D3D11_H 1 +#define HAVE_ROAPI_H 1 +#define HAVE_D3D12_H 1 +#define HAVE_SHELLSCALINGAPI_H 1 #define HAVE_MMDEVICEAPI_H 1 #define HAVE_AUDIOCLIENT_H 1 +#define HAVE_TPCSHRD_H 1 +#define HAVE_SENSORSAPI_H 1 +#if (defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64)) && (defined(_MSC_VER) && _MSC_VER >= 1600) +#define HAVE_IMMINTRIN_H 1 +#elif defined(__has_include) && (defined(__i386__) || defined(__x86_64)) +# if __has_include() +# define HAVE_IMMINTRIN_H 1 +# endif +#endif /* This is disabled by default to avoid C runtime dependencies and manifest requirements */ #ifdef HAVE_LIBC @@ -94,6 +67,7 @@ typedef unsigned int uintptr_t; #define HAVE_LIMITS_H 1 #define HAVE_MATH_H 1 #define HAVE_SIGNAL_H 1 +#define HAVE_STDINT_H 1 #define HAVE_STDIO_H 1 #define HAVE_STRING_H 1 @@ -104,6 +78,7 @@ typedef unsigned int uintptr_t; #define HAVE_FREE 1 #define HAVE_ALLOCA 1 #define HAVE_QSORT 1 +#define HAVE_BSEARCH 1 #define HAVE_ABS 1 #define HAVE_MEMSET 1 #define HAVE_MEMCPY 1 @@ -118,9 +93,6 @@ typedef unsigned int uintptr_t; #define HAVE_STRRCHR 1 #define HAVE_STRSTR 1 /* #undef HAVE_STRTOK_R */ -#if defined(_MSC_VER) -#define HAVE_STRTOK_S 1 -#endif /* These functions have security warnings, so we won't use them */ /* #undef HAVE__LTOA */ /* #undef HAVE__ULTOA */ @@ -133,61 +105,72 @@ typedef unsigned int uintptr_t; #define HAVE_STRNCMP 1 #define HAVE__STRICMP 1 #define HAVE__STRNICMP 1 +#define HAVE__WCSICMP 1 +#define HAVE__WCSNICMP 1 +#define HAVE__WCSDUP 1 #define HAVE_ACOS 1 -#define HAVE_ACOSF 1 #define HAVE_ASIN 1 -#define HAVE_ASINF 1 #define HAVE_ATAN 1 -#define HAVE_ATANF 1 #define HAVE_ATAN2 1 +#define HAVE_CEIL 1 +#define HAVE_COS 1 +#define HAVE_EXP 1 +#define HAVE_FABS 1 +#define HAVE_FLOOR 1 +#define HAVE_FMOD 1 +#define HAVE_LOG 1 +#define HAVE_LOG10 1 +#define HAVE_POW 1 +#define HAVE_SIN 1 +#define HAVE_SQRT 1 +#define HAVE_TAN 1 +#define HAVE_ACOSF 1 +#define HAVE_ASINF 1 +#define HAVE_ATANF 1 #define HAVE_ATAN2F 1 #define HAVE_CEILF 1 #define HAVE__COPYSIGN 1 -#define HAVE_COS 1 #define HAVE_COSF 1 -#define HAVE_EXP 1 #define HAVE_EXPF 1 -#define HAVE_FABS 1 #define HAVE_FABSF 1 -#define HAVE_FLOOR 1 #define HAVE_FLOORF 1 -#define HAVE_FMOD 1 #define HAVE_FMODF 1 -#define HAVE_LOG 1 #define HAVE_LOGF 1 -#define HAVE_LOG10 1 #define HAVE_LOG10F 1 -#define HAVE_POW 1 #define HAVE_POWF 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 #if defined(_MSC_VER) /* These functions were added with the VC++ 2013 C runtime library */ -#if _MSC_VER >= 1800 #define HAVE_STRTOLL 1 +#define HAVE_STRTOULL 1 #define HAVE_VSSCANF 1 +#define HAVE_LROUND 1 +#define HAVE_LROUNDF 1 +#define HAVE_ROUND 1 +#define HAVE_ROUNDF 1 #define HAVE_SCALBN 1 #define HAVE_SCALBNF 1 -#endif -/* This function is available with at least the VC++ 2008 C runtime library */ -#if _MSC_VER >= 1400 +#define HAVE_TRUNC 1 +#define HAVE_TRUNCF 1 #define HAVE__FSEEKI64 1 +#ifdef _USE_MATH_DEFINES +#define HAVE_M_PI 1 #endif -#endif -#if !defined(_MSC_VER) || defined(_USE_MATH_DEFINES) +#else #define HAVE_M_PI 1 #endif #else #define HAVE_STDARG_H 1 #define HAVE_STDDEF_H 1 +#define HAVE_STDINT_H 1 #endif /* Enable various audio drivers */ +#if defined(HAVE_MMDEVICEAPI_H) && defined(HAVE_AUDIOCLIENT_H) #define SDL_AUDIO_DRIVER_WASAPI 1 +#endif #define SDL_AUDIO_DRIVER_DSOUND 1 #define SDL_AUDIO_DRIVER_WINMM 1 #define SDL_AUDIO_DRIVER_DISK 1 @@ -195,18 +178,28 @@ typedef unsigned int uintptr_t; /* Enable various input drivers */ #define SDL_JOYSTICK_DINPUT 1 -#define SDL_JOYSTICK_XINPUT 1 #define SDL_JOYSTICK_HIDAPI 1 +#define SDL_JOYSTICK_RAWINPUT 1 +#define SDL_JOYSTICK_VIRTUAL 1 +#ifdef HAVE_WINDOWS_GAMING_INPUT_H +#define SDL_JOYSTICK_WGI 1 +#endif +#define SDL_JOYSTICK_XINPUT 1 #define SDL_HAPTIC_DINPUT 1 #define SDL_HAPTIC_XINPUT 1 -/* Enable the dummy sensor driver */ -#define SDL_SENSOR_DUMMY 1 +/* Enable the sensor driver */ +#ifdef HAVE_SENSORSAPI_H +#define SDL_SENSOR_WINDOWS 1 +#else +#define SDL_SENSOR_DUMMY 1 +#endif /* Enable various shared object loading systems */ #define SDL_LOADSO_WINDOWS 1 /* Enable various threading systems */ +#define SDL_THREAD_GENERIC_COND_SUFFIX 1 #define SDL_THREAD_WINDOWS 1 /* Enable various timer systems */ @@ -219,8 +212,11 @@ typedef unsigned int uintptr_t; #ifndef SDL_VIDEO_RENDER_D3D #define SDL_VIDEO_RENDER_D3D 1 #endif -#ifndef SDL_VIDEO_RENDER_D3D11 -#define SDL_VIDEO_RENDER_D3D11 0 +#if !defined(SDL_VIDEO_RENDER_D3D11) && defined(HAVE_D3D11_H) +#define SDL_VIDEO_RENDER_D3D11 1 +#endif +#if !defined(SDL_VIDEO_RENDER_D3D12) && defined(HAVE_D3D12_H) +#define SDL_VIDEO_RENDER_D3D12 1 #endif /* Enable OpenGL support */ @@ -252,9 +248,6 @@ typedef unsigned int uintptr_t; /* Enable filesystem support */ #define SDL_FILESYSTEM_WINDOWS 1 -/* Enable assembly routines (Win64 doesn't have inline asm) */ -#ifndef _WIN64 -#define SDL_ASSEMBLY_ROUTINES 1 -#endif +#endif /* SDL_config_wingdk_h_ */ -#endif /* SDL_config_windows_h_ */ +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/include/SDL_config_winrt.h b/SDL2-2.30.5/include/SDL_config_winrt.h similarity index 69% rename from SDL2-2.0.12/include/SDL_config_winrt.h rename to SDL2-2.30.5/include/SDL_config_winrt.h index fa03389..3a11456 100644 --- a/SDL2-2.0.12/include/SDL_config_winrt.h +++ b/SDL2-2.30.5/include/SDL_config_winrt.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -42,64 +42,25 @@ /* This is a set of defines to configure the SDL features */ -#if !defined(_STDINT_H_) && (!defined(HAVE_STDINT_H) || !_HAVE_STDINT_H) -#if defined(__GNUC__) || defined(__DMC__) || defined(__WATCOMC__) -#define HAVE_STDINT_H 1 -#elif defined(_MSC_VER) -typedef signed __int8 int8_t; -typedef unsigned __int8 uint8_t; -typedef signed __int16 int16_t; -typedef unsigned __int16 uint16_t; -typedef signed __int32 int32_t; -typedef unsigned __int32 uint32_t; -typedef signed __int64 int64_t; -typedef unsigned __int64 uint64_t; -#ifndef _UINTPTR_T_DEFINED -#ifdef _WIN64 -typedef unsigned __int64 uintptr_t; -#else -typedef unsigned int uintptr_t; -#endif -#define _UINTPTR_T_DEFINED -#endif -/* Older Visual C++ headers don't have the Win64-compatible typedefs... */ -#if ((_MSC_VER <= 1200) && (!defined(DWORD_PTR))) -#define DWORD_PTR DWORD -#endif -#if ((_MSC_VER <= 1200) && (!defined(LONG_PTR))) -#define LONG_PTR LONG -#endif -#else /* !__GNUC__ && !_MSC_VER */ -typedef signed char int8_t; -typedef unsigned char uint8_t; -typedef signed short int16_t; -typedef unsigned short uint16_t; -typedef signed int int32_t; -typedef unsigned int uint32_t; -typedef signed long long int64_t; -typedef unsigned long long uint64_t; -#ifndef _SIZE_T_DEFINED_ -#define _SIZE_T_DEFINED_ -typedef unsigned int size_t; -#endif -typedef unsigned int uintptr_t; -#endif /* __GNUC__ || _MSC_VER */ -#endif /* !_STDINT_H_ && !HAVE_STDINT_H */ - #ifdef _WIN64 # define SIZEOF_VOIDP 8 #else # define SIZEOF_VOIDP 4 #endif +#ifdef __clang__ +# define HAVE_GCC_ATOMICS 1 +#endif + /* Useful headers */ #define HAVE_DXGI_H 1 -#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP +#if !SDL_WINAPI_FAMILY_PHONE #define HAVE_XINPUT_H 1 #endif #define HAVE_MMDEVICEAPI_H 1 #define HAVE_AUDIOCLIENT_H 1 +#define HAVE_TPCSHRD_H 1 #define HAVE_LIBC 1 #define STDC_HEADERS 1 @@ -108,6 +69,7 @@ typedef unsigned int uintptr_t; #define HAVE_LIMITS_H 1 #define HAVE_MATH_H 1 #define HAVE_SIGNAL_H 1 +#define HAVE_STDINT_H 1 #define HAVE_STDIO_H 1 #define HAVE_STRING_H 1 @@ -118,6 +80,7 @@ typedef unsigned int uintptr_t; #define HAVE_FREE 1 #define HAVE_ALLOCA 1 #define HAVE_QSORT 1 +#define HAVE_BSEARCH 1 #define HAVE_ABS 1 #define HAVE_MEMSET 1 #define HAVE_MEMCPY 1 @@ -126,17 +89,13 @@ typedef unsigned int uintptr_t; #define HAVE_STRLEN 1 #define HAVE__STRREV 1 #define HAVE__STRUPR 1 -//#define HAVE__STRLWR 1 // TODO, WinRT: consider using _strlwr_s instead #define HAVE_STRCHR 1 #define HAVE_STRRCHR 1 #define HAVE_STRSTR 1 -#define HAVE_STRTOK_S 1 -//#define HAVE_ITOA 1 // TODO, WinRT: consider using _itoa_s instead -//#define HAVE__LTOA 1 // TODO, WinRT: consider using _ltoa_s instead -//#define HAVE__ULTOA 1 // TODO, WinRT: consider using _ultoa_s instead #define HAVE_STRTOL 1 #define HAVE_STRTOUL 1 -//#define HAVE_STRTOLL 1 +/* #undef HAVE_STRTOLL */ +/* #undef HAVE_STRTOULL */ #define HAVE_STRTOD 1 #define HAVE_ATOI 1 #define HAVE_ATOF 1 @@ -145,7 +104,12 @@ typedef unsigned int uintptr_t; #define HAVE__STRICMP 1 #define HAVE__STRNICMP 1 #define HAVE_VSNPRINTF 1 -//#define HAVE_SSCANF 1 // TODO, WinRT: consider using sscanf_s instead +/* TODO, WinRT: consider using ??_s versions of the following */ +/* #undef HAVE__STRLWR */ +/* #undef HAVE_ITOA */ +/* #undef HAVE__LTOA */ +/* #undef HAVE__ULTOA */ +/* #undef HAVE_SSCANF */ #define HAVE_M_PI 1 #define HAVE_ACOS 1 #define HAVE_ACOSF 1 @@ -172,8 +136,12 @@ typedef unsigned int uintptr_t; #define HAVE_LOGF 1 #define HAVE_LOG10 1 #define HAVE_LOG10F 1 +#define HAVE_LROUND 1 +#define HAVE_LROUNDF 1 #define HAVE_POW 1 #define HAVE_POWF 1 +#define HAVE_ROUND 1 +#define HAVE_ROUNDF 1 #define HAVE__SCALB 1 #define HAVE_SIN 1 #define HAVE_SINF 1 @@ -181,22 +149,35 @@ typedef unsigned int uintptr_t; #define HAVE_SQRTF 1 #define HAVE_TAN 1 #define HAVE_TANF 1 +#define HAVE_TRUNC 1 +#define HAVE_TRUNCF 1 #define HAVE__FSEEKI64 1 +#define HAVE_ROAPI_H 1 + /* Enable various audio drivers */ #define SDL_AUDIO_DRIVER_WASAPI 1 #define SDL_AUDIO_DRIVER_DISK 1 #define SDL_AUDIO_DRIVER_DUMMY 1 /* Enable various input drivers */ -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP +#if SDL_WINAPI_FAMILY_PHONE #define SDL_JOYSTICK_DISABLED 1 #define SDL_HAPTIC_DISABLED 1 #else +#define SDL_JOYSTICK_VIRTUAL 1 +#if (NTDDI_VERSION >= NTDDI_WIN10) +#define SDL_JOYSTICK_WGI 1 +#define SDL_HAPTIC_DISABLED 1 +#else #define SDL_JOYSTICK_XINPUT 1 #define SDL_HAPTIC_XINPUT 1 +#endif /* WIN10 */ #endif +/* WinRT doesn't have HIDAPI available */ +#define SDL_HIDAPI_DISABLED 1 + /* Enable the dummy sensor driver */ #define SDL_SENSOR_DUMMY 1 @@ -205,6 +186,7 @@ typedef unsigned int uintptr_t; /* Enable various threading systems */ #if (NTDDI_VERSION >= NTDDI_WINBLUE) +#define SDL_THREAD_GENERIC_COND_SUFFIX 1 #define SDL_THREAD_WINDOWS 1 #else /* WinRT on Windows 8.0 and Windows Phone 8.0 don't support CreateThread() */ @@ -225,16 +207,14 @@ typedef unsigned int uintptr_t; /* Enable appropriate renderer(s) */ #define SDL_VIDEO_RENDER_D3D11 1 -#if SDL_VIDEO_OPENGL_ES2 +/* Disable D3D12 as it's not implemented for WinRT */ +/* #undef SDL_VIDEO_RENDER_D3D12 */ + +#ifdef SDL_VIDEO_OPENGL_ES2 #define SDL_VIDEO_RENDER_OGL_ES2 1 #endif /* Enable system power support */ #define SDL_POWER_WINRT 1 -/* Enable assembly routines (Win64 doesn't have inline asm) */ -#ifndef _WIN64 -#define SDL_ASSEMBLY_ROUTINES 1 -#endif - #endif /* SDL_config_winrt_h_ */ diff --git a/SDL2-2.30.5/include/SDL_config_xbox.h b/SDL2-2.30.5/include/SDL_config_xbox.h new file mode 100644 index 0000000..a2ea8cb --- /dev/null +++ b/SDL2-2.30.5/include/SDL_config_xbox.h @@ -0,0 +1,240 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#ifndef SDL_config_wingdk_h_ +#define SDL_config_wingdk_h_ +#define SDL_config_h_ + +#include "SDL_platform.h" + +/* Windows GDK does not need Windows SDK version checks because it requires + * a recent version of the Windows 10 SDK. */ + +/* GDK only supports 64-bit */ +# define SIZEOF_VOIDP 8 + +#ifdef __clang__ +# define HAVE_GCC_ATOMICS 1 +#endif + +/*#define HAVE_DDRAW_H 1*/ +/*#define HAVE_DINPUT_H 1*/ +/*#define HAVE_DSOUND_H 1*/ +/* No SDK version checks needed for these because the SDK has to be new. */ +/* #define HAVE_DXGI_H 1 */ +#define HAVE_XINPUT_H 1 +/*#define HAVE_WINDOWS_GAMING_INPUT_H 1*/ +/*#define HAVE_D3D11_H 1*/ +/*#define HAVE_ROAPI_H 1*/ +#define HAVE_D3D12_H 1 +/*#define HAVE_SHELLSCALINGAPI_H 1*/ +#define HAVE_MMDEVICEAPI_H 1 +#define HAVE_AUDIOCLIENT_H 1 +/*#define HAVE_TPCSHRD_H 1*/ +/*#define HAVE_SENSORSAPI_H 1*/ +#if (defined(_M_IX86) || defined(_M_X64) || defined(_M_AMD64)) && (defined(_MSC_VER) && _MSC_VER >= 1600) +#define HAVE_IMMINTRIN_H 1 +#elif defined(__has_include) && (defined(__i386__) || defined(__x86_64)) +# if __has_include() +# define HAVE_IMMINTRIN_H 1 +# endif +#endif + +/* This is disabled by default to avoid C runtime dependencies and manifest requirements */ +#ifdef HAVE_LIBC +/* Useful headers */ +#define STDC_HEADERS 1 +#define HAVE_CTYPE_H 1 +#define HAVE_FLOAT_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_MATH_H 1 +#define HAVE_SIGNAL_H 1 +#define HAVE_STDINT_H 1 +#define HAVE_STDIO_H 1 +#define HAVE_STRING_H 1 + +/* C library functions */ +#define HAVE_MALLOC 1 +#define HAVE_CALLOC 1 +#define HAVE_REALLOC 1 +#define HAVE_FREE 1 +#define HAVE_ALLOCA 1 +#define HAVE_QSORT 1 +#define HAVE_BSEARCH 1 +#define HAVE_ABS 1 +#define HAVE_MEMSET 1 +#define HAVE_MEMCPY 1 +#define HAVE_MEMMOVE 1 +#define HAVE_MEMCMP 1 +#define HAVE_STRLEN 1 +#define HAVE__STRREV 1 +/* These functions have security warnings, so we won't use them */ +/* #undef HAVE__STRUPR */ +/* #undef HAVE__STRLWR */ +#define HAVE_STRCHR 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSTR 1 +/* #undef HAVE_STRTOK_R */ +/* These functions have security warnings, so we won't use them */ +/* #undef HAVE__LTOA */ +/* #undef HAVE__ULTOA */ +#define HAVE_STRTOL 1 +#define HAVE_STRTOUL 1 +#define HAVE_STRTOD 1 +#define HAVE_ATOI 1 +#define HAVE_ATOF 1 +#define HAVE_STRCMP 1 +#define HAVE_STRNCMP 1 +#define HAVE__STRICMP 1 +#define HAVE__STRNICMP 1 +#define HAVE__WCSICMP 1 +#define HAVE__WCSNICMP 1 +#define HAVE__WCSDUP 1 +#define HAVE_ACOS 1 +#define HAVE_ASIN 1 +#define HAVE_ATAN 1 +#define HAVE_ATAN2 1 +#define HAVE_CEIL 1 +#define HAVE_COS 1 +#define HAVE_EXP 1 +#define HAVE_FABS 1 +#define HAVE_FLOOR 1 +#define HAVE_FMOD 1 +#define HAVE_LOG 1 +#define HAVE_LOG10 1 +#define HAVE_POW 1 +#define HAVE_SIN 1 +#define HAVE_SQRT 1 +#define HAVE_TAN 1 +#define HAVE_ACOSF 1 +#define HAVE_ASINF 1 +#define HAVE_ATANF 1 +#define HAVE_ATAN2F 1 +#define HAVE_CEILF 1 +#define HAVE__COPYSIGN 1 +#define HAVE_COSF 1 +#define HAVE_EXPF 1 +#define HAVE_FABSF 1 +#define HAVE_FLOORF 1 +#define HAVE_FMODF 1 +#define HAVE_LOGF 1 +#define HAVE_LOG10F 1 +#define HAVE_POWF 1 +#define HAVE_SINF 1 +#define HAVE_SQRTF 1 +#define HAVE_TANF 1 +#if defined(_MSC_VER) +/* These functions were added with the VC++ 2013 C runtime library */ +#define HAVE_STRTOLL 1 +#define HAVE_STRTOULL 1 +#define HAVE_VSSCANF 1 +#define HAVE_LROUND 1 +#define HAVE_LROUNDF 1 +#define HAVE_ROUND 1 +#define HAVE_ROUNDF 1 +#define HAVE_SCALBN 1 +#define HAVE_SCALBNF 1 +#define HAVE_TRUNC 1 +#define HAVE_TRUNCF 1 +#define HAVE__FSEEKI64 1 +#ifdef _USE_MATH_DEFINES +#define HAVE_M_PI 1 +#endif +#else +#define HAVE_M_PI 1 +#endif +#else +#define HAVE_STDARG_H 1 +#define HAVE_STDDEF_H 1 +#define HAVE_STDINT_H 1 +#endif + +/* Enable various audio drivers */ +#if defined(HAVE_MMDEVICEAPI_H) && defined(HAVE_AUDIOCLIENT_H) +#define SDL_AUDIO_DRIVER_WASAPI 1 +#endif +/*#define SDL_AUDIO_DRIVER_DSOUND 1*/ +/*#define SDL_AUDIO_DRIVER_WINMM 1*/ +#define SDL_AUDIO_DRIVER_DISK 1 +#define SDL_AUDIO_DRIVER_DUMMY 1 + +/* Enable various input drivers */ +/*#define SDL_JOYSTICK_DINPUT 1*/ +/*#define SDL_JOYSTICK_HIDAPI 1*/ +/*#define SDL_JOYSTICK_RAWINPUT 1*/ +#define SDL_JOYSTICK_VIRTUAL 1 +#ifdef HAVE_WINDOWS_GAMING_INPUT_H +#define SDL_JOYSTICK_WGI 1 +#endif +#define SDL_JOYSTICK_XINPUT 1 +/*#define SDL_HAPTIC_DINPUT 1*/ +#define SDL_HAPTIC_XINPUT 1 + +/* Enable the sensor driver */ +#ifdef HAVE_SENSORSAPI_H +#define SDL_SENSOR_WINDOWS 1 +#else +#define SDL_SENSOR_DUMMY 1 +#endif + +/* Enable various shared object loading systems */ +#define SDL_LOADSO_WINDOWS 1 + +/* Enable various threading systems */ +#define SDL_THREAD_GENERIC_COND_SUFFIX 1 +#define SDL_THREAD_WINDOWS 1 + +/* Enable various timer systems */ +#define SDL_TIMER_WINDOWS 1 + +/* Enable various video drivers */ +#define SDL_VIDEO_DRIVER_DUMMY 1 +#define SDL_VIDEO_DRIVER_WINDOWS 1 + +#if !defined(SDL_VIDEO_RENDER_D3D12) && defined(HAVE_D3D12_H) +#define SDL_VIDEO_RENDER_D3D12 1 +#endif + +/* Enable OpenGL support */ +#ifndef SDL_VIDEO_OPENGL +#define SDL_VIDEO_OPENGL 1 +#endif +#ifndef SDL_VIDEO_OPENGL_WGL +#define SDL_VIDEO_OPENGL_WGL 1 +#endif +#ifndef SDL_VIDEO_RENDER_OGL +#define SDL_VIDEO_RENDER_OGL 1 +#endif + +/* Enable system power support */ +/*#define SDL_POWER_WINDOWS 1*/ +#define SDL_POWER_HARDWIRED 1 + +/* Enable filesystem support */ +/* #define SDL_FILESYSTEM_WINDOWS 1*/ +#define SDL_FILESYSTEM_XBOX 1 + +/* Disable IME as not supported yet (TODO: Xbox IME?) */ +#define SDL_DISABLE_WINDOWS_IME 1 + +#endif /* SDL_config_wingdk_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/include/SDL_copying.h b/SDL2-2.30.5/include/SDL_copying.h similarity index 93% rename from SDL2-2.0.12/include/SDL_copying.h rename to SDL2-2.30.5/include/SDL_copying.h index 4f8a2bc..da90893 100644 --- a/SDL2-2.0.12/include/SDL_copying.h +++ b/SDL2-2.30.5/include/SDL_copying.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.30.5/include/SDL_cpuinfo.h b/SDL2-2.30.5/include/SDL_cpuinfo.h new file mode 100644 index 0000000..2a9dd38 --- /dev/null +++ b/SDL2-2.30.5/include/SDL_cpuinfo.h @@ -0,0 +1,594 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_cpuinfo.h + * + * CPU feature detection for SDL. + */ + +#ifndef SDL_cpuinfo_h_ +#define SDL_cpuinfo_h_ + +#include "SDL_stdinc.h" + +/* Need to do this here because intrin.h has C++ code in it */ +/* Visual Studio 2005 has a bug where intrin.h conflicts with winnt.h */ +#if defined(_MSC_VER) && (_MSC_VER >= 1500) && (defined(_M_IX86) || defined(_M_X64)) +#ifdef __clang__ +/* As of Clang 11, '_m_prefetchw' is conflicting with the winnt.h's version, + so we define the needed '_m_prefetch' here as a pseudo-header, until the issue is fixed. */ + +#ifndef __PRFCHWINTRIN_H +#define __PRFCHWINTRIN_H + +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +_m_prefetch(void *__P) +{ + __builtin_prefetch (__P, 0, 3 /* _MM_HINT_T0 */); +} + +#endif /* __PRFCHWINTRIN_H */ +#endif /* __clang__ */ +#include +#ifndef _WIN64 +#ifndef __MMX__ +#define __MMX__ +#endif +#ifndef __3dNOW__ +#define __3dNOW__ +#endif +#endif +#ifndef __SSE__ +#define __SSE__ +#endif +#ifndef __SSE2__ +#define __SSE2__ +#endif +#ifndef __SSE3__ +#define __SSE3__ +#endif +#elif defined(__MINGW64_VERSION_MAJOR) +#include +#if !defined(SDL_DISABLE_ARM_NEON_H) && defined(__ARM_NEON) +# include +#endif +#else +/* altivec.h redefining bool causes a number of problems, see bugs 3993 and 4392, so you need to explicitly define SDL_ENABLE_ALTIVEC_H to have it included. */ +#if defined(HAVE_ALTIVEC_H) && defined(__ALTIVEC__) && !defined(__APPLE_ALTIVEC__) && defined(SDL_ENABLE_ALTIVEC_H) +#include +#endif +#if !defined(SDL_DISABLE_ARM_NEON_H) +# if defined(__ARM_NEON) +# include +# elif defined(__WINDOWS__) || defined(__WINRT__) || defined(__GDK__) +/* Visual Studio doesn't define __ARM_ARCH, but _M_ARM (if set, always 7), and _M_ARM64 (if set, always 1). */ +# if defined(_M_ARM) +# include +# include +# define __ARM_NEON 1 /* Set __ARM_NEON so that it can be used elsewhere, at compile time */ +# endif +# if defined (_M_ARM64) +# include +# include +# define __ARM_NEON 1 /* Set __ARM_NEON so that it can be used elsewhere, at compile time */ +# define __ARM_ARCH 8 +# endif +# endif +#endif +#endif /* compiler version */ + +#if defined(__3dNOW__) && !defined(SDL_DISABLE_MM3DNOW_H) +#include +#endif +#if defined(__loongarch_sx) && !defined(SDL_DISABLE_LSX_H) +#include +#define __LSX__ +#endif +#if defined(__loongarch_asx) && !defined(SDL_DISABLE_LASX_H) +#include +#define __LASX__ +#endif +#if defined(HAVE_IMMINTRIN_H) && !defined(SDL_DISABLE_IMMINTRIN_H) +#include +#else +#if defined(__MMX__) && !defined(SDL_DISABLE_MMINTRIN_H) +#include +#endif +#if defined(__SSE__) && !defined(SDL_DISABLE_XMMINTRIN_H) +#include +#endif +#if defined(__SSE2__) && !defined(SDL_DISABLE_EMMINTRIN_H) +#include +#endif +#if defined(__SSE3__) && !defined(SDL_DISABLE_PMMINTRIN_H) +#include +#endif +#endif /* HAVE_IMMINTRIN_H */ + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* This is a guess for the cacheline size used for padding. + * Most x86 processors have a 64 byte cache line. + * The 64-bit PowerPC processors have a 128 byte cache line. + * We'll use the larger value to be generally safe. + */ +#define SDL_CACHELINE_SIZE 128 + +/** + * Get the number of CPU cores available. + * + * \returns the total number of logical CPU cores. On CPUs that include + * technologies such as hyperthreading, the number of logical cores + * may be more than the number of physical cores. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC int SDLCALL SDL_GetCPUCount(void); + +/** + * Determine the L1 cache line size of the CPU. + * + * This is useful for determining multi-threaded structure padding or SIMD + * prefetch sizes. + * + * \returns the L1 cache line size of the CPU, in bytes. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC int SDLCALL SDL_GetCPUCacheLineSize(void); + +/** + * Determine whether the CPU has the RDTSC instruction. + * + * This always returns false on CPUs that aren't using Intel instruction sets. + * + * \returns SDL_TRUE if the CPU has the RDTSC instruction or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Has3DNow + * \sa SDL_HasAltiVec + * \sa SDL_HasAVX + * \sa SDL_HasAVX2 + * \sa SDL_HasMMX + * \sa SDL_HasSSE + * \sa SDL_HasSSE2 + * \sa SDL_HasSSE3 + * \sa SDL_HasSSE41 + * \sa SDL_HasSSE42 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasRDTSC(void); + +/** + * Determine whether the CPU has AltiVec features. + * + * This always returns false on CPUs that aren't using PowerPC instruction + * sets. + * + * \returns SDL_TRUE if the CPU has AltiVec features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Has3DNow + * \sa SDL_HasAVX + * \sa SDL_HasAVX2 + * \sa SDL_HasMMX + * \sa SDL_HasRDTSC + * \sa SDL_HasSSE + * \sa SDL_HasSSE2 + * \sa SDL_HasSSE3 + * \sa SDL_HasSSE41 + * \sa SDL_HasSSE42 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasAltiVec(void); + +/** + * Determine whether the CPU has MMX features. + * + * This always returns false on CPUs that aren't using Intel instruction sets. + * + * \returns SDL_TRUE if the CPU has MMX features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Has3DNow + * \sa SDL_HasAltiVec + * \sa SDL_HasAVX + * \sa SDL_HasAVX2 + * \sa SDL_HasRDTSC + * \sa SDL_HasSSE + * \sa SDL_HasSSE2 + * \sa SDL_HasSSE3 + * \sa SDL_HasSSE41 + * \sa SDL_HasSSE42 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasMMX(void); + +/** + * Determine whether the CPU has 3DNow! features. + * + * This always returns false on CPUs that aren't using AMD instruction sets. + * + * \returns SDL_TRUE if the CPU has 3DNow! features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HasAltiVec + * \sa SDL_HasAVX + * \sa SDL_HasAVX2 + * \sa SDL_HasMMX + * \sa SDL_HasRDTSC + * \sa SDL_HasSSE + * \sa SDL_HasSSE2 + * \sa SDL_HasSSE3 + * \sa SDL_HasSSE41 + * \sa SDL_HasSSE42 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_Has3DNow(void); + +/** + * Determine whether the CPU has SSE features. + * + * This always returns false on CPUs that aren't using Intel instruction sets. + * + * \returns SDL_TRUE if the CPU has SSE features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Has3DNow + * \sa SDL_HasAltiVec + * \sa SDL_HasAVX + * \sa SDL_HasAVX2 + * \sa SDL_HasMMX + * \sa SDL_HasRDTSC + * \sa SDL_HasSSE2 + * \sa SDL_HasSSE3 + * \sa SDL_HasSSE41 + * \sa SDL_HasSSE42 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE(void); + +/** + * Determine whether the CPU has SSE2 features. + * + * This always returns false on CPUs that aren't using Intel instruction sets. + * + * \returns SDL_TRUE if the CPU has SSE2 features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Has3DNow + * \sa SDL_HasAltiVec + * \sa SDL_HasAVX + * \sa SDL_HasAVX2 + * \sa SDL_HasMMX + * \sa SDL_HasRDTSC + * \sa SDL_HasSSE + * \sa SDL_HasSSE3 + * \sa SDL_HasSSE41 + * \sa SDL_HasSSE42 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE2(void); + +/** + * Determine whether the CPU has SSE3 features. + * + * This always returns false on CPUs that aren't using Intel instruction sets. + * + * \returns SDL_TRUE if the CPU has SSE3 features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Has3DNow + * \sa SDL_HasAltiVec + * \sa SDL_HasAVX + * \sa SDL_HasAVX2 + * \sa SDL_HasMMX + * \sa SDL_HasRDTSC + * \sa SDL_HasSSE + * \sa SDL_HasSSE2 + * \sa SDL_HasSSE41 + * \sa SDL_HasSSE42 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE3(void); + +/** + * Determine whether the CPU has SSE4.1 features. + * + * This always returns false on CPUs that aren't using Intel instruction sets. + * + * \returns SDL_TRUE if the CPU has SSE4.1 features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Has3DNow + * \sa SDL_HasAltiVec + * \sa SDL_HasAVX + * \sa SDL_HasAVX2 + * \sa SDL_HasMMX + * \sa SDL_HasRDTSC + * \sa SDL_HasSSE + * \sa SDL_HasSSE2 + * \sa SDL_HasSSE3 + * \sa SDL_HasSSE42 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE41(void); + +/** + * Determine whether the CPU has SSE4.2 features. + * + * This always returns false on CPUs that aren't using Intel instruction sets. + * + * \returns SDL_TRUE if the CPU has SSE4.2 features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Has3DNow + * \sa SDL_HasAltiVec + * \sa SDL_HasAVX + * \sa SDL_HasAVX2 + * \sa SDL_HasMMX + * \sa SDL_HasRDTSC + * \sa SDL_HasSSE + * \sa SDL_HasSSE2 + * \sa SDL_HasSSE3 + * \sa SDL_HasSSE41 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE42(void); + +/** + * Determine whether the CPU has AVX features. + * + * This always returns false on CPUs that aren't using Intel instruction sets. + * + * \returns SDL_TRUE if the CPU has AVX features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.2. + * + * \sa SDL_Has3DNow + * \sa SDL_HasAltiVec + * \sa SDL_HasAVX2 + * \sa SDL_HasMMX + * \sa SDL_HasRDTSC + * \sa SDL_HasSSE + * \sa SDL_HasSSE2 + * \sa SDL_HasSSE3 + * \sa SDL_HasSSE41 + * \sa SDL_HasSSE42 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasAVX(void); + +/** + * Determine whether the CPU has AVX2 features. + * + * This always returns false on CPUs that aren't using Intel instruction sets. + * + * \returns SDL_TRUE if the CPU has AVX2 features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.4. + * + * \sa SDL_Has3DNow + * \sa SDL_HasAltiVec + * \sa SDL_HasAVX + * \sa SDL_HasMMX + * \sa SDL_HasRDTSC + * \sa SDL_HasSSE + * \sa SDL_HasSSE2 + * \sa SDL_HasSSE3 + * \sa SDL_HasSSE41 + * \sa SDL_HasSSE42 + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasAVX2(void); + +/** + * Determine whether the CPU has AVX-512F (foundation) features. + * + * This always returns false on CPUs that aren't using Intel instruction sets. + * + * \returns SDL_TRUE if the CPU has AVX-512F features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.9. + * + * \sa SDL_HasAVX + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasAVX512F(void); + +/** + * Determine whether the CPU has ARM SIMD (ARMv6) features. + * + * This is different from ARM NEON, which is a different instruction set. + * + * This always returns false on CPUs that aren't using ARM instruction sets. + * + * \returns SDL_TRUE if the CPU has ARM SIMD features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.12. + * + * \sa SDL_HasNEON + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasARMSIMD(void); + +/** + * Determine whether the CPU has NEON (ARM SIMD) features. + * + * This always returns false on CPUs that aren't using ARM instruction sets. + * + * \returns SDL_TRUE if the CPU has ARM NEON features or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasNEON(void); + +/** + * Determine whether the CPU has LSX (LOONGARCH SIMD) features. + * + * This always returns false on CPUs that aren't using LOONGARCH instruction + * sets. + * + * \returns SDL_TRUE if the CPU has LOONGARCH LSX features or SDL_FALSE if + * not. + * + * \since This function is available since SDL 2.24.0. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasLSX(void); + +/** + * Determine whether the CPU has LASX (LOONGARCH SIMD) features. + * + * This always returns false on CPUs that aren't using LOONGARCH instruction + * sets. + * + * \returns SDL_TRUE if the CPU has LOONGARCH LASX features or SDL_FALSE if + * not. + * + * \since This function is available since SDL 2.24.0. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasLASX(void); + +/** + * Get the amount of RAM configured in the system. + * + * \returns the amount of RAM configured in the system in MiB. + * + * \since This function is available since SDL 2.0.1. + */ +extern DECLSPEC int SDLCALL SDL_GetSystemRAM(void); + +/** + * Report the alignment this system needs for SIMD allocations. + * + * This will return the minimum number of bytes to which a pointer must be + * aligned to be compatible with SIMD instructions on the current machine. For + * example, if the machine supports SSE only, it will return 16, but if it + * supports AVX-512F, it'll return 64 (etc). This only reports values for + * instruction sets SDL knows about, so if your SDL build doesn't have + * SDL_HasAVX512F(), then it might return 16 for the SSE support it sees and + * not 64 for the AVX-512 instructions that exist but SDL doesn't know about. + * Plan accordingly. + * + * \returns the alignment in bytes needed for available, known SIMD + * instructions. + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC size_t SDLCALL SDL_SIMDGetAlignment(void); + +/** + * Allocate memory in a SIMD-friendly way. + * + * This will allocate a block of memory that is suitable for use with SIMD + * instructions. Specifically, it will be properly aligned and padded for the + * system's supported vector instructions. + * + * The memory returned will be padded such that it is safe to read or write an + * incomplete vector at the end of the memory block. This can be useful so you + * don't have to drop back to a scalar fallback at the end of your SIMD + * processing loop to deal with the final elements without overflowing the + * allocated buffer. + * + * You must free this memory with SDL_FreeSIMD(), not free() or SDL_free() or + * delete[], etc. + * + * Note that SDL will only deal with SIMD instruction sets it is aware of; for + * example, SDL 2.0.8 knows that SSE wants 16-byte vectors (SDL_HasSSE()), and + * AVX2 wants 32 bytes (SDL_HasAVX2()), but doesn't know that AVX-512 wants + * 64. To be clear: if you can't decide to use an instruction set with an + * SDL_Has*() function, don't use that instruction set with memory allocated + * through here. + * + * SDL_AllocSIMD(0) will return a non-NULL pointer, assuming the system isn't + * out of memory, but you are not allowed to dereference it (because you only + * own zero bytes of that buffer). + * + * \param len The length, in bytes, of the block to allocate. The actual + * allocated block might be larger due to padding, etc. + * \returns a pointer to the newly-allocated block, NULL if out of memory. + * + * \since This function is available since SDL 2.0.10. + * + * \sa SDL_SIMDGetAlignment + * \sa SDL_SIMDRealloc + * \sa SDL_SIMDFree + */ +extern DECLSPEC void * SDLCALL SDL_SIMDAlloc(const size_t len); + +/** + * Reallocate memory obtained from SDL_SIMDAlloc + * + * It is not valid to use this function on a pointer from anything but + * SDL_SIMDAlloc(). It can't be used on pointers from malloc, realloc, + * SDL_malloc, memalign, new[], etc. + * + * \param mem The pointer obtained from SDL_SIMDAlloc. This function also + * accepts NULL, at which point this function is the same as + * calling SDL_SIMDAlloc with a NULL pointer. + * \param len The length, in bytes, of the block to allocated. The actual + * allocated block might be larger due to padding, etc. Passing 0 + * will return a non-NULL pointer, assuming the system isn't out of + * memory. + * \returns a pointer to the newly-reallocated block, NULL if out of memory. + * + * \since This function is available since SDL 2.0.14. + * + * \sa SDL_SIMDGetAlignment + * \sa SDL_SIMDAlloc + * \sa SDL_SIMDFree + */ +extern DECLSPEC void * SDLCALL SDL_SIMDRealloc(void *mem, const size_t len); + +/** + * Deallocate memory obtained from SDL_SIMDAlloc + * + * It is not valid to use this function on a pointer from anything but + * SDL_SIMDAlloc() or SDL_SIMDRealloc(). It can't be used on pointers from + * malloc, realloc, SDL_malloc, memalign, new[], etc. + * + * However, SDL_SIMDFree(NULL) is a legal no-op. + * + * The memory pointed to by `ptr` is no longer valid for access upon return, + * and may be returned to the system or reused by a future allocation. The + * pointer passed to this function is no longer safe to dereference once this + * function returns, and should be discarded. + * + * \param ptr The pointer, returned from SDL_SIMDAlloc or SDL_SIMDRealloc, to + * deallocate. NULL is a legal no-op. + * + * \since This function is available since SDL 2.0.10. + * + * \sa SDL_SIMDAlloc + * \sa SDL_SIMDRealloc + */ +extern DECLSPEC void SDLCALL SDL_SIMDFree(void *ptr); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_cpuinfo_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/include/SDL_egl.h b/SDL2-2.30.5/include/SDL_egl.h similarity index 56% rename from SDL2-2.0.12/include/SDL_egl.h rename to SDL2-2.30.5/include/SDL_egl.h index 531441e..a4276e6 100644 --- a/SDL2-2.0.12/include/SDL_egl.h +++ b/SDL2-2.30.5/include/SDL_egl.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -24,7 +24,11 @@ * * This is a simple file to encapsulate the EGL API headers. */ -#if !defined(_MSC_VER) && !defined(__ANDROID__) +#if !defined(_MSC_VER) && !defined(__ANDROID__) && !defined(SDL_USE_BUILTIN_OPENGL_DEFINITIONS) + +#if defined(__vita__) || defined(__psp2__) +#include +#endif #include #include @@ -37,7 +41,7 @@ #define __khrplatform_h_ /* -** Copyright (c) 2008-2009 The Khronos Group Inc. +** Copyright (c) 2008-2018 The Khronos Group Inc. ** ** Permission is hereby granted, free of charge, to any person obtaining a ** copy of this software and/or associated documentation files (the @@ -60,104 +64,112 @@ */ /* Khronos platform-specific types and definitions. -* -* $Revision: 23298 $ on $Date: 2013-09-30 17:07:13 -0700 (Mon, 30 Sep 2013) $ -* -* Adopters may modify this file to suit their platform. Adopters are -* encouraged to submit platform specific modifications to the Khronos -* group so that they can be included in future versions of this file. -* Please submit changes by sending them to the public Khronos Bugzilla -* (http://khronos.org/bugzilla) by filing a bug against product -* "Khronos (general)" component "Registry". -* -* A predefined template which fills in some of the bug fields can be -* reached using http://tinyurl.com/khrplatform-h-bugreport, but you -* must create a Bugzilla login first. -* -* -* See the Implementer's Guidelines for information about where this file -* should be located on your system and for more details of its use: -* http://www.khronos.org/registry/implementers_guide.pdf -* -* This file should be included as -* #include -* by Khronos client API header files that use its types and defines. -* -* The types in khrplatform.h should only be used to define API-specific types. -* -* Types defined in khrplatform.h: -* khronos_int8_t signed 8 bit -* khronos_uint8_t unsigned 8 bit -* khronos_int16_t signed 16 bit -* khronos_uint16_t unsigned 16 bit -* khronos_int32_t signed 32 bit -* khronos_uint32_t unsigned 32 bit -* khronos_int64_t signed 64 bit -* khronos_uint64_t unsigned 64 bit -* khronos_intptr_t signed same number of bits as a pointer -* khronos_uintptr_t unsigned same number of bits as a pointer -* khronos_ssize_t signed size -* khronos_usize_t unsigned size -* khronos_float_t signed 32 bit floating point -* khronos_time_ns_t unsigned 64 bit time in nanoseconds -* khronos_utime_nanoseconds_t unsigned time interval or absolute time in -* nanoseconds -* khronos_stime_nanoseconds_t signed time interval in nanoseconds -* khronos_boolean_enum_t enumerated boolean type. This should -* only be used as a base type when a client API's boolean type is -* an enum. Client APIs which use an integer or other type for -* booleans cannot use this as the base type for their boolean. -* -* Tokens defined in khrplatform.h: -* -* KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values. -* -* KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0. -* KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0. -* -* Calling convention macros defined in this file: -* KHRONOS_APICALL -* KHRONOS_APIENTRY -* KHRONOS_APIATTRIBUTES -* -* These may be used in function prototypes as: -* -* KHRONOS_APICALL void KHRONOS_APIENTRY funcname( -* int arg1, -* int arg2) KHRONOS_APIATTRIBUTES; -*/ + * + * The master copy of khrplatform.h is maintained in the Khronos EGL + * Registry repository at https://github.com/KhronosGroup/EGL-Registry + * The last semantic modification to khrplatform.h was at commit ID: + * 67a3e0864c2d75ea5287b9f3d2eb74a745936692 + * + * Adopters may modify this file to suit their platform. Adopters are + * encouraged to submit platform specific modifications to the Khronos + * group so that they can be included in future versions of this file. + * Please submit changes by filing pull requests or issues on + * the EGL Registry repository linked above. + * + * + * See the Implementer's Guidelines for information about where this file + * should be located on your system and for more details of its use: + * http://www.khronos.org/registry/implementers_guide.pdf + * + * This file should be included as + * #include + * by Khronos client API header files that use its types and defines. + * + * The types in khrplatform.h should only be used to define API-specific types. + * + * Types defined in khrplatform.h: + * khronos_int8_t signed 8 bit + * khronos_uint8_t unsigned 8 bit + * khronos_int16_t signed 16 bit + * khronos_uint16_t unsigned 16 bit + * khronos_int32_t signed 32 bit + * khronos_uint32_t unsigned 32 bit + * khronos_int64_t signed 64 bit + * khronos_uint64_t unsigned 64 bit + * khronos_intptr_t signed same number of bits as a pointer + * khronos_uintptr_t unsigned same number of bits as a pointer + * khronos_ssize_t signed size + * khronos_usize_t unsigned size + * khronos_float_t signed 32 bit floating point + * khronos_time_ns_t unsigned 64 bit time in nanoseconds + * khronos_utime_nanoseconds_t unsigned time interval or absolute time in + * nanoseconds + * khronos_stime_nanoseconds_t signed time interval in nanoseconds + * khronos_boolean_enum_t enumerated boolean type. This should + * only be used as a base type when a client API's boolean type is + * an enum. Client APIs which use an integer or other type for + * booleans cannot use this as the base type for their boolean. + * + * Tokens defined in khrplatform.h: + * + * KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values. + * + * KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0. + * KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0. + * + * Calling convention macros defined in this file: + * KHRONOS_APICALL + * KHRONOS_APIENTRY + * KHRONOS_APIATTRIBUTES + * + * These may be used in function prototypes as: + * + * KHRONOS_APICALL void KHRONOS_APIENTRY funcname( + * int arg1, + * int arg2) KHRONOS_APIATTRIBUTES; + */ + +#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC) +# define KHRONOS_STATIC 1 +#endif /*------------------------------------------------------------------------- -* Definition of KHRONOS_APICALL -*------------------------------------------------------------------------- -* This precedes the return type of the function in the function prototype. -*/ -#if defined(_WIN32) && !defined(__SCITECH_SNAP__) && !defined(SDL_VIDEO_STATIC_ANGLE) + * Definition of KHRONOS_APICALL + *------------------------------------------------------------------------- + * This precedes the return type of the function in the function prototype. + */ +#if defined(KHRONOS_STATIC) + /* If the preprocessor constant KHRONOS_STATIC is defined, make the + * header compatible with static linking. */ +# define KHRONOS_APICALL +#elif defined(_WIN32) # define KHRONOS_APICALL __declspec(dllimport) #elif defined (__SYMBIAN32__) # define KHRONOS_APICALL IMPORT_C +#elif defined(__ANDROID__) +# define KHRONOS_APICALL __attribute__((visibility("default"))) #else # define KHRONOS_APICALL #endif /*------------------------------------------------------------------------- -* Definition of KHRONOS_APIENTRY -*------------------------------------------------------------------------- -* This follows the return type of the function and precedes the function -* name in the function prototype. -*/ + * Definition of KHRONOS_APIENTRY + *------------------------------------------------------------------------- + * This follows the return type of the function and precedes the function + * name in the function prototype. + */ #if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__) -/* Win32 but not WinCE */ + /* Win32 but not WinCE */ # define KHRONOS_APIENTRY __stdcall #else # define KHRONOS_APIENTRY #endif /*------------------------------------------------------------------------- -* Definition of KHRONOS_APIATTRIBUTES -*------------------------------------------------------------------------- -* This follows the closing parenthesis of the function prototype arguments. -*/ + * Definition of KHRONOS_APIATTRIBUTES + *------------------------------------------------------------------------- + * This follows the closing parenthesis of the function prototype arguments. + */ #if defined (__ARMCC_2__) #define KHRONOS_APIATTRIBUTES __softfp #else @@ -165,14 +177,14 @@ #endif /*------------------------------------------------------------------------- -* basic type definitions -*-----------------------------------------------------------------------*/ + * basic type definitions + *-----------------------------------------------------------------------*/ #if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__) /* -* Using -*/ + * Using + */ #include typedef int32_t khronos_int32_t; typedef uint32_t khronos_uint32_t; @@ -180,12 +192,26 @@ typedef int64_t khronos_int64_t; typedef uint64_t khronos_uint64_t; #define KHRONOS_SUPPORT_INT64 1 #define KHRONOS_SUPPORT_FLOAT 1 +/* + * To support platform where unsigned long cannot be used interchangeably with + * inptr_t (e.g. CHERI-extended ISAs), we can use the stdint.h intptr_t. + * Ideally, we could just use (u)intptr_t everywhere, but this could result in + * ABI breakage if khronos_uintptr_t is changed from unsigned long to + * unsigned long long or similar (this results in different C++ name mangling). + * To avoid changes for existing platforms, we restrict usage of intptr_t to + * platforms where the size of a pointer is larger than the size of long. + */ +#if defined(__SIZEOF_LONG__) && defined(__SIZEOF_POINTER__) +#if __SIZEOF_POINTER__ > __SIZEOF_LONG__ +#define KHRONOS_USE_INTPTR_T +#endif +#endif #elif defined(__VMS ) || defined(__sgi) /* -* Using -*/ + * Using + */ #include typedef int32_t khronos_int32_t; typedef uint32_t khronos_uint32_t; @@ -197,8 +223,8 @@ typedef uint64_t khronos_uint64_t; #elif defined(_WIN32) && !defined(__SCITECH_SNAP__) /* -* Win32 -*/ + * Win32 + */ typedef __int32 khronos_int32_t; typedef unsigned __int32 khronos_uint32_t; typedef __int64 khronos_int64_t; @@ -209,8 +235,8 @@ typedef unsigned __int64 khronos_uint64_t; #elif defined(__sun__) || defined(__digital__) /* -* Sun or Digital -*/ + * Sun or Digital + */ typedef int khronos_int32_t; typedef unsigned int khronos_uint32_t; #if defined(__arch64__) || defined(_LP64) @@ -226,8 +252,8 @@ typedef unsigned long long int khronos_uint64_t; #elif 0 /* -* Hypothetical platform with no float or int64 support -*/ + * Hypothetical platform with no float or int64 support + */ typedef int khronos_int32_t; typedef unsigned int khronos_uint32_t; #define KHRONOS_SUPPORT_INT64 0 @@ -236,8 +262,8 @@ typedef unsigned int khronos_uint32_t; #else /* -* Generic fallback -*/ + * Generic fallback + */ #include typedef int32_t khronos_int32_t; typedef uint32_t khronos_uint32_t; @@ -250,67 +276,74 @@ typedef uint64_t khronos_uint64_t; /* -* Types that are (so far) the same on all platforms -*/ + * Types that are (so far) the same on all platforms + */ typedef signed char khronos_int8_t; typedef unsigned char khronos_uint8_t; typedef signed short int khronos_int16_t; typedef unsigned short int khronos_uint16_t; /* -* Types that differ between LLP64 and LP64 architectures - in LLP64, -* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears -* to be the only LLP64 architecture in current use. -*/ -#ifdef _WIN64 + * Types that differ between LLP64 and LP64 architectures - in LLP64, + * pointers are 64 bits, but 'long' is still 32 bits. Win64 appears + * to be the only LLP64 architecture in current use. + */ +#ifdef KHRONOS_USE_INTPTR_T +typedef intptr_t khronos_intptr_t; +typedef uintptr_t khronos_uintptr_t; +#elif defined(_WIN64) typedef signed long long int khronos_intptr_t; typedef unsigned long long int khronos_uintptr_t; -typedef signed long long int khronos_ssize_t; -typedef unsigned long long int khronos_usize_t; #else typedef signed long int khronos_intptr_t; typedef unsigned long int khronos_uintptr_t; +#endif + +#if defined(_WIN64) +typedef signed long long int khronos_ssize_t; +typedef unsigned long long int khronos_usize_t; +#else typedef signed long int khronos_ssize_t; typedef unsigned long int khronos_usize_t; #endif #if KHRONOS_SUPPORT_FLOAT /* -* Float type -*/ + * Float type + */ typedef float khronos_float_t; #endif #if KHRONOS_SUPPORT_INT64 /* Time types -* -* These types can be used to represent a time interval in nanoseconds or -* an absolute Unadjusted System Time. Unadjusted System Time is the number -* of nanoseconds since some arbitrary system event (e.g. since the last -* time the system booted). The Unadjusted System Time is an unsigned -* 64 bit value that wraps back to 0 every 584 years. Time intervals -* may be either signed or unsigned. -*/ + * + * These types can be used to represent a time interval in nanoseconds or + * an absolute Unadjusted System Time. Unadjusted System Time is the number + * of nanoseconds since some arbitrary system event (e.g. since the last + * time the system booted). The Unadjusted System Time is an unsigned + * 64 bit value that wraps back to 0 every 584 years. Time intervals + * may be either signed or unsigned. + */ typedef khronos_uint64_t khronos_utime_nanoseconds_t; typedef khronos_int64_t khronos_stime_nanoseconds_t; #endif /* -* Dummy value used to pad enum types to 32 bits. -*/ + * Dummy value used to pad enum types to 32 bits. + */ #ifndef KHRONOS_MAX_ENUM #define KHRONOS_MAX_ENUM 0x7FFFFFFF #endif /* -* Enumerated boolean type -* -* Values other than zero should be considered to be true. Therefore -* comparisons should not be made against KHRONOS_TRUE. -*/ + * Enumerated boolean type + * + * Values other than zero should be considered to be true. Therefore + * comparisons should not be made against KHRONOS_TRUE. + */ typedef enum { KHRONOS_FALSE = 0, - KHRONOS_TRUE = 1, + KHRONOS_TRUE = 1, KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM } khronos_boolean_enum_t; @@ -321,49 +354,30 @@ typedef enum { #define __eglplatform_h_ /* -** Copyright (c) 2007-2009 The Khronos Group Inc. -** -** Permission is hereby granted, free of charge, to any person obtaining a -** copy of this software and/or associated documentation files (the -** "Materials"), to deal in the Materials without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Materials, and to -** permit persons to whom the Materials are furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be included -** in all copies or substantial portions of the Materials. -** -** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +** Copyright 2007-2020 The Khronos Group Inc. +** SPDX-License-Identifier: Apache-2.0 */ /* Platform-specific types and definitions for egl.h -* $Revision: 12306 $ on $Date: 2010-08-25 09:51:28 -0700 (Wed, 25 Aug 2010) $ -* -* Adopters may modify khrplatform.h and this file to suit their platform. -* You are encouraged to submit all modifications to the Khronos group so that -* they can be included in future versions of this file. Please submit changes -* by sending them to the public Khronos Bugzilla (http://khronos.org/bugzilla) -* by filing a bug against product "EGL" component "Registry". -*/ + * + * Adopters may modify khrplatform.h and this file to suit their platform. + * You are encouraged to submit all modifications to the Khronos group so that + * they can be included in future versions of this file. Please submit changes + * by filing an issue or pull request on the public Khronos EGL Registry, at + * https://www.github.com/KhronosGroup/EGL-Registry/ + */ /*#include */ /* Macros used in EGL function prototype declarations. -* -* EGL functions should be prototyped as: -* -* EGLAPI return-type EGLAPIENTRY eglFunction(arguments); -* typedef return-type (EXPAPIENTRYP PFNEGLFUNCTIONPROC) (arguments); -* -* KHRONOS_APICALL and KHRONOS_APIENTRY are defined in KHR/khrplatform.h -*/ + * + * EGL functions should be prototyped as: + * + * EGLAPI return-type EGLAPIENTRY eglFunction(arguments); + * typedef return-type (EXPAPIENTRYP PFNEGLFUNCTIONPROC) (arguments); + * + * KHRONOS_APICALL and KHRONOS_APIENTRY are defined in KHR/khrplatform.h + */ #ifndef EGLAPI #define EGLAPI KHRONOS_APICALL @@ -375,42 +389,44 @@ typedef enum { #define EGLAPIENTRYP EGLAPIENTRY* /* The types NativeDisplayType, NativeWindowType, and NativePixmapType -* are aliases of window-system-dependent types, such as X Display * or -* Windows Device Context. They must be defined in platform-specific -* code below. The EGL-prefixed versions of Native*Type are the same -* types, renamed in EGL 1.3 so all types in the API start with "EGL". -* -* Khronos STRONGLY RECOMMENDS that you use the default definitions -* provided below, since these changes affect both binary and source -* portability of applications using EGL running on different EGL -* implementations. -*/ + * are aliases of window-system-dependent types, such as X Display * or + * Windows Device Context. They must be defined in platform-specific + * code below. The EGL-prefixed versions of Native*Type are the same + * types, renamed in EGL 1.3 so all types in the API start with "EGL". + * + * Khronos STRONGLY RECOMMENDS that you use the default definitions + * provided below, since these changes affect both binary and source + * portability of applications using EGL running on different EGL + * implementations. + */ -#if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */ +#if defined(EGL_NO_PLATFORM_SPECIFIC_TYPES) + +typedef void *EGLNativeDisplayType; +typedef void *EGLNativePixmapType; +typedef void *EGLNativeWindowType; + +#elif defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */ #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN 1 #endif -#ifndef NOMINMAX /* don't define min() and max(). */ -#define NOMINMAX -#endif #include -#if __WINRT__ -#include -typedef IUnknown * EGLNativeWindowType; -typedef IUnknown * EGLNativePixmapType; -typedef IUnknown * EGLNativeDisplayType; -#else typedef HDC EGLNativeDisplayType; typedef HBITMAP EGLNativePixmapType; typedef HWND EGLNativeWindowType; -#endif + +#elif defined(__EMSCRIPTEN__) + +typedef int EGLNativeDisplayType; +typedef int EGLNativePixmapType; +typedef int EGLNativeWindowType; #elif defined(__WINSCW__) || defined(__SYMBIAN32__) /* Symbian */ typedef int EGLNativeDisplayType; -typedef void *EGLNativeWindowType; typedef void *EGLNativePixmapType; +typedef void *EGLNativeWindowType; #elif defined(WL_EGL_PLATFORM) @@ -424,31 +440,22 @@ typedef struct gbm_device *EGLNativeDisplayType; typedef struct gbm_bo *EGLNativePixmapType; typedef void *EGLNativeWindowType; -#elif defined(__ANDROID__) /* Android */ +#elif defined(__ANDROID__) || defined(ANDROID) struct ANativeWindow; struct egl_native_pixmap_t; -typedef struct ANativeWindow *EGLNativeWindowType; -typedef struct egl_native_pixmap_t *EGLNativePixmapType; -typedef void *EGLNativeDisplayType; +typedef void* EGLNativeDisplayType; +typedef struct egl_native_pixmap_t* EGLNativePixmapType; +typedef struct ANativeWindow* EGLNativeWindowType; -#elif defined(MIR_EGL_PLATFORM) +#elif defined(USE_OZONE) -#include -typedef MirEGLNativeDisplayType EGLNativeDisplayType; -typedef void *EGLNativePixmapType; -typedef MirEGLNativeWindowType EGLNativeWindowType; +typedef intptr_t EGLNativeDisplayType; +typedef intptr_t EGLNativePixmapType; +typedef intptr_t EGLNativeWindowType; -#elif defined(__unix__) - -#ifdef MESA_EGL_NO_X11_HEADERS - -typedef void *EGLNativeDisplayType; -typedef khronos_uintptr_t EGLNativePixmapType; -typedef khronos_uintptr_t EGLNativeWindowType; - -#else +#elif defined(USE_X11) /* X11 (tentative) */ #include @@ -458,7 +465,31 @@ typedef Display *EGLNativeDisplayType; typedef Pixmap EGLNativePixmapType; typedef Window EGLNativeWindowType; -#endif /* MESA_EGL_NO_X11_HEADERS */ +#elif defined(__unix__) + +typedef void *EGLNativeDisplayType; +typedef khronos_uintptr_t EGLNativePixmapType; +typedef khronos_uintptr_t EGLNativeWindowType; + +#elif defined(__APPLE__) + +typedef int EGLNativeDisplayType; +typedef void *EGLNativePixmapType; +typedef void *EGLNativeWindowType; + +#elif defined(__HAIKU__) + +#include + +typedef void *EGLNativeDisplayType; +typedef khronos_uintptr_t EGLNativePixmapType; +typedef khronos_uintptr_t EGLNativeWindowType; + +#elif defined(__Fuchsia__) + +typedef void *EGLNativeDisplayType; +typedef khronos_uintptr_t EGLNativePixmapType; +typedef khronos_uintptr_t EGLNativeWindowType; #else #error "Platform not recognized" @@ -471,16 +502,25 @@ typedef EGLNativeWindowType NativeWindowType; /* Define EGLint. This must be a signed integral type large enough to contain -* all legal attribute names and values passed into and out of EGL, whether -* their type is boolean, bitmask, enumerant (symbolic constant), integer, -* handle, or other. While in general a 32-bit integer will suffice, if -* handles are 64 bit types, then EGLint should be defined as a signed 64-bit -* integer type. -*/ + * all legal attribute names and values passed into and out of EGL, whether + * their type is boolean, bitmask, enumerant (symbolic constant), integer, + * handle, or other. While in general a 32-bit integer will suffice, if + * handles are 64 bit types, then EGLint should be defined as a signed 64-bit + * integer type. + */ typedef khronos_int32_t EGLint; + +/* C++ / C typecast macros for special EGL handle values */ +#if defined(__cplusplus) +#define EGL_CAST(type, value) (static_cast(value)) +#else +#define EGL_CAST(type, value) ((type) (value)) +#endif + #endif /* __eglplatform_h */ + #ifndef __egl_h_ #define __egl_h_ 1 @@ -489,39 +529,24 @@ extern "C" { #endif /* -** Copyright (c) 2013-2015 The Khronos Group Inc. +** Copyright 2013-2020 The Khronos Group Inc. +** SPDX-License-Identifier: Apache-2.0 ** -** Permission is hereby granted, free of charge, to any person obtaining a -** copy of this software and/or associated documentation files (the -** "Materials"), to deal in the Materials without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Materials, and to -** permit persons to whom the Materials are furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be included -** in all copies or substantial portions of the Materials. -** -** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. -*/ -/* -** This header is generated from the Khronos OpenGL / OpenGL ES XML -** API Registry. The current version of the Registry, generator scripts +** This header is generated from the Khronos EGL XML API Registry. +** The current version of the Registry, generator scripts ** used to make the header, and the header can be found at -** http://www.opengl.org/registry/ +** http://www.khronos.org/registry/egl ** -** Khronos $Revision: 31566 $ on $Date: 2015-06-23 08:48:48 -0700 (Tue, 23 Jun 2015) $ +** Khronos $Git commit SHA1: 6fb1daea15 $ on $Git commit date: 2022-05-25 09:41:13 -0600 $ */ /*#include */ -/* Generated on date 20150623 */ +#ifndef EGL_EGL_PROTOTYPES +#define EGL_EGL_PROTOTYPES 1 +#endif + +/* Generated on date 20220525 */ /* Generated C header for: * API: egl @@ -536,6 +561,8 @@ extern "C" { #define EGL_VERSION_1_0 1 typedef unsigned int EGLBoolean; typedef void *EGLDisplay; +/*#include */ +/*#include */ typedef void *EGLConfig; typedef void *EGLSurface; typedef void *EGLContext; @@ -559,7 +586,7 @@ typedef void (*__eglMustCastToProperFunctionPointerType)(void); #define EGL_CONFIG_ID 0x3028 #define EGL_CORE_NATIVE_ENGINE 0x305B #define EGL_DEPTH_SIZE 0x3025 -#define EGL_DONT_CARE ((EGLint)-1) +#define EGL_DONT_CARE EGL_CAST(EGLint,-1) #define EGL_DRAW 0x3059 #define EGL_EXTENSIONS 0x3055 #define EGL_FALSE 0 @@ -576,9 +603,9 @@ typedef void (*__eglMustCastToProperFunctionPointerType)(void); #define EGL_NONE 0x3038 #define EGL_NON_CONFORMANT_CONFIG 0x3051 #define EGL_NOT_INITIALIZED 0x3001 -#define EGL_NO_CONTEXT ((EGLContext)0) -#define EGL_NO_DISPLAY ((EGLDisplay)0) -#define EGL_NO_SURFACE ((EGLSurface)0) +#define EGL_NO_CONTEXT EGL_CAST(EGLContext,0) +#define EGL_NO_DISPLAY EGL_CAST(EGLDisplay,0) +#define EGL_NO_SURFACE EGL_CAST(EGLSurface,0) #define EGL_PBUFFER_BIT 0x0001 #define EGL_PIXMAP_BIT 0x0002 #define EGL_READ 0x305A @@ -599,6 +626,31 @@ typedef void (*__eglMustCastToProperFunctionPointerType)(void); #define EGL_VERSION 0x3054 #define EGL_WIDTH 0x3057 #define EGL_WINDOW_BIT 0x0004 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCHOOSECONFIGPROC) (EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOPYBUFFERSPROC) (EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target); +typedef EGLContext (EGLAPIENTRYP PFNEGLCREATECONTEXTPROC) (EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list); +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPBUFFERSURFACEPROC) (EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list); +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPIXMAPSURFACEPROC) (EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list); +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEWINDOWSURFACEPROC) (EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYCONTEXTPROC) (EGLDisplay dpy, EGLContext ctx); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSURFACEPROC) (EGLDisplay dpy, EGLSurface surface); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETCONFIGATTRIBPROC) (EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETCONFIGSPROC) (EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config); +typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETCURRENTDISPLAYPROC) (void); +typedef EGLSurface (EGLAPIENTRYP PFNEGLGETCURRENTSURFACEPROC) (EGLint readdraw); +typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETDISPLAYPROC) (EGLNativeDisplayType display_id); +typedef EGLint (EGLAPIENTRYP PFNEGLGETERRORPROC) (void); +typedef __eglMustCastToProperFunctionPointerType (EGLAPIENTRYP PFNEGLGETPROCADDRESSPROC) (const char *procname); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLINITIALIZEPROC) (EGLDisplay dpy, EGLint *major, EGLint *minor); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLMAKECURRENTPROC) (EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYCONTEXTPROC) (EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value); +typedef const char *(EGLAPIENTRYP PFNEGLQUERYSTRINGPROC) (EGLDisplay dpy, EGLint name); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSPROC) (EGLDisplay dpy, EGLSurface surface); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLTERMINATEPROC) (EGLDisplay dpy); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLWAITGLPROC) (void); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLWAITNATIVEPROC) (EGLint engine); +#if EGL_EGL_PROTOTYPES EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig (EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config); EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers (EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target); EGLAPI EGLContext EGLAPIENTRY eglCreateContext (EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list); @@ -623,6 +675,7 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers (EGLDisplay dpy, EGLSurface surface EGLAPI EGLBoolean EGLAPIENTRY eglTerminate (EGLDisplay dpy); EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL (void); EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative (EGLint engine); +#endif #endif /* EGL_VERSION_1_0 */ #ifndef EGL_VERSION_1_1 @@ -641,10 +694,16 @@ EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative (EGLint engine); #define EGL_TEXTURE_RGB 0x305D #define EGL_TEXTURE_RGBA 0x305E #define EGL_TEXTURE_TARGET 0x3081 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLBINDTEXIMAGEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint buffer); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLRELEASETEXIMAGEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint buffer); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSURFACEATTRIBPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPINTERVALPROC) (EGLDisplay dpy, EGLint interval); +#if EGL_EGL_PROTOTYPES EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage (EGLDisplay dpy, EGLSurface surface, EGLint buffer); EGLAPI EGLBoolean EGLAPIENTRY eglReleaseTexImage (EGLDisplay dpy, EGLSurface surface, EGLint buffer); EGLAPI EGLBoolean EGLAPIENTRY eglSurfaceAttrib (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value); EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval (EGLDisplay dpy, EGLint interval); +#endif #endif /* EGL_VERSION_1_1 */ #ifndef EGL_VERSION_1_2 @@ -678,13 +737,20 @@ typedef void *EGLClientBuffer; #define EGL_RGB_BUFFER 0x308E #define EGL_SINGLE_BUFFER 0x3085 #define EGL_SWAP_BEHAVIOR 0x3093 -#define EGL_UNKNOWN ((EGLint)-1) +#define EGL_UNKNOWN EGL_CAST(EGLint,-1) #define EGL_VERTICAL_RESOLUTION 0x3091 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLBINDAPIPROC) (EGLenum api); +typedef EGLenum (EGLAPIENTRYP PFNEGLQUERYAPIPROC) (void); +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPBUFFERFROMCLIENTBUFFERPROC) (EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLRELEASETHREADPROC) (void); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLWAITCLIENTPROC) (void); +#if EGL_EGL_PROTOTYPES EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI (EGLenum api); EGLAPI EGLenum EGLAPIENTRY eglQueryAPI (void); EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer (EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list); EGLAPI EGLBoolean EGLAPIENTRY eglReleaseThread (void); EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient (void); +#endif #endif /* EGL_VERSION_1_2 */ #ifndef EGL_VERSION_1_3 @@ -705,7 +771,7 @@ EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient (void); #ifndef EGL_VERSION_1_4 #define EGL_VERSION_1_4 1 -#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)0) +#define EGL_DEFAULT_DISPLAY EGL_CAST(EGLNativeDisplayType,0) #define EGL_MULTISAMPLE_RESOLVE_BOX_BIT 0x0200 #define EGL_MULTISAMPLE_RESOLVE 0x3099 #define EGL_MULTISAMPLE_RESOLVE_DEFAULT 0x309A @@ -713,7 +779,10 @@ EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient (void); #define EGL_OPENGL_API 0x30A2 #define EGL_OPENGL_BIT 0x0008 #define EGL_SWAP_BEHAVIOR_PRESERVED_BIT 0x0400 +typedef EGLContext (EGLAPIENTRYP PFNEGLGETCURRENTCONTEXTPROC) (void); +#if EGL_EGL_PROTOTYPES EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext (void); +#endif #endif /* EGL_VERSION_1_4 */ #ifndef EGL_VERSION_1_5 @@ -747,7 +816,7 @@ typedef void *EGLImage; #define EGL_FOREVER 0xFFFFFFFFFFFFFFFFull #define EGL_TIMEOUT_EXPIRED 0x30F5 #define EGL_CONDITION_SATISFIED 0x30F6 -#define EGL_NO_SYNC ((EGLSync)0) +#define EGL_NO_SYNC EGL_CAST(EGLSync,0) #define EGL_SYNC_FENCE 0x30F9 #define EGL_GL_COLORSPACE 0x309D #define EGL_GL_COLORSPACE_SRGB 0x3089 @@ -764,7 +833,18 @@ typedef void *EGLImage; #define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x30B7 #define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x30B8 #define EGL_IMAGE_PRESERVED 0x30D2 -#define EGL_NO_IMAGE ((EGLImage)0) +#define EGL_NO_IMAGE EGL_CAST(EGLImage,0) +typedef EGLSync (EGLAPIENTRYP PFNEGLCREATESYNCPROC) (EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCPROC) (EGLDisplay dpy, EGLSync sync); +typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCPROC) (EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBPROC) (EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value); +typedef EGLImage (EGLAPIENTRYP PFNEGLCREATEIMAGEPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEPROC) (EGLDisplay dpy, EGLImage image); +typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYPROC) (EGLenum platform, void *native_display, const EGLAttrib *attrib_list); +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMWINDOWSURFACEPROC) (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list); +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC) (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLWAITSYNCPROC) (EGLDisplay dpy, EGLSync sync, EGLint flags); +#if EGL_EGL_PROTOTYPES EGLAPI EGLSync EGLAPIENTRY eglCreateSync (EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list); EGLAPI EGLBoolean EGLAPIENTRY eglDestroySync (EGLDisplay dpy, EGLSync sync); EGLAPI EGLint EGLAPIENTRY eglClientWaitSync (EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout); @@ -775,6 +855,7 @@ EGLAPI EGLDisplay EGLAPIENTRY eglGetPlatformDisplay (EGLenum platform, void *nat EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformWindowSurface (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list); EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurface (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list); EGLAPI EGLBoolean EGLAPIENTRY eglWaitSync (EGLDisplay dpy, EGLSync sync, EGLint flags); +#endif #endif /* EGL_VERSION_1_5 */ #ifdef __cplusplus @@ -784,7 +865,6 @@ EGLAPI EGLBoolean EGLAPIENTRY eglWaitSync (EGLDisplay dpy, EGLSync sync, EGLint #endif /* __egl_h_ */ - #ifndef __eglext_h_ #define __eglext_h_ 1 @@ -793,39 +873,20 @@ extern "C" { #endif /* -** Copyright (c) 2013-2015 The Khronos Group Inc. +** Copyright 2013-2020 The Khronos Group Inc. +** SPDX-License-Identifier: Apache-2.0 ** -** Permission is hereby granted, free of charge, to any person obtaining a -** copy of this software and/or associated documentation files (the -** "Materials"), to deal in the Materials without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Materials, and to -** permit persons to whom the Materials are furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be included -** in all copies or substantial portions of the Materials. -** -** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. -*/ -/* -** This header is generated from the Khronos OpenGL / OpenGL ES XML -** API Registry. The current version of the Registry, generator scripts +** This header is generated from the Khronos EGL XML API Registry. +** The current version of the Registry, generator scripts ** used to make the header, and the header can be found at -** http://www.opengl.org/registry/ +** http://www.khronos.org/registry/egl ** -** Khronos $Revision: 31566 $ on $Date: 2015-06-23 08:48:48 -0700 (Tue, 23 Jun 2015) $ +** Khronos $Git commit SHA1: 6fb1daea15 $ on $Git commit date: 2022-05-25 09:41:13 -0600 $ */ /*#include */ -#define EGL_EGLEXT_VERSION 20150623 +#define EGL_EGLEXT_VERSION 20220525 /* Generated C header for: * API: egl @@ -864,6 +925,13 @@ EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSync64KHR (EGLDisplay dpy, EGLenum type, #define EGL_VG_ALPHA_FORMAT_PRE_BIT_KHR 0x0040 #endif /* EGL_KHR_config_attribs */ +#ifndef EGL_KHR_context_flush_control +#define EGL_KHR_context_flush_control 1 +#define EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR 0 +#define EGL_CONTEXT_RELEASE_BEHAVIOR_KHR 0x2097 +#define EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR 0x2098 +#endif /* EGL_KHR_context_flush_control */ + #ifndef EGL_KHR_create_context #define EGL_KHR_create_context 1 #define EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098 @@ -886,6 +954,42 @@ EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSync64KHR (EGLDisplay dpy, EGLenum type, #define EGL_CONTEXT_OPENGL_NO_ERROR_KHR 0x31B3 #endif /* EGL_KHR_create_context_no_error */ +#ifndef EGL_KHR_debug +#define EGL_KHR_debug 1 +typedef void *EGLLabelKHR; +typedef void *EGLObjectKHR; +typedef void (EGLAPIENTRY *EGLDEBUGPROCKHR)(EGLenum error,const char *command,EGLint messageType,EGLLabelKHR threadLabel,EGLLabelKHR objectLabel,const char* message); +#define EGL_OBJECT_THREAD_KHR 0x33B0 +#define EGL_OBJECT_DISPLAY_KHR 0x33B1 +#define EGL_OBJECT_CONTEXT_KHR 0x33B2 +#define EGL_OBJECT_SURFACE_KHR 0x33B3 +#define EGL_OBJECT_IMAGE_KHR 0x33B4 +#define EGL_OBJECT_SYNC_KHR 0x33B5 +#define EGL_OBJECT_STREAM_KHR 0x33B6 +#define EGL_DEBUG_MSG_CRITICAL_KHR 0x33B9 +#define EGL_DEBUG_MSG_ERROR_KHR 0x33BA +#define EGL_DEBUG_MSG_WARN_KHR 0x33BB +#define EGL_DEBUG_MSG_INFO_KHR 0x33BC +#define EGL_DEBUG_CALLBACK_KHR 0x33B8 +typedef EGLint (EGLAPIENTRYP PFNEGLDEBUGMESSAGECONTROLKHRPROC) (EGLDEBUGPROCKHR callback, const EGLAttrib *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEBUGKHRPROC) (EGLint attribute, EGLAttrib *value); +typedef EGLint (EGLAPIENTRYP PFNEGLLABELOBJECTKHRPROC) (EGLDisplay display, EGLenum objectType, EGLObjectKHR object, EGLLabelKHR label); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLint EGLAPIENTRY eglDebugMessageControlKHR (EGLDEBUGPROCKHR callback, const EGLAttrib *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryDebugKHR (EGLint attribute, EGLAttrib *value); +EGLAPI EGLint EGLAPIENTRY eglLabelObjectKHR (EGLDisplay display, EGLenum objectType, EGLObjectKHR object, EGLLabelKHR label); +#endif +#endif /* EGL_KHR_debug */ + +#ifndef EGL_KHR_display_reference +#define EGL_KHR_display_reference 1 +#define EGL_TRACK_REFERENCES_KHR 0x3352 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDISPLAYATTRIBKHRPROC) (EGLDisplay dpy, EGLint name, EGLAttrib *value); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribKHR (EGLDisplay dpy, EGLint name, EGLAttrib *value); +#endif +#endif /* EGL_KHR_display_reference */ + #ifndef EGL_KHR_fence_sync #define EGL_KHR_fence_sync 1 typedef khronos_utime_nanoseconds_t EGLTimeKHR; @@ -948,7 +1052,7 @@ EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribKHR (EGLDisplay dpy, EGLSyncKHR sy #define EGL_KHR_image 1 typedef void *EGLImageKHR; #define EGL_NATIVE_PIXMAP_KHR 0x30B0 -#define EGL_NO_IMAGE_KHR ((EGLImageKHR)0) +#define EGL_NO_IMAGE_KHR EGL_CAST(EGLImageKHR,0) typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEIMAGEKHRPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list); typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay dpy, EGLImageKHR image); #ifdef EGL_EGLEXT_PROTOTYPES @@ -1010,6 +1114,16 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface64KHR (EGLDisplay dpy, EGLSurface s #endif #endif /* EGL_KHR_lock_surface3 */ +#ifndef EGL_KHR_mutable_render_buffer +#define EGL_KHR_mutable_render_buffer 1 +#define EGL_MUTABLE_RENDER_BUFFER_BIT_KHR 0x1000 +#endif /* EGL_KHR_mutable_render_buffer */ + +#ifndef EGL_KHR_no_config_context +#define EGL_KHR_no_config_context 1 +#define EGL_NO_CONFIG_KHR EGL_CAST(EGLConfig,0) +#endif /* EGL_KHR_no_config_context */ + #ifndef EGL_KHR_partial_update #define EGL_KHR_partial_update 1 #define EGL_BUFFER_AGE_KHR 0x313D @@ -1052,7 +1166,7 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSetDamageRegionKHR (EGLDisplay dpy, EGLSurface #define EGL_SYNC_REUSABLE_KHR 0x30FA #define EGL_SYNC_FLUSH_COMMANDS_BIT_KHR 0x0001 #define EGL_FOREVER_KHR 0xFFFFFFFFFFFFFFFFull -#define EGL_NO_SYNC_KHR ((EGLSyncKHR)0) +#define EGL_NO_SYNC_KHR EGL_CAST(EGLSyncKHR,0) typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode); #ifdef EGL_EGLEXT_PROTOTYPES EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode); @@ -1065,7 +1179,7 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, typedef void *EGLStreamKHR; typedef khronos_uint64_t EGLuint64KHR; #ifdef KHRONOS_SUPPORT_INT64 -#define EGL_NO_STREAM_KHR ((EGLStreamKHR)0) +#define EGL_NO_STREAM_KHR EGL_CAST(EGLStreamKHR,0) #define EGL_CONSUMER_LATENCY_USEC_KHR 0x3210 #define EGL_PRODUCER_FRAME_KHR 0x3212 #define EGL_CONSUMER_FRAME_KHR 0x3213 @@ -1093,6 +1207,24 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamu64KHR (EGLDisplay dpy, EGLStreamKHR #endif /* KHRONOS_SUPPORT_INT64 */ #endif /* EGL_KHR_stream */ +#ifndef EGL_KHR_stream_attrib +#define EGL_KHR_stream_attrib 1 +#ifdef KHRONOS_SUPPORT_INT64 +typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMATTRIBKHRPROC) (EGLDisplay dpy, const EGLAttrib *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSETSTREAMATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLAttrib value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLAttrib *value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERACQUIREATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERRELEASEATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLStreamKHR EGLAPIENTRY eglCreateStreamAttribKHR (EGLDisplay dpy, const EGLAttrib *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglSetStreamAttribKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLAttrib value); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamAttribKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLAttrib *value); +EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerAcquireAttribKHR (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerReleaseAttribKHR (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list); +#endif +#endif /* KHRONOS_SUPPORT_INT64 */ +#endif /* EGL_KHR_stream_attrib */ + #ifndef EGL_KHR_stream_consumer_gltexture #define EGL_KHR_stream_consumer_gltexture 1 #ifdef EGL_KHR_stream @@ -1112,7 +1244,7 @@ EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerReleaseKHR (EGLDisplay dpy, EGLSt #define EGL_KHR_stream_cross_process_fd 1 typedef int EGLNativeFileDescriptorKHR; #ifdef EGL_KHR_stream -#define EGL_NO_FILE_DESCRIPTOR_KHR ((EGLNativeFileDescriptorKHR)(-1)) +#define EGL_NO_FILE_DESCRIPTOR_KHR EGL_CAST(EGLNativeFileDescriptorKHR,-1) typedef EGLNativeFileDescriptorKHR (EGLAPIENTRYP PFNEGLGETSTREAMFILEDESCRIPTORKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream); typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC) (EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor); #ifdef EGL_EGLEXT_PROTOTYPES @@ -1159,9 +1291,9 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreateStreamProducerSurfaceKHR (EGLDisplay dpy, #ifndef EGL_KHR_swap_buffers_with_damage #define EGL_KHR_swap_buffers_with_damage 1 -typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC) (EGLDisplay dpy, EGLSurface surface, const EGLint *rects, EGLint n_rects); #ifdef EGL_EGLEXT_PROTOTYPES -EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageKHR (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects); +EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageKHR (EGLDisplay dpy, EGLSurface surface, const EGLint *rects, EGLint n_rects); #endif #endif /* EGL_KHR_swap_buffers_with_damage */ @@ -1178,6 +1310,10 @@ EGLAPI EGLint EGLAPIENTRY eglWaitSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLin #endif #endif /* EGL_KHR_wait_sync */ +#ifndef EGL_ANDROID_GLES_layers +#define EGL_ANDROID_GLES_layers 1 +#endif /* EGL_ANDROID_GLES_layers */ + #ifndef EGL_ANDROID_blob_cache #define EGL_ANDROID_blob_cache 1 typedef khronos_ssize_t EGLsizeiANDROID; @@ -1189,11 +1325,69 @@ EGLAPI void EGLAPIENTRY eglSetBlobCacheFuncsANDROID (EGLDisplay dpy, EGLSetBlobF #endif #endif /* EGL_ANDROID_blob_cache */ +#ifndef EGL_ANDROID_create_native_client_buffer +#define EGL_ANDROID_create_native_client_buffer 1 +#define EGL_NATIVE_BUFFER_USAGE_ANDROID 0x3143 +#define EGL_NATIVE_BUFFER_USAGE_PROTECTED_BIT_ANDROID 0x00000001 +#define EGL_NATIVE_BUFFER_USAGE_RENDERBUFFER_BIT_ANDROID 0x00000002 +#define EGL_NATIVE_BUFFER_USAGE_TEXTURE_BIT_ANDROID 0x00000004 +typedef EGLClientBuffer (EGLAPIENTRYP PFNEGLCREATENATIVECLIENTBUFFERANDROIDPROC) (const EGLint *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLClientBuffer EGLAPIENTRY eglCreateNativeClientBufferANDROID (const EGLint *attrib_list); +#endif +#endif /* EGL_ANDROID_create_native_client_buffer */ + #ifndef EGL_ANDROID_framebuffer_target #define EGL_ANDROID_framebuffer_target 1 #define EGL_FRAMEBUFFER_TARGET_ANDROID 0x3147 #endif /* EGL_ANDROID_framebuffer_target */ +#ifndef EGL_ANDROID_front_buffer_auto_refresh +#define EGL_ANDROID_front_buffer_auto_refresh 1 +#define EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID 0x314C +#endif /* EGL_ANDROID_front_buffer_auto_refresh */ + +#ifndef EGL_ANDROID_get_frame_timestamps +#define EGL_ANDROID_get_frame_timestamps 1 +typedef khronos_stime_nanoseconds_t EGLnsecsANDROID; +#define EGL_TIMESTAMP_PENDING_ANDROID EGL_CAST(EGLnsecsANDROID,-2) +#define EGL_TIMESTAMP_INVALID_ANDROID EGL_CAST(EGLnsecsANDROID,-1) +#define EGL_TIMESTAMPS_ANDROID 0x3430 +#define EGL_COMPOSITE_DEADLINE_ANDROID 0x3431 +#define EGL_COMPOSITE_INTERVAL_ANDROID 0x3432 +#define EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID 0x3433 +#define EGL_REQUESTED_PRESENT_TIME_ANDROID 0x3434 +#define EGL_RENDERING_COMPLETE_TIME_ANDROID 0x3435 +#define EGL_COMPOSITION_LATCH_TIME_ANDROID 0x3436 +#define EGL_FIRST_COMPOSITION_START_TIME_ANDROID 0x3437 +#define EGL_LAST_COMPOSITION_START_TIME_ANDROID 0x3438 +#define EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID 0x3439 +#define EGL_DISPLAY_PRESENT_TIME_ANDROID 0x343A +#define EGL_DEQUEUE_READY_TIME_ANDROID 0x343B +#define EGL_READS_DONE_TIME_ANDROID 0x343C +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETCOMPOSITORTIMINGSUPPORTEDANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLint name); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETCOMPOSITORTIMINGANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLint numTimestamps, const EGLint *names, EGLnsecsANDROID *values); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETNEXTFRAMEIDANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLuint64KHR *frameId); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETFRAMETIMESTAMPSUPPORTEDANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLint timestamp); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETFRAMETIMESTAMPSANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLuint64KHR frameId, EGLint numTimestamps, const EGLint *timestamps, EGLnsecsANDROID *values); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglGetCompositorTimingSupportedANDROID (EGLDisplay dpy, EGLSurface surface, EGLint name); +EGLAPI EGLBoolean EGLAPIENTRY eglGetCompositorTimingANDROID (EGLDisplay dpy, EGLSurface surface, EGLint numTimestamps, const EGLint *names, EGLnsecsANDROID *values); +EGLAPI EGLBoolean EGLAPIENTRY eglGetNextFrameIdANDROID (EGLDisplay dpy, EGLSurface surface, EGLuint64KHR *frameId); +EGLAPI EGLBoolean EGLAPIENTRY eglGetFrameTimestampSupportedANDROID (EGLDisplay dpy, EGLSurface surface, EGLint timestamp); +EGLAPI EGLBoolean EGLAPIENTRY eglGetFrameTimestampsANDROID (EGLDisplay dpy, EGLSurface surface, EGLuint64KHR frameId, EGLint numTimestamps, const EGLint *timestamps, EGLnsecsANDROID *values); +#endif +#endif /* EGL_ANDROID_get_frame_timestamps */ + +#ifndef EGL_ANDROID_get_native_client_buffer +#define EGL_ANDROID_get_native_client_buffer 1 +struct AHardwareBuffer; +typedef EGLClientBuffer (EGLAPIENTRYP PFNEGLGETNATIVECLIENTBUFFERANDROIDPROC) (const struct AHardwareBuffer *buffer); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLClientBuffer EGLAPIENTRY eglGetNativeClientBufferANDROID (const struct AHardwareBuffer *buffer); +#endif +#endif /* EGL_ANDROID_get_native_client_buffer */ + #ifndef EGL_ANDROID_image_native_buffer #define EGL_ANDROID_image_native_buffer 1 #define EGL_NATIVE_BUFFER_ANDROID 0x3140 @@ -1211,6 +1405,14 @@ EGLAPI EGLint EGLAPIENTRY eglDupNativeFenceFDANDROID (EGLDisplay dpy, EGLSyncKHR #endif #endif /* EGL_ANDROID_native_fence_sync */ +#ifndef EGL_ANDROID_presentation_time +#define EGL_ANDROID_presentation_time 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLPRESENTATIONTIMEANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLnsecsANDROID time); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglPresentationTimeANDROID (EGLDisplay dpy, EGLSurface surface, EGLnsecsANDROID time); +#endif +#endif /* EGL_ANDROID_presentation_time */ + #ifndef EGL_ANDROID_recordable #define EGL_ANDROID_recordable 1 #define EGL_RECORDABLE_ANDROID 0x3142 @@ -1239,16 +1441,40 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSu #define EGL_ANGLE_surface_d3d_texture_2d_share_handle 1 #endif /* EGL_ANGLE_surface_d3d_texture_2d_share_handle */ +#ifndef EGL_ANGLE_sync_control_rate +#define EGL_ANGLE_sync_control_rate 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETMSCRATEANGLEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *numerator, EGLint *denominator); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglGetMscRateANGLE (EGLDisplay dpy, EGLSurface surface, EGLint *numerator, EGLint *denominator); +#endif +#endif /* EGL_ANGLE_sync_control_rate */ + #ifndef EGL_ANGLE_window_fixed_size #define EGL_ANGLE_window_fixed_size 1 #define EGL_FIXED_SIZE_ANGLE 0x3201 #endif /* EGL_ANGLE_window_fixed_size */ +#ifndef EGL_ARM_image_format +#define EGL_ARM_image_format 1 +#define EGL_COLOR_COMPONENT_TYPE_UNSIGNED_INTEGER_ARM 0x3287 +#define EGL_COLOR_COMPONENT_TYPE_INTEGER_ARM 0x3288 +#endif /* EGL_ARM_image_format */ + +#ifndef EGL_ARM_implicit_external_sync +#define EGL_ARM_implicit_external_sync 1 +#define EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM 0x328A +#endif /* EGL_ARM_implicit_external_sync */ + #ifndef EGL_ARM_pixmap_multisample_discard #define EGL_ARM_pixmap_multisample_discard 1 #define EGL_DISCARD_SAMPLES_ARM 0x3286 #endif /* EGL_ARM_pixmap_multisample_discard */ +#ifndef EGL_EXT_bind_to_front +#define EGL_EXT_bind_to_front 1 +#define EGL_FRONT_BUFFER_EXT 0x3464 +#endif /* EGL_EXT_bind_to_front */ + #ifndef EGL_EXT_buffer_age #define EGL_EXT_buffer_age 1 #define EGL_BUFFER_AGE_EXT 0x313D @@ -1258,6 +1484,45 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSu #define EGL_EXT_client_extensions 1 #endif /* EGL_EXT_client_extensions */ +#ifndef EGL_EXT_client_sync +#define EGL_EXT_client_sync 1 +#define EGL_SYNC_CLIENT_EXT 0x3364 +#define EGL_SYNC_CLIENT_SIGNAL_EXT 0x3365 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCLIENTSIGNALSYNCEXTPROC) (EGLDisplay dpy, EGLSync sync, const EGLAttrib *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglClientSignalSyncEXT (EGLDisplay dpy, EGLSync sync, const EGLAttrib *attrib_list); +#endif +#endif /* EGL_EXT_client_sync */ + +#ifndef EGL_EXT_compositor +#define EGL_EXT_compositor 1 +#define EGL_PRIMARY_COMPOSITOR_CONTEXT_EXT 0x3460 +#define EGL_EXTERNAL_REF_ID_EXT 0x3461 +#define EGL_COMPOSITOR_DROP_NEWEST_FRAME_EXT 0x3462 +#define EGL_COMPOSITOR_KEEP_NEWEST_FRAME_EXT 0x3463 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORSETCONTEXTLISTEXTPROC) (const EGLint *external_ref_ids, EGLint num_entries); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORSETCONTEXTATTRIBUTESEXTPROC) (EGLint external_ref_id, const EGLint *context_attributes, EGLint num_entries); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORSETWINDOWLISTEXTPROC) (EGLint external_ref_id, const EGLint *external_win_ids, EGLint num_entries); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORSETWINDOWATTRIBUTESEXTPROC) (EGLint external_win_id, const EGLint *window_attributes, EGLint num_entries); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORBINDTEXWINDOWEXTPROC) (EGLint external_win_id); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORSETSIZEEXTPROC) (EGLint external_win_id, EGLint width, EGLint height); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOMPOSITORSWAPPOLICYEXTPROC) (EGLint external_win_id, EGLint policy); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSetContextListEXT (const EGLint *external_ref_ids, EGLint num_entries); +EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSetContextAttributesEXT (EGLint external_ref_id, const EGLint *context_attributes, EGLint num_entries); +EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSetWindowListEXT (EGLint external_ref_id, const EGLint *external_win_ids, EGLint num_entries); +EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSetWindowAttributesEXT (EGLint external_win_id, const EGLint *window_attributes, EGLint num_entries); +EGLAPI EGLBoolean EGLAPIENTRY eglCompositorBindTexWindowEXT (EGLint external_win_id); +EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSetSizeEXT (EGLint external_win_id, EGLint width, EGLint height); +EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSwapPolicyEXT (EGLint external_win_id, EGLint policy); +#endif +#endif /* EGL_EXT_compositor */ + +#ifndef EGL_EXT_config_select_group +#define EGL_EXT_config_select_group 1 +#define EGL_CONFIG_SELECT_GROUP_EXT 0x34C0 +#endif /* EGL_EXT_config_select_group */ + #ifndef EGL_EXT_create_context_robustness #define EGL_EXT_create_context_robustness 1 #define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT 0x30BF @@ -1269,7 +1534,7 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSu #ifndef EGL_EXT_device_base #define EGL_EXT_device_base 1 typedef void *EGLDeviceEXT; -#define EGL_NO_DEVICE_EXT ((EGLDeviceEXT)(0)) +#define EGL_NO_DEVICE_EXT EGL_CAST(EGLDeviceEXT,0) #define EGL_BAD_DEVICE_EXT 0x322B #define EGL_DEVICE_EXT 0x322C typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEVICEATTRIBEXTPROC) (EGLDeviceEXT device, EGLint attribute, EGLAttrib *value); @@ -1287,8 +1552,14 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribEXT (EGLDisplay dpy, EGLint a #ifndef EGL_EXT_device_drm #define EGL_EXT_device_drm 1 #define EGL_DRM_DEVICE_FILE_EXT 0x3233 +#define EGL_DRM_MASTER_FD_EXT 0x333C #endif /* EGL_EXT_device_drm */ +#ifndef EGL_EXT_device_drm_render_node +#define EGL_EXT_device_drm_render_node 1 +#define EGL_DRM_RENDER_NODE_FILE_EXT 0x3377 +#endif /* EGL_EXT_device_drm_render_node */ + #ifndef EGL_EXT_device_enumeration #define EGL_EXT_device_enumeration 1 #endif /* EGL_EXT_device_enumeration */ @@ -1296,12 +1567,68 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribEXT (EGLDisplay dpy, EGLint a #ifndef EGL_EXT_device_openwf #define EGL_EXT_device_openwf 1 #define EGL_OPENWF_DEVICE_ID_EXT 0x3237 +#define EGL_OPENWF_DEVICE_EXT 0x333D #endif /* EGL_EXT_device_openwf */ +#ifndef EGL_EXT_device_persistent_id +#define EGL_EXT_device_persistent_id 1 +#define EGL_DEVICE_UUID_EXT 0x335C +#define EGL_DRIVER_UUID_EXT 0x335D +#define EGL_DRIVER_NAME_EXT 0x335E +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEVICEBINARYEXTPROC) (EGLDeviceEXT device, EGLint name, EGLint max_size, void *value, EGLint *size); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQueryDeviceBinaryEXT (EGLDeviceEXT device, EGLint name, EGLint max_size, void *value, EGLint *size); +#endif +#endif /* EGL_EXT_device_persistent_id */ + #ifndef EGL_EXT_device_query #define EGL_EXT_device_query 1 #endif /* EGL_EXT_device_query */ +#ifndef EGL_EXT_device_query_name +#define EGL_EXT_device_query_name 1 +#define EGL_RENDERER_EXT 0x335F +#endif /* EGL_EXT_device_query_name */ + +#ifndef EGL_EXT_explicit_device +#define EGL_EXT_explicit_device 1 +#endif /* EGL_EXT_explicit_device */ + +#ifndef EGL_EXT_gl_colorspace_bt2020_linear +#define EGL_EXT_gl_colorspace_bt2020_linear 1 +#define EGL_GL_COLORSPACE_BT2020_LINEAR_EXT 0x333F +#endif /* EGL_EXT_gl_colorspace_bt2020_linear */ + +#ifndef EGL_EXT_gl_colorspace_bt2020_pq +#define EGL_EXT_gl_colorspace_bt2020_pq 1 +#define EGL_GL_COLORSPACE_BT2020_PQ_EXT 0x3340 +#endif /* EGL_EXT_gl_colorspace_bt2020_pq */ + +#ifndef EGL_EXT_gl_colorspace_display_p3 +#define EGL_EXT_gl_colorspace_display_p3 1 +#define EGL_GL_COLORSPACE_DISPLAY_P3_EXT 0x3363 +#endif /* EGL_EXT_gl_colorspace_display_p3 */ + +#ifndef EGL_EXT_gl_colorspace_display_p3_linear +#define EGL_EXT_gl_colorspace_display_p3_linear 1 +#define EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT 0x3362 +#endif /* EGL_EXT_gl_colorspace_display_p3_linear */ + +#ifndef EGL_EXT_gl_colorspace_display_p3_passthrough +#define EGL_EXT_gl_colorspace_display_p3_passthrough 1 +#define EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT 0x3490 +#endif /* EGL_EXT_gl_colorspace_display_p3_passthrough */ + +#ifndef EGL_EXT_gl_colorspace_scrgb +#define EGL_EXT_gl_colorspace_scrgb 1 +#define EGL_GL_COLORSPACE_SCRGB_EXT 0x3351 +#endif /* EGL_EXT_gl_colorspace_scrgb */ + +#ifndef EGL_EXT_gl_colorspace_scrgb_linear +#define EGL_EXT_gl_colorspace_scrgb_linear 1 +#define EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT 0x3350 +#endif /* EGL_EXT_gl_colorspace_scrgb_linear */ + #ifndef EGL_EXT_image_dma_buf_import #define EGL_EXT_image_dma_buf_import 1 #define EGL_LINUX_DMA_BUF_EXT 0x3270 @@ -1328,6 +1655,39 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribEXT (EGLDisplay dpy, EGLint a #define EGL_YUV_CHROMA_SITING_0_5_EXT 0x3285 #endif /* EGL_EXT_image_dma_buf_import */ +#ifndef EGL_EXT_image_dma_buf_import_modifiers +#define EGL_EXT_image_dma_buf_import_modifiers 1 +#define EGL_DMA_BUF_PLANE3_FD_EXT 0x3440 +#define EGL_DMA_BUF_PLANE3_OFFSET_EXT 0x3441 +#define EGL_DMA_BUF_PLANE3_PITCH_EXT 0x3442 +#define EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT 0x3443 +#define EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT 0x3444 +#define EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT 0x3445 +#define EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT 0x3446 +#define EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT 0x3447 +#define EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT 0x3448 +#define EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT 0x3449 +#define EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT 0x344A +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDMABUFFORMATSEXTPROC) (EGLDisplay dpy, EGLint max_formats, EGLint *formats, EGLint *num_formats); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDMABUFMODIFIERSEXTPROC) (EGLDisplay dpy, EGLint format, EGLint max_modifiers, EGLuint64KHR *modifiers, EGLBoolean *external_only, EGLint *num_modifiers); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQueryDmaBufFormatsEXT (EGLDisplay dpy, EGLint max_formats, EGLint *formats, EGLint *num_formats); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryDmaBufModifiersEXT (EGLDisplay dpy, EGLint format, EGLint max_modifiers, EGLuint64KHR *modifiers, EGLBoolean *external_only, EGLint *num_modifiers); +#endif +#endif /* EGL_EXT_image_dma_buf_import_modifiers */ + +#ifndef EGL_EXT_image_gl_colorspace +#define EGL_EXT_image_gl_colorspace 1 +#define EGL_GL_COLORSPACE_DEFAULT_EXT 0x314D +#endif /* EGL_EXT_image_gl_colorspace */ + +#ifndef EGL_EXT_image_implicit_sync_control +#define EGL_EXT_image_implicit_sync_control 1 +#define EGL_IMPORT_SYNC_TYPE_EXT 0x3470 +#define EGL_IMPORT_IMPLICIT_SYNC_EXT 0x3471 +#define EGL_IMPORT_EXPLICIT_SYNC_EXT 0x3472 +#endif /* EGL_EXT_image_implicit_sync_control */ + #ifndef EGL_EXT_multiview_window #define EGL_EXT_multiview_window 1 #define EGL_MULTIVIEW_VIEW_COUNT_EXT 0x3134 @@ -1337,8 +1697,8 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribEXT (EGLDisplay dpy, EGLint a #define EGL_EXT_output_base 1 typedef void *EGLOutputLayerEXT; typedef void *EGLOutputPortEXT; -#define EGL_NO_OUTPUT_LAYER_EXT ((EGLOutputLayerEXT)0) -#define EGL_NO_OUTPUT_PORT_EXT ((EGLOutputPortEXT)0) +#define EGL_NO_OUTPUT_LAYER_EXT EGL_CAST(EGLOutputLayerEXT,0) +#define EGL_NO_OUTPUT_PORT_EXT EGL_CAST(EGLOutputPortEXT,0) #define EGL_BAD_OUTPUT_LAYER_EXT 0x322D #define EGL_BAD_OUTPUT_PORT_EXT 0x322E #define EGL_SWAP_INTERVAL_EXT 0x322F @@ -1375,6 +1735,13 @@ EGLAPI const char *EGLAPIENTRY eglQueryOutputPortStringEXT (EGLDisplay dpy, EGLO #define EGL_OPENWF_PORT_ID_EXT 0x3239 #endif /* EGL_EXT_output_openwf */ +#ifndef EGL_EXT_pixel_format_float +#define EGL_EXT_pixel_format_float 1 +#define EGL_COLOR_COMPONENT_TYPE_EXT 0x3339 +#define EGL_COLOR_COMPONENT_TYPE_FIXED_EXT 0x333A +#define EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT 0x333B +#endif /* EGL_EXT_pixel_format_float */ + #ifndef EGL_EXT_platform_base #define EGL_EXT_platform_base 1 typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYEXTPROC) (EGLenum platform, void *native_display, const EGLint *attrib_list); @@ -1403,9 +1770,24 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurfaceEXT (EGLDisplay dpy, #define EGL_PLATFORM_X11_SCREEN_EXT 0x31D6 #endif /* EGL_EXT_platform_x11 */ +#ifndef EGL_EXT_platform_xcb +#define EGL_EXT_platform_xcb 1 +#define EGL_PLATFORM_XCB_EXT 0x31DC +#define EGL_PLATFORM_XCB_SCREEN_EXT 0x31DE +#endif /* EGL_EXT_platform_xcb */ + +#ifndef EGL_EXT_present_opaque +#define EGL_EXT_present_opaque 1 +#define EGL_PRESENT_OPAQUE_EXT 0x31DF +#endif /* EGL_EXT_present_opaque */ + +#ifndef EGL_EXT_protected_content +#define EGL_EXT_protected_content 1 +#define EGL_PROTECTED_CONTENT_EXT 0x32C0 +#endif /* EGL_EXT_protected_content */ + #ifndef EGL_EXT_protected_surface #define EGL_EXT_protected_surface 1 -#define EGL_PROTECTED_CONTENT_EXT 0x32C0 #endif /* EGL_EXT_protected_surface */ #ifndef EGL_EXT_stream_consumer_egloutput @@ -1416,14 +1798,68 @@ EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerOutputEXT (EGLDisplay dpy, EGLStr #endif #endif /* EGL_EXT_stream_consumer_egloutput */ +#ifndef EGL_EXT_surface_CTA861_3_metadata +#define EGL_EXT_surface_CTA861_3_metadata 1 +#define EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT 0x3360 +#define EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT 0x3361 +#endif /* EGL_EXT_surface_CTA861_3_metadata */ + +#ifndef EGL_EXT_surface_SMPTE2086_metadata +#define EGL_EXT_surface_SMPTE2086_metadata 1 +#define EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT 0x3341 +#define EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT 0x3342 +#define EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT 0x3343 +#define EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT 0x3344 +#define EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT 0x3345 +#define EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT 0x3346 +#define EGL_SMPTE2086_WHITE_POINT_X_EXT 0x3347 +#define EGL_SMPTE2086_WHITE_POINT_Y_EXT 0x3348 +#define EGL_SMPTE2086_MAX_LUMINANCE_EXT 0x3349 +#define EGL_SMPTE2086_MIN_LUMINANCE_EXT 0x334A +#define EGL_METADATA_SCALING_EXT 50000 +#endif /* EGL_EXT_surface_SMPTE2086_metadata */ + +#ifndef EGL_EXT_surface_compression +#define EGL_EXT_surface_compression 1 +#define EGL_SURFACE_COMPRESSION_EXT 0x34B0 +#define EGL_SURFACE_COMPRESSION_PLANE1_EXT 0x328E +#define EGL_SURFACE_COMPRESSION_PLANE2_EXT 0x328F +#define EGL_SURFACE_COMPRESSION_FIXED_RATE_NONE_EXT 0x34B1 +#define EGL_SURFACE_COMPRESSION_FIXED_RATE_DEFAULT_EXT 0x34B2 +#define EGL_SURFACE_COMPRESSION_FIXED_RATE_1BPC_EXT 0x34B4 +#define EGL_SURFACE_COMPRESSION_FIXED_RATE_2BPC_EXT 0x34B5 +#define EGL_SURFACE_COMPRESSION_FIXED_RATE_3BPC_EXT 0x34B6 +#define EGL_SURFACE_COMPRESSION_FIXED_RATE_4BPC_EXT 0x34B7 +#define EGL_SURFACE_COMPRESSION_FIXED_RATE_5BPC_EXT 0x34B8 +#define EGL_SURFACE_COMPRESSION_FIXED_RATE_6BPC_EXT 0x34B9 +#define EGL_SURFACE_COMPRESSION_FIXED_RATE_7BPC_EXT 0x34BA +#define EGL_SURFACE_COMPRESSION_FIXED_RATE_8BPC_EXT 0x34BB +#define EGL_SURFACE_COMPRESSION_FIXED_RATE_9BPC_EXT 0x34BC +#define EGL_SURFACE_COMPRESSION_FIXED_RATE_10BPC_EXT 0x34BD +#define EGL_SURFACE_COMPRESSION_FIXED_RATE_11BPC_EXT 0x34BE +#define EGL_SURFACE_COMPRESSION_FIXED_RATE_12BPC_EXT 0x34BF +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSUPPORTEDCOMPRESSIONRATESEXTPROC) (EGLDisplay dpy, EGLConfig config, const EGLAttrib *attrib_list, EGLint *rates, EGLint rate_size, EGLint *num_rates); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQuerySupportedCompressionRatesEXT (EGLDisplay dpy, EGLConfig config, const EGLAttrib *attrib_list, EGLint *rates, EGLint rate_size, EGLint *num_rates); +#endif +#endif /* EGL_EXT_surface_compression */ + #ifndef EGL_EXT_swap_buffers_with_damage #define EGL_EXT_swap_buffers_with_damage 1 -typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC) (EGLDisplay dpy, EGLSurface surface, const EGLint *rects, EGLint n_rects); #ifdef EGL_EGLEXT_PROTOTYPES -EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageEXT (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects); +EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageEXT (EGLDisplay dpy, EGLSurface surface, const EGLint *rects, EGLint n_rects); #endif #endif /* EGL_EXT_swap_buffers_with_damage */ +#ifndef EGL_EXT_sync_reuse +#define EGL_EXT_sync_reuse 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNSIGNALSYNCEXTPROC) (EGLDisplay dpy, EGLSync sync, const EGLAttrib *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglUnsignalSyncEXT (EGLDisplay dpy, EGLSync sync, const EGLAttrib *attrib_list); +#endif +#endif /* EGL_EXT_sync_reuse */ + #ifndef EGL_EXT_yuv_surface #define EGL_EXT_yuv_surface 1 #define EGL_YUV_ORDER_EXT 0x3301 @@ -1484,6 +1920,12 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurfaceHI (EGLDisplay dpy, EGLConfi #define EGL_CONTEXT_PRIORITY_LOW_IMG 0x3103 #endif /* EGL_IMG_context_priority */ +#ifndef EGL_IMG_image_plane_attribs +#define EGL_IMG_image_plane_attribs 1 +#define EGL_NATIVE_BUFFER_MULTIPLANE_SEPARATE_IMG 0x3105 +#define EGL_NATIVE_BUFFER_PLANE_OFFSET_IMG 0x3106 +#endif /* EGL_IMG_image_plane_attribs */ + #ifndef EGL_MESA_drm_image #define EGL_MESA_drm_image 1 #define EGL_DRM_BUFFER_FORMAT_MESA 0x31D0 @@ -1493,6 +1935,7 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurfaceHI (EGLDisplay dpy, EGLConfi #define EGL_DRM_BUFFER_STRIDE_MESA 0x31D4 #define EGL_DRM_BUFFER_USE_SCANOUT_MESA 0x00000001 #define EGL_DRM_BUFFER_USE_SHARE_MESA 0x00000002 +#define EGL_DRM_BUFFER_USE_CURSOR_MESA 0x00000004 typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEDRMIMAGEMESAPROC) (EGLDisplay dpy, const EGLint *attrib_list); typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDRMIMAGEMESAPROC) (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride); #ifdef EGL_EGLEXT_PROTOTYPES @@ -1516,6 +1959,21 @@ EGLAPI EGLBoolean EGLAPIENTRY eglExportDMABUFImageMESA (EGLDisplay dpy, EGLImage #define EGL_PLATFORM_GBM_MESA 0x31D7 #endif /* EGL_MESA_platform_gbm */ +#ifndef EGL_MESA_platform_surfaceless +#define EGL_MESA_platform_surfaceless 1 +#define EGL_PLATFORM_SURFACELESS_MESA 0x31DD +#endif /* EGL_MESA_platform_surfaceless */ + +#ifndef EGL_MESA_query_driver +#define EGL_MESA_query_driver 1 +typedef char *(EGLAPIENTRYP PFNEGLGETDISPLAYDRIVERCONFIGPROC) (EGLDisplay dpy); +typedef const char *(EGLAPIENTRYP PFNEGLGETDISPLAYDRIVERNAMEPROC) (EGLDisplay dpy); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI char *EGLAPIENTRY eglGetDisplayDriverConfig (EGLDisplay dpy); +EGLAPI const char *EGLAPIENTRY eglGetDisplayDriverName (EGLDisplay dpy); +#endif +#endif /* EGL_MESA_query_driver */ + #ifndef EGL_NOK_swap_region #define EGL_NOK_swap_region 1 typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGIONNOKPROC) (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects); @@ -1542,6 +2000,11 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersRegion2NOK (EGLDisplay dpy, EGLSurfa #define EGL_AUTO_STEREO_NV 0x3136 #endif /* EGL_NV_3dvision_surface */ +#ifndef EGL_NV_context_priority_realtime +#define EGL_NV_context_priority_realtime 1 +#define EGL_CONTEXT_PRIORITY_REALTIME_NV 0x3357 +#endif /* EGL_NV_context_priority_realtime */ + #ifndef EGL_NV_coverage_sample #define EGL_NV_coverage_sample 1 #define EGL_COVERAGE_BUFFERS_NV 0x30E0 @@ -1599,6 +2062,181 @@ EGLAPI EGLBoolean EGLAPIENTRY eglPostSubBufferNV (EGLDisplay dpy, EGLSurface sur #endif #endif /* EGL_NV_post_sub_buffer */ +#ifndef EGL_NV_quadruple_buffer +#define EGL_NV_quadruple_buffer 1 +#define EGL_QUADRUPLE_BUFFER_NV 0x3231 +#endif /* EGL_NV_quadruple_buffer */ + +#ifndef EGL_NV_robustness_video_memory_purge +#define EGL_NV_robustness_video_memory_purge 1 +#define EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV 0x334C +#endif /* EGL_NV_robustness_video_memory_purge */ + +#ifndef EGL_NV_stream_consumer_eglimage +#define EGL_NV_stream_consumer_eglimage 1 +#define EGL_STREAM_CONSUMER_IMAGE_NV 0x3373 +#define EGL_STREAM_IMAGE_ADD_NV 0x3374 +#define EGL_STREAM_IMAGE_REMOVE_NV 0x3375 +#define EGL_STREAM_IMAGE_AVAILABLE_NV 0x3376 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMIMAGECONSUMERCONNECTNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLint num_modifiers, const EGLuint64KHR *modifiers, const EGLAttrib *attrib_list); +typedef EGLint (EGLAPIENTRYP PFNEGLQUERYSTREAMCONSUMEREVENTNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLTime timeout, EGLenum *event, EGLAttrib *aux); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMACQUIREIMAGENVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLImage *pImage, EGLSync sync); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMRELEASEIMAGENVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLImage image, EGLSync sync); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglStreamImageConsumerConnectNV (EGLDisplay dpy, EGLStreamKHR stream, EGLint num_modifiers, const EGLuint64KHR *modifiers, const EGLAttrib *attrib_list); +EGLAPI EGLint EGLAPIENTRY eglQueryStreamConsumerEventNV (EGLDisplay dpy, EGLStreamKHR stream, EGLTime timeout, EGLenum *event, EGLAttrib *aux); +EGLAPI EGLBoolean EGLAPIENTRY eglStreamAcquireImageNV (EGLDisplay dpy, EGLStreamKHR stream, EGLImage *pImage, EGLSync sync); +EGLAPI EGLBoolean EGLAPIENTRY eglStreamReleaseImageNV (EGLDisplay dpy, EGLStreamKHR stream, EGLImage image, EGLSync sync); +#endif +#endif /* EGL_NV_stream_consumer_eglimage */ + +#ifndef EGL_NV_stream_consumer_gltexture_yuv +#define EGL_NV_stream_consumer_gltexture_yuv 1 +#define EGL_YUV_PLANE0_TEXTURE_UNIT_NV 0x332C +#define EGL_YUV_PLANE1_TEXTURE_UNIT_NV 0x332D +#define EGL_YUV_PLANE2_TEXTURE_UNIT_NV 0x332E +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALATTRIBSNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalAttribsNV (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list); +#endif +#endif /* EGL_NV_stream_consumer_gltexture_yuv */ + +#ifndef EGL_NV_stream_cross_display +#define EGL_NV_stream_cross_display 1 +#define EGL_STREAM_CROSS_DISPLAY_NV 0x334E +#endif /* EGL_NV_stream_cross_display */ + +#ifndef EGL_NV_stream_cross_object +#define EGL_NV_stream_cross_object 1 +#define EGL_STREAM_CROSS_OBJECT_NV 0x334D +#endif /* EGL_NV_stream_cross_object */ + +#ifndef EGL_NV_stream_cross_partition +#define EGL_NV_stream_cross_partition 1 +#define EGL_STREAM_CROSS_PARTITION_NV 0x323F +#endif /* EGL_NV_stream_cross_partition */ + +#ifndef EGL_NV_stream_cross_process +#define EGL_NV_stream_cross_process 1 +#define EGL_STREAM_CROSS_PROCESS_NV 0x3245 +#endif /* EGL_NV_stream_cross_process */ + +#ifndef EGL_NV_stream_cross_system +#define EGL_NV_stream_cross_system 1 +#define EGL_STREAM_CROSS_SYSTEM_NV 0x334F +#endif /* EGL_NV_stream_cross_system */ + +#ifndef EGL_NV_stream_dma +#define EGL_NV_stream_dma 1 +#define EGL_STREAM_DMA_NV 0x3371 +#define EGL_STREAM_DMA_SERVER_NV 0x3372 +#endif /* EGL_NV_stream_dma */ + +#ifndef EGL_NV_stream_fifo_next +#define EGL_NV_stream_fifo_next 1 +#define EGL_PENDING_FRAME_NV 0x3329 +#define EGL_STREAM_TIME_PENDING_NV 0x332A +#endif /* EGL_NV_stream_fifo_next */ + +#ifndef EGL_NV_stream_fifo_synchronous +#define EGL_NV_stream_fifo_synchronous 1 +#define EGL_STREAM_FIFO_SYNCHRONOUS_NV 0x3336 +#endif /* EGL_NV_stream_fifo_synchronous */ + +#ifndef EGL_NV_stream_flush +#define EGL_NV_stream_flush 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMFLUSHNVPROC) (EGLDisplay dpy, EGLStreamKHR stream); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglStreamFlushNV (EGLDisplay dpy, EGLStreamKHR stream); +#endif +#endif /* EGL_NV_stream_flush */ + +#ifndef EGL_NV_stream_frame_limits +#define EGL_NV_stream_frame_limits 1 +#define EGL_PRODUCER_MAX_FRAME_HINT_NV 0x3337 +#define EGL_CONSUMER_MAX_FRAME_HINT_NV 0x3338 +#endif /* EGL_NV_stream_frame_limits */ + +#ifndef EGL_NV_stream_metadata +#define EGL_NV_stream_metadata 1 +#define EGL_MAX_STREAM_METADATA_BLOCKS_NV 0x3250 +#define EGL_MAX_STREAM_METADATA_BLOCK_SIZE_NV 0x3251 +#define EGL_MAX_STREAM_METADATA_TOTAL_SIZE_NV 0x3252 +#define EGL_PRODUCER_METADATA_NV 0x3253 +#define EGL_CONSUMER_METADATA_NV 0x3254 +#define EGL_PENDING_METADATA_NV 0x3328 +#define EGL_METADATA0_SIZE_NV 0x3255 +#define EGL_METADATA1_SIZE_NV 0x3256 +#define EGL_METADATA2_SIZE_NV 0x3257 +#define EGL_METADATA3_SIZE_NV 0x3258 +#define EGL_METADATA0_TYPE_NV 0x3259 +#define EGL_METADATA1_TYPE_NV 0x325A +#define EGL_METADATA2_TYPE_NV 0x325B +#define EGL_METADATA3_TYPE_NV 0x325C +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDISPLAYATTRIBNVPROC) (EGLDisplay dpy, EGLint attribute, EGLAttrib *value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSETSTREAMMETADATANVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLint n, EGLint offset, EGLint size, const void *data); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMMETADATANVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum name, EGLint n, EGLint offset, EGLint size, void *data); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribNV (EGLDisplay dpy, EGLint attribute, EGLAttrib *value); +EGLAPI EGLBoolean EGLAPIENTRY eglSetStreamMetadataNV (EGLDisplay dpy, EGLStreamKHR stream, EGLint n, EGLint offset, EGLint size, const void *data); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamMetadataNV (EGLDisplay dpy, EGLStreamKHR stream, EGLenum name, EGLint n, EGLint offset, EGLint size, void *data); +#endif +#endif /* EGL_NV_stream_metadata */ + +#ifndef EGL_NV_stream_origin +#define EGL_NV_stream_origin 1 +#define EGL_STREAM_FRAME_ORIGIN_X_NV 0x3366 +#define EGL_STREAM_FRAME_ORIGIN_Y_NV 0x3367 +#define EGL_STREAM_FRAME_MAJOR_AXIS_NV 0x3368 +#define EGL_CONSUMER_AUTO_ORIENTATION_NV 0x3369 +#define EGL_PRODUCER_AUTO_ORIENTATION_NV 0x336A +#define EGL_LEFT_NV 0x336B +#define EGL_RIGHT_NV 0x336C +#define EGL_TOP_NV 0x336D +#define EGL_BOTTOM_NV 0x336E +#define EGL_X_AXIS_NV 0x336F +#define EGL_Y_AXIS_NV 0x3370 +#endif /* EGL_NV_stream_origin */ + +#ifndef EGL_NV_stream_remote +#define EGL_NV_stream_remote 1 +#define EGL_STREAM_STATE_INITIALIZING_NV 0x3240 +#define EGL_STREAM_TYPE_NV 0x3241 +#define EGL_STREAM_PROTOCOL_NV 0x3242 +#define EGL_STREAM_ENDPOINT_NV 0x3243 +#define EGL_STREAM_LOCAL_NV 0x3244 +#define EGL_STREAM_PRODUCER_NV 0x3247 +#define EGL_STREAM_CONSUMER_NV 0x3248 +#define EGL_STREAM_PROTOCOL_FD_NV 0x3246 +#endif /* EGL_NV_stream_remote */ + +#ifndef EGL_NV_stream_reset +#define EGL_NV_stream_reset 1 +#define EGL_SUPPORT_RESET_NV 0x3334 +#define EGL_SUPPORT_REUSE_NV 0x3335 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLRESETSTREAMNVPROC) (EGLDisplay dpy, EGLStreamKHR stream); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglResetStreamNV (EGLDisplay dpy, EGLStreamKHR stream); +#endif +#endif /* EGL_NV_stream_reset */ + +#ifndef EGL_NV_stream_socket +#define EGL_NV_stream_socket 1 +#define EGL_STREAM_PROTOCOL_SOCKET_NV 0x324B +#define EGL_SOCKET_HANDLE_NV 0x324C +#define EGL_SOCKET_TYPE_NV 0x324D +#endif /* EGL_NV_stream_socket */ + +#ifndef EGL_NV_stream_socket_inet +#define EGL_NV_stream_socket_inet 1 +#define EGL_SOCKET_TYPE_INET_NV 0x324F +#endif /* EGL_NV_stream_socket_inet */ + +#ifndef EGL_NV_stream_socket_unix +#define EGL_NV_stream_socket_unix 1 +#define EGL_SOCKET_TYPE_UNIX_NV 0x324E +#endif /* EGL_NV_stream_socket_unix */ + #ifndef EGL_NV_stream_sync #define EGL_NV_stream_sync 1 #define EGL_SYNC_NEW_FRAME_NV 0x321F @@ -1625,7 +2263,7 @@ typedef khronos_utime_nanoseconds_t EGLTimeNV; #define EGL_SYNC_TYPE_NV 0x30ED #define EGL_SYNC_CONDITION_NV 0x30EE #define EGL_SYNC_FENCE_NV 0x30EF -#define EGL_NO_SYNC_NV ((EGLSyncNV)0) +#define EGL_NO_SYNC_NV EGL_CAST(EGLSyncNV,0) typedef EGLSyncNV (EGLAPIENTRYP PFNEGLCREATEFENCESYNCNVPROC) (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list); typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCNVPROC) (EGLSyncNV sync); typedef EGLBoolean (EGLAPIENTRYP PFNEGLFENCENVPROC) (EGLSyncNV sync); @@ -1656,6 +2294,11 @@ EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeNV (void); #endif /* KHRONOS_SUPPORT_INT64 */ #endif /* EGL_NV_system_time */ +#ifndef EGL_NV_triple_buffer +#define EGL_NV_triple_buffer 1 +#define EGL_TRIPLE_BUFFER_NV 0x3230 +#endif /* EGL_NV_triple_buffer */ + #ifndef EGL_TIZEN_image_native_buffer #define EGL_TIZEN_image_native_buffer 1 #define EGL_NATIVE_BUFFER_TIZEN 0x32A0 @@ -1666,11 +2309,44 @@ EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeNV (void); #define EGL_NATIVE_SURFACE_TIZEN 0x32A1 #endif /* EGL_TIZEN_image_native_surface */ +#ifndef EGL_WL_bind_wayland_display +#define EGL_WL_bind_wayland_display 1 +#define PFNEGLBINDWAYLANDDISPLAYWL PFNEGLBINDWAYLANDDISPLAYWLPROC +#define PFNEGLUNBINDWAYLANDDISPLAYWL PFNEGLUNBINDWAYLANDDISPLAYWLPROC +#define PFNEGLQUERYWAYLANDBUFFERWL PFNEGLQUERYWAYLANDBUFFERWLPROC +struct wl_display; +struct wl_resource; +#define EGL_WAYLAND_BUFFER_WL 0x31D5 +#define EGL_WAYLAND_PLANE_WL 0x31D6 +#define EGL_TEXTURE_Y_U_V_WL 0x31D7 +#define EGL_TEXTURE_Y_UV_WL 0x31D8 +#define EGL_TEXTURE_Y_XUXV_WL 0x31D9 +#define EGL_TEXTURE_EXTERNAL_WL 0x31DA +#define EGL_WAYLAND_Y_INVERTED_WL 0x31DB +typedef EGLBoolean (EGLAPIENTRYP PFNEGLBINDWAYLANDDISPLAYWLPROC) (EGLDisplay dpy, struct wl_display *display); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNBINDWAYLANDDISPLAYWLPROC) (EGLDisplay dpy, struct wl_display *display); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYWAYLANDBUFFERWLPROC) (EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglBindWaylandDisplayWL (EGLDisplay dpy, struct wl_display *display); +EGLAPI EGLBoolean EGLAPIENTRY eglUnbindWaylandDisplayWL (EGLDisplay dpy, struct wl_display *display); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryWaylandBufferWL (EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value); +#endif +#endif /* EGL_WL_bind_wayland_display */ + +#ifndef EGL_WL_create_wayland_buffer_from_image +#define EGL_WL_create_wayland_buffer_from_image 1 +#define PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWL PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWLPROC +struct wl_buffer; +typedef struct wl_buffer *(EGLAPIENTRYP PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWLPROC) (EGLDisplay dpy, EGLImageKHR image); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI struct wl_buffer *EGLAPIENTRY eglCreateWaylandBufferFromImageWL (EGLDisplay dpy, EGLImageKHR image); +#endif +#endif /* EGL_WL_create_wayland_buffer_from_image */ + #ifdef __cplusplus } #endif #endif /* __eglext_h_ */ - #endif /* _MSC_VER */ diff --git a/SDL2-2.30.5/include/SDL_endian.h b/SDL2-2.30.5/include/SDL_endian.h new file mode 100644 index 0000000..591ccac --- /dev/null +++ b/SDL2-2.30.5/include/SDL_endian.h @@ -0,0 +1,348 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_endian.h + * + * Functions for reading and writing endian-specific values + */ + +#ifndef SDL_endian_h_ +#define SDL_endian_h_ + +#include "SDL_stdinc.h" + +#if defined(_MSC_VER) && (_MSC_VER >= 1400) +/* As of Clang 11, '_m_prefetchw' is conflicting with the winnt.h's version, + so we define the needed '_m_prefetch' here as a pseudo-header, until the issue is fixed. */ +#ifdef __clang__ +#ifndef __PRFCHWINTRIN_H +#define __PRFCHWINTRIN_H +static __inline__ void __attribute__((__always_inline__, __nodebug__)) +_m_prefetch(void *__P) +{ + __builtin_prefetch(__P, 0, 3 /* _MM_HINT_T0 */); +} +#endif /* __PRFCHWINTRIN_H */ +#endif /* __clang__ */ + +#include +#endif + +/** + * \name The two types of endianness + */ +/* @{ */ +#define SDL_LIL_ENDIAN 1234 +#define SDL_BIG_ENDIAN 4321 +/* @} */ + +#ifndef SDL_BYTEORDER /* Not defined in SDL_config.h? */ +#ifdef __linux__ +#include +#define SDL_BYTEORDER __BYTE_ORDER +#elif defined(__OpenBSD__) || defined(__DragonFly__) +#include +#define SDL_BYTEORDER BYTE_ORDER +#elif defined(__FreeBSD__) || defined(__NetBSD__) +#include +#define SDL_BYTEORDER BYTE_ORDER +/* predefs from newer gcc and clang versions: */ +#elif defined(__ORDER_LITTLE_ENDIAN__) && defined(__ORDER_BIG_ENDIAN__) && defined(__BYTE_ORDER__) +#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) +#define SDL_BYTEORDER SDL_LIL_ENDIAN +#elif (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) +#define SDL_BYTEORDER SDL_BIG_ENDIAN +#else +#error Unsupported endianness +#endif /**/ +#else +#if defined(__hppa__) || \ + defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || \ + (defined(__MIPS__) && defined(__MIPSEB__)) || \ + defined(__ppc__) || defined(__POWERPC__) || defined(__powerpc__) || defined(__PPC__) || \ + defined(__sparc__) +#define SDL_BYTEORDER SDL_BIG_ENDIAN +#else +#define SDL_BYTEORDER SDL_LIL_ENDIAN +#endif +#endif /* __linux__ */ +#endif /* !SDL_BYTEORDER */ + +#ifndef SDL_FLOATWORDORDER /* Not defined in SDL_config.h? */ +/* predefs from newer gcc versions: */ +#if defined(__ORDER_LITTLE_ENDIAN__) && defined(__ORDER_BIG_ENDIAN__) && defined(__FLOAT_WORD_ORDER__) +#if (__FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__) +#define SDL_FLOATWORDORDER SDL_LIL_ENDIAN +#elif (__FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__) +#define SDL_FLOATWORDORDER SDL_BIG_ENDIAN +#else +#error Unsupported endianness +#endif /**/ +#elif defined(__MAVERICK__) +/* For Maverick, float words are always little-endian. */ +#define SDL_FLOATWORDORDER SDL_LIL_ENDIAN +#elif (defined(__arm__) || defined(__thumb__)) && !defined(__VFP_FP__) && !defined(__ARM_EABI__) +/* For FPA, float words are always big-endian. */ +#define SDL_FLOATWORDORDER SDL_BIG_ENDIAN +#else +/* By default, assume that floats words follow the memory system mode. */ +#define SDL_FLOATWORDORDER SDL_BYTEORDER +#endif /* __FLOAT_WORD_ORDER__ */ +#endif /* !SDL_FLOATWORDORDER */ + + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \file SDL_endian.h + */ + +/* various modern compilers may have builtin swap */ +#if defined(__GNUC__) || defined(__clang__) +# define HAS_BUILTIN_BSWAP16 (_SDL_HAS_BUILTIN(__builtin_bswap16)) || \ + (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)) +# define HAS_BUILTIN_BSWAP32 (_SDL_HAS_BUILTIN(__builtin_bswap32)) || \ + (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) +# define HAS_BUILTIN_BSWAP64 (_SDL_HAS_BUILTIN(__builtin_bswap64)) || \ + (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) + + /* this one is broken */ +# define HAS_BROKEN_BSWAP (__GNUC__ == 2 && __GNUC_MINOR__ <= 95) +#else +# define HAS_BUILTIN_BSWAP16 0 +# define HAS_BUILTIN_BSWAP32 0 +# define HAS_BUILTIN_BSWAP64 0 +# define HAS_BROKEN_BSWAP 0 +#endif + +#if HAS_BUILTIN_BSWAP16 +#define SDL_Swap16(x) __builtin_bswap16(x) +#elif (defined(_MSC_VER) && (_MSC_VER >= 1400)) && !defined(__ICL) +#pragma intrinsic(_byteswap_ushort) +#define SDL_Swap16(x) _byteswap_ushort(x) +#elif defined(__i386__) && !HAS_BROKEN_BSWAP +SDL_FORCE_INLINE Uint16 +SDL_Swap16(Uint16 x) +{ + __asm__("xchgb %b0,%h0": "=q"(x):"0"(x)); + return x; +} +#elif defined(__x86_64__) +SDL_FORCE_INLINE Uint16 +SDL_Swap16(Uint16 x) +{ + __asm__("xchgb %b0,%h0": "=Q"(x):"0"(x)); + return x; +} +#elif (defined(__powerpc__) || defined(__ppc__)) +SDL_FORCE_INLINE Uint16 +SDL_Swap16(Uint16 x) +{ + int result; + + __asm__("rlwimi %0,%2,8,16,23": "=&r"(result):"0"(x >> 8), "r"(x)); + return (Uint16)result; +} +#elif (defined(__m68k__) && !defined(__mcoldfire__)) +SDL_FORCE_INLINE Uint16 +SDL_Swap16(Uint16 x) +{ + __asm__("rorw #8,%0": "=d"(x): "0"(x):"cc"); + return x; +} +#elif defined(__WATCOMC__) && defined(__386__) +extern __inline Uint16 SDL_Swap16(Uint16); +#pragma aux SDL_Swap16 = \ + "xchg al, ah" \ + parm [ax] \ + modify [ax]; +#else +SDL_FORCE_INLINE Uint16 +SDL_Swap16(Uint16 x) +{ + return SDL_static_cast(Uint16, ((x << 8) | (x >> 8))); +} +#endif + +#if HAS_BUILTIN_BSWAP32 +#define SDL_Swap32(x) __builtin_bswap32(x) +#elif (defined(_MSC_VER) && (_MSC_VER >= 1400)) && !defined(__ICL) +#pragma intrinsic(_byteswap_ulong) +#define SDL_Swap32(x) _byteswap_ulong(x) +#elif defined(__i386__) && !HAS_BROKEN_BSWAP +SDL_FORCE_INLINE Uint32 +SDL_Swap32(Uint32 x) +{ + __asm__("bswap %0": "=r"(x):"0"(x)); + return x; +} +#elif defined(__x86_64__) +SDL_FORCE_INLINE Uint32 +SDL_Swap32(Uint32 x) +{ + __asm__("bswapl %0": "=r"(x):"0"(x)); + return x; +} +#elif (defined(__powerpc__) || defined(__ppc__)) +SDL_FORCE_INLINE Uint32 +SDL_Swap32(Uint32 x) +{ + Uint32 result; + + __asm__("rlwimi %0,%2,24,16,23": "=&r"(result): "0" (x>>24), "r"(x)); + __asm__("rlwimi %0,%2,8,8,15" : "=&r"(result): "0" (result), "r"(x)); + __asm__("rlwimi %0,%2,24,0,7" : "=&r"(result): "0" (result), "r"(x)); + return result; +} +#elif (defined(__m68k__) && !defined(__mcoldfire__)) +SDL_FORCE_INLINE Uint32 +SDL_Swap32(Uint32 x) +{ + __asm__("rorw #8,%0\n\tswap %0\n\trorw #8,%0": "=d"(x): "0"(x):"cc"); + return x; +} +#elif defined(__WATCOMC__) && defined(__386__) +extern __inline Uint32 SDL_Swap32(Uint32); +#pragma aux SDL_Swap32 = \ + "bswap eax" \ + parm [eax] \ + modify [eax]; +#else +SDL_FORCE_INLINE Uint32 +SDL_Swap32(Uint32 x) +{ + return SDL_static_cast(Uint32, ((x << 24) | ((x << 8) & 0x00FF0000) | + ((x >> 8) & 0x0000FF00) | (x >> 24))); +} +#endif + +#if HAS_BUILTIN_BSWAP64 +#define SDL_Swap64(x) __builtin_bswap64(x) +#elif (defined(_MSC_VER) && (_MSC_VER >= 1400)) && !defined(__ICL) +#pragma intrinsic(_byteswap_uint64) +#define SDL_Swap64(x) _byteswap_uint64(x) +#elif defined(__i386__) && !HAS_BROKEN_BSWAP +SDL_FORCE_INLINE Uint64 +SDL_Swap64(Uint64 x) +{ + union { + struct { + Uint32 a, b; + } s; + Uint64 u; + } v; + v.u = x; + __asm__("bswapl %0 ; bswapl %1 ; xchgl %0,%1" + : "=r"(v.s.a), "=r"(v.s.b) + : "0" (v.s.a), "1"(v.s.b)); + return v.u; +} +#elif defined(__x86_64__) +SDL_FORCE_INLINE Uint64 +SDL_Swap64(Uint64 x) +{ + __asm__("bswapq %0": "=r"(x):"0"(x)); + return x; +} +#elif defined(__WATCOMC__) && defined(__386__) +extern __inline Uint64 SDL_Swap64(Uint64); +#pragma aux SDL_Swap64 = \ + "bswap eax" \ + "bswap edx" \ + "xchg eax,edx" \ + parm [eax edx] \ + modify [eax edx]; +#else +SDL_FORCE_INLINE Uint64 +SDL_Swap64(Uint64 x) +{ + Uint32 hi, lo; + + /* Separate into high and low 32-bit values and swap them */ + lo = SDL_static_cast(Uint32, x & 0xFFFFFFFF); + x >>= 32; + hi = SDL_static_cast(Uint32, x & 0xFFFFFFFF); + x = SDL_Swap32(lo); + x <<= 32; + x |= SDL_Swap32(hi); + return (x); +} +#endif + + +SDL_FORCE_INLINE float +SDL_SwapFloat(float x) +{ + union { + float f; + Uint32 ui32; + } swapper; + swapper.f = x; + swapper.ui32 = SDL_Swap32(swapper.ui32); + return swapper.f; +} + +/* remove extra macros */ +#undef HAS_BROKEN_BSWAP +#undef HAS_BUILTIN_BSWAP16 +#undef HAS_BUILTIN_BSWAP32 +#undef HAS_BUILTIN_BSWAP64 + +/** + * \name Swap to native + * Byteswap item from the specified endianness to the native endianness. + */ +/* @{ */ +#if SDL_BYTEORDER == SDL_LIL_ENDIAN +#define SDL_SwapLE16(X) (X) +#define SDL_SwapLE32(X) (X) +#define SDL_SwapLE64(X) (X) +#define SDL_SwapFloatLE(X) (X) +#define SDL_SwapBE16(X) SDL_Swap16(X) +#define SDL_SwapBE32(X) SDL_Swap32(X) +#define SDL_SwapBE64(X) SDL_Swap64(X) +#define SDL_SwapFloatBE(X) SDL_SwapFloat(X) +#else +#define SDL_SwapLE16(X) SDL_Swap16(X) +#define SDL_SwapLE32(X) SDL_Swap32(X) +#define SDL_SwapLE64(X) SDL_Swap64(X) +#define SDL_SwapFloatLE(X) SDL_SwapFloat(X) +#define SDL_SwapBE16(X) (X) +#define SDL_SwapBE32(X) (X) +#define SDL_SwapBE64(X) (X) +#define SDL_SwapFloatBE(X) (X) +#endif +/* @} *//* Swap to native */ + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_endian_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/include/SDL_error.h b/SDL2-2.30.5/include/SDL_error.h new file mode 100644 index 0000000..2df6463 --- /dev/null +++ b/SDL2-2.30.5/include/SDL_error.h @@ -0,0 +1,163 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_error.h + * + * Simple error message routines for SDL. + */ + +#ifndef SDL_error_h_ +#define SDL_error_h_ + +#include "SDL_stdinc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Public functions */ + + +/** + * Set the SDL error message for the current thread. + * + * Calling this function will replace any previous error message that was set. + * + * This function always returns -1, since SDL frequently uses -1 to signify an + * failing result, leading to this idiom: + * + * ```c + * if (error_code) { + * return SDL_SetError("This operation has failed: %d", error_code); + * } + * ``` + * + * \param fmt a printf()-style message format string + * \param ... additional parameters matching % tokens in the `fmt` string, if + * any + * \returns always -1. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ClearError + * \sa SDL_GetError + */ +extern DECLSPEC int SDLCALL SDL_SetError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(1); + +/** + * Retrieve a message about the last error that occurred on the current + * thread. + * + * It is possible for multiple errors to occur before calling SDL_GetError(). + * Only the last error is returned. + * + * The message is only applicable when an SDL function has signaled an error. + * You must check the return values of SDL function calls to determine when to + * appropriately call SDL_GetError(). You should *not* use the results of + * SDL_GetError() to decide if an error has occurred! Sometimes SDL will set + * an error string even when reporting success. + * + * SDL will *not* clear the error string for successful API calls. You *must* + * check return values for failure cases before you can assume the error + * string applies. + * + * Error strings are set per-thread, so an error set in a different thread + * will not interfere with the current thread's operation. + * + * The returned string is internally allocated and must not be freed by the + * application. + * + * \returns a message with information about the specific error that occurred, + * or an empty string if there hasn't been an error message set since + * the last call to SDL_ClearError(). The message is only applicable + * when an SDL function has signaled an error. You must check the + * return values of SDL function calls to determine when to + * appropriately call SDL_GetError(). + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ClearError + * \sa SDL_SetError + */ +extern DECLSPEC const char *SDLCALL SDL_GetError(void); + +/** + * Get the last error message that was set for the current thread. + * + * This allows the caller to copy the error string into a provided buffer, but + * otherwise operates exactly the same as SDL_GetError(). + * + * \param errstr A buffer to fill with the last error message that was set for + * the current thread + * \param maxlen The size of the buffer pointed to by the errstr parameter + * \returns the pointer passed in as the `errstr` parameter. + * + * \since This function is available since SDL 2.0.14. + * + * \sa SDL_GetError + */ +extern DECLSPEC char * SDLCALL SDL_GetErrorMsg(char *errstr, int maxlen); + +/** + * Clear any previous error message for this thread. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetError + * \sa SDL_SetError + */ +extern DECLSPEC void SDLCALL SDL_ClearError(void); + +/** + * \name Internal error functions + * + * \internal + * Private error reporting function - used internally. + */ +/* @{ */ +#define SDL_OutOfMemory() SDL_Error(SDL_ENOMEM) +#define SDL_Unsupported() SDL_Error(SDL_UNSUPPORTED) +#define SDL_InvalidParamError(param) SDL_SetError("Parameter '%s' is invalid", (param)) +typedef enum +{ + SDL_ENOMEM, + SDL_EFREAD, + SDL_EFWRITE, + SDL_EFSEEK, + SDL_UNSUPPORTED, + SDL_LASTERROR +} SDL_errorcode; +/* SDL_Error() unconditionally returns -1. */ +extern DECLSPEC int SDLCALL SDL_Error(SDL_errorcode code); +/* @} *//* Internal error functions */ + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_error_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/include/SDL_events.h b/SDL2-2.30.5/include/SDL_events.h similarity index 51% rename from SDL2-2.0.12/include/SDL_events.h rename to SDL2-2.30.5/include/SDL_events.h index 32cfbe3..eccbba2 100644 --- a/SDL2-2.0.12/include/SDL_events.h +++ b/SDL2-2.30.5/include/SDL_events.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -50,7 +50,7 @@ extern "C" { #define SDL_PRESSED 1 /** - * \brief The types of events that can be delivered. + * The types of events that can be delivered. */ typedef enum { @@ -85,6 +85,8 @@ typedef enum Called on Android in onResume() */ + SDL_LOCALECHANGED, /**< The user's locale preferences have changed. */ + /* Display events */ SDL_DISPLAYEVENT = 0x150, /**< Display state change */ @@ -100,6 +102,7 @@ typedef enum SDL_KEYMAPCHANGED, /**< Keymap changed due to a system event such as an input language or keyboard layout change. */ + SDL_TEXTEDITING_EXT, /**< Extended keyboard text editing (composition) */ /* Mouse events */ SDL_MOUSEMOTION = 0x400, /**< Mouse moved */ @@ -115,6 +118,7 @@ typedef enum SDL_JOYBUTTONUP, /**< Joystick button released */ SDL_JOYDEVICEADDED, /**< A new joystick has been inserted into the system */ SDL_JOYDEVICEREMOVED, /**< An opened joystick has been removed */ + SDL_JOYBATTERYUPDATED, /**< Joystick battery level change */ /* Game controller events */ SDL_CONTROLLERAXISMOTION = 0x650, /**< Game controller axis motion */ @@ -123,6 +127,12 @@ typedef enum SDL_CONTROLLERDEVICEADDED, /**< A new Game controller has been inserted into the system */ SDL_CONTROLLERDEVICEREMOVED, /**< An opened Game controller has been removed */ SDL_CONTROLLERDEVICEREMAPPED, /**< The controller mapping was updated */ + SDL_CONTROLLERTOUCHPADDOWN, /**< Game controller touchpad was touched */ + SDL_CONTROLLERTOUCHPADMOTION, /**< Game controller touchpad finger was moved */ + SDL_CONTROLLERTOUCHPADUP, /**< Game controller touchpad finger was lifted */ + SDL_CONTROLLERSENSORUPDATE, /**< Game controller sensor was updated */ + SDL_CONTROLLERUPDATECOMPLETE_RESERVED_FOR_SDL3, + SDL_CONTROLLERSTEAMHANDLEUPDATED, /**< Game controller Steam handle has changed */ /* Touch events */ SDL_FINGERDOWN = 0x700, @@ -135,7 +145,7 @@ typedef enum SDL_MULTIGESTURE, /* Clipboard events */ - SDL_CLIPBOARDUPDATE = 0x900, /**< The clipboard changed */ + SDL_CLIPBOARDUPDATE = 0x900, /**< The clipboard or primary selection changed */ /* Drag and drop events */ SDL_DROPFILE = 0x1000, /**< The system requests a file open */ @@ -154,6 +164,9 @@ typedef enum SDL_RENDER_TARGETS_RESET = 0x2000, /**< The render targets have been reset and their contents need to be updated */ SDL_RENDER_DEVICE_RESET, /**< The device has been reset and all textures need to be recreated */ + /* Internal events */ + SDL_POLLSENTINEL = 0x7F00, /**< Signals the end of an event poll cycle */ + /** Events ::SDL_USEREVENT through ::SDL_LASTEVENT are for your use, * and should be allocated with SDL_RegisterEvents() */ @@ -234,6 +247,19 @@ typedef struct SDL_TextEditingEvent Sint32 length; /**< The length of selected editing text */ } SDL_TextEditingEvent; +/** + * \brief Extended keyboard text editing event structure (event.editExt.*) when text would be + * truncated if stored in the text buffer SDL_TextEditingEvent + */ +typedef struct SDL_TextEditingExtEvent +{ + Uint32 type; /**< ::SDL_TEXTEDITING_EXT */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + Uint32 windowID; /**< The window with keyboard focus, if any */ + char* text; /**< The editing text, which should be freed with SDL_free(), and will not be NULL */ + Sint32 start; /**< The start cursor of selected editing text */ + Sint32 length; /**< The length of selected editing text */ +} SDL_TextEditingExtEvent; #define SDL_TEXTINPUTEVENT_TEXT_SIZE (32) /** @@ -292,6 +318,10 @@ typedef struct SDL_MouseWheelEvent Sint32 x; /**< The amount scrolled horizontally, positive to the right and negative to the left */ Sint32 y; /**< The amount scrolled vertically, positive away from the user and negative toward the user */ Uint32 direction; /**< Set to one of the SDL_MOUSEWHEEL_* defines. When FLIPPED the values in X and Y will be opposite. Multiply by -1 to change them back */ + float preciseX; /**< The amount scrolled horizontally, positive to the right and negative to the left, with float precision (added in 2.0.18) */ + float preciseY; /**< The amount scrolled vertically, positive away from the user and negative toward the user, with float precision (added in 2.0.18) */ + Sint32 mouseX; /**< X coordinate, relative to window (added in 2.26.0) */ + Sint32 mouseY; /**< Y coordinate, relative to window (added in 2.26.0) */ } SDL_MouseWheelEvent; /** @@ -370,6 +400,16 @@ typedef struct SDL_JoyDeviceEvent Sint32 which; /**< The joystick device index for the ADDED event, instance id for the REMOVED event */ } SDL_JoyDeviceEvent; +/** + * \brief Joysick battery level change event structure (event.jbattery.*) + */ +typedef struct SDL_JoyBatteryEvent +{ + Uint32 type; /**< ::SDL_JOYBATTERYUPDATED */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_JoystickID which; /**< The joystick instance id */ + SDL_JoystickPowerLevel level; /**< The joystick battery level */ +} SDL_JoyBatteryEvent; /** * \brief Game controller axis motion event structure (event.caxis.*) @@ -408,11 +448,39 @@ typedef struct SDL_ControllerButtonEvent */ typedef struct SDL_ControllerDeviceEvent { - Uint32 type; /**< ::SDL_CONTROLLERDEVICEADDED, ::SDL_CONTROLLERDEVICEREMOVED, or ::SDL_CONTROLLERDEVICEREMAPPED */ + Uint32 type; /**< ::SDL_CONTROLLERDEVICEADDED, ::SDL_CONTROLLERDEVICEREMOVED, ::SDL_CONTROLLERDEVICEREMAPPED, or ::SDL_CONTROLLERSTEAMHANDLEUPDATED */ Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ Sint32 which; /**< The joystick device index for the ADDED event, instance id for the REMOVED or REMAPPED event */ } SDL_ControllerDeviceEvent; +/** + * \brief Game controller touchpad event structure (event.ctouchpad.*) + */ +typedef struct SDL_ControllerTouchpadEvent +{ + Uint32 type; /**< ::SDL_CONTROLLERTOUCHPADDOWN or ::SDL_CONTROLLERTOUCHPADMOTION or ::SDL_CONTROLLERTOUCHPADUP */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_JoystickID which; /**< The joystick instance id */ + Sint32 touchpad; /**< The index of the touchpad */ + Sint32 finger; /**< The index of the finger on the touchpad */ + float x; /**< Normalized in the range 0...1 with 0 being on the left */ + float y; /**< Normalized in the range 0...1 with 0 being at the top */ + float pressure; /**< Normalized in the range 0...1 */ +} SDL_ControllerTouchpadEvent; + +/** + * \brief Game controller sensor event structure (event.csensor.*) + */ +typedef struct SDL_ControllerSensorEvent +{ + Uint32 type; /**< ::SDL_CONTROLLERSENSORUPDATE */ + Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ + SDL_JoystickID which; /**< The joystick instance id */ + Sint32 sensor; /**< The type of the sensor, one of the values of ::SDL_SensorType */ + float data[3]; /**< Up to 3 values from the sensor, as defined in SDL_sensor.h */ + Uint64 timestamp_us; /**< The timestamp of the sensor reading in microseconds, if the hardware provides this information. */ +} SDL_ControllerSensorEvent; + /** * \brief Audio device event structure (event.adevice.*) */ @@ -502,6 +570,7 @@ typedef struct SDL_SensorEvent Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ Sint32 which; /**< The instance ID of the sensor */ float data[6]; /**< Up to 6 values from the sensor - additional values can be queried using SDL_SensorGetData() */ + Uint64 timestamp_us; /**< The timestamp of the sensor reading in microseconds, if the hardware provides this information. */ } SDL_SensorEvent; /** @@ -513,15 +582,6 @@ typedef struct SDL_QuitEvent Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ } SDL_QuitEvent; -/** - * \brief OS Specific event - */ -typedef struct SDL_OSEvent -{ - Uint32 type; /**< ::SDL_QUIT */ - Uint32 timestamp; /**< In milliseconds, populated using SDL_GetTicks() */ -} SDL_OSEvent; - /** * \brief A user-defined event type (event.user.*) */ @@ -557,56 +617,81 @@ typedef struct SDL_SysWMEvent */ typedef union SDL_Event { - Uint32 type; /**< Event type, shared with all events */ - SDL_CommonEvent common; /**< Common event data */ - SDL_DisplayEvent display; /**< Display event data */ - SDL_WindowEvent window; /**< Window event data */ - SDL_KeyboardEvent key; /**< Keyboard event data */ - SDL_TextEditingEvent edit; /**< Text editing event data */ - SDL_TextInputEvent text; /**< Text input event data */ - SDL_MouseMotionEvent motion; /**< Mouse motion event data */ - SDL_MouseButtonEvent button; /**< Mouse button event data */ - SDL_MouseWheelEvent wheel; /**< Mouse wheel event data */ - SDL_JoyAxisEvent jaxis; /**< Joystick axis event data */ - SDL_JoyBallEvent jball; /**< Joystick ball event data */ - SDL_JoyHatEvent jhat; /**< Joystick hat event data */ - SDL_JoyButtonEvent jbutton; /**< Joystick button event data */ - SDL_JoyDeviceEvent jdevice; /**< Joystick device change event data */ - SDL_ControllerAxisEvent caxis; /**< Game Controller axis event data */ - SDL_ControllerButtonEvent cbutton; /**< Game Controller button event data */ - SDL_ControllerDeviceEvent cdevice; /**< Game Controller device event data */ - SDL_AudioDeviceEvent adevice; /**< Audio device event data */ - SDL_SensorEvent sensor; /**< Sensor event data */ - SDL_QuitEvent quit; /**< Quit request event data */ - SDL_UserEvent user; /**< Custom event data */ - SDL_SysWMEvent syswm; /**< System dependent window event data */ - SDL_TouchFingerEvent tfinger; /**< Touch finger event data */ - SDL_MultiGestureEvent mgesture; /**< Gesture event data */ - SDL_DollarGestureEvent dgesture; /**< Gesture event data */ - SDL_DropEvent drop; /**< Drag and drop event data */ + Uint32 type; /**< Event type, shared with all events */ + SDL_CommonEvent common; /**< Common event data */ + SDL_DisplayEvent display; /**< Display event data */ + SDL_WindowEvent window; /**< Window event data */ + SDL_KeyboardEvent key; /**< Keyboard event data */ + SDL_TextEditingEvent edit; /**< Text editing event data */ + SDL_TextEditingExtEvent editExt; /**< Extended text editing event data */ + SDL_TextInputEvent text; /**< Text input event data */ + SDL_MouseMotionEvent motion; /**< Mouse motion event data */ + SDL_MouseButtonEvent button; /**< Mouse button event data */ + SDL_MouseWheelEvent wheel; /**< Mouse wheel event data */ + SDL_JoyAxisEvent jaxis; /**< Joystick axis event data */ + SDL_JoyBallEvent jball; /**< Joystick ball event data */ + SDL_JoyHatEvent jhat; /**< Joystick hat event data */ + SDL_JoyButtonEvent jbutton; /**< Joystick button event data */ + SDL_JoyDeviceEvent jdevice; /**< Joystick device change event data */ + SDL_JoyBatteryEvent jbattery; /**< Joystick battery event data */ + SDL_ControllerAxisEvent caxis; /**< Game Controller axis event data */ + SDL_ControllerButtonEvent cbutton; /**< Game Controller button event data */ + SDL_ControllerDeviceEvent cdevice; /**< Game Controller device event data */ + SDL_ControllerTouchpadEvent ctouchpad; /**< Game Controller touchpad event data */ + SDL_ControllerSensorEvent csensor; /**< Game Controller sensor event data */ + SDL_AudioDeviceEvent adevice; /**< Audio device event data */ + SDL_SensorEvent sensor; /**< Sensor event data */ + SDL_QuitEvent quit; /**< Quit request event data */ + SDL_UserEvent user; /**< Custom event data */ + SDL_SysWMEvent syswm; /**< System dependent window event data */ + SDL_TouchFingerEvent tfinger; /**< Touch finger event data */ + SDL_MultiGestureEvent mgesture; /**< Gesture event data */ + SDL_DollarGestureEvent dgesture; /**< Gesture event data */ + SDL_DropEvent drop; /**< Drag and drop event data */ - /* This is necessary for ABI compatibility between Visual C++ and GCC - Visual C++ will respect the push pack pragma and use 52 bytes for - this structure, and GCC will use the alignment of the largest datatype - within the union, which is 8 bytes. + /* This is necessary for ABI compatibility between Visual C++ and GCC. + Visual C++ will respect the push pack pragma and use 52 bytes (size of + SDL_TextEditingEvent, the largest structure for 32-bit and 64-bit + architectures) for this union, and GCC will use the alignment of the + largest datatype within the union, which is 8 bytes on 64-bit + architectures. So... we'll add padding to force the size to be 56 bytes for both. + + On architectures where pointers are 16 bytes, this needs rounding up to + the next multiple of 16, 64, and on architectures where pointers are + even larger the size of SDL_UserEvent will dominate as being 3 pointers. */ - Uint8 padding[56]; + Uint8 padding[sizeof(void *) <= 8 ? 56 : sizeof(void *) == 16 ? 64 : 3 * sizeof(void *)]; } SDL_Event; /* Make sure we haven't broken binary compatibility */ -SDL_COMPILE_TIME_ASSERT(SDL_Event, sizeof(SDL_Event) == 56); +SDL_COMPILE_TIME_ASSERT(SDL_Event, sizeof(SDL_Event) == sizeof(((SDL_Event *)NULL)->padding)); /* Function prototypes */ /** - * Pumps the event loop, gathering events from the input devices. + * Pump the event loop, gathering events from the input devices. * - * This function updates the event queue and internal input device state. + * This function updates the event queue and internal input device state. * - * This should only be run in the thread that sets the video mode. + * **WARNING**: This should only be run in the thread that initialized the + * video subsystem, and for extra safety, you should consider only doing those + * things on the main thread in any case. + * + * SDL_PumpEvents() gathers all the pending input information from devices and + * places it in the event queue. Without calls to SDL_PumpEvents() no events + * would ever be placed on the queue. Often the need for calls to + * SDL_PumpEvents() is hidden from the user since SDL_PollEvent() and + * SDL_WaitEvent() implicitly call SDL_PumpEvents(). However, if you are not + * polling or waiting for events (e.g. you are filtering them), then you must + * call SDL_PumpEvents() to force an event queue update. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_PollEvent + * \sa SDL_WaitEvent */ extern DECLSPEC void SDLCALL SDL_PumpEvents(void); @@ -619,22 +704,42 @@ typedef enum } SDL_eventaction; /** - * Checks the event queue for messages and optionally returns them. + * Check the event queue for messages and optionally return them. * - * If \c action is ::SDL_ADDEVENT, up to \c numevents events will be added to - * the back of the event queue. + * `action` may be any of the following: * - * If \c action is ::SDL_PEEKEVENT, up to \c numevents events at the front - * of the event queue, within the specified minimum and maximum type, - * will be returned and will not be removed from the queue. + * - `SDL_ADDEVENT`: up to `numevents` events will be added to the back of the + * event queue. + * - `SDL_PEEKEVENT`: `numevents` events at the front of the event queue, + * within the specified minimum and maximum type, will be returned to the + * caller and will _not_ be removed from the queue. + * - `SDL_GETEVENT`: up to `numevents` events at the front of the event queue, + * within the specified minimum and maximum type, will be returned to the + * caller and will be removed from the queue. * - * If \c action is ::SDL_GETEVENT, up to \c numevents events at the front - * of the event queue, within the specified minimum and maximum type, - * will be returned and will be removed from the queue. + * You may have to call SDL_PumpEvents() before calling this function. + * Otherwise, the events may not be ready to be filtered when you call + * SDL_PeepEvents(). * - * \return The number of events actually stored, or -1 if there was an error. + * This function is thread-safe. * - * This function is thread-safe. + * \param events destination buffer for the retrieved events + * \param numevents if action is SDL_ADDEVENT, the number of events to add + * back to the event queue; if action is SDL_PEEKEVENT or + * SDL_GETEVENT, the maximum number of events to retrieve + * \param action action to take; see [[#action|Remarks]] for details + * \param minType minimum value of the event type to be considered; + * SDL_FIRSTEVENT is a safe choice + * \param maxType maximum value of the event type to be considered; + * SDL_LASTEVENT is a safe choice + * \returns the number of events actually stored or a negative error code on + * failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_PollEvent + * \sa SDL_PumpEvents + * \sa SDL_PushEvent */ extern DECLSPEC int SDLCALL SDL_PeepEvents(SDL_Event * events, int numevents, SDL_eventaction action, @@ -642,113 +747,354 @@ extern DECLSPEC int SDLCALL SDL_PeepEvents(SDL_Event * events, int numevents, /* @} */ /** - * Checks to see if certain event types are in the event queue. + * Check for the existence of a certain event type in the event queue. + * + * If you need to check for a range of event types, use SDL_HasEvents() + * instead. + * + * \param type the type of event to be queried; see SDL_EventType for details + * \returns SDL_TRUE if events matching `type` are present, or SDL_FALSE if + * events matching `type` are not present. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HasEvents */ extern DECLSPEC SDL_bool SDLCALL SDL_HasEvent(Uint32 type); + + +/** + * Check for the existence of certain event types in the event queue. + * + * If you need to check for a single event type, use SDL_HasEvent() instead. + * + * \param minType the low end of event type to be queried, inclusive; see + * SDL_EventType for details + * \param maxType the high end of event type to be queried, inclusive; see + * SDL_EventType for details + * \returns SDL_TRUE if events with type >= `minType` and <= `maxType` are + * present, or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HasEvents + */ extern DECLSPEC SDL_bool SDLCALL SDL_HasEvents(Uint32 minType, Uint32 maxType); /** - * This function clears events from the event queue - * This function only affects currently queued events. If you want to make - * sure that all pending OS events are flushed, you can call SDL_PumpEvents() - * on the main thread immediately before the flush call. + * Clear events of a specific type from the event queue. + * + * This will unconditionally remove any events from the queue that match + * `type`. If you need to remove a range of event types, use SDL_FlushEvents() + * instead. + * + * It's also normal to just ignore events you don't care about in your event + * loop without calling this function. + * + * This function only affects currently queued events. If you want to make + * sure that all pending OS events are flushed, you can call SDL_PumpEvents() + * on the main thread immediately before the flush call. + * + * \param type the type of event to be cleared; see SDL_EventType for details + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_FlushEvents */ extern DECLSPEC void SDLCALL SDL_FlushEvent(Uint32 type); + +/** + * Clear events of a range of types from the event queue. + * + * This will unconditionally remove any events from the queue that are in the + * range of `minType` to `maxType`, inclusive. If you need to remove a single + * event type, use SDL_FlushEvent() instead. + * + * It's also normal to just ignore events you don't care about in your event + * loop without calling this function. + * + * This function only affects currently queued events. If you want to make + * sure that all pending OS events are flushed, you can call SDL_PumpEvents() + * on the main thread immediately before the flush call. + * + * \param minType the low end of event type to be cleared, inclusive; see + * SDL_EventType for details + * \param maxType the high end of event type to be cleared, inclusive; see + * SDL_EventType for details + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_FlushEvent + */ extern DECLSPEC void SDLCALL SDL_FlushEvents(Uint32 minType, Uint32 maxType); /** - * \brief Polls for currently pending events. + * Poll for currently pending events. * - * \return 1 if there are any pending events, or 0 if there are none available. + * If `event` is not NULL, the next event is removed from the queue and stored + * in the SDL_Event structure pointed to by `event`. The 1 returned refers to + * this event, immediately stored in the SDL Event structure -- not an event + * to follow. * - * \param event If not NULL, the next event is removed from the queue and - * stored in that area. + * If `event` is NULL, it simply returns 1 if there is an event in the queue, + * but will not remove it from the queue. + * + * As this function may implicitly call SDL_PumpEvents(), you can only call + * this function in the thread that set the video mode. + * + * SDL_PollEvent() is the favored way of receiving system events since it can + * be done from the main loop and does not suspend the main loop while waiting + * on an event to be posted. + * + * The common practice is to fully process the event queue once every frame, + * usually as a first step before updating the game's state: + * + * ```c + * while (game_is_still_running) { + * SDL_Event event; + * while (SDL_PollEvent(&event)) { // poll until all events are handled! + * // decide what to do with this event. + * } + * + * // update game state, draw the current frame + * } + * ``` + * + * \param event the SDL_Event structure to be filled with the next event from + * the queue, or NULL + * \returns 1 if there is a pending event or 0 if there are none available. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetEventFilter + * \sa SDL_PeepEvents + * \sa SDL_PushEvent + * \sa SDL_SetEventFilter + * \sa SDL_WaitEvent + * \sa SDL_WaitEventTimeout */ extern DECLSPEC int SDLCALL SDL_PollEvent(SDL_Event * event); /** - * \brief Waits indefinitely for the next available event. + * Wait indefinitely for the next available event. * - * \return 1, or 0 if there was an error while waiting for events. + * If `event` is not NULL, the next event is removed from the queue and stored + * in the SDL_Event structure pointed to by `event`. * - * \param event If not NULL, the next event is removed from the queue and - * stored in that area. + * As this function may implicitly call SDL_PumpEvents(), you can only call + * this function in the thread that initialized the video subsystem. + * + * \param event the SDL_Event structure to be filled in with the next event + * from the queue, or NULL + * \returns 1 on success or 0 if there was an error while waiting for events; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_PollEvent + * \sa SDL_PumpEvents + * \sa SDL_WaitEventTimeout */ extern DECLSPEC int SDLCALL SDL_WaitEvent(SDL_Event * event); /** - * \brief Waits until the specified timeout (in milliseconds) for the next - * available event. + * Wait until the specified timeout (in milliseconds) for the next available + * event. * - * \return 1, or 0 if there was an error while waiting for events. + * If `event` is not NULL, the next event is removed from the queue and stored + * in the SDL_Event structure pointed to by `event`. * - * \param event If not NULL, the next event is removed from the queue and - * stored in that area. - * \param timeout The timeout (in milliseconds) to wait for next event. + * As this function may implicitly call SDL_PumpEvents(), you can only call + * this function in the thread that initialized the video subsystem. + * + * \param event the SDL_Event structure to be filled in with the next event + * from the queue, or NULL + * \param timeout the maximum number of milliseconds to wait for the next + * available event + * \returns 1 on success or 0 if there was an error while waiting for events; + * call SDL_GetError() for more information. This also returns 0 if + * the timeout elapsed without an event arriving. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_PollEvent + * \sa SDL_PumpEvents + * \sa SDL_WaitEvent */ extern DECLSPEC int SDLCALL SDL_WaitEventTimeout(SDL_Event * event, int timeout); /** - * \brief Add an event to the event queue. + * Add an event to the event queue. * - * \return 1 on success, 0 if the event was filtered, or -1 if the event queue - * was full or there was some other error. + * The event queue can actually be used as a two way communication channel. + * Not only can events be read from the queue, but the user can also push + * their own events onto it. `event` is a pointer to the event structure you + * wish to push onto the queue. The event is copied into the queue, and the + * caller may dispose of the memory pointed to after SDL_PushEvent() returns. + * + * Note: Pushing device input events onto the queue doesn't modify the state + * of the device within SDL. + * + * This function is thread-safe, and can be called from other threads safely. + * + * Note: Events pushed onto the queue with SDL_PushEvent() get passed through + * the event filter but events added with SDL_PeepEvents() do not. + * + * For pushing application-specific events, please use SDL_RegisterEvents() to + * get an event type that does not conflict with other code that also wants + * its own custom event types. + * + * \param event the SDL_Event to be added to the queue + * \returns 1 on success, 0 if the event was filtered, or a negative error + * code on failure; call SDL_GetError() for more information. A + * common reason for error is the event queue being full. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_PeepEvents + * \sa SDL_PollEvent + * \sa SDL_RegisterEvents */ extern DECLSPEC int SDLCALL SDL_PushEvent(SDL_Event * event); +/** + * A function pointer used for callbacks that watch the event queue. + * + * \param userdata what was passed as `userdata` to SDL_SetEventFilter() + * or SDL_AddEventWatch, etc + * \param event the event that triggered the callback + * \returns 1 to permit event to be added to the queue, and 0 to disallow + * it. When used with SDL_AddEventWatch, the return value is ignored. + * + * \sa SDL_SetEventFilter + * \sa SDL_AddEventWatch + */ typedef int (SDLCALL * SDL_EventFilter) (void *userdata, SDL_Event * event); /** - * Sets up a filter to process all events before they change internal state and - * are posted to the internal event queue. + * Set up a filter to process all events before they change internal state and + * are posted to the internal event queue. * - * The filter is prototyped as: - * \code - * int SDL_EventFilter(void *userdata, SDL_Event * event); - * \endcode + * If the filter function returns 1 when called, then the event will be added + * to the internal queue. If it returns 0, then the event will be dropped from + * the queue, but the internal state will still be updated. This allows + * selective filtering of dynamically arriving events. * - * If the filter returns 1, then the event will be added to the internal queue. - * If it returns 0, then the event will be dropped from the queue, but the - * internal state will still be updated. This allows selective filtering of - * dynamically arriving events. + * **WARNING**: Be very careful of what you do in the event filter function, + * as it may run in a different thread! * - * \warning Be very careful of what you do in the event filter function, as - * it may run in a different thread! + * On platforms that support it, if the quit event is generated by an + * interrupt signal (e.g. pressing Ctrl-C), it will be delivered to the + * application at the next event poll. * - * There is one caveat when dealing with the ::SDL_QuitEvent event type. The - * event filter is only called when the window manager desires to close the - * application window. If the event filter returns 1, then the window will - * be closed, otherwise the window will remain open if possible. + * There is one caveat when dealing with the ::SDL_QuitEvent event type. The + * event filter is only called when the window manager desires to close the + * application window. If the event filter returns 1, then the window will be + * closed, otherwise the window will remain open if possible. * - * If the quit event is generated by an interrupt signal, it will bypass the - * internal queue and be delivered to the application at the next event poll. + * Note: Disabled events never make it to the event filter function; see + * SDL_EventState(). + * + * Note: If you just want to inspect events without filtering, you should use + * SDL_AddEventWatch() instead. + * + * Note: Events pushed onto the queue with SDL_PushEvent() get passed through + * the event filter, but events pushed onto the queue with SDL_PeepEvents() do + * not. + * + * \param filter An SDL_EventFilter function to call when an event happens + * \param userdata a pointer that is passed to `filter` + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AddEventWatch + * \sa SDL_EventState + * \sa SDL_GetEventFilter + * \sa SDL_PeepEvents + * \sa SDL_PushEvent */ extern DECLSPEC void SDLCALL SDL_SetEventFilter(SDL_EventFilter filter, void *userdata); /** - * Return the current event filter - can be used to "chain" filters. - * If there is no event filter set, this function returns SDL_FALSE. + * Query the current event filter. + * + * This function can be used to "chain" filters, by saving the existing filter + * before replacing it with a function that will call that saved filter. + * + * \param filter the current callback function will be stored here + * \param userdata the pointer that is passed to the current event filter will + * be stored here + * \returns SDL_TRUE on success or SDL_FALSE if there is no event filter set. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetEventFilter */ extern DECLSPEC SDL_bool SDLCALL SDL_GetEventFilter(SDL_EventFilter * filter, void **userdata); /** - * Add a function which is called when an event is added to the queue. + * Add a callback to be triggered when an event is added to the event queue. + * + * `filter` will be called when an event happens, and its return value is + * ignored. + * + * **WARNING**: Be very careful of what you do in the event filter function, + * as it may run in a different thread! + * + * If the quit event is generated by a signal (e.g. SIGINT), it will bypass + * the internal queue and be delivered to the watch callback immediately, and + * arrive at the next event poll. + * + * Note: the callback is called for events posted by the user through + * SDL_PushEvent(), but not for disabled events, nor for events by a filter + * callback set with SDL_SetEventFilter(), nor for events posted by the user + * through SDL_PeepEvents(). + * + * \param filter an SDL_EventFilter function to call when an event happens. + * \param userdata a pointer that is passed to `filter` + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_DelEventWatch + * \sa SDL_SetEventFilter */ extern DECLSPEC void SDLCALL SDL_AddEventWatch(SDL_EventFilter filter, void *userdata); /** - * Remove an event watch function added with SDL_AddEventWatch() + * Remove an event watch callback added with SDL_AddEventWatch(). + * + * This function takes the same input as SDL_AddEventWatch() to identify and + * delete the corresponding callback. + * + * \param filter the function originally passed to SDL_AddEventWatch() + * \param userdata the pointer originally passed to SDL_AddEventWatch() + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AddEventWatch */ extern DECLSPEC void SDLCALL SDL_DelEventWatch(SDL_EventFilter filter, void *userdata); /** - * Run the filter function on the current event queue, removing any - * events for which the filter returns 0. + * Run a specific filter function on the current event queue, removing any + * events for which the filter returns 0. + * + * See SDL_SetEventFilter() for more information. Unlike SDL_SetEventFilter(), + * this function does not change the filter permanently, it only uses the + * supplied filter until this function returns. + * + * \param filter the SDL_EventFilter function to call when an event happens + * \param userdata a pointer that is passed to `filter` + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetEventFilter + * \sa SDL_SetEventFilter */ extern DECLSPEC void SDLCALL SDL_FilterEvents(SDL_EventFilter filter, void *userdata); @@ -760,24 +1106,45 @@ extern DECLSPEC void SDLCALL SDL_FilterEvents(SDL_EventFilter filter, #define SDL_ENABLE 1 /** - * This function allows you to set the state of processing certain events. - * - If \c state is set to ::SDL_IGNORE, that event will be automatically - * dropped from the event queue and will not be filtered. - * - If \c state is set to ::SDL_ENABLE, that event will be processed - * normally. - * - If \c state is set to ::SDL_QUERY, SDL_EventState() will return the - * current processing state of the specified event. + * Set the state of processing events by type. + * + * `state` may be any of the following: + * + * - `SDL_QUERY`: returns the current processing state of the specified event + * - `SDL_IGNORE` (aka `SDL_DISABLE`): the event will automatically be dropped + * from the event queue and will not be filtered + * - `SDL_ENABLE`: the event will be processed normally + * + * \param type the type of event; see SDL_EventType for details + * \param state how to process the event + * \returns `SDL_DISABLE` or `SDL_ENABLE`, representing the processing state + * of the event before this function makes any changes to it. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetEventState */ extern DECLSPEC Uint8 SDLCALL SDL_EventState(Uint32 type, int state); /* @} */ #define SDL_GetEventState(type) SDL_EventState(type, SDL_QUERY) /** - * This function allocates a set of user-defined events, and returns - * the beginning event number for that set of events. + * Allocate a set of user-defined events, and return the beginning event + * number for that set of events. * - * If there aren't enough user-defined events left, this function - * returns (Uint32)-1 + * Calling this function with `numevents` <= 0 is an error and will return + * (Uint32)-1. + * + * Note, (Uint32)-1 means the maximum unsigned 32-bit integer value (or + * 0xFFFFFFFF), but is clearer to write. + * + * \param numevents the number of events to be allocated + * \returns the beginning event number, or (Uint32)-1 if there are not enough + * user-defined events left. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_PushEvent */ extern DECLSPEC Uint32 SDLCALL SDL_RegisterEvents(int numevents); diff --git a/SDL2-2.30.5/include/SDL_filesystem.h b/SDL2-2.30.5/include/SDL_filesystem.h new file mode 100644 index 0000000..0749889 --- /dev/null +++ b/SDL2-2.30.5/include/SDL_filesystem.h @@ -0,0 +1,149 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_filesystem.h + * + * \brief Include file for filesystem SDL API functions + */ + +#ifndef SDL_filesystem_h_ +#define SDL_filesystem_h_ + +#include "SDL_stdinc.h" + +#include "begin_code.h" + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Get the directory where the application was run from. + * + * This is not necessarily a fast call, so you should call this once near + * startup and save the string if you need it. + * + * **Mac OS X and iOS Specific Functionality**: If the application is in a + * ".app" bundle, this function returns the Resource directory (e.g. + * MyApp.app/Contents/Resources/). This behaviour can be overridden by adding + * a property to the Info.plist file. Adding a string key with the name + * SDL_FILESYSTEM_BASE_DIR_TYPE with a supported value will change the + * behaviour. + * + * Supported values for the SDL_FILESYSTEM_BASE_DIR_TYPE property (Given an + * application in /Applications/SDLApp/MyApp.app): + * + * - `resource`: bundle resource directory (the default). For example: + * `/Applications/SDLApp/MyApp.app/Contents/Resources` + * - `bundle`: the Bundle directory. For example: + * `/Applications/SDLApp/MyApp.app/` + * - `parent`: the containing directory of the bundle. For example: + * `/Applications/SDLApp/` + * + * **Nintendo 3DS Specific Functionality**: This function returns "romfs" + * directory of the application as it is uncommon to store resources outside + * the executable. As such it is not a writable directory. + * + * The returned path is guaranteed to end with a path separator ('\\' on + * Windows, '/' on most other platforms). + * + * The pointer returned is owned by the caller. Please call SDL_free() on the + * pointer when done with it. + * + * \returns an absolute path in UTF-8 encoding to the application data + * directory. NULL will be returned on error or when the platform + * doesn't implement this functionality, call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.1. + * + * \sa SDL_GetPrefPath + */ +extern DECLSPEC char *SDLCALL SDL_GetBasePath(void); + +/** + * Get the user-and-app-specific path where files can be written. + * + * Get the "pref dir". This is meant to be where users can write personal + * files (preferences and save games, etc) that are specific to your + * application. This directory is unique per user, per application. + * + * This function will decide the appropriate location in the native + * filesystem, create the directory if necessary, and return a string of the + * absolute path to the directory in UTF-8 encoding. + * + * On Windows, the string might look like: + * + * `C:\\Users\\bob\\AppData\\Roaming\\My Company\\My Program Name\\` + * + * On Linux, the string might look like: + * + * `/home/bob/.local/share/My Program Name/` + * + * On Mac OS X, the string might look like: + * + * `/Users/bob/Library/Application Support/My Program Name/` + * + * You should assume the path returned by this function is the only safe place + * to write files (and that SDL_GetBasePath(), while it might be writable, or + * even the parent of the returned path, isn't where you should be writing + * things). + * + * Both the org and app strings may become part of a directory name, so please + * follow these rules: + * + * - Try to use the same org string (_including case-sensitivity_) for all + * your applications that use this function. + * - Always use a unique app string for each one, and make sure it never + * changes for an app once you've decided on it. + * - Unicode characters are legal, as long as it's UTF-8 encoded, but... + * - ...only use letters, numbers, and spaces. Avoid punctuation like "Game + * Name 2: Bad Guy's Revenge!" ... "Game Name 2" is sufficient. + * + * The returned path is guaranteed to end with a path separator ('\\' on + * Windows, '/' on most other platforms). + * + * The pointer returned is owned by the caller. Please call SDL_free() on the + * pointer when done with it. + * + * \param org the name of your organization + * \param app the name of your application + * \returns a UTF-8 string of the user directory in platform-dependent + * notation. NULL if there's a problem (creating directory failed, + * etc.). + * + * \since This function is available since SDL 2.0.1. + * + * \sa SDL_GetBasePath + */ +extern DECLSPEC char *SDLCALL SDL_GetPrefPath(const char *org, const char *app); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_filesystem_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/include/SDL_gamecontroller.h b/SDL2-2.30.5/include/SDL_gamecontroller.h new file mode 100644 index 0000000..281fa35 --- /dev/null +++ b/SDL2-2.30.5/include/SDL_gamecontroller.h @@ -0,0 +1,1096 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_gamecontroller.h + * + * Include file for SDL game controller event handling + */ + +#ifndef SDL_gamecontroller_h_ +#define SDL_gamecontroller_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_rwops.h" +#include "SDL_sensor.h" +#include "SDL_joystick.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \file SDL_gamecontroller.h + * + * In order to use these functions, SDL_Init() must have been called + * with the ::SDL_INIT_GAMECONTROLLER flag. This causes SDL to scan the system + * for game controllers, and load appropriate drivers. + * + * If you would like to receive controller updates while the application + * is in the background, you should set the following hint before calling + * SDL_Init(): SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS + */ + +/** + * The gamecontroller structure used to identify an SDL game controller + */ +struct _SDL_GameController; +typedef struct _SDL_GameController SDL_GameController; + +typedef enum +{ + SDL_CONTROLLER_TYPE_UNKNOWN = 0, + SDL_CONTROLLER_TYPE_XBOX360, + SDL_CONTROLLER_TYPE_XBOXONE, + SDL_CONTROLLER_TYPE_PS3, + SDL_CONTROLLER_TYPE_PS4, + SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO, + SDL_CONTROLLER_TYPE_VIRTUAL, + SDL_CONTROLLER_TYPE_PS5, + SDL_CONTROLLER_TYPE_AMAZON_LUNA, + SDL_CONTROLLER_TYPE_GOOGLE_STADIA, + SDL_CONTROLLER_TYPE_NVIDIA_SHIELD, + SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_LEFT, + SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT, + SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_PAIR, + SDL_CONTROLLER_TYPE_MAX +} SDL_GameControllerType; + +typedef enum +{ + SDL_CONTROLLER_BINDTYPE_NONE = 0, + SDL_CONTROLLER_BINDTYPE_BUTTON, + SDL_CONTROLLER_BINDTYPE_AXIS, + SDL_CONTROLLER_BINDTYPE_HAT +} SDL_GameControllerBindType; + +/** + * Get the SDL joystick layer binding for this controller button/axis mapping + */ +typedef struct SDL_GameControllerButtonBind +{ + SDL_GameControllerBindType bindType; + union + { + int button; + int axis; + struct { + int hat; + int hat_mask; + } hat; + } value; + +} SDL_GameControllerButtonBind; + + +/** + * To count the number of game controllers in the system for the following: + * + * ```c + * int nJoysticks = SDL_NumJoysticks(); + * int nGameControllers = 0; + * for (int i = 0; i < nJoysticks; i++) { + * if (SDL_IsGameController(i)) { + * nGameControllers++; + * } + * } + * ``` + * + * Using the SDL_HINT_GAMECONTROLLERCONFIG hint or the SDL_GameControllerAddMapping() you can add support for controllers SDL is unaware of or cause an existing controller to have a different binding. The format is: + * guid,name,mappings + * + * Where GUID is the string value from SDL_JoystickGetGUIDString(), name is the human readable string for the device and mappings are controller mappings to joystick ones. + * Under Windows there is a reserved GUID of "xinput" that covers any XInput devices. + * The mapping format for joystick is: + * bX - a joystick button, index X + * hX.Y - hat X with value Y + * aX - axis X of the joystick + * Buttons can be used as a controller axis and vice versa. + * + * This string shows an example of a valid mapping for a controller + * + * ```c + * "03000000341a00003608000000000000,PS3 Controller,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7", + * ``` + */ + +/** + * Load a set of Game Controller mappings from a seekable SDL data stream. + * + * You can call this function several times, if needed, to load different + * database files. + * + * If a new mapping is loaded for an already known controller GUID, the later + * version will overwrite the one currently loaded. + * + * Mappings not belonging to the current platform or with no platform field + * specified will be ignored (i.e. mappings for Linux will be ignored in + * Windows, etc). + * + * This function will load the text database entirely in memory before + * processing it, so take this into consideration if you are in a memory + * constrained environment. + * + * \param rw the data stream for the mappings to be added + * \param freerw non-zero to close the stream after being read + * \returns the number of mappings added or -1 on error; call SDL_GetError() + * for more information. + * + * \since This function is available since SDL 2.0.2. + * + * \sa SDL_GameControllerAddMapping + * \sa SDL_GameControllerAddMappingsFromFile + * \sa SDL_GameControllerMappingForGUID + */ +extern DECLSPEC int SDLCALL SDL_GameControllerAddMappingsFromRW(SDL_RWops * rw, int freerw); + +/** + * Load a set of mappings from a file, filtered by the current SDL_GetPlatform() + * + * Convenience macro. + */ +#define SDL_GameControllerAddMappingsFromFile(file) SDL_GameControllerAddMappingsFromRW(SDL_RWFromFile(file, "rb"), 1) + +/** + * Add support for controllers that SDL is unaware of or to cause an existing + * controller to have a different binding. + * + * The mapping string has the format "GUID,name,mapping", where GUID is the + * string value from SDL_JoystickGetGUIDString(), name is the human readable + * string for the device and mappings are controller mappings to joystick + * ones. Under Windows there is a reserved GUID of "xinput" that covers all + * XInput devices. The mapping format for joystick is: {| |bX |a joystick + * button, index X |- |hX.Y |hat X with value Y |- |aX |axis X of the joystick + * |} Buttons can be used as a controller axes and vice versa. + * + * This string shows an example of a valid mapping for a controller: + * + * ```c + * "341a3608000000000000504944564944,Afterglow PS3 Controller,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7" + * ``` + * + * \param mappingString the mapping string + * \returns 1 if a new mapping is added, 0 if an existing mapping is updated, + * -1 on error; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerMapping + * \sa SDL_GameControllerMappingForGUID + */ +extern DECLSPEC int SDLCALL SDL_GameControllerAddMapping(const char* mappingString); + +/** + * Get the number of mappings installed. + * + * \returns the number of mappings. + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC int SDLCALL SDL_GameControllerNumMappings(void); + +/** + * Get the mapping at a particular index. + * + * \returns the mapping string. Must be freed with SDL_free(). Returns NULL if + * the index is out of range. + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC char * SDLCALL SDL_GameControllerMappingForIndex(int mapping_index); + +/** + * Get the game controller mapping string for a given GUID. + * + * The returned string must be freed with SDL_free(). + * + * \param guid a structure containing the GUID for which a mapping is desired + * \returns a mapping string or NULL on error; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickGetDeviceGUID + * \sa SDL_JoystickGetGUID + */ +extern DECLSPEC char * SDLCALL SDL_GameControllerMappingForGUID(SDL_JoystickGUID guid); + +/** + * Get the current mapping of a Game Controller. + * + * The returned string must be freed with SDL_free(). + * + * Details about mappings are discussed with SDL_GameControllerAddMapping(). + * + * \param gamecontroller the game controller you want to get the current + * mapping for + * \returns a string that has the controller's mapping or NULL if no mapping + * is available; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerAddMapping + * \sa SDL_GameControllerMappingForGUID + */ +extern DECLSPEC char * SDLCALL SDL_GameControllerMapping(SDL_GameController *gamecontroller); + +/** + * Check if the given joystick is supported by the game controller interface. + * + * `joystick_index` is the same as the `device_index` passed to + * SDL_JoystickOpen(). + * + * \param joystick_index the device_index of a device, up to + * SDL_NumJoysticks() + * \returns SDL_TRUE if the given joystick is supported by the game controller + * interface, SDL_FALSE if it isn't or it's an invalid index. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerNameForIndex + * \sa SDL_GameControllerOpen + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IsGameController(int joystick_index); + +/** + * Get the implementation dependent name for the game controller. + * + * This function can be called before any controllers are opened. + * + * `joystick_index` is the same as the `device_index` passed to + * SDL_JoystickOpen(). + * + * \param joystick_index the device_index of a device, from zero to + * SDL_NumJoysticks()-1 + * \returns the implementation-dependent name for the game controller, or NULL + * if there is no name or the index is invalid. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerName + * \sa SDL_GameControllerOpen + * \sa SDL_IsGameController + */ +extern DECLSPEC const char *SDLCALL SDL_GameControllerNameForIndex(int joystick_index); + +/** + * Get the implementation dependent path for the game controller. + * + * This function can be called before any controllers are opened. + * + * `joystick_index` is the same as the `device_index` passed to + * SDL_JoystickOpen(). + * + * \param joystick_index the device_index of a device, from zero to + * SDL_NumJoysticks()-1 + * \returns the implementation-dependent path for the game controller, or NULL + * if there is no path or the index is invalid. + * + * \since This function is available since SDL 2.24.0. + * + * \sa SDL_GameControllerPath + */ +extern DECLSPEC const char *SDLCALL SDL_GameControllerPathForIndex(int joystick_index); + +/** + * Get the type of a game controller. + * + * This can be called before any controllers are opened. + * + * \param joystick_index the device_index of a device, from zero to + * SDL_NumJoysticks()-1 + * \returns the controller type. + * + * \since This function is available since SDL 2.0.12. + */ +extern DECLSPEC SDL_GameControllerType SDLCALL SDL_GameControllerTypeForIndex(int joystick_index); + +/** + * Get the mapping of a game controller. + * + * This can be called before any controllers are opened. + * + * \param joystick_index the device_index of a device, from zero to + * SDL_NumJoysticks()-1 + * \returns the mapping string. Must be freed with SDL_free(). Returns NULL if + * no mapping is available. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC char *SDLCALL SDL_GameControllerMappingForDeviceIndex(int joystick_index); + +/** + * Open a game controller for use. + * + * `joystick_index` is the same as the `device_index` passed to + * SDL_JoystickOpen(). + * + * The index passed as an argument refers to the N'th game controller on the + * system. This index is not the value which will identify this controller in + * future controller events. The joystick's instance id (SDL_JoystickID) will + * be used there instead. + * + * \param joystick_index the device_index of a device, up to + * SDL_NumJoysticks() + * \returns a gamecontroller identifier or NULL if an error occurred; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerClose + * \sa SDL_GameControllerNameForIndex + * \sa SDL_IsGameController + */ +extern DECLSPEC SDL_GameController *SDLCALL SDL_GameControllerOpen(int joystick_index); + +/** + * Get the SDL_GameController associated with an instance id. + * + * \param joyid the instance id to get the SDL_GameController for + * \returns an SDL_GameController on success or NULL on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.4. + */ +extern DECLSPEC SDL_GameController *SDLCALL SDL_GameControllerFromInstanceID(SDL_JoystickID joyid); + +/** + * Get the SDL_GameController associated with a player index. + * + * Please note that the player index is _not_ the device index, nor is it the + * instance id! + * + * \param player_index the player index, which is not the device index or the + * instance id! + * \returns the SDL_GameController associated with a player index. + * + * \since This function is available since SDL 2.0.12. + * + * \sa SDL_GameControllerGetPlayerIndex + * \sa SDL_GameControllerSetPlayerIndex + */ +extern DECLSPEC SDL_GameController *SDLCALL SDL_GameControllerFromPlayerIndex(int player_index); + +/** + * Get the implementation-dependent name for an opened game controller. + * + * This is the same name as returned by SDL_GameControllerNameForIndex(), but + * it takes a controller identifier instead of the (unstable) device index. + * + * \param gamecontroller a game controller identifier previously returned by + * SDL_GameControllerOpen() + * \returns the implementation dependent name for the game controller, or NULL + * if there is no name or the identifier passed is invalid. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerNameForIndex + * \sa SDL_GameControllerOpen + */ +extern DECLSPEC const char *SDLCALL SDL_GameControllerName(SDL_GameController *gamecontroller); + +/** + * Get the implementation-dependent path for an opened game controller. + * + * This is the same path as returned by SDL_GameControllerNameForIndex(), but + * it takes a controller identifier instead of the (unstable) device index. + * + * \param gamecontroller a game controller identifier previously returned by + * SDL_GameControllerOpen() + * \returns the implementation dependent path for the game controller, or NULL + * if there is no path or the identifier passed is invalid. + * + * \since This function is available since SDL 2.24.0. + * + * \sa SDL_GameControllerPathForIndex + */ +extern DECLSPEC const char *SDLCALL SDL_GameControllerPath(SDL_GameController *gamecontroller); + +/** + * Get the type of this currently opened controller + * + * This is the same name as returned by SDL_GameControllerTypeForIndex(), but + * it takes a controller identifier instead of the (unstable) device index. + * + * \param gamecontroller the game controller object to query. + * \returns the controller type. + * + * \since This function is available since SDL 2.0.12. + */ +extern DECLSPEC SDL_GameControllerType SDLCALL SDL_GameControllerGetType(SDL_GameController *gamecontroller); + +/** + * Get the player index of an opened game controller. + * + * For XInput controllers this returns the XInput user index. + * + * \param gamecontroller the game controller object to query. + * \returns the player index for controller, or -1 if it's not available. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC int SDLCALL SDL_GameControllerGetPlayerIndex(SDL_GameController *gamecontroller); + +/** + * Set the player index of an opened game controller. + * + * \param gamecontroller the game controller object to adjust. + * \param player_index Player index to assign to this controller, or -1 to + * clear the player index and turn off player LEDs. + * + * \since This function is available since SDL 2.0.12. + */ +extern DECLSPEC void SDLCALL SDL_GameControllerSetPlayerIndex(SDL_GameController *gamecontroller, int player_index); + +/** + * Get the USB vendor ID of an opened controller, if available. + * + * If the vendor ID isn't available this function returns 0. + * + * \param gamecontroller the game controller object to query. + * \return the USB vendor ID, or zero if unavailable. + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC Uint16 SDLCALL SDL_GameControllerGetVendor(SDL_GameController *gamecontroller); + +/** + * Get the USB product ID of an opened controller, if available. + * + * If the product ID isn't available this function returns 0. + * + * \param gamecontroller the game controller object to query. + * \return the USB product ID, or zero if unavailable. + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC Uint16 SDLCALL SDL_GameControllerGetProduct(SDL_GameController *gamecontroller); + +/** + * Get the product version of an opened controller, if available. + * + * If the product version isn't available this function returns 0. + * + * \param gamecontroller the game controller object to query. + * \return the USB product version, or zero if unavailable. + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC Uint16 SDLCALL SDL_GameControllerGetProductVersion(SDL_GameController *gamecontroller); + +/** + * Get the firmware version of an opened controller, if available. + * + * If the firmware version isn't available this function returns 0. + * + * \param gamecontroller the game controller object to query. + * \return the controller firmware version, or zero if unavailable. + * + * \since This function is available since SDL 2.24.0. + */ +extern DECLSPEC Uint16 SDLCALL SDL_GameControllerGetFirmwareVersion(SDL_GameController *gamecontroller); + +/** + * Get the serial number of an opened controller, if available. + * + * Returns the serial number of the controller, or NULL if it is not + * available. + * + * \param gamecontroller the game controller object to query. + * \return the serial number, or NULL if unavailable. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC const char * SDLCALL SDL_GameControllerGetSerial(SDL_GameController *gamecontroller); + +/** + * Get the Steam Input handle of an opened controller, if available. + * + * Returns an InputHandle_t for the controller that can be used with Steam Input API: + * https://partner.steamgames.com/doc/api/ISteamInput + * + * \param gamecontroller the game controller object to query. + * \returns the gamepad handle, or 0 if unavailable. + * + * \since This function is available since SDL 2.30.0. + */ +extern DECLSPEC Uint64 SDLCALL SDL_GameControllerGetSteamHandle(SDL_GameController *gamecontroller); + + +/** + * Check if a controller has been opened and is currently connected. + * + * \param gamecontroller a game controller identifier previously returned by + * SDL_GameControllerOpen() + * \returns SDL_TRUE if the controller has been opened and is currently + * connected, or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerClose + * \sa SDL_GameControllerOpen + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GameControllerGetAttached(SDL_GameController *gamecontroller); + +/** + * Get the Joystick ID from a Game Controller. + * + * This function will give you a SDL_Joystick object, which allows you to use + * the SDL_Joystick functions with a SDL_GameController object. This would be + * useful for getting a joystick's position at any given time, even if it + * hasn't moved (moving it would produce an event, which would have the axis' + * value). + * + * The pointer returned is owned by the SDL_GameController. You should not + * call SDL_JoystickClose() on it, for example, since doing so will likely + * cause SDL to crash. + * + * \param gamecontroller the game controller object that you want to get a + * joystick from + * \returns a SDL_Joystick object; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC SDL_Joystick *SDLCALL SDL_GameControllerGetJoystick(SDL_GameController *gamecontroller); + +/** + * Query or change current state of Game Controller events. + * + * If controller events are disabled, you must call SDL_GameControllerUpdate() + * yourself and check the state of the controller when you want controller + * information. + * + * Any number can be passed to SDL_GameControllerEventState(), but only -1, 0, + * and 1 will have any effect. Other numbers will just be returned. + * + * \param state can be one of `SDL_QUERY`, `SDL_IGNORE`, or `SDL_ENABLE` + * \returns the same value passed to the function, with exception to -1 + * (SDL_QUERY), which will return the current state. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickEventState + */ +extern DECLSPEC int SDLCALL SDL_GameControllerEventState(int state); + +/** + * Manually pump game controller updates if not using the loop. + * + * This function is called automatically by the event loop if events are + * enabled. Under such circumstances, it will not be necessary to call this + * function. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC void SDLCALL SDL_GameControllerUpdate(void); + + +/** + * The list of axes available from a controller + * + * Thumbstick axis values range from SDL_JOYSTICK_AXIS_MIN to SDL_JOYSTICK_AXIS_MAX, + * and are centered within ~8000 of zero, though advanced UI will allow users to set + * or autodetect the dead zone, which varies between controllers. + * + * Trigger axis values range from 0 (released) to SDL_JOYSTICK_AXIS_MAX + * (fully pressed) when reported by SDL_GameControllerGetAxis(). Note that this is not the + * same range that will be reported by the lower-level SDL_GetJoystickAxis(). + */ +typedef enum +{ + SDL_CONTROLLER_AXIS_INVALID = -1, + SDL_CONTROLLER_AXIS_LEFTX, + SDL_CONTROLLER_AXIS_LEFTY, + SDL_CONTROLLER_AXIS_RIGHTX, + SDL_CONTROLLER_AXIS_RIGHTY, + SDL_CONTROLLER_AXIS_TRIGGERLEFT, + SDL_CONTROLLER_AXIS_TRIGGERRIGHT, + SDL_CONTROLLER_AXIS_MAX +} SDL_GameControllerAxis; + +/** + * Convert a string into SDL_GameControllerAxis enum. + * + * This function is called internally to translate SDL_GameController mapping + * strings for the underlying joystick device into the consistent + * SDL_GameController mapping. You do not normally need to call this function + * unless you are parsing SDL_GameController mappings in your own code. + * + * Note specially that "righttrigger" and "lefttrigger" map to + * `SDL_CONTROLLER_AXIS_TRIGGERRIGHT` and `SDL_CONTROLLER_AXIS_TRIGGERLEFT`, + * respectively. + * + * \param str string representing a SDL_GameController axis + * \returns the SDL_GameControllerAxis enum corresponding to the input string, + * or `SDL_CONTROLLER_AXIS_INVALID` if no match was found. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerGetStringForAxis + */ +extern DECLSPEC SDL_GameControllerAxis SDLCALL SDL_GameControllerGetAxisFromString(const char *str); + +/** + * Convert from an SDL_GameControllerAxis enum to a string. + * + * The caller should not SDL_free() the returned string. + * + * \param axis an enum value for a given SDL_GameControllerAxis + * \returns a string for the given axis, or NULL if an invalid axis is + * specified. The string returned is of the format used by + * SDL_GameController mapping strings. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerGetAxisFromString + */ +extern DECLSPEC const char* SDLCALL SDL_GameControllerGetStringForAxis(SDL_GameControllerAxis axis); + +/** + * Get the SDL joystick layer binding for a controller axis mapping. + * + * \param gamecontroller a game controller + * \param axis an axis enum value (one of the SDL_GameControllerAxis values) + * \returns a SDL_GameControllerButtonBind describing the bind. On failure + * (like the given Controller axis doesn't exist on the device), its + * `.bindType` will be `SDL_CONTROLLER_BINDTYPE_NONE`. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerGetBindForButton + */ +extern DECLSPEC SDL_GameControllerButtonBind SDLCALL +SDL_GameControllerGetBindForAxis(SDL_GameController *gamecontroller, + SDL_GameControllerAxis axis); + +/** + * Query whether a game controller has a given axis. + * + * This merely reports whether the controller's mapping defined this axis, as + * that is all the information SDL has about the physical device. + * + * \param gamecontroller a game controller + * \param axis an axis enum value (an SDL_GameControllerAxis value) + * \returns SDL_TRUE if the controller has this axis, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC SDL_bool SDLCALL +SDL_GameControllerHasAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis); + +/** + * Get the current state of an axis control on a game controller. + * + * The axis indices start at index 0. + * + * For thumbsticks, the state is a value ranging from -32768 (up/left) + * to 32767 (down/right). + * + * Triggers range from 0 when released to 32767 when fully pressed, and + * never return a negative value. Note that this differs from the value + * reported by the lower-level SDL_GetJoystickAxis(), which normally uses + * the full range. + * + * \param gamecontroller a game controller + * \param axis an axis index (one of the SDL_GameControllerAxis values) + * \returns axis state (including 0) on success or 0 (also) on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerGetButton + */ +extern DECLSPEC Sint16 SDLCALL +SDL_GameControllerGetAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis); + +/** + * The list of buttons available from a controller + */ +typedef enum +{ + SDL_CONTROLLER_BUTTON_INVALID = -1, + SDL_CONTROLLER_BUTTON_A, + SDL_CONTROLLER_BUTTON_B, + SDL_CONTROLLER_BUTTON_X, + SDL_CONTROLLER_BUTTON_Y, + SDL_CONTROLLER_BUTTON_BACK, + SDL_CONTROLLER_BUTTON_GUIDE, + SDL_CONTROLLER_BUTTON_START, + SDL_CONTROLLER_BUTTON_LEFTSTICK, + SDL_CONTROLLER_BUTTON_RIGHTSTICK, + SDL_CONTROLLER_BUTTON_LEFTSHOULDER, + SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, + SDL_CONTROLLER_BUTTON_DPAD_UP, + SDL_CONTROLLER_BUTTON_DPAD_DOWN, + SDL_CONTROLLER_BUTTON_DPAD_LEFT, + SDL_CONTROLLER_BUTTON_DPAD_RIGHT, + SDL_CONTROLLER_BUTTON_MISC1, /* Xbox Series X share button, PS5 microphone button, Nintendo Switch Pro capture button, Amazon Luna microphone button */ + SDL_CONTROLLER_BUTTON_PADDLE1, /* Xbox Elite paddle P1 (upper left, facing the back) */ + SDL_CONTROLLER_BUTTON_PADDLE2, /* Xbox Elite paddle P3 (upper right, facing the back) */ + SDL_CONTROLLER_BUTTON_PADDLE3, /* Xbox Elite paddle P2 (lower left, facing the back) */ + SDL_CONTROLLER_BUTTON_PADDLE4, /* Xbox Elite paddle P4 (lower right, facing the back) */ + SDL_CONTROLLER_BUTTON_TOUCHPAD, /* PS4/PS5 touchpad button */ + SDL_CONTROLLER_BUTTON_MAX +} SDL_GameControllerButton; + +/** + * Convert a string into an SDL_GameControllerButton enum. + * + * This function is called internally to translate SDL_GameController mapping + * strings for the underlying joystick device into the consistent + * SDL_GameController mapping. You do not normally need to call this function + * unless you are parsing SDL_GameController mappings in your own code. + * + * \param str string representing a SDL_GameController axis + * \returns the SDL_GameControllerButton enum corresponding to the input + * string, or `SDL_CONTROLLER_AXIS_INVALID` if no match was found. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC SDL_GameControllerButton SDLCALL SDL_GameControllerGetButtonFromString(const char *str); + +/** + * Convert from an SDL_GameControllerButton enum to a string. + * + * The caller should not SDL_free() the returned string. + * + * \param button an enum value for a given SDL_GameControllerButton + * \returns a string for the given button, or NULL if an invalid button is + * specified. The string returned is of the format used by + * SDL_GameController mapping strings. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerGetButtonFromString + */ +extern DECLSPEC const char* SDLCALL SDL_GameControllerGetStringForButton(SDL_GameControllerButton button); + +/** + * Get the SDL joystick layer binding for a controller button mapping. + * + * \param gamecontroller a game controller + * \param button an button enum value (an SDL_GameControllerButton value) + * \returns a SDL_GameControllerButtonBind describing the bind. On failure + * (like the given Controller button doesn't exist on the device), + * its `.bindType` will be `SDL_CONTROLLER_BINDTYPE_NONE`. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerGetBindForAxis + */ +extern DECLSPEC SDL_GameControllerButtonBind SDLCALL +SDL_GameControllerGetBindForButton(SDL_GameController *gamecontroller, + SDL_GameControllerButton button); + +/** + * Query whether a game controller has a given button. + * + * This merely reports whether the controller's mapping defined this button, + * as that is all the information SDL has about the physical device. + * + * \param gamecontroller a game controller + * \param button a button enum value (an SDL_GameControllerButton value) + * \returns SDL_TRUE if the controller has this button, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GameControllerHasButton(SDL_GameController *gamecontroller, + SDL_GameControllerButton button); + +/** + * Get the current state of a button on a game controller. + * + * \param gamecontroller a game controller + * \param button a button index (one of the SDL_GameControllerButton values) + * \returns 1 for pressed state or 0 for not pressed state or error; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerGetAxis + */ +extern DECLSPEC Uint8 SDLCALL SDL_GameControllerGetButton(SDL_GameController *gamecontroller, + SDL_GameControllerButton button); + +/** + * Get the number of touchpads on a game controller. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC int SDLCALL SDL_GameControllerGetNumTouchpads(SDL_GameController *gamecontroller); + +/** + * Get the number of supported simultaneous fingers on a touchpad on a game + * controller. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC int SDLCALL SDL_GameControllerGetNumTouchpadFingers(SDL_GameController *gamecontroller, int touchpad); + +/** + * Get the current state of a finger on a touchpad on a game controller. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC int SDLCALL SDL_GameControllerGetTouchpadFinger(SDL_GameController *gamecontroller, int touchpad, int finger, Uint8 *state, float *x, float *y, float *pressure); + +/** + * Return whether a game controller has a particular sensor. + * + * \param gamecontroller The controller to query + * \param type The type of sensor to query + * \returns SDL_TRUE if the sensor exists, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GameControllerHasSensor(SDL_GameController *gamecontroller, SDL_SensorType type); + +/** + * Set whether data reporting for a game controller sensor is enabled. + * + * \param gamecontroller The controller to update + * \param type The type of sensor to enable/disable + * \param enabled Whether data reporting should be enabled + * \returns 0 or -1 if an error occurred. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC int SDLCALL SDL_GameControllerSetSensorEnabled(SDL_GameController *gamecontroller, SDL_SensorType type, SDL_bool enabled); + +/** + * Query whether sensor data reporting is enabled for a game controller. + * + * \param gamecontroller The controller to query + * \param type The type of sensor to query + * \returns SDL_TRUE if the sensor is enabled, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GameControllerIsSensorEnabled(SDL_GameController *gamecontroller, SDL_SensorType type); + +/** + * Get the data rate (number of events per second) of a game controller + * sensor. + * + * \param gamecontroller The controller to query + * \param type The type of sensor to query + * \return the data rate, or 0.0f if the data rate is not available. + * + * \since This function is available since SDL 2.0.16. + */ +extern DECLSPEC float SDLCALL SDL_GameControllerGetSensorDataRate(SDL_GameController *gamecontroller, SDL_SensorType type); + +/** + * Get the current state of a game controller sensor. + * + * The number of values and interpretation of the data is sensor dependent. + * See SDL_sensor.h for the details for each type of sensor. + * + * \param gamecontroller The controller to query + * \param type The type of sensor to query + * \param data A pointer filled with the current sensor state + * \param num_values The number of values to write to data + * \return 0 or -1 if an error occurred. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC int SDLCALL SDL_GameControllerGetSensorData(SDL_GameController *gamecontroller, SDL_SensorType type, float *data, int num_values); + +/** + * Get the current state of a game controller sensor with the timestamp of the + * last update. + * + * The number of values and interpretation of the data is sensor dependent. + * See SDL_sensor.h for the details for each type of sensor. + * + * \param gamecontroller The controller to query + * \param type The type of sensor to query + * \param timestamp A pointer filled with the timestamp in microseconds of the + * current sensor reading if available, or 0 if not + * \param data A pointer filled with the current sensor state + * \param num_values The number of values to write to data + * \return 0 or -1 if an error occurred. + * + * \since This function is available since SDL 2.26.0. + */ +extern DECLSPEC int SDLCALL SDL_GameControllerGetSensorDataWithTimestamp(SDL_GameController *gamecontroller, SDL_SensorType type, Uint64 *timestamp, float *data, int num_values); + +/** + * Start a rumble effect on a game controller. + * + * Each call to this function cancels any previous rumble effect, and calling + * it with 0 intensity stops any rumbling. + * + * \param gamecontroller The controller to vibrate + * \param low_frequency_rumble The intensity of the low frequency (left) + * rumble motor, from 0 to 0xFFFF + * \param high_frequency_rumble The intensity of the high frequency (right) + * rumble motor, from 0 to 0xFFFF + * \param duration_ms The duration of the rumble effect, in milliseconds + * \returns 0, or -1 if rumble isn't supported on this controller + * + * \since This function is available since SDL 2.0.9. + * + * \sa SDL_GameControllerHasRumble + */ +extern DECLSPEC int SDLCALL SDL_GameControllerRumble(SDL_GameController *gamecontroller, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms); + +/** + * Start a rumble effect in the game controller's triggers. + * + * Each call to this function cancels any previous trigger rumble effect, and + * calling it with 0 intensity stops any rumbling. + * + * Note that this is rumbling of the _triggers_ and not the game controller as + * a whole. This is currently only supported on Xbox One controllers. If you + * want the (more common) whole-controller rumble, use + * SDL_GameControllerRumble() instead. + * + * \param gamecontroller The controller to vibrate + * \param left_rumble The intensity of the left trigger rumble motor, from 0 + * to 0xFFFF + * \param right_rumble The intensity of the right trigger rumble motor, from 0 + * to 0xFFFF + * \param duration_ms The duration of the rumble effect, in milliseconds + * \returns 0, or -1 if trigger rumble isn't supported on this controller + * + * \since This function is available since SDL 2.0.14. + * + * \sa SDL_GameControllerHasRumbleTriggers + */ +extern DECLSPEC int SDLCALL SDL_GameControllerRumbleTriggers(SDL_GameController *gamecontroller, Uint16 left_rumble, Uint16 right_rumble, Uint32 duration_ms); + +/** + * Query whether a game controller has an LED. + * + * \param gamecontroller The controller to query + * \returns SDL_TRUE, or SDL_FALSE if this controller does not have a + * modifiable LED + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GameControllerHasLED(SDL_GameController *gamecontroller); + +/** + * Query whether a game controller has rumble support. + * + * \param gamecontroller The controller to query + * \returns SDL_TRUE, or SDL_FALSE if this controller does not have rumble + * support + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_GameControllerRumble + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GameControllerHasRumble(SDL_GameController *gamecontroller); + +/** + * Query whether a game controller has rumble support on triggers. + * + * \param gamecontroller The controller to query + * \returns SDL_TRUE, or SDL_FALSE if this controller does not have trigger + * rumble support + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_GameControllerRumbleTriggers + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GameControllerHasRumbleTriggers(SDL_GameController *gamecontroller); + +/** + * Update a game controller's LED color. + * + * \param gamecontroller The controller to update + * \param red The intensity of the red LED + * \param green The intensity of the green LED + * \param blue The intensity of the blue LED + * \returns 0, or -1 if this controller does not have a modifiable LED + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC int SDLCALL SDL_GameControllerSetLED(SDL_GameController *gamecontroller, Uint8 red, Uint8 green, Uint8 blue); + +/** + * Send a controller specific effect packet + * + * \param gamecontroller The controller to affect + * \param data The data to send to the controller + * \param size The size of the data to send to the controller + * \returns 0, or -1 if this controller or driver doesn't support effect + * packets + * + * \since This function is available since SDL 2.0.16. + */ +extern DECLSPEC int SDLCALL SDL_GameControllerSendEffect(SDL_GameController *gamecontroller, const void *data, int size); + +/** + * Close a game controller previously opened with SDL_GameControllerOpen(). + * + * \param gamecontroller a game controller identifier previously returned by + * SDL_GameControllerOpen() + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerOpen + */ +extern DECLSPEC void SDLCALL SDL_GameControllerClose(SDL_GameController *gamecontroller); + +/** + * Return the sfSymbolsName for a given button on a game controller on Apple + * platforms. + * + * \param gamecontroller the controller to query + * \param button a button on the game controller + * \returns the sfSymbolsName or NULL if the name can't be found + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_GameControllerGetAppleSFSymbolsNameForAxis + */ +extern DECLSPEC const char* SDLCALL SDL_GameControllerGetAppleSFSymbolsNameForButton(SDL_GameController *gamecontroller, SDL_GameControllerButton button); + +/** + * Return the sfSymbolsName for a given axis on a game controller on Apple + * platforms. + * + * \param gamecontroller the controller to query + * \param axis an axis on the game controller + * \returns the sfSymbolsName or NULL if the name can't be found + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_GameControllerGetAppleSFSymbolsNameForButton + */ +extern DECLSPEC const char* SDLCALL SDL_GameControllerGetAppleSFSymbolsNameForAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_gamecontroller_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/include/SDL_gesture.h b/SDL2-2.30.5/include/SDL_gesture.h similarity index 53% rename from SDL2-2.0.12/include/SDL_gesture.h rename to SDL2-2.30.5/include/SDL_gesture.h index 81ed431..4fffa5f 100644 --- a/SDL2-2.0.12/include/SDL_gesture.h +++ b/SDL2-2.30.5/include/SDL_gesture.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -46,36 +46,66 @@ typedef Sint64 SDL_GestureID; /* Function prototypes */ /** - * \brief Begin Recording a gesture on the specified touch, or all touches (-1) + * Begin recording a gesture on a specified touch device or all touch devices. * + * If the parameter `touchId` is -1 (i.e., all devices), this function will + * always return 1, regardless of whether there actually are any devices. * + * \param touchId the touch device id, or -1 for all touch devices + * \returns 1 on success or 0 if the specified device could not be found. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetTouchDevice */ extern DECLSPEC int SDLCALL SDL_RecordGesture(SDL_TouchID touchId); /** - * \brief Save all currently loaded Dollar Gesture templates + * Save all currently loaded Dollar Gesture templates. * + * \param dst a SDL_RWops to save to + * \returns the number of saved templates on success or 0 on failure; call + * SDL_GetError() for more information. * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LoadDollarTemplates + * \sa SDL_SaveDollarTemplate */ extern DECLSPEC int SDLCALL SDL_SaveAllDollarTemplates(SDL_RWops *dst); /** - * \brief Save a currently loaded Dollar Gesture template + * Save a currently loaded Dollar Gesture template. * + * \param gestureId a gesture id + * \param dst a SDL_RWops to save to + * \returns 1 on success or 0 on failure; call SDL_GetError() for more + * information. * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LoadDollarTemplates + * \sa SDL_SaveAllDollarTemplates */ extern DECLSPEC int SDLCALL SDL_SaveDollarTemplate(SDL_GestureID gestureId,SDL_RWops *dst); /** - * \brief Load Dollar Gesture templates from a file + * Load Dollar Gesture templates from a file. * + * \param touchId a touch id + * \param src a SDL_RWops to load from + * \returns the number of loaded templates on success or a negative error code + * (or 0) on failure; call SDL_GetError() for more information. * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SaveAllDollarTemplates + * \sa SDL_SaveDollarTemplate */ extern DECLSPEC int SDLCALL SDL_LoadDollarTemplates(SDL_TouchID touchId, SDL_RWops *src); - /* Ends C function definitions when using C++ */ #ifdef __cplusplus } diff --git a/SDL2-2.30.5/include/SDL_guid.h b/SDL2-2.30.5/include/SDL_guid.h new file mode 100644 index 0000000..7daa5f1 --- /dev/null +++ b/SDL2-2.30.5/include/SDL_guid.h @@ -0,0 +1,100 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_guid.h + * + * Include file for handling ::SDL_GUID values. + */ + +#ifndef SDL_guid_h_ +#define SDL_guid_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * An SDL_GUID is a 128-bit identifier for an input device that + * identifies that device across runs of SDL programs on the same + * platform. If the device is detached and then re-attached to a + * different port, or if the base system is rebooted, the device + * should still report the same GUID. + * + * GUIDs are as precise as possible but are not guaranteed to + * distinguish physically distinct but equivalent devices. For + * example, two game controllers from the same vendor with the same + * product ID and revision may have the same GUID. + * + * GUIDs may be platform-dependent (i.e., the same device may report + * different GUIDs on different operating systems). + */ +typedef struct { + Uint8 data[16]; +} SDL_GUID; + +/* Function prototypes */ + +/** + * Get an ASCII string representation for a given ::SDL_GUID. + * + * You should supply at least 33 bytes for pszGUID. + * + * \param guid the ::SDL_GUID you wish to convert to string + * \param pszGUID buffer in which to write the ASCII string + * \param cbGUID the size of pszGUID + * + * \since This function is available since SDL 2.24.0. + * + * \sa SDL_GUIDFromString + */ +extern DECLSPEC void SDLCALL SDL_GUIDToString(SDL_GUID guid, char *pszGUID, int cbGUID); + +/** + * Convert a GUID string into a ::SDL_GUID structure. + * + * Performs no error checking. If this function is given a string containing + * an invalid GUID, the function will silently succeed, but the GUID generated + * will not be useful. + * + * \param pchGUID string containing an ASCII representation of a GUID + * \returns a ::SDL_GUID structure. + * + * \since This function is available since SDL 2.24.0. + * + * \sa SDL_GUIDToString + */ +extern DECLSPEC SDL_GUID SDLCALL SDL_GUIDFromString(const char *pchGUID); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_guid_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/include/SDL_haptic.h b/SDL2-2.30.5/include/SDL_haptic.h similarity index 67% rename from SDL2-2.0.12/include/SDL_haptic.h rename to SDL2-2.30.5/include/SDL_haptic.h index aa6f47f..c9ed847 100644 --- a/SDL2-2.0.12/include/SDL_haptic.h +++ b/SDL2-2.30.5/include/SDL_haptic.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -76,7 +76,7 @@ * } * * // Create the effect - * memset( &effect, 0, sizeof(SDL_HapticEffect) ); // 0 is safe default + * SDL_memset( &effect, 0, sizeof(SDL_HapticEffect) ); // 0 is safe default * effect.type = SDL_HAPTIC_SINE; * effect.periodic.direction.type = SDL_HAPTIC_POLAR; // Polar coordinates * effect.periodic.direction.dir[0] = 18000; // Force comes from south @@ -336,6 +336,14 @@ typedef struct _SDL_Haptic SDL_Haptic; */ #define SDL_HAPTIC_SPHERICAL 2 +/** + * \brief Use this value to play an effect on the steering wheel axis. This + * provides better compatibility across platforms and devices as SDL will guess + * the correct axis. + * \sa SDL_HapticDirection + */ +#define SDL_HAPTIC_STEERING_AXIS 3 + /* @} *//* Direction encodings */ /* @} *//* Haptic features */ @@ -444,6 +452,7 @@ typedef struct _SDL_Haptic SDL_Haptic; * \sa SDL_HAPTIC_POLAR * \sa SDL_HAPTIC_CARTESIAN * \sa SDL_HAPTIC_SPHERICAL + * \sa SDL_HAPTIC_STEERING_AXIS * \sa SDL_HapticEffect * \sa SDL_HapticNumAxes */ @@ -811,419 +820,513 @@ typedef union SDL_HapticEffect /* Function prototypes */ + /** - * \brief Count the number of haptic devices attached to the system. + * Count the number of haptic devices attached to the system. * - * \return Number of haptic devices detected on the system. + * \returns the number of haptic devices detected on the system or a negative + * error code on failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticName */ extern DECLSPEC int SDLCALL SDL_NumHaptics(void); /** - * \brief Get the implementation dependent name of a haptic device. + * Get the implementation dependent name of a haptic device. * - * This can be called before any joysticks are opened. - * If no name can be found, this function returns NULL. + * This can be called before any joysticks are opened. If no name can be + * found, this function returns NULL. * - * \param device_index Index of the device to get its name. - * \return Name of the device or NULL on error. + * \param device_index index of the device to query. + * \returns the name of the device or NULL on failure; call SDL_GetError() for + * more information. * - * \sa SDL_NumHaptics + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_NumHaptics */ extern DECLSPEC const char *SDLCALL SDL_HapticName(int device_index); /** - * \brief Opens a haptic device for use. + * Open a haptic device for use. * - * The index passed as an argument refers to the N'th haptic device on this - * system. + * The index passed as an argument refers to the N'th haptic device on this + * system. * - * When opening a haptic device, its gain will be set to maximum and - * autocenter will be disabled. To modify these values use - * SDL_HapticSetGain() and SDL_HapticSetAutocenter(). + * When opening a haptic device, its gain will be set to maximum and + * autocenter will be disabled. To modify these values use SDL_HapticSetGain() + * and SDL_HapticSetAutocenter(). * - * \param device_index Index of the device to open. - * \return Device identifier or NULL on error. + * \param device_index index of the device to open + * \returns the device identifier or NULL on failure; call SDL_GetError() for + * more information. * - * \sa SDL_HapticIndex - * \sa SDL_HapticOpenFromMouse - * \sa SDL_HapticOpenFromJoystick - * \sa SDL_HapticClose - * \sa SDL_HapticSetGain - * \sa SDL_HapticSetAutocenter - * \sa SDL_HapticPause - * \sa SDL_HapticStopAll + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticClose + * \sa SDL_HapticIndex + * \sa SDL_HapticOpenFromJoystick + * \sa SDL_HapticOpenFromMouse + * \sa SDL_HapticPause + * \sa SDL_HapticSetAutocenter + * \sa SDL_HapticSetGain + * \sa SDL_HapticStopAll */ extern DECLSPEC SDL_Haptic *SDLCALL SDL_HapticOpen(int device_index); /** - * \brief Checks if the haptic device at index has been opened. + * Check if the haptic device at the designated index has been opened. * - * \param device_index Index to check to see if it has been opened. - * \return 1 if it has been opened or 0 if it hasn't. + * \param device_index the index of the device to query + * \returns 1 if it has been opened, 0 if it hasn't or on failure; call + * SDL_GetError() for more information. * - * \sa SDL_HapticOpen - * \sa SDL_HapticIndex + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticIndex + * \sa SDL_HapticOpen */ extern DECLSPEC int SDLCALL SDL_HapticOpened(int device_index); /** - * \brief Gets the index of a haptic device. + * Get the index of a haptic device. * - * \param haptic Haptic device to get the index of. - * \return The index of the haptic device or -1 on error. + * \param haptic the SDL_Haptic device to query + * \returns the index of the specified haptic device or a negative error code + * on failure; call SDL_GetError() for more information. * - * \sa SDL_HapticOpen - * \sa SDL_HapticOpened + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticOpen + * \sa SDL_HapticOpened */ extern DECLSPEC int SDLCALL SDL_HapticIndex(SDL_Haptic * haptic); /** - * \brief Gets whether or not the current mouse has haptic capabilities. + * Query whether or not the current mouse has haptic capabilities. * - * \return SDL_TRUE if the mouse is haptic, SDL_FALSE if it isn't. + * \returns SDL_TRUE if the mouse is haptic or SDL_FALSE if it isn't. * - * \sa SDL_HapticOpenFromMouse + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticOpenFromMouse */ extern DECLSPEC int SDLCALL SDL_MouseIsHaptic(void); /** - * \brief Tries to open a haptic device from the current mouse. + * Try to open a haptic device from the current mouse. * - * \return The haptic device identifier or NULL on error. + * \returns the haptic device identifier or NULL on failure; call + * SDL_GetError() for more information. * - * \sa SDL_MouseIsHaptic - * \sa SDL_HapticOpen + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticOpen + * \sa SDL_MouseIsHaptic */ extern DECLSPEC SDL_Haptic *SDLCALL SDL_HapticOpenFromMouse(void); /** - * \brief Checks to see if a joystick has haptic features. + * Query if a joystick has haptic features. * - * \param joystick Joystick to test for haptic capabilities. - * \return SDL_TRUE if the joystick is haptic, SDL_FALSE if it isn't - * or -1 if an error occurred. + * \param joystick the SDL_Joystick to test for haptic capabilities + * \returns SDL_TRUE if the joystick is haptic, SDL_FALSE if it isn't, or a + * negative error code on failure; call SDL_GetError() for more + * information. * - * \sa SDL_HapticOpenFromJoystick + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticOpenFromJoystick */ extern DECLSPEC int SDLCALL SDL_JoystickIsHaptic(SDL_Joystick * joystick); /** - * \brief Opens a haptic device for use from a joystick device. + * Open a haptic device for use from a joystick device. * - * You must still close the haptic device separately. It will not be closed - * with the joystick. + * You must still close the haptic device separately. It will not be closed + * with the joystick. * - * When opening from a joystick you should first close the haptic device before - * closing the joystick device. If not, on some implementations the haptic - * device will also get unallocated and you'll be unable to use force feedback - * on that device. + * When opened from a joystick you should first close the haptic device before + * closing the joystick device. If not, on some implementations the haptic + * device will also get unallocated and you'll be unable to use force feedback + * on that device. * - * \param joystick Joystick to create a haptic device from. - * \return A valid haptic device identifier on success or NULL on error. + * \param joystick the SDL_Joystick to create a haptic device from + * \returns a valid haptic device identifier on success or NULL on failure; + * call SDL_GetError() for more information. * - * \sa SDL_HapticOpen - * \sa SDL_HapticClose + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticClose + * \sa SDL_HapticOpen + * \sa SDL_JoystickIsHaptic */ extern DECLSPEC SDL_Haptic *SDLCALL SDL_HapticOpenFromJoystick(SDL_Joystick * joystick); /** - * \brief Closes a haptic device previously opened with SDL_HapticOpen(). + * Close a haptic device previously opened with SDL_HapticOpen(). * - * \param haptic Haptic device to close. + * \param haptic the SDL_Haptic device to close + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticOpen */ extern DECLSPEC void SDLCALL SDL_HapticClose(SDL_Haptic * haptic); /** - * \brief Returns the number of effects a haptic device can store. + * Get the number of effects a haptic device can store. * - * On some platforms this isn't fully supported, and therefore is an - * approximation. Always check to see if your created effect was actually - * created and do not rely solely on SDL_HapticNumEffects(). + * On some platforms this isn't fully supported, and therefore is an + * approximation. Always check to see if your created effect was actually + * created and do not rely solely on SDL_HapticNumEffects(). * - * \param haptic The haptic device to query effect max. - * \return The number of effects the haptic device can store or - * -1 on error. + * \param haptic the SDL_Haptic device to query + * \returns the number of effects the haptic device can store or a negative + * error code on failure; call SDL_GetError() for more information. * - * \sa SDL_HapticNumEffectsPlaying - * \sa SDL_HapticQuery + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticNumEffectsPlaying + * \sa SDL_HapticQuery */ extern DECLSPEC int SDLCALL SDL_HapticNumEffects(SDL_Haptic * haptic); /** - * \brief Returns the number of effects a haptic device can play at the same - * time. + * Get the number of effects a haptic device can play at the same time. * - * This is not supported on all platforms, but will always return a value. - * Added here for the sake of completeness. + * This is not supported on all platforms, but will always return a value. * - * \param haptic The haptic device to query maximum playing effects. - * \return The number of effects the haptic device can play at the same time - * or -1 on error. + * \param haptic the SDL_Haptic device to query maximum playing effects + * \returns the number of effects the haptic device can play at the same time + * or a negative error code on failure; call SDL_GetError() for more + * information. * - * \sa SDL_HapticNumEffects - * \sa SDL_HapticQuery + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticNumEffects + * \sa SDL_HapticQuery */ extern DECLSPEC int SDLCALL SDL_HapticNumEffectsPlaying(SDL_Haptic * haptic); /** - * \brief Gets the haptic device's supported features in bitwise manner. + * Get the haptic device's supported features in bitwise manner. * - * Example: - * \code - * if (SDL_HapticQuery(haptic) & SDL_HAPTIC_CONSTANT) { - * printf("We have constant haptic effect!\n"); - * } - * \endcode + * \param haptic the SDL_Haptic device to query + * \returns a list of supported haptic features in bitwise manner (OR'd), or 0 + * on failure; call SDL_GetError() for more information. * - * \param haptic The haptic device to query. - * \return Haptic features in bitwise manner (OR'd). + * \since This function is available since SDL 2.0.0. * - * \sa SDL_HapticNumEffects - * \sa SDL_HapticEffectSupported + * \sa SDL_HapticEffectSupported + * \sa SDL_HapticNumEffects */ extern DECLSPEC unsigned int SDLCALL SDL_HapticQuery(SDL_Haptic * haptic); /** - * \brief Gets the number of haptic axes the device has. + * Get the number of haptic axes the device has. * - * \sa SDL_HapticDirection + * The number of haptic axes might be useful if working with the + * SDL_HapticDirection effect. + * + * \param haptic the SDL_Haptic device to query + * \returns the number of axes on success or a negative error code on failure; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. */ extern DECLSPEC int SDLCALL SDL_HapticNumAxes(SDL_Haptic * haptic); /** - * \brief Checks to see if effect is supported by haptic. + * Check to see if an effect is supported by a haptic device. * - * \param haptic Haptic device to check on. - * \param effect Effect to check to see if it is supported. - * \return SDL_TRUE if effect is supported, SDL_FALSE if it isn't or -1 on error. + * \param haptic the SDL_Haptic device to query + * \param effect the desired effect to query + * \returns SDL_TRUE if effect is supported, SDL_FALSE if it isn't, or a + * negative error code on failure; call SDL_GetError() for more + * information. * - * \sa SDL_HapticQuery - * \sa SDL_HapticNewEffect + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticNewEffect + * \sa SDL_HapticQuery */ extern DECLSPEC int SDLCALL SDL_HapticEffectSupported(SDL_Haptic * haptic, SDL_HapticEffect * effect); /** - * \brief Creates a new haptic effect on the device. + * Create a new haptic effect on a specified device. * - * \param haptic Haptic device to create the effect on. - * \param effect Properties of the effect to create. - * \return The identifier of the effect on success or -1 on error. + * \param haptic an SDL_Haptic device to create the effect on + * \param effect an SDL_HapticEffect structure containing the properties of + * the effect to create + * \returns the ID of the effect on success or a negative error code on + * failure; call SDL_GetError() for more information. * - * \sa SDL_HapticUpdateEffect - * \sa SDL_HapticRunEffect - * \sa SDL_HapticDestroyEffect + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticDestroyEffect + * \sa SDL_HapticRunEffect + * \sa SDL_HapticUpdateEffect */ extern DECLSPEC int SDLCALL SDL_HapticNewEffect(SDL_Haptic * haptic, SDL_HapticEffect * effect); /** - * \brief Updates the properties of an effect. + * Update the properties of an effect. * - * Can be used dynamically, although behavior when dynamically changing - * direction may be strange. Specifically the effect may reupload itself - * and start playing from the start. You cannot change the type either when - * running SDL_HapticUpdateEffect(). + * Can be used dynamically, although behavior when dynamically changing + * direction may be strange. Specifically the effect may re-upload itself and + * start playing from the start. You also cannot change the type either when + * running SDL_HapticUpdateEffect(). * - * \param haptic Haptic device that has the effect. - * \param effect Identifier of the effect to update. - * \param data New effect properties to use. - * \return 0 on success or -1 on error. + * \param haptic the SDL_Haptic device that has the effect + * \param effect the identifier of the effect to update + * \param data an SDL_HapticEffect structure containing the new effect + * properties to use + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. * - * \sa SDL_HapticNewEffect - * \sa SDL_HapticRunEffect - * \sa SDL_HapticDestroyEffect + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticDestroyEffect + * \sa SDL_HapticNewEffect + * \sa SDL_HapticRunEffect */ extern DECLSPEC int SDLCALL SDL_HapticUpdateEffect(SDL_Haptic * haptic, int effect, SDL_HapticEffect * data); /** - * \brief Runs the haptic effect on its associated haptic device. + * Run the haptic effect on its associated haptic device. * - * If iterations are ::SDL_HAPTIC_INFINITY, it'll run the effect over and over - * repeating the envelope (attack and fade) every time. If you only want the - * effect to last forever, set ::SDL_HAPTIC_INFINITY in the effect's length - * parameter. + * To repeat the effect over and over indefinitely, set `iterations` to + * `SDL_HAPTIC_INFINITY`. (Repeats the envelope - attack and fade.) To make + * one instance of the effect last indefinitely (so the effect does not fade), + * set the effect's `length` in its structure/union to `SDL_HAPTIC_INFINITY` + * instead. * - * \param haptic Haptic device to run the effect on. - * \param effect Identifier of the haptic effect to run. - * \param iterations Number of iterations to run the effect. Use - * ::SDL_HAPTIC_INFINITY for infinity. - * \return 0 on success or -1 on error. + * \param haptic the SDL_Haptic device to run the effect on + * \param effect the ID of the haptic effect to run + * \param iterations the number of iterations to run the effect; use + * `SDL_HAPTIC_INFINITY` to repeat forever + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. * - * \sa SDL_HapticStopEffect - * \sa SDL_HapticDestroyEffect - * \sa SDL_HapticGetEffectStatus + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticDestroyEffect + * \sa SDL_HapticGetEffectStatus + * \sa SDL_HapticStopEffect */ extern DECLSPEC int SDLCALL SDL_HapticRunEffect(SDL_Haptic * haptic, int effect, Uint32 iterations); /** - * \brief Stops the haptic effect on its associated haptic device. + * Stop the haptic effect on its associated haptic device. * - * \param haptic Haptic device to stop the effect on. - * \param effect Identifier of the effect to stop. - * \return 0 on success or -1 on error. + * * * - * \sa SDL_HapticRunEffect - * \sa SDL_HapticDestroyEffect + * \param haptic the SDL_Haptic device to stop the effect on + * \param effect the ID of the haptic effect to stop + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticDestroyEffect + * \sa SDL_HapticRunEffect */ extern DECLSPEC int SDLCALL SDL_HapticStopEffect(SDL_Haptic * haptic, int effect); /** - * \brief Destroys a haptic effect on the device. + * Destroy a haptic effect on the device. * - * This will stop the effect if it's running. Effects are automatically - * destroyed when the device is closed. + * This will stop the effect if it's running. Effects are automatically + * destroyed when the device is closed. * - * \param haptic Device to destroy the effect on. - * \param effect Identifier of the effect to destroy. + * \param haptic the SDL_Haptic device to destroy the effect on + * \param effect the ID of the haptic effect to destroy * - * \sa SDL_HapticNewEffect + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticNewEffect */ extern DECLSPEC void SDLCALL SDL_HapticDestroyEffect(SDL_Haptic * haptic, int effect); /** - * \brief Gets the status of the current effect on the haptic device. + * Get the status of the current effect on the specified haptic device. * - * Device must support the ::SDL_HAPTIC_STATUS feature. + * Device must support the SDL_HAPTIC_STATUS feature. * - * \param haptic Haptic device to query the effect status on. - * \param effect Identifier of the effect to query its status. - * \return 0 if it isn't playing, 1 if it is playing or -1 on error. + * \param haptic the SDL_Haptic device to query for the effect status on + * \param effect the ID of the haptic effect to query its status + * \returns 0 if it isn't playing, 1 if it is playing, or a negative error + * code on failure; call SDL_GetError() for more information. * - * \sa SDL_HapticRunEffect - * \sa SDL_HapticStopEffect + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticRunEffect + * \sa SDL_HapticStopEffect */ extern DECLSPEC int SDLCALL SDL_HapticGetEffectStatus(SDL_Haptic * haptic, int effect); /** - * \brief Sets the global gain of the device. + * Set the global gain of the specified haptic device. * - * Device must support the ::SDL_HAPTIC_GAIN feature. + * Device must support the SDL_HAPTIC_GAIN feature. * - * The user may specify the maximum gain by setting the environment variable - * SDL_HAPTIC_GAIN_MAX which should be between 0 and 100. All calls to - * SDL_HapticSetGain() will scale linearly using SDL_HAPTIC_GAIN_MAX as the - * maximum. + * The user may specify the maximum gain by setting the environment variable + * `SDL_HAPTIC_GAIN_MAX` which should be between 0 and 100. All calls to + * SDL_HapticSetGain() will scale linearly using `SDL_HAPTIC_GAIN_MAX` as the + * maximum. * - * \param haptic Haptic device to set the gain on. - * \param gain Value to set the gain to, should be between 0 and 100. - * \return 0 on success or -1 on error. + * \param haptic the SDL_Haptic device to set the gain on + * \param gain value to set the gain to, should be between 0 and 100 (0 - 100) + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. * - * \sa SDL_HapticQuery + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticQuery */ extern DECLSPEC int SDLCALL SDL_HapticSetGain(SDL_Haptic * haptic, int gain); /** - * \brief Sets the global autocenter of the device. + * Set the global autocenter of the device. * - * Autocenter should be between 0 and 100. Setting it to 0 will disable - * autocentering. + * Autocenter should be between 0 and 100. Setting it to 0 will disable + * autocentering. * - * Device must support the ::SDL_HAPTIC_AUTOCENTER feature. + * Device must support the SDL_HAPTIC_AUTOCENTER feature. * - * \param haptic Haptic device to set autocentering on. - * \param autocenter Value to set autocenter to, 0 disables autocentering. - * \return 0 on success or -1 on error. + * \param haptic the SDL_Haptic device to set autocentering on + * \param autocenter value to set autocenter to (0-100) + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. * - * \sa SDL_HapticQuery + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticQuery */ extern DECLSPEC int SDLCALL SDL_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter); /** - * \brief Pauses a haptic device. + * Pause a haptic device. * - * Device must support the ::SDL_HAPTIC_PAUSE feature. Call - * SDL_HapticUnpause() to resume playback. + * Device must support the `SDL_HAPTIC_PAUSE` feature. Call + * SDL_HapticUnpause() to resume playback. * - * Do not modify the effects nor add new ones while the device is paused. - * That can cause all sorts of weird errors. + * Do not modify the effects nor add new ones while the device is paused. That + * can cause all sorts of weird errors. * - * \param haptic Haptic device to pause. - * \return 0 on success or -1 on error. + * \param haptic the SDL_Haptic device to pause + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. * - * \sa SDL_HapticUnpause + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticUnpause */ extern DECLSPEC int SDLCALL SDL_HapticPause(SDL_Haptic * haptic); /** - * \brief Unpauses a haptic device. + * Unpause a haptic device. * - * Call to unpause after SDL_HapticPause(). + * Call to unpause after SDL_HapticPause(). * - * \param haptic Haptic device to unpause. - * \return 0 on success or -1 on error. + * \param haptic the SDL_Haptic device to unpause + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. * - * \sa SDL_HapticPause + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticPause */ extern DECLSPEC int SDLCALL SDL_HapticUnpause(SDL_Haptic * haptic); /** - * \brief Stops all the currently playing effects on a haptic device. + * Stop all the currently playing effects on a haptic device. * - * \param haptic Haptic device to stop. - * \return 0 on success or -1 on error. + * \param haptic the SDL_Haptic device to stop + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. */ extern DECLSPEC int SDLCALL SDL_HapticStopAll(SDL_Haptic * haptic); /** - * \brief Checks to see if rumble is supported on a haptic device. + * Check whether rumble is supported on a haptic device. * - * \param haptic Haptic device to check to see if it supports rumble. - * \return SDL_TRUE if effect is supported, SDL_FALSE if it isn't or -1 on error. + * \param haptic haptic device to check for rumble support + * \returns SDL_TRUE if effect is supported, SDL_FALSE if it isn't, or a + * negative error code on failure; call SDL_GetError() for more + * information. * - * \sa SDL_HapticRumbleInit - * \sa SDL_HapticRumblePlay - * \sa SDL_HapticRumbleStop + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticRumbleInit + * \sa SDL_HapticRumblePlay + * \sa SDL_HapticRumbleStop */ extern DECLSPEC int SDLCALL SDL_HapticRumbleSupported(SDL_Haptic * haptic); /** - * \brief Initializes the haptic device for simple rumble playback. + * Initialize a haptic device for simple rumble playback. * - * \param haptic Haptic device to initialize for simple rumble playback. - * \return 0 on success or -1 on error. + * \param haptic the haptic device to initialize for simple rumble playback + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. * - * \sa SDL_HapticOpen - * \sa SDL_HapticRumbleSupported - * \sa SDL_HapticRumblePlay - * \sa SDL_HapticRumbleStop + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticOpen + * \sa SDL_HapticRumblePlay + * \sa SDL_HapticRumbleStop + * \sa SDL_HapticRumbleSupported */ extern DECLSPEC int SDLCALL SDL_HapticRumbleInit(SDL_Haptic * haptic); /** - * \brief Runs simple rumble on a haptic device + * Run a simple rumble effect on a haptic device. * - * \param haptic Haptic device to play rumble effect on. - * \param strength Strength of the rumble to play as a 0-1 float value. - * \param length Length of the rumble to play in milliseconds. - * \return 0 on success or -1 on error. + * \param haptic the haptic device to play the rumble effect on + * \param strength strength of the rumble to play as a 0-1 float value + * \param length length of the rumble to play in milliseconds + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. * - * \sa SDL_HapticRumbleSupported - * \sa SDL_HapticRumbleInit - * \sa SDL_HapticRumbleStop + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticRumbleInit + * \sa SDL_HapticRumbleStop + * \sa SDL_HapticRumbleSupported */ extern DECLSPEC int SDLCALL SDL_HapticRumblePlay(SDL_Haptic * haptic, float strength, Uint32 length ); /** - * \brief Stops the simple rumble on a haptic device. + * Stop the simple rumble on a haptic device. * - * \param haptic Haptic to stop the rumble on. - * \return 0 on success or -1 on error. + * \param haptic the haptic device to stop the rumble effect on + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. * - * \sa SDL_HapticRumbleSupported - * \sa SDL_HapticRumbleInit - * \sa SDL_HapticRumblePlay + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HapticRumbleInit + * \sa SDL_HapticRumblePlay + * \sa SDL_HapticRumbleSupported */ extern DECLSPEC int SDLCALL SDL_HapticRumbleStop(SDL_Haptic * haptic); diff --git a/SDL2-2.30.5/include/SDL_hidapi.h b/SDL2-2.30.5/include/SDL_hidapi.h new file mode 100644 index 0000000..b9d8ffa --- /dev/null +++ b/SDL2-2.30.5/include/SDL_hidapi.h @@ -0,0 +1,451 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_hidapi.h + * + * Header file for SDL HIDAPI functions. + * + * This is an adaptation of the original HIDAPI interface by Alan Ott, + * and includes source code licensed under the following BSD license: + * + Copyright (c) 2010, Alan Ott, Signal 11 Software + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of Signal 11 Software nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + * + * If you would like a version of SDL without this code, you can build SDL + * with SDL_HIDAPI_DISABLED defined to 1. You might want to do this for example + * on iOS or tvOS to avoid a dependency on the CoreBluetooth framework. + */ + +#ifndef SDL_hidapi_h_ +#define SDL_hidapi_h_ + +#include "SDL_stdinc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief A handle representing an open HID device + */ +struct SDL_hid_device_; +typedef struct SDL_hid_device_ SDL_hid_device; /**< opaque hidapi structure */ + +/** hidapi info structure */ +/** + * \brief Information about a connected HID device + */ +typedef struct SDL_hid_device_info +{ + /** Platform-specific device path */ + char *path; + /** Device Vendor ID */ + unsigned short vendor_id; + /** Device Product ID */ + unsigned short product_id; + /** Serial Number */ + wchar_t *serial_number; + /** Device Release Number in binary-coded decimal, + also known as Device Version Number */ + unsigned short release_number; + /** Manufacturer String */ + wchar_t *manufacturer_string; + /** Product string */ + wchar_t *product_string; + /** Usage Page for this Device/Interface + (Windows/Mac only). */ + unsigned short usage_page; + /** Usage for this Device/Interface + (Windows/Mac only).*/ + unsigned short usage; + /** The USB interface which this logical device + represents. + + * Valid on both Linux implementations in all cases. + * Valid on the Windows implementation only if the device + contains more than one interface. */ + int interface_number; + + /** Additional information about the USB interface. + Valid on libusb and Android implementations. */ + int interface_class; + int interface_subclass; + int interface_protocol; + + /** Pointer to the next device */ + struct SDL_hid_device_info *next; +} SDL_hid_device_info; + + +/** + * Initialize the HIDAPI library. + * + * This function initializes the HIDAPI library. Calling it is not strictly + * necessary, as it will be called automatically by SDL_hid_enumerate() and + * any of the SDL_hid_open_*() functions if it is needed. This function should + * be called at the beginning of execution however, if there is a chance of + * HIDAPI handles being opened by different threads simultaneously. + * + * Each call to this function should have a matching call to SDL_hid_exit() + * + * \returns 0 on success and -1 on error. + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_hid_exit + */ +extern DECLSPEC int SDLCALL SDL_hid_init(void); + +/** + * Finalize the HIDAPI library. + * + * This function frees all of the static data associated with HIDAPI. It + * should be called at the end of execution to avoid memory leaks. + * + * \returns 0 on success and -1 on error. + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_hid_init + */ +extern DECLSPEC int SDLCALL SDL_hid_exit(void); + +/** + * Check to see if devices may have been added or removed. + * + * Enumerating the HID devices is an expensive operation, so you can call this + * to see if there have been any system device changes since the last call to + * this function. A change in the counter returned doesn't necessarily mean + * that anything has changed, but you can call SDL_hid_enumerate() to get an + * updated device list. + * + * Calling this function for the first time may cause a thread or other system + * resource to be allocated to track device change notifications. + * + * \returns a change counter that is incremented with each potential device + * change, or 0 if device change detection isn't available. + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_hid_enumerate + */ +extern DECLSPEC Uint32 SDLCALL SDL_hid_device_change_count(void); + +/** + * Enumerate the HID Devices. + * + * This function returns a linked list of all the HID devices attached to the + * system which match vendor_id and product_id. If `vendor_id` is set to 0 + * then any vendor matches. If `product_id` is set to 0 then any product + * matches. If `vendor_id` and `product_id` are both set to 0, then all HID + * devices will be returned. + * + * \param vendor_id The Vendor ID (VID) of the types of device to open. + * \param product_id The Product ID (PID) of the types of device to open. + * \returns a pointer to a linked list of type SDL_hid_device_info, containing + * information about the HID devices attached to the system, or NULL + * in the case of failure. Free this linked list by calling + * SDL_hid_free_enumeration(). + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_hid_device_change_count + */ +extern DECLSPEC SDL_hid_device_info * SDLCALL SDL_hid_enumerate(unsigned short vendor_id, unsigned short product_id); + +/** + * Free an enumeration Linked List + * + * This function frees a linked list created by SDL_hid_enumerate(). + * + * \param devs Pointer to a list of struct_device returned from + * SDL_hid_enumerate(). + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC void SDLCALL SDL_hid_free_enumeration(SDL_hid_device_info *devs); + +/** + * Open a HID device using a Vendor ID (VID), Product ID (PID) and optionally + * a serial number. + * + * If `serial_number` is NULL, the first device with the specified VID and PID + * is opened. + * + * \param vendor_id The Vendor ID (VID) of the device to open. + * \param product_id The Product ID (PID) of the device to open. + * \param serial_number The Serial Number of the device to open (Optionally + * NULL). + * \returns a pointer to a SDL_hid_device object on success or NULL on + * failure. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC SDL_hid_device * SDLCALL SDL_hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number); + +/** + * Open a HID device by its path name. + * + * The path name be determined by calling SDL_hid_enumerate(), or a + * platform-specific path name can be used (eg: /dev/hidraw0 on Linux). + * + * \param path The path name of the device to open + * \returns a pointer to a SDL_hid_device object on success or NULL on + * failure. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC SDL_hid_device * SDLCALL SDL_hid_open_path(const char *path, int bExclusive /* = false */); + +/** + * Write an Output report to a HID device. + * + * The first byte of `data` must contain the Report ID. For devices which only + * support a single report, this must be set to 0x0. The remaining bytes + * contain the report data. Since the Report ID is mandatory, calls to + * SDL_hid_write() will always contain one more byte than the report contains. + * For example, if a hid report is 16 bytes long, 17 bytes must be passed to + * SDL_hid_write(), the Report ID (or 0x0, for devices with a single report), + * followed by the report data (16 bytes). In this example, the length passed + * in would be 17. + * + * SDL_hid_write() will send the data on the first OUT endpoint, if one + * exists. If it does not, it will send the data through the Control Endpoint + * (Endpoint 0). + * + * \param dev A device handle returned from SDL_hid_open(). + * \param data The data to send, including the report number as the first + * byte. + * \param length The length in bytes of the data to send. + * \returns the actual number of bytes written and -1 on error. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC int SDLCALL SDL_hid_write(SDL_hid_device *dev, const unsigned char *data, size_t length); + +/** + * Read an Input report from a HID device with timeout. + * + * Input reports are returned to the host through the INTERRUPT IN endpoint. + * The first byte will contain the Report number if the device uses numbered + * reports. + * + * \param dev A device handle returned from SDL_hid_open(). + * \param data A buffer to put the read data into. + * \param length The number of bytes to read. For devices with multiple + * reports, make sure to read an extra byte for the report + * number. + * \param milliseconds timeout in milliseconds or -1 for blocking wait. + * \returns the actual number of bytes read and -1 on error. If no packet was + * available to be read within the timeout period, this function + * returns 0. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC int SDLCALL SDL_hid_read_timeout(SDL_hid_device *dev, unsigned char *data, size_t length, int milliseconds); + +/** + * Read an Input report from a HID device. + * + * Input reports are returned to the host through the INTERRUPT IN endpoint. + * The first byte will contain the Report number if the device uses numbered + * reports. + * + * \param dev A device handle returned from SDL_hid_open(). + * \param data A buffer to put the read data into. + * \param length The number of bytes to read. For devices with multiple + * reports, make sure to read an extra byte for the report + * number. + * \returns the actual number of bytes read and -1 on error. If no packet was + * available to be read and the handle is in non-blocking mode, this + * function returns 0. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC int SDLCALL SDL_hid_read(SDL_hid_device *dev, unsigned char *data, size_t length); + +/** + * Set the device handle to be non-blocking. + * + * In non-blocking mode calls to SDL_hid_read() will return immediately with a + * value of 0 if there is no data to be read. In blocking mode, SDL_hid_read() + * will wait (block) until there is data to read before returning. + * + * Nonblocking can be turned on and off at any time. + * + * \param dev A device handle returned from SDL_hid_open(). + * \param nonblock enable or not the nonblocking reads - 1 to enable + * nonblocking - 0 to disable nonblocking. + * \returns 0 on success and -1 on error. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC int SDLCALL SDL_hid_set_nonblocking(SDL_hid_device *dev, int nonblock); + +/** + * Send a Feature report to the device. + * + * Feature reports are sent over the Control endpoint as a Set_Report + * transfer. The first byte of `data` must contain the Report ID. For devices + * which only support a single report, this must be set to 0x0. The remaining + * bytes contain the report data. Since the Report ID is mandatory, calls to + * SDL_hid_send_feature_report() will always contain one more byte than the + * report contains. For example, if a hid report is 16 bytes long, 17 bytes + * must be passed to SDL_hid_send_feature_report(): the Report ID (or 0x0, for + * devices which do not use numbered reports), followed by the report data (16 + * bytes). In this example, the length passed in would be 17. + * + * \param dev A device handle returned from SDL_hid_open(). + * \param data The data to send, including the report number as the first + * byte. + * \param length The length in bytes of the data to send, including the report + * number. + * \returns the actual number of bytes written and -1 on error. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC int SDLCALL SDL_hid_send_feature_report(SDL_hid_device *dev, const unsigned char *data, size_t length); + +/** + * Get a feature report from a HID device. + * + * Set the first byte of `data` to the Report ID of the report to be read. + * Make sure to allow space for this extra byte in `data`. Upon return, the + * first byte will still contain the Report ID, and the report data will start + * in data[1]. + * + * \param dev A device handle returned from SDL_hid_open(). + * \param data A buffer to put the read data into, including the Report ID. + * Set the first byte of `data` to the Report ID of the report to + * be read, or set it to zero if your device does not use numbered + * reports. + * \param length The number of bytes to read, including an extra byte for the + * report ID. The buffer can be longer than the actual report. + * \returns the number of bytes read plus one for the report ID (which is + * still in the first byte), or -1 on error. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC int SDLCALL SDL_hid_get_feature_report(SDL_hid_device *dev, unsigned char *data, size_t length); + +/** + * Close a HID device. + * + * \param dev A device handle returned from SDL_hid_open(). + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC void SDLCALL SDL_hid_close(SDL_hid_device *dev); + +/** + * Get The Manufacturer String from a HID device. + * + * \param dev A device handle returned from SDL_hid_open(). + * \param string A wide string buffer to put the data into. + * \param maxlen The length of the buffer in multiples of wchar_t. + * \returns 0 on success and -1 on error. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC int SDLCALL SDL_hid_get_manufacturer_string(SDL_hid_device *dev, wchar_t *string, size_t maxlen); + +/** + * Get The Product String from a HID device. + * + * \param dev A device handle returned from SDL_hid_open(). + * \param string A wide string buffer to put the data into. + * \param maxlen The length of the buffer in multiples of wchar_t. + * \returns 0 on success and -1 on error. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC int SDLCALL SDL_hid_get_product_string(SDL_hid_device *dev, wchar_t *string, size_t maxlen); + +/** + * Get The Serial Number String from a HID device. + * + * \param dev A device handle returned from SDL_hid_open(). + * \param string A wide string buffer to put the data into. + * \param maxlen The length of the buffer in multiples of wchar_t. + * \returns 0 on success and -1 on error. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC int SDLCALL SDL_hid_get_serial_number_string(SDL_hid_device *dev, wchar_t *string, size_t maxlen); + +/** + * Get a string from a HID device, based on its string index. + * + * \param dev A device handle returned from SDL_hid_open(). + * \param string_index The index of the string to get. + * \param string A wide string buffer to put the data into. + * \param maxlen The length of the buffer in multiples of wchar_t. + * \returns 0 on success and -1 on error. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC int SDLCALL SDL_hid_get_indexed_string(SDL_hid_device *dev, int string_index, wchar_t *string, size_t maxlen); + +/** + * Start or stop a BLE scan on iOS and tvOS to pair Steam Controllers + * + * \param active SDL_TRUE to start the scan, SDL_FALSE to stop the scan + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC void SDLCALL SDL_hid_ble_scan(SDL_bool active); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_hidapi_h_ */ + +/* vi: set sts=4 ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/include/SDL_hints.h b/SDL2-2.30.5/include/SDL_hints.h new file mode 100644 index 0000000..a26ab60 --- /dev/null +++ b/SDL2-2.30.5/include/SDL_hints.h @@ -0,0 +1,2892 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_hints.h + * + * Official documentation for SDL configuration variables + * + * This file contains functions to set and get configuration hints, + * as well as listing each of them alphabetically. + * + * The convention for naming hints is SDL_HINT_X, where "SDL_X" is + * the environment variable that can be used to override the default. + * + * In general these hints are just that - they may or may not be + * supported or applicable on any given platform, but they provide + * a way for an application or user to give the library a hint as + * to how they would like the library to work. + */ + +#ifndef SDL_hints_h_ +#define SDL_hints_h_ + +#include "SDL_stdinc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief A variable controlling whether the Android / iOS built-in + * accelerometer should be listed as a joystick device. + * + * This variable can be set to the following values: + * "0" - The accelerometer is not listed as a joystick + * "1" - The accelerometer is available as a 3 axis joystick (the default). + */ +#define SDL_HINT_ACCELEROMETER_AS_JOYSTICK "SDL_ACCELEROMETER_AS_JOYSTICK" + +/** + * \brief Specify the behavior of Alt+Tab while the keyboard is grabbed. + * + * By default, SDL emulates Alt+Tab functionality while the keyboard is grabbed + * and your window is full-screen. This prevents the user from getting stuck in + * your application if you've enabled keyboard grab. + * + * The variable can be set to the following values: + * "0" - SDL will not handle Alt+Tab. Your application is responsible + for handling Alt+Tab while the keyboard is grabbed. + * "1" - SDL will minimize your window when Alt+Tab is pressed (default) +*/ +#define SDL_HINT_ALLOW_ALT_TAB_WHILE_GRABBED "SDL_ALLOW_ALT_TAB_WHILE_GRABBED" + +/** + * \brief If set to "0" then never set the top most bit on a SDL Window, even if the video mode expects it. + * This is a debugging aid for developers and not expected to be used by end users. The default is "1" + * + * This variable can be set to the following values: + * "0" - don't allow topmost + * "1" - allow topmost + */ +#define SDL_HINT_ALLOW_TOPMOST "SDL_ALLOW_TOPMOST" + +/** + * \brief Android APK expansion main file version. Should be a string number like "1", "2" etc. + * + * Must be set together with SDL_HINT_ANDROID_APK_EXPANSION_PATCH_FILE_VERSION. + * + * If both hints were set then SDL_RWFromFile() will look into expansion files + * after a given relative path was not found in the internal storage and assets. + * + * By default this hint is not set and the APK expansion files are not searched. + */ +#define SDL_HINT_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION "SDL_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION" + +/** + * \brief Android APK expansion patch file version. Should be a string number like "1", "2" etc. + * + * Must be set together with SDL_HINT_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION. + * + * If both hints were set then SDL_RWFromFile() will look into expansion files + * after a given relative path was not found in the internal storage and assets. + * + * By default this hint is not set and the APK expansion files are not searched. + */ +#define SDL_HINT_ANDROID_APK_EXPANSION_PATCH_FILE_VERSION "SDL_ANDROID_APK_EXPANSION_PATCH_FILE_VERSION" + +/** + * \brief A variable to control whether the event loop will block itself when the app is paused. + * + * The variable can be set to the following values: + * "0" - Non blocking. + * "1" - Blocking. (default) + * + * The value should be set before SDL is initialized. + */ +#define SDL_HINT_ANDROID_BLOCK_ON_PAUSE "SDL_ANDROID_BLOCK_ON_PAUSE" + +/** + * \brief A variable to control whether SDL will pause audio in background + * (Requires SDL_ANDROID_BLOCK_ON_PAUSE as "Non blocking") + * + * The variable can be set to the following values: + * "0" - Non paused. + * "1" - Paused. (default) + * + * The value should be set before SDL is initialized. + */ +#define SDL_HINT_ANDROID_BLOCK_ON_PAUSE_PAUSEAUDIO "SDL_ANDROID_BLOCK_ON_PAUSE_PAUSEAUDIO" + +/** + * \brief A variable to control whether we trap the Android back button to handle it manually. + * This is necessary for the right mouse button to work on some Android devices, or + * to be able to trap the back button for use in your code reliably. If set to true, + * the back button will show up as an SDL_KEYDOWN / SDL_KEYUP pair with a keycode of + * SDL_SCANCODE_AC_BACK. + * + * The variable can be set to the following values: + * "0" - Back button will be handled as usual for system. (default) + * "1" - Back button will be trapped, allowing you to handle the key press + * manually. (This will also let right mouse click work on systems + * where the right mouse button functions as back.) + * + * The value of this hint is used at runtime, so it can be changed at any time. + */ +#define SDL_HINT_ANDROID_TRAP_BACK_BUTTON "SDL_ANDROID_TRAP_BACK_BUTTON" + +/** + * \brief Specify an application name. + * + * This hint lets you specify the application name sent to the OS when + * required. For example, this will often appear in volume control applets for + * audio streams, and in lists of applications which are inhibiting the + * screensaver. You should use a string that describes your program ("My Game + * 2: The Revenge") + * + * Setting this to "" or leaving it unset will have SDL use a reasonable + * default: probably the application's name or "SDL Application" if SDL + * doesn't have any better information. + * + * Note that, for audio streams, this can be overridden with + * SDL_HINT_AUDIO_DEVICE_APP_NAME. + * + * On targets where this is not supported, this hint does nothing. + */ +#define SDL_HINT_APP_NAME "SDL_APP_NAME" + +/** + * \brief A variable controlling whether controllers used with the Apple TV + * generate UI events. + * + * When UI events are generated by controller input, the app will be + * backgrounded when the Apple TV remote's menu button is pressed, and when the + * pause or B buttons on gamepads are pressed. + * + * More information about properly making use of controllers for the Apple TV + * can be found here: + * https://developer.apple.com/tvos/human-interface-guidelines/remote-and-controllers/ + * + * This variable can be set to the following values: + * "0" - Controller input does not generate UI events (the default). + * "1" - Controller input generates UI events. + */ +#define SDL_HINT_APPLE_TV_CONTROLLER_UI_EVENTS "SDL_APPLE_TV_CONTROLLER_UI_EVENTS" + +/** + * \brief A variable controlling whether the Apple TV remote's joystick axes + * will automatically match the rotation of the remote. + * + * This variable can be set to the following values: + * "0" - Remote orientation does not affect joystick axes (the default). + * "1" - Joystick axes are based on the orientation of the remote. + */ +#define SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION "SDL_APPLE_TV_REMOTE_ALLOW_ROTATION" + +/** + * \brief A variable controlling the audio category on iOS and Mac OS X + * + * This variable can be set to the following values: + * + * "ambient" - Use the AVAudioSessionCategoryAmbient audio category, will be muted by the phone mute switch (default) + * "playback" - Use the AVAudioSessionCategoryPlayback category + * + * For more information, see Apple's documentation: + * https://developer.apple.com/library/content/documentation/Audio/Conceptual/AudioSessionProgrammingGuide/AudioSessionCategoriesandModes/AudioSessionCategoriesandModes.html + */ +#define SDL_HINT_AUDIO_CATEGORY "SDL_AUDIO_CATEGORY" + +/** + * \brief Specify an application name for an audio device. + * + * Some audio backends (such as PulseAudio) allow you to describe your audio + * stream. Among other things, this description might show up in a system + * control panel that lets the user adjust the volume on specific audio + * streams instead of using one giant master volume slider. + * + * This hints lets you transmit that information to the OS. The contents of + * this hint are used while opening an audio device. You should use a string + * that describes your program ("My Game 2: The Revenge") + * + * Setting this to "" or leaving it unset will have SDL use a reasonable + * default: this will be the name set with SDL_HINT_APP_NAME, if that hint is + * set. Otherwise, it'll probably the application's name or "SDL Application" + * if SDL doesn't have any better information. + * + * On targets where this is not supported, this hint does nothing. + */ +#define SDL_HINT_AUDIO_DEVICE_APP_NAME "SDL_AUDIO_DEVICE_APP_NAME" + +/** + * \brief Specify an application name for an audio device. + * + * Some audio backends (such as PulseAudio) allow you to describe your audio + * stream. Among other things, this description might show up in a system + * control panel that lets the user adjust the volume on specific audio + * streams instead of using one giant master volume slider. + * + * This hints lets you transmit that information to the OS. The contents of + * this hint are used while opening an audio device. You should use a string + * that describes your what your program is playing ("audio stream" is + * probably sufficient in many cases, but this could be useful for something + * like "team chat" if you have a headset playing VoIP audio separately). + * + * Setting this to "" or leaving it unset will have SDL use a reasonable + * default: "audio stream" or something similar. + * + * On targets where this is not supported, this hint does nothing. + */ +#define SDL_HINT_AUDIO_DEVICE_STREAM_NAME "SDL_AUDIO_DEVICE_STREAM_NAME" + +/** + * \brief Specify an application role for an audio device. + * + * Some audio backends (such as Pipewire) allow you to describe the role of + * your audio stream. Among other things, this description might show up in + * a system control panel or software for displaying and manipulating media + * playback/capture graphs. + * + * This hints lets you transmit that information to the OS. The contents of + * this hint are used while opening an audio device. You should use a string + * that describes your what your program is playing (Game, Music, Movie, + * etc...). + * + * Setting this to "" or leaving it unset will have SDL use a reasonable + * default: "Game" or something similar. + * + * On targets where this is not supported, this hint does nothing. + */ +#define SDL_HINT_AUDIO_DEVICE_STREAM_ROLE "SDL_AUDIO_DEVICE_STREAM_ROLE" + +/** + * \brief A variable controlling speed/quality tradeoff of audio resampling. + * + * If available, SDL can use libsamplerate ( http://www.mega-nerd.com/SRC/ ) + * to handle audio resampling. There are different resampling modes available + * that produce different levels of quality, using more CPU. + * + * If this hint isn't specified to a valid setting, or libsamplerate isn't + * available, SDL will use the default, internal resampling algorithm. + * + * As of SDL 2.26, SDL_ConvertAudio() respects this hint when libsamplerate is available. + * + * This hint is currently only checked at audio subsystem initialization. + * + * This variable can be set to the following values: + * + * "0" or "default" - Use SDL's internal resampling (Default when not set - low quality, fast) + * "1" or "fast" - Use fast, slightly higher quality resampling, if available + * "2" or "medium" - Use medium quality resampling, if available + * "3" or "best" - Use high quality resampling, if available + */ +#define SDL_HINT_AUDIO_RESAMPLING_MODE "SDL_AUDIO_RESAMPLING_MODE" + +/** + * \brief A variable controlling whether SDL updates joystick state when getting input events + * + * This variable can be set to the following values: + * + * "0" - You'll call SDL_JoystickUpdate() manually + * "1" - SDL will automatically call SDL_JoystickUpdate() (default) + * + * This hint can be toggled on and off at runtime. + */ +#define SDL_HINT_AUTO_UPDATE_JOYSTICKS "SDL_AUTO_UPDATE_JOYSTICKS" + +/** + * \brief A variable controlling whether SDL updates sensor state when getting input events + * + * This variable can be set to the following values: + * + * "0" - You'll call SDL_SensorUpdate() manually + * "1" - SDL will automatically call SDL_SensorUpdate() (default) + * + * This hint can be toggled on and off at runtime. + */ +#define SDL_HINT_AUTO_UPDATE_SENSORS "SDL_AUTO_UPDATE_SENSORS" + +/** + * \brief Prevent SDL from using version 4 of the bitmap header when saving BMPs. + * + * The bitmap header version 4 is required for proper alpha channel support and + * SDL will use it when required. Should this not be desired, this hint can + * force the use of the 40 byte header version which is supported everywhere. + * + * The variable can be set to the following values: + * "0" - Surfaces with a colorkey or an alpha channel are saved to a + * 32-bit BMP file with an alpha mask. SDL will use the bitmap + * header version 4 and set the alpha mask accordingly. + * "1" - Surfaces with a colorkey or an alpha channel are saved to a + * 32-bit BMP file without an alpha mask. The alpha channel data + * will be in the file, but applications are going to ignore it. + * + * The default value is "0". + */ +#define SDL_HINT_BMP_SAVE_LEGACY_FORMAT "SDL_BMP_SAVE_LEGACY_FORMAT" + +/** + * \brief Override for SDL_GetDisplayUsableBounds() + * + * If set, this hint will override the expected results for + * SDL_GetDisplayUsableBounds() for display index 0. Generally you don't want + * to do this, but this allows an embedded system to request that some of the + * screen be reserved for other uses when paired with a well-behaved + * application. + * + * The contents of this hint must be 4 comma-separated integers, the first + * is the bounds x, then y, width and height, in that order. + */ +#define SDL_HINT_DISPLAY_USABLE_BOUNDS "SDL_DISPLAY_USABLE_BOUNDS" + +/** + * \brief Disable giving back control to the browser automatically + * when running with asyncify + * + * With -s ASYNCIFY, SDL2 calls emscripten_sleep during operations + * such as refreshing the screen or polling events. + * + * This hint only applies to the emscripten platform + * + * The variable can be set to the following values: + * "0" - Disable emscripten_sleep calls (if you give back browser control manually or use asyncify for other purposes) + * "1" - Enable emscripten_sleep calls (the default) + */ +#define SDL_HINT_EMSCRIPTEN_ASYNCIFY "SDL_EMSCRIPTEN_ASYNCIFY" + +/** + * \brief override the binding element for keyboard inputs for Emscripten builds + * + * This hint only applies to the emscripten platform + * + * The variable can be one of + * "#window" - The javascript window object (this is the default) + * "#document" - The javascript document object + * "#screen" - the javascript window.screen object + * "#canvas" - the WebGL canvas element + * any other string without a leading # sign applies to the element on the page with that ID. + */ +#define SDL_HINT_EMSCRIPTEN_KEYBOARD_ELEMENT "SDL_EMSCRIPTEN_KEYBOARD_ELEMENT" + +/** + * \brief A variable that controls whether the on-screen keyboard should be shown when text input is active + * + * The variable can be set to the following values: + * "0" - Do not show the on-screen keyboard + * "1" - Show the on-screen keyboard + * + * The default value is "1". This hint must be set before text input is activated. + */ +#define SDL_HINT_ENABLE_SCREEN_KEYBOARD "SDL_ENABLE_SCREEN_KEYBOARD" + +/** + * \brief A variable that controls whether Steam Controllers should be exposed using the SDL joystick and game controller APIs + * + * The variable can be set to the following values: + * "0" - Do not scan for Steam Controllers + * "1" - Scan for Steam Controllers (the default) + * + * The default value is "1". This hint must be set before initializing the joystick subsystem. + */ +#define SDL_HINT_ENABLE_STEAM_CONTROLLERS "SDL_ENABLE_STEAM_CONTROLLERS" + +/** + * \brief A variable controlling verbosity of the logging of SDL events pushed onto the internal queue. + * + * This variable can be set to the following values, from least to most verbose: + * + * "0" - Don't log any events (default) + * "1" - Log most events (other than the really spammy ones). + * "2" - Include mouse and finger motion events. + * "3" - Include SDL_SysWMEvent events. + * + * This is generally meant to be used to debug SDL itself, but can be useful + * for application developers that need better visibility into what is going + * on in the event queue. Logged events are sent through SDL_Log(), which + * means by default they appear on stdout on most platforms or maybe + * OutputDebugString() on Windows, and can be funneled by the app with + * SDL_LogSetOutputFunction(), etc. + * + * This hint can be toggled on and off at runtime, if you only need to log + * events for a small subset of program execution. + */ +#define SDL_HINT_EVENT_LOGGING "SDL_EVENT_LOGGING" + +/** + * \brief A variable controlling whether raising the window should be done more forcefully + * + * This variable can be set to the following values: + * "0" - No forcing (the default) + * "1" - Extra level of forcing + * + * At present, this is only an issue under MS Windows, which makes it nearly impossible to + * programmatically move a window to the foreground, for "security" reasons. See + * http://stackoverflow.com/a/34414846 for a discussion. + */ +#define SDL_HINT_FORCE_RAISEWINDOW "SDL_HINT_FORCE_RAISEWINDOW" + +/** + * \brief A variable controlling how 3D acceleration is used to accelerate the SDL screen surface. + * + * SDL can try to accelerate the SDL screen surface by using streaming + * textures with a 3D rendering engine. This variable controls whether and + * how this is done. + * + * This variable can be set to the following values: + * "0" - Disable 3D acceleration + * "1" - Enable 3D acceleration, using the default renderer. + * "X" - Enable 3D acceleration, using X where X is one of the valid rendering drivers. (e.g. "direct3d", "opengl", etc.) + * + * By default SDL tries to make a best guess for each platform whether + * to use acceleration or not. + */ +#define SDL_HINT_FRAMEBUFFER_ACCELERATION "SDL_FRAMEBUFFER_ACCELERATION" + +/** + * \brief A variable that lets you manually hint extra gamecontroller db entries. + * + * The variable should be newline delimited rows of gamecontroller config data, see SDL_gamecontroller.h + * + * This hint must be set before calling SDL_Init(SDL_INIT_GAMECONTROLLER) + * You can update mappings after the system is initialized with SDL_GameControllerMappingForGUID() and SDL_GameControllerAddMapping() + */ +#define SDL_HINT_GAMECONTROLLERCONFIG "SDL_GAMECONTROLLERCONFIG" + +/** + * \brief A variable that lets you provide a file with extra gamecontroller db entries. + * + * The file should contain lines of gamecontroller config data, see SDL_gamecontroller.h + * + * This hint must be set before calling SDL_Init(SDL_INIT_GAMECONTROLLER) + * You can update mappings after the system is initialized with SDL_GameControllerMappingForGUID() and SDL_GameControllerAddMapping() + */ +#define SDL_HINT_GAMECONTROLLERCONFIG_FILE "SDL_GAMECONTROLLERCONFIG_FILE" + +/** + * \brief A variable that overrides the automatic controller type detection + * + * The variable should be comma separated entries, in the form: VID/PID=type + * + * The VID and PID should be hexadecimal with exactly 4 digits, e.g. 0x00fd + * + * The type should be one of: + * Xbox360 + * XboxOne + * PS3 + * PS4 + * PS5 + * SwitchPro + * + * This hint affects what driver is used, and must be set before calling SDL_Init(SDL_INIT_GAMECONTROLLER) + */ +#define SDL_HINT_GAMECONTROLLERTYPE "SDL_GAMECONTROLLERTYPE" + +/** + * \brief A variable containing a list of devices to skip when scanning for game controllers. + * + * The format of the string is a comma separated list of USB VID/PID pairs + * in hexadecimal form, e.g. + * + * 0xAAAA/0xBBBB,0xCCCC/0xDDDD + * + * The variable can also take the form of @file, in which case the named + * file will be loaded and interpreted as the value of the variable. + */ +#define SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES "SDL_GAMECONTROLLER_IGNORE_DEVICES" + +/** + * \brief If set, all devices will be skipped when scanning for game controllers except for the ones listed in this variable. + * + * The format of the string is a comma separated list of USB VID/PID pairs + * in hexadecimal form, e.g. + * + * 0xAAAA/0xBBBB,0xCCCC/0xDDDD + * + * The variable can also take the form of @file, in which case the named + * file will be loaded and interpreted as the value of the variable. + */ +#define SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES_EXCEPT "SDL_GAMECONTROLLER_IGNORE_DEVICES_EXCEPT" + +/** + * \brief If set, game controller face buttons report their values according to their labels instead of their positional layout. + * + * For example, on Nintendo Switch controllers, normally you'd get: + * + * (Y) + * (X) (B) + * (A) + * + * but if this hint is set, you'll get: + * + * (X) + * (Y) (A) + * (B) + * + * The variable can be set to the following values: + * "0" - Report the face buttons by position, as though they were on an Xbox controller. + * "1" - Report the face buttons by label instead of position + * + * The default value is "1". This hint may be set at any time. + */ +#define SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS "SDL_GAMECONTROLLER_USE_BUTTON_LABELS" + +/** + * \brief A variable controlling whether grabbing input grabs the keyboard + * + * This variable can be set to the following values: + * "0" - Grab will affect only the mouse + * "1" - Grab will affect mouse and keyboard + * + * By default SDL will not grab the keyboard so system shortcuts still work. + */ +#define SDL_HINT_GRAB_KEYBOARD "SDL_GRAB_KEYBOARD" + +/** + * \brief A variable containing a list of devices to ignore in SDL_hid_enumerate() + * + * For example, to ignore the Shanwan DS3 controller and any Valve controller, you might + * have the string "0x2563/0x0523,0x28de/0x0000" + */ +#define SDL_HINT_HIDAPI_IGNORE_DEVICES "SDL_HIDAPI_IGNORE_DEVICES" + +/** + * \brief A variable controlling whether the idle timer is disabled on iOS. + * + * When an iOS app does not receive touches for some time, the screen is + * dimmed automatically. For games where the accelerometer is the only input + * this is problematic. This functionality can be disabled by setting this + * hint. + * + * As of SDL 2.0.4, SDL_EnableScreenSaver() and SDL_DisableScreenSaver() + * accomplish the same thing on iOS. They should be preferred over this hint. + * + * This variable can be set to the following values: + * "0" - Enable idle timer + * "1" - Disable idle timer + */ +#define SDL_HINT_IDLE_TIMER_DISABLED "SDL_IOS_IDLE_TIMER_DISABLED" + +/** + * \brief A variable to control whether certain IMEs should handle text editing internally instead of sending SDL_TEXTEDITING events. + * + * The variable can be set to the following values: + * "0" - SDL_TEXTEDITING events are sent, and it is the application's + * responsibility to render the text from these events and + * differentiate it somehow from committed text. (default) + * "1" - If supported by the IME then SDL_TEXTEDITING events are not sent, + * and text that is being composed will be rendered in its own UI. + */ +#define SDL_HINT_IME_INTERNAL_EDITING "SDL_IME_INTERNAL_EDITING" + +/** + * \brief A variable to control whether certain IMEs should show native UI components (such as the Candidate List) instead of suppressing them. + * + * The variable can be set to the following values: + * "0" - Native UI components are not display. (default) + * "1" - Native UI components are displayed. + */ +#define SDL_HINT_IME_SHOW_UI "SDL_IME_SHOW_UI" + +/** + * \brief A variable to control if extended IME text support is enabled. + * If enabled then SDL_TextEditingExtEvent will be issued if the text would be truncated otherwise. + * Additionally SDL_TextInputEvent will be dispatched multiple times so that it is not truncated. + * + * The variable can be set to the following values: + * "0" - Legacy behavior. Text can be truncated, no heap allocations. (default) + * "1" - Modern behavior. + */ +#define SDL_HINT_IME_SUPPORT_EXTENDED_TEXT "SDL_IME_SUPPORT_EXTENDED_TEXT" + +/** + * \brief A variable controlling whether the home indicator bar on iPhone X + * should be hidden. + * + * This variable can be set to the following values: + * "0" - The indicator bar is not hidden (default for windowed applications) + * "1" - The indicator bar is hidden and is shown when the screen is touched (useful for movie playback applications) + * "2" - The indicator bar is dim and the first swipe makes it visible and the second swipe performs the "home" action (default for fullscreen applications) + */ +#define SDL_HINT_IOS_HIDE_HOME_INDICATOR "SDL_IOS_HIDE_HOME_INDICATOR" + +/** + * \brief A variable that lets you enable joystick (and gamecontroller) events even when your app is in the background. + * + * The variable can be set to the following values: + * "0" - Disable joystick & gamecontroller input events when the + * application is in the background. + * "1" - Enable joystick & gamecontroller input events when the + * application is in the background. + * + * The default value is "0". This hint may be set at any time. + */ +#define SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS "SDL_JOYSTICK_ALLOW_BACKGROUND_EVENTS" + +/** + * A variable containing a list of arcade stick style controllers. + * + * The format of the string is a comma separated list of USB VID/PID pairs + * in hexadecimal form, e.g. + * + * 0xAAAA/0xBBBB,0xCCCC/0xDDDD + * + * The variable can also take the form of @file, in which case the named + * file will be loaded and interpreted as the value of the variable. + */ +#define SDL_HINT_JOYSTICK_ARCADESTICK_DEVICES "SDL_JOYSTICK_ARCADESTICK_DEVICES" + +/** + * A variable containing a list of devices that are not arcade stick style controllers. This will override SDL_HINT_JOYSTICK_ARCADESTICK_DEVICES and the built in device list. + * + * The format of the string is a comma separated list of USB VID/PID pairs + * in hexadecimal form, e.g. + * + * 0xAAAA/0xBBBB,0xCCCC/0xDDDD + * + * The variable can also take the form of @file, in which case the named + * file will be loaded and interpreted as the value of the variable. + */ +#define SDL_HINT_JOYSTICK_ARCADESTICK_DEVICES_EXCLUDED "SDL_JOYSTICK_ARCADESTICK_DEVICES_EXCLUDED" + +/** + * A variable containing a list of devices that should not be considerd joysticks. + * + * The format of the string is a comma separated list of USB VID/PID pairs + * in hexadecimal form, e.g. + * + * 0xAAAA/0xBBBB,0xCCCC/0xDDDD + * + * The variable can also take the form of @file, in which case the named + * file will be loaded and interpreted as the value of the variable. + */ +#define SDL_HINT_JOYSTICK_BLACKLIST_DEVICES "SDL_JOYSTICK_BLACKLIST_DEVICES" + +/** + * A variable containing a list of devices that should be considered joysticks. This will override SDL_HINT_JOYSTICK_BLACKLIST_DEVICES and the built in device list. + * + * The format of the string is a comma separated list of USB VID/PID pairs + * in hexadecimal form, e.g. + * + * 0xAAAA/0xBBBB,0xCCCC/0xDDDD + * + * The variable can also take the form of @file, in which case the named + * file will be loaded and interpreted as the value of the variable. + */ +#define SDL_HINT_JOYSTICK_BLACKLIST_DEVICES_EXCLUDED "SDL_JOYSTICK_BLACKLIST_DEVICES_EXCLUDED" + +/** + * A variable containing a list of flightstick style controllers. + * + * The format of the string is a comma separated list of USB VID/PID pairs + * in hexadecimal form, e.g. + * + * 0xAAAA/0xBBBB,0xCCCC/0xDDDD + * + * The variable can also take the form of @file, in which case the named + * file will be loaded and interpreted as the value of the variable. + */ +#define SDL_HINT_JOYSTICK_FLIGHTSTICK_DEVICES "SDL_JOYSTICK_FLIGHTSTICK_DEVICES" + +/** + * A variable containing a list of devices that are not flightstick style controllers. This will override SDL_HINT_JOYSTICK_FLIGHTSTICK_DEVICES and the built in device list. + * + * The format of the string is a comma separated list of USB VID/PID pairs + * in hexadecimal form, e.g. + * + * 0xAAAA/0xBBBB,0xCCCC/0xDDDD + * + * The variable can also take the form of @file, in which case the named + * file will be loaded and interpreted as the value of the variable. + */ +#define SDL_HINT_JOYSTICK_FLIGHTSTICK_DEVICES_EXCLUDED "SDL_JOYSTICK_FLIGHTSTICK_DEVICES_EXCLUDED" + +/** + * A variable containing a list of devices known to have a GameCube form factor. + * + * The format of the string is a comma separated list of USB VID/PID pairs + * in hexadecimal form, e.g. + * + * 0xAAAA/0xBBBB,0xCCCC/0xDDDD + * + * The variable can also take the form of @file, in which case the named + * file will be loaded and interpreted as the value of the variable. + */ +#define SDL_HINT_JOYSTICK_GAMECUBE_DEVICES "SDL_JOYSTICK_GAMECUBE_DEVICES" + +/** + * A variable containing a list of devices known not to have a GameCube form factor. This will override SDL_HINT_JOYSTICK_GAMECUBE_DEVICES and the built in device list. + * + * The format of the string is a comma separated list of USB VID/PID pairs + * in hexadecimal form, e.g. + * + * 0xAAAA/0xBBBB,0xCCCC/0xDDDD + * + * The variable can also take the form of @file, in which case the named + * file will be loaded and interpreted as the value of the variable. + */ +#define SDL_HINT_JOYSTICK_GAMECUBE_DEVICES_EXCLUDED "SDL_JOYSTICK_GAMECUBE_DEVICES_EXCLUDED" + +/** + * \brief A variable controlling whether the HIDAPI joystick drivers should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI drivers are not used + * "1" - HIDAPI drivers are used (the default) + * + * This variable is the default for all drivers, but can be overridden by the hints for specific drivers below. + */ +#define SDL_HINT_JOYSTICK_HIDAPI "SDL_JOYSTICK_HIDAPI" + +/** + * \brief A variable controlling whether the HIDAPI driver for Nintendo GameCube controllers should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI driver is not used + * "1" - HIDAPI driver is used + * + * The default is the value of SDL_HINT_JOYSTICK_HIDAPI + */ +#define SDL_HINT_JOYSTICK_HIDAPI_GAMECUBE "SDL_JOYSTICK_HIDAPI_GAMECUBE" + +/** + * \brief A variable controlling whether "low_frequency_rumble" and "high_frequency_rumble" is used to implement + * the GameCube controller's 3 rumble modes, Stop(0), Rumble(1), and StopHard(2) + * this is useful for applications that need full compatibility for things like ADSR envelopes. + * Stop is implemented by setting "low_frequency_rumble" to "0" and "high_frequency_rumble" ">0" + * Rumble is both at any arbitrary value, + * StopHard is implemented by setting both "low_frequency_rumble" and "high_frequency_rumble" to "0" + * + * This variable can be set to the following values: + * "0" - Normal rumble behavior is behavior is used (default) + * "1" - Proper GameCube controller rumble behavior is used + * + */ +#define SDL_HINT_JOYSTICK_GAMECUBE_RUMBLE_BRAKE "SDL_JOYSTICK_GAMECUBE_RUMBLE_BRAKE" + +/** + * \brief A variable controlling whether the HIDAPI driver for Nintendo Switch Joy-Cons should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI driver is not used + * "1" - HIDAPI driver is used + * + * The default is the value of SDL_HINT_JOYSTICK_HIDAPI + */ +#define SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS "SDL_JOYSTICK_HIDAPI_JOY_CONS" + +/** + * \brief A variable controlling whether Nintendo Switch Joy-Con controllers will be combined into a single Pro-like controller when using the HIDAPI driver + * + * This variable can be set to the following values: + * "0" - Left and right Joy-Con controllers will not be combined and each will be a mini-gamepad + * "1" - Left and right Joy-Con controllers will be combined into a single controller (the default) + */ +#define SDL_HINT_JOYSTICK_HIDAPI_COMBINE_JOY_CONS "SDL_JOYSTICK_HIDAPI_COMBINE_JOY_CONS" + +/** + * \brief A variable controlling whether Nintendo Switch Joy-Con controllers will be in vertical mode when using the HIDAPI driver + * + * This variable can be set to the following values: + * "0" - Left and right Joy-Con controllers will not be in vertical mode (the default) + * "1" - Left and right Joy-Con controllers will be in vertical mode + * + * This hint must be set before calling SDL_Init(SDL_INIT_GAMECONTROLLER) + */ +#define SDL_HINT_JOYSTICK_HIDAPI_VERTICAL_JOY_CONS "SDL_JOYSTICK_HIDAPI_VERTICAL_JOY_CONS" + +/** + * \brief A variable controlling whether the HIDAPI driver for Amazon Luna controllers connected via Bluetooth should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI driver is not used + * "1" - HIDAPI driver is used + * + * The default is the value of SDL_HINT_JOYSTICK_HIDAPI + */ +#define SDL_HINT_JOYSTICK_HIDAPI_LUNA "SDL_JOYSTICK_HIDAPI_LUNA" + +/** + * \brief A variable controlling whether the HIDAPI driver for Nintendo Online classic controllers should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI driver is not used + * "1" - HIDAPI driver is used + * + * The default is the value of SDL_HINT_JOYSTICK_HIDAPI + */ +#define SDL_HINT_JOYSTICK_HIDAPI_NINTENDO_CLASSIC "SDL_JOYSTICK_HIDAPI_NINTENDO_CLASSIC" + +/** + * \brief A variable controlling whether the HIDAPI driver for NVIDIA SHIELD controllers should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI driver is not used + * "1" - HIDAPI driver is used + * + * The default is the value of SDL_HINT_JOYSTICK_HIDAPI + */ +#define SDL_HINT_JOYSTICK_HIDAPI_SHIELD "SDL_JOYSTICK_HIDAPI_SHIELD" + +/** + * \brief A variable controlling whether the HIDAPI driver for PS3 controllers should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI driver is not used + * "1" - HIDAPI driver is used + * + * The default is the value of SDL_HINT_JOYSTICK_HIDAPI on macOS, and "0" on other platforms. + * + * It is not possible to use this driver on Windows, due to limitations in the default drivers + * installed. See https://github.com/ViGEm/DsHidMini for an alternative driver on Windows. + */ +#define SDL_HINT_JOYSTICK_HIDAPI_PS3 "SDL_JOYSTICK_HIDAPI_PS3" + +/** + * \brief A variable controlling whether the HIDAPI driver for PS4 controllers should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI driver is not used + * "1" - HIDAPI driver is used + * + * The default is the value of SDL_HINT_JOYSTICK_HIDAPI + */ +#define SDL_HINT_JOYSTICK_HIDAPI_PS4 "SDL_JOYSTICK_HIDAPI_PS4" + +/** + * \brief A variable controlling whether extended input reports should be used for PS4 controllers when using the HIDAPI driver. + * + * This variable can be set to the following values: + * "0" - extended reports are not enabled (the default) + * "1" - extended reports + * + * Extended input reports allow rumble on Bluetooth PS4 controllers, but + * break DirectInput handling for applications that don't use SDL. + * + * Once extended reports are enabled, they can not be disabled without + * power cycling the controller. + * + * For compatibility with applications written for versions of SDL prior + * to the introduction of PS5 controller support, this value will also + * control the state of extended reports on PS5 controllers when the + * SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE hint is not explicitly set. + */ +#define SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE "SDL_JOYSTICK_HIDAPI_PS4_RUMBLE" + +/** + * \brief A variable controlling whether the HIDAPI driver for PS5 controllers should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI driver is not used + * "1" - HIDAPI driver is used + * + * The default is the value of SDL_HINT_JOYSTICK_HIDAPI + */ +#define SDL_HINT_JOYSTICK_HIDAPI_PS5 "SDL_JOYSTICK_HIDAPI_PS5" + +/** + * \brief A variable controlling whether the player LEDs should be lit to indicate which player is associated with a PS5 controller. + * + * This variable can be set to the following values: + * "0" - player LEDs are not enabled + * "1" - player LEDs are enabled (the default) + */ +#define SDL_HINT_JOYSTICK_HIDAPI_PS5_PLAYER_LED "SDL_JOYSTICK_HIDAPI_PS5_PLAYER_LED" + +/** + * \brief A variable controlling whether extended input reports should be used for PS5 controllers when using the HIDAPI driver. + * + * This variable can be set to the following values: + * "0" - extended reports are not enabled (the default) + * "1" - extended reports + * + * Extended input reports allow rumble on Bluetooth PS5 controllers, but + * break DirectInput handling for applications that don't use SDL. + * + * Once extended reports are enabled, they can not be disabled without + * power cycling the controller. + * + * For compatibility with applications written for versions of SDL prior + * to the introduction of PS5 controller support, this value defaults to + * the value of SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE. + */ +#define SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE "SDL_JOYSTICK_HIDAPI_PS5_RUMBLE" + +/** + * \brief A variable controlling whether the HIDAPI driver for Google Stadia controllers should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI driver is not used + * "1" - HIDAPI driver is used + * + * The default is the value of SDL_HINT_JOYSTICK_HIDAPI + */ +#define SDL_HINT_JOYSTICK_HIDAPI_STADIA "SDL_JOYSTICK_HIDAPI_STADIA" + +/** + * \brief A variable controlling whether the HIDAPI driver for Bluetooth Steam Controllers should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI driver is not used + * "1" - HIDAPI driver is used for Steam Controllers, which requires Bluetooth access + * and may prompt the user for permission on iOS and Android. + * + * The default is "0" + */ +#define SDL_HINT_JOYSTICK_HIDAPI_STEAM "SDL_JOYSTICK_HIDAPI_STEAM" + +/** + * \brief A variable controlling whether the HIDAPI driver for the Steam Deck builtin controller should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI driver is not used + * "1" - HIDAPI driver is used + * + * The default is the value of SDL_HINT_JOYSTICK_HIDAPI + */ +#define SDL_HINT_JOYSTICK_HIDAPI_STEAMDECK "SDL_JOYSTICK_HIDAPI_STEAMDECK" + +/** + * \brief A variable controlling whether the HIDAPI driver for Nintendo Switch controllers should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI driver is not used + * "1" - HIDAPI driver is used + * + * The default is the value of SDL_HINT_JOYSTICK_HIDAPI + */ +#define SDL_HINT_JOYSTICK_HIDAPI_SWITCH "SDL_JOYSTICK_HIDAPI_SWITCH" + +/** + * \brief A variable controlling whether the Home button LED should be turned on when a Nintendo Switch Pro controller is opened + * + * This variable can be set to the following values: + * "0" - home button LED is turned off + * "1" - home button LED is turned on + * + * By default the Home button LED state is not changed. This hint can also be set to a floating point value between 0.0 and 1.0 which controls the brightness of the Home button LED. + */ +#define SDL_HINT_JOYSTICK_HIDAPI_SWITCH_HOME_LED "SDL_JOYSTICK_HIDAPI_SWITCH_HOME_LED" + +/** + * \brief A variable controlling whether the Home button LED should be turned on when a Nintendo Switch Joy-Con controller is opened + * + * This variable can be set to the following values: + * "0" - home button LED is turned off + * "1" - home button LED is turned on + * + * By default the Home button LED state is not changed. This hint can also be set to a floating point value between 0.0 and 1.0 which controls the brightness of the Home button LED. + */ +#define SDL_HINT_JOYSTICK_HIDAPI_JOYCON_HOME_LED "SDL_JOYSTICK_HIDAPI_JOYCON_HOME_LED" + +/** + * \brief A variable controlling whether the player LEDs should be lit to indicate which player is associated with a Nintendo Switch controller. + * + * This variable can be set to the following values: + * "0" - player LEDs are not enabled + * "1" - player LEDs are enabled (the default) + */ +#define SDL_HINT_JOYSTICK_HIDAPI_SWITCH_PLAYER_LED "SDL_JOYSTICK_HIDAPI_SWITCH_PLAYER_LED" + +/** + * \brief A variable controlling whether the HIDAPI driver for Nintendo Wii and Wii U controllers should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI driver is not used + * "1" - HIDAPI driver is used + * + * This driver doesn't work with the dolphinbar, so the default is SDL_FALSE for now. + */ +#define SDL_HINT_JOYSTICK_HIDAPI_WII "SDL_JOYSTICK_HIDAPI_WII" + +/** + * \brief A variable controlling whether the player LEDs should be lit to indicate which player is associated with a Wii controller. + * + * This variable can be set to the following values: + * "0" - player LEDs are not enabled + * "1" - player LEDs are enabled (the default) + */ +#define SDL_HINT_JOYSTICK_HIDAPI_WII_PLAYER_LED "SDL_JOYSTICK_HIDAPI_WII_PLAYER_LED" + +/** + * \brief A variable controlling whether the HIDAPI driver for XBox controllers should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI driver is not used + * "1" - HIDAPI driver is used + * + * The default is "0" on Windows, otherwise the value of SDL_HINT_JOYSTICK_HIDAPI + */ +#define SDL_HINT_JOYSTICK_HIDAPI_XBOX "SDL_JOYSTICK_HIDAPI_XBOX" + +/** + * \brief A variable controlling whether the HIDAPI driver for XBox 360 controllers should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI driver is not used + * "1" - HIDAPI driver is used + * + * The default is the value of SDL_HINT_JOYSTICK_HIDAPI_XBOX + */ +#define SDL_HINT_JOYSTICK_HIDAPI_XBOX_360 "SDL_JOYSTICK_HIDAPI_XBOX_360" + +/** + * \brief A variable controlling whether the player LEDs should be lit to indicate which player is associated with an Xbox 360 controller. + * + * This variable can be set to the following values: + * "0" - player LEDs are not enabled + * "1" - player LEDs are enabled (the default) + */ +#define SDL_HINT_JOYSTICK_HIDAPI_XBOX_360_PLAYER_LED "SDL_JOYSTICK_HIDAPI_XBOX_360_PLAYER_LED" + +/** + * \brief A variable controlling whether the HIDAPI driver for XBox 360 wireless controllers should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI driver is not used + * "1" - HIDAPI driver is used + * + * The default is the value of SDL_HINT_JOYSTICK_HIDAPI_XBOX_360 + */ +#define SDL_HINT_JOYSTICK_HIDAPI_XBOX_360_WIRELESS "SDL_JOYSTICK_HIDAPI_XBOX_360_WIRELESS" + +/** + * \brief A variable controlling whether the HIDAPI driver for XBox One controllers should be used. + * + * This variable can be set to the following values: + * "0" - HIDAPI driver is not used + * "1" - HIDAPI driver is used + * + * The default is the value of SDL_HINT_JOYSTICK_HIDAPI_XBOX + */ +#define SDL_HINT_JOYSTICK_HIDAPI_XBOX_ONE "SDL_JOYSTICK_HIDAPI_XBOX_ONE" + +/** + * \brief A variable controlling whether the Home button LED should be turned on when an Xbox One controller is opened + * + * This variable can be set to the following values: + * "0" - home button LED is turned off + * "1" - home button LED is turned on + * + * By default the Home button LED state is not changed. This hint can also be set to a floating point value between 0.0 and 1.0 which controls the brightness of the Home button LED. The default brightness is 0.4. + */ +#define SDL_HINT_JOYSTICK_HIDAPI_XBOX_ONE_HOME_LED "SDL_JOYSTICK_HIDAPI_XBOX_ONE_HOME_LED" + +/** + * A variable controlling whether IOKit should be used for controller handling. + * + * This variable can be set to the following values: + * "0" - IOKit is not used + * "1" - IOKit is used (the default) + */ +#define SDL_HINT_JOYSTICK_IOKIT "SDL_JOYSTICK_IOKIT" + +/** + * A variable controlling whether GCController should be used for controller handling. + * + * This variable can be set to the following values: + * "0" - GCController is not used + * "1" - GCController is used (the default) + */ +#define SDL_HINT_JOYSTICK_MFI "SDL_JOYSTICK_MFI" + +/** + * \brief A variable controlling whether the RAWINPUT joystick drivers should be used for better handling XInput-capable devices. + * + * This variable can be set to the following values: + * "0" - RAWINPUT drivers are not used + * "1" - RAWINPUT drivers are used (the default) + */ +#define SDL_HINT_JOYSTICK_RAWINPUT "SDL_JOYSTICK_RAWINPUT" + +/** + * \brief A variable controlling whether the RAWINPUT driver should pull correlated data from XInput. + * + * This variable can be set to the following values: + * "0" - RAWINPUT driver will only use data from raw input APIs + * "1" - RAWINPUT driver will also pull data from XInput, providing + * better trigger axes, guide button presses, and rumble support + * for Xbox controllers + * + * The default is "1". This hint applies to any joysticks opened after setting the hint. + */ +#define SDL_HINT_JOYSTICK_RAWINPUT_CORRELATE_XINPUT "SDL_JOYSTICK_RAWINPUT_CORRELATE_XINPUT" + +/** + * \brief A variable controlling whether the ROG Chakram mice should show up as joysticks + * + * This variable can be set to the following values: + * "0" - ROG Chakram mice do not show up as joysticks (the default) + * "1" - ROG Chakram mice show up as joysticks + */ +#define SDL_HINT_JOYSTICK_ROG_CHAKRAM "SDL_JOYSTICK_ROG_CHAKRAM" + +/** + * \brief A variable controlling whether a separate thread should be used + * for handling joystick detection and raw input messages on Windows + * + * This variable can be set to the following values: + * "0" - A separate thread is not used (the default) + * "1" - A separate thread is used for handling raw input messages + * + */ +#define SDL_HINT_JOYSTICK_THREAD "SDL_JOYSTICK_THREAD" + +/** + * A variable containing a list of throttle style controllers. + * + * The format of the string is a comma separated list of USB VID/PID pairs + * in hexadecimal form, e.g. + * + * 0xAAAA/0xBBBB,0xCCCC/0xDDDD + * + * The variable can also take the form of @file, in which case the named + * file will be loaded and interpreted as the value of the variable. + */ +#define SDL_HINT_JOYSTICK_THROTTLE_DEVICES "SDL_JOYSTICK_THROTTLE_DEVICES" + +/** + * A variable containing a list of devices that are not throttle style controllers. This will override SDL_HINT_JOYSTICK_THROTTLE_DEVICES and the built in device list. + * + * The format of the string is a comma separated list of USB VID/PID pairs + * in hexadecimal form, e.g. + * + * 0xAAAA/0xBBBB,0xCCCC/0xDDDD + * + * The variable can also take the form of @file, in which case the named + * file will be loaded and interpreted as the value of the variable. + */ +#define SDL_HINT_JOYSTICK_THROTTLE_DEVICES_EXCLUDED "SDL_JOYSTICK_THROTTLE_DEVICES_EXCLUDED" + +/** + * \brief A variable controlling whether Windows.Gaming.Input should be used for controller handling. + * + * This variable can be set to the following values: + * "0" - WGI is not used + * "1" - WGI is used (the default) + */ +#define SDL_HINT_JOYSTICK_WGI "SDL_JOYSTICK_WGI" + +/** + * A variable containing a list of wheel style controllers. + * + * The format of the string is a comma separated list of USB VID/PID pairs + * in hexadecimal form, e.g. + * + * 0xAAAA/0xBBBB,0xCCCC/0xDDDD + * + * The variable can also take the form of @file, in which case the named + * file will be loaded and interpreted as the value of the variable. + */ +#define SDL_HINT_JOYSTICK_WHEEL_DEVICES "SDL_JOYSTICK_WHEEL_DEVICES" + +/** + * A variable containing a list of devices that are not wheel style controllers. This will override SDL_HINT_JOYSTICK_WHEEL_DEVICES and the built in device list. + * + * The format of the string is a comma separated list of USB VID/PID pairs + * in hexadecimal form, e.g. + * + * 0xAAAA/0xBBBB,0xCCCC/0xDDDD + * + * The variable can also take the form of @file, in which case the named + * file will be loaded and interpreted as the value of the variable. + */ +#define SDL_HINT_JOYSTICK_WHEEL_DEVICES_EXCLUDED "SDL_JOYSTICK_WHEEL_DEVICES_EXCLUDED" + +/** + * A variable containing a list of devices known to have all axes centered at zero. + * + * The format of the string is a comma separated list of USB VID/PID pairs + * in hexadecimal form, e.g. + * + * 0xAAAA/0xBBBB,0xCCCC/0xDDDD + * + * The variable can also take the form of @file, in which case the named + * file will be loaded and interpreted as the value of the variable. + */ +#define SDL_HINT_JOYSTICK_ZERO_CENTERED_DEVICES "SDL_JOYSTICK_ZERO_CENTERED_DEVICES" + +/** + * \brief Determines whether SDL enforces that DRM master is required in order + * to initialize the KMSDRM video backend. + * + * The DRM subsystem has a concept of a "DRM master" which is a DRM client that + * has the ability to set planes, set cursor, etc. When SDL is DRM master, it + * can draw to the screen using the SDL rendering APIs. Without DRM master, SDL + * is still able to process input and query attributes of attached displays, + * but it cannot change display state or draw to the screen directly. + * + * In some cases, it can be useful to have the KMSDRM backend even if it cannot + * be used for rendering. An app may want to use SDL for input processing while + * using another rendering API (such as an MMAL overlay on Raspberry Pi) or + * using its own code to render to DRM overlays that SDL doesn't support. + * + * This hint must be set before initializing the video subsystem. + * + * This variable can be set to the following values: + * "0" - SDL will allow usage of the KMSDRM backend without DRM master + * "1" - SDL Will require DRM master to use the KMSDRM backend (default) + */ +#define SDL_HINT_KMSDRM_REQUIRE_DRM_MASTER "SDL_KMSDRM_REQUIRE_DRM_MASTER" + +/** + * \brief A comma separated list of devices to open as joysticks + * + * This variable is currently only used by the Linux joystick driver. + */ +#define SDL_HINT_JOYSTICK_DEVICE "SDL_JOYSTICK_DEVICE" + +/** + * \brief A variable controlling whether joysticks on Linux will always treat 'hat' axis inputs (ABS_HAT0X - ABS_HAT3Y) as 8-way digital hats without checking whether they may be analog. + * + * This variable can be set to the following values: + * "0" - Only map hat axis inputs to digital hat outputs if the input axes appear to actually be digital (the default) + * "1" - Always handle the input axes numbered ABS_HAT0X to ABS_HAT3Y as digital hats + */ +#define SDL_HINT_LINUX_DIGITAL_HATS "SDL_LINUX_DIGITAL_HATS" + +/** + * \brief A variable controlling whether digital hats on Linux will apply deadzones to their underlying input axes or use unfiltered values. + * + * This variable can be set to the following values: + * "0" - Return digital hat values based on unfiltered input axis values + * "1" - Return digital hat values with deadzones on the input axes taken into account (the default) + */ +#define SDL_HINT_LINUX_HAT_DEADZONES "SDL_LINUX_HAT_DEADZONES" + +/** + * \brief A variable controlling whether to use the classic /dev/input/js* joystick interface or the newer /dev/input/event* joystick interface on Linux + * + * This variable can be set to the following values: + * "0" - Use /dev/input/event* + * "1" - Use /dev/input/js* + * + * By default the /dev/input/event* interfaces are used + */ +#define SDL_HINT_LINUX_JOYSTICK_CLASSIC "SDL_LINUX_JOYSTICK_CLASSIC" + +/** + * \brief A variable controlling whether joysticks on Linux adhere to their HID-defined deadzones or return unfiltered values. + * + * This variable can be set to the following values: + * "0" - Return unfiltered joystick axis values (the default) + * "1" - Return axis values with deadzones taken into account + */ +#define SDL_HINT_LINUX_JOYSTICK_DEADZONES "SDL_LINUX_JOYSTICK_DEADZONES" + +/** + * \brief A variable controlling the default SDL log levels. + * + * This variable is a comma separated set of category=level tokens that define the default logging levels for SDL applications. + * + * The category can be a numeric category, one of "app", "error", "assert", "system", "audio", "video", "render", "input", "test", or `*` for any unspecified category. + * + * The level can be a numeric level, one of "verbose", "debug", "info", "warn", "error", "critical", or "quiet" to disable that category. + * + * You can omit the category if you want to set the logging level for all categories. + * + * If this hint isn't set, the default log levels are equivalent to: + * "app=info,assert=warn,test=verbose,*=error" + */ +#define SDL_HINT_LOGGING "SDL_LOGGING" + +/** +* \brief When set don't force the SDL app to become a foreground process +* +* This hint only applies to Mac OS X. +* +*/ +#define SDL_HINT_MAC_BACKGROUND_APP "SDL_MAC_BACKGROUND_APP" + +/** + * \brief A variable that determines whether ctrl+click should generate a right-click event on Mac + * + * If present, holding ctrl while left clicking will generate a right click + * event when on Mac. + */ +#define SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK "SDL_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK" + +/** + * \brief A variable controlling whether dispatching OpenGL context updates should block the dispatching thread until the main thread finishes processing + * + * This variable can be set to the following values: + * "0" - Dispatching OpenGL context updates will block the dispatching thread until the main thread finishes processing (default). + * "1" - Dispatching OpenGL context updates will allow the dispatching thread to continue execution. + * + * Generally you want the default, but if you have OpenGL code in a background thread on a Mac, and the main thread + * hangs because it's waiting for that background thread, but that background thread is also hanging because it's + * waiting for the main thread to do an update, this might fix your issue. + * + * This hint only applies to macOS. + * + * This hint is available since SDL 2.24.0. + * + */ +#define SDL_HINT_MAC_OPENGL_ASYNC_DISPATCH "SDL_MAC_OPENGL_ASYNC_DISPATCH" + +/** + * \brief A variable setting the double click radius, in pixels. + */ +#define SDL_HINT_MOUSE_DOUBLE_CLICK_RADIUS "SDL_MOUSE_DOUBLE_CLICK_RADIUS" + +/** + * \brief A variable setting the double click time, in milliseconds. + */ +#define SDL_HINT_MOUSE_DOUBLE_CLICK_TIME "SDL_MOUSE_DOUBLE_CLICK_TIME" + +/** + * \brief Allow mouse click events when clicking to focus an SDL window + * + * This variable can be set to the following values: + * "0" - Ignore mouse clicks that activate a window + * "1" - Generate events for mouse clicks that activate a window + * + * By default SDL will ignore mouse clicks that activate a window + */ +#define SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH "SDL_MOUSE_FOCUS_CLICKTHROUGH" + +/** + * \brief A variable setting the speed scale for mouse motion, in floating point, when the mouse is not in relative mode + */ +#define SDL_HINT_MOUSE_NORMAL_SPEED_SCALE "SDL_MOUSE_NORMAL_SPEED_SCALE" + +/** + * \brief A variable controlling whether relative mouse mode constrains the mouse to the center of the window + * + * This variable can be set to the following values: + * "0" - Relative mouse mode constrains the mouse to the window + * "1" - Relative mouse mode constrains the mouse to the center of the window + * + * Constraining to the center of the window works better for FPS games and when the + * application is running over RDP. Constraining to the whole window works better + * for 2D games and increases the chance that the mouse will be in the correct + * position when using high DPI mice. + * + * By default SDL will constrain the mouse to the center of the window + */ +#define SDL_HINT_MOUSE_RELATIVE_MODE_CENTER "SDL_MOUSE_RELATIVE_MODE_CENTER" + +/** + * \brief A variable controlling whether relative mouse mode is implemented using mouse warping + * + * This variable can be set to the following values: + * "0" - Relative mouse mode uses raw input + * "1" - Relative mouse mode uses mouse warping + * + * By default SDL will use raw input for relative mouse mode + */ +#define SDL_HINT_MOUSE_RELATIVE_MODE_WARP "SDL_MOUSE_RELATIVE_MODE_WARP" + +/** + * \brief A variable controlling whether relative mouse motion is affected by renderer scaling + * + * This variable can be set to the following values: + * "0" - Relative motion is unaffected by DPI or renderer's logical size + * "1" - Relative motion is scaled according to DPI scaling and logical size + * + * By default relative mouse deltas are affected by DPI and renderer scaling + */ +#define SDL_HINT_MOUSE_RELATIVE_SCALING "SDL_MOUSE_RELATIVE_SCALING" + +/** + * \brief A variable setting the scale for mouse motion, in floating point, when the mouse is in relative mode + */ +#define SDL_HINT_MOUSE_RELATIVE_SPEED_SCALE "SDL_MOUSE_RELATIVE_SPEED_SCALE" + +/** + * \brief A variable controlling whether the system mouse acceleration curve is used for relative mouse motion. + * + * This variable can be set to the following values: + * "0" - Relative mouse motion will be unscaled (the default) + * "1" - Relative mouse motion will be scaled using the system mouse acceleration curve. + * + * If SDL_HINT_MOUSE_RELATIVE_SPEED_SCALE is set, that will override the system speed scale. + */ +#define SDL_HINT_MOUSE_RELATIVE_SYSTEM_SCALE "SDL_MOUSE_RELATIVE_SYSTEM_SCALE" + +/** + * \brief A variable controlling whether a motion event should be generated for mouse warping in relative mode. + * + * This variable can be set to the following values: + * "0" - Warping the mouse will not generate a motion event in relative mode + * "1" - Warping the mouse will generate a motion event in relative mode + * + * By default warping the mouse will not generate motion events in relative mode. This avoids the application having to filter out large relative motion due to warping. + */ +#define SDL_HINT_MOUSE_RELATIVE_WARP_MOTION "SDL_MOUSE_RELATIVE_WARP_MOTION" + +/** + * \brief A variable controlling whether the hardware cursor stays visible when relative mode is active. + * + * This variable can be set to the following values: + * "0" - The cursor will be hidden while relative mode is active (default) + * "1" - The cursor will remain visible while relative mode is active + * + * Note that for systems without raw hardware inputs, relative mode is implemented using warping, so the hardware cursor will visibly warp between frames if this is enabled on those systems. + */ +#define SDL_HINT_MOUSE_RELATIVE_CURSOR_VISIBLE "SDL_MOUSE_RELATIVE_CURSOR_VISIBLE" + +/** + * A variable controlling whether mouse events should generate synthetic touch + * events + * + * This variable can be set to the following values: + * "0" - Mouse events will not generate touch events (default for desktop platforms) + * "1" - Mouse events will generate touch events (default for mobile platforms, such as Android and iOS) + */ +#define SDL_HINT_MOUSE_TOUCH_EVENTS "SDL_MOUSE_TOUCH_EVENTS" + +/** + * \brief A variable controlling whether the mouse is captured while mouse buttons are pressed + * + * This variable can be set to the following values: + * "0" - The mouse is not captured while mouse buttons are pressed + * "1" - The mouse is captured while mouse buttons are pressed + * + * By default the mouse is captured while mouse buttons are pressed so if the mouse is dragged + * outside the window, the application continues to receive mouse events until the button is + * released. + */ +#define SDL_HINT_MOUSE_AUTO_CAPTURE "SDL_MOUSE_AUTO_CAPTURE" + +/** + * \brief Tell SDL not to catch the SIGINT or SIGTERM signals. + * + * This hint only applies to Unix-like platforms, and should set before + * any calls to SDL_Init() + * + * The variable can be set to the following values: + * "0" - SDL will install a SIGINT and SIGTERM handler, and when it + * catches a signal, convert it into an SDL_QUIT event. + * "1" - SDL will not install a signal handler at all. + */ +#define SDL_HINT_NO_SIGNAL_HANDLERS "SDL_NO_SIGNAL_HANDLERS" + +/** + * \brief A variable controlling what driver to use for OpenGL ES contexts. + * + * On some platforms, currently Windows and X11, OpenGL drivers may support + * creating contexts with an OpenGL ES profile. By default SDL uses these + * profiles, when available, otherwise it attempts to load an OpenGL ES + * library, e.g. that provided by the ANGLE project. This variable controls + * whether SDL follows this default behaviour or will always load an + * OpenGL ES library. + * + * Circumstances where this is useful include + * - Testing an app with a particular OpenGL ES implementation, e.g ANGLE, + * or emulator, e.g. those from ARM, Imagination or Qualcomm. + * - Resolving OpenGL ES function addresses at link time by linking with + * the OpenGL ES library instead of querying them at run time with + * SDL_GL_GetProcAddress(). + * + * Caution: for an application to work with the default behaviour across + * different OpenGL drivers it must query the OpenGL ES function + * addresses at run time using SDL_GL_GetProcAddress(). + * + * This variable is ignored on most platforms because OpenGL ES is native + * or not supported. + * + * This variable can be set to the following values: + * "0" - Use ES profile of OpenGL, if available. (Default when not set.) + * "1" - Load OpenGL ES library using the default library names. + * + */ +#define SDL_HINT_OPENGL_ES_DRIVER "SDL_OPENGL_ES_DRIVER" + +/** + * \brief A variable controlling which orientations are allowed on iOS/Android. + * + * In some circumstances it is necessary to be able to explicitly control + * which UI orientations are allowed. + * + * This variable is a space delimited list of the following values: + * "LandscapeLeft", "LandscapeRight", "Portrait" "PortraitUpsideDown" + */ +#define SDL_HINT_ORIENTATIONS "SDL_IOS_ORIENTATIONS" + +/** + * \brief A variable controlling the use of a sentinel event when polling the event queue + * + * This variable can be set to the following values: + * "0" - Disable poll sentinels + * "1" - Enable poll sentinels + * + * When polling for events, SDL_PumpEvents is used to gather new events from devices. + * If a device keeps producing new events between calls to SDL_PumpEvents, a poll loop will + * become stuck until the new events stop. + * This is most noticeable when moving a high frequency mouse. + * + * By default, poll sentinels are enabled. + */ +#define SDL_HINT_POLL_SENTINEL "SDL_POLL_SENTINEL" + +/** + * \brief Override for SDL_GetPreferredLocales() + * + * If set, this will be favored over anything the OS might report for the + * user's preferred locales. Changing this hint at runtime will not generate + * a SDL_LOCALECHANGED event (but if you can change the hint, you can push + * your own event, if you want). + * + * The format of this hint is a comma-separated list of language and locale, + * combined with an underscore, as is a common format: "en_GB". Locale is + * optional: "en". So you might have a list like this: "en_GB,jp,es_PT" + */ +#define SDL_HINT_PREFERRED_LOCALES "SDL_PREFERRED_LOCALES" + +/** + * \brief A variable describing the content orientation on QtWayland-based platforms. + * + * On QtWayland platforms, windows are rotated client-side to allow for custom + * transitions. In order to correctly position overlays (e.g. volume bar) and + * gestures (e.g. events view, close/minimize gestures), the system needs to + * know in which orientation the application is currently drawing its contents. + * + * This does not cause the window to be rotated or resized, the application + * needs to take care of drawing the content in the right orientation (the + * framebuffer is always in portrait mode). + * + * This variable can be one of the following values: + * "primary" (default), "portrait", "landscape", "inverted-portrait", "inverted-landscape" + * + * Since SDL 2.0.22 this variable accepts a comma-separated list of values above. + */ +#define SDL_HINT_QTWAYLAND_CONTENT_ORIENTATION "SDL_QTWAYLAND_CONTENT_ORIENTATION" + +/** + * \brief Flags to set on QtWayland windows to integrate with the native window manager. + * + * On QtWayland platforms, this hint controls the flags to set on the windows. + * For example, on Sailfish OS "OverridesSystemGestures" disables swipe gestures. + * + * This variable is a space-separated list of the following values (empty = no flags): + * "OverridesSystemGestures", "StaysOnTop", "BypassWindowManager" + */ +#define SDL_HINT_QTWAYLAND_WINDOW_FLAGS "SDL_QTWAYLAND_WINDOW_FLAGS" + +/** + * \brief A variable controlling whether the 2D render API is compatible or efficient. + * + * This variable can be set to the following values: + * + * "0" - Don't use batching to make rendering more efficient. + * "1" - Use batching, but might cause problems if app makes its own direct OpenGL calls. + * + * Up to SDL 2.0.9, the render API would draw immediately when requested. Now + * it batches up draw requests and sends them all to the GPU only when forced + * to (during SDL_RenderPresent, when changing render targets, by updating a + * texture that the batch needs, etc). This is significantly more efficient, + * but it can cause problems for apps that expect to render on top of the + * render API's output. As such, SDL will disable batching if a specific + * render backend is requested (since this might indicate that the app is + * planning to use the underlying graphics API directly). This hint can + * be used to explicitly request batching in this instance. It is a contract + * that you will either never use the underlying graphics API directly, or + * if you do, you will call SDL_RenderFlush() before you do so any current + * batch goes to the GPU before your work begins. Not following this contract + * will result in undefined behavior. + */ +#define SDL_HINT_RENDER_BATCHING "SDL_RENDER_BATCHING" + +/** + * \brief A variable controlling how the 2D render API renders lines + * + * This variable can be set to the following values: + * "0" - Use the default line drawing method (Bresenham's line algorithm as of SDL 2.0.20) + * "1" - Use the driver point API using Bresenham's line algorithm (correct, draws many points) + * "2" - Use the driver line API (occasionally misses line endpoints based on hardware driver quirks, was the default before 2.0.20) + * "3" - Use the driver geometry API (correct, draws thicker diagonal lines) + * + * This variable should be set when the renderer is created. + */ +#define SDL_HINT_RENDER_LINE_METHOD "SDL_RENDER_LINE_METHOD" + +/** + * \brief A variable controlling whether to enable Direct3D 11+'s Debug Layer. + * + * This variable does not have any effect on the Direct3D 9 based renderer. + * + * This variable can be set to the following values: + * "0" - Disable Debug Layer use + * "1" - Enable Debug Layer use + * + * By default, SDL does not use Direct3D Debug Layer. + */ +#define SDL_HINT_RENDER_DIRECT3D11_DEBUG "SDL_RENDER_DIRECT3D11_DEBUG" + +/** + * \brief A variable controlling whether the Direct3D device is initialized for thread-safe operations. + * + * This variable can be set to the following values: + * "0" - Thread-safety is not enabled (faster) + * "1" - Thread-safety is enabled + * + * By default the Direct3D device is created with thread-safety disabled. + */ +#define SDL_HINT_RENDER_DIRECT3D_THREADSAFE "SDL_RENDER_DIRECT3D_THREADSAFE" + +/** + * \brief A variable specifying which render driver to use. + * + * If the application doesn't pick a specific renderer to use, this variable + * specifies the name of the preferred renderer. If the preferred renderer + * can't be initialized, the normal default renderer is used. + * + * This variable is case insensitive and can be set to the following values: + * "direct3d" + * "direct3d11" + * "direct3d12" + * "opengl" + * "opengles2" + * "opengles" + * "metal" + * "software" + * + * The default varies by platform, but it's the first one in the list that + * is available on the current platform. + */ +#define SDL_HINT_RENDER_DRIVER "SDL_RENDER_DRIVER" + +/** + * \brief A variable controlling the scaling policy for SDL_RenderSetLogicalSize. + * + * This variable can be set to the following values: + * "0" or "letterbox" - Uses letterbox/sidebars to fit the entire rendering on screen + * "1" or "overscan" - Will zoom the rendering so it fills the entire screen, allowing edges to be drawn offscreen + * + * By default letterbox is used + */ +#define SDL_HINT_RENDER_LOGICAL_SIZE_MODE "SDL_RENDER_LOGICAL_SIZE_MODE" + +/** + * \brief A variable controlling whether the OpenGL render driver uses shaders if they are available. + * + * This variable can be set to the following values: + * "0" - Disable shaders + * "1" - Enable shaders + * + * By default shaders are used if OpenGL supports them. + */ +#define SDL_HINT_RENDER_OPENGL_SHADERS "SDL_RENDER_OPENGL_SHADERS" + +/** + * \brief A variable controlling the scaling quality + * + * This variable can be set to the following values: + * "0" or "nearest" - Nearest pixel sampling + * "1" or "linear" - Linear filtering (supported by OpenGL and Direct3D) + * "2" or "best" - Currently this is the same as "linear" + * + * By default nearest pixel sampling is used + */ +#define SDL_HINT_RENDER_SCALE_QUALITY "SDL_RENDER_SCALE_QUALITY" + +/** + * \brief A variable controlling whether updates to the SDL screen surface should be synchronized with the vertical refresh, to avoid tearing. + * + * This variable can be set to the following values: + * "0" - Disable vsync + * "1" - Enable vsync + * + * By default SDL does not sync screen surface updates with vertical refresh. + */ +#define SDL_HINT_RENDER_VSYNC "SDL_RENDER_VSYNC" + +/** + * \brief A variable controlling whether the Metal render driver select low power device over default one + * + * This variable can be set to the following values: + * "0" - Use the prefered OS device + * "1" - Select a low power one + * + * By default the prefered OS device is used. + */ +#define SDL_HINT_RENDER_METAL_PREFER_LOW_POWER_DEVICE "SDL_RENDER_METAL_PREFER_LOW_POWER_DEVICE" + +/** + * A variable containing a list of ROG gamepad capable mice. + * + * The format of the string is a comma separated list of USB VID/PID pairs + * in hexadecimal form, e.g. + * + * 0xAAAA/0xBBBB,0xCCCC/0xDDDD + * + * The variable can also take the form of @file, in which case the named + * file will be loaded and interpreted as the value of the variable. + */ +#define SDL_HINT_ROG_GAMEPAD_MICE "SDL_ROG_GAMEPAD_MICE" + +/** + * A variable containing a list of devices that are not ROG gamepad capable mice. This will override SDL_HINT_ROG_GAMEPAD_MICE and the built in device list. + * + * The format of the string is a comma separated list of USB VID/PID pairs + * in hexadecimal form, e.g. + * + * 0xAAAA/0xBBBB,0xCCCC/0xDDDD + * + * The variable can also take the form of @file, in which case the named + * file will be loaded and interpreted as the value of the variable. + */ +#define SDL_HINT_ROG_GAMEPAD_MICE_EXCLUDED "SDL_ROG_GAMEPAD_MICE_EXCLUDED" + +/** + * \brief A variable controlling if VSYNC is automatically disable if doesn't reach the enough FPS + * + * This variable can be set to the following values: + * "0" - It will be using VSYNC as defined in the main flag. Default + * "1" - If VSYNC was previously enabled, then it will disable VSYNC if doesn't reach enough speed + * + * By default SDL does not enable the automatic VSYNC + */ +#define SDL_HINT_PS2_DYNAMIC_VSYNC "SDL_PS2_DYNAMIC_VSYNC" + +/** + * \brief A variable to control whether the return key on the soft keyboard + * should hide the soft keyboard on Android and iOS. + * + * The variable can be set to the following values: + * "0" - The return key will be handled as a key event. This is the behaviour of SDL <= 2.0.3. (default) + * "1" - The return key will hide the keyboard. + * + * The value of this hint is used at runtime, so it can be changed at any time. + */ +#define SDL_HINT_RETURN_KEY_HIDES_IME "SDL_RETURN_KEY_HIDES_IME" + +/** + * \brief Tell SDL which Dispmanx layer to use on a Raspberry PI + * + * Also known as Z-order. The variable can take a negative or positive value. + * The default is 10000. + */ +#define SDL_HINT_RPI_VIDEO_LAYER "SDL_RPI_VIDEO_LAYER" + +/** + * \brief Specify an "activity name" for screensaver inhibition. + * + * Some platforms, notably Linux desktops, list the applications which are + * inhibiting the screensaver or other power-saving features. + * + * This hint lets you specify the "activity name" sent to the OS when + * SDL_DisableScreenSaver() is used (or the screensaver is automatically + * disabled). The contents of this hint are used when the screensaver is + * disabled. You should use a string that describes what your program is doing + * (and, therefore, why the screensaver is disabled). For example, "Playing a + * game" or "Watching a video". + * + * Setting this to "" or leaving it unset will have SDL use a reasonable + * default: "Playing a game" or something similar. + * + * On targets where this is not supported, this hint does nothing. + */ +#define SDL_HINT_SCREENSAVER_INHIBIT_ACTIVITY_NAME "SDL_SCREENSAVER_INHIBIT_ACTIVITY_NAME" + +/** + * \brief Specifies whether SDL_THREAD_PRIORITY_TIME_CRITICAL should be treated as realtime. + * + * On some platforms, like Linux, a realtime priority thread may be subject to restrictions + * that require special handling by the application. This hint exists to let SDL know that + * the app is prepared to handle said restrictions. + * + * On Linux, SDL will apply the following configuration to any thread that becomes realtime: + * * The SCHED_RESET_ON_FORK bit will be set on the scheduling policy, + * * An RLIMIT_RTTIME budget will be configured to the rtkit specified limit. + * * Exceeding this limit will result in the kernel sending SIGKILL to the app, + * * Refer to the man pages for more information. + * + * This variable can be set to the following values: + * "0" - default platform specific behaviour + * "1" - Force SDL_THREAD_PRIORITY_TIME_CRITICAL to a realtime scheduling policy + */ +#define SDL_HINT_THREAD_FORCE_REALTIME_TIME_CRITICAL "SDL_THREAD_FORCE_REALTIME_TIME_CRITICAL" + +/** +* \brief A string specifying additional information to use with SDL_SetThreadPriority. +* +* By default SDL_SetThreadPriority will make appropriate system changes in order to +* apply a thread priority. For example on systems using pthreads the scheduler policy +* is changed automatically to a policy that works well with a given priority. +* Code which has specific requirements can override SDL's default behavior with this hint. +* +* pthread hint values are "current", "other", "fifo" and "rr". +* Currently no other platform hint values are defined but may be in the future. +* +* \note On Linux, the kernel may send SIGKILL to realtime tasks which exceed the distro +* configured execution budget for rtkit. This budget can be queried through RLIMIT_RTTIME +* after calling SDL_SetThreadPriority(). +*/ +#define SDL_HINT_THREAD_PRIORITY_POLICY "SDL_THREAD_PRIORITY_POLICY" + +/** +* \brief A string specifying SDL's threads stack size in bytes or "0" for the backend's default size +* +* Use this hint in case you need to set SDL's threads stack size to other than the default. +* This is specially useful if you build SDL against a non glibc libc library (such as musl) which +* provides a relatively small default thread stack size (a few kilobytes versus the default 8MB glibc uses). +* Support for this hint is currently available only in the pthread, Windows, and PSP backend. +* +* Instead of this hint, in 2.0.9 and later, you can use +* SDL_CreateThreadWithStackSize(). This hint only works with the classic +* SDL_CreateThread(). +*/ +#define SDL_HINT_THREAD_STACK_SIZE "SDL_THREAD_STACK_SIZE" + +/** + * \brief A variable that controls the timer resolution, in milliseconds. + * + * The higher resolution the timer, the more frequently the CPU services + * timer interrupts, and the more precise delays are, but this takes up + * power and CPU time. This hint is only used on Windows. + * + * See this blog post for more information: + * http://randomascii.wordpress.com/2013/07/08/windows-timer-resolution-megawatts-wasted/ + * + * If this variable is set to "0", the system timer resolution is not set. + * + * The default value is "1". This hint may be set at any time. + */ +#define SDL_HINT_TIMER_RESOLUTION "SDL_TIMER_RESOLUTION" + +/** + * \brief A variable controlling whether touch events should generate synthetic mouse events + * + * This variable can be set to the following values: + * "0" - Touch events will not generate mouse events + * "1" - Touch events will generate mouse events + * + * By default SDL will generate mouse events for touch events + */ +#define SDL_HINT_TOUCH_MOUSE_EVENTS "SDL_TOUCH_MOUSE_EVENTS" + +/** + * \brief A variable controlling which touchpad should generate synthetic mouse events + * + * This variable can be set to the following values: + * "0" - Only front touchpad should generate mouse events. Default + * "1" - Only back touchpad should generate mouse events. + * "2" - Both touchpads should generate mouse events. + * + * By default SDL will generate mouse events for all touch devices + */ +#define SDL_HINT_VITA_TOUCH_MOUSE_DEVICE "SDL_HINT_VITA_TOUCH_MOUSE_DEVICE" + +/** + * \brief A variable controlling whether the Android / tvOS remotes + * should be listed as joystick devices, instead of sending keyboard events. + * + * This variable can be set to the following values: + * "0" - Remotes send enter/escape/arrow key events + * "1" - Remotes are available as 2 axis, 2 button joysticks (the default). + */ +#define SDL_HINT_TV_REMOTE_AS_JOYSTICK "SDL_TV_REMOTE_AS_JOYSTICK" + +/** + * \brief A variable controlling whether the screensaver is enabled. + * + * This variable can be set to the following values: + * "0" - Disable screensaver + * "1" - Enable screensaver + * + * By default SDL will disable the screensaver. + */ +#define SDL_HINT_VIDEO_ALLOW_SCREENSAVER "SDL_VIDEO_ALLOW_SCREENSAVER" + +/** + * \brief Tell the video driver that we only want a double buffer. + * + * By default, most lowlevel 2D APIs will use a triple buffer scheme that + * wastes no CPU time on waiting for vsync after issuing a flip, but + * introduces a frame of latency. On the other hand, using a double buffer + * scheme instead is recommended for cases where low latency is an important + * factor because we save a whole frame of latency. + * We do so by waiting for vsync immediately after issuing a flip, usually just + * after eglSwapBuffers call in the backend's *_SwapWindow function. + * + * Since it's driver-specific, it's only supported where possible and + * implemented. Currently supported the following drivers: + * + * - KMSDRM (kmsdrm) + * - Raspberry Pi (raspberrypi) + */ +#define SDL_HINT_VIDEO_DOUBLE_BUFFER "SDL_VIDEO_DOUBLE_BUFFER" + +/** + * \brief A variable controlling whether the EGL window is allowed to be + * composited as transparent, rather than opaque. + * + * Most window systems will always render windows opaque, even if the surface + * format has an alpha channel. This is not always true, however, so by default + * SDL will try to enforce opaque composition. To override this behavior, you + * can set this hint to "1". + */ +#define SDL_HINT_VIDEO_EGL_ALLOW_TRANSPARENCY "SDL_VIDEO_EGL_ALLOW_TRANSPARENCY" + +/** + * \brief A variable controlling whether the graphics context is externally managed. + * + * This variable can be set to the following values: + * "0" - SDL will manage graphics contexts that are attached to windows. + * "1" - Disable graphics context management on windows. + * + * By default SDL will manage OpenGL contexts in certain situations. For example, on Android the + * context will be automatically saved and restored when pausing the application. Additionally, some + * platforms will assume usage of OpenGL if Vulkan isn't used. Setting this to "1" will prevent this + * behavior, which is desireable when the application manages the graphics context, such as + * an externally managed OpenGL context or attaching a Vulkan surface to the window. + */ +#define SDL_HINT_VIDEO_EXTERNAL_CONTEXT "SDL_VIDEO_EXTERNAL_CONTEXT" + +/** + * \brief If set to 1, then do not allow high-DPI windows. ("Retina" on Mac and iOS) + */ +#define SDL_HINT_VIDEO_HIGHDPI_DISABLED "SDL_VIDEO_HIGHDPI_DISABLED" + +/** + * \brief A variable that dictates policy for fullscreen Spaces on Mac OS X. + * + * This hint only applies to Mac OS X. + * + * The variable can be set to the following values: + * "0" - Disable Spaces support (FULLSCREEN_DESKTOP won't use them and + * SDL_WINDOW_RESIZABLE windows won't offer the "fullscreen" + * button on their titlebars). + * "1" - Enable Spaces support (FULLSCREEN_DESKTOP will use them and + * SDL_WINDOW_RESIZABLE windows will offer the "fullscreen" + * button on their titlebars). + * + * The default value is "1". This hint must be set before any windows are created. + */ +#define SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES "SDL_VIDEO_MAC_FULLSCREEN_SPACES" + +/** + * \brief Minimize your SDL_Window if it loses key focus when in fullscreen mode. Defaults to false. + * \warning Before SDL 2.0.14, this defaulted to true! In 2.0.14, we're + * seeing if "true" causes more problems than it solves in modern times. + * + */ +#define SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS "SDL_VIDEO_MINIMIZE_ON_FOCUS_LOSS" + +/** + * \brief A variable controlling whether the libdecor Wayland backend is allowed to be used. + * + * This variable can be set to the following values: + * "0" - libdecor use is disabled. + * "1" - libdecor use is enabled (default). + * + * libdecor is used over xdg-shell when xdg-decoration protocol is unavailable. + */ +#define SDL_HINT_VIDEO_WAYLAND_ALLOW_LIBDECOR "SDL_VIDEO_WAYLAND_ALLOW_LIBDECOR" + +/** + * \brief A variable controlling whether the libdecor Wayland backend is preferred over native decrations. + * + * When this hint is set, libdecor will be used to provide window decorations, even if xdg-decoration is + * available. (Note that, by default, libdecor will use xdg-decoration itself if available). + * + * This variable can be set to the following values: + * "0" - libdecor is enabled only if server-side decorations are unavailable. + * "1" - libdecor is always enabled if available. + * + * libdecor is used over xdg-shell when xdg-decoration protocol is unavailable. + */ +#define SDL_HINT_VIDEO_WAYLAND_PREFER_LIBDECOR "SDL_VIDEO_WAYLAND_PREFER_LIBDECOR" + +/** + * \brief A variable controlling whether video mode emulation is enabled under Wayland. + * + * When this hint is set, a standard set of emulated CVT video modes will be exposed for use by the application. + * If it is disabled, the only modes exposed will be the logical desktop size and, in the case of a scaled + * desktop, the native display resolution. + * + * This variable can be set to the following values: + * "0" - Video mode emulation is disabled. + * "1" - Video mode emulation is enabled. + * + * By default video mode emulation is enabled. + */ +#define SDL_HINT_VIDEO_WAYLAND_MODE_EMULATION "SDL_VIDEO_WAYLAND_MODE_EMULATION" + +/** + * \brief Enable or disable mouse pointer warp emulation, needed by some older games. + * + * When this hint is set, any SDL will emulate mouse warps using relative mouse mode. + * This is required for some older games (such as Source engine games), which warp the + * mouse to the centre of the screen rather than using relative mouse motion. Note that + * relative mouse mode may have different mouse acceleration behaviour than pointer warps. + * + * This variable can be set to the following values: + * "0" - All mouse warps fail, as mouse warping is not available under wayland. + * "1" - Some mouse warps will be emulated by forcing relative mouse mode. + * + * If not set, this is automatically enabled unless an application uses relative mouse + * mode directly. + */ +#define SDL_HINT_VIDEO_WAYLAND_EMULATE_MOUSE_WARP "SDL_VIDEO_WAYLAND_EMULATE_MOUSE_WARP" + +/** +* \brief A variable that is the address of another SDL_Window* (as a hex string formatted with "%p"). +* +* If this hint is set before SDL_CreateWindowFrom() and the SDL_Window* it is set to has +* SDL_WINDOW_OPENGL set (and running on WGL only, currently), then two things will occur on the newly +* created SDL_Window: +* +* 1. Its pixel format will be set to the same pixel format as this SDL_Window. This is +* needed for example when sharing an OpenGL context across multiple windows. +* +* 2. The flag SDL_WINDOW_OPENGL will be set on the new window so it can be used for +* OpenGL rendering. +* +* This variable can be set to the following values: +* The address (as a string "%p") of the SDL_Window* that new windows created with SDL_CreateWindowFrom() should +* share a pixel format with. +*/ +#define SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT "SDL_VIDEO_WINDOW_SHARE_PIXEL_FORMAT" + +/** + * \brief When calling SDL_CreateWindowFrom(), make the window compatible with OpenGL. + * + * This variable can be set to the following values: + * "0" - Don't add any graphics flags to the SDL_WindowFlags + * "1" - Add SDL_WINDOW_OPENGL to the SDL_WindowFlags + * + * By default SDL will not make the foreign window compatible with OpenGL. + */ +#define SDL_HINT_VIDEO_FOREIGN_WINDOW_OPENGL "SDL_VIDEO_FOREIGN_WINDOW_OPENGL" + +/** + * \brief When calling SDL_CreateWindowFrom(), make the window compatible with Vulkan. + * + * This variable can be set to the following values: + * "0" - Don't add any graphics flags to the SDL_WindowFlags + * "1" - Add SDL_WINDOW_VULKAN to the SDL_WindowFlags + * + * By default SDL will not make the foreign window compatible with Vulkan. + */ +#define SDL_HINT_VIDEO_FOREIGN_WINDOW_VULKAN "SDL_VIDEO_FOREIGN_WINDOW_VULKAN" + +/** +* \brief A variable specifying which shader compiler to preload when using the Chrome ANGLE binaries +* +* SDL has EGL and OpenGL ES2 support on Windows via the ANGLE project. It +* can use two different sets of binaries, those compiled by the user from source +* or those provided by the Chrome browser. In the later case, these binaries require +* that SDL loads a DLL providing the shader compiler. +* +* This variable can be set to the following values: +* "d3dcompiler_46.dll" - default, best for Vista or later. +* "d3dcompiler_43.dll" - for XP support. +* "none" - do not load any library, useful if you compiled ANGLE from source and included the compiler in your binaries. +* +*/ +#define SDL_HINT_VIDEO_WIN_D3DCOMPILER "SDL_VIDEO_WIN_D3DCOMPILER" + +/** + * \brief A variable controlling whether X11 should use GLX or EGL by default + * + * This variable can be set to the following values: + * "0" - Use GLX + * "1" - Use EGL + * + * By default SDL will use GLX when both are present. + */ +#define SDL_HINT_VIDEO_X11_FORCE_EGL "SDL_VIDEO_X11_FORCE_EGL" + +/** + * \brief A variable controlling whether the X11 _NET_WM_BYPASS_COMPOSITOR hint should be used. + * + * This variable can be set to the following values: + * "0" - Disable _NET_WM_BYPASS_COMPOSITOR + * "1" - Enable _NET_WM_BYPASS_COMPOSITOR + * + * By default SDL will use _NET_WM_BYPASS_COMPOSITOR + * + */ +#define SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR "SDL_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR" + +/** + * \brief A variable controlling whether the X11 _NET_WM_PING protocol should be supported. + * + * This variable can be set to the following values: + * "0" - Disable _NET_WM_PING + * "1" - Enable _NET_WM_PING + * + * By default SDL will use _NET_WM_PING, but for applications that know they + * will not always be able to respond to ping requests in a timely manner they can + * turn it off to avoid the window manager thinking the app is hung. + * The hint is checked in CreateWindow. + */ +#define SDL_HINT_VIDEO_X11_NET_WM_PING "SDL_VIDEO_X11_NET_WM_PING" + +/** + * \brief A variable forcing the visual ID chosen for new X11 windows + * + */ +#define SDL_HINT_VIDEO_X11_WINDOW_VISUALID "SDL_VIDEO_X11_WINDOW_VISUALID" + +/** + * \brief A no-longer-used variable controlling whether the X11 Xinerama extension should be used. + * + * Before SDL 2.0.24, this would let apps and users disable Xinerama support on X11. + * Now SDL never uses Xinerama, and does not check for this hint at all. + * The preprocessor define is left here for source compatibility. + */ +#define SDL_HINT_VIDEO_X11_XINERAMA "SDL_VIDEO_X11_XINERAMA" + +/** + * \brief A variable controlling whether the X11 XRandR extension should be used. + * + * This variable can be set to the following values: + * "0" - Disable XRandR + * "1" - Enable XRandR + * + * By default SDL will use XRandR. + */ +#define SDL_HINT_VIDEO_X11_XRANDR "SDL_VIDEO_X11_XRANDR" + +/** + * \brief A no-longer-used variable controlling whether the X11 VidMode extension should be used. + * + * Before SDL 2.0.24, this would let apps and users disable XVidMode support on X11. + * Now SDL never uses XVidMode, and does not check for this hint at all. + * The preprocessor define is left here for source compatibility. + */ +#define SDL_HINT_VIDEO_X11_XVIDMODE "SDL_VIDEO_X11_XVIDMODE" + +/** + * \brief Controls how the fact chunk affects the loading of a WAVE file. + * + * The fact chunk stores information about the number of samples of a WAVE + * file. The Standards Update from Microsoft notes that this value can be used + * to 'determine the length of the data in seconds'. This is especially useful + * for compressed formats (for which this is a mandatory chunk) if they produce + * multiple sample frames per block and truncating the block is not allowed. + * The fact chunk can exactly specify how many sample frames there should be + * in this case. + * + * Unfortunately, most application seem to ignore the fact chunk and so SDL + * ignores it by default as well. + * + * This variable can be set to the following values: + * + * "truncate" - Use the number of samples to truncate the wave data if + * the fact chunk is present and valid + * "strict" - Like "truncate", but raise an error if the fact chunk + * is invalid, not present for non-PCM formats, or if the + * data chunk doesn't have that many samples + * "ignorezero" - Like "truncate", but ignore fact chunk if the number of + * samples is zero + * "ignore" - Ignore fact chunk entirely (default) + */ +#define SDL_HINT_WAVE_FACT_CHUNK "SDL_WAVE_FACT_CHUNK" + +/** + * \brief Controls how the size of the RIFF chunk affects the loading of a WAVE file. + * + * The size of the RIFF chunk (which includes all the sub-chunks of the WAVE + * file) is not always reliable. In case the size is wrong, it's possible to + * just ignore it and step through the chunks until a fixed limit is reached. + * + * Note that files that have trailing data unrelated to the WAVE file or + * corrupt files may slow down the loading process without a reliable boundary. + * By default, SDL stops after 10000 chunks to prevent wasting time. Use the + * environment variable SDL_WAVE_CHUNK_LIMIT to adjust this value. + * + * This variable can be set to the following values: + * + * "force" - Always use the RIFF chunk size as a boundary for the chunk search + * "ignorezero" - Like "force", but a zero size searches up to 4 GiB (default) + * "ignore" - Ignore the RIFF chunk size and always search up to 4 GiB + * "maximum" - Search for chunks until the end of file (not recommended) + */ +#define SDL_HINT_WAVE_RIFF_CHUNK_SIZE "SDL_WAVE_RIFF_CHUNK_SIZE" + +/** + * \brief Controls how a truncated WAVE file is handled. + * + * A WAVE file is considered truncated if any of the chunks are incomplete or + * the data chunk size is not a multiple of the block size. By default, SDL + * decodes until the first incomplete block, as most applications seem to do. + * + * This variable can be set to the following values: + * + * "verystrict" - Raise an error if the file is truncated + * "strict" - Like "verystrict", but the size of the RIFF chunk is ignored + * "dropframe" - Decode until the first incomplete sample frame + * "dropblock" - Decode until the first incomplete block (default) + */ +#define SDL_HINT_WAVE_TRUNCATION "SDL_WAVE_TRUNCATION" + +/** + * \brief Tell SDL not to name threads on Windows with the 0x406D1388 Exception. + * The 0x406D1388 Exception is a trick used to inform Visual Studio of a + * thread's name, but it tends to cause problems with other debuggers, + * and the .NET runtime. Note that SDL 2.0.6 and later will still use + * the (safer) SetThreadDescription API, introduced in the Windows 10 + * Creators Update, if available. + * + * The variable can be set to the following values: + * "0" - SDL will raise the 0x406D1388 Exception to name threads. + * This is the default behavior of SDL <= 2.0.4. + * "1" - SDL will not raise this exception, and threads will be unnamed. (default) + * This is necessary with .NET languages or debuggers that aren't Visual Studio. + */ +#define SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING "SDL_WINDOWS_DISABLE_THREAD_NAMING" + +/** + * \brief Controls whether menus can be opened with their keyboard shortcut (Alt+mnemonic). + * + * If the mnemonics are enabled, then menus can be opened by pressing the Alt + * key and the corresponding mnemonic (for example, Alt+F opens the File menu). + * However, in case an invalid mnemonic is pressed, Windows makes an audible + * beep to convey that nothing happened. This is true even if the window has + * no menu at all! + * + * Because most SDL applications don't have menus, and some want to use the Alt + * key for other purposes, SDL disables mnemonics (and the beeping) by default. + * + * Note: This also affects keyboard events: with mnemonics enabled, when a + * menu is opened from the keyboard, you will not receive a KEYUP event for + * the mnemonic key, and *might* not receive one for Alt. + * + * This variable can be set to the following values: + * "0" - Alt+mnemonic does nothing, no beeping. (default) + * "1" - Alt+mnemonic opens menus, invalid mnemonics produce a beep. + */ +#define SDL_HINT_WINDOWS_ENABLE_MENU_MNEMONICS "SDL_WINDOWS_ENABLE_MENU_MNEMONICS" + +/** + * \brief A variable controlling whether the windows message loop is processed by SDL + * + * This variable can be set to the following values: + * "0" - The window message loop is not run + * "1" - The window message loop is processed in SDL_PumpEvents() + * + * By default SDL will process the windows message loop + */ +#define SDL_HINT_WINDOWS_ENABLE_MESSAGELOOP "SDL_WINDOWS_ENABLE_MESSAGELOOP" + +/** + * \brief Force SDL to use Critical Sections for mutexes on Windows. + * On Windows 7 and newer, Slim Reader/Writer Locks are available. + * They offer better performance, allocate no kernel ressources and + * use less memory. SDL will fall back to Critical Sections on older + * OS versions or if forced to by this hint. + * + * This variable can be set to the following values: + * "0" - Use SRW Locks when available. If not, fall back to Critical Sections. (default) + * "1" - Force the use of Critical Sections in all cases. + * + */ +#define SDL_HINT_WINDOWS_FORCE_MUTEX_CRITICAL_SECTIONS "SDL_WINDOWS_FORCE_MUTEX_CRITICAL_SECTIONS" + +/** + * \brief Force SDL to use Kernel Semaphores on Windows. + * Kernel Semaphores are inter-process and require a context + * switch on every interaction. On Windows 8 and newer, the + * WaitOnAddress API is available. Using that and atomics to + * implement semaphores increases performance. + * SDL will fall back to Kernel Objects on older OS versions + * or if forced to by this hint. + * + * This variable can be set to the following values: + * "0" - Use Atomics and WaitOnAddress API when available. If not, fall back to Kernel Objects. (default) + * "1" - Force the use of Kernel Objects in all cases. + * + */ +#define SDL_HINT_WINDOWS_FORCE_SEMAPHORE_KERNEL "SDL_WINDOWS_FORCE_SEMAPHORE_KERNEL" + +/** + * \brief A variable to specify custom icon resource id from RC file on Windows platform + */ +#define SDL_HINT_WINDOWS_INTRESOURCE_ICON "SDL_WINDOWS_INTRESOURCE_ICON" +#define SDL_HINT_WINDOWS_INTRESOURCE_ICON_SMALL "SDL_WINDOWS_INTRESOURCE_ICON_SMALL" + +/** + * \brief Tell SDL not to generate window-close events for Alt+F4 on Windows. + * + * The variable can be set to the following values: + * "0" - SDL will generate a window-close event when it sees Alt+F4. + * "1" - SDL will only do normal key handling for Alt+F4. + */ +#define SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4 "SDL_WINDOWS_NO_CLOSE_ON_ALT_F4" + +/** + * \brief Use the D3D9Ex API introduced in Windows Vista, instead of normal D3D9. + * Direct3D 9Ex contains changes to state management that can eliminate device + * loss errors during scenarios like Alt+Tab or UAC prompts. D3D9Ex may require + * some changes to your application to cope with the new behavior, so this + * is disabled by default. + * + * This hint must be set before initializing the video subsystem. + * + * For more information on Direct3D 9Ex, see: + * - https://docs.microsoft.com/en-us/windows/win32/direct3darticles/graphics-apis-in-windows-vista#direct3d-9ex + * - https://docs.microsoft.com/en-us/windows/win32/direct3darticles/direct3d-9ex-improvements + * + * This variable can be set to the following values: + * "0" - Use the original Direct3D 9 API (default) + * "1" - Use the Direct3D 9Ex API on Vista and later (and fall back if D3D9Ex is unavailable) + * + */ +#define SDL_HINT_WINDOWS_USE_D3D9EX "SDL_WINDOWS_USE_D3D9EX" + +/** + * \brief Controls whether SDL will declare the process to be DPI aware. + * + * This hint must be set before initializing the video subsystem. + * + * The main purpose of declaring DPI awareness is to disable OS bitmap scaling of SDL windows on monitors with + * a DPI scale factor. + * + * This hint is equivalent to requesting DPI awareness via external means (e.g. calling SetProcessDpiAwarenessContext) + * and does not cause SDL to use a virtualized coordinate system, so it will generally give you 1 SDL coordinate = 1 pixel + * even on high-DPI displays. + * + * For more information, see: + * https://docs.microsoft.com/en-us/windows/win32/hidpi/high-dpi-desktop-application-development-on-windows + * + * This variable can be set to the following values: + * "" - Do not change the DPI awareness (default). + * "unaware" - Declare the process as DPI unaware. (Windows 8.1 and later). + * "system" - Request system DPI awareness. (Vista and later). + * "permonitor" - Request per-monitor DPI awareness. (Windows 8.1 and later). + * "permonitorv2" - Request per-monitor V2 DPI awareness. (Windows 10, version 1607 and later). + * The most visible difference from "permonitor" is that window title bar will be scaled + * to the visually correct size when dragging between monitors with different scale factors. + * This is the preferred DPI awareness level. + * + * If the requested DPI awareness is not available on the currently running OS, SDL will try to request the best + * available match. + */ +#define SDL_HINT_WINDOWS_DPI_AWARENESS "SDL_WINDOWS_DPI_AWARENESS" + +/** + * \brief Uses DPI-scaled points as the SDL coordinate system on Windows. + * + * This changes the SDL coordinate system units to be DPI-scaled points, rather than pixels everywhere. + * This means windows will be appropriately sized, even when created on high-DPI displays with scaling. + * + * e.g. requesting a 640x480 window from SDL, on a display with 125% scaling in Windows display settings, + * will create a window with an 800x600 client area (in pixels). + * + * Setting this to "1" implicitly requests process DPI awareness (setting SDL_WINDOWS_DPI_AWARENESS is unnecessary), + * and forces SDL_WINDOW_ALLOW_HIGHDPI on all windows. + * + * This variable can be set to the following values: + * "0" - SDL coordinates equal Windows coordinates. No automatic window resizing when dragging + * between monitors with different scale factors (unless this is performed by + * Windows itself, which is the case when the process is DPI unaware). + * "1" - SDL coordinates are in DPI-scaled points. Automatically resize windows as needed on + * displays with non-100% scale factors. + */ +#define SDL_HINT_WINDOWS_DPI_SCALING "SDL_WINDOWS_DPI_SCALING" + +/** + * \brief A variable controlling whether the window frame and title bar are interactive when the cursor is hidden + * + * This variable can be set to the following values: + * "0" - The window frame is not interactive when the cursor is hidden (no move, resize, etc) + * "1" - The window frame is interactive when the cursor is hidden + * + * By default SDL will allow interaction with the window frame when the cursor is hidden + */ +#define SDL_HINT_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN "SDL_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN" + +/** +* \brief A variable controlling whether the window is activated when the SDL_ShowWindow function is called +* +* This variable can be set to the following values: +* "0" - The window is activated when the SDL_ShowWindow function is called +* "1" - The window is not activated when the SDL_ShowWindow function is called +* +* By default SDL will activate the window when the SDL_ShowWindow function is called +*/ +#define SDL_HINT_WINDOW_NO_ACTIVATION_WHEN_SHOWN "SDL_WINDOW_NO_ACTIVATION_WHEN_SHOWN" + +/** \brief Allows back-button-press events on Windows Phone to be marked as handled + * + * Windows Phone devices typically feature a Back button. When pressed, + * the OS will emit back-button-press events, which apps are expected to + * handle in an appropriate manner. If apps do not explicitly mark these + * events as 'Handled', then the OS will invoke its default behavior for + * unhandled back-button-press events, which on Windows Phone 8 and 8.1 is to + * terminate the app (and attempt to switch to the previous app, or to the + * device's home screen). + * + * Setting the SDL_HINT_WINRT_HANDLE_BACK_BUTTON hint to "1" will cause SDL + * to mark back-button-press events as Handled, if and when one is sent to + * the app. + * + * Internally, Windows Phone sends back button events as parameters to + * special back-button-press callback functions. Apps that need to respond + * to back-button-press events are expected to register one or more + * callback functions for such, shortly after being launched (during the + * app's initialization phase). After the back button is pressed, the OS + * will invoke these callbacks. If the app's callback(s) do not explicitly + * mark the event as handled by the time they return, or if the app never + * registers one of these callback, the OS will consider the event + * un-handled, and it will apply its default back button behavior (terminate + * the app). + * + * SDL registers its own back-button-press callback with the Windows Phone + * OS. This callback will emit a pair of SDL key-press events (SDL_KEYDOWN + * and SDL_KEYUP), each with a scancode of SDL_SCANCODE_AC_BACK, after which + * it will check the contents of the hint, SDL_HINT_WINRT_HANDLE_BACK_BUTTON. + * If the hint's value is set to "1", the back button event's Handled + * property will get set to 'true'. If the hint's value is set to something + * else, or if it is unset, SDL will leave the event's Handled property + * alone. (By default, the OS sets this property to 'false', to note.) + * + * SDL apps can either set SDL_HINT_WINRT_HANDLE_BACK_BUTTON well before a + * back button is pressed, or can set it in direct-response to a back button + * being pressed. + * + * In order to get notified when a back button is pressed, SDL apps should + * register a callback function with SDL_AddEventWatch(), and have it listen + * for SDL_KEYDOWN events that have a scancode of SDL_SCANCODE_AC_BACK. + * (Alternatively, SDL_KEYUP events can be listened-for. Listening for + * either event type is suitable.) Any value of SDL_HINT_WINRT_HANDLE_BACK_BUTTON + * set by such a callback, will be applied to the OS' current + * back-button-press event. + * + * More details on back button behavior in Windows Phone apps can be found + * at the following page, on Microsoft's developer site: + * http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj247550(v=vs.105).aspx + */ +#define SDL_HINT_WINRT_HANDLE_BACK_BUTTON "SDL_WINRT_HANDLE_BACK_BUTTON" + +/** \brief Label text for a WinRT app's privacy policy link + * + * Network-enabled WinRT apps must include a privacy policy. On Windows 8, 8.1, and RT, + * Microsoft mandates that this policy be available via the Windows Settings charm. + * SDL provides code to add a link there, with its label text being set via the + * optional hint, SDL_HINT_WINRT_PRIVACY_POLICY_LABEL. + * + * Please note that a privacy policy's contents are not set via this hint. A separate + * hint, SDL_HINT_WINRT_PRIVACY_POLICY_URL, is used to link to the actual text of the + * policy. + * + * The contents of this hint should be encoded as a UTF8 string. + * + * The default value is "Privacy Policy". This hint should only be set during app + * initialization, preferably before any calls to SDL_Init(). + * + * For additional information on linking to a privacy policy, see the documentation for + * SDL_HINT_WINRT_PRIVACY_POLICY_URL. + */ +#define SDL_HINT_WINRT_PRIVACY_POLICY_LABEL "SDL_WINRT_PRIVACY_POLICY_LABEL" + +/** + * \brief A URL to a WinRT app's privacy policy + * + * All network-enabled WinRT apps must make a privacy policy available to its + * users. On Windows 8, 8.1, and RT, Microsoft mandates that this policy be + * be available in the Windows Settings charm, as accessed from within the app. + * SDL provides code to add a URL-based link there, which can point to the app's + * privacy policy. + * + * To setup a URL to an app's privacy policy, set SDL_HINT_WINRT_PRIVACY_POLICY_URL + * before calling any SDL_Init() functions. The contents of the hint should + * be a valid URL. For example, "http://www.example.com". + * + * The default value is "", which will prevent SDL from adding a privacy policy + * link to the Settings charm. This hint should only be set during app init. + * + * The label text of an app's "Privacy Policy" link may be customized via another + * hint, SDL_HINT_WINRT_PRIVACY_POLICY_LABEL. + * + * Please note that on Windows Phone, Microsoft does not provide standard UI + * for displaying a privacy policy link, and as such, SDL_HINT_WINRT_PRIVACY_POLICY_URL + * will not get used on that platform. Network-enabled phone apps should display + * their privacy policy through some other, in-app means. + */ +#define SDL_HINT_WINRT_PRIVACY_POLICY_URL "SDL_WINRT_PRIVACY_POLICY_URL" + +/** + * \brief Mark X11 windows as override-redirect. + * + * If set, this _might_ increase framerate at the expense of the desktop + * not working as expected. Override-redirect windows aren't noticed by the + * window manager at all. + * + * You should probably only use this for fullscreen windows, and you probably + * shouldn't even use it for that. But it's here if you want to try! + */ +#define SDL_HINT_X11_FORCE_OVERRIDE_REDIRECT "SDL_X11_FORCE_OVERRIDE_REDIRECT" + +/** + * \brief A variable that lets you disable the detection and use of Xinput gamepad devices + * + * The variable can be set to the following values: + * "0" - Disable XInput detection (only uses direct input) + * "1" - Enable XInput detection (the default) + */ +#define SDL_HINT_XINPUT_ENABLED "SDL_XINPUT_ENABLED" + + /** + * \brief A variable that lets you disable the detection and use of DirectInput gamepad devices + * + * The variable can be set to the following values: + * "0" - Disable DirectInput detection (only uses XInput) + * "1" - Enable DirectInput detection (the default) + */ +#define SDL_HINT_DIRECTINPUT_ENABLED "SDL_DIRECTINPUT_ENABLED" + +/** + * \brief A variable that causes SDL to use the old axis and button mapping for XInput devices. + * + * This hint is for backwards compatibility only and will be removed in SDL 2.1 + * + * The default value is "0". This hint must be set before SDL_Init() + */ +#define SDL_HINT_XINPUT_USE_OLD_JOYSTICK_MAPPING "SDL_XINPUT_USE_OLD_JOYSTICK_MAPPING" + +/** + * \brief A variable that causes SDL to not ignore audio "monitors" + * + * This is currently only used for PulseAudio and ignored elsewhere. + * + * By default, SDL ignores audio devices that aren't associated with physical + * hardware. Changing this hint to "1" will expose anything SDL sees that + * appears to be an audio source or sink. This will add "devices" to the list + * that the user probably doesn't want or need, but it can be useful in + * scenarios where you want to hook up SDL to some sort of virtual device, + * etc. + * + * The default value is "0". This hint must be set before SDL_Init(). + * + * This hint is available since SDL 2.0.16. Before then, virtual devices are + * always ignored. + */ +#define SDL_HINT_AUDIO_INCLUDE_MONITORS "SDL_AUDIO_INCLUDE_MONITORS" + +/** + * \brief A variable that forces X11 windows to create as a custom type. + * + * This is currently only used for X11 and ignored elsewhere. + * + * During SDL_CreateWindow, SDL uses the _NET_WM_WINDOW_TYPE X11 property + * to report to the window manager the type of window it wants to create. + * This might be set to various things if SDL_WINDOW_TOOLTIP or + * SDL_WINDOW_POPUP_MENU, etc, were specified. For "normal" windows that + * haven't set a specific type, this hint can be used to specify a custom + * type. For example, a dock window might set this to + * "_NET_WM_WINDOW_TYPE_DOCK". + * + * If not set or set to "", this hint is ignored. This hint must be set + * before the SDL_CreateWindow() call that it is intended to affect. + * + * This hint is available since SDL 2.0.22. + */ +#define SDL_HINT_X11_WINDOW_TYPE "SDL_X11_WINDOW_TYPE" + +/** + * \brief A variable that decides whether to send SDL_QUIT when closing the final window. + * + * By default, SDL sends an SDL_QUIT event when there is only one window + * and it receives an SDL_WINDOWEVENT_CLOSE event, under the assumption most + * apps would also take the loss of this window as a signal to terminate the + * program. + * + * However, it's not unreasonable in some cases to have the program continue + * to live on, perhaps to create new windows later. + * + * Changing this hint to "0" will cause SDL to not send an SDL_QUIT event + * when the final window is requesting to close. Note that in this case, + * there are still other legitimate reasons one might get an SDL_QUIT + * event: choosing "Quit" from the macOS menu bar, sending a SIGINT (ctrl-c) + * on Unix, etc. + * + * The default value is "1". This hint can be changed at any time. + * + * This hint is available since SDL 2.0.22. Before then, you always get + * an SDL_QUIT event when closing the final window. + */ +#define SDL_HINT_QUIT_ON_LAST_WINDOW_CLOSE "SDL_QUIT_ON_LAST_WINDOW_CLOSE" + + +/** + * \brief A variable that decides what video backend to use. + * + * By default, SDL will try all available video backends in a reasonable + * order until it finds one that can work, but this hint allows the app + * or user to force a specific target, such as "x11" if, say, you are + * on Wayland but want to try talking to the X server instead. + * + * This functionality has existed since SDL 2.0.0 (indeed, before that) + * but before 2.0.22 this was an environment variable only. In 2.0.22, + * it was upgraded to a full SDL hint, so you can set the environment + * variable as usual or programatically set the hint with SDL_SetHint, + * which won't propagate to child processes. + * + * The default value is unset, in which case SDL will try to figure out + * the best video backend on your behalf. This hint needs to be set + * before SDL_Init() is called to be useful. + * + * This hint is available since SDL 2.0.22. Before then, you could set + * the environment variable to get the same effect. + */ +#define SDL_HINT_VIDEODRIVER "SDL_VIDEODRIVER" + +/** + * \brief A variable that decides what audio backend to use. + * + * By default, SDL will try all available audio backends in a reasonable + * order until it finds one that can work, but this hint allows the app + * or user to force a specific target, such as "alsa" if, say, you are + * on PulseAudio but want to try talking to the lower level instead. + * + * This functionality has existed since SDL 2.0.0 (indeed, before that) + * but before 2.0.22 this was an environment variable only. In 2.0.22, + * it was upgraded to a full SDL hint, so you can set the environment + * variable as usual or programatically set the hint with SDL_SetHint, + * which won't propagate to child processes. + * + * The default value is unset, in which case SDL will try to figure out + * the best audio backend on your behalf. This hint needs to be set + * before SDL_Init() is called to be useful. + * + * This hint is available since SDL 2.0.22. Before then, you could set + * the environment variable to get the same effect. + */ +#define SDL_HINT_AUDIODRIVER "SDL_AUDIODRIVER" + +/** + * \brief A variable that decides what KMSDRM device to use. + * + * Internally, SDL might open something like "/dev/dri/cardNN" to + * access KMSDRM functionality, where "NN" is a device index number. + * + * SDL makes a guess at the best index to use (usually zero), but the + * app or user can set this hint to a number between 0 and 99 to + * force selection. + * + * This hint is available since SDL 2.24.0. + */ +#define SDL_HINT_KMSDRM_DEVICE_INDEX "SDL_KMSDRM_DEVICE_INDEX" + + +/** + * \brief A variable that treats trackpads as touch devices. + * + * On macOS (and possibly other platforms in the future), SDL will report + * touches on a trackpad as mouse input, which is generally what users + * expect from this device; however, these are often actually full + * multitouch-capable touch devices, so it might be preferable to some apps + * to treat them as such. + * + * Setting this hint to true will make the trackpad input report as a + * multitouch device instead of a mouse. The default is false. + * + * Note that most platforms don't support this hint. As of 2.24.0, it + * only supports MacBooks' trackpads on macOS. Others may follow later. + * + * This hint is checked during SDL_Init and can not be changed after. + * + * This hint is available since SDL 2.24.0. + */ +#define SDL_HINT_TRACKPAD_IS_TOUCH_ONLY "SDL_TRACKPAD_IS_TOUCH_ONLY" + +/** + * Cause SDL to call dbus_shutdown() on quit. + * + * This is useful as a debug tool to validate memory leaks, but shouldn't ever + * be set in production applications, as other libraries used by the application + * might use dbus under the hood and this cause cause crashes if they continue + * after SDL_Quit(). + * + * This variable can be set to the following values: + * "0" - SDL will not call dbus_shutdown() on quit (default) + * "1" - SDL will call dbus_shutdown() on quit + * + * This hint is available since SDL 2.30.0. + */ +#define SDL_HINT_SHUTDOWN_DBUS_ON_QUIT "SDL_SHUTDOWN_DBUS_ON_QUIT" + + +/** + * \brief An enumeration of hint priorities + */ +typedef enum +{ + SDL_HINT_DEFAULT, + SDL_HINT_NORMAL, + SDL_HINT_OVERRIDE +} SDL_HintPriority; + + +/** + * Set a hint with a specific priority. + * + * The priority controls the behavior when setting a hint that already has a + * value. Hints will replace existing hints of their priority and lower. + * Environment variables are considered to have override priority. + * + * \param name the hint to set + * \param value the value of the hint variable + * \param priority the SDL_HintPriority level for the hint + * \returns SDL_TRUE if the hint was set, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetHint + * \sa SDL_SetHint + */ +extern DECLSPEC SDL_bool SDLCALL SDL_SetHintWithPriority(const char *name, + const char *value, + SDL_HintPriority priority); + +/** + * Set a hint with normal priority. + * + * Hints will not be set if there is an existing override hint or environment + * variable that takes precedence. You can use SDL_SetHintWithPriority() to + * set the hint with override priority instead. + * + * \param name the hint to set + * \param value the value of the hint variable + * \returns SDL_TRUE if the hint was set, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetHint + * \sa SDL_SetHintWithPriority + */ +extern DECLSPEC SDL_bool SDLCALL SDL_SetHint(const char *name, + const char *value); + +/** + * Reset a hint to the default value. + * + * This will reset a hint to the value of the environment variable, or NULL if + * the environment isn't set. Callbacks will be called normally with this + * change. + * + * \param name the hint to set + * \returns SDL_TRUE if the hint was set, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.24.0. + * + * \sa SDL_GetHint + * \sa SDL_SetHint + */ +extern DECLSPEC SDL_bool SDLCALL SDL_ResetHint(const char *name); + +/** + * Reset all hints to the default values. + * + * This will reset all hints to the value of the associated environment + * variable, or NULL if the environment isn't set. Callbacks will be called + * normally with this change. + * + * \since This function is available since SDL 2.26.0. + * + * \sa SDL_GetHint + * \sa SDL_SetHint + * \sa SDL_ResetHint + */ +extern DECLSPEC void SDLCALL SDL_ResetHints(void); + +/** + * Get the value of a hint. + * + * \param name the hint to query + * \returns the string value of a hint or NULL if the hint isn't set. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetHint + * \sa SDL_SetHintWithPriority + */ +extern DECLSPEC const char * SDLCALL SDL_GetHint(const char *name); + +/** + * Get the boolean value of a hint variable. + * + * \param name the name of the hint to get the boolean value from + * \param default_value the value to return if the hint does not exist + * \returns the boolean value of a hint or the provided default value if the + * hint does not exist. + * + * \since This function is available since SDL 2.0.5. + * + * \sa SDL_GetHint + * \sa SDL_SetHint + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GetHintBoolean(const char *name, SDL_bool default_value); + +/** + * Type definition of the hint callback function. + * + * \param userdata what was passed as `userdata` to SDL_AddHintCallback() + * \param name what was passed as `name` to SDL_AddHintCallback() + * \param oldValue the previous hint value + * \param newValue the new value hint is to be set to + */ +typedef void (SDLCALL *SDL_HintCallback)(void *userdata, const char *name, const char *oldValue, const char *newValue); + +/** + * Add a function to watch a particular hint. + * + * \param name the hint to watch + * \param callback An SDL_HintCallback function that will be called when the + * hint value changes + * \param userdata a pointer to pass to the callback function + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_DelHintCallback + */ +extern DECLSPEC void SDLCALL SDL_AddHintCallback(const char *name, + SDL_HintCallback callback, + void *userdata); + +/** + * Remove a function watching a particular hint. + * + * \param name the hint being watched + * \param callback An SDL_HintCallback function that will be called when the + * hint value changes + * \param userdata a pointer being passed to the callback function + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AddHintCallback + */ +extern DECLSPEC void SDLCALL SDL_DelHintCallback(const char *name, + SDL_HintCallback callback, + void *userdata); + +/** + * Clear all hints. + * + * This function is automatically called during SDL_Quit(), and deletes all + * callbacks without calling them and frees all memory associated with hints. + * If you're calling this from application code you probably want to call + * SDL_ResetHints() instead. + * + * This function will be removed from the API the next time we rev the ABI. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ResetHints + */ +extern DECLSPEC void SDLCALL SDL_ClearHints(void); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_hints_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/include/SDL_joystick.h b/SDL2-2.30.5/include/SDL_joystick.h new file mode 100644 index 0000000..7a3faf8 --- /dev/null +++ b/SDL2-2.30.5/include/SDL_joystick.h @@ -0,0 +1,1074 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_joystick.h + * + * Include file for SDL joystick event handling + * + * The term "device_index" identifies currently plugged in joystick devices between 0 and SDL_NumJoysticks(), with the exact joystick + * behind a device_index changing as joysticks are plugged and unplugged. + * + * The term "instance_id" is the current instantiation of a joystick device in the system, if the joystick is removed and then re-inserted + * then it will get a new instance_id, instance_id's are monotonically increasing identifiers of a joystick plugged in. + * + * The term "player_index" is the number assigned to a player on a specific + * controller. For XInput controllers this returns the XInput user index. + * Many joysticks will not be able to supply this information. + * + * The term JoystickGUID is a stable 128-bit identifier for a joystick device that does not change over time, it identifies class of + * the device (a X360 wired controller for example). This identifier is platform dependent. + */ + +#ifndef SDL_joystick_h_ +#define SDL_joystick_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_guid.h" +#include "SDL_mutex.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \file SDL_joystick.h + * + * In order to use these functions, SDL_Init() must have been called + * with the ::SDL_INIT_JOYSTICK flag. This causes SDL to scan the system + * for joysticks, and load appropriate drivers. + * + * If you would like to receive joystick updates while the application + * is in the background, you should set the following hint before calling + * SDL_Init(): SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS + */ + +/** + * The joystick structure used to identify an SDL joystick + */ +#ifdef SDL_THREAD_SAFETY_ANALYSIS +extern SDL_mutex *SDL_joystick_lock; +#endif +struct _SDL_Joystick; +typedef struct _SDL_Joystick SDL_Joystick; + +/* A structure that encodes the stable unique id for a joystick device */ +typedef SDL_GUID SDL_JoystickGUID; + +/** + * This is a unique ID for a joystick for the time it is connected to the system, + * and is never reused for the lifetime of the application. If the joystick is + * disconnected and reconnected, it will get a new ID. + * + * The ID value starts at 0 and increments from there. The value -1 is an invalid ID. + */ +typedef Sint32 SDL_JoystickID; + +typedef enum +{ + SDL_JOYSTICK_TYPE_UNKNOWN, + SDL_JOYSTICK_TYPE_GAMECONTROLLER, + SDL_JOYSTICK_TYPE_WHEEL, + SDL_JOYSTICK_TYPE_ARCADE_STICK, + SDL_JOYSTICK_TYPE_FLIGHT_STICK, + SDL_JOYSTICK_TYPE_DANCE_PAD, + SDL_JOYSTICK_TYPE_GUITAR, + SDL_JOYSTICK_TYPE_DRUM_KIT, + SDL_JOYSTICK_TYPE_ARCADE_PAD, + SDL_JOYSTICK_TYPE_THROTTLE +} SDL_JoystickType; + +typedef enum +{ + SDL_JOYSTICK_POWER_UNKNOWN = -1, + SDL_JOYSTICK_POWER_EMPTY, /* <= 5% */ + SDL_JOYSTICK_POWER_LOW, /* <= 20% */ + SDL_JOYSTICK_POWER_MEDIUM, /* <= 70% */ + SDL_JOYSTICK_POWER_FULL, /* <= 100% */ + SDL_JOYSTICK_POWER_WIRED, + SDL_JOYSTICK_POWER_MAX +} SDL_JoystickPowerLevel; + +/* Set max recognized G-force from accelerometer + See src/joystick/uikit/SDL_sysjoystick.m for notes on why this is needed + */ +#define SDL_IPHONE_MAX_GFORCE 5.0 + + +/* 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. + * + * As of SDL 2.26.0, you can take the joystick lock around reinitializing the + * joystick subsystem, to prevent other threads from seeing joysticks in an + * uninitialized state. However, all open joysticks will be closed and SDL + * functions called with them will fail. + * + * \since This function is available since SDL 2.0.7. + */ +extern DECLSPEC void SDLCALL SDL_LockJoysticks(void) SDL_ACQUIRE(SDL_joystick_lock); + + +/** + * Unlocking 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. + * + * \since This function is available since SDL 2.0.7. + */ +extern DECLSPEC void SDLCALL SDL_UnlockJoysticks(void) SDL_RELEASE(SDL_joystick_lock); + +/** + * Count the number of joysticks attached to the system. + * + * \returns the number of attached joysticks on success or a negative error + * code on failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickName + * \sa SDL_JoystickPath + * \sa SDL_JoystickOpen + */ +extern DECLSPEC int SDLCALL SDL_NumJoysticks(void); + +/** + * Get the implementation dependent name of a joystick. + * + * This can be called before any joysticks are opened. + * + * \param device_index the index of the joystick to query (the N'th joystick + * on the system) + * \returns the name of the selected joystick. If no name can be found, this + * function returns NULL; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickName + * \sa SDL_JoystickOpen + */ +extern DECLSPEC const char *SDLCALL SDL_JoystickNameForIndex(int device_index); + +/** + * Get the implementation dependent path of a joystick. + * + * This can be called before any joysticks are opened. + * + * \param device_index the index of the joystick to query (the N'th joystick + * on the system) + * \returns the path of the selected joystick. If no path can be found, this + * function returns NULL; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.24.0. + * + * \sa SDL_JoystickPath + * \sa SDL_JoystickOpen + */ +extern DECLSPEC const char *SDLCALL SDL_JoystickPathForIndex(int device_index); + +/** + * Get the player index of a joystick, or -1 if it's not available This can be + * called before any joysticks are opened. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC int SDLCALL SDL_JoystickGetDevicePlayerIndex(int device_index); + +/** + * Get the implementation-dependent GUID for the joystick at a given device + * index. + * + * This function can be called before any joysticks are opened. + * + * \param device_index the index of the joystick to query (the N'th joystick + * on the system + * \returns the GUID of the selected joystick. If called on an invalid index, + * this function returns a zero GUID + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickGetGUID + * \sa SDL_JoystickGetGUIDString + */ +extern DECLSPEC SDL_JoystickGUID SDLCALL SDL_JoystickGetDeviceGUID(int device_index); + +/** + * Get the USB vendor ID of a joystick, if available. + * + * This can be called before any joysticks are opened. If the vendor ID isn't + * available this function returns 0. + * + * \param device_index the index of the joystick to query (the N'th joystick + * on the system + * \returns the USB vendor ID of the selected joystick. If called on an + * invalid index, this function returns zero + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC Uint16 SDLCALL SDL_JoystickGetDeviceVendor(int device_index); + +/** + * Get the USB product ID of a joystick, if available. + * + * This can be called before any joysticks are opened. If the product ID isn't + * available this function returns 0. + * + * \param device_index the index of the joystick to query (the N'th joystick + * on the system + * \returns the USB product ID of the selected joystick. If called on an + * invalid index, this function returns zero + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC Uint16 SDLCALL SDL_JoystickGetDeviceProduct(int device_index); + +/** + * Get the product version of a joystick, if available. + * + * This can be called before any joysticks are opened. If the product version + * isn't available this function returns 0. + * + * \param device_index the index of the joystick to query (the N'th joystick + * on the system + * \returns the product version of the selected joystick. If called on an + * invalid index, this function returns zero + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC Uint16 SDLCALL SDL_JoystickGetDeviceProductVersion(int device_index); + +/** + * Get the type of a joystick, if available. + * + * This can be called before any joysticks are opened. + * + * \param device_index the index of the joystick to query (the N'th joystick + * on the system + * \returns the SDL_JoystickType of the selected joystick. If called on an + * invalid index, this function returns `SDL_JOYSTICK_TYPE_UNKNOWN` + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC SDL_JoystickType SDLCALL SDL_JoystickGetDeviceType(int device_index); + +/** + * Get the instance ID of a joystick. + * + * This can be called before any joysticks are opened. + * + * \param device_index the index of the joystick to query (the N'th joystick + * on the system + * \returns the instance id of the selected joystick. If called on an invalid + * index, this function returns -1. + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC SDL_JoystickID SDLCALL SDL_JoystickGetDeviceInstanceID(int device_index); + +/** + * Open a joystick for use. + * + * The `device_index` argument refers to the N'th joystick presently + * recognized by SDL on the system. It is **NOT** the same as the instance ID + * used to identify the joystick in future events. See + * SDL_JoystickInstanceID() for more details about instance IDs. + * + * The joystick subsystem must be initialized before a joystick can be opened + * for use. + * + * \param device_index the index of the joystick to query + * \returns a joystick identifier or NULL if an error occurred; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickClose + * \sa SDL_JoystickInstanceID + */ +extern DECLSPEC SDL_Joystick *SDLCALL SDL_JoystickOpen(int device_index); + +/** + * Get the SDL_Joystick associated with an instance id. + * + * \param instance_id the instance id to get the SDL_Joystick for + * \returns an SDL_Joystick on success or NULL on failure; call SDL_GetError() + * for more information. + * + * \since This function is available since SDL 2.0.4. + */ +extern DECLSPEC SDL_Joystick *SDLCALL SDL_JoystickFromInstanceID(SDL_JoystickID instance_id); + +/** + * Get the SDL_Joystick associated with a player index. + * + * \param player_index the player index to get the SDL_Joystick for + * \returns an SDL_Joystick on success or NULL on failure; call SDL_GetError() + * for more information. + * + * \since This function is available since SDL 2.0.12. + */ +extern DECLSPEC SDL_Joystick *SDLCALL SDL_JoystickFromPlayerIndex(int player_index); + +/** + * Attach a new virtual joystick. + * + * \returns the joystick's device index, or -1 if an error occurred. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC int SDLCALL SDL_JoystickAttachVirtual(SDL_JoystickType type, + int naxes, + int nbuttons, + int nhats); + +/** + * The structure that defines an extended virtual joystick description + * + * The caller must zero the structure and then initialize the version with `SDL_VIRTUAL_JOYSTICK_DESC_VERSION` before passing it to SDL_JoystickAttachVirtualEx() + * All other elements of this structure are optional and can be left 0. + * + * \sa SDL_JoystickAttachVirtualEx + */ +typedef struct SDL_VirtualJoystickDesc +{ + Uint16 version; /**< `SDL_VIRTUAL_JOYSTICK_DESC_VERSION` */ + Uint16 type; /**< `SDL_JoystickType` */ + Uint16 naxes; /**< the number of axes on this joystick */ + Uint16 nbuttons; /**< the number of buttons on this joystick */ + Uint16 nhats; /**< the number of hats on this joystick */ + Uint16 vendor_id; /**< the USB vendor ID of this joystick */ + Uint16 product_id; /**< the USB product ID of this joystick */ + Uint16 padding; /**< unused */ + Uint32 button_mask; /**< A mask of which buttons are valid for this controller + e.g. (1 << SDL_CONTROLLER_BUTTON_A) */ + Uint32 axis_mask; /**< A mask of which axes are valid for this controller + e.g. (1 << SDL_CONTROLLER_AXIS_LEFTX) */ + const char *name; /**< the name of the joystick */ + + void *userdata; /**< User data pointer passed to callbacks */ + void (SDLCALL *Update)(void *userdata); /**< Called when the joystick state should be updated */ + void (SDLCALL *SetPlayerIndex)(void *userdata, int player_index); /**< Called when the player index is set */ + int (SDLCALL *Rumble)(void *userdata, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble); /**< Implements SDL_JoystickRumble() */ + int (SDLCALL *RumbleTriggers)(void *userdata, Uint16 left_rumble, Uint16 right_rumble); /**< Implements SDL_JoystickRumbleTriggers() */ + int (SDLCALL *SetLED)(void *userdata, Uint8 red, Uint8 green, Uint8 blue); /**< Implements SDL_JoystickSetLED() */ + int (SDLCALL *SendEffect)(void *userdata, const void *data, int size); /**< Implements SDL_JoystickSendEffect() */ + +} SDL_VirtualJoystickDesc; + +/** + * \brief The current version of the SDL_VirtualJoystickDesc structure + */ +#define SDL_VIRTUAL_JOYSTICK_DESC_VERSION 1 + +/** + * Attach a new virtual joystick with extended properties. + * + * \returns the joystick's device index, or -1 if an error occurred. + * + * \since This function is available since SDL 2.24.0. + */ +extern DECLSPEC int SDLCALL SDL_JoystickAttachVirtualEx(const SDL_VirtualJoystickDesc *desc); + +/** + * Detach a virtual joystick. + * + * \param device_index a value previously returned from + * SDL_JoystickAttachVirtual() + * \returns 0 on success, or -1 if an error occurred. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC int SDLCALL SDL_JoystickDetachVirtual(int device_index); + +/** + * Query whether or not the joystick at a given device index is virtual. + * + * \param device_index a joystick device index. + * \returns SDL_TRUE if the joystick is virtual, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_JoystickIsVirtual(int device_index); + +/** + * Set values on an opened, virtual-joystick's axis. + * + * Please note that values set here will not be applied until the next call to + * SDL_JoystickUpdate, which can either be called directly, or can be called + * indirectly through various other SDL APIs, including, but not limited to + * the following: SDL_PollEvent, SDL_PumpEvents, SDL_WaitEventTimeout, + * SDL_WaitEvent. + * + * Note that when sending trigger axes, you should scale the value to the full + * range of Sint16. For example, a trigger at rest would have the value of + * `SDL_JOYSTICK_AXIS_MIN`. + * + * \param joystick the virtual joystick on which to set state. + * \param axis the specific axis on the virtual joystick to set. + * \param value the new value for the specified axis. + * \returns 0 on success, -1 on error. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC int SDLCALL SDL_JoystickSetVirtualAxis(SDL_Joystick *joystick, int axis, Sint16 value); + +/** + * Set values on an opened, virtual-joystick's button. + * + * Please note that values set here will not be applied until the next call to + * SDL_JoystickUpdate, which can either be called directly, or can be called + * indirectly through various other SDL APIs, including, but not limited to + * the following: SDL_PollEvent, SDL_PumpEvents, SDL_WaitEventTimeout, + * SDL_WaitEvent. + * + * \param joystick the virtual joystick on which to set state. + * \param button the specific button on the virtual joystick to set. + * \param value the new value for the specified button. + * \returns 0 on success, -1 on error. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC int SDLCALL SDL_JoystickSetVirtualButton(SDL_Joystick *joystick, int button, Uint8 value); + +/** + * Set values on an opened, virtual-joystick's hat. + * + * Please note that values set here will not be applied until the next call to + * SDL_JoystickUpdate, which can either be called directly, or can be called + * indirectly through various other SDL APIs, including, but not limited to + * the following: SDL_PollEvent, SDL_PumpEvents, SDL_WaitEventTimeout, + * SDL_WaitEvent. + * + * \param joystick the virtual joystick on which to set state. + * \param hat the specific hat on the virtual joystick to set. + * \param value the new value for the specified hat. + * \returns 0 on success, -1 on error. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC int SDLCALL SDL_JoystickSetVirtualHat(SDL_Joystick *joystick, int hat, Uint8 value); + +/** + * Get the implementation dependent name of a joystick. + * + * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen() + * \returns the name of the selected joystick. If no name can be found, this + * function returns NULL; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickNameForIndex + * \sa SDL_JoystickOpen + */ +extern DECLSPEC const char *SDLCALL SDL_JoystickName(SDL_Joystick *joystick); + +/** + * Get the implementation dependent path of a joystick. + * + * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen() + * \returns the path of the selected joystick. If no path can be found, this + * function returns NULL; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.24.0. + * + * \sa SDL_JoystickPathForIndex + */ +extern DECLSPEC const char *SDLCALL SDL_JoystickPath(SDL_Joystick *joystick); + +/** + * Get the player index of an opened joystick. + * + * For XInput controllers this returns the XInput user index. Many joysticks + * will not be able to supply this information. + * + * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen() + * \returns the player index, or -1 if it's not available. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC int SDLCALL SDL_JoystickGetPlayerIndex(SDL_Joystick *joystick); + +/** + * Set the player index of an opened joystick. + * + * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen() + * \param player_index Player index to assign to this joystick, or -1 to clear + * the player index and turn off player LEDs. + * + * \since This function is available since SDL 2.0.12. + */ +extern DECLSPEC void SDLCALL SDL_JoystickSetPlayerIndex(SDL_Joystick *joystick, int player_index); + +/** + * Get the implementation-dependent GUID for the joystick. + * + * This function requires an open joystick. + * + * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen() + * \returns the GUID of the given joystick. If called on an invalid index, + * this function returns a zero GUID; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickGetDeviceGUID + * \sa SDL_JoystickGetGUIDString + */ +extern DECLSPEC SDL_JoystickGUID SDLCALL SDL_JoystickGetGUID(SDL_Joystick *joystick); + +/** + * Get the USB vendor ID of an opened joystick, if available. + * + * If the vendor ID isn't available this function returns 0. + * + * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen() + * \returns the USB vendor ID of the selected joystick, or 0 if unavailable. + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC Uint16 SDLCALL SDL_JoystickGetVendor(SDL_Joystick *joystick); + +/** + * Get the USB product ID of an opened joystick, if available. + * + * If the product ID isn't available this function returns 0. + * + * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen() + * \returns the USB product ID of the selected joystick, or 0 if unavailable. + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC Uint16 SDLCALL SDL_JoystickGetProduct(SDL_Joystick *joystick); + +/** + * Get the product version of an opened joystick, if available. + * + * If the product version isn't available this function returns 0. + * + * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen() + * \returns the product version of the selected joystick, or 0 if unavailable. + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC Uint16 SDLCALL SDL_JoystickGetProductVersion(SDL_Joystick *joystick); + +/** + * Get the firmware version of an opened joystick, if available. + * + * If the firmware version isn't available this function returns 0. + * + * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen() + * \returns the firmware version of the selected joystick, or 0 if + * unavailable. + * + * \since This function is available since SDL 2.24.0. + */ +extern DECLSPEC Uint16 SDLCALL SDL_JoystickGetFirmwareVersion(SDL_Joystick *joystick); + +/** + * Get the serial number of an opened joystick, if available. + * + * Returns the serial number of the joystick, or NULL if it is not available. + * + * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen() + * \returns the serial number of the selected joystick, or NULL if + * unavailable. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC const char * SDLCALL SDL_JoystickGetSerial(SDL_Joystick *joystick); + +/** + * Get the type of an opened joystick. + * + * \param joystick the SDL_Joystick obtained from SDL_JoystickOpen() + * \returns the SDL_JoystickType of the selected joystick. + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC SDL_JoystickType SDLCALL SDL_JoystickGetType(SDL_Joystick *joystick); + +/** + * Get an ASCII string representation for a given SDL_JoystickGUID. + * + * You should supply at least 33 bytes for pszGUID. + * + * \param guid the SDL_JoystickGUID you wish to convert to string + * \param pszGUID buffer in which to write the ASCII string + * \param cbGUID the size of pszGUID + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickGetDeviceGUID + * \sa SDL_JoystickGetGUID + * \sa SDL_JoystickGetGUIDFromString + */ +extern DECLSPEC void SDLCALL SDL_JoystickGetGUIDString(SDL_JoystickGUID guid, char *pszGUID, int cbGUID); + +/** + * Convert a GUID string into a SDL_JoystickGUID structure. + * + * Performs no error checking. If this function is given a string containing + * an invalid GUID, the function will silently succeed, but the GUID generated + * will not be useful. + * + * \param pchGUID string containing an ASCII representation of a GUID + * \returns a SDL_JoystickGUID structure. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickGetGUIDString + */ +extern DECLSPEC SDL_JoystickGUID SDLCALL SDL_JoystickGetGUIDFromString(const char *pchGUID); + +/** + * Get the device information encoded in a SDL_JoystickGUID structure + * + * \param guid the SDL_JoystickGUID you wish to get info about + * \param vendor A pointer filled in with the device VID, or 0 if not + * available + * \param product A pointer filled in with the device PID, or 0 if not + * available + * \param version A pointer filled in with the device version, or 0 if not + * available + * \param crc16 A pointer filled in with a CRC used to distinguish different + * products with the same VID/PID, or 0 if not available + * + * \since This function is available since SDL 2.26.0. + * + * \sa SDL_JoystickGetDeviceGUID + */ +extern DECLSPEC void SDLCALL SDL_GetJoystickGUIDInfo(SDL_JoystickGUID guid, Uint16 *vendor, Uint16 *product, Uint16 *version, Uint16 *crc16); + +/** + * Get the status of a specified joystick. + * + * \param joystick the joystick to query + * \returns SDL_TRUE if the joystick has been opened, SDL_FALSE if it has not; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickClose + * \sa SDL_JoystickOpen + */ +extern DECLSPEC SDL_bool SDLCALL SDL_JoystickGetAttached(SDL_Joystick *joystick); + +/** + * Get the instance ID of an opened joystick. + * + * \param joystick an SDL_Joystick structure containing joystick information + * \returns the instance ID of the specified joystick on success or a negative + * error code on failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickOpen + */ +extern DECLSPEC SDL_JoystickID SDLCALL SDL_JoystickInstanceID(SDL_Joystick *joystick); + +/** + * Get the number of general axis controls on a joystick. + * + * Often, the directional pad on a game controller will either look like 4 + * separate buttons or a POV hat, and not axes, but all of this is up to the + * device and platform. + * + * \param joystick an SDL_Joystick structure containing joystick information + * \returns the number of axis controls/number of axes on success or a + * negative error code on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickGetAxis + * \sa SDL_JoystickOpen + */ +extern DECLSPEC int SDLCALL SDL_JoystickNumAxes(SDL_Joystick *joystick); + +/** + * Get the number of trackballs on a joystick. + * + * Joystick trackballs have only relative motion events associated with them + * and their state cannot be polled. + * + * Most joysticks do not have trackballs. + * + * \param joystick an SDL_Joystick structure containing joystick information + * \returns the number of trackballs on success or a negative error code on + * failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickGetBall + */ +extern DECLSPEC int SDLCALL SDL_JoystickNumBalls(SDL_Joystick *joystick); + +/** + * Get the number of POV hats on a joystick. + * + * \param joystick an SDL_Joystick structure containing joystick information + * \returns the number of POV hats on success or a negative error code on + * failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickGetHat + * \sa SDL_JoystickOpen + */ +extern DECLSPEC int SDLCALL SDL_JoystickNumHats(SDL_Joystick *joystick); + +/** + * Get the number of buttons on a joystick. + * + * \param joystick an SDL_Joystick structure containing joystick information + * \returns the number of buttons on success or a negative error code on + * failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickGetButton + * \sa SDL_JoystickOpen + */ +extern DECLSPEC int SDLCALL SDL_JoystickNumButtons(SDL_Joystick *joystick); + +/** + * Update the current state of the open joysticks. + * + * This is called automatically by the event loop if any joystick events are + * enabled. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickEventState + */ +extern DECLSPEC void SDLCALL SDL_JoystickUpdate(void); + +/** + * Enable/disable joystick event polling. + * + * If joystick events are disabled, you must call SDL_JoystickUpdate() + * yourself and manually check the state of the joystick when you want + * joystick information. + * + * It is recommended that you leave joystick event handling enabled. + * + * **WARNING**: Calling this function may delete all events currently in SDL's + * event queue. + * + * While `param` is meant to be one of `SDL_QUERY`, `SDL_IGNORE`, or + * `SDL_ENABLE`, this function accepts any value, with any non-zero value that + * isn't `SDL_QUERY` being treated as `SDL_ENABLE`. + * + * If SDL was built with events disabled (extremely uncommon!), this will + * do nothing and always return `SDL_IGNORE`. + * + * \param state can be one of `SDL_QUERY`, `SDL_IGNORE`, or `SDL_ENABLE` + * \returns If `state` is `SDL_QUERY` then the current state is returned, + * otherwise `state` is returned (even if it was not one of the + * allowed values). + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GameControllerEventState + */ +extern DECLSPEC int SDLCALL SDL_JoystickEventState(int state); + +#define SDL_JOYSTICK_AXIS_MAX 32767 +#define SDL_JOYSTICK_AXIS_MIN -32768 + +/** + * Get the current state of an axis control on a joystick. + * + * SDL makes no promises about what part of the joystick any given axis refers + * to. Your game should have some sort of configuration UI to let users + * specify what each axis should be bound to. Alternately, SDL's higher-level + * Game Controller API makes a great effort to apply order to this lower-level + * interface, so you know that a specific axis is the "left thumb stick," etc. + * + * The value returned by SDL_JoystickGetAxis() is a signed integer (-32768 to + * 32767) representing the current position of the axis. It may be necessary + * to impose certain tolerances on these values to account for jitter. + * + * \param joystick an SDL_Joystick structure containing joystick information + * \param axis the axis to query; the axis indices start at index 0 + * \returns a 16-bit signed integer representing the current position of the + * axis or 0 on failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickNumAxes + */ +extern DECLSPEC Sint16 SDLCALL SDL_JoystickGetAxis(SDL_Joystick *joystick, + int axis); + +/** + * Get the initial state of an axis control on a joystick. + * + * The state is a value ranging from -32768 to 32767. + * + * The axis indices start at index 0. + * + * \param joystick an SDL_Joystick structure containing joystick information + * \param axis the axis to query; the axis indices start at index 0 + * \param state Upon return, the initial value is supplied here. + * \return SDL_TRUE if this axis has any initial value, or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_JoystickGetAxisInitialState(SDL_Joystick *joystick, + int axis, Sint16 *state); + +/** + * \name Hat positions + */ +/* @{ */ +#define SDL_HAT_CENTERED 0x00 +#define SDL_HAT_UP 0x01 +#define SDL_HAT_RIGHT 0x02 +#define SDL_HAT_DOWN 0x04 +#define SDL_HAT_LEFT 0x08 +#define SDL_HAT_RIGHTUP (SDL_HAT_RIGHT|SDL_HAT_UP) +#define SDL_HAT_RIGHTDOWN (SDL_HAT_RIGHT|SDL_HAT_DOWN) +#define SDL_HAT_LEFTUP (SDL_HAT_LEFT|SDL_HAT_UP) +#define SDL_HAT_LEFTDOWN (SDL_HAT_LEFT|SDL_HAT_DOWN) +/* @} */ + +/** + * Get the current state of a POV hat on a joystick. + * + * The returned value will be one of the following positions: + * + * - `SDL_HAT_CENTERED` + * - `SDL_HAT_UP` + * - `SDL_HAT_RIGHT` + * - `SDL_HAT_DOWN` + * - `SDL_HAT_LEFT` + * - `SDL_HAT_RIGHTUP` + * - `SDL_HAT_RIGHTDOWN` + * - `SDL_HAT_LEFTUP` + * - `SDL_HAT_LEFTDOWN` + * + * \param joystick an SDL_Joystick structure containing joystick information + * \param hat the hat index to get the state from; indices start at index 0 + * \returns the current hat position. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickNumHats + */ +extern DECLSPEC Uint8 SDLCALL SDL_JoystickGetHat(SDL_Joystick *joystick, + int hat); + +/** + * Get the ball axis change since the last poll. + * + * Trackballs can only return relative motion since the last call to + * SDL_JoystickGetBall(), these motion deltas are placed into `dx` and `dy`. + * + * Most joysticks do not have trackballs. + * + * \param joystick the SDL_Joystick to query + * \param ball the ball index to query; ball indices start at index 0 + * \param dx stores the difference in the x axis position since the last poll + * \param dy stores the difference in the y axis position since the last poll + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickNumBalls + */ +extern DECLSPEC int SDLCALL SDL_JoystickGetBall(SDL_Joystick *joystick, + int ball, int *dx, int *dy); + +/** + * Get the current state of a button on a joystick. + * + * \param joystick an SDL_Joystick structure containing joystick information + * \param button the button index to get the state from; indices start at + * index 0 + * \returns 1 if the specified button is pressed, 0 otherwise. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickNumButtons + */ +extern DECLSPEC Uint8 SDLCALL SDL_JoystickGetButton(SDL_Joystick *joystick, + int button); + +/** + * Start a rumble effect. + * + * Each call to this function cancels any previous rumble effect, and calling + * it with 0 intensity stops any rumbling. + * + * \param joystick The joystick to vibrate + * \param low_frequency_rumble The intensity of the low frequency (left) + * rumble motor, from 0 to 0xFFFF + * \param high_frequency_rumble The intensity of the high frequency (right) + * rumble motor, from 0 to 0xFFFF + * \param duration_ms The duration of the rumble effect, in milliseconds + * \returns 0, or -1 if rumble isn't supported on this joystick + * + * \since This function is available since SDL 2.0.9. + * + * \sa SDL_JoystickHasRumble + */ +extern DECLSPEC int SDLCALL SDL_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms); + +/** + * Start a rumble effect in the joystick's triggers + * + * Each call to this function cancels any previous trigger rumble effect, and + * calling it with 0 intensity stops any rumbling. + * + * Note that this is rumbling of the _triggers_ and not the game controller as + * a whole. This is currently only supported on Xbox One controllers. If you + * want the (more common) whole-controller rumble, use SDL_JoystickRumble() + * instead. + * + * \param joystick The joystick to vibrate + * \param left_rumble The intensity of the left trigger rumble motor, from 0 + * to 0xFFFF + * \param right_rumble The intensity of the right trigger rumble motor, from 0 + * to 0xFFFF + * \param duration_ms The duration of the rumble effect, in milliseconds + * \returns 0, or -1 if trigger rumble isn't supported on this joystick + * + * \since This function is available since SDL 2.0.14. + * + * \sa SDL_JoystickHasRumbleTriggers + */ +extern DECLSPEC int SDLCALL SDL_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble, Uint32 duration_ms); + +/** + * Query whether a joystick has an LED. + * + * An example of a joystick LED is the light on the back of a PlayStation 4's + * DualShock 4 controller. + * + * \param joystick The joystick to query + * \return SDL_TRUE if the joystick has a modifiable LED, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_JoystickHasLED(SDL_Joystick *joystick); + +/** + * Query whether a joystick has rumble support. + * + * \param joystick The joystick to query + * \return SDL_TRUE if the joystick has rumble, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_JoystickRumble + */ +extern DECLSPEC SDL_bool SDLCALL SDL_JoystickHasRumble(SDL_Joystick *joystick); + +/** + * Query whether a joystick has rumble support on triggers. + * + * \param joystick The joystick to query + * \return SDL_TRUE if the joystick has trigger rumble, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_JoystickRumbleTriggers + */ +extern DECLSPEC SDL_bool SDLCALL SDL_JoystickHasRumbleTriggers(SDL_Joystick *joystick); + +/** + * Update a joystick's LED color. + * + * An example of a joystick LED is the light on the back of a PlayStation 4's + * DualShock 4 controller. + * + * \param joystick The joystick to update + * \param red The intensity of the red LED + * \param green The intensity of the green LED + * \param blue The intensity of the blue LED + * \returns 0 on success, -1 if this joystick does not have a modifiable LED + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC int SDLCALL SDL_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue); + +/** + * Send a joystick specific effect packet + * + * \param joystick The joystick to affect + * \param data The data to send to the joystick + * \param size The size of the data to send to the joystick + * \returns 0, or -1 if this joystick or driver doesn't support effect packets + * + * \since This function is available since SDL 2.0.16. + */ +extern DECLSPEC int SDLCALL SDL_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size); + +/** + * Close a joystick previously opened with SDL_JoystickOpen(). + * + * \param joystick The joystick device to close + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_JoystickOpen + */ +extern DECLSPEC void SDLCALL SDL_JoystickClose(SDL_Joystick *joystick); + +/** + * Get the battery level of a joystick as SDL_JoystickPowerLevel. + * + * \param joystick the SDL_Joystick to query + * \returns the current battery level as SDL_JoystickPowerLevel on success or + * `SDL_JOYSTICK_POWER_UNKNOWN` if it is unknown + * + * \since This function is available since SDL 2.0.4. + */ +extern DECLSPEC SDL_JoystickPowerLevel SDLCALL SDL_JoystickCurrentPowerLevel(SDL_Joystick *joystick); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_joystick_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/include/SDL_keyboard.h b/SDL2-2.30.5/include/SDL_keyboard.h new file mode 100644 index 0000000..03c7b5a --- /dev/null +++ b/SDL2-2.30.5/include/SDL_keyboard.h @@ -0,0 +1,355 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_keyboard.h + * + * Include file for SDL keyboard event handling + */ + +#ifndef SDL_keyboard_h_ +#define SDL_keyboard_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_keycode.h" +#include "SDL_video.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief The SDL keysym structure, used in key events. + * + * \note If you are looking for translated character input, see the ::SDL_TEXTINPUT event. + */ +typedef struct SDL_Keysym +{ + SDL_Scancode scancode; /**< SDL physical key code - see ::SDL_Scancode for details */ + SDL_Keycode sym; /**< SDL virtual key code - see ::SDL_Keycode for details */ + Uint16 mod; /**< current key modifiers */ + Uint32 unused; +} SDL_Keysym; + +/* Function prototypes */ + +/** + * Query the window which currently has keyboard focus. + * + * \returns the window with keyboard focus. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC SDL_Window * SDLCALL SDL_GetKeyboardFocus(void); + +/** + * Get a snapshot of the current state of the keyboard. + * + * The pointer returned is a pointer to an internal SDL array. It will be + * valid for the whole lifetime of the application and should not be freed by + * the caller. + * + * A array element with a value of 1 means that the key is pressed and a value + * of 0 means that it is not. Indexes into this array are obtained by using + * SDL_Scancode values. + * + * Use SDL_PumpEvents() to update the state array. + * + * This function gives you the current state after all events have been + * processed, so if a key or button has been pressed and released before you + * process events, then the pressed state will never show up in the + * SDL_GetKeyboardState() calls. + * + * Note: This function doesn't take into account whether shift has been + * pressed or not. + * + * \param numkeys if non-NULL, receives the length of the returned array + * \returns a pointer to an array of key states. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_PumpEvents + * \sa SDL_ResetKeyboard + */ +extern DECLSPEC const Uint8 *SDLCALL SDL_GetKeyboardState(int *numkeys); + +/** + * Clear the state of the keyboard + * + * This function will generate key up events for all pressed keys. + * + * \since This function is available since SDL 2.24.0. + * + * \sa SDL_GetKeyboardState + */ +extern DECLSPEC void SDLCALL SDL_ResetKeyboard(void); + +/** + * Get the current key modifier state for the keyboard. + * + * \returns an OR'd combination of the modifier keys for the keyboard. See + * SDL_Keymod for details. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetKeyboardState + * \sa SDL_SetModState + */ +extern DECLSPEC SDL_Keymod SDLCALL SDL_GetModState(void); + +/** + * Set the current key modifier state for the keyboard. + * + * The inverse of SDL_GetModState(), SDL_SetModState() allows you to impose + * modifier key states on your application. Simply pass your desired modifier + * states into `modstate`. This value may be a bitwise, OR'd combination of + * SDL_Keymod values. + * + * This does not change the keyboard state, only the key modifier flags that + * SDL reports. + * + * \param modstate the desired SDL_Keymod for the keyboard + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetModState + */ +extern DECLSPEC void SDLCALL SDL_SetModState(SDL_Keymod modstate); + +/** + * Get the key code corresponding to the given scancode according to the + * current keyboard layout. + * + * See SDL_Keycode for details. + * + * \param scancode the desired SDL_Scancode to query + * \returns the SDL_Keycode that corresponds to the given SDL_Scancode. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetKeyName + * \sa SDL_GetScancodeFromKey + */ +extern DECLSPEC SDL_Keycode SDLCALL SDL_GetKeyFromScancode(SDL_Scancode scancode); + +/** + * Get the scancode corresponding to the given key code according to the + * current keyboard layout. + * + * See SDL_Scancode for details. + * + * \param key the desired SDL_Keycode to query + * \returns the SDL_Scancode that corresponds to the given SDL_Keycode. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetKeyFromScancode + * \sa SDL_GetScancodeName + */ +extern DECLSPEC SDL_Scancode SDLCALL SDL_GetScancodeFromKey(SDL_Keycode key); + +/** + * Get a human-readable name for a scancode. + * + * See SDL_Scancode for details. + * + * **Warning**: The returned name is by design not stable across platforms, + * e.g. the name for `SDL_SCANCODE_LGUI` is "Left GUI" under Linux but "Left + * Windows" under Microsoft Windows, and some scancodes like + * `SDL_SCANCODE_NONUSBACKSLASH` don't have any name at all. There are even + * scancodes that share names, e.g. `SDL_SCANCODE_RETURN` and + * `SDL_SCANCODE_RETURN2` (both called "Return"). This function is therefore + * unsuitable for creating a stable cross-platform two-way mapping between + * strings and scancodes. + * + * \param scancode the desired SDL_Scancode to query + * \returns a pointer to the name for the scancode. If the scancode doesn't + * have a name this function returns an empty string (""). + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetScancodeFromKey + * \sa SDL_GetScancodeFromName + */ +extern DECLSPEC const char *SDLCALL SDL_GetScancodeName(SDL_Scancode scancode); + +/** + * Get a scancode from a human-readable name. + * + * \param name the human-readable scancode name + * \returns the SDL_Scancode, or `SDL_SCANCODE_UNKNOWN` if the name wasn't + * recognized; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetKeyFromName + * \sa SDL_GetScancodeFromKey + * \sa SDL_GetScancodeName + */ +extern DECLSPEC SDL_Scancode SDLCALL SDL_GetScancodeFromName(const char *name); + +/** + * Get a human-readable name for a key. + * + * See SDL_Scancode and SDL_Keycode for details. + * + * \param key the desired SDL_Keycode to query + * \returns a pointer to a UTF-8 string that stays valid at least until the + * next call to this function. If you need it around any longer, you + * must copy it. If the key doesn't have a name, this function + * returns an empty string (""). + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetKeyFromName + * \sa SDL_GetKeyFromScancode + * \sa SDL_GetScancodeFromKey + */ +extern DECLSPEC const char *SDLCALL SDL_GetKeyName(SDL_Keycode key); + +/** + * Get a key code from a human-readable name. + * + * \param name the human-readable key name + * \returns key code, or `SDLK_UNKNOWN` if the name wasn't recognized; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetKeyFromScancode + * \sa SDL_GetKeyName + * \sa SDL_GetScancodeFromName + */ +extern DECLSPEC SDL_Keycode SDLCALL SDL_GetKeyFromName(const char *name); + +/** + * Start accepting Unicode text input events. + * + * This function will start accepting Unicode text input events in the focused + * SDL window, and start emitting SDL_TextInputEvent (SDL_TEXTINPUT) and + * SDL_TextEditingEvent (SDL_TEXTEDITING) events. Please use this function in + * pair with SDL_StopTextInput(). + * + * On some platforms using this function activates the screen keyboard. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetTextInputRect + * \sa SDL_StopTextInput + */ +extern DECLSPEC void SDLCALL SDL_StartTextInput(void); + +/** + * Check whether or not Unicode text input events are enabled. + * + * \returns SDL_TRUE if text input events are enabled else SDL_FALSE. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_StartTextInput + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IsTextInputActive(void); + +/** + * Stop receiving any text input events. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_StartTextInput + */ +extern DECLSPEC void SDLCALL SDL_StopTextInput(void); + +/** + * Dismiss the composition window/IME without disabling the subsystem. + * + * \since This function is available since SDL 2.0.22. + * + * \sa SDL_StartTextInput + * \sa SDL_StopTextInput + */ +extern DECLSPEC void SDLCALL SDL_ClearComposition(void); + +/** + * Returns if an IME Composite or Candidate window is currently shown. + * + * \since This function is available since SDL 2.0.22. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IsTextInputShown(void); + +/** + * Set the rectangle used to type Unicode text inputs. Native input methods + * will place a window with word suggestions near it, without covering the + * text being inputted. + * + * To start text input in a given location, this function is intended to be + * called before SDL_StartTextInput, although some platforms support moving + * the rectangle even while text input (and a composition) is active. + * + * Note: If you want to use the system native IME window, try setting hint + * **SDL_HINT_IME_SHOW_UI** to **1**, otherwise this function won't give you + * any feedback. + * + * \param rect the SDL_Rect structure representing the rectangle to receive + * text (ignored if NULL) + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_StartTextInput + */ +extern DECLSPEC void SDLCALL SDL_SetTextInputRect(const SDL_Rect *rect); + +/** + * Check whether the platform has screen keyboard support. + * + * \returns SDL_TRUE if the platform has some screen keyboard support or + * SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_StartTextInput + * \sa SDL_IsScreenKeyboardShown + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasScreenKeyboardSupport(void); + +/** + * Check whether the screen keyboard is shown for given window. + * + * \param window the window for which screen keyboard should be queried + * \returns SDL_TRUE if screen keyboard is shown or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HasScreenKeyboardSupport + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IsScreenKeyboardShown(SDL_Window *window); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_keyboard_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/include/SDL_keycode.h b/SDL2-2.30.5/include/SDL_keycode.h similarity index 95% rename from SDL2-2.0.12/include/SDL_keycode.h rename to SDL2-2.30.5/include/SDL_keycode.h index a1ce7a4..57a71bd 100644 --- a/SDL2-2.0.12/include/SDL_keycode.h +++ b/SDL2-2.30.5/include/SDL_keycode.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -40,7 +40,7 @@ * an SDLK_* constant for those keys that do not generate characters. * * A special exception is the number keys at the top of the keyboard which - * always map to SDLK_0...SDLK_9, regardless of layout. + * map to SDLK_0...SDLK_9 on AZERTY layouts. */ typedef Sint32 SDL_Keycode; @@ -52,7 +52,7 @@ typedef enum SDLK_UNKNOWN = 0, SDLK_RETURN = '\r', - SDLK_ESCAPE = '\033', + SDLK_ESCAPE = '\x1B', SDLK_BACKSPACE = '\b', SDLK_TAB = '\t', SDLK_SPACE = ' ', @@ -88,9 +88,11 @@ typedef enum SDLK_GREATER = '>', SDLK_QUESTION = '?', SDLK_AT = '@', + /* Skip uppercase letters */ + SDLK_LEFTBRACKET = '[', SDLK_BACKSLASH = '\\', SDLK_RIGHTBRACKET = ']', @@ -145,7 +147,7 @@ typedef enum SDLK_INSERT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_INSERT), SDLK_HOME = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_HOME), SDLK_PAGEUP = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PAGEUP), - SDLK_DELETE = '\177', + SDLK_DELETE = '\x7F', SDLK_END = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_END), SDLK_PAGEDOWN = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_PAGEDOWN), SDLK_RIGHT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_RIGHT), @@ -316,7 +318,12 @@ typedef enum SDLK_APP2 = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_APP2), SDLK_AUDIOREWIND = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOREWIND), - SDLK_AUDIOFASTFORWARD = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOFASTFORWARD) + SDLK_AUDIOFASTFORWARD = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_AUDIOFASTFORWARD), + + SDLK_SOFTLEFT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SOFTLEFT), + SDLK_SOFTRIGHT = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_SOFTRIGHT), + SDLK_CALL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_CALL), + SDLK_ENDCALL = SDL_SCANCODE_TO_KEYCODE(SDL_SCANCODE_ENDCALL) } SDL_KeyCode; /** @@ -336,13 +343,15 @@ typedef enum KMOD_NUM = 0x1000, KMOD_CAPS = 0x2000, KMOD_MODE = 0x4000, - KMOD_RESERVED = 0x8000 -} SDL_Keymod; + KMOD_SCROLL = 0x8000, -#define KMOD_CTRL (KMOD_LCTRL|KMOD_RCTRL) -#define KMOD_SHIFT (KMOD_LSHIFT|KMOD_RSHIFT) -#define KMOD_ALT (KMOD_LALT|KMOD_RALT) -#define KMOD_GUI (KMOD_LGUI|KMOD_RGUI) + KMOD_CTRL = KMOD_LCTRL | KMOD_RCTRL, + KMOD_SHIFT = KMOD_LSHIFT | KMOD_RSHIFT, + KMOD_ALT = KMOD_LALT | KMOD_RALT, + KMOD_GUI = KMOD_LGUI | KMOD_RGUI, + + KMOD_RESERVED = KMOD_SCROLL /* This is for source-level compatibility with SDL 2.0.0. */ +} SDL_Keymod; #endif /* SDL_keycode_h_ */ diff --git a/SDL2-2.0.12/include/SDL_loadso.h b/SDL2-2.30.5/include/SDL_loadso.h similarity index 60% rename from SDL2-2.0.12/include/SDL_loadso.h rename to SDL2-2.30.5/include/SDL_loadso.h index 89578a9..4edc22e 100644 --- a/SDL2-2.0.12/include/SDL_loadso.h +++ b/SDL2-2.30.5/include/SDL_loadso.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -51,22 +51,56 @@ extern "C" { #endif /** - * This function dynamically loads a shared object and returns a pointer - * to the object handle (or NULL if there was an error). - * The 'sofile' parameter is a system dependent name of the object file. + * Dynamically load a shared object. + * + * \param sofile a system-dependent name of the object file + * \returns an opaque pointer to the object handle or NULL if there was an + * error; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LoadFunction + * \sa SDL_UnloadObject */ extern DECLSPEC void *SDLCALL SDL_LoadObject(const char *sofile); /** - * Given an object handle, this function looks up the address of the - * named function in the shared object and returns it. This address - * is no longer valid after calling SDL_UnloadObject(). + * Look up the address of the named function in a shared object. + * + * This function pointer is no longer valid after calling SDL_UnloadObject(). + * + * This function can only look up C function names. Other languages may have + * name mangling and intrinsic language support that varies from compiler to + * compiler. + * + * Make sure you declare your function pointers with the same calling + * convention as the actual library function. Your code will crash + * mysteriously if you do not do this. + * + * If the requested function doesn't exist, NULL is returned. + * + * \param handle a valid shared object handle returned by SDL_LoadObject() + * \param name the name of the function to look up + * \returns a pointer to the function or NULL if there was an error; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LoadObject + * \sa SDL_UnloadObject */ extern DECLSPEC void *SDLCALL SDL_LoadFunction(void *handle, const char *name); /** - * Unload a shared object from memory. + * Unload a shared object from memory. + * + * \param handle a valid shared object handle returned by SDL_LoadObject() + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LoadFunction + * \sa SDL_LoadObject */ extern DECLSPEC void SDLCALL SDL_UnloadObject(void *handle); diff --git a/SDL2-2.30.5/include/SDL_locale.h b/SDL2-2.30.5/include/SDL_locale.h new file mode 100644 index 0000000..0b6118f --- /dev/null +++ b/SDL2-2.30.5/include/SDL_locale.h @@ -0,0 +1,103 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_locale.h + * + * Include file for SDL locale services + */ + +#ifndef _SDL_locale_h +#define _SDL_locale_h + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + + +typedef struct SDL_Locale +{ + const char *language; /**< A language name, like "en" for English. */ + const char *country; /**< A country, like "US" for America. Can be NULL. */ +} SDL_Locale; + +/** + * Report the user's preferred locale. + * + * This returns an array of SDL_Locale structs, the final item zeroed out. + * When the caller is done with this array, it should call SDL_free() on the + * returned value; all the memory involved is allocated in a single block, so + * a single SDL_free() will suffice. + * + * Returned language strings are in the format xx, where 'xx' is an ISO-639 + * language specifier (such as "en" for English, "de" for German, etc). + * Country strings are in the format YY, where "YY" is an ISO-3166 country + * code (such as "US" for the United States, "CA" for Canada, etc). Country + * might be NULL if there's no specific guidance on them (so you might get { + * "en", "US" } for American English, but { "en", NULL } means "English + * language, generically"). Language strings are never NULL, except to + * terminate the array. + * + * Please note that not all of these strings are 2 characters; some are three + * or more. + * + * The returned list of locales are in the order of the user's preference. For + * example, a German citizen that is fluent in US English and knows enough + * Japanese to navigate around Tokyo might have a list like: { "de", "en_US", + * "jp", NULL }. Someone from England might prefer British English (where + * "color" is spelled "colour", etc), but will settle for anything like it: { + * "en_GB", "en", NULL }. + * + * This function returns NULL on error, including when the platform does not + * supply this information at all. + * + * This might be a "slow" call that has to query the operating system. It's + * best to ask for this once and save the results. However, this list can + * change, usually because the user has changed a system preference outside of + * your program; SDL will send an SDL_LOCALECHANGED event in this case, if + * possible, and you can call this function again to get an updated copy of + * preferred locales. + * + * \return array of locales, terminated with a locale with a NULL language + * field. Will return NULL on error. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC SDL_Locale * SDLCALL SDL_GetPreferredLocales(void); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif +#include "close_code.h" + +#endif /* _SDL_locale_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/include/SDL_log.h b/SDL2-2.30.5/include/SDL_log.h new file mode 100644 index 0000000..bd030c6 --- /dev/null +++ b/SDL2-2.30.5/include/SDL_log.h @@ -0,0 +1,404 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_log.h + * + * Simple log messages with categories and priorities. + * + * By default logs are quiet, but if you're debugging SDL you might want: + * + * SDL_LogSetAllPriority(SDL_LOG_PRIORITY_WARN); + * + * Here's where the messages go on different platforms: + * Windows: debug output stream + * Android: log output + * Others: standard error output (stderr) + */ + +#ifndef SDL_log_h_ +#define SDL_log_h_ + +#include "SDL_stdinc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * \brief The maximum size of a log message prior to SDL 2.0.24 + * + * As of 2.0.24 there is no limit to the length of SDL log messages. + */ +#define SDL_MAX_LOG_MESSAGE 4096 + +/** + * \brief The predefined log categories + * + * By default the application category is enabled at the INFO level, + * the assert category is enabled at the WARN level, test is enabled + * at the VERBOSE level and all other categories are enabled at the + * ERROR level. + */ +typedef enum +{ + SDL_LOG_CATEGORY_APPLICATION, + SDL_LOG_CATEGORY_ERROR, + SDL_LOG_CATEGORY_ASSERT, + SDL_LOG_CATEGORY_SYSTEM, + SDL_LOG_CATEGORY_AUDIO, + SDL_LOG_CATEGORY_VIDEO, + SDL_LOG_CATEGORY_RENDER, + SDL_LOG_CATEGORY_INPUT, + SDL_LOG_CATEGORY_TEST, + + /* Reserved for future SDL library use */ + SDL_LOG_CATEGORY_RESERVED1, + SDL_LOG_CATEGORY_RESERVED2, + SDL_LOG_CATEGORY_RESERVED3, + SDL_LOG_CATEGORY_RESERVED4, + SDL_LOG_CATEGORY_RESERVED5, + SDL_LOG_CATEGORY_RESERVED6, + SDL_LOG_CATEGORY_RESERVED7, + SDL_LOG_CATEGORY_RESERVED8, + SDL_LOG_CATEGORY_RESERVED9, + SDL_LOG_CATEGORY_RESERVED10, + + /* Beyond this point is reserved for application use, e.g. + enum { + MYAPP_CATEGORY_AWESOME1 = SDL_LOG_CATEGORY_CUSTOM, + MYAPP_CATEGORY_AWESOME2, + MYAPP_CATEGORY_AWESOME3, + ... + }; + */ + SDL_LOG_CATEGORY_CUSTOM +} SDL_LogCategory; + +/** + * \brief The predefined log priorities + */ +typedef enum +{ + SDL_LOG_PRIORITY_VERBOSE = 1, + SDL_LOG_PRIORITY_DEBUG, + SDL_LOG_PRIORITY_INFO, + SDL_LOG_PRIORITY_WARN, + SDL_LOG_PRIORITY_ERROR, + SDL_LOG_PRIORITY_CRITICAL, + SDL_NUM_LOG_PRIORITIES +} SDL_LogPriority; + + +/** + * Set the priority of all log categories. + * + * \param priority the SDL_LogPriority to assign + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LogSetPriority + */ +extern DECLSPEC void SDLCALL SDL_LogSetAllPriority(SDL_LogPriority priority); + +/** + * Set the priority of a particular log category. + * + * \param category the category to assign a priority to + * \param priority the SDL_LogPriority to assign + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LogGetPriority + * \sa SDL_LogSetAllPriority + */ +extern DECLSPEC void SDLCALL SDL_LogSetPriority(int category, + SDL_LogPriority priority); + +/** + * Get the priority of a particular log category. + * + * \param category the category to query + * \returns the SDL_LogPriority for the requested category + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LogSetPriority + */ +extern DECLSPEC SDL_LogPriority SDLCALL SDL_LogGetPriority(int category); + +/** + * Reset all priorities to default. + * + * This is called by SDL_Quit(). + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LogSetAllPriority + * \sa SDL_LogSetPriority + */ +extern DECLSPEC void SDLCALL SDL_LogResetPriorities(void); + +/** + * Log a message with SDL_LOG_CATEGORY_APPLICATION and SDL_LOG_PRIORITY_INFO. + * + * = * \param fmt a printf() style message format string + * + * \param ... additional parameters matching % tokens in the `fmt` string, if + * any + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LogCritical + * \sa SDL_LogDebug + * \sa SDL_LogError + * \sa SDL_LogInfo + * \sa SDL_LogMessage + * \sa SDL_LogMessageV + * \sa SDL_LogVerbose + * \sa SDL_LogWarn + */ +extern DECLSPEC void SDLCALL SDL_Log(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(1); + +/** + * Log a message with SDL_LOG_PRIORITY_VERBOSE. + * + * \param category the category of the message + * \param fmt a printf() style message format string + * \param ... additional parameters matching % tokens in the **fmt** string, + * if any + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Log + * \sa SDL_LogCritical + * \sa SDL_LogDebug + * \sa SDL_LogError + * \sa SDL_LogInfo + * \sa SDL_LogMessage + * \sa SDL_LogMessageV + * \sa SDL_LogWarn + */ +extern DECLSPEC void SDLCALL SDL_LogVerbose(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); + +/** + * Log a message with SDL_LOG_PRIORITY_DEBUG. + * + * \param category the category of the message + * \param fmt a printf() style message format string + * \param ... additional parameters matching % tokens in the **fmt** string, + * if any + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Log + * \sa SDL_LogCritical + * \sa SDL_LogError + * \sa SDL_LogInfo + * \sa SDL_LogMessage + * \sa SDL_LogMessageV + * \sa SDL_LogVerbose + * \sa SDL_LogWarn + */ +extern DECLSPEC void SDLCALL SDL_LogDebug(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); + +/** + * Log a message with SDL_LOG_PRIORITY_INFO. + * + * \param category the category of the message + * \param fmt a printf() style message format string + * \param ... additional parameters matching % tokens in the **fmt** string, + * if any + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Log + * \sa SDL_LogCritical + * \sa SDL_LogDebug + * \sa SDL_LogError + * \sa SDL_LogMessage + * \sa SDL_LogMessageV + * \sa SDL_LogVerbose + * \sa SDL_LogWarn + */ +extern DECLSPEC void SDLCALL SDL_LogInfo(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); + +/** + * Log a message with SDL_LOG_PRIORITY_WARN. + * + * \param category the category of the message + * \param fmt a printf() style message format string + * \param ... additional parameters matching % tokens in the **fmt** string, + * if any + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Log + * \sa SDL_LogCritical + * \sa SDL_LogDebug + * \sa SDL_LogError + * \sa SDL_LogInfo + * \sa SDL_LogMessage + * \sa SDL_LogMessageV + * \sa SDL_LogVerbose + */ +extern DECLSPEC void SDLCALL SDL_LogWarn(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); + +/** + * Log a message with SDL_LOG_PRIORITY_ERROR. + * + * \param category the category of the message + * \param fmt a printf() style message format string + * \param ... additional parameters matching % tokens in the **fmt** string, + * if any + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Log + * \sa SDL_LogCritical + * \sa SDL_LogDebug + * \sa SDL_LogInfo + * \sa SDL_LogMessage + * \sa SDL_LogMessageV + * \sa SDL_LogVerbose + * \sa SDL_LogWarn + */ +extern DECLSPEC void SDLCALL SDL_LogError(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); + +/** + * Log a message with SDL_LOG_PRIORITY_CRITICAL. + * + * \param category the category of the message + * \param fmt a printf() style message format string + * \param ... additional parameters matching % tokens in the **fmt** string, + * if any + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Log + * \sa SDL_LogDebug + * \sa SDL_LogError + * \sa SDL_LogInfo + * \sa SDL_LogMessage + * \sa SDL_LogMessageV + * \sa SDL_LogVerbose + * \sa SDL_LogWarn + */ +extern DECLSPEC void SDLCALL SDL_LogCritical(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); + +/** + * Log a message with the specified category and priority. + * + * \param category the category of the message + * \param priority the priority of the message + * \param fmt a printf() style message format string + * \param ... additional parameters matching % tokens in the **fmt** string, + * if any + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Log + * \sa SDL_LogCritical + * \sa SDL_LogDebug + * \sa SDL_LogError + * \sa SDL_LogInfo + * \sa SDL_LogMessageV + * \sa SDL_LogVerbose + * \sa SDL_LogWarn + */ +extern DECLSPEC void SDLCALL SDL_LogMessage(int category, + SDL_LogPriority priority, + SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(3); + +/** + * Log a message with the specified category and priority. + * + * \param category the category of the message + * \param priority the priority of the message + * \param fmt a printf() style message format string + * \param ap a variable argument list + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Log + * \sa SDL_LogCritical + * \sa SDL_LogDebug + * \sa SDL_LogError + * \sa SDL_LogInfo + * \sa SDL_LogMessage + * \sa SDL_LogVerbose + * \sa SDL_LogWarn + */ +extern DECLSPEC void SDLCALL SDL_LogMessageV(int category, + SDL_LogPriority priority, + SDL_PRINTF_FORMAT_STRING const char *fmt, va_list ap) SDL_PRINTF_VARARG_FUNCV(3); + +/** + * The prototype for the log output callback function. + * + * This function is called by SDL when there is new text to be logged. + * + * \param userdata what was passed as `userdata` to SDL_LogSetOutputFunction() + * \param category the category of the message + * \param priority the priority of the message + * \param message the message being output + */ +typedef void (SDLCALL *SDL_LogOutputFunction)(void *userdata, int category, SDL_LogPriority priority, const char *message); + +/** + * Get the current log output function. + * + * \param callback an SDL_LogOutputFunction filled in with the current log + * callback + * \param userdata a pointer filled in with the pointer that is passed to + * `callback` + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LogSetOutputFunction + */ +extern DECLSPEC void SDLCALL SDL_LogGetOutputFunction(SDL_LogOutputFunction *callback, void **userdata); + +/** + * Replace the default log output function with one of your own. + * + * \param callback an SDL_LogOutputFunction to call instead of the default + * \param userdata a pointer that is passed to `callback` + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LogGetOutputFunction + */ +extern DECLSPEC void SDLCALL SDL_LogSetOutputFunction(SDL_LogOutputFunction callback, void *userdata); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_log_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/include/SDL_main.h b/SDL2-2.30.5/include/SDL_main.h new file mode 100644 index 0000000..a66c84b --- /dev/null +++ b/SDL2-2.30.5/include/SDL_main.h @@ -0,0 +1,282 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#ifndef SDL_main_h_ +#define SDL_main_h_ + +#include "SDL_stdinc.h" + +/** + * \file SDL_main.h + * + * Redefine main() on some platforms so that it is called by SDL. + */ + +#ifndef SDL_MAIN_HANDLED +#if defined(__WIN32__) +/* On Windows SDL provides WinMain(), which parses the command line and passes + the arguments to your main function. + + If you provide your own WinMain(), you may define SDL_MAIN_HANDLED + */ +#define SDL_MAIN_AVAILABLE + +#elif defined(__WINRT__) +/* On WinRT, SDL provides a main function that initializes CoreApplication, + creating an instance of IFrameworkView in the process. + + Please note that #include'ing SDL_main.h is not enough to get a main() + function working. In non-XAML apps, the file, + src/main/winrt/SDL_WinRT_main_NonXAML.cpp, or a copy of it, must be compiled + into the app itself. In XAML apps, the function, SDL_WinRTRunApp must be + called, with a pointer to the Direct3D-hosted XAML control passed in. +*/ +#define SDL_MAIN_NEEDED + +#elif defined(__GDK__) +/* On GDK, SDL provides a main function that initializes the game runtime. + + Please note that #include'ing SDL_main.h is not enough to get a main() + function working. You must either link against SDL2main or, if not possible, + call the SDL_GDKRunApp function from your entry point. +*/ +#define SDL_MAIN_NEEDED + +#elif defined(__IPHONEOS__) +/* On iOS SDL provides a main function that creates an application delegate + and starts the iOS application run loop. + + If you link with SDL dynamically on iOS, the main function can't be in a + shared library, so you need to link with libSDLmain.a, which includes a + stub main function that calls into the shared library to start execution. + + See src/video/uikit/SDL_uikitappdelegate.m for more details. + */ +#define SDL_MAIN_NEEDED + +#elif defined(__ANDROID__) +/* On Android SDL provides a Java class in SDLActivity.java that is the + main activity entry point. + + See docs/README-android.md for more details on extending that class. + */ +#define SDL_MAIN_NEEDED + +/* We need to export SDL_main so it can be launched from Java */ +#define SDLMAIN_DECLSPEC DECLSPEC + +#elif defined(__NACL__) +/* On NACL we use ppapi_simple to set up the application helper code, + then wait for the first PSE_INSTANCE_DIDCHANGEVIEW event before + starting the user main function. + All user code is run in a separate thread by ppapi_simple, thus + allowing for blocking io to take place via nacl_io +*/ +#define SDL_MAIN_NEEDED + +#elif defined(__PSP__) +/* On PSP SDL provides a main function that sets the module info, + activates the GPU and starts the thread required to be able to exit + the software. + + If you provide this yourself, you may define SDL_MAIN_HANDLED + */ +#define SDL_MAIN_AVAILABLE + +#elif defined(__PS2__) +#define SDL_MAIN_AVAILABLE + +#define SDL_PS2_SKIP_IOP_RESET() \ + void reset_IOP(); \ + void reset_IOP() {} + +#elif defined(__3DS__) +/* + On N3DS, SDL provides a main function that sets up the screens + and storage. + + If you provide this yourself, you may define SDL_MAIN_HANDLED +*/ +#define SDL_MAIN_AVAILABLE + +#endif +#endif /* SDL_MAIN_HANDLED */ + +#ifndef SDLMAIN_DECLSPEC +#define SDLMAIN_DECLSPEC +#endif + +/** + * \file SDL_main.h + * + * The application's main() function must be called with C linkage, + * and should be declared like this: + * \code + * #ifdef __cplusplus + * extern "C" + * #endif + * int main(int argc, char *argv[]) + * { + * } + * \endcode + */ + +#if defined(SDL_MAIN_NEEDED) || defined(SDL_MAIN_AVAILABLE) +#define main SDL_main +#endif + +#include "begin_code.h" +#ifdef __cplusplus +extern "C" { +#endif + +/** + * The prototype for the application's main() function + */ +typedef int (*SDL_main_func)(int argc, char *argv[]); +extern SDLMAIN_DECLSPEC int SDL_main(int argc, char *argv[]); + + +/** + * Circumvent failure of SDL_Init() when not using SDL_main() as an entry + * point. + * + * This function is defined in SDL_main.h, along with the preprocessor rule to + * redefine main() as SDL_main(). Thus to ensure that your main() function + * will not be changed it is necessary to define SDL_MAIN_HANDLED before + * including SDL.h. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_Init + */ +extern DECLSPEC void SDLCALL SDL_SetMainReady(void); + +#if defined(__WIN32__) || defined(__GDK__) + +/** + * Register a win32 window class for SDL's use. + * + * This can be called to set the application window class at startup. It is + * safe to call this multiple times, as long as every call is eventually + * paired with a call to SDL_UnregisterApp, but a second registration attempt + * while a previous registration is still active will be ignored, other than + * to increment a counter. + * + * Most applications do not need to, and should not, call this directly; SDL + * will call it when initializing the video subsystem. + * + * \param name the window class name, in UTF-8 encoding. If NULL, SDL + * currently uses "SDL_app" but this isn't guaranteed. + * \param style the value to use in WNDCLASSEX::style. If `name` is NULL, SDL + * currently uses `(CS_BYTEALIGNCLIENT | CS_OWNDC)` regardless of + * what is specified here. + * \param hInst the HINSTANCE to use in WNDCLASSEX::hInstance. If zero, SDL + * will use `GetModuleHandle(NULL)` instead. + * \returns 0 on success, -1 on error. SDL_GetError() may have details. + * + * \since This function is available since SDL 2.0.2. + */ +extern DECLSPEC int SDLCALL SDL_RegisterApp(const char *name, Uint32 style, void *hInst); + +/** + * Deregister the win32 window class from an SDL_RegisterApp call. + * + * This can be called to undo the effects of SDL_RegisterApp. + * + * Most applications do not need to, and should not, call this directly; SDL + * will call it when deinitializing the video subsystem. + * + * It is safe to call this multiple times, as long as every call is eventually + * paired with a prior call to SDL_RegisterApp. The window class will only be + * deregistered when the registration counter in SDL_RegisterApp decrements to + * zero through calls to this function. + * + * \since This function is available since SDL 2.0.2. + */ +extern DECLSPEC void SDLCALL SDL_UnregisterApp(void); + +#endif /* defined(__WIN32__) || defined(__GDK__) */ + + +#ifdef __WINRT__ + +/** + * Initialize and launch an SDL/WinRT application. + * + * \param mainFunction the SDL app's C-style main(), an SDL_main_func + * \param reserved reserved for future use; should be NULL + * \returns 0 on success or -1 on failure; call SDL_GetError() to retrieve + * more information on the failure. + * + * \since This function is available since SDL 2.0.3. + */ +extern DECLSPEC int SDLCALL SDL_WinRTRunApp(SDL_main_func mainFunction, void * reserved); + +#endif /* __WINRT__ */ + +#if defined(__IPHONEOS__) + +/** + * Initializes and launches an SDL application. + * + * \param argc The argc parameter from the application's main() function + * \param argv The argv parameter from the application's main() function + * \param mainFunction The SDL app's C-style main(), an SDL_main_func + * \return the return value from mainFunction + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC int SDLCALL SDL_UIKitRunApp(int argc, char *argv[], SDL_main_func mainFunction); + +#endif /* __IPHONEOS__ */ + +#ifdef __GDK__ + +/** + * Initialize and launch an SDL GDK application. + * + * \param mainFunction the SDL app's C-style main(), an SDL_main_func + * \param reserved reserved for future use; should be NULL + * \returns 0 on success or -1 on failure; call SDL_GetError() to retrieve + * more information on the failure. + * + * \since This function is available since SDL 2.24.0. + */ +extern DECLSPEC int SDLCALL SDL_GDKRunApp(SDL_main_func mainFunction, void *reserved); + +/** + * Callback from the application to let the suspend continue. + * + * \since This function is available since SDL 2.28.0. + */ +extern DECLSPEC void SDLCALL SDL_GDKSuspendComplete(void); + +#endif /* __GDK__ */ + +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_main_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/include/SDL_messagebox.h b/SDL2-2.30.5/include/SDL_messagebox.h similarity index 52% rename from SDL2-2.0.12/include/SDL_messagebox.h rename to SDL2-2.30.5/include/SDL_messagebox.h index 03639ce..5ace6f2 100644 --- a/SDL2-2.0.12/include/SDL_messagebox.h +++ b/SDL2-2.30.5/include/SDL_messagebox.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -32,7 +32,7 @@ extern "C" { #endif /** - * \brief SDL_MessageBox flags. If supported will display warning icon, etc. + * SDL_MessageBox flags. If supported will display warning icon, etc. */ typedef enum { @@ -44,7 +44,7 @@ typedef enum } SDL_MessageBoxFlags; /** - * \brief Flags for SDL_MessageBoxButtonData. + * Flags for SDL_MessageBoxButtonData. */ typedef enum { @@ -53,7 +53,7 @@ typedef enum } SDL_MessageBoxButtonFlags; /** - * \brief Individual button data. + * Individual button data. */ typedef struct { @@ -63,7 +63,7 @@ typedef struct } SDL_MessageBoxButtonData; /** - * \brief RGB value used in a message box color scheme + * RGB value used in a message box color scheme */ typedef struct { @@ -81,7 +81,7 @@ typedef enum } SDL_MessageBoxColorType; /** - * \brief A set of colors to use for message box dialogs + * A set of colors to use for message box dialogs */ typedef struct { @@ -89,7 +89,7 @@ typedef struct } SDL_MessageBoxColorScheme; /** - * \brief MessageBox structure containing title, text, window, etc. + * MessageBox structure containing title, text, window, etc. */ typedef struct { @@ -105,32 +105,79 @@ typedef struct } SDL_MessageBoxData; /** - * \brief Create a modal message box. + * Create a modal message box. * - * \param messageboxdata The SDL_MessageBoxData structure with title, text, etc. - * \param buttonid The pointer to which user id of hit button should be copied. + * If your needs aren't complex, it might be easier to use + * SDL_ShowSimpleMessageBox. * - * \return -1 on error, otherwise 0 and buttonid contains user id of button - * hit or -1 if dialog was closed. + * This function should be called on the thread that created the parent + * window, or on the main thread if the messagebox has no parent. It will + * block execution of that thread until the user clicks a button or closes the + * messagebox. * - * \note This function should be called on the thread that created the parent - * window, or on the main thread if the messagebox has no parent. It will - * block execution of that thread until the user clicks a button or - * closes the messagebox. + * This function may be called at any time, even before SDL_Init(). This makes + * it useful for reporting errors like a failure to create a renderer or + * OpenGL context. + * + * On X11, SDL rolls its own dialog box with X11 primitives instead of a + * formal toolkit like GTK+ or Qt. + * + * Note that if SDL_Init() would fail because there isn't any available video + * target, this function is likely to fail for the same reasons. If this is a + * concern, check the return value from this function and fall back to writing + * to stderr if you can. + * + * \param messageboxdata the SDL_MessageBoxData structure with title, text and + * other options + * \param buttonid the pointer to which user id of hit button should be copied + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ShowSimpleMessageBox */ extern DECLSPEC int SDLCALL SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid); /** - * \brief Create a simple modal message box + * Display a simple modal message box. * - * \param flags ::SDL_MessageBoxFlags - * \param title UTF-8 title text - * \param message UTF-8 message text - * \param window The parent window, or NULL for no parent + * If your needs aren't complex, this function is preferred over + * SDL_ShowMessageBox. * - * \return 0 on success, -1 on error + * `flags` may be any of the following: * - * \sa SDL_ShowMessageBox + * - `SDL_MESSAGEBOX_ERROR`: error dialog + * - `SDL_MESSAGEBOX_WARNING`: warning dialog + * - `SDL_MESSAGEBOX_INFORMATION`: informational dialog + * + * This function should be called on the thread that created the parent + * window, or on the main thread if the messagebox has no parent. It will + * block execution of that thread until the user clicks a button or closes the + * messagebox. + * + * This function may be called at any time, even before SDL_Init(). This makes + * it useful for reporting errors like a failure to create a renderer or + * OpenGL context. + * + * On X11, SDL rolls its own dialog box with X11 primitives instead of a + * formal toolkit like GTK+ or Qt. + * + * Note that if SDL_Init() would fail because there isn't any available video + * target, this function is likely to fail for the same reasons. If this is a + * concern, check the return value from this function and fall back to writing + * to stderr if you can. + * + * \param flags an SDL_MessageBoxFlags value + * \param title UTF-8 title text + * \param message UTF-8 message text + * \param window the parent window, or NULL for no parent + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ShowMessageBox */ extern DECLSPEC int SDLCALL SDL_ShowSimpleMessageBox(Uint32 flags, const char *title, const char *message, SDL_Window *window); diff --git a/SDL2-2.0.12/include/SDL_metal.h b/SDL2-2.30.5/include/SDL_metal.h similarity index 52% rename from SDL2-2.0.12/include/SDL_metal.h rename to SDL2-2.30.5/include/SDL_metal.h index 3b7eb18..50f7b2a 100644 --- a/SDL2-2.0.12/include/SDL_metal.h +++ b/SDL2-2.30.5/include/SDL_metal.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -49,37 +49,59 @@ typedef void *SDL_MetalView; /* @{ */ /** - * \brief Create a CAMetalLayer-backed NSView/UIView and attach it to the - * specified window. + * Create a CAMetalLayer-backed NSView/UIView and attach it to the specified + * window. * - * On macOS, this does *not* associate a MTLDevice with the CAMetalLayer on its - * own. It is up to user code to do that. + * On macOS, this does *not* associate a MTLDevice with the CAMetalLayer on + * its own. It is up to user code to do that. * - * The returned handle can be casted directly to a NSView or UIView, and the - * CAMetalLayer can be accessed from the view's 'layer' property. + * The returned handle can be casted directly to a NSView or UIView. To access + * the backing CAMetalLayer, call SDL_Metal_GetLayer(). * - * \code - * SDL_MetalView metalview = SDL_Metal_CreateView(window); - * UIView *uiview = (__bridge UIView *)metalview; - * CAMetalLayer *metallayer = (CAMetalLayer *)uiview.layer; - * // [...] - * SDL_Metal_DestroyView(metalview); - * \endcode + * \since This function is available since SDL 2.0.12. * - * \sa SDL_Metal_DestroyView + * \sa SDL_Metal_DestroyView + * \sa SDL_Metal_GetLayer */ extern DECLSPEC SDL_MetalView SDLCALL SDL_Metal_CreateView(SDL_Window * window); /** - * \brief Destroy an existing SDL_MetalView object. + * Destroy an existing SDL_MetalView object. * - * This should be called before SDL_DestroyWindow, if SDL_Metal_CreateView was - * called after SDL_CreateWindow. + * This should be called before SDL_DestroyWindow, if SDL_Metal_CreateView was + * called after SDL_CreateWindow. * - * \sa SDL_Metal_CreateView + * \since This function is available since SDL 2.0.12. + * + * \sa SDL_Metal_CreateView */ extern DECLSPEC void SDLCALL SDL_Metal_DestroyView(SDL_MetalView view); +/** + * Get a pointer to the backing CAMetalLayer for the given view. + * + * \since This function is available since SDL 2.0.14. + * + * \sa SDL_Metal_CreateView + */ +extern DECLSPEC void *SDLCALL SDL_Metal_GetLayer(SDL_MetalView view); + +/** + * Get the size of a window's underlying drawable in pixels (for use with + * setting viewport, scissor & etc). + * + * \param window SDL_Window from which the drawable size should be queried + * \param w Pointer to variable for storing the width in pixels, may be NULL + * \param h Pointer to variable for storing the height in pixels, may be NULL + * + * \since This function is available since SDL 2.0.14. + * + * \sa SDL_GetWindowSize + * \sa SDL_CreateWindow + */ +extern DECLSPEC void SDLCALL SDL_Metal_GetDrawableSize(SDL_Window* window, int *w, + int *h); + /* @} *//* Metal support functions */ /* Ends C function definitions when using C++ */ diff --git a/SDL2-2.30.5/include/SDL_misc.h b/SDL2-2.30.5/include/SDL_misc.h new file mode 100644 index 0000000..113ba7a --- /dev/null +++ b/SDL2-2.30.5/include/SDL_misc.h @@ -0,0 +1,79 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_misc.h + * + * \brief Include file for SDL API functions that don't fit elsewhere. + */ + +#ifndef SDL_misc_h_ +#define SDL_misc_h_ + +#include "SDL_stdinc.h" + +#include "begin_code.h" + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Open a URL/URI in the browser or other appropriate external application. + * + * Open a URL in a separate, system-provided application. How this works will + * vary wildly depending on the platform. This will likely launch what makes + * sense to handle a specific URL's protocol (a web browser for `http://`, + * etc), but it might also be able to launch file managers for directories and + * other things. + * + * What happens when you open a URL varies wildly as well: your game window + * may lose focus (and may or may not lose focus if your game was fullscreen + * or grabbing input at the time). On mobile devices, your app will likely + * move to the background or your process might be paused. Any given platform + * may or may not handle a given URL. + * + * If this is unimplemented (or simply unavailable) for a platform, this will + * fail with an error. A successful result does not mean the URL loaded, just + * that we launched _something_ to handle it (or at least believe we did). + * + * All this to say: this function can be useful, but you should definitely + * test it on every platform you target. + * + * \param url A valid URL/URI to open. Use `file:///full/path/to/file` for + * local files, if supported. + * \returns 0 on success, or -1 on error; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC int SDLCALL SDL_OpenURL(const char *url); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_misc_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/include/SDL_mouse.h b/SDL2-2.30.5/include/SDL_mouse.h new file mode 100644 index 0000000..687ff12 --- /dev/null +++ b/SDL2-2.30.5/include/SDL_mouse.h @@ -0,0 +1,464 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_mouse.h + * + * Include file for SDL mouse event handling. + */ + +#ifndef SDL_mouse_h_ +#define SDL_mouse_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_video.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct SDL_Cursor SDL_Cursor; /**< Implementation dependent */ + +/** + * \brief Cursor types for SDL_CreateSystemCursor(). + */ +typedef enum +{ + SDL_SYSTEM_CURSOR_ARROW, /**< Arrow */ + SDL_SYSTEM_CURSOR_IBEAM, /**< I-beam */ + SDL_SYSTEM_CURSOR_WAIT, /**< Wait */ + SDL_SYSTEM_CURSOR_CROSSHAIR, /**< Crosshair */ + SDL_SYSTEM_CURSOR_WAITARROW, /**< Small wait cursor (or Wait if not available) */ + SDL_SYSTEM_CURSOR_SIZENWSE, /**< Double arrow pointing northwest and southeast */ + SDL_SYSTEM_CURSOR_SIZENESW, /**< Double arrow pointing northeast and southwest */ + SDL_SYSTEM_CURSOR_SIZEWE, /**< Double arrow pointing west and east */ + SDL_SYSTEM_CURSOR_SIZENS, /**< Double arrow pointing north and south */ + SDL_SYSTEM_CURSOR_SIZEALL, /**< Four pointed arrow pointing north, south, east, and west */ + SDL_SYSTEM_CURSOR_NO, /**< Slashed circle or crossbones */ + SDL_SYSTEM_CURSOR_HAND, /**< Hand */ + SDL_NUM_SYSTEM_CURSORS +} SDL_SystemCursor; + +/** + * \brief Scroll direction types for the Scroll event + */ +typedef enum +{ + SDL_MOUSEWHEEL_NORMAL, /**< The scroll direction is normal */ + SDL_MOUSEWHEEL_FLIPPED /**< The scroll direction is flipped / natural */ +} SDL_MouseWheelDirection; + +/* Function prototypes */ + +/** + * Get the window which currently has mouse focus. + * + * \returns the window with mouse focus. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC SDL_Window * SDLCALL SDL_GetMouseFocus(void); + +/** + * Retrieve the current state of the mouse. + * + * The current button state is returned as a button bitmask, which can be + * tested using the `SDL_BUTTON(X)` macros (where `X` is generally 1 for the + * left, 2 for middle, 3 for the right button), and `x` and `y` are set to the + * mouse cursor position relative to the focus window. You can pass NULL for + * either `x` or `y`. + * + * \param x the x coordinate of the mouse cursor position relative to the + * focus window + * \param y the y coordinate of the mouse cursor position relative to the + * focus window + * \returns a 32-bit button bitmask of the current button state. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetGlobalMouseState + * \sa SDL_GetRelativeMouseState + * \sa SDL_PumpEvents + */ +extern DECLSPEC Uint32 SDLCALL SDL_GetMouseState(int *x, int *y); + +/** + * Get the current state of the mouse in relation to the desktop. + * + * This works similarly to SDL_GetMouseState(), but the coordinates will be + * reported relative to the top-left of the desktop. This can be useful if you + * need to track the mouse outside of a specific window and SDL_CaptureMouse() + * doesn't fit your needs. For example, it could be useful if you need to + * track the mouse while dragging a window, where coordinates relative to a + * window might not be in sync at all times. + * + * Note: SDL_GetMouseState() returns the mouse position as SDL understands it + * from the last pump of the event queue. This function, however, queries the + * OS for the current mouse position, and as such, might be a slightly less + * efficient function. Unless you know what you're doing and have a good + * reason to use this function, you probably want SDL_GetMouseState() instead. + * + * \param x filled in with the current X coord relative to the desktop; can be + * NULL + * \param y filled in with the current Y coord relative to the desktop; can be + * NULL + * \returns the current button state as a bitmask which can be tested using + * the SDL_BUTTON(X) macros. + * + * \since This function is available since SDL 2.0.4. + * + * \sa SDL_CaptureMouse + */ +extern DECLSPEC Uint32 SDLCALL SDL_GetGlobalMouseState(int *x, int *y); + +/** + * Retrieve the relative state of the mouse. + * + * The current button state is returned as a button bitmask, which can be + * tested using the `SDL_BUTTON(X)` macros (where `X` is generally 1 for the + * left, 2 for middle, 3 for the right button), and `x` and `y` are set to the + * mouse deltas since the last call to SDL_GetRelativeMouseState() or since + * event initialization. You can pass NULL for either `x` or `y`. + * + * \param x a pointer filled with the last recorded x coordinate of the mouse + * \param y a pointer filled with the last recorded y coordinate of the mouse + * \returns a 32-bit button bitmask of the relative button state. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetMouseState + */ +extern DECLSPEC Uint32 SDLCALL SDL_GetRelativeMouseState(int *x, int *y); + +/** + * Move the mouse cursor to the given position within the window. + * + * This function generates a mouse motion event if relative mode is not + * enabled. If relative mode is enabled, you can force mouse events for the + * warp by setting the SDL_HINT_MOUSE_RELATIVE_WARP_MOTION hint. + * + * Note that this function will appear to succeed, but not actually move the + * mouse when used over Microsoft Remote Desktop. + * + * \param window the window to move the mouse into, or NULL for the current + * mouse focus + * \param x the x coordinate within the window + * \param y the y coordinate within the window + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_WarpMouseGlobal + */ +extern DECLSPEC void SDLCALL SDL_WarpMouseInWindow(SDL_Window * window, + int x, int y); + +/** + * Move the mouse to the given position in global screen space. + * + * This function generates a mouse motion event. + * + * A failure of this function usually means that it is unsupported by a + * platform. + * + * Note that this function will appear to succeed, but not actually move the + * mouse when used over Microsoft Remote Desktop. + * + * \param x the x coordinate + * \param y the y coordinate + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.4. + * + * \sa SDL_WarpMouseInWindow + */ +extern DECLSPEC int SDLCALL SDL_WarpMouseGlobal(int x, int y); + +/** + * Set relative mouse mode. + * + * While the mouse is in relative mode, the cursor is hidden, the mouse + * position is constrained to the window, and SDL will report continuous + * relative mouse motion even if the mouse is at the edge of the window. + * + * This function will flush any pending mouse motion. + * + * \param enabled SDL_TRUE to enable relative mode, SDL_FALSE to disable. + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * If relative mode is not supported, this returns -1. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetRelativeMouseMode + */ +extern DECLSPEC int SDLCALL SDL_SetRelativeMouseMode(SDL_bool enabled); + +/** + * Capture the mouse and to track input outside an SDL window. + * + * Capturing enables your app to obtain mouse events globally, instead of just + * within your window. Not all video targets support this function. When + * capturing is enabled, the current window will get all mouse events, but + * unlike relative mode, no change is made to the cursor and it is not + * restrained to your window. + * + * This function may also deny mouse input to other windows--both those in + * your application and others on the system--so you should use this function + * sparingly, and in small bursts. For example, you might want to track the + * mouse while the user is dragging something, until the user releases a mouse + * button. It is not recommended that you capture the mouse for long periods + * of time, such as the entire time your app is running. For that, you should + * probably use SDL_SetRelativeMouseMode() or SDL_SetWindowGrab(), depending + * on your goals. + * + * While captured, mouse events still report coordinates relative to the + * current (foreground) window, but those coordinates may be outside the + * bounds of the window (including negative values). Capturing is only allowed + * for the foreground window. If the window loses focus while capturing, the + * capture will be disabled automatically. + * + * While capturing is enabled, the current window will have the + * `SDL_WINDOW_MOUSE_CAPTURE` flag set. + * + * Please note that as of SDL 2.0.22, SDL will attempt to "auto capture" the + * mouse while the user is pressing a button; this is to try and make mouse + * behavior more consistent between platforms, and deal with the common case + * of a user dragging the mouse outside of the window. This means that if you + * are calling SDL_CaptureMouse() only to deal with this situation, you no + * longer have to (although it is safe to do so). If this causes problems for + * your app, you can disable auto capture by setting the + * `SDL_HINT_MOUSE_AUTO_CAPTURE` hint to zero. + * + * \param enabled SDL_TRUE to enable capturing, SDL_FALSE to disable. + * \returns 0 on success or -1 if not supported; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.4. + * + * \sa SDL_GetGlobalMouseState + */ +extern DECLSPEC int SDLCALL SDL_CaptureMouse(SDL_bool enabled); + +/** + * Query whether relative mouse mode is enabled. + * + * \returns SDL_TRUE if relative mode is enabled or SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetRelativeMouseMode + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GetRelativeMouseMode(void); + +/** + * Create a cursor using the specified bitmap data and mask (in MSB format). + * + * `mask` has to be in MSB (Most Significant Bit) format. + * + * The cursor width (`w`) must be a multiple of 8 bits. + * + * The cursor is created in black and white according to the following: + * + * - data=0, mask=1: white + * - data=1, mask=1: black + * - data=0, mask=0: transparent + * - data=1, mask=0: inverted color if possible, black if not. + * + * Cursors created with this function must be freed with SDL_FreeCursor(). + * + * If you want to have a color cursor, or create your cursor from an + * SDL_Surface, you should use SDL_CreateColorCursor(). Alternately, you can + * hide the cursor and draw your own as part of your game's rendering, but it + * will be bound to the framerate. + * + * Also, since SDL 2.0.0, SDL_CreateSystemCursor() is available, which + * provides twelve readily available system cursors to pick from. + * + * \param data the color value for each pixel of the cursor + * \param mask the mask value for each pixel of the cursor + * \param w the width of the cursor + * \param h the height of the cursor + * \param hot_x the X-axis location of the upper left corner of the cursor + * relative to the actual mouse position + * \param hot_y the Y-axis location of the upper left corner of the cursor + * relative to the actual mouse position + * \returns a new cursor with the specified parameters on success or NULL on + * failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_FreeCursor + * \sa SDL_SetCursor + * \sa SDL_ShowCursor + */ +extern DECLSPEC SDL_Cursor *SDLCALL SDL_CreateCursor(const Uint8 * data, + const Uint8 * mask, + int w, int h, int hot_x, + int hot_y); + +/** + * Create a color cursor. + * + * \param surface an SDL_Surface structure representing the cursor image + * \param hot_x the x position of the cursor hot spot + * \param hot_y the y position of the cursor hot spot + * \returns the new cursor on success or NULL on failure; call SDL_GetError() + * for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateCursor + * \sa SDL_FreeCursor + */ +extern DECLSPEC SDL_Cursor *SDLCALL SDL_CreateColorCursor(SDL_Surface *surface, + int hot_x, + int hot_y); + +/** + * Create a system cursor. + * + * \param id an SDL_SystemCursor enum value + * \returns a cursor on success or NULL on failure; call SDL_GetError() for + * more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_FreeCursor + */ +extern DECLSPEC SDL_Cursor *SDLCALL SDL_CreateSystemCursor(SDL_SystemCursor id); + +/** + * Set the active cursor. + * + * This function sets the currently active cursor to the specified one. If the + * cursor is currently visible, the change will be immediately represented on + * the display. SDL_SetCursor(NULL) can be used to force cursor redraw, if + * this is desired for any reason. + * + * \param cursor a cursor to make active + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateCursor + * \sa SDL_GetCursor + * \sa SDL_ShowCursor + */ +extern DECLSPEC void SDLCALL SDL_SetCursor(SDL_Cursor * cursor); + +/** + * Get the active cursor. + * + * This function returns a pointer to the current cursor which is owned by the + * library. It is not necessary to free the cursor with SDL_FreeCursor(). + * + * \returns the active cursor or NULL if there is no mouse. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetCursor + */ +extern DECLSPEC SDL_Cursor *SDLCALL SDL_GetCursor(void); + +/** + * Get the default cursor. + * + * You do not have to call SDL_FreeCursor() on the return value, but it is + * safe to do so. + * + * \returns the default cursor on success or NULL on failure. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateSystemCursor + */ +extern DECLSPEC SDL_Cursor *SDLCALL SDL_GetDefaultCursor(void); + +/** + * Free a previously-created cursor. + * + * Use this function to free cursor resources created with SDL_CreateCursor(), + * SDL_CreateColorCursor() or SDL_CreateSystemCursor(). + * + * \param cursor the cursor to free + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateColorCursor + * \sa SDL_CreateCursor + * \sa SDL_CreateSystemCursor + */ +extern DECLSPEC void SDLCALL SDL_FreeCursor(SDL_Cursor * cursor); + +/** + * Toggle whether or not the cursor is shown. + * + * The cursor starts off displayed but can be turned off. Passing `SDL_ENABLE` + * displays the cursor and passing `SDL_DISABLE` hides it. + * + * The current state of the mouse cursor can be queried by passing + * `SDL_QUERY`; either `SDL_DISABLE` or `SDL_ENABLE` will be returned. + * + * \param toggle `SDL_ENABLE` to show the cursor, `SDL_DISABLE` to hide it, + * `SDL_QUERY` to query the current state without changing it. + * \returns `SDL_ENABLE` if the cursor is shown, or `SDL_DISABLE` if the + * cursor is hidden, or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateCursor + * \sa SDL_SetCursor + */ +extern DECLSPEC int SDLCALL SDL_ShowCursor(int toggle); + +/** + * Used as a mask when testing buttons in buttonstate. + * + * - Button 1: Left mouse button + * - Button 2: Middle mouse button + * - Button 3: Right mouse button + */ +#define SDL_BUTTON(X) (1 << ((X)-1)) +#define SDL_BUTTON_LEFT 1 +#define SDL_BUTTON_MIDDLE 2 +#define SDL_BUTTON_RIGHT 3 +#define SDL_BUTTON_X1 4 +#define SDL_BUTTON_X2 5 +#define SDL_BUTTON_LMASK SDL_BUTTON(SDL_BUTTON_LEFT) +#define SDL_BUTTON_MMASK SDL_BUTTON(SDL_BUTTON_MIDDLE) +#define SDL_BUTTON_RMASK SDL_BUTTON(SDL_BUTTON_RIGHT) +#define SDL_BUTTON_X1MASK SDL_BUTTON(SDL_BUTTON_X1) +#define SDL_BUTTON_X2MASK SDL_BUTTON(SDL_BUTTON_X2) + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_mouse_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/include/SDL_mutex.h b/SDL2-2.30.5/include/SDL_mutex.h new file mode 100644 index 0000000..eaa21f2 --- /dev/null +++ b/SDL2-2.30.5/include/SDL_mutex.h @@ -0,0 +1,545 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#ifndef SDL_mutex_h_ +#define SDL_mutex_h_ + +/** + * \file SDL_mutex.h + * + * Functions to provide thread synchronization primitives. + */ + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +/******************************************************************************/ +/* Enable thread safety attributes only with clang. + * The attributes can be safely erased when compiling with other compilers. + */ +#if defined(SDL_THREAD_SAFETY_ANALYSIS) && \ + defined(__clang__) && (!defined(SWIG)) +#define SDL_THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x)) +#else +#define SDL_THREAD_ANNOTATION_ATTRIBUTE__(x) /* no-op */ +#endif + +#define SDL_CAPABILITY(x) \ + SDL_THREAD_ANNOTATION_ATTRIBUTE__(capability(x)) + +#define SDL_SCOPED_CAPABILITY \ + SDL_THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable) + +#define SDL_GUARDED_BY(x) \ + SDL_THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x)) + +#define SDL_PT_GUARDED_BY(x) \ + SDL_THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x)) + +#define SDL_ACQUIRED_BEFORE(x) \ + SDL_THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(x)) + +#define SDL_ACQUIRED_AFTER(x) \ + SDL_THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(x)) + +#define SDL_REQUIRES(x) \ + SDL_THREAD_ANNOTATION_ATTRIBUTE__(requires_capability(x)) + +#define SDL_REQUIRES_SHARED(x) \ + SDL_THREAD_ANNOTATION_ATTRIBUTE__(requires_shared_capability(x)) + +#define SDL_ACQUIRE(x) \ + SDL_THREAD_ANNOTATION_ATTRIBUTE__(acquire_capability(x)) + +#define SDL_ACQUIRE_SHARED(x) \ + SDL_THREAD_ANNOTATION_ATTRIBUTE__(acquire_shared_capability(x)) + +#define SDL_RELEASE(x) \ + SDL_THREAD_ANNOTATION_ATTRIBUTE__(release_capability(x)) + +#define SDL_RELEASE_SHARED(x) \ + SDL_THREAD_ANNOTATION_ATTRIBUTE__(release_shared_capability(x)) + +#define SDL_RELEASE_GENERIC(x) \ + SDL_THREAD_ANNOTATION_ATTRIBUTE__(release_generic_capability(x)) + +#define SDL_TRY_ACQUIRE(x, y) \ + SDL_THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_capability(x, y)) + +#define SDL_TRY_ACQUIRE_SHARED(x, y) \ + SDL_THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_shared_capability(x, y)) + +#define SDL_EXCLUDES(x) \ + SDL_THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(x)) + +#define SDL_ASSERT_CAPABILITY(x) \ + SDL_THREAD_ANNOTATION_ATTRIBUTE__(assert_capability(x)) + +#define SDL_ASSERT_SHARED_CAPABILITY(x) \ + SDL_THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_capability(x)) + +#define SDL_RETURN_CAPABILITY(x) \ + SDL_THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x)) + +#define SDL_NO_THREAD_SAFETY_ANALYSIS \ + SDL_THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis) + +/******************************************************************************/ + + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Synchronization functions which can time out return this value + * if they time out. + */ +#define SDL_MUTEX_TIMEDOUT 1 + +/** + * This is the timeout value which corresponds to never time out. + */ +#define SDL_MUTEX_MAXWAIT (~(Uint32)0) + + +/** + * \name Mutex functions + */ +/* @{ */ + +/* The SDL mutex structure, defined in SDL_sysmutex.c */ +struct SDL_mutex; +typedef struct SDL_mutex SDL_mutex; + +/** + * Create a new mutex. + * + * All newly-created mutexes begin in the _unlocked_ state. + * + * Calls to SDL_LockMutex() will not return while the mutex is locked by + * another thread. See SDL_TryLockMutex() to attempt to lock without blocking. + * + * SDL mutexes are reentrant. + * + * \returns the initialized and unlocked mutex or NULL on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_DestroyMutex + * \sa SDL_LockMutex + * \sa SDL_TryLockMutex + * \sa SDL_UnlockMutex + */ +extern DECLSPEC SDL_mutex *SDLCALL SDL_CreateMutex(void); + +/** + * Lock the mutex. + * + * This will block until the mutex is available, which is to say it is in the + * unlocked state and the OS has chosen the caller as the next thread to lock + * it. Of all threads waiting to lock the mutex, only one may do so at a time. + * + * It is legal for the owning thread to lock an already-locked mutex. It must + * unlock it the same number of times before it is actually made available for + * other threads in the system (this is known as a "recursive mutex"). + * + * \param mutex the mutex to lock + * \return 0, or -1 on error. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC int SDLCALL SDL_LockMutex(SDL_mutex * mutex) SDL_ACQUIRE(mutex); +#define SDL_mutexP(m) SDL_LockMutex(m) + +/** + * Try to lock a mutex without blocking. + * + * This works just like SDL_LockMutex(), but if the mutex is not available, + * this function returns `SDL_MUTEX_TIMEOUT` immediately. + * + * This technique is useful if you need exclusive access to a resource but + * don't want to wait for it, and will return to it to try again later. + * + * \param mutex the mutex to try to lock + * \returns 0, `SDL_MUTEX_TIMEDOUT`, or -1 on error; call SDL_GetError() for + * more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateMutex + * \sa SDL_DestroyMutex + * \sa SDL_LockMutex + * \sa SDL_UnlockMutex + */ +extern DECLSPEC int SDLCALL SDL_TryLockMutex(SDL_mutex * mutex) SDL_TRY_ACQUIRE(0, mutex); + +/** + * Unlock the mutex. + * + * It is legal for the owning thread to lock an already-locked mutex. It must + * unlock it the same number of times before it is actually made available for + * other threads in the system (this is known as a "recursive mutex"). + * + * It is an error to unlock a mutex that has not been locked by the current + * thread, and doing so results in undefined behavior. + * + * It is also an error to unlock a mutex that isn't locked at all. + * + * \param mutex the mutex to unlock. + * \returns 0, or -1 on error. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC int SDLCALL SDL_UnlockMutex(SDL_mutex * mutex) SDL_RELEASE(mutex); +#define SDL_mutexV(m) SDL_UnlockMutex(m) + +/** + * Destroy a mutex created with SDL_CreateMutex(). + * + * This function must be called on any mutex that is no longer needed. Failure + * to destroy a mutex will result in a system memory or resource leak. While + * it is safe to destroy a mutex that is _unlocked_, it is not safe to attempt + * to destroy a locked mutex, and may result in undefined behavior depending + * on the platform. + * + * \param mutex the mutex to destroy + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateMutex + * \sa SDL_LockMutex + * \sa SDL_TryLockMutex + * \sa SDL_UnlockMutex + */ +extern DECLSPEC void SDLCALL SDL_DestroyMutex(SDL_mutex * mutex); + +/* @} *//* Mutex functions */ + + +/** + * \name Semaphore functions + */ +/* @{ */ + +/* The SDL semaphore structure, defined in SDL_syssem.c */ +struct SDL_semaphore; +typedef struct SDL_semaphore SDL_sem; + +/** + * Create a semaphore. + * + * This function creates a new semaphore and initializes it with the value + * `initial_value`. Each wait operation on the semaphore will atomically + * decrement the semaphore value and potentially block if the semaphore value + * is 0. Each post operation will atomically increment the semaphore value and + * wake waiting threads and allow them to retry the wait operation. + * + * \param initial_value the starting value of the semaphore + * \returns a new semaphore or NULL on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_DestroySemaphore + * \sa SDL_SemPost + * \sa SDL_SemTryWait + * \sa SDL_SemValue + * \sa SDL_SemWait + * \sa SDL_SemWaitTimeout + */ +extern DECLSPEC SDL_sem *SDLCALL SDL_CreateSemaphore(Uint32 initial_value); + +/** + * Destroy a semaphore. + * + * It is not safe to destroy a semaphore if there are threads currently + * waiting on it. + * + * \param sem the semaphore to destroy + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateSemaphore + * \sa SDL_SemPost + * \sa SDL_SemTryWait + * \sa SDL_SemValue + * \sa SDL_SemWait + * \sa SDL_SemWaitTimeout + */ +extern DECLSPEC void SDLCALL SDL_DestroySemaphore(SDL_sem * sem); + +/** + * Wait until a semaphore has a positive value and then decrements it. + * + * This function suspends the calling thread until either the semaphore + * pointed to by `sem` has a positive value or the call is interrupted by a + * signal or error. If the call is successful it will atomically decrement the + * semaphore value. + * + * This function is the equivalent of calling SDL_SemWaitTimeout() with a time + * length of `SDL_MUTEX_MAXWAIT`. + * + * \param sem the semaphore wait on + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateSemaphore + * \sa SDL_DestroySemaphore + * \sa SDL_SemPost + * \sa SDL_SemTryWait + * \sa SDL_SemValue + * \sa SDL_SemWait + * \sa SDL_SemWaitTimeout + */ +extern DECLSPEC int SDLCALL SDL_SemWait(SDL_sem * sem); + +/** + * See if a semaphore has a positive value and decrement it if it does. + * + * This function checks to see if the semaphore pointed to by `sem` has a + * positive value and atomically decrements the semaphore value if it does. If + * the semaphore doesn't have a positive value, the function immediately + * returns SDL_MUTEX_TIMEDOUT. + * + * \param sem the semaphore to wait on + * \returns 0 if the wait succeeds, `SDL_MUTEX_TIMEDOUT` if the wait would + * block, or a negative error code on failure; call SDL_GetError() + * for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateSemaphore + * \sa SDL_DestroySemaphore + * \sa SDL_SemPost + * \sa SDL_SemValue + * \sa SDL_SemWait + * \sa SDL_SemWaitTimeout + */ +extern DECLSPEC int SDLCALL SDL_SemTryWait(SDL_sem * sem); + +/** + * Wait until a semaphore has a positive value and then decrements it. + * + * This function suspends the calling thread until either the semaphore + * pointed to by `sem` has a positive value, the call is interrupted by a + * signal or error, or the specified time has elapsed. If the call is + * successful it will atomically decrement the semaphore value. + * + * \param sem the semaphore to wait on + * \param timeout the length of the timeout, in milliseconds + * \returns 0 if the wait succeeds, `SDL_MUTEX_TIMEDOUT` if the wait does not + * succeed in the allotted time, or a negative error code on failure; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateSemaphore + * \sa SDL_DestroySemaphore + * \sa SDL_SemPost + * \sa SDL_SemTryWait + * \sa SDL_SemValue + * \sa SDL_SemWait + */ +extern DECLSPEC int SDLCALL SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout); + +/** + * Atomically increment a semaphore's value and wake waiting threads. + * + * \param sem the semaphore to increment + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateSemaphore + * \sa SDL_DestroySemaphore + * \sa SDL_SemTryWait + * \sa SDL_SemValue + * \sa SDL_SemWait + * \sa SDL_SemWaitTimeout + */ +extern DECLSPEC int SDLCALL SDL_SemPost(SDL_sem * sem); + +/** + * Get the current value of a semaphore. + * + * \param sem the semaphore to query + * \returns the current value of the semaphore. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateSemaphore + */ +extern DECLSPEC Uint32 SDLCALL SDL_SemValue(SDL_sem * sem); + +/* @} *//* Semaphore functions */ + + +/** + * \name Condition variable functions + */ +/* @{ */ + +/* The SDL condition variable structure, defined in SDL_syscond.c */ +struct SDL_cond; +typedef struct SDL_cond SDL_cond; + +/** + * Create a condition variable. + * + * \returns a new condition variable or NULL on failure; call SDL_GetError() + * for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CondBroadcast + * \sa SDL_CondSignal + * \sa SDL_CondWait + * \sa SDL_CondWaitTimeout + * \sa SDL_DestroyCond + */ +extern DECLSPEC SDL_cond *SDLCALL SDL_CreateCond(void); + +/** + * Destroy a condition variable. + * + * \param cond the condition variable to destroy + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CondBroadcast + * \sa SDL_CondSignal + * \sa SDL_CondWait + * \sa SDL_CondWaitTimeout + * \sa SDL_CreateCond + */ +extern DECLSPEC void SDLCALL SDL_DestroyCond(SDL_cond * cond); + +/** + * Restart one of the threads that are waiting on the condition variable. + * + * \param cond the condition variable to signal + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CondBroadcast + * \sa SDL_CondWait + * \sa SDL_CondWaitTimeout + * \sa SDL_CreateCond + * \sa SDL_DestroyCond + */ +extern DECLSPEC int SDLCALL SDL_CondSignal(SDL_cond * cond); + +/** + * Restart all threads that are waiting on the condition variable. + * + * \param cond the condition variable to signal + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CondSignal + * \sa SDL_CondWait + * \sa SDL_CondWaitTimeout + * \sa SDL_CreateCond + * \sa SDL_DestroyCond + */ +extern DECLSPEC int SDLCALL SDL_CondBroadcast(SDL_cond * cond); + +/** + * Wait until a condition variable is signaled. + * + * This function unlocks the specified `mutex` and waits for another thread to + * call SDL_CondSignal() or SDL_CondBroadcast() on the condition variable + * `cond`. Once the condition variable is signaled, the mutex is re-locked and + * the function returns. + * + * The mutex must be locked before calling this function. + * + * This function is the equivalent of calling SDL_CondWaitTimeout() with a + * time length of `SDL_MUTEX_MAXWAIT`. + * + * \param cond the condition variable to wait on + * \param mutex the mutex used to coordinate thread access + * \returns 0 when it is signaled or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CondBroadcast + * \sa SDL_CondSignal + * \sa SDL_CondWaitTimeout + * \sa SDL_CreateCond + * \sa SDL_DestroyCond + */ +extern DECLSPEC int SDLCALL SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex); + +/** + * Wait until a condition variable is signaled or a certain time has passed. + * + * This function unlocks the specified `mutex` and waits for another thread to + * call SDL_CondSignal() or SDL_CondBroadcast() on the condition variable + * `cond`, or for the specified time to elapse. Once the condition variable is + * signaled or the time elapsed, the mutex is re-locked and the function + * returns. + * + * The mutex must be locked before calling this function. + * + * \param cond the condition variable to wait on + * \param mutex the mutex used to coordinate thread access + * \param ms the maximum time to wait, in milliseconds, or `SDL_MUTEX_MAXWAIT` + * to wait indefinitely + * \returns 0 if the condition variable is signaled, `SDL_MUTEX_TIMEDOUT` if + * the condition is not signaled in the allotted time, or a negative + * error code on failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CondBroadcast + * \sa SDL_CondSignal + * \sa SDL_CondWait + * \sa SDL_CreateCond + * \sa SDL_DestroyCond + */ +extern DECLSPEC int SDLCALL SDL_CondWaitTimeout(SDL_cond * cond, + SDL_mutex * mutex, Uint32 ms); + +/* @} *//* Condition variable functions */ + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_mutex_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/include/SDL_name.h b/SDL2-2.30.5/include/SDL_name.h similarity index 94% rename from SDL2-2.0.12/include/SDL_name.h rename to SDL2-2.30.5/include/SDL_name.h index a49c488..71e9354 100644 --- a/SDL2-2.0.12/include/SDL_name.h +++ b/SDL2-2.30.5/include/SDL_name.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/include/SDL_opengl.h b/SDL2-2.30.5/include/SDL_opengl.h similarity index 98% rename from SDL2-2.0.12/include/SDL_opengl.h rename to SDL2-2.30.5/include/SDL_opengl.h index 5cd302c..2bb38c5 100644 --- a/SDL2-2.0.12/include/SDL_opengl.h +++ b/SDL2-2.30.5/include/SDL_opengl.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -2107,57 +2107,6 @@ typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLsh -/* - * ???. GL_MESA_packed_depth_stencil - * XXX obsolete - */ -#ifndef GL_MESA_packed_depth_stencil -#define GL_MESA_packed_depth_stencil 1 - -#define GL_DEPTH_STENCIL_MESA 0x8750 -#define GL_UNSIGNED_INT_24_8_MESA 0x8751 -#define GL_UNSIGNED_INT_8_24_REV_MESA 0x8752 -#define GL_UNSIGNED_SHORT_15_1_MESA 0x8753 -#define GL_UNSIGNED_SHORT_1_15_REV_MESA 0x8754 - -#endif /* GL_MESA_packed_depth_stencil */ - - -#ifndef GL_ATI_blend_equation_separate -#define GL_ATI_blend_equation_separate 1 - -#define GL_ALPHA_BLEND_EQUATION_ATI 0x883D - -GLAPI void GLAPIENTRY glBlendEquationSeparateATI( GLenum modeRGB, GLenum modeA ); -typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEATIPROC) (GLenum modeRGB, GLenum modeA); - -#endif /* GL_ATI_blend_equation_separate */ - - -/* GL_OES_EGL_image */ -#ifndef GL_OES_EGL_image -typedef void* GLeglImageOES; -#endif - -#ifndef GL_OES_EGL_image -#define GL_OES_EGL_image 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glEGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image); -GLAPI void APIENTRY glEGLImageTargetRenderbufferStorageOES (GLenum target, GLeglImageOES image); -#endif -typedef void (APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, GLeglImageOES image); -typedef void (APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLeglImageOES image); -#endif - - -/** - ** NOTE!!!!! If you add new functions to this file, or update - ** glext.h be sure to regenerate the gl_mangle.h file. See comments - ** in that file for details. - **/ - - - /********************************************************************** * Begin system-specific stuff */ diff --git a/SDL2-2.0.12/include/SDL_opengl_glext.h b/SDL2-2.30.5/include/SDL_opengl_glext.h similarity index 84% rename from SDL2-2.0.12/include/SDL_opengl_glext.h rename to SDL2-2.30.5/include/SDL_opengl_glext.h index 6a402b1..ff6ad12 100644 --- a/SDL2-2.0.12/include/SDL_opengl_glext.h +++ b/SDL2-2.30.5/include/SDL_opengl_glext.h @@ -1,12 +1,49 @@ -#ifndef __glext_h_ +/* SDL modified the include guard to be compatible with Mesa and Apple include guards: + * - Mesa uses: __gl_glext_h_ + * - Apple uses: __glext_h_ */ +#if !defined(__glext_h_) && !defined(__gl_glext_h_) #define __glext_h_ 1 +#define __gl_glext_h_ 1 #ifdef __cplusplus extern "C" { #endif /* -** Copyright (c) 2013-2014 The Khronos Group Inc. +** Copyright 2013-2020 The Khronos Group Inc. +** SPDX-License-Identifier: MIT +** +** This header is generated from the Khronos OpenGL / OpenGL ES XML +** API Registry. The current version of the Registry, generator scripts +** used to make the header, and the header can be found at +** https://github.com/KhronosGroup/OpenGL-Registry +*/ + +#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN 1 +#endif +#include +#endif + +#ifndef APIENTRY +#define APIENTRY +#endif +#ifndef APIENTRYP +#define APIENTRYP APIENTRY * +#endif +#ifndef GLAPI +#define GLAPI extern +#endif + +#define GL_GLEXT_VERSION 20220530 + +/*#include */ +#ifndef __khrplatform_h_ +#define __khrplatform_h_ + +/* +** Copyright (c) 2008-2018 The Khronos Group Inc. ** ** Permission is hereby granted, free of charge, to any person obtaining a ** copy of this software and/or associated documentation files (the @@ -27,36 +64,292 @@ extern "C" { ** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE ** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. */ + +/* Khronos platform-specific types and definitions. + * + * The master copy of khrplatform.h is maintained in the Khronos EGL + * Registry repository at https://github.com/KhronosGroup/EGL-Registry + * The last semantic modification to khrplatform.h was at commit ID: + * 67a3e0864c2d75ea5287b9f3d2eb74a745936692 + * + * Adopters may modify this file to suit their platform. Adopters are + * encouraged to submit platform specific modifications to the Khronos + * group so that they can be included in future versions of this file. + * Please submit changes by filing pull requests or issues on + * the EGL Registry repository linked above. + * + * + * See the Implementer's Guidelines for information about where this file + * should be located on your system and for more details of its use: + * http://www.khronos.org/registry/implementers_guide.pdf + * + * This file should be included as + * #include + * by Khronos client API header files that use its types and defines. + * + * The types in khrplatform.h should only be used to define API-specific types. + * + * Types defined in khrplatform.h: + * khronos_int8_t signed 8 bit + * khronos_uint8_t unsigned 8 bit + * khronos_int16_t signed 16 bit + * khronos_uint16_t unsigned 16 bit + * khronos_int32_t signed 32 bit + * khronos_uint32_t unsigned 32 bit + * khronos_int64_t signed 64 bit + * khronos_uint64_t unsigned 64 bit + * khronos_intptr_t signed same number of bits as a pointer + * khronos_uintptr_t unsigned same number of bits as a pointer + * khronos_ssize_t signed size + * khronos_usize_t unsigned size + * khronos_float_t signed 32 bit floating point + * khronos_time_ns_t unsigned 64 bit time in nanoseconds + * khronos_utime_nanoseconds_t unsigned time interval or absolute time in + * nanoseconds + * khronos_stime_nanoseconds_t signed time interval in nanoseconds + * khronos_boolean_enum_t enumerated boolean type. This should + * only be used as a base type when a client API's boolean type is + * an enum. Client APIs which use an integer or other type for + * booleans cannot use this as the base type for their boolean. + * + * Tokens defined in khrplatform.h: + * + * KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values. + * + * KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0. + * KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0. + * + * Calling convention macros defined in this file: + * KHRONOS_APICALL + * KHRONOS_APIENTRY + * KHRONOS_APIATTRIBUTES + * + * These may be used in function prototypes as: + * + * KHRONOS_APICALL void KHRONOS_APIENTRY funcname( + * int arg1, + * int arg2) KHRONOS_APIATTRIBUTES; + */ + +#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC) +# define KHRONOS_STATIC 1 +#endif + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APICALL + *------------------------------------------------------------------------- + * This precedes the return type of the function in the function prototype. + */ +#if defined(KHRONOS_STATIC) + /* If the preprocessor constant KHRONOS_STATIC is defined, make the + * header compatible with static linking. */ +# define KHRONOS_APICALL +#elif defined(_WIN32) +# define KHRONOS_APICALL __declspec(dllimport) +#elif defined (__SYMBIAN32__) +# define KHRONOS_APICALL IMPORT_C +#elif defined(__ANDROID__) +# define KHRONOS_APICALL __attribute__((visibility("default"))) +#else +# define KHRONOS_APICALL +#endif + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APIENTRY + *------------------------------------------------------------------------- + * This follows the return type of the function and precedes the function + * name in the function prototype. + */ +#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__) + /* Win32 but not WinCE */ +# define KHRONOS_APIENTRY __stdcall +#else +# define KHRONOS_APIENTRY +#endif + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APIATTRIBUTES + *------------------------------------------------------------------------- + * This follows the closing parenthesis of the function prototype arguments. + */ +#if defined (__ARMCC_2__) +#define KHRONOS_APIATTRIBUTES __softfp +#else +#define KHRONOS_APIATTRIBUTES +#endif + +/*------------------------------------------------------------------------- + * basic type definitions + *-----------------------------------------------------------------------*/ +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__) + + /* -** This header is generated from the Khronos OpenGL / OpenGL ES XML -** API Registry. The current version of the Registry, generator scripts -** used to make the header, and the header can be found at -** http://www.opengl.org/registry/ -** -** Khronos $Revision: 26745 $ on $Date: 2014-05-21 03:12:26 -0700 (Wed, 21 May 2014) $ -*/ - -#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN 1 + * Using + */ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 +/* + * To support platform where unsigned long cannot be used interchangeably with + * inptr_t (e.g. CHERI-extended ISAs), we can use the stdint.h intptr_t. + * Ideally, we could just use (u)intptr_t everywhere, but this could result in + * ABI breakage if khronos_uintptr_t is changed from unsigned long to + * unsigned long long or similar (this results in different C++ name mangling). + * To avoid changes for existing platforms, we restrict usage of intptr_t to + * platforms where the size of a pointer is larger than the size of long. + */ +#if defined(__SIZEOF_LONG__) && defined(__SIZEOF_POINTER__) +#if __SIZEOF_POINTER__ > __SIZEOF_LONG__ +#define KHRONOS_USE_INTPTR_T #endif -#ifndef NOMINMAX /* don't define min() and max(). */ -#define NOMINMAX -#endif -#include #endif -#ifndef APIENTRY -#define APIENTRY -#endif -#ifndef APIENTRYP -#define APIENTRYP APIENTRY * -#endif -#ifndef GLAPI -#define GLAPI extern +#elif defined(__VMS ) || defined(__sgi) + +/* + * Using + */ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(_WIN32) && !defined(__SCITECH_SNAP__) + +/* + * Win32 + */ +typedef __int32 khronos_int32_t; +typedef unsigned __int32 khronos_uint32_t; +typedef __int64 khronos_int64_t; +typedef unsigned __int64 khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(__sun__) || defined(__digital__) + +/* + * Sun or Digital + */ +typedef int khronos_int32_t; +typedef unsigned int khronos_uint32_t; +#if defined(__arch64__) || defined(_LP64) +typedef long int khronos_int64_t; +typedef unsigned long int khronos_uint64_t; +#else +typedef long long int khronos_int64_t; +typedef unsigned long long int khronos_uint64_t; +#endif /* __arch64__ */ +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif 0 + +/* + * Hypothetical platform with no float or int64 support + */ +typedef int khronos_int32_t; +typedef unsigned int khronos_uint32_t; +#define KHRONOS_SUPPORT_INT64 0 +#define KHRONOS_SUPPORT_FLOAT 0 + +#else + +/* + * Generic fallback + */ +#include +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + #endif -#define GL_GLEXT_VERSION 20140521 + +/* + * Types that are (so far) the same on all platforms + */ +typedef signed char khronos_int8_t; +typedef unsigned char khronos_uint8_t; +typedef signed short int khronos_int16_t; +typedef unsigned short int khronos_uint16_t; + +/* + * Types that differ between LLP64 and LP64 architectures - in LLP64, + * pointers are 64 bits, but 'long' is still 32 bits. Win64 appears + * to be the only LLP64 architecture in current use. + */ +#ifdef KHRONOS_USE_INTPTR_T +typedef intptr_t khronos_intptr_t; +typedef uintptr_t khronos_uintptr_t; +#elif defined(_WIN64) +typedef signed long long int khronos_intptr_t; +typedef unsigned long long int khronos_uintptr_t; +#else +typedef signed long int khronos_intptr_t; +typedef unsigned long int khronos_uintptr_t; +#endif + +#if defined(_WIN64) +typedef signed long long int khronos_ssize_t; +typedef unsigned long long int khronos_usize_t; +#else +typedef signed long int khronos_ssize_t; +typedef unsigned long int khronos_usize_t; +#endif + +#if KHRONOS_SUPPORT_FLOAT +/* + * Float type + */ +typedef float khronos_float_t; +#endif + +#if KHRONOS_SUPPORT_INT64 +/* Time types + * + * These types can be used to represent a time interval in nanoseconds or + * an absolute Unadjusted System Time. Unadjusted System Time is the number + * of nanoseconds since some arbitrary system event (e.g. since the last + * time the system booted). The Unadjusted System Time is an unsigned + * 64 bit value that wraps back to 0 every 584 years. Time intervals + * may be either signed or unsigned. + */ +typedef khronos_uint64_t khronos_utime_nanoseconds_t; +typedef khronos_int64_t khronos_stime_nanoseconds_t; +#endif + +/* + * Dummy value used to pad enum types to 32 bits. + */ +#ifndef KHRONOS_MAX_ENUM +#define KHRONOS_MAX_ENUM 0x7FFFFFFF +#endif + +/* + * Enumerated boolean type + * + * Values other than zero should be considered to be true. Therefore + * comparisons should not be made against KHRONOS_TRUE. + */ +typedef enum { + KHRONOS_FALSE = 0, + KHRONOS_TRUE = 1, + KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM +} khronos_boolean_enum_t; + +#endif /* __khrplatform_h_ */ /* Generated C header for: * API: gl @@ -358,15 +651,17 @@ GLAPI void APIENTRY glMultTransposeMatrixd (const GLdouble *m); #define GL_TEXTURE_FILTER_CONTROL 0x8500 #define GL_DEPTH_TEXTURE_MODE 0x884B #define GL_COMPARE_R_TO_TEXTURE 0x884E -#define GL_FUNC_ADD 0x8006 -#define GL_FUNC_SUBTRACT 0x800A -#define GL_FUNC_REVERSE_SUBTRACT 0x800B -#define GL_MIN 0x8007 -#define GL_MAX 0x8008 +#define GL_BLEND_COLOR 0x8005 +#define GL_BLEND_EQUATION 0x8009 #define GL_CONSTANT_COLOR 0x8001 #define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 #define GL_CONSTANT_ALPHA 0x8003 #define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_FUNC_ADD 0x8006 +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_FUNC_SUBTRACT 0x800A +#define GL_MIN 0x8007 +#define GL_MAX 0x8008 typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount); typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount); @@ -467,14 +762,8 @@ GLAPI void APIENTRY glBlendEquation (GLenum mode); #ifndef GL_VERSION_1_5 #define GL_VERSION_1_5 1 -#include -#ifdef __MACOSX__ -typedef long GLsizeiptr; -typedef long GLintptr; -#else -typedef ptrdiff_t GLsizeiptr; -typedef ptrdiff_t GLintptr; -#endif +typedef khronos_ssize_t GLsizeiptr; +typedef khronos_intptr_t GLintptr; #define GL_BUFFER_SIZE 0x8764 #define GL_BUFFER_USAGE 0x8765 #define GL_QUERY_COUNTER_BITS 0x8864 @@ -887,7 +1176,7 @@ GLAPI void APIENTRY glUniformMatrix4x3fv (GLint location, GLsizei count, GLboole #ifndef GL_VERSION_3_0 #define GL_VERSION_3_0 1 -typedef unsigned short GLhalf; +typedef khronos_uint16_t GLhalf; #define GL_COMPARE_REF_TO_TEXTURE 0x884E #define GL_CLIP_DISTANCE0 0x3000 #define GL_CLIP_DISTANCE1 0x3001 @@ -1049,6 +1338,22 @@ typedef unsigned short GLhalf; #define GL_COLOR_ATTACHMENT13 0x8CED #define GL_COLOR_ATTACHMENT14 0x8CEE #define GL_COLOR_ATTACHMENT15 0x8CEF +#define GL_COLOR_ATTACHMENT16 0x8CF0 +#define GL_COLOR_ATTACHMENT17 0x8CF1 +#define GL_COLOR_ATTACHMENT18 0x8CF2 +#define GL_COLOR_ATTACHMENT19 0x8CF3 +#define GL_COLOR_ATTACHMENT20 0x8CF4 +#define GL_COLOR_ATTACHMENT21 0x8CF5 +#define GL_COLOR_ATTACHMENT22 0x8CF6 +#define GL_COLOR_ATTACHMENT23 0x8CF7 +#define GL_COLOR_ATTACHMENT24 0x8CF8 +#define GL_COLOR_ATTACHMENT25 0x8CF9 +#define GL_COLOR_ATTACHMENT26 0x8CFA +#define GL_COLOR_ATTACHMENT27 0x8CFB +#define GL_COLOR_ATTACHMENT28 0x8CFC +#define GL_COLOR_ATTACHMENT29 0x8CFD +#define GL_COLOR_ATTACHMENT30 0x8CFE +#define GL_COLOR_ATTACHMENT31 0x8CFF #define GL_DEPTH_ATTACHMENT 0x8D00 #define GL_STENCIL_ATTACHMENT 0x8D20 #define GL_FRAMEBUFFER 0x8D40 @@ -1316,11 +1621,13 @@ GLAPI GLboolean APIENTRY glIsVertexArray (GLuint array); #define GL_UNIFORM_BUFFER_START 0x8A29 #define GL_UNIFORM_BUFFER_SIZE 0x8A2A #define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B +#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C #define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D #define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E #define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F #define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 #define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 +#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32 #define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 #define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 #define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 @@ -1339,6 +1646,7 @@ GLAPI GLboolean APIENTRY glIsVertexArray (GLuint array); #define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 #define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 #define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45 #define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 #define GL_INVALID_INDEX 0xFFFFFFFFu typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount); @@ -1372,45 +1680,8 @@ GLAPI void APIENTRY glUniformBlockBinding (GLuint program, GLuint uniformBlockIn #ifndef GL_VERSION_3_2 #define GL_VERSION_3_2 1 typedef struct __GLsync *GLsync; -#ifndef GLEXT_64_TYPES_DEFINED -/* This code block is duplicated in glxext.h, so must be protected */ -#define GLEXT_64_TYPES_DEFINED -/* Define int32_t, int64_t, and uint64_t types for UST/MSC */ -/* (as used in the GL_EXT_timer_query extension). */ -#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L -#include -#elif defined(__sun__) || defined(__digital__) -#include -#if defined(__STDC__) -#if defined(__arch64__) || defined(_LP64) -typedef long int int64_t; -typedef unsigned long int uint64_t; -#else -typedef long long int int64_t; -typedef unsigned long long int uint64_t; -#endif /* __arch64__ */ -#endif /* __STDC__ */ -#elif defined( __VMS ) || defined(__sgi) -#include -#elif defined(__SCO__) || defined(__USLC__) -#include -#elif defined(__UNIXOS2__) || defined(__SOL64__) -typedef long int int32_t; -typedef long long int int64_t; -typedef unsigned long long int uint64_t; -#elif defined(_WIN32) && defined(__GNUC__) -#include -#elif defined(_WIN32) -typedef __int32 int32_t; -typedef __int64 int64_t; -typedef unsigned __int64 uint64_t; -#else -/* Fallback if nothing above works */ -#include -#endif -#endif -typedef uint64_t GLuint64; -typedef int64_t GLint64; +typedef khronos_uint64_t GLuint64; +typedef khronos_int64_t GLint64; #define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001 #define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002 #define GL_LINES_ADJACENCY 0x000A @@ -1486,7 +1757,7 @@ typedef void (APIENTRYP PFNGLDELETESYNCPROC) (GLsync sync); typedef GLenum (APIENTRYP PFNGLCLIENTWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); typedef void (APIENTRYP PFNGLWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); typedef void (APIENTRYP PFNGLGETINTEGER64VPROC) (GLenum pname, GLint64 *data); -typedef void (APIENTRYP PFNGLGETSYNCIVPROC) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +typedef void (APIENTRYP PFNGLGETSYNCIVPROC) (GLsync sync, GLenum pname, GLsizei count, GLsizei *length, GLint *values); typedef void (APIENTRYP PFNGLGETINTEGER64I_VPROC) (GLenum target, GLuint index, GLint64 *data); typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERI64VPROC) (GLenum target, GLenum pname, GLint64 *params); typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); @@ -1506,7 +1777,7 @@ GLAPI void APIENTRY glDeleteSync (GLsync sync); GLAPI GLenum APIENTRY glClientWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout); GLAPI void APIENTRY glWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout); GLAPI void APIENTRY glGetInteger64v (GLenum pname, GLint64 *data); -GLAPI void APIENTRY glGetSynciv (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +GLAPI void APIENTRY glGetSynciv (GLsync sync, GLenum pname, GLsizei count, GLsizei *length, GLint *values); GLAPI void APIENTRY glGetInteger64i_v (GLenum target, GLuint index, GLint64 *data); GLAPI void APIENTRY glGetBufferParameteri64v (GLenum target, GLenum pname, GLint64 *params); GLAPI void APIENTRY glFramebufferTexture (GLenum target, GLenum attachment, GLuint texture, GLint level); @@ -1762,8 +2033,8 @@ typedef void (APIENTRYP PFNGLGETUNIFORMDVPROC) (GLuint program, GLint location, typedef GLint (APIENTRYP PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC) (GLuint program, GLenum shadertype, const GLchar *name); typedef GLuint (APIENTRYP PFNGLGETSUBROUTINEINDEXPROC) (GLuint program, GLenum shadertype, const GLchar *name); typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC) (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values); -typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); -typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINENAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); +typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); +typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINENAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); typedef void (APIENTRYP PFNGLUNIFORMSUBROUTINESUIVPROC) (GLenum shadertype, GLsizei count, const GLuint *indices); typedef void (APIENTRYP PFNGLGETUNIFORMSUBROUTINEUIVPROC) (GLenum shadertype, GLint location, GLuint *params); typedef void (APIENTRYP PFNGLGETPROGRAMSTAGEIVPROC) (GLuint program, GLenum shadertype, GLenum pname, GLint *values); @@ -1809,8 +2080,8 @@ GLAPI void APIENTRY glGetUniformdv (GLuint program, GLint location, GLdouble *pa GLAPI GLint APIENTRY glGetSubroutineUniformLocation (GLuint program, GLenum shadertype, const GLchar *name); GLAPI GLuint APIENTRY glGetSubroutineIndex (GLuint program, GLenum shadertype, const GLchar *name); GLAPI void APIENTRY glGetActiveSubroutineUniformiv (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values); -GLAPI void APIENTRY glGetActiveSubroutineUniformName (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); -GLAPI void APIENTRY glGetActiveSubroutineName (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); +GLAPI void APIENTRY glGetActiveSubroutineUniformName (GLuint program, GLenum shadertype, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); +GLAPI void APIENTRY glGetActiveSubroutineName (GLuint program, GLenum shadertype, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); GLAPI void APIENTRY glUniformSubroutinesuiv (GLenum shadertype, GLsizei count, const GLuint *indices); GLAPI void APIENTRY glGetUniformSubroutineuiv (GLenum shadertype, GLint location, GLuint *params); GLAPI void APIENTRY glGetProgramStageiv (GLuint program, GLenum shadertype, GLenum pname, GLint *values); @@ -1868,7 +2139,7 @@ GLAPI void APIENTRY glGetQueryIndexediv (GLenum target, GLuint index, GLenum pna #define GL_VIEWPORT_INDEX_PROVOKING_VERTEX 0x825F #define GL_UNDEFINED_VERTEX 0x8260 typedef void (APIENTRYP PFNGLRELEASESHADERCOMPILERPROC) (void); -typedef void (APIENTRYP PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length); +typedef void (APIENTRYP PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint *shaders, GLenum binaryFormat, const void *binary, GLsizei length); typedef void (APIENTRYP PFNGLGETSHADERPRECISIONFORMATPROC) (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision); typedef void (APIENTRYP PFNGLDEPTHRANGEFPROC) (GLfloat n, GLfloat f); typedef void (APIENTRYP PFNGLCLEARDEPTHFPROC) (GLfloat d); @@ -1957,7 +2228,7 @@ typedef void (APIENTRYP PFNGLGETFLOATI_VPROC) (GLenum target, GLuint index, GLfl typedef void (APIENTRYP PFNGLGETDOUBLEI_VPROC) (GLenum target, GLuint index, GLdouble *data); #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glReleaseShaderCompiler (void); -GLAPI void APIENTRY glShaderBinary (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length); +GLAPI void APIENTRY glShaderBinary (GLsizei count, const GLuint *shaders, GLenum binaryFormat, const void *binary, GLsizei length); GLAPI void APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision); GLAPI void APIENTRY glDepthRangef (GLfloat n, GLfloat f); GLAPI void APIENTRY glClearDepthf (GLfloat d); @@ -2049,6 +2320,10 @@ GLAPI void APIENTRY glGetDoublei_v (GLenum target, GLuint index, GLdouble *data) #ifndef GL_VERSION_4_2 #define GL_VERSION_4_2 1 +#define GL_COPY_READ_BUFFER_BINDING 0x8F36 +#define GL_COPY_WRITE_BUFFER_BINDING 0x8F37 +#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24 +#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23 #define GL_UNPACK_COMPRESSED_BLOCK_WIDTH 0x9127 #define GL_UNPACK_COMPRESSED_BLOCK_HEIGHT 0x9128 #define GL_UNPACK_COMPRESSED_BLOCK_DEPTH 0x9129 @@ -2160,7 +2435,7 @@ GLAPI void APIENTRY glGetDoublei_v (GLenum target, GLuint index, GLdouble *data) typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance); typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance); typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance); -typedef void (APIENTRYP PFNGLGETINTERNALFORMATIVPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params); +typedef void (APIENTRYP PFNGLGETINTERNALFORMATIVPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei count, GLint *params); typedef void (APIENTRYP PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC) (GLuint program, GLuint bufferIndex, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLBINDIMAGETEXTUREPROC) (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); typedef void (APIENTRYP PFNGLMEMORYBARRIERPROC) (GLbitfield barriers); @@ -2173,7 +2448,7 @@ typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC) (GLenum m GLAPI void APIENTRY glDrawArraysInstancedBaseInstance (GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance); GLAPI void APIENTRY glDrawElementsInstancedBaseInstance (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance); GLAPI void APIENTRY glDrawElementsInstancedBaseVertexBaseInstance (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance); -GLAPI void APIENTRY glGetInternalformativ (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params); +GLAPI void APIENTRY glGetInternalformativ (GLenum target, GLenum internalformat, GLenum pname, GLsizei count, GLint *params); GLAPI void APIENTRY glGetActiveAtomicCounterBufferiv (GLuint program, GLuint bufferIndex, GLenum pname, GLint *params); GLAPI void APIENTRY glBindImageTexture (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); GLAPI void APIENTRY glMemoryBarrier (GLbitfield barriers); @@ -2220,6 +2495,7 @@ typedef void (APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum #define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER 0x90ED #define GL_DISPATCH_INDIRECT_BUFFER 0x90EE #define GL_DISPATCH_INDIRECT_BUFFER_BINDING 0x90EF +#define GL_COMPUTE_SHADER_BIT 0x00000020 #define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242 #define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243 #define GL_DEBUG_CALLBACK_FUNCTION 0x8244 @@ -2453,7 +2729,7 @@ typedef void (APIENTRYP PFNGLDISPATCHCOMPUTEINDIRECTPROC) (GLintptr indirect); typedef void (APIENTRYP PFNGLCOPYIMAGESUBDATAPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); typedef void (APIENTRYP PFNGLFRAMEBUFFERPARAMETERIPROC) (GLenum target, GLenum pname, GLint param); typedef void (APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETINTERNALFORMATI64VPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64 *params); +typedef void (APIENTRYP PFNGLGETINTERNALFORMATI64VPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei count, GLint64 *params); typedef void (APIENTRYP PFNGLINVALIDATETEXSUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); typedef void (APIENTRYP PFNGLINVALIDATETEXIMAGEPROC) (GLuint texture, GLint level); typedef void (APIENTRYP PFNGLINVALIDATEBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length); @@ -2465,7 +2741,7 @@ typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum typedef void (APIENTRYP PFNGLGETPROGRAMINTERFACEIVPROC) (GLuint program, GLenum programInterface, GLenum pname, GLint *params); typedef GLuint (APIENTRYP PFNGLGETPROGRAMRESOURCEINDEXPROC) (GLuint program, GLenum programInterface, const GLchar *name); typedef void (APIENTRYP PFNGLGETPROGRAMRESOURCENAMEPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); -typedef void (APIENTRYP PFNGLGETPROGRAMRESOURCEIVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params); +typedef void (APIENTRYP PFNGLGETPROGRAMRESOURCEIVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei count, GLsizei *length, GLint *params); typedef GLint (APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONPROC) (GLuint program, GLenum programInterface, const GLchar *name); typedef GLint (APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC) (GLuint program, GLenum programInterface, const GLchar *name); typedef void (APIENTRYP PFNGLSHADERSTORAGEBLOCKBINDINGPROC) (GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding); @@ -2497,7 +2773,7 @@ GLAPI void APIENTRY glDispatchComputeIndirect (GLintptr indirect); GLAPI void APIENTRY glCopyImageSubData (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); GLAPI void APIENTRY glFramebufferParameteri (GLenum target, GLenum pname, GLint param); GLAPI void APIENTRY glGetFramebufferParameteriv (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetInternalformati64v (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64 *params); +GLAPI void APIENTRY glGetInternalformati64v (GLenum target, GLenum internalformat, GLenum pname, GLsizei count, GLint64 *params); GLAPI void APIENTRY glInvalidateTexSubImage (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); GLAPI void APIENTRY glInvalidateTexImage (GLuint texture, GLint level); GLAPI void APIENTRY glInvalidateBufferSubData (GLuint buffer, GLintptr offset, GLsizeiptr length); @@ -2509,7 +2785,7 @@ GLAPI void APIENTRY glMultiDrawElementsIndirect (GLenum mode, GLenum type, const GLAPI void APIENTRY glGetProgramInterfaceiv (GLuint program, GLenum programInterface, GLenum pname, GLint *params); GLAPI GLuint APIENTRY glGetProgramResourceIndex (GLuint program, GLenum programInterface, const GLchar *name); GLAPI void APIENTRY glGetProgramResourceName (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); -GLAPI void APIENTRY glGetProgramResourceiv (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params); +GLAPI void APIENTRY glGetProgramResourceiv (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei count, GLsizei *length, GLint *params); GLAPI GLint APIENTRY glGetProgramResourceLocation (GLuint program, GLenum programInterface, const GLchar *name); GLAPI GLint APIENTRY glGetProgramResourceLocationIndex (GLuint program, GLenum programInterface, const GLchar *name); GLAPI void APIENTRY glShaderStorageBlockBinding (GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding); @@ -2579,10 +2855,345 @@ GLAPI void APIENTRY glBindVertexBuffers (GLuint first, GLsizei count, const GLui #endif #endif /* GL_VERSION_4_4 */ +#ifndef GL_VERSION_4_5 +#define GL_VERSION_4_5 1 +#define GL_CONTEXT_LOST 0x0507 +#define GL_NEGATIVE_ONE_TO_ONE 0x935E +#define GL_ZERO_TO_ONE 0x935F +#define GL_CLIP_ORIGIN 0x935C +#define GL_CLIP_DEPTH_MODE 0x935D +#define GL_QUERY_WAIT_INVERTED 0x8E17 +#define GL_QUERY_NO_WAIT_INVERTED 0x8E18 +#define GL_QUERY_BY_REGION_WAIT_INVERTED 0x8E19 +#define GL_QUERY_BY_REGION_NO_WAIT_INVERTED 0x8E1A +#define GL_MAX_CULL_DISTANCES 0x82F9 +#define GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES 0x82FA +#define GL_TEXTURE_TARGET 0x1006 +#define GL_QUERY_TARGET 0x82EA +#define GL_GUILTY_CONTEXT_RESET 0x8253 +#define GL_INNOCENT_CONTEXT_RESET 0x8254 +#define GL_UNKNOWN_CONTEXT_RESET 0x8255 +#define GL_RESET_NOTIFICATION_STRATEGY 0x8256 +#define GL_LOSE_CONTEXT_ON_RESET 0x8252 +#define GL_NO_RESET_NOTIFICATION 0x8261 +#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT 0x00000004 +#define GL_COLOR_TABLE 0x80D0 +#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1 +#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2 +#define GL_PROXY_COLOR_TABLE 0x80D3 +#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4 +#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5 +#define GL_CONVOLUTION_1D 0x8010 +#define GL_CONVOLUTION_2D 0x8011 +#define GL_SEPARABLE_2D 0x8012 +#define GL_HISTOGRAM 0x8024 +#define GL_PROXY_HISTOGRAM 0x8025 +#define GL_MINMAX 0x802E +#define GL_CONTEXT_RELEASE_BEHAVIOR 0x82FB +#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH 0x82FC +typedef void (APIENTRYP PFNGLCLIPCONTROLPROC) (GLenum origin, GLenum depth); +typedef void (APIENTRYP PFNGLCREATETRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint *ids); +typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC) (GLuint xfb, GLuint index, GLuint buffer); +typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC) (GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKIVPROC) (GLuint xfb, GLenum pname, GLint *param); +typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKI_VPROC) (GLuint xfb, GLenum pname, GLuint index, GLint *param); +typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKI64_VPROC) (GLuint xfb, GLenum pname, GLuint index, GLint64 *param); +typedef void (APIENTRYP PFNGLCREATEBUFFERSPROC) (GLsizei n, GLuint *buffers); +typedef void (APIENTRYP PFNGLNAMEDBUFFERSTORAGEPROC) (GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags); +typedef void (APIENTRYP PFNGLNAMEDBUFFERDATAPROC) (GLuint buffer, GLsizeiptr size, const void *data, GLenum usage); +typedef void (APIENTRYP PFNGLNAMEDBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data); +typedef void (APIENTRYP PFNGLCOPYNAMEDBUFFERSUBDATAPROC) (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +typedef void (APIENTRYP PFNGLCLEARNAMEDBUFFERDATAPROC) (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data); +typedef void (APIENTRYP PFNGLCLEARNAMEDBUFFERSUBDATAPROC) (GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); +typedef void *(APIENTRYP PFNGLMAPNAMEDBUFFERPROC) (GLuint buffer, GLenum access); +typedef void *(APIENTRYP PFNGLMAPNAMEDBUFFERRANGEPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access); +typedef GLboolean (APIENTRYP PFNGLUNMAPNAMEDBUFFERPROC) (GLuint buffer); +typedef void (APIENTRYP PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length); +typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERIVPROC) (GLuint buffer, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERI64VPROC) (GLuint buffer, GLenum pname, GLint64 *params); +typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPOINTERVPROC) (GLuint buffer, GLenum pname, void **params); +typedef void (APIENTRYP PFNGLGETNAMEDBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, void *data); +typedef void (APIENTRYP PFNGLCREATEFRAMEBUFFERSPROC) (GLsizei n, GLuint *framebuffers); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC) (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC) (GLuint framebuffer, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTUREPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC) (GLuint framebuffer, GLenum buf); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC) (GLuint framebuffer, GLsizei n, const GLenum *bufs); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC) (GLuint framebuffer, GLenum src); +typedef void (APIENTRYP PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC) (GLuint framebuffer, GLsizei numAttachments, const GLenum *attachments); +typedef void (APIENTRYP PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC) (GLuint framebuffer, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLCLEARNAMEDFRAMEBUFFERIVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint *value); +typedef void (APIENTRYP PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint *value); +typedef void (APIENTRYP PFNGLCLEARNAMEDFRAMEBUFFERFVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat *value); +typedef void (APIENTRYP PFNGLCLEARNAMEDFRAMEBUFFERFIPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); +typedef void (APIENTRYP PFNGLBLITNAMEDFRAMEBUFFERPROC) (GLuint readFramebuffer, GLuint drawFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +typedef GLenum (APIENTRYP PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC) (GLuint framebuffer, GLenum target); +typedef void (APIENTRYP PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC) (GLuint framebuffer, GLenum pname, GLint *param); +typedef void (APIENTRYP PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLCREATERENDERBUFFERSPROC) (GLsizei n, GLuint *renderbuffers); +typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEPROC) (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC) (GLuint renderbuffer, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLCREATETEXTURESPROC) (GLenum target, GLsizei n, GLuint *textures); +typedef void (APIENTRYP PFNGLTEXTUREBUFFERPROC) (GLuint texture, GLenum internalformat, GLuint buffer); +typedef void (APIENTRYP PFNGLTEXTUREBUFFERRANGEPROC) (GLuint texture, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); +typedef void (APIENTRYP PFNGLTEXTURESTORAGE1DPROC) (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width); +typedef void (APIENTRYP PFNGLTEXTURESTORAGE2DPROC) (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLTEXTURESTORAGE3DPROC) (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +typedef void (APIENTRYP PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC) (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +typedef void (APIENTRYP PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC) (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE1DPROC) (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE2DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE3DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC) (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); +typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); +typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE1DPROC) (GLuint texture, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE2DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE3DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLTEXTUREPARAMETERFPROC) (GLuint texture, GLenum pname, GLfloat param); +typedef void (APIENTRYP PFNGLTEXTUREPARAMETERFVPROC) (GLuint texture, GLenum pname, const GLfloat *param); +typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIPROC) (GLuint texture, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIIVPROC) (GLuint texture, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIUIVPROC) (GLuint texture, GLenum pname, const GLuint *params); +typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIVPROC) (GLuint texture, GLenum pname, const GLint *param); +typedef void (APIENTRYP PFNGLGENERATETEXTUREMIPMAPPROC) (GLuint texture); +typedef void (APIENTRYP PFNGLBINDTEXTUREUNITPROC) (GLuint unit, GLuint texture); +typedef void (APIENTRYP PFNGLGETTEXTUREIMAGEPROC) (GLuint texture, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels); +typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC) (GLuint texture, GLint level, GLsizei bufSize, void *pixels); +typedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERFVPROC) (GLuint texture, GLint level, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERIVPROC) (GLuint texture, GLint level, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERFVPROC) (GLuint texture, GLenum pname, GLfloat *params); +typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIIVPROC) (GLuint texture, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIUIVPROC) (GLuint texture, GLenum pname, GLuint *params); +typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIVPROC) (GLuint texture, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLCREATEVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays); +typedef void (APIENTRYP PFNGLDISABLEVERTEXARRAYATTRIBPROC) (GLuint vaobj, GLuint index); +typedef void (APIENTRYP PFNGLENABLEVERTEXARRAYATTRIBPROC) (GLuint vaobj, GLuint index); +typedef void (APIENTRYP PFNGLVERTEXARRAYELEMENTBUFFERPROC) (GLuint vaobj, GLuint buffer); +typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXBUFFERPROC) (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); +typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXBUFFERSPROC) (GLuint vaobj, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides); +typedef void (APIENTRYP PFNGLVERTEXARRAYATTRIBBINDINGPROC) (GLuint vaobj, GLuint attribindex, GLuint bindingindex); +typedef void (APIENTRYP PFNGLVERTEXARRAYATTRIBFORMATPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); +typedef void (APIENTRYP PFNGLVERTEXARRAYATTRIBIFORMATPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (APIENTRYP PFNGLVERTEXARRAYATTRIBLFORMATPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +typedef void (APIENTRYP PFNGLVERTEXARRAYBINDINGDIVISORPROC) (GLuint vaobj, GLuint bindingindex, GLuint divisor); +typedef void (APIENTRYP PFNGLGETVERTEXARRAYIVPROC) (GLuint vaobj, GLenum pname, GLint *param); +typedef void (APIENTRYP PFNGLGETVERTEXARRAYINDEXEDIVPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint *param); +typedef void (APIENTRYP PFNGLGETVERTEXARRAYINDEXED64IVPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint64 *param); +typedef void (APIENTRYP PFNGLCREATESAMPLERSPROC) (GLsizei n, GLuint *samplers); +typedef void (APIENTRYP PFNGLCREATEPROGRAMPIPELINESPROC) (GLsizei n, GLuint *pipelines); +typedef void (APIENTRYP PFNGLCREATEQUERIESPROC) (GLenum target, GLsizei n, GLuint *ids); +typedef void (APIENTRYP PFNGLGETQUERYBUFFEROBJECTI64VPROC) (GLuint id, GLuint buffer, GLenum pname, GLintptr offset); +typedef void (APIENTRYP PFNGLGETQUERYBUFFEROBJECTIVPROC) (GLuint id, GLuint buffer, GLenum pname, GLintptr offset); +typedef void (APIENTRYP PFNGLGETQUERYBUFFEROBJECTUI64VPROC) (GLuint id, GLuint buffer, GLenum pname, GLintptr offset); +typedef void (APIENTRYP PFNGLGETQUERYBUFFEROBJECTUIVPROC) (GLuint id, GLuint buffer, GLenum pname, GLintptr offset); +typedef void (APIENTRYP PFNGLMEMORYBARRIERBYREGIONPROC) (GLbitfield barriers); +typedef void (APIENTRYP PFNGLGETTEXTURESUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLsizei bufSize, void *pixels); +typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei bufSize, void *pixels); +typedef GLenum (APIENTRYP PFNGLGETGRAPHICSRESETSTATUSPROC) (void); +typedef void (APIENTRYP PFNGLGETNCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint lod, GLsizei bufSize, void *pixels); +typedef void (APIENTRYP PFNGLGETNTEXIMAGEPROC) (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels); +typedef void (APIENTRYP PFNGLGETNUNIFORMDVPROC) (GLuint program, GLint location, GLsizei bufSize, GLdouble *params); +typedef void (APIENTRYP PFNGLGETNUNIFORMFVPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); +typedef void (APIENTRYP PFNGLGETNUNIFORMIVPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params); +typedef void (APIENTRYP PFNGLGETNUNIFORMUIVPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint *params); +typedef void (APIENTRYP PFNGLREADNPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); +typedef void (APIENTRYP PFNGLGETNMAPDVPROC) (GLenum target, GLenum query, GLsizei bufSize, GLdouble *v); +typedef void (APIENTRYP PFNGLGETNMAPFVPROC) (GLenum target, GLenum query, GLsizei bufSize, GLfloat *v); +typedef void (APIENTRYP PFNGLGETNMAPIVPROC) (GLenum target, GLenum query, GLsizei bufSize, GLint *v); +typedef void (APIENTRYP PFNGLGETNPIXELMAPFVPROC) (GLenum map, GLsizei bufSize, GLfloat *values); +typedef void (APIENTRYP PFNGLGETNPIXELMAPUIVPROC) (GLenum map, GLsizei bufSize, GLuint *values); +typedef void (APIENTRYP PFNGLGETNPIXELMAPUSVPROC) (GLenum map, GLsizei bufSize, GLushort *values); +typedef void (APIENTRYP PFNGLGETNPOLYGONSTIPPLEPROC) (GLsizei bufSize, GLubyte *pattern); +typedef void (APIENTRYP PFNGLGETNCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *table); +typedef void (APIENTRYP PFNGLGETNCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *image); +typedef void (APIENTRYP PFNGLGETNSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, void *row, GLsizei columnBufSize, void *column, void *span); +typedef void (APIENTRYP PFNGLGETNHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); +typedef void (APIENTRYP PFNGLGETNMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); +typedef void (APIENTRYP PFNGLTEXTUREBARRIERPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glClipControl (GLenum origin, GLenum depth); +GLAPI void APIENTRY glCreateTransformFeedbacks (GLsizei n, GLuint *ids); +GLAPI void APIENTRY glTransformFeedbackBufferBase (GLuint xfb, GLuint index, GLuint buffer); +GLAPI void APIENTRY glTransformFeedbackBufferRange (GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +GLAPI void APIENTRY glGetTransformFeedbackiv (GLuint xfb, GLenum pname, GLint *param); +GLAPI void APIENTRY glGetTransformFeedbacki_v (GLuint xfb, GLenum pname, GLuint index, GLint *param); +GLAPI void APIENTRY glGetTransformFeedbacki64_v (GLuint xfb, GLenum pname, GLuint index, GLint64 *param); +GLAPI void APIENTRY glCreateBuffers (GLsizei n, GLuint *buffers); +GLAPI void APIENTRY glNamedBufferStorage (GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags); +GLAPI void APIENTRY glNamedBufferData (GLuint buffer, GLsizeiptr size, const void *data, GLenum usage); +GLAPI void APIENTRY glNamedBufferSubData (GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data); +GLAPI void APIENTRY glCopyNamedBufferSubData (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +GLAPI void APIENTRY glClearNamedBufferData (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data); +GLAPI void APIENTRY glClearNamedBufferSubData (GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); +GLAPI void *APIENTRY glMapNamedBuffer (GLuint buffer, GLenum access); +GLAPI void *APIENTRY glMapNamedBufferRange (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access); +GLAPI GLboolean APIENTRY glUnmapNamedBuffer (GLuint buffer); +GLAPI void APIENTRY glFlushMappedNamedBufferRange (GLuint buffer, GLintptr offset, GLsizeiptr length); +GLAPI void APIENTRY glGetNamedBufferParameteriv (GLuint buffer, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetNamedBufferParameteri64v (GLuint buffer, GLenum pname, GLint64 *params); +GLAPI void APIENTRY glGetNamedBufferPointerv (GLuint buffer, GLenum pname, void **params); +GLAPI void APIENTRY glGetNamedBufferSubData (GLuint buffer, GLintptr offset, GLsizeiptr size, void *data); +GLAPI void APIENTRY glCreateFramebuffers (GLsizei n, GLuint *framebuffers); +GLAPI void APIENTRY glNamedFramebufferRenderbuffer (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +GLAPI void APIENTRY glNamedFramebufferParameteri (GLuint framebuffer, GLenum pname, GLint param); +GLAPI void APIENTRY glNamedFramebufferTexture (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); +GLAPI void APIENTRY glNamedFramebufferTextureLayer (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); +GLAPI void APIENTRY glNamedFramebufferDrawBuffer (GLuint framebuffer, GLenum buf); +GLAPI void APIENTRY glNamedFramebufferDrawBuffers (GLuint framebuffer, GLsizei n, const GLenum *bufs); +GLAPI void APIENTRY glNamedFramebufferReadBuffer (GLuint framebuffer, GLenum src); +GLAPI void APIENTRY glInvalidateNamedFramebufferData (GLuint framebuffer, GLsizei numAttachments, const GLenum *attachments); +GLAPI void APIENTRY glInvalidateNamedFramebufferSubData (GLuint framebuffer, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void APIENTRY glClearNamedFramebufferiv (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint *value); +GLAPI void APIENTRY glClearNamedFramebufferuiv (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint *value); +GLAPI void APIENTRY glClearNamedFramebufferfv (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat *value); +GLAPI void APIENTRY glClearNamedFramebufferfi (GLuint framebuffer, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); +GLAPI void APIENTRY glBlitNamedFramebuffer (GLuint readFramebuffer, GLuint drawFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +GLAPI GLenum APIENTRY glCheckNamedFramebufferStatus (GLuint framebuffer, GLenum target); +GLAPI void APIENTRY glGetNamedFramebufferParameteriv (GLuint framebuffer, GLenum pname, GLint *param); +GLAPI void APIENTRY glGetNamedFramebufferAttachmentParameteriv (GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params); +GLAPI void APIENTRY glCreateRenderbuffers (GLsizei n, GLuint *renderbuffers); +GLAPI void APIENTRY glNamedRenderbufferStorage (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI void APIENTRY glNamedRenderbufferStorageMultisample (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI void APIENTRY glGetNamedRenderbufferParameteriv (GLuint renderbuffer, GLenum pname, GLint *params); +GLAPI void APIENTRY glCreateTextures (GLenum target, GLsizei n, GLuint *textures); +GLAPI void APIENTRY glTextureBuffer (GLuint texture, GLenum internalformat, GLuint buffer); +GLAPI void APIENTRY glTextureBufferRange (GLuint texture, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); +GLAPI void APIENTRY glTextureStorage1D (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width); +GLAPI void APIENTRY glTextureStorage2D (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI void APIENTRY glTextureStorage3D (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +GLAPI void APIENTRY glTextureStorage2DMultisample (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +GLAPI void APIENTRY glTextureStorage3DMultisample (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +GLAPI void APIENTRY glTextureSubImage1D (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glTextureSubImage2D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glTextureSubImage3D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); +GLAPI void APIENTRY glCompressedTextureSubImage1D (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); +GLAPI void APIENTRY glCompressedTextureSubImage2D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); +GLAPI void APIENTRY glCompressedTextureSubImage3D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); +GLAPI void APIENTRY glCopyTextureSubImage1D (GLuint texture, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +GLAPI void APIENTRY glCopyTextureSubImage2D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void APIENTRY glCopyTextureSubImage3D (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void APIENTRY glTextureParameterf (GLuint texture, GLenum pname, GLfloat param); +GLAPI void APIENTRY glTextureParameterfv (GLuint texture, GLenum pname, const GLfloat *param); +GLAPI void APIENTRY glTextureParameteri (GLuint texture, GLenum pname, GLint param); +GLAPI void APIENTRY glTextureParameterIiv (GLuint texture, GLenum pname, const GLint *params); +GLAPI void APIENTRY glTextureParameterIuiv (GLuint texture, GLenum pname, const GLuint *params); +GLAPI void APIENTRY glTextureParameteriv (GLuint texture, GLenum pname, const GLint *param); +GLAPI void APIENTRY glGenerateTextureMipmap (GLuint texture); +GLAPI void APIENTRY glBindTextureUnit (GLuint unit, GLuint texture); +GLAPI void APIENTRY glGetTextureImage (GLuint texture, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels); +GLAPI void APIENTRY glGetCompressedTextureImage (GLuint texture, GLint level, GLsizei bufSize, void *pixels); +GLAPI void APIENTRY glGetTextureLevelParameterfv (GLuint texture, GLint level, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetTextureLevelParameteriv (GLuint texture, GLint level, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetTextureParameterfv (GLuint texture, GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetTextureParameterIiv (GLuint texture, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetTextureParameterIuiv (GLuint texture, GLenum pname, GLuint *params); +GLAPI void APIENTRY glGetTextureParameteriv (GLuint texture, GLenum pname, GLint *params); +GLAPI void APIENTRY glCreateVertexArrays (GLsizei n, GLuint *arrays); +GLAPI void APIENTRY glDisableVertexArrayAttrib (GLuint vaobj, GLuint index); +GLAPI void APIENTRY glEnableVertexArrayAttrib (GLuint vaobj, GLuint index); +GLAPI void APIENTRY glVertexArrayElementBuffer (GLuint vaobj, GLuint buffer); +GLAPI void APIENTRY glVertexArrayVertexBuffer (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); +GLAPI void APIENTRY glVertexArrayVertexBuffers (GLuint vaobj, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides); +GLAPI void APIENTRY glVertexArrayAttribBinding (GLuint vaobj, GLuint attribindex, GLuint bindingindex); +GLAPI void APIENTRY glVertexArrayAttribFormat (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); +GLAPI void APIENTRY glVertexArrayAttribIFormat (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +GLAPI void APIENTRY glVertexArrayAttribLFormat (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +GLAPI void APIENTRY glVertexArrayBindingDivisor (GLuint vaobj, GLuint bindingindex, GLuint divisor); +GLAPI void APIENTRY glGetVertexArrayiv (GLuint vaobj, GLenum pname, GLint *param); +GLAPI void APIENTRY glGetVertexArrayIndexediv (GLuint vaobj, GLuint index, GLenum pname, GLint *param); +GLAPI void APIENTRY glGetVertexArrayIndexed64iv (GLuint vaobj, GLuint index, GLenum pname, GLint64 *param); +GLAPI void APIENTRY glCreateSamplers (GLsizei n, GLuint *samplers); +GLAPI void APIENTRY glCreateProgramPipelines (GLsizei n, GLuint *pipelines); +GLAPI void APIENTRY glCreateQueries (GLenum target, GLsizei n, GLuint *ids); +GLAPI void APIENTRY glGetQueryBufferObjecti64v (GLuint id, GLuint buffer, GLenum pname, GLintptr offset); +GLAPI void APIENTRY glGetQueryBufferObjectiv (GLuint id, GLuint buffer, GLenum pname, GLintptr offset); +GLAPI void APIENTRY glGetQueryBufferObjectui64v (GLuint id, GLuint buffer, GLenum pname, GLintptr offset); +GLAPI void APIENTRY glGetQueryBufferObjectuiv (GLuint id, GLuint buffer, GLenum pname, GLintptr offset); +GLAPI void APIENTRY glMemoryBarrierByRegion (GLbitfield barriers); +GLAPI void APIENTRY glGetTextureSubImage (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLsizei bufSize, void *pixels); +GLAPI void APIENTRY glGetCompressedTextureSubImage (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei bufSize, void *pixels); +GLAPI GLenum APIENTRY glGetGraphicsResetStatus (void); +GLAPI void APIENTRY glGetnCompressedTexImage (GLenum target, GLint lod, GLsizei bufSize, void *pixels); +GLAPI void APIENTRY glGetnTexImage (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels); +GLAPI void APIENTRY glGetnUniformdv (GLuint program, GLint location, GLsizei bufSize, GLdouble *params); +GLAPI void APIENTRY glGetnUniformfv (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); +GLAPI void APIENTRY glGetnUniformiv (GLuint program, GLint location, GLsizei bufSize, GLint *params); +GLAPI void APIENTRY glGetnUniformuiv (GLuint program, GLint location, GLsizei bufSize, GLuint *params); +GLAPI void APIENTRY glReadnPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); +GLAPI void APIENTRY glGetnMapdv (GLenum target, GLenum query, GLsizei bufSize, GLdouble *v); +GLAPI void APIENTRY glGetnMapfv (GLenum target, GLenum query, GLsizei bufSize, GLfloat *v); +GLAPI void APIENTRY glGetnMapiv (GLenum target, GLenum query, GLsizei bufSize, GLint *v); +GLAPI void APIENTRY glGetnPixelMapfv (GLenum map, GLsizei bufSize, GLfloat *values); +GLAPI void APIENTRY glGetnPixelMapuiv (GLenum map, GLsizei bufSize, GLuint *values); +GLAPI void APIENTRY glGetnPixelMapusv (GLenum map, GLsizei bufSize, GLushort *values); +GLAPI void APIENTRY glGetnPolygonStipple (GLsizei bufSize, GLubyte *pattern); +GLAPI void APIENTRY glGetnColorTable (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *table); +GLAPI void APIENTRY glGetnConvolutionFilter (GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *image); +GLAPI void APIENTRY glGetnSeparableFilter (GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, void *row, GLsizei columnBufSize, void *column, void *span); +GLAPI void APIENTRY glGetnHistogram (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); +GLAPI void APIENTRY glGetnMinmax (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); +GLAPI void APIENTRY glTextureBarrier (void); +#endif +#endif /* GL_VERSION_4_5 */ + +#ifndef GL_VERSION_4_6 +#define GL_VERSION_4_6 1 +#define GL_SHADER_BINARY_FORMAT_SPIR_V 0x9551 +#define GL_SPIR_V_BINARY 0x9552 +#define GL_PARAMETER_BUFFER 0x80EE +#define GL_PARAMETER_BUFFER_BINDING 0x80EF +#define GL_CONTEXT_FLAG_NO_ERROR_BIT 0x00000008 +#define GL_VERTICES_SUBMITTED 0x82EE +#define GL_PRIMITIVES_SUBMITTED 0x82EF +#define GL_VERTEX_SHADER_INVOCATIONS 0x82F0 +#define GL_TESS_CONTROL_SHADER_PATCHES 0x82F1 +#define GL_TESS_EVALUATION_SHADER_INVOCATIONS 0x82F2 +#define GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED 0x82F3 +#define GL_FRAGMENT_SHADER_INVOCATIONS 0x82F4 +#define GL_COMPUTE_SHADER_INVOCATIONS 0x82F5 +#define GL_CLIPPING_INPUT_PRIMITIVES 0x82F6 +#define GL_CLIPPING_OUTPUT_PRIMITIVES 0x82F7 +#define GL_POLYGON_OFFSET_CLAMP 0x8E1B +#define GL_SPIR_V_EXTENSIONS 0x9553 +#define GL_NUM_SPIR_V_EXTENSIONS 0x9554 +#define GL_TEXTURE_MAX_ANISOTROPY 0x84FE +#define GL_MAX_TEXTURE_MAX_ANISOTROPY 0x84FF +#define GL_TRANSFORM_FEEDBACK_OVERFLOW 0x82EC +#define GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW 0x82ED +typedef void (APIENTRYP PFNGLSPECIALIZESHADERPROC) (GLuint shader, const GLchar *pEntryPoint, GLuint numSpecializationConstants, const GLuint *pConstantIndex, const GLuint *pConstantValue); +typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC) (GLenum mode, const void *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC) (GLenum mode, GLenum type, const void *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +typedef void (APIENTRYP PFNGLPOLYGONOFFSETCLAMPPROC) (GLfloat factor, GLfloat units, GLfloat clamp); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSpecializeShader (GLuint shader, const GLchar *pEntryPoint, GLuint numSpecializationConstants, const GLuint *pConstantIndex, const GLuint *pConstantValue); +GLAPI void APIENTRY glMultiDrawArraysIndirectCount (GLenum mode, const void *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +GLAPI void APIENTRY glMultiDrawElementsIndirectCount (GLenum mode, GLenum type, const void *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +GLAPI void APIENTRY glPolygonOffsetClamp (GLfloat factor, GLfloat units, GLfloat clamp); +#endif +#endif /* GL_VERSION_4_6 */ + #ifndef GL_ARB_ES2_compatibility #define GL_ARB_ES2_compatibility 1 #endif /* GL_ARB_ES2_compatibility */ +#ifndef GL_ARB_ES3_1_compatibility +#define GL_ARB_ES3_1_compatibility 1 +#endif /* GL_ARB_ES3_1_compatibility */ + +#ifndef GL_ARB_ES3_2_compatibility +#define GL_ARB_ES3_2_compatibility 1 +#define GL_PRIMITIVE_BOUNDING_BOX_ARB 0x92BE +#define GL_MULTISAMPLE_LINE_WIDTH_RANGE_ARB 0x9381 +#define GL_MULTISAMPLE_LINE_WIDTH_GRANULARITY_ARB 0x9382 +typedef void (APIENTRYP PFNGLPRIMITIVEBOUNDINGBOXARBPROC) (GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPrimitiveBoundingBoxARB (GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW); +#endif +#endif /* GL_ARB_ES3_2_compatibility */ + #ifndef GL_ARB_ES3_compatibility #define GL_ARB_ES3_compatibility 1 #endif /* GL_ARB_ES3_compatibility */ @@ -2597,7 +3208,7 @@ GLAPI void APIENTRY glBindVertexBuffers (GLuint first, GLsizei count, const GLui #ifndef GL_ARB_bindless_texture #define GL_ARB_bindless_texture 1 -typedef uint64_t GLuint64EXT; +typedef khronos_uint64_t GLuint64EXT; #define GL_UNSIGNED_INT64_ARB 0x140F typedef GLuint64 (APIENTRYP PFNGLGETTEXTUREHANDLEARBPROC) (GLuint texture); typedef GLuint64 (APIENTRYP PFNGLGETTEXTURESAMPLERHANDLEARBPROC) (GLuint texture, GLuint sampler); @@ -2663,6 +3274,10 @@ GLAPI GLsync APIENTRY glCreateSyncFromCLeventARB (struct _cl_context *context, s #define GL_ARB_clear_texture 1 #endif /* GL_ARB_clear_texture */ +#ifndef GL_ARB_clip_control +#define GL_ARB_clip_control 1 +#endif /* GL_ARB_clip_control */ + #ifndef GL_ARB_color_buffer_float #define GL_ARB_color_buffer_float 1 #define GL_RGBA_FLOAT_MODE_ARB 0x8820 @@ -2686,7 +3301,6 @@ GLAPI void APIENTRY glClampColorARB (GLenum target, GLenum clamp); #ifndef GL_ARB_compute_shader #define GL_ARB_compute_shader 1 -#define GL_COMPUTE_SHADER_BIT 0x00000020 #endif /* GL_ARB_compute_shader */ #ifndef GL_ARB_compute_variable_group_size @@ -2701,20 +3315,26 @@ GLAPI void APIENTRY glDispatchComputeGroupSizeARB (GLuint num_groups_x, GLuint n #endif #endif /* GL_ARB_compute_variable_group_size */ +#ifndef GL_ARB_conditional_render_inverted +#define GL_ARB_conditional_render_inverted 1 +#endif /* GL_ARB_conditional_render_inverted */ + #ifndef GL_ARB_conservative_depth #define GL_ARB_conservative_depth 1 #endif /* GL_ARB_conservative_depth */ #ifndef GL_ARB_copy_buffer #define GL_ARB_copy_buffer 1 -#define GL_COPY_READ_BUFFER_BINDING 0x8F36 -#define GL_COPY_WRITE_BUFFER_BINDING 0x8F37 #endif /* GL_ARB_copy_buffer */ #ifndef GL_ARB_copy_image #define GL_ARB_copy_image 1 #endif /* GL_ARB_copy_image */ +#ifndef GL_ARB_cull_distance +#define GL_ARB_cull_distance 1 +#endif /* GL_ARB_cull_distance */ + #ifndef GL_ARB_debug_output #define GL_ARB_debug_output 1 typedef void (APIENTRY *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); @@ -2769,6 +3389,14 @@ GLAPI GLuint APIENTRY glGetDebugMessageLogARB (GLuint count, GLsizei bufSize, GL #define GL_DEPTH_TEXTURE_MODE_ARB 0x884B #endif /* GL_ARB_depth_texture */ +#ifndef GL_ARB_derivative_control +#define GL_ARB_derivative_control 1 +#endif /* GL_ARB_derivative_control */ + +#ifndef GL_ARB_direct_state_access +#define GL_ARB_direct_state_access 1 +#endif /* GL_ARB_direct_state_access */ + #ifndef GL_ARB_draw_buffers #define GL_ARB_draw_buffers 1 #define GL_MAX_DRAW_BUFFERS_ARB 0x8824 @@ -2979,6 +3607,10 @@ GLAPI GLboolean APIENTRY glIsProgramARB (GLuint program); #define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB 0x8B8B #endif /* GL_ARB_fragment_shader */ +#ifndef GL_ARB_fragment_shader_interlock +#define GL_ARB_fragment_shader_interlock 1 +#endif /* GL_ARB_fragment_shader_interlock */ + #ifndef GL_ARB_framebuffer_no_attachments #define GL_ARB_framebuffer_no_attachments 1 #endif /* GL_ARB_framebuffer_no_attachments */ @@ -2991,11 +3623,6 @@ GLAPI GLboolean APIENTRY glIsProgramARB (GLuint program); #define GL_ARB_framebuffer_sRGB 1 #endif /* GL_ARB_framebuffer_sRGB */ -#ifndef GL_KHR_context_flush_control -#define GL_CONTEXT_RELEASE_BEHAVIOR 0x82FB -#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH 0x82FC -#endif /* GL_KHR_context_flush_control */ - #ifndef GL_ARB_geometry_shader4 #define GL_ARB_geometry_shader4 1 #define GL_LINES_ADJACENCY_ARB 0x000A @@ -3032,6 +3659,20 @@ GLAPI void APIENTRY glFramebufferTextureFaceARB (GLenum target, GLenum attachmen #define GL_ARB_get_program_binary 1 #endif /* GL_ARB_get_program_binary */ +#ifndef GL_ARB_get_texture_sub_image +#define GL_ARB_get_texture_sub_image 1 +#endif /* GL_ARB_get_texture_sub_image */ + +#ifndef GL_ARB_gl_spirv +#define GL_ARB_gl_spirv 1 +#define GL_SHADER_BINARY_FORMAT_SPIR_V_ARB 0x9551 +#define GL_SPIR_V_BINARY_ARB 0x9552 +typedef void (APIENTRYP PFNGLSPECIALIZESHADERARBPROC) (GLuint shader, const GLchar *pEntryPoint, GLuint numSpecializationConstants, const GLuint *pConstantIndex, const GLuint *pConstantValue); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSpecializeShaderARB (GLuint shader, const GLchar *pEntryPoint, GLuint numSpecializationConstants, const GLuint *pConstantIndex, const GLuint *pConstantValue); +#endif +#endif /* GL_ARB_gl_spirv */ + #ifndef GL_ARB_gpu_shader5 #define GL_ARB_gpu_shader5 1 #endif /* GL_ARB_gpu_shader5 */ @@ -3040,9 +3681,94 @@ GLAPI void APIENTRY glFramebufferTextureFaceARB (GLenum target, GLenum attachmen #define GL_ARB_gpu_shader_fp64 1 #endif /* GL_ARB_gpu_shader_fp64 */ +#ifndef GL_ARB_gpu_shader_int64 +#define GL_ARB_gpu_shader_int64 1 +#define GL_INT64_ARB 0x140E +#define GL_INT64_VEC2_ARB 0x8FE9 +#define GL_INT64_VEC3_ARB 0x8FEA +#define GL_INT64_VEC4_ARB 0x8FEB +#define GL_UNSIGNED_INT64_VEC2_ARB 0x8FF5 +#define GL_UNSIGNED_INT64_VEC3_ARB 0x8FF6 +#define GL_UNSIGNED_INT64_VEC4_ARB 0x8FF7 +typedef void (APIENTRYP PFNGLUNIFORM1I64ARBPROC) (GLint location, GLint64 x); +typedef void (APIENTRYP PFNGLUNIFORM2I64ARBPROC) (GLint location, GLint64 x, GLint64 y); +typedef void (APIENTRYP PFNGLUNIFORM3I64ARBPROC) (GLint location, GLint64 x, GLint64 y, GLint64 z); +typedef void (APIENTRYP PFNGLUNIFORM4I64ARBPROC) (GLint location, GLint64 x, GLint64 y, GLint64 z, GLint64 w); +typedef void (APIENTRYP PFNGLUNIFORM1I64VARBPROC) (GLint location, GLsizei count, const GLint64 *value); +typedef void (APIENTRYP PFNGLUNIFORM2I64VARBPROC) (GLint location, GLsizei count, const GLint64 *value); +typedef void (APIENTRYP PFNGLUNIFORM3I64VARBPROC) (GLint location, GLsizei count, const GLint64 *value); +typedef void (APIENTRYP PFNGLUNIFORM4I64VARBPROC) (GLint location, GLsizei count, const GLint64 *value); +typedef void (APIENTRYP PFNGLUNIFORM1UI64ARBPROC) (GLint location, GLuint64 x); +typedef void (APIENTRYP PFNGLUNIFORM2UI64ARBPROC) (GLint location, GLuint64 x, GLuint64 y); +typedef void (APIENTRYP PFNGLUNIFORM3UI64ARBPROC) (GLint location, GLuint64 x, GLuint64 y, GLuint64 z); +typedef void (APIENTRYP PFNGLUNIFORM4UI64ARBPROC) (GLint location, GLuint64 x, GLuint64 y, GLuint64 z, GLuint64 w); +typedef void (APIENTRYP PFNGLUNIFORM1UI64VARBPROC) (GLint location, GLsizei count, const GLuint64 *value); +typedef void (APIENTRYP PFNGLUNIFORM2UI64VARBPROC) (GLint location, GLsizei count, const GLuint64 *value); +typedef void (APIENTRYP PFNGLUNIFORM3UI64VARBPROC) (GLint location, GLsizei count, const GLuint64 *value); +typedef void (APIENTRYP PFNGLUNIFORM4UI64VARBPROC) (GLint location, GLsizei count, const GLuint64 *value); +typedef void (APIENTRYP PFNGLGETUNIFORMI64VARBPROC) (GLuint program, GLint location, GLint64 *params); +typedef void (APIENTRYP PFNGLGETUNIFORMUI64VARBPROC) (GLuint program, GLint location, GLuint64 *params); +typedef void (APIENTRYP PFNGLGETNUNIFORMI64VARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLint64 *params); +typedef void (APIENTRYP PFNGLGETNUNIFORMUI64VARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint64 *params); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1I64ARBPROC) (GLuint program, GLint location, GLint64 x); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2I64ARBPROC) (GLuint program, GLint location, GLint64 x, GLint64 y); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3I64ARBPROC) (GLuint program, GLint location, GLint64 x, GLint64 y, GLint64 z); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4I64ARBPROC) (GLuint program, GLint location, GLint64 x, GLint64 y, GLint64 z, GLint64 w); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1I64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLint64 *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2I64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLint64 *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3I64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLint64 *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4I64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLint64 *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UI64ARBPROC) (GLuint program, GLint location, GLuint64 x); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UI64ARBPROC) (GLuint program, GLint location, GLuint64 x, GLuint64 y); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UI64ARBPROC) (GLuint program, GLint location, GLuint64 x, GLuint64 y, GLuint64 z); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UI64ARBPROC) (GLuint program, GLint location, GLuint64 x, GLuint64 y, GLuint64 z, GLuint64 w); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UI64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UI64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UI64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 *value); +typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UI64VARBPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 *value); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glUniform1i64ARB (GLint location, GLint64 x); +GLAPI void APIENTRY glUniform2i64ARB (GLint location, GLint64 x, GLint64 y); +GLAPI void APIENTRY glUniform3i64ARB (GLint location, GLint64 x, GLint64 y, GLint64 z); +GLAPI void APIENTRY glUniform4i64ARB (GLint location, GLint64 x, GLint64 y, GLint64 z, GLint64 w); +GLAPI void APIENTRY glUniform1i64vARB (GLint location, GLsizei count, const GLint64 *value); +GLAPI void APIENTRY glUniform2i64vARB (GLint location, GLsizei count, const GLint64 *value); +GLAPI void APIENTRY glUniform3i64vARB (GLint location, GLsizei count, const GLint64 *value); +GLAPI void APIENTRY glUniform4i64vARB (GLint location, GLsizei count, const GLint64 *value); +GLAPI void APIENTRY glUniform1ui64ARB (GLint location, GLuint64 x); +GLAPI void APIENTRY glUniform2ui64ARB (GLint location, GLuint64 x, GLuint64 y); +GLAPI void APIENTRY glUniform3ui64ARB (GLint location, GLuint64 x, GLuint64 y, GLuint64 z); +GLAPI void APIENTRY glUniform4ui64ARB (GLint location, GLuint64 x, GLuint64 y, GLuint64 z, GLuint64 w); +GLAPI void APIENTRY glUniform1ui64vARB (GLint location, GLsizei count, const GLuint64 *value); +GLAPI void APIENTRY glUniform2ui64vARB (GLint location, GLsizei count, const GLuint64 *value); +GLAPI void APIENTRY glUniform3ui64vARB (GLint location, GLsizei count, const GLuint64 *value); +GLAPI void APIENTRY glUniform4ui64vARB (GLint location, GLsizei count, const GLuint64 *value); +GLAPI void APIENTRY glGetUniformi64vARB (GLuint program, GLint location, GLint64 *params); +GLAPI void APIENTRY glGetUniformui64vARB (GLuint program, GLint location, GLuint64 *params); +GLAPI void APIENTRY glGetnUniformi64vARB (GLuint program, GLint location, GLsizei bufSize, GLint64 *params); +GLAPI void APIENTRY glGetnUniformui64vARB (GLuint program, GLint location, GLsizei bufSize, GLuint64 *params); +GLAPI void APIENTRY glProgramUniform1i64ARB (GLuint program, GLint location, GLint64 x); +GLAPI void APIENTRY glProgramUniform2i64ARB (GLuint program, GLint location, GLint64 x, GLint64 y); +GLAPI void APIENTRY glProgramUniform3i64ARB (GLuint program, GLint location, GLint64 x, GLint64 y, GLint64 z); +GLAPI void APIENTRY glProgramUniform4i64ARB (GLuint program, GLint location, GLint64 x, GLint64 y, GLint64 z, GLint64 w); +GLAPI void APIENTRY glProgramUniform1i64vARB (GLuint program, GLint location, GLsizei count, const GLint64 *value); +GLAPI void APIENTRY glProgramUniform2i64vARB (GLuint program, GLint location, GLsizei count, const GLint64 *value); +GLAPI void APIENTRY glProgramUniform3i64vARB (GLuint program, GLint location, GLsizei count, const GLint64 *value); +GLAPI void APIENTRY glProgramUniform4i64vARB (GLuint program, GLint location, GLsizei count, const GLint64 *value); +GLAPI void APIENTRY glProgramUniform1ui64ARB (GLuint program, GLint location, GLuint64 x); +GLAPI void APIENTRY glProgramUniform2ui64ARB (GLuint program, GLint location, GLuint64 x, GLuint64 y); +GLAPI void APIENTRY glProgramUniform3ui64ARB (GLuint program, GLint location, GLuint64 x, GLuint64 y, GLuint64 z); +GLAPI void APIENTRY glProgramUniform4ui64ARB (GLuint program, GLint location, GLuint64 x, GLuint64 y, GLuint64 z, GLuint64 w); +GLAPI void APIENTRY glProgramUniform1ui64vARB (GLuint program, GLint location, GLsizei count, const GLuint64 *value); +GLAPI void APIENTRY glProgramUniform2ui64vARB (GLuint program, GLint location, GLsizei count, const GLuint64 *value); +GLAPI void APIENTRY glProgramUniform3ui64vARB (GLuint program, GLint location, GLsizei count, const GLuint64 *value); +GLAPI void APIENTRY glProgramUniform4ui64vARB (GLuint program, GLint location, GLsizei count, const GLuint64 *value); +#endif +#endif /* GL_ARB_gpu_shader_int64 */ + #ifndef GL_ARB_half_float_pixel #define GL_ARB_half_float_pixel 1 -typedef unsigned short GLhalfARB; +typedef khronos_uint16_t GLhalfARB; #define GL_HALF_FLOAT_ARB 0x140B #endif /* GL_ARB_half_float_pixel */ @@ -3052,11 +3778,6 @@ typedef unsigned short GLhalfARB; #ifndef GL_ARB_imaging #define GL_ARB_imaging 1 -#define GL_BLEND_COLOR 0x8005 -#define GL_BLEND_EQUATION 0x8009 -#define GL_CONVOLUTION_1D 0x8010 -#define GL_CONVOLUTION_2D 0x8011 -#define GL_SEPARABLE_2D 0x8012 #define GL_CONVOLUTION_BORDER_MODE 0x8013 #define GL_CONVOLUTION_FILTER_SCALE 0x8014 #define GL_CONVOLUTION_FILTER_BIAS 0x8015 @@ -3074,8 +3795,6 @@ typedef unsigned short GLhalfARB; #define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021 #define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022 #define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023 -#define GL_HISTOGRAM 0x8024 -#define GL_PROXY_HISTOGRAM 0x8025 #define GL_HISTOGRAM_WIDTH 0x8026 #define GL_HISTOGRAM_FORMAT 0x8027 #define GL_HISTOGRAM_RED_SIZE 0x8028 @@ -3084,7 +3803,6 @@ typedef unsigned short GLhalfARB; #define GL_HISTOGRAM_ALPHA_SIZE 0x802B #define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C #define GL_HISTOGRAM_SINK 0x802D -#define GL_MINMAX 0x802E #define GL_MINMAX_FORMAT 0x802F #define GL_MINMAX_SINK 0x8030 #define GL_TABLE_TOO_LARGE 0x8031 @@ -3099,12 +3817,6 @@ typedef unsigned short GLhalfARB; #define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9 #define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA #define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB -#define GL_COLOR_TABLE 0x80D0 -#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1 -#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2 -#define GL_PROXY_COLOR_TABLE 0x80D3 -#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4 -#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5 #define GL_COLOR_TABLE_SCALE 0x80D6 #define GL_COLOR_TABLE_BIAS 0x80D7 #define GL_COLOR_TABLE_FORMAT 0x80D8 @@ -3190,11 +3902,11 @@ GLAPI void APIENTRY glResetMinmax (GLenum target); #define GL_ARB_indirect_parameters 1 #define GL_PARAMETER_BUFFER_ARB 0x80EE #define GL_PARAMETER_BUFFER_BINDING_ARB 0x80EF -typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC) (GLenum mode, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); -typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC) (GLenum mode, GLenum type, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC) (GLenum mode, const void *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC) (GLenum mode, GLenum type, const void *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); #ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glMultiDrawArraysIndirectCountARB (GLenum mode, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); -GLAPI void APIENTRY glMultiDrawElementsIndirectCountARB (GLenum mode, GLenum type, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +GLAPI void APIENTRY glMultiDrawArraysIndirectCountARB (GLenum mode, const void *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +GLAPI void APIENTRY glMultiDrawElementsIndirectCountARB (GLenum mode, GLenum type, const void *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); #endif #endif /* GL_ARB_indirect_parameters */ @@ -3214,6 +3926,25 @@ GLAPI void APIENTRY glVertexAttribDivisorARB (GLuint index, GLuint divisor); #ifndef GL_ARB_internalformat_query2 #define GL_ARB_internalformat_query2 1 #define GL_SRGB_DECODE_ARB 0x8299 +#define GL_VIEW_CLASS_EAC_R11 0x9383 +#define GL_VIEW_CLASS_EAC_RG11 0x9384 +#define GL_VIEW_CLASS_ETC2_RGB 0x9385 +#define GL_VIEW_CLASS_ETC2_RGBA 0x9386 +#define GL_VIEW_CLASS_ETC2_EAC_RGBA 0x9387 +#define GL_VIEW_CLASS_ASTC_4x4_RGBA 0x9388 +#define GL_VIEW_CLASS_ASTC_5x4_RGBA 0x9389 +#define GL_VIEW_CLASS_ASTC_5x5_RGBA 0x938A +#define GL_VIEW_CLASS_ASTC_6x5_RGBA 0x938B +#define GL_VIEW_CLASS_ASTC_6x6_RGBA 0x938C +#define GL_VIEW_CLASS_ASTC_8x5_RGBA 0x938D +#define GL_VIEW_CLASS_ASTC_8x6_RGBA 0x938E +#define GL_VIEW_CLASS_ASTC_8x8_RGBA 0x938F +#define GL_VIEW_CLASS_ASTC_10x5_RGBA 0x9390 +#define GL_VIEW_CLASS_ASTC_10x6_RGBA 0x9391 +#define GL_VIEW_CLASS_ASTC_10x8_RGBA 0x9392 +#define GL_VIEW_CLASS_ASTC_10x10_RGBA 0x9393 +#define GL_VIEW_CLASS_ASTC_12x10_RGBA 0x9394 +#define GL_VIEW_CLASS_ASTC_12x12_RGBA 0x9395 #endif /* GL_ARB_internalformat_query2 */ #ifndef GL_ARB_invalidate_subdata @@ -3419,6 +4150,30 @@ GLAPI void APIENTRY glGetQueryObjectuivARB (GLuint id, GLenum pname, GLuint *par #define GL_ARB_occlusion_query2 1 #endif /* GL_ARB_occlusion_query2 */ +#ifndef GL_ARB_parallel_shader_compile +#define GL_ARB_parallel_shader_compile 1 +#define GL_MAX_SHADER_COMPILER_THREADS_ARB 0x91B0 +#define GL_COMPLETION_STATUS_ARB 0x91B1 +typedef void (APIENTRYP PFNGLMAXSHADERCOMPILERTHREADSARBPROC) (GLuint count); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMaxShaderCompilerThreadsARB (GLuint count); +#endif +#endif /* GL_ARB_parallel_shader_compile */ + +#ifndef GL_ARB_pipeline_statistics_query +#define GL_ARB_pipeline_statistics_query 1 +#define GL_VERTICES_SUBMITTED_ARB 0x82EE +#define GL_PRIMITIVES_SUBMITTED_ARB 0x82EF +#define GL_VERTEX_SHADER_INVOCATIONS_ARB 0x82F0 +#define GL_TESS_CONTROL_SHADER_PATCHES_ARB 0x82F1 +#define GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB 0x82F2 +#define GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB 0x82F3 +#define GL_FRAGMENT_SHADER_INVOCATIONS_ARB 0x82F4 +#define GL_COMPUTE_SHADER_INVOCATIONS_ARB 0x82F5 +#define GL_CLIPPING_INPUT_PRIMITIVES_ARB 0x82F6 +#define GL_CLIPPING_OUTPUT_PRIMITIVES_ARB 0x82F7 +#endif /* GL_ARB_pipeline_statistics_query */ + #ifndef GL_ARB_pixel_buffer_object #define GL_ARB_pixel_buffer_object 1 #define GL_PIXEL_PACK_BUFFER_ARB 0x88EB @@ -3447,6 +4202,14 @@ GLAPI void APIENTRY glPointParameterfvARB (GLenum pname, const GLfloat *params); #define GL_COORD_REPLACE_ARB 0x8862 #endif /* GL_ARB_point_sprite */ +#ifndef GL_ARB_polygon_offset_clamp +#define GL_ARB_polygon_offset_clamp 1 +#endif /* GL_ARB_polygon_offset_clamp */ + +#ifndef GL_ARB_post_depth_coverage +#define GL_ARB_post_depth_coverage 1 +#endif /* GL_ARB_post_depth_coverage */ + #ifndef GL_ARB_program_interface_query #define GL_ARB_program_interface_query 1 #endif /* GL_ARB_program_interface_query */ @@ -3520,6 +4283,26 @@ GLAPI void APIENTRY glGetnMinmaxARB (GLenum target, GLboolean reset, GLenum form #define GL_ARB_robustness_isolation 1 #endif /* GL_ARB_robustness_isolation */ +#ifndef GL_ARB_sample_locations +#define GL_ARB_sample_locations 1 +#define GL_SAMPLE_LOCATION_SUBPIXEL_BITS_ARB 0x933D +#define GL_SAMPLE_LOCATION_PIXEL_GRID_WIDTH_ARB 0x933E +#define GL_SAMPLE_LOCATION_PIXEL_GRID_HEIGHT_ARB 0x933F +#define GL_PROGRAMMABLE_SAMPLE_LOCATION_TABLE_SIZE_ARB 0x9340 +#define GL_SAMPLE_LOCATION_ARB 0x8E50 +#define GL_PROGRAMMABLE_SAMPLE_LOCATION_ARB 0x9341 +#define GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_ARB 0x9342 +#define GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_ARB 0x9343 +typedef void (APIENTRYP PFNGLFRAMEBUFFERSAMPLELOCATIONSFVARBPROC) (GLenum target, GLuint start, GLsizei count, const GLfloat *v); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVARBPROC) (GLuint framebuffer, GLuint start, GLsizei count, const GLfloat *v); +typedef void (APIENTRYP PFNGLEVALUATEDEPTHVALUESARBPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFramebufferSampleLocationsfvARB (GLenum target, GLuint start, GLsizei count, const GLfloat *v); +GLAPI void APIENTRY glNamedFramebufferSampleLocationsfvARB (GLuint framebuffer, GLuint start, GLsizei count, const GLfloat *v); +GLAPI void APIENTRY glEvaluateDepthValuesARB (void); +#endif +#endif /* GL_ARB_sample_locations */ + #ifndef GL_ARB_sample_shading #define GL_ARB_sample_shading 1 #define GL_SAMPLE_SHADING_ARB 0x8C36 @@ -3546,14 +4329,26 @@ GLAPI void APIENTRY glMinSampleShadingARB (GLfloat value); #define GL_ARB_separate_shader_objects 1 #endif /* GL_ARB_separate_shader_objects */ +#ifndef GL_ARB_shader_atomic_counter_ops +#define GL_ARB_shader_atomic_counter_ops 1 +#endif /* GL_ARB_shader_atomic_counter_ops */ + #ifndef GL_ARB_shader_atomic_counters #define GL_ARB_shader_atomic_counters 1 #endif /* GL_ARB_shader_atomic_counters */ +#ifndef GL_ARB_shader_ballot +#define GL_ARB_shader_ballot 1 +#endif /* GL_ARB_shader_ballot */ + #ifndef GL_ARB_shader_bit_encoding #define GL_ARB_shader_bit_encoding 1 #endif /* GL_ARB_shader_bit_encoding */ +#ifndef GL_ARB_shader_clock +#define GL_ARB_shader_clock 1 +#endif /* GL_ARB_shader_clock */ + #ifndef GL_ARB_shader_draw_parameters #define GL_ARB_shader_draw_parameters 1 #endif /* GL_ARB_shader_draw_parameters */ @@ -3710,10 +4505,18 @@ GLAPI void APIENTRY glGetShaderSourceARB (GLhandleARB obj, GLsizei maxLength, GL #define GL_ARB_shader_subroutine 1 #endif /* GL_ARB_shader_subroutine */ +#ifndef GL_ARB_shader_texture_image_samples +#define GL_ARB_shader_texture_image_samples 1 +#endif /* GL_ARB_shader_texture_image_samples */ + #ifndef GL_ARB_shader_texture_lod #define GL_ARB_shader_texture_lod 1 #endif /* GL_ARB_shader_texture_lod */ +#ifndef GL_ARB_shader_viewport_layer_array +#define GL_ARB_shader_viewport_layer_array 1 +#endif /* GL_ARB_shader_viewport_layer_array */ + #ifndef GL_ARB_shading_language_100 #define GL_ARB_shading_language_100 1 #define GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C @@ -3760,11 +4563,25 @@ GLAPI void APIENTRY glGetNamedStringivARB (GLint namelen, const GLchar *name, GL #define GL_TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF #endif /* GL_ARB_shadow_ambient */ +#ifndef GL_ARB_sparse_buffer +#define GL_ARB_sparse_buffer 1 +#define GL_SPARSE_STORAGE_BIT_ARB 0x0400 +#define GL_SPARSE_BUFFER_PAGE_SIZE_ARB 0x82F8 +typedef void (APIENTRYP PFNGLBUFFERPAGECOMMITMENTARBPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLboolean commit); +typedef void (APIENTRYP PFNGLNAMEDBUFFERPAGECOMMITMENTEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, GLboolean commit); +typedef void (APIENTRYP PFNGLNAMEDBUFFERPAGECOMMITMENTARBPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, GLboolean commit); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBufferPageCommitmentARB (GLenum target, GLintptr offset, GLsizeiptr size, GLboolean commit); +GLAPI void APIENTRY glNamedBufferPageCommitmentEXT (GLuint buffer, GLintptr offset, GLsizeiptr size, GLboolean commit); +GLAPI void APIENTRY glNamedBufferPageCommitmentARB (GLuint buffer, GLintptr offset, GLsizeiptr size, GLboolean commit); +#endif +#endif /* GL_ARB_sparse_buffer */ + #ifndef GL_ARB_sparse_texture #define GL_ARB_sparse_texture 1 #define GL_TEXTURE_SPARSE_ARB 0x91A6 #define GL_VIRTUAL_PAGE_SIZE_INDEX_ARB 0x91A7 -#define GL_MIN_SPARSE_LEVEL_ARB 0x919B +#define GL_NUM_SPARSE_LEVELS_ARB 0x91AA #define GL_NUM_VIRTUAL_PAGE_SIZES_ARB 0x91A8 #define GL_VIRTUAL_PAGE_SIZE_X_ARB 0x9195 #define GL_VIRTUAL_PAGE_SIZE_Y_ARB 0x9196 @@ -3773,12 +4590,24 @@ GLAPI void APIENTRY glGetNamedStringivARB (GLint namelen, const GLchar *name, GL #define GL_MAX_SPARSE_3D_TEXTURE_SIZE_ARB 0x9199 #define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_ARB 0x919A #define GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB 0x91A9 -typedef void (APIENTRYP PFNGLTEXPAGECOMMITMENTARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean resident); +typedef void (APIENTRYP PFNGLTEXPAGECOMMITMENTARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit); #ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexPageCommitmentARB (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean resident); +GLAPI void APIENTRY glTexPageCommitmentARB (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit); #endif #endif /* GL_ARB_sparse_texture */ +#ifndef GL_ARB_sparse_texture2 +#define GL_ARB_sparse_texture2 1 +#endif /* GL_ARB_sparse_texture2 */ + +#ifndef GL_ARB_sparse_texture_clamp +#define GL_ARB_sparse_texture_clamp 1 +#endif /* GL_ARB_sparse_texture_clamp */ + +#ifndef GL_ARB_spirv_extensions +#define GL_ARB_spirv_extensions 1 +#endif /* GL_ARB_spirv_extensions */ + #ifndef GL_ARB_stencil_texturing #define GL_ARB_stencil_texturing 1 #endif /* GL_ARB_stencil_texturing */ @@ -3791,6 +4620,10 @@ GLAPI void APIENTRY glTexPageCommitmentARB (GLenum target, GLint level, GLint xo #define GL_ARB_tessellation_shader 1 #endif /* GL_ARB_tessellation_shader */ +#ifndef GL_ARB_texture_barrier +#define GL_ARB_texture_barrier 1 +#endif /* GL_ARB_texture_barrier */ + #ifndef GL_ARB_texture_border_clamp #define GL_ARB_texture_border_clamp 1 #define GL_CLAMP_TO_BORDER_ARB 0x812D @@ -3927,6 +4760,16 @@ GLAPI void APIENTRY glGetCompressedTexImageARB (GLenum target, GLint level, void #define GL_DOT3_RGBA_ARB 0x86AF #endif /* GL_ARB_texture_env_dot3 */ +#ifndef GL_ARB_texture_filter_anisotropic +#define GL_ARB_texture_filter_anisotropic 1 +#endif /* GL_ARB_texture_filter_anisotropic */ + +#ifndef GL_ARB_texture_filter_minmax +#define GL_ARB_texture_filter_minmax 1 +#define GL_TEXTURE_REDUCTION_MODE_ARB 0x9366 +#define GL_WEIGHTED_AVERAGE_ARB 0x9367 +#endif /* GL_ARB_texture_filter_minmax */ + #ifndef GL_ARB_texture_float #define GL_ARB_texture_float 1 #define GL_TEXTURE_RED_TYPE_ARB 0x8C10 @@ -4025,8 +4868,6 @@ GLAPI void APIENTRY glGetCompressedTexImageARB (GLenum target, GLint level, void #ifndef GL_ARB_transform_feedback2 #define GL_ARB_transform_feedback2 1 -#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23 -#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24 #endif /* GL_ARB_transform_feedback2 */ #ifndef GL_ARB_transform_feedback3 @@ -4037,6 +4878,12 @@ GLAPI void APIENTRY glGetCompressedTexImageARB (GLenum target, GLint level, void #define GL_ARB_transform_feedback_instanced 1 #endif /* GL_ARB_transform_feedback_instanced */ +#ifndef GL_ARB_transform_feedback_overflow_query +#define GL_ARB_transform_feedback_overflow_query 1 +#define GL_TRANSFORM_FEEDBACK_OVERFLOW_ARB 0x82EC +#define GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW_ARB 0x82ED +#endif /* GL_ARB_transform_feedback_overflow_query */ + #ifndef GL_ARB_transpose_matrix #define GL_ARB_transpose_matrix 1 #define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3 @@ -4057,9 +4904,6 @@ GLAPI void APIENTRY glMultTransposeMatrixdARB (const GLdouble *m); #ifndef GL_ARB_uniform_buffer_object #define GL_ARB_uniform_buffer_object 1 -#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C -#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32 -#define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45 #endif /* GL_ARB_uniform_buffer_object */ #ifndef GL_ARB_vertex_array_bgra @@ -4148,13 +4992,8 @@ GLAPI void APIENTRY glVertexBlendARB (GLint count); #ifndef GL_ARB_vertex_buffer_object #define GL_ARB_vertex_buffer_object 1 -#ifdef __MACOSX__ /* The OS X headers haven't caught up with Khronos yet */ -typedef long GLsizeiptrARB; -typedef long GLintptrARB; -#else -typedef ptrdiff_t GLsizeiptrARB; -typedef ptrdiff_t GLintptrARB; -#endif +typedef khronos_ssize_t GLsizeiptrARB; +typedef khronos_intptr_t GLintptrARB; #define GL_BUFFER_SIZE_ARB 0x8764 #define GL_BUFFER_USAGE_ARB 0x8765 #define GL_ARRAY_BUFFER_ARB 0x8892 @@ -4349,6 +5188,12 @@ GLAPI GLint APIENTRY glGetAttribLocationARB (GLhandleARB programObj, const GLcha #ifndef GL_ARB_viewport_array #define GL_ARB_viewport_array 1 +typedef void (APIENTRYP PFNGLDEPTHRANGEARRAYDVNVPROC) (GLuint first, GLsizei count, const GLdouble *v); +typedef void (APIENTRYP PFNGLDEPTHRANGEINDEXEDDNVPROC) (GLuint index, GLdouble n, GLdouble f); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDepthRangeArraydvNV (GLuint first, GLsizei count, const GLdouble *v); +GLAPI void APIENTRY glDepthRangeIndexeddNV (GLuint index, GLdouble n, GLdouble f); +#endif #endif /* GL_ARB_viewport_array */ #ifndef GL_ARB_window_pos @@ -4389,10 +5234,82 @@ GLAPI void APIENTRY glWindowPos3svARB (const GLshort *v); #endif #endif /* GL_ARB_window_pos */ +#ifndef GL_KHR_blend_equation_advanced +#define GL_KHR_blend_equation_advanced 1 +#define GL_MULTIPLY_KHR 0x9294 +#define GL_SCREEN_KHR 0x9295 +#define GL_OVERLAY_KHR 0x9296 +#define GL_DARKEN_KHR 0x9297 +#define GL_LIGHTEN_KHR 0x9298 +#define GL_COLORDODGE_KHR 0x9299 +#define GL_COLORBURN_KHR 0x929A +#define GL_HARDLIGHT_KHR 0x929B +#define GL_SOFTLIGHT_KHR 0x929C +#define GL_DIFFERENCE_KHR 0x929E +#define GL_EXCLUSION_KHR 0x92A0 +#define GL_HSL_HUE_KHR 0x92AD +#define GL_HSL_SATURATION_KHR 0x92AE +#define GL_HSL_COLOR_KHR 0x92AF +#define GL_HSL_LUMINOSITY_KHR 0x92B0 +typedef void (APIENTRYP PFNGLBLENDBARRIERKHRPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBlendBarrierKHR (void); +#endif +#endif /* GL_KHR_blend_equation_advanced */ + +#ifndef GL_KHR_blend_equation_advanced_coherent +#define GL_KHR_blend_equation_advanced_coherent 1 +#define GL_BLEND_ADVANCED_COHERENT_KHR 0x9285 +#endif /* GL_KHR_blend_equation_advanced_coherent */ + +#ifndef GL_KHR_context_flush_control +#define GL_KHR_context_flush_control 1 +#endif /* GL_KHR_context_flush_control */ + #ifndef GL_KHR_debug #define GL_KHR_debug 1 #endif /* GL_KHR_debug */ +#ifndef GL_KHR_no_error +#define GL_KHR_no_error 1 +#define GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR 0x00000008 +#endif /* GL_KHR_no_error */ + +#ifndef GL_KHR_parallel_shader_compile +#define GL_KHR_parallel_shader_compile 1 +#define GL_MAX_SHADER_COMPILER_THREADS_KHR 0x91B0 +#define GL_COMPLETION_STATUS_KHR 0x91B1 +typedef void (APIENTRYP PFNGLMAXSHADERCOMPILERTHREADSKHRPROC) (GLuint count); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMaxShaderCompilerThreadsKHR (GLuint count); +#endif +#endif /* GL_KHR_parallel_shader_compile */ + +#ifndef GL_KHR_robust_buffer_access_behavior +#define GL_KHR_robust_buffer_access_behavior 1 +#endif /* GL_KHR_robust_buffer_access_behavior */ + +#ifndef GL_KHR_robustness +#define GL_KHR_robustness 1 +#define GL_CONTEXT_ROBUST_ACCESS 0x90F3 +#endif /* GL_KHR_robustness */ + +#ifndef GL_KHR_shader_subgroup +#define GL_KHR_shader_subgroup 1 +#define GL_SUBGROUP_SIZE_KHR 0x9532 +#define GL_SUBGROUP_SUPPORTED_STAGES_KHR 0x9533 +#define GL_SUBGROUP_SUPPORTED_FEATURES_KHR 0x9534 +#define GL_SUBGROUP_QUAD_ALL_STAGES_KHR 0x9535 +#define GL_SUBGROUP_FEATURE_BASIC_BIT_KHR 0x00000001 +#define GL_SUBGROUP_FEATURE_VOTE_BIT_KHR 0x00000002 +#define GL_SUBGROUP_FEATURE_ARITHMETIC_BIT_KHR 0x00000004 +#define GL_SUBGROUP_FEATURE_BALLOT_BIT_KHR 0x00000008 +#define GL_SUBGROUP_FEATURE_SHUFFLE_BIT_KHR 0x00000010 +#define GL_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT_KHR 0x00000020 +#define GL_SUBGROUP_FEATURE_CLUSTERED_BIT_KHR 0x00000040 +#define GL_SUBGROUP_FEATURE_QUAD_BIT_KHR 0x00000080 +#endif /* GL_KHR_shader_subgroup */ + #ifndef GL_KHR_texture_compression_astc_hdr #define GL_KHR_texture_compression_astc_hdr 1 #define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0 @@ -4429,6 +5346,10 @@ GLAPI void APIENTRY glWindowPos3svARB (const GLshort *v); #define GL_KHR_texture_compression_astc_ldr 1 #endif /* GL_KHR_texture_compression_astc_ldr */ +#ifndef GL_KHR_texture_compression_astc_sliced_3d +#define GL_KHR_texture_compression_astc_sliced_3d 1 +#endif /* GL_KHR_texture_compression_astc_sliced_3d */ + #ifndef GL_OES_byte_coordinates #define GL_OES_byte_coordinates 1 typedef void (APIENTRYP PFNGLMULTITEXCOORD1BOESPROC) (GLenum texture, GLbyte s); @@ -4447,11 +5368,11 @@ typedef void (APIENTRYP PFNGLTEXCOORD3BOESPROC) (GLbyte s, GLbyte t, GLbyte r); typedef void (APIENTRYP PFNGLTEXCOORD3BVOESPROC) (const GLbyte *coords); typedef void (APIENTRYP PFNGLTEXCOORD4BOESPROC) (GLbyte s, GLbyte t, GLbyte r, GLbyte q); typedef void (APIENTRYP PFNGLTEXCOORD4BVOESPROC) (const GLbyte *coords); -typedef void (APIENTRYP PFNGLVERTEX2BOESPROC) (GLbyte x); +typedef void (APIENTRYP PFNGLVERTEX2BOESPROC) (GLbyte x, GLbyte y); typedef void (APIENTRYP PFNGLVERTEX2BVOESPROC) (const GLbyte *coords); -typedef void (APIENTRYP PFNGLVERTEX3BOESPROC) (GLbyte x, GLbyte y); +typedef void (APIENTRYP PFNGLVERTEX3BOESPROC) (GLbyte x, GLbyte y, GLbyte z); typedef void (APIENTRYP PFNGLVERTEX3BVOESPROC) (const GLbyte *coords); -typedef void (APIENTRYP PFNGLVERTEX4BOESPROC) (GLbyte x, GLbyte y, GLbyte z); +typedef void (APIENTRYP PFNGLVERTEX4BOESPROC) (GLbyte x, GLbyte y, GLbyte z, GLbyte w); typedef void (APIENTRYP PFNGLVERTEX4BVOESPROC) (const GLbyte *coords); #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glMultiTexCoord1bOES (GLenum texture, GLbyte s); @@ -4470,11 +5391,11 @@ GLAPI void APIENTRY glTexCoord3bOES (GLbyte s, GLbyte t, GLbyte r); GLAPI void APIENTRY glTexCoord3bvOES (const GLbyte *coords); GLAPI void APIENTRY glTexCoord4bOES (GLbyte s, GLbyte t, GLbyte r, GLbyte q); GLAPI void APIENTRY glTexCoord4bvOES (const GLbyte *coords); -GLAPI void APIENTRY glVertex2bOES (GLbyte x); +GLAPI void APIENTRY glVertex2bOES (GLbyte x, GLbyte y); GLAPI void APIENTRY glVertex2bvOES (const GLbyte *coords); -GLAPI void APIENTRY glVertex3bOES (GLbyte x, GLbyte y); +GLAPI void APIENTRY glVertex3bOES (GLbyte x, GLbyte y, GLbyte z); GLAPI void APIENTRY glVertex3bvOES (const GLbyte *coords); -GLAPI void APIENTRY glVertex4bOES (GLbyte x, GLbyte y, GLbyte z); +GLAPI void APIENTRY glVertex4bOES (GLbyte x, GLbyte y, GLbyte z, GLbyte w); GLAPI void APIENTRY glVertex4bvOES (const GLbyte *coords); #endif #endif /* GL_OES_byte_coordinates */ @@ -4495,7 +5416,7 @@ GLAPI void APIENTRY glVertex4bvOES (const GLbyte *coords); #ifndef GL_OES_fixed_point #define GL_OES_fixed_point 1 -typedef GLint GLfixed; +typedef khronos_int32_t GLfixed; #define GL_FIXED_OES 0x140C typedef void (APIENTRYP PFNGLALPHAFUNCXOESPROC) (GLenum func, GLfixed ref); typedef void (APIENTRYP PFNGLCLEARCOLORXOESPROC) (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); @@ -4526,7 +5447,6 @@ typedef void (APIENTRYP PFNGLPOINTPARAMETERXVOESPROC) (GLenum pname, const GLfix typedef void (APIENTRYP PFNGLPOINTSIZEXOESPROC) (GLfixed size); typedef void (APIENTRYP PFNGLPOLYGONOFFSETXOESPROC) (GLfixed factor, GLfixed units); typedef void (APIENTRYP PFNGLROTATEXOESPROC) (GLfixed angle, GLfixed x, GLfixed y, GLfixed z); -typedef void (APIENTRYP PFNGLSAMPLECOVERAGEOESPROC) (GLfixed value, GLboolean invert); typedef void (APIENTRYP PFNGLSCALEXOESPROC) (GLfixed x, GLfixed y, GLfixed z); typedef void (APIENTRYP PFNGLTEXENVXOESPROC) (GLenum target, GLenum pname, GLfixed param); typedef void (APIENTRYP PFNGLTEXENVXVOESPROC) (GLenum target, GLenum pname, const GLfixed *params); @@ -4631,7 +5551,6 @@ GLAPI void APIENTRY glPointParameterxvOES (GLenum pname, const GLfixed *params); GLAPI void APIENTRY glPointSizexOES (GLfixed size); GLAPI void APIENTRY glPolygonOffsetxOES (GLfixed factor, GLfixed units); GLAPI void APIENTRY glRotatexOES (GLfixed angle, GLfixed x, GLfixed y, GLfixed z); -GLAPI void APIENTRY glSampleCoverageOES (GLfixed value, GLboolean invert); GLAPI void APIENTRY glScalexOES (GLfixed x, GLfixed y, GLfixed z); GLAPI void APIENTRY glTexEnvxOES (GLenum target, GLenum pname, GLfixed param); GLAPI void APIENTRY glTexEnvxvOES (GLenum target, GLenum pname, const GLfixed *params); @@ -4793,12 +5712,12 @@ typedef void (APIENTRY *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severi typedef void (APIENTRYP PFNGLDEBUGMESSAGEENABLEAMDPROC) (GLenum category, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTAMDPROC) (GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar *buf); typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKAMDPROC) (GLDEBUGPROCAMD callback, void *userParam); -typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGAMDPROC) (GLuint count, GLsizei bufsize, GLenum *categories, GLuint *severities, GLuint *ids, GLsizei *lengths, GLchar *message); +typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGAMDPROC) (GLuint count, GLsizei bufSize, GLenum *categories, GLuint *severities, GLuint *ids, GLsizei *lengths, GLchar *message); #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glDebugMessageEnableAMD (GLenum category, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); GLAPI void APIENTRY glDebugMessageInsertAMD (GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar *buf); GLAPI void APIENTRY glDebugMessageCallbackAMD (GLDEBUGPROCAMD callback, void *userParam); -GLAPI GLuint APIENTRY glGetDebugMessageLogAMD (GLuint count, GLsizei bufsize, GLenum *categories, GLuint *severities, GLuint *ids, GLsizei *lengths, GLchar *message); +GLAPI GLuint APIENTRY glGetDebugMessageLogAMD (GLuint count, GLsizei bufSize, GLenum *categories, GLuint *severities, GLuint *ids, GLsizei *lengths, GLchar *message); #endif #endif /* GL_AMD_debug_output */ @@ -4822,13 +5741,68 @@ GLAPI void APIENTRY glBlendEquationSeparateIndexedAMD (GLuint buf, GLenum modeRG #endif #endif /* GL_AMD_draw_buffers_blend */ +#ifndef GL_AMD_framebuffer_multisample_advanced +#define GL_AMD_framebuffer_multisample_advanced 1 +#define GL_RENDERBUFFER_STORAGE_SAMPLES_AMD 0x91B2 +#define GL_MAX_COLOR_FRAMEBUFFER_SAMPLES_AMD 0x91B3 +#define GL_MAX_COLOR_FRAMEBUFFER_STORAGE_SAMPLES_AMD 0x91B4 +#define GL_MAX_DEPTH_STENCIL_FRAMEBUFFER_SAMPLES_AMD 0x91B5 +#define GL_NUM_SUPPORTED_MULTISAMPLE_MODES_AMD 0x91B6 +#define GL_SUPPORTED_MULTISAMPLE_MODES_AMD 0x91B7 +typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC) (GLenum target, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC) (GLuint renderbuffer, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glRenderbufferStorageMultisampleAdvancedAMD (GLenum target, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI void APIENTRY glNamedRenderbufferStorageMultisampleAdvancedAMD (GLuint renderbuffer, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height); +#endif +#endif /* GL_AMD_framebuffer_multisample_advanced */ + +#ifndef GL_AMD_framebuffer_sample_positions +#define GL_AMD_framebuffer_sample_positions 1 +#define GL_SUBSAMPLE_DISTANCE_AMD 0x883F +#define GL_PIXELS_PER_SAMPLE_PATTERN_X_AMD 0x91AE +#define GL_PIXELS_PER_SAMPLE_PATTERN_Y_AMD 0x91AF +#define GL_ALL_PIXELS_AMD 0xFFFFFFFF +typedef void (APIENTRYP PFNGLFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC) (GLenum target, GLuint numsamples, GLuint pixelindex, const GLfloat *values); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERSAMPLEPOSITIONSFVAMDPROC) (GLuint framebuffer, GLuint numsamples, GLuint pixelindex, const GLfloat *values); +typedef void (APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERFVAMDPROC) (GLenum target, GLenum pname, GLuint numsamples, GLuint pixelindex, GLsizei size, GLfloat *values); +typedef void (APIENTRYP PFNGLGETNAMEDFRAMEBUFFERPARAMETERFVAMDPROC) (GLuint framebuffer, GLenum pname, GLuint numsamples, GLuint pixelindex, GLsizei size, GLfloat *values); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFramebufferSamplePositionsfvAMD (GLenum target, GLuint numsamples, GLuint pixelindex, const GLfloat *values); +GLAPI void APIENTRY glNamedFramebufferSamplePositionsfvAMD (GLuint framebuffer, GLuint numsamples, GLuint pixelindex, const GLfloat *values); +GLAPI void APIENTRY glGetFramebufferParameterfvAMD (GLenum target, GLenum pname, GLuint numsamples, GLuint pixelindex, GLsizei size, GLfloat *values); +GLAPI void APIENTRY glGetNamedFramebufferParameterfvAMD (GLuint framebuffer, GLenum pname, GLuint numsamples, GLuint pixelindex, GLsizei size, GLfloat *values); +#endif +#endif /* GL_AMD_framebuffer_sample_positions */ + #ifndef GL_AMD_gcn_shader #define GL_AMD_gcn_shader 1 #endif /* GL_AMD_gcn_shader */ +#ifndef GL_AMD_gpu_shader_half_float +#define GL_AMD_gpu_shader_half_float 1 +#define GL_FLOAT16_NV 0x8FF8 +#define GL_FLOAT16_VEC2_NV 0x8FF9 +#define GL_FLOAT16_VEC3_NV 0x8FFA +#define GL_FLOAT16_VEC4_NV 0x8FFB +#define GL_FLOAT16_MAT2_AMD 0x91C5 +#define GL_FLOAT16_MAT3_AMD 0x91C6 +#define GL_FLOAT16_MAT4_AMD 0x91C7 +#define GL_FLOAT16_MAT2x3_AMD 0x91C8 +#define GL_FLOAT16_MAT2x4_AMD 0x91C9 +#define GL_FLOAT16_MAT3x2_AMD 0x91CA +#define GL_FLOAT16_MAT3x4_AMD 0x91CB +#define GL_FLOAT16_MAT4x2_AMD 0x91CC +#define GL_FLOAT16_MAT4x3_AMD 0x91CD +#endif /* GL_AMD_gpu_shader_half_float */ + +#ifndef GL_AMD_gpu_shader_int16 +#define GL_AMD_gpu_shader_int16 1 +#endif /* GL_AMD_gpu_shader_int16 */ + #ifndef GL_AMD_gpu_shader_int64 #define GL_AMD_gpu_shader_int64 1 -typedef int64_t GLint64EXT; +typedef khronos_int64_t GLint64EXT; #define GL_INT64_NV 0x140E #define GL_UNSIGNED_INT64_NV 0x140F #define GL_INT8_NV 0x8FE0 @@ -4853,10 +5827,6 @@ typedef int64_t GLint64EXT; #define GL_UNSIGNED_INT64_VEC2_NV 0x8FF5 #define GL_UNSIGNED_INT64_VEC3_NV 0x8FF6 #define GL_UNSIGNED_INT64_VEC4_NV 0x8FF7 -#define GL_FLOAT16_NV 0x8FF8 -#define GL_FLOAT16_VEC2_NV 0x8FF9 -#define GL_FLOAT16_VEC3_NV 0x8FFA -#define GL_FLOAT16_VEC4_NV 0x8FFB typedef void (APIENTRYP PFNGLUNIFORM1I64NVPROC) (GLint location, GLint64EXT x); typedef void (APIENTRYP PFNGLUNIFORM2I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y); typedef void (APIENTRYP PFNGLUNIFORM3I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); @@ -5029,7 +5999,6 @@ GLAPI void APIENTRY glGetPerfMonitorCounterDataAMD (GLuint monitor, GLenum pname #ifndef GL_AMD_sample_positions #define GL_AMD_sample_positions 1 -#define GL_SUBSAMPLE_DISTANCE_AMD 0x883F typedef void (APIENTRYP PFNGLSETMULTISAMPLEFVAMDPROC) (GLenum pname, GLuint index, const GLfloat *val); #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glSetMultisamplefvAMD (GLenum pname, GLuint index, const GLfloat *val); @@ -5044,6 +6013,22 @@ GLAPI void APIENTRY glSetMultisamplefvAMD (GLenum pname, GLuint index, const GLf #define GL_AMD_shader_atomic_counter_ops 1 #endif /* GL_AMD_shader_atomic_counter_ops */ +#ifndef GL_AMD_shader_ballot +#define GL_AMD_shader_ballot 1 +#endif /* GL_AMD_shader_ballot */ + +#ifndef GL_AMD_shader_explicit_vertex_parameter +#define GL_AMD_shader_explicit_vertex_parameter 1 +#endif /* GL_AMD_shader_explicit_vertex_parameter */ + +#ifndef GL_AMD_shader_gpu_shader_half_float_fetch +#define GL_AMD_shader_gpu_shader_half_float_fetch 1 +#endif /* GL_AMD_shader_gpu_shader_half_float_fetch */ + +#ifndef GL_AMD_shader_image_load_store_lod +#define GL_AMD_shader_image_load_store_lod 1 +#endif /* GL_AMD_shader_image_load_store_lod */ + #ifndef GL_AMD_shader_stencil_export #define GL_AMD_shader_stencil_export 1 #endif /* GL_AMD_shader_stencil_export */ @@ -5083,6 +6068,10 @@ GLAPI void APIENTRY glStencilOpValueAMD (GLenum face, GLuint value); #endif #endif /* GL_AMD_stencil_operation_extended */ +#ifndef GL_AMD_texture_gather_bias_lod +#define GL_AMD_texture_gather_bias_lod 1 +#endif /* GL_AMD_texture_gather_bias_lod */ + #ifndef GL_AMD_texture_texture4 #define GL_AMD_texture_texture4 1 #endif /* GL_AMD_texture_texture4 */ @@ -5783,6 +6772,21 @@ GLAPI void APIENTRY glVertexBlendEnvfATI (GLenum pname, GLfloat param); #define GL_422_REV_AVERAGE_EXT 0x80CF #endif /* GL_EXT_422_pixels */ +#ifndef GL_EXT_EGL_image_storage +#define GL_EXT_EGL_image_storage 1 +typedef void *GLeglImageOES; +typedef void (APIENTRYP PFNGLEGLIMAGETARGETTEXSTORAGEEXTPROC) (GLenum target, GLeglImageOES image, const GLint* attrib_list); +typedef void (APIENTRYP PFNGLEGLIMAGETARGETTEXTURESTORAGEEXTPROC) (GLuint texture, GLeglImageOES image, const GLint* attrib_list); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glEGLImageTargetTexStorageEXT (GLenum target, GLeglImageOES image, const GLint* attrib_list); +GLAPI void APIENTRY glEGLImageTargetTextureStorageEXT (GLuint texture, GLeglImageOES image, const GLint* attrib_list); +#endif +#endif /* GL_EXT_EGL_image_storage */ + +#ifndef GL_EXT_EGL_sync +#define GL_EXT_EGL_sync 1 +#endif /* GL_EXT_EGL_sync */ + #ifndef GL_EXT_abgr #define GL_EXT_abgr 1 #define GL_ABGR_EXT 0x8000 @@ -6345,7 +7349,7 @@ typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC) (GLuint vaob typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC) (GLuint vaobj, GLuint attribindex, GLuint bindingindex); typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC) (GLuint vaobj, GLuint bindingindex, GLuint divisor); typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); -typedef void (APIENTRYP PFNGLTEXTUREPAGECOMMITMENTEXTPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean resident); +typedef void (APIENTRYP PFNGLTEXTUREPAGECOMMITMENTEXTPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit); typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBDIVISOREXTPROC) (GLuint vaobj, GLuint index, GLuint divisor); #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glMatrixLoadfEXT (GLenum mode, const GLfloat *m); @@ -6601,7 +7605,7 @@ GLAPI void APIENTRY glVertexArrayVertexAttribLFormatEXT (GLuint vaobj, GLuint at GLAPI void APIENTRY glVertexArrayVertexAttribBindingEXT (GLuint vaobj, GLuint attribindex, GLuint bindingindex); GLAPI void APIENTRY glVertexArrayVertexBindingDivisorEXT (GLuint vaobj, GLuint bindingindex, GLuint divisor); GLAPI void APIENTRY glVertexArrayVertexAttribLOffsetEXT (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); -GLAPI void APIENTRY glTexturePageCommitmentEXT (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean resident); +GLAPI void APIENTRY glTexturePageCommitmentEXT (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit); GLAPI void APIENTRY glVertexArrayVertexAttribDivisorEXT (GLuint vaobj, GLuint index, GLuint divisor); #endif #endif /* GL_EXT_direct_state_access */ @@ -6634,6 +7638,17 @@ GLAPI void APIENTRY glDrawRangeElementsEXT (GLenum mode, GLuint start, GLuint en #endif #endif /* GL_EXT_draw_range_elements */ +#ifndef GL_EXT_external_buffer +#define GL_EXT_external_buffer 1 +typedef void *GLeglClientBufferEXT; +typedef void (APIENTRYP PFNGLBUFFERSTORAGEEXTERNALEXTPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags); +typedef void (APIENTRYP PFNGLNAMEDBUFFERSTORAGEEXTERNALEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBufferStorageExternalEXT (GLenum target, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags); +GLAPI void APIENTRY glNamedBufferStorageExternalEXT (GLuint buffer, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags); +#endif +#endif /* GL_EXT_external_buffer */ + #ifndef GL_EXT_fog_coord #define GL_EXT_fog_coord 1 #define GL_FOG_COORDINATE_SOURCE_EXT 0x8450 @@ -6824,7 +7839,6 @@ GLAPI void APIENTRY glProgramLocalParameters4fvEXT (GLenum target, GLuint index, #ifndef GL_EXT_gpu_shader4 #define GL_EXT_gpu_shader4 1 -#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_EXT 0x88FD #define GL_SAMPLER_1D_ARRAY_EXT 0x8DC0 #define GL_SAMPLER_2D_ARRAY_EXT 0x8DC1 #define GL_SAMPLER_BUFFER_EXT 0x8DC2 @@ -6852,6 +7866,7 @@ GLAPI void APIENTRY glProgramLocalParameters4fvEXT (GLenum target, GLuint index, #define GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8 #define GL_MIN_PROGRAM_TEXEL_OFFSET_EXT 0x8904 #define GL_MAX_PROGRAM_TEXEL_OFFSET_EXT 0x8905 +#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_EXT 0x88FD typedef void (APIENTRYP PFNGLGETUNIFORMUIVEXTPROC) (GLuint program, GLint location, GLuint *params); typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONEXTPROC) (GLuint program, GLuint color, const GLchar *name); typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONEXTPROC) (GLuint program, const GLchar *name); @@ -6863,6 +7878,29 @@ typedef void (APIENTRYP PFNGLUNIFORM1UIVEXTPROC) (GLint location, GLsizei count, typedef void (APIENTRYP PFNGLUNIFORM2UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP PFNGLUNIFORM3UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP PFNGLUNIFORM4UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IEXTPROC) (GLuint index, GLint x); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IEXTPROC) (GLuint index, GLint x, GLint y); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IEXTPROC) (GLuint index, GLint x, GLint y, GLint z); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IEXTPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIEXTPROC) (GLuint index, GLuint x); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIEXTPROC) (GLuint index, GLuint x, GLuint y); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVEXTPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVEXTPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVEXTPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVEXTPROC) (GLuint index, const GLint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVEXTPROC) (GLuint index, const GLuint *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVEXTPROC) (GLuint index, const GLbyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVEXTPROC) (GLuint index, const GLshort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVEXTPROC) (GLuint index, const GLubyte *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVEXTPROC) (GLuint index, const GLushort *v); +typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVEXTPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVEXTPROC) (GLuint index, GLenum pname, GLuint *params); #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glGetUniformuivEXT (GLuint program, GLint location, GLuint *params); GLAPI void APIENTRY glBindFragDataLocationEXT (GLuint program, GLuint color, const GLchar *name); @@ -6875,6 +7913,29 @@ GLAPI void APIENTRY glUniform1uivEXT (GLint location, GLsizei count, const GLuin GLAPI void APIENTRY glUniform2uivEXT (GLint location, GLsizei count, const GLuint *value); GLAPI void APIENTRY glUniform3uivEXT (GLint location, GLsizei count, const GLuint *value); GLAPI void APIENTRY glUniform4uivEXT (GLint location, GLsizei count, const GLuint *value); +GLAPI void APIENTRY glVertexAttribI1iEXT (GLuint index, GLint x); +GLAPI void APIENTRY glVertexAttribI2iEXT (GLuint index, GLint x, GLint y); +GLAPI void APIENTRY glVertexAttribI3iEXT (GLuint index, GLint x, GLint y, GLint z); +GLAPI void APIENTRY glVertexAttribI4iEXT (GLuint index, GLint x, GLint y, GLint z, GLint w); +GLAPI void APIENTRY glVertexAttribI1uiEXT (GLuint index, GLuint x); +GLAPI void APIENTRY glVertexAttribI2uiEXT (GLuint index, GLuint x, GLuint y); +GLAPI void APIENTRY glVertexAttribI3uiEXT (GLuint index, GLuint x, GLuint y, GLuint z); +GLAPI void APIENTRY glVertexAttribI4uiEXT (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); +GLAPI void APIENTRY glVertexAttribI1ivEXT (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttribI2ivEXT (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttribI3ivEXT (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttribI4ivEXT (GLuint index, const GLint *v); +GLAPI void APIENTRY glVertexAttribI1uivEXT (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttribI2uivEXT (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttribI3uivEXT (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttribI4uivEXT (GLuint index, const GLuint *v); +GLAPI void APIENTRY glVertexAttribI4bvEXT (GLuint index, const GLbyte *v); +GLAPI void APIENTRY glVertexAttribI4svEXT (GLuint index, const GLshort *v); +GLAPI void APIENTRY glVertexAttribI4ubvEXT (GLuint index, const GLubyte *v); +GLAPI void APIENTRY glVertexAttribI4usvEXT (GLuint index, const GLushort *v); +GLAPI void APIENTRY glVertexAttribIPointerEXT (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); +GLAPI void APIENTRY glGetVertexAttribIivEXT (GLuint index, GLenum pname, GLint *params); +GLAPI void APIENTRY glGetVertexAttribIuivEXT (GLuint index, GLenum pname, GLuint *params); #endif #endif /* GL_EXT_gpu_shader4 */ @@ -6977,6 +8038,89 @@ GLAPI void APIENTRY glTextureMaterialEXT (GLenum face, GLenum mode); #endif #endif /* GL_EXT_light_texture */ +#ifndef GL_EXT_memory_object +#define GL_EXT_memory_object 1 +#define GL_TEXTURE_TILING_EXT 0x9580 +#define GL_DEDICATED_MEMORY_OBJECT_EXT 0x9581 +#define GL_PROTECTED_MEMORY_OBJECT_EXT 0x959B +#define GL_NUM_TILING_TYPES_EXT 0x9582 +#define GL_TILING_TYPES_EXT 0x9583 +#define GL_OPTIMAL_TILING_EXT 0x9584 +#define GL_LINEAR_TILING_EXT 0x9585 +#define GL_NUM_DEVICE_UUIDS_EXT 0x9596 +#define GL_DEVICE_UUID_EXT 0x9597 +#define GL_DRIVER_UUID_EXT 0x9598 +#define GL_UUID_SIZE_EXT 16 +typedef void (APIENTRYP PFNGLGETUNSIGNEDBYTEVEXTPROC) (GLenum pname, GLubyte *data); +typedef void (APIENTRYP PFNGLGETUNSIGNEDBYTEI_VEXTPROC) (GLenum target, GLuint index, GLubyte *data); +typedef void (APIENTRYP PFNGLDELETEMEMORYOBJECTSEXTPROC) (GLsizei n, const GLuint *memoryObjects); +typedef GLboolean (APIENTRYP PFNGLISMEMORYOBJECTEXTPROC) (GLuint memoryObject); +typedef void (APIENTRYP PFNGLCREATEMEMORYOBJECTSEXTPROC) (GLsizei n, GLuint *memoryObjects); +typedef void (APIENTRYP PFNGLMEMORYOBJECTPARAMETERIVEXTPROC) (GLuint memoryObject, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLGETMEMORYOBJECTPARAMETERIVEXTPROC) (GLuint memoryObject, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLTEXSTORAGEMEM2DEXTPROC) (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset); +typedef void (APIENTRYP PFNGLTEXSTORAGEMEM2DMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); +typedef void (APIENTRYP PFNGLTEXSTORAGEMEM3DEXTPROC) (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset); +typedef void (APIENTRYP PFNGLTEXSTORAGEMEM3DMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); +typedef void (APIENTRYP PFNGLBUFFERSTORAGEMEMEXTPROC) (GLenum target, GLsizeiptr size, GLuint memory, GLuint64 offset); +typedef void (APIENTRYP PFNGLTEXTURESTORAGEMEM2DEXTPROC) (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset); +typedef void (APIENTRYP PFNGLTEXTURESTORAGEMEM2DMULTISAMPLEEXTPROC) (GLuint texture, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); +typedef void (APIENTRYP PFNGLTEXTURESTORAGEMEM3DEXTPROC) (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset); +typedef void (APIENTRYP PFNGLTEXTURESTORAGEMEM3DMULTISAMPLEEXTPROC) (GLuint texture, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); +typedef void (APIENTRYP PFNGLNAMEDBUFFERSTORAGEMEMEXTPROC) (GLuint buffer, GLsizeiptr size, GLuint memory, GLuint64 offset); +typedef void (APIENTRYP PFNGLTEXSTORAGEMEM1DEXTPROC) (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLuint memory, GLuint64 offset); +typedef void (APIENTRYP PFNGLTEXTURESTORAGEMEM1DEXTPROC) (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLuint memory, GLuint64 offset); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGetUnsignedBytevEXT (GLenum pname, GLubyte *data); +GLAPI void APIENTRY glGetUnsignedBytei_vEXT (GLenum target, GLuint index, GLubyte *data); +GLAPI void APIENTRY glDeleteMemoryObjectsEXT (GLsizei n, const GLuint *memoryObjects); +GLAPI GLboolean APIENTRY glIsMemoryObjectEXT (GLuint memoryObject); +GLAPI void APIENTRY glCreateMemoryObjectsEXT (GLsizei n, GLuint *memoryObjects); +GLAPI void APIENTRY glMemoryObjectParameterivEXT (GLuint memoryObject, GLenum pname, const GLint *params); +GLAPI void APIENTRY glGetMemoryObjectParameterivEXT (GLuint memoryObject, GLenum pname, GLint *params); +GLAPI void APIENTRY glTexStorageMem2DEXT (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset); +GLAPI void APIENTRY glTexStorageMem2DMultisampleEXT (GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); +GLAPI void APIENTRY glTexStorageMem3DEXT (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset); +GLAPI void APIENTRY glTexStorageMem3DMultisampleEXT (GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); +GLAPI void APIENTRY glBufferStorageMemEXT (GLenum target, GLsizeiptr size, GLuint memory, GLuint64 offset); +GLAPI void APIENTRY glTextureStorageMem2DEXT (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset); +GLAPI void APIENTRY glTextureStorageMem2DMultisampleEXT (GLuint texture, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); +GLAPI void APIENTRY glTextureStorageMem3DEXT (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset); +GLAPI void APIENTRY glTextureStorageMem3DMultisampleEXT (GLuint texture, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); +GLAPI void APIENTRY glNamedBufferStorageMemEXT (GLuint buffer, GLsizeiptr size, GLuint memory, GLuint64 offset); +GLAPI void APIENTRY glTexStorageMem1DEXT (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLuint memory, GLuint64 offset); +GLAPI void APIENTRY glTextureStorageMem1DEXT (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLuint memory, GLuint64 offset); +#endif +#endif /* GL_EXT_memory_object */ + +#ifndef GL_EXT_memory_object_fd +#define GL_EXT_memory_object_fd 1 +#define GL_HANDLE_TYPE_OPAQUE_FD_EXT 0x9586 +typedef void (APIENTRYP PFNGLIMPORTMEMORYFDEXTPROC) (GLuint memory, GLuint64 size, GLenum handleType, GLint fd); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glImportMemoryFdEXT (GLuint memory, GLuint64 size, GLenum handleType, GLint fd); +#endif +#endif /* GL_EXT_memory_object_fd */ + +#ifndef GL_EXT_memory_object_win32 +#define GL_EXT_memory_object_win32 1 +#define GL_HANDLE_TYPE_OPAQUE_WIN32_EXT 0x9587 +#define GL_HANDLE_TYPE_OPAQUE_WIN32_KMT_EXT 0x9588 +#define GL_DEVICE_LUID_EXT 0x9599 +#define GL_DEVICE_NODE_MASK_EXT 0x959A +#define GL_LUID_SIZE_EXT 8 +#define GL_HANDLE_TYPE_D3D12_TILEPOOL_EXT 0x9589 +#define GL_HANDLE_TYPE_D3D12_RESOURCE_EXT 0x958A +#define GL_HANDLE_TYPE_D3D11_IMAGE_EXT 0x958B +#define GL_HANDLE_TYPE_D3D11_IMAGE_KMT_EXT 0x958C +typedef void (APIENTRYP PFNGLIMPORTMEMORYWIN32HANDLEEXTPROC) (GLuint memory, GLuint64 size, GLenum handleType, void *handle); +typedef void (APIENTRYP PFNGLIMPORTMEMORYWIN32NAMEEXTPROC) (GLuint memory, GLuint64 size, GLenum handleType, const void *name); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glImportMemoryWin32HandleEXT (GLuint memory, GLuint64 size, GLenum handleType, void *handle); +GLAPI void APIENTRY glImportMemoryWin32NameEXT (GLuint memory, GLuint64 size, GLenum handleType, const void *name); +#endif +#endif /* GL_EXT_memory_object_win32 */ + #ifndef GL_EXT_misc_attribute #define GL_EXT_misc_attribute 1 #endif /* GL_EXT_misc_attribute */ @@ -7018,6 +8162,18 @@ GLAPI void APIENTRY glSamplePatternEXT (GLenum pattern); #endif #endif /* GL_EXT_multisample */ +#ifndef GL_EXT_multiview_tessellation_geometry_shader +#define GL_EXT_multiview_tessellation_geometry_shader 1 +#endif /* GL_EXT_multiview_tessellation_geometry_shader */ + +#ifndef GL_EXT_multiview_texture_multisample +#define GL_EXT_multiview_texture_multisample 1 +#endif /* GL_EXT_multiview_texture_multisample */ + +#ifndef GL_EXT_multiview_timer_query +#define GL_EXT_multiview_timer_query 1 +#endif /* GL_EXT_multiview_timer_query */ + #ifndef GL_EXT_packed_depth_stencil #define GL_EXT_packed_depth_stencil 1 #define GL_DEPTH_STENCIL_EXT 0x84F9 @@ -7127,6 +8283,19 @@ GLAPI void APIENTRY glPolygonOffsetEXT (GLfloat factor, GLfloat bias); #endif #endif /* GL_EXT_polygon_offset */ +#ifndef GL_EXT_polygon_offset_clamp +#define GL_EXT_polygon_offset_clamp 1 +#define GL_POLYGON_OFFSET_CLAMP_EXT 0x8E1B +typedef void (APIENTRYP PFNGLPOLYGONOFFSETCLAMPEXTPROC) (GLfloat factor, GLfloat units, GLfloat clamp); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glPolygonOffsetClampEXT (GLfloat factor, GLfloat units, GLfloat clamp); +#endif +#endif /* GL_EXT_polygon_offset_clamp */ + +#ifndef GL_EXT_post_depth_coverage +#define GL_EXT_post_depth_coverage 1 +#endif /* GL_EXT_post_depth_coverage */ + #ifndef GL_EXT_provoking_vertex #define GL_EXT_provoking_vertex 1 #define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT 0x8E4C @@ -7139,6 +8308,20 @@ GLAPI void APIENTRY glProvokingVertexEXT (GLenum mode); #endif #endif /* GL_EXT_provoking_vertex */ +#ifndef GL_EXT_raster_multisample +#define GL_EXT_raster_multisample 1 +#define GL_RASTER_MULTISAMPLE_EXT 0x9327 +#define GL_RASTER_SAMPLES_EXT 0x9328 +#define GL_MAX_RASTER_SAMPLES_EXT 0x9329 +#define GL_RASTER_FIXED_SAMPLE_LOCATIONS_EXT 0x932A +#define GL_MULTISAMPLE_RASTERIZATION_ALLOWED_EXT 0x932B +#define GL_EFFECTIVE_RASTER_SAMPLES_EXT 0x932C +typedef void (APIENTRYP PFNGLRASTERSAMPLESEXTPROC) (GLuint samples, GLboolean fixedsamplelocations); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glRasterSamplesEXT (GLuint samples, GLboolean fixedsamplelocations); +#endif +#endif /* GL_EXT_raster_multisample */ + #ifndef GL_EXT_rescale_normal #define GL_EXT_rescale_normal 1 #define GL_RESCALE_NORMAL_EXT 0x803A @@ -7191,6 +8374,55 @@ GLAPI void APIENTRY glSecondaryColorPointerEXT (GLint size, GLenum type, GLsizei #endif #endif /* GL_EXT_secondary_color */ +#ifndef GL_EXT_semaphore +#define GL_EXT_semaphore 1 +#define GL_LAYOUT_GENERAL_EXT 0x958D +#define GL_LAYOUT_COLOR_ATTACHMENT_EXT 0x958E +#define GL_LAYOUT_DEPTH_STENCIL_ATTACHMENT_EXT 0x958F +#define GL_LAYOUT_DEPTH_STENCIL_READ_ONLY_EXT 0x9590 +#define GL_LAYOUT_SHADER_READ_ONLY_EXT 0x9591 +#define GL_LAYOUT_TRANSFER_SRC_EXT 0x9592 +#define GL_LAYOUT_TRANSFER_DST_EXT 0x9593 +#define GL_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_EXT 0x9530 +#define GL_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_EXT 0x9531 +typedef void (APIENTRYP PFNGLGENSEMAPHORESEXTPROC) (GLsizei n, GLuint *semaphores); +typedef void (APIENTRYP PFNGLDELETESEMAPHORESEXTPROC) (GLsizei n, const GLuint *semaphores); +typedef GLboolean (APIENTRYP PFNGLISSEMAPHOREEXTPROC) (GLuint semaphore); +typedef void (APIENTRYP PFNGLSEMAPHOREPARAMETERUI64VEXTPROC) (GLuint semaphore, GLenum pname, const GLuint64 *params); +typedef void (APIENTRYP PFNGLGETSEMAPHOREPARAMETERUI64VEXTPROC) (GLuint semaphore, GLenum pname, GLuint64 *params); +typedef void (APIENTRYP PFNGLWAITSEMAPHOREEXTPROC) (GLuint semaphore, GLuint numBufferBarriers, const GLuint *buffers, GLuint numTextureBarriers, const GLuint *textures, const GLenum *srcLayouts); +typedef void (APIENTRYP PFNGLSIGNALSEMAPHOREEXTPROC) (GLuint semaphore, GLuint numBufferBarriers, const GLuint *buffers, GLuint numTextureBarriers, const GLuint *textures, const GLenum *dstLayouts); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGenSemaphoresEXT (GLsizei n, GLuint *semaphores); +GLAPI void APIENTRY glDeleteSemaphoresEXT (GLsizei n, const GLuint *semaphores); +GLAPI GLboolean APIENTRY glIsSemaphoreEXT (GLuint semaphore); +GLAPI void APIENTRY glSemaphoreParameterui64vEXT (GLuint semaphore, GLenum pname, const GLuint64 *params); +GLAPI void APIENTRY glGetSemaphoreParameterui64vEXT (GLuint semaphore, GLenum pname, GLuint64 *params); +GLAPI void APIENTRY glWaitSemaphoreEXT (GLuint semaphore, GLuint numBufferBarriers, const GLuint *buffers, GLuint numTextureBarriers, const GLuint *textures, const GLenum *srcLayouts); +GLAPI void APIENTRY glSignalSemaphoreEXT (GLuint semaphore, GLuint numBufferBarriers, const GLuint *buffers, GLuint numTextureBarriers, const GLuint *textures, const GLenum *dstLayouts); +#endif +#endif /* GL_EXT_semaphore */ + +#ifndef GL_EXT_semaphore_fd +#define GL_EXT_semaphore_fd 1 +typedef void (APIENTRYP PFNGLIMPORTSEMAPHOREFDEXTPROC) (GLuint semaphore, GLenum handleType, GLint fd); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glImportSemaphoreFdEXT (GLuint semaphore, GLenum handleType, GLint fd); +#endif +#endif /* GL_EXT_semaphore_fd */ + +#ifndef GL_EXT_semaphore_win32 +#define GL_EXT_semaphore_win32 1 +#define GL_HANDLE_TYPE_D3D12_FENCE_EXT 0x9594 +#define GL_D3D12_FENCE_VALUE_EXT 0x9595 +typedef void (APIENTRYP PFNGLIMPORTSEMAPHOREWIN32HANDLEEXTPROC) (GLuint semaphore, GLenum handleType, void *handle); +typedef void (APIENTRYP PFNGLIMPORTSEMAPHOREWIN32NAMEEXTPROC) (GLuint semaphore, GLenum handleType, const void *name); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glImportSemaphoreWin32HandleEXT (GLuint semaphore, GLenum handleType, void *handle); +GLAPI void APIENTRY glImportSemaphoreWin32NameEXT (GLuint semaphore, GLenum handleType, const void *name); +#endif +#endif /* GL_EXT_semaphore_win32 */ + #ifndef GL_EXT_separate_shader_objects #define GL_EXT_separate_shader_objects 1 #define GL_ACTIVE_PROGRAM_EXT 0x8B8D @@ -7211,6 +8443,19 @@ GLAPI GLuint APIENTRY glCreateShaderProgramEXT (GLenum type, const GLchar *strin #define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA #endif /* GL_EXT_separate_specular_color */ +#ifndef GL_EXT_shader_framebuffer_fetch +#define GL_EXT_shader_framebuffer_fetch 1 +#define GL_FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT 0x8A52 +#endif /* GL_EXT_shader_framebuffer_fetch */ + +#ifndef GL_EXT_shader_framebuffer_fetch_non_coherent +#define GL_EXT_shader_framebuffer_fetch_non_coherent 1 +typedef void (APIENTRYP PFNGLFRAMEBUFFERFETCHBARRIEREXTPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFramebufferFetchBarrierEXT (void); +#endif +#endif /* GL_EXT_shader_framebuffer_fetch_non_coherent */ + #ifndef GL_EXT_shader_image_load_formatted #define GL_EXT_shader_image_load_formatted 1 #endif /* GL_EXT_shader_image_load_formatted */ @@ -7284,6 +8529,10 @@ GLAPI void APIENTRY glMemoryBarrierEXT (GLbitfield barriers); #define GL_EXT_shader_integer_mix 1 #endif /* GL_EXT_shader_integer_mix */ +#ifndef GL_EXT_shader_samples_identical +#define GL_EXT_shader_samples_identical 1 +#endif /* GL_EXT_shader_samples_identical */ + #ifndef GL_EXT_shadow_funcs #define GL_EXT_shadow_funcs 1 #endif /* GL_EXT_shadow_funcs */ @@ -7293,6 +8542,10 @@ GLAPI void APIENTRY glMemoryBarrierEXT (GLbitfield barriers); #define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB #endif /* GL_EXT_shared_texture_palette */ +#ifndef GL_EXT_sparse_texture2 +#define GL_EXT_sparse_texture2 1 +#endif /* GL_EXT_sparse_texture2 */ + #ifndef GL_EXT_stencil_clear_tag #define GL_EXT_stencil_clear_tag 1 #define GL_STENCIL_TAG_BITS_EXT 0x88F2 @@ -7405,6 +8658,10 @@ GLAPI void APIENTRY glTexSubImage3DEXT (GLenum target, GLint level, GLint xoffse #define GL_TEXTURE_BINDING_2D_ARRAY_EXT 0x8C1D #define GL_MAX_ARRAY_TEXTURE_LAYERS_EXT 0x88FF #define GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT 0x884E +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFramebufferTextureLayerEXT (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +#endif #endif /* GL_EXT_texture_array */ #ifndef GL_EXT_texture_buffer_object @@ -7501,6 +8758,12 @@ GLAPI void APIENTRY glTexBufferEXT (GLenum target, GLenum internalformat, GLuint #define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF #endif /* GL_EXT_texture_filter_anisotropic */ +#ifndef GL_EXT_texture_filter_minmax +#define GL_EXT_texture_filter_minmax 1 +#define GL_TEXTURE_REDUCTION_MODE_EXT 0x9366 +#define GL_WEIGHTED_AVERAGE_EXT 0x9367 +#endif /* GL_EXT_texture_filter_minmax */ + #ifndef GL_EXT_texture_integer #define GL_EXT_texture_integer 1 #define GL_RGBA32UI_EXT 0x8D70 @@ -7633,6 +8896,16 @@ GLAPI void APIENTRY glTextureNormalEXT (GLenum mode); #define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F #endif /* GL_EXT_texture_sRGB */ +#ifndef GL_EXT_texture_sRGB_R8 +#define GL_EXT_texture_sRGB_R8 1 +#define GL_SR8_EXT 0x8FBD +#endif /* GL_EXT_texture_sRGB_R8 */ + +#ifndef GL_EXT_texture_sRGB_RG8 +#define GL_EXT_texture_sRGB_RG8 1 +#define GL_SRG8_EXT 0x8FBE +#endif /* GL_EXT_texture_sRGB_RG8 */ + #ifndef GL_EXT_texture_sRGB_decode #define GL_EXT_texture_sRGB_decode 1 #define GL_TEXTURE_SRGB_DECODE_EXT 0x8A48 @@ -7640,6 +8913,10 @@ GLAPI void APIENTRY glTextureNormalEXT (GLenum mode); #define GL_SKIP_DECODE_EXT 0x8A4A #endif /* GL_EXT_texture_sRGB_decode */ +#ifndef GL_EXT_texture_shadow_lod +#define GL_EXT_texture_shadow_lod 1 +#endif /* GL_EXT_texture_shadow_lod */ + #ifndef GL_EXT_texture_shared_exponent #define GL_EXT_texture_shared_exponent 1 #define GL_RGB9_E5_EXT 0x8C3D @@ -7667,6 +8944,36 @@ GLAPI void APIENTRY glTextureNormalEXT (GLenum mode); #define GL_RGBA_SNORM 0x8F93 #endif /* GL_EXT_texture_snorm */ +#ifndef GL_EXT_texture_storage +#define GL_EXT_texture_storage 1 +#define GL_TEXTURE_IMMUTABLE_FORMAT_EXT 0x912F +#define GL_RGBA32F_EXT 0x8814 +#define GL_RGB32F_EXT 0x8815 +#define GL_ALPHA32F_EXT 0x8816 +#define GL_LUMINANCE32F_EXT 0x8818 +#define GL_LUMINANCE_ALPHA32F_EXT 0x8819 +#define GL_RGBA16F_EXT 0x881A +#define GL_RGB16F_EXT 0x881B +#define GL_ALPHA16F_EXT 0x881C +#define GL_LUMINANCE16F_EXT 0x881E +#define GL_LUMINANCE_ALPHA16F_EXT 0x881F +#define GL_BGRA8_EXT 0x93A1 +#define GL_R8_EXT 0x8229 +#define GL_RG8_EXT 0x822B +#define GL_R32F_EXT 0x822E +#define GL_RG32F_EXT 0x8230 +#define GL_R16F_EXT 0x822D +#define GL_RG16F_EXT 0x822F +typedef void (APIENTRYP PFNGLTEXSTORAGE1DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +typedef void (APIENTRYP PFNGLTEXSTORAGE2DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLTEXSTORAGE3DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glTexStorage1DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +GLAPI void APIENTRY glTexStorage2DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +GLAPI void APIENTRY glTexStorage3DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +#endif +#endif /* GL_EXT_texture_storage */ + #ifndef GL_EXT_texture_swizzle #define GL_EXT_texture_swizzle 1 #define GL_TEXTURE_SWIZZLE_R_EXT 0x8E42 @@ -8045,6 +9352,30 @@ GLAPI void APIENTRY glVertexWeightPointerEXT (GLint size, GLenum type, GLsizei s #endif #endif /* GL_EXT_vertex_weighting */ +#ifndef GL_EXT_win32_keyed_mutex +#define GL_EXT_win32_keyed_mutex 1 +typedef GLboolean (APIENTRYP PFNGLACQUIREKEYEDMUTEXWIN32EXTPROC) (GLuint memory, GLuint64 key, GLuint timeout); +typedef GLboolean (APIENTRYP PFNGLRELEASEKEYEDMUTEXWIN32EXTPROC) (GLuint memory, GLuint64 key); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLboolean APIENTRY glAcquireKeyedMutexWin32EXT (GLuint memory, GLuint64 key, GLuint timeout); +GLAPI GLboolean APIENTRY glReleaseKeyedMutexWin32EXT (GLuint memory, GLuint64 key); +#endif +#endif /* GL_EXT_win32_keyed_mutex */ + +#ifndef GL_EXT_window_rectangles +#define GL_EXT_window_rectangles 1 +#define GL_INCLUSIVE_EXT 0x8F10 +#define GL_EXCLUSIVE_EXT 0x8F11 +#define GL_WINDOW_RECTANGLE_EXT 0x8F12 +#define GL_WINDOW_RECTANGLE_MODE_EXT 0x8F13 +#define GL_MAX_WINDOW_RECTANGLES_EXT 0x8F14 +#define GL_NUM_WINDOW_RECTANGLES_EXT 0x8F15 +typedef void (APIENTRYP PFNGLWINDOWRECTANGLESEXTPROC) (GLenum mode, GLsizei count, const GLint *box); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glWindowRectanglesEXT (GLenum mode, GLsizei count, const GLint *box); +#endif +#endif /* GL_EXT_window_rectangles */ + #ifndef GL_EXT_x11_sync_object #define GL_EXT_x11_sync_object 1 #define GL_SYNC_X11_FENCE_EXT 0x90E1 @@ -8222,10 +9553,28 @@ GLAPI void APIENTRY glBlendFuncSeparateINGR (GLenum sfactorRGB, GLenum dfactorRG #define GL_INTERLACE_READ_INGR 0x8568 #endif /* GL_INGR_interlace_read */ +#ifndef GL_INTEL_blackhole_render +#define GL_INTEL_blackhole_render 1 +#define GL_BLACKHOLE_RENDER_INTEL 0x83FC +#endif /* GL_INTEL_blackhole_render */ + +#ifndef GL_INTEL_conservative_rasterization +#define GL_INTEL_conservative_rasterization 1 +#define GL_CONSERVATIVE_RASTERIZATION_INTEL 0x83FE +#endif /* GL_INTEL_conservative_rasterization */ + #ifndef GL_INTEL_fragment_shader_ordering #define GL_INTEL_fragment_shader_ordering 1 #endif /* GL_INTEL_fragment_shader_ordering */ +#ifndef GL_INTEL_framebuffer_CMAA +#define GL_INTEL_framebuffer_CMAA 1 +typedef void (APIENTRYP PFNGLAPPLYFRAMEBUFFERATTACHMENTCMAAINTELPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glApplyFramebufferAttachmentCMAAINTEL (void); +#endif +#endif /* GL_INTEL_framebuffer_CMAA */ + #ifndef GL_INTEL_map_texture #define GL_INTEL_map_texture 1 #define GL_TEXTURE_MEMORY_LAYOUT_INTEL 0x83FF @@ -8290,7 +9639,7 @@ typedef void (APIENTRYP PFNGLENDPERFQUERYINTELPROC) (GLuint queryHandle); typedef void (APIENTRYP PFNGLGETFIRSTPERFQUERYIDINTELPROC) (GLuint *queryId); typedef void (APIENTRYP PFNGLGETNEXTPERFQUERYIDINTELPROC) (GLuint queryId, GLuint *nextQueryId); typedef void (APIENTRYP PFNGLGETPERFCOUNTERINFOINTELPROC) (GLuint queryId, GLuint counterId, GLuint counterNameLength, GLchar *counterName, GLuint counterDescLength, GLchar *counterDesc, GLuint *counterOffset, GLuint *counterDataSize, GLuint *counterTypeEnum, GLuint *counterDataTypeEnum, GLuint64 *rawCounterMaxValue); -typedef void (APIENTRYP PFNGLGETPERFQUERYDATAINTELPROC) (GLuint queryHandle, GLuint flags, GLsizei dataSize, GLvoid *data, GLuint *bytesWritten); +typedef void (APIENTRYP PFNGLGETPERFQUERYDATAINTELPROC) (GLuint queryHandle, GLuint flags, GLsizei dataSize, void *data, GLuint *bytesWritten); typedef void (APIENTRYP PFNGLGETPERFQUERYIDBYNAMEINTELPROC) (GLchar *queryName, GLuint *queryId); typedef void (APIENTRYP PFNGLGETPERFQUERYINFOINTELPROC) (GLuint queryId, GLuint queryNameLength, GLchar *queryName, GLuint *dataSize, GLuint *noCounters, GLuint *noInstances, GLuint *capsMask); #ifdef GL_GLEXT_PROTOTYPES @@ -8301,7 +9650,7 @@ GLAPI void APIENTRY glEndPerfQueryINTEL (GLuint queryHandle); GLAPI void APIENTRY glGetFirstPerfQueryIdINTEL (GLuint *queryId); GLAPI void APIENTRY glGetNextPerfQueryIdINTEL (GLuint queryId, GLuint *nextQueryId); GLAPI void APIENTRY glGetPerfCounterInfoINTEL (GLuint queryId, GLuint counterId, GLuint counterNameLength, GLchar *counterName, GLuint counterDescLength, GLchar *counterDesc, GLuint *counterOffset, GLuint *counterDataSize, GLuint *counterTypeEnum, GLuint *counterDataTypeEnum, GLuint64 *rawCounterMaxValue); -GLAPI void APIENTRY glGetPerfQueryDataINTEL (GLuint queryHandle, GLuint flags, GLsizei dataSize, GLvoid *data, GLuint *bytesWritten); +GLAPI void APIENTRY glGetPerfQueryDataINTEL (GLuint queryHandle, GLuint flags, GLsizei dataSize, void *data, GLuint *bytesWritten); GLAPI void APIENTRY glGetPerfQueryIdByNameINTEL (GLchar *queryName, GLuint *queryId); GLAPI void APIENTRY glGetPerfQueryInfoINTEL (GLuint queryId, GLuint queryNameLength, GLchar *queryName, GLuint *dataSize, GLuint *noCounters, GLuint *noInstances, GLuint *capsMask); #endif @@ -8317,11 +9666,37 @@ GLAPI void APIENTRY glGetPerfQueryInfoINTEL (GLuint queryId, GLuint queryNameLen #define GL_TEXTURE_2D_STACK_BINDING_MESAX 0x875E #endif /* GL_MESAX_texture_stack */ +#ifndef GL_MESA_framebuffer_flip_x +#define GL_MESA_framebuffer_flip_x 1 +#define GL_FRAMEBUFFER_FLIP_X_MESA 0x8BBC +#endif /* GL_MESA_framebuffer_flip_x */ + +#ifndef GL_MESA_framebuffer_flip_y +#define GL_MESA_framebuffer_flip_y 1 +#define GL_FRAMEBUFFER_FLIP_Y_MESA 0x8BBB +typedef void (APIENTRYP PFNGLFRAMEBUFFERPARAMETERIMESAPROC) (GLenum target, GLenum pname, GLint param); +typedef void (APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVMESAPROC) (GLenum target, GLenum pname, GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFramebufferParameteriMESA (GLenum target, GLenum pname, GLint param); +GLAPI void APIENTRY glGetFramebufferParameterivMESA (GLenum target, GLenum pname, GLint *params); +#endif +#endif /* GL_MESA_framebuffer_flip_y */ + +#ifndef GL_MESA_framebuffer_swap_xy +#define GL_MESA_framebuffer_swap_xy 1 +#define GL_FRAMEBUFFER_SWAP_XY_MESA 0x8BBD +#endif /* GL_MESA_framebuffer_swap_xy */ + #ifndef GL_MESA_pack_invert #define GL_MESA_pack_invert 1 #define GL_PACK_INVERT_MESA 0x8758 #endif /* GL_MESA_pack_invert */ +#ifndef GL_MESA_program_binary_formats +#define GL_MESA_program_binary_formats 1 +#define GL_PROGRAM_BINARY_FORMAT_MESA 0x875F +#endif /* GL_MESA_program_binary_formats */ + #ifndef GL_MESA_resize_buffers #define GL_MESA_resize_buffers 1 typedef void (APIENTRYP PFNGLRESIZEBUFFERSMESAPROC) (void); @@ -8330,6 +9705,17 @@ GLAPI void APIENTRY glResizeBuffersMESA (void); #endif #endif /* GL_MESA_resize_buffers */ +#ifndef GL_MESA_shader_integer_functions +#define GL_MESA_shader_integer_functions 1 +#endif /* GL_MESA_shader_integer_functions */ + +#ifndef GL_MESA_tile_raster_order +#define GL_MESA_tile_raster_order 1 +#define GL_TILE_RASTER_ORDER_FIXED_MESA 0x8BB8 +#define GL_TILE_RASTER_ORDER_INCREASING_X_MESA 0x8BB9 +#define GL_TILE_RASTER_ORDER_INCREASING_Y_MESA 0x8BBA +#endif /* GL_MESA_tile_raster_order */ + #ifndef GL_MESA_window_pos #define GL_MESA_window_pos 1 typedef void (APIENTRYP PFNGLWINDOWPOS2DMESAPROC) (GLdouble x, GLdouble y); @@ -8391,6 +9777,10 @@ GLAPI void APIENTRY glWindowPos4svMESA (const GLshort *v); #define GL_YCBCR_MESA 0x8757 #endif /* GL_MESA_ycbcr_texture */ +#ifndef GL_NVX_blend_equation_advanced_multi_draw_buffers +#define GL_NVX_blend_equation_advanced_multi_draw_buffers 1 +#endif /* GL_NVX_blend_equation_advanced_multi_draw_buffers */ + #ifndef GL_NVX_conditional_render #define GL_NVX_conditional_render 1 typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERNVXPROC) (GLuint id); @@ -8410,6 +9800,65 @@ GLAPI void APIENTRY glEndConditionalRenderNVX (void); #define GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX 0x904B #endif /* GL_NVX_gpu_memory_info */ +#ifndef GL_NVX_gpu_multicast2 +#define GL_NVX_gpu_multicast2 1 +#define GL_UPLOAD_GPU_MASK_NVX 0x954A +typedef void (APIENTRYP PFNGLUPLOADGPUMASKNVXPROC) (GLbitfield mask); +typedef void (APIENTRYP PFNGLMULTICASTVIEWPORTARRAYVNVXPROC) (GLuint gpu, GLuint first, GLsizei count, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTICASTVIEWPORTPOSITIONWSCALENVXPROC) (GLuint gpu, GLuint index, GLfloat xcoeff, GLfloat ycoeff); +typedef void (APIENTRYP PFNGLMULTICASTSCISSORARRAYVNVXPROC) (GLuint gpu, GLuint first, GLsizei count, const GLint *v); +typedef GLuint (APIENTRYP PFNGLASYNCCOPYBUFFERSUBDATANVXPROC) (GLsizei waitSemaphoreCount, const GLuint *waitSemaphoreArray, const GLuint64 *fenceValueArray, GLuint readGpu, GLbitfield writeGpuMask, GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size, GLsizei signalSemaphoreCount, const GLuint *signalSemaphoreArray, const GLuint64 *signalValueArray); +typedef GLuint (APIENTRYP PFNGLASYNCCOPYIMAGESUBDATANVXPROC) (GLsizei waitSemaphoreCount, const GLuint *waitSemaphoreArray, const GLuint64 *waitValueArray, GLuint srcGpu, GLbitfield dstGpuMask, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth, GLsizei signalSemaphoreCount, const GLuint *signalSemaphoreArray, const GLuint64 *signalValueArray); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glUploadGpuMaskNVX (GLbitfield mask); +GLAPI void APIENTRY glMulticastViewportArrayvNVX (GLuint gpu, GLuint first, GLsizei count, const GLfloat *v); +GLAPI void APIENTRY glMulticastViewportPositionWScaleNVX (GLuint gpu, GLuint index, GLfloat xcoeff, GLfloat ycoeff); +GLAPI void APIENTRY glMulticastScissorArrayvNVX (GLuint gpu, GLuint first, GLsizei count, const GLint *v); +GLAPI GLuint APIENTRY glAsyncCopyBufferSubDataNVX (GLsizei waitSemaphoreCount, const GLuint *waitSemaphoreArray, const GLuint64 *fenceValueArray, GLuint readGpu, GLbitfield writeGpuMask, GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size, GLsizei signalSemaphoreCount, const GLuint *signalSemaphoreArray, const GLuint64 *signalValueArray); +GLAPI GLuint APIENTRY glAsyncCopyImageSubDataNVX (GLsizei waitSemaphoreCount, const GLuint *waitSemaphoreArray, const GLuint64 *waitValueArray, GLuint srcGpu, GLbitfield dstGpuMask, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth, GLsizei signalSemaphoreCount, const GLuint *signalSemaphoreArray, const GLuint64 *signalValueArray); +#endif +#endif /* GL_NVX_gpu_multicast2 */ + +#ifndef GL_NVX_linked_gpu_multicast +#define GL_NVX_linked_gpu_multicast 1 +#define GL_LGPU_SEPARATE_STORAGE_BIT_NVX 0x0800 +#define GL_MAX_LGPU_GPUS_NVX 0x92BA +typedef void (APIENTRYP PFNGLLGPUNAMEDBUFFERSUBDATANVXPROC) (GLbitfield gpuMask, GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data); +typedef void (APIENTRYP PFNGLLGPUCOPYIMAGESUBDATANVXPROC) (GLuint sourceGpu, GLbitfield destinationGpuMask, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srxY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); +typedef void (APIENTRYP PFNGLLGPUINTERLOCKNVXPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glLGPUNamedBufferSubDataNVX (GLbitfield gpuMask, GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data); +GLAPI void APIENTRY glLGPUCopyImageSubDataNVX (GLuint sourceGpu, GLbitfield destinationGpuMask, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srxY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); +GLAPI void APIENTRY glLGPUInterlockNVX (void); +#endif +#endif /* GL_NVX_linked_gpu_multicast */ + +#ifndef GL_NVX_progress_fence +#define GL_NVX_progress_fence 1 +typedef GLuint (APIENTRYP PFNGLCREATEPROGRESSFENCENVXPROC) (void); +typedef void (APIENTRYP PFNGLSIGNALSEMAPHOREUI64NVXPROC) (GLuint signalGpu, GLsizei fenceObjectCount, const GLuint *semaphoreArray, const GLuint64 *fenceValueArray); +typedef void (APIENTRYP PFNGLWAITSEMAPHOREUI64NVXPROC) (GLuint waitGpu, GLsizei fenceObjectCount, const GLuint *semaphoreArray, const GLuint64 *fenceValueArray); +typedef void (APIENTRYP PFNGLCLIENTWAITSEMAPHOREUI64NVXPROC) (GLsizei fenceObjectCount, const GLuint *semaphoreArray, const GLuint64 *fenceValueArray); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLuint APIENTRY glCreateProgressFenceNVX (void); +GLAPI void APIENTRY glSignalSemaphoreui64NVX (GLuint signalGpu, GLsizei fenceObjectCount, const GLuint *semaphoreArray, const GLuint64 *fenceValueArray); +GLAPI void APIENTRY glWaitSemaphoreui64NVX (GLuint waitGpu, GLsizei fenceObjectCount, const GLuint *semaphoreArray, const GLuint64 *fenceValueArray); +GLAPI void APIENTRY glClientWaitSemaphoreui64NVX (GLsizei fenceObjectCount, const GLuint *semaphoreArray, const GLuint64 *fenceValueArray); +#endif +#endif /* GL_NVX_progress_fence */ + +#ifndef GL_NV_alpha_to_coverage_dither_control +#define GL_NV_alpha_to_coverage_dither_control 1 +#define GL_ALPHA_TO_COVERAGE_DITHER_DEFAULT_NV 0x934D +#define GL_ALPHA_TO_COVERAGE_DITHER_ENABLE_NV 0x934E +#define GL_ALPHA_TO_COVERAGE_DITHER_DISABLE_NV 0x934F +#define GL_ALPHA_TO_COVERAGE_DITHER_MODE_NV 0x92BF +typedef void (APIENTRYP PFNGLALPHATOCOVERAGEDITHERCONTROLNVPROC) (GLenum mode); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glAlphaToCoverageDitherControlNV (GLenum mode); +#endif +#endif /* GL_NV_alpha_to_coverage_dither_control */ + #ifndef GL_NV_bindless_multi_draw_indirect #define GL_NV_bindless_multi_draw_indirect 1 typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSNVPROC) (GLenum mode, const void *indirect, GLsizei drawCount, GLsizei stride, GLint vertexBufferCount); @@ -8420,6 +9869,16 @@ GLAPI void APIENTRY glMultiDrawElementsIndirectBindlessNV (GLenum mode, GLenum t #endif #endif /* GL_NV_bindless_multi_draw_indirect */ +#ifndef GL_NV_bindless_multi_draw_indirect_count +#define GL_NV_bindless_multi_draw_indirect_count 1 +typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTBINDLESSCOUNTNVPROC) (GLenum mode, const void *indirect, GLsizei drawCount, GLsizei maxDrawCount, GLsizei stride, GLint vertexBufferCount); +typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTBINDLESSCOUNTNVPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei drawCount, GLsizei maxDrawCount, GLsizei stride, GLint vertexBufferCount); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glMultiDrawArraysIndirectBindlessCountNV (GLenum mode, const void *indirect, GLsizei drawCount, GLsizei maxDrawCount, GLsizei stride, GLint vertexBufferCount); +GLAPI void APIENTRY glMultiDrawElementsIndirectBindlessCountNV (GLenum mode, GLenum type, const void *indirect, GLsizei drawCount, GLsizei maxDrawCount, GLsizei stride, GLint vertexBufferCount); +#endif +#endif /* GL_NV_bindless_multi_draw_indirect_count */ + #ifndef GL_NV_bindless_texture #define GL_NV_bindless_texture 1 typedef GLuint64 (APIENTRYP PFNGLGETTEXTUREHANDLENVPROC) (GLuint texture); @@ -8516,16 +9975,94 @@ GLAPI void APIENTRY glBlendBarrierNV (void); #define GL_BLEND_ADVANCED_COHERENT_NV 0x9285 #endif /* GL_NV_blend_equation_advanced_coherent */ +#ifndef GL_NV_blend_minmax_factor +#define GL_NV_blend_minmax_factor 1 +#endif /* GL_NV_blend_minmax_factor */ + #ifndef GL_NV_blend_square #define GL_NV_blend_square 1 #endif /* GL_NV_blend_square */ +#ifndef GL_NV_clip_space_w_scaling +#define GL_NV_clip_space_w_scaling 1 +#define GL_VIEWPORT_POSITION_W_SCALE_NV 0x937C +#define GL_VIEWPORT_POSITION_W_SCALE_X_COEFF_NV 0x937D +#define GL_VIEWPORT_POSITION_W_SCALE_Y_COEFF_NV 0x937E +typedef void (APIENTRYP PFNGLVIEWPORTPOSITIONWSCALENVPROC) (GLuint index, GLfloat xcoeff, GLfloat ycoeff); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glViewportPositionWScaleNV (GLuint index, GLfloat xcoeff, GLfloat ycoeff); +#endif +#endif /* GL_NV_clip_space_w_scaling */ + +#ifndef GL_NV_command_list +#define GL_NV_command_list 1 +#define GL_TERMINATE_SEQUENCE_COMMAND_NV 0x0000 +#define GL_NOP_COMMAND_NV 0x0001 +#define GL_DRAW_ELEMENTS_COMMAND_NV 0x0002 +#define GL_DRAW_ARRAYS_COMMAND_NV 0x0003 +#define GL_DRAW_ELEMENTS_STRIP_COMMAND_NV 0x0004 +#define GL_DRAW_ARRAYS_STRIP_COMMAND_NV 0x0005 +#define GL_DRAW_ELEMENTS_INSTANCED_COMMAND_NV 0x0006 +#define GL_DRAW_ARRAYS_INSTANCED_COMMAND_NV 0x0007 +#define GL_ELEMENT_ADDRESS_COMMAND_NV 0x0008 +#define GL_ATTRIBUTE_ADDRESS_COMMAND_NV 0x0009 +#define GL_UNIFORM_ADDRESS_COMMAND_NV 0x000A +#define GL_BLEND_COLOR_COMMAND_NV 0x000B +#define GL_STENCIL_REF_COMMAND_NV 0x000C +#define GL_LINE_WIDTH_COMMAND_NV 0x000D +#define GL_POLYGON_OFFSET_COMMAND_NV 0x000E +#define GL_ALPHA_REF_COMMAND_NV 0x000F +#define GL_VIEWPORT_COMMAND_NV 0x0010 +#define GL_SCISSOR_COMMAND_NV 0x0011 +#define GL_FRONT_FACE_COMMAND_NV 0x0012 +typedef void (APIENTRYP PFNGLCREATESTATESNVPROC) (GLsizei n, GLuint *states); +typedef void (APIENTRYP PFNGLDELETESTATESNVPROC) (GLsizei n, const GLuint *states); +typedef GLboolean (APIENTRYP PFNGLISSTATENVPROC) (GLuint state); +typedef void (APIENTRYP PFNGLSTATECAPTURENVPROC) (GLuint state, GLenum mode); +typedef GLuint (APIENTRYP PFNGLGETCOMMANDHEADERNVPROC) (GLenum tokenID, GLuint size); +typedef GLushort (APIENTRYP PFNGLGETSTAGEINDEXNVPROC) (GLenum shadertype); +typedef void (APIENTRYP PFNGLDRAWCOMMANDSNVPROC) (GLenum primitiveMode, GLuint buffer, const GLintptr *indirects, const GLsizei *sizes, GLuint count); +typedef void (APIENTRYP PFNGLDRAWCOMMANDSADDRESSNVPROC) (GLenum primitiveMode, const GLuint64 *indirects, const GLsizei *sizes, GLuint count); +typedef void (APIENTRYP PFNGLDRAWCOMMANDSSTATESNVPROC) (GLuint buffer, const GLintptr *indirects, const GLsizei *sizes, const GLuint *states, const GLuint *fbos, GLuint count); +typedef void (APIENTRYP PFNGLDRAWCOMMANDSSTATESADDRESSNVPROC) (const GLuint64 *indirects, const GLsizei *sizes, const GLuint *states, const GLuint *fbos, GLuint count); +typedef void (APIENTRYP PFNGLCREATECOMMANDLISTSNVPROC) (GLsizei n, GLuint *lists); +typedef void (APIENTRYP PFNGLDELETECOMMANDLISTSNVPROC) (GLsizei n, const GLuint *lists); +typedef GLboolean (APIENTRYP PFNGLISCOMMANDLISTNVPROC) (GLuint list); +typedef void (APIENTRYP PFNGLLISTDRAWCOMMANDSSTATESCLIENTNVPROC) (GLuint list, GLuint segment, const void **indirects, const GLsizei *sizes, const GLuint *states, const GLuint *fbos, GLuint count); +typedef void (APIENTRYP PFNGLCOMMANDLISTSEGMENTSNVPROC) (GLuint list, GLuint segments); +typedef void (APIENTRYP PFNGLCOMPILECOMMANDLISTNVPROC) (GLuint list); +typedef void (APIENTRYP PFNGLCALLCOMMANDLISTNVPROC) (GLuint list); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glCreateStatesNV (GLsizei n, GLuint *states); +GLAPI void APIENTRY glDeleteStatesNV (GLsizei n, const GLuint *states); +GLAPI GLboolean APIENTRY glIsStateNV (GLuint state); +GLAPI void APIENTRY glStateCaptureNV (GLuint state, GLenum mode); +GLAPI GLuint APIENTRY glGetCommandHeaderNV (GLenum tokenID, GLuint size); +GLAPI GLushort APIENTRY glGetStageIndexNV (GLenum shadertype); +GLAPI void APIENTRY glDrawCommandsNV (GLenum primitiveMode, GLuint buffer, const GLintptr *indirects, const GLsizei *sizes, GLuint count); +GLAPI void APIENTRY glDrawCommandsAddressNV (GLenum primitiveMode, const GLuint64 *indirects, const GLsizei *sizes, GLuint count); +GLAPI void APIENTRY glDrawCommandsStatesNV (GLuint buffer, const GLintptr *indirects, const GLsizei *sizes, const GLuint *states, const GLuint *fbos, GLuint count); +GLAPI void APIENTRY glDrawCommandsStatesAddressNV (const GLuint64 *indirects, const GLsizei *sizes, const GLuint *states, const GLuint *fbos, GLuint count); +GLAPI void APIENTRY glCreateCommandListsNV (GLsizei n, GLuint *lists); +GLAPI void APIENTRY glDeleteCommandListsNV (GLsizei n, const GLuint *lists); +GLAPI GLboolean APIENTRY glIsCommandListNV (GLuint list); +GLAPI void APIENTRY glListDrawCommandsStatesClientNV (GLuint list, GLuint segment, const void **indirects, const GLsizei *sizes, const GLuint *states, const GLuint *fbos, GLuint count); +GLAPI void APIENTRY glCommandListSegmentsNV (GLuint list, GLuint segments); +GLAPI void APIENTRY glCompileCommandListNV (GLuint list); +GLAPI void APIENTRY glCallCommandListNV (GLuint list); +#endif +#endif /* GL_NV_command_list */ + #ifndef GL_NV_compute_program5 #define GL_NV_compute_program5 1 #define GL_COMPUTE_PROGRAM_NV 0x90FB #define GL_COMPUTE_PROGRAM_PARAMETER_BUFFER_NV 0x90FC #endif /* GL_NV_compute_program5 */ +#ifndef GL_NV_compute_shader_derivatives +#define GL_NV_compute_shader_derivatives 1 +#endif /* GL_NV_compute_shader_derivatives */ + #ifndef GL_NV_conditional_render #define GL_NV_conditional_render 1 #define GL_QUERY_WAIT_NV 0x8E13 @@ -8540,6 +10077,49 @@ GLAPI void APIENTRY glEndConditionalRenderNV (void); #endif #endif /* GL_NV_conditional_render */ +#ifndef GL_NV_conservative_raster +#define GL_NV_conservative_raster 1 +#define GL_CONSERVATIVE_RASTERIZATION_NV 0x9346 +#define GL_SUBPIXEL_PRECISION_BIAS_X_BITS_NV 0x9347 +#define GL_SUBPIXEL_PRECISION_BIAS_Y_BITS_NV 0x9348 +#define GL_MAX_SUBPIXEL_PRECISION_BIAS_BITS_NV 0x9349 +typedef void (APIENTRYP PFNGLSUBPIXELPRECISIONBIASNVPROC) (GLuint xbits, GLuint ybits); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glSubpixelPrecisionBiasNV (GLuint xbits, GLuint ybits); +#endif +#endif /* GL_NV_conservative_raster */ + +#ifndef GL_NV_conservative_raster_dilate +#define GL_NV_conservative_raster_dilate 1 +#define GL_CONSERVATIVE_RASTER_DILATE_NV 0x9379 +#define GL_CONSERVATIVE_RASTER_DILATE_RANGE_NV 0x937A +#define GL_CONSERVATIVE_RASTER_DILATE_GRANULARITY_NV 0x937B +typedef void (APIENTRYP PFNGLCONSERVATIVERASTERPARAMETERFNVPROC) (GLenum pname, GLfloat value); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glConservativeRasterParameterfNV (GLenum pname, GLfloat value); +#endif +#endif /* GL_NV_conservative_raster_dilate */ + +#ifndef GL_NV_conservative_raster_pre_snap +#define GL_NV_conservative_raster_pre_snap 1 +#define GL_CONSERVATIVE_RASTER_MODE_PRE_SNAP_NV 0x9550 +#endif /* GL_NV_conservative_raster_pre_snap */ + +#ifndef GL_NV_conservative_raster_pre_snap_triangles +#define GL_NV_conservative_raster_pre_snap_triangles 1 +#define GL_CONSERVATIVE_RASTER_MODE_NV 0x954D +#define GL_CONSERVATIVE_RASTER_MODE_POST_SNAP_NV 0x954E +#define GL_CONSERVATIVE_RASTER_MODE_PRE_SNAP_TRIANGLES_NV 0x954F +typedef void (APIENTRYP PFNGLCONSERVATIVERASTERPARAMETERINVPROC) (GLenum pname, GLint param); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glConservativeRasterParameteriNV (GLenum pname, GLint param); +#endif +#endif /* GL_NV_conservative_raster_pre_snap_triangles */ + +#ifndef GL_NV_conservative_raster_underestimation +#define GL_NV_conservative_raster_underestimation 1 +#endif /* GL_NV_conservative_raster_underestimation */ + #ifndef GL_NV_copy_depth_to_color #define GL_NV_copy_depth_to_color 1 #define GL_DEPTH_STENCIL_TO_RGBA_NV 0x886E @@ -8589,6 +10169,23 @@ GLAPI void APIENTRY glDrawTextureNV (GLuint texture, GLuint sampler, GLfloat x0, #endif #endif /* GL_NV_draw_texture */ +#ifndef GL_NV_draw_vulkan_image +#define GL_NV_draw_vulkan_image 1 +typedef void (APIENTRY *GLVULKANPROCNV)(void); +typedef void (APIENTRYP PFNGLDRAWVKIMAGENVPROC) (GLuint64 vkImage, GLuint sampler, GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1, GLfloat z, GLfloat s0, GLfloat t0, GLfloat s1, GLfloat t1); +typedef GLVULKANPROCNV (APIENTRYP PFNGLGETVKPROCADDRNVPROC) (const GLchar *name); +typedef void (APIENTRYP PFNGLWAITVKSEMAPHORENVPROC) (GLuint64 vkSemaphore); +typedef void (APIENTRYP PFNGLSIGNALVKSEMAPHORENVPROC) (GLuint64 vkSemaphore); +typedef void (APIENTRYP PFNGLSIGNALVKFENCENVPROC) (GLuint64 vkFence); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawVkImageNV (GLuint64 vkImage, GLuint sampler, GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1, GLfloat z, GLfloat s0, GLfloat t0, GLfloat s1, GLfloat t1); +GLAPI GLVULKANPROCNV APIENTRY glGetVkProcAddrNV (const GLchar *name); +GLAPI void APIENTRY glWaitVkSemaphoreNV (GLuint64 vkSemaphore); +GLAPI void APIENTRY glSignalVkSemaphoreNV (GLuint64 vkSemaphore); +GLAPI void APIENTRY glSignalVkFenceNV (GLuint64 vkFence); +#endif +#endif /* GL_NV_draw_vulkan_image */ + #ifndef GL_NV_evaluators #define GL_NV_evaluators 1 #define GL_EVAL_2D_NV 0x86C0 @@ -8682,6 +10279,11 @@ GLAPI void APIENTRY glSetFenceNV (GLuint fence, GLenum condition); #endif #endif /* GL_NV_fence */ +#ifndef GL_NV_fill_rectangle +#define GL_NV_fill_rectangle 1 +#define GL_FILL_RECTANGLE_NV 0x933C +#endif /* GL_NV_fill_rectangle */ + #ifndef GL_NV_float_buffer #define GL_NV_float_buffer 1 #define GL_FLOAT_R_NV 0x8880 @@ -8708,6 +10310,16 @@ GLAPI void APIENTRY glSetFenceNV (GLuint fence, GLenum condition); #define GL_EYE_PLANE_ABSOLUTE_NV 0x855C #endif /* GL_NV_fog_distance */ +#ifndef GL_NV_fragment_coverage_to_color +#define GL_NV_fragment_coverage_to_color 1 +#define GL_FRAGMENT_COVERAGE_TO_COLOR_NV 0x92DD +#define GL_FRAGMENT_COVERAGE_COLOR_NV 0x92DE +typedef void (APIENTRYP PFNGLFRAGMENTCOVERAGECOLORNVPROC) (GLuint color); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFragmentCoverageColorNV (GLuint color); +#endif +#endif /* GL_NV_fragment_coverage_to_color */ + #ifndef GL_NV_fragment_program #define GL_NV_fragment_program 1 #define GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868 @@ -8749,6 +10361,34 @@ GLAPI void APIENTRY glGetProgramNamedParameterdvNV (GLuint id, GLsizei len, cons #define GL_NV_fragment_program_option 1 #endif /* GL_NV_fragment_program_option */ +#ifndef GL_NV_fragment_shader_barycentric +#define GL_NV_fragment_shader_barycentric 1 +#endif /* GL_NV_fragment_shader_barycentric */ + +#ifndef GL_NV_fragment_shader_interlock +#define GL_NV_fragment_shader_interlock 1 +#endif /* GL_NV_fragment_shader_interlock */ + +#ifndef GL_NV_framebuffer_mixed_samples +#define GL_NV_framebuffer_mixed_samples 1 +#define GL_COVERAGE_MODULATION_TABLE_NV 0x9331 +#define GL_COLOR_SAMPLES_NV 0x8E20 +#define GL_DEPTH_SAMPLES_NV 0x932D +#define GL_STENCIL_SAMPLES_NV 0x932E +#define GL_MIXED_DEPTH_SAMPLES_SUPPORTED_NV 0x932F +#define GL_MIXED_STENCIL_SAMPLES_SUPPORTED_NV 0x9330 +#define GL_COVERAGE_MODULATION_NV 0x9332 +#define GL_COVERAGE_MODULATION_TABLE_SIZE_NV 0x9333 +typedef void (APIENTRYP PFNGLCOVERAGEMODULATIONTABLENVPROC) (GLsizei n, const GLfloat *v); +typedef void (APIENTRYP PFNGLGETCOVERAGEMODULATIONTABLENVPROC) (GLsizei bufSize, GLfloat *v); +typedef void (APIENTRYP PFNGLCOVERAGEMODULATIONNVPROC) (GLenum components); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glCoverageModulationTableNV (GLsizei n, const GLfloat *v); +GLAPI void APIENTRY glGetCoverageModulationTableNV (GLsizei bufSize, GLfloat *v); +GLAPI void APIENTRY glCoverageModulationNV (GLenum components); +#endif +#endif /* GL_NV_framebuffer_mixed_samples */ + #ifndef GL_NV_framebuffer_multisample_coverage #define GL_NV_framebuffer_multisample_coverage 1 #define GL_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8CAB @@ -8768,12 +10408,10 @@ GLAPI void APIENTRY glRenderbufferStorageMultisampleCoverageNV (GLenum target, G #define GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV 0x8C28 typedef void (APIENTRYP PFNGLPROGRAMVERTEXLIMITNVPROC) (GLenum target, GLint limit); typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glProgramVertexLimitNV (GLenum target, GLint limit); GLAPI void APIENTRY glFramebufferTextureEXT (GLenum target, GLenum attachment, GLuint texture, GLint level); -GLAPI void APIENTRY glFramebufferTextureLayerEXT (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); GLAPI void APIENTRY glFramebufferTextureFaceEXT (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); #endif #endif /* GL_NV_geometry_program4 */ @@ -8782,6 +10420,45 @@ GLAPI void APIENTRY glFramebufferTextureFaceEXT (GLenum target, GLenum attachmen #define GL_NV_geometry_shader4 1 #endif /* GL_NV_geometry_shader4 */ +#ifndef GL_NV_geometry_shader_passthrough +#define GL_NV_geometry_shader_passthrough 1 +#endif /* GL_NV_geometry_shader_passthrough */ + +#ifndef GL_NV_gpu_multicast +#define GL_NV_gpu_multicast 1 +#define GL_PER_GPU_STORAGE_BIT_NV 0x0800 +#define GL_MULTICAST_GPUS_NV 0x92BA +#define GL_RENDER_GPU_MASK_NV 0x9558 +#define GL_PER_GPU_STORAGE_NV 0x9548 +#define GL_MULTICAST_PROGRAMMABLE_SAMPLE_LOCATION_NV 0x9549 +typedef void (APIENTRYP PFNGLRENDERGPUMASKNVPROC) (GLbitfield mask); +typedef void (APIENTRYP PFNGLMULTICASTBUFFERSUBDATANVPROC) (GLbitfield gpuMask, GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data); +typedef void (APIENTRYP PFNGLMULTICASTCOPYBUFFERSUBDATANVPROC) (GLuint readGpu, GLbitfield writeGpuMask, GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +typedef void (APIENTRYP PFNGLMULTICASTCOPYIMAGESUBDATANVPROC) (GLuint srcGpu, GLbitfield dstGpuMask, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); +typedef void (APIENTRYP PFNGLMULTICASTBLITFRAMEBUFFERNVPROC) (GLuint srcGpu, GLuint dstGpu, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +typedef void (APIENTRYP PFNGLMULTICASTFRAMEBUFFERSAMPLELOCATIONSFVNVPROC) (GLuint gpu, GLuint framebuffer, GLuint start, GLsizei count, const GLfloat *v); +typedef void (APIENTRYP PFNGLMULTICASTBARRIERNVPROC) (void); +typedef void (APIENTRYP PFNGLMULTICASTWAITSYNCNVPROC) (GLuint signalGpu, GLbitfield waitGpuMask); +typedef void (APIENTRYP PFNGLMULTICASTGETQUERYOBJECTIVNVPROC) (GLuint gpu, GLuint id, GLenum pname, GLint *params); +typedef void (APIENTRYP PFNGLMULTICASTGETQUERYOBJECTUIVNVPROC) (GLuint gpu, GLuint id, GLenum pname, GLuint *params); +typedef void (APIENTRYP PFNGLMULTICASTGETQUERYOBJECTI64VNVPROC) (GLuint gpu, GLuint id, GLenum pname, GLint64 *params); +typedef void (APIENTRYP PFNGLMULTICASTGETQUERYOBJECTUI64VNVPROC) (GLuint gpu, GLuint id, GLenum pname, GLuint64 *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glRenderGpuMaskNV (GLbitfield mask); +GLAPI void APIENTRY glMulticastBufferSubDataNV (GLbitfield gpuMask, GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data); +GLAPI void APIENTRY glMulticastCopyBufferSubDataNV (GLuint readGpu, GLbitfield writeGpuMask, GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +GLAPI void APIENTRY glMulticastCopyImageSubDataNV (GLuint srcGpu, GLbitfield dstGpuMask, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); +GLAPI void APIENTRY glMulticastBlitFramebufferNV (GLuint srcGpu, GLuint dstGpu, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +GLAPI void APIENTRY glMulticastFramebufferSampleLocationsfvNV (GLuint gpu, GLuint framebuffer, GLuint start, GLsizei count, const GLfloat *v); +GLAPI void APIENTRY glMulticastBarrierNV (void); +GLAPI void APIENTRY glMulticastWaitSyncNV (GLuint signalGpu, GLbitfield waitGpuMask); +GLAPI void APIENTRY glMulticastGetQueryObjectivNV (GLuint gpu, GLuint id, GLenum pname, GLint *params); +GLAPI void APIENTRY glMulticastGetQueryObjectuivNV (GLuint gpu, GLuint id, GLenum pname, GLuint *params); +GLAPI void APIENTRY glMulticastGetQueryObjecti64vNV (GLuint gpu, GLuint id, GLenum pname, GLint64 *params); +GLAPI void APIENTRY glMulticastGetQueryObjectui64vNV (GLuint gpu, GLuint id, GLenum pname, GLuint64 *params); +#endif +#endif /* GL_NV_gpu_multicast */ + #ifndef GL_NV_gpu_program4 #define GL_NV_gpu_program4 1 #define GL_MIN_PROGRAM_TEXEL_OFFSET_NV 0x8904 @@ -8954,15 +10631,130 @@ GLAPI void APIENTRY glVertexAttribs4hvNV (GLuint index, GLsizei n, const GLhalfN #endif #endif /* GL_NV_half_float */ +#ifndef GL_NV_internalformat_sample_query +#define GL_NV_internalformat_sample_query 1 +#define GL_MULTISAMPLES_NV 0x9371 +#define GL_SUPERSAMPLE_SCALE_X_NV 0x9372 +#define GL_SUPERSAMPLE_SCALE_Y_NV 0x9373 +#define GL_CONFORMANT_NV 0x9374 +typedef void (APIENTRYP PFNGLGETINTERNALFORMATSAMPLEIVNVPROC) (GLenum target, GLenum internalformat, GLsizei samples, GLenum pname, GLsizei count, GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGetInternalformatSampleivNV (GLenum target, GLenum internalformat, GLsizei samples, GLenum pname, GLsizei count, GLint *params); +#endif +#endif /* GL_NV_internalformat_sample_query */ + #ifndef GL_NV_light_max_exponent #define GL_NV_light_max_exponent 1 #define GL_MAX_SHININESS_NV 0x8504 #define GL_MAX_SPOT_EXPONENT_NV 0x8505 #endif /* GL_NV_light_max_exponent */ +#ifndef GL_NV_memory_attachment +#define GL_NV_memory_attachment 1 +#define GL_ATTACHED_MEMORY_OBJECT_NV 0x95A4 +#define GL_ATTACHED_MEMORY_OFFSET_NV 0x95A5 +#define GL_MEMORY_ATTACHABLE_ALIGNMENT_NV 0x95A6 +#define GL_MEMORY_ATTACHABLE_SIZE_NV 0x95A7 +#define GL_MEMORY_ATTACHABLE_NV 0x95A8 +#define GL_DETACHED_MEMORY_INCARNATION_NV 0x95A9 +#define GL_DETACHED_TEXTURES_NV 0x95AA +#define GL_DETACHED_BUFFERS_NV 0x95AB +#define GL_MAX_DETACHED_TEXTURES_NV 0x95AC +#define GL_MAX_DETACHED_BUFFERS_NV 0x95AD +typedef void (APIENTRYP PFNGLGETMEMORYOBJECTDETACHEDRESOURCESUIVNVPROC) (GLuint memory, GLenum pname, GLint first, GLsizei count, GLuint *params); +typedef void (APIENTRYP PFNGLRESETMEMORYOBJECTPARAMETERNVPROC) (GLuint memory, GLenum pname); +typedef void (APIENTRYP PFNGLTEXATTACHMEMORYNVPROC) (GLenum target, GLuint memory, GLuint64 offset); +typedef void (APIENTRYP PFNGLBUFFERATTACHMEMORYNVPROC) (GLenum target, GLuint memory, GLuint64 offset); +typedef void (APIENTRYP PFNGLTEXTUREATTACHMEMORYNVPROC) (GLuint texture, GLuint memory, GLuint64 offset); +typedef void (APIENTRYP PFNGLNAMEDBUFFERATTACHMEMORYNVPROC) (GLuint buffer, GLuint memory, GLuint64 offset); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGetMemoryObjectDetachedResourcesuivNV (GLuint memory, GLenum pname, GLint first, GLsizei count, GLuint *params); +GLAPI void APIENTRY glResetMemoryObjectParameterNV (GLuint memory, GLenum pname); +GLAPI void APIENTRY glTexAttachMemoryNV (GLenum target, GLuint memory, GLuint64 offset); +GLAPI void APIENTRY glBufferAttachMemoryNV (GLenum target, GLuint memory, GLuint64 offset); +GLAPI void APIENTRY glTextureAttachMemoryNV (GLuint texture, GLuint memory, GLuint64 offset); +GLAPI void APIENTRY glNamedBufferAttachMemoryNV (GLuint buffer, GLuint memory, GLuint64 offset); +#endif +#endif /* GL_NV_memory_attachment */ + +#ifndef GL_NV_memory_object_sparse +#define GL_NV_memory_object_sparse 1 +typedef void (APIENTRYP PFNGLBUFFERPAGECOMMITMENTMEMNVPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLuint memory, GLuint64 memOffset, GLboolean commit); +typedef void (APIENTRYP PFNGLTEXPAGECOMMITMENTMEMNVPROC) (GLenum target, GLint layer, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset, GLboolean commit); +typedef void (APIENTRYP PFNGLNAMEDBUFFERPAGECOMMITMENTMEMNVPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, GLuint memory, GLuint64 memOffset, GLboolean commit); +typedef void (APIENTRYP PFNGLTEXTUREPAGECOMMITMENTMEMNVPROC) (GLuint texture, GLint layer, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset, GLboolean commit); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBufferPageCommitmentMemNV (GLenum target, GLintptr offset, GLsizeiptr size, GLuint memory, GLuint64 memOffset, GLboolean commit); +GLAPI void APIENTRY glTexPageCommitmentMemNV (GLenum target, GLint layer, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset, GLboolean commit); +GLAPI void APIENTRY glNamedBufferPageCommitmentMemNV (GLuint buffer, GLintptr offset, GLsizeiptr size, GLuint memory, GLuint64 memOffset, GLboolean commit); +GLAPI void APIENTRY glTexturePageCommitmentMemNV (GLuint texture, GLint layer, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset, GLboolean commit); +#endif +#endif /* GL_NV_memory_object_sparse */ + +#ifndef GL_NV_mesh_shader +#define GL_NV_mesh_shader 1 +#define GL_MESH_SHADER_NV 0x9559 +#define GL_TASK_SHADER_NV 0x955A +#define GL_MAX_MESH_UNIFORM_BLOCKS_NV 0x8E60 +#define GL_MAX_MESH_TEXTURE_IMAGE_UNITS_NV 0x8E61 +#define GL_MAX_MESH_IMAGE_UNIFORMS_NV 0x8E62 +#define GL_MAX_MESH_UNIFORM_COMPONENTS_NV 0x8E63 +#define GL_MAX_MESH_ATOMIC_COUNTER_BUFFERS_NV 0x8E64 +#define GL_MAX_MESH_ATOMIC_COUNTERS_NV 0x8E65 +#define GL_MAX_MESH_SHADER_STORAGE_BLOCKS_NV 0x8E66 +#define GL_MAX_COMBINED_MESH_UNIFORM_COMPONENTS_NV 0x8E67 +#define GL_MAX_TASK_UNIFORM_BLOCKS_NV 0x8E68 +#define GL_MAX_TASK_TEXTURE_IMAGE_UNITS_NV 0x8E69 +#define GL_MAX_TASK_IMAGE_UNIFORMS_NV 0x8E6A +#define GL_MAX_TASK_UNIFORM_COMPONENTS_NV 0x8E6B +#define GL_MAX_TASK_ATOMIC_COUNTER_BUFFERS_NV 0x8E6C +#define GL_MAX_TASK_ATOMIC_COUNTERS_NV 0x8E6D +#define GL_MAX_TASK_SHADER_STORAGE_BLOCKS_NV 0x8E6E +#define GL_MAX_COMBINED_TASK_UNIFORM_COMPONENTS_NV 0x8E6F +#define GL_MAX_MESH_WORK_GROUP_INVOCATIONS_NV 0x95A2 +#define GL_MAX_TASK_WORK_GROUP_INVOCATIONS_NV 0x95A3 +#define GL_MAX_MESH_TOTAL_MEMORY_SIZE_NV 0x9536 +#define GL_MAX_TASK_TOTAL_MEMORY_SIZE_NV 0x9537 +#define GL_MAX_MESH_OUTPUT_VERTICES_NV 0x9538 +#define GL_MAX_MESH_OUTPUT_PRIMITIVES_NV 0x9539 +#define GL_MAX_TASK_OUTPUT_COUNT_NV 0x953A +#define GL_MAX_DRAW_MESH_TASKS_COUNT_NV 0x953D +#define GL_MAX_MESH_VIEWS_NV 0x9557 +#define GL_MESH_OUTPUT_PER_VERTEX_GRANULARITY_NV 0x92DF +#define GL_MESH_OUTPUT_PER_PRIMITIVE_GRANULARITY_NV 0x9543 +#define GL_MAX_MESH_WORK_GROUP_SIZE_NV 0x953B +#define GL_MAX_TASK_WORK_GROUP_SIZE_NV 0x953C +#define GL_MESH_WORK_GROUP_SIZE_NV 0x953E +#define GL_TASK_WORK_GROUP_SIZE_NV 0x953F +#define GL_MESH_VERTICES_OUT_NV 0x9579 +#define GL_MESH_PRIMITIVES_OUT_NV 0x957A +#define GL_MESH_OUTPUT_TYPE_NV 0x957B +#define GL_UNIFORM_BLOCK_REFERENCED_BY_MESH_SHADER_NV 0x959C +#define GL_UNIFORM_BLOCK_REFERENCED_BY_TASK_SHADER_NV 0x959D +#define GL_REFERENCED_BY_MESH_SHADER_NV 0x95A0 +#define GL_REFERENCED_BY_TASK_SHADER_NV 0x95A1 +#define GL_MESH_SHADER_BIT_NV 0x00000040 +#define GL_TASK_SHADER_BIT_NV 0x00000080 +#define GL_MESH_SUBROUTINE_NV 0x957C +#define GL_TASK_SUBROUTINE_NV 0x957D +#define GL_MESH_SUBROUTINE_UNIFORM_NV 0x957E +#define GL_TASK_SUBROUTINE_UNIFORM_NV 0x957F +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_MESH_SHADER_NV 0x959E +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TASK_SHADER_NV 0x959F +typedef void (APIENTRYP PFNGLDRAWMESHTASKSNVPROC) (GLuint first, GLuint count); +typedef void (APIENTRYP PFNGLDRAWMESHTASKSINDIRECTNVPROC) (GLintptr indirect); +typedef void (APIENTRYP PFNGLMULTIDRAWMESHTASKSINDIRECTNVPROC) (GLintptr indirect, GLsizei drawcount, GLsizei stride); +typedef void (APIENTRYP PFNGLMULTIDRAWMESHTASKSINDIRECTCOUNTNVPROC) (GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glDrawMeshTasksNV (GLuint first, GLuint count); +GLAPI void APIENTRY glDrawMeshTasksIndirectNV (GLintptr indirect); +GLAPI void APIENTRY glMultiDrawMeshTasksIndirectNV (GLintptr indirect, GLsizei drawcount, GLsizei stride); +GLAPI void APIENTRY glMultiDrawMeshTasksIndirectCountNV (GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +#endif +#endif /* GL_NV_mesh_shader */ + #ifndef GL_NV_multisample_coverage #define GL_NV_multisample_coverage 1 -#define GL_COLOR_SAMPLES_NV 0x8E20 #endif /* GL_NV_multisample_coverage */ #ifndef GL_NV_multisample_filter_hint @@ -9075,13 +10867,11 @@ GLAPI void APIENTRY glProgramBufferParametersIuivNV (GLenum target, GLuint bindi #define GL_SKIP_MISSING_GLYPH_NV 0x90A9 #define GL_USE_MISSING_GLYPH_NV 0x90AA #define GL_PATH_ERROR_POSITION_NV 0x90AB -#define GL_PATH_FOG_GEN_MODE_NV 0x90AC #define GL_ACCUM_ADJACENT_PAIRS_NV 0x90AD #define GL_ADJACENT_PAIRS_NV 0x90AE #define GL_FIRST_TO_REST_NV 0x90AF #define GL_PATH_GEN_MODE_NV 0x90B0 #define GL_PATH_GEN_COEFF_NV 0x90B1 -#define GL_PATH_GEN_COLOR_FORMAT_NV 0x90B2 #define GL_PATH_GEN_COMPONENTS_NV 0x90B3 #define GL_PATH_STENCIL_FUNC_NV 0x90B7 #define GL_PATH_STENCIL_REF_NV 0x90B8 @@ -9150,8 +10940,44 @@ GLAPI void APIENTRY glProgramBufferParametersIuivNV (GLenum target, GLuint bindi #define GL_FONT_UNDERLINE_POSITION_BIT_NV 0x04000000 #define GL_FONT_UNDERLINE_THICKNESS_BIT_NV 0x08000000 #define GL_FONT_HAS_KERNING_BIT_NV 0x10000000 +#define GL_ROUNDED_RECT_NV 0xE8 +#define GL_RELATIVE_ROUNDED_RECT_NV 0xE9 +#define GL_ROUNDED_RECT2_NV 0xEA +#define GL_RELATIVE_ROUNDED_RECT2_NV 0xEB +#define GL_ROUNDED_RECT4_NV 0xEC +#define GL_RELATIVE_ROUNDED_RECT4_NV 0xED +#define GL_ROUNDED_RECT8_NV 0xEE +#define GL_RELATIVE_ROUNDED_RECT8_NV 0xEF +#define GL_RELATIVE_RECT_NV 0xF7 +#define GL_FONT_GLYPHS_AVAILABLE_NV 0x9368 +#define GL_FONT_TARGET_UNAVAILABLE_NV 0x9369 +#define GL_FONT_UNAVAILABLE_NV 0x936A +#define GL_FONT_UNINTELLIGIBLE_NV 0x936B +#define GL_CONIC_CURVE_TO_NV 0x1A +#define GL_RELATIVE_CONIC_CURVE_TO_NV 0x1B +#define GL_FONT_NUM_GLYPH_INDICES_BIT_NV 0x20000000 +#define GL_STANDARD_FONT_FORMAT_NV 0x936C +#define GL_2_BYTES_NV 0x1407 +#define GL_3_BYTES_NV 0x1408 +#define GL_4_BYTES_NV 0x1409 +#define GL_EYE_LINEAR_NV 0x2400 +#define GL_OBJECT_LINEAR_NV 0x2401 +#define GL_CONSTANT_NV 0x8576 +#define GL_PATH_FOG_GEN_MODE_NV 0x90AC #define GL_PRIMARY_COLOR_NV 0x852C #define GL_SECONDARY_COLOR_NV 0x852D +#define GL_PATH_GEN_COLOR_FORMAT_NV 0x90B2 +#define GL_PATH_PROJECTION_NV 0x1701 +#define GL_PATH_MODELVIEW_NV 0x1700 +#define GL_PATH_MODELVIEW_STACK_DEPTH_NV 0x0BA3 +#define GL_PATH_MODELVIEW_MATRIX_NV 0x0BA6 +#define GL_PATH_MAX_MODELVIEW_STACK_DEPTH_NV 0x0D36 +#define GL_PATH_TRANSPOSE_MODELVIEW_MATRIX_NV 0x84E3 +#define GL_PATH_PROJECTION_STACK_DEPTH_NV 0x0BA4 +#define GL_PATH_PROJECTION_MATRIX_NV 0x0BA7 +#define GL_PATH_MAX_PROJECTION_STACK_DEPTH_NV 0x0D38 +#define GL_PATH_TRANSPOSE_PROJECTION_MATRIX_NV 0x84E4 +#define GL_FRAGMENT_INPUT_NV 0x936D typedef GLuint (APIENTRYP PFNGLGENPATHSNVPROC) (GLsizei range); typedef void (APIENTRYP PFNGLDELETEPATHSNVPROC) (GLuint path, GLsizei range); typedef GLboolean (APIENTRYP PFNGLISPATHNVPROC) (GLuint path); @@ -9178,9 +11004,6 @@ typedef void (APIENTRYP PFNGLSTENCILSTROKEPATHNVPROC) (GLuint path, GLint refere typedef void (APIENTRYP PFNGLSTENCILFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum transformType, const GLfloat *transformValues); typedef void (APIENTRYP PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum transformType, const GLfloat *transformValues); typedef void (APIENTRYP PFNGLPATHCOVERDEPTHFUNCNVPROC) (GLenum func); -typedef void (APIENTRYP PFNGLPATHCOLORGENNVPROC) (GLenum color, GLenum genMode, GLenum colorFormat, const GLfloat *coeffs); -typedef void (APIENTRYP PFNGLPATHTEXGENNVPROC) (GLenum texCoordSet, GLenum genMode, GLint components, const GLfloat *coeffs); -typedef void (APIENTRYP PFNGLPATHFOGGENNVPROC) (GLenum genMode); typedef void (APIENTRYP PFNGLCOVERFILLPATHNVPROC) (GLuint path, GLenum coverMode); typedef void (APIENTRYP PFNGLCOVERSTROKEPATHNVPROC) (GLuint path, GLenum coverMode); typedef void (APIENTRYP PFNGLCOVERFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); @@ -9193,14 +11016,32 @@ typedef void (APIENTRYP PFNGLGETPATHDASHARRAYNVPROC) (GLuint path, GLfloat *dash typedef void (APIENTRYP PFNGLGETPATHMETRICSNVPROC) (GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLsizei stride, GLfloat *metrics); typedef void (APIENTRYP PFNGLGETPATHMETRICRANGENVPROC) (GLbitfield metricQueryMask, GLuint firstPathName, GLsizei numPaths, GLsizei stride, GLfloat *metrics); typedef void (APIENTRYP PFNGLGETPATHSPACINGNVPROC) (GLenum pathListMode, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, GLfloat *returnedSpacing); -typedef void (APIENTRYP PFNGLGETPATHCOLORGENIVNVPROC) (GLenum color, GLenum pname, GLint *value); -typedef void (APIENTRYP PFNGLGETPATHCOLORGENFVNVPROC) (GLenum color, GLenum pname, GLfloat *value); -typedef void (APIENTRYP PFNGLGETPATHTEXGENIVNVPROC) (GLenum texCoordSet, GLenum pname, GLint *value); -typedef void (APIENTRYP PFNGLGETPATHTEXGENFVNVPROC) (GLenum texCoordSet, GLenum pname, GLfloat *value); typedef GLboolean (APIENTRYP PFNGLISPOINTINFILLPATHNVPROC) (GLuint path, GLuint mask, GLfloat x, GLfloat y); typedef GLboolean (APIENTRYP PFNGLISPOINTINSTROKEPATHNVPROC) (GLuint path, GLfloat x, GLfloat y); typedef GLfloat (APIENTRYP PFNGLGETPATHLENGTHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments); typedef GLboolean (APIENTRYP PFNGLPOINTALONGPATHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments, GLfloat distance, GLfloat *x, GLfloat *y, GLfloat *tangentX, GLfloat *tangentY); +typedef void (APIENTRYP PFNGLMATRIXLOAD3X2FNVPROC) (GLenum matrixMode, const GLfloat *m); +typedef void (APIENTRYP PFNGLMATRIXLOAD3X3FNVPROC) (GLenum matrixMode, const GLfloat *m); +typedef void (APIENTRYP PFNGLMATRIXLOADTRANSPOSE3X3FNVPROC) (GLenum matrixMode, const GLfloat *m); +typedef void (APIENTRYP PFNGLMATRIXMULT3X2FNVPROC) (GLenum matrixMode, const GLfloat *m); +typedef void (APIENTRYP PFNGLMATRIXMULT3X3FNVPROC) (GLenum matrixMode, const GLfloat *m); +typedef void (APIENTRYP PFNGLMATRIXMULTTRANSPOSE3X3FNVPROC) (GLenum matrixMode, const GLfloat *m); +typedef void (APIENTRYP PFNGLSTENCILTHENCOVERFILLPATHNVPROC) (GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode); +typedef void (APIENTRYP PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC) (GLuint path, GLint reference, GLuint mask, GLenum coverMode); +typedef void (APIENTRYP PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); +typedef void (APIENTRYP PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); +typedef GLenum (APIENTRYP PFNGLPATHGLYPHINDEXRANGENVPROC) (GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint pathParameterTemplate, GLfloat emScale, GLuint *baseAndCount); +typedef GLenum (APIENTRYP PFNGLPATHGLYPHINDEXARRAYNVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +typedef GLenum (APIENTRYP PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC) (GLuint firstPathName, GLenum fontTarget, GLsizeiptr fontSize, const void *fontData, GLsizei faceIndex, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +typedef void (APIENTRYP PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC) (GLuint program, GLint location, GLenum genMode, GLint components, const GLfloat *coeffs); +typedef void (APIENTRYP PFNGLGETPROGRAMRESOURCEFVNVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei count, GLsizei *length, GLfloat *params); +typedef void (APIENTRYP PFNGLPATHCOLORGENNVPROC) (GLenum color, GLenum genMode, GLenum colorFormat, const GLfloat *coeffs); +typedef void (APIENTRYP PFNGLPATHTEXGENNVPROC) (GLenum texCoordSet, GLenum genMode, GLint components, const GLfloat *coeffs); +typedef void (APIENTRYP PFNGLPATHFOGGENNVPROC) (GLenum genMode); +typedef void (APIENTRYP PFNGLGETPATHCOLORGENIVNVPROC) (GLenum color, GLenum pname, GLint *value); +typedef void (APIENTRYP PFNGLGETPATHCOLORGENFVNVPROC) (GLenum color, GLenum pname, GLfloat *value); +typedef void (APIENTRYP PFNGLGETPATHTEXGENIVNVPROC) (GLenum texCoordSet, GLenum pname, GLint *value); +typedef void (APIENTRYP PFNGLGETPATHTEXGENFVNVPROC) (GLenum texCoordSet, GLenum pname, GLfloat *value); #ifdef GL_GLEXT_PROTOTYPES GLAPI GLuint APIENTRY glGenPathsNV (GLsizei range); GLAPI void APIENTRY glDeletePathsNV (GLuint path, GLsizei range); @@ -9228,9 +11069,6 @@ GLAPI void APIENTRY glStencilStrokePathNV (GLuint path, GLint reference, GLuint GLAPI void APIENTRY glStencilFillPathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum transformType, const GLfloat *transformValues); GLAPI void APIENTRY glStencilStrokePathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum transformType, const GLfloat *transformValues); GLAPI void APIENTRY glPathCoverDepthFuncNV (GLenum func); -GLAPI void APIENTRY glPathColorGenNV (GLenum color, GLenum genMode, GLenum colorFormat, const GLfloat *coeffs); -GLAPI void APIENTRY glPathTexGenNV (GLenum texCoordSet, GLenum genMode, GLint components, const GLfloat *coeffs); -GLAPI void APIENTRY glPathFogGenNV (GLenum genMode); GLAPI void APIENTRY glCoverFillPathNV (GLuint path, GLenum coverMode); GLAPI void APIENTRY glCoverStrokePathNV (GLuint path, GLenum coverMode); GLAPI void APIENTRY glCoverFillPathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); @@ -9243,17 +11081,40 @@ GLAPI void APIENTRY glGetPathDashArrayNV (GLuint path, GLfloat *dashArray); GLAPI void APIENTRY glGetPathMetricsNV (GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLsizei stride, GLfloat *metrics); GLAPI void APIENTRY glGetPathMetricRangeNV (GLbitfield metricQueryMask, GLuint firstPathName, GLsizei numPaths, GLsizei stride, GLfloat *metrics); GLAPI void APIENTRY glGetPathSpacingNV (GLenum pathListMode, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, GLfloat *returnedSpacing); -GLAPI void APIENTRY glGetPathColorGenivNV (GLenum color, GLenum pname, GLint *value); -GLAPI void APIENTRY glGetPathColorGenfvNV (GLenum color, GLenum pname, GLfloat *value); -GLAPI void APIENTRY glGetPathTexGenivNV (GLenum texCoordSet, GLenum pname, GLint *value); -GLAPI void APIENTRY glGetPathTexGenfvNV (GLenum texCoordSet, GLenum pname, GLfloat *value); GLAPI GLboolean APIENTRY glIsPointInFillPathNV (GLuint path, GLuint mask, GLfloat x, GLfloat y); GLAPI GLboolean APIENTRY glIsPointInStrokePathNV (GLuint path, GLfloat x, GLfloat y); GLAPI GLfloat APIENTRY glGetPathLengthNV (GLuint path, GLsizei startSegment, GLsizei numSegments); GLAPI GLboolean APIENTRY glPointAlongPathNV (GLuint path, GLsizei startSegment, GLsizei numSegments, GLfloat distance, GLfloat *x, GLfloat *y, GLfloat *tangentX, GLfloat *tangentY); +GLAPI void APIENTRY glMatrixLoad3x2fNV (GLenum matrixMode, const GLfloat *m); +GLAPI void APIENTRY glMatrixLoad3x3fNV (GLenum matrixMode, const GLfloat *m); +GLAPI void APIENTRY glMatrixLoadTranspose3x3fNV (GLenum matrixMode, const GLfloat *m); +GLAPI void APIENTRY glMatrixMult3x2fNV (GLenum matrixMode, const GLfloat *m); +GLAPI void APIENTRY glMatrixMult3x3fNV (GLenum matrixMode, const GLfloat *m); +GLAPI void APIENTRY glMatrixMultTranspose3x3fNV (GLenum matrixMode, const GLfloat *m); +GLAPI void APIENTRY glStencilThenCoverFillPathNV (GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode); +GLAPI void APIENTRY glStencilThenCoverStrokePathNV (GLuint path, GLint reference, GLuint mask, GLenum coverMode); +GLAPI void APIENTRY glStencilThenCoverFillPathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); +GLAPI void APIENTRY glStencilThenCoverStrokePathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); +GLAPI GLenum APIENTRY glPathGlyphIndexRangeNV (GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint pathParameterTemplate, GLfloat emScale, GLuint *baseAndCount); +GLAPI GLenum APIENTRY glPathGlyphIndexArrayNV (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +GLAPI GLenum APIENTRY glPathMemoryGlyphIndexArrayNV (GLuint firstPathName, GLenum fontTarget, GLsizeiptr fontSize, const void *fontData, GLsizei faceIndex, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +GLAPI void APIENTRY glProgramPathFragmentInputGenNV (GLuint program, GLint location, GLenum genMode, GLint components, const GLfloat *coeffs); +GLAPI void APIENTRY glGetProgramResourcefvNV (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei count, GLsizei *length, GLfloat *params); +GLAPI void APIENTRY glPathColorGenNV (GLenum color, GLenum genMode, GLenum colorFormat, const GLfloat *coeffs); +GLAPI void APIENTRY glPathTexGenNV (GLenum texCoordSet, GLenum genMode, GLint components, const GLfloat *coeffs); +GLAPI void APIENTRY glPathFogGenNV (GLenum genMode); +GLAPI void APIENTRY glGetPathColorGenivNV (GLenum color, GLenum pname, GLint *value); +GLAPI void APIENTRY glGetPathColorGenfvNV (GLenum color, GLenum pname, GLfloat *value); +GLAPI void APIENTRY glGetPathTexGenivNV (GLenum texCoordSet, GLenum pname, GLint *value); +GLAPI void APIENTRY glGetPathTexGenfvNV (GLenum texCoordSet, GLenum pname, GLfloat *value); #endif #endif /* GL_NV_path_rendering */ +#ifndef GL_NV_path_rendering_shared_edge +#define GL_NV_path_rendering_shared_edge 1 +#define GL_SHARED_EDGE_NV 0xC0 +#endif /* GL_NV_path_rendering_shared_edge */ + #ifndef GL_NV_pixel_data_range #define GL_NV_pixel_data_range 1 #define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878 @@ -9319,6 +11180,38 @@ GLAPI void APIENTRY glPrimitiveRestartIndexNV (GLuint index); #endif #endif /* GL_NV_primitive_restart */ +#ifndef GL_NV_primitive_shading_rate +#define GL_NV_primitive_shading_rate 1 +#define GL_SHADING_RATE_IMAGE_PER_PRIMITIVE_NV 0x95B1 +#define GL_SHADING_RATE_IMAGE_PALETTE_COUNT_NV 0x95B2 +#endif /* GL_NV_primitive_shading_rate */ + +#ifndef GL_NV_query_resource +#define GL_NV_query_resource 1 +#define GL_QUERY_RESOURCE_TYPE_VIDMEM_ALLOC_NV 0x9540 +#define GL_QUERY_RESOURCE_MEMTYPE_VIDMEM_NV 0x9542 +#define GL_QUERY_RESOURCE_SYS_RESERVED_NV 0x9544 +#define GL_QUERY_RESOURCE_TEXTURE_NV 0x9545 +#define GL_QUERY_RESOURCE_RENDERBUFFER_NV 0x9546 +#define GL_QUERY_RESOURCE_BUFFEROBJECT_NV 0x9547 +typedef GLint (APIENTRYP PFNGLQUERYRESOURCENVPROC) (GLenum queryType, GLint tagId, GLuint count, GLint *buffer); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLint APIENTRY glQueryResourceNV (GLenum queryType, GLint tagId, GLuint count, GLint *buffer); +#endif +#endif /* GL_NV_query_resource */ + +#ifndef GL_NV_query_resource_tag +#define GL_NV_query_resource_tag 1 +typedef void (APIENTRYP PFNGLGENQUERYRESOURCETAGNVPROC) (GLsizei n, GLint *tagIds); +typedef void (APIENTRYP PFNGLDELETEQUERYRESOURCETAGNVPROC) (GLsizei n, const GLint *tagIds); +typedef void (APIENTRYP PFNGLQUERYRESOURCETAGNVPROC) (GLint tagId, const GLchar *tagString); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glGenQueryResourceTagNV (GLsizei n, GLint *tagIds); +GLAPI void APIENTRY glDeleteQueryResourceTagNV (GLsizei n, const GLint *tagIds); +GLAPI void APIENTRY glQueryResourceTagNV (GLint tagId, const GLchar *tagString); +#endif +#endif /* GL_NV_query_resource_tag */ + #ifndef GL_NV_register_combiners #define GL_NV_register_combiners 1 #define GL_REGISTER_COMBINERS_NV 0x8522 @@ -9411,6 +11304,52 @@ GLAPI void APIENTRY glGetCombinerStageParameterfvNV (GLenum stage, GLenum pname, #endif #endif /* GL_NV_register_combiners2 */ +#ifndef GL_NV_representative_fragment_test +#define GL_NV_representative_fragment_test 1 +#define GL_REPRESENTATIVE_FRAGMENT_TEST_NV 0x937F +#endif /* GL_NV_representative_fragment_test */ + +#ifndef GL_NV_robustness_video_memory_purge +#define GL_NV_robustness_video_memory_purge 1 +#define GL_PURGED_CONTEXT_RESET_NV 0x92BB +#endif /* GL_NV_robustness_video_memory_purge */ + +#ifndef GL_NV_sample_locations +#define GL_NV_sample_locations 1 +#define GL_SAMPLE_LOCATION_SUBPIXEL_BITS_NV 0x933D +#define GL_SAMPLE_LOCATION_PIXEL_GRID_WIDTH_NV 0x933E +#define GL_SAMPLE_LOCATION_PIXEL_GRID_HEIGHT_NV 0x933F +#define GL_PROGRAMMABLE_SAMPLE_LOCATION_TABLE_SIZE_NV 0x9340 +#define GL_SAMPLE_LOCATION_NV 0x8E50 +#define GL_PROGRAMMABLE_SAMPLE_LOCATION_NV 0x9341 +#define GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_NV 0x9342 +#define GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_NV 0x9343 +typedef void (APIENTRYP PFNGLFRAMEBUFFERSAMPLELOCATIONSFVNVPROC) (GLenum target, GLuint start, GLsizei count, const GLfloat *v); +typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVNVPROC) (GLuint framebuffer, GLuint start, GLsizei count, const GLfloat *v); +typedef void (APIENTRYP PFNGLRESOLVEDEPTHVALUESNVPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFramebufferSampleLocationsfvNV (GLenum target, GLuint start, GLsizei count, const GLfloat *v); +GLAPI void APIENTRY glNamedFramebufferSampleLocationsfvNV (GLuint framebuffer, GLuint start, GLsizei count, const GLfloat *v); +GLAPI void APIENTRY glResolveDepthValuesNV (void); +#endif +#endif /* GL_NV_sample_locations */ + +#ifndef GL_NV_sample_mask_override_coverage +#define GL_NV_sample_mask_override_coverage 1 +#endif /* GL_NV_sample_mask_override_coverage */ + +#ifndef GL_NV_scissor_exclusive +#define GL_NV_scissor_exclusive 1 +#define GL_SCISSOR_TEST_EXCLUSIVE_NV 0x9555 +#define GL_SCISSOR_BOX_EXCLUSIVE_NV 0x9556 +typedef void (APIENTRYP PFNGLSCISSOREXCLUSIVENVPROC) (GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (APIENTRYP PFNGLSCISSOREXCLUSIVEARRAYVNVPROC) (GLuint first, GLsizei count, const GLint *v); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glScissorExclusiveNV (GLint x, GLint y, GLsizei width, GLsizei height); +GLAPI void APIENTRY glScissorExclusiveArrayvNV (GLuint first, GLsizei count, const GLint *v); +#endif +#endif /* GL_NV_scissor_exclusive */ + #ifndef GL_NV_shader_atomic_counters #define GL_NV_shader_atomic_counters 1 #endif /* GL_NV_shader_atomic_counters */ @@ -9419,6 +11358,18 @@ GLAPI void APIENTRY glGetCombinerStageParameterfvNV (GLenum stage, GLenum pname, #define GL_NV_shader_atomic_float 1 #endif /* GL_NV_shader_atomic_float */ +#ifndef GL_NV_shader_atomic_float64 +#define GL_NV_shader_atomic_float64 1 +#endif /* GL_NV_shader_atomic_float64 */ + +#ifndef GL_NV_shader_atomic_fp16_vector +#define GL_NV_shader_atomic_fp16_vector 1 +#endif /* GL_NV_shader_atomic_fp16_vector */ + +#ifndef GL_NV_shader_atomic_int64 +#define GL_NV_shader_atomic_int64 1 +#endif /* GL_NV_shader_atomic_int64 */ + #ifndef GL_NV_shader_buffer_load #define GL_NV_shader_buffer_load 1 #define GL_BUFFER_GPU_ADDRESS_NV 0x8F1D @@ -9463,6 +11414,15 @@ GLAPI void APIENTRY glProgramUniformui64vNV (GLuint program, GLint location, GLs #define GL_NV_shader_storage_buffer_object 1 #endif /* GL_NV_shader_storage_buffer_object */ +#ifndef GL_NV_shader_subgroup_partitioned +#define GL_NV_shader_subgroup_partitioned 1 +#define GL_SUBGROUP_FEATURE_PARTITIONED_BIT_NV 0x00000100 +#endif /* GL_NV_shader_subgroup_partitioned */ + +#ifndef GL_NV_shader_texture_footprint +#define GL_NV_shader_texture_footprint 1 +#endif /* GL_NV_shader_texture_footprint */ + #ifndef GL_NV_shader_thread_group #define GL_NV_shader_thread_group 1 #define GL_WARP_SIZE_NV 0x9339 @@ -9474,6 +11434,51 @@ GLAPI void APIENTRY glProgramUniformui64vNV (GLuint program, GLint location, GLs #define GL_NV_shader_thread_shuffle 1 #endif /* GL_NV_shader_thread_shuffle */ +#ifndef GL_NV_shading_rate_image +#define GL_NV_shading_rate_image 1 +#define GL_SHADING_RATE_IMAGE_NV 0x9563 +#define GL_SHADING_RATE_NO_INVOCATIONS_NV 0x9564 +#define GL_SHADING_RATE_1_INVOCATION_PER_PIXEL_NV 0x9565 +#define GL_SHADING_RATE_1_INVOCATION_PER_1X2_PIXELS_NV 0x9566 +#define GL_SHADING_RATE_1_INVOCATION_PER_2X1_PIXELS_NV 0x9567 +#define GL_SHADING_RATE_1_INVOCATION_PER_2X2_PIXELS_NV 0x9568 +#define GL_SHADING_RATE_1_INVOCATION_PER_2X4_PIXELS_NV 0x9569 +#define GL_SHADING_RATE_1_INVOCATION_PER_4X2_PIXELS_NV 0x956A +#define GL_SHADING_RATE_1_INVOCATION_PER_4X4_PIXELS_NV 0x956B +#define GL_SHADING_RATE_2_INVOCATIONS_PER_PIXEL_NV 0x956C +#define GL_SHADING_RATE_4_INVOCATIONS_PER_PIXEL_NV 0x956D +#define GL_SHADING_RATE_8_INVOCATIONS_PER_PIXEL_NV 0x956E +#define GL_SHADING_RATE_16_INVOCATIONS_PER_PIXEL_NV 0x956F +#define GL_SHADING_RATE_IMAGE_BINDING_NV 0x955B +#define GL_SHADING_RATE_IMAGE_TEXEL_WIDTH_NV 0x955C +#define GL_SHADING_RATE_IMAGE_TEXEL_HEIGHT_NV 0x955D +#define GL_SHADING_RATE_IMAGE_PALETTE_SIZE_NV 0x955E +#define GL_MAX_COARSE_FRAGMENT_SAMPLES_NV 0x955F +#define GL_SHADING_RATE_SAMPLE_ORDER_DEFAULT_NV 0x95AE +#define GL_SHADING_RATE_SAMPLE_ORDER_PIXEL_MAJOR_NV 0x95AF +#define GL_SHADING_RATE_SAMPLE_ORDER_SAMPLE_MAJOR_NV 0x95B0 +typedef void (APIENTRYP PFNGLBINDSHADINGRATEIMAGENVPROC) (GLuint texture); +typedef void (APIENTRYP PFNGLGETSHADINGRATEIMAGEPALETTENVPROC) (GLuint viewport, GLuint entry, GLenum *rate); +typedef void (APIENTRYP PFNGLGETSHADINGRATESAMPLELOCATIONIVNVPROC) (GLenum rate, GLuint samples, GLuint index, GLint *location); +typedef void (APIENTRYP PFNGLSHADINGRATEIMAGEBARRIERNVPROC) (GLboolean synchronize); +typedef void (APIENTRYP PFNGLSHADINGRATEIMAGEPALETTENVPROC) (GLuint viewport, GLuint first, GLsizei count, const GLenum *rates); +typedef void (APIENTRYP PFNGLSHADINGRATESAMPLEORDERNVPROC) (GLenum order); +typedef void (APIENTRYP PFNGLSHADINGRATESAMPLEORDERCUSTOMNVPROC) (GLenum rate, GLuint samples, const GLint *locations); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glBindShadingRateImageNV (GLuint texture); +GLAPI void APIENTRY glGetShadingRateImagePaletteNV (GLuint viewport, GLuint entry, GLenum *rate); +GLAPI void APIENTRY glGetShadingRateSampleLocationivNV (GLenum rate, GLuint samples, GLuint index, GLint *location); +GLAPI void APIENTRY glShadingRateImageBarrierNV (GLboolean synchronize); +GLAPI void APIENTRY glShadingRateImagePaletteNV (GLuint viewport, GLuint first, GLsizei count, const GLenum *rates); +GLAPI void APIENTRY glShadingRateSampleOrderNV (GLenum order); +GLAPI void APIENTRY glShadingRateSampleOrderCustomNV (GLenum rate, GLuint samples, const GLint *locations); +#endif +#endif /* GL_NV_shading_rate_image */ + +#ifndef GL_NV_stereo_view_rendering +#define GL_NV_stereo_view_rendering 1 +#endif /* GL_NV_stereo_view_rendering */ + #ifndef GL_NV_tessellation_program5 #define GL_NV_tessellation_program5 1 #define GL_MAX_PROGRAM_PATCH_ATTRIBS_NV 0x86D8 @@ -9550,6 +11555,10 @@ GLAPI void APIENTRY glTextureImage3DMultisampleCoverageNV (GLuint texture, GLenu #define GL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8 #endif /* GL_NV_texture_rectangle */ +#ifndef GL_NV_texture_rectangle_compressed +#define GL_NV_texture_rectangle_compressed 1 +#endif /* GL_NV_texture_rectangle_compressed */ + #ifndef GL_NV_texture_shader #define GL_NV_texture_shader 1 #define GL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C @@ -9653,6 +11662,23 @@ GLAPI void APIENTRY glTextureImage3DMultisampleCoverageNV (GLuint texture, GLenu #define GL_FORCE_BLUE_TO_ONE_NV 0x8860 #endif /* GL_NV_texture_shader3 */ +#ifndef GL_NV_timeline_semaphore +#define GL_NV_timeline_semaphore 1 +#define GL_TIMELINE_SEMAPHORE_VALUE_NV 0x9595 +#define GL_SEMAPHORE_TYPE_NV 0x95B3 +#define GL_SEMAPHORE_TYPE_BINARY_NV 0x95B4 +#define GL_SEMAPHORE_TYPE_TIMELINE_NV 0x95B5 +#define GL_MAX_TIMELINE_SEMAPHORE_VALUE_DIFFERENCE_NV 0x95B6 +typedef void (APIENTRYP PFNGLCREATESEMAPHORESNVPROC) (GLsizei n, GLuint *semaphores); +typedef void (APIENTRYP PFNGLSEMAPHOREPARAMETERIVNVPROC) (GLuint semaphore, GLenum pname, const GLint *params); +typedef void (APIENTRYP PFNGLGETSEMAPHOREPARAMETERIVNVPROC) (GLuint semaphore, GLenum pname, GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glCreateSemaphoresNV (GLsizei n, GLuint *semaphores); +GLAPI void APIENTRY glSemaphoreParameterivNV (GLuint semaphore, GLenum pname, const GLint *params); +GLAPI void APIENTRY glGetSemaphoreParameterivNV (GLuint semaphore, GLenum pname, GLint *params); +#endif +#endif /* GL_NV_timeline_semaphore */ + #ifndef GL_NV_transform_feedback #define GL_NV_transform_feedback 1 #define GL_BACK_PRIMARY_COLOR_NV 0x8C77 @@ -9688,7 +11714,7 @@ GLAPI void APIENTRY glTextureImage3DMultisampleCoverageNV (GLuint texture, GLenu #define GL_SKIP_COMPONENTS1_NV -6 typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKNVPROC) (GLenum primitiveMode); typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKNVPROC) (void); -typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC) (GLuint count, const GLint *attribs, GLenum bufferMode); +typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC) (GLsizei count, const GLint *attribs, GLenum bufferMode); typedef void (APIENTRYP PFNGLBINDBUFFERRANGENVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); typedef void (APIENTRYP PFNGLBINDBUFFEROFFSETNVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset); typedef void (APIENTRYP PFNGLBINDBUFFERBASENVPROC) (GLenum target, GLuint index, GLuint buffer); @@ -9701,7 +11727,7 @@ typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKSTREAMATTRIBSNVPROC) (GLsizei coun #ifdef GL_GLEXT_PROTOTYPES GLAPI void APIENTRY glBeginTransformFeedbackNV (GLenum primitiveMode); GLAPI void APIENTRY glEndTransformFeedbackNV (void); -GLAPI void APIENTRY glTransformFeedbackAttribsNV (GLuint count, const GLint *attribs, GLenum bufferMode); +GLAPI void APIENTRY glTransformFeedbackAttribsNV (GLsizei count, const GLint *attribs, GLenum bufferMode); GLAPI void APIENTRY glBindBufferRangeNV (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); GLAPI void APIENTRY glBindBufferOffsetNV (GLenum target, GLuint index, GLuint buffer, GLintptr offset); GLAPI void APIENTRY glBindBufferBaseNV (GLenum target, GLuint index, GLuint buffer); @@ -9738,6 +11764,13 @@ GLAPI void APIENTRY glDrawTransformFeedbackNV (GLenum mode, GLuint id); #endif #endif /* GL_NV_transform_feedback2 */ +#ifndef GL_NV_uniform_buffer_unified_memory +#define GL_NV_uniform_buffer_unified_memory 1 +#define GL_UNIFORM_BUFFER_UNIFIED_NV 0x936E +#define GL_UNIFORM_BUFFER_ADDRESS_NV 0x936F +#define GL_UNIFORM_BUFFER_LENGTH_NV 0x9370 +#endif /* GL_NV_uniform_buffer_unified_memory */ + #ifndef GL_NV_vdpau_interop #define GL_NV_vdpau_interop 1 typedef GLintptr GLvdpauSurfaceNV; @@ -9751,7 +11784,7 @@ typedef GLvdpauSurfaceNV (APIENTRYP PFNGLVDPAUREGISTERVIDEOSURFACENVPROC) (const typedef GLvdpauSurfaceNV (APIENTRYP PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC) (const void *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames); typedef GLboolean (APIENTRYP PFNGLVDPAUISSURFACENVPROC) (GLvdpauSurfaceNV surface); typedef void (APIENTRYP PFNGLVDPAUUNREGISTERSURFACENVPROC) (GLvdpauSurfaceNV surface); -typedef void (APIENTRYP PFNGLVDPAUGETSURFACEIVNVPROC) (GLvdpauSurfaceNV surface, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +typedef void (APIENTRYP PFNGLVDPAUGETSURFACEIVNVPROC) (GLvdpauSurfaceNV surface, GLenum pname, GLsizei count, GLsizei *length, GLint *values); typedef void (APIENTRYP PFNGLVDPAUSURFACEACCESSNVPROC) (GLvdpauSurfaceNV surface, GLenum access); typedef void (APIENTRYP PFNGLVDPAUMAPSURFACESNVPROC) (GLsizei numSurfaces, const GLvdpauSurfaceNV *surfaces); typedef void (APIENTRYP PFNGLVDPAUUNMAPSURFACESNVPROC) (GLsizei numSurface, const GLvdpauSurfaceNV *surfaces); @@ -9762,13 +11795,21 @@ GLAPI GLvdpauSurfaceNV APIENTRY glVDPAURegisterVideoSurfaceNV (const void *vdpSu GLAPI GLvdpauSurfaceNV APIENTRY glVDPAURegisterOutputSurfaceNV (const void *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames); GLAPI GLboolean APIENTRY glVDPAUIsSurfaceNV (GLvdpauSurfaceNV surface); GLAPI void APIENTRY glVDPAUUnregisterSurfaceNV (GLvdpauSurfaceNV surface); -GLAPI void APIENTRY glVDPAUGetSurfaceivNV (GLvdpauSurfaceNV surface, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +GLAPI void APIENTRY glVDPAUGetSurfaceivNV (GLvdpauSurfaceNV surface, GLenum pname, GLsizei count, GLsizei *length, GLint *values); GLAPI void APIENTRY glVDPAUSurfaceAccessNV (GLvdpauSurfaceNV surface, GLenum access); GLAPI void APIENTRY glVDPAUMapSurfacesNV (GLsizei numSurfaces, const GLvdpauSurfaceNV *surfaces); GLAPI void APIENTRY glVDPAUUnmapSurfacesNV (GLsizei numSurface, const GLvdpauSurfaceNV *surfaces); #endif #endif /* GL_NV_vdpau_interop */ +#ifndef GL_NV_vdpau_interop2 +#define GL_NV_vdpau_interop2 1 +typedef GLvdpauSurfaceNV (APIENTRYP PFNGLVDPAUREGISTERVIDEOSURFACEWITHPICTURESTRUCTURENVPROC) (const void *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames, GLboolean isFrameStructure); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI GLvdpauSurfaceNV APIENTRY glVDPAURegisterVideoSurfaceWithPictureStructureNV (const void *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames, GLboolean isFrameStructure); +#endif +#endif /* GL_NV_vdpau_interop2 */ + #ifndef GL_NV_vertex_array_range #define GL_NV_vertex_array_range 1 #define GL_VERTEX_ARRAY_RANGE_NV 0x851D @@ -10124,54 +12165,6 @@ GLAPI void APIENTRY glVertexAttribs4ubvNV (GLuint index, GLsizei count, const GL #ifndef GL_NV_vertex_program4 #define GL_NV_vertex_program4 1 #define GL_VERTEX_ATTRIB_ARRAY_INTEGER_NV 0x88FD -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IEXTPROC) (GLuint index, GLint x); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IEXTPROC) (GLuint index, GLint x, GLint y); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IEXTPROC) (GLuint index, GLint x, GLint y, GLint z); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IEXTPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIEXTPROC) (GLuint index, GLuint x); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIEXTPROC) (GLuint index, GLuint x, GLuint y); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVEXTPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVEXTPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVEXTPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVEXTPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVEXTPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVEXTPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVEXTPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVEXTPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVEXTPROC) (GLuint index, const GLbyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVEXTPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVEXTPROC) (GLuint index, const GLubyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVEXTPROC) (GLuint index, const GLushort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVEXTPROC) (GLuint index, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVEXTPROC) (GLuint index, GLenum pname, GLuint *params); -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexAttribI1iEXT (GLuint index, GLint x); -GLAPI void APIENTRY glVertexAttribI2iEXT (GLuint index, GLint x, GLint y); -GLAPI void APIENTRY glVertexAttribI3iEXT (GLuint index, GLint x, GLint y, GLint z); -GLAPI void APIENTRY glVertexAttribI4iEXT (GLuint index, GLint x, GLint y, GLint z, GLint w); -GLAPI void APIENTRY glVertexAttribI1uiEXT (GLuint index, GLuint x); -GLAPI void APIENTRY glVertexAttribI2uiEXT (GLuint index, GLuint x, GLuint y); -GLAPI void APIENTRY glVertexAttribI3uiEXT (GLuint index, GLuint x, GLuint y, GLuint z); -GLAPI void APIENTRY glVertexAttribI4uiEXT (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -GLAPI void APIENTRY glVertexAttribI1ivEXT (GLuint index, const GLint *v); -GLAPI void APIENTRY glVertexAttribI2ivEXT (GLuint index, const GLint *v); -GLAPI void APIENTRY glVertexAttribI3ivEXT (GLuint index, const GLint *v); -GLAPI void APIENTRY glVertexAttribI4ivEXT (GLuint index, const GLint *v); -GLAPI void APIENTRY glVertexAttribI1uivEXT (GLuint index, const GLuint *v); -GLAPI void APIENTRY glVertexAttribI2uivEXT (GLuint index, const GLuint *v); -GLAPI void APIENTRY glVertexAttribI3uivEXT (GLuint index, const GLuint *v); -GLAPI void APIENTRY glVertexAttribI4uivEXT (GLuint index, const GLuint *v); -GLAPI void APIENTRY glVertexAttribI4bvEXT (GLuint index, const GLbyte *v); -GLAPI void APIENTRY glVertexAttribI4svEXT (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttribI4ubvEXT (GLuint index, const GLubyte *v); -GLAPI void APIENTRY glVertexAttribI4usvEXT (GLuint index, const GLushort *v); -GLAPI void APIENTRY glVertexAttribIPointerEXT (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); -GLAPI void APIENTRY glGetVertexAttribIivEXT (GLuint index, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetVertexAttribIuivEXT (GLuint index, GLenum pname, GLuint *params); -#endif #endif /* GL_NV_vertex_program4 */ #ifndef GL_NV_video_capture @@ -10233,6 +12226,30 @@ GLAPI void APIENTRY glVideoCaptureStreamParameterdvNV (GLuint video_capture_slot #endif #endif /* GL_NV_video_capture */ +#ifndef GL_NV_viewport_array2 +#define GL_NV_viewport_array2 1 +#endif /* GL_NV_viewport_array2 */ + +#ifndef GL_NV_viewport_swizzle +#define GL_NV_viewport_swizzle 1 +#define GL_VIEWPORT_SWIZZLE_POSITIVE_X_NV 0x9350 +#define GL_VIEWPORT_SWIZZLE_NEGATIVE_X_NV 0x9351 +#define GL_VIEWPORT_SWIZZLE_POSITIVE_Y_NV 0x9352 +#define GL_VIEWPORT_SWIZZLE_NEGATIVE_Y_NV 0x9353 +#define GL_VIEWPORT_SWIZZLE_POSITIVE_Z_NV 0x9354 +#define GL_VIEWPORT_SWIZZLE_NEGATIVE_Z_NV 0x9355 +#define GL_VIEWPORT_SWIZZLE_POSITIVE_W_NV 0x9356 +#define GL_VIEWPORT_SWIZZLE_NEGATIVE_W_NV 0x9357 +#define GL_VIEWPORT_SWIZZLE_X_NV 0x9358 +#define GL_VIEWPORT_SWIZZLE_Y_NV 0x9359 +#define GL_VIEWPORT_SWIZZLE_Z_NV 0x935A +#define GL_VIEWPORT_SWIZZLE_W_NV 0x935B +typedef void (APIENTRYP PFNGLVIEWPORTSWIZZLENVPROC) (GLuint index, GLenum swizzlex, GLenum swizzley, GLenum swizzlez, GLenum swizzlew); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glViewportSwizzleNV (GLuint index, GLenum swizzlex, GLenum swizzley, GLenum swizzlez, GLenum swizzlew); +#endif +#endif /* GL_NV_viewport_swizzle */ + #ifndef GL_OML_interlace #define GL_OML_interlace 1 #define GL_INTERLACE_OML 0x8980 @@ -10255,6 +12272,22 @@ GLAPI void APIENTRY glVideoCaptureStreamParameterdvNV (GLuint video_capture_slot #define GL_FORMAT_SUBSAMPLE_244_244_OML 0x8983 #endif /* GL_OML_subsample */ +#ifndef GL_OVR_multiview +#define GL_OVR_multiview 1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR 0x9630 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR 0x9632 +#define GL_MAX_VIEWS_OVR 0x9631 +#define GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR 0x9633 +typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews); +#ifdef GL_GLEXT_PROTOTYPES +GLAPI void APIENTRY glFramebufferTextureMultiviewOVR (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews); +#endif +#endif /* GL_OVR_multiview */ + +#ifndef GL_OVR_multiview2 +#define GL_OVR_multiview2 1 +#endif /* GL_OVR_multiview2 */ + #ifndef GL_PGI_misc_hints #define GL_PGI_misc_hints 1 #define GL_PREFER_DOUBLEBUFFER_HINT_PGI 0x1A1F8 @@ -10811,10 +12844,10 @@ GLAPI void APIENTRY glReferencePlaneSGIX (const GLdouble *equation); #ifndef GL_SGIX_resample #define GL_SGIX_resample 1 -#define GL_PACK_RESAMPLE_SGIX 0x842C -#define GL_UNPACK_RESAMPLE_SGIX 0x842D -#define GL_RESAMPLE_REPLICATE_SGIX 0x842E -#define GL_RESAMPLE_ZERO_FILL_SGIX 0x842F +#define GL_PACK_RESAMPLE_SGIX 0x842E +#define GL_UNPACK_RESAMPLE_SGIX 0x842F +#define GL_RESAMPLE_REPLICATE_SGIX 0x8433 +#define GL_RESAMPLE_ZERO_FILL_SGIX 0x8434 #define GL_RESAMPLE_DECIMATE_SGIX 0x8430 #endif /* GL_SGIX_resample */ diff --git a/SDL2-2.0.12/include/SDL_opengles.h b/SDL2-2.30.5/include/SDL_opengles.h similarity index 95% rename from SDL2-2.0.12/include/SDL_opengles.h rename to SDL2-2.30.5/include/SDL_opengles.h index 5c2a3e6..7e9a1ab 100644 --- a/SDL2-2.0.12/include/SDL_opengles.h +++ b/SDL2-2.30.5/include/SDL_opengles.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/include/SDL_opengles2.h b/SDL2-2.30.5/include/SDL_opengles2.h similarity index 91% rename from SDL2-2.0.12/include/SDL_opengles2.h rename to SDL2-2.30.5/include/SDL_opengles2.h index 00bc180..9697134 100644 --- a/SDL2-2.0.12/include/SDL_opengles2.h +++ b/SDL2-2.30.5/include/SDL_opengles2.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,7 +26,7 @@ */ #include "SDL_config.h" -#ifndef _MSC_VER +#if !defined(_MSC_VER) && !defined(SDL_USE_BUILTIN_OPENGL_DEFINITIONS) #ifdef __IPHONEOS__ #include diff --git a/SDL2-2.30.5/include/SDL_opengles2_gl2.h b/SDL2-2.30.5/include/SDL_opengles2_gl2.h new file mode 100644 index 0000000..d13622a --- /dev/null +++ b/SDL2-2.30.5/include/SDL_opengles2_gl2.h @@ -0,0 +1,656 @@ +#ifndef __gles2_gl2_h_ +#define __gles2_gl2_h_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Copyright 2013-2020 The Khronos Group Inc. +** SPDX-License-Identifier: MIT +** +** This header is generated from the Khronos OpenGL / OpenGL ES XML +** API Registry. The current version of the Registry, generator scripts +** used to make the header, and the header can be found at +** https://github.com/KhronosGroup/OpenGL-Registry +*/ + +/*#include */ + +#ifndef GL_APIENTRYP +#define GL_APIENTRYP GL_APIENTRY* +#endif + +#ifndef GL_GLES_PROTOTYPES +#define GL_GLES_PROTOTYPES 1 +#endif + +/* Generated on date 20220530 */ + +/* Generated C header for: + * API: gles2 + * Profile: common + * Versions considered: 2\.[0-9] + * Versions emitted: .* + * Default extensions included: None + * Additional extensions included: _nomatch_^ + * Extensions removed: _nomatch_^ + */ + +#ifndef GL_ES_VERSION_2_0 +#define GL_ES_VERSION_2_0 1 +/*#include */ +typedef khronos_int8_t GLbyte; +typedef khronos_float_t GLclampf; +typedef khronos_int32_t GLfixed; +typedef khronos_int16_t GLshort; +typedef khronos_uint16_t GLushort; +typedef void GLvoid; +typedef struct __GLsync *GLsync; +typedef khronos_int64_t GLint64; +typedef khronos_uint64_t GLuint64; +typedef unsigned int GLenum; +typedef unsigned int GLuint; +typedef char GLchar; +typedef khronos_float_t GLfloat; +typedef khronos_ssize_t GLsizeiptr; +typedef khronos_intptr_t GLintptr; +typedef unsigned int GLbitfield; +typedef int GLint; +typedef unsigned char GLboolean; +typedef int GLsizei; +typedef khronos_uint8_t GLubyte; +#define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_STENCIL_BUFFER_BIT 0x00000400 +#define GL_COLOR_BUFFER_BIT 0x00004000 +#define GL_FALSE 0 +#define GL_TRUE 1 +#define GL_POINTS 0x0000 +#define GL_LINES 0x0001 +#define GL_LINE_LOOP 0x0002 +#define GL_LINE_STRIP 0x0003 +#define GL_TRIANGLES 0x0004 +#define GL_TRIANGLE_STRIP 0x0005 +#define GL_TRIANGLE_FAN 0x0006 +#define GL_ZERO 0 +#define GL_ONE 1 +#define GL_SRC_COLOR 0x0300 +#define GL_ONE_MINUS_SRC_COLOR 0x0301 +#define GL_SRC_ALPHA 0x0302 +#define GL_ONE_MINUS_SRC_ALPHA 0x0303 +#define GL_DST_ALPHA 0x0304 +#define GL_ONE_MINUS_DST_ALPHA 0x0305 +#define GL_DST_COLOR 0x0306 +#define GL_ONE_MINUS_DST_COLOR 0x0307 +#define GL_SRC_ALPHA_SATURATE 0x0308 +#define GL_FUNC_ADD 0x8006 +#define GL_BLEND_EQUATION 0x8009 +#define GL_BLEND_EQUATION_RGB 0x8009 +#define GL_BLEND_EQUATION_ALPHA 0x883D +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_BLEND_COLOR 0x8005 +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 +#define GL_STREAM_DRAW 0x88E0 +#define GL_STATIC_DRAW 0x88E4 +#define GL_DYNAMIC_DRAW 0x88E8 +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_USAGE 0x8765 +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 +#define GL_FRONT 0x0404 +#define GL_BACK 0x0405 +#define GL_FRONT_AND_BACK 0x0408 +#define GL_TEXTURE_2D 0x0DE1 +#define GL_CULL_FACE 0x0B44 +#define GL_BLEND 0x0BE2 +#define GL_DITHER 0x0BD0 +#define GL_STENCIL_TEST 0x0B90 +#define GL_DEPTH_TEST 0x0B71 +#define GL_SCISSOR_TEST 0x0C11 +#define GL_POLYGON_OFFSET_FILL 0x8037 +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_COVERAGE 0x80A0 +#define GL_NO_ERROR 0 +#define GL_INVALID_ENUM 0x0500 +#define GL_INVALID_VALUE 0x0501 +#define GL_INVALID_OPERATION 0x0502 +#define GL_OUT_OF_MEMORY 0x0505 +#define GL_CW 0x0900 +#define GL_CCW 0x0901 +#define GL_LINE_WIDTH 0x0B21 +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#define GL_CULL_FACE_MODE 0x0B45 +#define GL_FRONT_FACE 0x0B46 +#define GL_DEPTH_RANGE 0x0B70 +#define GL_DEPTH_WRITEMASK 0x0B72 +#define GL_DEPTH_CLEAR_VALUE 0x0B73 +#define GL_DEPTH_FUNC 0x0B74 +#define GL_STENCIL_CLEAR_VALUE 0x0B91 +#define GL_STENCIL_FUNC 0x0B92 +#define GL_STENCIL_FAIL 0x0B94 +#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 +#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 +#define GL_STENCIL_REF 0x0B97 +#define GL_STENCIL_VALUE_MASK 0x0B93 +#define GL_STENCIL_WRITEMASK 0x0B98 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_FAIL 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 +#define GL_STENCIL_BACK_REF 0x8CA3 +#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 +#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 +#define GL_VIEWPORT 0x0BA2 +#define GL_SCISSOR_BOX 0x0C10 +#define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_WRITEMASK 0x0C23 +#define GL_UNPACK_ALIGNMENT 0x0CF5 +#define GL_PACK_ALIGNMENT 0x0D05 +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_VIEWPORT_DIMS 0x0D3A +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_RED_BITS 0x0D52 +#define GL_GREEN_BITS 0x0D53 +#define GL_BLUE_BITS 0x0D54 +#define GL_ALPHA_BITS 0x0D55 +#define GL_DEPTH_BITS 0x0D56 +#define GL_STENCIL_BITS 0x0D57 +#define GL_POLYGON_OFFSET_UNITS 0x2A00 +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#define GL_TEXTURE_BINDING_2D 0x8069 +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 +#define GL_DONT_CARE 0x1100 +#define GL_FASTEST 0x1101 +#define GL_NICEST 0x1102 +#define GL_GENERATE_MIPMAP_HINT 0x8192 +#define GL_BYTE 0x1400 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_SHORT 0x1402 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_INT 0x1404 +#define GL_UNSIGNED_INT 0x1405 +#define GL_FLOAT 0x1406 +#define GL_FIXED 0x140C +#define GL_DEPTH_COMPONENT 0x1902 +#define GL_ALPHA 0x1906 +#define GL_RGB 0x1907 +#define GL_RGBA 0x1908 +#define GL_LUMINANCE 0x1909 +#define GL_LUMINANCE_ALPHA 0x190A +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB +#define GL_MAX_VARYING_VECTORS 0x8DFC +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD +#define GL_SHADER_TYPE 0x8B4F +#define GL_DELETE_STATUS 0x8B80 +#define GL_LINK_STATUS 0x8B82 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_CURRENT_PROGRAM 0x8B8D +#define GL_NEVER 0x0200 +#define GL_LESS 0x0201 +#define GL_EQUAL 0x0202 +#define GL_LEQUAL 0x0203 +#define GL_GREATER 0x0204 +#define GL_NOTEQUAL 0x0205 +#define GL_GEQUAL 0x0206 +#define GL_ALWAYS 0x0207 +#define GL_KEEP 0x1E00 +#define GL_REPLACE 0x1E01 +#define GL_INCR 0x1E02 +#define GL_DECR 0x1E03 +#define GL_INVERT 0x150A +#define GL_INCR_WRAP 0x8507 +#define GL_DECR_WRAP 0x8508 +#define GL_VENDOR 0x1F00 +#define GL_RENDERER 0x1F01 +#define GL_VERSION 0x1F02 +#define GL_EXTENSIONS 0x1F03 +#define GL_NEAREST 0x2600 +#define GL_LINEAR 0x2601 +#define GL_NEAREST_MIPMAP_NEAREST 0x2700 +#define GL_LINEAR_MIPMAP_NEAREST 0x2701 +#define GL_NEAREST_MIPMAP_LINEAR 0x2702 +#define GL_LINEAR_MIPMAP_LINEAR 0x2703 +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MIN_FILTER 0x2801 +#define GL_TEXTURE_WRAP_S 0x2802 +#define GL_TEXTURE_WRAP_T 0x2803 +#define GL_TEXTURE 0x1702 +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_ACTIVE_TEXTURE 0x84E0 +#define GL_REPEAT 0x2901 +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_MIRRORED_REPEAT 0x8370 +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT4 0x8B5C +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_CUBE 0x8B60 +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F +#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B +#define GL_COMPILE_STATUS 0x8B81 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_SHADER_COMPILER 0x8DFA +#define GL_SHADER_BINARY_FORMATS 0x8DF8 +#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 +#define GL_LOW_FLOAT 0x8DF0 +#define GL_MEDIUM_FLOAT 0x8DF1 +#define GL_HIGH_FLOAT 0x8DF2 +#define GL_LOW_INT 0x8DF3 +#define GL_MEDIUM_INT 0x8DF4 +#define GL_HIGH_INT 0x8DF5 +#define GL_FRAMEBUFFER 0x8D40 +#define GL_RENDERBUFFER 0x8D41 +#define GL_RGBA4 0x8056 +#define GL_RGB5_A1 0x8057 +#define GL_RGB565 0x8D62 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_STENCIL_INDEX8 0x8D48 +#define GL_RENDERBUFFER_WIDTH 0x8D42 +#define GL_RENDERBUFFER_HEIGHT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 +#define GL_RENDERBUFFER_RED_SIZE 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 +#define GL_COLOR_ATTACHMENT0 0x8CE0 +#define GL_DEPTH_ATTACHMENT 0x8D00 +#define GL_STENCIL_ATTACHMENT 0x8D20 +#define GL_NONE 0 +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9 +#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD +#define GL_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_RENDERBUFFER_BINDING 0x8CA7 +#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 +#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 +typedef void (GL_APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture); +typedef void (GL_APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader); +typedef void (GL_APIENTRYP PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar *name); +typedef void (GL_APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer); +typedef void (GL_APIENTRYP PFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer); +typedef void (GL_APIENTRYP PFNGLBINDRENDERBUFFERPROC) (GLenum target, GLuint renderbuffer); +typedef void (GL_APIENTRYP PFNGLBINDTEXTUREPROC) (GLenum target, GLuint texture); +typedef void (GL_APIENTRYP PFNGLBLENDCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode); +typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha); +typedef void (GL_APIENTRYP PFNGLBLENDFUNCPROC) (GLenum sfactor, GLenum dfactor); +typedef void (GL_APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +typedef void (GL_APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const void *data, GLenum usage); +typedef void (GL_APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const void *data); +typedef GLenum (GL_APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target); +typedef void (GL_APIENTRYP PFNGLCLEARPROC) (GLbitfield mask); +typedef void (GL_APIENTRYP PFNGLCLEARCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +typedef void (GL_APIENTRYP PFNGLCLEARDEPTHFPROC) (GLfloat d); +typedef void (GL_APIENTRYP PFNGLCLEARSTENCILPROC) (GLint s); +typedef void (GL_APIENTRYP PFNGLCOLORMASKPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +typedef void (GL_APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader); +typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); +typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); +typedef void (GL_APIENTRYP PFNGLCOPYTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +typedef void (GL_APIENTRYP PFNGLCOPYTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef GLuint (GL_APIENTRYP PFNGLCREATEPROGRAMPROC) (void); +typedef GLuint (GL_APIENTRYP PFNGLCREATESHADERPROC) (GLenum type); +typedef void (GL_APIENTRYP PFNGLCULLFACEPROC) (GLenum mode); +typedef void (GL_APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers); +typedef void (GL_APIENTRYP PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint *framebuffers); +typedef void (GL_APIENTRYP PFNGLDELETEPROGRAMPROC) (GLuint program); +typedef void (GL_APIENTRYP PFNGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint *renderbuffers); +typedef void (GL_APIENTRYP PFNGLDELETESHADERPROC) (GLuint shader); +typedef void (GL_APIENTRYP PFNGLDELETETEXTURESPROC) (GLsizei n, const GLuint *textures); +typedef void (GL_APIENTRYP PFNGLDEPTHFUNCPROC) (GLenum func); +typedef void (GL_APIENTRYP PFNGLDEPTHMASKPROC) (GLboolean flag); +typedef void (GL_APIENTRYP PFNGLDEPTHRANGEFPROC) (GLfloat n, GLfloat f); +typedef void (GL_APIENTRYP PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader); +typedef void (GL_APIENTRYP PFNGLDISABLEPROC) (GLenum cap); +typedef void (GL_APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index); +typedef void (GL_APIENTRYP PFNGLDRAWARRAYSPROC) (GLenum mode, GLint first, GLsizei count); +typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices); +typedef void (GL_APIENTRYP PFNGLENABLEPROC) (GLenum cap); +typedef void (GL_APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index); +typedef void (GL_APIENTRYP PFNGLFINISHPROC) (void); +typedef void (GL_APIENTRYP PFNGLFLUSHPROC) (void); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +typedef void (GL_APIENTRYP PFNGLFRONTFACEPROC) (GLenum mode); +typedef void (GL_APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers); +typedef void (GL_APIENTRYP PFNGLGENERATEMIPMAPPROC) (GLenum target); +typedef void (GL_APIENTRYP PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint *framebuffers); +typedef void (GL_APIENTRYP PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint *renderbuffers); +typedef void (GL_APIENTRYP PFNGLGENTEXTURESPROC) (GLsizei n, GLuint *textures); +typedef void (GL_APIENTRYP PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +typedef void (GL_APIENTRYP PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +typedef void (GL_APIENTRYP PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders); +typedef GLint (GL_APIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name); +typedef void (GL_APIENTRYP PFNGLGETBOOLEANVPROC) (GLenum pname, GLboolean *data); +typedef void (GL_APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef GLenum (GL_APIENTRYP PFNGLGETERRORPROC) (void); +typedef void (GL_APIENTRYP PFNGLGETFLOATVPROC) (GLenum pname, GLfloat *data); +typedef void (GL_APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETINTEGERVPROC) (GLenum pname, GLint *data); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +typedef void (GL_APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +typedef void (GL_APIENTRYP PFNGLGETSHADERPRECISIONFORMATPROC) (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision); +typedef void (GL_APIENTRYP PFNGLGETSHADERSOURCEPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); +typedef const GLubyte *(GL_APIENTRYP PFNGLGETSTRINGPROC) (GLenum name); +typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); +typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat *params); +typedef void (GL_APIENTRYP PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint *params); +typedef GLint (GL_APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name); +typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat *params); +typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, void **pointer); +typedef void (GL_APIENTRYP PFNGLHINTPROC) (GLenum target, GLenum mode); +typedef GLboolean (GL_APIENTRYP PFNGLISBUFFERPROC) (GLuint buffer); +typedef GLboolean (GL_APIENTRYP PFNGLISENABLEDPROC) (GLenum cap); +typedef GLboolean (GL_APIENTRYP PFNGLISFRAMEBUFFERPROC) (GLuint framebuffer); +typedef GLboolean (GL_APIENTRYP PFNGLISPROGRAMPROC) (GLuint program); +typedef GLboolean (GL_APIENTRYP PFNGLISRENDERBUFFERPROC) (GLuint renderbuffer); +typedef GLboolean (GL_APIENTRYP PFNGLISSHADERPROC) (GLuint shader); +typedef GLboolean (GL_APIENTRYP PFNGLISTEXTUREPROC) (GLuint texture); +typedef void (GL_APIENTRYP PFNGLLINEWIDTHPROC) (GLfloat width); +typedef void (GL_APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program); +typedef void (GL_APIENTRYP PFNGLPIXELSTOREIPROC) (GLenum pname, GLint param); +typedef void (GL_APIENTRYP PFNGLPOLYGONOFFSETPROC) (GLfloat factor, GLfloat units); +typedef void (GL_APIENTRYP PFNGLREADPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels); +typedef void (GL_APIENTRYP PFNGLRELEASESHADERCOMPILERPROC) (void); +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLfloat value, GLboolean invert); +typedef void (GL_APIENTRYP PFNGLSCISSORPROC) (GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint *shaders, GLenum binaryFormat, const void *binary, GLsizei length); +typedef void (GL_APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length); +typedef void (GL_APIENTRYP PFNGLSTENCILFUNCPROC) (GLenum func, GLint ref, GLuint mask); +typedef void (GL_APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC) (GLenum face, GLenum func, GLint ref, GLuint mask); +typedef void (GL_APIENTRYP PFNGLSTENCILMASKPROC) (GLuint mask); +typedef void (GL_APIENTRYP PFNGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask); +typedef void (GL_APIENTRYP PFNGLSTENCILOPPROC) (GLenum fail, GLenum zfail, GLenum zpass); +typedef void (GL_APIENTRYP PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +typedef void (GL_APIENTRYP PFNGLTEXIMAGE2DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (GL_APIENTRYP PFNGLTEXPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat param); +typedef void (GL_APIENTRYP PFNGLTEXPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); +typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, GLint param); +typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +typedef void (GL_APIENTRYP PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0); +typedef void (GL_APIENTRYP PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint v0); +typedef void (GL_APIENTRYP PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1); +typedef void (GL_APIENTRYP PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1); +typedef void (GL_APIENTRYP PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (GL_APIENTRYP PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2); +typedef void (GL_APIENTRYP PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (GL_APIENTRYP PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (GL_APIENTRYP PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program); +typedef void (GL_APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat *v); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat *v); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat *v); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat *v); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); +typedef void (GL_APIENTRYP PFNGLVIEWPORTPROC) (GLint x, GLint y, GLsizei width, GLsizei height); +#if GL_GLES_PROTOTYPES +GL_APICALL void GL_APIENTRY glActiveTexture (GLenum texture); +GL_APICALL void GL_APIENTRY glAttachShader (GLuint program, GLuint shader); +GL_APICALL void GL_APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar *name); +GL_APICALL void GL_APIENTRY glBindBuffer (GLenum target, GLuint buffer); +GL_APICALL void GL_APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer); +GL_APICALL void GL_APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer); +GL_APICALL void GL_APIENTRY glBindTexture (GLenum target, GLuint texture); +GL_APICALL void GL_APIENTRY glBlendColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GL_APICALL void GL_APIENTRY glBlendEquation (GLenum mode); +GL_APICALL void GL_APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha); +GL_APICALL void GL_APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor); +GL_APICALL void GL_APIENTRY glBlendFuncSeparate (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); +GL_APICALL void GL_APIENTRY glBufferData (GLenum target, GLsizeiptr size, const void *data, GLenum usage); +GL_APICALL void GL_APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const void *data); +GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus (GLenum target); +GL_APICALL void GL_APIENTRY glClear (GLbitfield mask); +GL_APICALL void GL_APIENTRY glClearColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +GL_APICALL void GL_APIENTRY glClearDepthf (GLfloat d); +GL_APICALL void GL_APIENTRY glClearStencil (GLint s); +GL_APICALL void GL_APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +GL_APICALL void GL_APIENTRY glCompileShader (GLuint shader); +GL_APICALL void GL_APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); +GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); +GL_APICALL void GL_APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +GL_APICALL void GL_APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL GLuint GL_APIENTRY glCreateProgram (void); +GL_APICALL GLuint GL_APIENTRY glCreateShader (GLenum type); +GL_APICALL void GL_APIENTRY glCullFace (GLenum mode); +GL_APICALL void GL_APIENTRY glDeleteBuffers (GLsizei n, const GLuint *buffers); +GL_APICALL void GL_APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint *framebuffers); +GL_APICALL void GL_APIENTRY glDeleteProgram (GLuint program); +GL_APICALL void GL_APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint *renderbuffers); +GL_APICALL void GL_APIENTRY glDeleteShader (GLuint shader); +GL_APICALL void GL_APIENTRY glDeleteTextures (GLsizei n, const GLuint *textures); +GL_APICALL void GL_APIENTRY glDepthFunc (GLenum func); +GL_APICALL void GL_APIENTRY glDepthMask (GLboolean flag); +GL_APICALL void GL_APIENTRY glDepthRangef (GLfloat n, GLfloat f); +GL_APICALL void GL_APIENTRY glDetachShader (GLuint program, GLuint shader); +GL_APICALL void GL_APIENTRY glDisable (GLenum cap); +GL_APICALL void GL_APIENTRY glDisableVertexAttribArray (GLuint index); +GL_APICALL void GL_APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count); +GL_APICALL void GL_APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const void *indices); +GL_APICALL void GL_APIENTRY glEnable (GLenum cap); +GL_APICALL void GL_APIENTRY glEnableVertexAttribArray (GLuint index); +GL_APICALL void GL_APIENTRY glFinish (void); +GL_APICALL void GL_APIENTRY glFlush (void); +GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +GL_APICALL void GL_APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GL_APICALL void GL_APIENTRY glFrontFace (GLenum mode); +GL_APICALL void GL_APIENTRY glGenBuffers (GLsizei n, GLuint *buffers); +GL_APICALL void GL_APIENTRY glGenerateMipmap (GLenum target); +GL_APICALL void GL_APIENTRY glGenFramebuffers (GLsizei n, GLuint *framebuffers); +GL_APICALL void GL_APIENTRY glGenRenderbuffers (GLsizei n, GLuint *renderbuffers); +GL_APICALL void GL_APIENTRY glGenTextures (GLsizei n, GLuint *textures); +GL_APICALL void GL_APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +GL_APICALL void GL_APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); +GL_APICALL void GL_APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders); +GL_APICALL GLint GL_APIENTRY glGetAttribLocation (GLuint program, const GLchar *name); +GL_APICALL void GL_APIENTRY glGetBooleanv (GLenum pname, GLboolean *data); +GL_APICALL void GL_APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params); +GL_APICALL GLenum GL_APIENTRY glGetError (void); +GL_APICALL void GL_APIENTRY glGetFloatv (GLenum pname, GLfloat *data); +GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetIntegerv (GLenum pname, GLint *data); +GL_APICALL void GL_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision); +GL_APICALL void GL_APIENTRY glGetShaderSource (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); +GL_APICALL const GLubyte *GL_APIENTRY glGetString (GLenum name); +GL_APICALL void GL_APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat *params); +GL_APICALL void GL_APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat *params); +GL_APICALL void GL_APIENTRY glGetUniformiv (GLuint program, GLint location, GLint *params); +GL_APICALL GLint GL_APIENTRY glGetUniformLocation (GLuint program, const GLchar *name); +GL_APICALL void GL_APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat *params); +GL_APICALL void GL_APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, void **pointer); +GL_APICALL void GL_APIENTRY glHint (GLenum target, GLenum mode); +GL_APICALL GLboolean GL_APIENTRY glIsBuffer (GLuint buffer); +GL_APICALL GLboolean GL_APIENTRY glIsEnabled (GLenum cap); +GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer (GLuint framebuffer); +GL_APICALL GLboolean GL_APIENTRY glIsProgram (GLuint program); +GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer (GLuint renderbuffer); +GL_APICALL GLboolean GL_APIENTRY glIsShader (GLuint shader); +GL_APICALL GLboolean GL_APIENTRY glIsTexture (GLuint texture); +GL_APICALL void GL_APIENTRY glLineWidth (GLfloat width); +GL_APICALL void GL_APIENTRY glLinkProgram (GLuint program); +GL_APICALL void GL_APIENTRY glPixelStorei (GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glPolygonOffset (GLfloat factor, GLfloat units); +GL_APICALL void GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels); +GL_APICALL void GL_APIENTRY glReleaseShaderCompiler (void); +GL_APICALL void GL_APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glSampleCoverage (GLfloat value, GLboolean invert); +GL_APICALL void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glShaderBinary (GLsizei count, const GLuint *shaders, GLenum binaryFormat, const void *binary, GLsizei length); +GL_APICALL void GL_APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length); +GL_APICALL void GL_APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilMask (GLuint mask); +GL_APICALL void GL_APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass); +GL_APICALL void GL_APIENTRY glStencilOpSeparate (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); +GL_APICALL void GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); +GL_APICALL void GL_APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param); +GL_APICALL void GL_APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat *params); +GL_APICALL void GL_APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint *params); +GL_APICALL void GL_APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); +GL_APICALL void GL_APIENTRY glUniform1f (GLint location, GLfloat v0); +GL_APICALL void GL_APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniform1i (GLint location, GLint v0); +GL_APICALL void GL_APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glUniform2f (GLint location, GLfloat v0, GLfloat v1); +GL_APICALL void GL_APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniform2i (GLint location, GLint v0, GLint v1); +GL_APICALL void GL_APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glUniform3f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +GL_APICALL void GL_APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniform3i (GLint location, GLint v0, GLint v1, GLint v2); +GL_APICALL void GL_APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glUniform4f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +GL_APICALL void GL_APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniform4i (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +GL_APICALL void GL_APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUseProgram (GLuint program); +GL_APICALL void GL_APIENTRY glValidateProgram (GLuint program); +GL_APICALL void GL_APIENTRY glVertexAttrib1f (GLuint index, GLfloat x); +GL_APICALL void GL_APIENTRY glVertexAttrib1fv (GLuint index, const GLfloat *v); +GL_APICALL void GL_APIENTRY glVertexAttrib2f (GLuint index, GLfloat x, GLfloat y); +GL_APICALL void GL_APIENTRY glVertexAttrib2fv (GLuint index, const GLfloat *v); +GL_APICALL void GL_APIENTRY glVertexAttrib3f (GLuint index, GLfloat x, GLfloat y, GLfloat z); +GL_APICALL void GL_APIENTRY glVertexAttrib3fv (GLuint index, const GLfloat *v); +GL_APICALL void GL_APIENTRY glVertexAttrib4f (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GL_APICALL void GL_APIENTRY glVertexAttrib4fv (GLuint index, const GLfloat *v); +GL_APICALL void GL_APIENTRY glVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); +GL_APICALL void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height); +#endif +#endif /* GL_ES_VERSION_2_0 */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/SDL2-2.30.5/include/SDL_opengles2_gl2ext.h b/SDL2-2.30.5/include/SDL_opengles2_gl2ext.h new file mode 100644 index 0000000..9448ce0 --- /dev/null +++ b/SDL2-2.30.5/include/SDL_opengles2_gl2ext.h @@ -0,0 +1,4033 @@ +#ifndef __gles2_gl2ext_h_ +#define __gles2_gl2ext_h_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Copyright 2013-2020 The Khronos Group Inc. +** SPDX-License-Identifier: MIT +** +** This header is generated from the Khronos OpenGL / OpenGL ES XML +** API Registry. The current version of the Registry, generator scripts +** used to make the header, and the header can be found at +** https://github.com/KhronosGroup/OpenGL-Registry +*/ + +#ifndef GL_APIENTRYP +#define GL_APIENTRYP GL_APIENTRY* +#endif + +/* Generated on date 20220530 */ + +/* Generated C header for: + * API: gles2 + * Profile: common + * Versions considered: 2\.[0-9] + * Versions emitted: _nomatch_^ + * Default extensions included: gles2 + * Additional extensions included: _nomatch_^ + * Extensions removed: _nomatch_^ + */ + +#ifndef GL_KHR_blend_equation_advanced +#define GL_KHR_blend_equation_advanced 1 +#define GL_MULTIPLY_KHR 0x9294 +#define GL_SCREEN_KHR 0x9295 +#define GL_OVERLAY_KHR 0x9296 +#define GL_DARKEN_KHR 0x9297 +#define GL_LIGHTEN_KHR 0x9298 +#define GL_COLORDODGE_KHR 0x9299 +#define GL_COLORBURN_KHR 0x929A +#define GL_HARDLIGHT_KHR 0x929B +#define GL_SOFTLIGHT_KHR 0x929C +#define GL_DIFFERENCE_KHR 0x929E +#define GL_EXCLUSION_KHR 0x92A0 +#define GL_HSL_HUE_KHR 0x92AD +#define GL_HSL_SATURATION_KHR 0x92AE +#define GL_HSL_COLOR_KHR 0x92AF +#define GL_HSL_LUMINOSITY_KHR 0x92B0 +typedef void (GL_APIENTRYP PFNGLBLENDBARRIERKHRPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glBlendBarrierKHR (void); +#endif +#endif /* GL_KHR_blend_equation_advanced */ + +#ifndef GL_KHR_blend_equation_advanced_coherent +#define GL_KHR_blend_equation_advanced_coherent 1 +#define GL_BLEND_ADVANCED_COHERENT_KHR 0x9285 +#endif /* GL_KHR_blend_equation_advanced_coherent */ + +#ifndef GL_KHR_context_flush_control +#define GL_KHR_context_flush_control 1 +#define GL_CONTEXT_RELEASE_BEHAVIOR_KHR 0x82FB +#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR 0x82FC +#endif /* GL_KHR_context_flush_control */ + +#ifndef GL_KHR_debug +#define GL_KHR_debug 1 +typedef void (GL_APIENTRY *GLDEBUGPROCKHR)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); +#define GL_SAMPLER 0x82E6 +#define GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR 0x8242 +#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_KHR 0x8243 +#define GL_DEBUG_CALLBACK_FUNCTION_KHR 0x8244 +#define GL_DEBUG_CALLBACK_USER_PARAM_KHR 0x8245 +#define GL_DEBUG_SOURCE_API_KHR 0x8246 +#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_KHR 0x8247 +#define GL_DEBUG_SOURCE_SHADER_COMPILER_KHR 0x8248 +#define GL_DEBUG_SOURCE_THIRD_PARTY_KHR 0x8249 +#define GL_DEBUG_SOURCE_APPLICATION_KHR 0x824A +#define GL_DEBUG_SOURCE_OTHER_KHR 0x824B +#define GL_DEBUG_TYPE_ERROR_KHR 0x824C +#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_KHR 0x824D +#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_KHR 0x824E +#define GL_DEBUG_TYPE_PORTABILITY_KHR 0x824F +#define GL_DEBUG_TYPE_PERFORMANCE_KHR 0x8250 +#define GL_DEBUG_TYPE_OTHER_KHR 0x8251 +#define GL_DEBUG_TYPE_MARKER_KHR 0x8268 +#define GL_DEBUG_TYPE_PUSH_GROUP_KHR 0x8269 +#define GL_DEBUG_TYPE_POP_GROUP_KHR 0x826A +#define GL_DEBUG_SEVERITY_NOTIFICATION_KHR 0x826B +#define GL_MAX_DEBUG_GROUP_STACK_DEPTH_KHR 0x826C +#define GL_DEBUG_GROUP_STACK_DEPTH_KHR 0x826D +#define GL_BUFFER_KHR 0x82E0 +#define GL_SHADER_KHR 0x82E1 +#define GL_PROGRAM_KHR 0x82E2 +#define GL_VERTEX_ARRAY_KHR 0x8074 +#define GL_QUERY_KHR 0x82E3 +#define GL_PROGRAM_PIPELINE_KHR 0x82E4 +#define GL_SAMPLER_KHR 0x82E6 +#define GL_MAX_LABEL_LENGTH_KHR 0x82E8 +#define GL_MAX_DEBUG_MESSAGE_LENGTH_KHR 0x9143 +#define GL_MAX_DEBUG_LOGGED_MESSAGES_KHR 0x9144 +#define GL_DEBUG_LOGGED_MESSAGES_KHR 0x9145 +#define GL_DEBUG_SEVERITY_HIGH_KHR 0x9146 +#define GL_DEBUG_SEVERITY_MEDIUM_KHR 0x9147 +#define GL_DEBUG_SEVERITY_LOW_KHR 0x9148 +#define GL_DEBUG_OUTPUT_KHR 0x92E0 +#define GL_CONTEXT_FLAG_DEBUG_BIT_KHR 0x00000002 +#define GL_STACK_OVERFLOW_KHR 0x0503 +#define GL_STACK_UNDERFLOW_KHR 0x0504 +typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGECONTROLKHRPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); +typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGEINSERTKHRPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); +typedef void (GL_APIENTRYP PFNGLDEBUGMESSAGECALLBACKKHRPROC) (GLDEBUGPROCKHR callback, const void *userParam); +typedef GLuint (GL_APIENTRYP PFNGLGETDEBUGMESSAGELOGKHRPROC) (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); +typedef void (GL_APIENTRYP PFNGLPUSHDEBUGGROUPKHRPROC) (GLenum source, GLuint id, GLsizei length, const GLchar *message); +typedef void (GL_APIENTRYP PFNGLPOPDEBUGGROUPKHRPROC) (void); +typedef void (GL_APIENTRYP PFNGLOBJECTLABELKHRPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar *label); +typedef void (GL_APIENTRYP PFNGLGETOBJECTLABELKHRPROC) (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label); +typedef void (GL_APIENTRYP PFNGLOBJECTPTRLABELKHRPROC) (const void *ptr, GLsizei length, const GLchar *label); +typedef void (GL_APIENTRYP PFNGLGETOBJECTPTRLABELKHRPROC) (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); +typedef void (GL_APIENTRYP PFNGLGETPOINTERVKHRPROC) (GLenum pname, void **params); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDebugMessageControlKHR (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); +GL_APICALL void GL_APIENTRY glDebugMessageInsertKHR (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); +GL_APICALL void GL_APIENTRY glDebugMessageCallbackKHR (GLDEBUGPROCKHR callback, const void *userParam); +GL_APICALL GLuint GL_APIENTRY glGetDebugMessageLogKHR (GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); +GL_APICALL void GL_APIENTRY glPushDebugGroupKHR (GLenum source, GLuint id, GLsizei length, const GLchar *message); +GL_APICALL void GL_APIENTRY glPopDebugGroupKHR (void); +GL_APICALL void GL_APIENTRY glObjectLabelKHR (GLenum identifier, GLuint name, GLsizei length, const GLchar *label); +GL_APICALL void GL_APIENTRY glGetObjectLabelKHR (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label); +GL_APICALL void GL_APIENTRY glObjectPtrLabelKHR (const void *ptr, GLsizei length, const GLchar *label); +GL_APICALL void GL_APIENTRY glGetObjectPtrLabelKHR (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); +GL_APICALL void GL_APIENTRY glGetPointervKHR (GLenum pname, void **params); +#endif +#endif /* GL_KHR_debug */ + +#ifndef GL_KHR_no_error +#define GL_KHR_no_error 1 +#define GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR 0x00000008 +#endif /* GL_KHR_no_error */ + +#ifndef GL_KHR_parallel_shader_compile +#define GL_KHR_parallel_shader_compile 1 +#define GL_MAX_SHADER_COMPILER_THREADS_KHR 0x91B0 +#define GL_COMPLETION_STATUS_KHR 0x91B1 +typedef void (GL_APIENTRYP PFNGLMAXSHADERCOMPILERTHREADSKHRPROC) (GLuint count); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glMaxShaderCompilerThreadsKHR (GLuint count); +#endif +#endif /* GL_KHR_parallel_shader_compile */ + +#ifndef GL_KHR_robust_buffer_access_behavior +#define GL_KHR_robust_buffer_access_behavior 1 +#endif /* GL_KHR_robust_buffer_access_behavior */ + +#ifndef GL_KHR_robustness +#define GL_KHR_robustness 1 +#define GL_CONTEXT_ROBUST_ACCESS_KHR 0x90F3 +#define GL_LOSE_CONTEXT_ON_RESET_KHR 0x8252 +#define GL_GUILTY_CONTEXT_RESET_KHR 0x8253 +#define GL_INNOCENT_CONTEXT_RESET_KHR 0x8254 +#define GL_UNKNOWN_CONTEXT_RESET_KHR 0x8255 +#define GL_RESET_NOTIFICATION_STRATEGY_KHR 0x8256 +#define GL_NO_RESET_NOTIFICATION_KHR 0x8261 +#define GL_CONTEXT_LOST_KHR 0x0507 +typedef GLenum (GL_APIENTRYP PFNGLGETGRAPHICSRESETSTATUSKHRPROC) (void); +typedef void (GL_APIENTRYP PFNGLREADNPIXELSKHRPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); +typedef void (GL_APIENTRYP PFNGLGETNUNIFORMFVKHRPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); +typedef void (GL_APIENTRYP PFNGLGETNUNIFORMIVKHRPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETNUNIFORMUIVKHRPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint *params); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL GLenum GL_APIENTRY glGetGraphicsResetStatusKHR (void); +GL_APICALL void GL_APIENTRY glReadnPixelsKHR (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); +GL_APICALL void GL_APIENTRY glGetnUniformfvKHR (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); +GL_APICALL void GL_APIENTRY glGetnUniformivKHR (GLuint program, GLint location, GLsizei bufSize, GLint *params); +GL_APICALL void GL_APIENTRY glGetnUniformuivKHR (GLuint program, GLint location, GLsizei bufSize, GLuint *params); +#endif +#endif /* GL_KHR_robustness */ + +#ifndef GL_KHR_shader_subgroup +#define GL_KHR_shader_subgroup 1 +#define GL_SUBGROUP_SIZE_KHR 0x9532 +#define GL_SUBGROUP_SUPPORTED_STAGES_KHR 0x9533 +#define GL_SUBGROUP_SUPPORTED_FEATURES_KHR 0x9534 +#define GL_SUBGROUP_QUAD_ALL_STAGES_KHR 0x9535 +#define GL_SUBGROUP_FEATURE_BASIC_BIT_KHR 0x00000001 +#define GL_SUBGROUP_FEATURE_VOTE_BIT_KHR 0x00000002 +#define GL_SUBGROUP_FEATURE_ARITHMETIC_BIT_KHR 0x00000004 +#define GL_SUBGROUP_FEATURE_BALLOT_BIT_KHR 0x00000008 +#define GL_SUBGROUP_FEATURE_SHUFFLE_BIT_KHR 0x00000010 +#define GL_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT_KHR 0x00000020 +#define GL_SUBGROUP_FEATURE_CLUSTERED_BIT_KHR 0x00000040 +#define GL_SUBGROUP_FEATURE_QUAD_BIT_KHR 0x00000080 +#endif /* GL_KHR_shader_subgroup */ + +#ifndef GL_KHR_texture_compression_astc_hdr +#define GL_KHR_texture_compression_astc_hdr 1 +#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0 +#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1 +#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2 +#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3 +#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4 +#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5 +#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6 +#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7 +#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8 +#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9 +#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA +#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB +#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC +#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD +#endif /* GL_KHR_texture_compression_astc_hdr */ + +#ifndef GL_KHR_texture_compression_astc_ldr +#define GL_KHR_texture_compression_astc_ldr 1 +#endif /* GL_KHR_texture_compression_astc_ldr */ + +#ifndef GL_KHR_texture_compression_astc_sliced_3d +#define GL_KHR_texture_compression_astc_sliced_3d 1 +#endif /* GL_KHR_texture_compression_astc_sliced_3d */ + +#ifndef GL_OES_EGL_image +#define GL_OES_EGL_image 1 +typedef void *GLeglImageOES; +typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, GLeglImageOES image); +typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLeglImageOES image); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glEGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image); +GL_APICALL void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES (GLenum target, GLeglImageOES image); +#endif +#endif /* GL_OES_EGL_image */ + +#ifndef GL_OES_EGL_image_external +#define GL_OES_EGL_image_external 1 +#define GL_TEXTURE_EXTERNAL_OES 0x8D65 +#define GL_TEXTURE_BINDING_EXTERNAL_OES 0x8D67 +#define GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES 0x8D68 +#define GL_SAMPLER_EXTERNAL_OES 0x8D66 +#endif /* GL_OES_EGL_image_external */ + +#ifndef GL_OES_EGL_image_external_essl3 +#define GL_OES_EGL_image_external_essl3 1 +#endif /* GL_OES_EGL_image_external_essl3 */ + +#ifndef GL_OES_compressed_ETC1_RGB8_sub_texture +#define GL_OES_compressed_ETC1_RGB8_sub_texture 1 +#endif /* GL_OES_compressed_ETC1_RGB8_sub_texture */ + +#ifndef GL_OES_compressed_ETC1_RGB8_texture +#define GL_OES_compressed_ETC1_RGB8_texture 1 +#define GL_ETC1_RGB8_OES 0x8D64 +#endif /* GL_OES_compressed_ETC1_RGB8_texture */ + +#ifndef GL_OES_compressed_paletted_texture +#define GL_OES_compressed_paletted_texture 1 +#define GL_PALETTE4_RGB8_OES 0x8B90 +#define GL_PALETTE4_RGBA8_OES 0x8B91 +#define GL_PALETTE4_R5_G6_B5_OES 0x8B92 +#define GL_PALETTE4_RGBA4_OES 0x8B93 +#define GL_PALETTE4_RGB5_A1_OES 0x8B94 +#define GL_PALETTE8_RGB8_OES 0x8B95 +#define GL_PALETTE8_RGBA8_OES 0x8B96 +#define GL_PALETTE8_R5_G6_B5_OES 0x8B97 +#define GL_PALETTE8_RGBA4_OES 0x8B98 +#define GL_PALETTE8_RGB5_A1_OES 0x8B99 +#endif /* GL_OES_compressed_paletted_texture */ + +#ifndef GL_OES_copy_image +#define GL_OES_copy_image 1 +typedef void (GL_APIENTRYP PFNGLCOPYIMAGESUBDATAOESPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glCopyImageSubDataOES (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); +#endif +#endif /* GL_OES_copy_image */ + +#ifndef GL_OES_depth24 +#define GL_OES_depth24 1 +#define GL_DEPTH_COMPONENT24_OES 0x81A6 +#endif /* GL_OES_depth24 */ + +#ifndef GL_OES_depth32 +#define GL_OES_depth32 1 +#define GL_DEPTH_COMPONENT32_OES 0x81A7 +#endif /* GL_OES_depth32 */ + +#ifndef GL_OES_depth_texture +#define GL_OES_depth_texture 1 +#endif /* GL_OES_depth_texture */ + +#ifndef GL_OES_draw_buffers_indexed +#define GL_OES_draw_buffers_indexed 1 +#define GL_MIN 0x8007 +#define GL_MAX 0x8008 +typedef void (GL_APIENTRYP PFNGLENABLEIOESPROC) (GLenum target, GLuint index); +typedef void (GL_APIENTRYP PFNGLDISABLEIOESPROC) (GLenum target, GLuint index); +typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONIOESPROC) (GLuint buf, GLenum mode); +typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONSEPARATEIOESPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +typedef void (GL_APIENTRYP PFNGLBLENDFUNCIOESPROC) (GLuint buf, GLenum src, GLenum dst); +typedef void (GL_APIENTRYP PFNGLBLENDFUNCSEPARATEIOESPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +typedef void (GL_APIENTRYP PFNGLCOLORMASKIOESPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +typedef GLboolean (GL_APIENTRYP PFNGLISENABLEDIOESPROC) (GLenum target, GLuint index); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glEnableiOES (GLenum target, GLuint index); +GL_APICALL void GL_APIENTRY glDisableiOES (GLenum target, GLuint index); +GL_APICALL void GL_APIENTRY glBlendEquationiOES (GLuint buf, GLenum mode); +GL_APICALL void GL_APIENTRY glBlendEquationSeparateiOES (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +GL_APICALL void GL_APIENTRY glBlendFunciOES (GLuint buf, GLenum src, GLenum dst); +GL_APICALL void GL_APIENTRY glBlendFuncSeparateiOES (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +GL_APICALL void GL_APIENTRY glColorMaskiOES (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +GL_APICALL GLboolean GL_APIENTRY glIsEnablediOES (GLenum target, GLuint index); +#endif +#endif /* GL_OES_draw_buffers_indexed */ + +#ifndef GL_OES_draw_elements_base_vertex +#define GL_OES_draw_elements_base_vertex 1 +typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXOESPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex); +typedef void (GL_APIENTRYP PFNGLDRAWRANGEELEMENTSBASEVERTEXOESPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex); +typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXOESPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex); +typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSBASEVERTEXEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount, const GLint *basevertex); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDrawElementsBaseVertexOES (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex); +GL_APICALL void GL_APIENTRY glDrawRangeElementsBaseVertexOES (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex); +GL_APICALL void GL_APIENTRY glDrawElementsInstancedBaseVertexOES (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex); +GL_APICALL void GL_APIENTRY glMultiDrawElementsBaseVertexEXT (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount, const GLint *basevertex); +#endif +#endif /* GL_OES_draw_elements_base_vertex */ + +#ifndef GL_OES_element_index_uint +#define GL_OES_element_index_uint 1 +#endif /* GL_OES_element_index_uint */ + +#ifndef GL_OES_fbo_render_mipmap +#define GL_OES_fbo_render_mipmap 1 +#endif /* GL_OES_fbo_render_mipmap */ + +#ifndef GL_OES_fragment_precision_high +#define GL_OES_fragment_precision_high 1 +#endif /* GL_OES_fragment_precision_high */ + +#ifndef GL_OES_geometry_point_size +#define GL_OES_geometry_point_size 1 +#endif /* GL_OES_geometry_point_size */ + +#ifndef GL_OES_geometry_shader +#define GL_OES_geometry_shader 1 +#define GL_GEOMETRY_SHADER_OES 0x8DD9 +#define GL_GEOMETRY_SHADER_BIT_OES 0x00000004 +#define GL_GEOMETRY_LINKED_VERTICES_OUT_OES 0x8916 +#define GL_GEOMETRY_LINKED_INPUT_TYPE_OES 0x8917 +#define GL_GEOMETRY_LINKED_OUTPUT_TYPE_OES 0x8918 +#define GL_GEOMETRY_SHADER_INVOCATIONS_OES 0x887F +#define GL_LAYER_PROVOKING_VERTEX_OES 0x825E +#define GL_LINES_ADJACENCY_OES 0x000A +#define GL_LINE_STRIP_ADJACENCY_OES 0x000B +#define GL_TRIANGLES_ADJACENCY_OES 0x000C +#define GL_TRIANGLE_STRIP_ADJACENCY_OES 0x000D +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_OES 0x8DDF +#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS_OES 0x8A2C +#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_OES 0x8A32 +#define GL_MAX_GEOMETRY_INPUT_COMPONENTS_OES 0x9123 +#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_OES 0x9124 +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_OES 0x8DE0 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_OES 0x8DE1 +#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS_OES 0x8E5A +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_OES 0x8C29 +#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_OES 0x92CF +#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS_OES 0x92D5 +#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS_OES 0x90CD +#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_OES 0x90D7 +#define GL_FIRST_VERTEX_CONVENTION_OES 0x8E4D +#define GL_LAST_VERTEX_CONVENTION_OES 0x8E4E +#define GL_UNDEFINED_VERTEX_OES 0x8260 +#define GL_PRIMITIVES_GENERATED_OES 0x8C87 +#define GL_FRAMEBUFFER_DEFAULT_LAYERS_OES 0x9312 +#define GL_MAX_FRAMEBUFFER_LAYERS_OES 0x9317 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_OES 0x8DA8 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_OES 0x8DA7 +#define GL_REFERENCED_BY_GEOMETRY_SHADER_OES 0x9309 +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTUREOESPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glFramebufferTextureOES (GLenum target, GLenum attachment, GLuint texture, GLint level); +#endif +#endif /* GL_OES_geometry_shader */ + +#ifndef GL_OES_get_program_binary +#define GL_OES_get_program_binary 1 +#define GL_PROGRAM_BINARY_LENGTH_OES 0x8741 +#define GL_NUM_PROGRAM_BINARY_FORMATS_OES 0x87FE +#define GL_PROGRAM_BINARY_FORMATS_OES 0x87FF +typedef void (GL_APIENTRYP PFNGLGETPROGRAMBINARYOESPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary); +typedef void (GL_APIENTRYP PFNGLPROGRAMBINARYOESPROC) (GLuint program, GLenum binaryFormat, const void *binary, GLint length); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGetProgramBinaryOES (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary); +GL_APICALL void GL_APIENTRY glProgramBinaryOES (GLuint program, GLenum binaryFormat, const void *binary, GLint length); +#endif +#endif /* GL_OES_get_program_binary */ + +#ifndef GL_OES_gpu_shader5 +#define GL_OES_gpu_shader5 1 +#endif /* GL_OES_gpu_shader5 */ + +#ifndef GL_OES_mapbuffer +#define GL_OES_mapbuffer 1 +#define GL_WRITE_ONLY_OES 0x88B9 +#define GL_BUFFER_ACCESS_OES 0x88BB +#define GL_BUFFER_MAPPED_OES 0x88BC +#define GL_BUFFER_MAP_POINTER_OES 0x88BD +typedef void *(GL_APIENTRYP PFNGLMAPBUFFEROESPROC) (GLenum target, GLenum access); +typedef GLboolean (GL_APIENTRYP PFNGLUNMAPBUFFEROESPROC) (GLenum target); +typedef void (GL_APIENTRYP PFNGLGETBUFFERPOINTERVOESPROC) (GLenum target, GLenum pname, void **params); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void *GL_APIENTRY glMapBufferOES (GLenum target, GLenum access); +GL_APICALL GLboolean GL_APIENTRY glUnmapBufferOES (GLenum target); +GL_APICALL void GL_APIENTRY glGetBufferPointervOES (GLenum target, GLenum pname, void **params); +#endif +#endif /* GL_OES_mapbuffer */ + +#ifndef GL_OES_packed_depth_stencil +#define GL_OES_packed_depth_stencil 1 +#define GL_DEPTH_STENCIL_OES 0x84F9 +#define GL_UNSIGNED_INT_24_8_OES 0x84FA +#define GL_DEPTH24_STENCIL8_OES 0x88F0 +#endif /* GL_OES_packed_depth_stencil */ + +#ifndef GL_OES_primitive_bounding_box +#define GL_OES_primitive_bounding_box 1 +#define GL_PRIMITIVE_BOUNDING_BOX_OES 0x92BE +typedef void (GL_APIENTRYP PFNGLPRIMITIVEBOUNDINGBOXOESPROC) (GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glPrimitiveBoundingBoxOES (GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW); +#endif +#endif /* GL_OES_primitive_bounding_box */ + +#ifndef GL_OES_required_internalformat +#define GL_OES_required_internalformat 1 +#define GL_ALPHA8_OES 0x803C +#define GL_DEPTH_COMPONENT16_OES 0x81A5 +#define GL_LUMINANCE4_ALPHA4_OES 0x8043 +#define GL_LUMINANCE8_ALPHA8_OES 0x8045 +#define GL_LUMINANCE8_OES 0x8040 +#define GL_RGBA4_OES 0x8056 +#define GL_RGB5_A1_OES 0x8057 +#define GL_RGB565_OES 0x8D62 +#define GL_RGB8_OES 0x8051 +#define GL_RGBA8_OES 0x8058 +#define GL_RGB10_EXT 0x8052 +#define GL_RGB10_A2_EXT 0x8059 +#endif /* GL_OES_required_internalformat */ + +#ifndef GL_OES_rgb8_rgba8 +#define GL_OES_rgb8_rgba8 1 +#endif /* GL_OES_rgb8_rgba8 */ + +#ifndef GL_OES_sample_shading +#define GL_OES_sample_shading 1 +#define GL_SAMPLE_SHADING_OES 0x8C36 +#define GL_MIN_SAMPLE_SHADING_VALUE_OES 0x8C37 +typedef void (GL_APIENTRYP PFNGLMINSAMPLESHADINGOESPROC) (GLfloat value); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glMinSampleShadingOES (GLfloat value); +#endif +#endif /* GL_OES_sample_shading */ + +#ifndef GL_OES_sample_variables +#define GL_OES_sample_variables 1 +#endif /* GL_OES_sample_variables */ + +#ifndef GL_OES_shader_image_atomic +#define GL_OES_shader_image_atomic 1 +#endif /* GL_OES_shader_image_atomic */ + +#ifndef GL_OES_shader_io_blocks +#define GL_OES_shader_io_blocks 1 +#endif /* GL_OES_shader_io_blocks */ + +#ifndef GL_OES_shader_multisample_interpolation +#define GL_OES_shader_multisample_interpolation 1 +#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_OES 0x8E5B +#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_OES 0x8E5C +#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS_OES 0x8E5D +#endif /* GL_OES_shader_multisample_interpolation */ + +#ifndef GL_OES_standard_derivatives +#define GL_OES_standard_derivatives 1 +#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES 0x8B8B +#endif /* GL_OES_standard_derivatives */ + +#ifndef GL_OES_stencil1 +#define GL_OES_stencil1 1 +#define GL_STENCIL_INDEX1_OES 0x8D46 +#endif /* GL_OES_stencil1 */ + +#ifndef GL_OES_stencil4 +#define GL_OES_stencil4 1 +#define GL_STENCIL_INDEX4_OES 0x8D47 +#endif /* GL_OES_stencil4 */ + +#ifndef GL_OES_surfaceless_context +#define GL_OES_surfaceless_context 1 +#define GL_FRAMEBUFFER_UNDEFINED_OES 0x8219 +#endif /* GL_OES_surfaceless_context */ + +#ifndef GL_OES_tessellation_point_size +#define GL_OES_tessellation_point_size 1 +#endif /* GL_OES_tessellation_point_size */ + +#ifndef GL_OES_tessellation_shader +#define GL_OES_tessellation_shader 1 +#define GL_PATCHES_OES 0x000E +#define GL_PATCH_VERTICES_OES 0x8E72 +#define GL_TESS_CONTROL_OUTPUT_VERTICES_OES 0x8E75 +#define GL_TESS_GEN_MODE_OES 0x8E76 +#define GL_TESS_GEN_SPACING_OES 0x8E77 +#define GL_TESS_GEN_VERTEX_ORDER_OES 0x8E78 +#define GL_TESS_GEN_POINT_MODE_OES 0x8E79 +#define GL_ISOLINES_OES 0x8E7A +#define GL_QUADS_OES 0x0007 +#define GL_FRACTIONAL_ODD_OES 0x8E7B +#define GL_FRACTIONAL_EVEN_OES 0x8E7C +#define GL_MAX_PATCH_VERTICES_OES 0x8E7D +#define GL_MAX_TESS_GEN_LEVEL_OES 0x8E7E +#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS_OES 0x8E7F +#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS_OES 0x8E80 +#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_OES 0x8E81 +#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_OES 0x8E82 +#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_OES 0x8E83 +#define GL_MAX_TESS_PATCH_COMPONENTS_OES 0x8E84 +#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_OES 0x8E85 +#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_OES 0x8E86 +#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS_OES 0x8E89 +#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS_OES 0x8E8A +#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_OES 0x886C +#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_OES 0x886D +#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_OES 0x8E1E +#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_OES 0x8E1F +#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_OES 0x92CD +#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_OES 0x92CE +#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS_OES 0x92D3 +#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS_OES 0x92D4 +#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS_OES 0x90CB +#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS_OES 0x90CC +#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_OES 0x90D8 +#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_OES 0x90D9 +#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED_OES 0x8221 +#define GL_IS_PER_PATCH_OES 0x92E7 +#define GL_REFERENCED_BY_TESS_CONTROL_SHADER_OES 0x9307 +#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER_OES 0x9308 +#define GL_TESS_CONTROL_SHADER_OES 0x8E88 +#define GL_TESS_EVALUATION_SHADER_OES 0x8E87 +#define GL_TESS_CONTROL_SHADER_BIT_OES 0x00000008 +#define GL_TESS_EVALUATION_SHADER_BIT_OES 0x00000010 +typedef void (GL_APIENTRYP PFNGLPATCHPARAMETERIOESPROC) (GLenum pname, GLint value); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glPatchParameteriOES (GLenum pname, GLint value); +#endif +#endif /* GL_OES_tessellation_shader */ + +#ifndef GL_OES_texture_3D +#define GL_OES_texture_3D 1 +#define GL_TEXTURE_WRAP_R_OES 0x8072 +#define GL_TEXTURE_3D_OES 0x806F +#define GL_TEXTURE_BINDING_3D_OES 0x806A +#define GL_MAX_3D_TEXTURE_SIZE_OES 0x8073 +#define GL_SAMPLER_3D_OES 0x8B5F +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES 0x8CD4 +typedef void (GL_APIENTRYP PFNGLTEXIMAGE3DOESPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); +typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); +typedef void (GL_APIENTRYP PFNGLCOPYTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DOESPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); +typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DOESPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glTexImage3DOES (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); +GL_APICALL void GL_APIENTRY glTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); +GL_APICALL void GL_APIENTRY glCopyTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glCompressedTexImage3DOES (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); +GL_APICALL void GL_APIENTRY glCompressedTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); +GL_APICALL void GL_APIENTRY glFramebufferTexture3DOES (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); +#endif +#endif /* GL_OES_texture_3D */ + +#ifndef GL_OES_texture_border_clamp +#define GL_OES_texture_border_clamp 1 +#define GL_TEXTURE_BORDER_COLOR_OES 0x1004 +#define GL_CLAMP_TO_BORDER_OES 0x812D +typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIIVOESPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIUIVOESPROC) (GLenum target, GLenum pname, const GLuint *params); +typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIIVOESPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIUIVOESPROC) (GLenum target, GLenum pname, GLuint *params); +typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIIVOESPROC) (GLuint sampler, GLenum pname, const GLint *param); +typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIUIVOESPROC) (GLuint sampler, GLenum pname, const GLuint *param); +typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIIVOESPROC) (GLuint sampler, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIUIVOESPROC) (GLuint sampler, GLenum pname, GLuint *params); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glTexParameterIivOES (GLenum target, GLenum pname, const GLint *params); +GL_APICALL void GL_APIENTRY glTexParameterIuivOES (GLenum target, GLenum pname, const GLuint *params); +GL_APICALL void GL_APIENTRY glGetTexParameterIivOES (GLenum target, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetTexParameterIuivOES (GLenum target, GLenum pname, GLuint *params); +GL_APICALL void GL_APIENTRY glSamplerParameterIivOES (GLuint sampler, GLenum pname, const GLint *param); +GL_APICALL void GL_APIENTRY glSamplerParameterIuivOES (GLuint sampler, GLenum pname, const GLuint *param); +GL_APICALL void GL_APIENTRY glGetSamplerParameterIivOES (GLuint sampler, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetSamplerParameterIuivOES (GLuint sampler, GLenum pname, GLuint *params); +#endif +#endif /* GL_OES_texture_border_clamp */ + +#ifndef GL_OES_texture_buffer +#define GL_OES_texture_buffer 1 +#define GL_TEXTURE_BUFFER_OES 0x8C2A +#define GL_TEXTURE_BUFFER_BINDING_OES 0x8C2A +#define GL_MAX_TEXTURE_BUFFER_SIZE_OES 0x8C2B +#define GL_TEXTURE_BINDING_BUFFER_OES 0x8C2C +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_OES 0x8C2D +#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT_OES 0x919F +#define GL_SAMPLER_BUFFER_OES 0x8DC2 +#define GL_INT_SAMPLER_BUFFER_OES 0x8DD0 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER_OES 0x8DD8 +#define GL_IMAGE_BUFFER_OES 0x9051 +#define GL_INT_IMAGE_BUFFER_OES 0x905C +#define GL_UNSIGNED_INT_IMAGE_BUFFER_OES 0x9067 +#define GL_TEXTURE_BUFFER_OFFSET_OES 0x919D +#define GL_TEXTURE_BUFFER_SIZE_OES 0x919E +typedef void (GL_APIENTRYP PFNGLTEXBUFFEROESPROC) (GLenum target, GLenum internalformat, GLuint buffer); +typedef void (GL_APIENTRYP PFNGLTEXBUFFERRANGEOESPROC) (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glTexBufferOES (GLenum target, GLenum internalformat, GLuint buffer); +GL_APICALL void GL_APIENTRY glTexBufferRangeOES (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); +#endif +#endif /* GL_OES_texture_buffer */ + +#ifndef GL_OES_texture_compression_astc +#define GL_OES_texture_compression_astc 1 +#define GL_COMPRESSED_RGBA_ASTC_3x3x3_OES 0x93C0 +#define GL_COMPRESSED_RGBA_ASTC_4x3x3_OES 0x93C1 +#define GL_COMPRESSED_RGBA_ASTC_4x4x3_OES 0x93C2 +#define GL_COMPRESSED_RGBA_ASTC_4x4x4_OES 0x93C3 +#define GL_COMPRESSED_RGBA_ASTC_5x4x4_OES 0x93C4 +#define GL_COMPRESSED_RGBA_ASTC_5x5x4_OES 0x93C5 +#define GL_COMPRESSED_RGBA_ASTC_5x5x5_OES 0x93C6 +#define GL_COMPRESSED_RGBA_ASTC_6x5x5_OES 0x93C7 +#define GL_COMPRESSED_RGBA_ASTC_6x6x5_OES 0x93C8 +#define GL_COMPRESSED_RGBA_ASTC_6x6x6_OES 0x93C9 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES 0x93E0 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES 0x93E1 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES 0x93E2 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES 0x93E3 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES 0x93E4 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES 0x93E5 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES 0x93E6 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES 0x93E7 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES 0x93E8 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES 0x93E9 +#endif /* GL_OES_texture_compression_astc */ + +#ifndef GL_OES_texture_cube_map_array +#define GL_OES_texture_cube_map_array 1 +#define GL_TEXTURE_CUBE_MAP_ARRAY_OES 0x9009 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_OES 0x900A +#define GL_SAMPLER_CUBE_MAP_ARRAY_OES 0x900C +#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_OES 0x900D +#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_OES 0x900E +#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_OES 0x900F +#define GL_IMAGE_CUBE_MAP_ARRAY_OES 0x9054 +#define GL_INT_IMAGE_CUBE_MAP_ARRAY_OES 0x905F +#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_OES 0x906A +#endif /* GL_OES_texture_cube_map_array */ + +#ifndef GL_OES_texture_float +#define GL_OES_texture_float 1 +#endif /* GL_OES_texture_float */ + +#ifndef GL_OES_texture_float_linear +#define GL_OES_texture_float_linear 1 +#endif /* GL_OES_texture_float_linear */ + +#ifndef GL_OES_texture_half_float +#define GL_OES_texture_half_float 1 +#define GL_HALF_FLOAT_OES 0x8D61 +#endif /* GL_OES_texture_half_float */ + +#ifndef GL_OES_texture_half_float_linear +#define GL_OES_texture_half_float_linear 1 +#endif /* GL_OES_texture_half_float_linear */ + +#ifndef GL_OES_texture_npot +#define GL_OES_texture_npot 1 +#endif /* GL_OES_texture_npot */ + +#ifndef GL_OES_texture_stencil8 +#define GL_OES_texture_stencil8 1 +#define GL_STENCIL_INDEX_OES 0x1901 +#define GL_STENCIL_INDEX8_OES 0x8D48 +#endif /* GL_OES_texture_stencil8 */ + +#ifndef GL_OES_texture_storage_multisample_2d_array +#define GL_OES_texture_storage_multisample_2d_array 1 +#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES 0x9102 +#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY_OES 0x9105 +#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY_OES 0x910B +#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY_OES 0x910C +#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY_OES 0x910D +typedef void (GL_APIENTRYP PFNGLTEXSTORAGE3DMULTISAMPLEOESPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glTexStorage3DMultisampleOES (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +#endif +#endif /* GL_OES_texture_storage_multisample_2d_array */ + +#ifndef GL_OES_texture_view +#define GL_OES_texture_view 1 +#define GL_TEXTURE_VIEW_MIN_LEVEL_OES 0x82DB +#define GL_TEXTURE_VIEW_NUM_LEVELS_OES 0x82DC +#define GL_TEXTURE_VIEW_MIN_LAYER_OES 0x82DD +#define GL_TEXTURE_VIEW_NUM_LAYERS_OES 0x82DE +#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF +typedef void (GL_APIENTRYP PFNGLTEXTUREVIEWOESPROC) (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glTextureViewOES (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers); +#endif +#endif /* GL_OES_texture_view */ + +#ifndef GL_OES_vertex_array_object +#define GL_OES_vertex_array_object 1 +#define GL_VERTEX_ARRAY_BINDING_OES 0x85B5 +typedef void (GL_APIENTRYP PFNGLBINDVERTEXARRAYOESPROC) (GLuint array); +typedef void (GL_APIENTRYP PFNGLDELETEVERTEXARRAYSOESPROC) (GLsizei n, const GLuint *arrays); +typedef void (GL_APIENTRYP PFNGLGENVERTEXARRAYSOESPROC) (GLsizei n, GLuint *arrays); +typedef GLboolean (GL_APIENTRYP PFNGLISVERTEXARRAYOESPROC) (GLuint array); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glBindVertexArrayOES (GLuint array); +GL_APICALL void GL_APIENTRY glDeleteVertexArraysOES (GLsizei n, const GLuint *arrays); +GL_APICALL void GL_APIENTRY glGenVertexArraysOES (GLsizei n, GLuint *arrays); +GL_APICALL GLboolean GL_APIENTRY glIsVertexArrayOES (GLuint array); +#endif +#endif /* GL_OES_vertex_array_object */ + +#ifndef GL_OES_vertex_half_float +#define GL_OES_vertex_half_float 1 +#endif /* GL_OES_vertex_half_float */ + +#ifndef GL_OES_vertex_type_10_10_10_2 +#define GL_OES_vertex_type_10_10_10_2 1 +#define GL_UNSIGNED_INT_10_10_10_2_OES 0x8DF6 +#define GL_INT_10_10_10_2_OES 0x8DF7 +#endif /* GL_OES_vertex_type_10_10_10_2 */ + +#ifndef GL_OES_viewport_array +#define GL_OES_viewport_array 1 +#define GL_MAX_VIEWPORTS_OES 0x825B +#define GL_VIEWPORT_SUBPIXEL_BITS_OES 0x825C +#define GL_VIEWPORT_BOUNDS_RANGE_OES 0x825D +#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX_OES 0x825F +typedef void (GL_APIENTRYP PFNGLVIEWPORTARRAYVOESPROC) (GLuint first, GLsizei count, const GLfloat *v); +typedef void (GL_APIENTRYP PFNGLVIEWPORTINDEXEDFOESPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); +typedef void (GL_APIENTRYP PFNGLVIEWPORTINDEXEDFVOESPROC) (GLuint index, const GLfloat *v); +typedef void (GL_APIENTRYP PFNGLSCISSORARRAYVOESPROC) (GLuint first, GLsizei count, const GLint *v); +typedef void (GL_APIENTRYP PFNGLSCISSORINDEXEDOESPROC) (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLSCISSORINDEXEDVOESPROC) (GLuint index, const GLint *v); +typedef void (GL_APIENTRYP PFNGLDEPTHRANGEARRAYFVOESPROC) (GLuint first, GLsizei count, const GLfloat *v); +typedef void (GL_APIENTRYP PFNGLDEPTHRANGEINDEXEDFOESPROC) (GLuint index, GLfloat n, GLfloat f); +typedef void (GL_APIENTRYP PFNGLGETFLOATI_VOESPROC) (GLenum target, GLuint index, GLfloat *data); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glViewportArrayvOES (GLuint first, GLsizei count, const GLfloat *v); +GL_APICALL void GL_APIENTRY glViewportIndexedfOES (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); +GL_APICALL void GL_APIENTRY glViewportIndexedfvOES (GLuint index, const GLfloat *v); +GL_APICALL void GL_APIENTRY glScissorArrayvOES (GLuint first, GLsizei count, const GLint *v); +GL_APICALL void GL_APIENTRY glScissorIndexedOES (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glScissorIndexedvOES (GLuint index, const GLint *v); +GL_APICALL void GL_APIENTRY glDepthRangeArrayfvOES (GLuint first, GLsizei count, const GLfloat *v); +GL_APICALL void GL_APIENTRY glDepthRangeIndexedfOES (GLuint index, GLfloat n, GLfloat f); +GL_APICALL void GL_APIENTRY glGetFloati_vOES (GLenum target, GLuint index, GLfloat *data); +#endif +#endif /* GL_OES_viewport_array */ + +#ifndef GL_AMD_compressed_3DC_texture +#define GL_AMD_compressed_3DC_texture 1 +#define GL_3DC_X_AMD 0x87F9 +#define GL_3DC_XY_AMD 0x87FA +#endif /* GL_AMD_compressed_3DC_texture */ + +#ifndef GL_AMD_compressed_ATC_texture +#define GL_AMD_compressed_ATC_texture 1 +#define GL_ATC_RGB_AMD 0x8C92 +#define GL_ATC_RGBA_EXPLICIT_ALPHA_AMD 0x8C93 +#define GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD 0x87EE +#endif /* GL_AMD_compressed_ATC_texture */ + +#ifndef GL_AMD_framebuffer_multisample_advanced +#define GL_AMD_framebuffer_multisample_advanced 1 +#define GL_RENDERBUFFER_STORAGE_SAMPLES_AMD 0x91B2 +#define GL_MAX_COLOR_FRAMEBUFFER_SAMPLES_AMD 0x91B3 +#define GL_MAX_COLOR_FRAMEBUFFER_STORAGE_SAMPLES_AMD 0x91B4 +#define GL_MAX_DEPTH_STENCIL_FRAMEBUFFER_SAMPLES_AMD 0x91B5 +#define GL_NUM_SUPPORTED_MULTISAMPLE_MODES_AMD 0x91B6 +#define GL_SUPPORTED_MULTISAMPLE_MODES_AMD 0x91B7 +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC) (GLenum target, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC) (GLuint renderbuffer, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleAdvancedAMD (GLenum target, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glNamedRenderbufferStorageMultisampleAdvancedAMD (GLuint renderbuffer, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height); +#endif +#endif /* GL_AMD_framebuffer_multisample_advanced */ + +#ifndef GL_AMD_performance_monitor +#define GL_AMD_performance_monitor 1 +#define GL_COUNTER_TYPE_AMD 0x8BC0 +#define GL_COUNTER_RANGE_AMD 0x8BC1 +#define GL_UNSIGNED_INT64_AMD 0x8BC2 +#define GL_PERCENTAGE_AMD 0x8BC3 +#define GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4 +#define GL_PERFMON_RESULT_SIZE_AMD 0x8BC5 +#define GL_PERFMON_RESULT_AMD 0x8BC6 +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORGROUPSAMDPROC) (GLint *numGroups, GLsizei groupsSize, GLuint *groups); +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERSAMDPROC) (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters); +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString); +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString); +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) (GLuint group, GLuint counter, GLenum pname, void *data); +typedef void (GL_APIENTRYP PFNGLGENPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors); +typedef void (GL_APIENTRYP PFNGLDELETEPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors); +typedef void (GL_APIENTRYP PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *counterList); +typedef void (GL_APIENTRYP PFNGLBEGINPERFMONITORAMDPROC) (GLuint monitor); +typedef void (GL_APIENTRYP PFNGLENDPERFMONITORAMDPROC) (GLuint monitor); +typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGetPerfMonitorGroupsAMD (GLint *numGroups, GLsizei groupsSize, GLuint *groups); +GL_APICALL void GL_APIENTRY glGetPerfMonitorCountersAMD (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters); +GL_APICALL void GL_APIENTRY glGetPerfMonitorGroupStringAMD (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString); +GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterStringAMD (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString); +GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterInfoAMD (GLuint group, GLuint counter, GLenum pname, void *data); +GL_APICALL void GL_APIENTRY glGenPerfMonitorsAMD (GLsizei n, GLuint *monitors); +GL_APICALL void GL_APIENTRY glDeletePerfMonitorsAMD (GLsizei n, GLuint *monitors); +GL_APICALL void GL_APIENTRY glSelectPerfMonitorCountersAMD (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *counterList); +GL_APICALL void GL_APIENTRY glBeginPerfMonitorAMD (GLuint monitor); +GL_APICALL void GL_APIENTRY glEndPerfMonitorAMD (GLuint monitor); +GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterDataAMD (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten); +#endif +#endif /* GL_AMD_performance_monitor */ + +#ifndef GL_AMD_program_binary_Z400 +#define GL_AMD_program_binary_Z400 1 +#define GL_Z400_BINARY_AMD 0x8740 +#endif /* GL_AMD_program_binary_Z400 */ + +#ifndef GL_ANDROID_extension_pack_es31a +#define GL_ANDROID_extension_pack_es31a 1 +#endif /* GL_ANDROID_extension_pack_es31a */ + +#ifndef GL_ANGLE_depth_texture +#define GL_ANGLE_depth_texture 1 +#endif /* GL_ANGLE_depth_texture */ + +#ifndef GL_ANGLE_framebuffer_blit +#define GL_ANGLE_framebuffer_blit 1 +#define GL_READ_FRAMEBUFFER_ANGLE 0x8CA8 +#define GL_DRAW_FRAMEBUFFER_ANGLE 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_BINDING_ANGLE 0x8CA6 +#define GL_READ_FRAMEBUFFER_BINDING_ANGLE 0x8CAA +typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERANGLEPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glBlitFramebufferANGLE (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#endif +#endif /* GL_ANGLE_framebuffer_blit */ + +#ifndef GL_ANGLE_framebuffer_multisample +#define GL_ANGLE_framebuffer_multisample 1 +#define GL_RENDERBUFFER_SAMPLES_ANGLE 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE 0x8D56 +#define GL_MAX_SAMPLES_ANGLE 0x8D57 +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleANGLE (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +#endif +#endif /* GL_ANGLE_framebuffer_multisample */ + +#ifndef GL_ANGLE_instanced_arrays +#define GL_ANGLE_instanced_arrays 1 +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE 0x88FE +typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDANGLEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDANGLEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISORANGLEPROC) (GLuint index, GLuint divisor); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDrawArraysInstancedANGLE (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +GL_APICALL void GL_APIENTRY glDrawElementsInstancedANGLE (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); +GL_APICALL void GL_APIENTRY glVertexAttribDivisorANGLE (GLuint index, GLuint divisor); +#endif +#endif /* GL_ANGLE_instanced_arrays */ + +#ifndef GL_ANGLE_pack_reverse_row_order +#define GL_ANGLE_pack_reverse_row_order 1 +#define GL_PACK_REVERSE_ROW_ORDER_ANGLE 0x93A4 +#endif /* GL_ANGLE_pack_reverse_row_order */ + +#ifndef GL_ANGLE_program_binary +#define GL_ANGLE_program_binary 1 +#define GL_PROGRAM_BINARY_ANGLE 0x93A6 +#endif /* GL_ANGLE_program_binary */ + +#ifndef GL_ANGLE_texture_compression_dxt3 +#define GL_ANGLE_texture_compression_dxt3 1 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE 0x83F2 +#endif /* GL_ANGLE_texture_compression_dxt3 */ + +#ifndef GL_ANGLE_texture_compression_dxt5 +#define GL_ANGLE_texture_compression_dxt5 1 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE 0x83F3 +#endif /* GL_ANGLE_texture_compression_dxt5 */ + +#ifndef GL_ANGLE_texture_usage +#define GL_ANGLE_texture_usage 1 +#define GL_TEXTURE_USAGE_ANGLE 0x93A2 +#define GL_FRAMEBUFFER_ATTACHMENT_ANGLE 0x93A3 +#endif /* GL_ANGLE_texture_usage */ + +#ifndef GL_ANGLE_translated_shader_source +#define GL_ANGLE_translated_shader_source 1 +#define GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE 0x93A0 +typedef void (GL_APIENTRYP PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGetTranslatedShaderSourceANGLE (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); +#endif +#endif /* GL_ANGLE_translated_shader_source */ + +#ifndef GL_APPLE_clip_distance +#define GL_APPLE_clip_distance 1 +#define GL_MAX_CLIP_DISTANCES_APPLE 0x0D32 +#define GL_CLIP_DISTANCE0_APPLE 0x3000 +#define GL_CLIP_DISTANCE1_APPLE 0x3001 +#define GL_CLIP_DISTANCE2_APPLE 0x3002 +#define GL_CLIP_DISTANCE3_APPLE 0x3003 +#define GL_CLIP_DISTANCE4_APPLE 0x3004 +#define GL_CLIP_DISTANCE5_APPLE 0x3005 +#define GL_CLIP_DISTANCE6_APPLE 0x3006 +#define GL_CLIP_DISTANCE7_APPLE 0x3007 +#endif /* GL_APPLE_clip_distance */ + +#ifndef GL_APPLE_color_buffer_packed_float +#define GL_APPLE_color_buffer_packed_float 1 +#endif /* GL_APPLE_color_buffer_packed_float */ + +#ifndef GL_APPLE_copy_texture_levels +#define GL_APPLE_copy_texture_levels 1 +typedef void (GL_APIENTRYP PFNGLCOPYTEXTURELEVELSAPPLEPROC) (GLuint destinationTexture, GLuint sourceTexture, GLint sourceBaseLevel, GLsizei sourceLevelCount); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glCopyTextureLevelsAPPLE (GLuint destinationTexture, GLuint sourceTexture, GLint sourceBaseLevel, GLsizei sourceLevelCount); +#endif +#endif /* GL_APPLE_copy_texture_levels */ + +#ifndef GL_APPLE_framebuffer_multisample +#define GL_APPLE_framebuffer_multisample 1 +#define GL_RENDERBUFFER_SAMPLES_APPLE 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_APPLE 0x8D56 +#define GL_MAX_SAMPLES_APPLE 0x8D57 +#define GL_READ_FRAMEBUFFER_APPLE 0x8CA8 +#define GL_DRAW_FRAMEBUFFER_APPLE 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_BINDING_APPLE 0x8CA6 +#define GL_READ_FRAMEBUFFER_BINDING_APPLE 0x8CAA +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEAPPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLRESOLVEMULTISAMPLEFRAMEBUFFERAPPLEPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleAPPLE (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glResolveMultisampleFramebufferAPPLE (void); +#endif +#endif /* GL_APPLE_framebuffer_multisample */ + +#ifndef GL_APPLE_rgb_422 +#define GL_APPLE_rgb_422 1 +#define GL_RGB_422_APPLE 0x8A1F +#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB +#define GL_RGB_RAW_422_APPLE 0x8A51 +#endif /* GL_APPLE_rgb_422 */ + +#ifndef GL_APPLE_sync +#define GL_APPLE_sync 1 +#define GL_SYNC_OBJECT_APPLE 0x8A53 +#define GL_MAX_SERVER_WAIT_TIMEOUT_APPLE 0x9111 +#define GL_OBJECT_TYPE_APPLE 0x9112 +#define GL_SYNC_CONDITION_APPLE 0x9113 +#define GL_SYNC_STATUS_APPLE 0x9114 +#define GL_SYNC_FLAGS_APPLE 0x9115 +#define GL_SYNC_FENCE_APPLE 0x9116 +#define GL_SYNC_GPU_COMMANDS_COMPLETE_APPLE 0x9117 +#define GL_UNSIGNALED_APPLE 0x9118 +#define GL_SIGNALED_APPLE 0x9119 +#define GL_ALREADY_SIGNALED_APPLE 0x911A +#define GL_TIMEOUT_EXPIRED_APPLE 0x911B +#define GL_CONDITION_SATISFIED_APPLE 0x911C +#define GL_WAIT_FAILED_APPLE 0x911D +#define GL_SYNC_FLUSH_COMMANDS_BIT_APPLE 0x00000001 +#define GL_TIMEOUT_IGNORED_APPLE 0xFFFFFFFFFFFFFFFFull +typedef GLsync (GL_APIENTRYP PFNGLFENCESYNCAPPLEPROC) (GLenum condition, GLbitfield flags); +typedef GLboolean (GL_APIENTRYP PFNGLISSYNCAPPLEPROC) (GLsync sync); +typedef void (GL_APIENTRYP PFNGLDELETESYNCAPPLEPROC) (GLsync sync); +typedef GLenum (GL_APIENTRYP PFNGLCLIENTWAITSYNCAPPLEPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); +typedef void (GL_APIENTRYP PFNGLWAITSYNCAPPLEPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); +typedef void (GL_APIENTRYP PFNGLGETINTEGER64VAPPLEPROC) (GLenum pname, GLint64 *params); +typedef void (GL_APIENTRYP PFNGLGETSYNCIVAPPLEPROC) (GLsync sync, GLenum pname, GLsizei count, GLsizei *length, GLint *values); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL GLsync GL_APIENTRY glFenceSyncAPPLE (GLenum condition, GLbitfield flags); +GL_APICALL GLboolean GL_APIENTRY glIsSyncAPPLE (GLsync sync); +GL_APICALL void GL_APIENTRY glDeleteSyncAPPLE (GLsync sync); +GL_APICALL GLenum GL_APIENTRY glClientWaitSyncAPPLE (GLsync sync, GLbitfield flags, GLuint64 timeout); +GL_APICALL void GL_APIENTRY glWaitSyncAPPLE (GLsync sync, GLbitfield flags, GLuint64 timeout); +GL_APICALL void GL_APIENTRY glGetInteger64vAPPLE (GLenum pname, GLint64 *params); +GL_APICALL void GL_APIENTRY glGetSyncivAPPLE (GLsync sync, GLenum pname, GLsizei count, GLsizei *length, GLint *values); +#endif +#endif /* GL_APPLE_sync */ + +#ifndef GL_APPLE_texture_format_BGRA8888 +#define GL_APPLE_texture_format_BGRA8888 1 +#define GL_BGRA_EXT 0x80E1 +#define GL_BGRA8_EXT 0x93A1 +#endif /* GL_APPLE_texture_format_BGRA8888 */ + +#ifndef GL_APPLE_texture_max_level +#define GL_APPLE_texture_max_level 1 +#define GL_TEXTURE_MAX_LEVEL_APPLE 0x813D +#endif /* GL_APPLE_texture_max_level */ + +#ifndef GL_APPLE_texture_packed_float +#define GL_APPLE_texture_packed_float 1 +#define GL_UNSIGNED_INT_10F_11F_11F_REV_APPLE 0x8C3B +#define GL_UNSIGNED_INT_5_9_9_9_REV_APPLE 0x8C3E +#define GL_R11F_G11F_B10F_APPLE 0x8C3A +#define GL_RGB9_E5_APPLE 0x8C3D +#endif /* GL_APPLE_texture_packed_float */ + +#ifndef GL_ARM_mali_program_binary +#define GL_ARM_mali_program_binary 1 +#define GL_MALI_PROGRAM_BINARY_ARM 0x8F61 +#endif /* GL_ARM_mali_program_binary */ + +#ifndef GL_ARM_mali_shader_binary +#define GL_ARM_mali_shader_binary 1 +#define GL_MALI_SHADER_BINARY_ARM 0x8F60 +#endif /* GL_ARM_mali_shader_binary */ + +#ifndef GL_ARM_rgba8 +#define GL_ARM_rgba8 1 +#endif /* GL_ARM_rgba8 */ + +#ifndef GL_ARM_shader_framebuffer_fetch +#define GL_ARM_shader_framebuffer_fetch 1 +#define GL_FETCH_PER_SAMPLE_ARM 0x8F65 +#define GL_FRAGMENT_SHADER_FRAMEBUFFER_FETCH_MRT_ARM 0x8F66 +#endif /* GL_ARM_shader_framebuffer_fetch */ + +#ifndef GL_ARM_shader_framebuffer_fetch_depth_stencil +#define GL_ARM_shader_framebuffer_fetch_depth_stencil 1 +#endif /* GL_ARM_shader_framebuffer_fetch_depth_stencil */ + +#ifndef GL_ARM_texture_unnormalized_coordinates +#define GL_ARM_texture_unnormalized_coordinates 1 +#define GL_TEXTURE_UNNORMALIZED_COORDINATES_ARM 0x8F6A +#endif /* GL_ARM_texture_unnormalized_coordinates */ + +#ifndef GL_DMP_program_binary +#define GL_DMP_program_binary 1 +#define GL_SMAPHS30_PROGRAM_BINARY_DMP 0x9251 +#define GL_SMAPHS_PROGRAM_BINARY_DMP 0x9252 +#define GL_DMP_PROGRAM_BINARY_DMP 0x9253 +#endif /* GL_DMP_program_binary */ + +#ifndef GL_DMP_shader_binary +#define GL_DMP_shader_binary 1 +#define GL_SHADER_BINARY_DMP 0x9250 +#endif /* GL_DMP_shader_binary */ + +#ifndef GL_EXT_EGL_image_array +#define GL_EXT_EGL_image_array 1 +#endif /* GL_EXT_EGL_image_array */ + +#ifndef GL_EXT_EGL_image_storage +#define GL_EXT_EGL_image_storage 1 +typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXSTORAGEEXTPROC) (GLenum target, GLeglImageOES image, const GLint* attrib_list); +typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXTURESTORAGEEXTPROC) (GLuint texture, GLeglImageOES image, const GLint* attrib_list); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glEGLImageTargetTexStorageEXT (GLenum target, GLeglImageOES image, const GLint* attrib_list); +GL_APICALL void GL_APIENTRY glEGLImageTargetTextureStorageEXT (GLuint texture, GLeglImageOES image, const GLint* attrib_list); +#endif +#endif /* GL_EXT_EGL_image_storage */ + +#ifndef GL_EXT_EGL_image_storage_compression +#define GL_EXT_EGL_image_storage_compression 1 +#define GL_SURFACE_COMPRESSION_EXT 0x96C0 +#define GL_SURFACE_COMPRESSION_FIXED_RATE_NONE_EXT 0x96C1 +#define GL_SURFACE_COMPRESSION_FIXED_RATE_DEFAULT_EXT 0x96C2 +#endif /* GL_EXT_EGL_image_storage_compression */ + +#ifndef GL_EXT_YUV_target +#define GL_EXT_YUV_target 1 +#define GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT 0x8BE7 +#endif /* GL_EXT_YUV_target */ + +#ifndef GL_EXT_base_instance +#define GL_EXT_base_instance 1 +typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEEXTPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance); +typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance); +typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDrawArraysInstancedBaseInstanceEXT (GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance); +GL_APICALL void GL_APIENTRY glDrawElementsInstancedBaseInstanceEXT (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance); +GL_APICALL void GL_APIENTRY glDrawElementsInstancedBaseVertexBaseInstanceEXT (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance); +#endif +#endif /* GL_EXT_base_instance */ + +#ifndef GL_EXT_blend_func_extended +#define GL_EXT_blend_func_extended 1 +#define GL_SRC1_COLOR_EXT 0x88F9 +#define GL_SRC1_ALPHA_EXT 0x8589 +#define GL_ONE_MINUS_SRC1_COLOR_EXT 0x88FA +#define GL_ONE_MINUS_SRC1_ALPHA_EXT 0x88FB +#define GL_SRC_ALPHA_SATURATE_EXT 0x0308 +#define GL_LOCATION_INDEX_EXT 0x930F +#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT 0x88FC +typedef void (GL_APIENTRYP PFNGLBINDFRAGDATALOCATIONINDEXEDEXTPROC) (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name); +typedef void (GL_APIENTRYP PFNGLBINDFRAGDATALOCATIONEXTPROC) (GLuint program, GLuint color, const GLchar *name); +typedef GLint (GL_APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONINDEXEXTPROC) (GLuint program, GLenum programInterface, const GLchar *name); +typedef GLint (GL_APIENTRYP PFNGLGETFRAGDATAINDEXEXTPROC) (GLuint program, const GLchar *name); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glBindFragDataLocationIndexedEXT (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name); +GL_APICALL void GL_APIENTRY glBindFragDataLocationEXT (GLuint program, GLuint color, const GLchar *name); +GL_APICALL GLint GL_APIENTRY glGetProgramResourceLocationIndexEXT (GLuint program, GLenum programInterface, const GLchar *name); +GL_APICALL GLint GL_APIENTRY glGetFragDataIndexEXT (GLuint program, const GLchar *name); +#endif +#endif /* GL_EXT_blend_func_extended */ + +#ifndef GL_EXT_blend_minmax +#define GL_EXT_blend_minmax 1 +#define GL_MIN_EXT 0x8007 +#define GL_MAX_EXT 0x8008 +#endif /* GL_EXT_blend_minmax */ + +#ifndef GL_EXT_buffer_storage +#define GL_EXT_buffer_storage 1 +#define GL_MAP_READ_BIT 0x0001 +#define GL_MAP_WRITE_BIT 0x0002 +#define GL_MAP_PERSISTENT_BIT_EXT 0x0040 +#define GL_MAP_COHERENT_BIT_EXT 0x0080 +#define GL_DYNAMIC_STORAGE_BIT_EXT 0x0100 +#define GL_CLIENT_STORAGE_BIT_EXT 0x0200 +#define GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT_EXT 0x00004000 +#define GL_BUFFER_IMMUTABLE_STORAGE_EXT 0x821F +#define GL_BUFFER_STORAGE_FLAGS_EXT 0x8220 +typedef void (GL_APIENTRYP PFNGLBUFFERSTORAGEEXTPROC) (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glBufferStorageEXT (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags); +#endif +#endif /* GL_EXT_buffer_storage */ + +#ifndef GL_EXT_clear_texture +#define GL_EXT_clear_texture 1 +typedef void (GL_APIENTRYP PFNGLCLEARTEXIMAGEEXTPROC) (GLuint texture, GLint level, GLenum format, GLenum type, const void *data); +typedef void (GL_APIENTRYP PFNGLCLEARTEXSUBIMAGEEXTPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glClearTexImageEXT (GLuint texture, GLint level, GLenum format, GLenum type, const void *data); +GL_APICALL void GL_APIENTRY glClearTexSubImageEXT (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data); +#endif +#endif /* GL_EXT_clear_texture */ + +#ifndef GL_EXT_clip_control +#define GL_EXT_clip_control 1 +#define GL_LOWER_LEFT_EXT 0x8CA1 +#define GL_UPPER_LEFT_EXT 0x8CA2 +#define GL_NEGATIVE_ONE_TO_ONE_EXT 0x935E +#define GL_ZERO_TO_ONE_EXT 0x935F +#define GL_CLIP_ORIGIN_EXT 0x935C +#define GL_CLIP_DEPTH_MODE_EXT 0x935D +typedef void (GL_APIENTRYP PFNGLCLIPCONTROLEXTPROC) (GLenum origin, GLenum depth); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glClipControlEXT (GLenum origin, GLenum depth); +#endif +#endif /* GL_EXT_clip_control */ + +#ifndef GL_EXT_clip_cull_distance +#define GL_EXT_clip_cull_distance 1 +#define GL_MAX_CLIP_DISTANCES_EXT 0x0D32 +#define GL_MAX_CULL_DISTANCES_EXT 0x82F9 +#define GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES_EXT 0x82FA +#define GL_CLIP_DISTANCE0_EXT 0x3000 +#define GL_CLIP_DISTANCE1_EXT 0x3001 +#define GL_CLIP_DISTANCE2_EXT 0x3002 +#define GL_CLIP_DISTANCE3_EXT 0x3003 +#define GL_CLIP_DISTANCE4_EXT 0x3004 +#define GL_CLIP_DISTANCE5_EXT 0x3005 +#define GL_CLIP_DISTANCE6_EXT 0x3006 +#define GL_CLIP_DISTANCE7_EXT 0x3007 +#endif /* GL_EXT_clip_cull_distance */ + +#ifndef GL_EXT_color_buffer_float +#define GL_EXT_color_buffer_float 1 +#endif /* GL_EXT_color_buffer_float */ + +#ifndef GL_EXT_color_buffer_half_float +#define GL_EXT_color_buffer_half_float 1 +#define GL_RGBA16F_EXT 0x881A +#define GL_RGB16F_EXT 0x881B +#define GL_RG16F_EXT 0x822F +#define GL_R16F_EXT 0x822D +#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT 0x8211 +#define GL_UNSIGNED_NORMALIZED_EXT 0x8C17 +#endif /* GL_EXT_color_buffer_half_float */ + +#ifndef GL_EXT_conservative_depth +#define GL_EXT_conservative_depth 1 +#endif /* GL_EXT_conservative_depth */ + +#ifndef GL_EXT_copy_image +#define GL_EXT_copy_image 1 +typedef void (GL_APIENTRYP PFNGLCOPYIMAGESUBDATAEXTPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glCopyImageSubDataEXT (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); +#endif +#endif /* GL_EXT_copy_image */ + +#ifndef GL_EXT_debug_label +#define GL_EXT_debug_label 1 +#define GL_PROGRAM_PIPELINE_OBJECT_EXT 0x8A4F +#define GL_PROGRAM_OBJECT_EXT 0x8B40 +#define GL_SHADER_OBJECT_EXT 0x8B48 +#define GL_BUFFER_OBJECT_EXT 0x9151 +#define GL_QUERY_OBJECT_EXT 0x9153 +#define GL_VERTEX_ARRAY_OBJECT_EXT 0x9154 +#define GL_TRANSFORM_FEEDBACK 0x8E22 +typedef void (GL_APIENTRYP PFNGLLABELOBJECTEXTPROC) (GLenum type, GLuint object, GLsizei length, const GLchar *label); +typedef void (GL_APIENTRYP PFNGLGETOBJECTLABELEXTPROC) (GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glLabelObjectEXT (GLenum type, GLuint object, GLsizei length, const GLchar *label); +GL_APICALL void GL_APIENTRY glGetObjectLabelEXT (GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label); +#endif +#endif /* GL_EXT_debug_label */ + +#ifndef GL_EXT_debug_marker +#define GL_EXT_debug_marker 1 +typedef void (GL_APIENTRYP PFNGLINSERTEVENTMARKEREXTPROC) (GLsizei length, const GLchar *marker); +typedef void (GL_APIENTRYP PFNGLPUSHGROUPMARKEREXTPROC) (GLsizei length, const GLchar *marker); +typedef void (GL_APIENTRYP PFNGLPOPGROUPMARKEREXTPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glInsertEventMarkerEXT (GLsizei length, const GLchar *marker); +GL_APICALL void GL_APIENTRY glPushGroupMarkerEXT (GLsizei length, const GLchar *marker); +GL_APICALL void GL_APIENTRY glPopGroupMarkerEXT (void); +#endif +#endif /* GL_EXT_debug_marker */ + +#ifndef GL_EXT_depth_clamp +#define GL_EXT_depth_clamp 1 +#define GL_DEPTH_CLAMP_EXT 0x864F +#endif /* GL_EXT_depth_clamp */ + +#ifndef GL_EXT_discard_framebuffer +#define GL_EXT_discard_framebuffer 1 +#define GL_COLOR_EXT 0x1800 +#define GL_DEPTH_EXT 0x1801 +#define GL_STENCIL_EXT 0x1802 +typedef void (GL_APIENTRYP PFNGLDISCARDFRAMEBUFFEREXTPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDiscardFramebufferEXT (GLenum target, GLsizei numAttachments, const GLenum *attachments); +#endif +#endif /* GL_EXT_discard_framebuffer */ + +#ifndef GL_EXT_disjoint_timer_query +#define GL_EXT_disjoint_timer_query 1 +#define GL_QUERY_COUNTER_BITS_EXT 0x8864 +#define GL_CURRENT_QUERY_EXT 0x8865 +#define GL_QUERY_RESULT_EXT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE_EXT 0x8867 +#define GL_TIME_ELAPSED_EXT 0x88BF +#define GL_TIMESTAMP_EXT 0x8E28 +#define GL_GPU_DISJOINT_EXT 0x8FBB +typedef void (GL_APIENTRYP PFNGLGENQUERIESEXTPROC) (GLsizei n, GLuint *ids); +typedef void (GL_APIENTRYP PFNGLDELETEQUERIESEXTPROC) (GLsizei n, const GLuint *ids); +typedef GLboolean (GL_APIENTRYP PFNGLISQUERYEXTPROC) (GLuint id); +typedef void (GL_APIENTRYP PFNGLBEGINQUERYEXTPROC) (GLenum target, GLuint id); +typedef void (GL_APIENTRYP PFNGLENDQUERYEXTPROC) (GLenum target); +typedef void (GL_APIENTRYP PFNGLQUERYCOUNTEREXTPROC) (GLuint id, GLenum target); +typedef void (GL_APIENTRYP PFNGLGETQUERYIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTIVEXTPROC) (GLuint id, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTUIVEXTPROC) (GLuint id, GLenum pname, GLuint *params); +typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTI64VEXTPROC) (GLuint id, GLenum pname, GLint64 *params); +typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTUI64VEXTPROC) (GLuint id, GLenum pname, GLuint64 *params); +typedef void (GL_APIENTRYP PFNGLGETINTEGER64VEXTPROC) (GLenum pname, GLint64 *data); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGenQueriesEXT (GLsizei n, GLuint *ids); +GL_APICALL void GL_APIENTRY glDeleteQueriesEXT (GLsizei n, const GLuint *ids); +GL_APICALL GLboolean GL_APIENTRY glIsQueryEXT (GLuint id); +GL_APICALL void GL_APIENTRY glBeginQueryEXT (GLenum target, GLuint id); +GL_APICALL void GL_APIENTRY glEndQueryEXT (GLenum target); +GL_APICALL void GL_APIENTRY glQueryCounterEXT (GLuint id, GLenum target); +GL_APICALL void GL_APIENTRY glGetQueryivEXT (GLenum target, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetQueryObjectivEXT (GLuint id, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetQueryObjectuivEXT (GLuint id, GLenum pname, GLuint *params); +GL_APICALL void GL_APIENTRY glGetQueryObjecti64vEXT (GLuint id, GLenum pname, GLint64 *params); +GL_APICALL void GL_APIENTRY glGetQueryObjectui64vEXT (GLuint id, GLenum pname, GLuint64 *params); +GL_APICALL void GL_APIENTRY glGetInteger64vEXT (GLenum pname, GLint64 *data); +#endif +#endif /* GL_EXT_disjoint_timer_query */ + +#ifndef GL_EXT_draw_buffers +#define GL_EXT_draw_buffers 1 +#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF +#define GL_MAX_DRAW_BUFFERS_EXT 0x8824 +#define GL_DRAW_BUFFER0_EXT 0x8825 +#define GL_DRAW_BUFFER1_EXT 0x8826 +#define GL_DRAW_BUFFER2_EXT 0x8827 +#define GL_DRAW_BUFFER3_EXT 0x8828 +#define GL_DRAW_BUFFER4_EXT 0x8829 +#define GL_DRAW_BUFFER5_EXT 0x882A +#define GL_DRAW_BUFFER6_EXT 0x882B +#define GL_DRAW_BUFFER7_EXT 0x882C +#define GL_DRAW_BUFFER8_EXT 0x882D +#define GL_DRAW_BUFFER9_EXT 0x882E +#define GL_DRAW_BUFFER10_EXT 0x882F +#define GL_DRAW_BUFFER11_EXT 0x8830 +#define GL_DRAW_BUFFER12_EXT 0x8831 +#define GL_DRAW_BUFFER13_EXT 0x8832 +#define GL_DRAW_BUFFER14_EXT 0x8833 +#define GL_DRAW_BUFFER15_EXT 0x8834 +#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 +#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 +#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 +#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 +#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 +#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 +#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 +#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 +#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 +#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 +#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA +#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB +#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC +#define GL_COLOR_ATTACHMENT13_EXT 0x8CED +#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE +#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF +typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSEXTPROC) (GLsizei n, const GLenum *bufs); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDrawBuffersEXT (GLsizei n, const GLenum *bufs); +#endif +#endif /* GL_EXT_draw_buffers */ + +#ifndef GL_EXT_draw_buffers_indexed +#define GL_EXT_draw_buffers_indexed 1 +typedef void (GL_APIENTRYP PFNGLENABLEIEXTPROC) (GLenum target, GLuint index); +typedef void (GL_APIENTRYP PFNGLDISABLEIEXTPROC) (GLenum target, GLuint index); +typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONIEXTPROC) (GLuint buf, GLenum mode); +typedef void (GL_APIENTRYP PFNGLBLENDEQUATIONSEPARATEIEXTPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +typedef void (GL_APIENTRYP PFNGLBLENDFUNCIEXTPROC) (GLuint buf, GLenum src, GLenum dst); +typedef void (GL_APIENTRYP PFNGLBLENDFUNCSEPARATEIEXTPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +typedef void (GL_APIENTRYP PFNGLCOLORMASKIEXTPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +typedef GLboolean (GL_APIENTRYP PFNGLISENABLEDIEXTPROC) (GLenum target, GLuint index); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glEnableiEXT (GLenum target, GLuint index); +GL_APICALL void GL_APIENTRY glDisableiEXT (GLenum target, GLuint index); +GL_APICALL void GL_APIENTRY glBlendEquationiEXT (GLuint buf, GLenum mode); +GL_APICALL void GL_APIENTRY glBlendEquationSeparateiEXT (GLuint buf, GLenum modeRGB, GLenum modeAlpha); +GL_APICALL void GL_APIENTRY glBlendFunciEXT (GLuint buf, GLenum src, GLenum dst); +GL_APICALL void GL_APIENTRY glBlendFuncSeparateiEXT (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +GL_APICALL void GL_APIENTRY glColorMaskiEXT (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); +GL_APICALL GLboolean GL_APIENTRY glIsEnablediEXT (GLenum target, GLuint index); +#endif +#endif /* GL_EXT_draw_buffers_indexed */ + +#ifndef GL_EXT_draw_elements_base_vertex +#define GL_EXT_draw_elements_base_vertex 1 +typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex); +typedef void (GL_APIENTRYP PFNGLDRAWRANGEELEMENTSBASEVERTEXEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex); +typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDrawElementsBaseVertexEXT (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex); +GL_APICALL void GL_APIENTRY glDrawRangeElementsBaseVertexEXT (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex); +GL_APICALL void GL_APIENTRY glDrawElementsInstancedBaseVertexEXT (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex); +#endif +#endif /* GL_EXT_draw_elements_base_vertex */ + +#ifndef GL_EXT_draw_instanced +#define GL_EXT_draw_instanced 1 +typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount); +typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDrawArraysInstancedEXT (GLenum mode, GLint start, GLsizei count, GLsizei primcount); +GL_APICALL void GL_APIENTRY glDrawElementsInstancedEXT (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); +#endif +#endif /* GL_EXT_draw_instanced */ + +#ifndef GL_EXT_draw_transform_feedback +#define GL_EXT_draw_transform_feedback 1 +typedef void (GL_APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKEXTPROC) (GLenum mode, GLuint id); +typedef void (GL_APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDEXTPROC) (GLenum mode, GLuint id, GLsizei instancecount); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDrawTransformFeedbackEXT (GLenum mode, GLuint id); +GL_APICALL void GL_APIENTRY glDrawTransformFeedbackInstancedEXT (GLenum mode, GLuint id, GLsizei instancecount); +#endif +#endif /* GL_EXT_draw_transform_feedback */ + +#ifndef GL_EXT_external_buffer +#define GL_EXT_external_buffer 1 +typedef void *GLeglClientBufferEXT; +typedef void (GL_APIENTRYP PFNGLBUFFERSTORAGEEXTERNALEXTPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags); +typedef void (GL_APIENTRYP PFNGLNAMEDBUFFERSTORAGEEXTERNALEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glBufferStorageExternalEXT (GLenum target, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags); +GL_APICALL void GL_APIENTRY glNamedBufferStorageExternalEXT (GLuint buffer, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags); +#endif +#endif /* GL_EXT_external_buffer */ + +#ifndef GL_EXT_float_blend +#define GL_EXT_float_blend 1 +#endif /* GL_EXT_float_blend */ + +#ifndef GL_EXT_fragment_shading_rate +#define GL_EXT_fragment_shading_rate 1 +#define GL_SHADING_RATE_1X1_PIXELS_EXT 0x96A6 +#define GL_SHADING_RATE_1X2_PIXELS_EXT 0x96A7 +#define GL_SHADING_RATE_2X1_PIXELS_EXT 0x96A8 +#define GL_SHADING_RATE_2X2_PIXELS_EXT 0x96A9 +#define GL_SHADING_RATE_1X4_PIXELS_EXT 0x96AA +#define GL_SHADING_RATE_4X1_PIXELS_EXT 0x96AB +#define GL_SHADING_RATE_4X2_PIXELS_EXT 0x96AC +#define GL_SHADING_RATE_2X4_PIXELS_EXT 0x96AD +#define GL_SHADING_RATE_4X4_PIXELS_EXT 0x96AE +#define GL_SHADING_RATE_EXT 0x96D0 +#define GL_SHADING_RATE_ATTACHMENT_EXT 0x96D1 +#define GL_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_EXT 0x96D2 +#define GL_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_EXT 0x96D3 +#define GL_FRAGMENT_SHADING_RATE_COMBINER_OP_MIN_EXT 0x96D4 +#define GL_FRAGMENT_SHADING_RATE_COMBINER_OP_MAX_EXT 0x96D5 +#define GL_FRAGMENT_SHADING_RATE_COMBINER_OP_MUL_EXT 0x96D6 +#define GL_MIN_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_WIDTH_EXT 0x96D7 +#define GL_MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_WIDTH_EXT 0x96D8 +#define GL_MIN_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_HEIGHT_EXT 0x96D9 +#define GL_MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_HEIGHT_EXT 0x96DA +#define GL_MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_ASPECT_RATIO_EXT 0x96DB +#define GL_MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_LAYERS_EXT 0x96DC +#define GL_FRAGMENT_SHADING_RATE_WITH_SHADER_DEPTH_STENCIL_WRITES_SUPPORTED_EXT 0x96DD +#define GL_FRAGMENT_SHADING_RATE_WITH_SAMPLE_MASK_SUPPORTED_EXT 0x96DE +#define GL_FRAGMENT_SHADING_RATE_ATTACHMENT_WITH_DEFAULT_FRAMEBUFFER_SUPPORTED_EXT 0x96DF +#define GL_FRAGMENT_SHADING_RATE_NON_TRIVIAL_COMBINERS_SUPPORTED_EXT 0x8F6F +typedef void (GL_APIENTRYP PFNGLGETFRAGMENTSHADINGRATESEXTPROC) (GLsizei samples, GLsizei maxCount, GLsizei *count, GLenum *shadingRates); +typedef void (GL_APIENTRYP PFNGLSHADINGRATEEXTPROC) (GLenum rate); +typedef void (GL_APIENTRYP PFNGLSHADINGRATECOMBINEROPSEXTPROC) (GLenum combinerOp0, GLenum combinerOp1); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERSHADINGRATEEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint baseLayer, GLsizei numLayers, GLsizei texelWidth, GLsizei texelHeight); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGetFragmentShadingRatesEXT (GLsizei samples, GLsizei maxCount, GLsizei *count, GLenum *shadingRates); +GL_APICALL void GL_APIENTRY glShadingRateEXT (GLenum rate); +GL_APICALL void GL_APIENTRY glShadingRateCombinerOpsEXT (GLenum combinerOp0, GLenum combinerOp1); +GL_APICALL void GL_APIENTRY glFramebufferShadingRateEXT (GLenum target, GLenum attachment, GLuint texture, GLint baseLayer, GLsizei numLayers, GLsizei texelWidth, GLsizei texelHeight); +#endif +#endif /* GL_EXT_fragment_shading_rate */ + +#ifndef GL_EXT_geometry_point_size +#define GL_EXT_geometry_point_size 1 +#endif /* GL_EXT_geometry_point_size */ + +#ifndef GL_EXT_geometry_shader +#define GL_EXT_geometry_shader 1 +#define GL_GEOMETRY_SHADER_EXT 0x8DD9 +#define GL_GEOMETRY_SHADER_BIT_EXT 0x00000004 +#define GL_GEOMETRY_LINKED_VERTICES_OUT_EXT 0x8916 +#define GL_GEOMETRY_LINKED_INPUT_TYPE_EXT 0x8917 +#define GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT 0x8918 +#define GL_GEOMETRY_SHADER_INVOCATIONS_EXT 0x887F +#define GL_LAYER_PROVOKING_VERTEX_EXT 0x825E +#define GL_LINES_ADJACENCY_EXT 0x000A +#define GL_LINE_STRIP_ADJACENCY_EXT 0x000B +#define GL_TRIANGLES_ADJACENCY_EXT 0x000C +#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0x000D +#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF +#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT 0x8A2C +#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8A32 +#define GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT 0x9123 +#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT 0x9124 +#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0 +#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1 +#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT 0x8E5A +#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29 +#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT 0x92CF +#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT 0x92D5 +#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT 0x90CD +#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT 0x90D7 +#define GL_FIRST_VERTEX_CONVENTION_EXT 0x8E4D +#define GL_LAST_VERTEX_CONVENTION_EXT 0x8E4E +#define GL_UNDEFINED_VERTEX_EXT 0x8260 +#define GL_PRIMITIVES_GENERATED_EXT 0x8C87 +#define GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT 0x9312 +#define GL_MAX_FRAMEBUFFER_LAYERS_EXT 0x9317 +#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 +#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7 +#define GL_REFERENCED_BY_GEOMETRY_SHADER_EXT 0x9309 +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTUREEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glFramebufferTextureEXT (GLenum target, GLenum attachment, GLuint texture, GLint level); +#endif +#endif /* GL_EXT_geometry_shader */ + +#ifndef GL_EXT_gpu_shader5 +#define GL_EXT_gpu_shader5 1 +#endif /* GL_EXT_gpu_shader5 */ + +#ifndef GL_EXT_instanced_arrays +#define GL_EXT_instanced_arrays 1 +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_EXT 0x88FE +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISOREXTPROC) (GLuint index, GLuint divisor); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glVertexAttribDivisorEXT (GLuint index, GLuint divisor); +#endif +#endif /* GL_EXT_instanced_arrays */ + +#ifndef GL_EXT_map_buffer_range +#define GL_EXT_map_buffer_range 1 +#define GL_MAP_READ_BIT_EXT 0x0001 +#define GL_MAP_WRITE_BIT_EXT 0x0002 +#define GL_MAP_INVALIDATE_RANGE_BIT_EXT 0x0004 +#define GL_MAP_INVALIDATE_BUFFER_BIT_EXT 0x0008 +#define GL_MAP_FLUSH_EXPLICIT_BIT_EXT 0x0010 +#define GL_MAP_UNSYNCHRONIZED_BIT_EXT 0x0020 +typedef void *(GL_APIENTRYP PFNGLMAPBUFFERRANGEEXTPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); +typedef void (GL_APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEEXTPROC) (GLenum target, GLintptr offset, GLsizeiptr length); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void *GL_APIENTRY glMapBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); +GL_APICALL void GL_APIENTRY glFlushMappedBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length); +#endif +#endif /* GL_EXT_map_buffer_range */ + +#ifndef GL_EXT_memory_object +#define GL_EXT_memory_object 1 +#define GL_TEXTURE_TILING_EXT 0x9580 +#define GL_DEDICATED_MEMORY_OBJECT_EXT 0x9581 +#define GL_PROTECTED_MEMORY_OBJECT_EXT 0x959B +#define GL_NUM_TILING_TYPES_EXT 0x9582 +#define GL_TILING_TYPES_EXT 0x9583 +#define GL_OPTIMAL_TILING_EXT 0x9584 +#define GL_LINEAR_TILING_EXT 0x9585 +#define GL_NUM_DEVICE_UUIDS_EXT 0x9596 +#define GL_DEVICE_UUID_EXT 0x9597 +#define GL_DRIVER_UUID_EXT 0x9598 +#define GL_UUID_SIZE_EXT 16 +typedef void (GL_APIENTRYP PFNGLGETUNSIGNEDBYTEVEXTPROC) (GLenum pname, GLubyte *data); +typedef void (GL_APIENTRYP PFNGLGETUNSIGNEDBYTEI_VEXTPROC) (GLenum target, GLuint index, GLubyte *data); +typedef void (GL_APIENTRYP PFNGLDELETEMEMORYOBJECTSEXTPROC) (GLsizei n, const GLuint *memoryObjects); +typedef GLboolean (GL_APIENTRYP PFNGLISMEMORYOBJECTEXTPROC) (GLuint memoryObject); +typedef void (GL_APIENTRYP PFNGLCREATEMEMORYOBJECTSEXTPROC) (GLsizei n, GLuint *memoryObjects); +typedef void (GL_APIENTRYP PFNGLMEMORYOBJECTPARAMETERIVEXTPROC) (GLuint memoryObject, GLenum pname, const GLint *params); +typedef void (GL_APIENTRYP PFNGLGETMEMORYOBJECTPARAMETERIVEXTPROC) (GLuint memoryObject, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLTEXSTORAGEMEM2DEXTPROC) (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset); +typedef void (GL_APIENTRYP PFNGLTEXSTORAGEMEM2DMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); +typedef void (GL_APIENTRYP PFNGLTEXSTORAGEMEM3DEXTPROC) (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset); +typedef void (GL_APIENTRYP PFNGLTEXSTORAGEMEM3DMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); +typedef void (GL_APIENTRYP PFNGLBUFFERSTORAGEMEMEXTPROC) (GLenum target, GLsizeiptr size, GLuint memory, GLuint64 offset); +typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGEMEM2DEXTPROC) (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset); +typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGEMEM2DMULTISAMPLEEXTPROC) (GLuint texture, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); +typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGEMEM3DEXTPROC) (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset); +typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGEMEM3DMULTISAMPLEEXTPROC) (GLuint texture, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); +typedef void (GL_APIENTRYP PFNGLNAMEDBUFFERSTORAGEMEMEXTPROC) (GLuint buffer, GLsizeiptr size, GLuint memory, GLuint64 offset); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGetUnsignedBytevEXT (GLenum pname, GLubyte *data); +GL_APICALL void GL_APIENTRY glGetUnsignedBytei_vEXT (GLenum target, GLuint index, GLubyte *data); +GL_APICALL void GL_APIENTRY glDeleteMemoryObjectsEXT (GLsizei n, const GLuint *memoryObjects); +GL_APICALL GLboolean GL_APIENTRY glIsMemoryObjectEXT (GLuint memoryObject); +GL_APICALL void GL_APIENTRY glCreateMemoryObjectsEXT (GLsizei n, GLuint *memoryObjects); +GL_APICALL void GL_APIENTRY glMemoryObjectParameterivEXT (GLuint memoryObject, GLenum pname, const GLint *params); +GL_APICALL void GL_APIENTRY glGetMemoryObjectParameterivEXT (GLuint memoryObject, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glTexStorageMem2DEXT (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset); +GL_APICALL void GL_APIENTRY glTexStorageMem2DMultisampleEXT (GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); +GL_APICALL void GL_APIENTRY glTexStorageMem3DEXT (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset); +GL_APICALL void GL_APIENTRY glTexStorageMem3DMultisampleEXT (GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); +GL_APICALL void GL_APIENTRY glBufferStorageMemEXT (GLenum target, GLsizeiptr size, GLuint memory, GLuint64 offset); +GL_APICALL void GL_APIENTRY glTextureStorageMem2DEXT (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset); +GL_APICALL void GL_APIENTRY glTextureStorageMem2DMultisampleEXT (GLuint texture, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); +GL_APICALL void GL_APIENTRY glTextureStorageMem3DEXT (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset); +GL_APICALL void GL_APIENTRY glTextureStorageMem3DMultisampleEXT (GLuint texture, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset); +GL_APICALL void GL_APIENTRY glNamedBufferStorageMemEXT (GLuint buffer, GLsizeiptr size, GLuint memory, GLuint64 offset); +#endif +#endif /* GL_EXT_memory_object */ + +#ifndef GL_EXT_memory_object_fd +#define GL_EXT_memory_object_fd 1 +#define GL_HANDLE_TYPE_OPAQUE_FD_EXT 0x9586 +typedef void (GL_APIENTRYP PFNGLIMPORTMEMORYFDEXTPROC) (GLuint memory, GLuint64 size, GLenum handleType, GLint fd); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glImportMemoryFdEXT (GLuint memory, GLuint64 size, GLenum handleType, GLint fd); +#endif +#endif /* GL_EXT_memory_object_fd */ + +#ifndef GL_EXT_memory_object_win32 +#define GL_EXT_memory_object_win32 1 +#define GL_HANDLE_TYPE_OPAQUE_WIN32_EXT 0x9587 +#define GL_HANDLE_TYPE_OPAQUE_WIN32_KMT_EXT 0x9588 +#define GL_DEVICE_LUID_EXT 0x9599 +#define GL_DEVICE_NODE_MASK_EXT 0x959A +#define GL_LUID_SIZE_EXT 8 +#define GL_HANDLE_TYPE_D3D12_TILEPOOL_EXT 0x9589 +#define GL_HANDLE_TYPE_D3D12_RESOURCE_EXT 0x958A +#define GL_HANDLE_TYPE_D3D11_IMAGE_EXT 0x958B +#define GL_HANDLE_TYPE_D3D11_IMAGE_KMT_EXT 0x958C +typedef void (GL_APIENTRYP PFNGLIMPORTMEMORYWIN32HANDLEEXTPROC) (GLuint memory, GLuint64 size, GLenum handleType, void *handle); +typedef void (GL_APIENTRYP PFNGLIMPORTMEMORYWIN32NAMEEXTPROC) (GLuint memory, GLuint64 size, GLenum handleType, const void *name); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glImportMemoryWin32HandleEXT (GLuint memory, GLuint64 size, GLenum handleType, void *handle); +GL_APICALL void GL_APIENTRY glImportMemoryWin32NameEXT (GLuint memory, GLuint64 size, GLenum handleType, const void *name); +#endif +#endif /* GL_EXT_memory_object_win32 */ + +#ifndef GL_EXT_multi_draw_arrays +#define GL_EXT_multi_draw_arrays 1 +typedef void (GL_APIENTRYP PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); +typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glMultiDrawArraysEXT (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); +GL_APICALL void GL_APIENTRY glMultiDrawElementsEXT (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount); +#endif +#endif /* GL_EXT_multi_draw_arrays */ + +#ifndef GL_EXT_multi_draw_indirect +#define GL_EXT_multi_draw_indirect 1 +typedef void (GL_APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTEXTPROC) (GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride); +typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTEXTPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glMultiDrawArraysIndirectEXT (GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride); +GL_APICALL void GL_APIENTRY glMultiDrawElementsIndirectEXT (GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride); +#endif +#endif /* GL_EXT_multi_draw_indirect */ + +#ifndef GL_EXT_multisampled_compatibility +#define GL_EXT_multisampled_compatibility 1 +#define GL_MULTISAMPLE_EXT 0x809D +#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F +#endif /* GL_EXT_multisampled_compatibility */ + +#ifndef GL_EXT_multisampled_render_to_texture +#define GL_EXT_multisampled_render_to_texture 1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT 0x8D6C +#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 +#define GL_MAX_SAMPLES_EXT 0x8D57 +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleEXT (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glFramebufferTexture2DMultisampleEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); +#endif +#endif /* GL_EXT_multisampled_render_to_texture */ + +#ifndef GL_EXT_multisampled_render_to_texture2 +#define GL_EXT_multisampled_render_to_texture2 1 +#endif /* GL_EXT_multisampled_render_to_texture2 */ + +#ifndef GL_EXT_multiview_draw_buffers +#define GL_EXT_multiview_draw_buffers 1 +#define GL_COLOR_ATTACHMENT_EXT 0x90F0 +#define GL_MULTIVIEW_EXT 0x90F1 +#define GL_DRAW_BUFFER_EXT 0x0C01 +#define GL_READ_BUFFER_EXT 0x0C02 +#define GL_MAX_MULTIVIEW_BUFFERS_EXT 0x90F2 +typedef void (GL_APIENTRYP PFNGLREADBUFFERINDEXEDEXTPROC) (GLenum src, GLint index); +typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSINDEXEDEXTPROC) (GLint n, const GLenum *location, const GLint *indices); +typedef void (GL_APIENTRYP PFNGLGETINTEGERI_VEXTPROC) (GLenum target, GLuint index, GLint *data); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glReadBufferIndexedEXT (GLenum src, GLint index); +GL_APICALL void GL_APIENTRY glDrawBuffersIndexedEXT (GLint n, const GLenum *location, const GLint *indices); +GL_APICALL void GL_APIENTRY glGetIntegeri_vEXT (GLenum target, GLuint index, GLint *data); +#endif +#endif /* GL_EXT_multiview_draw_buffers */ + +#ifndef GL_EXT_multiview_tessellation_geometry_shader +#define GL_EXT_multiview_tessellation_geometry_shader 1 +#endif /* GL_EXT_multiview_tessellation_geometry_shader */ + +#ifndef GL_EXT_multiview_texture_multisample +#define GL_EXT_multiview_texture_multisample 1 +#endif /* GL_EXT_multiview_texture_multisample */ + +#ifndef GL_EXT_multiview_timer_query +#define GL_EXT_multiview_timer_query 1 +#endif /* GL_EXT_multiview_timer_query */ + +#ifndef GL_EXT_occlusion_query_boolean +#define GL_EXT_occlusion_query_boolean 1 +#define GL_ANY_SAMPLES_PASSED_EXT 0x8C2F +#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT 0x8D6A +#endif /* GL_EXT_occlusion_query_boolean */ + +#ifndef GL_EXT_polygon_offset_clamp +#define GL_EXT_polygon_offset_clamp 1 +#define GL_POLYGON_OFFSET_CLAMP_EXT 0x8E1B +typedef void (GL_APIENTRYP PFNGLPOLYGONOFFSETCLAMPEXTPROC) (GLfloat factor, GLfloat units, GLfloat clamp); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glPolygonOffsetClampEXT (GLfloat factor, GLfloat units, GLfloat clamp); +#endif +#endif /* GL_EXT_polygon_offset_clamp */ + +#ifndef GL_EXT_post_depth_coverage +#define GL_EXT_post_depth_coverage 1 +#endif /* GL_EXT_post_depth_coverage */ + +#ifndef GL_EXT_primitive_bounding_box +#define GL_EXT_primitive_bounding_box 1 +#define GL_PRIMITIVE_BOUNDING_BOX_EXT 0x92BE +typedef void (GL_APIENTRYP PFNGLPRIMITIVEBOUNDINGBOXEXTPROC) (GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glPrimitiveBoundingBoxEXT (GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW); +#endif +#endif /* GL_EXT_primitive_bounding_box */ + +#ifndef GL_EXT_protected_textures +#define GL_EXT_protected_textures 1 +#define GL_CONTEXT_FLAG_PROTECTED_CONTENT_BIT_EXT 0x00000010 +#define GL_TEXTURE_PROTECTED_EXT 0x8BFA +#endif /* GL_EXT_protected_textures */ + +#ifndef GL_EXT_pvrtc_sRGB +#define GL_EXT_pvrtc_sRGB 1 +#define GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT 0x8A54 +#define GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT 0x8A55 +#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT 0x8A56 +#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT 0x8A57 +#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV2_IMG 0x93F0 +#define GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV2_IMG 0x93F1 +#endif /* GL_EXT_pvrtc_sRGB */ + +#ifndef GL_EXT_raster_multisample +#define GL_EXT_raster_multisample 1 +#define GL_RASTER_MULTISAMPLE_EXT 0x9327 +#define GL_RASTER_SAMPLES_EXT 0x9328 +#define GL_MAX_RASTER_SAMPLES_EXT 0x9329 +#define GL_RASTER_FIXED_SAMPLE_LOCATIONS_EXT 0x932A +#define GL_MULTISAMPLE_RASTERIZATION_ALLOWED_EXT 0x932B +#define GL_EFFECTIVE_RASTER_SAMPLES_EXT 0x932C +typedef void (GL_APIENTRYP PFNGLRASTERSAMPLESEXTPROC) (GLuint samples, GLboolean fixedsamplelocations); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glRasterSamplesEXT (GLuint samples, GLboolean fixedsamplelocations); +#endif +#endif /* GL_EXT_raster_multisample */ + +#ifndef GL_EXT_read_format_bgra +#define GL_EXT_read_format_bgra 1 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT 0x8365 +#define GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT 0x8366 +#endif /* GL_EXT_read_format_bgra */ + +#ifndef GL_EXT_render_snorm +#define GL_EXT_render_snorm 1 +#define GL_R8_SNORM 0x8F94 +#define GL_RG8_SNORM 0x8F95 +#define GL_RGBA8_SNORM 0x8F97 +#define GL_R16_SNORM_EXT 0x8F98 +#define GL_RG16_SNORM_EXT 0x8F99 +#define GL_RGBA16_SNORM_EXT 0x8F9B +#endif /* GL_EXT_render_snorm */ + +#ifndef GL_EXT_robustness +#define GL_EXT_robustness 1 +#define GL_GUILTY_CONTEXT_RESET_EXT 0x8253 +#define GL_INNOCENT_CONTEXT_RESET_EXT 0x8254 +#define GL_UNKNOWN_CONTEXT_RESET_EXT 0x8255 +#define GL_CONTEXT_ROBUST_ACCESS_EXT 0x90F3 +#define GL_RESET_NOTIFICATION_STRATEGY_EXT 0x8256 +#define GL_LOSE_CONTEXT_ON_RESET_EXT 0x8252 +#define GL_NO_RESET_NOTIFICATION_EXT 0x8261 +typedef GLenum (GL_APIENTRYP PFNGLGETGRAPHICSRESETSTATUSEXTPROC) (void); +typedef void (GL_APIENTRYP PFNGLREADNPIXELSEXTPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); +typedef void (GL_APIENTRYP PFNGLGETNUNIFORMFVEXTPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); +typedef void (GL_APIENTRYP PFNGLGETNUNIFORMIVEXTPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL GLenum GL_APIENTRY glGetGraphicsResetStatusEXT (void); +GL_APICALL void GL_APIENTRY glReadnPixelsEXT (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); +GL_APICALL void GL_APIENTRY glGetnUniformfvEXT (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); +GL_APICALL void GL_APIENTRY glGetnUniformivEXT (GLuint program, GLint location, GLsizei bufSize, GLint *params); +#endif +#endif /* GL_EXT_robustness */ + +#ifndef GL_EXT_sRGB +#define GL_EXT_sRGB 1 +#define GL_SRGB_EXT 0x8C40 +#define GL_SRGB_ALPHA_EXT 0x8C42 +#define GL_SRGB8_ALPHA8_EXT 0x8C43 +#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT 0x8210 +#endif /* GL_EXT_sRGB */ + +#ifndef GL_EXT_sRGB_write_control +#define GL_EXT_sRGB_write_control 1 +#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9 +#endif /* GL_EXT_sRGB_write_control */ + +#ifndef GL_EXT_semaphore +#define GL_EXT_semaphore 1 +#define GL_LAYOUT_GENERAL_EXT 0x958D +#define GL_LAYOUT_COLOR_ATTACHMENT_EXT 0x958E +#define GL_LAYOUT_DEPTH_STENCIL_ATTACHMENT_EXT 0x958F +#define GL_LAYOUT_DEPTH_STENCIL_READ_ONLY_EXT 0x9590 +#define GL_LAYOUT_SHADER_READ_ONLY_EXT 0x9591 +#define GL_LAYOUT_TRANSFER_SRC_EXT 0x9592 +#define GL_LAYOUT_TRANSFER_DST_EXT 0x9593 +#define GL_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_EXT 0x9530 +#define GL_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_EXT 0x9531 +typedef void (GL_APIENTRYP PFNGLGENSEMAPHORESEXTPROC) (GLsizei n, GLuint *semaphores); +typedef void (GL_APIENTRYP PFNGLDELETESEMAPHORESEXTPROC) (GLsizei n, const GLuint *semaphores); +typedef GLboolean (GL_APIENTRYP PFNGLISSEMAPHOREEXTPROC) (GLuint semaphore); +typedef void (GL_APIENTRYP PFNGLSEMAPHOREPARAMETERUI64VEXTPROC) (GLuint semaphore, GLenum pname, const GLuint64 *params); +typedef void (GL_APIENTRYP PFNGLGETSEMAPHOREPARAMETERUI64VEXTPROC) (GLuint semaphore, GLenum pname, GLuint64 *params); +typedef void (GL_APIENTRYP PFNGLWAITSEMAPHOREEXTPROC) (GLuint semaphore, GLuint numBufferBarriers, const GLuint *buffers, GLuint numTextureBarriers, const GLuint *textures, const GLenum *srcLayouts); +typedef void (GL_APIENTRYP PFNGLSIGNALSEMAPHOREEXTPROC) (GLuint semaphore, GLuint numBufferBarriers, const GLuint *buffers, GLuint numTextureBarriers, const GLuint *textures, const GLenum *dstLayouts); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGenSemaphoresEXT (GLsizei n, GLuint *semaphores); +GL_APICALL void GL_APIENTRY glDeleteSemaphoresEXT (GLsizei n, const GLuint *semaphores); +GL_APICALL GLboolean GL_APIENTRY glIsSemaphoreEXT (GLuint semaphore); +GL_APICALL void GL_APIENTRY glSemaphoreParameterui64vEXT (GLuint semaphore, GLenum pname, const GLuint64 *params); +GL_APICALL void GL_APIENTRY glGetSemaphoreParameterui64vEXT (GLuint semaphore, GLenum pname, GLuint64 *params); +GL_APICALL void GL_APIENTRY glWaitSemaphoreEXT (GLuint semaphore, GLuint numBufferBarriers, const GLuint *buffers, GLuint numTextureBarriers, const GLuint *textures, const GLenum *srcLayouts); +GL_APICALL void GL_APIENTRY glSignalSemaphoreEXT (GLuint semaphore, GLuint numBufferBarriers, const GLuint *buffers, GLuint numTextureBarriers, const GLuint *textures, const GLenum *dstLayouts); +#endif +#endif /* GL_EXT_semaphore */ + +#ifndef GL_EXT_semaphore_fd +#define GL_EXT_semaphore_fd 1 +typedef void (GL_APIENTRYP PFNGLIMPORTSEMAPHOREFDEXTPROC) (GLuint semaphore, GLenum handleType, GLint fd); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glImportSemaphoreFdEXT (GLuint semaphore, GLenum handleType, GLint fd); +#endif +#endif /* GL_EXT_semaphore_fd */ + +#ifndef GL_EXT_semaphore_win32 +#define GL_EXT_semaphore_win32 1 +#define GL_HANDLE_TYPE_D3D12_FENCE_EXT 0x9594 +#define GL_D3D12_FENCE_VALUE_EXT 0x9595 +typedef void (GL_APIENTRYP PFNGLIMPORTSEMAPHOREWIN32HANDLEEXTPROC) (GLuint semaphore, GLenum handleType, void *handle); +typedef void (GL_APIENTRYP PFNGLIMPORTSEMAPHOREWIN32NAMEEXTPROC) (GLuint semaphore, GLenum handleType, const void *name); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glImportSemaphoreWin32HandleEXT (GLuint semaphore, GLenum handleType, void *handle); +GL_APICALL void GL_APIENTRY glImportSemaphoreWin32NameEXT (GLuint semaphore, GLenum handleType, const void *name); +#endif +#endif /* GL_EXT_semaphore_win32 */ + +#ifndef GL_EXT_separate_depth_stencil +#define GL_EXT_separate_depth_stencil 1 +#endif /* GL_EXT_separate_depth_stencil */ + +#ifndef GL_EXT_separate_shader_objects +#define GL_EXT_separate_shader_objects 1 +#define GL_ACTIVE_PROGRAM_EXT 0x8259 +#define GL_VERTEX_SHADER_BIT_EXT 0x00000001 +#define GL_FRAGMENT_SHADER_BIT_EXT 0x00000002 +#define GL_ALL_SHADER_BITS_EXT 0xFFFFFFFF +#define GL_PROGRAM_SEPARABLE_EXT 0x8258 +#define GL_PROGRAM_PIPELINE_BINDING_EXT 0x825A +typedef void (GL_APIENTRYP PFNGLACTIVESHADERPROGRAMEXTPROC) (GLuint pipeline, GLuint program); +typedef void (GL_APIENTRYP PFNGLBINDPROGRAMPIPELINEEXTPROC) (GLuint pipeline); +typedef GLuint (GL_APIENTRYP PFNGLCREATESHADERPROGRAMVEXTPROC) (GLenum type, GLsizei count, const GLchar **strings); +typedef void (GL_APIENTRYP PFNGLDELETEPROGRAMPIPELINESEXTPROC) (GLsizei n, const GLuint *pipelines); +typedef void (GL_APIENTRYP PFNGLGENPROGRAMPIPELINESEXTPROC) (GLsizei n, GLuint *pipelines); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMPIPELINEINFOLOGEXTPROC) (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMPIPELINEIVEXTPROC) (GLuint pipeline, GLenum pname, GLint *params); +typedef GLboolean (GL_APIENTRYP PFNGLISPROGRAMPIPELINEEXTPROC) (GLuint pipeline); +typedef void (GL_APIENTRYP PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1FEXTPROC) (GLuint program, GLint location, GLfloat v0); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1IEXTPROC) (GLuint program, GLint location, GLint v0); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUSEPROGRAMSTAGESEXTPROC) (GLuint pipeline, GLbitfield stages, GLuint program); +typedef void (GL_APIENTRYP PFNGLVALIDATEPROGRAMPIPELINEEXTPROC) (GLuint pipeline); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1UIEXTPROC) (GLuint program, GLint location, GLuint v0); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glActiveShaderProgramEXT (GLuint pipeline, GLuint program); +GL_APICALL void GL_APIENTRY glBindProgramPipelineEXT (GLuint pipeline); +GL_APICALL GLuint GL_APIENTRY glCreateShaderProgramvEXT (GLenum type, GLsizei count, const GLchar **strings); +GL_APICALL void GL_APIENTRY glDeleteProgramPipelinesEXT (GLsizei n, const GLuint *pipelines); +GL_APICALL void GL_APIENTRY glGenProgramPipelinesEXT (GLsizei n, GLuint *pipelines); +GL_APICALL void GL_APIENTRY glGetProgramPipelineInfoLogEXT (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +GL_APICALL void GL_APIENTRY glGetProgramPipelineivEXT (GLuint pipeline, GLenum pname, GLint *params); +GL_APICALL GLboolean GL_APIENTRY glIsProgramPipelineEXT (GLuint pipeline); +GL_APICALL void GL_APIENTRY glProgramParameteriEXT (GLuint program, GLenum pname, GLint value); +GL_APICALL void GL_APIENTRY glProgramUniform1fEXT (GLuint program, GLint location, GLfloat v0); +GL_APICALL void GL_APIENTRY glProgramUniform1fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniform1iEXT (GLuint program, GLint location, GLint v0); +GL_APICALL void GL_APIENTRY glProgramUniform1ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniform2fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1); +GL_APICALL void GL_APIENTRY glProgramUniform2fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniform2iEXT (GLuint program, GLint location, GLint v0, GLint v1); +GL_APICALL void GL_APIENTRY glProgramUniform2ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniform3fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +GL_APICALL void GL_APIENTRY glProgramUniform3fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniform3iEXT (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); +GL_APICALL void GL_APIENTRY glProgramUniform3ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniform4fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +GL_APICALL void GL_APIENTRY glProgramUniform4fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniform4iEXT (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +GL_APICALL void GL_APIENTRY glProgramUniform4ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUseProgramStagesEXT (GLuint pipeline, GLbitfield stages, GLuint program); +GL_APICALL void GL_APIENTRY glValidateProgramPipelineEXT (GLuint pipeline); +GL_APICALL void GL_APIENTRY glProgramUniform1uiEXT (GLuint program, GLint location, GLuint v0); +GL_APICALL void GL_APIENTRY glProgramUniform2uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1); +GL_APICALL void GL_APIENTRY glProgramUniform3uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); +GL_APICALL void GL_APIENTRY glProgramUniform4uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +GL_APICALL void GL_APIENTRY glProgramUniform1uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glProgramUniform2uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glProgramUniform3uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glProgramUniform4uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix2x3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix3x2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix2x4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix4x2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix3x4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix4x3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +#endif +#endif /* GL_EXT_separate_shader_objects */ + +#ifndef GL_EXT_shader_framebuffer_fetch +#define GL_EXT_shader_framebuffer_fetch 1 +#define GL_FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT 0x8A52 +#endif /* GL_EXT_shader_framebuffer_fetch */ + +#ifndef GL_EXT_shader_framebuffer_fetch_non_coherent +#define GL_EXT_shader_framebuffer_fetch_non_coherent 1 +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERFETCHBARRIEREXTPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glFramebufferFetchBarrierEXT (void); +#endif +#endif /* GL_EXT_shader_framebuffer_fetch_non_coherent */ + +#ifndef GL_EXT_shader_group_vote +#define GL_EXT_shader_group_vote 1 +#endif /* GL_EXT_shader_group_vote */ + +#ifndef GL_EXT_shader_implicit_conversions +#define GL_EXT_shader_implicit_conversions 1 +#endif /* GL_EXT_shader_implicit_conversions */ + +#ifndef GL_EXT_shader_integer_mix +#define GL_EXT_shader_integer_mix 1 +#endif /* GL_EXT_shader_integer_mix */ + +#ifndef GL_EXT_shader_io_blocks +#define GL_EXT_shader_io_blocks 1 +#endif /* GL_EXT_shader_io_blocks */ + +#ifndef GL_EXT_shader_non_constant_global_initializers +#define GL_EXT_shader_non_constant_global_initializers 1 +#endif /* GL_EXT_shader_non_constant_global_initializers */ + +#ifndef GL_EXT_shader_pixel_local_storage +#define GL_EXT_shader_pixel_local_storage 1 +#define GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_FAST_SIZE_EXT 0x8F63 +#define GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_SIZE_EXT 0x8F67 +#define GL_SHADER_PIXEL_LOCAL_STORAGE_EXT 0x8F64 +#endif /* GL_EXT_shader_pixel_local_storage */ + +#ifndef GL_EXT_shader_pixel_local_storage2 +#define GL_EXT_shader_pixel_local_storage2 1 +#define GL_MAX_SHADER_COMBINED_LOCAL_STORAGE_FAST_SIZE_EXT 0x9650 +#define GL_MAX_SHADER_COMBINED_LOCAL_STORAGE_SIZE_EXT 0x9651 +#define GL_FRAMEBUFFER_INCOMPLETE_INSUFFICIENT_SHADER_COMBINED_LOCAL_STORAGE_EXT 0x9652 +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC) (GLuint target, GLsizei size); +typedef GLsizei (GL_APIENTRYP PFNGLGETFRAMEBUFFERPIXELLOCALSTORAGESIZEEXTPROC) (GLuint target); +typedef void (GL_APIENTRYP PFNGLCLEARPIXELLOCALSTORAGEUIEXTPROC) (GLsizei offset, GLsizei n, const GLuint *values); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glFramebufferPixelLocalStorageSizeEXT (GLuint target, GLsizei size); +GL_APICALL GLsizei GL_APIENTRY glGetFramebufferPixelLocalStorageSizeEXT (GLuint target); +GL_APICALL void GL_APIENTRY glClearPixelLocalStorageuiEXT (GLsizei offset, GLsizei n, const GLuint *values); +#endif +#endif /* GL_EXT_shader_pixel_local_storage2 */ + +#ifndef GL_EXT_shader_samples_identical +#define GL_EXT_shader_samples_identical 1 +#endif /* GL_EXT_shader_samples_identical */ + +#ifndef GL_EXT_shader_texture_lod +#define GL_EXT_shader_texture_lod 1 +#endif /* GL_EXT_shader_texture_lod */ + +#ifndef GL_EXT_shadow_samplers +#define GL_EXT_shadow_samplers 1 +#define GL_TEXTURE_COMPARE_MODE_EXT 0x884C +#define GL_TEXTURE_COMPARE_FUNC_EXT 0x884D +#define GL_COMPARE_REF_TO_TEXTURE_EXT 0x884E +#define GL_SAMPLER_2D_SHADOW_EXT 0x8B62 +#endif /* GL_EXT_shadow_samplers */ + +#ifndef GL_EXT_sparse_texture +#define GL_EXT_sparse_texture 1 +#define GL_TEXTURE_SPARSE_EXT 0x91A6 +#define GL_VIRTUAL_PAGE_SIZE_INDEX_EXT 0x91A7 +#define GL_NUM_SPARSE_LEVELS_EXT 0x91AA +#define GL_NUM_VIRTUAL_PAGE_SIZES_EXT 0x91A8 +#define GL_VIRTUAL_PAGE_SIZE_X_EXT 0x9195 +#define GL_VIRTUAL_PAGE_SIZE_Y_EXT 0x9196 +#define GL_VIRTUAL_PAGE_SIZE_Z_EXT 0x9197 +#define GL_TEXTURE_2D_ARRAY 0x8C1A +#define GL_TEXTURE_3D 0x806F +#define GL_MAX_SPARSE_TEXTURE_SIZE_EXT 0x9198 +#define GL_MAX_SPARSE_3D_TEXTURE_SIZE_EXT 0x9199 +#define GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_EXT 0x919A +#define GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_EXT 0x91A9 +typedef void (GL_APIENTRYP PFNGLTEXPAGECOMMITMENTEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glTexPageCommitmentEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLboolean commit); +#endif +#endif /* GL_EXT_sparse_texture */ + +#ifndef GL_EXT_sparse_texture2 +#define GL_EXT_sparse_texture2 1 +#endif /* GL_EXT_sparse_texture2 */ + +#ifndef GL_EXT_tessellation_point_size +#define GL_EXT_tessellation_point_size 1 +#endif /* GL_EXT_tessellation_point_size */ + +#ifndef GL_EXT_tessellation_shader +#define GL_EXT_tessellation_shader 1 +#define GL_PATCHES_EXT 0x000E +#define GL_PATCH_VERTICES_EXT 0x8E72 +#define GL_TESS_CONTROL_OUTPUT_VERTICES_EXT 0x8E75 +#define GL_TESS_GEN_MODE_EXT 0x8E76 +#define GL_TESS_GEN_SPACING_EXT 0x8E77 +#define GL_TESS_GEN_VERTEX_ORDER_EXT 0x8E78 +#define GL_TESS_GEN_POINT_MODE_EXT 0x8E79 +#define GL_ISOLINES_EXT 0x8E7A +#define GL_QUADS_EXT 0x0007 +#define GL_FRACTIONAL_ODD_EXT 0x8E7B +#define GL_FRACTIONAL_EVEN_EXT 0x8E7C +#define GL_MAX_PATCH_VERTICES_EXT 0x8E7D +#define GL_MAX_TESS_GEN_LEVEL_EXT 0x8E7E +#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS_EXT 0x8E7F +#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT 0x8E80 +#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_EXT 0x8E81 +#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_EXT 0x8E82 +#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_EXT 0x8E83 +#define GL_MAX_TESS_PATCH_COMPONENTS_EXT 0x8E84 +#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_EXT 0x8E85 +#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_EXT 0x8E86 +#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS_EXT 0x8E89 +#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS_EXT 0x8E8A +#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_EXT 0x886C +#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_EXT 0x886D +#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_EXT 0x8E1E +#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT 0x8E1F +#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_EXT 0x92CD +#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_EXT 0x92CE +#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS_EXT 0x92D3 +#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS_EXT 0x92D4 +#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS_EXT 0x90CB +#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS_EXT 0x90CC +#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_EXT 0x90D8 +#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_EXT 0x90D9 +#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED 0x8221 +#define GL_IS_PER_PATCH_EXT 0x92E7 +#define GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT 0x9307 +#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT 0x9308 +#define GL_TESS_CONTROL_SHADER_EXT 0x8E88 +#define GL_TESS_EVALUATION_SHADER_EXT 0x8E87 +#define GL_TESS_CONTROL_SHADER_BIT_EXT 0x00000008 +#define GL_TESS_EVALUATION_SHADER_BIT_EXT 0x00000010 +typedef void (GL_APIENTRYP PFNGLPATCHPARAMETERIEXTPROC) (GLenum pname, GLint value); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glPatchParameteriEXT (GLenum pname, GLint value); +#endif +#endif /* GL_EXT_tessellation_shader */ + +#ifndef GL_EXT_texture_border_clamp +#define GL_EXT_texture_border_clamp 1 +#define GL_TEXTURE_BORDER_COLOR_EXT 0x1004 +#define GL_CLAMP_TO_BORDER_EXT 0x812D +typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); +typedef void (GL_APIENTRYP PFNGLTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, const GLuint *params); +typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, GLuint *params); +typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIIVEXTPROC) (GLuint sampler, GLenum pname, const GLint *param); +typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIUIVEXTPROC) (GLuint sampler, GLenum pname, const GLuint *param); +typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIIVEXTPROC) (GLuint sampler, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIUIVEXTPROC) (GLuint sampler, GLenum pname, GLuint *params); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glTexParameterIivEXT (GLenum target, GLenum pname, const GLint *params); +GL_APICALL void GL_APIENTRY glTexParameterIuivEXT (GLenum target, GLenum pname, const GLuint *params); +GL_APICALL void GL_APIENTRY glGetTexParameterIivEXT (GLenum target, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetTexParameterIuivEXT (GLenum target, GLenum pname, GLuint *params); +GL_APICALL void GL_APIENTRY glSamplerParameterIivEXT (GLuint sampler, GLenum pname, const GLint *param); +GL_APICALL void GL_APIENTRY glSamplerParameterIuivEXT (GLuint sampler, GLenum pname, const GLuint *param); +GL_APICALL void GL_APIENTRY glGetSamplerParameterIivEXT (GLuint sampler, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetSamplerParameterIuivEXT (GLuint sampler, GLenum pname, GLuint *params); +#endif +#endif /* GL_EXT_texture_border_clamp */ + +#ifndef GL_EXT_texture_buffer +#define GL_EXT_texture_buffer 1 +#define GL_TEXTURE_BUFFER_EXT 0x8C2A +#define GL_TEXTURE_BUFFER_BINDING_EXT 0x8C2A +#define GL_MAX_TEXTURE_BUFFER_SIZE_EXT 0x8C2B +#define GL_TEXTURE_BINDING_BUFFER_EXT 0x8C2C +#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D +#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT_EXT 0x919F +#define GL_SAMPLER_BUFFER_EXT 0x8DC2 +#define GL_INT_SAMPLER_BUFFER_EXT 0x8DD0 +#define GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8 +#define GL_IMAGE_BUFFER_EXT 0x9051 +#define GL_INT_IMAGE_BUFFER_EXT 0x905C +#define GL_UNSIGNED_INT_IMAGE_BUFFER_EXT 0x9067 +#define GL_TEXTURE_BUFFER_OFFSET_EXT 0x919D +#define GL_TEXTURE_BUFFER_SIZE_EXT 0x919E +typedef void (GL_APIENTRYP PFNGLTEXBUFFEREXTPROC) (GLenum target, GLenum internalformat, GLuint buffer); +typedef void (GL_APIENTRYP PFNGLTEXBUFFERRANGEEXTPROC) (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glTexBufferEXT (GLenum target, GLenum internalformat, GLuint buffer); +GL_APICALL void GL_APIENTRY glTexBufferRangeEXT (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); +#endif +#endif /* GL_EXT_texture_buffer */ + +#ifndef GL_EXT_texture_compression_astc_decode_mode +#define GL_EXT_texture_compression_astc_decode_mode 1 +#define GL_TEXTURE_ASTC_DECODE_PRECISION_EXT 0x8F69 +#endif /* GL_EXT_texture_compression_astc_decode_mode */ + +#ifndef GL_EXT_texture_compression_bptc +#define GL_EXT_texture_compression_bptc 1 +#define GL_COMPRESSED_RGBA_BPTC_UNORM_EXT 0x8E8C +#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT 0x8E8D +#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT 0x8E8E +#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT 0x8E8F +#endif /* GL_EXT_texture_compression_bptc */ + +#ifndef GL_EXT_texture_compression_dxt1 +#define GL_EXT_texture_compression_dxt1 1 +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 +#endif /* GL_EXT_texture_compression_dxt1 */ + +#ifndef GL_EXT_texture_compression_rgtc +#define GL_EXT_texture_compression_rgtc 1 +#define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB +#define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC +#define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD +#define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE +#endif /* GL_EXT_texture_compression_rgtc */ + +#ifndef GL_EXT_texture_compression_s3tc +#define GL_EXT_texture_compression_s3tc 1 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 +#endif /* GL_EXT_texture_compression_s3tc */ + +#ifndef GL_EXT_texture_compression_s3tc_srgb +#define GL_EXT_texture_compression_s3tc_srgb 1 +#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F +#endif /* GL_EXT_texture_compression_s3tc_srgb */ + +#ifndef GL_EXT_texture_cube_map_array +#define GL_EXT_texture_cube_map_array 1 +#define GL_TEXTURE_CUBE_MAP_ARRAY_EXT 0x9009 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_EXT 0x900A +#define GL_SAMPLER_CUBE_MAP_ARRAY_EXT 0x900C +#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_EXT 0x900D +#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_EXT 0x900E +#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_EXT 0x900F +#define GL_IMAGE_CUBE_MAP_ARRAY_EXT 0x9054 +#define GL_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x905F +#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x906A +#endif /* GL_EXT_texture_cube_map_array */ + +#ifndef GL_EXT_texture_filter_anisotropic +#define GL_EXT_texture_filter_anisotropic 1 +#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE +#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF +#endif /* GL_EXT_texture_filter_anisotropic */ + +#ifndef GL_EXT_texture_filter_minmax +#define GL_EXT_texture_filter_minmax 1 +#define GL_TEXTURE_REDUCTION_MODE_EXT 0x9366 +#define GL_WEIGHTED_AVERAGE_EXT 0x9367 +#endif /* GL_EXT_texture_filter_minmax */ + +#ifndef GL_EXT_texture_format_BGRA8888 +#define GL_EXT_texture_format_BGRA8888 1 +#endif /* GL_EXT_texture_format_BGRA8888 */ + +#ifndef GL_EXT_texture_format_sRGB_override +#define GL_EXT_texture_format_sRGB_override 1 +#define GL_TEXTURE_FORMAT_SRGB_OVERRIDE_EXT 0x8FBF +#endif /* GL_EXT_texture_format_sRGB_override */ + +#ifndef GL_EXT_texture_mirror_clamp_to_edge +#define GL_EXT_texture_mirror_clamp_to_edge 1 +#define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743 +#endif /* GL_EXT_texture_mirror_clamp_to_edge */ + +#ifndef GL_EXT_texture_norm16 +#define GL_EXT_texture_norm16 1 +#define GL_R16_EXT 0x822A +#define GL_RG16_EXT 0x822C +#define GL_RGBA16_EXT 0x805B +#define GL_RGB16_EXT 0x8054 +#define GL_RGB16_SNORM_EXT 0x8F9A +#endif /* GL_EXT_texture_norm16 */ + +#ifndef GL_EXT_texture_query_lod +#define GL_EXT_texture_query_lod 1 +#endif /* GL_EXT_texture_query_lod */ + +#ifndef GL_EXT_texture_rg +#define GL_EXT_texture_rg 1 +#define GL_RED_EXT 0x1903 +#define GL_RG_EXT 0x8227 +#define GL_R8_EXT 0x8229 +#define GL_RG8_EXT 0x822B +#endif /* GL_EXT_texture_rg */ + +#ifndef GL_EXT_texture_sRGB_R8 +#define GL_EXT_texture_sRGB_R8 1 +#define GL_SR8_EXT 0x8FBD +#endif /* GL_EXT_texture_sRGB_R8 */ + +#ifndef GL_EXT_texture_sRGB_RG8 +#define GL_EXT_texture_sRGB_RG8 1 +#define GL_SRG8_EXT 0x8FBE +#endif /* GL_EXT_texture_sRGB_RG8 */ + +#ifndef GL_EXT_texture_sRGB_decode +#define GL_EXT_texture_sRGB_decode 1 +#define GL_TEXTURE_SRGB_DECODE_EXT 0x8A48 +#define GL_DECODE_EXT 0x8A49 +#define GL_SKIP_DECODE_EXT 0x8A4A +#endif /* GL_EXT_texture_sRGB_decode */ + +#ifndef GL_EXT_texture_shadow_lod +#define GL_EXT_texture_shadow_lod 1 +#endif /* GL_EXT_texture_shadow_lod */ + +#ifndef GL_EXT_texture_storage +#define GL_EXT_texture_storage 1 +#define GL_TEXTURE_IMMUTABLE_FORMAT_EXT 0x912F +#define GL_ALPHA8_EXT 0x803C +#define GL_LUMINANCE8_EXT 0x8040 +#define GL_LUMINANCE8_ALPHA8_EXT 0x8045 +#define GL_RGBA32F_EXT 0x8814 +#define GL_RGB32F_EXT 0x8815 +#define GL_ALPHA32F_EXT 0x8816 +#define GL_LUMINANCE32F_EXT 0x8818 +#define GL_LUMINANCE_ALPHA32F_EXT 0x8819 +#define GL_ALPHA16F_EXT 0x881C +#define GL_LUMINANCE16F_EXT 0x881E +#define GL_LUMINANCE_ALPHA16F_EXT 0x881F +#define GL_R32F_EXT 0x822E +#define GL_RG32F_EXT 0x8230 +typedef void (GL_APIENTRYP PFNGLTEXSTORAGE1DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +typedef void (GL_APIENTRYP PFNGLTEXSTORAGE2DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLTEXSTORAGE3DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE1DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE2DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE3DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glTexStorage1DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +GL_APICALL void GL_APIENTRY glTexStorage2DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glTexStorage3DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +GL_APICALL void GL_APIENTRY glTextureStorage1DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +GL_APICALL void GL_APIENTRY glTextureStorage2DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glTextureStorage3DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +#endif +#endif /* GL_EXT_texture_storage */ + +#ifndef GL_EXT_texture_storage_compression +#define GL_EXT_texture_storage_compression 1 +#define GL_NUM_SURFACE_COMPRESSION_FIXED_RATES_EXT 0x8F6E +#define GL_SURFACE_COMPRESSION_FIXED_RATE_1BPC_EXT 0x96C4 +#define GL_SURFACE_COMPRESSION_FIXED_RATE_2BPC_EXT 0x96C5 +#define GL_SURFACE_COMPRESSION_FIXED_RATE_3BPC_EXT 0x96C6 +#define GL_SURFACE_COMPRESSION_FIXED_RATE_4BPC_EXT 0x96C7 +#define GL_SURFACE_COMPRESSION_FIXED_RATE_5BPC_EXT 0x96C8 +#define GL_SURFACE_COMPRESSION_FIXED_RATE_6BPC_EXT 0x96C9 +#define GL_SURFACE_COMPRESSION_FIXED_RATE_7BPC_EXT 0x96CA +#define GL_SURFACE_COMPRESSION_FIXED_RATE_8BPC_EXT 0x96CB +#define GL_SURFACE_COMPRESSION_FIXED_RATE_9BPC_EXT 0x96CC +#define GL_SURFACE_COMPRESSION_FIXED_RATE_10BPC_EXT 0x96CD +#define GL_SURFACE_COMPRESSION_FIXED_RATE_11BPC_EXT 0x96CE +#define GL_SURFACE_COMPRESSION_FIXED_RATE_12BPC_EXT 0x96CF +typedef void (GL_APIENTRYP PFNGLTEXSTORAGEATTRIBS2DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, const GLint* attrib_list); +typedef void (GL_APIENTRYP PFNGLTEXSTORAGEATTRIBS3DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, const GLint* attrib_list); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glTexStorageAttribs2DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, const GLint* attrib_list); +GL_APICALL void GL_APIENTRY glTexStorageAttribs3DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, const GLint* attrib_list); +#endif +#endif /* GL_EXT_texture_storage_compression */ + +#ifndef GL_EXT_texture_type_2_10_10_10_REV +#define GL_EXT_texture_type_2_10_10_10_REV 1 +#define GL_UNSIGNED_INT_2_10_10_10_REV_EXT 0x8368 +#endif /* GL_EXT_texture_type_2_10_10_10_REV */ + +#ifndef GL_EXT_texture_view +#define GL_EXT_texture_view 1 +#define GL_TEXTURE_VIEW_MIN_LEVEL_EXT 0x82DB +#define GL_TEXTURE_VIEW_NUM_LEVELS_EXT 0x82DC +#define GL_TEXTURE_VIEW_MIN_LAYER_EXT 0x82DD +#define GL_TEXTURE_VIEW_NUM_LAYERS_EXT 0x82DE +typedef void (GL_APIENTRYP PFNGLTEXTUREVIEWEXTPROC) (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glTextureViewEXT (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers); +#endif +#endif /* GL_EXT_texture_view */ + +#ifndef GL_EXT_unpack_subimage +#define GL_EXT_unpack_subimage 1 +#define GL_UNPACK_ROW_LENGTH_EXT 0x0CF2 +#define GL_UNPACK_SKIP_ROWS_EXT 0x0CF3 +#define GL_UNPACK_SKIP_PIXELS_EXT 0x0CF4 +#endif /* GL_EXT_unpack_subimage */ + +#ifndef GL_EXT_win32_keyed_mutex +#define GL_EXT_win32_keyed_mutex 1 +typedef GLboolean (GL_APIENTRYP PFNGLACQUIREKEYEDMUTEXWIN32EXTPROC) (GLuint memory, GLuint64 key, GLuint timeout); +typedef GLboolean (GL_APIENTRYP PFNGLRELEASEKEYEDMUTEXWIN32EXTPROC) (GLuint memory, GLuint64 key); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL GLboolean GL_APIENTRY glAcquireKeyedMutexWin32EXT (GLuint memory, GLuint64 key, GLuint timeout); +GL_APICALL GLboolean GL_APIENTRY glReleaseKeyedMutexWin32EXT (GLuint memory, GLuint64 key); +#endif +#endif /* GL_EXT_win32_keyed_mutex */ + +#ifndef GL_EXT_window_rectangles +#define GL_EXT_window_rectangles 1 +#define GL_INCLUSIVE_EXT 0x8F10 +#define GL_EXCLUSIVE_EXT 0x8F11 +#define GL_WINDOW_RECTANGLE_EXT 0x8F12 +#define GL_WINDOW_RECTANGLE_MODE_EXT 0x8F13 +#define GL_MAX_WINDOW_RECTANGLES_EXT 0x8F14 +#define GL_NUM_WINDOW_RECTANGLES_EXT 0x8F15 +typedef void (GL_APIENTRYP PFNGLWINDOWRECTANGLESEXTPROC) (GLenum mode, GLsizei count, const GLint *box); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glWindowRectanglesEXT (GLenum mode, GLsizei count, const GLint *box); +#endif +#endif /* GL_EXT_window_rectangles */ + +#ifndef GL_FJ_shader_binary_GCCSO +#define GL_FJ_shader_binary_GCCSO 1 +#define GL_GCCSO_SHADER_BINARY_FJ 0x9260 +#endif /* GL_FJ_shader_binary_GCCSO */ + +#ifndef GL_IMG_bindless_texture +#define GL_IMG_bindless_texture 1 +typedef GLuint64 (GL_APIENTRYP PFNGLGETTEXTUREHANDLEIMGPROC) (GLuint texture); +typedef GLuint64 (GL_APIENTRYP PFNGLGETTEXTURESAMPLERHANDLEIMGPROC) (GLuint texture, GLuint sampler); +typedef void (GL_APIENTRYP PFNGLUNIFORMHANDLEUI64IMGPROC) (GLint location, GLuint64 value); +typedef void (GL_APIENTRYP PFNGLUNIFORMHANDLEUI64VIMGPROC) (GLint location, GLsizei count, const GLuint64 *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64IMGPROC) (GLuint program, GLint location, GLuint64 value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64VIMGPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 *values); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL GLuint64 GL_APIENTRY glGetTextureHandleIMG (GLuint texture); +GL_APICALL GLuint64 GL_APIENTRY glGetTextureSamplerHandleIMG (GLuint texture, GLuint sampler); +GL_APICALL void GL_APIENTRY glUniformHandleui64IMG (GLint location, GLuint64 value); +GL_APICALL void GL_APIENTRY glUniformHandleui64vIMG (GLint location, GLsizei count, const GLuint64 *value); +GL_APICALL void GL_APIENTRY glProgramUniformHandleui64IMG (GLuint program, GLint location, GLuint64 value); +GL_APICALL void GL_APIENTRY glProgramUniformHandleui64vIMG (GLuint program, GLint location, GLsizei count, const GLuint64 *values); +#endif +#endif /* GL_IMG_bindless_texture */ + +#ifndef GL_IMG_framebuffer_downsample +#define GL_IMG_framebuffer_downsample 1 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_AND_DOWNSAMPLE_IMG 0x913C +#define GL_NUM_DOWNSAMPLE_SCALES_IMG 0x913D +#define GL_DOWNSAMPLE_SCALES_IMG 0x913E +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SCALE_IMG 0x913F +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DDOWNSAMPLEIMGPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint xscale, GLint yscale); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERDOWNSAMPLEIMGPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer, GLint xscale, GLint yscale); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glFramebufferTexture2DDownsampleIMG (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint xscale, GLint yscale); +GL_APICALL void GL_APIENTRY glFramebufferTextureLayerDownsampleIMG (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer, GLint xscale, GLint yscale); +#endif +#endif /* GL_IMG_framebuffer_downsample */ + +#ifndef GL_IMG_multisampled_render_to_texture +#define GL_IMG_multisampled_render_to_texture 1 +#define GL_RENDERBUFFER_SAMPLES_IMG 0x9133 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG 0x9134 +#define GL_MAX_SAMPLES_IMG 0x9135 +#define GL_TEXTURE_SAMPLES_IMG 0x9136 +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEIMGPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMGPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleIMG (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glFramebufferTexture2DMultisampleIMG (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); +#endif +#endif /* GL_IMG_multisampled_render_to_texture */ + +#ifndef GL_IMG_program_binary +#define GL_IMG_program_binary 1 +#define GL_SGX_PROGRAM_BINARY_IMG 0x9130 +#endif /* GL_IMG_program_binary */ + +#ifndef GL_IMG_read_format +#define GL_IMG_read_format 1 +#define GL_BGRA_IMG 0x80E1 +#define GL_UNSIGNED_SHORT_4_4_4_4_REV_IMG 0x8365 +#endif /* GL_IMG_read_format */ + +#ifndef GL_IMG_shader_binary +#define GL_IMG_shader_binary 1 +#define GL_SGX_BINARY_IMG 0x8C0A +#endif /* GL_IMG_shader_binary */ + +#ifndef GL_IMG_texture_compression_pvrtc +#define GL_IMG_texture_compression_pvrtc 1 +#define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00 +#define GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG 0x8C01 +#define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02 +#define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8C03 +#endif /* GL_IMG_texture_compression_pvrtc */ + +#ifndef GL_IMG_texture_compression_pvrtc2 +#define GL_IMG_texture_compression_pvrtc2 1 +#define GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG 0x9137 +#define GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG 0x9138 +#endif /* GL_IMG_texture_compression_pvrtc2 */ + +#ifndef GL_IMG_texture_filter_cubic +#define GL_IMG_texture_filter_cubic 1 +#define GL_CUBIC_IMG 0x9139 +#define GL_CUBIC_MIPMAP_NEAREST_IMG 0x913A +#define GL_CUBIC_MIPMAP_LINEAR_IMG 0x913B +#endif /* GL_IMG_texture_filter_cubic */ + +#ifndef GL_INTEL_blackhole_render +#define GL_INTEL_blackhole_render 1 +#define GL_BLACKHOLE_RENDER_INTEL 0x83FC +#endif /* GL_INTEL_blackhole_render */ + +#ifndef GL_INTEL_conservative_rasterization +#define GL_INTEL_conservative_rasterization 1 +#define GL_CONSERVATIVE_RASTERIZATION_INTEL 0x83FE +#endif /* GL_INTEL_conservative_rasterization */ + +#ifndef GL_INTEL_framebuffer_CMAA +#define GL_INTEL_framebuffer_CMAA 1 +typedef void (GL_APIENTRYP PFNGLAPPLYFRAMEBUFFERATTACHMENTCMAAINTELPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glApplyFramebufferAttachmentCMAAINTEL (void); +#endif +#endif /* GL_INTEL_framebuffer_CMAA */ + +#ifndef GL_INTEL_performance_query +#define GL_INTEL_performance_query 1 +#define GL_PERFQUERY_SINGLE_CONTEXT_INTEL 0x00000000 +#define GL_PERFQUERY_GLOBAL_CONTEXT_INTEL 0x00000001 +#define GL_PERFQUERY_WAIT_INTEL 0x83FB +#define GL_PERFQUERY_FLUSH_INTEL 0x83FA +#define GL_PERFQUERY_DONOT_FLUSH_INTEL 0x83F9 +#define GL_PERFQUERY_COUNTER_EVENT_INTEL 0x94F0 +#define GL_PERFQUERY_COUNTER_DURATION_NORM_INTEL 0x94F1 +#define GL_PERFQUERY_COUNTER_DURATION_RAW_INTEL 0x94F2 +#define GL_PERFQUERY_COUNTER_THROUGHPUT_INTEL 0x94F3 +#define GL_PERFQUERY_COUNTER_RAW_INTEL 0x94F4 +#define GL_PERFQUERY_COUNTER_TIMESTAMP_INTEL 0x94F5 +#define GL_PERFQUERY_COUNTER_DATA_UINT32_INTEL 0x94F8 +#define GL_PERFQUERY_COUNTER_DATA_UINT64_INTEL 0x94F9 +#define GL_PERFQUERY_COUNTER_DATA_FLOAT_INTEL 0x94FA +#define GL_PERFQUERY_COUNTER_DATA_DOUBLE_INTEL 0x94FB +#define GL_PERFQUERY_COUNTER_DATA_BOOL32_INTEL 0x94FC +#define GL_PERFQUERY_QUERY_NAME_LENGTH_MAX_INTEL 0x94FD +#define GL_PERFQUERY_COUNTER_NAME_LENGTH_MAX_INTEL 0x94FE +#define GL_PERFQUERY_COUNTER_DESC_LENGTH_MAX_INTEL 0x94FF +#define GL_PERFQUERY_GPA_EXTENDED_COUNTERS_INTEL 0x9500 +typedef void (GL_APIENTRYP PFNGLBEGINPERFQUERYINTELPROC) (GLuint queryHandle); +typedef void (GL_APIENTRYP PFNGLCREATEPERFQUERYINTELPROC) (GLuint queryId, GLuint *queryHandle); +typedef void (GL_APIENTRYP PFNGLDELETEPERFQUERYINTELPROC) (GLuint queryHandle); +typedef void (GL_APIENTRYP PFNGLENDPERFQUERYINTELPROC) (GLuint queryHandle); +typedef void (GL_APIENTRYP PFNGLGETFIRSTPERFQUERYIDINTELPROC) (GLuint *queryId); +typedef void (GL_APIENTRYP PFNGLGETNEXTPERFQUERYIDINTELPROC) (GLuint queryId, GLuint *nextQueryId); +typedef void (GL_APIENTRYP PFNGLGETPERFCOUNTERINFOINTELPROC) (GLuint queryId, GLuint counterId, GLuint counterNameLength, GLchar *counterName, GLuint counterDescLength, GLchar *counterDesc, GLuint *counterOffset, GLuint *counterDataSize, GLuint *counterTypeEnum, GLuint *counterDataTypeEnum, GLuint64 *rawCounterMaxValue); +typedef void (GL_APIENTRYP PFNGLGETPERFQUERYDATAINTELPROC) (GLuint queryHandle, GLuint flags, GLsizei dataSize, void *data, GLuint *bytesWritten); +typedef void (GL_APIENTRYP PFNGLGETPERFQUERYIDBYNAMEINTELPROC) (GLchar *queryName, GLuint *queryId); +typedef void (GL_APIENTRYP PFNGLGETPERFQUERYINFOINTELPROC) (GLuint queryId, GLuint queryNameLength, GLchar *queryName, GLuint *dataSize, GLuint *noCounters, GLuint *noInstances, GLuint *capsMask); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glBeginPerfQueryINTEL (GLuint queryHandle); +GL_APICALL void GL_APIENTRY glCreatePerfQueryINTEL (GLuint queryId, GLuint *queryHandle); +GL_APICALL void GL_APIENTRY glDeletePerfQueryINTEL (GLuint queryHandle); +GL_APICALL void GL_APIENTRY glEndPerfQueryINTEL (GLuint queryHandle); +GL_APICALL void GL_APIENTRY glGetFirstPerfQueryIdINTEL (GLuint *queryId); +GL_APICALL void GL_APIENTRY glGetNextPerfQueryIdINTEL (GLuint queryId, GLuint *nextQueryId); +GL_APICALL void GL_APIENTRY glGetPerfCounterInfoINTEL (GLuint queryId, GLuint counterId, GLuint counterNameLength, GLchar *counterName, GLuint counterDescLength, GLchar *counterDesc, GLuint *counterOffset, GLuint *counterDataSize, GLuint *counterTypeEnum, GLuint *counterDataTypeEnum, GLuint64 *rawCounterMaxValue); +GL_APICALL void GL_APIENTRY glGetPerfQueryDataINTEL (GLuint queryHandle, GLuint flags, GLsizei dataSize, void *data, GLuint *bytesWritten); +GL_APICALL void GL_APIENTRY glGetPerfQueryIdByNameINTEL (GLchar *queryName, GLuint *queryId); +GL_APICALL void GL_APIENTRY glGetPerfQueryInfoINTEL (GLuint queryId, GLuint queryNameLength, GLchar *queryName, GLuint *dataSize, GLuint *noCounters, GLuint *noInstances, GLuint *capsMask); +#endif +#endif /* GL_INTEL_performance_query */ + +#ifndef GL_MESA_bgra +#define GL_MESA_bgra 1 +#define GL_BGR_EXT 0x80E0 +#endif /* GL_MESA_bgra */ + +#ifndef GL_MESA_framebuffer_flip_x +#define GL_MESA_framebuffer_flip_x 1 +#define GL_FRAMEBUFFER_FLIP_X_MESA 0x8BBC +#endif /* GL_MESA_framebuffer_flip_x */ + +#ifndef GL_MESA_framebuffer_flip_y +#define GL_MESA_framebuffer_flip_y 1 +#define GL_FRAMEBUFFER_FLIP_Y_MESA 0x8BBB +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERPARAMETERIMESAPROC) (GLenum target, GLenum pname, GLint param); +typedef void (GL_APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVMESAPROC) (GLenum target, GLenum pname, GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glFramebufferParameteriMESA (GLenum target, GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glGetFramebufferParameterivMESA (GLenum target, GLenum pname, GLint *params); +#endif +#endif /* GL_MESA_framebuffer_flip_y */ + +#ifndef GL_MESA_framebuffer_swap_xy +#define GL_MESA_framebuffer_swap_xy 1 +#define GL_FRAMEBUFFER_SWAP_XY_MESA 0x8BBD +#endif /* GL_MESA_framebuffer_swap_xy */ + +#ifndef GL_MESA_program_binary_formats +#define GL_MESA_program_binary_formats 1 +#define GL_PROGRAM_BINARY_FORMAT_MESA 0x875F +#endif /* GL_MESA_program_binary_formats */ + +#ifndef GL_MESA_shader_integer_functions +#define GL_MESA_shader_integer_functions 1 +#endif /* GL_MESA_shader_integer_functions */ + +#ifndef GL_NVX_blend_equation_advanced_multi_draw_buffers +#define GL_NVX_blend_equation_advanced_multi_draw_buffers 1 +#endif /* GL_NVX_blend_equation_advanced_multi_draw_buffers */ + +#ifndef GL_NV_bindless_texture +#define GL_NV_bindless_texture 1 +typedef GLuint64 (GL_APIENTRYP PFNGLGETTEXTUREHANDLENVPROC) (GLuint texture); +typedef GLuint64 (GL_APIENTRYP PFNGLGETTEXTURESAMPLERHANDLENVPROC) (GLuint texture, GLuint sampler); +typedef void (GL_APIENTRYP PFNGLMAKETEXTUREHANDLERESIDENTNVPROC) (GLuint64 handle); +typedef void (GL_APIENTRYP PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC) (GLuint64 handle); +typedef GLuint64 (GL_APIENTRYP PFNGLGETIMAGEHANDLENVPROC) (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format); +typedef void (GL_APIENTRYP PFNGLMAKEIMAGEHANDLERESIDENTNVPROC) (GLuint64 handle, GLenum access); +typedef void (GL_APIENTRYP PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC) (GLuint64 handle); +typedef void (GL_APIENTRYP PFNGLUNIFORMHANDLEUI64NVPROC) (GLint location, GLuint64 value); +typedef void (GL_APIENTRYP PFNGLUNIFORMHANDLEUI64VNVPROC) (GLint location, GLsizei count, const GLuint64 *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC) (GLuint program, GLint location, GLuint64 value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 *values); +typedef GLboolean (GL_APIENTRYP PFNGLISTEXTUREHANDLERESIDENTNVPROC) (GLuint64 handle); +typedef GLboolean (GL_APIENTRYP PFNGLISIMAGEHANDLERESIDENTNVPROC) (GLuint64 handle); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL GLuint64 GL_APIENTRY glGetTextureHandleNV (GLuint texture); +GL_APICALL GLuint64 GL_APIENTRY glGetTextureSamplerHandleNV (GLuint texture, GLuint sampler); +GL_APICALL void GL_APIENTRY glMakeTextureHandleResidentNV (GLuint64 handle); +GL_APICALL void GL_APIENTRY glMakeTextureHandleNonResidentNV (GLuint64 handle); +GL_APICALL GLuint64 GL_APIENTRY glGetImageHandleNV (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format); +GL_APICALL void GL_APIENTRY glMakeImageHandleResidentNV (GLuint64 handle, GLenum access); +GL_APICALL void GL_APIENTRY glMakeImageHandleNonResidentNV (GLuint64 handle); +GL_APICALL void GL_APIENTRY glUniformHandleui64NV (GLint location, GLuint64 value); +GL_APICALL void GL_APIENTRY glUniformHandleui64vNV (GLint location, GLsizei count, const GLuint64 *value); +GL_APICALL void GL_APIENTRY glProgramUniformHandleui64NV (GLuint program, GLint location, GLuint64 value); +GL_APICALL void GL_APIENTRY glProgramUniformHandleui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64 *values); +GL_APICALL GLboolean GL_APIENTRY glIsTextureHandleResidentNV (GLuint64 handle); +GL_APICALL GLboolean GL_APIENTRY glIsImageHandleResidentNV (GLuint64 handle); +#endif +#endif /* GL_NV_bindless_texture */ + +#ifndef GL_NV_blend_equation_advanced +#define GL_NV_blend_equation_advanced 1 +#define GL_BLEND_OVERLAP_NV 0x9281 +#define GL_BLEND_PREMULTIPLIED_SRC_NV 0x9280 +#define GL_BLUE_NV 0x1905 +#define GL_COLORBURN_NV 0x929A +#define GL_COLORDODGE_NV 0x9299 +#define GL_CONJOINT_NV 0x9284 +#define GL_CONTRAST_NV 0x92A1 +#define GL_DARKEN_NV 0x9297 +#define GL_DIFFERENCE_NV 0x929E +#define GL_DISJOINT_NV 0x9283 +#define GL_DST_ATOP_NV 0x928F +#define GL_DST_IN_NV 0x928B +#define GL_DST_NV 0x9287 +#define GL_DST_OUT_NV 0x928D +#define GL_DST_OVER_NV 0x9289 +#define GL_EXCLUSION_NV 0x92A0 +#define GL_GREEN_NV 0x1904 +#define GL_HARDLIGHT_NV 0x929B +#define GL_HARDMIX_NV 0x92A9 +#define GL_HSL_COLOR_NV 0x92AF +#define GL_HSL_HUE_NV 0x92AD +#define GL_HSL_LUMINOSITY_NV 0x92B0 +#define GL_HSL_SATURATION_NV 0x92AE +#define GL_INVERT_OVG_NV 0x92B4 +#define GL_INVERT_RGB_NV 0x92A3 +#define GL_LIGHTEN_NV 0x9298 +#define GL_LINEARBURN_NV 0x92A5 +#define GL_LINEARDODGE_NV 0x92A4 +#define GL_LINEARLIGHT_NV 0x92A7 +#define GL_MINUS_CLAMPED_NV 0x92B3 +#define GL_MINUS_NV 0x929F +#define GL_MULTIPLY_NV 0x9294 +#define GL_OVERLAY_NV 0x9296 +#define GL_PINLIGHT_NV 0x92A8 +#define GL_PLUS_CLAMPED_ALPHA_NV 0x92B2 +#define GL_PLUS_CLAMPED_NV 0x92B1 +#define GL_PLUS_DARKER_NV 0x9292 +#define GL_PLUS_NV 0x9291 +#define GL_RED_NV 0x1903 +#define GL_SCREEN_NV 0x9295 +#define GL_SOFTLIGHT_NV 0x929C +#define GL_SRC_ATOP_NV 0x928E +#define GL_SRC_IN_NV 0x928A +#define GL_SRC_NV 0x9286 +#define GL_SRC_OUT_NV 0x928C +#define GL_SRC_OVER_NV 0x9288 +#define GL_UNCORRELATED_NV 0x9282 +#define GL_VIVIDLIGHT_NV 0x92A6 +#define GL_XOR_NV 0x1506 +typedef void (GL_APIENTRYP PFNGLBLENDPARAMETERINVPROC) (GLenum pname, GLint value); +typedef void (GL_APIENTRYP PFNGLBLENDBARRIERNVPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glBlendParameteriNV (GLenum pname, GLint value); +GL_APICALL void GL_APIENTRY glBlendBarrierNV (void); +#endif +#endif /* GL_NV_blend_equation_advanced */ + +#ifndef GL_NV_blend_equation_advanced_coherent +#define GL_NV_blend_equation_advanced_coherent 1 +#define GL_BLEND_ADVANCED_COHERENT_NV 0x9285 +#endif /* GL_NV_blend_equation_advanced_coherent */ + +#ifndef GL_NV_blend_minmax_factor +#define GL_NV_blend_minmax_factor 1 +#define GL_FACTOR_MIN_AMD 0x901C +#define GL_FACTOR_MAX_AMD 0x901D +#endif /* GL_NV_blend_minmax_factor */ + +#ifndef GL_NV_clip_space_w_scaling +#define GL_NV_clip_space_w_scaling 1 +#define GL_VIEWPORT_POSITION_W_SCALE_NV 0x937C +#define GL_VIEWPORT_POSITION_W_SCALE_X_COEFF_NV 0x937D +#define GL_VIEWPORT_POSITION_W_SCALE_Y_COEFF_NV 0x937E +typedef void (GL_APIENTRYP PFNGLVIEWPORTPOSITIONWSCALENVPROC) (GLuint index, GLfloat xcoeff, GLfloat ycoeff); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glViewportPositionWScaleNV (GLuint index, GLfloat xcoeff, GLfloat ycoeff); +#endif +#endif /* GL_NV_clip_space_w_scaling */ + +#ifndef GL_NV_compute_shader_derivatives +#define GL_NV_compute_shader_derivatives 1 +#endif /* GL_NV_compute_shader_derivatives */ + +#ifndef GL_NV_conditional_render +#define GL_NV_conditional_render 1 +#define GL_QUERY_WAIT_NV 0x8E13 +#define GL_QUERY_NO_WAIT_NV 0x8E14 +#define GL_QUERY_BY_REGION_WAIT_NV 0x8E15 +#define GL_QUERY_BY_REGION_NO_WAIT_NV 0x8E16 +typedef void (GL_APIENTRYP PFNGLBEGINCONDITIONALRENDERNVPROC) (GLuint id, GLenum mode); +typedef void (GL_APIENTRYP PFNGLENDCONDITIONALRENDERNVPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glBeginConditionalRenderNV (GLuint id, GLenum mode); +GL_APICALL void GL_APIENTRY glEndConditionalRenderNV (void); +#endif +#endif /* GL_NV_conditional_render */ + +#ifndef GL_NV_conservative_raster +#define GL_NV_conservative_raster 1 +#define GL_CONSERVATIVE_RASTERIZATION_NV 0x9346 +#define GL_SUBPIXEL_PRECISION_BIAS_X_BITS_NV 0x9347 +#define GL_SUBPIXEL_PRECISION_BIAS_Y_BITS_NV 0x9348 +#define GL_MAX_SUBPIXEL_PRECISION_BIAS_BITS_NV 0x9349 +typedef void (GL_APIENTRYP PFNGLSUBPIXELPRECISIONBIASNVPROC) (GLuint xbits, GLuint ybits); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glSubpixelPrecisionBiasNV (GLuint xbits, GLuint ybits); +#endif +#endif /* GL_NV_conservative_raster */ + +#ifndef GL_NV_conservative_raster_pre_snap +#define GL_NV_conservative_raster_pre_snap 1 +#define GL_CONSERVATIVE_RASTER_MODE_PRE_SNAP_NV 0x9550 +#endif /* GL_NV_conservative_raster_pre_snap */ + +#ifndef GL_NV_conservative_raster_pre_snap_triangles +#define GL_NV_conservative_raster_pre_snap_triangles 1 +#define GL_CONSERVATIVE_RASTER_MODE_NV 0x954D +#define GL_CONSERVATIVE_RASTER_MODE_POST_SNAP_NV 0x954E +#define GL_CONSERVATIVE_RASTER_MODE_PRE_SNAP_TRIANGLES_NV 0x954F +typedef void (GL_APIENTRYP PFNGLCONSERVATIVERASTERPARAMETERINVPROC) (GLenum pname, GLint param); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glConservativeRasterParameteriNV (GLenum pname, GLint param); +#endif +#endif /* GL_NV_conservative_raster_pre_snap_triangles */ + +#ifndef GL_NV_copy_buffer +#define GL_NV_copy_buffer 1 +#define GL_COPY_READ_BUFFER_NV 0x8F36 +#define GL_COPY_WRITE_BUFFER_NV 0x8F37 +typedef void (GL_APIENTRYP PFNGLCOPYBUFFERSUBDATANVPROC) (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glCopyBufferSubDataNV (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +#endif +#endif /* GL_NV_copy_buffer */ + +#ifndef GL_NV_coverage_sample +#define GL_NV_coverage_sample 1 +#define GL_COVERAGE_COMPONENT_NV 0x8ED0 +#define GL_COVERAGE_COMPONENT4_NV 0x8ED1 +#define GL_COVERAGE_ATTACHMENT_NV 0x8ED2 +#define GL_COVERAGE_BUFFERS_NV 0x8ED3 +#define GL_COVERAGE_SAMPLES_NV 0x8ED4 +#define GL_COVERAGE_ALL_FRAGMENTS_NV 0x8ED5 +#define GL_COVERAGE_EDGE_FRAGMENTS_NV 0x8ED6 +#define GL_COVERAGE_AUTOMATIC_NV 0x8ED7 +#define GL_COVERAGE_BUFFER_BIT_NV 0x00008000 +typedef void (GL_APIENTRYP PFNGLCOVERAGEMASKNVPROC) (GLboolean mask); +typedef void (GL_APIENTRYP PFNGLCOVERAGEOPERATIONNVPROC) (GLenum operation); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glCoverageMaskNV (GLboolean mask); +GL_APICALL void GL_APIENTRY glCoverageOperationNV (GLenum operation); +#endif +#endif /* GL_NV_coverage_sample */ + +#ifndef GL_NV_depth_nonlinear +#define GL_NV_depth_nonlinear 1 +#define GL_DEPTH_COMPONENT16_NONLINEAR_NV 0x8E2C +#endif /* GL_NV_depth_nonlinear */ + +#ifndef GL_NV_draw_buffers +#define GL_NV_draw_buffers 1 +#define GL_MAX_DRAW_BUFFERS_NV 0x8824 +#define GL_DRAW_BUFFER0_NV 0x8825 +#define GL_DRAW_BUFFER1_NV 0x8826 +#define GL_DRAW_BUFFER2_NV 0x8827 +#define GL_DRAW_BUFFER3_NV 0x8828 +#define GL_DRAW_BUFFER4_NV 0x8829 +#define GL_DRAW_BUFFER5_NV 0x882A +#define GL_DRAW_BUFFER6_NV 0x882B +#define GL_DRAW_BUFFER7_NV 0x882C +#define GL_DRAW_BUFFER8_NV 0x882D +#define GL_DRAW_BUFFER9_NV 0x882E +#define GL_DRAW_BUFFER10_NV 0x882F +#define GL_DRAW_BUFFER11_NV 0x8830 +#define GL_DRAW_BUFFER12_NV 0x8831 +#define GL_DRAW_BUFFER13_NV 0x8832 +#define GL_DRAW_BUFFER14_NV 0x8833 +#define GL_DRAW_BUFFER15_NV 0x8834 +#define GL_COLOR_ATTACHMENT0_NV 0x8CE0 +#define GL_COLOR_ATTACHMENT1_NV 0x8CE1 +#define GL_COLOR_ATTACHMENT2_NV 0x8CE2 +#define GL_COLOR_ATTACHMENT3_NV 0x8CE3 +#define GL_COLOR_ATTACHMENT4_NV 0x8CE4 +#define GL_COLOR_ATTACHMENT5_NV 0x8CE5 +#define GL_COLOR_ATTACHMENT6_NV 0x8CE6 +#define GL_COLOR_ATTACHMENT7_NV 0x8CE7 +#define GL_COLOR_ATTACHMENT8_NV 0x8CE8 +#define GL_COLOR_ATTACHMENT9_NV 0x8CE9 +#define GL_COLOR_ATTACHMENT10_NV 0x8CEA +#define GL_COLOR_ATTACHMENT11_NV 0x8CEB +#define GL_COLOR_ATTACHMENT12_NV 0x8CEC +#define GL_COLOR_ATTACHMENT13_NV 0x8CED +#define GL_COLOR_ATTACHMENT14_NV 0x8CEE +#define GL_COLOR_ATTACHMENT15_NV 0x8CEF +typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSNVPROC) (GLsizei n, const GLenum *bufs); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDrawBuffersNV (GLsizei n, const GLenum *bufs); +#endif +#endif /* GL_NV_draw_buffers */ + +#ifndef GL_NV_draw_instanced +#define GL_NV_draw_instanced 1 +typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDNVPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDNVPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDrawArraysInstancedNV (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +GL_APICALL void GL_APIENTRY glDrawElementsInstancedNV (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); +#endif +#endif /* GL_NV_draw_instanced */ + +#ifndef GL_NV_draw_vulkan_image +#define GL_NV_draw_vulkan_image 1 +typedef void (GL_APIENTRY *GLVULKANPROCNV)(void); +typedef void (GL_APIENTRYP PFNGLDRAWVKIMAGENVPROC) (GLuint64 vkImage, GLuint sampler, GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1, GLfloat z, GLfloat s0, GLfloat t0, GLfloat s1, GLfloat t1); +typedef GLVULKANPROCNV (GL_APIENTRYP PFNGLGETVKPROCADDRNVPROC) (const GLchar *name); +typedef void (GL_APIENTRYP PFNGLWAITVKSEMAPHORENVPROC) (GLuint64 vkSemaphore); +typedef void (GL_APIENTRYP PFNGLSIGNALVKSEMAPHORENVPROC) (GLuint64 vkSemaphore); +typedef void (GL_APIENTRYP PFNGLSIGNALVKFENCENVPROC) (GLuint64 vkFence); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDrawVkImageNV (GLuint64 vkImage, GLuint sampler, GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1, GLfloat z, GLfloat s0, GLfloat t0, GLfloat s1, GLfloat t1); +GL_APICALL GLVULKANPROCNV GL_APIENTRY glGetVkProcAddrNV (const GLchar *name); +GL_APICALL void GL_APIENTRY glWaitVkSemaphoreNV (GLuint64 vkSemaphore); +GL_APICALL void GL_APIENTRY glSignalVkSemaphoreNV (GLuint64 vkSemaphore); +GL_APICALL void GL_APIENTRY glSignalVkFenceNV (GLuint64 vkFence); +#endif +#endif /* GL_NV_draw_vulkan_image */ + +#ifndef GL_NV_explicit_attrib_location +#define GL_NV_explicit_attrib_location 1 +#endif /* GL_NV_explicit_attrib_location */ + +#ifndef GL_NV_fbo_color_attachments +#define GL_NV_fbo_color_attachments 1 +#define GL_MAX_COLOR_ATTACHMENTS_NV 0x8CDF +#endif /* GL_NV_fbo_color_attachments */ + +#ifndef GL_NV_fence +#define GL_NV_fence 1 +#define GL_ALL_COMPLETED_NV 0x84F2 +#define GL_FENCE_STATUS_NV 0x84F3 +#define GL_FENCE_CONDITION_NV 0x84F4 +typedef void (GL_APIENTRYP PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint *fences); +typedef void (GL_APIENTRYP PFNGLGENFENCESNVPROC) (GLsizei n, GLuint *fences); +typedef GLboolean (GL_APIENTRYP PFNGLISFENCENVPROC) (GLuint fence); +typedef GLboolean (GL_APIENTRYP PFNGLTESTFENCENVPROC) (GLuint fence); +typedef void (GL_APIENTRYP PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLFINISHFENCENVPROC) (GLuint fence); +typedef void (GL_APIENTRYP PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDeleteFencesNV (GLsizei n, const GLuint *fences); +GL_APICALL void GL_APIENTRY glGenFencesNV (GLsizei n, GLuint *fences); +GL_APICALL GLboolean GL_APIENTRY glIsFenceNV (GLuint fence); +GL_APICALL GLboolean GL_APIENTRY glTestFenceNV (GLuint fence); +GL_APICALL void GL_APIENTRY glGetFenceivNV (GLuint fence, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glFinishFenceNV (GLuint fence); +GL_APICALL void GL_APIENTRY glSetFenceNV (GLuint fence, GLenum condition); +#endif +#endif /* GL_NV_fence */ + +#ifndef GL_NV_fill_rectangle +#define GL_NV_fill_rectangle 1 +#define GL_FILL_RECTANGLE_NV 0x933C +#endif /* GL_NV_fill_rectangle */ + +#ifndef GL_NV_fragment_coverage_to_color +#define GL_NV_fragment_coverage_to_color 1 +#define GL_FRAGMENT_COVERAGE_TO_COLOR_NV 0x92DD +#define GL_FRAGMENT_COVERAGE_COLOR_NV 0x92DE +typedef void (GL_APIENTRYP PFNGLFRAGMENTCOVERAGECOLORNVPROC) (GLuint color); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glFragmentCoverageColorNV (GLuint color); +#endif +#endif /* GL_NV_fragment_coverage_to_color */ + +#ifndef GL_NV_fragment_shader_barycentric +#define GL_NV_fragment_shader_barycentric 1 +#endif /* GL_NV_fragment_shader_barycentric */ + +#ifndef GL_NV_fragment_shader_interlock +#define GL_NV_fragment_shader_interlock 1 +#endif /* GL_NV_fragment_shader_interlock */ + +#ifndef GL_NV_framebuffer_blit +#define GL_NV_framebuffer_blit 1 +#define GL_READ_FRAMEBUFFER_NV 0x8CA8 +#define GL_DRAW_FRAMEBUFFER_NV 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_BINDING_NV 0x8CA6 +#define GL_READ_FRAMEBUFFER_BINDING_NV 0x8CAA +typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERNVPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glBlitFramebufferNV (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#endif +#endif /* GL_NV_framebuffer_blit */ + +#ifndef GL_NV_framebuffer_mixed_samples +#define GL_NV_framebuffer_mixed_samples 1 +#define GL_COVERAGE_MODULATION_TABLE_NV 0x9331 +#define GL_COLOR_SAMPLES_NV 0x8E20 +#define GL_DEPTH_SAMPLES_NV 0x932D +#define GL_STENCIL_SAMPLES_NV 0x932E +#define GL_MIXED_DEPTH_SAMPLES_SUPPORTED_NV 0x932F +#define GL_MIXED_STENCIL_SAMPLES_SUPPORTED_NV 0x9330 +#define GL_COVERAGE_MODULATION_NV 0x9332 +#define GL_COVERAGE_MODULATION_TABLE_SIZE_NV 0x9333 +typedef void (GL_APIENTRYP PFNGLCOVERAGEMODULATIONTABLENVPROC) (GLsizei n, const GLfloat *v); +typedef void (GL_APIENTRYP PFNGLGETCOVERAGEMODULATIONTABLENVPROC) (GLsizei bufSize, GLfloat *v); +typedef void (GL_APIENTRYP PFNGLCOVERAGEMODULATIONNVPROC) (GLenum components); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glCoverageModulationTableNV (GLsizei n, const GLfloat *v); +GL_APICALL void GL_APIENTRY glGetCoverageModulationTableNV (GLsizei bufSize, GLfloat *v); +GL_APICALL void GL_APIENTRY glCoverageModulationNV (GLenum components); +#endif +#endif /* GL_NV_framebuffer_mixed_samples */ + +#ifndef GL_NV_framebuffer_multisample +#define GL_NV_framebuffer_multisample 1 +#define GL_RENDERBUFFER_SAMPLES_NV 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_NV 0x8D56 +#define GL_MAX_SAMPLES_NV 0x8D57 +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLENVPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleNV (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +#endif +#endif /* GL_NV_framebuffer_multisample */ + +#ifndef GL_NV_generate_mipmap_sRGB +#define GL_NV_generate_mipmap_sRGB 1 +#endif /* GL_NV_generate_mipmap_sRGB */ + +#ifndef GL_NV_geometry_shader_passthrough +#define GL_NV_geometry_shader_passthrough 1 +#endif /* GL_NV_geometry_shader_passthrough */ + +#ifndef GL_NV_gpu_shader5 +#define GL_NV_gpu_shader5 1 +typedef khronos_int64_t GLint64EXT; +typedef khronos_uint64_t GLuint64EXT; +#define GL_INT64_NV 0x140E +#define GL_UNSIGNED_INT64_NV 0x140F +#define GL_INT8_NV 0x8FE0 +#define GL_INT8_VEC2_NV 0x8FE1 +#define GL_INT8_VEC3_NV 0x8FE2 +#define GL_INT8_VEC4_NV 0x8FE3 +#define GL_INT16_NV 0x8FE4 +#define GL_INT16_VEC2_NV 0x8FE5 +#define GL_INT16_VEC3_NV 0x8FE6 +#define GL_INT16_VEC4_NV 0x8FE7 +#define GL_INT64_VEC2_NV 0x8FE9 +#define GL_INT64_VEC3_NV 0x8FEA +#define GL_INT64_VEC4_NV 0x8FEB +#define GL_UNSIGNED_INT8_NV 0x8FEC +#define GL_UNSIGNED_INT8_VEC2_NV 0x8FED +#define GL_UNSIGNED_INT8_VEC3_NV 0x8FEE +#define GL_UNSIGNED_INT8_VEC4_NV 0x8FEF +#define GL_UNSIGNED_INT16_NV 0x8FF0 +#define GL_UNSIGNED_INT16_VEC2_NV 0x8FF1 +#define GL_UNSIGNED_INT16_VEC3_NV 0x8FF2 +#define GL_UNSIGNED_INT16_VEC4_NV 0x8FF3 +#define GL_UNSIGNED_INT64_VEC2_NV 0x8FF5 +#define GL_UNSIGNED_INT64_VEC3_NV 0x8FF6 +#define GL_UNSIGNED_INT64_VEC4_NV 0x8FF7 +#define GL_FLOAT16_NV 0x8FF8 +#define GL_FLOAT16_VEC2_NV 0x8FF9 +#define GL_FLOAT16_VEC3_NV 0x8FFA +#define GL_FLOAT16_VEC4_NV 0x8FFB +#define GL_PATCHES 0x000E +typedef void (GL_APIENTRYP PFNGLUNIFORM1I64NVPROC) (GLint location, GLint64EXT x); +typedef void (GL_APIENTRYP PFNGLUNIFORM2I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y); +typedef void (GL_APIENTRYP PFNGLUNIFORM3I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); +typedef void (GL_APIENTRYP PFNGLUNIFORM4I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); +typedef void (GL_APIENTRYP PFNGLUNIFORM1I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM2I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM3I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM4I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM1UI64NVPROC) (GLint location, GLuint64EXT x); +typedef void (GL_APIENTRYP PFNGLUNIFORM2UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y); +typedef void (GL_APIENTRYP PFNGLUNIFORM3UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); +typedef void (GL_APIENTRYP PFNGLUNIFORM4UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); +typedef void (GL_APIENTRYP PFNGLUNIFORM1UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM2UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM3UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); +typedef void (GL_APIENTRYP PFNGLUNIFORM4UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); +typedef void (GL_APIENTRYP PFNGLGETUNIFORMI64VNVPROC) (GLuint program, GLint location, GLint64EXT *params); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1I64NVPROC) (GLuint program, GLint location, GLint64EXT x); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glUniform1i64NV (GLint location, GLint64EXT x); +GL_APICALL void GL_APIENTRY glUniform2i64NV (GLint location, GLint64EXT x, GLint64EXT y); +GL_APICALL void GL_APIENTRY glUniform3i64NV (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); +GL_APICALL void GL_APIENTRY glUniform4i64NV (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); +GL_APICALL void GL_APIENTRY glUniform1i64vNV (GLint location, GLsizei count, const GLint64EXT *value); +GL_APICALL void GL_APIENTRY glUniform2i64vNV (GLint location, GLsizei count, const GLint64EXT *value); +GL_APICALL void GL_APIENTRY glUniform3i64vNV (GLint location, GLsizei count, const GLint64EXT *value); +GL_APICALL void GL_APIENTRY glUniform4i64vNV (GLint location, GLsizei count, const GLint64EXT *value); +GL_APICALL void GL_APIENTRY glUniform1ui64NV (GLint location, GLuint64EXT x); +GL_APICALL void GL_APIENTRY glUniform2ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y); +GL_APICALL void GL_APIENTRY glUniform3ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); +GL_APICALL void GL_APIENTRY glUniform4ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); +GL_APICALL void GL_APIENTRY glUniform1ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value); +GL_APICALL void GL_APIENTRY glUniform2ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value); +GL_APICALL void GL_APIENTRY glUniform3ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value); +GL_APICALL void GL_APIENTRY glUniform4ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value); +GL_APICALL void GL_APIENTRY glGetUniformi64vNV (GLuint program, GLint location, GLint64EXT *params); +GL_APICALL void GL_APIENTRY glProgramUniform1i64NV (GLuint program, GLint location, GLint64EXT x); +GL_APICALL void GL_APIENTRY glProgramUniform2i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y); +GL_APICALL void GL_APIENTRY glProgramUniform3i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); +GL_APICALL void GL_APIENTRY glProgramUniform4i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); +GL_APICALL void GL_APIENTRY glProgramUniform1i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); +GL_APICALL void GL_APIENTRY glProgramUniform2i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); +GL_APICALL void GL_APIENTRY glProgramUniform3i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); +GL_APICALL void GL_APIENTRY glProgramUniform4i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); +GL_APICALL void GL_APIENTRY glProgramUniform1ui64NV (GLuint program, GLint location, GLuint64EXT x); +GL_APICALL void GL_APIENTRY glProgramUniform2ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y); +GL_APICALL void GL_APIENTRY glProgramUniform3ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); +GL_APICALL void GL_APIENTRY glProgramUniform4ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); +GL_APICALL void GL_APIENTRY glProgramUniform1ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +GL_APICALL void GL_APIENTRY glProgramUniform2ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +GL_APICALL void GL_APIENTRY glProgramUniform3ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +GL_APICALL void GL_APIENTRY glProgramUniform4ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); +#endif +#endif /* GL_NV_gpu_shader5 */ + +#ifndef GL_NV_image_formats +#define GL_NV_image_formats 1 +#endif /* GL_NV_image_formats */ + +#ifndef GL_NV_instanced_arrays +#define GL_NV_instanced_arrays 1 +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_NV 0x88FE +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISORNVPROC) (GLuint index, GLuint divisor); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glVertexAttribDivisorNV (GLuint index, GLuint divisor); +#endif +#endif /* GL_NV_instanced_arrays */ + +#ifndef GL_NV_internalformat_sample_query +#define GL_NV_internalformat_sample_query 1 +#define GL_TEXTURE_2D_MULTISAMPLE 0x9100 +#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102 +#define GL_MULTISAMPLES_NV 0x9371 +#define GL_SUPERSAMPLE_SCALE_X_NV 0x9372 +#define GL_SUPERSAMPLE_SCALE_Y_NV 0x9373 +#define GL_CONFORMANT_NV 0x9374 +typedef void (GL_APIENTRYP PFNGLGETINTERNALFORMATSAMPLEIVNVPROC) (GLenum target, GLenum internalformat, GLsizei samples, GLenum pname, GLsizei count, GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGetInternalformatSampleivNV (GLenum target, GLenum internalformat, GLsizei samples, GLenum pname, GLsizei count, GLint *params); +#endif +#endif /* GL_NV_internalformat_sample_query */ + +#ifndef GL_NV_memory_attachment +#define GL_NV_memory_attachment 1 +#define GL_ATTACHED_MEMORY_OBJECT_NV 0x95A4 +#define GL_ATTACHED_MEMORY_OFFSET_NV 0x95A5 +#define GL_MEMORY_ATTACHABLE_ALIGNMENT_NV 0x95A6 +#define GL_MEMORY_ATTACHABLE_SIZE_NV 0x95A7 +#define GL_MEMORY_ATTACHABLE_NV 0x95A8 +#define GL_DETACHED_MEMORY_INCARNATION_NV 0x95A9 +#define GL_DETACHED_TEXTURES_NV 0x95AA +#define GL_DETACHED_BUFFERS_NV 0x95AB +#define GL_MAX_DETACHED_TEXTURES_NV 0x95AC +#define GL_MAX_DETACHED_BUFFERS_NV 0x95AD +typedef void (GL_APIENTRYP PFNGLGETMEMORYOBJECTDETACHEDRESOURCESUIVNVPROC) (GLuint memory, GLenum pname, GLint first, GLsizei count, GLuint *params); +typedef void (GL_APIENTRYP PFNGLRESETMEMORYOBJECTPARAMETERNVPROC) (GLuint memory, GLenum pname); +typedef void (GL_APIENTRYP PFNGLTEXATTACHMEMORYNVPROC) (GLenum target, GLuint memory, GLuint64 offset); +typedef void (GL_APIENTRYP PFNGLBUFFERATTACHMEMORYNVPROC) (GLenum target, GLuint memory, GLuint64 offset); +typedef void (GL_APIENTRYP PFNGLTEXTUREATTACHMEMORYNVPROC) (GLuint texture, GLuint memory, GLuint64 offset); +typedef void (GL_APIENTRYP PFNGLNAMEDBUFFERATTACHMEMORYNVPROC) (GLuint buffer, GLuint memory, GLuint64 offset); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGetMemoryObjectDetachedResourcesuivNV (GLuint memory, GLenum pname, GLint first, GLsizei count, GLuint *params); +GL_APICALL void GL_APIENTRY glResetMemoryObjectParameterNV (GLuint memory, GLenum pname); +GL_APICALL void GL_APIENTRY glTexAttachMemoryNV (GLenum target, GLuint memory, GLuint64 offset); +GL_APICALL void GL_APIENTRY glBufferAttachMemoryNV (GLenum target, GLuint memory, GLuint64 offset); +GL_APICALL void GL_APIENTRY glTextureAttachMemoryNV (GLuint texture, GLuint memory, GLuint64 offset); +GL_APICALL void GL_APIENTRY glNamedBufferAttachMemoryNV (GLuint buffer, GLuint memory, GLuint64 offset); +#endif +#endif /* GL_NV_memory_attachment */ + +#ifndef GL_NV_memory_object_sparse +#define GL_NV_memory_object_sparse 1 +typedef void (GL_APIENTRYP PFNGLBUFFERPAGECOMMITMENTMEMNVPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLuint memory, GLuint64 memOffset, GLboolean commit); +typedef void (GL_APIENTRYP PFNGLTEXPAGECOMMITMENTMEMNVPROC) (GLenum target, GLint layer, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset, GLboolean commit); +typedef void (GL_APIENTRYP PFNGLNAMEDBUFFERPAGECOMMITMENTMEMNVPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, GLuint memory, GLuint64 memOffset, GLboolean commit); +typedef void (GL_APIENTRYP PFNGLTEXTUREPAGECOMMITMENTMEMNVPROC) (GLuint texture, GLint layer, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset, GLboolean commit); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glBufferPageCommitmentMemNV (GLenum target, GLintptr offset, GLsizeiptr size, GLuint memory, GLuint64 memOffset, GLboolean commit); +GL_APICALL void GL_APIENTRY glTexPageCommitmentMemNV (GLenum target, GLint layer, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset, GLboolean commit); +GL_APICALL void GL_APIENTRY glNamedBufferPageCommitmentMemNV (GLuint buffer, GLintptr offset, GLsizeiptr size, GLuint memory, GLuint64 memOffset, GLboolean commit); +GL_APICALL void GL_APIENTRY glTexturePageCommitmentMemNV (GLuint texture, GLint layer, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset, GLboolean commit); +#endif +#endif /* GL_NV_memory_object_sparse */ + +#ifndef GL_NV_mesh_shader +#define GL_NV_mesh_shader 1 +#define GL_MESH_SHADER_NV 0x9559 +#define GL_TASK_SHADER_NV 0x955A +#define GL_MAX_MESH_UNIFORM_BLOCKS_NV 0x8E60 +#define GL_MAX_MESH_TEXTURE_IMAGE_UNITS_NV 0x8E61 +#define GL_MAX_MESH_IMAGE_UNIFORMS_NV 0x8E62 +#define GL_MAX_MESH_UNIFORM_COMPONENTS_NV 0x8E63 +#define GL_MAX_MESH_ATOMIC_COUNTER_BUFFERS_NV 0x8E64 +#define GL_MAX_MESH_ATOMIC_COUNTERS_NV 0x8E65 +#define GL_MAX_MESH_SHADER_STORAGE_BLOCKS_NV 0x8E66 +#define GL_MAX_COMBINED_MESH_UNIFORM_COMPONENTS_NV 0x8E67 +#define GL_MAX_TASK_UNIFORM_BLOCKS_NV 0x8E68 +#define GL_MAX_TASK_TEXTURE_IMAGE_UNITS_NV 0x8E69 +#define GL_MAX_TASK_IMAGE_UNIFORMS_NV 0x8E6A +#define GL_MAX_TASK_UNIFORM_COMPONENTS_NV 0x8E6B +#define GL_MAX_TASK_ATOMIC_COUNTER_BUFFERS_NV 0x8E6C +#define GL_MAX_TASK_ATOMIC_COUNTERS_NV 0x8E6D +#define GL_MAX_TASK_SHADER_STORAGE_BLOCKS_NV 0x8E6E +#define GL_MAX_COMBINED_TASK_UNIFORM_COMPONENTS_NV 0x8E6F +#define GL_MAX_MESH_WORK_GROUP_INVOCATIONS_NV 0x95A2 +#define GL_MAX_TASK_WORK_GROUP_INVOCATIONS_NV 0x95A3 +#define GL_MAX_MESH_TOTAL_MEMORY_SIZE_NV 0x9536 +#define GL_MAX_TASK_TOTAL_MEMORY_SIZE_NV 0x9537 +#define GL_MAX_MESH_OUTPUT_VERTICES_NV 0x9538 +#define GL_MAX_MESH_OUTPUT_PRIMITIVES_NV 0x9539 +#define GL_MAX_TASK_OUTPUT_COUNT_NV 0x953A +#define GL_MAX_DRAW_MESH_TASKS_COUNT_NV 0x953D +#define GL_MAX_MESH_VIEWS_NV 0x9557 +#define GL_MESH_OUTPUT_PER_VERTEX_GRANULARITY_NV 0x92DF +#define GL_MESH_OUTPUT_PER_PRIMITIVE_GRANULARITY_NV 0x9543 +#define GL_MAX_MESH_WORK_GROUP_SIZE_NV 0x953B +#define GL_MAX_TASK_WORK_GROUP_SIZE_NV 0x953C +#define GL_MESH_WORK_GROUP_SIZE_NV 0x953E +#define GL_TASK_WORK_GROUP_SIZE_NV 0x953F +#define GL_MESH_VERTICES_OUT_NV 0x9579 +#define GL_MESH_PRIMITIVES_OUT_NV 0x957A +#define GL_MESH_OUTPUT_TYPE_NV 0x957B +#define GL_UNIFORM_BLOCK_REFERENCED_BY_MESH_SHADER_NV 0x959C +#define GL_UNIFORM_BLOCK_REFERENCED_BY_TASK_SHADER_NV 0x959D +#define GL_REFERENCED_BY_MESH_SHADER_NV 0x95A0 +#define GL_REFERENCED_BY_TASK_SHADER_NV 0x95A1 +#define GL_MESH_SHADER_BIT_NV 0x00000040 +#define GL_TASK_SHADER_BIT_NV 0x00000080 +#define GL_MESH_SUBROUTINE_NV 0x957C +#define GL_TASK_SUBROUTINE_NV 0x957D +#define GL_MESH_SUBROUTINE_UNIFORM_NV 0x957E +#define GL_TASK_SUBROUTINE_UNIFORM_NV 0x957F +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_MESH_SHADER_NV 0x959E +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TASK_SHADER_NV 0x959F +typedef void (GL_APIENTRYP PFNGLDRAWMESHTASKSNVPROC) (GLuint first, GLuint count); +typedef void (GL_APIENTRYP PFNGLDRAWMESHTASKSINDIRECTNVPROC) (GLintptr indirect); +typedef void (GL_APIENTRYP PFNGLMULTIDRAWMESHTASKSINDIRECTNVPROC) (GLintptr indirect, GLsizei drawcount, GLsizei stride); +typedef void (GL_APIENTRYP PFNGLMULTIDRAWMESHTASKSINDIRECTCOUNTNVPROC) (GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDrawMeshTasksNV (GLuint first, GLuint count); +GL_APICALL void GL_APIENTRY glDrawMeshTasksIndirectNV (GLintptr indirect); +GL_APICALL void GL_APIENTRY glMultiDrawMeshTasksIndirectNV (GLintptr indirect, GLsizei drawcount, GLsizei stride); +GL_APICALL void GL_APIENTRY glMultiDrawMeshTasksIndirectCountNV (GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +#endif +#endif /* GL_NV_mesh_shader */ + +#ifndef GL_NV_non_square_matrices +#define GL_NV_non_square_matrices 1 +#define GL_FLOAT_MAT2x3_NV 0x8B65 +#define GL_FLOAT_MAT2x4_NV 0x8B66 +#define GL_FLOAT_MAT3x2_NV 0x8B67 +#define GL_FLOAT_MAT3x4_NV 0x8B68 +#define GL_FLOAT_MAT4x2_NV 0x8B69 +#define GL_FLOAT_MAT4x3_NV 0x8B6A +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX2X3FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX3X2FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX2X4FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX4X2FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX3X4FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLUNIFORMMATRIX4X3FVNVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glUniformMatrix2x3fvNV (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix3x2fvNV (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix2x4fvNV (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix4x2fvNV (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix3x4fvNV (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glUniformMatrix4x3fvNV (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +#endif +#endif /* GL_NV_non_square_matrices */ + +#ifndef GL_NV_path_rendering +#define GL_NV_path_rendering 1 +typedef double GLdouble; +#define GL_PATH_FORMAT_SVG_NV 0x9070 +#define GL_PATH_FORMAT_PS_NV 0x9071 +#define GL_STANDARD_FONT_NAME_NV 0x9072 +#define GL_SYSTEM_FONT_NAME_NV 0x9073 +#define GL_FILE_NAME_NV 0x9074 +#define GL_PATH_STROKE_WIDTH_NV 0x9075 +#define GL_PATH_END_CAPS_NV 0x9076 +#define GL_PATH_INITIAL_END_CAP_NV 0x9077 +#define GL_PATH_TERMINAL_END_CAP_NV 0x9078 +#define GL_PATH_JOIN_STYLE_NV 0x9079 +#define GL_PATH_MITER_LIMIT_NV 0x907A +#define GL_PATH_DASH_CAPS_NV 0x907B +#define GL_PATH_INITIAL_DASH_CAP_NV 0x907C +#define GL_PATH_TERMINAL_DASH_CAP_NV 0x907D +#define GL_PATH_DASH_OFFSET_NV 0x907E +#define GL_PATH_CLIENT_LENGTH_NV 0x907F +#define GL_PATH_FILL_MODE_NV 0x9080 +#define GL_PATH_FILL_MASK_NV 0x9081 +#define GL_PATH_FILL_COVER_MODE_NV 0x9082 +#define GL_PATH_STROKE_COVER_MODE_NV 0x9083 +#define GL_PATH_STROKE_MASK_NV 0x9084 +#define GL_COUNT_UP_NV 0x9088 +#define GL_COUNT_DOWN_NV 0x9089 +#define GL_PATH_OBJECT_BOUNDING_BOX_NV 0x908A +#define GL_CONVEX_HULL_NV 0x908B +#define GL_BOUNDING_BOX_NV 0x908D +#define GL_TRANSLATE_X_NV 0x908E +#define GL_TRANSLATE_Y_NV 0x908F +#define GL_TRANSLATE_2D_NV 0x9090 +#define GL_TRANSLATE_3D_NV 0x9091 +#define GL_AFFINE_2D_NV 0x9092 +#define GL_AFFINE_3D_NV 0x9094 +#define GL_TRANSPOSE_AFFINE_2D_NV 0x9096 +#define GL_TRANSPOSE_AFFINE_3D_NV 0x9098 +#define GL_UTF8_NV 0x909A +#define GL_UTF16_NV 0x909B +#define GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV 0x909C +#define GL_PATH_COMMAND_COUNT_NV 0x909D +#define GL_PATH_COORD_COUNT_NV 0x909E +#define GL_PATH_DASH_ARRAY_COUNT_NV 0x909F +#define GL_PATH_COMPUTED_LENGTH_NV 0x90A0 +#define GL_PATH_FILL_BOUNDING_BOX_NV 0x90A1 +#define GL_PATH_STROKE_BOUNDING_BOX_NV 0x90A2 +#define GL_SQUARE_NV 0x90A3 +#define GL_ROUND_NV 0x90A4 +#define GL_TRIANGULAR_NV 0x90A5 +#define GL_BEVEL_NV 0x90A6 +#define GL_MITER_REVERT_NV 0x90A7 +#define GL_MITER_TRUNCATE_NV 0x90A8 +#define GL_SKIP_MISSING_GLYPH_NV 0x90A9 +#define GL_USE_MISSING_GLYPH_NV 0x90AA +#define GL_PATH_ERROR_POSITION_NV 0x90AB +#define GL_ACCUM_ADJACENT_PAIRS_NV 0x90AD +#define GL_ADJACENT_PAIRS_NV 0x90AE +#define GL_FIRST_TO_REST_NV 0x90AF +#define GL_PATH_GEN_MODE_NV 0x90B0 +#define GL_PATH_GEN_COEFF_NV 0x90B1 +#define GL_PATH_GEN_COMPONENTS_NV 0x90B3 +#define GL_PATH_STENCIL_FUNC_NV 0x90B7 +#define GL_PATH_STENCIL_REF_NV 0x90B8 +#define GL_PATH_STENCIL_VALUE_MASK_NV 0x90B9 +#define GL_PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV 0x90BD +#define GL_PATH_STENCIL_DEPTH_OFFSET_UNITS_NV 0x90BE +#define GL_PATH_COVER_DEPTH_FUNC_NV 0x90BF +#define GL_PATH_DASH_OFFSET_RESET_NV 0x90B4 +#define GL_MOVE_TO_RESETS_NV 0x90B5 +#define GL_MOVE_TO_CONTINUES_NV 0x90B6 +#define GL_CLOSE_PATH_NV 0x00 +#define GL_MOVE_TO_NV 0x02 +#define GL_RELATIVE_MOVE_TO_NV 0x03 +#define GL_LINE_TO_NV 0x04 +#define GL_RELATIVE_LINE_TO_NV 0x05 +#define GL_HORIZONTAL_LINE_TO_NV 0x06 +#define GL_RELATIVE_HORIZONTAL_LINE_TO_NV 0x07 +#define GL_VERTICAL_LINE_TO_NV 0x08 +#define GL_RELATIVE_VERTICAL_LINE_TO_NV 0x09 +#define GL_QUADRATIC_CURVE_TO_NV 0x0A +#define GL_RELATIVE_QUADRATIC_CURVE_TO_NV 0x0B +#define GL_CUBIC_CURVE_TO_NV 0x0C +#define GL_RELATIVE_CUBIC_CURVE_TO_NV 0x0D +#define GL_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0E +#define GL_RELATIVE_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0F +#define GL_SMOOTH_CUBIC_CURVE_TO_NV 0x10 +#define GL_RELATIVE_SMOOTH_CUBIC_CURVE_TO_NV 0x11 +#define GL_SMALL_CCW_ARC_TO_NV 0x12 +#define GL_RELATIVE_SMALL_CCW_ARC_TO_NV 0x13 +#define GL_SMALL_CW_ARC_TO_NV 0x14 +#define GL_RELATIVE_SMALL_CW_ARC_TO_NV 0x15 +#define GL_LARGE_CCW_ARC_TO_NV 0x16 +#define GL_RELATIVE_LARGE_CCW_ARC_TO_NV 0x17 +#define GL_LARGE_CW_ARC_TO_NV 0x18 +#define GL_RELATIVE_LARGE_CW_ARC_TO_NV 0x19 +#define GL_RESTART_PATH_NV 0xF0 +#define GL_DUP_FIRST_CUBIC_CURVE_TO_NV 0xF2 +#define GL_DUP_LAST_CUBIC_CURVE_TO_NV 0xF4 +#define GL_RECT_NV 0xF6 +#define GL_CIRCULAR_CCW_ARC_TO_NV 0xF8 +#define GL_CIRCULAR_CW_ARC_TO_NV 0xFA +#define GL_CIRCULAR_TANGENT_ARC_TO_NV 0xFC +#define GL_ARC_TO_NV 0xFE +#define GL_RELATIVE_ARC_TO_NV 0xFF +#define GL_BOLD_BIT_NV 0x01 +#define GL_ITALIC_BIT_NV 0x02 +#define GL_GLYPH_WIDTH_BIT_NV 0x01 +#define GL_GLYPH_HEIGHT_BIT_NV 0x02 +#define GL_GLYPH_HORIZONTAL_BEARING_X_BIT_NV 0x04 +#define GL_GLYPH_HORIZONTAL_BEARING_Y_BIT_NV 0x08 +#define GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV 0x10 +#define GL_GLYPH_VERTICAL_BEARING_X_BIT_NV 0x20 +#define GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV 0x40 +#define GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV 0x80 +#define GL_GLYPH_HAS_KERNING_BIT_NV 0x100 +#define GL_FONT_X_MIN_BOUNDS_BIT_NV 0x00010000 +#define GL_FONT_Y_MIN_BOUNDS_BIT_NV 0x00020000 +#define GL_FONT_X_MAX_BOUNDS_BIT_NV 0x00040000 +#define GL_FONT_Y_MAX_BOUNDS_BIT_NV 0x00080000 +#define GL_FONT_UNITS_PER_EM_BIT_NV 0x00100000 +#define GL_FONT_ASCENDER_BIT_NV 0x00200000 +#define GL_FONT_DESCENDER_BIT_NV 0x00400000 +#define GL_FONT_HEIGHT_BIT_NV 0x00800000 +#define GL_FONT_MAX_ADVANCE_WIDTH_BIT_NV 0x01000000 +#define GL_FONT_MAX_ADVANCE_HEIGHT_BIT_NV 0x02000000 +#define GL_FONT_UNDERLINE_POSITION_BIT_NV 0x04000000 +#define GL_FONT_UNDERLINE_THICKNESS_BIT_NV 0x08000000 +#define GL_FONT_HAS_KERNING_BIT_NV 0x10000000 +#define GL_ROUNDED_RECT_NV 0xE8 +#define GL_RELATIVE_ROUNDED_RECT_NV 0xE9 +#define GL_ROUNDED_RECT2_NV 0xEA +#define GL_RELATIVE_ROUNDED_RECT2_NV 0xEB +#define GL_ROUNDED_RECT4_NV 0xEC +#define GL_RELATIVE_ROUNDED_RECT4_NV 0xED +#define GL_ROUNDED_RECT8_NV 0xEE +#define GL_RELATIVE_ROUNDED_RECT8_NV 0xEF +#define GL_RELATIVE_RECT_NV 0xF7 +#define GL_FONT_GLYPHS_AVAILABLE_NV 0x9368 +#define GL_FONT_TARGET_UNAVAILABLE_NV 0x9369 +#define GL_FONT_UNAVAILABLE_NV 0x936A +#define GL_FONT_UNINTELLIGIBLE_NV 0x936B +#define GL_CONIC_CURVE_TO_NV 0x1A +#define GL_RELATIVE_CONIC_CURVE_TO_NV 0x1B +#define GL_FONT_NUM_GLYPH_INDICES_BIT_NV 0x20000000 +#define GL_STANDARD_FONT_FORMAT_NV 0x936C +#define GL_PATH_PROJECTION_NV 0x1701 +#define GL_PATH_MODELVIEW_NV 0x1700 +#define GL_PATH_MODELVIEW_STACK_DEPTH_NV 0x0BA3 +#define GL_PATH_MODELVIEW_MATRIX_NV 0x0BA6 +#define GL_PATH_MAX_MODELVIEW_STACK_DEPTH_NV 0x0D36 +#define GL_PATH_TRANSPOSE_MODELVIEW_MATRIX_NV 0x84E3 +#define GL_PATH_PROJECTION_STACK_DEPTH_NV 0x0BA4 +#define GL_PATH_PROJECTION_MATRIX_NV 0x0BA7 +#define GL_PATH_MAX_PROJECTION_STACK_DEPTH_NV 0x0D38 +#define GL_PATH_TRANSPOSE_PROJECTION_MATRIX_NV 0x84E4 +#define GL_FRAGMENT_INPUT_NV 0x936D +typedef GLuint (GL_APIENTRYP PFNGLGENPATHSNVPROC) (GLsizei range); +typedef void (GL_APIENTRYP PFNGLDELETEPATHSNVPROC) (GLuint path, GLsizei range); +typedef GLboolean (GL_APIENTRYP PFNGLISPATHNVPROC) (GLuint path); +typedef void (GL_APIENTRYP PFNGLPATHCOMMANDSNVPROC) (GLuint path, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords); +typedef void (GL_APIENTRYP PFNGLPATHCOORDSNVPROC) (GLuint path, GLsizei numCoords, GLenum coordType, const void *coords); +typedef void (GL_APIENTRYP PFNGLPATHSUBCOMMANDSNVPROC) (GLuint path, GLsizei commandStart, GLsizei commandsToDelete, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords); +typedef void (GL_APIENTRYP PFNGLPATHSUBCOORDSNVPROC) (GLuint path, GLsizei coordStart, GLsizei numCoords, GLenum coordType, const void *coords); +typedef void (GL_APIENTRYP PFNGLPATHSTRINGNVPROC) (GLuint path, GLenum format, GLsizei length, const void *pathString); +typedef void (GL_APIENTRYP PFNGLPATHGLYPHSNVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLsizei numGlyphs, GLenum type, const void *charcodes, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +typedef void (GL_APIENTRYP PFNGLPATHGLYPHRANGENVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyph, GLsizei numGlyphs, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +typedef void (GL_APIENTRYP PFNGLWEIGHTPATHSNVPROC) (GLuint resultPath, GLsizei numPaths, const GLuint *paths, const GLfloat *weights); +typedef void (GL_APIENTRYP PFNGLCOPYPATHNVPROC) (GLuint resultPath, GLuint srcPath); +typedef void (GL_APIENTRYP PFNGLINTERPOLATEPATHSNVPROC) (GLuint resultPath, GLuint pathA, GLuint pathB, GLfloat weight); +typedef void (GL_APIENTRYP PFNGLTRANSFORMPATHNVPROC) (GLuint resultPath, GLuint srcPath, GLenum transformType, const GLfloat *transformValues); +typedef void (GL_APIENTRYP PFNGLPATHPARAMETERIVNVPROC) (GLuint path, GLenum pname, const GLint *value); +typedef void (GL_APIENTRYP PFNGLPATHPARAMETERINVPROC) (GLuint path, GLenum pname, GLint value); +typedef void (GL_APIENTRYP PFNGLPATHPARAMETERFVNVPROC) (GLuint path, GLenum pname, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPATHPARAMETERFNVPROC) (GLuint path, GLenum pname, GLfloat value); +typedef void (GL_APIENTRYP PFNGLPATHDASHARRAYNVPROC) (GLuint path, GLsizei dashCount, const GLfloat *dashArray); +typedef void (GL_APIENTRYP PFNGLPATHSTENCILFUNCNVPROC) (GLenum func, GLint ref, GLuint mask); +typedef void (GL_APIENTRYP PFNGLPATHSTENCILDEPTHOFFSETNVPROC) (GLfloat factor, GLfloat units); +typedef void (GL_APIENTRYP PFNGLSTENCILFILLPATHNVPROC) (GLuint path, GLenum fillMode, GLuint mask); +typedef void (GL_APIENTRYP PFNGLSTENCILSTROKEPATHNVPROC) (GLuint path, GLint reference, GLuint mask); +typedef void (GL_APIENTRYP PFNGLSTENCILFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum transformType, const GLfloat *transformValues); +typedef void (GL_APIENTRYP PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum transformType, const GLfloat *transformValues); +typedef void (GL_APIENTRYP PFNGLPATHCOVERDEPTHFUNCNVPROC) (GLenum func); +typedef void (GL_APIENTRYP PFNGLCOVERFILLPATHNVPROC) (GLuint path, GLenum coverMode); +typedef void (GL_APIENTRYP PFNGLCOVERSTROKEPATHNVPROC) (GLuint path, GLenum coverMode); +typedef void (GL_APIENTRYP PFNGLCOVERFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); +typedef void (GL_APIENTRYP PFNGLCOVERSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); +typedef void (GL_APIENTRYP PFNGLGETPATHPARAMETERIVNVPROC) (GLuint path, GLenum pname, GLint *value); +typedef void (GL_APIENTRYP PFNGLGETPATHPARAMETERFVNVPROC) (GLuint path, GLenum pname, GLfloat *value); +typedef void (GL_APIENTRYP PFNGLGETPATHCOMMANDSNVPROC) (GLuint path, GLubyte *commands); +typedef void (GL_APIENTRYP PFNGLGETPATHCOORDSNVPROC) (GLuint path, GLfloat *coords); +typedef void (GL_APIENTRYP PFNGLGETPATHDASHARRAYNVPROC) (GLuint path, GLfloat *dashArray); +typedef void (GL_APIENTRYP PFNGLGETPATHMETRICSNVPROC) (GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLsizei stride, GLfloat *metrics); +typedef void (GL_APIENTRYP PFNGLGETPATHMETRICRANGENVPROC) (GLbitfield metricQueryMask, GLuint firstPathName, GLsizei numPaths, GLsizei stride, GLfloat *metrics); +typedef void (GL_APIENTRYP PFNGLGETPATHSPACINGNVPROC) (GLenum pathListMode, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, GLfloat *returnedSpacing); +typedef GLboolean (GL_APIENTRYP PFNGLISPOINTINFILLPATHNVPROC) (GLuint path, GLuint mask, GLfloat x, GLfloat y); +typedef GLboolean (GL_APIENTRYP PFNGLISPOINTINSTROKEPATHNVPROC) (GLuint path, GLfloat x, GLfloat y); +typedef GLfloat (GL_APIENTRYP PFNGLGETPATHLENGTHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments); +typedef GLboolean (GL_APIENTRYP PFNGLPOINTALONGPATHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments, GLfloat distance, GLfloat *x, GLfloat *y, GLfloat *tangentX, GLfloat *tangentY); +typedef void (GL_APIENTRYP PFNGLMATRIXLOAD3X2FNVPROC) (GLenum matrixMode, const GLfloat *m); +typedef void (GL_APIENTRYP PFNGLMATRIXLOAD3X3FNVPROC) (GLenum matrixMode, const GLfloat *m); +typedef void (GL_APIENTRYP PFNGLMATRIXLOADTRANSPOSE3X3FNVPROC) (GLenum matrixMode, const GLfloat *m); +typedef void (GL_APIENTRYP PFNGLMATRIXMULT3X2FNVPROC) (GLenum matrixMode, const GLfloat *m); +typedef void (GL_APIENTRYP PFNGLMATRIXMULT3X3FNVPROC) (GLenum matrixMode, const GLfloat *m); +typedef void (GL_APIENTRYP PFNGLMATRIXMULTTRANSPOSE3X3FNVPROC) (GLenum matrixMode, const GLfloat *m); +typedef void (GL_APIENTRYP PFNGLSTENCILTHENCOVERFILLPATHNVPROC) (GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode); +typedef void (GL_APIENTRYP PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC) (GLuint path, GLint reference, GLuint mask, GLenum coverMode); +typedef void (GL_APIENTRYP PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); +typedef void (GL_APIENTRYP PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); +typedef GLenum (GL_APIENTRYP PFNGLPATHGLYPHINDEXRANGENVPROC) (GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint pathParameterTemplate, GLfloat emScale, GLuint *baseAndCount); +typedef GLenum (GL_APIENTRYP PFNGLPATHGLYPHINDEXARRAYNVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +typedef GLenum (GL_APIENTRYP PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC) (GLuint firstPathName, GLenum fontTarget, GLsizeiptr fontSize, const void *fontData, GLsizei faceIndex, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +typedef void (GL_APIENTRYP PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC) (GLuint program, GLint location, GLenum genMode, GLint components, const GLfloat *coeffs); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMRESOURCEFVNVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei count, GLsizei *length, GLfloat *params); +typedef void (GL_APIENTRYP PFNGLMATRIXFRUSTUMEXTPROC) (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +typedef void (GL_APIENTRYP PFNGLMATRIXLOADIDENTITYEXTPROC) (GLenum mode); +typedef void (GL_APIENTRYP PFNGLMATRIXLOADTRANSPOSEFEXTPROC) (GLenum mode, const GLfloat *m); +typedef void (GL_APIENTRYP PFNGLMATRIXLOADTRANSPOSEDEXTPROC) (GLenum mode, const GLdouble *m); +typedef void (GL_APIENTRYP PFNGLMATRIXLOADFEXTPROC) (GLenum mode, const GLfloat *m); +typedef void (GL_APIENTRYP PFNGLMATRIXLOADDEXTPROC) (GLenum mode, const GLdouble *m); +typedef void (GL_APIENTRYP PFNGLMATRIXMULTTRANSPOSEFEXTPROC) (GLenum mode, const GLfloat *m); +typedef void (GL_APIENTRYP PFNGLMATRIXMULTTRANSPOSEDEXTPROC) (GLenum mode, const GLdouble *m); +typedef void (GL_APIENTRYP PFNGLMATRIXMULTFEXTPROC) (GLenum mode, const GLfloat *m); +typedef void (GL_APIENTRYP PFNGLMATRIXMULTDEXTPROC) (GLenum mode, const GLdouble *m); +typedef void (GL_APIENTRYP PFNGLMATRIXORTHOEXTPROC) (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +typedef void (GL_APIENTRYP PFNGLMATRIXPOPEXTPROC) (GLenum mode); +typedef void (GL_APIENTRYP PFNGLMATRIXPUSHEXTPROC) (GLenum mode); +typedef void (GL_APIENTRYP PFNGLMATRIXROTATEFEXTPROC) (GLenum mode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z); +typedef void (GL_APIENTRYP PFNGLMATRIXROTATEDEXTPROC) (GLenum mode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z); +typedef void (GL_APIENTRYP PFNGLMATRIXSCALEFEXTPROC) (GLenum mode, GLfloat x, GLfloat y, GLfloat z); +typedef void (GL_APIENTRYP PFNGLMATRIXSCALEDEXTPROC) (GLenum mode, GLdouble x, GLdouble y, GLdouble z); +typedef void (GL_APIENTRYP PFNGLMATRIXTRANSLATEFEXTPROC) (GLenum mode, GLfloat x, GLfloat y, GLfloat z); +typedef void (GL_APIENTRYP PFNGLMATRIXTRANSLATEDEXTPROC) (GLenum mode, GLdouble x, GLdouble y, GLdouble z); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL GLuint GL_APIENTRY glGenPathsNV (GLsizei range); +GL_APICALL void GL_APIENTRY glDeletePathsNV (GLuint path, GLsizei range); +GL_APICALL GLboolean GL_APIENTRY glIsPathNV (GLuint path); +GL_APICALL void GL_APIENTRY glPathCommandsNV (GLuint path, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords); +GL_APICALL void GL_APIENTRY glPathCoordsNV (GLuint path, GLsizei numCoords, GLenum coordType, const void *coords); +GL_APICALL void GL_APIENTRY glPathSubCommandsNV (GLuint path, GLsizei commandStart, GLsizei commandsToDelete, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords); +GL_APICALL void GL_APIENTRY glPathSubCoordsNV (GLuint path, GLsizei coordStart, GLsizei numCoords, GLenum coordType, const void *coords); +GL_APICALL void GL_APIENTRY glPathStringNV (GLuint path, GLenum format, GLsizei length, const void *pathString); +GL_APICALL void GL_APIENTRY glPathGlyphsNV (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLsizei numGlyphs, GLenum type, const void *charcodes, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +GL_APICALL void GL_APIENTRY glPathGlyphRangeNV (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyph, GLsizei numGlyphs, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +GL_APICALL void GL_APIENTRY glWeightPathsNV (GLuint resultPath, GLsizei numPaths, const GLuint *paths, const GLfloat *weights); +GL_APICALL void GL_APIENTRY glCopyPathNV (GLuint resultPath, GLuint srcPath); +GL_APICALL void GL_APIENTRY glInterpolatePathsNV (GLuint resultPath, GLuint pathA, GLuint pathB, GLfloat weight); +GL_APICALL void GL_APIENTRY glTransformPathNV (GLuint resultPath, GLuint srcPath, GLenum transformType, const GLfloat *transformValues); +GL_APICALL void GL_APIENTRY glPathParameterivNV (GLuint path, GLenum pname, const GLint *value); +GL_APICALL void GL_APIENTRY glPathParameteriNV (GLuint path, GLenum pname, GLint value); +GL_APICALL void GL_APIENTRY glPathParameterfvNV (GLuint path, GLenum pname, const GLfloat *value); +GL_APICALL void GL_APIENTRY glPathParameterfNV (GLuint path, GLenum pname, GLfloat value); +GL_APICALL void GL_APIENTRY glPathDashArrayNV (GLuint path, GLsizei dashCount, const GLfloat *dashArray); +GL_APICALL void GL_APIENTRY glPathStencilFuncNV (GLenum func, GLint ref, GLuint mask); +GL_APICALL void GL_APIENTRY glPathStencilDepthOffsetNV (GLfloat factor, GLfloat units); +GL_APICALL void GL_APIENTRY glStencilFillPathNV (GLuint path, GLenum fillMode, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilStrokePathNV (GLuint path, GLint reference, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilFillPathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum transformType, const GLfloat *transformValues); +GL_APICALL void GL_APIENTRY glStencilStrokePathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum transformType, const GLfloat *transformValues); +GL_APICALL void GL_APIENTRY glPathCoverDepthFuncNV (GLenum func); +GL_APICALL void GL_APIENTRY glCoverFillPathNV (GLuint path, GLenum coverMode); +GL_APICALL void GL_APIENTRY glCoverStrokePathNV (GLuint path, GLenum coverMode); +GL_APICALL void GL_APIENTRY glCoverFillPathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); +GL_APICALL void GL_APIENTRY glCoverStrokePathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); +GL_APICALL void GL_APIENTRY glGetPathParameterivNV (GLuint path, GLenum pname, GLint *value); +GL_APICALL void GL_APIENTRY glGetPathParameterfvNV (GLuint path, GLenum pname, GLfloat *value); +GL_APICALL void GL_APIENTRY glGetPathCommandsNV (GLuint path, GLubyte *commands); +GL_APICALL void GL_APIENTRY glGetPathCoordsNV (GLuint path, GLfloat *coords); +GL_APICALL void GL_APIENTRY glGetPathDashArrayNV (GLuint path, GLfloat *dashArray); +GL_APICALL void GL_APIENTRY glGetPathMetricsNV (GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLsizei stride, GLfloat *metrics); +GL_APICALL void GL_APIENTRY glGetPathMetricRangeNV (GLbitfield metricQueryMask, GLuint firstPathName, GLsizei numPaths, GLsizei stride, GLfloat *metrics); +GL_APICALL void GL_APIENTRY glGetPathSpacingNV (GLenum pathListMode, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, GLfloat *returnedSpacing); +GL_APICALL GLboolean GL_APIENTRY glIsPointInFillPathNV (GLuint path, GLuint mask, GLfloat x, GLfloat y); +GL_APICALL GLboolean GL_APIENTRY glIsPointInStrokePathNV (GLuint path, GLfloat x, GLfloat y); +GL_APICALL GLfloat GL_APIENTRY glGetPathLengthNV (GLuint path, GLsizei startSegment, GLsizei numSegments); +GL_APICALL GLboolean GL_APIENTRY glPointAlongPathNV (GLuint path, GLsizei startSegment, GLsizei numSegments, GLfloat distance, GLfloat *x, GLfloat *y, GLfloat *tangentX, GLfloat *tangentY); +GL_APICALL void GL_APIENTRY glMatrixLoad3x2fNV (GLenum matrixMode, const GLfloat *m); +GL_APICALL void GL_APIENTRY glMatrixLoad3x3fNV (GLenum matrixMode, const GLfloat *m); +GL_APICALL void GL_APIENTRY glMatrixLoadTranspose3x3fNV (GLenum matrixMode, const GLfloat *m); +GL_APICALL void GL_APIENTRY glMatrixMult3x2fNV (GLenum matrixMode, const GLfloat *m); +GL_APICALL void GL_APIENTRY glMatrixMult3x3fNV (GLenum matrixMode, const GLfloat *m); +GL_APICALL void GL_APIENTRY glMatrixMultTranspose3x3fNV (GLenum matrixMode, const GLfloat *m); +GL_APICALL void GL_APIENTRY glStencilThenCoverFillPathNV (GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode); +GL_APICALL void GL_APIENTRY glStencilThenCoverStrokePathNV (GLuint path, GLint reference, GLuint mask, GLenum coverMode); +GL_APICALL void GL_APIENTRY glStencilThenCoverFillPathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); +GL_APICALL void GL_APIENTRY glStencilThenCoverStrokePathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); +GL_APICALL GLenum GL_APIENTRY glPathGlyphIndexRangeNV (GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint pathParameterTemplate, GLfloat emScale, GLuint *baseAndCount); +GL_APICALL GLenum GL_APIENTRY glPathGlyphIndexArrayNV (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +GL_APICALL GLenum GL_APIENTRY glPathMemoryGlyphIndexArrayNV (GLuint firstPathName, GLenum fontTarget, GLsizeiptr fontSize, const void *fontData, GLsizei faceIndex, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); +GL_APICALL void GL_APIENTRY glProgramPathFragmentInputGenNV (GLuint program, GLint location, GLenum genMode, GLint components, const GLfloat *coeffs); +GL_APICALL void GL_APIENTRY glGetProgramResourcefvNV (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei count, GLsizei *length, GLfloat *params); +GL_APICALL void GL_APIENTRY glMatrixFrustumEXT (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +GL_APICALL void GL_APIENTRY glMatrixLoadIdentityEXT (GLenum mode); +GL_APICALL void GL_APIENTRY glMatrixLoadTransposefEXT (GLenum mode, const GLfloat *m); +GL_APICALL void GL_APIENTRY glMatrixLoadTransposedEXT (GLenum mode, const GLdouble *m); +GL_APICALL void GL_APIENTRY glMatrixLoadfEXT (GLenum mode, const GLfloat *m); +GL_APICALL void GL_APIENTRY glMatrixLoaddEXT (GLenum mode, const GLdouble *m); +GL_APICALL void GL_APIENTRY glMatrixMultTransposefEXT (GLenum mode, const GLfloat *m); +GL_APICALL void GL_APIENTRY glMatrixMultTransposedEXT (GLenum mode, const GLdouble *m); +GL_APICALL void GL_APIENTRY glMatrixMultfEXT (GLenum mode, const GLfloat *m); +GL_APICALL void GL_APIENTRY glMatrixMultdEXT (GLenum mode, const GLdouble *m); +GL_APICALL void GL_APIENTRY glMatrixOrthoEXT (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +GL_APICALL void GL_APIENTRY glMatrixPopEXT (GLenum mode); +GL_APICALL void GL_APIENTRY glMatrixPushEXT (GLenum mode); +GL_APICALL void GL_APIENTRY glMatrixRotatefEXT (GLenum mode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z); +GL_APICALL void GL_APIENTRY glMatrixRotatedEXT (GLenum mode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z); +GL_APICALL void GL_APIENTRY glMatrixScalefEXT (GLenum mode, GLfloat x, GLfloat y, GLfloat z); +GL_APICALL void GL_APIENTRY glMatrixScaledEXT (GLenum mode, GLdouble x, GLdouble y, GLdouble z); +GL_APICALL void GL_APIENTRY glMatrixTranslatefEXT (GLenum mode, GLfloat x, GLfloat y, GLfloat z); +GL_APICALL void GL_APIENTRY glMatrixTranslatedEXT (GLenum mode, GLdouble x, GLdouble y, GLdouble z); +#endif +#endif /* GL_NV_path_rendering */ + +#ifndef GL_NV_path_rendering_shared_edge +#define GL_NV_path_rendering_shared_edge 1 +#define GL_SHARED_EDGE_NV 0xC0 +#endif /* GL_NV_path_rendering_shared_edge */ + +#ifndef GL_NV_pixel_buffer_object +#define GL_NV_pixel_buffer_object 1 +#define GL_PIXEL_PACK_BUFFER_NV 0x88EB +#define GL_PIXEL_UNPACK_BUFFER_NV 0x88EC +#define GL_PIXEL_PACK_BUFFER_BINDING_NV 0x88ED +#define GL_PIXEL_UNPACK_BUFFER_BINDING_NV 0x88EF +#endif /* GL_NV_pixel_buffer_object */ + +#ifndef GL_NV_polygon_mode +#define GL_NV_polygon_mode 1 +#define GL_POLYGON_MODE_NV 0x0B40 +#define GL_POLYGON_OFFSET_POINT_NV 0x2A01 +#define GL_POLYGON_OFFSET_LINE_NV 0x2A02 +#define GL_POINT_NV 0x1B00 +#define GL_LINE_NV 0x1B01 +#define GL_FILL_NV 0x1B02 +typedef void (GL_APIENTRYP PFNGLPOLYGONMODENVPROC) (GLenum face, GLenum mode); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glPolygonModeNV (GLenum face, GLenum mode); +#endif +#endif /* GL_NV_polygon_mode */ + +#ifndef GL_NV_primitive_shading_rate +#define GL_NV_primitive_shading_rate 1 +#define GL_SHADING_RATE_IMAGE_PER_PRIMITIVE_NV 0x95B1 +#define GL_SHADING_RATE_IMAGE_PALETTE_COUNT_NV 0x95B2 +#endif /* GL_NV_primitive_shading_rate */ + +#ifndef GL_NV_read_buffer +#define GL_NV_read_buffer 1 +#define GL_READ_BUFFER_NV 0x0C02 +typedef void (GL_APIENTRYP PFNGLREADBUFFERNVPROC) (GLenum mode); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glReadBufferNV (GLenum mode); +#endif +#endif /* GL_NV_read_buffer */ + +#ifndef GL_NV_read_buffer_front +#define GL_NV_read_buffer_front 1 +#endif /* GL_NV_read_buffer_front */ + +#ifndef GL_NV_read_depth +#define GL_NV_read_depth 1 +#endif /* GL_NV_read_depth */ + +#ifndef GL_NV_read_depth_stencil +#define GL_NV_read_depth_stencil 1 +#endif /* GL_NV_read_depth_stencil */ + +#ifndef GL_NV_read_stencil +#define GL_NV_read_stencil 1 +#endif /* GL_NV_read_stencil */ + +#ifndef GL_NV_representative_fragment_test +#define GL_NV_representative_fragment_test 1 +#define GL_REPRESENTATIVE_FRAGMENT_TEST_NV 0x937F +#endif /* GL_NV_representative_fragment_test */ + +#ifndef GL_NV_sRGB_formats +#define GL_NV_sRGB_formats 1 +#define GL_SLUMINANCE_NV 0x8C46 +#define GL_SLUMINANCE_ALPHA_NV 0x8C44 +#define GL_SRGB8_NV 0x8C41 +#define GL_SLUMINANCE8_NV 0x8C47 +#define GL_SLUMINANCE8_ALPHA8_NV 0x8C45 +#define GL_COMPRESSED_SRGB_S3TC_DXT1_NV 0x8C4C +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_NV 0x8C4D +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_NV 0x8C4E +#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_NV 0x8C4F +#define GL_ETC1_SRGB8_NV 0x88EE +#endif /* GL_NV_sRGB_formats */ + +#ifndef GL_NV_sample_locations +#define GL_NV_sample_locations 1 +#define GL_SAMPLE_LOCATION_SUBPIXEL_BITS_NV 0x933D +#define GL_SAMPLE_LOCATION_PIXEL_GRID_WIDTH_NV 0x933E +#define GL_SAMPLE_LOCATION_PIXEL_GRID_HEIGHT_NV 0x933F +#define GL_PROGRAMMABLE_SAMPLE_LOCATION_TABLE_SIZE_NV 0x9340 +#define GL_SAMPLE_LOCATION_NV 0x8E50 +#define GL_PROGRAMMABLE_SAMPLE_LOCATION_NV 0x9341 +#define GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_NV 0x9342 +#define GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_NV 0x9343 +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERSAMPLELOCATIONSFVNVPROC) (GLenum target, GLuint start, GLsizei count, const GLfloat *v); +typedef void (GL_APIENTRYP PFNGLNAMEDFRAMEBUFFERSAMPLELOCATIONSFVNVPROC) (GLuint framebuffer, GLuint start, GLsizei count, const GLfloat *v); +typedef void (GL_APIENTRYP PFNGLRESOLVEDEPTHVALUESNVPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glFramebufferSampleLocationsfvNV (GLenum target, GLuint start, GLsizei count, const GLfloat *v); +GL_APICALL void GL_APIENTRY glNamedFramebufferSampleLocationsfvNV (GLuint framebuffer, GLuint start, GLsizei count, const GLfloat *v); +GL_APICALL void GL_APIENTRY glResolveDepthValuesNV (void); +#endif +#endif /* GL_NV_sample_locations */ + +#ifndef GL_NV_sample_mask_override_coverage +#define GL_NV_sample_mask_override_coverage 1 +#endif /* GL_NV_sample_mask_override_coverage */ + +#ifndef GL_NV_scissor_exclusive +#define GL_NV_scissor_exclusive 1 +#define GL_SCISSOR_TEST_EXCLUSIVE_NV 0x9555 +#define GL_SCISSOR_BOX_EXCLUSIVE_NV 0x9556 +typedef void (GL_APIENTRYP PFNGLSCISSOREXCLUSIVENVPROC) (GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLSCISSOREXCLUSIVEARRAYVNVPROC) (GLuint first, GLsizei count, const GLint *v); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glScissorExclusiveNV (GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glScissorExclusiveArrayvNV (GLuint first, GLsizei count, const GLint *v); +#endif +#endif /* GL_NV_scissor_exclusive */ + +#ifndef GL_NV_shader_atomic_fp16_vector +#define GL_NV_shader_atomic_fp16_vector 1 +#endif /* GL_NV_shader_atomic_fp16_vector */ + +#ifndef GL_NV_shader_noperspective_interpolation +#define GL_NV_shader_noperspective_interpolation 1 +#endif /* GL_NV_shader_noperspective_interpolation */ + +#ifndef GL_NV_shader_subgroup_partitioned +#define GL_NV_shader_subgroup_partitioned 1 +#define GL_SUBGROUP_FEATURE_PARTITIONED_BIT_NV 0x00000100 +#endif /* GL_NV_shader_subgroup_partitioned */ + +#ifndef GL_NV_shader_texture_footprint +#define GL_NV_shader_texture_footprint 1 +#endif /* GL_NV_shader_texture_footprint */ + +#ifndef GL_NV_shading_rate_image +#define GL_NV_shading_rate_image 1 +#define GL_SHADING_RATE_IMAGE_NV 0x9563 +#define GL_SHADING_RATE_NO_INVOCATIONS_NV 0x9564 +#define GL_SHADING_RATE_1_INVOCATION_PER_PIXEL_NV 0x9565 +#define GL_SHADING_RATE_1_INVOCATION_PER_1X2_PIXELS_NV 0x9566 +#define GL_SHADING_RATE_1_INVOCATION_PER_2X1_PIXELS_NV 0x9567 +#define GL_SHADING_RATE_1_INVOCATION_PER_2X2_PIXELS_NV 0x9568 +#define GL_SHADING_RATE_1_INVOCATION_PER_2X4_PIXELS_NV 0x9569 +#define GL_SHADING_RATE_1_INVOCATION_PER_4X2_PIXELS_NV 0x956A +#define GL_SHADING_RATE_1_INVOCATION_PER_4X4_PIXELS_NV 0x956B +#define GL_SHADING_RATE_2_INVOCATIONS_PER_PIXEL_NV 0x956C +#define GL_SHADING_RATE_4_INVOCATIONS_PER_PIXEL_NV 0x956D +#define GL_SHADING_RATE_8_INVOCATIONS_PER_PIXEL_NV 0x956E +#define GL_SHADING_RATE_16_INVOCATIONS_PER_PIXEL_NV 0x956F +#define GL_SHADING_RATE_IMAGE_BINDING_NV 0x955B +#define GL_SHADING_RATE_IMAGE_TEXEL_WIDTH_NV 0x955C +#define GL_SHADING_RATE_IMAGE_TEXEL_HEIGHT_NV 0x955D +#define GL_SHADING_RATE_IMAGE_PALETTE_SIZE_NV 0x955E +#define GL_MAX_COARSE_FRAGMENT_SAMPLES_NV 0x955F +#define GL_SHADING_RATE_SAMPLE_ORDER_DEFAULT_NV 0x95AE +#define GL_SHADING_RATE_SAMPLE_ORDER_PIXEL_MAJOR_NV 0x95AF +#define GL_SHADING_RATE_SAMPLE_ORDER_SAMPLE_MAJOR_NV 0x95B0 +typedef void (GL_APIENTRYP PFNGLBINDSHADINGRATEIMAGENVPROC) (GLuint texture); +typedef void (GL_APIENTRYP PFNGLGETSHADINGRATEIMAGEPALETTENVPROC) (GLuint viewport, GLuint entry, GLenum *rate); +typedef void (GL_APIENTRYP PFNGLGETSHADINGRATESAMPLELOCATIONIVNVPROC) (GLenum rate, GLuint samples, GLuint index, GLint *location); +typedef void (GL_APIENTRYP PFNGLSHADINGRATEIMAGEBARRIERNVPROC) (GLboolean synchronize); +typedef void (GL_APIENTRYP PFNGLSHADINGRATEIMAGEPALETTENVPROC) (GLuint viewport, GLuint first, GLsizei count, const GLenum *rates); +typedef void (GL_APIENTRYP PFNGLSHADINGRATESAMPLEORDERNVPROC) (GLenum order); +typedef void (GL_APIENTRYP PFNGLSHADINGRATESAMPLEORDERCUSTOMNVPROC) (GLenum rate, GLuint samples, const GLint *locations); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glBindShadingRateImageNV (GLuint texture); +GL_APICALL void GL_APIENTRY glGetShadingRateImagePaletteNV (GLuint viewport, GLuint entry, GLenum *rate); +GL_APICALL void GL_APIENTRY glGetShadingRateSampleLocationivNV (GLenum rate, GLuint samples, GLuint index, GLint *location); +GL_APICALL void GL_APIENTRY glShadingRateImageBarrierNV (GLboolean synchronize); +GL_APICALL void GL_APIENTRY glShadingRateImagePaletteNV (GLuint viewport, GLuint first, GLsizei count, const GLenum *rates); +GL_APICALL void GL_APIENTRY glShadingRateSampleOrderNV (GLenum order); +GL_APICALL void GL_APIENTRY glShadingRateSampleOrderCustomNV (GLenum rate, GLuint samples, const GLint *locations); +#endif +#endif /* GL_NV_shading_rate_image */ + +#ifndef GL_NV_shadow_samplers_array +#define GL_NV_shadow_samplers_array 1 +#define GL_SAMPLER_2D_ARRAY_SHADOW_NV 0x8DC4 +#endif /* GL_NV_shadow_samplers_array */ + +#ifndef GL_NV_shadow_samplers_cube +#define GL_NV_shadow_samplers_cube 1 +#define GL_SAMPLER_CUBE_SHADOW_NV 0x8DC5 +#endif /* GL_NV_shadow_samplers_cube */ + +#ifndef GL_NV_stereo_view_rendering +#define GL_NV_stereo_view_rendering 1 +#endif /* GL_NV_stereo_view_rendering */ + +#ifndef GL_NV_texture_border_clamp +#define GL_NV_texture_border_clamp 1 +#define GL_TEXTURE_BORDER_COLOR_NV 0x1004 +#define GL_CLAMP_TO_BORDER_NV 0x812D +#endif /* GL_NV_texture_border_clamp */ + +#ifndef GL_NV_texture_compression_s3tc_update +#define GL_NV_texture_compression_s3tc_update 1 +#endif /* GL_NV_texture_compression_s3tc_update */ + +#ifndef GL_NV_texture_npot_2D_mipmap +#define GL_NV_texture_npot_2D_mipmap 1 +#endif /* GL_NV_texture_npot_2D_mipmap */ + +#ifndef GL_NV_timeline_semaphore +#define GL_NV_timeline_semaphore 1 +#define GL_TIMELINE_SEMAPHORE_VALUE_NV 0x9595 +#define GL_SEMAPHORE_TYPE_NV 0x95B3 +#define GL_SEMAPHORE_TYPE_BINARY_NV 0x95B4 +#define GL_SEMAPHORE_TYPE_TIMELINE_NV 0x95B5 +#define GL_MAX_TIMELINE_SEMAPHORE_VALUE_DIFFERENCE_NV 0x95B6 +typedef void (GL_APIENTRYP PFNGLCREATESEMAPHORESNVPROC) (GLsizei n, GLuint *semaphores); +typedef void (GL_APIENTRYP PFNGLSEMAPHOREPARAMETERIVNVPROC) (GLuint semaphore, GLenum pname, const GLint *params); +typedef void (GL_APIENTRYP PFNGLGETSEMAPHOREPARAMETERIVNVPROC) (GLuint semaphore, GLenum pname, GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glCreateSemaphoresNV (GLsizei n, GLuint *semaphores); +GL_APICALL void GL_APIENTRY glSemaphoreParameterivNV (GLuint semaphore, GLenum pname, const GLint *params); +GL_APICALL void GL_APIENTRY glGetSemaphoreParameterivNV (GLuint semaphore, GLenum pname, GLint *params); +#endif +#endif /* GL_NV_timeline_semaphore */ + +#ifndef GL_NV_viewport_array +#define GL_NV_viewport_array 1 +#define GL_MAX_VIEWPORTS_NV 0x825B +#define GL_VIEWPORT_SUBPIXEL_BITS_NV 0x825C +#define GL_VIEWPORT_BOUNDS_RANGE_NV 0x825D +#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX_NV 0x825F +typedef void (GL_APIENTRYP PFNGLVIEWPORTARRAYVNVPROC) (GLuint first, GLsizei count, const GLfloat *v); +typedef void (GL_APIENTRYP PFNGLVIEWPORTINDEXEDFNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); +typedef void (GL_APIENTRYP PFNGLVIEWPORTINDEXEDFVNVPROC) (GLuint index, const GLfloat *v); +typedef void (GL_APIENTRYP PFNGLSCISSORARRAYVNVPROC) (GLuint first, GLsizei count, const GLint *v); +typedef void (GL_APIENTRYP PFNGLSCISSORINDEXEDNVPROC) (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLSCISSORINDEXEDVNVPROC) (GLuint index, const GLint *v); +typedef void (GL_APIENTRYP PFNGLDEPTHRANGEARRAYFVNVPROC) (GLuint first, GLsizei count, const GLfloat *v); +typedef void (GL_APIENTRYP PFNGLDEPTHRANGEINDEXEDFNVPROC) (GLuint index, GLfloat n, GLfloat f); +typedef void (GL_APIENTRYP PFNGLGETFLOATI_VNVPROC) (GLenum target, GLuint index, GLfloat *data); +typedef void (GL_APIENTRYP PFNGLENABLEINVPROC) (GLenum target, GLuint index); +typedef void (GL_APIENTRYP PFNGLDISABLEINVPROC) (GLenum target, GLuint index); +typedef GLboolean (GL_APIENTRYP PFNGLISENABLEDINVPROC) (GLenum target, GLuint index); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glViewportArrayvNV (GLuint first, GLsizei count, const GLfloat *v); +GL_APICALL void GL_APIENTRY glViewportIndexedfNV (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); +GL_APICALL void GL_APIENTRY glViewportIndexedfvNV (GLuint index, const GLfloat *v); +GL_APICALL void GL_APIENTRY glScissorArrayvNV (GLuint first, GLsizei count, const GLint *v); +GL_APICALL void GL_APIENTRY glScissorIndexedNV (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glScissorIndexedvNV (GLuint index, const GLint *v); +GL_APICALL void GL_APIENTRY glDepthRangeArrayfvNV (GLuint first, GLsizei count, const GLfloat *v); +GL_APICALL void GL_APIENTRY glDepthRangeIndexedfNV (GLuint index, GLfloat n, GLfloat f); +GL_APICALL void GL_APIENTRY glGetFloati_vNV (GLenum target, GLuint index, GLfloat *data); +GL_APICALL void GL_APIENTRY glEnableiNV (GLenum target, GLuint index); +GL_APICALL void GL_APIENTRY glDisableiNV (GLenum target, GLuint index); +GL_APICALL GLboolean GL_APIENTRY glIsEnablediNV (GLenum target, GLuint index); +#endif +#endif /* GL_NV_viewport_array */ + +#ifndef GL_NV_viewport_array2 +#define GL_NV_viewport_array2 1 +#endif /* GL_NV_viewport_array2 */ + +#ifndef GL_NV_viewport_swizzle +#define GL_NV_viewport_swizzle 1 +#define GL_VIEWPORT_SWIZZLE_POSITIVE_X_NV 0x9350 +#define GL_VIEWPORT_SWIZZLE_NEGATIVE_X_NV 0x9351 +#define GL_VIEWPORT_SWIZZLE_POSITIVE_Y_NV 0x9352 +#define GL_VIEWPORT_SWIZZLE_NEGATIVE_Y_NV 0x9353 +#define GL_VIEWPORT_SWIZZLE_POSITIVE_Z_NV 0x9354 +#define GL_VIEWPORT_SWIZZLE_NEGATIVE_Z_NV 0x9355 +#define GL_VIEWPORT_SWIZZLE_POSITIVE_W_NV 0x9356 +#define GL_VIEWPORT_SWIZZLE_NEGATIVE_W_NV 0x9357 +#define GL_VIEWPORT_SWIZZLE_X_NV 0x9358 +#define GL_VIEWPORT_SWIZZLE_Y_NV 0x9359 +#define GL_VIEWPORT_SWIZZLE_Z_NV 0x935A +#define GL_VIEWPORT_SWIZZLE_W_NV 0x935B +typedef void (GL_APIENTRYP PFNGLVIEWPORTSWIZZLENVPROC) (GLuint index, GLenum swizzlex, GLenum swizzley, GLenum swizzlez, GLenum swizzlew); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glViewportSwizzleNV (GLuint index, GLenum swizzlex, GLenum swizzley, GLenum swizzlez, GLenum swizzlew); +#endif +#endif /* GL_NV_viewport_swizzle */ + +#ifndef GL_OVR_multiview +#define GL_OVR_multiview 1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR 0x9630 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR 0x9632 +#define GL_MAX_VIEWS_OVR 0x9631 +#define GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR 0x9633 +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glFramebufferTextureMultiviewOVR (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews); +#endif +#endif /* GL_OVR_multiview */ + +#ifndef GL_OVR_multiview2 +#define GL_OVR_multiview2 1 +#endif /* GL_OVR_multiview2 */ + +#ifndef GL_OVR_multiview_multisampled_render_to_texture +#define GL_OVR_multiview_multisampled_render_to_texture 1 +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVRPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLsizei samples, GLint baseViewIndex, GLsizei numViews); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glFramebufferTextureMultisampleMultiviewOVR (GLenum target, GLenum attachment, GLuint texture, GLint level, GLsizei samples, GLint baseViewIndex, GLsizei numViews); +#endif +#endif /* GL_OVR_multiview_multisampled_render_to_texture */ + +#ifndef GL_QCOM_YUV_texture_gather +#define GL_QCOM_YUV_texture_gather 1 +#endif /* GL_QCOM_YUV_texture_gather */ + +#ifndef GL_QCOM_alpha_test +#define GL_QCOM_alpha_test 1 +#define GL_ALPHA_TEST_QCOM 0x0BC0 +#define GL_ALPHA_TEST_FUNC_QCOM 0x0BC1 +#define GL_ALPHA_TEST_REF_QCOM 0x0BC2 +typedef void (GL_APIENTRYP PFNGLALPHAFUNCQCOMPROC) (GLenum func, GLclampf ref); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glAlphaFuncQCOM (GLenum func, GLclampf ref); +#endif +#endif /* GL_QCOM_alpha_test */ + +#ifndef GL_QCOM_binning_control +#define GL_QCOM_binning_control 1 +#define GL_BINNING_CONTROL_HINT_QCOM 0x8FB0 +#define GL_CPU_OPTIMIZED_QCOM 0x8FB1 +#define GL_GPU_OPTIMIZED_QCOM 0x8FB2 +#define GL_RENDER_DIRECT_TO_FRAMEBUFFER_QCOM 0x8FB3 +#endif /* GL_QCOM_binning_control */ + +#ifndef GL_QCOM_driver_control +#define GL_QCOM_driver_control 1 +typedef void (GL_APIENTRYP PFNGLGETDRIVERCONTROLSQCOMPROC) (GLint *num, GLsizei size, GLuint *driverControls); +typedef void (GL_APIENTRYP PFNGLGETDRIVERCONTROLSTRINGQCOMPROC) (GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString); +typedef void (GL_APIENTRYP PFNGLENABLEDRIVERCONTROLQCOMPROC) (GLuint driverControl); +typedef void (GL_APIENTRYP PFNGLDISABLEDRIVERCONTROLQCOMPROC) (GLuint driverControl); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGetDriverControlsQCOM (GLint *num, GLsizei size, GLuint *driverControls); +GL_APICALL void GL_APIENTRY glGetDriverControlStringQCOM (GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString); +GL_APICALL void GL_APIENTRY glEnableDriverControlQCOM (GLuint driverControl); +GL_APICALL void GL_APIENTRY glDisableDriverControlQCOM (GLuint driverControl); +#endif +#endif /* GL_QCOM_driver_control */ + +#ifndef GL_QCOM_extended_get +#define GL_QCOM_extended_get 1 +#define GL_TEXTURE_WIDTH_QCOM 0x8BD2 +#define GL_TEXTURE_HEIGHT_QCOM 0x8BD3 +#define GL_TEXTURE_DEPTH_QCOM 0x8BD4 +#define GL_TEXTURE_INTERNAL_FORMAT_QCOM 0x8BD5 +#define GL_TEXTURE_FORMAT_QCOM 0x8BD6 +#define GL_TEXTURE_TYPE_QCOM 0x8BD7 +#define GL_TEXTURE_IMAGE_VALID_QCOM 0x8BD8 +#define GL_TEXTURE_NUM_LEVELS_QCOM 0x8BD9 +#define GL_TEXTURE_TARGET_QCOM 0x8BDA +#define GL_TEXTURE_OBJECT_VALID_QCOM 0x8BDB +#define GL_STATE_RESTORE 0x8BDC +typedef void (GL_APIENTRYP PFNGLEXTGETTEXTURESQCOMPROC) (GLuint *textures, GLint maxTextures, GLint *numTextures); +typedef void (GL_APIENTRYP PFNGLEXTGETBUFFERSQCOMPROC) (GLuint *buffers, GLint maxBuffers, GLint *numBuffers); +typedef void (GL_APIENTRYP PFNGLEXTGETRENDERBUFFERSQCOMPROC) (GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers); +typedef void (GL_APIENTRYP PFNGLEXTGETFRAMEBUFFERSQCOMPROC) (GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers); +typedef void (GL_APIENTRYP PFNGLEXTGETTEXLEVELPARAMETERIVQCOMPROC) (GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLEXTTEXOBJECTSTATEOVERRIDEIQCOMPROC) (GLenum target, GLenum pname, GLint param); +typedef void (GL_APIENTRYP PFNGLEXTGETTEXSUBIMAGEQCOMPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, void *texels); +typedef void (GL_APIENTRYP PFNGLEXTGETBUFFERPOINTERVQCOMPROC) (GLenum target, void **params); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glExtGetTexturesQCOM (GLuint *textures, GLint maxTextures, GLint *numTextures); +GL_APICALL void GL_APIENTRY glExtGetBuffersQCOM (GLuint *buffers, GLint maxBuffers, GLint *numBuffers); +GL_APICALL void GL_APIENTRY glExtGetRenderbuffersQCOM (GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers); +GL_APICALL void GL_APIENTRY glExtGetFramebuffersQCOM (GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers); +GL_APICALL void GL_APIENTRY glExtGetTexLevelParameterivQCOM (GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glExtTexObjectStateOverrideiQCOM (GLenum target, GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glExtGetTexSubImageQCOM (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, void *texels); +GL_APICALL void GL_APIENTRY glExtGetBufferPointervQCOM (GLenum target, void **params); +#endif +#endif /* GL_QCOM_extended_get */ + +#ifndef GL_QCOM_extended_get2 +#define GL_QCOM_extended_get2 1 +typedef void (GL_APIENTRYP PFNGLEXTGETSHADERSQCOMPROC) (GLuint *shaders, GLint maxShaders, GLint *numShaders); +typedef void (GL_APIENTRYP PFNGLEXTGETPROGRAMSQCOMPROC) (GLuint *programs, GLint maxPrograms, GLint *numPrograms); +typedef GLboolean (GL_APIENTRYP PFNGLEXTISPROGRAMBINARYQCOMPROC) (GLuint program); +typedef void (GL_APIENTRYP PFNGLEXTGETPROGRAMBINARYSOURCEQCOMPROC) (GLuint program, GLenum shadertype, GLchar *source, GLint *length); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glExtGetShadersQCOM (GLuint *shaders, GLint maxShaders, GLint *numShaders); +GL_APICALL void GL_APIENTRY glExtGetProgramsQCOM (GLuint *programs, GLint maxPrograms, GLint *numPrograms); +GL_APICALL GLboolean GL_APIENTRY glExtIsProgramBinaryQCOM (GLuint program); +GL_APICALL void GL_APIENTRY glExtGetProgramBinarySourceQCOM (GLuint program, GLenum shadertype, GLchar *source, GLint *length); +#endif +#endif /* GL_QCOM_extended_get2 */ + +#ifndef GL_QCOM_frame_extrapolation +#define GL_QCOM_frame_extrapolation 1 +typedef void (GL_APIENTRYP PFNGLEXTRAPOLATETEX2DQCOMPROC) (GLuint src1, GLuint src2, GLuint output, GLfloat scaleFactor); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glExtrapolateTex2DQCOM (GLuint src1, GLuint src2, GLuint output, GLfloat scaleFactor); +#endif +#endif /* GL_QCOM_frame_extrapolation */ + +#ifndef GL_QCOM_framebuffer_foveated +#define GL_QCOM_framebuffer_foveated 1 +#define GL_FOVEATION_ENABLE_BIT_QCOM 0x00000001 +#define GL_FOVEATION_SCALED_BIN_METHOD_BIT_QCOM 0x00000002 +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERFOVEATIONCONFIGQCOMPROC) (GLuint framebuffer, GLuint numLayers, GLuint focalPointsPerLayer, GLuint requestedFeatures, GLuint *providedFeatures); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERFOVEATIONPARAMETERSQCOMPROC) (GLuint framebuffer, GLuint layer, GLuint focalPoint, GLfloat focalX, GLfloat focalY, GLfloat gainX, GLfloat gainY, GLfloat foveaArea); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glFramebufferFoveationConfigQCOM (GLuint framebuffer, GLuint numLayers, GLuint focalPointsPerLayer, GLuint requestedFeatures, GLuint *providedFeatures); +GL_APICALL void GL_APIENTRY glFramebufferFoveationParametersQCOM (GLuint framebuffer, GLuint layer, GLuint focalPoint, GLfloat focalX, GLfloat focalY, GLfloat gainX, GLfloat gainY, GLfloat foveaArea); +#endif +#endif /* GL_QCOM_framebuffer_foveated */ + +#ifndef GL_QCOM_motion_estimation +#define GL_QCOM_motion_estimation 1 +#define GL_MOTION_ESTIMATION_SEARCH_BLOCK_X_QCOM 0x8C90 +#define GL_MOTION_ESTIMATION_SEARCH_BLOCK_Y_QCOM 0x8C91 +typedef void (GL_APIENTRYP PFNGLTEXESTIMATEMOTIONQCOMPROC) (GLuint ref, GLuint target, GLuint output); +typedef void (GL_APIENTRYP PFNGLTEXESTIMATEMOTIONREGIONSQCOMPROC) (GLuint ref, GLuint target, GLuint output, GLuint mask); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glTexEstimateMotionQCOM (GLuint ref, GLuint target, GLuint output); +GL_APICALL void GL_APIENTRY glTexEstimateMotionRegionsQCOM (GLuint ref, GLuint target, GLuint output, GLuint mask); +#endif +#endif /* GL_QCOM_motion_estimation */ + +#ifndef GL_QCOM_perfmon_global_mode +#define GL_QCOM_perfmon_global_mode 1 +#define GL_PERFMON_GLOBAL_MODE_QCOM 0x8FA0 +#endif /* GL_QCOM_perfmon_global_mode */ + +#ifndef GL_QCOM_render_shared_exponent +#define GL_QCOM_render_shared_exponent 1 +#endif /* GL_QCOM_render_shared_exponent */ + +#ifndef GL_QCOM_shader_framebuffer_fetch_noncoherent +#define GL_QCOM_shader_framebuffer_fetch_noncoherent 1 +#define GL_FRAMEBUFFER_FETCH_NONCOHERENT_QCOM 0x96A2 +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERFETCHBARRIERQCOMPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glFramebufferFetchBarrierQCOM (void); +#endif +#endif /* GL_QCOM_shader_framebuffer_fetch_noncoherent */ + +#ifndef GL_QCOM_shader_framebuffer_fetch_rate +#define GL_QCOM_shader_framebuffer_fetch_rate 1 +#endif /* GL_QCOM_shader_framebuffer_fetch_rate */ + +#ifndef GL_QCOM_shading_rate +#define GL_QCOM_shading_rate 1 +#define GL_SHADING_RATE_QCOM 0x96A4 +#define GL_SHADING_RATE_PRESERVE_ASPECT_RATIO_QCOM 0x96A5 +#define GL_SHADING_RATE_1X1_PIXELS_QCOM 0x96A6 +#define GL_SHADING_RATE_1X2_PIXELS_QCOM 0x96A7 +#define GL_SHADING_RATE_2X1_PIXELS_QCOM 0x96A8 +#define GL_SHADING_RATE_2X2_PIXELS_QCOM 0x96A9 +#define GL_SHADING_RATE_4X2_PIXELS_QCOM 0x96AC +#define GL_SHADING_RATE_4X4_PIXELS_QCOM 0x96AE +typedef void (GL_APIENTRYP PFNGLSHADINGRATEQCOMPROC) (GLenum rate); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glShadingRateQCOM (GLenum rate); +#endif +#endif /* GL_QCOM_shading_rate */ + +#ifndef GL_QCOM_texture_foveated +#define GL_QCOM_texture_foveated 1 +#define GL_TEXTURE_FOVEATED_FEATURE_BITS_QCOM 0x8BFB +#define GL_TEXTURE_FOVEATED_MIN_PIXEL_DENSITY_QCOM 0x8BFC +#define GL_TEXTURE_FOVEATED_FEATURE_QUERY_QCOM 0x8BFD +#define GL_TEXTURE_FOVEATED_NUM_FOCAL_POINTS_QUERY_QCOM 0x8BFE +#define GL_FRAMEBUFFER_INCOMPLETE_FOVEATION_QCOM 0x8BFF +typedef void (GL_APIENTRYP PFNGLTEXTUREFOVEATIONPARAMETERSQCOMPROC) (GLuint texture, GLuint layer, GLuint focalPoint, GLfloat focalX, GLfloat focalY, GLfloat gainX, GLfloat gainY, GLfloat foveaArea); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glTextureFoveationParametersQCOM (GLuint texture, GLuint layer, GLuint focalPoint, GLfloat focalX, GLfloat focalY, GLfloat gainX, GLfloat gainY, GLfloat foveaArea); +#endif +#endif /* GL_QCOM_texture_foveated */ + +#ifndef GL_QCOM_texture_foveated2 +#define GL_QCOM_texture_foveated2 1 +#define GL_TEXTURE_FOVEATED_CUTOFF_DENSITY_QCOM 0x96A0 +#endif /* GL_QCOM_texture_foveated2 */ + +#ifndef GL_QCOM_texture_foveated_subsampled_layout +#define GL_QCOM_texture_foveated_subsampled_layout 1 +#define GL_FOVEATION_SUBSAMPLED_LAYOUT_METHOD_BIT_QCOM 0x00000004 +#define GL_MAX_SHADER_SUBSAMPLED_IMAGE_UNITS_QCOM 0x8FA1 +#endif /* GL_QCOM_texture_foveated_subsampled_layout */ + +#ifndef GL_QCOM_tiled_rendering +#define GL_QCOM_tiled_rendering 1 +#define GL_COLOR_BUFFER_BIT0_QCOM 0x00000001 +#define GL_COLOR_BUFFER_BIT1_QCOM 0x00000002 +#define GL_COLOR_BUFFER_BIT2_QCOM 0x00000004 +#define GL_COLOR_BUFFER_BIT3_QCOM 0x00000008 +#define GL_COLOR_BUFFER_BIT4_QCOM 0x00000010 +#define GL_COLOR_BUFFER_BIT5_QCOM 0x00000020 +#define GL_COLOR_BUFFER_BIT6_QCOM 0x00000040 +#define GL_COLOR_BUFFER_BIT7_QCOM 0x00000080 +#define GL_DEPTH_BUFFER_BIT0_QCOM 0x00000100 +#define GL_DEPTH_BUFFER_BIT1_QCOM 0x00000200 +#define GL_DEPTH_BUFFER_BIT2_QCOM 0x00000400 +#define GL_DEPTH_BUFFER_BIT3_QCOM 0x00000800 +#define GL_DEPTH_BUFFER_BIT4_QCOM 0x00001000 +#define GL_DEPTH_BUFFER_BIT5_QCOM 0x00002000 +#define GL_DEPTH_BUFFER_BIT6_QCOM 0x00004000 +#define GL_DEPTH_BUFFER_BIT7_QCOM 0x00008000 +#define GL_STENCIL_BUFFER_BIT0_QCOM 0x00010000 +#define GL_STENCIL_BUFFER_BIT1_QCOM 0x00020000 +#define GL_STENCIL_BUFFER_BIT2_QCOM 0x00040000 +#define GL_STENCIL_BUFFER_BIT3_QCOM 0x00080000 +#define GL_STENCIL_BUFFER_BIT4_QCOM 0x00100000 +#define GL_STENCIL_BUFFER_BIT5_QCOM 0x00200000 +#define GL_STENCIL_BUFFER_BIT6_QCOM 0x00400000 +#define GL_STENCIL_BUFFER_BIT7_QCOM 0x00800000 +#define GL_MULTISAMPLE_BUFFER_BIT0_QCOM 0x01000000 +#define GL_MULTISAMPLE_BUFFER_BIT1_QCOM 0x02000000 +#define GL_MULTISAMPLE_BUFFER_BIT2_QCOM 0x04000000 +#define GL_MULTISAMPLE_BUFFER_BIT3_QCOM 0x08000000 +#define GL_MULTISAMPLE_BUFFER_BIT4_QCOM 0x10000000 +#define GL_MULTISAMPLE_BUFFER_BIT5_QCOM 0x20000000 +#define GL_MULTISAMPLE_BUFFER_BIT6_QCOM 0x40000000 +#define GL_MULTISAMPLE_BUFFER_BIT7_QCOM 0x80000000 +typedef void (GL_APIENTRYP PFNGLSTARTTILINGQCOMPROC) (GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask); +typedef void (GL_APIENTRYP PFNGLENDTILINGQCOMPROC) (GLbitfield preserveMask); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glStartTilingQCOM (GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask); +GL_APICALL void GL_APIENTRY glEndTilingQCOM (GLbitfield preserveMask); +#endif +#endif /* GL_QCOM_tiled_rendering */ + +#ifndef GL_QCOM_writeonly_rendering +#define GL_QCOM_writeonly_rendering 1 +#define GL_WRITEONLY_RENDERING_QCOM 0x8823 +#endif /* GL_QCOM_writeonly_rendering */ + +#ifndef GL_VIV_shader_binary +#define GL_VIV_shader_binary 1 +#define GL_SHADER_BINARY_VIV 0x8FC4 +#endif /* GL_VIV_shader_binary */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/SDL2-2.30.5/include/SDL_opengles2_gl2platform.h b/SDL2-2.30.5/include/SDL_opengles2_gl2platform.h new file mode 100644 index 0000000..426796e --- /dev/null +++ b/SDL2-2.30.5/include/SDL_opengles2_gl2platform.h @@ -0,0 +1,27 @@ +#ifndef __gl2platform_h_ +#define __gl2platform_h_ + +/* +** Copyright 2017-2020 The Khronos Group Inc. +** SPDX-License-Identifier: Apache-2.0 +*/ + +/* Platform-specific types and definitions for OpenGL ES 2.X gl2.h + * + * Adopters may modify khrplatform.h and this file to suit their platform. + * Please contribute modifications back to Khronos as pull requests on the + * public github repository: + * https://github.com/KhronosGroup/OpenGL-Registry + */ + +/*#include */ + +#ifndef GL_APICALL +#define GL_APICALL KHRONOS_APICALL +#endif + +#ifndef GL_APIENTRY +#define GL_APIENTRY KHRONOS_APIENTRY +#endif + +#endif /* __gl2platform_h_ */ diff --git a/SDL2-2.0.12/include/SDL_opengles2_khrplatform.h b/SDL2-2.30.5/include/SDL_opengles2_khrplatform.h similarity index 84% rename from SDL2-2.0.12/include/SDL_opengles2_khrplatform.h rename to SDL2-2.30.5/include/SDL_opengles2_khrplatform.h index c9e6f17..0164644 100644 --- a/SDL2-2.0.12/include/SDL_opengles2_khrplatform.h +++ b/SDL2-2.30.5/include/SDL_opengles2_khrplatform.h @@ -2,7 +2,7 @@ #define __khrplatform_h_ /* -** Copyright (c) 2008-2009 The Khronos Group Inc. +** Copyright (c) 2008-2018 The Khronos Group Inc. ** ** Permission is hereby granted, free of charge, to any person obtaining a ** copy of this software and/or associated documentation files (the @@ -26,18 +26,16 @@ /* Khronos platform-specific types and definitions. * - * $Revision: 23298 $ on $Date: 2013-09-30 17:07:13 -0700 (Mon, 30 Sep 2013) $ + * The master copy of khrplatform.h is maintained in the Khronos EGL + * Registry repository at https://github.com/KhronosGroup/EGL-Registry + * The last semantic modification to khrplatform.h was at commit ID: + * 67a3e0864c2d75ea5287b9f3d2eb74a745936692 * * Adopters may modify this file to suit their platform. Adopters are * encouraged to submit platform specific modifications to the Khronos * group so that they can be included in future versions of this file. - * Please submit changes by sending them to the public Khronos Bugzilla - * (http://khronos.org/bugzilla) by filing a bug against product - * "Khronos (general)" component "Registry". - * - * A predefined template which fills in some of the bug fields can be - * reached using http://tinyurl.com/khrplatform-h-bugreport, but you - * must create a Bugzilla login first. + * Please submit changes by filing pull requests or issues on + * the EGL Registry repository linked above. * * * See the Implementer's Guidelines for information about where this file @@ -92,15 +90,25 @@ * int arg2) KHRONOS_APIATTRIBUTES; */ +#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC) +# define KHRONOS_STATIC 1 +#endif + /*------------------------------------------------------------------------- * Definition of KHRONOS_APICALL *------------------------------------------------------------------------- * This precedes the return type of the function in the function prototype. */ -#if defined(_WIN32) && !defined(__SCITECH_SNAP__) +#if defined(KHRONOS_STATIC) + /* If the preprocessor constant KHRONOS_STATIC is defined, make the + * header compatible with static linking. */ +# define KHRONOS_APICALL +#elif defined(_WIN32) # define KHRONOS_APICALL __declspec(dllimport) #elif defined (__SYMBIAN32__) # define KHRONOS_APICALL IMPORT_C +#elif defined(__ANDROID__) +# define KHRONOS_APICALL __attribute__((visibility("default"))) #else # define KHRONOS_APICALL #endif @@ -145,6 +153,20 @@ typedef int64_t khronos_int64_t; typedef uint64_t khronos_uint64_t; #define KHRONOS_SUPPORT_INT64 1 #define KHRONOS_SUPPORT_FLOAT 1 +/* + * To support platform where unsigned long cannot be used interchangeably with + * inptr_t (e.g. CHERI-extended ISAs), we can use the stdint.h intptr_t. + * Ideally, we could just use (u)intptr_t everywhere, but this could result in + * ABI breakage if khronos_uintptr_t is changed from unsigned long to + * unsigned long long or similar (this results in different C++ name mangling). + * To avoid changes for existing platforms, we restrict usage of intptr_t to + * platforms where the size of a pointer is larger than the size of long. + */ +#if defined(__SIZEOF_LONG__) && defined(__SIZEOF_POINTER__) +#if __SIZEOF_POINTER__ > __SIZEOF_LONG__ +#define KHRONOS_USE_INTPTR_T +#endif +#endif #elif defined(__VMS ) || defined(__sgi) @@ -223,18 +245,25 @@ typedef signed short int khronos_int16_t; typedef unsigned short int khronos_uint16_t; /* - * Types that differ between LLP64 and LP64 architectures - in LLP64, + * Types that differ between LLP64 and LP64 architectures - in LLP64, * pointers are 64 bits, but 'long' is still 32 bits. Win64 appears * to be the only LLP64 architecture in current use. */ -#ifdef _WIN64 +#ifdef KHRONOS_USE_INTPTR_T +typedef intptr_t khronos_intptr_t; +typedef uintptr_t khronos_uintptr_t; +#elif defined(_WIN64) typedef signed long long int khronos_intptr_t; typedef unsigned long long int khronos_uintptr_t; -typedef signed long long int khronos_ssize_t; -typedef unsigned long long int khronos_usize_t; #else typedef signed long int khronos_intptr_t; typedef unsigned long int khronos_uintptr_t; +#endif + +#if defined(_WIN64) +typedef signed long long int khronos_ssize_t; +typedef unsigned long long int khronos_usize_t; +#else typedef signed long int khronos_ssize_t; typedef unsigned long int khronos_usize_t; #endif diff --git a/SDL2-2.0.12/include/SDL_pixels.h b/SDL2-2.30.5/include/SDL_pixels.h similarity index 60% rename from SDL2-2.0.12/include/SDL_pixels.h rename to SDL2-2.30.5/include/SDL_pixels.h index 1b119e4..44757cd 100644 --- a/SDL2-2.0.12/include/SDL_pixels.h +++ b/SDL2-2.30.5/include/SDL_pixels.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -61,7 +61,10 @@ typedef enum SDL_PIXELTYPE_ARRAYU16, SDL_PIXELTYPE_ARRAYU32, SDL_PIXELTYPE_ARRAYF16, - SDL_PIXELTYPE_ARRAYF32 + SDL_PIXELTYPE_ARRAYF32, + + /* This must be at the end of the list to avoid breaking the existing ABI */ + SDL_PIXELTYPE_INDEX2 } SDL_PixelType; /** Bitmap pixel order, high bit -> low bit. */ @@ -134,6 +137,7 @@ typedef enum #define SDL_ISPIXELFORMAT_INDEXED(format) \ (!SDL_ISPIXELFORMAT_FOURCC(format) && \ ((SDL_PIXELTYPE(format) == SDL_PIXELTYPE_INDEX1) || \ + (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_INDEX2) || \ (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_INDEX4) || \ (SDL_PIXELTYPE(format) == SDL_PIXELTYPE_INDEX8))) @@ -177,6 +181,12 @@ typedef enum SDL_PIXELFORMAT_INDEX1MSB = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX1, SDL_BITMAPORDER_1234, 0, 1, 0), + SDL_PIXELFORMAT_INDEX2LSB = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX2, SDL_BITMAPORDER_4321, 0, + 2, 0), + SDL_PIXELFORMAT_INDEX2MSB = + SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX2, SDL_BITMAPORDER_1234, 0, + 2, 0), SDL_PIXELFORMAT_INDEX4LSB = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX4, SDL_BITMAPORDER_4321, 0, 4, 0), @@ -188,18 +198,22 @@ typedef enum SDL_PIXELFORMAT_RGB332 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED8, SDL_PACKEDORDER_XRGB, SDL_PACKEDLAYOUT_332, 8, 1), - SDL_PIXELFORMAT_RGB444 = + SDL_PIXELFORMAT_XRGB4444 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XRGB, SDL_PACKEDLAYOUT_4444, 12, 2), - SDL_PIXELFORMAT_BGR444 = + SDL_PIXELFORMAT_RGB444 = SDL_PIXELFORMAT_XRGB4444, + SDL_PIXELFORMAT_XBGR4444 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XBGR, SDL_PACKEDLAYOUT_4444, 12, 2), - SDL_PIXELFORMAT_RGB555 = + SDL_PIXELFORMAT_BGR444 = SDL_PIXELFORMAT_XBGR4444, + SDL_PIXELFORMAT_XRGB1555 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XRGB, SDL_PACKEDLAYOUT_1555, 15, 2), - SDL_PIXELFORMAT_BGR555 = + SDL_PIXELFORMAT_RGB555 = SDL_PIXELFORMAT_XRGB1555, + SDL_PIXELFORMAT_XBGR1555 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XBGR, SDL_PACKEDLAYOUT_1555, 15, 2), + SDL_PIXELFORMAT_BGR555 = SDL_PIXELFORMAT_XBGR1555, SDL_PIXELFORMAT_ARGB4444 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ARGB, SDL_PACKEDLAYOUT_4444, 16, 2), @@ -236,15 +250,17 @@ typedef enum SDL_PIXELFORMAT_BGR24 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_ARRAYU8, SDL_ARRAYORDER_BGR, 0, 24, 3), - SDL_PIXELFORMAT_RGB888 = + SDL_PIXELFORMAT_XRGB8888 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_XRGB, SDL_PACKEDLAYOUT_8888, 24, 4), + SDL_PIXELFORMAT_RGB888 = SDL_PIXELFORMAT_XRGB8888, SDL_PIXELFORMAT_RGBX8888 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_RGBX, SDL_PACKEDLAYOUT_8888, 24, 4), - SDL_PIXELFORMAT_BGR888 = + SDL_PIXELFORMAT_XBGR8888 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_XBGR, SDL_PACKEDLAYOUT_8888, 24, 4), + SDL_PIXELFORMAT_BGR888 = SDL_PIXELFORMAT_XBGR8888, SDL_PIXELFORMAT_BGRX8888 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_BGRX, SDL_PACKEDLAYOUT_8888, 24, 4), @@ -270,11 +286,19 @@ typedef enum SDL_PIXELFORMAT_ARGB32 = SDL_PIXELFORMAT_ARGB8888, SDL_PIXELFORMAT_BGRA32 = SDL_PIXELFORMAT_BGRA8888, SDL_PIXELFORMAT_ABGR32 = SDL_PIXELFORMAT_ABGR8888, + SDL_PIXELFORMAT_RGBX32 = SDL_PIXELFORMAT_RGBX8888, + SDL_PIXELFORMAT_XRGB32 = SDL_PIXELFORMAT_XRGB8888, + SDL_PIXELFORMAT_BGRX32 = SDL_PIXELFORMAT_BGRX8888, + SDL_PIXELFORMAT_XBGR32 = SDL_PIXELFORMAT_XBGR8888, #else SDL_PIXELFORMAT_RGBA32 = SDL_PIXELFORMAT_ABGR8888, SDL_PIXELFORMAT_ARGB32 = SDL_PIXELFORMAT_BGRA8888, SDL_PIXELFORMAT_BGRA32 = SDL_PIXELFORMAT_ARGB8888, SDL_PIXELFORMAT_ABGR32 = SDL_PIXELFORMAT_RGBA8888, + SDL_PIXELFORMAT_RGBX32 = SDL_PIXELFORMAT_XBGR8888, + SDL_PIXELFORMAT_XRGB32 = SDL_PIXELFORMAT_BGRX8888, + SDL_PIXELFORMAT_BGRX32 = SDL_PIXELFORMAT_XRGB8888, + SDL_PIXELFORMAT_XBGR32 = SDL_PIXELFORMAT_RGBX8888, #endif SDL_PIXELFORMAT_YV12 = /**< Planar mode: Y + V + U (3 planes) */ @@ -295,6 +319,11 @@ typedef enum SDL_DEFINE_PIXELFOURCC('O', 'E', 'S', ' ') } SDL_PixelFormatEnum; +/** + * The bits of this structure can be directly reinterpreted as an integer-packed + * color which uses the SDL_PIXELFORMAT_RGBA32 format (SDL_PIXELFORMAT_ABGR8888 + * on little-endian systems and SDL_PIXELFORMAT_RGBA8888 on big-endian systems). + */ typedef struct SDL_Color { Uint8 r; @@ -339,16 +368,31 @@ typedef struct SDL_PixelFormat } SDL_PixelFormat; /** - * \brief Get the human readable name of a pixel format + * Get the human readable name of a pixel format. + * + * \param format the pixel format to query + * \returns the human readable name of the specified pixel format or + * `SDL_PIXELFORMAT_UNKNOWN` if the format isn't recognized. + * + * \since This function is available since SDL 2.0.0. */ extern DECLSPEC const char* SDLCALL SDL_GetPixelFormatName(Uint32 format); /** - * \brief Convert one of the enumerated pixel formats to a bpp and RGBA masks. + * Convert one of the enumerated pixel formats to a bpp value and RGBA masks. * - * \return SDL_TRUE, or SDL_FALSE if the conversion wasn't possible. + * \param format one of the SDL_PixelFormatEnum values + * \param bpp a bits per pixel value; usually 15, 16, or 32 + * \param Rmask a pointer filled in with the red mask for the format + * \param Gmask a pointer filled in with the green mask for the format + * \param Bmask a pointer filled in with the blue mask for the format + * \param Amask a pointer filled in with the alpha mask for the format + * \returns SDL_TRUE on success or SDL_FALSE if the conversion wasn't + * possible; call SDL_GetError() for more information. * - * \sa SDL_MasksToPixelFormatEnum() + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_MasksToPixelFormatEnum */ extern DECLSPEC SDL_bool SDLCALL SDL_PixelFormatEnumToMasks(Uint32 format, int *bpp, @@ -358,12 +402,21 @@ extern DECLSPEC SDL_bool SDLCALL SDL_PixelFormatEnumToMasks(Uint32 format, Uint32 * Amask); /** - * \brief Convert a bpp and RGBA masks to an enumerated pixel format. + * Convert a bpp value and RGBA masks to an enumerated pixel format. * - * \return The pixel format, or ::SDL_PIXELFORMAT_UNKNOWN if the conversion - * wasn't possible. + * This will return `SDL_PIXELFORMAT_UNKNOWN` if the conversion wasn't + * possible. * - * \sa SDL_PixelFormatEnumToMasks() + * \param bpp a bits per pixel value; usually 15, 16, or 32 + * \param Rmask the red mask for the format + * \param Gmask the green mask for the format + * \param Bmask the blue mask for the format + * \param Amask the alpha mask for the format + * \returns one of the SDL_PixelFormatEnum values + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_PixelFormatEnumToMasks */ extern DECLSPEC Uint32 SDLCALL SDL_MasksToPixelFormatEnum(int bpp, Uint32 Rmask, @@ -372,84 +425,213 @@ extern DECLSPEC Uint32 SDLCALL SDL_MasksToPixelFormatEnum(int bpp, Uint32 Amask); /** - * \brief Create an SDL_PixelFormat structure from a pixel format enum. + * Create an SDL_PixelFormat structure corresponding to a pixel format. + * + * Returned structure may come from a shared global cache (i.e. not newly + * allocated), and hence should not be modified, especially the palette. Weird + * errors such as `Blit combination not supported` may occur. + * + * \param pixel_format one of the SDL_PixelFormatEnum values + * \returns the new SDL_PixelFormat structure or NULL on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_FreeFormat */ extern DECLSPEC SDL_PixelFormat * SDLCALL SDL_AllocFormat(Uint32 pixel_format); /** - * \brief Free an SDL_PixelFormat structure. + * Free an SDL_PixelFormat structure allocated by SDL_AllocFormat(). + * + * \param format the SDL_PixelFormat structure to free + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AllocFormat */ extern DECLSPEC void SDLCALL SDL_FreeFormat(SDL_PixelFormat *format); /** - * \brief Create a palette structure with the specified number of color - * entries. + * Create a palette structure with the specified number of color entries. * - * \return A new palette, or NULL if there wasn't enough memory. + * The palette entries are initialized to white. * - * \note The palette entries are initialized to white. + * \param ncolors represents the number of color entries in the color palette + * \returns a new SDL_Palette structure on success or NULL on failure (e.g. if + * there wasn't enough memory); call SDL_GetError() for more + * information. * - * \sa SDL_FreePalette() + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_FreePalette */ extern DECLSPEC SDL_Palette *SDLCALL SDL_AllocPalette(int ncolors); /** - * \brief Set the palette for a pixel format structure. + * Set the palette for a pixel format structure. + * + * \param format the SDL_PixelFormat structure that will use the palette + * \param palette the SDL_Palette structure that will be used + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AllocPalette + * \sa SDL_FreePalette */ extern DECLSPEC int SDLCALL SDL_SetPixelFormatPalette(SDL_PixelFormat * format, SDL_Palette *palette); /** - * \brief Set a range of colors in a palette. + * Set a range of colors in a palette. * - * \param palette The palette to modify. - * \param colors An array of colors to copy into the palette. - * \param firstcolor The index of the first palette entry to modify. - * \param ncolors The number of entries to modify. + * \param palette the SDL_Palette structure to modify + * \param colors an array of SDL_Color structures to copy into the palette + * \param firstcolor the index of the first palette entry to modify + * \param ncolors the number of entries to modify + * \returns 0 on success or a negative error code if not all of the colors + * could be set; call SDL_GetError() for more information. * - * \return 0 on success, or -1 if not all of the colors could be set. + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AllocPalette + * \sa SDL_CreateRGBSurface */ extern DECLSPEC int SDLCALL SDL_SetPaletteColors(SDL_Palette * palette, const SDL_Color * colors, int firstcolor, int ncolors); /** - * \brief Free a palette created with SDL_AllocPalette(). + * Free a palette created with SDL_AllocPalette(). * - * \sa SDL_AllocPalette() + * \param palette the SDL_Palette structure to be freed + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AllocPalette */ extern DECLSPEC void SDLCALL SDL_FreePalette(SDL_Palette * palette); /** - * \brief Maps an RGB triple to an opaque pixel value for a given pixel format. + * Map an RGB triple to an opaque pixel value for a given pixel format. * - * \sa SDL_MapRGBA + * This function maps the RGB color value to the specified pixel format and + * returns the pixel value best approximating the given RGB color value for + * the given pixel format. + * + * If the format has a palette (8-bit) the index of the closest matching color + * in the palette will be returned. + * + * If the specified pixel format has an alpha component it will be returned as + * all 1 bits (fully opaque). + * + * If the pixel format bpp (color depth) is less than 32-bpp then the unused + * upper bits of the return value can safely be ignored (e.g., with a 16-bpp + * format the return value can be assigned to a Uint16, and similarly a Uint8 + * for an 8-bpp format). + * + * \param format an SDL_PixelFormat structure describing the pixel format + * \param r the red component of the pixel in the range 0-255 + * \param g the green component of the pixel in the range 0-255 + * \param b the blue component of the pixel in the range 0-255 + * \returns a pixel value + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetRGB + * \sa SDL_GetRGBA + * \sa SDL_MapRGBA */ extern DECLSPEC Uint32 SDLCALL SDL_MapRGB(const SDL_PixelFormat * format, Uint8 r, Uint8 g, Uint8 b); /** - * \brief Maps an RGBA quadruple to a pixel value for a given pixel format. + * Map an RGBA quadruple to a pixel value for a given pixel format. * - * \sa SDL_MapRGB + * This function maps the RGBA color value to the specified pixel format and + * returns the pixel value best approximating the given RGBA color value for + * the given pixel format. + * + * If the specified pixel format has no alpha component the alpha value will + * be ignored (as it will be in formats with a palette). + * + * If the format has a palette (8-bit) the index of the closest matching color + * in the palette will be returned. + * + * If the pixel format bpp (color depth) is less than 32-bpp then the unused + * upper bits of the return value can safely be ignored (e.g., with a 16-bpp + * format the return value can be assigned to a Uint16, and similarly a Uint8 + * for an 8-bpp format). + * + * \param format an SDL_PixelFormat structure describing the format of the + * pixel + * \param r the red component of the pixel in the range 0-255 + * \param g the green component of the pixel in the range 0-255 + * \param b the blue component of the pixel in the range 0-255 + * \param a the alpha component of the pixel in the range 0-255 + * \returns a pixel value + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetRGB + * \sa SDL_GetRGBA + * \sa SDL_MapRGB */ extern DECLSPEC Uint32 SDLCALL SDL_MapRGBA(const SDL_PixelFormat * format, Uint8 r, Uint8 g, Uint8 b, Uint8 a); /** - * \brief Get the RGB components from a pixel of the specified format. + * Get RGB values from a pixel in the specified format. * - * \sa SDL_GetRGBA + * This function uses the entire 8-bit [0..255] range when converting color + * components from pixel formats with less than 8-bits per RGB component + * (e.g., a completely white pixel in 16-bit RGB565 format would return [0xff, + * 0xff, 0xff] not [0xf8, 0xfc, 0xf8]). + * + * \param pixel a pixel value + * \param format an SDL_PixelFormat structure describing the format of the + * pixel + * \param r a pointer filled in with the red component + * \param g a pointer filled in with the green component + * \param b a pointer filled in with the blue component + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetRGBA + * \sa SDL_MapRGB + * \sa SDL_MapRGBA */ extern DECLSPEC void SDLCALL SDL_GetRGB(Uint32 pixel, const SDL_PixelFormat * format, Uint8 * r, Uint8 * g, Uint8 * b); /** - * \brief Get the RGBA components from a pixel of the specified format. + * Get RGBA values from a pixel in the specified format. * - * \sa SDL_GetRGB + * This function uses the entire 8-bit [0..255] range when converting color + * components from pixel formats with less than 8-bits per RGB component + * (e.g., a completely white pixel in 16-bit RGB565 format would return [0xff, + * 0xff, 0xff] not [0xf8, 0xfc, 0xf8]). + * + * If the surface has no alpha component, the alpha will be returned as 0xff + * (100% opaque). + * + * \param pixel a pixel value + * \param format an SDL_PixelFormat structure describing the format of the + * pixel + * \param r a pointer filled in with the red component + * \param g a pointer filled in with the green component + * \param b a pointer filled in with the blue component + * \param a a pointer filled in with the alpha component + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetRGB + * \sa SDL_MapRGB + * \sa SDL_MapRGBA */ extern DECLSPEC void SDLCALL SDL_GetRGBA(Uint32 pixel, const SDL_PixelFormat * format, @@ -457,7 +639,14 @@ extern DECLSPEC void SDLCALL SDL_GetRGBA(Uint32 pixel, Uint8 * a); /** - * \brief Calculate a 256 entry gamma ramp for a gamma value. + * Calculate a 256 entry gamma ramp for a gamma value. + * + * \param gamma a gamma value where 0.0 is black and 1.0 is identity + * \param ramp an array of 256 values filled in with the gamma ramp + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetWindowGammaRamp */ extern DECLSPEC void SDLCALL SDL_CalculateGammaRamp(float gamma, Uint16 * ramp); diff --git a/SDL2-2.0.12/include/SDL_platform.h b/SDL2-2.30.5/include/SDL_platform.h similarity index 67% rename from SDL2-2.0.12/include/SDL_platform.h rename to SDL2-2.30.5/include/SDL_platform.h index 7166557..2b11bf2 100644 --- a/SDL2-2.0.12/include/SDL_platform.h +++ b/SDL2-2.30.5/include/SDL_platform.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -65,11 +65,42 @@ #undef __LINUX__ /* do we need to do this? */ #define __ANDROID__ 1 #endif +#if defined(__NGAGE__) +#undef __NGAGE__ +#define __NGAGE__ 1 +#endif #if defined(__APPLE__) /* lets us know what version of Mac OS X we're compiling on */ -#include "AvailabilityMacros.h" -#include "TargetConditionals.h" +#include +#ifndef __has_extension /* Older compilers don't support this */ +#define __has_extension(x) 0 +#include +#undef __has_extension +#else +#include +#endif + +/* Fix building with older SDKs that don't define these + See this for more information: + https://stackoverflow.com/questions/12132933/preprocessor-macro-for-os-x-targets +*/ +#ifndef TARGET_OS_MACCATALYST +#define TARGET_OS_MACCATALYST 0 +#endif +#ifndef TARGET_OS_IOS +#define TARGET_OS_IOS 0 +#endif +#ifndef TARGET_OS_IPHONE +#define TARGET_OS_IPHONE 0 +#endif +#ifndef TARGET_OS_TV +#define TARGET_OS_TV 0 +#endif +#ifndef TARGET_OS_SIMULATOR +#define TARGET_OS_SIMULATOR 0 +#endif + #if TARGET_OS_TV #undef __TVOS__ #define __TVOS__ 1 @@ -83,9 +114,9 @@ /* if not compiling for iOS */ #undef __MACOSX__ #define __MACOSX__ 1 -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 -# error SDL for Mac OS X only supports deploying on 10.6 and above. -#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < 1060 */ +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070 +# error SDL for Mac OS X only supports deploying on 10.7 and above. +#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < 1070 */ #endif /* TARGET_OS_IPHONE */ #endif /* defined(__APPLE__) */ @@ -119,7 +150,7 @@ #endif #if defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) -/* Try to find out if we're compiling for WinRT or non-WinRT */ +/* Try to find out if we're compiling for WinRT, GDK or non-WinRT/GDK */ #if defined(_MSC_VER) && defined(__has_include) #if __has_include() #define HAVE_WINAPIFAMILY_H 1 @@ -141,9 +172,24 @@ #define WINAPI_FAMILY_WINRT 0 #endif /* HAVE_WINAPIFAMILY_H */ +#if (HAVE_WINAPIFAMILY_H) && defined(WINAPI_FAMILY_PHONE_APP) +#define SDL_WINAPI_FAMILY_PHONE (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) +#else +#define SDL_WINAPI_FAMILY_PHONE 0 +#endif + #if WINAPI_FAMILY_WINRT #undef __WINRT__ #define __WINRT__ 1 +#elif defined(_GAMING_DESKTOP) /* GDK project configuration always defines _GAMING_XXX */ +#undef __WINGDK__ +#define __WINGDK__ 1 +#elif defined(_GAMING_XBOX_XBOXONE) +#undef __XBOXONE__ +#define __XBOXONE__ 1 +#elif defined(_GAMING_XBOX_SCARLETT) +#undef __XBOXSERIES__ +#define __XBOXSERIES__ 1 #else #undef __WINDOWS__ #define __WINDOWS__ 1 @@ -154,10 +200,20 @@ #undef __WIN32__ #define __WIN32__ 1 #endif -#if defined(__PSP__) +/* This is to support generic "any GDK" separate from a platform-specific GDK */ +#if defined(__WINGDK__) || defined(__XBOXONE__) || defined(__XBOXSERIES__) +#undef __GDK__ +#define __GDK__ 1 +#endif +#if defined(__PSP__) || defined(__psp__) +#ifdef __PSP__ #undef __PSP__ +#endif #define __PSP__ 1 #endif +#if defined(PS2) +#define __PS2__ 1 +#endif /* The NACL compiler defines __native_client__ and __pnacl__ * Ref: http://www.chromium.org/nativeclient/pnacl/stability-of-the-pnacl-bitcode-abi @@ -175,6 +231,14 @@ #define __SDL_NOGETPROCADDR__ #endif +#if defined(__vita__) +#define __VITA__ 1 +#endif + +#if defined(__3DS__) +#undef __3DS__ +#define __3DS__ 1 +#endif #include "begin_code.h" /* Set up for C function definitions, even when using C++ */ @@ -183,7 +247,20 @@ extern "C" { #endif /** - * \brief Gets the name of the platform. + * Get the name of the platform. + * + * Here are the names returned for some (but not all) supported platforms: + * + * - "Windows" + * - "Mac OS X" + * - "Linux" + * - "iOS" + * - "Android" + * + * \returns the name of the platform. If the correct platform name is not + * available, returns a string beginning with the text "Unknown". + * + * \since This function is available since SDL 2.0.0. */ extern DECLSPEC const char * SDLCALL SDL_GetPlatform (void); diff --git a/SDL2-2.0.12/include/SDL_power.h b/SDL2-2.30.5/include/SDL_power.h similarity index 56% rename from SDL2-2.0.12/include/SDL_power.h rename to SDL2-2.30.5/include/SDL_power.h index 39884cc..0520065 100644 --- a/SDL2-2.0.12/include/SDL_power.h +++ b/SDL2-2.30.5/include/SDL_power.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -37,7 +37,7 @@ extern "C" { #endif /** - * \brief The basic state for the system's power supply. + * The basic state for the system's power supply. */ typedef enum { @@ -48,21 +48,33 @@ typedef enum SDL_POWERSTATE_CHARGED /**< Plugged in, battery charged */ } SDL_PowerState; - /** - * \brief Get the current power supply details. + * Get the current power supply details. * - * \param secs Seconds of battery life left. You can pass a NULL here if - * you don't care. Will return -1 if we can't determine a - * value, or we're not running on a battery. + * You should never take a battery status as absolute truth. Batteries + * (especially failing batteries) are delicate hardware, and the values + * reported here are best estimates based on what that hardware reports. It's + * not uncommon for older batteries to lose stored power much faster than it + * reports, or completely drain when reporting it has 20 percent left, etc. * - * \param pct Percentage of battery life left, between 0 and 100. You can - * pass a NULL here if you don't care. Will return -1 if we - * can't determine a value, or we're not running on a battery. + * Battery status can change at any time; if you are concerned with power + * state, you should call this function frequently, and perhaps ignore changes + * until they seem to be stable for a few seconds. * - * \return The state of the battery (if any). + * It's possible a platform can only report battery percentage or time left + * but not both. + * + * \param seconds seconds of battery life left, you can pass a NULL here if + * you don't care, will return -1 if we can't determine a + * value, or we're not running on a battery + * \param percent percentage of battery life left, between 0 and 100, you can + * pass a NULL here if you don't care, will return -1 if we + * can't determine a value, or we're not running on a battery + * \returns an SDL_PowerState enum representing the current battery state. + * + * \since This function is available since SDL 2.0.0. */ -extern DECLSPEC SDL_PowerState SDLCALL SDL_GetPowerInfo(int *secs, int *pct); +extern DECLSPEC SDL_PowerState SDLCALL SDL_GetPowerInfo(int *seconds, int *percent); /* Ends C function definitions when using C++ */ #ifdef __cplusplus diff --git a/SDL2-2.0.12/include/SDL_quit.h b/SDL2-2.30.5/include/SDL_quit.h similarity index 97% rename from SDL2-2.0.12/include/SDL_quit.h rename to SDL2-2.30.5/include/SDL_quit.h index b2bd5da..3f69dc9 100644 --- a/SDL2-2.0.12/include/SDL_quit.h +++ b/SDL2-2.30.5/include/SDL_quit.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.30.5/include/SDL_rect.h b/SDL2-2.30.5/include/SDL_rect.h new file mode 100644 index 0000000..5ce1f0b --- /dev/null +++ b/SDL2-2.30.5/include/SDL_rect.h @@ -0,0 +1,376 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_rect.h + * + * Header file for SDL_rect definition and management functions. + */ + +#ifndef SDL_rect_h_ +#define SDL_rect_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" +#include "SDL_pixels.h" +#include "SDL_rwops.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * The structure that defines a point (integer) + * + * \sa SDL_EnclosePoints + * \sa SDL_PointInRect + */ +typedef struct SDL_Point +{ + int x; + int y; +} SDL_Point; + +/** + * The structure that defines a point (floating point) + * + * \sa SDL_EncloseFPoints + * \sa SDL_PointInFRect + */ +typedef struct SDL_FPoint +{ + float x; + float y; +} SDL_FPoint; + + +/** + * A rectangle, with the origin at the upper left (integer). + * + * \sa SDL_RectEmpty + * \sa SDL_RectEquals + * \sa SDL_HasIntersection + * \sa SDL_IntersectRect + * \sa SDL_IntersectRectAndLine + * \sa SDL_UnionRect + * \sa SDL_EnclosePoints + */ +typedef struct SDL_Rect +{ + int x, y; + int w, h; +} SDL_Rect; + + +/** + * A rectangle, with the origin at the upper left (floating point). + * + * \sa SDL_FRectEmpty + * \sa SDL_FRectEquals + * \sa SDL_FRectEqualsEpsilon + * \sa SDL_HasIntersectionF + * \sa SDL_IntersectFRect + * \sa SDL_IntersectFRectAndLine + * \sa SDL_UnionFRect + * \sa SDL_EncloseFPoints + * \sa SDL_PointInFRect + */ +typedef struct SDL_FRect +{ + float x; + float y; + float w; + float h; +} SDL_FRect; + + +/** + * Returns true if point resides inside a rectangle. + */ +SDL_FORCE_INLINE SDL_bool SDL_PointInRect(const SDL_Point *p, const SDL_Rect *r) +{ + return ( (p->x >= r->x) && (p->x < (r->x + r->w)) && + (p->y >= r->y) && (p->y < (r->y + r->h)) ) ? SDL_TRUE : SDL_FALSE; +} + +/** + * Returns true if the rectangle has no area. + */ +SDL_FORCE_INLINE SDL_bool SDL_RectEmpty(const SDL_Rect *r) +{ + return ((!r) || (r->w <= 0) || (r->h <= 0)) ? SDL_TRUE : SDL_FALSE; +} + +/** + * Returns true if the two rectangles are equal. + */ +SDL_FORCE_INLINE SDL_bool SDL_RectEquals(const SDL_Rect *a, const SDL_Rect *b) +{ + return (a && b && (a->x == b->x) && (a->y == b->y) && + (a->w == b->w) && (a->h == b->h)) ? SDL_TRUE : SDL_FALSE; +} + +/** + * Determine whether two rectangles intersect. + * + * If either pointer is NULL the function will return SDL_FALSE. + * + * \param A an SDL_Rect structure representing the first rectangle + * \param B an SDL_Rect structure representing the second rectangle + * \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_IntersectRect + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasIntersection(const SDL_Rect * A, + const SDL_Rect * B); + +/** + * Calculate the intersection of two rectangles. + * + * If `result` is NULL then this function will return SDL_FALSE. + * + * \param A an SDL_Rect structure representing the first rectangle + * \param B an SDL_Rect structure representing the second rectangle + * \param result an SDL_Rect structure filled in with the intersection of + * rectangles `A` and `B` + * \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HasIntersection + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IntersectRect(const SDL_Rect * A, + const SDL_Rect * B, + SDL_Rect * result); + +/** + * Calculate the union of two rectangles. + * + * \param A an SDL_Rect structure representing the first rectangle + * \param B an SDL_Rect structure representing the second rectangle + * \param result an SDL_Rect structure filled in with the union of rectangles + * `A` and `B` + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC void SDLCALL SDL_UnionRect(const SDL_Rect * A, + const SDL_Rect * B, + SDL_Rect * result); + +/** + * Calculate a minimal rectangle enclosing a set of points. + * + * If `clip` is not NULL then only points inside of the clipping rectangle are + * considered. + * + * \param points an array of SDL_Point structures representing points to be + * enclosed + * \param count the number of structures in the `points` array + * \param clip an SDL_Rect used for clipping or NULL to enclose all points + * \param result an SDL_Rect structure filled in with the minimal enclosing + * rectangle + * \returns SDL_TRUE if any points were enclosed or SDL_FALSE if all the + * points were outside of the clipping rectangle. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_EnclosePoints(const SDL_Point * points, + int count, + const SDL_Rect * clip, + SDL_Rect * result); + +/** + * Calculate the intersection of a rectangle and line segment. + * + * This function is used to clip a line segment to a rectangle. A line segment + * contained entirely within the rectangle or that does not intersect will + * remain unchanged. A line segment that crosses the rectangle at either or + * both ends will be clipped to the boundary of the rectangle and the new + * coordinates saved in `X1`, `Y1`, `X2`, and/or `Y2` as necessary. + * + * \param rect an SDL_Rect structure representing the rectangle to intersect + * \param X1 a pointer to the starting X-coordinate of the line + * \param Y1 a pointer to the starting Y-coordinate of the line + * \param X2 a pointer to the ending X-coordinate of the line + * \param Y2 a pointer to the ending Y-coordinate of the line + * \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IntersectRectAndLine(const SDL_Rect * + rect, int *X1, + int *Y1, int *X2, + int *Y2); + + +/* SDL_FRect versions... */ + +/** + * Returns true if point resides inside a rectangle. + */ +SDL_FORCE_INLINE SDL_bool SDL_PointInFRect(const SDL_FPoint *p, const SDL_FRect *r) +{ + return ( (p->x >= r->x) && (p->x < (r->x + r->w)) && + (p->y >= r->y) && (p->y < (r->y + r->h)) ) ? SDL_TRUE : SDL_FALSE; +} + +/** + * Returns true if the rectangle has no area. + */ +SDL_FORCE_INLINE SDL_bool SDL_FRectEmpty(const SDL_FRect *r) +{ + return ((!r) || (r->w <= 0.0f) || (r->h <= 0.0f)) ? SDL_TRUE : SDL_FALSE; +} + +/** + * Returns true if the two rectangles are equal, within some given epsilon. + * + * \since This function is available since SDL 2.0.22. + */ +SDL_FORCE_INLINE SDL_bool SDL_FRectEqualsEpsilon(const SDL_FRect *a, const SDL_FRect *b, const float epsilon) +{ + return (a && b && ((a == b) || + ((SDL_fabsf(a->x - b->x) <= epsilon) && + (SDL_fabsf(a->y - b->y) <= epsilon) && + (SDL_fabsf(a->w - b->w) <= epsilon) && + (SDL_fabsf(a->h - b->h) <= epsilon)))) + ? SDL_TRUE : SDL_FALSE; +} + +/** + * Returns true if the two rectangles are equal, using a default epsilon. + * + * \since This function is available since SDL 2.0.22. + */ +SDL_FORCE_INLINE SDL_bool SDL_FRectEquals(const SDL_FRect *a, const SDL_FRect *b) +{ + return SDL_FRectEqualsEpsilon(a, b, SDL_FLT_EPSILON); +} + +/** + * Determine whether two rectangles intersect with float precision. + * + * If either pointer is NULL the function will return SDL_FALSE. + * + * \param A an SDL_FRect structure representing the first rectangle + * \param B an SDL_FRect structure representing the second rectangle + * \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.22. + * + * \sa SDL_IntersectRect + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasIntersectionF(const SDL_FRect * A, + const SDL_FRect * B); + +/** + * Calculate the intersection of two rectangles with float precision. + * + * If `result` is NULL then this function will return SDL_FALSE. + * + * \param A an SDL_FRect structure representing the first rectangle + * \param B an SDL_FRect structure representing the second rectangle + * \param result an SDL_FRect structure filled in with the intersection of + * rectangles `A` and `B` + * \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.22. + * + * \sa SDL_HasIntersectionF + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IntersectFRect(const SDL_FRect * A, + const SDL_FRect * B, + SDL_FRect * result); + +/** + * Calculate the union of two rectangles with float precision. + * + * \param A an SDL_FRect structure representing the first rectangle + * \param B an SDL_FRect structure representing the second rectangle + * \param result an SDL_FRect structure filled in with the union of rectangles + * `A` and `B` + * + * \since This function is available since SDL 2.0.22. + */ +extern DECLSPEC void SDLCALL SDL_UnionFRect(const SDL_FRect * A, + const SDL_FRect * B, + SDL_FRect * result); + +/** + * Calculate a minimal rectangle enclosing a set of points with float + * precision. + * + * If `clip` is not NULL then only points inside of the clipping rectangle are + * considered. + * + * \param points an array of SDL_FPoint structures representing points to be + * enclosed + * \param count the number of structures in the `points` array + * \param clip an SDL_FRect used for clipping or NULL to enclose all points + * \param result an SDL_FRect structure filled in with the minimal enclosing + * rectangle + * \returns SDL_TRUE if any points were enclosed or SDL_FALSE if all the + * points were outside of the clipping rectangle. + * + * \since This function is available since SDL 2.0.22. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_EncloseFPoints(const SDL_FPoint * points, + int count, + const SDL_FRect * clip, + SDL_FRect * result); + +/** + * Calculate the intersection of a rectangle and line segment with float + * precision. + * + * This function is used to clip a line segment to a rectangle. A line segment + * contained entirely within the rectangle or that does not intersect will + * remain unchanged. A line segment that crosses the rectangle at either or + * both ends will be clipped to the boundary of the rectangle and the new + * coordinates saved in `X1`, `Y1`, `X2`, and/or `Y2` as necessary. + * + * \param rect an SDL_FRect structure representing the rectangle to intersect + * \param X1 a pointer to the starting X-coordinate of the line + * \param Y1 a pointer to the starting Y-coordinate of the line + * \param X2 a pointer to the ending X-coordinate of the line + * \param Y2 a pointer to the ending Y-coordinate of the line + * \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.22. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IntersectFRectAndLine(const SDL_FRect * + rect, float *X1, + float *Y1, float *X2, + float *Y2); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_rect_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/include/SDL_render.h b/SDL2-2.30.5/include/SDL_render.h new file mode 100644 index 0000000..b7135bb --- /dev/null +++ b/SDL2-2.30.5/include/SDL_render.h @@ -0,0 +1,1924 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_render.h + * + * Header file for SDL 2D rendering functions. + * + * This API supports the following features: + * * single pixel points + * * single pixel lines + * * filled rectangles + * * texture images + * + * The primitives may be drawn in opaque, blended, or additive modes. + * + * The texture images may be drawn in opaque, blended, or additive modes. + * They can have an additional color tint or alpha modulation applied to + * them, and may also be stretched with linear interpolation. + * + * This API is designed to accelerate simple 2D operations. You may + * want more functionality such as polygons and particle effects and + * in that case you should use SDL's OpenGL/Direct3D support or one + * of the many good 3D engines. + * + * These functions must be called from the main thread. + * See this bug for details: https://github.com/libsdl-org/SDL/issues/986 + */ + +#ifndef SDL_render_h_ +#define SDL_render_h_ + +#include "SDL_stdinc.h" +#include "SDL_rect.h" +#include "SDL_video.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Flags used when creating a rendering context + */ +typedef enum +{ + SDL_RENDERER_SOFTWARE = 0x00000001, /**< The renderer is a software fallback */ + SDL_RENDERER_ACCELERATED = 0x00000002, /**< The renderer uses hardware + acceleration */ + SDL_RENDERER_PRESENTVSYNC = 0x00000004, /**< Present is synchronized + with the refresh rate */ + SDL_RENDERER_TARGETTEXTURE = 0x00000008 /**< The renderer supports + rendering to texture */ +} SDL_RendererFlags; + +/** + * Information on the capabilities of a render driver or context. + */ +typedef struct SDL_RendererInfo +{ + const char *name; /**< The name of the renderer */ + Uint32 flags; /**< Supported ::SDL_RendererFlags */ + Uint32 num_texture_formats; /**< The number of available texture formats */ + Uint32 texture_formats[16]; /**< The available texture formats */ + int max_texture_width; /**< The maximum texture width */ + int max_texture_height; /**< The maximum texture height */ +} SDL_RendererInfo; + +/** + * Vertex structure + */ +typedef struct SDL_Vertex +{ + SDL_FPoint position; /**< Vertex position, in SDL_Renderer coordinates */ + SDL_Color color; /**< Vertex color */ + SDL_FPoint tex_coord; /**< Normalized texture coordinates, if needed */ +} SDL_Vertex; + +/** + * The scaling mode for a texture. + */ +typedef enum +{ + SDL_ScaleModeNearest, /**< nearest pixel sampling */ + SDL_ScaleModeLinear, /**< linear filtering */ + SDL_ScaleModeBest /**< anisotropic filtering */ +} SDL_ScaleMode; + +/** + * The access pattern allowed for a texture. + */ +typedef enum +{ + SDL_TEXTUREACCESS_STATIC, /**< Changes rarely, not lockable */ + SDL_TEXTUREACCESS_STREAMING, /**< Changes frequently, lockable */ + SDL_TEXTUREACCESS_TARGET /**< Texture can be used as a render target */ +} SDL_TextureAccess; + +/** + * The texture channel modulation used in SDL_RenderCopy(). + */ +typedef enum +{ + SDL_TEXTUREMODULATE_NONE = 0x00000000, /**< No modulation */ + SDL_TEXTUREMODULATE_COLOR = 0x00000001, /**< srcC = srcC * color */ + SDL_TEXTUREMODULATE_ALPHA = 0x00000002 /**< srcA = srcA * alpha */ +} SDL_TextureModulate; + +/** + * Flip constants for SDL_RenderCopyEx + */ +typedef enum +{ + SDL_FLIP_NONE = 0x00000000, /**< Do not flip */ + SDL_FLIP_HORIZONTAL = 0x00000001, /**< flip horizontally */ + SDL_FLIP_VERTICAL = 0x00000002 /**< flip vertically */ +} SDL_RendererFlip; + +/** + * A structure representing rendering state + */ +struct SDL_Renderer; +typedef struct SDL_Renderer SDL_Renderer; + +/** + * An efficient driver-specific representation of pixel data + */ +struct SDL_Texture; +typedef struct SDL_Texture SDL_Texture; + +/* Function prototypes */ + +/** + * Get the number of 2D rendering drivers available for the current display. + * + * A render driver is a set of code that handles rendering and texture + * management on a particular display. Normally there is only one, but some + * drivers may have several available with different capabilities. + * + * There may be none if SDL was compiled without render support. + * + * \returns a number >= 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateRenderer + * \sa SDL_GetRenderDriverInfo + */ +extern DECLSPEC int SDLCALL SDL_GetNumRenderDrivers(void); + +/** + * Get info about a specific 2D rendering driver for the current display. + * + * \param index the index of the driver to query information about + * \param info an SDL_RendererInfo structure to be filled with information on + * the rendering driver + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateRenderer + * \sa SDL_GetNumRenderDrivers + */ +extern DECLSPEC int SDLCALL SDL_GetRenderDriverInfo(int index, + SDL_RendererInfo * info); + +/** + * Create a window and default renderer. + * + * \param width the width of the window + * \param height the height of the window + * \param window_flags the flags used to create the window (see + * SDL_CreateWindow()) + * \param window a pointer filled with the window, or NULL on error + * \param renderer a pointer filled with the renderer, or NULL on error + * \returns 0 on success, or -1 on error; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateRenderer + * \sa SDL_CreateWindow + */ +extern DECLSPEC int SDLCALL SDL_CreateWindowAndRenderer( + int width, int height, Uint32 window_flags, + SDL_Window **window, SDL_Renderer **renderer); + + +/** + * Create a 2D rendering context for a window. + * + * \param window the window where rendering is displayed + * \param index the index of the rendering driver to initialize, or -1 to + * initialize the first one supporting the requested flags + * \param flags 0, or one or more SDL_RendererFlags OR'd together + * \returns a valid rendering context or NULL if there was an error; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateSoftwareRenderer + * \sa SDL_DestroyRenderer + * \sa SDL_GetNumRenderDrivers + * \sa SDL_GetRendererInfo + */ +extern DECLSPEC SDL_Renderer * SDLCALL SDL_CreateRenderer(SDL_Window * window, + int index, Uint32 flags); + +/** + * Create a 2D software rendering context for a surface. + * + * Two other API which can be used to create SDL_Renderer: + * SDL_CreateRenderer() and SDL_CreateWindowAndRenderer(). These can _also_ + * create a software renderer, but they are intended to be used with an + * SDL_Window as the final destination and not an SDL_Surface. + * + * \param surface the SDL_Surface structure representing the surface where + * rendering is done + * \returns a valid rendering context or NULL if there was an error; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateRenderer + * \sa SDL_CreateWindowRenderer + * \sa SDL_DestroyRenderer + */ +extern DECLSPEC SDL_Renderer * SDLCALL SDL_CreateSoftwareRenderer(SDL_Surface * surface); + +/** + * Get the renderer associated with a window. + * + * \param window the window to query + * \returns the rendering context on success or NULL on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateRenderer + */ +extern DECLSPEC SDL_Renderer * SDLCALL SDL_GetRenderer(SDL_Window * window); + +/** + * Get the window associated with a renderer. + * + * \param renderer the renderer to query + * \returns the window on success or NULL on failure; call SDL_GetError() for + * more information. + * + * \since This function is available since SDL 2.0.22. + */ +extern DECLSPEC SDL_Window * SDLCALL SDL_RenderGetWindow(SDL_Renderer *renderer); + +/** + * Get information about a rendering context. + * + * \param renderer the rendering context + * \param info an SDL_RendererInfo structure filled with information about the + * current renderer + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateRenderer + */ +extern DECLSPEC int SDLCALL SDL_GetRendererInfo(SDL_Renderer * renderer, + SDL_RendererInfo * info); + +/** + * Get the output size in pixels of a rendering context. + * + * Due to high-dpi displays, you might end up with a rendering context that + * has more pixels than the window that contains it, so use this instead of + * SDL_GetWindowSize() to decide how much drawing area you have. + * + * \param renderer the rendering context + * \param w an int filled with the width + * \param h an int filled with the height + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetRenderer + */ +extern DECLSPEC int SDLCALL SDL_GetRendererOutputSize(SDL_Renderer * renderer, + int *w, int *h); + +/** + * Create a texture for a rendering context. + * + * You can set the texture scaling method by setting + * `SDL_HINT_RENDER_SCALE_QUALITY` before creating the texture. + * + * \param renderer the rendering context + * \param format one of the enumerated values in SDL_PixelFormatEnum + * \param access one of the enumerated values in SDL_TextureAccess + * \param w the width of the texture in pixels + * \param h the height of the texture in pixels + * \returns a pointer to the created texture or NULL if no rendering context + * was active, the format was unsupported, or the width or height + * were out of range; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateTextureFromSurface + * \sa SDL_DestroyTexture + * \sa SDL_QueryTexture + * \sa SDL_UpdateTexture + */ +extern DECLSPEC SDL_Texture * SDLCALL SDL_CreateTexture(SDL_Renderer * renderer, + Uint32 format, + int access, int w, + int h); + +/** + * Create a texture from an existing surface. + * + * The surface is not modified or freed by this function. + * + * The SDL_TextureAccess hint for the created texture is + * `SDL_TEXTUREACCESS_STATIC`. + * + * The pixel format of the created texture may be different from the pixel + * format of the surface. Use SDL_QueryTexture() to query the pixel format of + * the texture. + * + * \param renderer the rendering context + * \param surface the SDL_Surface structure containing pixel data used to fill + * the texture + * \returns the created texture or NULL on failure; call SDL_GetError() for + * more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateTexture + * \sa SDL_DestroyTexture + * \sa SDL_QueryTexture + */ +extern DECLSPEC SDL_Texture * SDLCALL SDL_CreateTextureFromSurface(SDL_Renderer * renderer, SDL_Surface * surface); + +/** + * Query the attributes of a texture. + * + * \param texture the texture to query + * \param format a pointer filled in with the raw format of the texture; the + * actual format may differ, but pixel transfers will use this + * format (one of the SDL_PixelFormatEnum values). This argument + * can be NULL if you don't need this information. + * \param access a pointer filled in with the actual access to the texture + * (one of the SDL_TextureAccess values). This argument can be + * NULL if you don't need this information. + * \param w a pointer filled in with the width of the texture in pixels. This + * argument can be NULL if you don't need this information. + * \param h a pointer filled in with the height of the texture in pixels. This + * argument can be NULL if you don't need this information. + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateTexture + */ +extern DECLSPEC int SDLCALL SDL_QueryTexture(SDL_Texture * texture, + Uint32 * format, int *access, + int *w, int *h); + +/** + * Set an additional color value multiplied into render copy operations. + * + * When this texture is rendered, during the copy operation each source color + * channel is modulated by the appropriate color value according to the + * following formula: + * + * `srcC = srcC * (color / 255)` + * + * Color modulation is not always supported by the renderer; it will return -1 + * if color modulation is not supported. + * + * \param texture the texture to update + * \param r the red color value multiplied into copy operations + * \param g the green color value multiplied into copy operations + * \param b the blue color value multiplied into copy operations + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetTextureColorMod + * \sa SDL_SetTextureAlphaMod + */ +extern DECLSPEC int SDLCALL SDL_SetTextureColorMod(SDL_Texture * texture, + Uint8 r, Uint8 g, Uint8 b); + + +/** + * Get the additional color value multiplied into render copy operations. + * + * \param texture the texture to query + * \param r a pointer filled in with the current red color value + * \param g a pointer filled in with the current green color value + * \param b a pointer filled in with the current blue color value + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetTextureAlphaMod + * \sa SDL_SetTextureColorMod + */ +extern DECLSPEC int SDLCALL SDL_GetTextureColorMod(SDL_Texture * texture, + Uint8 * r, Uint8 * g, + Uint8 * b); + +/** + * Set an additional alpha value multiplied into render copy operations. + * + * When this texture is rendered, during the copy operation the source alpha + * value is modulated by this alpha value according to the following formula: + * + * `srcA = srcA * (alpha / 255)` + * + * Alpha modulation is not always supported by the renderer; it will return -1 + * if alpha modulation is not supported. + * + * \param texture the texture to update + * \param alpha the source alpha value multiplied into copy operations + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetTextureAlphaMod + * \sa SDL_SetTextureColorMod + */ +extern DECLSPEC int SDLCALL SDL_SetTextureAlphaMod(SDL_Texture * texture, + Uint8 alpha); + +/** + * Get the additional alpha value multiplied into render copy operations. + * + * \param texture the texture to query + * \param alpha a pointer filled in with the current alpha value + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetTextureColorMod + * \sa SDL_SetTextureAlphaMod + */ +extern DECLSPEC int SDLCALL SDL_GetTextureAlphaMod(SDL_Texture * texture, + Uint8 * alpha); + +/** + * Set the blend mode for a texture, used by SDL_RenderCopy(). + * + * If the blend mode is not supported, the closest supported mode is chosen + * and this function returns -1. + * + * \param texture the texture to update + * \param blendMode the SDL_BlendMode to use for texture blending + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetTextureBlendMode + * \sa SDL_RenderCopy + */ +extern DECLSPEC int SDLCALL SDL_SetTextureBlendMode(SDL_Texture * texture, + SDL_BlendMode blendMode); + +/** + * Get the blend mode used for texture copy operations. + * + * \param texture the texture to query + * \param blendMode a pointer filled in with the current SDL_BlendMode + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetTextureBlendMode + */ +extern DECLSPEC int SDLCALL SDL_GetTextureBlendMode(SDL_Texture * texture, + SDL_BlendMode *blendMode); + +/** + * Set the scale mode used for texture scale operations. + * + * If the scale mode is not supported, the closest supported mode is chosen. + * + * \param texture The texture to update. + * \param scaleMode the SDL_ScaleMode to use for texture scaling. + * \returns 0 on success, or -1 if the texture is not valid. + * + * \since This function is available since SDL 2.0.12. + * + * \sa SDL_GetTextureScaleMode + */ +extern DECLSPEC int SDLCALL SDL_SetTextureScaleMode(SDL_Texture * texture, + SDL_ScaleMode scaleMode); + +/** + * Get the scale mode used for texture scale operations. + * + * \param texture the texture to query. + * \param scaleMode a pointer filled in with the current scale mode. + * \return 0 on success, or -1 if the texture is not valid. + * + * \since This function is available since SDL 2.0.12. + * + * \sa SDL_SetTextureScaleMode + */ +extern DECLSPEC int SDLCALL SDL_GetTextureScaleMode(SDL_Texture * texture, + SDL_ScaleMode *scaleMode); + +/** + * Associate a user-specified pointer with a texture. + * + * \param texture the texture to update. + * \param userdata the pointer to associate with the texture. + * \returns 0 on success, or -1 if the texture is not valid. + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_GetTextureUserData + */ +extern DECLSPEC int SDLCALL SDL_SetTextureUserData(SDL_Texture * texture, + void *userdata); + +/** + * Get the user-specified pointer associated with a texture + * + * \param texture the texture to query. + * \return the pointer associated with the texture, or NULL if the texture is + * not valid. + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_SetTextureUserData + */ +extern DECLSPEC void * SDLCALL SDL_GetTextureUserData(SDL_Texture * texture); + +/** + * Update the given texture rectangle with new pixel data. + * + * The pixel data must be in the pixel format of the texture. Use + * SDL_QueryTexture() to query the pixel format of the texture. + * + * This is a fairly slow function, intended for use with static textures that + * do not change often. + * + * If the texture is intended to be updated often, it is preferred to create + * the texture as streaming and use the locking functions referenced below. + * While this function will work with streaming textures, for optimization + * reasons you may not get the pixels back if you lock the texture afterward. + * + * \param texture the texture to update + * \param rect an SDL_Rect structure representing the area to update, or NULL + * to update the entire texture + * \param pixels the raw pixel data in the format of the texture + * \param pitch the number of bytes in a row of pixel data, including padding + * between lines + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateTexture + * \sa SDL_LockTexture + * \sa SDL_UnlockTexture + */ +extern DECLSPEC int SDLCALL SDL_UpdateTexture(SDL_Texture * texture, + const SDL_Rect * rect, + const void *pixels, int pitch); + +/** + * Update a rectangle within a planar YV12 or IYUV texture with new pixel + * data. + * + * You can use SDL_UpdateTexture() as long as your pixel data is a contiguous + * block of Y and U/V planes in the proper order, but this function is + * available if your pixel data is not contiguous. + * + * \param texture the texture to update + * \param rect a pointer to the rectangle of pixels to update, or NULL to + * update the entire texture + * \param Yplane the raw pixel data for the Y plane + * \param Ypitch the number of bytes between rows of pixel data for the Y + * plane + * \param Uplane the raw pixel data for the U plane + * \param Upitch the number of bytes between rows of pixel data for the U + * plane + * \param Vplane the raw pixel data for the V plane + * \param Vpitch the number of bytes between rows of pixel data for the V + * plane + * \returns 0 on success or -1 if the texture is not valid; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.1. + * + * \sa SDL_UpdateTexture + */ +extern DECLSPEC int SDLCALL SDL_UpdateYUVTexture(SDL_Texture * texture, + const SDL_Rect * rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *Uplane, int Upitch, + const Uint8 *Vplane, int Vpitch); + +/** + * Update a rectangle within a planar NV12 or NV21 texture with new pixels. + * + * You can use SDL_UpdateTexture() as long as your pixel data is a contiguous + * block of NV12/21 planes in the proper order, but this function is available + * if your pixel data is not contiguous. + * + * \param texture the texture to update + * \param rect a pointer to the rectangle of pixels to update, or NULL to + * update the entire texture. + * \param Yplane the raw pixel data for the Y plane. + * \param Ypitch the number of bytes between rows of pixel data for the Y + * plane. + * \param UVplane the raw pixel data for the UV plane. + * \param UVpitch the number of bytes between rows of pixel data for the UV + * plane. + * \return 0 on success, or -1 if the texture is not valid. + * + * \since This function is available since SDL 2.0.16. + */ +extern DECLSPEC int SDLCALL SDL_UpdateNVTexture(SDL_Texture * texture, + const SDL_Rect * rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *UVplane, int UVpitch); + +/** + * Lock a portion of the texture for **write-only** pixel access. + * + * As an optimization, the pixels made available for editing don't necessarily + * contain the old texture data. This is a write-only operation, and if you + * need to keep a copy of the texture data you should do that at the + * application level. + * + * You must use SDL_UnlockTexture() to unlock the pixels and apply any + * changes. + * + * \param texture the texture to lock for access, which was created with + * `SDL_TEXTUREACCESS_STREAMING` + * \param rect an SDL_Rect structure representing the area to lock for access; + * NULL to lock the entire texture + * \param pixels this is filled in with a pointer to the locked pixels, + * appropriately offset by the locked area + * \param pitch this is filled in with the pitch of the locked pixels; the + * pitch is the length of one row in bytes + * \returns 0 on success or a negative error code if the texture is not valid + * or was not created with `SDL_TEXTUREACCESS_STREAMING`; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_UnlockTexture + */ +extern DECLSPEC int SDLCALL SDL_LockTexture(SDL_Texture * texture, + const SDL_Rect * rect, + void **pixels, int *pitch); + +/** + * Lock a portion of the texture for **write-only** pixel access, and expose + * it as a SDL surface. + * + * Besides providing an SDL_Surface instead of raw pixel data, this function + * operates like SDL_LockTexture. + * + * As an optimization, the pixels made available for editing don't necessarily + * contain the old texture data. This is a write-only operation, and if you + * need to keep a copy of the texture data you should do that at the + * application level. + * + * You must use SDL_UnlockTexture() to unlock the pixels and apply any + * changes. + * + * The returned surface is freed internally after calling SDL_UnlockTexture() + * or SDL_DestroyTexture(). The caller should not free it. + * + * \param texture the texture to lock for access, which was created with + * `SDL_TEXTUREACCESS_STREAMING` + * \param rect a pointer to the rectangle to lock for access. If the rect is + * NULL, the entire texture will be locked + * \param surface this is filled in with an SDL surface representing the + * locked area + * \returns 0 on success, or -1 if the texture is not valid or was not created + * with `SDL_TEXTUREACCESS_STREAMING` + * + * \since This function is available since SDL 2.0.12. + * + * \sa SDL_LockTexture + * \sa SDL_UnlockTexture + */ +extern DECLSPEC int SDLCALL SDL_LockTextureToSurface(SDL_Texture *texture, + const SDL_Rect *rect, + SDL_Surface **surface); + +/** + * Unlock a texture, uploading the changes to video memory, if needed. + * + * **Warning**: Please note that SDL_LockTexture() is intended to be + * write-only; it will not guarantee the previous contents of the texture will + * be provided. You must fully initialize any area of a texture that you lock + * before unlocking it, as the pixels might otherwise be uninitialized memory. + * + * Which is to say: locking and immediately unlocking a texture can result in + * corrupted textures, depending on the renderer in use. + * + * \param texture a texture locked by SDL_LockTexture() + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LockTexture + */ +extern DECLSPEC void SDLCALL SDL_UnlockTexture(SDL_Texture * texture); + +/** + * Determine whether a renderer supports the use of render targets. + * + * \param renderer the renderer that will be checked + * \returns SDL_TRUE if supported or SDL_FALSE if not. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetRenderTarget + */ +extern DECLSPEC SDL_bool SDLCALL SDL_RenderTargetSupported(SDL_Renderer *renderer); + +/** + * Set a texture as the current rendering target. + * + * Before using this function, you should check the + * `SDL_RENDERER_TARGETTEXTURE` bit in the flags of SDL_RendererInfo to see if + * render targets are supported. + * + * The default render target is the window for which the renderer was created. + * To stop rendering to a texture and render to the window again, call this + * function with a NULL `texture`. + * + * \param renderer the rendering context + * \param texture the targeted texture, which must be created with the + * `SDL_TEXTUREACCESS_TARGET` flag, or NULL to render to the + * window instead of a texture. + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetRenderTarget + */ +extern DECLSPEC int SDLCALL SDL_SetRenderTarget(SDL_Renderer *renderer, + SDL_Texture *texture); + +/** + * Get the current render target. + * + * The default render target is the window for which the renderer was created, + * and is reported a NULL here. + * + * \param renderer the rendering context + * \returns the current render target or NULL for the default render target. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetRenderTarget + */ +extern DECLSPEC SDL_Texture * SDLCALL SDL_GetRenderTarget(SDL_Renderer *renderer); + +/** + * Set a device independent resolution for rendering. + * + * This function uses the viewport and scaling functionality to allow a fixed + * logical resolution for rendering, regardless of the actual output + * resolution. If the actual output resolution doesn't have the same aspect + * ratio the output rendering will be centered within the output display. + * + * If the output display is a window, mouse and touch events in the window + * will be filtered and scaled so they seem to arrive within the logical + * resolution. The SDL_HINT_MOUSE_RELATIVE_SCALING hint controls whether + * relative motion events are also scaled. + * + * If this function results in scaling or subpixel drawing by the rendering + * backend, it will be handled using the appropriate quality hints. + * + * \param renderer the renderer for which resolution should be set + * \param w the width of the logical resolution + * \param h the height of the logical resolution + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderGetLogicalSize + */ +extern DECLSPEC int SDLCALL SDL_RenderSetLogicalSize(SDL_Renderer * renderer, int w, int h); + +/** + * Get device independent resolution for rendering. + * + * When using the main rendering target (eg no target texture is set): this + * may return 0 for `w` and `h` if the SDL_Renderer has never had its logical + * size set by SDL_RenderSetLogicalSize(). Otherwise it returns the logical + * width and height. + * + * When using a target texture: Never return 0 for `w` and `h` at first. Then + * it returns the logical width and height that are set. + * + * \param renderer a rendering context + * \param w an int to be filled with the width + * \param h an int to be filled with the height + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderSetLogicalSize + */ +extern DECLSPEC void SDLCALL SDL_RenderGetLogicalSize(SDL_Renderer * renderer, int *w, int *h); + +/** + * Set whether to force integer scales for resolution-independent rendering. + * + * This function restricts the logical viewport to integer values - that is, + * when a resolution is between two multiples of a logical size, the viewport + * size is rounded down to the lower multiple. + * + * \param renderer the renderer for which integer scaling should be set + * \param enable enable or disable the integer scaling for rendering + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.5. + * + * \sa SDL_RenderGetIntegerScale + * \sa SDL_RenderSetLogicalSize + */ +extern DECLSPEC int SDLCALL SDL_RenderSetIntegerScale(SDL_Renderer * renderer, + SDL_bool enable); + +/** + * Get whether integer scales are forced for resolution-independent rendering. + * + * \param renderer the renderer from which integer scaling should be queried + * \returns SDL_TRUE if integer scales are forced or SDL_FALSE if not and on + * failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.5. + * + * \sa SDL_RenderSetIntegerScale + */ +extern DECLSPEC SDL_bool SDLCALL SDL_RenderGetIntegerScale(SDL_Renderer * renderer); + +/** + * Set the drawing area for rendering on the current target. + * + * When the window is resized, the viewport is reset to fill the entire new + * window size. + * + * \param renderer the rendering context + * \param rect the SDL_Rect structure representing the drawing area, or NULL + * to set the viewport to the entire target + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderGetViewport + */ +extern DECLSPEC int SDLCALL SDL_RenderSetViewport(SDL_Renderer * renderer, + const SDL_Rect * rect); + +/** + * Get the drawing area for the current target. + * + * \param renderer the rendering context + * \param rect an SDL_Rect structure filled in with the current drawing area + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderSetViewport + */ +extern DECLSPEC void SDLCALL SDL_RenderGetViewport(SDL_Renderer * renderer, + SDL_Rect * rect); + +/** + * Set the clip rectangle for rendering on the specified target. + * + * \param renderer the rendering context for which clip rectangle should be + * set + * \param rect an SDL_Rect structure representing the clip area, relative to + * the viewport, or NULL to disable clipping + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderGetClipRect + * \sa SDL_RenderIsClipEnabled + */ +extern DECLSPEC int SDLCALL SDL_RenderSetClipRect(SDL_Renderer * renderer, + const SDL_Rect * rect); + +/** + * Get the clip rectangle for the current target. + * + * \param renderer the rendering context from which clip rectangle should be + * queried + * \param rect an SDL_Rect structure filled in with the current clipping area + * or an empty rectangle if clipping is disabled + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderIsClipEnabled + * \sa SDL_RenderSetClipRect + */ +extern DECLSPEC void SDLCALL SDL_RenderGetClipRect(SDL_Renderer * renderer, + SDL_Rect * rect); + +/** + * Get whether clipping is enabled on the given renderer. + * + * \param renderer the renderer from which clip state should be queried + * \returns SDL_TRUE if clipping is enabled or SDL_FALSE if not; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.4. + * + * \sa SDL_RenderGetClipRect + * \sa SDL_RenderSetClipRect + */ +extern DECLSPEC SDL_bool SDLCALL SDL_RenderIsClipEnabled(SDL_Renderer * renderer); + + +/** + * Set the drawing scale for rendering on the current target. + * + * The drawing coordinates are scaled by the x/y scaling factors before they + * are used by the renderer. This allows resolution independent drawing with a + * single coordinate system. + * + * If this results in scaling or subpixel drawing by the rendering backend, it + * will be handled using the appropriate quality hints. For best results use + * integer scaling factors. + * + * \param renderer a rendering context + * \param scaleX the horizontal scaling factor + * \param scaleY the vertical scaling factor + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderGetScale + * \sa SDL_RenderSetLogicalSize + */ +extern DECLSPEC int SDLCALL SDL_RenderSetScale(SDL_Renderer * renderer, + float scaleX, float scaleY); + +/** + * Get the drawing scale for the current target. + * + * \param renderer the renderer from which drawing scale should be queried + * \param scaleX a pointer filled in with the horizontal scaling factor + * \param scaleY a pointer filled in with the vertical scaling factor + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderSetScale + */ +extern DECLSPEC void SDLCALL SDL_RenderGetScale(SDL_Renderer * renderer, + float *scaleX, float *scaleY); + +/** + * Get logical coordinates of point in renderer when given real coordinates of + * point in window. + * + * Logical coordinates will differ from real coordinates when render is scaled + * and logical renderer size set + * + * \param renderer the renderer from which the logical coordinates should be + * calculated + * \param windowX the real X coordinate in the window + * \param windowY the real Y coordinate in the window + * \param logicalX the pointer filled with the logical x coordinate + * \param logicalY the pointer filled with the logical y coordinate + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_RenderGetScale + * \sa SDL_RenderSetScale + * \sa SDL_RenderGetLogicalSize + * \sa SDL_RenderSetLogicalSize + */ +extern DECLSPEC void SDLCALL SDL_RenderWindowToLogical(SDL_Renderer * renderer, + int windowX, int windowY, + float *logicalX, float *logicalY); + + +/** + * Get real coordinates of point in window when given logical coordinates of + * point in renderer. + * + * Logical coordinates will differ from real coordinates when render is scaled + * and logical renderer size set + * + * \param renderer the renderer from which the window coordinates should be + * calculated + * \param logicalX the logical x coordinate + * \param logicalY the logical y coordinate + * \param windowX the pointer filled with the real X coordinate in the window + * \param windowY the pointer filled with the real Y coordinate in the window + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_RenderGetScale + * \sa SDL_RenderSetScale + * \sa SDL_RenderGetLogicalSize + * \sa SDL_RenderSetLogicalSize + */ +extern DECLSPEC void SDLCALL SDL_RenderLogicalToWindow(SDL_Renderer * renderer, + float logicalX, float logicalY, + int *windowX, int *windowY); + +/** + * Set the color used for drawing operations (Rect, Line and Clear). + * + * Set the color for drawing or filling rectangles, lines, and points, and for + * SDL_RenderClear(). + * + * \param renderer the rendering context + * \param r the red value used to draw on the rendering target + * \param g the green value used to draw on the rendering target + * \param b the blue value used to draw on the rendering target + * \param a the alpha value used to draw on the rendering target; usually + * `SDL_ALPHA_OPAQUE` (255). Use SDL_SetRenderDrawBlendMode to + * specify how the alpha channel is used + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetRenderDrawColor + * \sa SDL_RenderClear + * \sa SDL_RenderDrawLine + * \sa SDL_RenderDrawLines + * \sa SDL_RenderDrawPoint + * \sa SDL_RenderDrawPoints + * \sa SDL_RenderDrawRect + * \sa SDL_RenderDrawRects + * \sa SDL_RenderFillRect + * \sa SDL_RenderFillRects + */ +extern DECLSPEC int SDLCALL SDL_SetRenderDrawColor(SDL_Renderer * renderer, + Uint8 r, Uint8 g, Uint8 b, + Uint8 a); + +/** + * Get the color used for drawing operations (Rect, Line and Clear). + * + * \param renderer the rendering context + * \param r a pointer filled in with the red value used to draw on the + * rendering target + * \param g a pointer filled in with the green value used to draw on the + * rendering target + * \param b a pointer filled in with the blue value used to draw on the + * rendering target + * \param a a pointer filled in with the alpha value used to draw on the + * rendering target; usually `SDL_ALPHA_OPAQUE` (255) + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetRenderDrawColor + */ +extern DECLSPEC int SDLCALL SDL_GetRenderDrawColor(SDL_Renderer * renderer, + Uint8 * r, Uint8 * g, Uint8 * b, + Uint8 * a); + +/** + * Set the blend mode used for drawing operations (Fill and Line). + * + * If the blend mode is not supported, the closest supported mode is chosen. + * + * \param renderer the rendering context + * \param blendMode the SDL_BlendMode to use for blending + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetRenderDrawBlendMode + * \sa SDL_RenderDrawLine + * \sa SDL_RenderDrawLines + * \sa SDL_RenderDrawPoint + * \sa SDL_RenderDrawPoints + * \sa SDL_RenderDrawRect + * \sa SDL_RenderDrawRects + * \sa SDL_RenderFillRect + * \sa SDL_RenderFillRects + */ +extern DECLSPEC int SDLCALL SDL_SetRenderDrawBlendMode(SDL_Renderer * renderer, + SDL_BlendMode blendMode); + +/** + * Get the blend mode used for drawing operations. + * + * \param renderer the rendering context + * \param blendMode a pointer filled in with the current SDL_BlendMode + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetRenderDrawBlendMode + */ +extern DECLSPEC int SDLCALL SDL_GetRenderDrawBlendMode(SDL_Renderer * renderer, + SDL_BlendMode *blendMode); + +/** + * Clear the current rendering target with the drawing color. + * + * This function clears the entire rendering target, ignoring the viewport and + * the clip rectangle. + * + * \param renderer the rendering context + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetRenderDrawColor + */ +extern DECLSPEC int SDLCALL SDL_RenderClear(SDL_Renderer * renderer); + +/** + * Draw a point on the current rendering target. + * + * SDL_RenderDrawPoint() draws a single point. If you want to draw multiple, + * use SDL_RenderDrawPoints() instead. + * + * \param renderer the rendering context + * \param x the x coordinate of the point + * \param y the y coordinate of the point + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderDrawLine + * \sa SDL_RenderDrawLines + * \sa SDL_RenderDrawPoints + * \sa SDL_RenderDrawRect + * \sa SDL_RenderDrawRects + * \sa SDL_RenderFillRect + * \sa SDL_RenderFillRects + * \sa SDL_RenderPresent + * \sa SDL_SetRenderDrawBlendMode + * \sa SDL_SetRenderDrawColor + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawPoint(SDL_Renderer * renderer, + int x, int y); + +/** + * Draw multiple points on the current rendering target. + * + * \param renderer the rendering context + * \param points an array of SDL_Point structures that represent the points to + * draw + * \param count the number of points to draw + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderDrawLine + * \sa SDL_RenderDrawLines + * \sa SDL_RenderDrawPoint + * \sa SDL_RenderDrawRect + * \sa SDL_RenderDrawRects + * \sa SDL_RenderFillRect + * \sa SDL_RenderFillRects + * \sa SDL_RenderPresent + * \sa SDL_SetRenderDrawBlendMode + * \sa SDL_SetRenderDrawColor + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawPoints(SDL_Renderer * renderer, + const SDL_Point * points, + int count); + +/** + * Draw a line on the current rendering target. + * + * SDL_RenderDrawLine() draws the line to include both end points. If you want + * to draw multiple, connecting lines use SDL_RenderDrawLines() instead. + * + * \param renderer the rendering context + * \param x1 the x coordinate of the start point + * \param y1 the y coordinate of the start point + * \param x2 the x coordinate of the end point + * \param y2 the y coordinate of the end point + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderDrawLines + * \sa SDL_RenderDrawPoint + * \sa SDL_RenderDrawPoints + * \sa SDL_RenderDrawRect + * \sa SDL_RenderDrawRects + * \sa SDL_RenderFillRect + * \sa SDL_RenderFillRects + * \sa SDL_RenderPresent + * \sa SDL_SetRenderDrawBlendMode + * \sa SDL_SetRenderDrawColor + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawLine(SDL_Renderer * renderer, + int x1, int y1, int x2, int y2); + +/** + * Draw a series of connected lines on the current rendering target. + * + * \param renderer the rendering context + * \param points an array of SDL_Point structures representing points along + * the lines + * \param count the number of points, drawing count-1 lines + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderDrawLine + * \sa SDL_RenderDrawPoint + * \sa SDL_RenderDrawPoints + * \sa SDL_RenderDrawRect + * \sa SDL_RenderDrawRects + * \sa SDL_RenderFillRect + * \sa SDL_RenderFillRects + * \sa SDL_RenderPresent + * \sa SDL_SetRenderDrawBlendMode + * \sa SDL_SetRenderDrawColor + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawLines(SDL_Renderer * renderer, + const SDL_Point * points, + int count); + +/** + * Draw a rectangle on the current rendering target. + * + * \param renderer the rendering context + * \param rect an SDL_Rect structure representing the rectangle to draw, or + * NULL to outline the entire rendering target + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderDrawLine + * \sa SDL_RenderDrawLines + * \sa SDL_RenderDrawPoint + * \sa SDL_RenderDrawPoints + * \sa SDL_RenderDrawRects + * \sa SDL_RenderFillRect + * \sa SDL_RenderFillRects + * \sa SDL_RenderPresent + * \sa SDL_SetRenderDrawBlendMode + * \sa SDL_SetRenderDrawColor + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawRect(SDL_Renderer * renderer, + const SDL_Rect * rect); + +/** + * Draw some number of rectangles on the current rendering target. + * + * \param renderer the rendering context + * \param rects an array of SDL_Rect structures representing the rectangles to + * be drawn + * \param count the number of rectangles + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderDrawLine + * \sa SDL_RenderDrawLines + * \sa SDL_RenderDrawPoint + * \sa SDL_RenderDrawPoints + * \sa SDL_RenderDrawRect + * \sa SDL_RenderFillRect + * \sa SDL_RenderFillRects + * \sa SDL_RenderPresent + * \sa SDL_SetRenderDrawBlendMode + * \sa SDL_SetRenderDrawColor + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawRects(SDL_Renderer * renderer, + const SDL_Rect * rects, + int count); + +/** + * Fill a rectangle on the current rendering target with the drawing color. + * + * The current drawing color is set by SDL_SetRenderDrawColor(), and the + * color's alpha value is ignored unless blending is enabled with the + * appropriate call to SDL_SetRenderDrawBlendMode(). + * + * \param renderer the rendering context + * \param rect the SDL_Rect structure representing the rectangle to fill, or + * NULL for the entire rendering target + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderDrawLine + * \sa SDL_RenderDrawLines + * \sa SDL_RenderDrawPoint + * \sa SDL_RenderDrawPoints + * \sa SDL_RenderDrawRect + * \sa SDL_RenderDrawRects + * \sa SDL_RenderFillRects + * \sa SDL_RenderPresent + * \sa SDL_SetRenderDrawBlendMode + * \sa SDL_SetRenderDrawColor + */ +extern DECLSPEC int SDLCALL SDL_RenderFillRect(SDL_Renderer * renderer, + const SDL_Rect * rect); + +/** + * Fill some number of rectangles on the current rendering target with the + * drawing color. + * + * \param renderer the rendering context + * \param rects an array of SDL_Rect structures representing the rectangles to + * be filled + * \param count the number of rectangles + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderDrawLine + * \sa SDL_RenderDrawLines + * \sa SDL_RenderDrawPoint + * \sa SDL_RenderDrawPoints + * \sa SDL_RenderDrawRect + * \sa SDL_RenderDrawRects + * \sa SDL_RenderFillRect + * \sa SDL_RenderPresent + */ +extern DECLSPEC int SDLCALL SDL_RenderFillRects(SDL_Renderer * renderer, + const SDL_Rect * rects, + int count); + +/** + * Copy a portion of the texture to the current rendering target. + * + * The texture is blended with the destination based on its blend mode set + * with SDL_SetTextureBlendMode(). + * + * The texture color is affected based on its color modulation set by + * SDL_SetTextureColorMod(). + * + * The texture alpha is affected based on its alpha modulation set by + * SDL_SetTextureAlphaMod(). + * + * \param renderer the rendering context + * \param texture the source texture + * \param srcrect the source SDL_Rect structure or NULL for the entire texture + * \param dstrect the destination SDL_Rect structure or NULL for the entire + * rendering target; the texture will be stretched to fill the + * given rectangle + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderCopyEx + * \sa SDL_SetTextureAlphaMod + * \sa SDL_SetTextureBlendMode + * \sa SDL_SetTextureColorMod + */ +extern DECLSPEC int SDLCALL SDL_RenderCopy(SDL_Renderer * renderer, + SDL_Texture * texture, + const SDL_Rect * srcrect, + const SDL_Rect * dstrect); + +/** + * Copy a portion of the texture to the current rendering, with optional + * rotation and flipping. + * + * Copy a portion of the texture to the current rendering target, optionally + * rotating it by angle around the given center and also flipping it + * top-bottom and/or left-right. + * + * The texture is blended with the destination based on its blend mode set + * with SDL_SetTextureBlendMode(). + * + * The texture color is affected based on its color modulation set by + * SDL_SetTextureColorMod(). + * + * The texture alpha is affected based on its alpha modulation set by + * SDL_SetTextureAlphaMod(). + * + * \param renderer the rendering context + * \param texture the source texture + * \param srcrect the source SDL_Rect structure or NULL for the entire texture + * \param dstrect the destination SDL_Rect structure or NULL for the entire + * rendering target + * \param angle an angle in degrees that indicates the rotation that will be + * applied to dstrect, rotating it in a clockwise direction + * \param center a pointer to a point indicating the point around which + * dstrect will be rotated (if NULL, rotation will be done + * around `dstrect.w / 2`, `dstrect.h / 2`) + * \param flip a SDL_RendererFlip value stating which flipping actions should + * be performed on the texture + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderCopy + * \sa SDL_SetTextureAlphaMod + * \sa SDL_SetTextureBlendMode + * \sa SDL_SetTextureColorMod + */ +extern DECLSPEC int SDLCALL SDL_RenderCopyEx(SDL_Renderer * renderer, + SDL_Texture * texture, + const SDL_Rect * srcrect, + const SDL_Rect * dstrect, + const double angle, + const SDL_Point *center, + const SDL_RendererFlip flip); + + +/** + * Draw a point on the current rendering target at subpixel precision. + * + * \param renderer The renderer which should draw a point. + * \param x The x coordinate of the point. + * \param y The y coordinate of the point. + * \return 0 on success, or -1 on error + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawPointF(SDL_Renderer * renderer, + float x, float y); + +/** + * Draw multiple points on the current rendering target at subpixel precision. + * + * \param renderer The renderer which should draw multiple points. + * \param points The points to draw + * \param count The number of points to draw + * \return 0 on success, or -1 on error + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawPointsF(SDL_Renderer * renderer, + const SDL_FPoint * points, + int count); + +/** + * Draw a line on the current rendering target at subpixel precision. + * + * \param renderer The renderer which should draw a line. + * \param x1 The x coordinate of the start point. + * \param y1 The y coordinate of the start point. + * \param x2 The x coordinate of the end point. + * \param y2 The y coordinate of the end point. + * \return 0 on success, or -1 on error + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawLineF(SDL_Renderer * renderer, + float x1, float y1, float x2, float y2); + +/** + * Draw a series of connected lines on the current rendering target at + * subpixel precision. + * + * \param renderer The renderer which should draw multiple lines. + * \param points The points along the lines + * \param count The number of points, drawing count-1 lines + * \return 0 on success, or -1 on error + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawLinesF(SDL_Renderer * renderer, + const SDL_FPoint * points, + int count); + +/** + * Draw a rectangle on the current rendering target at subpixel precision. + * + * \param renderer The renderer which should draw a rectangle. + * \param rect A pointer to the destination rectangle, or NULL to outline the + * entire rendering target. + * \return 0 on success, or -1 on error + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawRectF(SDL_Renderer * renderer, + const SDL_FRect * rect); + +/** + * Draw some number of rectangles on the current rendering target at subpixel + * precision. + * + * \param renderer The renderer which should draw multiple rectangles. + * \param rects A pointer to an array of destination rectangles. + * \param count The number of rectangles. + * \return 0 on success, or -1 on error + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC int SDLCALL SDL_RenderDrawRectsF(SDL_Renderer * renderer, + const SDL_FRect * rects, + int count); + +/** + * Fill a rectangle on the current rendering target with the drawing color at + * subpixel precision. + * + * \param renderer The renderer which should fill a rectangle. + * \param rect A pointer to the destination rectangle, or NULL for the entire + * rendering target. + * \return 0 on success, or -1 on error + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC int SDLCALL SDL_RenderFillRectF(SDL_Renderer * renderer, + const SDL_FRect * rect); + +/** + * Fill some number of rectangles on the current rendering target with the + * drawing color at subpixel precision. + * + * \param renderer The renderer which should fill multiple rectangles. + * \param rects A pointer to an array of destination rectangles. + * \param count The number of rectangles. + * \return 0 on success, or -1 on error + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC int SDLCALL SDL_RenderFillRectsF(SDL_Renderer * renderer, + const SDL_FRect * rects, + int count); + +/** + * Copy a portion of the texture to the current rendering target at subpixel + * precision. + * + * \param renderer The renderer which should copy parts of a texture. + * \param texture The source texture. + * \param srcrect A pointer to the source rectangle, or NULL for the entire + * texture. + * \param dstrect A pointer to the destination rectangle, or NULL for the + * entire rendering target. + * \return 0 on success, or -1 on error + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC int SDLCALL SDL_RenderCopyF(SDL_Renderer * renderer, + SDL_Texture * texture, + const SDL_Rect * srcrect, + const SDL_FRect * dstrect); + +/** + * Copy a portion of the source texture to the current rendering target, with + * rotation and flipping, at subpixel precision. + * + * \param renderer The renderer which should copy parts of a texture. + * \param texture The source texture. + * \param srcrect A pointer to the source rectangle, or NULL for the entire + * texture. + * \param dstrect A pointer to the destination rectangle, or NULL for the + * entire rendering target. + * \param angle An angle in degrees that indicates the rotation that will be + * applied to dstrect, rotating it in a clockwise direction + * \param center A pointer to a point indicating the point around which + * dstrect will be rotated (if NULL, rotation will be done + * around dstrect.w/2, dstrect.h/2). + * \param flip An SDL_RendererFlip value stating which flipping actions should + * be performed on the texture + * \return 0 on success, or -1 on error + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC int SDLCALL SDL_RenderCopyExF(SDL_Renderer * renderer, + SDL_Texture * texture, + const SDL_Rect * srcrect, + const SDL_FRect * dstrect, + const double angle, + const SDL_FPoint *center, + const SDL_RendererFlip flip); + +/** + * Render a list of triangles, optionally using a texture and indices into the + * vertex array Color and alpha modulation is done per vertex + * (SDL_SetTextureColorMod and SDL_SetTextureAlphaMod are ignored). + * + * \param renderer The rendering context. + * \param texture (optional) The SDL texture to use. + * \param vertices Vertices. + * \param num_vertices Number of vertices. + * \param indices (optional) An array of integer indices into the 'vertices' + * array, if NULL all vertices will be rendered in sequential + * order. + * \param num_indices Number of indices. + * \return 0 on success, or -1 if the operation is not supported + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_RenderGeometryRaw + * \sa SDL_Vertex + */ +extern DECLSPEC int SDLCALL SDL_RenderGeometry(SDL_Renderer *renderer, + SDL_Texture *texture, + const SDL_Vertex *vertices, int num_vertices, + const int *indices, int num_indices); + +/** + * Render a list of triangles, optionally using a texture and indices into the + * vertex arrays Color and alpha modulation is done per vertex + * (SDL_SetTextureColorMod and SDL_SetTextureAlphaMod are ignored). + * + * \param renderer The rendering context. + * \param texture (optional) The SDL texture to use. + * \param xy Vertex positions + * \param xy_stride Byte size to move from one element to the next element + * \param color Vertex colors (as SDL_Color) + * \param color_stride Byte size to move from one element to the next element + * \param uv Vertex normalized texture coordinates + * \param uv_stride Byte size to move from one element to the next element + * \param num_vertices Number of vertices. + * \param indices (optional) An array of indices into the 'vertices' arrays, + * if NULL all vertices will be rendered in sequential order. + * \param num_indices Number of indices. + * \param size_indices Index size: 1 (byte), 2 (short), 4 (int) + * \return 0 on success, or -1 if the operation is not supported + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_RenderGeometry + * \sa SDL_Vertex + */ +extern DECLSPEC int SDLCALL SDL_RenderGeometryRaw(SDL_Renderer *renderer, + SDL_Texture *texture, + const float *xy, int xy_stride, + const SDL_Color *color, int color_stride, + const float *uv, int uv_stride, + int num_vertices, + const void *indices, int num_indices, int size_indices); + +/** + * Read pixels from the current rendering target to an array of pixels. + * + * **WARNING**: This is a very slow operation, and should not be used + * frequently. If you're using this on the main rendering target, it should be + * called after rendering and before SDL_RenderPresent(). + * + * `pitch` specifies the number of bytes between rows in the destination + * `pixels` data. This allows you to write to a subrectangle or have padded + * rows in the destination. Generally, `pitch` should equal the number of + * pixels per row in the `pixels` data times the number of bytes per pixel, + * but it might contain additional padding (for example, 24bit RGB Windows + * Bitmap data pads all rows to multiples of 4 bytes). + * + * \param renderer the rendering context + * \param rect an SDL_Rect structure representing the area to read, or NULL + * for the entire render target + * \param format an SDL_PixelFormatEnum value of the desired format of the + * pixel data, or 0 to use the format of the rendering target + * \param pixels a pointer to the pixel data to copy into + * \param pitch the pitch of the `pixels` parameter + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC int SDLCALL SDL_RenderReadPixels(SDL_Renderer * renderer, + const SDL_Rect * rect, + Uint32 format, + void *pixels, int pitch); + +/** + * Update the screen with any rendering performed since the previous call. + * + * SDL's rendering functions operate on a backbuffer; that is, calling a + * rendering function such as SDL_RenderDrawLine() does not directly put a + * line on the screen, but rather updates the backbuffer. As such, you compose + * your entire scene and *present* the composed backbuffer to the screen as a + * complete picture. + * + * Therefore, when using SDL's rendering API, one does all drawing intended + * for the frame, and then calls this function once per frame to present the + * final drawing to the user. + * + * The backbuffer should be considered invalidated after each present; do not + * assume that previous contents will exist between frames. You are strongly + * encouraged to call SDL_RenderClear() to initialize the backbuffer before + * starting each new frame's drawing, even if you plan to overwrite every + * pixel. + * + * \param renderer the rendering context + * + * \threadsafety You may only call this function on the main thread. If this + * happens to work on a background thread on any given platform + * or backend, it's purely by luck and you should not rely on it + * to work next time. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RenderClear + * \sa SDL_RenderDrawLine + * \sa SDL_RenderDrawLines + * \sa SDL_RenderDrawPoint + * \sa SDL_RenderDrawPoints + * \sa SDL_RenderDrawRect + * \sa SDL_RenderDrawRects + * \sa SDL_RenderFillRect + * \sa SDL_RenderFillRects + * \sa SDL_SetRenderDrawBlendMode + * \sa SDL_SetRenderDrawColor + */ +extern DECLSPEC void SDLCALL SDL_RenderPresent(SDL_Renderer * renderer); + +/** + * Destroy the specified texture. + * + * Passing NULL or an otherwise invalid texture will set the SDL error message + * to "Invalid texture". + * + * \param texture the texture to destroy + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateTexture + * \sa SDL_CreateTextureFromSurface + */ +extern DECLSPEC void SDLCALL SDL_DestroyTexture(SDL_Texture * texture); + +/** + * Destroy the rendering context for a window and free associated textures. + * + * If `renderer` is NULL, this function will return immediately after setting + * the SDL error message to "Invalid renderer". See SDL_GetError(). + * + * \param renderer the rendering context + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateRenderer + */ +extern DECLSPEC void SDLCALL SDL_DestroyRenderer(SDL_Renderer * renderer); + +/** + * Force the rendering context to flush any pending commands to the underlying + * rendering API. + * + * You do not need to (and in fact, shouldn't) call this function unless you + * are planning to call into OpenGL/Direct3D/Metal/whatever directly in + * addition to using an SDL_Renderer. + * + * This is for a very-specific case: if you are using SDL's render API, you + * asked for a specific renderer backend (OpenGL, Direct3D, etc), you set + * SDL_HINT_RENDER_BATCHING to "1", and you plan to make OpenGL/D3D/whatever + * calls in addition to SDL render API calls. If all of this applies, you + * should call SDL_RenderFlush() between calls to SDL's render API and the + * low-level API you're using in cooperation. + * + * In all other cases, you can ignore this function. This is only here to get + * maximum performance out of a specific situation. In all other cases, SDL + * will do the right thing, perhaps at a performance loss. + * + * This function is first available in SDL 2.0.10, and is not needed in 2.0.9 + * and earlier, as earlier versions did not queue rendering commands at all, + * instead flushing them to the OS immediately. + * + * \param renderer the rendering context + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC int SDLCALL SDL_RenderFlush(SDL_Renderer * renderer); + + +/** + * Bind an OpenGL/ES/ES2 texture to the current context. + * + * This is for use with OpenGL instructions when rendering OpenGL primitives + * directly. + * + * If not NULL, `texw` and `texh` will be filled with the width and height + * values suitable for the provided texture. In most cases, both will be 1.0, + * however, on systems that support the GL_ARB_texture_rectangle extension, + * these values will actually be the pixel width and height used to create the + * texture, so this factor needs to be taken into account when providing + * texture coordinates to OpenGL. + * + * You need a renderer to create an SDL_Texture, therefore you can only use + * this function with an implicit OpenGL context from SDL_CreateRenderer(), + * not with your own OpenGL context. If you need control over your OpenGL + * context, you need to write your own texture-loading methods. + * + * Also note that SDL may upload RGB textures as BGR (or vice-versa), and + * re-order the color channels in the shaders phase, so the uploaded texture + * may have swapped color channels. + * + * \param texture the texture to bind to the current OpenGL/ES/ES2 context + * \param texw a pointer to a float value which will be filled with the + * texture width or NULL if you don't need that value + * \param texh a pointer to a float value which will be filled with the + * texture height or NULL if you don't need that value + * \returns 0 on success, or -1 if the operation is not supported; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GL_MakeCurrent + * \sa SDL_GL_UnbindTexture + */ +extern DECLSPEC int SDLCALL SDL_GL_BindTexture(SDL_Texture *texture, float *texw, float *texh); + +/** + * Unbind an OpenGL/ES/ES2 texture from the current context. + * + * See SDL_GL_BindTexture() for examples on how to use these functions + * + * \param texture the texture to unbind from the current OpenGL/ES/ES2 context + * \returns 0 on success, or -1 if the operation is not supported + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GL_BindTexture + * \sa SDL_GL_MakeCurrent + */ +extern DECLSPEC int SDLCALL SDL_GL_UnbindTexture(SDL_Texture *texture); + +/** + * Get the CAMetalLayer associated with the given Metal renderer. + * + * This function returns `void *`, so SDL doesn't have to include Metal's + * headers, but it can be safely cast to a `CAMetalLayer *`. + * + * \param renderer The renderer to query + * \returns a `CAMetalLayer *` on success, or NULL if the renderer isn't a + * Metal renderer + * + * \since This function is available since SDL 2.0.8. + * + * \sa SDL_RenderGetMetalCommandEncoder + */ +extern DECLSPEC void *SDLCALL SDL_RenderGetMetalLayer(SDL_Renderer * renderer); + +/** + * Get the Metal command encoder for the current frame + * + * This function returns `void *`, so SDL doesn't have to include Metal's + * headers, but it can be safely cast to an `id`. + * + * Note that as of SDL 2.0.18, this will return NULL if Metal refuses to give + * SDL a drawable to render to, which might happen if the window is + * hidden/minimized/offscreen. This doesn't apply to command encoders for + * render targets, just the window's backbuffer. Check your return values! + * + * \param renderer The renderer to query + * \returns an `id` on success, or NULL if the + * renderer isn't a Metal renderer or there was an error. + * + * \since This function is available since SDL 2.0.8. + * + * \sa SDL_RenderGetMetalLayer + */ +extern DECLSPEC void *SDLCALL SDL_RenderGetMetalCommandEncoder(SDL_Renderer * renderer); + +/** + * Toggle VSync of the given renderer. + * + * \param renderer The renderer to toggle + * \param vsync 1 for on, 0 for off. All other values are reserved + * \returns a 0 int on success, or non-zero on failure + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC int SDLCALL SDL_RenderSetVSync(SDL_Renderer* renderer, int vsync); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_render_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/include/SDL_revision.h b/SDL2-2.30.5/include/SDL_revision.h new file mode 100644 index 0000000..bede229 --- /dev/null +++ b/SDL2-2.30.5/include/SDL_revision.h @@ -0,0 +1,7 @@ +/* Generated by updaterev.sh, do not edit */ +#ifdef SDL_VENDOR_INFO +#define SDL_REVISION "SDL-release-2.30.5-0-g2eef7ca47 (" SDL_VENDOR_INFO ")" +#else +#define SDL_REVISION "SDL-release-2.30.5-0-g2eef7ca47" +#endif +#define SDL_REVISION_NUMBER 0 diff --git a/SDL2-2.30.5/include/SDL_rwops.h b/SDL2-2.30.5/include/SDL_rwops.h new file mode 100644 index 0000000..9dd99f9 --- /dev/null +++ b/SDL2-2.30.5/include/SDL_rwops.h @@ -0,0 +1,841 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_rwops.h + * + * This file provides a general interface for SDL to read and write + * data streams. It can easily be extended to files, memory, etc. + */ + +#ifndef SDL_rwops_h_ +#define SDL_rwops_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* RWops Types */ +#define SDL_RWOPS_UNKNOWN 0U /**< Unknown stream type */ +#define SDL_RWOPS_WINFILE 1U /**< Win32 file */ +#define SDL_RWOPS_STDFILE 2U /**< Stdio file */ +#define SDL_RWOPS_JNIFILE 3U /**< Android asset */ +#define SDL_RWOPS_MEMORY 4U /**< Memory stream */ +#define SDL_RWOPS_MEMORY_RO 5U /**< Read-Only memory stream */ + +/** + * This is the read/write operation structure -- very basic. + */ +typedef struct SDL_RWops +{ + /** + * Return the size of the file in this rwops, or -1 if unknown + */ + Sint64 (SDLCALL * size) (struct SDL_RWops * context); + + /** + * Seek to \c offset relative to \c whence, one of stdio's whence values: + * RW_SEEK_SET, RW_SEEK_CUR, RW_SEEK_END + * + * \return the final offset in the data stream, or -1 on error. + */ + Sint64 (SDLCALL * seek) (struct SDL_RWops * context, Sint64 offset, + int whence); + + /** + * Read up to \c maxnum objects each of size \c size from the data + * stream to the area pointed at by \c ptr. + * + * \return the number of objects read, or 0 at error or end of file. + */ + size_t (SDLCALL * read) (struct SDL_RWops * context, void *ptr, + size_t size, size_t maxnum); + + /** + * Write exactly \c num objects each of size \c size from the area + * pointed at by \c ptr to data stream. + * + * \return the number of objects written, or 0 at error or end of file. + */ + size_t (SDLCALL * write) (struct SDL_RWops * context, const void *ptr, + size_t size, size_t num); + + /** + * Close and free an allocated SDL_RWops structure. + * + * \return 0 if successful or -1 on write error when flushing data. + */ + int (SDLCALL * close) (struct SDL_RWops * context); + + Uint32 type; + union + { +#if defined(__ANDROID__) + struct + { + void *asset; + } androidio; +#elif defined(__WIN32__) || defined(__GDK__) + struct + { + SDL_bool append; + void *h; + struct + { + void *data; + size_t size; + size_t left; + } buffer; + } windowsio; +#endif + +#ifdef HAVE_STDIO_H + struct + { + SDL_bool autoclose; + FILE *fp; + } stdio; +#endif + struct + { + Uint8 *base; + Uint8 *here; + Uint8 *stop; + } mem; + struct + { + void *data1; + void *data2; + } unknown; + } hidden; + +} SDL_RWops; + + +/** + * \name RWFrom functions + * + * Functions to create SDL_RWops structures from various data streams. + */ +/* @{ */ + +/** + * Use this function to create a new SDL_RWops structure for reading from + * and/or writing to a named file. + * + * The `mode` string is treated roughly the same as in a call to the C + * library's fopen(), even if SDL doesn't happen to use fopen() behind the + * scenes. + * + * Available `mode` strings: + * + * - "r": Open a file for reading. The file must exist. + * - "w": Create an empty file for writing. If a file with the same name + * already exists its content is erased and the file is treated as a new + * empty file. + * - "a": Append to a file. Writing operations append data at the end of the + * file. The file is created if it does not exist. + * - "r+": Open a file for update both reading and writing. The file must + * exist. + * - "w+": Create an empty file for both reading and writing. If a file with + * the same name already exists its content is erased and the file is + * treated as a new empty file. + * - "a+": Open a file for reading and appending. All writing operations are + * performed at the end of the file, protecting the previous content to be + * overwritten. You can reposition (fseek, rewind) the internal pointer to + * anywhere in the file for reading, but writing operations will move it + * back to the end of file. The file is created if it does not exist. + * + * **NOTE**: In order to open a file as a binary file, a "b" character has to + * be included in the `mode` string. This additional "b" character can either + * be appended at the end of the string (thus making the following compound + * modes: "rb", "wb", "ab", "r+b", "w+b", "a+b") or be inserted between the + * letter and the "+" sign for the mixed modes ("rb+", "wb+", "ab+"). + * Additional characters may follow the sequence, although they should have no + * effect. For example, "t" is sometimes appended to make explicit the file is + * a text file. + * + * This function supports Unicode filenames, but they must be encoded in UTF-8 + * format, regardless of the underlying operating system. + * + * As a fallback, SDL_RWFromFile() will transparently open a matching filename + * in an Android app's `assets`. + * + * Closing the SDL_RWops will close the file handle SDL is holding internally. + * + * \param file a UTF-8 string representing the filename to open + * \param mode an ASCII string representing the mode to be used for opening + * the file. + * \returns a pointer to the SDL_RWops structure that is created, or NULL on + * failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RWclose + * \sa SDL_RWFromConstMem + * \sa SDL_RWFromFP + * \sa SDL_RWFromMem + * \sa SDL_RWread + * \sa SDL_RWseek + * \sa SDL_RWtell + * \sa SDL_RWwrite + */ +extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromFile(const char *file, + const char *mode); + +#ifdef HAVE_STDIO_H + +extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromFP(FILE * fp, SDL_bool autoclose); + +#else + +/** + * Use this function to create an SDL_RWops structure from a standard I/O file + * pointer (stdio.h's `FILE*`). + * + * This function is not available on Windows, since files opened in an + * application on that platform cannot be used by a dynamically linked + * library. + * + * On some platforms, the first parameter is a `void*`, on others, it's a + * `FILE*`, depending on what system headers are available to SDL. It is + * always intended to be the `FILE*` type from the C runtime's stdio.h. + * + * \param fp the `FILE*` that feeds the SDL_RWops stream + * \param autoclose SDL_TRUE to close the `FILE*` when closing the SDL_RWops, + * SDL_FALSE to leave the `FILE*` open when the RWops is + * closed + * \returns a pointer to the SDL_RWops structure that is created, or NULL on + * failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RWclose + * \sa SDL_RWFromConstMem + * \sa SDL_RWFromFile + * \sa SDL_RWFromMem + * \sa SDL_RWread + * \sa SDL_RWseek + * \sa SDL_RWtell + * \sa SDL_RWwrite + */ +extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromFP(void * fp, + SDL_bool autoclose); +#endif + +/** + * Use this function to prepare a read-write memory buffer for use with + * SDL_RWops. + * + * This function sets up an SDL_RWops struct based on a memory area of a + * certain size, for both read and write access. + * + * This memory buffer is not copied by the RWops; the pointer you provide must + * remain valid until you close the stream. Closing the stream will not free + * the original buffer. + * + * If you need to make sure the RWops never writes to the memory buffer, you + * should use SDL_RWFromConstMem() with a read-only buffer of memory instead. + * + * \param mem a pointer to a buffer to feed an SDL_RWops stream + * \param size the buffer size, in bytes + * \returns a pointer to a new SDL_RWops structure, or NULL if it fails; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RWclose + * \sa SDL_RWFromConstMem + * \sa SDL_RWFromFile + * \sa SDL_RWFromFP + * \sa SDL_RWFromMem + * \sa SDL_RWread + * \sa SDL_RWseek + * \sa SDL_RWtell + * \sa SDL_RWwrite + */ +extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromMem(void *mem, int size); + +/** + * Use this function to prepare a read-only memory buffer for use with RWops. + * + * This function sets up an SDL_RWops struct based on a memory area of a + * certain size. It assumes the memory area is not writable. + * + * Attempting to write to this RWops stream will report an error without + * writing to the memory buffer. + * + * This memory buffer is not copied by the RWops; the pointer you provide must + * remain valid until you close the stream. Closing the stream will not free + * the original buffer. + * + * If you need to write to a memory buffer, you should use SDL_RWFromMem() + * with a writable buffer of memory instead. + * + * \param mem a pointer to a read-only buffer to feed an SDL_RWops stream + * \param size the buffer size, in bytes + * \returns a pointer to a new SDL_RWops structure, or NULL if it fails; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RWclose + * \sa SDL_RWFromConstMem + * \sa SDL_RWFromFile + * \sa SDL_RWFromFP + * \sa SDL_RWFromMem + * \sa SDL_RWread + * \sa SDL_RWseek + * \sa SDL_RWtell + */ +extern DECLSPEC SDL_RWops *SDLCALL SDL_RWFromConstMem(const void *mem, + int size); + +/* @} *//* RWFrom functions */ + + +/** + * Use this function to allocate an empty, unpopulated SDL_RWops structure. + * + * Applications do not need to use this function unless they are providing + * their own SDL_RWops implementation. If you just need a SDL_RWops to + * read/write a common data source, you should use the built-in + * implementations in SDL, like SDL_RWFromFile() or SDL_RWFromMem(), etc. + * + * You must free the returned pointer with SDL_FreeRW(). Depending on your + * operating system and compiler, there may be a difference between the + * malloc() and free() your program uses and the versions SDL calls + * internally. Trying to mix the two can cause crashing such as segmentation + * faults. Since all SDL_RWops must free themselves when their **close** + * method is called, all SDL_RWops must be allocated through this function, so + * they can all be freed correctly with SDL_FreeRW(). + * + * \returns a pointer to the allocated memory on success, or NULL on failure; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_FreeRW + */ +extern DECLSPEC SDL_RWops *SDLCALL SDL_AllocRW(void); + +/** + * Use this function to free an SDL_RWops structure allocated by + * SDL_AllocRW(). + * + * Applications do not need to use this function unless they are providing + * their own SDL_RWops implementation. If you just need a SDL_RWops to + * read/write a common data source, you should use the built-in + * implementations in SDL, like SDL_RWFromFile() or SDL_RWFromMem(), etc, and + * call the **close** method on those SDL_RWops pointers when you are done + * with them. + * + * Only use SDL_FreeRW() on pointers returned by SDL_AllocRW(). The pointer is + * invalid as soon as this function returns. Any extra memory allocated during + * creation of the SDL_RWops is not freed by SDL_FreeRW(); the programmer must + * be responsible for managing that memory in their **close** method. + * + * \param area the SDL_RWops structure to be freed + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AllocRW + */ +extern DECLSPEC void SDLCALL SDL_FreeRW(SDL_RWops * area); + +#define RW_SEEK_SET 0 /**< Seek from the beginning of data */ +#define RW_SEEK_CUR 1 /**< Seek relative to current read point */ +#define RW_SEEK_END 2 /**< Seek relative to the end of data */ + +/** + * Use this function to get the size of the data stream in an SDL_RWops. + * + * Prior to SDL 2.0.10, this function was a macro. + * + * \param context the SDL_RWops to get the size of the data stream from + * \returns the size of the data stream in the SDL_RWops on success, -1 if + * unknown or a negative error code on failure; call SDL_GetError() + * for more information. + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC Sint64 SDLCALL SDL_RWsize(SDL_RWops *context); + +/** + * Seek within an SDL_RWops data stream. + * + * This function seeks to byte `offset`, relative to `whence`. + * + * `whence` may be any of the following values: + * + * - `RW_SEEK_SET`: seek from the beginning of data + * - `RW_SEEK_CUR`: seek relative to current read point + * - `RW_SEEK_END`: seek relative to the end of data + * + * If this stream can not seek, it will return -1. + * + * SDL_RWseek() is actually a wrapper function that calls the SDL_RWops's + * `seek` method appropriately, to simplify application development. + * + * Prior to SDL 2.0.10, this function was a macro. + * + * \param context a pointer to an SDL_RWops structure + * \param offset an offset in bytes, relative to **whence** location; can be + * negative + * \param whence any of `RW_SEEK_SET`, `RW_SEEK_CUR`, `RW_SEEK_END` + * \returns the final offset in the data stream after the seek or -1 on error. + * + * \since This function is available since SDL 2.0.10. + * + * \sa SDL_RWclose + * \sa SDL_RWFromConstMem + * \sa SDL_RWFromFile + * \sa SDL_RWFromFP + * \sa SDL_RWFromMem + * \sa SDL_RWread + * \sa SDL_RWtell + * \sa SDL_RWwrite + */ +extern DECLSPEC Sint64 SDLCALL SDL_RWseek(SDL_RWops *context, + Sint64 offset, int whence); + +/** + * Determine the current read/write offset in an SDL_RWops data stream. + * + * SDL_RWtell is actually a wrapper function that calls the SDL_RWops's `seek` + * method, with an offset of 0 bytes from `RW_SEEK_CUR`, to simplify + * application development. + * + * Prior to SDL 2.0.10, this function was a macro. + * + * \param context a SDL_RWops data stream object from which to get the current + * offset + * \returns the current offset in the stream, or -1 if the information can not + * be determined. + * + * \since This function is available since SDL 2.0.10. + * + * \sa SDL_RWclose + * \sa SDL_RWFromConstMem + * \sa SDL_RWFromFile + * \sa SDL_RWFromFP + * \sa SDL_RWFromMem + * \sa SDL_RWread + * \sa SDL_RWseek + * \sa SDL_RWwrite + */ +extern DECLSPEC Sint64 SDLCALL SDL_RWtell(SDL_RWops *context); + +/** + * Read from a data source. + * + * This function reads up to `maxnum` objects each of size `size` from the + * data source to the area pointed at by `ptr`. This function may read less + * objects than requested. It will return zero when there has been an error or + * the data stream is completely read. + * + * SDL_RWread() is actually a function wrapper that calls the SDL_RWops's + * `read` method appropriately, to simplify application development. + * + * Prior to SDL 2.0.10, this function was a macro. + * + * \param context a pointer to an SDL_RWops structure + * \param ptr a pointer to a buffer to read data into + * \param size the size of each object to read, in bytes + * \param maxnum the maximum number of objects to be read + * \returns the number of objects read, or 0 at error or end of file; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.10. + * + * \sa SDL_RWclose + * \sa SDL_RWFromConstMem + * \sa SDL_RWFromFile + * \sa SDL_RWFromFP + * \sa SDL_RWFromMem + * \sa SDL_RWseek + * \sa SDL_RWwrite + */ +extern DECLSPEC size_t SDLCALL SDL_RWread(SDL_RWops *context, + void *ptr, size_t size, + size_t maxnum); + +/** + * Write to an SDL_RWops data stream. + * + * This function writes exactly `num` objects each of size `size` from the + * area pointed at by `ptr` to the stream. If this fails for any reason, it'll + * return less than `num` to demonstrate how far the write progressed. On + * success, it returns `num`. + * + * SDL_RWwrite is actually a function wrapper that calls the SDL_RWops's + * `write` method appropriately, to simplify application development. + * + * Prior to SDL 2.0.10, this function was a macro. + * + * \param context a pointer to an SDL_RWops structure + * \param ptr a pointer to a buffer containing data to write + * \param size the size of an object to write, in bytes + * \param num the number of objects to write + * \returns the number of objects written, which will be less than **num** on + * error; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.10. + * + * \sa SDL_RWclose + * \sa SDL_RWFromConstMem + * \sa SDL_RWFromFile + * \sa SDL_RWFromFP + * \sa SDL_RWFromMem + * \sa SDL_RWread + * \sa SDL_RWseek + */ +extern DECLSPEC size_t SDLCALL SDL_RWwrite(SDL_RWops *context, + const void *ptr, size_t size, + size_t num); + +/** + * Close and free an allocated SDL_RWops structure. + * + * SDL_RWclose() closes and cleans up the SDL_RWops stream. It releases any + * resources used by the stream and frees the SDL_RWops itself with + * SDL_FreeRW(). This returns 0 on success, or -1 if the stream failed to + * flush to its output (e.g. to disk). + * + * Note that if this fails to flush the stream to disk, this function reports + * an error, but the SDL_RWops is still invalid once this function returns. + * + * Prior to SDL 2.0.10, this function was a macro. + * + * \param context SDL_RWops structure to close + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.10. + * + * \sa SDL_RWFromConstMem + * \sa SDL_RWFromFile + * \sa SDL_RWFromFP + * \sa SDL_RWFromMem + * \sa SDL_RWread + * \sa SDL_RWseek + * \sa SDL_RWwrite + */ +extern DECLSPEC int SDLCALL SDL_RWclose(SDL_RWops *context); + +/** + * Load all the data from an SDL data stream. + * + * The data is allocated with a zero byte at the end (null terminated) for + * convenience. This extra byte is not included in the value reported via + * `datasize`. + * + * The data should be freed with SDL_free(). + * + * \param src the SDL_RWops to read all available data from + * \param datasize if not NULL, will store the number of bytes read + * \param freesrc if non-zero, calls SDL_RWclose() on `src` before returning + * \returns the data, or NULL if there was an error. + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC void *SDLCALL SDL_LoadFile_RW(SDL_RWops *src, + size_t *datasize, + int freesrc); + +/** + * Load all the data from a file path. + * + * The data is allocated with a zero byte at the end (null terminated) for + * convenience. This extra byte is not included in the value reported via + * `datasize`. + * + * The data should be freed with SDL_free(). + * + * Prior to SDL 2.0.10, this function was a macro wrapping around + * SDL_LoadFile_RW. + * + * \param file the path to read all available data from + * \param datasize if not NULL, will store the number of bytes read + * \returns the data, or NULL if there was an error. + * + * \since This function is available since SDL 2.0.10. + */ +extern DECLSPEC void *SDLCALL SDL_LoadFile(const char *file, size_t *datasize); + +/** + * \name Read endian functions + * + * Read an item of the specified endianness and return in native format. + */ +/* @{ */ + +/** + * Use this function to read a byte from an SDL_RWops. + * + * \param src the SDL_RWops to read from + * \returns the read byte on success or 0 on failure; call SDL_GetError() for + * more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_WriteU8 + */ +extern DECLSPEC Uint8 SDLCALL SDL_ReadU8(SDL_RWops * src); + +/** + * Use this function to read 16 bits of little-endian data from an SDL_RWops + * and return in native format. + * + * SDL byteswaps the data only if necessary, so the data returned will be in + * the native byte order. + * + * \param src the stream from which to read data + * \returns 16 bits of data in the native byte order of the platform. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ReadBE16 + */ +extern DECLSPEC Uint16 SDLCALL SDL_ReadLE16(SDL_RWops * src); + +/** + * Use this function to read 16 bits of big-endian data from an SDL_RWops and + * return in native format. + * + * SDL byteswaps the data only if necessary, so the data returned will be in + * the native byte order. + * + * \param src the stream from which to read data + * \returns 16 bits of data in the native byte order of the platform. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ReadLE16 + */ +extern DECLSPEC Uint16 SDLCALL SDL_ReadBE16(SDL_RWops * src); + +/** + * Use this function to read 32 bits of little-endian data from an SDL_RWops + * and return in native format. + * + * SDL byteswaps the data only if necessary, so the data returned will be in + * the native byte order. + * + * \param src the stream from which to read data + * \returns 32 bits of data in the native byte order of the platform. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ReadBE32 + */ +extern DECLSPEC Uint32 SDLCALL SDL_ReadLE32(SDL_RWops * src); + +/** + * Use this function to read 32 bits of big-endian data from an SDL_RWops and + * return in native format. + * + * SDL byteswaps the data only if necessary, so the data returned will be in + * the native byte order. + * + * \param src the stream from which to read data + * \returns 32 bits of data in the native byte order of the platform. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ReadLE32 + */ +extern DECLSPEC Uint32 SDLCALL SDL_ReadBE32(SDL_RWops * src); + +/** + * Use this function to read 64 bits of little-endian data from an SDL_RWops + * and return in native format. + * + * SDL byteswaps the data only if necessary, so the data returned will be in + * the native byte order. + * + * \param src the stream from which to read data + * \returns 64 bits of data in the native byte order of the platform. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ReadBE64 + */ +extern DECLSPEC Uint64 SDLCALL SDL_ReadLE64(SDL_RWops * src); + +/** + * Use this function to read 64 bits of big-endian data from an SDL_RWops and + * return in native format. + * + * SDL byteswaps the data only if necessary, so the data returned will be in + * the native byte order. + * + * \param src the stream from which to read data + * \returns 64 bits of data in the native byte order of the platform. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ReadLE64 + */ +extern DECLSPEC Uint64 SDLCALL SDL_ReadBE64(SDL_RWops * src); +/* @} *//* Read endian functions */ + +/** + * \name Write endian functions + * + * Write an item of native format to the specified endianness. + */ +/* @{ */ + +/** + * Use this function to write a byte to an SDL_RWops. + * + * \param dst the SDL_RWops to write to + * \param value the byte value to write + * \returns 1 on success or 0 on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ReadU8 + */ +extern DECLSPEC size_t SDLCALL SDL_WriteU8(SDL_RWops * dst, Uint8 value); + +/** + * Use this function to write 16 bits in native format to a SDL_RWops as + * little-endian data. + * + * SDL byteswaps the data only if necessary, so the application always + * specifies native format, and the data written will be in little-endian + * format. + * + * \param dst the stream to which data will be written + * \param value the data to be written, in native format + * \returns 1 on successful write, 0 on error. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_WriteBE16 + */ +extern DECLSPEC size_t SDLCALL SDL_WriteLE16(SDL_RWops * dst, Uint16 value); + +/** + * Use this function to write 16 bits in native format to a SDL_RWops as + * big-endian data. + * + * SDL byteswaps the data only if necessary, so the application always + * specifies native format, and the data written will be in big-endian format. + * + * \param dst the stream to which data will be written + * \param value the data to be written, in native format + * \returns 1 on successful write, 0 on error. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_WriteLE16 + */ +extern DECLSPEC size_t SDLCALL SDL_WriteBE16(SDL_RWops * dst, Uint16 value); + +/** + * Use this function to write 32 bits in native format to a SDL_RWops as + * little-endian data. + * + * SDL byteswaps the data only if necessary, so the application always + * specifies native format, and the data written will be in little-endian + * format. + * + * \param dst the stream to which data will be written + * \param value the data to be written, in native format + * \returns 1 on successful write, 0 on error. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_WriteBE32 + */ +extern DECLSPEC size_t SDLCALL SDL_WriteLE32(SDL_RWops * dst, Uint32 value); + +/** + * Use this function to write 32 bits in native format to a SDL_RWops as + * big-endian data. + * + * SDL byteswaps the data only if necessary, so the application always + * specifies native format, and the data written will be in big-endian format. + * + * \param dst the stream to which data will be written + * \param value the data to be written, in native format + * \returns 1 on successful write, 0 on error. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_WriteLE32 + */ +extern DECLSPEC size_t SDLCALL SDL_WriteBE32(SDL_RWops * dst, Uint32 value); + +/** + * Use this function to write 64 bits in native format to a SDL_RWops as + * little-endian data. + * + * SDL byteswaps the data only if necessary, so the application always + * specifies native format, and the data written will be in little-endian + * format. + * + * \param dst the stream to which data will be written + * \param value the data to be written, in native format + * \returns 1 on successful write, 0 on error. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_WriteBE64 + */ +extern DECLSPEC size_t SDLCALL SDL_WriteLE64(SDL_RWops * dst, Uint64 value); + +/** + * Use this function to write 64 bits in native format to a SDL_RWops as + * big-endian data. + * + * SDL byteswaps the data only if necessary, so the application always + * specifies native format, and the data written will be in big-endian format. + * + * \param dst the stream to which data will be written + * \param value the data to be written, in native format + * \returns 1 on successful write, 0 on error. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_WriteLE64 + */ +extern DECLSPEC size_t SDLCALL SDL_WriteBE64(SDL_RWops * dst, Uint64 value); +/* @} *//* Write endian functions */ + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_rwops_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/include/SDL_scancode.h b/SDL2-2.30.5/include/SDL_scancode.h similarity index 85% rename from SDL2-2.0.12/include/SDL_scancode.h rename to SDL2-2.30.5/include/SDL_scancode.h index b19197d..fe13d5b 100644 --- a/SDL2-2.0.12/include/SDL_scancode.h +++ b/SDL2-2.30.5/include/SDL_scancode.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -225,16 +225,16 @@ typedef enum SDL_SCANCODE_F23 = 114, SDL_SCANCODE_F24 = 115, SDL_SCANCODE_EXECUTE = 116, - SDL_SCANCODE_HELP = 117, - SDL_SCANCODE_MENU = 118, + SDL_SCANCODE_HELP = 117, /**< AL Integrated Help Center */ + SDL_SCANCODE_MENU = 118, /**< Menu (show menu) */ SDL_SCANCODE_SELECT = 119, - SDL_SCANCODE_STOP = 120, - SDL_SCANCODE_AGAIN = 121, /**< redo */ - SDL_SCANCODE_UNDO = 122, - SDL_SCANCODE_CUT = 123, - SDL_SCANCODE_COPY = 124, - SDL_SCANCODE_PASTE = 125, - SDL_SCANCODE_FIND = 126, + SDL_SCANCODE_STOP = 120, /**< AC Stop */ + SDL_SCANCODE_AGAIN = 121, /**< AC Redo/Repeat */ + SDL_SCANCODE_UNDO = 122, /**< AC Undo */ + SDL_SCANCODE_CUT = 123, /**< AC Cut */ + SDL_SCANCODE_COPY = 124, /**< AC Copy */ + SDL_SCANCODE_PASTE = 125, /**< AC Paste */ + SDL_SCANCODE_FIND = 126, /**< AC Find */ SDL_SCANCODE_MUTE = 127, SDL_SCANCODE_VOLUMEUP = 128, SDL_SCANCODE_VOLUMEDOWN = 129, @@ -265,9 +265,9 @@ typedef enum SDL_SCANCODE_LANG8 = 151, /**< reserved */ SDL_SCANCODE_LANG9 = 152, /**< reserved */ - SDL_SCANCODE_ALTERASE = 153, /**< Erase-Eaze */ + SDL_SCANCODE_ALTERASE = 153, /**< Erase-Eaze */ SDL_SCANCODE_SYSREQ = 154, - SDL_SCANCODE_CANCEL = 155, + SDL_SCANCODE_CANCEL = 155, /**< AC Cancel */ SDL_SCANCODE_CLEAR = 156, SDL_SCANCODE_PRIOR = 157, SDL_SCANCODE_RETURN2 = 158, @@ -345,6 +345,11 @@ typedef enum * \name Usage page 0x0C * * These values are mapped from usage page 0x0C (USB consumer page). + * See https://usb.org/sites/default/files/hut1_2.pdf + * + * There are way more keys in the spec than we can represent in the + * current scancode range, so pick the ones that commonly come up in + * real world usage. */ /* @{ */ @@ -354,17 +359,17 @@ typedef enum SDL_SCANCODE_AUDIOPLAY = 261, SDL_SCANCODE_AUDIOMUTE = 262, SDL_SCANCODE_MEDIASELECT = 263, - SDL_SCANCODE_WWW = 264, + SDL_SCANCODE_WWW = 264, /**< AL Internet Browser */ SDL_SCANCODE_MAIL = 265, - SDL_SCANCODE_CALCULATOR = 266, + SDL_SCANCODE_CALCULATOR = 266, /**< AL Calculator */ SDL_SCANCODE_COMPUTER = 267, - SDL_SCANCODE_AC_SEARCH = 268, - SDL_SCANCODE_AC_HOME = 269, - SDL_SCANCODE_AC_BACK = 270, - SDL_SCANCODE_AC_FORWARD = 271, - SDL_SCANCODE_AC_STOP = 272, - SDL_SCANCODE_AC_REFRESH = 273, - SDL_SCANCODE_AC_BOOKMARKS = 274, + SDL_SCANCODE_AC_SEARCH = 268, /**< AC Search */ + SDL_SCANCODE_AC_HOME = 269, /**< AC Home */ + SDL_SCANCODE_AC_BACK = 270, /**< AC Back */ + SDL_SCANCODE_AC_FORWARD = 271, /**< AC Forward */ + SDL_SCANCODE_AC_STOP = 272, /**< AC Stop */ + SDL_SCANCODE_AC_REFRESH = 273, /**< AC Refresh */ + SDL_SCANCODE_AC_BOOKMARKS = 274, /**< AC Bookmarks */ /* @} *//* Usage page 0x0C */ @@ -383,7 +388,7 @@ typedef enum SDL_SCANCODE_KBDILLUMDOWN = 279, SDL_SCANCODE_KBDILLUMUP = 280, SDL_SCANCODE_EJECT = 281, - SDL_SCANCODE_SLEEP = 282, + SDL_SCANCODE_SLEEP = 282, /**< SC System Sleep */ SDL_SCANCODE_APP1 = 283, SDL_SCANCODE_APP2 = 284, @@ -402,6 +407,26 @@ typedef enum /* @} *//* Usage page 0x0C (additional media keys) */ + /** + * \name Mobile keys + * + * These are values that are often used on mobile phones. + */ + /* @{ */ + + SDL_SCANCODE_SOFTLEFT = 287, /**< Usually situated below the display on phones and + used as a multi-function feature key for selecting + a software defined function shown on the bottom left + of the display. */ + SDL_SCANCODE_SOFTRIGHT = 288, /**< Usually situated below the display on phones and + used as a multi-function feature key for selecting + a software defined function shown on the bottom right + of the display. */ + SDL_SCANCODE_CALL = 289, /**< Used for accepting phone calls. */ + SDL_SCANCODE_ENDCALL = 290, /**< Used for rejecting phone calls. */ + + /* @} *//* Mobile keys */ + /* Add any other keys here. */ SDL_NUM_SCANCODES = 512 /**< not a key, just marks the number of scancodes diff --git a/SDL2-2.30.5/include/SDL_sensor.h b/SDL2-2.30.5/include/SDL_sensor.h new file mode 100644 index 0000000..8b89ef6 --- /dev/null +++ b/SDL2-2.30.5/include/SDL_sensor.h @@ -0,0 +1,322 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_sensor.h + * + * Include file for SDL sensor event handling + * + */ + +#ifndef SDL_sensor_h_ +#define SDL_sensor_h_ + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C" { +/* *INDENT-ON* */ +#endif + +/** + * \brief SDL_sensor.h + * + * In order to use these functions, SDL_Init() must have been called + * with the ::SDL_INIT_SENSOR flag. This causes SDL to scan the system + * for sensors, and load appropriate drivers. + */ + +struct _SDL_Sensor; +typedef struct _SDL_Sensor SDL_Sensor; + +/** + * This is a unique ID for a sensor for the time it is connected to the system, + * and is never reused for the lifetime of the application. + * + * The ID value starts at 0 and increments from there. The value -1 is an invalid ID. + */ +typedef Sint32 SDL_SensorID; + +/* The different sensors defined by SDL + * + * Additional sensors may be available, using platform dependent semantics. + * + * Hare are the additional Android sensors: + * https://developer.android.com/reference/android/hardware/SensorEvent.html#values + */ +typedef enum +{ + SDL_SENSOR_INVALID = -1, /**< Returned for an invalid sensor */ + SDL_SENSOR_UNKNOWN, /**< Unknown sensor type */ + SDL_SENSOR_ACCEL, /**< Accelerometer */ + SDL_SENSOR_GYRO, /**< Gyroscope */ + SDL_SENSOR_ACCEL_L, /**< Accelerometer for left Joy-Con controller and Wii nunchuk */ + SDL_SENSOR_GYRO_L, /**< Gyroscope for left Joy-Con controller */ + SDL_SENSOR_ACCEL_R, /**< Accelerometer for right Joy-Con controller */ + SDL_SENSOR_GYRO_R /**< Gyroscope for right Joy-Con controller */ +} SDL_SensorType; + +/** + * Accelerometer sensor + * + * The accelerometer returns the current acceleration in SI meters per + * second squared. This measurement includes the force of gravity, so + * a device at rest will have an value of SDL_STANDARD_GRAVITY away + * from the center of the earth, which is a positive Y value. + * + * values[0]: Acceleration on the x axis + * values[1]: Acceleration on the y axis + * values[2]: Acceleration on the z axis + * + * For phones held in portrait mode and game controllers held in front of you, + * the axes are defined as follows: + * -X ... +X : left ... right + * -Y ... +Y : bottom ... top + * -Z ... +Z : farther ... closer + * + * The axis data is not changed when the phone is rotated. + * + * \sa SDL_GetDisplayOrientation() + */ +#define SDL_STANDARD_GRAVITY 9.80665f + +/** + * Gyroscope sensor + * + * The gyroscope returns the current rate of rotation in radians per second. + * The rotation is positive in the counter-clockwise direction. That is, + * an observer looking from a positive location on one of the axes would + * see positive rotation on that axis when it appeared to be rotating + * counter-clockwise. + * + * values[0]: Angular speed around the x axis (pitch) + * values[1]: Angular speed around the y axis (yaw) + * values[2]: Angular speed around the z axis (roll) + * + * For phones held in portrait mode and game controllers held in front of you, + * the axes are defined as follows: + * -X ... +X : left ... right + * -Y ... +Y : bottom ... top + * -Z ... +Z : farther ... closer + * + * The axis data is not changed when the phone or controller is rotated. + * + * \sa SDL_GetDisplayOrientation() + */ + +/* Function prototypes */ + +/** + * Locking for multi-threaded access to the sensor API + * + * If you are using the sensor API or handling events from multiple threads + * you should use these locking functions to protect access to the sensors. + * + * In particular, you are guaranteed that the sensor list won't change, so the + * API functions that take a sensor index will be valid, and sensor events + * will not be delivered. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC void SDLCALL SDL_LockSensors(void); +extern DECLSPEC void SDLCALL SDL_UnlockSensors(void); + +/** + * Count the number of sensors attached to the system right now. + * + * \returns the number of sensors detected. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC int SDLCALL SDL_NumSensors(void); + +/** + * Get the implementation dependent name of a sensor. + * + * \param device_index The sensor to obtain name from + * \returns the sensor name, or NULL if `device_index` is out of range. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC const char *SDLCALL SDL_SensorGetDeviceName(int device_index); + +/** + * Get the type of a sensor. + * + * \param device_index The sensor to get the type from + * \returns the SDL_SensorType, or `SDL_SENSOR_INVALID` if `device_index` is + * out of range. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC SDL_SensorType SDLCALL SDL_SensorGetDeviceType(int device_index); + +/** + * Get the platform dependent type of a sensor. + * + * \param device_index The sensor to check + * \returns the sensor platform dependent type, or -1 if `device_index` is out + * of range. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC int SDLCALL SDL_SensorGetDeviceNonPortableType(int device_index); + +/** + * Get the instance ID of a sensor. + * + * \param device_index The sensor to get instance id from + * \returns the sensor instance ID, or -1 if `device_index` is out of range. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC SDL_SensorID SDLCALL SDL_SensorGetDeviceInstanceID(int device_index); + +/** + * Open a sensor for use. + * + * \param device_index The sensor to open + * \returns an SDL_Sensor sensor object, or NULL if an error occurred. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC SDL_Sensor *SDLCALL SDL_SensorOpen(int device_index); + +/** + * Return the SDL_Sensor associated with an instance id. + * + * \param instance_id The sensor from instance id + * \returns an SDL_Sensor object. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC SDL_Sensor *SDLCALL SDL_SensorFromInstanceID(SDL_SensorID instance_id); + +/** + * Get the implementation dependent name of a sensor + * + * \param sensor The SDL_Sensor object + * \returns the sensor name, or NULL if `sensor` is NULL. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC const char *SDLCALL SDL_SensorGetName(SDL_Sensor *sensor); + +/** + * Get the type of a sensor. + * + * \param sensor The SDL_Sensor object to inspect + * \returns the SDL_SensorType type, or `SDL_SENSOR_INVALID` if `sensor` is + * NULL. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC SDL_SensorType SDLCALL SDL_SensorGetType(SDL_Sensor *sensor); + +/** + * Get the platform dependent type of a sensor. + * + * \param sensor The SDL_Sensor object to inspect + * \returns the sensor platform dependent type, or -1 if `sensor` is NULL. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC int SDLCALL SDL_SensorGetNonPortableType(SDL_Sensor *sensor); + +/** + * Get the instance ID of a sensor. + * + * \param sensor The SDL_Sensor object to inspect + * \returns the sensor instance ID, or -1 if `sensor` is NULL. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC SDL_SensorID SDLCALL SDL_SensorGetInstanceID(SDL_Sensor *sensor); + +/** + * Get the current state of an opened sensor. + * + * The number of values and interpretation of the data is sensor dependent. + * + * \param sensor The SDL_Sensor object to query + * \param data A pointer filled with the current sensor state + * \param num_values The number of values to write to data + * \returns 0 or -1 if an error occurred. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC int SDLCALL SDL_SensorGetData(SDL_Sensor *sensor, float *data, int num_values); + +/** + * Get the current state of an opened sensor with the timestamp of the last + * update. + * + * The number of values and interpretation of the data is sensor dependent. + * + * \param sensor The SDL_Sensor object to query + * \param timestamp A pointer filled with the timestamp in microseconds of the + * current sensor reading if available, or 0 if not + * \param data A pointer filled with the current sensor state + * \param num_values The number of values to write to data + * \returns 0 or -1 if an error occurred. + * + * \since This function is available since SDL 2.26.0. + */ +extern DECLSPEC int SDLCALL SDL_SensorGetDataWithTimestamp(SDL_Sensor *sensor, Uint64 *timestamp, float *data, int num_values); + +/** + * Close a sensor previously opened with SDL_SensorOpen(). + * + * \param sensor The SDL_Sensor object to close + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC void SDLCALL SDL_SensorClose(SDL_Sensor *sensor); + +/** + * Update the current state of the open sensors. + * + * This is called automatically by the event loop if sensor events are + * enabled. + * + * This needs to be called from the thread that initialized the sensor + * subsystem. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC void SDLCALL SDL_SensorUpdate(void); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif +#include "close_code.h" + +#endif /* SDL_sensor_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/include/SDL_shape.h b/SDL2-2.30.5/include/SDL_shape.h similarity index 67% rename from SDL2-2.0.12/include/SDL_shape.h rename to SDL2-2.30.5/include/SDL_shape.h index cbd9deb..4783cf2 100644 --- a/SDL2-2.0.12/include/SDL_shape.h +++ b/SDL2-2.30.5/include/SDL_shape.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -44,33 +44,38 @@ extern "C" { #define SDL_WINDOW_LACKS_SHAPE -3 /** - * \brief Create a window that can be shaped with the specified position, dimensions, and flags. + * Create a window that can be shaped with the specified position, dimensions, + * and flags. * - * \param title The title of the window, in UTF-8 encoding. - * \param x The x position of the window, ::SDL_WINDOWPOS_CENTERED, or - * ::SDL_WINDOWPOS_UNDEFINED. - * \param y The y position of the window, ::SDL_WINDOWPOS_CENTERED, or - * ::SDL_WINDOWPOS_UNDEFINED. - * \param w The width of the window. - * \param h The height of the window. - * \param flags The flags for the window, a mask of SDL_WINDOW_BORDERLESS with any of the following: - * ::SDL_WINDOW_OPENGL, ::SDL_WINDOW_INPUT_GRABBED, - * ::SDL_WINDOW_HIDDEN, ::SDL_WINDOW_RESIZABLE, - * ::SDL_WINDOW_MAXIMIZED, ::SDL_WINDOW_MINIMIZED, - * ::SDL_WINDOW_BORDERLESS is always set, and ::SDL_WINDOW_FULLSCREEN is always unset. + * \param title The title of the window, in UTF-8 encoding. + * \param x The x position of the window, ::SDL_WINDOWPOS_CENTERED, or + * ::SDL_WINDOWPOS_UNDEFINED. + * \param y The y position of the window, ::SDL_WINDOWPOS_CENTERED, or + * ::SDL_WINDOWPOS_UNDEFINED. + * \param w The width of the window. + * \param h The height of the window. + * \param flags The flags for the window, a mask of SDL_WINDOW_BORDERLESS with + * any of the following: ::SDL_WINDOW_OPENGL, + * ::SDL_WINDOW_INPUT_GRABBED, ::SDL_WINDOW_HIDDEN, + * ::SDL_WINDOW_RESIZABLE, ::SDL_WINDOW_MAXIMIZED, + * ::SDL_WINDOW_MINIMIZED, ::SDL_WINDOW_BORDERLESS is always set, + * and ::SDL_WINDOW_FULLSCREEN is always unset. + * \return the window created, or NULL if window creation failed. * - * \return The window created, or NULL if window creation failed. + * \since This function is available since SDL 2.0.0. * - * \sa SDL_DestroyWindow() + * \sa SDL_DestroyWindow */ extern DECLSPEC SDL_Window * SDLCALL SDL_CreateShapedWindow(const char *title,unsigned int x,unsigned int y,unsigned int w,unsigned int h,Uint32 flags); /** - * \brief Return whether the given window is a shaped window. + * Return whether the given window is a shaped window. * * \param window The window to query for being shaped. + * \return SDL_TRUE if the window is a window that can be shaped, SDL_FALSE if + * the window is unshaped or NULL. * - * \return SDL_TRUE if the window is a window that can be shaped, SDL_FALSE if the window is unshaped or NULL. + * \since This function is available since SDL 2.0.0. * * \sa SDL_CreateShapedWindow */ @@ -106,29 +111,35 @@ typedef struct SDL_WindowShapeMode { } SDL_WindowShapeMode; /** - * \brief Set the shape and parameters of a shaped window. + * Set the shape and parameters of a shaped window. * * \param window The shaped window whose parameters should be set. * \param shape A surface encoding the desired shape for the window. * \param shape_mode The parameters to set for the shaped window. + * \return 0 on success, SDL_INVALID_SHAPE_ARGUMENT on an invalid shape + * argument, or SDL_NONSHAPEABLE_WINDOW if the SDL_Window given does + * not reference a valid shaped window. * - * \return 0 on success, SDL_INVALID_SHAPE_ARGUMENT on an invalid shape argument, or SDL_NONSHAPEABLE_WINDOW - * if the SDL_Window given does not reference a valid shaped window. + * \since This function is available since SDL 2.0.0. * * \sa SDL_WindowShapeMode - * \sa SDL_GetShapedWindowMode. + * \sa SDL_GetShapedWindowMode */ extern DECLSPEC int SDLCALL SDL_SetWindowShape(SDL_Window *window,SDL_Surface *shape,SDL_WindowShapeMode *shape_mode); /** - * \brief Get the shape parameters of a shaped window. + * Get the shape parameters of a shaped window. * * \param window The shaped window whose parameters should be retrieved. - * \param shape_mode An empty shape-mode structure to fill, or NULL to check whether the window has a shape. + * \param shape_mode An empty shape-mode structure to fill, or NULL to check + * whether the window has a shape. + * \return 0 if the window has a shape and, provided shape_mode was not NULL, + * shape_mode has been filled with the mode data, + * SDL_NONSHAPEABLE_WINDOW if the SDL_Window given is not a shaped + * window, or SDL_WINDOW_LACKS_SHAPE if the SDL_Window given is a + * shapeable window currently lacking a shape. * - * \return 0 if the window has a shape and, provided shape_mode was not NULL, shape_mode has been filled with the mode - * data, SDL_NONSHAPEABLE_WINDOW if the SDL_Window given is not a shaped window, or SDL_WINDOW_LACKS_SHAPE if - * the SDL_Window given is a shapeable window currently lacking a shape. + * \since This function is available since SDL 2.0.0. * * \sa SDL_WindowShapeMode * \sa SDL_SetWindowShape diff --git a/SDL2-2.0.12/include/SDL_stdinc.h b/SDL2-2.30.5/include/SDL_stdinc.h similarity index 67% rename from SDL2-2.0.12/include/SDL_stdinc.h rename to SDL2-2.30.5/include/SDL_stdinc.h index d96e18b..45e2a78 100644 --- a/SDL2-2.0.12/include/SDL_stdinc.h +++ b/SDL2-2.30.5/include/SDL_stdinc.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -74,12 +74,14 @@ # include #endif #ifdef HAVE_MATH_H -# if defined(__WINRT__) +# if defined(_MSC_VER) /* Defining _USE_MATH_DEFINES is required to get M_PI to be defined on - WinRT. See http://msdn.microsoft.com/en-us/library/4hwaceh6.aspx + Visual Studio. See http://msdn.microsoft.com/en-us/library/4hwaceh6.aspx for more information. */ -# define _USE_MATH_DEFINES +# ifndef _USE_MATH_DEFINES +# define _USE_MATH_DEFINES +# endif # endif # include #endif @@ -105,10 +107,27 @@ # elif defined(__MRC__) void *alloca(unsigned); # else -char *alloca(); +void *alloca(size_t); # endif #endif +#ifdef SIZE_MAX +# define SDL_SIZE_MAX SIZE_MAX +#else +# define SDL_SIZE_MAX ((size_t) -1) +#endif + +/** + * Check if the compiler supports a given builtin. + * Supported by virtually all clang versions and recent gcc. Use this + * instead of checking the clang version if possible. + */ +#ifdef __has_builtin +#define _SDL_HAS_BUILTIN(x) __has_builtin(x) +#else +#define _SDL_HAS_BUILTIN(x) 0 +#endif + /** * The number of elements in an array. */ @@ -217,53 +236,94 @@ typedef uint64_t Uint64; /* @} *//* Basic data types */ -/* Make sure we have macros for printing 64 bit values. +/** + * \name Floating-point constants + */ +/* @{ */ + +#ifdef FLT_EPSILON +#define SDL_FLT_EPSILON FLT_EPSILON +#else +#define SDL_FLT_EPSILON 1.1920928955078125e-07F /* 0x0.000002p0 */ +#endif + +/* @} *//* Floating-point constants */ + +/* Make sure we have macros for printing width-based integers. * should define these but this is not true all platforms. * (for example win32) */ #ifndef SDL_PRIs64 -#ifdef PRIs64 -#define SDL_PRIs64 PRIs64 -#elif defined(__WIN32__) +#if defined(__WIN32__) || defined(__GDK__) #define SDL_PRIs64 "I64d" -#elif defined(__LINUX__) && defined(__LP64__) +#elif defined(PRIs64) +#define SDL_PRIs64 PRIs64 +#elif defined(__LP64__) && !defined(__APPLE__) #define SDL_PRIs64 "ld" #else #define SDL_PRIs64 "lld" #endif #endif #ifndef SDL_PRIu64 -#ifdef PRIu64 -#define SDL_PRIu64 PRIu64 -#elif defined(__WIN32__) +#if defined(__WIN32__) || defined(__GDK__) #define SDL_PRIu64 "I64u" -#elif defined(__LINUX__) && defined(__LP64__) +#elif defined(PRIu64) +#define SDL_PRIu64 PRIu64 +#elif defined(__LP64__) && !defined(__APPLE__) #define SDL_PRIu64 "lu" #else #define SDL_PRIu64 "llu" #endif #endif #ifndef SDL_PRIx64 -#ifdef PRIx64 -#define SDL_PRIx64 PRIx64 -#elif defined(__WIN32__) +#if defined(__WIN32__) || defined(__GDK__) #define SDL_PRIx64 "I64x" -#elif defined(__LINUX__) && defined(__LP64__) +#elif defined(PRIx64) +#define SDL_PRIx64 PRIx64 +#elif defined(__LP64__) && !defined(__APPLE__) #define SDL_PRIx64 "lx" #else #define SDL_PRIx64 "llx" #endif #endif #ifndef SDL_PRIX64 -#ifdef PRIX64 -#define SDL_PRIX64 PRIX64 -#elif defined(__WIN32__) +#if defined(__WIN32__) || defined(__GDK__) #define SDL_PRIX64 "I64X" -#elif defined(__LINUX__) && defined(__LP64__) +#elif defined(PRIX64) +#define SDL_PRIX64 PRIX64 +#elif defined(__LP64__) && !defined(__APPLE__) #define SDL_PRIX64 "lX" #else #define SDL_PRIX64 "llX" #endif #endif +#ifndef SDL_PRIs32 +#ifdef PRId32 +#define SDL_PRIs32 PRId32 +#else +#define SDL_PRIs32 "d" +#endif +#endif +#ifndef SDL_PRIu32 +#ifdef PRIu32 +#define SDL_PRIu32 PRIu32 +#else +#define SDL_PRIu32 "u" +#endif +#endif +#ifndef SDL_PRIx32 +#ifdef PRIx32 +#define SDL_PRIx32 PRIx32 +#else +#define SDL_PRIx32 "x" +#endif +#endif +#ifndef SDL_PRIX32 +#ifdef PRIX32 +#define SDL_PRIX32 PRIX32 +#else +#define SDL_PRIX32 "X" +#endif +#endif /* Annotations to help code analysis tools */ #ifdef SDL_DISABLE_ANALYZE_MACROS @@ -276,7 +336,9 @@ typedef uint64_t Uint64; #define SDL_PRINTF_FORMAT_STRING #define SDL_SCANF_FORMAT_STRING #define SDL_PRINTF_VARARG_FUNC( fmtargnumber ) +#define SDL_PRINTF_VARARG_FUNCV( fmtargnumber ) #define SDL_SCANF_VARARG_FUNC( fmtargnumber ) +#define SDL_SCANF_VARARG_FUNCV( fmtargnumber ) #else #if defined(_MSC_VER) && (_MSC_VER >= 1600) /* VS 2010 and above */ #include @@ -302,15 +364,33 @@ typedef uint64_t Uint64; #endif #if defined(__GNUC__) #define SDL_PRINTF_VARARG_FUNC( fmtargnumber ) __attribute__ (( format( __printf__, fmtargnumber, fmtargnumber+1 ))) +#define SDL_PRINTF_VARARG_FUNCV( fmtargnumber ) __attribute__(( format( __printf__, fmtargnumber, 0 ))) #define SDL_SCANF_VARARG_FUNC( fmtargnumber ) __attribute__ (( format( __scanf__, fmtargnumber, fmtargnumber+1 ))) +#define SDL_SCANF_VARARG_FUNCV( fmtargnumber ) __attribute__(( format( __scanf__, fmtargnumber, 0 ))) #else #define SDL_PRINTF_VARARG_FUNC( fmtargnumber ) +#define SDL_PRINTF_VARARG_FUNCV( fmtargnumber ) #define SDL_SCANF_VARARG_FUNC( fmtargnumber ) +#define SDL_SCANF_VARARG_FUNCV( fmtargnumber ) #endif #endif /* SDL_DISABLE_ANALYZE_MACROS */ +#ifndef SDL_COMPILE_TIME_ASSERT +#if defined(__cplusplus) +#if (__cplusplus >= 201103L) +#define SDL_COMPILE_TIME_ASSERT(name, x) static_assert(x, #x) +#endif +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) +#define SDL_COMPILE_TIME_ASSERT(name, x) _Static_assert(x, #x) +#endif +#endif /* !SDL_COMPILE_TIME_ASSERT */ + +#ifndef SDL_COMPILE_TIME_ASSERT +/* universal, but may trigger -Wunused-local-typedefs */ #define SDL_COMPILE_TIME_ASSERT(name, x) \ typedef int SDL_compile_time_assert_ ## name[(x) * 2 - 1] +#endif + /** \cond */ #ifndef DOXYGEN_SHOULD_IGNORE_THIS SDL_COMPILE_TIME_ASSERT(uint8, sizeof(Uint8) == 1); @@ -332,7 +412,7 @@ SDL_COMPILE_TIME_ASSERT(sint64, sizeof(Sint64) == 8); /** \cond */ #ifndef DOXYGEN_SHOULD_IGNORE_THIS -#if !defined(__ANDROID__) +#if !defined(__ANDROID__) && !defined(__VITA__) && !defined(__3DS__) /* TODO: include/SDL_stdinc.h:174: error: size of array 'SDL_dummy_enum' is negative */ typedef enum { @@ -369,7 +449,19 @@ 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 + * Get the original set of SDL memory functions + * + * \since This function is available since SDL 2.24.0. + */ +extern DECLSPEC void SDLCALL SDL_GetOriginalMemoryFunctions(SDL_malloc_func *malloc_func, + SDL_calloc_func *calloc_func, + SDL_realloc_func *realloc_func, + SDL_free_func *free_func); + +/** + * Get the current set of SDL memory functions + * + * \since This function is available since SDL 2.0.7. */ extern DECLSPEC void SDLCALL SDL_GetMemoryFunctions(SDL_malloc_func *malloc_func, SDL_calloc_func *calloc_func, @@ -377,12 +469,9 @@ extern DECLSPEC void SDLCALL SDL_GetMemoryFunctions(SDL_malloc_func *malloc_func SDL_free_func *free_func); /** - * \brief Replace SDL's memory allocation functions with a custom set + * 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. + * \since This function is available since SDL 2.0.7. */ extern DECLSPEC int SDLCALL SDL_SetMemoryFunctions(SDL_malloc_func malloc_func, SDL_calloc_func calloc_func, @@ -390,41 +479,58 @@ extern DECLSPEC int SDLCALL SDL_SetMemoryFunctions(SDL_malloc_func malloc_func, SDL_free_func free_func); /** - * \brief Get the number of outstanding (unfreed) allocations + * Get the number of outstanding (unfreed) allocations + * + * \since This function is available since SDL 2.0.7. */ 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); -extern DECLSPEC void SDLCALL SDL_qsort(void *base, size_t nmemb, size_t size, int (*compare) (const void *, const void *)); +extern DECLSPEC void SDLCALL SDL_qsort(void *base, size_t nmemb, size_t size, int (SDLCALL *compare) (const void *, const void *)); +extern DECLSPEC void * SDLCALL SDL_bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (SDLCALL *compare) (const void *, const void *)); extern DECLSPEC int SDLCALL SDL_abs(int x); -/* !!! FIXME: these have side effects. You probably shouldn't use them. */ -/* !!! FIXME: Maybe we do forceinline functions of SDL_mini, SDL_minf, etc? */ +/* NOTE: these double-evaluate their arguments, so you should never have side effects in the parameters */ #define SDL_min(x, y) (((x) < (y)) ? (x) : (y)) #define SDL_max(x, y) (((x) > (y)) ? (x) : (y)) +#define SDL_clamp(x, a, b) (((x) < (a)) ? (a) : (((x) > (b)) ? (b) : (x))) +extern DECLSPEC int SDLCALL SDL_isalpha(int x); +extern DECLSPEC int SDLCALL SDL_isalnum(int x); +extern DECLSPEC int SDLCALL SDL_isblank(int x); +extern DECLSPEC int SDLCALL SDL_iscntrl(int x); extern DECLSPEC int SDLCALL SDL_isdigit(int x); +extern DECLSPEC int SDLCALL SDL_isxdigit(int x); +extern DECLSPEC int SDLCALL SDL_ispunct(int x); extern DECLSPEC int SDLCALL SDL_isspace(int x); extern DECLSPEC int SDLCALL SDL_isupper(int x); extern DECLSPEC int SDLCALL SDL_islower(int x); +extern DECLSPEC int SDLCALL SDL_isprint(int x); +extern DECLSPEC int SDLCALL SDL_isgraph(int x); extern DECLSPEC int SDLCALL SDL_toupper(int x); extern DECLSPEC int SDLCALL SDL_tolower(int x); +extern DECLSPEC Uint16 SDLCALL SDL_crc16(Uint16 crc, const void *data, size_t len); +extern DECLSPEC Uint32 SDLCALL SDL_crc32(Uint32 crc, const void *data, size_t len); + extern DECLSPEC void *SDLCALL SDL_memset(SDL_OUT_BYTECAP(len) void *dst, int c, size_t len); #define SDL_zero(x) SDL_memset(&(x), 0, sizeof((x))) #define SDL_zerop(x) SDL_memset((x), 0, sizeof(*(x))) #define SDL_zeroa(x) SDL_memset((x), 0, sizeof((x))) +#define SDL_copyp(dst, src) \ + { SDL_COMPILE_TIME_ASSERT(SDL_copyp, sizeof (*(dst)) == sizeof (*(src))); } \ + SDL_memcpy((dst), (src), sizeof (*(src))) + + /* Note that memset() is a byte assignment and this is a 32-bit assignment, so they're not directly equivalent. */ SDL_FORCE_INLINE void SDL_memset4(void *dst, Uint32 val, size_t dwords) { -#ifdef __APPLE__ - memset_pattern4(dst, &val, dwords * 4); -#elif defined(__GNUC__) && defined(i386) +#if defined(__GNUC__) && defined(__i386__) int u0, u1, u2; __asm__ __volatile__ ( "cld \n\t" @@ -437,14 +543,14 @@ SDL_FORCE_INLINE void SDL_memset4(void *dst, Uint32 val, size_t dwords) size_t _n = (dwords + 3) / 4; Uint32 *_p = SDL_static_cast(Uint32 *, dst); Uint32 _val = (val); - if (dwords == 0) + if (dwords == 0) { return; - switch (dwords % 4) - { - case 0: do { *_p++ = _val; /* fallthrough */ - case 3: *_p++ = _val; /* fallthrough */ - case 2: *_p++ = _val; /* fallthrough */ - case 1: *_p++ = _val; /* fallthrough */ + } + switch (dwords % 4) { + case 0: do { *_p++ = _val; SDL_FALLTHROUGH; + case 3: *_p++ = _val; SDL_FALLTHROUGH; + case 2: *_p++ = _val; SDL_FALLTHROUGH; + case 1: *_p++ = _val; } while ( --_n ); } #endif @@ -463,6 +569,8 @@ extern DECLSPEC wchar_t *SDLCALL SDL_wcsstr(const wchar_t *haystack, const wchar extern DECLSPEC int SDLCALL SDL_wcscmp(const wchar_t *str1, const wchar_t *str2); extern DECLSPEC int SDLCALL SDL_wcsncmp(const wchar_t *str1, const wchar_t *str2, size_t maxlen); +extern DECLSPEC int SDLCALL SDL_wcscasecmp(const wchar_t *str1, const wchar_t *str2); +extern DECLSPEC int SDLCALL SDL_wcsncasecmp(const wchar_t *str1, const wchar_t *str2, size_t len); extern DECLSPEC size_t SDLCALL SDL_strlen(const char *str); extern DECLSPEC size_t SDLCALL SDL_strlcpy(SDL_OUT_Z_CAP(maxlen) char *dst, const char *src, size_t maxlen); @@ -475,8 +583,10 @@ extern DECLSPEC char *SDLCALL SDL_strlwr(char *str); extern DECLSPEC char *SDLCALL SDL_strchr(const char *str, int c); extern DECLSPEC char *SDLCALL SDL_strrchr(const char *str, int c); extern DECLSPEC char *SDLCALL SDL_strstr(const char *haystack, const char *needle); +extern DECLSPEC char *SDLCALL SDL_strcasestr(const char *haystack, const char *needle); extern DECLSPEC char *SDLCALL SDL_strtokr(char *s1, const char *s2, char **saveptr); extern DECLSPEC size_t SDLCALL SDL_utf8strlen(const char *str); +extern DECLSPEC size_t SDLCALL SDL_utf8strnlen(const char *str, size_t bytes); extern DECLSPEC char *SDLCALL SDL_itoa(int value, char *str, int radix); extern DECLSPEC char *SDLCALL SDL_uitoa(unsigned int value, char *str, int radix); @@ -499,9 +609,11 @@ extern DECLSPEC int SDLCALL SDL_strcasecmp(const char *str1, const char *str2); extern DECLSPEC int SDLCALL SDL_strncasecmp(const char *str1, const char *str2, size_t len); extern DECLSPEC int SDLCALL SDL_sscanf(const char *text, SDL_SCANF_FORMAT_STRING const char *fmt, ...) SDL_SCANF_VARARG_FUNC(2); -extern DECLSPEC int SDLCALL SDL_vsscanf(const char *text, const char *fmt, va_list ap); +extern DECLSPEC int SDLCALL SDL_vsscanf(const char *text, SDL_SCANF_FORMAT_STRING const char *fmt, va_list ap) SDL_SCANF_VARARG_FUNCV(2); extern DECLSPEC int SDLCALL SDL_snprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, SDL_PRINTF_FORMAT_STRING const char *fmt, ... ) SDL_PRINTF_VARARG_FUNC(3); -extern DECLSPEC int SDLCALL SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt, va_list ap); +extern DECLSPEC int SDLCALL SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, SDL_PRINTF_FORMAT_STRING const char *fmt, va_list ap) SDL_PRINTF_VARARG_FUNCV(3); +extern DECLSPEC int SDLCALL SDL_asprintf(char **strp, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); +extern DECLSPEC int SDLCALL SDL_vasprintf(char **strp, SDL_PRINTF_FORMAT_STRING const char *fmt, va_list ap) SDL_PRINTF_VARARG_FUNCV(2); #ifndef HAVE_M_PI #ifndef M_PI @@ -509,14 +621,28 @@ extern DECLSPEC int SDLCALL SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size #endif #endif +/** + * Use this function to compute arc cosine of `x`. + * + * The definition of `y = acos(x)` is `x = cos(y)`. + * + * Domain: `-1 <= x <= 1` + * + * Range: `0 <= y <= Pi` + * + * \param x floating point value, in radians. + * \returns arc cosine of `x`. + * + * \since This function is available since SDL 2.0.2. + */ extern DECLSPEC double SDLCALL SDL_acos(double x); extern DECLSPEC float SDLCALL SDL_acosf(float x); extern DECLSPEC double SDLCALL SDL_asin(double x); extern DECLSPEC float SDLCALL SDL_asinf(float x); extern DECLSPEC double SDLCALL SDL_atan(double x); extern DECLSPEC float SDLCALL SDL_atanf(float x); -extern DECLSPEC double SDLCALL SDL_atan2(double x, double y); -extern DECLSPEC float SDLCALL SDL_atan2f(float x, float y); +extern DECLSPEC double SDLCALL SDL_atan2(double y, double x); +extern DECLSPEC float SDLCALL SDL_atan2f(float y, float x); extern DECLSPEC double SDLCALL SDL_ceil(double x); extern DECLSPEC float SDLCALL SDL_ceilf(float x); extern DECLSPEC double SDLCALL SDL_copysign(double x, double y); @@ -529,6 +655,8 @@ extern DECLSPEC double SDLCALL SDL_fabs(double x); extern DECLSPEC float SDLCALL SDL_fabsf(float x); extern DECLSPEC double SDLCALL SDL_floor(double x); extern DECLSPEC float SDLCALL SDL_floorf(float x); +extern DECLSPEC double SDLCALL SDL_trunc(double x); +extern DECLSPEC float SDLCALL SDL_truncf(float x); extern DECLSPEC double SDLCALL SDL_fmod(double x, double y); extern DECLSPEC float SDLCALL SDL_fmodf(float x, float y); extern DECLSPEC double SDLCALL SDL_log(double x); @@ -537,6 +665,10 @@ extern DECLSPEC double SDLCALL SDL_log10(double x); extern DECLSPEC float SDLCALL SDL_log10f(float x); extern DECLSPEC double SDLCALL SDL_pow(double x, double y); extern DECLSPEC float SDLCALL SDL_powf(float x, float y); +extern DECLSPEC double SDLCALL SDL_round(double x); +extern DECLSPEC float SDLCALL SDL_roundf(float x); +extern DECLSPEC long SDLCALL SDL_lround(double x); +extern DECLSPEC long SDLCALL SDL_lroundf(float x); extern DECLSPEC double SDLCALL SDL_scalbn(double x, int n); extern DECLSPEC float SDLCALL SDL_scalbnf(float x, int n); extern DECLSPEC double SDLCALL SDL_sin(double x); @@ -560,21 +692,50 @@ extern DECLSPEC int SDLCALL SDL_iconv_close(SDL_iconv_t cd); extern DECLSPEC size_t SDLCALL SDL_iconv(SDL_iconv_t cd, const char **inbuf, size_t * inbytesleft, char **outbuf, size_t * outbytesleft); + /** - * This function converts a string between encodings in one pass, returning a - * string that must be freed with SDL_free() or NULL on error. + * This function converts a buffer or string between encodings in one pass, + * returning a string that must be freed with SDL_free() or NULL on error. + * + * \since This function is available since SDL 2.0.0. */ extern DECLSPEC char *SDLCALL SDL_iconv_string(const char *tocode, const char *fromcode, const char *inbuf, size_t inbytesleft); #define SDL_iconv_utf8_locale(S) SDL_iconv_string("", "UTF-8", S, SDL_strlen(S)+1) -#define SDL_iconv_utf8_ucs2(S) (Uint16 *)SDL_iconv_string("UCS-2-INTERNAL", "UTF-8", S, SDL_strlen(S)+1) -#define SDL_iconv_utf8_ucs4(S) (Uint32 *)SDL_iconv_string("UCS-4-INTERNAL", "UTF-8", S, SDL_strlen(S)+1) +#define SDL_iconv_utf8_ucs2(S) (Uint16 *)SDL_iconv_string("UCS-2", "UTF-8", S, SDL_strlen(S)+1) +#define SDL_iconv_utf8_ucs4(S) (Uint32 *)SDL_iconv_string("UCS-4", "UTF-8", S, SDL_strlen(S)+1) +#define SDL_iconv_wchar_utf8(S) SDL_iconv_string("UTF-8", "WCHAR_T", (char *)S, (SDL_wcslen(S)+1)*sizeof(wchar_t)) /* force builds using Clang's static analysis tools to use literal C runtime here, since there are possibly tests that are ineffective otherwise. */ #if defined(__clang_analyzer__) && !defined(SDL_DISABLE_ANALYZE_MACROS) + +/* The analyzer knows about strlcpy even when the system doesn't provide it */ +#ifndef HAVE_STRLCPY +size_t strlcpy(char* dst, const char* src, size_t size); +#endif + +/* The analyzer knows about strlcat even when the system doesn't provide it */ +#ifndef HAVE_STRLCAT +size_t strlcat(char* dst, const char* src, size_t size); +#endif + +#ifndef HAVE_WCSLCPY +size_t wcslcpy(wchar_t *dst, const wchar_t *src, size_t size); +#endif + +#ifndef HAVE_WCSLCAT +size_t wcslcat(wchar_t *dst, const wchar_t *src, size_t size); +#endif + +/* Starting LLVM 16, the analyser errors out if these functions do not have + their prototype defined (clang-diagnostic-implicit-function-declaration) */ +#include +#include +#include + #define SDL_malloc malloc #define SDL_calloc calloc #define SDL_realloc realloc @@ -583,16 +744,23 @@ extern DECLSPEC char *SDLCALL SDL_iconv_string(const char *tocode, #define SDL_memcpy memcpy #define SDL_memmove memmove #define SDL_memcmp memcmp -#define SDL_strlen strlen #define SDL_strlcpy strlcpy #define SDL_strlcat strlcat +#define SDL_strlen strlen +#define SDL_wcslen wcslen +#define SDL_wcslcpy wcslcpy +#define SDL_wcslcat wcslcat #define SDL_strdup strdup +#define SDL_wcsdup wcsdup #define SDL_strchr strchr #define SDL_strrchr strrchr #define SDL_strstr strstr +#define SDL_wcsstr wcsstr #define SDL_strtokr strtok_r #define SDL_strcmp strcmp +#define SDL_wcscmp wcscmp #define SDL_strncmp strncmp +#define SDL_wcsncmp wcsncmp #define SDL_strcasecmp strcasecmp #define SDL_strncasecmp strncasecmp #define SDL_sscanf sscanf @@ -606,6 +774,65 @@ SDL_FORCE_INLINE void *SDL_memcpy4(SDL_OUT_BYTECAP(dwords*4) void *dst, SDL_IN_B return SDL_memcpy(dst, src, dwords * 4); } +/** + * If a * b would overflow, return -1. Otherwise store a * b via ret + * and return 0. + * + * \since This function is available since SDL 2.24.0. + */ +SDL_FORCE_INLINE int SDL_size_mul_overflow (size_t a, + size_t b, + size_t *ret) +{ + if (a != 0 && b > SDL_SIZE_MAX / a) { + return -1; + } + *ret = a * b; + return 0; +} + +#if _SDL_HAS_BUILTIN(__builtin_mul_overflow) +/* This needs to be wrapped in an inline rather than being a direct #define, + * because __builtin_mul_overflow() is type-generic, but we want to be + * consistent about interpreting a and b as size_t. */ +SDL_FORCE_INLINE int _SDL_size_mul_overflow_builtin (size_t a, + size_t b, + size_t *ret) +{ + return __builtin_mul_overflow(a, b, ret) == 0 ? 0 : -1; +} +#define SDL_size_mul_overflow(a, b, ret) (_SDL_size_mul_overflow_builtin(a, b, ret)) +#endif + +/** + * If a + b would overflow, return -1. Otherwise store a + b via ret + * and return 0. + * + * \since This function is available since SDL 2.24.0. + */ +SDL_FORCE_INLINE int SDL_size_add_overflow (size_t a, + size_t b, + size_t *ret) +{ + if (b > SDL_SIZE_MAX - a) { + return -1; + } + *ret = a + b; + return 0; +} + +#if _SDL_HAS_BUILTIN(__builtin_add_overflow) +/* This needs to be wrapped in an inline rather than being a direct #define, + * the same as the call to __builtin_mul_overflow() above. */ +SDL_FORCE_INLINE int _SDL_size_add_overflow_builtin (size_t a, + size_t b, + size_t *ret) +{ + return __builtin_add_overflow(a, b, ret) == 0 ? 0 : -1; +} +#define SDL_size_add_overflow(a, b, ret) (_SDL_size_add_overflow_builtin(a, b, ret)) +#endif + /* Ends C function definitions when using C++ */ #ifdef __cplusplus } diff --git a/SDL2-2.30.5/include/SDL_surface.h b/SDL2-2.30.5/include/SDL_surface.h new file mode 100644 index 0000000..ceeb86b --- /dev/null +++ b/SDL2-2.30.5/include/SDL_surface.h @@ -0,0 +1,997 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_surface.h + * + * Header file for ::SDL_Surface definition and management functions. + */ + +#ifndef SDL_surface_h_ +#define SDL_surface_h_ + +#include "SDL_stdinc.h" +#include "SDL_pixels.h" +#include "SDL_rect.h" +#include "SDL_blendmode.h" +#include "SDL_rwops.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \name Surface flags + * + * These are the currently supported flags for the ::SDL_Surface. + * + * \internal + * Used internally (read-only). + */ +/* @{ */ +#define SDL_SWSURFACE 0 /**< Just here for compatibility */ +#define SDL_PREALLOC 0x00000001 /**< Surface uses preallocated memory */ +#define SDL_RLEACCEL 0x00000002 /**< Surface is RLE encoded */ +#define SDL_DONTFREE 0x00000004 /**< Surface is referenced internally */ +#define SDL_SIMD_ALIGNED 0x00000008 /**< Surface uses aligned memory */ +/* @} *//* Surface flags */ + +/** + * Evaluates to true if the surface needs to be locked before access. + */ +#define SDL_MUSTLOCK(S) (((S)->flags & SDL_RLEACCEL) != 0) + +typedef struct SDL_BlitMap SDL_BlitMap; /* this is an opaque type. */ + +/** + * \brief A collection of pixels used in software blitting. + * + * \note This structure should be treated as read-only, except for \c pixels, + * which, if not NULL, contains the raw pixel data for the surface. + */ +typedef struct SDL_Surface +{ + Uint32 flags; /**< Read-only */ + SDL_PixelFormat *format; /**< Read-only */ + int w, h; /**< Read-only */ + int pitch; /**< Read-only */ + void *pixels; /**< Read-write */ + + /** Application data associated with the surface */ + void *userdata; /**< Read-write */ + + /** information needed for surfaces requiring locks */ + int locked; /**< Read-only */ + + /** list of BlitMap that hold a reference to this surface */ + void *list_blitmap; /**< Private */ + + /** clipping information */ + SDL_Rect clip_rect; /**< Read-only */ + + /** info for fast blit mapping to other surfaces */ + SDL_BlitMap *map; /**< Private */ + + /** Reference count -- used when freeing surface */ + int refcount; /**< Read-mostly */ +} SDL_Surface; + +/** + * \brief The type of function used for surface blitting functions. + */ +typedef int (SDLCALL *SDL_blit) (struct SDL_Surface * src, SDL_Rect * srcrect, + struct SDL_Surface * dst, SDL_Rect * dstrect); + +/** + * \brief The formula used for converting between YUV and RGB + */ +typedef enum +{ + SDL_YUV_CONVERSION_JPEG, /**< Full range JPEG */ + SDL_YUV_CONVERSION_BT601, /**< BT.601 (the default) */ + SDL_YUV_CONVERSION_BT709, /**< BT.709 */ + SDL_YUV_CONVERSION_AUTOMATIC /**< BT.601 for SD content, BT.709 for HD content */ +} SDL_YUV_CONVERSION_MODE; + +/** + * Allocate a new RGB surface. + * + * If `depth` is 4 or 8 bits, an empty palette is allocated for the surface. + * If `depth` is greater than 8 bits, the pixel format is set using the + * [RGBA]mask parameters. + * + * The [RGBA]mask parameters are the bitmasks used to extract that color from + * a pixel. For instance, `Rmask` being 0xFF000000 means the red data is + * stored in the most significant byte. Using zeros for the RGB masks sets a + * default value, based on the depth. For example: + * + * ```c++ + * SDL_CreateRGBSurface(0,w,h,32,0,0,0,0); + * ``` + * + * However, using zero for the Amask results in an Amask of 0. + * + * By default surfaces with an alpha mask are set up for blending as with: + * + * ```c++ + * SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_BLEND) + * ``` + * + * You can change this by calling SDL_SetSurfaceBlendMode() and selecting a + * different `blendMode`. + * + * \param flags the flags are unused and should be set to 0 + * \param width the width of the surface + * \param height the height of the surface + * \param depth the depth of the surface in bits + * \param Rmask the red mask for the pixels + * \param Gmask the green mask for the pixels + * \param Bmask the blue mask for the pixels + * \param Amask the alpha mask for the pixels + * \returns the new SDL_Surface structure that is created or NULL if it fails; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateRGBSurfaceFrom + * \sa SDL_CreateRGBSurfaceWithFormat + * \sa SDL_FreeSurface + */ +extern DECLSPEC SDL_Surface *SDLCALL SDL_CreateRGBSurface + (Uint32 flags, int width, int height, int depth, + Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask); + + +/* !!! FIXME for 2.1: why does this ask for depth? Format provides that. */ + +/** + * Allocate a new RGB surface with a specific pixel format. + * + * This function operates mostly like SDL_CreateRGBSurface(), except instead + * of providing pixel color masks, you provide it with a predefined format + * from SDL_PixelFormatEnum. + * + * \param flags the flags are unused and should be set to 0 + * \param width the width of the surface + * \param height the height of the surface + * \param depth the depth of the surface in bits + * \param format the SDL_PixelFormatEnum for the new surface's pixel format. + * \returns the new SDL_Surface structure that is created or NULL if it fails; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.5. + * + * \sa SDL_CreateRGBSurface + * \sa SDL_CreateRGBSurfaceFrom + * \sa SDL_FreeSurface + */ +extern DECLSPEC SDL_Surface *SDLCALL SDL_CreateRGBSurfaceWithFormat + (Uint32 flags, int width, int height, int depth, Uint32 format); + +/** + * Allocate a new RGB surface with existing pixel data. + * + * This function operates mostly like SDL_CreateRGBSurface(), except it does + * not allocate memory for the pixel data, instead the caller provides an + * existing buffer of data for the surface to use. + * + * No copy is made of the pixel data. Pixel data is not managed automatically; + * you must free the surface before you free the pixel data. + * + * \param pixels a pointer to existing pixel data + * \param width the width of the surface + * \param height the height of the surface + * \param depth the depth of the surface in bits + * \param pitch the pitch of the surface in bytes + * \param Rmask the red mask for the pixels + * \param Gmask the green mask for the pixels + * \param Bmask the blue mask for the pixels + * \param Amask the alpha mask for the pixels + * \returns the new SDL_Surface structure that is created or NULL if it fails; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateRGBSurface + * \sa SDL_CreateRGBSurfaceWithFormat + * \sa SDL_FreeSurface + */ +extern DECLSPEC SDL_Surface *SDLCALL SDL_CreateRGBSurfaceFrom(void *pixels, + int width, + int height, + int depth, + int pitch, + Uint32 Rmask, + Uint32 Gmask, + Uint32 Bmask, + Uint32 Amask); + +/* !!! FIXME for 2.1: why does this ask for depth? Format provides that. */ + +/** + * Allocate a new RGB surface with with a specific pixel format and existing + * pixel data. + * + * This function operates mostly like SDL_CreateRGBSurfaceFrom(), except + * instead of providing pixel color masks, you provide it with a predefined + * format from SDL_PixelFormatEnum. + * + * No copy is made of the pixel data. Pixel data is not managed automatically; + * you must free the surface before you free the pixel data. + * + * \param pixels a pointer to existing pixel data + * \param width the width of the surface + * \param height the height of the surface + * \param depth the depth of the surface in bits + * \param pitch the pitch of the surface in bytes + * \param format the SDL_PixelFormatEnum for the new surface's pixel format. + * \returns the new SDL_Surface structure that is created or NULL if it fails; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.5. + * + * \sa SDL_CreateRGBSurfaceFrom + * \sa SDL_CreateRGBSurfaceWithFormat + * \sa SDL_FreeSurface + */ +extern DECLSPEC SDL_Surface *SDLCALL SDL_CreateRGBSurfaceWithFormatFrom + (void *pixels, int width, int height, int depth, int pitch, Uint32 format); + +/** + * Free an RGB surface. + * + * It is safe to pass NULL to this function. + * + * \param surface the SDL_Surface to free. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateRGBSurface + * \sa SDL_CreateRGBSurfaceFrom + * \sa SDL_LoadBMP + * \sa SDL_LoadBMP_RW + */ +extern DECLSPEC void SDLCALL SDL_FreeSurface(SDL_Surface * surface); + +/** + * Set the palette used by a surface. + * + * A single palette can be shared with many surfaces. + * + * \param surface the SDL_Surface structure to update + * \param palette the SDL_Palette structure to use + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC int SDLCALL SDL_SetSurfacePalette(SDL_Surface * surface, + SDL_Palette * palette); + +/** + * Set up a surface for directly accessing the pixels. + * + * Between calls to SDL_LockSurface() / SDL_UnlockSurface(), you can write to + * and read from `surface->pixels`, using the pixel format stored in + * `surface->format`. Once you are done accessing the surface, you should use + * SDL_UnlockSurface() to release it. + * + * Not all surfaces require locking. If `SDL_MUSTLOCK(surface)` evaluates to + * 0, then you can read and write to the surface at any time, and the pixel + * format of the surface will not change. + * + * \param surface the SDL_Surface structure to be locked + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_MUSTLOCK + * \sa SDL_UnlockSurface + */ +extern DECLSPEC int SDLCALL SDL_LockSurface(SDL_Surface * surface); + +/** + * Release a surface after directly accessing the pixels. + * + * \param surface the SDL_Surface structure to be unlocked + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LockSurface + */ +extern DECLSPEC void SDLCALL SDL_UnlockSurface(SDL_Surface * surface); + +/** + * Load a BMP image from a seekable SDL data stream. + * + * The new surface should be freed with SDL_FreeSurface(). Not doing so will + * result in a memory leak. + * + * src is an open SDL_RWops buffer, typically loaded with SDL_RWFromFile. + * Alternitavely, you might also use the macro SDL_LoadBMP to load a bitmap + * from a file, convert it to an SDL_Surface and then close the file. + * + * \param src the data stream for the surface + * \param freesrc non-zero to close the stream after being read + * \returns a pointer to a new SDL_Surface structure or NULL if there was an + * error; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_FreeSurface + * \sa SDL_RWFromFile + * \sa SDL_LoadBMP + * \sa SDL_SaveBMP_RW + */ +extern DECLSPEC SDL_Surface *SDLCALL SDL_LoadBMP_RW(SDL_RWops * src, + int freesrc); + +/** + * Load a surface from a file. + * + * Convenience macro. + */ +#define SDL_LoadBMP(file) SDL_LoadBMP_RW(SDL_RWFromFile(file, "rb"), 1) + +/** + * Save a surface to a seekable SDL data stream in BMP format. + * + * Surfaces with a 24-bit, 32-bit and paletted 8-bit format get saved in the + * BMP directly. Other RGB formats with 8-bit or higher get converted to a + * 24-bit surface or, if they have an alpha mask or a colorkey, to a 32-bit + * surface before they are saved. YUV and paletted 1-bit and 4-bit formats are + * not supported. + * + * \param surface the SDL_Surface structure containing the image to be saved + * \param dst a data stream to save to + * \param freedst non-zero to close the stream after being written + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_LoadBMP_RW + * \sa SDL_SaveBMP + */ +extern DECLSPEC int SDLCALL SDL_SaveBMP_RW + (SDL_Surface * surface, SDL_RWops * dst, int freedst); + +/** + * Save a surface to a file. + * + * Convenience macro. + */ +#define SDL_SaveBMP(surface, file) \ + SDL_SaveBMP_RW(surface, SDL_RWFromFile(file, "wb"), 1) + +/** + * Set the RLE acceleration hint for a surface. + * + * If RLE is enabled, color key and alpha blending blits are much faster, but + * the surface must be locked before directly accessing the pixels. + * + * \param surface the SDL_Surface structure to optimize + * \param flag 0 to disable, non-zero to enable RLE acceleration + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_BlitSurface + * \sa SDL_LockSurface + * \sa SDL_UnlockSurface + */ +extern DECLSPEC int SDLCALL SDL_SetSurfaceRLE(SDL_Surface * surface, + int flag); + +/** + * Returns whether the surface is RLE enabled + * + * It is safe to pass a NULL `surface` here; it will return SDL_FALSE. + * + * \param surface the SDL_Surface structure to query + * \returns SDL_TRUE if the surface is RLE enabled, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.14. + * + * \sa SDL_SetSurfaceRLE + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasSurfaceRLE(SDL_Surface * surface); + +/** + * Set the color key (transparent pixel) in a surface. + * + * The color key defines a pixel value that will be treated as transparent in + * a blit. For example, one can use this to specify that cyan pixels should be + * considered transparent, and therefore not rendered. + * + * It is a pixel of the format used by the surface, as generated by + * SDL_MapRGB(). + * + * RLE acceleration can substantially speed up blitting of images with large + * horizontal runs of transparent pixels. See SDL_SetSurfaceRLE() for details. + * + * \param surface the SDL_Surface structure to update + * \param flag SDL_TRUE to enable color key, SDL_FALSE to disable color key + * \param key the transparent pixel + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_BlitSurface + * \sa SDL_GetColorKey + */ +extern DECLSPEC int SDLCALL SDL_SetColorKey(SDL_Surface * surface, + int flag, Uint32 key); + +/** + * Returns whether the surface has a color key + * + * It is safe to pass a NULL `surface` here; it will return SDL_FALSE. + * + * \param surface the SDL_Surface structure to query + * \return SDL_TRUE if the surface has a color key, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.9. + * + * \sa SDL_SetColorKey + * \sa SDL_GetColorKey + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasColorKey(SDL_Surface * surface); + +/** + * Get the color key (transparent pixel) for a surface. + * + * The color key is a pixel of the format used by the surface, as generated by + * SDL_MapRGB(). + * + * If the surface doesn't have color key enabled this function returns -1. + * + * \param surface the SDL_Surface structure to query + * \param key a pointer filled in with the transparent pixel + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_BlitSurface + * \sa SDL_SetColorKey + */ +extern DECLSPEC int SDLCALL SDL_GetColorKey(SDL_Surface * surface, + Uint32 * key); + +/** + * Set an additional color value multiplied into blit operations. + * + * When this surface is blitted, during the blit operation each source color + * channel is modulated by the appropriate color value according to the + * following formula: + * + * `srcC = srcC * (color / 255)` + * + * \param surface the SDL_Surface structure to update + * \param r the red color value multiplied into blit operations + * \param g the green color value multiplied into blit operations + * \param b the blue color value multiplied into blit operations + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetSurfaceColorMod + * \sa SDL_SetSurfaceAlphaMod + */ +extern DECLSPEC int SDLCALL SDL_SetSurfaceColorMod(SDL_Surface * surface, + Uint8 r, Uint8 g, Uint8 b); + + +/** + * Get the additional color value multiplied into blit operations. + * + * \param surface the SDL_Surface structure to query + * \param r a pointer filled in with the current red color value + * \param g a pointer filled in with the current green color value + * \param b a pointer filled in with the current blue color value + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetSurfaceAlphaMod + * \sa SDL_SetSurfaceColorMod + */ +extern DECLSPEC int SDLCALL SDL_GetSurfaceColorMod(SDL_Surface * surface, + Uint8 * r, Uint8 * g, + Uint8 * b); + +/** + * Set an additional alpha value used in blit operations. + * + * When this surface is blitted, during the blit operation the source alpha + * value is modulated by this alpha value according to the following formula: + * + * `srcA = srcA * (alpha / 255)` + * + * \param surface the SDL_Surface structure to update + * \param alpha the alpha value multiplied into blit operations + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetSurfaceAlphaMod + * \sa SDL_SetSurfaceColorMod + */ +extern DECLSPEC int SDLCALL SDL_SetSurfaceAlphaMod(SDL_Surface * surface, + Uint8 alpha); + +/** + * Get the additional alpha value used in blit operations. + * + * \param surface the SDL_Surface structure to query + * \param alpha a pointer filled in with the current alpha value + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetSurfaceColorMod + * \sa SDL_SetSurfaceAlphaMod + */ +extern DECLSPEC int SDLCALL SDL_GetSurfaceAlphaMod(SDL_Surface * surface, + Uint8 * alpha); + +/** + * Set the blend mode used for blit operations. + * + * To copy a surface to another surface (or texture) without blending with the + * existing data, the blendmode of the SOURCE surface should be set to + * `SDL_BLENDMODE_NONE`. + * + * \param surface the SDL_Surface structure to update + * \param blendMode the SDL_BlendMode to use for blit blending + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetSurfaceBlendMode + */ +extern DECLSPEC int SDLCALL SDL_SetSurfaceBlendMode(SDL_Surface * surface, + SDL_BlendMode blendMode); + +/** + * Get the blend mode used for blit operations. + * + * \param surface the SDL_Surface structure to query + * \param blendMode a pointer filled in with the current SDL_BlendMode + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetSurfaceBlendMode + */ +extern DECLSPEC int SDLCALL SDL_GetSurfaceBlendMode(SDL_Surface * surface, + SDL_BlendMode *blendMode); + +/** + * Set the clipping rectangle for a surface. + * + * When `surface` is the destination of a blit, only the area within the clip + * rectangle is drawn into. + * + * Note that blits are automatically clipped to the edges of the source and + * destination surfaces. + * + * \param surface the SDL_Surface structure to be clipped + * \param rect the SDL_Rect structure representing the clipping rectangle, or + * NULL to disable clipping + * \returns SDL_TRUE if the rectangle intersects the surface, otherwise + * SDL_FALSE and blits will be completely clipped. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_BlitSurface + * \sa SDL_GetClipRect + */ +extern DECLSPEC SDL_bool SDLCALL SDL_SetClipRect(SDL_Surface * surface, + const SDL_Rect * rect); + +/** + * Get the clipping rectangle for a surface. + * + * When `surface` is the destination of a blit, only the area within the clip + * rectangle is drawn into. + * + * \param surface the SDL_Surface structure representing the surface to be + * clipped + * \param rect an SDL_Rect structure filled in with the clipping rectangle for + * the surface + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_BlitSurface + * \sa SDL_SetClipRect + */ +extern DECLSPEC void SDLCALL SDL_GetClipRect(SDL_Surface * surface, + SDL_Rect * rect); + +/* + * Creates a new surface identical to the existing surface. + * + * The returned surface should be freed with SDL_FreeSurface(). + * + * \param surface the surface to duplicate. + * \returns a copy of the surface, or NULL on failure; call SDL_GetError() for + * more information. + */ +extern DECLSPEC SDL_Surface *SDLCALL SDL_DuplicateSurface(SDL_Surface * surface); + +/** + * Copy an existing surface to a new surface of the specified format. + * + * This function is used to optimize images for faster *repeat* blitting. This + * is accomplished by converting the original and storing the result as a new + * surface. The new, optimized surface can then be used as the source for + * future blits, making them faster. + * + * \param src the existing SDL_Surface structure to convert + * \param fmt the SDL_PixelFormat structure that the new surface is optimized + * for + * \param flags the flags are unused and should be set to 0; this is a + * leftover from SDL 1.2's API + * \returns the new SDL_Surface structure that is created or NULL if it fails; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AllocFormat + * \sa SDL_ConvertSurfaceFormat + * \sa SDL_CreateRGBSurface + */ +extern DECLSPEC SDL_Surface *SDLCALL SDL_ConvertSurface + (SDL_Surface * src, const SDL_PixelFormat * fmt, Uint32 flags); + +/** + * Copy an existing surface to a new surface of the specified format enum. + * + * This function operates just like SDL_ConvertSurface(), but accepts an + * SDL_PixelFormatEnum value instead of an SDL_PixelFormat structure. As such, + * it might be easier to call but it doesn't have access to palette + * information for the destination surface, in case that would be important. + * + * \param src the existing SDL_Surface structure to convert + * \param pixel_format the SDL_PixelFormatEnum that the new surface is + * optimized for + * \param flags the flags are unused and should be set to 0; this is a + * leftover from SDL 1.2's API + * \returns the new SDL_Surface structure that is created or NULL if it fails; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AllocFormat + * \sa SDL_ConvertSurface + * \sa SDL_CreateRGBSurface + */ +extern DECLSPEC SDL_Surface *SDLCALL SDL_ConvertSurfaceFormat + (SDL_Surface * src, Uint32 pixel_format, Uint32 flags); + +/** + * Copy a block of pixels of one format to another format. + * + * \param width the width of the block to copy, in pixels + * \param height the height of the block to copy, in pixels + * \param src_format an SDL_PixelFormatEnum value of the `src` pixels format + * \param src a pointer to the source pixels + * \param src_pitch the pitch of the source pixels, in bytes + * \param dst_format an SDL_PixelFormatEnum value of the `dst` pixels format + * \param dst a pointer to be filled in with new pixel data + * \param dst_pitch the pitch of the destination pixels, in bytes + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC int SDLCALL SDL_ConvertPixels(int width, int height, + Uint32 src_format, + const void * src, int src_pitch, + Uint32 dst_format, + void * dst, int dst_pitch); + +/** + * Premultiply the alpha on a block of pixels. + * + * This is safe to use with src == dst, but not for other overlapping areas. + * + * This function is currently only implemented for SDL_PIXELFORMAT_ARGB8888. + * + * \param width the width of the block to convert, in pixels + * \param height the height of the block to convert, in pixels + * \param src_format an SDL_PixelFormatEnum value of the `src` pixels format + * \param src a pointer to the source pixels + * \param src_pitch the pitch of the source pixels, in bytes + * \param dst_format an SDL_PixelFormatEnum value of the `dst` pixels format + * \param dst a pointer to be filled in with premultiplied pixel data + * \param dst_pitch the pitch of the destination pixels, in bytes + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC int SDLCALL SDL_PremultiplyAlpha(int width, int height, + Uint32 src_format, + const void * src, int src_pitch, + Uint32 dst_format, + void * dst, int dst_pitch); + +/** + * Perform a fast fill of a rectangle with a specific color. + * + * `color` should be a pixel of the format used by the surface, and can be + * generated by SDL_MapRGB() or SDL_MapRGBA(). If the color value contains an + * alpha component then the destination is simply filled with that alpha + * information, no blending takes place. + * + * If there is a clip rectangle set on the destination (set via + * SDL_SetClipRect()), then this function will fill based on the intersection + * of the clip rectangle and `rect`. + * + * \param dst the SDL_Surface structure that is the drawing target + * \param rect the SDL_Rect structure representing the rectangle to fill, or + * NULL to fill the entire surface + * \param color the color to fill with + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_FillRects + */ +extern DECLSPEC int SDLCALL SDL_FillRect + (SDL_Surface * dst, const SDL_Rect * rect, Uint32 color); + +/** + * Perform a fast fill of a set of rectangles with a specific color. + * + * `color` should be a pixel of the format used by the surface, and can be + * generated by SDL_MapRGB() or SDL_MapRGBA(). If the color value contains an + * alpha component then the destination is simply filled with that alpha + * information, no blending takes place. + * + * If there is a clip rectangle set on the destination (set via + * SDL_SetClipRect()), then this function will fill based on the intersection + * of the clip rectangle and `rect`. + * + * \param dst the SDL_Surface structure that is the drawing target + * \param rects an array of SDL_Rects representing the rectangles to fill. + * \param count the number of rectangles in the array + * \param color the color to fill with + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_FillRect + */ +extern DECLSPEC int SDLCALL SDL_FillRects + (SDL_Surface * dst, const SDL_Rect * rects, int count, Uint32 color); + +/* !!! FIXME: merge this documentation with the wiki */ +/** + * Performs a fast blit from the source surface to the destination surface. + * + * This assumes that the source and destination rectangles are + * the same size. If either \c srcrect or \c dstrect are NULL, the entire + * surface (\c src or \c dst) is copied. The final blit rectangles are saved + * in \c srcrect and \c dstrect after all clipping is performed. + * + * \returns 0 if the blit is successful, otherwise it returns -1. + * + * The blit function should not be called on a locked surface. + * + * The blit semantics for surfaces with and without blending and colorkey + * are defined as follows: + * \verbatim + RGBA->RGB: + Source surface blend mode set to SDL_BLENDMODE_BLEND: + alpha-blend (using the source alpha-channel and per-surface alpha) + SDL_SRCCOLORKEY ignored. + Source surface blend mode set to SDL_BLENDMODE_NONE: + copy RGB. + if SDL_SRCCOLORKEY set, only copy the pixels matching the + RGB values of the source color key, ignoring alpha in the + comparison. + + RGB->RGBA: + Source surface blend mode set to SDL_BLENDMODE_BLEND: + alpha-blend (using the source per-surface alpha) + Source surface blend mode set to SDL_BLENDMODE_NONE: + copy RGB, set destination alpha to source per-surface alpha value. + both: + if SDL_SRCCOLORKEY set, only copy the pixels matching the + source color key. + + RGBA->RGBA: + Source surface blend mode set to SDL_BLENDMODE_BLEND: + alpha-blend (using the source alpha-channel and per-surface alpha) + SDL_SRCCOLORKEY ignored. + Source surface blend mode set to SDL_BLENDMODE_NONE: + copy all of RGBA to the destination. + if SDL_SRCCOLORKEY set, only copy the pixels matching the + RGB values of the source color key, ignoring alpha in the + comparison. + + RGB->RGB: + Source surface blend mode set to SDL_BLENDMODE_BLEND: + alpha-blend (using the source per-surface alpha) + Source surface blend mode set to SDL_BLENDMODE_NONE: + copy RGB. + both: + if SDL_SRCCOLORKEY set, only copy the pixels matching the + source color key. + \endverbatim + * + * You should call SDL_BlitSurface() unless you know exactly how SDL + * blitting works internally and how to use the other blit functions. + */ +#define SDL_BlitSurface SDL_UpperBlit + +/** + * Perform a fast blit from the source surface to the destination surface. + * + * SDL_UpperBlit() has been replaced by SDL_BlitSurface(), which is merely a + * macro for this function with a less confusing name. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_BlitSurface + */ +extern DECLSPEC int SDLCALL SDL_UpperBlit + (SDL_Surface * src, const SDL_Rect * srcrect, + SDL_Surface * dst, SDL_Rect * dstrect); + +/** + * Perform low-level surface blitting only. + * + * This is a semi-private blit function and it performs low-level surface + * blitting, assuming the input rectangles have already been clipped. + * + * Unless you know what you're doing, you should be using SDL_BlitSurface() + * instead. + * + * \param src the SDL_Surface structure to be copied from + * \param srcrect the SDL_Rect structure representing the rectangle to be + * copied, or NULL to copy the entire surface + * \param dst the SDL_Surface structure that is the blit target + * \param dstrect the SDL_Rect structure representing the rectangle that is + * copied into + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_BlitSurface + */ +extern DECLSPEC int SDLCALL SDL_LowerBlit + (SDL_Surface * src, SDL_Rect * srcrect, + SDL_Surface * dst, SDL_Rect * dstrect); + + +/** + * Perform a fast, low quality, stretch blit between two surfaces of the same + * format. + * + * Please use SDL_BlitScaled() instead. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC int SDLCALL SDL_SoftStretch(SDL_Surface * src, + const SDL_Rect * srcrect, + SDL_Surface * dst, + const SDL_Rect * dstrect); + +/** + * Perform bilinear scaling between two surfaces of the same format, 32BPP. + * + * \since This function is available since SDL 2.0.16. + */ +extern DECLSPEC int SDLCALL SDL_SoftStretchLinear(SDL_Surface * src, + const SDL_Rect * srcrect, + SDL_Surface * dst, + const SDL_Rect * dstrect); + + +#define SDL_BlitScaled SDL_UpperBlitScaled + +/** + * Perform a scaled surface copy to a destination surface. + * + * SDL_UpperBlitScaled() has been replaced by SDL_BlitScaled(), which is + * merely a macro for this function with a less confusing name. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_BlitScaled + */ +extern DECLSPEC int SDLCALL SDL_UpperBlitScaled + (SDL_Surface * src, const SDL_Rect * srcrect, + SDL_Surface * dst, SDL_Rect * dstrect); + +/** + * Perform low-level surface scaled blitting only. + * + * This is a semi-private function and it performs low-level surface blitting, + * assuming the input rectangles have already been clipped. + * + * \param src the SDL_Surface structure to be copied from + * \param srcrect the SDL_Rect structure representing the rectangle to be + * copied + * \param dst the SDL_Surface structure that is the blit target + * \param dstrect the SDL_Rect structure representing the rectangle that is + * copied into + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_BlitScaled + */ +extern DECLSPEC int SDLCALL SDL_LowerBlitScaled + (SDL_Surface * src, SDL_Rect * srcrect, + SDL_Surface * dst, SDL_Rect * dstrect); + +/** + * Set the YUV conversion mode + * + * \since This function is available since SDL 2.0.8. + */ +extern DECLSPEC void SDLCALL SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_MODE mode); + +/** + * Get the YUV conversion mode + * + * \since This function is available since SDL 2.0.8. + */ +extern DECLSPEC SDL_YUV_CONVERSION_MODE SDLCALL SDL_GetYUVConversionMode(void); + +/** + * Get the YUV conversion mode, returning the correct mode for the resolution + * when the current conversion mode is SDL_YUV_CONVERSION_AUTOMATIC + * + * \since This function is available since SDL 2.0.8. + */ +extern DECLSPEC SDL_YUV_CONVERSION_MODE SDLCALL SDL_GetYUVConversionModeForResolution(int width, int height); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_surface_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/include/SDL_system.h b/SDL2-2.30.5/include/SDL_system.h new file mode 100644 index 0000000..ddae4f8 --- /dev/null +++ b/SDL2-2.30.5/include/SDL_system.h @@ -0,0 +1,638 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_system.h + * + * Include file for platform specific SDL API functions + */ + +#ifndef SDL_system_h_ +#define SDL_system_h_ + +#include "SDL_stdinc.h" +#include "SDL_keyboard.h" +#include "SDL_render.h" +#include "SDL_video.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + + +/* Platform specific functions for Windows */ +#if defined(__WIN32__) || defined(__GDK__) + +typedef void (SDLCALL * SDL_WindowsMessageHook)(void *userdata, void *hWnd, unsigned int message, Uint64 wParam, Sint64 lParam); + +/** + * Set a callback for every Windows message, run before TranslateMessage(). + * + * \param callback The SDL_WindowsMessageHook function to call. + * \param userdata a pointer to pass to every iteration of `callback` + * + * \since This function is available since SDL 2.0.4. + */ +extern DECLSPEC void SDLCALL SDL_SetWindowsMessageHook(SDL_WindowsMessageHook callback, void *userdata); + +#endif /* defined(__WIN32__) || defined(__GDK__) */ + +#if defined(__WIN32__) || defined(__WINGDK__) + +/** + * Get the D3D9 adapter index that matches the specified display index. + * + * The returned adapter index can be passed to `IDirect3D9::CreateDevice` and + * controls on which monitor a full screen application will appear. + * + * \param displayIndex the display index for which to get the D3D9 adapter + * index + * \returns the D3D9 adapter index on success or a negative error code on + * failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.1. + */ +extern DECLSPEC int SDLCALL SDL_Direct3D9GetAdapterIndex( int displayIndex ); + +typedef struct IDirect3DDevice9 IDirect3DDevice9; + +/** + * Get the D3D9 device associated with a renderer. + * + * Once you are done using the device, you should release it to avoid a + * resource leak. + * + * \param renderer the renderer from which to get the associated D3D device + * \returns the D3D9 device associated with given renderer or NULL if it is + * not a D3D9 renderer; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.1. + */ +extern DECLSPEC IDirect3DDevice9* SDLCALL SDL_RenderGetD3D9Device(SDL_Renderer * renderer); + +typedef struct ID3D11Device ID3D11Device; + +/** + * Get the D3D11 device associated with a renderer. + * + * Once you are done using the device, you should release it to avoid a + * resource leak. + * + * \param renderer the renderer from which to get the associated D3D11 device + * \returns the D3D11 device associated with given renderer or NULL if it is + * not a D3D11 renderer; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.16. + */ +extern DECLSPEC ID3D11Device* SDLCALL SDL_RenderGetD3D11Device(SDL_Renderer * renderer); + +#endif /* defined(__WIN32__) || defined(__WINGDK__) */ + +#if defined(__WIN32__) || defined(__GDK__) + +typedef struct ID3D12Device ID3D12Device; + +/** + * Get the D3D12 device associated with a renderer. + * + * Once you are done using the device, you should release it to avoid a + * resource leak. + * + * \param renderer the renderer from which to get the associated D3D12 device + * \returns the D3D12 device associated with given renderer or NULL if it is + * not a D3D12 renderer; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.24.0. + */ +extern DECLSPEC ID3D12Device* SDLCALL SDL_RenderGetD3D12Device(SDL_Renderer* renderer); + +#endif /* defined(__WIN32__) || defined(__GDK__) */ + +#if defined(__WIN32__) || defined(__WINGDK__) + +/** + * Get the DXGI Adapter and Output indices for the specified display index. + * + * The DXGI Adapter and Output indices can be passed to `EnumAdapters` and + * `EnumOutputs` respectively to get the objects required to create a DX10 or + * DX11 device and swap chain. + * + * Before SDL 2.0.4 this function did not return a value. Since SDL 2.0.4 it + * returns an SDL_bool. + * + * \param displayIndex the display index for which to get both indices + * \param adapterIndex a pointer to be filled in with the adapter index + * \param outputIndex a pointer to be filled in with the output index + * \returns SDL_TRUE on success or SDL_FALSE on failure; call SDL_GetError() + * for more information. + * + * \since This function is available since SDL 2.0.2. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_DXGIGetOutputInfo( int displayIndex, int *adapterIndex, int *outputIndex ); + +#endif /* defined(__WIN32__) || defined(__WINGDK__) */ + +/* Platform specific functions for Linux */ +#ifdef __LINUX__ + +/** + * Sets the UNIX nice value for a thread. + * + * This uses setpriority() if possible, and RealtimeKit if available. + * + * \param threadID the Unix thread ID to change priority of. + * \param priority The new, Unix-specific, priority value. + * \returns 0 on success, or -1 on error. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC int SDLCALL SDL_LinuxSetThreadPriority(Sint64 threadID, int priority); + +/** + * Sets the priority (not nice level) and scheduling policy for a thread. + * + * This uses setpriority() if possible, and RealtimeKit if available. + * + * \param threadID The Unix thread ID to change priority of. + * \param sdlPriority The new SDL_ThreadPriority value. + * \param schedPolicy The new scheduling policy (SCHED_FIFO, SCHED_RR, + * SCHED_OTHER, etc...) + * \returns 0 on success, or -1 on error. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC int SDLCALL SDL_LinuxSetThreadPriorityAndPolicy(Sint64 threadID, int sdlPriority, int schedPolicy); + +#endif /* __LINUX__ */ + +/* Platform specific functions for iOS */ +#ifdef __IPHONEOS__ + +#define SDL_iOSSetAnimationCallback(window, interval, callback, callbackParam) SDL_iPhoneSetAnimationCallback(window, interval, callback, callbackParam) + +/** + * Use this function to set the animation callback on Apple iOS. + * + * The function prototype for `callback` is: + * + * ```c + * void callback(void* callbackParam); + * ``` + * + * Where its parameter, `callbackParam`, is what was passed as `callbackParam` + * to SDL_iPhoneSetAnimationCallback(). + * + * This function is only available on Apple iOS. + * + * For more information see: + * https://github.com/libsdl-org/SDL/blob/main/docs/README-ios.md + * + * This functions is also accessible using the macro + * SDL_iOSSetAnimationCallback() since SDL 2.0.4. + * + * \param window the window for which the animation callback should be set + * \param interval the number of frames after which **callback** will be + * called + * \param callback the function to call for every frame. + * \param callbackParam a pointer that is passed to `callback`. + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_iPhoneSetEventPump + */ +extern DECLSPEC int SDLCALL SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (SDLCALL *callback)(void*), void *callbackParam); + +#define SDL_iOSSetEventPump(enabled) SDL_iPhoneSetEventPump(enabled) + +/** + * Use this function to enable or disable the SDL event pump on Apple iOS. + * + * This function is only available on Apple iOS. + * + * This functions is also accessible using the macro SDL_iOSSetEventPump() + * since SDL 2.0.4. + * + * \param enabled SDL_TRUE to enable the event pump, SDL_FALSE to disable it + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_iPhoneSetAnimationCallback + */ +extern DECLSPEC void SDLCALL SDL_iPhoneSetEventPump(SDL_bool enabled); + +#endif /* __IPHONEOS__ */ + + +/* Platform specific functions for Android */ +#ifdef __ANDROID__ + +/** + * Get the Android Java Native Interface Environment of the current thread. + * + * This is the JNIEnv one needs to access the Java virtual machine from native + * code, and is needed for many Android APIs to be usable from C. + * + * The prototype of the function in SDL's code actually declare a void* return + * type, even if the implementation returns a pointer to a JNIEnv. The + * rationale being that the SDL headers can avoid including jni.h. + * + * \returns a pointer to Java native interface object (JNIEnv) to which the + * current thread is attached, or 0 on error. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AndroidGetActivity + */ +extern DECLSPEC void * SDLCALL SDL_AndroidGetJNIEnv(void); + +/** + * Retrieve the Java instance of the Android activity class. + * + * The prototype of the function in SDL's code actually declares a void* + * return type, even if the implementation returns a jobject. The rationale + * being that the SDL headers can avoid including jni.h. + * + * The jobject returned by the function is a local reference and must be + * released by the caller. See the PushLocalFrame() and PopLocalFrame() or + * DeleteLocalRef() functions of the Java native interface: + * + * https://docs.oracle.com/javase/1.5.0/docs/guide/jni/spec/functions.html + * + * \returns the jobject representing the instance of the Activity class of the + * Android application, or NULL on error. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AndroidGetJNIEnv + */ +extern DECLSPEC void * SDLCALL SDL_AndroidGetActivity(void); + +/** + * Query Android API level of the current device. + * + * - API level 31: Android 12 + * - API level 30: Android 11 + * - API level 29: Android 10 + * - API level 28: Android 9 + * - API level 27: Android 8.1 + * - API level 26: Android 8.0 + * - API level 25: Android 7.1 + * - API level 24: Android 7.0 + * - API level 23: Android 6.0 + * - API level 22: Android 5.1 + * - API level 21: Android 5.0 + * - API level 20: Android 4.4W + * - API level 19: Android 4.4 + * - API level 18: Android 4.3 + * - API level 17: Android 4.2 + * - API level 16: Android 4.1 + * - API level 15: Android 4.0.3 + * - API level 14: Android 4.0 + * - API level 13: Android 3.2 + * - API level 12: Android 3.1 + * - API level 11: Android 3.0 + * - API level 10: Android 2.3.3 + * + * \returns the Android API level. + * + * \since This function is available since SDL 2.0.12. + */ +extern DECLSPEC int SDLCALL SDL_GetAndroidSDKVersion(void); + +/** + * Query if the application is running on Android TV. + * + * \returns SDL_TRUE if this is Android TV, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.8. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IsAndroidTV(void); + +/** + * Query if the application is running on a Chromebook. + * + * \returns SDL_TRUE if this is a Chromebook, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IsChromebook(void); + +/** + * Query if the application is running on a Samsung DeX docking station. + * + * \returns SDL_TRUE if this is a DeX docking station, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IsDeXMode(void); + +/** + * Trigger the Android system back button behavior. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC void SDLCALL SDL_AndroidBackButton(void); + +/** + See the official Android developer guide for more information: + http://developer.android.com/guide/topics/data/data-storage.html +*/ +#define SDL_ANDROID_EXTERNAL_STORAGE_READ 0x01 +#define SDL_ANDROID_EXTERNAL_STORAGE_WRITE 0x02 + +/** + * Get the path used for internal storage for this application. + * + * This path is unique to your application and cannot be written to by other + * applications. + * + * Your internal storage path is typically: + * `/data/data/your.app.package/files`. + * + * \returns the path used for internal storage or NULL on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AndroidGetExternalStorageState + */ +extern DECLSPEC const char * SDLCALL SDL_AndroidGetInternalStoragePath(void); + +/** + * Get the current state of external storage. + * + * The current state of external storage, a bitmask of these values: + * `SDL_ANDROID_EXTERNAL_STORAGE_READ`, `SDL_ANDROID_EXTERNAL_STORAGE_WRITE`. + * + * If external storage is currently unavailable, this will return 0. + * + * \returns the current state of external storage on success or 0 on failure; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AndroidGetExternalStoragePath + */ +extern DECLSPEC int SDLCALL SDL_AndroidGetExternalStorageState(void); + +/** + * Get the path used for external storage for this application. + * + * This path is unique to your application, but is public and can be written + * to by other applications. + * + * Your external storage path is typically: + * `/storage/sdcard0/Android/data/your.app.package/files`. + * + * \returns the path used for external storage for this application on success + * or NULL on failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AndroidGetExternalStorageState + */ +extern DECLSPEC const char * SDLCALL SDL_AndroidGetExternalStoragePath(void); + +/** + * Request permissions at runtime. + * + * This blocks the calling thread until the permission is granted or denied. + * + * \param permission The permission to request. + * \returns SDL_TRUE if the permission was granted, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.14. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_AndroidRequestPermission(const char *permission); + +/** + * Shows an Android toast notification. + * + * Toasts are a sort of lightweight notification that are unique to Android. + * + * https://developer.android.com/guide/topics/ui/notifiers/toasts + * + * Shows toast in UI thread. + * + * For the `gravity` parameter, choose a value from here, or -1 if you don't + * have a preference: + * + * https://developer.android.com/reference/android/view/Gravity + * + * \param message text message to be shown + * \param duration 0=short, 1=long + * \param gravity where the notification should appear on the screen. + * \param xoffset set this parameter only when gravity >=0 + * \param yoffset set this parameter only when gravity >=0 + * \returns 0 if success, -1 if any error occurs. + * + * \since This function is available since SDL 2.0.16. + */ +extern DECLSPEC int SDLCALL SDL_AndroidShowToast(const char* message, int duration, int gravity, int xoffset, int yoffset); + +/** + * Send a user command to SDLActivity. + * + * Override "boolean onUnhandledMessage(Message msg)" to handle the message. + * + * \param command user command that must be greater or equal to 0x8000 + * \param param user parameter + * + * \since This function is available since SDL 2.0.22. + */ +extern DECLSPEC int SDLCALL SDL_AndroidSendMessage(Uint32 command, int param); + +#endif /* __ANDROID__ */ + +/* Platform specific functions for WinRT */ +#ifdef __WINRT__ + +/** + * \brief WinRT / Windows Phone path types + */ +typedef enum +{ + /** \brief The installed app's root directory. + Files here are likely to be read-only. */ + SDL_WINRT_PATH_INSTALLED_LOCATION, + + /** \brief The app's local data store. Files may be written here */ + SDL_WINRT_PATH_LOCAL_FOLDER, + + /** \brief The app's roaming data store. Unsupported on Windows Phone. + Files written here may be copied to other machines via a network + connection. + */ + SDL_WINRT_PATH_ROAMING_FOLDER, + + /** \brief The app's temporary data store. Unsupported on Windows Phone. + Files written here may be deleted at any time. */ + SDL_WINRT_PATH_TEMP_FOLDER +} SDL_WinRT_Path; + + +/** + * \brief WinRT Device Family + */ +typedef enum +{ + /** \brief Unknown family */ + SDL_WINRT_DEVICEFAMILY_UNKNOWN, + + /** \brief Desktop family*/ + SDL_WINRT_DEVICEFAMILY_DESKTOP, + + /** \brief Mobile family (for example smartphone) */ + SDL_WINRT_DEVICEFAMILY_MOBILE, + + /** \brief XBox family */ + SDL_WINRT_DEVICEFAMILY_XBOX, +} SDL_WinRT_DeviceFamily; + + +/** + * Retrieve a WinRT defined path on the local file system. + * + * Not all paths are available on all versions of Windows. This is especially + * true on Windows Phone. Check the documentation for the given SDL_WinRT_Path + * for more information on which path types are supported where. + * + * Documentation on most app-specific path types on WinRT can be found on + * MSDN, at the URL: + * + * https://msdn.microsoft.com/en-us/library/windows/apps/hh464917.aspx + * + * \param pathType the type of path to retrieve, one of SDL_WinRT_Path + * \returns a UCS-2 string (16-bit, wide-char) containing the path, or NULL if + * the path is not available for any reason; call SDL_GetError() for + * more information. + * + * \since This function is available since SDL 2.0.3. + * + * \sa SDL_WinRTGetFSPathUTF8 + */ +extern DECLSPEC const wchar_t * SDLCALL SDL_WinRTGetFSPathUNICODE(SDL_WinRT_Path pathType); + +/** + * Retrieve a WinRT defined path on the local file system. + * + * Not all paths are available on all versions of Windows. This is especially + * true on Windows Phone. Check the documentation for the given SDL_WinRT_Path + * for more information on which path types are supported where. + * + * Documentation on most app-specific path types on WinRT can be found on + * MSDN, at the URL: + * + * https://msdn.microsoft.com/en-us/library/windows/apps/hh464917.aspx + * + * \param pathType the type of path to retrieve, one of SDL_WinRT_Path + * \returns a UTF-8 string (8-bit, multi-byte) containing the path, or NULL if + * the path is not available for any reason; call SDL_GetError() for + * more information. + * + * \since This function is available since SDL 2.0.3. + * + * \sa SDL_WinRTGetFSPathUNICODE + */ +extern DECLSPEC const char * SDLCALL SDL_WinRTGetFSPathUTF8(SDL_WinRT_Path pathType); + +/** + * Detects the device family of WinRT platform at runtime. + * + * \returns a value from the SDL_WinRT_DeviceFamily enum. + * + * \since This function is available since SDL 2.0.8. + */ +extern DECLSPEC SDL_WinRT_DeviceFamily SDLCALL SDL_WinRTGetDeviceFamily(); + +#endif /* __WINRT__ */ + +/** + * Query if the current device is a tablet. + * + * If SDL can't determine this, it will return SDL_FALSE. + * + * \returns SDL_TRUE if the device is a tablet, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.9. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IsTablet(void); + +/* Functions used by iOS application delegates to notify SDL about state changes */ +extern DECLSPEC void SDLCALL SDL_OnApplicationWillTerminate(void); +extern DECLSPEC void SDLCALL SDL_OnApplicationDidReceiveMemoryWarning(void); +extern DECLSPEC void SDLCALL SDL_OnApplicationWillResignActive(void); +extern DECLSPEC void SDLCALL SDL_OnApplicationDidEnterBackground(void); +extern DECLSPEC void SDLCALL SDL_OnApplicationWillEnterForeground(void); +extern DECLSPEC void SDLCALL SDL_OnApplicationDidBecomeActive(void); +#ifdef __IPHONEOS__ +extern DECLSPEC void SDLCALL SDL_OnApplicationDidChangeStatusBarOrientation(void); +#endif + +/* Functions used only by GDK */ +#if defined(__GDK__) +typedef struct XTaskQueueObject *XTaskQueueHandle; +typedef struct XUser *XUserHandle; + +/** + * Gets a reference to the global async task queue handle for GDK, + * initializing if needed. + * + * Once you are done with the task queue, you should call + * XTaskQueueCloseHandle to reduce the reference count to avoid a resource + * leak. + * + * \param outTaskQueue a pointer to be filled in with task queue handle. + * \returns 0 if success, -1 if any error occurs. + * + * \since This function is available since SDL 2.24.0. + */ +extern DECLSPEC int SDLCALL SDL_GDKGetTaskQueue(XTaskQueueHandle * outTaskQueue); + +/** + * Gets a reference to the default user handle for GDK. + * + * This is effectively a synchronous version of XUserAddAsync, which always + * prefers the default user and allows a sign-in UI. + * + * \param outUserHandle a pointer to be filled in with the default user + * handle. + * \returns 0 if success, -1 if any error occurs. + * + * \since This function is available since SDL 2.28.0. + */ +extern DECLSPEC int SDLCALL SDL_GDKGetDefaultUser(XUserHandle * outUserHandle); + +#endif + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_system_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/include/SDL_syswm.h b/SDL2-2.30.5/include/SDL_syswm.h similarity index 71% rename from SDL2-2.0.12/include/SDL_syswm.h rename to SDL2-2.30.5/include/SDL_syswm.h index e877b2a..7b8bd6e 100644 --- a/SDL2-2.0.12/include/SDL_syswm.h +++ b/SDL2-2.30.5/include/SDL_syswm.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -98,6 +98,10 @@ typedef struct _UIViewController UIViewController; typedef Uint32 GLuint; #endif +#if defined(SDL_VIDEO_VULKAN) || defined(SDL_VIDEO_METAL) +#define SDL_METALVIEW_TAG 255 +#endif + #if defined(SDL_VIDEO_DRIVER_ANDROID) typedef struct ANativeWindow ANativeWindow; typedef void *EGLSurface; @@ -106,8 +110,17 @@ typedef void *EGLSurface; #if defined(SDL_VIDEO_DRIVER_VIVANTE) #include "SDL_egl.h" #endif + +#if defined(SDL_VIDEO_DRIVER_OS2) +#define INCL_WIN +#include +#endif #endif /* SDL_PROTOTYPES_ONLY */ +#if defined(SDL_VIDEO_DRIVER_KMSDRM) +struct gbm_device; +#endif + #include "begin_code.h" /* Set up for C function definitions, even when using C++ */ @@ -133,7 +146,9 @@ typedef enum SDL_SYSWM_ANDROID, SDL_SYSWM_VIVANTE, SDL_SYSWM_OS2, - SDL_SYSWM_HAIKU + SDL_SYSWM_HAIKU, + SDL_SYSWM_KMSDRM, + SDL_SYSWM_RISCOS } SDL_SYSWM_TYPE; /** @@ -186,6 +201,16 @@ struct SDL_SysWMmsg int dummy; /* No Vivante window events yet */ } vivante; +#endif +#if defined(SDL_VIDEO_DRIVER_OS2) + struct + { + BOOL fFrame; /**< TRUE if hwnd is a frame window */ + HWND hwnd; /**< The window receiving the message */ + ULONG msg; /**< The message identifier */ + MPARAM mp1; /**< The first first message parameter */ + MPARAM mp2; /**< The second first message parameter */ + } os2; #endif /* Can't have an empty union */ int dummy; @@ -236,8 +261,12 @@ struct SDL_SysWMinfo #if defined(SDL_VIDEO_DRIVER_COCOA) struct { -#if defined(__OBJC__) && defined(__has_feature) && __has_feature(objc_arc) +#if defined(__OBJC__) && defined(__has_feature) + #if __has_feature(objc_arc) NSWindow __unsafe_unretained *window; /**< The Cocoa window */ + #else + NSWindow *window; /**< The Cocoa window */ + #endif #else NSWindow *window; /**< The Cocoa window */ #endif @@ -246,8 +275,12 @@ struct SDL_SysWMinfo #if defined(SDL_VIDEO_DRIVER_UIKIT) struct { -#if defined(__OBJC__) && defined(__has_feature) && __has_feature(objc_arc) +#if defined(__OBJC__) && defined(__has_feature) + #if __has_feature(objc_arc) UIWindow __unsafe_unretained *window; /**< The UIKit window */ + #else + UIWindow *window; /**< The UIKit window */ + #endif #else UIWindow *window; /**< The UIKit window */ #endif @@ -259,9 +292,14 @@ struct SDL_SysWMinfo #if defined(SDL_VIDEO_DRIVER_WAYLAND) struct { - struct wl_display *display; /**< Wayland display */ - struct wl_surface *surface; /**< Wayland surface */ - struct wl_shell_surface *shell_surface; /**< Wayland shell_surface (window manager handle) */ + struct wl_display *display; /**< Wayland display */ + struct wl_surface *surface; /**< Wayland surface */ + void *shell_surface; /**< DEPRECATED Wayland shell_surface (window manager handle) */ + struct wl_egl_window *egl_window; /**< Wayland EGL window (native window) */ + struct xdg_surface *xdg_surface; /**< Wayland xdg surface (window manager handle) */ + struct xdg_toplevel *xdg_toplevel; /**< Wayland xdg toplevel role */ + struct xdg_popup *xdg_popup; /**< Wayland xdg popup role */ + struct xdg_positioner *xdg_positioner; /**< Wayland xdg positioner, for popup */ } wl; #endif #if defined(SDL_VIDEO_DRIVER_MIR) /* no longer available, left for API/ABI compatibility. Remove in 2.1! */ @@ -280,6 +318,14 @@ struct SDL_SysWMinfo } android; #endif +#if defined(SDL_VIDEO_DRIVER_OS2) + struct + { + HWND hwnd; /**< The window handle */ + HWND hwndFrame; /**< The frame window handle */ + } os2; +#endif + #if defined(SDL_VIDEO_DRIVER_VIVANTE) struct { @@ -288,6 +334,15 @@ struct SDL_SysWMinfo } vivante; #endif +#if defined(SDL_VIDEO_DRIVER_KMSDRM) + struct + { + int dev_index; /**< Device index (ex: the X in /dev/dri/cardX) */ + int drm_fd; /**< DRM FD (unavailable on Vulkan windows) */ + struct gbm_device *gbm_dev; /**< GBM device (unavailable on Vulkan windows) */ + } kmsdrm; +#endif + /* Make sure this union is always 64 bytes (8 64-bit pointers). */ /* Be careful not to overflow this if you add a new target! */ Uint8 dummy[64]; @@ -298,23 +353,23 @@ struct SDL_SysWMinfo typedef struct SDL_SysWMinfo SDL_SysWMinfo; -/* Function prototypes */ + /** - * \brief This function allows access to driver-dependent window information. + * Get driver-specific information about a window. * - * \param window The window about which information is being requested - * \param info This structure must be initialized with the SDL version, and is - * then filled in with information about the given window. + * You must include SDL_syswm.h for the declaration of SDL_SysWMinfo. * - * \return SDL_TRUE if the function is implemented and the version member of - * the \c info struct is valid, SDL_FALSE otherwise. + * The caller must initialize the `info` structure's version by using + * `SDL_VERSION(&info.version)`, and then this function will fill in the rest + * of the structure with information about the given window. * - * You typically use this function like this: - * \code - * SDL_SysWMinfo info; - * SDL_VERSION(&info.version); - * if ( SDL_GetWindowWMInfo(window, &info) ) { ... } - * \endcode + * \param window the window about which information is being requested + * \param info an SDL_SysWMinfo structure filled in with window information + * \returns SDL_TRUE if the function is implemented and the `version` member + * of the `info` struct is valid, or SDL_FALSE if the information + * could not be retrieved; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. */ extern DECLSPEC SDL_bool SDLCALL SDL_GetWindowWMInfo(SDL_Window * window, SDL_SysWMinfo * info); diff --git a/SDL2-2.0.12/include/SDL_test.h b/SDL2-2.30.5/include/SDL_test.h similarity index 97% rename from SDL2-2.0.12/include/SDL_test.h rename to SDL2-2.30.5/include/SDL_test.h index 7095427..e5acbee 100644 --- a/SDL2-2.0.12/include/SDL_test.h +++ b/SDL2-2.30.5/include/SDL_test.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/include/SDL_test_assert.h b/SDL2-2.30.5/include/SDL_test_assert.h similarity index 94% rename from SDL2-2.0.12/include/SDL_test_assert.h rename to SDL2-2.30.5/include/SDL_test_assert.h index 19b9095..4f98335 100644 --- a/SDL2-2.0.12/include/SDL_test_assert.h +++ b/SDL2-2.30.5/include/SDL_test_assert.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -66,7 +66,7 @@ void SDLTest_Assert(int assertCondition, SDL_PRINTF_FORMAT_STRING const char *as * \param assertCondition Evaluated condition or variable to assert; fail (==0) or pass (!=0). * \param assertDescription Message to log with the assert describing it. * - * \returns Returns the assertCondition so it can be used to externally to break execution flow if desired. + * \returns the assertCondition so it can be used to externally to break execution flow if desired. */ int SDLTest_AssertCheck(int assertCondition, SDL_PRINTF_FORMAT_STRING const char *assertDescription, ...) SDL_PRINTF_VARARG_FUNC(2); diff --git a/SDL2-2.0.12/include/SDL_test_common.h b/SDL2-2.30.5/include/SDL_test_common.h similarity index 86% rename from SDL2-2.0.12/include/SDL_test_common.h rename to SDL2-2.30.5/include/SDL_test_common.h index 3ad2030..d977e46 100644 --- a/SDL2-2.0.12/include/SDL_test_common.h +++ b/SDL2-2.30.5/include/SDL_test_common.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -37,6 +37,9 @@ #if defined(__PSP__) #define DEFAULT_WINDOW_WIDTH 480 #define DEFAULT_WINDOW_HEIGHT 272 +#elif defined(__VITA__) +#define DEFAULT_WINDOW_WIDTH 960 +#define DEFAULT_WINDOW_HEIGHT 544 #else #define DEFAULT_WINDOW_WIDTH 640 #define DEFAULT_WINDOW_HEIGHT 480 @@ -47,6 +50,7 @@ #define VERBOSE_RENDER 0x00000004 #define VERBOSE_EVENT 0x00000008 #define VERBOSE_AUDIO 0x00000010 +#define VERBOSE_MOTION 0x00000020 typedef struct { @@ -61,6 +65,7 @@ typedef struct const char *window_title; const char *window_icon; Uint32 window_flags; + SDL_bool flash_on_focus_loss; int window_x; int window_y; int window_w; @@ -110,6 +115,10 @@ typedef struct int gl_minor_version; int gl_debug; int gl_profile_mask; + + /* Additional fields added in 2.0.18 */ + SDL_Rect confine; + } SDLTest_CommonState; #include "begin_code.h" @@ -126,7 +135,7 @@ extern "C" { * \param argv Array of command line parameters * \param flags Flags indicating which subsystem to initialize (i.e. SDL_INIT_VIDEO | SDL_INIT_AUDIO) * - * \returns Returns a newly allocated common state object. + * \returns a newly allocated common state object. */ SDLTest_CommonState *SDLTest_CommonCreateState(char **argv, Uint32 flags); @@ -136,7 +145,7 @@ SDLTest_CommonState *SDLTest_CommonCreateState(char **argv, Uint32 flags); * \param state The common state describing the test window to create. * \param index The index of the argument to process in argv[]. * - * \returns The number of arguments processed (i.e. 1 for --fullscreen, 2 for --video [videodriver], or -1 on error. + * \returns the number of arguments processed (i.e. 1 for --fullscreen, 2 for --video [videodriver], or -1 on error. */ int SDLTest_CommonArg(SDLTest_CommonState * state, int index); @@ -164,7 +173,7 @@ void SDLTest_CommonLogUsage(SDLTest_CommonState * state, const char *argv0, cons * those strings' memory is freed and can no longer be used. * * \param state The common state describing the test window to create. - * \returns String with usage information + * \returns a string with usage information */ const char *SDLTest_CommonUsage(SDLTest_CommonState * state); @@ -173,7 +182,7 @@ const char *SDLTest_CommonUsage(SDLTest_CommonState * state); * * \param state The common state describing the test window to create. * - * \returns True if initialization succeeded, false otherwise + * \returns SDL_TRUE if initialization succeeded, false otherwise */ SDL_bool SDLTest_CommonInit(SDLTest_CommonState * state); @@ -184,7 +193,7 @@ SDL_bool SDLTest_CommonInit(SDLTest_CommonState * state); * \param argc argc, as supplied to SDL_main * \param argv argv, as supplied to SDL_main * - * \returns False if app should quit, true otherwise. + * \returns SDL_FALSE if app should quit, true otherwise. */ SDL_bool SDLTest_CommonDefaultArgs(SDLTest_CommonState * state, const int argc, char **argv); @@ -206,6 +215,15 @@ void SDLTest_CommonEvent(SDLTest_CommonState * state, SDL_Event * event, int *do */ void SDLTest_CommonQuit(SDLTest_CommonState * state); +/** + * \brief Draws various window information (position, size, etc.) to the renderer. + * + * \param renderer The renderer to draw to. + * \param window The window whose information should be displayed. + * \param usedHeight Returns the height used, so the caller can draw more below. + * + */ +void SDLTest_CommonDrawWindowInfo(SDL_Renderer * renderer, SDL_Window * window, int * usedHeight); /* Ends C function definitions when using C++ */ #ifdef __cplusplus diff --git a/SDL2-2.0.12/include/SDL_test_compare.h b/SDL2-2.30.5/include/SDL_test_compare.h similarity index 97% rename from SDL2-2.0.12/include/SDL_test_compare.h rename to SDL2-2.30.5/include/SDL_test_compare.h index 38b22bb..61a38d0 100644 --- a/SDL2-2.0.12/include/SDL_test_compare.h +++ b/SDL2-2.30.5/include/SDL_test_compare.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/include/SDL_test_crc32.h b/SDL2-2.30.5/include/SDL_test_crc32.h similarity index 98% rename from SDL2-2.0.12/include/SDL_test_crc32.h rename to SDL2-2.30.5/include/SDL_test_crc32.h index 611066a..e347831 100644 --- a/SDL2-2.0.12/include/SDL_test_crc32.h +++ b/SDL2-2.30.5/include/SDL_test_crc32.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.30.5/include/SDL_test_font.h b/SDL2-2.30.5/include/SDL_test_font.h new file mode 100644 index 0000000..620c821 --- /dev/null +++ b/SDL2-2.30.5/include/SDL_test_font.h @@ -0,0 +1,168 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_font.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_font_h_ +#define SDL_test_font_h_ + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Function prototypes */ + +#define FONT_CHARACTER_SIZE 8 +#define FONT_LINE_HEIGHT (FONT_CHARACTER_SIZE + 2) + +/** + * \brief Draw a string in the currently set font. + * + * \param renderer The renderer to draw on. + * \param x The X coordinate of the upper left corner of the character. + * \param y The Y coordinate of the upper left corner of the character. + * \param c The character to draw. + * + * \returns 0 on success, -1 on failure. + */ +int SDLTest_DrawCharacter(SDL_Renderer *renderer, int x, int y, Uint32 c); + +/** + * \brief Draw a UTF-8 string in the currently set font. + * + * The font currently only supports characters in the Basic Latin and Latin-1 Supplement sets. + * + * \param renderer The renderer to draw on. + * \param x The X coordinate of the upper left corner of the string. + * \param y The Y coordinate of the upper left corner of the string. + * \param s The string to draw. + * + * \returns 0 on success, -1 on failure. + */ +int SDLTest_DrawString(SDL_Renderer *renderer, int x, int y, const char *s); + +/** + * \brief Data used for multi-line text output + */ +typedef struct SDLTest_TextWindow +{ + SDL_Rect rect; + int current; + int numlines; + char **lines; +} SDLTest_TextWindow; + +/** + * \brief Create a multi-line text output window + * + * \param x The X coordinate of the upper left corner of the window. + * \param y The Y coordinate of the upper left corner of the window. + * \param w The width of the window (currently ignored) + * \param h The height of the window (currently ignored) + * + * \returns the new window, or NULL on failure. + * + * \since This function is available since SDL 2.24.0 + */ +SDLTest_TextWindow *SDLTest_TextWindowCreate(int x, int y, int w, int h); + +/** + * \brief Display a multi-line text output window + * + * This function should be called every frame to display the text + * + * \param textwin The text output window + * \param renderer The renderer to use for display + * + * \since This function is available since SDL 2.24.0 + */ +void SDLTest_TextWindowDisplay(SDLTest_TextWindow *textwin, SDL_Renderer *renderer); + +/** + * \brief Add text to a multi-line text output window + * + * Adds UTF-8 text to the end of the current text. The newline character starts a + * new line of text. The backspace character deletes the last character or, if the + * line is empty, deletes the line and goes to the end of the previous line. + * + * \param textwin The text output window + * \param fmt A printf() style format string + * \param ... additional parameters matching % tokens in the `fmt` string, if any + * + * \since This function is available since SDL 2.24.0 + */ +void SDLTest_TextWindowAddText(SDLTest_TextWindow *textwin, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) SDL_PRINTF_VARARG_FUNC(2); + +/** + * \brief Add text to a multi-line text output window + * + * Adds UTF-8 text to the end of the current text. The newline character starts a + * new line of text. The backspace character deletes the last character or, if the + * line is empty, deletes the line and goes to the end of the previous line. + * + * \param textwin The text output window + * \param text The text to add to the window + * \param len The length, in bytes, of the text to add to the window + * + * \since This function is available since SDL 2.24.0 + */ +void SDLTest_TextWindowAddTextWithLength(SDLTest_TextWindow *textwin, const char *text, size_t len); + +/** + * \brief Clear the text in a multi-line text output window + * + * \param textwin The text output window + * + * \since This function is available since SDL 2.24.0 + */ +void SDLTest_TextWindowClear(SDLTest_TextWindow *textwin); + +/** + * \brief Free the storage associated with a multi-line text output window + * + * \param textwin The text output window + * + * \since This function is available since SDL 2.24.0 + */ +void SDLTest_TextWindowDestroy(SDLTest_TextWindow *textwin); + +/** + * \brief Cleanup textures used by font drawing functions. + */ +void SDLTest_CleanupTextDrawing(void); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_test_font_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/include/SDL_test_fuzzer.h b/SDL2-2.30.5/include/SDL_test_fuzzer.h similarity index 87% rename from SDL2-2.0.12/include/SDL_test_fuzzer.h rename to SDL2-2.30.5/include/SDL_test_fuzzer.h index cb5a17a..a847ccb 100644 --- a/SDL2-2.0.12/include/SDL_test_fuzzer.h +++ b/SDL2-2.30.5/include/SDL_test_fuzzer.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -66,14 +66,14 @@ void SDLTest_FuzzerInit(Uint64 execKey); /** * Returns a random Uint8 * - * \returns Generated integer + * \returns a generated integer */ Uint8 SDLTest_RandomUint8(void); /** * Returns a random Sint8 * - * \returns Generated signed integer + * \returns a generated signed integer */ Sint8 SDLTest_RandomSint8(void); @@ -81,14 +81,14 @@ Sint8 SDLTest_RandomSint8(void); /** * Returns a random Uint16 * - * \returns Generated integer + * \returns a generated integer */ Uint16 SDLTest_RandomUint16(void); /** * Returns a random Sint16 * - * \returns Generated signed integer + * \returns a generated signed integer */ Sint16 SDLTest_RandomSint16(void); @@ -96,7 +96,7 @@ Sint16 SDLTest_RandomSint16(void); /** * Returns a random integer * - * \returns Generated integer + * \returns a generated integer */ Sint32 SDLTest_RandomSint32(void); @@ -104,14 +104,14 @@ Sint32 SDLTest_RandomSint32(void); /** * Returns a random positive integer * - * \returns Generated integer + * \returns a generated integer */ Uint32 SDLTest_RandomUint32(void); /** * Returns random Uint64. * - * \returns Generated integer + * \returns a generated integer */ Uint64 SDLTest_RandomUint64(void); @@ -119,28 +119,28 @@ Uint64 SDLTest_RandomUint64(void); /** * Returns random Sint64. * - * \returns Generated signed integer + * \returns a generated signed integer */ Sint64 SDLTest_RandomSint64(void); /** - * \returns random float in range [0.0 - 1.0[ + * \returns a random float in range [0.0 - 1.0] */ float SDLTest_RandomUnitFloat(void); /** - * \returns random double in range [0.0 - 1.0[ + * \returns a random double in range [0.0 - 1.0] */ double SDLTest_RandomUnitDouble(void); /** - * \returns random float. + * \returns a random float. * */ float SDLTest_RandomFloat(void); /** - * \returns random double. + * \returns a random double. * */ double SDLTest_RandomDouble(void); @@ -162,7 +162,7 @@ double SDLTest_RandomDouble(void); * \param boundary2 Upper boundary limit * \param validDomain Should the generated boundary be valid (=within the bounds) or not? * - * \returns Random boundary value for the given range and domain or 0 with error set + * \returns a random boundary value for the given range and domain or 0 with error set */ Uint8 SDLTest_RandomUint8BoundaryValue(Uint8 boundary1, Uint8 boundary2, SDL_bool validDomain); @@ -183,7 +183,7 @@ Uint8 SDLTest_RandomUint8BoundaryValue(Uint8 boundary1, Uint8 boundary2, SDL_boo * \param boundary2 Upper boundary limit * \param validDomain Should the generated boundary be valid (=within the bounds) or not? * - * \returns Random boundary value for the given range and domain or 0 with error set + * \returns a random boundary value for the given range and domain or 0 with error set */ Uint16 SDLTest_RandomUint16BoundaryValue(Uint16 boundary1, Uint16 boundary2, SDL_bool validDomain); @@ -204,7 +204,7 @@ Uint16 SDLTest_RandomUint16BoundaryValue(Uint16 boundary1, Uint16 boundary2, SDL * \param boundary2 Upper boundary limit * \param validDomain Should the generated boundary be valid (=within the bounds) or not? * - * \returns Random boundary value for the given range and domain or 0 with error set + * \returns a random boundary value for the given range and domain or 0 with error set */ Uint32 SDLTest_RandomUint32BoundaryValue(Uint32 boundary1, Uint32 boundary2, SDL_bool validDomain); @@ -225,7 +225,7 @@ Uint32 SDLTest_RandomUint32BoundaryValue(Uint32 boundary1, Uint32 boundary2, SDL * \param boundary2 Upper boundary limit * \param validDomain Should the generated boundary be valid (=within the bounds) or not? * - * \returns Random boundary value for the given range and domain or 0 with error set + * \returns a random boundary value for the given range and domain or 0 with error set */ Uint64 SDLTest_RandomUint64BoundaryValue(Uint64 boundary1, Uint64 boundary2, SDL_bool validDomain); @@ -246,7 +246,7 @@ Uint64 SDLTest_RandomUint64BoundaryValue(Uint64 boundary1, Uint64 boundary2, SDL * \param boundary2 Upper boundary limit * \param validDomain Should the generated boundary be valid (=within the bounds) or not? * - * \returns Random boundary value for the given range and domain or SINT8_MIN with error set + * \returns a random boundary value for the given range and domain or SINT8_MIN with error set */ Sint8 SDLTest_RandomSint8BoundaryValue(Sint8 boundary1, Sint8 boundary2, SDL_bool validDomain); @@ -268,7 +268,7 @@ Sint8 SDLTest_RandomSint8BoundaryValue(Sint8 boundary1, Sint8 boundary2, SDL_boo * \param boundary2 Upper boundary limit * \param validDomain Should the generated boundary be valid (=within the bounds) or not? * - * \returns Random boundary value for the given range and domain or SINT16_MIN with error set + * \returns a random boundary value for the given range and domain or SINT16_MIN with error set */ Sint16 SDLTest_RandomSint16BoundaryValue(Sint16 boundary1, Sint16 boundary2, SDL_bool validDomain); @@ -289,7 +289,7 @@ Sint16 SDLTest_RandomSint16BoundaryValue(Sint16 boundary1, Sint16 boundary2, SDL * \param boundary2 Upper boundary limit * \param validDomain Should the generated boundary be valid (=within the bounds) or not? * - * \returns Random boundary value for the given range and domain or SINT32_MIN with error set + * \returns a random boundary value for the given range and domain or SINT32_MIN with error set */ Sint32 SDLTest_RandomSint32BoundaryValue(Sint32 boundary1, Sint32 boundary2, SDL_bool validDomain); @@ -310,7 +310,7 @@ Sint32 SDLTest_RandomSint32BoundaryValue(Sint32 boundary1, Sint32 boundary2, SDL * \param boundary2 Upper boundary limit * \param validDomain Should the generated boundary be valid (=within the bounds) or not? * - * \returns Random boundary value for the given range and domain or SINT64_MIN with error set + * \returns a random boundary value for the given range and domain or SINT64_MIN with error set */ Sint64 SDLTest_RandomSint64BoundaryValue(Sint64 boundary1, Sint64 boundary2, SDL_bool validDomain); @@ -324,7 +324,7 @@ Sint64 SDLTest_RandomSint64BoundaryValue(Sint64 boundary1, Sint64 boundary2, SDL * \param min Minimum inclusive value of returned random number * \param max Maximum inclusive value of returned random number * - * \returns Generated random integer in range + * \returns a generated random integer in range */ Sint32 SDLTest_RandomIntegerInRange(Sint32 min, Sint32 max); @@ -336,7 +336,7 @@ Sint32 SDLTest_RandomIntegerInRange(Sint32 min, Sint32 max); * * Note: Returned string needs to be deallocated. * - * \returns Newly allocated random string; or NULL if length was invalid or string could not be allocated. + * \returns a newly allocated random string; or NULL if length was invalid or string could not be allocated. */ char * SDLTest_RandomAsciiString(void); @@ -350,7 +350,7 @@ char * SDLTest_RandomAsciiString(void); * * \param maxLength The maximum length of the generated string. * - * \returns Newly allocated random string; or NULL if maxLength was invalid or string could not be allocated. + * \returns a newly allocated random string; or NULL if maxLength was invalid or string could not be allocated. */ char * SDLTest_RandomAsciiStringWithMaximumLength(int maxLength); @@ -364,12 +364,14 @@ char * SDLTest_RandomAsciiStringWithMaximumLength(int maxLength); * * \param size The length of the generated string * - * \returns Newly allocated random string; or NULL if size was invalid or string could not be allocated. + * \returns a newly allocated random string; or NULL if size was invalid or string could not be allocated. */ char * SDLTest_RandomAsciiStringOfSize(int size); /** - * Returns the invocation count for the fuzzer since last ...FuzzerInit. + * Get the invocation count for the fuzzer since last ...FuzzerInit. + * + * \returns the invocation count. */ int SDLTest_GetFuzzerInvocationCount(void); diff --git a/SDL2-2.0.12/include/SDL_test_harness.h b/SDL2-2.30.5/include/SDL_test_harness.h similarity index 94% rename from SDL2-2.0.12/include/SDL_test_harness.h rename to SDL2-2.30.5/include/SDL_test_harness.h index 97d9812..bd9e4f8 100644 --- a/SDL2-2.0.12/include/SDL_test_harness.h +++ b/SDL2-2.30.5/include/SDL_test_harness.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -76,9 +76,9 @@ typedef struct SDLTest_TestCaseReference { /* !< Func2Stress */ SDLTest_TestCaseFp testCase; /* !< Short name (or function name) "Func2Stress" */ - char *name; + const char *name; /* !< Long name or full description "This test pushes func2() to the limit." */ - char *description; + const char *description; /* !< Set to TEST_ENABLED or TEST_DISABLED (test won't be run) */ int enabled; } SDLTest_TestCaseReference; @@ -88,7 +88,7 @@ typedef struct SDLTest_TestCaseReference { */ typedef struct SDLTest_TestSuiteReference { /* !< "PlatformSuite" */ - char *name; + const char *name; /* !< The function that is run before each test. NULL skips. */ SDLTest_TestCaseSetUpFp testSetUp; /* !< The test cases that are run as part of the suite. Last item should be NULL. */ @@ -105,7 +105,7 @@ typedef struct SDLTest_TestSuiteReference { * * \param length The length of the seed string to generate * - * \returns The generated seed string + * \returns the generated seed string */ char *SDLTest_GenerateRunSeed(const int length); @@ -118,7 +118,7 @@ char *SDLTest_GenerateRunSeed(const int length); * \param filter Filter specification. NULL disables. Case sensitive. * \param testIterations Number of iterations to run each test case. * - * \returns Test run result; 0 when all tests passed, 1 if any tests failed. + * \returns the test run result: 0 when all tests passed, 1 if any tests failed. */ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *userRunSeed, Uint64 userExecKey, const char *filter, int testIterations); diff --git a/SDL2-2.0.12/include/SDL_test_images.h b/SDL2-2.30.5/include/SDL_test_images.h similarity index 97% rename from SDL2-2.0.12/include/SDL_test_images.h rename to SDL2-2.30.5/include/SDL_test_images.h index 1cc3ee2..b5bcb0a 100644 --- a/SDL2-2.0.12/include/SDL_test_images.h +++ b/SDL2-2.30.5/include/SDL_test_images.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/include/SDL_test_log.h b/SDL2-2.30.5/include/SDL_test_log.h similarity index 96% rename from SDL2-2.0.12/include/SDL_test_log.h rename to SDL2-2.30.5/include/SDL_test_log.h index 6066f90..ea9ae5e 100644 --- a/SDL2-2.0.12/include/SDL_test_log.h +++ b/SDL2-2.30.5/include/SDL_test_log.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/include/SDL_test_md5.h b/SDL2-2.30.5/include/SDL_test_md5.h similarity index 98% rename from SDL2-2.0.12/include/SDL_test_md5.h rename to SDL2-2.30.5/include/SDL_test_md5.h index b1c51d9..3764b04 100644 --- a/SDL2-2.0.12/include/SDL_test_md5.h +++ b/SDL2-2.30.5/include/SDL_test_md5.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/include/SDL_test_memory.h b/SDL2-2.30.5/include/SDL_test_memory.h similarity index 96% rename from SDL2-2.0.12/include/SDL_test_memory.h rename to SDL2-2.30.5/include/SDL_test_memory.h index df69f93..9bd1432 100644 --- a/SDL2-2.0.12/include/SDL_test_memory.h +++ b/SDL2-2.30.5/include/SDL_test_memory.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/include/SDL_test_random.h b/SDL2-2.30.5/include/SDL_test_random.h similarity index 96% rename from SDL2-2.0.12/include/SDL_test_random.h rename to SDL2-2.30.5/include/SDL_test_random.h index 9404e9d..344646a 100644 --- a/SDL2-2.0.12/include/SDL_test_random.h +++ b/SDL2-2.30.5/include/SDL_test_random.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -98,7 +98,7 @@ extern "C" { * * \param rndContext pointer to context structure * - * \returns A random number (32bit unsigned integer) + * \returns a random number (32bit unsigned integer) * */ unsigned int SDLTest_Random(SDLTest_RandomContext *rndContext); diff --git a/SDL2-2.30.5/include/SDL_thread.h b/SDL2-2.30.5/include/SDL_thread.h new file mode 100644 index 0000000..dc7f536 --- /dev/null +++ b/SDL2-2.30.5/include/SDL_thread.h @@ -0,0 +1,464 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#ifndef SDL_thread_h_ +#define SDL_thread_h_ + +/** + * \file SDL_thread.h + * + * Header for the SDL thread management routines. + */ + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +/* Thread synchronization primitives */ +#include "SDL_atomic.h" +#include "SDL_mutex.h" + +#if (defined(__WIN32__) || defined(__GDK__)) && !defined(__WINRT__) +#include /* _beginthreadex() and _endthreadex() */ +#endif +#if defined(__OS2__) /* for _beginthread() and _endthread() */ +#ifndef __EMX__ +#include +#else +#include +#endif +#endif + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* The SDL thread structure, defined in SDL_thread.c */ +struct SDL_Thread; +typedef struct SDL_Thread SDL_Thread; + +/* The SDL thread ID */ +typedef unsigned long SDL_threadID; + +/* Thread local storage ID, 0 is the invalid ID */ +typedef unsigned int SDL_TLSID; + +/** + * The SDL thread priority. + * + * SDL will make system changes as necessary in order to apply the thread priority. + * Code which attempts to control thread state related to priority should be aware + * that calling SDL_SetThreadPriority may alter such state. + * SDL_HINT_THREAD_PRIORITY_POLICY can be used to control aspects of this behavior. + * + * \note On many systems you require special privileges to set high or time critical priority. + */ +typedef enum { + SDL_THREAD_PRIORITY_LOW, + SDL_THREAD_PRIORITY_NORMAL, + SDL_THREAD_PRIORITY_HIGH, + SDL_THREAD_PRIORITY_TIME_CRITICAL +} SDL_ThreadPriority; + +/** + * The function passed to SDL_CreateThread(). + * + * \param data what was passed as `data` to SDL_CreateThread() + * \returns a value that can be reported through SDL_WaitThread(). + */ +typedef int (SDLCALL * SDL_ThreadFunction) (void *data); + + +#if (defined(__WIN32__) || defined(__GDK__)) && !defined(__WINRT__) +/** + * \file SDL_thread.h + * + * We compile SDL into a DLL. This means, that it's the DLL which + * creates a new thread for the calling process with the SDL_CreateThread() + * API. There is a problem with this, that only the RTL of the SDL2.DLL will + * be initialized for those threads, and not the RTL of the calling + * application! + * + * To solve this, we make a little hack here. + * + * We'll always use the caller's _beginthread() and _endthread() APIs to + * start a new thread. This way, if it's the SDL2.DLL which uses this API, + * then the RTL of SDL2.DLL will be used to create the new thread, and if it's + * the application, then the RTL of the application will be used. + * + * So, in short: + * Always use the _beginthread() and _endthread() of the calling runtime + * library! + */ +#define SDL_PASSED_BEGINTHREAD_ENDTHREAD + +typedef uintptr_t (__cdecl * pfnSDL_CurrentBeginThread) + (void *, unsigned, unsigned (__stdcall *func)(void *), + void * /*arg*/, unsigned, unsigned * /* threadID */); +typedef void (__cdecl * pfnSDL_CurrentEndThread) (unsigned code); + +#ifndef SDL_beginthread +#define SDL_beginthread _beginthreadex +#endif +#ifndef SDL_endthread +#define SDL_endthread _endthreadex +#endif + +extern DECLSPEC SDL_Thread *SDLCALL +SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data, + pfnSDL_CurrentBeginThread pfnBeginThread, + pfnSDL_CurrentEndThread pfnEndThread); + +extern DECLSPEC SDL_Thread *SDLCALL +SDL_CreateThreadWithStackSize(SDL_ThreadFunction fn, + const char *name, const size_t stacksize, void *data, + pfnSDL_CurrentBeginThread pfnBeginThread, + pfnSDL_CurrentEndThread pfnEndThread); + + +#if defined(SDL_CreateThread) && SDL_DYNAMIC_API +#undef SDL_CreateThread +#define SDL_CreateThread(fn, name, data) SDL_CreateThread_REAL(fn, name, data, (pfnSDL_CurrentBeginThread)SDL_beginthread, (pfnSDL_CurrentEndThread)SDL_endthread) +#undef SDL_CreateThreadWithStackSize +#define SDL_CreateThreadWithStackSize(fn, name, stacksize, data) SDL_CreateThreadWithStackSize_REAL(fn, name, stacksize, data, (pfnSDL_CurrentBeginThread)SDL_beginthread, (pfnSDL_CurrentEndThread)SDL_endthread) +#else +#define SDL_CreateThread(fn, name, data) SDL_CreateThread(fn, name, data, (pfnSDL_CurrentBeginThread)SDL_beginthread, (pfnSDL_CurrentEndThread)SDL_endthread) +#define SDL_CreateThreadWithStackSize(fn, name, stacksize, data) SDL_CreateThreadWithStackSize(fn, name, stacksize, data, (pfnSDL_CurrentBeginThread)SDL_beginthread, (pfnSDL_CurrentEndThread)SDL_endthread) +#endif + +#elif defined(__OS2__) +/* + * just like the windows case above: We compile SDL2 + * into a dll with Watcom's runtime statically linked. + */ +#define SDL_PASSED_BEGINTHREAD_ENDTHREAD + +typedef int (*pfnSDL_CurrentBeginThread)(void (*func)(void *), void *, unsigned, void * /*arg*/); +typedef void (*pfnSDL_CurrentEndThread)(void); + +#ifndef SDL_beginthread +#define SDL_beginthread _beginthread +#endif +#ifndef SDL_endthread +#define SDL_endthread _endthread +#endif + +extern DECLSPEC SDL_Thread *SDLCALL +SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data, + pfnSDL_CurrentBeginThread pfnBeginThread, + pfnSDL_CurrentEndThread pfnEndThread); +extern DECLSPEC SDL_Thread *SDLCALL +SDL_CreateThreadWithStackSize(SDL_ThreadFunction fn, const char *name, const size_t stacksize, void *data, + pfnSDL_CurrentBeginThread pfnBeginThread, + pfnSDL_CurrentEndThread pfnEndThread); + +#if defined(SDL_CreateThread) && SDL_DYNAMIC_API +#undef SDL_CreateThread +#define SDL_CreateThread(fn, name, data) SDL_CreateThread_REAL(fn, name, data, (pfnSDL_CurrentBeginThread)SDL_beginthread, (pfnSDL_CurrentEndThread)SDL_endthread) +#undef SDL_CreateThreadWithStackSize +#define SDL_CreateThreadWithStackSize(fn, name, stacksize, data) SDL_CreateThreadWithStackSize_REAL(fn, name, stacksize, data, (pfnSDL_CurrentBeginThread)SDL_beginthread, (pfnSDL_CurrentEndThread)SDL_endthread) +#else +#define SDL_CreateThread(fn, name, data) SDL_CreateThread(fn, name, data, (pfnSDL_CurrentBeginThread)SDL_beginthread, (pfnSDL_CurrentEndThread)SDL_endthread) +#define SDL_CreateThreadWithStackSize(fn, name, stacksize, data) SDL_CreateThreadWithStackSize(fn, name, stacksize, data, (pfnSDL_CurrentBeginThread)SDL_beginthread, (pfnSDL_CurrentEndThread)SDL_endthread) +#endif + +#else + +/** + * Create a new thread with a default stack size. + * + * This is equivalent to calling: + * + * ```c + * SDL_CreateThreadWithStackSize(fn, name, 0, data); + * ``` + * + * \param fn the SDL_ThreadFunction function to call in the new thread + * \param name the name of the thread + * \param data a pointer that is passed to `fn` + * \returns an opaque pointer to the new thread object on success, NULL if the + * new thread could not be created; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateThreadWithStackSize + * \sa SDL_WaitThread + */ +extern DECLSPEC SDL_Thread *SDLCALL +SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data); + +/** + * Create a new thread with a specific stack size. + * + * SDL makes an attempt to report `name` to the system, so that debuggers can + * display it. Not all platforms support this. + * + * Thread naming is a little complicated: Most systems have very small limits + * for the string length (Haiku has 32 bytes, Linux currently has 16, Visual + * C++ 6.0 has _nine_!), and possibly other arbitrary rules. You'll have to + * see what happens with your system's debugger. The name should be UTF-8 (but + * using the naming limits of C identifiers is a better bet). There are no + * requirements for thread naming conventions, so long as the string is + * null-terminated UTF-8, but these guidelines are helpful in choosing a name: + * + * https://stackoverflow.com/questions/149932/naming-conventions-for-threads + * + * If a system imposes requirements, SDL will try to munge the string for it + * (truncate, etc), but the original string contents will be available from + * SDL_GetThreadName(). + * + * The size (in bytes) of the new stack can be specified. Zero means "use the + * system default" which might be wildly different between platforms. x86 + * Linux generally defaults to eight megabytes, an embedded device might be a + * few kilobytes instead. You generally need to specify a stack that is a + * multiple of the system's page size (in many cases, this is 4 kilobytes, but + * check your system documentation). + * + * In SDL 2.1, stack size will be folded into the original SDL_CreateThread + * function, but for backwards compatibility, this is currently a separate + * function. + * + * \param fn the SDL_ThreadFunction function to call in the new thread + * \param name the name of the thread + * \param stacksize the size, in bytes, to allocate for the new thread stack. + * \param data a pointer that is passed to `fn` + * \returns an opaque pointer to the new thread object on success, NULL if the + * new thread could not be created; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.9. + * + * \sa SDL_WaitThread + */ +extern DECLSPEC SDL_Thread *SDLCALL +SDL_CreateThreadWithStackSize(SDL_ThreadFunction fn, const char *name, const size_t stacksize, void *data); + +#endif + +/** + * Get the thread name as it was specified in SDL_CreateThread(). + * + * This is internal memory, not to be freed by the caller, and remains valid + * until the specified thread is cleaned up by SDL_WaitThread(). + * + * \param thread the thread to query + * \returns a pointer to a UTF-8 string that names the specified thread, or + * NULL if it doesn't have a name. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateThread + */ +extern DECLSPEC const char *SDLCALL SDL_GetThreadName(SDL_Thread *thread); + +/** + * Get the thread identifier for the current thread. + * + * This thread identifier is as reported by the underlying operating system. + * If SDL is running on a platform that does not support threads the return + * value will always be zero. + * + * This function also returns a valid thread ID when called from the main + * thread. + * + * \returns the ID of the current thread. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetThreadID + */ +extern DECLSPEC SDL_threadID SDLCALL SDL_ThreadID(void); + +/** + * Get the thread identifier for the specified thread. + * + * This thread identifier is as reported by the underlying operating system. + * If SDL is running on a platform that does not support threads the return + * value will always be zero. + * + * \param thread the thread to query + * \returns the ID of the specified thread, or the ID of the current thread if + * `thread` is NULL. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ThreadID + */ +extern DECLSPEC SDL_threadID SDLCALL SDL_GetThreadID(SDL_Thread * thread); + +/** + * Set the priority for the current thread. + * + * Note that some platforms will not let you alter the priority (or at least, + * promote the thread to a higher priority) at all, and some require you to be + * an administrator account. Be prepared for this to fail. + * + * \param priority the SDL_ThreadPriority to set + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC int SDLCALL SDL_SetThreadPriority(SDL_ThreadPriority priority); + +/** + * Wait for a thread to finish. + * + * Threads that haven't been detached will remain (as a "zombie") until this + * function cleans them up. Not doing so is a resource leak. + * + * Once a thread has been cleaned up through this function, the SDL_Thread + * that references it becomes invalid and should not be referenced again. As + * such, only one thread may call SDL_WaitThread() on another. + * + * The return code for the thread function is placed in the area pointed to by + * `status`, if `status` is not NULL. + * + * You may not wait on a thread that has been used in a call to + * SDL_DetachThread(). Use either that function or this one, but not both, or + * behavior is undefined. + * + * It is safe to pass a NULL thread to this function; it is a no-op. + * + * Note that the thread pointer is freed by this function and is not valid + * afterward. + * + * \param thread the SDL_Thread pointer that was returned from the + * SDL_CreateThread() call that started this thread + * \param status pointer to an integer that will receive the value returned + * from the thread function by its 'return', or NULL to not + * receive such value back. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateThread + * \sa SDL_DetachThread + */ +extern DECLSPEC void SDLCALL SDL_WaitThread(SDL_Thread * thread, int *status); + +/** + * Let a thread clean up on exit without intervention. + * + * A thread may be "detached" to signify that it should not remain until + * another thread has called SDL_WaitThread() on it. Detaching a thread is + * useful for long-running threads that nothing needs to synchronize with or + * further manage. When a detached thread is done, it simply goes away. + * + * There is no way to recover the return code of a detached thread. If you + * need this, don't detach the thread and instead use SDL_WaitThread(). + * + * Once a thread is detached, you should usually assume the SDL_Thread isn't + * safe to reference again, as it will become invalid immediately upon the + * detached thread's exit, instead of remaining until someone has called + * SDL_WaitThread() to finally clean it up. As such, don't detach the same + * thread more than once. + * + * If a thread has already exited when passed to SDL_DetachThread(), it will + * stop waiting for a call to SDL_WaitThread() and clean up immediately. It is + * not safe to detach a thread that might be used with SDL_WaitThread(). + * + * You may not call SDL_WaitThread() on a thread that has been detached. Use + * either that function or this one, but not both, or behavior is undefined. + * + * It is safe to pass NULL to this function; it is a no-op. + * + * \param thread the SDL_Thread pointer that was returned from the + * SDL_CreateThread() call that started this thread + * + * \since This function is available since SDL 2.0.2. + * + * \sa SDL_CreateThread + * \sa SDL_WaitThread + */ +extern DECLSPEC void SDLCALL SDL_DetachThread(SDL_Thread * thread); + +/** + * Create a piece of thread-local storage. + * + * This creates an identifier that is globally visible to all threads but + * refers to data that is thread-specific. + * + * \returns the newly created thread local storage identifier or 0 on error. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_TLSGet + * \sa SDL_TLSSet + */ +extern DECLSPEC SDL_TLSID SDLCALL SDL_TLSCreate(void); + +/** + * Get the current thread's value associated with a thread local storage ID. + * + * \param id the thread local storage ID + * \returns the value associated with the ID for the current thread or NULL if + * no value has been set; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_TLSCreate + * \sa SDL_TLSSet + */ +extern DECLSPEC void * SDLCALL SDL_TLSGet(SDL_TLSID id); + +/** + * Set the current thread's value associated with a thread local storage ID. + * + * The function prototype for `destructor` is: + * + * ```c + * void destructor(void *value) + * ``` + * + * where its parameter `value` is what was passed as `value` to SDL_TLSSet(). + * + * \param id the thread local storage ID + * \param value the value to associate with the ID for the current thread + * \param destructor a function called when the thread exits, to free the + * value + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_TLSCreate + * \sa SDL_TLSGet + */ +extern DECLSPEC int SDLCALL SDL_TLSSet(SDL_TLSID id, const void *value, void (SDLCALL *destructor)(void*)); + +/** + * Cleanup all TLS data for this thread. + * + * \since This function is available since SDL 2.0.16. + */ +extern DECLSPEC void SDLCALL SDL_TLSCleanup(void); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_thread_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/include/SDL_timer.h b/SDL2-2.30.5/include/SDL_timer.h new file mode 100644 index 0000000..8123e43 --- /dev/null +++ b/SDL2-2.30.5/include/SDL_timer.h @@ -0,0 +1,222 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#ifndef SDL_timer_h_ +#define SDL_timer_h_ + +/** + * \file SDL_timer.h + * + * Header for the SDL time management routines. + */ + +#include "SDL_stdinc.h" +#include "SDL_error.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Get the number of milliseconds since SDL library initialization. + * + * This value wraps if the program runs for more than ~49 days. + * + * This function is not recommended as of SDL 2.0.18; use SDL_GetTicks64() + * instead, where the value doesn't wrap every ~49 days. There are places in + * SDL where we provide a 32-bit timestamp that can not change without + * breaking binary compatibility, though, so this function isn't officially + * deprecated. + * + * \returns an unsigned 32-bit value representing the number of milliseconds + * since the SDL library initialized. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_TICKS_PASSED + */ +extern DECLSPEC Uint32 SDLCALL SDL_GetTicks(void); + +/** + * Get the number of milliseconds since SDL library initialization. + * + * Note that you should not use the SDL_TICKS_PASSED macro with values + * returned by this function, as that macro does clever math to compensate for + * the 32-bit overflow every ~49 days that SDL_GetTicks() suffers from. 64-bit + * values from this function can be safely compared directly. + * + * For example, if you want to wait 100 ms, you could do this: + * + * ```c + * const Uint64 timeout = SDL_GetTicks64() + 100; + * while (SDL_GetTicks64() < timeout) { + * // ... do work until timeout has elapsed + * } + * ``` + * + * \returns an unsigned 64-bit value representing the number of milliseconds + * since the SDL library initialized. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC Uint64 SDLCALL SDL_GetTicks64(void); + +/** + * Compare 32-bit SDL ticks values, and return true if `A` has passed `B`. + * + * This should be used with results from SDL_GetTicks(), as this macro + * attempts to deal with the 32-bit counter wrapping back to zero every ~49 + * days, but should _not_ be used with SDL_GetTicks64(), which does not have + * that problem. + * + * For example, with SDL_GetTicks(), if you want to wait 100 ms, you could + * do this: + * + * ```c + * const Uint32 timeout = SDL_GetTicks() + 100; + * while (!SDL_TICKS_PASSED(SDL_GetTicks(), timeout)) { + * // ... do work until timeout has elapsed + * } + * ``` + * + * Note that this does not handle tick differences greater + * than 2^31 so take care when using the above kind of code + * with large timeout delays (tens of days). + */ +#define SDL_TICKS_PASSED(A, B) ((Sint32)((B) - (A)) <= 0) + +/** + * Get the current value of the high resolution counter. + * + * This function is typically used for profiling. + * + * The counter values are only meaningful relative to each other. Differences + * between values can be converted to times by using + * SDL_GetPerformanceFrequency(). + * + * \returns the current counter value. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetPerformanceFrequency + */ +extern DECLSPEC Uint64 SDLCALL SDL_GetPerformanceCounter(void); + +/** + * Get the count per second of the high resolution counter. + * + * \returns a platform-specific count per second. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetPerformanceCounter + */ +extern DECLSPEC Uint64 SDLCALL SDL_GetPerformanceFrequency(void); + +/** + * Wait a specified number of milliseconds before returning. + * + * This function waits a specified number of milliseconds before returning. It + * waits at least the specified time, but possibly longer due to OS + * scheduling. + * + * \param ms the number of milliseconds to delay + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC void SDLCALL SDL_Delay(Uint32 ms); + +/** + * Function prototype for the timer callback function. + * + * The callback function is passed the current timer interval and returns + * the next timer interval. If the returned value is the same as the one + * passed in, the periodic alarm continues, otherwise a new alarm is + * scheduled. If the callback returns 0, the periodic alarm is cancelled. + */ +typedef Uint32 (SDLCALL * SDL_TimerCallback) (Uint32 interval, void *param); + +/** + * Definition of the timer ID type. + */ +typedef int SDL_TimerID; + +/** + * Call a callback function at a future time. + * + * If you use this function, you must pass `SDL_INIT_TIMER` to SDL_Init(). + * + * The callback function is passed the current timer interval and the user + * supplied parameter from the SDL_AddTimer() call and should return the next + * timer interval. If the value returned from the callback is 0, the timer is + * canceled. + * + * The callback is run on a separate thread. + * + * Timers take into account the amount of time it took to execute the + * callback. For example, if the callback took 250 ms to execute and returned + * 1000 (ms), the timer would only wait another 750 ms before its next + * iteration. + * + * Timing may be inexact due to OS scheduling. Be sure to note the current + * time with SDL_GetTicks() or SDL_GetPerformanceCounter() in case your + * callback needs to adjust for variances. + * + * \param interval the timer delay, in milliseconds, passed to `callback` + * \param callback the SDL_TimerCallback function to call when the specified + * `interval` elapses + * \param param a pointer that is passed to `callback` + * \returns a timer ID or 0 if an error occurs; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RemoveTimer + */ +extern DECLSPEC SDL_TimerID SDLCALL SDL_AddTimer(Uint32 interval, + SDL_TimerCallback callback, + void *param); + +/** + * Remove a timer created with SDL_AddTimer(). + * + * \param id the ID of the timer to remove + * \returns SDL_TRUE if the timer is removed or SDL_FALSE if the timer wasn't + * found. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_AddTimer + */ +extern DECLSPEC SDL_bool SDLCALL SDL_RemoveTimer(SDL_TimerID id); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_timer_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/include/SDL_touch.h b/SDL2-2.30.5/include/SDL_touch.h similarity index 56% rename from SDL2-2.0.12/include/SDL_touch.h rename to SDL2-2.30.5/include/SDL_touch.h index fa5a37c..f6a5db4 100644 --- a/SDL2-2.0.12/include/SDL_touch.h +++ b/SDL2-2.30.5/include/SDL_touch.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -64,30 +64,78 @@ typedef struct SDL_Finger #define SDL_MOUSE_TOUCHID ((Sint64)-1) -/* Function prototypes */ - /** - * \brief Get the number of registered touch devices. + * Get the number of registered touch devices. + * + * On some platforms SDL first sees the touch device if it was actually used. + * Therefore SDL_GetNumTouchDevices() may return 0 although devices are + * available. After using all devices at least once the number will be + * correct. + * + * This was fixed for Android in SDL 2.0.1. + * + * \returns the number of registered touch devices. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetTouchDevice */ extern DECLSPEC int SDLCALL SDL_GetNumTouchDevices(void); /** - * \brief Get the touch ID with the given index, or 0 if the index is invalid. + * Get the touch ID with the given index. + * + * \param index the touch device index + * \returns the touch ID with the given index on success or 0 if the index is + * invalid; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetNumTouchDevices */ extern DECLSPEC SDL_TouchID SDLCALL SDL_GetTouchDevice(int index); /** - * \brief Get the type of the given touch device. + * Get the touch device name as reported from the driver or NULL if the index + * is invalid. + * + * \since This function is available since SDL 2.0.22. + */ +extern DECLSPEC const char* SDLCALL SDL_GetTouchName(int index); + +/** + * Get the type of the given touch device. + * + * \since This function is available since SDL 2.0.10. */ extern DECLSPEC SDL_TouchDeviceType SDLCALL SDL_GetTouchDeviceType(SDL_TouchID touchID); /** - * \brief Get the number of active fingers for a given touch device. + * Get the number of active fingers for a given touch device. + * + * \param touchID the ID of a touch device + * \returns the number of active fingers for a given touch device on success + * or 0 on failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetTouchFinger */ extern DECLSPEC int SDLCALL SDL_GetNumTouchFingers(SDL_TouchID touchID); /** - * \brief Get the finger object of the given touch, with the given index. + * Get the finger object for specified touch device ID and finger index. + * + * The returned resource is owned by SDL and should not be deallocated. + * + * \param touchID the ID of the requested touch device + * \param index the index of the requested finger + * \returns a pointer to the SDL_Finger object or NULL if no object at the + * given ID and index could be found. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_RecordGesture */ extern DECLSPEC SDL_Finger * SDLCALL SDL_GetTouchFinger(SDL_TouchID touchID, int index); diff --git a/SDL2-2.0.12/include/SDL_types.h b/SDL2-2.30.5/include/SDL_types.h similarity index 94% rename from SDL2-2.0.12/include/SDL_types.h rename to SDL2-2.30.5/include/SDL_types.h index b6bb571..e8d33c6 100644 --- a/SDL2-2.0.12/include/SDL_types.h +++ b/SDL2-2.30.5/include/SDL_types.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.30.5/include/SDL_version.h b/SDL2-2.30.5/include/SDL_version.h new file mode 100644 index 0000000..0043660 --- /dev/null +++ b/SDL2-2.30.5/include/SDL_version.h @@ -0,0 +1,204 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_version.h + * + * This header defines the current SDL version. + */ + +#ifndef SDL_version_h_ +#define SDL_version_h_ + +#include "SDL_stdinc.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Information about the version of SDL in use. + * + * Represents the library's version as three levels: major revision + * (increments with massive changes, additions, and enhancements), + * minor revision (increments with backwards-compatible changes to the + * major revision), and patchlevel (increments with fixes to the minor + * revision). + * + * \sa SDL_VERSION + * \sa SDL_GetVersion + */ +typedef struct SDL_version +{ + Uint8 major; /**< major version */ + Uint8 minor; /**< minor version */ + Uint8 patch; /**< update version */ +} SDL_version; + +/* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL +*/ +#define SDL_MAJOR_VERSION 2 +#define SDL_MINOR_VERSION 30 +#define SDL_PATCHLEVEL 5 + +/** + * Macro to determine SDL version program was compiled against. + * + * This macro fills in a SDL_version structure with the version of the + * library you compiled against. This is determined by what header the + * compiler uses. Note that if you dynamically linked the library, you might + * have a slightly newer or older version at runtime. That version can be + * determined with SDL_GetVersion(), which, unlike SDL_VERSION(), + * is not a macro. + * + * \param x A pointer to a SDL_version struct to initialize. + * + * \sa SDL_version + * \sa SDL_GetVersion + */ +#define SDL_VERSION(x) \ +{ \ + (x)->major = SDL_MAJOR_VERSION; \ + (x)->minor = SDL_MINOR_VERSION; \ + (x)->patch = SDL_PATCHLEVEL; \ +} + +/* TODO: Remove this whole block in SDL 3 */ +#if SDL_MAJOR_VERSION < 3 +/** + * This macro turns the version numbers into a numeric value: + * \verbatim + (1,2,3) -> (1203) + \endverbatim + * + * This assumes that there will never be more than 100 patchlevels. + * + * In versions higher than 2.9.0, the minor version overflows into + * the thousands digit: for example, 2.23.0 is encoded as 4300, + * and 2.255.99 would be encoded as 25799. + * This macro will not be available in SDL 3.x. + */ +#define SDL_VERSIONNUM(X, Y, Z) \ + ((X)*1000 + (Y)*100 + (Z)) + +/** + * This is the version number macro for the current SDL version. + * + * In versions higher than 2.9.0, the minor version overflows into + * the thousands digit: for example, 2.23.0 is encoded as 4300. + * This macro will not be available in SDL 3.x. + * + * Deprecated, use SDL_VERSION_ATLEAST or SDL_VERSION instead. + */ +#define SDL_COMPILEDVERSION \ + SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) +#endif /* SDL_MAJOR_VERSION < 3 */ + +/** + * This macro will evaluate to true if compiled with SDL at least X.Y.Z. + */ +#define SDL_VERSION_ATLEAST(X, Y, Z) \ + ((SDL_MAJOR_VERSION >= X) && \ + (SDL_MAJOR_VERSION > X || SDL_MINOR_VERSION >= Y) && \ + (SDL_MAJOR_VERSION > X || SDL_MINOR_VERSION > Y || SDL_PATCHLEVEL >= Z)) + +/** + * Get the version of SDL that is linked against your program. + * + * If you are linking to SDL dynamically, then it is possible that the current + * version will be different than the version you compiled against. This + * function returns the current version, while SDL_VERSION() is a macro that + * tells you what version you compiled with. + * + * This function may be called safely at any time, even before SDL_Init(). + * + * \param ver the SDL_version structure that contains the version information + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetRevision + */ +extern DECLSPEC void SDLCALL SDL_GetVersion(SDL_version * ver); + +/** + * Get the code revision of SDL that is linked against your program. + * + * This value is the revision of the code you are linked with and may be + * different from the code you are compiling with, which is found in the + * constant SDL_REVISION. + * + * The revision is arbitrary string (a hash value) uniquely identifying the + * exact revision of the SDL library in use, and is only useful in comparing + * against other revisions. It is NOT an incrementing number. + * + * If SDL wasn't built from a git repository with the appropriate tools, this + * will return an empty string. + * + * Prior to SDL 2.0.16, before development moved to GitHub, this returned a + * hash for a Mercurial repository. + * + * You shouldn't use this function for anything but logging it for debugging + * purposes. The string is not intended to be reliable in any way. + * + * \returns an arbitrary string, uniquely identifying the exact revision of + * the SDL library in use. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetVersion + */ +extern DECLSPEC const char *SDLCALL SDL_GetRevision(void); + +/** + * Obsolete function, do not use. + * + * When SDL was hosted in a Mercurial repository, and was built carefully, + * this would return the revision number that the build was created from. This + * number was not reliable for several reasons, but more importantly, SDL is + * now hosted in a git repository, which does not offer numbers at all, only + * hashes. This function only ever returns zero now. Don't use it. + * + * Before SDL 2.0.16, this might have returned an unreliable, but non-zero + * number. + * + * \deprecated Use SDL_GetRevision() instead; if SDL was carefully built, it + * will return a git hash. + * + * \returns zero, always, in modern SDL releases. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetRevision + */ +extern SDL_DEPRECATED DECLSPEC int SDLCALL SDL_GetRevisionNumber(void); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_version_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/include/SDL_video.h b/SDL2-2.30.5/include/SDL_video.h new file mode 100644 index 0000000..fa47d30 --- /dev/null +++ b/SDL2-2.30.5/include/SDL_video.h @@ -0,0 +1,2184 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_video.h + * + * Header file for SDL video functions. + */ + +#ifndef SDL_video_h_ +#define SDL_video_h_ + +#include "SDL_stdinc.h" +#include "SDL_pixels.h" +#include "SDL_rect.h" +#include "SDL_surface.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief The structure that defines a display mode + * + * \sa SDL_GetNumDisplayModes() + * \sa SDL_GetDisplayMode() + * \sa SDL_GetDesktopDisplayMode() + * \sa SDL_GetCurrentDisplayMode() + * \sa SDL_GetClosestDisplayMode() + * \sa SDL_SetWindowDisplayMode() + * \sa SDL_GetWindowDisplayMode() + */ +typedef struct +{ + Uint32 format; /**< pixel format */ + int w; /**< width, in screen coordinates */ + int h; /**< height, in screen coordinates */ + int refresh_rate; /**< refresh rate (or zero for unspecified) */ + void *driverdata; /**< driver-specific data, initialize to 0 */ +} SDL_DisplayMode; + +/** + * \brief The type used to identify a window + * + * \sa SDL_CreateWindow() + * \sa SDL_CreateWindowFrom() + * \sa SDL_DestroyWindow() + * \sa SDL_FlashWindow() + * \sa SDL_GetWindowData() + * \sa SDL_GetWindowFlags() + * \sa SDL_GetWindowGrab() + * \sa SDL_GetWindowKeyboardGrab() + * \sa SDL_GetWindowMouseGrab() + * \sa SDL_GetWindowPosition() + * \sa SDL_GetWindowSize() + * \sa SDL_GetWindowTitle() + * \sa SDL_HideWindow() + * \sa SDL_MaximizeWindow() + * \sa SDL_MinimizeWindow() + * \sa SDL_RaiseWindow() + * \sa SDL_RestoreWindow() + * \sa SDL_SetWindowData() + * \sa SDL_SetWindowFullscreen() + * \sa SDL_SetWindowGrab() + * \sa SDL_SetWindowKeyboardGrab() + * \sa SDL_SetWindowMouseGrab() + * \sa SDL_SetWindowIcon() + * \sa SDL_SetWindowPosition() + * \sa SDL_SetWindowSize() + * \sa SDL_SetWindowBordered() + * \sa SDL_SetWindowResizable() + * \sa SDL_SetWindowTitle() + * \sa SDL_ShowWindow() + */ +typedef struct SDL_Window SDL_Window; + +/** + * \brief The flags on a window + * + * \sa SDL_GetWindowFlags() + */ +typedef enum +{ + SDL_WINDOW_FULLSCREEN = 0x00000001, /**< fullscreen window */ + SDL_WINDOW_OPENGL = 0x00000002, /**< window usable with OpenGL context */ + SDL_WINDOW_SHOWN = 0x00000004, /**< window is visible */ + SDL_WINDOW_HIDDEN = 0x00000008, /**< window is not visible */ + SDL_WINDOW_BORDERLESS = 0x00000010, /**< no window decoration */ + SDL_WINDOW_RESIZABLE = 0x00000020, /**< window can be resized */ + SDL_WINDOW_MINIMIZED = 0x00000040, /**< window is minimized */ + SDL_WINDOW_MAXIMIZED = 0x00000080, /**< window is maximized */ + SDL_WINDOW_MOUSE_GRABBED = 0x00000100, /**< window has grabbed mouse input */ + SDL_WINDOW_INPUT_FOCUS = 0x00000200, /**< window has input focus */ + SDL_WINDOW_MOUSE_FOCUS = 0x00000400, /**< window has mouse focus */ + SDL_WINDOW_FULLSCREEN_DESKTOP = ( SDL_WINDOW_FULLSCREEN | 0x00001000 ), + SDL_WINDOW_FOREIGN = 0x00000800, /**< window not created by SDL */ + SDL_WINDOW_ALLOW_HIGHDPI = 0x00002000, /**< window should be created in high-DPI mode if supported. + On macOS NSHighResolutionCapable must be set true in the + application's Info.plist for this to have any effect. */ + SDL_WINDOW_MOUSE_CAPTURE = 0x00004000, /**< window has mouse captured (unrelated to MOUSE_GRABBED) */ + SDL_WINDOW_ALWAYS_ON_TOP = 0x00008000, /**< window should always be above others */ + SDL_WINDOW_SKIP_TASKBAR = 0x00010000, /**< window should not be added to the taskbar */ + SDL_WINDOW_UTILITY = 0x00020000, /**< window should be treated as a utility window */ + SDL_WINDOW_TOOLTIP = 0x00040000, /**< window should be treated as a tooltip */ + SDL_WINDOW_POPUP_MENU = 0x00080000, /**< window should be treated as a popup menu */ + SDL_WINDOW_KEYBOARD_GRABBED = 0x00100000, /**< window has grabbed keyboard input */ + SDL_WINDOW_VULKAN = 0x10000000, /**< window usable for Vulkan surface */ + SDL_WINDOW_METAL = 0x20000000, /**< window usable for Metal view */ + + SDL_WINDOW_INPUT_GRABBED = SDL_WINDOW_MOUSE_GRABBED /**< equivalent to SDL_WINDOW_MOUSE_GRABBED for compatibility */ +} SDL_WindowFlags; + +/** + * \brief Used to indicate that you don't care what the window position is. + */ +#define SDL_WINDOWPOS_UNDEFINED_MASK 0x1FFF0000u +#define SDL_WINDOWPOS_UNDEFINED_DISPLAY(X) (SDL_WINDOWPOS_UNDEFINED_MASK|(X)) +#define SDL_WINDOWPOS_UNDEFINED SDL_WINDOWPOS_UNDEFINED_DISPLAY(0) +#define SDL_WINDOWPOS_ISUNDEFINED(X) \ + (((X)&0xFFFF0000) == SDL_WINDOWPOS_UNDEFINED_MASK) + +/** + * \brief Used to indicate that the window position should be centered. + */ +#define SDL_WINDOWPOS_CENTERED_MASK 0x2FFF0000u +#define SDL_WINDOWPOS_CENTERED_DISPLAY(X) (SDL_WINDOWPOS_CENTERED_MASK|(X)) +#define SDL_WINDOWPOS_CENTERED SDL_WINDOWPOS_CENTERED_DISPLAY(0) +#define SDL_WINDOWPOS_ISCENTERED(X) \ + (((X)&0xFFFF0000) == SDL_WINDOWPOS_CENTERED_MASK) + +/** + * \brief Event subtype for window events + */ +typedef enum +{ + SDL_WINDOWEVENT_NONE, /**< Never used */ + SDL_WINDOWEVENT_SHOWN, /**< Window has been shown */ + SDL_WINDOWEVENT_HIDDEN, /**< Window has been hidden */ + SDL_WINDOWEVENT_EXPOSED, /**< Window has been exposed and should be + redrawn */ + SDL_WINDOWEVENT_MOVED, /**< Window has been moved to data1, data2 + */ + SDL_WINDOWEVENT_RESIZED, /**< Window has been resized to data1xdata2 */ + SDL_WINDOWEVENT_SIZE_CHANGED, /**< The window size has changed, either as + a result of an API call or through the + system or user changing the window size. */ + SDL_WINDOWEVENT_MINIMIZED, /**< Window has been minimized */ + SDL_WINDOWEVENT_MAXIMIZED, /**< Window has been maximized */ + SDL_WINDOWEVENT_RESTORED, /**< Window has been restored to normal size + and position */ + SDL_WINDOWEVENT_ENTER, /**< Window has gained mouse focus */ + SDL_WINDOWEVENT_LEAVE, /**< Window has lost mouse focus */ + SDL_WINDOWEVENT_FOCUS_GAINED, /**< Window has gained keyboard focus */ + SDL_WINDOWEVENT_FOCUS_LOST, /**< Window has lost keyboard focus */ + SDL_WINDOWEVENT_CLOSE, /**< The window manager requests that the window be closed */ + SDL_WINDOWEVENT_TAKE_FOCUS, /**< Window is being offered a focus (should SetWindowInputFocus() on itself or a subwindow, or ignore) */ + SDL_WINDOWEVENT_HIT_TEST, /**< Window had a hit test that wasn't SDL_HITTEST_NORMAL. */ + SDL_WINDOWEVENT_ICCPROF_CHANGED,/**< The ICC profile of the window's display has changed. */ + SDL_WINDOWEVENT_DISPLAY_CHANGED /**< Window has been moved to display data1. */ +} SDL_WindowEventID; + +/** + * \brief Event subtype for display events + */ +typedef enum +{ + SDL_DISPLAYEVENT_NONE, /**< Never used */ + SDL_DISPLAYEVENT_ORIENTATION, /**< Display orientation has changed to data1 */ + SDL_DISPLAYEVENT_CONNECTED, /**< Display has been added to the system */ + SDL_DISPLAYEVENT_DISCONNECTED, /**< Display has been removed from the system */ + SDL_DISPLAYEVENT_MOVED /**< Display has changed position */ +} SDL_DisplayEventID; + +/** + * \brief Display orientation + */ +typedef enum +{ + SDL_ORIENTATION_UNKNOWN, /**< The display orientation can't be determined */ + SDL_ORIENTATION_LANDSCAPE, /**< The display is in landscape mode, with the right side up, relative to portrait mode */ + SDL_ORIENTATION_LANDSCAPE_FLIPPED, /**< The display is in landscape mode, with the left side up, relative to portrait mode */ + SDL_ORIENTATION_PORTRAIT, /**< The display is in portrait mode */ + SDL_ORIENTATION_PORTRAIT_FLIPPED /**< The display is in portrait mode, upside down */ +} SDL_DisplayOrientation; + +/** + * \brief Window flash operation + */ +typedef enum +{ + SDL_FLASH_CANCEL, /**< Cancel any window flash state */ + SDL_FLASH_BRIEFLY, /**< Flash the window briefly to get attention */ + SDL_FLASH_UNTIL_FOCUSED /**< Flash the window until it gets focus */ +} SDL_FlashOperation; + +/** + * \brief An opaque handle to an OpenGL context. + */ +typedef void *SDL_GLContext; + +/** + * \brief OpenGL configuration attributes + */ +typedef enum +{ + SDL_GL_RED_SIZE, + SDL_GL_GREEN_SIZE, + SDL_GL_BLUE_SIZE, + SDL_GL_ALPHA_SIZE, + SDL_GL_BUFFER_SIZE, + SDL_GL_DOUBLEBUFFER, + SDL_GL_DEPTH_SIZE, + SDL_GL_STENCIL_SIZE, + SDL_GL_ACCUM_RED_SIZE, + SDL_GL_ACCUM_GREEN_SIZE, + SDL_GL_ACCUM_BLUE_SIZE, + SDL_GL_ACCUM_ALPHA_SIZE, + SDL_GL_STEREO, + SDL_GL_MULTISAMPLEBUFFERS, + SDL_GL_MULTISAMPLESAMPLES, + SDL_GL_ACCELERATED_VISUAL, + SDL_GL_RETAINED_BACKING, + SDL_GL_CONTEXT_MAJOR_VERSION, + SDL_GL_CONTEXT_MINOR_VERSION, + SDL_GL_CONTEXT_EGL, + SDL_GL_CONTEXT_FLAGS, + SDL_GL_CONTEXT_PROFILE_MASK, + SDL_GL_SHARE_WITH_CURRENT_CONTEXT, + SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, + SDL_GL_CONTEXT_RELEASE_BEHAVIOR, + SDL_GL_CONTEXT_RESET_NOTIFICATION, + SDL_GL_CONTEXT_NO_ERROR, + SDL_GL_FLOATBUFFERS +} SDL_GLattr; + +typedef enum +{ + SDL_GL_CONTEXT_PROFILE_CORE = 0x0001, + SDL_GL_CONTEXT_PROFILE_COMPATIBILITY = 0x0002, + SDL_GL_CONTEXT_PROFILE_ES = 0x0004 /**< GLX_CONTEXT_ES2_PROFILE_BIT_EXT */ +} SDL_GLprofile; + +typedef enum +{ + SDL_GL_CONTEXT_DEBUG_FLAG = 0x0001, + SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG = 0x0002, + SDL_GL_CONTEXT_ROBUST_ACCESS_FLAG = 0x0004, + SDL_GL_CONTEXT_RESET_ISOLATION_FLAG = 0x0008 +} SDL_GLcontextFlag; + +typedef enum +{ + SDL_GL_CONTEXT_RELEASE_BEHAVIOR_NONE = 0x0000, + SDL_GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH = 0x0001 +} SDL_GLcontextReleaseFlag; + +typedef enum +{ + SDL_GL_CONTEXT_RESET_NO_NOTIFICATION = 0x0000, + SDL_GL_CONTEXT_RESET_LOSE_CONTEXT = 0x0001 +} SDL_GLContextResetNotification; + +/* Function prototypes */ + +/** + * Get the number of video drivers compiled into SDL. + * + * \returns a number >= 1 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetVideoDriver + */ +extern DECLSPEC int SDLCALL SDL_GetNumVideoDrivers(void); + +/** + * Get the name of a built in video driver. + * + * The video drivers are presented in the order in which they are normally + * checked during initialization. + * + * \param index the index of a video driver + * \returns the name of the video driver with the given **index**. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetNumVideoDrivers + */ +extern DECLSPEC const char *SDLCALL SDL_GetVideoDriver(int index); + +/** + * Initialize the video subsystem, optionally specifying a video driver. + * + * This function initializes the video subsystem, setting up a connection to + * the window manager, etc, and determines the available display modes and + * pixel formats, but does not initialize a window or graphics mode. + * + * If you use this function and you haven't used the SDL_INIT_VIDEO flag with + * either SDL_Init() or SDL_InitSubSystem(), you should call SDL_VideoQuit() + * before calling SDL_Quit(). + * + * It is safe to call this function multiple times. SDL_VideoInit() will call + * SDL_VideoQuit() itself if the video subsystem has already been initialized. + * + * You can use SDL_GetNumVideoDrivers() and SDL_GetVideoDriver() to find a + * specific `driver_name`. + * + * \param driver_name the name of a video driver to initialize, or NULL for + * the default driver + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetNumVideoDrivers + * \sa SDL_GetVideoDriver + * \sa SDL_InitSubSystem + * \sa SDL_VideoQuit + */ +extern DECLSPEC int SDLCALL SDL_VideoInit(const char *driver_name); + +/** + * Shut down the video subsystem, if initialized with SDL_VideoInit(). + * + * This function closes all windows, and restores the original video mode. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_VideoInit + */ +extern DECLSPEC void SDLCALL SDL_VideoQuit(void); + +/** + * Get the name of the currently initialized video driver. + * + * \returns the name of the current video driver or NULL if no driver has been + * initialized. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetNumVideoDrivers + * \sa SDL_GetVideoDriver + */ +extern DECLSPEC const char *SDLCALL SDL_GetCurrentVideoDriver(void); + +/** + * Get the number of available video displays. + * + * \returns a number >= 1 or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetDisplayBounds + */ +extern DECLSPEC int SDLCALL SDL_GetNumVideoDisplays(void); + +/** + * Get the name of a display in UTF-8 encoding. + * + * \param displayIndex the index of display from which the name should be + * queried + * \returns the name of a display or NULL for an invalid display index or + * failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetNumVideoDisplays + */ +extern DECLSPEC const char * SDLCALL SDL_GetDisplayName(int displayIndex); + +/** + * Get the desktop area represented by a display. + * + * The primary display (`displayIndex` zero) is always located at 0,0. + * + * \param displayIndex the index of the display to query + * \param rect the SDL_Rect structure filled in with the display bounds + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetNumVideoDisplays + */ +extern DECLSPEC int SDLCALL SDL_GetDisplayBounds(int displayIndex, SDL_Rect * rect); + +/** + * Get the usable desktop area represented by a display. + * + * The primary display (`displayIndex` zero) is always located at 0,0. + * + * This is the same area as SDL_GetDisplayBounds() reports, but with portions + * reserved by the system removed. For example, on Apple's macOS, this + * subtracts the area occupied by the menu bar and dock. + * + * Setting a window to be fullscreen generally bypasses these unusable areas, + * so these are good guidelines for the maximum space available to a + * non-fullscreen window. + * + * The parameter `rect` is ignored if it is NULL. + * + * This function also returns -1 if the parameter `displayIndex` is out of + * range. + * + * \param displayIndex the index of the display to query the usable bounds + * from + * \param rect the SDL_Rect structure filled in with the display bounds + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.5. + * + * \sa SDL_GetDisplayBounds + * \sa SDL_GetNumVideoDisplays + */ +extern DECLSPEC int SDLCALL SDL_GetDisplayUsableBounds(int displayIndex, SDL_Rect * rect); + +/** + * Get the dots/pixels-per-inch for a display. + * + * Diagonal, horizontal and vertical DPI can all be optionally returned if the + * appropriate parameter is non-NULL. + * + * A failure of this function usually means that either no DPI information is + * available or the `displayIndex` is out of range. + * + * **WARNING**: This reports the DPI that the hardware reports, and it is not + * always reliable! It is almost always better to use SDL_GetWindowSize() to + * find the window size, which might be in logical points instead of pixels, + * and then SDL_GL_GetDrawableSize(), SDL_Vulkan_GetDrawableSize(), + * SDL_Metal_GetDrawableSize(), or SDL_GetRendererOutputSize(), and compare + * the two values to get an actual scaling value between the two. We will be + * rethinking how high-dpi details should be managed in SDL3 to make things + * more consistent, reliable, and clear. + * + * \param displayIndex the index of the display from which DPI information + * should be queried + * \param ddpi a pointer filled in with the diagonal DPI of the display; may + * be NULL + * \param hdpi a pointer filled in with the horizontal DPI of the display; may + * be NULL + * \param vdpi a pointer filled in with the vertical DPI of the display; may + * be NULL + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.4. + * + * \sa SDL_GetNumVideoDisplays + */ +extern DECLSPEC int SDLCALL SDL_GetDisplayDPI(int displayIndex, float * ddpi, float * hdpi, float * vdpi); + +/** + * Get the orientation of a display. + * + * \param displayIndex the index of the display to query + * \returns The SDL_DisplayOrientation enum value of the display, or + * `SDL_ORIENTATION_UNKNOWN` if it isn't available. + * + * \since This function is available since SDL 2.0.9. + * + * \sa SDL_GetNumVideoDisplays + */ +extern DECLSPEC SDL_DisplayOrientation SDLCALL SDL_GetDisplayOrientation(int displayIndex); + +/** + * Get the number of available display modes. + * + * The `displayIndex` needs to be in the range from 0 to + * SDL_GetNumVideoDisplays() - 1. + * + * \param displayIndex the index of the display to query + * \returns a number >= 1 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetDisplayMode + * \sa SDL_GetNumVideoDisplays + */ +extern DECLSPEC int SDLCALL SDL_GetNumDisplayModes(int displayIndex); + +/** + * Get information about a specific display mode. + * + * The display modes are sorted in this priority: + * + * - width -> largest to smallest + * - height -> largest to smallest + * - bits per pixel -> more colors to fewer colors + * - packed pixel layout -> largest to smallest + * - refresh rate -> highest to lowest + * + * \param displayIndex the index of the display to query + * \param modeIndex the index of the display mode to query + * \param mode an SDL_DisplayMode structure filled in with the mode at + * `modeIndex` + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetNumDisplayModes + */ +extern DECLSPEC int SDLCALL SDL_GetDisplayMode(int displayIndex, int modeIndex, + SDL_DisplayMode * mode); + +/** + * Get information about the desktop's display mode. + * + * There's a difference between this function and SDL_GetCurrentDisplayMode() + * when SDL runs fullscreen and has changed the resolution. In that case this + * function will return the previous native display mode, and not the current + * display mode. + * + * \param displayIndex the index of the display to query + * \param mode an SDL_DisplayMode structure filled in with the current display + * mode + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetCurrentDisplayMode + * \sa SDL_GetDisplayMode + * \sa SDL_SetWindowDisplayMode + */ +extern DECLSPEC int SDLCALL SDL_GetDesktopDisplayMode(int displayIndex, SDL_DisplayMode * mode); + +/** + * Get information about the current display mode. + * + * There's a difference between this function and SDL_GetDesktopDisplayMode() + * when SDL runs fullscreen and has changed the resolution. In that case this + * function will return the current display mode, and not the previous native + * display mode. + * + * \param displayIndex the index of the display to query + * \param mode an SDL_DisplayMode structure filled in with the current display + * mode + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetDesktopDisplayMode + * \sa SDL_GetDisplayMode + * \sa SDL_GetNumVideoDisplays + * \sa SDL_SetWindowDisplayMode + */ +extern DECLSPEC int SDLCALL SDL_GetCurrentDisplayMode(int displayIndex, SDL_DisplayMode * mode); + + +/** + * Get the closest match to the requested display mode. + * + * The available display modes are scanned and `closest` is filled in with the + * closest mode matching the requested mode and returned. The mode format and + * refresh rate default to the desktop mode if they are set to 0. The modes + * are scanned with size being first priority, format being second priority, + * and finally checking the refresh rate. If all the available modes are too + * small, then NULL is returned. + * + * \param displayIndex the index of the display to query + * \param mode an SDL_DisplayMode structure containing the desired display + * mode + * \param closest an SDL_DisplayMode structure filled in with the closest + * match of the available display modes + * \returns the passed in value `closest` or NULL if no matching video mode + * was available; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetDisplayMode + * \sa SDL_GetNumDisplayModes + */ +extern DECLSPEC SDL_DisplayMode * SDLCALL SDL_GetClosestDisplayMode(int displayIndex, const SDL_DisplayMode * mode, SDL_DisplayMode * closest); + +/** + * Get the index of the display containing a point + * + * \param point the point to query + * \returns the index of the display containing the point or a negative error + * code on failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.24.0. + * + * \sa SDL_GetDisplayBounds + * \sa SDL_GetNumVideoDisplays + */ +extern DECLSPEC int SDLCALL SDL_GetPointDisplayIndex(const SDL_Point * point); + +/** + * Get the index of the display primarily containing a rect + * + * \param rect the rect to query + * \returns the index of the display entirely containing the rect or closest + * to the center of the rect on success or a negative error code on + * failure; call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.24.0. + * + * \sa SDL_GetDisplayBounds + * \sa SDL_GetNumVideoDisplays + */ +extern DECLSPEC int SDLCALL SDL_GetRectDisplayIndex(const SDL_Rect * rect); + +/** + * Get the index of the display associated with a window. + * + * \param window the window to query + * \returns the index of the display containing the center of the window on + * success or a negative error code on failure; call SDL_GetError() + * for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetDisplayBounds + * \sa SDL_GetNumVideoDisplays + */ +extern DECLSPEC int SDLCALL SDL_GetWindowDisplayIndex(SDL_Window * window); + +/** + * Set the display mode to use when a window is visible at fullscreen. + * + * This only affects the display mode used when the window is fullscreen. To + * change the window size when the window is not fullscreen, use + * SDL_SetWindowSize(). + * + * \param window the window to affect + * \param mode the SDL_DisplayMode structure representing the mode to use, or + * NULL to use the window's dimensions and the desktop's format + * and refresh rate + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowDisplayMode + * \sa SDL_SetWindowFullscreen + */ +extern DECLSPEC int SDLCALL SDL_SetWindowDisplayMode(SDL_Window * window, + const SDL_DisplayMode * mode); + +/** + * Query the display mode to use when a window is visible at fullscreen. + * + * \param window the window to query + * \param mode an SDL_DisplayMode structure filled in with the fullscreen + * display mode + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetWindowDisplayMode + * \sa SDL_SetWindowFullscreen + */ +extern DECLSPEC int SDLCALL SDL_GetWindowDisplayMode(SDL_Window * window, + SDL_DisplayMode * mode); + +/** + * Get the raw ICC profile data for the screen the window is currently on. + * + * Data returned should be freed with SDL_free. + * + * \param window the window to query + * \param size the size of the ICC profile + * \returns the raw ICC profile data on success or NULL on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.18. + */ +extern DECLSPEC void* SDLCALL SDL_GetWindowICCProfile(SDL_Window * window, size_t* size); + +/** + * Get the pixel format associated with the window. + * + * \param window the window to query + * \returns the pixel format of the window on success or + * SDL_PIXELFORMAT_UNKNOWN on failure; call SDL_GetError() for more + * information. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC Uint32 SDLCALL SDL_GetWindowPixelFormat(SDL_Window * window); + +/** + * Create a window with the specified position, dimensions, and flags. + * + * `flags` may be any of the following OR'd together: + * + * - `SDL_WINDOW_FULLSCREEN`: fullscreen window + * - `SDL_WINDOW_FULLSCREEN_DESKTOP`: fullscreen window at desktop resolution + * - `SDL_WINDOW_OPENGL`: window usable with an OpenGL context + * - `SDL_WINDOW_VULKAN`: window usable with a Vulkan instance + * - `SDL_WINDOW_METAL`: window usable with a Metal instance + * - `SDL_WINDOW_HIDDEN`: window is not visible + * - `SDL_WINDOW_BORDERLESS`: no window decoration + * - `SDL_WINDOW_RESIZABLE`: window can be resized + * - `SDL_WINDOW_MINIMIZED`: window is minimized + * - `SDL_WINDOW_MAXIMIZED`: window is maximized + * - `SDL_WINDOW_INPUT_GRABBED`: window has grabbed input focus + * - `SDL_WINDOW_ALLOW_HIGHDPI`: window should be created in high-DPI mode if + * supported (>= SDL 2.0.1) + * + * `SDL_WINDOW_SHOWN` is ignored by SDL_CreateWindow(). The SDL_Window is + * implicitly shown if SDL_WINDOW_HIDDEN is not set. `SDL_WINDOW_SHOWN` may be + * queried later using SDL_GetWindowFlags(). + * + * On Apple's macOS, you **must** set the NSHighResolutionCapable Info.plist + * property to YES, otherwise you will not receive a High-DPI OpenGL canvas. + * + * If the window is created with the `SDL_WINDOW_ALLOW_HIGHDPI` flag, its size + * in pixels may differ from its size in screen coordinates on platforms with + * high-DPI support (e.g. iOS and macOS). Use SDL_GetWindowSize() to query the + * client area's size in screen coordinates, and SDL_GL_GetDrawableSize() or + * SDL_GetRendererOutputSize() to query the drawable size in pixels. Note that + * when this flag is set, the drawable size can vary after the window is + * created and should be queried after major window events such as when the + * window is resized or moved between displays. + * + * If the window is set fullscreen, the width and height parameters `w` and + * `h` will not be used. However, invalid size parameters (e.g. too large) may + * still fail. Window size is actually limited to 16384 x 16384 for all + * platforms at window creation. + * + * If the window is created with any of the SDL_WINDOW_OPENGL or + * SDL_WINDOW_VULKAN flags, then the corresponding LoadLibrary function + * (SDL_GL_LoadLibrary or SDL_Vulkan_LoadLibrary) is called and the + * corresponding UnloadLibrary function is called by SDL_DestroyWindow(). + * + * If SDL_WINDOW_VULKAN is specified and there isn't a working Vulkan driver, + * SDL_CreateWindow() will fail because SDL_Vulkan_LoadLibrary() will fail. + * + * If SDL_WINDOW_METAL is specified on an OS that does not support Metal, + * SDL_CreateWindow() will fail. + * + * On non-Apple devices, SDL requires you to either not link to the Vulkan + * loader or link to a dynamic library version. This limitation may be removed + * in a future version of SDL. + * + * \param title the title of the window, in UTF-8 encoding + * \param x the x position of the window, `SDL_WINDOWPOS_CENTERED`, or + * `SDL_WINDOWPOS_UNDEFINED` + * \param y the y position of the window, `SDL_WINDOWPOS_CENTERED`, or + * `SDL_WINDOWPOS_UNDEFINED` + * \param w the width of the window, in screen coordinates + * \param h the height of the window, in screen coordinates + * \param flags 0, or one or more SDL_WindowFlags OR'd together + * \returns the window that was created or NULL on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateWindowFrom + * \sa SDL_DestroyWindow + */ +extern DECLSPEC SDL_Window * SDLCALL SDL_CreateWindow(const char *title, + int x, int y, int w, + int h, Uint32 flags); + +/** + * Create an SDL window from an existing native window. + * + * In some cases (e.g. OpenGL) and on some platforms (e.g. Microsoft Windows) + * the hint `SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT` needs to be configured + * before using SDL_CreateWindowFrom(). + * + * \param data a pointer to driver-dependent window creation data, typically + * your native window cast to a void* + * \returns the window that was created or NULL on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateWindow + * \sa SDL_DestroyWindow + */ +extern DECLSPEC SDL_Window * SDLCALL SDL_CreateWindowFrom(const void *data); + +/** + * Get the numeric ID of a window. + * + * The numeric ID is what SDL_WindowEvent references, and is necessary to map + * these events to specific SDL_Window objects. + * + * \param window the window to query + * \returns the ID of the window on success or 0 on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowFromID + */ +extern DECLSPEC Uint32 SDLCALL SDL_GetWindowID(SDL_Window * window); + +/** + * Get a window from a stored ID. + * + * The numeric ID is what SDL_WindowEvent references, and is necessary to map + * these events to specific SDL_Window objects. + * + * \param id the ID of the window + * \returns the window associated with `id` or NULL if it doesn't exist; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowID + */ +extern DECLSPEC SDL_Window * SDLCALL SDL_GetWindowFromID(Uint32 id); + +/** + * Get the window flags. + * + * \param window the window to query + * \returns a mask of the SDL_WindowFlags associated with `window` + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateWindow + * \sa SDL_HideWindow + * \sa SDL_MaximizeWindow + * \sa SDL_MinimizeWindow + * \sa SDL_SetWindowFullscreen + * \sa SDL_SetWindowGrab + * \sa SDL_ShowWindow + */ +extern DECLSPEC Uint32 SDLCALL SDL_GetWindowFlags(SDL_Window * window); + +/** + * Set the title of a window. + * + * This string is expected to be in UTF-8 encoding. + * + * \param window the window to change + * \param title the desired window title in UTF-8 format + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowTitle + */ +extern DECLSPEC void SDLCALL SDL_SetWindowTitle(SDL_Window * window, + const char *title); + +/** + * Get the title of a window. + * + * \param window the window to query + * \returns the title of the window in UTF-8 format or "" if there is no + * title. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetWindowTitle + */ +extern DECLSPEC const char *SDLCALL SDL_GetWindowTitle(SDL_Window * window); + +/** + * Set the icon for a window. + * + * \param window the window to change + * \param icon an SDL_Surface structure containing the icon for the window + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC void SDLCALL SDL_SetWindowIcon(SDL_Window * window, + SDL_Surface * icon); + +/** + * Associate an arbitrary named pointer with a window. + * + * `name` is case-sensitive. + * + * \param window the window to associate with the pointer + * \param name the name of the pointer + * \param userdata the associated pointer + * \returns the previous value associated with `name`. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowData + */ +extern DECLSPEC void* SDLCALL SDL_SetWindowData(SDL_Window * window, + const char *name, + void *userdata); + +/** + * Retrieve the data pointer associated with a window. + * + * \param window the window to query + * \param name the name of the pointer + * \returns the value associated with `name`. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetWindowData + */ +extern DECLSPEC void *SDLCALL SDL_GetWindowData(SDL_Window * window, + const char *name); + +/** + * Set the position of a window. + * + * The window coordinate origin is the upper left of the display. + * + * \param window the window to reposition + * \param x the x coordinate of the window in screen coordinates, or + * `SDL_WINDOWPOS_CENTERED` or `SDL_WINDOWPOS_UNDEFINED` + * \param y the y coordinate of the window in screen coordinates, or + * `SDL_WINDOWPOS_CENTERED` or `SDL_WINDOWPOS_UNDEFINED` + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowPosition + */ +extern DECLSPEC void SDLCALL SDL_SetWindowPosition(SDL_Window * window, + int x, int y); + +/** + * Get the position of a window. + * + * If you do not need the value for one of the positions a NULL may be passed + * in the `x` or `y` parameter. + * + * \param window the window to query + * \param x a pointer filled in with the x position of the window, in screen + * coordinates, may be NULL + * \param y a pointer filled in with the y position of the window, in screen + * coordinates, may be NULL + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetWindowPosition + */ +extern DECLSPEC void SDLCALL SDL_GetWindowPosition(SDL_Window * window, + int *x, int *y); + +/** + * Set the size of a window's client area. + * + * The window size in screen coordinates may differ from the size in pixels, + * if the window was created with `SDL_WINDOW_ALLOW_HIGHDPI` on a platform + * with high-dpi support (e.g. iOS or macOS). Use SDL_GL_GetDrawableSize() or + * SDL_GetRendererOutputSize() to get the real client area size in pixels. + * + * Fullscreen windows automatically match the size of the display mode, and + * you should use SDL_SetWindowDisplayMode() to change their size. + * + * \param window the window to change + * \param w the width of the window in pixels, in screen coordinates, must be + * > 0 + * \param h the height of the window in pixels, in screen coordinates, must be + * > 0 + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowSize + * \sa SDL_SetWindowDisplayMode + */ +extern DECLSPEC void SDLCALL SDL_SetWindowSize(SDL_Window * window, int w, + int h); + +/** + * Get the size of a window's client area. + * + * NULL can safely be passed as the `w` or `h` parameter if the width or + * height value is not desired. + * + * The window size in screen coordinates may differ from the size in pixels, + * if the window was created with `SDL_WINDOW_ALLOW_HIGHDPI` on a platform + * with high-dpi support (e.g. iOS or macOS). Use SDL_GL_GetDrawableSize(), + * SDL_Vulkan_GetDrawableSize(), or SDL_GetRendererOutputSize() to get the + * real client area size in pixels. + * + * \param window the window to query the width and height from + * \param w a pointer filled in with the width of the window, in screen + * coordinates, may be NULL + * \param h a pointer filled in with the height of the window, in screen + * coordinates, may be NULL + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GL_GetDrawableSize + * \sa SDL_Vulkan_GetDrawableSize + * \sa SDL_SetWindowSize + */ +extern DECLSPEC void SDLCALL SDL_GetWindowSize(SDL_Window * window, int *w, + int *h); + +/** + * Get the size of a window's borders (decorations) around the client area. + * + * Note: If this function fails (returns -1), the size values will be + * initialized to 0, 0, 0, 0 (if a non-NULL pointer is provided), as if the + * window in question was borderless. + * + * Note: This function may fail on systems where the window has not yet been + * decorated by the display server (for example, immediately after calling + * SDL_CreateWindow). It is recommended that you wait at least until the + * window has been presented and composited, so that the window system has a + * chance to decorate the window and provide the border dimensions to SDL. + * + * This function also returns -1 if getting the information is not supported. + * + * \param window the window to query the size values of the border + * (decorations) from + * \param top pointer to variable for storing the size of the top border; NULL + * is permitted + * \param left pointer to variable for storing the size of the left border; + * NULL is permitted + * \param bottom pointer to variable for storing the size of the bottom + * border; NULL is permitted + * \param right pointer to variable for storing the size of the right border; + * NULL is permitted + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.5. + * + * \sa SDL_GetWindowSize + */ +extern DECLSPEC int SDLCALL SDL_GetWindowBordersSize(SDL_Window * window, + int *top, int *left, + int *bottom, int *right); + +/** + * Get the size of a window in pixels. + * + * This may differ from SDL_GetWindowSize() if we're rendering to a high-DPI + * drawable, i.e. the window was created with `SDL_WINDOW_ALLOW_HIGHDPI` on a + * platform with high-DPI support (Apple calls this "Retina"), and not + * disabled by the `SDL_HINT_VIDEO_HIGHDPI_DISABLED` hint. + * + * \param window the window from which the drawable size should be queried + * \param w a pointer to variable for storing the width in pixels, may be NULL + * \param h a pointer to variable for storing the height in pixels, may be + * NULL + * + * \since This function is available since SDL 2.26.0. + * + * \sa SDL_CreateWindow + * \sa SDL_GetWindowSize + */ +extern DECLSPEC void SDLCALL SDL_GetWindowSizeInPixels(SDL_Window * window, + int *w, int *h); + +/** + * Set the minimum size of a window's client area. + * + * \param window the window to change + * \param min_w the minimum width of the window in pixels + * \param min_h the minimum height of the window in pixels + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowMinimumSize + * \sa SDL_SetWindowMaximumSize + */ +extern DECLSPEC void SDLCALL SDL_SetWindowMinimumSize(SDL_Window * window, + int min_w, int min_h); + +/** + * Get the minimum size of a window's client area. + * + * \param window the window to query + * \param w a pointer filled in with the minimum width of the window, may be + * NULL + * \param h a pointer filled in with the minimum height of the window, may be + * NULL + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowMaximumSize + * \sa SDL_SetWindowMinimumSize + */ +extern DECLSPEC void SDLCALL SDL_GetWindowMinimumSize(SDL_Window * window, + int *w, int *h); + +/** + * Set the maximum size of a window's client area. + * + * \param window the window to change + * \param max_w the maximum width of the window in pixels + * \param max_h the maximum height of the window in pixels + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowMaximumSize + * \sa SDL_SetWindowMinimumSize + */ +extern DECLSPEC void SDLCALL SDL_SetWindowMaximumSize(SDL_Window * window, + int max_w, int max_h); + +/** + * Get the maximum size of a window's client area. + * + * \param window the window to query + * \param w a pointer filled in with the maximum width of the window, may be + * NULL + * \param h a pointer filled in with the maximum height of the window, may be + * NULL + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowMinimumSize + * \sa SDL_SetWindowMaximumSize + */ +extern DECLSPEC void SDLCALL SDL_GetWindowMaximumSize(SDL_Window * window, + int *w, int *h); + +/** + * Set the border state of a window. + * + * This will add or remove the window's `SDL_WINDOW_BORDERLESS` flag and add + * or remove the border from the actual window. This is a no-op if the + * window's border already matches the requested state. + * + * You can't change the border state of a fullscreen window. + * + * \param window the window of which to change the border state + * \param bordered SDL_FALSE to remove border, SDL_TRUE to add border + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowFlags + */ +extern DECLSPEC void SDLCALL SDL_SetWindowBordered(SDL_Window * window, + SDL_bool bordered); + +/** + * Set the user-resizable state of a window. + * + * This will add or remove the window's `SDL_WINDOW_RESIZABLE` flag and + * allow/disallow user resizing of the window. This is a no-op if the window's + * resizable state already matches the requested state. + * + * You can't change the resizable state of a fullscreen window. + * + * \param window the window of which to change the resizable state + * \param resizable SDL_TRUE to allow resizing, SDL_FALSE to disallow + * + * \since This function is available since SDL 2.0.5. + * + * \sa SDL_GetWindowFlags + */ +extern DECLSPEC void SDLCALL SDL_SetWindowResizable(SDL_Window * window, + SDL_bool resizable); + +/** + * Set the window to always be above the others. + * + * This will add or remove the window's `SDL_WINDOW_ALWAYS_ON_TOP` flag. This + * will bring the window to the front and keep the window above the rest. + * + * \param window The window of which to change the always on top state + * \param on_top SDL_TRUE to set the window always on top, SDL_FALSE to + * disable + * + * \since This function is available since SDL 2.0.16. + * + * \sa SDL_GetWindowFlags + */ +extern DECLSPEC void SDLCALL SDL_SetWindowAlwaysOnTop(SDL_Window * window, + SDL_bool on_top); + +/** + * Show a window. + * + * \param window the window to show + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_HideWindow + * \sa SDL_RaiseWindow + */ +extern DECLSPEC void SDLCALL SDL_ShowWindow(SDL_Window * window); + +/** + * Hide a window. + * + * \param window the window to hide + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_ShowWindow + */ +extern DECLSPEC void SDLCALL SDL_HideWindow(SDL_Window * window); + +/** + * Raise a window above other windows and set the input focus. + * + * \param window the window to raise + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC void SDLCALL SDL_RaiseWindow(SDL_Window * window); + +/** + * Make a window as large as possible. + * + * \param window the window to maximize + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_MinimizeWindow + * \sa SDL_RestoreWindow + */ +extern DECLSPEC void SDLCALL SDL_MaximizeWindow(SDL_Window * window); + +/** + * Minimize a window to an iconic representation. + * + * \param window the window to minimize + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_MaximizeWindow + * \sa SDL_RestoreWindow + */ +extern DECLSPEC void SDLCALL SDL_MinimizeWindow(SDL_Window * window); + +/** + * Restore the size and position of a minimized or maximized window. + * + * \param window the window to restore + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_MaximizeWindow + * \sa SDL_MinimizeWindow + */ +extern DECLSPEC void SDLCALL SDL_RestoreWindow(SDL_Window * window); + +/** + * Set a window's fullscreen state. + * + * `flags` may be `SDL_WINDOW_FULLSCREEN`, for "real" fullscreen with a + * videomode change; `SDL_WINDOW_FULLSCREEN_DESKTOP` for "fake" fullscreen + * that takes the size of the desktop; and 0 for windowed mode. + * + * \param window the window to change + * \param flags `SDL_WINDOW_FULLSCREEN`, `SDL_WINDOW_FULLSCREEN_DESKTOP` or 0 + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowDisplayMode + * \sa SDL_SetWindowDisplayMode + */ +extern DECLSPEC int SDLCALL SDL_SetWindowFullscreen(SDL_Window * window, + Uint32 flags); + +/** + * Return whether the window has a surface associated with it. + * + * \returns SDL_TRUE if there is a surface associated with the window, or + * SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.28.0. + * + * \sa SDL_GetWindowSurface + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasWindowSurface(SDL_Window *window); + +/** + * Get the SDL surface associated with the window. + * + * A new surface will be created with the optimal format for the window, if + * necessary. This surface will be freed when the window is destroyed. Do not + * free this surface. + * + * This surface will be invalidated if the window is resized. After resizing a + * window this function must be called again to return a valid surface. + * + * You may not combine this with 3D or the rendering API on this window. + * + * This function is affected by `SDL_HINT_FRAMEBUFFER_ACCELERATION`. + * + * \param window the window to query + * \returns the surface associated with the window, or NULL on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_DestroyWindowSurface + * \sa SDL_HasWindowSurface + * \sa SDL_UpdateWindowSurface + * \sa SDL_UpdateWindowSurfaceRects + */ +extern DECLSPEC SDL_Surface * SDLCALL SDL_GetWindowSurface(SDL_Window * window); + +/** + * Copy the window surface to the screen. + * + * This is the function you use to reflect any changes to the surface on the + * screen. + * + * This function is equivalent to the SDL 1.2 API SDL_Flip(). + * + * \param window the window to update + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowSurface + * \sa SDL_UpdateWindowSurfaceRects + */ +extern DECLSPEC int SDLCALL SDL_UpdateWindowSurface(SDL_Window * window); + +/** + * Copy areas of the window surface to the screen. + * + * This is the function you use to reflect changes to portions of the surface + * on the screen. + * + * This function is equivalent to the SDL 1.2 API SDL_UpdateRects(). + * + * Note that this function will update _at least_ the rectangles specified, + * but this is only intended as an optimization; in practice, this might + * update more of the screen (or all of the screen!), depending on what + * method SDL uses to send pixels to the system. + * + * \param window the window to update + * \param rects an array of SDL_Rect structures representing areas of the + * surface to copy, in pixels + * \param numrects the number of rectangles + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowSurface + * \sa SDL_UpdateWindowSurface + */ +extern DECLSPEC int SDLCALL SDL_UpdateWindowSurfaceRects(SDL_Window * window, + const SDL_Rect * rects, + int numrects); + +/** + * Destroy the surface associated with the window. + * + * \param window the window to update + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.28.0. + * + * \sa SDL_GetWindowSurface + * \sa SDL_HasWindowSurface + */ +extern DECLSPEC int SDLCALL SDL_DestroyWindowSurface(SDL_Window *window); + +/** + * Set a window's input grab mode. + * + * When input is grabbed, the mouse is confined to the window. This function + * will also grab the keyboard if `SDL_HINT_GRAB_KEYBOARD` is set. To grab the + * keyboard without also grabbing the mouse, use SDL_SetWindowKeyboardGrab(). + * + * If the caller enables a grab while another window is currently grabbed, the + * other window loses its grab in favor of the caller's window. + * + * \param window the window for which the input grab mode should be set + * \param grabbed SDL_TRUE to grab input or SDL_FALSE to release input + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetGrabbedWindow + * \sa SDL_GetWindowGrab + */ +extern DECLSPEC void SDLCALL SDL_SetWindowGrab(SDL_Window * window, + SDL_bool grabbed); + +/** + * Set a window's keyboard grab mode. + * + * Keyboard grab enables capture of system keyboard shortcuts like Alt+Tab or + * the Meta/Super key. Note that not all system keyboard shortcuts can be + * captured by applications (one example is Ctrl+Alt+Del on Windows). + * + * This is primarily intended for specialized applications such as VNC clients + * or VM frontends. Normal games should not use keyboard grab. + * + * When keyboard grab is enabled, SDL will continue to handle Alt+Tab when the + * window is full-screen to ensure the user is not trapped in your + * application. If you have a custom keyboard shortcut to exit fullscreen + * mode, you may suppress this behavior with + * `SDL_HINT_ALLOW_ALT_TAB_WHILE_GRABBED`. + * + * If the caller enables a grab while another window is currently grabbed, the + * other window loses its grab in favor of the caller's window. + * + * \param window The window for which the keyboard grab mode should be set. + * \param grabbed This is SDL_TRUE to grab keyboard, and SDL_FALSE to release. + * + * \since This function is available since SDL 2.0.16. + * + * \sa SDL_GetWindowKeyboardGrab + * \sa SDL_SetWindowMouseGrab + * \sa SDL_SetWindowGrab + */ +extern DECLSPEC void SDLCALL SDL_SetWindowKeyboardGrab(SDL_Window * window, + SDL_bool grabbed); + +/** + * Set a window's mouse grab mode. + * + * Mouse grab confines the mouse cursor to the window. + * + * \param window The window for which the mouse grab mode should be set. + * \param grabbed This is SDL_TRUE to grab mouse, and SDL_FALSE to release. + * + * \since This function is available since SDL 2.0.16. + * + * \sa SDL_GetWindowMouseGrab + * \sa SDL_SetWindowKeyboardGrab + * \sa SDL_SetWindowGrab + */ +extern DECLSPEC void SDLCALL SDL_SetWindowMouseGrab(SDL_Window * window, + SDL_bool grabbed); + +/** + * Get a window's input grab mode. + * + * \param window the window to query + * \returns SDL_TRUE if input is grabbed, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetWindowGrab + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GetWindowGrab(SDL_Window * window); + +/** + * Get a window's keyboard grab mode. + * + * \param window the window to query + * \returns SDL_TRUE if keyboard is grabbed, and SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.16. + * + * \sa SDL_SetWindowKeyboardGrab + * \sa SDL_GetWindowGrab + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GetWindowKeyboardGrab(SDL_Window * window); + +/** + * Get a window's mouse grab mode. + * + * \param window the window to query + * \returns SDL_TRUE if mouse is grabbed, and SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.16. + * + * \sa SDL_SetWindowKeyboardGrab + * \sa SDL_GetWindowGrab + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GetWindowMouseGrab(SDL_Window * window); + +/** + * Get the window that currently has an input grab enabled. + * + * \returns the window if input is grabbed or NULL otherwise. + * + * \since This function is available since SDL 2.0.4. + * + * \sa SDL_GetWindowGrab + * \sa SDL_SetWindowGrab + */ +extern DECLSPEC SDL_Window * SDLCALL SDL_GetGrabbedWindow(void); + +/** + * Confines the cursor to the specified area of a window. + * + * Note that this does NOT grab the cursor, it only defines the area a cursor + * is restricted to when the window has mouse focus. + * + * \param window The window that will be associated with the barrier. + * \param rect A rectangle area in window-relative coordinates. If NULL the + * barrier for the specified window will be destroyed. + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_GetWindowMouseRect + * \sa SDL_SetWindowMouseGrab + */ +extern DECLSPEC int SDLCALL SDL_SetWindowMouseRect(SDL_Window * window, const SDL_Rect * rect); + +/** + * Get the mouse confinement rectangle of a window. + * + * \param window The window to query + * \returns A pointer to the mouse confinement rectangle of a window, or NULL + * if there isn't one. + * + * \since This function is available since SDL 2.0.18. + * + * \sa SDL_SetWindowMouseRect + */ +extern DECLSPEC const SDL_Rect * SDLCALL SDL_GetWindowMouseRect(SDL_Window * window); + +/** + * Set the brightness (gamma multiplier) for a given window's display. + * + * Despite the name and signature, this method sets the brightness of the + * entire display, not an individual window. A window is considered to be + * owned by the display that contains the window's center pixel. (The index of + * this display can be retrieved using SDL_GetWindowDisplayIndex().) The + * brightness set will not follow the window if it is moved to another + * display. + * + * Many platforms will refuse to set the display brightness in modern times. + * You are better off using a shader to adjust gamma during rendering, or + * something similar. + * + * \param window the window used to select the display whose brightness will + * be changed + * \param brightness the brightness (gamma multiplier) value to set where 0.0 + * is completely dark and 1.0 is normal brightness + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowBrightness + * \sa SDL_SetWindowGammaRamp + */ +extern DECLSPEC int SDLCALL SDL_SetWindowBrightness(SDL_Window * window, float brightness); + +/** + * Get the brightness (gamma multiplier) for a given window's display. + * + * Despite the name and signature, this method retrieves the brightness of the + * entire display, not an individual window. A window is considered to be + * owned by the display that contains the window's center pixel. (The index of + * this display can be retrieved using SDL_GetWindowDisplayIndex().) + * + * \param window the window used to select the display whose brightness will + * be queried + * \returns the brightness for the display where 0.0 is completely dark and + * 1.0 is normal brightness. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetWindowBrightness + */ +extern DECLSPEC float SDLCALL SDL_GetWindowBrightness(SDL_Window * window); + +/** + * Set the opacity for a window. + * + * The parameter `opacity` will be clamped internally between 0.0f + * (transparent) and 1.0f (opaque). + * + * This function also returns -1 if setting the opacity isn't supported. + * + * \param window the window which will be made transparent or opaque + * \param opacity the opacity value (0.0f - transparent, 1.0f - opaque) + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.5. + * + * \sa SDL_GetWindowOpacity + */ +extern DECLSPEC int SDLCALL SDL_SetWindowOpacity(SDL_Window * window, float opacity); + +/** + * Get the opacity of a window. + * + * If transparency isn't supported on this platform, opacity will be reported + * as 1.0f without error. + * + * The parameter `opacity` is ignored if it is NULL. + * + * This function also returns -1 if an invalid window was provided. + * + * \param window the window to get the current opacity value from + * \param out_opacity the float filled in (0.0f - transparent, 1.0f - opaque) + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.5. + * + * \sa SDL_SetWindowOpacity + */ +extern DECLSPEC int SDLCALL SDL_GetWindowOpacity(SDL_Window * window, float * out_opacity); + +/** + * Set the window as a modal for another window. + * + * \param modal_window the window that should be set modal + * \param parent_window the parent window for the modal window + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.5. + */ +extern DECLSPEC int SDLCALL SDL_SetWindowModalFor(SDL_Window * modal_window, SDL_Window * parent_window); + +/** + * Explicitly set input focus to the window. + * + * You almost certainly want SDL_RaiseWindow() instead of this function. Use + * this with caution, as you might give focus to a window that is completely + * obscured by other windows. + * + * \param window the window that should get the input focus + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.5. + * + * \sa SDL_RaiseWindow + */ +extern DECLSPEC int SDLCALL SDL_SetWindowInputFocus(SDL_Window * window); + +/** + * Set the gamma ramp for the display that owns a given window. + * + * Set the gamma translation table for the red, green, and blue channels of + * the video hardware. Each table is an array of 256 16-bit quantities, + * representing a mapping between the input and output for that channel. The + * input is the index into the array, and the output is the 16-bit gamma value + * at that index, scaled to the output color precision. + * + * Despite the name and signature, this method sets the gamma ramp of the + * entire display, not an individual window. A window is considered to be + * owned by the display that contains the window's center pixel. (The index of + * this display can be retrieved using SDL_GetWindowDisplayIndex().) The gamma + * ramp set will not follow the window if it is moved to another display. + * + * \param window the window used to select the display whose gamma ramp will + * be changed + * \param red a 256 element array of 16-bit quantities representing the + * translation table for the red channel, or NULL + * \param green a 256 element array of 16-bit quantities representing the + * translation table for the green channel, or NULL + * \param blue a 256 element array of 16-bit quantities representing the + * translation table for the blue channel, or NULL + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GetWindowGammaRamp + */ +extern DECLSPEC int SDLCALL SDL_SetWindowGammaRamp(SDL_Window * window, + const Uint16 * red, + const Uint16 * green, + const Uint16 * blue); + +/** + * Get the gamma ramp for a given window's display. + * + * Despite the name and signature, this method retrieves the gamma ramp of the + * entire display, not an individual window. A window is considered to be + * owned by the display that contains the window's center pixel. (The index of + * this display can be retrieved using SDL_GetWindowDisplayIndex().) + * + * \param window the window used to select the display whose gamma ramp will + * be queried + * \param red a 256 element array of 16-bit quantities filled in with the + * translation table for the red channel, or NULL + * \param green a 256 element array of 16-bit quantities filled in with the + * translation table for the green channel, or NULL + * \param blue a 256 element array of 16-bit quantities filled in with the + * translation table for the blue channel, or NULL + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_SetWindowGammaRamp + */ +extern DECLSPEC int SDLCALL SDL_GetWindowGammaRamp(SDL_Window * window, + Uint16 * red, + Uint16 * green, + Uint16 * blue); + +/** + * Possible return values from the SDL_HitTest callback. + * + * \sa SDL_HitTest + */ +typedef enum +{ + SDL_HITTEST_NORMAL, /**< Region is normal. No special properties. */ + SDL_HITTEST_DRAGGABLE, /**< Region can drag entire window. */ + SDL_HITTEST_RESIZE_TOPLEFT, + SDL_HITTEST_RESIZE_TOP, + SDL_HITTEST_RESIZE_TOPRIGHT, + SDL_HITTEST_RESIZE_RIGHT, + SDL_HITTEST_RESIZE_BOTTOMRIGHT, + SDL_HITTEST_RESIZE_BOTTOM, + SDL_HITTEST_RESIZE_BOTTOMLEFT, + SDL_HITTEST_RESIZE_LEFT +} SDL_HitTestResult; + +/** + * Callback used for hit-testing. + * + * \param win the SDL_Window where hit-testing was set on + * \param area an SDL_Point which should be hit-tested + * \param data what was passed as `callback_data` to SDL_SetWindowHitTest() + * \return an SDL_HitTestResult value. + * + * \sa SDL_SetWindowHitTest + */ +typedef SDL_HitTestResult (SDLCALL *SDL_HitTest)(SDL_Window *win, + const SDL_Point *area, + void *data); + +/** + * Provide a callback that decides if a window region has special properties. + * + * Normally windows are dragged and resized by decorations provided by the + * system window manager (a title bar, borders, etc), but for some apps, it + * makes sense to drag them from somewhere else inside the window itself; for + * example, one might have a borderless window that wants to be draggable from + * any part, or simulate its own title bar, etc. + * + * This function lets the app provide a callback that designates pieces of a + * given window as special. This callback is run during event processing if we + * need to tell the OS to treat a region of the window specially; the use of + * this callback is known as "hit testing." + * + * Mouse input may not be delivered to your application if it is within a + * special area; the OS will often apply that input to moving the window or + * resizing the window and not deliver it to the application. + * + * Specifying NULL for a callback disables hit-testing. Hit-testing is + * disabled by default. + * + * Platforms that don't support this functionality will return -1 + * unconditionally, even if you're attempting to disable hit-testing. + * + * Your callback may fire at any time, and its firing does not indicate any + * specific behavior (for example, on Windows, this certainly might fire when + * the OS is deciding whether to drag your window, but it fires for lots of + * other reasons, too, some unrelated to anything you probably care about _and + * when the mouse isn't actually at the location it is testing_). Since this + * can fire at any time, you should try to keep your callback efficient, + * devoid of allocations, etc. + * + * \param window the window to set hit-testing on + * \param callback the function to call when doing a hit-test + * \param callback_data an app-defined void pointer passed to **callback** + * \returns 0 on success or -1 on error (including unsupported); call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.4. + */ +extern DECLSPEC int SDLCALL SDL_SetWindowHitTest(SDL_Window * window, + SDL_HitTest callback, + void *callback_data); + +/** + * Request a window to demand attention from the user. + * + * \param window the window to be flashed + * \param operation the flash operation + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.16. + */ +extern DECLSPEC int SDLCALL SDL_FlashWindow(SDL_Window * window, SDL_FlashOperation operation); + +/** + * Destroy a window. + * + * If `window` is NULL, this function will return immediately after setting + * the SDL error message to "Invalid window". See SDL_GetError(). + * + * \param window the window to destroy + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_CreateWindow + * \sa SDL_CreateWindowFrom + */ +extern DECLSPEC void SDLCALL SDL_DestroyWindow(SDL_Window * window); + + +/** + * Check whether the screensaver is currently enabled. + * + * The screensaver is disabled by default since SDL 2.0.2. Before SDL 2.0.2 + * the screensaver was enabled by default. + * + * The default can also be changed using `SDL_HINT_VIDEO_ALLOW_SCREENSAVER`. + * + * \returns SDL_TRUE if the screensaver is enabled, SDL_FALSE if it is + * disabled. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_DisableScreenSaver + * \sa SDL_EnableScreenSaver + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IsScreenSaverEnabled(void); + +/** + * Allow the screen to be blanked by a screen saver. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_DisableScreenSaver + * \sa SDL_IsScreenSaverEnabled + */ +extern DECLSPEC void SDLCALL SDL_EnableScreenSaver(void); + +/** + * Prevent the screen from being blanked by a screen saver. + * + * If you disable the screensaver, it is automatically re-enabled when SDL + * quits. + * + * The screensaver is disabled by default since SDL 2.0.2. Before SDL 2.0.2 + * the screensaver was enabled by default. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_EnableScreenSaver + * \sa SDL_IsScreenSaverEnabled + */ +extern DECLSPEC void SDLCALL SDL_DisableScreenSaver(void); + + +/** + * \name OpenGL support functions + */ +/* @{ */ + +/** + * Dynamically load an OpenGL library. + * + * This should be done after initializing the video driver, but before + * creating any OpenGL windows. If no OpenGL library is loaded, the default + * library will be loaded upon creation of the first OpenGL window. + * + * If you do this, you need to retrieve all of the GL functions used in your + * program from the dynamic library using SDL_GL_GetProcAddress(). + * + * \param path the platform dependent OpenGL library name, or NULL to open the + * default OpenGL library + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GL_GetProcAddress + * \sa SDL_GL_UnloadLibrary + */ +extern DECLSPEC int SDLCALL SDL_GL_LoadLibrary(const char *path); + +/** + * Get an OpenGL function by name. + * + * If the GL library is loaded at runtime with SDL_GL_LoadLibrary(), then all + * GL functions must be retrieved this way. Usually this is used to retrieve + * function pointers to OpenGL extensions. + * + * There are some quirks to looking up OpenGL functions that require some + * extra care from the application. If you code carefully, you can handle + * these quirks without any platform-specific code, though: + * + * - On Windows, function pointers are specific to the current GL context; + * this means you need to have created a GL context and made it current + * before calling SDL_GL_GetProcAddress(). If you recreate your context or + * create a second context, you should assume that any existing function + * pointers aren't valid to use with it. This is (currently) a + * Windows-specific limitation, and in practice lots of drivers don't suffer + * this limitation, but it is still the way the wgl API is documented to + * work and you should expect crashes if you don't respect it. Store a copy + * of the function pointers that comes and goes with context lifespan. + * - On X11, function pointers returned by this function are valid for any + * context, and can even be looked up before a context is created at all. + * This means that, for at least some common OpenGL implementations, if you + * look up a function that doesn't exist, you'll get a non-NULL result that + * is _NOT_ safe to call. You must always make sure the function is actually + * available for a given GL context before calling it, by checking for the + * existence of the appropriate extension with SDL_GL_ExtensionSupported(), + * or verifying that the version of OpenGL you're using offers the function + * as core functionality. + * - Some OpenGL drivers, on all platforms, *will* return NULL if a function + * isn't supported, but you can't count on this behavior. Check for + * extensions you use, and if you get a NULL anyway, act as if that + * extension wasn't available. This is probably a bug in the driver, but you + * can code defensively for this scenario anyhow. + * - Just because you're on Linux/Unix, don't assume you'll be using X11. + * Next-gen display servers are waiting to replace it, and may or may not + * make the same promises about function pointers. + * - OpenGL function pointers must be declared `APIENTRY` as in the example + * code. This will ensure the proper calling convention is followed on + * platforms where this matters (Win32) thereby avoiding stack corruption. + * + * \param proc the name of an OpenGL function + * \returns a pointer to the named OpenGL function. The returned pointer + * should be cast to the appropriate function signature. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GL_ExtensionSupported + * \sa SDL_GL_LoadLibrary + * \sa SDL_GL_UnloadLibrary + */ +extern DECLSPEC void *SDLCALL SDL_GL_GetProcAddress(const char *proc); + +/** + * Unload the OpenGL library previously loaded by SDL_GL_LoadLibrary(). + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GL_LoadLibrary + */ +extern DECLSPEC void SDLCALL SDL_GL_UnloadLibrary(void); + +/** + * Check if an OpenGL extension is supported for the current context. + * + * This function operates on the current GL context; you must have created a + * context and it must be current before calling this function. Do not assume + * that all contexts you create will have the same set of extensions + * available, or that recreating an existing context will offer the same + * extensions again. + * + * While it's probably not a massive overhead, this function is not an O(1) + * operation. Check the extensions you care about after creating the GL + * context and save that information somewhere instead of calling the function + * every time you need to know. + * + * \param extension the name of the extension to check + * \returns SDL_TRUE if the extension is supported, SDL_FALSE otherwise. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_GL_ExtensionSupported(const char + *extension); + +/** + * Reset all previously set OpenGL context attributes to their default values. + * + * \since This function is available since SDL 2.0.2. + * + * \sa SDL_GL_GetAttribute + * \sa SDL_GL_SetAttribute + */ +extern DECLSPEC void SDLCALL SDL_GL_ResetAttributes(void); + +/** + * Set an OpenGL window attribute before window creation. + * + * This function sets the OpenGL attribute `attr` to `value`. The requested + * attributes should be set before creating an OpenGL window. You should use + * SDL_GL_GetAttribute() to check the values after creating the OpenGL + * context, since the values obtained can differ from the requested ones. + * + * \param attr an SDL_GLattr enum value specifying the OpenGL attribute to set + * \param value the desired value for the attribute + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GL_GetAttribute + * \sa SDL_GL_ResetAttributes + */ +extern DECLSPEC int SDLCALL SDL_GL_SetAttribute(SDL_GLattr attr, int value); + +/** + * Get the actual value for an attribute from the current context. + * + * \param attr an SDL_GLattr enum value specifying the OpenGL attribute to get + * \param value a pointer filled in with the current value of `attr` + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GL_ResetAttributes + * \sa SDL_GL_SetAttribute + */ +extern DECLSPEC int SDLCALL SDL_GL_GetAttribute(SDL_GLattr attr, int *value); + +/** + * Create an OpenGL context for an OpenGL window, and make it current. + * + * Windows users new to OpenGL should note that, for historical reasons, GL + * functions added after OpenGL version 1.1 are not available by default. + * Those functions must be loaded at run-time, either with an OpenGL + * extension-handling library or with SDL_GL_GetProcAddress() and its related + * functions. + * + * SDL_GLContext is an alias for `void *`. It's opaque to the application. + * + * \param window the window to associate with the context + * \returns the OpenGL context associated with `window` or NULL on error; call + * SDL_GetError() for more details. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GL_DeleteContext + * \sa SDL_GL_MakeCurrent + */ +extern DECLSPEC SDL_GLContext SDLCALL SDL_GL_CreateContext(SDL_Window * + window); + +/** + * Set up an OpenGL context for rendering into an OpenGL window. + * + * The context must have been created with a compatible window. + * + * \param window the window to associate with the context + * \param context the OpenGL context to associate with the window + * \returns 0 on success or a negative error code on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GL_CreateContext + */ +extern DECLSPEC int SDLCALL SDL_GL_MakeCurrent(SDL_Window * window, + SDL_GLContext context); + +/** + * Get the currently active OpenGL window. + * + * \returns the currently active OpenGL window on success or NULL on failure; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC SDL_Window* SDLCALL SDL_GL_GetCurrentWindow(void); + +/** + * Get the currently active OpenGL context. + * + * \returns the currently active OpenGL context or NULL on failure; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GL_MakeCurrent + */ +extern DECLSPEC SDL_GLContext SDLCALL SDL_GL_GetCurrentContext(void); + +/** + * Get the size of a window's underlying drawable in pixels. + * + * This returns info useful for calling glViewport(). + * + * This may differ from SDL_GetWindowSize() if we're rendering to a high-DPI + * drawable, i.e. the window was created with `SDL_WINDOW_ALLOW_HIGHDPI` on a + * platform with high-DPI support (Apple calls this "Retina"), and not + * disabled by the `SDL_HINT_VIDEO_HIGHDPI_DISABLED` hint. + * + * \param window the window from which the drawable size should be queried + * \param w a pointer to variable for storing the width in pixels, may be NULL + * \param h a pointer to variable for storing the height in pixels, may be + * NULL + * + * \since This function is available since SDL 2.0.1. + * + * \sa SDL_CreateWindow + * \sa SDL_GetWindowSize + */ +extern DECLSPEC void SDLCALL SDL_GL_GetDrawableSize(SDL_Window * window, int *w, + int *h); + +/** + * Set the swap interval for the current OpenGL context. + * + * Some systems allow specifying -1 for the interval, to enable adaptive + * vsync. Adaptive vsync works the same as vsync, but if you've already missed + * the vertical retrace for a given frame, it swaps buffers immediately, which + * might be less jarring for the user during occasional framerate drops. If an + * application requests adaptive vsync and the system does not support it, + * this function will fail and return -1. In such a case, you should probably + * retry the call with 1 for the interval. + * + * Adaptive vsync is implemented for some glX drivers with + * GLX_EXT_swap_control_tear, and for some Windows drivers with + * WGL_EXT_swap_control_tear. + * + * Read more on the Khronos wiki: + * https://www.khronos.org/opengl/wiki/Swap_Interval#Adaptive_Vsync + * + * \param interval 0 for immediate updates, 1 for updates synchronized with + * the vertical retrace, -1 for adaptive vsync + * \returns 0 on success or -1 if setting the swap interval is not supported; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GL_GetSwapInterval + */ +extern DECLSPEC int SDLCALL SDL_GL_SetSwapInterval(int interval); + +/** + * Get the swap interval for the current OpenGL context. + * + * If the system can't determine the swap interval, or there isn't a valid + * current context, this function will return 0 as a safe default. + * + * \returns 0 if there is no vertical retrace synchronization, 1 if the buffer + * swap is synchronized with the vertical retrace, and -1 if late + * swaps happen immediately instead of waiting for the next retrace; + * call SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GL_SetSwapInterval + */ +extern DECLSPEC int SDLCALL SDL_GL_GetSwapInterval(void); + +/** + * Update a window with OpenGL rendering. + * + * This is used with double-buffered OpenGL contexts, which are the default. + * + * On macOS, make sure you bind 0 to the draw framebuffer before swapping the + * window, otherwise nothing will happen. If you aren't using + * glBindFramebuffer(), this is the default and you won't have to do anything + * extra. + * + * \param window the window to change + * + * \since This function is available since SDL 2.0.0. + */ +extern DECLSPEC void SDLCALL SDL_GL_SwapWindow(SDL_Window * window); + +/** + * Delete an OpenGL context. + * + * \param context the OpenGL context to be deleted + * + * \since This function is available since SDL 2.0.0. + * + * \sa SDL_GL_CreateContext + */ +extern DECLSPEC void SDLCALL SDL_GL_DeleteContext(SDL_GLContext context); + +/* @} *//* OpenGL support functions */ + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_video_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/include/SDL_vulkan.h b/SDL2-2.30.5/include/SDL_vulkan.h new file mode 100644 index 0000000..ab86a0b --- /dev/null +++ b/SDL2-2.30.5/include/SDL_vulkan.h @@ -0,0 +1,215 @@ +/* + Simple DirectMedia Layer + Copyright (C) 2017, Mark Callow + + 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_vulkan.h + * + * Header file for functions to creating Vulkan surfaces on SDL windows. + */ + +#ifndef SDL_vulkan_h_ +#define SDL_vulkan_h_ + +#include "SDL_video.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Avoid including vulkan.h, don't define VkInstance if it's already included */ +#ifdef VULKAN_H_ +#define NO_SDL_VULKAN_TYPEDEFS +#endif +#ifndef NO_SDL_VULKAN_TYPEDEFS +#define VK_DEFINE_HANDLE(object) typedef struct object##_T* object; + +#if defined(__LP64__) || defined(_WIN64) || defined(__x86_64__) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__) +#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T *object; +#else +#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object; +#endif + +VK_DEFINE_HANDLE(VkInstance) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR) + +#endif /* !NO_SDL_VULKAN_TYPEDEFS */ + +typedef VkInstance SDL_vulkanInstance; +typedef VkSurfaceKHR SDL_vulkanSurface; /* for compatibility with Tizen */ + +/** + * \name Vulkan support functions + * + * \note SDL_Vulkan_GetInstanceExtensions & SDL_Vulkan_CreateSurface API + * is compatable with Tizen's implementation of Vulkan in SDL. + */ +/* @{ */ + +/** + * Dynamically load the Vulkan loader library. + * + * This should be called after initializing the video driver, but before + * creating any Vulkan windows. If no Vulkan loader library is loaded, the + * default library will be loaded upon creation of the first Vulkan window. + * + * It is fairly common for Vulkan applications to link with libvulkan instead + * of explicitly loading it at run time. This will work with SDL provided the + * application links to a dynamic library and both it and SDL use the same + * search path. + * + * If you specify a non-NULL `path`, an application should retrieve all of the + * Vulkan functions it uses from the dynamic library using + * SDL_Vulkan_GetVkGetInstanceProcAddr unless you can guarantee `path` points + * to the same vulkan loader library the application linked to. + * + * On Apple devices, if `path` is NULL, SDL will attempt to find the + * `vkGetInstanceProcAddr` address within all the Mach-O images of the current + * process. This is because it is fairly common for Vulkan applications to + * link with libvulkan (and historically MoltenVK was provided as a static + * library). If it is not found, on macOS, SDL will attempt to load + * `vulkan.framework/vulkan`, `libvulkan.1.dylib`, + * `MoltenVK.framework/MoltenVK`, and `libMoltenVK.dylib`, in that order. On + * iOS, SDL will attempt to load `libMoltenVK.dylib`. Applications using a + * dynamic framework or .dylib must ensure it is included in its application + * bundle. + * + * On non-Apple devices, application linking with a static libvulkan is not + * supported. Either do not link to the Vulkan loader or link to a dynamic + * library version. + * + * \param path The platform dependent Vulkan loader library name or NULL + * \returns 0 on success or -1 if the library couldn't be loaded; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 2.0.6. + * + * \sa SDL_Vulkan_GetVkInstanceProcAddr + * \sa SDL_Vulkan_UnloadLibrary + */ +extern DECLSPEC int SDLCALL SDL_Vulkan_LoadLibrary(const char *path); + +/** + * Get the address of the `vkGetInstanceProcAddr` function. + * + * This should be called after either calling SDL_Vulkan_LoadLibrary() or + * creating an SDL_Window with the `SDL_WINDOW_VULKAN` flag. + * + * \returns the function pointer for `vkGetInstanceProcAddr` or NULL on error. + * + * \since This function is available since SDL 2.0.6. + */ +extern DECLSPEC void *SDLCALL SDL_Vulkan_GetVkGetInstanceProcAddr(void); + +/** + * Unload the Vulkan library previously loaded by SDL_Vulkan_LoadLibrary() + * + * \since This function is available since SDL 2.0.6. + * + * \sa SDL_Vulkan_LoadLibrary + */ +extern DECLSPEC void SDLCALL SDL_Vulkan_UnloadLibrary(void); + +/** + * Get the names of the Vulkan instance extensions needed to create a surface + * with SDL_Vulkan_CreateSurface. + * + * If `pNames` is NULL, then the number of required Vulkan instance extensions + * is returned in `pCount`. Otherwise, `pCount` must point to a variable set + * to the number of elements in the `pNames` array, and on return the variable + * is overwritten with the number of names actually written to `pNames`. If + * `pCount` is less than the number of required extensions, at most `pCount` + * structures will be written. If `pCount` is smaller than the number of + * required extensions, SDL_FALSE will be returned instead of SDL_TRUE, to + * indicate that not all the required extensions were returned. + * + * The `window` parameter is currently needed to be valid as of SDL 2.0.8, + * however, this parameter will likely be removed in future releases + * + * \param window A window for which the required Vulkan instance extensions + * should be retrieved (will be deprecated in a future release) + * \param pCount A pointer to an unsigned int corresponding to the number of + * extensions to be returned + * \param pNames NULL or a pointer to an array to be filled with required + * Vulkan instance extensions + * \returns SDL_TRUE on success, SDL_FALSE on error. + * + * \since This function is available since SDL 2.0.6. + * + * \sa SDL_Vulkan_CreateSurface + */ +extern DECLSPEC SDL_bool SDLCALL SDL_Vulkan_GetInstanceExtensions(SDL_Window *window, + unsigned int *pCount, + const char **pNames); + +/** + * Create a Vulkan rendering surface for a window. + * + * The `window` must have been created with the `SDL_WINDOW_VULKAN` flag and + * `instance` must have been created with extensions returned by + * SDL_Vulkan_GetInstanceExtensions() enabled. + * + * \param window The window to which to attach the Vulkan surface + * \param instance The Vulkan instance handle + * \param surface A pointer to a VkSurfaceKHR handle to output the newly + * created surface + * \returns SDL_TRUE on success, SDL_FALSE on error. + * + * \since This function is available since SDL 2.0.6. + * + * \sa SDL_Vulkan_GetInstanceExtensions + * \sa SDL_Vulkan_GetDrawableSize + */ +extern DECLSPEC SDL_bool SDLCALL SDL_Vulkan_CreateSurface(SDL_Window *window, + VkInstance instance, + VkSurfaceKHR* surface); + +/** + * Get the size of the window's underlying drawable dimensions in pixels. + * + * This may differ from SDL_GetWindowSize() if we're rendering to a high-DPI + * drawable, i.e. the window was created with `SDL_WINDOW_ALLOW_HIGHDPI` on a + * platform with high-DPI support (Apple calls this "Retina"), and not + * disabled by the `SDL_HINT_VIDEO_HIGHDPI_DISABLED` hint. + * + * \param window an SDL_Window for which the size is to be queried + * \param w Pointer to the variable to write the width to or NULL + * \param h Pointer to the variable to write the height to or NULL + * + * \since This function is available since SDL 2.0.6. + * + * \sa SDL_GetWindowSize + * \sa SDL_CreateWindow + * \sa SDL_Vulkan_CreateSurface + */ +extern DECLSPEC void SDLCALL SDL_Vulkan_GetDrawableSize(SDL_Window * window, + int *w, int *h); + +/* @} *//* Vulkan support functions */ + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* SDL_vulkan_h_ */ diff --git a/SDL2-2.0.12/include/begin_code.h b/SDL2-2.30.5/include/begin_code.h similarity index 77% rename from SDL2-2.0.12/include/begin_code.h rename to SDL2-2.30.5/include/begin_code.h index 170d69e..a47a7d2 100644 --- a/SDL2-2.0.12/include/begin_code.h +++ b/SDL2-2.30.5/include/begin_code.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -28,14 +28,16 @@ */ /* This shouldn't be nested -- included it around code only. */ -#ifdef _begin_code_h +#ifdef SDL_begin_code_h #error Nested inclusion of begin_code.h #endif -#define _begin_code_h +#define SDL_begin_code_h #ifndef SDL_DEPRECATED -# if (__GNUC__ >= 4) /* technically, this arrived in gcc 3.1, but oh well. */ +# if defined(__GNUC__) && (__GNUC__ >= 4) /* technically, this arrived in gcc 3.1, but oh well. */ # define SDL_DEPRECATED __attribute__((deprecated)) +# elif defined(_MSC_VER) +# define SDL_DEPRECATED __declspec(deprecated) # else # define SDL_DEPRECATED # endif @@ -51,15 +53,11 @@ /* Some compilers use a special export keyword */ #ifndef DECLSPEC -# if defined(__WIN32__) || defined(__WINRT__) -# ifdef __BORLANDC__ -# ifdef BUILD_SDL -# define DECLSPEC -# else -# define DECLSPEC __declspec(dllimport) -# endif -# else +# if defined(__WIN32__) || defined(__WINRT__) || defined(__CYGWIN__) || defined(__GDK__) +# ifdef DLL_EXPORT # define DECLSPEC __declspec(dllexport) +# else +# define DECLSPEC # endif # elif defined(__OS2__) # ifdef BUILD_SDL @@ -78,7 +76,7 @@ /* By default SDL uses the C calling convention */ #ifndef SDLCALL -#if (defined(__WIN32__) || defined(__WINRT__)) && !defined(__GNUC__) +#if (defined(__WIN32__) || defined(__WINRT__) || defined(__GDK__)) && !defined(__GNUC__) #define SDLCALL __cdecl #elif defined(__OS2__) || defined(__EMX__) #define SDLCALL _System @@ -111,7 +109,7 @@ #ifdef __BORLANDC__ #pragma nopackwarning #endif -#ifdef _M_X64 +#ifdef _WIN64 /* Use 8-byte alignment on 64-bit architectures, so pointers are aligned */ #pragma pack(push,8) #else @@ -168,3 +166,24 @@ #endif #endif /* NULL */ #endif /* ! Mac OS X - breaks precompiled headers */ + +#ifndef SDL_FALLTHROUGH +#if (defined(__cplusplus) && __cplusplus >= 201703L) || \ + (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202000L) +#define SDL_FALLTHROUGH [[fallthrough]] +#else +#if defined(__has_attribute) +#define SDL_HAS_FALLTHROUGH __has_attribute(__fallthrough__) +#else +#define SDL_HAS_FALLTHROUGH 0 +#endif /* __has_attribute */ +#if SDL_HAS_FALLTHROUGH && \ + ((defined(__GNUC__) && __GNUC__ >= 7) || \ + (defined(__clang_major__) && __clang_major__ >= 10)) +#define SDL_FALLTHROUGH __attribute__((__fallthrough__)) +#else +#define SDL_FALLTHROUGH do {} while (0) /* fallthrough */ +#endif /* SDL_HAS_FALLTHROUGH */ +#undef SDL_HAS_FALLTHROUGH +#endif /* C++17 or C2x */ +#endif /* SDL_FALLTHROUGH not defined */ diff --git a/SDL2-2.0.12/include/close_code.h b/SDL2-2.30.5/include/close_code.h similarity index 92% rename from SDL2-2.0.12/include/close_code.h rename to SDL2-2.30.5/include/close_code.h index 6aa411b..50a0e6f 100644 --- a/SDL2-2.0.12/include/close_code.h +++ b/SDL2-2.30.5/include/close_code.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,10 +26,10 @@ * after you finish any function and structure declarations in your headers */ -#ifndef _begin_code_h +#ifndef SDL_begin_code_h #error close_code.h included without matching begin_code.h #endif -#undef _begin_code_h +#undef SDL_begin_code_h /* Reset structure packing at previous byte alignment */ #if defined(_MSC_VER) || defined(__MWERKS__) || defined(__BORLANDC__) diff --git a/SDL2-2.30.5/lib/x64/SDL2.dll b/SDL2-2.30.5/lib/x64/SDL2.dll new file mode 100644 index 0000000000000000000000000000000000000000..57dacb7b758283d216bb9b12cc4e9ed2a2a88ae7 GIT binary patch literal 2531840 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

IG<<12Cwl&&0bVPsDAa19;+muEuv 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

AlKA@>-+UZ>L``*6Yha3v>!E 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

xPMyc?==RjK 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%0AQdF{?!mCf3`1k<{VB!RiKaKWPTSxgVhCLCx@vtg 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

S)W0`(}U_q-*3GNgP8bTHFbo510c|(~y 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

VCc%5 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

nX=kRk-wx`J?mM|dM=N%3j;5X`QofZ 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 z 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

S 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 z zxC}W8N2>nHgFB85Ir1t93|6E~w!ZbGzX}EOv{+M3;8J(7*y#-gp26=r|b#FaO8K$YY2|~ z?Vmf2EIW{L=y?@)F~YPAj9xv1}pw0Q}`qQlJod0f9*7X(-?#M;DTlTCDRoxyvdlO`^ivNVfFG#zg>z{I%mNvvqG-{OQE_Qxo}NAT0Y7 z*&UZ1Zg(7@qqX3DB)emrL2P%_MqQjf<9pSWB%eLhHBrlrn5nnJ> zjpUYIeqjorz_0wMk*Mmr>rS?V4ox>;|uZKm56aLssU zHbz+?<$%y_mu<)q#EcghWDrt$y>3z7GLh*BBs>%Nkrh(X*LMcH5mL*OvMljy21lJz zDN~ZnT!=auBC$5 z-W7E>cfQG~yit52PhDg5h_TIl4R%2K*!-(q$!30pP<^!6cU#fSJ7Q;D+li%fB;^h> z)buECA(B{I<38KKD=j83mNk7$*vc#=xrhA@zL}>F#$JlmA=oA3E1&GbQS}29;JdJt zxpu@(Bt)kxtz+mq13>Bqo}ZB6@#?{bM;RH}LcpLj!=qME{iIVZmov(+Im)nYmx9R7 zZ2OP%n>XU(a=-;reH2P?b$Xx$`d=S=ZJVGc|EcK+rv8W@1EIZJWlK$K@Q1-@nSDc8M;m_ z(O6oij_i)2L1~>@$z&;2r9;OL(b_R+Kmu9j)5%`Bs3oDp3aafbBEIkh@7^%M5tXcU zYQrJ2t{%CeY0?V0n3eU-8r*-`XC3Q!=31v#TaLU=t*XD#I`zrqb!5C~DF>}n_o|dK ze`J+kwoa`|9KKFH)b6NEBD))yMR>8HoT6KqP(T@SgqKHakuG_Vu8w__1ENCMPPo$27e4ge zFN@h1M*OAzMiLmfU|37XjR;?In0Zz*Kx>0+ctcVl2Z0j6$*d=<*WM_*cPs*t(at;} ziUp1p5hMl^C7=v$A?{o(4?>JM^py}}5iI(>xyKbI(w;qoaU#H1z{HMVH;6h2C^~%A zS?tlGr_iFGr!Jtl%K;KCGN5QH>JAj~r;LE2njYgq?M#f61UWZ0jGu6=42&^o=lfq}(uAZ^*3Gz|~n z(W+)K#1}Kf?JgY-!GMJnoffj=S9w-vH%D3N@*78-wyV{Y4>19BBM_lTBCJSRjtCtP zel7-ta|8%4ECIreZvqIvb8LX{0l}xCJJc#bHZit397e_Psfe3+I2ulROZbRY=ra3Z zF9i7&$AkTsA3r?!9r7B22dBCH@aKpJSC{=a=)Aw?r_ameKJ-`DjFydV3q6|wIIq@U z+#zx0`@stKckM~c$yGMVtfyO4f*&+irh<;?9M(TA75pGw5iYB)B5)*s$MJU*e<$+y z#9Z=Fn5rJb>!hG1&6$0h*}X>w!*toqj+*cVN22<1wk>e(73zxNl!cg%9fffa>&cx3|qrJdqxLx81vx8Gf5h z>r${jf7Ra)eLK1*Oa2raTNMUbG|89 z)5Z5myyb&6ok7RkVX3M6l8NnHg|Ic5yZNMHw662jkt=r}V$$L(IPR3(&7%~U%-v*v z`Pg|N`o40PVkJ9wk5a*>@G~Y@lw7%c*#7*U;hnpN2OT>Wt=!dnLTdDm(c2b1GAmkPSc>xE_WNI$uP zp)hULwQM@Y^SGL*Q{rJ44bz!F4X(SuQan2IwV>rabZNSI!+C?$>G+<7pyT3Ulrm0v zO;UxbZG2r>U6op;DYIr9V~oMILlODgo0|FvB-tdgaPvfh297hDL=DuCIf1};Dv5;hRx z?&w?;e*9p~%ss(%yXliO#uxR1j!_pC(_uuyFd|`VHN#vM7=2~Djte@f^xDoV;=tC5 zlmX-nIz~acs-!4v94k-Tw&q$AfmChFHFp3cCUH0UK5+wJd7MX9G%xO6zF+Ri|_ zT9U7OwP;x_mNVl}ZF7DkQ^F-+O1z3L^!dSo`)jsfjN&s>Vtq2v6?9BUP2EG!K2(#t z*?4wRgVj6Yqx8arnznhb^38fFVo!=vid7a@-KGSuCEMn`?(*Qx@-7U?Tltpq4)4F< z#`7nvd@K?glinS^+V*IA)uif0$#5RR?OktD`BdB3A^9Jv?moLZM_PMbzHEr6+PDd+ zwoks+_DP!asY63btI6GDWKo`x+)BbfBI+fJ{MGU;veJ=cSb)EM^u}@T;Mj+@O^d=$ z9z;BiFy-ewvaL=*}U5YJ3iXqO#@2ZK96!Xy)4XBv|!F9`--ZN9x z(}I@a2?ohfA-3q8cz?e5sCr8oO=R#Qy);nPH8EC#HGPbeZJ0Fq$T*?OF-d}~a%9`1ZOMv7;n@C7 zLg)}J90;F321zw=bV+py)e*v-6pJfJBF1LC7RhBZm19dZbKU+9*$`LB=1$mm=SUIS z2iqpb*XD$9sm;@9iUwA5CK;U~z(0nxtnyCrbl*P}ViMTOuB?zcipG!fA$XuWu_Oqw{O2ibE(snm&7s)A;bR8rj~l^&9u zi3Loq#ieeHuWp<)k`&`W2B}1T=tmnbcAb}XSvZlXjQA}PE}*HURRF0-;AA zLH{~+@f*mW^RF5ze=aTRU%?L$KWHn#4=x?aU(~NlNAVZ+>(Zk7C5GMddb#*P{o-oO zmr%dj>)B<(sGJ0Oz_^)6xJp?a6;C5i39n)~1zqcyOL%!JIQy}8!a`NTw(>Pi>D zwR2b1=slyiHElZ-qKkZ7de-sFeDof&XX=jf0zUORMW1wBODI)88NQR;KP6>~u?;qL z+4~lBsfnGvqYl@h$V~XXYIJAQR?xvZ(Au2WVfSNP)UB^53Z7W6k_x5scNkyGE-tB1 z%OrdlBuo;7j}M?&g?co&ZUyt0!7vk+8?=}^&(Y-%b&B;UlyTMYD0+Hm?%q+IyQ`!(jX4w!CusOol$p(CdXod)H`1G8-VlvJ%e-^< zM8N#$ZKC%&#v+~B|DO^>=%B|>Wx70paVNeBFcLszDwD24HilLv?anz9`JUbvB~cYuY68&I%9Hn@BXNOmA|N$WXnh^RXhSQ7R!db93kDEn^^uXq}X* zWYj*grsPVhX<#nA${4X34vgZm9!zB7qb~I#5!PWAV19Piny{6C-I!p&C&Q1uZVJ)? zdO_wdSCC?1D^*)th-f8Y3!q}ax}dfKR(mf2 zA=(m%OMc()Ip^M)3=>NGw*9|v|M1bwy=OnqdCs$+a~)B=HW@d9zGQ1iWl}=|2oVtR z9KPi&n}gDqs4nI9mT+wbqChki*+|Ky3`xD+X4cSuoK3>)qZ*;LCypP99W9X8Tn4Tb z=PW+#e6zF<-g(0j_|p$(|LgdZ10DZg=16i}2ZkfOnYLMlDTQWXT5#2>YhK`oni49MIFYD}I)dMtU=m@h5$5j!BAkzsKlKFcWJc7#0c@K;t?9;}C?HJwm-459wBUh1Q2`S2aB`NELtP3yDV}}( z8~KxRTzL_k-UJ=P7w5o|2D~q>>CT{h(d;L$hTCa%Opk&eYtGRrQiq^O@q^3ks%RTM zSzTyv8rwS!7IOUahQAVCEL!ivZ^!I+!kv|8+4r#Pv!E3%(hdJV)E4$eh{5e7Z7EZ_-fD6C2_X<&}qgwqN;yp@LElhnkcL7_G! zOaw|I*_D`MbeS+bk+pa8N(pG-Pi|lEDQZ)#*#cQ$@`62YKYCoRBwPU3aziNtAGnr8 zKC~(smQ6q<0!mOrx|gby#6u69Pc-X=4~9Ew((A$5bTH8^g`wcGSIhAPTWeVeu%tPU zs*=zMk~yA~Qh@t{v=zM-i2De~hOI+M5CcmA)?N6&NxD9u(mwY(-G11TiQ5q~8xgl1 zrB_Pu@%Zi7{7Kwy%=|2VGoFAJgn0m+`~!HK=zj!8$KkDTJFVqzOc5w7ola#Xo!XKP zp+PBl9p+-PG^lIiH7Ft@Y*&_V=~3W^GVT%RWKB@802E~cf?!ww(gVmJr|v%4-u%($wL6-NS0|P!M2xY+4gkj zS5^=Oxfa(X-nQrI#*_TyNyLBUbA@#;A*iAUM>LAoVAe{kW`jC`!OLzq&_K`F3T$j|W^;@uT?U@iayU;qRq!M%wSTPSNgGmV=%Yu|Wnq&t z^m$6Y)|T8%u2j;Y1)a&bk-`^YZ-RG;EeQomkxJoOf*0}~>0LUgoRDJDu^C$20MmdA zUhpDm23>ZNBTsno59dYFve%s#3DcgpUrv4yHuH#5a*=)N>Ghx(vuE62!|Fo+9^FrU`E2% z%Y7pJy-AtTK-k)|3Dh1pWAjIX7fD!Tz8A-fz>oo(i4YBYKw8UdWwZIe8)=nck7|?{Ka!H+h8`wt{P z+5+K7V3Fl_!UVyRM3TT=pr^o^7}KH6S@5I7yd5w{$4O7Z%XDOWUOxEBd@4z`4k}Cc zy6W*8+6M6u#2dO4^$TzGPJ}4@3ETu4MlKQ%4w&wrkZGN=eX25(xxBqACVFq4*c}Ps zJVFYQgxFr=EU`~=&`)AG55m{LKkR58#Iv>F{|#wkJh5mVVEEVGlCQKS9|@8y9BP1- z|58N_Jb`AX6X>g)&0YjWJ`X@U7s5VO;&aW{LN}ly6omY4(Q6G@RH$%$A`B9NI~wpU zXvZ3+fd*s9&%KTm{NQ-ubMG8(vmWS>P+tQ&0P(h}?jy%R%P8%nQCfwE#N)k+F~jt7 za{yz+^dOce^Ia>N2Ou^J@OcJH-%aqR_K4pf1Bn!VTe$0u-r7~PHx9=e#@RT&emo!3 z8j7|_%w9d8Ue|n}_skUFGVz)?ogwfWxNUz=n+VOFP5cgT6(MH2@_6aaKN8hzkz)ny z2;zM`h8DgF=-q|Q3G8M8NvBVMjz{-DIUxmWvG5Qw(j>AAB`y3G;Ezao;rZX^ac;vt z0HQNUYSNc7?&SC0=)EcefI%k0Jpx9bmEo>wFEaOl}f#UH~lobnt3XA|? z+lVe;h>qPhY(6p+5e-hB^u99hQ?O>B7lhR_epvjSS!de=n-KE z*aDgfR2cltrotY8Ns7;)#vdjWbRyaqGmM2*0*sP9c{ATdR&I_EHRy>=F$;mda$g-S z{oNhIUkhuMoME9VmDlv_avP1u2#mJHi@%A!ay*In>-oFz7gEMR*$%i}BK}I;1t=(4 z(CeKPf0MWs5GHK975-=V+ml~G;;%S)Ah9?Oe{*4>2dx*Y8y93?;V;|@arjHO!W9Yl zE6{iBkH4}-*5JNyP z1Rj5Am2kd?GSKFQn%9#k0c-{y$Dy#Kz=`o#M?-&mz+YhR<)t?E2Fqdsgb5}3krPDqQF9iC_5qsONrud(_b)A zjRFKj3E*!Qd1M+POc?_ILG-75fd4=r-iVBXEBLwf^qx82w`7ZQr7cswhz8{eA;?Uz zAjz17HgJGIXG{Kq{sBR{EOR^N?|~;lIts@3uPrSrc5oxKlN_YW3jT9xowkWZaWfA|D_vFdyX2X{mH1Zum@>E zASOPKf)hxgGf;I>pSByVXzb@t9!k^OMq&jw9k)iNC zoC-O@6=eS${$xiM{3o7Ql>F(~c}2;e5W}^R0Y5#SR~$FAJA=ac!h=Kpx#tz1WP8WX zEB>!JuZSJ;fBw8;3ZjILomb?AkjKs|#$DL(f9brUU{uG>D~=8iJc9nT{M7F3>3@D+ z@f+yw*m*^D71aNR^NKug@*iHP$5uuK4&i-24!}dTGEfqyiORz7@Qfo*RQRGp zU+gcUSZfg-@$5;lDAxHY;9b3VXC_W{O*rfkgD$gp$_r(( zaOFVrj$UD}E3c@@I*$>}I>{4m4X^P!_lKJ*!kcw<3kRaaUFaX*L|d<`BhWg+vvYJ* zAK(pd)bTMmYJ&1MiXC|32MpX^oCNdo5@!ycryg}4ALEPeT*HQ1Mf%I)q$V58XM=@a zT+~f4HNceP#`UlW)I`914*u6u%5Wvk8c%ow0+Vr{2k$&R;C1dU3-efNn|OK)S#4#` zPi5L(Jn@qCVx+#s2c9lj?{&8F)L8}+H+!8Md8j4Nioo~bCC3WXr@=bSQ}0CIb5cFw zLmUwfO|7U*N7b*;=f*PUAy4>2ymj))xz!uyP4{nk!taD}ab>I5+35-IV>X_|RJ_j5 zc!?GVgpuLM5{hr|It>nv1A0phjsp_nw+|yt9MBji0$qzd;ZAXlptfRe3Tl3h@wAq) zLyqSwJe4^&mxZ_EWlLH34NsVX@^Zi&5egjQh|(}>bWx0P;L|zJeTK#7xHy(ieRvq4 z2FC%3Yl#zp(+fkn6=xegJXJV19nHLr*`viYIe+%S#=cSzKs)mIx(^uxaIDTgIGUU5 zsh=tr95cgQI465PtnS?Ajb4%J)hf0j?{i))(%hMXLGSg{t#P>J0XB?ZozTO;af~fD zmk`XyI(zE-MJrRaidIA#yC4~?!EFXj_;dsgFo8NXYPq?bUN4SFiBrgG;{&yP2t`gQjpkll8uea) z4=ZlcmV|Kg1`exE>wZ`j-#NLGet^0?;+$GE`;y#Dhq39qd%N@~KI7nNti=}5!)tV2 zMSCLXy&gVfbgt{@(pCVQgPTA{M1f9z6cHv8oX@L0G)!C8%)#Tk2D)>jw&J+prW#W( z=+vXroG-GR9=*+}H-D6dj}V_~%m{SgHvRRYhaWQ2xway_Uk`Wc;qAtK=t>Wp@}7g# zQF;D}K@4P(=<{SfTAI>!Vr^%h|7>5>-BsH;%s(c$%|Ag8G@ui>|S;q|`o zE?n%ahueMOH;g%xzQVMdjU74ojbhvQqF&c1WE#(2{S|I0!V8waSe!S{OB-W!2RG&Knk}+inWcHVprRz z-44V%Bzg#X8h%@k_8%pN+-?LX+ubeHquH~OZ0tB2%Z2`@M$&&9IRP_k*Q0({VRXJT zJo@KIFtp0Ay1*y$6qwp^WMV8TdN9{z2T?cL|8muQ*_->jJOZnL2f#pMUD20a7;W7; z4g~|oSC$BCAX9d8UqI2$FwY9@?TW1@VgU06WVfRA#VBbUcZGm1k8Ycbw6D6lFVNa< z(|0?}8|yma@B9>2Nxf*Br*VMjeTEA_-9ls?^9+%7yWU7(li%uKX@z2pDtYk^+^9G`Q1M}H=~3P6sJnNsaX#JfJirtEek!XH8iM~@-*!w>t} z$Uke4-j@j+TD1QP%!A3TNPb$)(QFV6ck@SlJA+4_`PgU=KKkJCG*43kmBw>9$ zg;xF$wxiv&w#Bm$t+1+FWFc*x*4MdKo*Ps6RkX>YXj}iy8kVMP<=!sOi-0S{t0oMv z6^XI{(e6y-D*UArHqQb=7?&?)=%G#iEMwXB{rG-JK*C1PG5)j&ix-KA_rSWmtIao& zK>8%%7tu4!Upk8IE1S<>uX|c=a+=p*VXya$CBT2jA$qsyrhKp!15iFQ!2<41Fp{fo_!+&j? zV*5|bPxW9ebtQy4&eR(jmuozNijhgVddZp^T>gWZp;hn^?j$kKM^<1v$J$fWGhYw9 z_z?Sw%$>o;!f)54>!EEmL;0PX9Y_c2{_=P%gzrr5$_>~iK!+-%=$dywGFLG3Tx7l| z_HnqyxPKu_N{EM>Q9%n{j)k|jx^cr3+&;L?>?t-6fV6Mql6;RK4v)b-`Y-W`{XZxA z@BcJ=0}Z}&3qV7{E87kfJJjuR(f;Kq@*+ru!*D&k7gr;u@667G1Pr>_f4ZHOi7Y`D z1mG>ai)OQ|anl)b^Lr2}oS%7$z-_`&TUmr?F_w#!6z)Io?PqzHT!~Gdz!@K(zmDXh+Ve@*y#& zZy>=u6P<8>TlizXP`kHF5I1uOvTP!ZiM9xez&*FNssXEJa(o@fs zR^r;Ll}6F~t1)TZDsw=O-1R)>R~Fvs2^+rfZatFqt{(Bs>8hL-YVv5_uPMNk{Fu!w zelvVf4g4C<49_*5YXLvePTMCo|M=(iKl2~z-`cT0H#oSf~P z%oa7vKZseXz0iP5Ksagn3VM`qzP?!YzvEBmyUmdpo@#NX<5EF}mhdVE9Xa&B?uw&pP3=Qdeivoc^b_a#?>oSN$^` zgkjfOLvn5{cd#p=Gso@+f6k=>4HX;2D9&oEfy26Wo?aM3pNVO(Hh)00H~2DPh4 zR;Kw+8(Ep*A2PBs%RjuNGDln1go}xyX(9C4CB_B1Db_2Io;FfuIs*Na@=~<_WCA%d zy&A0i#opwZ?;5|lYi}2R!Gc;SP)D;jB17Pg`5?07`c{Nnbr_wZ*;|llE@FCYvx0tz z_E$-k@~SVq$ru^f+Z8UICfWf#Rr1>O>PYG2P*V*)RYH*^)`T9NuYZVTBl+hg^?*4BPXT#i$_k% z@Q)igDa$`)m*N6c|)3M_9Wc*HN>kc7g8j zzbw|E?L(>0FX->6d9HRrg~R_8*hoX|f)gDzKd)VInZy6%wzsPqx{qhetr$;v#>mn% z|EVKOGyD@rmS*{96m1(>n&bZ_ATJ2DTK|^v`B~^#z`CVeho0c5U6`8dJh>^bBRya^ z!*{hJDXvm2UZt4cMj?o-AMeDMwijaWSb9g>&+K=L-wIJWFivkIwG5EE zM2&X>#;XM%Ky8d!3ogS0u%xh8Cf;+j;BWY@_>9>y&z9fC`q>$Oyu(^oz;_mmACvp! z2DfRUTGXyx*ayJ9E;4QgXnBT4xLlGckRv^WOKMWQ5Ri3&- zi_&Xy#a^$f>%1tnCd0zJq9zXD&YFElFC73nf!}icuE}f##aOHMTlm%S09tm@Htxu$ z7IR0=KwsE--ROPY9$Lb*g5S7m#jm_6Tzr)KQ6zk>Wc8| zK3FN-Y9CZYqO1#xil@)v({bYYBn78Xmd%R?Jcb9BT!&(?#Uzz(O8`%7S;$cc=d24x4g zHKugDd-67B;vz=lFU#Az0*j~728-G#aPl_i0c42E?;ulVtm5*@>Zu~@Wh-mUDvVKN zH5t7{)?=|O(kEFfU1Z%A%i=ziS@<$026|&GtGAt%CbBAHS%8eFrDk`bmE&2JsdB7Q zoD$1A&TdbR!V$~rV`s^(K7OXX3lchkQ91_Os`r56*4s12)O&m5!!fN$@%1h&Zk8#9 z+KP=;+P)_IzYYIy!m^M4YYLWKJ8LVR2kn*5n?Kk3!WMlf165i@2 zh$QlWLG)tO7`2WzuD}Mw6a@& z$BX`8SogZhtp5JdNj~T#h`V*VZw5M57#f4@!#^ct)7a@)tJ9;OWMD(O4cF7rr9SIG zLa%qSSB3nsUQb7_>{18zTtw`_I$lKN!OC7l+~Io?)EV@O!$KW3Hy{oc@C5dv_ED^t z-#ymeWj1~hyKgaY(4{SX0tvMXUGBkJ=!bYDLe4>}I?TG?)T6iL(jo{W@3+!?(ZvJw z=nMuJpAguUr#--r@TN8yDPSVY)(mc~FB@?nwNMLw0-$;#S+2k#*dt0XS0lHc6o+;W zE%-y^0v$`8g6N2?`imz8#VBc#7NOxD_1Qgi%4Q~xt$}y z%^bO3FR*hYh?pZc`6+geq%_Qtl*Vc2NJ7)@v1rDhpOB+ZStaRAyO`5fJ5|yc&Prr7 z+8L6d0Rl^}8eGTvf*5|E>pryln~wc_pa0lXp2stJ#r4*Vyu;%Z_-F*3@*>QM&4Akm_iV><9vMH{LSnM_(od z-DkLDS`mo28U64_*r$QDnev|Vb!ioWmR>qMI>ma)S}l|gH=TKB2MyCozV$?MU4hOn zKXeh(cn+)KX-VT{KV5Av3i&)T7HWtV3W2g~`AY7|mvWB~x4c?@(Df+ke%(3>N0#kY zDToeFBe&tIeEji2%l+^BJGv^Omk&_M?;_cli!^Oz`l>H7P{f2y1o!riO*8Jl8iN51 zGHXH7?D6W+sY?Ihfd9Ac##6{2CwVf6O8fSq9#ni zNekWzysOgYHNoguy}|A4+v1*qaxlcZ)2iwg=Pydvg3sc;MHm3R+RC8=FhV_gJ1FRl zprkhzlA6V)XFT>@v>lz$ZEjJdRe8fzX|%3{58C3HA5WnwOR)Oo2KPU^6GH$ThvG!IfIp@18-%Be3Mrv-`6tQ5*3q@v@_ieJcg@8d#_8xxPD>yQQ{?T@v93JwRu zp{j7{ImTY>c5@@VQr3RL8a;I|!|@_njIj@zico}OO9cPa$^Rw%Q-;`IV&r%8GBB*_ zxmcH$(i{w_%e-AQDra^E2Z?-5`0-yByzsPf+s`Dr4* zTIOS(uK2lsuvE-_RQ%jGA`Npt8S}#2v*g_Kjdl=?OYh&POWTb zYlmnDU&kg4hZs+>oqn-)tPMn(VfbV_h4Jka%XY$SM{FxJGtjt!&HMn)L)+HRhoUA= z;9v%ppDMi<`aCBeXHSVYR#KmZzF2qXStqBVh7)xTv(G1%m-dzNIhI~7-!DvfKO^D& zMEl*cZ`=xd%bUihGuz>oc4Oict=f$V(T*;$&09+6=ODGERM;_E0yJF+ZYC`rG5e6T zFR=wZ{Hh>)#`GJoq%i#r)5E3cWjj!G%7F~DHJj3o@!mwGn+S#1JOwxgyaJxy`YnaM zG(g$-9jBk4iB^o4s)c@jE}oTs{uEN|^0vNzJPMdM-=3)N+xegV75T^CnwSrJK(SmA zf39TYLxT0?PE9X}GqO%c%lVLo&Q0Vmu zbl8o0V2j4gzru4iYd=0PvGfAghvD_zz}LrV!S92%2EKOs@r_-C1dK`neZ$g@O4EXS zL5Big=PY`Dl(S|zb4M4KW&6Jq*rCy=&|AAZ3k9J{0w;F;B?HHx(w5+{Lp+Y) z7#|-KkE52XqFD`iWIX@Fb_4$Qn1sDZ<-a?x;o?RxDt`SHX zwb)-s(J5Y}%^6gQ;t*?*n$us$v+>ddCk-@G3s*AkcH^6>p$mI#sCQgLU7w?&+qyL* zW!UY;K-Exjj}5(o%GQWhu%UwZh5#oarh*@1YAe025;>=wL3fFIIsMgd_7d??c<#Uw-7?@nHmAr-bkyx3srmSH~YMv+6$}pumCa08Rw%t%Y?NHK~&z7 z4L)tc1|w46(PdsDqB=-##rhUuJrNYT84XZ@l52O{4-_^OS*u{_SJPrS3aqw*H9D3h zg?Spbq=q#lmSx$5EN!uOEGy9_wC7=a6jEqsgHm7I8p{G=5~Q}mxWdXh4>L>gU(Z=t z%DVBeowXxNj( z+wDy|Mm&m5`_6u*icPx*kC73vJ^STD-S_Ms@gCc=AK=}CJ#FpT*YM8HM_>;I_d&u^ z=ySp6Xc*75ehq5FvxU+hiD#mvQ8_MdtI0+GszEk)L66(xCvk0kAJ4{d@vT^>V*Exm z)boa&64%fKHq?As+;A*gm2snL=%OA+lpWVlIvbiF-w<~iQPCKp8Y;Fn*jxJum7M-t z@hc&vRNp4!LbSk&M7h`&-Ep4;j=kl-r&_r0@D~13AzSFaDSwO>JdMP0x|X3JeHFxR zeEv{OKGj0!0eOm=z(n9P%LiwI;zllIDG@?(i^&rtxf$pl&@oFOqZJ*1TN7~ue1Agh za#Gx!3;y(}HOZVoAK=+Shu@25fes!F*`BO9vQx;fV&|xxXI%H7+KleRol}M!ixmX_ ziuttNCFMCV@zhn;_M|=e6swI(SHr67tC~Amj^K zUkLePYe*qq=r7&ddu6h0570-8E#-_ggUQ8>zf~f5z{o=51Y@wKop#~=AMDAnEPLC- zt<>i&@YJc z{{8|rq;l~J5J&D?j0x;(%Wja<>1Ev%kRPy2EdFVeVO|x}L#%j`IYkhTJczz{wQ95v zhMM8zOrvKF)qL}7&9E>xvhPtqIM zzeEN3CMx`u748-lwE7mb87a@9af;AZ5R{W%e=wv2YO<~^lq)&{ZF_1|MM+-yUYcwgAX`CbGi>X=8_w*ryAn@y$whHaIIa($pj9;szzJh#$zmS^o`YV1G!Z(K zNs0NlIWnOAvSu1CI!{kW%Y!$@**8>t!W_aK5oUULi!a<#F>AZ0v50d3^6f@ks;9A# zZ&9CXFpfs}O4f4lPM=o3)_6&Tt?stUw;TWUElVFRs_83dfinu$`e5n)@MkPz+7zJ| z3nY!FvEB6Jz@GUry?6`t;?seVae6T~DD+}q^qWJB`@gMp<5~CihWnHK zaN-(eh>>0T8e{^l&^w;MSN*j6qF~H5uL@>V2o66)3%!q?Y~|#1E%Xs8h<7*EP6%e+ za1*{#f{%3~wgRz|blP5Wml6}`F&9iNNuiUiLgxv}m!w2TNHudln*lAt$+E-x+GZ6R z!9o-)k`(%-Rp=WUJ7{ zEJWERNuj?46$mb2Axb$(3cXx!6|DDu^GcjYS4X^&l)`ovC9!Jq`HCH?e#dr}OVd8>)aF}hy+8w4w ze9*RHy(ixH+g7a2c;}g@VYW`($P|u2PyqrZ2@0IBL=_rCJmIvG6#BGI6*|8sQt_Hq zLQsJoNW~LYAwdOtAQeljLIQDnAQjhGg~SG@UX^6j#a1CfPkJB~Cs>8V2JeAXd|IpK zFNjVLq+*j*NKk&6%ypD2U2l?RY(w>9!N!wRY=g2 z9!N#oV#|(3&KurYR0CE@y5C|{g@@78w_;g|^mJ7$E0Lc5B$j3A?G`-^T3NJ(o~{Mq z7w$4|iRtZFDM*GFlVXb5dk{@)T#iaIqePHWq)AX*XlGnxX9$=KvNMY945F}+h75Bo zJn0Cymx_El6!}+5sK`s466Tz4>i=yRUcBr^Jwxfgg>FUiXO`RViTb(BKf}&X z)W;!@*X?--ZLD&3IUt7$sgyc94_!@$zzPAoQhyN+o-=bC=XL3;#1H=HIE$aJzj&TV zC#Uft#(`&&qedyd-qgMoULc@g(O?E$ZANd07&>*40zr$)1Kgp?oHnOd;5XdAx6 z`{oWv?r;PZ7=OGK(mNdH=+@_&=xID1?LZW+bQ-^5PWUrR4Bl?cLa=~z3l-HI2OApa z0C}GB?+28B$3gzJQ{(nu-1(e!wM9+dNZq}t3AYe}g|(#@1KX7R>x*2E=<}OgZuo^B zyn(Xs2Iw#G{&}~kxZBX*r(fvZ(EHlby&w{L=m7jeU-Z_3E3r6?3vTk3 zG*L-J$qJoe6}ns*Zj%*qqL2srY%UbN&<8+GsT@~es||r4-&?X44y3ilWj8|~g}gNY z`yrGK=EcZ|w?Mf(*x3Up0ht{LW3ud>q1(_BjFImPwz#J@#ukO0L-0E(RJI#k;I-zk z?)IgWsUbyMs5mg4QxkDQ!Gm|1%~%YG4&U*ERGNuZcEbl*jWPekuHtAx7q0y zD%yyZ$6^#a7pV!3u@K*$;D@m+ za$GqJIl*SSH-dtm-;7mR`;d8+fF}hsc*8f%1Cn0)PjG;WW^#&;iBER z%r0Rgq*AsDkwZ14%p%T#9ciPSWhXaz>UKCC*f4cXU5ml{>tXwq<7GfuqX48Hw|U+)*g}AtXWO zd=vqnrtALO+RDkUxe(w0E;;}$$KZ^&q+@Uzeyf_BGOC)_WWY8*v=Z;2ad{*z4{58n z`9K*9hj#(X>UQ%ld}H5~hqa$;(>H5VU&GHDEw@=a0r4QR zTZTZ0>^0idb%>EbNT|{E3h3cHIO1aRi8!{X{Clr}>e%v`bgZnQTt<;h3PSbOdHhOz z^bxd=#@#~48o(GF+vSVT?<;iIF@NJyGdoPUr zw!mt~&?Uov)mIBB+Qw zUpW{3^L*t*C_i>-N;69SYH9 z_=qZE-=I&tC2ZgAWe^sE=VL>aK^iG6krqTM%jxKSWu4b<1 zcLR~^X}k=7MVEr%igTErm-CRQJ56872Iv??RO7Ys4bUeFjYVvsbOsFjiy`5Zg?Dfv z3MwTgdP{cI=m0s#X-O?>DIg69ZSyaM+HroW=XdPT)2QR`izK|O)TPl*qgfz_Q^dE~GjEopbSV9(xuS-^F8r@QBS9 zbQ-|Oi%iPH@|+qeT?m9P(N+d(QKbqwL$novC3wcdyAb`H;dzmbRq%9oyYWrRv9ed` zSBjMS;Ub)fL!5f!(2DzA{7>&NbzDT(eDG3zYo}fSTDuY3^XXQ^#YfZLLSv4Kf>vKa zlm3t%O>=82bDiMo&Xg(;+9B+$I#pCNBx|2#W3asQ~>TYq1%Pj_=Am=VxZjWBfrB{PItN-KwPp-^ zwyUzJ2~J^O`lEfo9mC~0TJSNfut-{;?$4?cPlyvoot9D&fZtLs5J=^Oo<>hq+AZnZ zFafdP0)<=3^NA>0-|_+BDZ|i6=)4oNYkIeo=Q5dfZ#iBI9>8@3)e zQ39CAh{|WrbULsm;Y(C+SG};Of<~*BwQN}ZKx`{*a0x&BlofX*i1$=_3DO!kMUT-NMhN2F0 z5BHvJ4}^XEs@J)q+l{S5(eg(^0C!_;g@^mFdAvL`ejfdle{%!wbO{{nr7dNM5Jbos zu3PbUvgPTtN)e7`sRE|Y4IdsEy+G%`# zT}Ri3vaaEJpew6}&e`i7=JleLT7spg`M!o~v30ZN`}S*MzKcfu{d27;1DcCPQ=at~ zbJ%^jQ-N~9CVAN6E9$rq?yCbv-%%Ob-FvA5?!+HCPYYO!Up*qQeuPWIx^FA<=WN4X zf1vhlXW{@kA%WifVu^66;dgN0#Vh_!b}i&*$QL2uURN!~s;%_77Co8b$7UPIi9DIc z$2{?v!AF;Pbn{VcQkXV7Gv?J)QAEhX-);V0;a5mNsz_atu*u)s8~!nQmcn}+IX8!L zoQOY2-;OEj;c^$q@L5&EGjpnVgyrt{kgXtTZo#vncf9|rnDGea3|T*#{?ukVeHz3S zd-6VkIR8KV`)U5$EHC_`!QA`O&wovvpMT>n0P*& zyf9KKSYdcQ$=o!kfntrc*F~Y6!Y;$77X~EP$xm@ z+-1DC>M_t*U*z#xREVd1_spOm>P9M%9Kdp?@V1X-K=Z)CA==U#QOg^dH=_&@i6NeQ z2X_OVbRKN$E94g3^oYB=wBQS%khK>({GSppOSP2?UE_#|6C+b*NbZZ|vMSvEcLop@ zCtUH@=c-`2%bD-O`)t>ERvudg>T({XzJ=(H#irxN*~zXep(q`ovV@`wT~oD{H@U9k zjjy9vei+MLLo!s1Y`^PjCZ5B@>-kiut@gPld7WDkCh#WIvvzG|VS_CMLpW;*D%_AWEf77I2-pH$OD0!xDAVW(d#IW za~%&UuhY(H*6uluvk0Z}FJ>_WO>8RIihlEr)zcxv;6YoBn^V`J$!C#ZwbreT<={D5 z=yCi7C}zVrjOm==E!b%+L=C>27jEI}x8oXcwqRl{VhB@2^-5L`AFMhX!X$eMo8dM1 zrQW-(rF0ajLRIr_4I{u?tKpCN3Nzj}0m+qveUs;!-9uhkpg&j!x%6uhIY{N6pR z;|(vEhO9MsCyl`4W;85Xn${$1dJ5hKAe&M2_L*A#Mm%q3uWS$!ZuG`#wpl1^$r=S) ztHR^vKoK4{Lsj7OY>pST*g`WBN^ffGFYq1XN7oPtS~B#Kulysm)tWJLT1VGt2jISV zrb6Y;Jo)+|g&un~~}W?8U*m4?vW>ky)c~|D6`B21Fo0 z5--qg69>%h>lQ&=TAz-l#(6(OKtGBQmGId5nRe}(&$Q|3pKKubu2sL&!9ZQu9-nDf zVeEa!c@tXkp$du&jw|9zC^8vEnzi8ZD1z|jv>xGZn_!ng^iWyRwldxg24rvpdrEcu8CQuvlcwR%)ibNY3y378 zUjFe3K=98D{+Z1`H;J%ln;s`pP)lD*B%|gD=k4u^+?WG*Zs<;o%nQ$N_%%Va&Ja{A z{Dyfw(n%gjv|KpjR*C*@pKLx%ZkNA>sY8&x5ji??#`#RQ%;CV@%wek6{Dc#?_{C@1 zv`yxlF}VjoPJezKRD*|v;0I76|LyqvX-%dX|2{ptmgR?7<)>#?^Zf$(9>d-#jX=pb6{?Pi(x z%#k+R0*2b)@S(# z1_ks0kh@(e`fsZrlOL34NSNnuU;k_OYD{kzCsXU6&_|Im0%H}GZ3yV}Aj0NBn z0y|PM4dYu##&k=2TZY^u_Q|!^$ub#MgGtK#M3zaVl9J2=vsks^Jc32_YE>rX2nN-Q zRGHKx*i%nH8BgHLOl|4=AS!yKw>RPjlW+2mj$96ds{caFchHkK<<$>x!x7?Lnif0_ zkF}jC+FiVVf)@W%kzkF(sQX2GS3_iKF*!HyW<>)oZN<3LNtg(|A>lQMI%wXNQ5J5- zk+!;B4uILyu{9IN;>Hd2G@1BpXIkdQvS8Ev43dHGHq#6XL#VKjN;54;KZsn;=wFDu zoC_YquP3n63BC;ikFtUpqtu!rFqi2YL|UHl;N!%R(tLDurZt>1jx?Nt!-td7Z8+={ zi^%avo6X-CK`urR89RdF-Hn9J%F;}@im9=R`?V=&pM5ty%{UgRJFWX`1Zze&dRSVs zn|I(~`)rrHD*Szx9UtDQuX^Tb`A_fIrL8W_;)w8jyuNie9ye;M$GU}$;VrRFusM^` zs~nJ}vszI&N6W=^4~wSyv>9Nki!S%#9sGtRX`yx#WU}3{pmAirEH{1ZJU1nb zXY~`nNFJi8)bc^&^yqy*5CDJA(|8si0_&<{qO*DH#E!0pVACq-?p>O9O&skAt^?v7XK*iMQzrW&1yB>=9b zJ(*E+oAjn-ykdLP28l=EP5brl?9iMRJn}eMxLro(tV9zcGN)aJqdXzrVM%P4kvZST zJ4v7N`5AZP-5fwaLjw;Fsq;f^&%u6c4cYkFV<>Yfbv7YyS(MO-Fuj+ZE~ahFV`4j? z)L>B{V-}PCNLCk9ZqdHFAClF?b$hR!zZWs?H5pi&Jgm)HJu*^{+)*8wPzY1y?#L8e zeRp++vOwX!-@HiqKom#3818NmHOwEhp$}VsR@7;`ar*Rjm{_Fsa&s&n#H7Ci;De$l ziW&=0j)`qA+xE-tMimm<9*Nm6^Mq*}7oy`Xx%Y-J_T%;pqv%V;Q&hPVlY?ZEUZAcLSnrMl6PMsoZ2OvCQXxYT8l&*NiIQR+XIA?f_uC1 z%v8X=RKVT5m1eOR>{%{BKV~`HuP?4Q++utPQ<69GW0E=#@1%ZzQC}4vg_xTmmlE#l z^=Q!b0tyu2`sAO>4}U;GtMo-*cKwPojf+FC#XGHvjVp1@b$A14@lqU}1)q{%4;h6c zu)jqSVbHl_gD3Fy_(e^%vKhynD~dMJ_CC|L(9e9#xaHLYkZ3QH&Em??>+n7@=;}m* z7VM+NQ<0cXxkBYqN10Y#_v%7$L{ar!gF(;o~6= zK=wzo$_731<687BKX1W11$P>uanwzi3Iy38@u44$uJ<+yT!Ha)(IRbyLFfY*xtTO5(ceYXEV)cvM{*nvRnf9D(|8C$gB;E!_Hcs3#7MjVPvk)^D4l#u z&q88%gt>1AdNkig0ZTus3cU0@UZIy<#lb|E$z3jqt)#TZlNGQ)r&8C#{VRsEDl9i) z;9!b&_a1N{^A3?$%XS3)$1-5xivCYh^nZm-*G!`diRNE1JVn;v2lBe68E;$x5`>L8 zt;H<~Tnmaw{#X?dojT1v=u0567Q`1Hy5w{@+ff3TalxKjH7qTofh7+;51T+%3|)#u zGYfw#Amgs0cEba(ibG&=BvswF>=v&6zQyN zZ+K08_5Audcj}Sb4~NuA-5_;fu;tG_3|=G09syqPOA2_vFPRh`he7l89mF2-i5BIT zJZgCL`_0k93w}vkUOEE2BFkJ{Lx3$$fvu>;y%2la;jOO~Ira5*c&l&V@*V}gJ)f5Z z-@YjOXTmS~;Xe$&ZNL5>!B0hK95Fs)AmTIf{;~LsWhWEF;{NNWFi^&4{OWA$VzQG4 zkt}CFj|}4xq;`+mh$9zq_x(PO!sg8=9G4CHDbU{Rb()RuarX;F*#6b|!vFCtJX`(` zq}cW>+rM4T_O~!AhHPlx_HXY8&aB!&#IgL_o|DP{q<_0V3=P7+&5!}yk^~~A8BIJf zEIitmq{Mr)g;P|Ici&lGvg$Nm{w2+gZmESs`k?Q)x=0Ip(SmYUQFhN>_bbe8@tI<7 zI-c)j7=0e9j>%q=ouAmxVF@lLlH z{NRW$GWkg%eE)*egGd%P7$L`XcXB2fRchj>GC8VjF{)nLeJ`_F>GO_vUcHXX4B~Cd z)gVo#@y@fH%W!S!G>RE3gRUQoW1^or0@kef zi^3tLp_(TMPK5sGyrs__u65xshtLTD@V}n}X2HP1+}rR_%!k|YfQxA1?8O62R$f;P z9`cM^aoL#3NCE0ij30Q>2iv7_50rOGS1EuzRJn0zl1TBhbjsj5 z;R_y+T_t?MuOdZxpv~0+Ry2UYS=>iCiyuNFJjrih>}un{p`2?j6=iGDg_SJK393KS zk8Jpp=YB)@lRIgHXaEFmdR9WB4JLZr66hJ>Zf3)jT60^^+GV%WCbC!!uXZfS^|9*e8lxJqrkng4; zzcMlg$86rfJ@>Ha6D|1JESQsE7$28MyBtmYrya@kIplED=VCxE!4i9j#ykkmqt6z3 zITxIX-=na^W_?#!w}xUkE)EAZhI8iO!)Xv*T88((7rtj<1bUEu1zhL&AQ6> zkdex^)>-z(L&oR#;{7)b$~1Mz_=xX6kN-ZJ?t^dv`5zmiH+)`jcs+pzwb0x&?wFf1 z;3c9(Mho7Dzc7~qRXL{o&M-=uF2`MhbXu2jrIARtjuZ?=y0)S`4Y$39ehb;b z)5y~g2g)AIt%*a3ub7+*(|6gX0(W%(%> z1g;b@@VPoI6opX`5{p;*cf66YII?{ot7xmsHEs2j6SUP6`od_1dvh@HD(zhhk6XiM+7N6 z%%`}62y29EhXPTd*r{;eV0mM%mFel1q6YjsD3?A8k8owDPZqzR8O27$QnI>{ZWH*!6ZQn&laKKu z2Sb`Z_9l$X@;G7K9OM%y8bAJ@;9c;uV&jKVP#kF3x@A99_t0Xw6L0)5gOE3prI!jZ zC5Tmnv_9dK3WNp2rjU8IbniL0>WwiU-A?%B5a@0mr{uW9{YRa;?LV@&>?bl!5i^nq zxn;MgbYPL%f~m$TqyblZ(?3f?p7bH5J#PDuP8N^i7}m4DV5*C^Fs#L+@FA(w-M6C| zoWKGEr4MPAc;CVIM8y6W zgF?i9^0C`Gn#BSu0WVYl%cwrkbJ$hlI!*a}-6b56`V3qZ~WU)mdb3rhG{wTgMQ_D4wp?qF`@JkEk zW6RRue13R=4C7-h{-aBBrns5CR=lAJs7%Zy7K(F`dgLkQ9TwO4!3ZTsGEO-!UCJ!R zCy!B%9J1&^Mwnfot;X2|09=b&XVEUQT#fC%Xz59(So&A><9_PWjQ# zX|yeMvxzgY_fTp$3bbnZ;$+k5jAdco+1T@&3tHJc%M^(+Xk;kEU|8VX0(|)d(JiRR zqAbXF5!Xaqz!%*a@>ODoe4!LDB-}f`DbbKd>C=*S4?55G=(MFR|qP-O@;vU4D^m;tBog(qsjxXEb)B|7l!r~G` z^E>d8G7n#M$ls4BywBano+2ye>~*x|``n8xkfm$4NS`^P&(0byqR-MVM(cMx+4f7> zzCZ~Iq}9UWVk1W!UYNDnd%L8(U&${QL3W8;4s*!cRK{0er$?sdw~V!o_`hb#Se(-J zUm%XSXu&3=U{L)x{uHKd;3h~$yAc^B?cFah5d}ozJS5T#8lkzv-zQQ&4EP*+9@%1a z#(^vtMwq{-5TCHZ>5Xe)PJX|ppJgPiqy)Vcg`kfKd-AzxSc-V3oJXJDB!rr5^JfQM zq46I9@O#lTtkZe4PG4FTc%>G}4*vyJb&IM`7oWq)(^fplL~X^=I{w^!J|@t*JFwB& zYT{HAZi40o0;j{Moacp4n4VF8Ew0N-i!3E!CWz*uk4X7^%%q-o@g9ZA`LxH5!UX6; zpA&3-GBU-5iS=jKIl|Vfg>WE%$1TQzI?z^5P>53}_`W%E$b1Mc#dqv=x&31JO~*>N zf{fj&MMbfGSr`_UP82m>ML8~N$D?uUw*ragNMPvU@PDKb_SNz{z~|`T{1Q4%4(G$B z(}bet$CAFnz|AN{8vK3Qio5Q?GvQ=@p!i;kaQ|Wc4)Y5n#o#9w=ryE?1$zB8`A_fI zsqWTAhkUq8- z9Wc^P!iFo^;np75(D6rH;*ungT<~!q?!*+&EA(-TyFWaQK0J!q(BJ3z9qEWX>t7aQ@K{Q{RN{nGU&5= zL@cVLKS@Sw&dT6fF)WtP<*snPj&PhZho`u=7V3re_~!H!SS^|6^8sJ>Sb@+|VAK%CpL{W$1vlay$ z{_|mYjuFN0F;QC)spHRG^sovHPauit&*@J`PF@P43P>Hb;1bk8dYVWdoPoy-|E-Zo z5XmSwIE^Hechp8o1<5=CO&487z_$TAc9(&FK=FSnl&cFUB zX+RZv?M4G^dLmEyNt(+5DB~1JbRfB6x$yl6L73aN+vOFhGhb5pprWl69ShiW%nLN3 z9oC{EL)Cj?JkyuQCyi$Uk7D#rjS-p9Euv{t&9&kboWCeCmiCislJ)_Zo#G4IjrT`L zdY{TftO;nvc4Gq)C42ROvaJF_BiW9KDi$P}3k%(u`;}ErKou(<>fRW>vA^X%5C&Aq zUv5{SqYb0j%cYR)VWG+8e#sc#@6 zNf+r9AOf^SNIxJbn`%z%CPPJ2ZF-Ubhd1*{Pf9^gn*85Ta+JSsjIDx_gwO|MD!})s zKs7rVs3KDaVsr%&aiCPvg(m-HJ#cqHe-mV!XK*irCE_4o?XR|n6#Rrhc2xfV`@es* zl*PP5Y{ptl-`byT-TnWS3X?_1;q*RxyGlwI)?~$o>BiceA1=iW!Pg=bV3M^$pG43Dn{T9zte;r_)^0ZVVmJ-lg`u87`e~`~q?s_P4fj>RH;#%kz!0 zvi7dTcNo0^BpoK z?(b3`in|+ZgnsEa(5rAVVn5|mURX%_4s;Fj@&f|-gxL+}ApB~to1{8BY zW=wkY0A_EX9R$Xf<7H%U7;D!&fHQ!8PhcHlU=R4~;~S;vVpNe9;@7Gn_cByX3w{A( zzYhnVA$l_u5;3PnF=7$H`Vi>~G4>@?vI0@tjlGCIlf)LHem>gKBezsX##6=^8o81e zcbpn2%Z1=|Qr+*U*{=TCBM_SzCu_k0U&c;DhLQT0m>|^>B8(|H8GAm5MDRweJoJDZ z5ems~zpB<2x-R#1_B}mS27Xgl*#aW88{bw~qKr#P`hbTq8~^Qx#K7Ycyc- z%uB@N;3)yNJ%Gu0ivvH$j~03wqebe=t_MZxOTQ4QU!p;6#d6p8@#Zdm=5dkugh&j! z9>N=(NWpL6J&EDoKEu%aESk)Nu7_3mlaiMQ+=T1Nc&9*$+wEeMT%{zArC*~EYoIMT z8*aHI|3;ABi8zX%`f$01tz~>{k3y`=?tzV#axF(X5T- z8_yu3(Oe3GsM;CIlGO*ZT`({J2bh>AeE`6Nej-}H*i*)JZyb|fWlsW^6a+prT zgEX^R=vr=v?bl(hbu{QS*%~!9`*>s@nWmUi>>9w&&yj$Tt{tYQ8XqFf+81>1>_hL; zy)*P)+r4u!9_6>CS|bd2S%T2=QLvNk!kah3`+LMHfz!$-o^wGPXM6 zCJVlU4ik6G4u|t6r-*3u4={Tw@owWdK$P8aJ7N>?@k_BMYT2$u%e1BC7(jQ*ci$i} zWO)=%P`6Vtbd%Sxc_kYbpEk%&EOl@v+T~H=n#auV+Q7NuPn@pg9w8pIFnNVONwBT!)56%PR7$@bX;vsuZ zXFrEAGMmrW=HcTDT5ttRlw3PN@r_8}QBfuP5|l&)R-Q3llup$n`h3G_J=fQ=6jXrU1-El+qU|5*0JhcKPxS*Z@QH!`h$TjWP}%yUJW_#O^# z>5pcYv-oJZQ1rm)(RguUG$PAz61p?JR%8^2n+dCdo-Jpu-n2d_LH3A#MDPkJq!#SQ7XDy1w#lt3k zKg!lW7&G^lH@v}9caT-IyBXKJ>Ph^Ow{5+!2dkyNOuZ7Rdbn7R>KVRSh#}f-TyRoH zSNH|?u7Gi$7)k8r7F^;&)aO5=9w5TJHXV?Vn4yOsdKBpZ$Oa~b2R(-$V;cb<$$o^- z^8j&J&@HWjbTN|sFmslpl#FhM(h<$hz8e5n#mv0@dobidb5XACr!hRbp7s2whZAj9 z(V^{ou!Fqda965`Y{Yr{BFkO199Z~`itz6N8(;W!8$6U!;=r>Eb^;4LjiQbP9-g>6 z@k9$eID;F5QurBa1itVy1dVa)aRMyA{;LGbH)CLVj!EG`58=mnDMNrI$mi>{c(72W z#Cg%|I%X|Hu{gN=H57vj%b98WIAJ%Ntw8yNG!kHJS&aRQv!@7aTqZ;n7d z>r49vBv@Qu_zpk>nQGCE#^a#!pui#Cpx}#S|M@Td9OFSR&jtpoekw+uJYMr|9Ulol ziZaNQc%11e`8DC=zm%F7ohF^wjdZuwboHv zF(#w9cTHnO^fHO0okl}0c3>p?dW^>K_a^AtUXYt@IW}969RPXuKtIernPuFW!gfu& zSU!5ImHF%P%_qR96iX7{Z$1vfz4Bj*_Tu(i_vR%`d*M+!u{ngsB^R zEP7XfR*b7Vu*ss?MR>N(KOn^}Z=Zk2K>_plPGrS|A@pPC?++mVSyt_qZ`;p=zaP$i zA4p)N|{qnr3mazk{a~s`AX&F0^8OCq=AW1)Ky|tN zK=oa%Cwla&V?7_VrF+sd-jBH%%d!1&@Dka0i3Hk0@!;Xji$mpiK? zV{v!EtAJ2nL5vwEZ0(Ddu?%;FZE)-W*guBj&>`+fGES`~a0lv<1=Ys=2fMoHw5^#3 z@Rne;3EuNPjTG=%8X^C^3Eq<^f()nMqYw~2&v-AVgW@y_<74foaER|B#ezA>gK-g{ z447-dZ(>COfz@?@z>wX0&|hqzuW-4|Qv8X-u=se`X`u7t!|OePLr(2JDwk;KcWB9f z3U-F@$OtmH*#wT-_DSeA5TmZEHeP@UOZudH0o?$DytFv{ao6AE8mz5Il`3=@Zp8v!QHCG=B_K#bn*8nAYFqSHac=2jzWHxJ|cYi))j@WrXxebX^711@(p zh9#)%t)Gq0r4ff2%a|vIM6WQ%a3y@1Z57cgov?@qJoalHU1-SPU*bD%njVI0S}F<* z_*5o0iZW7yD+jaP#FB7)qauL_^|$@HAtfJ|C&Hz5u8 z5x;ldhu<~tQ*}(i3CJJ5if|sNu}OUW)MX&aVEfY3}UO+9&M}DT6^lT+Ij%- z!i2kcDc}vn*1JAqP(dpUVH5wtWZ0= zX02xMv8}(o_3G!qr;J~K%u{yeiT9IPcp5~PMs7wmfEWKzYg^Agl za|0CEzUQGkP`XbuQ;)hA5vb_s#2#S6c+Y*c6r3xf-*9zm7j;Fy={xU9rM+Hm^N$K& zr{~>oDbOaJ zfVX%j%WZN#?g4N0-GF50ywd<-P1{SV5lniZlNoLdeorWN#VUJg1{mir>8+T5tF(LMD?}q#p8fE*CslYZtq7 zFQK)4X`me!+8a5&E)c!Bq#ruhzf&4|g2pBMdT)5hf!Y)5M8j$=t~SbC(dR_Cq^o-@ zp7|TrPKC4$T-&(o)<3y@hzPLB!Drks(_OIB@EP|)fli>|qCiy{KBKZNpHT^YKGXfM zFhgvNZlvlppqJ?(m*4VIWCpS>!#dB8aWQbbNR z@Ock-lYms%2Kb-{yjei;TG=^c9&nz3TI|`t9|JV&Ik3#GpHJP@omtM8!Wnvepb*|U zag#H@gT}seLrT{HnP=}rj9KO|;#$s0JTy)XGjn9{b$~m&PWbu{)|c?rxuXD}FvM)V z!jP}O1{uDjNG)75VD7p7eTwRnMPJE0JOj}H(Id3C)?ojz3`oOcLG~TU4jGU%*%oAP z;C#aArJ1`~-d!UVXcg2iWkA|cZ7!>$eli1MmoXs!D$YGVC~S#;tRo}Ya*@^r{i6_b zXUM&lWD1zclH$36a{OMN3ouQV(?GwY!+@r)&&-d?_208`4;64ROl#fZz$RH`8Hk~Y z-yZ6973OHCxhX5nw*kG^2Bcd`fb0ORZ37beqzCAaZ9wV?AUi;d(;)veq0#-g?S@XXFN`oUeg4@_ymJF7F$|DCyhpPI99r7d1hKcNIVQ z--SK-|L;bm4tneE6o$h|6roqJ(0{4aXgWn=U)2{s*fYaRFYy*J$c)_ zk6e6p=6&RcDTSwz3+KI|SCThzeY>(_1V@QHYC60+KRjD|$pfmXsm}|M^j`9J^J!jH zon=1Fwz7~<_8PX|3gaJ6BI8}y2V}ph8Z+U{tEyqb<}k=R{MqVWt{64oOkPOj0)$Rn z5m`EUted@ZI3k_MBMq7Bk4I%d8e$reUZb5eAd9(~%Z}T7`L(96F+xe)*E7*}M@V0l zdd7!T(M)8AKY7g*(Y9^;WjckokTVULmjT(8oN4~F49Kozfh=JPWk7Z%3uNj2kPJx5 zCN;r3iR_hu*oABx_pSCp1{q~{vZ6j*9!=J>wI$h$is3ItA(Kd4Aop?Be{Pa<_G{C5}3H ziF2|_oavQ#l}dbPbyfpCd10#?_evan@Dh*BD)Dfy#2=`{rtA{wuwgpfQz_A)YDiI{ z`3E>p@98J1Q6lXb2T1f;A#9aVtRds#v%!D;wYqgzYic+|G;)UjJ|_&Zs6iWs7<;+& zd8Pl}>y6~f(7-l+&;H7Y`^CxoBJ|GCui?x20(rcLKT2Pdu3e5%!c&bm6zl3la`o{6 z^X3h;93iPMR4=+;k61p&c*JWDw`9qFSK~dY<7IO-U_V2WRN% zgE{Ug-0JB;fvu8$*y2J{w?8QJMeiH^=aYQ<`cGog^fImATug#g_mA4^H`DN$fv*+B_%Day%aXUS`9CUmk?oeb~_e4vo4AebWA?_>~KH_#4+d!dWc zV`W(~x-UOcs2*DSi;i2(|Mm@NeuWW`s()QN$vMDyML{H zv+e%1q+R%tbU1zbQk-besR#$X94yqJZQwwc>(cnx?-;q-S@M(I=r_HcMycs4W1ro4 zQ6RoO-V%s@*g5(^=ki}FI$RuBCesvlx!-@gt99LcMe1L547(nk{5Iun3pGvZU>`wm z8h}dd#Zc}}cLu4WA5}&MM@^PoPX}(Sc2?C+TjhpGfZNEZ@waIoSINl~-&EDJ?!K0uVdBJPJ2ieSd|Xjq$w&b#s5K=(L62R*=8DDw~_kAV2E= zXCWxspTYYcpvHdse?1vj%JuCRQa#bANM5AXZ(IZJp8F1Sj6EMZfDOd0RNUeF;d2`P zTfv`Ko;LVy@#UV^eSB%-uiLnxDAtwJpbg-p6ot)c%#| z6lyvjHSCyz0M7VOr&i^;37|6a4QU+B89?Yrnp{<|Yg8xh*H@6wS#eF*y7-mj`CsI$ znAaU2>*w;nCn@Tk#xA5-S2dC1xVzt}KHMdQd5CmnRRuw3#q6TGYI|jOm+nw@t7MG1 zusN$Yuxom98B%WmT-n!s?WQ!ltp0e?q>Bi+%3?s+JzBlSfjtor7N?hPl58+0?ydig5@g% z&e5sr?CY7xo+?I97v-Bm)};%1T0Rl9{prrAzfPQGDb7HeIKgpDl zsDwlXs^TCCXU`(hvAU32tP822TB$*`Qc#UWuTu}tevkVzi3tACYdG(rs}T=)F~?{p>1}mZud-JHVu^1VhKu+nn7iWw#mrfw28M58Jsq zxKTJ;X>gV%f#fvhM4Hm(em6^-g9err$GTEcRR)#?DAJt_qQrLumh~nON<34qYH*^< zi3Zzk)zE%PcG9xVd{<+f)er3zSFiKO(@3521l%8xU3*nPWgZ2n43OQcl%Uv6?UGkn zQ@RW|_qw5JX8-P8mW)TFchkP0Nzi!+l;--MK*ok`gow5Q#Yn~G=%44?SG;B7p-zMn zPuBBO%PqA^)AU-1F##HNGpBm9X@cPhY&+;npwYdINV;-N!n20mNz zF2CmX{|@_cdx>uQB<_@v8(Vkd=6P4AWkEUXlY=H?!7IDE({zj*Uz7D9Prb>r*WLRM zwa$k0AkX-Y@=&|#QuFSVv3JIMaF~H2yGfM;gtZ7}T-@4LRiEUk}Z5{no zH!{mu4s-qW72teEoNmg+uuL`#i!NkE)kWua#p?TP^?pfJSL4v9ejnzYBLKo_PwRG! zs)$A(<8N+l)2!}+<_}@YR_g(Qv1~noU8{@3S94g{-KT9Q&d{nY>UKQ8@%5ruD6-pA ztjC!&+_%0&spK7(YpB-25?^8y%NDvOy0!yVR)$N+)`?KZh0*`Ag^c=sVN}cyfKjar zqcY_oCHvY!#IV5b)tWy7h^PvHiv%cGfjk9Nivo0tHzpKl_z+5-lVXck*0Lz&e z3|qc*2e6N{+?3hk&6#v+5~^Z`T=a5DRriYAaDk2u7R)LTl&`yit<8clC0@R62KFCWFhLt}C z!OidzwVRxoeo-FHpo(&+Pw^rqa;uo_sR zBi0R5zH+X8NSMp-AJqeX?^|zwf4;^3KI8I>t>hkloE{IECD-GRMYJIlkB%3f_PDRu z{QTUUdG&avl2B?R>f}UKUT&4)UZ4dp(84!NkwvF`HC@+{rn8;JQ+Sve@d05x0hz{& zu#ogElT?0aqH2ieie@DVc|8PgGIAJGY3Y-+D`G(>=RXA49F>JInJ;xjAi_l3; zTws}2GW5BV`_*S?RGvsf)xs?3>w-1{wKr*O2|`Zy86cpNh@55hC3U=VIVw?S#WPAl zi*_9&W?M2sh&iwb-2a7!_r!IJ|2T~o;ws$0CkOxt3hR6s;sIcUcR{T`yDA_FaDSGTUXP@VX3JneMVk)c#!_M@!pu`9DAX7rJa35hZ1& z%lVlu3;IvGEbzg)tVX69_xKnhQe``@A#pb`$f*m{P|dito^qE0f$8Xxx?9`giYnvz zkU>bJKNAQ6s5*|{jrIokpZofl$2JT+ws? z!SG^##QibR(!jC{`0KutjugrCA~%>wpPfy?R_9EGLAQd5uzRZedy+`xxJ)Part;)rM_pz4Sz4^?l`m*e*XLm2#=G`%t zn7vQUo0RluYL0t&YF8_LxGZX3g>)K?V|pw;E{|^vBFo<~3HEt;>Cy0QdCvTu6hq=^ zhd8nK*>Woio%w&aQCASPMN!?I`7he2s}G6fVQX+rMK5Q*mJ}JUw^6ey`Z@D|XQOVg zQFAH|bLRidM%`?qZmBrRnUCfmhX+m?_&FrfIdNCXZG2T6H~S|<&QC`!P~_m*=MkAm zN8YZ;ve}hHE>1@ZB`SV2`*lY1J=G%br;ue`GcDE-V>c#rN@J?~EYLPc`ooD9NfV??OS_zeJVZi;tz4~T^326n z`n=3t(5?y^msQ2&_EjvKV5=C{u8K+$Ci3S~Y*tU|U>UAP^%g9dfzAKb0JXp`b9=R` zQ*2+RTOUDB{kEF57xe1fM>5$Q<%zs;0MLhDxP_uVKcwWZLeM$XJzS5##>Zcx#sH`| zz*2me%o;xT9?^ZLh(R^{kz{nh4*=4?z`E)=J?yVJ4RwFK!`Q?rxw1<-oJf?JiqsQr z&oj)j`+hP@?MRf`sTfdm-f80JUr2nR;;$l}Nu8eRBcW$v$&AzyeAq>MuTp)0_BAz1 zsqQMdk4jUU)9^{?KL5Yd-yc|?ziWlBpSAkhkK2Xc zNQXJUz|BFto*sn6Jn{>fvcxu6a;&F~(NTth@G;c?818>m`X3?xW4!;NZ9%6zQ}yS_ z77&Pu=W|d8w>!dF?@97C=PGlhM0lmQ-PRNBka4LQJ12K3r z*xk2u2M;*SvFpY@lI5L}8w?uk)_m?^$6$~B-Rk~`D7&>pxoMO=hG~EQ+6Sdc5%rKJ zYv&>2lyznPBx~O9P4b!8^TI7wXal=fR4)L$M}oyxVPYDA!sG#>P>-l>c5hg<7DM~m#6$H0 zs4j29P=7I1mBg|d-ebT64T?C(1PL@%Y4vf1|1s15n4=FK9je!_d*Ru3-Wo3hlhf5v z3wZ+zIu>-Mw(1=BWIx$y?UK1$ffx@~T6c9=@>OydzBj3~n-)5ah4vFCkB#3WMsRtO zCv$1L6FUULr$hgc=odCdo-xc7m@SxSZ+-=_`hjt2h)AZ*W3>ar(hw^sDv#9-{2&cU zo4t6Nft)nN>IIa?>IFXj%5MRa=hb7i0xzW@k|b;ktWMz1X-Iw=Vl@KydXU<**-x|E z)5!eu(s??k^H@#6^faU(4f%n|b5^>vqBNw7fecMUL``km3Js*MATqu?%a}L`B&&wj zFa2)nj)Ki#l@TAMA-bw-Aq6JSi)n~eIcU%hF_0(I5UXzx#5U{~X^2%e2x1#{3lQTp zE)*ZlaSkoK%2PM&l$v;G8fQF3aGXXZTCpOyWuI0X|3D!#y0s&=RerdQNq8pQ*| z5;1}$7p5!QI?+~^mipV(XQlqXkjm&A+Sd7xVLQG3wpNmO+TI;GP{fNP2kaZ~fbB~S zY6H)lSKgMZ^UCb=`yCV5NAFu{nBzTsd*}CYV$%A<^m*l*BuI^0)Be0N4PPqw=gOLC z9Oo0d@6fPa1l99O=Gibz{|iJ~XWFO3QLMw=27SnwF%$=$wu?!xCsvZ#%?pWsM~XO* zP19#{{*m}gJ#cB(r)D3gC5G~XIo{ZstC_EU8F z0e!lEuJP#f4CrZS*#f6uPEO~}Y&ij-Vr2AeEA@w#6?D$w`tm94Uoe3*>AF@o;%6S5 zMZJ~9{oz^K=yW_CJ(uZu`$4O&+v*+^;TJo_E{zU&xJKFxG*Z zR0n57W{<$;MP8Ykz^)} zx3QMzxers-&sa~uk6Hflk^gGTPu|lmJU<;yx98{Msc)Y6%r@&S4Zm0LDF=t&E%+Jx z!L#W@6G_~;v=`yIgl~^N%pfLBAF|V5qV!{I`u>^pPW2iBo(E$%!Zva3VheOOg24Tvhv$*NfT5?~7}|J#Zq3k;t< zjEdE&(k$9cU7%s_ynH-4MCHH={H<&FzH@PSAV2+!!>99ecrj~@ z-$VIbS-259EkCW5_m>%#qp44DoFw6`ZsPl0BJ7SYE~r@6X~0i+yq9j8P4}yoH?msD zdA%`^n;J^w^5BS0T$7QD&4G5nxT}4xlFq7{yWW&Qtur2&5oYQf_h-a#UY(dyVz(Ii zYvkRMP-0;{soYm9ceL)_7+=-ga)hyUntIWcOJwgbrR2FX;I??2K)e)+-(@xp_sQqY zt(Hxp1b%mI9M535|Gom}PWu()&qo`5AukOXXTXq(_?u(7OwKDa2pz?>O_x=bUs>wh zF6rOu(QN(Zc->w921?r{Rb05AaJn%nu+~28G{w1?9~|laf&`TdZ!Q@$mK$k3l;n8s zPp;GX<8y9&Botj0H0aRMV{vp%u6o|o71ZSV(za0aS#!LN=}ahLKSS{&K(Q;@EAwKs zJjeL|sI+eRi@=Sp)HF1Pf7yzW;pz76;|n=efWW;v24Zy0v)fVq4z_>?S(Zv6z-gGLZL$N+e!?e(UF!jbtK5jtt+qwyJDoz>J@qG>_CK zFWR9@)@)Vhzuw!GDtd-m^!78{Yi`Prczb`;^hjN?9tWJ5)NS%~^*4SiMmn+A`DN-y ziZ2>@T2)#2sD)K!wsPxxyj|51s&3qsPO!X^{OKgL)VZ6&+_Om)|BE=Gb>^g>58k6Y z88k3w)y7z^l6lC|uY?l47;fmpO{MeloyIGeMrY}{gX$VS?NnSB-Iu$3C}lXKR;I=Y zf*;14tdG5&(d0-!)5(BZ41HRD z0_khxFPQTsS=fe&hlj}M;cv(^1zi55xt zM2LI-0-C{Zw{L_@Z@nVj+~oW(6*%lA1qSmJNuEp|D>3j$8CQ)}gObV7$oN2=1BO)~)6>H{+k)yii>X!sB(q zG|^yyVZ9etonh`zFRVJVELkUCcXua)3nx^>jlV_F9YU20t4{NX$C%R>P8hLp%*cfk z0&AHaMGkrQ20rteVyUD1!7P;~8aHq`2F zli4N|Yfw#m2gZ$W6HHWf5=c-ue&NowU3aU-@*HKJXw#LG=Cl=!Ox- zqkRURwztx&aRKgG;x52hw2~}_vLjLtIgE8}Ml{rPW0iS++7fd&hrXFR=3CL@LH6Av zIQ^p&bKN(%*)9V71CRc$eHHrKOymLS??R-s_ViZ*iAR5*KCLbNZHPQoKR1{gdEDQE z)1;LB4*GjK^moxjR-75j4A87cOOM7UtRj!@dK>~WMoK45Z~}$JymQ1S9;2-5*HHB7 zdcry3ZObnJX^{Bn;DoaR`W31YFiE>_k_hKiwGCsQ0dr%Vo z!Hm%)l!Bu|i9-x`zYvi@fql+tVoS%oF!UCBl;x8db{-qjzH@*hCR~>)ZeG%(2Ho`;AWM*6y`1FbC`wj;0ibSkr3xzmKA=kTD zDDj(1N-@2E8IDQomtK=X;~Ni`6cel@xL!e&C446B=TP@;Z7j*io!H-h$HiJPgV~h| zKg2&a%}>3o@>9HUJ?x>*(g$%I#*%8eQCZhFKGG4F{VE}ph~JVa2I>A===#5 z*m#1<>B1k+f7(ogcwno=y*Ga=+_Nvuwt#Lv{&@(8Y4c2jfMA~YUSxb!sk3wp|0fKR z@mf*g#t}V!|3-0m>WIeNYrBUhyTiWN!DF#S@}4SZ_7}?*opC63Uu3J6K1`P_WaUa$gyW+ICq~sc>*J$N;>ohnbD=)A$*Za9@UWWdE+G;7ni_nf=2^ zdK2~aVzJbR7Q+h7LtU%6JD1bMy2bIi(@jncCp}f^UfxYTlwuZEjiwj8YqVtCNkTvZ zKN9xwdkVj}QyDdkUmj2$buz!jZdpG$AVbNr)jglGQ*~0Apg$S-h>nC)iwR1e(P}i; zG}}#m0`%4G zYVsYPoo|NnNk4Csbx^X8?$CJj&rWuxlF4y1MfLHTB9*WEv`O1JJ8fU3ZMJD&4%lW( zaqKpkw4Jikeo9p8Zqn*OWASL?Sh83*45}N^8M;}(?ADEdhR5EffVvT#SeAoHv2N60 zJMVq2vK6>x6vX8s)syO?GQ_WGjy-q}RW#T(>LoAkyG6wHvvK!(aVf>+**L%K*A*xJ zSSP{bk+5)YCGr|R4b1(ays30Aj`U*SZ}bP=({F*uq3FtSKnVa zv1DY+3h}qnr&W4Pw9%*C_s8vc?;j983!B+^6^|7}Ds8o#jTu9LytM5uA z+P@hYIn3n-u4#r9;lSUte?Z(nA#8CDPy_>=GOlws3Ku+GQ25ZqXta=+-)<%r`xR}$ z;MET67d7#lg#?jLhPqvj#naHL!w0Tv+;;1Lw4dEZjJI(<%DOe2%hw8-JnmaKy7$u0 zE06D}D|EwWHGf=G_<8x#yGS*wQ{4PQ`?naRG|rgK?p`Xk*V98eOW%O^gbCQozGDEX zP1p)9UT3P*N^W^k<7*_Gbdv55`g+OiZj^l{?UAIi)D-@hbskJCP-`fEooN8yIqOW6 zzEIi0JS3YxEpjiSR(6N@;p8;R+_w9>ZIAN6acQ62>kcGG%S*m}Rpvg!qa+H&UryAN z(ws#f6LOZG^7hDroE4TZaUny;!qV1==KppLn|z`ggFiTy#CTq2id?T{IMq+`R={YB zU~k+y(pqhiJb1HNuw}cK5t*p=wMD#wq0+MCjt5W3$Q@@(flW3mc;J`N=U-GnmIA3J z{x$?`i5q#$uu1(wiLtmeHe$);|Ctd>p5&g~>9@d!AJ3@4I6j!+huZo(64uq4x8aNr z{WI>}(OR9jwx}k4LqTBOXv0d&M{P{+MgQjxsT|}Yh zPh&6Y{|B@iuoO*)9d|mxx0dbjUFmNP#77sqlON@}USd)a0e|_;6bsWgkT@Gk&~E+B z%&fneh79n)RfY_3S&+A))B^dbX4>rQSnl1_v2K(xLRe>A*zNC(Umc|TIqsuJSyxrv z{#t>F+qwl$5V?>ORXsXd=geI5Ze756W5EMT`m5j5_V|J%-$5R`Y*?)U^e4?YDEII# z>UP!YUhp^eB`WI2NaYweaUQ%T(b-pj6)qF`br$vD3>klqOI9v?t&Xu7$_hPpL;)ub zqffV9)*C;g5WVlU&d7OA>XA9!%$lZatB_kHFYff@#f>Ww zWtQd_QYflC3X;LpOgHtZSz)nMCpvilk?b57Om8Xi+G!cy`D@re8UV3>Y?1!XS@aC4 zvpNyvPzf1wBT;D`o-X}(GGt`1*+Y=$$c7&8(LnvJRSl6p@)PVBd03tL5`jp+XEBjf z5Id8U;u5b2Jgp5?T9hfk4bN!o>rFR>3ReI&x|NywAYw{Uy|Hq+ysuIZch}LwS}kL* zs5m@fuw*nXp5&P}VyfoX8;ie)spQ1q3L}KRNmJ@??Dc0Sb{!)wiH#>bmsIu& zHI4686K}4+@o+#@fNGio19aDx%OdNWKPsqe_$bFIe3{w&Qx_)2S#nk``OfT+OyzO$ zIL}$~La?wI=p8a;2XYp6ytQ2aT5?v$K=XSA$X4&=IDx_!>Z;>+=q|QWsDS+a3g~K} z7j_o3Q}YMZ`~jOu;VKIMjW{yJ7dT7K?W}r}pXNDBHU|q=0{umI3$4Th;lz?r&XOWs ziKgavRr5w_USMB@AFrlg(1E;x<_~QCx0GL)Er=R6m1a|SK$TY)en95m$Rmy*`KTx^ z=50BpK&f|cs}t!Rcs8eirSP==QtekDkU35vLE{0 z@q44rfO(q!x`ut~OTctvxi@SJG_iFfY}S?DVA=B3zRZ{_FQpsXX~uJdH=ZVm=9IBs zV1|sr5zdT34J&=^wq{tEC&p95;l;bmv?q+wb3_`t%^ zo^GE?MN)mP+8!(XlE*(()8ssO%Cj$)7A{2tq3q7m@u)CDgVb-%_6qSv*@6W<_|wga z90IQH%5h>_iBa|s_*L&>Z<&vdvq`WIc`>$3VK>)q+gIUjK^x`#VUqrvy1jG~EW?`* zV4=`NGVaHl{iLR85)R)g86JN_DLK~I)Gm6FU4!A6RFzuA7X{omi~`QTn*uH(LjGN^ zQ%q1XHN^OQArHz_pZ;T5q_>Dn&1FY5JA~dB8E&^1?yH)eM>|Y0n}deQ>@dvFRsG!S zKQ#SpT+G<8Ro{0C);gu#?&qf_zF<6&Oz|B$t_?+3JV47CnpOO@TvP|^OJ6;2>;Q`Z zed_Z9S$*Rvw`7emlI-)8B8`}dt%pNorZhcD>X+8|903&)BR$NQagc@o6kEu(Dny$o z5O)KSsYN6=e7JWkz9i7Ars~+`t!*;GSZDR=UJ((fQy^A62#H^^E0V>i6 zw-kAUS5Id}(qmK4o{6AJgPe(>Z-ooC>OSGlx>ZL%$YRIeKtvGU}vI;^LB-2bfCK z6nzkDF6zaf2}eUYrya_D?jytp5mR-fK>=-4wLx~nkm5&a`j4$Q{KQqg-J5xHCWuaf z+g+rBYdr}yNUuLX7#U>P0%z$3hf>l7)Usk~e`m!NN7hlAVyJEDc%HkyxMUPt%Qk2a zCox5R?x*uI`wEKwbLFY%n4c-8^ew0KQ#=|#$BOcAHZc&$DZF$4#Wsi~@7~ig;4Pf* z6aP2jKT`?YAx|$6|2mN(+PH5V#P{U4xt)cv+hJoVir{KhRA#;}eqYTPV!o%m2CR>b zpJINw?4nYfzS_!Y@Sr5bawWeTfly$d?W|YlVr+ot<)`%7_f;wuphcm{=F?3B>O#)E zWa@3P>P_8_FJsysyOVi;5^VF=Wn1}V3&=FIaapLU1LPC~p47pmOGwS;vk`vI~z*ceM1iEqKFg4L2Eb7)Z7 z$sF`6uLQ=s22=5NlyYCOrIZ^EqX}_aZUFgEe!@-dQU;*xh5`IN(OJMqQA_WV)K+LhTAlST|OBtEF2tjCJp_&9W)E3+D>>qh8PTCL;Uc!QRjh*`uNpa^xNpHwM^a-JNXe zZN&0Jl$P?K)BOwq^4)477h}kKGd>vmZ;rm-A-WR3gj?OW*JULa9raypX^XlR-J=pM zwTaA&K$0PG6WH8pEtc>1K)yFFncXfVF21AEd4886*U@(?$yAYB-9Op<{Sk1^xp+#~ zDM&+7zBb&gD=>R)ny;(39ueN^t|1Qg7t8GG(_$qrnL$gabK0Kk2^sYQN|l-1)q8(sHxB9A$%GCajw1w--{lb%pVanRsW#dPvb-C1RrL$~WF( zAqqJwHr^|0WyxO;#6G^n>TlwDBh*qX>Y${1+Z*g$G+M`JuMdIu&ln^$RRKscZ?mdIF=bPzi8ke~dj z_H^d61JRi<$wfd72{Uwtb%gOl1lxL#Cavr!WFKS8JrJ!K>VdLp%>d&52ejtuXZEKx zlZi95CMa67#thy8Y0VQWHA4H*nqPX+?P*Pe7vG-N%<$q5Kx@W%pln)mn&J#86s=iH z^DM3TGx;Ga&kRh{nvHx~T2rSlLu+o5pZ;f$ZkmrOWAYo1j&P3hLD z_6iXXBNE|2(UOj$!-fqq7;Jd9!F;<_n01(Q*$fKrc-kv#w0g2$WsN*gSuSlB2@>P= zF5m9%S*!@qS=2C7+=G5`Ar<$+L5urkR&jT#xJOl-<;}B-JJ&C+M#XJ7XmMv{6?dkJ zo2=rj2$EG?M-|5strAb5WvW%Fh*1h?AXD=1uNZsI@iUZYjPzZ`PJoYa$taFJoYlUTbjP4v+*lVlK2{|X5vw)3St*6L9WkS+OE*h!zgfrH zW;wUN$A@7gv{wD$(g>BBhG=B$*bUm?o}%XLx8&aWuQqKNXWF7;@b-gbbZzO@D23me zL4Ipq1s}56ns$S8*D+ax^ZRSttyq6>#`z7ZeiSi$9tg)RyXd>!omdIfUCVJ%M{e0k zZF9%_tV_R3?(6t|sm4h8URuFwbQ-6USNpM%2tF}^dSE$apOx*Bi|Ax(26nR8E2YDq zA(!L7JF^?68W8&oKc`MI_ntF0Q%)dpUXe~cs47lF;MUD=4M%96&{fwk#~5neievvk zqVWMLk0z%F2ks#49X~OVSC?=#*&Jf&3i8emNEpAmBsCVGf4*kw*OaUN?npMi9I8!s z$@dUs!^Ubkn`M4Gn<;Bt@dyucZmvZSR4e`33{bpnnk%1_iAQKud`HNJa=8^5kghkH zxKiSLg2Bid9{H}nptbqZFhTW1?Jp>NwOkF`Z}WcJi)IWBckeqIUhTzaHgzi~Jm$q8 zVDrAy17&aCwTu9U1JpA`Z*Bm}@4X2TJKv2QPUs;)(=O&J#?CQkbi%BTtjQs|9U|pla z`e#mtg#pg%wCpy38F}Bx&D#G*(~Y|fB@RWGJ)mq(>>Z{!Fnpua*qvc&*UiR3c0c1z zrXe&|Wca^Bn*Va7CCz^_zimkKvsdm%nrA%eQ61Z`{}-gWZ&t(Hfi&rWq~($vb!yPi9HOoPQ+qjPNbXpIF||e7_X2n52t}7azz-D+frfi53#`cz zgp7^Ge^DALk056b0q5H3Mq797RV5Qq@jhH4$3!-II^oAkJ|=7cyZA``@iQT^Pqb2b zpIf{Z-enN&5&C6#ARUH??x+o(;>7bBE{i+GqBw!TS-nZC_Bx3);%GDuKE>hb*dj46 z=uWHwwx>LK#bz*S8AIE%)G`N9p8SU7Qr5H+YF=nB)ELTmy)D~wedehc(xh>s2St14 z(V={w1eSZCY_aDU;(QY5ks|lb$365h?6u{YKC=rmSn|Kz?LGB@w-I=|e$j~24mZ1M zGW8v5Z!`af<#*R&ew3<3rM+0*c&@35r>q^8Ih+m{pAq^T>R$aqD=(3tLH3hiSQuEQ zsbU9Fk_+6kyd;;`a4gNO7a~dG@e&G+caQUuT-+u}Rw*Gj&r5QCO?>A8OR03<<6@@T zG9Eaoyo$0)8SXx>Bw8aN+R)6Z=xmhtwJ`EL^%i?a9KzlX_#ZST7c|%J+}42c&*k1g zF)D%!&l(u(tkml;_8%T}yzPz6lZKw|K|?;&n|{+=_b?AyX}j4jZ|gc+?{M40cJ;mo z)UYe^!|w0@zF^~i#ZC6qjiNeco_zx5Zd3ea>3G&&tP@589>)>?s%-P_SM!&#QJ@Dl z%*Qg$HCmlSUK-=rPvIlouesgF+q-N957Qwt{+98( z3TREDq6GUgZ4SonE(!C4l~%@(Xlmxfvyw!d=S|IZe+z0Q?ocLbY2^L1oB-Q{iccL% zp?<%qGO08$q-W7IL$!70Y^gT1(h_2*vQM}VtjDg>F74~Fjl#&6UX$&~t9xixTD0k& z*lIR}tIUS*nYST)&JLRvT17&H7SclPPuwe$pLcej*N*H-tgJwqY!T)WFJ35NUYlTrmpJeICOx5Q6JlP7tS(kxE-UREf&#$Lr@qnV1u?%4jjM7f8$RrgaA zCUacP`U%F7L4wsXZshtF-ulY4P-7oMZB)99wufSy;2-wikWU{raNb_G7!(2_4HiLC zeH7aDpTc7UVci-w$VZ`V7UZA27!+DZTxyN6FAxbyl11ye2lA+4_dC%J#smwUz-iA~ zO-#&~tBBEJy|C7IvkpOh7%h&o#AtDxwar_FSJ)~omt~f=#dN8$+N*;r{IsGRX2qtJ z*e@Jl)w*46`Zh{0Be@+|=~bEhqO-f@F*7>e+fbQRp7i3gSNZo=Ed8Aa(sm&NpjCdS ziQBVWTZpP}A+@^W|FGQh3vYO`}PQx-v zV!u`E9|HX%Mi9txkLR_5c(asvk20>2VM0g=EfQ}e&*)zuZrwVjPQtX=u4B%m<7+vS zPW|}3*47zG`9lFCcRyuCBV-|!(Xw2x;9X&O)DV`17btkSzQ*f|`|q_SA$^^%uS$J! zC#SY#xM8-kxH{GYQ?6xv|MTrwJK;CjVA->I9yHC`*^C}^ss~N8c5U*W=|R)1U7Nfm z9yHC`waMEFsNq}Fg4{%-0D@&TtZb^59lSbWol$yT+4_f?Kz8W*mt}PR@oG4c z$?qDj$gbsDp<-Bu6a7>5l_y&^B?S%bK zl8>ESjU4!0`RBKsH*k-~G;lpSi5k9R^}zL{(ZvPy!s}&@!vn1w!JY50#^Gs-$@xDr z#9?qUP`@WPd?_|UNeppi%8_~sot5-m)lCD2qpu2<|9#$vxmgu#3=C`z3|y(gsNe=$@m+!@pVw5WqpNE=-e*4%Q%}T z(Z+u)*XgYE3(H;HH@ZHL-=pPt;K=xnX1AzvVYsA(&{0Gmlj|0dmD}2WS!rYPE57?e z7KRHKQ-#~|C5f8m4r_X1AHl_>_wDMRTqqNsd55{{Ns_+!bd9xWf9jqNIW3#9KTBAj z6SleOJI`yVLOv%dDPTqY++jyW9;u&uYTw8M&XNhkjr<H!)@yS)&efhv# zqzRb;HF6|LZdQ`jBx!lSZn1rzODnCey0E#@xqB_9E$|b&%4d~CdYasNHVYyjqdP`6 zIiZLlInllCCQ*!VcV6|Fh3ZHzZ*kw6Yw2`L-+LAH33B+N^G61I=iE>%9BD zLp346@~WYjuhKr8p9kYr+`n~V_YgEfr0%-t*1(YEJ8~X|8qOWYzQDi@InUjLKEa)~ zV^^!i!7LO!VZQ0zQEoL*9|fI7$5EE;;gGxN;VaO^gW%x^1`s@SV*j8W^l=HeSRDD) z+N!}hi3zX{gcsmzlkPKX?Zp?LVo;rihnqbZ$kphv;n)HQE+ylYL&fvzpnv! zxSMSv1f(fgnYaA=oJZ^+GIq3Yi2EE{qu9qGIQ1l79jS?Ks9bE@KM{IyE|=j^8ZT?t;?pxN*7(IYL^l+*Jeh7! zbOY^Iqq)AMHvcKQVMohl3!^8sdf}6oV??I^4EtA-sq*q_jo04?BZeVTG6~k(qPMKAR{pb-QO#|_b zP{lPm5g-(MKGCw&?8FWtWLk3GO`|cp4au3{ZpQ2Vehczfw^_5!CdzW3Acemu=k>LH zxPP%0WCkC=zh?`;zq}uBZ;gJzp{cxOmF?nzvQXlZnTe|2BeVpa*kj0U&VpC?9#L;1 zW)U$$Yrtu|nNL`(%jl7I#PV}RVR|pD9-T^k@ALE7>tDW=yxxqUH)j2Zsg`kFG@4&% zz>!Ylv04lbbBE`AA32QyI<=xGe7*P34$qi|Au%{>iQUgHyFcAHOWhbz$1)m5PJe&l zc9>gAr0LroG$(b0%1!$(86l$LG-`0@!k3hxF3dg$K6W?>7sC}@d0H_3MP2i{g7}{L z4|mjoicV}L=~3Zv*``r8b7SN0TC!hq9XDOG zuP)nV``nF@w0*`ytw!AR+llq(JHGPydh$l!ck1_b4wtL*j!B}+`pf zrmmqiH#gkZnZHQQY-lZJUR#NOUY)IuaYQ+QTGeO~ELszUF&XF<(LNEYfl#W{K6K)+ zN#C7tg44L2Z%;pH+K~F2fCjJe7qFLV(=^h53C$mWECFcV8=VSrn#SicQSN=ynW3MN z-?o$*a?!cpt^(C+XF*C0ZBQ@F&CKh8q^?ZY$0U77VVa~(XERAZ2SVH>^j~q$DehJq zx7SPe2gR8Z8d^^{A#%O#!q<#IApU(_p!sv2`P2RU{U$L7`=0$Ku?0yhJ&E%eF|fAr zw`#8GO1R2&V>afR^sLy4Eu@~ZU8(u}h#u87wnlcC?xkiC<)v!;8Q*4hQn#_$nxRQu zOdMmkIUoP&yWDBh7`I9rbt+Nrxr*pU1kC$sLeCTr;QNBk*|jn^ z@ooT8&ZlmMrjH+4$*gDS2Hy|4{ffV zkrZPb!1fyFSVYX&WW(>#yjv7DaLXZ9^vsF=M-$+LJg`~1>3*Eo}ZAa@` zZvCdF3NN(p&`*$HQb%9^%jk^mpys?tZqvqibMyP&jm-|x_c|oq{K8GVMjCy$Lmk7x zg~)ua)_>Ro~5tVtp z8>3Hpm(?vEiNI5_74Zg}PRYfv+k?)C_sB++#r3zAkI_yJ)nMHYnYoVOFEs9&>Tmr|X9&TQFDC13&>lJd@^3wVGYNT@8 zWSp6u@r~3F>RfEH|H4#S&)od8ddsr2+j{H%rF!@LBCEk~r0#@5q}OZWynZOR2g{D= zIR>SoGpxlNN)0vTm+@1J#|1NF^KT_rZPSkn$2MJ41m97{4ISZ!`g^#>=}^9O#UjZt zIS=tZ*Uyvgt=Sd7jv5>tw8Tpq4q95e> zmjs@=V@GTKH@W^TE$$LXkDwLEu(|gD1)K6!DjwRL*nhA@%o2^hH!=`kjUIj^^Korw zurv87`r!9Q##cq(?`NAE{h(7Y?(&FR;j5vh^DZu2#0_iq3K zX!DxRyUGHN@C3`%CI@dmo)=C7v`pPU0!W={*!a<1XkR{R2PgJ9V;$J&?ne8uBNycv zdW&4TE;X9fHt%%LyvO#KA!2LVNspmHx;o(x$%BhHhJ<3}+g_;Y?g(mA9P*=Wx^4Ec zicVCE+jnAx;2mSrMKsGJc%ut>1BNAtAG_xFIzaL|1h_)2)>QppAwQ_=L+44YT}LG<&DZTD=gmDI#QJ z$m1>bsrqcY)G5}k^Pnl(tn-0e(IE~4Jq_}1%QeV*7e7MY)EV^FBmA8?k6c%M0Yn(w znA9b;8x|^)kBvnA=xwA-k|L(dC*qb)A_Zl_?Oha#yh%t4Z;2T;Qc z$-(%q48})4$W0YkY!q&tVOQ!IsdJc2Ll}SEiUV-^F`%L~+}}fWXURtAAvESY4T%}> z^Q@tM&1AZ+T_zMGY}eVDKKWU8rqoTW&Kb##Y{98{9I+duO!b60n6b%3P9~Dw+kB5u z0_~!yootcVYfkhuNLI*>zabBy1KmCosUbeAz&ZytyuEn%^W5z%=(9Od_IP{C*uP0+ zMpSx%;yq?b2W=i(^eWT@pJ&F!hYsM^k_tME??#o;6E(*1NPH6Z+&Mgpq=i0}EDdve zM``W4s#5;uNH2oy>CdR-h;Kjzq~_69fEYrBz5wwDvikzWM|}IjQ}~CH9Zn~u6`Xo} z(;4}1vQ&JP?d4GvnvzE!L5X${dGs0AlSj||yB-~zHmvDUs{%{wDGS3^Chb9w-2tRR zCUuP(tf$1T9Jk;$Ba@o_2!?m?KH3w$K%QrNn{f>Ht)HuY%M>n}tVcEA%)bv*l1 z*RaVy-%GA}@UuekrXi0hIC56nHA@POiM!%*3e6}SCK!c-6AP(aToc|g(tN=Xn20mtYMvvf+Uk@g8ko)I1$lWb8 z!#uUI><4t;n_=Ti&pa;_A2rAQ`fY}(s@72dj7kB0sJjhFe&rENXVt_=XC5A>c!}HI zz%2L#w1#%~Y5BIZZ>6}?U9w7Y(2=Y`K^Cc_k)V8uKZ(|)j-V({ZdSSnNVj|h0F9(ZF!eo@%kD=s@Uq=B@aFSq;0>949O59{B@2Ab zL*pmFpayg+C$%k;4h>eSUj6dY$5+;WjILrI{_6&2ax9!SIQ0m@tp4FYK=tOS-d3?W zN7Pd^+kR1>M_Gve4)4xt1S{5P?9Dp0a_0BDI{R|{s)-cve0G2C1n54d=#w+;wE5O% z@+Fj@r`lxs(d_%tycJcpE$F?16n|OV&!WH5IPV!GId+2G-NeKu3dS~FJIp=&Dv|9~ z?vkx6pS4<#SuT7UuC;XN50p@bf!pZXj9t~DZy}JnF+4WVaI2xX;VM#0gtB%qhF6Pl zQitX2=<&oHlK;Rn-EtIt>){aZ%09&FSSR2%Ox_kOUVzqbVbI zk5Ix`ZbJ}wqGWp|SZf}m%80|+?@#;whID?Dr8mp}@QYUY(sUL{*<~(n>jDKl!{}jX zV~d^GEUF7MRlZ}WCTSUuq#~3sx1wfr8pmkbU@cFr z-&cem4>TR|P0{z9`n`xcg}`D+nm6+6EZM|*-TD>y{n9z0?*+_(w{GmnB}U6&##!>? zQ*Bde7S;uW1Dn2ekN4V36jDvDCw}BBR@W}@CYx#Vwd@u?K01we`m>bU!k1Sc(g;I# z#@GIk4dxs{=qSAG8C*EMnY+#nB zpRdm}DwyIElhpWfo$s7(&v#C9>!#RsHHFl8A%Nk3kip0C>0*8it{^LDAbzDeDZPR* zsJ~S#L%xdlRyi#{yM(wKq_32O-%jGP`sdB`@Q^>E0|AK?l%B=)w0$Srx=57 z@H6)x{$Q^_X`Z@BG%>wjv_-`eW*g)@Rfof8+7VA9WKUoOrV2Z=^7}~Oa!z8AzuXd4 zTfaw-x4K8KgC0McUKce@XP-jdXNBVHTe>nY<{g{zjp0Al4{r^BDL-S?ArAVzw?>=Y zyCS<<8RqGITAIwdYTNGFK>dcMW-u5mK3l)i33ZL#g*%RP)O@OH_S35cebec^b~v%4 zDMfAhJku6yXw~c%cx~yG()(+6owsez$KivI;|5^WdR0LdbKHquRh?32{WJV;Ti>a6 zjECDXF1KUMglUYKFpV)2rZHy1G{$Ez#-FnM=%`skj4|7Aj{C;-wxb29mkeuB=?h$M zqasL?6P@*@9y2SPcLHz}Hn^V5*dqkX-*sXSp%%b%p;0H8O=c6yeEcyvI_EF9i`D(? zLUDwq2#f#P0eLThTkEOgiC*k+&0F1{E2^JeszI4~nsV5x#5}scQ#qef0hm!KRomzi z=HW~kCs?^^l+O7A?k$rop&J5K@Tn1vEE17$V$brIQGu{EKB-dwx^b61i!cHK5`>{? z=Ti-aJd@xXR~C3&U}P*pG^~K3m3jjcTKVAT2ja2V7gsHFS7P<`zT}Ywc*~VBEEstE8@n(O{ zaZh0!Q_pC1rsvbdA4Yu3V;S?Z#mhwMv(6t(XR^WvwI|~c!m}sa`bB4BPZpTe-f|2& zZ0uq5>;Z=;X1p_`U2+VK2#;o0rN zb?I>SdsK^5?K2Z-CG*KQk6!$z4NWp3H6V2#FQ31uhT?xkPFkd;ljh_v!!i#GEAjEzAiL*H6(he^_8526lO@~drdzP}i`LMz zE!ZP3x>{xMh|d<@@+{7YY(jsAc~$lBV95`h*vn)@pOx!5OW5iDsorQ@N#Xf!+36ct z-<^Tz#)-63{!P-GG9X=2u^`l_SPWm90f{JDP@Vw=GoZXQ$U3AMm;nhVZ7%d@6xclj z5}gwWwYC9$b*tC*qt&|~IyMwDoGVFNxlt1{vjG`i4X- z9q%!58W7w585xikW_J6>Wk5(hZQ6gb4=N#pQC9}zJmXSOE#FbN4l?%(7Tw@=@)#vj zTMv+EhDn5juwzY=-N`15R~weuPSaZ75P77Za*!ZutUK6GJXld`q@TDa5YGo+{8Nl* zgXODgopGz&pIn81biD^;_S4AWxNE`?J_)v8;frip^rFp8U*}{*CY!wFuXg=f`_K!_ z;CQbs%m^T_KLQO&AMnlwG>~JIu#9z$M19A9v|hMw_}^S*tce!e{ZC> z(H0@|mqZHF_B@=}Ve5EaVfZusPRR?OfOwco``Hf1H&6pMkFk}JLnsFuIy_O$TdgOc z)9V-e$U8fPxAW7#a|BS!2U*0y@R{3(Ge_Dpd0^WhEgM^@oNOX|93PCY=V!3{(RsX- zw301oUqPfRof=L9>#02lQglcQ)Fc*!EGfQC@t*yYhl0j_=$Ub{AL{Mf5AmK-yb4>D zpQ<$N7m2DOyLbPx`P0L5H{v#ZAm@@ywEVvgi6%K&;g>DuL^tQPFS3lA?Ebz?Nlg-4 z3cJ*aWR)$~rdKn`)8hku9iH*`UK>it-+NJ_(r=Qfx-n@g51-_X)DVuyn%%<#xk(mq z$G|{-lAVHTlgD<{c~uQx)xIh2m^8@XqkV5?XsBt#xhY6+;<}l(J|^@9>%9Pe_=L)raou0 z;Zm}@n-UE&@=mtHym;?puZwOZV923orB}E3pN#iql-u%1)?TeoZe1GdT`+lo#bmH5 zgUiVyH-cF~W_!e)9YF265r5#PxnM)2Q{4zK_$BasylEQdpexX){!jORn4TI4Nv&M` zH+8$l?VOXUIooW`7Jm-7UtUWx_b8I3_siLeDaww)y{f;1?g7PpdCS}X&uq8`~jg~-|O1&Ff7En}6OPl^` zeJ{(&rFm+Uw|>3KplkynaDGb(4syR8?-RPNkwYv&Gx$ioy;Sf0BRx9j(ZBudBe&Iv zz7@5hZ$)kBTUW2E)LW7Rq4n#}B6y-2CDG(4NXl_;|G#GF7X1fukOH7}$5pzYzLHMv z(RV}Npsf=iZC#;oiAujge$~2fYT81oQ~W_X0FfIdB6pmv-fi$I(q3RluGcQxjA?0T zoB7DlyDvY?(7U?fJGg=3?cPn}db?|;TUs|_ayG5&>OL0|tt)Cn>%xgq|I;B|`?62+ zDm;>x$Fv=k>gu`>&hfMCeZ3`;#Xo=PuBT+Fj%UJQM0L33n2*CEo8h7>b0RN_ ziAF}9SaN2CW6z5URyr|bx7FAhe(cfQ@S}#&9u*v3-PdV+7lLTQqX{4CH1_kuA#F2x zG!K+$&+0vNwa4n!DA7S!y?G`PtlnATjrO|Nm@uqftul#0^0~K(eoE-VUd!qQ{KVY( z+S`WJI}V5z0ve66y?IuMa@^?Uuz9aAo0d=0NEBdGLxdR(*l^CE%g@7B@DIer&nt+b z9sgWIpU|9eq`OF_oNeA8cLpN2-lQ_q{6e^U;^!v)X6Ft~9P@Bj62=R+rDZ^YlIf}2+n6M;wZ|v74z;)=eL0fJJRylr`P+L z3{Ipamd)vS6=rb5mspmz0Wkt9%}QMNr$L@(b#K6zxEcVZhN=BJ|B$4G7X(ITulr*^ z(1vdNA69x`=kuW%8>$DIr7j9$jXrdSvm6C>%88M@{CRdvU1pa8IYAD z1+u+bn*qUytIg?N{m}>6#TuJ{0?j=AUZ0lVI<~wmztuM#Hu4)h ziaX&sozRCM>$)PC&hPPmx@j1H!+oV}2ZyyIm;xQ0HH{h1&BCBUcB@)fRjYt|=oHkl zqYSGYojY9qeOLB2AIWI42y=kMn8Doj=omkLj`!G0qN*!bAG)lY?=#fa6yjE}9!A6c zJKdcH3urbZ%XC3h>Q&bP`P08C!(`;w9Vl&$}1#ie6E?!mOEIofvU3@|pXX&_7_u_f@`>g8f_I_4xwTuBcq08E;0l7Q@ zkAM9sc>z#KR;K%M4&f_!WHMe=>i*(pjHA57@v6aslN5NoYM8qLAhLYCYB++x+=6Sn zkLrMavutxyUS+(hXx*skTJK(8K0gM@z~CwTUf@)Z1%xMMcw!nJ5^gWGE1{{|w|`?; z5-^I4>2ki&m)&ARYfMOmrmiF=i$gh|0_goKnYVYlk!+|cs8{(sz3V-}%XMY<8qR>^ z?)?JE{}c5r?|^ysCEgD~S@?m0U5ax$iZ76+LND{iSF-CD!XccHi7P}|&nme0oV?t{pVRLY? z85)M3ANVUK3UgGgC#>NFiSduEtCtI1Dej#*) z*4GRJ7m}@Zd+Ocs6`pmC@GwlxL2wBJ*QBzse6SQCwOAUA zuWcIg9QD8#cR35k%kkB|zA4dEPZ?=`xE8aYWh;GSitc$}G~$3pe7wv}Vxk@uu*j>a zqXL7loAsL;SvI!u!|-3Ct4K-cIaTniFk3&WZJ8eMehQbz)x=qarUE zKI)S2T%IwJTl7EDC-JCFeTFcmLF*a)Obu`E+t8{F1@PKd0gTJy6rYI!);+o^EmsHR zaLe#diaCy$YJ5404^sG0!h!e};~-t(&dQ-DASOQ}5A#GB=111zOowiCpv>Hpyp_w| ztBl_G{L8!y7b&e_7Y~|t5NRDmh;z(S(?QU|*FG0{kO?XTT9A_s{A#MrcAkLRQnG<> zc)&>lf+1~yPXk<5NhG>Be3R`fU+0WlS351~7M+jCp^Hi2c}4LJ18SxP8*^%N-PU*E zqR%O2y))q+-lC6_-nOxVUu6Suz3q)tEu+}XUR>yD~GcL zoJL1wFS)6Yg6BAmIRrWH3&p?0_6Uuidk3ebDV?uo_V>h;Vt39{yIP~GPST5v&Z1rn zgsHqk_#|2oIYueYCq=_5`Ej+0KKB#lhP%NIhM(5b*{Uv^ON2o+J@zi)#YWz|6C4jF zs%lwb;X@K*f?656zaw+0pYn^&yp`P@nMmus4GCf0Ik8i9=nImb^JrHmb`pi5MRj7m z_z;!c3lD83fyr>c{T;k&XLCqgPgyx8|896!vpUZ4o-Z~iLvk$^H(p1U*GM9M(;N3# zCx~q7NYP)rkFOh5qMh9skF|G!Z>mTizmw8Hxs+3oC@5&qss+() zRa`1o8we1jAP6EVDhgXsSw&40SB2Ij!0{Ns%X(SYUA(NzuJ=X}8_{~(@!d9&kb5-YLkta5|i$h4Z+&V;mCk{YfsrCXbc#BOh$}?t8h4CniC!jPi z9w{CT`w7NY`NRxHCm!h!6I-}4)=KS6pTUTb5B(8A*3Dq z5ujzfsO}pR>Nj|d5myFn4R&6Jt4c2}pX9L3F^YFc=eo09nbq(I&(qdipbO$RB{Bb^jN zgggZyg;IreSs!sW6&I_AkTq7F?@P4egUmgR`0sQvCm8WO{dTI6*g<|=#oS(em1l{V zN(L7RgscOCOJwc~Dvqst)q6mQwGgP}yamJMtdO__3Na{7?>G1?O-|Mb@luk&i3%69 zj50`23V3pU_1Y^1Lei3(B*;^xp~TwcD6YZ%eZ7-rh)P4rxoJL1j_QSht4jygXzr4Dlen#Yk z>IzSd^1E{XvcSg??rQo+sJPnvfbKnJQ1-x;J0$EL7gGa8j&lo>{6=ClCCBN3VLXM= zR&xi8x&S8F;s}$=Hth|lS=EGnu^LhKD)r4IJ3cd#epst!>Sx@Pm#Hq1K7ZIvJi+DK zu2OFXF}X8muzXd}7_my`&JRb(lDU+=^`y4IfE2%(bu@M*4rfkv<~^478;J&@6%(rC z1rnL)F%pl`Fhzt{LWE~Urb4?yhk%nDZAdrAnY49+l@gzsjs+Un2DVjT%}d%)iFCqjP02b@ahiiDdb^b10nx>Dz16BTx5kj`Q- zTPMs%%^)oH+IkqKdh$@m7no1fTr$X=O9tEToFQ{bp%H&YN=gv7~%|)nM0(05nUiK`rF?62rG>z7eTSN&97Ivo)wzNf* zELVxryzI$Ll+rs=UxsU&M5P9R5#9d~$dyL?D&&FGD1Mk{1UNw-a3jmx7r8}EP*{@(~I(?Ew)h{t6ZiWjob-NH3N~SxQEW^pMW5nKWOt4O*Wc$fW_sJw19|FRd z#IKa2#HmU?WUUc@Q<|1R=;)7xgWt(xVAb7fgKrRAs2NT6fzdc5J8IPBz#GC%AR!ktNuOM61?bTFY zP4#@IF6KwAlD+}}HOpM#St7=(!trG~iAKoNN;ruTUn-8-sKKQL`%DdRE9cV1tu7lm z)(saQgwhO`hqQGg#Fw;=(3HOW5_dXCU8EtVaZR&jR*Xzma82|qkxc)7_DlWjvX-fU zJJpEKy{}H($YPNqVn<|U^_aSoS{#2wm0@et)W!i-!v9dD)T2&n<;T^W0rLUMu5^vu z{RtkC8K3=NjJFq;BD9`rFDetB*fw%8{ILC-@WY3CDqWbIYhRvQp60cb=ki+0yPNV< zQQ@VI2(L=+OUY;0m#dNsqfa#sR#Ln2!l8=I$P3n379^1`NFbdRo9-?~ZqGZ_p7#`s zkw!%QxgR36hpZ7SMh1rjG0LsOMgp6jao3+?!%Yo!^nbePksJ+8ZhwZX^YIzQwj@iD zOF^h~tkcK;Q|F%ZFFO}f$#(8Pqz$rT`PyQIq{)Y~E_g8xQOT4P!IHXh5dQ$aA)4%Kw&tKgBkfr1=`lDEo|Dw|$uKrYdJ9SGS z1<>eKjnL@#M>A*3mR+|0QzQ6PB#`ROn>Ng` zd;^Z}?8*9bQ}H?bA&2hYh;dm~+o1gwiq0LCxjnxtntW^K76F@u;cvoLKkGr|uzFqe zmT>a<*+eW+t8P5Kyv&vis_=GNQMqzRo+sAijqcEHv0=$)gsmZym8zpTJx_9mtvOP% z{r4kLgEp#K_;hv#GX4RTAIcNiC2d-&?KZ?q<%N8wZllfB^PK%3&j0wYSj`a>c7n`n zWNMD|X!H#!?yRnBX!Moy=9JF%5bISn6U)BoffKPn@ICu|EA1D}Iek3&JLCFbKSqzy z3(X^&WCg-wM%tHNr7pKjSQN&g$C6J=B1cxoZX4&l<#tZ`U7Q^G6ZU@In_E}^?T2*q z>Tt5}-7uJN@;Pa+1OM69kOIIPXbl__wni7|o!ziCa3n0G5+w|ee%3%y5tmYAAD-NS zJg_&<0P6N(B`9hpr7`KoZFd+C5aIH@(Z83$llG&%R~C@D9jg3Kip>m7G1rI8#t{9w z`f&P{rD1^0@ht!*or`^30e8j>&B)pZ7hWptrZ!H-+t7TPy~{sy-T8{KwZb~#n% z3|Ht_+uun2VGTf2m;c=86CD5!2Y`($RihOE_Z=w!Wa{5a{nLWx9(@Q-VOiCltxs2X z`+upfE|6_+WlnX)s=Ai#9rr)9SJ4lHJYVXye3we`423RD{ayN~siT{OG<&)CokVwr zW78&kBA;9H?k2AM;~CxPO-a`41IfHm6PQC^l{k0E(wke~{fDXgzCPyvzP>DOX^|G%`a?2z`ca6vwjl_{>!%g@=z{?YZK>*&RRZR)D%E;+KF zNRa{O)KtDs1k(wdyNyob9Wczctme1iKi*m4(Z{3HQ;UXzoM#E%xJ>x4CEpn)}6l2W|*vcu8gULObdHMWV28*IE*RUv-$hH{m&JyViD z6!tD3UjB3RL&YO-^5B220ZHZD3y5P&BU$*Ed@eazc0k3;2{5}3#)6lpUIq%_AH*dz zN#E}zWf_I)YJiKHswVE1%7%JBt?KpdxycS^*oKC(%KIJl8i{d808Mwc zV$v&kXTf!`{p$IcIbfO0)^M=8_CP-l5X&0<=Ba$FDmLQl<>NFy66i%&^PzU_jG41| zCG@k?BJIS=;lQA%?1SjeQFtQkS~l)}?`FCAY(icSL^iAB8v@znny#v22X2jAqax1} ziwU=*-T8~$*LRFO%A?STJfPBb?m)Vxy9k4;QK|ehL-ur&--ARFi+ z7xhun2RhZ&eAU~L5xa4_aXrEtjve|@$pjJmDqGB#8>B(gX;9==no%lWZ1eB2!xL0n zCLx|-I`Y0+DLSZc*&8bR0{fZS!pgilx<>g=+U82{!fnRbynEwadS7}DVrmu z7?a$_OxE2RIG%~iuOI~M4g&T)mutBO zReND#v*t^i9uyFzIc9~xWbE&q1LSB<`PU30{2 zHQG~~DUkF~L#N)-p!x{(!g*&@K-`%lHHh8ph$>5&Uk;tPwyYlWn5HhyI!B#Xjy2?m z%a=uZ_3sw_26Y6N&e!G-PUa`rMobS!`8+Gk2I=!s7GUn;5wad!ASIV=XZ1V%w;J9T z2szj4vn6CHZ~Rj2xm8wDnvtm%V;MGNo%;IxyZVlh`kqzwMNV<*63A-cbUIch4w3j&_edgz@|m9It_o~QPNde3cH;CP{dUhEHA}} z*8Ws2abWU@At;_z@1$x7;Y^++vnQxBRZc!VseQy{>1kcNEIpk7Y%S?&G*@5ZU|cBP zrKg}$aYjzdr6-4SvNN)4UrR$bT8y4e_TN#0x+5gIrKzDMf6h67SW@;iG&j`z(Ec@` zS#zbw5^JVk=Ez~Qq`$(}>2`SHOhFBfBB-Qac;d(Ax^SQ%393rQYnQh?HRG@LV!?yPn7Le2Ag)lu6W4`t*k-@po_?X8 zBf}Fl`I`!#SooN81q!qKJZqLfTJ|;cGn)R)z-cKkS=I_5IYnOW6geh5@c}6!Y-&&e zNQ#}~6kGnh6g%TNb5qQBhacLpr(zn)MoA<;Xm&4lEqF4sC_@^4u9~HC8gpeXXsU0C zZ)ZJQBBLAo#{y}4j}s|gy8j$=cT;Cq-f@|R$jwXU1B%E^irajyO{B}0%|NbH$v{7s zJZ-e6Q=XdY*K^)j(+11La7S56==sOBUw(*7v+eVwdR63`N*}4s6`R`%TNJ)&#OF}0 zI!H2Xnq7vmH0$EY5LIJL)DG|;PkLk+UOG(&@Qu7dGMC;WeRT%Jnoa4EBW3gn=aq$R zTlpiWe8q$c3Sr-5|`tLB`$s3_kt?C%QD3x8}FPi#qw7kQ*`@jxKUI=8pg55 z3yi~x>~{(Pf%)2Ap+sK3_$Xwm<=(|*>5*N-<)1~HkcqWqe#WcF+daE}B^M{_kl(&Wh(UQqEaWS`RGAwSLCMll}hbvTM(2Z-!_UeUX0jf)DD+XD~{A^Z^f53i6B?kWmYe?ftt_5p2<jmvM@IQvA&s^*;;PII#3A8ua2{hA8cBHC*y zb_NUnwPuY6N);;$pg7s`02OKhU)xcLAZtA=fiKt4Xg8}dce~IXB|oQji!>?{A1h*X z88<$w`L^$Vq(viANeTS2%~yzk0|U%OLQ?)OUlNZN4NfO*Vk;m6{~_!DX=sju=7+=0 zmG(A|;%5B|WsuPmr{=SiofqarT1JHw-Ltr!8uT=LW1g^HeQLl@S`@(tI*`}os)LU9 z>4PP9U_ceM3r^n{dx)&`u7`641!Z4zvH(5x;C4KF^X$sAk2Uyoj$~Ma`{6p#8hn;H zaHKVuLjYrlFC~5)&r^9`Y@cy7NHzyftFmq`8qS*MRIUlAN>-H6Zu{?N@52@RZqU$) zPuy|g@Ya)Ow_3y!(p;(F`GMhEWlayj&4zOzj@%^byYoeIPf@w|lluccRk4zLW!+wM zAoVJ@DY-eC5VmeceX>T@TxY;HDPe(>(3=wE97fWAPi_e@Rf1S{8}YxY`Ue(qc!IVM zE2%P>@dkvzKgTV?iLWC#Dh5vpxrYVg4SS&%WLiWqMXCZ`qX1dN_U30GS4FdIJ#^KJ zXpSQSu@)DN4f~x`)`w?68R^*ZbKLc=HF{*@K;^}%_O_}t{li8BhK*qXOxD73q9gX> zrAFd!#0}!qTzoz+#WR#m=x`vERzQ6P;KIHmD91x4;o~dPJ7hi~W53FLS~#G(H_?1Z z@&;o+9x(6>Uko4YMVC%cox?-uPWx* zy|#Jv$vnH%HW#15vqNpOasiQe9{`nynv`tLid+{qd#q{8%p->Y)OXU?_63=tM^0`M zKi^CTvX9LG!LolA;E65UDsbIUTF5@=W}Sb(`$-mQzMz+GUH$F)0nN& z3x)ptT+RsD`l=cssclS-ne-y%jU&CL=yz0lNL|Lni=>Ckq)yE(zbu{l2rC=uJa2lh zxL*qcYIgl+HyxxFk?^+Zmr{F^ehJuX<;C1ow%K0ATgo8gyqxx^iW!q@2VdT#}cTrJIh- z_D^>4uKo4uX^?AioF(38D9HwL$stx0jQ8QDElyv}lx%yJ+LxaR3lr00mIn&1_;6kp zF;qNutDmHE^>p!90o$C)9%-a_WUy`|pK?}_O~*aEp#U6k;EZrH{Kb{0oM&Y9Gf)hznag??*wj|B}{% z=yj13!sQ#Hol_r^N{zen4Y(AOENBv~dleT#>avXzhumsc2%ThA(y3FMzft;`LuJd} znD#XK_WN}2q%Kt>)zerbG$Mal8sipch7NSLnZ#mtF-OkhmaT)2`Ybu1zCvbS>BHyA zr|HjFcs&R4ZYij;er1;e0X=JyTb9?|Q!^kam##BPJtIDu;OhQ2l|*+|_rJDxbUVW@ zfG<*e-Y`)BMnB9>&BVy!*N7iZzhQgoRot_!^rrbHhrnS;uMI%owahE?zzc+*RT}v! zY|RKuw$^K2#`YH6MDejDdYmP;6OejU3E&Rue2tQ@Uiid3W8s+M z5yrx*;wsyV)`~Ip+pzhWqVZQi&M)Jm6**Ztsw~kqT-YN1jA;%u=CA%c)AB?%sK8}p zJCH`Ia`@Y)$^)dkzRD@AVX)r24@>i9kZqBsWZ|n-@sS$YO#d{soJg%jEZfI2_`*y- zIQkyei#1%9#8BVVN)Pptob_U1>JhqFuNNcN9=eVZeW_k6zF_xPh4j5&6#_46N9Ur< zQUqK6gAxCW>a5*OhQqHotrGu@3TweXQcK{{Qs2K^k5ywk>aNGmq*I$_vl#11l}-N) zTel#CP;qPNuh`jePFX?Ohc(Oi7T4X6F96-eecd_3;u8*`=Zrg^CzVjN+>Yd|Xb^fZ z5od)U9gJY;tVbO^`2xGGY~B6~J^5q%DNFR^tC^p)o*b3k)1n?jPwvvB&|m5*N_NY2 zz!yVIV(D1uhwg5ApLe)dTfA=l5qLKNPFnIP0V*6832}5JZj8O8GzRlfLtj2 zRn%8!-EEH&xU-?TtfoAoWT8QpnOK9I69!dK-zbb85@oC?Cd^d5Gz$SbBJ|_Hmj+V?m)uo+F zpUR<~;IpJz4VuE%1B%>Dt!`n`cnxhvY82TUeKXuTzE<$)fnoY4NmU=Z_CLuU@+}ol z@vD=I?jHU;`;pi;>HfY7qN9hA0C5usUaLr@@n!msCCdH{E(4;N^Qoyp_4?O zYoRwQ3YQo&i|Xv&zgB{S5$_|3l0AC=B)HvV zpV~>$bV4ix?H#)meh(f{_%-6k6IfmQv*#7@VHT|Y>4LU+G3)szLFqgraRjmAaOG)0 zl31LfT`q#fxF(beuDy;vaH;zzRo#DNN%ZsT+G)MhdC|>F$?vgWq|U4rpT3DryPg-i z%_&DDPq&=fX(f1Gh>L&P*tAJ`(Tz<@aC!$^C5xTfVIcQtODk{1j4_mcA zKSnb~Qiv|Mmt>c6e~=adWj72a#)4>T>ZIgYaoBFm9KxrJ7q@*;j&xVz6v<9~{S8+P z5G&vDbhh^_(Je&6+TRmY>2guoh<3Rk#=g!F13c}w148A zU;{izKK}lNKTYKN!V9ux1XUSrgpY#nwEtLLz^|MFRJgXqmfu6|tAF`jWqGTtc2(xG zsk6Qq}38Br~eZ8*bXBibLS2^r$L;|4?`oeJuttko86A^ETPPYtL=195gRL12Yv;IZ$=c^;{I$dy3hc8buNYJau2eo}KYCo)*>YhWpiEb@S4ixs;)Y8Ydx><1 zefQyvG^-Wo(NKz_`(%?Lkf^_v)~y&Pi+37RBMHOF@u)shnWJu;6GDMnCLkSqN-c=ETE`bi&D>7#4In0WJ7 zmsjbjIb?gRlKB9eLTIuhJU?<=?8m%FA#-!NDp%-V+tDWr!+Vi?&TGp>O2SRR@=XC} z*$+|)9eoy&Rc_>IoVR2B?e6~<4y1PBI>)P<>iv^ew8C})S3ZTkB|<2%2)5IW5Bal0 z6bWzksa%^Q#hLk$m6~-4Vnj!~HlC0qxegHiN-k{i#BNg!32|a%n6e*GF)zPOP1LXlNv87MH%?nD0kre}M-)<& z^+{?-+pJy+iN9Avow%N0mosb(S#7T&Z_a#ISWaza>k?lNHJgp!%blgF(tuQYYd>A# zpX?7&AW-2=bDN%3d;$VJwA>pgH+43gNy!<~X9}8JgT-pc9v{`>yR>uZx6;lJgqs8e z%iIBzsAqUX1D03AqS%Qsdyv2{S`fJkLf;vabEi!kY*l5P29%}iw^Bl>eX6L%B~W)} zuuiJbY;j{Jai)bYhuH&L!x}$b`i%G_tH`+%6NAQZ5n!Z%aTR@wOV9aR_ z%vWSNRT~FNUZW{>@WP7v3H7>Q{L(Vn^h-dIw<H@XIjgq*`{xv)H z$-)O8W>Iu3T!lVT4amkTcbLMbg}qC?Pm6J-LL-|*FzekKyB~^1A&XskEwN{OfyUrI zrtNHbbwvW-I})bo#^H~~LcC$T1=2vc&^2$~=yArvU`O6){3ACH7S%9Ax=7o!AT2O74*LOz{F5 zVZMWv9kT=rHDMfGn#yy=C(H%5a3UA0v9PkIXj;OarNuqJne>ZfezjX~7gi+7|HuYG z&0vT}W=hA3>m|})N**~?Zxwv>xoj-ytyQ{t_p*dEF8C7Dnwvs!;lzc$$=sx^mR#Mzlp{9|6=SjcK$SD4YkSFQpA7Qc8D z6xPxY@DLhAj&KAFWA;hHMxfb#5?(2(DkT-vblZba6X}XzxwD%kjAWH^y6kk7y{m+8 zAiV5rhV$v(O5^^Ou>;=7&GhY;Uw86YLpso3M*L-xVBbpWL>`qjou=`p94mXnzm%-AKi#4;=yZD z@dSZ0JlsrSo{vgFhUoZW_6ndM;HqLdA23rx%{@djzku`-TdrdgBro5#SLj%`R!@IY zv}T?R!j`^;n2fbNAoh==owi(9Kw}Q{(2co?@}x1>$`b&dYT1}412R}6^-g0Tr5=C# zs*^|Eekk(?-w*TM^tTq~Ksol%>|=pNmIhAOnePZ=s-*X?CLd;i(gxL8L8q@(Ct|Jb zhW8+xCZ4rebQtzwTLoUd{UiM&@`Ier6@N};n}scg6N(;xPa6rXkDGtzCZ5S&8`GAu{x zVX5V?vUMq$VhI1L#4J3Oir7WF95%0wRW9I-uK0APumXP@fy1JX%2LWHk#l+OpUelf zUsb9u>TBHG8Gg+Mi+0OlzJ;|1O7uW_gA+o^8;(_xwq7z+pF z$qJDDkVtzbwZiDv0up?Z{r{s}ef+8S!HhWM$ph-f2H@G>@8$fE?{EnhX1+Oc3d32> zA0`XC5NJ=?hD=Nu-+#JSTfWjD0bd<4pgkzmKDk%jztglz=vnJ4%(v41Gl3aKfPfGa z6?`i_uc>&NZuPhlEUC3@`h$wrUT;l=EBlzW@jt6FIO|8*O-+ArNKAG{oEJ_X-;07k zg61Epe9QNaEwjm6AmeDrW}$pR$Cc7Bfreaf-Pl>=ciMRx@CWPU#*DIcY5#G6-RLvP zA;cl76w`N$&L6FJgom8-)lPkvl7h;DRCcaY*+d9+_dTMTnLt&}>^XwgtX0j8wo#OQ zXxo722{L8jxsS|^zUD7;;rWs;+7o?Lt>HAf+;uVI$MU^P0>EM2Tew80ji6TcU#Gx% z{|3Mz_DnL$*wONLvhbu9^&X|_t!+{7^-jI7NKR+mu1T5fi)HYy8kM?P2SFc;P`Y|j z)tT=c`9%*?S2FlOMEInC3P3c*i(iqEz@N+{y}Al(H{x=CF^<@{*X#A-dg7ql=jJg6 zYgD>sb}q;B$!WMM9t_5LgpNa$!p=9;JMGd6w|Z;~C&c^srX;`Repfv;FrYWc2M<{zSJ{ zCBt63-@SX4A#P&>EvgABlnH$#n z_7i9+jD$6oSahJcx?7bX7nQ<60wjh{R@6{TdZS1Vaw$1!1iKu1$+J)SSSBfL)bTNa zIc2HKPIYmL!;4Bof0~VHe-DZjc;1i#b$6+y(EE0^*=3;p17kzU=P3R*hKH{8 zoq2oH!k9pV20rb-atb?%54rq82&^lhG|hDCXZ&cAv|mJ*1Jbm6cunw?pe+-B&%cTf zS!^}uS;2x(FPukv%>e}=E6C;a1M;n42RBS9_cXt}kx?o4=^-^MDA+KysC^uz6VX{jGB7o=D{&c6;SV3Y|% z+x2-TPhCD74lbhYnoZy1gpurJdUo+7I;GL~Iw8UYC717MiI!m~(kFaHeJB0bQn*qY zKO*r-|20yX>5KBEg5$g_o+5p0`o_6|*Xy*>O$3+g;8?{FUL+vEGs2;sic=&Y(vi3B z@@6E&1qXHiiZ9{kU1KL7#j7`Jr2Q7%3VX(wh7hgr-7i8zvhaeW0@3vC-$pj28;_1B z{317eOE#Pv2@0=v!Ua()i9&$Th)O7rEKg`UwF>_x*^>T?-C|6>Q`@LhWk~&^wqq2BUyd&x@#HajlK&BmOsT>U1?_CJiQ;xRAw*RueJwo7K$Bvm>OTy zUPlR0byg%YB3~6sm_@u(PKeK&tgKB zx&k1L>@#04WjUy;K`sTU*R2aiA?icGq%M`z}>TvX$2n(dz zj|3!DrbQ8&Ov_xC|P(W4>dsh-{lTaeWMFoJIaP>G=z@a-p+{k z;tjF4Uh^4j^~7);nuFR#S3{nsSI3&$MZZ8ZH~L^<+0>tHM{~n^u!TEyDo7Z7s;SWfFXsWaxSm8%(wUmc+w|`C1ILp=8nx54P zLoGhufXdV2Rj7v6NSC}Y8#<_BQEaYky2nkQ*>8DQfy90x>=}4aTvWWkD=Saw?>UMJ zXm<+|K*oxmppTKfa?q_o?QqGvpVjPMB0J_+aW; zZa>EHUQI(k&r&qBn}-%__RSI^Vx6`;?H@pnv_GH0Da*HcqA$>O!Coq*oj;Myo`h9v z+W#qoB6SUKFlmh+y&l_a=MyM+FG4qAHsHG6`2BJ_y>_oQTT(uh6yBWu4q4!hqDpg> zH88(?cccw1?_%DRuRAAaePkasX;->wM`lP3HCKm|1NIMX*k3frYzWqFl~ThMBADJh z8m`N#rkso0>)~RxhzA3#{F)yci1bFHvHj&nJi_3(`N)bb1mQf7-->PgM16H%@L)eA zw!b8DZESzP=n-{eB%~_oFK2#|9nt~8whfUd02BoMSYpij6-Dt@bo1(PY-cClj=1F? zpljz$kUg=>Jz?*g>233p;l;7$4!5ji~c=)>!_AM!0z zNDe;gt~lg-;vwHM3FM}~@{sQdhkRdh$oFN3e2+imTV|2m@-L9@x>4%)JoURp{hqIW zN6N3zQQd{|29m}u?#7$k5~Idnta-*Qhs|!cYJgXZs)W`M@2PE0vmbCvz+4^Mdd{i= zd3Y9V9a~cqTU|e!%MZv-1>m4rE)-nSE|vY<11-0p3)Z9wH%+)@R^ljQ#qw{}#nI2cqmzLyWe1 z-1F8X!9WUq-BdY8a2V2nH*#CqK4s~{N2^F1U~5j^g2&6z5#xz(&9yh31^bu`Kg26x zf)V;SG7?$KjVJcrh-$cfP_$2wD06`xRh+bbt`#=x3h#`Q4dxyd|G^e>Rbp3kxSLA# z*FO+>JWGXH$p!P39_MD(54KUVx#5R(J=e}27_mFrs`w-eV;~4<2o@%GMPAkbz)Ev! zFQxX3ejK@0csVLHyY7o!=|x9SmANwQ|NJ*FBCBr)9%^CBYH2gv_~vBuNV>&2pr}2|ET0!kd$BiTuH8(d^fW$NnBnEXa!# z$F}@TV(H`FZn1xnV$X7lokQx%eJgS0D3*Mga#f@3AyRa0&$B+1nv~n9w527OoiCo$^OVmedB(AYvCzJixt-I1zO`K4gnz)B3JAVii znjA02Ae++u6DUoh&LB!>C#}c;uFg9%|Eh75_CG7tTRk>h;f$J~xg!06=yDAX+bK%^ znS*2nLn4~$T1K@(Ad@IX3@R$W=DbLr?!nA=fyQ{|o2|7y_Sdh`oR7B9oO!A_Y*4Hd zNTILJV(w0oouBh<&3%DjTh@1g`JjN=g@E)2i#!2Y9LBbJ?XtIE1EO@3&>}bVC<(pC z39WHMeT1?_r7S({e*ffRiX7x0nYgfR%K<49@SqkLDc)yB*O+s zM}Et8u^gy{FT<94(yY`(^;xO#+${wibEVSG^i3aNf#{+(g(TG1#= zNrQ;FZjW4_6_bVg1__Frq$>g-&67~mK)FOp2P>FpF{ zBo;^x%kfJwU;-^S;`d8f?04gk2F2$C?c*3-dTo{Uq{8vy-NL!C&yuNW!sQ68E5$sZ z(ulW$e#2;*YxtBuxzAC)Wvt5|CRO_?D~qCd7*QSoL^aAb-Oi9~dWOMa4T;ht$9-o^ z*O_?Hfz`&34Nj)-g2wdIi$mJ258=DjvDN^mC|Xv%;T2V{Q>PIhheia^Wp~ibFGfcy zBjKcYv5e3l6qv83{iaJ~oX`(<#`Yg)%(93CowIY%DgBU~ILMtmpDhuaRur4$`hwkE_?W$!EzK1EYRPx=f+WZEQ6$!Wu+ zOITU0QaquCWb7*XRw7Ecpsb1)-$|$s0+U`8yvcrH4bM!|OictKQ-c=f`H;kuZaz=j z`ygy*qdN9gsmU`49Vc03H^!bMf&96!CdSa|_)}NcmWo~-FS3(e*c-knLP+Htcn8U# zs9RGg0_j`Opt+=;q8ckpbcwAREBolT_UeY0kTtXqO6?MRYFm!5)Th=m(`M!~+xmDH zMiSi**w(T1Ur@v7eq4qZ1v&*;RaM4X0y4IScxJFYlI>a+84Hr zp;%(_B&MQeOumWKT`9F_{9&_ys-^%nO5Gy%8)N4K>2!uFQN3rhrDDcr8fZ6i|v^1 z;TO0M5}c;a;nQQKpT1w!CbuHZdP#~&`ro>ZO}+Ze z6a&Apx6EO_M4mPhyx{IJwyhJ(c_UH7*MfkN_(>!fv0`{d^A3SnV5p%YD>z0Vw}RuG zVQA+82FpeQ;pBKB=3RqbZCtss+Bn!yZEP4^klLm=9QGYIQ#t-X+EbdsWiBNg1_Y^1 z0=Ub!s4S535@KJoahKeXFs&3QT=a&tG$~8Rj(WVvaEaw~Q@oyfQ!}MVCRCQp_|7Vz zfaLwf0N_Dh;|^OTc^?N85-*02FNIwk&WE|5xosVY;ISFKi_0j#GkUMZ5v0G2If1F5 z9RnuX#wht%QgZ-u8LPTqH0(@)!Xr?~M7t(fhZU?$JMXMvzsG;!MIyzvWc=|qlI0zK z$U@2|RLUOX{zb}vq5()fAt@0PN_bSHMF^O+P)RYv`c<2^G3hgx+(H^i_CnHQ6}{<4 zk$mWCGWVMshBEZi7UuvkBJ-*HuV*amXq7@Dgr4o zpNF2mlD_8EsFpc?n+Uv33?p+ij^n6%lsq_&$nF>k2A+tG%IVMZ6xvE1MtR@c)PNl9PVx8QQQtU!eJP zi4>^k@!%q%@Q_?~$MmgcnW3hwZK&d%q)VNlD0IQ_2m?dfzkQ5eIo&0+FMAs=tCN~3 z`z9KidWsL%!5M1d>pAB93#30tn$)F0XnQ`Cspx5$8-YRXlpF&(L)Kq}3yF^tW~WE> z?1Y8gP%@_dn*rcI%uaa%xSE}=6o%>WL6@rtOUW?9EQcGigG^R?SxHQTgy0D^0DwUc zOu_zf&%YRF>#(&;JtR$c*@_G+^I9&dg)wmZUpnWuy*bh8R zxEQqVWKYVr^_Lv=7$*lbM%pKAR~;ZBVe;9B>u)E00biUKi_krjNItn&Rq>QwV~VF@ z(b|I?(_}K62czq?w%0q-!-#&7H)NKS#$Ph~Kzadsh`7RLdw1bs50r2wp-(`HnpP(9 zJE?dwp13zMqio>+3f|FBPGPE<@@CNJ6e{k@Z&h(Y>T<)I(o#)&_P2qKHUch1+tB}qUozA+Q@KRim$!y*^S;C%5jH9;hmyl1 zr`e^rU#~z|D)B|TzWadoF=I{*(>+rhlBMiM9I^dfwmwoJ!I&fKK6F3eh(DQEh!Ja|8osHbu|^_P z$C^K;{TG26Q8T=FE>$|4Ex#p9_GFYJ?X>@JK9y48QPQM-BgKi9P|XvnoJ2b6Q(I8> zKv5ceK?)^^59=qR;eg2Ztw#8onVC#YcYfy)iF7TW* zD8F&wWZh$XLe}v75XXtx;|{3hV5z96pstd%f4y{+?tU^5?9qPbrLOhBsh2#dZfX|y z88>HFZnFHUA-(e7#k-Jl+P~82pck0j_3BH2NIk}<{qQ?rrksNa6JZJVZG2^Qh38Wj zs;QX-rUpBhEPtGwD@0I1vwSyBncR8TnMgS~1b(kUykm7*VI;~SWu+$${1%1iwac}_ zbte<1B7Rx69{y|&1q_wtM}4Xn1ys*lP-DdZM8&Bmz;KqHq`&R?2PBtEzXj5uK`aik zLCk#~+!coJ# zC6t(}cF9r6uoShzC1}e8=kih6hYk?V;b?)Zd*|_i_?8eqMPci(eFG|C#dGC={}YBb<}$NE?fu!U+0kPM zkW1apY1r90)V7}8K6FiLpU>?)`B{qNk1`sL0#%A1 zYK5Wy6JhcRt~~qws??4q>GZy3Lqxqi0jLDi8yJm3dTxlr3W#uMGIhHUmlOw)Co{#Z zOo>{+g;U|pW{9T!M-J^Qrjt@;Y6MBj)==kP$VZWCAd8t#dPA0;%!ZI@4=PUujo}T! zaz$4KY?B(p>j(9EM<}ZUCQC?mGYUx;Tmmh69uEF+Kw^qQy&AY5;mugHcSbvNt=dF* z_=jeR>XI5m<-wXe1|#mZ5ds=aMm>$bw*WTvop_pssKfTujaq=1q{yCwA=pIR4uQ&) zwJ}G65K_Hf4=P?*H{ZD1s~6BW?r!D2!HfMNZ8*+J={kzcV`BF4rw|!b?n*)yjSrIOJ;4Gj)0$4H1yk&6`bJL*i5* zCuP7W`BbMYky@m{Dpm_p;2swCWnZU$2miIZHttHt>eTo#5*AaCk|AEAXGF;Oodk%; zt#&+~gs7GN1u0`B6c`rH<4(V_jFDopb6$JfLhoz8h88wfx0Wc6bAn}EtZub@VyMoa zIZxsoM1~kCH4+F%FygY+%M22GGi?{`pnXjYe9b-J7BG;sztdo3r$$$&0M{BRFgjzg zO07uTIjM-k?B?%xrIp?xHCEiMW+p5Z`H4izTdMq*kxM1gkjU;t?u!>c!n>%+Ao2ds z6wl|&Nc=;55q-)}HvXTa&cv_fBPEHbnT3DB@(!mZpgkg8e(3a_KRY_KyLH=;&%lK^vx% z!G0ffLjZICLSljHNumI90S}rcs%4s9MFrT!aL)(=3~GvE%2B&_N;|Q_Sg2E)D`Pt< zA^gPA`Jx&p(qU1nc&(Nt$q&?`_Cll@II(S9Qg2-5`(z4EU`lpZ2aW4iF-NVG(2I6| zXI!!`wnQw?NIG@b4x*_TmBT^nLK&0y98XN7pit>=p0Ef`a6XQLkudIvqMw)_)g zdE<~|Y%Ba!PI41kU?jv{hzdo8x|#Y24X{SyO@&sXV$h*A(W?kSW$%p+to~u8Cog(z zm3h<1Q~{7V6z^KD*xlJGS9h5T{rbo+x_fhr?5^yzmwtjp9yEsAAPFSMO=UkRQIE?f z1lJ45g`WYub)AS$-S>HJV-ySTCXuXWJgJ+18Tr#LBBjl#i+&mTnM8Jw z$g_x4dR*5&i^E0c#wx5TFS$%qMGM53SJWzBk-GM_{2ow1WRTUW;&Hxlp9wk)brDEx z|0UWh(#?Gre@R?y|M=*&>hi@c2T(GTF3PoEm5#vlr#}OLpb~2aZKNs}&)yc>e-!s& zV#3`^MY%a6Z!(InB@6Wm54&YW&Fj7oC3|G?sxV0Zy+$so_zRC{ zyTxDdP^a}Po{)g|7jKt<@j~L-Zea0A5+FB=>ioJq^IK(_uR!E1+@H^uvv4(}^eo;c z>5s~!U;Mdzx6giWk?#Xgt1eIMM<;}1&7GnJKP)548_|Aa)b&dtSt{Rqj;r|2*`wvK z6FwEv{@+xJkP>+t#?>#gJNu6?C!s4lM_=0)Djw#IJYQB{KAuBZ_t!T)g?Ve?tuLaN zH~rV}ST5%)*k>->v8|0h^kKDS6Z80l+6_*3rx%BcJ+Sc0pjd_P02t;(_e@W}_kwza3#@xTge2sgAUSf*4CkC*i+wdU?SJx2k)iy*q5hDSr?yqss3K0j zi;PUDPtd~TR4>=GS;s$LAwhj-ZxrV@s?((t@Rz7fTQ+kG!ufLE_@n{1 zS1e?>8?)-kL%b~y>|8K{yifHC+sL+c?ld~~{l)>)h^5(^?DLoArjD-D^k}!&utbj9 zR~f978;+FSjHPzS1;iziJ*M1LWRHX z_ZzJQVon8Odk4-u=C>hZX+0*n$JlMiq7BtlG-t)LaZMi)m+xl9GlZ6<+^la)G`v}t zEYXrSQ}VMCEu`#JEGcsepF?!&XfOpa=>AxAi6r*#V3?}j6H`OQ)4>03jIUBf1h~z* zkW@;s@02br%qhK8N|z&OIs8DM7no}KK6pk(hALQ2MAW?%6;Rey-GC_IKzj>qpG!J^)wdGBw%ZPgkG&F@5ilM_EU^er(`DO*ZtsG*Cp{$-aGP zN$P7w%QaHBoOOT|2JF+m62)iX6bit6xRBDhEHJ%+#`l!QgNRCd>9Yz>BmO%&LCz?| zZxG@~z~0-Wa-TwOosIO9Q=^H^*v~0v4x;sfkF-wv+xL@2=H^IS)taAwEo{8-;NNjD z)pkB*B@5SGLbZ*)FA0)A`^qP%Tr-Xw`+3xZ^sM@IP$Dxi_ z2?D|G3Q)PWetW| z!El_K!$sIddrv^EvY)<12d#IP2_i>`7jnUJg3m=I3}Jiuqk!WaHQoqmE1y6_ zNbfzkdT+Y1RS95fL6iczs@;aP|NBx^UROO&iX|A1^Q^vuDAy%lA?6Z6SwPx}%1pBB z^m2$Q_ui2Id>jvqv$o zi$Iz7cX!%{MJm>0;sqOV1Ska=YD@>@h4VdCqyzuhRgpxE zJ;%s6cxmvmZTijYQu%n9y-YdE}Jh1j2%K`6~Ih_GL|8Nz6I!J@#FzIn6B6SbYR3+<%*}ImX~=YY0yI z?@*r@WW=NbyN86Dv1w8c8SV{RRz0n^{S@e)t`%l1W27N{pGv2bh{5(oY<|`0(ro`{ z?;mA^8Vmm>aI!KR1Y0rRg7i_1i}CpzX{6rf zM7_B|d4Vv7?$+bJ_UnA%Ik%9)6(T3@GZxl|-``ccBh7l$j0tLj=J(Nj*y@!-C$1=4 zQ*Cw_z+E5`fgB%gD_W+xGPqTzs@qMM&lBIA1&nF?^M@IP6W>*C6ux|j3H)UNmK)ST zm%xi{LW}ulqH0X|{Z#qtJGcd*U3G1-`>JaG*sHTmaOL%Zi5 zOpeSe-!T2xlsIu+uLgKZ*t;&24E`K`XsEY-xVK)7m$1eT$1sa<)Le8>e83DXUyJKF zEj)*k)okFZ0a^o8&U#}plQC#-wl7G5!+l}^KErRmtjI+uST|Pfk4)rr9G)WbX`;%7 zzJQF}Z9xO=!^u9}+{W^>vojv$xGMk4*GC3%;3tWKR2^HiUD_0$xM+)N z&s*W--y{Tkdil0Y=?MFx5Aks`@d;^M6r*mp}Pqw4z)TDJ?@yubb-f^9#1%781X`2i(Vp5DQk_!e!a1Jh#22Mw+O$O3qehNFl)3vcEy{qpTvs59e0ltLhgH^abCU8omSkxA9)9YjV*~Mw3Wn^4P#um|TMqP}`?&SEr&T;Sm znj>-*<=^l>r!FV;$p1Apdty0qG(wrI3+;(uP95lozey}qeD3{1G%JLCAC8Pt$_ehE z5cM9rQXx4ySVmnJ96_b@tyDF%5k&eLWSL_6j+`&PLh?OrQZuDM&MW%b5M<@gYuO93 zF>$)cgxoH)m6_!C7ckAgvqSacqawHVDnJXp1l0X3W~|kkGvtD9$(~DKJ$E$=XiKpqZ6c^O^@kumpKoP zdkXZ2tAzhwIaCNoaO6+oJ4y!c4hW8zo?-K7Ie^XU8L@!{t{;}1`@TU;IUOu{UQ~Iw zUdn3S^o}b()#ag!Xj;Q@+cq_FUjDz-U+C2ToBxOU*U&Lif7$<1zw3Vl_o`++ZMKj4 zTxNcKyl5@~Ot{Dyye#(fBWyFZ&Fisd3a4NeJqJcd5=7UA+B@3Hngk8l~0Fd)xjF;t;2*%k?C)q#BlWr#zc8ls#6MA(YU zr&@oNTD1!#O8kL2inZ9HdWntPYKyAVk!r&ItvU(3Ru&Ul0JkhTbkrDoMpE-9%bG#4 zC1Qk>mYdqWLh!i3^M}UZlmZ`*({QYb>rzfB34ayefB_ZI7*lyvW#S81&byT&DYApO zbt~}S?ZDqczgXE=+m&MEZzxW(aX*Rs2?7>-x+vDHUb`wzuN@i2i^W zxmAc}&T1fS!6jCFnBD&%pPmX4YSjL&FM1X=spygE>LUL?J2smBVO}z*q>E>XsMcN-+BA(xBHJT?qkH>7wF1Y8L`#8xczOlW=53be84k~VrS1G zQZ%BR*f8=FuiMf zt&Y`~;@-kL$ojqPj}1)*QSGja9J?qW#U+FJL=Mg4F70{Z`{J-_vp^hTi0p-AS5;nr zqg}R6i4$-=W{&0FAo7kh;-(_%R_&r4cb+5U5NqL|)PWT`GZNOV*TPQf`cil~K8S7;Cnms;Z!Q2a6pWU*1c?52~F1H7Q6j}=OI%GVl0mi78b z?7mZWx4F3X6FYuv-3K?OeoLYF(dpCcv!<;s|A7!?1c3?}MM8+l!X@Xy-zzvDh`>9U z7?;%6F-{o}Pf7Hr5^Y&3I_dutK_sprvAv>2%so10w#59sMNCY`%#)aTI%d9t;^lhv zh&?1#(+Q`@pj9#pqYe_3=?IJIZ=q5~C6b+dic&%i$|4YDkNi}C7lD1PDr=d2f`r7D z$R{F=>>t9qtcvGPK--|K#;8nGkNsm4c#E8f^^>VytC?O}RmXnpjF3}Zkzb&lKlWT} z#)N)Ee{dQ`U5d>u9RXrqeFWFytY{+VmF+8AW4=6}RR6!qb;u{xg++~$*ORdYl%+Nl z6dS$dEr>Gj@frsWPYNb?IU_Q25im_C5SVU|6mh@jun#RfkVzbfXBwl4uDb*WiT0vDd zrH+=AiYW_N%Bij#d{^DeN>N~`N?I>S)k*(*b zYGXf)8+C>#{gM zzcteNT20L6OaV*A&1CF4t4~ukRR7S(o>BaA2*a8wEP_VFM+q5`t{#JzREUq91&GE+ zY1j(l4jW-ft4S?v&0aulve-%bKdRE*DAQ{X>7Ia^bz%C_OO!>3dWAGZ z6$lElWmAbRQFQ7uy<Vb%?)xx1Pxd60EceC;r+vMcz}alfjEQHQYE^JcW4)< zAXZuwwjyv&@fn>#rCYS}pnng5Hn!2=w$^xprzZV*)ToL_OcM0KP$-5H58=mYf6XzX z<86t;u;?K0=cA@KX~6PxrMLE|68{;CDa^|>kLy{Qn*t2bPGpaxhYRY5ECs4UxenydDOUOBEZx>YT?8Dn_H zihQUJLZBwxczk*W$yX%9OOqo5vF0O<0r>n~?lnWN1e~&>ub^i_Qe_6_*bqwPd@7X% zrvN3SA?gwFza#qE|Btt~fsd-V{{OQifvDgO$|63mb+t)F4K3JEL3hapHySW1YOL5s zp)^&hR5wa}z=TbZ?RAj~T5YwZm9|=~TD2{ptqC9jA0waw+KLa=y95+`K*Y-a-k+Jf z*#vF>-|zqbd;Rl*y>}k&nVBzUr7 z(?&9MDMZ>H{qdR`%$aN_s@1xvrjr{0t5$#ig>BDDSOJ!m6N zQG~X@y}M0cAO5?;zs%uBgHUF}3%B}D6Ov#rDbU@A62>t1?xa+ z%tKm4qEMKxo?`T8Z@gxCUYZ{dnVTSw`QH7Db)w}Co3Ehzb$^}ZeK;Ehkpw_HuX%4N ztPP?*6H?CKPRrIhwN~CMQ8i?PO^32KwRUL;u-RbcVR9S?N8p;s8I+r zzYur8%4Y*0wO(!Dm@ImUI!4HC{Gb9w5?beS&y<+(9ry`p)VM zoYtcWSUmwREF0L5J4CYA|8k{}pOAW}>vUh=pxs}iZ>VIiZ&iDHmk2ddoQFAp-? z(WkS%(zNsn!c1=P;^{+d#ujAkjqG~{P9lG}K2dM&Vrxh)t$g~*%h5=w=|Rs$5sHp?%RAUP`pZDW+_jv>r5 zsd$Yf9_%B^lfjHGT{Nkwe4>@~i<8H$dvW zH=Z|qN|h8wHW3uTH9~Ot{Xa`1PVCDc5nF^0lW3fa%qHx*Qq*arCJ43c-k)F2i56j7c@nx_6WTuP6EgOCd-Zo!sj4mlLFI&79 z(O5%L-ah}*Q>XtqH^`_t*D~Q&vN4P7KFevli5D&Uj0lho7C@Rg#$y(Jd#fn=EczCh zMc)Ed=SvoSMrctju6hId{HuX9V*9lFvW1BuG52vX%4#lTXE1H_bTY!Me`e++wCHz? zm*bdZrUKe!nt_6Fn?*WB7I<3#oKpc$8_RIG?*_@2b{p&NC8#Iu7ALs=V2q)hk9gRv zwfDYm_cqWvKYG2q7ren0IbQsF1P1#Nhz;@oej&G)ROa^2Tn+CLmtHrd2U&Qn1GWD{ zolfQe^14QGBRk?ELd?jtNR6WUr97>k)<}6oa$nwc6638#wgBTYh zyVMsPyUy2}S15C5NZ=P3DBA5Dr}Ye2pxyA6!nMP@g)|NWFgLZm26!E~=Zmw5&4kEm z>!+H~TX}s#FJ;0nA-T-Q7;y{UM(+j6bPZ*|J?KQkMdEs3@mBvVsdz0Ysf)9128k0uVz@c$V{@5#5a%&m#i)!?XM8&wwK$bnpknyIUsGWe zZ|^+wG1y5C#2tWu^0Eu&@?tg-O)-I@rY5th70o=j8M8?H0UOHI2k*2cqwR+wE+3aJ z`m=Bzza#Dr>8Bd}Cg#q*OEJmil^GdbM_b+#MMYaUI2+cv{Qj4K$%hXXaDM5U*}^Ny=~~ zw)GX9FeDx2sK`EM7r?1njb{>9n-qNT$qwfs_KTm2F4GPHEjr=k>JlgU3j!xUsyt3o zyMSyyv<-93WWmQfI^HM=Y>x-l#0w1{tOh;&pqRzYebD zzT0=FX-}427IXMV+Zy9QPsaHFap(3X3RZ67S=$-B83#(Flnr9&q)**yyH#S00E5o$A!b+T@9y{OB+m zb>%bFk) z+L!7)wFBudiVOP4PuyWgF){bP3LZ6*o3=F_!O}^weWvI-+qgTL)S41%t76C;^ zFONB=b&*|NuTx+P&55@dhI%tONG;i1#@D09@Gbk(S!&Q~Y)^GTm%^q9gdL)nn9M!7 z<|;_8)(8G!a~aEWWt?v_u6@UXTVygyp<^dc9TJ=qp*|lv7Zkr$DTR){x|eJpI`zdb z5rfggvQcImy5TECO9*bHo9bap^y4f1r|DYaLmJ}Q;K}`^ z#~ZtnM~|))T|9-8v3Dq|S#f1wiJ{4xY2@IC(7kHU^Z`?1b?PNVpg7Ye zo`$liPdHF595(}_`&6^;%Xo2=OXij@WXg@qi}{I}KpiE_?Z92~u6|8J z&2e(^FlW`x;TcM?3y>>T`+%l7S8e3Ls8%-esB_iEA{&_19u0J+x-iB~zFC+U6`#`O z-fZcu@QL;6pmbee^wT#ShJ_vMB<4qAp|@}R4niwUmht`Rj5~zDG1KP9D6yG$;D}aJ zdrV7d``LwBb{t+zQmZKrJi?m{pS58x?+Y4Y`jcAqRvCZZYziVp zIYlY*204Ux@93W!qcJ1XZTw_|zBW4W0x`~;4I~N@?}4@qjrFjXY;aYfD5o{t4n$3f znw>PHp{j+xWw#&Dm@+9E9^NVFiSa6ikU-oA&hU1!3lq`uj&dA76z>79P9WI<(@aXX zOCaawpeUfx=NDG|F&`LSs}VF)nOhBg=SV->6=T7tDUziTiaf@WFfLS2aDOMH7@EJD z`0Df(d(xK|RlD;-CK~LYO7wp&-j>UTIOUqwHDDvelxft`e*2>4z;*dkG*DG*rd&Dt z#Gx!bRQiCrfV2BkVYu9E#|8@utVjC6|op~lBCu>OAKo-2yb-W2*xm_JxgEg=w;SYERrkaht zTJ#C}RyV`xQ{g$5K79|#LS8IAJ=iaOZU8=~8bwFX5kZlh%fLxROWIyndUCO`(aUexkGX=dnLXTv9~oj`4%D!OIz@k?PRmDPfj1%3e$n)# zu!vKnoB0l;;*($k@zHCje* zqFPk`M9Jb3YG{`Ai2>9^Kl#$%SRA_c&l6x@27UN=wPjTkRDOmcvyHBpeYk}FT zv(j#G9t<;cGl`tPSd+MJLTa_tK#e|dkIL#~bmN36QCm?d#B1CdZYb$?a{PEX^<18~ zQP}C&OdSJ(#FpgpshS9azXQIUNvg%$_|~3iT~@}cNnb_vGcPk%=P&y@aoOPKS&X8o zHucv2LSDbW>>IgnHj$p?P*V4XtP5it!PVrS% zXDfUIz%tj-Q@QUkJ2m~X_xDcz`+kWn-G5&;Bv+qr2}GqpFrAkz8<^p+tfuo$1Npkr zxO>hpXK-OWJ+M^%XwkymA`8{PRl{t&BKVWcMI?&fkoQSJ&eRgY z{IkYedTF;+TifFM?l<}EZ}eHVjAkR)a7_be=mnmd23yypIby9Ar>J94fKCdZ5?wOP zM8;AtDCZdO&)8VXmrgs;&XX@Ve_d!M{Fqz(!VEmbOy@v<$7Z>cqUjJ7IyG{Lu`AjH zwE+Cp?!mbT>uVF(wbV?K0I!p>uQ*TEh9?5G38>3Th*t5nHolJdixpqw$4|_@V)E#t zvq_AQsQg^;$MHhW6UD-3$KCPZxik50q4ZZr#RI#X*;0t%n;Bd?b5`mdCDiCGSB>f( zFm3+dgj>!dLJnKJ?@ryD7A7dW0eN|;Gq^wC;;He&EV|649Gp*Mf`ow{B2ZtB?^NS4besHYzrO#2ODYgZ1_Y4N_^7s$h&)m9lV#n?y;~l$> zF7JXqb;kF|K-Y`AQpFRebC}0+rd07*0^Y8>GzzMQ0rQ{7m=W*~9%cmGaF9j-#g>8; zVXV{JWG=MaU8A#YJB*IbctI*a$HBSvU2<=AMRBo61_MiHkJZLG<-S%fc;SZzuik#HhmJr`LF@Hw1mvr+A1! z$$a!D;O*Nq!<^~IHP5v>*Yq*kTF2N0zbS_&A8o1{fin7?rwV!IJ z*nSiX0ZIMZJKbV$l%MGzq&k0T4a@DF_7rdM&EfHdo!T-t7QVsT&(Ha&pYu!ukE(-j z^rbsYrgyM6Rhjb)m^kmQB?;HxI>0tY}UoqHT%)?+iHbmIAn>F?1w%8s@pK0od zFgWbI5lvoSjaqekZsyQtNGR{br-)RxW9y z`qdE^lCZaIHa}FHev-?VdMRikM2V?Z5K+go%p2l2`w3dg_|u4sE@=++!+dK8AE-}Y z+*QM*JksD)i4>TX_D{OJ2&mU+E$=er8Q69-;}Fl3@Q9DIZ>xl=Q2NZG*kzmViUziV z$az^Ikl`!7Uz7T$_FlGWYHubi#Z$dbo#4qm^B55pUtBq|xhNj!jJc;qlkWx+rCjUB z!H?`T`9S4TH-ysDN@Va_FAJzTZ@Db4)oC?Upys$)W!34MnB(f=9oeE}=hSJ*St0Jf zh_U^cslSL{N@h66`MoO z6xw@nJN0F{?yJf6veBkQ?7HP#TT){W3fL$#p;8ZkLLgKol)(Fe>5$z4-sogbfaPKd?u-MSlS z-XZ`~sp%m$tJhxCZ5wB*Fv+h%EziuLJU-RFLeoC|W&*kP0epzPK=#IidCw-MLK{u@ z0Q`Jf>@@+r``09lym1J>BW9&YnX8lwm2wktqnx%MQ4aBo6kkPrX1XHOsfAT#Zu3g? zH#(8fkSZMUsxjLk^P$Q-RGCjDvoA3Hfxa8DCbNk#yoA_n_i8_3H@oD$79`w{c7CrD zf-PIiM9ZmX-5Lg=?CWXn3~*$$uru|-ro`NP>3B*$i;}S$e^2wRW&5j5Lhx)7FdxYV z|GG_Summ$seobl()i05M8E(-@ZV+I%zNCingmCagxS0s=X|(7QAV!G`4;^l}-h(_0 z*PG~QL%lZ4x{*QS{mRc;O4e4JHJQtLG+DJZvIv;SS(=$N2DOt_?_G_tsobq_5x5c0 zRItr>SGbjTCTnpl{sOgV)WwK&CxZi5@!ec4G!6>mj3{xCnkg_x7NQZtPY{lGywT4) z>U=!B*u@l4RH74m_Han-={*2}T0|P5gu{>{wrQfC8OP8hE<=?WIsF_RV?P8H!*7bGy3^HD;~j6ovNrAP*Do>99alsHhntB$iZ-c+!Z3AV5sl;T*sv0B zFh+#Ap8B3(vAVtp{XNJ#?J#p*VHun zV|sE|zrnqb%yuZxw&TU@ZTcd zyS#}CSP_@iPNB!+>F?r{hOUmMM<)Gt?}r+1p!bA6!rjdKvVeMsfEnN7sI;vQH@12z z7~vPwGDE-3Su-Cl!(5wD_i*m3`>*rqnr!fvjB0BWzU=dB$eUY_fyz+&{3)F3y5-lP zN8GBW5X!UcN)(w%5uc-W7}x8drN^U9kN=1nh%PnmjMC2W$OhLlNv}xm&L)OMU1_C9 zQwwFV4V1mHB`)3I@%48_LAras>Fe%+m>jO#IsWvb#B;WNt~o`P^oo+Z4!dS4q~3i9 zEG2JW$%flm05B4_c-BkCE(PSKR%Kt(1>^{I5lm33O04rHS%Or~(g6$bO}U?w_2)-*rXq83UI!&?MIXFVlrOuUuCCDUS8eDAoILlgM`cbpze&N^Alq zrex|#Cj4$&n=s5zP1f z{4RYB40*TL!8O1koVPXHOpMklGo)RVwn0U)%5Vmk61>Y8L_mCI-ggGqD{^tTnLN(m zh7bW17ADYGLEy3QA`_SqA%Kd}1nTMt+!by&f%*mli^JMM0>BIc4}>?Hz`d#o;m5+; zP59yYHryK4_J}jMd65m@941)qP~1zGbsjlk9AajsCMTI`dxTqqy5vLI5q=>29L3 zfl=(mICf75cEv{j*5>;yEbi9SzrcK^& zf2>)=K(+aB9>g(@fx|r4q;M>+w(xKI!X`^?@gt?AW<}tzRK38xtx_$)r@=JU4ZMid zk_Cax?_tn6egOh*2`N1t{OLgh3f!XEU~)|6xMs}qRemMckH z9dGpa4kB!-yfbl%hT&*6B80k)eG3`j&_K-|1=h#uy5z2Fowf@=I)jpA6U%)qe3+7S zRmUE~pAEzv-XG2LQ}4HWO4RU9R*RXGDl|WQ|AS^l(M;YcnD|mv4F>&}-iHW<}XgMwudfXMBuE#>d(tN9fO!UTKkBQQmB@=T+6R5PTUex19&Y5N>)Oev;GEr-K&{$&ZhhOiGMurUz|1 zfE8NeOf3Lo2wLBEKFgXho;Cy8AKy|2nX$dmtJz=0npDLGHhQO-7&F>yb6snCBft%J zpT^yp4cI2*%-MJ$_wHHjh{@`uXxvhT&ZBh3&ArbRni^S6+29e$mSQ8Cpt^eGXjThc6q-bg#V+1RvDDTH4WF~`9aQSO4dStxmimIly-FL>*clp!i zMsGRrb(LB=xRp%geUFDd)^SikRAp05r!yExQhRbFdF z6h{+e8^FRv7I(rLN0&z3MW^a&m^Y$JCK2U@6Bt5ixZ*yF+qVscri07K;%yOcW;r-vJ_T%^HPp9xZUsS`FfmAiBl_;$NZsct8 zgw$qGcpoN|pzwYk7KQ7xAAwzY{leoBpEXwktix%&QvCui4A%(7pL&PsNj>7;BiFFY znp$kgAoCE}dgQ&9twMlUN+VAl>Z~xl6_@&-daqu|su?lIBuOI;TYBgXQ7%hd_9T;= z1Ea^6CJwUlcgsqFvQl9)Zw2mn&bjVio1R!Arwpl0Vzk~hs0#l>ek*@Qz|ST%*&UVK zj6NCJv-oTybKwDj1x_5k9~!~65})Q+wFqK(_GQ&n#gbw^I-HNtM!)PPjhKKxO|!We z>5*GO>STw4lEzC<=AtuLh~=e+Y4iR4VRVewHpJa=^~{%cSj(YZh*go#he7$Deq=Be zGMs=B&e|axY^D03s@{%ohFPr^iLVYGaTAOhBL-k8||pRWChB4 zYodh%bZe2NJ@(|vddZgBA02e~{*1xJryHlNHnvv_`skCATN`zhKH`)^xoS<^wfm%T z_jFpQbh|}Ir3XF2ckFg*f^T0|Pa{-K{xdE*SOjj_z(xaiVPYVv zZHg%BAceMI48>YASV+f_>my+KH(snaH(qd5BD)^H{~vB*iIdtbwf#zaXBd9>xeb>o z#lJ!ff+UIpU*-Q=`gphu(O=`Hn&SR+SxPt3yrig4^s|RsY&P(}%e!FaXW7gWBhW?E zjLW(@Qh`QOv$4f|35 zBI@5mwY}+clHUTDE?gbYCM&!p*RdVzo*=q_ddj(KVZH7IQ%0K>SdluCyfKqR;E2p+aG)=1 zFYH0>_3q~gi?uoU4^7fKTl@-_7}#&+@M4Ub4RYenEL6MeU(<@)6_=AwWsG@T&Dg_}TQ9RVv+ID;c#9Xo=DO-g(Q0ekViGkCr}C484Lu3%}buL&;>Z|21r zyl9aPKVar-XYjp(kzZ@GB!~C1ByT6$*eb}JKx^%AYLhc~Zl8traPL^IGh-l!X!1!p z_uq-bj73+*+sE{3;&Al1nLp;%ksaQ!D=X|Z z4$>FKM_*ZHCd(WG%^XQB3vwq#*<40hb|?dg>fk>$ct*(p7W8`($Ffgz!zn~eG!dUA zg2`R~CODKJ+uj9wIMocTfL4?7i&S;5R87 z(bQMteCiFrDALFUd3}~_AE;#$#B6qUa_etjK5>7lk%pmI+uB(t$i_LB9(U(y++l)& z)HS$)gMf{l(YTsFdX7H1@t=q`j;SGXj2zFz-NS!HDM%~`IX^@)(xyWQ>`9KG2+1|; z2v#VVlWVHU$5gk@{iT57GGk^uJ_UE*QcjGSAMbd#uzRqP??{R#-*40aKQ`{pF-sgb zR@vZ2p#P>fQXBmY-iM#;&XTKXlh1Da@zUGZxs=2?{b0U+9A$XMzlx-jc8KAYr8>F) zk^nS^%9Re^m@4Fbc&fkm*={ycvrXSMItt{w6)$uD!OLb%?L4`wj!BM7|>Ki(x;zw*N5$3;dXAsIs=Wqs|ftv`7rCAWs_ zac_S~ie)*a2wj-@_1KTI);_l^`RRVw)TY)z#LxC0P++}tyCYXyJEPE*iKBn z62rwb^1jqK(xC6es8iaN=`~X(hfB44Hbf@_xLA~aZZNr$Z?(&WVMXMVP4SNILasvC zz+9x2yPcn>!n}$n(mLAj47L_t-h(G=4QQ<*wAo_@9c5~BEg}uk4HT>ff4p8&esoDl ziDq}uyM!e5jP|g&Ns`WCUt|Yst{8QSkWYFjJ4Sd3DIy#E+w)952Ca5OAW9DoiPD9o z8c3|prpq7VHRQs`MVr#v{|X)iy0vh7pXyFf&tFr4PF4r5H zu=KF>TXu4SKjXxtWu^Mi&i}q}Z1^!#-8zWjwNqu>+6|Ak^Z|2RQ;57ZX|h;acRS(d z6^_~P!=iW0d-1pJwix2z+K6oM6zJBcZeM@mJ$knByrOe0#-obcyqJ1Gql2=+*VS9? zqRbUk;ZAaPZ^`LheE7IJtATt6y;hCE+4p@|gSeLD86vX5f8-(9d7P9EQe=7jRCi}y z#-+ZMZt-uFB(w%(yOHa6no%KJx8fwpsETjIrj&J|)o&Pe1^by4M5W`Vx|J*D^ZpTg zi>cx>`384G@9zBxz{BDe*kQU0G7iP)XaYwP~9n<}Nm$dR0?2 zRN1G6B{A@eK~z*fD4>oW-pCj@;%2s zo0^J9hXrNv=onq~K;3(snZwOSJ5=h{)tN(L-buJwf>p}7P>*XiOK)~QV3>?OK;=A> zdO7<_`iuZe-&eR_ibIFl;Kh5D^I{d9DGn)rmgc-PzQ~CK*CQAg%aqJ8!V}~fkY*LF zp(@@vm5hqc;yXyy9{}(Y2LIlx$K&V~`bjn_=qzr`K|2`&O%axU3p5vb{j4d~Lo#Rd{{4fiKM`tWaigtb{KI@g->(dMJ(~q|RTT2scwhUD-NYH8lXW zxLC|Yr**^Y{C{4#6X8ZC%Zp#s&qn>MRxB4Xqe=3K#k;>Ekj%NhNlJ5{Kc^}v zL#UjxWU1nbsQRzSC>Q9w*yBG(yRYDar5W1{0P1@2bACO^=#+h=yjz_Mw>kCf7QDX= z{Yf_(ljC=N-oL<^bBiVHE^zpr_557$lHP)^E0J}kGvotP7ahE?9ouR;);Z8>hd*?N zeng!ttMC}`6wl&2fkKfxKXeXguXcta@?88+{=dwB&@Z&vzNTT$g|9|Y zbbiMjBU;@{oCN~Jrw6LZW%x+NdetYI(hP8Ro-5uuT9<%7Q{KEJD zmLByDc`!{MUW?tTchKp`BI)46s7rP9XcaLmU>bXomUaGxE<1-8y7}mrk z0WoSOxey!R3!YT^s7J<_X_C`tneVd{@#QPY|DzB&7Wx)D247`4B{Ua6J+GDPMlUQA zQML#J1!2mJrwWsQpA7#E9K1HU{HwWlZudGS#r;}yW{?EiEKHqKw5sZmf>l)|D3j)h zVaMiH?d#qi<8AIa1KoLXy_~VXJEvAJRi*BnNxbms`Cs#+_Tj?@;`s1Dcg|FkZHPOs zQBi^Rxn~63+o$u60c_XYbB4~XI>4P%XEGh+&Z##q!phV&OV8FJ%b84WDK=GcqA<4V ziDVHcPuW^(Q}k(TR5UO9+j@D&QYj|!2IhNVEjQmA`Ds#ks$DU$yA4$7kjf-wHs~$H zez&;?!W6AJ*ovUjbLLTg=0=m51ycieNKn%BRB{oW=~vlE1Xj-9Ykj&JURIn1m~ z=_yb;Sttcn-ce>_uz1{O{n=s`z4^wQ!H{|FBHKZ{Y7ecQcQ+||C67exgGnIXsKJt= zUIOb)CQ&c}nc-+(aWhZMn+`!jf7_4pcmhT#hlYT=Km(_W+UYO(mMWJ`@N z@@kj~*jzvuw=5qYfepws7Tse-9&8-ceP+j?qGh63F_|#72ykO6v&rej2G1Zk%JF`!+ zIc^UB#=@8szEU~HR#(30%sx2x`8_sqa`-AGR;ZLyVwLFSo!K9QIaAHWIRFVIk5tA} zW0l?T-P+T6QVli}7aT7kX zI<+arPD{MHe4YOqtH$|-zKqzs>YNEA%au}3TCLI|WK%Y% z)rr;RPn*aSas?b;U5+`VA>k|1PlD-@;Z??n2AKJJ2#Q!{eV*3Ln>}PH+Xe#^!-t=A<$yyH%tnUQC^f2 zZa5m(zxgvgGsV1zi^Nu>e`faQX7+vlHn_m(2SQ8?xKvZRxAi=kQ@I8jzIKVypEs&Z z+5t03DGUs*>6D&qulYvg7f&wL=alsfhkI41TYL=X7p)K>g}h{l4^QbWLl~Lii;{s6 z82+EdgDc=@Ib)66;Zl+bSlG_+=5eGQLl5+yJe7@TB*gug^c3Y`& z4OT+`reE#WW66h2DeFgCb|2Y#S~kRHX*xHa+Ed+{O$_cn!;HUZ^9?lUSeoFUqIAh< zRp5zoHRigDQ6mSu+R^V}7*Atf%29LrECk<Ow}e1_U%)OUK9_B(kYLHBT$U)q7) zr}^uFFO+v^zPzJV-hN*!&!7S^h5@X09o)O5F@8yB_Oz?|%iHxR8U1#da_-@L?_TZl z%hArH%GvmSFZ`{yepH$!3VEhEt)jOALl2-&^neKK)v7**9ulUQF%$zW#G!@tKKlG( zN>z;C&sqcZrhk+-jYdA!4W!xNSN|@Z5ijpOu3@*)>pzPl5PJ#7hNsQ9`2AYGKOd*! zxh;*klqekkp3}d6+h5p=K;PWfhd?i)lK!ZHK>uMAAv})h^dZp0d*w@w!&b-Abn@DG z0jJvF(edQ9b-cFn+9}KD9MsH}#K<1j!ZY;B@E=b}BeKyamD3;DXMZ0|_RV!ExjG|e zBzxb;C&xP@^?a9uNw7h|j7L$74sAX#toL*evXDhm=vCzImP0gZ^2hy}^}P0(ze z*adk6F@Ml~0JoEL=7ezW+!E8KnYS}%9HWDy$~RP%81wW;e*dE@{-m2Po!IuwFX$Ar zIl|USelE~_?OOxUBZvyGct1Q1+gnV6eygYZGcE1R8ucmfQEZbmU(GS10K&xgv}r&q z7nn@$>F8FrFa?sbAC`xvav01}udwPhGRo)q=pK2;`)s@^k^W1p_MvzGAzw$ne~wmo zBacR$`u#L3pNQRHm^kQFr7Sz%Si>ISE@%ar$=w0&DX;>|$!86jb&$`ut@)!bro=cA z{-GNkHaa<%Pn=)1<7c}2P0M$4_E8OSceYxVTsogTMRB*028wE(R-Kq|-GxNs8Wdys zw)aJzc4#LbS1tNsk6h-=yTXudMhE_MKFeu6g0Y^X3x(eyZ`{2-kHOsrgHG$YCc&Rr z2Zd>8_UsS_`v%G#B)UnJBaO&UL*`j_D^G-zuxlE{+i*9js#8weu~a0wL_(O^-#7P* zx(jYr>e__U8EXwK{dNgXBNH4ZTA&h*qsWW27IMc8#C=s_f7iWB z5J14O!pPYuN{C#r*noA~cBu7tFfnL*BZOi@&~3whrUN-q_h} zM4n#QvGnD%eqRY_Pm(JetVAs12|J%*9PbyOgy!AHO&jqo-b6@q6kYMu1djR7%N4{{ zH#1XRB=cjbN9Th#uIVeGmP-flV{itRD~|msjB<_PZOz0Z-^VaxPp!-pnK(Anp~o{a z(Bs#R6FoYuXB(oh+%Y|N5WnWHroF?gTc1v&N@U!A^_@>qu#RolBQIo2F^UGb zc%NcfE?K>67m{-gSEX`m(R|8NmQKDr_JdEQn#FZl@?ljYUA$N^q;4SRqI}NcXDu+s z>DU+bN|w!JY0qV`idf_1+{;nZKWV=&JoofK<|-NpAHowx?G*H!{l=-cA00u?DQiSk znH{K?@XzHIf9k=NrmQ9pp0Y?-p@dxjk^bUd={NUIw{&mLDg8=aYWe!f`@0TdpNCbEcWYOux}f3*V)e7LV!qn9fT5j2v>v)L&}6vnxhy%iKk&mak4# z{sj4zv5n{)=`aQ`#>tG>hNzR7-jn~Q zev;yUsr}VKhmdc?HgB9hA8J02sS5}7v+-L_rbT;9ixkg(JucXAQ&;PnHJ_XTTnd}O zJ8$l4miVx!Wz74Usil&In&90`xeTGo%pE|?;oqtwW$x`=9ECFj=xOc6!4*(F`eiVS z^yE(uIz9(y{^7DY#oi&cI>nlySu;i3+L_q+N9qNrD%(ZJH4V2DoV6Qr>xxjX{)6gV zX~C3bY5>z4{!O`r?cZYe05UVPVdiY`BmWF`rRzo-R76QUyV>yZ5$zVfsgLF4cyt?< z4Lm51z^Cr4m;K5M;{Ne$Lq)#7dRrs)nm<|anAw7}DA=*sD{)wH zf;CMWXoia@R>K>QK4r9kDfWYL5^Q(Kitk>(t{*g^kp?aP|RMe22R9zndz{Z;-8b;i^FVIR?fb$b*e2N z!)dJakm+Je3Vo&7u<@g|QTtvJOitgCYro$K{yZ&>wRhbcroC_LroZ%{8vtnv)Q_0y zK)<~-D4=UNi55@&-kE*ct1FbgqLH5t-p`|Ndw;B$z1r(HNbUWDhH##vn)c!!zgKg; zciD_$waNWTtifc>hV+-YQrm0udv#tj&0&6=zeEq4=b!KPK?mbHbMm%6Q9X2NKFd6} zwNEPJM|1XGneJfT$&K$G`Oy7?ky5w_tY)kvwpCt>p2^1zr6J%XVsZD}63Mb2g~U^B zrk;$TS{YnX#vCi=Jgj(gI3?fM?_QKS+7v4NwC!);6wq}TMu)ftj5(bdsi6BVI%3V6 zhHrr*K0EAScn*0NzW%B23LqzW+HvCB%Opqli>KCMTqOz6UMAWKJfxN=H-kinxIZe5 zyWeup8kp(`tcnJ@s+q@P>G6SV@U!1*$%=oEY~nbLRAcBU-*nyKkjG?D#~wUaDd54H}{qi@oh#=RD%63Ul<{tY_HFP?c6ih6GsiNd{qcI7|;O zXuhj5T0D+b{?g#qJ%jL?#1--6XaH?U4D@E5!B(a_N2$q~!veIomqBB*Ai3vZuQg1w z9jvFW#Lw)W7iL>!nc}_E-_>^L21{WpgxffU<9zB>@AY9!QV*~tdXlM*yjBd?Tc;^e z;JfGb8lAoPqw%C73{X+&Bz2*xj+rJE0}0OJbWDjG2|+GD#4Vr1=lJNV(xz!~_wrC& zp7G^lJ>%Vdx*F)9w)DOp+l}5Prp>e9Q1K#pkj2FD55yY~%vaVZF+UMv-*ohYzAYUa zy{u27$;!e+TBkpZO`W;_G9*DC#9qkcVi6rTh(1Gz2Ft@tC6YZ@w*Fp?0<^$Arw6|q z!LNG`PNGcC9{g_k*Y0fhb9Obh+P7CVBoAKq%*bY!g<#!weS72qd1|?e*kv0Kd~H&Z zNwRKd>PbS<(`h1a_z8%Z=|L~OE*S(5AVg(OB`P%@{MqHhKFZEkJy|^b_`*^qmJnWH zJ{iybkomX{8#m1R-WTFR-dXv$cAKxv8=H@N+QwCQ<@vaEHm=eO=HuS9aS<<&kNd#J z#l3B+yRF|Y8&~IT%*TCh%(`GDVCDpsZP1N4R3cl%K+_L1-l%;^0~(f(#U~zYz|<+J%VZ+* z>BCIAG3(gCRJcsH_ohc(b*RbPplmYbIPh?aNF^761~VPH#c#wlXI9Pd0gd{R%`r?% z30wP9iD4?7uWtae*@snp{t+h2N`+}j@Mna{rvc^zD=s?9;Q4Nw^C?BsnBu#SG&xuM zISn4WfbhMLfe8AGck>Fc4LM-?bOQ~#^=OktLeEXdm@HmzD4T)u{x?k)&EgA3n=HF} zLlM#^pJ1{G=@;`#K~nRo3{w~C7~BYSAK~9Q)@12oSel0Ehw2ueccrD4T-{a?22@!N z6j_qxrss!K58+!msbcY6GF2Iztn_o5UZY-vS~2_gv0g6C+u&r}&tm9>dX0L6%8*4> zpT>C=vef6w^XnCSkej*us=vi6SsHs61R4iDqiZNxjRIu`);(mI*}EX>ILafQEW-2z zBptHM?OhPn4W27QAxk9J+AMeUE{N(5x)M_mvZ%VJ4K!%Hw|7CHanyH-CyPjXvCY!n zyCA9?JdCTK$fD|=#Vd8`>Rpgfs{LNF7!(VY7ubAWt~9c&y4j50*MDMbEp$=E;`e`T zAnxj2sHpLpw8XUgrO>?k~0Vc_pdBW3~7+1PEl_0 z;_3lDmDy$fy*B3$p-(b3_;3Vcm{^lgo6_3<4&^f1K zjkvr_$*!5X-rP@X96w$)WAS4YmBBe>7er}ZW0+@yo zrosh1_TEc<1Vb>hH!?dFB8wThv^_Bf5}QjLlbH7`{`#cxTdB5K%mPwXa9W>MTxSPD zUe=r^Zk0n;^yPwV^jDV(@TCA21d|BDH+2}z$J|??YIVS-r0t01uV{7FPT9JDj%wBD z>u34e#@=dU&r$4OdSWNr*zYNJk(!Vm)W&-@_~AY5cHgufq?#pEN;rYT6EO z#|6e^%!C}l7_D8Y;?slTYpVG;(C0`&Pz_ew^0h$esW8a06cBxd*<}T0$h| zlwFx!TB07=3{HG{i^P$DISKxXF#odm`%#jT@L1lSIL{EuyCitgp+@n3QQYNLhT!Ll zI^`rXlIy6YAz)E_iZki$i364h-wd;e)?R);?dQ!`Zk%-SN1u1Xr+Q~u;PU!ANV zoAg`*XYy-5Bap2tZOb}yPXb70lJJ@z%+Ozt^<#4pS{smJ4Dh5LTMPDBv>ySU4x)N+ z$@%-jZsZwMd9}LW1Th2Vf(|XH?3z#hTQp3ARZ{+FLJIP&4}vpS1^v8B|HclEX$`AR zbAP(AY3hxTFp_jl8OBVO(Pqxjoi_8v>9 zWG&`?+8ow?(nYepmB9w_M1X{>(<*B#`9D`CbX2D(=-O{O2dJRV0{ybT- z)WHjVLu9BGpTCkh-y{YPSKW-%I3{X+I$VxP`+o{a)Rx*kesXNSz0`w}f5@haaXj>-Iq_q@K7 zJ~8)|m>wd7)5gvNRjdt1FbqO7=);(KgW}@qw)CC~#Q4Z~Lz%AzU2~(k{ zZnW#EXlp6o=~&+|fGFLJv^qP~ynDVLV3eytx3x1wL@0KM_=oKB1@dK?mmqt0l2*LF zj>1o}g|oF0{D?5oyA^$;jeeNuBI-!=TZ%5R(OhkjlONm`Gkd!AjoP$48uda%v~ma> z%Fc&zEPCi$X@|^2oSTGJ^r3I*+LKGSGhJ%uZ8#681+N0@oVMYj9PMYHY)QzwszSti zlQJ99x?1t+TedQ6(OyK&mbNz!HV}7jF`3fAcU1Y$^qpvtg*=ArfY_i<(!n=L6-T{k zvjO3+EqX~HH+=w-=c%4kOjNZKd)NQ?N<)5!^^-&G zZHe!jy9r%jo9WyrTY9{Wn0bBB^J@V!xfqu6&p!O-S;Z&r*FLtGCi3skh+!XlLq;bT za&qYo@8JO0OAk6&)foaDACq3CP}pfuPx%FQio8ZdogOq?ncpp<&=<}4%*mJ7yVW*OpWQ(pIcI3aG_G7`8T$TA|0 z(Y&78$YB7UUqV8tY}?OIRzyTBF_i5}b(k5M!=Db7wHpf-uikOv(CWfGOf8msPZXMA zzp+Q&Ne?qAus&o`!lF5V9bWB)A{Ktro#d-S|_ z;9qtdCJLDi^!gL<-Fd;Gv@WL=BO7>%r0?K~$MaNww<;V>6@}fZveW>#YB&l&DFjE# zr5wC$Fq4++ux-VLu0E}GM?JVuzA|3U$MM|+#aLIp6cQn00f5|tIP1w7AeQmYCH%)D zN_=Nkq%?6#EYLq17#L0+BzhtfAZn|Rv zI*O#Ahk+B7BU^N5t|sa>u`eKdP+efKaw&?`9`?7Gc*6OF)$ zWz4Jju{Kt|ynJk*Lbh)hftJMb^KwJAM0Nt zKd5VKI#*H(qj{+%nA31&1(T(3QZIR1Pn1iPL@6vSy7RPXGxm`yYm!_0)wnk)_p$nj&x+7OHlyF_L71kTO{a zoeGet4FbY(39^KFHt-zIGw$67gTX=3*|*9;(GKu6)zTZzhQn3TUJ*AvwRR73ycCJ^)SGbLxBh7tN=VCWl`~FR;WqBL;>NF%6LOB1gGZrEuh3 z&l%a`6CTDj`077tZo-m`84nxbjizZi#l@kYebjpiu@^stBb$<=`Qx8~E2kdVdfsR2|- z6)!8}SQ)QF;+<8Pe})PI?ef@6MAUhR44qZOOfj8RAw4@b_e)jbrs1^GSbDgo64CvT z2~)Pk(la!=j?dFe)IFaK>Y6IH<_A=Ks))bx}@{SJU1UmU%;HrPrPQkT2u3i9B zTizjmjR%p2xGMwiLMpk@Zo@Dhe<~s{hweV25%TX>#um6nf_wNO@aARB00CHb9ntoy zT$B~h`p6MTYJ27KfDKzGu*=&vCS}#h;!Rh@#MBIXCAW| z&tG639|PZOe5e=mxKM%r#5}6qD~t!{FJ&O!jK{d;)N%~`I2|xg$8Z`b054beC6>w< zb|Sv9UL*Z~$~Q2@`*OZPgDSM_>dia$VFdj*-eK1<;->@De|`AI_8z`*&V!b3xTtS6 zNo!~C{{r7g7?Lr3qvlKb#(DpRZycoirE}cG=NBJ>W<~x7ev$J7*Oy=Xs)t|n8PD7Y zPb>cmy`6&Yo$>TPqPGL)|0jCe^*}Fr>sH|Z9laGi(wp9XAbhdYVXfH<<_A{$ddOa!@?H79RlQrN%Ro1lp)Bc?Ld&n$j&t^)J(OE!4P zTx!EU(yIQPcJgXJ*@96?k59q*+2A;vp0w%1zmWbFoBpUxAGlY#zrM=NyV!u07*C?c z2H~k%36=;Ee`hQpgB+rj1hPL%i2+o?S_s&6krou~2aD92HmOm{Mr*&2&zC2#1*JZI zm!UF6sPF~{q_N+zjJ-BIdIS!BH5)vFj!VAvIkCwVC6Z4|jA^b@y@7>z(m$7#q91$s zPcM+PBzw$sCFapN-`7_rw?@Ee_fym%wT|QNw-so4?3-$TyM$H@)kK`kc{&8rTIwHMsn%gvmf|Kdxs8md0dfNxi!*_TYrU{z(W#=Jyz^XvPa<07FZ z`E@il8qF#>?*4oO4|6}X9N%$Dvy`z_(S77;*?{XjZ94pw4U}(Djb*yJ99($6 zg)5Tcx5Ai8N&B*b`@x}$_g1iCpS@>`$guk0ZPAv06%wj)<;^(wA zXuf_!Ur*v|)7C^wEcK2t7Ps?Max3n3IK${KAmZ4}x96x{%`!{nK1825)E^D_F`(_n z&l8&>t;(x`qJfYNUe%M-2cK47+xdRH0YCYkw7Ur`L;u$BdDeBDzzjM>z0!zcIY_A>1 zHBoKz$=K6#*_L+=9e0Y3Q@dNV2?-TD)w}oEBfp{z;5cUh>;04KFhO2}@Ks}6I%8z_ zC-{(NsQUn`V*=8bODu-}HgYg{I;)5o=(cq4-lXz%<(;1}WC{X_1EM$;5K{T9pyeGJ zv4>%lYd|)*FY|`hjFV7m(xNEk8WteouueTFIXT4&g)_#iu-~GoCJ)fQe2s1Bf$K1K zRvER#s+#0`{mjms(Q_~%sxsKR9T9a~jgK+7a8D%#wdHw!xN@)Ew181%=W`a`3~6b1 z>SP~E&El+_>&?8Zw@FmCQr{~kntK1{*cf!Kali9PDETM5{c+G9ZP{$c zf!AvsnEqnizn>fTar&RJaI}H&5)fh(Q|na$#t7Fw2RMpsu~cW~V4ha*xmu-N|NfS2 z<~bABtU7{e)`6||lAyMB)Hm%Jrd2+%^q;erd=ZD(-usX3&Km%`@dor9v&8GA7EXN2 zY;bjCgKrQ=IA|t=$pnn3VGmGAvN%umcx)gVC9PpjCWFxk+xc~Gd+wh7KAB>~-TO3B z&}6X*dI^=0Fxq;PqNt5b7-re&OZPDS;RaPr=X?^4W|xj`8Lk6%lE{WjO_$otyh$!{ zjKMScy@CUb!;!eWk>y6ij;^gIzSw(Vi#BcE@V=_k)~Pmq(6$qw`7$WK3P3tSse1Z* zjiNJKA5JZ++8e#YN8l^)gbn|R_czVsZ%;Q@NWnX=|R~i{EaT} zrA0Y)eByYEckhuXPJ(0@t35Z0`U;hev-fJmmL7hF-RMs5_wOOp^-6*sfxeDHyvf_P zWV?IakJ`8Y(M9DDER56t*MG79?<6kY{{;5x|2Zn>G44>d{ZEGf(*Hhxz0>r&dqzYZ zw0|}@3W`OG5&>Jj9@E$7Du0D9Ou&jGaDVLY?MDTDKeGPwV6z{_-QW;&ktyQP(*A(V z1{0PpHpJcJ!zv>^cRi$&4c^>h8rQBZL+gh0Wlvd`hRf^Kw*N>>XtwO*AO$j~uDGx#ta&F%W(sXDeh3O-BF+ zIg1E)Jk-;~ee>fhb!^2^hGoV)B{)_2sot~L##1HLLx2AKuFV+BFAPj~>}@yV<&s<0 zCzh(ctFo_jqq8^mOFEC@{zTtLoxhYe@9uZaBwiwcAFTBdOrxFl4D4m?Qv+SZ*Yyi@ z#oe>e7}b@GT{obhU=~+(oHdMK>DcuIu|mc`rzRB{mNRLPSrPPX)Sn7*cInsZ@qAfFg8!0@bp)vsV)%#w25F1af7m zb_$E{HvG?AKZE|!Ue7GH-lycsbxReT_@r-9YM*;h60m&eJ~Ek@%q{(U_G$cj z+W2dF#ruLDXM_OBnqp>2L8AZ8ana_cB08{O*d>i{?^eT?sKG?(c43 zF?Zj;x%g!nsL)l4cql!825hxyfP2ME_H~ZbO$;+25`EcMr*G*SQ-uh^G~>8+3QoC=LtBN<@~G6K}(+}6R)MuoOF zMy8er*67Og#Qr;@@HPeiQ?re(vt@V(scnw0U_;->AoTl-6s1D zTv?!f{H3deS*(;@yyK5@+y3H&dzZh{4y+m4PPiv|FGt$BEWi zr{cu_G4sA=);GXYg3AV2t}zOQ1sx3y{@Q?RYVstEbw$J;EhWU3_)Dl z*;*Y9;AZmj4()95atUX?Il6Yqa>;ZJP~2*;?vx{pXM;BxTs1|I_ybPcLhzICO7@>I zVa?n~r26@RnRH_M79ld1$J@Ry8GZ+^wJ}EVw!?c`u@buN_)fi;S;AIvj@~$&n7OxC zxDS6xZe{Q5F|)rOHy0@y3&Lfq4dz!(NImO4_qv2M$!3sE#zI=c;=1Ox-Us=&YIwEkPS? z>MyaH))S2^UEN@cz0{|)F5HX7Qunlz>HjcxF7QznSN~5i3qgrbs6_ErqXrEYG_j&Y zM0d#&HX1M@V!VQ)5#L%x-Dtcg-Hoz+Tt%x^tG3#{)n071UI3{|!Y!ax5xk*R!Rxce zyOxVu_y7IPJkRb1Y~Md0%|0`8=62@HnKNh3oUxX0JsU*UWnVnP^3Y`@#@}e!R-!Sg z+(H8KyHB4NQ;d-nNTg{jV?Dc=hK_Bjqsm(flCu>%lgW&q`h|zRif17}rq-|NG!5+9 zs5Y_C&7?kXBJ+W4#pjpU#5+hdn^f;D4B356gX&Bz;ZdPYOUT08$l5U{R+glC66-%r ztl}!X6YEjnt;DKI!ITs^6N#w0rejry$y02?iS>&UtHPacQ%I#ECWW&V?KCb{x57y- zuy{js!*`QaRnf537PG_+>O3}FR7vZ)K{_R98EfyiNT6JJvO_6O@@A!@exyv$SY?LW z8WCxn?AgjpO^H*pf%U-UQTME>Q!~>IF=|nv1o!yi20O=_0@isydJ~FDm;H&s*}C@3 zQJ4$(a<*H<|U61F=Y|D9ZfQ6e?Gp*%$p+6T3bDhdzAdiJ5|W-B_lwP9w2w)wj%X zZ-1Db$6TH%UU;fbj9ZX|Wbtqozo&Y|zY+&KpD6xvlFuZT>-6-YESo*q3wjZ&&0r3;eb~Wtp;nj@II|t9uCI7;# zN|#;Ak2T|*e3M$(P@b6#?lm488^QzPPa3Igi+2!GWZy$p&Y3{`?-NtP1GHrW`^OtI z{`t$~DwH zJ4elD8EW=^w=T;gf5R~NT34`pX>Z>e2FxZ2jP zGmlDr@^0V7+T(`lbJwZl`2*5rVzInvl;9^YvA9TEe`tYvM?9{g<0Jinyq41vZa$AR zq|u+F`~1-d9FHoatNSv{8^jB|@3_KllpB4$KAh3oefMWb^yc?{y&sDH53Jq~eq#0g z4dGqQn4$OU3-o?bW?4?(|4)_BObJNx4Phs_KZ()QH<`W6RD?f6BgbLM4vidu+c75d zWGL*8{&GANwi4A=_)Fib14xVt= z19${i9juGgkXgG)Ypt~Lo3i~1+sEW_y7Vv_`KFPt5BK%H{v?0D-?z3itDk+}&2m&4 z@*{Wqs9o&L;>Nk(**^h)FWIGTpu2;gib$lV63uawx(r?Xf0qBtZidg@(F*O9A2Q|J zAm_?9d57;QKbC)11(EC4CC>acocz3bo;i}Eeya})n-|RJPc*eOc=kr~<$PZCk8l^tBHQi|K_GbXbNR2e!bCFIYW#6ycJy#19_M9MtCk6 zp=)TQGDtdkuqhT_>=ARn7)6>Kb40?XJ-&Xl(=?j-^iy2 zO>vT3tIqa4=9ee%TyY=g!81dFnkNJm6!&aCJzty$-|3rg>4Ozq+{NNo9n6kcHM`(^ zIX|BahJzf!F#ykN2?iSmu@`*`xg z=P!m{g5qtjX3gsWkhjyOam1V`K35*4@u`4tve7`l|2c2Jc|9`;G&%x)6Rh+l=Ao0?Xy|G!ZM^c-!6~Bcy z#fra-u;R1atl?D1$}>hx)Z!wQ<{4j`=e%ad^M3p>zT*r66tk3FJaP7S()atG5IN_ib0z6=C4H{HoZ4& zrgT1NW@X0}I}UKJdk9A4EI0^{eW+%)Z2hbsI#Dc2)ng<6!0D{aOZcovNbMlg}WZvDyxV!tv%j$=&);7 zCEornv1Gf}6gE)K{Ns0Y9$cdDgVEIhe1x;0+j+3Q6l`+CnBv9V`GsG?KZ7UK4$);a z>8cQ3Ui=?vq|j=%ofu0WQ|c|F7k+2C+pz*cBc)9Mg2;Ak0@y(?G_iC{x)SyEmz2V$ zB3*XQ?-`ilad%`qr zq-mOAZZz#1HeA~_%{Hs+Wf7|Th~{tYnlAKAj8u_x%MydZY{fZein1EYeUMn<>hdBd zc^R49`eErIMc(Ppib5JV!|{3PWy1lOqf!$+@W`2_U{3f(Z2l_yWF;Xs8x}T75%zt= zXm~p_#kH;#vrXoL^LB=)daX-bKSSy>Mr>GYy9oM)=+Mf5($d4KalO+n-W2fUnscpU zMyhQeEZ{I=V8g1j74N|S8JDhaXi_Y(yoO`bJ)Z)+C?iW1`233c9S3A4<>g0QcSnu1 z77RfkXS=y-i%qrhhs-#?@jFKCE%vFIiHv4`KNU3FELOiXt%%=ma`Y(2UzB4fas>Pl z4(ivK>3jiw1_W`G0HdopH~%o-K5pNiL3-vD6BV|^Hb{^stH^GmO)YyUimPDR%wK}2 zy%cqbqJBkG0khElvETl$^CL+@oX@kI24WJXhUv59zHx&W-uM+yNjga}2V}IH1ogV% zgH7p2&7-S&IVxuS(waMrb>GBiL>6`kT>F!C=CRoKti6Q*ydyvTj_sB?Ghd@!6;o>+ z43Ybb&Vpo>l%;c{Rr`6baJfj1Y!^QRIo5sC_UAmlk@pK4ODj{o-tGTVJLA{T#?k%T zD4n=%V|g&XTH&}sJ2kRU3)p{X=WU&!PK`HH|#jZ{%*Kk#DvA6(%io_SeVR z^KEuz{t~YhFvdHD@6I$Lf4N;z^ZSMV^zAR5TBlPlYXwcLC@xq&KRp|3JSN~TG~u;e zuSmRKJaR?q;SP1ptkqk;FUs-t*q|*g?#)q7>@5)(4$ z>#x72Ka}t{RT)!nrVN)pu38$9QRZ@JB}`RM*N>`Qv+3etsRr)1YRAHgjeMTzTh;Hr zgq1Hc>?E~$+<1C2NoyoH>Tm9U7 znnEszRsBJYHR2 zRl5dRZqvn;DkOzhto}{R$%{GpRyQD#YB^?oJ>I~PviAe-DEam^hdy3TyS(ldU-?HT zq|2Qw%DL-5|0xO=?ww$G+ZAY`i%Y6IHhw$cb zQRd4x&3@X@qZ|5ojR6|T3t1<#fcO{O*pWX#f({2{ORKxXBmPVT>x&sb6PLN{{qNXo z1@;QqBeO1H8f;WD`4V;z;00JX4`Sj`ZHO z#ZL?(Wt>NOlWmrARncQXb_+lT38ZVIlhiKM`|>r&Cp~5qYj1D8+4OD-TwaaY#16YR zq2)$v5R5Yw`gXM%8XApSNgLype82Fu*)tm#OWJ4`OVvGeJ0;`sYmBZr=$pshjH{!A zS#b+pd96`)?Zru#N2xEgk_SG#$p3|(&cl4h$z0i-&8{fA3w->|rfhGb%63rHC%w!Dw`>R({EcJJ34MuG;qaP>oE z5falWOJcxgt;B9I5iv#Z+oWGO=J?x++UK_YD9^&pA~5eBQvJ9fx4%5VW1X%SNwz#z zwKcI2`O9Q#0&9yqk7W2$?HY-#P3gw!O&3;T=~HUgK*I**G@?c=v^~Hwv=TxWABE#Z zVUjJjW%#G*w>%ZL47M1RB+E5IPECeV*ncWo?NFI&`&dKkexW!2V4F&j_MHKj%!jE_JGT|q4 zx)JWxzb8~uA%1>D>?3p*r5rl#BszyPgRUpRBNXab01mJg+5{wL!n_tyBZ-`d~ zQ;KO;7pZEy!b&rreUzJ`W_J7YQ@4z&I2)y~ZKRN-3Na+|N_*}&u|H&(!Ik?HIY@a8q2C!Wf)1N^VvzS| zfc;r{Emh6Ytn;brV+*>Q4{AIo8F~1`elI$&1Ox7cr^ejJwQ-1{d8*;p8z>(~{WVXI zgskStq`!>SCo6Xs-Z^3FW;UTr>vhe6= zx@tK!6-C(Ye2YWmtm9nQ>?_f(W z9oC$U^<|h79ZV_A+ugyiH~)QGf-}EWq`rtzhG8m|IICou_)I`eoL)p6>+Zr8=oXjRiZehlYC2w zb~U*L+>^LOi6SB=xkQOtn~6S*=orq#`GJzVGxw2Z`MA}GEudcSbKGSK#D?t?-D(z202d_ zrp}kn&?pssCE=M(?w_^bEAc#EQ`k>2c$TC_Jw(`)e!{%BYyGpMtaaPUrHDB6y{}}L zJ~=%RuSs8X2Gm7cqbd8&FuS9?X|8=$p2N;;^KhU3R)M-kck*z%iO?<(&k)Om2;7C>O{{yXKexyLq;# z_VGrucO*^DWY{-O)4tJoM8ivnzADX0_*khK{q5fyx!agqL1jAXbx`IajMv z(ll^*(7Ty81UTH@wry+x|F-H-e=bz{1#*s&`$s9VpFI7r#r8c) zFo@0VH+HopzsZk!9n4#cz_Ma0^d>%zkn=K6yoC!YJz!uPP8{>A^3O-@q+f9r4qKr$Nq}!kB_eF4L&aQ zi_PKVSb_G(#}6%NlMmV-AAcnAd+^a`^9&F2!bgLC}q1W4tQPOFjL8Drrex#Ex-1@I62ha|?isO~xMCiq~Q~%MYq6?+;X?l6LoQ zxHWgm%8M5g{c~CT3zoZkfBHc_(timtDAtW(O=&I${d8hsWmc&oh3wMcJi*(J7U(tI z#Mhi)y`+lZ%nTF@O6hhen5<4v%C?+=&1#m-yjl?To4nmUL!_Ya=5JJg#DxYSs!>iD z@d+s7I9z^0=MasCuUz0V*a>UD!nrTi0k%}p>xsUD5(7nH&VM_ifq<4Noy(koqR={( zH=7$$aT#u%`(xM4O_-tev)S#+G$Ow~XRdH4C?B@^xJq9E=eAFC=ODu2U9NGOSM$7) zQ2g^fJ90cDQWQUv<5Nyyog02ltI$lbpDWv`cc6^>fw$UU+D zF((DyW(>eU0T2ALZ`owMjs|{_ZU5#k&-L$4K7CYrH_`}ob76iwA+udmKv>LW${v>J z1@RbrdEqT{z$1n7T4o0-FQA9aotPgMhIj8zFJ}HMg1^z5;84!H{~yMb)VwEcTxx{P zc+G(~d#|t6JoCFft~rJV28EJWB82BJYOHhIg?cw z8+}x@)UIYy^IHSf#a0i|ucrSQQdAuxl@&XZxSU=V8xvlmLI%+CCq62bgMHX|93Gd( zcZGmz$CnhP=C+-jr$ucif-!SrHQtr;`Z$zNEQ@Iix>VzgY-x^mVw!v~`KMqS6&F6u0p#X{gO2{n}TKL!m> zm!)e@I+DLI;yzWeA`q;8q>v%M6$-O7WgSnhe+@*}ROW&7^6^S?m5Bp)}HN}Aj` zHQFl4vd`;2}eYyYsK@%c7GIlS*EyX68FkNcHhu{Z7iMM?h$nY9gs`jZ=P0 z|0@ms@A|zI@++?K*k19-IjG2-tc^)9AJFfVpWCgg+IMWaqLc&PKfi3dHF?%D`I>$J z!_Lf$`jTkBnAwq2sxs%JfZ_GK#q!$#3Qx zL2AzKYufB2xeyR^KR0I#Wxu@v%B~=_fP4Dy)AnOtMzY!u%3)qQ3yv>0{32dqIS+im zOgEn_3>&xS^=iX!I80-(Gv9|d1DZLFM)a${fPX-}mi38)TsY0@^!+&se%zVU+}SPO zI8%p{d_6yeTxyn?*UyOQ`nYX>spf7t1ZwhE{#_TFmEY;oX{qaXe~CSa|;_t!GZxn-uA-B1dZCw46kcLEe=_FfES@zyf*#=>~&Gf3{1gXz0%P73FU%ze`)bXA9r-iq@w#F@) z862q-Dw>SBu_HkXycIy}jkWt=8KF5n69|U)gWH&Dpm~m_el} zMX@#J`O>-IxKjR{#C7R2kYlbM4vS532h^zen#>SEV$H!vOYku>_?WE^XCxYJXXIT~ z9R#u!Z`2u+Ll$X^XFY`NB%eYAj=6)RP@Ij%oacBMkGY>Ql44i01K?Dw+*uGAFt>h3 zZ`xwaGf?8=x@6UtV37rCx6Cie;PV0R7hjoJ$e761x)p678_m5tNIj$;=#_e8U@-R& zrXDT{xyNJdr>mOdnoHvQrj-`j_^zbWGN2i*dP+?%{pEEFHrQZcP_}ut(z2!v1_Mo|We63{T$wDk zI-jDx`n3B?=YV5Mzl=Etfb%b%(?k1o>K4gKJ^J2_Z|?<6T%=OvY6*;HWgXT&$CNq~ zu#2rP_r3y2Iz4daAH!3O)OsWeE2TPGO5%Fi2D$mw1K(o{fiHPG8f z7TfCTOj@?!n!>LB$|U-10MEy^tB87xmFeov0)P)R!|gH>PE7yGR$WD_nrKyK9}}1F z&o9;9sY^+*(8%XZ*>u@qia%WO(sY}sMn&zfC@~D*Edw+kvurBs z>T8^2F-?I+<3Fw+@<%EyY8x0GH>(tbDfgI|SHmg}|7CQNcY#_;2rwlKK@A7;TZuS$ z%qXGJd+2iEs-C?JIaZk*!|Lj1I|&)hP~uGdGrn;zd`0PZlMe7q&cIUjvpM*d7-PDy zMR+)i%T$@&f~bM&)p3d%6h!T&s3R5i6`MsniU+DGe%p2o+J-NK`f6_&Z8LfnQ^onJ zqF9+1n4Kn_t?#1oz4bAgRg}@qR4ir>x(~j6D-c|I%%u69XWx(a-k-0HT>DhUppT-m z6BbPhDzn z-+h^rU(9;}ZrO6>WUqo(mV;GpZ|Ff{^pDTG@}H^TGrPHGUTVb`61N@3& zQ}CMj@GRDTmStp99IdDq7F zy*bEYqVBRq9ybd&+>)t{oMrA+97|E&!>lM^$fV@^J6w&ngNjK&n07UH5`>vmU2Ts^p>q>rs}uKdmP!Hmj>?2tTQ{#`DlW zHZB|j4ZBZ@XIDd%0=g2G|r6y9PBPnUF65;hgI6k|*{FY)$vZMz4`ntVxldY|=KQ~F#M z&WbZJII}0)6n_b_Isz!opVTb6b?akuCr$HyjhY2!(sdtEy_1^wD~fJ`HHbBb7nLX; z(=RnjgB*^)?1u9Z1FQ}(MK=2#hk)4DvL9!I1psuaUsmNJly6KnCPz?MWl$Kb z-C(YN0lQE@qMj|%|H88J{c|hsz#1y>*pcyGe^p&*b7;O=n>m7PS`XZc&VF!@Shyj; zl?qP&kN|oB)1iD}H{^jdY8lMq1tiO-JkYroXlU#wD~9w&Lrvl%8M!RPnJ{H#gIe^srks4^q=YO*tY{d~s$9@CDT0I#2Vv z^CR65aYjB`rLlHKK2bH3-$mv8VcwgvG40i8rBBrzs#ndZ#W*t<)Zrx01Z?~e^QrT2 zk;iLP-sIk(oVBk{bUQ`Tax8K~4>35Y8Gk4fnBOr+@{7l;1?}8%-PPz3fJ(j!6lVU> zx}{F~M!sXS)sz%u868>p z($tbndhXK%6he>iCl1AYyR2ys=ei>Sqh+yKCD(C#FS|ake^Gnq zA2&^Pc{LqZmdwG;*{$6ZVGQ0)FK=CCW}}A7>Q~%r*9#TFoIw;d5sZdEQ2u0!WiA&@ z(4VNYI4W0^pZi_<+jHBLe_J7FI1hU5wxB;L1dZlFPuUhUTnLJpLC}DjZ9yvvK@p?_ z(9pJ^x?Gd%7Q2A}^tETV>DJ;xP~qCgz=PX@-cksPlpKI2w*@^{0!fblcYZV%s@9~L zX?~xmn#1oR%{zb6G^YMxCr!NS2+f?CFtZ~%Naw8tJBf&>B#e%;IknuMPWM1c{&c#P zPek;&yYPz)e*{AR4N~7tcCW8mPd3e@kC-~TA#+ykMop-X2^LN`l)LP(qMC<`H68kP z_t$m#5K|e!JiCQ&ZlLN0SYvwFP43Z6k-Ev>wyk%MZpKE3b8x|K8PL`naZjMvS5}4n z8Q07`zifQ}^v~@)dphPk_`FLGI-bUSngJhGY(=Kv94J!gym+V9a1y;TP5}zLB*>k^D25KZ6t?IVYfY_OM0Y?qU)knr1j+_;feS+QI@ica%4djH zeHV+3mVL~RbvyEM6H-5S`_aGcfGZWd{&y}@J?0`0a*+&`{BXg7p!dx?KZ@nsGehlJ za7jUXbQ`{)Jx8iNNW8rF`9jd1Q*3)q%eAM$wkK$Z$}en3L3peCZ3~5EP}t5dD8jeb z%Q4&pcPPj|eb2R@MH?gg6{FR1%XYoDT$+(s`uLKjv`se)7JK@3_LbM09I^B*RUPE? zc3=>Y2WG_FCrre|+H9Yb=hwB^jhVY_U)~~=Zt?o`8x+ET4K!t!2VGNx1L}*M9+A+h zY8cL--f30s-axTEzd|bCz6l4w?b4*@;7p7NBB23jXw%3(U~JnAkctsp z&DKm)AQES;4)>$({~92)(mh_e1h0s*U>U#Dylcv%0M;()nFhC!fjZMC0zE zwI5IB7;@LXHp71!-D^9L=$cah(thm>JV-UBZ-^s-VfE(qV*EvOUT+$AsFOTR#D^!v z9sMk^RF`scWvDSdr8=@uVw-n@d2}=M-6|0#CVspkdYhm!$5FZX#-h1|tQm9aW{uo( z^(lEU$>2`=E_#P`#$2@_mY!2>yWw=z!eC9WgZ^~wC6>$0E#5hwV^AayQZ3%ipQ64A z@J<9Bi7b@=;8a&Tb$e%`v$m}@x1B!s?tOv`_^)nEZ2_G^rGt-gG343U({dUnK_;PzjfW2rFj1LM^w zOy8D0QW9IV)AE<K#$;DL7*_$<=0IIPQ)^D{qCrpT4 zPc>NvGp6Czy6xgMe+OmM;1}RC74yPnv-aXeCcPlcj7FoxdfZztY_q=i_2l%?VwA8B z?%Xt1dWX*w!#bwgtF<3tuUa4e4Y=E2!_Apt!&u>t< zsL5amEs0}F$`@&8Wb1rMX~c(}#n1JIhlD3MMdz+6-=ETFy%0Nh&2~k_9S9Yb#ZUKa z*{kR49Y;Q$D(|fytNccBVi2XfPV?w_rFWRxAQT*EKf>M!(<=OJ^9$;p%k39ySM{wf zTn~*t#~uQt%NCx8-r?)Jbo#)19KE4G|4KE2{BEnN0gvA9522PwSNtAOd;^IWn=MQ_ z^fQ31nL7&kP&*+r5JySK%(YLwDAw68RdSx^yf;R%)j3q&-bXMT!A zZKMfqN0&W$dpVU~yIvVIa`d$^(ajm5IWV|iOP5WJEW|dRfOch}O~2LP^2M~DEt0q| z56Iwb)=&hZWJ^B%HdBqu8+VB%sLIG}YLOpMzZRQo=*IA#TtLvurHIJmdr`HO3@3jq zav*1A%>A{B!vn>x#6=cLtc=b2h0$E4k7@FL!2_=SH@ryOS5J?n>!(eueVuK5?HcCB zF!mtHFcl?wiqYf^iPrU8b+Fs~ExtaSWK8j24`_QmI(Inf5u|*<^e>ehS3U<1uj!xx zjc%h32<`j|)-%)I8g} zb8KPD@!=tP8d#LkMGhm6!JDAGuGvstx-7(x_p>xdJPE5$&CgH^ceRE4=Q+TgTnIPM zrr%)GpH%wc-;;iuO}|^|yOEx`n0DB#OKsB6l$5=mq!!^IH$E2VDGPL(fL;^Ok8}BF z+N23eTCAku{qo!S5B`lFtM!EsTO%)cOmkg;mw^tZiC%SYAL%zf7}#wGj=EA)^P~o@ zG91Snd1>o;NO`i5bt*p4EC$X;ghwFE8b?a;h51q8CIUlU= zDbmntFKN`9=jgcChnk94y3H)z@tv@WD1q;tj3cj(_r8hNt&0y#t=9g+SsW`x_qAJe z$hA6FM>y$r}vZGQ4Zky}INay9HMIA*Q zW}3u1ocXbV$yM>~JK6^oIbFJ;lUf;Z7EdkhSznq?7V~gLcI0XUJ6b3`;n__*I3}&mSpw-JdbZ&Z->U-Xk~Bp+YNm|C@(J}tz~Y|Sai1y z&n$kQ`hs~Ao|(uPe>H=766Q1c+*z9WH2?*>1?{8U&>wU8Q~x!8`O?hn@5_H~F8}f0 zo4-``yWz1*Ge6!sd)OX*7SPw$^Sj9n4OaQ7m2lm*ip-Yx)WtA5W%~DFF_CcyrR}rH zZfrl|e%O>^Cm*A$s|}#~w<;ar=Oq)@AucRjJt;SV^H^V$isf6SRl%I6UAJC{GO)L^psqPX%ApP3qUG=kT99-WOsl%mS-^#1 zCgnm>vD`>jbx^N&TiO_=cbx`pE}Bh@-Sxh8jo6KzXmXOe_K%k4O7w=x5=+6z(1Z3i z7*Vq|HGMZknAX&kJun?=#pRo~X4NNHSWO?EYBo=>Nt{p){>-g+Y zr>lf7sYd6i;B-Z$-}3G^avCknH#u3B;O=+Hr+Qt{b}b9Z9viQZ0@07+e( zj^X3N4K3p8ZlDXTWg}BW3MQo4@+3M-^H_l!x=%2AKqFK8x`nXGKLi#Wfx0QY5ws40 z-E(_B$uclgcH>XOaNX~2#{Q_ZpX!Y^jlGCA$%|l(bW+v8?xFpk_w5r#$Aog#8QSo} z7;el;r6pc|wTR$#1=e{B35YV*_h@)A;cehn_fLK>w8;D6Ri6aDi9Sy?w0Pg4TcC^Q z{M^j2__=1EZwR{Wt61uyneLR9L@4aSzP$Q(KgnkHM1K{?`BShpS``m@N2_Z8VWp6F zghH%fhw!WC$NJ3%D{hn{Zp2b!zDSi9_5E5ly48!m%36izku!{(66QxQsZYi=`xS?% zK;|~N1pLk80q{@@yi)=26a(CAUSRRtDeV%Z%~qqQ)Z3B%qDwZbSV20Y#41nvCwG$G zU6`J~Z&21rgXyxh4vV^FXAtI9L?`(M`J-;=1f|can7~hOD9m5|(-Bg#1AyL8tslj! zGMLYVen7A(U9vjBC%f+M(%uQvl&i6>yX|9^W?8z__*P}(C`1ao8bw;qX=W=qoOq%~ zSyy{wVb;U?E~C(-3etJoxKpb}U3`wo+L-zbPgq*=v4LoRhfdrwR|Fdd zMCV0`W1CW|C#Or+^x+E+^mLcfDkr(GX-0XhZu_=AT1$vlNrvdVMSMLrD-@wDT)lr- z?99DVsk2^7;q+t7K19bxu8#G*vt2AbYWZi3iCMqUJsvUKJrQf*wn;HpH)XoxJLN8N z5$+9(V^It5e;Hu~dVlE(sA5*d%hyq+O9|6fZ;qvg4Nr_-N(|%IR~oDPXWMTrzDzFG zNs>@8)Cy5!ZXsaWtK7q0jk(*S^e8nIgh9=4xgV_C^Ae!0c>{8ZiKA=%Hno*-Cr8OA zlH40MBX-UF0w~sz2nva&6y7Y$4hCrQtW`&+hdrxqc#AFJ;F z;X`v_HHZ`plHC59nEY=(%hsWl2On!>9Utbtb> zEk_Hu=>V>XYk3rLoYo3#Qnlq}g`6!L)i0a_uxZ5X@{5Rbz)Jl3wmQRlzHoj}cJApi z&N!X>Y2lgXppP?!W=w+36&eN{D!=Sk>|PpAFVo4e;du*ARuDQ;ZZj8YfyC6isN6}eQ?iutqy<>+RM8ULOQCEhvh z8bafi@?F0G`LDzX5WI{shgJW+bkEw?p_kOFPzo|J7EeP4d4FX~s_A$UDuFFt`DNmf zxw1P<<>FUnjMHVeoJ_~Qxz?zEF$@C|dHfsfb0Cquys0T;@V9es=zqJceCh2)|NCAx za*ScMegDYamvYM*&K_W1^7@my=#Ky0@5O4z`~xvo6XLw8O07?xsXMz1TdOsg9(D}GLa@P-?5X{LX@^-{1F z_5FD(c~7d-)Jk-iog1>;s~s0Bj}M8aRx)&!AAaGKhl)-eSj6wq)saQoc}z^LZH@kD z_!rJeE5C3?t!nMuQ1n@}cwMV@B$qA~V2uT784$p1dZ9nm-GUnHLzM(j{a~Ey+87;@ zCWNW2c_3A-%oRg%ROVbKp8(c9k=70KfJ!G1$gz2Gl82h?dpNwg;2pakDW=t)!lCDK++d5v8(;#Vc*moIGx(vTNUigOGZ3W$TaFa@8_H zN4=0P8H&huP{g^d$C!-y`f|e`?9{&G|D4*IzB3EvcM3B0=eL>Fl>oHxCD}%-S*npz zUynY|nC~t)(aiK%=Jd+~KBoB}#KwpX#?#K{N~1`Bh4)>wp}3~8SF{0fR-6{6B&OP9 zcGm0~OZ`|J9J*_^RaOS`8hchBHf3PjUPMxT>Li=}5*vj$Sn-W)4JdIIQJhKd+CAc{ zqqby6f05mM4HRmMTd4cxeZTeh6YT#w^ZUPk_6EGiB_pz#Zlpct{%t)?hIhb1s@zD7 z2fETN-`Oy$JuWU!<**O*z;{wh8#y2A`LI0J^XZUSPaoc}*Ko?)*wa@M!5{W#;$gU+ zeHFl_)S8G08Y8_U*iw+|ZKj68i4Q8tFsy0t(-DSOd3ySWM|hdVd;(>@VD+bBO*#1K zR(_9G?xw-CVOmvKZ9%=+`F8hqgTGGo_Ixm8FvhgKG-*KMgYw{ehr|cY;I9{pqnS0N zm8pC&J9V_7i&yb~H$RciC7Oqk&aaCqi;BX|FMA_aClKk}q8R6wO9sEv+W8H$;MOHj zFCQ4O^+Y>A|l+(mrIMO|ZcpC5D~(Sf1mrI_jR^((`tR{-c=zQ8h(HgP)d^ z-;*H{1uMbykS^LPFpXRN@%-@|pQ##x! z#jJo`e;_~n?hv=@QTug3%sqW}6Lu@%i7C&x|9Q|8;9i%VmJ$NS2L{F4IOxm#2D*ODe8{dm*7PCBVrY$gL@ui!mr~S%Y@60GGQEZ zBB35;zR7z6X>M7RAdB^mZpD%MqW$BEukD`Oa2m~EBJJQdw1^L#L&Z_|^qJs97Tzeo~iC5t0B0Di_d(T_0y$v%Jv!dZ_ zIuhR#1IVf>Hh?fnVg>HpkPct^sd2 zQ8e9N9G!brODxe#GrwzF&7{O2p$7Y#v6EA8^9DE4maW6IAzC6VB0svPPc!&oAbUhq z7AL>vllNhN4GM^Aj@MFKxm$6aFtjGV@5m+WE%tP(VJYyU|L`u*=re#$g^uTM-;49y zTMf0YX}bg!-uZ}kO;zD&>O-#zeX2&`Q%0LHJ>87y=|_}YG9}XS?`(XR$+JGj^}r2R zG8R4Wg(mbytA~Rp8pY_g=xas8X@*RXVar%J!n;495f)h`Ye;gZOp}cHB-CT*-a7^n z$#2T|gDAc!Q8S!>j7A2w0`#V;gZ)V*Y^$iC|Z8W?q3k1#eI?+{RXnu~eEA0@`$?R&}eE9y=vH&dUMMtZy-Mp#6>-Ty!n7f`x0Khk2^<7F+zJ>5XUbVv?DiTAX%9cKt_L2&Oif3MJ1|V{G8ZYvjoyRKvyN#>M0zJQ z>$fp=QOrq7sTdnKx`cEmDf^>^qEv&A3_CWcrGqfT@CE#H%BAH++?YYEg2AnJ=C|(= zO<%zLn!QKnX9f-P8&2iS;aR^qOrE-xPM4C>6N)>S#9f#0ZOSSeKw0o!wInEV+~_t% zMu!epEF1fAqt7EEUTvFmIC+u#n^I-diOn3(V$Gu2l&UyN!NUmZ)@nr^p}uFeGM4S9 z&&Lb4T*3abI#yRUn8cWS$9k&Lfp_vIDvi~R`T7!J!dM%MU7kv8Z|Je<1EfcVhhXjj z$?WeQgNPH~olA!^j>yJ$GAut`aUgknqXW#+;_ZDi68GpY+7PCluD_Gnt$2-qB#^%- z6k4fJ_thh7F^C%d2mzz7nMk8bHnRY8<;f~|%In78P3kr8py;@s59u+>y`P=SroK0H zDG~Zd+B`mcL+1w(K-IBfVGnQ(QS4g)`6*vSTw;FM%fyH~DG2CTEk;29ytS^*(MI^e zn0v(>DQ|a+^-eP4(IT*oPGO7plk4nV?p6%QhI=2+rcp8}d)Izcd#~G%8gGq0(Dpv9 z-`;E2n`&q`S^}f2^7V?np*FwH%$1NIO*$namoCTF-*ycPv{Q9Xz`;}r&BoRn;W+CS}9x)U`)YNx8gZ9U^nE3{;Io_wp^!6 zy;ioFxoijZ%Qlnknay^8LAK;7vZ+bGh0)QZebuDtG$}KiVVGyJl`eZCHc+&Ayq!kg zOL61*M>v~B{uK=~d_8}<>~SEy$4D0<{tapnF@Adyd?$22e~Zo1|GqGGFG373b7jv& zU*4u->UYVGx^fP%o&y9?x0YPge+ru69Rfswkt>9?FkAW~Et z(^O(oOZ3W1`_59$5*hjt1+&wBu@U=4-j#OCc2fj%?F3?{OdUXBA%`e@&|he`(MD-d zlUky-KFJDBp7%)t{L|wMxTlab3t<6W#=BExXA24C=i*7Ez9#c04K^4K!|`Ej1(I@R zPY`X^bEQ|3PTtFu_r=*;5ry{!6Pk{2f*!h5Zafn>D(FfurFt8TMmTe+xIJfbjPp89 z!9v*_r&&Ax;g<0fxUX*=-HyaGNYGHbjNt8I=+8vV(j3y&pXeyalVSs6v-A+~HMPCht)?wvZY=HhLDGpyTok=C zaZUU7PS;69_cn|rZ&6}WdvT_bFsQ))^DHxYYYas#SK0nVs>drcz7(+7?v5Kj@oMBg zt%>$gb#1!?B&Iy2X7a2at=+8+sbLYDQ*tv0m+Bk0Y@f~;e?+qoc8C1HyW>n#S*58= z>!-=Wr1o-kwe6nyoknx7qJ9NA3C>lsW`sV_2x(NDu1DxjliN@^dDaW274@kh&9=zC zp4hBadT)3?Tcu2qoum;8x9wls;h8^~Iy)#&Z8CkU{y+NWB-+R%ta!9$6b_H;;%`RX zfkN2d2_4+_SZ~7-!Z^ueInNDS1ob`6Z;J@)g^45AI&*dXRGo;V&n@QkqLog>pn>?P zrdi7;re_r!mOi<-TkVR%2rDDSPYdOfQp04SIv`rNq3s=0^yw4RLw=OO?SYwd|6qH^ zvBhJpFtlGHaWcQ|jWWODXA^NS^id#OXdamR=TSGb?0gBLV9UA^+Vjz$ic26*{F$!c z{9q;mL}K)+g9GPf~-gS+L)IBEb9d`zF@X9t zXSv_Tu2ad9+h1ae2rnZ^|BTA8&}Jg&?~4G?-!{jG2%1Jke#fzk!Piv*zV@E!<7>G6DEAzFfUiL&V$bzIv90Vnxd2~(uVU2p{1-`Z zps}3!y{*qRSL4Al^t>{phpaYo2kM=Zje2MMjT3eX`_8gCwT$sx(uUs9gTRXH-HJM{ zi^DFvq)*~rj9c*rN#ba`avu7k`CiplwlVY=pCwM04m=^iS4;wi9&XucKG|mi@~{O_ z!EVJ%ie3Z2o@y7Z1>kQM;4P|RyS$c=CJ_}?JY&As2i6%d(0cNFUwZsrVCWVg1prp*Se*3BJs zXU;98^_SZ_(P4V@?JBxD&=1NgWQ%vgR^>kyl)t#O&Xk|HVz;9BZ^TaUz~{YxFB60I z++f;s?|`<2eca2FUQq3C>DxJXKIWI>Bz5*_+WN6+>jxPNf;9vJG+)x9EWeg59kAMY7rg{YojG#5$TLc*8?x;pMTM^!9pobXT zj0G#S8}53?QSkZeXBat3u^j+Iq$>aY*(S%q(jisa@~xn2%2%oO_CsK~gP*8>nH=SQ z9eI4D%T7`~RY5%kebIW-@BGESXNWx9O8p$Tq}Dd^oMGxYWa9V_y-3R^+0Jjiqw;uT z=Qmk??MBm^O@h?Km7KZgx{KawE8F)=_JkGBenCOs^R8dMeTgipwS{6wPG zrDlx7FzBkLvuL_xa9(!PZY1?Nk(FBHqzc6}Xf91>-@J^roTj#51~yx*8PfN+d4YY~ z{V{xX(hj$s^)ws5J?1W0PYF@?oOXLRt=VlT=a?hroH*uix}H*$$9w|x>Lh>ZM5`;!~WAc3gv5H`7|51*KNPkXOR zDr-NEn1dxVuFiszDHtb5ISWV(Dv@~8JvlvOY3sys#qqtGQm@vo>2tsj@|#RqqIGL7 z-ldVNKGAVSZGDlB%SwvkgQBU;Yu69P0Ia9DvF_Qn2PSd^kTv&e*w7?68;R7dh&so9 z#_2#bwZ$-lXzJ^=>m%;uqAt&bVHaVZQn$q6 zmc6jW#$d?m*2uWQao%X?8y4_~9KM!ZTrYf$D{cEIn#xRcBPC6#^;{}dZ_|^%vPwwX zUyfm=uJn%*bDh5T`cJZr=?3oUEH9y1PI?{{M>zhUJnNIm#UDrO{&n>n=*@5C#MBo` z3mSWX-`FDx8(TLxzWdhWy5!=0)XqBEsYZfHbXZ#obfmkf8HwdcsQ+ra349!ZRC&Wg zqQY4S{2LpeC@S7=z`&9rZ0$!+8KvV)Nijhc?c_iBHD|*P)7xmQ0TgUP}*N))I2jO=|ZFNb?h? z>!(Z(f4}7Xmc@7dx)-;C;&2>`QwLoQ1}cJ=Aw9J4Uhr- zOIVJjCfM!8p=ToXcw27BOUmIuQl2x76UKw1ZVM(oHGXF7NsUA) z|8IIVntq@tdyVj~xX<{1va|TT#-4YFH}1V`p+?YLg^IeDVtcSfdhtkl`gaoFyt$ub z`OY$_(Q|E4)JsHVbh+K|FOxez>OMX6yti*gjt2^_3(RvvKL-_g`}e}VkI{RuLGIZw zFt%OU{{Y7md*y`?x^LM(tPQn=KOA^B!n?Ei!H13vvHchO^cYHj6pnh{rpk&{z2o>KLCb27EXmsw$=#y_U*d=VQEhGuHVgp=>Cg6?3+sO zX2rzv%<{qDej6f0wde?5?+ripldSjU6y5fBlGhO#bGMVI!TMft9vl>s&6cAoyMV*| z>t|?GQT-usoP@}pBwV|(uOc_!#PbtN!?C*0(6-kdQ)=vB-EkHV<=z{|VKW|TAXhXU zW*H8R(`Vg^EBAv%&Tus|DcmB?TTGjbfaqKANe*?(hN=mv&mto~59Eq9J(N&c9_%&rGm zIds^_iT`}_`L6Vw%lMS%l9)95Es@mclT%)!u@g4lnp0nEfvriMho)Kbx_=wmD!Apv zRExpaRI9SIcSW+($>|+@`f~Opmf`XE%$olSRNROh=A8_YMe4E_y$8cToDBFAd;Tz< zSF`(>dbi{$L9?hcu@ajHT^eE~FBuf%ejugXn=X0+wR}_EWIq-=I(K)$e_^o|bUoA0%h18_5l6Wh5_CPldwYd9-#yeHO_Jd0{=KBWm#qf z(eQ6Acf*smyDi3RvPhsywGF1WdDgzUb!uQIXv5RD3OD4!mVY4wkKg_jh*sR+x}8`N ztvU!3IM#vUR~8v9eUEV>Wc^Uw4MoIK*RH39oS3mkFEuQNzdJOg@w%F>IQ~!=9sC-0 zt*COMYVuKK=bdcl9{xFzX^%&^tRIdQe!$yzP&71r5G3kOI;7)D8k1^hcPEYFq|2RD z!(|O8SxO^%ua&e%&mn+gv<^7Q4W>~h`&i$(q3)rJ5z67elkBztuSGb-c(0Ns1?MX*WepiMvEEOz_ydwIdH6zzN?{3?JK6EZq ziB?@Chy6Hgvi*?}B9`T4M{B~!vfN450+}ldD@BSE$1vBEKBWf1e88`>;PsyO%3EP@ zhcM>`|FacSwL@82AAd&|OhzAY5Uw=NtE!P;A2$0fwy{n^n&4<^Bb|#@@)_%Szl86Y zu9-Czf5&IDq7zq_4!|ti-BJ33s225Rdu7cS$e$9!N7PJm_y93;VGS#CYd?R4y%OaO zm-7?wGz!`{RmV~-J?qN{udahqoaAB3p01dCAkzod^^qL0)Oi>L&{b^!)!3iOG(or|7q$NQVIQq6K_{w=mu>15Rz6koe4xrXEEAFKb)eBHAt#-^vL zY1S%Oa}m4!j<5G^dq2{#`HJ|!72)iueXmVeksP9a(X#WZn&9QJ^et6qsimn*wqoXb zt$_CUO6N9*a?a7D7e<<@=5SiMd^FB#DwWy#7U4P{0fw&9`|DyY`eSyX060)7Ka`DL z15bn*J;&j6h3F~APE5b1$ikK6LqVB+1?qX(TmaFvu2pHjp`?$$E*nEea$ z;H1eMrOYE_#=HM}s~#oFhoG2rHI!8o6h-41Sq`>hbPMXadTG&5^1kT^8mC;x8KDeg5w+sm*33TlN)O zwPlj1`!RnAE5|Uk^sJvVNbF>x_VYy@=P}US0Q81T)2VUWuG=L17$Y@^cZL?cO${Ow zVb2uqZL0r7>$e>?!$mZX{kTYOKKKpHzT&Uj20f;j%uHyjU%lQZY>#M-n~(Km{g&z# z70B$v9}-_pm#+9J%p~%J%;waz@>CD{_*G6y*E7YNG+mmbskhC9INw}fG-rV4LEq5E z*h`g>k7|C!S1a}FRcn2ho_rlQ1Mt@6o%jn&hjPi~hE6(Ov!(20e$vgwTC!QCy^AMm zpfEmQv{wQbn>D&dfIaWAf-mO8Kh4s9E*d3?Sids0_b+t;!tmik`rz(cm}1YKoqJGQo47g_&6k)qL*|0!IsE@G#D zy-kB%7`hYU$I`^qb;eM^Pc_3~n&Dc%da?8ghomOj^^U(9`Sc0)j-OeI7371$5cC4N zC`AvK2pv8ZokUY=#5jJvU;l}1`4Xl+WO&0!O~|D2K1g$slOL_>;5RoX{2RMO8Mxc^ z!9V4>$9yp~d$yVhH-oZ3wznfeO{Ca^s8J(_4WPZ$ zd5SQr7(q+{!l=m2_WAm%4#gvw__vMt zy&%GhIM7Cv2;v|`TuDS;;pFdk0<*E-3hWP4%$34n1u}K+ex!HjnFcFA2T&Mau34TK zf7ax37Q;w61z65<8E1m%p%IUkPbHw zA0BOtwSJ;lpLm_QXRBDZY-b{wS|=(kUC{z0dHfapWDD{oe$6FFRGXA$wN)N%#2%|z zS*obhq;u8U^5FK9T%uWGkJEie{9fkv8P(j&=UOzmYD_L=fZW>mY9dFCZj@DUXoicn z2eIK-1(p?;bH#(poK+Y7-BfDovFDKm`xLYTe-w2fsztc7oHvCd22;4TYWI2(rP@uG z_b}b6m{`q8m;}PqQW81hOP4*YA)h>f5ys;mvRxqmmi#$klv& zN{Y%jUKJ#ksacsFD1m*oDe^`Y`E`UMvE(B*$||m^?pOTVivL9rPizmR@w8x`wj}TT zANTM6d4%ozn6o7I#Q*F4yG|c=uz@xA?{N{9B8axm(FK{ca_+MX)~@R?#fOt|5G+I=HGyP?beBYa5Ca|_{SgGkMQxgtz~AL6Ogm?cp6Bx7suqr~F9W zuHo~#4!1jwYVQhtam7sq#P@cO2Ze2mVriV2ZlLjf3w`|xBwfQpvf#gL)g&rs!$*!) zZHM)}XYl0AZye!e4=<>90GBKbms=4TPHR%CH^>%$sN*u;k=Sb8izBF{HPPH-HP^G1px$3>n>XPaRrL@03Tm1OGu@Kj6=Ovg~2=^R<2E zG4N^HnYrQ-alWF!9>wYpcRsS;{LKv9D!g%g|Md5BVV~FJs&X=iQ&pa4X8ImxdCrIX z!HXNg3}|6#<`BCJ`h!7;vRyak7eCazsieyuS-hD+h={WTUvXDCm# zFlKStDRS>1^F*1dqC6Y?_)q_jy*B}GvP$2^Q`$g*hJ+(cp`^7TfVm+hCOd+^9* z`wzoZu6pQ{aQwR|xYHYwYb&GcTQFGb@oq{q7LZ92Zm?Z*ktoLY_#<1UM=&xtmSMXU z5+F&p|5ap-^|K_rD92v?l-ke6p4gDBvgPtZ$@-BWd2jLUHE1U zeBnh{McogGH+d~;w0McS>+p>LhvN&@;R!uq5Q|Pgym<)T&X5iPQW+)dYb7N#`?nx4 zDLS7oKN35dThXt0#Kr1gAZ-3rnVLWyBWKBx9ZCsw(!Cy*hz@!f9FM~&9fl8G&aKK^ zAA~wVcT|}n#0c8uStrL$V$o!u50Jm4`!`#ZMHMZuqbb=>z2B6oU;ikT6y6RF+0 zn49dMAqafh%p+zf+g5y=ztKM45pzGN)ugsde$0~CM zcaIT^CVO{){3YEdyr3+4(ZZZwhx>$u=n9(bLusd5mepUGPi#jK8;)lu>LfcS-3?Ox z4ab_a&3{OpG~5+pgLVQyIl`A=9|be2=n8p(*YwQ7gJ~0BYTrJe4N29T2l`OSzb`=? z(SiL2VTKr(3truQ<^c$FN9-TMA?beec{oP~4w96jj&0&OVmDP7drw(QMeJMfh4}^k z52!5fe;IPC(o9~H6i|m}1ErCoxX^3BLi`~fHAD9+Gc0{r<|KhdVgd9L)d-7kk9;TH zHPYxJ_TLK$lE}-jRl4p=){75yR%_mP9%`Xs_aakB6e&sD>V+?G>mmt>F&8@Bp_MG@ zJ_qC?!ZWN0S4f10V?4giSKpFr4(QQBsrCRaWDNwb&cME(>D;EuDqn@g`F_&veg&~% z{PqcX%BDrym*IX)Yz)VnfTa6Vq-off!HnkHMTs=D++|*gC|hug(6N00Cg#6~p$k%K zxjm!waGo(MR-8);P0qSdXuO_Q*fPU@6>OB8iavIo&|fl$^t~+u zFutJ^kZV6s$g$0EoGNiaqWSM2kre=2czdun1YP4x-;hYJM{^8+hXdj3Q2at@{WN&ShWp>=N|AO^6=58#WFZJbpcPB4kFl%W4BzV6 z^^)S8KR9dd1tBGooIi-VC+OKZMfWp)=)!T-{&mY2CK6-;t zbI_Zrz=t6qi?={EMTaA8vtOEw;ofwzD)5g0Np~CgZP;Tlqrm$p$wD;yiu8`}CiCjk z59oJRT0R!)6iq8GMW$r=opC+_c@Oh}dt{r}x$*&I$CRyc`B;sQCVMl|P<`i2Xt6Ml z!7X1jiKyf2{;0Dd%z7gBwVH~#<{oeqHUBnz%cyjrS%t<3iwG@#p~g_rjf+vO2@y2e zPluEIA;zoGUd>nP(9p2LK&VnU9fr07$r33)^EVjP8}=SS3!C{5kfLk)XBibb)?^=q zfI_jJkE{71W|WBXMe~$nzDPz&2cRjRFabnH1|FjztfrbWN8AMYqmu`9Qj;S+ek*wx zi4G+CB+~|_auNGs@PwIYPqmhU>`Quovhw$+TQgG0s{3K|hIfMUGym z5sh!yDK5dB%7YFqKB*{JFr<1%$=FK^3aYo37a!%USpg#DR+@7P!}=r3RS6mPKR}_d zU*1>oOo`yV9K@TDb}IeEGRUa?=*+`s^VL9vKz98SbMPPTpQPVm$r_bDA@~Mu!myu$ z2O}hVkD}lvMQ31x(Y`WYwn&y1BA30d?T?B(?Xb>JL9_Nbyrs4rce3%8nr`1wdmp&O zaA|wPIG1(4*B~RqY;)UvYW%2xq9Yc%Tz)8z-c%3+&5#jJm;3oR4|%BI&#=ZFHb|Yw zE1hjM1-HSXlXJy%5GG1H@5d(uUl4g9aUy)A>z`_!fA5Eix@)Xd)JqTVWIaL?LLix@ za==9RN<=WLLFhTqp%MvqrIYdg~2XX``I??mCQOc|}ga%2z5&aLiW#$#j`` zR!l*{E;GDHy#_M_`41M%nl5%5??HAq%vCA1nqL;FJ)UEPOyxW&(khxr`oAI_Dqhoa zt|&oLW;aYD5<}3Nu;2Z_eEw*h3innvDeejDgp&^ruK$Qu_kBGWDOYG<>RubWpiUoIUdj)T4~5=pS>VG(IhoqQ4SL zrG#8uRt|TI!z;>RHXI_2i8&xzDuXb%TM-8|C>MT_B$cu7R>&5WwlClYl6OR8z${YhJ!b8G5MoF&H z|8DWh6+4wkL~gxQR`gnHwQpseJgH{b@64BGy71zrQrx_i!D`82O{EJl3D#ZhY#9cv z`7a!>1!8L|oh`JrV3DDA1kA^Vqe(^`FM})orf?i?@@G0msp}_J6h4^%Mjhw(0q<@* zX*YBgsT3o2w<2N5JuNq63_fa}f%_`pz;9=zn))Q{WyBG;9Bt!0UHqriBOc>i88oDy6rw`-l?!LNH#jPu}K8$J*9mcd=(%FHEar0nlw0}BRlm(X+ zjD1>(AV+raKw{KGU_BP?CEsqZoS?OwlsU^bo7M2I;u*hD7$9rj3mL`9y3s^-{5TjS z&c>^NYax`Ol>Q)KS)?ACy(d9dU1Xe<9+iHUr<3%nuRrPO%X7X!dq#&D*;{#3S+x!K z5#(}*ykoRE%RJ*EtQx}yoYn6^K(OE#=&bNqT85mWSmaoB6Qiinc`9@a?J$3NuPicE zJ%qT2Hxd&*rnrdl%?u+sbyhwW{ztc2{JFF@`15VEBD+F)QF$X%ej;zFjFyptJkEbg}8SAnh@8 zw^hCk`&{_M^ro|(A2!*i;#>X_A51@xRPWD*Kl7pY+8`@Oe`H%(WV3lk0h&Vuk4ACF zM&5rZSuY;2B`|-6v=wng%P;jrs``jLV=27IXUPVcb7_&0XVBOzB_kfx{gwOZNtdQp zKN72he{p=&a+EnTgQXnbpd;qgI_~3T*2Ea@WDG0d$tcZ7WHq9JMiD71I}yXe;l&m9 zW6;%L2=L0QBGRxi9D6JR(XJPESvD=-hU6ur_(L%9*YQ=ETy?gE07z_McIYKf=%xA% zHmtNGrTOSZwxbP$doFXvQHqTakJKAqFCaSqMWW~vijG55pas<&08vymVfLXHSNq3c zA>S@SGWPLfrANXrfit*y!le%-4&lDxww*3+niw1)J6FoJTJ5GSi(nb~6)F(saZjV} zptJprRH1&uUTJ>e-iK7Uh*+6__s_Q=7Zh6Ej>? zAK<>7E(5enPIwxYsMuenwLK$1u8OKR6KR>O2$KMv5MU&&-$+}duDjo4JWr*q(PrF# zqxGND)*e`&MeAGA);?=f0ekY9eJJ;DBX6~pQ+8!| zug`hoB-A{ZvYa=*i2CGQ@d^G{Q$(|6phTo!7yTBt>FIWZ`3!_XozKi11d8Wx)vp&e zWv19rjWA? zXUH>iB9r^T3DiPXt~7ssz4q=m7h@$Mov|D;;kLQQR^1&?U~|^&MTE|EGY791QV`q1 z!wy2#-X7>W5UYo=o(dvn4*gld@(`@R3g+T_e5hb*g;0iMC)jeKZxPva-gpn_!FQ*i z%X!0Jv^fXDt}uZYxPah;2zIu)YCyUa?|@s$`h4(6_lR>(g$N-$%f`#ijpzfw?ePc6 zl*Q^U@H65NevtcTW_l0hNs4Arv(pMkJ ztcV0SZF7MThh?lG*L#y!m64 zIf(QfibyX!9djs8W8i7bp*-Q4n$p3CBoWG(N(&F^%LiX$59zB+vRfL>@u6eFZ%;!! z8;`L3=X-*xZ*@;_9{M#=!(<-YA594_$bgr&#D&;lsEkGZ2lQn4^ygiGuO$U#5FiI zwZ^9n()i75BqG)625-ph4^AsZhr6~E9d0AKR50D@!6uIKy9ZgpB(c@8i^r2d_ zv^iWwHVF?=VmzEVNQxcKAoEw)SRKdl)oS3+`{%!)AO1^tvYtl+$8khVB?*xmNyGW~ zhT`TWBg>6Rm;jWbp63K`nzrbflBS%P^brz06dh+l5M+?@yYvlo`;sdueU$ott@pnk z#|F~-&zGXZd>R`b`1y}2#nleEVU3RbxS!RLOaJe+I&!dW=7~QmnDlmItYEIh4>&bY z`+^%};5VP{Yn2-mN2#4Mef}l0+uI;|>3jyN6^ngeCoOij>rWeT9wCqYHb%~rzF_bn zTJWSCHT;3}f<>K|H3lYQIBnkW=IJ>J6hC%~_xKykW9Qe`-ej{$l*nW0AW}XlPYMI& zB2@p^3Z&<_D@l4C1<>dN>||;ds8Zopmz{e->Y*IEGq$mEsurvw}%+jIe^a5|{5) zODnY34KjH%k8!8VV=Ty#$%{Bhd2~WCfXhE?@&bRJLzV_vs^kB!%y91fQnPdgC`Azu z)+`+gmiEQmN6PzW@kUrW*y4?_^yig?uryT?uEgQ!Wc9kWH%wNil5hzn*#A)T_aYp` z9(NS#QVx?Si+!`RQ7mtbER*)0$zMI9I0QoP#LSJszm z?F`mg`_1M!?f=#+9JRkv88eU8-_OeT)A&9d-%0nw4SDfn*?HlsN(@@s;7H*&@lMdD&biE$J*Ab)y{g~> zfAnu&;Xn2nNs4F-;9iI_ast|R-pe10n4LNx1%u1FIZ;{Sw;b2v9A)<-8 zeQnY%>|XhU-Dc+X+0A41xGGXzpe>(S^-amMq05Bk4cQU&luPB4-4mQv;bKq~K9v=> z;T9sP@!Z&!JCfqATB42r=$vL9`qgI7`&jRZ)(3nwIk6kfu=Mi zRY;$rkot(qwX4zXp#-;;tQ>fmWeQ??5T~!Pnvg;Ok?( zQ1#lmsuFE!>9Aj|1Pc}3skaJnkH43ez=s0i9orLtq&13Mm-YBoLv z?fROfvS4=BjDp#D!!3v(-w=NJlQ!jQMcjU4)MMR+_p|)6S&fe5@h|j{IR@cyf87IB zqJE_(Eq8j3HhWY>vfzUI1#I?xl~W_JBk@tiVyEstqQ2q#1^Je}RjGd{zYD%Y zgsO|iV&XHGY&j}_%fw%y<|cb0@# zR~Mu1!QZPU`td$grTId_x^bdR4R`##W+D&0T~n!7X9pA3?P6hEjs4wHkFta&ihh;L zlD6F7(U@kM>vaGh13>;qTNH|g9whDn8A=fICglWKVEjp(7{k(o2hL$q`^#0*o}|{6 zN1z1gExjWqyCVBcKZH1?V~^ndpB?7L&veo21Cq)9lJz@eZ2(6@l|1g&@Llg(q{-L5 zH;FM1&n7u**25^(p%o}RD08m+B@AFhyn6>myebyPB^iwPJU9TVzP^_|pAk~^Fzl?+ zp?ru=qA4`*(iVyv-~sC8e(vvGaRLt~s@TFszFm$UGTLe8VZ|*+N~OoTOCMG&JTB8W zCNc|;h5E9eVnE_>Rc%ne^~38;`i<*)RPS~BRZV#NThxT}d!SPhc?jpaYMc2%H_2^z z0kTUG5AzjebuN_p!Aj>4y<2|evID3Kcrt2-`H=X4V};Isd4b=&3s$-o^iouWw9|B# zxm0-;`D0<#CBDRys+vr5nZHynS_0LNS8FO-?$zy6^+%EBvPh$hKZXxgmZdED|FQfO za`-taIhx(RHUPS)#3Dz=`d#;L6VuW75RJZPBZ6WG=&sk{H(23|Gs9c=k&ILn7`R^>8&spywS}%mdNh~*IqELf^c@EJ%-`qX z(C0>>TcnL)V>4{Uj z#o?NcTtBdc3k<&ZVxfVNSw@OqJ?I=9; z(bh*IjEPlnRCv^T_{=g(IzvYvUPcvi)AQqE#|z4{`%yqO^exyoz|gYg3G_Y5mIn;` zz4*-VZ`dQSfE4h`J@fH?qa%zjXY^y3u}*Rze<4W~PovBIF&h>n?z6?m+N^Q**~;s) z;uVi@v41jdQ~pi4*Rou%pK$-D8dXHKr^MY~LyJ(lJix!Mh(_@b+i?(l(dnuCZNZ-5 z^%o=cPSvJ*#l8&dXvv29sF9ul<>#IPO&F-D#kX$9caU-je0N-}I*e5!^@Ph(9~lz| zG?=*%l}MK_(icq{#miM_JW>cJq~kZ#RJhzI@faZq4v7h0ei_~geixbTns^L#N7`=! zOQTE~35GM2_!fLR6Kmizo!^Af-oGyY@FEY&_r)M4AyabAc{$QGVjOHLm6ipU9Zh;D z2rbOFRSz(SVG|HTtH(T9d|I;-RT0c5kX*~IRDH1ShuH5sKGhs1tNwACN8JJQ`X%w; zaNGeKqc$nb$dNJ%mU=MRF#H~K^$Lp`pGQ$+oU>3C%}?Qq&1t=)=-v)OgM-yyse31? z?ixMJKV%~;I`caO5#|H)T##oz03I~i-3Y8AY_fMs8@pIWwIRJpk1t-)8dU+$7+jz- z*qqf#;w{BgLIfXz7t5MjoXt^?LB$-v1L0e}?o%A=Zz2z}O6!l-;>BDeUH{GRAo3>i z#o(uGu8cHyBW^6VM}n_@L@E7&3SwT_#aha3NSCMdypl$+bK*#3EtVLEJIfhUx(xR# zwfo+Kx%Wh2#}b#ccTcTfBoX8udXlHWpHOT1gbQgZr5lKu623)*Xsz~RzJU|9VjO(aQbBgSsE7+*{zDz8-6>mu91%xD|Sb|mmTZ`a?C=3dSi9ii&M)l{Ow7-L?S_DqoXE%=ZBtbxS63Bh%`4*2UPfl`h_90y zieQh$gY1il=#dtvxfzyHx0K^+@FwkIvrj||NFs86lDE zC#{$h%+JQ0>F(6J9o|0`Hi-B4#9;M8QO8p8J{I0n6mkCs?GvT4XiQ621S>ReR1Dc? zUV)P$tc+)FI1Ut<%TQj*xe(6A)!yi2TqytH+Lz6FE5A+--@Kx2DKu-_{|ZGQ*5XSh zXI435#6B$PYWXASR8te(l+%q7{L%eIRhePm>cEo?FGjY=*>R1mb;J9zoi~1_cw=87 zI;`}40qjhozc*H@vFe3jUQz5O)F8a~seG!@2z^ZTdm_`BA#A(HY$z0_+V>xgs3Kod zMbioc!8XX=ocW08FA}{B^}+K>){7N-R8fQ=yYDp!To#>{wb3WZD8cU~{{(lx4@w2t zXWlM~Dk7aF@Ucxd2yIwi!Q-Ble-QG_8rh5vKPwBTO{fBIc2b3+KBdDQa^Nd0tIN3j zYFub*MRCr|BT6mZsuAP8?>SD+*})FqvW{nyG*@EyGeoctmo zVP63OHCVam-N?mak{O*TPZua@J+l%fE85KB^5GeW5s0!xu7d}CD4}aH1lm7U%3vTR zzcn~=^b0MWrQSyxQ`3pAWkt({33$!RSgwW|OrAi;+v{a=pvUjTedvb~&bjtB@tSyy z`}O`vv)}lI2h)r=NOZ0ZiR5k3#KZJ0q)jrPo3Bz=Q<4c-WNAK>=?Wt6?Lb}aDhZ4k z!L1UyOxGC9|Mc9Y1am$i=Or|-H$S&y&%!2q95o06&nwY)sHuf>ZA?NZ`h&7GPgH+T z@x>C4YF7R+X4_%yhU6|wq~^&&*p8>zRyS3YA~!74cPYo2D90xI z1~|wc9e92LiL-UST)%OZKdZhHst@I}8`4%^bM)fEUuae#5lPm7wvMeqH?BIP|FiFh z>I`gj&z3G&lVsiqkGi?SY1fc}i6 zOY{&6gV|??gyCj5jN`VyFM&+lOixx*WU*I58VkMAvy$QcKV0)SL@q77C6Y1tf?rY} z;59|G)g782_SK0aoW!3Zs=Gy$be<&ZtW2^*jX?YQ_LK344-)@hX|D!h#{VtUWF%c! z3o0E2>BvF9zTbc1frK0hpdRY)p&h>acKGhx;k)ezEBrzE@w)q``SBg?GwD55(aT~2 zKQiVUYQc~p|KCx+M8|KOBX!AKPi68}?`yixh6hn&9nF!;ur~kj=V6pbBs@wU*IoRR z?uJiVuHHV(pa<)nu0QQxF6jA?5XP9CH+4eI@cnjYq%P@2{9X|MBl<3KH^2wf5{!Y& zunuR~{|u`s!<(l@`_#AeP~`?CjzxI)IoQKr?Dyhb3RXML&(TqFD_gYpOtRjCkGh|l zE`#G9^G^fSZhudIWSr_4>pS^up_ZNcRrl93>Z;_=+HX2Y zdefQS3I8I!ec$W!dj6dBcsg>Y6rAkUH<^oX{|Z;zZn8@cyJVXGqUXWnYw#tPThk>B z*`Ag>lppSjf^VCGgZ;(9{<+ny{;Zvt)p>2fp2oyN5%f|Im_lGP=r+BG8QfX+tfZzo z57}SnqOSd5|K&p;vP+uPq0eR#NySw>bbNK47l8L2=TIyHF_MaL*BCndE z+c2TK$bKs#L(${pd(;vbN4JfBJ5!&!+zsBW${ag4*PnoQF~B2C>EzhRC_lktM!uE` zGz~$au{vU(2t)DqrG2dtBQYGwptIETh2hxXL5zl@H@x}p#EXK@f&1u0Am5bpt~PE@ zwcKbnRg~y|Q|)J)`3Nix`=(ARH{Q{2k8YFtYPkOb8_=t2 zYNN~CeV8=e>Y;L!hss=h!mV&$y3JgU;F)b%(<}2QxQk~nH&;TK>%rUN6Xr;;T60>v zU~2!+aGVS`s4NjCy~OmYQ+wx1^+2eRE%SdL zwqlg>v_d&CStutSQFo$859z;@-aqrnd^KIJ=_76uNHnHlZ6FHHoGXt}wpw+Mv&Mrj z^KKNB=shb$Oh6=*1MC>b+*M#}_;m~W~ib*o(|fY{ZHk@e8##2&WOi0IkcybCU?dg7W< zDhadYW+7sac@*-Db;*<8Br;qpV=COW67KYN;jH$i+eaXEzGEJZd#R{MP|@|Lq*E`# zqV_vrls?4qRGWjx)><+L@3+Dx=|1m9seaCtPbzLZD&ZeF|MYz@S`M$I;+_sWCEx)C zh%5gDf6^uS;42|91o9>LuT^k4fZs#) zAE2r>*&_!aeuFgEMJzM^){Vc3UMs*Ei@JK!#g4dQoR{cZYT@q=97}uM40H(P4s$;X- z{E_!X^({K&t>)*SOYIg>pXxVZg$tPDzEJi2jW5w==2XVOluL1jj}EhE%XQM9M<-%^ zkp-Pbk;cmK_?hQce~w~^?7$uEnVrl*vZV!yintxSPoji*C``KRx%z%d3BBEBbGu5k z6?w3hG(MZWaC_0#mVdwth*&E=qK;SJN4whD18P#5#qkcLpVEf1>@z=@A`9BcHZ1J% zM4o)Ez_b_|K{oaW7a;Yv77?hI-u%w8?U2I3@>?X@)~V8Vu6$LxPtX({bt63DRl#c| z!QsQTUQpb#k9;8dK+SdcSzL0~#8jAlW;T4mU2P2GLOy)ms(kH$eqFHBStGi&O^5Q8 z!1XM%6O8Cc{8>%rx3bd{E$fowpCI@3oj1z=rw2a7a4O zJ)&u{x@XeeXPL`3VI4dA<78#-gRjf7fe&TAT#wq0TOc zJ)&7E&cDZw6kg*Sjc9ZqlIlOudAMH{pP~&=Ml+m8IBT8~gJEBbYf9L-&BDwgvU7A> z(*4{%r}QtQBU0xR({Z-=9Zi!(?)#@MJgO|E&Pos2g6CSgpb9oAW z--q9pttwx})p=!d%pj@>JW!GI#uDhC*@kCD9}Vjx=+^R9EYt~ zi8;9~QkthkY~=hqUnq$>zI`W6&>f#!>*b{THl&b2&y(;v3?a;`;3u-V<)L;9EMZTu zd*YLXHDAo^t!2KX_ouK^Puasf_@wM%p5Ho+M7u{3mw+o7R=WNvc>|=;FX>*i7lSB= zgw%a|X+^v(7x{~OJ6jSw~*RR|0A1CsTSK&8ZA5aTkxn4RAO!8D! zc%)-hkXlfvDM`AI(?p!ut}ZM{wHv7W7D}RyPj{;PD}rulN!N$vNGqd0tcTZr2w`3b zKd286wyzJV^TXHMFoi*r=%I%J2+HYp3jLu_Nd_E9Vlo1^beHteHYwQ6CUzA@?z4xVKELcHW!!X1xJ7#kn4s& z+}D&20MBXUMy}3_l;XTvQ;5wJMW0cci}|@I1=Z~(Bfj~m_y()^79l=8(digd8FoZf zJedjT`DNn8kI^-xxA=5_AgeCD`~Uq%2kj3=?>kaRBrX;xQ|j$4%v_Op}jLD#A2 zv^s>4{HD)ur9Vl!Pg``b@QOanI+E`G@FUeq?U&n;3srxW`vzI|nOSMl58J3@Lqu`m z>nfNfW)VZbHb0S(56xfWN_2imqcc3CFCQGfBsZ(t)l`c8eW{TsygpxBot=_xm#UVv zLp4y$sS=-jYPHW)d%N$epKNb(gyi^iJKF2%nDL=H<4rX8wTLNIgBKv6>F%Lw@LY*R zP1{oKHR^aBp_A^r7YaM1Enbh(@);T`8;a+A2I@EDQ)@ zKMLrqk-Pn9ZUe>AS#yDWNn@WahN#;KIukQtPM5J7Z_sF-{1U;@9y^XVmizs5@3{YJ zx!-gM_h8yR)z-wI!YA5x9c;YQ4B%nYY= zUQ^?z%z`lnLIEfgwnNG$>7H;6*x!WCQ&ksTM=tOZj6po}yLNd%Pm^w)w|TGAY&ldDQWjZKz#md@N2o;Atn) zkY}EBe=ocdbqRbi9Bm%L#66=xv^*W_=QJf^+7rPiVDOEf+6Qr=s43C+6vokoeZSBEOB>diRqzX)JH z2d^lvcT@GHUu!rkE9rjs3#(gA*SBmP&Zg7B{10JM^~V|yq|P1H8ZODjJ)L@yYVasRgjRb{`2-Wh9+B~Jc3T3@#^eCoeU z|2N_<>WHPh=Vzp^+Y44Y_R~Md^acH1eXuu2;koClQAwqz#Dd~&HF~fdRKBMkugh&kQ+hA@` zW-P(&fBX#N+cu0_zlA{tvm1cUn#D3|$?zpwR1iQIk`R@j84U(Q*D`oc)h~Q6>hOJK zhwu3vzAxzTeKx*RW0WpGHZZIs}b@Nl*t7xYA*3Qh(#?b z$CnUtDtdVH*nWEFC+glUaYh{ywc6Wx9H$H{{edX`z6gbPIZPb76ZMa=q^T zu*KR%)-^skmDK%X>b@poG(R{gB;~mSukm-b>a) zq|mluW$(*;;Iaohim~S*3QD+AhhLE^{wb- zYZK{Xm7v`mqT-vT-fyv+{W4>ps$ykk5B)$ElzC zBYikDDv!K49rSfB2^HI_iwwu$kDU++%?kRkhM3Z1cj8le2z88$!xkMAy0ZRN=-X2B zx$?*h<~%fHd9ty(zrXmaYPZEa#gC->OY~wbe>WVBA31HsuLeJmG?VUkU>lk6H`uL6 z248OZL%Kha{zuv4ofJeRT@CtCnJVHU$^2r>HaIChL@Y<_2T1aR|el7R; zKjp6aC&NAg(W-ZCoSa62Z@0of>Dw$Pqfy5xiav)$UkLMB*zVaS^mW(teWpIzeudK2 z^HD_Pmx%Z$^>5i{9v*$A)``{FpV2371CRzHJshBBF5j(`F1tyM(@PPp9Q@%7?u@Ol z#=TRgADhq1o|On?vV!puQxdHEC4s2>y)B3gt$K4WnU~W5^@ z#&rEa`;kCVhXCBqc@ty9>XdsX{ck1R)s;e#+BL!(ZQC;_vG^~yR#Wtxrs&yco(Os@ zV&o{({HC|iv(J3^%O8N5@nqCCH9n()b_Y*y`lWt%AX8RPSln?xsN?=oNB8wIkIC3i zX{YZ!{MkIHiHN*zUh~T5=%VaLe1Lk3c0Mri%@|CT)qaK%szo&me<32iculznZjZEK zFJWtCc;VnI=ZZRP`N1g4N^XX>1c=JEK^M>phr?#Wi|6O}DtSg;L@9X+>v>zr)AB#8 z=k|Om2PSObJShm9^IT8MW{}b^U!qjw~;w{dbLx@z4 zF(!#3;qS^KpH7N=U1p&2f8885p zBa$@;U4;Ef`j|@_PIyUW&z7q>N+5 zSgefW#5h(N%f&cO8K;Y}Tp3Rj<8)=5A;!~`@mw)N=Q`p&PmJd(<6JSGr;O)|ac)~9 z?)1A9qY5>nMy42b78s69{FqTHykto6O0(_1ghYaiIvU?th*O|LeJLYxF=LoyzjXI?MA?S)PQx z<$o^A|2tW2YxFs5o>lozyHB}wKayEH6ql~6ut@ntNa)-m{M7~ z4dd8-7J((A~BfgQ{rUX$n7vY1^C|yrd~CQdqhc#xqHfm%W7qJ#rpu z=J9iqZrkh%&Ta~~rqcU5Griw|hC`=!&~(~1dxDdi!Xj;@Gm{HQRmoHEfh-_2=1-W< zU&RfH8B^) zsL8jUdaGIY=od2P-9MghW0ou2xgQ}rDegQ76Sz~L=DBMWcgFmfxsfk0>l4<<)LjRB zG97S9H7Lpq1lC|OBz$=(<-a+@|0MWVHA(n_34<^tp7QxohR?&b&+smfaOCThpS>`t zZEjqN3~QxsA}d%jwHZ%Es@nMUzJsO^MgBmzB6@ zDDL~K{fNkmW=_3YaX!3NuQ>a)Snqgpz1bq`&0tUHQ1~3TOc4i)3>&U7wVu^xwLYbM zz>AT$%txM4QO;qMeOiu}bJ%wA9VzjZ8@_;C+v$InPqVX=@uoF*vlC0>R-_d&w7 z%3--c;!NzSXnVzEf5iRat2n4S8P@F>F8gzZX1}MT>>Ty*BFXhZy)ZY)mZ0HyNZVEa zQ}a2c9}?HEK6p|%3XzM4Bw^!^aRK4*@6@vBKA+x*W%CJB7if%}KTc(r0st$y8yDwJl zKBn5eeiu423mR<$1(8{P8J8oo76J+*vu67vby6{;Ehxz(Z0zk=t2V|(&TL6T$Mc8u z{Wefk7J04=j9&PJkaUCQZ+#HDt^@O?qlMvo$d8P^jycAw_&ukSIRCsU$+W&1*+@*K z2mO9|NKx9EYA05J#Lz~oy;$-*!VjBD*Z!B6H7k0z94Gg|GWnqTD`MR?gT5w0TXLij}wzsbCQW4pXVk)nUL z92*>~^1cpvU)O}>i@?4qulR^aSe>Z-)1 z{fcTN0E?mOqfUPm;-mTsbFAX1`>QQDQ3y*572Pqo-?A0HP(MW9#BH^(h9&MzNA47} zp;pW0`JOM5+K3{ahbnbm;?f>?xJ}FdEYf_}_Rl`0+mV{EnRnn!(;rbi4>~>Pifbk7 zI1yih!@I=IlCX8YWXy!FhU(+Mh?zt20_N7>Fzhlb&bM@xbjpff`*qJrk>^WZkB1ww z%DOg&_j#&!M`n7BnPY?ll9K=;L<9|z`I_INpB~+&=FalamrRE9a6npCyxAFD1UH%F zrYzHo`yR_2O_VO;Of=QpTYuD)Qzh6%Dzk#!zbFS+WR*Dyk3cOS)6cFOu8K$X@QQEp zE@eVSo)o`C-*{K&jnhGmR4<&V4E+bHzx6mN%5z}X7cjE)OX$h0v^SU+*6 zN)U5uP=<3FRS{!CevUe;8Wnv6!b$JpmK|Nv-W7U%qZC1Q@_zJ-;M@w3hQ;EQx<;ei?u2{H{GIxi#i_6<^b zw0nAdB0Y!y3wnksdWv<7@6|Dzpyvj}Xwef2Az9zb@%g5!BS~l{=68>(++3d#+W)WU zF~mO(CVz@Qg^HfP=ol}`h_P*b20b##RP==4u^o$qo=bG-&;Fjy&3c5k&R3H|reYlz zizSDQC5|BWCw3$5pP~KjChjC|A#NnDA+9E_A}%H_AkHC9C5|PIAoeGABkn(q=@WMn zw-7fH*AQ0|R}mKz7ZB$VrxM2!M-clHyAk(KXZpmQ#4W^)#5Kg##8t$_#0A7T#Hqxw z#1X{)#BRj>M8}h;xWjiDQW)i2aG( zi2J87ed12y7UD+Y8sci=D&k_|0^%IvRN`3T2x5QY?lPV3PU05gM&cUcYT_#5V&Veg z9O6{sSmFp`e_}V{{!-?bxRbbrxRJPqxSF_%xR|(rIEOfuIF>kq*q_*qxPPKf|0>qM z3yG%_ClZe%4kq>@b|QYs`m>9;mDosplz1=kHsW&PRm2O4rxPaBVib&%(FN zA=TTUG09JOe|E4RmImo}C)4|V<~d!UL{R*zOvEhu?K2a0TezrGuyd2z%ntAG6znaE z22M+PmU~f3eix!UcyZ=Jf#Uaq?{i+1EzIi#zJ)g-fA3X)-Y%fUZ}V+z`nGdvzkdh$ z9&0L~(ArPH{UB`ns;y@~)Ns!harTOGNIGC;iZ!44HTG^x)*p_1S(4tTKPXBN8qC$$ z@Acy-rBEv|d=Va%D%l2Hvo{}xqgjFfP+>v{%=LW0f6)n(pTg7>GG%SfoBM%Zs18N2 zk=xwi`t*KcxnV0W-gFg2VFS6)_dF%58K2JOs}NNQ7GUsOSW>*F8jm{cFmZ-~81+N3 zpTGm6{P;;E5*@JC-|%6!KMTGVdYXg`o7r2$M$XE!t^ww`;Cr3&eMSMMv*r2uNp}}? zNwV&#`87g7a;_{Is1NUYCYT!yd>`KRU3IUpeJO&-PH8}-%TT|dnMy=!Jo4m8QOSBA z0;*d~cs0D-*d8H@rUEB=5jEw+!%HD zC(owrXD?c zrp+1YEMb8`5l-sgT7Fp0aLc_`Mch!f9C6XfKTJJ~JwnCyE z=I`!aVKdzU${z20H#W=KOW8f9|mMcgnLVL}16U1u5nDJUJ)99Xr zLYmFVZ5Z!*$a)a+=eRNi-6a?p&%v#Nx2xZgmwohBCX|vurgJ62a(!#q4@cZesUITH z?@!2{=cbMMV4B`3+#~H)%bp(Zk5r-OIN`uL1j235JxTX8MWX#B*x(!6G>ytsiayDM zbXpz?Kc8&*3&$_R{*Z)xQHV`#mFxN!J>f4pillq*SjnPek$hu-9tQpN-El)i#;wC4 zpKD|lZ--`1S9OaVKj9s{i7xX@MI*?02;^kM44Ukt5l_pz?YcAWZ(#6r*2vz^wW3(H z+_3k6SLvsphFz2W`?b2~vW7u9#Y)%b?CMVq`@8T0vfeevql8=DN{^9v2SGViR~q*9 zFk!p2dY$xdFiTP9TXMTN;Xyf>w_~`K!ultwMy>d1vR4D-ugQKjO-c95#V&mn&K#GM z9-l#&`2^}>%WqQjA)2!h3UcaTW0`br~jf~jQ3}~wyZcX37Q&G z_lm`RQGWMM(9etE$cLS{5_oHHt}E$-&7+de=$5ncv9VbnJgy|_M}^LdKnu?Eg%*Fx z3}0S(q@ldH@v7WxKPDPmuIes>YcyI2t*Fg#1vrvRI`t8bP zV?o>5{);9e(dK1ELRxbq~V|j4{_=A~i@oQH- zl*u0q)El6%X!Hw}%ZhX{1=6etc8xsG`*P&TKb`CRowcRzZ&8^SN%(pYs3MqhQDA&| zR^zg+?A|HgLwpNRTdulYX_{BO7l_um=|rxd@Y>ZdWW;M?W~^9WF> z@?CBW91eOgtpr2INsX9(QR(>US=+4|(W6}0pSrJN)r&-l78^iAc~6lBA_JW*`nCpN zn1s4J19PI&qGz51&&r7u;Gn|M#0zdk>)stkdgu8sf`Oxx= zRbZ)0ROS{y2V1W4pl;Dd#+tG|um%V9a60-m14GMO{^7WO@QuIWhiret$2oW)z$}m` zQE1Tq1yzlGywF>QSX?cCWqnX@?`-gZ1oJigC%zy+fB<-8594n%By(N~p_Y4^OgSLN zXqdPTy>Y7ldsVvyB@*K#;eg*bKiA)Ms^WoiboT6Go-6Jc-V3-am6eQI$^BDSa%!b| z_2)9}m_*%_n&}gF61NaH64ww{6IT%z6BiKY z5T_Ey5=RjG6T1=jdzn6QCvgjLBXJFJHE|VjF>wKL4sq8pI^M0sMuk>=G;)T>4A!LUuh2&An#yThtT8OmWA1XH<@H)N<_1poZG%ExTwBbH7U ze&v~o4(a24^C5$^S4CIi?i-!5CoW?N$`y8FsbYCq0~!P2tHw&{{d+jPcD!19;2>0-mmrJYSr zo5)FK`ca=9{yS7T$Cgh~^aqG8V)HU>A0q~cE@E?t?!*AmMGP%vyhIPtMvO1f?)Ai4 zVu)Bl^btM8_^)-iI%14iMGO$VL>DoBJ;M=W#0sL9Xd}k2BYnhLVu)Bl^buXe*2Owp zGciW2A_jIAnp>_`uD~LX#hiD_luOn=F4Z{;_ zi6LSI(MR+UZNzvr!xL+XAz}s5L$nd&L53sN5<|oaqL=6*#;?}l>WCp?faoFGi1DkK z4lzcoBKn9PqKz28lHrK8#1OH9=p%ZFHe$SrbP_|v3ZjqbBF3*^dc;~{h!`Mxh&E#U za)u+;5<|oaqL1hy+KBPX7@k;53=u1cUZRcIe5npsOROULh%RFM678>!7$a5@14J*; zMT{>XUBno%g6JcxeO8712j@ z5t}QS4lzWmAo_?NqKz2;CG$nBC5DIy+jwW^&;kzSVxQz zD~MjAjTpaBhpQu25d%aIvGoGdMXV);h#q2V1?eEx5o5$EVu0u+x`?gkGd!`57$a5@ z14J*;MU2lSoy1yVh*&}N5k17#^B9g;OY{+K#Q3@NN311Q5xqngvH2YBKScBq<8!oq z9Wh3%AbN>5V)NPBe~joOdWfyF86Po3tRVV`E@J#F?Z1{-Mf4Ekv*=E&BKn9fV*E_{ zBf5yqXOJFZj95YR5naUiO!_B=hykL97(bo6Jx{*qLsZWl>UiTL?6*b zj8D}5>WCqtkLV)COX!bSMf4GE#AYAUB~}rAL>IC76#64p5q(4#F@Cc4S5K@WdWm%t zw7ZMgI-dTCwZsrHK=cq>$I(AAMhp;L#Q0e4uZ|cZ28bSFYcb;^#)vLryhyv(5-W%v zV*Dh!6Dx>bqKnviqW0HJtRseq6+|D=Lu@^P;fQs_7_o}zBYKE7VtkAaUr&q?tB3)j zm*^t49?x`%b;KC4iWnezh&E#LaXNf0v5M#;dWfx~NguJ6=p%ZFHe%dM|HK%vis&P{ zi1A~!|2krb7$ACxt;aB4VvJZp^b%df)=}DjGqH{sBUTZ8L=VwMY#yn@*Ahd-0MScq zJ(~0rW5gIAjIKvTZi6LSI(MR+UTMKo#dSWdxM64kC zh%RF5Fs4VWB~}rAL=UlbDAOU<603*-qL=6*#)s%|wZssyg6Jc zJ%Ztg6+|D=L$nd&gS7uTVu%*Jv5FWVdWkM# zYhUfZnOH}R5vzy+qL=6*#@#x6J+YP;B32N6#CRY2C)N@}#0sK^*xFnBj}a?~UZRcI z+)MkbB~}pQJ((V{mKY*d5Pd`!vDKx+)e)Oh+d+N81F&4h_%Ej zVu0u&wmRsaSW65MD~LX#hiD_l^BA5OBUTXuL=UmGJN*-5#42Kd=q1{S&E0gkT4IP8 zAbN=|Vry6Jzm6Cq28b?Vb1vg0RuKb453#O`_7@^n5Pd`!G2WT!603+lqKg=}(;qQJ z3=mz!)*S6GMyw!ui7sMmw)WRdtRu#VRm1?%OLP%iJL&NC#9Cq%(MNO<<5{Gi7$Q~> zZA7n4`@?hgYTv(kDKY6+-?hXL5ke`--b1tz;|H{TJuybCBKn9fV*CfjPpl&Ph%RFM zd&WzQ5i5vZV(WMGN311Q5M9L9{n}qMv5pucRuNnG(I2sn7$a5?y+j+aeyIC7 zEA1~vtRnh|9-@sH|5E!;otK3=98CSp&-?#;zN&wJCO$}9Lwtz%H)0*}QQ~97wZ!$r zjl?I3PZR5jjl^e(n~Bd8w-8?81I6L%0lA^wxN zmzedSE{AT!-oydKA;e>dClP%_tC>vU_nE|Vh!+#*5iccH5rf2q#OsM6VhwR6@g`!7 zcsucT#CwQ;CO%Ajl(?Sw6tRK0nfMa%HR4;u_lZ`1JK}D-e{~3d9mD-^edqi|m$QS| zhj=*gNTStVhw*zf@dV;nqMvvg@qa2GXE6S`#QDVQiBaNe;u_*Vh))uqBfdi1LEKIJ ziugUzzDDz_2eBW~Lp+)|hB$#ZnK*+un|LAd5@I!R3Gqha?Zn>`|4dv~?k0Xs zJV4BSNb|oJaS(AZaTxJ9;yB_Y;&kGf#0ug(;?=|u@fPCmh--)&h?|M85w{WFCGH}A zO8knL^Dz4hVn5;l;{U7V_;0%Z&4GV&;NKkhHwXUBfuF+x*IRlV{5gLAGk%KxhvTm; zzCi6y{9M{_VOagmd$PSec5m-3J&rrB7WdBD|7|)*{PBa>k7Mw7hxpsan*O>tf06C> z#>;Yki{G92-G$$3{O-nY27VRzU4Y+(_|3y_K7Lo>cNu<{<5!8_ukg#>a#_xKYiHzK zhTpaL-GSfb_+5dY*v-Z7V*KXgcPoCk;WyYG&N=fw(WktwM-F~={5s>;1;3v7dGPy> ztaUwZ&R*9ey9ey-$)0t|uD#|sn){xQUj=>_;Ai{l_<}6_vhnLI=Ip*>Y_`kCbiywO zKRbS%@k{4AZOR$@)8$uq5PPfq3ZHIYemOZaa*n)Ll>fK?n{kkMEm_tUsZ?rt#~^L9|sq8>GsHs95?FK(5!(+4Z|H4q|V$ z4_kfv{AI?OY5u)!ZcZJ3kKyO-GB;-uet!G{_|3!bYW)6$-=p~1a_8oB+jLpZ`?WiA zT($-Fp7`~`uQz^u@N?tW7r%b^<>Pl4ey`!zBYS~;hJ9yOSD&3-OT9b0K0bP9*Z(Nq z+0{5@XV5bwBqiJajY^CjFo{2^vQoCa|Y#6=LR zAZ~^DCBy)Zn@3lOT8MnXbRWVcs^j4H?f%^Fw)^uT3Lthw*Q(-3FlYRcV0VZ__n-(a zL>@#U1kwBFb?o=K7PX9@LN4cA)zCVqf1$ zX^~OGCyh@V1$0zeROD}M%vjIV-~7S9xqc}~0x@BtJU*yxLCPBmBTj}i(%TjqHvfeB z#{?14V2EQ=$4T}8Mb8dcp+uksQz#&;3q-_+LJ~s=^pZ=pNEchAt8p3;3L-idt!YGo zt%u1m9v%?300Ss($%EFupgi(Fj8@oKmO<9+Ap)IW*80q-f__V8f1etc-us1($n_;5 zf`5pz=VyX6IzJ>kdwvMBJU`2GQbHLDh@VCY2q>*b2?!`{LYsUW*G|R7CPbeWKxxaso`)L1UvnNve&3x}dSve0 zbtCTkJAvD!uOfG;=4%R3R(=Vjk^Bf_6vDP`N#GNk7WdSo=rJAPY=dt1fdu`Zg}eO(W8jep%ddrj~<&q#E(uMJ(d^^ za%g}LRbwj$IzP60Tn!-L6~g?V`G?BQe8?d`4$ra)ps3s|2gb&wJ*}8glv|uTqrg@a z#ke#H+GzuIKdRC;u$Kg!viYnL4+#-fZyCZ+#@_kboIcwQs)tQ;hI2^e- zkG4TTfx}I>-!0}mk-+2e3Bu1@iupmPAU2QqA&rJPrJPC@ znpb2lq+pdUU{OJp&QxX@-@E%pE&TgLTdVW&O0KGM)ix)Sl?@`Jgv$w*snwFnLkv`6 z6M6D#A1y~%(AV23EnezI!Q>+Poq!sqnB&>vi$}77bs;_<$e53(-`<~} z0CMRH-&6nKeTQ7ujeF8ShS4tH1doxA?Lot(v;MlUG(BPAvS8mSJkC^SS8DhWUb1K5 z4~MT1%U}FQtc&)OjXl-s0bV+6N_1e(rIg{1S`0Pr1b@3v+eF}{g z#mb79oQk^FQK4G*DTk84UBU?@MN$PcJQuD_Bhb#gWL+ZHJE5OA!?kD-Z)eZt zYevp5;;oul&ym%-4q7vRX?S|L%j)nSSJ#)!jT~9znlbVm$@kVKtfGRC3sh8$kS}W} zC@9rQ{L6WPp~9i>WZpQL|3dE*OAr|CPs%3=)0MQFYskfjrNYe$PJrGryK z#)J$WkT2D}9uyjb3O_U#@+D%88-G`7v!J9z+_{KwZ3_mebtwb zb(m7ucqIG7>&p_;t|#^n5pLC8u5Vj$^yH>P^(oGkp_y}f&sOEl&MF*Ny58My-SL1Y z#FJJ{KI1>h??N@vBfk98pb0VGr#;p`EvA2nI(+Hn`qpa=D>~HIA39Zb3aU7n;(49$ z_#D-_X~jn&OH%+|k>Y$?4|R=P<^S^Ju4kWI?f=omYN_u5V5&Owe*GzEJjEG#h%w&> z!-4h{(gDqv1G0TMgDc}>wM|uW+G*|_r=psfBB=dK()~8=-d7~=+St(L-P(X`Ne45V z#{UFwa7+B)D&F7|bE=BfPV-t0LQYO2ETgs1yWo%>~pM}frSlXmxZ zg?nGJxyz-%fVRLcjjFEMl7)i~Y6i8&57@(tJE)1%@&=t~_nED9nxEs;Kc}J){?ip| zU4>fdG&{^`_T3Ip?K5=6)540G;)=qWin%o<5nr{te`Rw2&ggzq!b@+d4Y*nxaKilm zqAK86U_f(8mt!iy2fFwHE%5_t%>VZ{#a741R`Lc_H}!!=@0AWZ%Nt~9s%i;zTA=0? zk`+a29y%9gg}SBUnK~!)3~(kz5CPCv0%GQMqXfe$k$*m!?VF!mR7f~7$gbAld!d`$+f(?sS z)ZDwW*E8~nIQ1*P-p@C7mEVfj`}uM^yhbjP$hZ4wsv>Wk^yD8_ZX~^iyYofe$#}1` z8qMWfB^@F=m*<2&A1IO<7g)cJW49~~)vpQ;o;d#_^$*5Uv0Hrf^0!F=r5wV(pGU@a zLDQkX&^tPQo%upx{*}iG$osEi(Oi-;&x28!_*V3Tx3A>tT>Ac(in66Uhl9oh1*xyl zJimnZvX8}kIVeQJRfsx-DFoLP{A;pJ!HL8%z0jrPmWcRlXF&PfbxyPq4(4m65<7`^p2{PmqS_4F5^*Y&XOMz4zdUiQM8fNB@ipe} z%XJIC*;%6!311V%M8r>+w6gyk&3E||8>OP~FK(4b3VDEwa`l4g230IChKTVweOBP1 zC|h!J$H|Z-+h8U!f=mr;D#CM=G5Xa=;$RuBiIW{dYy} z?ZFvaE_!e1j=Zn7k1E)fS1`hK79BgX=bIyg)~t8k&~uHKbQTBk zJW=|$iskTJcTP3G8B#_i=+E9ZBcA4W#p9l*w1g+Bfe`ShlRt1(6hXWP?RfKL5hPHg z_DNXunvaW0puaidg%Qq*0CZas-387>sghFhGA1=t%D6No7Jn2t<;BQ!9YF~NHGIvB@ ze1u=z#}fv07dS!7t-6v8bVH7us0tM}7W)(uf= zPC7>@^cm+Kdj%gNz3lc@xR|NyF&~p@G1s;84RL<~TYrVmb*0F_RxnntiPUplsT)`{ zjZ2|PQ2fyIN$Gj9A>hWtJ7Jg6X-=z)^(o<=yC@I4-O$szAKH8#h|?*pVLp4h^GZ7I z4Z*U%)9DG$AnxvC(jnd9JF8ULPB-0S%QLbScDLAzjycO?>G= zodMYmqOI&H7V66)E7=xK)cP9r&Q;TSKj4Zq?)&tDiIQ|04cX{{rba&nTkYpM*G!@V zb7jzb;(P0P1L=5taU>18${ncZ^$NBszAML9BvahfhyS2>BRaY#bCq&VyVvX7Z%AFY zNtkO5_#0#Oyx8VO=IW-t)VY2_yYC@fA5>7q8+fF8a8f(fFfx;zzu5D)0T8|PCP}+zRI8Z=QvpG1A(v|@!=@3?l zL6o-SVaw|*%F!vXfh}(V0O|NFk3~GF+@Y&<=qeq$N{6oU|Ff>rgmjfJjn8r@EB}0D zCDPeDbd`TiU1b31DtG;ZnITx}D(Cn2YMjkKV%&bMv1^KY^Gu|hq_D0s3D_-ll|l<$ z<>OH1&{aBgm4BwLG8^Wx|7Bg}i=eCAw=LYEtbC-h62`^xF8FP~TOk{o|D3+kiAOED z`4%)ms3?cd(xJ0-=q&$jI!mOV%$&34b+>L$_C5Vn{_|5NpL!W7TSh)YKZ&gPc%Yl? z=Fm?%^pg*4BUw{Z^ji`f57I^bQ<)CiQ~(M zO?YfVjKlEpPd9vYd_VrS???3B|8LnnMu0A{*UXgE1ZWclOMPOh{v-W+ouAHn>U`9< zbf+Cpv5&|76?8scf^=mMh+5)S1n;<&YUqi=0aM(ZISGE2c z{h|cA46Y)x-5{%9M3|+1F&Oe}pdf+tfVZ(8@Siq%z>5}oz}pTzpkwVbyBgZD_Sv!a z`7gBgS&8(3F}IK03GMID0{+QbK*#sqZ~NZ+Z|VSpK?k^YcPz6*JG}cXb%2Q->Mq+_(%<)<9+bk-Ut6# z{hu?Ba{Dx56xgJw;N#D+4%)E}8n5AYtb_h{u7gJUzsX}2yG3hD7WG=^KgIQUxE|^M zKJ&8H|6KsABNVuS*5)Y0j$m6DX~(`$1H3$lNPmbz4nxe!9)zR78l$0fG5UuCDo5>G z`d@sOEkrm(q&Q;zFFr!=hFma40V}GG6(tPPC`cjNiUL)ostTuO6%)u~VmokHYM>x{ zKcLmED8u8RKc*(6^+IXOz_!3*Y##BUh>o#cEzQ+TW0p02)%IMlOmV# zgvfB4`AN1d7DE)2Wah|Xs6N!0@Q^k4(EoSOhzT&vN;nr!I4Mgj!3e-vD?uTY{VFTL zKfw#qNRa)JUXbSWC7OhM$uL6D_l<^FLwxLsrnvo_Ue&xIt?}T9Yd{O9M|;WO>ZaJ% zra>*dZZ*6?2jgQ~dHyt~%UzE6Zb{c0vOybpaVMJkw8jrH#t+a-PXr4-F(UU|-#|9w8_;IVnv}NkUCa%4wf5jaPRQ z-$o=fk1{6cr8+-O7-xO-FxrPF419@769sE0(ic;ju8nSsPx@&@QqRaA4(D%x?&oix z&$w*5N9L55No5ftpRrtmCb_Ki1E-_vahb9n(gz+jtf5ss^=6X>uoJuFgk|S!3E_HD( z6=|MTgpb^>n*XvN5#EQ#f^dS6=~QgE-mYg zKtG>Kv7lTXBODzqi;W8}&dD05%2(%Q75bCu>xJnQxKVtgL`N7`Q>0QNBfAQ6y!jk( z@pMYSI~7wpJ!#LT25`p5&*hcOxzJxGY*uQd+JuwiMD|+tI5%q z)i2$-0+^?1O7snh>Rf{?me;R_QfENL;qK}gMUyvgdrQA=^Rl{S>(<6lmHv6neg`=p zs`WjaGUVg6{chh59?IX%kzG;#<6Wuy{_?|Z{ukC<qQQ}ahd1O&$$@R3n?yJ1 z=`mzJ;Z&q{@^|O<zclw!6lyp_?wpb!5>e zQCZ)0_%3E;;>tVMV`LK#I5(R8BsT6!A${|kDe)5M_*oXDusM0vq|347YCE~Mq_X4pjvRqn5xRyJ-ujn_nt)? z)_C#9BPUkJu3kTV>EdR7f_GG0r#B@rZ${Pkkd3Jjy_eFj?a**%n@`oxUgE< zbIttMmizZyv&L)U3OM%0Ez_~mix)55XuJVcT;D95)9QpATirZ;?5kxhn*lzyng6^3 z>e_T-$*A5QpZ7WmJ~>AyU8exkkxQRnyaA1G<{yH~-hBNdue1&?h{y|~sM+iVab8%( zY`VhlRJ{9Lli(`l{;5fDhjhOMFAJT=*9wo@&|fnt=rf=p?H!&gE}q-Dpy^!J05bNq zQBC==Z$`Xwy6JWlDc(lM3h&*x5%osZmJhF8+uBjMcGB~~)BHxie*Ab;Q0tG~&mGVB z@k#f*Wy-!3DHQn<0eq-y)e}d~d~vJL_tDIqOU=Hu^)hnP^*(abHFCMPC-TL66%ZaDJ~`oRthJ5b_DvW) zoD4iJY#GwaZ*BAzG_Nq2e}yE7n=pa0oM+Tn{0jLAl>Jrb8AIV5A34uZ+xND(2EV#j z=+e?}ExwR=Se!wIe=l13xXL5&2juFqq;$M^sMtS4ByZ8D>10R58KQYbd|9Nphc;mu zkJBVowZrw!-6qhsl!GEbypp-g2M+lyywbMSk6pS264{?>eCr`M^Pv*M_uN6~&Zx4>> zgX^Il9EU2rvJ_oYN30jQsQBQ(QQHm<9Q}y%83WKB4(b4c6!KxxhO}c@P{;3`BiMRx zRAcXrZD#L{-h8>`#NeDxbWASd#mD+Preao2o-Xr z>w86+Z=$$w+gqbVf){^iRW=dG_i-}J3F;cJ zzI*Hjw6RAO_<=G*^Ob+xm3WPt%s)?j*62pNb$IEJti!K-)s_6qSDoS)ue3De@G+|Y z!1}nlebN07)c0uccf7x>yf^-~_ZON|Gp={vB0Y@>T4~=1t!FHHbvzz>=1X`jaBMyI z5@xrLe0X-;g|~{dA9C+_`f37yM2h)6<4-gYNjySDf#wqGX1zCpK85fZM$}akOB;Lc zTh_Bo4vxwr6N%m1TuU3oCE~9n_gpjh14o>>)~Cv|W$x=gek_(Hl?Hz0+MUSY2RfIx z1AK6Q-Sv;bT{`3Uj#?-yDwBy5aBfM7269O_x3ppR!V+;ZlT&Ui@fKw0`{7(&Lw7-@ z6udVgzmdvqoM=IoVKB}aWC?=ob{Wp?DbWh1nug-s{)TEn4n4fPzyo=G+`}mkkn6*8 zb%Nzl;NlUZ2TS$_Hyb6>4T6q+8OM*xW_~yC;Jf0;hN;a;;o$8EU6zOoArt1aN^w@Qm7N zDrHsND!?8vDW+IW212(#Dj@xrpvSRc>xO-~>b*^yFSxpGiiF3WL;uwdo#4=aF_+FB zAeNSCNepcEx|eE^W)+#p8(%fX5uqTWi)u1N6j0hSAbldj7GMyiEqU1TwSe<%%FrRG z99hRX^j{AB*Ppp7h(rIympSxb4*i!y|MmZQ7m(lf{qT3!e+5oU{OSF`XKVMB)c5Hml{kHelpRE5f9oP&zR)}S} z>y`fm{Z~-lk(;3Cy0N|LTZjJZzoq|r@13WpA#NWlWgnaNsNR@A4yhh4gT4~1W(X-n z1w>o>uP$KwHNav2<*@(yE9t+I;fhtl#p(^eS6Tip8x1&X|K$Q@f7Rb*9rj-i`!6m9 z7cdGBvH$V~_*dJ1tI`ol<#Sf?pb2$?3JIZE`s0O&P%CFcT&jG$To^p83IX-8#hwmU%8FP zi>jeS>0sp*+Brv6keQd|%`Z8xq;d?NlRM{;?@HZ5g#mt0@gm;E3jr&8yw;~~%d5d# zH$Jw-O?XA%KT|Nn*e~G5vGy88N0r;)!NWbl(n}ZH_EujVZ-*-Kj(K4x8PVDNOEPS_ zt99QyFqSvSwAwAf-`Egvv7uaJJZ2PqK)baoOZ6gu+KsoLC|tI}!9^~w8&uK`X>^Cs`v%b7 z+K_Vwa+kzqx58zMxq;UWf%-DH_=vMyLv5=@VJLIetB&09P3+%aMoN5h3yO-N(*w;0 zV22YEGkSk{bNUM}2&ed6T6tm3ITRcU)X3DCI)%rTv{5Gn>H!&^r!`q2zM`A*x$6yEBmK7%t zy?=Dc3fRJS+Xy(ec&<82R!}gbSXB&F6piD@-Ovm~b>?P0Gdyz~z**x;A4heKy`K2k zN~iC@5nuoQA%?Qvz?3m#RzWc|K92h|z6Tt3VC)VPzwJBX@2&?M{7vle=a)`@v$rTx z@al$>C1`%3$97;hV8(1Y->9^(1N#`t{;Km0haH&14(td&p4rLQVF%{01N&R;=KkB> zU;jxx*c6ysuy$Z*fy+bez!d9>KYKodzkbNRZ$bY>f9 z{;Q0WQNj^R8S5-$4Ff9Qmf*NgdBSMUj}6VHFVFWI?mzOzB7)AYHU(weuMO1j`few2@d-&=K9$K z#9{w6wlYcQL&YanZX*1m#N)XNJg*wh5*BiAK3)<4oEmCe^{L!%w* zADu&o!Q9oc{?W1iagm{X-MWpHp+d*{N5}d{qx($>FTJHU;A(Ba3G@Gps(@pG0nH^{ zj;RD6=wOk2{D2zs|NTv|)$y^Fyg}7}VExG7UGH`3@r+#whOpG;#EOLB{{C+`?7tlL zUpn`hdhB4;VgI#!&B*yhyj3&nIkH;UL2KqO4NnhuSsni4>iUwokt2&-Ge({x`QCiT z`o~``^>?g)te7dTD6FZNTT>G8RlECFCin0D+wZUcq~1#f-*c?q>wkLvBj~@{B!AiU zkFDqXzchCGGlNQJ@_ulcJ@P|`{>$P2%j~TP)HLSc(0_?Xxw}{0XPvVDv31a% z*i{bwmqY*M(0_R+^b=>e77gOdIsAWROBN0~s2S86KVT0p4!rkid4o>0`^;84 z&ChY_pHoo?|LF>~u0pMJnjPje`)-HXb1I&pE1nkq&+EVbH`YJ?we?>q+Sktf5Z)uP zWkApe^F9vpMfxwt`bX#lhyB<8Fa4Ke{iDPG*WcOymt*}S@`3AE|L9o%=ve>wSNo3m zyW4^3CymqRz496nH#~Rg=vQ8ka;$%J=)oL%Fozz@;RnCD%ca18w!kips;&+_*hBr` z|8K8antGplX|Emi)jp+buw^o4fubqEq z|6j-f`>)l1@u9=ex?a?AmI1ACvkYt=@uA4(p-;{GFrqsCYWqQ&ux!YuJ!=n!Fw6Cj zmOj9gP=*5Hr%?g|O6ySq0!kZE0tX5x>Wdtlx9vl;Xb@qQ7Uh;aY6R6`8V+$c9cV$;SpVL z1xwN8X%3RBD*FBww#t@I2o7b&;ZD*`<#LrcLkEuTz?b3-5#LoLq}i)|mlWA~|61Q+ zi+uVhu>BT(!&tXr0li_< z$kePk#j^^t()_&=mkP6$!l_N|31|41@7BQqDP?ao>|Aj)Us`!AsIr8J;eRM70T0Jj;H?h++_9n(({7Y|QT&FHe1v5>*^d>goMkD2R!#I6n)uEk- zj)FvskF0>Yc{M|Lkazs)bH8dCnl6)<{ z3>3V4&^B7vTN_)BU0r>t5DgD56S(l&~Vnx?e8vu z#tTNY!?eh;r{o`5Q#l0suiqp0lq4+olnf_hcmI@hHfr5dD_3SE=)W7bYvnt)_XV^C zH)KmGQXIjtV9x6KFPN=rj(9Zl9)9lr1)qLXR!M{g@mH$?MGbzvKc0K9VO7D~`}2F& zlplYl>+>^dSzgy^uv6k*UJhaoq38NG_9?g^+Isoc%kQiVeJn^ZZC>3`K!iepv@^PN zh$Pv#Bp-8%Ai_RhTI}?7|LDUR&6447FJFx2CMN86>@GasE$1pN7JkRRhO)ovTxBSn z+avuvIQE~Mo5L$KR=B;c_;Y^G`)m5&&xPye_s%nZ=lV;p#7TG#Aw9*HZHS?o_mIs} z!k;^h7s!$JleKMiYv?B<39o!rZh?8v=u6j6qaBGug+pQg$+d2rNLkoAXE`T-V&#%A z4$inMln|Ay@6Z$y-muaLe|{9qD2`Kt0P&m*NmT>vHOanVr4lHVYTR6ln8F1j@y3So zK+y@Qo8_L(F1bx|1Ls3QSFxxYN04g>RD(a!&IdV$+Lq{8109~1H#@&~Ze~_N@wigG z3v#i!>f&VBEwh@=k(Ym(-swp8gwXyWlFz}t=84*}r7Mp1JG6Ag&J<@|6!^$2%qp5O zt1u(0Xk6)5cXaF%=cag_^O+)^a<1C6)z+^j4If#^m#o8&=I`^P`JY^miSD0=tj8?u zd2no4{l8&9N>0(-r=rt!1SJ%l7Dv~JD@$EM|!~ z4&02%J`soug$=vvN;)f!=g5gF2IV=OUq;5CF>w4Ro_v6IcUrq!eE8e_CH~6y0G&9d z;T@sNkeJkVKXyw>*dMm^^J9syIW@n*RIiDo1P$l+dulp>GqO4Dw8$lW|G^W2;X`7Q zZtavUdk=3=`J7TPSLdXb;0-FTIA!ac=IR8ER>d<&t76K@%Tjj%!-f2lbv*xKXl1v< zb3>Xm#d~jzjz=GL4*eYTLNIj1!vfOjAe_fx{PXi6?aJ01EthknkXpL6Kv{)c@fJM?o8^m7xgn*RCZ zqPK^QS6<$9Ir)h#4*i_NF7AKTF3zE!bLi*hRH&&6zZ0JBH+AlpB_0J5k5Ag&+ZFD8 zNr#=>-NX57r2Qtp_3ho$54Dr~75ce9v|iMqpZkyK=XQQQprNJkO#@Z*LHN-F$JI#v zvEpCY&%F#k64yKI=N$Suq!#--*w5*NjQw1&js4slz~$I}&fj4_7k8qmPiy=TWBdTU z^hB`W6C-*_erpo!QMligdVEKDT%(*e8lCPa+&__ed`)>QP`cl2cfTz4aQI&PmA=>h zL;AVjw)V96H}Ac97@h;a_qT0(HgrR6_ul-YHgp6p91QHnsq)o%S%v=O`dz|wigs&w zqeM>-YbX+Jt4RrRU?)h}=kv6HcX?pr^rStT8cu={TQ0AJmUR+%YiUu8uvwfZY*A{Y z)eVC5e>59Kp~5CGuj4NgJW=EC_vAUgtS&}e*|}J|PvEbOR%)EN69nG;hAYJPG4Es@ z``q>O-0+3rpB>HRl^SKkHp&9#xH%n&iVIC0Ix&9q=&=c~?`Ed^0Z9^XV0&lZj2U?| z3cdN4*GJxNz8&0QH%E3;|E4C|$b0>q^k7NASy|V-SmBqVR=wLrsYj^LWhbXiLO$E- z9U1(;f0g05@c<7W9NDEmIbY*A}$DOzle!w3dd%0+aw$1Jq_Y{>GPIBN3{uR zHDzwD-@0tlxok1Q!ID==SAW5Hb%#mHsI2dXb_{(cEfE^1h6Y?WDO|Vc%nbk!_sKTN ziN;=pzsnGDhsiBO=j^;0D)Ua98B4Fn3`4ey(Pjg>yv*q9r{8_+`i;ug6_=l_KXmks zd_}RU)12B)3phWNMH3Y}T>RHeSu?Wpq*eYORa14yC;%)1R^GWD6GE*9tAMt$o#$2@ zO>tg?cGfJ)QDtTorp(C9${WYsC<2p!$>%OU`SQhy=Pp(guO*a!Dqra|!T0L*JBghV zQ5F4%wrb29aHg+Jo4qn2W@x9x2{9qUGE^6sBoxk7%*ZV$hCMhZ-++dr?xcO12#xm- zA;6r;VN37__9k%X=^p6mPS1Ykz;(gy(`6&yYfcTFyB+E2&SE>d?_kDmX-9X^!jA4H zlsW9^bh0Dj4AHzIzARGQLz}RS$7vEaOUC(E@djy|;!bG%Tjc{xyuoKRan+gt9k*Ls z{D3OnVDJRhUNXSYG)T)EY~YAnOS;h|-ENe0-4j31*c5kowZrw!-6AKPVYtsF;QJ|DMJx2(hqqWmMyX4rv z^Y`rE>Cn?T^mGnA-5K={?|#z9T~c{6KIOTY7h(vvm0!ob#h1J%|5tjtY?zm@c61i| zd0N`h{jU8y8`5WW!M1M8#F7bOtqkYDnr@<4Yhg{d=7BX`V&_wIMc zm!`yVvnhdd@?Bs{ zLWtuMhf6?%aX$eNqJR}O%Zd_)tC9j`TVO?js!~;jQ?rT*1?+EN0*+s6KZgYRHTHA=?e(kZ z%-FMoq`4=MtjOLE^~l)Nags`)2t&QWu3tr%<@(h)$fJO4-;&HJCY^)Rh)@twPb(mz zfYO$MwPRBQ$PTh?Ia+7hhUc7jpaRP|r_o~0`6ZP7Rp*=|;G`bCcB3!RB>WrOv90Yc zToicNYyGk=LUAHVzqzr;dhOBCOBYXU6eq2s~nkzw^N9{Q2t#NK_hvO>mYqxZu-SW%S&IaukEbeeF^#$#g>LJ=K zgDkOH=AZKm?bcPdT{}c3>HQU={6+Uyh%VLSxgVq5_hj>S3JOT4S+GKMTO_54R`3SF z3eiTiLi8%Ayo9%5g{Y~aYcd%V*+$;xJY**VEznhJU zvLz>XoD5mA?ZlFT5o9V_6w0`)UgJfkz)H@WjcqrNUERzd+9fJ(<$yhsT~YO$`|pa{ z+k-Q$VKl71e)WeO%qX=>7*_d1q8^x{=$1VZbZFNwdKQWS(G~apG)hq;tuuhbG%ae#fzDJUi@sv0K@RoleCnQ(xz*JUhKm;v73a?ghYk;Ga-6_XUW(z z<`0KZsf0KU5?Qa?blo`S`8`9XUE^o>E~4Xa?LzPRn*xGR0^gf9@BXuZv%it;`U}7N z<3aXEzWZ~!6Cs38HgR2ORK7s;I6`TCxC}bnZd7M1q zMmIj6IKvOz5W|0;FC&unlx?b?xoX#srSsN|G(W5xs$~rm1Ir^`#M8wH6tak9CMst^*dz^ zt&x}f^29@;q`c7kA6MSmpz{WDntnUyQ@1XcUv4O;-C{(!tpa2DmBx!ScdKFNxi{)J zE?rT7D#f`p9DV_romE(rJELG6cfB)OTq#}yYcs2jb+E27s=_xhE%d|NiD^e-LZrvw zXPA~1Cl9^P`2O6Cem$9;oAu1_%yGr4;w)xy=Ezn4FHi1z_Q}=$A3-H!(Y$cJcmfiq}I zh%9ZGp!5k()x;>gSh8ZWUp2F2u;iPNnzS&6T}hWL%RhyA62%dnCq&|cO3o*< zQdw<~IQo^9vE2n8&_HWtLur6q7yR+}!AO;}n&NM8)<{-MMTrr&BGZ??=(%`7)x@j# zK%xJ{99qyVl97SQosn4P)>-9LB%CZ0kp3n1C;dAw?4HAYZsw~2-G_8v504Du8n{zJ zpAb@r3WygVc7%d+5Ix~h@+y1|ABOlJ)4xD_Z1_|3F9)G@G>>^$K)M8kv+Ea8+Wfu7 z{=!Yfk4_#v_P!3nT!xq+aEJsR51!?ylTqMssrEbOY94RP6IuIRP{7Oh?!hx1LkU4;}^Pnf8>{sbP$e~>MGFQ2l zjPi*UqJ0|Wl}S1uDn7At6X6#nznbK(^9*WM$i|dZUDjM%#1Bjqi~(U`%0>8BnNU|d zNx5}y+IE!WQRrNTLpeHE?^30l0=f|Xne9JxoWk^ zWE`6NEb^lVa3wX}rHdjHQWMfd)cVeiCA5m44yuCkho}mgZf%A^{_E%oU>iMo~hVVGBJ4M1qpd9Mn=+Z#`2Q(gKiD`RN{e>8Y=dKa;fNH z6OZ>`Vqu9IN z&V2*>ABd{2?;-2vn790a?_=bE%2$HsEk9i$G;ML_d5GPa33EqU`W(7E;{7>SM}Oeu zR^I)4_tHQqdPa-!Gdt1dnT?d@>@$1tU+kG}{+@Z%Gh1T+nO#i%mGrm2^7{^+%V^I3 z(C2bcn8xyPeEuQN;xTaSAAJ^w3KOip-Hz`LRD=q-4>6ysO@fEvE@VD;I7${)xQQ3TNy`kei)LUY-KG6_%Nk{SX@{5_>i*75?I znC~fZ>Ng2o{4JB1B^^5!e^05poH{FJKAY%?f}xSk*i*|(vN4D8=S^jn;%pH1*plw& zbB+ICvV_`tL@2qUn*M91*|t?s&ZEr7_5Fl7-W?dwER0XZ`0}aQzI?GS#56QJ{arzw z!qk7bW4gJW2lYeUsEt2ZKPyzoFs6Ps|7$6D12W4s7$1)wZ>ZDnpFfoda+cqhlS_8& z$o23>zfAqAV7$%LuOP>m+aY}zs{4$=|5YXM&G7uAc$oh4^)-J_0Hb`X{V$R!;R~8=RH%X$u^#%lmR>SmUgmRHhA%>mjqPaaK-gjt!3a6$REf zE2l(lgJXWWh{e;)*CZ>a^cicMl~ZAh<9evM*8HrTN*=7^S8c+as13=$6fcjHO|UO8*Fg)e0N*p ztenQZHaOd^4bIAGvc=i+I$&9k#kjv^jk9u6wm7bbYOv;K`11PW5LtINLurt#MXP!`C)A=BK~2##uR~-`n7r-}s{?{$SkIKUw3fob=B& zINL6l?SFK>X}+wS#tt?(=GVJgrsoX@%wW6 z+u)dA5@wCFa_W29;FzE4!{W28#=Skt8fWDs`r6>Q9wNpXXXTU*u)#6E!UkvMRNCU0 z-xOzA&x3K-Nv&~KPQ5LT>(R$s^RsfA5^ZqI-)@7mauUO=`M<^d>Jb*W#kfE#x<#kfmWTH~yoWQ`4u>mk=zL@G~6Od63qN-;JyZQ>J? zpHil0X6H=HD^M2}&z>`H!Eew zjE&7lT8^D~xApYd58BROykxp^_4-L?yKi>P9;Ba~T4gx2kvx}?9&E13a z^z!!U=-Wx`*V#XyOV@5xU{LqqkkH4%dW83k=+(QABr>XRbibJXu>%GUiW@xSaj8rm zpD;9WSkmwjBa>4`jaG~qJ1%v6+JuRdo_KQdl&79ns?swuv$Ch=uHAdy*t>6k{ed?R9(wC-V?$$8^Wh`!v>ZKl{KUz3-)lW} z`pnt)Klrfi-1!R^Kf3g>>GG9Nu3o$T>5b1m|KjGCUwz&F&8=^5e|P8myFdK+k9+_8 z3H@eeHReeDWEtA`GvD2JFx79FWWF9*o_qC7Ip+XFb#+WRTMvctP_}%Vb@^C~v;5?C zrd+a%p%k0Pl)|_a=M|W?zs~R*4GdLc+=Que2QJ6d!1Cea6gaQPls&&UZR8{NGWD2P z`EXu=snW=lOL4glQv)uS>|x4VG1cv6@_I~ZOx2hwF{LooDTyhK zsqqw3Zu*#^x>kk~A275X=i704E2esk8*$!*^R4XhCgykpF8{Ui5m+wC`^@pu)0pCV z4WBc4;xfju{D#k%yb<#$Sbj{^xIQJD$CSpDmG70etou*>HB+zTCPS(37)sw}s1BDK zzF_i3=O@hftD4VHipNls3quvS9wX)_MGUUQxB}Nt;CwsgW98dmw3bid&K%$F#!w39 zNpB{v#(4!US41$lt`9En%}_}gLrKi9#Qc&T3{G@sDAk3bdR(r2n$+AhQVIIqT(#*~%s%Vrz-Qkmlvm{Keq zh3gx~PzlaUF{MT`cq_|?k2B)D0#gH~dX^7UHKsJCtb86vtmRWqVA_#lD#4V()R4xM zlj9jmVMoFF&Xbt3{f8)*%O#w^re+mSKqP_6zf%Vn!d)OD z`Z~E2I@oorw~H4MAo3xy-F=B}o?>E(PiLaPIDj}2(3SA&N)c1L1rf)oVB+zhP@<`O z7%?#HAP$7}CMv=uL~cYBq3Rt?6i8x-b{Z#-|fsq-7FkCT0`OPvj5{lcy0!pUNXXQWg;R($z$0Rw41!)MBDGcQ*0O z^f|<+f_cP#^#Vdt^c=Bw7EO$pQ%c;NrzKu~ww#zkR}#H6iwIG96>+cf1>)Xf9U*#g z8PR)LHIcsJC1OiW4e|4u)kN+qYl%`O7Y`6KFCQdS*WV)YzAzHi?Ttj+cg@70 ze;k4B`dTc92GUX(A1Up`lfn4N=p?=z#z#)O3*upX;%S{Q0mdhR4iF86@fk{Y^Gt;C zNu>LWhr##^qrJK&!T2Q6$Eo2kKEvsz?jvA)M$p7#BVl|-(iP#!Fh0q&s&@*EPYS&} zY7~smDEhJfqhWkT(-#IRV0;wx?7?GTe8$jyq+?-x#?pfLaWFpP=%0qB!uX`poraHx z@flC2Ca1ypq|tATo&e)BfsPwD5yodC{YBa&7@tXW^Ak_N_&h-$edi>62l6 zCeu$%odV-Ch5lyxQ!qYH(fid;!}vT+@13QD@lnz@=c!jH+FFdr*qmW_Nyd>o0X1j{EW#mE1b<&)aTr^j-&v*&^3Bj^1&@-04TJ-+loMh+5F zJ*KUP7`(lSp}IF2N;fi8{UJk5rx+@E8{=#}m|uzW3QUbghR=x04VbdyD?4p1AMpvp zFTH|~!&HBr$ty55U1svs4a|>^)8jn#DT5pE@$HyjkMlZAX-r8>36^33+im0{zhLT> ze9llKrn=9Vyb_n2aGv;*!RfCUs>6BWCX+Yd0mvmt$?TPtFh8jI^Ii@5or*OFx*RN#Tp%{Jz z&a>agtlTW6FIe|4i{Ga!aQjsZZN=2MmdVrA4=<-)VQ{G)ANMjt@7HUc7)%f}L;^ep z(GZQubI{}P>oY_tL?uKTq8_3Vq6s3rcnK0B1yKS~3Q+-33GqP)`++$>38uP^lg;B! zzQ@Re`o&(~pjzsFVvbMwnW2Vp%<*gsH#iyQ`V3r#66x0Eg**mt;xn{;wspB-IzA36 z-@r9ejWt z94*y&*!d2!gCiFL593ES)x&UfgFOsKH`c>&sU2Kq2bbHy*rccJS$T@H{(sz8$>44nD&UuC{~Ew1XGg!HewR#dh#ncJSGD@MrAcbL`-A?cnq5 z;PdU^3+&*}+QFZ*gFkNvr|sY+cJNX=xW*2ywS$-0!O=RNhh4W7cJN9&_(D7QB0KnE zJ9w2He2E?W1v~hQc5s~?e5oCLnH_w&9lY8OzQPXvk{x`d9lXX4zRC{1+77ogMrYJGkBsUTX(mZwKFC2j6H1-(&~hYzN@I%HPW3JV-!b;68=RH@stwM{DYk>(mmkZ+%HPiN z^C1C&mH#%R&GKWMmH(~{&dPt!2503*-@TUgu=4Y5@L$M}+hy_l@?)HSo%!BYZel3? z4nx&AZ@{!2Q^{tgT#BgzQyr$1ktuKA&QNj}Lru8cgz;8PjhHHTGklV_7^*wMP+|+F z&@U($eV#V!6X3MX!GP;;-^%c{VyeLP5go1h@nQFg-Q)53qITG}?jK~4X#JFFS9zA9 zYD{TN^_UtkZN=1tX*;IW`^@pC^Y}bI$Mt@}P$@2N#pOm!4VWt07(O-TBR|B)m4gdXmaKhg4tsgV>wSLb~>Lx=KUt)^$G^YBm8Qg&LCQREg zrSNek%%{dwf~gc!3R4nO0@K#7nEG{?N^dcFDX!P{yx2Ul-+9#d>-tYIUysH<3~j~K zgef6ma0*iirV32en9`UM{TP0ICuW=^kxX9Km!ZS}T#oD4<8lMetD~866F%OE>($|M z5+84hW%z9Eli2fSsdNIvM^9y_0_P3cOkRoeYL-sNe7Kyzc>?F#b8&qbSLQK!39g@> z#^l>^xe?k%;$6SRo)LDgjb0bh0HFw4=D9p&4m6=72 zOGth?UzJNHl3idbMvyOj2Q*RfaVrVMcjoHVhQU(WzQEin+=9#*&lC~d zt_(l>zc@EPi$MR1h_P9)RRJL{%u-D!Wa%>si;3Y=3uY8%5wg5zRC9|coMVoZ6%}O_ zn$J30m76!KFpE+ZQz1oESV+;pkjx$tRB>VM)Tvp8S(#MGEGQW0=0Z`Ag%mwTxVVHA zxwx25L^f{R(6On6%G_AGx#2>y5V=glDs#h6E64VD*_fE4O$c$OHk22$E7%xW(CE!0MDx zpM@0l#zl;z6eHefXXd`L7xqmNG1^iT%%_d zQ!}!u{H**LFaSdf3uhEk&>5NND#$LJkxyl+ia}O@@^R@ig>Z>MY4MC-mK9}XO-E&L zSy>#Hngip5E=J~31qljf6jMdB)TpnZFUJ>5FPQO6fw`};kOa^dT9+F?S3}$gF%x1j z#0U1JjNz!clP&&btMZDnhypmn<7m^JM;cHgDPt zo;H>5X9%Y9&zU^cT)sd1*Sbu;oxxM4@^o1OwO>CC6TpuRj?U$&|DEr2e$BN1hwtw- zeAM!uR8tm=jR|yte?5D6hYY@BED-!VzsWqubpGGpyvFmpOy?y@{iW5vr2WnH*K$G7 zFD8J9vlX>`C`ZT_k!fRwHn8mkd{gOGC@BP+)!9Toz&kt&t!fTNFKj`_t%N5A) zH)y}#67lCFDI|QJg!uVhJ^c)?-uN!>G+Wo$#75`xMKUnV%HvNOG z|6qqd*zFJY`h)poI5IpsK;R!Ra_lI6o4|0vc;BcnfnQWmOpu@N;M?c_=cDWopEZB* z#y@!5AN;p`yZ`k6X7(%PO>q?XW>1-(!Jnr|S-DyBQfCbw@xcT3ue)H1AS}aja!TgB z!Cd+0-2G01gH}okj0%Vx8xZCf`|o4nQK7yug0Zk5nvXs{^rA-!qJJa47y7$5i1;3F z^1-=5#P=)_qVZUgG4-*9bp5W2o1dj$Mc=T^u`;GPu3kwM0na%zu zM_A6zo;8V2VSK7e`K9gTw3OMiQ`56t|7~HkZ)ikF051z4Q@{M59z?r($s?pUUz59Y(%!2~w@Kbd4?&&%Y~=l{sV zRp6JAo&M`ip3JYGmufj{dJeBZdd9ER^UH<*P4Qc_N!e4U@`S&WcT7eGe-F?8z55^4 zfA7cV?*DoHytF}iEwkpO%$=8=X_=KeD(4>@_U#U=C_-8J^9~V|9!dr+IBvFL#Iqi|K-(`zdQe-i-0dk zQgi-~OCl>Xb@Jc*|HwV4@4rRDpk9gs#RAO&%{7_=O-;)J%QcpTmTMIY6b1i1_TT+q z>(=n2nwkQBRe|MN%feq{JfA_@e|Qb@=V|yI2D$%3_xJqYd!9IWR?$+Pmx4G~K|M$AT`~0c;6U>95z!$1~K{l1I zFZe?9&kr*SCeP=8G5>!pQ2vfX-s5v8^Hplb+*v7nW%wsLr=(`_g~;!k;=iW;EciP~ z{EtiinG{6-X3v)=se@siIww0NeXzXYMNLo5%Hk{Jl-ZUGQ|AtTelz&+|F@0*e=Pbh z_Vf57oi=@1+W*MrpUJ^}{yF@7dCu2wd{$3Qo$~+K(AhFIXY%ifSt&WwXJyYC%#wC| zd=4i4e@y+mn)?q+4(j;pubNr@b4>oR)F12c3}#LGW90wh_s^PNKILCUWTjdTS|jVf z=zdj^zqc9O@0SlP-E-_*J#+qTU+nJ30qWkzfnhuhwh#WnJO1EPJkFXsIq4s-P05<~ zug;$Wm5;VTyZNOIz7$HCGQ~2J&w>2QA!-sE& z0h0^ye0wI4i^v7tRZD@~&lR9oV;yL<-vZ<#c7u)uhd^8YNzk>c68w-zLHmKjl=ZU@R~y`b-$knSSnXqgL&bPu6Q3$JU?U88hpg$w$0 z&nRR1XO$VP=x;^$No;9ZX9s#fGL#lsy3zfchSA*`-n3#FLJQk4S|QDcmU-<*5BQCu zf1V1aPfWh$5dJ|Vmd86oK6d6GwHr*S+r0( zpYGOKNcT@$LJJcM=su+)T6lUXEfcqlmgz5{W%icQ{i9aU{Y~YxXk7&@bYD%&+*?Br z%vneGYiywVPW(m7hHRqy-fX62inr1N)9tkA><(HOxQmwgu$val+e^#J@27ir9iT<7 zhv>el!?YmeDBWLwjFw3|LHBo^q(w!iX&J?{bl>`ObiYw0ExVJXdu=GX?+BoK9T{5o zsFap*;^@9(RkXnNA}!o~iS9GIObgdtq5Cwh(J}?sX_<~2blazD=ib;M)xgm zr-k=AXc^6){Qh0EU}ZPmd##5S$oA2FBl>yz0lGg%zzDtxnEnzWBd`=PB2vT%LS>l# z*D{PSN0t#N%P|AncyN_x`Y*^c17Qk`;I#rXkgmuGdK4L9sS+d5Rc3@ccyLf*1gBM) z0Z5hUXH^+dpc>PELyZxJt26!g)EQBX1|xc;!SqLKGW`!VnSp36X5g+CBMjAMgg3Mq zfxiwTl9nq%JdHqsIug=rR53`iy9)J|k$;XZoiaFv6!ij51_I5<^B{XTQ%3lJ2iS}eY&ByBdU%*<&I~Z-jL^h_5#?Gi z!pA&#STX}EEE!>gB_qJC7|{kRM)-xtKGuwABM*(%%m8Y`43yh2{dG2sz}c2xYs(B= zv1J6>c8nm=ju9QSV}#%Bn0|N&BU&yO(zC0{)Wcn)|8R1t)Mqum2h~juy?Zot7bYg^UeA|8~BN{)H5tIyN`p@(2 zw?ml$HD_i3c4kDAof$y|kI(b{XM9`e!t~p@FrpwHr@Qcb@o)n`wHNWQym%A~AJZ(Xq8&j0c^Wk|E zr1En-&qAK};2uJ6ew^QPz>w#w$n)uRWeVQ&^4;fUWBK+WSEg_+FZV(or?@hCfqdJQ zAJ^t(Zg*jd>UjMbUf1nBEOKEA<6M}0nAcyI$3J)*-F9XQ_w%^GnaLl|+s@UQDUx$$ z3hIV3!c#+;!os0UQ4DYIA$+@o_rX;sW?+L8BbdyCs}obu!~5zQ@2j;uj&o#0HjYgG zC*GfDc)!kfVDeB0rf|TX$-ijN6fWg)03QP~_Ke^P9}`7XVj6!h6Kd9)obA{&NqwP8lSw`TJBI3z|}GgV!DY#y~@d}FPcLPaZv zAT1f6$(BsMh9$4F1>-Z-f*H`TUMz#l)2c* zpOY0POun`F~3Fb(GIb9H9#G<7DwU5$BDpvH())fnL>Rpzy&Dr0$6g%J-|VSE{7#>!8b znRHW$c^jd`ym_q16vituzI+a{p33K;Px8#jS@MievmCQ)t{jusCd<6emSrw>$S_t5 zWEk^K5tB5Zhjt-zAxp@tYZfq(83Ly0=>W~$@28V)_R;YddubV}hu(Ffo6g_cMf+|1 zNl#hcN$*(HL0ipgr}rnc(bi*H>0+#f-r@9v_B3p!Yh}OF(&n#p%kwYvq^nJ|?CH<6 z%$84dM&U=gEv=D$9R7h;@ou1VjNa251@Gwl@88f1ufL}AkJZz46|d+$887K45ijVu z9?$74t!MO`=BM=4yH9BAlaJ}w%OBCs(;w1ufe+}h*0r>-{~jG)cb9fOUqjDXb%zd1 zyG`Hry+!XdzDXyyUZ?YJU89}%U8VQsT%qG5FVofz)imCJk;Wfhp!XlCqU-ZGdT%sK zTRKSTNxd{}a}Urj_E9vkKtlTkleE7{CB6ImIojsZS^CZTGjxCIX?iboiWVxJq?bNB zP7}wD(LRfh(!QZb=!<5D>E5pg>BZaunq9e{u1efTSGn$`xqkj$t=UEU@7zgWnze)W z#kbQwYTIbxi!HR^_+~nP5q}>CZ=_|6|DydruBS1uj?ODvOD~zQhL&|$O;>eR(9)|b z>B3FrboEsJZueeJ_sf^jeUD3M-$Tpjz6Hg!%&4VwpJ5U0_ql-X&(5cXMoZ{L%tAUp zF^4V|&8JHbWYKcLbLf)h*|cy&I=u{=L6^LoMi-Z+()n(a>D(vDbZJ2%UE~l?|E!Ir z3zm$h6&%LW-4CPar3DdmiAxy0@c9^8aYYc_<2{O&|Kv{#w~eHK2K&(R{WvXqb_6X* zs^Z9YO>y0(>i(pgSD313K+2@)uk-2|n- z#+t&`$WfOq?@M~BHc4vwG06v+zsO+}d3;#lX zLYt9+rmcw5-W`Zi)NZ7=YcJBW?*P*7dl>0>c@+7ceFBkFK8ZFaRtYsN#Q1w2MX-A@s9 z_&L%t=Ow>aJtFt`4Wi!v4(YQ0fV7YLh$v0^jPxw}f(TcALxkI#k?sR6h~nWkr0qxt z(zfp>@?%>!(o@=tXfEtW6x;-;oRtt2YKc(!J`t+eD1*w^$fCmYa;V}ad9*J_0qq{E zh$;+ILiw0Q`(7!dG7=S3utF78n4pFZ*sG&`&FW|`t%1rGXrev-T4=w#Hd=f|8djvn4qHlCTOp(DJpzv ziY}gShRSJ}qeZ*S(R?opbm`V%eF!DTW!$7 z*|um`qb(|%Xor?OutOIH3_(SeLr{T@J=#@aj|zXp=imcp=cN6j4mv8Mt|1upyz@X#Jix2cDta3uU*hGD_3+N z!4>V>?1~oDx}v2@Zm0lvLxq`cXxSb&G_S@D?d|6KL)=k8m^<1%*BzDH?2dL(?&z{Q zceJ?E9nID7K+BvxP&t1OR56Z+*&b+ao(H;YwFjEB-2+{G*aMY0>w)%D9_Y_1545z} z0~KE3X?W8tI~H%@k_?G;Cg=j(1ii=bv4`+b zX@u6e8KH-c7^0}PA$n_z0cx*lfUaMrkACUWLp5gUp;PL0(X0qvbln9V^tQ7OdSiz+ z`c7FJ?VhiN4tuMKP6*LND=Ib6`(_%b-7ynfi&an`{``z1 zl+m5Ll+gBmMRZMqA{x&qps=9=nl?`!y>V9#O>mM!J&R>g?4=A^<|TtJUm-%3-wSy! z3DMHk0<`A(0MeYAX&-Vk=(kiNM`gFWci&<$m+n2NN?2!q!n3@^qyafG&`?Bx(=;EmRnUI<(tcq z`Fbmm{556BeC1Lkvt$|4EGR}Y7Zo8ZI}4ERhCJlk%SA}r;~b>tZZ@KKb1q_9oq-rs zr6bzRbi{(1iWr}tjF_J1?}#%ANY|M-MD5&or1^Xd@{@{0zA<4)N7Wca?)qrN>P`Ui zp8rGJmh}Yk>Jx^vwIhhK2tstVJdrP!9*F5MSH#$VDDq*P1M)fD4iObwBSzaSkk{u; zk^Z|z$mb?~q*qB7X?D~?ltR>z=GiL9=XHw6XIc(Xej`G()dYxIW;ZY|VJFwpU-#@{`&>A6_iUK6m;(14i-j2?9M*Z^52M8>+%Vi7 zUh~clUUuFDo?5I07mQbc9SXXki{n2)Wj?h~#RLv&op2P|y=fz){H6%XAQByLok#TiXjtZpLe>weB5d8Q4e}9sW!?$$q00$Niu#9B8A6mQKppwTCiE z@27NX1fX@Y2xxW4fX}6Jpj%4;bZ%7yLMvsUv0DXbTdM)VW_6&bqY0XewSZ}-Ht0y! z1#fTZfo=~2@Z~Q<@UF!OsD+yVr30qGsMieihFE~6t(L&B!3uOa*#Ol{Tk!gX9q4Kr z0)E;$faX|7&{pmQWSODh<2z@drRE9*!`*;xggY?J^Z*TI!$AG+;h_GEC#b*V1v>9| zgWe|)kbe#X%~uG}eTjnp$0I=79SoRU#)0fPF)-glfG;b2Kv$+O(2f}iM+5Wr(LhKA0lkI6Km!^Bl-qbX8Uo%YgaQqXFu$gZCS{?;nSww@bv(do9F9xXHivjX+V?lTQSkN_T958r44k#v# z2Wrp9gZB{=fZF8=pl^6A=-M3%bXDVk{@gh5<53*g;5`wPZI}oKzD)!T{_#L_TRc#2 ziU-|D0@zxd0CwC-09x9KASoshd|sCb%pkqJOYH34W;$AgR< zUQdU3pz&-XNGY8N42DkxlV8Mvfg&F4eDELg7;3$hMO04~G?Fy_g40Mf?; zUEz4px^^7MwHgO3PK^aS(XrrXbqsJB69X>aiv}m6qk-z$mD#3>xa><9xcYGEL6aVR+aDFmE|2?2537%*hW7;w8h80>Ej0^_5Dz^wD5 zL4wX`kUwV>Xt^B-tQ-Qt`+@+V`qUp-y7~i+B0q5O;YjeoZX~G5_63iseL%6M53q_S zz>5Q7;PVX!pJ+T6%otB_Z-x9=oSpe;5bI_Gx2DDe2 zg1v`KfW;+ap#8!K!0m?Mftn%MV`l(%WBOoXv>q5eT^CHv(*Zu~wL!=sEl@*if~$8l zfcI;4VA`Sva%9xN7+qDc!Bz!q@l*zS{z^bTS`nO2Q2$56eC+_W{ZJp(%l7d3tBczBv6G7JYp2$0wNaWTEz}ISnOZyM8|9Yxh4Rb% zOpP!4NWESEftq#TJ@u1(OLbj)O?5wgMfH4oK_z!RqnecKs5;{(ROHY{l+TCx!3H^nW++0OT28NxL=)XTEiP>~OV(Gt2 zGFxwpB=hY$$@|Kck_pR8Bo>(klAT|-g+{`JLS@R@9@Yq-h}%BZ~mC`=M^bBhZJ5C!p_Z&p_rkE1~Xh z0BVuvAjswtWbb?xY8iGD61des&gQj{hst9}sj&`{zw#1VQSk=yoX`M0()k3vzWN2q z&1#0m>a{^zPj*5!cn^eL>4!3HgmBdh5!|yu7T)bI4-acqfTOl4!O0_4;LmSVVZFub zu&bUXeCmJ}?BT5gyH@GK@`3tr{xt)*bfgiySZWLpxS7K6E;HCx*#f?rX$hM=u!42m zZQ#ywTX@DBJ2=+O9-f%z0AIcA2z#guh2?^r;oVDJU>U|0cKPlG*P3|1(SgI@()8hQ z<|IcHsp90}v$tV~t8V!TMAXr-|7`C_;48JKD1J8g$;G)J5 zxO8JE?CKK+Z~qVmSCxgs8;3-|o);tFtrH^Q)t@5a%-krrRVEsaTp11H>M^kFsu(z5 zX)JuPa4bxSAh2IF{ z;M$-#c*p8E*sV4Wp07C(o*O(7wl0_mSDl{-Yc@=T^|j(*B`hA^nGz2-7RAG6`{H5# zb5WRn5)Y6177z39F~LjJ6X0Z%1h~^C0Uqm^0H-Du`qfv2EOJS1G_zlhUZL*hAX~D!AloL!M>s>_)A$NJVz}O zW>-bP@6{ssSP6$O$c4k(3c_H+j!^hedMMoVDg-u*2!S1{#=t#JW8gQNg5gDiU|5tE z1V`Q;4Oh60hRL;~;DgP9@Y1kAIP6#e+$t9U&rS4)Z=LspwUzzgfW(oo&naJcguoZ> z3-y7kwh?g92QhrXO$=X|i^JJf7`$5+gQ?LY;A1OLxcn9Z2Ph-(z-Sm=zYKzPFM7k7 z-Ci&?%nKII^n`8q42L}*4}&d~hVj1gfbXQc!};6YV2|6bFx%w-{>SGTtP8|Y|DYJu3j@iObZri{GU#(#SHEZ~UvlZ+y#uDC} zW&sP9nZsjto533yQ~1qe6Ij047#^x*42!Ld;0VMJ4v#Q^v8np7<6=EnZ=Eju;(!iJ z(%SHn8vcyF(S#dXHQ+7s8t`*%b@;l28axhBh2ICMz*%w1@VDto@bp|oxVBUQ4&5XV zlLzErm2^8L^*^Ipgn>V}Sn|AgGqI-tseHVEC) z0&P9j3|Ua; z2US5zX)H8Q!a$~n0i=CR0*(D#2?^xRL+4!2LMAb%p@an|p{AY3q3Fv;p*Ky3p$wfv zkTre)>Pg!Nom#gCI(cCiRQhEHRARgxIu^VYy1Q^QWPD;HwBpSMJ~yt1W(Kc?goUf2 zO_B;Is<|BU9J&J1pIQc)?JI$T-xfm)td>GIClx}-=zPfO?jmSfTn@CaVIH&~cMde5 zI2$tGGXuhrY0%+ElcB`<$&ju=0;DgEg(jztgL<{2p$!+pq1?G4&|!xl$o5?Tv}?ym z=u9#JRoh??pWh(9MuX-R4TGjfxj}7C&QO7jBb5EX4sv6yp&ffIpz$kBA+7mFkp2{X zXxca(NH$axY8s^mS&UMKb_OdzX;HG!@Hipl@Tk|jslCHHz~YDZo!BPtu^Sq^=RK+S zcCvZqypgbe4sXkV z&EAEA_1?LcE4-D~mU+8PUFuy|y4X9$Z?5-Ht2A$S%|!3Xnlav&t%ALy{e8SObG*Iz zyVhGz$HqH;p^>*hR?~Z5g}nEth;FY>ha0_i2R!l`|MrsCj6J8lybtX3I#9CGOZi>4 z*G($QYsD%zFZ!#hm%q&;&*HW|^EdGaZ#rOGM#wDf z8nrV?pBHmT-OCF|dg~I>=yV||UQtZmo>)p&+pZvO8dj2Dwy!45Le`N~%LY=qW)tZ+ zWGgvvb~|~{br;!ib`P0kwx4`jdXQv39VQk0j*-mz6XeJTr^xHtXGtpPJgJ#OlDrQ{ z{v#}M&0Q(E@;OJgyt+VMsJle2dU%=KTzQp*cU>osF1SgWMcgJ+3~EUA$9G9)!+r98 z@B@cIy<~TFFX=w5kE{{)lj+<0$$72= z@SzHSysF5MGILS%)KCy-F0H%%x}Tql(DNQIJp?}U;8Igv!uRwS_; zDUviy6iJfih$OrZB?_BG60aj7i2*5+oa983?n@#`z_owDV1F_#lH5Kcl6>0#n|^TJ z;QB#6gZw5sh$Lf_MUwB0Ldm)-LP^t3p~NpoDA^tGzN?7j=_|o_3LQy}C$j z-A^*}LnpZp?Ie9lI)2$L*Q}k)OKu~J_qCEOFI&hI!xj<_{y`opZYCQ~eE((l0mX0R zVaKoJr>HOFx~wJ=+whqTJN}7GzWni*zrHnnAgA{Xo0`E?TfxJv3=xkAp`e3^8g zTuqjHUn0YV7fG$#Rpi5s9JwilCF7i>Wa&4W3 zc$UmpJVPG4d5ZKYK1rqro*;#S83g4S>+5;d38GJDVjm9ESW}1x~7mCd6UR#qGa+yNdjr8GLg(& zJ%PNgGmf;{98Df_i6jTkgpnnqLdaLQg2*W;qsXQXe{#;skz}Wp54l8wld_>BNU9Yk ziRIp8tD7fz=&=VGzr>Byv~?jb-*h4m6*-U-9fy$OH#Vf@7AszV3$j7cjJ$Tim^_+e zNYcLgdzP*eGc2EQ#PSJQ$9$q&H=j@uirV;7; zrxA0AX#`z2l?ct6O4zARB?9-S5@$xF5~;OQh$(4Ph?9Mj3IBDI3Hu?FiE&^O@o>x} zV$aJIf}Nd03>`=&8doI~oo2~I-0>tr6HOwFuO$*W(TRjheFA~ZNFcVg#S`Q5;)&@B z@x+tW6N#M$6NyVZ;|O27IKuQ;EHU0amiT^t0?`OhAPDJrqDwrU(7QN}SU++ckzGBO zkot`!rd7ufxg%qUmJ88DtvH%6l|~VF;V9zU`AA~EdnA#5EP}Xa7eVaV6;8Z13@6sE z4I|Ddg%SRRp+wNn5aQD85aQ(fF@#p!7~)e+FoF056GBN4;pY@Y^lcwa4A&S6I9jp9^h~AMz>GY9=-(z2*bfhm4dD4g2XXHcV z7Zb#XZ(`!f1ThhF2`7?=;zZYajIin*K|Gs0g0Q)T68#=1F>5nIWcI^^;uM&GZa_q@ z3q-`O^CluXyofikUW7X9Nj$djB(S34gwOk7#QT6@gu@{ZLQT#wi3pWbBK*fI66Qw~h?m{+L{W%5p|(?wDEuxMyToY*KgH!#hj>S9yLfMRt9a|S7I6vo zLp<~4cX3eOH?gh7S8;DullV#UXYm=~C-IuSjpA&-58_Gh--~0Hy%Wa|c`KfC?X`G) zTD|zX(krpfu@~ZbA`#c9d&k5X z3y+G6Y>$XLY7U8S=N=Tx+Z_-ey|+(%Zt-5Ro#P&{%;R0+@TEJ&N*+7J-u2tW4=c8c zKVn%fu3yQt>=`nfT(IV(}iwrDC18g<{if1>*c8dE#$oi^Ut(=ZdqG7l>CD%@e=x znIq1hpCL|YNf#Gq%n)~eohAmeQpI<^O%i*~Nfx)YC5R0cP86>e#ENH>jT0ZyiV=rz zj})gkgp2DdL&W#|gT)??Mv0ZC1&Akhj}$wu_7UgUiN!(e2=U%=h&ca;x45CgQ~Ye` zFmd87H}U**7qN}TQ1Q%j4&pJfL&UcPw&E{Gti)$xEW{>4GqL9>V{uEOp*TrXU%aGR zM;w}?C4T6tA=YVB6|3)27GH^16l2En;stdw;_R(LaSq*&Z}IEK-cJ{?%tX2IwRuKiTibF@SKDF)Ghh-Jm3G+PcY)lH)e8L~Ac5=W@ z-BiIGP3uRfeLgrMu0LVKgV`_9)ebdh4@AD8OD|4jEK~P06Zbr04hAbqXIR=u58lV6 zw-YBwE3VCzepyx`z5UmEY0CQD(*1cSq~+sjsiyfgsY~qx>65J2QZ<>c(kuC0(%v=^ zd(l#f4e`@pE8_Lo{B#r6D$9zUooUaePH|yH;lo)!cZ40HNU(<<`?FWK1+xX?BiLG{ zaqRK46IsWo6c+tBm93kX&MN(!!(N@UfK`9Hn4M!=$eKS`%4#erVg0R_v&^M(HY;%z zJF9&SySsEfYofQ2eY|5cd*5mstF&haTV%4EMb_?RT}21j$+Hi!4;~$1m%_){IU7&1 zJHDT0<^0dF2iI4!<*y{{30s=gm?~vY?d8~2&n~b>)T&tp>e<%XH>{X`$JTCdV9zaV zWS>WWVq+YdSdE`wSo7*{?2_fptn-)_)vF3<=yLtj^|%pDdR)*9eQrpjKKD4qfQx%(z@3ROEci zFy~gUH|L%=m~;Bx7MyRf1($fwf}3S*$<3W)$)z8*cae+Hxl#n-$K-4{)2G&)))8wiFUOio3AE-eX&BHCY_^;;NaPw#Ca0hy{IeLXQ z#~5mJhYo0QOFgu>D5)l=8>q?MsnOu_$7yiRFV(rHlhnDTjcT07Of~M^S55TM_pz0?d)b?Nd)Vv+ z-7Fp4#cnhG$y$8vU_+(tto@2M_Vl<`w%MwM{oK^d?mhpVHDCOVoig$(yFlR!8++?B zYrN_cdn)`RYpdDF=G|>zFI2o|n}gr6Itp)DmrJkNk&Elu@m{ak%&#xl_4}W*)p5^Q z1x8GvPJvUh>^ad;Y z^BU{8_bR)6%oR4ht(x7k{Sxcwf04Cps$z@Qa_l&WWp}(_*!V)4-DU^a2{$C{_H>e+ zp;5_RIdhIZ8-13A+fTC-HlAYjpp$IQljCgBf@7?=!BKWAd6+#v_7Gd#c7WAhzn@L= z*vDqx-NQ!C+Rgq{-o<7f-oZ)(wzIF_Ze`!)Z(%Q+Zf48DMiw3S7yGznJv(LfI`;k0 zwQR!m)$D^QtJu-P3ii^Day9^6!QOjZ#?HzrWz958*muW^*(*Uy*()Ck*~X;>Y~si~ z)_2Jwwt&iEE!whK$UTcam7dA&J2H#aZk)j?+oiFqC#SOe_fBGC-zKrAtP|K1ljGRL z1LN81#u)aaQxsb}JDe>&7s6_G1+kgLDE3T=Kl`-Cm;GWuux%+A`|~)$_Wbl_>`PiI&=wiwil^C&kul3oRBXrr!&06f- z4t2I}tSWniRAN6FDzG~j%d&Ug2-)5>{nD8!UD9UHHt80X@6ybMPtt-*@1+m-)=P6r zo=NA=dL(@^{+{%3z%6O3_f=`#(2G)UTd8y?|8eIfi?dQin-fwQr^C{Vp8KSu{dP(Z zj@=@CJ#&Lprew8LfBy>UkgLn2=$8Vi#5qT5zkIgz$=4~;XK@pyKKCM}reUL{`47d? z#go0HHa$b7#oMf<=lqSNY=?$aazm0WlqrR-eE-c=NsVZ#6ww3R|CM)m3qL=Q+Dmo5fos*AYt8bme zVqDH*BbQfV(e)Ho;wHtO=T>1s+$HQm?-eY|>jq|@b{qS$;Vxev)nYqeJi?ZDKE)QR zzQD3g>ak4Qx7aNE25g4yM{KG|6BeiX4GZaP#=Ks%VtPym_Gx_=wr^@LmNlkXGY zF$p4k8!dxB)s@3l(&cfl3krC&mJ&WKNg2;Ps)EmIQN@!Wb=*H!12?BM@upTS{J66Y zo-|1pm;Xx--*Z_Xcl}|2pENeYt$mI0l~YXc55=aq_g*tRS89$QePDqXKY=>)E48a9f_V@=22mG>$Bfd@737@Gv6!+>IivRrLj7#cV@VV8lxYJQL z{8fcJzHYV$?jJG??-(*1Khi%OPki8s8yxV$A7pvs>j?;-s0iZ@H89?_2Em_3p!g-V z5jb^i1WxB+_^n|${^cExo39h&lW+nD4Fo=<+y_7E;)@5|@x{BRkHl}v_~GPMKm3BL zKmNJOANLLmzz@^~;P9kCytOe9e>h_l{^s*2+$e1{p7(Y%t`ir8*VP2!cYK2J-c!MN zis=|!P%;Lu`!WXq9ub23oejaCX@=tG(nImuE1@`K8is$!2*clA2*aH;!tv_3aQwu+ zaQw@saD1st1fDfJ0%wm$;He)Y@L5)o_|x%`_~G(Myj~iK7c@oU6$Vkbyl)iVIxPy1 zSs8^pos7a4-ig8kK1bmdveEbi(`bC3M>Ia)KN_!%iN?uE(YVX(Xxx24G=6y;>c z(ZMKu<+3O|by5_rgh$~E^rCRU%XGUc5+~P2;yEdixS?AlzNI??@2ZZ#eaj>8xe*cg zDxC;?>%(w-%ldGW++s`+Uioe`zI5Se{&mD?{O;aS_*lw}+fA#kG^1pc#Lj8BLW5ZrzZ zj6ZFI@Zl369HPDP&&J+(_(Csy##2w6@bbj(t{IM7H4VeP{DpJoIt4piWsEI8s=@}}P-Bg^s$1h}VODtON=tm-O$&Usf(4%FXO7RyGs8*B6t`;#qQrIEEVFqi5^mJNM|}J`Z(q4|!cY8`8nm)3ot{Ocf(JV*<1@x7;R*$cxXlp-{PKNy{8N`4 zzS&9+e>hqe-<=_Y5Bw#G4^!RL(J`QEtaHvAIproi>0i&gNbWyValpEv715Hv8AO~ zG5pG9Oi891tM$2v9m}i2HcMG-Pd9_zfN4x`0fm)Ul9)%^c}#WqIm~+Q8EoE}Q<%z+ z6WBNRqj2e9DmeOQQO55|8v9NUEL#G3NAW1xB~rl`0Ds|(qL zd9C{kGkdxo+ho2DJD9o#i#f3h+ugnrTPrTdhL$bI=GK;C>1HLE>GWc(q_PM*BPztO zJ$cwc@gnT-%LQ1-|Hs~w05(xIy&NKn%Bg}EiwJVGkfTkL*Mp{QdO(kuq^00d(j;vo zZBx@0iU;85g*P6biYIuYek$J3T?NI@TR*%}QBY736;VHb?~i}pwVT}}Jt-it@H)Gj zz23Z;dGqGYo0;E~wnRKD?Vm5yr4^ldX4*@GtJ4NZzO+$Qv(g3+Jw0v9b2HMGh0D@h zW87)Ke^`>Xd~sn~OF=t*Hl1XG7}J8Skf_Qy0FnGPUl9$5IPNK9oA%eP8OJE0?7n{KhS*#|*t8wX9-s>Y7I{OAQ=) zQR zztm~@zo35{^*MTQ=j-T)J}Z%b^j+xWGp<6dHH~OW;Z!uJdKB6m{=sIrWT_4O18o%z zm#$a_K7un|xP4XGx!s*ZTiOqX-k7y>gP<8(nW{#kI#yv*RCs*j!dbL z%3iCME_OCZx4qaRy>Y`rY1Q)=N`t>zB(3XnrS$XgYov3>{!^+-SRy?*;WnvY)H2CF z=pJeDFUzIm5B?=hcw~jtu;2;llf0GEv;Af1yXRI*fyTAc_~T!aOsij&&Y$t7bo94x zNk7ebPa69Bda1d2gLM4Y8>QZ*o25yszLah}a+{QM=690$=^c{)&!43CY`;jCg?^Xj z-}aaEu~(3f`JtD5_PKrJKl>acFT13leCEOZ<+2M7k*oeVRK6v2nEdm`!{s@J1LcuV z4wAngF+|>a_E7oI^~2;c<5BXP7auK$*AJH+V~>#?4adrJo;ptc@Ymzz+LV#9IV{SC z`$x%@8%~tp7;ut&R>~OJSus|geZk4{3wMo^Pg^ryPX2I$e9HET^4&WVynNELROql8px?%g&#Zr?bAC#b`>suw|GX+g_D`Q8XC9X+U-L<(Tz-pPzPU6@o^e>Ve8cK&d3q>EzU^3t zT>XMWULDMp?;emRk9Z(Y9_7fFS8vFde{Cp`U+XnhPQQAp>>4pmK4R%KxnXpnyx^`v zIbAH0A6!x-zcsK}e)u27a^8={^0G5ZWa*_6`Q}8Y>{#rSrSF|`??TX5?>R+2;*V40 zkBVIKxwpCGgSWZl7PDJ^XP#Rg{)}68{^gd>MjrW=CXf8|gC6;vjUM@@L8bDDDW!7$ znWgeY*OtofK3yuKk4oj0zm>|KqsrtVhBEp8a?9l2rN45- z&oX)OO=WW8k}`Sdjb(D)wPo^~mzBx)Ei98iX)Ke^@|Vfgt}^+#^fLL>lu0a0y;e5HTIbRMunJ4$Q*9P+r69dhy=Ir7a% z=E&ujWy^E^%94Mt&yv6R)Gkjcvdf3GX3A5?WXgT7o+79Jk|F2kxR zX>!%JRQYG1qZ5}S`NzIUu9{_&FKo5SWkap<`ZH7Hq0d?5{zqAWUXtZhIZ0l4c#?e0 z>1Mh4UnY6-??!oTu2D|D)*xTDVY2+GbzV(yga`WNCflI7EJZ?qK=(I|s>`Zw!t!;cy~{^Fv3^5zE*l9#;IS3cyIK61)&edLqv zz2#2=z2ws`6J+P7`AhPB_lNXN((lsPbAOe@wf`r5bjZ)rOy^J112_C2y}99g z>5UV&OApt4E6sa&n`Hd&R_RmQSJGt*zK~M>y;<6N=;zY?&P}lH{!^)O!v^W%6F-)o zsrgVE{m2JW>(B4Oi0EDEmJ8mNetdPEboG$`Nb_gDA+5dhHOc?YE0RCyW$BIcUX+%- z^n&#D;I-27)1H$y-?v&?_R}-c4^w0bmO4x0KUyh`9rv{K?3^d1KmYx>wDHKtq`ImV z(!)T`u*Raj*3D!*@$_4!TSF@w8=9;gfermmG1sw7lk4 z>G8EUOAn7+BHeoKjnV}lfxNa|FHK!?tz`Orv2^ljS4(48Un$u}Um?v}beVML_C-?f zvP+~3pS?($H10y_f7kv)`s;rSr8Cygm&QMNjx_uF7U`rp&60O!SQ>2)NpmLDN@pAu zl(zJ(k_P`@rS$dJ6;jit)1=2goFP5+UYT_EyKZUV`%Y=jM@7=ppG}p%`X*1>{%el( zasMo7)v;5gtBh%qf2vJNsj^5zFEUGi-fNJ4eJxQs0%BTB897e6u4s%jbis*I>*FJ( z8@@SCx@YV$(vSY5rG@tnlS;lBEY+9?O7G4;OuF=qL!{eB9xNRMYy1E6Mlb0{_y1Z? z82Vf5;17Rl{qmmet#{4)x^=2&OY4^8jjb&weAL?Si1%8T^{KC zTF*(ppmpFG=Rxe0rq*Yjvs*p0DqF1!X0+b?FK6pPU+1-!CQWI5_$o{5z+V$v=QWIJ z{qvXOS}(b3SZjLHVXc2`?bG_wj9*r5-}&XLGhcXrRqA~&uDWpfQ>#Y5eD5k-zZ+M* zRC&oNw-j1cwB5NXX|S$XIjYy0D>DXs{d7gcA;#nhU!_bjS6ScL z{-AZ-)GgM_k37OQZ;u6eU;1LmA#`{tO-ZD*f$lkM6C_t;DqK4v@b%+6R$v1XIzB_T)G&oeDqr6eCK-f#dkNL zs$NUbw};HXJ=^CcH0-pO(U6B2Cn+JZbIzd(1r^aZ;7%rDUi{l7x9mwtt6 z&0CS-xvl8Ag0IoYH@-%`Y1`0+FKk1%Tfaf~-uDf9c<{Gq^_*|fXYYTDjyHXW&Rz5! zI_RVC&}(D2qZjJ8qXCa?M|bSljxL+;4wO1}2f8+M z2fDCq2O3qg1I=#UfzF=41La+?18swH>cSo9UoAV(_SzjtJbee6RB@3*85_vU?r>bGn|f1bAu`G;*oci;CldNbu~^w|qr(XYi@ z(V_2ug^V-5LcWi`M32w-5{d79fnF&30xey;1xc1I=!E+=qqm1`MjID=j*7Q_hK$9Z zq2@<7q1+*x&~*(P(VW*mMZb*s6diuvC+O9;HXzGM8<4N*W0e2=N9ccte}pcc{vq0W z`+AhP0I(XHp)f`-q%8O;hWLCtkHq3W6&(InpuXv69ML@njlqd#2Nq2{7% z(U*DGppvY`=()73QEJLn=tbj|s50RSG~(pT(buCcLmwY^Df;#3MJRLVB}hKvVl?~E zi%>;fAx& z>J1_E$0v2@EoW@-bNCssb4=*idkm=Zy-DcugA>s`sT0xFXN^a-_n(Z$ zZytlTop2I*__PyI;8s{S{^<#5!>HrY!_~*4>mM0`uKw+4bcf?8wD!7T=!7jp(3O_K z$Z`2VH01Nc(UGZ#p^_U8MQ{DoAD!(!7@hOvLFn-jeNocF-ssP*0!mx{Kii-S{;=Ix z`KxVR?$0)9@{hKe$A52oW8k;8pZa}m+ur+2+cSMO+bR#)WZN+G6C3y++Zs|nuwCwa z*LGVytgXK0P1{AQUbCJ0<;%9I!(X%+OV-*3UcSb*<+W#Q?+lh~t4>>KTlKFeZSVAY z+_vS^6*i;vkga*-gSK}TEw@ek>@jTHC2>uC@)YywW!KkjrhOpIl@MS6yuT__zyg3)Y`+vzQjxzI^6v+u@!$wv+yQ zmhG3@>ujssLEDc*0=8o}%(4k9PP4sxWx4I+W{+)Vjnj5`pwRa4?0nlx=jPb{b7Q8h zvt<9>l-CcS?Bz=!urjV4_cRAc(3(_z%uI_<+obj zJmW^|C3CK|9=hyGtGr>6HD%(3*5{90V7>9TX6wg7o%Ngve(P;5r&auP=d#W|T zm}OnvA6XyjZLu*mPd+N0*m(993r8d7grCUh_^D8c(aK}XyF1>`pO_#Fc%P4eSP9cAecm+K+TuI@e zs~EhR!Nm+-L*Y6G*IY}F`E%A>M~@d@&)^LduDFrGCG7mo6mGhOLg6+B`Gam}$9GWZ zTuR}rW$gG)3OC(FVdg#T{Jj+N$2jk!$4i$}xZ-{a*E~Ss;(t+Sc$mULD=1v?D24nv z!sG0^Cm4K^!dXvKn7N9=O|9%$rf}gi6!Pah_`m}hZ@gZJ%M{yHo6~Jq`KAELWH_(< zAmhU~pU!wV&zrIQ#c5MMxT|5x5jU^SSX6me#?w>sGk)07kPcG!{RLxywv!i)*_6Ec3Ee`bbf^F0|qzI|oJIm0GpytVO_4C7(h>7^TwnDU=r-pLrz z_oyj{UOyybOu>+h0r#3RKD_j{^nmNUj7`^9XEY3aGd<-}dq!c(r5X93ot@!N-Iy-j za$m-P4@RfYt^O|KqdtilxsPthxbnt_GhUkZOGddZ3EuTZ#)31Cn{xb2f5x$sKgnpU z89W7-|NfOU<=-OCYb#`&zi~vyrHdA&U-wga#^pg<#jL|G`T(F7ge zDQN#e#v1&)0g4shzc5?-PguBcEk4h;h59XTq4uA!@FjjNhB!`jQLu%CG0r7%QOAu( zVl#_|PoqJzz_yXM?LGUwdiUvjP``uwA9Cn`!wx@U;Gn@nh7LROsH2CEIOf>njz3|f zIO@dFCyg0<^0@I6CMG0Knykj}N2zJ)8B;RtS=l*`+`RmPsnZIJic6fQxZIx7vgzeB zW}bT5>1R~TqGA54Yl3IauC1#NHJlZ0Y-*k}w`Jbh=bU@q`~?fo|HlOvUUcy#i!QzF z@++>q>gvVUTzlR1|GeSGo0i;s%dNNFe#g>fciwgPJ@?+X{Qd_X{MSPdKeFP{#~y#; z$)}!PxvEu?pLurmn&+Nh`@+9peCg#^UVZKLH{Sfuy0_kb=iT?-|6u)xAAP*xlTSBp z`t0+~TfX@6tF2#e`{vv4wtv6lhaZ3X@6Z4D%dfxv{>Ptx{f{Oi*`t3KEZDho!A|@a zz|I9g8IeUx%{zsKJGK87z}1oe-~xP+Qt$&cWhWd*6g{_Tf5p#%4~i^;kOpV)wrS_i z?=f#-sNo6nEBoUKL+TL{HM+caDZhTP<_0hKE0sGu6aC({vAImHDSyO9BY{F)#AADz{>bt6|REZ+=}e{(&A|q z?t+;P0r(f<%d;#Z6p%>LEL5|4qsLWRoNf2uq$&^`8)DUmgT5w#0YBt&A;F6Uyho9s zyfW9G?V+y}ni$5^$I?$JEGR1Q2t4dNO}_!DIxvQC>K7Ufo}4DJ<8dX#8i*nv2*>;h z3nj5>UPFL36uDeE$I}lG)Q=+(*~RJJIRSD3e%pB7#w30{d21B}WEaU}Am%o?G3XD} zHwCMLIP7)2hh&o`^+A+)oa}(LHO^#117bIdwZXa|NpAu*hfRGS&QpS;Uz1l+%3#$k ztq-(7@OK=lJOJMWk+jJ*1WQ$QoQ%9xIG+kmal+^-^7R6#NF&a{!`q{gUdAe36l`oH z`BjwXX>J$z@A01BW^+=6XbqH?0lii?)lgPwtb@?(yg}6G5-K3CR}jE&hiB*D zdPn^L_=I@x!D>PI{<&GfrbcHV>}JuogMnJV+ED5P9W70P`oI<>o8@!My!4J)<`En9qzFE0WmCi9Qi*X&6;v(UYarIgF zz>YtZ)1mUbxj~>)oS!P7QV1gsh|{k{7JRynewD{CWHAnpy3W_!*aV4=e4#*9RnQj% zY~d71V%*!K>!W!=G-Gl4z!B#mv4y{*ubLhXK`M=gFhte|!PDW-Q@&4S7fSJz_>_84 z5*as_l0Rlt(iGzbGa*a0SM)W9!+@3Ac{-GHx>m1jn@%FGYm)%@b7OzM{wXmkP~>#v zF&2qICQ803Di^BB>j#? zuBx0EMVIleQ#vF?;_?JqD#HfqeIcB~i+o{3pB4h$0z}DN4T1Xua4~fC9PbK+M9>`E z04Y=OZIo;nGsO}qfDfe)jeMWlaQuY|{*>z@L?Wp^VV;SaE!}8;2F5^;?`{RH95$Q~t2Yc{VOt|)3OKLr z>%9y+7xfxW&V4D+f976GdI`O&dJBD^^j^}-+>4$+7_!D30vXE&2!}y-t|Np&!eC*j zaHMdwFhV#^7%7}6j1k5QiGoQ;0YyFw@`yQwa>xKSTbLvKL%3SFO?XInR(K2E@|SQl zJoS`bjlFK_^<1y*y~N&Sy|3;4Ztvsz)b?51=cK+@_3eGo1qTi4_h7%WgNO9r)PLm#emz*_y z@~k(5l}(K7g}gw0bFe;8P~Q}&6|zB6d7H!e-sajyK@{DPyQR9u8x%!I7X)1iD3v~Y zQI3#5uR2uEZp8S)8`h|EWg~T>ET;zgOy=#c-|z@NpdBE>fM5K%!DEL-W<>sp`X)z z0jQvJg3t-z9$cK`4F_>rqe)^Z(H`;j{y-JfvkBifiOCQAe)eASJoT;gHZNq6nF~4y z{-Da{AZTQDkc_4Y)cx9q9{VziAeuT6>)mQ;*3pl?TNl)1X3T!&0lAH@dFf=#l z$NN}hrjPNHL4YxROas}06)_Ft$-{CBz?MOuCXVyu7q~_E?{t-9*|Q2~h;|V&#f_p@ zo>B@!GwqA$50Kif!sBoi6%@m;usDxA7N09DnO@{5Dsi!NZE$9KL17_$H>9DnXHUy> zm6R6eC|Bn|3cNT!DYxa8xEyhA)BRLf0{QG5I73^WgT7;$V@8qP8F?nVu)vvBVt3_~ zI&?C z&GjX&0>A|wWJf(Ly9Bb%WqVk)H21+l8^0Enl)+6f;x8_lUM!BQY_6VyS-UPUg(sMC&eC!{i@O&j?TT1owvKzo6aBl>E57EBTgXShp3~%j5h4FY*A9 zM!$*Bc2q429bk)zI-6UPUFxpLvlkS{co6-uumrM0>T8(|XQQ9yu}^bUkh`L8$S?2! z=PG$7_0KEF&IU<<%|x*g#Ar|XT}MBWQYeamxENxT1lbiqSP-FxzXF&Q2#cld)d?Mq zbc5`HO(5PHp>t}0?1gx*(dWfVC7f**X9wo--MSDKhm>yN@ug0J4UeN7I0@2Ug4}BB zJxwsOOUHR{X}&@%P^o!B;RXC8nz^$>&!HbuR06`hsDxP4+I;`qnxL-+*N9cPS!}`I z0LE}c>L&tzOy`iOcmdsf%j>SMM&%njZ5D@@^>y%+lxF8U0T=P;pX0YF1UXe3 zydWPS?;{LG17X5enD~If2sJh~g8mHq6nW}L@OMPjoBzNFL|b*Yqu5>IVroZxx@iP! zV~BhU?siW#oKDyQ?;6!z6W*ntl?zhL;ZmxrCje4StP~bll6XaxL*PSJTR++L$F4bj z1*&<@s|V0O&qh^m+N{ne1u5OAt|02omy?g`71^xF87l<%Tdq;GIJvP)dF zxr<5*Jq5}eDWT}(j`qENP|};c1e2iP0AohH18475KZ3o{RpQJoAQ`R2aoD_0yMcK6 zwt5rp5C~W0z!S0@kU3g8$}YhPfSJlkG5|-iiN4(w*&KwfjpRmFBw@t8k$l`i`f87= zNFRNwS*5ikbvIcdJCStTV3TSb)5x_;K^#4%d6YOV3+tG<1?5E!tYiK7FZreEy$|5K=aLpCQZ95-?a)fEy&LEWc z;r<-Mww+6$EE;>Dw1_Uww)`+ z!#x1ECP2F-Lc2j}fpQa+l~9I5`4xWq3+_7(p1%OfM^N&hy`F?}D4aiS)Pd3-4#onW z&WExT%4#T|Lir8wI2_vOb|}w4c^PnxpR)n>(||w5K^X=`fbuQ0*Lo-~Kv@ChRw#?0 zG(njK1-ES~lnGEqK!Y3KrN^G zDAyw#E?0>QiN(!zPCQA~D5i^Jf{JyVbxZ|*p*jea2ICFRxE}PANrfts>YF{tN31@0 zdWXzI;`HbKP;IR@EV5_NT*l$Kp$5o;E`TjZ`GG!^Wk`qHtD!3jz?2JIwGey{&dtJJ zJVNGixpg0>XFz!t-#{%7l^Pxwp$aC4VvY6^uPy}sO>U5U4JQa9MR16vQ*wf$?FxR>; z*9nDzswROP!)3q~c+yLl7MKSru{fFUOyE0-d}kuxabVLZKQQtg6W=lOog}`K%y%q& zCx!1=`Hqe682HX4!QRjSV^NYxU2ulLI?R7c2aEu|jDRpBV9W?8GXl-C8 zVXOjLO>mtlNpQ3Te9eH4d@v^qMPQg0+<+hOWN|lz8U%Z_H&_o6!5El_SA9w@#Fc4)_l7 z6B8#ZY^8ZPIRO5GNga-C$a1e9mH3)qc7XlF+L|Bc2U@^0iZnlAaWT6oTub-dH9=r` z%=aP?Cf$LVWhxKobwo74v=qLO?&B-z9=@~)Ol)p&eDKx4gq1%SDh3M~-E)QmbLbxB zCH$)s49WBy;hmy@Kj>u)H+}kap$I0ZfF){u&9#I9vcaPRcq}Z~vqd*>2!2VnNTeA+ zOmFx&Hx!=h4g1MOgln@!SD*@JP{`F;q0sC)Z+Ld2kQK&at{!Gq2$QOZSSnH@H>=6C ztek>cU~5mPx*FWg_#x$O_8Z*fIFm?<+CTtAMMHxT|1r_(xdPbiN%wO>V(@QthpL*0 zoW(l?i@3hP&Gmi)JJd_Di@X3Uq4=O+jRAWHRYAeC=rvG+P|k!h8%iydIwEP|k*8gkpkXhLQvYFC?%)Nr8eLjcrh{)A8X@j)j6d z-b0{>P!ge}Lpc@7=}=CCG8#%Ml#`*%f|39QrURkxBhSi2f{+QnXMzHh3HN4#Lv`*`{%FKoW2BAzaFJ$II0kdspK9m9|Q=v?QvH+e}1Q4vAnc#Sx>4b6$6c-dw zM>9Q8N}-fNnGU5K$_ywop}_ZM!nbC^H)oy!r2@(3^Gv{bCg401aGnV`&jg%j0?so5 z=b7g~ITy-#Q07B{x@0bday}INUcOxf#~16)@!z@vm%y`bhH?v(TcO+r<#s4{Kv@c9 z8I(Jr+y&)sD4lu73b_7JD33vT9Lf_=o`mugl&7Jrgt7`sD-;Qe4CNUp&q7%ZWet?) zpga#{EtD6a{2R)PP+o%aGL%=Kyb9$tD6d0#1In9F{sUzll((R~4dopu??QPG%KK10 zfU+LShfqF(@-dVRP(Fde>$nN_KZEi)l+94KK=}g7mr%Zf!msN|*sGV2*&9k9D1D(E z1f?I8gQ4_?atM?|p$vd>7?i`I906q@ltEAiLm2{PD3oDPj)Za)l%t^xhcW`nF;I?$ zavYT7p_~9^BoqB%}Cc=iDd9KgV?$G`;LBgg5E`C+{C{P#Ttv7Ugp6QJ~g zlEk3M;3x)9Wbh;g@pX6`3kBbIGJ|6n#JUGQZ-Ih0th3-Pg#x;m3ik1Rc*F0<+eiuo zkwN@^yy5rbZ8QY}{tmq1_u&nH2j0w3@Ov@D8-71N#@~ZC{C<3FWe~p)ANOVOAO`y} zcrb(g8N@mmzWz`K2QYXTgNHMC1cL(^9K_&Y28S>>l)+&P9?9TQ3?9wka0W*(cnpKb zGI$(=$1^w?Al{4=5M2`Qj)sE2AGZgF$qeH9;|Un#~ZFc-f;c#hUcHCrWZ`p_;*Y*m`*T_*r4Eh<85_d6$n%W z>tRSGz?z|e9~(R;nW_@7uLLY+phwj3N@nmYa!N|Gz(5EdQrXigJYX9nM%fs@x$HRw zrPKgRe=RO?71_b;>U4np(2bq2*!n^2=>Yyzg%GYLd{|w zIO9|2K3EQc-6X-Au|B{MN@n^6LAkEM+t?_2MeH6A%TdlDZNQL!9(4<7#E*89wjnn+ z(ic<)uqU&((FbdM@JgIe82dky$z(bcScIE)+<4_`XwO<`-w>Fs!DwFxRxH@T)@h+Q z#2jbftHH(}g4F~9Olreg5Nsg~g8>)D+ahssfjNL+J$y#cPb&;oBAAC3Yw)6v2KeI- z1saL_XfOcJ1P91^5nS)#5{92_cwtij3|&ouI(9Ex1_75b4}Ep@2>652=VL=UAS&bw zlC^Zoq6&7CNXR&X5S2zMD#>xcsy3ICy&tL?4uBy6%=d7UA8=ULP#eI`sl;?Bdgp+- z0lTP@>laSpZt0OmdB6bnBOl{e<^>{ur7zOn2Qvg?{0Z=8XlA?uMu>SQo=Cu#fs+!Q zIDo5l7t$GMRu>F#dt>j*ijv}rLc80;{O*7~vA>rfEPia;&K*$lAK$hU?=J__VHrgoc>IE`iPw`*CSI=~ zo;(*klzjo#F;Yjb#tJ+;UV)bmAWlEveG0bWmZr)0Co+K&Y6#SmX%2XKjQiSnRn*nG z`(Yhh`|s601a84N!1#4d&kcv_a^W-a+Ge02^2Jb9n6x1@gcn=lb$&n)p4>z$`D?U* zOdzXyh&MA-4Q9c~^GIFsG6#5|pD+n{Zh;+)ubL77wQaB+UUDQfhJ8Y~621>s&5{j& zE8g;f_k%tp!n|BKAbO#U@dH=mli+DRC+G`+w27c`em!3|p}7o39eN&k~G9P&5&nj&v- z2byxBFNKSh2k4Ira6c9BN8SY=1vYq?OoEjJIp8iv@683ek2>wdHNZ2E^cr{{e02fV z6tkLv%fjk;n3ICDu0TTw<`pq#gJU+VEvYET1C`HFK^>Uf!q{MSg#bTg*Fsk=z{0Xg zNiCBNEigM}P>=9QVQgKnBJx4>3Gg5fc(>!_ZaMrC93U^bugPk9A8$Djf;NsiqvGWcJm$K`?9;S>n@H^p<6#jk@ zb`IhPF`zH(Ljt(cH{n%c2-bfjkpE!+o-YU!VVHx2N^n3J)94)&gnHGC2~L7TESy?k z)e_btlyzsgKgCnMfv^bEm1Mn*iiwEp&g2rDU4`AVge>AmD&om{vLp{Y6{?}nR34y6 zX6ghS>q0CNk=o@E8p97zIzf7dyrK$(J^l?lhT#^6S_^gFh6Z2JnPS7cvkdSOh zvLz)YTku~2lMvqogPHE?UyPSWQm+em8C!KEw9uhXJt*i26Tq0@MU{qxN>ph~@HhBj z8XQ$xU=QOPRVKk6nJz+=$*|kpfGSfG@K3U`8e#gi z78G<;X`?5Udy?rf++?DAaF=<00yuMr;holm7F20Un1?FO#MGgFUnR_R(Ql&PX*4Mx zYBZ}~YQ$fSKhItKPztuwCg~?TYAIHZoc~8W1cR@XLZJ+7P$RT*GHtppwOicp?-E8e zU!;CdcksF=+D##w7|gBmi$T_-6JlwRltSE zUmGw1&7>sI{Uq48>FGxyia10-Mgv$->6wfiYsFeDe9>29(zUS9FvGr;Ng$POl<#P_ z{u=okgPUSdQCwW?*7wIig8Ke0P)f&9)+UknP{RuHIL#4%s@gv)Pd6DD_2SR4X((BJdP;&2 z@jU#LbpyWHnaRpZfJ>olg;IIgH#=7z`pwRJpq$J0@$p#L*Y?Y*N7Za9|>RT?`J?2?Bg`1kvebM}&S5 zT|dUZyP#H;fTQ;G8mczI=hGd~&J0YagL7tzE;wnLPio#)orsbN>ODBCAT-)1w-<2CU2>9Py0VQDA*L@qo_Bf)O|zFuS38J^K~>yomZw ztRc9qkkchqxs=8hV+5CII~3Z@E6k!H)VS2GYHLiL zSJ+EW+2mM5IZ3=%Oo>!S@i02iUIeR|__{mT%Pq*OAPbJb_80F0+!_M*%UA7xe8d-N z`kNp?ya^b!CssB1;QHvNfkQZU3nxqIV3Nb-DFw|1e-SL3i-^+z7HJ5-z}gPmf9a4M zFA^9J&s{$Do1MWiAmhe;vvVOpT%2%j{mI|#j522957%vJ|E?h8_n+5M_zQ!-G580A z!dvwBehePQ;86^YVsH|JX$;yK%xAEK!RZX1&R~GSItH5=e1JjSXDf#m_WkFv>n>pM zG6t_<@HPhdjm{xd zt-xXZxu*9`jwx^`rZ}GbMx&Kt$EL+o9-%AIO$ckZV~VOPN+(N4+E6*w-jcv|G-geS ziz&TTAQq;~aWTd5loBu`6Fk{WjG7DvpeJKOG4ysYGaC}A`>+TWTphNI*vrD+FWM!kwQP&9z?OySOp7lG2Y<7<`;@Nk8CpC-0qj;c_j;2#vBZwJ+*9 zwv!m*_%WM|RIV8e-U$4d6I@=1{VUpGrlCc&hkdY$1o{FPs6_OX?T@IKMVd-&RrXNX z#ictpDXG6R*`!=R+Bd>D9?`!3fQj^9RaHiq52YKSdv{a7TPK!LrAf?#;ROuOBR-xF zqPtm%*y9IUL6E;uW67vWc47blLr-N$td5qo{dtwwV9s%sLP!u-JWhm< zWoXBPTxOM1`N(Hw&ovOWieVb`DQi}+DJLZ6W}6MT?~B5)I`Z!5fDMZZ6-~4&V_1R- zk4OayD5qVy!a6ek0LE1jq{ZcmI>c87YQST>qf6>!N5}cAGkDV|3V(mRB~gLg$qtQ@ zvm(Da{)`4Q(^DBeAE3LK3YMPkI)b+YbcZ!ltsLcaXRz?@QA>A4AnxLID!{tTG^0mweq_Vr}*=1RxuV=E+U{N|R*x~)xzSf={tmogp zJ&nn+^^sz#j)5TssCcLY5PY^)i^aT{%vF zM%wGZ09&;rYx}WI;V%wN{9O$cU86iL{!Dy)ttCI5yf{FA@#wEp_&Y#<%7B~8KR(`8 z@W?tXZGW|E=x=|}=R1VQZqngii^pyVL_IwkEE;oxA`gKQcjed;obC4svv&-;QakwD zH8i*v;;(B&7)5_tbCp7W?%V_OEs=wtuHdbkq_?**Y}W{ms)5mbYp`f$5P3hm3+ZmJ z?LLTSOJ^tix`D@T(&1i<$LF?JQ zLwCQwi;ckX&-HSnN!tL5Jivy{y$}5g{yY2qdkOlZzTaYsZC7^xP4M5*@84VTZ!pEy zV+sCYFfef+m}iRN>DkR$=IHs64&hNx1b?%6rnq?QqAbR$gs-y zks}1Epmhn42k0>hkx_Uwwk;obfq0Ci3GK;Q<1P&ox`MZElHcBjw{A#5RSxobK$9W% z{HDA3?=`{6>7w)XibEZH%LHefak0_JqPOVm{H2g2p$@MqogRc#I64n~&B~9?JIJzu za`$b8%thbCSER#oc2knNEZoG`)XvZZo`hFxC1HCr{cH+MNec!F)&-i(yg&2r=!l+OW!IzRqIthcLhI|zaf73 z62IM`Cs?Zt0W4UlHy~5C03_Ib5CJgHo@j{nknZ#vWo=i|=E~$)E4g*#Vqsl=>~)S2 zE0fg~TPE&e7`0N6(@T|?#sjD_R8^^1Ab4mBK$Kg1-qb`a8Syw3*2Y3?pRO*D?F2G* z+cIrK)cO{4l98w#)veYJc>q6J{3IQ~Ph0$DOfqQo{{!@+r61b?`e~DXya(_T3qO7f zWhBVNT2lxodF-2oVn~lJUU8%mx-P z%7*kF;iK`cAS5aR5yywmK;zOF&B2RUI9oiEt-rb zOYXjGBhcdk%*L7k7ztSf4_UcI`!egg-ydZ+4CSFA?WV@YRE*4yPNE0$SkSVOPGl1 zf_Z|+se@Rem|WT%tFn1s<(60>e$@nNnxqM8dwb1vfvm|?rEx$`fO>|))neHsv&eEp zI%)jZ?in9C&IA*?Z<|Wwc}D<`suf1tvufEukqb%5%)yd%vz!JJaspK#5eNx@1Aq%s zpoYcr6wDFb>sUIDnB8KF;oS-62SxAFPzlIM1s~iD1H4cf_KL2g1e~+cmy+WB`-%&e zz($j4Ft$FHVq^A9eLtH6IVZ#{2m(F5prHGR;Od7yBD5|rrV>AyUI*XL@*SvQrdV8G zEL_=dBD!)3>9En92s(+SMoV?!LpUhBY*3kvjyGQE?{{EO16o%g&gA!Hg=Jl_%viu53n(6~z)I$EM zx=5oa8Nl<|o=y+cv?5~f-~ou*6om)vGQ|B357uN8B?SF^N^Wi=!RUV)5J1!_fgSy2N59{bPlCV^eGo85gwvu?Nq%W zuD+O;=&tdGXN!4mXx|j@p2b?CHIP(=>-RUe*=f5y#by_&FDdfhuao~QV;nf7drDnd zB|Y8ReBtLF=oBK=0fi61I7R)6D|Px(UY^5du!%0{9fGwY8-xBW=_H2w7+-2V!^Kb5?5c$`7-;SPpH4>%z}IvFfojb2D@q&HA>7b}`U z*PhHPLlta}7ca}>W%lzkbo9mXvcKUW$se0O_BTAhY7LF$iqk`)$1IvA#aP7CdH&$) z6*b+emX^JWQ#e;t!A3bl`0W3+KB?SOwtCv5Y|Eo}{_6#Y2a$JU$a;}zru>VwUV zVv)Bc7a~50dEg_8Qy7azQ`xR&U9BL~jT~r}`529)3PPTdF^+?%+KBNquwdZ);xom@2NoFJBZ#i(ew|P+xPecX=sv>W&>pLhfi>rsSb6R- zo)S8o=f2b9296-AXhfeWLjKg8#PX=_rR$?h{ZK)xl)2TprV+~(WG)#BZvZuCl}XeYW2-c2av(7s2Ah640*K$j** zhnJpj?$~(Qy|$*vc~VX<_($Dlb6GVDZe18i|pR@3K2hB6!(3-ILw! z$;Fl=JR^oJSxq70OqEqa)DVr*N}c6Y)ry*~6`GD~cvJ7tyAfLW0$L*U_^3<$e#P(0 ztczQc@2&HSZeJ)2pByE__dOw?=l>*4lseqcd7B!W>jPp@aCWokt_kS|qx%fi$I%5i zejrW&)gY~GVLVl<0YAYe>{aXV2Z?WKc2iArZA~)?+uk#{iQ)~NmrPtv&~%HuUR=H< z>t-N^-ixs@s~@=aV8^HCaAjyeko~droMc_Y({?9# z*)K2>#RoJx3@4KaIT%LQj>_H0<>>IpT6>%lLqzDdj}Co`8oINe86 zI}@F{{x9zEx6S@fI~&33wSTC98u`fmLZjl*=QjtZ20=51d<;4jP@~B!8uG5pTM+G@ zsEp_N`WBNuK4U@g)KcuS?4U{v?XaRJmwHA=>#~VPL!*)MnfsHOe7f;Ufzy#kM3H7X zx$|~iEt6@3Qt7O@9Z<=1L8yQ>hHX1yEmKldyxYoT0~v3EHm+SqUQpNI^)=!7 zb>D0(atKv&*GpC%#YEQT)G*aL+O)xNn_C_nlhBj7wDS0j8`cW1%1ggEFGcVC* zFh#o!bhn-NGON8hJ_q|8wMc8jZ5a}#W+yt$24iVd8+R8K8k*=i_u3eD7|liExSWFehUO+>iPcbj=P}Z@$(h;a_9$*RzbN#PqE$#ReN2x<9!kel zW0;f#rg$vx5bWdgM1#NwIFw&=1Ku+dUoX|Z6eZE|{cXyKXg!3_=fxlaRqitfYhF+8 zf3KDLpr1^`(^k>_S?tcZJ9Un2k?o-wEA0fQYPM7Pf%y^pjXsS7O+sO)ItUIVHDY#6 zu(sCS6b^XndPeo!tq6%@mWsxQDK0)jVLwS6ulNKSzG!A!!<5j{jP zaS+7$$HM5vXk-Bax!q2s7mlClz)>&>jIpE9rMf9Om~ES?3Ob8M2Q(?bA|2q+2Qb;8 zAT^e%kwk-fYV>*q50-d%APeQ~K5WJ8K7nYpNln+fN68|JZ;aM>_{dE*YBC~sZ=|rd zA|#4WY;p0CvR~rE8xJ3fIE`GP5SvIkKNgNsH@alx013d`*KDQZCWzOj^}8&x=VaSG zGevi9nP?CDy#7GsfZ1N#Py?e6caP6-DgvzoBC#WyReN@Bjt`5O1)AdhLQ!EJZ_pU( zRqXcdsCu>ccbf{m_$**ifz9OACelkND#^2p<<8_p2peA8+!)ncc74!6`$kpe-mAu@ zoR1W|RPHvs=>1~$YP=ZZ(hC@bcP+jAz3>v3UiMGCaQ_jDMHknu$eC!hS}dZwxd9@Y z@u*c;%xH$To%W{FDqvb3(hXE-=iBDso~hk@D5!UCW<3-4}=a!o3nJq`Yhn`Fm@gSn-BsN{`%K1gh zaJ#_Z7R!Suw!uv=kE}-Rii@`J(}ROcHl|?nbXxqxU(cf>KSzeLnxcWyyhq{WJf+wNKL2e)dr8Q(Rv$$DoTg@X^EF z@$N?m?^jGLu8`3{?RLzZX#n~F+JlIuSV;B^Q_xEHm=2=$vGGQYksPDogRf69nlvl- z03Y+JYQ2p$oMGHpH;B=LXzc}B&7mXFoY}`JjIWKZlAJIPCy7(}o6qwnB^l#cYHd&|7m!m?6pKPoOO$SJTZ{2edqp#_A!KQy-<`zUtVjgfJr){%2! z=UG}8L^hGnc7Q4o10ylx-z7m`M%dU05ke!jgyI>~N<@2sD;IJwJE8-ZbXmy7?iy7Y zg(*nU0;p2Zre?&X7=J*tn!v|zg3)Plz}v{QdO78u)zV z&MBy(?=>TpNpA6JR>-U54E`(yfYCmDjbe>d>?H@5<` zqZf6Op*TKaT`<*~%(^^4#i2&vqq>k-oRqxFv`T%v3oS8HQsv?YhNA6i+TB@?1P)se z7Kryk93Orb=D^}l*2ecJaXR;Bzc{mn*^@M0lrXL@DV<>_eX>q^5pKgHccQg{wLlre z<4%bv2M}@02>Y<`1V;N@UNMqT)M^chXpI$}SKM^n6*etIt0}~d+=vZTFskQtkzzGb zdxlqwfP|9z+TfgkI30rAlGO&<0je=Mp%SW@#Ecp#93P#O;(8ZBz#HkP==`2G)JgXEX7u)_K|3uYTY9N-7cF~rCfF@K}xyVW8pp#%aWS4U>f*kwY6Io9i~ zK1?&!kxU0{ep<~|M=~9-0CJI{vHyX#PsZ(#w!S(OX4hG||s&hJV*NtU0L5782w`eoo6wW9N0z*>cqQY#-+>DC|9 z25nOtWz@Uu;CIyya$Z;MVkKTD&d6P<~Y&jJ9Q#2dYH6D7w3 zpWjGH)|mYbdOSdH2zbz1_&eDdvKX_Gf-9mkWW9mH=AAcX=#jyWV>6A`J5iO33SDT? zf$`CkajmuTqX+4NNtUSTFFjrG`Jkvg-tFLFUlA9aKP<3e$zVy*<-utO4~m?i^Ie$G zK|e^2P@%DojaBF4JmXuc$#THO{(yyp4s+h}xhM28b^63g+f;TXl2RI_FTt6m&0 zTt81q)>2A)c-eR42=8gBLdx-?^s{>Zi+1=Y5-*+LpXgpkBT;m{4yC0wIY>MB1{Tzg zNmcQxDyB;83_5_}BRL&js_3}e2op=R$5HwnvrbRfjJ_lB(k(vH;6*Q5I*%9~8+9P9 zL~Oipf5K#oSL>&O=>^ij?=PX?IR9|s(9Y7+{>NgND9$lXvRI;QG`pBeq6ROdBkPtu zgZCp4JVukK3*=?e9;g3~%rxo*gO2_q%yMeis`MiIL0UvV!tvruit0!92fQ?ente6E z<1lo@q;4?ZTi}CuO=|7gOgGb#bbkp}B!D z#FBt%e@9DCcPPAVbq1l`uXZTv&GyIHR&{)%;HOHjuM&cxDR-iE z`h8w^c>{FqD-F_&zb<(7toQ|!fAb}`3QQtS}zu55dbL!4SN14j&= z*3(jmtF?SmLABuP=H{T!i8uAg+aJv8EOUdAtL&t<38#4Lv%Gwf3uIt%lNIjR9N+!w zY5N*FqT`k7#HwTE7G(+&#)CRdLtjs$r9<_EXwcF1gr|4Xd6pT2V!P`opU=H-6!V#` z8DUV$no(=p!Xxvj`k6G%2y{x?5gL&6UHTY0ove?(;i5F4NOI#QN&K1WcP7#N&oIla z^JN^NisW$(r8MXkU>w&;?#PWL%0p7pUUtI2L1HFA1Y@MB{BKuod4^a}VXscZ~F`tK+V?KiekVg%P9OTfC~0~0kVw$~68kuIuy;rUs#QXcG1E{DC4chnH+XHpLa z)o2Shd;zyAirO~FsIp&ceBt!L>#K3H1PY0&Z<1J6NR~nD5!E)Tqo5~PTn+v3P%B$C z23LK(OE+QqT1nAb6fmHei8jBSlNjEG1+R=WL!&dmE=JP zYwzr^w+`$lVPY8|O-{Q!?W943F#s=RG;^1mvsPNlt+3-lDTj0O-sCoJJl;_^+2W? zsUl75@ksPQ7M5PokIW_`*Ne3Mn#+4OEZokY=MQ@^UNw{SyMFPSmL1xZQo6-z-185f z5Mv5WvsMkW7N>uu-X@*?OY80Q);HAz!ruK(&r$HA9~VU9C5B$pX=~@-Mo(7o!t&N| z9Wa67#pMm2*(?@?DudKjRKqTvAFpcpT5AOEK_}W645W9WjpCma8jtz_KDZp!YP>3a zz%Y|Ij>GH}iHETpf^o+-lkbsnroul4-Mky+A9o-;$6K2)5flDAgqJWU(%nR_F{=CN z@(Kdxrl59^nh`>TJ9%_wgc+1`Tl6T3kQ2~L2gVk9da)j$7qTWR3NHufB_>{y+rvxQ9uhD;#7Oac zV)XQqtcfxcL%!@|c!_7cQ1HU1n>3?7f)`jO4Y9i>L998E#2$c{+)AGWvjAkRi+-_M z2TU%CF-djIfn{0x@2S#Go8bO2;(KWH1Nv2=a8u8HmhxRZUWHbx<9H%r8DgYTjcwbT z2=joy0OTTt`{g_K|Cqn^f z>c`h-7|oz*L~KA;b3(PvI7^l;R7FoFLf7b;~3JqiD?!@aem?WG5U1#Rc_C;#1se`P38hM zl(H|GpB25Os)}mlX59kQ1b3OESS(L;+HTGpS8z!IA$~Buv?(aq ztg>=TtZ)@dn@p)c? zB`tosuhZ`#*%@QTN{a~2N8G;_;udN3R7NK>Ychl<4?#9|YVgp=j-KppcjdZt6(New zp&|qX3&#hi3xltU`5jZ{;dJ4Ih3f_}Hx%{-L|1biM8JuOmd?8@@EKpKamxcJfjFy4xr=h7yjAg{^9x{f;xvJqPZYa!c}7Yf)2b~4!7dfEZPE#-=$uXzzJX8< z5#kl}F)Cl3NmfH!1hUWaO{GE~1TP9cY&HYUc4^lL6OBbMGPr|c5(F(3Ba7(G`rr(*peL0~k@~ zG~=lvvGp}WY<&&F!+;Cz{)ZPu&KhIO*_eHBCx`vVT6AG6ne4MN09&88j z*3X6XG0hDPwe!TOFa%1ml)B3juob`rb6S{kG^5{6%b0G;T6}w~P&!>Om}nVFYcSz> z0wF@jhgO?r<`?jU6YNy53_KO4Ns&yYt)p&WOND8t2DUM$r8InRt7P$ZHKP#Ho_p1I zD(k#8(L?ZeHUt9xLL7$O4SMP9fS5}xEq`;1lXi?9VR7R06qJ}xK5nlZVG^>KTqqkuc!S`yBo>;mgH+Q&Utq{ zAgy%QdY@^H{9y6;jYh9#saOI{n}MsY87eAd(9uZ@P6~T$h@=h(w4F=DRg~EP9HXqM2lrsiV%@uNYS;Pf%68 z82kpK7nntgU^tE^9v|J1WYt&_57I;(VaG|At8{9>d_*cK=;~(Vbe-Gj zE{!4=14Fuq#~eRA-j&8UjxFMz5SXnXMRtADe(hJ8Tt&x6zGR&}*n_+KNPmy+seya# za3R7L6*+#Yw6eIS`uIxwIbQrWHjdKA;qc52*1K!4voZ*qD528n;iXp9p~L7ns!qr4 z$ov8Nm2*r%jO|KE+!_=r;c|t~qrj?Ut-TVbqfbh-w*(tSqbV_~xv2>}|0B$F-D4vy zTK4#Kq=FX3PRIRhA$pOvKf-v4KtuQDPWD=95@m-{);;LQm-{I`l=(LOdQ%-f{+4W_ zswIkzPAffByKR*LJ3bi<;9jfMZ*_Rs6+@zSk`3q;wf1e6Jf3endD^BbtGbEdp(B^4 ze4Zmo?`NyS$F8J{-PWtLm-H!OT*&itfc(_VU?yNZlm#ncf&(ul;}HbKaal#gUbzLrOqF{EKm;%NOyB!MP<;|@lc*xvRCTG*X;lwXf&#XvY-#% z(n1yul6W34yA=fOswxx)4Xei&S9iCDoUfJo!I}X+hl$~yt{)d&ISVTM^Qa z6ZB|C#)@tm-HIx|^SsUAwxP}2Jk#MSaTb=k#dZ@o?-n7jTf7q@rldLD_^n1d!KPUi z0sUeyt28&)URWY#x$~TW#UznBx9n;qPfIwuZg5wcR63yKMf4LKFB+o?))%7i;@mF~ z!|4S^iDW!r(W+4xFU?g|u$)MY5gtS%bCku*9TAFpJCjaGDnc=GopD#fgD84%m+D6b z$52T!Z_#u0Bf}9>LRZ3rDD~s>#Rju(UOn7ge{%iF{%~-P8oCz-xm}weW_^8%b`q4y zINnotn%DUZIe$QW^Qp?~3WdZO_dvfuA|)A9D8xDu-V&N!-s(W4rEph{`1iPWtc+}H zf_`s9FkwQJf~PDV##S4qyHM9W!hEdLiwFOz)FvlC#cqPwYin?y9LivMvMUrZ&%Fj1Mu6!!m!!t#$P zY}i2I;!h}aeoEo2jTEkAaK|QkZ1|kQn#~k0-$LQyFDPvJlEPVEQJBA#{r)wD>$g!T zeoJA^cNAuBr*Qc96qfIx@TMOqT>m5c{l65>`kBJz|3~50Unm^+8~got3YY%De*cp~ z!~ZDU!QhIW^teHoMet_mMd1zxSM;XGzxJUp^B@Wr^`mgz!4&pCgu?toDHI1#C>+Ml zA5P&-M^NY-NMZj$6s}>gWib1F2!-Q@QkXxC!iFO$Y&nX;MMqP(d^m+KkDzetF%2)rQ<#4Og*787TqIJsVibihpGe`R(G>1DiNb|rC|o+0!sRDZxMm!M>&8>KX##~i zCQ>LQQrLeIg@YzjXfROdG*URrL}87Yolj!N$rQF&D7-0!!o^k!m)j_O8Bw?xobPAW3Q~2@>3b)RraNVgCt~`w$pU!?i zgF;~zg=-jG=cUIxDk*%~N8vg@h3f+puB>9`t0~-6L*b4fg)g5;;riJWE~=%lp^n0q zdJ3H(3THJ?SaTMI3&ZTVk;0ZH3Kum~xO@(UE9O$TriH?F^C;YOHv9b?_WQZ){CO1q zI-kNp3n?6TK82b8pwM{%g*6vaxacAZmtRcbx=SehbrFTbFQd?UIfdm{P&n&K3Tv*S zu;FS77cQo7@ii1Ky_Q1fbrf2!r%?PSh2w6Zu>3{}TW+Fo@e&HHH#2w(h55HqIO{eF z8*Zm?;T;qjma^kz6t26I!cBKk`0L#a-b0~yABEQC6b`zd!mSMc`T#rsFA9f0MB%uH zDKtDnp>+j?nU7Lf{uqU`9;dM32?`fIN#W9`C|vn8h3i&QxM>wT-^$KQ6z-5I?Efr< z<5p8>SVLj{a}?G*PvN4q6fS>(9sirch8HPxzC_`#3~qXv9t*EhIPNtH%U}P0_PzzM z>ay>RU(m5L!G2OzHq6~{l zeOGP8YhI}EFTGibAW3OSl5doy5icsQ1}|=zgg2i5=lfjF`Td@qjhSU-`@whL-{*P0 z-{mIQylT8l)f0jJ+b;*lP zNWSzhlDD3eeB&FE-}$EGyWf($@omXd-;vxpC3z;7+{OH&eP5a&d26ELNs@OYOMd4F z#Yakh?p^z$TloiBOX1(Kgs{N+g!vyVuga-rnumgLVW-g}Y6sh24G$&$OKNN!y! zIh!hZYP#fU8Ood{m+_R3Wb7J{7gPbN1XY2mK}$eOLCZiRq0i>KWaUe(f<1QIrevx~T*S%POACtRrs#zH&Y_Pe32_Pl%5d8K?B+zUX z1lrpowT;%LmOBz@sSWzu0+DIO&9yVq^9tM<41Y*tLA$@X;Rf7bh|7oYvn2Gq?afwc zplwY{c$Gz)Cz@Mu#?3k;;*4olNn70vMyr1+f?-xv<}J4J%Vta~sVoq{VKRd)#>EBs z{$BP|oC)o>diY1h6EZiJRzbhGbUNysEinO|vBvDbC-`SIYY6tBT*N_%9WIR`E0D zNV#(qw-ldZ;F$`$6@|IOrmUwJ#P_jDQF=d=i zQ7&KLUhKiqYre$@q0luAohs29iuCfU@?yR_{55T3jyS_tSW>*8s8ZbhYDD9-ayBPL zZgTjaSAwduq`0Co=IY?~G1nY&@_yRWhcAv?%te{mS0u{$2sT0T73WIsnkc!ICV2wH zi5Tn16-@s@+nWGN1SNrzK_fsTL8Cy|f(Co4DhsF2Ve~g^c8P~w8wsKPn^Jc@qqW-% z#h#Ue+SauOSR)R}MZ+mJNULU3EjTQ0u5TH@6G}Jn*~>~%F_x5gyp_w!J?Y!4>Akr3zY&>yo0b+JFZIuJ6IqA{`gB-(_EP_W6->JG5Co4K3(H((J| zNqe*3?s&Y0J8I_WK}1bG;>L7aKn$Dge(sBdE-+c&&qD1%Uuw6ArUrE6R=B0%t@Hu`2qM^jvOP?t%!a;TjCE# z;LboX8DKe<2;^d15rE5e7PU0hpigc@ESdz1gLTcphDLmrP&?`eT}~)xR0qO!xCqW# z5Do;IomTnbU{eHn-5ZeQH0m5yyrE26OB!+fq*J9F6=56J#N~zXBa+iMAZBdx-h~>4jh|OO9QRyU`r^_=8QGsG`$Iz?4if&NcMaf)r9;JL)`sw zbmvhMIfdaPdZlJA_C}9HjY&r<0(*hi`3EghO|Z?f?LM-lk-c7sx?<#;mNkK}Teb#K z5t|cYi=f*oY>((02b^U?*^A`DwS#CGvHKl6oclWw&1p6(QM4R?&QDv%F0z>v7ATy^gFoqwKgm+lf18 zIdMm)6VKV`#0e}l#qM5`fk&_@qwV(f8=ZKgfk!8_oMo5)h=J1$JR#93Kj9oFPONp} z6!v+C`|X)dd}fvtk7j3%vxjG~fqe#EY2ao9f6BnO8hE3D+4xL{|5-EnczbwQs^=U# z9%7fj%Q3f7k;40)dyZpxt zTyNl841Ak`KV#r719uzv|A1%MzTa`feo}%ne3uxw#=v#JcJ~royT{w(mo#$K1iO8* zfkzm4q=82pIN{7y6YTCM8hE6EQw%)Xz^SLf=NR@$UyJ-^$F~^x45XLceyoAdHgFo^W0ybA zz{v@pxx#KglC5JOv4#Ivs1Gl+;Y5Bk$&N2Yf5eV&PyCp`6XwhLw9gy(4u#W|eYe8e ziyp)NJ_DaOO1iK0KfI^O;r~Yre4&B!44jPqk3Ib7E|@dQj?)Z$se#iCJlnu?4D2%S zrQdh@_v)igocMDmPBQSEzc}qv!&Rg0;b%LXcm(=8cKdS__Nec1p~BZGJVoI)g{La~ zIfb(n-m36Sg?B2Pukh~_UZ8NV!U@R#6rOQctNC1oqv26lhbJM)kXKmCPcU#ovLUaq z&Tk1Loaw>daN;p&KkVr>*1%^P_*?^DVBpUh_&J5As`!5d<=yUI=7c$^gy$>!ECa82 zNZRZ8^j1AN-mag_9yr^M6Ox=b$-v!-nG@{tMGKrb;iQ4le%a+&?u!%cc#MHl4gBh( zGtRZkvv)r2zzGIsr=0fZCl{Yb`c*1@64|#eu)CLJ;B$MO_Gtz_&%hTM_!0w8G4NCa zryF>NfoB_dj)8LwJlDYU4ScnMa}Atl;0^;PyzWe&L<1)oIN87>3_Q}n>;2?kCy zaFT(O4Ls7o32!>xXYV+1f`M82PbS;*3#)MABm<8z@c9P*ih)^`)4c=(CmJ}(z#|QO zrh(5gaEgIb4a}}}h9}X$Nd`{7-YNg)n@;?ef!{XpI|e>w;4dZjCRw`j0zVt$Ej#`t z+JC|!Rla|3;6n;`DEk)_{<6YdjVd3hVg#6^@2aVI971h2K&7Jqo9}W%$3L@Jxljsc?zHTNSQX z_&*iyRQMi+?^gI*3V%=GdllC1-KVe)&;1JP@I0Wf4$n4)f1%v_w!%6*-%(hH=er8) z@N8FDhvz|sb$A|9Sm(d*Dg3hX@4pn5xsS1(3Xjf{>G!C@+WlP$>-g`uM zD6GT#V}*5kJg%^g|6YZ)|36V!r`Jyv*718n;Y(C_pH$eb@Xr*!R^gu;c%Q;+l>ILh z{=C9ZD}0Z_2NZrp;X?FZDL+4>G5V`^{5vK8M`izOg;Vln`u6feUCmJ}(z{v(4Vc?Ml z9&O+;20p{UV-0+!fzLAVI0KJ2@Yx2QXy9`V{2>FU8TdQ{pKssxYugeTPSK)`WJo*!M`SYs{ywt$UocJ;WpTEv&pJ+WX-R{138~v3gln=Z8Rs&}n^CdSMc!PlxjQNz4n4h(~ z&r+T98zV6vZ?`|&n7>Fg#$(?x!k3WjbT1*viNA^8kL>RIjro#05}o${ZN%q6(?6_Y zvAcJ>A%CNRyA0fB;Bq$ka{Kq4VcX{f3@lXQQtE4j5f-5kexfl?%s-|2OT)+;)|!*?Z+GGUt!?y8<;U?dL|p`n_}RE z*PQa*iO&9UZPS?3op_J&y`C`e(+2(!%B$VINd~^yz?lYq29I6; z{JU$;wBrj5%+6w>Kfu&;nUP<0e^uM-{;I~hKdSNnGxD$QuW5VTKhs$E&otKkDUH8k zl&2pW_*nz@ByvZ2Y)FygFYR9Lxc%o^8i0S^$Uh0M%l?rTNnqPXOx6HA(ZD0En?_8v z*^dHFx8W4v3>zK|e5nmThVWlz!(TA)31GYY^T0TkEBbWcd)f6n4Sb7%KV{%sf$i?! zX4r2u@cl;k#((SAmfioe4SbG)Cm495fzLJYTjLq~Xf(E1t2q8(dZG;{8hC_(M;e#| z+kcP9Gwc)2KA2AXVfB+};1R&d+A_vF(xw+wzID-Pm*Ts%mBg>?dgh{;H{bZ%M3>^b zrTH7Vrk;{l=5Op8b=`!Sm)_GePrJ8z-nuJZ&H3Ye#dk7x=v3Z}Be{z2l5&TD={dCP z)tonBf2-@7%;^VGi*MWA)y_7~d-2MfPJQyDfdv!)qV;mMyZg638V+7re|6ugXZE^x z{^;sy2d8{@W%c;nFYbKw+|Xn7xmQ=wvsby_t2lEB?^tVs#pDGa7pi2%>UUR?Hm8vsb%xedg;=M>wo@SE?e>S@^cFQ z+mILWawR={ICtd!r}K}#Q*yO*=wz-=KgCa}`0P?1Y1W}%z*kT@7yRM+lV^OVQn|A~ z*NkuMdyu9p|J72@!t|SdmK%8P$uBOvbzg3R`@{FGX!~XE;!8h&O%>9KKhW~re>FXq zn>3T27gYFDTu?qV`lrWp-$|PLJn`2PuAOk`@~a<}?tew(qkQBSnJ%Y!= z^xb`T{k<7`>!LSuDc|4t+p}G7U38x7hLsoM{bJXT-kAcN;hI}G4Q7|Su3L}=^K4hw zs#&nR!u8zeuY`S$>w+C~Av4dl{Mq@C%XO99sNe|75r!h>w4uD zw&T)P=Dx|tetky{tJsjky8fKQHu-L0>2K_0CojB;9pqnO_22(hde11{oBOLd8y|h;&3kt~{@{+C zUps!$)!+7Zb(G!og{wDD{P}s^32$D#=9ZT9QGcoKruvoY(2*ci@9b>Q zIiLw3szB^ABY;V66etBW8Z-uU252nkOwd`NaiCO?d|FjG)A87?{I^`vUe_y#U35LF!=qi% z^=j`fWzwN-bo(INh0b}ux?xva>t%0U{mQp`v&TJrc5Y+p=g$AjrJ1=CHyk?k#B)n> zzj#aYD=%F7$=p-!hc5VG&jY!UiWSfOy#2LD@A<-&-5YP3ked+r)1RI#$j?nrs($j~ zrl#C0e?9V+Ki7RZ_l8px&c||VML2c6jPD@Yqt1Cc96NvBd&9<2t@HllMCUVSL|)C6 z_ID`zH*yaLF2DHZkKQn^>_`3)4cmSnZP#=?D&wW&tLv4M>U;I>8vnbCUzq#t&ACU< zTs?Ww`ulRPnZLig{>%q+vATTkKF{}a`3Cld$;Eqe&s5>OJhXCJ!H#e2y8E4j-suOw zo!fMG+jsx8{h{2CpL@xvpM3n0+{cgJiT2@1<-ShU*!NQ=9oohjPHkGAug#aec5=^! z&HqW+7SCqgPIm~1KkebrVA~8K(J^RP#Ku9ZiOzbj31Azc)z%oW#FAcGh@ELo$7T!W zqg@h9AlkCVi!FPBaDl(g&%)vr8{7uo=GYcki(3~12!+(c0^PcnK%{wUn-#&$npih& zeY`yoUWe7c7FMpeV)1$;cmwuuz(232w7}!_m6Rgihs;VUf z7g)JR$CM%wlw0ep((0^iifU#g~3p0 zK-H+FO;x13jFYO5>|f22Hu){B>pW{&b9<8yMK)L)h=_O8IM{UoQ0>PqjtJF}Q`=Wh zrOJ!mYiMIOHWt^@e`NnDb(iDY(PNWW?iorf>h#)mtQLD`!>oNZquMYUfLRqsc`|4+ zXaZ=O;`B~LcKboQLEWJ3HcsyvivX!VhaS6LoI~K+BYC&tt`|Ng%)1qLy(qD4Pdaj^ z=TAC%c=q|CZP9%ya#HuLv>((D(|s&@*L^K*Pr77I{V#f_z8lHthukB5lA(9vB%>eF z(e~OclGC!}F1-`iZj(I8M*Znn?E<8@M90f`M^x)wTs;EE`BQ~$)1o0mVMX1f>OGt} zfC_7xMb*_bQTfr|?5tQ_A$I8NHn6@Odze&-v_hzrsfL!%5^q`Q0#!d1mU$PuD_K?P zqSCS@rQj7+<>h7GN>4$4SxK1})t24NT~c1;E-UwV(M*&%q=gMhSC*A6c9$-T3RSTD zGHmB6&aXs+qCG7x!FFJ~!-ekr$}(@YyQIovmzQl%MWwsaW0!V1)8GAaRA!Y>k&S6F z?L97qk=I-1Wu;}6g>;SpTU>?>$?i%wlY5d&$|@?=D@44W3RKs4aaX&GOWb+bCR$ci zSyqV6p`NnE9_TJ(#ia;uae-9V2=!=5)L&sQOqRGSuyeAcq`>Q5LJg~#&e7z;83Lj; zeZJ->e+u*nXd9>t^jXl2pb)6if0SPbUZUO!6U_sjW|(Qae+NDZaUTnM8)h z?8hk{)P5s4=zv)Tve#OG-X8X;Q6E(la9g`xQ0(>OSI#W(Vf(wsT~OgJMEMfR1%cIQ zbYwK>=EeL*L{7qTH2w%^v~R4J8Hr>&w92PKDLR@GXEP^efcmt^XcVC!E9CKb*k zBAsTci&O%6;SVL0@=z+o+%xOJ+LmVOozo_?rk1(@E7tLsamn$)J7);<0uA_LwSi`e zD7F4pJUd)(W^Lm|j1`1iT3e+7 z4$sHu@LSkIjy-f14rXa=!LbzbsiZDrlh~h$zM0>u!G+TG7LK;4ZEu|hFWanOz13*02mm;Wr3RmTowcTM9UK+z1!y}hh8(EfDO15=9Es6@DES-k0b?;hR>M~c zgrS$R`6w^{!cl(cj-#C3Pu_l%uf_Xzyc5>s!aIdr=4wPoWn907GGgodQaeZOAGLkd zc2e6%?Vg_J(DNS2*6eeW)6P9NF?Hg^=l~0HcybdzB45xTQXA<4?Z*2qfji|oj*goo zXE!PiA@L+~eu`rlQt8f{1cTp@A`o9p_ku{5 z%yxt5!H~7W--NBC;g8}~<;g1cKr&kW1ePph2b8NGqTI6na;*_xwl9+{4%UWSA}#f8 zR=PLCDk`Zcv1GBsrpl&PWZ|$id&bNeIXKsRM%L_^b7rvz9(dpy@hQf2cXo8_?CfB> zh$ubDJb{ht9(TrpLe)bNe z*7n%@xXtQ)GfNrQt=|)D?}>QN6G=P{x-V{LDK83)FbSNXFv22mA~3!MvRGmVI1%2H zJMf1HpK27z5p`pJEeT&(;Djhn6gUxhITZ1|1Wp1@V)qNT6Icq&c=reuF6ffXX5m+g z2uBC!EdDc`|K3yn`(g1@xs{Fiw56OZn-%6DmVo&SDuUV@9v=uvsA1D|X-{|(oF z1J-|(SE%kIve$p~PIiy9JtVl!e`J1W`u0cjo}LZ)Sp7%lFYP}pWXb$OQ4diQ^6#Dh zrbMRU=nJdeHcX|im6*}flXU4g?PhI;MN?@J9HS7#VJ~%*hV=M+g;k{(50;hsd>GH7 zbCH!LyKq@^=Q=vW*#$$CmyIL(lemGkHc%Z5(9G=+{IPf7mDZ5-REHqDz`9oT#c`tt z`kD=TG=BY{{?qXXm?TAX7vs+JYn$*Vj=u6lcf)Gqj33AqOoo$)o^+=EwM^@1!s|e3 zm;9Zz3czWRM`fT3WNgaN z18;SRMs5WedBvM1`XE_C7;oS3TQL0H8k~6aQMXm13MbjVDMi@zZKGR zy75o>&ZB(kuA}_rN728>`@?u|#Cr$c32S=xk)ynBZ9{NIT_~hSe@hn>7y4^)4fr}% zH?uA)OW28$XdfQRa5&RN+1ng&+V^)P&UiE{3*+s)ss+M>IQI7O>LBS$gD-oI%M$K6 z!(+Es-_calpI1irwEiLLs=A7oKE(ww`?+&5Bwg%Z8*FNCDx`BeOOP|0Yu8CVDlb*d zfwkh8nL4W;V|psfAsReWK2X6KBs|gj(#T&CF+{g&@#6rFGir-aZ8W5MO^ta(39_zL zzXMEHHG43GSq3;YaQa5W<8(*SdKo}F%VHK1n8r+7XrXoUrjXSlW zU~4Nz%XX(sckun9Ga_^6qESIOWCF`M)Hw30EM@EVE2>}E5-wWPEI(x&y{H^gjwVZD zm1&&sGLqKX;3-O<5|+wArGu1^2dBn`q9cYYu%%QizmxozMFV=Nlb zi7|IFIL2Uc=MP{k9#Nw>e|geYHhUQ=FMgpFb3n1_Zf4h)1y^?zBGDgyvt-pF+`GSJ z+K=A)-X~qRubQ*zvu|$xpNzK_b-$YO>-?=<_wC&I^CP$Z>Hdi=DbIYm^zI!+U%KMI z%euyW<+(MhYkpYt!}L)J`8#r^O`7{edH7IK$!*(bXTCZ6p8XVGBK^=@gM6Z<)W?kW zGh_CYN{l@>?#bNe#udB3cL@XWC(gVHyE$K2J&3>CK|P>u&=)~pKyMaIKjeod3I(lG zp@;LEZzl6-$c%TA(RLQzDTJ}P8~{A!WfjHZ_W{h)=a-dvF;hdoCG^W*ar%ALVmeOt z=7u6)+>GD%OZ@BbTiKB6CEN6%3~Ri^P zarbv6E>iNY`O$H`T zd4>el19=)B!I=)MY!Y)qBQP(6IUe<%h`F0_n_&+hX?~?@GtJMyYy2n7F!%CeH_hwB z%vJYcZ{-`N&k39io+~vH*$Xm z%_)(8h#9;b3p4$mbO>&W`60M@2w~q$^FtLy1>W5dcCiF8$G8lB7T#_#dZ|~aNQ)fK z08!lOAwMa8`XRsH&12UcOwWs-p5BH4xnHTcn8!{&#mVp|Fq;R8_mB>ez2Zc7R(AU^ zDNK44pAe`6q@OPJ;sPi8tqSh|cPX-))7T^g_Y#pJ$@r%q{6w)5zjom_8Qe=LM$ki; zy3Uy~Gjm1`?(U7vT^Cm@C`JAj=}qOPTzjC*2#&(XMfr+8l)e=AB)rr_O{E(Y_HkHX zIZ#_v2LC8c$PK%H!ad~{t!KHK8`XHpQ#&7AMgCHKPkD~&=SN^r35WNCwjsGK*irp_Bg}~y=AfxkpN3cYm)@o! z9FrBMw1EKRt`S|V!G9OfzX_0QB>!H27eF1U=V<%=E|4dZlIr~UzXedJ@xLR1Re|U| znRo|YkQ$>%k4Uru_!77+C>X8sy{ZboKPe1xMz|(5R{ztxuK$sjlBiCi2W3Fi z@gDq~rt5HBcNN|wWwd`nwYpRgShR%V5X(#=E{&6(PNH$wS= z+}V&L_ik14BuBp^+4Bor7;~|bv%5!f_TQDry*w>vxM%;JiNgFzC6@sI@Og7lCPwKr z((ORJ`kUrXkWa*e%)&;fcVZ%4Y}o#)bxvnyx7Y7ffB#AYaPoH&;bim>;AuBrZv>IK z`B0dMZUa#mD7?tW=!eT+pU95Zi&GcgwAZ?1AN#$MUe(OuGTS@WI1Zs^?)Rf2)ypBc zPho%8^(2%6(9;jOL2;mZd9Zqt>Sn6VD1PLp1=5dBL#mtMhFVwoK(uZpIjUcufBGjk z^R2i2@Saay`mN7CbWJz8^^dGy^>1DjK70N8*Z%G`T)%#>>sNbz8LWP_=bypqSNrd% z!}aTM{rX<(*LAPEyPiES^_}m$F!e_MpD%ddkNTDB&dvdT*VVu2+Ur;9H~h7~>kiki z|9bVSGk*-+f2Dk3&o2YjuV(%ksD33m`#OQ)`gOQ|eXsTFfro$T`rg__-~HbHn>XJ& z`sNao8K}=n zbFRa40>g8zy1x5I)vq`F^ar26^~*23^2(v@H5)p2J@bCluN3Fbf0_A#;rjLcs9&9V zVt7tqxc~aV1OJM@Y3cf$IQ_nL%bT9^Uwn4+o*!@f+|FBza!~xGw@eJCCo4?9zu}j2>Ye`+t|6ecW(er!zvtdU zBpFgLr33z8u0c$*yf5nuo`q*Fc)A+&Zq^s*^#+tM|H$;;15y9adE)k(mB+ds z{ZZ=iC)2XiYbpKy(e=N5eERpE!x*mr`~N;ST>tl9r)JNSXk7+er}lo&nGDzevG!xQ z{zv7FXRtMGQbPWv{(slku1J0SnIC`Qz}Q{vuE$@#?)|F&DFmJW1amCI_5Z(b{qM|! z|C)0;!}b4g{V!|t*m&#R)c;@q-d#0+TI!v+^5MC+?Q8nc+f@J4{zN_hvm2Ni1)59P zhz9m;5Y7K|z?_KYbe4jp)4TXfZ|N9^(fp4zB^g!Eb|92`KSzhTHZD&@A-10bV?%^Q zV93VbL$L+ExIj}tgUxXab4+iASxRc*kpPaf9cIewz5Oz1x_U5e6$WK4|?Ay?elVh=q`YP z_5;yc!sx!2IQtbT&Gch`Co_uEyLn9gfpjUK>Tj)O?DI(UK7_p{{c_ZMnwN*4?`M9J zGnG2_v3ne-9MB`u1KgA&yZ3sok9m#+_R(j{a}D(Q4mczbXMN+aZ+*}~^q8Xd)=-PT zPMvotPSJ?FZ$4Wq4t7G3J9a40kj~e6ujdP$KHfN?wbmYKw;Da)W)*T}m^I^Xh|R=K=o#2G7!td2|g-*QcRpq}nsaIh7}8Wja_rq;FLw$;ev?_N(I ztMymvTh~Uy@c3Q(3q5(}s4SSL*Qauh^l^u9=$9X{7TI_R{wlqapg7q7^!^m$(4v6h zt|R{nk5BK8x22`6BG}L@4mx7j>O*0(vaiQMNXFsD;lRh+alUaK&XtpejgCkY=XyEx zD&TNEf?aU{|n$fE;) z<+)~}u8SSZ{$9_!JAHkvvLNLIXZY;pP?rA%H{W5pZ`C>R- zs;$xAjI*Wmk#LcV-j(~&b_CzTJnoLY+w_t5?))vzl|tR`M&yjej&;bLXD! z{Hg3ApFc(Y++-Wk*dre4aG9L?)#L{0kUJwlG;T1@zlM=`WQ`*0OI1>1=T6}emNV|l z8+F@{bBlgZnE9<2k4#wlTITZAlTWmi+?&4bm7ULa_Od*?knuc`@)1r z^Xh^#zO~Ht$hvEv@G~v zkB#Q{6>OikX7iXaAN~*$C0CJ5ApF&172=wPe(qKOezxv+$Lo*NZ`Snf?2rDY^gWk= zXl{hQadb@NlHtI z@?MqbxLRR4yM>-ZKbH1mwMPmc61MpBYkBX=OEd|Ir#ngFqvuGh|8_hs%|9_-nz&w- z?k<`jv3CB@b}9EIrQiKKDfbm6r_;>!RVjDZY2>;;Jw&H4@63irAAO6c|~lG5IJN~;z#He<%+k#Ozh zVR6&I?3SZP`JX{Af|8HnP9l)&RoqIUrw?FX?2T=EbOl7C_(v^Wrnz{7lW ze&}>Ww>OWmwAYUEJ3$*kji9w4N>h1qpgIg!-qjK7>D8>W$`G>!C74?ai8DOqL5tBY z7w-8=&v2YmtE}`<$cUoj1}`h-WCL!Q(&rV@4Hb<2>LlX$CgKX344MVnoN$bgO7Z>a$~B*Nfv=*-jf_GvlRk2cZvou`sspuw_Jdp(9^;uH3sere z@seZwZO}2$^Ps0d9g~molc1MDPk^2UAv1VNDdQEeg5nDK(hw5&c(7>SNlalZz-1oo z&En`OWFc{B4g_%#mWmakBu)eNe7s#AP^@qvlqv$P{xA(D8bbLYy5dand~rt>0P&gi ztI3>RXVpjF+H3TyxY!I=6;h7F#cle~m54BCZEGZt=sg&rkxlF^KSYNR%c%oc;|er) zIP701^yoe`c`;r?$RkEX(33AtH4n}db$mmC+B|eShVXhf($vjXl+TbuC0;YF-cThhhPTV)&VZ|Lul<{x^$%>R2If1C*bldMT|NFK|*x7 zTLpT$c$cTQmbXN*$%eAHJgHQHXbkBZ7)n{uZ4A&`MJ#5mX>f` zHpyrZOMjSnnpZ13m5HTb^bQ*e2*hF)5wJWnO}Hsv?%A*WA+VYo+UAd@c39wlyuLeHf|Y zM^zdi3)C(?t>~~IpPJf3_(0NG#K(=ouv%wBs_|?GE2{!53vLCIRhk+e%fh2PtEXd% zWfkXZsiCvo;4)%utNJ1c6bxmq?{981L5kCn#@Pi@gG#5(RvP9v25MK?OsQbB3ok_C z;m^npEZhN|0U8BL0iEsW_EeD8!E3|G`2`-M5q05>t|qIdSUKQNNZRygHuPxV~0i zR-^LS+%Z!kQzH1Iq%Wxp;AYc+p0dGV`fBnfyMStjG1^`wH|(Qt4*RNVQ8`qIL)0^8 zTrq}eO@~d^j7)j5I?{(qk8Nx{R!43viXtRqjeX(HXdE%qL_9emDN3f@=`ka3~toLEW*r zo(&bmTjcWhC4!V_F)t~|f!geJN;qn9DpgQ2Gh|ZOLTdXCHdAN#+ht~n6?Q7tnFGbk zo^X(p%}F|GOtS?MAyFSXDnG-IaHGukx3MmBegj)b|6$=r#xt`8``d)ey8Lo$nKdSE zs%KqAwp9bzW((VDYs?sO0vD0C;3h;&TaFR;3Q(Sysf|PqnVF7nG949gW)?0co0B!m ziSUicA@71bTuczCuMgHzKRDuW&MRzWhMSq5HO;azXJlr=S$xS^nb~l{=Jx_q7=F*3 zH49pJxiV{3mQy^>6o;EvUWpr3r5_Z${#6HMe5tVH`G9dvK?ZD z>Jd}x0i^V5y2aNL=2B0Tcw|^rd`SWNGuFb~%+OLHV@9~Y!&SJ0rOv9B&Lh#t8Rb5* zv%R5{;Uq8CnO-1iY+mS)++d0!O>AO1iUlnqhN7Ca+HjwHgz9`568L6)biT?BG5|=P z8DY3w*V2|Q(o23@Bs2L-wheY$`7v#_HFjJ1?dTJcGSa)U5mzD8?Lq;6WZevFZiWm8 zs;FoM0DWp1(&5!Kst7X7GWM@mzL2joXJ=nI>x!(*tSgQP zik#VSXW#;-G^o_&WX%x)n3FZrsbUm5?Me0wL}0k+&G>gMdZGh0T>j7s%32C-oh}-& z2Jgz8>?@t6$!PIn1u#2nCQ1`Z;uSNqbDTN@mcXp6>}Yw1%5dX{*=aP$|0azeO5poe z{w^QxL;mabA^SB^_D-Zf)+77Cbr1hZ%g1mZ@Ly*5^>12q{yE!~;d1lAC^ros*d}MV z++ad(c+8__691|RzkkyfXRzO6Y^7>Qze5aRzWiN{XWrj-XSn?6nfSkb`T5|sJpat) zXZSazf3Dw@25VycwjZvB=L6#Z&i$|5z6}2+B!B1qo3}0>;G$#efxUUm zln^Vb?7_i`Qytn?x%ic}`|zgLcmk;O^R2eMx5wUD^890*=(ATyx&^#o9`@3Jes$F` z{s^cN@5X9-5o2?Iil-tw&K4E9fLE@C#pj_l@h}PpYxL?_WvDU*p%8Xh>1`~wtt-NO zXxmwAD}>>oTDlSU5RdC!Mk23jaOsWi_8!~z3oNhdpf=XOPqzHZ8C;hz*y4^5!-@h zAm{d%ShWBvV;4&p-xy1k$wGK4S3mA0etDMIvs4vbI1O2Q z;>Ow3B6A=X&FNhqP_ZGE&^TED*(UBz4OsNw2?9fWfPVQJW-43R6TVsQ4w4(EXeU(+ zQ|XBA9g;5v{x(0HmjL^D1V$5pYR`v#R?T(3reJfEe=TGX_}GRYY;v<#NNtWfm$fZB z#wT2RjPF>EJ#2X2wiJ8RmK@_Dg~^PF%!aZb<=yQ+K}|8p7L)}gWbfEgqH0*l;@CU3 zoW!wrY&ntk18+G|_F|i-EuTljAnna9CsAu`Yly|q*pY%(Rmj=*pX{PNC@^(_c7w#D z_nl}?`%i59SCo{K^=nrs7?qx-`DJC^0$;h;lV4m>Tvp23o8?B7I@TC$Xk>H(MSByR zy7&5H{7%plpgA8q#*08pL5-lbppBqALHB}ALM8<~4U`Ug7Wie*!ysp<82l5vCG-M# z&)T*?xY-{NGKgEo7KYI=!-TIYo%$u zbpMA|)YF52$)$sql|4f&2pmL7{yG<3W=KxZ7LYg#2W@#)ES8sRzC$f*L^hr|z|whi z5yj$pwYt6kBKhc-Ca+`rQ^b0Cij7$F?wp^Ds`%O+xp~HW8#T(*r_XR1`5OC4`dzO} zM*>pN9fi@@pK_Y|W4L@o_mKQO%7QRznQ;pN2GO8*2M7Jiegp`%g8#2*0PT5yR!< z-==*0n~pDr+mF^zAZ#DI`-bPIs1_HGeZV31mjBz0zlYn8f1>g+JpPUzyn&zaul}6RB0Fhhuw5^?(W%+9w=nTC$ z9Rf$=9%l`~e4*RlVyMSr_FI(`OQ%8W7rija5sm24mfH3`EL(Co{C7wnN^f#@22OXR zxd{8pj2Uz&p|Di_FNft24;&pNWn~%I$M;hw%!>^^Yu=Fmre*UU4ez8)$9rtsIgHdA(^9?K1 zT>3obek!QU)KRE9BEqfMSS41;()pdSHIH#(7E_{v8Ql{QExER1pY0K$lR)Wc&{+7V z(YcrMm{6Oty3zn{M-LKKi6^{MCr+Ems81hP-zR#GIjt^jjUxKBDhlG)hy9mEiX5)p zkFR7&Z(4C%Kv3?r5bIf6t$Ml;0xQ*`r=t&`uY)~^3;l|m!{Cx&Jr>kjSo2xvbuU=# zDXokxw)GViFDN=qv{ei)34|hn(~0W9UV_!h!TK>{h7xFsx7<4s4B>W)+O~9DL{o>W z5Ti$%TT`b*rdq)WuB5|?#9*C_UR*udfs(n1-`UQtS*nuNG8o)haKZt`W zm80RH8#}a^Rq63|ySESf)sEue@=%x?)*rzDhsb z0*q`WZx&juZmppkO48HCFypd}%nYWJ!Iplsr@~HZ|AkG0UVC>*gWlYnuX?{x_=h`k zB|fCMD5KJd{&rNmB-en}>=;DDwT2O5XpiY0qo^q^ z5sRQDo>Dw}R$T^Llj#dXa!rK*u2SIH;UBwek=yI5WDta0WntEA z`a4~+tl4=U1?5ZD>=JDtUuI?td&y>ID{=iYGh2zvm;4Gy=T}Tuf60yzDG{GuTq<{} z5}YN>)L$hzOG(a(Nz#|-D3bevDbLb#aj_GBRAJg9L{GMX=POKicGBZfnD!>qGs(aU z6{fox=_xnx5{2m=P}CVss<6Ie@^%A%MPa&sl%B5}_+Eu| zZ~xl{en{anq&oYNVgF;p{uzbU^^xp12L8RmxJF1kFB$g#XV~|my;q`wHHjOGeRR9q zAoT=p`@yZ(QVMlL4Ah4M0cjj{RDU^3nCN(FYmGHen_f`))-}A93-cW_Pw&pHO6EV5pKl@F zU$@2mcH8^CvtH%1Z1|%}=OLKuw9@{k!7g(xv(;Fr+VDK$ewBCU{PWOfhZvqexcZ0r z@i=A!#q9_4U*$hk@ji}sl6%2sMtJ1Bm>);yzRH6(e1UrZuF@s>PpS8Ia7tTxGPAO0 z&bngum2-03dHDsN!UaXe3m26vE-fp+##>QYRlQ{CvgK0J@wY=Gs%PTe3#RQco*KCM zr%qsHk=NrcP`8v;6fgH^P01lr8EnF>W&=FE-@itjGr=B~JXLW^@e5BL8s#9kbD^DX zJd|{yjW|Xp_J5ASicB^78>NGPasIm~#rco!2e$uvb-nZ7!MB|ME=qR(d-W5}f2U5J zVs=VMfa^ArL3Aco0=`fpJB53Y-{C3jq=PIasyW^8W~UMCEpDetN?!B4P_PY$Jv7zm zVWRUu3;M!&CB>D#{PHSap~qcWyFNKI{r&Y)?ogxTt^XmpwQ^|s*R)888_wswodU-2oEvN&u5p*Z0 z8+0#ZK7LIvp9bnJ@8vr{YeDls4D@Z7udV3i>7Y!I3seMJ0cs`g?d8{3L$<1yr+`vH z7AO;@+)9ZI1M}%ltS{L%`n>tdUgrI1L_9d3)&9a4cZUthTPs|2sfwzlmdEc zDRe=VpoHbU{NZa67SLKy2WT^>8?+s?5%xd21@9r4uY+7G!qC>sUvBT^PppC5N`yr{ z<=>L&Tz$*bM5r;;}e;1+_q<`#2`R`DY{3pXBd)xj0QpG3#>2PO^?c+Z< zvyXR=>*K}X+rfVevmQ_o^gH0U&XV@qz{&o4@HwDsNGG+AzdpW?r%dSMp8!t<9|8U( z%s&U33tW0mA7|jNpDpdXz*|B859Y5=g#VyhKxLrwK`%jeJLs}=`}mZ!KK{yw`uGme z&7g&#iJ(KUTMoO%^I>;hA723;0xt)j49-AFct3eTAAcCM8}tNdKj;vs7sNmvllu6} zm-X??kHRfbH)zgOV3?h_65;$vA1}HJGI*bp0}i@#F63agXdc3!i#UN8sP}5P4cZTS z0%U=H5A*$?CqTPF4}-RY?gf#~$vmXjLWI4zkJlIV@#+Pj!ajbMr;m>;=;OD4tPlAe z;RLmUR)ESuMWEhl=)gYpdbkDZy$=3^_JekVdYAX{t6|>(-U?a)DhIhhnS|lSs=7Yj z09pZB2J(UyfeJvKHE=i3$8QMs@odm-jeY$2hCZGJs;=+j55TUrwU2LW>EmNSKW^^h z9|Emv>f^gYef%8I_t*CEFM`&Bt_S6Trh>+To&k;g2Ga5-#1Yg1Y6Ufd4&4ZI(B2-T z<0lbE5Cipg!Va{b=w^Hi*t<3%KA;XzD`*9%oH*pS!2WA@^zpkucYr<(>IAI=t=f$A zh5hc^rF`n=;RmP}_z-A6=sMV+wWW_IgWmii>_A6A&x2~=#&p<^f;&l|x1sww=s4(q zLC-?Jx4Vz~??&2!t^pN;+@KuLPrrh=eFJg7AF}s>-;4D57UFXc^2k=C!#Df*m5;)W zhe6**9De|LP%4OlPQrW~**}8tf_8(pgYE@A0sH;nf8K*{3i{q-eLM~H)7?ma&~3Z= z_^Z%;=ocu5`|$0aLR$WJAHVOJKK{dB_VHis@8e&88u{!wga?!fvOuXI2I~DC$~>s` z**^Z|-y;8l@<3^z<1l+1bT??@A$%85D`*9%9OMFJg6908kAM6i@)PLo-y>|GFMzHG zrGxH)`Ge2*@tZ(PLD`_Opd;{qH|RHbXFfTf(0#q+uInW4ST4D!;ME_RGq7W-12<->?!g#tv6(W7~{EgjxA%7#}5pgYFzS5MJ?hN#|^-d{2ki9+p@!~Vs z_luWaro8FCJ$@7>^LyCsBTihc3F~0}AkY`xLy*$H3d^yh$ z`ZYX5=&$4%LO;SYg#LP-A@n!!EQqt@O+3pYzJ+JGhC!g+hM=_d=YdY~o&v_!jPU5%1z&p}&=Th5k0~75Y2S;UN2++$;3=axnvy zvX3vf$ov3b?jnAWFBkep_;R6toG%ypC-`!q&-rrFAIo?R7#o|yYb@fayv9X5jn|O= zSc}(?{@4s&L;7R0cn#@~&EYjd-_2J7vat*KN{hIcuXGV#&Q}Wk8opBKujDI*euS?S z`s?{hp}&DgAkM~a;t`AZ79MdC@8S`mzm-RX{x%*F`a5_;=d<#1HcILjMR~FZ7S|^+NvyUoZ4IUr+j}jBfyAsVRJeMLd;na1l@A8%RIZ;u}am zHG^*;{nRYJf%H>z_y(cx=9>Un>O#KBBJSmzT*R02O+vqhZxZ?|`6i(s;hTj1dcH~M zZ{S-X&Qdq=Ef(=De2a^C7vCcExAHAQe;Yd6WWIxM5&Ap%7NNhFcfpvY?&Dn+@dLce zMf@P|68cAYm(V}XyM+D;-X-)o?;`yPjBf>F6H@qAi+C#E>LQ-Tx03z@i*F_U2^oAV z=}*YwTSJ;`dj%9p}&pq5c)g#4xzu3?-2TX`A&$l3H$g?i}(S)(?$Fs z-zoHu@SQ^cINvGsPw<^WpYxrhpT_uJFqW3W_gchL`Cb?CG`^Sg(=5K1^wTmhSR$Uq z_mX~E4&N*E-FzP)OIyhIS;W13pNsf%zE9}a@O?smCEq9XBYdCGU(fdm{SEv8#97)V ze!wEWg&%Mc@8So9{#JfK=x^f(g#HeGK`6M=av0{D_Nq8b3n%lPrFO^e1KTBcwkmiytBV zNjdz8(0B9WfNau2e%vDN<;Pvbm-FL7zlI+d`YZWyp&#MLh5mYeT^^ z;#>F$7x6BBLg;VhCxresenRN);3tIsPJTk@@1^-z$nWE#A)9o7bD@8bbD@8PbD@8n zbD@8NbD@uE`NOjR2W{DgTTHgaE+*SlziJyhnQY^Fm~5-|Fxlon-%Wm_?;zR$D@E4j zt`u1(`%$Nob!UpKBYRS0UAHGi)>(&9=a4=69HI`fQe|D>N|j~WkFrSCovE^n^`y$O zvL{vM`NPPoWRJdz$b(jz%uB8`nJ4`ChGgBDCcjZnnoR3GX)?_YqmPqJ0v1mpZdp8) zxXa>c#QkXdiFaB&gLsd{vxx7pcnvz(tGzGpcX8UFBcj`kl9`l!UM8lFnrRm0PW`)jyGyc2ym;ypDy zi};=zoN6$pLowo9wEMGC0|ec@JhacI76FA z+=}om#9a~IMcg0ZTZwm~%^=m@-*W9t=uBsxs_)S??GRj_@1pihxp;G+)bQq z;|qyf=%W&MZR5*{`?v8L;+@<0O5#1}!x7)JjjtzucpKk9obBM7h+F8}5O?k1UBvx6 z_*UYbJNP!@J!t!h@7ck35apAl`F?XA$3nF%|K{N4T3f7V9k}ZXM@d;x3Fe zi2IN88seSD`AXtFSky;+5BlQ748E;`Y6^^bRxoa&Nn+cprTKUfyCjDW1Y$ zC_tO2Y5BL`T7s**TGm9Yyv5~KJ!}}$Z`PV%TccHjJ(P7=)-Ns&ieP77-P$SG)Q4wE z-SnE)R-q^^5yIv@?B#PVDknMnZqb%7_HNgltxR%>u=ASC19hj|EIV=pM}1EtFoTm87vtPQcHcvw0f zlmIeeqE|bLO`S**UxmBc<16tjaOW@c$txX68Bg?nL3xp4nTCzf zvRUK$EMZ4GC#s7JJY~Km#ihQ2nFaY}i_42kJYLq^(i~uQGwZPHq7_*y?3;C^&~O;d z?r${Ha2IDb6nKlP;UXT9-$Xf!Wy zmMQNR2eil(9Gd?QJvb#V2Zd?01P{R-rxILIw*lIn8A^H>YSG}7*R-# znY7Gk2=THjD1Ev;HH_0whO8e|fCEeX!M0MI5we;Zz9IN;lULdcN`|TjN$7}sbjyn= z<%i&(mWJXr?Sb$*H)#$*FDk4R)z!1)?U41A4xB*om-p2URX?hr{Vxct4&o+gTz*Q4 zK-Ede-&WreZc=rrvXJGoVqJ6Xq9QLz>WpVIX>XNZtT51A8z?Mrmlk--iVH}XzK%^d zKNLjnv>Q&Tn}OS*W9irG4@YEWjpG}{Aw&^W;LQ!W@YtbJ>FPC<)iyj>A^2UJ_fx2lpO{BFYj3ag$ESx+N2#2XZ zS#M2=h`#V7-)sD{pe|4e=sHjcbR*~~(DR^UptnKWK#zdtfu?~dk@5L`wb(A-7Qp#j zvWllRRlQsO5bSUhxD=_2pQl7-9a?_xpCLt3(5FR9FEXmH#vcjT@=gP~aTKIF)ftH8 zDqAlE0`i<1ic?98zpg}fM9P{&>u|w3&hilb7IBydB{6!sNJcW2sXT+?(7z1PXr(C_ ziBRIFQy}X^@$vX1?jPFN zP4d(+EW&9T;-b|8PjxYJHeS2@z5`-FVUl6jr!_G)HIuP9 zps#{H4bl(!gSm_$9~Ebp7e`zzYiXB*ZyZ>%N+i7cw99U@kq>$t_^q=n|xQzB;{&`=k6mS&Yy;ZLV z4X86~K%F`L0*2f)6K52eF@f={S+n{X=PmHYGlujPS6mTKI-apxI^N%Pn7iS8e+#$t zx4#9<2hf09S@Aq4KVY8KFRY54;1kc_TOx-d|Q`^iH(Gz$b0kb?a+ufiE8?`af9sNP$gZFSZGV?kme()rz=Y634-Dx{vK#K}}Np0OCpOo_Z zN~=v9uO{>03o+Zi+J?F^k3OGl;1Et>%TN+;^5f+;3#u$!K7{gMU~BcN(z*(PME7C+ z0-g>@Sp1vdBkakT`~(YP5M%ll)zyMIw6$PKmme>?Qz1WEhWgKs(Dr{uKggGytgWw@ zc%%0^GsGefq`pQ1pxHk`c19`j`pU=lrKF-dRWrY z#s{t2u=znnht*(tgJ6`Y__YoS9my4YE3x39M2%ml>T=Igq+uTj`DPA9Gzywx8b4*r zHQJ|PTiC1*(~7A*RZZd+xsl^dq1WrFBLhqMXcnGw8j*nNSjw`2Bdyw7->6vWH3t{7 z-%{tbJHG$NyxXg5%RR@IRYAJnv5n-MT79wDa-s-E3-;91HdHL6JYtgy8+w!#v=<|w zTsDU)+*qpUWed@3XdPq70CY-F=3i_o82bspSB+&;DLRU=aO|$i!34$UPWs!LoAG`E!SWG(~7Cv zN=bGBmdFitp48I%QVoS_tcz&jjIVk*eWt*$=AE6ET$rAomRFnvK^8WiAd$<>5uS!Q zTBB;}>##;!PznRyHiNTBdSPi@`4ZZ_EiEgb7Me zhFvcS$wa5NB8l8O6fJG;;d3WON^y)r9R_iNJ*Wm~!=w=kMOr|Alji6L{h{jSth zSqg~|@{)_w@+TCJhY+LM3rWTNN{qCPn$2rmbT2gy=ru=lqvTA%(t@he3K~74`QyF? zQV*aYEQL~2B!$CAS8Q+J2zL?O-{7j?=D}sbO@$i`Hw11V+;5j}Z~qGJ9k>_a?u6S2 zw+ZedxGJ~;xY2M!;0D6|whnRN-htbMG$86jkCxjk>6Uy(RJbTd+ehp{mX<9fVNYn{ zuUsrkTkduk1tO$mQ&8!UFw9QM%1kXz%PEBRNK|hGDokVE!<>`nfQr}GgHE`MK$+ZVk|Ew`5pB> zOvmIA8anBFhrN?xbeW#ng;}$baLckDW=YK+syfDh#?0TV5r5b~lnPClM zwZKIZQAHX`Q-?yTtci&AuP_%%@|86UY6YojIbxpAPsvM5%dut>RGU&4G|pKSBRML$ z4`DO}!f$*Q+YaC=%4HJe5TJ7|L$(+x9hIm_!6*+_ru13Ey zQ!v_yT(v>}3hOHfnvJPmBcu1SZG=@_Xtx81`V1%n1c3uVhR-B#$9imjr+lVIi zUWqV)PNFEr9&1>5?3;okq%B=HQJh0DT3&W$0jMfQ=~yw0{bsT8O`A(fIVv0Am^86+ zNE3mOa(-cQt{cq>vObCy!ewM2HK`yJR92|c4&|qG-0xCs3{PouQnCv3X}>)?Hx>Gb z)XWr0%{e1ldtWk3%ECicuHZss`bLJXX`^cDR`4xwL*NF& z{T2kDhWAFei{SnS_afXTxOd3G|8=;p;Hm&;!Oeps`WG)sGxn=JnZ^j2wzOU<)=o#WGYG6zUoBrM6)avSQs#9-Ccl{N~=gWwYcGeQf# zurk5?>+zKPXype15yZ5#NUR6{4aMOKduh5CHu@^Db~Kc340H&AR8_xJxz4vro0^vh zXZU18qM`ayy+uu@sOU04})oW|dcDy27zFaza$_-+Sz>6292+a_a zcuLY(7mL);WbrO8mwD4e?ZljGJ!0Qj@R-C(8I3`-0!-3lCA%hAL*mnfx{WA8A+Hb& zjHzc4itIH?9P%uo=Vaq0!n`!GxX{fss6B>NWiri&Fr4G1+JRt^!$ zT?7vi+)27L78%tf5kyVj5EWqgV-N;4Ai18Yp$wP^!|{bj94(hlru4ymXS>?&vH)!lM71o4OAab!dHMJzEr-dbB`5W~{(;3#th$QzY zeZ@$oxV~1rQfj@8o#Ze)K9yx@-T0;BDU}cqo{U8bm99Q!ny9o0>6OwZ%S4fy{MpsC zD2pkj#9D|=0FO>3BwKZTqt`>C+%W)!a#1*5s~mO)pHZyJ>-+<+ns$BKfz#hu`uR!s zZW;Z=h`?=6AOO~N+VuYvzxl*9{+oq0qM3hPKJEU23DaL(w(X=RwjT7v_TSe%@!Gqs z)5vAGH$5?G%32X_+5e_YJ8tS>(;xcb?30T3dTI0j=G_$vckR>{pSUJ*n6T(aM5w!M z1gZNqM1$e*qKAcGAdYk?4-UI(r)XcazuJB#*0!^>1=^?WFT!3N{q||!x4+wdzD(Bm z>u*>8VNY237e+5FkZq5W*q;GN=+(Q=9((T9w_pDO0|)KBk0Wv4{q{fLz=IAx7TpjIrb zJY!K+bxp1J%sO9v!{Q}N8_)Xd-_HK~GXFW}Et zSFXQm!_^zF`Ny?^>#o1y#+z=w<<{G7zvIrk?!Kq_-uv!<;K7F;e&o@|9^bV2i7mmc zPd@eZGtWM^?fDn}`QpD`db#D5S6_SmjW_@O)_?x{_B;Rg?t888fAHZ)AAj=cXPg2Z(E4bo1KPkW?58Kd5IX;V6^k zEqBIJ8>*`t4erKVitGD0wM#OD)XKo-5DuiM_LY!2-)*!y3j6n>==M z`Pli;^;k0BhF0T*FgdL_uP|He?&c-U zN{fid45{Ui7A_9S>NBuEo6>-_Xc06Zk}Gj46BBQJT`le3`LOb~3#IisEMMp}E$H+h zSh-%9pA2@BG@*&fEh==6agLuXqQJXGa4u3cIkYonf5(HeFqzl#^FPmFJS;tQ$v(X)qqh4l0K7;r}~vki;(+EGBm zFIxCW-_384l9l*eF8H}LUDJEv1MaCxkl)XuzJmNYD33b*ric9O&c62oZO7@#eV+aW zE(CWaTr-s3^aLj@T{C6%s=iYag946Hfs@Sojp|PlEzAwHmlC;&NUiG76e0VcoL|^S zYA`0gXw5>j7os?|p|pxFF~)h0@(N5Em>uajiM`2KK_dCeY={0*S=!r=>Cp>6XkYBl z-hTS@KVa}*OrpixYEL>g^BnZp{OxUreqZ`Wy=V_;M-YAcr_jBx#@(;UfZ?M%Pc9$VEDHB3=WZs;MOzP5bv>R4BL@=SM8Ir4jVIeCUIw^t5)aN(ibbh1)v*D$j z+UwNHdGue=!bkdUev6bE`SqF7XRkigLPUEApuOChWDh%|wzdM?8SZH>uiPaLC%+&G z71)(xu%lIen|YvjSDt9$BYii&MM~Ge_Z*l$l*=DaMhcS*w#DbEAO#}P3yy%`v%l6~ z8|ECpRM+xx$gR4QR*S1+(~`2S0$PFv4A^0X71FdBX$8fh1H1XfLc1v65Jw8$nVO&E zy7gh+{xUhiNJGYpHn{-TJVVi&Y`hR(sh2LmAv)SNlI9|OBom~E@)H>sM6zBeSV&Ht zVS^kjD-Bn*r)JK`EWoZVcHZ5YIWsyUP@>baa&cH1n~h0@S=jwfD=6qB8iI5sSg6;5 zYUI`;m(Z^0zw!yVX`22|jC&Xd!Q=K0uF=l#O|Y9W8QfeZOkm=AUM${N~LS5t)k6|}HP;vm;_Gx-gJIY8pbaVTGlgA#6xR zNKXW;^3+sd+j_}DPmPF4qRdESY5uTvQp1Oe#ll-sJ~ku>$QZ9{~TW}(i8Kv{4~7)gx8YpRW>nVLKr=7=09$YFwjpwveg)K4L% zw7$WoH+aE~duXfE&;^1t)?{bQ^@|9fT`Np+xvLNneRyR%beugImHu>b9Od3QMiZ(4bIZS8%sL5fnlg`} z*64{^Kcs;f;#8xB>M(jFPgXnNg3WA5ax8zDQBf$l(69+@MM#?@hTx*(ybm0?qn+HZ zBX+cpK34uVzinqQeNT??%?!UQ?@gmH=HM}T7?bBPvKsXjEqtW!=C??R+3^*;DeuEJ z<;!OHY~#Brf3DqI`iwNblWdWmXOB8msEWIc?}OxLd><9%`;>^^jcA&arL(7wkrkf( z=sz8phn~cjHu$i^P?Y_3$TSo7-$UlLa^e~`eRK}K1COgMw(yPkT5eJ z>Jh^Jk}=B~N|6xN$>XWv^RN-Zo?q}_bg~U6M*T?2TemZcr5Ivb@w=sm&RaT)R{g6AleIW@&1`hBIz`H0^Y_YPcG7pc~LBCZof& z!%=@3g!VcaLh9!eHSLalHO;xdrY(XSe}JZa1UL3T*eHU_JVev(8mwt=>eQb!?a0ws zrHs+EmFq2h{Fi^bJolpiDBrFf@?G+id%gpbzb%*aAovhnbX5v*}Qy^(DJ>X(~k3S(U!}EU{z=#ih>{oz%?6 z9fxxsvb||VN%>G1FtskR#5l77TQELMy3*qHY$RAp%95~n=czM-)0TK7~?4%|}yTePnjF>A*9gxZ|wqn1{t)P2AnxG;Ai^AH{$+DfIciD9T< zsG+TVhkl)OsyH_lI8nY!jJG#c!p&3UyVVHiHQqtvyJU79nqSjy*CtTaUibJKSOQd^oMH2B9P-}pIexw3 zmGoQPt;X~d3bg9V*1_u*u6C_hxnWe*@Kc_7{+ml1SO0xQ_VT7G@6@kKg0Gg(zHR?2 zCgt9e{_e#O9e2NPZzDdv~uhe9lD-s8yM!Je;83}wQ6lX?ojt( zys=tvo~^32yxKyHC#DtzsFF%L^9-x628V{xZ=UgUUbY7t1u1Ae6}2#f?3?#jEMVr? z-53+-;D;H+e4mYxu@ux|0o%zl1Qle?*%Wk+mWh$lt2JN@9j6s*6Ky%=eiLkd^TkL! zFD$-23{U?Aq)#}UwshuXk|YZKn-;4cO@cIu+CbU+L#H8(K=_(m3Ty0jjhQ%6zP+5;kO3ofYafea3yeFI6qty zoEwgKuIyYo?-qOH+w^_NF>ixKWYIJ^Hlm#DDI z@W1;a^}8A8|JZlu#gW6A;k)ZSA9P=^rfakWk>@K>P6N;D++BOV8iwHg&y{XFevepX z!8J(J^y`kdiT}veJCFCR2yy0JxTF1@6+7C0^Q&$iz6DWM^!+{N$HT@FegHUE0CyGI z^FM(1ww3sew+V~i1j9W`;f&wW-mfG6Xw+FW|Bk-TM!b`jp`5SW(f;!lJKEDX?r1+6 zZXn#ZSMO+FfNz;_qv5FkmU_Kn`C#^Au=_Y8nhQgAX~mfkMAB$%@8{gVI3Fiv4bCAn zfYx~`z^Y*n7pcPlffNgrk#N=;-0^Fa0+~RDPzo_2>usnmSs(Cg30%GLg-(?HIUnM~ z&%jJp1umgR%z$TNPE*T*C@1CDiY{hh?}U945)&K=0~7X57?iL~I|p1K#GeU$681>w zm#|mD-~{3}V*iwPG06?u4cd*iup4c^?LUe0J{;~Za5~%(a7V%og*ysv7~F8U5pYDD(lbtb`VwCM2=P<2@PfW4Ls< z58y__kV3a%Qi1}@UG%J%Vm+i&~N z3k={w=CDC z%6LWyaEP>j1__C=p3R3DX5))oQ*s^!8Xg5%Gja;X!kmPbVh6JG3sN%O8A-wi`Xg4b z?EHNA%#}X#1nSD_>Iw1|n#}6zEEvkm%udnpv#^G&<{5zTUG>-$K!!LfgFot1|&XA*;i(l)YHg-}W{S4`HR#jGG&j?$ja_c?%vAF05;zG6;ab*bU z`^m#muq#nhE)TVUF0u<`8hWG+E!&u!^p&qxsb|U}O&~#9rX&phOB8 zN>wdv0^o`!56pks)JTQQ%o2OQT@t#Z zqf8jk!Xzf8KxG(D_}agq)VC;Akdav<4>3`((>zR$=6!Mr;`%-OFrME&-qHTtN0xJZ zV*R#%r{B}z=k36s!u+)p|5M=~;)&&*3$>6}L4YY_3Rr~aVVXz<`;3_?Ra%39s0x=g z$UBF~7NJiQSLGS9QFiPb;Gl1#-6$kQ@m8kS)@2*?$ZZWlMv5u9 z2~l1F(FSaSg^cJy7sLl`CukkGi?LylGXo|!lTy>Ol4d|?pnfEiH~gEpQAYV_*iF(> z$Xuz%$QK1*njc#GTyxze69g6H{RzN?-j;-rSV>6 zyjL4<+UGO=Q~Efb%=s}rNz?9e3FHy}pz(z)WWdm*-5{@Jn2oH)*(`*kRF?=lh#{RD zpJd)(Q&KB33`mNULbia-EAworP+*yi{iCq@Sh?6t2}YBO$xIzKp~O%{G4cUt(hvnZ zjbv0wCc?iG9Xxh1-5DYa!St3~sYo9BKgAy3_+kv2bQUv|6GBaX3!wM2Fhqz^mS%QY zIgirW^Mn1aH2C9SU7d&ad`z;Wa8&4dhwlB$g@_SN!Mu79Ch_D4GTdj$@?i~DxxfvL z!bUc3bTJO}iXlp#$i$!o&2%JflqjX3WFbk^zK<#&p(c!7YFgU~*(T9)JQWaCz*e?u zys*K#`h})HVNw!SA}PyiYauf6#kere8XppLIo|ARysyNYp4sPOjR$8w5wZh?XJaN0 zS?w@GWADV8KvKx6bODKOg-ky~PWu?=t#4v_$TK7};^q7F!NxzC4DK8dUfi#}<5 z@>YsZ)ZEOvM}&ffDDZMjB4M6{GpeVg9YI3T(s3?2QZjM}Kc}`vUXq3&WT=}qyOYY# zK=YTh=V3XMwiFW?{Kf1gW;G*UNwCBmPM|OCOdRvlGJV*z#C~Xa04+Zw1!h4*^Rj)S zj8ZU)gpAB*CKb`mIiyVl!#dS+l3hIB258dIHeC@U3*073rv&n$;)~M;vb^l_H^cU2 zHquU-k(QO43&B7{|D3|&>>QXg%*jm2H=2wUPMV-L4Q3Z*;QVmb53t zdm3B|d|#??m*^NpZhZJgTDpfQX6Eg33x&Wucv2T3G>>DU5? z9xd6M5vRPN1X(7B5%RUsBzvHb%Gq3YhuIFGEJ}MjW5$WQU}p>CSlo&ym7uih8XA3t zRWWmKnmQugdn!t-Yu4MyTp*bfGY1F*1kn@5hdzq*1QKzFn?W4i9z{wZp-ZI%tFESJ zsji}Ku>aoW_zD4-L!>P{%|MN6qA}mFN^M$9L(iQs-Y^zn8D5K&Ba19^9Pi9(8rg-D zmCvvk3@_&{aghEOsh9Pp@n*|88gS(3M8i;sONFwpxNFcbsEm?FIH1I(-JOKXNAvU4 z6x7N@qbF!}L)vyrO2KW8(r98)2JGRI;7Hn%5I5PufG0%xc}bc1X~u<*6g@dN55^`* z-_h8?gXPBjg1OMez{3JSgp_%Tw74rmAUnpofu{ zBX`C+Tc(pCICa{UhDr(KR8qTXiEVE_MeKW$mJ@}EFkWPMsxZzQV}mZV&_y{4Iy+B4 z8|#A#1-C4RuyIMjW2b{GWYyI+>S_QhenfwRP&xghw#=Fo)T6CUXX5B_JoF^dvIFf?QZnD)!ZKQpGGJKFWDB zpR5VuKBUm03~{>17SKGq9DxBb^8*sBl z)LPB1Tndg4k|MgZT3>>z48Z2rqt!{#lBJzx%qAgg-?Ge2ITjelDsc{#1W~4Sc2ESJ z7c&T20Bps8rw~TNr2!pz)2FyjlT4wKBuk#WfnhbWAQQT7MU)KgsfSV#E;&dyuT`g^ z$68#NXGv_eDJKf-)d)67)TT~zio9dfUF(Bx69g?%J5wJ?W(1E`0@D@(vTBcyu9i}Z z!IqAsE%s#LuJunKIu~zXVeh#!q2|-Z&{_$1hu) z(a2;EQt6}aqI{7t1WqG-U*9k7JL-OE{|xRexNUF;Jdu4z%t1qlDrfeOJun>Bw)WPvF8tRTfF!yuMKg)`@MWMo!N5B&`%9F34s(vcU~ka`uBYzN7ZKyyA0 ziyJ6pa$5Q3yS5$vX&~dqcMqO-!o1fG`t8nj-=~jTo_focyWY9w$&wE=*AQ&Wk_`#@ zltSiK2Wgz8UzoHQ{U^IxE?^;!tiuuk#Y{&%eMMT*;ye^uU96L4X*>RGgmy zCz|6XbL8TJhExpHR%b(_2a6%Q@En6h#)t;fZBurTGDw!2U^L4csytGh5#mrJ zA1Ar&GGSAfpt2~XP1kVQ~O7f-}= zX@Ixeu#FffsZ6LocZ3hjof#-%5}+T8NemL0k~&IdNDKNke^9NESzDw~D8!MT@q=HScuP4;WoD(O>P6mT>X`+)khYlMxXSm^p4l4)P zz@;Lp{%)wZ5SK3aC1P3REg)sJP?#kp`f|O|Q$Jd-$7$k)mGW3rciWnBNu2o;v{M4oO@^`jgDQll+i`o=+yAyXdy!@5SlBE*&7p~rBrPojug%~bE^c86b}0p z4RjxyE!EKZJj#o1H3GB;(~tdK7OqfVv?1ZRM;AQY~lrjw8|14nB5b# ze}2N{B_Eyr?iCMj6JM$GWWc%Ls6$W(al+|vBjGxEs83QKqJBwzkQx>BOX{C{!BO(& z^UVp1FPJ(1Q1|2cv&S61buc6a(DyR#K@GOQ=c2U8nGf|pn%lIYf7NJi8|IuiN6c;X z!)$$MWk%C0U1IR3#!^pih)7S~7tPo^)ponyZj-=il!-PASv@!y(!ZgVfP6yrCia{& zk+aOCx-u+p^T{|R7Oce1OrgVRn0oPa9dA1JG;!Y>Bq10Xx`H>oijW1UR~b?<+jt?{U0&%DsuFA9;iW|5XIP*PM%;+uI~aMpIzJ`!?zLy1 zfqnbkzG=ZHzkfY6<+h)uPIhIy^7R{|w@w*6=eW#k*HwP^$;nw~KT}RNMKDcpi?cSp@-`n=c@$>FI z{;iqo=IHwz>P%R3&a+>=Q+C45*_WSIIQ_)h($XV6_Y5vCekS?cibwxA@_;Ryj~p^z z`z-m|ytUrti^gAeSly&xFva)y>>0P5KkdyYZa!%9rPX)+?fqNM%-yhb!spMt_r?6R zdtLnHDW4xQ>z?QO&)u=5;UClnY5a?J#=LAnMRi4;p{baXU2JX+7U#ei#R5ZbTZ2bo zX#7{bpv8bY!|<;ZV}hkwnjR8mp~cctCp3Eq9dIFvF-_%S8B`Az9%fqWZFWhFc%}jp z1b`4Lc0C@Nc;y1RyO)-sQKKpRhP>QJ^hT33?Y_dpvunS5IdRoLwM6LoI(3xi9#p8t zLkURUCA8uZKDO_4&?Yx4)nb1P>tos+vL;}44Snda2IFj1l&@l(u?Mpa>GsdI5!e1X zmF{(Ts*lu*&u?sW9+63#w?gKoSj$DS2&MFtDUJFZ;s~+i1_FOFcf#vg0DZYGT8j5`ciA zp%fdNK74AZ7J@*04GAK3kFXL+OFc>06kRC1)Ra~kB*MHH4d9ekSS(Tx48=1=n&m=% z2_{^aco`e!FEJXPw)puC^G&G7MQaY1+ z|Jv?{bHmYZ?n)wjvxo6^;%^Td>31{YTYF2=#F5dgw7iBI9Lj}>dx+W%imjl&`dY8~ z75NZTHw88t2-(OtltqR7&}{dHw+~EKgVlX1N-JwZeTim~GVn$a;JZsLyZA=m$Om4p zNtN*p`1yL>k8kAYp*6d?ewSZt^=C{^#&Bd*UN!c!meK?wKc{*Y8{%=R-Xq4V7uqsW z27lXBVhYu4babU1fp~M>6Ka1ISck$Q4J>8onIxq%nx*ZtFw$lAZzHJuW-2oqo8gA) zuC%*h6jUfdAMj8^FcN@STd=KlhU6KS7Z^(x)6UVPU)M|}7gpXlH9>4dZ9|CC1xfyn{x3yUfI%4(}({ z&N_Z|&@qZiE9-MjKdj^+J*|cY7pDM5Z=@MYo?Z)(afW_T`;P0Ckz+4mDN>(MZs>g zG47iqFp)}=l-WR;1YK9s4h3^5-=i~^qz6K<`4m+7 z5D|Ks4N$f>TZ!q3cPHbopo=bs&ZEtV+^j$D%J3 zOs*9}AT1PitQ12ZjI`}h&~|F;>!Iv!qMB)5j{|k2vJS=v`_}kkBXc2cnc^C4Q8%yq z1EV!0=hya?*}t}*1$R5#f8kz&dlK#;xPQQ{g`@g6>9NwJl^D$fQZ8mHg_!;!Es@ft zm>sY*0-tAwG34{=$AzXfFMDeX|J{6+(f`A}U zMw2Dfx9H|ZNabi8M=B=XP&{lvl3>S-Db(-8hApYGXh`4WFuguc1FmDL^9UA=R+3N? z1V@kaV^$sG?kf3o6mLGH7eZxaSa~QsQA;)%!;pY_fgh> zqxHs0PnGEG#Ky`!mSJ8q;S$(MmpUktF4vQ4eFhlZx|R9=VA%OG@>OE&OB$dSWd81( z<|_CCAFA2yBXZfU_VP=XK)h>@5oToFR4^v|6&zx8jzvnubIRBRR6aA zD%{#fh1(u3RMKnRq{8~oDt^}_wY;@VwY(j3ij?%UF=~8miV8O`RAG(f*TvwHXR?&^ zTa(oBp@qS14Au-j-5f7ke^T)W?qvCULxoFTP~oFP zlEDrJ>kM|yQtKz+Qp?MmrTRNkRsY~)YJT0DRM`Kp3cFbNw!>I`8GO81{{BKWeqe|i zzA0O!&sn7UyK+?6d5bz;Xt%0x$x&)}M>=b-nJQeu=8u+})%nE1VE2*g_*Sw*9pAhs zsO`;LsFt_CLiG>w_G_$b%<^m9qUI+!OHHqt`TO@#^XEua;ilWw@^T)b=BMpgHGJFa zYW=l*r;ZP+`X}YWTLpSpGgz z{aZg)VSS)Fo_dSb_UbrF#pfKM!YzEhdPwyTo~5Sm-m2Dj^E8#-);tw%8>hnhWEF17 zRpBNEJKU}GJ&9;&~-mkPV~RN(-l&%x+(vHZ0#*qxxJ=VbJ@ z_GkXA`~r!pziU4g*7sN8X67I4rTVw@QDN72YJE7qRAKKID(w17g~ky&%WW+PC(xx*pSptNk}HjKN+NcAu%j z0iOyx89(i)SN+>gQ0L3GzpLYIfWiJ-)bY9bJ$3%lzg7KPZcyR28Wn%w8`aS~&^203-+PP->kPj>LoE+iiVAzH)bcD@q{5D{@>cy@nZNfS)!)zj zbyi*u1~;+x>0s?M$oyL?)cpHzQsJhXRk-;^753h%j&I%(D*fJ(D(oE2;Gxt$9wLN(6Rl~bkd)8TdZz^N;$^4rSQ`@JTwST{+jxSD!3OE0%mY0jQFW2{~ zzxJ~V2Y+JlzH0ixLshtKyBglh;&7 zIxD~C{;Gc)D-Tz`>fbthj>2EIFu0Y;Z`)R>_3geyh4qV6ILQ11D^-7u!G0e9LKdFE zfeTcB|M@B$SgXRWOBu}YdoNS{OBg=K<*L7Sg$lP`slv_cRM@>ngx2#p+*2`76ZM_ONU!=nBxoZDvzFy6boA=KN zsys3{UWFfF@U0APW^faO0}Niz;I^SEy{*juBL@2qQOENDgG+dRGSvLHvHEtMr24n8 z`VV}swr4*pUq6#ixn`^Bx!C;fW%6(rg9FE?{8C_)3b*8|u=7S0E*Y)DZpII{q^SOZ zR26n7sc_pA6)rhJg&osWxMjKuyO*f2_pd4(7^%WdOI6r^feN=Zs<3yJ3b$UP!hsu9 z*w5gSCe^=bstRi}RM@{!g-h0{uzsxydjl#Qyi|q#St_jOs&GrT3O6OIu+HY2wlS)I z(=rtfo}t8ieF3Ts!Yus%YCo6;COQ-%E*DqNDM!d|xu`!7*p?N}8q zajI}|oC-Uat8nx4>UzVwr`q2&zY4c9`D|de%D=X<^^!YB9iLqd>iFeluzQ$FpU&j_ z&S%{UzofJMDd$v`AJ;~ya3EF1-3OvJ+|NKXa3EM zUKdN>%lw;eSI6T3lh-&$ss4_mRk-a?6>jRM&R2f6f9qv%ph6Aru2kVx2KyNtJW37U zGK#gQrD}O=Y&>Yu)bMR9)b^|oSKC{FwXeWD6~CXs8iSh{>|k))sVqGvp9?VgRm)E* zeO@N7Yh|#bRps}zL)7{Ue6RX9-K+YyexdrizEt5L+b?Whpq790ek$xfRD}a)tL5MH zHx+JaRN-dkuP;~qH3qkytNOPvxQ)RM7T?L*cN6n(W3c-?6<-PS4>DM1;hoIi*+)$; zuu|UNX6|qL|EJc6gXx0=xjg3@b^L3)L4}*wtFXRKh1>ip9AL1cQT5l)QDLW7h21qO z+_Xf6wK^4UUarDT=c=%_QiYq(Q{j@;D(pI6g@c!8n%RDUbE4|+VDj?dzG{DKWBuRzAe%oP zQsEXRKWt;+wLR4IOWsoXtswJvWHEk<=`U!^zlHg?F*x{7m0xOoUWMJvzwHIp-?>eN zwdYj0g~4712YGr7Zenl=gPRzB|4S-WrpQh~?wY`-5q>i`E z<5mA4Yfk|-|FyFHg%-A75*)71zd@$I=Vbe7ZFy>YYGv~JHr9VzSpRV_`FN1QI+KsL zUZ>LMV&$hZc|a4Bj|Z7N-8oF{&p{?%_aCkLJDI%P+pf~%{6mG?4p8~4wjHW}%MU8- z9j1nF+Fyl(2di+)DJtw{>ASdm`w%s}cC-q&j!@xdE{|sN@zx<~_$DT=_x?}KUkfWA z*8#)u%E%M9Cf^PvGt}SO{J&x1Qphc)c66mo^4@p6I1Gv@MH!%IefC(fAmZhZep-LQ}qurSPQ8BZ5b-8vGjt>zlFg~^=f>b z!7diQwXdpg-@^0{ytCBwni;HRss0WII~nZa@XIQ{5@=E3AS?e87GL{L)d%u2|0V_p z7#w793xk8%YW`Xn>>sK6>#wTxJC0ZPOPr%rxcMoyzmx=3xaC0=4nC~HI`eONRP_&R zQQ@{HRk)eq^KMoBoh*Fo1FFCNm(iO1!d@0$XZ{+49Sjbz_$>@>W3ZpWO*JY#+gSf_)~Wt_jtV;& z+{W6o#{B)cYWy|^mv~kGCN_RJ%T<3bFOT`Ezn}RBS^se}`brqAvGGl3{nO9Gv;277 zj2;Fzy`r|K0P}BVu;W@ay%y%*%3$XTHN2})g*lj2?}_4o08G;(M9Dm(lBF^I?$9UrmcudR+}F>{z10ZiZiD{mH@L64w6Q3~tL} z>9hV5tX2KJJ{4{{lfk_FS^WeU>}2h!gtZs#EH!<9g$lPUP~ldO3OgAbWbGlq;F5(b zKEvl?_*@^U^R;%IIv=`MtLI1j?7XJNU>Ad1^3?e5%_{%z$Wi^ht5yG&EY-htx(a(Q zQp2|~d@T+&d~2c#x9p?Bj(t_QjfL0yss1{P-`cLy)3Uc3-oK{`w+vF@5*EIV!Mdh~ z_s&-F1zJ_O=IJqd+n9e~s)}DfS%tl0 zRM^ehe{hEC-^^eqORr_D8s0lug35wL{o?`yy37(mH>UvLC`>|4?XyWN`f7pahyClo z{qEfK(N)X(W^Pzh|KXOS9(sSE^Tt2sHqJ=8?~I{K9{u#T!}e|MwV`*};W>|9SGJFT z*xF}$zj468gIZpi(RAQnr(b#g5ihP-cEuxi&q>d{_P)~^`!rrMYs9wemc07g>h#qI zTvIyrnO~=U_Qc`Yz5CYBSfBjx*$?*ed~UaWNp-~i$v(6F;r@18%@mINlRanq!~MzT zv;E=z+|CjAx7%u@%;4z^PSD!kt={Z)K{D4{EKfd=AX#mkrz0Y zO;~^8tcU%h7Zu+WobO=%{TX~s$@1hUv!6(L{DIs9-g{|u>Dq?|KX%sD6EZd&o_G2y z6F>c6>F38~5Bu;{&;bebL*>#&F9Me3}E<<_*?3Tr#9`C9XR!d6Ha~Ln@=5E-nq%?c{Q== zFQ~6aPyYIl1xd9>Uwc#XeFKjF;E)%3H4kF(2Qv7Xq{c_yZhtQ2p?md*#<$(u&wtVt zTjoB~l6b)})Zb3oI=yLG>+kbRaxVJ6cW)WG!1LfCkAC^D4aZ-QalYrrslOlhuIt3- zo=N#Jwowcc^=@Bd9Kx^&jH zAO3vmSsyfRIrH@O-#+)o>&cI0kJ)S5*ekZL{(9iP+fVc*T{nK}1AD$ae%!)dznx#W zp(N$<+qId8UGqWJNYe6eV$uaIQ2CP{+_kpBUt?H%>PFQf5_mK zuU&u5k98mBoKyH!pkmF5dphszmy$T>qr^)u?W^enH!K*=(jUg)p$z_rr9XoCAIacS zmfv$3yqv)$4E8hl90ni7@cqE(Yi02J4E}(@Zo_a}P>yQpCo@>r_7*;-zsBGU7JdeU z_hIlb1~(;tKjn&nFC_+E#{5{)|B-dae6jAu&s#Ht?cbEYaLK7nDQ8R%-sm}a{rbPR zKH_-w=I{HR(supzBOXlNwD+9{PTPLX)uSZcnn~Y7*Y>(;;?!3XH(o{kd;RS#&wtVQ z%VRGkUUV+fpLN@Sd%k{U)JbnWn6cr#-fzEuZT{vb2X9L}eBU>69)0=&=jMX%gEF^T zD81_vGJd=57|h>CBmPOgynnIuwlesaoLg@Hbj{rKRsY%XOrQVyUJNq-vtIwfIiviQ zL|Cu{eUq!5Q+z{)jCv{Yu8)y^>XMVl<{3Rf@mEXN77sZyW6>*#5A=rrqockHJl)r^ z-{O}OH+%mx-xc>h@Ytb_hc+Vq#KZPFiG_cK(f1Pbe|^>S`%HTN z%2~Jh(npTHu3_6@D;^ni>ew%5tnK^iMdMFN`1eYd{&@@@#nN+4Xgl)kg29e89*pnD zymCn1A^SG8w0@j&ng1|<#*~-q_UI#LXfywNGk8x1@55la!-bxp_^YM+vtFrOv$ZAh zwwJV$E7uK8+?)9?D|+2^{0DE(+FUuOZFS1vGyHGwUp3*DmlAI}0_8j4fhksUccay(z7mXNxbAm)Zc#&zGj1a?#9h0ypnj)OoE-y1W*6ufQ=`r zr>@}X?S1X6zYl6jyn0W}7rk$IWZICem5UyDCGoDa5dX=mbIxPo&tdS2IsT%rYF`hDcR$DJ#W88GRtmc%tTOZ@&*D)zkEM$i0DQs-W9 zyEXonG5EZPvNlu?eJyd#HK1o<>fI|C?DRKonUZmR_U%`lR{r&IS8C%JT(V!@YJ2+U zBK@&8{$x3WH$D6BqS-cln;GnPyk2m?I}8qU$-F&tvdqfA9ay-0Zdc zxIaAO{yPpohwuB%6XvGB(eDwgN{aNwIqzWGw(?axqqzUqcE&Ny(^ft;?%>Psdzsly1e_nfS?)KI%GakO<*Ri)9H}8S|+a4-LaO~V%ij(z6L z{C^|-ueSMkBFoQ$v{xSPx5rCaxBR7lVe*8{S6}nMQIFhtWNFf!7hHAVXTMHgb_5IG z%J9F>;D--rymf5zZ%8SK3C+i~+w#(Z`=>bLZX%bHmKGwmM+WjUpr>s=E*jFq3c z-ZlMSX7&5YkKe!5tF$cR+ToKoq%Z#V-2+*CvdKzMQ2f=>mleNo(~N`9&)#_Ir7QaV zeDYzs{2ub(XI9CX%~zJsSh3{T{XV~7|04%iZu{!(t-S=Hz=aZwUXpRhpVN5p?CUL+KfZC|+(R7?R)T*Uv*oNqS@_#u zTXcNdfzJ~wU=k^=O{0A_&_2WY~-+l8-iJOmiCu>_Z?RnPTOLE^j{-4R#czDj7 zACDX`vL*4>+rU2!)cX|Ob?}FQ{`;iec~k8jXZHTjK?{HVcFFqO1u2i!6`gp}sy)u^ z&+zqQuz%9!T9;O96#SW?cg8x)d$SF{XcDa&u-2*<{ak# z!jxm*UU@9|`93J0N7rw7iNP;2I51#+;q8-9-)GADE*kpZ|K8O)Hgo;k|5y6Vi8tgQ z`O$r=2j?D`vgz9!XZ~^PwEMsRDPv*bxRtpN{WyHuH+PInX&f`XX0M#5GtTY%){`IK zGxMs#L6hr_x%h^Z75g1i^TYlVKYxSeFEHodw;h!Ja^mH`0UyoJqec|k%kx}To)>I7 z=$FR^FHOBZZScFjzg#!&u6g@RK7H`_$^O&Imc6$2wZrGU(O7%Mw9K^YUOBtr)sd_A z|N84!i{`uccHO(zX?HjNQFQZfea`&pmr=i`-#_N4sr&c&;gy!H*Z$?|r-siuXIa7_ z6|bf4z5Ozu`=n7NGavlNf1WEk@X7z%eCZ{7U4QgGscUo6ufH@eP5XEi9g))H{bSTW3qM`AU0ZkCc_$U6t$S?W}leO28ZTXGk?@xiv5gEO9eAYq}!goG~tx{ez@s^ zoVpi2dFq(dRX5f)zwMuN!+(k||MiKv;mZ@-jy&4|PAz}Xu`df>vPkXUE#q?M9$e8`HxoNY%<%6#D5>2D34 zFeP_5i%(Yp(i0Sav7WmmP+T;8P1-#T=|4}u`ObNXhZhY^`}nQw8;*bE>g}@}?_K@g zqx~Oz`idE=*7xyx&lr2yr7vE5T2lI_Gai2G;oOXypSrZ-?IoLUO?xN#Vy*h+19lvL z*2)1VUVX;!yJp_^m)}2jI}#qodVHXLJwA=mv(OttCHf~K|0Vr?P1yUG`cL*B z?6@=sF!-&l7oU3X`_Hu`uJi-m{LeElWc5q;iP94kf3@@h@*RTdE>U`d;;)uoa?*hJ zF0rkbkCfj-{;xCo=-Nbjg5s~1K0&@i@OTD~WAHEr_kHe~D;CdtCGp~wXg__Li|+nu zz^0|P`M|;W+1?CBvlCBHzS0wz|Go_F#o$B+kCEww@?(G@csTPP#L8y`gV!?o(=jam z!%t8AZpXb1IghNYf3#o96aRb*^OK!_o&D>|?|bt`Q;&gzg`mVAMlDB6zT3py0ww+(aXl)a@;>qg}X_UaQgs#Uu^TI z8%x#i9)wRr7>~GxkM4r3z}*GmPxs;{Z1uQ1p%AoqKvVd=lDm`tNF_HL7(KYhVb@A0 z_Vm?)9=aE?+Nc?yaU=L*e5V?&+eu1eS$|Z1U7@cWl*)SIp?AKNyPy6%lyWulNquAY zbI~*O(+E+DabWjz(Ear1qyN{69vP{t3nDaVe!6hYrYlv6p%jOrhkcws~; z$M<^t-r12+(ivO&s1~U<^YO07KN`zvUfuO_j3s@wXl2!)j%qeb(6(!B&R)aaOP}O+ za#8EDoK616PLcXMw)D}=Oyepp+w5Y`h!=k94ORHpRXWsCv7mU-mks*7yG>mz$7l1# zX<2{SXhGJk!@FLJ@hU&J=%>Wd?>cQ%%kiU6-WR{CbL9t)TD>M<3%5> zJBXjJ#ZBnD)05*x-|ntE%yNu9eKe;wpv=s%|IgAth%=>Cn&i5>$~VQXeC+sX^r!?U zBKeQqDWO=>S1DRLt*@wzNJ6o@qem>qHMgw^;?V4jCdv*>#V-J>$Fi% ziCz24Lc1fW3ElnM^*N;H@XPiTOZ>HB{>jH*x(k_h7P?*z>ZoNw@ukn4KX;wZ*wJTi z)5Igyqczo`3`ySg=b(>jmE_7h-^#7}5(T+iYs>^si~C!trBqm9rSvQ(|^FerZcOBXGa zdb$ristUC1ikvuh^hrwU(Q9aKC5bvoiFdcR$BsVgEv2BYr{>q4#c#GvDQT}j9ajp8 z6qPQm)vaBuutsP55XH(fC9A{X|38dby1t_A{3B$z4ky_$NCL!4NVqmiVbg z>QE*PkX%z4(HQ;bDIeM|q&=^2iZU^tEx>3J>4{zW6aWL2Nj>BVG*46lC$;6>lf=c2 zK2vAJ9M`FwXeJ|Wr5-B=+SS~7EsEIDM-pGsG|7jfS&POoxt38WQ)@An_(>asByY50 zvUUQ)+f(POc8kW?(N~0)L_1pcQHgY${yg+~Af<{;tBOzgN%|Vlwy0%Mt5^GHvgiYg zM627qRrBuAPkJ3Ro7RQo16AjG5BN5H;o@}sV| zKNUYg*3L<^7O9dM|MKynH&eT$UK0Mq7k>f9kV=dU#LL!2d? z-qrkb%}t-sEGEjreK>C=N7Lw9pz+qa5l*|8RH*IHpu)eq6%nHFzXau7@U=?p=nR%5m1@L%15 zpSL+X72Sbfj*J$iBW#Sekk$-hZ`K4(~1>fxzYfp6z)*bjs zzDJTPlF4%(yF2i!?O5(xn9{b$wPJnke)>A*w=Bx!ub!qaa<8+f>}mS!W2r@z^{YGR zBh5CF%hTvk2@ZrtRdY4oJ@`pNE6*Gd6*M|^wUzxj=!@RUx`RF`w;*kXI+PvFjMgaD zQ~1pi=_&kXzv>SB)K*Cw!YcLd?Y|a&v($SEzgg-%g+B$7c^bWlBa~0~*1sLUtc#w* zPoqL9RxBjBi~jT+eI#2e#aJcxOQKQuXQ3~=XZ3XZA`P3)r1#ykKDEXld;5>C{5+EU zDw_PnqA%LcdPj2JXe~1y^-r4l@?3BvIgn2yi4<{2azB75*!lhu=^V0Zzk*gmjbaCp zb{%MDQ_II*B0Yhh&R)-PoSMc+?>u&sfFQOyeo_LfGZ#5m)PVDQaWBlQIbFr=; zK5p;q*v$J-?C6U$E=nzqa*Vjpo565ryke%Ki-XHv_dv8rt5-#NlhtmY+o*Ul*7J_bh#X7XB() z|4`|R)LY_Res=vpv(D`A_~JKDA=3O$W0zVUL`N*~R|!p3k~`4(jDX2lWdg96A=y2XQ%ZRowy+>Y^1eb&(TNc0jyIJk!Xu;`H>clJd+X4zFZ_4Vpl#p zi$8oVY;V`*?^x1Ddl&W4YLPsG)NARQ#L}cD{2g!lXk@bMOz$kcv80crqQv8pY>-9* zxhJ=?6sctxd-}}Lp$;WSy7#gVMr!*+NzdSqHXEyD6I=SIznS)(q})Y4mto&qh*nyE zPWr-UC5z73)vvw$q%67t?MwCs(hZ;)Xy^OFpOL<9srLUuzU)EqO=_6~W z#6kJsI@|Y+ef!A*cG`0`Wrw__m>AV}?DF3+{%B)D?C=xMMZ5s*KhUWJDQWMl6uK9G zcqzmZKkd7a4N^H~(5jGR-QC3>k*&*m*nXf@-y)$YLvt^+NBWY1zhnW3&R3FEmguMW zJFBsHwcn2E-+9hK(iyw@jRk%2Y=3U>T_gb@`#YUUC9OJ)UHL@AAD(9mdo0%{ZnSBV zGX9e35>edAdcFbtPf;k{o`ikeqgbg-5vO&<(=q>9sUCJ7}|U7dfvMOe@A(bHU6&J4+2dWlQC}d-P`tURd648&+e8_wvbfrY^$)S+FktNGl@D&QyZxlYZMEo{a5$lCr!L^P$H$yCJjA> zzpETd_tAH<&|aj~WcVpkv$VqB-A5nw^YHWP@y1WPHkJ*kaN9fGi{G3DXs-5&%IHb_ zwDTNq{FGzj_f2~Zyanzqe#!ZGLwp8Fb_pNJ2B_X8c8=A8y9a;tJ^t>&AKvcF5{MQ4 z@OeaHh+q1$Om`)HyB;a60?4ia*}$b%S|QquwDE3fo2sLTS$6d93HVlOr8cYN@ZO>^4kwzM%UjOwrM!f&rrI|bc^pVsLZBai;j5XC&?LU`bM*2)xG$`+d#bWcV>ku{`fnVk;Ml; zafl@KC21jzJ*v)Z626yV6p}Y1S#2@WuXxZW<>zum6_4~SP5k(b?_>pwM)qspt6QFB5H(?kgi(Rh@Bw@yH+HCtiyrEBrj8Rrazs^c?=q>z*i#2YoY9 zH}kQojDD+}ESq@Y-`zVkEb8J@K6YL`9_4SQPqSq_)2DT2JkzIqRKv+Rs0jUC{wBWE z)P1(w3bfao`8%HUnRfam_f8`M@k%6jBTa1ibO-+E(wX?ykC}fJzsjS|BlMv zvOFbgA^z=OE&oaO%E#|`;g|9sxjH8svix2}lZ<%a&p~@9O+b3$kv`p*K&wBxFEPI9 zrwFYr^9)s_m2Q0T+d0K_tY@XB4%vC7nzeMZqHATuhd%S9PrS;X_Ftn(bVRcX{fSTh zEc|@D3?Vjt#2Y^!FS{GRI(l*J@u~lv(Ugcs`A5Sa&OOCD{{`sfOTj;oe2Zl6WjM#9 zKJmzZXEI$o1@XY2k2OjKMtJK6c3QFI!bv+`J&oT!Cd4QImQF@|)3@iuUaHpb_~P$u zbc;{_qA^YCyhPI_@47y2Jj$mCy`64WmC^*OE+YMkKmLx}NNn(%yiMeN#*X&+VuODc zMw?n_Ki3#1mrP9yYvmqo9*hlsw~)#ZPg~9?$ix?)X3a=6Hrp+3#2df5mI`ly-HSiG z7Gi;)+gKruBef+`{g@o7s&(8m_^m$KJ@~2BnYRsh?OqwPrR*Agb-*X}zG$su%8MiE zI>#sd-7Q~}eriSZJMxVsR7Sf;f5+)lF5;O!&ED}$pKf2EIk2NAp7;wfA4pA$a;&`N z8k_F;qdGO8_~Q2gE7fuIo$PqxpN-O|(@Pya-GSfgjp3AZ2mX$@)b7B~Wrp@r=nnkH z*%7ke-GQG@7T1d&NSbX{-y>3DgFh3q8%Zqd1lPS7zoL)WY5{aF{_vjAz4*g>!tUWu zM~O>Wv1vDok2KVOWhBvFZW@FMkt9r2LzHD*o_M!=j-(@Q05Y-HTtY@67wH<;{vFSJ@r;kBnc|O3&e!wbFC= z&GFD`3z2^HJbfMYp6(exBDWv2{5tAg-9w*ANl(?Ei9b?Jbw~R#@kgqO?!?b^8>l|w zg8e{_6y-0{o5ia&bk$E*HT{L!@!;)S2{KGCJr@u~lg z@!Q9tp1|K3&ued^Jx`y#wCt40-#t%Xq*2|XGq&_)V69jUNr%*#tj7AG9+s0y(@Ao# z;WZmu{Nb9*Bz>#~_MN}kGamJ~YxH&0!eU!~`9fY?hZ^f@xy1`V-_x>Mtop0F@JG^} zAxgRne|XE0<z?{45b}`1K>mg-vdtp@MCx;@OGWaK=aA=+=k{E~y60Z$*0-uyEEbDJGM~ZcoIrB2FJ)~n zpOFl;*OxyZ9YQ|ITT!T&KURdu*lMK3ecgQH5LSk@z`n^us5jd~PP>H(7m3;Vx#D<_Z*e6 zH$D~ZI-kUXm)Bn5U^M=k9(v*Qu>!+WXe;YMN z(YIXrDEd~jGm1X*m6{P?96mRAy`5&YWQX#%xAg44v3=;BJ0U)MWQc%>pI=FYudh+^ za|YEr`Txb#=crGjR?bjAb-#}OE0({6Z~f9ZI9h(|x8w2a&cGTczvC}OAV=WqYJ}CN zo96ZX2>hipsE)xe&*aD9ljYSICX5WRg?;-oO7ow%|396gQE~=(zhhP~O8yi-^*cx7 zr+#NNe*SC`L-qGj`p@IfTcI!h(n;MebNDn0e>p4b92|o`*Sm3W41US_`^H}{rwB{q zt0xj={VYCc?bTEM9DZ5z%2{80?$eEHI!Dnrxkk}9iy1|K#QaKEXH@^oStqy3QSvRt ze2(6;|M?!!nsqbdp`ZLE{N)VF2z+u#%cmlk^gZ=YixX|Vn<6gFu8*a^tXY+@pMK}^ zX)H_Dlexa0WT)S85)G>hW947N$4B;)pNK+tYfggQ{V{_6{!<5>!*>3-O@UptUr38` zAG@C5T^i4~(=SnU-g(+WpL$15N8pT*zet;rlP|@CW9ZxHyp4a|$ILncm6MEQ%-y-) zLU($$?6BSZkEOy4589QAGX8Pm5&ZWMjXl#ilMrj&JY?%#Yh1KHocG5xf)d(%%_ zyElEkJ0*-T(Ohg1X$&w^YVbvG{=l}AD3-a@in}lu7qIo|u{VFIuk1lz??cjxj_~Yq zgcwI(CD9vUUlnVmM&lEA=FUyE2HcO&2|MLiANo+?^fGRJ#TQZE$9s?VBhF$B*IS8o zOfBcbQ%U#BS7#?Fu6^!>U$T>a^of+_ufFut(W8fbm`8&D_?F}vE7>m}d(g4UZ8q8i z|J_}GYwa7f_I`XQ$P7=Tj>3E^bTy9@tA6?+?Ww^IGR7KzufkOB7UyN?@UTQu31KOeVhebxE!YgU(f>nHCk zSz%&-ajv4ZuYPj)`F?M`?0EdTe!rc+AEf7y)wi>vbmya;F{$@$FaI0E=Dl4%%d~6o z!&&k<@WUMJIq<`b{5kNcM69g@J3oKRvCw_vFSPA*^)EDLE8*wRkK?D>2tAKJpO?ST z6U=!#fBUV^o=4~}J$r&I#u7xVXt|U2X#Vp17E-PG=cD+GW7>1$FUPFTU61)!UH|gT z2ENAD8`iSh$MJ{9&z%Brl>LBzDY=PupP$4IG@o=k-60cxW|ZK}cdZ!(sa?L19+7SMIi_EeVe5%WY4i@z-YXeevT_yk->bi_a)PCi{2s zGpy0u+P!&O)4IR+#rJb*sVOg`j>7*@WWSMB8GrSa&**ROUzYWL_~0MJgHc(D54Yz> z)A;>7IL#vEzxMYvwuhG5==)4IreE%5ZS=pBw)+=pLu^N1+kYQ(ct>vbww*q|q$)ty zOPR?mSUn@#Pc*Et25S|6Z`1D<{IYL_i}Co& ztx<=sHP|-q)m0(-8&;;R5sxRW`YrqNI{xhUIbZ6$Tn#l0N=gqQ@_!$6rrT zMM!-iA|Ubm-#FGUUvt3h9)Pqf7e1^5g!R>x6%Wto?>5jSk3En?Wvvq=btJ| z7>% z^vgbYKmC&D+iE{)`(B72AP1a(ZR4MFV(nHAv!lGnXs7>piq4H{o@@Vh3w`&GjK_L= zqvgz z;(Ia_59Ra+PFKNF-^zdFGakxp{OT@BCXOIdw%*8Geg2DYB<3jp#@izIG?(va{yr1` zNEAX1knT|-3t_MO%HML-Xx!)GzoYeQ(NR7cJHLMO{QcY0uZ{Ej?q?yJd8~isv>*{~CX3yBoh-^p`skY)j-j_sp!1b8Z}!Q0R7jpY}QVk1e;I_pSC((*IX?5&ArT zthKMqYBYQKtJpE0JSVY@`)%Xn(fpUQQ)BoilE3*BCF*>Zn2}t>&D|*xtU;~iUPswS zJAW2&U^8(|Y0v&=_Pfkqo2B;T?|bPrtkIBt)|Jw@727yd4?K!LGA7(K#7#z5S#E9L z4!2slAFy%3-beBGop5&Bfx|8Q`HC&}{7Cq?oyHwoZ_yr$ha`W-$Yz$gcz+MXZv9| z%QCIv@*GmwhwmeQdRm26f#|wfoU^#^{KpYm$nE_3T>8&N8guTB_D^oVIsRJg!eqHm z`pwzJx%jIa-H&d6t)D;L&44_s#SNgA=dza7_ha=}!(Tj7#oW$6-FNhwU`I5B=BlAM>|VDR4ghd5$fwIsNwh{F$ZYxjddfGMK&x zl}sBkJZo$0+2?-OaNYEN^S7*9G=4n)-mh)UV5c9my*E?cMNQR>+sd*0$5CgxvhG~@ z(|zKvTmx<`(O%JapXJlq{pDHLed3={CH30(i9fTFunOax{4Hn3wGZA${z9*OJb&Ea zsWC1ZIwyY4p4@YutNmO*#$UTvbSaM3FSYQtLij@bNjw*FzU=8({``EB+7bU){(h1u zPvgBf!Z&Tr-|q*1E0D&>CHCd+LR+dxUl0i=LjLXVe-_>3uZ5-k#0* zT&$qz8M(23N}TEUqxoCoWjsC+pYEjCqNSevg?-3cWfXnu6{F~zj~+$eeDo;#Yj!!h zePVoTEkpJ9Uh+Q^-|$K@h@1ui_Km~~}$Rb$u|{BR!# zy92_{VIPdMm9F#f={Wqn4IGDWJvx+r+xQ*oyI%isk1#HdlRw6{);JD7Ut!i8KeqWW zQZz*Z1S_kJtYXG7lmvPfot{8YzE>pO?Ou{l}IbuN{@w zX3$9=`RDjGYcHeli9y#-)>Mn=B|j@Mj9xcN_S2vJ=|2*y=5(OCENOrIIGfRjJ}qWv zbuQcMC&k`9^ug!+@psW^m8*qGvH9EwKR!t(#2G<9^hG1+d;B&=KP}PhcKMijU5Zt{ zmH1OnyRzLi;k`v8>C;YY^f`-wN_Z;beZL3u!_Ou5(iKbArmv=qB~t+&JDg1`@=rwvDgUu z&+c%zWl^hX%BR$gz=tMz|ED53QZMZw7>!S@o%ySr7LLS!Ci=jWlBv27zBo1dB;2u6 zwf=l^ufw2zpzQzBzsa9fu~&ZgywDFv);|3|ra$*Peff{+?;C$|`iEP3#{SnoHSbFW%pV80xPB8b=U-lvW=;tNqK|l0CX*=|$pZ37L^f}X+ zy1xAAyT5&j&{RLEX7ux3{+<3`#QVOP`d{b?N70WxNnSR-?T2rOZM%8;;kV36Tp!!< zi7vvP73TZv_b_e8H+}D^PT$l1+_lQu*vrK;h}Y!%dg|RoNSy4+yy?$E_3eWX^5--8 z)^4$h|DCS4Q02kgi`e`|EcyAgZt=5x$6ouobLiUnYval-E&ntc|4Y#g8J!oR9WrF; zs~!JGX_XhEVV~`WE1{$5o7G$8^&0SQ6z;hJh&d6}g+vf9L?)f9 zXoaCm(MBI1Pk+P*u2EKut@M|4?%c2U?^r+1e@H*oc@O%Yqgq~LY}1d=`0xm!3?a|q zb1(X7++!HM=$G1{jsC@CpO+F-^|DVi{z2^hX7b&ftZjGnaJ%8U{Vn~T9Pm4#e7ks7@rUrs*hq9h%%|fTwJ@5E_>)+s-e~!o?B!sF`5}ai zo{z%cYQHWOHh`qt(j zpO0rI@5HE^X2fGANAPzc$R~+~RBO4@Uz~^Y;FCe+9^|+$I9L93pZFurq-FKSMk2)5 z&S>H3zVYuix*V67IBWcWFIph?&RkJzh3&Ia*#7&lmzVp{8huuN8KD?ul|!p#)L9j` z4bWHddbw9m`nfTvC;dNV1n5cM_H=|WJ?V$>tW`Gmq>r~z>+~A6arCvd$I-7FqkG~% zn{t&@p}dhO2>-oaL)jOfG1YP@YK7zI_iw-0qiJv5#y>hB^U59Tp@$25<{tf&=+Apl zU;bnIp@s7|xw+C&_@#_zU;NlYXu-bp+jGcU@VWUwS6|EHs#$6e`nhqnC;iwejk3P? z;6J7xOVgiz*sDrb?K1YjpIh}F`s859i!aA*hS1LcoPOLQMp@r`(2v`HH2qkb{``-& zuX+27wy&7}Ui~pEXVphfJBeF+{;9ovV)`++{psiC93jeH{&RDJp7fXc9yojXkLk}_ zqc8oozSmzqc8B{6Yq|19TXC=aao<#$;h%l!_h`SbBxWBue$DC6xpob;>t{}X$p`eH zzvKgY(2x75>xQTP^yAj(PruCv^uS;0gZ=66)gLRu)H}0QwH`&b^IxJL^KDkvkAA)v z_M@Ngh5hK~d*LYh)*7Se*Y?6u`2W3(!yi^^U$^ zZ>Rr_c&=BHiM?IP{HcfOMc?#oe#_o_(a(FAE#q%qKY8ymioR>BmwsaYYrRW9`QqMT ztv`zX9{v4AJRc`zv8p#>d@s>=o?Saz^i!g59x0^WlYYJjw%c!s|JZ^}ic$2fHAc~| z?ScL9^F44B{q6euPG+}uN3z$@mR70S`Cq4Ryklb{=!ZRV1pRzZv>p?`kHF9O)EL)3 zjmHmL(@_0=JbrCYcb>wh@%$}E`Xli3o+y;spU2}LZy&Mzp*L{3?PN0IuwFsan|`Y;_QsEGWlMadXI_@{7t>$2#oqG8w$fj| zn0{=FvE^^|A7P|iwid%`*Iym|+Df5)`2Q%o$(SQheaqfqc9X=fee}NxIPxkxO{{L^UsH47b$zc!Z{jh}C!b-!dSHJZQJpBSpYuj5~fO|yfH z9dGRU)GBxT^hmzBnj*S<#qM7E`1@<=WmE&NSChG1_OuoMnV`mU8^!p&AALO+k6i<| zvWxplPKF_lcrTSaORppFm!jAs@Uekc;!{tPZ}prHdN~4rsSowUXO}e@WtH%9+P!p| zs*>4Z@={jYI1luFWDe)R4}JbQ@WUDLIq;YIL)183?Ni4TJ*`1+`i*xjrpWrapMDh0 zPQNy^QS>cV>q(zEI5*tA6>q}sy6frmEhN&@7?`D}ucPt9z6CEwUFSp`R_@zE@6n;3T58I(1{!?l1H`AHc)aKhs zy}jvcj86`azOa6h%Q$>E`Bxcn^o;6Ir{Qx?eDalcUaOwf>gQmDnBnty{E}rW7vu4l z`}xuMsW$rIV{h!u!?*ft4E<%DI(pCfQSFLlh<+4)+N#b&Km9MsU-I5{^6QEcD=w!g z$Nf&$QFR8V^LCeJ{!}AhNdL2G6d*_Qu?nS~K3SDJzuph`(2q3-7P*}GB=bG=*SX)PpO}8WkGAq3-d^?nG@p$1F&RbhM-Tc->m5Dl zm!scy{pa*^TByTop&C2bQ$A2Pm^+_UL zP9}IH|C@|+`z-yQ8?ISf;jI7gF1I@Q^|tq1He~DXmtqpvPQ85G_QXo5>PB;yY6r_m zwfxfysAFT^!Oh`6-{povUUScT=`V9%ub&eCcy4W1*0*d{;*!+zpZ2pK#nN6+*(;}& zd)iOG?EAp0r4JQ7Dg9N{M{0ln!}RON(!-cHlA&Ja%XHC3pBV#Zs_N;9^y#%z!urrJ zTVWsiP+^7Sk$5N0V#abxs(iDZ_gy z-)PS3@uXS$clfH6Z=HU7+rh_p{Bqmo@V}B)xR%ynl;b>azge`e)Z7{+-^AFL8YwBYz!!YJL6M|NE)mzN?noTA^P5#Hie@s%r?0e&~6A znBgYpMKQ$Fe>BAiI;5FbrUyg@To;VOZ3UK z`OQjRW3+`nXRBV_@wol>Y6;tazuYdS!d~=KyWK+HPVXe+X(M$DfA}Eo6DM}~NuoWX zgtZ$|_S0Y1b8q^oo?GdEkeYTPtlD1Imww89%lPv|_PcPV+!FuuwrJu12Z=Yo6%5wT zUdg*fl1u(*6#cm*)}!M0WANwgW?ani$paCYGZy_d&>~SfHFxi(zhN9V{eC0Q^jY@e zQdeGgv#4^=hR=MD?3CvBZiK|X-_PSI(~G_Lq@Qbree~H!sCCD`${dM$H*P7awLN4U zkDrs;w0i`8xprZT{CeO0Z_^IW8qK%rmwV=KrZ%O5?fCX>$M4y`WNB^p);oy+m?4mX zWQ~uQa{g-5?;8ENKj=$;-ZR_i|AY8HqEq&?5oJ9U9ibQ9e=yfhYyT?K*V)J;!NLQ7 zl#u~nGnXgjp-sMYBx&V8{r&tV$Y(N2y^xWMk&3#6ef-VsrLX*>^&8XA_2f4Fd@I@| zHf2ZFYq5@xqGR&3*PA`rk@)-NzYsr#{QrE{E5DQeGLKn88=1?8?#%bGM)`%%WJDnQ z`A^AbZp!^{0K7eqihkU43~m0t1)r95i7l7Gx`fBvhBS)4^@UONEh-yD-%hm~MgO?= zk5^80PfIO&ZhTAqOPJr*ng~uN34KubFU;=jeODza!Yw>&OlUu;wT#5(QeU15kYWhmw_u}K_eT_1uUeo@|`itq$?QSpstg4RW zKc+vLf3(3mHCFtyJbjRU#Mm8LWZXu3_4nn}SBW|DuYUB~WrL%=_&M(vN;-o6kJ5@S zrR{p~Pem;AwUgL`))s`^@7K?T#6(n+Ts_EF)a=zyj{f?r$7S4t&rZHSL?$XQhT2PTj4Ylsv;TXZ>RD0<@8ziUoe}% znuw*X9#At4ti#8@TB~F1k57fM?t9dFw3wg3G^WR+@hxsPK3eeImus99))9KU`M&~V z4}HdV+W(iShL^gB=d%8fzw+^99DUW)IQm+_p>rl{jrsc?e2w_f7h}BEyyvwz$F*K#^q1CMkB~2i-_t*@$*(o%aRmGE?$k$4ilIhgWc${fFnSDr8kJbCf z+9$uZ;;++u&w5qPDq6j=^LY$^saHKGe%wQklRxj3_uw;+WWMrtP<*vaKOKp^O~a=a z`KbT6lE{MjEcv;s*<8S935GF>zFEmW`p$1@7ST$d`WV(H;xhuMPNdeAb4hJ~8uOT& zsaDByou;$!{V06XXNb-7QTWfKuW;)gK0EZ==fp=R$Kg{iOKi(psh^N{PW*oI)4Q%G zdw-tz42ulxG*WW-c$WNW^Qm?AYM-wp8ndc5`X!abze+1;jldk$zv+WMBA5>Z)D|LD_UZYywy(n=!bJY--~wWnenSX z{kSb+wE3se_@;N-CwGoVe|$r%^9a50@x9ayTi)L^J%WCVgro3ntSLwSs)5n?9>aPL z!F132arm}-VR?PQXLs}bh}B2WB5bN*pG`3?(f*}K zdiy}{EeO4`^KvA9E(dTVzSRV}^xMXVSpQ#$j#;C#-AZKT{Z5$j%u2b~FTb8x_cFPQ zW)0VLupd93PndVLc)kaH^%i>K(sPN}@Fm#!jR?_${;0VjI^NG8;~^Dn+@1H`RErZ@ zo3&%EX_%dur2{VvDKefSUaJ+T+;Pe1l@{pnlfvszq#`hORhau52% z8u*Lcs~>&ycri+E`my!2`WHs7e4doO&AC?_|I74Ct07B0uqVDpzVQe?1|MH-F~Lbr ze0m~rnOb6KDedxkMIHCU$JJEx7VJeou66KQ(0o+se2m9WdxT^2)C(UvZI#!`$3A@T zF|kzssg1s!jlg;#d3a)|-$gQ32=gu3lRh?dE&s6=P`d)t6F-hrx3tf){$l#e|CYOW zSdC*`TGGWh`E%aL?aH2d;$KWwM-G4+ihT{zuyXHh_}_?yeR#kw-B&?PL>NJ91nWp+ z=(|rEL*HY(?eyKZ#G|3>hNm9%@iX-m)qC(gd%h%7h|nfqiN3dYNSo(A^u4{u(2ryK z5Tg(OaZKNz{@;frqvt;Sld-gMl0E;I(|Rp8L{bMG$42H?IYE3q!`O#Ec71SG_VQQ~ zDdz4&FZ{PtuCYeqn2SF6j3&fqdW&v+uFz6+->ZMN;K#n=c==;ray)+QYmUc{ebMpw zv9Icb&%L_%o0m!TcQ5-c_n|)gr}Vv#^rAnXd8;4lNB^zN_lY#)dno$Q_sj(={b41^ z2>R?T*3qPw{lxq`eUGOYVL7{;+`i{cTJgi23n#?T9&z1uDe5iF!P@lOO1)LSkUmvx zv{QT@Kpgj$r1CMiO+If&q8u!de4@rb@WL5=@#@4H{nIpR+sO)W@82k0*3!ZoC!BYl zdeeU_{8K}HBWo>}Q%s}hrIj?f2S1D|W2yX8FZ%3xrb1j-&BoH#6-is6bFAD`FZmcj zh<~w^mMFL%etv}6LqFW>meU>IEz|e?)?QT<_T1F#^6%qUfBHVQkKsSv0UyhgerlJG zS{B`Hv5kNKy{_iIku3h!+1r-(cYIFJVm}G3UdqVT>PKg~jNEvb&xNwCx7GhXJ?BPS zs{Qx>IAPm88tuQg6a4hti?!2EYw6ob6Rw#y`QqPuAF9RIUh#4|wT(8a^^<$(>zSJ2 z`Ali=tGC}A|8x5IGvW}-1`s1Hzxv8IUyrM$|Me6-{UYtdEn7rYjMv}GlkQlFb4)H% zFZ$m}uelXpz@Oo(mcE_xL^jO&K6L7TZ*4~0P6p>?kiieftZ-B$zOUKE5=s<5*Yam8 z3&gm;h>pG#Darp~VQ>-8`W&MNeWcg=viTl~TKYcI(i@DgglES3?Z4NRl(l_S{pq{! zL(A>-x7nxbPk+BAw^=|tf1!PEkuUsxtSjRweBZ}koJ$Pp+Vej8ajwv4hVT36Kbqnn z<_^9NUNh@-4vxVu$F%$KAB)^N+jWWJr+xG-!qxXMGk}(_Mf=RzmS$}G@Xd49R4T@D z+owMGVa1P8*7u(DbG^MM{akO~Lffhs&78Ca#^KlXv7_)yHqaCQgJ_;Tah#v*W87()zn6N$@%SZ8SdWa~ zkLPcxx5T{hshvO1Pq+R4Bwi$(`-Z2R&iS%$>iJuu|BYDINo;EVYNhXX8Ok!JYv1&t zpO1~e=tDmrJGRh&CjD0TRX&>Xqudch{_WIwf3eRKIA6in$Li>B&+oR)~3f>(l#f*cGvJKynmbiL;A>a5^w%`s>jw(dUonsp1zNK`^UFs`C|H^pV`Czt&E}g z^QBi0`XRq5)*kxYv}du(dS+nyBmRXP=Aq6x)QuL zqQ_d;#@~%t1#8gEMNTp%TUF-v`k+|9OZ0Q2P%KmUsa?J}9@z7HTit-;)^W{b*n_{f zeuvimT{zd>pK&})B_{C{8JQX6ZFp zJU0yLS{L8(E$4jMsXgo-r5X#J`)ez{&s4zD_G5h1`e65OWTWWgrPopT*4`-}z400E zM(S7TyEOaxXTKRWdQ_NTMQtrO0$*2dnT?+&i`KQMHomN#kK`}x2V?QQzZp*HeZTx) zPJZPyc^W)Oecy(szW8$u_n_~43(q5;US&tw(+x{{Jxfd9{u}T|9S9zk8CTxon2dNVLj;oMf~TLL`T?e`sz*pTfrh` zrpo*>h<-|Wrr!7`sfs2OU}x#4@}{3h$>p@->j?yl&x!=mDUs=G$=hGc zJLm1G1i3Y>H9y^kpY|!D>*mK(U?7DeE_F^gVtn`^P>0 zqn~M$-b03B=Hc;Bw77St-{gT^!v}! zet5MqJ*T{-{qpqZy~a_t@n0MLEyu@?Ctrm>w)1Ur_jLL!Fg+jGO zNAo{#jjjBDH&u$=Og`}ATrHoz=|jJqCF?_<6OTVikGuKAw>|WxpGvY!|7VFn^sJH7 zgNG7Lxj)cZf~`k{l~rvS&aL<%qUkF4-h)1|M(I?NQS{Sx%E`ueJ@C^OoA=TZ`gVL~ z0=9!LY|E6FGP3^7R{3l3=N>WUs12X^K`XGlCxz0-wE47^zDKe>=@S>S>)%GDmq9LU zUa|CYs_<)lwV(%k-E0SlA}v^Jx4v zKerV>wE88vN6}xC%XGXIU*{TBa9IU)t;B|`?@Rb9!%OLBtXKMuEg}JQ$~@H0A+vuQ zQ(yL9_M04i`@0Y)*GIPUU!tFmeS7KqoG=&N?blCCKjnUzei+Y{c3UpVAO7AwWNZQL zzt@(zl`+Q70E{WdpVsL^iP4_=Eb4bX^X2Qf{QY_^GDg-<%lMwb{X%AOC*gsd&Br8H zv{b>nOh26O=JRc}zh~u?{;U<^KG)p-`?@-ZUi3?GS}px;_Urmb+MCAnd7lI)4(+gwZD%eFU^SId)96RuBCq=l&(c)vO?^di!+dMPB-j_J?ZCc zs3(0qTkAfPHGDnA@KVO(G5)2VeolMq_E}HgYx?Tj|LL8-eIc6X^z5gfW-eCqzIO~* zZl4sN^FZ;k;eN2~W6yg3=O*d*5+VL9dUz>2?Mr*ow)3zo|11Y`1D~uPH@jV|9w|JRen|v+wz0ZXhwfu*(+nTt@Fly;< zi~n4H|9!vti$|Ba_KNfI`1VWjH&;{qM0FJBf?5v?EygsX?@RjWji0lCBk^;+`h57R zjU(~FVn-`go>tZKgN)C3eLJ5%wvOfaZQVX>Tqo`&s=t|HkQO`Lr=PDM{LO>EfAF_= zy@53x;-DweOKN?{K7615pQnGe;rH(!d+>Yo54X^~{>>s%tM||Q+P@Y*=NWtW=UV(+ z%byQF)W$LTkL3?%nq%=tkI&`y=j@3WG8(L9nnuaLjPDk39(=ceUidomC+iTu_R`0K zUdbq@@t*m!`Vnp)zQ@0L|2o>f+wk40ybX?&->vFA_`WOkJovGfRUVGie~hozu!Nsx z@0fArDnQ-K+AoN7V>H)z{M3risdai94g2Qi$d>7RB7ggGs^s+yXIo}vy?snt!$d#5 z`OEd$P=l@dbB%o_dSpfLw~*ZIxd(lG6OeE^RGVmzsby0&yH%fkv{l#vU$6WZpWuruvdq? zK&lQ_&bJ z$uFBZJVt+JtM^xbR?(~L;`MwUrN0|#TkWs3^L^vb*7fW8vR-nG{^0AwG}hL6731!x z{u|dRv}m!P{wyAF*?HLro(~m8xKmAetpFP!_=AsdTX{jIoF@4k0DEeW& zyH>NR-LZGS&hk|QJ^9PsrP!1HyD5u8&90s=;@NXuJ@^-qoc$bO3-`mfnx?BMYni{{ zW!?w(bV*IC&UBKeXmP^ognJW19Z*+5D`%&a{vG<$Pv;`eEz!vJY14Z={NxD*E`0 z)>i&46Jl#dzFraTP;m2USoLSiJr~2Sy5AZ_f_jTpU zv9{0_d`_{vl=Y@K;L8{6eu#(ygD=hI2{n`y;jDLP#9pLzRg z#b5G9{q;|)BRR7G-Dk&%4%Ee3j|?qfG(MK^J8whe?d_kly0%j-osTW@Bh&BVQJ7_! zPTAwGxmWM!Pvkq>z3>0hv3VMcuQehuV*F_fer#cJ3%AUzx60p+AID6g2A1TvJ3ko5 zk&?RhSJI|b+3VQGXcPV`)*%^h$T+;0XJ5-mf2k{$)-TIiI~RY*Yv-ME79v)CGueBY z*HEwad@lZL#=bTC3tP6X{qz6I+L{@X`+-oyrmgvVU;UN&<6MB-sfDp!&ypU2|J8)6 zwGlTGqv=di`%<1O*VFytZ$8o=!Qa!wtg|S$EuPNJ z-`t{(=kFh79Anfv9`bmE{+9V$?tw?}_oL`9oXu%lUrjxc z9U);v+Uny*^8eS#2E*2zKaa;xdt}VRc>MF(kLq97J@E(a+3~UdA?6PY_qfGcX?**b zeiT2omht!((u1$1b(k&Q&NMI{{|6Z_s0pz-ZQKUS_{*~>kz_&irbew7 zW`>-8=lQepx=CI8_ryw6g5q+W7DK4D%dI`n#C? z6f1L=GB#MYof);ypwoYYcMD%5=!e$2jlR~3agQu>rnwAtb0_3X@xK*%w=#}0S7g_{ zW+gN$${My-icuZIT83sPnB`J6|6c~29D$$D zJRK*0d3VAn`-|IOD-LwUEVYFr^dI7}ILDkWJ*jmA^$kHnAbRP&>A z4}9BOqVdZc$*bymEVW@H=*Oege)}>0W4hK-`{_TCYF%t0Un#ktK6fv^5d=6_+ESGo87_;IY_Yb`2aZ~FO`GMk>S;hh6N^r8Ln87HnkHDz!5c;-uq1&K$A zQ2D&H3ez87y;Hne?3oF@uS+vief(E!zh+5w_+d+bYLe)ow|-JDxSzhpB8-Z7sGEkl z2ZHv(|3hp|BXzvvtH}b(RYR`g{rKO@T!WQwP6>M}aR5HVZ~Praf4M57r+hz6^E#W+ z#q+E<4o&-3pZ5J}+I2J*|H*Xj`<2XGsZ?T=<;136#hTY%b?sZGzt)bm^uNBF@qR0O zQ;lJ-t-oL6YcGBClk*YRDC>J2|I}e{e-dMj-UO|_fV>EO(kh3r-q%yU#_t7-@zPJ@ z@t4Pd@%ZJj5nYVOU$(UI_?oN3a+WobT84h!%Adv7T8Vruagtkbh%|zJXmKOxhxwQh z^y9uAYHR*H9zWFPIq*YmAA_HtL(Q@IW`zD(J>aAt&1utrsrc%1zGocG6AMrk81_yb zUzYlB?bxy_$IAs)!#?q$NJxHZOv z*(%?h{^yd}rs}PDx%>D&tW-ZwClvC9zGIjw+T8aSf_g3g z5>8lEdzVo{U;1AQ+H1i<6X{5j0hh1p@HweOwTCW|H~xmx-#8^~e%nxg`msgzr(ahW zXWHzK&sn}7rdkBFsa5aj{-x;r<77+J-%#iDFLzeH_j%b4%7<)RF&H(O@zno8wrSCO9g!*N6do8Wa{gdlD=r8{W{}IaP^p|^%YP!FCKgd|E zvCet)`_mLD5Dnlx*Is?(=X~q%G+IaPO+SrrM$msGeu#)sb;zmRj7W?H-^rLn|Iv|& z93GMA(rW~N)G2bxqD9lhggR zUrAfFw&l_Iscw4WyS?1VI9sQQ6hEyG=fowdXYn>VhKGLOq0DcnYyXOD12@S&~xl!4>MB!vfhZt(AIM7OCPzv{OLUL{_>|Q599bt>*^m% zi|Q(~`L?m`SH^FNK*#BaQ!lCbeKU=yo(&4MGt$0G_{;f?e*UL~AFqfVum2Y7I7j;s zfBCr@N9pGzQ9UEXNzlXBIq+Lrs26`eYL`c?&nEvypRUb*_OqXT{Kb8KMEln87hAS+ z(X0K^(V!HEu?ofRRARCpr>760I%d!Jfxo5xa5R7G5nHUn`@~`(?5yFw)mKH^Y63V?<5asH-Mi$Ir96;pT$D=i9f9?iATkA z^T+A^TkO&d;AsAzO*v;Y8IBy~`RaK7Qjg_52ECT@V#n#PmOtw;#+kmKTYsgzjd6LO z_{+^>*ZKQgMrT%Pc9{PV4Oipc?qnLJU#{b;!mH#q*U7@wgKAR=b zUpzBdYkynt>wE_sjM48r?#jtN4j(j+3bD8m_?+RwK5;!w^=ie^w7t_m_vk;xr;?RZ zQaP8@UVG^0)NDkIG=4587V>lZnZv{3`V}oHIn^i-%|Km;bvI{b>BTH5@Dd+!~I> z*K?YvG_u#R_>Toy_piL3>b00PFOSvto4>g|nO^Pve)B)KN8{VxkLI7#%!!n#pJP3D z?R6}Fb8mVqzDC@B#-!(IN_sk$zkihYi!s5g#LtCqJ@Z(6qHNCyXe^>xAx25Y#`JaH z_%pp3pZATw)MMQ@{?awZWBH>xRVx$E(|(R`c62WJPaF65&Fja=KlF-!T|X&*rY~zZ zdmpF2UnE{968ubjHftERw~AS{)zdQ;-(D>IyBO2$8r*rd{*4xM2jponJwz{wFyUyQv+jpJ6^R}<` zSG?R4@rB$m5x>UT|AqLAcn5sS#VCB8Njwt2|7waD*sb)7@M7m%r{hzs75{W!_&a+1 zH2tv?EnVkmIb~q9{@VDPYjG@p77yu3vuWK$ z9K|0wC|W$)}i<{><&Sutx-bd3m2|xGdkNSLKcC3ah;o2%^FMRE#l`(`n?QD(Ez2YOWsWh>_}l6h3E* z_MaX1>mPIeR6q04J=IuhvGM0#?YEu3v_)I_V}7Q&y?0aWL*B|_b21;SfB!815gDm& z_}84w_JjPA-@KiE&o}cb`gQ%R;Ttb8w#J1^nMc*bSp4PMOgPw&|E2V4c2J&6{u=z$ ztGW%2mH*uOU&2?NoKJqO1nY-S-~L_tdU!tGlKj2;pV{Bs+pvqsW{C63!K3l>l?40s zANPCBtdQ$rRrU1A|uO4WrN59ww>WQf!4KCdkHe=;bj+q-|F+43M(D?SyzXq&T{E#(%zAr_uW|pm1)cv3}BO z_4~$OTCF~UzYAHFxDns`T)a$t`?HNxOZUjm?Mo}%wPNU@oRS>Q9^$O%#kad6cdt!MGqQ)(TfO!Bmnps)*M9U@ zsti77{b3yGD87hkU;n&s&GUVP55yqat{ z-*eXJQ@Qd^{_`vf@zgKU=j-?@|33EQvDE&lmOqWQe8tcBbxQfCz4X^c$i4K}M!3E7 ztta|iCf3tl`fIJ+m;Ssp*6DvP{nGXy*k~8Wq)Rfa(`N+xAiba44H=_PGNv*+pjVd9 zU9wi_OMi=gOeas|47s@`*7^Ih$gUa){i zTkXg2bM|9Ah3{MW%h5NUN708@>|e2emroi4gm~$5t9;)G)fdyuMo)>@_xqeiVh;Dw zFL`~(*hgQ_<6+I9v{SereSA9c9pi|<`q96bT9q5lLWF(v*F8v2`Z;TArQgzbXobD> zb3A+Nw$n%BnytIOyR(k7c$k6MN@PgAmcCJB4bLI~n*lG!8a4U}Z~fJ^jJMTUj5hkl zv&D3lWr%eWe%ecatp~Kx|4Q`otXen7(MEqQ8yIRvpWEpFMSKfuRqJ^%Lu#eZYHm5( zXjJ{Zjs8;^UCGvtvd>)9;JoIZ+W23~*3A*t>Dx}ieBavh`?bCUw`=ru?yO@PCmW{z zoizsYXnN}F8~Ha_kp71Ax0hZ$@$sbfHwP+|Fu@|W?~ zZ*v`sKR<^!wZ$Iz7vhg^rWp42Q(ssf)t!rD@XK~^41T$GX&s;XQ=g0BZ*m#o@K)>f ztZj?_x8S?i8zUd|HS*m;-~4r`vy#1zq3==q82V*<_mOe?0#3THzW#s{@SgtU&76qqU`4TZwE}@-P07|8KlegQuSK z=cmiA+iwg1PJbRZm1g=q<(qq_cKN(Tuz2=W*b2I~SkN@nV=Mo$j?9mgwA0RiiGHaj zv={%-$>qK^R?z)JsqXmPiXZ!Ki$q*%;*ju;l#%p_LiW=4)gqUnzW0p5Pj#4UH~Vg% z{1$7t>?!s>`tfQ>+>^t#gR3c5%h{u>B-~8%UakMw$j(rUO7cv z&)4`yMjvMK@8vzWO0rJh^VxbcMY!LuhQFoXm%Nf|d>?cPAPIy4fUblQ$IFleLwZgD~WNh zrLX#qEp&A=wf%LbUdr0t-rMCP!qM|nLL{S?zW1V!HEYEUag@(t+Ue^}r?nEa)30e4 z*U}jJC2cvbJspK#>cM01OK2vwzmLI(D$#7-*E@P{{PWe+hZ0Ay*2ew3xN%7wqSg$77`|je^F|r}b>V zXxLiw=RWv3Yoayh=W(YTjK}v}ZHmq3@%YPjb~JvfjehtiSuvek_$d0d7TyP+x&>Bd zsd1>WRPIJ8kz5p?;U}m%T$D{Id0qq+i#{ z%l75FyXJ9BkMX63e(EvJGWC5w|H~H8n|>O2Omi!dBRA;W#LAIRz3H!4WW+4g z;fFmWw%dKbPqiKM#;11r?x)EvUQaUx&n5mUQCG_eCUyAe9+A->bJypWTJ5f4h&>tUWpQ zb^k%^QU1N<7wEgMr`5*PgYV-nN8dEAxrn@1@Nf6wKNDNUhRJfWM^>@*&g(iqxfg$J z59L1kW_4++)$1?ZGs{}dd(o1O<*Wl*|1YgVt?}=>a~ZdY5aRj{t>q}WpO=O2Xn zub)mF<3^bE{t^Bj?oyds@aMnZKmITC_a|@Y!qYzfx12BI^GfoJDgS9pxAGVNzQ2BB z`u+7A)9we0A=%kAB?S_R|loH6Jgg7dkHfFabkyR9a;?v5UB|Wb(G|NuSP|r|HnJ&~ z^4a_JHV*pXTPw%&vReA#9xB()djB^23xA*IB&6!kwfvQ6*8YB5{)cl~KS+z;Ol$7B zT-oEvE3o_OLCv>Lp#4FC2Zs6&I~>@VRH{-<9?jl&r<= z&Yt%0SK`WO^FD%pIF5~=AI7>P=s%Kt4!ag={PY-ny)%wT?bio?4Se{YR62E4YJPtn`)!YU~;M=&Zr!y|E)s4VsjfokA z?E!UZ=TGDDmq+9A`0CB6S_v8_&@`eoKYg3)btEz2o)cqsg0TuEUsL7rUXY z@%-5e|GaIE!zVLfD~05V{B?}{DL$1Y#9{1}AOb1B&ch!zOeTe!aF=aqJb(Wneut=`Y!^4_v+*fr?8oEXpF@*2;0e9q$2iVX6h zRJw3ygT2m$zZ}&VcSqPyUO%-l=(+S)%9pz4^l3bQwVFyfJBq*MS=4y_gr_LgWYl6k zjpxsIlxuBW{n!tuv7;jfSCrkyeN z+0vs&w9j&naM^iE@u^>WIPH7AmRLYfg0vb$>d78SH3Mh*Gc&oBiU!Wi_$7!JV(R_q zm#n;%f3g*vaCvig|M{2lr1z9?UIsP9z9PIuKhU3RE>C+Tebd(#{nYSpYfPi)hi9Oq zHWhvzg+7xmaPn47o~jpq zN#5S{Q@iRzzqF3t?te}HvF9(*UyhwIm0t3_p5~^B@pY$fUej^<@}IVTKmFLKmiF9U z{2P7z5~mVb1b_wLF-ota@O50rYxtTrJoUrBmT{ddF}_lLRX_S)Oj`XQ^w|~jOnmQ+ zoZZ0AzVNKioR0g*w}e0M6Coet@#lS}KmKFUHS2k3|I52QI2QGWX!GYj@-N{ZBmd9S z=}h#U*n{+v&*?AAlWMp>et3?q=JquHC)&74;XC<{$D&e{dxI7N&of2V(r_Ak#k zddU~gXhQEZmVWFD;+E4-eef@)k%RMjH zhraYv>)B$z@2B;#OBsh=%H9<6WH%3%=J#`%!f#sT(`rxjH)egVM89Oi?fmNsM0vyw zwbR}{_%0%akba4GkXreFEO)uQ6O6DzyuA9?PM;e>--!=q9!oZIPP>!|jrC@qTIHi! zmvdxpWsSI$lQ-JDx6=Q!(EcbnxaCz@N9a#Kwub)nV{hD_{@jPTw&qW*_?%(zaq?-) ze%X-v(2v{1X!G7qpDeG=^lQ9wEB$XpKg3Dc?`zpn%*hX0_doBcTljCGUt_WVzufxm?a$e5v=E~*^&V9FxB499vRAAAsGie1zu3FVdPA6t7oOm`3c ze2c|4yode|68|x_ah3`hgR80TTF(KFtC(WU@KYHdidwO)cZ*RQ#jHffQ}vw7d*{LF zO+OuHYUp#?3su$dt`WPgSN$%ZRCmP9zW1|s?`55QRvWtwV_iPo5lPF?=Clz=b-Qb8 z+J`(1)tqFc^fqNhQ9Rwj`>Rl@D!SK^juGWznl^9-G>%@ ztNbUwzzmu5zBt33y{~$g@EoCqK3N6Mt-A@xZ2NtUXH$@R`kEPL|EQmoUT2?bAGzPB z-XakE?r|S~{F-~-SihtG0>6TX;m=#ibG7hKX4Gya^qU&+9`wD^tDb-L*e`@T=I&Rr z7bl08;`FAUwn#mF&+Opi>bP&we@q`Qb|tNd=dn3tsvADn^M4_le=oFtdGPgQ9T!3w zkE&Um9PKvxAtz2P{FYPoe18^_F}@Q8@f`k3Z>8|t`rmtwdfV@PMR42i|L&6lw*4Mo zLYC{THGXn@$_S7}chu?$(?d*i1&ezwsMsl@!I zpVsL=5kJq|W*$FWiKk{AT>t(?B2dnGjbqIk`m7V+=kX}o=KRX;hfRHNEI}Q8jT;^d zuNEoR9?kxErW`(ch-R6pW`)3<{A9>Xddh;Ll z94vXA{&L*1)*kEhHB0?#wb@|uH(o4GL@j__j9hDO6m7Dx6uffnjOxN zdNz4r;`+MVqssDy^tGPxm3WPMx+Xyl|Bs~)&=bCr|4(AS%;RlFxc&EQJy$v0PJgM@ zO!_+g#&Q$eP_50a=sKF_`h_9X@c*??do4O{Z@oJH)0sCb_Cx}leaGp*Pec;Usgbqg z&Mwc<)bPKJe!uq75t6gNxCzEbPG*)`ZC1Az-`XsEuaUomk6zKR#$GCK%iVGCu?OD~ z%OlMm`Zedo)X`@?K$htz$xghK|6WTbi!4#NvoY_-Yv{)joPVm-um6J9^iT1w6Dnor zJnrEyN53vU!}2sHXZ&%FWBzM;;2!=jrWT~$^5@B;T!$U&?zx?QSXB_8p8rf*AiO(s zTl?12@1?)*#m@2m%+K&ycw-`l{EeEi5^MCgMnAQw5TOVC&!*WvqskkRkCBHPf6G4U zocO6OdduHB*7wH8r{JgXw#zdcZH3)Oehg`ERG)I$$^PAGmO66an$=|7Qi ziQ53f*9iKt)r4sC=kfSqYmLGGUPeZCJXyxCK6}&0f3@O=8tI{b>U0^EuwsjUw7R2@ zd}aEE#>|_$gVwyonD*btU)UN)^GC*?3Z}B&#@dH^3g*-$9?pxu+%~jUAO6gH%+K?! zqi?66Qb+Pm{wry7n|-xYb(|Xh-^gr&9{lR=o|FUMH>>E}jem!voSRGRJdHP7dxne!Yz^`oD1t|)cS+D96%YZhIu`hyT5dJi5naO#3+fu%$-uzpgcxupd7D8f(`P!w|O8Cr^DT zV~(!!TV{rDIm_p@VCkz5ed;i8jOFOPCwgb;9rd8^v7%|k-+R!< zt7%5SPA*_2{gq_;HF|Kg`BM-4(-iOezR~*ZQy>3zlHLA96}4-kp%%8w|8W|tewk)A zm7^3n9`BdmS$g?XrW#>n2#8`;f8pUFoqs)JGZjNfXP z^PIP9zvLfE?WXqa?OT>V#`p0g#OAr5{CO>Jq5o&`4eU93Q{9ull1;p z4IG7E8Uc>N_ZdfQ14rSPEMOb{FL&e9y4`P~Z&brw#I1H^S{{vG(ra)0+DON6?Y)=$ zA$}O??4e)NrX%RDwVCOT_dWQb&bCG8qwv!xF_bud9wUE@U-Hd8^&i@7C}A)8I6*S^ z+D6|-)As$SDG&Sb$q;znN6*HJ5&F|_>785qhv_#bU))n;Y3HBz$^V7KjVHXkR#(1uJY>$e7Dv)A4lNF_3X>`kaBpR_{-^W41e($v6O2)9zWK? z5%_U57hA~j_~(}2eK(poUVcB@tS^3k9ig9m(2v`0EC06Yu^xSFYo9gxu|M5XA6(*` z^^ef^*a|SKersHPb2sL(+UITA-hRFCm%Iioudh6RR4-B$|4v46WM_vR5%lvZiXp15 zJDso8{`K_NBAGh=9S=#uy@GYW=hQ~#GTb4rCz7@4Z~pr=xt8gZX@4mzSS4E_{L$2)4JDd@wdJ&wB*f4;8P_- zi|C$%60+)G1U~D3dR8NQ0hV9m@y{WDTw}1Lfid!j_{)7@Jbviy=9(CT|3Unck5Ee% za6Eq89>?Ry?J)wM^~qZq8(vO#f#1vSMi@w&@#IgMH%y*A`y4UDmq}}}< zn{cjiGpmF17K@*@$=`}!vYxH+G4r*$nbJ1-a`f{u^rIj9ZEK}|^ut+$QQxC~pD!-W zShw?EqF?ICE>rll4d1Z2UzS}l*!xSVHfOXUKcRDXa7NOvku=3;ul@_k34JXi^sUUX zAIdE`tYztZL9<2ncXoG*_GVUtE+_9B{vy<6?s+tRzSlV?qw({-@;Ll_ukC}+{RUde zSsH!k_T6G%HFmV8{TKmm?oJ8*T;}8_v2t>NKid0j9D%=- z3qAsWX&l&xPyGY42ah7ZlQDzLFn^P`(XjPv{6k13?H^n4m#iV?jZeqxXUSUb1Aj}_ zG=e`O5Av0?o9##mZNk0Z9KA>T)#JBWmU6q_zUukQS=N#GIm;P?4^{5}`9~SmHPg(# zs(Pz&OFBP)%T{%M{&H4zpY)frx)JyNa|(BR6y48$*6{N-a~yu&CiddLozB)ILqp9jXCmh2Rbh+A&&S}G?eQ4= zeA}amWAO8BzaO7DH8XGGORaf2HCn(v`RnmZEpQZmsRj1n>we~!55ALr_l2|qS;prF z>c0hlg#3?Xy^%8?nLT?IQ=13cqyHBCk_S2pe}w(F$Uma}xhs|tpE*i7dsfoCjzfF& zpW=H20M+x)pZf53-}P6r?EBKbCClH>AGNw)aQg&fBL&KTB3)+?|uZC9CSkAEO9)+kDSnZ^J$I#ck8q;$u8R zoae%&oj)Cczho&#;4fLi9(=6};FKRC+;-j58l&--bbkc?lJ5KBQ}f3?m2K_NPyfsK zB~Ne^e#s7w!Y|pu9{jjwA#C@Owz0VQwHN;+aUH9)oX)U?gFX1{#7^sci8q;Zg}nIq z5X;V|WAW?T#W+2dzj-e?7JuGL*72W6TWc*F=T!fESA~bBbr%eO&gH7tuhZANUp1S! z_xELvjIzGB$REqR?e~^1H!fQ7?f0YPGx~8gvvE6rZ{c6hDY%xM!Z(tud@S~JImNcj zVq@LbN>}4w+`gEPSUhc#wD2GPzLvwS^yfX*IF8@j=p%Hl|J{G~@BN4GzJLAA|MtK9`@etpAN|k&L&`*o|44k_eCNCE zGk7ia`gS(e?_vk0F}~$@Z>Q+@cFKz2H&1srkNqy+YXvfA-(MB}bxgUmqdS)1X#Q#6 zYmt-I&CA>-#X0z=eW|SPA;Ho7Kb!J>9}2o>m6x?nc9fjt-&j5S(g^{vJ*A({CEta} za4ph&DLr4ajN7E?#Xoy-E~S>`)#Q!dOKeInzCZf)y$n}(JBnV4hkhqqYTMszm#H1)0?69 zv}}L>;{AjDwZyA$clYF8`XjO-iq@#De%u{_Z?&vCQ`^^u{rJ=RO5$^Lq&I8rwf=to zP4}9%kEp%$WB58czL9xZ9}jT^e>OH?Z`88cxW485iml_5>F=4~Gxxi%`pfZmKlI1W zVa)-Ay4%AWBS0_vqZW`^4g1YoJX$||PB-{X<_3OdTMHjHUZ?LP`Rftoj^&Rzjjj*t zs#&{6d+`_AJY&?YSli7s$J#fK?#G|rU3&ZAPf{!Y)0A=iP1Z7B%M;m_`iLX8!2bMQ zNKZXYJtaQZWgCw@`QvUeJENqQn^E|>@}t>kUDeu_59`IBa>DunaR+;fuO4jmxuJ#i z;*XpRYkueQ|Kv5ne<>>pyi>1#yQANkj{50Gv&JXkGaRD~r}W+rpWF&-Hk>MLKA^Uj zmALB{Kaj8GoRT?5w#Jm_p_hJGhg!bjZ_e3~@w1(NZY$Anb16I%bKPcEiE782Ui$k{ zc+uH45viZky-jQ0*1h=qNm^G=-f^!$h0*=tk8{0xwdx4{DSz+9+J2FKiq+BHKAZeZ zybIMmKd5g~VD?L%W`uWyc#_0vfGP%o3edF=Fwm96;mN)hX$>EC>U%07(8*DMDk z25ZS_MbGj0&tyCxPgPfedIW!XF){@@vs0_pIp_BNky-&Kv*qh;*kw(>^>g7uLm4kW zBPlC0%xUN6T#v_Jwu7VbHSb{2{t@lZ=?<@?XTFg(_^Y%)+(XC9ue;E+=75-z`age- z$JcR-Y~qbz>)F3Y;#2)ded65q;bOe}jvwCZWg0jaKCNP>t{N}7_jB>5wXjwrkmF3h zI~RXf(}^u>(dqf@Yjk{AKmNJ>mu{u2iQ`HZFuwigHNuSa-9lKnX4Z`f7K$R7KT*be*Qlj&j~MyW!B2v5&33M0IJ_~=}7fQ;K@ z22Y}iCE3x$vG}R~SkL11vrl}+NBieW+7KA@0Q*G9KRQr_hzY=a(!F*@R$h?o#k5%bl-{>ay>WBYY zB&GknmH${n`$l%C6Q}DwN7{sy6!y62itc-fU-8#e3=qxc$BJ|D$9k&Y(3s~9efHvy zEVABZQ`(=D=iyxVxv_MleQECIHn}OhZbqBq%f9QUKk9Q*{_qUpno&Ey{rF?vNc2M- zzdtVNuRrC_yaQtm*&XeJdE1AFUi!hFZU2O>?#K7agt@~qH>MSTAHknSX`Cgatx0Yd z587^BWAqoUtuteNRq*Yj+D}&(>RM?;`_zsdJ>`EaBdgAA`t|Le{CzcfM|M7H9iv(< zR;zIvYlG*sU*j*dUA;Gvz5I4M!Q7^L+0PbyMwgRBU7TB9diCRv-EL??Zx@+sBF{lD z{BH!EoQuWwN8{sj@nw435xFMD^>r?K$_r)8TvDh9P;v`ynebhgOzwak)lcT}A*YbuQkK!*s z18?OvY`&8lzW)L+#Ipn3Eez?E&m*yCz7ykD$9-XE$ z0k7m-6EZC~$z1u7jNTd{KA$o#b(-qO-_OFKR?g?nHe)?m6p=TcQepM0spn;zFr^KR(f5Ys`T>75) z8XGW*JQ7smP@-YhLUXug3H{{PDk@#!{6>&pNGs41A3yCz(A-HFv#hsLKmI<79TGFy z*?&Z<7Ok5$=IQ5>AOaTULjA;bUw6BL6ckp94QX&#mEPpZ+~#;irOFn>>~_;aqU_Hdt}4 zT6Q#k>;>9tEB4#xl74=WJ&t?r?=MrPAod?Mt&U{++Nb~dND+^+*ud>H-Wp!|eiXh| z?B0kKlC|{LQTW`%j(7Sv<$f$K4LNb1!l$G7qo0sbg~#wU7N4wku4>XbI1)eI8w3|) z@$uWlqxrol`|)+;e)q`>llcHoZ-F6?%crH+KKTuQ?k5a$3w>Rw*A+b7clSzSKeWg` zE6tmS|7OX`df;n5$!Z%+GJWq)zvRhcT>CTv|Bdun^3>>B>oyH-{(cNTaWr$g`Rf?` zazE~m&zw!GQjoSkeIhnI1QDB_?m*OJvnnE*aGV&2pW97vMEizwu`&Af%tL9^bvZ}q z*YTOT;YamU5l8i>vH0t|=tkqOMav`b8Jn2(Gh3u@#VgiicUdXWlZU(|@=yKw)1Gb- zNq_oYDTGA*>9b1-&vi8^Y$W|~mF8oUKR4@BjpP{?Uxd7>5VAtvqkg1cC?f=9>Jfj zzKzm9YdIG2_vgPY(>W6VLR#?;=}W}d%xN!WT{C_4$B*Z9{pmlG{_;wC%&!uq(UKY` zeJ672KDJoG5%^)wawPrIT6xQQV}Jhi-b1ZIw^>rG^YBv-eDh6loM?HP+ydz;O{(7v^2cLR(-vyG+7{asr zbyd+V@CbagZl|r(o;ze5ZsYGp5beAho3G^88u!qrzk!rL@nesDEC0*%e-!Ud^~LgQ zoP35)W!bI7MlYvop>(xq5B}Fv^r!PbL#v4iLyhdg|3N&O=0dL~`LJEP&DJnR(buXT z&jFV5knQ-Esn^^tbun6Zf!BB~ZTU{J8|3iG@o$+wmg(Ey5aAPHYOSbgGXLIFzC6C} zSF-aD_2eL5DLNOv*?V3q{_S}FmN^-NACG6H+90%W1U}=J&-PsRqwtsTV)QZc$M{Ry zKLUSgc0C3^^^8kVTu=M^TE@|9@xhu?x)%R{3-st<&2|a_|mQw>Bi9Miwa=>;57^uDIGh%VhKJ~LF!C6~3H;G5%$JJtn>hGiRi8aG| zF-O*?UikE(+zF1o=s%Hmz0Onx^rg>=g~nr85dESbedy`lNUbbVPt%J&UX^}EZsCuh zk;l--pV#%UQTUwD@OFxdh@MN;KmFP-*01gf5Aj*!!o%rWs*fULSo&2vSvgkfr zy!!k#3g2rO=a}I)#nJ%sJBgT;kRr)&5o+1y{ZI@08`wA@yuur>_yY?b%Ls8h-AF&+Sa+ zzkN>IlRi7&(wzJl`fE|AYj6zyvQKvOe*MGOpzG$n#zQap9iJF-t?I?l`^k^S@kZ|^ zk3@~6zIw?wr?0-2sNc_z*YCm;347sNJ|Uf}_NU*Y>SbU1(t6Be$;{_Yh$yX9I;ual z>&L2Hh-*00%5Gn_69>bpy>z##4`^Qqc`s>I{vZ&^Lv(tl(6MDpZCsKm_O zaoeuHCHlH|G4zli$G?dCa9@0ATcye}7n<>oV>z>_@O?jjx>HrpPKx(-fHR6d{)|{a z=ZobYy%(Pft)JAPQL{P6BfSiGcWm>HQFpPxyKv+JGtre(r%IiS7x zAvgGGsxZUX2>Kq&u3Ow#d|l6bCA#)g!nJZsvz@t&SE!x+?Vr=X>jx`%AtM?YI4om1 z7ZP)(pGN2}9KmyTN~_kcGL7Ib$5Xn(ZMr%a{&H20aW}@kYV=cUYa{eW#TqM!o_$Ww z^Q#-1&|**iykFM)jh^_qc4O3FUz1jv&QI$YjbG|lX2D0}*Y>MD{1J_EQY|-cUC8q( zst7U4`o2YeX2n#DalV>Hyk)8S&@cC=KJ=N3F_+gkE8OqcPT#V&Rt>DRA9kJs`>oUJ zs)wIWtj_<2xQF&6_PLo(-@TMxrK_k<b#tbrv4$rPKoVk$;UZ@N3jt zJeD>=KI$$?Qj}U}i~k>CUvc}Sar}~0Bid(K!dREbd|iXLmjLvk@52pIWy4U1%}!^M3sp#u9#cz3do#;#Kkp^VhNX@X>ZA$g%v@uX~#& zkKwQE6OY07nGa)?<)g@s9D`3pkgqa44xf9hiA0FYS*wcoot5e|j^mG9p+>MCWv}yi z41e*MWPOMCc6@F>)EV!sc>M4aUY1iJ!kXir^q+|3v%VC*M$rFUEDdkX-krDw=XHo9 z@Wa;XNk8YsdeX;BkO|=)B68^INk?J3*>g{P-*-kGx_L=M%D?x-|50SWk*rzxO6l7S z_~C<|HeIB{%ZNX&(ya4{yX8_PT4mKE%-l9o`G|?{Z;<`h5S3}XgFtp z8!piu6=FQ;&F0*cO(Y%nc&E)%4SnW&mZ7t|u?&H~dnE|E>J!uMLH{(Jj^hYO8NO=y zzrO2J)FhhbJSqq&#?LkMjh?Q6*&YkcWqvhj2CiutS|fh7(DzfS(YL5lMFWGv_@7HX3F8z}H|0KQc zwe&gA`&lq%#gd5_E-I;^uL@ukNeM<`hNNsVrS&W zORp{ZVIPz2`Zhh4EV7mU<7p%_s_pVWo+2~tU-&ycy98@sPBnkE@<+_aOfk)|&ME6R zt@OVY>PUYz-Nbn%PeirvO5_*(Z|XnvGyVgr<%~@X)ylulC#=>|SC?4hV7@^;X4>Oh z>DyRtT+V;b7{>@oWeYcyQQu2tJU3Tx#vSq4)!jIVCqBvFn!V-z{Wr2gQ2vGSQF=c& zf1gSJ$BVNDr8OQzq5e8Ie>PtzjRyCHKl7t$ta5JtI78277v8G=bZ-8hO7D9i9MaEf z&X;5*`pEt}=a1|JeT5v!`U=Cj^~)HCuj4k?+L{`-j@1oC3%u%^Kw|-;( zG;_rXzqPtPhJVd`y_aZ5GecyO(WiOWu*Ku&E&S#7G_;SL^PWe3i*p^wG{ZZi_FA3f z`S_15V+-%JL_hw&ntIahozDvA*Sa=GOw@O8&=~%S1a3Z!0UA#-A`rFS+*L8N4v|KZ zv0dAz{`y_!uhkCv@%O#-esV0=@}Fk9VlB0DrWzc>A2R|@dY}f%&g6}`wYn&>qouiJ zU;7L7_nmNd+l9kz`b+05%s-d~YQD^Dd%OH8eNOhI&X5YIpC`|2F<6L|d+sA&81=;{ z{prU$iu%ykIikh|tP!$4r1^%i^mX?g8GbU?xi#Xk_*4wP5J~Bwc`o|l=WV19eLEAM zm0w~!q9=CikS|!CVfDfPLG;K7H$TmB3w>WRV9b9cQXr9MbahPS^nX^39zLjv9O7Q- zpY98ProkTb^AY+h?FT(pf6T)*GhT`WnNOa?8p$c}I+8zn_(?1lTV<@9ug1CE+0(iC zE7{$B;jd(O=i<-eia3fkZszYtw{M=mvKEiz&+1Ls%gOmw`8i&!!~4gd?uO7+4vlA1 zpB+kY|M-tRw*Bq!Q0hBW*o_;Yj}DQ7O&L$L(&P?hk+E8V+lTx)ooOOyBRXd|G>xkGfoj z`@{eF$A{Ry*Jk$TX@7F`;VBG9x1Zzh={4uFKeE-9VR|9sLLBQjSN?RQetmyI{fKZR ze}2b$9HF?j=1=#5zoiK3eEii#P+Ry5S27>U8S}m_9Im0n-frG<`pr@Jr3_nN{8;9A zB`~jnk@z(c)EfR{iE6c4J)D2B+raC%^rQ}EJ2e$;u^xKk*RJau7d`NE)exbF-BuY< z*FS37=L;Fp8I{;AXH^iNNvpDM$9Fm(*Ax1C&kt(&TWYf&?UScZt1X>8)ldH={BV~n zb!f~cSrran7owXeJB;Kn2 zs5N1nV@<&G=iIeTMZebXT!|mPk$*@0mcG{bFVWZUy#`Z9w$Fr*@b<0s_FtyYjSifc zLGR7K_VG{5M3so1W0)JO`qO_lwG$qRTr;ENQkDHae7B2IEzCapcpYlo%CEij--?c` zujf$q(3hqXf=j>M|8iCfnSo{Rv`+tP@eq0<*QMz5;e$U5)wd5m$e+)|T5T72 z{I7JreJg(1W^gw$4ss_7`?2w4*PlkRHT}kvA2y=4%hx8=mm(1n=?jsL2!H-+mG4K< z>I>13#{yv{r=31?+jmngfwp@oyMY<=nH`Y(rfrvRVO--sq>m57-tjT(lvS2(^p|xK zYH1sNk5M0qre1xr){t^L|M(;w4Vekn$9Iq8lS zHGX%x=x8gxQ)$b7tot{o+=oA?w2Y?~vExZLl}miE)nS&dO&_urv?tN%**kLib2Q*O2G_<9EMy5BT}R{hQC$MP9nd+$wu zwEl>S$Xe)b_xARWf4{67bkwS!CHk$p*@FL-`1G1_d29R6=`ZWBRex*rTXooqPdB&b(n zdyK9l?5{*WmeAX&wSDU7*K4p9|2y%1wnyG`uw`59Prsx|*J=1P8oyrCAy@v~%HLD5 z+^Z_fRgC@gZS|Haj~hYfoI=(u^xor%cWz64<%{Xp*itKg=t;}1Sw9oqgU|f} z_;@l=ti98Q>1z-D?}ehCC91R;+pv*egBqK5`o8K~GgghIpXZ>)ZcNYX{9TLISR-Oh zi&aZz;r7g)zN=}(C}q6%(WgILODmF1%g^Sw(SIgXW2sCZ>3c8wS{F*z^;S-AzmhYb z@H5;nyZjoDkB(nSpEyl@!(%Sxs~D4uf(=E--X&h5c!nWHJQAl@yURr_0NTi zlt1;y@W-C<{KM)KcgKd#g8=}7)s?8A6GmOoY*PhzXS%b5BFYJ7h-hLZP@ z{5_rGe0EUS{Sa6rD?$DmiQjJj&X+wM%^&$sYW(cg3;(gS0jCnCBgrWG77Y-cj67d| zJ`&`|hg5!@amM30)d}kDS)WByrKr_frzXFcMylKS)4t5v`NZ?N(`ubBd+OD`PX+Id zRDqG%VFawLU#o2&rH{4Xziu;?A|_G%-d8@y=gH5Si7~@Z{qXVARxeMiiN52#k|C}= z_rgbBsync)@YRcceMTZguj^m*DEh9>&R$N@;Ysd&(s59uAMQm)Hl4kArlLl^8v304 zokOUludyn<(dN5W`gjrg@umF9Y-LTBHv053vrOf9`|tl|BC!4Uv1AtOrTgUC z=!d&+zn|izl%7iMf9|J0-;?OnTiZX@2|j%-_G;sQnf?|ZzZbup`BE*m(JyNZ%g@y$ zx6wB*HrJ!?m=9aOwf*S@jBxBCi7{fT{;7@s3(*4EwmRCN^q{Yv!g&s#+UWl%-ciR@ zqH@mfUz4PbKD)HutTT z6|$wTef0grE_z1Hxgyokr+3D6<;G{-@38{bDHxYIIfgY!jfCrdpSFX`Wqg$0>*)V5 zwL*?Y-S2;rJvtvg-Iflu*He^vDKcN(Nt&ZR@4tEbS*QP4W;585%^M9Z<)6DWuBRyJ zmDo4g5ZitCNPbOJ1HafM{W!N{&?xJBJ^e4InXT1Mji8TxF&?M89<_gSlauenM$h`M zAKzIcJ%9dck9~A84bG{8Y{0=jaXC zmGg6q{NGPj|E>YoETLY0Z5gt!^dWoI|DL;b_@(A&+JBFXoM%B+<0q*RV&^YAfR%@c$1JU93T~q)(?xJ3e9Y z`BxwMIvPF_WGv{T*sVrKZS9*{G90(?_pS5+Bt^g6GxkxejU4^;LQBr+hpnTTy|5;Y zdsrC>G!9Trlfj~b1>5;`vU%5aJN++&hS$Im;ruMtQM#vbFa0<&ov#_J(|;oR#q+4= zMn6O;eD^Mim0c_Tw2wZ%6(4gcEu7cWKKfrww3lMwee{WXmt*XG^uH9l(VKu=%VFLTC$%U{U61?UVb`LpeO$|^JD6|+cg@2_v*)PTe*5r zno+jv$K=sj6r&*)RC=}3XC?0sp~?)CDCYTHmV&s6zP!A?w66bW;uC%rx*vox+=u>X zE=9^eGks$G=hCu|WIW;d?Sdbx`+d0|uKk|54KV_1M`(-r4q6IpK>2%Li(Frm4z;j^ zPdrG)nV!FgKCWb(!=9P>+4(m1_gB)6RQAKMzxL2~dNC(Xecpe<_KSaI@iXIhyavLa zOmYQ8W|mze-{iMshlufWn|#FYTkttGiCssGayHT_A4lPnn^8~DAD?!zxGioo@;F$1 zZ14F>;kaGwQxE-oCBDk$WSWO0-et~}&SnhN-+SQe%$k}G?o>b@^*z1^KABx2duErh zcka{w{vz7sR?@f9JMbVx)xGSXhy2v3y%*`R{PfkEeyZ!<^jmvWAAEcV-6Nc* zeI5U}_9Y8I57zkU3-QN9wNw|xz9P0P{nSJM$jr!#?8-?+>`BvoEhSCw#s6ZO9fPbnd~*E6uZ*_vRqk0^+c(y) zR;0a5_JXbBS{v+@KaE$7uD$Q4uf2s8DSD0Hk(OVdTA%;N`Wrd-KnHu}XFMQ7%+B0g zt#42II;U+LA@<@g#ZEo+w-yWT=if3EX7TZR3wJ0s=qvaMs=;9q7Km40!pKvbFc^BEyn4kPi^$^b1x$UA(!?@eypZ_A3UdP|O*B_5x@(SDA z$K%aho0x>7=+8a1A;#}5_*TKIXABdm_zHF@66{AGe|9bZu~xVqmzk9P@bj67QS_H} z&1o~bQoELk>Bry26zPy->=~>6apU zvkQCQPro%{H)MTp!FQdl%?cc&2Yn*#-=%GIKgJ*O&U!Vs^ALx|afW4gYVS?!!QYo+ zMP$3z`hsi4pZef)`)94hj?GgKe0rnq+@UTxuIgXTZuG(DTq2~`8)3ret`Ges8G7gs zo251+jZJ&Ck4FMpZ^~W;taUVf_ZReFZm4JO$eh{t1GMNb%xPh1=qrw!N?x}-Ubo=4 zQ*X1skUse?+9|G!kNs|0s;Oz4+t=*`i_{VR`p&9_|>1j zuE^<{WcBbJR%+vN*qt#i8e%`$z&N+jCfu5ZM?{)NTCqk$hrBe5MY=r0=i$=%w{d7Bh z9b;PeAA8K9yUH2G9!@r%@;|4Kbc}Nr&6f5ow(CEqzd63IUpPXY{=S|@=U=3KJ_`4& zvg+PTauv*&<2jO3ukF8U^uH6Uy%me)&-hixzwgOOEwuLc)@C*Xc^S;`L!TUaed5Qh z`$|m8I{qy4Kn%s*G+&CQ>~>kBlz-n(A1UKGQHWGW-+Psw;B_T5YwAP2 z>&{^-e`-JLbPb`EerP|?*z@~G)A&d1<9W=wsMxsQhyPe`H5zt$>C+zhEW*(DaOQxN zcK7>o71#{MtTn41U=L`r&_&n4OyLU#8Q&=y{ADdecI= zHyn*$*2KJT^3BowE%%l=kG1?UGK8^TSiLr<>fiLB|BYA%d9>WCjeZ!L_}G`DYv0w; ze>Pmwh!4P@;1Lj z*|FOGc_D3iJ@G^PFjCll1<&W1#l-J*{MFFU&sO@;-KGW~8lee%TN z$ys@fI{NX-A64nB5XUR|`AqB>`t_cC3_j;pS#3V&z|`y{?5BT={m{Zme73EcZ(l$1 z_D%hDtN#4=mfhLrH%(jH@%OJEq2J%d%2^p;$3S}iPq-c*o)kpJ?pFTO9A>HVaJ_%G z;D`HPOn1C5>2FTo&U*^~CSDuBV}+}f`|0b6PWap0Xw{egx8mh#7gljDr3dqj=E{D) zFFvQv$7jj3(5JdX?;0$%cG&Xz+(zH>@gNb;kd^mag|984||Ut@SfLzF{Bq{qk#@{5}(i@zdV5 zU%tl@O|pj03J>E(tAu;yo8xO{pA6zj+Q52XD__Ka!$f)zP^Z=dPc}q9l&6gU@@V$-xvM&qi z+VeL0^)sXv`d>@Lc+=PlE%euXq3I-iZ=tUz_2~T**cOo|>k3O*-WK{+WyJobaPGR) z8~4*+_UNIma?dUJ2$io9YoSj@ zhwjS{A-@IxMxQ$!<_PolXyM;ivHTS8RNvk+^{Iva#WWV{8rB+J!)c-K<9n#N zSSM+OI)=WUT@Z2+*IIqd?iDkc!}k{cxRr=Vhco4gBgtfu8;vy(Qg7>@|19l?*IA+$ zQ{P6vKKfXu|9I-{cr@L=lsiY=XBnOu4`o==e@dS_+BpIHO8(=|HQL~`(D(6^YBzS` zZU4PydB{8I&QJPd?zN3SyKe>?w4D?=>Rb7b>3=h!q?t#>TjpQyNn|&Kt{+%_J)Uuf zD`)czab7O_b{l?(Xq58r`|0DQ%DX1^(_hxuHu{W&HX{#pHOFe9k6)wS*LuavV6HOH z2x}cczE%9&7JMBebT#V~c#kFQ?eu-L>_y)xrkZ39p0~3W{+)i<=6Sl-0^8{8SPa*&nNC9=G$c2mk8_fAiq)AN=i|w2ZOL zKDf2fS1k9?_x{l?m)YYUeD6Pbe3RI)a_?jCsV%A7h1&-|wrAhHv+UnofAR0tqdg3E zKz=X%UsqyN9q!|w9{WnHRPn97LJQqPKOC>e_Wuj%Th}5Bvm$!B^?Y{6QISy^eQMjM zhCX9z`zb=p`qf>gml6+*82`98i22zI`IFNpo_>mawdy9Un@PV4!q z-d0@WV@ba$K4;p_Z(0j`sp>1VrZ)Oi4Qn+G>t1up))G&qXo5_OYa+kO(1!1b-15c_ zm9-n__tR%=xDu>U{4YmZ`}rp;`pd+Bt_H3LeJcAo`-Kzq^`72xy_?y!z4yTXO}vZN zZvFr4oey|iRh{>5YJmb-8MT;-RYxtPLc|e+sTkL3o07By7)u~s3_3t+N=adCQ&MWw z0a8*i=m3Efj5>5vQXuNcrlw+CM=Yi+&A%SMI%D5Jk05(%@_ovTTRdO+PZqzFO`_i!mE(iVm}K%y>)B3! zY~GfUTItnqAZ6PMLys)saNNB+iNvEfJG9j|6=)fymqzC^kutJ0Xi{ClR)!eq``txvLM zm(=XldQvv?Nu>FT-<$zbzta-`4(fPqAYbuYxwWpT#EZ{r8Tl#y=(!F(Y?! z>4us0y!p#trhQg)Ipib%=J7lAY)^E|`OCk|mT%*VQ^`E~R9u{tuTr+%na6fzSpsgZTf^2CX3_OpD%FYQ6nB4@UlJpV}@SM>bJD)#G{ zFN-~5#xK28{bRiHv-X*I@#`})nU_!U@LkOPxTf#6l7QemyAJpXTZ2Fhn- z9#Hy28BuSBt+@pKduqneGkrdqe8hcx(kHn!?>CUO&eEzkPPg~W&JL3IALd<^`7ht} z`fh21`7Gb~ZN#i=xpr*z7||tc?hEm}@ae0bu32@j$wrRh>KeCd%Q9;$^)4+s^ZOez zt>5_NSHl%-S+gm>6e_J!u9;YWg)g6Y@u$B}6h3|CSz`PeD}4N)pr4a*m-LFaPOofi znr<`ZTCnWL=lN+r$@jFvmyh&C>bjd88Lp4IYsf=6si(D>;|Qx=n^gGp$z401>6FE9 zL1s$gd*Rb}73q_5Q>%Wgd*b4)3(hwPsSL_=|AP_ul(LX z`s)A+oxVEib^|Gr(URPyq5l;+e);8f^S($Kz3C}P9={wN)pKCgEUJ1&m3kJHx?(-^ z9qaroooDRLR{Z+2wWQZd=NVeFl|I?C_2(3sZAY)O=r%Na=~FGi?8%cKb*vQ5R{CTe zjNEsA6XhtQI_XiDavrPJG@9pC$&b}msx3O6>6dz+z4+y~NpE7DqvpEgcQ(}6IQza; zO7VE5U-liuNL;mkcU;KUhc&5*sVX%6W znRL9;XO5fH3O(s9;~!;aD}DNvm)YrmgY4i1eA`HkmV!nZ?-j#@_FjEPkscUQb&v=NqE$tI;LM{OG%1)8Bus?^|~mr;7hFO00#El=K|3E?qsjLG>Wg z7SsxlTc$@>w@yFvSN3#S6>{D5UN3ujY#3M4)S zdntSKO@Hh0Qr{!4*Kg+WOD|`YjJ%T4l73nK3K70)U*_FndX2`uE`0oIMp}+S@n%yB z5r6tu5At9BX3JkmJ*zy+Ihr||j4gY4mGAtU@$1*2XU44F$u)j+ZIBw@+{E=XwYovB zoylLm!`FL@e1)%vt4b&L^snUTC~YCpmE>I0UrXz{Y5JaJwU$FYo7>vg3Kzav^JYoK z_gv$T?Qdn4OU=%iIm~bP$!cmg@;7spaenhBJ>&Hp3(Y5Prk*9tcl@e%h@H*0&TQ55 zF4UY>e)^Bt_A_%Y&ozJQSS!7*+(WrBqp^*&sQkpgg)4Vz3?@hYrs*2Cu2sixx$50q z<6q5KM$YEsEI`g4N(zsy%z{crrEp0y9=p8plZC&z(!XYbjUuN+&{mG|hnw$g1$OKQsK9dr`cSRqqudf2m8=N>6t2$IEkme!o8UeDnrJ`%R3uqx(P^f6t6R zQ7@dY{K;=8$Zv`*Wj|3XpK__cndz6A2J?;;dCHQ^f6EF6`6U~PQRa1`*WSclo3~~N zmJ&)6-!}jB{JW;(krAtUR=&))pU?S}#2)*uc@;}iB4)_VaW|;?E z|9UG*e%(0V>67_wNtt<$o$v7L2wP@!H!))@?L;qcv)!1UkNB67qs_!=UV)VryK==W zb|%4$G1l`DzZ_4J)pl%*v9IzGzs$Z!-y`ea^}l?FFD+MQ3e#P|oA3B#bhd%gmU{=& zNkhKlFU0;6U4PN5HI7IA>Zki@>5Ww{pO5mB`*Wl3R*Y_=`3-;O5hVZNFJ(WIBd#hV zx$9VZJn3uX7gMBts-92IVdRLN{4f9M)1R^_M_kn_%M7U+vB_Dt6d*<&DLdJmidd{9KFdZi(AvKRXu+F3YB_FwYqmq_0rLMf;m!FGuCocHs6t1 zqwCpkdwS35iLtF@pq>eTz&e8sQVcl`ZS{cetGvscmA z$}=I7|IKdtX6`Yw8^2zPYBU+!*QqCL$uZUJk&~6+@lC%RN9F0?a(doh=`F3k+p353%3k)1<6Hicewm$?o=(ol)S0l1 zGUX_cPA-mb`lY?gJ!zLS&T7eO4?e!>mvMdaYiWf}pWdTeZ8)}VC+fqGZ~79C8_e|P zD}8E4Sv_ew{-{=-n6LU_Yj!n%`*-U2^^uz@fzse3zjUJg6E`QNSrRchh&bP^h$p6fKH-6np8VV7=#AY28q&*ZO zepzEC>wMI`9E}NDTK4%%Cw$fWS$8_=vxB*muO7c#X_C7@VxNPPeg4cIA$p#{Y?YSh zH+=nQk#70O6L?za9o2d|c~Yy~o3osDCinlTHREbtMfUncTdZ7JlwSVw6Te!AC^K-@ z-)zRef|%7xg68S@N*U#+>Z@iqefqE5&2IZpM=WcNwOpm0&HR6Y{aade^i`bMj9+?b z>ue;pZ;QPv^7yphnZ4`m){hl`;_LS_=YM4clzIOl&&rXWLhdz|b8_?ArW_T_>kaDu zEGsQmtyom3_G6|m-uj13(paeUZQwYdU#T(A_GD&B?je!6!a~L`vqRBWie@{0Gd}54 zR??Q_9xnZ_kom8p<;rz2H4c{*Dl=12nD|vszLfo@i9D;jh1QW4^Zo*BpDAqoa;4DB zzd4&3yNafe@tggXy0)f|y=In$-ZtcQVbbTKEpDMTNSl!QQFn~Q>(>eszm$xuQjt|# zvPviZNYX67wQ<^wSyqKgpZvb4`HKV6j#XbTPoR}{By(+M{mtB`%(NA*{$z|Ky-NIY z%VeBcnDR@WKC51HZQtrTq+H|O#4%o;4QQVE%G0e<_dbP;KT#j3_XE+bWhUoVKW6#F z9|Os~cG6awrbjyZl{=M|LdRdj9<_<{$wYsJj$hSMqS*7*K2}VxCQ!c)8r^qT$H7D? z$WQ*ImanJ3P~%{kEtEB%@_)Rm{IcD=gDz3J%=hz?KC>01x6hh!ix)cnRC{ZF;#aLu z#;Y<`k|#cxqm@)8GW+qTDv{{g$yfa(E}vBAI{7IdnWahhh*F6BCyGCHUF0YKYW@2r z+UBO|kx=97R~Ke0ep$Pn&Cxwy?QdrM`8m3$lRoLY)#%eR-8;z0&+MJ$7p>JV+ey!% zYC}FND+{mWd-4tI7hK|91xVdKlE-hRBsOk!#V7g5SnVf;j6c=fs-z&-_|50#AFuo; zi+?urFKtWzRg~F`e`af!t8nH~H1Rkq*ZPmGcQvw-D>^dkpngeIu6fFNN&MC1g^m9T z;+AXdYo|whH}HR^YmD=sK3St8J(`+dm40gla}nk|gx*KZM*Pw9AhQ?0)QS4dW7%(R zOxQwV#}oRi{Fjf}qo|bwG7?>z)Ai%z$B)?kM;$k!p9CXkC^Gln5@+r*AN_Z#_*3;^ zxt4z&=e`>$;cLld?7f}lev$EbHCr?C_nGp~FtfREl=Q{cX^Dn*c%N>@{ z>*mey;vGNZ#h>W=l1DWMDPv1%Y3h20T!&MCxuwr6L#wYb^KE**!M6i(l6N%J^LN*4XP3 zW{kOoFGsfMs}Hf|D{+^f^6v)u9*KYr=6rOjMNn~|O+ z{*xi{(LUrJ2H6vDPS`S2*6WiQdwl)HmeUS(5*yPQMje^7v)sm&u*2>D6y^Zj#4;1tl$W!_nWE zjr>Q)C-=|DvxU{sOXefhy_7PZh~LU{FaN~xr*k)CA>*I9j&o*P%su`(%2u99A>#(~ zXew>dS_w2WR_mSFh(B37n2q=oojXe@q>f+jZ{m%pqVM{ST`^pU@T2$Y%)>X^NOYPL zx0gbMpR7GtEmKh;;!oBda*sdun6DqN%rQv1BgM?~pH2MHD;8r*V7B5{Z9> z)^Wb$mzj9Embseal#HBL@+#iCDzg*{9e=8Gu~hNP`J(jy@-zeMxv6SoD|u^V`xX@2 zE19`V-T$Q@e!SJMnTBtr*!)GY*s;2mZj&-AA1jUN&F*HJetC|TtcFr^R&u@kD#~82 zrpWv8{xVB{?7nUGqugcxFrQB? zb3}5cuGaF)e6}17Qs0LcukJEWpEWzB)=#LX=gaf5)fwu{SklRV%XBM~^CQ)7=JWWf z=A)z)Tj3`jEo77a==nagMO)#d&VTIptrn}o$n5*EEk;7f<@?cX%*s(LE8h8Rw&|~@9%ZDbx7U27KRSH# zs3}i)QZty=`Y1g<{dK1KGkY)@$$043TX=4u)n@h3Gp~O$e09fr>KL+3|7vPnMvroR zMLn58U6IyvlWF);E|*g4GE*i;<#gkjS#s)~Y~r6;YL`#XoNbI#SDA*Ns9qAqkZJgt zmRBLdPn4HrB6=x8EvWKkAAABx>lTcwtQv|GYQ}9yUjUqnMKd!`_;_tUh(=2 z_{=LYGt(yTWDJUfY%sW`5t=->lUIGk;rLjuXk|Wz3Z38ovI#Ofy{5^BaCT zS0v1sm8TPb?D15dJgsISB!o=AFZHR;Mde&*!}J)2tSinSeW=_ zMpD*Im}hM=s#Gh*thSckEPZb2OSb2z7L;4~R=yIo*5u)*NP1Cg?cPCh9(Q1#J`Lq&qud+OU@yotuu4J_4O0x@J9ZAhqw9BW@ z#H^mpN`0#SF-C(y$ZVUs+G4Jd&E@;%wK*A^$#0y;o6E~3{3}SYj1goOO4gXFqp5mgRJ!BP zT;ey6y4KMs)AEmAGbh)2WCUy0LwZ*rlc(QWohSX0lz*n@kjcZ3PV<$7e#4BF{ONx` zUh7D;|3t?x-=A4#nZ++FXJ&>mvsSHll7}C?@5aB9pZxoBr$Xy=y{Waz`nir=N0xjy z(O>5pzO==Sgcf}+mCx|4yu?qbRi@FDs(hqxF~?bYYmjhq`F=VrA(!x_50AYXADwf> znS>wR+VXRJP`!oBXkCw*r`PUpjM>LiJq0*<`X!Yz(=Q{9c(s?R{*rw^o!ZMJ{OB=@ zjPb3$H98g1pOTe;a%{bheo^jFk+WH;@#w$w%O^Tyi9b=S(V^#(zeM3L<#;RCk>lTQ z7#n+G;#bdjCk~CI9))tQHCvzuM38AHKO?Na?2D2l5}k%<;&* zzt$Q^eV>bdUFi5z^#+BGKh-%#;p5*(eOT)Sq;*6e(+eHHwYT3iJrhNlG0N)JL!wQODy@3;`pS` zT2ZgAjb?IelN1-aep9uyLd37eLYwKelbsnBs{LfvV)CE=R3#qUPLs#4UxAo8vzh$+ z<`smi8Rf_^Gt=w$=B$2fnxkJOkKg=${O5G4(XzU#B2QG`6mwThdUuf&Dt;LgrnAy0 zz4*;>i@Mt=KHIs}NtniW9WpOmlpo1&>lO!iuJcxNE7#I;WL0Z=>qD&Z!OY{B8aK>* zU*9XE%P=4LQ{l_6+Q|rT6RT^j(co;fk7VPJeB@8Um$Mg{2}@R%@$#CF_~ooi)|W=t zn;BO=!oTeG{7K&Ad1=w{G^V7e{9VzA$xC)Vexo=D6pyeqM&GarZ#%P^xv#F1U zxs{)sfhGUTJbXEGvYw|Zd6VlJ={_GWRsS!)yCl8vGFt0aNRBGAcl=gYYbAe$IX{%T zmpw7r9ur$%nbnValJ-VQ&02ww?Cdbp{YUOFm9rzMAsH>s3_I~iH8x-7tIYDZl6q0= zw4}XRbI0-WonA^Zk6+g5%JXLupYxb`6VELCbY~5$7%~fA*6`gry-%guZ_OAo4c{7R zq_@{*7QX!En)>ZXssBsam&|ee%$BHfkXiV$23B&A-rSJHkXiV$c3*NJy_&RSIRnYO z&ds{XJbt;lqMj)xBPBT-iyrIBR@uANnOW+&kIdtjk%-is9B^RWkJAODBa>S1yT|M=#wyde40NAsDMkM;dRjK8AyIr+sO zIlpOSkC73t{EDo3A6q`=_ascYVx)e}N8KGK$8L#J?K$aOhfG|4X85vNUamSw*lI+e z<^yiwmCBnOm#wvR>91`|etcH(o7YydjU!e5)OAfcs>_^8rvKCxWR zc+}HiRV*q#wL)?k<*S}Op?;Amld?>mKWPtg)i`lGNp=l0-SDMttC>-m$&(SPoC}#x z!m{RM&2fwA>4z_KEOOmDcE%vx@2fLsSzl+}shUpvlYB|}Np7UI%Pf_m^zxW)`l3H) zmQ5z7yUiCE5w@rFx#)nfAr_l=~v8nqraDK_!pD*TS>k2JgNS& z317~lq-Cmk4w)5H=Nj?yl}-4oX(MtyXDdE)MNe#wQiZ>gRwsS?%=X*J+69>hQrkDO zhszwHzAvW^-`q=A5SIB=PV2d#l_|!Rr#n9hdhVayhl);L@e{&a`v41 zSez>S=&!God+P9G(GhRyGxLAr^m8Ai=TapgeX-PwjA@hq z<(~g~;xwOft4cb01#qf%T{Hts(Xr+*0x{?M!-k852o8n16)|-!)y+ zauuaH=`%mFi{EO0>ReLJx6~COX@xT8mZvkykyv^=>u7A|+Vbq;Pjyt!HGFH-Vuci+ zvP-{|TI}8!KlIG|Kh^$bhOg>LTA?~~HP6HHmHyS#w3@?+%}I9QucmaYqmVh4lXvxd z-0~5=j9C&Lm8 z$!{CWu_p0IHM{)D+^=UkZ1cz_d5hPQQire3psypHa#gZ%`iiKW$H~!@iC^dfBrJH`436s5}p7Z*({F4!xlvVV~R%=8kp;~{b({GJcq&BQqDva#E zuSN_qU#e;~deoYI`l7F}$X;u;SLrop{<3xI^sgoiIlGjzI`dc}y+WcV4q9m!$~}BJ zK1#Z!A5yD!)UV(qZZpv-$Z!0apKIqgeskQJ{;?px@yoGTMxnAEI9ab?)j;m?t2USD zY$spgt9gp%>FYppeMwe)rjx_m5L%K ziQl}-vyN8g;a~C`#g=jE@UsckiX(pbmrd^zH%!mb$cj00-;fz>d3K28L*A1yYNF4| zm5?obD*0dL@ym(3XAWq-eQdVFA|B$xOTmC~~5{F+xhthn^LmDicaAKg;T zD;jd$Uq(C|6Yj0Gq-hiRm!pt;&iui1=l^ zDn~P!hnHs@B>O9T{IT;Dsmeo7Ya!C7??ZZ=(XR_1fAZcqU-3tenRClus*!qh=-C`U zQiUJep0ZniBUc&J3S2oOlo>+l0o5~LrB}38FUK$c*za4fX3jOH^L<(KEXNXg#*A7~ zYn5Sk-@k$!$y#%@b|w0HoE5U7_~FY~e=TFw=sm?cSCjtDysj9#@>AlCy#|tP_${PB zt@Bj(e3&V^VtTc7>>7GKPtmWli(h8J)7s=+G0jZ}YQ>$}d^?YSvTkG*GKW zWp*p^u{rL%xXCQ`Iqr)3uV7{`dJ`}N3OZ-KgsG}j*!v|Y?^*1 z(#F5dxyPTa%qIVG-K5B8}=lqW8q; zI?X13(qGT)>Ef4Rw&9z5P^x&c3EvD`o(~|`FVt1f*k7DCXZ`f>Wi{+|95ZXC`*{x( z{i`f;G&Q%#Jou*9LzgR9)^9M$=vVqQsfX;tm#6lrnI!W%k-BOgTMyZXFD1Y6^;Is* znX6JG>J6_yRYTVCTh|@rx@{(R%~@$ooxU2vmMaR9n&|Si@-HJ6xk6{&9kG@=u)bqG z1tgvGRV!tRa!H@u1)|Q6)x99`Q>Dik`?~P)Coh#;;+OM3>0Pbafy?Q4Wn?2;(kqSG zjz4*6#MX_x$~ApzMqi#6BYlw?bEH=?DlM}YfBcduMEnwF3v=Y3px2Q-NM7BVW_!_V z=y<0ueyLfh%vbuOEHM>+I`qX8hUI+wqD&RlS&{lw10w70b9Ve$AwlhV0{) zyYXet(>jjDPlcJ&_?~_IY8FFQNyzy_qPX)FzRU@IhO$l+PyF2FGJc88U-I}9*L3#z zk3DCP&UfP2W|l&3@o(aMP|gKqo+P^zWFLRLdB)7oz-BZ4OzOp~sdUmOS1jaLGd8ma zs97+HN!`^X|0nxPKYVp>g&HkdA!hRZn@N=#Z|C~`^h+|k^d*{YwbE@;`r)hVq#IZ% zxRH^zti8UT@=)uq6W3Sz;mh&ZJl>e8ORs-Z?dMY3kBq_9uPDkrM~PFFpYY8RF<1V@ zi!c5B$M%O(8rC&YE4?~p7JhVpmtG9%hkpenE@xzN)Q(pYddk)7Ov6_*RD}rN>W}4^ zAnnIICT^U*E^N+e#O5PW`qe!B3c`_D@#rfavEMJ<|8VPbQ(wCHOJ{!l+RCSo{rx>7 zcVDyg;_>RipA24J^T`d! zXmIBZcYXZnQ)(`IbnVY>-TL@d&z}|>yrFMDJ;nB7ZTp>1mHcGgzU|8%+Gs8PSU;XGe9-O%8ysK&sPHp=0s;SDF{xzlFyXU9>{Mut5DZk(|Up#N+lf|2U z_t& zV(*@jXaB9@o~Qr#!l^$y|DzwP-LqrQZ(qCbFBgArZu2+(`as>v!E@HFJGc7dH#|D- zEBil3c3%FSimMKM_ODle>lsH%Qfyz4V*8>L+uxC5yPkhNeeX>1eLa7A`RU>7+fUZQ*SDXNVtc;Z_aAqj_T~Eb z|M#-a;H9P4op0jUN(m%gY`@9~X-hMB?rS`kO zIOXutuiyUr{|vRRzge#zeY^fzuWx<3UZ47Qo0eXE`GA9RjlNy)PxS5YN)f+3#rAin*#4dr z+fPlgUEja;^y|k{eY<`<)wlm$ium7{V*44|cD+A%Z;I__Yuk4otaxk9vdzoxyynWg z53l;eU-b5+Z`aFD->#RR-XH1T*SG7h_4Mf5_5Mch-}Um*_g{Uxo_>A1UjKUkulMiz zcD=vV!`IudzTK|XpT1q+zx3_;{-dW)|GeH__2Z*{ywkVq#~;1^Qk91u{%_ib4-Jm} z?&9{3Ts~2^{X>uF<*jemU#ALBPp@7c`s>9h>O&7t-(U3OmA+j+Ug_KQCr!*s($q2xgMT=ywJDn<1M}a)bpe7zk2;uKD2A}-Q|y0-F?y54?o^q`)z%H z)8p62gL?k;^y%C6{X^fb?_c`%QmsDp?fQ6A->&a}`gXni_3f$h|2{2!dim<*nJT?A z_9tyVLEqo?^y=eFz5VO^qu!oUwTD#O_4cUeUq2q`=TCb0`teHtzMg+QfBJU4zti^@ zJ$}9X^zzrsPv774?Rx$G?7TO%{(5Tp<$L$;zWu6i4g6Er)t|n-=8OlH_xNvmw&B5l zJG1xY(D@z4FPC<_*tDtQ^vdmyo5~v(ca&f9!&fg~T~*ewSbwdjU*E3R&x4UQ@BKgR zAG_4|tEZN|^E~^Cx4QrBN252oSA47d)ZA6J#yXee!cdl$rU{xKF~4v-5-|g>C?Zjzt)eB`gZ;Jrf=8Bi~4qb|JS$c#}j?K zetgom>-~qmUGM+&?RtCBx9i6reY?It=-c)7s&CiNm-X%X`Le!U?|=2}`td>EuJ@Pv zc71=;x9ja)Z;$$G{quTwdi(8o@1;TKrl)EjeCJ0OJo}ZGkL)ga`iVWSK5|L#d#`!L zJuq_0r_cEFQ_uZoOYKnT!gKGx{kE@99^CV@zf|sDx^3CWf4%1y*WC1-Ki>Au$M>DG z{K2{V7ysz{^WJyQy$|1c``j|;k7~d5!qew1{K)<@|JeP|KU}eNd)IUSviQM!?)vJ- zPJi$R+g@97&!rD`&i$W_zj{~27kZZ3PQUo>hR+__eEx;SyT05|xBR;+R^0j3XTJDv zcMiO|@XsH3rsTcBmHvV6RsL7`wf?7HJ+s&KY-r_IuG?LD`smK)V8hxow?62&wEe~U zXP*3U%@6+W=X-AX_mWGO-uLjYOOKrXtDAoQ&9STfXa4gg4}a_ZOCJ699Sh(0@} z_k-Uq-g)*LH&%c1w-31QdQ06Cuh>5D?#JifvizateYZMyJoVT2E%CkauGj8c)%~lF zJ^LTd_iS(a(Z+@^{IGu6gQxHK$0tAPJZ;|_|1$T5=Z~$p|Iusy=_|j!@8k=&zVeNe z@4IyQcTTN1c6E>O!_T>0|NiOTpDp{!UnZ`-W#O`O=A8HVQwz`9QoZ}__pd71KC=0H z&py}rUz?m4_no@&+h6_O-+i&XW8SgVue7hYW6>Xuy}EL3*&Ubv-w%H6o*&iR9lmDk z*B701)zzP_IrSTxpIY|AOa5`?V8flu&-?L`AFuw_!WH*z?s#RvYqp>M?gjhmTR-Ti z`lj#Xb2gk?{vS{8xcU2=xAtAq^}GH%J0I9^aKjn%AOHOwjmrj4|L*!vp1r>4&u?3~ zciT(1tZc8k`R0ZVAAIrS_q}86!hN5w-T7DdXYbv$=$F6Pe#3Luec~g|AC%Ot`QDC0 ztCl=pan_e#eqq@+fBtA_=OYK-_oZF6f7p7#pDy3!zUPHYYDzz~>f7gk^yeElEPvp+ z%1>_d{I26OC%yk`>)!C$%lF=W#mC=b|KNYL-}dQKA3bA5)mLsBJmZ4XZ>&A5eBliz z*ZunPt`EHD;%9&Vk?@<(YHQf#`2O%rGxjqbjn+v|5)q(=k9y3{>Q6V_3e3E z!!2*v_`z4cazWL<&$;`uZ(Vcm$~(?G|CzFX+YtQy7r(OnYp>pJ|Ke+(-21M|(HjR& zw=KWziC_KruGK&4dgH{u{PYd$u3i4Ek8K-zx^u((7C2rk*?02iFTd?O_qGiFLr>{{ z-tnaE^8fpXr8~Cm{(R$wyMJAAam~|%mtV1R$KG8V?t1vo@2pdUTtpZ$Xu zoPWXj4sHB(V*82mInh2&>>nrkhZFtdiQ~hGz;66nR1SOad(aZtk3Wu_Z~(7o zfk%~m9{&Q1|7&3{-h*tm%LM0R-}--F8FApVYzQkSqD{{(WvZv3mL3ijdUm9!<;iQoG%$^`b~ z!H?56VDaCfb~u7pI}M`~cHy5#U9cDb1KJ^2> zMRX7jAM`YKGl-Bl5r={IjS9_Tsmp zEwB%N7`4Fx{L~uS5^TduP$z81-;I2*1OE`}f}QxqXb0@VKY@B+H@+VEVGn+2C1nmr z@Ym1~Y^!GK7+sM2Fgd?$In5#VF$h%^}}xb z4>!?1;Rt>d?T5KB*Lc7~S;2n%vd>aJunWInBW)6P;`gE>@)>-~CcY1Q@o%8HSMol7 zatp@^*oJ%1d|3QBv=9#C7i^|XU?<*;%H=b77g_@Q@ex!BhwvlF3G)z4S{!6E$n_fmIo5dZ#tv~6MhOI`FEun*t%0LOG;{NZlu z3l8AB9;Cj6@!KAvj^s1=*w;87!D0MQJ(NFee4Tv_d4#{g@d&jDf739Q`Dyd83t#;( zWe&UXr90_EkVj$s zszKTq?8Ymqd_num0)WQM$H>VXD>);69 zae9%_0{ifO)Fz+77Zev6?XVrc6LrdG4pRNspl3M5!i;0peZVDYbifqV($zeQbe z1i#B$Wc0v3{O&u*qcDE=o#as%zyC|*5%%M|I>{p(!1sKWJi3fTe5FEmvzrV;h z2#4|C?jVnF1b^jgMaE&+=qWNz`X>2>ZFtGfBI77*$3L*E$S^)h`QR7sE;8o9PJG4V z)HUqFulzQ32D|aK-z_rium}GMS`3Hqb$f~ohrEv;Mm2B*k9@Dla0%l@gGGiLw&ADz zvB+o?#t*z)WHiHJd!Xg=)0JJCYehYz7e za1ehUIp8op|5e%&Y{#om4eY|3Q622Tx1k2uhwnm-Z~z}g&2Sih$7GSQ1-9drXglo0 z8;}on<85dM?8SSKANJ!xLza2PNC3;P;u!zo>2`;ZR~ z;ZvvwX2f8;2knL(_+Qb0yk9iOXh0*d8*f8l*o*g~!*Bq94jqBRc=4P$hVg0gh*zRw z*oj|<7Qi0-UbG1I<9m<;4&sN=5;%gN_J%n|6>P)LMYXU4Uxn&m7rq`fz#jZA)Cl|V z$51mIz@I@aa0q`1wZRd*c3pxmU@kh`hIDj8O5jc#WeDWM)3bx^uXrB9Q!-+Sd`LGAyiR^Fye-1g|Fn-!8 zdJMdam1H16G$OU`wZDHEzxj={8Q6|5L-Vd9o%nh*ANJt)qJ^*@e-bT*gZLP7 zz+wCtS^^tqP=?3}JMcPG3%l`7vz{gNC9LA^67MPvfSctr^9j`*$VHe(v zx?m69i+bPyehBr$5xn?KbBrO_hF79}uoG`UA=r(#p@Xm&??GYMkMBW;;UGSSB5)XA z^Jdx`?8dv0?Rq|sk03i7!jGUb*mw($mcS0Y4pqT!yc4-#AO2sc0gm7c=g%?L!FIe3 zwaDl3HWBQ_dr&*<$A?fS9K>HhU2qt$Jd@ACPP_pHU^l)M?S;Mg{U`|g@jYli9K^>^ z2oB@LZ>4--8(xME!4A9@O~5X^86AN=cqf{IefVQ&ZX@-AKZAjScrU7i1Nb3S3rFzc1>_U9;pM0icH*Bw9@v9#Lv64Re+;$5 z0sH{!gv0pBZ)1OiZFm{#g&lY;>W5vp2MxgD+fWep;g6yHZ~zaZ5G?-YvnW&8j;}(8 zVHfU2M_}<@WUS@8_yJT5hw-^@=eP#ja3@*>i#H+%?7{u05*FWwYTyul1l7UDLcWLG zumi6}&9F-xwZI;{6ScuUydSm00elQ~!ePAl9h47j!#$`M7T<>U!ajT-3c?|L?mH<5 z`8<9$3d0V31v(77@HP~Iy?8&Gf&=&%n)eyv#a}`5VdGu&foLIY$1Bky*oilwGT4pp zMdff1KZI)F2)@uxnZS0u61ia~el=PLyYbD)1AFoN(H7W`4!Y+J03d0`!A#@n_<9pB%IEWuYQ*Z=dSW20!qfGFN(0tg5 zH=>2G2Y&!9hW+?HR1Sym2y(*W#fvE)*oI$(>R>0{fZVVf-;CD5Ui^OKf&KU%v;_|0 zzd>F&f-ig@Z3VXDm1qa-#2b(wcH^7TZrF=IgaWW1A3=NJ5dK@V502m`oy#`ZhL@uQ zuoG`UVc3n|jt;{kofiUskqIqxxFFudsAZ)|S&;r{AsiV4&f8X2}khL$|)<@hM$dGumfL#*1#@&Epo#iyc4a1efSf|0|)Uj)CPy~ zW2hZAF64NGI$=A05$b}S_d+@u^ZrF$KLIF5{KaKXnA^f)}2uJX9fd>k9x|E<6F;efeHOOiWyl6Q@H(^rcH>=W5$wkg zpmI2j&tJl^0Jh_GBKbVtg&O7a_yN=+pT~o# zD`_XN9j_I^E_@?e1AFlv)Cl|WA=C^9@k6Kuj^M=~W1oU;crV%x2XM#Vv+uy-jc70I z!Jk0;;UGSS4#Hu4?#JneVH^HoGyyyDMsyVR;18g=H<2EE1liyaKF7&E4BPMzqs6cj z{|qXJJ@^C23H$MVs1^?4uc9@uv6N#pYJ{EmXOIW>;5$(p9Kin-ZHL47$;)U5unqq( z^21KN1@*&TaWn)6@B?T+9L9^6^BT6{`n!yl@cz z4eEp=_?s`L&xGxGCF+HpcmwK(-FO=sfW3GR8iM`!2-*jS@F^66jcW3R#$X3tiw?ss zybVQQFW!%)-~c{?=6MK5-a|Ins39D*5O&}VXff=@??UCU4}T0f;Q;;&s)0lJOUMOB z@Y7b(PGB2;E^@;Tyb-N~J$Mh=0{ihH)D8#nG1Li%@wuyLGq4RWM}F9eH=usljklu# z*oP0HARNTU&;G13U3XbQt#FUFZnx$DcyRXUPlxGAf3R+BwF1(E`|kUx60E zZu}19fPHvBs)Pgh2&#fZ_ynqjBY5$p^oOtwFGCHm1FuDmunTV%!5+L5wZJ}n7ixn8 z_;aWo4&!q!qtAqGcsc5Uop=M<4ZHD96o7qrKN^Aq_z2nuhwuq`4M*?`E~l(uC%zXQ zf`j-GGzA+j(vONal774nEr8v4Ct3vi@B!q2gZKohgd_6aCulRUcmrAkyYahFBkaTb zkp~Xo2hbKcjL%t3-eDWQ8u?&1-iQ41d3+27KeEFCd;~3qL-^b)$un%jyO0z1;|I_h zIE>G|iv2=9gI|DJU?<*)ys!tq4|T$R`~cbkhw(G(scYDdUx)U}=kYGIUp|kA(E<59 zUc81ng>85_ioj010ZqYfybaB5p?vViP%#|9{~IlUBlw&Dfjq)?{6bU?JMr65CG5kW zLbY%RpF$0=aW(A+t%DtS9cqEycsugKK71GIgah~(>Vm`gMW3XuVJGfI1F-lo+6Ra5 zlN!h`Y{SdYA=rU8q6yf8ccCfRk3Wg#ZKkc_W5@=F@ndKKY+N(P_nfxY?T15n1chMn(;BH8*oK#(L$Cv{LldwYZ$n36FW!TUR`Q7NLG$1sK89>?7=HyV zfQ_~6*T@dr@e9#n*oikF2kgeTq9w2w??F!3k3WfO;2{12a=~Hz7+M1xpP??08@A&Y zqIIwnZ$KW{jc-O|_UcrBWMU3fD(0()6D)0+wcp} zA=rsuha#{CzZXrxe*76U?^enmKZfSR#s*hst0#-iDUIUc3i6VLv{EYTzI~ zhFowMpF(S3<0d)hpuNF%yb`U0o%of=1H19fXbbGcdyp6Q<4>aPa1eh1`QR{q4DEo8 zo7rEGAGYIFXgBP_ThIXP#d}Z?_TxinKODrzPzVm=b3BwGY{Nf}4#7_RY7~LpcpEwj zd-0u!iAf`X{|XhuVf+|c02`kr@5m0@@e9#n*oj|_9IzX2LrY*U-h-U5A0I+Ba1eh1 zx!^E<46T8UjqJV=I~!bknE9lsC_z)t*1Gz7cx z&1fI&#qUQWupb{n2jC$70vdzE_$%lTY;2)S&;)G9FGNRRCw?`Wg5CILG`EfL@t>e# zI3(}gN*jf3c$o-x;JZ;d9Kc6VjeH)rZKWN`=Wz#e%jfY`s2O(Q>ro5r!MC9{*oTKu zJ1ibSU9k9RpQF9OHoP3|hMoA8XaIKOo6!*L#e2{`*pEMnM&Ka+JURe}@hLP08*TJy z=n(9{8&CvxC^8(xC8!*;wBb;1t30{LJkUX8k77haEc zz;3(=^}rsy75QN=-hp~yAKs02!+yLE^}_*t5Cz~MK8yz75I&0b!eM+I4Z#t75(Qyn z8|g>;U>jb7_QQ6(6pg?RyaI(_Cti&Xz%INV9faL@6B>g(cq5It=^q zJ~ROb@Ie%TgZMBy0*CNXbQBKb<7f(w;FHMsBI&=A^rN}34R@eQG4eY^NQ3LG7JCGap;oYba z_TznM9UQ<1Q8OIGhmi*k;iISp4&&o!3mm~GQ5$S*C;i9^+wc<94%_ikv>kTf6{r(- z;?>9pyYPC{1-tPkv;+3wt*8g~;vL8j`|xhm3;Xdtv>OiKgQy=4;=?EahwxD}0Eh8$ zv=@%xlV}JwzC`*_5VqkZXdi6HKZf?hPP`h0U>9DG4!~}_2_1wzcqI2k~JPfkXHxIs%9BadZ@p;HTV0n}=<937YFAop>pl2RrZzR17=u zdSrv$coSLxd+=7Y5cc97$PWAPZnOyY<9%o`9KZ)r863oikpm9lqo^DXQG4eY^NQ3LG7JCGap;oYba z_TznM9UQ<1Q8OIGhmi*k;iISp4&&o!3mm~GQ5$S@l78fcZFmW4hwXSN+73JL3e*WZ z@oMCQU3fj}g57u%+5vm;R@4J~@ebsNeRwzOh5dLR+6@QrLDUZi@nIBzL-;5ffW!DW z+6zbUNi+l-cawe;gl%{U+6UY5QnVj-;1y^DcH;FY1iSH8bP)F9-#}s5j}M~5a1b9x z5jcd8q9bq^A4f;w2tJ9XVB;&K2N}1K9=rt2h3$ALng=`Z3RDa`@oHp)U3fj354-Uu zv;g+tt!N?a#XFE4_Tk-V5$wnN&|)}%527+Shz}zN9KuIYIUL5v(Goansn_&C}NNAO8B z1RM8|eiVdlcnR7E+woGgA9mmsXasiR)hGnJ@OpFrcH>RxAnd_g(HQK-J5U(*;oayE z?8p1iVK{&fq6s*N52FYi!bi~&IE;^@qi_VDL{l&e!i`gqaXab9OVC`{j+df&umi6^ z#jq2vMmE@m*Q5Ec8*f4jU=QAk7Q$Y<1KD98-i;Q)e!LGYh6DH@DuaXgFmk{ld=!<# zVSF4dfg|{w`)L2L4L=V#VFzA;s$eHxjcQ;QUXN;FH{OI?um^8Nb+8xjKx<$h-i;by zKi-GjZ~z}fjc^bjM(f}ZK8l**Fg}hva0H)3EwIr=IioGG4KG1$upKW&Uf6+Gpmx}a zSEKE)3$I6=up4heKG=h|qAu8r--~v@e!LI$zybV8Rf;=||=9KuJ@VK|Kc8BM^(1Ed*6U>jb7j=*-j6di>fcm%<@g_76_Ta6k81~{F$OilHZZseE<9%oW9KZ+BLO6&IBRd?zN6{iUjE|$m za0H)3Ww6mr`jG>+;U%aXw&SH}3GBctP$lfdtC16S;q|BrcH>Q`2KL~ss229(9moay z@NQHG`|&=s1`gnZr~wY*!^jPX@KMwVhw*W=4vyfHs2MhPFmHf7unj*8wZL}#T(kvt z;1#G1cH-5@3%l@o)DFAxCbS*);H{_=_TnAL2mA1D)CK$TKC}Z4;De|K4&uYe4~Otk z)C-64akLwb;FG8yHXfw>Q2@5#C1?P)ycHG0Uc3X@U?1L%=EHux4=sQL_#j#c z2k~KKheP-%S_FsjakLnY;FG8fHoivskps5jC8!*>R@jkQ$4&Z~R0S@BB$PI_^QPc>B@o}^cj^LB188&)I zKk~pfyacttcDxjAfgN}SYJ;74HS)qPydJf~ZoCO?hdp>J>V&;`2lBx_yc>1Fe!LIu zfCKm->Vbp!F!IA8d=&MW7W5lYSI{ZFmV9fbDoG+6z1I3N!>e@oE%= zU3fj(2fOhmv>*21t!M=H;vFai`|xgb0QTcgpo4G_A4X$v2!8>E;V?dq4#5$85*>z( zZ;)m*0o(8r6oKt{DLMi>@CtMkcH-4&3U=Z3$k;}j@g_7E_Ta5(9_+RHoOEmU^`xl%3%jyftJ8d zyc$))F1#K&VK?4{s$dV^ifUjl-hpaiAKr~zupjS3b#MS5L~Gz6K8zaR5I&0Ba2Ov) zjc^2?MC)K~CNxe#&9DtGK_1wSm!cNffmfg{uoJIFZLkZkM_$;CH=%aegSVpXuov$@ zov;t@Mn2e&_n|I0fDfV_a1b9xJ#YvgMSeJpkE32Vf={B|u<&Up zd=!P@Fg}hB!4Z5C9fpmaq#sSdHoOEyU^`xlj=&DQ0v&~&cr}`WU3fh*?j-$q6PgQq z@K!Vr_Tn9=81~`a$OilIJ~ST=;DcxZ9K?swLO6tvB0C($$I&7tLgo^rL3jhL<1@Y{yGc3+%uv&=%N52GG9gpVRW9LC2{FC4)q(Qeq- zMfy=cY{N@X0Jh_$XaIKL6=*N)#H-N|?856&5O(8DXdmpsThV^li+7+A*oSwc5bVeM z&;dAr52Ax`5FbWka0nkoVK|JBqeE~6pG1dY;}O!2CSV(0f+DaTFGWXS2VQ}W!cM#z zO~Ed_9vK~^A8$f)VGrJl=D}XP0~NzQyc^kIKi-Gt!vTB{Er5ggFj@$Q@KI!k!}vH_ z1V`{mv=}z}NIxorZFmWCz;?V8mBS9a0xf}^cr~hoU3fim!fw0?Rly#-71h9AyaUz3 zKD-;bU_ai6>fiuAh}OVCd>A#rA$%0M;V?dq8sP{&iPpi!ZqkpMVH;k8Jg^-vMJ=!c zuRvR1Cti)(U>9DGys#T@LhY~zZ$;Z-FW!MVVISU&e6SzyLtStHA4EIgAU=$G;1E8F z{BRf_N4;(LbK#+#6_o%G|aXfEufY;V?dq>~I91M2leKang?#!#2DGmBDtr6gglAUV+MCCw>`P0=w`}p-R||Hz6nN z!CO%k?8Q4!4eZ0aQ7!Dp`;ZF`;De|R4&uXT4IIKpQ3D*t$B`S3;FG8kHu_0FS_j+k z64VUa@lxc09e4$5ft`3Y+5)@qdejEH@h0SjJ$Nf>hrM_Q+7A2hZqy0;@jm2(1Nb27 zf`j-l+5v~~QPcy6@p0sbBlslhg^h2KezY65;U%aaw&SHJ06XvsGypsCYP1)2;q_<; zcH>Pb2z&7VN74PqTRk5R9DnQn=-#?NPThMeWDcUFZO25h%s~`u97K)SK@3_;Zxq7WM9mrpQL}ImLfZ~PEF2Ss#z7Pd-{<>}*W>l-<9*NlynlSoMMq{}rOxx! zSfvX*536;N7onm{ybNn}nV-d4UE$ZTPFHyYs=CHouwI9I-9I+!1oy`#o#er&=@gH^ zW}W6S*s3!;0o!zzryyM8{&@!Kb)K(AlP>T)wCEx)LPD2#89H^DpTz)O;ny%wS9t@H zy2e{DNQe8}KZfW8_s1}u?L$@yS11RV+Ka07#!vDd1UE^=DK!^K#gfuv(Y-SyXg| zU&9(*)o{tvbguuubRr zYJ_XuKhHzGF7hHY=@KtPi!SrCNazZ`hE84O4H%$nyafYwc+mYLsT15EgLIMyV~9@i z2n^F{9)pz5@B|FkS)PKCI>$3GO6U1%q;-MkVYDvtB8=4~UWReH%+DgDEBqS9>nd-+ zL|x-8n54r}_m8YjaDPnJNgj-;I>jR}O{aMbayr8kFkNT)9L&@?o`G39&%Z-n7kD0K z>mo1099`mN=+KxC&Hl63I5w3IpJP-A{$cxaV zOS}v%y3Efap)33vI(3ydV1Tai77Wy3nLqyrNuA^o7^2fW1}UB42^g-kJOv|lj%Q$$ z&hyns>jKZiXkFw*7^_RX4C8c}pG8Jj_%)2zRsIkYb&a=Rk`Bw=7qU9VBQRB`c?_oM z3{OB#XL$;y>m1L(Or7VeF-sSC9`d@#i!fW4cp2vCGCzxMUE!5~bGBpi=UAx2Bi0a0 zbdnFnQk~)7Vudd7eOReWybh~%m0SMqjOhfA!aAMiX;`mwya1bYkym50uJ9|^rmH-7 zg>%wvefT~!=@K_T<_zcrpY^!C);a#B>^)6~CwvANBXyP=*V@N8p8xu~J<=t96O(k6 zcX`A6j85@>Z@E{U=GLk;)CvCgyVfd>=VRAGpVCr z!FXNeQ?{B{9K)?&IZHahiLafR*qr~L^Pr>e#sXd9mTlh0;uyXFi{ltBW2ue~-#8CC zx`35B`fF6;^>6(?)OX%zbc#R0R$b%W>gz(&?_KAYFj`kRG}MK$I(iv0y3ErW>%wH6 z)f|rU8w(qujT#FqSHJU37z2!2h@d5o#!`pstbd3m5)f)g^_U#zrL%liP!mv-Rr`n zc%6q1uJgGMbLTsT)P-5P$S-->=>N2mwa$VuI zSfQ)@9m+cFRTmDyN}b_rv04}SA*|75?m5iY>jeJ>Rh{Sm`+@b*MNX#b!e$-)6NG~G z;ZxA0vwS%cy1@5hfG+W8Nb0b+^}vugo>w5H%e)OEJ$$+s4k4x zNgkfIo^cG1#Y~;yiI}CcJnY~)pHK0%JmHYKFehH;{SS3cbei`ZT^AO_F?{l2b)gu? z@a~7#g~jnYZ$n9kF?C@FEZ0dMj1_SVe>2va$1z9Lg&+OYI_oq~8E0*Ej<5V#U0AOR zyatTqgZsKa8N;Qm;mlY9nBI>!%Uxi0e&r&&*(;rFph*Z9iQ>wNCU8uHl5);5me z+!@ZTjy~~hYpb)o(>b2y8+t>m|F7P7MbcyHvrY>yNMZWq{?`i*M3|ElQ(XU{DuJYE)>cT)B@^#@~S6H7o zhF`|mIEL3_oUZYA$i(r#_1YM(6Woc3I?01DNvC)MvO3GxV5%J{`+-j&DF&7x`(d(iMIW6cWq)PN(@+tk*^U5}V?ftLs7sHtQtM#5SGhcjj25xn7e`z1I5c9N&VZF7lTc zqQiA{;RK{~mLJ4OUFLq>&ZzpwMzC2Ph1#57&uqyFGb#_Rkj zX6Z6#3)WdjA8@^O)@h!519XvJMp0Ke_kY$_M^{mb*ZGLK)>dcuZj^P28*j9>I>Fzd zqQgzzujW}#UFE`jKZ|wrZK&xY--XS(#2c_x*Z40tTibY@k6GZo@kaO04YxVZI>Aq4 zkgo8RxBD5O3w+oeerD(lHx#{3#_`mr}2c3& z9M30|J*ROz--qeC#AiNX9dwTOc+#2CDSjVwb&c6w zj+d@--|;$6dd}Q+mXChkdC(bt>>u_$j^Xzz<~z^#;s@54uP$@*T6?M!e8@WQOFF}k zV`?13Bj2>II?Yqwa{oHV6W;fJqO<%YO1i=aZt(Lxj^`7wDvsf&u{w_7_pw&j_>B+j zqpouEht9B0@Dyy*Id1#N-pzNNM{F_|o#v-7NLP5bkL{gK@sk)8uk$ZH@$Bm?KaTOb z%m;mH?R1*=|ID)*o9831i`?ULXH_S71Lo=)|NRU5rOW&@mgoxKx5YZ>5`VkZbFITy z{(d0T`<$28;n~=z3w-Ey^`22{&X4w}58HH^FRZH%EjN3Pcx8Qk7@#YBc|&~|q6?gE ztPjI=^v*r&!)Tr4U7G5{c%9J7zAt zSE4>_(kWhot-8dw_Nfo`xAu&?i@lYBP@>JsnQQ6GlsG?y?cUgu<|^@-!TfN?sy zUzfFt*ZD3?j^lYozj~i9bN@W0e|?y#bG!+&b&Y>DpgwfRF+6Oo`A{s>89ok+ zb(Sy35?$cEceGYH>#7>cb!%-G*U0!F`a@N&XDOvfus8SWX0 zx%)8lk7Ic2;pV8rnELRWvG!Nz`HCa!!}2(W zFC6F0$Lsvu&+MI!ch@7dQi{`4gKrNgB9 za6U%sJb#Vx@%qWm^C|UVsxEQzG-p^x_d4A@>jXcBCA!R)P4>*{JdZoWJ?jkr6YF$^ z=bq_4bdmR)>U`=nFG17oz861)PF?1wF+f-N6%5o>eh*1qYK4bGY=h{0R&Z`eM zp6@+Q7x^oUi`Orx4?7{FlYAy7>KxyFq4TLr{4KI^{B+|nIgaN8F-@oWcudz>&SR#I zzAgS*7rBf%I{Hl%bd|rsd>t;T5B*WpNgjcPI?Y)u*3rK~N$2@mEY}6T1uJxs??G9Y z_z|qsWquy3bcNr*YF*_+XZV?-GkncV=Smm2c5!{!tfO`QlpE}3-=p0{mt!F^z`G#(D*F~Q6dta}!eBmG5a~#8` z6r7)Uogcm4`O#&bFxQ!n*LllLe%=+W=REhhz}e7wuHNRH>*#@ZxKEwrGmFl-&hZ6z zTI)ETZ^Lw5jK}h z%$bj4_;pN*W4PBN=BpF@*a~~3%e?ss`>n&1_2G$?&akdGyD{$>k5C4SvqW~52qs^$MYNL)>ZEK${cl) z|BfZP%*TFhzB7bAyVJAGcZLR^`}1sapB@cim`?I7 z^$lU9F7j864Pl%PJsU!EuZA#LC-|?4hA>N)_~yP1VR0PK-JK0#g)VTitHEdbye5Z! z4PmX0Zp0>?;PX+_dG5w$UEr6nRag16{=R;pHQ{{+G=wId=GzB0_za-$%e9>v!XOjIxMxFJl_IerAwb(tp*G2eKdA3=A# z&V%-B2y=CcFTnzx=SQ$Gj^VGdM2Ddb;kjWAVX3Zg=?4vArH;N}AM2y@eA5W)ql>)T zD09Ed>+{5e8o~gb<(n}?7x^g+(-r>hp$$GiXf9kH*APbO==4$MtD}cbXb4kvitA5p z@XxjOf{#T(XZf|$8p3>Cuv};Ppfi1Mo#ywZG=$Z< z#{Zhy5Z34l_dct^XAFH`J`o#rmY1NWOZ@Y*oridxYuKuzkNsss*cPwz8>qkAee!A3 z8bXWC@dFs3%Y4|m&Z5rnZaM3wQ~ba48^UlME@%i>&#*?iz^xZsYn|X5^VUii`5i3O zHQwoR_o|b8)fM(s7x=HgwWqqo_sn+wWAk@cHiUILT-D&e*^Z2luAS+-I&ctdo4#d}mRY`1soz!W^CD|K90-bdAR^be7_E?){*3)(P&vtifjn zy$*M+uqLtjkjFglI>Uc{-1pKYeiIXQmB&2c{KPT*>nA-UI?p#h)evUtBL8}&vlOrM zNl&{so#ppY&^6xU8PAJO@l}|w3;Zw^=rVtdVjRzhKWoi(hA+lqo#&ye%vYy)^z+VM z9K)w#mCo^;e>r=)z$0I32sTCyT&jxHa~)HUFMT| zG={l4%Ojc_eV)I!eba9!i$cWw-$be1!_G=}jy`lVeP!!%vx zD|T=6IY;ZynLQiB{5XbBAKK`%jpojK{jf2t&?!FRM~z`!9K#n5cmF!iOHjYW{qy>L z-KVbcw2|&r=Xl%!jbV_^@Vy7Sw>X|pJ;J@kF}(TcMxSA{ZkfiAKCUs$*3rjfzRq&; zgvPKyNB5rKK6Qfk!U~<@^HA0~J|C-eo?pXiUFA8jbVr`@pGp)hOu!BA3CKmOwt)X_Lq%e zy3TU#bdmLsWB7XyTIV>1zg_Ok=eqo!^AkAdz7uSPVf(r)hYfNChH9U6H|4CH$CAT>KcEJ zybez`hGm$o%lyPsjXoD?Ja1cRU*edjtwBUbH$3M|>IA>C+Ow^zJiFq&=>i|}qOaE( zJ{L_Td&HN&=GoB&UW6gK#0~2jeJ;{#^04=uC7t3sJ~A&|mNFhD1H{7yZ?FrDR&@AV9$<8^*v z7k@2|=k=JTYy6{Kd-}|y{o+$FOK16XMTd+WfK|RC% zgL{UBI?ZokMI6Jo@7pu1(nVglpZm}y{>_2rrSm*4Z7vU3bMALY&oD$M`M0Cpzb^3E zKXd;&$16{CZ@R+iliY)j{^7|z!(yG{MJVeM7f6ndFMEcuI>8@a(9`D`eJwX$*fUIx*ZBlY(^-BAIbG!) zFX|a)>Lma4a%-+L{P^#BhPk@T)93XJOLU&Q|74!Jz(0G=J;(7p`<m28=XbKDBb)H^s3QJ@2 zS9Q%{v-Ur&3&n=!F#I8F$lXoNVXQ9j?|V1GXzyH~T%54z6B?%f=k9@c#1a9^)8JaOOV zFfv}}eMU5g(K^jLjcg8+bdtyH?>^&rJ`dA$ju#@QOME}3>oPxqnYzMXW0npFG>1Cm zb%M9YY@Os0n4{A?<0sZg=lP?9ntk5TIpHVL%|37FHTl+qn|I|M%7R)_ccPQuruY1n@>niW{yt5R?@JU#% zv;2FM<9L1yt8|&)M@858@E4pno#ExE#xZ==>gKRX7xtsUmVZ#*I2LE{K;F*VY04qudq=k_>TU)!ZuyxyO4Oq zym-qFy+WrBJN612cIp*|=^8)tylJ3{6u&U2m(O(?&z-yX3JY|SkJ+PFDC#WVhLSGwn^>x=eBog8(RuF13SHpmP}UV5 zIKJ|E7nojcWn66WNIA-b$ACJ7w@+Fw9 z^ZX^cbvU|LxEKrKb^b3F>l&YxaW-_0FT%<=hHt_uUF5q^(ItKcYjlNQ!8%>#FHzOu z80(CUI>CEjlTPtSY}RQ$8e4USbJ(V%XCXZ59=M2l9sL}dbcNqTi>~oDBy>2|HFW9( z55xeSm<|sWbcw4ANOX4?}d0FTyaL=lRF=3MpOW2QW&PdF6O}sw;fW37%_R zh@NQgbe6~e+A3a+42c71X7^Ew_+Z1z*I~~FC(rVX>*#Kb z*9D$-w)ZZb{@Y7hRE8KjJ_W_;Y zGq6H^pQ#d(P1IrCTNUPn*7*E;Ad_qxwI z#4)@P>vfHPdB3&LIldI(3G?NXAFvKO%fEQg++*`TOU+%Ux#J;o*GV4su(|6L{|6Iw zjn^+T-`Knv({)(xo-tD=cqh!#N!|^4o#I|I)qc4Bv2J?=V^y`PEsy!=yN#kGae}>nuN+ zch9=QBd_Qkx^&}DD@V1B!Z}bk2zvH!@w*LIX z4||6JI>je_-8-aomS6bB*Xs&z3@u@zuJI-HEn%w8^U9`{Fe{GXmwUB@1-i=bwzPyL zaXjymXbCHHicjrm39EIEPuaaCtkYSZw_i)xtc$$gxR%iJj5Xm;k7@~nbU3;tY&fjcj{u_esWd2TwTCCrc4`S4R)!eX7_Kb_GMO1i{{obA5jb-sOCOIWLm z{PDRhVWX~bCD#(R>gaW7de*#n6IyhQw;`d!`L3Z;CpdpWOBkS|e=^to>omW2Q%e}7 zYdm>=OBkzj{OUt3VZ5$#-xV!BH)$XFtbetH*>Mavy=ZN9g7^E{+Uhi4*1t8Z)OoJk zy)~?hW4N$)YuK!#6Z^J?mQ}8E;eggKP)DD6U~3qrb9~rOT0>fAxKFw@jMGW(b4Y8* z#^z_nw1%0w!sj2+8W!t3FB#YBbDh?fcgeJdwK~Nkj%f`wo#xk$Z4Kc$bL1z+w}wt# z;hRo$54y;wPHOepQ1`=2e$g7H>k{vBdTZ#`Dejuw8W!p#*Pq!MN;<)NPi+mWbea!8 zx79zJnhWoe^Sz$;wLI%W-%ICt?-{LrZ^?K*43l(*`&?|kI?2tyb`Ltiujbu@uJRwR zXbmfLi8o!@8rJ9m2vI&i%dMYx&de)-XVa-?fI@Z)goEUF3u3`d&K2v*uY_ zo##()u}^XQt*xPbfpyji-h5lDe@=G&cJnH>hKf${33s=KjXKMxF1Ej`-2<=wOKTXe zD}2p;_EZ=6qEc&^tn+-?gRLPKo9}|df;T*>1V^+HFIG)cy%Rk&3Uxb9t^T*HHBVFU0U$95I$T$Ae9>wN&UbIJX47a~! zUvz?Zd8aij)hS-G-kf!bFW=Z2*6RYF^FeFargMDWrqkInb**cQ5VnSVH>EiBY2zIm^< zP}M~q_`|laRVVqKAGL)<#ai(f7^1^IZDGs4ZDCmK{o2Cb`?rPBI?ab+lFsn)$m%S= zHmWU5)>XbH-4zMxErrN4JIWqIvP|$GZR6eE#w7U+4L})7nB>=lK3J+CpBJdDL0%L8p1UbKHYY za2HnTB=4Ma53%`}3){kao#p*5ZVTIVnwx)ZeO~gleD$T)M;CbiE3A)B^I@2-Gko-w zZDD3?zI;wwD8%u6)bHEE;&`36D>x52!I%D@^Puy*=e)Mi^s+f}>wITJC%EBO_Yj+p zx!pbJET8um_n>q9+`VmKfv)hl2in3?o#9;`Hbl)WY+d7@zT>ay3^#w^ z%;*F!!9rc)`j6~ayv_%1Y6~lLn*a5wx#$Y#J~I~`-SD}&#PNJ5w(1gp_l4Jb#Ton3 z_u6V+I>9?)kWTW$7^2I3&sS|BrAyrOtuqwI^IT+fkt>*_qm$ox7IgH%n5Hwl<96*K z7q9cD$m`IfJ?w%xI>l2P+C#U_@vV*RVZJW%-OcS`p)T>!z1qVHo#BR-_OMDPcw%dN zSgW&qWLtY!AII?YM0*IYI!ipDqdg>alIL}{he5i?`*pR4Q98|^4rmW!b=bZ={C9`; zFizL_v|W4;o#UN$YY$nSJ*>4m-*@(A2_T%Y|?2y^84*!v(E4}*rp5I z^9Svr{xz?|6OhnZervdO(N*4W-*%tr@H+g)e(hmoyv|J{+kL*n*YZCwNmuxl{q0#C z!!19yzi|v7bf9(6Y2N)%d#Y3X9v12vHyqX;mc;RV=;7w8GrVkUdswc^+>&VzYvLHb z_;~Zuc^-a(`(Nwz`6LX~S^jQfdr0c=^Y(BZM(P5O|Ajq`V|f2F-M>!rTT|S>u5!Pr z?O~Qq@|EW}pSr*=|Is;&V|c`$thr9}eW>aZzkrRp!hgQgUc~GC0yf9%+_A7dY}H9# zgl%yQ*WG1bUN=X+3{5)E4aXjCGVYCXWhm=1k6F>~ zGd}i_r#xzXbdFD4*&b>-%RheJ9N+M@d;&)4EdOUsdl;>2ybY6dc*Qkjb%tL?PFMMX z*FD?1%=`Y^8PjPV`Ih~P&4;6;GkgJ->O9|z<+>D&vM%#~u~OG~WVJo4)@i=vo%XO! z=lSIS*k7IH0=DYt)d>H#*PMRWp6ckM(4sS3MnXp~T<^KlB_992ebiY#bc635$MdX> zUQ6e>^8@ciI>`l$*U=w;XsvXOzr!>gK57p?LQbc79cJk&Kefr8>I!#!?6q`~7esWC z2Y%xI;&uK#mgoY9nl;qX{jegA;o&IjG~e*4HPl5O`I&Wz*LmgVo@HI(^_!gyUE{sK zu%2-YKZeb^%!hsH9Ow*BL(@8Ei629YF7s#T)M1Nt#sHn+4M^%*yuQ_Q5wG(G43F3O z@UN|Hyv}zcqf311|GdxZ9FP0PGZ4q{uy36=o#NG)tt&k3JMZIhJa_u9z`AvkXQ80; ze8hH%Fjr^zO)St=9#xkJ3w4_R)-w^7>M{>(N`%!q$+J+=c^=xF2y1kTyRl9ecoV9+ z#^ZV=!g`(Id$CcMxJO$e)O3PBz_vJ^r?>kr*WUE{yh|bxT6Btkk4|0SBl@@}o#8)Y zh%WK)zKM|1Xl#n~ULurrjt|~B z5mxC8Z`{q=#xcBnko(qUK5KXD8^?3Y9*MA7C%8YtTlR=w9Bd7BmA@L2@XuS$QSY6>We_+4kc;4rS zi7-*8`9e(AdA=J{b&21>G+pCeQr2Imc!#~61D)iXFiRJCJ!Z%8eDHAlqBHyi=IRRH zux}z1<9Hr0G7%Q*Brp7l_17iNA7ssS^gC&LscYP0bRw+P2_BF2IvahM{fJ|DyTh${ z9K+v?O@ysF9FYiDA8kM0wm$q6lDfim8Rt_c_#&iqp0_*3I>+lg0i$%5yN|3# zoUZbZk8@8t&Fe8q*Z9Wq)>ap}Zld+n3EmsC<9I$Db99ai=+@B#e{S7$l8?Xwo#6{n z)Or337U~kOz+zqIEm)$%iHWcXr8tJ4Kv`G#tdkO9rOxrYsOTDhjj9fl5}_B?>ja;V zjXKZQqNWRc3pVQ_H=S(F<9L1)q3V7(af-jDqsJqmv;628-Z$bHKI2S#p>v#?0v&xL zM(QH}>@0hsGkh^d>pZ`SvAW8Ko$Wm&j^X{zvF19>r=05y>n!&>&pFdcesZSu*AWh^$FeaIv@L3AAir`Yx%NgjeplY^U{j(y3G5mHD0HA`*)1jN#1#* z@#{7B|HSy%ywjJ)$L5{BF+Mh*-qbg=yk{SITtDax&r0?U-8#=JhxQGtb%i$%H~xM1 zyl>x7e~|Gy!Oe#oADgcm*EcNG1>WVjzF~z<@e@Dq8`kIwpPKC(Ht8IHdZyRf;5Dc8 z4QtQp8wTns-#V>t7_N(a;(5N8&hkzd^bM1Bl0Tg8UUiNCKBI4#tIPbiOZ)n~xaJ>U zX%0HgFJ9L-tkYFK{|58XdG2$wd2RHX{Kq@`hC#Z-o9^rzM(G-7?&=%H>*!-JS!cP& z-F?GUo#1CMQ&;#i%+X;{->@ADaSV51u1@ki%-2Q!l#Uc^uDwMOl~lajep1KKvegr!#ybs=CNCmh=r9b)J8Zt-8QZV4JRR+h6;J@PT{g zK4{TN-UA7p;(gGm(|kAv=nNl&fjY~tA*ri8;a+4ub&=mdMOXPVtkwQ- zEuULA-Mc4SpFFNx&&C4-Rm-(QV>`}bV-@a^*bXeorL0Ttx1V+a(d@RQ4EMI_( z&hwtHcyG}uJ`-7;<1a8-hgYrN+xApP-;Zux=I2q+6@CMAb(P=8d|l(Ou|S7v-_VMp zPVkpl7_YzM^*?})zWYPZOKe{Bk>?^dKa6#{%>O}E*Z5Pc*I`rN@O^C5DLw=>o#7L) zS!a3D$Mz*QpY@4#-ekUf1qSE>U$)sg>pXXUVQqDi$6%Ds@SFd$wz|rv_2>wbb&dzt zb%cBz&!^URgzk8qmo|6!OuYN&*L!t@lCE-dOGj9t6MRH#M_8pZd;-?!EMI}Oy1>_C zoi6gbsOlQ`XzK_Yb%J-mCY|IlsOb!!hOIisjU63fTO7{|k@&B5=GHEA&I_%aFdhKrRI>Dm`o3Bpuupu2`u}<-xds>Uw{QA(2 zuu@m~$YC9!qBDHf56n^Lc+L;aOBeX25$<0X`5z6K2=lFcI=saJJgf8$c z=+s5N2Lp78AHhIf=I4>r74CnuJ<>_O?l}9R3!EI^5yr;rJO<-+hEKyJo#QKzjpMoP zczdK1+z-=ql6OH)r+6Ps*J(Z&Gj)bf#4MfVvys<1z67&%p8tG;J<=uaKfzw;B>wT=vtE+tc zxgBAu&hj%CT3cP=x6mEOaL?(^txoW+n6FcO2o~rJueiv%=`!!~D{B(R@by@si+nd$ z=@P$*)w;^>prUKsV}|pr6TBJ%S>bvnc6qN;Oz2{!6HUyDt;z_*~Li~ImK>oUKD zt-8veVVe#!JHlXuPkk?*fF_;gtC7$J-tH3TUnlrZBz1|W{Mvhs&hfLeI>Ja@;hTPA zUv!c0xzt|7@x0#8$luq-nFjD9FT8!2Oz6E1-k?+Ac zUE)WO(PjPuxbJu{B=jZxA-S{@;%9TQunc=RfwG>gb(5_p?bSc_@bI z6z_+WPV>PSt}}cQM(R9Yj#0Y6i;&hOejlTCjlV`lhs~ZfjMoX?0~2+MpF>txxbX{T zK91pyn5k>L`#%?D$X&hT-l=`6Rkb%xD4!6&2s3)gv2duM3TDZU>Ab(sewI>RuXu?_9bo6JKs6*e*a5g6E9KV5Sy2_VzbcX41Jb#XS9N*a)F2@{Q;MT6r zP|ykP+pjY$&`Ca^zctZmJ`H7^<8@f6t2}Bzr$3X=7+xER*LmFb)=FnMwWBrB(GMVe zX}-McPS!!E_~!3*`gdKxp2s?zK70m&)qx2Se@X<_v{Sgb(!0KWWMn_ zPsJRax34+IG5o)g&VUa4oBILg60h^!*rZGR zAU5kVKZUKj!pHr%Gi=jYz6D{6dGRA?(q;Z?l;5G!;lR#tDv~(Io$f_EPpb_n&=u29@`m~ z=oG(zrMeQY9bvC^iT{C0yw06Rx>ud#!KmsK--PwL$b0_OTE**pD>ldLya?NLi624O zYEAfg)aweLeU!D*IqpVM7kCMV=n}t%l&Yo(L?SjPF$W&RSQxc7V13ThQ;wZ z7f$L7B^`a>DbAQq^KIGAuqKY-ALp%Gyw0~=ZXLdIo!hUl);hsEW1voQ7D*j_C5Gq% z-*}btql^6L9Op!r`OIs~SLgVn>pVNU#%FY!bG*(EVP+i9&m*rZ{559l@Vn0N47%fW zZY^|%`8vU)uQy+v;Y;Rrh7~%`-=dGzY3;n(i;-l(hmr@QR0F7fVn zo3BoBkHzMt6Z~Jy*ERm&&-OGnuX?~f>I#4VLBG~1?)j)W>I5H(jXJ~4k2(MGIv@17 z_XnNk{1eXh|ICpuc+&pH=D$7dXM-+t-M`FBC-~}@?VT?0b+4F9Y(D2z_pfvO>$mNZ z&U16snbZmXKa_NlkAKI$=q&I3uJ<>c<}a{GhxMJ|J#5o8{^mXJ&)Zyo-}}J^>#xha zc%ysMCBEeYXG|CQj~ExP^MxN;f1T$CF-e#CZA{ixKJ+8++d9L!|C)=Aehvj);eH?6 z3!UU=P>k1k`6uo}m-#!a(4pqN4Xbp4o4&L!I>GyIahAR@Ummj6Ty%;*{K~I&jo%e*GZm)tj_Xp8oR<&o#*YExj6&C0uztGwh7U~LT+q%M1 z9sN(Nh}ZcetkgA5ws(b9I{IK#bcUb6nmC@HN_2(wvH7JwU7@C{{2sRH8rSvh^8dSV zZ#)F`I>jHNN!R$Cj;=63=lImlt}rMz@6^@hvlZ@v|A4eE@J|PJg|RxrOE6xS_$6d@ zmA7H4_99_>vk!kjpscipAS=NjEJkK47&XB&NA-ZaP> z>KdnZ@ACN%W4QNV>!TBV05<6~{}!8dfwM#0pN^g|v@5iHr}=UW(gp7M{jM-fC-@AE z);a#y54wDI(wg&#z0FaldC@-RqD%bA@UAdl*Z9PJyTW3fGJ1Mxz0yowa)N$SfdMkBdWT{2mivF z#4$WC>uksC-0M`&cn`0`-$z2Hcm_Ikoz8ze1{8FHyD(QLd3Vg$DZU*G zbTMB0wKEf&ADQJD*JVELGG|6-`DLutRsPN8)<@_0den50+pchCbb`OV%JZ(n)%FpI zI&bDSTY;EORt=XumM)<>s#3`Xe;ACI)o@~IfDb36xQb%BrTwuW&G|KShL zQoPR9>#dcJo_vEf(K+6PqOS2-^PJImorldgcb(#Mu{vJo={GwkI?wZN@w&RmFJq&w z@`ziliB9u=cX;23%}4yn&w_e$;Zu>&Io|$GXGSOaRSeWs9<WOIG#VmOkLw%fAMU_G5oi`+9zG+=P^Hy=QprGSNTH}b&X%W*O`ph`QrQR zi_Y`Euv}O8{*q@|m%04`Kd*Iy7h{bs@lPM@3hQ)+PsT=_io#ii)(_vFr=)g>!Nb)N6UY+d5F zFh^JU9dzp&@AzNqualg{TpfKV=Iaa>KDPck`dKX075)lKboj(MM@c7m2Q1Y|9*X5U z#Rp)8PV*Tk>m1*RmAc5UW0kJ*88zz_$ME1!z4z)A@Bf*-&}nYi>d@3Le1lT# z=6+#C2XvW#(bX@k)>(e7U%#+cSNU^n)S-XBa3yNGz+15`ULVje{2KL5&Iup0eLw#U z;dS_S4AMnjk72sTJqGp*!*zm(ey?8`ty4S$<8_{wVUjNMc{}$DlXZ@lBNwmpfMmZg zQzxU5*Li*%bK)5O4h0={=@$;de4XaUP>f^vD=dyR>txCG*;;fe}UC;{Gfhe0xCMo$=$89j(!;Hb(vp5O;`B~Y}R3qexVCn z<9MEcZ92;rp}yJo}ij5hNlee z=g$_kCj2SJ>HlZ%UEuR7s=fc&`)NyW(6p3thX`2i5(+2+Vw&D4wh+_Odg0hy`m_zC z$wMxsAZo0D6%k`qKt+vJu_|h;D0q(*5fwcVIe?0qQ&I79GzU>R=+Xao?LF&x)-%t3 z(jvac_xxY->91?en%kN+Yi7@$J$pay#5wL?z)JXLXa{(Sq=CK}Tns+|opjP1*9>0+ zeGym--w3@5binsRcY|K|F=*4t^do#Tbk=j`a2_4qpnc#LNe{gbd;oqF`YUi7{225} zFa+;Tnd7E{+u>`Vhk!fbYoRBAFTmG9uK~mG1JE16J@A9j_k(-khoGMVBk;q}uY>#H zN1)#Y55bQ@{|X+4cXe~z;b0WL7CIL^0$&GR1|EfPgciVW;DufW#^C#*!{Bjvq0c&% zzJ{-Zz6DH}if+*BPop2<2cS2CT9HF9Ii0?PFF^kWPKS4AP(G-K?}u)E-W)#dL|*9q zXVPErqtM@jwUYk%^cU!WuYt}11^8O%??5m781zSH(MRy3(3ib{@de)u-EuDd0zUwK z9~gokf<6jvhaZC;`$FswUk6G1u~VQ>z-(5VZV$KY$Ae*}&2ZV_dIi{Wdbr-5epdguzU7QPwU z12(|-L*D{A;0K}q4hryN(7B5lGw^lL9pGyCA?WYH0K8j*ZNb|l4fHl}i==^GeI9w> z2cT{#eIe82WWE20sFQ z5IinvpuYf5z>h)y1pWfgL0`8I;H3w?e%_+jYFR$yQFX6O@OK+>#aeg?OQ9QuCn0r(;4aTn1y z@O99o;CA>%Xgl}!@58=)@-kHa@Z z+rSg>1?VR57x;eY-}2ahU-VqZoD2?vZ-jmb)WQ!z{{x%^KL&mFdVC(f4tg0l2fiQr z8L$w382U}H41NTdd;z)% zyiL+Te+h1eAA`QM1AD?ZL%#ur;76b{FT;lLwb0jsd*KJ52X*7aB8Tn(qwqt}GkefU z_$#=MfZF{iANsN@=_mMR=xe~~@cqzFfHUETpr^hPzk;uaE&$8m8=;>Cjqtj@z-J#_&Vqx!9(!w^>bVfJPh9mT?Izro1yE# zBk%?2o57>-1JI9wG58^9|5khtUg$5tgc+21{Tw$1Jo33`Cv<=K>7Qp`6nZ>Z$@>vP zPXiaj*F(<-o4F?vx)NLkFZ5qPKfKUQ;A(iGuK`=(`=Qr?!?LfRH-lV#T%@Yc_#&|eMCutQE zV>fYLRF{O6-)Dl`XI`!@ZjK7Ybdr8Tcl4RKx63_qD~{WqAnL-uutY|gm@$Wyardfl|< zsf8(xlZPjbOc;&FNS|e+ESarC^pJY24r&XflE&uA@q4<71vB!7eG;}Iw7(5&ePNzG zm1%XeyzNWn!?O5>a!o^qEyMm(-IRtlk#;nBztS`_r?{EXF>Y$zl;+8WeHteXPZ)_u zv6;k+AN{>l>Q;p93B#c+_Y~H0Ewwhaa?6VyTQlq^X>1>BKPau1PveuZ#y*u9`Ng)| z`onre=iPoBN&WZvz7hE@FPFNr#*w7o>C@YOmAtJ!ueFKls`^xGlf;Mix3;moq?J0h z`})*Zv@WGq56i1AO4TPdpUN%OI#f1+-~974Q)2TloR!X|vGatLTVBf$8bvOu+Y2gb zC-d8@8~A+sQ2{S;VfkTrf4=3vHFo=Mj?yw@EZXwM(?#Nr@obAMA zl`VP3D|7CCZtk5E`8}Tr?hwkHO_}?l+Z5V2aVOU=z8zg5??(Rj=G%|o^3d}2`Y8In zfb%wwPIjk1#CPuR;ddC&=_qtM44vknQw@2hq0>GQ=Pys>n=YhzHfb_#vHS0^lkEe` zi*9l3WF!=+`ijKyF8WDZ`F7^!Delk>limK&fi9eh{zua!*Xc=Irzdg-H`D}ukKPYm z`L580ebM#EN?ohXOFD*Y`9{RniL3=CPzS$7zAK{+DPwzv{D5iXnUt-Uo$ItNr8;jY z&GK{YlWNrVIhc-tOZXIQR{tClCUgH4w;2ih_7}j*-m8)q~2Mx>q z0pnwOtG)Z>S{>G5%eFf1jeIJ<-OM#^qTEl|^rAx(GS#IT9dEpA9&MLWm524o+C<}? zF4ek1TZLh*r`q_@a`u!?cPLT<~n^J+D@P2+jh zzZ$iDX89~X&~}G555t;HsV%n}uW6Nr`ex~4`^1(T=G8KlhVfZ>HLcPx&)*xiI%l;h zT$|bSS$f)d%d38&Oy+>`>d<^44g1)ZTg^sRUrl54*?6t5Vhm*Xv@JvPWtF9MhScWI z%BN*&J`LNn8mH8jsp+lE@*1ysHLO(SA=UV>FT${<6KdyttAlNeO)qn{O&7-PDQxrF zI{r`a)#|cx)i+C~aUsnbmzu_wV|k6Y?X>Zhw`nw=jaOON{~FeKr791p#%GnSahgZN zS-NSOkdBvD%X=zy+q9ui|D(fJ_iFdnHjU-2o==D0Q=4qr)#|S%SNkiqWvNWs-I}qd zP|Y5pzTtI5%e8gw&3yi}*GU=Ih@{?X>!fP(jB>&@SF?9DxwVB&vp2ljQ|aF1*_$+0 zr)s>`S&i;ZJ({;#+C9bZDWB%AM#t;BFwdUsVB@V`T29tA!{+%%@mk;COLY$48-28n ztoCZ0(r_;LAGy~J&Wl(*Ew4IOYjdc37!J#lHC45;s>y8`me0~nWlBRo-rM=Pnl9Dk zVLf3uw2Lh#jI(XD>9kEsZMv`wn@{~VOcUy8%d@;K%ksr?W#7cFm$SxlSZ^2(_0aZ( za$C2i329h%mOh%NS{pS!q}tw4zBhV>d8&o0)uD2wVSd||tTu=FYQU#*-y=~69T?W43>I+bg>r>cidZ`-5gD&5<3 zs)y$Ld#Sw_&@!wJVLdkP>F`-~sZ6OYe>_=uO$c??@IQ;H?n+gUJ%z(|h4YZ+&w7TZ zabX!*Hr2GM*WTo@x% z8~=Yhulg%hyJ-0TcKx5x@BiEwdB(QS*!CG8c*X~w@quT2;29ry#s~Js2cGWwQS!@K zw7scI(q!E`sSf{WD)mX3@?L}7C+;-w1Z44YKe#J6uRm>)n--m1dY8@Kqe|Hgz7C<) zo^eaL4ZhsHNn`5>@3F&sVb#Ibq4xsz-dJS!aqqhSRNhnJckqHYfRkrTySDCMAD!kFKQz_7;GQY&^gAcJ6L;+6o_+HqcjVTI?qJ@Dn$3CE8PTDY?~H1_S$jho zm%OvPxbmG{?GM|I^@q9jPt>_rJbH?|=%MGhW%r!y7TkG~J8Q>@?$n!4aK~*u-W|F5 zICtQNW6`IrQXgsGE`7ri-xFIV^-qY(d(QZ$q!CEJ>@4kGB=3Ij3eE}dO&WP_66O;> z(Xo}KGVZJb&_3ZAzsf-)>&H}%yVc-3JF2AF?W4b%}=4tL2-uXO~ zcRu$g-89C#j--n7@zx$zS83;cW(=tfJ4wl#Wy`?s9R^7I5ByFp|ri%}5GyW=Z+s#^M8)H)Jl|^NYZMP$dc4f)JF`@R? zwux@Z9P;7HImEUrS#v$FG$y57JEw%@YWebBFl!rW)wt)*tCeSUcsji5_f*Re`-ok4 z2ey`RdSCffJz39ooB3PUPT~`K{jIjv4ErfrH_WbFw@2hWE z$otdRrSDHqo#>`UTT9=1N#4=TxqVdUq|S#c>$E;?d9h6xmiFxquSTR(``h%wH+g%7 zX8|OA6aJs*e051@$)mQkeW~S(9at|;-lA6z>X!Low+Y*Kq%>dhjCf+{zGR-)OWG*; z?e}!T@SfUi^$h2#y^Txk6PMY|83kqiqEo3mTYh8 z%gPtF&-!cFzA!A`RpMTIYLn?_Nwd?0PnqRTxp|74yLGZVocoP~xZlXUUlRRy`Y|Co z*?ZbOg(a`fGy07e87EsZt_gNNP(N3y{x3e1weQhn=4TzFnpddGlxE2^E~HvcHMzzs z6`R=WgXr8HtPP~Uw*+IgTDovdi~Slh>=*jLp2nN#uq#7{(7stV&njDFJA-yw-%r*T z?Eh$AW%+zH+3rBktaP?6%S+nUAiwmb%(?1U;(K;|HqZN0&1BY0`?zV3?Nc|YIsGzW z=3Y!VR>N@EH{vT=cbHcFtlGW2#%um?Uf5>FxYT3gB|Ldj`8~JD_M6Bzqx|<8wh-of z&S$dsb_#oM$Fui#^wx>Y5fhjr_$C(j?4kE1*RE}P-JDpy?woAC<&}Jw=On(%b0Xj6 zIf3u;9M3+@ag_P;$}(*}``%F49_>qMht4rJz2!BnQnin+L&T;#SK1Tkho6de)&9>M2b=DZH<}XIJ&Ywl6#6-<$WtUJQj?3^~)^%#NG<^^6C9+VR$>TTC8ptK`*jA$6->R&v+WXe|)9y zi|%s0P#VtX_I}awv!}Y*o0%InaIbxz@t11y!>3n1FVQhz+nnU*If$(BtRGgBpE85B z-YnL7GnvP0_(t3e&PUEIAInLanWU*9%?#4)N19{G(=6b33h(5%aChv_Gmu$41DVM) zkQ(-KXRrrxV)=DNY_$uUE#W)sch17rGqJUN%Wnp@*6-sTTWM?QH|xXVw^@4#GQPG1 z*LCYZ;$NW;SR1PUs(&f9{u%PNd@0+G8%bMjjEyJHTFYs@;%C-xvUCjFD0wB_HZu=O zyVZ}X&ExZed3;abBhH%NLw!TtlJC7PE%y`ARj#?B<2FCvOWF4Y`iQJMkY)LR?PKBR z`7%Y9?Pi`!>@d6Bzjcn1e%84!(RpUM&dE0(c|MUmW6Jm*rPyJc8Sh#BCjDgn$?9t5 z(#D3s&sEQ4|8E*&@8EL%l50xFvoEpXw!ntsn_1UVk#Enq#@c>Le8hjJGApgr*A zbzKx&=yxR(dk4>VllGigIaeg|=U2+dd;XX7doZu<&v!-nUgxyv@Y0^P=p?%C3T!X! zf6V)ojy3UL<>$dC`;@av`;>a!uzn@!73v@3_4VIl>tqi%;~Ukow&r8JW#8jX>>hlJ zIkE5hO8X}AV=LvN|MtLM;zzqP{3x6o#I8+dz1QHMeN?t#H2EHSqQeU-bx7oASIVpT z^HcSI(c8}Zi9a1zK93~+C+9da=7uCrz72bLrHp$Xy>PITKRL57i zc9Ar;UONwE`J;``noqK1V&g3tK48a#>Ynsp#`zbW^Q5fSjIuraiF*B!2ecLniuzq~dbncn?9(C4vo-Etie#n|TtJyKU z-c+-Z^tJ6j^$+!pFwWXM%eJ=v#{2fLv}Im!9oW|Mw2+tV*6&@ac(FGtWX z2hlJ4vj(oX2bK2k%IKSFeI`D~y?e!)!}dotzqB?BeJQJtMHY_hELpX_uGTi`E7_xv z_^iItzSeOjVM*Ii#ZLby`Iai>Z?7WXRYktLio9C-)+*_%$*YyKJENR6N4Pal?CVxN zI^8XQXqsDi&s2Bzom1Sr9h2EF+lT!!&b@7($k?BdJY`NoYp3ZimD~Ma zX^-uP@pMYo${FWGWPCJaj3L!s; z@9p;#Rv*c#Uu>=W5Ry*%Xq)LH&8t-VOsQ?N+Sko;?(u`1d*ndp?&tU0?&9}=SI%~> zcYo*B5_kGcDms|^!TpG@A$|t&@V)yIKb`n##LujLy-xb+t(9XTk-xo){0)_IX;aqR zB=TZg3~!&UJRQDT`FkS|pIuo!_9nkgGhSKa#o03UmX~yY55l=Ye7GUF=g#WGtaMqj zth_SrS~KQ{to+sXu1HJfi8u9<70I zYMl0|&YL1{pq(1d@VA60nlWo!Wy$Q^XnA{oGfaEOiwo0+VQI^jjJdE{8*N>d56c}d zE=(JS|No%Vcx|X=?<~3avmG0j5A7C)!*TLd!%wvhqO0V|y0$)5`JQymnj`kKHyYX} z4DYEe+8n4`j zD*c}&59*KL?#aMhS7>ncCG|MiMetU+k zWjy_Fu%Xm4d`Pd;Pu2Ivv(Z1YuBTehsw3R0C#JgPk4|w5ADZmW zzK8L7C*yMm?QvTXFv z();Pydih~{=_?s)j(?P|=omaIqfe^Uq3fxq>X-kMbv<2w`bUiAYGbyVe0xS8{5>}N zXN`sbO}ajvar=LZZ`d|iUdH9F3|~s_Co=Y*5_!h^C)MP3-_7#6=T?n|`=gRq_fTbD zvD=&}Z7}Dt5nOXHz8ylKu&J>>6^BxTE zeI&nQy=xC`)O>1}to`+Bc2+-9D($VE=4y9La))qsU^Zt5itmr@ChqwC`2BXy!4O~Z z{U>>jIo|nP=?i_%A@zt(yQ}z(ede2GZ`-dDA3lp1ul!4oaF;%D6z_~Yi#_jJ_Pmc| z&-)1Wybov3`!M#b4`t8#5Y8_g%o=$~<(OA{TbqeYo=r%-0vl&}tGA|;XF$S-bA_~P zd$3obK3oXuNam*(SL&Ladzs)4;rzz|od3ui>)M|1`Gx4yYR0d`+hqVBmL{`nu#cn!| z#w%0GPMya9nQ6OoNFGN-}2T6WUPk!m0G_YFH)xXiIyGqm6UIFuw~5i z*ECzNmQ#&Nc>*m*snoH>&qtOI%dxuHwp-q&(fn2x`kU3E!RrvF34K!Ap;YSG;_WE* zl>FPw++OXRjpkP!G%Qqgx8J~#bTS`koaWQ8{VhC|g*2QG!tl&Vy!&|+-`!b~es{!yg zb6Crq&06Lx)-um$EpsOAzov41pnWD(*RIlztaVv6nF zvlcy%M9(A8^KkS$3_TA;&qK(6F!>K6f5zF*B)`1pdnox2A^*YTKZyJXl79~Q4f2O=4F`De*ntLXF3l5fw@C;2|*0p;)V%DSc7tXsl+HC+ej zwNBP@dJhxE+4Y89*JNFLH9lO!YCU%Cq%uph_Gz+YVfod3HcQ7aZAO4tLhGN@?#dyKA6p#J!+aKdsa1p?b;Ma=dpv zZJYPR+d3_;^^0wGnf(^kp}6)%7srdx8)x_^5AD83h-*Rb)H zx8tP8H`_Mti{w1A`as4rNa-8C!?OPdzH=4cUs+$be6s&@ zY~?k^>R64}HVO^ftvX9w(!L|g-yOH@%lZ~lmP~wnOW@;2Oy?ch$()(nhck2X8wvZD z=0nkYo40e)&J3H0&)EG{Yn!Y%Ezg#1dCAjY{5GjK<2zHf9C2Y-!~ItqpWIi z_rEF&sazlDnd_t4AxtOXV`^N*JJ>seeT(E8YrNgIjwq+{&+*7iDBQoswaGj9MZ)do;IVwb!59`(Ncy^RDT3;63LcHz! zl3z6@d)T`&=5VR6n|4atZttT~hOT9#pLd#m&bmHIULDWX{QExR|Kasj+9JBEF5#H1 z`mK?Svqs4^-o7iE@qU2XTB)_Ue5`aMYaA&=A(>r2%@`=Im@d~O2hG> zx{7?4@v+e7G@WgS)HBcfVKrX!DV6*>AE->JExX#9-=>i^*|3ze)6YMumyHjvGd50q zv>{l>gtoHjZF{Y}TE87U%^l49<}>+i;PR2^{eB*LOF4QS4fzJYrXH`}YICxbt$wC{ zAXM$Hanj!H#s_R&nnv;oA6_3qTS?ygGJGRzF3P$-OJ8j>^OM$}ToaEgJ?BiWgHs~0 zPO&}OF55i}7_V06K zwKKVY3BG-0{nhfeZ=~)fuV;8olsw%TJ}dGjFBf}l3C4)#N&I+XWM`4cK1bEM6Wvd! zy!X<1(dsMwEox zkMbh!QQlEmW-``im&Us7AJNPDRPsLAMAp`POQhP^v+2WeBH?Z`-&AXl)!phNzHH-k z&QM<$8|xgNl$|jaHIJn-{>1;odu*v|p7%-Z|MtUOJI_#>d4{r@XDAo&3}q3|P|o2Q z%4vLO`2@bR{H)FUavhq^b?BtZ`Of-*)wk-JIph0>HlMaVX>Z1TzD*nYq~?`=vG)u* zC#j8e4w1E<@S$JWIxH_~6=B`hwl*8!oOs$H|R+@#)&b*F7_wYsb2ttJo0W@vX?r`RwYyQ;IqWnDWY z{X8?)rC(${qxq`oW$R7)=DhO0vGJDIa)rvZ$M(1SM0l^Sd87?{v%g#I+7Q~NS~{s` zPrvOGjuXja{Z+yOt9zKo#!1@5jvLDD81{eC9~twdwXxVy=1P&Zn*C?3Pu3+nGu9;y zW;|QnwO?!<($;Ne9bo5zM8}MMHmzT&)M5MI@)D=e^kTm)Mn|ztlkwfG^|a;<)7thW zb`QR(ulcm?5*B||c~)PmzB10jy_iF$aISL>??oTL?|nU|bR9o(I^XX8I^XWTn{$%bSK>%fFxn(~Q#tIT`bjE=UyRDbmip)$^GJA`lYeQNDv%Tar1Tb~L|uALWE zo*k9zm6jX!u`OTHZ1*~=p5x_{IBnxR)2{Kpkr|Fr>C4@A6-)i<14>0l@vm?mZT0OE zT5a6g_WeD4R^O;iY=5e*$0XQOdP-t6bYqZ9IxEZ8!6kq!(Y1@~Zi{*s9z6 zYUoo|Z_9^1D{(sSOWdwNhX(4meNtwlgQDbn)XAI}+^eV!wEa@Ho%coG`^6F?! z)fPgxppT`ZpXO1jb%%YSeI8OxZ|x-YH<@`r^JrQPSEJHi+n=^P;qUWhtIlCLT93wC z-7FvWr{vRXkI=AO32U0HxbbARPb?okH%1HoxWfRBu*($)oj1SvsC=+ccl1Q>yZiO5S-H z{%`dQ^GLWG8%y49lQ&G4Wv?)ehOHiZ!)v>gN;xtPBrNl(QY}BZe^^*rV})VcUgh_6 z&u9Bn>j|mqmt_mvPFq&!_qMO49GkBiFJ;&{UiGS$-pZ42V)6~lNB9Qj{d@!SF1~@e zl5b!3^6ksDeEafrzJ1B>x0m^%?%jxf+Gg7(k=u4ieL4pmFm=%Zx#AaDhW8nnIGP)a z8Y|XMR!3X5woU2??W3~ssLdbR-quMO|F8W$@|A1WNt;h-nVZ;ldCob(arJZE#mncq zftSs7gM8m<Tj8N7P;Q~4jLK|t*5M_?gt`W*=M%MxuhHv~7ZGzT;0c=rA zd4rTcDs@n94f;FUSqoqL0ph?IW!69&K|N>&Bgp!p!_Ybj0|yFV0MwCxl(^bEkb{~x zkXGWaLpS(Z+BNub=0hvKu)LE1S?+EFkF z#y$@H6!GXYD!vVMx5JBmAA_g7G5WU#+9<$QjriiIj4@Crb_e~SApQ%+D6b&0os_X1 z-N1nGlv5yoJ#h|MEf}M1W6&XFBh){D?+k**HzEgvz)3$qNASZT=m2O21u%-N9$E{= z;Oj`+FL6S_0B8myk_K7>8o?;xdg!oFY*LRMM#WdKyZb0<#UHLE?`?$fi5k$4&1>=9 zMs%(Rb)*^m5MlbO2EGwAg97LW1H#h}{q*S|X$H2V~ ze*N@WJ@wWTt|3kTC(vIg{aJ(k1_;-|*TD~?_wbuYOL*i%lnE_>dStab$U`}`$m_r; zr~zYAH}Qj@A2gDFfOL(-HG_V};TW_Y45Rx1{Wb_jNLz=!2Bm)Z8ZZjRgr^J#YT<_| ze+V>UM@Lx&{9%N0Mm~<5yu;ESP)qtod~%3>bHvr7@8FxM4~#K}nz4TYj3RH8u}q#i z($~BlO8Umnk)Anz6k34RFg`}fTLV9U%n=?VJPc~#N1#K<>m^>s0~lir)?ojB=+Jg} z>T;ll@@oa?T?2-Rt4EhcP=gKX80*8LH|=evosFMB25LY(s09ubXvZKZP{s&!6pX!| zF!j}MC5&B1B@AC+JPv)3a`2BD(0mhl@t1mNBN+P_Wq=_t2!_F^@Y|6QKO$+sAQ%Rt zU;y-^=Md$LQpYgky6#3O7y*ssuLsTWqxe7pIwrmc9TuN}jzIgNj&uXi8mSXn3mt;i z2_?-C{X7hY=%0ES?{`op^$y)ixyXh;0uM&u2SDL7ltFv@KTVyKGYSTg50btaIt)fA zuOC_m3ZJH2>{0+Dl-)053OceKUUUNm(2T7IXmhj7chFIMXIT6P41p0)i@wA3TMe{8 zIfL*8FaY|2Lp}l>1EXLF)FEq>z7gNS5Be#8Y=Cs+@5i=7*HaFtLsldHaRYJm^DwBB zIz%q*q%HMeMDmM{pcWKB^P4FLKNtc1U=$x5zy>w+TRpTuTkDx4Mwl;a!6@No!nL3u zTMi@Z7yDuVM&jzgfY@Kc*smFWOy*kXz|E9P{2<{m=?D6z4%^hDXCvsBINDlA-a7PZ z1a;_8k1maJeE?&`H%lJ+a`3I_PMZE}DI1LKpkCtK5b@GR+B}RuG*aFeZFA^c103>x z${CWfxW*K~FnLG75EuacU=TEJB@L*h?mBcHK+jtGq?WeSgJx+Hr~{3_f!cRa&bxs0 z33M1*%RDdwKPn(R0v!C%lmSMty915469?)+0gMTcyav>QIsvkNFaUS$|?_{k@z6FP>h9$7QtQTPGcHv$^TJ0d!QI#5GgEf^wh2%QJX(+>tfLGqKnUedvj zNV{miBYgpRBXWnlAASJ1&yio!(?27hMUEW@?xYOLZicUg)_^hcjDkk^0ptY%d>!Zq zjf5NV{~Bl=s0H-`iKFahf#e5u;$vWtxKS_+9H_%*3NjC2i$U@ZeE^-%y%BjGeK$hh zVK4+nkr$}18Jx!b)FSXwunuejuLo}h?*pFz!{9sMC*Zf>FJRx+x$a0%2hIh{KptEP z-VC;bPlK<6AA{e432k%T{@^I^Jg^wN9Bcwx!A;-;;7;%j@I&xhu+Q4L?r?AtcmY@r zTEQ#9JHZ#h2zUhi8O+Jgbti)tf{VdM@J4V8xD$LE{1iM6Cas(64gtr2Gr%IS3S0tS z1Ga$=fG>jYfM0`n{akk-I2qJ~CU7yh6l@09f}6mHz-PeS;0NHB;0Z8!19kvMgHu2Q zSPeSBwcwrLQ{Y=*H+TZfXvc2g46qC|gUi7izM>^ z{VtvBjswfUMlb+w1NVVHfde|QGgt%q!Mnj%z`uiu8|S)t-~!MEwt+jq55XV6%+9&) zM6d)jgR8(G_yYJbcmmXR&2{rZ8@Lj@1Ka_=1AYc36zFeoE_gZU1#bs;f(OAEn0y)j z2c8R-gLU8va6PyM+z##n_k&-8TsJlcCxa!R1$2QMz^&l(;NQTnz+b?O9_$Uy0jt4U z&b*eYv4if2>3mibOn6`>cD)^2-?6^;BDYmFbuvAegoW< zj2Un|m=9hIE(KSEcZ1u(x47lG6MPf=5d0ea8PvRLu6s5(3#z5z#rIL@JaA3@FVa? zFs&bb!MWhY;1!@3yaBu)d>MQf{0>ZcEn^Iv4OW9L@H+5*a0mD{_yyQ!3-bV21lqyt zzf{oyH;3n`fFbp05kArDfQ!jWfSOS_sFL(nO1h<2)fd|0v zKzt2lgVVth&--17bY1htmhk+BpS>QZyG3W$Wf$PC7;5P6z@NMuT z@GI~qQ1g214o(5*f(t+%yb`<(d;fa;5%4?kXE0|gz6;I=mx6w9BNzf-1rLCq zf!@EY(=umgM%+zWmHehr=k zxi{j6;5cvwSO}WHD?mHw1+M|ufg8cC;8S22d>i}#`~o}<{sv}V&sYPegN0xvXal|A zT5u!yF!&<)F8Dck63loLV*#86mV*}12d)F}2A>3913v)20{;#6zX3af2Jmvw1KtE~ z1z!h00gr*nZ>F!o>EHs;4En$u!3V*Yz<0qT;7KrhV6J-(XaFw?T-iA(~9=rr}fos4`;5P78@I&wznEH15 z4m=Muf_324U;um=d<8rNeg*ypX5L8IU;(%o^no{m?clTEJKz!UXRzN*jAw8fSPs^K zKCl(M4-A1}@BsKF_%oP#GuIMuGICz^ z`CvV`3S0-?18xJK1K$I`1vB1>e&Br21}+2Fg13VYgD-<`f$xJ~fIooTyRZW|5}XK5 z1LuIn;6m_Hunu&AE5Oy@25=J?1h;`Zz%ckGco6&y{0I0WaJOIwFbf%mQ6JNP*GEcgoeCU_8xf?t6@fC+=N6C44K2d9I2unepQt)Lsc8e9k7 z4hF$T!5v^1_zw61_yu?jJPC5|!#}{G;Mt%KoCOwv3&9%D30@7Z2k!*8f=`2C@GbBl z_$l};_$!#Yo&MzsRP1t&Uq^M5+&*ryo8qRrX>PjPmtW_b;cDDWo?PzlX1fF29Cx5Q z$Q|tX3Zy&C9qx{BN4i?~EO(SU+8yJb?dG~;-Er=CcY-_7o#ak-&vB=?I(Mp@=T38{ zyEEK#-Sga;?)mO4ceXpn@jWK@LRatRy9T$wEp&_AVz4x0cZs{yb-0bL z({;ImyUcaF9@p#o+$MLq+w87zSGrfatK6&HtKDl{zk99Q;$G*jcGtLT-Rs>}_Xc;J zd!xJFy~*9+-s}e4TiiDHR`)jdc6Xz@$=&SU;oj-qGy3e}LxzD>VxG%adxi7n6 z_Z7FxebwFNzUJB{ zS`wWXEsf5PUKA~hmPZ#v7xKXR#ZgnVB3c<;6s?L@M=yz98oexfd315~FVQQaHN1e; z617Hc(b^~05;lIYT?Bia~sMqRwLd|A{T^+df8!^H$^u@Z;l2yE4nRuYxK70?a__V zP0`KKJEC_+?}~1T-W|OsdT%rsy)W7xy+8Uu^ug%X=tI$t=)=)RqK`(mMIVbk9(^Jj ziar_bj6N0J9(_9cOms(dXY|?VbJ6FcFGOFAz7%~q8jija?TWq{-4%T;x;y%MbWik+ z=$p~EqI;unN8gG5H5!S&8{HRuFSij6KW>N@#0%p^@#1(%d|tdXK0kg@ zyewWGUl3myH^wiHo8lGm%J`yqRlGWWN&M3IW%0}7i{pQZUlFf~o8y+aHExU7#`$<% zyguF#x5t;nm&P6O#<(-?iVN{&ad+Gk_r`tkrug!Bb9_a7W&Fzcs`yp$tK-+i{qbw# zE%EE(tK)0pYvb3)TjMvx*Trv)uaDmp-w?k!9*Ex(Z;Rg=zb$@yd}Dl5d~^Jc_?_{) z;#=Z($M1>X8xO|si?_$`k3SH9FupbZP`o4laQu<@qw#I=$KsF2pNNOzPsTgrPsO*# zpN>Bh-x1##e>VPH{Q39`@fYJS#b1txj=vt?6MrNAX8f)A-uT<` zcjAAIN8<0s_r>3f?~ng2ejt7@eklHa{Db(1@x$?t;vdI9iAUpqk9WsEjUS1B7XLi{ zMf_;|%lKFEujAju{}KN-{#`s4|7ZMI{QLOv_z&?P<3Ghu#QzmP8UH!{OZ?yQU*o?q z^+&llm&;AaP0UTo?US3Fo06NFo0glN+c&pgZbq&qH#0XYw|{PS?tt8!+=01+atG%Q z$sL+IEO&VBh}@C6+T62pN9B&r9g}-@Zf@?_+;O?%b0_3Z%$<}wIrp60DY?4bskwQ% z({iWh&d5DC_q^Phx##E3%AK7%C-;Kfxw#kS>T~mR4Y>umg}Ft!#knQ9^Kwgb=jUFO zTb5g~aM`@)tnKJI^}!2Hnz7>iwP~5zoI zO5#_Pr6yFKdS&+&L57PuQQtSKZ*6v_t>%r;`9r@0+%e&TUROi};?yi=#Z7n@%lNNM!u3gc- zzOyCuF$u12@pjdK_*0iR0kTc`?p~upDrjuqobT|8r;-(Y-RoM4DkZtR$T;KzI;}Uq zpsS;+dqH1!k6OY@J5yKmiNg5heZBe3sTq>=O-mZe>I{U7ySp}Kre59NyP-m*Qema& zummid@Ae}t)p13BV@qK}SGTuzqQQy{ErtBr)$N^YyDm5NujpFWdwENDzA2-WD|&kK z8!POwGQU}z%9P%~{dQY_X#KN?TTif~jDB=h_Sn)3~BN7QST3 zQijcieZ7Ug-ld)Ex)L21zVw3mjZ4=sV|8DV3i2Jn1hz2WQ89rbYti(ViTjs)ZDGEr zx4Y{K@k?J|5-vG{Pf(_@mz8&o7h02gk+DOW#2R>E9s_PL242|Sop0+sZQ=8=!u+)@ zh2DJkQk*08&V}tgG9#^M>(1vpSF|vEQsw&!9qny+zb$!DXI9chooyYA`^Al2#o57& ztfV-RBu1u>{T#ozy`!TE^^#gOkPcNssG6krf{vD+4aNk?44K5Ixn;t%$!Sv3J?SKy zra@+WcQHXTx+G{XKoa)XA7QO6B)oe5s-(~*%hoh7f^2^w(%GZ4m!YBQ@SnU)DP_V% zn|t$}JxshS`U-`v?%sUrK$Iap*4x|N-pXvEMIfUE-FR+LOew6c*PYPTe~`XE}(k6c>d;gZ}KvAswHpe>+SW|`pWWqWe!n4tSGK}MZ|=?5ayPl zGOo5h!Fc-ZIc`r{EN<`KC|9^u`ED6`86AP$&hO%4*X|d26-K(CZ{y0YzP1g8mbHuV zA_~eb#iXl}VvqgJKwaDCC&>yueB`(-S-}L;)xEH#wv~p4ZY-WvmfXRUhJ(Ey^14L^Snn)Z2oJs?xZX-RzWfX0VKmeqyVdt8b$(I%`~ASjcA$>&BMe z^scJB5hA9g)vBu6L3`{Sx@PU7b?bDAQ(h}q!EB!(V*E)#uAj-6uHLia+2b_nqQctZ zQ0I!$)5Dz;GhsR|(^a5cI#k}2m!(PCNr>e>Gj)qn-<6416!L8usb%HY=etYOcem@Z zQz}gFY;CHBmL8U6+HEX<8ZTNPm#1azo%!O80$D}g)u+o5!X52};@VQ;3Ac8&bSEn{ z)h)S-_w=$3E^yT?-i%6ex$%2ZK3(ohI9=?dO)t~g$7Gd}=2_LgHs7@{%%gXdl)W&& zuBES|WbL3AG+Jy^yoD)cqyDn8dM@qlDr9KmMGY8fZLtr$aAD(8HA(fHwy%Av3%lD{ z0k#zP4MeNdmKP;=7Uh+dHWWyg1eW*s)f!>hKuTBrs>+g%uGW^0WUHcd&p_5C-7T%H zWjC$}0((e*tU7miZ+&Mx;;S!h=Wv#J1y>NE4egj z5@DIT%kvw%y02K=*V!g^Dw-Z|D^Dg{GG(Pzww%?(eAzflEM6>0q~aXukgOCZu4l!j zkF7YpIZZv)%9AT;W#NgqZ1I!tMU~XuQ!lWkm|;*9<3H=$+2N^TqQ-ppI@uy*xtxq` ze}776m>6!xxEb$kD-P9U!-u(#twq~mOsTz6nmS2xgX%3|W`4@0(>&~yU zQ;>x7-21F$Q;;3YVrv?^+c$ELw1V5bq^sqgP-`>WWp>tLGe=Xv&M)#5kfmA^I}p80 zn2BfD>8dQE%&oLjTP`o(aHCzNsARS)RW7?nsT)``q{&ydbg%cjrNtsj{gS3BH=oMV zO_;LQvo%;+fQv$D7%yrqm8kq6>FNmT=Va!(zRd_H@wUexDSZd-+9NvrB7w#L2FjuE8{H zt+0~2nWD2Mf#;rHR9S9j(lMSPDy@?#S5l_KzAUA!sqA)y#dPHrFul)j=<3GRdaO_Q z2quONy`9CqiF|J=w+;4^bfzgA!DTVlbZNxmj+XUBJ9v@Ynfv9d*2QYgY@B2GG^t#D zwBe~_>4F8^hOKMYI~q+H7N}Q;$`Y2hY;ND!x3SU=%iBAvM99@5qaYF6WlyT%g@u;3 z_TJ*qNrh&fEN@SveH2h^ccpS7S=wp#*Gp;54tr6!vb{I7(CX!Of_dphtI|z;nGd z!bx-L&$lC71}Llb)!PQ-@bsoK(>m9qVwE(Hm&DqPyhQKEJ7!8M7#TrlWDCsjw(XZ%32m?Xvu)d^(ggHhprGRZHTi zr8T8ykZCB`%(hW7RoHE8jbnmM8|3FCE7z^%Kqg+meqyBxl-0lqgQTxa987`k>(tyK|X=mr>!VGW1qGnO>vb~5o2~EOr0{%!832M|RA4 z{+NbIJdQo=j77@0V9dR4H()Y7?Xhuwgvnx_!uO<3GfHwF2qjKN&W7rLd{)|7{q4a*zX_@{RgT*#xp zmhP4LjRiRulUh#X>^h~>um)@<-M2~lUJ_i`dI{H#Vvy&+rQ~gwCL1w6(ud4lm7F5d zCTjg{mzGWmNPN1pTZ*;UNs0Hjf5kd{n1`Ka(Y>rI-B^Pz=w|lh9@1x6zcAn0SBxxe z$&r$&F1<$&+AI+)B)TXlUHy@^xNe7E&TU%DdNrX2)5qgPCl7{w{`R8T*VBtE=fZN4 zX6ryin3jp8RiDCA&+3-$^y0isHgFm`{8^!5D7leN@9}wZpgS)qo9?_UZ|S+TXJwbU zFE-0EF;KRBbICQA`v4Pxp1(`(8p`Im3-XsI zIk+J3#4ah9`}zo)S$i4 zaYeGxlnVPcmKCOlVv@+@M$b+k$);pUz2dP&Vak`?O{-dTpO(s`w+rM<@vz9vqPH7q*y zxoP$!a9VmllE(O*EeR~M$(AiL$(AiL$u2t6m(|9m)Dj+V>xs6e{Q7o|y>;WvK1CWf zoz{dmZpxQVx29X3rIVdL+*L^D&r;AY+N~hH(<@1ASO$Ob?j}v5qO4@;FfC8l6DCad z!F|Khjo+5b6Io`$u*me7SD3VTzg4PRL|Mtg0wrCUj$EBfhs4tIRAkFjnJupe=x3WCwPp(v^OJs8I zS}zyz;wD_Nj%51h{4P&P)^hZYed6>QP@bT4Z79k!Dv_&A@j-7fp}FLxvZcvxhrR1f zPlN7AvubeB$fbvGQWe%*+#Xs2(ff22WLFVpS2K{<*_L$+=Yy z#uv|I6I|8O(dV_vZ?qA@+q2r~DxtJRk%lvN6w(M;_UP%QGD+oGq*8Qp>^!)k3u22m zYoWZWvyonvU7Oka|DD+HwF?2p3NgFda>uFC(736$d|K$E8{%9=!qcXNw|pZlW@ZR6mFtmIyOWo z$N19)t39PFG1VTs5?A(IwD?FNiO_3Z`Qx~n@m``9u`wqw@-=X#}xuC*=V=Hut{kc-+x$^pwJ?ucF3-n^%((}BcsK;*woY&QrF6@b^ zczBnV%Qm;2aR~an4PEI*wrqs2XlJj6d%a|T!A96?BCo5+J*vKXCa7RyH#u+ zcb5iGssfLX#J`hnO(ZLqt&lZ)XJ5L|mteQN1*DN&hm@sZDQlm)`}f33`#BeNa_3um zQjr9UgEu|LZnl%sm&!`_Vb8y#ygeSdRZfs?Ifis{G5_#o=W@x_Y&@v%Wiej z%gqI=%2Fjq2P-9Mmz33zq%4ystNXOFBogN+FR5U5ZZ0bLP%-FBLY5KX?nx<1uiwQNGSW*=DZ#2sDL_-P#htu8k+j99k=;T2o`e^R zq01v=IaIolFNW+2DOoX<-jiaZqmWJl$(gvM)}m}_rx^~bTX>e}x4u@(?Q`)i*@yi7 zuMhbf;3QPMQT8F5vUsbU#QA&Wme$lpEp1&TW?iCOOOJneD~yT?yp7T81H1&0CWJ|E z+*#pu&MU<#*HvWNlMJmrjA{RxDR)G=7-m-}-QpA`&CJ3a zGoh`!%{M&1Ih_ZfX`*%7U}3zdqsvd$>xA>djsD`k4#tagoxYw|fI2rNDs50auC3vp1RV*6AscZ1x>5fpyeaOv5x(tN{(y ztYcbZ)v%_!bg) zjiz=k`)T(i+?rBMh3nLd4oY+!pn88gbu8B)*paHJ=_Ftzt^)}okxvnjN8X=3(@ zy_->Vi7j%y>&`@pqDlIE*qg-%JJn2^T6#>UZ7S=+O+BR!ySxp))L|0z-2$uK0$c2s zg!k?#yssa&tS^#qsU$T2f9>}#{$FnII+5JD{8(d!?&8JK0Y9Ho1W?!1ix4BEQg~;l@Og%=n64?f1_ZZn$WSfy4 z^qErL+mPLZ>^vje`eVN3g>3AzrF4VH2EWR;;m}+E{(@{6S+&0nccpQgJiXRaP5(|G z{(z@7=iv<<0VRuBYdCdcLQtJYDDMm7ZSf>5ZP==IQ4=z1!0VJpGNQ zfAzHH?zH~nJgxV%$*>_5r}Z7;X`QF_p04z? z!_%#vYPs8ec&Ddd^7LL$f9&aFp2qj2_0@QKgs1a7ZSeGEo_2V8wWsg&bcd&(^Yk81 zf8gnFJ&nJS)_0Jn^E_?vw9(UMPrE(c>gjtt-RbE)p8mkoUwQhZr?bA9)_0Vrb)KH< z=_*gxdAh~Zk9hhePap8~=bk>{>Ev&v<G|G z^yi*F>FMly)B29{w9eCoo;G^=3Qs#cz1GuPJl*N(E>A~1-R9qXy2aD$J$;*}@A33jPlr7HoTqnr`W;Un@^rVSTK{h~{2kvPp3e33 zxt^Zqsph*l2zU5!zo!G9-s9D8Y@$|=@KH=%~@22$~9D5{c>1WPfAn6bixz|%)Pop8Ue z$J4o|`GJ-yD;9iHCq>9D8wd-`)v z|LEzY2YtPsp5*CSo;G=UiKm-9-RkKrp6>MYZcl&U>64!7IGy@XT3@ZFXL+je%Y671 zo_2cL@97PmZuj&vp5Eo@4?KO;(?5E;A8SkbJHpe`JzeH$v!|V&UhC@ISR)TQG@3 z#mVtE&W^ZV3CTe(0*f}UcCVFia#%Y#P$wcc+cmWJHgxnlzVE(ZLl>_-m;+IK;hhtp zd@3*B#M4f`@SYx9Ajig*g5w+SX;{AU%2|9KIcm(jikO899N&UZ(=S}GnlHk8erdxB zPUgyUM7{=}$`v-SVYd z_u44^I-=BnwdeiO2zL!(&iAypmbLkzh$r=Oc!2jsR=cZW9?maZO2c~Gs}eqWa=M_U z(BocR3YU%qxp#?l>4N1v$zR90b!>cxNUT}ih)AT4dJdBQS6ls}8Zx@MZl%7p< zx8~%li4A>xWQtGF9qN{D+{mfGuC{ib3v*n*mz4A;QW~;=Bf{-#iCD%V588W{%1dAW zU6DNWCGMPJTw2CbA6~kA5vQv2a;R~>;5zjx=;HlgiT zz2BwZMCF@2wDTS>OO9g@zSoDPk@MaCCbXI_^rt>u{9r5T|Ker-ldJAf@4Ncel@6K{ zk;`|Gmv)I=_z0zYVU)a}5+-yPA@9S8Jzag>ZHb|ABiD(yw{z5yH|6C;N&YdJ`q?<&H}v{taMX%1K71`k!1OTe{Y{Wg=bFxv9OoD>+=es)eWd z%p>z%tHg-0!8rXw92S z(zG{|Iq-&1O3ERTUC1ZII{2Jto-YFT@J@`oTcmnKM-1kEC6X1rYrS*0KPTbjz4GK$ zw!f6Z$qUl*vN7Lva!2OKC*Mj*KQ88$gDN)E9b7t`8S#|S=jxrsvgJd>MQtSX{yN0xureHn|!=3pr`8}$}P)tY&$H{J)AQq zld$=ZZ8)*)Ppky1{)#Zq+mplP(sZ*n$+_oENMFrM>MhO`mrh77RpyIK`mLsp ziWmyKEd5r~YbPXc^eo!kmgmDAa#h(jLCy+`6Yx{9@X70P#i8chmyq@Nv&haJIFTtO z(<2W~V&s#PwJYCa&n< zwJrCSiN&|WbZENwPh8p2le&ldpzt_QdNBT02~kZNx@{uI1v96BZ%pLPM$$2W*CyX& zU(S1p?%N_|qUC@2K8koPJ@uW5`U-90knX!0PWtYC4WV5x*CFQ~P)X8h&i!PfoHS!L zS;29bj=aA#jb=$P)3iye`BKAz4ZKC$g;(^pH(bH#$Rj2thr;}Pv)Ub*hLf&b>DH`i z?`mDMPEHQ+n=WfwHukJvlb3@^t})`UQ9B>}=c8O-jMm7R9CuD`O<($L{TUNlTIF=e zQ4{c>hjS+G0~7Qt$=wrpd@m3B-8Y0w&RG0r z!lrfpfC0aqvtZeZviISSA|YiZozW-#xt*a%7tOg(uMQ+r5i76 zrr$NKUy z{2n)`vFNmbk8Lx(Z0e!5&l$NE<}=ARBicJiGhC5|6)d`RUm?D-9r9|V~54#oTq0Hj04qj@KH`$S`j8<&m{lIjLl4ydP zzxEP-Pas_$$XZKA^9;XANC$L!z?Z(|h|vWsh~#v#q> z%)JbYo@9<(#_B@8cF2p?ZS*2uwOk|xe~OvkLrPX3B1+!1VBW_s3Rf)MDDOsJ>emTN z+c*%+tCV_ucl;8P_c&s7HSPFKq*R(}w`lWxej}+|vYOvC;?s~;eSXu(yM$E3ZyWhg znugyvT8I;Ot>+-MR)n9mY+TK69!ZPk*E>opiXTdUTrNw^)$ZqR(Z)jW6{c;!bBj9H zrp57#MTw)O$MaJcVaf7mD_!2j=;&gF`Zp_8`_ixbMs#}mo}b%4;tO5+v3EM^hzKv3 z-^0sW+#scsvO88}iJQtqC>>OnN~DX#4cw_dtQ~ZkhLhe&UN3OZE0e8AFHZRj($CMi zbCcNQwHQv%J63Ge$qh6YeOJq)Xg%W%rTFm}Gjo zQ{?Fvef(XLb9ad>J#3!z-GdTNZL+MZb3MPtvf4dVE<>9imn2E9M@nIF+hzIA^~s#^ zvvN5(e{LlHRhDF7EoUa%>8oXlnC6MIDG>$>6dgNUix(xcQ~;! z{MxzRof*GK-XN#ospvq?dTPOO`E%(vW^*%$w+3(-P-Fhd0Oare7(% zEeWSHYDxNzxRE`8)GnWm(^)^?oeWHwwD{rjKt{=*FP9-1E=tnrBe|vY9}ZaU?k&a^ zT`zI89``^oCT+0Si+Ud-CRstU1CYGQ&AqvoFoJ&qF9%fR>a^PZG)`yqm0egvF1zlr znAh#rmRk7-!v1?r-m-rbNwMs|CLx{q)43&;ywp4gu8cxHaz?%k`GMW{ z&fR&0AAM-P->~{x#BW&2!^iArTH2dH$ZyZxeF*UN<|@aw802?IMb$OmT4`Dx?)~pK z({Ro2pGbSUjS+AZsPYqi{PP4O5Yr(i@Q3^_)px=KR zWqSy3^Z*~(HJTK}&34-(zlL4A_7Ia%tN;$?CtRg8N&+(#uC|aTij2mFsG1(9Axt3| zt>F)C8tcyl^BJy=f-6*^BKt5^7=8ZOrZyf5^Bu1CK>&fm{&Ty9pUyjV%&bX==UWvA zDuEq^?UMzY{%wJEWuZ#M(by`!@zpuAW7Zvj?wr5-w7EGqy-Yg(yVQgP% z3<%y0pMvAI%ayD5Fv-u?R4{ohn%pCW2z1%yvb^F@uH=AbhPo#g8 z%Ny5j-ng-DaO)2i?bfRr;9q<5+!=K-eeZ`&y4J4G*kzZrtASk&d?IUL52~JEPIXK} ze(JG@S=kBZPJcT6rSk-Hq!Y}8{$+UDB;m?`~7cs^+6OuvTt({Ez?8lJz4 z|Jma&=l}I@O!|$v+u6aNJz9UOd6j^6o^M`hH=C7!UH5S2Czwh70cKVIInMR~@5JK0 zS#13bv#jG?N)&hxC4L3VH=6a2S@|(HJiC_fV4t@!7yBXhe;1`W#1?Q>`w)@m-qAU) z;+4mk(VgX`BF_gn7N!G_+xT3-b*y`so&I?Ld)S}N@P54CWz0S=V9t55S%1BGW@YI% z`LHsBa^aYVD92kTO0z!yeH^`qoPLTcWqYvFt0*@s5u0Hi_Wg`Bfw5ik6&!mRIbTLi z2q-bTQUT{;SI(}5)!reF|0a0}dA#19lclqq*7eG^RyDLL(`E8i%y9n}{@CLd`67;$ zaqK%t{Uz$^$%(6A_4J^rZFYyi#If}V|FOMpV0|Ckhi#eO#rEp!hp#quditE3HTyyJ zdKG2bL#sQ)xz<;3+%gFH66zgX9j~%lc#Nw!Z0cftUtc;uWjlO29@+)eG(Hs&<4M0j z{(+z`P?45&Nh?}YVsHj;bPU1h8lurNB%^Q0#=uaFp`jWhLo>#PZcGen_{P+j8M!ex z3S(iE#?q*a+8`!p@@B^r%&sY#JySCKrfd#O#T=TdIWjeKZ0hF3q^569&6$~-bF(lP zW@#?X%B)RdaTafNEWzqpqSdn`t8dBHz*4NCrCK9Pv&NQgO)P5p*3_C=xiz;6Yhjhv z(yFZ5A~t99cE=X%t}WU-NN^wr@}EnVs8nyRa8_X)o={ zu5IFQ4)1gv!Rb1p({m)J@5s);QJkTpIwMDO#*Xex9P0Sa)R{TCGj|GS;grtOshrv& zF6Z)Y#}(YJE4n>ba{I3A4qU|@x~e;JHFxal?!=|8?@ryBo4a$ja2IarF5SwlUE*;b z?{z%E>w2Qs^CYkD$=<+IyrHLhBTw_jp6*RN>iOQ(n|Zl6_X=;}mEO{;yxJo^=ktEY z7yPa-`aNIr`@ZZCe8nI7sz35If9&i2#HYURPyLyn`*XkW7k=q4{mQR>5^w<@bOIsh z24c_)q@W+j!5~nAVW0-1Knuo!9!vrn_`x)o1$i(JieM3x!7`|VIv^nz@?j?w!fq&r zy-*7Kp&SlEB^-uoI106J9O~gDq@f>9!&#Vz^RNgPVHqyNDy%~iaS2O(Gik(KMPxc{GoTXc3jsGOD6FA~6^9aVHkyZY;*VSc?0x z91mh89>!`sinVwg>+vL}u^&(4S)9l7xQG{V88721u49sL37>QlA?YS!(o3YIpUBA| zQIcVzCZj}4#)+Ox5}NqQG?^uNGEa(Rk(9|YsggP&DVOqTCl%6eDyF?uO8cpt4pJo@ zrfND$wRD{7=_IA8pH9t5f>H2LmhE2NBpY-4l%EX zST{tBn;^E$5!33BM;wz7zf`neig;BZP7%Z>5phXDJkk+|a>So1<`8pwh&4mRm#%WpI~&K zpP}lsMn|#wnzkCM+(JKTTWBX?3*D4&p_!B|^b*-ZE72`&<^EFH-G}1M?d;--Joru8H6o-L%xM)*c^3Of1jS|7=$xj0%@Iq)Hnd8 z(f?Yb{wZ{SfjCc~^F`=;1-f2`o+o^VTtyw^@H3Uc!Nc_6U54;16XZOHN2yI7zC?l_ zQPF=W{6_)bvCc_&rstTR@EfFc8q(GdqdMU(r04b(&+8o_SCG z)<>2nlq3BRcgRk`C zUtL4n4B&r9&@dDD-Wfda0y?HnIVhPfl-`0lSA1+|pOjc}v}4pZhtatU0@H_j8)AeW zgSz-oaC6X>rNcqP^)Lnwz*Rwus1z)l9xb0aX533$m2nr;D3 zQhOW-Nf&ga4`nw56&Ztw%s@gGxaQjDpzpe1AAN9-AvE3?yu%0Um_z3+!8kbZjV^da z9daNQT~LZX6y6YYVhl3jL*>muB$l8N9F$%c6rvBMhYM5p8y&k+U9(1al?}JRYuf&5 zJc82GKnPfL&!P58Pyxc~rr5_fmhb?b5uiRLP#IP>9VCX8tZWo$2iigcZDATz2Vt3k zt&}0bx27Z<`l4KeNEbnI@c`Lj>P3ReRX}rC9u!J9Z*r-?Zg_AT5qeh!uTjBjbZFiw zls=A?FOo41F|ZQG(x5z!fzxMW&N;u*4D^k$@oz;D-`)u>$X- zff-Wp!W{mmgbqI03Keicrh6%PU=9{oq9u|SZYc#wUImB5gW!pvcQWp$3YVyZ*iCU? z3y``Bl#Yj65<%x=kU16iSqG7u;%*mkO%*5{4+1B`ImsYz>KQ$X2VoOI*JQXT6;w@! z*POyh6(DI9>u=&E!of=sP&CHJCHN@?HB=0AMf)zKi;!GkH_ba?;p)$pZmV&_3QjT z?{m)kykGBE9aw3Nt~_Y#H%<@#-Y_!^yU+~#WA?r?_t{_nK5Afp{QiiB`po^11HN&r!Plol zA2{~}gOA-U6ydTB7T{e*c-Y`egFI%Pbb)3j7FR!mY?F;Yafg zZbiNcx7}m#?Wcv(I2%{s=B*9BJp*CjTelfp|CCUK8+SGM&QU@UzO{wH^=E+(eD_F$ z>&_F3aKr8fH+Nu{fOrX4JZNy!y+RSLf*rySE;jfI%7pNP9)ojHZiG)c z1?5LL`#_8HaRolEEXHsJ&Osc6PaI}&&KU?39yjg@^67Dtl)Eu-2 z;QXU4Zo?J$G;C|Y=BEj;OSk~>5pF^rG}hw^T!6A5dE9zJYi(?!y(h7WGE>=GGQCG$_WkiPPAD-t~$%$ z=);91)P;t6!)3x?7Ot~|TzR#@(KkR2sBJV@xd?Qiwu`~4Jz)>1J*uHRoFj%%F z!h}s4a?MJiaU$X&bha{RpC=@tgL2XM8Lq&4kw1;ca0Tu@OhcW7G6v)?9??*py@bX` z(8d7yf!P}B{R6__8eD;sb~ZQ>bxU~b?gj^5FBIXeryCqNjPS6KD;_jBZC4=y^|sv% z4uUM-hT!pqns2^={C$7LXTWYBNrVE1n zK4^q1?=$%7fRF_A6@uCiX#wO_=No+Wdho9o>P^VI#*MfF)6qWwdD^1}&7*`QO!jK1 znJ8yKHXgTt%?2=zHbH3YWH5di!oY{tYp5BhPYu|g0lZ}w4f(!1gvO7M9>Otbn}B*1 z_!=8<1vZ>w@i?xCyESNWEv_i@mD_2^s}Uyr;}i`wjyeJ4j}9^T*9AfnzV?7c2Upi~nN zTCh*p#^C1zLIUcD-&$;sEAVd62uB>NA#c4#5Y+zX8tjGf0gx-UH#ik`2rG`$Q1#1& z!5m!YfCqg*y&mmB1MU9x4-0ww42!dH1)8@R{1bFQ$$Jex09`1*|*C0_C@k@U+2c8_@nx?-NKr;nlMYHeMnW zVV468j@(-)!ZBzsfP4ny3ZPb=pdtV9BsnKO&p{le}*~)R1@tVkUxD!Lm}S; z`Ll+GT7kF#c{TDv*nspBR_|nibgl*_FV|3SUM&dn+TVf z@XfOgzIC0DgzL62_|^i1ft#*0xNZV;;G1akglpCtd>!>h_~Drbw?Bn;0{nWVhFXns z1mv#~7vZxS}ekKkx<8>Tmbopt2NYG^n1eOqZ;zw zrv*VBdz^;+J?a)v@4Zz+K7jNP?%mPgflUZwOkEG#fc)J}8fx7=f*^l4tf3~ig?-@I zM+`dW;l2c%aJz>5&&`6M<_sF_brbp>@J5VPgm~R%@qdgRw6yXd(hVa`I~bLev5WWxPO0x@7yaSpx%Qv1IYU?(NL2p4?x~~ ziiSFN8uBp>WrK16)cWfU);@vq1lG*akiXdj@$3QG&KmNRgM`LOOOU=LLUo<5AvZjR zc2C&e;LNLpBz$C(!N>5M@Zs|fK6+lGhkEW1YCiSj2WDT zwn8|w*Wj$X5e7btvLW1ncnRO@(NOO?5aoZMkT=3EpjQ1%Lw*-=6E=ZI_~|YNo6vs< zH`EQjdj{mr5b8vf8(|BK!-Nx$)sPbx3xawM>Ys27+9V*KS*xMC_Cz`DiMT=2cmh}8 zJFrjq@x2=A%)N!iM^GPx@pClf1ky(MG06gJ?l4&WB*quu*!?ur%7-wnJ%l;wh{3fe zbHaxn)KJH7#JI6h$g@wk*cI1ZaSz3PlkmYYgIOa&5q3a(CA`dHn-hg1JpU|%Z6QzC z=4pc$w1m=l6jxxItqgX2N+`ls;A=d9EASlTk+9`#gXf+u6yYUE3t{I83-qC#fmdK0 zBkX`U2`{sF5!x`}4mvs|}vN8_E;d z33fHW+X;B_4F=oqEtCfO+xEcA&#;(|E3oCI2G2#>2)o{Fuo3YQX5D5m+A9=cY?i?& z;wOxNPgp)?P+2V$p}K>`leiL4_k^*F3@Q&o4j36WsBD8Uu$*k&CgjH(24|y<5-wYB z@Wma3BwTu)!57ef0HveFa>)lfh*e7YOHUGWZ0>Zo(JOH24zQ zKjCwTk8r{623Mdy37>n!;DQT42R?(e5YC@v@Y(Hz)IeYPEO72U2IpS^K5)*F246W9 z=>k4^v%y73GvU1X1{Y(zB7Ab#;8Rx$Nx0}ZgY(eF2p8XF@G10h!ly5_*aKJKqNfcm zxk^aF73Uay0b>f`!fg#ca~AReT!=IgEK9Nm zch!)OTqy|ZB^xy4BL^W2{P9GChaVG?@aLlp{(`ILw6ed4f!NIcDlh|a3wsB^b!76H~8yiLJ}TD`D)yOEAUsO5m2As&ET_7 z3#G9Wt^|xTgo{QDK7R`22#*?Ex+C^YfJ<($I09FI`m)9hT!D)=8C-}mB76@0oN)1e z7MJ1*d~Sikg}4%qMqC<5-_gL~bqm-#9QAm8zXi(bdSLk+gA<-XeFMiFtD&YZ!nzfB zCE6Nc1IA3k9%ze%*R3_!9qo#+$Lgd-*8;mwGkD#Wumc>A@*|vZgu&j3Pvb0Hfj1&fjV*9Rf4a@$2fGSM_zC(b;W(55 zVf|Wz_uL>P;m#d2)X-gmAn!cE;t^bdV=p#%?{-20>VT^ZT1Y=2?>bLI9rGmSF;8Oc zd98+OtptB1co=g4)jmW+{$d;K*KC8|$SWX!ah!%a<#5bvfe&47aPq@K5ng?s!EPuE z!pYkk9CndVga*nMkUv5H2h@^>4BmlzA7ROAgLfbegu`YV3?Y4lC9p|2bj)CQzEFgv zC~v~x(+2O{5&Lw&@HGaF;}9>>e#cE3sw)KK%#mI(_`E`+{K1_$>DMOd)2 z!69hlgtwn+(2q0`7D9$F?_7iVN+?3#a)U#_BOHwKA}lz?;O)D>4&f<-e#A>yc!k0I zyI_YN)1s0!Uu@|m;VQ=pti*0e;7Ba96$kUe?d<RznBRm^>hBq4g677+2%k2iY_Fx|bcwgOM`Q;cFpxb+shWu48 z*2lpAj9A=;D{ve73ZV9T!a&Txeg)x7gSR}0eJS8f4I1*nU9k?|Rj3bNU_rlu zGf*~!(~&R2X*U?0j`Rcaggpq$mh~+hICOA$S?|1|xr2QJ!-ozo8|v+!C6+B)w79=N z<%;8pZJ5Ig7B71Hvfl3DZUN%5gR7l^dZn|x*&2s>ZG3_(1yl-;SL*fVC=;**;*G{U zOCVmW8Z#Y*xXWABDzmABL`RwqZPixP8kPFO>UguYZvJFrv{P#~+Dv*1A!}nw-Iz%_ zL)A`9_C=Cm+ISXCj(1b>R5D47c%-qS+Nm~Hvz%B0@!B!Z5{P$9yV>e6H4`SzNV`f8 zGa1iOh+7%q#YQ2b*4mZ&#L5cOaTLdGO!5{%T%s86NWIcn73dm@;f^*st$M&U6vG`u z&GLNI+J<7dYg4u*8U6${g}}C<7;bx_GRm7&t!*fVJ2^2?Z3Vi9Vz~9@nuu#CHr`gP z5yh)1hP$Fwnc(GLYa0r2JIy#=M={(u-cHlUJK7qZxgSfh36mav?L!^j^;i=o&Ukek zt%k8I!SY5Y)`dJGSl)PZH7`9VYKqewpNKR;Al{nMcD>qQJWFuAFiK*&IQ8!ePpqR@ z-LXj?CzwRAymp6ICU``!ywM=7;1R*{8VOTVoMxq6O$0_Qv9OR6YH%r}B`gz5APe*} zEE7i|?qp~A{x0n6ms1NHLCI+yP%JkrIWS$x;b*JL#~(|udXp2pRKX*Hi*ZfFtAk*9 zqbnmG5iAdbQ^eF1%S9Zl?I1)1XB7pV@Tr`cOsBajGN37B!IfIjIvJ74G{Wk#LYhia zwN5h_EGek9BgUi-6Q>?(=%Ch!7?TC39&t?A=tQhZ&#QErHCBE)NILkjJftsorHUbj zaZr>*ARYa4GGT&JaO(*dl!A+N#g>Uw@W*2AnB#?g4heBR7C)mN>nPT$>vq1gkT&bF zT0ZHqoT@FgM=K3pVr@ep-fH{XN8u=1voS&UfcfgeE}I_x;JSd~}6nN{e_ zij_bht+c0n@|y!c${>B90wUX)#REx#>M zh-~1>BhW#jFAt|+I_T(Jffyz~%j?Z1AJa@&>kubUG6dpbtZwj0x(OE?uBBNvuJI=C zmCGrpW5N%vLJXr(Z?0fq=74!*FmDU znv)Hl2@@_jTt~BPK4P`H*E2u4qN9*ij12V=-r6j|^SGvAnmEHwMtG(6b72N6*wy&%ygshFJl@o5PW%9!^ zh!_hc%Ost_Di#ni!>2RLCcW-XbG$Y>+*;S)9ObLSknSb3Vw&h>7B{f6PK{YI$(bd4 zPo>qWRa=AAdKGtiw_(8YI;B`*r+f66$y#f(c49G~?z!DVEOJuih&d-`$zBfe=j1GzX!C&#l-FBa%$aHes!eZKzIl;bf<}mX+{aMkOg~im{BRk%VpQu~0xJ zIn!KYF-|3^URu>O*TrH1ndD45hpOY)bZEBts2p>c)ttDs>{%p_(9%ks$w*T$>ON#2C5A;++?1I>0Mq$!rWq*9;cS%eKkBEHG*+-7j|XGD^*nT&)uRa=6M zATDQyLmALTkZt`i# zvE0&HXXQ|*GP-K0ww@OsR|;jw0(zOTx2Q7CwL&^c8nM1!)_n?6U?~tO?0`yA7#NJ! zK&#el)jH9QKjM)F6`>)sm>H2|daKCz%0wz4liYCskSPvk%G0a_k{q&$V0lP>$RmQY zi~*_<>|T*+OC*`WrSn_O@%gnnFK9+&G6O6YD>0zsF#+7#5&@!l3usks+S^XV3I@sQ zUF^Z7Ovq7)J0H9C0n-vpEbXwF4KCFL%d1xT9UMF&7+$9u>=+C#)da(f+WX*AO)$JQ zXf0vE8H(Y?v(>?+hC85W9*T9Hw#96Fnzdcz zzq-0MS}n`JWm+9=v{%#88%4}ab%rLYe4C;uH*HWet&UqWQT_BamN!{GppwH)Smow7++CT5XGePT>yvH%D39qFRwS?29Qjlk7Rgh|Geb-~ z=8*Kl+FC8l#0nDU&&Nai;1Q6MvJ8@a$7FRfX?=`HGQHJfa#8`AmbdkUMfOqTW%3D&Qssx*=?<=o1)e zva%93by;3;=gLahv}So;8%fSe*tq8oES`&9VP1$-D2~dcuvVz{*BaHdL6daAwJ96y z9Uhv?S~8MiNS5DS@6?tA_c%y6qLo>=@UYMV5iD$ojo&QgXC?`PK|?P`Q1yRJQ2b3B2_TC=Dss$%@5;-fF?Q%gA0fH z7V;G*m8vCLnMLysT@)J86wB=&iqb~}$Lmg*L?JHP&Coh*Igbx^FJ#68GRaZuK9hx>PiGiSLZ#sv2iL%QPvV6Ml381RO;1Euu#;d9GT>3 zl=G$IIDVYT^PQ%#KNn|qg0%xF1uU29)IKHKQAuiHWnvI#Lwy1)!SlKkW^tA;)I`M- zfi%reuIVVmom;7oPU09~_2A0*cxA8>oSw-rNe7*;uYu<@o<==1#Wp;HC%XU&a zW|>n-3f&0SNwoJvw=E}F`PbYrhF*0XRRT_IYcPGx0vHIW(eL@iU~ zWU!x4I(#mOPLk*|HesP;NVhiifcf@nwBK7$t-T`bOApoxDoJ4!E5criQ*DekZCV)3 zoV6RDm4az4m+K&cm>I^?O{Z(i;whM6JOw$(h>fRUhVkUOthB0}1E-KHpanY(F z8rTp=LAADvaA32bl2q^HM7@TC(wQ!lut?r+GT0(ubrvyF*>r3%+ZfiAWivfJ2jF)T z8-=BlliTXNS8!SBui{!D(T#t&aAaOpA)d`r>TZ`$$a!)}^n`DKbK4P+#M;b*shHx0B$~#od3DTKJ7pb)zotkRr zor{;48ffD#8{L=C_)<3MpIeYqfe! zI9-EqMkw1uXS*WvR@$;c`NeJ8^_xN~5D0a92l~Qdw-FINl*9`vSmEhcKC&8|Z#7XS z)*LnGC`U0fj4f*aC}3u(NLjVLs?(g{oS-i8$UElSSZpnqYG(LOlXkq?L280H^*&d~ zx0-rtYh&zdj0FcVkiV2|^=LpXS4+57YiX@9)?8Drm*JBp2AY5q)kBt@i!ste{!+7n zUfXkZRJ4 zPYHO7_M||eJ-=RA5%nD_tQlmvsFvYcC)odw7(psx*&;&22<-Na2Im9|vzi`A_Tt1d zE80R*(}VaU$s+nfve3opm|ApCN_m0pj7DL<;05W9_CgE$njYAWBn!K#WKXj-hV6nf z1-C3?q`vV5Qbhg*cU@7E;;Z>`7uRVrW@v4q4fdp<~Bg4QJ~TvnV4*C&{89=HpG5 z_9*rT_!;6Hm$a~sHMY~WO~N91-`bP?mV`y}izmjg%qoi_$1TyKJ1QST7x@j$*z%`-`-DB4Ioqz95gyqV4% z@B>XBbwiKu8=)5O;@B-6hNp`#M6WKw^w!=)i!TB zIc^YBR;!4Laf3V^ikE(qql2bg94m;$5i_OiSb=>^-YWF$Bwu8f7ijb~CMG-co1?*z zk|Otv8))VB-U}tq4D#a1ncR405YGafpu{Ma%Z_7_JSJN0l}YpBRFVq1G&32}NwTj! zqz6aZU~J86&`pSM8f4j|XGEDUizVghG~s1+SkJ3q4G=R)=U{WFroT4Q!t-txMZ~bO zXq1?rkK(L-D{SKsk9bytwrFt%FlRqxS^0Tu;U<9gK87YI=rxp}un-0e9X3p%yc(4%%6v5oSK%SZU<2L^|MDX|tZdW)4o<^Hzt{ge)t+u(ArzB=m{5 zFe#kjQ({GvmTGDuzFKx1aF5tBEXNS{;<%(3;AGehRZXI9(2% znCasw*Fow6ri%xWaxbh4eHIDrRA#~cgKncG$bTsMe=k+jz3Le z@`gq7x;;8Gthz(GwTzKCW3-@>6iT!R`>b)QPbDopvFX?t4WD|MbOubTF35;_(N$TTa<_ToH+)Y?fT86ON;FEBc6vNUf!Mg`8m(lD7 z%_U@!JUz$KH!#;)?ZC`3Q7U567pW(S%<)MRm87RxnGVS4Tr%5BFzYpRD|v9eIRXzm zG#k#yCtRyFSj9O3)O49%hEJMHE3FBw($`2vsgxIJn3S+$F61qTq)}x-%oqgt*pp?G z-rUMWXR>8-!=ebtB!@bf%6^uu?d#{{xShaz54X?BOpeZxlnFDQ*Dwc@N>l7W=A zQBNZYWF(RBG%I0GUgrcu7Rl4I@kEjlb-K_O5*g~MmZ;-h+}AtY#FMP>J>r8o*~!sJ zmz87;lBMVChct1vt2P=OZVKrnX`Zm>WMd9VV>dr18jwlO3DMw-6-K-do@H~rfr>sw zQKlELxgKiNoI8c@uXWYZc(Y9 zcOp~iFTuVfrrJ~Gz?yNAS!=`VCitL}Bt`SHntgab3lov*)TPLzxD|S{A(M1X=5o~d znF&7&a0!hBV%@153n_C6u8q|K&e1NZwK|i*6xc-^@=G=6t<7XJ(1iroHn04Z#~bpw zW?#Ep%k#Jf#!;)%y|%_zT`rT6Kwh_JveU^nM6Yc{^7;#c7Xs3#iO)5od81P(W`mAE zLrJFaHJRH(kLQgbZDWxD*F_em){O+XF3gsXLAlXqs&OYj;<$k%pC>yIMQMsgjj2>i zMwa=t*7%xAtLoTU6R}W~ilJ(&mhE>aHOq@M%15%?7)Irr+-_aVu{C4)Q9Pu{?#bEA zMKWXoHVgBxkiHw1aHDw5pb_k;6e@aigO2?hKMIaM<;cmHJSN=myVnL=FwUCeMAAJt z>zx}rAZ}QZJi2pnHadj>*TurLe_n2aW*L!eX|f=mNm)TH;!gWyj@9*7S66d&k3|W+j>}}ofc zMDZ~hZy}ob8kJ(+Yl6|FHjW@-d)p}0vhpluM@1UTiXbh$xH#hUP_$9e25DmDkWppa zKr1?3Qly)mE}<4lEeR)9=-fLwAicoQU03x#}aabGh^zNeXRa%Tz1WDQTR^d@zy zS%;G?JZZsuFcVn&x2eVg-wm6SoXQ#-6w1t)^L0UL&<$N`N)2$CGzC^Yv*-_#5z9?w zNl$ZqqbM_^#Y*jz=EtT)mquSZG|rR~RvHs^pUq}G5K3(XTN`D04un!0)HyesjzB22 z;p@i?!SPm1SWbEA)M_-Yg+_|;EhI++Sy`DxVrkqYkY9$S@o~A-QZ#&q>ctoulB0EI zhMC5LQ7amMLp8_GYVs_Ul^G0hvD8kqFfFqaiKTWBQL-*g^1@c92`^ovmWpI!FI}&e znQ_a~thIPqT2?N|b}X8;m#kxxRI$};%Im-{h4I^XU z&3fCeg*HF*O{MnijQDUR_v8 zzpe;W;{`&>w6nS3Cm_kCrLUb3s)t* z*!-xphO6TfylliES?sH6*`<~6{qT@Zk~kZhl?>@5 zY0{{LgM!vcw`7vjKjX(Zj7T!huYY1KVvsDd*8}J8@fHH3S}DA(zdV&Hs3e79U;&PX z)kb*^7?EU*Kr{|9qL+#GbBs)}kK=>E1Id8wZN)oGM$Ax2%AB%m8!~GsA>G@fWYE$> z^O?Ml-g8OIElm5;C=ym0ixVl0s1WeF@m0Z(#J$KgMXvBQ43HO@ziI*Q_Y%B%GOPj@gi9*2i zI)jsq5(Urk(saVNM4Yj_ynR!oL?z^UEgH)7LqHlog7<7p-ebPk#DIA)zB7_EKt~TG zyC*x%Q9SDlhFlW^F8e4Os31*P|S}t z>5+L7jZxC9Se|-CiM(dT@|5BddCemEm9?>DwJ;q8$?>aegLD#KlN^6cI}%B%F4&F*#msg=50XN{c6!b5ydKGF66Y_Q2oGF2 zAwzePYa%b`BxPt$0_Tj!mUWUZF_2)u;_|GHoSa_wQlMS!ENe6yBXyjd4adwJ*I8|2 zk+f_%JceP~i+JgMrYMq}gwtMuIHy$32squ*=(|OfN<(uJq&yB+{qSN&$!pO^@Y0-> zNpUL^<_uW5fk=Ssw)GLMWoTm~QzaoQ#_eDiw7Ry6dMe9AB;a)M7@xjs#fL>Is)9^% z81WX=8gO0FSqaapneR0uT&Bh9+uG4>O26krdW`RBq+f*ieVq|W=3tXDX2Ve!x2M^p z&o87xjzO}R_fl%$^RPaGuV*mfm_yQ-`<6(@9Fo?rt&lv=2_upWt+WmuIXXPu!iY{L z^MxalD##>9XG${G0OG&KV6G$GRwt!8g^WRibo2x^98`O(Qjura<;I^M z0^5Iq2!Xj6yx|Ou-`P3UT3LwqODij)TsUGV!+pKOk`-Fw$^(Uc=wyf9OtzoX4ofCw zTkB{WQ|YB_(xaC*Yyx_k{MdHHaI!=Aka4|Qs*$isZy~<(Qn&ArE~!=d2Llt9m$x&@ ztODnG4U|kjy(YoR%h)d%fo$*=sBi9tO28*gn9*m+qQ(}GtsE8nTQgBAa6m+P;iAAk}?5M zlQ+*|PGqyJtmusye2pTKHk~ALHp9}w_@rsFMeiAgdx0T6kpVS%rKt9sbwynf*HnBkiCwNr(lNh^kkgd`V4t)7?Y>x zqVn7@F1*%@fh>9b(3XQA z3Ezrk!i?qR7nO>84oTA)+SD+oMpAf9FzF#o+_QCB^cN;m`{qQhqm!f=Eru(t6?hDp z@yd|rlP204XR;ef%pqws=Mw3d<5LAYxaHGyA{u~6dr414bJl#h@(`4 z^Snl%{tQR@G~DDQE`J{(O~U3Wn>P@7Oo$kvWs=QXHXJYQydNh8QZQ24 z)Up%iX`YL(y(d;R(OaZo@QSI)l_h(*qIURq0elJQnlRr5h=}be6u=8(pi$;xG#e=lF(oe-b$6I%_OxhXC%Tr~fmJKzOnzuGDM|3ZFaJ4yJ z?F5fQSAC)2o zlQl60Ya}aNaC{o{^YEmr7%EA@Z4n*vOXH6iR(5e?q)a+w`4nJy)r;kL(d|l_b5kw2 zjKOy97(NDqIXGXlhw71-w}TtQlA(1C{)IxLSujY}E=pHcCNe(wGECCJ`L?`##2{Hj zX6~w5g;htyAX$_bHyo`!a@-(>w%v7E&}{Pk&LX0KPnx~>GWuv|pWZjaboUsZlBXUd zN<~P&sEA(JNRIsExUtsEnNzA2>_l(Y)OwDsb9vaoeaN6$wMRPvy$O#r;AV(khvVJ1 zAQAu22A$8M?;qe{(NcUIV7S^EuQkF)O;ZRZHhOE=m>I2-H=gQvlRnGcYJ`t20&8XB ziCsz?wp#HStHi5QU@(zOEFsEy^z^g`d+94$&N}U7gxoPBgKH zID2p+YrHyjHe)fegO)KIIgKeuoF9Ci)=BuU&kj^u%jqkQaQ&gbRu>Fd5YOM@Zi>jiGybxbS#OFngxmYgJ@=}tFZ{D+SIw%Lj2tc335a$ zGl<8uk=GRn71T%yJD+$m###@PwLGgq=Xk1kLw5{Ier(0?`5~1`%q1;41G9LrpILVl z;zrNKi)Z2VV`y^3cv)h)A)PGHCl_*(A)O?b(pR;D$J>tL?68RVmmJL9V(G$Yq(Y7Z z4p~_;SzlFY=toVdKgtY~>A>8QRrt@nXNvcQv=dC0C~Kfpl36oPqDs>cvY8%Bz&z(B zlUK7(f=ee8V|MI)I@v3-`XQU?A%0o|Wc)z-m;(XQ?S1E>?twm>7YJvY0r`#7!@oDo z48txo!~U4P@66fz>)%IhJJYdZzn?xD`JIdK$;kgZmDq0u>f#$x zJo6PPCa#p?DbUVZCB@-KOCjn~T=oVfW&u~Pl;Q@^HrAwAgx|a1x+mlw#dWYobt6$v zQfz;W6bEbs)=F{Iu4rQ?DRJiqQGO?)O|6&W*!P2X6w{^e6JLb0f*guFN#_BPNDQeq>nN8tJ}u1`Q_{VSE&9+-|Yd88ZVKL>g}XkYk!Ev_4J z?V#-+coy2xN0AR)>$q+M+9q6kZjxfwRZ<*{vbq!4@){|o?}t3258a3I9Qdk4y&xZ; zoe#O|5kBHgXj{P5(@_^l+fhv^dMBkgeJ0vN1G2yY<5KK|>t(pE{}AlVfIP6vThJ!o z2RlDPd7`X$c@^p!IAsHLfx(s(*81T(7xR zigWiz8ukJmYOd_Bq@m~p!lX92e%?=$`>#k~^z4=8c_2ce`8@CIQXB-i`+kP~27ruZB(F@<}OHzZvcGWGU*v z&ZnZU?TP;KKD1llB!qWDK6W@B{rEvC)E`l{H>2!+h4u>G;in;fw1p06_gsg*@l7eN z`<4`2;P(PtuSC0HBE=He zJHJbb$58g$16Q4i^nL`_kAePSDNg+;>KWMX42(agqi^B&WB7dnFb27!&qCjU&fU1q zfc&N#(BE($I}qugek0oVDwNB25#EHpf;ztp*E(d*0BzcdO8j;Uv|U^;oXfS2LkxednJ=Yzg2(um)!7oZ-2t?>J)9TDCN z<0o)E(lvWa*m^Gd_)C7&egc?hIG!^31Q#{*x!45 z^ikjp#5oAQJX=xxM34*BdIMZX+_KCZWoAf3x`FRVbWiZ%+I2wVjIgP;wA zzYVUpL8kF>lqt$={bd-ZzKFhisT3D~0sTiIZJ^!xCA5{Vps#}d7{Z&*LHqs$`VVAB zz+3-0DR#dA^?ijDkKp$O_`SntFixM3cJx`)3vkc5XvYX23Efj+>*i0Q4_}1w?>w}t zi!tsYeC4OmjzPN~w7Wn%5aCNdjlK#z4f<7=NO2D0*b`~n_Ckzjh~rdT54jv^1r~iC zy1;&ryX?!j0uLi^gNXZ9r1z{JAkDu-+r0;49j;qotZ3l(NpmrFV@y38Df_~x|m=gf~2VnffeOREaZmPoW3Ake1I)5YX<-M2}d=0j5 z!}u~2^RhpoU;G*O#J?cF_`NG=S3ZJq2JPV>Tu;PU_SnO?FG1!>$ZWvxBOk(8g6ox! zOELX1l*iwY7s%ZSy1?(#K|7u7fnP`XvcIA(9!38E4#MxhFp#OTL3z)MU z<%oPAdko4R_tyLAzPrhs^V}3xtcLNXM-q&CZ1g(Eh*vId?K_7lC;smCF zz9nQHMISx_k?y4^^FfsFJJB`}J`TD! z-66%+xDMhvV;=h90+eAN<}nAO|KsXB}{w1Ckv*cysi{eY-a`8v8P`+LE%e&+k#LwlY#6EIg zIa}^0f1xfEukE^9{X+g)-KV}Rt`Nt_yHrcg=o;vHullAsuSEbZlj>3NE4ho@RbDUNB>y0G?YdH4D=(K{ zkzbQn$*bjM@*4R?`BnL4d4>GC{DypW*O%md^4IbWYA-da4p#fCH>;`|Q}fh9)u-OB z2GpQhqRoEC>Q#rRL)Bt+pn99?SMN|qs%7dZwL~4JW~%+v z4E08JfZ9jxt=^>GqGqcj)VtM)s;Gn1QnjyIpiUO2h|1Mr5cbBW= z&*V?!bGo{^ey$!@zf`|c_o_Kv-Cf_6-;+1UJ-g<~gXLWL68U@e2lYGkNA)N5Rq++E zf7hG4R;ZdI3RS>SVP+ovS{q&R3sS7pPCEv(zWl zIqE$1G4)CHQMHwPk=$0kP)?Iu%KwNtvZdN;5BUbUy?n8JuG~&4`5gH?xwU-0+(y1Y z-X;%{AC@P}-mZCFd&`;fb#gB`OZ`Y*BKPQ;+4Tc?t9(@cRlZE^q#l#os7K^qNss;A}l>LqFiwWT^m{Z0Nu z-Y=hvX~fp*dFs#dN%?!ZoqDm_QN2_>B_Ef6mruy&tGCFex>@`{d|Q1>Js|!eo)o{4 z=ZlxCH_N}MN7aq$R&|rQMg2(Kpnjl!sBTl=Q`f88)pynR)y-;9E|IU6yUCs9hvXUJ z!{R6EPPIw>k2+QURXip(s)xk;)$imh)SJ5Y?b@enzpmL`v%2mPzY%l0?iaro$EcUf z)oPKPQ0vrh)ZfH{uK8Wx7T1Yyif@UV#Es$x@m=vf@qKZM{Gs@f__4TE+$L@pw}`qr zNt~b#>e{mFg($rPRqFlX`Ir{GN=}zTZjxJcsjk1NUO8X( z$o=J8H+mz^`Lr4T_rv!KOjFP*U52ty8Ns>OMXtSl^4p7$@k0m$EWgsO!+KgIZtKNCL@|08}X?hr2$i^USLR2(LT#5={i#1Z0fF;Dc0X<|$9ZgHeoCXNynF(Rgm zSBX(ECaPk&SRq!5RiZAo5-$*6RhO&Js*BWx>T~K#>Pq!xb%pwh`i#0*eO_IvzMw8s zUsRW<_lXn4@!~}BVzHgrUc5x?AYLI}E_N0>ikFF<#7o6NqDPF2rkD^7F)3DyIpR6u zHR9D`H?gZYMzq8W#dAelbi^95R%|QQiS^%}iua1+#4E)vq9%?OZxeGxx0opo6mJ#7Vo(f-H;C7Z z*NHvEYsKzjZ?TuyQ=kj}_wMxHyVHN~PXE0-{rB$l-@DWQXLqMAeeS6{@Fzjfy+8@x zk+U@O5LpN6_2wv^=#Se^6W~R(=I8*P+;;H!utESHU-j=!bG$~699d{?_fQxb=(HFC zPwT=^$fkqgjE`e4VJMUyZmo+H%sFwRGdWgk>c_V_sT3+6(RNb^ZrR|2uzPi-R;P!D zUdb@bvC%@;5dFz3W}?WGw>mIs65caetB+~Xxl4w1409{>(Mj?j1NTGYaGM36z7$9D zjUydB|KgUG!aI{K|K3{kx}px^MUu&?iP9LRcW!kGqM$u|qs=zQCm=O@F zbYnd&ytz19!B;AcaARx;r%~{(oC}g0l^{UvscDM<7FJhVcs(CQ?u3Y7kK$PyL~-v4 zq$JiL&2wOVSebo~$Wd{mMQfvG@l`$Zp(jsRIN7P1Z;}}K!Gn8(IJK51(yKenoM+HW zw@H$6?AU^STMP#$e3FK$*EPOSoI-ca$9Sih=mJ+{|WQt>W zB?^ESpdnCh;n-nxm42DQ+p-7EV*-CcE#?*Fkw3E)Jbou#9EQ=pW{g7|OGySWe`KbY z&fZM2=59|`QY+R4Y{R}GK`}yo3x+QT+tA&p}QK{-eHqL)2=nng8o(ovlPO;yh_#3p| zgOky&JI_g0A8s1h&}n4+N6B>T2(sRV<5KV<4!9E_Co~jQ=VSfGFUS)3dx}qLw2Wl z=u@`dNbW16^p3eZuVW=MUuD&=X%`7DY~t2h5M4Z=<>E=dTACgfM%vR8Lb;E{;0rOu zhvRgj15c5dOIWwuCQT(w=XO3d;2jZ#?){<`9x`cIa)*=f(XZ4h36K{RceXZ_phl5% z6X-qh1z9N*w_XMF_VstW?1yl|43Ihc&Q)G7bQ7GFv7Tbfjcm@9EK)F4+6_TyD|E1DIo+7H!3Nnmg_jRV!Fsi29Pb}_&`8EN@)Pn-uKLh8= zY0R7Xf`xgT+msN-^fq28r}q<#qkJ=0qp{x62aWe89Sz8|#4^po*Ihs!ny8Kz#=W$4 z+ZLE<;Y9`?p;_5#=WbT2aPDZsa|agBrSG)S3vR_i0cj<=cKYSy>a_`agUuy_Ue_II zR$BTUCQroVwcWuycmj7_{SJ*&rw{Ma=e}LoeE!K~JxH^icI9jsoh7xgYSXyxVAe1q zyO8~SZc*A%EjTun4R=A2esvecfR({2cwEb*#*%vIeGGdmg1E_f??7LXn6xac5U*=X zIOQgTJO?w?-WPU>d3DtpxZR5Cy!t^CMtO3aDo-OmTuTdY|s*H>jZ(vzr zTCF)n`px}2!MwYh(UE+l$qEh29T{0!>=E}*o_NcvcvUv&1IhnCpaub-; zxW2(gPLUyPn!9O5+&b$91sUyU1>S|KmlP3u-Nn5qV^hUASd7^hVH~fvwpzzi{CJiOWGj+4m%&N0!GkeT%}glgd1*Xn4V?c$+y{XWEz-xS21+s3BxCp-c{owNISGVBtWxi_b%iNs?HmLuejBe?^bU5Xw!M#o1qc#p6Q3=Atf z@IX)u6^8B?G42(oTsN_@>7C3lu$8nTva46-c7E}HO!5ql-ZtqHCW zyu#+3|HhJq8((AIsE50mj^kWPdlOj7WF0Dlt{pZrN$V0hq$E|F`clp~xNh&$yQpb= zHqd&0aN$tjLeu*xxCEz=bW@?9v)J!_XU;NiBuJ{>sV%Xq90b$l1rhlo0%1MJb@p_? zH3Pi=iHUF9%p05prxo$`cMlcG>-RqwE-a{v<{i4onSf8t{FDT#8SEV%n(G9IhUT%K zMW#XChtX%xgD_pElJto49;pl*kmbtc1gMBN;EZjm_A( ztP+hX&g`HD4F*L-+&m}qjr1wXqogDJsl z5^At(=eQ+pp!n(qZ)kn(TxTg}1e_~+>9Gxrj zrvxZuc6L3N&!vfPmw$yl8xH+j!V8}j@E)g4ibGe|eoGD-7y-;0J<4;=V|TGJ06ptU z$VF&_g$ru^V3;}gw&_6abMNDxnok3@BjHm!OpEo_3ex<`+hgomV{ z~>F|jP6iXV)b~*$_^dnu zZQhd+NembMnsh8!fcb)?@m7aeA14~Ql_6=p)bip!$m9pYucAebZ@8%&rLh)#kPJR; z#wW1|nW(SR8%;*Uf16Fm?+(Rire5gr;X`jq`s5YI7U@Sg?H*i8vj(ir+q9jntr^n% z0UmGzso{A^eMra(7H7W(m$s|bRhHUzTOWfvbU>~y{F&w+IMS*@U)<2Jl_0MBsi}$y-_}BV$GO855&v{-L>K_cbE;xv+6kVbbdj3v>LxIIVX_6k}cNGHXZvCa5=^!0_?W8w2Rpu(fw z=AF;Q8qNn^K&Pc_;axf4Shu>xCY&i)BuNkdrG5>afWJ2siu!gKl!JGh97N4-c}BU+ zS+PxH;TqUm;jS!=4eFR|=g<&wkI$4as3qkBPQF~gh_eTh@$l$VMI`51+EZg!-=1R% z!aGei9P&(EJi4{z*~Z)^^Xy#Dgo+21MaVT-Xt|vRXQzV`yR7_an@T?b)O-rjQN$vE z+U~C7$n-cKr4~e#G@Y$C;rs_iDI>I#!RE^)Ukt@rRqPI1%&4X05 zV*8tFBAB0pz7SvBqke8~dPL9;E8P^>GTg%Fz;@l(1aUbe>x-eC5D zsb>zt+H;j>0>J$TkgWPO4^u5U9?b=TKa*0m394CA|hdSG!6 z&dkF;yX^-fM!Y9{(pS(~hqsdK)Iw-@{v@_c^mc4W4f{J@k zZGG`pQb9KUhlAQHW*&u*f1X#660gDFBoFUQ*09aZN1X7>Q95RjvR{Cr9ddq8#Oo@w zMx{>~Yds&PsdB{@Wv9~e9mojcfl|?>G-bGdi015#Nz-yE*rFGF9255;_Y)a2KXp&A z```9GF~6U)xPd2`{z-)n7M<6eV`tk*=A|;f9%Es)UNqEj;caL?MG*S|Jo7r;7HER=1C zOBPFI&9iIe%7`hW%4pO7SgtcwY2$0Vlm`0YNE0}=-LU~YH!^(uFbnqz{qkJ*t6BW0 zX@!wC`n2uqI2z-ow%8Riy9V^bsElI0P5!L4nhQ9VNiY&_39V7PnK0TKwHdFjHRAxT zMrgUqF#WKkdeaWp%juUTj@ujYa{RC)H&0)ISAZI;b&`^AZKmHT9m{;xmP(Z*-A8E6 z@T4j9jae0X0 zcVkVsNS+C{^{WUvy|s3w?zW5RHzs73K2onV%tlwOJqlOArlHo_V>tb2GG1%1XyN@# zD_^HAYx`UG8TXsM;b?!iaiqu8e65XhEQS19X0+2ZDX76_ zWYe%T+3un0-;<1vxw11eIbl@YP>ic7m=2bPt_60QzIAn4XngH?=Y0zY4jmj`);n)#?qJ`*@S%gt&^2a(v1oBWj-*A9st&!Sz@DcH0TSCV*d!wcoDIsXxH0==t(gtKz0k0Qk$ zB@%7!S0ZM*rDh48a*(M_UHaA$LZYb`R#XT$)@J=p#4>hCl_zuG6M2cKTvI<3UM=uO z!N`G6ihxcX8KXx0v3ld5f=eFby;N{A?rP0-QFFBi4&sJs$>#YCCYgzuT$8X$X~kJa zQnmp-t<1oy1xvxR`6QKo4~-qxAPkyRm!4WzAw%i0AJ8j^s$CQQ0q^Fd7mTkzL%bp?+(HZS2B+Ub9 z{h01qNon6A&q|UeX0!&zy9HQ@PpP8)j7%lLyp2pL#(j=F8^O&tvap(`%7%XAKSiYW zynC4h4!Y~}(^K#_lUi7yW7|_0u&2W}D^VO4pF+|!oYL50uO(%ctmlzZJKi&iS*@BA z_?xkYIgNg8V)J5Co70Cr%8UfB1e6Lf|0ZQJ`fx}YQy=}Giix~Vor%p{lf)R(Mwlsm{krLiMMOB39yWCFHv^Ng*}$ zy^`be^C3Ate+xb4lQ))t=A5p$Q+)1(RaS_qPrne6<0fk-Oy;oOjlHyls^-;o>pmsN zB9AROI?nV|vy8OW+4AB(TyhozPcDH#yvc}+X%cyL2?g2tv4D|ycnP_IpO=88kDnzJ z=kq0CxLFyE>uDw7><-NX)6%hwA?F1qunA^XLpOVKLMWDJeqjRE!stv~$aE*;A}U_; z&%~lPiIa6nwS!q?H$6hIUSk4V#Pg$1G`18>>p>>gWIZm`G+Rc_n@p^#XGdl{OjR{A zGdG2Phtmx=ANP9E7U^EDG#V18ws$C)xdHY~8cmVSUa@;(!)J0CP5wTb;aTb9Wk z8P7=QSzOw3>6^ysFrIwrIE*QGR5FmzuY?%4&icexz@&GkVnTOB!SVg_tPCc{F++2l zooUFfN%2FQkpXwA(;VH*G7G;p8LmCvnc)O`pBU-fj%Zpjj>G)jME0io1UC8{`MwD> z+#p0F6^5R2W;!T2)eML2*r#_5yFphRD-F|QUfuVHOLN@fh-t_yeB}gWyH%Wz&N54) zv)p`imWfiZK6G-i7N=W7raRe}p{Au-_FZ_KuL||OQ=L*qydDgF?xg0@)VSBo16ejS zhEbb6OYVy&(6elRPB+7iw*lPg-twWqSY>yRT$+rho=kky6T*Ep7o$J)n^Dt8Xft%? z!6(NJmc}k3bVPkmFSE(d{$`Bw6Tmrk;oql>sn3ySnC|p%hQ-d%=SsUcBAii8Zw96U ziC*{s%IPKFS;yFERL%L}j85)*_US3&KrvxseTVIC=OM_;n)g@Z{ar(~Pob2CU|um^^c=6zK3EeCLQoV6jROqfzVK%h65-V- zCd^7G+QU&OX8jxm#L(MO$V!*+*j_ZJoddz-879Q~sC=Clq(GW;=7-7F9+3iJ@{1G@ z$U9O%&_0p^%D~i9V& zE3;=+`r6h{6PKk4B=^>onhE@7f2q~vPi6rd?!jCSK!kEh|Ga<7QxYbd@Uy z-md7dd3^ESVlVBU!si6vbw#-mexG#E zxrZ+<7Ww&#S$5|^d;5xcXaMAjf+&VKAj{aWV$&Koy=3 zJw5UZ#u(l^SU}8mTkK<`Jv4R)7WfPECS$RAv}j~r!^$PG)JT1Ym5Ap&h)p4i4uv;O ztxMM_7DaC#smuQ zV~iI2AY&}=iHsB5E90#Iz4?<4!TLc|Tq@CvJ)xg6A5G+~EM~xGSwaeLdES2+7u3hT z1690az=tI3(TwY~$*&nFXzym6U|v0C6z1uSQ4y1VlRGBiUFDb*JaZU?qJFVEl+u3C zVp5`r_q@3b_l(Br-f2KeO}2TsuQV=BPwwLPugs$~@{1OvLyLkKESbIRytRCX$kS6Q z4XoOqTAUEaC|BWA3loLYf%meUIpb%olrx1=J}T#VEoU*>Yw_tLMm{FuMoKB|f;ur5sW(u!uarPZ!u(Bpe8E&P8Yot`K!~M9GuxBNMsY?!NJD+YD zW!mm4JiBH1n0CM2yNPzo<-86~rsm}rGQ;9@KKL zbD=b9RlnQMsChqhp+K^7&G@8a8rCyiKym)*0;2I!7m%WtP4P}!{#{cuXN@;y4YhQ~ z)Uat94-Y52)bwFhOD{X~?v-PIc02?0eNQr^WumQ~$U^LVuGCDlBUYHn?oJilvdEuB zwAl!wT_F=sveAM5SoDtcq$aqTp~F&hCsm1+KE@(y{5CIW@sgfM+4GKIM19m!sO~eX zW^la+JzhT79SCaH`pFn1raIQ8+3r+U?g&pHpwk!h z5qr=oIhX~t@-s@FSrVgF%^Vu?s@cM@isY3qDD~nwQ8e{}IlH#WoNe;Vl4M%dd@?OF zcecqJ&YW!`ras%0Z*%7U#J%_h88z&}mtT&TJ1K-njb<_kIy(DWSH>vw@t5J|4*e7{ zMhA2Xy7T&%vDY^mY-$!N%mZLX%iUPZBFvu%Dvak(1bMde448@8xCWySla(>kW@)M; zJuOs3m^ltq@Myck_zlcNXuJpJ7~x{Luoj;LDj0!3!N6d0;D_hj`xaz6p@+eck@y)5 z*`}y?4Bp3Jo@zZ0GBct7LC)Y_2tA$oA`FSxbAU&}fQDOtNI(H{LVA)h@Koq+F@J>- zF={`?r(LqqZ(Ov*yEcrPET0T7w?$|;@!r0nnrQ&Pk6C(h=E2bIP|3<9^mWKGtKAZM zkB2cQV=47=$m2=5dOe+pFi(g)PUjCXLrZqV^#RZ5Jcp)5+h$omi9Q1F@vvmy*$cS2 zVDVx-uM#ho_ner-NDrEv|HOnz6`5nxL_OY8ENIT7qPM2!^}0W>8Yny|n)gw1oWjQ< zH-+;`fs-2T8!_6Yv$SBF&eDSIHcg8*>MSkQ)!rCcO2~U%uvbTp3O!%@XAFbOIh#DE zF}8M~#={eM+z+2=j6^QO!XV#m`$s$X}rk8c&8S z48NH{2;MWJFz=sr@}$Z5#-n9S2t>m8t%psoLC!S;X9z?H9*cmWeQpLi?O-BE{x>~a zd*Sp!npXn85Ri1d+c^CKB9xqFYbl{*lR(AI~rt*ry>c zAb8K7Ov@0_ytygkAYOp&+HKtlTrjVS!+3M{|_XhMM((MXAWi3TL{DC!B}Btd%@WlZa1lvCnHU3+-fsE9WgCPj6$Bx+(7&eP z|L5pmE(*jx3b&X@<}H&_{^vhj9)g0>rG(4v93gZ{S2~K$mx;y7%qAHqi9%*yPa*m% z=s){M)`chv2fvl*$N&F(Z?^w8tz*{gH?h{C#K?z+{&2NU75>9tu62wVR`EY;9s4*U zwT=s2z+S0!{NLC5v#Cw0fl{}?Tf3I=Y>-ivP_Kb6k&_?dT+TrwiCC$^GA!?XxM@oe=x~O*<@_;q;?0U{J3d+pzwe$N%_p zoxd%#ck9q=v#T}nzplU8Z+1hakL&7t-uoYFB@*KXEdRgS&O0!Qq6^@k6hS&tqzMrb zr1ww+B!v=4AS9t9;c~eo2ba5Wg@Aw*0a2u=AR?e(SBi+BbRmQiAV47W5?bgrB-9YT zd3(3Jv%4>vxmo_Zzw*nQSLV%|+4myVouD~rV)&&bYZsH4RhiHV$uxI&X$d3#D5y=g zYOR&2qkTYnRYEB&QXp~kJSY_Zz89*RK_AYh;RCXPQ%u2u{@)xNL_gM# zs%3(HimN%$=vzXGKMJfLWaSzUpY;?ZdPPBkO1Svfy;wO!qV(AtQ$eB?o>v#1S9Ds^Vb<7%WB? zY0+eo-xEkc@kfDWL-rCwnHBdTc2t#k)Nlt8z`Tl><)7Mq^gP&NHIbyA7vVLn72?^y z&hMBGJ6Cm@=6)BYE9aSCQWkJ(&>VPEB@FX&r)46rpnAeqZ~i-fZHLu+o#s%Tu_P5q zKMG32R&V*Nj+r1;O^GJW-VlXh=3r8-+AuvGq^hOicy8srry;gJzFzj8I)vsU((nl( zUNffof>!>K=1-dAS7a0d;8*P5P0CDgwnI?~Lkx=4~0?UQ$ zCLiy6d=xCAu9D<=V=fZBkP6w6zfPU77k0^dN|yM|sRR>$6jUxOmwH~e^i{~E-bPvK zqc<}VIS(%_l61TlA=Vd(!aF44WuoU*tVr= z{R(2XSZdL4Ibe%T@}a@Qc<+h6NM3*7%|18YCd8)s5aB^JuMhYlHd(3V!kk8g+w4EN zd@^G>c%i%Z9zt|!u4Idonj`}fe-zj!klnz#?cojB4O%Ez@}wV;;f1v#J6xTA2B-ND zT1zF3Zqg$G#UBNgt~KKEGlta8fy|_plBb?gC88wLEie<2@zkb64?)J(N+vz_%4;5$ z3H52PDi`)WUjx}8*cm#@EI5CY!ijqro%ghsi0AbhG%>pZq4~))((%!I2BxQJ8*SO3Cx3}C zQXZNop~N2r))R6|Hf!v-Ymom1NF?(1!ZU|Y{QF*L3EAO>wfJ3-DNspLrJ5qMz%n5k zI`;W*r@w8PGU;s{or@KC7$qNS)8{i!Nea0wHIvf zEHp9k1o&O3lI0oUDH7PD7q*+7fB#!yH|ry^gt4IBGq9>;r;Grh5+5cq;7eq8k536C z{wVOeAr_yu_}EFPN``wlV*d`wiKQO}rXV+yCCBx@1~-!tDhgHZXSXwN?mJ{j8g_5RJSpAP?LMsEAd03g zbcz})@cJQo3jD|KE^r1@9NyX$R((7(XY*~)(-4ZIc{s&xdC2ZGD`M?qc$N7cMWP>0 zF|Qh8by-y(CxbLYDTXF>VV4Hk{dO74;_DOzTd7Z~y|W$$TN_C7T5>NUvTO$wT)AGkQ2T0)9H z3amk77d~`h#q~D`F$N>@pHPtOVt&`T*L(;uRzXyJjVubrZlj2g|Gp_`J7lf`Eak*_QC-rS z7F2K8ju-w-^W#7pNz>?d0$$TF57@PF-ed3pyGT=Z&G(*#oLsgqoc{<;E)I%CI##zGdmN2822q zrNYvRjXucCHA!IcM?pQ)7g^yM3nrduNXTRICDU#7MIw8AZG-sE_n&Nf-j=Z6N7<0V zB_xoZ+g-!Q#7EgI4$r6rVbr?xkBC1Cx(00!ogWM~r?w~m$5^KS!!sp7{0Ahp6!br7 zjqGo$i=EAZo6d3h{wGc-+>&`N5|-WS5if62;)64gwU5u23zK5JXJV0M!&>`Ih%6uc z8&kNwRs~aLi7}7MD*4xO@VE*2(fvsa3{nQ*vo`DvOP$(n9>5!xiT^?7wl5^Z$jH8b z5AK;K<;!-@?cvZgLQOO8xzLnQC;vNDA6+AH=El{~OHBy>!~FQ_sXUVS;tw95u5#zl z8Sv>T`O(GRTRi@S#FCMBGLJVW+^P9-$p`>p&T|4x7qODw$Xp(d>@9C4MkK@DGOYmr z0T&zDQA77Ex&!|GQGRT6TVvKYvYQNCHtIBF5YzJ|yPM+3>Sm>4(RAz6)!7hDKmHG@ zIG9#svhU=+$oYNprtfytC-hJ9qr3aX39TnN$jHt$e@nCNAoq;_CWk@WKJV#mklJy( zx2Iq6CG=1Ko389HEd3kej{-*+B)(?foO2DL`po?Q3p*L)#vwblgFdM|Dg``jR=!lH z$q?^u1}vjl<;8YTd+pR**g`F;_d(Km`7zZ7#ZE;cSW>Zrx1pN-Wq#D)E*vLLOrsrk z70&@V=jTWCjE?hOqnPLHj1PDYp7YheQ>CGR-qSIeYi5^B2bmY-M|ba!9R7-(?Ok8* z&x8EyYm^$~a6{d%N%THZR(kCx!Gji}Y)z?(*_M5gjJJ0E@JEpGF8Vhn*%jPh+quVq zd#`6~Pi!~v>S5Ru7yrk9AWZm_(BhAR<^Y(kyM3^BFX;N4{~+^9jn&EDdt7d(4`F|c zvW0;JqKJ}(7g$!Lc0Ho^@@!_X`A!@fERx);busb1UH=Ig;M#*F+i1y63 z7h&v{gsgDn=~9{OC;uF6q3mHd_;IiKxT z6u-cBg+#=&MV|>CvX%|W3^zh6L?SYH zMglTt6<9PJZ+I=+hY(jHM9&~72`K(3s4g+y#gHm@fcHDagT^!Ntc7nk#d!5FGZxOe2eSR8B-&h7s__D|Y#8aCL(5J9>2Hc;F((M~ zHoTV!dj)Ye!FU#4L9A1fFFGm9rJ%?Gx7p9)MT>TNF$(;ZBN>?AC(i{U81udJyvde`HReDaPQk zXlKbu#v}eHuxB9hy*+1ZHbk?nTCTgpTa1lEQq1#n11kvM&27^Vd0(_+HsdO1xC}Ov zMAIB2oVEm=>=emBbGF4LL2TPjG2LOtpTz8Fo*f;jl^)!3`82$gOV-c=LxVVUhwbPG zeltFY>|uw76=I8~%H6D%iLt`d2cHJkP7RAQ??bYOwNXPaf|cyjuzK6gB#s)KW-^0K zl#1QsvCa>%8z!EG&JVja%)Y`0d)&5y+yrmk_{&B3QYuAe@^(f;R?`)*@(ApFdsLJV zM=Zx0Vm8w9%JCGik-Zd&8h0rvO#HzUDR20feh!gxpUiSkXcFe#sUE_y@3BZ6*}kym zIfx^v6p@V8i!w#4pTV-q*9y6}{-xa?Y4B~yewijr2o?V}yVYYFTR5fCHPF}rCB@%n zBTWG*7Za&G8Vi`6Dx8lG$}I7H2^5`!tXz8=CY^I;f8o7(noJ~f7~wGwXUsx;`Q&e{ z^L)rk9@4PF$aFgS?pF+8~e5{W;%y-)Zu?HI)q zC-RE&c;VMb7E*d^$?cGZ9H&Vx2dT9wRK^?^vG1gZtjWj#)(I6$r7&g|)~RKu@3@oj zHO@(yMc#_}K~H%hDWDX_&O5YVgK7@Bl$&-s-6j0P)fny}Xdv)F*p%>I?geRP* zbmsM1v|jLlGYTG+i}Uc1^G(mQQ=Y-DeOAG9w*+w?7%8AG8vJ`m#7)p(hJq+OMsb%d zDWD!2JW#gWQQ)1^@-$BwnR&>H=EeJ8fE7Kj;JHuW?o$pWpe`#~vvhf3MK2&kUK_>E z;=Q`=+y!Uxi!zTK17giqgGIM!jhw#AE$z3h#*!de2>>iHRn1=})J(te%gp zVv$+Bg>&6?iexv%ynq_}@42P+L5#VfB$-H2Gn&kxFj!1nF$VF2?e{w#0zbG(6V34k z`o70%Buus4I;VqqLZx;LN|olGLJN3m4#wv zAm_-`jtefrIr5HzAy05)&o^5myHHxPF#{~*E=3_~!rhELQX=P{7)RYC@a%gukpvNP zZzfa#_$px7e(?PpF?(S@$jXPvo$n%VdTX~Vu@9fNO^j-u=m7zi3W55ihv? z=HJ4bsceiXG$&4=zEKfs@&Guug?-9TP6Xx7rWX#0Y~umT%S# za_VbyD(L|1b`RAwuIvGmt4WKccR;R3S`z0fV*U`addXq%hsRo4Z&)|saza?-Gvvfmt%F!uql4pS@6FEukiH#?4lUCpdCD9DzH@k`&8q z96=rMm`^20_Flm@AscQlN~tKmtvGaqeDP|k^wk---zrUUY%XIQ_f#Wf<@yhLvcre4 z%AhQG>8h`6vs!OC39^+{@!Vxb4i<6_N$^t za}di2G3H)@)q9oVn4?WL^|K{b7FLBieBoF!oK-8xEccbMzs*k0at>vp%uGbiSNqHXG{#`{)>}oN@QtD%7A-Q>#LHDmfZeCTxf(Ad- zXO`@1iA2gb67CDPT-DSxJ!UH+)x@BjEMfLrbq$Za-;e_(yKIQ(Mfo>*0-jex%?b(# zAYB7v%ob`JU?yUDNc_4@ci>F?x`xQ5H{|pk_r{r<;CD6EByu_xUIcXGTu;RB{5pp2 z0l%xIW`-C>o8w*aoUs!j2K-Pb4~RY*qS>kg5%GtK%_B2?2=NUK(MIm>2w(O+PZ3<(ixbe3%1urt#$9U^)ObD zm3vwu_6n%<^2x$0ptm(l?rBj-CV2hi++&al)>qRa%uYI3vswyPp?&vyp);`0Hc+$r zhwxTt5l?vQ%BkJp2@Pf1z`p%RXGT(1hmt8@&f<&gv`rW9%Y=SfjsAs5Jdku^wOL%e zo`LL8#lQYt`0l8&hu__h;4~Y#yD=jB{PnZn2pM)01u2kx!$Rivs6SZM#}mJ6x(jyS zrV64PrAPm2%=-(!y!t6Hn<<#2vgyI9J{@D06U%1?j{EK)*Md7*8e=5 zHCrf1oM&1jyEYnEoC2?JspOavx$Oko9fJCQeiwF!R!SOqCO4Yzo*voRXFs@k58i9G zR^Pa<9 zZ(9uqE`Y?R(z0-@`w>>9%`KL64NfcVP^NH^E(6)U8^uQ#VmE`C`j~`$Es;#~`|j_g0xM9-B6dPvgUhDE%)%^l?f6{b8;C9%mRfPFet@l_ z|F@TOK(ek1T3>4dXXL^v0c+Z)-}WJ_Zc0`{G-*i5EgMql*l@M~VYprDF7X^K1AEyL zWrZ=XAad?0|81UdyA&i-{K7)QgF>i+7&8aSek#1#<_Wyt>p^k)4d9RksV!73KH(<3 z-|MMhw2&dp7LMgOE5p`agiJVCL22E*MOPWbykdxE!jd~)2TlmZu{h2BxH@?tnt3$v zhjiFWddZvs(m6qgeg;^kVcydDH?xo0qk}*ZtS~T!GA(!lF;~{LrcinHZM0b z4ZgDPqoPphJiFB)=b~2zmr95IFihqI!M5aZzwniXVy0nH{K6Ze9Oxj|Ct(!==x&QsMkKK&FJ+b$wNi`RtK7Ep#LC@p1C*gXfyL{hHX zgh=|Hg3_wFjA7OaLYYt};vDFHsFFf087l?rpm*<;xm%%wUL-{^k_nhr@m|hT9^{Y> z@ur=>#9xIxbr?l;*XP56DZ^vd78bi#{BZmh#BPJka=)O^40dE)Pb?cMx_ZG)$Wo$2 z8hIGP`;C7~qV{U+sqA5bSD=J)gMJbyDvyQO$3a#qA zvm5SFOcKkpm3QU5QAAGfb6R#3dichmEI(^B^#0%z!wQ5bNrdQz3Xq1WvH%5BQ<-;s?#%p!+z+w{-CfdT7 z*blm3IM`GkOZwK3b;8`neFVJ7ECSAO)t&O}Zjd3ha#eBs0VnA}r`upTUH zYu-N%Jy@n_sk%)l#A4IS6Q89*Y?`X&a{4VcMPp^dMF$~MnTFF~Q&o>oX4ff_sZ{BF zHy2{mM>v<8iJeW>&42kkoK2={nccbG$0Bb&LS72m16j()T9!WX2#JJGnh(70Lztf+ zOx{R@*-rHMcTa=u%*dCgLkvRp)878CXTW~?sg@gV;+(CAdF1fT=ELBTGqpV4XopB= zsQq&;NHXUh0fK``0EAOH}U_QRP7*qi8)Wj<9oG=)yo1a<_h1ze2I|A8*bHuT-LS3V#^_W zp>q&h=BtS>|DH{A=X#BB~*eG%64J1t9}92e1H^zDhdg!(f?ph}h`R z(jlpE&i^4_rg|7GGZi@@^?mvK^Ke4?F<+|U(83!(;cW*s56*YLpbOYo|2rNl9g5GEqY z;;?H7Ip_F%5G{1U`(4dZH+^BJA@#Vz1MCOkCT$f(6YmYVvMgi;XMS=y8&>cSiWTB= znz(KUk!ahn;?zChO{*!6dqgCcLle@R5HZ{U#CD^b363asAWG9kcDZlp*n zFOJp2_KWUg%VxlSu}&rhnxb5kK+LfS$wUXOt-cK?>tzb(cssywzmhZDpGnL@5B z-OVw@5fk$AG0TPIESIZQ6JDHbR1nD{R~yk5$M;&;gqpkW7CQ~^G&jjC&TrVUUGS^! zH;=Sn8<>^U5I>zPMVl(4}>YhSN`05pyKMDgm>ryu90oNc4|PBHzQC zoE|Ni=@g7rGVIMx{W;6-LWOFp%!7}>EEcUoBvofHXW>fn}YWutv>wZL}4~r zl7grek99RMd;BCS?kd>hc9}&A`%z?irEDh59Hg%J%Zw_|!Ml=WPJe@)=S>_oPjUB= zl#7s2?2strF^<25{*aW}Ca`K$#y{~Fpc=JP%@LYGQjJmBX-EZlR#-XVi-lbtT8JS* z_rB_5t_2+i{p?mSxcaIir;U3t_0r*lpCVBlBODPns*_C@tBV?%z-)QQ9`bpXMd&-W zM`DsjOXl~vUqE9s(TAKKln(C|_KGZF{F1-HPUigC{fr}BX1j@hr^Lv)C0{=VjV_vxpb>~!x>@-*+1MDVp`tD~oaeNDjMgOU<>^cw8f4_p}=~JS_ zG5a3&CSv-{V%MNjb3nl(X%BR)hZm`wJ&Le8-`pdX#E>UOTw45%o zput&?=3D*)`j0LJ!?qlXY!+yGm$ygs#ZMn+GDTTs`t*xfY)qi^J7Pt?D1s2n3E@`M`ZqT zK~dqm>I{*aV6v(LIpB0*aheA_H#-6Nb)Hw7y}%9R7lxyUNVC zdIaLp1rJ5&WI%RyQNvL$9xDx#YI^5iPl8mJM4HKzAbcypv2S3v zll9AOxee!tOpzmxcY^~&ge}BC4i>V?m}Nt(ed@G`%W$^5EHcSGld4$(v$bOyON=_0 z3mUs3a_pvf7ilVyU>PF}Z{Uy$*%#Y6{=5VlyDHLL@!T52PUh2=t~m&+cTM6r;&@jN zdrxum$$~Vkd<5Zz3*LExf?RcW#aT;?5oG5qzE&tZ+lo_{oxrh>EY>clH7p9wvnp%xWUzg+WQ>^ zt7|9+1+jypKh#MAJGiT)@ZAX`@#k9cCcD6c?kPBmMPrUXSRFjdaq$9Fg0duz(V{2^ zvQv|B+jz{rsqCg?%f`V6oc8J zDa5gp5Z`wUzMBiRhQ}g_SeJj7=Dr-7K`13E1_-@So+v0SIr?E>b(8D2*F6GRo+>C@ zvt5HIYsH) zmczo3y}5nv^eot$|5vC8{NYG)jwVA^x{M_`P zF@!|5GSfv*v1LZ)fu4$MSX?B;&R=fORmgTN*XW~*gjS^0emFyl;{20hqT0;wkVe1^ejLBC1 z@t3wK;xtM) z=9NUEWFc3PG|*Zl1&zF_w&<_5NuLgQ2wJO*vM9lr*AcUkQd55rCMCRv()8Baq;o$A zUFE9aG)g#Tts&V?x0wr`!!BA?Nwc^daU2m6^Xi&MHm8GqR8x?;naD+&lWs}RDis#7 z1_$-L1re({$_g`3&l#941mjhI>&9{5)ll)A(BD^S{_H#?b9^OzdIr2^dtJ>7Y#G?R zIq#hS_G+|m`SYiMSQ8_*;3guKvYZ_ggjwLV5MnzukbPAVUlPhI9^d?GHJ&R%1C>C=*U)Mr-d0a3#I;8ftdsoYJ zhyib@S@50-CO2?c4z??;x1QP#dthBPPu&!hc_lI3J++y((1IKg;52Ot*@=iZ zzViJpVY1ZQ3Zlm?B5d4JVlROj{~arICatevhT6$XXx&c?mcQ*=AvbR{9CB&V~vad2+4C4uxp%>cdCRAeJ^#^Il*q{p`~}av+vARx@>prC59!FlB?# znWKrC$QfTSR@G+Xh5V_hn$<6SjMXRy7d@<{$hjVAU@grwEdE%Az0bTgCQ6v-)?C4h zFxX>F&KEUBE+s7HF<58|1=Af?B5WR$k(ZS@reQIA!n}PaAZE9en6NSUIUFWC=iEUo zxA&7YPPl2A=c~~%o zhJ1TtqrwQgy(70#$NvrzZll^$oUWt?yu5U*TEglajn;?Xft~aniUJ)tE##?Qykg^K zrJ*+wea0S#6LSZOMs{t^)x+LL&FI!L1Kvk<6iK8fG|^JNpT;vwhny^vk8imLp4EwB za)0xWSjOzJ%g^}`&bt&xDVX;*g1v{>HTL!nxEb#(@=WoeHV0Quj;!9WZ+7g3)$@}n z5%w|t4P0-1kk!lk*?98)3wceT zk^)zIHW#HJX6r_>(x4?(vcPw{NGz+vM(+0bUdCX1ujQA<*I@7Msvzmr0U0~H?4A7Q zPS`)XDTwfmi@|A-orzgz*jweJn|j@bx60iyR)4cI4z%ZR8se!dXIA}T{R}h4esd4H z#RX}&rcq|232WZQEH8HYZTw483REt7;9O;!GiIVM5=pl0O@7vh5PRlBv{^$*<_MoI zDH|LzuQHMy#57xX7NiZv*-9X@wAlJ~YEmN)h#_jCE*izWW!2KXPrzGxsfnDr#3tdS zmFay4x)b%*u=LU*CgH%J8VZweLe*4G{bBid|EcAKZY_NjEdBee<*gsH4PG*YDLA~n zk1&gzTyJ|8SY)_Fl21(|#Y2T&KK&_@%T6|Uj@=J?$v4_Hb{Aw{17r?opAM|v zQ!C@l1Gq06NKrmg!9^<1c(SK1gP9p4u^=`u*&r{oqrBl@!Pq zv~3aCeF}N`G__{;-4HK^$ixsb^%sh)9B-_!{u#w*y_DobNbgZ3;VU`ub8Vi=1d_>4 z|Lpc&@T#E{&lb%)i2*xZTlx+^1<@i>CWRWv3?C<%!(_49Ipo4Bfz5vXNT~V`qiFJH zK_0Md{LEH@%?>$RzUo$(9b%xE`c7cPP6$h;C+>z5LX=DmGm&O@@O>qGfE+?D;ABBr zy&S72yjNsOGSm}{G!Y&*!c#VXi^&?z$wW@7Yoo%`eF!reV+sc3y^L6e_2)&2m!ZOH zQuEx!WEsY8If!)AB4aLqbTKl`(@RVE$crqe3}n_Ivcvs$pz;Zbps^YrqCQE{j*eO^yreK|c>KPPWyuS!o__}CfZ-aR{_`RWzyA6qh@>NA7JSnt z3@TGT5@EI##5TLG%oTPdi;_kjoWB^`%Ph=eJFvV^{44mHuAe2`(Xo2Y=zu0h0R z-pmOVDjQA>&u)&5b6QE)IC+a;CSnn-Mzcvd5Yb#}qS9QLS(yGN92}4W`WvNTnH{8Y z?-->^Fk2|Ho^=)teF{F9s3vxGk?#1yxK57s#4`KBqe2h)5aMVxk&GgZH-vH3I5GVt z1auO<6&j=A*$q)VvLTg#(${Anh8^jBHLJVX89@rTGLBVum}DDEm%j~`IaW;zGTL~0 z$YE#A&h29^fSrufuwX1`SDVqr<9FD}KLzNR{~Fhdqyj|9zll zh8ReDG*>*|>p{%p&Fg=>4a5l=BD9?1CL$3#@SBfL!k#oyL$pO3ETj{RY^3Zl4au86 zvroJ1LwJ+4JaQ^iDv{MIu=vvA*1JN6JsIV3=7osQhwPXle5vxGn%6tQVC3q@ioJ{; zJlb{yv^PafBe$=lRWG04Biid?Iw4GRn5yPM=brcBzC<<`R_$R`x=+76dH||))6~3h z7^=*{LSBfh8oTZY#Ltg3EXBv_%wB-W)j#ypogmkAH7mmG3#4PzT7wnEC=lvOn;cdVSkw`{G z2dK)^dRS!WLZi@k_EU=ESx0{x)s&r;g{|V1_sc$l-C!og3OAFP4Wvbw&<>f4h^^wJ zj=@)86=zXI^%E&p$*|j))Z%A_&dak!jxELsJ^GwRp6_C?2-%}`&7%+@=V(drc`4sl z$H;q&#lP&l1fKnw$a5O(B-!)SA@q${*J75QgoyRI#IhwIC}xkwEaQihN3MfqeBoh5 z1c$>%+g2CH2@-qbII3{Nhwyf8F2x~7WWFvN$UfcV>lJy>mtdaEA&)sY^n);t4p?;& z7+=Z^@+6#tf$Yd1R9tuhZp-G2456S96v#nAZhD?p`dOHO@|8%jj|sLJN2mr-Fh>R? z=UzPN{xPt#1s+mgE7>l(^5tomovmmPcOUHRYnr3Pu=@?Na-|oC9EUryg%ZbNGemRG zbV2T{3QxB@hC8c86p4S@3Kmn_Y|Ig+ST5F*xW633ZXL$7h(8Ut4&NwvNE1|cjUnr} zD=73JtmC%|n#$DKNl3=|VVV0EAbu}VkTfkodv0u zd1(F2(I#7vm41ZHY#|tDamu>wz*$an`nb3_*eT1=DSZc=vQ~&3mt};(>S@leF@9FN zz+MV8eJ@Lx@UT)zgvZ2a!+cgI_FZz@&tkU1cgeqNnBpVQE~A|$D;&-_e9jlyPv=@Q zZ$r=RRT^@?5kzDWA8NN5{i37wt~YjQKI^Ctq5q+z!?49*bClh{)f)lHUoW3(x(lpn zwUXD@3TYoV5%ZHyHBRP%pZw_|!bb$WU1PD>`9(_0RJhGpqvr5`OMtB7%$sME;T*7* zqD2U28;+9=vZr64IwcQc=U)=Xo*+CB>SnP;aZNhIGH1)I-Pur$_*+d2vZ~80>@gIn z?*I7u;A8NO$vTPWcma_*v)Y4gV1esJ3UtL(Hj-qQ2DzOa_s%C-z}cYW(2Wsw;Vh~C zECVh@UYJ~$o8@v^|R&NstMjM4--St}{ z(JlSV@w5trkVFw;Dk<4}D*})h-nXdu4)IRt75p`?lcq ziiK`MEZpZIL^;Tv2G=bLrtuo7-mKFA- z=@Vcakr`as6{d@_IStZ57e_q|(`f4Ija>?4cj|d^*HzHPF`2-l3xtr;pyUA{9QP1n z6iJmH+D@3-F9kGlf+A2tu&)!M?Okuyy$y_$BEw?idMAZN+`^NeZH0(?ie^xPFs~J& zjT&JFAsaa@GU9o@sKD}1-^7|vVWrMc1WE{YZ6H!u-aBvsZ0fAY;Oc;a>7rRV|18i& zhKCSqB9*dH91$J4CmfzsLbzc)=V8Q|qa(?4sz`^CCqu;QMK@2qAxs%MPmy@1mtfz0 zl`&S!gzvsCP@HI?kwBy|&R~r-MHprj?k*wsr34U zc~!+EEjnE>1|!I7*MOO=6qEMa+|$`0?KKrS!ETFo8J!v^t5&fafHtQBF2N1Jbrq9* z>S89th>4FxA>y)%1w%5BhwbWw;3$H)bH@g z3Ak^*rJ_V87@RzB*RXY4lU7EU&~lq%!RJEWON7<+zbta)G}QI)s3?(6-X1~Nt`PI* z7uR4{xJ%JU`_JfngA2RAA?Kx|+x~b6_uKarRA;2sW{n~T*%6A+!c4?=*_70ua^QrP zMG<+YMPV6M#z!9u^`844j+uPyL8T__vLH8jg@)DN1utTtOWyOl__;Dx5@>HTk zn`7xMNf%0?{l|qKZ@CgB)^14P+9we0&-5R<9b|bXQ7pDZx`~M{vOF68=UJfSNfe<% zuCpbtU)taRP@c;am(@t63cAR$^YZ%JK>1(cBJlr5njH@Ec@FhKi7u3i(f7^(;y!Ly(I@HffO&xgyzk7G>+WAv@Lfg73vYi zXa-eQVb%sxRhcvB*hQ$S6qgws1gxqursAY4AjK;p!A{Bn9JwvFmyBq+_5^rf2?c`^ zgk9&zS|tx$c>>m|q)1U1E~_@MwYv6n`F>cdQXWD)=lu)Du+4QQ1EaLaFvS~rI!t1W z?{`*B0Y({$!8MN$*$oc_Ta!TNWn~5oGt}7!OZCjW1d^1KDWv_k3}Mwe7Of2ZJMM*O zRo=r$u<=aR!J>L_!W+V!+p98xat>x0ka&3U)rZ2JTLlkcBxx8&Efcfz>SM26FDG&oFryDjpD zcJ}j1!W-H*lpIp#@P41d)~tEC@i$@3YEzszof*rzCZ7Ptn-oLu?BuP=M}>G&M`lEG zecy^iM%UElLU!_&%&-^@dhdvT_B?PI;%{A=LMK|f_)6p6>&}2q>QNM~dOLE~dD^hw zV_>{ZF%o%f3#o5b9#QHt)HmzP46DW=*;fqF{_!V$pMzc+&?MT7b)hWlQ6n8F4P^>> z5=Jc=I|b3qfSeHF{MLw~n5fb-bEHHVMP|Nq2(;f=X6PQh%5*+`6&OuqhLh(V1eT%R ze_a1OXrw947@@aDYR&9*8zgB)Q>elzvqlgL4sN?O3nXc-U{DZt+d?Q4%UOhqW(%6) z;-Vmxv+CbvAAr25rIJEnm{$z3;c=J0IuBZDB~x4pl^grIzJd2cM>eCjYuHiEc*nyaUtiK?UtQ#g>y~g7{G)@& zP!)ce{R62&BwT5d2m0tJF*xNwvWSI~BTqvX(Me=DW7?9<%3|cpyO6xT#K;eC!1>`_ z6^SeNLL?e?B{UZ#>a65gNiS<2TSo5ZH{|vgx^eh=eWfd|QqY&XIv0N}`cac+Zi@4%TQ`^eOPrE)<7O zT3J05i)K>`rCtL@SDB&v+3QlRzl0miZZhKqoV{LpwWyHecc&?QF#yp?)6U(6tRje_ z&~C}B6U6`D>^&p{{J)3HctPi)$mU0cdzzj!i8e8Ie?iu4;pi2Y!N!7RisCf!e}F&G A>;M1& literal 0 HcmV?d00001 diff --git a/SDL2-2.30.5/lib/x64/SDL2main.lib b/SDL2-2.30.5/lib/x64/SDL2main.lib new file mode 100644 index 0000000000000000000000000000000000000000..1981305fc5bc2ea865b5f35d02eb0d2e9659e265 GIT binary patch literal 36644 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 literal 0 HcmV?d00001 diff --git a/SDL2-2.30.5/lib/x64/SDL2test.lib b/SDL2-2.30.5/lib/x64/SDL2test.lib new file mode 100644 index 0000000000000000000000000000000000000000..0255ad475e4deec32f313495ba1c4d3db4f51ee1 GIT binary patch literal 966202 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 z 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 WD#J+$TVB~v(y)~j_ib3Ceg7|dAV_Ke literal 0 HcmV?d00001 diff --git a/SDL2-2.0.12/sdl2-config-version.cmake.in b/SDL2-2.30.5/sdl2-config-version.cmake.in similarity index 81% rename from SDL2-2.0.12/sdl2-config-version.cmake.in rename to SDL2-2.30.5/sdl2-config-version.cmake.in index c987bc1..5c6aee4 100644 --- a/SDL2-2.0.12/sdl2-config-version.cmake.in +++ b/SDL2-2.30.5/sdl2-config-version.cmake.in @@ -1,3 +1,5 @@ +# sdl2 cmake project-config-version input for ./configure scripts + set(PACKAGE_VERSION "@SDL_VERSION@") if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION) @@ -8,4 +10,3 @@ else() set(PACKAGE_VERSION_EXACT TRUE) endif() endif() - diff --git a/SDL2-2.30.5/sdl2-config.cmake.in b/SDL2-2.30.5/sdl2-config.cmake.in new file mode 100644 index 0000000..842f826 --- /dev/null +++ b/SDL2-2.30.5/sdl2-config.cmake.in @@ -0,0 +1,222 @@ +# sdl2 cmake project-config input for ./configure script + +include(FeatureSummary) +set_package_properties(SDL2 PROPERTIES + URL "https://www.libsdl.org/" + DESCRIPTION "low level access to audio, keyboard, mouse, joystick, and graphics hardware" +) + +# Copied from `configure_package_config_file` +macro(set_and_check _var _file) + set(${_var} "${_file}") + if(NOT EXISTS "${_file}") + message(FATAL_ERROR "File or directory ${_file} referenced by variable ${_var} does not exist !") + endif() +endmacro() + +get_filename_component(CMAKE_CURRENT_LIST_DIR ${CMAKE_CURRENT_LIST_DIR} REALPATH) +get_filename_component(prefix "${CMAKE_CURRENT_LIST_DIR}/@cmake_prefix_relpath@" ABSOLUTE) + +set(exec_prefix "@exec_prefix@") +set(bindir "@bindir@") +set(libdir "@libdir@") +set(includedir "@includedir@") + +set_and_check(SDL2_PREFIX "${prefix}") +set_and_check(SDL2_EXEC_PREFIX "${exec_prefix}") +set_and_check(SDL2_BINDIR "${bindir}") +set_and_check(SDL2_INCLUDE_DIR "${includedir}/SDL2") +set_and_check(SDL2_LIBDIR "${libdir}") +set(SDL2_INCLUDE_DIRS "${includedir};${SDL2_INCLUDE_DIR}") + +set(SDL2_LIBRARIES SDL2::SDL2) +set(SDL2_STATIC_LIBRARIES SDL2::SDL2-static) +set(SDL2MAIN_LIBRARY) +set(SDL2TEST_LIBRARY SDL2::SDL2test) + +unset(prefix) +unset(exec_prefix) +unset(bindir) +unset(libdir) +unset(includedir) + +set(_sdl2_libraries_in "@SDL_LIBS@") +set(_sdl2_static_private_libs_in "@SDL_STATIC_LIBS@") + +# Convert _sdl2_libraries to list and keep only libraries + library directories +string(REGEX MATCHALL "-[lm]([-a-zA-Z0-9._]+)" _sdl2_libraries "${_sdl2_libraries_in}") +string(REGEX REPLACE "^-l" "" _sdl2_libraries "${_sdl2_libraries}") +string(REGEX REPLACE ";-l" ";" _sdl2_libraries "${_sdl2_libraries}") +string(REGEX MATCHALL "-L([-a-zA-Z0-9._/]+)" _sdl2_libdirs "${_sdl2_libraries_in}") +string(REGEX REPLACE "^-L" "" _sdl2_libdirs "${_sdl2_libdirs}") +string(REGEX REPLACE ";-L" ";" _sdl2_libdirs "${_sdl2_libdirs}") +list(APPEND _sdl2_libdirs "${SDL2_LIBDIR}") + +# Convert _sdl2_static_private_libs to list and keep only libraries + library directories +string(REGEX MATCHALL "(-[lm]([-a-zA-Z0-9._]+))|(-Wl,[^ ]*framework[^ ]*)|(-pthread)" _sdl2_static_private_libs "${_sdl2_static_private_libs_in}") +string(REGEX REPLACE "^-l" "" _sdl2_static_private_libs "${_sdl2_static_private_libs}") +string(REGEX REPLACE ";-l" ";" _sdl2_static_private_libs "${_sdl2_static_private_libs}") +string(REGEX MATCHALL "-L([-a-zA-Z0-9._/]+)" _sdl2_static_private_libdirs "${_sdl2_static_private_libs_in}") +string(REGEX REPLACE "^-L" "" _sdl2_static_private_libdirs "${_sdl2_static_private_libdirs}") +string(REGEX REPLACE ";-L" ";" _sdl2_static_private_libdirs "${_sdl2_static_private_libdirs}") + +# Set SDL2_NO_MWINDOWS to a true-ish value to not add the -mwindows link option +if(SDL2_NO_MWINDOWS) + list(REMOVE_ITEM _sdl2_libraries "-mwindows") +endif() + +if(_sdl2_libraries MATCHES ".*SDL2main.*") + list(INSERT SDL2_LIBRARIES 0 SDL2::SDL2main) + list(INSERT SDL2_STATIC_LIBRARIES 0 SDL2::SDL2main) +endif() + +set(_sdl2main_library ${SDL2_LIBDIR}/libSDL2main.a) +if(EXISTS "${_sdl2main_library}") + set(SDL2MAIN_LIBRARY SDL2::SDL2main) + if(NOT TARGET SDL2::SDL2main) + add_library(SDL2::SDL2main STATIC IMPORTED) + set_target_properties(SDL2::SDL2main + PROPERTIES + IMPORTED_LOCATION "${_sdl2main_library}" + COMPATIBLE_INTERFACE_STRING "SDL_VERSION" + INTERFACE_SDL_VERSION "SDL2" + ) + if(WIN32) + # INTERFACE_LINK_OPTIONS needs CMake 3.13 + cmake_minimum_required(VERSION 3.13) + # Mark WinMain/WinMain@16 as undefined, such that it will be withheld by the linker. + if(CMAKE_SIZEOF_VOID_P EQUAL 4) + set_target_properties(SDL2::SDL2main + PROPERTIES + INTERFACE_LINK_OPTIONS "$<$,EXECUTABLE>:-Wl,--undefined=_WinMain@16>" + ) + else() + set_target_properties(SDL2::SDL2main + PROPERTIES + INTERFACE_LINK_OPTIONS "$<$,EXECUTABLE>:-Wl,--undefined=WinMain>" + ) + endif() + endif() + endif() + set(SDL2_SDL2main_FOUND TRUE) +else() + set(SDL2_SDL2main_FOUND FALSE) +endif() +unset(_sdl2main_library) + +# Remove SDL2 since this is the "central" library +# Remove SDL2main since this will be provided by SDL2::SDL2main (if available) +# Remove mingw32 and cygwin since these are not needed when using `-Wl,--undefined,WinMain` +set(_sdl2_link_libraries ${_sdl2_libraries}) +list(REMOVE_ITEM _sdl2_link_libraries SDL2 SDL2main mingw32 cygwin) + +if(WIN32) + set(_sdl2_implib "${SDL2_LIBDIR}/libSDL2.dll.a") + set(_sdl2_dll "${SDL2_BINDIR}/SDL2.dll") + if(EXISTS "${_sdl2_implib}" AND EXISTS "${_sdl2_dll}") + if(NOT TARGET SDL2::SDL2) + add_library(SDL2::SDL2 SHARED IMPORTED) + set_target_properties(SDL2::SDL2 PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIR}" + INTERFACE_LINK_LIBRARIES "${_sdl2_link_libraries}" + INTERFACE_LINK_DIRECTORIES "${_sdl2_libdirs}" + IMPORTED_LINK_INTERFACE_LANGUAGES "C" + IMPORTED_IMPLIB "${_sdl2_implib}" + IMPORTED_LOCATION "${_sdl2_dll}" + COMPATIBLE_INTERFACE_STRING "SDL_VERSION" + INTERFACE_SDL_VERSION "SDL2" + ) + endif() + set(SDL2_SDL2_FOUND TRUE) + else() + set(SDL2_SDL2_FOUND FALSE) + endif() + unset(_sdl2_implib) + unset(_sdl2_dll) +else() + set(_sdl2_shared "${SDL2_LIBDIR}/libSDL2${CMAKE_SHARED_LIBRARY_SUFFIX}") + if(EXISTS "${_sdl2_shared}") + if(NOT TARGET SDL2::SDL2) + add_library(SDL2::SDL2 SHARED IMPORTED) + set_target_properties(SDL2::SDL2 PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIR}" + INTERFACE_LINK_LIBRARIES "${_sdl2_link_libraries}" + INTERFACE_LINK_DIRECTORIES "${_sdl2_libdirs}" + IMPORTED_LINK_INTERFACE_LANGUAGES "C" + IMPORTED_LOCATION "${_sdl2_shared}" + COMPATIBLE_INTERFACE_STRING "SDL_VERSION" + INTERFACE_SDL_VERSION "SDL2" + ) + endif() + set(SDL2_SDL2_FOUND TRUE) + else() + set(SDL2_SDL2_FOUND FALSE) + endif() + unset(_sdl2_shared) +endif() + +set(_sdl2_static "${SDL2_LIBDIR}/libSDL2.a") +if(EXISTS "${_sdl2_static}") + if(NOT TARGET SDL2::SDL2-static) + add_library(SDL2::SDL2-static STATIC IMPORTED) + set_target_properties(SDL2::SDL2-static + PROPERTIES + IMPORTED_LOCATION "${_sdl2_static}" + INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIR}" + INTERFACE_LINK_LIBRARIES "${_sdl2_link_libraries};${_sdl2_static_private_libs}" + INTERFACE_LINK_DIRECTORIES "${_sdl2_libdirs};${_sdl2_static_private_libdirs}" + IMPORTED_LINK_INTERFACE_LANGUAGES "C" + COMPATIBLE_INTERFACE_STRING "SDL_VERSION" + INTERFACE_SDL_VERSION "SDL2" + ) + endif() + set(SDL2_SDL2-static_FOUND TRUE) +else() + set(SDL2_SDL2-static_FOUND FALSE) +endif() +unset(_sdl2_static) + +unset(_sdl2_link_libraries) + +set(_sdl2test_library "${SDL2_LIBDIR}/libSDL2_test.a") +if(EXISTS "${_sdl2test_library}") + if(NOT TARGET SDL2::SDL2test) + add_library(SDL2::SDL2test STATIC IMPORTED) + set_target_properties(SDL2::SDL2test + PROPERTIES + IMPORTED_LOCATION "${_sdl2test_library}" + INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIR}" + IMPORTED_LINK_INTERFACE_LANGUAGES "C" + COMPATIBLE_INTERFACE_STRING "SDL_VERSION" + INTERFACE_SDL_VERSION "SDL2" + ) + endif() + set(SDL2_SDL2test_FOUND TRUE) +else() + set(SDL2_SDL2test_FOUND FALSE) +endif() +unset(_sdl2test_library) + +# Copied from `configure_package_config_file` +macro(check_required_components _NAME) + foreach(comp ${${_NAME}_FIND_COMPONENTS}) + if(NOT ${_NAME}_${comp}_FOUND) + if(${_NAME}_FIND_REQUIRED_${comp}) + set(${_NAME}_FOUND FALSE) + endif() + endif() + endforeach() +endmacro() + +check_required_components(SDL2) + +# Create SDL2::SDL2 alias for static-only builds +if(TARGET SDL2::SDL2-static AND NOT TARGET SDL2::SDL2) + if(CMAKE_VERSION VERSION_LESS "3.18") + # FIXME: Aliasing local targets is not supported on CMake < 3.18, so make it global. + add_library(SDL2::SDL2 INTERFACE IMPORTED) + set_target_properties(SDL2::SDL2 PROPERTIES INTERFACE_LINK_LIBRARIES "SDL2::SDL2-static") + else() + add_library(SDL2::SDL2 ALIAS SDL2::SDL2-static) + endif() +endif() diff --git a/SDL2-2.0.12/sdl2-config.in b/SDL2-2.30.5/sdl2-config.in similarity index 73% rename from SDL2-2.0.12/sdl2-config.in rename to SDL2-2.30.5/sdl2-config.in index 254a345..f6eca76 100644 --- a/SDL2-2.0.12/sdl2-config.in +++ b/SDL2-2.30.5/sdl2-config.in @@ -1,6 +1,10 @@ #!/bin/sh -prefix=@prefix@ +# Get the canonical path of the folder containing this script +bindir=$(cd -P -- "$(dirname -- "$0")" && printf '%s\n' "$(pwd -P)") + +# Calculate the canonical path of the prefix, relative to the folder of this script +prefix=$(cd -P -- "$bindir/@bin_prefix_relpath@" && printf '%s\n' "$(pwd -P)") exec_prefix=@exec_prefix@ exec_prefix_set=no libdir=@libdir@ @@ -49,7 +53,8 @@ while test $# -gt 0; do @ENABLE_SHARED_TRUE@ ;; @ENABLE_STATIC_TRUE@@ENABLE_SHARED_TRUE@ --static-libs) @ENABLE_STATIC_TRUE@@ENABLE_SHARED_FALSE@ --libs|--static-libs) -@ENABLE_STATIC_TRUE@ echo -L@libdir@ @SDL_RLD_FLAGS@ @SDL_STATIC_LIBS@ +@ENABLE_STATIC_TRUE@ sdl_static_libs=$(echo "@SDL_LIBS@ @SDL_STATIC_LIBS@" | sed -E "s#-lSDL2[ $]#$libdir/libSDL2.a #g") +@ENABLE_STATIC_TRUE@ echo -L@libdir@ $sdl_static_libs @ENABLE_STATIC_TRUE@ ;; *) echo "${usage}" 1>&2 diff --git a/SDL2-2.0.12/sdl2.m4 b/SDL2-2.30.5/sdl2.m4 similarity index 89% rename from SDL2-2.0.12/sdl2.m4 rename to SDL2-2.30.5/sdl2.m4 index 0a73bc7..274753b 100644 --- a/SDL2-2.0.12/sdl2.m4 +++ b/SDL2-2.30.5/sdl2.m4 @@ -7,14 +7,17 @@ # # Changelog: # * also look for SDL2.framework under Mac OS X +# * removed HP/UX 9 support. +# * updated for newer autoconf. +# * (v3) use $PKG_CONFIG for pkg-config cross-compiling support -# serial 1 +# serial 3 dnl AM_PATH_SDL2([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) dnl Test for SDL, and define SDL_CFLAGS and SDL_LIBS dnl AC_DEFUN([AM_PATH_SDL2], -[dnl +[dnl dnl Get the cflags and libraries from the sdl2-config script dnl AC_ARG_WITH(sdl-prefix,[ --with-sdl-prefix=PFX Prefix where SDL is installed (optional)], @@ -52,7 +55,7 @@ AC_ARG_VAR(SDL2_FRAMEWORK, [Path to SDL2.framework]) if test "x$sdl_pc" = xyes ; then no_sdl="" - SDL2_CONFIG="pkg-config sdl2" + SDL2_CONFIG="$PKG_CONFIG sdl2" else as_save_PATH="$PATH" if test "x$prefix" != xNONE && test "$cross_compiling" != yes; then @@ -68,8 +71,8 @@ AC_ARG_VAR(SDL2_FRAMEWORK, [Path to SDL2.framework]) sdl_framework=$SDL2_FRAMEWORK else for d in / ~/ /System/; do - if test -d "$dLibrary/Frameworks/SDL2.framework"; then - sdl_framework="$dLibrary/Frameworks/SDL2.framework" + if test -d "${d}Library/Frameworks/SDL2.framework"; then + sdl_framework="${d}Library/Frameworks/SDL2.framework" fi done fi @@ -109,41 +112,19 @@ dnl Now check if the installed SDL is sufficiently new. (Also sanity dnl checks the results of sdl2-config to some extent dnl rm -f conf.sdltest - AC_TRY_RUN([ + AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include #include -#include #include "SDL.h" -char* -my_strdup (char *str) -{ - char *new_str; - - if (str) - { - new_str = (char *)malloc ((strlen (str) + 1) * sizeof(char)); - strcpy (new_str, str); - } - else - new_str = NULL; - - return new_str; -} - int main (int argc, char *argv[]) { int major, minor, micro; - char *tmp_version; + FILE *fp = fopen("conf.sdltest", "w"); - /* This hangs on some systems (?) - system ("touch conf.sdltest"); - */ - { FILE *fp = fopen("conf.sdltest", "a"); if ( fp ) fclose(fp); } + if (fp) fclose(fp); - /* HP/UX 9 (%@#!) writes to sscanf strings */ - tmp_version = my_strdup("$min_sdl_version"); - if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { + if (sscanf("$min_sdl_version", "%d.%d.%d", &major, &minor, µ) != 3) { printf("%s, bad version string\n", "$min_sdl_version"); exit(1); } @@ -166,7 +147,7 @@ int main (int argc, char *argv[]) } } -],, no_sdl=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) +]])], [], [no_sdl=yes], [echo $ac_n "cross compiling; assumed OK... $ac_c"]) CFLAGS="$ac_save_CFLAGS" CXXFLAGS="$ac_save_CXXFLAGS" LIBS="$ac_save_LIBS" @@ -197,7 +178,7 @@ int main (int argc, char *argv[]) CFLAGS="$CFLAGS $SDL_CFLAGS" CXXFLAGS="$CXXFLAGS $SDL_CFLAGS" LIBS="$LIBS $SDL_LIBS" - AC_TRY_LINK([ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include #include "SDL.h" @@ -205,7 +186,7 @@ int main(int argc, char *argv[]) { return 0; } #undef main #define main K_and_R_C_main -], [ return 0; ], +]], [[ return 0; ]])], [ echo "*** The test program compiled, but did not run. This usually means" echo "*** that the run-time linker is not finding SDL or finding the wrong" echo "*** version of SDL. If it is not finding SDL, you'll need to set your" diff --git a/SDL2-2.0.12/sdl2.pc.in b/SDL2-2.30.5/sdl2.pc.in similarity index 66% rename from SDL2-2.0.12/sdl2.pc.in rename to SDL2-2.30.5/sdl2.pc.in index b11667d..23a1d69 100644 --- a/SDL2-2.0.12/sdl2.pc.in +++ b/SDL2-2.30.5/sdl2.pc.in @@ -8,8 +8,7 @@ includedir=@includedir@ Name: sdl2 Description: Simple DirectMedia Layer is a cross-platform multimedia library designed to provide low level access to audio, keyboard, mouse, joystick, 3D hardware via OpenGL, and 2D video framebuffer. Version: @SDL_VERSION@ -Requires: +Requires.private: @PKGCONFIG_DEPENDS@ Conflicts: -Libs: -L${libdir} @SDL_RLD_FLAGS@ @SDL_LIBS@ -Libs.private: @SDL_STATIC_LIBS@ -Cflags: -I${includedir}/SDL2 @SDL_CFLAGS@ +Libs: -L${libdir} @SDL_RLD_FLAGS@ @SDL_LIBS@ @PKGCONFIG_LIBS_PRIV@ @SDL_STATIC_LIBS@ +Cflags: -I${includedir} -I${includedir}/SDL2 @SDL_CFLAGS@ diff --git a/SDL2-2.30.5/src/SDL.c b/SDL2-2.30.5/src/SDL.c new file mode 100644 index 0000000..7065fe7 --- /dev/null +++ b/SDL2-2.30.5/src/SDL.c @@ -0,0 +1,673 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#if defined(__WIN32__) || defined(__GDK__) +#include "core/windows/SDL_windows.h" +#elif defined(__OS2__) +#include /* _exit() */ +#elif !defined(__WINRT__) +#include /* _exit(), etc. */ +#endif +#if defined(__OS2__) +#include "core/os2/SDL_os2.h" +#ifdef SDL_THREAD_OS2 +#include "thread/os2/SDL_systls_c.h" +#endif +#endif + +/* this checks for HAVE_DBUS_DBUS_H internally. */ +#include "core/linux/SDL_dbus.h" + +#if defined(__EMSCRIPTEN__) +#include +#endif + +/* Initialization code for SDL */ + +#include "SDL.h" +#include "SDL_bits.h" +#include "SDL_revision.h" +#include "SDL_assert_c.h" +#include "SDL_log_c.h" +#include "events/SDL_events_c.h" +#include "haptic/SDL_haptic_c.h" +#include "joystick/SDL_joystick_c.h" +#include "sensor/SDL_sensor_c.h" + +/* Initialization/Cleanup routines */ +#ifndef SDL_TIMERS_DISABLED +#include "timer/SDL_timer_c.h" +#endif +#ifdef SDL_VIDEO_DRIVER_WINDOWS +extern int SDL_HelperWindowCreate(void); +extern int SDL_HelperWindowDestroy(void); +#endif + +#ifdef SDL_BUILD_MAJOR_VERSION +SDL_COMPILE_TIME_ASSERT(SDL_BUILD_MAJOR_VERSION, + SDL_MAJOR_VERSION == SDL_BUILD_MAJOR_VERSION); +SDL_COMPILE_TIME_ASSERT(SDL_BUILD_MINOR_VERSION, + SDL_MINOR_VERSION == SDL_BUILD_MINOR_VERSION); +SDL_COMPILE_TIME_ASSERT(SDL_BUILD_MICRO_VERSION, + SDL_PATCHLEVEL == SDL_BUILD_MICRO_VERSION); +#endif + +SDL_COMPILE_TIME_ASSERT(SDL_MAJOR_VERSION_min, SDL_MAJOR_VERSION >= 0); +/* Limited only by the need to fit in SDL_version */ +SDL_COMPILE_TIME_ASSERT(SDL_MAJOR_VERSION_max, SDL_MAJOR_VERSION <= 255); + +SDL_COMPILE_TIME_ASSERT(SDL_MINOR_VERSION_min, SDL_MINOR_VERSION >= 0); +/* Limited only by the need to fit in SDL_version */ +SDL_COMPILE_TIME_ASSERT(SDL_MINOR_VERSION_max, SDL_MINOR_VERSION <= 255); + +SDL_COMPILE_TIME_ASSERT(SDL_PATCHLEVEL_min, SDL_PATCHLEVEL >= 0); +/* Limited by its encoding in SDL_VERSIONNUM and in the ABI versions */ +SDL_COMPILE_TIME_ASSERT(SDL_PATCHLEVEL_max, SDL_PATCHLEVEL <= 99); + +/* This is not declared in any header, although it is shared between some + parts of SDL, because we don't want anything calling it without an + extremely good reason. */ +extern SDL_NORETURN void SDL_ExitProcess(int exitcode); +SDL_NORETURN void SDL_ExitProcess(int exitcode) +{ +#if defined(__WIN32__) || defined(__GDK__) + /* "if you do not know the state of all threads in your process, it is + better to call TerminateProcess than ExitProcess" + https://msdn.microsoft.com/en-us/library/windows/desktop/ms682658(v=vs.85).aspx */ + TerminateProcess(GetCurrentProcess(), exitcode); + /* MingW doesn't have TerminateProcess marked as noreturn, so add an + ExitProcess here that will never be reached but make MingW happy. */ + ExitProcess(exitcode); +#elif defined(__EMSCRIPTEN__) + emscripten_cancel_main_loop(); /* this should "kill" the app. */ + emscripten_force_exit(exitcode); /* this should "kill" the app. */ + exit(exitcode); +#elif defined(__HAIKU__) /* Haiku has _Exit, but it's not marked noreturn. */ + _exit(exitcode); +#elif defined(HAVE__EXIT) /* Upper case _Exit() */ + _Exit(exitcode); +#else + _exit(exitcode); +#endif +} + +/* The initialized subsystems */ +#ifdef SDL_MAIN_NEEDED +static SDL_bool SDL_MainIsReady = SDL_FALSE; +#else +static SDL_bool SDL_MainIsReady = SDL_TRUE; +#endif +static SDL_bool SDL_bInMainQuit = SDL_FALSE; +static Uint8 SDL_SubsystemRefCount[32]; + +/* Private helper to increment a subsystem's ref counter. */ +static void SDL_PrivateSubsystemRefCountIncr(Uint32 subsystem) +{ + const int subsystem_index = SDL_MostSignificantBitIndex32(subsystem); + SDL_assert((subsystem_index < 0) || (SDL_SubsystemRefCount[subsystem_index] < 255)); + if (subsystem_index >= 0) { + ++SDL_SubsystemRefCount[subsystem_index]; + } +} + +/* Private helper to decrement a subsystem's ref counter. */ +static void SDL_PrivateSubsystemRefCountDecr(Uint32 subsystem) +{ + const int subsystem_index = SDL_MostSignificantBitIndex32(subsystem); + if ((subsystem_index >= 0) && (SDL_SubsystemRefCount[subsystem_index] > 0)) { + --SDL_SubsystemRefCount[subsystem_index]; + } +} + +/* Private helper to check if a system needs init. */ +static SDL_bool SDL_PrivateShouldInitSubsystem(Uint32 subsystem) +{ + const int subsystem_index = SDL_MostSignificantBitIndex32(subsystem); + SDL_assert((subsystem_index < 0) || (SDL_SubsystemRefCount[subsystem_index] < 255)); + return ((subsystem_index >= 0) && (SDL_SubsystemRefCount[subsystem_index] == 0)) ? SDL_TRUE : SDL_FALSE; +} + +/* Private helper to check if a system needs to be quit. */ +static SDL_bool SDL_PrivateShouldQuitSubsystem(Uint32 subsystem) +{ + const int subsystem_index = SDL_MostSignificantBitIndex32(subsystem); + if ((subsystem_index >= 0) && (SDL_SubsystemRefCount[subsystem_index] == 0)) { + return SDL_FALSE; + } + + /* If we're in SDL_Quit, we shut down every subsystem, even if refcount + * isn't zero. + */ + return (((subsystem_index >= 0) && (SDL_SubsystemRefCount[subsystem_index] == 1)) || SDL_bInMainQuit) ? SDL_TRUE : SDL_FALSE; +} + +/* Private helper to either increment's existing ref counter, + * or fully init a new subsystem. */ +static SDL_bool SDL_PrivateInitOrIncrSubsystem(Uint32 subsystem) +{ + int subsystem_index = SDL_MostSignificantBitIndex32(subsystem); + SDL_assert((subsystem_index < 0) || (SDL_SubsystemRefCount[subsystem_index] < 255)); + if (subsystem_index < 0) { + return SDL_FALSE; + } + if (SDL_SubsystemRefCount[subsystem_index] > 0) { + ++SDL_SubsystemRefCount[subsystem_index]; + return SDL_TRUE; + } + return SDL_InitSubSystem(subsystem) == 0; +} + +void SDL_SetMainReady(void) +{ + SDL_MainIsReady = SDL_TRUE; +} + +int SDL_InitSubSystem(Uint32 flags) +{ + Uint32 flags_initialized = 0; + + if (!SDL_MainIsReady) { + return SDL_SetError("Application didn't initialize properly, did you include SDL_main.h in the file containing your main() function?"); + } + + SDL_LogInit(); + + /* Clear the error message */ + SDL_ClearError(); + +#ifdef SDL_USE_LIBDBUS + SDL_DBus_Init(); +#endif + +#ifdef SDL_THREAD_OS2 + SDL_OS2TLSAlloc(); /* thread/os2/SDL_systls.c */ +#endif + +#ifdef SDL_VIDEO_DRIVER_WINDOWS + if (flags & (SDL_INIT_HAPTIC | SDL_INIT_JOYSTICK)) { + if (SDL_HelperWindowCreate() < 0) { + goto quit_and_error; + } + } +#endif + +#ifndef SDL_TIMERS_DISABLED + SDL_TicksInit(); +#endif + + /* Initialize the event subsystem */ + if (flags & SDL_INIT_EVENTS) { +#ifndef SDL_EVENTS_DISABLED + if (SDL_PrivateShouldInitSubsystem(SDL_INIT_EVENTS)) { + if (SDL_EventsInit() < 0) { + goto quit_and_error; + } + } + SDL_PrivateSubsystemRefCountIncr(SDL_INIT_EVENTS); + flags_initialized |= SDL_INIT_EVENTS; +#else + SDL_SetError("SDL not built with events support"); + goto quit_and_error; +#endif + } + + /* Initialize the timer subsystem */ + if (flags & SDL_INIT_TIMER) { +#if !defined(SDL_TIMERS_DISABLED) && !defined(SDL_TIMER_DUMMY) + if (SDL_PrivateShouldInitSubsystem(SDL_INIT_TIMER)) { + if (SDL_TimerInit() < 0) { + goto quit_and_error; + } + } + SDL_PrivateSubsystemRefCountIncr(SDL_INIT_TIMER); + flags_initialized |= SDL_INIT_TIMER; +#else + SDL_SetError("SDL not built with timer support"); + goto quit_and_error; +#endif + } + + /* Initialize the video subsystem */ + if (flags & SDL_INIT_VIDEO) { +#ifndef SDL_VIDEO_DISABLED + if (SDL_PrivateShouldInitSubsystem(SDL_INIT_VIDEO)) { + /* video implies events */ + if (!SDL_PrivateInitOrIncrSubsystem(SDL_INIT_EVENTS)) { + goto quit_and_error; + } + + if (SDL_VideoInit(NULL) < 0) { + goto quit_and_error; + } + } + SDL_PrivateSubsystemRefCountIncr(SDL_INIT_VIDEO); + flags_initialized |= SDL_INIT_VIDEO; +#else + SDL_SetError("SDL not built with video support"); + goto quit_and_error; +#endif + } + + /* Initialize the audio subsystem */ + if (flags & SDL_INIT_AUDIO) { +#ifndef SDL_AUDIO_DISABLED + if (SDL_PrivateShouldInitSubsystem(SDL_INIT_AUDIO)) { + /* audio implies events */ + if (!SDL_PrivateInitOrIncrSubsystem(SDL_INIT_EVENTS)) { + goto quit_and_error; + } + + if (SDL_AudioInit(NULL) < 0) { + goto quit_and_error; + } + } + SDL_PrivateSubsystemRefCountIncr(SDL_INIT_AUDIO); + flags_initialized |= SDL_INIT_AUDIO; +#else + SDL_SetError("SDL not built with audio support"); + goto quit_and_error; +#endif + } + + /* Initialize the joystick subsystem */ + if (flags & SDL_INIT_JOYSTICK) { +#ifndef SDL_JOYSTICK_DISABLED + if (SDL_PrivateShouldInitSubsystem(SDL_INIT_JOYSTICK)) { + /* joystick implies events */ + if (!SDL_PrivateInitOrIncrSubsystem(SDL_INIT_EVENTS)) { + goto quit_and_error; + } + + if (SDL_JoystickInit() < 0) { + goto quit_and_error; + } + } + SDL_PrivateSubsystemRefCountIncr(SDL_INIT_JOYSTICK); + flags_initialized |= SDL_INIT_JOYSTICK; +#else + SDL_SetError("SDL not built with joystick support"); + goto quit_and_error; +#endif + } + + if (flags & SDL_INIT_GAMECONTROLLER) { +#ifndef SDL_JOYSTICK_DISABLED + if (SDL_PrivateShouldInitSubsystem(SDL_INIT_GAMECONTROLLER)) { + /* game controller implies joystick */ + if (!SDL_PrivateInitOrIncrSubsystem(SDL_INIT_JOYSTICK)) { + goto quit_and_error; + } + + if (SDL_GameControllerInit() < 0) { + goto quit_and_error; + } + } + SDL_PrivateSubsystemRefCountIncr(SDL_INIT_GAMECONTROLLER); + flags_initialized |= SDL_INIT_GAMECONTROLLER; +#else + SDL_SetError("SDL not built with joystick support"); + goto quit_and_error; +#endif + } + + /* Initialize the haptic subsystem */ + if (flags & SDL_INIT_HAPTIC) { +#ifndef SDL_HAPTIC_DISABLED + if (SDL_PrivateShouldInitSubsystem(SDL_INIT_HAPTIC)) { + if (SDL_HapticInit() < 0) { + goto quit_and_error; + } + } + SDL_PrivateSubsystemRefCountIncr(SDL_INIT_HAPTIC); + flags_initialized |= SDL_INIT_HAPTIC; +#else + SDL_SetError("SDL not built with haptic (force feedback) support"); + goto quit_and_error; +#endif + } + + /* Initialize the sensor subsystem */ + if (flags & SDL_INIT_SENSOR) { +#ifndef SDL_SENSOR_DISABLED + if (SDL_PrivateShouldInitSubsystem(SDL_INIT_SENSOR)) { + if (SDL_SensorInit() < 0) { + goto quit_and_error; + } + } + SDL_PrivateSubsystemRefCountIncr(SDL_INIT_SENSOR); + flags_initialized |= SDL_INIT_SENSOR; +#else + SDL_SetError("SDL not built with sensor support"); + goto quit_and_error; +#endif + } + + (void)flags_initialized; /* make static analysis happy, since this only gets used in error cases. */ + + return 0; + +quit_and_error: + SDL_QuitSubSystem(flags_initialized); + return -1; +} + +int SDL_Init(Uint32 flags) +{ + return SDL_InitSubSystem(flags); +} + +void SDL_QuitSubSystem(Uint32 flags) +{ +#if defined(__OS2__) +#ifdef SDL_THREAD_OS2 + SDL_OS2TLSFree(); /* thread/os2/SDL_systls.c */ +#endif + SDL_OS2Quit(); +#endif + + /* Shut down requested initialized subsystems */ +#ifndef SDL_SENSOR_DISABLED + if (flags & SDL_INIT_SENSOR) { + if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_SENSOR)) { + SDL_SensorQuit(); + } + SDL_PrivateSubsystemRefCountDecr(SDL_INIT_SENSOR); + } +#endif + +#ifndef SDL_JOYSTICK_DISABLED + if (flags & SDL_INIT_GAMECONTROLLER) { + if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_GAMECONTROLLER)) { + SDL_GameControllerQuit(); + /* game controller implies joystick */ + SDL_QuitSubSystem(SDL_INIT_JOYSTICK); + } + SDL_PrivateSubsystemRefCountDecr(SDL_INIT_GAMECONTROLLER); + } + + if (flags & SDL_INIT_JOYSTICK) { + if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_JOYSTICK)) { + SDL_JoystickQuit(); + /* joystick implies events */ + SDL_QuitSubSystem(SDL_INIT_EVENTS); + } + SDL_PrivateSubsystemRefCountDecr(SDL_INIT_JOYSTICK); + } +#endif + +#ifndef SDL_HAPTIC_DISABLED + if (flags & SDL_INIT_HAPTIC) { + if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_HAPTIC)) { + SDL_HapticQuit(); + } + SDL_PrivateSubsystemRefCountDecr(SDL_INIT_HAPTIC); + } +#endif + +#ifndef SDL_AUDIO_DISABLED + if (flags & SDL_INIT_AUDIO) { + if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_AUDIO)) { + SDL_AudioQuit(); + /* audio implies events */ + SDL_QuitSubSystem(SDL_INIT_EVENTS); + } + SDL_PrivateSubsystemRefCountDecr(SDL_INIT_AUDIO); + } +#endif + +#ifndef SDL_VIDEO_DISABLED + if (flags & SDL_INIT_VIDEO) { + if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_VIDEO)) { + SDL_VideoQuit(); + /* video implies events */ + SDL_QuitSubSystem(SDL_INIT_EVENTS); + } + SDL_PrivateSubsystemRefCountDecr(SDL_INIT_VIDEO); + } +#endif + +#if !defined(SDL_TIMERS_DISABLED) && !defined(SDL_TIMER_DUMMY) + if (flags & SDL_INIT_TIMER) { + if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_TIMER)) { + SDL_TimerQuit(); + } + SDL_PrivateSubsystemRefCountDecr(SDL_INIT_TIMER); + } +#endif + +#ifndef SDL_EVENTS_DISABLED + if (flags & SDL_INIT_EVENTS) { + if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_EVENTS)) { + SDL_EventsQuit(); + } + SDL_PrivateSubsystemRefCountDecr(SDL_INIT_EVENTS); + } +#endif +} + +Uint32 SDL_WasInit(Uint32 flags) +{ + int i; + int num_subsystems = SDL_arraysize(SDL_SubsystemRefCount); + Uint32 initialized = 0; + + /* Fast path for checking one flag */ + if (SDL_HasExactlyOneBitSet32(flags)) { + int subsystem_index = SDL_MostSignificantBitIndex32(flags); + return SDL_SubsystemRefCount[subsystem_index] ? flags : 0; + } + + if (!flags) { + flags = SDL_INIT_EVERYTHING; + } + + num_subsystems = SDL_min(num_subsystems, SDL_MostSignificantBitIndex32(flags) + 1); + + /* Iterate over each bit in flags, and check the matching subsystem. */ + for (i = 0; i < num_subsystems; ++i) { + if ((flags & 1) && SDL_SubsystemRefCount[i] > 0) { + initialized |= (1 << i); + } + + flags >>= 1; + } + + return initialized; +} + +void SDL_Quit(void) +{ + SDL_bInMainQuit = SDL_TRUE; + + /* Quit all subsystems */ +#ifdef SDL_VIDEO_DRIVER_WINDOWS + SDL_HelperWindowDestroy(); +#endif + SDL_QuitSubSystem(SDL_INIT_EVERYTHING); + +#ifndef SDL_TIMERS_DISABLED + SDL_TicksQuit(); +#endif + +#ifdef SDL_USE_LIBDBUS + SDL_DBus_Quit(); +#endif + + SDL_ClearHints(); + SDL_AssertionsQuit(); + + SDL_LogQuit(); + + /* Now that every subsystem has been quit, we reset the subsystem refcount + * and the list of initialized subsystems. + */ + SDL_memset(SDL_SubsystemRefCount, 0x0, sizeof(SDL_SubsystemRefCount)); + + SDL_TLSCleanup(); + + SDL_bInMainQuit = SDL_FALSE; +} + +/* Get the library version number */ +void SDL_GetVersion(SDL_version *ver) +{ + static SDL_bool check_hint = SDL_TRUE; + static SDL_bool legacy_version = SDL_FALSE; + + if (!ver) { + return; + } + + SDL_VERSION(ver); + + if (check_hint) { + check_hint = SDL_FALSE; + legacy_version = SDL_GetHintBoolean("SDL_LEGACY_VERSION", SDL_FALSE); + } + + if (legacy_version) { + /* Prior to SDL 2.24.0, the patch version was incremented with every release */ + ver->patch = ver->minor; + ver->minor = 0; + } +} + +/* Get the library source revision */ +const char *SDL_GetRevision(void) +{ + return SDL_REVISION; +} + +/* Get the library source revision number */ +int SDL_GetRevisionNumber(void) +{ + return 0; /* doesn't make sense without Mercurial. */ +} + +/* Get the name of the platform */ +const char *SDL_GetPlatform(void) +{ +#if defined(__AIX__) + return "AIX"; +#elif defined(__ANDROID__) + return "Android"; +#elif defined(__BSDI__) + return "BSDI"; +#elif defined(__DREAMCAST__) + return "Dreamcast"; +#elif defined(__EMSCRIPTEN__) + return "Emscripten"; +#elif defined(__FREEBSD__) + return "FreeBSD"; +#elif defined(__HAIKU__) + return "Haiku"; +#elif defined(__HPUX__) + return "HP-UX"; +#elif defined(__IRIX__) + return "Irix"; +#elif defined(__LINUX__) + return "Linux"; +#elif defined(__MINT__) + return "Atari MiNT"; +#elif defined(__MACOS__) + return "MacOS Classic"; +#elif defined(__MACOSX__) + return "Mac OS X"; +#elif defined(__NACL__) + return "NaCl"; +#elif defined(__NETBSD__) + return "NetBSD"; +#elif defined(__OPENBSD__) + return "OpenBSD"; +#elif defined(__OS2__) + return "OS/2"; +#elif defined(__OSF__) + return "OSF/1"; +#elif defined(__QNXNTO__) + return "QNX Neutrino"; +#elif defined(__RISCOS__) + return "RISC OS"; +#elif defined(__SOLARIS__) + return "Solaris"; +#elif defined(__WIN32__) + return "Windows"; +#elif defined(__WINRT__) + return "WinRT"; +#elif defined(__WINGDK__) + return "WinGDK"; +#elif defined(__XBOXONE__) + return "Xbox One"; +#elif defined(__XBOXSERIES__) + return "Xbox Series X|S"; +#elif defined(__TVOS__) + return "tvOS"; +#elif defined(__IPHONEOS__) + return "iOS"; +#elif defined(__PS2__) + return "PlayStation 2"; +#elif defined(__PSP__) + return "PlayStation Portable"; +#elif defined(__VITA__) + return "PlayStation Vita"; +#elif defined(__NGAGE__) + return "Nokia N-Gage"; +#elif defined(__3DS__) + return "Nintendo 3DS"; +#else + return "Unknown (see SDL_platform.h)"; +#endif +} + +SDL_bool SDL_IsTablet(void) +{ +#if defined(__ANDROID__) + extern SDL_bool SDL_IsAndroidTablet(void); + return SDL_IsAndroidTablet(); +#elif defined(__IPHONEOS__) + extern SDL_bool SDL_IsIPad(void); + return SDL_IsIPad(); +#else + return SDL_FALSE; +#endif +} + +#if defined(__WIN32__) + +#if (!defined(HAVE_LIBC) || defined(__WATCOMC__)) && !defined(SDL_STATIC_LIB) +/* FIXME: Still need to include DllMain() on Watcom C ? */ + +BOOL APIENTRY MINGW32_FORCEALIGN _DllMainCRTStartup(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) +{ + switch (ul_reason_for_call) { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} +#endif /* Building DLL */ + +#endif /* defined(__WIN32__) || defined(__GDK__) */ + +/* vi: set sts=4 ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/SDL_assert.c b/SDL2-2.30.5/src/SDL_assert.c similarity index 67% rename from SDL2-2.0.12/src/SDL_assert.c rename to SDL2-2.30.5/src/SDL_assert.c index f942501..1ca41e7 100644 --- a/SDL2-2.0.12/src/SDL_assert.c +++ b/SDL2-2.30.5/src/SDL_assert.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "./SDL_internal.h" -#if defined(__WIN32__) +#if defined(__WIN32__) || defined(__GDK__) #include "core/windows/SDL_windows.h" #endif @@ -32,7 +32,7 @@ #include "SDL_assert_c.h" #include "video/SDL_sysvideo.h" -#ifdef __WIN32__ +#if defined(__WIN32__) || defined(__GDK__) #ifndef WS_OVERLAPPEDWINDOW #define WS_OVERLAPPEDWINDOW 0 #endif @@ -42,12 +42,21 @@ #endif #if defined(__EMSCRIPTEN__) -#include + #include + /* older Emscriptens don't have this, but we need to for wasm64 compatibility. */ + #ifndef MAIN_THREAD_EM_ASM_PTR + #ifdef __wasm64__ + #error You need to upgrade your Emscripten compiler to support wasm64 + #else + #define MAIN_THREAD_EM_ASM_PTR MAIN_THREAD_EM_ASM_INT + #endif + #endif #endif +/* The size of the stack buffer to use for rendering assert messages. */ +#define SDL_MAX_ASSERT_MESSAGE_STACK 256 -static SDL_assert_state SDLCALL -SDL_PromptAssertion(const SDL_assert_data *data, void *userdata); +static SDL_assert_state SDLCALL SDL_PromptAssertion(const SDL_assert_data *data, void *userdata); /* * We keep all triggered assertions in a singly-linked list so we can @@ -63,12 +72,10 @@ static SDL_AssertionHandler assertion_handler = SDL_PromptAssertion; static void *assertion_userdata = NULL; #ifdef __GNUC__ -static void -debug_print(const char *fmt, ...) __attribute__((format (printf, 1, 2))); +static void debug_print(const char *fmt, ...) __attribute__((format(printf, 1, 2))); #endif -static void -debug_print(const char *fmt, ...) +static void debug_print(const char *fmt, ...) { va_list ap; va_start(ap, fmt); @@ -76,29 +83,42 @@ debug_print(const char *fmt, ...) va_end(ap); } - static void SDL_AddAssertionToReport(SDL_assert_data *data) { /* (data) is always a static struct defined with the assert macros, so we don't have to worry about copying or allocating them. */ data->trigger_count++; - if (data->trigger_count == 1) { /* not yet added? */ + if (data->trigger_count == 1) { /* not yet added? */ data->next = triggered_assertions; triggered_assertions = data; } } +#if defined(__WIN32__) || defined(__GDK__) +#define ENDLINE "\r\n" +#else +#define ENDLINE "\n" +#endif + +static int SDL_RenderAssertMessage(char *buf, size_t buf_len, const SDL_assert_data *data) +{ + return SDL_snprintf(buf, buf_len, + "Assertion failure at %s (%s:%d), triggered %u %s:" ENDLINE " '%s'", + data->function, data->filename, data->linenum, + data->trigger_count, (data->trigger_count == 1) ? "time" : "times", + data->condition); +} static void SDL_GenerateAssertionReport(void) { const SDL_assert_data *item = triggered_assertions; /* only do this if the app hasn't assigned an assertion handler. */ - if ((item != NULL) && (assertion_handler != SDL_PromptAssertion)) { + if ((item) && (assertion_handler != SDL_PromptAssertion)) { debug_print("\n\nSDL assertion report.\n"); debug_print("All SDL assertions between last init/quit:\n\n"); - while (item != NULL) { + while (item) { debug_print( "'%s'\n" " * %s (%s:%d)\n" @@ -116,7 +136,6 @@ static void SDL_GenerateAssertionReport(void) } } - /* This is not declared in any header, although it is shared between some parts of SDL, because we don't want anything calling it without an extremely good reason. */ @@ -126,9 +145,8 @@ extern void SDL_ExitProcess(int exitcode); #endif extern SDL_NORETURN void SDL_ExitProcess(int exitcode); - #if defined(__WATCOMC__) -static void SDL_AbortAssertion (void); +static void SDL_AbortAssertion(void); #pragma aux SDL_AbortAssertion aborts; #endif static SDL_NORETURN void SDL_AbortAssertion(void) @@ -137,53 +155,61 @@ static SDL_NORETURN void SDL_AbortAssertion(void) SDL_ExitProcess(42); } - -static SDL_assert_state SDLCALL -SDL_PromptAssertion(const SDL_assert_data *data, void *userdata) +static SDL_assert_state SDLCALL SDL_PromptAssertion(const SDL_assert_data *data, void *userdata) { -#ifdef __WIN32__ - #define ENDLINE "\r\n" -#else - #define ENDLINE "\n" -#endif - const char *envr; SDL_assert_state state = SDL_ASSERTION_ABORT; SDL_Window *window; SDL_MessageBoxData messagebox; SDL_MessageBoxButtonData buttons[] = { - { 0, SDL_ASSERTION_RETRY, "Retry" }, - { 0, SDL_ASSERTION_BREAK, "Break" }, - { 0, SDL_ASSERTION_ABORT, "Abort" }, - { SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, - SDL_ASSERTION_IGNORE, "Ignore" }, - { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, - SDL_ASSERTION_ALWAYS_IGNORE, "Always Ignore" } + { 0, SDL_ASSERTION_RETRY, "Retry" }, + { 0, SDL_ASSERTION_BREAK, "Break" }, + { 0, SDL_ASSERTION_ABORT, "Abort" }, + { SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, + SDL_ASSERTION_IGNORE, "Ignore" }, + { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, + SDL_ASSERTION_ALWAYS_IGNORE, "Always Ignore" } }; - char *message; int selected; - (void) userdata; /* unused in default handler. */ + char stack_buf[SDL_MAX_ASSERT_MESSAGE_STACK]; + char *message = stack_buf; + size_t buf_len = sizeof(stack_buf); + int len; - /* !!! FIXME: why is this using SDL_stack_alloc and not just "char message[SDL_MAX_LOG_MESSAGE];" ? */ - message = SDL_stack_alloc(char, SDL_MAX_LOG_MESSAGE); - if (!message) { - /* Uh oh, we're in real trouble now... */ + (void)userdata; /* unused in default handler. */ + + /* Assume the output will fit... */ + len = SDL_RenderAssertMessage(message, buf_len, data); + + /* .. and if it didn't, try to allocate as much room as we actually need. */ + if (len >= (int)buf_len) { + if (SDL_size_add_overflow(len, 1, &buf_len) == 0) { + message = (char *)SDL_malloc(buf_len); + if (message) { + len = SDL_RenderAssertMessage(message, buf_len, data); + } else { + message = stack_buf; + } + } + } + + /* Something went very wrong */ + if (len < 0) { + if (message != stack_buf) { + SDL_free(message); + } return SDL_ASSERTION_ABORT; } - SDL_snprintf(message, SDL_MAX_LOG_MESSAGE, - "Assertion failure at %s (%s:%d), triggered %u %s:" ENDLINE - " '%s'", - data->function, data->filename, data->linenum, - data->trigger_count, (data->trigger_count == 1) ? "time" : "times", - data->condition); debug_print("\n\n%s\n\n", message); /* let env. variable override, so unit tests won't block in a GUI. */ envr = SDL_getenv("SDL_ASSERT"); - if (envr != NULL) { - SDL_stack_free(message); + if (envr) { + if (message != stack_buf) { + SDL_free(message); + } if (SDL_strcmp(envr, "abort") == 0) { return SDL_ASSERTION_ABORT; @@ -196,7 +222,7 @@ SDL_PromptAssertion(const SDL_assert_data *data, void *userdata) } else if (SDL_strcmp(envr, "always_ignore") == 0) { return SDL_ASSERTION_ALWAYS_IGNORE; } else { - return SDL_ASSERTION_ABORT; /* oh well. */ + return SDL_ASSERTION_ABORT; /* oh well. */ } } @@ -227,15 +253,13 @@ SDL_PromptAssertion(const SDL_assert_data *data, void *userdata) } else { state = (SDL_assert_state)selected; } - } - - else - { + } else { #if defined(__EMSCRIPTEN__) /* This is nasty, but we can't block on a custom UI. */ - for ( ; ; ) { + for (;;) { SDL_bool okay = SDL_TRUE; - char *buf = (char *) EM_ASM_INT({ + /* *INDENT-OFF* */ /* clang-format off */ + char *buf = (char *) MAIN_THREAD_EM_ASM_PTR({ var str = UTF8ToString($0) + '\n\n' + 'Abort/Retry/Ignore/AlwaysIgnore? [ariA] :'; @@ -245,12 +269,14 @@ SDL_PromptAssertion(const SDL_assert_data *data, void *userdata) } return allocate(intArrayFromString(reply), 'i8', ALLOC_NORMAL); }, message); + /* *INDENT-ON* */ /* clang-format on */ if (SDL_strcmp(buf, "a") == 0) { state = SDL_ASSERTION_ABORT; - /* (currently) no break functionality on Emscripten +#if 0 /* (currently) no break functionality on Emscripten */ } else if (SDL_strcmp(buf, "b") == 0) { - state = SDL_ASSERTION_BREAK; */ + state = SDL_ASSERTION_BREAK; +#endif } else if (SDL_strcmp(buf, "r") == 0) { state = SDL_ASSERTION_RETRY; } else if (SDL_strcmp(buf, "i") == 0) { @@ -268,11 +294,11 @@ SDL_PromptAssertion(const SDL_assert_data *data, void *userdata) } #elif defined(HAVE_STDIO_H) /* this is a little hacky. */ - for ( ; ; ) { + for (;;) { char buf[32]; - fprintf(stderr, "Abort/Break/Retry/Ignore/AlwaysIgnore? [abriA] : "); - fflush(stderr); - if (fgets(buf, sizeof (buf), stdin) == NULL) { + (void)fprintf(stderr, "Abort/Break/Retry/Ignore/AlwaysIgnore? [abriA] : "); + (void)fflush(stderr); + if (fgets(buf, sizeof(buf), stdin) == NULL) { break; } @@ -301,15 +327,14 @@ SDL_PromptAssertion(const SDL_assert_data *data, void *userdata) SDL_RestoreWindow(window); } - SDL_stack_free(message); + if (message != stack_buf) { + SDL_free(message); + } return state; } - -SDL_assert_state -SDL_ReportAssertion(SDL_assert_data *data, const char *func, const char *file, - int line) +SDL_assert_state SDL_ReportAssertion(SDL_assert_data *data, const char *func, const char *file, int line) { SDL_assert_state state = SDL_ASSERTION_IGNORE; static int assertion_running = 0; @@ -317,19 +342,17 @@ SDL_ReportAssertion(SDL_assert_data *data, const char *func, const char *file, #ifndef SDL_THREADS_DISABLED static SDL_SpinLock spinlock = 0; SDL_AtomicLock(&spinlock); - if (assertion_mutex == NULL) { /* never called SDL_Init()? */ + if (!assertion_mutex) { /* never called SDL_Init()? */ assertion_mutex = SDL_CreateMutex(); - if (assertion_mutex == NULL) { + if (!assertion_mutex) { SDL_AtomicUnlock(&spinlock); - return SDL_ASSERTION_IGNORE; /* oh well, I guess. */ + return SDL_ASSERTION_IGNORE; /* oh well, I guess. */ } } SDL_AtomicUnlock(&spinlock); - if (SDL_LockMutex(assertion_mutex) < 0) { - return SDL_ASSERTION_IGNORE; /* oh well, I guess. */ - } -#endif + SDL_LockMutex(assertion_mutex); +#endif /* !SDL_THREADS_DISABLED */ /* doing this because Visual C is upset over assigning in the macro. */ if (data->trigger_count == 0) { @@ -341,13 +364,14 @@ SDL_ReportAssertion(SDL_assert_data *data, const char *func, const char *file, SDL_AddAssertionToReport(data); assertion_running++; - if (assertion_running > 1) { /* assert during assert! Abort. */ + if (assertion_running > 1) { /* assert during assert! Abort. */ if (assertion_running == 2) { SDL_AbortAssertion(); - } else if (assertion_running == 3) { /* Abort asserted! */ + } else if (assertion_running == 3) { /* Abort asserted! */ SDL_ExitProcess(42); } else { - while (1) { /* do nothing but spin; what else can you do?! */ } + while (1) { /* do nothing but spin; what else can you do?! */ + } } } @@ -355,21 +379,20 @@ SDL_ReportAssertion(SDL_assert_data *data, const char *func, const char *file, state = assertion_handler(data, assertion_userdata); } - switch (state) - { - case SDL_ASSERTION_ALWAYS_IGNORE: - state = SDL_ASSERTION_IGNORE; - data->always_ignore = 1; - break; + switch (state) { + case SDL_ASSERTION_ALWAYS_IGNORE: + state = SDL_ASSERTION_IGNORE; + data->always_ignore = 1; + break; - case SDL_ASSERTION_IGNORE: - case SDL_ASSERTION_RETRY: - case SDL_ASSERTION_BREAK: - break; /* macro handles these. */ + case SDL_ASSERTION_IGNORE: + case SDL_ASSERTION_RETRY: + case SDL_ASSERTION_BREAK: + break; /* macro handles these. */ - case SDL_ASSERTION_ABORT: - SDL_AbortAssertion(); - /*break; ...shouldn't return, but oh well. */ + case SDL_ASSERTION_ABORT: + SDL_AbortAssertion(); + /*break; ...shouldn't return, but oh well. */ } assertion_running--; @@ -381,16 +404,17 @@ SDL_ReportAssertion(SDL_assert_data *data, const char *func, const char *file, return state; } - void SDL_AssertionsQuit(void) { +#if SDL_ASSERT_LEVEL > 0 SDL_GenerateAssertionReport(); #ifndef SDL_THREADS_DISABLED - if (assertion_mutex != NULL) { + if (assertion_mutex) { SDL_DestroyMutex(assertion_mutex); assertion_mutex = NULL; } #endif +#endif /* SDL_ASSERT_LEVEL > 0 */ } void SDL_SetAssertionHandler(SDL_AssertionHandler handler, void *userdata) @@ -413,8 +437,8 @@ void SDL_ResetAssertionReport(void) { SDL_assert_data *next = NULL; SDL_assert_data *item; - for (item = triggered_assertions; item != NULL; item = next) { - next = (SDL_assert_data *) item->next; + for (item = triggered_assertions; item; item = next) { + next = (SDL_assert_data *)item->next; item->always_ignore = SDL_FALSE; item->trigger_count = 0; item->next = NULL; @@ -430,7 +454,7 @@ SDL_AssertionHandler SDL_GetDefaultAssertionHandler(void) SDL_AssertionHandler SDL_GetAssertionHandler(void **userdata) { - if (userdata != NULL) { + if (userdata) { *userdata = assertion_userdata; } return assertion_handler; diff --git a/SDL2-2.0.12/src/SDL_assert_c.h b/SDL2-2.30.5/src/SDL_assert_c.h similarity index 94% rename from SDL2-2.0.12/src/SDL_assert_c.h rename to SDL2-2.30.5/src/SDL_assert_c.h index b59c8d9..330acb8 100644 --- a/SDL2-2.0.12/src/SDL_assert_c.h +++ b/SDL2-2.30.5/src/SDL_assert_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/SDL_dataqueue.c b/SDL2-2.30.5/src/SDL_dataqueue.c similarity index 66% rename from SDL2-2.0.12/src/SDL_dataqueue.c rename to SDL2-2.30.5/src/SDL_dataqueue.c index 8a7a38b..e32ba31 100644 --- a/SDL2-2.0.12/src/SDL_dataqueue.c +++ b/SDL2-2.30.5/src/SDL_dataqueue.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -18,31 +18,30 @@ 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.h" #include "./SDL_dataqueue.h" -#include "SDL_assert.h" typedef struct SDL_DataQueuePacket { - size_t datalen; /* bytes currently in use in this packet. */ - size_t startpos; /* bytes currently consumed in this packet. */ - struct SDL_DataQueuePacket *next; /* next item in linked list. */ - Uint8 data[SDL_VARIABLE_LENGTH_ARRAY]; /* packet data */ + size_t datalen; /* bytes currently in use in this packet. */ + size_t startpos; /* bytes currently consumed in this packet. */ + struct SDL_DataQueuePacket *next; /* next item in linked list. */ + Uint8 data[SDL_VARIABLE_LENGTH_ARRAY]; /* packet data */ } SDL_DataQueuePacket; struct SDL_DataQueue { + SDL_mutex *lock; SDL_DataQueuePacket *head; /* device fed from here. */ SDL_DataQueuePacket *tail; /* queue fills to here. */ SDL_DataQueuePacket *pool; /* these are unused packets. */ - size_t packet_size; /* size of new packets */ - size_t queued_bytes; /* number of bytes of data in the queue. */ + size_t packet_size; /* size of new packets */ + size_t queued_bytes; /* number of bytes of data in the queue. */ }; -static void -SDL_FreeDataQueueList(SDL_DataQueuePacket *packet) +static void SDL_FreeDataQueueList(SDL_DataQueuePacket *packet) { while (packet) { SDL_DataQueuePacket *next = packet->next; @@ -51,27 +50,27 @@ SDL_FreeDataQueueList(SDL_DataQueuePacket *packet) } } - -/* this all expects that you managed thread safety elsewhere. */ - -SDL_DataQueue * -SDL_NewDataQueue(const size_t _packetlen, const size_t initialslack) +SDL_DataQueue *SDL_NewDataQueue(const size_t _packetlen, const size_t initialslack) { - SDL_DataQueue *queue = (SDL_DataQueue *) SDL_malloc(sizeof (SDL_DataQueue)); + SDL_DataQueue *queue = (SDL_DataQueue *)SDL_calloc(1, sizeof(SDL_DataQueue)); if (!queue) { SDL_OutOfMemory(); - return NULL; } else { const size_t packetlen = _packetlen ? _packetlen : 1024; const size_t wantpackets = (initialslack + (packetlen - 1)) / packetlen; size_t i; - SDL_zerop(queue); queue->packet_size = packetlen; + queue->lock = SDL_CreateMutex(); + if (!queue->lock) { + SDL_free(queue); + return NULL; + } + for (i = 0; i < wantpackets; i++) { - SDL_DataQueuePacket *packet = (SDL_DataQueuePacket *) SDL_malloc(sizeof (SDL_DataQueuePacket) + packetlen); + SDL_DataQueuePacket *packet = (SDL_DataQueuePacket *)SDL_malloc(sizeof(SDL_DataQueuePacket) + packetlen); if (packet) { /* don't care if this fails, we'll deal later. */ packet->datalen = 0; packet->startpos = 0; @@ -84,21 +83,20 @@ SDL_NewDataQueue(const size_t _packetlen, const size_t initialslack) return queue; } -void -SDL_FreeDataQueue(SDL_DataQueue *queue) +void SDL_FreeDataQueue(SDL_DataQueue *queue) { if (queue) { SDL_FreeDataQueueList(queue->head); SDL_FreeDataQueueList(queue->pool); + SDL_DestroyMutex(queue->lock); SDL_free(queue); } } -void -SDL_ClearDataQueue(SDL_DataQueue *queue, const size_t slack) +void SDL_ClearDataQueue(SDL_DataQueue *queue, const size_t slack) { const size_t packet_size = queue ? queue->packet_size : 1; - const size_t slackpackets = (slack + (packet_size-1)) / packet_size; + const size_t slackpackets = (slack + (packet_size - 1)) / packet_size; SDL_DataQueuePacket *packet; SDL_DataQueuePacket *prev = NULL; size_t i; @@ -107,6 +105,8 @@ SDL_ClearDataQueue(SDL_DataQueue *queue, const size_t slack) return; } + SDL_LockMutex(queue->lock); + packet = queue->head; /* merge the available pool and the current queue into one list. */ @@ -122,7 +122,7 @@ SDL_ClearDataQueue(SDL_DataQueue *queue, const size_t slack) queue->queued_bytes = 0; queue->pool = packet; - /* Optionally keep some slack in the pool to reduce malloc pressure. */ + /* Optionally keep some slack in the pool to reduce memory allocation pressure. */ for (i = 0; packet && (i < slackpackets); i++) { prev = packet; packet = packet->next; @@ -134,24 +134,26 @@ SDL_ClearDataQueue(SDL_DataQueue *queue, const size_t slack) queue->pool = NULL; } - SDL_FreeDataQueueList(packet); /* free extra packets */ + SDL_UnlockMutex(queue->lock); + + SDL_FreeDataQueueList(packet); /* free extra packets */ } -static SDL_DataQueuePacket * -AllocateDataQueuePacket(SDL_DataQueue *queue) +/* You must hold queue->lock before calling this! */ +static SDL_DataQueuePacket *AllocateDataQueuePacket(SDL_DataQueue *queue) { SDL_DataQueuePacket *packet; SDL_assert(queue != NULL); packet = queue->pool; - if (packet != NULL) { + if (packet) { /* we have one available in the pool. */ queue->pool = packet->next; } else { /* Have to allocate a new one! */ - packet = (SDL_DataQueuePacket *) SDL_malloc(sizeof (SDL_DataQueuePacket) + queue->packet_size); - if (packet == NULL) { + packet = (SDL_DataQueuePacket *)SDL_malloc(sizeof(SDL_DataQueuePacket) + queue->packet_size); + if (!packet) { return NULL; } } @@ -159,9 +161,9 @@ AllocateDataQueuePacket(SDL_DataQueue *queue) packet->datalen = 0; packet->startpos = 0; packet->next = NULL; - + SDL_assert((queue->head != NULL) == (queue->queued_bytes != 0)); - if (queue->tail == NULL) { + if (!queue->tail) { queue->head = packet; } else { queue->tail->next = packet; @@ -170,12 +172,10 @@ AllocateDataQueuePacket(SDL_DataQueue *queue) return packet; } - -int -SDL_WriteToDataQueue(SDL_DataQueue *queue, const void *_data, const size_t _len) +int SDL_WriteToDataQueue(SDL_DataQueue *queue, const void *_data, const size_t _len) { size_t len = _len; - const Uint8 *data = (const Uint8 *) _data; + const Uint8 *data = (const Uint8 *)_data; const size_t packet_size = queue ? queue->packet_size : 0; SDL_DataQueuePacket *orighead; SDL_DataQueuePacket *origtail; @@ -186,22 +186,24 @@ SDL_WriteToDataQueue(SDL_DataQueue *queue, const void *_data, const size_t _len) return SDL_InvalidParamError("queue"); } + SDL_LockMutex(queue->lock); + orighead = queue->head; origtail = queue->tail; origlen = origtail ? origtail->datalen : 0; while (len > 0) { SDL_DataQueuePacket *packet = queue->tail; - SDL_assert(!packet || (packet->datalen <= packet_size)); + SDL_assert(packet == NULL || (packet->datalen <= packet_size)); if (!packet || (packet->datalen >= packet_size)) { /* tail packet missing or completely full; we need a new packet. */ packet = AllocateDataQueuePacket(queue); if (!packet) { /* uhoh, reset so we've queued nothing new, free what we can. */ if (!origtail) { - packet = queue->head; /* whole queue. */ + packet = queue->head; /* whole queue. */ } else { - packet = origtail->next; /* what we added to existing queue. */ + packet = origtail->next; /* what we added to existing queue. */ origtail->next = NULL; origtail->datalen = origlen; } @@ -209,7 +211,8 @@ SDL_WriteToDataQueue(SDL_DataQueue *queue, const void *_data, const size_t _len) queue->tail = origtail; queue->pool = NULL; - SDL_FreeDataQueueList(packet); /* give back what we can. */ + SDL_UnlockMutex(queue->lock); + SDL_FreeDataQueueList(packet); /* give back what we can. */ return SDL_OutOfMemory(); } } @@ -222,6 +225,8 @@ SDL_WriteToDataQueue(SDL_DataQueue *queue, const void *_data, const size_t _len) queue->queued_bytes += datalen; } + SDL_UnlockMutex(queue->lock); + return 0; } @@ -229,7 +234,7 @@ size_t SDL_PeekIntoDataQueue(SDL_DataQueue *queue, void *_buf, const size_t _len) { size_t len = _len; - Uint8 *buf = (Uint8 *) _buf; + Uint8 *buf = (Uint8 *)_buf; Uint8 *ptr = buf; SDL_DataQueuePacket *packet; @@ -237,6 +242,8 @@ SDL_PeekIntoDataQueue(SDL_DataQueue *queue, void *_buf, const size_t _len) return 0; } + SDL_LockMutex(queue->lock); + 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); @@ -247,14 +254,16 @@ SDL_PeekIntoDataQueue(SDL_DataQueue *queue, void *_buf, const size_t _len) len -= cpy; } - return (size_t) (ptr - buf); + SDL_UnlockMutex(queue->lock); + + return (size_t)(ptr - buf); } size_t SDL_ReadFromDataQueue(SDL_DataQueue *queue, void *_buf, const size_t _len) { size_t len = _len; - Uint8 *buf = (Uint8 *) _buf; + Uint8 *buf = (Uint8 *)_buf; Uint8 *ptr = buf; SDL_DataQueuePacket *packet; @@ -262,6 +271,8 @@ SDL_ReadFromDataQueue(SDL_DataQueue *queue, void *_buf, const size_t _len) return 0; } + SDL_LockMutex(queue->lock); + while ((len > 0) && ((packet = queue->head) != NULL)) { const size_t avail = packet->datalen - packet->startpos; const size_t cpy = SDL_min(len, avail); @@ -273,7 +284,7 @@ SDL_ReadFromDataQueue(SDL_DataQueue *queue, void *_buf, const size_t _len) queue->queued_bytes -= cpy; len -= cpy; - if (packet->startpos == packet->datalen) { /* packet is done, put it in the pool. */ + if (packet->startpos == packet->datalen) { /* packet is done, put it in the pool. */ queue->head = packet->next; SDL_assert((packet->next != NULL) || (packet == queue->tail)); packet->next = queue->pool; @@ -283,57 +294,30 @@ SDL_ReadFromDataQueue(SDL_DataQueue *queue, void *_buf, const size_t _len) SDL_assert((queue->head != NULL) == (queue->queued_bytes != 0)); - if (queue->head == NULL) { - queue->tail = NULL; /* in case we drained the queue entirely. */ + if (!queue->head) { + queue->tail = NULL; /* in case we drained the queue entirely. */ } - return (size_t) (ptr - buf); + SDL_UnlockMutex(queue->lock); + + return (size_t)(ptr - buf); } size_t SDL_CountDataQueue(SDL_DataQueue *queue) { - return queue ? queue->queued_bytes : 0; + size_t retval = 0; + if (queue) { + SDL_LockMutex(queue->lock); + retval = queue->queued_bytes; + SDL_UnlockMutex(queue->lock); + } + return retval; } -void * -SDL_ReserveSpaceInDataQueue(SDL_DataQueue *queue, const size_t len) +SDL_mutex *SDL_GetDataQueueMutex(SDL_DataQueue *queue) { - SDL_DataQueuePacket *packet; - - if (!queue) { - SDL_InvalidParamError("queue"); - return NULL; - } else if (len == 0) { - SDL_InvalidParamError("len"); - return NULL; - } else if (len > queue->packet_size) { - SDL_SetError("len is larger than packet size"); - return NULL; - } - - packet = queue->head; - if (packet) { - const size_t avail = queue->packet_size - packet->datalen; - if (len <= avail) { /* we can use the space at end of this packet. */ - void *retval = packet->data + packet->datalen; - packet->datalen += len; - queue->queued_bytes += len; - return retval; - } - } - - /* Need a fresh packet. */ - packet = AllocateDataQueuePacket(queue); - if (!packet) { - SDL_OutOfMemory(); - return NULL; - } - - packet->datalen = len; - queue->queued_bytes += len; - return packet->data; + return queue ? queue->lock : NULL; } /* vi: set ts=4 sw=4 expandtab: */ - diff --git a/SDL2-2.0.12/src/SDL_dataqueue.h b/SDL2-2.30.5/src/SDL_dataqueue.h similarity index 62% rename from SDL2-2.0.12/src/SDL_dataqueue.h rename to SDL2-2.30.5/src/SDL_dataqueue.h index b089236..972a521 100644 --- a/SDL2-2.0.12/src/SDL_dataqueue.h +++ b/SDL2-2.30.5/src/SDL_dataqueue.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -33,23 +33,8 @@ int SDL_WriteToDataQueue(SDL_DataQueue *queue, const void *data, const size_t le 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) - as if it's been written to, but returns a pointer to that space. You may write - to this space until a read would consume it. Writes (and other calls to this - function) will safely append their data after this reserved space and can - be in flight at the same time. There is no thread safety. - If there isn't an existing block of memory that can contain the reserved - space, one will be allocated for it. You can not (currently) allocate - a space larger than the packetlen requested in SDL_NewDataQueue. - Returned buffer is uninitialized. - This lets you avoid an extra copy in some cases, but it's safer to use - SDL_WriteToDataQueue() unless you know what you're doing. - Returns pointer to buffer of at least (len) bytes, NULL on error. -*/ -void *SDL_ReserveSpaceInDataQueue(SDL_DataQueue *queue, const size_t len); +SDL_mutex *SDL_GetDataQueueMutex(SDL_DataQueue *queue); /* don't destroy this, obviously. */ #endif /* SDL_dataqueue_h_ */ /* vi: set ts=4 sw=4 expandtab: */ - diff --git a/SDL2-2.30.5/src/SDL_error.c b/SDL2-2.30.5/src/SDL_error.c new file mode 100644 index 0000000..d5c45fb --- /dev/null +++ b/SDL2-2.30.5/src/SDL_error.c @@ -0,0 +1,123 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +/* Simple error handling in SDL */ + +#include "SDL_error.h" +#include "SDL_error_c.h" + +int SDL_SetError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) +{ + /* Ignore call if invalid format pointer was passed */ + if (fmt) { + va_list ap; + int result; + SDL_error *error = SDL_GetErrBuf(); + + error->error = 1; /* mark error as valid */ + + va_start(ap, fmt); + result = SDL_vsnprintf(error->str, error->len, fmt, ap); + va_end(ap); + + if (result >= 0 && (size_t)result >= error->len && error->realloc_func) { + size_t len = (size_t)result + 1; + char *str = (char *)error->realloc_func(error->str, len); + if (str) { + error->str = str; + error->len = len; + va_start(ap, fmt); + (void)SDL_vsnprintf(error->str, error->len, fmt, ap); + va_end(ap); + } + } + + if (SDL_LogGetPriority(SDL_LOG_CATEGORY_ERROR) <= SDL_LOG_PRIORITY_DEBUG) { + /* If we are in debug mode, print out the error message */ + SDL_LogDebug(SDL_LOG_CATEGORY_ERROR, "%s", error->str); + } + } + + return -1; +} + +/* Available for backwards compatibility */ +const char *SDL_GetError(void) +{ + const SDL_error *error = SDL_GetErrBuf(); + return error->error ? error->str : ""; +} + +void SDL_ClearError(void) +{ + SDL_GetErrBuf()->error = 0; +} + +/* Very common errors go here */ +int SDL_Error(SDL_errorcode code) +{ + switch (code) { + case SDL_ENOMEM: + return SDL_SetError("Out of memory"); + case SDL_EFREAD: + return SDL_SetError("Error reading from datastream"); + case SDL_EFWRITE: + return SDL_SetError("Error writing to datastream"); + case SDL_EFSEEK: + return SDL_SetError("Error seeking in datastream"); + case SDL_UNSUPPORTED: + return SDL_SetError("That operation is not supported"); + default: + return SDL_SetError("Unknown SDL error"); + } +} + +#ifdef TEST_ERROR +int main(int argc, char *argv[]) +{ + char buffer[BUFSIZ + 1]; + + SDL_SetError("Hi there!"); + printf("Error 1: %s\n", SDL_GetError()); + SDL_ClearError(); + SDL_memset(buffer, '1', BUFSIZ); + buffer[BUFSIZ] = 0; + SDL_SetError("This is the error: %s (%f)", buffer, 1.0); + printf("Error 2: %s\n", SDL_GetError()); + exit(0); +} +#endif + +char *SDL_GetErrorMsg(char *errstr, int maxlen) +{ + const SDL_error *error = SDL_GetErrBuf(); + + if (error->error) { + SDL_strlcpy(errstr, error->str, maxlen); + } else { + *errstr = '\0'; + } + + return errstr; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/SDL_error_c.h b/SDL2-2.30.5/src/SDL_error_c.h new file mode 100644 index 0000000..1aae3be --- /dev/null +++ b/SDL2-2.30.5/src/SDL_error_c.h @@ -0,0 +1,44 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +/* This file defines a structure that carries language-independent + error messages +*/ + +#ifndef SDL_error_c_h_ +#define SDL_error_c_h_ + +typedef struct SDL_error +{ + int error; /* This is a numeric value corresponding to the current error */ + char *str; + size_t len; + SDL_realloc_func realloc_func; + SDL_free_func free_func; +} SDL_error; + +/* Defined in SDL_thread.c */ +extern SDL_error *SDL_GetErrBuf(void); + +#endif /* SDL_error_c_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/SDL_guid.c b/SDL2-2.30.5/src/SDL_guid.c new file mode 100644 index 0000000..2f91edb --- /dev/null +++ b/SDL2-2.30.5/src/SDL_guid.c @@ -0,0 +1,91 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_guid.h" + +/* convert the guid to a printable string */ +void SDL_GUIDToString(SDL_GUID guid, char *pszGUID, int cbGUID) +{ + static const char k_rgchHexToASCII[] = "0123456789abcdef"; + int i; + + if ((!pszGUID) || (cbGUID <= 0)) { + return; + } + + for (i = 0; i < sizeof(guid.data) && i < (cbGUID - 1) / 2; i++) { + /* each input byte writes 2 ascii chars, and might write a null byte. */ + /* If we don't have room for next input byte, stop */ + unsigned char c = guid.data[i]; + + *pszGUID++ = k_rgchHexToASCII[c >> 4]; + *pszGUID++ = k_rgchHexToASCII[c & 0x0F]; + } + *pszGUID = '\0'; +} + +/*----------------------------------------------------------------------------- + * Purpose: Returns the 4 bit nibble for a hex character + * Input : c - + * Output : unsigned char + *-----------------------------------------------------------------------------*/ +static unsigned char nibble(unsigned char c) +{ + if ((c >= '0') && (c <= '9')) { + return c - '0'; + } + + if ((c >= 'A') && (c <= 'F')) { + return c - 'A' + 0x0a; + } + + if ((c >= 'a') && (c <= 'f')) { + return c - 'a' + 0x0a; + } + + /* received an invalid character, and no real way to return an error */ + /* AssertMsg1(false, "Q_nibble invalid hex character '%c' ", c); */ + return 0; +} + +/* convert the string version of a guid to the struct */ +SDL_GUID SDL_GUIDFromString(const char *pchGUID) +{ + SDL_GUID guid; + int maxoutputbytes = sizeof(guid); + size_t len = SDL_strlen(pchGUID); + Uint8 *p; + size_t i; + + /* Make sure it's even */ + len = (len) & ~0x1; + + SDL_memset(&guid, 0x00, sizeof(guid)); + + p = (Uint8 *)&guid; + for (i = 0; (i < len) && ((p - (Uint8 *)&guid) < maxoutputbytes); i += 2, p++) { + *p = (nibble((unsigned char)pchGUID[i]) << 4) | nibble((unsigned char)pchGUID[i + 1]); + } + + return guid; +} diff --git a/SDL2-2.0.12/src/SDL_hints.c b/SDL2-2.30.5/src/SDL_hints.c similarity index 67% rename from SDL2-2.0.12/src/SDL_hints.c rename to SDL2-2.30.5/src/SDL_hints.c index d6bdd13..2455cc1 100644 --- a/SDL2-2.0.12/src/SDL_hints.c +++ b/SDL2-2.30.5/src/SDL_hints.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -24,17 +24,18 @@ #include "SDL_error.h" #include "SDL_hints_c.h" - /* Assuming there aren't many hints set and they aren't being queried in critical performance paths, we'll just use linked lists here. */ -typedef struct SDL_HintWatch { +typedef struct SDL_HintWatch +{ SDL_HintCallback callback; void *userdata; struct SDL_HintWatch *next; } SDL_HintWatch; -typedef struct SDL_Hint { +typedef struct SDL_Hint +{ char *name; char *value; SDL_HintPriority priority; @@ -44,15 +45,13 @@ typedef struct SDL_Hint { static SDL_Hint *SDL_hints; -SDL_bool -SDL_SetHintWithPriority(const char *name, const char *value, - SDL_HintPriority priority) +SDL_bool SDL_SetHintWithPriority(const char *name, const char *value, SDL_HintPriority priority) { const char *env; SDL_Hint *hint; SDL_HintWatch *entry; - if (!name || !value) { + if (!name) { return SDL_FALSE; } @@ -66,8 +65,9 @@ SDL_SetHintWithPriority(const char *name, const char *value, if (priority < hint->priority) { return SDL_FALSE; } - if (!hint->value || !value || SDL_strcmp(hint->value, value) != 0) { - for (entry = hint->callbacks; entry; ) { + if (hint->value != value && + (!value || !hint->value || SDL_strcmp(hint->value, value) != 0)) { + for (entry = hint->callbacks; entry;) { /* Save the next entry in case this one is deleted */ SDL_HintWatch *next = entry->next; entry->callback(entry->userdata, name, hint->value, value); @@ -95,18 +95,76 @@ SDL_SetHintWithPriority(const char *name, const char *value, return SDL_TRUE; } -SDL_bool -SDL_SetHint(const char *name, const char *value) +SDL_bool SDL_ResetHint(const char *name) +{ + const char *env; + SDL_Hint *hint; + SDL_HintWatch *entry; + + if (!name) { + return SDL_FALSE; + } + + env = SDL_getenv(name); + for (hint = SDL_hints; hint; hint = hint->next) { + if (SDL_strcmp(name, hint->name) == 0) { + if ((!env && hint->value) || + (env && !hint->value) || + (env && SDL_strcmp(env, hint->value) != 0)) { + for (entry = hint->callbacks; entry;) { + /* Save the next entry in case this one is deleted */ + SDL_HintWatch *next = entry->next; + entry->callback(entry->userdata, name, hint->value, env); + entry = next; + } + } + SDL_free(hint->value); + hint->value = NULL; + hint->priority = SDL_HINT_DEFAULT; + return SDL_TRUE; + } + } + return SDL_FALSE; +} + +void SDL_ResetHints(void) +{ + const char *env; + SDL_Hint *hint; + SDL_HintWatch *entry; + + for (hint = SDL_hints; hint; hint = hint->next) { + env = SDL_getenv(hint->name); + if ((!env && hint->value) || + (env && !hint->value) || + (env && SDL_strcmp(env, hint->value) != 0)) { + for (entry = hint->callbacks; entry;) { + /* Save the next entry in case this one is deleted */ + SDL_HintWatch *next = entry->next; + entry->callback(entry->userdata, hint->name, hint->value, env); + entry = next; + } + } + SDL_free(hint->value); + hint->value = NULL; + hint->priority = SDL_HINT_DEFAULT; + } +} + +SDL_bool SDL_SetHint(const char *name, const char *value) { return SDL_SetHintWithPriority(name, value, SDL_HINT_NORMAL); } -const char * -SDL_GetHint(const char *name) +const char *SDL_GetHint(const char *name) { const char *env; SDL_Hint *hint; + if (!name) { + return NULL; + } + env = SDL_getenv(name); for (hint = SDL_hints; hint; hint = hint->next) { if (SDL_strcmp(name, hint->name) == 0) { @@ -119,8 +177,7 @@ SDL_GetHint(const char *name) return env; } -SDL_bool -SDL_GetStringBoolean(const char *value, SDL_bool default_value) +SDL_bool SDL_GetStringBoolean(const char *value, SDL_bool default_value) { if (!value || !*value) { return default_value; @@ -131,15 +188,13 @@ SDL_GetStringBoolean(const char *value, SDL_bool default_value) return SDL_TRUE; } -SDL_bool -SDL_GetHintBoolean(const char *name, SDL_bool default_value) +SDL_bool SDL_GetHintBoolean(const char *name, SDL_bool default_value) { const char *hint = SDL_GetHint(name); return SDL_GetStringBoolean(hint, default_value); } -void -SDL_AddHintCallback(const char *name, SDL_HintCallback callback, void *userdata) +void SDL_AddHintCallback(const char *name, SDL_HintCallback callback, void *userdata) { SDL_Hint *hint; SDL_HintWatch *entry; @@ -178,6 +233,12 @@ SDL_AddHintCallback(const char *name, SDL_HintCallback callback, void *userdata) return; } hint->name = SDL_strdup(name); + if (!hint->name) { + SDL_free(entry); + SDL_free(hint); + SDL_OutOfMemory(); + return; + } hint->value = NULL; hint->priority = SDL_HINT_DEFAULT; hint->callbacks = NULL; @@ -194,8 +255,7 @@ SDL_AddHintCallback(const char *name, SDL_HintCallback callback, void *userdata) callback(userdata, name, value, value); } -void -SDL_DelHintCallback(const char *name, SDL_HintCallback callback, void *userdata) +void SDL_DelHintCallback(const char *name, SDL_HintCallback callback, void *userdata) { SDL_Hint *hint; SDL_HintWatch *entry, *prev; @@ -231,7 +291,7 @@ void SDL_ClearHints(void) SDL_free(hint->name); SDL_free(hint->value); - for (entry = hint->callbacks; entry; ) { + for (entry = hint->callbacks; entry;) { SDL_HintWatch *freeable = entry; entry = entry->next; SDL_free(freeable); diff --git a/SDL2-2.0.12/src/SDL_hints_c.h b/SDL2-2.30.5/src/SDL_hints_c.h similarity index 95% rename from SDL2-2.0.12/src/SDL_hints_c.h rename to SDL2-2.30.5/src/SDL_hints_c.h index ae731d4..8af9fc5 100644 --- a/SDL2-2.0.12/src/SDL_hints_c.h +++ b/SDL2-2.30.5/src/SDL_hints_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.30.5/src/SDL_internal.h b/SDL2-2.30.5/src/SDL_internal.h new file mode 100644 index 0000000..b193ede --- /dev/null +++ b/SDL2-2.30.5/src/SDL_internal.h @@ -0,0 +1,213 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ +#ifndef SDL_internal_h_ +#define SDL_internal_h_ + +/* Many of SDL's features require _GNU_SOURCE on various platforms */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +/* This is for a variable-length array at the end of a struct: + struct x { int y; char z[SDL_VARIABLE_LENGTH_ARRAY]; }; + Use this because GCC 2 needs different magic than other compilers. */ +#if (defined(__GNUC__) && (__GNUC__ <= 2)) || defined(__CC_ARM) || defined(__cplusplus) +#define SDL_VARIABLE_LENGTH_ARRAY 1 +#else +#define SDL_VARIABLE_LENGTH_ARRAY +#endif + +#define SDL_MAX_SMALL_ALLOC_STACKSIZE 128 +#define SDL_small_alloc(type, count, pisstack) ((*(pisstack) = ((sizeof(type) * (count)) < SDL_MAX_SMALL_ALLOC_STACKSIZE)), (*(pisstack) ? SDL_stack_alloc(type, count) : (type *)SDL_malloc(sizeof(type) * (count)))) +#define SDL_small_free(ptr, isstack) \ + if ((isstack)) { \ + SDL_stack_free(ptr); \ + } else { \ + SDL_free(ptr); \ + } + +#include "dynapi/SDL_dynapi.h" + +#if SDL_DYNAMIC_API +#include "dynapi/SDL_dynapi_overrides.h" +/* force DECLSPEC off...it's all internal symbols now. + These will have actual #defines during SDL_dynapi.c only */ +#define DECLSPEC +#endif + +#include "SDL_config.h" + +/* If you run into a warning that O_CLOEXEC is redefined, update the SDL configuration header for your platform to add HAVE_O_CLOEXEC */ +#ifndef HAVE_O_CLOEXEC +#define O_CLOEXEC 0 +#endif + +/* A few #defines to reduce SDL2 footprint. + Only effective when library is statically linked. + You have to manually edit this file. */ +#ifndef SDL_LEAN_AND_MEAN +#define SDL_LEAN_AND_MEAN 0 +#endif + +/* Optimized functions from 'SDL_blit_0.c' + - blit with source BitsPerPixel < 8, palette */ +#ifndef SDL_HAVE_BLIT_0 +#define SDL_HAVE_BLIT_0 !SDL_LEAN_AND_MEAN +#endif + +/* Optimized functions from 'SDL_blit_1.c' + - blit with source BytesPerPixel == 1, palette */ +#ifndef SDL_HAVE_BLIT_1 +#define SDL_HAVE_BLIT_1 !SDL_LEAN_AND_MEAN +#endif + +/* Optimized functions from 'SDL_blit_A.c' + - blit with 'SDL_BLENDMODE_BLEND' blending mode */ +#ifndef SDL_HAVE_BLIT_A +#define SDL_HAVE_BLIT_A !SDL_LEAN_AND_MEAN +#endif + +/* Optimized functions from 'SDL_blit_N.c' + - blit with COLORKEY mode, or nothing */ +#ifndef SDL_HAVE_BLIT_N +#define SDL_HAVE_BLIT_N !SDL_LEAN_AND_MEAN +#endif + +/* Optimized functions from 'SDL_blit_N.c' + - RGB565 conversion with Lookup tables */ +#ifndef SDL_HAVE_BLIT_N_RGB565 +#define SDL_HAVE_BLIT_N_RGB565 !SDL_LEAN_AND_MEAN +#endif + +/* Optimized functions from 'SDL_blit_AUTO.c' + - blit with modulate color, modulate alpha, any blending mode + - scaling or not */ +#ifndef SDL_HAVE_BLIT_AUTO +#define SDL_HAVE_BLIT_AUTO !SDL_LEAN_AND_MEAN +#endif + +/* Run-Length-Encoding + - SDL_SetColorKey() called with SDL_RLEACCEL flag */ +#ifndef SDL_HAVE_RLE +#define SDL_HAVE_RLE !SDL_LEAN_AND_MEAN +#endif + +/* Software SDL_Renderer + - creation of software renderer + - *not* general blitting functions + - {blend,draw}{fillrect,line,point} internal functions */ +#ifndef SDL_VIDEO_RENDER_SW +#define SDL_VIDEO_RENDER_SW !SDL_LEAN_AND_MEAN +#endif + +/* YUV formats + - handling of YUV surfaces + - blitting and conversion functions */ +#ifndef SDL_HAVE_YUV +#define SDL_HAVE_YUV !SDL_LEAN_AND_MEAN +#endif + +#ifndef SDL_RENDER_DISABLED +/* define the not defined ones as 0 */ +#ifndef SDL_VIDEO_RENDER_D3D +#define SDL_VIDEO_RENDER_D3D 0 +#endif +#ifndef SDL_VIDEO_RENDER_D3D11 +#define SDL_VIDEO_RENDER_D3D11 0 +#endif +#ifndef SDL_VIDEO_RENDER_D3D12 +#define SDL_VIDEO_RENDER_D3D12 0 +#endif +#ifndef SDL_VIDEO_RENDER_METAL +#define SDL_VIDEO_RENDER_METAL 0 +#endif +#ifndef SDL_VIDEO_RENDER_OGL +#define SDL_VIDEO_RENDER_OGL 0 +#endif +#ifndef SDL_VIDEO_RENDER_OGL_ES +#define SDL_VIDEO_RENDER_OGL_ES 0 +#endif +#ifndef SDL_VIDEO_RENDER_OGL_ES2 +#define SDL_VIDEO_RENDER_OGL_ES2 0 +#endif +#ifndef SDL_VIDEO_RENDER_DIRECTFB +#define SDL_VIDEO_RENDER_DIRECTFB 0 +#endif +#ifndef SDL_VIDEO_RENDER_PS2 +#define SDL_VIDEO_RENDER_PS2 0 +#endif +#ifndef SDL_VIDEO_RENDER_PSP +#define SDL_VIDEO_RENDER_PSP 0 +#endif +#ifndef SDL_VIDEO_RENDER_VITA_GXM +#define SDL_VIDEO_RENDER_VITA_GXM 0 +#endif +#else /* define all as 0 */ +#undef SDL_VIDEO_RENDER_SW +#define SDL_VIDEO_RENDER_SW 0 +#undef SDL_VIDEO_RENDER_D3D +#define SDL_VIDEO_RENDER_D3D 0 +#undef SDL_VIDEO_RENDER_D3D11 +#define SDL_VIDEO_RENDER_D3D11 0 +#undef SDL_VIDEO_RENDER_D3D12 +#define SDL_VIDEO_RENDER_D3D12 0 +#undef SDL_VIDEO_RENDER_METAL +#define SDL_VIDEO_RENDER_METAL 0 +#undef SDL_VIDEO_RENDER_OGL +#define SDL_VIDEO_RENDER_OGL 0 +#undef SDL_VIDEO_RENDER_OGL_ES +#define SDL_VIDEO_RENDER_OGL_ES 0 +#undef SDL_VIDEO_RENDER_OGL_ES2 +#define SDL_VIDEO_RENDER_OGL_ES2 0 +#undef SDL_VIDEO_RENDER_DIRECTFB +#define SDL_VIDEO_RENDER_DIRECTFB 0 +#undef SDL_VIDEO_RENDER_PS2 +#define SDL_VIDEO_RENDER_PS2 0 +#undef SDL_VIDEO_RENDER_PSP +#define SDL_VIDEO_RENDER_PSP 0 +#undef SDL_VIDEO_RENDER_VITA_GXM +#define SDL_VIDEO_RENDER_VITA_GXM 0 +#endif /* SDL_RENDER_DISABLED */ + +#define SDL_HAS_RENDER_DRIVER \ + (SDL_VIDEO_RENDER_SW | \ + SDL_VIDEO_RENDER_D3D | \ + SDL_VIDEO_RENDER_D3D11 | \ + SDL_VIDEO_RENDER_D3D12 | \ + SDL_VIDEO_RENDER_METAL | \ + SDL_VIDEO_RENDER_OGL | \ + SDL_VIDEO_RENDER_OGL_ES | \ + SDL_VIDEO_RENDER_OGL_ES2 | \ + SDL_VIDEO_RENDER_DIRECTFB | \ + SDL_VIDEO_RENDER_PS2 | \ + SDL_VIDEO_RENDER_PSP | \ + SDL_VIDEO_RENDER_VITA_GXM) + +#if !defined(SDL_RENDER_DISABLED) && !SDL_HAS_RENDER_DRIVER +#error SDL_RENDER enabled without any backend drivers. +#endif + +#include "SDL_assert.h" +#include "SDL_log.h" + +#endif /* SDL_internal_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/SDL_list.c b/SDL2-2.30.5/src/SDL_list.c new file mode 100644 index 0000000..b7f45de --- /dev/null +++ b/SDL2-2.30.5/src/SDL_list.c @@ -0,0 +1,89 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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.h" +#include "./SDL_list.h" + +/* Push */ +int SDL_ListAdd(SDL_ListNode **head, void *ent) +{ + SDL_ListNode *node = SDL_malloc(sizeof(*node)); + + if (!node) { + return SDL_OutOfMemory(); + } + + node->entry = ent; + node->next = *head; + *head = node; + return 0; +} + +/* Pop from end as a FIFO (if add with SDL_ListAdd) */ +void SDL_ListPop(SDL_ListNode **head, void **ent) +{ + SDL_ListNode **ptr = head; + + /* Invalid or empty */ + if (!head || !*head) { + return; + } + + while ((*ptr)->next) { + ptr = &(*ptr)->next; + } + + if (ent) { + *ent = (*ptr)->entry; + } + + SDL_free(*ptr); + *ptr = NULL; +} + +void SDL_ListRemove(SDL_ListNode **head, void *ent) +{ + SDL_ListNode **ptr = head; + + while (*ptr) { + if ((*ptr)->entry == ent) { + SDL_ListNode *tmp = *ptr; + *ptr = (*ptr)->next; + SDL_free(tmp); + return; + } + ptr = &(*ptr)->next; + } +} + +void SDL_ListClear(SDL_ListNode **head) +{ + SDL_ListNode *l = *head; + *head = NULL; + while (l) { + SDL_ListNode *tmp = l; + l = l->next; + SDL_free(tmp); + } +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/events/SDL_sysevents.h b/SDL2-2.30.5/src/SDL_list.h similarity index 68% rename from SDL2-2.0.12/src/events/SDL_sysevents.h rename to SDL2-2.30.5/src/SDL_list.h index 73f8f7f..f855e9b 100644 --- a/SDL2-2.0.12/src/events/SDL_sysevents.h +++ b/SDL2-2.30.5/src/SDL_list.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -18,19 +18,21 @@ misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ -#include "../SDL_internal.h" -#include "../video/SDL_sysvideo.h" +#ifndef SDL_list_h_ +#define SDL_list_h_ -/* Useful functions and variables from SDL_sysevents.c */ +typedef struct SDL_ListNode +{ + void *entry; + struct SDL_ListNode *next; +} SDL_ListNode; -#if defined(__HAIKU__) -/* The Haiku event loops run in a separate thread */ -#define MUST_THREAD_EVENTS -#endif +int SDL_ListAdd(SDL_ListNode **head, void *ent); +void SDL_ListPop(SDL_ListNode **head, void **ent); +void SDL_ListRemove(SDL_ListNode **head, void *ent); +void SDL_ListClear(SDL_ListNode **head); -#ifdef __WIN32__ /* Windows doesn't allow a separate event thread */ -#define CANT_THREAD_EVENTS -#endif +#endif /* SDL_list_h_ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/SDL_log.c b/SDL2-2.30.5/src/SDL_log.c new file mode 100644 index 0000000..9e324e3 --- /dev/null +++ b/SDL2-2.30.5/src/SDL_log.c @@ -0,0 +1,611 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#if defined(__WIN32__) || defined(__WINRT__) || defined(__GDK__) +#include "core/windows/SDL_windows.h" +#endif + +/* Simple log messages in SDL */ + +#include "SDL_error.h" +#include "SDL_log.h" +#include "SDL_hints.h" +#include "SDL_mutex.h" +#include "SDL_log_c.h" + +#ifdef HAVE_STDIO_H +#include +#endif + +#if defined(__ANDROID__) +#include +#endif + +#include "stdlib/SDL_vacopy.h" + +/* The size of the stack buffer to use for rendering log messages. */ +#define SDL_MAX_LOG_MESSAGE_STACK 256 + +#define DEFAULT_CATEGORY -1 + +typedef struct SDL_LogLevel +{ + int category; + SDL_LogPriority priority; + struct SDL_LogLevel *next; +} SDL_LogLevel; + +/* The default log output function */ +static void SDLCALL SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority, const char *message); + +static SDL_LogLevel *SDL_loglevels; +static SDL_bool SDL_forced_priority = SDL_FALSE; +static SDL_LogPriority SDL_forced_priority_level; +static SDL_LogOutputFunction SDL_log_function = SDL_LogOutput; +static void *SDL_log_userdata = NULL; +static SDL_mutex *log_function_mutex = NULL; + +/* If this list changes, update the documentation for SDL_HINT_LOGGING */ +static const char *SDL_priority_prefixes[] = { + NULL, + "VERBOSE", + "DEBUG", + "INFO", + "WARN", + "ERROR", + "CRITICAL" +}; +SDL_COMPILE_TIME_ASSERT(priority_prefixes, SDL_arraysize(SDL_priority_prefixes) == SDL_NUM_LOG_PRIORITIES); + +/* If this list changes, update the documentation for SDL_HINT_LOGGING */ +static const char *SDL_category_prefixes[] = { + "APP", + "ERROR", + "ASSERT", + "SYSTEM", + "AUDIO", + "VIDEO", + "RENDER", + "INPUT", + "TEST" +}; +SDL_COMPILE_TIME_ASSERT(category_prefixes, SDL_arraysize(SDL_category_prefixes) == SDL_LOG_CATEGORY_RESERVED1); + +#ifdef __ANDROID__ +static int SDL_android_priority[SDL_NUM_LOG_PRIORITIES] = { + ANDROID_LOG_UNKNOWN, + ANDROID_LOG_VERBOSE, + ANDROID_LOG_DEBUG, + ANDROID_LOG_INFO, + ANDROID_LOG_WARN, + ANDROID_LOG_ERROR, + ANDROID_LOG_FATAL +}; +#endif /* __ANDROID__ */ + +void SDL_LogInit(void) +{ + if (!log_function_mutex) { + /* if this fails we'll try to continue without it. */ + log_function_mutex = SDL_CreateMutex(); + } +} + +void SDL_LogQuit(void) +{ + SDL_LogResetPriorities(); + if (log_function_mutex) { + SDL_DestroyMutex(log_function_mutex); + log_function_mutex = NULL; + } +} + +void SDL_LogSetAllPriority(SDL_LogPriority priority) +{ + SDL_LogLevel *entry; + + for (entry = SDL_loglevels; entry; entry = entry->next) { + entry->priority = priority; + } + + SDL_forced_priority = SDL_TRUE; + SDL_forced_priority_level = priority; +} + +void SDL_LogSetPriority(int category, SDL_LogPriority priority) +{ + SDL_LogLevel *entry; + + for (entry = SDL_loglevels; entry; entry = entry->next) { + if (entry->category == category) { + entry->priority = priority; + return; + } + } + + /* Create a new entry */ + entry = (SDL_LogLevel *)SDL_malloc(sizeof(*entry)); + if (entry) { + entry->category = category; + entry->priority = priority; + entry->next = SDL_loglevels; + SDL_loglevels = entry; + } +} + +static SDL_bool SDL_ParseLogCategory(const char *string, size_t length, int *category) +{ + int i; + + if (SDL_isdigit(*string)) { + *category = SDL_atoi(string); + return SDL_TRUE; + } + + if (*string == '*') { + *category = DEFAULT_CATEGORY; + return SDL_TRUE; + } + + for (i = 0; i < SDL_arraysize(SDL_category_prefixes); ++i) { + if (SDL_strncasecmp(string, SDL_category_prefixes[i], length) == 0) { + *category = i; + return SDL_TRUE; + } + } + return SDL_FALSE; +} + +static SDL_bool SDL_ParseLogPriority(const char *string, size_t length, SDL_LogPriority *priority) +{ + int i; + + if (SDL_isdigit(*string)) { + i = SDL_atoi(string); + if (i == 0) { + /* 0 has a special meaning of "disable this category" */ + *priority = SDL_NUM_LOG_PRIORITIES; + return SDL_TRUE; + } + if (i >= SDL_LOG_PRIORITY_VERBOSE && i < SDL_NUM_LOG_PRIORITIES) { + *priority = (SDL_LogPriority)i; + return SDL_TRUE; + } + return SDL_FALSE; + } + + if (SDL_strncasecmp(string, "quiet", length) == 0) { + *priority = SDL_NUM_LOG_PRIORITIES; + return SDL_TRUE; + } + + for (i = SDL_LOG_PRIORITY_VERBOSE; i < SDL_NUM_LOG_PRIORITIES; ++i) { + if (SDL_strncasecmp(string, SDL_priority_prefixes[i], length) == 0) { + *priority = (SDL_LogPriority)i; + return SDL_TRUE; + } + } + return SDL_FALSE; +} + +static SDL_bool SDL_ParseLogCategoryPriority(const char *hint, int category, SDL_LogPriority *priority) +{ + const char *name, *next; + int current_category; + + if (category == DEFAULT_CATEGORY && SDL_strchr(hint, '=') == NULL) { + return SDL_ParseLogPriority(hint, SDL_strlen(hint), priority); + } + + for (name = hint; name; name = next) { + const char *sep = SDL_strchr(name, '='); + if (!sep) { + break; + } + next = SDL_strchr(sep, ','); + if (next) { + ++next; + } + + if (SDL_ParseLogCategory(name, (sep - name), ¤t_category)) { + if (current_category == category) { + const char *value = sep + 1; + size_t len; + if (next) { + len = (next - value - 1); + } else { + len = SDL_strlen(value); + } + return SDL_ParseLogPriority(value, len, priority); + } + } + } + return SDL_FALSE; +} + +static SDL_LogPriority SDL_GetDefaultLogPriority(int category) +{ + const char *hint = SDL_GetHint(SDL_HINT_LOGGING); + if (hint) { + SDL_LogPriority priority; + + if (SDL_ParseLogCategoryPriority(hint, category, &priority)) { + return priority; + } + if (SDL_ParseLogCategoryPriority(hint, DEFAULT_CATEGORY, &priority)) { + return priority; + } + } + + switch (category) { + case SDL_LOG_CATEGORY_APPLICATION: + return SDL_LOG_PRIORITY_INFO; + case SDL_LOG_CATEGORY_ASSERT: + return SDL_LOG_PRIORITY_WARN; + case SDL_LOG_CATEGORY_TEST: + return SDL_LOG_PRIORITY_VERBOSE; + default: + return SDL_LOG_PRIORITY_ERROR; + } +} + +SDL_LogPriority SDL_LogGetPriority(int category) +{ + SDL_LogLevel *entry; + + for (entry = SDL_loglevels; entry; entry = entry->next) { + if (entry->category == category) { + return entry->priority; + } + } + + if (SDL_forced_priority) { + return SDL_forced_priority_level; + } + + return SDL_GetDefaultLogPriority(category); +} + +void SDL_LogResetPriorities(void) +{ + SDL_LogLevel *entry; + + while (SDL_loglevels) { + entry = SDL_loglevels; + SDL_loglevels = entry->next; + SDL_free(entry); + } + SDL_forced_priority = SDL_FALSE; +} + +void SDL_Log(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + SDL_LogMessageV(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, fmt, ap); + va_end(ap); +} + +void SDL_LogVerbose(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + SDL_LogMessageV(category, SDL_LOG_PRIORITY_VERBOSE, fmt, ap); + va_end(ap); +} + +void SDL_LogDebug(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + SDL_LogMessageV(category, SDL_LOG_PRIORITY_DEBUG, fmt, ap); + va_end(ap); +} + +void SDL_LogInfo(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + SDL_LogMessageV(category, SDL_LOG_PRIORITY_INFO, fmt, ap); + va_end(ap); +} + +void SDL_LogWarn(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + SDL_LogMessageV(category, SDL_LOG_PRIORITY_WARN, fmt, ap); + va_end(ap); +} + +void SDL_LogError(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + SDL_LogMessageV(category, SDL_LOG_PRIORITY_ERROR, fmt, ap); + va_end(ap); +} + +void SDL_LogCritical(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + SDL_LogMessageV(category, SDL_LOG_PRIORITY_CRITICAL, fmt, ap); + va_end(ap); +} + +void SDL_LogMessage(int category, SDL_LogPriority priority, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + SDL_LogMessageV(category, priority, fmt, ap); + va_end(ap); +} + +#ifdef __ANDROID__ +static const char *GetCategoryPrefix(int category) +{ + if (category < SDL_LOG_CATEGORY_RESERVED1) { + return SDL_category_prefixes[category]; + } + if (category < SDL_LOG_CATEGORY_CUSTOM) { + return "RESERVED"; + } + return "CUSTOM"; +} +#endif /* __ANDROID__ */ + +void SDL_LogMessageV(int category, SDL_LogPriority priority, const char *fmt, va_list ap) +{ + char *message = NULL; + char stack_buf[SDL_MAX_LOG_MESSAGE_STACK]; + size_t len_plus_term; + int len; + va_list aq; + + /* Nothing to do if we don't have an output function */ + if (!SDL_log_function) { + return; + } + + /* Make sure we don't exceed array bounds */ + if ((int)priority < 0 || priority >= SDL_NUM_LOG_PRIORITIES) { + return; + } + + /* See if we want to do anything with this message */ + if (priority < SDL_LogGetPriority(category)) { + return; + } + + if (!log_function_mutex) { + /* this mutex creation can race if you log from two threads at startup. You should have called SDL_Init first! */ + log_function_mutex = SDL_CreateMutex(); + } + + /* Render into stack buffer */ + va_copy(aq, ap); + len = SDL_vsnprintf(stack_buf, sizeof(stack_buf), fmt, aq); + va_end(aq); + + if (len < 0) { + return; + } + + /* If message truncated, allocate and re-render */ + if (len >= sizeof(stack_buf) && SDL_size_add_overflow(len, 1, &len_plus_term) == 0) { + /* Allocate exactly what we need, including the zero-terminator */ + message = (char *)SDL_malloc(len_plus_term); + if (!message) { + return; + } + va_copy(aq, ap); + len = SDL_vsnprintf(message, len_plus_term, fmt, aq); + va_end(aq); + } else { + message = stack_buf; + } + + /* Chop off final endline. */ + if ((len > 0) && (message[len - 1] == '\n')) { + message[--len] = '\0'; + if ((len > 0) && (message[len - 1] == '\r')) { /* catch "\r\n", too. */ + message[--len] = '\0'; + } + } + + SDL_LockMutex(log_function_mutex); + SDL_log_function(SDL_log_userdata, category, priority, message); + SDL_UnlockMutex(log_function_mutex); + + /* Free only if dynamically allocated */ + if (message != stack_buf) { + SDL_free(message); + } +} + +#if defined(__WIN32__) && !defined(HAVE_STDIO_H) && !defined(__WINRT__) && !defined(__GDK__) +/* Flag tracking the attachment of the console: 0=unattached, 1=attached to a console, 2=attached to a file, -1=error */ +static int consoleAttached = 0; + +/* Handle to stderr output of console. */ +static HANDLE stderrHandle = NULL; +#endif + +static void SDLCALL SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority, + const char *message) +{ +#if defined(__WIN32__) || defined(__WINRT__) || defined(__GDK__) + /* Way too many allocations here, urgh */ + /* Note: One can't call SDL_SetError here, since that function itself logs. */ + { + char *output; + size_t length; + LPTSTR tstr; + SDL_bool isstack; + +#if !defined(HAVE_STDIO_H) && !defined(__WINRT__) && !defined(__GDK__) + BOOL attachResult; + DWORD attachError; + DWORD charsWritten; + DWORD consoleMode; + + /* Maybe attach console and get stderr handle */ + if (consoleAttached == 0) { + attachResult = AttachConsole(ATTACH_PARENT_PROCESS); + if (!attachResult) { + attachError = GetLastError(); + if (attachError == ERROR_INVALID_HANDLE) { + /* This is expected when running from Visual Studio */ + /*OutputDebugString(TEXT("Parent process has no console\r\n"));*/ + consoleAttached = -1; + } else if (attachError == ERROR_GEN_FAILURE) { + OutputDebugString(TEXT("Could not attach to console of parent process\r\n")); + consoleAttached = -1; + } else if (attachError == ERROR_ACCESS_DENIED) { + /* Already attached */ + consoleAttached = 1; + } else { + OutputDebugString(TEXT("Error attaching console\r\n")); + consoleAttached = -1; + } + } else { + /* Newly attached */ + consoleAttached = 1; + } + + if (consoleAttached == 1) { + stderrHandle = GetStdHandle(STD_ERROR_HANDLE); + + if (GetConsoleMode(stderrHandle, &consoleMode) == 0) { + /* WriteConsole fails if the output is redirected to a file. Must use WriteFile instead. */ + consoleAttached = 2; + } + } + } +#endif /* !defined(HAVE_STDIO_H) && !defined(__WINRT__) && !defined(__GDK__) */ + + length = SDL_strlen(SDL_priority_prefixes[priority]) + 2 + SDL_strlen(message) + 1 + 1 + 1; + output = SDL_small_alloc(char, length, &isstack); + (void)SDL_snprintf(output, length, "%s: %s\r\n", SDL_priority_prefixes[priority], message); + tstr = WIN_UTF8ToString(output); + + /* Output to debugger */ + OutputDebugString(tstr); + +#if !defined(HAVE_STDIO_H) && !defined(__WINRT__) && !defined(__GDK__) + /* Screen output to stderr, if console was attached. */ + if (consoleAttached == 1) { + if (!WriteConsole(stderrHandle, tstr, (DWORD)SDL_tcslen(tstr), &charsWritten, NULL)) { + OutputDebugString(TEXT("Error calling WriteConsole\r\n")); + if (GetLastError() == ERROR_NOT_ENOUGH_MEMORY) { + OutputDebugString(TEXT("Insufficient heap memory to write message\r\n")); + } + } + + } else if (consoleAttached == 2) { + if (!WriteFile(stderrHandle, output, (DWORD)SDL_strlen(output), &charsWritten, NULL)) { + OutputDebugString(TEXT("Error calling WriteFile\r\n")); + } + } +#endif /* !defined(HAVE_STDIO_H) && !defined(__WINRT__) && !defined(__GDK__) */ + + SDL_free(tstr); + SDL_small_free(output, isstack); + } +#elif defined(__ANDROID__) + { + char tag[32]; + + SDL_snprintf(tag, SDL_arraysize(tag), "SDL/%s", GetCategoryPrefix(category)); + __android_log_write(SDL_android_priority[priority], tag, message); + } +#elif defined(__APPLE__) && (defined(SDL_VIDEO_DRIVER_COCOA) || defined(SDL_VIDEO_DRIVER_UIKIT)) + /* Technically we don't need Cocoa/UIKit, but that's where this function is defined for now. + */ + extern void SDL_NSLog(const char *prefix, const char *text); + { + SDL_NSLog(SDL_priority_prefixes[priority], message); + return; + } +#elif defined(__PSP__) || defined(__PS2__) + { + FILE *pFile; + pFile = fopen("SDL_Log.txt", "a"); + if (pFile) { + (void)fprintf(pFile, "%s: %s\n", SDL_priority_prefixes[priority], message); + (void)fclose(pFile); + } + } +#elif defined(__VITA__) + { + FILE *pFile; + pFile = fopen("ux0:/data/SDL_Log.txt", "a"); + if (pFile) { + (void)fprintf(pFile, "%s: %s\n", SDL_priority_prefixes[priority], message); + (void)fclose(pFile); + } + } +#elif defined(__3DS__) + { + FILE *pFile; + pFile = fopen("sdmc:/3ds/SDL_Log.txt", "a"); + if (pFile) { + (void)fprintf(pFile, "%s: %s\n", SDL_priority_prefixes[priority], message); + (void)fclose(pFile); + } + } +#endif +#if defined(HAVE_STDIO_H) && \ + !(defined(__APPLE__) && (defined(SDL_VIDEO_DRIVER_COCOA) || defined(SDL_VIDEO_DRIVER_UIKIT))) + fprintf(stderr, "%s: %s\n", SDL_priority_prefixes[priority], message); +#ifdef __NACL__ + fflush(stderr); +#endif +#endif +} + +void SDL_LogGetOutputFunction(SDL_LogOutputFunction *callback, void **userdata) +{ + if (callback) { + *callback = SDL_log_function; + } + if (userdata) { + *userdata = SDL_log_userdata; + } +} + +void SDL_LogSetOutputFunction(SDL_LogOutputFunction callback, void *userdata) +{ + SDL_log_function = callback; + SDL_log_userdata = userdata; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/SDL_log_c.h b/SDL2-2.30.5/src/SDL_log_c.h new file mode 100644 index 0000000..4d6676d --- /dev/null +++ b/SDL2-2.30.5/src/SDL_log_c.h @@ -0,0 +1,33 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +/* This file defines useful function for working with SDL logging */ + +#ifndef SDL_log_c_h_ +#define SDL_log_c_h_ + +extern void SDL_LogInit(void); +extern void SDL_LogQuit(void); + +#endif /* SDL_log_c_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/SDL_utils.c b/SDL2-2.30.5/src/SDL_utils.c new file mode 100644 index 0000000..10a3083 --- /dev/null +++ b/SDL2-2.30.5/src/SDL_utils.c @@ -0,0 +1,52 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_utils_c.h" + +/* Common utility functions that aren't in the public API */ + +int SDL_powerof2(int x) +{ + int value; + + if (x <= 0) { + /* Return some sane value - we shouldn't hit this in our use cases */ + return 1; + } + + /* This trick works for 32-bit values */ + { + SDL_COMPILE_TIME_ASSERT(SDL_powerof2, sizeof(x) == sizeof(Uint32)); + } + value = x; + value -= 1; + value |= value >> 1; + value |= value >> 2; + value |= value >> 4; + value |= value >> 8; + value |= value >> 16; + value += 1; + + return value; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/SDL_utils_c.h b/SDL2-2.30.5/src/SDL_utils_c.h new file mode 100644 index 0000000..4c00d8b --- /dev/null +++ b/SDL2-2.30.5/src/SDL_utils_c.h @@ -0,0 +1,32 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#ifndef SDL_utils_h_ +#define SDL_utils_h_ + +/* Common utility functions that aren't in the public API */ + +/* Return the smallest power of 2 greater than or equal to 'x' */ +extern int SDL_powerof2(int x); + +#endif /* SDL_utils_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/atomic/SDL_atomic.c b/SDL2-2.30.5/src/atomic/SDL_atomic.c similarity index 64% rename from SDL2-2.0.12/src/atomic/SDL_atomic.c rename to SDL2-2.30.5/src/atomic/SDL_atomic.c index 6a84cd5..e843c8d 100644 --- a/SDL2-2.0.12/src/atomic/SDL_atomic.c +++ b/SDL2-2.30.5/src/atomic/SDL_atomic.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -36,33 +36,32 @@ #endif /* The __atomic_load_n() intrinsic showed up in different times for different compilers. */ -#if defined(HAVE_GCC_ATOMICS) -# if defined(__clang__) -# if __has_builtin(__atomic_load_n) - /* !!! FIXME: this advertises as available in the NDK but uses an external symbol we don't have. - It might be in a later NDK or we might need an extra library? --ryan. */ -# if !defined(__ANDROID__) -# define HAVE_ATOMIC_LOAD_N 1 -# endif -# endif -# elif defined(__GNUC__) -# if (__GNUC__ >= 5) -# define HAVE_ATOMIC_LOAD_N 1 -# endif -# endif +#if defined(__clang__) +#if __has_builtin(__atomic_load_n) || defined(HAVE_GCC_ATOMICS) +/* !!! FIXME: this advertises as available in the NDK but uses an external symbol we don't have. + It might be in a later NDK or we might need an extra library? --ryan. */ +#if !defined(__ANDROID__) +#define HAVE_ATOMIC_LOAD_N 1 +#endif +#endif +#elif defined(__GNUC__) +#if (__GNUC__ >= 5) +#define HAVE_ATOMIC_LOAD_N 1 +#endif #endif +/* *INDENT-OFF* */ /* clang-format off */ #if defined(__WATCOMC__) && defined(__386__) SDL_COMPILE_TIME_ASSERT(intsize, 4==sizeof(int)); #define HAVE_WATCOM_ATOMICS -extern _inline int _SDL_xchg_watcom(volatile int *a, int v); +extern __inline int _SDL_xchg_watcom(volatile int *a, int v); #pragma aux _SDL_xchg_watcom = \ "lock xchg [ecx], eax" \ parm [ecx] [eax] \ value [eax] \ modify exact [eax]; -extern _inline unsigned char _SDL_cmpxchg_watcom(volatile int *a, int newval, int oldval); +extern __inline unsigned char _SDL_cmpxchg_watcom(volatile int *a, int newval, int oldval); #pragma aux _SDL_cmpxchg_watcom = \ "lock cmpxchg [edx], ecx" \ "setz al" \ @@ -70,13 +69,15 @@ extern _inline unsigned char _SDL_cmpxchg_watcom(volatile int *a, int newval, in value [al] \ modify exact [eax]; -extern _inline int _SDL_xadd_watcom(volatile int *a, int v); +extern __inline int _SDL_xadd_watcom(volatile int *a, int v); #pragma aux _SDL_xadd_watcom = \ "lock xadd [ecx], eax" \ parm [ecx] [eax] \ value [eax] \ modify exact [eax]; + #endif /* __WATCOMC__ && __386__ */ +/* *INDENT-ON* */ /* clang-format on */ /* If any of the operations are not provided then we must emulate some @@ -102,22 +103,20 @@ extern _inline int _SDL_xadd_watcom(volatile int *a, int v); */ #if !defined(HAVE_MSC_ATOMICS) && !defined(HAVE_GCC_ATOMICS) && !defined(__MACOSX__) && !defined(__SOLARIS__) && !defined(HAVE_WATCOM_ATOMICS) -#define EMULATE_CAS 1 +#define EMULATE_CAS #endif -#if EMULATE_CAS +#ifdef EMULATE_CAS static SDL_SpinLock locks[32]; -static SDL_INLINE void -enterLock(void *a) +static SDL_INLINE void enterLock(void *a) { uintptr_t index = ((((uintptr_t)a) >> 3) & 0x1f); SDL_AtomicLock(&locks[index]); } -static SDL_INLINE void -leaveLock(void *a) +static SDL_INLINE void leaveLock(void *a) { uintptr_t index = ((((uintptr_t)a) >> 3) & 0x1f); @@ -125,23 +124,20 @@ leaveLock(void *a) } #endif - -SDL_bool -SDL_AtomicCAS(SDL_atomic_t *a, int oldval, int newval) +SDL_bool SDL_AtomicCAS(SDL_atomic_t *a, int oldval, int newval) { #ifdef HAVE_MSC_ATOMICS - return (_InterlockedCompareExchange((long*)&a->value, (long)newval, (long)oldval) == (long)oldval); + SDL_COMPILE_TIME_ASSERT(atomic_cas, sizeof(long) == sizeof(a->value)); + return _InterlockedCompareExchange((long *)&a->value, (long)newval, (long)oldval) == (long)oldval; #elif defined(HAVE_WATCOM_ATOMICS) - return (SDL_bool) _SDL_cmpxchg_watcom(&a->value, newval, oldval); + return (SDL_bool)_SDL_cmpxchg_watcom(&a->value, newval, oldval); #elif defined(HAVE_GCC_ATOMICS) return (SDL_bool) __sync_bool_compare_and_swap(&a->value, oldval, newval); #elif defined(__MACOSX__) /* this is deprecated in 10.12 sdk; favor gcc atomics. */ return (SDL_bool) OSAtomicCompareAndSwap32Barrier(oldval, newval, &a->value); -#elif defined(__SOLARIS__) && defined(_LP64) - return (SDL_bool) ((int) atomic_cas_64((volatile uint64_t*)&a->value, (uint64_t)oldval, (uint64_t)newval) == oldval); -#elif defined(__SOLARIS__) && !defined(_LP64) - return (SDL_bool) ((int) atomic_cas_32((volatile uint32_t*)&a->value, (uint32_t)oldval, (uint32_t)newval) == oldval); -#elif EMULATE_CAS +#elif defined(__SOLARIS__) + return (SDL_bool)((int)atomic_cas_uint((volatile uint_t *)&a->value, (uint_t)oldval, (uint_t)newval) == oldval); +#elif defined(EMULATE_CAS) SDL_bool retval = SDL_FALSE; enterLock(a); @@ -153,19 +149,16 @@ SDL_AtomicCAS(SDL_atomic_t *a, int oldval, int newval) return retval; #else - #error Please define your platform. +#error Please define your platform. #endif } -SDL_bool -SDL_AtomicCASPtr(void **a, void *oldval, void *newval) +SDL_bool SDL_AtomicCASPtr(void **a, void *oldval, void *newval) { -#if defined(HAVE_MSC_ATOMICS) && (_M_IX86) - return (_InterlockedCompareExchange((long*)a, (long)newval, (long)oldval) == (long)oldval); -#elif defined(HAVE_MSC_ATOMICS) && (!_M_IX86) - return (_InterlockedCompareExchangePointer(a, newval, oldval) == oldval); +#if defined(HAVE_MSC_ATOMICS) + return _InterlockedCompareExchangePointer(a, newval, oldval) == oldval; #elif defined(HAVE_WATCOM_ATOMICS) - return (SDL_bool) _SDL_cmpxchg_watcom((int *)a, (long)newval, (long)oldval); + return (SDL_bool)_SDL_cmpxchg_watcom((int *)a, (long)newval, (long)oldval); #elif defined(HAVE_GCC_ATOMICS) return __sync_bool_compare_and_swap(a, oldval, newval); #elif defined(__MACOSX__) && defined(__LP64__) /* this is deprecated in 10.12 sdk; favor gcc atomics. */ @@ -173,8 +166,8 @@ SDL_AtomicCASPtr(void **a, void *oldval, void *newval) #elif defined(__MACOSX__) && !defined(__LP64__) /* this is deprecated in 10.12 sdk; favor gcc atomics. */ return (SDL_bool) OSAtomicCompareAndSwap32Barrier((int32_t)oldval, (int32_t)newval, (int32_t*) a); #elif defined(__SOLARIS__) - return (SDL_bool) (atomic_cas_ptr(a, oldval, newval) == oldval); -#elif EMULATE_CAS + return (SDL_bool)(atomic_cas_ptr(a, oldval, newval) == oldval); +#elif defined(EMULATE_CAS) SDL_bool retval = SDL_FALSE; enterLock(a); @@ -186,23 +179,21 @@ SDL_AtomicCASPtr(void **a, void *oldval, void *newval) return retval; #else - #error Please define your platform. +#error Please define your platform. #endif } -int -SDL_AtomicSet(SDL_atomic_t *a, int v) +int SDL_AtomicSet(SDL_atomic_t *a, int v) { #ifdef HAVE_MSC_ATOMICS - return _InterlockedExchange((long*)&a->value, v); + SDL_COMPILE_TIME_ASSERT(atomic_set, sizeof(long) == sizeof(a->value)); + return _InterlockedExchange((long *)&a->value, v); #elif defined(HAVE_WATCOM_ATOMICS) return _SDL_xchg_watcom(&a->value, v); #elif defined(HAVE_GCC_ATOMICS) return __sync_lock_test_and_set(&a->value, v); -#elif defined(__SOLARIS__) && defined(_LP64) - return (int) atomic_swap_64((volatile uint64_t*)&a->value, (uint64_t)v); -#elif defined(__SOLARIS__) && !defined(_LP64) - return (int) atomic_swap_32((volatile uint32_t*)&a->value, (uint32_t)v); +#elif defined(__SOLARIS__) + return (int)atomic_swap_uint((volatile uint_t *)&a->value, v); #else int value; do { @@ -212,15 +203,12 @@ SDL_AtomicSet(SDL_atomic_t *a, int v) #endif } -void* -SDL_AtomicSetPtr(void **a, void *v) +void *SDL_AtomicSetPtr(void **a, void *v) { -#if defined(HAVE_MSC_ATOMICS) && (_M_IX86) - return (void *) _InterlockedExchange((long *)a, (long) v); -#elif defined(HAVE_MSC_ATOMICS) && (!_M_IX86) +#if defined(HAVE_MSC_ATOMICS) return _InterlockedExchangePointer(a, v); #elif defined(HAVE_WATCOM_ATOMICS) - return (void *) _SDL_xchg_watcom((int *)a, (long)v); + return (void *)_SDL_xchg_watcom((int *)a, (long)v); #elif defined(HAVE_GCC_ATOMICS) return __sync_lock_test_and_set(a, v); #elif defined(__SOLARIS__) @@ -234,11 +222,11 @@ SDL_AtomicSetPtr(void **a, void *v) #endif } -int -SDL_AtomicAdd(SDL_atomic_t *a, int v) +int SDL_AtomicAdd(SDL_atomic_t *a, int v) { #ifdef HAVE_MSC_ATOMICS - return _InterlockedExchangeAdd((long*)&a->value, v); + SDL_COMPILE_TIME_ASSERT(atomic_add, sizeof(long) == sizeof(a->value)); + return _InterlockedExchangeAdd((long *)&a->value, v); #elif defined(HAVE_WATCOM_ATOMICS) return _SDL_xadd_watcom(&a->value, v); #elif defined(HAVE_GCC_ATOMICS) @@ -246,11 +234,7 @@ SDL_AtomicAdd(SDL_atomic_t *a, int v) #elif defined(__SOLARIS__) int pv = a->value; membar_consumer(); -#if defined(_LP64) - atomic_add_64((volatile uint64_t*)&a->value, v); -#elif !defined(_LP64) - atomic_add_32((volatile uint32_t*)&a->value, v); -#endif + atomic_add_int((volatile uint_t *)&a->value, v); return pv; #else int value; @@ -261,11 +245,21 @@ SDL_AtomicAdd(SDL_atomic_t *a, int v) #endif } -int -SDL_AtomicGet(SDL_atomic_t *a) +int SDL_AtomicGet(SDL_atomic_t *a) { #ifdef HAVE_ATOMIC_LOAD_N return __atomic_load_n(&a->value, __ATOMIC_SEQ_CST); +#elif defined(HAVE_MSC_ATOMICS) + SDL_COMPILE_TIME_ASSERT(atomic_get, sizeof(long) == sizeof(a->value)); + return _InterlockedOr((long *)&a->value, 0); +#elif defined(HAVE_WATCOM_ATOMICS) + return _SDL_xadd_watcom(&a->value, 0); +#elif defined(HAVE_GCC_ATOMICS) + return __sync_or_and_fetch(&a->value, 0); +#elif defined(__MACOSX__) /* this is deprecated in 10.12 sdk; favor gcc atomics. */ + return sizeof(a->value) == sizeof(uint32_t) ? OSAtomicOr32Barrier(0, (volatile uint32_t *)&a->value) : OSAtomicAdd64Barrier(0, (volatile int64_t *)&a->value); +#elif defined(__SOLARIS__) + return atomic_or_uint((volatile uint_t *)&a->value, 0); #else int value; do { @@ -275,11 +269,16 @@ SDL_AtomicGet(SDL_atomic_t *a) #endif } -void * -SDL_AtomicGetPtr(void **a) +void *SDL_AtomicGetPtr(void **a) { #ifdef HAVE_ATOMIC_LOAD_N return __atomic_load_n(a, __ATOMIC_SEQ_CST); +#elif defined(HAVE_MSC_ATOMICS) + return _InterlockedCompareExchangePointer(a, NULL, NULL); +#elif defined(HAVE_GCC_ATOMICS) + return __sync_val_compare_and_swap(a, (void *)0, (void *)0); +#elif defined(__SOLARIS__) + return atomic_cas_ptr(a, (void *)0, (void *)0); #else void *value; do { @@ -293,14 +292,12 @@ SDL_AtomicGetPtr(void **a) #error This file should be built in arm mode so the mcr instruction is available for memory barriers #endif -void -SDL_MemoryBarrierReleaseFunction(void) +void SDL_MemoryBarrierReleaseFunction(void) { SDL_MemoryBarrierRelease(); } -void -SDL_MemoryBarrierAcquireFunction(void) +void SDL_MemoryBarrierAcquireFunction(void) { SDL_MemoryBarrierAcquire(); } diff --git a/SDL2-2.0.12/src/atomic/SDL_spinlock.c b/SDL2-2.30.5/src/atomic/SDL_spinlock.c similarity index 61% rename from SDL2-2.0.12/src/atomic/SDL_spinlock.c rename to SDL2-2.30.5/src/atomic/SDL_spinlock.c index aa8ae57..a2d1d3f 100644 --- a/SDL2-2.0.12/src/atomic/SDL_spinlock.c +++ b/SDL2-2.30.5/src/atomic/SDL_spinlock.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../SDL_internal.h" -#if defined(__WIN32__) || defined(__WINRT__) +#if defined(__WIN32__) || defined(__WINRT__) || defined(__GDK__) #include "../core/windows/SDL_windows.h" #endif @@ -40,21 +40,30 @@ #include #endif +#if defined(PS2) +#include +#endif + +#if !defined(HAVE_GCC_ATOMICS) && defined(__MACOSX__) +#include +#endif + +/* *INDENT-OFF* */ /* clang-format off */ #if defined(__WATCOMC__) && defined(__386__) SDL_COMPILE_TIME_ASSERT(locksize, 4==sizeof(SDL_SpinLock)); -extern _inline int _SDL_xchg_watcom(volatile int *a, int v); +extern __inline int _SDL_xchg_watcom(volatile int *a, int v); #pragma aux _SDL_xchg_watcom = \ "lock xchg [ecx], eax" \ parm [ecx] [eax] \ value [eax] \ modify exact [eax]; #endif /* __WATCOMC__ && __386__ */ +/* *INDENT-ON* */ /* clang-format on */ /* This function is where all the magic happens... */ -SDL_bool -SDL_AtomicTryLock(SDL_SpinLock *lock) +SDL_bool SDL_AtomicTryLock(SDL_SpinLock *lock) { -#if SDL_ATOMIC_DISABLED +#ifdef SDL_ATOMIC_DISABLED /* Terrible terrible damage */ static SDL_mutex *_spinlock_mutex; @@ -72,50 +81,61 @@ SDL_AtomicTryLock(SDL_SpinLock *lock) return SDL_FALSE; } +#elif defined(HAVE_GCC_ATOMICS) || defined(HAVE_GCC_SYNC_LOCK_TEST_AND_SET) + return __sync_lock_test_and_set(lock, 1) == 0; + +#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64)) + return _InterlockedExchange_acq(lock, 1) == 0; + #elif defined(_MSC_VER) SDL_COMPILE_TIME_ASSERT(locksize, sizeof(*lock) == sizeof(long)); - return (InterlockedExchange((long*)lock, 1) == 0); + return InterlockedExchange((long *)lock, 1) == 0; #elif defined(__WATCOMC__) && defined(__386__) return _SDL_xchg_watcom(lock, 1) == 0; -#elif HAVE_GCC_ATOMICS || HAVE_GCC_SYNC_LOCK_TEST_AND_SET - return (__sync_lock_test_and_set(lock, 1) == 0); - -#elif defined(__GNUC__) && defined(__arm__) && \ - (defined(__ARM_ARCH_3__) || defined(__ARM_ARCH_3M__) || \ - defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__) || \ - defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5TE__) || \ - defined(__ARM_ARCH_5TEJ__)) +#elif defined(__GNUC__) && defined(__arm__) && \ + (defined(__ARM_ARCH_3__) || defined(__ARM_ARCH_3M__) || \ + defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__) || \ + defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5TE__) || \ + defined(__ARM_ARCH_5TEJ__)) int result; #if defined(__RISCOS__) if (__cpucap_have_rex()) { - __asm__ __volatile__ ( + __asm__ __volatile__( "ldrex %0, [%2]\nteq %0, #0\nstrexeq %0, %1, [%2]" - : "=&r" (result) : "r" (1), "r" (lock) : "cc", "memory"); - return (result == 0); + : "=&r"(result) + : "r"(1), "r"(lock) + : "cc", "memory"); + return result == 0; } #endif - __asm__ __volatile__ ( + __asm__ __volatile__( "swp %0, %1, [%2]\n" - : "=&r,&r" (result) : "r,0" (1), "r,r" (lock) : "memory"); - return (result == 0); + : "=&r,&r"(result) + : "r,0"(1), "r,r"(lock) + : "memory"); + return result == 0; #elif defined(__GNUC__) && defined(__arm__) int result; - __asm__ __volatile__ ( + __asm__ __volatile__( "ldrex %0, [%2]\nteq %0, #0\nstrexeq %0, %1, [%2]" - : "=&r" (result) : "r" (1), "r" (lock) : "cc", "memory"); - return (result == 0); + : "=&r"(result) + : "r"(1), "r"(lock) + : "cc", "memory"); + return result == 0; #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) int result; __asm__ __volatile__( "lock ; xchgl %0, (%1)\n" - : "=r" (result) : "r" (lock), "0" (1) : "cc", "memory"); - return (result == 0); + : "=r"(result) + : "r"(lock), "0"(1) + : "cc", "memory"); + return result == 0; #elif defined(__MACOSX__) || defined(__IPHONEOS__) /* Maybe used for PowerPC, but the Intel asm or gcc atomics are favored. */ @@ -123,40 +143,40 @@ SDL_AtomicTryLock(SDL_SpinLock *lock) #elif defined(__SOLARIS__) && defined(_LP64) /* Used for Solaris with non-gcc compilers. */ - return (SDL_bool) ((int) atomic_cas_64((volatile uint64_t*)lock, 0, 1) == 0); + return (SDL_bool)((int)atomic_cas_64((volatile uint64_t *)lock, 0, 1) == 0); #elif defined(__SOLARIS__) && !defined(_LP64) /* Used for Solaris with non-gcc compilers. */ - return (SDL_bool) ((int) atomic_cas_32((volatile uint32_t*)lock, 0, 1) == 0); + return (SDL_bool)((int)atomic_cas_32((volatile uint32_t *)lock, 0, 1) == 0); +#elif defined(PS2) + uint32_t oldintr; + SDL_bool res = SDL_FALSE; + // disable interuption + oldintr = DIntr(); + if (*lock == 0) { + *lock = 1; + res = SDL_TRUE; + } + // enable interuption + if (oldintr) { + EIntr(); + } + return res; #else #error Please implement for your platform. return SDL_FALSE; #endif } -/* "REP NOP" is PAUSE, coded for tools that don't know it by that name. */ -#if (defined(__GNUC__) || defined(__clang__)) && (defined(__i386__) || defined(__x86_64__)) - #define PAUSE_INSTRUCTION() __asm__ __volatile__("pause\n") /* Some assemblers can't do REP NOP, so go with PAUSE. */ -#elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) - #define PAUSE_INSTRUCTION() _mm_pause() /* this is actually "rep nop" and not a SIMD instruction. No inline asm in MSVC x86-64! */ -#elif defined(__WATCOMC__) && defined(__386__) - /* watcom assembler rejects PAUSE if CPU < i686, and it refuses REP NOP as an invalid combination. Hardcode the bytes. */ - extern _inline void PAUSE_INSTRUCTION(void); - #pragma aux PAUSE_INSTRUCTION = "db 0f3h,90h" -#else - #define PAUSE_INSTRUCTION() -#endif - -void -SDL_AtomicLock(SDL_SpinLock *lock) +void SDL_AtomicLock(SDL_SpinLock *lock) { int iterations = 0; /* FIXME: Should we have an eventual timeout? */ while (!SDL_AtomicTryLock(lock)) { if (iterations < 32) { iterations++; - PAUSE_INSTRUCTION(); + SDL_CPUPauseInstruction(); } else { /* !!! FIXME: this doesn't definitely give up the current timeslice, it does different things on various platforms. */ SDL_Delay(0); @@ -164,20 +184,22 @@ SDL_AtomicLock(SDL_SpinLock *lock) } } -void -SDL_AtomicUnlock(SDL_SpinLock *lock) +void SDL_AtomicUnlock(SDL_SpinLock *lock) { -#if defined(_MSC_VER) +#if defined(HAVE_GCC_ATOMICS) || defined(HAVE_GCC_SYNC_LOCK_TEST_AND_SET) + __sync_lock_release(lock); + +#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64)) + _InterlockedExchange_rel(lock, 0); + +#elif defined(_MSC_VER) _ReadWriteBarrier(); *lock = 0; #elif defined(__WATCOMC__) && defined(__386__) - SDL_CompilerBarrier (); + SDL_CompilerBarrier(); *lock = 0; -#elif HAVE_GCC_ATOMICS || HAVE_GCC_SYNC_LOCK_TEST_AND_SET - __sync_lock_release(lock); - #elif defined(__SOLARIS__) /* Used for Solaris when not using gcc. */ *lock = 0; diff --git a/SDL2-2.0.12/src/audio/SDL_audio.c b/SDL2-2.30.5/src/audio/SDL_audio.c similarity index 60% rename from SDL2-2.0.12/src/audio/SDL_audio.c rename to SDL2-2.30.5/src/audio/SDL_audio.c index 3137493..96586fe 100644 --- a/SDL2-2.0.12/src/audio/SDL_audio.c +++ b/SDL2-2.30.5/src/audio/SDL_audio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -27,107 +27,131 @@ #include "SDL_audio_c.h" #include "SDL_sysaudio.h" #include "../thread/SDL_systhread.h" +#include "../SDL_utils_c.h" #define _THIS SDL_AudioDevice *_this +typedef struct AudioThreadStartupData +{ + SDL_AudioDevice *device; + SDL_sem *startup_semaphore; +} AudioThreadStartupData; + static SDL_AudioDriver current_audio; static SDL_AudioDevice *open_devices[16]; /* Available audio drivers */ static const AudioBootStrap *const bootstrap[] = { -#if SDL_AUDIO_DRIVER_PULSEAUDIO +#ifdef SDL_AUDIO_DRIVER_PULSEAUDIO &PULSEAUDIO_bootstrap, #endif -#if SDL_AUDIO_DRIVER_ALSA +#ifdef SDL_AUDIO_DRIVER_ALSA &ALSA_bootstrap, #endif -#if SDL_AUDIO_DRIVER_SNDIO +#ifdef SDL_AUDIO_DRIVER_SNDIO &SNDIO_bootstrap, #endif -#if SDL_AUDIO_DRIVER_NETBSD +#ifdef SDL_AUDIO_DRIVER_NETBSD &NETBSDAUDIO_bootstrap, #endif -#if SDL_AUDIO_DRIVER_OSS - &DSP_bootstrap, -#endif -#if SDL_AUDIO_DRIVER_QSA +#ifdef SDL_AUDIO_DRIVER_QSA &QSAAUDIO_bootstrap, #endif -#if SDL_AUDIO_DRIVER_SUNAUDIO +#ifdef SDL_AUDIO_DRIVER_SUNAUDIO &SUNAUDIO_bootstrap, #endif -#if SDL_AUDIO_DRIVER_ARTS +#ifdef SDL_AUDIO_DRIVER_ARTS &ARTS_bootstrap, #endif -#if SDL_AUDIO_DRIVER_ESD +#ifdef SDL_AUDIO_DRIVER_ESD &ESD_bootstrap, #endif -#if SDL_AUDIO_DRIVER_NACL +#ifdef SDL_AUDIO_DRIVER_NACL &NACLAUDIO_bootstrap, #endif -#if SDL_AUDIO_DRIVER_NAS +#ifdef SDL_AUDIO_DRIVER_NAS &NAS_bootstrap, #endif -#if SDL_AUDIO_DRIVER_WASAPI +#ifdef SDL_AUDIO_DRIVER_WASAPI &WASAPI_bootstrap, #endif -#if SDL_AUDIO_DRIVER_DSOUND +#ifdef SDL_AUDIO_DRIVER_DSOUND &DSOUND_bootstrap, #endif -#if SDL_AUDIO_DRIVER_WINMM +#ifdef SDL_AUDIO_DRIVER_WINMM &WINMM_bootstrap, #endif -#if SDL_AUDIO_DRIVER_PAUDIO +#ifdef SDL_AUDIO_DRIVER_PAUDIO &PAUDIO_bootstrap, #endif -#if SDL_AUDIO_DRIVER_HAIKU +#ifdef SDL_AUDIO_DRIVER_HAIKU &HAIKUAUDIO_bootstrap, #endif -#if SDL_AUDIO_DRIVER_COREAUDIO +#ifdef SDL_AUDIO_DRIVER_COREAUDIO &COREAUDIO_bootstrap, #endif -#if SDL_AUDIO_DRIVER_FUSIONSOUND +#ifdef SDL_AUDIO_DRIVER_FUSIONSOUND &FUSIONSOUND_bootstrap, #endif -#if SDL_AUDIO_DRIVER_OPENSLES +#ifdef SDL_AUDIO_DRIVER_AAUDIO + &aaudio_bootstrap, +#endif +#ifdef SDL_AUDIO_DRIVER_OPENSLES &openslES_bootstrap, #endif -#if SDL_AUDIO_DRIVER_ANDROID +#ifdef SDL_AUDIO_DRIVER_ANDROID &ANDROIDAUDIO_bootstrap, #endif -#if SDL_AUDIO_DRIVER_PSP +#ifdef SDL_AUDIO_DRIVER_PS2 + &PS2AUDIO_bootstrap, +#endif +#ifdef SDL_AUDIO_DRIVER_PSP &PSPAUDIO_bootstrap, #endif -#if SDL_AUDIO_DRIVER_EMSCRIPTEN +#ifdef SDL_AUDIO_DRIVER_VITA + &VITAAUD_bootstrap, +#endif +#ifdef SDL_AUDIO_DRIVER_N3DS + &N3DSAUDIO_bootstrap, +#endif +#ifdef SDL_AUDIO_DRIVER_EMSCRIPTEN &EMSCRIPTENAUDIO_bootstrap, #endif -#if SDL_AUDIO_DRIVER_JACK +#ifdef SDL_AUDIO_DRIVER_JACK &JACK_bootstrap, #endif -#if SDL_AUDIO_DRIVER_DISK +#ifdef SDL_AUDIO_DRIVER_PIPEWIRE + &PIPEWIRE_bootstrap, +#endif +#ifdef SDL_AUDIO_DRIVER_OSS + &DSP_bootstrap, +#endif +#ifdef SDL_AUDIO_DRIVER_OS2 + &OS2AUDIO_bootstrap, +#endif +#ifdef SDL_AUDIO_DRIVER_DISK &DISKAUDIO_bootstrap, #endif -#if SDL_AUDIO_DRIVER_DUMMY +#ifdef SDL_AUDIO_DRIVER_DUMMY &DUMMYAUDIO_bootstrap, #endif NULL }; - #ifdef HAVE_LIBSAMPLERATE_H #ifdef SDL_LIBSAMPLERATE_DYNAMIC static void *SRC_lib = NULL; #endif SDL_bool SRC_available = SDL_FALSE; int SRC_converter = 0; -SRC_STATE* (*SRC_src_new)(int converter_type, int channels, int *error) = NULL; +SRC_STATE *(*SRC_src_new)(int converter_type, int channels, int *error) = NULL; int (*SRC_src_process)(SRC_STATE *state, SRC_DATA *data) = NULL; int (*SRC_src_reset)(SRC_STATE *state) = NULL; -SRC_STATE* (*SRC_src_delete)(SRC_STATE *state) = NULL; -const char* (*SRC_src_strerror)(int error) = NULL; +SRC_STATE *(*SRC_src_delete)(SRC_STATE *state) = NULL; +const char *(*SRC_src_strerror)(int error) = NULL; +int (*SRC_src_simple)(SRC_DATA *data, int converter_type, int channels) = NULL; -static SDL_bool -LoadLibSampleRate(void) +static SDL_bool LoadLibSampleRate(void) { const char *hint = SDL_GetHint(SDL_HINT_AUDIO_RESAMPLING_MODE); @@ -135,15 +159,17 @@ LoadLibSampleRate(void) SRC_converter = 0; if (!hint || *hint == '0' || SDL_strcasecmp(hint, "default") == 0) { - return SDL_FALSE; /* don't load anything. */ + return SDL_FALSE; /* don't load anything. */ } else if (*hint == '1' || SDL_strcasecmp(hint, "fast") == 0) { SRC_converter = SRC_SINC_FASTEST; } else if (*hint == '2' || SDL_strcasecmp(hint, "medium") == 0) { SRC_converter = SRC_SINC_MEDIUM_QUALITY; } else if (*hint == '3' || SDL_strcasecmp(hint, "best") == 0) { SRC_converter = SRC_SINC_BEST_QUALITY; + } else if (*hint == '4' || SDL_strcasecmp(hint, "linear") == 0) { + SRC_converter = SRC_LINEAR; } else { - return SDL_FALSE; /* treat it like "default", don't load anything. */ + return SDL_FALSE; /* treat it like "default", don't load anything. */ } #ifdef SDL_LIBSAMPLERATE_DYNAMIC @@ -154,13 +180,16 @@ LoadLibSampleRate(void) return SDL_FALSE; } + /* *INDENT-OFF* */ /* clang-format off */ SRC_src_new = (SRC_STATE* (*)(int converter_type, int channels, int *error))SDL_LoadFunction(SRC_lib, "src_new"); SRC_src_process = (int (*)(SRC_STATE *state, SRC_DATA *data))SDL_LoadFunction(SRC_lib, "src_process"); SRC_src_reset = (int(*)(SRC_STATE *state))SDL_LoadFunction(SRC_lib, "src_reset"); SRC_src_delete = (SRC_STATE* (*)(SRC_STATE *state))SDL_LoadFunction(SRC_lib, "src_delete"); SRC_src_strerror = (const char* (*)(int error))SDL_LoadFunction(SRC_lib, "src_strerror"); + SRC_src_simple = (int(*)(SRC_DATA *data, int converter_type, int channels))SDL_LoadFunction(SRC_lib, "src_simple"); +/* *INDENT-ON* */ /* clang-format on */ - if (!SRC_src_new || !SRC_src_process || !SRC_src_reset || !SRC_src_delete || !SRC_src_strerror) { + if (!SRC_src_new || !SRC_src_process || !SRC_src_reset || !SRC_src_delete || !SRC_src_strerror || !SRC_src_simple) { SDL_UnloadObject(SRC_lib); SRC_lib = NULL; return SDL_FALSE; @@ -171,14 +200,14 @@ LoadLibSampleRate(void) SRC_src_reset = src_reset; SRC_src_delete = src_delete; SRC_src_strerror = src_strerror; + SRC_src_simple = src_simple; #endif SRC_available = SDL_TRUE; return SDL_TRUE; } -static void -UnloadLibSampleRate(void) +static void UnloadLibSampleRate(void) { #ifdef SDL_LIBSAMPLERATE_DYNAMIC if (SRC_lib != NULL) { @@ -196,8 +225,7 @@ UnloadLibSampleRate(void) } #endif -static SDL_AudioDevice * -get_audio_device(SDL_AudioDeviceID id) +static SDL_AudioDevice *get_audio_device(SDL_AudioDeviceID id) { id--; if ((id >= SDL_arraysize(open_devices)) || (open_devices[id] == NULL)) { @@ -208,92 +236,67 @@ get_audio_device(SDL_AudioDeviceID id) return open_devices[id]; } - /* stubs for audio drivers that don't need a specific entry point... */ -static void -SDL_AudioDetectDevices_Default(void) +static void SDL_AudioDetectDevices_Default(void) { /* you have to write your own implementation if these assertions fail. */ SDL_assert(current_audio.impl.OnlyHasDefaultOutputDevice); SDL_assert(current_audio.impl.OnlyHasDefaultCaptureDevice || !current_audio.impl.HasCaptureSupport); - SDL_AddAudioDevice(SDL_FALSE, DEFAULT_OUTPUT_DEVNAME, (void *) ((size_t) 0x1)); + SDL_AddAudioDevice(SDL_FALSE, DEFAULT_OUTPUT_DEVNAME, NULL, (void *)((size_t)0x1)); if (current_audio.impl.HasCaptureSupport) { - SDL_AddAudioDevice(SDL_TRUE, DEFAULT_INPUT_DEVNAME, (void *) ((size_t) 0x2)); + SDL_AddAudioDevice(SDL_TRUE, DEFAULT_INPUT_DEVNAME, NULL, (void *)((size_t)0x2)); } } -static void -SDL_AudioThreadInit_Default(_THIS) -{ /* no-op. */ +static void SDL_AudioThreadInit_Default(_THIS) +{ /* no-op. */ } -static void -SDL_AudioThreadDeinit_Default(_THIS) -{ /* no-op. */ +static void SDL_AudioThreadDeinit_Default(_THIS) +{ /* no-op. */ } -static void -SDL_AudioBeginLoopIteration_Default(_THIS) -{ /* no-op. */ +static void SDL_AudioWaitDevice_Default(_THIS) +{ /* no-op. */ } -static void -SDL_AudioWaitDevice_Default(_THIS) -{ /* no-op. */ +static void SDL_AudioPlayDevice_Default(_THIS) +{ /* no-op. */ } -static void -SDL_AudioPlayDevice_Default(_THIS) -{ /* no-op. */ -} - -static Uint8 * -SDL_AudioGetDeviceBuf_Default(_THIS) +static Uint8 *SDL_AudioGetDeviceBuf_Default(_THIS) { return NULL; } -static int -SDL_AudioCaptureFromDevice_Default(_THIS, void *buffer, int buflen) +static int SDL_AudioCaptureFromDevice_Default(_THIS, void *buffer, int buflen) { - return -1; /* just fail immediately. */ + return -1; /* just fail immediately. */ } -static void -SDL_AudioFlushCapture_Default(_THIS) -{ /* no-op. */ +static void SDL_AudioFlushCapture_Default(_THIS) +{ /* no-op. */ } -static void -SDL_AudioPrepareToClose_Default(_THIS) -{ /* no-op. */ +static void SDL_AudioCloseDevice_Default(_THIS) +{ /* no-op. */ } -static void -SDL_AudioCloseDevice_Default(_THIS) -{ /* no-op. */ +static void SDL_AudioDeinitialize_Default(void) +{ /* no-op. */ } -static void -SDL_AudioDeinitialize_Default(void) -{ /* no-op. */ +static void SDL_AudioFreeDeviceHandle_Default(void *handle) +{ /* no-op. */ } -static void -SDL_AudioFreeDeviceHandle_Default(void *handle) -{ /* no-op. */ -} - - -static int -SDL_AudioOpenDevice_Default(_THIS, void *handle, const char *devname, int iscapture) +static int SDL_AudioOpenDevice_Default(_THIS, const char *devname) { return SDL_Unsupported(); } -static SDL_INLINE SDL_bool -is_in_audio_device_thread(SDL_AudioDevice * device) +static SDL_INLINE SDL_bool is_in_audio_device_thread(SDL_AudioDevice *device) { /* The device thread locks the same mutex, but not through the public API. This check is in case the application, in the audio callback, @@ -306,59 +309,40 @@ is_in_audio_device_thread(SDL_AudioDevice * device) return SDL_FALSE; } -static void -SDL_AudioLockDevice_Default(SDL_AudioDevice * device) +static void SDL_AudioLockDevice_Default(SDL_AudioDevice *device) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang assumes recursive locks */ { if (!is_in_audio_device_thread(device)) { SDL_LockMutex(device->mixer_lock); } } -static void -SDL_AudioUnlockDevice_Default(SDL_AudioDevice * device) +static void SDL_AudioUnlockDevice_Default(SDL_AudioDevice *device) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang assumes recursive locks */ { if (!is_in_audio_device_thread(device)) { SDL_UnlockMutex(device->mixer_lock); } } -static void -SDL_AudioLockOrUnlockDeviceWithNoMixerLock(SDL_AudioDevice * device) -{ -} - -static void -finish_audio_entry_points_init(void) +static void finish_audio_entry_points_init(void) { /* * Fill in stub functions for unused driver entry points. This lets us * blindly call them without having to check for validity first. */ - if (current_audio.impl.SkipMixerLock) { - if (current_audio.impl.LockDevice == NULL) { - current_audio.impl.LockDevice = SDL_AudioLockOrUnlockDeviceWithNoMixerLock; - } - if (current_audio.impl.UnlockDevice == NULL) { - current_audio.impl.UnlockDevice = SDL_AudioLockOrUnlockDeviceWithNoMixerLock; - } +#define FILL_STUB(x) \ + if (current_audio.impl.x == NULL) { \ + current_audio.impl.x = SDL_Audio##x##_Default; \ } - -#define FILL_STUB(x) \ - if (current_audio.impl.x == NULL) { \ - current_audio.impl.x = SDL_Audio##x##_Default; \ - } FILL_STUB(DetectDevices); FILL_STUB(OpenDevice); FILL_STUB(ThreadInit); FILL_STUB(ThreadDeinit); - FILL_STUB(BeginLoopIteration); FILL_STUB(WaitDevice); FILL_STUB(PlayDevice); FILL_STUB(GetDeviceBuf); FILL_STUB(CaptureFromDevice); FILL_STUB(FlushCapture); - FILL_STUB(PrepareToClose); FILL_STUB(CloseDevice); FILL_STUB(LockDevice); FILL_STUB(UnlockDevice); @@ -367,21 +351,19 @@ finish_audio_entry_points_init(void) #undef FILL_STUB } - /* device hotplug support... */ -static int -add_audio_device(const char *name, void *handle, SDL_AudioDeviceItem **devices, int *devCount) +static int add_audio_device(const char *name, SDL_AudioSpec *spec, void *handle, SDL_AudioDeviceItem **devices, int *devCount) { int retval = -1; SDL_AudioDeviceItem *item; const SDL_AudioDeviceItem *i; int dupenum = 0; - SDL_assert(handle != NULL); /* we reserve NULL, audio backends can't use it. */ + SDL_assert(handle != NULL); /* we reserve NULL, audio backends can't use it. */ SDL_assert(name != NULL); - item = (SDL_AudioDeviceItem *) SDL_malloc(sizeof (SDL_AudioDeviceItem)); + item = (SDL_AudioDeviceItem *)SDL_malloc(sizeof(SDL_AudioDeviceItem)); if (!item) { return SDL_OutOfMemory(); } @@ -394,6 +376,11 @@ add_audio_device(const char *name, void *handle, SDL_AudioDeviceItem **devices, item->dupenum = 0; item->name = item->original_name; + if (spec != NULL) { + SDL_copyp(&item->spec, spec); + } else { + SDL_zero(item->spec); + } item->handle = handle; SDL_LockMutex(current_audio.detectionLock); @@ -401,50 +388,46 @@ add_audio_device(const char *name, void *handle, SDL_AudioDeviceItem **devices, for (i = *devices; i != NULL; i = i->next) { if (SDL_strcmp(name, i->original_name) == 0) { dupenum = i->dupenum + 1; - break; /* stop at the highest-numbered dupe. */ + break; /* stop at the highest-numbered dupe. */ } } if (dupenum) { const size_t len = SDL_strlen(name) + 16; - char *replacement = (char *) SDL_malloc(len); + char *replacement = (char *)SDL_malloc(len); if (!replacement) { SDL_UnlockMutex(current_audio.detectionLock); SDL_free(item->original_name); SDL_free(item); - SDL_OutOfMemory(); - return -1; + return SDL_OutOfMemory(); } - SDL_snprintf(replacement, len, "%s (%d)", name, dupenum + 1); + (void)SDL_snprintf(replacement, len, "%s (%d)", name, dupenum + 1); item->dupenum = dupenum; item->name = replacement; } item->next = *devices; *devices = item; - retval = (*devCount)++; /* !!! FIXME: this should be an atomic increment */ + retval = (*devCount)++; /* !!! FIXME: this should be an atomic increment */ SDL_UnlockMutex(current_audio.detectionLock); return retval; } -static SDL_INLINE int -add_capture_device(const char *name, void *handle) +static SDL_INLINE int add_capture_device(const char *name, SDL_AudioSpec *spec, void *handle) { SDL_assert(current_audio.impl.HasCaptureSupport); - return add_audio_device(name, handle, ¤t_audio.inputDevices, ¤t_audio.inputDeviceCount); + return add_audio_device(name, spec, handle, ¤t_audio.inputDevices, ¤t_audio.inputDeviceCount); } -static SDL_INLINE int -add_output_device(const char *name, void *handle) +static SDL_INLINE int add_output_device(const char *name, SDL_AudioSpec *spec, void *handle) { - return add_audio_device(name, handle, ¤t_audio.outputDevices, ¤t_audio.outputDeviceCount); + return add_audio_device(name, spec, handle, ¤t_audio.outputDevices, ¤t_audio.outputDeviceCount); } -static void -free_device_list(SDL_AudioDeviceItem **devices, int *devCount) +static void free_device_list(SDL_AudioDeviceItem **devices, int *devCount) { SDL_AudioDeviceItem *item, *next; for (item = *devices; item != NULL; item = next) { @@ -463,12 +446,10 @@ free_device_list(SDL_AudioDeviceItem **devices, int *devCount) *devCount = 0; } - /* The audio backends call this when a new device is plugged in. */ -void -SDL_AddAudioDevice(const int iscapture, const char *name, void *handle) +void SDL_AddAudioDevice(const SDL_bool iscapture, const char *name, SDL_AudioSpec *spec, void *handle) { - const int device_index = iscapture ? add_capture_device(name, handle) : add_output_device(name, handle); + const int device_index = iscapture ? add_capture_device(name, spec, handle) : add_output_device(name, spec, handle); if (device_index != -1) { /* Post the event, if desired */ if (SDL_GetEventState(SDL_AUDIODEVICEADDED) == SDL_ENABLE) { @@ -488,11 +469,11 @@ void SDL_OpenedAudioDeviceDisconnected(SDL_AudioDevice *device) SDL_assert(get_audio_device(device->id) == device); if (!SDL_AtomicGet(&device->enabled)) { - return; /* don't report disconnects more than once. */ + return; /* don't report disconnects more than once. */ } if (SDL_AtomicGet(&device->shutdown)) { - return; /* don't report disconnect if we're trying to close device. */ + return; /* don't report disconnect if we're trying to close device. */ } /* Ends the audio callback and mark the device as STOPPED, but the @@ -512,8 +493,7 @@ void SDL_OpenedAudioDeviceDisconnected(SDL_AudioDevice *device) } } -static void -mark_device_removed(void *handle, SDL_AudioDeviceItem *devices, SDL_bool *removedFlag) +static void mark_device_removed(void *handle, SDL_AudioDeviceItem *devices, SDL_bool *removedFlag) { SDL_AudioDeviceItem *item; SDL_assert(handle != NULL); @@ -527,11 +507,11 @@ mark_device_removed(void *handle, SDL_AudioDeviceItem *devices, SDL_bool *remove } /* The audio backends call this when a device is removed from the system. */ -void -SDL_RemoveAudioDevice(const int iscapture, void *handle) +void SDL_RemoveAudioDevice(const SDL_bool iscapture, void *handle) { int device_index; SDL_AudioDevice *device = NULL; + SDL_bool device_was_opened = SDL_FALSE; SDL_LockMutex(current_audio.detectionLock); if (iscapture) { @@ -539,54 +519,67 @@ SDL_RemoveAudioDevice(const int iscapture, void *handle) } else { mark_device_removed(handle, current_audio.outputDevices, ¤t_audio.outputDevicesRemoved); } - for (device_index = 0; device_index < SDL_arraysize(open_devices); device_index++) - { + for (device_index = 0; device_index < SDL_arraysize(open_devices); device_index++) { device = open_devices[device_index]; - if (device != NULL && device->handle == handle) - { + if (device != NULL && device->handle == handle) { + device_was_opened = SDL_TRUE; SDL_OpenedAudioDeviceDisconnected(device); break; } } + + /* Devices that aren't opened, as of 2.24.0, will post an + SDL_AUDIODEVICEREMOVED event with the `which` field set to zero. + Apps can use this to decide if they need to refresh a list of + available devices instead of closing an opened one. + Note that opened devices will send the non-zero event in + SDL_OpenedAudioDeviceDisconnected(). */ + if (!device_was_opened) { + if (SDL_GetEventState(SDL_AUDIODEVICEREMOVED) == SDL_ENABLE) { + SDL_Event event; + SDL_zero(event); + event.adevice.type = SDL_AUDIODEVICEREMOVED; + event.adevice.which = 0; + event.adevice.iscapture = iscapture ? 1 : 0; + SDL_PushEvent(&event); + } + } + SDL_UnlockMutex(current_audio.detectionLock); current_audio.impl.FreeDeviceHandle(handle); } - - /* buffer queueing support... */ -static void SDLCALL -SDL_BufferQueueDrainCallback(void *userdata, Uint8 *stream, int len) +static void SDLCALL SDL_BufferQueueDrainCallback(void *userdata, Uint8 *stream, int len) { /* this function always holds the mixer lock before being called. */ - SDL_AudioDevice *device = (SDL_AudioDevice *) userdata; + SDL_AudioDevice *device = (SDL_AudioDevice *)userdata; size_t dequeued; - SDL_assert(device != NULL); /* this shouldn't ever happen, right?! */ - SDL_assert(!device->iscapture); /* this shouldn't ever happen, right?! */ - SDL_assert(len >= 0); /* this shouldn't ever happen, right?! */ + SDL_assert(device != NULL); /* this shouldn't ever happen, right?! */ + SDL_assert(!device->iscapture); /* this shouldn't ever happen, right?! */ + SDL_assert(len >= 0); /* this shouldn't ever happen, right?! */ dequeued = SDL_ReadFromDataQueue(device->buffer_queue, stream, len); stream += dequeued; - len -= (int) dequeued; + len -= (int)dequeued; - if (len > 0) { /* fill any remaining space in the stream with silence. */ + if (len > 0) { /* fill any remaining space in the stream with silence. */ SDL_assert(SDL_CountDataQueue(device->buffer_queue) == 0); - SDL_memset(stream, device->spec.silence, len); + SDL_memset(stream, device->callbackspec.silence, len); } } -static void SDLCALL -SDL_BufferQueueFillCallback(void *userdata, Uint8 *stream, int len) +static void SDLCALL SDL_BufferQueueFillCallback(void *userdata, Uint8 *stream, int len) { /* this function always holds the mixer lock before being called. */ - SDL_AudioDevice *device = (SDL_AudioDevice *) userdata; + SDL_AudioDevice *device = (SDL_AudioDevice *)userdata; - SDL_assert(device != NULL); /* this shouldn't ever happen, right?! */ - SDL_assert(device->iscapture); /* this shouldn't ever happen, right?! */ - SDL_assert(len >= 0); /* this shouldn't ever happen, right?! */ + SDL_assert(device != NULL); /* this shouldn't ever happen, right?! */ + SDL_assert(device->iscapture); /* this shouldn't ever happen, right?! */ + SDL_assert(len >= 0); /* this shouldn't ever happen, right?! */ /* note that if this needs to allocate more space and run out of memory, we have no choice but to quietly drop the data and hope it works out @@ -594,14 +587,13 @@ SDL_BufferQueueFillCallback(void *userdata, Uint8 *stream, int len) SDL_WriteToDataQueue(device->buffer_queue, stream, len); } -int -SDL_QueueAudio(SDL_AudioDeviceID devid, const void *data, Uint32 len) +int SDL_QueueAudio(SDL_AudioDeviceID devid, const void *data, Uint32 len) { SDL_AudioDevice *device = get_audio_device(devid); int rc = 0; if (!device) { - return -1; /* get_audio_device() will have set the error state */ + return -1; /* get_audio_device() will have set the error state */ } else if (device->iscapture) { return SDL_SetError("This is a capture device, queueing not allowed"); } else if (device->callbackspec.callback != SDL_BufferQueueDrainCallback) { @@ -617,27 +609,25 @@ SDL_QueueAudio(SDL_AudioDeviceID devid, const void *data, Uint32 len) return rc; } -Uint32 -SDL_DequeueAudio(SDL_AudioDeviceID devid, void *data, Uint32 len) +Uint32 SDL_DequeueAudio(SDL_AudioDeviceID devid, void *data, Uint32 len) { SDL_AudioDevice *device = get_audio_device(devid); Uint32 rc; - if ( (len == 0) || /* nothing to do? */ - (!device) || /* called with bogus device id */ - (!device->iscapture) || /* playback devices can't dequeue */ - (device->callbackspec.callback != SDL_BufferQueueFillCallback) ) { /* not set for queueing */ - return 0; /* just report zero bytes dequeued. */ + if ((len == 0) || /* nothing to do? */ + (!device) || /* called with bogus device id */ + (!device->iscapture) || /* playback devices can't dequeue */ + (device->callbackspec.callback != SDL_BufferQueueFillCallback)) { /* not set for queueing */ + return 0; /* just report zero bytes dequeued. */ } current_audio.impl.LockDevice(device); - rc = (Uint32) SDL_ReadFromDataQueue(device->buffer_queue, data, len); + rc = (Uint32)SDL_ReadFromDataQueue(device->buffer_queue, data, len); current_audio.impl.UnlockDevice(device); return rc; } -Uint32 -SDL_GetQueuedAudioSize(SDL_AudioDeviceID devid) +Uint32 SDL_GetQueuedAudioSize(SDL_AudioDeviceID devid) { Uint32 retval = 0; SDL_AudioDevice *device = get_audio_device(devid); @@ -648,51 +638,52 @@ SDL_GetQueuedAudioSize(SDL_AudioDeviceID devid) /* Nothing to do unless we're set up for queueing. */ if (device->callbackspec.callback == SDL_BufferQueueDrainCallback || - device->callbackspec.callback == SDL_BufferQueueFillCallback) - { + device->callbackspec.callback == SDL_BufferQueueFillCallback) { current_audio.impl.LockDevice(device); - retval = (Uint32) SDL_CountDataQueue(device->buffer_queue); + retval = (Uint32)SDL_CountDataQueue(device->buffer_queue); current_audio.impl.UnlockDevice(device); } return retval; } -void -SDL_ClearQueuedAudio(SDL_AudioDeviceID devid) +void SDL_ClearQueuedAudio(SDL_AudioDeviceID devid) { SDL_AudioDevice *device = get_audio_device(devid); if (!device) { - return; /* nothing to do. */ + return; /* nothing to do. */ } /* Blank out the device and release the mutex. Free it afterwards. */ current_audio.impl.LockDevice(device); - /* Keep up to two packets in the pool to reduce future malloc pressure. */ + /* Keep up to two packets in the pool to reduce future memory allocation pressure. */ SDL_ClearDataQueue(device->buffer_queue, SDL_AUDIOBUFFERQUEUE_PACKETLEN * 2); current_audio.impl.UnlockDevice(device); } +#ifdef SDL_AUDIO_DRIVER_ANDROID +extern void Android_JNI_AudioSetThreadPriority(int, int); +#endif /* The general mixing thread function */ -static int SDLCALL -SDL_RunAudio(void *devicep) +static int SDLCALL SDL_RunAudio(void *userdata) { - SDL_AudioDevice *device = (SDL_AudioDevice *) devicep; + const AudioThreadStartupData *startup_data = (const AudioThreadStartupData *) userdata; + SDL_AudioDevice *device = startup_data->device; void *udata = device->callbackspec.userdata; SDL_AudioCallback callback = device->callbackspec.callback; int data_len = 0; Uint8 *data; + Uint8 *device_buf_keepsafe = NULL; SDL_assert(!device->iscapture); -#if SDL_AUDIO_DRIVER_ANDROID +#ifdef SDL_AUDIO_DRIVER_ANDROID { /* Set thread priority to THREAD_PRIORITY_AUDIO */ - extern void Android_JNI_AudioSetThreadPriority(int, int); Android_JNI_AudioSetThreadPriority(device->iscapture, device->id); } #else @@ -702,17 +693,27 @@ SDL_RunAudio(void *devicep) /* Perform any thread setup */ device->threadid = SDL_ThreadID(); + + SDL_SemPost(startup_data->startup_semaphore); /* SDL_OpenAudioDevice may now continue. */ + current_audio.impl.ThreadInit(device); /* Loop, filling the audio buffers */ while (!SDL_AtomicGet(&device->shutdown)) { - current_audio.impl.BeginLoopIteration(device); data_len = device->callbackspec.size; /* Fill the current buffer with sound */ if (!device->stream && SDL_AtomicGet(&device->enabled)) { - SDL_assert(data_len == device->spec.size); data = current_audio.impl.GetDeviceBuf(device); + + if (device->stream && SDL_AtomicGet(&device->enabled)) { + /* Oops. Audio device reset and now we suddenly use a stream, */ + /* so save this devicebuf for later, to prevent de-sync */ + if (data != NULL) { + device_buf_keepsafe = data; + } + data = NULL; + } } else { /* if the device isn't enabled, we still write to the work_buffer, so the app's callback will fire with @@ -730,7 +731,7 @@ SDL_RunAudio(void *devicep) /* !!! FIXME: this should be LockDevice. */ SDL_LockMutex(device->mixer_lock); if (SDL_AtomicGet(&device->paused)) { - SDL_memset(data, device->spec.silence, data_len); + SDL_memset(data, device->callbackspec.silence, data_len); } else { callback(udata, data, data_len); } @@ -741,15 +742,27 @@ SDL_RunAudio(void *devicep) /* if this fails...oh well. We'll play silence here. */ SDL_AudioStreamPut(device->stream, data, data_len); - while (SDL_AudioStreamAvailable(device->stream) >= ((int) device->spec.size)) { + while (SDL_AudioStreamAvailable(device->stream) >= ((int)device->spec.size)) { int got; - data = SDL_AtomicGet(&device->enabled) ? current_audio.impl.GetDeviceBuf(device) : NULL; + if (SDL_AtomicGet(&device->enabled)) { + /* if device reset occured - a switch from direct output to streaming */ + /* use the already aquired device buffer */ + if (device_buf_keepsafe) { + data = device_buf_keepsafe; + device_buf_keepsafe = NULL; + } else { + /* else - normal flow, just acquire the device buffer here */ + data = current_audio.impl.GetDeviceBuf(device); + } + } else { + data = NULL; + } got = SDL_AudioStreamGet(device->stream, data ? data : device->work_buffer, device->spec.size); - SDL_assert((got < 0) || (got == device->spec.size)); + SDL_assert((got <= 0) || (got == device->spec.size)); - if (data == NULL) { /* device is having issues... */ + if (data == NULL) { /* device is having issues... */ const Uint32 delay = ((device->spec.samples * 1000) / device->spec.freq); - SDL_Delay(delay); /* wait for as long as this buffer would have played. Maybe device recovers later? */ + SDL_Delay(delay); /* wait for as long as this buffer would have played. Maybe device recovers later? */ } else { if (got != device->spec.size) { SDL_memset(data, device->spec.silence, device->spec.size); @@ -758,19 +771,25 @@ SDL_RunAudio(void *devicep) current_audio.impl.WaitDevice(device); } } + + /* it seems resampling was not fast enough, device_buf_keepsafe was not released yet, so play silence here */ + if (device_buf_keepsafe) { + SDL_memset(device_buf_keepsafe, device->spec.silence, device->spec.size); + current_audio.impl.PlayDevice(device); + current_audio.impl.WaitDevice(device); + device_buf_keepsafe = NULL; + } } else if (data == device->work_buffer) { /* nothing to do; pause like we queued a buffer to play. */ const Uint32 delay = ((device->spec.samples * 1000) / device->spec.freq); SDL_Delay(delay); - } else { /* writing directly to the device. */ + } else { /* writing directly to the device. */ /* queue this buffer and wait for it to finish playing. */ current_audio.impl.PlayDevice(device); current_audio.impl.WaitDevice(device); } } - current_audio.impl.PrepareToClose(device); - /* Wait for the audio to drain. */ SDL_Delay(((device->spec.samples * 1000) / device->spec.freq) * 2); @@ -781,11 +800,11 @@ SDL_RunAudio(void *devicep) /* !!! FIXME: this needs to deal with device spec changes. */ /* The general capture thread function */ -static int SDLCALL -SDL_CaptureAudio(void *devicep) +static int SDLCALL SDL_CaptureAudio(void *userdata) { - SDL_AudioDevice *device = (SDL_AudioDevice *) devicep; - const int silence = (int) device->spec.silence; + const AudioThreadStartupData *startup_data = (const AudioThreadStartupData *) userdata; + SDL_AudioDevice *device = startup_data->device; + const int silence = (int)device->spec.silence; const Uint32 delay = ((device->spec.samples * 1000) / device->spec.freq); const int data_len = device->spec.size; Uint8 *data; @@ -794,10 +813,9 @@ SDL_CaptureAudio(void *devicep) SDL_assert(device->iscapture); -#if SDL_AUDIO_DRIVER_ANDROID +#ifdef SDL_AUDIO_DRIVER_ANDROID { /* Set thread priority to THREAD_PRIORITY_AUDIO */ - extern void Android_JNI_AudioSetThreadPriority(int, int); Android_JNI_AudioSetThreadPriority(device->iscapture, device->id); } #else @@ -807,6 +825,9 @@ SDL_CaptureAudio(void *devicep) /* Perform any thread setup */ device->threadid = SDL_ThreadID(); + + SDL_SemPost(startup_data->startup_semaphore); /* SDL_OpenAudioDevice may now continue. */ + current_audio.impl.ThreadInit(device); /* Loop, filling the audio buffers */ @@ -814,14 +835,12 @@ SDL_CaptureAudio(void *devicep) int still_need; Uint8 *ptr; - current_audio.impl.BeginLoopIteration(device); - if (SDL_AtomicGet(&device->paused)) { - SDL_Delay(delay); /* just so we don't cook the CPU. */ + SDL_Delay(delay); /* just so we don't cook the CPU. */ if (device->stream) { SDL_AudioStreamClear(device->stream); } - current_audio.impl.FlushCapture(device); /* dump anything pending. */ + current_audio.impl.FlushCapture(device); /* dump anything pending. */ continue; } @@ -839,15 +858,15 @@ SDL_CaptureAudio(void *devicep) But we don't process it further or call the app's callback. */ if (!SDL_AtomicGet(&device->enabled)) { - SDL_Delay(delay); /* try to keep callback firing at normal pace. */ + SDL_Delay(delay); /* try to keep callback firing at normal pace. */ } else { while (still_need > 0) { const int rc = current_audio.impl.CaptureFromDevice(device, ptr, still_need); - SDL_assert(rc <= still_need); /* device should not overflow buffer. :) */ + SDL_assert(rc <= still_need); /* device should not overflow buffer. :) */ if (rc > 0) { still_need -= rc; ptr += rc; - } else { /* uhoh, device failed for some reason! */ + } else { /* uhoh, device failed for some reason! */ SDL_OpenedAudioDeviceDisconnected(device); break; } @@ -863,7 +882,7 @@ SDL_CaptureAudio(void *devicep) /* if this fails...oh well. */ SDL_AudioStreamPut(device->stream, data, data_len); - while (SDL_AudioStreamAvailable(device->stream) >= ((int) device->callbackspec.size)) { + while (SDL_AudioStreamAvailable(device->stream) >= ((int)device->callbackspec.size)) { const int got = SDL_AudioStreamGet(device->stream, device->work_buffer, device->callbackspec.size); SDL_assert((got < 0) || (got == device->callbackspec.size)); if (got != device->callbackspec.size) { @@ -877,7 +896,7 @@ SDL_CaptureAudio(void *devicep) } SDL_UnlockMutex(device->mixer_lock); } - } else { /* feeding user callback directly without streaming. */ + } else { /* feeding user callback directly without streaming. */ /* !!! FIXME: this should be LockDevice. */ SDL_LockMutex(device->mixer_lock); if (!SDL_AtomicGet(&device->paused)) { @@ -894,11 +913,11 @@ SDL_CaptureAudio(void *devicep) return 0; } - -static SDL_AudioFormat -SDL_ParseAudioFormat(const char *string) +static SDL_AudioFormat SDL_ParseAudioFormat(const char *string) { -#define CHECK_FMT_STRING(x) if (SDL_strcmp(string, #x) == 0) return AUDIO_##x +#define CHECK_FMT_STRING(x) \ + if (SDL_strcmp(string, #x) == 0) \ + return AUDIO_##x CHECK_FMT_STRING(U8); CHECK_FMT_STRING(S8); CHECK_FMT_STRING(U16LSB); @@ -921,14 +940,12 @@ SDL_ParseAudioFormat(const char *string) return 0; } -int -SDL_GetNumAudioDrivers(void) +int SDL_GetNumAudioDrivers(void) { return SDL_arraysize(bootstrap) - 1; } -const char * -SDL_GetAudioDriver(int index) +const char *SDL_GetAudioDriver(int index) { if (index >= 0 && index < SDL_GetNumAudioDrivers()) { return bootstrap[index]->name; @@ -936,38 +953,72 @@ SDL_GetAudioDriver(int index) return NULL; } -int -SDL_AudioInit(const char *driver_name) +int SDL_AudioInit(const char *driver_name) { - int i = 0; - int initialized = 0; - int tried_to_init = 0; + int i; + SDL_bool initialized = SDL_FALSE, tried_to_init = SDL_FALSE; - if (SDL_WasInit(SDL_INIT_AUDIO)) { - SDL_AudioQuit(); /* shutdown driver if already running. */ + if (SDL_GetCurrentAudioDriver()) { + SDL_AudioQuit(); /* shutdown driver if already running. */ } - SDL_zero(current_audio); SDL_zeroa(open_devices); /* Select the proper audio driver */ if (driver_name == NULL) { - driver_name = SDL_getenv("SDL_AUDIODRIVER"); + driver_name = SDL_GetHint(SDL_HINT_AUDIODRIVER); } - for (i = 0; (!initialized) && (bootstrap[i]); ++i) { - /* make sure we should even try this driver before doing so... */ - const AudioBootStrap *backend = bootstrap[i]; - if ((driver_name && (SDL_strncasecmp(backend->name, driver_name, SDL_strlen(driver_name)) != 0)) || - (!driver_name && backend->demand_only)) { - continue; - } + if (driver_name != NULL && *driver_name != 0) { + const char *driver_attempt = driver_name; + while (driver_attempt != NULL && *driver_attempt != 0 && !initialized) { + const char *driver_attempt_end = SDL_strchr(driver_attempt, ','); + size_t driver_attempt_len = (driver_attempt_end != NULL) ? (driver_attempt_end - driver_attempt) + : SDL_strlen(driver_attempt); +#ifdef SDL_AUDIO_DRIVER_DSOUND + /* SDL 1.2 uses the name "dsound", so we'll support both. */ + if (driver_attempt_len == SDL_strlen("dsound") && + (SDL_strncasecmp(driver_attempt, "dsound", driver_attempt_len) == 0)) { + driver_attempt = "directsound"; + driver_attempt_len = SDL_strlen("directsound"); + } +#endif - tried_to_init = 1; - SDL_zero(current_audio); - current_audio.name = backend->name; - current_audio.desc = backend->desc; - initialized = backend->init(¤t_audio.impl); +#ifdef SDL_AUDIO_DRIVER_PULSEAUDIO + /* SDL 1.2 uses the name "pulse", so we'll support both. */ + if (driver_attempt_len == SDL_strlen("pulse") && + (SDL_strncasecmp(driver_attempt, "pulse", driver_attempt_len) == 0)) { + driver_attempt = "pulseaudio"; + driver_attempt_len = SDL_strlen("pulseaudio"); + } +#endif + + for (i = 0; bootstrap[i]; ++i) { + if ((driver_attempt_len == SDL_strlen(bootstrap[i]->name)) && + (SDL_strncasecmp(bootstrap[i]->name, driver_attempt, driver_attempt_len) == 0)) { + tried_to_init = SDL_TRUE; + SDL_zero(current_audio); + current_audio.name = bootstrap[i]->name; + current_audio.desc = bootstrap[i]->desc; + initialized = bootstrap[i]->init(¤t_audio.impl); + break; + } + } + + driver_attempt = (driver_attempt_end) ? (driver_attempt_end + 1) : NULL; + } + } else { + for (i = 0; (!initialized) && (bootstrap[i]); ++i) { + if (bootstrap[i]->demand_only) { + continue; + } + + tried_to_init = SDL_TRUE; + SDL_zero(current_audio); + current_audio.name = bootstrap[i]->name; + current_audio.desc = bootstrap[i]->desc; + initialized = bootstrap[i]->init(¤t_audio.impl); + } } if (!initialized) { @@ -981,7 +1032,7 @@ SDL_AudioInit(const char *driver_name) } SDL_zero(current_audio); - return -1; /* No driver was available, so fail. */ + return -1; /* No driver was available, so fail. */ } current_audio.detectionLock = SDL_CreateMutex(); @@ -1001,15 +1052,13 @@ SDL_AudioInit(const char *driver_name) /* * Get the current audio driver name */ -const char * -SDL_GetCurrentAudioDriver() +const char *SDL_GetCurrentAudioDriver(void) { return current_audio.name; } /* Clean out devices that we've removed but had to keep around for stability. */ -static void -clean_out_device_list(SDL_AudioDeviceItem **devices, int *devCount, SDL_bool *removedFlag) +static void clean_out_device_list(SDL_AudioDeviceItem **devices, int *devCount, SDL_bool *removedFlag) { SDL_AudioDeviceItem *item = *devices; SDL_AudioDeviceItem *prev = NULL; @@ -1040,13 +1089,11 @@ clean_out_device_list(SDL_AudioDeviceItem **devices, int *devCount, SDL_bool *re *removedFlag = SDL_FALSE; } - -int -SDL_GetNumAudioDevices(int iscapture) +int SDL_GetNumAudioDevices(int iscapture) { int retval = 0; - if (!SDL_WasInit(SDL_INIT_AUDIO)) { + if (!SDL_GetCurrentAudioDriver()) { return -1; } @@ -1065,49 +1112,83 @@ SDL_GetNumAudioDevices(int iscapture) return retval; } - -const char * -SDL_GetAudioDeviceName(int index, int iscapture) +const char *SDL_GetAudioDeviceName(int index, int iscapture) { - const char *retval = NULL; + SDL_AudioDeviceItem *item; + int i; + const char *retval; - if (!SDL_WasInit(SDL_INIT_AUDIO)) { + if (!SDL_GetCurrentAudioDriver()) { SDL_SetError("Audio subsystem is not initialized"); return NULL; } - if (iscapture && !current_audio.impl.HasCaptureSupport) { - SDL_SetError("No capture support"); - return NULL; - } - - if (index >= 0) { - SDL_AudioDeviceItem *item; - int i; - - SDL_LockMutex(current_audio.detectionLock); - item = iscapture ? current_audio.inputDevices : current_audio.outputDevices; - i = iscapture ? current_audio.inputDeviceCount : current_audio.outputDeviceCount; - if (index < i) { - for (i--; i > index; i--, item = item->next) { - SDL_assert(item != NULL); - } + SDL_LockMutex(current_audio.detectionLock); + item = iscapture ? current_audio.inputDevices : current_audio.outputDevices; + i = iscapture ? current_audio.inputDeviceCount : current_audio.outputDeviceCount; + if (index >= 0 && index < i) { + for (i--; i > index; i--, item = item->next) { SDL_assert(item != NULL); - retval = item->name; } - SDL_UnlockMutex(current_audio.detectionLock); - } - - if (retval == NULL) { - SDL_SetError("No such device"); + SDL_assert(item != NULL); + retval = item->name; + } else { + SDL_InvalidParamError("index"); + retval = NULL; } + SDL_UnlockMutex(current_audio.detectionLock); return retval; } +int SDL_GetAudioDeviceSpec(int index, int iscapture, SDL_AudioSpec *spec) +{ + SDL_AudioDeviceItem *item; + int i, retval; -static void -close_audio_device(SDL_AudioDevice * device) + if (spec == NULL) { + return SDL_InvalidParamError("spec"); + } + + if (!SDL_GetCurrentAudioDriver()) { + return SDL_SetError("Audio subsystem is not initialized"); + } + + SDL_LockMutex(current_audio.detectionLock); + item = iscapture ? current_audio.inputDevices : current_audio.outputDevices; + i = iscapture ? current_audio.inputDeviceCount : current_audio.outputDeviceCount; + if (index >= 0 && index < i) { + for (i--; i > index; i--, item = item->next) { + SDL_assert(item != NULL); + } + SDL_assert(item != NULL); + SDL_copyp(spec, &item->spec); + retval = 0; + } else { + retval = SDL_InvalidParamError("index"); + } + SDL_UnlockMutex(current_audio.detectionLock); + + return retval; +} + +int SDL_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture) +{ + if (spec == NULL) { + return SDL_InvalidParamError("spec"); + } + + if (!SDL_GetCurrentAudioDriver()) { + return SDL_SetError("Audio subsystem is not initialized"); + } + + if (current_audio.impl.GetDefaultAudioInfo == NULL) { + return SDL_Unsupported(); + } + return current_audio.impl.GetDefaultAudioInfo(name, spec, iscapture); +} + +static void close_audio_device(SDL_AudioDevice *device) { if (!device) { return; @@ -1148,61 +1229,68 @@ close_audio_device(SDL_AudioDevice * device) SDL_free(device); } +static Uint16 GetDefaultSamplesFromFreq(int freq) +{ + /* Pick a default of ~46 ms at desired frequency */ + /* !!! FIXME: remove this when the non-Po2 resampling is in. */ + const Uint16 max_sample = (freq / 1000) * 46; + Uint16 current_sample = 1; + while (current_sample < max_sample) { + current_sample *= 2; + } + return current_sample; +} /* * Sanity check desired AudioSpec for SDL_OpenAudio() in (orig). * Fills in a sanitized copy in (prepared). * Returns non-zero if okay, zero on fatal parameters in (orig). */ -static int -prepare_audiospec(const SDL_AudioSpec * orig, SDL_AudioSpec * prepared) +static int prepare_audiospec(const SDL_AudioSpec *orig, SDL_AudioSpec *prepared) { - SDL_memcpy(prepared, orig, sizeof(SDL_AudioSpec)); + SDL_copyp(prepared, orig); if (orig->freq == 0) { + static const int DEFAULT_FREQ = 22050; const char *env = SDL_getenv("SDL_AUDIO_FREQUENCY"); - if ((!env) || ((prepared->freq = SDL_atoi(env)) == 0)) { - prepared->freq = 22050; /* a reasonable default */ + if (env != NULL) { + int freq = SDL_atoi(env); + prepared->freq = freq != 0 ? freq : DEFAULT_FREQ; + } else { + prepared->freq = DEFAULT_FREQ; } } if (orig->format == 0) { const char *env = SDL_getenv("SDL_AUDIO_FORMAT"); - if ((!env) || ((prepared->format = SDL_ParseAudioFormat(env)) == 0)) { - prepared->format = AUDIO_S16; /* a reasonable default */ + if (env != NULL) { + const SDL_AudioFormat format = SDL_ParseAudioFormat(env); + prepared->format = format != 0 ? format : AUDIO_S16; + } else { + prepared->format = AUDIO_S16; } } - switch (orig->channels) { - case 0:{ - const char *env = SDL_getenv("SDL_AUDIO_CHANNELS"); - if ((!env) || ((prepared->channels = (Uint8) SDL_atoi(env)) == 0)) { - prepared->channels = 2; /* a reasonable default */ - } - break; + if (orig->channels == 0) { + const char *env = SDL_getenv("SDL_AUDIO_CHANNELS"); + if (env != NULL) { + Uint8 channels = (Uint8)SDL_atoi(env); + prepared->channels = channels != 0 ? channels : 2; + } else { + prepared->channels = 2; } - case 1: /* Mono */ - case 2: /* Stereo */ - case 4: /* Quadrophonic */ - case 6: /* 5.1 surround */ - case 8: /* 7.1 surround */ - break; - default: + } else if (orig->channels > 8) { SDL_SetError("Unsupported number of audio channels."); return 0; } if (orig->samples == 0) { const char *env = SDL_getenv("SDL_AUDIO_SAMPLES"); - if ((!env) || ((prepared->samples = (Uint16) SDL_atoi(env)) == 0)) { - /* Pick a default of ~46 ms at desired frequency */ - /* !!! FIXME: remove this when the non-Po2 resampling is in. */ - const int samples = (prepared->freq / 1000) * 46; - int power2 = 1; - while (power2 < samples) { - power2 *= 2; - } - prepared->samples = power2; + if (env != NULL) { + Uint16 samples = (Uint16)SDL_atoi(env); + prepared->samples = samples != 0 ? samples : GetDefaultSamplesFromFreq(prepared->freq); + } else { + prepared->samples = GetDefaultSamplesFromFreq(prepared->freq); } } @@ -1212,12 +1300,10 @@ prepare_audiospec(const SDL_AudioSpec * orig, SDL_AudioSpec * prepared) return 1; } -static SDL_AudioDeviceID -open_audio_device(const char *devname, int iscapture, - const SDL_AudioSpec * desired, SDL_AudioSpec * obtained, - int allowed_changes, int min_id) +static SDL_AudioDeviceID open_audio_device(const char *devname, int iscapture, + const SDL_AudioSpec *desired, SDL_AudioSpec *obtained, + int allowed_changes, int min_id) { - const SDL_bool is_internal_thread = (desired->callback == NULL); SDL_AudioDeviceID id = 0; SDL_AudioSpec _obtained; SDL_AudioDevice *device; @@ -1225,7 +1311,7 @@ open_audio_device(const char *devname, int iscapture, void *handle = NULL; int i = 0; - if (!SDL_WasInit(SDL_INIT_AUDIO)) { + if (!SDL_GetCurrentAudioDriver()) { SDL_SetError("Audio subsystem is not initialized"); return 0; } @@ -1235,19 +1321,6 @@ open_audio_device(const char *devname, int iscapture, return 0; } - /* !!! FIXME: there is a race condition here if two devices open from two threads at once. */ - /* Find an available device ID... */ - for (id = min_id - 1; id < SDL_arraysize(open_devices); id++) { - if (open_devices[id] == NULL) { - break; - } - } - - if (id == SDL_arraysize(open_devices)) { - SDL_SetError("Too many open audio devices"); - return 0; - } - if (!obtained) { obtained = &_obtained; } @@ -1277,12 +1350,15 @@ open_audio_device(const char *devname, int iscapture, } devname = NULL; + SDL_LockMutex(current_audio.detectionLock); for (i = 0; i < SDL_arraysize(open_devices); i++) { if ((open_devices[i]) && (open_devices[i]->iscapture)) { SDL_SetError("Audio device already open"); + SDL_UnlockMutex(current_audio.detectionLock); return 0; } } + SDL_UnlockMutex(current_audio.detectionLock); } else if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) { if ((devname) && (SDL_strcmp(devname, DEFAULT_OUTPUT_DEVNAME) != 0)) { SDL_SetError("No such device"); @@ -1290,12 +1366,15 @@ open_audio_device(const char *devname, int iscapture, } devname = NULL; + SDL_LockMutex(current_audio.detectionLock); for (i = 0; i < SDL_arraysize(open_devices); i++) { if ((open_devices[i]) && (!open_devices[i]->iscapture)) { + SDL_UnlockMutex(current_audio.detectionLock); SDL_SetError("Audio device already open"); return 0; } } + SDL_UnlockMutex(current_audio.detectionLock); } else if (devname != NULL) { /* if the app specifies an exact string, we can pass the backend an actual device handle thingey, which saves them the effort of @@ -1322,22 +1401,21 @@ open_audio_device(const char *devname, int iscapture, } } - device = (SDL_AudioDevice *) SDL_calloc(1, sizeof (SDL_AudioDevice)); + device = (SDL_AudioDevice *)SDL_calloc(1, sizeof(SDL_AudioDevice)); if (device == NULL) { SDL_OutOfMemory(); return 0; } - device->id = id + 1; device->spec = *obtained; device->iscapture = iscapture ? SDL_TRUE : SDL_FALSE; device->handle = handle; - SDL_AtomicSet(&device->shutdown, 0); /* just in case. */ + SDL_AtomicSet(&device->shutdown, 0); /* just in case. */ SDL_AtomicSet(&device->paused, 1); SDL_AtomicSet(&device->enabled, 1); /* Create a mutex for locking the sound buffers */ - if (!current_audio.impl.SkipMixerLock) { + if (current_audio.impl.LockDevice == SDL_AudioLockDevice_Default) { device->mixer_lock = SDL_CreateMutex(); if (device->mixer_lock == NULL) { close_audio_device(device); @@ -1346,7 +1424,14 @@ open_audio_device(const char *devname, int iscapture, } } - if (current_audio.impl.OpenDevice(device, handle, devname, iscapture) < 0) { + /* For backends that require a power-of-two value for spec.samples, take the + * value we got from 'desired' and round up to the nearest value + */ + if (!current_audio.impl.SupportsNonPow2Samples && device->spec.samples > 0) { + device->spec.samples = SDL_powerof2(device->spec.samples); + } + + if (current_audio.impl.OpenDevice(device, devname) < 0) { close_audio_device(device); return 0; } @@ -1386,19 +1471,19 @@ open_audio_device(const char *devname, int iscapture, } } - SDL_CalculateAudioSpec(obtained); /* recalc after possible changes. */ + SDL_CalculateAudioSpec(obtained); /* recalc after possible changes. */ device->callbackspec = *obtained; if (build_stream) { if (iscapture) { device->stream = SDL_NewAudioStream(device->spec.format, - device->spec.channels, device->spec.freq, - obtained->format, obtained->channels, obtained->freq); + device->spec.channels, device->spec.freq, + obtained->format, obtained->channels, obtained->freq); } else { device->stream = SDL_NewAudioStream(obtained->format, obtained->channels, - obtained->freq, device->spec.format, - device->spec.channels, device->spec.freq); + obtained->freq, device->spec.format, + device->spec.channels, device->spec.freq); } if (!device->stream) { @@ -1407,7 +1492,7 @@ open_audio_device(const char *devname, int iscapture, } } - if (device->spec.callback == NULL) { /* use buffer queueing? */ + if (device->spec.callback == NULL) { /* use buffer queueing? */ /* pool a few packets to start. Enough for two callbacks. */ device->buffer_queue = SDL_NewDataQueue(SDL_AUDIOBUFFERQUEUE_PACKETLEN, obtained->size * 2); if (!device->buffer_queue) { @@ -1426,39 +1511,64 @@ open_audio_device(const char *devname, int iscapture, } SDL_assert(device->work_buffer_len > 0); - device->work_buffer = (Uint8 *) SDL_malloc(device->work_buffer_len); + device->work_buffer = (Uint8 *)SDL_malloc(device->work_buffer_len); if (device->work_buffer == NULL) { close_audio_device(device); SDL_OutOfMemory(); return 0; } - open_devices[id] = device; /* add it to our list of open devices. */ + /* Find an available device ID... */ + SDL_LockMutex(current_audio.detectionLock); + for (id = min_id - 1; id < SDL_arraysize(open_devices); id++) { + if (open_devices[id] == NULL) { + break; + } + } + + if (id == SDL_arraysize(open_devices)) { + close_audio_device(device); + SDL_SetError("Too many open audio devices"); + SDL_UnlockMutex(current_audio.detectionLock); + return 0; + } + + device->id = id + 1; + open_devices[id] = device; /* add it to our list of open devices. */ + SDL_UnlockMutex(current_audio.detectionLock); /* Start the audio thread if necessary */ if (!current_audio.impl.ProvidesOwnCallbackThread) { /* Start the audio thread */ - /* !!! FIXME: we don't force the audio thread stack size here if it calls into user code, but maybe we should? */ - /* buffer queueing callback only needs a few bytes, so make the stack tiny. */ - const size_t stacksize = is_internal_thread ? 64 * 1024 : 0; char threadname[64]; + AudioThreadStartupData startup_data; - SDL_snprintf(threadname, sizeof (threadname), "SDLAudio%c%d", (iscapture) ? 'C' : 'P', (int) device->id); - device->thread = SDL_CreateThreadInternal(iscapture ? SDL_CaptureAudio : SDL_RunAudio, threadname, stacksize, device); + startup_data.device = device; + startup_data.startup_semaphore = SDL_CreateSemaphore(0); + if (!startup_data.startup_semaphore) { + close_audio_device(device); + SDL_SetError("Couldn't create audio thread startup semaphore"); + return 0; + } + (void)SDL_snprintf(threadname, sizeof(threadname), "SDLAudio%c%" SDL_PRIu32, (iscapture) ? 'C' : 'P', device->id); + + device->thread = SDL_CreateThreadInternal(iscapture ? SDL_CaptureAudio : SDL_RunAudio, threadname, 0, &startup_data); if (device->thread == NULL) { + SDL_DestroySemaphore(startup_data.startup_semaphore); close_audio_device(device); SDL_SetError("Couldn't create audio thread"); return 0; } + + SDL_SemWait(startup_data.startup_semaphore); + SDL_DestroySemaphore(startup_data.startup_semaphore); } return device->id; } - -int -SDL_OpenAudio(SDL_AudioSpec * desired, SDL_AudioSpec * obtained) +int SDL_OpenAudio(SDL_AudioSpec *desired, SDL_AudioSpec *obtained) { SDL_AudioDeviceID id = 0; @@ -1471,8 +1581,7 @@ SDL_OpenAudio(SDL_AudioSpec * desired, SDL_AudioSpec * obtained) /* SDL_OpenAudio() is legacy and can only act on Device ID #1. */ if (open_devices[0] != NULL) { - SDL_SetError("Audio device is already opened"); - return -1; + return SDL_SetError("Audio device is already opened"); } if (obtained) { @@ -1493,17 +1602,15 @@ SDL_OpenAudio(SDL_AudioSpec * desired, SDL_AudioSpec * obtained) return (id == 0) ? -1 : 0; } -SDL_AudioDeviceID -SDL_OpenAudioDevice(const char *device, int iscapture, - const SDL_AudioSpec * desired, SDL_AudioSpec * obtained, +SDL_AudioDeviceID SDL_OpenAudioDevice(const char *device, int iscapture, + const SDL_AudioSpec *desired, SDL_AudioSpec *obtained, int allowed_changes) { return open_audio_device(device, iscapture, desired, obtained, allowed_changes, 2); } -SDL_AudioStatus -SDL_GetAudioDeviceStatus(SDL_AudioDeviceID devid) +SDL_AudioStatus SDL_GetAudioDeviceStatus(SDL_AudioDeviceID devid) { SDL_AudioDevice *device = get_audio_device(devid); SDL_AudioStatus status = SDL_AUDIO_STOPPED; @@ -1517,15 +1624,12 @@ SDL_GetAudioDeviceStatus(SDL_AudioDeviceID devid) return status; } - -SDL_AudioStatus -SDL_GetAudioStatus(void) +SDL_AudioStatus SDL_GetAudioStatus(void) { return SDL_GetAudioDeviceStatus(1); } -void -SDL_PauseAudioDevice(SDL_AudioDeviceID devid, int pause_on) +void SDL_PauseAudioDevice(SDL_AudioDeviceID devid, int pause_on) { SDL_AudioDevice *device = get_audio_device(devid); if (device) { @@ -1535,15 +1639,12 @@ SDL_PauseAudioDevice(SDL_AudioDeviceID devid, int pause_on) } } -void -SDL_PauseAudio(int pause_on) +void SDL_PauseAudio(int pause_on) { SDL_PauseAudioDevice(1, pause_on); } - -void -SDL_LockAudioDevice(SDL_AudioDeviceID devid) +void SDL_LockAudioDevice(SDL_AudioDeviceID devid) { /* Obtain a lock on the mixing buffers */ SDL_AudioDevice *device = get_audio_device(devid); @@ -1552,14 +1653,12 @@ SDL_LockAudioDevice(SDL_AudioDeviceID devid) } } -void -SDL_LockAudio(void) +void SDL_LockAudio(void) { SDL_LockAudioDevice(1); } -void -SDL_UnlockAudioDevice(SDL_AudioDeviceID devid) +void SDL_UnlockAudioDevice(SDL_AudioDeviceID devid) { /* Obtain a lock on the mixing buffers */ SDL_AudioDevice *device = get_audio_device(devid); @@ -1568,30 +1667,26 @@ SDL_UnlockAudioDevice(SDL_AudioDeviceID devid) } } -void -SDL_UnlockAudio(void) +void SDL_UnlockAudio(void) { SDL_UnlockAudioDevice(1); } -void -SDL_CloseAudioDevice(SDL_AudioDeviceID devid) +void SDL_CloseAudioDevice(SDL_AudioDeviceID devid) { close_audio_device(get_audio_device(devid)); } -void -SDL_CloseAudio(void) +void SDL_CloseAudio(void) { SDL_CloseAudioDevice(1); } -void -SDL_AudioQuit(void) +void SDL_AudioQuit(void) { SDL_AudioDeviceID i; - if (!current_audio.name) { /* not initialized?! */ + if (!current_audio.name) { /* not initialized?! */ return; } @@ -1613,38 +1708,35 @@ SDL_AudioQuit(void) #ifdef HAVE_LIBSAMPLERATE_H UnloadLibSampleRate(); #endif - - SDL_FreeResampleFilter(); } #define NUM_FORMATS 10 static int format_idx; static int format_idx_sub; static SDL_AudioFormat format_list[NUM_FORMATS][NUM_FORMATS] = { - {AUDIO_U8, AUDIO_S8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB, - AUDIO_U16MSB, AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB}, - {AUDIO_S8, AUDIO_U8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB, - AUDIO_U16MSB, AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB}, - {AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_S32LSB, - AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_U8, AUDIO_S8}, - {AUDIO_S16MSB, AUDIO_S16LSB, AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_S32MSB, - AUDIO_S32LSB, AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_U8, AUDIO_S8}, - {AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_S32LSB, - AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_U8, AUDIO_S8}, - {AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_S16MSB, AUDIO_S16LSB, AUDIO_S32MSB, - AUDIO_S32LSB, AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_U8, AUDIO_S8}, - {AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_S16LSB, - AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_U8, AUDIO_S8}, - {AUDIO_S32MSB, AUDIO_S32LSB, AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_S16MSB, - AUDIO_S16LSB, AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_U8, AUDIO_S8}, - {AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_S16LSB, - AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_U8, AUDIO_S8}, - {AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_S32MSB, AUDIO_S32LSB, AUDIO_S16MSB, - AUDIO_S16LSB, AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_U8, AUDIO_S8}, + { AUDIO_U8, AUDIO_S8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB, + AUDIO_U16MSB, AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB }, + { AUDIO_S8, AUDIO_U8, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB, + AUDIO_U16MSB, AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB }, + { AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_S32LSB, + AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_U8, AUDIO_S8 }, + { AUDIO_S16MSB, AUDIO_S16LSB, AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_S32MSB, + AUDIO_S32LSB, AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_U8, AUDIO_S8 }, + { AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_S16LSB, AUDIO_S16MSB, AUDIO_S32LSB, + AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_U8, AUDIO_S8 }, + { AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_S16MSB, AUDIO_S16LSB, AUDIO_S32MSB, + AUDIO_S32LSB, AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_U8, AUDIO_S8 }, + { AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_S16LSB, + AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_U8, AUDIO_S8 }, + { AUDIO_S32MSB, AUDIO_S32LSB, AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_S16MSB, + AUDIO_S16LSB, AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_U8, AUDIO_S8 }, + { AUDIO_F32LSB, AUDIO_F32MSB, AUDIO_S32LSB, AUDIO_S32MSB, AUDIO_S16LSB, + AUDIO_S16MSB, AUDIO_U16LSB, AUDIO_U16MSB, AUDIO_U8, AUDIO_S8 }, + { AUDIO_F32MSB, AUDIO_F32LSB, AUDIO_S32MSB, AUDIO_S32LSB, AUDIO_S16MSB, + AUDIO_S16LSB, AUDIO_U16MSB, AUDIO_U16LSB, AUDIO_U8, AUDIO_S8 }, }; -SDL_AudioFormat -SDL_FirstAudioFormat(SDL_AudioFormat format) +SDL_AudioFormat SDL_FirstAudioFormat(SDL_AudioFormat format) { for (format_idx = 0; format_idx < NUM_FORMATS; ++format_idx) { if (format_list[format_idx][0] == format) { @@ -1655,8 +1747,7 @@ SDL_FirstAudioFormat(SDL_AudioFormat format) return SDL_NextAudioFormat(); } -SDL_AudioFormat -SDL_NextAudioFormat(void) +SDL_AudioFormat SDL_NextAudioFormat(void) { if ((format_idx == NUM_FORMATS) || (format_idx_sub == NUM_FORMATS)) { return 0; @@ -1664,26 +1755,25 @@ SDL_NextAudioFormat(void) return format_list[format_idx][format_idx_sub++]; } -Uint8 -SDL_SilenceValueForFormat(const SDL_AudioFormat format) +Uint8 SDL_SilenceValueForFormat(const SDL_AudioFormat format) { switch (format) { - /* !!! FIXME: 0x80 isn't perfect for U16, but we can't fit 0x8000 in a - !!! FIXME: byte for memset() use. This is actually 0.1953 percent - !!! FIXME: off from silence. Maybe just don't use U16. */ - case AUDIO_U16LSB: - case AUDIO_U16MSB: - case AUDIO_U8: - return 0x80; + /* !!! FIXME: 0x80 isn't perfect for U16, but we can't fit 0x8000 in a + !!! FIXME: byte for SDL_memset() use. This is actually 0.1953 percent + !!! FIXME: off from silence. Maybe just don't use U16. */ + case AUDIO_U16LSB: + case AUDIO_U16MSB: + case AUDIO_U8: + return 0x80; - default: break; - } + default: + break; + } return 0x00; } -void -SDL_CalculateAudioSpec(SDL_AudioSpec * spec) +void SDL_CalculateAudioSpec(SDL_AudioSpec *spec) { spec->silence = SDL_SilenceValueForFormat(spec->format); spec->size = SDL_AUDIO_BITSIZE(spec->format) / 8; @@ -1691,13 +1781,11 @@ SDL_CalculateAudioSpec(SDL_AudioSpec * spec) spec->size *= spec->samples; } - /* * Moved here from SDL_mixer.c, since it relies on internals of an opened * audio device (and is deprecated, by the way!). */ -void -SDL_MixAudio(Uint8 * dst, const Uint8 * src, Uint32 len, int volume) +void SDL_MixAudio(Uint8 *dst, const Uint8 *src, Uint32 len, int volume) { /* Mix the user-level audio format */ SDL_AudioDevice *device = get_audio_device(1); diff --git a/SDL2-2.0.12/src/audio/SDL_audio_c.h b/SDL2-2.30.5/src/audio/SDL_audio_c.h similarity index 79% rename from SDL2-2.0.12/src/audio/SDL_audio_c.h rename to SDL2-2.30.5/src/audio/SDL_audio_c.h index aa3bf20..5bc2b41 100644 --- a/SDL2-2.0.12/src/audio/SDL_audio_c.h +++ b/SDL2-2.30.5/src/audio/SDL_audio_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -29,7 +29,7 @@ #endif #if DEBUG_CONVERT -#define LOG_DEBUG_CONVERT(from, to) fprintf(stderr, "Converting %s to %s.\n", from, to); +#define LOG_DEBUG_CONVERT(from, to) SDL_Log("SDL_AUDIO_CONVERT: Converting %s to %s.\n", from, to); #else #define LOG_DEBUG_CONVERT(from, to) #endif @@ -40,11 +40,12 @@ #include "samplerate.h" extern SDL_bool SRC_available; extern int SRC_converter; -extern SRC_STATE* (*SRC_src_new)(int converter_type, int channels, int *error); +extern SRC_STATE *(*SRC_src_new)(int converter_type, int channels, int *error); extern int (*SRC_src_process)(SRC_STATE *state, SRC_DATA *data); extern int (*SRC_src_reset)(SRC_STATE *state); -extern SRC_STATE* (*SRC_src_delete)(SRC_STATE *state); -extern const char* (*SRC_src_strerror)(int error); +extern SRC_STATE *(*SRC_src_delete)(SRC_STATE *state); +extern const char *(*SRC_src_strerror)(int error); +extern int (*SRC_src_simple)(SRC_DATA *data, int converter_type, int channels); #endif /* Functions to get a list of "close" audio formats */ @@ -53,7 +54,7 @@ extern SDL_AudioFormat SDL_NextAudioFormat(void); /* Function to calculate the size and silence for a SDL_AudioSpec */ extern Uint8 SDL_SilenceValueForFormat(const SDL_AudioFormat format); -extern void SDL_CalculateAudioSpec(SDL_AudioSpec * spec); +extern void SDL_CalculateAudioSpec(SDL_AudioSpec *spec); /* Choose the audio filter functions below */ extern void SDL_ChooseAudioConverters(void); @@ -70,11 +71,6 @@ extern SDL_AudioFilter SDL_Convert_F32_to_S16; extern SDL_AudioFilter SDL_Convert_F32_to_U16; extern SDL_AudioFilter SDL_Convert_F32_to_S32; -/* You need to call SDL_PrepareResampleFilter() before using the internal resampler. - SDL_AudioQuit() calls SDL_FreeResamplerFilter(), you should never call it yourself. */ -extern int SDL_PrepareResampleFilter(void); -extern void SDL_FreeResampleFilter(void); - #endif /* SDL_audio_c_h_ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/audio/SDL_audio_channel_converters.h b/SDL2-2.30.5/src/audio/SDL_audio_channel_converters.h new file mode 100644 index 0000000..95e22b1 --- /dev/null +++ b/SDL2-2.30.5/src/audio/SDL_audio_channel_converters.h @@ -0,0 +1,1402 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +/* DO NOT EDIT, THIS FILE WAS GENERATED BY build-scripts/gen_audio_channel_conversion.c */ + +static void SDLCALL SDL_ConvertMonoToStereo(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *)(cvt->buf + ((cvt->len_cvt / 1) * 2))) - 2; + const float *src = ((const float *)(cvt->buf + cvt->len_cvt)) - 1; + int i; + + LOG_DEBUG_CONVERT("mono", "stereo"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof(float) * 1); i; i--, src -= 1, dst -= 2) { + const float srcFC = src[0]; + dst[1] /* FR */ = srcFC; + dst[0] /* FL */ = srcFC; + } + + cvt->len_cvt = cvt->len_cvt * 2; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_ConvertMonoTo21(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *)(cvt->buf + ((cvt->len_cvt / 1) * 3))) - 3; + const float *src = ((const float *)(cvt->buf + cvt->len_cvt)) - 1; + int i; + + LOG_DEBUG_CONVERT("mono", "2.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof(float) * 1); i; i--, src -= 1, dst -= 3) { + const float srcFC = src[0]; + dst[2] /* LFE */ = 0.0f; + dst[1] /* FR */ = srcFC; + dst[0] /* FL */ = srcFC; + } + + cvt->len_cvt = cvt->len_cvt * 3; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_ConvertMonoToQuad(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *)(cvt->buf + ((cvt->len_cvt / 1) * 4))) - 4; + const float *src = ((const float *)(cvt->buf + cvt->len_cvt)) - 1; + int i; + + LOG_DEBUG_CONVERT("mono", "quad"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof(float) * 1); i; i--, src -= 1, dst -= 4) { + const float srcFC = src[0]; + dst[3] /* BR */ = 0.0f; + dst[2] /* BL */ = 0.0f; + dst[1] /* FR */ = srcFC; + dst[0] /* FL */ = srcFC; + } + + cvt->len_cvt = cvt->len_cvt * 4; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_ConvertMonoTo41(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *)(cvt->buf + ((cvt->len_cvt / 1) * 5))) - 5; + const float *src = ((const float *)(cvt->buf + cvt->len_cvt)) - 1; + int i; + + LOG_DEBUG_CONVERT("mono", "4.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof(float) * 1); i; i--, src -= 1, dst -= 5) { + const float srcFC = src[0]; + dst[4] /* BR */ = 0.0f; + dst[3] /* BL */ = 0.0f; + dst[2] /* LFE */ = 0.0f; + dst[1] /* FR */ = srcFC; + dst[0] /* FL */ = srcFC; + } + + cvt->len_cvt = cvt->len_cvt * 5; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_ConvertMonoTo51(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *)(cvt->buf + ((cvt->len_cvt / 1) * 6))) - 6; + const float *src = ((const float *)(cvt->buf + cvt->len_cvt)) - 1; + int i; + + LOG_DEBUG_CONVERT("mono", "5.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof(float) * 1); i; i--, src -= 1, dst -= 6) { + const float srcFC = src[0]; + dst[5] /* BR */ = 0.0f; + dst[4] /* BL */ = 0.0f; + dst[3] /* LFE */ = 0.0f; + dst[2] /* FC */ = 0.0f; + dst[1] /* FR */ = srcFC; + dst[0] /* FL */ = srcFC; + } + + cvt->len_cvt = cvt->len_cvt * 6; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_ConvertMonoTo61(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *)(cvt->buf + ((cvt->len_cvt / 1) * 7))) - 7; + const float *src = ((const float *)(cvt->buf + cvt->len_cvt)) - 1; + int i; + + LOG_DEBUG_CONVERT("mono", "6.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof(float) * 1); i; i--, src -= 1, dst -= 7) { + const float srcFC = src[0]; + dst[6] /* SR */ = 0.0f; + dst[5] /* SL */ = 0.0f; + dst[4] /* BC */ = 0.0f; + dst[3] /* LFE */ = 0.0f; + dst[2] /* FC */ = 0.0f; + dst[1] /* FR */ = srcFC; + dst[0] /* FL */ = srcFC; + } + + cvt->len_cvt = cvt->len_cvt * 7; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_ConvertMonoTo71(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *)(cvt->buf + ((cvt->len_cvt / 1) * 8))) - 8; + const float *src = ((const float *)(cvt->buf + cvt->len_cvt)) - 1; + int i; + + LOG_DEBUG_CONVERT("mono", "7.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof(float) * 1); i; i--, src -= 1, dst -= 8) { + const float srcFC = src[0]; + dst[7] /* SR */ = 0.0f; + dst[6] /* SL */ = 0.0f; + dst[5] /* BR */ = 0.0f; + dst[4] /* BL */ = 0.0f; + dst[3] /* LFE */ = 0.0f; + dst[2] /* FC */ = 0.0f; + dst[1] /* FR */ = srcFC; + dst[0] /* FL */ = srcFC; + } + + cvt->len_cvt = cvt->len_cvt * 8; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_ConvertStereoToMono(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *)cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("stereo", "mono"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof(float) * 2); i; i--, src += 2, dst += 1) { + dst[0] /* FC */ = (src[0] * 0.500000000f) + (src[1] * 0.500000000f); + } + + cvt->len_cvt = cvt->len_cvt / 2; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_ConvertStereoTo21(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *)(cvt->buf + ((cvt->len_cvt / 2) * 3))) - 3; + const float *src = ((const float *)(cvt->buf + cvt->len_cvt)) - 2; + int i; + + LOG_DEBUG_CONVERT("stereo", "2.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof(float) * 2); i; i--, src -= 2, dst -= 3) { + dst[2] /* LFE */ = 0.0f; + dst[1] /* FR */ = src[1]; + dst[0] /* FL */ = src[0]; + } + + cvt->len_cvt = (cvt->len_cvt / 2) * 3; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_ConvertStereoToQuad(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *)(cvt->buf + ((cvt->len_cvt / 2) * 4))) - 4; + const float *src = ((const float *)(cvt->buf + cvt->len_cvt)) - 2; + int i; + + LOG_DEBUG_CONVERT("stereo", "quad"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof(float) * 2); i; i--, src -= 2, dst -= 4) { + dst[3] /* BR */ = 0.0f; + dst[2] /* BL */ = 0.0f; + dst[1] /* FR */ = src[1]; + dst[0] /* FL */ = src[0]; + } + + cvt->len_cvt = (cvt->len_cvt / 2) * 4; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_ConvertStereoTo41(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *)(cvt->buf + ((cvt->len_cvt / 2) * 5))) - 5; + const float *src = ((const float *)(cvt->buf + cvt->len_cvt)) - 2; + int i; + + LOG_DEBUG_CONVERT("stereo", "4.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof(float) * 2); i; i--, src -= 2, dst -= 5) { + dst[4] /* BR */ = 0.0f; + dst[3] /* BL */ = 0.0f; + dst[2] /* LFE */ = 0.0f; + dst[1] /* FR */ = src[1]; + dst[0] /* FL */ = src[0]; + } + + cvt->len_cvt = (cvt->len_cvt / 2) * 5; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_ConvertStereoTo51(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *)(cvt->buf + ((cvt->len_cvt / 2) * 6))) - 6; + const float *src = ((const float *)(cvt->buf + cvt->len_cvt)) - 2; + int i; + + LOG_DEBUG_CONVERT("stereo", "5.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof(float) * 2); i; i--, src -= 2, dst -= 6) { + dst[5] /* BR */ = 0.0f; + dst[4] /* BL */ = 0.0f; + dst[3] /* LFE */ = 0.0f; + dst[2] /* FC */ = 0.0f; + dst[1] /* FR */ = src[1]; + dst[0] /* FL */ = src[0]; + } + + cvt->len_cvt = (cvt->len_cvt / 2) * 6; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_ConvertStereoTo61(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *)(cvt->buf + ((cvt->len_cvt / 2) * 7))) - 7; + const float *src = ((const float *)(cvt->buf + cvt->len_cvt)) - 2; + int i; + + LOG_DEBUG_CONVERT("stereo", "6.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof(float) * 2); i; i--, src -= 2, dst -= 7) { + dst[6] /* SR */ = 0.0f; + dst[5] /* SL */ = 0.0f; + dst[4] /* BC */ = 0.0f; + dst[3] /* LFE */ = 0.0f; + dst[2] /* FC */ = 0.0f; + dst[1] /* FR */ = src[1]; + dst[0] /* FL */ = src[0]; + } + + cvt->len_cvt = (cvt->len_cvt / 2) * 7; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_ConvertStereoTo71(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *)(cvt->buf + ((cvt->len_cvt / 2) * 8))) - 8; + const float *src = ((const float *)(cvt->buf + cvt->len_cvt)) - 2; + int i; + + LOG_DEBUG_CONVERT("stereo", "7.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof(float) * 2); i; i--, src -= 2, dst -= 8) { + dst[7] /* SR */ = 0.0f; + dst[6] /* SL */ = 0.0f; + dst[5] /* BR */ = 0.0f; + dst[4] /* BL */ = 0.0f; + dst[3] /* LFE */ = 0.0f; + dst[2] /* FC */ = 0.0f; + dst[1] /* FR */ = src[1]; + dst[0] /* FL */ = src[0]; + } + + cvt->len_cvt = (cvt->len_cvt / 2) * 8; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_Convert21ToMono(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *)cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("2.1", "mono"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof(float) * 3); i; i--, src += 3, dst += 1) { + dst[0] /* FC */ = (src[0] * 0.333333343f) + (src[1] * 0.333333343f) + (src[2] * 0.333333343f); + } + + cvt->len_cvt = cvt->len_cvt / 3; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_Convert21ToStereo(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *)cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("2.1", "stereo"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof(float) * 3); i; i--, src += 3, dst += 2) { + const float srcLFE = src[2]; + dst[0] /* FL */ = (src[0] * 0.800000012f) + (srcLFE * 0.200000003f); + dst[1] /* FR */ = (src[1] * 0.800000012f) + (srcLFE * 0.200000003f); + } + + cvt->len_cvt = (cvt->len_cvt / 3) * 2; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_Convert21ToQuad(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *)(cvt->buf + ((cvt->len_cvt / 3) * 4))) - 4; + const float *src = ((const float *)(cvt->buf + cvt->len_cvt)) - 3; + int i; + + LOG_DEBUG_CONVERT("2.1", "quad"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof(float) * 3); i; i--, src -= 3, dst -= 4) { + const float srcLFE = src[2]; + dst[3] /* BR */ = (srcLFE * 0.111111112f); + dst[2] /* BL */ = (srcLFE * 0.111111112f); + dst[1] /* FR */ = (srcLFE * 0.111111112f) + (src[1] * 0.888888896f); + dst[0] /* FL */ = (srcLFE * 0.111111112f) + (src[0] * 0.888888896f); + } + + cvt->len_cvt = (cvt->len_cvt / 3) * 4; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_Convert21To41(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *)(cvt->buf + ((cvt->len_cvt / 3) * 5))) - 5; + const float *src = ((const float *)(cvt->buf + cvt->len_cvt)) - 3; + int i; + + LOG_DEBUG_CONVERT("2.1", "4.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof(float) * 3); i; i--, src -= 3, dst -= 5) { + dst[4] /* BR */ = 0.0f; + dst[3] /* BL */ = 0.0f; + dst[2] /* LFE */ = src[2]; + dst[1] /* FR */ = src[1]; + dst[0] /* FL */ = src[0]; + } + + cvt->len_cvt = (cvt->len_cvt / 3) * 5; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_Convert21To51(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *)(cvt->buf + ((cvt->len_cvt / 3) * 6))) - 6; + const float *src = ((const float *)(cvt->buf + cvt->len_cvt)) - 3; + int i; + + LOG_DEBUG_CONVERT("2.1", "5.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof(float) * 3); i; i--, src -= 3, dst -= 6) { + dst[5] /* BR */ = 0.0f; + dst[4] /* BL */ = 0.0f; + dst[3] /* LFE */ = src[2]; + dst[2] /* FC */ = 0.0f; + dst[1] /* FR */ = src[1]; + dst[0] /* FL */ = src[0]; + } + + cvt->len_cvt = (cvt->len_cvt / 3) * 6; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_Convert21To61(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *)(cvt->buf + ((cvt->len_cvt / 3) * 7))) - 7; + const float *src = ((const float *)(cvt->buf + cvt->len_cvt)) - 3; + int i; + + LOG_DEBUG_CONVERT("2.1", "6.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof(float) * 3); i; i--, src -= 3, dst -= 7) { + dst[6] /* SR */ = 0.0f; + dst[5] /* SL */ = 0.0f; + dst[4] /* BC */ = 0.0f; + dst[3] /* LFE */ = src[2]; + dst[2] /* FC */ = 0.0f; + dst[1] /* FR */ = src[1]; + dst[0] /* FL */ = src[0]; + } + + cvt->len_cvt = (cvt->len_cvt / 3) * 7; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_Convert21To71(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *)(cvt->buf + ((cvt->len_cvt / 3) * 8))) - 8; + const float *src = ((const float *)(cvt->buf + cvt->len_cvt)) - 3; + int i; + + LOG_DEBUG_CONVERT("2.1", "7.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof(float) * 3); i; i--, src -= 3, dst -= 8) { + dst[7] /* SR */ = 0.0f; + dst[6] /* SL */ = 0.0f; + dst[5] /* BR */ = 0.0f; + dst[4] /* BL */ = 0.0f; + dst[3] /* LFE */ = src[2]; + dst[2] /* FC */ = 0.0f; + dst[1] /* FR */ = src[1]; + dst[0] /* FL */ = src[0]; + } + + cvt->len_cvt = (cvt->len_cvt / 3) * 8; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_ConvertQuadToMono(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *)cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("quad", "mono"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof(float) * 4); i; i--, src += 4, dst += 1) { + dst[0] /* FC */ = (src[0] * 0.250000000f) + (src[1] * 0.250000000f) + (src[2] * 0.250000000f) + (src[3] * 0.250000000f); + } + + cvt->len_cvt = cvt->len_cvt / 4; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_ConvertQuadToStereo(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *)cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("quad", "stereo"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof(float) * 4); i; i--, src += 4, dst += 2) { + const float srcBL = src[2]; + const float srcBR = src[3]; + dst[0] /* FL */ = (src[0] * 0.421000004f) + (srcBL * 0.358999997f) + (srcBR * 0.219999999f); + dst[1] /* FR */ = (src[1] * 0.421000004f) + (srcBL * 0.219999999f) + (srcBR * 0.358999997f); + } + + cvt->len_cvt = (cvt->len_cvt / 4) * 2; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_ConvertQuadTo21(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *)cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("quad", "2.1"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof(float) * 4); i; i--, src += 4, dst += 3) { + const float srcBL = src[2]; + const float srcBR = src[3]; + dst[0] /* FL */ = (src[0] * 0.421000004f) + (srcBL * 0.358999997f) + (srcBR * 0.219999999f); + dst[1] /* FR */ = (src[1] * 0.421000004f) + (srcBL * 0.219999999f) + (srcBR * 0.358999997f); + dst[2] /* LFE */ = 0.0f; + } + + cvt->len_cvt = (cvt->len_cvt / 4) * 3; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_ConvertQuadTo41(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *)(cvt->buf + ((cvt->len_cvt / 4) * 5))) - 5; + const float *src = ((const float *)(cvt->buf + cvt->len_cvt)) - 4; + int i; + + LOG_DEBUG_CONVERT("quad", "4.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof(float) * 4); i; i--, src -= 4, dst -= 5) { + dst[4] /* BR */ = src[3]; + dst[3] /* BL */ = src[2]; + dst[2] /* LFE */ = 0.0f; + dst[1] /* FR */ = src[1]; + dst[0] /* FL */ = src[0]; + } + + cvt->len_cvt = (cvt->len_cvt / 4) * 5; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_ConvertQuadTo51(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *)(cvt->buf + ((cvt->len_cvt / 4) * 6))) - 6; + const float *src = ((const float *)(cvt->buf + cvt->len_cvt)) - 4; + int i; + + LOG_DEBUG_CONVERT("quad", "5.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof(float) * 4); i; i--, src -= 4, dst -= 6) { + dst[5] /* BR */ = src[3]; + dst[4] /* BL */ = src[2]; + dst[3] /* LFE */ = 0.0f; + dst[2] /* FC */ = 0.0f; + dst[1] /* FR */ = src[1]; + dst[0] /* FL */ = src[0]; + } + + cvt->len_cvt = (cvt->len_cvt / 4) * 6; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_ConvertQuadTo61(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *)(cvt->buf + ((cvt->len_cvt / 4) * 7))) - 7; + const float *src = ((const float *)(cvt->buf + cvt->len_cvt)) - 4; + int i; + + LOG_DEBUG_CONVERT("quad", "6.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof(float) * 4); i; i--, src -= 4, dst -= 7) { + const float srcBL = src[2]; + const float srcBR = src[3]; + dst[6] /* SR */ = (srcBR * 0.796000004f); + dst[5] /* SL */ = (srcBL * 0.796000004f); + dst[4] /* BC */ = (srcBR * 0.500000000f) + (srcBL * 0.500000000f); + dst[3] /* LFE */ = 0.0f; + dst[2] /* FC */ = 0.0f; + dst[1] /* FR */ = (src[1] * 0.939999998f); + dst[0] /* FL */ = (src[0] * 0.939999998f); + } + + cvt->len_cvt = (cvt->len_cvt / 4) * 7; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_ConvertQuadTo71(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *)(cvt->buf + ((cvt->len_cvt / 4) * 8))) - 8; + const float *src = ((const float *)(cvt->buf + cvt->len_cvt)) - 4; + int i; + + LOG_DEBUG_CONVERT("quad", "7.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof(float) * 4); i; i--, src -= 4, dst -= 8) { + dst[7] /* SR */ = 0.0f; + dst[6] /* SL */ = 0.0f; + dst[5] /* BR */ = src[3]; + dst[4] /* BL */ = src[2]; + dst[3] /* LFE */ = 0.0f; + dst[2] /* FC */ = 0.0f; + dst[1] /* FR */ = src[1]; + dst[0] /* FL */ = src[0]; + } + + cvt->len_cvt = (cvt->len_cvt / 4) * 8; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_Convert41ToMono(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *)cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("4.1", "mono"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof(float) * 5); i; i--, src += 5, dst += 1) { + dst[0] /* FC */ = (src[0] * 0.200000003f) + (src[1] * 0.200000003f) + (src[2] * 0.200000003f) + (src[3] * 0.200000003f) + (src[4] * 0.200000003f); + } + + cvt->len_cvt = cvt->len_cvt / 5; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_Convert41ToStereo(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *)cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("4.1", "stereo"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof(float) * 5); i; i--, src += 5, dst += 2) { + const float srcLFE = src[2]; + const float srcBL = src[3]; + const float srcBR = src[4]; + dst[0] /* FL */ = (src[0] * 0.374222219f) + (srcLFE * 0.111111112f) + (srcBL * 0.319111109f) + (srcBR * 0.195555553f); + dst[1] /* FR */ = (src[1] * 0.374222219f) + (srcLFE * 0.111111112f) + (srcBL * 0.195555553f) + (srcBR * 0.319111109f); + } + + cvt->len_cvt = (cvt->len_cvt / 5) * 2; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_Convert41To21(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *)cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("4.1", "2.1"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof(float) * 5); i; i--, src += 5, dst += 3) { + const float srcBL = src[3]; + const float srcBR = src[4]; + dst[0] /* FL */ = (src[0] * 0.421000004f) + (srcBL * 0.358999997f) + (srcBR * 0.219999999f); + dst[1] /* FR */ = (src[1] * 0.421000004f) + (srcBL * 0.219999999f) + (srcBR * 0.358999997f); + dst[2] /* LFE */ = src[2]; + } + + cvt->len_cvt = (cvt->len_cvt / 5) * 3; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_Convert41ToQuad(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *)cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("4.1", "quad"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof(float) * 5); i; i--, src += 5, dst += 4) { + const float srcLFE = src[2]; + dst[0] /* FL */ = (src[0] * 0.941176474f) + (srcLFE * 0.058823530f); + dst[1] /* FR */ = (src[1] * 0.941176474f) + (srcLFE * 0.058823530f); + dst[2] /* BL */ = (srcLFE * 0.058823530f) + (src[3] * 0.941176474f); + dst[3] /* BR */ = (srcLFE * 0.058823530f) + (src[4] * 0.941176474f); + } + + cvt->len_cvt = (cvt->len_cvt / 5) * 4; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_Convert41To51(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *)(cvt->buf + ((cvt->len_cvt / 5) * 6))) - 6; + const float *src = ((const float *)(cvt->buf + cvt->len_cvt)) - 5; + int i; + + LOG_DEBUG_CONVERT("4.1", "5.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof(float) * 5); i; i--, src -= 5, dst -= 6) { + dst[5] /* BR */ = src[4]; + dst[4] /* BL */ = src[3]; + dst[3] /* LFE */ = src[2]; + dst[2] /* FC */ = 0.0f; + dst[1] /* FR */ = src[1]; + dst[0] /* FL */ = src[0]; + } + + cvt->len_cvt = (cvt->len_cvt / 5) * 6; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_Convert41To61(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *)(cvt->buf + ((cvt->len_cvt / 5) * 7))) - 7; + const float *src = ((const float *)(cvt->buf + cvt->len_cvt)) - 5; + int i; + + LOG_DEBUG_CONVERT("4.1", "6.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof(float) * 5); i; i--, src -= 5, dst -= 7) { + const float srcBL = src[3]; + const float srcBR = src[4]; + dst[6] /* SR */ = (srcBR * 0.796000004f); + dst[5] /* SL */ = (srcBL * 0.796000004f); + dst[4] /* BC */ = (srcBR * 0.500000000f) + (srcBL * 0.500000000f); + dst[3] /* LFE */ = src[2]; + dst[2] /* FC */ = 0.0f; + dst[1] /* FR */ = (src[1] * 0.939999998f); + dst[0] /* FL */ = (src[0] * 0.939999998f); + } + + cvt->len_cvt = (cvt->len_cvt / 5) * 7; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_Convert41To71(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *)(cvt->buf + ((cvt->len_cvt / 5) * 8))) - 8; + const float *src = ((const float *)(cvt->buf + cvt->len_cvt)) - 5; + int i; + + LOG_DEBUG_CONVERT("4.1", "7.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof(float) * 5); i; i--, src -= 5, dst -= 8) { + dst[7] /* SR */ = 0.0f; + dst[6] /* SL */ = 0.0f; + dst[5] /* BR */ = src[4]; + dst[4] /* BL */ = src[3]; + dst[3] /* LFE */ = src[2]; + dst[2] /* FC */ = 0.0f; + dst[1] /* FR */ = src[1]; + dst[0] /* FL */ = src[0]; + } + + cvt->len_cvt = (cvt->len_cvt / 5) * 8; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_Convert51ToMono(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *)cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("5.1", "mono"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof(float) * 6); i; i--, src += 6, dst += 1) { + dst[0] /* FC */ = (src[0] * 0.166666672f) + (src[1] * 0.166666672f) + (src[2] * 0.166666672f) + (src[3] * 0.166666672f) + (src[4] * 0.166666672f) + (src[5] * 0.166666672f); + } + + cvt->len_cvt = cvt->len_cvt / 6; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_Convert51ToStereo(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *)cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("5.1", "stereo"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof(float) * 6); i; i--, src += 6, dst += 2) { + const float srcFC = src[2]; + const float srcLFE = src[3]; + const float srcBL = src[4]; + const float srcBR = src[5]; + dst[0] /* FL */ = (src[0] * 0.294545442f) + (srcFC * 0.208181813f) + (srcLFE * 0.090909094f) + (srcBL * 0.251818180f) + (srcBR * 0.154545456f); + dst[1] /* FR */ = (src[1] * 0.294545442f) + (srcFC * 0.208181813f) + (srcLFE * 0.090909094f) + (srcBL * 0.154545456f) + (srcBR * 0.251818180f); + } + + cvt->len_cvt = (cvt->len_cvt / 6) * 2; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_Convert51To21(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *)cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("5.1", "2.1"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof(float) * 6); i; i--, src += 6, dst += 3) { + const float srcFC = src[2]; + const float srcBL = src[4]; + const float srcBR = src[5]; + dst[0] /* FL */ = (src[0] * 0.324000001f) + (srcFC * 0.229000002f) + (srcBL * 0.277000010f) + (srcBR * 0.170000002f); + dst[1] /* FR */ = (src[1] * 0.324000001f) + (srcFC * 0.229000002f) + (srcBL * 0.170000002f) + (srcBR * 0.277000010f); + dst[2] /* LFE */ = src[3]; + } + + cvt->len_cvt = (cvt->len_cvt / 6) * 3; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_Convert51ToQuad(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *)cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("5.1", "quad"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof(float) * 6); i; i--, src += 6, dst += 4) { + const float srcFC = src[2]; + const float srcLFE = src[3]; + dst[0] /* FL */ = (src[0] * 0.558095276f) + (srcFC * 0.394285709f) + (srcLFE * 0.047619049f); + dst[1] /* FR */ = (src[1] * 0.558095276f) + (srcFC * 0.394285709f) + (srcLFE * 0.047619049f); + dst[2] /* BL */ = (srcLFE * 0.047619049f) + (src[4] * 0.558095276f); + dst[3] /* BR */ = (srcLFE * 0.047619049f) + (src[5] * 0.558095276f); + } + + cvt->len_cvt = (cvt->len_cvt / 6) * 4; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_Convert51To41(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *)cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("5.1", "4.1"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof(float) * 6); i; i--, src += 6, dst += 5) { + const float srcFC = src[2]; + dst[0] /* FL */ = (src[0] * 0.586000025f) + (srcFC * 0.414000005f); + dst[1] /* FR */ = (src[1] * 0.586000025f) + (srcFC * 0.414000005f); + dst[2] /* LFE */ = src[3]; + dst[3] /* BL */ = (src[4] * 0.586000025f); + dst[4] /* BR */ = (src[5] * 0.586000025f); + } + + cvt->len_cvt = (cvt->len_cvt / 6) * 5; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_Convert51To61(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *)(cvt->buf + ((cvt->len_cvt / 6) * 7))) - 7; + const float *src = ((const float *)(cvt->buf + cvt->len_cvt)) - 6; + int i; + + LOG_DEBUG_CONVERT("5.1", "6.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof(float) * 6); i; i--, src -= 6, dst -= 7) { + const float srcBL = src[4]; + const float srcBR = src[5]; + dst[6] /* SR */ = (srcBR * 0.796000004f); + dst[5] /* SL */ = (srcBL * 0.796000004f); + dst[4] /* BC */ = (srcBR * 0.500000000f) + (srcBL * 0.500000000f); + dst[3] /* LFE */ = src[3]; + dst[2] /* FC */ = (src[2] * 0.939999998f); + dst[1] /* FR */ = (src[1] * 0.939999998f); + dst[0] /* FL */ = (src[0] * 0.939999998f); + } + + cvt->len_cvt = (cvt->len_cvt / 6) * 7; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_Convert51To71(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *)(cvt->buf + ((cvt->len_cvt / 6) * 8))) - 8; + const float *src = ((const float *)(cvt->buf + cvt->len_cvt)) - 6; + int i; + + LOG_DEBUG_CONVERT("5.1", "7.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof(float) * 6); i; i--, src -= 6, dst -= 8) { + dst[7] /* SR */ = 0.0f; + dst[6] /* SL */ = 0.0f; + dst[5] /* BR */ = src[5]; + dst[4] /* BL */ = src[4]; + dst[3] /* LFE */ = src[3]; + dst[2] /* FC */ = src[2]; + dst[1] /* FR */ = src[1]; + dst[0] /* FL */ = src[0]; + } + + cvt->len_cvt = (cvt->len_cvt / 6) * 8; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_Convert61ToMono(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *)cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("6.1", "mono"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof(float) * 7); i; i--, src += 7, dst += 1) { + dst[0] /* FC */ = (src[0] * 0.143142849f) + (src[1] * 0.143142849f) + (src[2] * 0.143142849f) + (src[3] * 0.142857149f) + (src[4] * 0.143142849f) + (src[5] * 0.143142849f) + (src[6] * 0.143142849f); + } + + cvt->len_cvt = cvt->len_cvt / 7; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_Convert61ToStereo(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *)cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("6.1", "stereo"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof(float) * 7); i; i--, src += 7, dst += 2) { + const float srcFC = src[2]; + const float srcLFE = src[3]; + const float srcBC = src[4]; + const float srcSL = src[5]; + const float srcSR = src[6]; + dst[0] /* FL */ = (src[0] * 0.247384623f) + (srcFC * 0.174461529f) + (srcLFE * 0.076923080f) + (srcBC * 0.174461529f) + (srcSL * 0.226153851f) + (srcSR * 0.100615382f); + dst[1] /* FR */ = (src[1] * 0.247384623f) + (srcFC * 0.174461529f) + (srcLFE * 0.076923080f) + (srcBC * 0.174461529f) + (srcSL * 0.100615382f) + (srcSR * 0.226153851f); + } + + cvt->len_cvt = (cvt->len_cvt / 7) * 2; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_Convert61To21(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *)cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("6.1", "2.1"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof(float) * 7); i; i--, src += 7, dst += 3) { + const float srcFC = src[2]; + const float srcBC = src[4]; + const float srcSL = src[5]; + const float srcSR = src[6]; + dst[0] /* FL */ = (src[0] * 0.268000007f) + (srcFC * 0.188999996f) + (srcBC * 0.188999996f) + (srcSL * 0.245000005f) + (srcSR * 0.108999997f); + dst[1] /* FR */ = (src[1] * 0.268000007f) + (srcFC * 0.188999996f) + (srcBC * 0.188999996f) + (srcSL * 0.108999997f) + (srcSR * 0.245000005f); + dst[2] /* LFE */ = src[3]; + } + + cvt->len_cvt = (cvt->len_cvt / 7) * 3; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_Convert61ToQuad(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *)cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("6.1", "quad"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof(float) * 7); i; i--, src += 7, dst += 4) { + const float srcFC = src[2]; + const float srcLFE = src[3]; + const float srcBC = src[4]; + const float srcSL = src[5]; + const float srcSR = src[6]; + dst[0] /* FL */ = (src[0] * 0.463679999f) + (srcFC * 0.327360004f) + (srcLFE * 0.040000003f) + (srcSL * 0.168960005f); + dst[1] /* FR */ = (src[1] * 0.463679999f) + (srcFC * 0.327360004f) + (srcLFE * 0.040000003f) + (srcSR * 0.168960005f); + dst[2] /* BL */ = (srcLFE * 0.040000003f) + (srcBC * 0.327360004f) + (srcSL * 0.431039989f); + dst[3] /* BR */ = (srcLFE * 0.040000003f) + (srcBC * 0.327360004f) + (srcSR * 0.431039989f); + } + + cvt->len_cvt = (cvt->len_cvt / 7) * 4; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_Convert61To41(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *)cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("6.1", "4.1"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof(float) * 7); i; i--, src += 7, dst += 5) { + const float srcFC = src[2]; + const float srcBC = src[4]; + const float srcSL = src[5]; + const float srcSR = src[6]; + dst[0] /* FL */ = (src[0] * 0.483000010f) + (srcFC * 0.340999991f) + (srcSL * 0.175999999f); + dst[1] /* FR */ = (src[1] * 0.483000010f) + (srcFC * 0.340999991f) + (srcSR * 0.175999999f); + dst[2] /* LFE */ = src[3]; + dst[3] /* BL */ = (srcBC * 0.340999991f) + (srcSL * 0.449000001f); + dst[4] /* BR */ = (srcBC * 0.340999991f) + (srcSR * 0.449000001f); + } + + cvt->len_cvt = (cvt->len_cvt / 7) * 5; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_Convert61To51(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *)cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("6.1", "5.1"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof(float) * 7); i; i--, src += 7, dst += 6) { + const float srcBC = src[4]; + const float srcSL = src[5]; + const float srcSR = src[6]; + dst[0] /* FL */ = (src[0] * 0.611000001f) + (srcSL * 0.223000005f); + dst[1] /* FR */ = (src[1] * 0.611000001f) + (srcSR * 0.223000005f); + dst[2] /* FC */ = (src[2] * 0.611000001f); + dst[3] /* LFE */ = src[3]; + dst[4] /* BL */ = (srcBC * 0.432000011f) + (srcSL * 0.568000019f); + dst[5] /* BR */ = (srcBC * 0.432000011f) + (srcSR * 0.568000019f); + } + + cvt->len_cvt = (cvt->len_cvt / 7) * 6; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_Convert61To71(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *)(cvt->buf + ((cvt->len_cvt / 7) * 8))) - 8; + const float *src = ((const float *)(cvt->buf + cvt->len_cvt)) - 7; + int i; + + LOG_DEBUG_CONVERT("6.1", "7.1"); + SDL_assert(format == AUDIO_F32SYS); + + /* convert backwards, since output is growing in-place. */ + for (i = cvt->len_cvt / (sizeof(float) * 7); i; i--, src -= 7, dst -= 8) { + const float srcBC = src[4]; + dst[7] /* SR */ = src[6]; + dst[6] /* SL */ = src[5]; + dst[5] /* BR */ = (srcBC * 0.707000017f); + dst[4] /* BL */ = (srcBC * 0.707000017f); + dst[3] /* LFE */ = src[3]; + dst[2] /* FC */ = src[2]; + dst[1] /* FR */ = src[1]; + dst[0] /* FL */ = src[0]; + } + + cvt->len_cvt = (cvt->len_cvt / 7) * 8; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_Convert71ToMono(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *)cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("7.1", "mono"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof(float) * 8); i; i--, src += 8, dst += 1) { + dst[0] /* FC */ = (src[0] * 0.125125006f) + (src[1] * 0.125125006f) + (src[2] * 0.125125006f) + (src[3] * 0.125000000f) + (src[4] * 0.125125006f) + (src[5] * 0.125125006f) + (src[6] * 0.125125006f) + (src[7] * 0.125125006f); + } + + cvt->len_cvt = cvt->len_cvt / 8; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_Convert71ToStereo(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *)cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("7.1", "stereo"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof(float) * 8); i; i--, src += 8, dst += 2) { + const float srcFC = src[2]; + const float srcLFE = src[3]; + const float srcBL = src[4]; + const float srcBR = src[5]; + const float srcSL = src[6]; + const float srcSR = src[7]; + dst[0] /* FL */ = (src[0] * 0.211866662f) + (srcFC * 0.150266662f) + (srcLFE * 0.066666670f) + (srcBL * 0.181066677f) + (srcBR * 0.111066669f) + (srcSL * 0.194133341f) + (srcSR * 0.085866667f); + dst[1] /* FR */ = (src[1] * 0.211866662f) + (srcFC * 0.150266662f) + (srcLFE * 0.066666670f) + (srcBL * 0.111066669f) + (srcBR * 0.181066677f) + (srcSL * 0.085866667f) + (srcSR * 0.194133341f); + } + + cvt->len_cvt = (cvt->len_cvt / 8) * 2; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_Convert71To21(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *)cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("7.1", "2.1"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof(float) * 8); i; i--, src += 8, dst += 3) { + const float srcFC = src[2]; + const float srcBL = src[4]; + const float srcBR = src[5]; + const float srcSL = src[6]; + const float srcSR = src[7]; + dst[0] /* FL */ = (src[0] * 0.226999998f) + (srcFC * 0.160999998f) + (srcBL * 0.194000006f) + (srcBR * 0.119000003f) + (srcSL * 0.208000004f) + (srcSR * 0.092000000f); + dst[1] /* FR */ = (src[1] * 0.226999998f) + (srcFC * 0.160999998f) + (srcBL * 0.119000003f) + (srcBR * 0.194000006f) + (srcSL * 0.092000000f) + (srcSR * 0.208000004f); + dst[2] /* LFE */ = src[3]; + } + + cvt->len_cvt = (cvt->len_cvt / 8) * 3; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_Convert71ToQuad(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *)cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("7.1", "quad"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof(float) * 8); i; i--, src += 8, dst += 4) { + const float srcFC = src[2]; + const float srcLFE = src[3]; + const float srcSL = src[6]; + const float srcSR = src[7]; + dst[0] /* FL */ = (src[0] * 0.466344833f) + (srcFC * 0.329241365f) + (srcLFE * 0.034482758f) + (srcSL * 0.169931039f); + dst[1] /* FR */ = (src[1] * 0.466344833f) + (srcFC * 0.329241365f) + (srcLFE * 0.034482758f) + (srcSR * 0.169931039f); + dst[2] /* BL */ = (srcLFE * 0.034482758f) + (src[4] * 0.466344833f) + (srcSL * 0.433517247f); + dst[3] /* BR */ = (srcLFE * 0.034482758f) + (src[5] * 0.466344833f) + (srcSR * 0.433517247f); + } + + cvt->len_cvt = (cvt->len_cvt / 8) * 4; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_Convert71To41(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *)cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("7.1", "4.1"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof(float) * 8); i; i--, src += 8, dst += 5) { + const float srcFC = src[2]; + const float srcSL = src[6]; + const float srcSR = src[7]; + dst[0] /* FL */ = (src[0] * 0.483000010f) + (srcFC * 0.340999991f) + (srcSL * 0.175999999f); + dst[1] /* FR */ = (src[1] * 0.483000010f) + (srcFC * 0.340999991f) + (srcSR * 0.175999999f); + dst[2] /* LFE */ = src[3]; + dst[3] /* BL */ = (src[4] * 0.483000010f) + (srcSL * 0.449000001f); + dst[4] /* BR */ = (src[5] * 0.483000010f) + (srcSR * 0.449000001f); + } + + cvt->len_cvt = (cvt->len_cvt / 8) * 5; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_Convert71To51(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *)cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("7.1", "5.1"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof(float) * 8); i; i--, src += 8, dst += 6) { + const float srcSL = src[6]; + const float srcSR = src[7]; + dst[0] /* FL */ = (src[0] * 0.518000007f) + (srcSL * 0.188999996f); + dst[1] /* FR */ = (src[1] * 0.518000007f) + (srcSR * 0.188999996f); + dst[2] /* FC */ = (src[2] * 0.518000007f); + dst[3] /* LFE */ = src[3]; + dst[4] /* BL */ = (src[4] * 0.518000007f) + (srcSL * 0.481999993f); + dst[5] /* BR */ = (src[5] * 0.518000007f) + (srcSR * 0.481999993f); + } + + cvt->len_cvt = (cvt->len_cvt / 8) * 6; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static void SDLCALL SDL_Convert71To61(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = (float *)cvt->buf; + const float *src = dst; + int i; + + LOG_DEBUG_CONVERT("7.1", "6.1"); + SDL_assert(format == AUDIO_F32SYS); + + for (i = cvt->len_cvt / (sizeof(float) * 8); i; i--, src += 8, dst += 7) { + const float srcBL = src[4]; + const float srcBR = src[5]; + dst[0] /* FL */ = (src[0] * 0.541000009f); + dst[1] /* FR */ = (src[1] * 0.541000009f); + dst[2] /* FC */ = (src[2] * 0.541000009f); + dst[3] /* LFE */ = src[3]; + dst[4] /* BC */ = (srcBL * 0.287999988f) + (srcBR * 0.287999988f); + dst[5] /* SL */ = (srcBL * 0.458999991f) + (src[6] * 0.541000009f); + dst[6] /* SR */ = (srcBR * 0.458999991f) + (src[7] * 0.541000009f); + } + + cvt->len_cvt = (cvt->len_cvt / 8) * 7; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static const SDL_AudioFilter channel_converters[8][8] = { /* [from][to] */ + { NULL, SDL_ConvertMonoToStereo, SDL_ConvertMonoTo21, SDL_ConvertMonoToQuad, SDL_ConvertMonoTo41, SDL_ConvertMonoTo51, SDL_ConvertMonoTo61, SDL_ConvertMonoTo71 }, + { SDL_ConvertStereoToMono, NULL, SDL_ConvertStereoTo21, SDL_ConvertStereoToQuad, SDL_ConvertStereoTo41, SDL_ConvertStereoTo51, SDL_ConvertStereoTo61, SDL_ConvertStereoTo71 }, + { SDL_Convert21ToMono, SDL_Convert21ToStereo, NULL, SDL_Convert21ToQuad, SDL_Convert21To41, SDL_Convert21To51, SDL_Convert21To61, SDL_Convert21To71 }, + { SDL_ConvertQuadToMono, SDL_ConvertQuadToStereo, SDL_ConvertQuadTo21, NULL, SDL_ConvertQuadTo41, SDL_ConvertQuadTo51, SDL_ConvertQuadTo61, SDL_ConvertQuadTo71 }, + { SDL_Convert41ToMono, SDL_Convert41ToStereo, SDL_Convert41To21, SDL_Convert41ToQuad, NULL, SDL_Convert41To51, SDL_Convert41To61, SDL_Convert41To71 }, + { SDL_Convert51ToMono, SDL_Convert51ToStereo, SDL_Convert51To21, SDL_Convert51ToQuad, SDL_Convert51To41, NULL, SDL_Convert51To61, SDL_Convert51To71 }, + { SDL_Convert61ToMono, SDL_Convert61ToStereo, SDL_Convert61To21, SDL_Convert61ToQuad, SDL_Convert61To41, SDL_Convert61To51, NULL, SDL_Convert61To71 }, + { SDL_Convert71ToMono, SDL_Convert71ToStereo, SDL_Convert71To21, SDL_Convert71ToQuad, SDL_Convert71To41, SDL_Convert71To51, SDL_Convert71To61, NULL } +}; + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/audio/SDL_audio_resampler_filter.h b/SDL2-2.30.5/src/audio/SDL_audio_resampler_filter.h new file mode 100644 index 0000000..a6dff39 --- /dev/null +++ b/SDL2-2.30.5/src/audio/SDL_audio_resampler_filter.h @@ -0,0 +1,1061 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +/* DO NOT EDIT, THIS FILE WAS GENERATED BY build-scripts/gen_audio_resampler_filter.c */ + +#define RESAMPLER_ZERO_CROSSINGS 5 +#define RESAMPLER_BITS_PER_SAMPLE 16 +#define RESAMPLER_SAMPLES_PER_ZERO_CROSSING (1 << ((RESAMPLER_BITS_PER_SAMPLE / 2) + 1)) +#define RESAMPLER_FILTER_SIZE ((RESAMPLER_SAMPLES_PER_ZERO_CROSSING * RESAMPLER_ZERO_CROSSINGS) + 1) + +static const float ResamplerFilter[RESAMPLER_FILTER_SIZE] = { + 1.000000000f, 0.999993682f, 0.999974370f, 0.999941289f, 0.999894559f, + 0.999834180f, 0.999760151f, 0.999672413f, 0.999571025f, 0.999455988f, + 0.999327302f, 0.999184966f, 0.999028981f, 0.998859286f, 0.998676121f, + 0.998479128f, 0.998268604f, 0.998044431f, 0.997806668f, 0.997555375f, + 0.997290313f, 0.997011721f, 0.996719599f, 0.996413827f, 0.996094406f, + 0.995761573f, 0.995415151f, 0.995055199f, 0.994681656f, 0.994294584f, + 0.993894041f, 0.993480027f, 0.993052363f, 0.992611289f, 0.992156804f, + 0.991688788f, 0.991207361f, 0.990712583f, 0.990204275f, 0.989682615f, + 0.989147604f, 0.988599122f, 0.988037288f, 0.987462223f, 0.986873686f, + 0.986271918f, 0.985656738f, 0.985028386f, 0.984386861f, 0.983731806f, + 0.983063757f, 0.982382476f, 0.981687963f, 0.980980217f, 0.980259418f, + 0.979525447f, 0.978778243f, 0.978018105f, 0.977244914f, 0.976458490f, + 0.975659251f, 0.974846840f, 0.974021494f, 0.973183155f, 0.972331941f, + 0.971467674f, 0.970590651f, 0.969700634f, 0.968797863f, 0.967882276f, + 0.966953754f, 0.966012537f, 0.965058565f, 0.964091897f, 0.963112533f, + 0.962120414f, 0.961115718f, 0.960098326f, 0.959068418f, 0.958025992f, + 0.956970990f, 0.955903471f, 0.954823375f, 0.953730941f, 0.952626109f, + 0.951508820f, 0.950379193f, 0.949237227f, 0.948082924f, 0.946916521f, + 0.945737660f, 0.944546640f, 0.943343520f, 0.942128360f, 0.940900803f, + 0.939661384f, 0.938409984f, 0.937146366f, 0.935870886f, 0.934583426f, + 0.933284163f, 0.931972861f, 0.930649877f, 0.929314911f, 0.927968264f, + 0.926609993f, 0.925239921f, 0.923858225f, 0.922464967f, 0.921060085f, + 0.919643581f, 0.918215632f, 0.916776240f, 0.915325403f, 0.913863063f, + 0.912389517f, 0.910904646f, 0.909408391f, 0.907901049f, 0.906382322f, + 0.904852629f, 0.903311789f, 0.901759744f, 0.900196850f, 0.898622811f, + 0.897037864f, 0.895442069f, 0.893835366f, 0.892217875f, 0.890589595f, + 0.888950586f, 0.887300909f, 0.885640502f, 0.883969545f, 0.882288039f, + 0.880595982f, 0.878893554f, 0.877180517f, 0.875457227f, 0.873723626f, + 0.871979713f, 0.870225549f, 0.868461132f, 0.866686642f, 0.864902079f, + 0.863107383f, 0.861302733f, 0.859488070f, 0.857663572f, 0.855829120f, + 0.853984952f, 0.852130949f, 0.850267172f, 0.848393857f, 0.846510828f, + 0.844618261f, 0.842716157f, 0.840804636f, 0.838883698f, 0.836953342f, + 0.835013688f, 0.833064795f, 0.831106603f, 0.829139292f, 0.827162862f, + 0.825177312f, 0.823182821f, 0.821179330f, 0.819167018f, 0.817145705f, + 0.815115690f, 0.813076973f, 0.811029494f, 0.808973312f, 0.806908667f, + 0.804835379f, 0.802753687f, 0.800663531f, 0.798565030f, 0.796458125f, + 0.794343054f, 0.792219698f, 0.790088236f, 0.787948668f, 0.785801113f, + 0.783645451f, 0.781481922f, 0.779310465f, 0.777131259f, 0.774944246f, + 0.772749543f, 0.770547271f, 0.768337309f, 0.766119778f, 0.763894856f, + 0.761662483f, 0.759422719f, 0.757175624f, 0.754921377f, 0.752659857f, + 0.750391185f, 0.748115480f, 0.745832801f, 0.743543088f, 0.741246462f, + 0.738943100f, 0.736632884f, 0.734315932f, 0.731992364f, 0.729662120f, + 0.727325320f, 0.724982083f, 0.722632408f, 0.720276356f, 0.717914045f, + 0.715545416f, 0.713170588f, 0.710789680f, 0.708402693f, 0.706009746f, + 0.703610778f, 0.701205969f, 0.698795319f, 0.696378946f, 0.693956852f, + 0.691529095f, 0.689095736f, 0.686656833f, 0.684212506f, 0.681762815f, + 0.679307759f, 0.676847458f, 0.674381971f, 0.671911240f, 0.669435501f, + 0.666954637f, 0.664468944f, 0.661978245f, 0.659482718f, 0.656982541f, + 0.654477477f, 0.651967824f, 0.649453580f, 0.646934807f, 0.644411504f, + 0.641883910f, 0.639351964f, 0.636815608f, 0.634275198f, 0.631730616f, + 0.629181862f, 0.626629114f, 0.624072373f, 0.621511757f, 0.618947387f, + 0.616379082f, 0.613807201f, 0.611231565f, 0.608652413f, 0.606069744f, + 0.603483617f, 0.600894034f, 0.598301172f, 0.595705032f, 0.593105674f, + 0.590503156f, 0.587897599f, 0.585289061f, 0.582677484f, 0.580063045f, + 0.577445805f, 0.574825764f, 0.572203040f, 0.569577694f, 0.566949785f, + 0.564319372f, 0.561686456f, 0.559051216f, 0.556413651f, 0.553773820f, + 0.551131785f, 0.548487663f, 0.545841396f, 0.543193221f, 0.540543079f, + 0.537890971f, 0.535237134f, 0.532581568f, 0.529924273f, 0.527265370f, + 0.524604917f, 0.521942914f, 0.519279540f, 0.516614795f, 0.513948679f, + 0.511281490f, 0.508612931f, 0.505943298f, 0.503272593f, 0.500600994f, + 0.497928351f, 0.495254934f, 0.492580622f, 0.489905566f, 0.487229884f, + 0.484553576f, 0.481876701f, 0.479199320f, 0.476521552f, 0.473843396f, + 0.471164882f, 0.468486160f, 0.465807229f, 0.463128209f, 0.460449100f, + 0.457770079f, 0.455091029f, 0.452412128f, 0.449733406f, 0.447054923f, + 0.444376737f, 0.441698909f, 0.439021617f, 0.436344713f, 0.433668375f, + 0.430992693f, 0.428317666f, 0.425643355f, 0.422969848f, 0.420297176f, + 0.417625397f, 0.414954633f, 0.412284881f, 0.409616232f, 0.406948745f, + 0.404282451f, 0.401617438f, 0.398953736f, 0.396291435f, 0.393630594f, + 0.390971363f, 0.388313591f, 0.385657459f, 0.383003026f, 0.380350292f, + 0.377699375f, 0.375050306f, 0.372403204f, 0.369758040f, 0.367114902f, + 0.364473879f, 0.361834973f, 0.359198302f, 0.356563985f, 0.353931844f, + 0.351302117f, 0.348674864f, 0.346050024f, 0.343427807f, 0.340808123f, + 0.338191152f, 0.335576862f, 0.332965344f, 0.330356658f, 0.327750862f, + 0.325147986f, 0.322548091f, 0.319951355f, 0.317357630f, 0.314767033f, + 0.312179655f, 0.309595555f, 0.307014734f, 0.304437339f, 0.301863313f, + 0.299292803f, 0.296725839f, 0.294162393f, 0.291602641f, 0.289046586f, + 0.286494225f, 0.283945769f, 0.281401068f, 0.278860301f, 0.276323408f, + 0.273790598f, 0.271261781f, 0.268737078f, 0.266216546f, 0.263700217f, + 0.261188149f, 0.258680373f, 0.256176978f, 0.253677934f, 0.251183391f, + 0.248693451f, 0.246207923f, 0.243727028f, 0.241250798f, 0.238779247f, + 0.236312449f, 0.233850464f, 0.231393293f, 0.228941023f, 0.226493701f, + 0.224051371f, 0.221614078f, 0.219181836f, 0.216754735f, 0.214332923f, + 0.211916193f, 0.209504753f, 0.207098618f, 0.204697832f, 0.202302471f, + 0.199912533f, 0.197528124f, 0.195149198f, 0.192775860f, 0.190408155f, + 0.188046113f, 0.185689807f, 0.183339253f, 0.180994540f, 0.178655609f, + 0.176322535f, 0.173995405f, 0.171674222f, 0.169359058f, 0.167049929f, + 0.164746925f, 0.162450001f, 0.160159275f, 0.157874763f, 0.155596510f, + 0.153324530f, 0.151058972f, 0.148799688f, 0.146546826f, 0.144300416f, + 0.142060474f, 0.139827073f, 0.137600228f, 0.135380000f, 0.133166388f, + 0.130959451f, 0.128759250f, 0.126565769f, 0.124379098f, 0.122199245f, + 0.120026320f, 0.117860198f, 0.115701027f, 0.113548823f, 0.111403592f, + 0.109265402f, 0.107134290f, 0.105010264f, 0.102893390f, 0.100783676f, + 0.098681159f, 0.096585885f, 0.094497882f, 0.092417173f, 0.090343870f, + 0.088277847f, 0.086219221f, 0.084168032f, 0.082124293f, 0.080088042f, + 0.078059308f, 0.076038122f, 0.074024513f, 0.072018512f, 0.070020139f, + 0.068029441f, 0.066046432f, 0.064071149f, 0.062103685f, 0.060143925f, + 0.058191977f, 0.056247860f, 0.054311592f, 0.052383222f, 0.050462760f, + 0.048550237f, 0.046645675f, 0.044749107f, 0.042860553f, 0.040980037f, + 0.039107583f, 0.037243221f, 0.035387039f, 0.033538923f, 0.031698968f, + 0.029867193f, 0.028043624f, 0.026228283f, 0.024421191f, 0.022622371f, + 0.020831848f, 0.019049639f, 0.017275762f, 0.015510243f, 0.013753103f, + 0.012004361f, 0.010264101f, 0.008532210f, 0.006808777f, 0.005093819f, + 0.003387353f, 0.001689399f, -0.000000024f, -0.001680900f, -0.003353210f, + -0.005016938f, -0.006672067f, -0.008318579f, -0.009956459f, -0.011585629f, + -0.013206195f, -0.014818084f, -0.016421281f, -0.018015765f, -0.019601526f, + -0.021178551f, -0.022746822f, -0.024306327f, -0.025857056f, -0.027398987f, + -0.028932119f, -0.030456433f, -0.031971917f, -0.033478502f, -0.034976289f, + -0.036465216f, -0.037945267f, -0.039416436f, -0.040878706f, -0.042332072f, + -0.043776520f, -0.045212042f, -0.046638630f, -0.048056271f, -0.049464963f, + -0.050864697f, -0.052255459f, -0.053637192f, -0.055009995f, -0.056373812f, + -0.057728622f, -0.059074435f, -0.060411237f, -0.061739020f, -0.063057788f, + -0.064367518f, -0.065668218f, -0.066959888f, -0.068242513f, -0.069516085f, + -0.070780613f, -0.072036028f, -0.073282443f, -0.074519798f, -0.075748093f, + -0.076967306f, -0.078177467f, -0.079378553f, -0.080570564f, -0.081753515f, + -0.082927369f, -0.084092163f, -0.085247882f, -0.086394526f, -0.087532081f, + -0.088660523f, -0.089779936f, -0.090890266f, -0.091991536f, -0.093083732f, + -0.094166860f, -0.095240898f, -0.096305899f, -0.097361818f, -0.098408684f, + -0.099446490f, -0.100475237f, -0.101494931f, -0.102505587f, -0.103507154f, + -0.104499720f, -0.105483264f, -0.106457770f, -0.107423261f, -0.108379729f, + -0.109327182f, -0.110265635f, -0.111195073f, -0.112115517f, -0.113026999f, + -0.113929473f, -0.114823014f, -0.115707509f, -0.116583094f, -0.117449738f, + -0.118307441f, -0.119156219f, -0.119996056f, -0.120826989f, -0.121649019f, + -0.122462146f, -0.123266406f, -0.124061778f, -0.124848284f, -0.125625938f, + -0.126394749f, -0.127154693f, -0.127905846f, -0.128648207f, -0.129381746f, + -0.130106509f, -0.130822510f, -0.131529734f, -0.132228225f, -0.132917970f, + -0.133599013f, -0.134271339f, -0.134934962f, -0.135589913f, -0.136236191f, + -0.136873797f, -0.137502789f, -0.138123170f, -0.138734937f, -0.139338136f, + -0.139932722f, -0.140518770f, -0.141096294f, -0.141665265f, -0.142225727f, + -0.142777696f, -0.143321201f, -0.143856242f, -0.144382849f, -0.144900993f, + -0.145410761f, -0.145912141f, -0.146405146f, -0.146889821f, -0.147366136f, + -0.147834152f, -0.148293883f, -0.148745313f, -0.149188504f, -0.149623469f, + -0.150050193f, -0.150468737f, -0.150879115f, -0.151281342f, -0.151675433f, + -0.152061403f, -0.152439296f, -0.152809098f, -0.153170869f, -0.153524607f, + -0.153870359f, -0.154208109f, -0.154537901f, -0.154859766f, -0.155173704f, + -0.155479759f, -0.155777946f, -0.156068295f, -0.156350806f, -0.156625539f, + -0.156892478f, -0.157151699f, -0.157403171f, -0.157646939f, -0.157883018f, + -0.158111468f, -0.158332288f, -0.158545509f, -0.158751160f, -0.158949256f, + -0.159139827f, -0.159322888f, -0.159498483f, -0.159666643f, -0.159827381f, + -0.159980699f, -0.160126686f, -0.160265297f, -0.160396621f, -0.160520658f, + -0.160637438f, -0.160746962f, -0.160849288f, -0.160944447f, -0.161032468f, + -0.161113337f, -0.161187142f, -0.161253884f, -0.161313564f, -0.161366254f, + -0.161411941f, -0.161450699f, -0.161482543f, -0.161507472f, -0.161525562f, + -0.161536828f, -0.161541268f, -0.161538944f, -0.161529869f, -0.161514089f, + -0.161491618f, -0.161462501f, -0.161426738f, -0.161384419f, -0.161335513f, + -0.161280081f, -0.161218151f, -0.161149755f, -0.161074907f, -0.160993651f, + -0.160906032f, -0.160812065f, -0.160711765f, -0.160605207f, -0.160492390f, + -0.160373345f, -0.160248131f, -0.160116762f, -0.159979254f, -0.159835666f, + -0.159686014f, -0.159530357f, -0.159368694f, -0.159201056f, -0.159027517f, + -0.158848062f, -0.158662766f, -0.158471599f, -0.158274680f, -0.158071980f, + -0.157863557f, -0.157649443f, -0.157429650f, -0.157204241f, -0.156973228f, + -0.156736642f, -0.156494558f, -0.156246960f, -0.155993909f, -0.155735433f, + -0.155471563f, -0.155202329f, -0.154927775f, -0.154647917f, -0.154362813f, + -0.154072478f, -0.153776988f, -0.153476328f, -0.153170541f, -0.152859688f, + -0.152543753f, -0.152222827f, -0.151896924f, -0.151566073f, -0.151230305f, + -0.150889665f, -0.150544196f, -0.150193915f, -0.149838865f, -0.149479061f, + -0.149114594f, -0.148745432f, -0.148371637f, -0.147993281f, -0.147610337f, + -0.147222877f, -0.146830946f, -0.146434546f, -0.146033719f, -0.145628527f, + -0.145218968f, -0.144805118f, -0.144386992f, -0.143964618f, -0.143538073f, + -0.143107325f, -0.142672464f, -0.142233476f, -0.141790435f, -0.141343385f, + -0.140892327f, -0.140437320f, -0.139978394f, -0.139515579f, -0.139048934f, + -0.138578460f, -0.138104215f, -0.137626216f, -0.137144551f, -0.136659175f, + -0.136170194f, -0.135677606f, -0.135181442f, -0.134681761f, -0.134178594f, + -0.133671984f, -0.133161947f, -0.132648528f, -0.132131740f, -0.131611660f, + -0.131088302f, -0.130561695f, -0.130031943f, -0.129498973f, -0.128962860f, + -0.128423676f, -0.127881393f, -0.127336115f, -0.126787826f, -0.126236603f, + -0.125682443f, -0.125125393f, -0.124565504f, -0.124002807f, -0.123437323f, + -0.122869089f, -0.122298159f, -0.121724561f, -0.121148311f, -0.120569460f, + -0.119988061f, -0.119404130f, -0.118817687f, -0.118228793f, -0.117637470f, + -0.117043748f, -0.116447672f, -0.115849286f, -0.115248613f, -0.114645667f, + -0.114040568f, -0.113433234f, -0.112823755f, -0.112212166f, -0.111598492f, + -0.110982776f, -0.110365056f, -0.109745361f, -0.109123722f, -0.108500175f, + -0.107874751f, -0.107247494f, -0.106618427f, -0.105987601f, -0.105355024f, + -0.104720749f, -0.104084812f, -0.103447236f, -0.102808066f, -0.102167316f, + -0.101525046f, -0.100881256f, -0.100236014f, -0.099589340f, -0.098941252f, + -0.098291807f, -0.097641021f, -0.096988983f, -0.096335620f, -0.095681041f, + -0.095025249f, -0.094368286f, -0.093710184f, -0.093050972f, -0.092390701f, + -0.091729380f, -0.091067046f, -0.090403758f, -0.089739501f, -0.089074343f, + -0.088408306f, -0.087741412f, -0.087073699f, -0.086405218f, -0.085735977f, + -0.085065998f, -0.084395349f, -0.083724037f, -0.083052084f, -0.082379535f, + -0.081706434f, -0.081032783f, -0.080358639f, -0.079684012f, -0.079008937f, + -0.078333504f, -0.077657640f, -0.076981425f, -0.076304883f, -0.075628042f, + -0.074950956f, -0.074273616f, -0.073596083f, -0.072918370f, -0.072240517f, + -0.071562558f, -0.070884496f, -0.070206381f, -0.069528244f, -0.068850100f, + -0.068171993f, -0.067493953f, -0.066815972f, -0.066138126f, -0.065460421f, + -0.064782880f, -0.064105548f, -0.063428439f, -0.062751584f, -0.062075011f, + -0.061398748f, -0.060722828f, -0.060047265f, -0.059372153f, -0.058697399f, + -0.058023106f, -0.057349272f, -0.056675948f, -0.056003150f, -0.055330887f, + -0.054659221f, -0.053988155f, -0.053317714f, -0.052647941f, -0.051978838f, + -0.051310450f, -0.050642796f, -0.049975898f, -0.049309790f, -0.048644483f, + -0.047980014f, -0.047316402f, -0.046653673f, -0.045991853f, -0.045330971f, + -0.044671040f, -0.044012092f, -0.043354150f, -0.042697236f, -0.042041373f, + -0.041386627f, -0.040732939f, -0.040080376f, -0.039428953f, -0.038778704f, + -0.038129643f, -0.037481792f, -0.036835186f, -0.036189832f, -0.035545766f, + -0.034902997f, -0.034261558f, -0.033621464f, -0.032982741f, -0.032345407f, + -0.031709481f, -0.031074993f, -0.030441960f, -0.029810399f, -0.029180335f, + -0.028551787f, -0.027924776f, -0.027299322f, -0.026675448f, -0.026053172f, + -0.025432510f, -0.024813488f, -0.024196124f, -0.023580479f, -0.022966485f, + -0.022354206f, -0.021743659f, -0.021134868f, -0.020527845f, -0.019922616f, + -0.019319192f, -0.018717598f, -0.018117845f, -0.017519956f, -0.016923945f, + -0.016329836f, -0.015737642f, -0.015147380f, -0.014559067f, -0.013972721f, + -0.013388360f, -0.012805998f, -0.012225654f, -0.011647343f, -0.011071082f, + -0.010496887f, -0.009924773f, -0.009354758f, -0.008786854f, -0.008221081f, + -0.007657450f, -0.007096022f, -0.006536725f, -0.005979617f, -0.005424712f, + -0.004872025f, -0.004321571f, -0.003773364f, -0.003227417f, -0.002683746f, + -0.002142363f, -0.001603282f, -0.001066516f, -0.000532080f, 0.000000015f, + 0.000529755f, 0.001057127f, 0.001582118f, 0.002104717f, 0.002624909f, + 0.003142685f, 0.003658031f, 0.004170935f, 0.004681387f, 0.005189373f, + 0.005694883f, 0.006197905f, 0.006698429f, 0.007196404f, 0.007691898f, + 0.008184860f, 0.008675281f, 0.009163151f, 0.009648458f, 0.010131192f, + 0.010611345f, 0.011088905f, 0.011563865f, 0.012036213f, 0.012505942f, + 0.012973041f, 0.013437501f, 0.013899315f, 0.014358475f, 0.014814967f, + 0.015268789f, 0.015719930f, 0.016168380f, 0.016614137f, 0.017057184f, + 0.017497523f, 0.017935142f, 0.018370032f, 0.018802188f, 0.019231608f, + 0.019658273f, 0.020082152f, 0.020503307f, 0.020921690f, 0.021337299f, + 0.021750130f, 0.022160176f, 0.022567427f, 0.022971880f, 0.023373535f, + 0.023772376f, 0.024168408f, 0.024561619f, 0.024952007f, 0.025339566f, + 0.025724288f, 0.026106175f, 0.026485221f, 0.026861422f, 0.027234772f, + 0.027605265f, 0.027972901f, 0.028337676f, 0.028699588f, 0.029058624f, + 0.029414795f, 0.029768089f, 0.030118505f, 0.030466037f, 0.030810660f, + 0.031152423f, 0.031491302f, 0.031827286f, 0.032160383f, 0.032490581f, + 0.032817882f, 0.033142287f, 0.033463787f, 0.033782389f, 0.034098089f, + 0.034410883f, 0.034720775f, 0.035027757f, 0.035331838f, 0.035633009f, + 0.035931274f, 0.036226626f, 0.036519073f, 0.036808614f, 0.037095241f, + 0.037378959f, 0.037659772f, 0.037937686f, 0.038212679f, 0.038484775f, + 0.038753960f, 0.039020218f, 0.039283592f, 0.039544068f, 0.039801639f, + 0.040056318f, 0.040308096f, 0.040556971f, 0.040802956f, 0.041046046f, + 0.041286245f, 0.041523557f, 0.041757982f, 0.041989524f, 0.042218179f, + 0.042443957f, 0.042666860f, 0.042886890f, 0.043104045f, 0.043318339f, + 0.043529764f, 0.043738328f, 0.043944035f, 0.044146888f, 0.044346895f, + 0.044544052f, 0.044738363f, 0.044929843f, 0.045118481f, 0.045304272f, + 0.045487255f, 0.045667417f, 0.045844764f, 0.046019293f, 0.046191018f, + 0.046359941f, 0.046526067f, 0.046689399f, 0.046849940f, 0.047007702f, + 0.047162689f, 0.047314901f, 0.047464348f, 0.047611035f, 0.047754966f, + 0.047896147f, 0.048034586f, 0.048170291f, 0.048303265f, 0.048433512f, + 0.048561048f, 0.048685864f, 0.048807982f, 0.048927400f, 0.049044125f, + 0.049158167f, 0.049269531f, 0.049378205f, 0.049484238f, 0.049587611f, + 0.049688339f, 0.049786422f, 0.049881872f, 0.049974691f, 0.050064899f, + 0.050152492f, 0.050237484f, 0.050319877f, 0.050399683f, 0.050476916f, + 0.050551571f, 0.050623666f, 0.050693203f, 0.050760195f, 0.050824653f, + 0.050886583f, 0.050945986f, 0.051002879f, 0.051057268f, 0.051109165f, + 0.051158577f, 0.051205512f, 0.051249981f, 0.051291991f, 0.051331542f, + 0.051368665f, 0.051403359f, 0.051435627f, 0.051465489f, 0.051492948f, + 0.051518012f, 0.051540703f, 0.051561009f, 0.051578961f, 0.051594563f, + 0.051607810f, 0.051618744f, 0.051627338f, 0.051633626f, 0.051637612f, + 0.051639307f, 0.051638719f, 0.051635865f, 0.051630747f, 0.051623378f, + 0.051613763f, 0.051601931f, 0.051587880f, 0.051571615f, 0.051553156f, + 0.051532514f, 0.051509693f, 0.051484708f, 0.051457576f, 0.051428299f, + 0.051396891f, 0.051363368f, 0.051327739f, 0.051290002f, 0.051250193f, + 0.051208302f, 0.051164351f, 0.051118344f, 0.051070303f, 0.051020239f, + 0.050968144f, 0.050914053f, 0.050857969f, 0.050799899f, 0.050739862f, + 0.050677869f, 0.050613929f, 0.050548054f, 0.050480254f, 0.050410546f, + 0.050338943f, 0.050265454f, 0.050190084f, 0.050112855f, 0.050033774f, + 0.049952857f, 0.049870111f, 0.049785554f, 0.049699202f, 0.049611051f, + 0.049521122f, 0.049429435f, 0.049335998f, 0.049240820f, 0.049143907f, + 0.049045283f, 0.048944961f, 0.048842940f, 0.048739251f, 0.048633892f, + 0.048526883f, 0.048418235f, 0.048307955f, 0.048196062f, 0.048082568f, + 0.047967490f, 0.047850832f, 0.047732603f, 0.047612831f, 0.047491513f, + 0.047368675f, 0.047244325f, 0.047118478f, 0.046991132f, 0.046862319f, + 0.046732042f, 0.046600312f, 0.046467155f, 0.046332560f, 0.046196572f, + 0.046059173f, 0.045920394f, 0.045780238f, 0.045638733f, 0.045495875f, + 0.045351684f, 0.045206167f, 0.045059349f, 0.044911236f, 0.044761848f, + 0.044611182f, 0.044459261f, 0.044306096f, 0.044151701f, 0.043996092f, + 0.043839272f, 0.043681268f, 0.043522079f, 0.043361723f, 0.043200217f, + 0.043037571f, 0.042873796f, 0.042708915f, 0.042542927f, 0.042375844f, + 0.042207699f, 0.042038482f, 0.041868217f, 0.041696910f, 0.041524585f, + 0.041351244f, 0.041176908f, 0.041001581f, 0.040825289f, 0.040648032f, + 0.040469825f, 0.040290687f, 0.040110629f, 0.039929654f, 0.039747790f, + 0.039565038f, 0.039381415f, 0.039196935f, 0.039011609f, 0.038825445f, + 0.038638465f, 0.038450673f, 0.038262092f, 0.038072724f, 0.037882581f, + 0.037691690f, 0.037500042f, 0.037307668f, 0.037114572f, 0.036920771f, + 0.036726266f, 0.036531083f, 0.036335230f, 0.036138717f, 0.035941560f, + 0.035743766f, 0.035545345f, 0.035346344f, 0.035146721f, 0.034946512f, + 0.034745730f, 0.034544386f, 0.034342494f, 0.034140065f, 0.033937111f, + 0.033733644f, 0.033529676f, 0.033325221f, 0.033120286f, 0.032914892f, + 0.032709036f, 0.032502741f, 0.032296017f, 0.032088876f, 0.031881329f, + 0.031673383f, 0.031465057f, 0.031256359f, 0.031047301f, 0.030837893f, + 0.030628148f, 0.030418083f, 0.030207697f, 0.029997014f, 0.029786035f, + 0.029574780f, 0.029363252f, 0.029151469f, 0.028939439f, 0.028727176f, + 0.028514685f, 0.028301982f, 0.028089074f, 0.027875982f, 0.027662706f, + 0.027449260f, 0.027235655f, 0.027021904f, 0.026808018f, 0.026594002f, + 0.026379872f, 0.026165638f, 0.025951311f, 0.025736896f, 0.025522409f, + 0.025307864f, 0.025093259f, 0.024878617f, 0.024663944f, 0.024449248f, + 0.024234539f, 0.024019832f, 0.023805158f, 0.023590479f, 0.023375830f, + 0.023161218f, 0.022946658f, 0.022732155f, 0.022517720f, 0.022303363f, + 0.022089096f, 0.021874927f, 0.021660868f, 0.021446921f, 0.021233102f, + 0.021019425f, 0.020805888f, 0.020592507f, 0.020379292f, 0.020166250f, + 0.019953389f, 0.019740723f, 0.019528257f, 0.019316001f, 0.019103965f, + 0.018892156f, 0.018680587f, 0.018469261f, 0.018258194f, 0.018047387f, + 0.017836852f, 0.017626595f, 0.017416634f, 0.017206967f, 0.016997607f, + 0.016788563f, 0.016579840f, 0.016371451f, 0.016163401f, 0.015955698f, + 0.015748354f, 0.015541371f, 0.015334761f, 0.015128531f, 0.014922690f, + 0.014717245f, 0.014512201f, 0.014307571f, 0.014103360f, 0.013899575f, + 0.013696224f, 0.013493315f, 0.013290856f, 0.013088853f, 0.012887316f, + 0.012686247f, 0.012485661f, 0.012285583f, 0.012085971f, 0.011886863f, + 0.011688258f, 0.011490168f, 0.011292599f, 0.011095556f, 0.010899050f, + 0.010703083f, 0.010507663f, 0.010312798f, 0.010118493f, 0.009924755f, + 0.009731592f, 0.009539006f, 0.009347008f, 0.009155600f, 0.008964794f, + 0.008774590f, 0.008584999f, 0.008396022f, 0.008207668f, 0.008019943f, + 0.007832851f, 0.007646400f, 0.007460595f, 0.007275441f, 0.007090943f, + 0.006907108f, 0.006723941f, 0.006541446f, 0.006359630f, 0.006178498f, + 0.005998055f, 0.005818305f, 0.005639255f, 0.005460909f, 0.005283272f, + 0.005106349f, 0.004930146f, 0.004754666f, 0.004579914f, 0.004405896f, + 0.004232615f, 0.004060077f, 0.003888285f, 0.003717245f, 0.003546960f, + 0.003377435f, 0.003208674f, 0.003040682f, 0.002873462f, 0.002707019f, + 0.002541356f, 0.002376478f, 0.002212389f, 0.002049116f, 0.001886615f, + 0.001724914f, 0.001564016f, 0.001403926f, 0.001244646f, 0.001086180f, + 0.000928532f, 0.000771705f, 0.000615702f, 0.000460527f, 0.000306183f, + 0.000152673f, -0.000000001f, -0.000151834f, -0.000302824f, -0.000452968f, + -0.000602263f, -0.000750707f, -0.000898296f, -0.001045028f, -0.001190900f, + -0.001335910f, -0.001480055f, -0.001623332f, -0.001765741f, -0.001907276f, + -0.002047938f, -0.002187723f, -0.002326628f, -0.002464653f, -0.002601795f, + -0.002738052f, -0.002873422f, -0.003007903f, -0.003141493f, -0.003274190f, + -0.003405993f, -0.003536900f, -0.003666909f, -0.003796018f, -0.003924227f, + -0.004051533f, -0.004177936f, -0.004303433f, -0.004428024f, -0.004551707f, + -0.004674482f, -0.004796346f, -0.004917298f, -0.005037338f, -0.005156465f, + -0.005274678f, -0.005391975f, -0.005508356f, -0.005623801f, -0.005738347f, + -0.005851975f, -0.005964684f, -0.006076474f, -0.006187343f, -0.006297291f, + -0.006406318f, -0.006514424f, -0.006621608f, -0.006727869f, -0.006833209f, + -0.006937624f, -0.007041118f, -0.007143687f, -0.007245334f, -0.007346058f, + -0.007445859f, -0.007544736f, -0.007642691f, -0.007739722f, -0.007835831f, + -0.007931018f, -0.008025283f, -0.008118626f, -0.008211047f, -0.008302549f, + -0.008393129f, -0.008482790f, -0.008571531f, -0.008659353f, -0.008746257f, + -0.008832245f, -0.008917316f, -0.009001471f, -0.009084711f, -0.009167036f, + -0.009248449f, -0.009328948f, -0.009408538f, -0.009487216f, -0.009564986f, + -0.009641849f, -0.009717803f, -0.009792852f, -0.009866998f, -0.009940239f, + -0.010012579f, -0.010084019f, -0.010154560f, -0.010224204f, -0.010292951f, + -0.010360803f, -0.010427763f, -0.010493831f, -0.010558996f, -0.010623286f, + -0.010686691f, -0.010749210f, -0.010810846f, -0.010871602f, -0.010931478f, + -0.010990476f, -0.011048601f, -0.011105850f, -0.011162230f, -0.011217739f, + -0.011272381f, -0.011326157f, -0.011379071f, -0.011431124f, -0.011482318f, + -0.011532655f, -0.011582140f, -0.011630770f, -0.011678550f, -0.011725485f, + -0.011771576f, -0.011816822f, -0.011861229f, -0.011904799f, -0.011947533f, + -0.011989436f, -0.012030509f, -0.012070752f, -0.012110173f, -0.012148771f, + -0.012186551f, -0.012223513f, -0.012259661f, -0.012295000f, -0.012329529f, + -0.012363252f, -0.012396174f, -0.012428297f, -0.012459621f, -0.012490152f, + -0.012519893f, -0.012548844f, -0.012577013f, -0.012604399f, -0.012631006f, + -0.012656839f, -0.012681897f, -0.012706185f, -0.012729709f, -0.012752469f, + -0.012774469f, -0.012795713f, -0.012816204f, -0.012835944f, -0.012854930f, + -0.012873179f, -0.012890689f, -0.012907463f, -0.012923501f, -0.012938812f, + -0.012953395f, -0.012967254f, -0.012980393f, -0.012992817f, -0.013004529f, + -0.013015532f, -0.013025828f, -0.013035421f, -0.013044316f, -0.013052518f, + -0.013060026f, -0.013066847f, -0.013072984f, -0.013078442f, -0.013083221f, + -0.013087329f, -0.013090767f, -0.013093537f, -0.013095647f, -0.013097100f, + -0.013097897f, -0.013098043f, -0.013097542f, -0.013096399f, -0.013094617f, + -0.013092197f, -0.013089147f, -0.013085471f, -0.013081170f, -0.013076247f, + -0.013070711f, -0.013064560f, -0.013057803f, -0.013050442f, -0.013042479f, + -0.013033919f, -0.013024768f, -0.013015027f, -0.013004702f, -0.012993797f, + -0.012982314f, -0.012970260f, -0.012957636f, -0.012944449f, -0.012930701f, + -0.012916395f, -0.012901539f, -0.012886133f, -0.012870182f, -0.012853689f, + -0.012836664f, -0.012819104f, -0.012801019f, -0.012782406f, -0.012763276f, + -0.012743629f, -0.012723471f, -0.012702805f, -0.012681637f, -0.012659966f, + -0.012637801f, -0.012615148f, -0.012592005f, -0.012568381f, -0.012544277f, + -0.012519698f, -0.012494650f, -0.012469133f, -0.012443157f, -0.012416720f, + -0.012389832f, -0.012362492f, -0.012334707f, -0.012306482f, -0.012277817f, + -0.012248720f, -0.012219194f, -0.012189244f, -0.012158873f, -0.012128084f, + -0.012096884f, -0.012065274f, -0.012033261f, -0.012000849f, -0.011968041f, + -0.011934839f, -0.011901250f, -0.011867279f, -0.011832927f, -0.011798202f, + -0.011763104f, -0.011727640f, -0.011691812f, -0.011655626f, -0.011619086f, + -0.011582195f, -0.011544957f, -0.011507377f, -0.011469459f, -0.011431207f, + -0.011392625f, -0.011353718f, -0.011314487f, -0.011274938f, -0.011235079f, + -0.011194907f, -0.011154431f, -0.011113651f, -0.011072575f, -0.011031206f, + -0.010989547f, -0.010947601f, -0.010905375f, -0.010862871f, -0.010820094f, + -0.010777046f, -0.010733733f, -0.010690158f, -0.010646327f, -0.010602240f, + -0.010557905f, -0.010513324f, -0.010468500f, -0.010423439f, -0.010378144f, + -0.010332618f, -0.010286866f, -0.010240891f, -0.010194698f, -0.010148291f, + -0.010101672f, -0.010054846f, -0.010007816f, -0.009960588f, -0.009913164f, + -0.009865548f, -0.009817744f, -0.009769755f, -0.009721586f, -0.009673241f, + -0.009624721f, -0.009576033f, -0.009527179f, -0.009478163f, -0.009428989f, + -0.009379660f, -0.009330180f, -0.009280552f, -0.009230781f, -0.009180869f, + -0.009130822f, -0.009080641f, -0.009030331f, -0.008979894f, -0.008929336f, + -0.008878659f, -0.008827867f, -0.008776963f, -0.008725950f, -0.008674833f, + -0.008623619f, -0.008572303f, -0.008520893f, -0.008469390f, -0.008417801f, + -0.008366127f, -0.008314372f, -0.008262540f, -0.008210634f, -0.008158657f, + -0.008106613f, -0.008054503f, -0.008002332f, -0.007950104f, -0.007897821f, + -0.007845488f, -0.007793106f, -0.007740679f, -0.007688211f, -0.007635703f, + -0.007583159f, -0.007530585f, -0.007477981f, -0.007425350f, -0.007372697f, + -0.007320023f, -0.007267332f, -0.007214627f, -0.007161912f, -0.007109188f, + -0.007056459f, -0.007003729f, -0.006951000f, -0.006898273f, -0.006845553f, + -0.006792843f, -0.006740147f, -0.006687465f, -0.006634800f, -0.006582157f, + -0.006529537f, -0.006476944f, -0.006424380f, -0.006371849f, -0.006319351f, + -0.006266891f, -0.006214471f, -0.006162094f, -0.006109761f, -0.006057477f, + -0.006005243f, -0.005953063f, -0.005900938f, -0.005848871f, -0.005796865f, + -0.005744927f, -0.005693051f, -0.005641241f, -0.005589503f, -0.005537837f, + -0.005486248f, -0.005434736f, -0.005383304f, -0.005331955f, -0.005280690f, + -0.005229514f, -0.005178426f, -0.005127430f, -0.005076529f, -0.005025723f, + -0.004975016f, -0.004924410f, -0.004873907f, -0.004823509f, -0.004773218f, + -0.004723036f, -0.004672966f, -0.004623009f, -0.004573168f, -0.004523444f, + -0.004473840f, -0.004424357f, -0.004374999f, -0.004325765f, -0.004276660f, + -0.004227683f, -0.004178838f, -0.004130126f, -0.004081549f, -0.004033110f, + -0.003984808f, -0.003936647f, -0.003888629f, -0.003840754f, -0.003793026f, + -0.003745445f, -0.003698014f, -0.003650733f, -0.003603605f, -0.003556631f, + -0.003509813f, -0.003463153f, -0.003416652f, -0.003370312f, -0.003324133f, + -0.003278119f, -0.003232269f, -0.003186587f, -0.003141073f, -0.003095729f, + -0.003050560f, -0.003005560f, -0.002960733f, -0.002916081f, -0.002871606f, + -0.002827310f, -0.002783192f, -0.002739255f, -0.002695500f, -0.002651928f, + -0.002608541f, -0.002565339f, -0.002522324f, -0.002479498f, -0.002436860f, + -0.002394413f, -0.002352157f, -0.002310094f, -0.002268225f, -0.002226550f, + -0.002185071f, -0.002143790f, -0.002102705f, -0.002061821f, -0.002021135f, + -0.001980651f, -0.001940368f, -0.001900289f, -0.001860412f, -0.001820740f, + -0.001781274f, -0.001742014f, -0.001702961f, -0.001664116f, -0.001625479f, + -0.001587052f, -0.001548836f, -0.001510830f, -0.001473036f, -0.001435455f, + -0.001398086f, -0.001360932f, -0.001323992f, -0.001287267f, -0.001250757f, + -0.001214464f, -0.001178389f, -0.001142530f, -0.001106890f, -0.001071468f, + -0.001036266f, -0.001001283f, -0.000966520f, -0.000931978f, -0.000897657f, + -0.000863557f, -0.000829685f, -0.000796029f, -0.000762597f, -0.000729387f, + -0.000696401f, -0.000663639f, -0.000631101f, -0.000598788f, -0.000566699f, + -0.000534836f, -0.000503197f, -0.000471784f, -0.000440597f, -0.000409636f, + -0.000378901f, -0.000348393f, -0.000318111f, -0.000288056f, -0.000258228f, + -0.000228626f, -0.000199252f, -0.000170105f, -0.000141186f, -0.000112493f, + -0.000084028f, -0.000055791f, -0.000027781f, 0.000000002f, 0.000027557f, + 0.000054884f, 0.000081984f, 0.000108857f, 0.000135502f, 0.000161920f, + 0.000188111f, 0.000214075f, 0.000239812f, 0.000265322f, 0.000290606f, + 0.000315663f, 0.000340493f, 0.000365097f, 0.000389476f, 0.000413628f, + 0.000437555f, 0.000461256f, 0.000484733f, 0.000507984f, 0.000531011f, + 0.000553814f, 0.000576393f, 0.000598748f, 0.000620879f, 0.000642788f, + 0.000664473f, 0.000685933f, 0.000707174f, 0.000728194f, 0.000748993f, + 0.000769570f, 0.000789927f, 0.000810064f, 0.000829982f, 0.000849680f, + 0.000869160f, 0.000888421f, 0.000907465f, 0.000926291f, 0.000944901f, + 0.000963294f, 0.000981472f, 0.000999434f, 0.001017181f, 0.001034715f, + 0.001052034f, 0.001069141f, 0.001086035f, 0.001102717f, 0.001119188f, + 0.001135448f, 0.001151499f, 0.001167339f, 0.001182971f, 0.001198395f, + 0.001213611f, 0.001228620f, 0.001243423f, 0.001258021f, 0.001272413f, + 0.001286602f, 0.001300586f, 0.001314368f, 0.001327948f, 0.001341327f, + 0.001354505f, 0.001367483f, 0.001380263f, 0.001392843f, 0.001405226f, + 0.001417413f, 0.001429403f, 0.001441198f, 0.001452798f, 0.001464205f, + 0.001475418f, 0.001486440f, 0.001497271f, 0.001507911f, 0.001518361f, + 0.001528623f, 0.001538696f, 0.001548581f, 0.001558281f, 0.001567796f, + 0.001577127f, 0.001586274f, 0.001595238f, 0.001604020f, 0.001612622f, + 0.001621043f, 0.001629285f, 0.001637349f, 0.001645236f, 0.001652946f, + 0.001660481f, 0.001667841f, 0.001675027f, 0.001682041f, 0.001688883f, + 0.001695554f, 0.001702055f, 0.001708387f, 0.001714552f, 0.001720549f, + 0.001726380f, 0.001732047f, 0.001737549f, 0.001742888f, 0.001748065f, + 0.001753081f, 0.001757936f, 0.001762632f, 0.001767171f, 0.001771552f, + 0.001775777f, 0.001779847f, 0.001783762f, 0.001787525f, 0.001791135f, + 0.001794595f, 0.001797904f, 0.001801064f, 0.001804076f, 0.001806941f, + 0.001809660f, 0.001812234f, 0.001814664f, 0.001816952f, 0.001819097f, + 0.001821102f, 0.001822967f, 0.001824693f, 0.001826282f, 0.001827733f, + 0.001829050f, 0.001830231f, 0.001831278f, 0.001832194f, 0.001832979f, + 0.001833633f, 0.001834158f, 0.001834554f, 0.001834824f, 0.001834967f, + 0.001834986f, 0.001834880f, 0.001834651f, 0.001834301f, 0.001833830f, + 0.001833239f, 0.001832529f, 0.001831702f, 0.001830758f, 0.001829698f, + 0.001828525f, 0.001827237f, 0.001825838f, 0.001824327f, 0.001822706f, + 0.001820976f, 0.001819138f, 0.001817193f, 0.001815141f, 0.001812985f, + 0.001810725f, 0.001808363f, 0.001805898f, 0.001803333f, 0.001800668f, + 0.001797904f, 0.001795043f, 0.001792086f, 0.001789033f, 0.001785886f, + 0.001782645f, 0.001779312f, 0.001775887f, 0.001772373f, 0.001768769f, + 0.001765078f, 0.001761299f, 0.001757434f, 0.001753483f, 0.001749449f, + 0.001745332f, 0.001741133f, 0.001736853f, 0.001732493f, 0.001728054f, + 0.001723537f, 0.001718944f, 0.001714273f, 0.001709529f, 0.001704710f, + 0.001699819f, 0.001694857f, 0.001689823f, 0.001684719f, 0.001679546f, + 0.001674306f, 0.001668998f, 0.001663625f, 0.001658187f, 0.001652685f, + 0.001647120f, 0.001641493f, 0.001635804f, 0.001630056f, 0.001624249f, + 0.001618383f, 0.001612461f, 0.001606481f, 0.001600448f, 0.001594359f, + 0.001588217f, 0.001582022f, 0.001575776f, 0.001569480f, 0.001563134f, + 0.001556739f, 0.001550296f, 0.001543806f, 0.001537270f, 0.001530689f, + 0.001524064f, 0.001517395f, 0.001510684f, 0.001503932f, 0.001497139f, + 0.001490306f, 0.001483435f, 0.001476525f, 0.001469578f, 0.001462596f, + 0.001455577f, 0.001448524f, 0.001441438f, 0.001434318f, 0.001427167f, + 0.001419984f, 0.001412771f, 0.001405529f, 0.001398258f, 0.001390959f, + 0.001383633f, 0.001376281f, 0.001368903f, 0.001361501f, 0.001354076f, + 0.001346627f, 0.001339155f, 0.001331663f, 0.001324150f, 0.001316617f, + 0.001309064f, 0.001301494f, 0.001293906f, 0.001286301f, 0.001278680f, + 0.001271044f, 0.001263393f, 0.001255728f, 0.001248050f, 0.001240360f, + 0.001232658f, 0.001224945f, 0.001217221f, 0.001209488f, 0.001201747f, + 0.001193997f, 0.001186240f, 0.001178476f, 0.001170706f, 0.001162930f, + 0.001155150f, 0.001147365f, 0.001139577f, 0.001131787f, 0.001123994f, + 0.001116200f, 0.001108405f, 0.001100609f, 0.001092814f, 0.001085020f, + 0.001077228f, 0.001069438f, 0.001061651f, 0.001053867f, 0.001046087f, + 0.001038312f, 0.001030542f, 0.001022778f, 0.001015020f, 0.001007270f, + 0.000999526f, 0.000991791f, 0.000984065f, 0.000976347f, 0.000968640f, + 0.000960942f, 0.000953256f, 0.000945580f, 0.000937917f, 0.000930266f, + 0.000922628f, 0.000915002f, 0.000907391f, 0.000899794f, 0.000892212f, + 0.000884646f, 0.000877095f, 0.000869560f, 0.000862042f, 0.000854541f, + 0.000847058f, 0.000839593f, 0.000832147f, 0.000824719f, 0.000817311f, + 0.000809923f, 0.000802555f, 0.000795208f, 0.000787881f, 0.000780577f, + 0.000773294f, 0.000766033f, 0.000758795f, 0.000751581f, 0.000744389f, + 0.000737222f, 0.000730079f, 0.000722960f, 0.000715866f, 0.000708798f, + 0.000701755f, 0.000694738f, 0.000687748f, 0.000680784f, 0.000673847f, + 0.000666937f, 0.000660055f, 0.000653202f, 0.000646376f, 0.000639579f, + 0.000632810f, 0.000626071f, 0.000619362f, 0.000612682f, 0.000606032f, + 0.000599412f, 0.000592823f, 0.000586265f, 0.000579738f, 0.000573242f, + 0.000566777f, 0.000560345f, 0.000553944f, 0.000547577f, 0.000541241f, + 0.000534938f, 0.000528668f, 0.000522432f, 0.000516228f, 0.000510059f, + 0.000503923f, 0.000497821f, 0.000491753f, 0.000485720f, 0.000479721f, + 0.000473757f, 0.000467828f, 0.000461934f, 0.000456075f, 0.000450252f, + 0.000444464f, 0.000438712f, 0.000432996f, 0.000427316f, 0.000421672f, + 0.000416064f, 0.000410493f, 0.000404958f, 0.000399460f, 0.000393998f, + 0.000388574f, 0.000383186f, 0.000377836f, 0.000372523f, 0.000367247f, + 0.000362008f, 0.000356807f, 0.000351643f, 0.000346517f, 0.000341429f, + 0.000336378f, 0.000331366f, 0.000326391f, 0.000321454f, 0.000316555f, + 0.000311695f, 0.000306872f, 0.000302088f, 0.000297341f, 0.000292633f, + 0.000287963f, 0.000283332f, 0.000278739f, 0.000274184f, 0.000269667f, + 0.000265189f, 0.000260749f, 0.000256348f, 0.000251985f, 0.000247661f, + 0.000243374f, 0.000239126f, 0.000234917f, 0.000230745f, 0.000226613f, + 0.000222518f, 0.000218462f, 0.000214443f, 0.000210464f, 0.000206522f, + 0.000202618f, 0.000198753f, 0.000194926f, 0.000191136f, 0.000187385f, + 0.000183671f, 0.000179996f, 0.000176358f, 0.000172758f, 0.000169195f, + 0.000165670f, 0.000162183f, 0.000158733f, 0.000155321f, 0.000151945f, + 0.000148607f, 0.000145307f, 0.000142043f, 0.000138816f, 0.000135626f, + 0.000132473f, 0.000129356f, 0.000126276f, 0.000123233f, 0.000120225f, + 0.000117255f, 0.000114320f, 0.000111421f, 0.000108558f, 0.000105731f, + 0.000102940f, 0.000100184f, 0.000097463f, 0.000094778f, 0.000092128f, + 0.000089513f, 0.000086933f, 0.000084388f, 0.000081878f, 0.000079402f, + 0.000076960f, 0.000074552f, 0.000072179f, 0.000069839f, 0.000067534f, + 0.000065261f, 0.000063023f, 0.000060817f, 0.000058645f, 0.000056506f, + 0.000054399f, 0.000052326f, 0.000050284f, 0.000048275f, 0.000046299f, + 0.000044354f, 0.000042441f, 0.000040560f, 0.000038710f, 0.000036891f, + 0.000035104f, 0.000033348f, 0.000031622f, 0.000029927f, 0.000028263f, + 0.000026628f, 0.000025024f, 0.000023450f, 0.000021905f, 0.000020390f, + 0.000018904f, 0.000017447f, 0.000016019f, 0.000014620f, 0.000013249f, + 0.000011907f, 0.000010593f, 0.000009307f, 0.000008048f, 0.000006818f, + 0.000005614f, 0.000004438f, 0.000003288f, 0.000002166f, 0.000001070f, + -0.000000000f +}; + +static const float ResamplerFilterDifference[RESAMPLER_FILTER_SIZE] = { + -0.000006318f, -0.000019312f, -0.000033081f, -0.000046730f, -0.000060380f, + -0.000074029f, -0.000087738f, -0.000101388f, -0.000115037f, -0.000128686f, + -0.000142336f, -0.000155985f, -0.000169694f, -0.000183165f, -0.000196993f, + -0.000210524f, -0.000224173f, -0.000237763f, -0.000251293f, -0.000265062f, + -0.000278592f, -0.000292122f, -0.000305772f, -0.000319421f, -0.000332832f, + -0.000346422f, -0.000359952f, -0.000373542f, -0.000387073f, -0.000400543f, + -0.000414014f, -0.000427663f, -0.000441074f, -0.000454485f, -0.000468016f, + -0.000481427f, -0.000494778f, -0.000508308f, -0.000521660f, -0.000535011f, + -0.000548482f, -0.000561833f, -0.000575066f, -0.000588536f, -0.000601768f, + -0.000615180f, -0.000628352f, -0.000641525f, -0.000655055f, -0.000668049f, + -0.000681281f, -0.000694513f, -0.000707746f, -0.000720799f, -0.000733972f, + -0.000747204f, -0.000760138f, -0.000773191f, -0.000786424f, -0.000799239f, + -0.000812411f, -0.000825346f, -0.000838339f, -0.000851214f, -0.000864267f, + -0.000877023f, -0.000890017f, -0.000902772f, -0.000915587f, -0.000928521f, + -0.000941217f, -0.000953972f, -0.000966668f, -0.000979364f, -0.000992119f, + -0.001004696f, -0.001017392f, -0.001029909f, -0.001042426f, -0.001055002f, + -0.001067519f, -0.001080096f, -0.001092434f, -0.001104832f, -0.001117289f, + -0.001129627f, -0.001141965f, -0.001154304f, -0.001166403f, -0.001178861f, + -0.001191020f, -0.001203120f, -0.001215160f, -0.001227558f, -0.001239419f, + -0.001251400f, -0.001263618f, -0.001275480f, -0.001287460f, -0.001299262f, + -0.001311302f, -0.001322985f, -0.001334965f, -0.001346648f, -0.001358271f, + -0.001370072f, -0.001381695f, -0.001393259f, -0.001404881f, -0.001416504f, + -0.001427948f, -0.001439393f, -0.001450837f, -0.001462340f, -0.001473546f, + -0.001484871f, -0.001496255f, -0.001507342f, -0.001518726f, -0.001529694f, + -0.001540840f, -0.001552045f, -0.001562893f, -0.001574039f, -0.001584947f, + -0.001595795f, -0.001606703f, -0.001617491f, -0.001628280f, -0.001639009f, + -0.001649678f, -0.001660407f, -0.001670957f, -0.001681507f, -0.001692057f, + -0.001702428f, -0.001713037f, -0.001723289f, -0.001733601f, -0.001743913f, + -0.001754165f, -0.001764417f, -0.001774490f, -0.001784563f, -0.001794696f, + -0.001804650f, -0.001814663f, -0.001824498f, -0.001834452f, -0.001844168f, + -0.001854002f, -0.001863778f, -0.001873314f, -0.001883030f, -0.001892567f, + -0.001902103f, -0.001911521f, -0.001920938f, -0.001930356f, -0.001939654f, + -0.001948893f, -0.001958191f, -0.001967311f, -0.001976430f, -0.001985550f, + -0.001994491f, -0.002003491f, -0.002012312f, -0.002021313f, -0.002030015f, + -0.002038717f, -0.002047479f, -0.002056181f, -0.002064645f, -0.002073288f, + -0.002081692f, -0.002090156f, -0.002098501f, -0.002106905f, -0.002115071f, + -0.002123356f, -0.002131462f, -0.002139568f, -0.002147555f, -0.002155662f, + -0.002163529f, -0.002171457f, -0.002179205f, -0.002187014f, -0.002194703f, + -0.002202272f, -0.002209961f, -0.002217531f, -0.002224922f, -0.002232373f, + -0.002239764f, -0.002247095f, -0.002254248f, -0.002261519f, -0.002268672f, + -0.002275705f, -0.002282679f, -0.002289712f, -0.002296627f, -0.002303362f, + -0.002310216f, -0.002316952f, -0.002323568f, -0.002330244f, -0.002336800f, + -0.002343237f, -0.002349675f, -0.002356052f, -0.002362311f, -0.002368629f, + -0.002374828f, -0.002380908f, -0.002386987f, -0.002392948f, -0.002398968f, + -0.002404809f, -0.002410650f, -0.002416372f, -0.002422094f, -0.002427757f, + -0.002433360f, -0.002438903f, -0.002444327f, -0.002449691f, -0.002455056f, + -0.002460301f, -0.002465487f, -0.002470732f, -0.002475739f, -0.002480865f, + -0.002485693f, -0.002490699f, -0.002495527f, -0.002500176f, -0.002505064f, + -0.002509654f, -0.002514243f, -0.002518773f, -0.002523303f, -0.002527595f, + -0.002531946f, -0.002536356f, -0.002540410f, -0.002544582f, -0.002548754f, + -0.002552748f, -0.002556741f, -0.002560616f, -0.002564371f, -0.002568305f, + -0.002571881f, -0.002575636f, -0.002579153f, -0.002582669f, -0.002586126f, + -0.002589583f, -0.002592862f, -0.002596140f, -0.002599359f, -0.002602518f, + -0.002605557f, -0.002608538f, -0.002611578f, -0.002614439f, -0.002617240f, + -0.002620041f, -0.002622724f, -0.002625346f, -0.002627909f, -0.002630413f, + -0.002632916f, -0.002635241f, -0.002637565f, -0.002639830f, -0.002642035f, + -0.002644122f, -0.002646267f, -0.002648175f, -0.002650142f, -0.002652109f, + -0.002653837f, -0.002655566f, -0.002657294f, -0.002658904f, -0.002660453f, + -0.002662003f, -0.002663374f, -0.002664745f, -0.002666116f, -0.002667189f, + -0.002668560f, -0.002669632f, -0.002670705f, -0.002671599f, -0.002672642f, + -0.002673417f, -0.002674311f, -0.002675056f, -0.002675682f, -0.002676308f, + -0.002676874f, -0.002677381f, -0.002677768f, -0.002678156f, -0.002678514f, + -0.002678722f, -0.002678931f, -0.002679020f, -0.002679110f, -0.002679020f, + -0.002679050f, -0.002678901f, -0.002678722f, -0.002678484f, -0.002678186f, + -0.002677828f, -0.002677292f, -0.002676904f, -0.002676338f, -0.002675682f, + -0.002675027f, -0.002674311f, -0.002673507f, -0.002672672f, -0.002671778f, + -0.002670765f, -0.002669752f, -0.002668649f, -0.002667487f, -0.002666295f, + -0.002665013f, -0.002663702f, -0.002662301f, -0.002660841f, -0.002659231f, + -0.002657771f, -0.002656132f, -0.002654433f, -0.002652735f, -0.002650917f, + -0.002649069f, -0.002647102f, -0.002645165f, -0.002643138f, -0.002641022f, + -0.002638906f, -0.002636671f, -0.002634317f, -0.002632141f, -0.002629727f, + -0.002627254f, -0.002624840f, -0.002622217f, -0.002619684f, -0.002616972f, + -0.002614290f, -0.002611518f, -0.002608687f, -0.002605796f, -0.002602875f, + -0.002599895f, -0.002596736f, -0.002593726f, -0.002590597f, -0.002587378f, + -0.002584100f, -0.002580822f, -0.002577394f, -0.002574027f, -0.002570510f, + -0.002566963f, -0.002563447f, -0.002559751f, -0.002556056f, -0.002552360f, + -0.002548456f, -0.002544701f, -0.002540767f, -0.002536893f, -0.002532810f, + -0.002528816f, -0.002524704f, -0.002520531f, -0.002516329f, -0.002512068f, + -0.002507776f, -0.002503395f, -0.002499044f, -0.002494544f, -0.002489939f, + -0.002485529f, -0.002480894f, -0.002476230f, -0.002471551f, -0.002466798f, + -0.002461985f, -0.002457172f, -0.002452269f, -0.002447322f, -0.002442330f, + -0.002437294f, -0.002432242f, -0.002427101f, -0.002421811f, -0.002416730f, + -0.002411440f, -0.002406135f, -0.002400786f, -0.002395362f, -0.002389938f, + -0.002384409f, -0.002378926f, -0.002373338f, -0.002367705f, -0.002362043f, + -0.002356306f, -0.002350554f, -0.002344713f, -0.002338931f, -0.002333075f, + -0.002327129f, -0.002321184f, -0.002315164f, -0.002309129f, -0.002303004f, + -0.002296925f, -0.002290726f, -0.002284512f, -0.002278253f, -0.002271980f, + -0.002265558f, -0.002259284f, -0.002252862f, -0.002246410f, -0.002239943f, + -0.002233401f, -0.002226844f, -0.002220228f, -0.002213612f, -0.002206936f, + -0.002200201f, -0.002193481f, -0.002186671f, -0.002179854f, -0.002172925f, + -0.002166122f, -0.002159171f, -0.002152205f, -0.002145231f, -0.002138190f, + -0.002131112f, -0.002124026f, -0.002116874f, -0.002109714f, -0.002102517f, + -0.002095275f, -0.002088003f, -0.002080709f, -0.002073303f, -0.002066024f, + -0.002058625f, -0.002051190f, -0.002043739f, -0.002036251f, -0.002028733f, + -0.002021186f, -0.002013609f, -0.002006002f, -0.001998372f, -0.001990698f, + -0.001983009f, -0.001975283f, -0.001967464f, -0.001959760f, -0.001951948f, + -0.001944117f, -0.001936268f, -0.001928370f, -0.001920462f, -0.001912523f, + -0.001904562f, -0.001896568f, -0.001888555f, -0.001880515f, -0.001872454f, + -0.001864363f, -0.001856182f, -0.001848117f, -0.001839954f, -0.001831776f, + -0.001823569f, -0.001815341f, -0.001807092f, -0.001798820f, -0.001790524f, + -0.001782209f, -0.001773877f, -0.001765518f, -0.001757140f, -0.001748742f, + -0.001740261f, -0.001731890f, -0.001723433f, -0.001714959f, -0.001706466f, + -0.001697953f, -0.001689423f, -0.001680876f, -0.001672311f, -0.001663728f, + -0.001655128f, -0.001646512f, -0.001637880f, -0.001629170f, -0.001620566f, + -0.001611889f, -0.001603196f, -0.001594484f, -0.001585761f, -0.001577025f, + -0.001568271f, -0.001559505f, -0.001550728f, -0.001541931f, -0.001533132f, + -0.001524314f, -0.001515483f, -0.001506586f, -0.001497786f, -0.001488928f, + -0.001480050f, -0.001471169f, -0.001462270f, -0.001453366f, -0.001444448f, + -0.001435522f, -0.001426589f, -0.001417641f, -0.001408692f, -0.001399733f, + -0.001390763f, -0.001381733f, -0.001372803f, -0.001363818f, -0.001354810f, + -0.001345813f, -0.001336802f, -0.001327783f, -0.001318768f, -0.001309730f, + -0.001300700f, -0.001291670f, -0.001282625f, -0.001273572f, -0.001264527f, + -0.001255415f, -0.001246415f, -0.001237355f, -0.001228295f, -0.001219213f, + -0.001210161f, -0.001201086f, -0.001192011f, -0.001182951f, -0.001173854f, + -0.001164794f, -0.001155719f, -0.001146644f, -0.001137555f, -0.001128443f, + -0.001119412f, -0.001110330f, -0.001101270f, -0.001092196f, -0.001083128f, + -0.001074038f, -0.001065001f, -0.001055919f, -0.001046866f, -0.001037806f, + -0.001028746f, -0.001019694f, -0.001010656f, -0.001001567f, -0.000992566f, + -0.000983544f, -0.000974506f, -0.000965491f, -0.000956468f, -0.000947453f, + -0.000938453f, -0.000929438f, -0.000920445f, -0.000911482f, -0.000902474f, + -0.000893541f, -0.000884496f, -0.000875585f, -0.000866644f, -0.000857703f, + -0.000848778f, -0.000839837f, -0.000830933f, -0.000822030f, -0.000813127f, + -0.000804260f, -0.000795372f, -0.000786506f, -0.000777654f, -0.000768811f, + -0.000759944f, -0.000751153f, -0.000742361f, -0.000733539f, -0.000724763f, + -0.000716001f, -0.000707224f, -0.000698492f, -0.000689745f, -0.000681043f, + -0.000672325f, -0.000663623f, -0.000654951f, -0.000646278f, -0.000637606f, + -0.000628993f, -0.000620380f, -0.000611767f, -0.000603199f, -0.000594586f, + -0.000586048f, -0.000577524f, -0.000568971f, -0.000560462f, -0.000551969f, + -0.000543505f, -0.000535041f, -0.000526607f, -0.000518143f, -0.000509769f, + -0.000501379f, -0.000493005f, -0.000484675f, -0.000476316f, -0.000468016f, + -0.000459731f, -0.000451431f, -0.000443190f, -0.000434965f, -0.000426725f, + -0.000418544f, -0.000410378f, -0.000402227f, -0.000394091f, -0.000385970f, + -0.000377893f, -0.000369802f, -0.000361770f, -0.000353739f, -0.000345752f, + -0.000337750f, -0.000329792f, -0.000321865f, -0.000313938f, -0.000306055f, + -0.000298187f, -0.000290349f, -0.000282511f, -0.000274733f, -0.000266939f, + -0.000259221f, -0.000251472f, -0.000243768f, -0.000236079f, -0.000228450f, + -0.000220820f, -0.000213221f, -0.000205651f, -0.000198096f, -0.000190571f, + -0.000183061f, -0.000175595f, -0.000168160f, -0.000160739f, -0.000153318f, + -0.000145987f, -0.000138611f, -0.000131324f, -0.000124037f, -0.000116780f, + -0.000109524f, -0.000102326f, -0.000095159f, -0.000088021f, -0.000080869f, + -0.000073805f, -0.000066742f, -0.000059679f, -0.000052691f, -0.000045687f, + -0.000038758f, -0.000031844f, -0.000024930f, -0.000018090f, -0.000011265f, + -0.000004441f, 0.000002325f, 0.000009075f, 0.000015780f, 0.000022471f, + 0.000029117f, 0.000035763f, 0.000042319f, 0.000048906f, 0.000055432f, + 0.000061929f, 0.000068396f, 0.000074849f, 0.000081256f, 0.000087619f, + 0.000093967f, 0.000100300f, 0.000106558f, 0.000112817f, 0.000119045f, + 0.000125214f, 0.000131369f, 0.000137508f, 0.000143588f, 0.000149652f, + 0.000155658f, 0.000161663f, 0.000167638f, 0.000173539f, 0.000179455f, + 0.000185296f, 0.000191167f, 0.000196919f, 0.000202700f, 0.000208423f, + 0.000214115f, 0.000219792f, 0.000225410f, 0.000231013f, 0.000236586f, + 0.000242084f, 0.000247598f, 0.000253052f, 0.000258476f, 0.000263870f, + 0.000269234f, 0.000274554f, 0.000279859f, 0.000285104f, 0.000290334f, + 0.000295490f, 0.000300661f, 0.000305787f, 0.000310853f, 0.000315934f, + 0.000320926f, 0.000325903f, 0.000330850f, 0.000335768f, 0.000340641f, + 0.000345469f, 0.000350282f, 0.000355050f, 0.000359803f, 0.000364468f, + 0.000369161f, 0.000373796f, 0.000378355f, 0.000382945f, 0.000387460f, + 0.000391930f, 0.000396401f, 0.000400826f, 0.000405192f, 0.000409558f, + 0.000413850f, 0.000418127f, 0.000422373f, 0.000426546f, 0.000430748f, + 0.000434861f, 0.000438988f, 0.000443041f, 0.000447050f, 0.000451058f, + 0.000455007f, 0.000458926f, 0.000462815f, 0.000466645f, 0.000470474f, + 0.000474244f, 0.000477999f, 0.000481665f, 0.000485376f, 0.000488982f, + 0.000492588f, 0.000496164f, 0.000499681f, 0.000503168f, 0.000506610f, + 0.000510037f, 0.000513420f, 0.000516787f, 0.000520080f, 0.000523359f, + 0.000526607f, 0.000529751f, 0.000532970f, 0.000536114f, 0.000539184f, + 0.000542283f, 0.000545278f, 0.000548288f, 0.000551224f, 0.000554159f, + 0.000557050f, 0.000559889f, 0.000562698f, 0.000565484f, 0.000568233f, + 0.000570931f, 0.000573598f, 0.000576250f, 0.000578851f, 0.000581399f, + 0.000583932f, 0.000586443f, 0.000588894f, 0.000591323f, 0.000593722f, + 0.000596076f, 0.000598386f, 0.000600673f, 0.000602946f, 0.000605099f, + 0.000607334f, 0.000609480f, 0.000611588f, 0.000613675f, 0.000615716f, + 0.000617720f, 0.000619695f, 0.000621639f, 0.000623547f, 0.000625424f, + 0.000627257f, 0.000629067f, 0.000630826f, 0.000632577f, 0.000634275f, + 0.000635937f, 0.000637576f, 0.000639170f, 0.000640750f, 0.000642270f, + 0.000643790f, 0.000645243f, 0.000646673f, 0.000648089f, 0.000649445f, + 0.000650786f, 0.000652038f, 0.000653364f, 0.000654578f, 0.000655793f, + 0.000656962f, 0.000658102f, 0.000659212f, 0.000660270f, 0.000661321f, + 0.000662334f, 0.000663288f, 0.000664257f, 0.000665158f, 0.000666037f, + 0.000666894f, 0.000667714f, 0.000668481f, 0.000669241f, 0.000669979f, + 0.000670649f, 0.000671312f, 0.000671953f, 0.000672549f, 0.000673100f, + 0.000673652f, 0.000674143f, 0.000674628f, 0.000675075f, 0.000675432f, + 0.000675865f, 0.000676215f, 0.000676543f, 0.000676841f, 0.000677086f, + 0.000677340f, 0.000677533f, 0.000677712f, 0.000677854f, 0.000677958f, + 0.000678062f, 0.000678115f, 0.000678137f, 0.000678144f, 0.000678107f, + 0.000678040f, 0.000677980f, 0.000677846f, 0.000677705f, 0.000677541f, + 0.000677332f, 0.000677109f, 0.000676855f, 0.000676572f, 0.000676263f, + 0.000675920f, 0.000675563f, 0.000675112f, 0.000674754f, 0.000674292f, + 0.000673834f, 0.000673324f, 0.000672799f, 0.000672262f, 0.000671666f, + 0.000671066f, 0.000670440f, 0.000669774f, 0.000669103f, 0.000668388f, + 0.000667654f, 0.000666898f, 0.000666108f, 0.000665307f, 0.000664469f, + 0.000663612f, 0.000662729f, 0.000661820f, 0.000660881f, 0.000659931f, + 0.000658948f, 0.000657942f, 0.000656914f, 0.000655863f, 0.000654746f, + 0.000653688f, 0.000652563f, 0.000651423f, 0.000650249f, 0.000649061f, + 0.000647850f, 0.000646606f, 0.000645354f, 0.000644065f, 0.000642769f, + 0.000641439f, 0.000640094f, 0.000638723f, 0.000637334f, 0.000635926f, + 0.000634488f, 0.000633033f, 0.000631562f, 0.000630064f, 0.000628548f, + 0.000627011f, 0.000625454f, 0.000623874f, 0.000622276f, 0.000620661f, + 0.000619022f, 0.000617364f, 0.000615645f, 0.000613993f, 0.000612279f, + 0.000610547f, 0.000608791f, 0.000607023f, 0.000605229f, 0.000603424f, + 0.000601593f, 0.000599753f, 0.000597889f, 0.000596011f, 0.000594109f, + 0.000592194f, 0.000590262f, 0.000588313f, 0.000586346f, 0.000584361f, + 0.000582362f, 0.000580344f, 0.000578311f, 0.000576260f, 0.000574195f, + 0.000572114f, 0.000570015f, 0.000567904f, 0.000565774f, 0.000563630f, + 0.000561428f, 0.000559297f, 0.000557108f, 0.000554904f, 0.000552687f, + 0.000550454f, 0.000548207f, 0.000545946f, 0.000543671f, 0.000541383f, + 0.000539081f, 0.000536765f, 0.000534437f, 0.000532095f, 0.000529740f, + 0.000527372f, 0.000524992f, 0.000522598f, 0.000520193f, 0.000517776f, + 0.000515345f, 0.000512904f, 0.000510451f, 0.000507986f, 0.000505510f, + 0.000503022f, 0.000500523f, 0.000497975f, 0.000495494f, 0.000492963f, + 0.000490420f, 0.000487870f, 0.000485308f, 0.000482734f, 0.000480153f, + 0.000477560f, 0.000474961f, 0.000472347f, 0.000469729f, 0.000467099f, + 0.000464460f, 0.000461814f, 0.000459160f, 0.000456492f, 0.000453821f, + 0.000451141f, 0.000448450f, 0.000445757f, 0.000443047f, 0.000440339f, + 0.000437619f, 0.000434890f, 0.000432156f, 0.000429420f, 0.000426665f, + 0.000423878f, 0.000421155f, 0.000418384f, 0.000415608f, 0.000412831f, + 0.000410046f, 0.000407251f, 0.000404453f, 0.000401655f, 0.000398841f, + 0.000396032f, 0.000393212f, 0.000390388f, 0.000387559f, 0.000384722f, + 0.000381887f, 0.000379046f, 0.000376200f, 0.000373350f, 0.000370493f, + 0.000367636f, 0.000364775f, 0.000361912f, 0.000359036f, 0.000356171f, + 0.000353293f, 0.000350416f, 0.000347532f, 0.000344623f, 0.000341764f, + 0.000338878f, 0.000335984f, 0.000333097f, 0.000330199f, 0.000327300f, + 0.000324406f, 0.000321500f, 0.000318602f, 0.000315700f, 0.000312794f, + 0.000309892f, 0.000306983f, 0.000304081f, 0.000301171f, 0.000298265f, + 0.000295352f, 0.000292446f, 0.000289541f, 0.000286628f, 0.000283718f, + 0.000280812f, 0.000277914f, 0.000274993f, 0.000272095f, 0.000269186f, + 0.000266258f, 0.000263374f, 0.000260476f, 0.000257570f, 0.000254679f, + 0.000251777f, 0.000248875f, 0.000245985f, 0.000243090f, 0.000240199f, + 0.000237312f, 0.000234425f, 0.000231542f, 0.000228655f, 0.000225779f, + 0.000222903f, 0.000220031f, 0.000217155f, 0.000214294f, 0.000211425f, + 0.000208564f, 0.000205707f, 0.000202853f, 0.000200007f, 0.000197157f, + 0.000194311f, 0.000191480f, 0.000188638f, 0.000185791f, 0.000182983f, + 0.000180162f, 0.000177346f, 0.000174530f, 0.000171725f, 0.000168923f, + 0.000166126f, 0.000163332f, 0.000160541f, 0.000157762f, 0.000154987f, + 0.000152212f, 0.000149447f, 0.000146687f, 0.000143930f, 0.000141181f, + 0.000138439f, 0.000135705f, 0.000132974f, 0.000130247f, 0.000127535f, + 0.000124816f, 0.000122119f, 0.000119418f, 0.000116725f, 0.000114042f, + 0.000111364f, 0.000108674f, 0.000106033f, 0.000103373f, 0.000100728f, + 0.000098083f, 0.000095449f, 0.000092819f, 0.000090208f, 0.000087593f, + 0.000084992f, 0.000082392f, 0.000079807f, 0.000077233f, 0.000074655f, + 0.000072096f, 0.000069536f, 0.000066992f, 0.000064459f, 0.000061929f, + 0.000059403f, 0.000056893f, 0.000054389f, 0.000051897f, 0.000049412f, + 0.000046935f, 0.000044469f, 0.000042010f, 0.000039551f, 0.000037123f, + 0.000034694f, 0.000032268f, 0.000029862f, 0.000027459f, 0.000025064f, + 0.000022691f, 0.000020307f, 0.000017952f, 0.000015602f, 0.000013247f, + 0.000010934f, 0.000008594f, 0.000006288f, 0.000003986f, 0.000001695f, + -0.000000589f, -0.000002854f, -0.000005119f, -0.000007369f, -0.000009615f, + -0.000011832f, -0.000014052f, -0.000016265f, -0.000018459f, -0.000020642f, + -0.000022821f, -0.000024986f, -0.000027131f, -0.000029277f, -0.000031408f, + -0.000033524f, -0.000035629f, -0.000037737f, -0.000039808f, -0.000041891f, + -0.000043951f, -0.000046007f, -0.000048041f, -0.000050064f, -0.000052094f, + -0.000054091f, -0.000056084f, -0.000058070f, -0.000060037f, -0.000061993f, + -0.000063941f, -0.000065874f, -0.000067800f, -0.000069708f, -0.000071604f, + -0.000073489f, -0.000075370f, -0.000077229f, -0.000079080f, -0.000080917f, + -0.000082746f, -0.000084557f, -0.000086352f, -0.000088152f, -0.000089929f, + -0.000091687f, -0.000093438f, -0.000095177f, -0.000096913f, -0.000098623f, + -0.000100322f, -0.000102021f, -0.000103690f, -0.000105359f, -0.000107009f, + -0.000108648f, -0.000110280f, -0.000111893f, -0.000113495f, -0.000115078f, + -0.000116657f, -0.000118230f, -0.000119772f, -0.000121318f, -0.000122838f, + -0.000124350f, -0.000125848f, -0.000127345f, -0.000128813f, -0.000130277f, + -0.000131730f, -0.000133157f, -0.000134595f, -0.000135988f, -0.000137400f, + -0.000138778f, -0.000140157f, -0.000141505f, -0.000142857f, -0.000144191f, + -0.000145517f, -0.000146817f, -0.000148114f, -0.000149388f, -0.000150666f, + -0.000151921f, -0.000153165f, -0.000154395f, -0.000155609f, -0.000156820f, + -0.000158004f, -0.000159189f, -0.000160355f, -0.000161506f, -0.000162646f, + -0.000163775f, -0.000164881f, -0.000165988f, -0.000167083f, -0.000168145f, + -0.000169218f, -0.000170264f, -0.000171307f, -0.000172324f, -0.000173341f, + -0.000174336f, -0.000175327f, -0.000176292f, -0.000177257f, -0.000178207f, + -0.000179138f, -0.000180058f, -0.000180975f, -0.000181865f, -0.000182752f, + -0.000183623f, -0.000184480f, -0.000185326f, -0.000186164f, -0.000186980f, + -0.000187792f, -0.000188582f, -0.000189368f, -0.000190143f, -0.000190891f, + -0.000191648f, -0.000192374f, -0.000193097f, -0.000193801f, -0.000194505f, + -0.000195183f, -0.000195853f, -0.000196513f, -0.000197157f, -0.000197794f, + -0.000198420f, -0.000199001f, -0.000199623f, -0.000200208f, -0.000200782f, + -0.000201344f, -0.000201892f, -0.000202429f, -0.000202954f, -0.000203468f, + -0.000203967f, -0.000204455f, -0.000204936f, -0.000205394f, -0.000205856f, + -0.000206295f, -0.000206724f, -0.000207141f, -0.000207547f, -0.000207946f, + -0.000208326f, -0.000208698f, -0.000209058f, -0.000209408f, -0.000209745f, + -0.000210065f, -0.000210386f, -0.000210684f, -0.000210978f, -0.000211256f, + -0.000211528f, -0.000211783f, -0.000212030f, -0.000212263f, -0.000212491f, + -0.000212703f, -0.000212908f, -0.000213092f, -0.000213277f, -0.000213446f, + -0.000213604f, -0.000213752f, -0.000213886f, -0.000214016f, -0.000214130f, + -0.000214234f, -0.000214327f, -0.000214415f, -0.000214487f, -0.000214545f, + -0.000214605f, -0.000214642f, -0.000214674f, -0.000214696f, -0.000214709f, + -0.000214707f, -0.000214674f, -0.000214679f, -0.000214649f, -0.000214612f, + -0.000214560f, -0.000214502f, -0.000214435f, -0.000214357f, -0.000214268f, + -0.000214169f, -0.000214059f, -0.000213947f, -0.000213819f, -0.000213677f, + -0.000213537f, -0.000213381f, -0.000213215f, -0.000213042f, -0.000212861f, + -0.000212666f, -0.000212466f, -0.000212256f, -0.000212036f, -0.000211809f, + -0.000211569f, -0.000211326f, -0.000211067f, -0.000210807f, -0.000210535f, + -0.000210257f, -0.000209961f, -0.000209667f, -0.000209359f, -0.000209045f, + -0.000208722f, -0.000208389f, -0.000208050f, -0.000207704f, -0.000207344f, + -0.000206983f, -0.000206610f, -0.000206229f, -0.000205842f, -0.000205445f, + -0.000205044f, -0.000204630f, -0.000204211f, -0.000203785f, -0.000203351f, + -0.000202909f, -0.000202459f, -0.000202003f, -0.000201537f, -0.000201069f, + -0.000200586f, -0.000200078f, -0.000199611f, -0.000199108f, -0.000198605f, + -0.000198090f, -0.000197569f, -0.000197043f, -0.000196506f, -0.000195967f, + -0.000195420f, -0.000194865f, -0.000194305f, -0.000193738f, -0.000193163f, + -0.000192585f, -0.000191999f, -0.000191407f, -0.000190807f, -0.000190204f, + -0.000189591f, -0.000188977f, -0.000188354f, -0.000187725f, -0.000187092f, + -0.000186451f, -0.000185805f, -0.000185154f, -0.000184498f, -0.000183835f, + -0.000183167f, -0.000182495f, -0.000181816f, -0.000181132f, -0.000180443f, + -0.000179750f, -0.000179050f, -0.000178346f, -0.000177636f, -0.000176923f, + -0.000176203f, -0.000175480f, -0.000174752f, -0.000174019f, -0.000173280f, + -0.000172539f, -0.000171792f, -0.000171040f, -0.000170285f, -0.000169525f, + -0.000168761f, -0.000167992f, -0.000167220f, -0.000166443f, -0.000165662f, + -0.000164878f, -0.000164090f, -0.000163272f, -0.000162501f, -0.000161701f, + -0.000160898f, -0.000160091f, -0.000159280f, -0.000158466f, -0.000157648f, + -0.000156827f, -0.000156003f, -0.000155175f, -0.000154344f, -0.000153510f, + -0.000152673f, -0.000151833f, -0.000150990f, -0.000150144f, -0.000149295f, + -0.000148444f, -0.000147589f, -0.000146732f, -0.000145872f, -0.000145010f, + -0.000144145f, -0.000143277f, -0.000142408f, -0.000141536f, -0.000140661f, + -0.000139785f, -0.000138906f, -0.000138025f, -0.000137142f, -0.000136257f, + -0.000135370f, -0.000134481f, -0.000133590f, -0.000132697f, -0.000131803f, + -0.000130907f, -0.000130009f, -0.000129110f, -0.000128209f, -0.000127306f, + -0.000126403f, -0.000125497f, -0.000124591f, -0.000123683f, -0.000122774f, + -0.000121864f, -0.000120952f, -0.000120040f, -0.000119127f, -0.000118212f, + -0.000117297f, -0.000116381f, -0.000115445f, -0.000114546f, -0.000113628f, + -0.000112709f, -0.000111789f, -0.000110869f, -0.000109948f, -0.000109027f, + -0.000108106f, -0.000107184f, -0.000106262f, -0.000105340f, -0.000104415f, + -0.000103494f, -0.000102570f, -0.000101647f, -0.000100723f, -0.000099801f, + -0.000098877f, -0.000097955f, -0.000097031f, -0.000096109f, -0.000095187f, + -0.000094265f, -0.000093343f, -0.000092422f, -0.000091502f, -0.000090580f, + -0.000089660f, -0.000088741f, -0.000087823f, -0.000086904f, -0.000085988f, + -0.000085071f, -0.000084155f, -0.000083240f, -0.000082325f, -0.000081412f, + -0.000080500f, -0.000079590f, -0.000078678f, -0.000077770f, -0.000076862f, + -0.000075955f, -0.000075049f, -0.000074145f, -0.000073241f, -0.000072340f, + -0.000071440f, -0.000070541f, -0.000069643f, -0.000068747f, -0.000067852f, + -0.000066960f, -0.000066068f, -0.000065166f, -0.000064289f, -0.000063405f, + -0.000062519f, -0.000061636f, -0.000060757f, -0.000059876f, -0.000058998f, + -0.000058125f, -0.000057249f, -0.000056379f, -0.000055509f, -0.000054643f, + -0.000053776f, -0.000052913f, -0.000052053f, -0.000051194f, -0.000050337f, + -0.000049485f, -0.000048630f, -0.000047781f, -0.000046935f, -0.000046090f, + -0.000045246f, -0.000044407f, -0.000043570f, -0.000042734f, -0.000041903f, + -0.000041073f, -0.000040242f, -0.000039421f, -0.000038599f, -0.000037779f, + -0.000036962f, -0.000036148f, -0.000035339f, -0.000034529f, -0.000033723f, + -0.000032922f, -0.000032122f, -0.000031324f, -0.000030532f, -0.000029741f, + -0.000028951f, -0.000028169f, -0.000027386f, -0.000026607f, -0.000025833f, + -0.000025058f, -0.000024288f, -0.000023524f, -0.000022760f, -0.000022001f, + -0.000021243f, -0.000020491f, -0.000019740f, -0.000018986f, -0.000018249f, + -0.000017510f, -0.000016774f, -0.000016038f, -0.000015311f, -0.000014583f, + -0.000013859f, -0.000013139f, -0.000012424f, -0.000011712f, -0.000011003f, + -0.000010296f, -0.000009594f, -0.000008895f, -0.000008201f, -0.000007508f, + -0.000006821f, -0.000006137f, -0.000005458f, -0.000004780f, -0.000004107f, + -0.000003438f, -0.000002770f, -0.000002110f, -0.000001453f, -0.000000797f, + -0.000000146f, 0.000000501f, 0.000001144f, 0.000001782f, 0.000002420f, + 0.000003050f, 0.000003677f, 0.000004301f, 0.000004923f, 0.000005536f, + 0.000006150f, 0.000006758f, 0.000007361f, 0.000007963f, 0.000008560f, + 0.000009151f, 0.000009741f, 0.000010326f, 0.000010905f, 0.000011482f, + 0.000012054f, 0.000012624f, 0.000013188f, 0.000013747f, 0.000014306f, + 0.000014856f, 0.000015406f, 0.000015951f, 0.000016493f, 0.000017026f, + 0.000017560f, 0.000018085f, 0.000018612f, 0.000019130f, 0.000019647f, + 0.000020158f, 0.000020666f, 0.000021168f, 0.000021671f, 0.000022165f, + 0.000022653f, 0.000023143f, 0.000023624f, 0.000024104f, 0.000024579f, + 0.000025048f, 0.000025516f, 0.000025976f, 0.000026437f, 0.000026888f, + 0.000027340f, 0.000027785f, 0.000028226f, 0.000028664f, 0.000029097f, + 0.000029526f, 0.000029950f, 0.000030371f, 0.000030789f, 0.000031200f, + 0.000031610f, 0.000032012f, 0.000032413f, 0.000032808f, 0.000033202f, + 0.000033589f, 0.000033971f, 0.000034352f, 0.000034725f, 0.000035098f, + 0.000035464f, 0.000035828f, 0.000036187f, 0.000036540f, 0.000036892f, + 0.000037238f, 0.000037580f, 0.000037918f, 0.000038252f, 0.000038582f, + 0.000038907f, 0.000039231f, 0.000039549f, 0.000039860f, 0.000040172f, + 0.000040476f, 0.000040780f, 0.000041076f, 0.000041369f, 0.000041659f, + 0.000041946f, 0.000042226f, 0.000042504f, 0.000042778f, 0.000043048f, + 0.000043313f, 0.000043575f, 0.000043831f, 0.000044088f, 0.000044335f, + 0.000044581f, 0.000044825f, 0.000045061f, 0.000045295f, 0.000045526f, + 0.000045752f, 0.000045975f, 0.000046193f, 0.000046407f, 0.000046619f, + 0.000046826f, 0.000047030f, 0.000047228f, 0.000047424f, 0.000047616f, + 0.000047805f, 0.000047988f, 0.000048169f, 0.000048346f, 0.000048519f, + 0.000048689f, 0.000048853f, 0.000049016f, 0.000049174f, 0.000049329f, + 0.000049480f, 0.000049627f, 0.000049771f, 0.000049912f, 0.000050047f, + 0.000050181f, 0.000050310f, 0.000050437f, 0.000050558f, 0.000050677f, + 0.000050792f, 0.000050904f, 0.000051012f, 0.000051118f, 0.000051214f, + 0.000051316f, 0.000051410f, 0.000051503f, 0.000051589f, 0.000051674f, + 0.000051755f, 0.000051832f, 0.000051906f, 0.000051977f, 0.000052044f, + 0.000052109f, 0.000052171f, 0.000052229f, 0.000052283f, 0.000052333f, + 0.000052382f, 0.000052427f, 0.000052468f, 0.000052508f, 0.000052543f, + 0.000052574f, 0.000052604f, 0.000052631f, 0.000052653f, 0.000052674f, + 0.000052691f, 0.000052704f, 0.000052716f, 0.000052724f, 0.000052729f, + 0.000052730f, 0.000052730f, 0.000052726f, 0.000052720f, 0.000052710f, + 0.000052697f, 0.000052682f, 0.000052664f, 0.000052643f, 0.000052620f, + 0.000052593f, 0.000052564f, 0.000052531f, 0.000052498f, 0.000052460f, + 0.000052420f, 0.000052377f, 0.000052333f, 0.000052284f, 0.000052234f, + 0.000052180f, 0.000052125f, 0.000052067f, 0.000052006f, 0.000051938f, + 0.000051877f, 0.000051809f, 0.000051738f, 0.000051666f, 0.000051590f, + 0.000051512f, 0.000051432f, 0.000051349f, 0.000051265f, 0.000051177f, + 0.000051088f, 0.000050996f, 0.000050901f, 0.000050805f, 0.000050707f, + 0.000050606f, 0.000050503f, 0.000050398f, 0.000050291f, 0.000050182f, + 0.000050070f, 0.000049957f, 0.000049842f, 0.000049724f, 0.000049604f, + 0.000049483f, 0.000049358f, 0.000049234f, 0.000049105f, 0.000048977f, + 0.000048845f, 0.000048712f, 0.000048577f, 0.000048439f, 0.000048302f, + 0.000048161f, 0.000048019f, 0.000047874f, 0.000047728f, 0.000047581f, + 0.000047431f, 0.000047280f, 0.000047128f, 0.000046974f, 0.000046818f, + 0.000046660f, 0.000046501f, 0.000046341f, 0.000046178f, 0.000046015f, + 0.000045849f, 0.000045683f, 0.000045514f, 0.000045344f, 0.000045168f, + 0.000045001f, 0.000044827f, 0.000044652f, 0.000044475f, 0.000044297f, + 0.000044117f, 0.000043937f, 0.000043755f, 0.000043572f, 0.000043387f, + 0.000043201f, 0.000043015f, 0.000042827f, 0.000042638f, 0.000042447f, + 0.000042256f, 0.000042063f, 0.000041869f, 0.000041675f, 0.000041479f, + 0.000041282f, 0.000041084f, 0.000040885f, 0.000040685f, 0.000040484f, + 0.000040283f, 0.000040080f, 0.000039876f, 0.000039672f, 0.000039466f, + 0.000039260f, 0.000039053f, 0.000038845f, 0.000038636f, 0.000038427f, + 0.000038217f, 0.000038006f, 0.000037794f, 0.000037581f, 0.000037368f, + 0.000037155f, 0.000036940f, 0.000036725f, 0.000036509f, 0.000036293f, + 0.000036076f, 0.000035858f, 0.000035640f, 0.000035422f, 0.000035202f, + 0.000034983f, 0.000034763f, 0.000034542f, 0.000034321f, 0.000034100f, + 0.000033873f, 0.000033655f, 0.000033432f, 0.000033209f, 0.000032986f, + 0.000032762f, 0.000032538f, 0.000032313f, 0.000032089f, 0.000031864f, + 0.000031638f, 0.000031413f, 0.000031187f, 0.000030961f, 0.000030735f, + 0.000030508f, 0.000030282f, 0.000030055f, 0.000029828f, 0.000029601f, + 0.000029374f, 0.000029147f, 0.000028920f, 0.000028692f, 0.000028465f, + 0.000028237f, 0.000028010f, 0.000027782f, 0.000027555f, 0.000027328f, + 0.000027100f, 0.000026873f, 0.000026645f, 0.000026418f, 0.000026191f, + 0.000025964f, 0.000025737f, 0.000025510f, 0.000025283f, 0.000025057f, + 0.000024830f, 0.000024604f, 0.000024378f, 0.000024152f, 0.000023927f, + 0.000023702f, 0.000023476f, 0.000023252f, 0.000023027f, 0.000022803f, + 0.000022579f, 0.000022355f, 0.000022132f, 0.000021908f, 0.000021686f, + 0.000021460f, 0.000021241f, 0.000021020f, 0.000020798f, 0.000020578f, + 0.000020357f, 0.000020137f, 0.000019917f, 0.000019698f, 0.000019480f, + 0.000019261f, 0.000019044f, 0.000018826f, 0.000018609f, 0.000018393f, + 0.000018177f, 0.000017962f, 0.000017748f, 0.000017533f, 0.000017320f, + 0.000017107f, 0.000016894f, 0.000016682f, 0.000016471f, 0.000016260f, + 0.000016050f, 0.000015841f, 0.000015632f, 0.000015424f, 0.000015216f, + 0.000015009f, 0.000014803f, 0.000014597f, 0.000014393f, 0.000014188f, + 0.000013985f, 0.000013782f, 0.000013580f, 0.000013379f, 0.000013178f, + 0.000012978f, 0.000012779f, 0.000012581f, 0.000012383f, 0.000012186f, + 0.000011990f, 0.000011795f, 0.000011600f, 0.000011407f, 0.000011214f, + 0.000011022f, 0.000010830f, 0.000010640f, 0.000010450f, 0.000010262f, + 0.000010074f, 0.000009884f, 0.000009700f, 0.000009515f, 0.000009331f, + 0.000009147f, 0.000008964f, 0.000008782f, 0.000008601f, 0.000008421f, + 0.000008242f, 0.000008064f, 0.000007887f, 0.000007710f, 0.000007535f, + 0.000007360f, 0.000007186f, 0.000007014f, 0.000006842f, 0.000006671f, + 0.000006501f, 0.000006332f, 0.000006164f, 0.000005997f, 0.000005831f, + 0.000005667f, 0.000005502f, 0.000005339f, 0.000005177f, 0.000005016f, + 0.000004855f, 0.000004696f, 0.000004538f, 0.000004381f, 0.000004225f, + 0.000004070f, 0.000003916f, 0.000003763f, 0.000003610f, 0.000003459f, + 0.000003309f, 0.000003160f, 0.000003012f, 0.000002865f, 0.000002719f, + 0.000002574f, 0.000002430f, 0.000002287f, 0.000002146f, 0.000002005f, + 0.000001865f, 0.000001726f, 0.000001589f, 0.000001452f, 0.000001316f, + 0.000001182f, 0.000001047f, 0.000000916f, 0.000000785f, 0.000000654f, + 0.000000525f, 0.000000397f, 0.000000270f, 0.000000143f, 0.000000019f, + -0.000000106f, -0.000000228f, -0.000000351f, -0.000000471f, -0.000000591f, + -0.000000710f, -0.000000827f, -0.000000944f, -0.000001059f, -0.000001174f, + -0.000001287f, -0.000001399f, -0.000001511f, -0.000001621f, -0.000001730f, + -0.000001838f, -0.000001945f, -0.000002051f, -0.000002156f, -0.000002260f, + -0.000002363f, -0.000002465f, -0.000002565f, -0.000002665f, -0.000002763f, + -0.000002861f, -0.000002958f, -0.000003053f, -0.000003147f, -0.000003241f, + -0.000003333f, -0.000003424f, -0.000003514f, -0.000003604f, -0.000003692f, + -0.000003779f, -0.000003865f, -0.000003950f, -0.000004034f, -0.000004117f, + -0.000004199f, -0.000004280f, -0.000004360f, -0.000004439f, -0.000004517f, + -0.000004594f, -0.000004670f, -0.000004744f, -0.000004819f, -0.000004891f, + -0.000004963f, -0.000005034f, -0.000005104f, -0.000005173f, -0.000005240f, + -0.000005307f, -0.000005373f, -0.000005438f, -0.000005502f, -0.000005565f, + -0.000005627f, -0.000005688f, -0.000005748f, -0.000005807f, -0.000005866f, + -0.000005922f, -0.000005979f, -0.000006034f, -0.000006089f, -0.000006142f, + -0.000006194f, -0.000006246f, -0.000006297f, -0.000006346f, -0.000006395f, + -0.000006443f, -0.000006490f, -0.000006536f, -0.000006581f, -0.000006625f, + -0.000006668f, -0.000006711f, -0.000006752f, -0.000006793f, -0.000006833f, + -0.000006872f, -0.000006909f, -0.000006947f, -0.000006983f, -0.000007018f, + -0.000007053f, -0.000007086f, -0.000007119f, -0.000007151f, -0.000007183f, + -0.000007213f, -0.000007242f, -0.000007271f, -0.000007299f, -0.000007326f, + -0.000007352f, -0.000007377f, -0.000007402f, -0.000007426f, -0.000007449f, + -0.000007471f, -0.000007493f, -0.000007513f, -0.000007533f, -0.000007552f, + -0.000007570f, -0.000007588f, -0.000007605f, -0.000007621f, -0.000007636f, + -0.000007651f, -0.000007665f, -0.000007678f, -0.000007690f, -0.000007702f, + -0.000007713f, -0.000007723f, -0.000007733f, -0.000007742f, -0.000007750f, + -0.000007757f, -0.000007764f, -0.000007770f, -0.000007775f, -0.000007780f, + -0.000007784f, -0.000007788f, -0.000007791f, -0.000007793f, -0.000007794f, + -0.000007795f, -0.000007795f, -0.000007795f, -0.000007794f, -0.000007792f, + -0.000007790f, -0.000007787f, -0.000007784f, -0.000007780f, -0.000007775f, + -0.000007770f, -0.000007764f, -0.000007758f, -0.000007751f, -0.000007743f, + -0.000007735f, -0.000007726f, -0.000007717f, -0.000007708f, -0.000007698f, + -0.000007687f, -0.000007675f, -0.000007663f, -0.000007651f, -0.000007638f, + -0.000007625f, -0.000007611f, -0.000007597f, -0.000007582f, -0.000007567f, + -0.000007551f, -0.000007535f, -0.000007518f, -0.000007501f, -0.000007483f, + -0.000007465f, -0.000007446f, -0.000007427f, -0.000007408f, -0.000007388f, + -0.000007368f, -0.000007347f, -0.000007326f, -0.000007305f, -0.000007283f, + -0.000007261f, -0.000007238f, -0.000007215f, -0.000007191f, -0.000007168f, + -0.000007143f, -0.000007119f, -0.000007094f, -0.000007068f, -0.000007043f, + -0.000007017f, -0.000006991f, -0.000006964f, -0.000006937f, -0.000006909f, + -0.000006882f, -0.000006854f, -0.000006826f, -0.000006797f, -0.000006768f, + -0.000006739f, -0.000006710f, -0.000006680f, -0.000006650f, -0.000006620f, + -0.000006589f, -0.000006558f, -0.000006527f, -0.000006496f, -0.000006464f, + -0.000006432f, -0.000006400f, -0.000006368f, -0.000006336f, -0.000006303f, + -0.000006270f, -0.000006237f, -0.000006203f, -0.000006170f, -0.000006136f, + -0.000006102f, -0.000006068f, -0.000006033f, -0.000005999f, -0.000005964f, + -0.000005929f, -0.000005894f, -0.000005859f, -0.000005823f, -0.000005788f, + -0.000005752f, -0.000005716f, -0.000005680f, -0.000005644f, -0.000005608f, + -0.000005571f, -0.000005535f, -0.000005498f, -0.000005461f, -0.000005424f, + -0.000005388f, -0.000005350f, -0.000005313f, -0.000005276f, -0.000005239f, + -0.000005201f, -0.000005164f, -0.000005126f, -0.000005088f, -0.000005051f, + -0.000005013f, -0.000004975f, -0.000004937f, -0.000004899f, -0.000004861f, + -0.000004823f, -0.000004784f, -0.000004746f, -0.000004708f, -0.000004670f, + -0.000004632f, -0.000004593f, -0.000004555f, -0.000004517f, -0.000004478f, + -0.000004440f, -0.000004401f, -0.000004363f, -0.000004324f, -0.000004286f, + -0.000004248f, -0.000004210f, -0.000004171f, -0.000004133f, -0.000004095f, + -0.000004056f, -0.000004018f, -0.000003980f, -0.000003942f, -0.000003904f, + -0.000003865f, -0.000003827f, -0.000003789f, -0.000003751f, -0.000003714f, + -0.000003676f, -0.000003638f, -0.000003600f, -0.000003562f, -0.000003525f, + -0.000003487f, -0.000003450f, -0.000003412f, -0.000003375f, -0.000003338f, + -0.000003301f, -0.000003264f, -0.000003227f, -0.000003190f, -0.000003153f, + -0.000003117f, -0.000003080f, -0.000003044f, -0.000003007f, -0.000002971f, + -0.000002935f, -0.000002899f, -0.000002863f, -0.000002827f, -0.000002791f, + -0.000002756f, -0.000002720f, -0.000002685f, -0.000002650f, -0.000002615f, + -0.000002580f, -0.000002545f, -0.000002511f, -0.000002476f, -0.000002442f, + -0.000002408f, -0.000002373f, -0.000002340f, -0.000002306f, -0.000002272f, + -0.000002239f, -0.000002205f, -0.000002172f, -0.000002139f, -0.000002106f, + -0.000002074f, -0.000002041f, -0.000002009f, -0.000001977f, -0.000001945f, + -0.000001913f, -0.000001881f, -0.000001850f, -0.000001818f, -0.000001787f, + -0.000001756f, -0.000001726f, -0.000001695f, -0.000001665f, -0.000001634f, + -0.000001604f, -0.000001574f, -0.000001545f, -0.000001515f, -0.000001486f, + -0.000001457f, -0.000001428f, -0.000001399f, -0.000001371f, -0.000001342f, + -0.000001314f, -0.000001286f, -0.000001258f, -0.000001231f, -0.000001203f, + -0.000001176f, -0.000001149f, -0.000001123f, -0.000001096f, -0.000001070f, + 0.000000000f +}; + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/audio/SDL_audiocvt.c b/SDL2-2.30.5/src/audio/SDL_audiocvt.c new file mode 100644 index 0000000..9087317 --- /dev/null +++ b/SDL2-2.30.5/src/audio/SDL_audiocvt.c @@ -0,0 +1,1429 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +/* Functions for audio drivers to perform runtime conversion of audio format */ + +#include "SDL.h" +#include "SDL_audio.h" +#include "SDL_audio_c.h" + +#include "SDL_loadso.h" +#include "../SDL_dataqueue.h" +#include "SDL_cpuinfo.h" + +#define DEBUG_AUDIOSTREAM 0 + +#ifdef __ARM_NEON +#define HAVE_NEON_INTRINSICS 1 +#endif + +#ifdef __SSE__ +#define HAVE_SSE_INTRINSICS 1 +#endif + +#ifdef __SSE3__ +#define HAVE_SSE3_INTRINSICS 1 +#endif + +#if defined(HAVE_IMMINTRIN_H) && !defined(SDL_DISABLE_IMMINTRIN_H) +#define HAVE_AVX_INTRINSICS 1 +#endif +#if defined __clang__ +#if (!__has_attribute(target)) +#undef HAVE_AVX_INTRINSICS +#endif +#if (defined(_MSC_VER) || defined(__SCE__)) && !defined(__AVX__) +#undef HAVE_AVX_INTRINSICS +#endif +#elif defined __GNUC__ +#if (__GNUC__ < 4) || (__GNUC__ == 4 && __GNUC_MINOR__ < 9) +#undef HAVE_AVX_INTRINSICS +#endif +#endif + +/* + * CHANNEL LAYOUTS AS SDL EXPECTS THEM: + * + * (Even if the platform expects something else later, that + * SDL will swizzle between the app and the platform). + * + * Abbreviations: + * - FRONT=single mono speaker + * - FL=front left speaker + * - FR=front right speaker + * - FC=front center speaker + * - BL=back left speaker + * - BR=back right speaker + * - SR=surround right speaker + * - SL=surround left speaker + * - BC=back center speaker + * - LFE=low-frequency speaker + * + * These are listed in the order they are laid out in + * memory, so "FL+FR" means "the front left speaker is + * layed out in memory first, then the front right, then + * it repeats for the next audio frame". + * + * 1 channel (mono) layout: FRONT + * 2 channels (stereo) layout: FL+FR + * 3 channels (2.1) layout: FL+FR+LFE + * 4 channels (quad) layout: FL+FR+BL+BR + * 5 channels (4.1) layout: FL+FR+LFE+BL+BR + * 6 channels (5.1) layout: FL+FR+FC+LFE+BL+BR + * 7 channels (6.1) layout: FL+FR+FC+LFE+BC+SL+SR + * 8 channels (7.1) layout: FL+FR+FC+LFE+BL+BR+SL+SR + */ + +#ifdef HAVE_SSE3_INTRINSICS +/* Convert from stereo to mono. Average left and right. */ +static void SDLCALL SDL_ConvertStereoToMono_SSE3(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + const __m128 divby2 = _mm_set1_ps(0.5f); + float *dst = (float *)cvt->buf; + const float *src = dst; + int i = cvt->len_cvt / 8; + + LOG_DEBUG_CONVERT("stereo", "mono (using SSE3)"); + SDL_assert(format == AUDIO_F32SYS); + + /* Do SSE blocks as long as we have 16 bytes available. + Just use unaligned load/stores, if the memory at runtime is + aligned it'll be just as fast on modern processors */ + while (i >= 4) { /* 4 * float32 */ + _mm_storeu_ps(dst, _mm_mul_ps(_mm_hadd_ps(_mm_loadu_ps(src), _mm_loadu_ps(src + 4)), divby2)); + i -= 4; + src += 8; + dst += 4; + } + + /* Finish off any leftovers with scalar operations. */ + while (i) { + *dst = (src[0] + src[1]) * 0.5f; + dst++; + i--; + src += 2; + } + + cvt->len_cvt /= 2; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} +#endif + +#ifdef HAVE_SSE_INTRINSICS +/* Convert from mono to stereo. Duplicate to stereo left and right. */ +static void SDLCALL SDL_ConvertMonoToStereo_SSE(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + float *dst = ((float *)(cvt->buf + (cvt->len_cvt * 2))) - 8; + const float *src = ((const float *)(cvt->buf + cvt->len_cvt)) - 4; + int i = cvt->len_cvt / sizeof(float); + + LOG_DEBUG_CONVERT("mono", "stereo (using SSE)"); + SDL_assert(format == AUDIO_F32SYS); + + /* Do SSE blocks as long as we have 16 bytes available. + Just use unaligned load/stores, if the memory at runtime is + aligned it'll be just as fast on modern processors */ + /* convert backwards, since output is growing in-place. */ + while (i >= 4) { /* 4 * float32 */ + const __m128 input = _mm_loadu_ps(src); /* A B C D */ + _mm_storeu_ps(dst, _mm_unpacklo_ps(input, input)); /* A A B B */ + _mm_storeu_ps(dst + 4, _mm_unpackhi_ps(input, input)); /* C C D D */ + i -= 4; + src -= 4; + dst -= 8; + } + + /* Finish off any leftovers with scalar operations. */ + src += 3; + dst += 6; /* adjust for smaller buffers. */ + while (i) { /* convert backwards, since output is growing in-place. */ + const float srcFC = src[0]; + dst[1] /* FR */ = srcFC; + dst[0] /* FL */ = srcFC; + i--; + src--; + dst -= 2; + } + + cvt->len_cvt *= 2; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} +#endif + +/* Include the autogenerated channel converters... */ +#include "SDL_audio_channel_converters.h" + +/* SDL's resampler uses a "bandlimited interpolation" algorithm: + https://ccrma.stanford.edu/~jos/resample/ */ + +#include "SDL_audio_resampler_filter.h" + +static Sint32 ResamplerPadding(const Sint32 inrate, const Sint32 outrate) +{ + /* This function uses integer arithmetics to avoid precision loss caused + * by large floating point numbers. Sint32 is needed for the large number + * multiplication. The integers are assumed to be non-negative so that + * division rounds by truncation. */ + if (inrate == outrate) { + return 0; + } + if (inrate > outrate) { + return (RESAMPLER_SAMPLES_PER_ZERO_CROSSING * inrate + outrate - 1) / 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, + const float *lpadding, const float *rpadding, + const float *inbuf, const int inbuflen, + float *outbuf, const int outbuflen) +{ + /* This function uses integer arithmetics to avoid precision loss caused + * by large floating point numbers. For some operations, Sint32 or Sint64 + * are needed for the large number multiplications. The input integers are + * assumed to be non-negative so that division rounds by truncation and + * modulo is always non-negative. Note that the operator order is important + * for these integer divisions. */ + const int paddinglen = ResamplerPadding(inrate, outrate); + const int framelen = chans * (int)sizeof(float); + const int inframes = inbuflen / framelen; + /* outbuflen isn't total to write, it's total available. */ + const int wantedoutframes = (int)((Sint64)inframes * outrate / inrate); + const int maxoutframes = outbuflen / framelen; + const int outframes = SDL_min(wantedoutframes, maxoutframes); + float *dst = outbuf; + int i, j, chan; + + for (i = 0; i < outframes; i++) { + const int srcindex = (int)((Sint64)i * inrate / outrate); + /* Calculating the following way avoids subtraction or modulo of large + * floats which have low result precision. + * interpolation1 + * = (i / outrate * inrate) - floor(i / outrate * inrate) + * = mod(i / outrate * inrate, 1) + * = mod(i * inrate, outrate) / outrate */ + const int srcfraction = ((Sint64)i) * inrate % outrate; + const float interpolation1 = ((float)srcfraction) / ((float)outrate); + const int filterindex1 = ((Sint32)srcfraction) * RESAMPLER_SAMPLES_PER_ZERO_CROSSING / outrate; + const float interpolation2 = 1.0f - interpolation1; + const int filterindex2 = ((Sint32)(outrate - srcfraction)) * RESAMPLER_SAMPLES_PER_ZERO_CROSSING / outrate; + + for (chan = 0; chan < chans; chan++) { + float outsample = 0.0f; + + /* do this twice to calculate the sample, once for the "left wing" and then same for the right. */ + for (j = 0; (filterindex1 + (j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING)) < RESAMPLER_FILTER_SIZE; j++) { + const int filt_ind = filterindex1 + j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING; + 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 += (float) (insample * (ResamplerFilter[filt_ind] + (interpolation1 * ResamplerFilterDifference[filt_ind]))); + } + + /* Do the right wing! */ + for (j = 0; (filterindex2 + (j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING)) < RESAMPLER_FILTER_SIZE; j++) { + const int filt_ind = filterindex2 + j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING; + 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 += (float) (insample * (ResamplerFilter[filt_ind] + (interpolation2 * ResamplerFilterDifference[filt_ind]))); + } + + *(dst++) = outsample; + } + } + + return outframes * chans * sizeof(float); +} + +int SDL_ConvertAudio(SDL_AudioCVT *cvt) +{ + /* !!! FIXME: (cvt) should be const; stack-copy it here. */ + /* !!! FIXME: (actually, we can't...len_cvt needs to be updated. Grr.) */ + + /* Make sure there's data to convert */ + if (!cvt->buf) { + return SDL_SetError("No buffer allocated for conversion"); + } + + /* Return okay if no conversion is necessary */ + cvt->len_cvt = cvt->len; + if (cvt->filters[0] == NULL) { + return 0; + } + + /* Set up the conversion and go! */ + cvt->filter_index = 0; + cvt->filters[0](cvt, cvt->src_format); + return 0; +} + +static void SDLCALL SDL_Convert_Byteswap(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ +#if DEBUG_CONVERT + SDL_Log("SDL_AUDIO_CONVERT: Converting byte order\n"); +#endif + + switch (SDL_AUDIO_BITSIZE(format)) { +#define CASESWAP(b) \ + case b: \ + { \ + Uint##b *ptr = (Uint##b *)cvt->buf; \ + int i; \ + for (i = cvt->len_cvt / sizeof(*ptr); i; --i, ++ptr) { \ + *ptr = SDL_Swap##b(*ptr); \ + } \ + break; \ + } + + CASESWAP(16); + CASESWAP(32); + CASESWAP(64); + +#undef CASESWAP + + default: + SDL_assert(!"unhandled byteswap datatype!"); + break; + } + + if (cvt->filters[++cvt->filter_index]) { + /* flip endian flag for data. */ + if (format & SDL_AUDIO_MASK_ENDIAN) { + format &= ~SDL_AUDIO_MASK_ENDIAN; + } else { + format |= SDL_AUDIO_MASK_ENDIAN; + } + cvt->filters[cvt->filter_index](cvt, format); + } +} + +static int SDL_AddAudioCVTFilter(SDL_AudioCVT *cvt, SDL_AudioFilter filter) +{ + if (cvt->filter_index >= SDL_AUDIOCVT_MAX_FILTERS) { + return SDL_SetError("Too many filters needed for conversion, exceeded maximum of %d", SDL_AUDIOCVT_MAX_FILTERS); + } + SDL_assert(filter != NULL); + cvt->filters[cvt->filter_index++] = filter; + cvt->filters[cvt->filter_index] = NULL; /* Moving terminator */ + return 0; +} + +static int SDL_BuildAudioTypeCVTToFloat(SDL_AudioCVT *cvt, const SDL_AudioFormat src_fmt) +{ + int retval = 0; /* 0 == no conversion necessary. */ + + if ((SDL_AUDIO_ISBIGENDIAN(src_fmt) != 0) == (SDL_BYTEORDER == SDL_LIL_ENDIAN) && SDL_AUDIO_BITSIZE(src_fmt) > 8) { + if (SDL_AddAudioCVTFilter(cvt, SDL_Convert_Byteswap) < 0) { + return -1; + } + retval = 1; /* added a converter. */ + } + + if (!SDL_AUDIO_ISFLOAT(src_fmt)) { + const Uint16 src_bitsize = SDL_AUDIO_BITSIZE(src_fmt); + const Uint16 dst_bitsize = 32; + SDL_AudioFilter filter = NULL; + + switch (src_fmt & ~SDL_AUDIO_MASK_ENDIAN) { + case AUDIO_S8: + filter = SDL_Convert_S8_to_F32; + break; + case AUDIO_U8: + filter = SDL_Convert_U8_to_F32; + break; + case AUDIO_S16: + filter = SDL_Convert_S16_to_F32; + break; + case AUDIO_U16: + filter = SDL_Convert_U16_to_F32; + break; + case AUDIO_S32: + filter = SDL_Convert_S32_to_F32; + break; + default: + SDL_assert(!"Unexpected audio format!"); + break; + } + + if (!filter) { + return SDL_SetError("No conversion from source format to float available"); + } + + if (SDL_AddAudioCVTFilter(cvt, filter) < 0) { + return -1; + } + if (src_bitsize < dst_bitsize) { + const int mult = (dst_bitsize / src_bitsize); + cvt->len_mult *= mult; + cvt->len_ratio *= mult; + } else if (src_bitsize > dst_bitsize) { + const int div = (src_bitsize / dst_bitsize); + cvt->len_ratio /= div; + } + + retval = 1; /* added a converter. */ + } + + return retval; +} + +static int SDL_BuildAudioTypeCVTFromFloat(SDL_AudioCVT *cvt, const SDL_AudioFormat dst_fmt) +{ + int retval = 0; /* 0 == no conversion necessary. */ + + if (!SDL_AUDIO_ISFLOAT(dst_fmt)) { + const Uint16 dst_bitsize = SDL_AUDIO_BITSIZE(dst_fmt); + const Uint16 src_bitsize = 32; + SDL_AudioFilter filter = NULL; + switch (dst_fmt & ~SDL_AUDIO_MASK_ENDIAN) { + case AUDIO_S8: + filter = SDL_Convert_F32_to_S8; + break; + case AUDIO_U8: + filter = SDL_Convert_F32_to_U8; + break; + case AUDIO_S16: + filter = SDL_Convert_F32_to_S16; + break; + case AUDIO_U16: + filter = SDL_Convert_F32_to_U16; + break; + case AUDIO_S32: + filter = SDL_Convert_F32_to_S32; + break; + default: + SDL_assert(!"Unexpected audio format!"); + break; + } + + if (!filter) { + return SDL_SetError("No conversion from float to format 0x%.4x available", dst_fmt); + } + + if (SDL_AddAudioCVTFilter(cvt, filter) < 0) { + return -1; + } + if (src_bitsize < dst_bitsize) { + const int mult = (dst_bitsize / src_bitsize); + cvt->len_mult *= mult; + cvt->len_ratio *= mult; + } else if (src_bitsize > dst_bitsize) { + const int div = (src_bitsize / dst_bitsize); + cvt->len_ratio /= div; + } + retval = 1; /* added a converter. */ + } + + if ((SDL_AUDIO_ISBIGENDIAN(dst_fmt) != 0) == (SDL_BYTEORDER == SDL_LIL_ENDIAN) && SDL_AUDIO_BITSIZE(dst_fmt) > 8) { + if (SDL_AddAudioCVTFilter(cvt, SDL_Convert_Byteswap) < 0) { + return -1; + } + retval = 1; /* added a converter. */ + } + + return retval; +} + +#ifdef HAVE_LIBSAMPLERATE_H + +static void SDL_ResampleCVT_SRC(SDL_AudioCVT *cvt, const int chans, const SDL_AudioFormat format) +{ + const float *src = (const float *)cvt->buf; + const int srclen = cvt->len_cvt; + float *dst = (float *)(cvt->buf + srclen); + const int dstlen = (cvt->len * cvt->len_mult) - srclen; + const int framelen = sizeof(float) * chans; + int result = 0; + SRC_DATA data; + + SDL_zero(data); + + data.data_in = (float *)src; /* Older versions of libsamplerate had a non-const pointer, but didn't write to it */ + data.input_frames = srclen / framelen; + + data.data_out = dst; + data.output_frames = dstlen / framelen; + + data.src_ratio = cvt->rate_incr; + + result = SRC_src_simple(&data, SRC_converter, chans); /* Simple API converts the whole buffer at once. No need for initialization. */ +/* !!! FIXME: Handle library failures? */ +#if DEBUG_CONVERT + if (result != 0) { + SDL_Log("src_simple() failed: %s", SRC_src_strerror(result)); + } +#else + (void)result; +#endif + + cvt->len_cvt = data.output_frames_gen * framelen; + + SDL_memmove(cvt->buf, dst, cvt->len_cvt); + + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, format); + } +} + +#endif /* HAVE_LIBSAMPLERATE_H */ + +static void SDL_ResampleCVT(SDL_AudioCVT *cvt, const int chans, const SDL_AudioFormat format) +{ + /* !!! FIXME in 2.1: there are ten slots in the filter list, and the theoretical maximum we use is six (seven with NULL terminator). + !!! FIXME in 2.1: We need to store data for this resampler, because the cvt structure doesn't store the original sample rates, + !!! FIXME in 2.1: so we steal the ninth and tenth slot. :( */ + const int inrate = (int)(size_t)cvt->filters[SDL_AUDIOCVT_MAX_FILTERS - 1]; + const int outrate = (int)(size_t)cvt->filters[SDL_AUDIOCVT_MAX_FILTERS]; + const float *src = (const float *)cvt->buf; + const int srclen = cvt->len_cvt; + /*float *dst = (float *) cvt->buf; + const int dstlen = (cvt->len * cvt->len_mult);*/ + /* !!! FIXME: remove this if we can get the resampler to work in-place again. */ + float *dst = (float *)(cvt->buf + srclen); + const int dstlen = (cvt->len * cvt->len_mult) - srclen; + const int requestedpadding = ResamplerPadding(inrate, outrate); + int paddingsamples; + float *padding; + + if (requestedpadding < SDL_MAX_SINT32 / chans) { + paddingsamples = requestedpadding * chans; + } else { + paddingsamples = 0; + } + SDL_assert(format == AUDIO_F32SYS); + + /* we keep no streaming state here, so pad with silence on both ends. */ + padding = (float *)SDL_calloc(paddingsamples ? paddingsamples : 1, sizeof(float)); + if (!padding) { + SDL_OutOfMemory(); + return; + } + + cvt->len_cvt = SDL_ResampleAudio(chans, inrate, outrate, padding, padding, src, srclen, dst, dstlen); + + SDL_free(padding); + + 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); + } +} + +/* !!! FIXME: We only have this macro salsa because SDL_AudioCVT doesn't + !!! FIXME: store channel info, so we have to have function entry + !!! FIXME: points for each supported channel count and multiple + !!! FIXME: vs arbitrary. When we rev the ABI, clean this up. */ +#define RESAMPLER_FUNCS(chans) \ + static void SDLCALL \ + SDL_ResampleCVT_c##chans(SDL_AudioCVT *cvt, SDL_AudioFormat format) \ + { \ + SDL_ResampleCVT(cvt, chans, format); \ + } +RESAMPLER_FUNCS(1) +RESAMPLER_FUNCS(2) +RESAMPLER_FUNCS(4) +RESAMPLER_FUNCS(6) +RESAMPLER_FUNCS(8) +#undef RESAMPLER_FUNCS + +#ifdef HAVE_LIBSAMPLERATE_H +#define RESAMPLER_FUNCS(chans) \ + static void SDLCALL \ + SDL_ResampleCVT_SRC_c##chans(SDL_AudioCVT *cvt, SDL_AudioFormat format) \ + { \ + SDL_ResampleCVT_SRC(cvt, chans, format); \ + } +RESAMPLER_FUNCS(1) +RESAMPLER_FUNCS(2) +RESAMPLER_FUNCS(4) +RESAMPLER_FUNCS(6) +RESAMPLER_FUNCS(8) +#undef RESAMPLER_FUNCS +#endif /* HAVE_LIBSAMPLERATE_H */ + +static SDL_AudioFilter ChooseCVTResampler(const int dst_channels) +{ +#ifdef HAVE_LIBSAMPLERATE_H + if (SRC_available) { + switch (dst_channels) { + case 1: + return SDL_ResampleCVT_SRC_c1; + case 2: + return SDL_ResampleCVT_SRC_c2; + case 4: + return SDL_ResampleCVT_SRC_c4; + case 6: + return SDL_ResampleCVT_SRC_c6; + case 8: + return SDL_ResampleCVT_SRC_c8; + default: + break; + } + } +#endif /* HAVE_LIBSAMPLERATE_H */ + + switch (dst_channels) { + case 1: + return SDL_ResampleCVT_c1; + case 2: + return SDL_ResampleCVT_c2; + case 4: + return SDL_ResampleCVT_c4; + case 6: + return SDL_ResampleCVT_c6; + case 8: + return SDL_ResampleCVT_c8; + default: + break; + } + + return NULL; +} + +static int SDL_BuildAudioResampleCVT(SDL_AudioCVT *cvt, const int dst_channels, + const int src_rate, const int dst_rate) +{ + SDL_AudioFilter filter; + + if (src_rate == dst_rate) { + return 0; /* no conversion necessary. */ + } + + filter = ChooseCVTResampler(dst_channels); + if (!filter) { + return SDL_SetError("No conversion available for these rates"); + } + + /* Update (cvt) with filter details... */ + if (SDL_AddAudioCVTFilter(cvt, filter) < 0) { + return -1; + } + + /* !!! FIXME in 2.1: there are ten slots in the filter list, and the theoretical maximum we use is six (seven with NULL terminator). + !!! FIXME in 2.1: We need to store data for this resampler, because the cvt structure doesn't store the original sample rates, + !!! FIXME in 2.1: so we steal the ninth and tenth slot. :( */ + if (cvt->filter_index >= (SDL_AUDIOCVT_MAX_FILTERS - 2)) { + return SDL_SetError("Too many filters needed for conversion, exceeded maximum of %d", SDL_AUDIOCVT_MAX_FILTERS - 2); + } + cvt->filters[SDL_AUDIOCVT_MAX_FILTERS - 1] = (SDL_AudioFilter)(uintptr_t)src_rate; + cvt->filters[SDL_AUDIOCVT_MAX_FILTERS] = (SDL_AudioFilter)(uintptr_t)dst_rate; + + if (src_rate < dst_rate) { + const double mult = ((double)dst_rate) / ((double)src_rate); + cvt->len_mult *= (int)SDL_ceil(mult); + cvt->len_ratio *= mult; + } else { + cvt->len_ratio /= ((double)src_rate) / ((double)dst_rate); + } + + /* !!! FIXME: remove this if we can get the resampler to work in-place again. */ + /* the buffer is big enough to hold the destination now, but + we need it large enough to hold a separate scratch buffer. */ + cvt->len_mult *= 2; + + return 1; /* added a converter. */ +} + +static SDL_bool SDL_SupportedAudioFormat(const SDL_AudioFormat fmt) +{ + switch (fmt) { + case AUDIO_U8: + case AUDIO_S8: + case AUDIO_U16LSB: + case AUDIO_S16LSB: + case AUDIO_U16MSB: + case AUDIO_S16MSB: + case AUDIO_S32LSB: + case AUDIO_S32MSB: + case AUDIO_F32LSB: + case AUDIO_F32MSB: + return SDL_TRUE; /* supported. */ + + default: + break; + } + + return SDL_FALSE; /* unsupported. */ +} + +static SDL_bool SDL_SupportedChannelCount(const int channels) +{ + return ((channels >= 1) && (channels <= 8)) ? SDL_TRUE : SDL_FALSE; +} + +/* Creates a set of audio filters to convert from one format to another. + Returns 0 if no conversion is needed, 1 if the audio filter is set up, + or -1 if an error like invalid parameter, unsupported format, etc. occurred. +*/ + +int SDL_BuildAudioCVT(SDL_AudioCVT *cvt, + SDL_AudioFormat src_format, Uint8 src_channels, int src_rate, + SDL_AudioFormat dst_format, Uint8 dst_channels, int dst_rate) +{ + SDL_AudioFilter channel_converter = NULL; + + /* Sanity check target pointer */ + if (!cvt) { + return SDL_InvalidParamError("cvt"); + } + + /* Make sure we zero out the audio conversion before error checking */ + SDL_zerop(cvt); + + if (!SDL_SupportedAudioFormat(src_format)) { + return SDL_SetError("Invalid source format"); + } + if (!SDL_SupportedAudioFormat(dst_format)) { + return SDL_SetError("Invalid destination format"); + } + if (!SDL_SupportedChannelCount(src_channels)) { + return SDL_SetError("Invalid source channels"); + } + if (!SDL_SupportedChannelCount(dst_channels)) { + return SDL_SetError("Invalid destination channels"); + } + if (src_rate <= 0) { + return SDL_SetError("Source rate is equal to or less than zero"); + } + if (dst_rate <= 0) { + return SDL_SetError("Destination rate is equal to or less than zero"); + } + if (src_rate >= SDL_MAX_SINT32 / RESAMPLER_SAMPLES_PER_ZERO_CROSSING) { + return SDL_SetError("Source rate is too high"); + } + if (dst_rate >= SDL_MAX_SINT32 / RESAMPLER_SAMPLES_PER_ZERO_CROSSING) { + return SDL_SetError("Destination rate is too high"); + } + +#if DEBUG_CONVERT + SDL_Log("SDL_AUDIO_CONVERT: Build format %04x->%04x, channels %u->%u, rate %d->%d\n", + src_format, dst_format, src_channels, dst_channels, src_rate, dst_rate); +#endif + + /* Start off with no conversion necessary */ + cvt->src_format = src_format; + cvt->dst_format = dst_format; + cvt->needed = 0; + cvt->filter_index = 0; + SDL_zeroa(cvt->filters); + cvt->len_mult = 1; + cvt->len_ratio = 1.0; + cvt->rate_incr = ((double)dst_rate) / ((double)src_rate); + + /* Make sure we've chosen audio conversion functions (SIMD, scalar, etc.) */ + SDL_ChooseAudioConverters(); + + /* Type conversion goes like this now: + - byteswap to CPU native format first if necessary. + - convert to native Float32 if necessary. + - resample and change channel count if necessary. + - convert to final data format. + - byteswap back to foreign format if necessary. + + The expectation is we can process data faster in float32 + (possibly with SIMD), and making several passes over the same + buffer is likely to be CPU cache-friendly, avoiding the + biggest performance hit in modern times. Previously we had + (script-generated) custom converters for every data type and + it was a bloat on SDL compile times and final library size. */ + + /* see if we can skip float conversion entirely. */ + if (src_rate == dst_rate && src_channels == dst_channels) { + if (src_format == dst_format) { + return 0; + } + + /* just a byteswap needed? */ + if ((src_format & ~SDL_AUDIO_MASK_ENDIAN) == (dst_format & ~SDL_AUDIO_MASK_ENDIAN)) { + if (SDL_AUDIO_BITSIZE(dst_format) == 8) { + return 0; + } + if (SDL_AddAudioCVTFilter(cvt, SDL_Convert_Byteswap) < 0) { + return -1; + } + cvt->needed = 1; + return 1; + } + } + + /* Convert data types, if necessary. Updates (cvt). */ + if (SDL_BuildAudioTypeCVTToFloat(cvt, src_format) < 0) { + return -1; /* shouldn't happen, but just in case... */ + } + + /* Channel conversion */ + + /* SDL_SupportedChannelCount should have caught these asserts, or we added a new format and forgot to update the table. */ + SDL_assert(src_channels <= SDL_arraysize(channel_converters)); + SDL_assert(dst_channels <= SDL_arraysize(channel_converters[0])); + + channel_converter = channel_converters[src_channels - 1][dst_channels - 1]; + if ((!channel_converter) != (src_channels == dst_channels)) { + /* All combinations of supported channel counts should have been handled by now, but let's be defensive */ + return SDL_SetError("Invalid channel combination"); + } else if (channel_converter != NULL) { + /* swap in some SIMD versions for a few of these. */ + if (channel_converter == SDL_ConvertStereoToMono) { + SDL_AudioFilter filter = NULL; +#ifdef HAVE_SSE3_INTRINSICS + if (!filter && SDL_HasSSE3()) { + filter = SDL_ConvertStereoToMono_SSE3; + } +#endif + if (filter) { + channel_converter = filter; + } + } else if (channel_converter == SDL_ConvertMonoToStereo) { + SDL_AudioFilter filter = NULL; +#ifdef HAVE_SSE_INTRINSICS + if (!filter && SDL_HasSSE()) { + filter = SDL_ConvertMonoToStereo_SSE; + } +#endif + if (filter) { + channel_converter = filter; + } + } + + if (SDL_AddAudioCVTFilter(cvt, channel_converter) < 0) { + return -1; + } + + if (src_channels < dst_channels) { + cvt->len_mult = ((cvt->len_mult * dst_channels) + (src_channels - 1)) / src_channels; + } + + cvt->len_ratio = (cvt->len_ratio * dst_channels) / src_channels; + src_channels = dst_channels; + } + + /* Do rate conversion, if necessary. Updates (cvt). */ + if (SDL_BuildAudioResampleCVT(cvt, dst_channels, src_rate, dst_rate) < 0) { + return -1; /* shouldn't happen, but just in case... */ + } + + /* Move to final data type. */ + if (SDL_BuildAudioTypeCVTFromFloat(cvt, dst_format) < 0) { + return -1; /* shouldn't happen, but just in case... */ + } + + cvt->needed = (cvt->filter_index != 0); + return cvt->needed; +} + +typedef int (*SDL_ResampleAudioStreamFunc)(SDL_AudioStream *stream, const void *inbuf, const int inbuflen, void *outbuf, const int outbuflen); +typedef void (*SDL_ResetAudioStreamResamplerFunc)(SDL_AudioStream *stream); +typedef void (*SDL_CleanupAudioStreamResamplerFunc)(SDL_AudioStream *stream); + +struct _SDL_AudioStream +{ + SDL_AudioCVT cvt_before_resampling; + 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; + SDL_AudioFormat src_format; + Uint8 src_channels; + int src_rate; + int dst_sample_frame_size; + SDL_AudioFormat dst_format; + Uint8 dst_channels; + int dst_rate; + 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; + SDL_CleanupAudioStreamResamplerFunc cleanup_resampler_func; +}; + +static Uint8 *EnsureStreamBufferSize(SDL_AudioStream *stream, int newlen) +{ + Uint8 *ptr; + size_t offset; + + if (stream->work_buffer_len >= newlen) { + ptr = stream->work_buffer_base; + } else { + ptr = (Uint8 *)SDL_realloc(stream->work_buffer_base, (size_t)newlen + 32); + if (!ptr) { + SDL_OutOfMemory(); + return NULL; + } + /* Make sure we're aligned to 16 bytes for SIMD code. */ + stream->work_buffer_base = ptr; + stream->work_buffer_len = newlen; + } + + offset = ((size_t)ptr) & 15; + return offset ? ptr + (16 - offset) : ptr; +} + +#ifdef HAVE_LIBSAMPLERATE_H +static int SDL_ResampleAudioStream_SRC(SDL_AudioStream *stream, const void *_inbuf, const int inbuflen, void *_outbuf, const int outbuflen) +{ + const float *inbuf = (const float *)_inbuf; + float *outbuf = (float *)_outbuf; + const int framelen = sizeof(float) * stream->pre_resample_channels; + SRC_STATE *state = (SRC_STATE *)stream->resampler_state; + SRC_DATA data; + int result; + + 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; + data.input_frames_used = 0; + + data.data_out = outbuf; + data.output_frames = outbuflen / framelen; + + data.end_of_input = 0; + data.src_ratio = stream->rate_incr; + + result = SRC_src_process(state, &data); + if (result != 0) { + SDL_SetError("src_process() failed: %s", SRC_src_strerror(result)); + return 0; + } + + /* If this fails, we need to store them off somewhere */ + SDL_assert(data.input_frames_used == data.input_frames); + + return data.output_frames_gen * (sizeof(float) * stream->pre_resample_channels); +} + +static void SDL_ResetAudioStreamResampler_SRC(SDL_AudioStream *stream) +{ + SRC_src_reset((SRC_STATE *)stream->resampler_state); +} + +static void SDL_CleanupAudioStreamResampler_SRC(SDL_AudioStream *stream) +{ + SRC_STATE *state = (SRC_STATE *)stream->resampler_state; + if (state) { + SRC_src_delete(state); + } + + stream->resampler_state = NULL; + stream->resampler_func = NULL; + stream->reset_resampler_func = NULL; + stream->cleanup_resampler_func = NULL; +} + +static SDL_bool SetupLibSampleRateResampling(SDL_AudioStream *stream) +{ + int result = 0; + SRC_STATE *state = NULL; + + if (SRC_available) { + state = SRC_src_new(SRC_converter, stream->pre_resample_channels, &result); + if (!state) { + SDL_SetError("src_new() failed: %s", SRC_src_strerror(result)); + } + } + + if (!state) { + SDL_CleanupAudioStreamResampler_SRC(stream); + return SDL_FALSE; + } + + stream->resampler_state = state; + stream->resampler_func = SDL_ResampleAudioStream_SRC; + stream->reset_resampler_func = SDL_ResetAudioStreamResampler_SRC; + stream->cleanup_resampler_func = SDL_CleanupAudioStreamResampler_SRC; + + return SDL_TRUE; +} +#endif /* HAVE_LIBSAMPLERATE_H */ + +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 = stream->resampler_padding_samples; + 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. */ + + 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 + paddingsamples) - (cpy / sizeof(float)), inbufend - cpy, cpy); + return retval; +} + +static void SDL_ResetAudioStreamResampler(SDL_AudioStream *stream) +{ + /* set all the padding to silence. */ + const int len = stream->resampler_padding_samples; + SDL_memset(stream->resampler_state, '\0', len * sizeof(float)); +} + +static void SDL_CleanupAudioStreamResampler(SDL_AudioStream *stream) +{ + SDL_free(stream->resampler_state); +} + +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) +{ + int packetlen = 4096; /* !!! FIXME: good enough for now. */ + Uint8 pre_resample_channels; + SDL_AudioStream *retval; + + if (src_channels == 0) { + SDL_InvalidParamError("src_channels"); + return NULL; + } + + if (dst_channels == 0) { + SDL_InvalidParamError("dst_channels"); + return NULL; + } + + retval = (SDL_AudioStream *)SDL_calloc(1, sizeof(SDL_AudioStream)); + if (!retval) { + SDL_OutOfMemory(); + return NULL; + } + + /* If increasing channels, do it after resampling, since we'd just + do more work to resample duplicate channels. If we're decreasing, do + it first so we resample the interpolated data instead of interpolating + 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; + retval->src_rate = src_rate; + retval->dst_sample_frame_size = (SDL_AUDIO_BITSIZE(dst_format) / 8) * dst_channels; + retval->dst_format = dst_format; + retval->dst_channels = dst_channels; + retval->dst_rate = dst_rate; + 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 ? retval->resampler_padding_samples : 1, sizeof(float)); + + if (!retval->resampler_padding) { + SDL_FreeAudioStream(retval); + SDL_OutOfMemory(); + return NULL; + } + + 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->staging_buffer) { + 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) { + SDL_FreeAudioStream(retval); + return NULL; /* SDL_BuildAudioCVT should have called SDL_SetError. */ + } + } else { + /* Don't resample at first. Just get us to Float32 format. */ + /* !!! FIXME: convert to int32 on devices without hardware float. */ + if (SDL_BuildAudioCVT(&retval->cvt_before_resampling, src_format, src_channels, src_rate, AUDIO_F32SYS, pre_resample_channels, src_rate) < 0) { + SDL_FreeAudioStream(retval); + return NULL; /* SDL_BuildAudioCVT should have called SDL_SetError. */ + } + +#ifdef HAVE_LIBSAMPLERATE_H + SetupLibSampleRateResampling(retval); +#endif + + if (!retval->resampler_func) { + retval->resampler_state = SDL_calloc(retval->resampler_padding_samples, sizeof(float)); + if (!retval->resampler_state) { + SDL_FreeAudioStream(retval); + SDL_OutOfMemory(); + return NULL; + } + + retval->resampler_func = SDL_ResampleAudioStream; + retval->reset_resampler_func = SDL_ResetAudioStreamResampler; + retval->cleanup_resampler_func = SDL_CleanupAudioStreamResampler; + } + + /* Convert us to the final format after resampling. */ + if (SDL_BuildAudioCVT(&retval->cvt_after_resampling, AUDIO_F32SYS, pre_resample_channels, dst_rate, dst_format, dst_channels, dst_rate) < 0) { + SDL_FreeAudioStream(retval); + return NULL; /* SDL_BuildAudioCVT should have called SDL_SetError. */ + } + } + + retval->queue = SDL_NewDataQueue(packetlen, (size_t)packetlen * 2); + if (!retval->queue) { + SDL_FreeAudioStream(retval); + return NULL; /* SDL_NewDataQueue should have called SDL_SetError. */ + } + + return retval; +} + +static int SDL_AudioStreamPutInternal(SDL_AudioStream *stream, const void *buf, int len, int *maxputbytes) +{ + int buflen = len; + int workbuflen; + Uint8 *workbuf; + Uint8 *resamplebuf = NULL; + int resamplebuflen = 0; + int neededpaddingbytes; + int paddingbytes; + + /* !!! 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. */ + + /* no padding prepended on first run. */ + neededpaddingbytes = stream->resampler_padding_samples * sizeof(float); + paddingbytes = stream->first_run ? 0 : neededpaddingbytes; + stream->first_run = SDL_FALSE; + + /* Make sure the work buffer can hold all the data we need at once... */ + workbuflen = buflen; + if (stream->cvt_before_resampling.needed) { + 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 + SDL_Log("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 + SDL_Log("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! */ + } + buflen = stream->cvt_before_resampling.len_cvt; + +#if DEBUG_AUDIOSTREAM + SDL_Log("AUDIOSTREAM: After initial conversion we have %d bytes\n", buflen); +#endif + } + + if (stream->dst_rate != stream->src_rate) { + /* 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; + } + + /* 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. */ + SDL_assert(buflen >= neededpaddingbytes); + if (buflen > neededpaddingbytes) { + buflen = stream->resampler_func(stream, workbuf, buflen - neededpaddingbytes, resamplebuf, resamplebuflen); + } else { + buflen = 0; + } + +#if DEBUG_AUDIOSTREAM + SDL_Log("AUDIOSTREAM: After resampling we have %d bytes\n", buflen); +#endif + } + + 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) { + return -1; /* uhoh! */ + } + buflen = stream->cvt_after_resampling.len_cvt; + +#if DEBUG_AUDIOSTREAM + SDL_Log("AUDIOSTREAM: After final conversion we have %d bytes\n", buflen); +#endif + } + +#if DEBUG_AUDIOSTREAM + SDL_Log("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; +} + +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 + SDL_Log("AUDIOSTREAM: wants to put %d preconverted bytes\n", buflen); +#endif + + if (!stream) { + return SDL_InvalidParamError("stream"); + } + if (!buf) { + return SDL_InvalidParamError("buf"); + } + if (len == 0) { + return 0; /* nothing to do. */ + } + 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 + SDL_Log("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, NULL); + } + + /* 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, NULL) < 0) { + return -1; + } + buf = (void *)((Uint8 *)buf + amount); + len -= amount; + } + return 0; +} + +int SDL_AudioStreamFlush(SDL_AudioStream *stream) +{ + if (!stream) { + return SDL_InvalidParamError("stream"); + } + +#if DEBUG_AUDIOSTREAM + SDL_Log("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 + SDL_Log("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) +{ +#if DEBUG_AUDIOSTREAM + SDL_Log("AUDIOSTREAM: want to get %d converted bytes\n", len); +#endif + + if (!stream) { + return SDL_InvalidParamError("stream"); + } + if (!buf) { + return SDL_InvalidParamError("buf"); + } + if (len <= 0) { + return 0; /* nothing to do. */ + } + if ((len % stream->dst_sample_frame_size) != 0) { + return SDL_SetError("Can't request partial sample frames"); + } + + return (int)SDL_ReadFromDataQueue(stream->queue, buf, len); +} + +/* number of converted/resampled bytes available */ +int 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, (size_t)stream->packetlen * 2); + if (stream->reset_resampler_func) { + stream->reset_resampler_func(stream); + } + stream->first_run = SDL_TRUE; + stream->staging_buffer_filled = 0; + } +} + +/* dispose of a stream */ +void SDL_FreeAudioStream(SDL_AudioStream *stream) +{ + if (stream) { + if (stream->cleanup_resampler_func) { + 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); + } +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/audio/SDL_audiodev.c b/SDL2-2.30.5/src/audio/SDL_audiodev.c similarity index 67% rename from SDL2-2.0.12/src/audio/SDL_audiodev.c rename to SDL2-2.30.5/src/audio/SDL_audiodev.c index 9d94f7d..903ba9e 100644 --- a/SDL2-2.0.12/src/audio/SDL_audiodev.c +++ b/SDL2-2.30.5/src/audio/SDL_audiodev.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -22,7 +22,7 @@ /* Get the name of the audio device we use for output */ -#if SDL_AUDIO_DRIVER_NETBSD || SDL_AUDIO_DRIVER_OSS || SDL_AUDIO_DRIVER_SUNAUDIO +#if defined(SDL_AUDIO_DRIVER_NETBSD) || defined(SDL_AUDIO_DRIVER_OSS) || defined(SDL_AUDIO_DRIVER_SUNAUDIO) #include #include @@ -34,9 +34,9 @@ #ifndef _PATH_DEV_DSP #if defined(__NETBSD__) || defined(__OPENBSD__) -#define _PATH_DEV_DSP "/dev/audio" +#define _PATH_DEV_DSP "/dev/audio" #else -#define _PATH_DEV_DSP "/dev/dsp" +#define _PATH_DEV_DSP "/dev/dsp" #endif #endif #ifndef _PATH_DEV_DSP24 @@ -46,12 +46,11 @@ #define _PATH_DEV_AUDIO "/dev/audio" #endif -static void -test_device(const int iscapture, const char *fname, int flags, int (*test) (int fd)) +static void test_device(const int iscapture, const char *fname, int flags, int (*test)(int fd)) { struct stat sb; if ((stat(fname, &sb) == 0) && (S_ISCHR(sb.st_mode))) { - const int audio_fd = open(fname, flags, 0); + const int audio_fd = open(fname, flags | O_CLOEXEC, 0); if (audio_fd >= 0) { const int okay = test(audio_fd); close(audio_fd); @@ -59,40 +58,46 @@ test_device(const int iscapture, const char *fname, int flags, int (*test) (int static size_t dummyhandle = 0; dummyhandle++; SDL_assert(dummyhandle != 0); - SDL_AddAudioDevice(iscapture, fname, (void *) dummyhandle); + + /* Note that spec is NULL; while we are opening the device + * endpoint here, the endpoint does not provide any mix format + * information, making this information inaccessible at + * enumeration time + */ + SDL_AddAudioDevice(iscapture, fname, NULL, (void *)(uintptr_t)dummyhandle); } } } } -static int -test_stub(int fd) +static int test_stub(int fd) { return 1; } -static void -SDL_EnumUnixAudioDevices_Internal(const int iscapture, const int classic, int (*test)(int)) +static void SDL_EnumUnixAudioDevices_Internal(const int iscapture, const int classic, int (*test)(int)) { const int flags = iscapture ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT; const char *audiodev; char audiopath[1024]; - if (test == NULL) + if (!test) { test = test_stub; + } /* Figure out what our audio device is */ - if (((audiodev = SDL_getenv("SDL_PATH_DSP")) == NULL) && - ((audiodev = SDL_getenv("AUDIODEV")) == NULL)) { + audiodev = SDL_getenv("SDL_PATH_DSP"); + if (!audiodev) { + audiodev = SDL_getenv("AUDIODEV"); + } + if (!audiodev) { if (classic) { audiodev = _PATH_DEV_AUDIO; } else { struct stat sb; /* Added support for /dev/sound/\* in Linux 2.4 */ - if (((stat("/dev/sound", &sb) == 0) && S_ISDIR(sb.st_mode)) - && ((stat(_PATH_DEV_DSP24, &sb) == 0) - && S_ISCHR(sb.st_mode))) { + if (((stat("/dev/sound", &sb) == 0) && S_ISDIR(sb.st_mode)) && ((stat(_PATH_DEV_DSP24, &sb) == 0) && S_ISCHR(sb.st_mode))) { audiodev = _PATH_DEV_DSP24; } else { audiodev = _PATH_DEV_DSP; @@ -104,16 +109,15 @@ SDL_EnumUnixAudioDevices_Internal(const int iscapture, const int classic, int (* if (SDL_strlen(audiodev) < (sizeof(audiopath) - 3)) { int instance = 0; while (instance <= 64) { - SDL_snprintf(audiopath, SDL_arraysize(audiopath), - "%s%d", audiodev, instance); + (void)SDL_snprintf(audiopath, SDL_arraysize(audiopath), + "%s%d", audiodev, instance); instance++; test_device(iscapture, audiopath, flags, test); } } } -void -SDL_EnumUnixAudioDevices(const int classic, int (*test)(int)) +void SDL_EnumUnixAudioDevices(const int classic, int (*test)(int)) { SDL_EnumUnixAudioDevices_Internal(SDL_TRUE, classic, test); SDL_EnumUnixAudioDevices_Internal(SDL_FALSE, classic, test); diff --git a/SDL2-2.0.12/src/audio/SDL_audiodev_c.h b/SDL2-2.30.5/src/audio/SDL_audiodev_c.h similarity index 87% rename from SDL2-2.0.12/src/audio/SDL_audiodev_c.h rename to SDL2-2.30.5/src/audio/SDL_audiodev_c.h index 3643441..1235ea4 100644 --- a/SDL2-2.0.12/src/audio/SDL_audiodev_c.h +++ b/SDL2-2.30.5/src/audio/SDL_audiodev_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -31,10 +31,10 @@ #ifdef USE_BLOCKING_WRITES #define OPEN_FLAGS_OUTPUT O_WRONLY -#define OPEN_FLAGS_INPUT O_RDONLY +#define OPEN_FLAGS_INPUT O_RDONLY #else -#define OPEN_FLAGS_OUTPUT (O_WRONLY|O_NONBLOCK) -#define OPEN_FLAGS_INPUT (O_RDONLY|O_NONBLOCK) +#define OPEN_FLAGS_OUTPUT (O_WRONLY | O_NONBLOCK) +#define OPEN_FLAGS_INPUT (O_RDONLY | O_NONBLOCK) #endif extern void SDL_EnumUnixAudioDevices(const int classic, int (*test)(int)); diff --git a/SDL2-2.30.5/src/audio/SDL_audiotypecvt.c b/SDL2-2.30.5/src/audio/SDL_audiotypecvt.c new file mode 100644 index 0000000..221bfbb --- /dev/null +++ b/SDL2-2.30.5/src/audio/SDL_audiotypecvt.c @@ -0,0 +1,1466 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_audio.h" +#include "SDL_audio_c.h" +#include "SDL_cpuinfo.h" + +#ifdef __ARM_NEON +#define HAVE_NEON_INTRINSICS 1 +#endif + +#ifdef __SSE2__ +#define HAVE_SSE2_INTRINSICS +#endif + +#if defined(__x86_64__) && defined(HAVE_SSE2_INTRINSICS) +#define NEED_SCALAR_CONVERTER_FALLBACKS 0 /* x86_64 guarantees SSE2. */ +#elif defined(__MACOSX__) && defined(HAVE_SSE2_INTRINSICS) +#define NEED_SCALAR_CONVERTER_FALLBACKS 0 /* Mac OS X/Intel guarantees SSE2. */ +#elif defined(__ARM_ARCH) && (__ARM_ARCH >= 8) && defined(HAVE_NEON_INTRINSICS) +#define NEED_SCALAR_CONVERTER_FALLBACKS 0 /* ARMv8+ promise NEON. */ +#elif defined(__APPLE__) && defined(__ARM_ARCH) && (__ARM_ARCH >= 7) && defined(HAVE_NEON_INTRINSICS) +#define NEED_SCALAR_CONVERTER_FALLBACKS 0 /* All Apple ARMv7 chips promise NEON support. */ +#endif + +/* Set to zero if platform is guaranteed to use a SIMD codepath here. */ +#ifndef NEED_SCALAR_CONVERTER_FALLBACKS +#define NEED_SCALAR_CONVERTER_FALLBACKS 1 +#endif + +/* Function pointers set to a CPU-specific implementation. */ +SDL_AudioFilter SDL_Convert_S8_to_F32 = NULL; +SDL_AudioFilter SDL_Convert_U8_to_F32 = NULL; +SDL_AudioFilter SDL_Convert_S16_to_F32 = NULL; +SDL_AudioFilter SDL_Convert_U16_to_F32 = NULL; +SDL_AudioFilter SDL_Convert_S32_to_F32 = NULL; +SDL_AudioFilter SDL_Convert_F32_to_S8 = NULL; +SDL_AudioFilter SDL_Convert_F32_to_U8 = NULL; +SDL_AudioFilter SDL_Convert_F32_to_S16 = NULL; +SDL_AudioFilter SDL_Convert_F32_to_U16 = NULL; +SDL_AudioFilter SDL_Convert_F32_to_S32 = NULL; + +#define DIVBY128 0.0078125f +#define DIVBY32768 0.000030517578125f +#define DIVBY8388607 0.00000011920930376163766f +#define DIVBY2147483648 0.0000000004656612873077392578125f /* 0x1p-31f */ + +#if NEED_SCALAR_CONVERTER_FALLBACKS + +/* This code requires that floats are in the IEEE-754 binary32 format */ +SDL_COMPILE_TIME_ASSERT(float_bits, sizeof(float) == sizeof(Uint32)); + +union float_bits { + Uint32 u32; + float f32; +}; + +/* Create a bit-mask based on the sign-bit. Should optimize to a single arithmetic-shift-right */ +#define SIGNMASK(x) (Uint32)(0u - ((Uint32)(x) >> 31)) + +static void SDLCALL SDL_Convert_S8_to_F32_Scalar(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + const int num_samples = cvt->len_cvt; + const Sint8 *src = (const Sint8 *)cvt->buf; + float *dst = (float *)cvt->buf; + int i; + + LOG_DEBUG_CONVERT("AUDIO_S8", "AUDIO_F32"); + + for (i = num_samples - 1; i >= 0; --i) { + /* 1) Construct a float in the range [65536.0, 65538.0) + * 2) Shift the float range to [-1.0, 1.0) */ + union float_bits x; + x.u32 = (Uint8)src[i] ^ 0x47800080u; + dst[i] = x.f32 - 65537.0f; + } + + cvt->len_cvt *= 4; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS); + } +} + +static void SDLCALL SDL_Convert_U8_to_F32_Scalar(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + const int num_samples = cvt->len_cvt; + const Uint8 *src = (const Uint8 *)cvt->buf; + float *dst = (float *)cvt->buf; + int i; + + LOG_DEBUG_CONVERT("AUDIO_U8", "AUDIO_F32"); + + for (i = num_samples - 1; i >= 0; --i) { + /* 1) Construct a float in the range [65536.0, 65538.0) + * 2) Shift the float range to [-1.0, 1.0) */ + union float_bits x; + x.u32 = src[i] ^ 0x47800000u; + dst[i] = x.f32 - 65537.0f; + } + + cvt->len_cvt *= 4; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS); + } +} + +static void SDLCALL SDL_Convert_S16_to_F32_Scalar(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + const int num_samples = cvt->len_cvt / sizeof(Sint16); + const Sint16 *src = (const Sint16 *)cvt->buf; + float *dst = (float *)cvt->buf; + int i; + + LOG_DEBUG_CONVERT("AUDIO_S16", "AUDIO_F32"); + + for (i = num_samples - 1; i >= 0; --i) { + /* 1) Construct a float in the range [256.0, 258.0) + * 2) Shift the float range to [-1.0, 1.0) */ + union float_bits x; + x.u32 = (Uint16)src[i] ^ 0x43808000u; + dst[i] = x.f32 - 257.0f; + } + + cvt->len_cvt *= 2; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS); + } +} + +static void SDLCALL SDL_Convert_U16_to_F32_Scalar(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + const Uint16 *src = ((const Uint16 *)(cvt->buf + cvt->len_cvt)) - 1; + float *dst = ((float *)(cvt->buf + cvt->len_cvt * 2)) - 1; + int i; + + LOG_DEBUG_CONVERT("AUDIO_U16", "AUDIO_F32"); + + for (i = cvt->len_cvt / sizeof(Uint16); i; --i, --src, --dst) { + *dst = (((float)*src) * DIVBY32768) - 1.0f; + } + + cvt->len_cvt *= 2; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS); + } +} + +static void SDLCALL SDL_Convert_S32_to_F32_Scalar(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + const Sint32 *src = (const Sint32 *)cvt->buf; + float *dst = (float *)cvt->buf; + int i; + + LOG_DEBUG_CONVERT("AUDIO_S32", "AUDIO_F32"); + + for (i = cvt->len_cvt / sizeof(Sint32); i; --i, ++src, ++dst) { + *dst = ((float)(*src >> 8)) * DIVBY8388607; + } + + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS); + } +} + +static void SDLCALL SDL_Convert_F32_to_S8_Scalar(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + const int num_samples = cvt->len_cvt / sizeof (float); + const float *src = (const float *)cvt->buf; + Sint8 *dst = (Sint8 *)cvt->buf; + int i; + + LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_S8"); + + for (i = 0; i < num_samples; ++i) { + /* 1) Shift the float range from [-1.0, 1.0] to [98303.0, 98305.0] + * 2) Shift the integer range from [0x47BFFF80, 0x47C00080] to [-128, 128] + * 3) Clamp the value to [-128, 127] */ + union float_bits x; + Uint32 y, z; + x.f32 = src[i] + 98304.0f; + + y = x.u32 - 0x47C00000u; + z = 0x7Fu - (y ^ SIGNMASK(y)); + y = y ^ (z & SIGNMASK(z)); + + dst[i] = (Sint8)(y & 0xFF); + } + + cvt->len_cvt /= 4; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, AUDIO_S8); + } +} + +static void SDLCALL SDL_Convert_F32_to_U8_Scalar(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + const int num_samples = cvt->len_cvt / sizeof (float); + const float *src = (const float *)cvt->buf; + Uint8 *dst = (Uint8 *)cvt->buf; + int i; + + LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_U8"); + + for (i = 0; i < num_samples; ++i) { + /* 1) Shift the float range from [-1.0, 1.0] to [98303.0, 98305.0] + * 2) Shift the integer range from [0x47BFFF80, 0x47C00080] to [-128, 128] + * 3) Clamp the value to [-128, 127] + * 4) Shift the integer range from [-128, 127] to [0, 255] */ + union float_bits x; + Uint32 y, z; + x.f32 = src[i] + 98304.0f; + + y = x.u32 - 0x47C00000u; + z = 0x7Fu - (y ^ SIGNMASK(y)); + y = (y ^ 0x80u) ^ (z & SIGNMASK(z)); + + dst[i] = (Uint8)(y & 0xFF); + } + + cvt->len_cvt /= 4; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, AUDIO_U8); + } +} + +static void SDLCALL SDL_Convert_F32_to_S16_Scalar(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + const int num_samples = cvt->len_cvt / sizeof (float); + const float *src = (const float *)cvt->buf; + Sint16 *dst = (Sint16 *)cvt->buf; + int i; + + LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_S16"); + + for (i = 0; i < num_samples; ++i) { + /* 1) Shift the float range from [-1.0, 1.0] to [383.0, 385.0] + * 2) Shift the integer range from [0x43BF8000, 0x43C08000] to [-32768, 32768] + * 3) Clamp values outside the [-32768, 32767] range */ + union float_bits x; + Uint32 y, z; + x.f32 = src[i] + 384.0f; + + y = x.u32 - 0x43C00000u; + z = 0x7FFFu - (y ^ SIGNMASK(y)); + y = y ^ (z & SIGNMASK(z)); + + dst[i] = (Sint16)(y & 0xFFFF); + } + + cvt->len_cvt /= 2; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, AUDIO_S16SYS); + } +} + +static void SDLCALL SDL_Convert_F32_to_U16_Scalar(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + const float *src = (const float *)cvt->buf; + Uint16 *dst = (Uint16 *)cvt->buf; + int i; + + LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_U16"); + + for (i = cvt->len_cvt / sizeof(float); i; --i, ++src, ++dst) { + const float sample = *src; + if (sample >= 1.0f) { + *dst = 65535; + } else if (sample <= -1.0f) { + *dst = 0; + } else { + *dst = (Uint16)((sample + 1.0f) * 32767.0f); + } + } + + cvt->len_cvt /= 2; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, AUDIO_U16SYS); + } +} + +static void SDLCALL SDL_Convert_F32_to_S32_Scalar(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + const int num_samples = cvt->len_cvt / sizeof (float); + const float *src = (const float *)cvt->buf; + Sint32 *dst = (Sint32 *)cvt->buf; + int i; + + LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_S32"); + + for (i = 0; i < num_samples; ++i) { + /* 1) Shift the float range from [-1.0, 1.0] to [-2147483648.0, 2147483648.0] + * 2) Set values outside the [-2147483648.0, 2147483647.0] range to -2147483648.0 + * 3) Convert the float to an integer, and fixup values outside the valid range */ + union float_bits x; + Uint32 y, z; + x.f32 = src[i]; + + y = x.u32 + 0x0F800000u; + z = y - 0xCF000000u; + z &= SIGNMASK(y ^ z); + x.u32 = y - z; + + dst[i] = (Sint32)x.f32 ^ (Sint32)SIGNMASK(z); + } + + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, AUDIO_S32SYS); + } +} +#endif + +#ifdef HAVE_SSE2_INTRINSICS +static void SDLCALL SDL_Convert_S8_to_F32_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + const Sint8 *src = (const Sint8 *)cvt->buf; + float *dst = (float *)cvt->buf; + int i = cvt->len_cvt; + + /* 1) Flip the sign bit to convert from S8 to U8 format + * 2) Construct a float in the range [65536.0, 65538.0) + * 3) Shift the float range to [-1.0, 1.0) + * dst[i] = i2f((src[i] ^ 0x80) | 0x47800000) - 65537.0 */ + const __m128i zero = _mm_setzero_si128(); + const __m128i flipper = _mm_set1_epi8(-0x80); + const __m128i caster = _mm_set1_epi16(0x4780 /* 0x47800000 = f2i(65536.0) */); + const __m128 offset = _mm_set1_ps(-65537.0); + + LOG_DEBUG_CONVERT("AUDIO_S8", "AUDIO_F32 (using SSE2)"); + + while (i >= 16) { + i -= 16; + + { + const __m128i bytes = _mm_xor_si128(_mm_loadu_si128((const __m128i *)&src[i]), flipper); + + const __m128i shorts1 = _mm_unpacklo_epi8(bytes, zero); + const __m128i shorts2 = _mm_unpackhi_epi8(bytes, zero); + + const __m128 floats1 = _mm_add_ps(_mm_castsi128_ps(_mm_unpacklo_epi16(shorts1, caster)), offset); + const __m128 floats2 = _mm_add_ps(_mm_castsi128_ps(_mm_unpackhi_epi16(shorts1, caster)), offset); + const __m128 floats3 = _mm_add_ps(_mm_castsi128_ps(_mm_unpacklo_epi16(shorts2, caster)), offset); + const __m128 floats4 = _mm_add_ps(_mm_castsi128_ps(_mm_unpackhi_epi16(shorts2, caster)), offset); + + _mm_storeu_ps(&dst[i], floats1); + _mm_storeu_ps(&dst[i + 4], floats2); + _mm_storeu_ps(&dst[i + 8], floats3); + _mm_storeu_ps(&dst[i + 12], floats4); + } + } + + while (i) { + --i; + _mm_store_ss(&dst[i], _mm_add_ss(_mm_castsi128_ps(_mm_cvtsi32_si128((Uint8)src[i] ^ 0x47800080u)), offset)); + } + + cvt->len_cvt *= 4; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS); + } +} + +static void SDLCALL SDL_Convert_U8_to_F32_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + const Sint8 *src = (const Sint8 *)cvt->buf; + float *dst = (float *)cvt->buf; + int i = cvt->len_cvt; + + /* 1) Construct a float in the range [65536.0, 65538.0) + * 2) Shift the float range to [-1.0, 1.0) + * dst[i] = i2f(src[i] | 0x47800000) - 65537.0 */ + const __m128i zero = _mm_setzero_si128(); + const __m128i caster = _mm_set1_epi16(0x4780 /* 0x47800000 = f2i(65536.0) */); + const __m128 offset = _mm_set1_ps(-65537.0); + + LOG_DEBUG_CONVERT("AUDIO_U8", "AUDIO_F32 (using SSE2)"); + + while (i >= 16) { + i -= 16; + + { + const __m128i bytes = _mm_loadu_si128((const __m128i *)&src[i]); + + const __m128i shorts1 = _mm_unpacklo_epi8(bytes, zero); + const __m128i shorts2 = _mm_unpackhi_epi8(bytes, zero); + + const __m128 floats1 = _mm_add_ps(_mm_castsi128_ps(_mm_unpacklo_epi16(shorts1, caster)), offset); + const __m128 floats2 = _mm_add_ps(_mm_castsi128_ps(_mm_unpackhi_epi16(shorts1, caster)), offset); + const __m128 floats3 = _mm_add_ps(_mm_castsi128_ps(_mm_unpacklo_epi16(shorts2, caster)), offset); + const __m128 floats4 = _mm_add_ps(_mm_castsi128_ps(_mm_unpackhi_epi16(shorts2, caster)), offset); + + _mm_storeu_ps(&dst[i], floats1); + _mm_storeu_ps(&dst[i + 4], floats2); + _mm_storeu_ps(&dst[i + 8], floats3); + _mm_storeu_ps(&dst[i + 12], floats4); + } + } + + while (i) { + --i; + _mm_store_ss(&dst[i], _mm_add_ss(_mm_castsi128_ps(_mm_cvtsi32_si128((Uint8)src[i] ^ 0x47800000u)), offset)); + } + + cvt->len_cvt *= 4; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS); + } +} + +static void SDLCALL SDL_Convert_S16_to_F32_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + const Sint16 *src = (const Sint16 *)cvt->buf; + float *dst = (float *)cvt->buf; + int i = cvt->len_cvt / 2; + + /* 1) Flip the sign bit to convert from S16 to U16 format + * 2) Construct a float in the range [256.0, 258.0) + * 3) Shift the float range to [-1.0, 1.0) + * dst[i] = i2f((src[i] ^ 0x8000) | 0x43800000) - 257.0 */ + const __m128i flipper = _mm_set1_epi16(-0x8000); + const __m128i caster = _mm_set1_epi16(0x4380 /* 0x43800000 = f2i(256.0) */); + const __m128 offset = _mm_set1_ps(-257.0f); + + LOG_DEBUG_CONVERT("AUDIO_S16", "AUDIO_F32 (using SSE2)"); + + while (i >= 16) { + i -= 16; + + { + const __m128i shorts1 = _mm_xor_si128(_mm_loadu_si128((const __m128i *)&src[i]), flipper); + const __m128i shorts2 = _mm_xor_si128(_mm_loadu_si128((const __m128i *)&src[i + 8]), flipper); + + const __m128 floats1 = _mm_add_ps(_mm_castsi128_ps(_mm_unpacklo_epi16(shorts1, caster)), offset); + const __m128 floats2 = _mm_add_ps(_mm_castsi128_ps(_mm_unpackhi_epi16(shorts1, caster)), offset); + const __m128 floats3 = _mm_add_ps(_mm_castsi128_ps(_mm_unpacklo_epi16(shorts2, caster)), offset); + const __m128 floats4 = _mm_add_ps(_mm_castsi128_ps(_mm_unpackhi_epi16(shorts2, caster)), offset); + + _mm_storeu_ps(&dst[i], floats1); + _mm_storeu_ps(&dst[i + 4], floats2); + _mm_storeu_ps(&dst[i + 8], floats3); + _mm_storeu_ps(&dst[i + 12], floats4); + } + } + + while (i) { + --i; + _mm_store_ss(&dst[i], _mm_add_ss(_mm_castsi128_ps(_mm_cvtsi32_si128((Uint16)src[i] ^ 0x43808000u)), offset)); + } + + cvt->len_cvt *= 2; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS); + } +} + +static void SDLCALL SDL_Convert_U16_to_F32_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + const Uint16 *src = ((const Uint16 *)(cvt->buf + cvt->len_cvt)) - 1; + float *dst = ((float *)(cvt->buf + cvt->len_cvt * 2)) - 1; + int i; + + LOG_DEBUG_CONVERT("AUDIO_U16", "AUDIO_F32 (using SSE2)"); + + /* Get dst aligned to 16 bytes (since buffer is growing, we don't have to worry about overreading from src) */ + for (i = cvt->len_cvt / sizeof(Sint16); i && (((size_t)(dst - 7)) & 15); --i, --src, --dst) { + *dst = (((float)*src) * DIVBY32768) - 1.0f; + } + + src -= 7; + dst -= 7; /* adjust to read SSE blocks from the start. */ + SDL_assert(!i || !(((size_t)dst) & 15)); + + /* Make sure src is aligned too. */ + if (!(((size_t)src) & 15)) { + /* Aligned! Do SSE blocks as long as we have 16 bytes available. */ + const __m128 divby32768 = _mm_set1_ps(DIVBY32768); + const __m128 minus1 = _mm_set1_ps(-1.0f); + while (i >= 8) { /* 8 * 16-bit */ + const __m128i ints = _mm_load_si128((__m128i const *)src); /* get 8 sint16 into an XMM register. */ + /* treat as int32, shift left to clear every other sint16, then back right with zero-extend. Now sint32. */ + const __m128i a = _mm_srli_epi32(_mm_slli_epi32(ints, 16), 16); + /* right-shift-sign-extend gets us sint32 with the other set of values. */ + const __m128i b = _mm_srli_epi32(ints, 16); + /* Interleave these back into the right order, convert to float, multiply, store. */ + _mm_store_ps(dst, _mm_add_ps(_mm_mul_ps(_mm_cvtepi32_ps(_mm_unpacklo_epi32(a, b)), divby32768), minus1)); + _mm_store_ps(dst + 4, _mm_add_ps(_mm_mul_ps(_mm_cvtepi32_ps(_mm_unpackhi_epi32(a, b)), divby32768), minus1)); + i -= 8; + src -= 8; + dst -= 8; + } + } + + src += 7; + dst += 7; /* adjust for any scalar finishing. */ + + /* Finish off any leftovers with scalar operations. */ + while (i) { + *dst = (((float)*src) * DIVBY32768) - 1.0f; + i--; + src--; + dst--; + } + + cvt->len_cvt *= 2; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS); + } +} + +static void SDLCALL SDL_Convert_S32_to_F32_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + const Sint32 *src = (const Sint32 *)cvt->buf; + float *dst = (float *)cvt->buf; + int i = cvt->len_cvt / 4; + + /* dst[i] = f32(src[i]) / f32(0x80000000) */ + const __m128 scaler = _mm_set1_ps(DIVBY2147483648); + + LOG_DEBUG_CONVERT("AUDIO_S32", "AUDIO_F32 (using SSE2)"); + + while (i >= 16) { + i -= 16; + + { + const __m128i ints1 = _mm_loadu_si128((const __m128i *)&src[i]); + const __m128i ints2 = _mm_loadu_si128((const __m128i *)&src[i + 4]); + const __m128i ints3 = _mm_loadu_si128((const __m128i *)&src[i + 8]); + const __m128i ints4 = _mm_loadu_si128((const __m128i *)&src[i + 12]); + + const __m128 floats1 = _mm_mul_ps(_mm_cvtepi32_ps(ints1), scaler); + const __m128 floats2 = _mm_mul_ps(_mm_cvtepi32_ps(ints2), scaler); + const __m128 floats3 = _mm_mul_ps(_mm_cvtepi32_ps(ints3), scaler); + const __m128 floats4 = _mm_mul_ps(_mm_cvtepi32_ps(ints4), scaler); + + _mm_storeu_ps(&dst[i], floats1); + _mm_storeu_ps(&dst[i + 4], floats2); + _mm_storeu_ps(&dst[i + 8], floats3); + _mm_storeu_ps(&dst[i + 12], floats4); + } + } + + while (i) { + --i; + _mm_store_ss(&dst[i], _mm_mul_ss(_mm_cvt_si2ss(_mm_setzero_ps(), src[i]), scaler)); + } + + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS); + } +} + +static void SDLCALL SDL_Convert_F32_to_S8_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + const float *src = (const float *)cvt->buf; + Sint8 *dst = (Sint8 *)cvt->buf; + int i = cvt->len_cvt / 4; + + /* 1) Shift the float range from [-1.0, 1.0] to [98303.0, 98305.0] + * 2) Extract the lowest 16 bits and clamp to [-128, 127] + * Overflow is correctly handled for inputs between roughly [-255.0, 255.0] + * dst[i] = clamp(i16(f2i(src[i] + 98304.0) & 0xFFFF), -128, 127) */ + const __m128 offset = _mm_set1_ps(98304.0f); + const __m128i mask = _mm_set1_epi16(0xFF); + + LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_S8 (using SSE2)"); + + while (i >= 16) { + const __m128 floats1 = _mm_loadu_ps(&src[0]); + const __m128 floats2 = _mm_loadu_ps(&src[4]); + const __m128 floats3 = _mm_loadu_ps(&src[8]); + const __m128 floats4 = _mm_loadu_ps(&src[12]); + + const __m128i ints1 = _mm_castps_si128(_mm_add_ps(floats1, offset)); + const __m128i ints2 = _mm_castps_si128(_mm_add_ps(floats2, offset)); + const __m128i ints3 = _mm_castps_si128(_mm_add_ps(floats3, offset)); + const __m128i ints4 = _mm_castps_si128(_mm_add_ps(floats4, offset)); + + const __m128i shorts1 = _mm_and_si128(_mm_packs_epi16(ints1, ints2), mask); + const __m128i shorts2 = _mm_and_si128(_mm_packs_epi16(ints3, ints4), mask); + + const __m128i bytes = _mm_packus_epi16(shorts1, shorts2); + + _mm_storeu_si128((__m128i*)dst, bytes); + + i -= 16; + src += 16; + dst += 16; + } + + while (i) { + const __m128i ints = _mm_castps_si128(_mm_add_ss(_mm_load_ss(src), offset)); + *dst = (Sint8)(_mm_cvtsi128_si32(_mm_packs_epi16(ints, ints)) & 0xFF); + + --i; + ++src; + ++dst; + } + + cvt->len_cvt /= 4; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, AUDIO_S8); + } +} + +static void SDLCALL SDL_Convert_F32_to_U8_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + const float *src = (const float *)cvt->buf; + Uint8 *dst = cvt->buf; + int i = cvt->len_cvt / 4; + + /* 1) Shift the float range from [-1.0, 1.0] to [98304.0, 98306.0] + * 2) Extract the lowest 16 bits and clamp to [0, 255] + * Overflow is correctly handled for inputs between roughly [-254.0, 254.0] + * dst[i] = clamp(i16(f2i(src[i] + 98305.0) & 0xFFFF), 0, 255) */ + const __m128 offset = _mm_set1_ps(98305.0f); + const __m128i mask = _mm_set1_epi16(0xFF); + + LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_U8 (using SSE2)"); + + while (i >= 16) { + const __m128 floats1 = _mm_loadu_ps(&src[0]); + const __m128 floats2 = _mm_loadu_ps(&src[4]); + const __m128 floats3 = _mm_loadu_ps(&src[8]); + const __m128 floats4 = _mm_loadu_ps(&src[12]); + + const __m128i ints1 = _mm_castps_si128(_mm_add_ps(floats1, offset)); + const __m128i ints2 = _mm_castps_si128(_mm_add_ps(floats2, offset)); + const __m128i ints3 = _mm_castps_si128(_mm_add_ps(floats3, offset)); + const __m128i ints4 = _mm_castps_si128(_mm_add_ps(floats4, offset)); + + const __m128i shorts1 = _mm_and_si128(_mm_packus_epi16(ints1, ints2), mask); + const __m128i shorts2 = _mm_and_si128(_mm_packus_epi16(ints3, ints4), mask); + + const __m128i bytes = _mm_packus_epi16(shorts1, shorts2); + + _mm_storeu_si128((__m128i*)dst, bytes); + + i -= 16; + src += 16; + dst += 16; + } + + while (i) { + const __m128i ints = _mm_castps_si128(_mm_add_ss(_mm_load_ss(src), offset)); + *dst = (Uint8)(_mm_cvtsi128_si32(_mm_packus_epi16(ints, ints)) & 0xFF); + + --i; + ++src; + ++dst; + } + + cvt->len_cvt /= 4; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, AUDIO_U8); + } +} + +static void SDLCALL SDL_Convert_F32_to_S16_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + const float *src = (const float *)cvt->buf; + Sint16 *dst = (Sint16 *)cvt->buf; + int i = cvt->len_cvt / 4; + + /* 1) Shift the float range from [-1.0, 1.0] to [256.0, 258.0] + * 2) Shift the int range from [0x43800000, 0x43810000] to [-32768,32768] + * 3) Clamp to range [-32768,32767] + * Overflow is correctly handled for inputs between roughly [-257.0, +inf) + * dst[i] = clamp(f2i(src[i] + 257.0) - 0x43808000, -32768, 32767) */ + const __m128 offset = _mm_set1_ps(257.0f); + + LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_S16 (using SSE2)"); + + while (i >= 16) { + const __m128 floats1 = _mm_loadu_ps(&src[0]); + const __m128 floats2 = _mm_loadu_ps(&src[4]); + const __m128 floats3 = _mm_loadu_ps(&src[8]); + const __m128 floats4 = _mm_loadu_ps(&src[12]); + + const __m128i ints1 = _mm_sub_epi32(_mm_castps_si128(_mm_add_ps(floats1, offset)), _mm_castps_si128(offset)); + const __m128i ints2 = _mm_sub_epi32(_mm_castps_si128(_mm_add_ps(floats2, offset)), _mm_castps_si128(offset)); + const __m128i ints3 = _mm_sub_epi32(_mm_castps_si128(_mm_add_ps(floats3, offset)), _mm_castps_si128(offset)); + const __m128i ints4 = _mm_sub_epi32(_mm_castps_si128(_mm_add_ps(floats4, offset)), _mm_castps_si128(offset)); + + const __m128i shorts1 = _mm_packs_epi32(ints1, ints2); + const __m128i shorts2 = _mm_packs_epi32(ints3, ints4); + + _mm_storeu_si128((__m128i*)&dst[0], shorts1); + _mm_storeu_si128((__m128i*)&dst[8], shorts2); + + i -= 16; + src += 16; + dst += 16; + } + + while (i) { + const __m128i ints = _mm_sub_epi32(_mm_castps_si128(_mm_add_ss(_mm_load_ss(src), offset)), _mm_castps_si128(offset)); + *dst = (Sint16)(_mm_cvtsi128_si32(_mm_packs_epi32(ints, ints)) & 0xFFFF); + + --i; + ++src; + ++dst; + } + + cvt->len_cvt /= 2; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, AUDIO_S16SYS); + } +} + +static void SDLCALL SDL_Convert_F32_to_U16_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + const float *src = (const float *)cvt->buf; + Uint16 *dst = (Uint16 *)cvt->buf; + int i; + + LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_U16 (using SSE2)"); + + /* Get dst aligned to 16 bytes */ + for (i = cvt->len_cvt / sizeof(float); i && (((size_t)dst) & 15); --i, ++src, ++dst) { + const float sample = *src; + if (sample >= 1.0f) { + *dst = 65535; + } else if (sample <= -1.0f) { + *dst = 0; + } else { + *dst = (Uint16)((sample + 1.0f) * 32767.0f); + } + } + + SDL_assert(!i || !(((size_t)dst) & 15)); + + /* Make sure src is aligned too. */ + if (!(((size_t)src) & 15)) { + /* Aligned! Do SSE blocks as long as we have 16 bytes available. */ + /* This calculates differently than the scalar path because SSE2 can't + pack int32 data down to unsigned int16. _mm_packs_epi32 does signed + saturation, so that would corrupt our data. _mm_packus_epi32 exists, + but not before SSE 4.1. So we convert from float to sint16, packing + that down with legit signed saturation, and then xor the top bit + against 1. This results in the correct unsigned 16-bit value, even + though it looks like dark magic. */ + const __m128 mulby32767 = _mm_set1_ps(32767.0f); + const __m128i topbit = _mm_set1_epi16(-32768); + const __m128 one = _mm_set1_ps(1.0f); + const __m128 negone = _mm_set1_ps(-1.0f); + __m128i *mmdst = (__m128i *)dst; + while (i >= 8) { /* 8 * float32 */ + const __m128i ints1 = _mm_cvtps_epi32(_mm_mul_ps(_mm_min_ps(_mm_max_ps(negone, _mm_load_ps(src)), one), mulby32767)); /* load 4 floats, clamp, convert to sint32 */ + const __m128i ints2 = _mm_cvtps_epi32(_mm_mul_ps(_mm_min_ps(_mm_max_ps(negone, _mm_load_ps(src + 4)), one), mulby32767)); /* load 4 floats, clamp, convert to sint32 */ + _mm_store_si128(mmdst, _mm_xor_si128(_mm_packs_epi32(ints1, ints2), topbit)); /* pack to sint16, xor top bit, store out. */ + i -= 8; + src += 8; + mmdst++; + } + dst = (Uint16 *)mmdst; + } + + /* Finish off any leftovers with scalar operations. */ + while (i) { + const float sample = *src; + if (sample >= 1.0f) { + *dst = 65535; + } else if (sample <= -1.0f) { + *dst = 0; + } else { + *dst = (Uint16)((sample + 1.0f) * 32767.0f); + } + i--; + src++; + dst++; + } + + cvt->len_cvt /= 2; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, AUDIO_U16SYS); + } +} + +static void SDLCALL SDL_Convert_F32_to_S32_SSE2(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + const float *src = (const float *)cvt->buf; + Sint32 *dst = (Sint32 *)cvt->buf; + int i = cvt->len_cvt / 4; + + /* 1) Scale the float range from [-1.0, 1.0] to [-2147483648.0, 2147483648.0] + * 2) Convert to integer (values too small/large become 0x80000000 = -2147483648) + * 3) Fixup values which were too large (0x80000000 ^ 0xFFFFFFFF = 2147483647) + * dst[i] = i32(src[i] * 2147483648.0) ^ ((src[i] >= 2147483648.0) ? 0xFFFFFFFF : 0x00000000) */ + const __m128 limit = _mm_set1_ps(2147483648.0f); + + LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_S32 (using SSE2)"); + + while (i >= 16) { + const __m128 floats1 = _mm_loadu_ps(&src[0]); + const __m128 floats2 = _mm_loadu_ps(&src[4]); + const __m128 floats3 = _mm_loadu_ps(&src[8]); + const __m128 floats4 = _mm_loadu_ps(&src[12]); + + const __m128 values1 = _mm_mul_ps(floats1, limit); + const __m128 values2 = _mm_mul_ps(floats2, limit); + const __m128 values3 = _mm_mul_ps(floats3, limit); + const __m128 values4 = _mm_mul_ps(floats4, limit); + + const __m128i ints1 = _mm_xor_si128(_mm_cvttps_epi32(values1), _mm_castps_si128(_mm_cmpge_ps(values1, limit))); + const __m128i ints2 = _mm_xor_si128(_mm_cvttps_epi32(values2), _mm_castps_si128(_mm_cmpge_ps(values2, limit))); + const __m128i ints3 = _mm_xor_si128(_mm_cvttps_epi32(values3), _mm_castps_si128(_mm_cmpge_ps(values3, limit))); + const __m128i ints4 = _mm_xor_si128(_mm_cvttps_epi32(values4), _mm_castps_si128(_mm_cmpge_ps(values4, limit))); + + _mm_storeu_si128((__m128i*)&dst[0], ints1); + _mm_storeu_si128((__m128i*)&dst[4], ints2); + _mm_storeu_si128((__m128i*)&dst[8], ints3); + _mm_storeu_si128((__m128i*)&dst[12], ints4); + + i -= 16; + src += 16; + dst += 16; + } + + while (i) { + const __m128 floats = _mm_load_ss(src); + const __m128 values = _mm_mul_ss(floats, limit); + const __m128i ints = _mm_xor_si128(_mm_cvttps_epi32(values), _mm_castps_si128(_mm_cmpge_ss(values, limit))); + *dst = (Sint32)_mm_cvtsi128_si32(ints); + + --i; + ++src; + ++dst; + } + + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, AUDIO_S32SYS); + } +} +#endif + +#ifdef HAVE_NEON_INTRINSICS +static void SDLCALL SDL_Convert_S8_to_F32_NEON(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + const Sint8 *src = ((const Sint8 *)(cvt->buf + cvt->len_cvt)) - 1; + float *dst = ((float *)(cvt->buf + cvt->len_cvt * 4)) - 1; + int i; + + LOG_DEBUG_CONVERT("AUDIO_S8", "AUDIO_F32 (using NEON)"); + + /* Get dst aligned to 16 bytes (since buffer is growing, we don't have to worry about overreading from src) */ + for (i = cvt->len_cvt; i && (((size_t)(dst - 15)) & 15); --i, --src, --dst) { + *dst = ((float)*src) * DIVBY128; + } + + src -= 15; + dst -= 15; /* adjust to read NEON blocks from the start. */ + SDL_assert(!i || !(((size_t)dst) & 15)); + + /* Make sure src is aligned too. */ + if (!(((size_t)src) & 15)) { + /* Aligned! Do NEON blocks as long as we have 16 bytes available. */ + const int8_t *mmsrc = (const int8_t *)src; + const float32x4_t divby128 = vdupq_n_f32(DIVBY128); + while (i >= 16) { /* 16 * 8-bit */ + const int8x16_t bytes = vld1q_s8(mmsrc); /* get 16 sint8 into a NEON register. */ + const int16x8_t int16hi = vmovl_s8(vget_high_s8(bytes)); /* convert top 8 bytes to 8 int16 */ + const int16x8_t int16lo = vmovl_s8(vget_low_s8(bytes)); /* convert bottom 8 bytes to 8 int16 */ + /* split int16 to two int32, then convert to float, then multiply to normalize, store. */ + vst1q_f32(dst, vmulq_f32(vcvtq_f32_s32(vmovl_s16(vget_low_s16(int16lo))), divby128)); + vst1q_f32(dst + 4, vmulq_f32(vcvtq_f32_s32(vmovl_s16(vget_high_s16(int16lo))), divby128)); + vst1q_f32(dst + 8, vmulq_f32(vcvtq_f32_s32(vmovl_s16(vget_low_s16(int16hi))), divby128)); + vst1q_f32(dst + 12, vmulq_f32(vcvtq_f32_s32(vmovl_s16(vget_high_s16(int16hi))), divby128)); + i -= 16; + mmsrc -= 16; + dst -= 16; + } + + src = (const Sint8 *)mmsrc; + } + + src += 15; + dst += 15; /* adjust for any scalar finishing. */ + + /* Finish off any leftovers with scalar operations. */ + while (i) { + *dst = ((float)*src) * DIVBY128; + i--; + src--; + dst--; + } + + cvt->len_cvt *= 4; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS); + } +} + +static void SDLCALL SDL_Convert_U8_to_F32_NEON(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + const Uint8 *src = ((const Uint8 *)(cvt->buf + cvt->len_cvt)) - 1; + float *dst = ((float *)(cvt->buf + cvt->len_cvt * 4)) - 1; + int i; + + LOG_DEBUG_CONVERT("AUDIO_U8", "AUDIO_F32 (using NEON)"); + + /* Get dst aligned to 16 bytes (since buffer is growing, we don't have to worry about overreading from src) */ + for (i = cvt->len_cvt; i && (((size_t)(dst - 15)) & 15); --i, --src, --dst) { + *dst = (((float)*src) * DIVBY128) - 1.0f; + } + + src -= 15; + dst -= 15; /* adjust to read NEON blocks from the start. */ + SDL_assert(!i || !(((size_t)dst) & 15)); + + /* Make sure src is aligned too. */ + if (!(((size_t)src) & 15)) { + /* Aligned! Do NEON blocks as long as we have 16 bytes available. */ + const uint8_t *mmsrc = (const uint8_t *)src; + const float32x4_t divby128 = vdupq_n_f32(DIVBY128); + const float32x4_t negone = vdupq_n_f32(-1.0f); + while (i >= 16) { /* 16 * 8-bit */ + const uint8x16_t bytes = vld1q_u8(mmsrc); /* get 16 uint8 into a NEON register. */ + const uint16x8_t uint16hi = vmovl_u8(vget_high_u8(bytes)); /* convert top 8 bytes to 8 uint16 */ + const uint16x8_t uint16lo = vmovl_u8(vget_low_u8(bytes)); /* convert bottom 8 bytes to 8 uint16 */ + /* split uint16 to two uint32, then convert to float, then multiply to normalize, subtract to adjust for sign, store. */ + vst1q_f32(dst, vmlaq_f32(negone, vcvtq_f32_u32(vmovl_u16(vget_low_u16(uint16lo))), divby128)); + vst1q_f32(dst + 4, vmlaq_f32(negone, vcvtq_f32_u32(vmovl_u16(vget_high_u16(uint16lo))), divby128)); + vst1q_f32(dst + 8, vmlaq_f32(negone, vcvtq_f32_u32(vmovl_u16(vget_low_u16(uint16hi))), divby128)); + vst1q_f32(dst + 12, vmlaq_f32(negone, vcvtq_f32_u32(vmovl_u16(vget_high_u16(uint16hi))), divby128)); + i -= 16; + mmsrc -= 16; + dst -= 16; + } + + src = (const Uint8 *)mmsrc; + } + + src += 15; + dst += 15; /* adjust for any scalar finishing. */ + + /* Finish off any leftovers with scalar operations. */ + while (i) { + *dst = (((float)*src) * DIVBY128) - 1.0f; + i--; + src--; + dst--; + } + + cvt->len_cvt *= 4; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS); + } +} + +static void SDLCALL SDL_Convert_S16_to_F32_NEON(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + const Sint16 *src = ((const Sint16 *)(cvt->buf + cvt->len_cvt)) - 1; + float *dst = ((float *)(cvt->buf + cvt->len_cvt * 2)) - 1; + int i; + + LOG_DEBUG_CONVERT("AUDIO_S16", "AUDIO_F32 (using NEON)"); + + /* Get dst aligned to 16 bytes (since buffer is growing, we don't have to worry about overreading from src) */ + for (i = cvt->len_cvt / sizeof(Sint16); i && (((size_t)(dst - 7)) & 15); --i, --src, --dst) { + *dst = ((float)*src) * DIVBY32768; + } + + src -= 7; + dst -= 7; /* adjust to read NEON blocks from the start. */ + SDL_assert(!i || !(((size_t)dst) & 15)); + + /* Make sure src is aligned too. */ + if (!(((size_t)src) & 15)) { + /* Aligned! Do NEON blocks as long as we have 16 bytes available. */ + const float32x4_t divby32768 = vdupq_n_f32(DIVBY32768); + while (i >= 8) { /* 8 * 16-bit */ + const int16x8_t ints = vld1q_s16((int16_t const *)src); /* get 8 sint16 into a NEON register. */ + /* split int16 to two int32, then convert to float, then multiply to normalize, store. */ + vst1q_f32(dst, vmulq_f32(vcvtq_f32_s32(vmovl_s16(vget_low_s16(ints))), divby32768)); + vst1q_f32(dst + 4, vmulq_f32(vcvtq_f32_s32(vmovl_s16(vget_high_s16(ints))), divby32768)); + i -= 8; + src -= 8; + dst -= 8; + } + } + + src += 7; + dst += 7; /* adjust for any scalar finishing. */ + + /* Finish off any leftovers with scalar operations. */ + while (i) { + *dst = ((float)*src) * DIVBY32768; + i--; + src--; + dst--; + } + + cvt->len_cvt *= 2; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS); + } +} + +static void SDLCALL SDL_Convert_U16_to_F32_NEON(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + const Uint16 *src = ((const Uint16 *)(cvt->buf + cvt->len_cvt)) - 1; + float *dst = ((float *)(cvt->buf + cvt->len_cvt * 2)) - 1; + int i; + + LOG_DEBUG_CONVERT("AUDIO_U16", "AUDIO_F32 (using NEON)"); + + /* Get dst aligned to 16 bytes (since buffer is growing, we don't have to worry about overreading from src) */ + for (i = cvt->len_cvt / sizeof(Sint16); i && (((size_t)(dst - 7)) & 15); --i, --src, --dst) { + *dst = (((float)*src) * DIVBY32768) - 1.0f; + } + + src -= 7; + dst -= 7; /* adjust to read NEON blocks from the start. */ + SDL_assert(!i || !(((size_t)dst) & 15)); + + /* Make sure src is aligned too. */ + if (!(((size_t)src) & 15)) { + /* Aligned! Do NEON blocks as long as we have 16 bytes available. */ + const float32x4_t divby32768 = vdupq_n_f32(DIVBY32768); + const float32x4_t negone = vdupq_n_f32(-1.0f); + while (i >= 8) { /* 8 * 16-bit */ + const uint16x8_t uints = vld1q_u16((uint16_t const *)src); /* get 8 uint16 into a NEON register. */ + /* split uint16 to two int32, then convert to float, then multiply to normalize, subtract for sign, store. */ + vst1q_f32(dst, vmlaq_f32(negone, vcvtq_f32_u32(vmovl_u16(vget_low_u16(uints))), divby32768)); + vst1q_f32(dst + 4, vmlaq_f32(negone, vcvtq_f32_u32(vmovl_u16(vget_high_u16(uints))), divby32768)); + i -= 8; + src -= 8; + dst -= 8; + } + } + + src += 7; + dst += 7; /* adjust for any scalar finishing. */ + + /* Finish off any leftovers with scalar operations. */ + while (i) { + *dst = (((float)*src) * DIVBY32768) - 1.0f; + i--; + src--; + dst--; + } + + cvt->len_cvt *= 2; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS); + } +} + +static void SDLCALL SDL_Convert_S32_to_F32_NEON(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + const Sint32 *src = (const Sint32 *)cvt->buf; + float *dst = (float *)cvt->buf; + int i; + + LOG_DEBUG_CONVERT("AUDIO_S32", "AUDIO_F32 (using NEON)"); + + /* Get dst aligned to 16 bytes */ + for (i = cvt->len_cvt / sizeof(Sint32); i && (((size_t)dst) & 15); --i, ++src, ++dst) { + *dst = ((float)(*src >> 8)) * DIVBY8388607; + } + + SDL_assert(!i || !(((size_t)dst) & 15)); + + /* Make sure src is aligned too. */ + if (!(((size_t)src) & 15)) { + /* Aligned! Do NEON blocks as long as we have 16 bytes available. */ + const float32x4_t divby8388607 = vdupq_n_f32(DIVBY8388607); + const int32_t *mmsrc = (const int32_t *)src; + while (i >= 4) { /* 4 * sint32 */ + /* shift out lowest bits so int fits in a float32. Small precision loss, but much faster. */ + vst1q_f32(dst, vmulq_f32(vcvtq_f32_s32(vshrq_n_s32(vld1q_s32(mmsrc), 8)), divby8388607)); + i -= 4; + mmsrc += 4; + dst += 4; + } + src = (const Sint32 *)mmsrc; + } + + /* Finish off any leftovers with scalar operations. */ + while (i) { + *dst = ((float)(*src >> 8)) * DIVBY8388607; + i--; + src++; + dst++; + } + + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, AUDIO_F32SYS); + } +} + +static void SDLCALL SDL_Convert_F32_to_S8_NEON(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + const float *src = (const float *)cvt->buf; + Sint8 *dst = (Sint8 *)cvt->buf; + int i; + + LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_S8 (using NEON)"); + + /* Get dst aligned to 16 bytes */ + for (i = cvt->len_cvt / sizeof(float); i && (((size_t)dst) & 15); --i, ++src, ++dst) { + const float sample = *src; + if (sample >= 1.0f) { + *dst = 127; + } else if (sample <= -1.0f) { + *dst = -128; + } else { + *dst = (Sint8)(sample * 127.0f); + } + } + + SDL_assert(!i || !(((size_t)dst) & 15)); + + /* Make sure src is aligned too. */ + if (!(((size_t)src) & 15)) { + /* Aligned! Do NEON blocks as long as we have 16 bytes available. */ + const float32x4_t one = vdupq_n_f32(1.0f); + const float32x4_t negone = vdupq_n_f32(-1.0f); + const float32x4_t mulby127 = vdupq_n_f32(127.0f); + int8_t *mmdst = (int8_t *)dst; + while (i >= 16) { /* 16 * float32 */ + const int32x4_t ints1 = vcvtq_s32_f32(vmulq_f32(vminq_f32(vmaxq_f32(negone, vld1q_f32(src)), one), mulby127)); /* load 4 floats, clamp, convert to sint32 */ + const int32x4_t ints2 = vcvtq_s32_f32(vmulq_f32(vminq_f32(vmaxq_f32(negone, vld1q_f32(src + 4)), one), mulby127)); /* load 4 floats, clamp, convert to sint32 */ + const int32x4_t ints3 = vcvtq_s32_f32(vmulq_f32(vminq_f32(vmaxq_f32(negone, vld1q_f32(src + 8)), one), mulby127)); /* load 4 floats, clamp, convert to sint32 */ + const int32x4_t ints4 = vcvtq_s32_f32(vmulq_f32(vminq_f32(vmaxq_f32(negone, vld1q_f32(src + 12)), one), mulby127)); /* load 4 floats, clamp, convert to sint32 */ + const int8x8_t i8lo = vmovn_s16(vcombine_s16(vmovn_s32(ints1), vmovn_s32(ints2))); /* narrow to sint16, combine, narrow to sint8 */ + const int8x8_t i8hi = vmovn_s16(vcombine_s16(vmovn_s32(ints3), vmovn_s32(ints4))); /* narrow to sint16, combine, narrow to sint8 */ + vst1q_s8(mmdst, vcombine_s8(i8lo, i8hi)); /* combine to int8x16_t, store out */ + i -= 16; + src += 16; + mmdst += 16; + } + dst = (Sint8 *)mmdst; + } + + /* Finish off any leftovers with scalar operations. */ + while (i) { + const float sample = *src; + if (sample >= 1.0f) { + *dst = 127; + } else if (sample <= -1.0f) { + *dst = -128; + } else { + *dst = (Sint8)(sample * 127.0f); + } + i--; + src++; + dst++; + } + + cvt->len_cvt /= 4; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, AUDIO_S8); + } +} + +static void SDLCALL SDL_Convert_F32_to_U8_NEON(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + const float *src = (const float *)cvt->buf; + Uint8 *dst = cvt->buf; + int i; + + LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_U8 (using NEON)"); + + /* Get dst aligned to 16 bytes */ + for (i = cvt->len_cvt / sizeof(float); i && (((size_t)dst) & 15); --i, ++src, ++dst) { + 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); + } + } + + SDL_assert(!i || !(((size_t)dst) & 15)); + + /* Make sure src is aligned too. */ + if (!(((size_t)src) & 15)) { + /* Aligned! Do NEON blocks as long as we have 16 bytes available. */ + const float32x4_t one = vdupq_n_f32(1.0f); + const float32x4_t negone = vdupq_n_f32(-1.0f); + const float32x4_t mulby127 = vdupq_n_f32(127.0f); + uint8_t *mmdst = (uint8_t *)dst; + while (i >= 16) { /* 16 * float32 */ + const uint32x4_t uints1 = vcvtq_u32_f32(vmulq_f32(vaddq_f32(vminq_f32(vmaxq_f32(negone, vld1q_f32(src)), one), one), mulby127)); /* load 4 floats, clamp, convert to uint32 */ + const uint32x4_t uints2 = vcvtq_u32_f32(vmulq_f32(vaddq_f32(vminq_f32(vmaxq_f32(negone, vld1q_f32(src + 4)), one), one), mulby127)); /* load 4 floats, clamp, convert to uint32 */ + const uint32x4_t uints3 = vcvtq_u32_f32(vmulq_f32(vaddq_f32(vminq_f32(vmaxq_f32(negone, vld1q_f32(src + 8)), one), one), mulby127)); /* load 4 floats, clamp, convert to uint32 */ + const uint32x4_t uints4 = vcvtq_u32_f32(vmulq_f32(vaddq_f32(vminq_f32(vmaxq_f32(negone, vld1q_f32(src + 12)), one), one), mulby127)); /* load 4 floats, clamp, convert to uint32 */ + const uint8x8_t ui8lo = vmovn_u16(vcombine_u16(vmovn_u32(uints1), vmovn_u32(uints2))); /* narrow to uint16, combine, narrow to uint8 */ + const uint8x8_t ui8hi = vmovn_u16(vcombine_u16(vmovn_u32(uints3), vmovn_u32(uints4))); /* narrow to uint16, combine, narrow to uint8 */ + vst1q_u8(mmdst, vcombine_u8(ui8lo, ui8hi)); /* combine to uint8x16_t, store out */ + i -= 16; + src += 16; + mmdst += 16; + } + + dst = (Uint8 *)mmdst; + } + + /* Finish off any leftovers with scalar operations. */ + while (i) { + 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); + } + i--; + src++; + dst++; + } + + cvt->len_cvt /= 4; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, AUDIO_U8); + } +} + +static void SDLCALL SDL_Convert_F32_to_S16_NEON(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + const float *src = (const float *)cvt->buf; + Sint16 *dst = (Sint16 *)cvt->buf; + int i; + + LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_S16 (using NEON)"); + + /* Get dst aligned to 16 bytes */ + for (i = cvt->len_cvt / sizeof(float); i && (((size_t)dst) & 15); --i, ++src, ++dst) { + const float sample = *src; + if (sample >= 1.0f) { + *dst = 32767; + } else if (sample <= -1.0f) { + *dst = -32768; + } else { + *dst = (Sint16)(sample * 32767.0f); + } + } + + SDL_assert(!i || !(((size_t)dst) & 15)); + + /* Make sure src is aligned too. */ + if (!(((size_t)src) & 15)) { + /* Aligned! Do NEON blocks as long as we have 16 bytes available. */ + const float32x4_t one = vdupq_n_f32(1.0f); + const float32x4_t negone = vdupq_n_f32(-1.0f); + const float32x4_t mulby32767 = vdupq_n_f32(32767.0f); + int16_t *mmdst = (int16_t *)dst; + while (i >= 8) { /* 8 * float32 */ + const int32x4_t ints1 = vcvtq_s32_f32(vmulq_f32(vminq_f32(vmaxq_f32(negone, vld1q_f32(src)), one), mulby32767)); /* load 4 floats, clamp, convert to sint32 */ + const int32x4_t ints2 = vcvtq_s32_f32(vmulq_f32(vminq_f32(vmaxq_f32(negone, vld1q_f32(src + 4)), one), mulby32767)); /* load 4 floats, clamp, convert to sint32 */ + vst1q_s16(mmdst, vcombine_s16(vmovn_s32(ints1), vmovn_s32(ints2))); /* narrow to sint16, combine, store out. */ + i -= 8; + src += 8; + mmdst += 8; + } + dst = (Sint16 *)mmdst; + } + + /* Finish off any leftovers with scalar operations. */ + while (i) { + const float sample = *src; + if (sample >= 1.0f) { + *dst = 32767; + } else if (sample <= -1.0f) { + *dst = -32768; + } else { + *dst = (Sint16)(sample * 32767.0f); + } + i--; + src++; + dst++; + } + + cvt->len_cvt /= 2; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, AUDIO_S16SYS); + } +} + +static void SDLCALL SDL_Convert_F32_to_U16_NEON(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + const float *src = (const float *)cvt->buf; + Uint16 *dst = (Uint16 *)cvt->buf; + int i; + + LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_U16 (using NEON)"); + + /* Get dst aligned to 16 bytes */ + for (i = cvt->len_cvt / sizeof(float); i && (((size_t)dst) & 15); --i, ++src, ++dst) { + const float sample = *src; + if (sample >= 1.0f) { + *dst = 65535; + } else if (sample <= -1.0f) { + *dst = 0; + } else { + *dst = (Uint16)((sample + 1.0f) * 32767.0f); + } + } + + SDL_assert(!i || !(((size_t)dst) & 15)); + + /* Make sure src is aligned too. */ + if (!(((size_t)src) & 15)) { + /* Aligned! Do NEON blocks as long as we have 16 bytes available. */ + const float32x4_t one = vdupq_n_f32(1.0f); + const float32x4_t negone = vdupq_n_f32(-1.0f); + const float32x4_t mulby32767 = vdupq_n_f32(32767.0f); + uint16_t *mmdst = (uint16_t *)dst; + while (i >= 8) { /* 8 * float32 */ + const uint32x4_t uints1 = vcvtq_u32_f32(vmulq_f32(vaddq_f32(vminq_f32(vmaxq_f32(negone, vld1q_f32(src)), one), one), mulby32767)); /* load 4 floats, clamp, convert to uint32 */ + const uint32x4_t uints2 = vcvtq_u32_f32(vmulq_f32(vaddq_f32(vminq_f32(vmaxq_f32(negone, vld1q_f32(src + 4)), one), one), mulby32767)); /* load 4 floats, clamp, convert to uint32 */ + vst1q_u16(mmdst, vcombine_u16(vmovn_u32(uints1), vmovn_u32(uints2))); /* narrow to uint16, combine, store out. */ + i -= 8; + src += 8; + mmdst += 8; + } + dst = (Uint16 *)mmdst; + } + + /* Finish off any leftovers with scalar operations. */ + while (i) { + const float sample = *src; + if (sample >= 1.0f) { + *dst = 65535; + } else if (sample <= -1.0f) { + *dst = 0; + } else { + *dst = (Uint16)((sample + 1.0f) * 32767.0f); + } + i--; + src++; + dst++; + } + + cvt->len_cvt /= 2; + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, AUDIO_U16SYS); + } +} + +static void SDLCALL SDL_Convert_F32_to_S32_NEON(SDL_AudioCVT *cvt, SDL_AudioFormat format) +{ + const float *src = (const float *)cvt->buf; + Sint32 *dst = (Sint32 *)cvt->buf; + int i; + + LOG_DEBUG_CONVERT("AUDIO_F32", "AUDIO_S32 (using NEON)"); + + /* Get dst aligned to 16 bytes */ + for (i = cvt->len_cvt / sizeof(float); i && (((size_t)dst) & 15); --i, ++src, ++dst) { + const float sample = *src; + if (sample >= 1.0f) { + *dst = 2147483647; + } else if (sample <= -1.0f) { + *dst = (-2147483647) - 1; + } else { + *dst = ((Sint32)(sample * 8388607.0f)) << 8; + } + } + + SDL_assert(!i || !(((size_t)dst) & 15)); + SDL_assert(!i || !(((size_t)src) & 15)); + + { + /* Aligned! Do NEON blocks as long as we have 16 bytes available. */ + const float32x4_t one = vdupq_n_f32(1.0f); + const float32x4_t negone = vdupq_n_f32(-1.0f); + const float32x4_t mulby8388607 = vdupq_n_f32(8388607.0f); + int32_t *mmdst = (int32_t *)dst; + while (i >= 4) { /* 4 * float32 */ + vst1q_s32(mmdst, vshlq_n_s32(vcvtq_s32_f32(vmulq_f32(vminq_f32(vmaxq_f32(negone, vld1q_f32(src)), one), mulby8388607)), 8)); + i -= 4; + src += 4; + mmdst += 4; + } + dst = (Sint32 *)mmdst; + } + + /* Finish off any leftovers with scalar operations. */ + while (i) { + const float sample = *src; + if (sample >= 1.0f) { + *dst = 2147483647; + } else if (sample <= -1.0f) { + *dst = (-2147483647) - 1; + } else { + *dst = ((Sint32)(sample * 8388607.0f)) << 8; + } + i--; + src++; + dst++; + } + + if (cvt->filters[++cvt->filter_index]) { + cvt->filters[cvt->filter_index](cvt, AUDIO_S32SYS); + } +} +#endif + +void SDL_ChooseAudioConverters(void) +{ + static SDL_bool converters_chosen = SDL_FALSE; + + if (converters_chosen) { + return; + } + +#define SET_CONVERTER_FUNCS(fntype) \ + SDL_Convert_S8_to_F32 = SDL_Convert_S8_to_F32_##fntype; \ + SDL_Convert_U8_to_F32 = SDL_Convert_U8_to_F32_##fntype; \ + SDL_Convert_S16_to_F32 = SDL_Convert_S16_to_F32_##fntype; \ + SDL_Convert_U16_to_F32 = SDL_Convert_U16_to_F32_##fntype; \ + SDL_Convert_S32_to_F32 = SDL_Convert_S32_to_F32_##fntype; \ + SDL_Convert_F32_to_S8 = SDL_Convert_F32_to_S8_##fntype; \ + SDL_Convert_F32_to_U8 = SDL_Convert_F32_to_U8_##fntype; \ + SDL_Convert_F32_to_S16 = SDL_Convert_F32_to_S16_##fntype; \ + SDL_Convert_F32_to_U16 = SDL_Convert_F32_to_U16_##fntype; \ + SDL_Convert_F32_to_S32 = SDL_Convert_F32_to_S32_##fntype; \ + converters_chosen = SDL_TRUE + +#ifdef HAVE_SSE2_INTRINSICS + if (SDL_HasSSE2()) { + SET_CONVERTER_FUNCS(SSE2); + return; + } +#endif + +#ifdef HAVE_NEON_INTRINSICS + if (SDL_HasNEON()) { + SET_CONVERTER_FUNCS(NEON); + return; + } +#endif + +#if NEED_SCALAR_CONVERTER_FALLBACKS + SET_CONVERTER_FUNCS(Scalar); +#endif + +#undef SET_CONVERTER_FUNCS + + SDL_assert(converters_chosen == SDL_TRUE); +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/audio/SDL_mixer.c b/SDL2-2.30.5/src/audio/SDL_mixer.c new file mode 100644 index 0000000..9cf96a6 --- /dev/null +++ b/SDL2-2.30.5/src/audio/SDL_mixer.c @@ -0,0 +1,345 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +/* This provides the default mixing callback for the SDL audio routines */ + +#include "SDL_cpuinfo.h" +#include "SDL_timer.h" +#include "SDL_audio.h" +#include "SDL_sysaudio.h" + +/* This table is used to add two sound values together and pin + * the value to avoid overflow. (used with permission from ARDI) + */ +static const Uint8 mix8[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, + 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, + 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, + 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, + 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, + 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, + 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, + 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, + 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, + 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, + 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, + 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, + 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, + 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, + 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, + 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, + 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, + 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, + 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; + +/* The volume ranges from 0 - 128 */ +#define ADJUST_VOLUME(s, v) (s = (s * v) / SDL_MIX_MAXVOLUME) +#define ADJUST_VOLUME_U8(s, v) (s = (((s - 128) * v) / SDL_MIX_MAXVOLUME) + 128) +#define ADJUST_VOLUME_U16(s, v) (s = (((s - 32768) * v) / SDL_MIX_MAXVOLUME) + 32768) + +void SDL_MixAudioFormat(Uint8 *dst, const Uint8 *src, SDL_AudioFormat format, + Uint32 len, int volume) +{ + if (volume == 0) { + return; + } + + switch (format) { + + case AUDIO_U8: + { + Uint8 src_sample; + + while (len--) { + src_sample = *src; + ADJUST_VOLUME_U8(src_sample, volume); + *dst = mix8[*dst + src_sample]; + ++dst; + ++src; + } + } break; + + case AUDIO_S8: + { + Sint8 *dst8, *src8; + Sint8 src_sample; + int dst_sample; + const int max_audioval = SDL_MAX_SINT8; + const int min_audioval = SDL_MIN_SINT8; + + src8 = (Sint8 *)src; + dst8 = (Sint8 *)dst; + while (len--) { + src_sample = *src8; + ADJUST_VOLUME(src_sample, volume); + dst_sample = *dst8 + src_sample; + if (dst_sample > max_audioval) { + dst_sample = max_audioval; + } else if (dst_sample < min_audioval) { + dst_sample = min_audioval; + } + *dst8 = dst_sample; + ++dst8; + ++src8; + } + } break; + + case AUDIO_S16LSB: + { + Sint16 src1, src2; + int dst_sample; + const int max_audioval = SDL_MAX_SINT16; + const int min_audioval = SDL_MIN_SINT16; + + len /= 2; + while (len--) { + src1 = SDL_SwapLE16(*(Sint16 *)src); + ADJUST_VOLUME(src1, volume); + src2 = SDL_SwapLE16(*(Sint16 *)dst); + src += 2; + dst_sample = src1 + src2; + if (dst_sample > max_audioval) { + dst_sample = max_audioval; + } else if (dst_sample < min_audioval) { + dst_sample = min_audioval; + } + *(Sint16 *)dst = SDL_SwapLE16(dst_sample); + dst += 2; + } + } break; + + case AUDIO_S16MSB: + { + Sint16 src1, src2; + int dst_sample; + const int max_audioval = SDL_MAX_SINT16; + const int min_audioval = SDL_MIN_SINT16; + + len /= 2; + while (len--) { + src1 = SDL_SwapBE16(*(Sint16 *)src); + ADJUST_VOLUME(src1, volume); + src2 = SDL_SwapBE16(*(Sint16 *)dst); + src += 2; + dst_sample = src1 + src2; + if (dst_sample > max_audioval) { + dst_sample = max_audioval; + } else if (dst_sample < min_audioval) { + dst_sample = min_audioval; + } + *(Sint16 *)dst = SDL_SwapBE16(dst_sample); + dst += 2; + } + } break; + + case AUDIO_U16LSB: + { + Uint16 src1, src2; + int dst_sample; + const int max_audioval = SDL_MAX_SINT16; + const int min_audioval = SDL_MIN_SINT16; + + len /= 2; + while (len--) { + src1 = SDL_SwapLE16(*(Uint16 *)src); + ADJUST_VOLUME_U16(src1, volume); + src2 = SDL_SwapLE16(*(Uint16 *)dst); + src += 2; + dst_sample = src1 + src2 - 32768 * 2; + if (dst_sample > max_audioval) { + dst_sample = max_audioval; + } else if (dst_sample < min_audioval) { + dst_sample = min_audioval; + } + dst_sample += 32768; + *(Uint16 *)dst = SDL_SwapLE16(dst_sample); + dst += 2; + } + } break; + + case AUDIO_U16MSB: + { + Uint16 src1, src2; + int dst_sample; + const int max_audioval = SDL_MAX_SINT16; + const int min_audioval = SDL_MIN_SINT16; + + len /= 2; + while (len--) { + src1 = SDL_SwapBE16(*(Uint16 *)src); + ADJUST_VOLUME_U16(src1, volume); + src2 = SDL_SwapBE16(*(Uint16 *)dst); + src += 2; + dst_sample = src1 + src2 - 32768 * 2; + if (dst_sample > max_audioval) { + dst_sample = max_audioval; + } else if (dst_sample < min_audioval) { + dst_sample = min_audioval; + } + dst_sample += 32768; + *(Uint16 *)dst = SDL_SwapBE16(dst_sample); + dst += 2; + } + } break; + + case AUDIO_S32LSB: + { + const Uint32 *src32 = (Uint32 *)src; + Uint32 *dst32 = (Uint32 *)dst; + Sint64 src1, src2; + Sint64 dst_sample; + const Sint64 max_audioval = SDL_MAX_SINT32; + const Sint64 min_audioval = SDL_MIN_SINT32; + + len /= 4; + while (len--) { + src1 = (Sint64)((Sint32)SDL_SwapLE32(*src32)); + src32++; + ADJUST_VOLUME(src1, volume); + src2 = (Sint64)((Sint32)SDL_SwapLE32(*dst32)); + dst_sample = src1 + src2; + if (dst_sample > max_audioval) { + dst_sample = max_audioval; + } else if (dst_sample < min_audioval) { + dst_sample = min_audioval; + } + *(dst32++) = SDL_SwapLE32((Uint32)((Sint32)dst_sample)); + } + } break; + + case AUDIO_S32MSB: + { + const Uint32 *src32 = (Uint32 *)src; + Uint32 *dst32 = (Uint32 *)dst; + Sint64 src1, src2; + Sint64 dst_sample; + const Sint64 max_audioval = SDL_MAX_SINT32; + const Sint64 min_audioval = SDL_MIN_SINT32; + + len /= 4; + while (len--) { + src1 = (Sint64)((Sint32)SDL_SwapBE32(*src32)); + src32++; + ADJUST_VOLUME(src1, volume); + src2 = (Sint64)((Sint32)SDL_SwapBE32(*dst32)); + dst_sample = src1 + src2; + if (dst_sample > max_audioval) { + dst_sample = max_audioval; + } else if (dst_sample < min_audioval) { + dst_sample = min_audioval; + } + *(dst32++) = SDL_SwapBE32((Uint32)((Sint32)dst_sample)); + } + } break; + + case AUDIO_F32LSB: + { + const float fmaxvolume = 1.0f / ((float)SDL_MIX_MAXVOLUME); + const float fvolume = (float)volume; + const float *src32 = (float *)src; + float *dst32 = (float *)dst; + float src1, src2; + double dst_sample; + /* !!! FIXME: are these right? */ + const double max_audioval = 3.402823466e+38F; + const double min_audioval = -3.402823466e+38F; + + len /= 4; + while (len--) { + src1 = ((SDL_SwapFloatLE(*src32) * fvolume) * fmaxvolume); + src2 = SDL_SwapFloatLE(*dst32); + src32++; + + dst_sample = ((double)src1) + ((double)src2); + if (dst_sample > max_audioval) { + dst_sample = max_audioval; + } else if (dst_sample < min_audioval) { + dst_sample = min_audioval; + } + *(dst32++) = SDL_SwapFloatLE((float)dst_sample); + } + } break; + + case AUDIO_F32MSB: + { + const float fmaxvolume = 1.0f / ((float)SDL_MIX_MAXVOLUME); + const float fvolume = (float)volume; + const float *src32 = (float *)src; + float *dst32 = (float *)dst; + float src1, src2; + double dst_sample; + /* !!! FIXME: are these right? */ + const double max_audioval = 3.402823466e+38F; + const double min_audioval = -3.402823466e+38F; + + len /= 4; + while (len--) { + src1 = ((SDL_SwapFloatBE(*src32) * fvolume) * fmaxvolume); + src2 = SDL_SwapFloatBE(*dst32); + src32++; + + dst_sample = ((double)src1) + ((double)src2); + if (dst_sample > max_audioval) { + dst_sample = max_audioval; + } else if (dst_sample < min_audioval) { + dst_sample = min_audioval; + } + *(dst32++) = SDL_SwapFloatBE((float)dst_sample); + } + } break; + + default: /* If this happens... FIXME! */ + SDL_SetError("SDL_MixAudioFormat(): unknown audio format"); + return; + } +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/audio/SDL_sysaudio.h b/SDL2-2.30.5/src/audio/SDL_sysaudio.h similarity index 78% rename from SDL2-2.0.12/src/audio/SDL_sysaudio.h rename to SDL2-2.30.5/src/audio/SDL_sysaudio.h index 7359adc..d569ba7 100644 --- a/SDL2-2.0.12/src/audio/SDL_sysaudio.h +++ b/SDL2-2.30.5/src/audio/SDL_sysaudio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -30,20 +30,20 @@ /* !!! FIXME: These are wordy and unlocalized... */ #define DEFAULT_OUTPUT_DEVNAME "System audio output device" -#define DEFAULT_INPUT_DEVNAME "System audio capture device" +#define DEFAULT_INPUT_DEVNAME "System audio capture device" /* The SDL audio driver */ typedef struct SDL_AudioDevice SDL_AudioDevice; -#define _THIS SDL_AudioDevice *_this +#define _THIS SDL_AudioDevice *_this /* Audio targets should call this as devices are added to the system (such as a USB headset being plugged in), and should also be called for for every device found during DetectDevices(). */ -extern void SDL_AddAudioDevice(const int iscapture, const char *name, void *handle); +extern void SDL_AddAudioDevice(const SDL_bool iscapture, const char *name, SDL_AudioSpec *spec, void *handle); /* Audio targets should call this as devices are removed, so SDL can update its list of available devices. */ -extern void SDL_RemoveAudioDevice(const int iscapture, void *handle); +extern void SDL_RemoveAudioDevice(const SDL_bool iscapture, void *handle); /* Audio targets should call this if an opened audio device is lost while being used. This can happen due to i/o errors, or a device being unplugged, @@ -64,46 +64,43 @@ extern void SDL_OpenedAudioDeviceDisconnected(SDL_AudioDevice *device); typedef struct SDL_AudioDriverImpl { - void (*DetectDevices) (void); - int (*OpenDevice) (_THIS, void *handle, const char *devname, int iscapture); - void (*ThreadInit) (_THIS); /* Called by audio thread at start */ - void (*ThreadDeinit) (_THIS); /* Called by audio thread at end */ - void (*BeginLoopIteration)(_THIS); /* Called by audio thread at top of loop */ - void (*WaitDevice) (_THIS); - void (*PlayDevice) (_THIS); - Uint8 *(*GetDeviceBuf) (_THIS); - int (*CaptureFromDevice) (_THIS, void *buffer, int buflen); - void (*FlushCapture) (_THIS); - void (*PrepareToClose) (_THIS); /**< Called between run and draining wait for playback devices */ - void (*CloseDevice) (_THIS); - void (*LockDevice) (_THIS); - void (*UnlockDevice) (_THIS); - void (*FreeDeviceHandle) (void *handle); /**< SDL is done with handle from SDL_AddAudioDevice() */ - void (*Deinitialize) (void); + void (*DetectDevices)(void); + int (*OpenDevice)(_THIS, const char *devname); + void (*ThreadInit)(_THIS); /* Called by audio thread at start */ + void (*ThreadDeinit)(_THIS); /* Called by audio thread at end */ + void (*WaitDevice)(_THIS); + void (*PlayDevice)(_THIS); + Uint8 *(*GetDeviceBuf)(_THIS); + int (*CaptureFromDevice)(_THIS, void *buffer, int buflen); + void (*FlushCapture)(_THIS); + void (*CloseDevice)(_THIS); + void (*LockDevice)(_THIS); + void (*UnlockDevice)(_THIS); + void (*FreeDeviceHandle)(void *handle); /**< SDL is done with handle from SDL_AddAudioDevice() */ + void (*Deinitialize)(void); + int (*GetDefaultAudioInfo)(char **name, SDL_AudioSpec *spec, int iscapture); /* !!! FIXME: add pause(), so we can optimize instead of mixing silence. */ /* Some flags to push duplicate code into the core and reduce #ifdefs. */ - /* !!! FIXME: these should be SDL_bool */ - int ProvidesOwnCallbackThread; - int SkipMixerLock; - int HasCaptureSupport; - int OnlyHasDefaultOutputDevice; - int OnlyHasDefaultCaptureDevice; - int AllowsArbitraryDeviceNames; + SDL_bool ProvidesOwnCallbackThread; + SDL_bool HasCaptureSupport; + SDL_bool OnlyHasDefaultOutputDevice; + SDL_bool OnlyHasDefaultCaptureDevice; + SDL_bool AllowsArbitraryDeviceNames; + SDL_bool SupportsNonPow2Samples; } SDL_AudioDriverImpl; - typedef struct SDL_AudioDeviceItem { void *handle; char *name; char *original_name; + SDL_AudioSpec spec; int dupenum; struct SDL_AudioDeviceItem *next; } SDL_AudioDeviceItem; - typedef struct SDL_AudioDriver { /* * * */ @@ -126,7 +123,6 @@ typedef struct SDL_AudioDriver SDL_AudioDeviceItem *inputDevices; } SDL_AudioDriver; - /* Define the SDL audio driver structure */ struct SDL_AudioDevice { @@ -177,11 +173,12 @@ typedef struct AudioBootStrap { const char *name; const char *desc; - int (*init) (SDL_AudioDriverImpl * impl); - int demand_only; /* 1==request explicitly, or it won't be available. */ + SDL_bool (*init)(SDL_AudioDriverImpl *impl); + SDL_bool demand_only; /* 1==request explicitly, or it won't be available. */ } AudioBootStrap; /* Not all of these are available in a given build. Use #ifdefs, etc. */ +extern AudioBootStrap PIPEWIRE_bootstrap; extern AudioBootStrap PULSEAUDIO_bootstrap; extern AudioBootStrap ALSA_bootstrap; extern AudioBootStrap JACK_bootstrap; @@ -203,10 +200,15 @@ extern AudioBootStrap COREAUDIO_bootstrap; extern AudioBootStrap DISKAUDIO_bootstrap; extern AudioBootStrap DUMMYAUDIO_bootstrap; extern AudioBootStrap FUSIONSOUND_bootstrap; +extern AudioBootStrap aaudio_bootstrap; extern AudioBootStrap openslES_bootstrap; extern AudioBootStrap ANDROIDAUDIO_bootstrap; +extern AudioBootStrap PS2AUDIO_bootstrap; extern AudioBootStrap PSPAUDIO_bootstrap; +extern AudioBootStrap VITAAUD_bootstrap; +extern AudioBootStrap N3DSAUDIO_bootstrap; extern AudioBootStrap EMSCRIPTENAUDIO_bootstrap; +extern AudioBootStrap OS2AUDIO_bootstrap; #endif /* SDL_sysaudio_h_ */ diff --git a/SDL2-2.0.12/src/audio/SDL_wave.c b/SDL2-2.30.5/src/audio/SDL_wave.c similarity index 89% rename from SDL2-2.0.12/src/audio/SDL_wave.c rename to SDL2-2.30.5/src/audio/SDL_wave.c index 95d3504..1ecce9b 100644 --- a/SDL2-2.0.12/src/audio/SDL_wave.c +++ b/SDL2-2.30.5/src/audio/SDL_wave.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -22,19 +22,17 @@ #ifdef HAVE_LIMITS_H #include -#else -#ifndef SIZE_MAX -#define SIZE_MAX ((size_t)-1) #endif #ifndef INT_MAX /* Make a lucky guess. */ #define INT_MAX SDL_MAX_SINT32 #endif +#ifndef SIZE_MAX +#define SIZE_MAX ((size_t)-1) #endif /* Microsoft WAVE file loading routines */ -#include "SDL_log.h" #include "SDL_hints.h" #include "SDL_audio.h" #include "SDL_wave.h" @@ -45,8 +43,7 @@ * Returns 0 on success, or -1 if the multiplication overflows, in which case f1 * does not get modified. */ -static int -SafeMult(size_t *f1, size_t f2) +static int SafeMult(size_t *f1, size_t f2) { if (*f1 > 0 && SIZE_MAX / *f1 <= f2) { return -1; @@ -68,21 +65,24 @@ typedef struct ADPCM_DecoderState void *cstate; /* Decoding state for each channel. */ /* ADPCM data. */ - struct { + struct + { Uint8 *data; size_t size; size_t pos; } input; /* Current ADPCM block in the ADPCM data above. */ - struct { + struct + { Uint8 *data; size_t size; size_t pos; } block; /* Decoded 16-bit PCM data. */ - struct { + struct + { Sint16 *data; size_t size; size_t pos; @@ -104,8 +104,7 @@ typedef struct MS_ADPCM_ChannelState } MS_ADPCM_ChannelState; #ifdef SDL_WAVE_DEBUG_LOG_FORMAT -static void -WaveDebugLogFormat(WaveFile *file) +static void WaveDebugLogFormat(WaveFile *file) { WaveFormat *format = &file->format; const char *fmtstr = "WAVE file: %s, %u Hz, %s, %u bits, %u %s/s"; @@ -139,55 +138,60 @@ WaveDebugLogFormat(WaveFile *file) break; } -#define SDL_WAVE_DEBUG_CHANNELCFG(STR, CODE) case CODE: wavechannel = STR; break; -#define SDL_WAVE_DEBUG_CHANNELSTR(STR, CODE) if (format->channelmask & CODE) { \ - SDL_strlcat(channelstr, channelstr[0] ? "-" STR : STR, sizeof(channelstr));} +#define SDL_WAVE_DEBUG_CHANNELCFG(STR, CODE) \ + case CODE: \ + wavechannel = STR; \ + break; +#define SDL_WAVE_DEBUG_CHANNELSTR(STR, CODE) \ + if (format->channelmask & CODE) { \ + SDL_strlcat(channelstr, channelstr[0] ? "-" STR : STR, sizeof(channelstr)); \ + } if (format->formattag == EXTENSIBLE_CODE && format->channelmask > 0) { switch (format->channelmask) { - SDL_WAVE_DEBUG_CHANNELCFG("1.0 Mono", 0x4) - SDL_WAVE_DEBUG_CHANNELCFG("1.1 Mono", 0xc) - SDL_WAVE_DEBUG_CHANNELCFG("2.0 Stereo", 0x3) - SDL_WAVE_DEBUG_CHANNELCFG("2.1 Stereo", 0xb) - SDL_WAVE_DEBUG_CHANNELCFG("3.0 Stereo", 0x7) - SDL_WAVE_DEBUG_CHANNELCFG("3.1 Stereo", 0xf) - SDL_WAVE_DEBUG_CHANNELCFG("3.0 Surround", 0x103) - SDL_WAVE_DEBUG_CHANNELCFG("3.1 Surround", 0x10b) - SDL_WAVE_DEBUG_CHANNELCFG("4.0 Quad", 0x33) - SDL_WAVE_DEBUG_CHANNELCFG("4.1 Quad", 0x3b) - SDL_WAVE_DEBUG_CHANNELCFG("4.0 Surround", 0x107) - SDL_WAVE_DEBUG_CHANNELCFG("4.1 Surround", 0x10f) - SDL_WAVE_DEBUG_CHANNELCFG("5.0", 0x37) - SDL_WAVE_DEBUG_CHANNELCFG("5.1", 0x3f) - SDL_WAVE_DEBUG_CHANNELCFG("5.0 Side", 0x607) - SDL_WAVE_DEBUG_CHANNELCFG("5.1 Side", 0x60f) - SDL_WAVE_DEBUG_CHANNELCFG("6.0", 0x137) - SDL_WAVE_DEBUG_CHANNELCFG("6.1", 0x13f) - SDL_WAVE_DEBUG_CHANNELCFG("6.0 Side", 0x707) - SDL_WAVE_DEBUG_CHANNELCFG("6.1 Side", 0x70f) - SDL_WAVE_DEBUG_CHANNELCFG("7.0", 0xf7) - SDL_WAVE_DEBUG_CHANNELCFG("7.1", 0xff) - SDL_WAVE_DEBUG_CHANNELCFG("7.0 Side", 0x6c7) - SDL_WAVE_DEBUG_CHANNELCFG("7.1 Side", 0x6cf) - SDL_WAVE_DEBUG_CHANNELCFG("7.0 Surround", 0x637) - SDL_WAVE_DEBUG_CHANNELCFG("7.1 Surround", 0x63f) - SDL_WAVE_DEBUG_CHANNELCFG("9.0 Surround", 0x5637) - SDL_WAVE_DEBUG_CHANNELCFG("9.1 Surround", 0x563f) - SDL_WAVE_DEBUG_CHANNELCFG("11.0 Surround", 0x56f7) - SDL_WAVE_DEBUG_CHANNELCFG("11.1 Surround", 0x56ff) + SDL_WAVE_DEBUG_CHANNELCFG("1.0 Mono", 0x4) + SDL_WAVE_DEBUG_CHANNELCFG("1.1 Mono", 0xc) + SDL_WAVE_DEBUG_CHANNELCFG("2.0 Stereo", 0x3) + SDL_WAVE_DEBUG_CHANNELCFG("2.1 Stereo", 0xb) + SDL_WAVE_DEBUG_CHANNELCFG("3.0 Stereo", 0x7) + SDL_WAVE_DEBUG_CHANNELCFG("3.1 Stereo", 0xf) + SDL_WAVE_DEBUG_CHANNELCFG("3.0 Surround", 0x103) + SDL_WAVE_DEBUG_CHANNELCFG("3.1 Surround", 0x10b) + SDL_WAVE_DEBUG_CHANNELCFG("4.0 Quad", 0x33) + SDL_WAVE_DEBUG_CHANNELCFG("4.1 Quad", 0x3b) + SDL_WAVE_DEBUG_CHANNELCFG("4.0 Surround", 0x107) + SDL_WAVE_DEBUG_CHANNELCFG("4.1 Surround", 0x10f) + SDL_WAVE_DEBUG_CHANNELCFG("5.0", 0x37) + SDL_WAVE_DEBUG_CHANNELCFG("5.1", 0x3f) + SDL_WAVE_DEBUG_CHANNELCFG("5.0 Side", 0x607) + SDL_WAVE_DEBUG_CHANNELCFG("5.1 Side", 0x60f) + SDL_WAVE_DEBUG_CHANNELCFG("6.0", 0x137) + SDL_WAVE_DEBUG_CHANNELCFG("6.1", 0x13f) + SDL_WAVE_DEBUG_CHANNELCFG("6.0 Side", 0x707) + SDL_WAVE_DEBUG_CHANNELCFG("6.1 Side", 0x70f) + SDL_WAVE_DEBUG_CHANNELCFG("7.0", 0xf7) + SDL_WAVE_DEBUG_CHANNELCFG("7.1", 0xff) + SDL_WAVE_DEBUG_CHANNELCFG("7.0 Side", 0x6c7) + SDL_WAVE_DEBUG_CHANNELCFG("7.1 Side", 0x6cf) + SDL_WAVE_DEBUG_CHANNELCFG("7.0 Surround", 0x637) + SDL_WAVE_DEBUG_CHANNELCFG("7.1 Surround", 0x63f) + SDL_WAVE_DEBUG_CHANNELCFG("9.0 Surround", 0x5637) + SDL_WAVE_DEBUG_CHANNELCFG("9.1 Surround", 0x563f) + SDL_WAVE_DEBUG_CHANNELCFG("11.0 Surround", 0x56f7) + SDL_WAVE_DEBUG_CHANNELCFG("11.1 Surround", 0x56ff) default: - SDL_WAVE_DEBUG_CHANNELSTR("FL", 0x1) - SDL_WAVE_DEBUG_CHANNELSTR("FR", 0x2) - SDL_WAVE_DEBUG_CHANNELSTR("FC", 0x4) - SDL_WAVE_DEBUG_CHANNELSTR("LF", 0x8) - SDL_WAVE_DEBUG_CHANNELSTR("BL", 0x10) - SDL_WAVE_DEBUG_CHANNELSTR("BR", 0x20) + SDL_WAVE_DEBUG_CHANNELSTR("FL", 0x1) + SDL_WAVE_DEBUG_CHANNELSTR("FR", 0x2) + SDL_WAVE_DEBUG_CHANNELSTR("FC", 0x4) + SDL_WAVE_DEBUG_CHANNELSTR("LF", 0x8) + SDL_WAVE_DEBUG_CHANNELSTR("BL", 0x10) + SDL_WAVE_DEBUG_CHANNELSTR("BR", 0x20) SDL_WAVE_DEBUG_CHANNELSTR("FLC", 0x40) SDL_WAVE_DEBUG_CHANNELSTR("FRC", 0x80) - SDL_WAVE_DEBUG_CHANNELSTR("BC", 0x100) - SDL_WAVE_DEBUG_CHANNELSTR("SL", 0x200) - SDL_WAVE_DEBUG_CHANNELSTR("SR", 0x400) - SDL_WAVE_DEBUG_CHANNELSTR("TC", 0x800) + SDL_WAVE_DEBUG_CHANNELSTR("BC", 0x100) + SDL_WAVE_DEBUG_CHANNELSTR("SL", 0x200) + SDL_WAVE_DEBUG_CHANNELSTR("SR", 0x400) + SDL_WAVE_DEBUG_CHANNELSTR("TC", 0x800) SDL_WAVE_DEBUG_CHANNELSTR("TFL", 0x1000) SDL_WAVE_DEBUG_CHANNELSTR("TFC", 0x2000) SDL_WAVE_DEBUG_CHANNELSTR("TFR", 0x4000) @@ -228,40 +232,39 @@ WaveDebugLogFormat(WaveFile *file) #endif #ifdef SDL_WAVE_DEBUG_DUMP_FORMAT -static void -WaveDebugDumpFormat(WaveFile *file, Uint32 rifflen, Uint32 fmtlen, Uint32 datalen) +static void WaveDebugDumpFormat(WaveFile *file, Uint32 rifflen, Uint32 fmtlen, Uint32 datalen) { WaveFormat *format = &file->format; const char *fmtstr1 = "WAVE chunk dump:\n" - "-------------------------------------------\n" - "RIFF %11u\n" - "-------------------------------------------\n" - " fmt %11u\n" - " wFormatTag 0x%04x\n" - " nChannels %11u\n" - " nSamplesPerSec %11u\n" - " nAvgBytesPerSec %11u\n" - " nBlockAlign %11u\n"; + "-------------------------------------------\n" + "RIFF %11u\n" + "-------------------------------------------\n" + " fmt %11u\n" + " wFormatTag 0x%04x\n" + " nChannels %11u\n" + " nSamplesPerSec %11u\n" + " nAvgBytesPerSec %11u\n" + " nBlockAlign %11u\n"; const char *fmtstr2 = " wBitsPerSample %11u\n"; const char *fmtstr3 = " cbSize %11u\n"; const char *fmtstr4a = " wValidBitsPerSample %11u\n"; const char *fmtstr4b = " wSamplesPerBlock %11u\n"; const char *fmtstr5 = " dwChannelMask 0x%08x\n" - " SubFormat\n" - " %08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x\n"; + " SubFormat\n" + " %08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x\n"; const char *fmtstr6 = "-------------------------------------------\n" - " fact\n" - " dwSampleLength %11u\n"; + " fact\n" + " dwSampleLength %11u\n"; const char *fmtstr7 = "-------------------------------------------\n" - " data %11u\n" - "-------------------------------------------\n"; + " data %11u\n" + "-------------------------------------------\n"; char *dumpstr; size_t dumppos = 0; const size_t bufsize = 1024; int res; dumpstr = SDL_malloc(bufsize); - if (dumpstr == NULL) { + if (!dumpstr) { return; } dumpstr[0] = 0; @@ -315,12 +318,11 @@ WaveDebugDumpFormat(WaveFile *file, Uint32 rifflen, Uint32 fmtlen, Uint32 datale SDL_LogDebug(SDL_LOG_CATEGORY_AUDIO, "%s", dumpstr); - free(dumpstr); + SDL_free(dumpstr); } #endif -static Sint64 -WaveAdjustToFactValue(WaveFile *file, Sint64 sampleframes) +static Sint64 WaveAdjustToFactValue(WaveFile *file, Sint64 sampleframes) { if (file->fact.status == 2) { if (file->facthint == FactStrict && sampleframes < file->fact.samplelength) { @@ -333,8 +335,7 @@ WaveAdjustToFactValue(WaveFile *file, Sint64 sampleframes) return sampleframes; } -static int -MS_ADPCM_CalculateSampleFrames(WaveFile *file, size_t datalength) +static int MS_ADPCM_CalculateSampleFrames(WaveFile *file, size_t datalength) { WaveFormat *format = &file->format; const size_t blockheadersize = (size_t)file->format.channels * 7; @@ -373,8 +374,7 @@ MS_ADPCM_CalculateSampleFrames(WaveFile *file, size_t datalength) return 0; } -static int -MS_ADPCM_Init(WaveFile *file, size_t datalength) +static int MS_ADPCM_Init(WaveFile *file, size_t datalength) { WaveFormat *format = &file->format; WaveChunk *chunk = &file->chunk; @@ -382,7 +382,7 @@ MS_ADPCM_Init(WaveFile *file, size_t datalength) const size_t blockdatasize = (size_t)format->blockalign - blockheadersize; const size_t blockframebitsize = (size_t)format->bitspersample * format->channels; const size_t blockdatasamples = (blockdatasize * 8) / blockframebitsize; - const Sint16 presetcoeffs[14] = {256, 0, 512, -256, 0, 0, 192, 64, 240, 0, 460, -208, 392, -232}; + const Sint16 presetcoeffs[14] = { 256, 0, 512, -256, 0, 0, 192, 64, 240, 0, 460, -208, 392, -232 }; size_t i, coeffcount; MS_ADPCM_CoeffData *coeffdata; @@ -441,7 +441,7 @@ MS_ADPCM_Init(WaveFile *file, size_t datalength) coeffdata = (MS_ADPCM_CoeffData *)SDL_malloc(sizeof(MS_ADPCM_CoeffData) + coeffcount * 4); file->decoderdata = coeffdata; /* Freed in cleanup. */ - if (coeffdata == NULL) { + if (!coeffdata) { return SDL_OutOfMemory(); } coeffdata->coeff = &coeffdata->aligndummy; @@ -492,8 +492,7 @@ MS_ADPCM_Init(WaveFile *file, size_t datalength) return 0; } -static Sint16 -MS_ADPCM_ProcessNibble(MS_ADPCM_ChannelState *cstate, Sint32 sample1, Sint32 sample2, Uint8 nybble) +static Sint16 MS_ADPCM_ProcessNibble(MS_ADPCM_ChannelState *cstate, Sint32 sample1, Sint32 sample2, Uint8 nybble) { const Sint32 max_audioval = 32767; const Sint32 min_audioval = -32768; @@ -529,8 +528,7 @@ MS_ADPCM_ProcessNibble(MS_ADPCM_ChannelState *cstate, Sint32 sample1, Sint32 sam return (Sint16)new_sample; } -static int -MS_ADPCM_DecodeBlockHeader(ADPCM_DecoderState *state) +static int MS_ADPCM_DecodeBlockHeader(ADPCM_DecoderState *state) { Uint8 coeffindex; const Uint32 channels = state->channels; @@ -551,20 +549,20 @@ MS_ADPCM_DecodeBlockHeader(ADPCM_DecoderState *state) cstate[c].coeff2 = ddata->coeff[coeffindex * 2 + 1]; /* Initial delta value. */ - o = channels + c * 2; + o = (size_t)channels + c * 2; cstate[c].delta = state->block.data[o] | ((Uint16)state->block.data[o + 1] << 8); /* Load the samples from the header. Interestingly, the sample later in * the output stream comes first. */ - o = channels * 3 + c * 2; + o = (size_t)channels * 3 + c * 2; sample = state->block.data[o] | ((Sint32)state->block.data[o + 1] << 8); if (sample >= 0x8000) { sample -= 0x10000; } state->output.data[state->output.pos + channels] = (Sint16)sample; - o = channels * 5 + c * 2; + o = (size_t)channels * 5 + c * 2; sample = state->block.data[o] | ((Sint32)state->block.data[o + 1] << 8); if (sample >= 0x8000) { sample -= 0x10000; @@ -590,8 +588,7 @@ MS_ADPCM_DecodeBlockHeader(ADPCM_DecoderState *state) * will always contain full sample frames (same sample count for each channel). * Incomplete sample frames are discarded. */ -static int -MS_ADPCM_DecodeBlockData(ADPCM_DecoderState *state) +static int MS_ADPCM_DecodeBlockData(ADPCM_DecoderState *state) { Uint16 nybble = 0; Sint16 sample1, sample2; @@ -638,8 +635,7 @@ MS_ADPCM_DecodeBlockData(ADPCM_DecoderState *state) return 0; } -static int -MS_ADPCM_Decode(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len) +static int MS_ADPCM_Decode(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len) { int result; size_t bytesleft, outputsize; @@ -687,8 +683,8 @@ MS_ADPCM_Decode(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len) state.output.pos = 0; state.output.size = outputsize / sizeof(Sint16); - state.output.data = (Sint16 *)SDL_malloc(outputsize); - if (state.output.data == NULL) { + state.output.data = (Sint16 *)SDL_calloc(1, outputsize); + if (!state.output.data) { return SDL_OutOfMemory(); } @@ -738,8 +734,7 @@ MS_ADPCM_Decode(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len) return 0; } -static int -IMA_ADPCM_CalculateSampleFrames(WaveFile *file, size_t datalength) +static int IMA_ADPCM_CalculateSampleFrames(WaveFile *file, size_t datalength) { WaveFormat *format = &file->format; const size_t blockheadersize = (size_t)format->channels * 4; @@ -792,8 +787,7 @@ IMA_ADPCM_CalculateSampleFrames(WaveFile *file, size_t datalength) return 0; } -static int -IMA_ADPCM_Init(WaveFile *file, size_t datalength) +static int IMA_ADPCM_Init(WaveFile *file, size_t datalength) { WaveFormat *format = &file->format; WaveChunk *chunk = &file->chunk; @@ -822,7 +816,7 @@ IMA_ADPCM_Init(WaveFile *file, size_t datalength) /* There's no specification for this, but it's basically the same * format because the extensible header has wSampePerBlocks too. */ - } else { + } else { /* The Standards Update says there 'should' be 2 bytes for wSamplesPerBlock. */ if (chunk->size >= 20 && format->extsize >= 2) { format->samplesperblock = chunk->data[18] | ((Uint16)chunk->data[19] << 8); @@ -858,8 +852,7 @@ IMA_ADPCM_Init(WaveFile *file, size_t datalength) return 0; } -static Sint16 -IMA_ADPCM_ProcessNibble(Sint8 *cindex, Sint16 lastsample, Uint8 nybble) +static Sint16 IMA_ADPCM_ProcessNibble(Sint8 *cindex, Sint16 lastsample, Uint8 nybble) { const Sint32 max_audioval = 32767; const Sint32 min_audioval = -32768; @@ -903,14 +896,18 @@ IMA_ADPCM_ProcessNibble(Sint8 *cindex, Sint16 lastsample, Uint8 nybble) * (nybble & 0x8 ? -1 : 1) * ((nybble & 0x7) * step / 4 + step / 8) */ delta = step >> 3; - if (nybble & 0x04) + if (nybble & 0x04) { delta += step; - if (nybble & 0x02) + } + if (nybble & 0x02) { delta += step >> 1; - if (nybble & 0x01) + } + if (nybble & 0x01) { delta += step >> 2; - if (nybble & 0x08) + } + if (nybble & 0x08) { delta = -delta; + } sample = lastsample + delta; @@ -924,12 +921,11 @@ IMA_ADPCM_ProcessNibble(Sint8 *cindex, Sint16 lastsample, Uint8 nybble) return (Sint16)sample; } -static int -IMA_ADPCM_DecodeBlockHeader(ADPCM_DecoderState *state) +static int IMA_ADPCM_DecodeBlockHeader(ADPCM_DecoderState *state) { Sint16 step; Uint32 c; - Uint8 *cstate = state->cstate; + Uint8 *cstate = (Uint8 *)state->cstate; for (c = 0; c < state->channels; c++) { size_t o = state->block.pos + c * 4; @@ -947,7 +943,7 @@ IMA_ADPCM_DecodeBlockHeader(ADPCM_DecoderState *state) /* Reserved byte in block header, should be 0. */ if (state->block.data[o + 3] != 0) { - /* Uh oh, corrupt data? Buggy code? */ ; + /* Uh oh, corrupt data? Buggy code? */; } } @@ -964,13 +960,12 @@ IMA_ADPCM_DecodeBlockHeader(ADPCM_DecoderState *state) * contains full sample frames (same sample count for each channel). * Incomplete sample frames are discarded. */ -static int -IMA_ADPCM_DecodeBlockData(ADPCM_DecoderState *state) +static int IMA_ADPCM_DecodeBlockData(ADPCM_DecoderState *state) { size_t i; int retval = 0; const Uint32 channels = state->channels; - const size_t subblockframesize = channels * 4; + const size_t subblockframesize = (size_t)channels * 4; Uint64 bytesrequired; Uint32 c; @@ -1034,8 +1029,7 @@ IMA_ADPCM_DecodeBlockData(ADPCM_DecoderState *state) return retval; } -static int -IMA_ADPCM_Decode(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len) +static int IMA_ADPCM_Decode(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len) { int result; size_t bytesleft, outputsize; @@ -1081,12 +1075,12 @@ IMA_ADPCM_Decode(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len) state.output.pos = 0; state.output.size = outputsize / sizeof(Sint16); state.output.data = (Sint16 *)SDL_malloc(outputsize); - if (state.output.data == NULL) { + if (!state.output.data) { return SDL_OutOfMemory(); } cstate = (Sint8 *)SDL_calloc(state.channels, sizeof(Sint8)); - if (cstate == NULL) { + if (!cstate) { SDL_free(state.output.data); return SDL_OutOfMemory(); } @@ -1138,8 +1132,7 @@ IMA_ADPCM_Decode(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len) return 0; } -static int -LAW_Init(WaveFile *file, size_t datalength) +static int LAW_Init(WaveFile *file, size_t datalength) { WaveFormat *format = &file->format; @@ -1167,8 +1160,7 @@ LAW_Init(WaveFile *file, size_t datalength) return 0; } -static int -LAW_Decode(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len) +static int LAW_Decode(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len) { #ifdef SDL_WAVE_LAW_LUT const Sint16 alaw_lut[256] = { @@ -1243,7 +1235,7 @@ LAW_Decode(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len) /* 1 to avoid allocating zero bytes, to keep static analysis happy. */ src = (Uint8 *)SDL_realloc(chunk->data, expanded_len ? expanded_len : 1); - if (src == NULL) { + if (!src) { return SDL_OutOfMemory(); } chunk->data = NULL; @@ -1310,8 +1302,7 @@ LAW_Decode(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len) return 0; } -static int -PCM_Init(WaveFile *file, size_t datalength) +static int PCM_Init(WaveFile *file, size_t datalength) { WaveFormat *format = &file->format; @@ -1335,7 +1326,8 @@ PCM_Init(WaveFile *file, size_t datalength) /* It wouldn't be that hard to support more exotic block sizes, but * the most common formats should do for now. */ - if (format->blockalign * 8 != format->channels * format->bitspersample) { + /* Make sure we're a multiple of the blockalign, at least. */ + if ((format->channels * format->bitspersample) % (format->blockalign * 8)) { return SDL_SetError("Unsupported block alignment"); } @@ -1353,8 +1345,7 @@ PCM_Init(WaveFile *file, size_t datalength) return 0; } -static int -PCM_ConvertSint24ToSint32(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len) +static int PCM_ConvertSint24ToSint32(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len) { WaveFormat *format = &file->format; WaveChunk *chunk = &file->chunk; @@ -1375,7 +1366,7 @@ PCM_ConvertSint24ToSint32(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len) /* 1 to avoid allocating zero bytes, to keep static analysis happy. */ ptr = (Uint8 *)SDL_realloc(chunk->data, expanded_len ? expanded_len : 1); - if (ptr == NULL) { + if (!ptr) { return SDL_OutOfMemory(); } @@ -1405,8 +1396,7 @@ PCM_ConvertSint24ToSint32(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len) return 0; } -static int -PCM_Decode(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len) +static int PCM_Decode(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len) { WaveFormat *format = &file->format; WaveChunk *chunk = &file->chunk; @@ -1448,12 +1438,11 @@ PCM_Decode(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len) return 0; } -static WaveRiffSizeHint -WaveGetRiffSizeHint() +static WaveRiffSizeHint WaveGetRiffSizeHint(void) { const char *hint = SDL_GetHint(SDL_HINT_WAVE_RIFF_CHUNK_SIZE); - if (hint != NULL) { + if (hint) { if (SDL_strcmp(hint, "force") == 0) { return RiffSizeForce; } else if (SDL_strcmp(hint, "ignore") == 0) { @@ -1468,12 +1457,11 @@ WaveGetRiffSizeHint() return RiffSizeNoHint; } -static WaveTruncationHint -WaveGetTruncationHint() +static WaveTruncationHint WaveGetTruncationHint(void) { const char *hint = SDL_GetHint(SDL_HINT_WAVE_TRUNCATION); - if (hint != NULL) { + if (hint) { if (SDL_strcmp(hint, "verystrict") == 0) { return TruncVeryStrict; } else if (SDL_strcmp(hint, "strict") == 0) { @@ -1488,12 +1476,11 @@ WaveGetTruncationHint() return TruncNoHint; } -static WaveFactChunkHint -WaveGetFactChunkHint() +static WaveFactChunkHint WaveGetFactChunkHint(void) { const char *hint = SDL_GetHint(SDL_HINT_WAVE_FACT_CHUNK); - if (hint != NULL) { + if (hint) { if (SDL_strcmp(hint, "truncate") == 0) { return FactTruncate; } else if (SDL_strcmp(hint, "strict") == 0) { @@ -1508,18 +1495,16 @@ WaveGetFactChunkHint() return FactNoHint; } -static void -WaveFreeChunkData(WaveChunk *chunk) +static void WaveFreeChunkData(WaveChunk *chunk) { - if (chunk->data != NULL) { + if (chunk->data) { SDL_free(chunk->data); chunk->data = NULL; } chunk->size = 0; } -static int -WaveNextChunk(SDL_RWops *src, WaveChunk *chunk) +static int WaveNextChunk(SDL_RWops *src, WaveChunk *chunk) { Uint32 chunkheader[2]; Sint64 nextposition = chunk->position + chunk->length; @@ -1551,8 +1536,7 @@ WaveNextChunk(SDL_RWops *src, WaveChunk *chunk) return 0; } -static int -WaveReadPartialChunkData(SDL_RWops *src, WaveChunk *chunk, size_t length) +static int WaveReadPartialChunkData(SDL_RWops *src, WaveChunk *chunk, size_t length) { WaveFreeChunkData(chunk); @@ -1561,8 +1545,8 @@ WaveReadPartialChunkData(SDL_RWops *src, WaveChunk *chunk, size_t length) } if (length > 0) { - chunk->data = SDL_malloc(length); - if (chunk->data == NULL) { + chunk->data = (Uint8 *)SDL_malloc(length); + if (!chunk->data) { return SDL_OutOfMemory(); } @@ -1580,30 +1564,32 @@ WaveReadPartialChunkData(SDL_RWops *src, WaveChunk *chunk, size_t length) return 0; } -static int -WaveReadChunkData(SDL_RWops *src, WaveChunk *chunk) +static int WaveReadChunkData(SDL_RWops *src, WaveChunk *chunk) { return WaveReadPartialChunkData(src, chunk, chunk->length); } -typedef struct WaveExtensibleGUID { +typedef struct WaveExtensibleGUID +{ Uint16 encoding; Uint8 guid[16]; } WaveExtensibleGUID; /* Some of the GUIDs that are used by WAVEFORMATEXTENSIBLE. */ -#define WAVE_FORMATTAG_GUID(tag) {(tag) & 0xff, (tag) >> 8, 0, 0, 0, 0, 16, 0, 128, 0, 0, 170, 0, 56, 155, 113} +#define WAVE_FORMATTAG_GUID(tag) \ + { \ + (tag) & 0xff, (tag) >> 8, 0, 0, 0, 0, 16, 0, 128, 0, 0, 170, 0, 56, 155, 113 \ + } static WaveExtensibleGUID extensible_guids[] = { - {PCM_CODE, WAVE_FORMATTAG_GUID(PCM_CODE)}, - {MS_ADPCM_CODE, WAVE_FORMATTAG_GUID(MS_ADPCM_CODE)}, - {IEEE_FLOAT_CODE, WAVE_FORMATTAG_GUID(IEEE_FLOAT_CODE)}, - {ALAW_CODE, WAVE_FORMATTAG_GUID(ALAW_CODE)}, - {MULAW_CODE, WAVE_FORMATTAG_GUID(MULAW_CODE)}, - {IMA_ADPCM_CODE, WAVE_FORMATTAG_GUID(IMA_ADPCM_CODE)} + { PCM_CODE, WAVE_FORMATTAG_GUID(PCM_CODE) }, + { MS_ADPCM_CODE, WAVE_FORMATTAG_GUID(MS_ADPCM_CODE) }, + { IEEE_FLOAT_CODE, WAVE_FORMATTAG_GUID(IEEE_FLOAT_CODE) }, + { ALAW_CODE, WAVE_FORMATTAG_GUID(ALAW_CODE) }, + { MULAW_CODE, WAVE_FORMATTAG_GUID(MULAW_CODE) }, + { IMA_ADPCM_CODE, WAVE_FORMATTAG_GUID(IMA_ADPCM_CODE) } }; -static Uint16 -WaveGetFormatGUIDEncoding(WaveFormat *format) +static Uint16 WaveGetFormatGUIDEncoding(WaveFormat *format) { size_t i; for (i = 0; i < SDL_arraysize(extensible_guids); i++) { @@ -1614,8 +1600,7 @@ WaveGetFormatGUIDEncoding(WaveFormat *format) return UNKNOWN_CODE; } -static int -WaveReadFormat(WaveFile *file) +static int WaveReadFormat(WaveFile *file) { WaveChunk *chunk = &file->chunk; WaveFormat *format = &file->format; @@ -1627,7 +1612,7 @@ WaveReadFormat(WaveFile *file) return SDL_SetError("Data of WAVE fmt chunk too big"); } fmtsrc = SDL_RWFromConstMem(chunk->data, (int)chunk->size); - if (fmtsrc == NULL) { + if (!fmtsrc) { return SDL_OutOfMemory(); } @@ -1676,8 +1661,7 @@ WaveReadFormat(WaveFile *file) return 0; } -static int -WaveCheckFormat(WaveFile *file, size_t datalength) +static int WaveCheckFormat(WaveFile *file, size_t datalength) { WaveFormat *format = &file->format; @@ -1716,7 +1700,7 @@ WaveCheckFormat(WaveFile *file, size_t datalength) if (file->facthint == FactStrict && file->fact.status <= 0) { return SDL_SetError("Missing fact chunk in WAVE file"); } - /* fallthrough */ + SDL_FALLTHROUGH; case PCM_CODE: /* All supported formats require a non-zero bit depth. */ if (file->chunk.size < 16) { @@ -1727,7 +1711,7 @@ WaveCheckFormat(WaveFile *file, size_t datalength) /* All supported formats must have a proper block size. */ if (format->blockalign == 0) { - return SDL_SetError("Invalid block alignment"); + format->blockalign = 1; /* force it to 1 if it was unset. */ } /* If the fact chunk is valid and the appropriate hint is set, the @@ -1784,8 +1768,7 @@ WaveCheckFormat(WaveFile *file, size_t datalength) return 0; } -static int -WaveLoad(SDL_RWops *src, WaveFile *file, SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len) +static int WaveLoad(SDL_RWops *src, WaveFile *file, SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len) { int result; Uint32 chunkcount = 0; @@ -1804,7 +1787,7 @@ WaveLoad(SDL_RWops *src, WaveFile *file, SDL_AudioSpec *spec, Uint8 **audio_buf, SDL_zero(datachunk); envchunkcountlimit = SDL_getenv("SDL_WAVE_CHUNK_LIMIT"); - if (envchunkcountlimit != NULL) { + if (envchunkcountlimit) { unsigned int count; if (SDL_sscanf(envchunkcountlimit, "%u", &count) == 1) { chunkcountlimit = count <= SDL_MAX_UINT32 ? count : SDL_MAX_UINT32; @@ -1855,7 +1838,7 @@ WaveLoad(SDL_RWops *src, WaveFile *file, SDL_AudioSpec *spec, Uint8 **audio_buf, RIFFend = RIFFchunk.position + SDL_MAX_UINT32; break; } - /* fallthrough */ + SDL_FALLTHROUGH; case RiffSizeForce: RIFFend = RIFFchunk.position + RIFFchunk.length; RIFFlengthknown = SDL_TRUE; @@ -1872,7 +1855,7 @@ WaveLoad(SDL_RWops *src, WaveFile *file, SDL_AudioSpec *spec, Uint8 **audio_buf, while ((Uint64)RIFFend > (Uint64)chunk->position + chunk->length + (chunk->length & 1)) { /* Abort after too many chunks or else corrupt files may waste time. */ if (chunkcount++ >= chunkcountlimit) { - return SDL_SetError("Chunk count in WAVE file exceeds limit of %u", chunkcountlimit); + return SDL_SetError("Chunk count in WAVE file exceeds limit of %" SDL_PRIu32, chunkcountlimit); } result = WaveNextChunk(src, chunk); @@ -2050,7 +2033,7 @@ WaveLoad(SDL_RWops *src, WaveFile *file, SDL_AudioSpec *spec, Uint8 **audio_buf, SDL_zerop(spec); spec->freq = format->frequency; spec->channels = (Uint8)format->channels; - spec->samples = 4096; /* Good default buffer size */ + spec->samples = 4096; /* Good default buffer size */ switch (format->encoding) { case MS_ADPCM_CODE: @@ -2094,8 +2077,7 @@ WaveLoad(SDL_RWops *src, WaveFile *file, SDL_AudioSpec *spec, Uint8 **audio_buf, return 0; } -SDL_AudioSpec * -SDL_LoadWAV_RW(SDL_RWops *src, int freesrc, SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len) +SDL_AudioSpec *SDL_LoadWAV_RW(SDL_RWops *src, int freesrc, SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len) { int result; WaveFile file; @@ -2103,16 +2085,16 @@ SDL_LoadWAV_RW(SDL_RWops *src, int freesrc, SDL_AudioSpec *spec, Uint8 **audio_b SDL_zero(file); /* Make sure we are passed a valid data source */ - if (src == NULL) { + if (!src) { /* Error may come from RWops. */ return NULL; - } else if (spec == NULL) { + } else if (!spec) { SDL_InvalidParamError("spec"); return NULL; - } else if (audio_buf == NULL) { + } else if (!audio_buf) { SDL_InvalidParamError("audio_buf"); return NULL; - } else if (audio_len == NULL) { + } else if (!audio_len) { SDL_InvalidParamError("audio_len"); return NULL; } @@ -2147,8 +2129,7 @@ SDL_LoadWAV_RW(SDL_RWops *src, int freesrc, SDL_AudioSpec *spec, Uint8 **audio_b /* Since the WAV memory is allocated in the shared library, it must also be freed here. (Necessary under Win32, VC++) */ -void -SDL_FreeWAV(Uint8 *audio_buf) +void SDL_FreeWAV(Uint8 *audio_buf) { SDL_free(audio_buf); } diff --git a/SDL2-2.0.12/src/audio/SDL_wave.h b/SDL2-2.30.5/src/audio/SDL_wave.h similarity index 77% rename from SDL2-2.0.12/src/audio/SDL_wave.h rename to SDL2-2.30.5/src/audio/SDL_wave.h index 09d945f..6d71e47 100644 --- a/SDL2-2.0.12/src/audio/SDL_wave.h +++ b/SDL2-2.30.5/src/audio/SDL_wave.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,14 +26,14 @@ /* Define values for Microsoft WAVE format */ /*******************************************/ /* FOURCC */ -#define RIFF 0x46464952 /* "RIFF" */ -#define WAVE 0x45564157 /* "WAVE" */ -#define FACT 0x74636166 /* "fact" */ -#define LIST 0x5453494c /* "LIST" */ -#define BEXT 0x74786562 /* "bext" */ -#define JUNK 0x4B4E554A /* "JUNK" */ -#define FMT 0x20746D66 /* "fmt " */ -#define DATA 0x61746164 /* "data" */ +#define RIFF 0x46464952 /* "RIFF" */ +#define WAVE 0x45564157 /* "WAVE" */ +#define FACT 0x74636166 /* "fact" */ +#define LIST 0x5453494c /* "LIST" */ +#define BEXT 0x74786562 /* "bext" */ +#define JUNK 0x4B4E554A /* "JUNK" */ +#define FMT 0x20746D66 /* "fmt " */ +#define DATA 0x61746164 /* "data" */ /* Format tags */ #define UNKNOWN_CODE 0x0000 #define PCM_CODE 0x0001 @@ -49,13 +49,13 @@ /* Stores the WAVE format information. */ typedef struct WaveFormat { - Uint16 formattag; /* Raw value of the first field in the fmt chunk data. */ - Uint16 encoding; /* Actual encoding, possibly from the extensible header. */ - Uint16 channels; /* Number of channels. */ - Uint32 frequency; /* Sampling rate in Hz. */ - Uint32 byterate; /* Average bytes per second. */ - Uint16 blockalign; /* Bytes per block. */ - Uint16 bitspersample; /* Currently supported are 8, 16, 24, 32, and 4 for ADPCM. */ + Uint16 formattag; /* Raw value of the first field in the fmt chunk data. */ + Uint16 encoding; /* Actual encoding, possibly from the extensible header. */ + Uint16 channels; /* Number of channels. */ + Uint32 frequency; /* Sampling rate in Hz. */ + Uint32 byterate; /* Average bytes per second. */ + Uint16 blockalign; /* Bytes per block. */ + Uint16 bitspersample; /* Currently supported are 8, 16, 24, 32, and 4 for ADPCM. */ /* Extra information size. Number of extra bytes starting at byte 18 in the * fmt chunk data. This is at least 22 for the extensible header. @@ -66,11 +66,12 @@ typedef struct WaveFormat Uint16 validsamplebits; Uint32 samplesperblock; /* For compressed formats. Can be zero. Actually 16 bits in the header. */ Uint32 channelmask; - Uint8 subformat[16]; /* A format GUID. */ + Uint8 subformat[16]; /* A format GUID. */ } WaveFormat; /* Stores information on the fact chunk. */ -typedef struct WaveFact { +typedef struct WaveFact +{ /* Represents the state of the fact chunk in the WAVE file. * Set to -1 if the fact chunk is invalid. * Set to 0 if the fact chunk is not present @@ -96,12 +97,13 @@ typedef struct WaveChunk Uint32 fourcc; /* FOURCC of the chunk. */ Uint32 length; /* Size of the chunk data. */ Sint64 position; /* Position of the data in the stream. */ - Uint8 *data; /* When allocated, this points to the chunk data. length is used for the malloc size. */ + Uint8 *data; /* When allocated, this points to the chunk data. length is used for the memory allocation size. */ size_t size; /* Number of bytes in data that could be read from the stream. Can be smaller than length. */ } WaveChunk; /* Controls how the size of the RIFF chunk affects the loading of a WAVE file. */ -typedef enum WaveRiffSizeHint { +typedef enum WaveRiffSizeHint +{ RiffSizeNoHint, RiffSizeForce, RiffSizeIgnoreZero, @@ -110,7 +112,8 @@ typedef enum WaveRiffSizeHint { } WaveRiffSizeHint; /* Controls how a truncated WAVE file is handled. */ -typedef enum WaveTruncationHint { +typedef enum WaveTruncationHint +{ TruncNoHint, TruncVeryStrict, TruncStrict, @@ -119,7 +122,8 @@ typedef enum WaveTruncationHint { } WaveTruncationHint; /* Controls how the fact chunk affects the loading of a WAVE file. */ -typedef enum WaveFactChunkHint { +typedef enum WaveFactChunkHint +{ FactNoHint, FactTruncate, FactStrict, @@ -139,7 +143,7 @@ typedef struct WaveFile */ Sint64 sampleframes; - void *decoderdata; /* Some decoders require extra data for a state. */ + void *decoderdata; /* Some decoders require extra data for a state. */ WaveRiffSizeHint riffhint; WaveTruncationHint trunchint; diff --git a/SDL2-2.30.5/src/audio/aaudio/SDL_aaudio.c b/SDL2-2.30.5/src/audio/aaudio/SDL_aaudio.c new file mode 100644 index 0000000..401fef6 --- /dev/null +++ b/SDL2-2.30.5/src/audio/aaudio/SDL_aaudio.c @@ -0,0 +1,530 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_AUDIO_DRIVER_AAUDIO + +#include "SDL_audio.h" +#include "SDL_loadso.h" +#include "../SDL_audio_c.h" +#include "../../core/android/SDL_android.h" +#include "SDL_aaudio.h" + +/* Debug */ +#if 0 +#define LOGI(...) SDL_Log(__VA_ARGS__); +#else +#define LOGI(...) +#endif + +typedef struct AAUDIO_Data +{ + AAudioStreamBuilder *builder; + void *handle; +#define SDL_PROC(ret, func, params) ret (*func) params; +#include "SDL_aaudiofuncs.h" +#undef SDL_PROC +} AAUDIO_Data; +static AAUDIO_Data ctx; + +static SDL_AudioDevice *audioDevice = NULL; +static SDL_AudioDevice *captureDevice = NULL; + +static int aaudio_LoadFunctions(AAUDIO_Data *data) +{ +#define SDL_PROC(ret, func, params) \ + do { \ + data->func = SDL_LoadFunction(data->handle, #func); \ + if (!data->func) { \ + return SDL_SetError("Couldn't load AAUDIO function %s: %s", #func, SDL_GetError()); \ + } \ + } while (0); +#include "SDL_aaudiofuncs.h" +#undef SDL_PROC + return 0; +} + +void aaudio_errorCallback(AAudioStream *stream, void *userData, aaudio_result_t error); +void aaudio_errorCallback(AAudioStream *stream, void *userData, aaudio_result_t error) +{ + LOGI("SDL aaudio_errorCallback: %d - %s", error, ctx.AAudio_convertResultToText(error)); +} + +#define LIB_AAUDIO_SO "libaaudio.so" + +static int aaudio_OpenDevice(_THIS, const char *devname) +{ + struct SDL_PrivateAudioData *private; + SDL_bool iscapture = this->iscapture; + aaudio_result_t res; + LOGI(__func__); + + SDL_assert((captureDevice == NULL) || !iscapture); + SDL_assert((audioDevice == NULL) || iscapture); + + if (iscapture) { + if (!Android_JNI_RequestPermission("android.permission.RECORD_AUDIO")) { + LOGI("This app doesn't have RECORD_AUDIO permission"); + return SDL_SetError("This app doesn't have RECORD_AUDIO permission"); + } + } + + if (iscapture) { + captureDevice = this; + } else { + audioDevice = this; + } + + this->hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, sizeof(*this->hidden)); + if (!this->hidden) { + return SDL_OutOfMemory(); + } + private = this->hidden; + + ctx.AAudioStreamBuilder_setSampleRate(ctx.builder, this->spec.freq); + ctx.AAudioStreamBuilder_setChannelCount(ctx.builder, this->spec.channels); + if(devname) { + private->devid = SDL_atoi(devname); + LOGI("Opening device id %d", private->devid); + ctx.AAudioStreamBuilder_setDeviceId(ctx.builder, private->devid); + } + { + const aaudio_direction_t direction = (iscapture ? AAUDIO_DIRECTION_INPUT : AAUDIO_DIRECTION_OUTPUT); + ctx.AAudioStreamBuilder_setDirection(ctx.builder, direction); + } + { + const aaudio_format_t format = (this->spec.format == AUDIO_S16SYS) ? AAUDIO_FORMAT_PCM_I16 : AAUDIO_FORMAT_PCM_FLOAT; + ctx.AAudioStreamBuilder_setFormat(ctx.builder, format); + } + + ctx.AAudioStreamBuilder_setErrorCallback(ctx.builder, aaudio_errorCallback, private); + ctx.AAudioStreamBuilder_setPerformanceMode(ctx.builder, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY); + + LOGI("AAudio Try to open %u hz %u bit chan %u %s samples %u", + this->spec.freq, SDL_AUDIO_BITSIZE(this->spec.format), + this->spec.channels, (this->spec.format & 0x1000) ? "BE" : "LE", this->spec.samples); + + res = ctx.AAudioStreamBuilder_openStream(ctx.builder, &private->stream); + if (res != AAUDIO_OK) { + LOGI("SDL Failed AAudioStreamBuilder_openStream %d", res); + return SDL_SetError("%s : %s", __func__, ctx.AAudio_convertResultToText(res)); + } + + this->spec.freq = ctx.AAudioStream_getSampleRate(private->stream); + this->spec.channels = ctx.AAudioStream_getChannelCount(private->stream); + { + aaudio_format_t fmt = ctx.AAudioStream_getFormat(private->stream); + if (fmt == AAUDIO_FORMAT_PCM_I16) { + this->spec.format = AUDIO_S16SYS; + } else if (fmt == AAUDIO_FORMAT_PCM_FLOAT) { + this->spec.format = AUDIO_F32SYS; + } + } + + LOGI("AAudio Try to open %u hz %u bit chan %u %s samples %u", + this->spec.freq, SDL_AUDIO_BITSIZE(this->spec.format), + this->spec.channels, (this->spec.format & 0x1000) ? "BE" : "LE", this->spec.samples); + + SDL_CalculateAudioSpec(&this->spec); + + /* Allocate mixing buffer */ + if (!iscapture) { + private->mixlen = this->spec.size; + private->mixbuf = (Uint8 *)SDL_malloc(private->mixlen); + if (!private->mixbuf) { + return SDL_OutOfMemory(); + } + SDL_memset(private->mixbuf, this->spec.silence, this->spec.size); + } + + private->frame_size = this->spec.channels * (SDL_AUDIO_BITSIZE(this->spec.format) / 8); + + res = ctx.AAudioStream_requestStart(private->stream); + if (res != AAUDIO_OK) { + LOGI("SDL Failed AAudioStream_requestStart %d iscapture:%d", res, iscapture); + return SDL_SetError("%s : %s", __func__, ctx.AAudio_convertResultToText(res)); + } + + LOGI("SDL AAudioStream_requestStart OK"); + return 0; +} + +static void aaudio_CloseDevice(_THIS) +{ + struct SDL_PrivateAudioData *private = this->hidden; + aaudio_result_t res; + LOGI(__func__); + + if (private->stream) { + res = ctx.AAudioStream_requestStop(private->stream); + if (res != AAUDIO_OK) { + LOGI("SDL Failed AAudioStream_requestStop %d", res); + SDL_SetError("%s : %s", __func__, ctx.AAudio_convertResultToText(res)); + return; + } + + res = ctx.AAudioStream_close(private->stream); + if (res != AAUDIO_OK) { + LOGI("SDL Failed AAudioStreamBuilder_delete %d", res); + SDL_SetError("%s : %s", __func__, ctx.AAudio_convertResultToText(res)); + return; + } + } + + if (this->iscapture) { + SDL_assert(captureDevice == this); + captureDevice = NULL; + } else { + SDL_assert(audioDevice == this); + audioDevice = NULL; + } + + SDL_free(this->hidden->mixbuf); + SDL_free(this->hidden); +} + +static Uint8 *aaudio_GetDeviceBuf(_THIS) +{ + struct SDL_PrivateAudioData *private = this->hidden; + return private->mixbuf; +} + +/* Try to reestablish an AAudioStream. + + This needs to get a stream with the same format as the previous one, + even if this means AAudio needs to handle a conversion it didn't when + we initially opened the device. If we can't get that, we are forced + to give up here. + + (This is more robust in SDL3, which is designed to handle + abrupt format changes.) +*/ +static int RebuildAAudioStream(SDL_AudioDevice *device) +{ + struct SDL_PrivateAudioData *hidden = device->hidden; + const SDL_bool iscapture = device->iscapture; + aaudio_result_t res; + + ctx.AAudioStreamBuilder_setSampleRate(ctx.builder, device->spec.freq); + ctx.AAudioStreamBuilder_setChannelCount(ctx.builder, device->spec.channels); + if(hidden->devid) { + LOGI("Reopening device id %d", hidden->devid); + ctx.AAudioStreamBuilder_setDeviceId(ctx.builder, hidden->devid); + } + { + const aaudio_direction_t direction = (iscapture ? AAUDIO_DIRECTION_INPUT : AAUDIO_DIRECTION_OUTPUT); + ctx.AAudioStreamBuilder_setDirection(ctx.builder, direction); + } + { + const aaudio_format_t format = (device->spec.format == AUDIO_S16SYS) ? AAUDIO_FORMAT_PCM_I16 : AAUDIO_FORMAT_PCM_FLOAT; + ctx.AAudioStreamBuilder_setFormat(ctx.builder, format); + } + + ctx.AAudioStreamBuilder_setErrorCallback(ctx.builder, aaudio_errorCallback, hidden); + ctx.AAudioStreamBuilder_setPerformanceMode(ctx.builder, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY); + + LOGI("AAudio Try to reopen %u hz %u bit chan %u %s samples %u", + device->spec.freq, SDL_AUDIO_BITSIZE(device->spec.format), + device->spec.channels, (device->spec.format & 0x1000) ? "BE" : "LE", device->spec.samples); + + res = ctx.AAudioStreamBuilder_openStream(ctx.builder, &hidden->stream); + if (res != AAUDIO_OK) { + LOGI("SDL Failed AAudioStreamBuilder_openStream %d", res); + return SDL_SetError("%s : %s", __func__, ctx.AAudio_convertResultToText(res)); + } + + { + const aaudio_format_t fmt = ctx.AAudioStream_getFormat(hidden->stream); + SDL_AudioFormat sdlfmt = (SDL_AudioFormat) 0; + if (fmt == AAUDIO_FORMAT_PCM_I16) { + sdlfmt = AUDIO_S16SYS; + } else if (fmt == AAUDIO_FORMAT_PCM_FLOAT) { + sdlfmt = AUDIO_F32SYS; + } + + /* We handle this better in SDL3, but this _needs_ to match the previous stream for SDL2. */ + if ( (device->spec.freq != ctx.AAudioStream_getSampleRate(hidden->stream)) || + (device->spec.channels != ctx.AAudioStream_getChannelCount(hidden->stream)) || + (device->spec.format != sdlfmt) ) { + LOGI("Didn't get an identical spec from AAudioStream during reopen!"); + ctx.AAudioStream_close(hidden->stream); + hidden->stream = NULL; + return SDL_SetError("Didn't get an identical spec from AAudioStream during reopen!"); + } + } + + res = ctx.AAudioStream_requestStart(hidden->stream); + if (res != AAUDIO_OK) { + LOGI("SDL Failed AAudioStream_requestStart %d iscapture:%d", res, iscapture); + return SDL_SetError("%s : %s", __func__, ctx.AAudio_convertResultToText(res)); + } + + return 0; +} + +static int RecoverAAudioDevice(SDL_AudioDevice *device) +{ + struct SDL_PrivateAudioData *hidden = device->hidden; + AAudioStream *stream = hidden->stream; + + /* attempt to build a new stream, in case there's a new default device. */ + hidden->stream = NULL; + ctx.AAudioStream_requestStop(stream); + ctx.AAudioStream_close(stream); + + if (RebuildAAudioStream(device) < 0) { + return -1; // oh well, we tried. + } + + return 0; +} + + +static void aaudio_PlayDevice(_THIS) +{ + struct SDL_PrivateAudioData *private = this->hidden; + aaudio_result_t res; + int64_t timeoutNanoseconds = 1 * 1000 * 1000; /* 8 ms */ + res = ctx.AAudioStream_write(private->stream, private->mixbuf, private->mixlen / private->frame_size, timeoutNanoseconds); + if (res < 0) { + LOGI("%s : %s", __func__, ctx.AAudio_convertResultToText(res)); + if (RecoverAAudioDevice(this) < 0) { + return; /* oh well, we went down hard. */ + } + } else { + LOGI("SDL AAudio play: %d frames, wanted:%d frames", (int)res, private->mixlen / private->frame_size); + } + +#if 0 + /* Log under-run count */ + { + static int prev = 0; + int32_t cnt = ctx.AAudioStream_getXRunCount(private->stream); + if (cnt != prev) { + SDL_Log("AAudio underrun: %d - total: %d", cnt - prev, cnt); + prev = cnt; + } + } +#endif +} + +static int aaudio_CaptureFromDevice(_THIS, void *buffer, int buflen) +{ + struct SDL_PrivateAudioData *private = this->hidden; + aaudio_result_t res; + int64_t timeoutNanoseconds = 8 * 1000 * 1000; /* 8 ms */ + res = ctx.AAudioStream_read(private->stream, buffer, buflen / private->frame_size, timeoutNanoseconds); + if (res < 0) { + LOGI("%s : %s", __func__, ctx.AAudio_convertResultToText(res)); + return -1; + } + LOGI("SDL AAudio capture:%d frames, wanted:%d frames", (int)res, buflen / private->frame_size); + return res * private->frame_size; +} + +static void aaudio_Deinitialize(void) +{ + LOGI(__func__); + if (ctx.handle) { + if (ctx.builder) { + aaudio_result_t res; + res = ctx.AAudioStreamBuilder_delete(ctx.builder); + if (res != AAUDIO_OK) { + SDL_SetError("Failed AAudioStreamBuilder_delete %s", ctx.AAudio_convertResultToText(res)); + } + } + SDL_UnloadObject(ctx.handle); + } + ctx.handle = NULL; + ctx.builder = NULL; + LOGI("End AAUDIO %s", SDL_GetError()); +} + +static SDL_bool aaudio_Init(SDL_AudioDriverImpl *impl) +{ + aaudio_result_t res; + LOGI(__func__); + + /* AAudio was introduced in Android 8.0, but has reference counting crash issues in that release, + * so don't use it until 8.1. + * + * See https://github.com/google/oboe/issues/40 for more information. + */ + if (SDL_GetAndroidSDKVersion() < 27) { + return SDL_FALSE; + } + + SDL_zero(ctx); + + ctx.handle = SDL_LoadObject(LIB_AAUDIO_SO); + if (!ctx.handle) { + LOGI("SDL couldn't find " LIB_AAUDIO_SO); + goto failure; + } + + if (aaudio_LoadFunctions(&ctx) < 0) { + goto failure; + } + + res = ctx.AAudio_createStreamBuilder(&ctx.builder); + if (res != AAUDIO_OK) { + LOGI("SDL Failed AAudio_createStreamBuilder %d", res); + goto failure; + } + + if (!ctx.builder) { + LOGI("SDL Failed AAudio_createStreamBuilder - builder NULL"); + goto failure; + } + + impl->DetectDevices = Android_DetectDevices; + impl->Deinitialize = aaudio_Deinitialize; + impl->OpenDevice = aaudio_OpenDevice; + impl->CloseDevice = aaudio_CloseDevice; + impl->PlayDevice = aaudio_PlayDevice; + impl->GetDeviceBuf = aaudio_GetDeviceBuf; + impl->CaptureFromDevice = aaudio_CaptureFromDevice; + impl->AllowsArbitraryDeviceNames = SDL_TRUE; + + /* and the capabilities */ + impl->HasCaptureSupport = SDL_TRUE; + impl->OnlyHasDefaultOutputDevice = SDL_FALSE; + impl->OnlyHasDefaultCaptureDevice = SDL_FALSE; + + /* this audio target is available. */ + LOGI("SDL aaudio_Init OK"); + return SDL_TRUE; + +failure: + if (ctx.handle) { + if (ctx.builder) { + ctx.AAudioStreamBuilder_delete(ctx.builder); + } + SDL_UnloadObject(ctx.handle); + } + ctx.handle = NULL; + ctx.builder = NULL; + return SDL_FALSE; +} + +AudioBootStrap aaudio_bootstrap = { + "AAudio", "AAudio audio driver", aaudio_Init, SDL_FALSE +}; + +/* Pause (block) all non already paused audio devices by taking their mixer lock */ +void aaudio_PauseDevices(void) +{ + /* TODO: Handle multiple devices? */ + struct SDL_PrivateAudioData *private; + if (audioDevice && audioDevice->hidden) { + SDL_LockMutex(audioDevice->mixer_lock); + private = (struct SDL_PrivateAudioData *)audioDevice->hidden; + if (private->stream) { + aaudio_result_t res = ctx.AAudioStream_requestPause(private->stream); + if (res != AAUDIO_OK) { + LOGI("SDL Failed AAudioStream_requestPause %d", res); + SDL_SetError("%s : %s", __func__, ctx.AAudio_convertResultToText(res)); + } + } + } + + if (captureDevice && captureDevice->hidden) { + SDL_LockMutex(captureDevice->mixer_lock); + private = (struct SDL_PrivateAudioData *)captureDevice->hidden; + if (private->stream) { + /* Pause() isn't implemented for 'capture', use Stop() */ + aaudio_result_t res = ctx.AAudioStream_requestStop(private->stream); + if (res != AAUDIO_OK) { + LOGI("SDL Failed AAudioStream_requestStop %d", res); + SDL_SetError("%s : %s", __func__, ctx.AAudio_convertResultToText(res)); + } + } + } +} + +/* Resume (unblock) all non already paused audio devices by releasing their mixer lock */ +void aaudio_ResumeDevices(void) +{ + /* TODO: Handle multiple devices? */ + struct SDL_PrivateAudioData *private; + if (audioDevice && audioDevice->hidden) { + private = (struct SDL_PrivateAudioData *)audioDevice->hidden; + if (private->stream) { + aaudio_result_t res = ctx.AAudioStream_requestStart(private->stream); + if (res != AAUDIO_OK) { + LOGI("SDL Failed AAudioStream_requestStart %d", res); + SDL_SetError("%s : %s", __func__, ctx.AAudio_convertResultToText(res)); + } + } + SDL_UnlockMutex(audioDevice->mixer_lock); + } + + if (captureDevice && captureDevice->hidden) { + private = (struct SDL_PrivateAudioData *)captureDevice->hidden; + if (private->stream) { + aaudio_result_t res = ctx.AAudioStream_requestStart(private->stream); + if (res != AAUDIO_OK) { + LOGI("SDL Failed AAudioStream_requestStart %d", res); + SDL_SetError("%s : %s", __func__, ctx.AAudio_convertResultToText(res)); + } + } + SDL_UnlockMutex(captureDevice->mixer_lock); + } +} + +/* + We can sometimes get into a state where AAudioStream_write() will just block forever until we pause and unpause. + None of the standard state queries indicate any problem in my testing. And the error callback doesn't actually get called. + But, AAudioStream_getTimestamp() does return AAUDIO_ERROR_INVALID_STATE +*/ +SDL_bool aaudio_DetectBrokenPlayState(void) +{ + AAudioStream *stream; + struct SDL_PrivateAudioData *private; + int64_t framePosition, timeNanoseconds; + aaudio_result_t res; + + if (!audioDevice || !audioDevice->hidden) { + return SDL_FALSE; + } + + private = audioDevice->hidden; + stream = private->stream; + if (!stream) { + return SDL_FALSE; + } + + res = ctx.AAudioStream_getTimestamp(stream, CLOCK_MONOTONIC, &framePosition, &timeNanoseconds); + if (res == AAUDIO_ERROR_INVALID_STATE) { + aaudio_stream_state_t currentState = ctx.AAudioStream_getState(stream); + /* AAudioStream_getTimestamp() will also return AAUDIO_ERROR_INVALID_STATE while the stream is still initially starting. But we only care if it silently went invalid while playing. */ + if (currentState == AAUDIO_STREAM_STATE_STARTED) { + LOGI("SDL aaudio_DetectBrokenPlayState: detected invalid audio device state: AAudioStream_getTimestamp result=%d, framePosition=%lld, timeNanoseconds=%lld, getState=%d", (int)res, (long long)framePosition, (long long)timeNanoseconds, (int)currentState); + return SDL_TRUE; + } + } + + return SDL_FALSE; +} + +#endif /* SDL_AUDIO_DRIVER_AAUDIO */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/audio/aaudio/SDL_aaudio.h b/SDL2-2.30.5/src/audio/aaudio/SDL_aaudio.h new file mode 100644 index 0000000..d61d1b0 --- /dev/null +++ b/SDL2-2.30.5/src/audio/aaudio/SDL_aaudio.h @@ -0,0 +1,50 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifndef _SDL_aaudio_h +#define _SDL_aaudio_h + +#include "../SDL_sysaudio.h" +#include +#include + +/* Hidden "this" pointer for the audio functions */ +#define _THIS SDL_AudioDevice *this + +struct SDL_PrivateAudioData +{ + AAudioStream *stream; + + /* Raw mixing buffer */ + Uint8 *mixbuf; + int mixlen; + int frame_size; + int devid; +}; + +void aaudio_ResumeDevices(void); +void aaudio_PauseDevices(void); +SDL_bool aaudio_DetectBrokenPlayState(void); + +#endif /* _SDL_aaudio_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/audio/aaudio/SDL_aaudiofuncs.h b/SDL2-2.30.5/src/audio/aaudio/SDL_aaudiofuncs.h new file mode 100644 index 0000000..2bc674c --- /dev/null +++ b/SDL2-2.30.5/src/audio/aaudio/SDL_aaudiofuncs.h @@ -0,0 +1,79 @@ +/* + Simple DirectMedia Layer + Copyright , (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#define SDL_PROC_UNUSED(ret, func, params) + +SDL_PROC(const char *, AAudio_convertResultToText, (aaudio_result_t returnCode)) +SDL_PROC(const char *, AAudio_convertStreamStateToText, (aaudio_stream_state_t state)) +SDL_PROC(aaudio_result_t, AAudio_createStreamBuilder, (AAudioStreamBuilder * *builder)) +SDL_PROC(void, AAudioStreamBuilder_setDeviceId, (AAudioStreamBuilder * builder, int32_t deviceId)) +SDL_PROC(void, AAudioStreamBuilder_setSampleRate, (AAudioStreamBuilder * builder, int32_t sampleRate)) +SDL_PROC(void, AAudioStreamBuilder_setChannelCount, (AAudioStreamBuilder * builder, int32_t channelCount)) +SDL_PROC_UNUSED(void, AAudioStreamBuilder_setSamplesPerFrame, (AAudioStreamBuilder * builder, int32_t samplesPerFrame)) +SDL_PROC(void, AAudioStreamBuilder_setFormat, (AAudioStreamBuilder * builder, aaudio_format_t format)) +SDL_PROC_UNUSED(void, AAudioStreamBuilder_setSharingMode, (AAudioStreamBuilder * builder, aaudio_sharing_mode_t sharingMode)) +SDL_PROC(void, AAudioStreamBuilder_setDirection, (AAudioStreamBuilder * builder, aaudio_direction_t direction)) +SDL_PROC_UNUSED(void, AAudioStreamBuilder_setBufferCapacityInFrames, (AAudioStreamBuilder * builder, int32_t numFrames)) +SDL_PROC(void, AAudioStreamBuilder_setPerformanceMode, (AAudioStreamBuilder * builder, aaudio_performance_mode_t mode)) +SDL_PROC_UNUSED(void, AAudioStreamBuilder_setUsage, (AAudioStreamBuilder * builder, aaudio_usage_t usage)) /* API 28 */ +SDL_PROC_UNUSED(void, AAudioStreamBuilder_setContentType, (AAudioStreamBuilder * builder, aaudio_content_type_t contentType)) /* API 28 */ +SDL_PROC_UNUSED(void, AAudioStreamBuilder_setInputPreset, (AAudioStreamBuilder * builder, aaudio_input_preset_t inputPreset)) /* API 28 */ +SDL_PROC_UNUSED(void, AAudioStreamBuilder_setAllowedCapturePolicy, (AAudioStreamBuilder * builder, aaudio_allowed_capture_policy_t capturePolicy)) /* API 29 */ +SDL_PROC_UNUSED(void, AAudioStreamBuilder_setSessionId, (AAudioStreamBuilder * builder, aaudio_session_id_t sessionId)) /* API 28 */ +SDL_PROC_UNUSED(void, AAudioStreamBuilder_setPrivacySensitive, (AAudioStreamBuilder * builder, bool privacySensitive)) /* API 30 */ +SDL_PROC_UNUSED(void, AAudioStreamBuilder_setDataCallback, (AAudioStreamBuilder * builder, AAudioStream_dataCallback callback, void *userData)) +SDL_PROC_UNUSED(void, AAudioStreamBuilder_setFramesPerDataCallback, (AAudioStreamBuilder * builder, int32_t numFrames)) +SDL_PROC(void, AAudioStreamBuilder_setErrorCallback, (AAudioStreamBuilder * builder, AAudioStream_errorCallback callback, void *userData)) +SDL_PROC(aaudio_result_t, AAudioStreamBuilder_openStream, (AAudioStreamBuilder * builder, AAudioStream **stream)) +SDL_PROC(aaudio_result_t, AAudioStreamBuilder_delete, (AAudioStreamBuilder * builder)) +SDL_PROC_UNUSED(aaudio_result_t, AAudioStream_release, (AAudioStream * stream)) /* API 30 */ +SDL_PROC(aaudio_result_t, AAudioStream_close, (AAudioStream * stream)) +SDL_PROC(aaudio_result_t, AAudioStream_requestStart, (AAudioStream * stream)) +SDL_PROC(aaudio_result_t, AAudioStream_requestPause, (AAudioStream * stream)) +SDL_PROC_UNUSED(aaudio_result_t, AAudioStream_requestFlush, (AAudioStream * stream)) +SDL_PROC(aaudio_result_t, AAudioStream_requestStop, (AAudioStream * stream)) +SDL_PROC(aaudio_stream_state_t, AAudioStream_getState, (AAudioStream * stream)) +SDL_PROC_UNUSED(aaudio_result_t, AAudioStream_waitForStateChange, (AAudioStream * stream, aaudio_stream_state_t inputState, aaudio_stream_state_t *nextState, int64_t timeoutNanoseconds)) +SDL_PROC(aaudio_result_t, AAudioStream_read, (AAudioStream * stream, void *buffer, int32_t numFrames, int64_t timeoutNanoseconds)) +SDL_PROC(aaudio_result_t, AAudioStream_write, (AAudioStream * stream, const void *buffer, int32_t numFrames, int64_t timeoutNanoseconds)) +SDL_PROC_UNUSED(aaudio_result_t, AAudioStream_setBufferSizeInFrames, (AAudioStream * stream, int32_t numFrames)) +SDL_PROC_UNUSED(int32_t, AAudioStream_getBufferSizeInFrames, (AAudioStream * stream)) +SDL_PROC_UNUSED(int32_t, AAudioStream_getFramesPerBurst, (AAudioStream * stream)) +SDL_PROC_UNUSED(int32_t, AAudioStream_getBufferCapacityInFrames, (AAudioStream * stream)) +SDL_PROC_UNUSED(int32_t, AAudioStream_getFramesPerDataCallback, (AAudioStream * stream)) +SDL_PROC(int32_t, AAudioStream_getXRunCount, (AAudioStream * stream)) +SDL_PROC(int32_t, AAudioStream_getSampleRate, (AAudioStream * stream)) +SDL_PROC(int32_t, AAudioStream_getChannelCount, (AAudioStream * stream)) +SDL_PROC_UNUSED(int32_t, AAudioStream_getSamplesPerFrame, (AAudioStream * stream)) +SDL_PROC_UNUSED(int32_t, AAudioStream_getDeviceId, (AAudioStream * stream)) +SDL_PROC(aaudio_format_t, AAudioStream_getFormat, (AAudioStream * stream)) +SDL_PROC_UNUSED(aaudio_sharing_mode_t, AAudioStream_getSharingMode, (AAudioStream * stream)) +SDL_PROC_UNUSED(aaudio_performance_mode_t, AAudioStream_getPerformanceMode, (AAudioStream * stream)) +SDL_PROC_UNUSED(aaudio_direction_t, AAudioStream_getDirection, (AAudioStream * stream)) +SDL_PROC_UNUSED(int64_t, AAudioStream_getFramesWritten, (AAudioStream * stream)) +SDL_PROC_UNUSED(int64_t, AAudioStream_getFramesRead, (AAudioStream * stream)) +SDL_PROC_UNUSED(aaudio_session_id_t, AAudioStream_getSessionId, (AAudioStream * stream)) /* API 28 */ +SDL_PROC(aaudio_result_t, AAudioStream_getTimestamp, (AAudioStream * stream, clockid_t clockid, int64_t *framePosition, int64_t *timeNanoseconds)) +SDL_PROC_UNUSED(aaudio_usage_t, AAudioStream_getUsage, (AAudioStream * stream)) /* API 28 */ +SDL_PROC_UNUSED(aaudio_content_type_t, AAudioStream_getContentType, (AAudioStream * stream)) /* API 28 */ +SDL_PROC_UNUSED(aaudio_input_preset_t, AAudioStream_getInputPreset, (AAudioStream * stream)) /* API 28 */ +SDL_PROC_UNUSED(aaudio_allowed_capture_policy_t, AAudioStream_getAllowedCapturePolicy, (AAudioStream * stream)) /* API 29 */ +SDL_PROC_UNUSED(bool, AAudioStream_isPrivacySensitive, (AAudioStream * stream)) /* API 30 */ diff --git a/SDL2-2.30.5/src/audio/alsa/SDL_alsa_audio.c b/SDL2-2.30.5/src/audio/alsa/SDL_alsa_audio.c new file mode 100644 index 0000000..3ed66f2 --- /dev/null +++ b/SDL2-2.30.5/src/audio/alsa/SDL_alsa_audio.c @@ -0,0 +1,991 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_AUDIO_DRIVER_ALSA + +#ifndef SDL_ALSA_NON_BLOCKING +#define SDL_ALSA_NON_BLOCKING 0 +#endif + +/* without the thread, you will detect devices on startup, but will not get futher hotplug events. But that might be okay. */ +#ifndef SDL_ALSA_HOTPLUG_THREAD +#define SDL_ALSA_HOTPLUG_THREAD 1 +#endif + +/* Allow access to a raw mixing buffer */ + +#include +#include /* For kill() */ +#include + +#include "SDL_timer.h" +#include "SDL_audio.h" +#include "../SDL_audio_c.h" +#include "SDL_alsa_audio.h" + +#ifdef SDL_AUDIO_DRIVER_ALSA_DYNAMIC +#include "SDL_loadso.h" +#endif + +static int (*ALSA_snd_pcm_open)(snd_pcm_t **, const char *, snd_pcm_stream_t, int); +static int (*ALSA_snd_pcm_close)(snd_pcm_t *pcm); +static snd_pcm_sframes_t (*ALSA_snd_pcm_writei)(snd_pcm_t *, const void *, snd_pcm_uframes_t); +static snd_pcm_sframes_t (*ALSA_snd_pcm_readi)(snd_pcm_t *, void *, snd_pcm_uframes_t); +static int (*ALSA_snd_pcm_recover)(snd_pcm_t *, int, int); +static int (*ALSA_snd_pcm_prepare)(snd_pcm_t *); +static int (*ALSA_snd_pcm_drain)(snd_pcm_t *); +static const char *(*ALSA_snd_strerror)(int); +static size_t (*ALSA_snd_pcm_hw_params_sizeof)(void); +static size_t (*ALSA_snd_pcm_sw_params_sizeof)(void); +static void (*ALSA_snd_pcm_hw_params_copy)(snd_pcm_hw_params_t *, const snd_pcm_hw_params_t *); +static int (*ALSA_snd_pcm_hw_params_any)(snd_pcm_t *, snd_pcm_hw_params_t *); +static int (*ALSA_snd_pcm_hw_params_set_access)(snd_pcm_t *, snd_pcm_hw_params_t *, snd_pcm_access_t); +static int (*ALSA_snd_pcm_hw_params_set_format)(snd_pcm_t *, snd_pcm_hw_params_t *, snd_pcm_format_t); +static int (*ALSA_snd_pcm_hw_params_set_channels)(snd_pcm_t *, snd_pcm_hw_params_t *, unsigned int); +static int (*ALSA_snd_pcm_hw_params_get_channels)(const snd_pcm_hw_params_t *, unsigned int *); +static int (*ALSA_snd_pcm_hw_params_set_rate_near)(snd_pcm_t *, snd_pcm_hw_params_t *, unsigned int *, int *); +static int (*ALSA_snd_pcm_hw_params_set_period_size_near)(snd_pcm_t *, snd_pcm_hw_params_t *, snd_pcm_uframes_t *, int *); +static int (*ALSA_snd_pcm_hw_params_get_period_size)(const snd_pcm_hw_params_t *, snd_pcm_uframes_t *, int *); +static int (*ALSA_snd_pcm_hw_params_set_periods_min)(snd_pcm_t *, snd_pcm_hw_params_t *, unsigned int *, int *); +static int (*ALSA_snd_pcm_hw_params_set_periods_first)(snd_pcm_t *, snd_pcm_hw_params_t *, unsigned int *, int *); +static int (*ALSA_snd_pcm_hw_params_get_periods)(const snd_pcm_hw_params_t *, unsigned int *, int *); +static int (*ALSA_snd_pcm_hw_params_set_buffer_size_near)(snd_pcm_t *pcm, snd_pcm_hw_params_t *, snd_pcm_uframes_t *); +static int (*ALSA_snd_pcm_hw_params_get_buffer_size)(const snd_pcm_hw_params_t *, snd_pcm_uframes_t *); +static int (*ALSA_snd_pcm_hw_params)(snd_pcm_t *, snd_pcm_hw_params_t *); +static int (*ALSA_snd_pcm_sw_params_current)(snd_pcm_t *, + snd_pcm_sw_params_t *); +static int (*ALSA_snd_pcm_sw_params_set_start_threshold)(snd_pcm_t *, snd_pcm_sw_params_t *, snd_pcm_uframes_t); +static int (*ALSA_snd_pcm_sw_params)(snd_pcm_t *, snd_pcm_sw_params_t *); +static int (*ALSA_snd_pcm_nonblock)(snd_pcm_t *, int); +static int (*ALSA_snd_pcm_wait)(snd_pcm_t *, int); +static int (*ALSA_snd_pcm_sw_params_set_avail_min)(snd_pcm_t *, snd_pcm_sw_params_t *, snd_pcm_uframes_t); +static int (*ALSA_snd_pcm_reset)(snd_pcm_t *); +static int (*ALSA_snd_device_name_hint)(int, const char *, void ***); +static char *(*ALSA_snd_device_name_get_hint)(const void *, const char *); +static int (*ALSA_snd_device_name_free_hint)(void **); +static snd_pcm_sframes_t (*ALSA_snd_pcm_avail)(snd_pcm_t *); +#ifdef SND_CHMAP_API_VERSION +static snd_pcm_chmap_t *(*ALSA_snd_pcm_get_chmap)(snd_pcm_t *); +static int (*ALSA_snd_pcm_chmap_print)(const snd_pcm_chmap_t *map, size_t maxlen, char *buf); +#endif + +#ifdef SDL_AUDIO_DRIVER_ALSA_DYNAMIC +#define snd_pcm_hw_params_sizeof ALSA_snd_pcm_hw_params_sizeof +#define snd_pcm_sw_params_sizeof ALSA_snd_pcm_sw_params_sizeof + +static const char *alsa_library = SDL_AUDIO_DRIVER_ALSA_DYNAMIC; +static void *alsa_handle = NULL; + +static int load_alsa_sym(const char *fn, void **addr) +{ + *addr = SDL_LoadFunction(alsa_handle, fn); + if (!*addr) { + /* Don't call SDL_SetError(): SDL_LoadFunction already did. */ + return 0; + } + + return 1; +} + +/* cast funcs to char* first, to please GCC's strict aliasing rules. */ +#define SDL_ALSA_SYM(x) \ + if (!load_alsa_sym(#x, (void **)(char *)&ALSA_##x)) \ + return -1 +#else +#define SDL_ALSA_SYM(x) ALSA_##x = x +#endif + +static int load_alsa_syms(void) +{ + SDL_ALSA_SYM(snd_pcm_open); + SDL_ALSA_SYM(snd_pcm_close); + SDL_ALSA_SYM(snd_pcm_writei); + SDL_ALSA_SYM(snd_pcm_readi); + SDL_ALSA_SYM(snd_pcm_recover); + SDL_ALSA_SYM(snd_pcm_prepare); + SDL_ALSA_SYM(snd_pcm_drain); + SDL_ALSA_SYM(snd_strerror); + SDL_ALSA_SYM(snd_pcm_hw_params_sizeof); + SDL_ALSA_SYM(snd_pcm_sw_params_sizeof); + SDL_ALSA_SYM(snd_pcm_hw_params_copy); + SDL_ALSA_SYM(snd_pcm_hw_params_any); + SDL_ALSA_SYM(snd_pcm_hw_params_set_access); + SDL_ALSA_SYM(snd_pcm_hw_params_set_format); + SDL_ALSA_SYM(snd_pcm_hw_params_set_channels); + SDL_ALSA_SYM(snd_pcm_hw_params_get_channels); + SDL_ALSA_SYM(snd_pcm_hw_params_set_rate_near); + SDL_ALSA_SYM(snd_pcm_hw_params_set_period_size_near); + SDL_ALSA_SYM(snd_pcm_hw_params_get_period_size); + SDL_ALSA_SYM(snd_pcm_hw_params_set_periods_min); + SDL_ALSA_SYM(snd_pcm_hw_params_set_periods_first); + SDL_ALSA_SYM(snd_pcm_hw_params_get_periods); + SDL_ALSA_SYM(snd_pcm_hw_params_set_buffer_size_near); + SDL_ALSA_SYM(snd_pcm_hw_params_get_buffer_size); + SDL_ALSA_SYM(snd_pcm_hw_params); + SDL_ALSA_SYM(snd_pcm_sw_params_current); + SDL_ALSA_SYM(snd_pcm_sw_params_set_start_threshold); + SDL_ALSA_SYM(snd_pcm_sw_params); + SDL_ALSA_SYM(snd_pcm_nonblock); + SDL_ALSA_SYM(snd_pcm_wait); + SDL_ALSA_SYM(snd_pcm_sw_params_set_avail_min); + SDL_ALSA_SYM(snd_pcm_reset); + SDL_ALSA_SYM(snd_device_name_hint); + SDL_ALSA_SYM(snd_device_name_get_hint); + SDL_ALSA_SYM(snd_device_name_free_hint); + SDL_ALSA_SYM(snd_pcm_avail); +#ifdef SND_CHMAP_API_VERSION + SDL_ALSA_SYM(snd_pcm_get_chmap); + SDL_ALSA_SYM(snd_pcm_chmap_print); +#endif + + return 0; +} + +#undef SDL_ALSA_SYM + +#ifdef SDL_AUDIO_DRIVER_ALSA_DYNAMIC + +static void UnloadALSALibrary(void) +{ + if (alsa_handle) { + SDL_UnloadObject(alsa_handle); + alsa_handle = NULL; + } +} + +static int LoadALSALibrary(void) +{ + int retval = 0; + if (!alsa_handle) { + alsa_handle = SDL_LoadObject(alsa_library); + if (!alsa_handle) { + retval = -1; + /* Don't call SDL_SetError(): SDL_LoadObject already did. */ + } else { + retval = load_alsa_syms(); + if (retval < 0) { + UnloadALSALibrary(); + } + } + } + return retval; +} + +#else + +static void UnloadALSALibrary(void) +{ +} + +static int LoadALSALibrary(void) +{ + load_alsa_syms(); + return 0; +} + +#endif /* SDL_AUDIO_DRIVER_ALSA_DYNAMIC */ + +static const char *get_audio_device(void *handle, const int channels) +{ + const char *device; + + if (handle) { + return (const char *)handle; + } + + /* !!! FIXME: we also check "SDL_AUDIO_DEVICE_NAME" at the higher level. */ + device = SDL_getenv("AUDIODEV"); /* Is there a standard variable name? */ + if (device) { + return device; + } + + if (channels == 6) { + return "plug:surround51"; + } else if (channels == 4) { + return "plug:surround40"; + } + + return "default"; +} + +/* This function waits until it is possible to write a full sound buffer */ +static void ALSA_WaitDevice(_THIS) +{ +#if SDL_ALSA_NON_BLOCKING + const snd_pcm_sframes_t needed = (snd_pcm_sframes_t)this->spec.samples; + while (SDL_AtomicGet(&this->enabled)) { + const snd_pcm_sframes_t rc = ALSA_snd_pcm_avail(this->hidden->pcm_handle); + if ((rc < 0) && (rc != -EAGAIN)) { + /* Hmm, not much we can do - abort */ + fprintf(stderr, "ALSA snd_pcm_avail failed (unrecoverable): %s\n", + ALSA_snd_strerror(rc)); + SDL_OpenedAudioDeviceDisconnected(this); + return; + } else if (rc < needed) { + const Uint32 delay = ((needed - (SDL_max(rc, 0))) * 1000) / this->spec.freq; + SDL_Delay(SDL_max(delay, 10)); + } else { + break; /* ready to go! */ + } + } +#endif +} + +/* !!! FIXME: is there a channel swizzler in alsalib instead? */ +/* + * https://bugzilla.libsdl.org/show_bug.cgi?id=110 + * "For Linux ALSA, this is FL-FR-RL-RR-C-LFE + * and for Windows DirectX [and CoreAudio], this is FL-FR-C-LFE-RL-RR" + */ +#define SWIZ6(T) \ + static void swizzle_alsa_channels_6_##T(void *buffer, const Uint32 bufferlen) \ + { \ + T *ptr = (T *)buffer; \ + Uint32 i; \ + for (i = 0; i < bufferlen; i++, ptr += 6) { \ + T tmp; \ + tmp = ptr[2]; \ + ptr[2] = ptr[4]; \ + ptr[4] = tmp; \ + tmp = ptr[3]; \ + ptr[3] = ptr[5]; \ + ptr[5] = tmp; \ + } \ + } + +/* !!! FIXME: is there a channel swizzler in alsalib instead? */ +/* !!! FIXME: this screams for a SIMD shuffle operation. */ +/* + * https://docs.microsoft.com/en-us/windows-hardware/drivers/audio/mapping-stream-formats-to-speaker-configurations + * For Linux ALSA, this appears to be FL-FR-RL-RR-C-LFE-SL-SR + * and for Windows DirectX [and CoreAudio], this is FL-FR-C-LFE-SL-SR-RL-RR" + */ +#define SWIZ8(T) \ + static void swizzle_alsa_channels_8_##T(void *buffer, const Uint32 bufferlen) \ + { \ + T *ptr = (T *)buffer; \ + Uint32 i; \ + for (i = 0; i < bufferlen; i++, ptr += 6) { \ + const T center = ptr[2]; \ + const T subwoofer = ptr[3]; \ + const T side_left = ptr[4]; \ + const T side_right = ptr[5]; \ + const T rear_left = ptr[6]; \ + const T rear_right = ptr[7]; \ + ptr[2] = rear_left; \ + ptr[3] = rear_right; \ + ptr[4] = center; \ + ptr[5] = subwoofer; \ + ptr[6] = side_left; \ + ptr[7] = side_right; \ + } \ + } + +#define CHANNEL_SWIZZLE(x) \ + x(Uint64) \ + x(Uint32) \ + x(Uint16) \ + x(Uint8) + +CHANNEL_SWIZZLE(SWIZ6) +CHANNEL_SWIZZLE(SWIZ8) + +#undef CHANNEL_SWIZZLE +#undef SWIZ6 +#undef SWIZ8 + +/* + * Called right before feeding this->hidden->mixbuf to the hardware. Swizzle + * channels from Windows/Mac order to the format alsalib will want. + */ +static void swizzle_alsa_channels(_THIS, void *buffer, Uint32 bufferlen) +{ + switch (this->spec.channels) { +#define CHANSWIZ(chans) \ + case chans: \ + switch ((this->spec.format & (0xFF))) { \ + case 8: \ + swizzle_alsa_channels_##chans##_Uint8(buffer, bufferlen); \ + break; \ + case 16: \ + swizzle_alsa_channels_##chans##_Uint16(buffer, bufferlen); \ + break; \ + case 32: \ + swizzle_alsa_channels_##chans##_Uint32(buffer, bufferlen); \ + break; \ + case 64: \ + swizzle_alsa_channels_##chans##_Uint64(buffer, bufferlen); \ + break; \ + default: \ + SDL_assert(!"unhandled bitsize"); \ + break; \ + } \ + return; + + CHANSWIZ(6); + CHANSWIZ(8); +#undef CHANSWIZ + default: + break; + } +} + +#ifdef SND_CHMAP_API_VERSION +/* Some devices have the right channel map, no swizzling necessary */ +static void no_swizzle(_THIS, void *buffer, Uint32 bufferlen) +{ +} +#endif /* SND_CHMAP_API_VERSION */ + +static void ALSA_PlayDevice(_THIS) +{ + const Uint8 *sample_buf = (const Uint8 *)this->hidden->mixbuf; + const int frame_size = ((SDL_AUDIO_BITSIZE(this->spec.format)) / 8) * + this->spec.channels; + snd_pcm_uframes_t frames_left = ((snd_pcm_uframes_t)this->spec.samples); + + this->hidden->swizzle_func(this, this->hidden->mixbuf, frames_left); + + while (frames_left > 0 && SDL_AtomicGet(&this->enabled)) { + int status = ALSA_snd_pcm_writei(this->hidden->pcm_handle, + sample_buf, frames_left); + + if (status < 0) { + if (status == -EAGAIN) { + /* Apparently snd_pcm_recover() doesn't handle this case - + does it assume snd_pcm_wait() above? */ + SDL_Delay(1); + continue; + } + status = ALSA_snd_pcm_recover(this->hidden->pcm_handle, status, 0); + if (status < 0) { + /* Hmm, not much we can do - abort */ + SDL_LogError(SDL_LOG_CATEGORY_AUDIO, + "ALSA write failed (unrecoverable): %s\n", + ALSA_snd_strerror(status)); + SDL_OpenedAudioDeviceDisconnected(this); + return; + } + continue; + } else if (status == 0) { + /* No frames were written (no available space in pcm device). + Allow other threads to catch up. */ + Uint32 delay = (frames_left / 2 * 1000) / this->spec.freq; + SDL_Delay(delay); + } + + sample_buf += status * frame_size; + frames_left -= status; + } +} + +static Uint8 *ALSA_GetDeviceBuf(_THIS) +{ + return this->hidden->mixbuf; +} + +static int ALSA_CaptureFromDevice(_THIS, void *buffer, int buflen) +{ + Uint8 *sample_buf = (Uint8 *)buffer; + const int frame_size = ((SDL_AUDIO_BITSIZE(this->spec.format)) / 8) * + this->spec.channels; + const int total_frames = buflen / frame_size; + snd_pcm_uframes_t frames_left = total_frames; + snd_pcm_uframes_t wait_time = frame_size / 2; + + SDL_assert((buflen % frame_size) == 0); + + while (frames_left > 0 && SDL_AtomicGet(&this->enabled)) { + int status; + + status = ALSA_snd_pcm_readi(this->hidden->pcm_handle, + sample_buf, frames_left); + + if (status == -EAGAIN) { + ALSA_snd_pcm_wait(this->hidden->pcm_handle, wait_time); + status = 0; + } else if (status < 0) { + /*printf("ALSA: capture error %d\n", status);*/ + status = ALSA_snd_pcm_recover(this->hidden->pcm_handle, status, 0); + if (status < 0) { + /* Hmm, not much we can do - abort */ + SDL_LogError(SDL_LOG_CATEGORY_AUDIO, + "ALSA read failed (unrecoverable): %s\n", + ALSA_snd_strerror(status)); + return -1; + } + continue; + } + + /*printf("ALSA: captured %d bytes\n", status * frame_size);*/ + sample_buf += status * frame_size; + frames_left -= status; + } + + this->hidden->swizzle_func(this, buffer, total_frames - frames_left); + + return (total_frames - frames_left) * frame_size; +} + +static void ALSA_FlushCapture(_THIS) +{ + ALSA_snd_pcm_reset(this->hidden->pcm_handle); +} + +static void ALSA_CloseDevice(_THIS) +{ + if (this->hidden->pcm_handle) { + /* Wait for the submitted audio to drain + ALSA_snd_pcm_drop() can hang, so don't use that. + */ + Uint32 delay = ((this->spec.samples * 1000) / this->spec.freq) * 2; + SDL_Delay(delay); + + ALSA_snd_pcm_close(this->hidden->pcm_handle); + } + SDL_free(this->hidden->mixbuf); + SDL_free(this->hidden); +} + +static int ALSA_set_buffer_size(_THIS, snd_pcm_hw_params_t *params) +{ + int status; + snd_pcm_hw_params_t *hwparams; + snd_pcm_uframes_t persize; + unsigned int periods; + + /* Copy the hardware parameters for this setup */ + snd_pcm_hw_params_alloca(&hwparams); + ALSA_snd_pcm_hw_params_copy(hwparams, params); + + /* Attempt to match the period size to the requested buffer size */ + persize = this->spec.samples; + status = ALSA_snd_pcm_hw_params_set_period_size_near( + this->hidden->pcm_handle, hwparams, &persize, NULL); + if (status < 0) { + return -1; + } + + /* Need to at least double buffer */ + periods = 2; + status = ALSA_snd_pcm_hw_params_set_periods_min( + this->hidden->pcm_handle, hwparams, &periods, NULL); + if (status < 0) { + return -1; + } + + status = ALSA_snd_pcm_hw_params_set_periods_first( + this->hidden->pcm_handle, hwparams, &periods, NULL); + if (status < 0) { + return -1; + } + + /* "set" the hardware with the desired parameters */ + status = ALSA_snd_pcm_hw_params(this->hidden->pcm_handle, hwparams); + if (status < 0) { + return -1; + } + + this->spec.samples = persize; + + /* This is useful for debugging */ + if (SDL_getenv("SDL_AUDIO_ALSA_DEBUG")) { + snd_pcm_uframes_t bufsize; + + ALSA_snd_pcm_hw_params_get_buffer_size(hwparams, &bufsize); + + SDL_LogError(SDL_LOG_CATEGORY_AUDIO, + "ALSA: period size = %ld, periods = %u, buffer size = %lu\n", + persize, periods, bufsize); + } + + return 0; +} + +static int ALSA_OpenDevice(_THIS, const char *devname) +{ + int status = 0; + SDL_bool iscapture = this->iscapture; + snd_pcm_t *pcm_handle = NULL; + snd_pcm_hw_params_t *hwparams = NULL; + snd_pcm_sw_params_t *swparams = NULL; + snd_pcm_format_t format = 0; + SDL_AudioFormat test_format = 0; + unsigned int rate = 0; + unsigned int channels = 0; +#ifdef SND_CHMAP_API_VERSION + snd_pcm_chmap_t *chmap; + char chmap_str[64]; +#endif + + /* Initialize all variables that we clean on shutdown */ + this->hidden = (struct SDL_PrivateAudioData *)SDL_malloc(sizeof(*this->hidden)); + if (!this->hidden) { + return SDL_OutOfMemory(); + } + SDL_zerop(this->hidden); + + /* Open the audio device */ + /* Name of device should depend on # channels in spec */ + status = ALSA_snd_pcm_open(&pcm_handle, + get_audio_device(this->handle, this->spec.channels), + iscapture ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK, + SND_PCM_NONBLOCK); + + if (status < 0) { + return SDL_SetError("ALSA: Couldn't open audio device: %s", ALSA_snd_strerror(status)); + } + + this->hidden->pcm_handle = pcm_handle; + + /* Figure out what the hardware is capable of */ + snd_pcm_hw_params_alloca(&hwparams); + status = ALSA_snd_pcm_hw_params_any(pcm_handle, hwparams); + if (status < 0) { + return SDL_SetError("ALSA: Couldn't get hardware config: %s", ALSA_snd_strerror(status)); + } + + /* SDL only uses interleaved sample output */ + status = ALSA_snd_pcm_hw_params_set_access(pcm_handle, hwparams, + SND_PCM_ACCESS_RW_INTERLEAVED); + if (status < 0) { + return SDL_SetError("ALSA: Couldn't set interleaved access: %s", ALSA_snd_strerror(status)); + } + + /* Try for a closest match on audio format */ + for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) { + switch (test_format) { + case AUDIO_U8: + format = SND_PCM_FORMAT_U8; + break; + case AUDIO_S8: + format = SND_PCM_FORMAT_S8; + break; + case AUDIO_S16LSB: + format = SND_PCM_FORMAT_S16_LE; + break; + case AUDIO_S16MSB: + format = SND_PCM_FORMAT_S16_BE; + break; + case AUDIO_U16LSB: + format = SND_PCM_FORMAT_U16_LE; + break; + case AUDIO_U16MSB: + format = SND_PCM_FORMAT_U16_BE; + break; + case AUDIO_S32LSB: + format = SND_PCM_FORMAT_S32_LE; + break; + case AUDIO_S32MSB: + format = SND_PCM_FORMAT_S32_BE; + break; + case AUDIO_F32LSB: + format = SND_PCM_FORMAT_FLOAT_LE; + break; + case AUDIO_F32MSB: + format = SND_PCM_FORMAT_FLOAT_BE; + break; + default: + continue; + } + if (ALSA_snd_pcm_hw_params_set_format(pcm_handle, hwparams, format) >= 0) { + break; + } + } + if (!test_format) { + return SDL_SetError("%s: Unsupported audio format", "alsa"); + } + this->spec.format = test_format; + + /* Validate number of channels and determine if swizzling is necessary + * Assume original swizzling, until proven otherwise. + */ + this->hidden->swizzle_func = swizzle_alsa_channels; +#ifdef SND_CHMAP_API_VERSION + chmap = ALSA_snd_pcm_get_chmap(pcm_handle); + if (chmap) { + if (ALSA_snd_pcm_chmap_print(chmap, sizeof(chmap_str), chmap_str) > 0) { + if (SDL_strcmp("FL FR FC LFE RL RR", chmap_str) == 0 || + SDL_strcmp("FL FR FC LFE SL SR", chmap_str) == 0) { + this->hidden->swizzle_func = no_swizzle; + } + } + free(chmap); + } +#endif /* SND_CHMAP_API_VERSION */ + + /* Set the number of channels */ + status = ALSA_snd_pcm_hw_params_set_channels(pcm_handle, hwparams, + this->spec.channels); + channels = this->spec.channels; + if (status < 0) { + status = ALSA_snd_pcm_hw_params_get_channels(hwparams, &channels); + if (status < 0) { + return SDL_SetError("ALSA: Couldn't set audio channels"); + } + this->spec.channels = channels; + } + + /* Set the audio rate */ + rate = this->spec.freq; + status = ALSA_snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, + &rate, NULL); + if (status < 0) { + return SDL_SetError("ALSA: Couldn't set audio frequency: %s", ALSA_snd_strerror(status)); + } + this->spec.freq = rate; + + /* Set the buffer size, in samples */ + status = ALSA_set_buffer_size(this, hwparams); + if (status < 0) { + return SDL_SetError("Couldn't set hardware audio parameters: %s", ALSA_snd_strerror(status)); + } + + /* Set the software parameters */ + snd_pcm_sw_params_alloca(&swparams); + status = ALSA_snd_pcm_sw_params_current(pcm_handle, swparams); + if (status < 0) { + return SDL_SetError("ALSA: Couldn't get software config: %s", ALSA_snd_strerror(status)); + } + status = ALSA_snd_pcm_sw_params_set_avail_min(pcm_handle, swparams, this->spec.samples); + if (status < 0) { + return SDL_SetError("Couldn't set minimum available samples: %s", ALSA_snd_strerror(status)); + } + status = + ALSA_snd_pcm_sw_params_set_start_threshold(pcm_handle, swparams, 1); + if (status < 0) { + return SDL_SetError("ALSA: Couldn't set start threshold: %s", ALSA_snd_strerror(status)); + } + status = ALSA_snd_pcm_sw_params(pcm_handle, swparams); + if (status < 0) { + return SDL_SetError("Couldn't set software audio parameters: %s", ALSA_snd_strerror(status)); + } + + /* Calculate the final parameters for this audio specification */ + SDL_CalculateAudioSpec(&this->spec); + + /* Allocate mixing buffer */ + if (!iscapture) { + this->hidden->mixlen = this->spec.size; + this->hidden->mixbuf = (Uint8 *)SDL_malloc(this->hidden->mixlen); + if (!this->hidden->mixbuf) { + return SDL_OutOfMemory(); + } + SDL_memset(this->hidden->mixbuf, this->spec.silence, this->hidden->mixlen); + } + +#if !SDL_ALSA_NON_BLOCKING + if (!iscapture) { + ALSA_snd_pcm_nonblock(pcm_handle, 0); + } +#endif + + /* We're ready to rock and roll. :-) */ + return 0; +} + +typedef struct ALSA_Device +{ + char *name; + SDL_bool iscapture; + struct ALSA_Device *next; +} ALSA_Device; + +static void add_device(const int iscapture, const char *name, void *hint, ALSA_Device **pSeen) +{ + ALSA_Device *dev = SDL_malloc(sizeof(ALSA_Device)); + char *desc; + char *handle = NULL; + char *ptr; + + if (!dev) { + return; + } + + /* Not all alsa devices are enumerable via snd_device_name_get_hint + (i.e. bluetooth devices). Therefore if hint is passed in to this + function as NULL, assume name contains desc. + Make sure not to free the storage associated with desc in this case */ + if (hint) { + desc = ALSA_snd_device_name_get_hint(hint, "DESC"); + if (!desc) { + SDL_free(dev); + return; + } + } else { + desc = (char *)name; + } + + SDL_assert(name != NULL); + + /* some strings have newlines, like "HDA NVidia, HDMI 0\nHDMI Audio Output". + just chop the extra lines off, this seems to get a reasonable device + name without extra details. */ + ptr = SDL_strchr(desc, '\n'); + if (ptr) { + *ptr = '\0'; + } + + /*printf("ALSA: adding %s device '%s' (%s)\n", iscapture ? "capture" : "output", name, desc);*/ + + handle = SDL_strdup(name); + if (!handle) { + if (hint) { + free(desc); + } + SDL_free(dev); + return; + } + + /* Note that spec is NULL, because we are required to open the device before + * acquiring the mix format, making this information inaccessible at + * enumeration time + */ + SDL_AddAudioDevice(iscapture, desc, NULL, handle); + if (hint) { + free(desc); + } + dev->name = handle; + dev->iscapture = iscapture; + dev->next = *pSeen; + *pSeen = dev; +} + +static ALSA_Device *hotplug_devices = NULL; + +static void ALSA_HotplugIteration(void) +{ + void **hints = NULL; + ALSA_Device *dev; + ALSA_Device *unseen; + ALSA_Device *seen; + ALSA_Device *next; + ALSA_Device *prev; + + if (ALSA_snd_device_name_hint(-1, "pcm", &hints) == 0) { + int i, j; + const char *match = NULL; + int bestmatch = 0xFFFF; + size_t match_len = 0; + int defaultdev = -1; + static const char *const prefixes[] = { + "hw:", "sysdefault:", "default:", NULL + }; + + unseen = hotplug_devices; + seen = NULL; + + /* Apparently there are several different ways that ALSA lists + actual hardware. It could be prefixed with "hw:" or "default:" + or "sysdefault:" and maybe others. Go through the list and see + if we can find a preferred prefix for the system. */ + for (i = 0; hints[i]; i++) { + char *name = ALSA_snd_device_name_get_hint(hints[i], "NAME"); + if (!name) { + continue; + } + + /* full name, not a prefix */ + if ((defaultdev == -1) && (SDL_strcmp(name, "default") == 0)) { + defaultdev = i; + } + + for (j = 0; prefixes[j]; j++) { + const char *prefix = prefixes[j]; + const size_t prefixlen = SDL_strlen(prefix); + if (SDL_strncmp(name, prefix, prefixlen) == 0) { + if (j < bestmatch) { + bestmatch = j; + match = prefix; + match_len = prefixlen; + } + } + } + + free(name); + } + + /* look through the list of device names to find matches */ + for (i = 0; hints[i]; i++) { + char *name; + + /* if we didn't find a device name prefix we like at all... */ + if ((!match) && (defaultdev != i)) { + continue; /* ...skip anything that isn't the default device. */ + } + + name = ALSA_snd_device_name_get_hint(hints[i], "NAME"); + if (!name) { + continue; + } + + /* only want physical hardware interfaces */ + if (!match || (SDL_strncmp(name, match, match_len) == 0)) { + char *ioid = ALSA_snd_device_name_get_hint(hints[i], "IOID"); + const SDL_bool isoutput = (!ioid) || (SDL_strcmp(ioid, "Output") == 0); + const SDL_bool isinput = (!ioid) || (SDL_strcmp(ioid, "Input") == 0); + SDL_bool have_output = SDL_FALSE; + SDL_bool have_input = SDL_FALSE; + + free(ioid); + + if (!isoutput && !isinput) { + free(name); + continue; + } + + prev = NULL; + for (dev = unseen; dev; dev = next) { + next = dev->next; + if ((SDL_strcmp(dev->name, name) == 0) && (((isinput) && dev->iscapture) || ((isoutput) && !dev->iscapture))) { + if (prev) { + prev->next = next; + } else { + unseen = next; + } + dev->next = seen; + seen = dev; + if (isinput) { + have_input = SDL_TRUE; + } + if (isoutput) { + have_output = SDL_TRUE; + } + } else { + prev = dev; + } + } + + if (isinput && !have_input) { + add_device(SDL_TRUE, name, hints[i], &seen); + } + if (isoutput && !have_output) { + add_device(SDL_FALSE, name, hints[i], &seen); + } + } + + free(name); + } + + ALSA_snd_device_name_free_hint(hints); + + hotplug_devices = seen; /* now we have a known-good list of attached devices. */ + + /* report anything still in unseen as removed. */ + for (dev = unseen; dev; dev = next) { + /*printf("ALSA: removing usb %s device '%s'\n", dev->iscapture ? "capture" : "output", dev->name);*/ + next = dev->next; + SDL_RemoveAudioDevice(dev->iscapture, dev->name); + SDL_free(dev->name); + SDL_free(dev); + } + } +} + +#if SDL_ALSA_HOTPLUG_THREAD +static SDL_atomic_t ALSA_hotplug_shutdown; +static SDL_Thread *ALSA_hotplug_thread; + +static int SDLCALL ALSA_HotplugThread(void *arg) +{ + SDL_SetThreadPriority(SDL_THREAD_PRIORITY_LOW); + + while (!SDL_AtomicGet(&ALSA_hotplug_shutdown)) { + /* Block awhile before checking again, unless we're told to stop. */ + const Uint32 ticks = SDL_GetTicks() + 5000; + while (!SDL_AtomicGet(&ALSA_hotplug_shutdown) && !SDL_TICKS_PASSED(SDL_GetTicks(), ticks)) { + SDL_Delay(100); + } + + ALSA_HotplugIteration(); /* run the check. */ + } + + return 0; +} +#endif + +static void ALSA_DetectDevices(void) +{ + ALSA_HotplugIteration(); /* run once now before a thread continues to check. */ + +#if SDL_ALSA_HOTPLUG_THREAD + SDL_AtomicSet(&ALSA_hotplug_shutdown, 0); + ALSA_hotplug_thread = SDL_CreateThread(ALSA_HotplugThread, "SDLHotplugALSA", NULL); + /* if the thread doesn't spin, oh well, you just don't get further hotplug events. */ +#endif +} + +static void ALSA_Deinitialize(void) +{ + ALSA_Device *dev; + ALSA_Device *next; + +#if SDL_ALSA_HOTPLUG_THREAD + if (ALSA_hotplug_thread) { + SDL_AtomicSet(&ALSA_hotplug_shutdown, 1); + SDL_WaitThread(ALSA_hotplug_thread, NULL); + ALSA_hotplug_thread = NULL; + } +#endif + + /* Shutting down! Clean up any data we've gathered. */ + for (dev = hotplug_devices; dev; dev = next) { + /*printf("ALSA: at shutdown, removing %s device '%s'\n", dev->iscapture ? "capture" : "output", dev->name);*/ + next = dev->next; + SDL_free(dev->name); + SDL_free(dev); + } + hotplug_devices = NULL; + + UnloadALSALibrary(); +} + +static SDL_bool ALSA_Init(SDL_AudioDriverImpl *impl) +{ + if (LoadALSALibrary() < 0) { + return SDL_FALSE; + } + + /* Set the function pointers */ + impl->DetectDevices = ALSA_DetectDevices; + impl->OpenDevice = ALSA_OpenDevice; + impl->WaitDevice = ALSA_WaitDevice; + impl->GetDeviceBuf = ALSA_GetDeviceBuf; + impl->PlayDevice = ALSA_PlayDevice; + impl->CloseDevice = ALSA_CloseDevice; + impl->Deinitialize = ALSA_Deinitialize; + impl->CaptureFromDevice = ALSA_CaptureFromDevice; + impl->FlushCapture = ALSA_FlushCapture; + + impl->HasCaptureSupport = SDL_TRUE; + impl->SupportsNonPow2Samples = SDL_TRUE; + + return SDL_TRUE; /* this audio target is available. */ +} + +AudioBootStrap ALSA_bootstrap = { + "alsa", "ALSA PCM audio", ALSA_Init, SDL_FALSE +}; + +#endif /* SDL_AUDIO_DRIVER_ALSA */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/audio/alsa/SDL_alsa_audio.h b/SDL2-2.30.5/src/audio/alsa/SDL_alsa_audio.h similarity index 93% rename from SDL2-2.0.12/src/audio/alsa/SDL_alsa_audio.h rename to SDL2-2.30.5/src/audio/alsa/SDL_alsa_audio.h index d0e6d0b..fb3f154 100644 --- a/SDL2-2.0.12/src/audio/alsa/SDL_alsa_audio.h +++ b/SDL2-2.30.5/src/audio/alsa/SDL_alsa_audio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -28,7 +28,7 @@ #include "../SDL_sysaudio.h" /* Hidden "this" pointer for the audio functions */ -#define _THIS SDL_AudioDevice *this +#define _THIS SDL_AudioDevice *this struct SDL_PrivateAudioData { diff --git a/SDL2-2.0.12/src/audio/android/SDL_androidaudio.c b/SDL2-2.30.5/src/audio/android/SDL_androidaudio.c similarity index 52% rename from SDL2-2.0.12/src/audio/android/SDL_androidaudio.c rename to SDL2-2.30.5/src/audio/android/SDL_androidaudio.c index 9881a45..8173686 100644 --- a/SDL2-2.0.12/src/audio/android/SDL_androidaudio.c +++ b/SDL2-2.30.5/src/audio/android/SDL_androidaudio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,11 +20,10 @@ */ #include "../../SDL_internal.h" -#if SDL_AUDIO_DRIVER_ANDROID +#ifdef SDL_AUDIO_DRIVER_ANDROID /* Output audio to Android */ -#include "SDL_assert.h" #include "SDL_audio.h" #include "../SDL_audio_c.h" #include "SDL_androidaudio.h" @@ -33,13 +32,14 @@ #include -static SDL_AudioDevice* audioDevice = NULL; -static SDL_AudioDevice* captureDevice = NULL; +static SDL_AudioDevice *audioDevice = NULL; +static SDL_AudioDevice *captureDevice = NULL; -static int -ANDROIDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) + +static int ANDROIDAUDIO_OpenDevice(_THIS, const char *devname) { SDL_AudioFormat test_format; + SDL_bool iscapture = this->iscapture; SDL_assert((captureDevice == NULL) || !iscapture); SDL_assert((audioDevice == NULL) || iscapture); @@ -50,29 +50,33 @@ ANDROIDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) audioDevice = this; } - this->hidden = (struct SDL_PrivateAudioData *) SDL_calloc(1, (sizeof *this->hidden)); - if (this->hidden == NULL) { + this->hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, sizeof(*this->hidden)); + if (!this->hidden) { return SDL_OutOfMemory(); } - test_format = SDL_FirstAudioFormat(this->spec.format); - while (test_format != 0) { /* no "UNKNOWN" constant */ + for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) { if ((test_format == AUDIO_U8) || - (test_format == AUDIO_S16) || - (test_format == AUDIO_F32)) { + (test_format == AUDIO_S16) || + (test_format == AUDIO_F32)) { this->spec.format = test_format; break; } - test_format = SDL_NextAudioFormat(); } - if (test_format == 0) { + if (!test_format) { /* Didn't find a compatible format :( */ - return SDL_SetError("No compatible audio format!"); + return SDL_SetError("%s: Unsupported audio format", "android"); } - if (Android_JNI_OpenAudioDevice(iscapture, &this->spec) < 0) { - return -1; + { + int audio_device_id = 0; + if (devname) { + audio_device_id = SDL_atoi(devname); + } + if (Android_JNI_OpenAudioDevice(iscapture, audio_device_id, &this->spec) < 0) { + return -1; + } } SDL_CalculateAudioSpec(&this->spec); @@ -80,32 +84,27 @@ ANDROIDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) return 0; } -static void -ANDROIDAUDIO_PlayDevice(_THIS) +static void ANDROIDAUDIO_PlayDevice(_THIS) { Android_JNI_WriteAudioBuffer(); } -static Uint8 * -ANDROIDAUDIO_GetDeviceBuf(_THIS) +static Uint8 *ANDROIDAUDIO_GetDeviceBuf(_THIS) { return Android_JNI_GetAudioBuffer(); } -static int -ANDROIDAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen) +static int ANDROIDAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen) { return Android_JNI_CaptureAudioBuffer(buffer, buflen); } -static void -ANDROIDAUDIO_FlushCapture(_THIS) +static void ANDROIDAUDIO_FlushCapture(_THIS) { Android_JNI_FlushCapturedAudio(); } -static void -ANDROIDAUDIO_CloseDevice(_THIS) +static void ANDROIDAUDIO_CloseDevice(_THIS) { /* At this point SDL_CloseAudioDevice via close_audio_device took care of terminating the audio thread so it's safe to terminate the Java side buffer and AudioTrack @@ -121,58 +120,40 @@ ANDROIDAUDIO_CloseDevice(_THIS) SDL_free(this->hidden); } -static int -ANDROIDAUDIO_Init(SDL_AudioDriverImpl * impl) +static SDL_bool ANDROIDAUDIO_Init(SDL_AudioDriverImpl *impl) { /* Set the function pointers */ + impl->DetectDevices = Android_DetectDevices; impl->OpenDevice = ANDROIDAUDIO_OpenDevice; impl->PlayDevice = ANDROIDAUDIO_PlayDevice; impl->GetDeviceBuf = ANDROIDAUDIO_GetDeviceBuf; impl->CloseDevice = ANDROIDAUDIO_CloseDevice; impl->CaptureFromDevice = ANDROIDAUDIO_CaptureFromDevice; impl->FlushCapture = ANDROIDAUDIO_FlushCapture; + impl->AllowsArbitraryDeviceNames = SDL_TRUE; /* and the capabilities */ impl->HasCaptureSupport = SDL_TRUE; - impl->OnlyHasDefaultOutputDevice = 1; - impl->OnlyHasDefaultCaptureDevice = 1; + impl->OnlyHasDefaultOutputDevice = SDL_FALSE; + impl->OnlyHasDefaultCaptureDevice = SDL_FALSE; - return 1; /* this audio target is available. */ + return SDL_TRUE; /* this audio target is available. */ } AudioBootStrap ANDROIDAUDIO_bootstrap = { - "android", "SDL Android audio driver", ANDROIDAUDIO_Init, 0 + "android", "SDL Android audio driver", ANDROIDAUDIO_Init, SDL_FALSE }; /* Pause (block) all non already paused audio devices by taking their mixer lock */ void ANDROIDAUDIO_PauseDevices(void) { /* TODO: Handle multiple devices? */ - struct SDL_PrivateAudioData *private; - if(audioDevice != NULL && audioDevice->hidden != NULL) { - private = (struct SDL_PrivateAudioData *) audioDevice->hidden; - if (SDL_AtomicGet(&audioDevice->paused)) { - /* The device is already paused, leave it alone */ - private->resume = SDL_FALSE; - } - else { - SDL_LockMutex(audioDevice->mixer_lock); - SDL_AtomicSet(&audioDevice->paused, 1); - private->resume = SDL_TRUE; - } + if (audioDevice && audioDevice->hidden) { + SDL_LockMutex(audioDevice->mixer_lock); } - if(captureDevice != NULL && captureDevice->hidden != NULL) { - private = (struct SDL_PrivateAudioData *) captureDevice->hidden; - if (SDL_AtomicGet(&captureDevice->paused)) { - /* The device is already paused, leave it alone */ - private->resume = SDL_FALSE; - } - else { - SDL_LockMutex(captureDevice->mixer_lock); - SDL_AtomicSet(&captureDevice->paused, 1); - private->resume = SDL_TRUE; - } + if (captureDevice && captureDevice->hidden) { + SDL_LockMutex(captureDevice->mixer_lock); } } @@ -180,27 +161,16 @@ void ANDROIDAUDIO_PauseDevices(void) void ANDROIDAUDIO_ResumeDevices(void) { /* TODO: Handle multiple devices? */ - struct SDL_PrivateAudioData *private; - if(audioDevice != NULL && audioDevice->hidden != NULL) { - private = (struct SDL_PrivateAudioData *) audioDevice->hidden; - if (private->resume) { - SDL_AtomicSet(&audioDevice->paused, 0); - private->resume = SDL_FALSE; - SDL_UnlockMutex(audioDevice->mixer_lock); - } + if (audioDevice && audioDevice->hidden) { + SDL_UnlockMutex(audioDevice->mixer_lock); } - if(captureDevice != NULL && captureDevice->hidden != NULL) { - private = (struct SDL_PrivateAudioData *) captureDevice->hidden; - if (private->resume) { - SDL_AtomicSet(&captureDevice->paused, 0); - private->resume = SDL_FALSE; - SDL_UnlockMutex(captureDevice->mixer_lock); - } + if (captureDevice && captureDevice->hidden) { + SDL_UnlockMutex(captureDevice->mixer_lock); } } -#else +#else void ANDROIDAUDIO_ResumeDevices(void) {} void ANDROIDAUDIO_PauseDevices(void) {} @@ -208,4 +178,3 @@ void ANDROIDAUDIO_PauseDevices(void) {} #endif /* SDL_AUDIO_DRIVER_ANDROID */ /* vi: set ts=4 sw=4 expandtab: */ - diff --git a/SDL2-2.0.12/src/audio/android/SDL_androidaudio.h b/SDL2-2.30.5/src/audio/android/SDL_androidaudio.h similarity index 87% rename from SDL2-2.0.12/src/audio/android/SDL_androidaudio.h rename to SDL2-2.30.5/src/audio/android/SDL_androidaudio.h index 6773eca..4e9df10 100644 --- a/SDL2-2.0.12/src/audio/android/SDL_androidaudio.h +++ b/SDL2-2.30.5/src/audio/android/SDL_androidaudio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,12 +26,11 @@ #include "../SDL_sysaudio.h" /* Hidden "this" pointer for the audio functions */ -#define _THIS SDL_AudioDevice *this +#define _THIS SDL_AudioDevice *this struct SDL_PrivateAudioData { - /* Resume device if it was paused automatically */ - int resume; + int unused; }; void ANDROIDAUDIO_ResumeDevices(void); diff --git a/SDL2-2.0.12/src/audio/arts/SDL_artsaudio.c b/SDL2-2.30.5/src/audio/arts/SDL_artsaudio.c similarity index 85% rename from SDL2-2.0.12/src/audio/arts/SDL_artsaudio.c rename to SDL2-2.30.5/src/audio/arts/SDL_artsaudio.c index 4f1a703..da91997 100644 --- a/SDL2-2.0.12/src/audio/arts/SDL_artsaudio.c +++ b/SDL2-2.30.5/src/audio/arts/SDL_artsaudio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_AUDIO_DRIVER_ARTS +#ifdef SDL_AUDIO_DRIVER_ARTS /* Allow access to a raw mixing buffer */ @@ -86,23 +86,21 @@ static struct #undef SDL_ARTS_SYM -static void -UnloadARTSLibrary() +static void UnloadARTSLibrary() { - if (arts_handle != NULL) { + if (arts_handle) { SDL_UnloadObject(arts_handle); arts_handle = NULL; } } -static int -LoadARTSLibrary(void) +static int LoadARTSLibrary(void) { int i, retval = -1; - if (arts_handle == NULL) { + if (!arts_handle) { arts_handle = SDL_LoadObject(arts_library); - if (arts_handle != NULL) { + if (arts_handle) { retval = 0; for (i = 0; i < SDL_arraysize(arts_functions); ++i) { *arts_functions[i].func = @@ -121,14 +119,12 @@ LoadARTSLibrary(void) #else -static void -UnloadARTSLibrary() +static void UnloadARTSLibrary() { return; } -static int -LoadARTSLibrary(void) +static int LoadARTSLibrary(void) { return 0; } @@ -136,8 +132,7 @@ LoadARTSLibrary(void) #endif /* SDL_AUDIO_DRIVER_ARTS_DYNAMIC */ /* This function waits until it is possible to write a full sound buffer */ -static void -ARTS_WaitDevice(_THIS) +static void ARTS_WaitDevice(_THIS) { Sint32 ticks; @@ -163,8 +158,7 @@ ARTS_WaitDevice(_THIS) } } -static void -ARTS_PlayDevice(_THIS) +static void ARTS_PlayDevice(_THIS) { /* Write the audio data */ int written = SDL_NAME(arts_write) (this->hidden->stream, @@ -185,15 +179,13 @@ ARTS_PlayDevice(_THIS) #endif } -static Uint8 * -ARTS_GetDeviceBuf(_THIS) +static Uint8 *ARTS_GetDeviceBuf(_THIS) { return (this->hidden->mixbuf); } -static void -ARTS_CloseDevice(_THIS) +static void ARTS_CloseDevice(_THIS) { if (this->hidden->stream) { SDL_NAME(arts_close_stream) (this->hidden->stream); @@ -203,8 +195,7 @@ ARTS_CloseDevice(_THIS) SDL_free(this->hidden); } -static int -ARTS_Suspend(void) +static int ARTS_Suspend(void) { const Uint32 abortms = SDL_GetTicks() + 3000; /* give up after 3 secs */ while ( (!SDL_NAME(arts_suspended)()) && !SDL_TICKS_PASSED(SDL_GetTicks(), abortms) ) { @@ -215,48 +206,38 @@ ARTS_Suspend(void) return SDL_NAME(arts_suspended)(); } -static int -ARTS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) +static int ARTS_OpenDevice(_THIS, const char *devname) { int rc = 0; - int bits = 0, frag_spec = 0; - SDL_AudioFormat test_format = 0, format = 0; + int bits, frag_spec = 0; + SDL_AudioFormat test_format = 0; /* Initialize all variables that we clean on shutdown */ - this->hidden = (struct SDL_PrivateAudioData *) - SDL_malloc((sizeof *this->hidden)); - if (this->hidden == NULL) { + this->hidden = (struct SDL_PrivateAudioData *)SDL_malloc(sizeof(*this->hidden)); + if (!this->hidden) { return SDL_OutOfMemory(); } SDL_zerop(this->hidden); /* Try for a closest match on audio format */ - for (test_format = SDL_FirstAudioFormat(this->spec.format); - !format && test_format;) { + for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) { #ifdef DEBUG_AUDIO fprintf(stderr, "Trying format 0x%4.4x\n", test_format); #endif switch (test_format) { case AUDIO_U8: - bits = 8; - format = 1; - break; case AUDIO_S16LSB: - bits = 16; - format = 1; break; default: - format = 0; - break; - } - if (!format) { - test_format = SDL_NextAudioFormat(); + continue; } + break; } - if (format == 0) { - return SDL_SetError("Couldn't find any hardware audio formats"); + if (!test_format) { + return SDL_SetError("%s: Unsupported audio format", "arts"); } this->spec.format = test_format; + bits = SDL_AUDIO_BITSIZE(test_format); if ((rc = SDL_NAME(arts_init) ()) != 0) { return SDL_SetError("Unable to initialize ARTS: %s", @@ -300,7 +281,7 @@ ARTS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) /* Allocate mixing buffer */ this->hidden->mixlen = this->spec.size; this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen); - if (this->hidden->mixbuf == NULL) { + if (!this->hidden->mixbuf) { return SDL_OutOfMemory(); } SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size); @@ -313,23 +294,21 @@ ARTS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) } -static void -ARTS_Deinitialize(void) +static void ARTS_Deinitialize(void) { UnloadARTSLibrary(); } -static int -ARTS_Init(SDL_AudioDriverImpl * impl) +static SDL_bool ARTS_Init(SDL_AudioDriverImpl *impl) { if (LoadARTSLibrary() < 0) { - return 0; + return SDL_FALSE; } else { if (SDL_NAME(arts_init) () != 0) { UnloadARTSLibrary(); SDL_SetError("ARTS: arts_init failed (no audio server?)"); - return 0; + return SDL_FALSE; } /* Play a stream so aRts doesn't crash */ @@ -350,14 +329,14 @@ ARTS_Init(SDL_AudioDriverImpl * impl) impl->GetDeviceBuf = ARTS_GetDeviceBuf; impl->CloseDevice = ARTS_CloseDevice; impl->Deinitialize = ARTS_Deinitialize; - impl->OnlyHasDefaultOutputDevice = 1; + impl->OnlyHasDefaultOutputDevice = SDL_TRUE; - return 1; /* this audio target is available. */ + return SDL_TRUE; /* this audio target is available. */ } AudioBootStrap ARTS_bootstrap = { - "arts", "Analog RealTime Synthesizer", ARTS_Init, 0 + "arts", "Analog RealTime Synthesizer", ARTS_Init, SDL_FALSE }; #endif /* SDL_AUDIO_DRIVER_ARTS */ diff --git a/SDL2-2.0.12/src/audio/arts/SDL_artsaudio.h b/SDL2-2.30.5/src/audio/arts/SDL_artsaudio.h similarity index 96% rename from SDL2-2.0.12/src/audio/arts/SDL_artsaudio.h rename to SDL2-2.30.5/src/audio/arts/SDL_artsaudio.h index 67676d9..fe55bcd 100644 --- a/SDL2-2.0.12/src/audio/arts/SDL_artsaudio.h +++ b/SDL2-2.30.5/src/audio/arts/SDL_artsaudio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/audio/coreaudio/SDL_coreaudio.h b/SDL2-2.30.5/src/audio/coreaudio/SDL_coreaudio.h similarity index 78% rename from SDL2-2.0.12/src/audio/coreaudio/SDL_coreaudio.h rename to SDL2-2.30.5/src/audio/coreaudio/SDL_coreaudio.h index f882007..d5d11ca 100644 --- a/SDL2-2.0.12/src/audio/coreaudio/SDL_coreaudio.h +++ b/SDL2-2.30.5/src/audio/coreaudio/SDL_coreaudio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,12 +26,11 @@ #include "../SDL_sysaudio.h" #if !defined(__IPHONEOS__) -#define MACOSX_COREAUDIO 1 +#define MACOSX_COREAUDIO #endif -#if MACOSX_COREAUDIO +#ifdef MACOSX_COREAUDIO #include -#include #else #import #import @@ -40,13 +39,22 @@ #include #include +/* Things named "Master" were renamed to "Main" in macOS 12.0's SDK. */ +#ifdef MACOSX_COREAUDIO +#include +#ifndef MAC_OS_VERSION_12_0 +#define kAudioObjectPropertyElementMain kAudioObjectPropertyElementMaster +#endif +#endif + /* Hidden "this" pointer for the audio functions */ -#define _THIS SDL_AudioDevice *this +#define _THIS SDL_AudioDevice *this struct SDL_PrivateAudioData { SDL_Thread *thread; AudioQueueRef audioQueue; + int numAudioBuffers; AudioQueueBufferRef *audioBuffer; void *buffer; UInt32 bufferOffset; @@ -54,9 +62,9 @@ struct SDL_PrivateAudioData AudioStreamBasicDescription strdesc; SDL_sem *ready_semaphore; char *thread_error; - SDL_atomic_t shutdown; -#if MACOSX_COREAUDIO +#ifdef MACOSX_COREAUDIO AudioDeviceID deviceID; + SDL_atomic_t device_change_flag; #else SDL_bool interrupted; CFTypeRef interruption_listener; diff --git a/SDL2-2.30.5/src/audio/coreaudio/SDL_coreaudio.m b/SDL2-2.30.5/src/audio/coreaudio/SDL_coreaudio.m new file mode 100644 index 0000000..26da64d --- /dev/null +++ b/SDL2-2.30.5/src/audio/coreaudio/SDL_coreaudio.m @@ -0,0 +1,1314 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_AUDIO_DRIVER_COREAUDIO + +/* !!! FIXME: clean out some of the macro salsa in here. */ + +#include "SDL_audio.h" +#include "SDL_hints.h" +#include "../SDL_audio_c.h" +#include "../SDL_sysaudio.h" +#include "SDL_coreaudio.h" +#include "../../thread/SDL_systhread.h" + +#define DEBUG_COREAUDIO 0 + +#if DEBUG_COREAUDIO +#define CHECK_RESULT(msg) \ + if (result != noErr) { \ + printf("COREAUDIO: Got error %d from '%s'!\n", (int)result, msg); \ + SDL_SetError("CoreAudio error (%s): %d", msg, (int)result); \ + return 0; \ + } +#else +#define CHECK_RESULT(msg) \ + if (result != noErr) { \ + SDL_SetError("CoreAudio error (%s): %d", msg, (int)result); \ + return 0; \ + } +#endif + +#ifdef MACOSX_COREAUDIO +static const AudioObjectPropertyAddress devlist_address = { + kAudioHardwarePropertyDevices, + kAudioObjectPropertyScopeGlobal, + kAudioObjectPropertyElementMain +}; + +typedef void (*addDevFn)(const char *name, SDL_AudioSpec *spec, const int iscapture, AudioDeviceID devId, void *data); + +typedef struct AudioDeviceList +{ + AudioDeviceID devid; + SDL_bool alive; + struct AudioDeviceList *next; +} AudioDeviceList; + +static AudioDeviceList *output_devs = NULL; +static AudioDeviceList *capture_devs = NULL; + +static SDL_bool add_to_internal_dev_list(const int iscapture, AudioDeviceID devId) +{ + AudioDeviceList *item = (AudioDeviceList *)SDL_malloc(sizeof(AudioDeviceList)); + if (item == NULL) { + return SDL_FALSE; + } + item->devid = devId; + item->alive = SDL_TRUE; + item->next = iscapture ? capture_devs : output_devs; + if (iscapture) { + capture_devs = item; + } else { + output_devs = item; + } + + return SDL_TRUE; +} + +static void addToDevList(const char *name, SDL_AudioSpec *spec, const int iscapture, AudioDeviceID devId, void *data) +{ + if (add_to_internal_dev_list(iscapture, devId)) { + SDL_AddAudioDevice(iscapture, name, spec, (void *)((size_t)devId)); + } +} + +static void build_device_list(int iscapture, addDevFn addfn, void *addfndata) +{ + OSStatus result = noErr; + UInt32 size = 0; + AudioDeviceID *devs = NULL; + UInt32 i = 0; + UInt32 max = 0; + + result = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, + &devlist_address, 0, NULL, &size); + if (result != kAudioHardwareNoError) { + return; + } + + devs = (AudioDeviceID *)alloca(size); + if (devs == NULL) { + return; + } + + result = AudioObjectGetPropertyData(kAudioObjectSystemObject, + &devlist_address, 0, NULL, &size, devs); + if (result != kAudioHardwareNoError) { + return; + } + + max = size / sizeof(AudioDeviceID); + for (i = 0; i < max; i++) { + CFStringRef cfstr = NULL; + char *ptr = NULL; + AudioDeviceID dev = devs[i]; + AudioBufferList *buflist = NULL; + int usable = 0; + CFIndex len = 0; + double sampleRate = 0; + SDL_AudioSpec spec; + const AudioObjectPropertyAddress addr = { + kAudioDevicePropertyStreamConfiguration, + iscapture ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput, + kAudioObjectPropertyElementMain + }; + const AudioObjectPropertyAddress nameaddr = { + kAudioObjectPropertyName, + iscapture ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput, + kAudioObjectPropertyElementMain + }; + const AudioObjectPropertyAddress freqaddr = { + kAudioDevicePropertyNominalSampleRate, + iscapture ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput, + kAudioObjectPropertyElementMain + }; + + result = AudioObjectGetPropertyDataSize(dev, &addr, 0, NULL, &size); + if (result != noErr) { + continue; + } + + buflist = (AudioBufferList *)SDL_malloc(size); + if (buflist == NULL) { + continue; + } + + result = AudioObjectGetPropertyData(dev, &addr, 0, NULL, + &size, buflist); + + SDL_zero(spec); + if (result == noErr) { + UInt32 j; + for (j = 0; j < buflist->mNumberBuffers; j++) { + spec.channels += buflist->mBuffers[j].mNumberChannels; + } + } + + SDL_free(buflist); + + if (spec.channels == 0) { + continue; + } + + size = sizeof(sampleRate); + result = AudioObjectGetPropertyData(dev, &freqaddr, 0, NULL, &size, &sampleRate); + if (result == noErr) { + spec.freq = (int)sampleRate; + } + + size = sizeof(CFStringRef); + result = AudioObjectGetPropertyData(dev, &nameaddr, 0, NULL, &size, &cfstr); + if (result != kAudioHardwareNoError) { + continue; + } + + len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(cfstr), + kCFStringEncodingUTF8); + + ptr = (char *)SDL_malloc(len + 1); + usable = ((ptr != NULL) && + (CFStringGetCString(cfstr, ptr, len + 1, kCFStringEncodingUTF8))); + + CFRelease(cfstr); + + if (usable) { + len = strlen(ptr); + /* Some devices have whitespace at the end...trim it. */ + while ((len > 0) && (ptr[len - 1] == ' ')) { + len--; + } + usable = (len > 0); + } + + if (usable) { + ptr[len] = '\0'; + +#if DEBUG_COREAUDIO + printf("COREAUDIO: Found %s device #%d: '%s' (devid %d)\n", + ((iscapture) ? "capture" : "output"), + (int)i, ptr, (int)dev); +#endif + addfn(ptr, &spec, iscapture, dev, addfndata); + } + SDL_free(ptr); /* addfn() would have copied the string. */ + } +} + +static void free_audio_device_list(AudioDeviceList **list) +{ + AudioDeviceList *item = *list; + while (item) { + AudioDeviceList *next = item->next; + SDL_free(item); + item = next; + } + *list = NULL; +} + +static void COREAUDIO_DetectDevices(void) +{ + build_device_list(SDL_TRUE, addToDevList, NULL); + build_device_list(SDL_FALSE, addToDevList, NULL); +} + +static void build_device_change_list(const char *name, SDL_AudioSpec *spec, const int iscapture, AudioDeviceID devId, void *data) +{ + AudioDeviceList **list = (AudioDeviceList **)data; + AudioDeviceList *item; + for (item = *list; item != NULL; item = item->next) { + if (item->devid == devId) { + item->alive = SDL_TRUE; + return; + } + } + + add_to_internal_dev_list(iscapture, devId); /* new device, add it. */ + SDL_AddAudioDevice(iscapture, name, spec, (void *)((size_t)devId)); +} + +static void reprocess_device_list(const int iscapture, AudioDeviceList **list) +{ + AudioDeviceList *item; + AudioDeviceList *prev = NULL; + for (item = *list; item != NULL; item = item->next) { + item->alive = SDL_FALSE; + } + + build_device_list(iscapture, build_device_change_list, list); + + /* free items in the list that aren't still alive. */ + item = *list; + while (item != NULL) { + AudioDeviceList *next = item->next; + if (item->alive) { + prev = item; + } else { + SDL_RemoveAudioDevice(iscapture, (void *)((size_t)item->devid)); + if (prev) { + prev->next = item->next; + } else { + *list = item->next; + } + SDL_free(item); + } + item = next; + } +} + +/* this is called when the system's list of available audio devices changes. */ +static OSStatus device_list_changed(AudioObjectID systemObj, UInt32 num_addr, const AudioObjectPropertyAddress *addrs, void *data) +{ + reprocess_device_list(SDL_TRUE, &capture_devs); + reprocess_device_list(SDL_FALSE, &output_devs); + return 0; +} +#endif + +static int open_playback_devices; +static int open_capture_devices; +static int num_open_devices; +static SDL_AudioDevice **open_devices; + +#ifndef MACOSX_COREAUDIO + +static BOOL session_active = NO; + +static void pause_audio_devices(void) +{ + int i; + + if (!open_devices) { + return; + } + + for (i = 0; i < num_open_devices; ++i) { + SDL_AudioDevice *device = open_devices[i]; + if (device->hidden->audioQueue && !device->hidden->interrupted) { + AudioQueuePause(device->hidden->audioQueue); + } + } +} + +static void resume_audio_devices(void) +{ + int i; + + if (!open_devices) { + return; + } + + for (i = 0; i < num_open_devices; ++i) { + SDL_AudioDevice *device = open_devices[i]; + if (device->hidden->audioQueue && !device->hidden->interrupted) { + AudioQueueStart(device->hidden->audioQueue, NULL); + } + } +} + +static void interruption_begin(_THIS) +{ + if (this != NULL && this->hidden->audioQueue != NULL) { + this->hidden->interrupted = SDL_TRUE; + AudioQueuePause(this->hidden->audioQueue); + } +} + +static void interruption_end(_THIS) +{ + if (this != NULL && this->hidden != NULL && this->hidden->audioQueue != NULL && this->hidden->interrupted && AudioQueueStart(this->hidden->audioQueue, NULL) == AVAudioSessionErrorCodeNone) { + this->hidden->interrupted = SDL_FALSE; + } +} + +@interface SDLInterruptionListener : NSObject + +@property(nonatomic, assign) SDL_AudioDevice *device; + +@end + +@implementation SDLInterruptionListener + +- (void)audioSessionInterruption:(NSNotification *)note +{ + @synchronized(self) { + NSNumber *type = note.userInfo[AVAudioSessionInterruptionTypeKey]; + if (type.unsignedIntegerValue == AVAudioSessionInterruptionTypeBegan) { + interruption_begin(self.device); + } else { + interruption_end(self.device); + } + } +} + +- (void)applicationBecameActive:(NSNotification *)note +{ + @synchronized(self) { + interruption_end(self.device); + } +} + +@end + +static BOOL update_audio_session(_THIS, SDL_bool open, SDL_bool allow_playandrecord) +{ + @autoreleasepool { + AVAudioSession *session = [AVAudioSession sharedInstance]; + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + + NSString *category = AVAudioSessionCategoryPlayback; + NSString *mode = AVAudioSessionModeDefault; + NSUInteger options = AVAudioSessionCategoryOptionMixWithOthers; + NSError *err = nil; + const char *hint; + + hint = SDL_GetHint(SDL_HINT_AUDIO_CATEGORY); + if (hint) { + if (SDL_strcasecmp(hint, "AVAudioSessionCategoryAmbient") == 0) { + category = AVAudioSessionCategoryAmbient; + } else if (SDL_strcasecmp(hint, "AVAudioSessionCategorySoloAmbient") == 0) { + category = AVAudioSessionCategorySoloAmbient; + options &= ~AVAudioSessionCategoryOptionMixWithOthers; + } else if (SDL_strcasecmp(hint, "AVAudioSessionCategoryPlayback") == 0 || + SDL_strcasecmp(hint, "playback") == 0) { + category = AVAudioSessionCategoryPlayback; + options &= ~AVAudioSessionCategoryOptionMixWithOthers; + } else if (SDL_strcasecmp(hint, "AVAudioSessionCategoryPlayAndRecord") == 0 || + SDL_strcasecmp(hint, "playandrecord") == 0) { + if (allow_playandrecord) { + category = AVAudioSessionCategoryPlayAndRecord; + } + } + } else if (open_playback_devices && open_capture_devices) { + category = AVAudioSessionCategoryPlayAndRecord; + } else if (open_capture_devices) { + category = AVAudioSessionCategoryRecord; + } + +#if !TARGET_OS_TV + if (category == AVAudioSessionCategoryPlayAndRecord) { + options |= AVAudioSessionCategoryOptionDefaultToSpeaker; + } +#endif + if (category == AVAudioSessionCategoryRecord || + category == AVAudioSessionCategoryPlayAndRecord) { + /* AVAudioSessionCategoryOptionAllowBluetooth isn't available in the SDK for + Apple TV but is still needed in order to output to Bluetooth devices. + */ + options |= 0x4; /* AVAudioSessionCategoryOptionAllowBluetooth; */ + } + if (category == AVAudioSessionCategoryPlayAndRecord) { + options |= AVAudioSessionCategoryOptionAllowBluetoothA2DP | + AVAudioSessionCategoryOptionAllowAirPlay; + } + if (category == AVAudioSessionCategoryPlayback || + category == AVAudioSessionCategoryPlayAndRecord) { + options |= AVAudioSessionCategoryOptionDuckOthers; + } + + if ([session respondsToSelector:@selector(setCategory:mode:options:error:)]) { + if (![session.category isEqualToString:category] || session.categoryOptions != options) { + /* Stop the current session so we don't interrupt other application audio */ + pause_audio_devices(); + [session setActive:NO error:nil]; + session_active = NO; + + if (![session setCategory:category mode:mode options:options error:&err]) { + NSString *desc = err.description; + SDL_SetError("Could not set Audio Session category: %s", desc.UTF8String); + return NO; + } + } + } else { + if (![session.category isEqualToString:category]) { + /* Stop the current session so we don't interrupt other application audio */ + pause_audio_devices(); + [session setActive:NO error:nil]; + session_active = NO; + + if (![session setCategory:category error:&err]) { + NSString *desc = err.description; + SDL_SetError("Could not set Audio Session category: %s", desc.UTF8String); + return NO; + } + } + } + + if ((open_playback_devices || open_capture_devices) && !session_active) { + if (![session setActive:YES error:&err]) { + if ([err code] == AVAudioSessionErrorCodeResourceNotAvailable && + category == AVAudioSessionCategoryPlayAndRecord) { + return update_audio_session(this, open, SDL_FALSE); + } + + NSString *desc = err.description; + SDL_SetError("Could not activate Audio Session: %s", desc.UTF8String); + return NO; + } + session_active = YES; + resume_audio_devices(); + } else if (!open_playback_devices && !open_capture_devices && session_active) { + pause_audio_devices(); + [session setActive:NO error:nil]; + session_active = NO; + } + + if (open) { + SDLInterruptionListener *listener = [SDLInterruptionListener new]; + listener.device = this; + + [center addObserver:listener + selector:@selector(audioSessionInterruption:) + name:AVAudioSessionInterruptionNotification + object:session]; + + /* An interruption end notification is not guaranteed to be sent if + we were previously interrupted... resuming if needed when the app + becomes active seems to be the way to go. */ + // Note: object: below needs to be nil, as otherwise it filters by the object, and session doesn't send foreground / active notifications. johna + [center addObserver:listener + selector:@selector(applicationBecameActive:) + name:UIApplicationDidBecomeActiveNotification + object:nil]; + + [center addObserver:listener + selector:@selector(applicationBecameActive:) + name:UIApplicationWillEnterForegroundNotification + object:nil]; + + this->hidden->interruption_listener = CFBridgingRetain(listener); + } else { + SDLInterruptionListener *listener = nil; + listener = (SDLInterruptionListener *)CFBridgingRelease(this->hidden->interruption_listener); + [center removeObserver:listener]; + @synchronized(listener) { + listener.device = NULL; + } + } + } + + return YES; +} +#endif + +/* The AudioQueue callback */ +static void outputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer) +{ + SDL_AudioDevice *this = (SDL_AudioDevice *)inUserData; + + /* This flag is set before this->mixer_lock is destroyed during + shutdown, so check it before grabbing the mutex, and then check it + again _after_ in case we blocked waiting on the lock. */ + if (SDL_AtomicGet(&this->shutdown)) { + return; /* don't do anything, since we don't even want to enqueue this buffer again. */ + } + + SDL_LockMutex(this->mixer_lock); + + if (SDL_AtomicGet(&this->shutdown)) { + SDL_UnlockMutex(this->mixer_lock); + return; /* don't do anything, since we don't even want to enqueue this buffer again. */ + } + + if (!SDL_AtomicGet(&this->enabled) || SDL_AtomicGet(&this->paused)) { + /* Supply silence if audio is not enabled or paused */ + SDL_memset(inBuffer->mAudioData, this->spec.silence, inBuffer->mAudioDataBytesCapacity); + if (this->stream) { + SDL_AudioStreamClear(this->stream); + } + } else if (this->stream) { + UInt32 remaining = inBuffer->mAudioDataBytesCapacity; + Uint8 *ptr = (Uint8 *)inBuffer->mAudioData; + + while (remaining > 0) { + if (SDL_AudioStreamAvailable(this->stream) == 0) { + /* Generate the data */ + (*this->callbackspec.callback)(this->callbackspec.userdata, + this->hidden->buffer, this->hidden->bufferSize); + this->hidden->bufferOffset = 0; + SDL_AudioStreamPut(this->stream, this->hidden->buffer, this->hidden->bufferSize); + } + if (SDL_AudioStreamAvailable(this->stream) > 0) { + int got; + UInt32 len = SDL_AudioStreamAvailable(this->stream); + if (len > remaining) { + len = remaining; + } + got = SDL_AudioStreamGet(this->stream, ptr, len); + SDL_assert((got < 0) || (got == len)); + if (got != len) { + SDL_memset(ptr, this->spec.silence, len); + } + ptr = ptr + len; + remaining -= len; + } + } + } else { + UInt32 remaining = inBuffer->mAudioDataBytesCapacity; + Uint8 *ptr = (Uint8 *)inBuffer->mAudioData; + + while (remaining > 0) { + UInt32 len; + if (this->hidden->bufferOffset >= this->hidden->bufferSize) { + /* Generate the data */ + (*this->callbackspec.callback)(this->callbackspec.userdata, + this->hidden->buffer, this->hidden->bufferSize); + this->hidden->bufferOffset = 0; + } + + len = this->hidden->bufferSize - this->hidden->bufferOffset; + if (len > remaining) { + len = remaining; + } + SDL_memcpy(ptr, (char *)this->hidden->buffer + this->hidden->bufferOffset, len); + ptr = ptr + len; + remaining -= len; + this->hidden->bufferOffset += len; + } + } + + AudioQueueEnqueueBuffer(this->hidden->audioQueue, inBuffer, 0, NULL); + + inBuffer->mAudioDataByteSize = inBuffer->mAudioDataBytesCapacity; + + SDL_UnlockMutex(this->mixer_lock); +} + +static void inputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer, + const AudioTimeStamp *inStartTime, UInt32 inNumberPacketDescriptions, + const AudioStreamPacketDescription *inPacketDescs) +{ + SDL_AudioDevice *this = (SDL_AudioDevice *)inUserData; + + if (SDL_AtomicGet(&this->shutdown)) { + return; /* don't do anything. */ + } + + /* ignore unless we're active. */ + if (!SDL_AtomicGet(&this->paused) && SDL_AtomicGet(&this->enabled)) { + const Uint8 *ptr = (const Uint8 *)inBuffer->mAudioData; + UInt32 remaining = inBuffer->mAudioDataByteSize; + while (remaining > 0) { + UInt32 len = this->hidden->bufferSize - this->hidden->bufferOffset; + if (len > remaining) { + len = remaining; + } + + SDL_memcpy((char *)this->hidden->buffer + this->hidden->bufferOffset, ptr, len); + ptr += len; + remaining -= len; + this->hidden->bufferOffset += len; + + if (this->hidden->bufferOffset >= this->hidden->bufferSize) { + SDL_LockMutex(this->mixer_lock); + (*this->callbackspec.callback)(this->callbackspec.userdata, this->hidden->buffer, this->hidden->bufferSize); + SDL_UnlockMutex(this->mixer_lock); + this->hidden->bufferOffset = 0; + } + } + } + + AudioQueueEnqueueBuffer(this->hidden->audioQueue, inBuffer, 0, NULL); +} + +#ifdef MACOSX_COREAUDIO +static const AudioObjectPropertyAddress alive_address = { + kAudioDevicePropertyDeviceIsAlive, + kAudioObjectPropertyScopeGlobal, + kAudioObjectPropertyElementMain +}; + +static OSStatus device_unplugged(AudioObjectID devid, UInt32 num_addr, const AudioObjectPropertyAddress *addrs, void *data) +{ + SDL_AudioDevice *this = (SDL_AudioDevice *)data; + SDL_bool dead = SDL_FALSE; + UInt32 isAlive = 1; + UInt32 size = sizeof(isAlive); + OSStatus error; + + if (!SDL_AtomicGet(&this->enabled)) { + return 0; /* already known to be dead. */ + } + + error = AudioObjectGetPropertyData(this->hidden->deviceID, &alive_address, + 0, NULL, &size, &isAlive); + + if (error == kAudioHardwareBadDeviceError) { + dead = SDL_TRUE; /* device was unplugged. */ + } else if ((error == kAudioHardwareNoError) && (!isAlive)) { + dead = SDL_TRUE; /* device died in some other way. */ + } + + if (dead) { + SDL_OpenedAudioDeviceDisconnected(this); + } + + return 0; +} + +/* macOS calls this when the default device changed (if we have a default device open). */ +static OSStatus default_device_changed(AudioObjectID inObjectID, UInt32 inNumberAddresses, const AudioObjectPropertyAddress *inAddresses, void *inUserData) +{ + SDL_AudioDevice *this = (SDL_AudioDevice *)inUserData; +#if DEBUG_COREAUDIO + printf("COREAUDIO: default device changed for SDL audio device %p!\n", this); +#endif + SDL_AtomicSet(&this->hidden->device_change_flag, 1); /* let the audioqueue thread pick up on this when safe to do so. */ + return noErr; +} +#endif + +static void COREAUDIO_CloseDevice(_THIS) +{ + const SDL_bool iscapture = this->iscapture; + int i; + +/* !!! FIXME: what does iOS do when a bluetooth audio device vanishes? Headphones unplugged? */ +/* !!! FIXME: (we only do a "default" device on iOS right now...can we do more?) */ +#ifdef MACOSX_COREAUDIO + if (this->handle != NULL) { /* we don't register this listener for default devices. */ + AudioObjectRemovePropertyListener(this->hidden->deviceID, &alive_address, device_unplugged, this); + } +#endif + + /* if callback fires again, feed silence; don't call into the app. */ + SDL_AtomicSet(&this->paused, 1); + + /* dispose of the audio queue before waiting on the thread, or it might stall for a long time! */ + if (this->hidden->audioQueue) { + AudioQueueFlush(this->hidden->audioQueue); + AudioQueueStop(this->hidden->audioQueue, 0); + AudioQueueDispose(this->hidden->audioQueue, 0); + } + + if (this->hidden->thread) { + SDL_assert(SDL_AtomicGet(&this->shutdown) != 0); /* should have been set by SDL_audio.c */ + SDL_WaitThread(this->hidden->thread, NULL); + } + + if (iscapture) { + open_capture_devices--; + } else { + open_playback_devices--; + } + +#ifndef MACOSX_COREAUDIO + update_audio_session(this, SDL_FALSE, SDL_TRUE); +#endif + + for (i = 0; i < num_open_devices; ++i) { + if (open_devices[i] == this) { + --num_open_devices; + if (i < num_open_devices) { + SDL_memmove(&open_devices[i], &open_devices[i + 1], sizeof(open_devices[i]) * (num_open_devices - i)); + } + break; + } + } + if (num_open_devices == 0) { + SDL_free(open_devices); + open_devices = NULL; + } + + if (this->hidden->ready_semaphore) { + SDL_DestroySemaphore(this->hidden->ready_semaphore); + } + + /* AudioQueueDispose() frees the actual buffer objects. */ + SDL_free(this->hidden->audioBuffer); + SDL_free(this->hidden->thread_error); + SDL_free(this->hidden->buffer); + SDL_free(this->hidden); +} + +#ifdef MACOSX_COREAUDIO +static int prepare_device(_THIS) +{ + void *handle = this->handle; + SDL_bool iscapture = this->iscapture; + AudioDeviceID devid = (AudioDeviceID)((size_t)handle); + OSStatus result = noErr; + UInt32 size = 0; + UInt32 alive = 0; + pid_t pid = 0; + + AudioObjectPropertyAddress addr = { + 0, + kAudioObjectPropertyScopeGlobal, + kAudioObjectPropertyElementMain + }; + + if (handle == NULL) { + size = sizeof(AudioDeviceID); + addr.mSelector = + ((iscapture) ? kAudioHardwarePropertyDefaultInputDevice : kAudioHardwarePropertyDefaultOutputDevice); + result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &addr, + 0, NULL, &size, &devid); + CHECK_RESULT("AudioHardwareGetProperty (default device)"); + } + + addr.mSelector = kAudioDevicePropertyDeviceIsAlive; + addr.mScope = iscapture ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput; + + size = sizeof(alive); + result = AudioObjectGetPropertyData(devid, &addr, 0, NULL, &size, &alive); + CHECK_RESULT("AudioDeviceGetProperty (kAudioDevicePropertyDeviceIsAlive)"); + + if (!alive) { + SDL_SetError("CoreAudio: requested device exists, but isn't alive."); + return 0; + } + + addr.mSelector = kAudioDevicePropertyHogMode; + size = sizeof(pid); + result = AudioObjectGetPropertyData(devid, &addr, 0, NULL, &size, &pid); + + /* some devices don't support this property, so errors are fine here. */ + if ((result == noErr) && (pid != -1)) { + SDL_SetError("CoreAudio: requested device is being hogged."); + return 0; + } + + this->hidden->deviceID = devid; + return 1; +} + +static int assign_device_to_audioqueue(_THIS) +{ + const AudioObjectPropertyAddress prop = { + kAudioDevicePropertyDeviceUID, + this->iscapture ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput, + kAudioObjectPropertyElementMain + }; + + OSStatus result; + CFStringRef devuid; + UInt32 devuidsize = sizeof(devuid); + result = AudioObjectGetPropertyData(this->hidden->deviceID, &prop, 0, NULL, &devuidsize, &devuid); + CHECK_RESULT("AudioObjectGetPropertyData (kAudioDevicePropertyDeviceUID)"); + result = AudioQueueSetProperty(this->hidden->audioQueue, kAudioQueueProperty_CurrentDevice, &devuid, devuidsize); + CHECK_RESULT("AudioQueueSetProperty (kAudioQueueProperty_CurrentDevice)"); + + return 1; +} +#endif + +static int prepare_audioqueue(_THIS) +{ + const AudioStreamBasicDescription *strdesc = &this->hidden->strdesc; + const int iscapture = this->iscapture; + OSStatus result; + int i, numAudioBuffers = 2; + AudioChannelLayout layout; + double MINIMUM_AUDIO_BUFFER_TIME_MS; + const double msecs = (this->spec.samples / ((double)this->spec.freq)) * 1000.0; + ; + + SDL_assert(CFRunLoopGetCurrent() != NULL); + + if (iscapture) { + result = AudioQueueNewInput(strdesc, inputCallback, this, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode, 0, &this->hidden->audioQueue); + CHECK_RESULT("AudioQueueNewInput"); + } else { + result = AudioQueueNewOutput(strdesc, outputCallback, this, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode, 0, &this->hidden->audioQueue); + CHECK_RESULT("AudioQueueNewOutput"); + } + +#ifdef MACOSX_COREAUDIO + if (!assign_device_to_audioqueue(this)) { + return 0; + } + + /* only listen for unplugging on specific devices, not the default device, as that should + switch to a different device (or hang out silently if there _is_ no other device). */ + if (this->handle != NULL) { + /* !!! FIXME: what does iOS do when a bluetooth audio device vanishes? Headphones unplugged? */ + /* !!! FIXME: (we only do a "default" device on iOS right now...can we do more?) */ + /* Fire a callback if the device stops being "alive" (disconnected, etc). */ + /* If this fails, oh well, we won't notice a device had an extraordinary event take place. */ + AudioObjectAddPropertyListener(this->hidden->deviceID, &alive_address, device_unplugged, this); + } +#endif + + /* Calculate the final parameters for this audio specification */ + SDL_CalculateAudioSpec(&this->spec); + + /* Set the channel layout for the audio queue */ + SDL_zero(layout); + switch (this->spec.channels) { + case 1: + layout.mChannelLayoutTag = kAudioChannelLayoutTag_Mono; + break; + case 2: + layout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo; + break; + case 3: + layout.mChannelLayoutTag = kAudioChannelLayoutTag_DVD_4; + break; + case 4: + layout.mChannelLayoutTag = kAudioChannelLayoutTag_Quadraphonic; + break; + case 5: + layout.mChannelLayoutTag = kAudioChannelLayoutTag_MPEG_5_0_A; + break; + case 6: + layout.mChannelLayoutTag = kAudioChannelLayoutTag_MPEG_5_1_A; + break; + case 7: + /* FIXME: Need to move channel[4] (BC) to channel[6] */ + layout.mChannelLayoutTag = kAudioChannelLayoutTag_MPEG_6_1_A; + break; + case 8: + layout.mChannelLayoutTag = kAudioChannelLayoutTag_MPEG_7_1_A; + break; + } + if (layout.mChannelLayoutTag != 0) { + result = AudioQueueSetProperty(this->hidden->audioQueue, kAudioQueueProperty_ChannelLayout, &layout, sizeof(layout)); + CHECK_RESULT("AudioQueueSetProperty(kAudioQueueProperty_ChannelLayout)"); + } + + /* Allocate a sample buffer */ + this->hidden->bufferSize = this->spec.size; + this->hidden->bufferOffset = iscapture ? 0 : this->hidden->bufferSize; + + this->hidden->buffer = SDL_malloc(this->hidden->bufferSize); + if (this->hidden->buffer == NULL) { + SDL_OutOfMemory(); + return 0; + } + + /* Make sure we can feed the device a minimum amount of time */ + MINIMUM_AUDIO_BUFFER_TIME_MS = 15.0; +#if defined(__IPHONEOS__) + if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1) { + /* Older iOS hardware, use 40 ms as a minimum time */ + MINIMUM_AUDIO_BUFFER_TIME_MS = 40.0; + } +#endif + if (msecs < MINIMUM_AUDIO_BUFFER_TIME_MS) { /* use more buffers if we have a VERY small sample set. */ + numAudioBuffers = ((int)SDL_ceil(MINIMUM_AUDIO_BUFFER_TIME_MS / msecs) * 2); + } + + this->hidden->numAudioBuffers = numAudioBuffers; + this->hidden->audioBuffer = SDL_calloc(1, sizeof(AudioQueueBufferRef) * numAudioBuffers); + if (this->hidden->audioBuffer == NULL) { + SDL_OutOfMemory(); + return 0; + } + +#if DEBUG_COREAUDIO + printf("COREAUDIO: numAudioBuffers == %d\n", numAudioBuffers); +#endif + + for (i = 0; i < numAudioBuffers; i++) { + result = AudioQueueAllocateBuffer(this->hidden->audioQueue, this->spec.size, &this->hidden->audioBuffer[i]); + CHECK_RESULT("AudioQueueAllocateBuffer"); + SDL_memset(this->hidden->audioBuffer[i]->mAudioData, this->spec.silence, this->hidden->audioBuffer[i]->mAudioDataBytesCapacity); + this->hidden->audioBuffer[i]->mAudioDataByteSize = this->hidden->audioBuffer[i]->mAudioDataBytesCapacity; + /* !!! FIXME: should we use AudioQueueEnqueueBufferWithParameters and specify all frames be "trimmed" so these are immediately ready to refill with SDL callback data? */ + result = AudioQueueEnqueueBuffer(this->hidden->audioQueue, this->hidden->audioBuffer[i], 0, NULL); + CHECK_RESULT("AudioQueueEnqueueBuffer"); + } + + result = AudioQueueStart(this->hidden->audioQueue, NULL); + CHECK_RESULT("AudioQueueStart"); + + /* We're running! */ + return 1; +} + +static int audioqueue_thread(void *arg) +{ + SDL_AudioDevice *this = (SDL_AudioDevice *)arg; + int rc; + +#ifdef MACOSX_COREAUDIO + const AudioObjectPropertyAddress default_device_address = { + this->iscapture ? kAudioHardwarePropertyDefaultInputDevice : kAudioHardwarePropertyDefaultOutputDevice, + kAudioObjectPropertyScopeGlobal, + kAudioObjectPropertyElementMain + }; + + if (this->handle == NULL) { /* opened the default device? Register to know if the user picks a new default. */ + /* we don't care if this fails; we just won't change to new default devices, but we still otherwise function in this case. */ + AudioObjectAddPropertyListener(kAudioObjectSystemObject, &default_device_address, default_device_changed, this); + } +#endif + + rc = prepare_audioqueue(this); + if (!rc) { + this->hidden->thread_error = SDL_strdup(SDL_GetError()); + SDL_SemPost(this->hidden->ready_semaphore); + return 0; + } + + SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH); + + /* init was successful, alert parent thread and start running... */ + SDL_SemPost(this->hidden->ready_semaphore); + + while (!SDL_AtomicGet(&this->shutdown)) { + CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.10, 1); + +#ifdef MACOSX_COREAUDIO + if ((this->handle == NULL) && SDL_AtomicGet(&this->hidden->device_change_flag)) { + const AudioDeviceID prev_devid = this->hidden->deviceID; + SDL_AtomicSet(&this->hidden->device_change_flag, 0); + +#if DEBUG_COREAUDIO + printf("COREAUDIO: audioqueue_thread is trying to switch to new default device!\n"); +#endif + + /* if any of this fails, there's not much to do but wait to see if the user gives up + and quits (flagging the audioqueue for shutdown), or toggles to some other system + output device (in which case we'll try again). */ + if (prepare_device(this) && (prev_devid != this->hidden->deviceID)) { + AudioQueueStop(this->hidden->audioQueue, 1); + if (assign_device_to_audioqueue(this)) { + int i; + for (i = 0; i < this->hidden->numAudioBuffers; i++) { + SDL_memset(this->hidden->audioBuffer[i]->mAudioData, this->spec.silence, this->hidden->audioBuffer[i]->mAudioDataBytesCapacity); + /* !!! FIXME: should we use AudioQueueEnqueueBufferWithParameters and specify all frames be "trimmed" so these are immediately ready to refill with SDL callback data? */ + AudioQueueEnqueueBuffer(this->hidden->audioQueue, this->hidden->audioBuffer[i], 0, NULL); + } + AudioQueueStart(this->hidden->audioQueue, NULL); + } + } + } +#endif + } + + if (!this->iscapture) { /* Drain off any pending playback. */ + const CFTimeInterval secs = (((this->spec.size / (SDL_AUDIO_BITSIZE(this->spec.format) / 8.0)) / this->spec.channels) / ((CFTimeInterval)this->spec.freq)) * 2.0; + CFRunLoopRunInMode(kCFRunLoopDefaultMode, secs, 0); + } + +#ifdef MACOSX_COREAUDIO + if (this->handle == NULL) { + /* we don't care if this fails; we just won't change to new default devices, but we still otherwise function in this case. */ + AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &default_device_address, default_device_changed, this); + } +#endif + + return 0; +} + +static int COREAUDIO_OpenDevice(_THIS, const char *devname) +{ + AudioStreamBasicDescription *strdesc; + SDL_AudioFormat test_format; + SDL_bool iscapture = this->iscapture; + SDL_AudioDevice **new_open_devices; + + /* Initialize all variables that we clean on shutdown */ + this->hidden = (struct SDL_PrivateAudioData *)SDL_malloc(sizeof(*this->hidden)); + if (this->hidden == NULL) { + return SDL_OutOfMemory(); + } + SDL_zerop(this->hidden); + + strdesc = &this->hidden->strdesc; + + if (iscapture) { + open_capture_devices++; + } else { + open_playback_devices++; + } + + new_open_devices = (SDL_AudioDevice **)SDL_realloc(open_devices, sizeof(open_devices[0]) * (num_open_devices + 1)); + if (new_open_devices) { + open_devices = new_open_devices; + open_devices[num_open_devices++] = this; + } + +#ifndef MACOSX_COREAUDIO + if (!update_audio_session(this, SDL_TRUE, SDL_TRUE)) { + return -1; + } + + /* Stop CoreAudio from doing expensive audio rate conversion */ + @autoreleasepool { + AVAudioSession *session = [AVAudioSession sharedInstance]; + [session setPreferredSampleRate:this->spec.freq error:nil]; + this->spec.freq = (int)session.sampleRate; +#if TARGET_OS_TV + if (iscapture) { + [session setPreferredInputNumberOfChannels:this->spec.channels error:nil]; + this->spec.channels = session.preferredInputNumberOfChannels; + } else { + [session setPreferredOutputNumberOfChannels:this->spec.channels error:nil]; + this->spec.channels = session.preferredOutputNumberOfChannels; + } +#else + /* Calling setPreferredOutputNumberOfChannels seems to break audio output on iOS */ +#endif /* TARGET_OS_TV */ + } +#endif + + /* Setup a AudioStreamBasicDescription with the requested format */ + SDL_zerop(strdesc); + strdesc->mFormatID = kAudioFormatLinearPCM; + strdesc->mFormatFlags = kLinearPCMFormatFlagIsPacked; + strdesc->mChannelsPerFrame = this->spec.channels; + strdesc->mSampleRate = this->spec.freq; + strdesc->mFramesPerPacket = 1; + + for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) { + /* CoreAudio handles most of SDL's formats natively, but not U16, apparently. */ + switch (test_format) { + case AUDIO_U8: + case AUDIO_S8: + case AUDIO_S16LSB: + case AUDIO_S16MSB: + case AUDIO_S32LSB: + case AUDIO_S32MSB: + case AUDIO_F32LSB: + case AUDIO_F32MSB: + break; + + default: + continue; + } + break; + } + + if (!test_format) { /* shouldn't happen, but just in case... */ + return SDL_SetError("%s: Unsupported audio format", "coreaudio"); + } + this->spec.format = test_format; + strdesc->mBitsPerChannel = SDL_AUDIO_BITSIZE(test_format); + if (SDL_AUDIO_ISBIGENDIAN(test_format)) { + strdesc->mFormatFlags |= kLinearPCMFormatFlagIsBigEndian; + } + + if (SDL_AUDIO_ISFLOAT(test_format)) { + strdesc->mFormatFlags |= kLinearPCMFormatFlagIsFloat; + } else if (SDL_AUDIO_ISSIGNED(test_format)) { + strdesc->mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger; + } + + strdesc->mBytesPerFrame = strdesc->mChannelsPerFrame * strdesc->mBitsPerChannel / 8; + strdesc->mBytesPerPacket = strdesc->mBytesPerFrame * strdesc->mFramesPerPacket; + +#ifdef MACOSX_COREAUDIO + if (!prepare_device(this)) { + return -1; + } +#endif + + /* This has to init in a new thread so it can get its own CFRunLoop. :/ */ + this->hidden->ready_semaphore = SDL_CreateSemaphore(0); + if (!this->hidden->ready_semaphore) { + return -1; /* oh well. */ + } + + this->hidden->thread = SDL_CreateThreadInternal(audioqueue_thread, "AudioQueue thread", 512 * 1024, this); + if (!this->hidden->thread) { + return -1; + } + + SDL_SemWait(this->hidden->ready_semaphore); + SDL_DestroySemaphore(this->hidden->ready_semaphore); + this->hidden->ready_semaphore = NULL; + + if ((this->hidden->thread != NULL) && (this->hidden->thread_error != NULL)) { + return SDL_SetError("%s", this->hidden->thread_error); + } + + return (this->hidden->thread != NULL) ? 0 : -1; +} + +#ifndef MACOSX_COREAUDIO +static int COREAUDIO_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture) +{ + AVAudioSession *session = [AVAudioSession sharedInstance]; + + if (name != NULL) { + *name = NULL; + } + SDL_zerop(spec); + spec->freq = [session sampleRate]; + spec->channels = [session outputNumberOfChannels]; + return 0; +} +#else /* MACOSX_COREAUDIO */ +static int COREAUDIO_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture) +{ + AudioDeviceID devid; + AudioBufferList *buflist; + OSStatus result; + UInt32 size; + CFStringRef cfstr; + char *devname; + int usable; + double sampleRate; + CFIndex len; + + AudioObjectPropertyAddress addr = { + iscapture ? kAudioHardwarePropertyDefaultInputDevice + : kAudioHardwarePropertyDefaultOutputDevice, + iscapture ? kAudioDevicePropertyScopeInput + : kAudioDevicePropertyScopeOutput, + kAudioObjectPropertyElementMain + }; + AudioObjectPropertyAddress nameaddr = { + kAudioObjectPropertyName, + iscapture ? kAudioDevicePropertyScopeInput + : kAudioDevicePropertyScopeOutput, + kAudioObjectPropertyElementMain + }; + AudioObjectPropertyAddress freqaddr = { + kAudioDevicePropertyNominalSampleRate, + iscapture ? kAudioDevicePropertyScopeInput + : kAudioDevicePropertyScopeOutput, + kAudioObjectPropertyElementMain + }; + AudioObjectPropertyAddress bufaddr = { + kAudioDevicePropertyStreamConfiguration, + iscapture ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput, + kAudioObjectPropertyElementMain + }; + + /* Get the Device ID */ + cfstr = NULL; + size = sizeof(AudioDeviceID); + result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &addr, + 0, NULL, &size, &devid); + + if (result != noErr) { + return SDL_SetError("%s: Default Device ID not found", "coreaudio"); + } + + if (name != NULL) { + /* Use the Device ID to get the name */ + size = sizeof(CFStringRef); + result = AudioObjectGetPropertyData(devid, &nameaddr, 0, NULL, &size, &cfstr); + + if (result != noErr) { + return SDL_SetError("%s: Default Device Name not found", "coreaudio"); + } + + len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(cfstr), + kCFStringEncodingUTF8); + devname = (char *)SDL_malloc(len + 1); + usable = ((devname != NULL) && + (CFStringGetCString(cfstr, devname, len + 1, kCFStringEncodingUTF8))); + CFRelease(cfstr); + + if (usable) { + usable = 0; + len = strlen(devname); + /* Some devices have whitespace at the end...trim it. */ + while ((len > 0) && (devname[len - 1] == ' ')) { + len--; + usable = len; + } + } + + if (usable) { + devname[len] = '\0'; + } + *name = devname; + } + + /* Uses the Device ID to get the spec */ + SDL_zerop(spec); + + sampleRate = 0; + size = sizeof(sampleRate); + result = AudioObjectGetPropertyData(devid, &freqaddr, 0, NULL, &size, &sampleRate); + + if (result != noErr) { + return SDL_SetError("%s: Default Device Sample Rate not found", "coreaudio"); + } + + spec->freq = (int)sampleRate; + + result = AudioObjectGetPropertyDataSize(devid, &bufaddr, 0, NULL, &size); + if (result != noErr) { + return SDL_SetError("%s: Default Device Data Size not found", "coreaudio"); + } + + buflist = (AudioBufferList *)SDL_malloc(size); + if (buflist == NULL) { + return SDL_SetError("%s: Default Device Buffer List not found", "coreaudio"); + } + + result = AudioObjectGetPropertyData(devid, &bufaddr, 0, NULL, + &size, buflist); + + if (result == noErr) { + UInt32 j; + for (j = 0; j < buflist->mNumberBuffers; j++) { + spec->channels += buflist->mBuffers[j].mNumberChannels; + } + } + + SDL_free(buflist); + + if (spec->channels == 0) { + return SDL_SetError("%s: Default Device has no channels!", "coreaudio"); + } + + return 0; +} +#endif /* MACOSX_COREAUDIO */ + +static void COREAUDIO_Deinitialize(void) +{ +#ifdef MACOSX_COREAUDIO + AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &devlist_address, device_list_changed, NULL); + free_audio_device_list(&capture_devs); + free_audio_device_list(&output_devs); +#endif +} + +static SDL_bool COREAUDIO_Init(SDL_AudioDriverImpl *impl) +{ + /* Set the function pointers */ + impl->OpenDevice = COREAUDIO_OpenDevice; + impl->CloseDevice = COREAUDIO_CloseDevice; + impl->Deinitialize = COREAUDIO_Deinitialize; + impl->GetDefaultAudioInfo = COREAUDIO_GetDefaultAudioInfo; + +#ifdef MACOSX_COREAUDIO + impl->DetectDevices = COREAUDIO_DetectDevices; + AudioObjectAddPropertyListener(kAudioObjectSystemObject, &devlist_address, device_list_changed, NULL); +#else + impl->OnlyHasDefaultOutputDevice = SDL_TRUE; + impl->OnlyHasDefaultCaptureDevice = SDL_TRUE; +#endif + + impl->ProvidesOwnCallbackThread = SDL_TRUE; + impl->HasCaptureSupport = SDL_TRUE; + impl->SupportsNonPow2Samples = SDL_TRUE; + + return SDL_TRUE; /* this audio target is available. */ +} + +AudioBootStrap COREAUDIO_bootstrap = { + "coreaudio", "CoreAudio", COREAUDIO_Init, SDL_FALSE +}; + +#endif /* SDL_AUDIO_DRIVER_COREAUDIO */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/audio/directsound/SDL_directsound.c b/SDL2-2.30.5/src/audio/directsound/SDL_directsound.c similarity index 61% rename from SDL2-2.0.12/src/audio/directsound/SDL_directsound.c rename to SDL2-2.30.5/src/audio/directsound/SDL_directsound.c index 856e116..a98a164 100644 --- a/SDL2-2.0.12/src/audio/directsound/SDL_directsound.c +++ b/SDL2-2.30.5/src/audio/directsound/SDL_directsound.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,69 +20,79 @@ */ #include "../../SDL_internal.h" -#if SDL_AUDIO_DRIVER_DSOUND +#ifdef SDL_AUDIO_DRIVER_DSOUND /* Allow access to a raw mixing buffer */ -#include "SDL_assert.h" #include "SDL_timer.h" #include "SDL_loadso.h" #include "SDL_audio.h" #include "../SDL_audio_c.h" #include "SDL_directsound.h" +#include +#ifdef HAVE_MMDEVICEAPI_H +#include "../../core/windows/SDL_immdevice.h" +#endif /* HAVE_MMDEVICEAPI_H */ #ifndef WAVE_FORMAT_IEEE_FLOAT #define WAVE_FORMAT_IEEE_FLOAT 0x0003 #endif +/* For Vista+, we can enumerate DSound devices with IMMDevice */ +#ifdef HAVE_MMDEVICEAPI_H +static SDL_bool SupportsIMMDevice = SDL_FALSE; +#endif /* HAVE_MMDEVICEAPI_H */ + /* DirectX function pointers for audio */ -static void* DSoundDLL = NULL; -typedef HRESULT (WINAPI *fnDirectSoundCreate8)(LPGUID,LPDIRECTSOUND*,LPUNKNOWN); -typedef HRESULT (WINAPI *fnDirectSoundEnumerateW)(LPDSENUMCALLBACKW, LPVOID); -typedef HRESULT (WINAPI *fnDirectSoundCaptureCreate8)(LPCGUID,LPDIRECTSOUNDCAPTURE8 *,LPUNKNOWN); -typedef HRESULT (WINAPI *fnDirectSoundCaptureEnumerateW)(LPDSENUMCALLBACKW,LPVOID); +static void *DSoundDLL = NULL; +typedef HRESULT(WINAPI *fnDirectSoundCreate8)(LPGUID, LPDIRECTSOUND *, LPUNKNOWN); +typedef HRESULT(WINAPI *fnDirectSoundEnumerateW)(LPDSENUMCALLBACKW, LPVOID); +typedef HRESULT(WINAPI *fnDirectSoundCaptureCreate8)(LPCGUID, LPDIRECTSOUNDCAPTURE8 *, LPUNKNOWN); +typedef HRESULT(WINAPI *fnDirectSoundCaptureEnumerateW)(LPDSENUMCALLBACKW, LPVOID); static fnDirectSoundCreate8 pDirectSoundCreate8 = NULL; static fnDirectSoundEnumerateW pDirectSoundEnumerateW = NULL; static fnDirectSoundCaptureCreate8 pDirectSoundCaptureCreate8 = NULL; static fnDirectSoundCaptureEnumerateW pDirectSoundCaptureEnumerateW = NULL; -static void -DSOUND_Unload(void) +static const GUID SDL_KSDATAFORMAT_SUBTYPE_PCM = { 0x00000001, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } }; +static const GUID SDL_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = { 0x00000003, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } }; + +static void DSOUND_Unload(void) { pDirectSoundCreate8 = NULL; pDirectSoundEnumerateW = NULL; pDirectSoundCaptureCreate8 = NULL; pDirectSoundCaptureEnumerateW = NULL; - if (DSoundDLL != NULL) { + if (DSoundDLL) { SDL_UnloadObject(DSoundDLL); DSoundDLL = NULL; } } - -static int -DSOUND_Load(void) +static int DSOUND_Load(void) { int loaded = 0; DSOUND_Unload(); DSoundDLL = SDL_LoadObject("DSOUND.DLL"); - if (DSoundDLL == NULL) { + if (!DSoundDLL) { SDL_SetError("DirectSound: failed to load DSOUND.DLL"); } else { - /* Now make sure we have DirectX 8 or better... */ - #define DSOUNDLOAD(f) { \ - p##f = (fn##f) SDL_LoadFunction(DSoundDLL, #f); \ - if (!p##f) loaded = 0; \ - } - loaded = 1; /* will reset if necessary. */ +/* Now make sure we have DirectX 8 or better... */ +#define DSOUNDLOAD(f) \ + { \ + p##f = (fn##f)SDL_LoadFunction(DSoundDLL, #f); \ + if (!p##f) \ + loaded = 0; \ + } + loaded = 1; /* will reset if necessary. */ DSOUNDLOAD(DirectSoundCreate8); DSOUNDLOAD(DirectSoundEnumerateW); DSOUNDLOAD(DirectSoundCaptureCreate8); DSOUNDLOAD(DirectSoundCaptureEnumerateW); - #undef DSOUNDLOAD +#undef DSOUNDLOAD if (!loaded) { SDL_SetError("DirectSound: System doesn't appear to have DX8."); @@ -96,13 +106,10 @@ DSOUND_Load(void) return loaded; } -static int -SetDSerror(const char *function, int code) +static int SetDSerror(const char *function, int code) { - static const char *error; - static char errbuf[1024]; + const char *error; - errbuf[0] = 0; switch (code) { case E_NOINTERFACE: error = "Unsupported interface -- Is DirectX 8.0 or later installed?"; @@ -138,49 +145,63 @@ SetDSerror(const char *function, int code) error = "Function not supported"; break; default: - SDL_snprintf(errbuf, SDL_arraysize(errbuf), - "%s: Unknown DirectSound error: 0x%x", function, code); + error = "Unknown DirectSound error"; break; } - if (!errbuf[0]) { - SDL_snprintf(errbuf, SDL_arraysize(errbuf), "%s: %s", function, - error); - } - return SDL_SetError("%s", errbuf); + + return SDL_SetError("%s: %s (0x%x)", function, error, code); } -static void -DSOUND_FreeDeviceHandle(void *handle) +static void DSOUND_FreeDeviceHandle(void *handle) { SDL_free(handle); } -static BOOL CALLBACK -FindAllDevs(LPGUID guid, LPCWSTR desc, LPCWSTR module, LPVOID data) +static int DSOUND_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture) { - const int iscapture = (int) ((size_t) data); - if (guid != NULL) { /* skip default device */ +#ifdef HAVE_MMDEVICEAPI_H + if (SupportsIMMDevice) { + return SDL_IMMDevice_GetDefaultAudioInfo(name, spec, iscapture); + } +#endif /* HAVE_MMDEVICEAPI_H */ + return SDL_Unsupported(); +} + +static BOOL CALLBACK FindAllDevs(LPGUID guid, LPCWSTR desc, LPCWSTR module, LPVOID data) +{ + const int iscapture = (int)((size_t)data); + if (guid != NULL) { /* skip default device */ char *str = WIN_LookupAudioDeviceName(desc, guid); - if (str != NULL) { - LPGUID cpyguid = (LPGUID) SDL_malloc(sizeof (GUID)); - SDL_memcpy(cpyguid, guid, sizeof (GUID)); - SDL_AddAudioDevice(iscapture, str, cpyguid); - SDL_free(str); /* addfn() makes a copy of this string. */ + if (str) { + LPGUID cpyguid = (LPGUID)SDL_malloc(sizeof(GUID)); + SDL_memcpy(cpyguid, guid, sizeof(GUID)); + + /* Note that spec is NULL, because we are required to connect to the + * device before getting the channel mask and output format, making + * this information inaccessible at enumeration time + */ + SDL_AddAudioDevice(iscapture, str, NULL, cpyguid); + SDL_free(str); /* addfn() makes a copy of this string. */ } } - return TRUE; /* keep enumerating. */ + return TRUE; /* keep enumerating. */ } -static void -DSOUND_DetectDevices(void) +static void DSOUND_DetectDevices(void) { - pDirectSoundCaptureEnumerateW(FindAllDevs, (void *) ((size_t) 1)); - pDirectSoundEnumerateW(FindAllDevs, (void *) ((size_t) 0)); +#ifdef HAVE_MMDEVICEAPI_H + if (SupportsIMMDevice) { + SDL_IMMDevice_EnumerateEndpoints(SDL_TRUE); + } else { +#endif /* HAVE_MMDEVICEAPI_H */ + pDirectSoundCaptureEnumerateW(FindAllDevs, (void *)((size_t)1)); + pDirectSoundEnumerateW(FindAllDevs, (void *)((size_t)0)); +#ifdef HAVE_MMDEVICEAPI_H + } +#endif /* HAVE_MMDEVICEAPI_H*/ } - -static void -DSOUND_WaitDevice(_THIS) +static void DSOUND_WaitDevice(_THIS) { DWORD status = 0; DWORD cursor = 0; @@ -208,10 +229,10 @@ DSOUND_WaitDevice(_THIS) /* Try to restore a lost sound buffer */ IDirectSoundBuffer_GetStatus(this->hidden->mixbuf, &status); - if ((status & DSBSTATUS_BUFFERLOST)) { + if (status & DSBSTATUS_BUFFERLOST) { IDirectSoundBuffer_Restore(this->hidden->mixbuf); IDirectSoundBuffer_GetStatus(this->hidden->mixbuf, &status); - if ((status & DSBSTATUS_BUFFERLOST)) { + if (status & DSBSTATUS_BUFFERLOST) { break; } } @@ -237,8 +258,7 @@ DSOUND_WaitDevice(_THIS) } } -static void -DSOUND_PlayDevice(_THIS) +static void DSOUND_PlayDevice(_THIS) { /* Unlock the buffer, allowing it to play */ if (this->hidden->locked_buf) { @@ -248,8 +268,7 @@ DSOUND_PlayDevice(_THIS) } } -static Uint8 * -DSOUND_GetDeviceBuf(_THIS) +static Uint8 *DSOUND_GetDeviceBuf(_THIS) { DWORD cursor = 0; DWORD junk = 0; @@ -267,7 +286,7 @@ DSOUND_GetDeviceBuf(_THIS) } if (result != DS_OK) { SetDSerror("DirectSound GetCurrentPosition", result); - return (NULL); + return NULL; } cursor /= this->spec.size; #ifdef DEBUG_SOUND @@ -290,25 +309,23 @@ DSOUND_GetDeviceBuf(_THIS) /* Lock the audio buffer */ result = IDirectSoundBuffer_Lock(this->hidden->mixbuf, cursor, this->spec.size, - (LPVOID *) & this->hidden->locked_buf, + (LPVOID *)&this->hidden->locked_buf, &rawlen, NULL, &junk, 0); if (result == DSERR_BUFFERLOST) { IDirectSoundBuffer_Restore(this->hidden->mixbuf); result = IDirectSoundBuffer_Lock(this->hidden->mixbuf, cursor, this->spec.size, - (LPVOID *) & this-> - hidden->locked_buf, &rawlen, NULL, + (LPVOID *)&this->hidden->locked_buf, &rawlen, NULL, &junk, 0); } if (result != DS_OK) { SetDSerror("DirectSound Lock", result); - return (NULL); + return NULL; } - return (this->hidden->locked_buf); + return this->hidden->locked_buf; } -static int -DSOUND_CaptureFromDevice(_THIS, void *buffer, int buflen) +static int DSOUND_CaptureFromDevice(_THIS, void *buffer, int buflen) { struct SDL_PrivateAudioData *h = this->hidden; DWORD junk, cursor, ptr1len, ptr2len; @@ -317,7 +334,7 @@ DSOUND_CaptureFromDevice(_THIS, void *buffer, int buflen) SDL_assert(buflen == this->spec.size); while (SDL_TRUE) { - if (SDL_AtomicGet(&this->shutdown)) { /* in case the buffer froze... */ + if (SDL_AtomicGet(&this->shutdown)) { /* in case the buffer froze... */ SDL_memset(buffer, this->spec.silence, buflen); return buflen; } @@ -326,7 +343,7 @@ DSOUND_CaptureFromDevice(_THIS, void *buffer, int buflen) return -1; } if ((cursor / this->spec.size) == h->lastchunk) { - SDL_Delay(1); /* FIXME: find out how much time is left and sleep that long */ + SDL_Delay(1); /* FIXME: find out how much time is left and sleep that long */ } else { break; } @@ -351,8 +368,7 @@ DSOUND_CaptureFromDevice(_THIS, void *buffer, int buflen) return ptr1len; } -static void -DSOUND_FlushCapture(_THIS) +static void DSOUND_FlushCapture(_THIS) { struct SDL_PrivateAudioData *h = this->hidden; DWORD junk, cursor; @@ -361,21 +377,20 @@ DSOUND_FlushCapture(_THIS) } } -static void -DSOUND_CloseDevice(_THIS) +static void DSOUND_CloseDevice(_THIS) { - if (this->hidden->mixbuf != NULL) { + if (this->hidden->mixbuf) { IDirectSoundBuffer_Stop(this->hidden->mixbuf); IDirectSoundBuffer_Release(this->hidden->mixbuf); } - if (this->hidden->sound != NULL) { + if (this->hidden->sound) { IDirectSound_Release(this->hidden->sound); } - if (this->hidden->capturebuf != NULL) { + if (this->hidden->capturebuf) { IDirectSoundCaptureBuffer_Stop(this->hidden->capturebuf); IDirectSoundCaptureBuffer_Release(this->hidden->capturebuf); } - if (this->hidden->capture != NULL) { + if (this->hidden->capture) { IDirectSoundCapture_Release(this->hidden->capture); } SDL_free(this->hidden); @@ -385,8 +400,7 @@ DSOUND_CloseDevice(_THIS) number of audio chunks available in the created buffer. This is for playback devices, not capture. */ -static int -CreateSecondary(_THIS, const DWORD bufsize, WAVEFORMATEX *wfmt) +static int CreateSecondary(_THIS, const DWORD bufsize, WAVEFORMATEX *wfmt) { LPDIRECTSOUND sndObj = this->hidden->sound; LPDIRECTSOUNDBUFFER *sndbuf = &this->hidden->mixbuf; @@ -410,14 +424,14 @@ CreateSecondary(_THIS, const DWORD bufsize, WAVEFORMATEX *wfmt) /* Silence the initial audio buffer */ result = IDirectSoundBuffer_Lock(*sndbuf, 0, format.dwBufferBytes, - (LPVOID *) & pvAudioPtr1, &dwAudioBytes1, - (LPVOID *) & pvAudioPtr2, &dwAudioBytes2, + (LPVOID *)&pvAudioPtr1, &dwAudioBytes1, + (LPVOID *)&pvAudioPtr2, &dwAudioBytes2, DSBLOCK_ENTIREBUFFER); if (result == DS_OK) { SDL_memset(pvAudioPtr1, this->spec.silence, dwAudioBytes1); IDirectSoundBuffer_Unlock(*sndbuf, - (LPVOID) pvAudioPtr1, dwAudioBytes1, - (LPVOID) pvAudioPtr2, dwAudioBytes2); + (LPVOID)pvAudioPtr1, dwAudioBytes1, + (LPVOID)pvAudioPtr2, dwAudioBytes2); } /* We're ready to go */ @@ -428,8 +442,7 @@ CreateSecondary(_THIS, const DWORD bufsize, WAVEFORMATEX *wfmt) number of audio chunks available in the created buffer. This is for capture devices, not playback. */ -static int -CreateCaptureBuffer(_THIS, const DWORD bufsize, WAVEFORMATEX *wfmt) +static int CreateCaptureBuffer(_THIS, const DWORD bufsize, WAVEFORMATEX *wfmt) { LPDIRECTSOUNDCAPTURE capture = this->hidden->capture; LPDIRECTSOUNDCAPTUREBUFFER *capturebuf = &this->hidden->capturebuf; @@ -437,7 +450,7 @@ CreateCaptureBuffer(_THIS, const DWORD bufsize, WAVEFORMATEX *wfmt) HRESULT result; SDL_zero(format); - format.dwSize = sizeof (format); + format.dwSize = sizeof(format); format.dwFlags = DSCBCAPS_WAVEMAPPED; format.dwBufferBytes = bufsize; format.lpwfxFormat = wfmt; @@ -468,21 +481,19 @@ CreateCaptureBuffer(_THIS, const DWORD bufsize, WAVEFORMATEX *wfmt) return 0; } -static int -DSOUND_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) +static int DSOUND_OpenDevice(_THIS, const char *devname) { const DWORD numchunks = 8; HRESULT result; - SDL_bool valid_format = SDL_FALSE; SDL_bool tried_format = SDL_FALSE; - SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format); - LPGUID guid = (LPGUID) handle; + SDL_bool iscapture = this->iscapture; + SDL_AudioFormat test_format; + LPGUID guid = (LPGUID)this->handle; DWORD bufsize; /* Initialize all variables that we clean on shutdown */ - this->hidden = (struct SDL_PrivateAudioData *) - SDL_malloc((sizeof *this->hidden)); - if (this->hidden == NULL) { + this->hidden = (struct SDL_PrivateAudioData *)SDL_malloc(sizeof(*this->hidden)); + if (!this->hidden) { return SDL_OutOfMemory(); } SDL_zerop(this->hidden); @@ -506,7 +517,7 @@ DSOUND_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) } } - while ((!valid_format) && (test_format)) { + for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) { switch (test_format) { case AUDIO_U8: case AUDIO_S16: @@ -522,62 +533,104 @@ DSOUND_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) bufsize = numchunks * this->spec.size; if ((bufsize < DSBSIZE_MIN) || (bufsize > DSBSIZE_MAX)) { SDL_SetError("Sound buffer size must be between %d and %d", - (int) ((DSBSIZE_MIN < numchunks) ? 1 : DSBSIZE_MIN / numchunks), - (int) (DSBSIZE_MAX / numchunks)); + (int)((DSBSIZE_MIN < numchunks) ? 1 : DSBSIZE_MIN / numchunks), + (int)(DSBSIZE_MAX / numchunks)); } else { int rc; - WAVEFORMATEX wfmt; + WAVEFORMATEXTENSIBLE wfmt; SDL_zero(wfmt); - if (SDL_AUDIO_ISFLOAT(this->spec.format)) { - wfmt.wFormatTag = WAVE_FORMAT_IEEE_FLOAT; + if (this->spec.channels > 2) { + wfmt.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; + wfmt.Format.cbSize = sizeof(wfmt) - sizeof(WAVEFORMATEX); + + if (SDL_AUDIO_ISFLOAT(this->spec.format)) { + SDL_memcpy(&wfmt.SubFormat, &SDL_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, sizeof(GUID)); + } else { + SDL_memcpy(&wfmt.SubFormat, &SDL_KSDATAFORMAT_SUBTYPE_PCM, sizeof(GUID)); + } + wfmt.Samples.wValidBitsPerSample = SDL_AUDIO_BITSIZE(this->spec.format); + + switch (this->spec.channels) { + case 3: /* 3.0 (or 2.1) */ + wfmt.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER; + break; + case 4: /* 4.0 */ + wfmt.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT; + break; + case 5: /* 5.0 (or 4.1) */ + wfmt.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT; + break; + case 6: /* 5.1 */ + wfmt.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT; + break; + case 7: /* 6.1 */ + wfmt.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | SPEAKER_BACK_CENTER; + break; + case 8: /* 7.1 */ + wfmt.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT; + break; + default: + SDL_assert(0 && "Unsupported channel count!"); + break; + } + } else if (SDL_AUDIO_ISFLOAT(this->spec.format)) { + wfmt.Format.wFormatTag = WAVE_FORMAT_IEEE_FLOAT; } else { - wfmt.wFormatTag = WAVE_FORMAT_PCM; + wfmt.Format.wFormatTag = WAVE_FORMAT_PCM; } - wfmt.wBitsPerSample = SDL_AUDIO_BITSIZE(this->spec.format); - wfmt.nChannels = this->spec.channels; - wfmt.nSamplesPerSec = this->spec.freq; - wfmt.nBlockAlign = wfmt.nChannels * (wfmt.wBitsPerSample / 8); - wfmt.nAvgBytesPerSec = wfmt.nSamplesPerSec * wfmt.nBlockAlign; + wfmt.Format.wBitsPerSample = SDL_AUDIO_BITSIZE(this->spec.format); + wfmt.Format.nChannels = this->spec.channels; + wfmt.Format.nSamplesPerSec = this->spec.freq; + wfmt.Format.nBlockAlign = wfmt.Format.nChannels * (wfmt.Format.wBitsPerSample / 8); + wfmt.Format.nAvgBytesPerSec = wfmt.Format.nSamplesPerSec * wfmt.Format.nBlockAlign; - rc = iscapture ? CreateCaptureBuffer(this, bufsize, &wfmt) : CreateSecondary(this, bufsize, &wfmt); + rc = iscapture ? CreateCaptureBuffer(this, bufsize, (WAVEFORMATEX *)&wfmt) : CreateSecondary(this, bufsize, (WAVEFORMATEX *)&wfmt); if (rc == 0) { this->hidden->num_buffers = numchunks; - valid_format = SDL_TRUE; + break; } } - break; + continue; + default: + continue; } - test_format = SDL_NextAudioFormat(); + break; } - if (!valid_format) { + if (!test_format) { if (tried_format) { - return -1; /* CreateSecondary() should have called SDL_SetError(). */ + return -1; /* CreateSecondary() should have called SDL_SetError(). */ } - return SDL_SetError("DirectSound: Unsupported audio format"); + return SDL_SetError("%s: Unsupported audio format", "directsound"); } /* Playback buffers will auto-start playing in DSOUND_WaitDevice() */ - return 0; /* good to go. */ + return 0; /* good to go. */ } - -static void -DSOUND_Deinitialize(void) +static void DSOUND_Deinitialize(void) { +#ifdef HAVE_MMDEVICEAPI_H + if (SupportsIMMDevice) { + SDL_IMMDevice_Quit(); + SupportsIMMDevice = SDL_FALSE; + } +#endif /* HAVE_MMDEVICEAPI_H */ DSOUND_Unload(); } - -static int -DSOUND_Init(SDL_AudioDriverImpl * impl) +static SDL_bool DSOUND_Init(SDL_AudioDriverImpl *impl) { if (!DSOUND_Load()) { - return 0; + return SDL_FALSE; } +#ifdef HAVE_MMDEVICEAPI_H + SupportsIMMDevice = !(SDL_IMMDevice_Init() < 0); +#endif /* HAVE_MMDEVICEAPI_H */ + /* Set the function pointers */ impl->DetectDevices = DSOUND_DetectDevices; impl->OpenDevice = DSOUND_OpenDevice; @@ -589,14 +642,16 @@ DSOUND_Init(SDL_AudioDriverImpl * impl) impl->CloseDevice = DSOUND_CloseDevice; impl->FreeDeviceHandle = DSOUND_FreeDeviceHandle; impl->Deinitialize = DSOUND_Deinitialize; + impl->GetDefaultAudioInfo = DSOUND_GetDefaultAudioInfo; impl->HasCaptureSupport = SDL_TRUE; + impl->SupportsNonPow2Samples = SDL_TRUE; - return 1; /* this audio target is available. */ + return SDL_TRUE; /* this audio target is available. */ } AudioBootStrap DSOUND_bootstrap = { - "directsound", "DirectSound", DSOUND_Init, 0 + "directsound", "DirectSound", DSOUND_Init, SDL_FALSE }; #endif /* SDL_AUDIO_DRIVER_DSOUND */ diff --git a/SDL2-2.0.12/src/audio/directsound/SDL_directsound.h b/SDL2-2.30.5/src/audio/directsound/SDL_directsound.h similarity index 93% rename from SDL2-2.0.12/src/audio/directsound/SDL_directsound.h rename to SDL2-2.30.5/src/audio/directsound/SDL_directsound.h index e120de6..051b9d7 100644 --- a/SDL2-2.0.12/src/audio/directsound/SDL_directsound.h +++ b/SDL2-2.30.5/src/audio/directsound/SDL_directsound.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -28,7 +28,7 @@ #include "../SDL_sysaudio.h" /* Hidden "this" pointer for the audio functions */ -#define _THIS SDL_AudioDevice *this +#define _THIS SDL_AudioDevice *this /* The DirectSound objects */ struct SDL_PrivateAudioData diff --git a/SDL2-2.0.12/src/audio/disk/SDL_diskaudio.c b/SDL2-2.30.5/src/audio/disk/SDL_diskaudio.c similarity index 53% rename from SDL2-2.0.12/src/audio/disk/SDL_diskaudio.c rename to SDL2-2.30.5/src/audio/disk/SDL_diskaudio.c index dfe1bc2..d9d4aae 100644 --- a/SDL2-2.0.12/src/audio/disk/SDL_diskaudio.c +++ b/SDL2-2.30.5/src/audio/disk/SDL_diskaudio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,11 +20,11 @@ */ #include "../../SDL_internal.h" -#if SDL_AUDIO_DRIVER_DISK +#ifdef SDL_AUDIO_DRIVER_DISK /* Output raw audio data to a file. */ -#if HAVE_STDIO_H +#ifdef HAVE_STDIO_H #include #endif @@ -33,153 +33,142 @@ #include "SDL_audio.h" #include "../SDL_audio_c.h" #include "SDL_diskaudio.h" -#include "SDL_log.h" /* !!! FIXME: these should be SDL hints, not environment variables. */ /* environment variables and defaults. */ -#define DISKENVR_OUTFILE "SDL_DISKAUDIOFILE" -#define DISKDEFAULT_OUTFILE "sdlaudio.raw" -#define DISKENVR_INFILE "SDL_DISKAUDIOFILEIN" -#define DISKDEFAULT_INFILE "sdlaudio-in.raw" -#define DISKENVR_IODELAY "SDL_DISKAUDIODELAY" +#define DISKENVR_OUTFILE "SDL_DISKAUDIOFILE" +#define DISKDEFAULT_OUTFILE "sdlaudio.raw" +#define DISKENVR_INFILE "SDL_DISKAUDIOFILEIN" +#define DISKDEFAULT_INFILE "sdlaudio-in.raw" +#define DISKENVR_IODELAY "SDL_DISKAUDIODELAY" /* This function waits until it is possible to write a full sound buffer */ -static void -DISKAUDIO_WaitDevice(_THIS) +static void DISKAUDIO_WaitDevice(_THIS) { - SDL_Delay(this->hidden->io_delay); + SDL_Delay(_this->hidden->io_delay); } -static void -DISKAUDIO_PlayDevice(_THIS) +static void DISKAUDIO_PlayDevice(_THIS) { - const size_t written = SDL_RWwrite(this->hidden->io, - this->hidden->mixbuf, - 1, this->spec.size); + const size_t written = SDL_RWwrite(_this->hidden->io, + _this->hidden->mixbuf, + 1, _this->spec.size); /* If we couldn't write, assume fatal error for now */ - if (written != this->spec.size) { - SDL_OpenedAudioDeviceDisconnected(this); + if (written != _this->spec.size) { + SDL_OpenedAudioDeviceDisconnected(_this); } #ifdef DEBUG_AUDIO fprintf(stderr, "Wrote %d bytes of audio data\n", written); #endif } -static Uint8 * -DISKAUDIO_GetDeviceBuf(_THIS) +static Uint8 *DISKAUDIO_GetDeviceBuf(_THIS) { - return (this->hidden->mixbuf); + return _this->hidden->mixbuf; } -static int -DISKAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen) +static int DISKAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen) { - struct SDL_PrivateAudioData *h = this->hidden; + struct SDL_PrivateAudioData *h = _this->hidden; const int origbuflen = buflen; SDL_Delay(h->io_delay); if (h->io) { const size_t br = SDL_RWread(h->io, buffer, 1, buflen); - buflen -= (int) br; - buffer = ((Uint8 *) buffer) + br; - if (buflen > 0) { /* EOF (or error, but whatever). */ + buflen -= (int)br; + buffer = ((Uint8 *)buffer) + br; + if (buflen > 0) { /* EOF (or error, but whatever). */ SDL_RWclose(h->io); h->io = NULL; } } /* if we ran out of file, just write silence. */ - SDL_memset(buffer, this->spec.silence, buflen); + SDL_memset(buffer, _this->spec.silence, buflen); return origbuflen; } -static void -DISKAUDIO_FlushCapture(_THIS) +static void DISKAUDIO_FlushCapture(_THIS) { /* no op...we don't advance the file pointer or anything. */ } - -static void -DISKAUDIO_CloseDevice(_THIS) +static void DISKAUDIO_CloseDevice(_THIS) { - if (this->hidden->io != NULL) { - SDL_RWclose(this->hidden->io); + if (_this->hidden->io) { + SDL_RWclose(_this->hidden->io); } - SDL_free(this->hidden->mixbuf); - SDL_free(this->hidden); + SDL_free(_this->hidden->mixbuf); + SDL_free(_this->hidden); } - -static const char * -get_filename(const int iscapture, const char *devname) +static const char *get_filename(const SDL_bool iscapture, const char *devname) { - if (devname == NULL) { + if (!devname) { devname = SDL_getenv(iscapture ? DISKENVR_INFILE : DISKENVR_OUTFILE); - if (devname == NULL) { + if (!devname) { devname = iscapture ? DISKDEFAULT_INFILE : DISKDEFAULT_OUTFILE; } } return devname; } -static int -DISKAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) +static int DISKAUDIO_OpenDevice(_THIS, const char *devname) { + void *handle = _this->handle; /* handle != NULL means "user specified the placeholder name on the fake detected device list" */ + SDL_bool iscapture = _this->iscapture; const char *fname = get_filename(iscapture, handle ? NULL : devname); const char *envr = SDL_getenv(DISKENVR_IODELAY); - this->hidden = (struct SDL_PrivateAudioData *) - SDL_malloc(sizeof(*this->hidden)); - if (this->hidden == NULL) { + _this->hidden = (struct SDL_PrivateAudioData *) + SDL_malloc(sizeof(*_this->hidden)); + if (!_this->hidden) { return SDL_OutOfMemory(); } - SDL_zerop(this->hidden); + SDL_zerop(_this->hidden); - if (envr != NULL) { - this->hidden->io_delay = SDL_atoi(envr); + if (envr) { + _this->hidden->io_delay = SDL_atoi(envr); } else { - this->hidden->io_delay = ((this->spec.samples * 1000) / this->spec.freq); + _this->hidden->io_delay = ((_this->spec.samples * 1000) / _this->spec.freq); } /* Open the audio device */ - this->hidden->io = SDL_RWFromFile(fname, iscapture ? "rb" : "wb"); - if (this->hidden->io == NULL) { + _this->hidden->io = SDL_RWFromFile(fname, iscapture ? "rb" : "wb"); + if (!_this->hidden->io) { return -1; } /* Allocate mixing buffer */ if (!iscapture) { - this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->spec.size); - if (this->hidden->mixbuf == NULL) { + _this->hidden->mixbuf = (Uint8 *)SDL_malloc(_this->spec.size); + if (!_this->hidden->mixbuf) { return SDL_OutOfMemory(); } - SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size); + SDL_memset(_this->hidden->mixbuf, _this->spec.silence, _this->spec.size); } SDL_LogCritical(SDL_LOG_CATEGORY_AUDIO, - "You are using the SDL disk i/o audio driver!\n"); + "You are using the SDL disk i/o audio driver!\n"); SDL_LogCritical(SDL_LOG_CATEGORY_AUDIO, - " %s file [%s].\n", iscapture ? "Reading from" : "Writing to", - fname); + " %s file [%s].\n", iscapture ? "Reading from" : "Writing to", + fname); /* We're ready to rock and roll. :-) */ return 0; } -static void -DISKAUDIO_DetectDevices(void) +static void DISKAUDIO_DetectDevices(void) { - SDL_AddAudioDevice(SDL_FALSE, DEFAULT_OUTPUT_DEVNAME, (void *) 0x1); - SDL_AddAudioDevice(SDL_TRUE, DEFAULT_INPUT_DEVNAME, (void *) 0x2); + SDL_AddAudioDevice(SDL_FALSE, DEFAULT_OUTPUT_DEVNAME, NULL, (void *)0x1); + SDL_AddAudioDevice(SDL_TRUE, DEFAULT_INPUT_DEVNAME, NULL, (void *)0x2); } -static int -DISKAUDIO_Init(SDL_AudioDriverImpl * impl) +static SDL_bool DISKAUDIO_Init(SDL_AudioDriverImpl *impl) { /* Set the function pointers */ impl->OpenDevice = DISKAUDIO_OpenDevice; @@ -192,14 +181,15 @@ DISKAUDIO_Init(SDL_AudioDriverImpl * impl) impl->CloseDevice = DISKAUDIO_CloseDevice; impl->DetectDevices = DISKAUDIO_DetectDevices; - impl->AllowsArbitraryDeviceNames = 1; + impl->AllowsArbitraryDeviceNames = SDL_TRUE; impl->HasCaptureSupport = SDL_TRUE; + impl->SupportsNonPow2Samples = SDL_TRUE; - return 1; /* this audio target is available. */ + return SDL_TRUE; /* this audio target is available. */ } AudioBootStrap DISKAUDIO_bootstrap = { - "disk", "direct-to-disk audio", DISKAUDIO_Init, 1 + "disk", "direct-to-disk audio", DISKAUDIO_Init, SDL_TRUE }; #endif /* SDL_AUDIO_DRIVER_DISK */ diff --git a/SDL2-2.0.12/src/audio/disk/SDL_diskaudio.h b/SDL2-2.30.5/src/audio/disk/SDL_diskaudio.h similarity index 92% rename from SDL2-2.0.12/src/audio/disk/SDL_diskaudio.h rename to SDL2-2.30.5/src/audio/disk/SDL_diskaudio.h index 44de8ac..8ae237f 100644 --- a/SDL2-2.0.12/src/audio/disk/SDL_diskaudio.h +++ b/SDL2-2.30.5/src/audio/disk/SDL_diskaudio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -27,7 +27,7 @@ #include "../SDL_sysaudio.h" /* Hidden "this" pointer for the audio functions */ -#define _THIS SDL_AudioDevice *this +#define _THIS SDL_AudioDevice *_this struct SDL_PrivateAudioData { diff --git a/SDL2-2.0.12/src/audio/dsp/SDL_dspaudio.c b/SDL2-2.30.5/src/audio/dsp/SDL_dspaudio.c similarity index 80% rename from SDL2-2.0.12/src/audio/dsp/SDL_dspaudio.c rename to SDL2-2.30.5/src/audio/dsp/SDL_dspaudio.c index b5df766..fdbad8f 100644 --- a/SDL2-2.0.12/src/audio/dsp/SDL_dspaudio.c +++ b/SDL2-2.30.5/src/audio/dsp/SDL_dspaudio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,12 +20,12 @@ */ #include "../../SDL_internal.h" -#if SDL_AUDIO_DRIVER_OSS +#ifdef SDL_AUDIO_DRIVER_OSS /* Allow access to a raw mixing buffer */ -#include /* For perror() */ -#include /* For strerror() */ +#include /* For perror() */ +#include /* For strerror() */ #include #include #include @@ -34,13 +34,7 @@ #include #include -#if SDL_AUDIO_DRIVER_OSS_SOUNDCARD_H -/* This is installed on some systems */ -#include -#else -/* This is recommended by OSS */ #include -#endif #include "SDL_timer.h" #include "SDL_audio.h" @@ -48,16 +42,12 @@ #include "../SDL_audiodev_c.h" #include "SDL_dspaudio.h" - -static void -DSP_DetectDevices(void) +static void DSP_DetectDevices(void) { SDL_EnumUnixAudioDevices(0, NULL); } - -static void -DSP_CloseDevice(_THIS) +static void DSP_CloseDevice(_THIS) { if (this->hidden->audio_fd >= 0) { close(this->hidden->audio_fd); @@ -66,10 +56,9 @@ DSP_CloseDevice(_THIS) SDL_free(this->hidden); } - -static int -DSP_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) +static int DSP_OpenDevice(_THIS, const char *devname) { + SDL_bool iscapture = this->iscapture; const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT); int format; int value; @@ -78,32 +67,32 @@ DSP_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) /* We don't care what the devname is...we'll try to open anything. */ /* ...but default to first name in the list... */ - if (devname == NULL) { + if (!devname) { devname = SDL_GetAudioDeviceName(0, iscapture); - if (devname == NULL) { + if (!devname) { return SDL_SetError("No such audio device"); } } /* Make sure fragment size stays a power of 2, or OSS fails. */ /* I don't know which of these are actually legal values, though... */ - if (this->spec.channels > 8) + if (this->spec.channels > 8) { this->spec.channels = 8; - else if (this->spec.channels > 4) + } else if (this->spec.channels > 4) { this->spec.channels = 4; - else if (this->spec.channels > 2) + } else if (this->spec.channels > 2) { this->spec.channels = 2; + } /* Initialize all variables that we clean on shutdown */ - this->hidden = (struct SDL_PrivateAudioData *) - SDL_malloc((sizeof *this->hidden)); - if (this->hidden == NULL) { + this->hidden = (struct SDL_PrivateAudioData *) SDL_malloc(sizeof(*this->hidden)); + if (!this->hidden) { return SDL_OutOfMemory(); } SDL_zerop(this->hidden); /* Open the audio device */ - this->hidden->audio_fd = open(devname, flags, 0); + this->hidden->audio_fd = open(devname, flags | O_CLOEXEC, 0); if (this->hidden->audio_fd < 0) { return SDL_SetError("Couldn't open %s: %s", devname, strerror(errno)); } @@ -209,11 +198,12 @@ DSP_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) SDL_CalculateAudioSpec(&this->spec); /* Determine the power of two of the fragment size */ - for (frag_spec = 0; (0x01U << frag_spec) < this->spec.size; ++frag_spec); + for (frag_spec = 0; (0x01U << frag_spec) < this->spec.size; ++frag_spec) { + } if ((0x01U << frag_spec) != this->spec.size) { return SDL_SetError("Fragment size must be a power of two"); } - frag_spec |= 0x00020000; /* two fragments, for low latency */ + frag_spec |= 0x00020000; /* two fragments, for low latency */ /* Set the audio buffering parameters */ #ifdef DEBUG_AUDIO @@ -237,8 +227,8 @@ DSP_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) /* Allocate mixing buffer */ if (!iscapture) { this->hidden->mixlen = this->spec.size; - this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen); - if (this->hidden->mixbuf == NULL) { + this->hidden->mixbuf = (Uint8 *)SDL_malloc(this->hidden->mixlen); + if (!this->hidden->mixbuf) { return SDL_OutOfMemory(); } SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size); @@ -248,9 +238,7 @@ DSP_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) return 0; } - -static void -DSP_PlayDevice(_THIS) +static void DSP_PlayDevice(_THIS) { struct SDL_PrivateAudioData *h = this->hidden; if (write(h->audio_fd, h->mixbuf, h->mixlen) == -1) { @@ -262,27 +250,24 @@ DSP_PlayDevice(_THIS) #endif } -static Uint8 * -DSP_GetDeviceBuf(_THIS) +static Uint8 *DSP_GetDeviceBuf(_THIS) { - return (this->hidden->mixbuf); + return this->hidden->mixbuf; } -static int -DSP_CaptureFromDevice(_THIS, void *buffer, int buflen) +static int DSP_CaptureFromDevice(_THIS, void *buffer, int buflen) { - return (int) read(this->hidden->audio_fd, buffer, buflen); + return (int)read(this->hidden->audio_fd, buffer, buflen); } -static void -DSP_FlushCapture(_THIS) +static void DSP_FlushCapture(_THIS) { struct SDL_PrivateAudioData *h = this->hidden; audio_buf_info info; if (ioctl(h->audio_fd, SNDCTL_DSP_GETISPACE, &info) == 0) { while (info.bytes > 0) { char buf[512]; - const size_t len = SDL_min(sizeof (buf), info.bytes); + const size_t len = SDL_min(sizeof(buf), info.bytes); const ssize_t br = read(h->audio_fd, buf, len); if (br <= 0) { break; @@ -292,9 +277,23 @@ DSP_FlushCapture(_THIS) } } -static int -DSP_Init(SDL_AudioDriverImpl * impl) +static SDL_bool InitTimeDevicesExist = SDL_FALSE; +static int look_for_devices_test(int fd) { + InitTimeDevicesExist = SDL_TRUE; /* note that _something_ exists. */ + /* Don't add to the device list, we're just seeing if any devices exist. */ + return 0; +} + +static SDL_bool DSP_Init(SDL_AudioDriverImpl *impl) +{ + InitTimeDevicesExist = SDL_FALSE; + SDL_EnumUnixAudioDevices(0, look_for_devices_test); + if (!InitTimeDevicesExist) { + SDL_SetError("dsp: No such audio device"); + return SDL_FALSE; /* maybe try a different backend. */ + } + /* Set the function pointers */ impl->DetectDevices = DSP_DetectDevices; impl->OpenDevice = DSP_OpenDevice; @@ -304,15 +303,14 @@ DSP_Init(SDL_AudioDriverImpl * impl) impl->CaptureFromDevice = DSP_CaptureFromDevice; impl->FlushCapture = DSP_FlushCapture; - impl->AllowsArbitraryDeviceNames = 1; + impl->AllowsArbitraryDeviceNames = SDL_TRUE; impl->HasCaptureSupport = SDL_TRUE; - return 1; /* this audio target is available. */ + return SDL_TRUE; /* this audio target is available. */ } - AudioBootStrap DSP_bootstrap = { - "dsp", "OSS /dev/dsp standard audio", DSP_Init, 0 + "dsp", "OSS /dev/dsp standard audio", DSP_Init, SDL_FALSE }; #endif /* SDL_AUDIO_DRIVER_OSS */ diff --git a/SDL2-2.0.12/src/audio/dsp/SDL_dspaudio.h b/SDL2-2.30.5/src/audio/dsp/SDL_dspaudio.h similarity index 88% rename from SDL2-2.0.12/src/audio/dsp/SDL_dspaudio.h rename to SDL2-2.30.5/src/audio/dsp/SDL_dspaudio.h index 2955bbc..11214a5 100644 --- a/SDL2-2.0.12/src/audio/dsp/SDL_dspaudio.h +++ b/SDL2-2.30.5/src/audio/dsp/SDL_dspaudio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,7 +26,7 @@ #include "../SDL_sysaudio.h" /* Hidden "this" pointer for the audio functions */ -#define _THIS SDL_AudioDevice *this +#define _THIS SDL_AudioDevice *this struct SDL_PrivateAudioData { @@ -37,7 +37,7 @@ struct SDL_PrivateAudioData Uint8 *mixbuf; int mixlen; }; -#define FUDGE_TICKS 10 /* The scheduler overhead ticks per frame */ +#define FUDGE_TICKS 10 /* The scheduler overhead ticks per frame */ #endif /* SDL_dspaudio_h_ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/audio/dummy/SDL_dummyaudio.c b/SDL2-2.30.5/src/audio/dummy/SDL_dummyaudio.c similarity index 66% rename from SDL2-2.0.12/src/audio/dummy/SDL_dummyaudio.c rename to SDL2-2.30.5/src/audio/dummy/SDL_dummyaudio.c index 8cbfc2f..b17cd44 100644 --- a/SDL2-2.0.12/src/audio/dummy/SDL_dummyaudio.c +++ b/SDL2-2.30.5/src/audio/dummy/SDL_dummyaudio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,6 +20,8 @@ */ #include "../../SDL_internal.h" +#ifdef SDL_AUDIO_DRIVER_DUMMY + /* Output audio to nowhere... */ #include "SDL_timer.h" @@ -27,39 +29,40 @@ #include "../SDL_audio_c.h" #include "SDL_dummyaudio.h" -static int -DUMMYAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) +static int DUMMYAUDIO_OpenDevice(_THIS, const char *devname) { - return 0; /* always succeeds. */ + _this->hidden = (void *)0x1; /* just something non-NULL */ + + return 0; /* always succeeds. */ } -static int -DUMMYAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen) +static int DUMMYAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen) { /* Delay to make this sort of simulate real audio input. */ - SDL_Delay((this->spec.samples * 1000) / this->spec.freq); + SDL_Delay((_this->spec.samples * 1000) / _this->spec.freq); /* always return a full buffer of silence. */ - SDL_memset(buffer, this->spec.silence, buflen); + SDL_memset(buffer, _this->spec.silence, buflen); return buflen; } -static int -DUMMYAUDIO_Init(SDL_AudioDriverImpl * impl) +static SDL_bool DUMMYAUDIO_Init(SDL_AudioDriverImpl *impl) { /* Set the function pointers */ impl->OpenDevice = DUMMYAUDIO_OpenDevice; impl->CaptureFromDevice = DUMMYAUDIO_CaptureFromDevice; - impl->OnlyHasDefaultOutputDevice = 1; - impl->OnlyHasDefaultCaptureDevice = 1; + impl->OnlyHasDefaultOutputDevice = SDL_TRUE; + impl->OnlyHasDefaultCaptureDevice = SDL_TRUE; impl->HasCaptureSupport = SDL_TRUE; - return 1; /* this audio target is available. */ + return SDL_TRUE; /* this audio target is available. */ } AudioBootStrap DUMMYAUDIO_bootstrap = { - "dummy", "SDL dummy audio driver", DUMMYAUDIO_Init, 1 + "dummy", "SDL dummy audio driver", DUMMYAUDIO_Init, SDL_TRUE }; +#endif + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/audio/dummy/SDL_dummyaudio.h b/SDL2-2.30.5/src/audio/dummy/SDL_dummyaudio.h similarity index 92% rename from SDL2-2.0.12/src/audio/dummy/SDL_dummyaudio.h rename to SDL2-2.30.5/src/audio/dummy/SDL_dummyaudio.h index 47d49e5..500f5d9 100644 --- a/SDL2-2.0.12/src/audio/dummy/SDL_dummyaudio.h +++ b/SDL2-2.30.5/src/audio/dummy/SDL_dummyaudio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,7 +26,7 @@ #include "../SDL_sysaudio.h" /* Hidden "this" pointer for the audio functions */ -#define _THIS SDL_AudioDevice *this +#define _THIS SDL_AudioDevice *_this struct SDL_PrivateAudioData { diff --git a/SDL2-2.0.12/src/audio/emscripten/SDL_emscriptenaudio.c b/SDL2-2.30.5/src/audio/emscripten/SDL_emscriptenaudio.c similarity index 70% rename from SDL2-2.0.12/src/audio/emscripten/SDL_emscriptenaudio.c rename to SDL2-2.30.5/src/audio/emscripten/SDL_emscriptenaudio.c index 0be3c69..8d21dab 100644 --- a/SDL2-2.0.12/src/audio/emscripten/SDL_emscriptenaudio.c +++ b/SDL2-2.30.5/src/audio/emscripten/SDL_emscriptenaudio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,21 +20,24 @@ */ #include "../../SDL_internal.h" -#if SDL_AUDIO_DRIVER_EMSCRIPTEN +#ifdef SDL_AUDIO_DRIVER_EMSCRIPTEN #include "SDL_audio.h" -#include "SDL_log.h" #include "../SDL_audio_c.h" #include "SDL_emscriptenaudio.h" -#include "SDL_assert.h" #include -static void -FeedAudioDevice(_THIS, const void *buf, const int buflen) +/* !!! FIXME: this currently expects that the audio callback runs in the main thread, + !!! FIXME: in intervals when the application isn't running, but that may not be + !!! FIXME: true always once pthread support becomes widespread. Revisit this code + !!! FIXME: at some point and see what needs to be done for that! */ + +static void FeedAudioDevice(_THIS, const void *buf, const int buflen) { const int framelen = (SDL_AUDIO_BITSIZE(this->spec.format) / 8) * this->spec.channels; - EM_ASM_ARGS({ + /* *INDENT-OFF* */ /* clang-format off */ + MAIN_THREAD_EM_ASM({ var SDL2 = Module['SDL2']; var numChannels = SDL2.audio.currentOutputBuffer['numberOfChannels']; for (var c = 0; c < numChannels; ++c) { @@ -48,10 +51,10 @@ FeedAudioDevice(_THIS, const void *buf, const int buflen) } } }, buf, buflen / framelen); +/* *INDENT-ON* */ /* clang-format on */ } -static void -HandleAudioProcess(_THIS) +static void HandleAudioProcess(_THIS) { SDL_AudioCallback callback = this->callbackspec.callback; const int stream_len = this->callbackspec.size; @@ -61,15 +64,18 @@ HandleAudioProcess(_THIS) if (this->stream) { SDL_AudioStreamClear(this->stream); } + + SDL_memset(this->work_buffer, this->spec.silence, this->spec.size); + FeedAudioDevice(this, this->work_buffer, this->spec.size); return; } - if (this->stream == NULL) { /* no conversion necessary. */ + if (!this->stream) { /* no conversion necessary. */ SDL_assert(this->spec.size == stream_len); callback(this->callbackspec.userdata, this->work_buffer, stream_len); - } else { /* streaming/converting */ + } else { /* streaming/converting */ int got; - while (SDL_AudioStreamAvailable(this->stream) < ((int) this->spec.size)) { + while (SDL_AudioStreamAvailable(this->stream) < ((int)this->spec.size)) { callback(this->callbackspec.userdata, this->work_buffer, stream_len); if (SDL_AudioStreamPut(this->stream, this->work_buffer, stream_len) == -1) { SDL_AudioStreamClear(this->stream); @@ -88,8 +94,7 @@ HandleAudioProcess(_THIS) FeedAudioDevice(this, this->work_buffer, this->spec.size); } -static void -HandleCaptureProcess(_THIS) +static void HandleCaptureProcess(_THIS) { SDL_AudioCallback callback = this->callbackspec.callback; const int stream_len = this->callbackspec.size; @@ -100,7 +105,8 @@ HandleCaptureProcess(_THIS) return; } - EM_ASM_ARGS({ + /* *INDENT-OFF* */ /* clang-format off */ + MAIN_THREAD_EM_ASM({ var SDL2 = Module['SDL2']; var numChannels = SDL2.capture.currentCaptureBuffer.numberOfChannels; for (var c = 0; c < numChannels; ++c) { @@ -119,14 +125,15 @@ HandleCaptureProcess(_THIS) } } } - }, this->work_buffer, (this->spec.size / sizeof (float)) / this->spec.channels); + }, this->work_buffer, (this->spec.size / sizeof(float)) / this->spec.channels); +/* *INDENT-ON* */ /* clang-format on */ /* okay, we've got an interleaved float32 array in C now. */ - if (this->stream == NULL) { /* no conversion necessary. */ + if (!this->stream) { /* no conversion necessary. */ SDL_assert(this->spec.size == stream_len); callback(this->callbackspec.userdata, this->work_buffer, stream_len); - } else { /* streaming/converting */ + } else { /* streaming/converting */ if (SDL_AudioStreamPut(this->stream, this->work_buffer, this->spec.size) == -1) { SDL_AtomicSet(&this->enabled, 0); } @@ -137,45 +144,40 @@ HandleCaptureProcess(_THIS) if (got != stream_len) { SDL_memset(this->work_buffer, this->callbackspec.silence, stream_len); } - callback(this->callbackspec.userdata, this->work_buffer, stream_len); /* Send it to the app. */ + callback(this->callbackspec.userdata, this->work_buffer, stream_len); /* Send it to the app. */ } } } - -static void -EMSCRIPTENAUDIO_CloseDevice(_THIS) +static void EMSCRIPTENAUDIO_CloseDevice(_THIS) { - EM_ASM_({ + /* *INDENT-OFF* */ /* clang-format off */ + MAIN_THREAD_EM_ASM({ var SDL2 = Module['SDL2']; if ($0) { if (SDL2.capture.silenceTimer !== undefined) { - clearTimeout(SDL2.capture.silenceTimer); + clearInterval(SDL2.capture.silenceTimer); } if (SDL2.capture.stream !== undefined) { var tracks = SDL2.capture.stream.getAudioTracks(); for (var i = 0; i < tracks.length; i++) { SDL2.capture.stream.removeTrack(tracks[i]); } - SDL2.capture.stream = undefined; } if (SDL2.capture.scriptProcessorNode !== undefined) { SDL2.capture.scriptProcessorNode.onaudioprocess = function(audioProcessingEvent) {}; SDL2.capture.scriptProcessorNode.disconnect(); - SDL2.capture.scriptProcessorNode = undefined; } if (SDL2.capture.mediaStreamNode !== undefined) { SDL2.capture.mediaStreamNode.disconnect(); - SDL2.capture.mediaStreamNode = undefined; - } - if (SDL2.capture.silenceBuffer !== undefined) { - SDL2.capture.silenceBuffer = undefined } SDL2.capture = undefined; } else { if (SDL2.audio.scriptProcessorNode != undefined) { SDL2.audio.scriptProcessorNode.disconnect(); - SDL2.audio.scriptProcessorNode = undefined; + } + if (SDL2.audio.silenceTimer !== undefined) { + clearInterval(SDL2.audio.silenceTimer); } SDL2.audio = undefined; } @@ -184,23 +186,26 @@ EMSCRIPTENAUDIO_CloseDevice(_THIS) SDL2.audioContext = undefined; } }, this->iscapture); +/* *INDENT-ON* */ /* clang-format on */ #if 0 /* !!! FIXME: currently not used. Can we move some stuff off the SDL2 namespace? --ryan. */ SDL_free(this->hidden); #endif } -static int -EMSCRIPTENAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) +EM_JS_DEPS(sdlaudio, "$autoResumeAudioContext,$dynCall"); + +static int EMSCRIPTENAUDIO_OpenDevice(_THIS, const char *devname) { - SDL_bool valid_format = SDL_FALSE; SDL_AudioFormat test_format; + SDL_bool iscapture = this->iscapture; int result; /* based on parts of library_sdl.js */ + /* *INDENT-OFF* */ /* clang-format off */ /* create context */ - result = EM_ASM_INT({ + result = MAIN_THREAD_EM_ASM_INT({ if(typeof(Module['SDL2']) === 'undefined') { Module['SDL2'] = {}; } @@ -217,34 +222,40 @@ EMSCRIPTENAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscaptu } else if (typeof(webkitAudioContext) !== 'undefined') { SDL2.audioContext = new webkitAudioContext(); } + if (SDL2.audioContext) { + if ((typeof navigator.userActivation) === 'undefined') { // Firefox doesn't have this (as of August 2023), use autoResumeAudioContext instead. + autoResumeAudioContext(SDL2.audioContext); + } + } } return SDL2.audioContext === undefined ? -1 : 0; }, iscapture); +/* *INDENT-ON* */ /* clang-format on */ + if (result < 0) { return SDL_SetError("Web Audio API is not available!"); } - test_format = SDL_FirstAudioFormat(this->spec.format); - while ((!valid_format) && (test_format)) { + for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) { switch (test_format) { case AUDIO_F32: /* web audio only supports floats */ - this->spec.format = test_format; - - valid_format = SDL_TRUE; break; + default: + continue; } - test_format = SDL_NextAudioFormat(); + break; } - if (!valid_format) { + if (!test_format) { /* Didn't find a compatible format :( */ - return SDL_SetError("No compatible audio format!"); + return SDL_SetError("%s: Unsupported audio format", "emscripten"); } + this->spec.format = test_format; /* Initialize all variables that we clean on shutdown */ #if 0 /* !!! FIXME: currently not used. Can we move some stuff off the SDL2 namespace? --ryan. */ this->hidden = (struct SDL_PrivateAudioData *) - SDL_malloc((sizeof *this->hidden)); + SDL_malloc(sizeof(*this->hidden)); if (this->hidden == NULL) { return SDL_OutOfMemory(); } @@ -253,13 +264,14 @@ EMSCRIPTENAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscaptu this->hidden = (struct SDL_PrivateAudioData *)0x1; /* limit to native freq */ - this->spec.freq = EM_ASM_INT_V({ + this->spec.freq = EM_ASM_INT({ var SDL2 = Module['SDL2']; return SDL2.audioContext.sampleRate; }); SDL_CalculateAudioSpec(&this->spec); + /* *INDENT-OFF* */ /* clang-format off */ if (iscapture) { /* The idea is to take the capture media stream, hook it up to an audio graph where we can pass it through a ScriptProcessorNode @@ -277,13 +289,14 @@ EMSCRIPTENAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscaptu feels like it's a pretty inefficient tapdance in similar ways, to be honest. */ - EM_ASM_({ + MAIN_THREAD_EM_ASM({ var SDL2 = Module['SDL2']; var have_microphone = function(stream) { //console.log('SDL audio capture: we have a microphone! Replacing silence callback.'); if (SDL2.capture.silenceTimer !== undefined) { - clearTimeout(SDL2.capture.silenceTimer); + clearInterval(SDL2.capture.silenceTimer); SDL2.capture.silenceTimer = undefined; + SDL2.capture.silenceBuffer = undefined } SDL2.capture.mediaStreamNode = SDL2.audioContext.createMediaStreamSource(stream); SDL2.capture.scriptProcessorNode = SDL2.audioContext.createScriptProcessor($1, $0, 1); @@ -310,7 +323,7 @@ EMSCRIPTENAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscaptu dynCall('vi', $2, [$3]); }; - SDL2.capture.silenceTimer = setTimeout(silence_callback, ($1 / SDL2.audioContext.sampleRate) * 1000); + SDL2.capture.silenceTimer = setInterval(silence_callback, ($1 / SDL2.audioContext.sampleRate) * 1000); if ((navigator.mediaDevices !== undefined) && (navigator.mediaDevices.getUserMedia !== undefined)) { navigator.mediaDevices.getUserMedia({ audio: true, video: false }).then(have_microphone).catch(no_microphone); @@ -320,59 +333,93 @@ EMSCRIPTENAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscaptu }, this->spec.channels, this->spec.samples, HandleCaptureProcess, this); } else { /* setup a ScriptProcessorNode */ - EM_ASM_ARGS({ + MAIN_THREAD_EM_ASM({ var SDL2 = Module['SDL2']; SDL2.audio.scriptProcessorNode = SDL2.audioContext['createScriptProcessor']($1, 0, $0); SDL2.audio.scriptProcessorNode['onaudioprocess'] = function (e) { if ((SDL2 === undefined) || (SDL2.audio === undefined)) { return; } + // if we're actually running the node, we don't need the fake callback anymore, so kill it. + if (SDL2.audio.silenceTimer !== undefined) { + clearInterval(SDL2.audio.silenceTimer); + SDL2.audio.silenceTimer = undefined; + SDL2.audio.silenceBuffer = undefined; + } SDL2.audio.currentOutputBuffer = e['outputBuffer']; dynCall('vi', $2, [$3]); }; + SDL2.audio.scriptProcessorNode['connect'](SDL2.audioContext['destination']); + + if (SDL2.audioContext.state === 'suspended') { // uhoh, autoplay is blocked. + SDL2.audio.silenceBuffer = SDL2.audioContext.createBuffer($0, $1, SDL2.audioContext.sampleRate); + SDL2.audio.silenceBuffer.getChannelData(0).fill(0.0); + var silence_callback = function() { + if ((typeof navigator.userActivation) !== 'undefined') { // Almost everything modern except Firefox (as of August 2023) + if (navigator.userActivation.hasBeenActive) { + SDL2.audioContext.resume(); + } + } + + // the buffer that gets filled here just gets ignored, so the app can make progress + // and/or avoid flooding audio queues until we can actually play audio. + SDL2.audio.currentOutputBuffer = SDL2.audio.silenceBuffer; + dynCall('vi', $2, [$3]); + SDL2.audio.currentOutputBuffer = undefined; + }; + + SDL2.audio.silenceTimer = setInterval(silence_callback, ($1 / SDL2.audioContext.sampleRate) * 1000); + } }, this->spec.channels, this->spec.samples, HandleAudioProcess, this); } +/* *INDENT-ON* */ /* clang-format on */ return 0; } -static int -EMSCRIPTENAUDIO_Init(SDL_AudioDriverImpl * impl) +static void EMSCRIPTENAUDIO_LockOrUnlockDeviceWithNoMixerLock(SDL_AudioDevice *device) { - int available; - int capture_available; +} + +static SDL_bool EMSCRIPTENAUDIO_Init(SDL_AudioDriverImpl *impl) +{ + SDL_bool available, capture_available; /* Set the function pointers */ impl->OpenDevice = EMSCRIPTENAUDIO_OpenDevice; impl->CloseDevice = EMSCRIPTENAUDIO_CloseDevice; - impl->OnlyHasDefaultOutputDevice = 1; + impl->OnlyHasDefaultOutputDevice = SDL_TRUE; /* no threads here */ - impl->SkipMixerLock = 1; - impl->ProvidesOwnCallbackThread = 1; + impl->LockDevice = impl->UnlockDevice = EMSCRIPTENAUDIO_LockOrUnlockDeviceWithNoMixerLock; + impl->ProvidesOwnCallbackThread = SDL_TRUE; + /* *INDENT-OFF* */ /* clang-format off */ /* check availability */ - available = EM_ASM_INT_V({ + available = MAIN_THREAD_EM_ASM_INT({ if (typeof(AudioContext) !== 'undefined') { - return 1; + return true; } else if (typeof(webkitAudioContext) !== 'undefined') { - return 1; + return true; } - return 0; + return false; }); +/* *INDENT-ON* */ /* clang-format on */ if (!available) { SDL_SetError("No audio context available"); } - capture_available = available && EM_ASM_INT_V({ + /* *INDENT-OFF* */ /* clang-format off */ + capture_available = available && MAIN_THREAD_EM_ASM_INT({ if ((typeof(navigator.mediaDevices) !== 'undefined') && (typeof(navigator.mediaDevices.getUserMedia) !== 'undefined')) { - return 1; + return true; } else if (typeof(navigator.webkitGetUserMedia) !== 'undefined') { - return 1; + return true; } - return 0; + return false; }); +/* *INDENT-ON* */ /* clang-format on */ impl->HasCaptureSupport = capture_available ? SDL_TRUE : SDL_FALSE; impl->OnlyHasDefaultCaptureDevice = capture_available ? SDL_TRUE : SDL_FALSE; @@ -381,7 +428,7 @@ EMSCRIPTENAUDIO_Init(SDL_AudioDriverImpl * impl) } AudioBootStrap EMSCRIPTENAUDIO_bootstrap = { - "emscripten", "SDL emscripten audio driver", EMSCRIPTENAUDIO_Init, 0 + "emscripten", "SDL emscripten audio driver", EMSCRIPTENAUDIO_Init, SDL_FALSE }; #endif /* SDL_AUDIO_DRIVER_EMSCRIPTEN */ diff --git a/SDL2-2.0.12/src/audio/emscripten/SDL_emscriptenaudio.h b/SDL2-2.30.5/src/audio/emscripten/SDL_emscriptenaudio.h similarity index 92% rename from SDL2-2.0.12/src/audio/emscripten/SDL_emscriptenaudio.h rename to SDL2-2.30.5/src/audio/emscripten/SDL_emscriptenaudio.h index 2048f25..54f6057 100644 --- a/SDL2-2.0.12/src/audio/emscripten/SDL_emscriptenaudio.h +++ b/SDL2-2.30.5/src/audio/emscripten/SDL_emscriptenaudio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,7 +26,7 @@ #include "../SDL_sysaudio.h" /* Hidden "this" pointer for the audio functions */ -#define _THIS SDL_AudioDevice *this +#define _THIS SDL_AudioDevice *this struct SDL_PrivateAudioData { diff --git a/SDL2-2.0.12/src/audio/esd/SDL_esdaudio.c b/SDL2-2.30.5/src/audio/esd/SDL_esdaudio.c similarity index 88% rename from SDL2-2.0.12/src/audio/esd/SDL_esdaudio.c rename to SDL2-2.30.5/src/audio/esd/SDL_esdaudio.c index 400f653..596f51a 100644 --- a/SDL2-2.0.12/src/audio/esd/SDL_esdaudio.c +++ b/SDL2-2.30.5/src/audio/esd/SDL_esdaudio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_AUDIO_DRIVER_ESD +#ifdef SDL_AUDIO_DRIVER_ESD /* Allow access to an ESD network stream mixing buffer */ @@ -64,21 +64,19 @@ static struct #undef SDL_ESD_SYM -static void -UnloadESDLibrary() +static void UnloadESDLibrary() { - if (esd_handle != NULL) { + if (esd_handle) { SDL_UnloadObject(esd_handle); esd_handle = NULL; } } -static int -LoadESDLibrary(void) +static int LoadESDLibrary(void) { int i, retval = -1; - if (esd_handle == NULL) { + if (!esd_handle) { esd_handle = SDL_LoadObject(esd_library); if (esd_handle) { retval = 0; @@ -98,14 +96,12 @@ LoadESDLibrary(void) #else -static void -UnloadESDLibrary() +static void UnloadESDLibrary() { return; } -static int -LoadESDLibrary(void) +static int LoadESDLibrary(void) { return 0; } @@ -114,8 +110,7 @@ LoadESDLibrary(void) /* This function waits until it is possible to write a full sound buffer */ -static void -ESD_WaitDevice(_THIS) +static void ESD_WaitDevice(_THIS) { Sint32 ticks; @@ -140,8 +135,7 @@ ESD_WaitDevice(_THIS) } } -static void -ESD_PlayDevice(_THIS) +static void ESD_PlayDevice(_THIS) { int written = 0; @@ -164,14 +158,12 @@ ESD_PlayDevice(_THIS) } } -static Uint8 * -ESD_GetDeviceBuf(_THIS) +static Uint8 *ESD_GetDeviceBuf(_THIS) { return (this->hidden->mixbuf); } -static void -ESD_CloseDevice(_THIS) +static void ESD_CloseDevice(_THIS) { if (this->hidden->audio_fd >= 0) { SDL_NAME(esd_close) (this->hidden->audio_fd); @@ -181,8 +173,7 @@ ESD_CloseDevice(_THIS) } /* Try to get the name of the program */ -static char * -get_progname(void) +static char *get_progname(void) { char *progname = NULL; #ifdef __LINUX__ @@ -194,7 +185,7 @@ get_progname(void) if (fp != NULL) { if (fgets(temp, sizeof(temp) - 1, fp)) { progname = SDL_strrchr(temp, '/'); - if (progname == NULL) { + if (!progname) { progname = temp; } else { progname = progname + 1; @@ -207,17 +198,15 @@ get_progname(void) } -static int -ESD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) +static int ESD_OpenDevice(_THIS, const char *devname) { esd_format_t format = (ESD_STREAM | ESD_PLAY); SDL_AudioFormat test_format = 0; int found = 0; /* Initialize all variables that we clean on shutdown */ - this->hidden = (struct SDL_PrivateAudioData *) - SDL_malloc((sizeof *this->hidden)); - if (this->hidden == NULL) { + this->hidden = (struct SDL_PrivateAudioData *)SDL_malloc(sizeof(*this->hidden)); + if (!this->hidden) { return SDL_OutOfMemory(); } SDL_zerop(this->hidden); @@ -275,7 +264,7 @@ ESD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) /* Allocate mixing buffer */ this->hidden->mixlen = this->spec.size; this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen); - if (this->hidden->mixbuf == NULL) { + if (!this->hidden->mixbuf) { return SDL_OutOfMemory(); } SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size); @@ -287,17 +276,15 @@ ESD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) return 0; } -static void -ESD_Deinitialize(void) +static void ESD_Deinitialize(void) { UnloadESDLibrary(); } -static int -ESD_Init(SDL_AudioDriverImpl * impl) +static SDL_bool ESD_Init(SDL_AudioDriverImpl * impl) { if (LoadESDLibrary() < 0) { - return 0; + return SDL_FALSE; } else { int connection = 0; @@ -308,7 +295,7 @@ ESD_Init(SDL_AudioDriverImpl * impl) if (connection < 0) { UnloadESDLibrary(); SDL_SetError("ESD: esd_open_sound failed (no audio server?)"); - return 0; + return SDL_FALSE; } SDL_NAME(esd_close) (connection); } @@ -320,14 +307,14 @@ ESD_Init(SDL_AudioDriverImpl * impl) impl->GetDeviceBuf = ESD_GetDeviceBuf; impl->CloseDevice = ESD_CloseDevice; impl->Deinitialize = ESD_Deinitialize; - impl->OnlyHasDefaultOutputDevice = 1; + impl->OnlyHasDefaultOutputDevice = SDL_TRUE; - return 1; /* this audio target is available. */ + return SDL_TRUE; /* this audio target is available. */ } AudioBootStrap ESD_bootstrap = { - "esd", "Enlightened Sound Daemon", ESD_Init, 0 + "esd", "Enlightened Sound Daemon", ESD_Init, SDL_FALSE }; #endif /* SDL_AUDIO_DRIVER_ESD */ diff --git a/SDL2-2.0.12/src/audio/esd/SDL_esdaudio.h b/SDL2-2.30.5/src/audio/esd/SDL_esdaudio.h similarity index 96% rename from SDL2-2.0.12/src/audio/esd/SDL_esdaudio.h rename to SDL2-2.30.5/src/audio/esd/SDL_esdaudio.h index b7bb06a..15e3d4e 100644 --- a/SDL2-2.0.12/src/audio/esd/SDL_esdaudio.h +++ b/SDL2-2.30.5/src/audio/esd/SDL_esdaudio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/audio/fusionsound/SDL_fsaudio.c b/SDL2-2.30.5/src/audio/fusionsound/SDL_fsaudio.c similarity index 81% rename from SDL2-2.0.12/src/audio/fusionsound/SDL_fsaudio.c rename to SDL2-2.30.5/src/audio/fusionsound/SDL_fsaudio.c index 262388e..5abab2e 100644 --- a/SDL2-2.0.12/src/audio/fusionsound/SDL_fsaudio.c +++ b/SDL2-2.30.5/src/audio/fusionsound/SDL_fsaudio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_AUDIO_DRIVER_FUSIONSOUND +#ifdef SDL_AUDIO_DRIVER_FUSIONSOUND /* !!! FIXME: why is this is SDL_FS_* instead of FUSIONSOUND_*? */ @@ -77,23 +77,21 @@ static struct #undef SDL_FS_SYM -static void -UnloadFusionSoundLibrary() +static void UnloadFusionSoundLibrary() { - if (fs_handle != NULL) { + if (fs_handle) { SDL_UnloadObject(fs_handle); fs_handle = NULL; } } -static int -LoadFusionSoundLibrary(void) +static int LoadFusionSoundLibrary(void) { int i, retval = -1; - if (fs_handle == NULL) { + if (!fs_handle) { fs_handle = SDL_LoadObject(fs_library); - if (fs_handle != NULL) { + if (fs_handle) { retval = 0; for (i = 0; i < SDL_arraysize(fs_functions); ++i) { *fs_functions[i].func = @@ -112,14 +110,12 @@ LoadFusionSoundLibrary(void) #else -static void -UnloadFusionSoundLibrary() +static void UnloadFusionSoundLibrary() { return; } -static int -LoadFusionSoundLibrary(void) +static int LoadFusionSoundLibrary(void) { return 0; } @@ -127,15 +123,13 @@ LoadFusionSoundLibrary(void) #endif /* SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC */ /* This function waits until it is possible to write a full sound buffer */ -static void -SDL_FS_WaitDevice(_THIS) +static void SDL_FS_WaitDevice(_THIS) { this->hidden->stream->Wait(this->hidden->stream, this->hidden->mixsamples); } -static void -SDL_FS_PlayDevice(_THIS) +static void SDL_FS_PlayDevice(_THIS) { DirectResult ret; @@ -152,15 +146,13 @@ SDL_FS_PlayDevice(_THIS) } -static Uint8 * -SDL_FS_GetDeviceBuf(_THIS) +static Uint8 *SDL_FS_GetDeviceBuf(_THIS) { return (this->hidden->mixbuf); } -static void -SDL_FS_CloseDevice(_THIS) +static void SDL_FS_CloseDevice(_THIS) { if (this->hidden->stream) { this->hidden->stream->Release(this->hidden->stream); @@ -173,63 +165,50 @@ SDL_FS_CloseDevice(_THIS) } -static int -SDL_FS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) +static int SDL_FS_OpenDevice(_THIS, const char *devname) { int bytes; - SDL_AudioFormat test_format = 0, format = 0; + SDL_AudioFormat test_format; FSSampleFormat fs_format; FSStreamDescription desc; DirectResult ret; /* Initialize all variables that we clean on shutdown */ - this->hidden = (struct SDL_PrivateAudioData *) - SDL_malloc((sizeof *this->hidden)); - if (this->hidden == NULL) { + this->hidden = (struct SDL_PrivateAudioData *)SDL_malloc(sizeof(*this->hidden)); + if (!this->hidden) { return SDL_OutOfMemory(); } SDL_zerop(this->hidden); /* Try for a closest match on audio format */ - for (test_format = SDL_FirstAudioFormat(this->spec.format); - !format && test_format;) { + for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) { #ifdef DEBUG_AUDIO fprintf(stderr, "Trying format 0x%4.4x\n", test_format); #endif switch (test_format) { case AUDIO_U8: fs_format = FSSF_U8; - bytes = 1; - format = 1; break; case AUDIO_S16SYS: fs_format = FSSF_S16; - bytes = 2; - format = 1; break; case AUDIO_S32SYS: fs_format = FSSF_S32; - bytes = 4; - format = 1; break; case AUDIO_F32SYS: fs_format = FSSF_FLOAT; - bytes = 4; - format = 1; break; default: - format = 0; - break; - } - if (!format) { - test_format = SDL_NextAudioFormat(); + continue; } + break; } - if (format == 0) { - return SDL_SetError("Couldn't find any hardware audio formats"); + if (!test_format) { + return SDL_SetError("%s: Unsupported audio format", "fusionsound"); } this->spec.format = test_format; + bytes = SDL_AUDIO_BITSIZE(test_format) / 8; /* Retrieve the main sound interface. */ ret = SDL_NAME(FusionSoundCreate) (&this->hidden->fs); @@ -271,7 +250,7 @@ SDL_FS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) /* Allocate mixing buffer */ this->hidden->mixlen = this->spec.size; this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen); - if (this->hidden->mixbuf == NULL) { + if (!this->hidden->mixbuf) { return SDL_OutOfMemory(); } SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size); @@ -281,18 +260,16 @@ SDL_FS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) } -static void -SDL_FS_Deinitialize(void) +static void SDL_FS_Deinitialize(void) { UnloadFusionSoundLibrary(); } -static int -SDL_FS_Init(SDL_AudioDriverImpl * impl) +static SDL_bool SDL_FS_Init(SDL_AudioDriverImpl * impl) { if (LoadFusionSoundLibrary() < 0) { - return 0; + return SDL_FALSE; } else { DirectResult ret; @@ -302,7 +279,7 @@ SDL_FS_Init(SDL_AudioDriverImpl * impl) SDL_SetError ("FusionSound: SDL_FS_init failed (FusionSoundInit: %d)", ret); - return 0; + return SDL_FALSE; } } @@ -313,14 +290,14 @@ SDL_FS_Init(SDL_AudioDriverImpl * impl) impl->GetDeviceBuf = SDL_FS_GetDeviceBuf; impl->CloseDevice = SDL_FS_CloseDevice; impl->Deinitialize = SDL_FS_Deinitialize; - impl->OnlyHasDefaultOutputDevice = 1; + impl->OnlyHasDefaultOutputDevice = SDL_TRUE; - return 1; /* this audio target is available. */ + return SDL_TRUE; /* this audio target is available. */ } AudioBootStrap FUSIONSOUND_bootstrap = { - "fusionsound", "FusionSound", SDL_FS_Init, 0 + "fusionsound", "FusionSound", SDL_FS_Init, SDL_FALSE }; #endif /* SDL_AUDIO_DRIVER_FUSIONSOUND */ diff --git a/SDL2-2.0.12/src/audio/fusionsound/SDL_fsaudio.h b/SDL2-2.30.5/src/audio/fusionsound/SDL_fsaudio.h similarity index 95% rename from SDL2-2.0.12/src/audio/fusionsound/SDL_fsaudio.h rename to SDL2-2.30.5/src/audio/fusionsound/SDL_fsaudio.h index 90a4642..556ea54 100644 --- a/SDL2-2.0.12/src/audio/fusionsound/SDL_fsaudio.h +++ b/SDL2-2.30.5/src/audio/fusionsound/SDL_fsaudio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/audio/haiku/SDL_haikuaudio.cc b/SDL2-2.30.5/src/audio/haiku/SDL_haikuaudio.cc similarity index 70% rename from SDL2-2.0.12/src/audio/haiku/SDL_haikuaudio.cc rename to SDL2-2.30.5/src/audio/haiku/SDL_haikuaudio.cc index 5fdb4cc..39b8d8c 100644 --- a/SDL2-2.0.12/src/audio/haiku/SDL_haikuaudio.cc +++ b/SDL2-2.30.5/src/audio/haiku/SDL_haikuaudio.cc @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_AUDIO_DRIVER_HAIKU +#ifdef SDL_AUDIO_DRIVER_HAIKU /* Allow access to the audio stream on Haiku */ @@ -36,57 +36,55 @@ extern "C" #include "../SDL_audio_c.h" #include "../SDL_sysaudio.h" #include "SDL_haikuaudio.h" -#include "SDL_assert.h" } /* !!! FIXME: have the callback call the higher level to avoid code dupe. */ /* The Haiku callback for handling the audio buffer */ -static void -FillSound(void *device, void *stream, size_t len, +static void FillSound(void *device, void *stream, size_t len, const media_raw_audio_format & format) { SDL_AudioDevice *audio = (SDL_AudioDevice *) device; SDL_AudioCallback callback = audio->callbackspec.callback; + SDL_LockMutex(audio->mixer_lock); + /* Only do something if audio is enabled */ if (!SDL_AtomicGet(&audio->enabled) || SDL_AtomicGet(&audio->paused)) { if (audio->stream) { SDL_AudioStreamClear(audio->stream); } SDL_memset(stream, audio->spec.silence, len); - return; - } + } else { + SDL_assert(audio->spec.size == len); - SDL_assert(audio->spec.size == len); + if (!audio->stream) { /* no conversion necessary. */ + callback(audio->callbackspec.userdata, (Uint8 *) stream, len); + } else { /* streaming/converting */ + const int stream_len = audio->callbackspec.size; + const int ilen = (int) len; + while (SDL_AudioStreamAvailable(audio->stream) < ilen) { + callback(audio->callbackspec.userdata, audio->work_buffer, stream_len); + if (SDL_AudioStreamPut(audio->stream, audio->work_buffer, stream_len) == -1) { + SDL_AudioStreamClear(audio->stream); + SDL_AtomicSet(&audio->enabled, 0); + break; + } + } - if (audio->stream == NULL) { /* no conversion necessary. */ - SDL_LockMutex(audio->mixer_lock); - callback(audio->callbackspec.userdata, (Uint8 *) stream, len); - SDL_UnlockMutex(audio->mixer_lock); - } else { /* streaming/converting */ - const int stream_len = audio->callbackspec.size; - const int ilen = (int) len; - while (SDL_AudioStreamAvailable(audio->stream) < ilen) { - callback(audio->callbackspec.userdata, audio->work_buffer, stream_len); - if (SDL_AudioStreamPut(audio->stream, audio->work_buffer, stream_len) == -1) { - SDL_AudioStreamClear(audio->stream); - SDL_AtomicSet(&audio->enabled, 0); - break; + const int got = SDL_AudioStreamGet(audio->stream, stream, ilen); + SDL_assert((got < 0) || (got == ilen)); + if (got != ilen) { + SDL_memset(stream, audio->spec.silence, len); } } - - const int got = SDL_AudioStreamGet(audio->stream, stream, ilen); - SDL_assert((got < 0) || (got == ilen)); - if (got != ilen) { - SDL_memset(stream, audio->spec.silence, len); - } } + + SDL_UnlockMutex(audio->mixer_lock); } -static void -HAIKUAUDIO_CloseDevice(_THIS) +static void HAIKUAUDIO_CloseDevice(_THIS) { if (_this->hidden->audio_obj) { _this->hidden->audio_obj->Stop(); @@ -100,8 +98,7 @@ static const int sig_list[] = { SIGHUP, SIGINT, SIGQUIT, SIGPIPE, SIGALRM, SIGTERM, SIGWINCH, 0 }; -static inline void -MaskSignals(sigset_t * omask) +static inline void MaskSignals(sigset_t * omask) { sigset_t mask; int i; @@ -113,19 +110,16 @@ MaskSignals(sigset_t * omask) sigprocmask(SIG_BLOCK, &mask, omask); } -static inline void -UnmaskSignals(sigset_t * omask) +static inline void UnmaskSignals(sigset_t * omask) { sigprocmask(SIG_SETMASK, omask, NULL); } -static int -HAIKUAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) +static int HAIKUAUDIO_OpenDevice(_THIS, const char *devname) { - int valid_datatype = 0; media_raw_audio_format format; - SDL_AudioFormat test_format = SDL_FirstAudioFormat(_this->spec.format); + SDL_AudioFormat test_format; /* Initialize all variables that we clean on shutdown */ _this->hidden = new SDL_PrivateAudioData; @@ -139,9 +133,7 @@ HAIKUAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) format.byte_order = B_MEDIA_LITTLE_ENDIAN; format.frame_rate = (float) _this->spec.freq; format.channel_count = _this->spec.channels; /* !!! FIXME: support > 2? */ - while ((!valid_datatype) && (test_format)) { - valid_datatype = 1; - _this->spec.format = test_format; + for (test_format = SDL_FirstAudioFormat(_this->spec.format); test_format; test_format = SDL_NextAudioFormat()) { switch (test_format) { case AUDIO_S8: format.format = media_raw_audio_format::B_AUDIO_CHAR; @@ -179,15 +171,15 @@ HAIKUAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) break; default: - valid_datatype = 0; - test_format = SDL_NextAudioFormat(); - break; + continue; } + break; } - if (!valid_datatype) { /* shouldn't happen, but just in case... */ - return SDL_SetError("Unsupported audio format"); + if (!test_format) { /* shouldn't happen, but just in case... */ + return SDL_SetError("%s: Unsupported audio format", "haiku"); } + _this->spec.format = test_format; /* Calculate the final parameters for this audio specification */ SDL_CalculateAudioSpec(&_this->spec); @@ -211,28 +203,26 @@ HAIKUAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) return 0; } -static void -HAIKUAUDIO_Deinitialize(void) +static void HAIKUAUDIO_Deinitialize(void) { SDL_QuitBeApp(); } -static int -HAIKUAUDIO_Init(SDL_AudioDriverImpl * impl) +static SDL_bool HAIKUAUDIO_Init(SDL_AudioDriverImpl * impl) { /* Initialize the Be Application, if it's not already started */ if (SDL_InitBeApp() < 0) { - return 0; + return SDL_FALSE; } /* Set the function pointers */ impl->OpenDevice = HAIKUAUDIO_OpenDevice; impl->CloseDevice = HAIKUAUDIO_CloseDevice; impl->Deinitialize = HAIKUAUDIO_Deinitialize; - impl->ProvidesOwnCallbackThread = 1; - impl->OnlyHasDefaultOutputDevice = 1; + impl->ProvidesOwnCallbackThread = SDL_TRUE; + impl->OnlyHasDefaultOutputDevice = SDL_TRUE; - return 1; /* this audio target is available. */ + return SDL_TRUE; /* this audio target is available. */ } extern "C" @@ -240,7 +230,7 @@ extern "C" extern AudioBootStrap HAIKUAUDIO_bootstrap; } AudioBootStrap HAIKUAUDIO_bootstrap = { - "haiku", "Haiku BSoundPlayer", HAIKUAUDIO_Init, 0 + "haiku", "Haiku BSoundPlayer", HAIKUAUDIO_Init, SDL_FALSE }; #endif /* SDL_AUDIO_DRIVER_HAIKU */ diff --git a/SDL2-2.0.12/src/audio/haiku/SDL_haikuaudio.h b/SDL2-2.30.5/src/audio/haiku/SDL_haikuaudio.h similarity index 92% rename from SDL2-2.0.12/src/audio/haiku/SDL_haikuaudio.h rename to SDL2-2.30.5/src/audio/haiku/SDL_haikuaudio.h index 1623cef..9acb6e1 100644 --- a/SDL2-2.0.12/src/audio/haiku/SDL_haikuaudio.h +++ b/SDL2-2.30.5/src/audio/haiku/SDL_haikuaudio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,7 +26,7 @@ #include "../SDL_sysaudio.h" /* Hidden "this" pointer for the audio functions */ -#define _THIS SDL_AudioDevice *_this +#define _THIS SDL_AudioDevice *_this struct SDL_PrivateAudioData { diff --git a/SDL2-2.0.12/src/audio/jack/SDL_jackaudio.c b/SDL2-2.30.5/src/audio/jack/SDL_jackaudio.c similarity index 68% rename from SDL2-2.0.12/src/audio/jack/SDL_jackaudio.c rename to SDL2-2.30.5/src/audio/jack/SDL_jackaudio.c index 55c162d..9be8799 100644 --- a/SDL2-2.0.12/src/audio/jack/SDL_jackaudio.c +++ b/SDL2-2.30.5/src/audio/jack/SDL_jackaudio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -18,12 +18,10 @@ misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ - #include "../../SDL_internal.h" -#if SDL_AUDIO_DRIVER_JACK +#ifdef SDL_AUDIO_DRIVER_JACK -#include "SDL_assert.h" #include "SDL_timer.h" #include "SDL_audio.h" #include "../SDL_audio_c.h" @@ -31,39 +29,36 @@ #include "SDL_loadso.h" #include "../../thread/SDL_systhread.h" - -static jack_client_t * (*JACK_jack_client_open) (const char *, jack_options_t, jack_status_t *, ...); -static int (*JACK_jack_client_close) (jack_client_t *); -static void (*JACK_jack_on_shutdown) (jack_client_t *, JackShutdownCallback, void *); -static int (*JACK_jack_activate) (jack_client_t *); -static int (*JACK_jack_deactivate) (jack_client_t *); -static void * (*JACK_jack_port_get_buffer) (jack_port_t *, jack_nframes_t); -static int (*JACK_jack_port_unregister) (jack_client_t *, jack_port_t *); -static void (*JACK_jack_free) (void *); -static const char ** (*JACK_jack_get_ports) (jack_client_t *, const char *, const char *, unsigned long); -static jack_nframes_t (*JACK_jack_get_sample_rate) (jack_client_t *); -static jack_nframes_t (*JACK_jack_get_buffer_size) (jack_client_t *); -static jack_port_t * (*JACK_jack_port_register) (jack_client_t *, const char *, const char *, unsigned long, unsigned long); -static jack_port_t * (*JACK_jack_port_by_name) (jack_client_t *, const char *); -static const char * (*JACK_jack_port_name) (const jack_port_t *); -static const char * (*JACK_jack_port_type) (const jack_port_t *); -static int (*JACK_jack_connect) (jack_client_t *, const char *, const char *); -static int (*JACK_jack_set_process_callback) (jack_client_t *, JackProcessCallback, void *); +static jack_client_t *(*JACK_jack_client_open)(const char *, jack_options_t, jack_status_t *, ...); +static int (*JACK_jack_client_close)(jack_client_t *); +static void (*JACK_jack_on_shutdown)(jack_client_t *, JackShutdownCallback, void *); +static int (*JACK_jack_activate)(jack_client_t *); +static int (*JACK_jack_deactivate)(jack_client_t *); +static void *(*JACK_jack_port_get_buffer)(jack_port_t *, jack_nframes_t); +static int (*JACK_jack_port_unregister)(jack_client_t *, jack_port_t *); +static void (*JACK_jack_free)(void *); +static const char **(*JACK_jack_get_ports)(jack_client_t *, const char *, const char *, unsigned long); +static jack_nframes_t (*JACK_jack_get_sample_rate)(jack_client_t *); +static jack_nframes_t (*JACK_jack_get_buffer_size)(jack_client_t *); +static jack_port_t *(*JACK_jack_port_register)(jack_client_t *, const char *, const char *, unsigned long, unsigned long); +static jack_port_t *(*JACK_jack_port_by_name)(jack_client_t *, const char *); +static const char *(*JACK_jack_port_name)(const jack_port_t *); +static const char *(*JACK_jack_port_type)(const jack_port_t *); +static int (*JACK_jack_connect)(jack_client_t *, const char *, const char *); +static int (*JACK_jack_set_process_callback)(jack_client_t *, JackProcessCallback, void *); static int load_jack_syms(void); - #ifdef SDL_AUDIO_DRIVER_JACK_DYNAMIC static const char *jack_library = SDL_AUDIO_DRIVER_JACK_DYNAMIC; static void *jack_handle = NULL; /* !!! FIXME: this is copy/pasted in several places now */ -static int -load_jack_sym(const char *fn, void **addr) +static int load_jack_sym(const char *fn, void **addr) { *addr = SDL_LoadFunction(jack_handle, fn); - if (*addr == NULL) { + if (!*addr) { /* Don't call SDL_SetError(): SDL_LoadFunction already did. */ return 0; } @@ -72,25 +67,24 @@ load_jack_sym(const char *fn, void **addr) } /* cast funcs to char* first, to please GCC's strict aliasing rules. */ -#define SDL_JACK_SYM(x) \ - if (!load_jack_sym(#x, (void **) (char *) &JACK_##x)) return -1 +#define SDL_JACK_SYM(x) \ + if (!load_jack_sym(#x, (void **)(char *)&JACK_##x)) \ + return -1 -static void -UnloadJackLibrary(void) +static void UnloadJackLibrary(void) { - if (jack_handle != NULL) { + if (jack_handle) { SDL_UnloadObject(jack_handle); jack_handle = NULL; } } -static int -LoadJackLibrary(void) +static int LoadJackLibrary(void) { int retval = 0; - if (jack_handle == NULL) { + if (!jack_handle) { jack_handle = SDL_LoadObject(jack_library); - if (jack_handle == NULL) { + if (!jack_handle) { retval = -1; /* Don't call SDL_SetError(): SDL_LoadObject already did. */ } else { @@ -107,13 +101,11 @@ LoadJackLibrary(void) #define SDL_JACK_SYM(x) JACK_##x = x -static void -UnloadJackLibrary(void) +static void UnloadJackLibrary(void) { } -static int -LoadJackLibrary(void) +static int LoadJackLibrary(void) { load_jack_syms(); return 0; @@ -121,9 +113,7 @@ LoadJackLibrary(void) #endif /* SDL_AUDIO_DRIVER_JACK_DYNAMIC */ - -static int -load_jack_syms(void) +static int load_jack_syms(void) { SDL_JACK_SYM(jack_client_open); SDL_JACK_SYM(jack_client_close); @@ -142,26 +132,24 @@ load_jack_syms(void) SDL_JACK_SYM(jack_port_type); SDL_JACK_SYM(jack_connect); SDL_JACK_SYM(jack_set_process_callback); + return 0; } - -static void -jackShutdownCallback(void *arg) /* JACK went away; device is lost. */ +static void jackShutdownCallback(void *arg) /* JACK went away; device is lost. */ { - SDL_AudioDevice *this = (SDL_AudioDevice *) arg; + SDL_AudioDevice *this = (SDL_AudioDevice *)arg; SDL_OpenedAudioDeviceDisconnected(this); - SDL_SemPost(this->hidden->iosem); /* unblock the SDL thread. */ + SDL_SemPost(this->hidden->iosem); /* unblock the SDL thread. */ } // !!! FIXME: implement and register these! -//typedef int(* JackSampleRateCallback)(jack_nframes_t nframes, void *arg) -//typedef int(* JackBufferSizeCallback)(jack_nframes_t nframes, void *arg) +// typedef int(* JackSampleRateCallback)(jack_nframes_t nframes, void *arg) +// typedef int(* JackBufferSizeCallback)(jack_nframes_t nframes, void *arg) -static int -jackProcessPlaybackCallback(jack_nframes_t nframes, void *arg) +static int jackProcessPlaybackCallback(jack_nframes_t nframes, void *arg) { - SDL_AudioDevice *this = (SDL_AudioDevice *) arg; + SDL_AudioDevice *this = (SDL_AudioDevice *)arg; jack_port_t **ports = this->hidden->sdlports; const int total_channels = this->spec.channels; const int total_frames = this->spec.samples; @@ -173,9 +161,9 @@ jackProcessPlaybackCallback(jack_nframes_t nframes, void *arg) } for (channelsi = 0; channelsi < total_channels; channelsi++) { - float *dst = (float *) JACK_jack_port_get_buffer(ports[channelsi], nframes); + float *dst = (float *)JACK_jack_port_get_buffer(ports[channelsi], nframes); if (dst) { - const float *src = ((float *) this->hidden->iobuffer) + channelsi; + const float *src = this->hidden->iobuffer + channelsi; int framesi; for (framesi = 0; framesi < total_frames; framesi++) { *(dst++) = *src; @@ -184,14 +172,12 @@ jackProcessPlaybackCallback(jack_nframes_t nframes, void *arg) } } - SDL_SemPost(this->hidden->iosem); /* tell SDL thread we're done; refill the buffer. */ - return 0; /* success */ + SDL_SemPost(this->hidden->iosem); /* tell SDL thread we're done; refill the buffer. */ + return 0; } - /* This function waits until it is possible to write a full sound buffer */ -static void -JACK_WaitDevice(_THIS) +static void JACK_WaitDevice(_THIS) { if (SDL_AtomicGet(&this->enabled)) { if (SDL_SemWait(this->hidden->iosem) == -1) { @@ -200,27 +186,24 @@ JACK_WaitDevice(_THIS) } } -static Uint8 * -JACK_GetDeviceBuf(_THIS) +static Uint8 *JACK_GetDeviceBuf(_THIS) { - return (Uint8 *) this->hidden->iobuffer; + return (Uint8 *)this->hidden->iobuffer; } - -static int -jackProcessCaptureCallback(jack_nframes_t nframes, void *arg) +static int jackProcessCaptureCallback(jack_nframes_t nframes, void *arg) { - SDL_AudioDevice *this = (SDL_AudioDevice *) arg; + SDL_AudioDevice *this = (SDL_AudioDevice *)arg; if (SDL_AtomicGet(&this->enabled)) { jack_port_t **ports = this->hidden->sdlports; const int total_channels = this->spec.channels; const int total_frames = this->spec.samples; int channelsi; - + for (channelsi = 0; channelsi < total_channels; channelsi++) { - const float *src = (const float *) JACK_jack_port_get_buffer(ports[channelsi], nframes); + const float *src = (const float *)JACK_jack_port_get_buffer(ports[channelsi], nframes); if (src) { - float *dst = ((float *) this->hidden->iobuffer) + channelsi; + float *dst = this->hidden->iobuffer + channelsi; int framesi; for (framesi = 0; framesi < total_frames; framesi++) { *dst = *(src++); @@ -230,14 +213,13 @@ jackProcessCaptureCallback(jack_nframes_t nframes, void *arg) } } - SDL_SemPost(this->hidden->iosem); /* tell SDL thread we're done; new buffer is ready! */ - return 0; /* success */ + SDL_SemPost(this->hidden->iosem); /* tell SDL thread we're done; new buffer is ready! */ + return 0; } -static int -JACK_CaptureFromDevice(_THIS, void *buffer, int buflen) +static int JACK_CaptureFromDevice(_THIS, void *buffer, int buflen) { - SDL_assert(buflen == this->spec.size); /* we always fill a full buffer. */ + SDL_assert(buflen == this->spec.size); /* we always fill a full buffer. */ /* Wait for JACK to fill the iobuffer */ if (SDL_SemWait(this->hidden->iosem) == -1) { @@ -248,15 +230,12 @@ JACK_CaptureFromDevice(_THIS, void *buffer, int buflen) return buflen; } -static void -JACK_FlushCapture(_THIS) +static void JACK_FlushCapture(_THIS) { SDL_SemWait(this->hidden->iosem); } - -static void -JACK_CloseDevice(_THIS) +static void JACK_CloseDevice(_THIS) { if (this->hidden->client) { JACK_jack_deactivate(this->hidden->client); @@ -278,15 +257,16 @@ JACK_CloseDevice(_THIS) } SDL_free(this->hidden->iobuffer); + SDL_free(this->hidden); } -static int -JACK_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) +static int JACK_OpenDevice(_THIS, const char *devname) { /* Note that JACK uses "output" for capture devices (they output audio data to us) and "input" for playback (we input audio data to them). Likewise, SDL's playback port will be "output" (we write data out) and capture will be "input" (we read data in). */ + SDL_bool iscapture = this->iscapture; const unsigned long sysportflags = iscapture ? JackPortIsOutput : JackPortIsInput; const unsigned long sdlportflags = iscapture ? JackPortIsInput : JackPortIsOutput; const JackProcessCallback callback = iscapture ? jackProcessCaptureCallback : jackProcessPlaybackCallback; @@ -300,7 +280,7 @@ JACK_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) int i; /* Initialize all variables that we clean on shutdown */ - this->hidden = (struct SDL_PrivateAudioData *) SDL_calloc(1, sizeof (*this->hidden)); + this->hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, sizeof(*this->hidden)); if (this->hidden == NULL) { return SDL_OutOfMemory(); } @@ -313,7 +293,7 @@ JACK_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) } devports = JACK_jack_get_ports(client, NULL, NULL, JackPortIsPhysical | sysportflags); - if (!devports || !devports[0]) { + if (devports == NULL || !devports[0]) { return SDL_SetError("No physical JACK ports available"); } @@ -322,21 +302,21 @@ JACK_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) } /* Filter out non-audio ports */ - audio_ports = SDL_calloc(ports, sizeof *audio_ports); + audio_ports = SDL_calloc(ports, sizeof(*audio_ports)); for (i = 0; i < ports; i++) { const jack_port_t *dport = JACK_jack_port_by_name(client, devports[i]); const char *type = JACK_jack_port_type(dport); const int len = SDL_strlen(type); /* See if type ends with "audio" */ - if (len >= 5 && !SDL_memcmp(type+len-5, "audio", 5)) { + if (len >= 5 && !SDL_memcmp(type + len - 5, "audio", 5)) { audio_ports[channels++] = i; } } if (channels == 0) { + SDL_free(audio_ports); return SDL_SetError("No physical JACK ports available"); } - /* !!! FIXME: docs say about buffer size: "This size may change, clients that depend on it must register a bufsize_callback so they will be notified if it does." */ /* Jack pretty much demands what it wants. */ @@ -349,36 +329,42 @@ JACK_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) this->hidden->iosem = SDL_CreateSemaphore(0); if (!this->hidden->iosem) { - return -1; /* error was set by SDL_CreateSemaphore */ + SDL_free(audio_ports); + return -1; /* error was set by SDL_CreateSemaphore */ } - this->hidden->iobuffer = (float *) SDL_calloc(1, this->spec.size); + this->hidden->iobuffer = (float *)SDL_calloc(1, this->spec.size); if (!this->hidden->iobuffer) { + SDL_free(audio_ports); return SDL_OutOfMemory(); } /* Build SDL's ports, which we will connect to the device ports. */ - this->hidden->sdlports = (jack_port_t **) SDL_calloc(channels, sizeof (jack_port_t *)); - if (this->hidden->sdlports == NULL) { + this->hidden->sdlports = (jack_port_t **)SDL_calloc(channels, sizeof(jack_port_t *)); + if (!this->hidden->sdlports) { + SDL_free(audio_ports); return SDL_OutOfMemory(); } for (i = 0; i < channels; i++) { char portname[32]; - SDL_snprintf(portname, sizeof (portname), "sdl_jack_%s_%d", sdlportstr, i); + (void)SDL_snprintf(portname, sizeof(portname), "sdl_jack_%s_%d", sdlportstr, i); this->hidden->sdlports[i] = JACK_jack_port_register(client, portname, JACK_DEFAULT_AUDIO_TYPE, sdlportflags, 0); if (this->hidden->sdlports[i] == NULL) { + SDL_free(audio_ports); return SDL_SetError("jack_port_register failed"); } } if (JACK_jack_set_process_callback(client, callback, this) != 0) { + SDL_free(audio_ports); return SDL_SetError("JACK: Couldn't set process callback"); } JACK_jack_on_shutdown(client, jackShutdownCallback, this); if (JACK_jack_activate(client) != 0) { + SDL_free(audio_ports); return SDL_SetError("Failed to activate JACK client"); } @@ -388,6 +374,7 @@ JACK_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) const char *srcport = iscapture ? devports[audio_ports[i]] : sdlport; const char *dstport = iscapture ? sdlport : devports[audio_ports[i]]; if (JACK_jack_connect(client, srcport, dstport) != 0) { + SDL_free(audio_ports); return SDL_SetError("Couldn't connect JACK ports: %s => %s", srcport, dstport); } } @@ -400,24 +387,22 @@ JACK_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) return 0; } -static void -JACK_Deinitialize(void) +static void JACK_Deinitialize(void) { UnloadJackLibrary(); } -static int -JACK_Init(SDL_AudioDriverImpl * impl) +static SDL_bool JACK_Init(SDL_AudioDriverImpl *impl) { if (LoadJackLibrary() < 0) { - return 0; + return SDL_FALSE; } else { /* Make sure a JACK server is running and available. */ jack_status_t status; jack_client_t *client = JACK_jack_client_open("SDL", JackNoStartServer, &status, NULL); - if (client == NULL) { + if (!client) { UnloadJackLibrary(); - return 0; + return SDL_FALSE; } JACK_jack_client_close(client); } @@ -434,11 +419,11 @@ JACK_Init(SDL_AudioDriverImpl * impl) impl->OnlyHasDefaultCaptureDevice = SDL_TRUE; impl->HasCaptureSupport = SDL_TRUE; - return 1; /* this audio target is available. */ + return SDL_TRUE; /* this audio target is available. */ } AudioBootStrap JACK_bootstrap = { - "jack", "JACK Audio Connection Kit", JACK_Init, 0 + "jack", "JACK Audio Connection Kit", JACK_Init, SDL_FALSE }; #endif /* SDL_AUDIO_DRIVER_JACK */ diff --git a/SDL2-2.0.12/src/audio/jack/SDL_jackaudio.h b/SDL2-2.30.5/src/audio/jack/SDL_jackaudio.h similarity index 95% rename from SDL2-2.0.12/src/audio/jack/SDL_jackaudio.h rename to SDL2-2.30.5/src/audio/jack/SDL_jackaudio.h index 254d099..e0ac2e9 100644 --- a/SDL2-2.0.12/src/audio/jack/SDL_jackaudio.h +++ b/SDL2-2.30.5/src/audio/jack/SDL_jackaudio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.30.5/src/audio/n3ds/SDL_n3dsaudio.c b/SDL2-2.30.5/src/audio/n3ds/SDL_n3dsaudio.c new file mode 100644 index 0000000..ea20a7c --- /dev/null +++ b/SDL2-2.30.5/src/audio/n3ds/SDL_n3dsaudio.c @@ -0,0 +1,337 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_AUDIO_DRIVER_N3DS + +#include "SDL_audio.h" + +/* N3DS Audio driver */ + +#include "../SDL_sysaudio.h" +#include "SDL_n3dsaudio.h" +#include "SDL_timer.h" + +#define N3DSAUDIO_DRIVER_NAME "n3ds" + +static dspHookCookie dsp_hook; +static SDL_AudioDevice *audio_device; + +static void FreePrivateData(_THIS); +static int FindAudioFormat(_THIS); + +/* fully local functions related to the wavebufs / DSP, not the same as the SDL-wide mixer lock */ +static SDL_INLINE void contextLock(_THIS) +{ + LightLock_Lock(&this->hidden->lock); +} + +static SDL_INLINE void contextUnlock(_THIS) +{ + LightLock_Unlock(&this->hidden->lock); +} + +static void N3DSAUD_DspHook(DSP_HookType hook) +{ + if (hook == DSPHOOK_ONCANCEL) { + contextLock(audio_device); + audio_device->hidden->isCancelled = SDL_TRUE; + SDL_AtomicSet(&audio_device->enabled, SDL_FALSE); + CondVar_Broadcast(&audio_device->hidden->cv); + contextUnlock(audio_device); + } +} + +static void AudioFrameFinished(void *device) +{ + bool shouldBroadcast = false; + unsigned i; + SDL_AudioDevice *this = (SDL_AudioDevice *)device; + + contextLock(this); + + for (i = 0; i < NUM_BUFFERS; i++) { + if (this->hidden->waveBuf[i].status == NDSP_WBUF_DONE) { + this->hidden->waveBuf[i].status = NDSP_WBUF_FREE; + shouldBroadcast = SDL_TRUE; + } + } + + if (shouldBroadcast) { + CondVar_Broadcast(&this->hidden->cv); + } + + contextUnlock(this); +} + +static int N3DSAUDIO_OpenDevice(_THIS, const char *devname) +{ + Result ndsp_init_res; + Uint8 *data_vaddr; + float mix[12]; + this->hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, sizeof(*this->hidden)); + + if (!this->hidden) { + return SDL_OutOfMemory(); + } + + /* Initialise the DSP service */ + ndsp_init_res = ndspInit(); + if (R_FAILED(ndsp_init_res)) { + if ((R_SUMMARY(ndsp_init_res) == RS_NOTFOUND) && (R_MODULE(ndsp_init_res) == RM_DSP)) { + SDL_SetError("DSP init failed: dspfirm.cdc missing!"); + } else { + SDL_SetError("DSP init failed. Error code: 0x%lX", ndsp_init_res); + } + return -1; + } + + /* Initialise internal state */ + LightLock_Init(&this->hidden->lock); + CondVar_Init(&this->hidden->cv); + + if (this->spec.channels > 2) { + this->spec.channels = 2; + } + + /* Should not happen but better be safe. */ + if (FindAudioFormat(this) < 0) { + return SDL_SetError("No supported audio format found."); + } + + /* Update the fragment size as size in bytes */ + SDL_CalculateAudioSpec(&this->spec); + + /* Allocate mixing buffer */ + if (this->spec.size >= SDL_MAX_UINT32 / 2) { + return SDL_SetError("Mixing buffer is too large."); + } + + this->hidden->mixlen = this->spec.size; + this->hidden->mixbuf = (Uint8 *)SDL_malloc(this->spec.size); + if (!this->hidden->mixbuf) { + return SDL_OutOfMemory(); + } + + SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size); + + data_vaddr = (Uint8 *)linearAlloc(this->hidden->mixlen * NUM_BUFFERS); + if (!data_vaddr) { + return SDL_OutOfMemory(); + } + + SDL_memset(data_vaddr, 0, this->hidden->mixlen * NUM_BUFFERS); + DSP_FlushDataCache(data_vaddr, this->hidden->mixlen * NUM_BUFFERS); + + this->hidden->nextbuf = 0; + this->hidden->channels = this->spec.channels; + this->hidden->samplerate = this->spec.freq; + + ndspChnReset(0); + + ndspChnSetInterp(0, NDSP_INTERP_LINEAR); + ndspChnSetRate(0, this->spec.freq); + ndspChnSetFormat(0, this->hidden->format); + + SDL_memset(mix, 0, sizeof(mix)); + mix[0] = 1.0; + mix[1] = 1.0; + ndspChnSetMix(0, mix); + + SDL_memset(this->hidden->waveBuf, 0, sizeof(ndspWaveBuf) * NUM_BUFFERS); + + for (unsigned i = 0; i < NUM_BUFFERS; i++) { + this->hidden->waveBuf[i].data_vaddr = data_vaddr; + this->hidden->waveBuf[i].nsamples = this->hidden->mixlen / this->hidden->bytePerSample; + data_vaddr += this->hidden->mixlen; + } + + /* Setup callback */ + audio_device = this; + ndspSetCallback(AudioFrameFinished, this); + dspHook(&dsp_hook, N3DSAUD_DspHook); + + return 0; +} + +static int N3DSAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen) +{ + /* Delay to make this sort of simulate real audio input. */ + SDL_Delay((this->spec.samples * 1000) / this->spec.freq); + + /* always return a full buffer of silence. */ + SDL_memset(buffer, this->spec.silence, buflen); + return buflen; +} + +static void N3DSAUDIO_PlayDevice(_THIS) +{ + size_t nextbuf; + size_t sampleLen; + + contextLock(this); + + nextbuf = this->hidden->nextbuf; + sampleLen = this->hidden->mixlen; + + if (this->hidden->isCancelled || + this->hidden->waveBuf[nextbuf].status != NDSP_WBUF_FREE) { + contextUnlock(this); + return; + } + + this->hidden->nextbuf = (nextbuf + 1) % NUM_BUFFERS; + + contextUnlock(this); + + memcpy((void *)this->hidden->waveBuf[nextbuf].data_vaddr, + this->hidden->mixbuf, sampleLen); + DSP_FlushDataCache(this->hidden->waveBuf[nextbuf].data_vaddr, sampleLen); + + ndspChnWaveBufAdd(0, &this->hidden->waveBuf[nextbuf]); +} + +static void N3DSAUDIO_WaitDevice(_THIS) +{ + contextLock(this); + while (!this->hidden->isCancelled && + this->hidden->waveBuf[this->hidden->nextbuf].status != NDSP_WBUF_FREE) { + CondVar_Wait(&this->hidden->cv, &this->hidden->lock); + } + contextUnlock(this); +} + +static Uint8 *N3DSAUDIO_GetDeviceBuf(_THIS) +{ + return this->hidden->mixbuf; +} + +static void N3DSAUDIO_CloseDevice(_THIS) +{ + contextLock(this); + + dspUnhook(&dsp_hook); + ndspSetCallback(NULL, NULL); + + if (!this->hidden->isCancelled) { + ndspChnReset(0); + memset(this->hidden->waveBuf, 0, sizeof(ndspWaveBuf) * NUM_BUFFERS); + CondVar_Broadcast(&this->hidden->cv); + } + + contextUnlock(this); + + ndspExit(); + + FreePrivateData(this); +} + +static void N3DSAUDIO_ThreadInit(_THIS) +{ + s32 current_priority = 0x30; + svcGetThreadPriority(¤t_priority, CUR_THREAD_HANDLE); + current_priority--; + /* 0x18 is reserved for video, 0x30 is the default for main thread */ + current_priority = SDL_clamp(current_priority, 0x19, 0x2F); + svcSetThreadPriority(CUR_THREAD_HANDLE, current_priority); +} + +static SDL_bool N3DSAUDIO_Init(SDL_AudioDriverImpl *impl) +{ + /* Set the function pointers */ + impl->OpenDevice = N3DSAUDIO_OpenDevice; + impl->PlayDevice = N3DSAUDIO_PlayDevice; + impl->WaitDevice = N3DSAUDIO_WaitDevice; + impl->GetDeviceBuf = N3DSAUDIO_GetDeviceBuf; + impl->CloseDevice = N3DSAUDIO_CloseDevice; + impl->ThreadInit = N3DSAUDIO_ThreadInit; + impl->OnlyHasDefaultOutputDevice = SDL_TRUE; + + /* Should be possible, but micInit would fail */ + impl->HasCaptureSupport = SDL_FALSE; + impl->CaptureFromDevice = N3DSAUDIO_CaptureFromDevice; + + return SDL_TRUE; /* this audio target is available. */ +} + +AudioBootStrap N3DSAUDIO_bootstrap = { + N3DSAUDIO_DRIVER_NAME, + "SDL N3DS audio driver", + N3DSAUDIO_Init, + 0 +}; + +/** + * Cleans up all allocated memory, safe to call with null pointers + */ +static void FreePrivateData(_THIS) +{ + if (!this->hidden) { + return; + } + + if (this->hidden->waveBuf[0].data_vaddr) { + linearFree((void *)this->hidden->waveBuf[0].data_vaddr); + } + + if (this->hidden->mixbuf) { + SDL_free(this->hidden->mixbuf); + this->hidden->mixbuf = NULL; + } + + SDL_free(this->hidden); + this->hidden = NULL; +} + +static int FindAudioFormat(_THIS) +{ + SDL_bool found_valid_format = SDL_FALSE; + Uint16 test_format = SDL_FirstAudioFormat(this->spec.format); + + while (!found_valid_format && test_format) { + this->spec.format = test_format; + switch (test_format) { + case AUDIO_S8: + /* Signed 8-bit audio supported */ + this->hidden->format = (this->spec.channels == 2) ? NDSP_FORMAT_STEREO_PCM8 : NDSP_FORMAT_MONO_PCM8; + this->hidden->isSigned = 1; + this->hidden->bytePerSample = this->spec.channels; + found_valid_format = SDL_TRUE; + break; + case AUDIO_S16: + /* Signed 16-bit audio supported */ + this->hidden->format = (this->spec.channels == 2) ? NDSP_FORMAT_STEREO_PCM16 : NDSP_FORMAT_MONO_PCM16; + this->hidden->isSigned = 1; + this->hidden->bytePerSample = this->spec.channels * 2; + found_valid_format = SDL_TRUE; + break; + default: + test_format = SDL_NextAudioFormat(); + break; + } + } + + return found_valid_format ? 0 : -1; +} + +#endif /* SDL_AUDIO_DRIVER_N3DS */ + +/* vi: set sts=4 ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/audio/n3ds/SDL_n3dsaudio.h b/SDL2-2.30.5/src/audio/n3ds/SDL_n3dsaudio.h new file mode 100644 index 0000000..274e9f3 --- /dev/null +++ b/SDL2-2.30.5/src/audio/n3ds/SDL_n3dsaudio.h @@ -0,0 +1,50 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#ifndef _SDL_n3dsaudio_h_ +#define _SDL_n3dsaudio_h_ + +#include <3ds.h> + +/* Hidden "this" pointer for the audio functions */ +#define _THIS SDL_AudioDevice *this + +#define NUM_BUFFERS 3 /* -- Minimum 2! */ + +struct SDL_PrivateAudioData +{ + /* Speaker data */ + Uint8 *mixbuf; + Uint32 mixlen; + Uint32 format; + Uint32 samplerate; + Uint32 channels; + Uint8 bytePerSample; + Uint32 isSigned; + Uint32 nextbuf; + ndspWaveBuf waveBuf[NUM_BUFFERS]; + LightLock lock; + CondVar cv; + SDL_bool isCancelled; +}; + +#endif /* _SDL_n3dsaudio_h_ */ +/* vi: set sts=4 ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/audio/nacl/SDL_naclaudio.c b/SDL2-2.30.5/src/audio/nacl/SDL_naclaudio.c similarity index 66% rename from SDL2-2.0.12/src/audio/nacl/SDL_naclaudio.c rename to SDL2-2.30.5/src/audio/nacl/SDL_naclaudio.c index 4caa652..f189256 100644 --- a/SDL2-2.0.12/src/audio/nacl/SDL_naclaudio.c +++ b/SDL2-2.30.5/src/audio/nacl/SDL_naclaudio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -21,7 +21,7 @@ #include "../../SDL_internal.h" -#if SDL_AUDIO_DRIVER_NACL +#ifdef SDL_AUDIO_DRIVER_NACL #include "SDL_naclaudio.h" @@ -45,12 +45,13 @@ static void nacl_audio_callback(void* samples, uint32_t buffer_size, PP_TimeDelta latency, void* data); /* FIXME: Make use of latency if needed */ -static void nacl_audio_callback(void* stream, uint32_t buffer_size, PP_TimeDelta latency, void* data) { +static void nacl_audio_callback(void* stream, uint32_t buffer_size, PP_TimeDelta latency, void* data) +{ const int len = (int) buffer_size; SDL_AudioDevice* _this = (SDL_AudioDevice*) data; SDL_AudioCallback callback = _this->callbackspec.callback; - - SDL_LockMutex(private->mutex); /* !!! FIXME: is this mutex necessary? */ + + SDL_LockMutex(_this->mixer_lock); /* Only do something if audio is enabled */ if (!SDL_AtomicGet(&_this->enabled) || SDL_AtomicGet(&_this->paused)) { @@ -58,106 +59,101 @@ static void nacl_audio_callback(void* stream, uint32_t buffer_size, PP_TimeDelta SDL_AudioStreamClear(_this->stream); } SDL_memset(stream, _this->spec.silence, len); - return; - } + } else { + SDL_assert(_this->spec.size == len); - SDL_assert(_this->spec.size == len); + if (!_this->stream) { /* no conversion necessary. */ + callback(_this->callbackspec.userdata, stream, len); + } else { /* streaming/converting */ + const int stream_len = _this->callbackspec.size; + while (SDL_AudioStreamAvailable(_this->stream) < len) { + callback(_this->callbackspec.userdata, _this->work_buffer, stream_len); + if (SDL_AudioStreamPut(_this->stream, _this->work_buffer, stream_len) == -1) { + SDL_AudioStreamClear(_this->stream); + SDL_AtomicSet(&_this->enabled, 0); + break; + } + } - if (_this->stream == NULL) { /* no conversion necessary. */ - SDL_LockMutex(_this->mixer_lock); - callback(_this->callbackspec.userdata, stream, len); - SDL_UnlockMutex(_this->mixer_lock); - } else { /* streaming/converting */ - const int stream_len = _this->callbackspec.size; - while (SDL_AudioStreamAvailable(_this->stream) < len) { - callback(_this->callbackspec.userdata, _this->work_buffer, stream_len); - if (SDL_AudioStreamPut(_this->stream, _this->work_buffer, stream_len) == -1) { - SDL_AudioStreamClear(_this->stream); - SDL_AtomicSet(&_this->enabled, 0); - break; + const int got = SDL_AudioStreamGet(_this->stream, stream, len); + SDL_assert((got < 0) || (got == len)); + if (got != len) { + SDL_memset(stream, _this->spec.silence, len); } } - - const int got = SDL_AudioStreamGet(_this->stream, stream, len); - SDL_assert((got < 0) || (got == len)); - if (got != len) { - SDL_memset(stream, _this->spec.silence, len); - } } - SDL_UnlockMutex(private->mutex); + SDL_UnlockMutex(_this->mixer_lock); } -static void NACLAUDIO_CloseDevice(SDL_AudioDevice *device) { +static void NACLAUDIO_CloseDevice(SDL_AudioDevice *device) +{ const PPB_Core *core = PSInterfaceCore(); const PPB_Audio *ppb_audio = PSInterfaceAudio(); SDL_PrivateAudioData *hidden = (SDL_PrivateAudioData *) device->hidden; - + ppb_audio->StopPlayback(hidden->audio); - SDL_DestroyMutex(hidden->mutex); core->ReleaseResource(hidden->audio); } -static int -NACLAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) { +static int NACLAUDIO_OpenDevice(_THIS, const char *devname) +{ PP_Instance instance = PSGetInstanceId(); const PPB_Audio *ppb_audio = PSInterfaceAudio(); const PPB_AudioConfig *ppb_audiocfg = PSInterfaceAudioConfig(); - - private = (SDL_PrivateAudioData *) SDL_calloc(1, (sizeof *private)); - if (private == NULL) { + + private = (SDL_PrivateAudioData *)SDL_calloc(1, sizeof(*private)); + if (!private) { return SDL_OutOfMemory(); } - - private->mutex = SDL_CreateMutex(); + _this->spec.freq = 44100; _this->spec.format = AUDIO_S16LSB; _this->spec.channels = 2; _this->spec.samples = ppb_audiocfg->RecommendSampleFrameCount( - instance, - PP_AUDIOSAMPLERATE_44100, + instance, + PP_AUDIOSAMPLERATE_44100, SAMPLE_FRAME_COUNT); - + /* Calculate the final parameters for this audio specification */ SDL_CalculateAudioSpec(&_this->spec); - + private->audio = ppb_audio->Create( instance, ppb_audiocfg->CreateStereo16Bit(instance, PP_AUDIOSAMPLERATE_44100, _this->spec.samples), - nacl_audio_callback, + nacl_audio_callback, _this); - + /* Start audio playback while we are still on the main thread. */ ppb_audio->StartPlayback(private->audio); - + return 0; } -static int -NACLAUDIO_Init(SDL_AudioDriverImpl * impl) +static SDL_bool NACLAUDIO_Init(SDL_AudioDriverImpl * impl) { if (PSGetInstanceId() == 0) { - return 0; + return SDL_FALSE; } - + /* Set the function pointers */ impl->OpenDevice = NACLAUDIO_OpenDevice; impl->CloseDevice = NACLAUDIO_CloseDevice; - impl->OnlyHasDefaultOutputDevice = 1; - impl->ProvidesOwnCallbackThread = 1; + impl->OnlyHasDefaultOutputDevice = SDL_TRUE; + impl->ProvidesOwnCallbackThread = SDL_TRUE; /* * impl->WaitDevice = NACLAUDIO_WaitDevice; * impl->GetDeviceBuf = NACLAUDIO_GetDeviceBuf; * impl->PlayDevice = NACLAUDIO_PlayDevice; * impl->Deinitialize = NACLAUDIO_Deinitialize; */ - - return 1; + + return SDL_TRUE; } AudioBootStrap NACLAUDIO_bootstrap = { NACLAUDIO_DRIVER_NAME, "SDL NaCl Audio Driver", - NACLAUDIO_Init, 0 + NACLAUDIO_Init, SDL_FALSE }; #endif /* SDL_AUDIO_DRIVER_NACL */ diff --git a/SDL2-2.0.12/src/audio/nacl/SDL_naclaudio.h b/SDL2-2.30.5/src/audio/nacl/SDL_naclaudio.h similarity index 92% rename from SDL2-2.0.12/src/audio/nacl/SDL_naclaudio.h rename to SDL2-2.30.5/src/audio/nacl/SDL_naclaudio.h index c1ef0d7..c08702b 100644 --- a/SDL2-2.0.12/src/audio/nacl/SDL_naclaudio.h +++ b/SDL2-2.30.5/src/audio/nacl/SDL_naclaudio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -34,8 +34,7 @@ #define private _this->hidden typedef struct SDL_PrivateAudioData { - SDL_mutex* mutex; - PP_Resource audio; + PP_Resource audio; } SDL_PrivateAudioData; #endif /* SDL_naclaudio_h_ */ diff --git a/SDL2-2.0.12/src/audio/nas/SDL_nasaudio.c b/SDL2-2.30.5/src/audio/nas/SDL_nasaudio.c similarity index 81% rename from SDL2-2.0.12/src/audio/nas/SDL_nasaudio.c rename to SDL2-2.30.5/src/audio/nas/SDL_nasaudio.c index 042e089..f3eb68f 100644 --- a/SDL2-2.0.12/src/audio/nas/SDL_nasaudio.c +++ b/SDL2-2.30.5/src/audio/nas/SDL_nasaudio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_AUDIO_DRIVER_NAS +#ifdef SDL_AUDIO_DRIVER_NAS /* Allow access to a raw mixing buffer */ @@ -56,11 +56,10 @@ static AuEventHandlerRec *(*NAS_AuRegisterEventHandler) static const char *nas_library = SDL_AUDIO_DRIVER_NAS_DYNAMIC; static void *nas_handle = NULL; -static int -load_nas_sym(const char *fn, void **addr) +static int load_nas_sym(const char *fn, void **addr) { *addr = SDL_LoadFunction(nas_handle, fn); - if (*addr == NULL) { + if (!*addr) { return 0; } return 1; @@ -73,8 +72,7 @@ load_nas_sym(const char *fn, void **addr) #define SDL_NAS_SYM(x) NAS_##x = x #endif -static int -load_nas_syms(void) +static int load_nas_syms(void) { SDL_NAS_SYM(AuCloseServer); SDL_NAS_SYM(AuNextEvent); @@ -94,30 +92,28 @@ load_nas_syms(void) #ifdef SDL_AUDIO_DRIVER_NAS_DYNAMIC -static void -UnloadNASLibrary(void) +static void UnloadNASLibrary(void) { - if (nas_handle != NULL) { + if (nas_handle) { SDL_UnloadObject(nas_handle); nas_handle = NULL; } } -static int -LoadNASLibrary(void) +static int LoadNASLibrary(void) { int retval = 0; - if (nas_handle == NULL) { + if (!nas_handle) { nas_handle = SDL_LoadObject(nas_library); - if (nas_handle == NULL) { + if (!nas_handle) { /* Copy error string so we can use it in a new SDL_SetError(). */ const char *origerr = SDL_GetError(); const size_t len = SDL_strlen(origerr) + 1; - char *err = (char *) alloca(len); + char *err = SDL_stack_alloc(char, len); SDL_strlcpy(err, origerr, len); + SDL_SetError("NAS: SDL_LoadObject('%s') failed: %s", nas_library, err); + SDL_stack_free(err); retval = -1; - SDL_SetError("NAS: SDL_LoadObject('%s') failed: %s", - nas_library, err); } else { retval = load_nas_syms(); if (retval < 0) { @@ -130,13 +126,11 @@ LoadNASLibrary(void) #else -static void -UnloadNASLibrary(void) +static void UnloadNASLibrary(void) { } -static int -LoadNASLibrary(void) +static int LoadNASLibrary(void) { load_nas_syms(); return 0; @@ -145,8 +139,7 @@ LoadNASLibrary(void) #endif /* SDL_AUDIO_DRIVER_NAS_DYNAMIC */ /* This function waits until it is possible to write a full sound buffer */ -static void -NAS_WaitDevice(_THIS) +static void NAS_WaitDevice(_THIS) { while (this->hidden->buf_free < this->hidden->mixlen) { AuEvent ev; @@ -155,8 +148,7 @@ NAS_WaitDevice(_THIS) } } -static void -NAS_PlayDevice(_THIS) +static void NAS_PlayDevice(_THIS) { while (this->hidden->mixlen > this->hidden->buf_free) { /* @@ -182,14 +174,12 @@ NAS_PlayDevice(_THIS) #endif } -static Uint8 * -NAS_GetDeviceBuf(_THIS) +static Uint8 *NAS_GetDeviceBuf(_THIS) { return (this->hidden->mixbuf); } -static int -NAS_CaptureFromDevice(_THIS, void *buffer, int buflen) +static int NAS_CaptureFromDevice(_THIS, void *buffer, int buflen) { struct SDL_PrivateAudioData *h = this->hidden; int retval; @@ -197,7 +187,7 @@ NAS_CaptureFromDevice(_THIS, void *buffer, int buflen) while (SDL_TRUE) { /* just keep the event queue moving and the server chattering. */ NAS_AuHandleEvents(h->aud); - + retval = (int) NAS_AuReadElement(h->aud, h->flow, 1, buflen, buffer, NULL); /*printf("read %d capture bytes\n", (int) retval);*/ if (retval == 0) { @@ -210,8 +200,7 @@ NAS_CaptureFromDevice(_THIS, void *buffer, int buflen) return retval; } -static void -NAS_FlushCapture(_THIS) +static void NAS_FlushCapture(_THIS) { struct SDL_PrivateAudioData *h = this->hidden; AuUint32 total = 0; @@ -221,14 +210,13 @@ NAS_FlushCapture(_THIS) do { /* just keep the event queue moving and the server chattering. */ NAS_AuHandleEvents(h->aud); - br = NAS_AuReadElement(h->aud, h->flow, 1, sizeof (buf), buf, NULL); + br = NAS_AuReadElement(h->aud, h->flow, 1, sizeof(buf), buf, NULL); /*printf("flushed %d capture bytes\n", (int) br);*/ total += br; - } while ((br == sizeof (buf)) && (total < this->spec.size)); + } while ((br == sizeof(buf)) && (total < this->spec.size)); } -static void -NAS_CloseDevice(_THIS) +static void NAS_CloseDevice(_THIS) { if (this->hidden->aud) { NAS_AuCloseServer(this->hidden->aud); @@ -237,28 +225,7 @@ NAS_CloseDevice(_THIS) SDL_free(this->hidden); } -static unsigned char -sdlformat_to_auformat(unsigned int fmt) -{ - switch (fmt) { - case AUDIO_U8: - return AuFormatLinearUnsigned8; - case AUDIO_S8: - return AuFormatLinearSigned8; - case AUDIO_U16LSB: - return AuFormatLinearUnsigned16LSB; - case AUDIO_U16MSB: - return AuFormatLinearUnsigned16MSB; - case AUDIO_S16LSB: - return AuFormatLinearSigned16LSB; - case AUDIO_S16MSB: - return AuFormatLinearSigned16MSB; - } - return AuNone; -} - -static AuBool -event_handler(AuServer * aud, AuEvent * ev, AuEventHandlerRec * hnd) +static AuBool event_handler(AuServer * aud, AuEvent * ev, AuEventHandlerRec * hnd) { SDL_AudioDevice *this = (SDL_AudioDevice *) hnd->data; struct SDL_PrivateAudioData *h = this->hidden; @@ -301,8 +268,7 @@ event_handler(AuServer * aud, AuEvent * ev, AuEventHandlerRec * hnd) return AuTrue; } -static AuDeviceID -find_device(_THIS) +static AuDeviceID find_device(_THIS) { /* These "Au" things are all macros, not functions... */ struct SDL_PrivateAudioData *h = this->hidden; @@ -330,32 +296,48 @@ find_device(_THIS) return AuNone; } -static int -NAS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) +static int NAS_OpenDevice(_THIS, const char *devname) { AuElement elms[3]; int buffer_size; - SDL_AudioFormat test_format, format; + SDL_bool iscapture = this->iscapture; + SDL_AudioFormat test_format, format = 0; /* Initialize all variables that we clean on shutdown */ - this->hidden = (struct SDL_PrivateAudioData *) - SDL_malloc((sizeof *this->hidden)); - if (this->hidden == NULL) { + this->hidden = (struct SDL_PrivateAudioData *)SDL_malloc(sizeof(*this->hidden)); + if (!this->hidden) { return SDL_OutOfMemory(); } SDL_zerop(this->hidden); /* Try for a closest match on audio format */ - format = 0; - for (test_format = SDL_FirstAudioFormat(this->spec.format); - !format && test_format;) { - format = sdlformat_to_auformat(test_format); - if (format == AuNone) { - test_format = SDL_NextAudioFormat(); + for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) { + switch (test_format) { + case AUDIO_U8: + format = AuFormatLinearUnsigned8; + break; + case AUDIO_S8: + format = AuFormatLinearSigned8; + break; + case AUDIO_U16LSB: + format = AuFormatLinearUnsigned16LSB; + break; + case AUDIO_U16MSB: + format = AuFormatLinearUnsigned16MSB; + break; + case AUDIO_S16LSB: + format = AuFormatLinearSigned16LSB; + break; + case AUDIO_S16MSB: + format = AuFormatLinearSigned16MSB; + break; + default: + continue; } + break; } - if (format == 0) { - return SDL_SetError("NAS: Couldn't find any hardware audio formats"); + if (!test_format) { + return SDL_SetError("%s: Unsupported audio format", "nas"); } this->spec.format = test_format; @@ -407,7 +389,7 @@ NAS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) if (!iscapture) { this->hidden->mixlen = this->spec.size; this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen); - if (this->hidden->mixbuf == NULL) { + if (!this->hidden->mixbuf) { return SDL_OutOfMemory(); } SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size); @@ -417,22 +399,20 @@ NAS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) return 0; } -static void -NAS_Deinitialize(void) +static void NAS_Deinitialize(void) { UnloadNASLibrary(); } -static int -NAS_Init(SDL_AudioDriverImpl * impl) +static SDL_bool NAS_Init(SDL_AudioDriverImpl * impl) { if (LoadNASLibrary() < 0) { - return 0; + return SDL_FALSE; } else { AuServer *aud = NAS_AuOpenServer("", 0, NULL, 0, NULL, NULL); - if (aud == NULL) { + if (!aud) { SDL_SetError("NAS: AuOpenServer() failed (no audio server?)"); - return 0; + return SDL_FALSE; } NAS_AuCloseServer(aud); } @@ -447,15 +427,15 @@ NAS_Init(SDL_AudioDriverImpl * impl) impl->CloseDevice = NAS_CloseDevice; impl->Deinitialize = NAS_Deinitialize; - impl->OnlyHasDefaultOutputDevice = 1; - impl->OnlyHasDefaultCaptureDevice = 1; + impl->OnlyHasDefaultOutputDevice = SDL_TRUE; + impl->OnlyHasDefaultCaptureDevice = SDL_TRUE; impl->HasCaptureSupport = SDL_TRUE; - return 1; /* this audio target is available. */ + return SDL_TRUE; /* this audio target is available. */ } AudioBootStrap NAS_bootstrap = { - "nas", "Network Audio System", NAS_Init, 0 + "nas", "Network Audio System", NAS_Init, SDL_FALSE }; #endif /* SDL_AUDIO_DRIVER_NAS */ diff --git a/SDL2-2.0.12/src/audio/nas/SDL_nasaudio.h b/SDL2-2.30.5/src/audio/nas/SDL_nasaudio.h similarity index 96% rename from SDL2-2.0.12/src/audio/nas/SDL_nasaudio.h rename to SDL2-2.30.5/src/audio/nas/SDL_nasaudio.h index 3e28118..0275c06 100644 --- a/SDL2-2.0.12/src/audio/nas/SDL_nasaudio.h +++ b/SDL2-2.30.5/src/audio/nas/SDL_nasaudio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/audio/netbsd/SDL_netbsdaudio.c b/SDL2-2.30.5/src/audio/netbsd/SDL_netbsdaudio.c similarity index 67% rename from SDL2-2.0.12/src/audio/netbsd/SDL_netbsdaudio.c rename to SDL2-2.30.5/src/audio/netbsd/SDL_netbsdaudio.c index 3fd78de..cc51599 100644 --- a/SDL2-2.0.12/src/audio/netbsd/SDL_netbsdaudio.c +++ b/SDL2-2.30.5/src/audio/netbsd/SDL_netbsdaudio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,11 +20,11 @@ */ #include "../../SDL_internal.h" -#if SDL_AUDIO_DRIVER_NETBSD +#ifdef SDL_AUDIO_DRIVER_NETBSD /* * Driver for native NetBSD audio(4). - * vedge@vedge.com.ar. + * nia@NetBSD.org */ #include @@ -45,18 +45,15 @@ /* #define DEBUG_AUDIO */ -static void -NETBSDAUDIO_DetectDevices(void) +static void NETBSDAUDIO_DetectDevices(void) { SDL_EnumUnixAudioDevices(0, NULL); } - -static void -NETBSDAUDIO_Status(_THIS) +static void NETBSDAUDIO_Status(_THIS) { #ifdef DEBUG_AUDIO - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ audio_info_t info; const struct audio_prinfo *prinfo; @@ -118,13 +115,12 @@ NETBSDAUDIO_Status(_THIS) "", this->spec.format, this->spec.size); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ + #endif /* DEBUG_AUDIO */ } - -static void -NETBSDAUDIO_PlayDevice(_THIS) +static void NETBSDAUDIO_PlayDevice(_THIS) { struct SDL_PrivateAudioData *h = this->hidden; int written; @@ -143,17 +139,14 @@ NETBSDAUDIO_PlayDevice(_THIS) #endif } -static Uint8 * -NETBSDAUDIO_GetDeviceBuf(_THIS) +static Uint8 *NETBSDAUDIO_GetDeviceBuf(_THIS) { - return (this->hidden->mixbuf); + return this->hidden->mixbuf; } - -static int -NETBSDAUDIO_CaptureFromDevice(_THIS, void *_buffer, int buflen) +static int NETBSDAUDIO_CaptureFromDevice(_THIS, void *_buffer, int buflen) { - Uint8 *buffer = (Uint8 *) _buffer; + Uint8 *buffer = (Uint8 *)_buffer; int br; br = read(this->hidden->audio_fd, buffer, buflen); @@ -169,30 +162,28 @@ NETBSDAUDIO_CaptureFromDevice(_THIS, void *_buffer, int buflen) return 0; } -static void -NETBSDAUDIO_FlushCapture(_THIS) +static void NETBSDAUDIO_FlushCapture(_THIS) { audio_info_t info; size_t remain; Uint8 buf[512]; if (ioctl(this->hidden->audio_fd, AUDIO_GETINFO, &info) < 0) { - return; /* oh well. */ + return; /* oh well. */ } - remain = (size_t) (info.record.samples * (SDL_AUDIO_BITSIZE(this->spec.format) / 8)); + remain = (size_t)(info.record.samples * (SDL_AUDIO_BITSIZE(this->spec.format) / 8)); while (remain > 0) { - const size_t len = SDL_min(sizeof (buf), remain); + const size_t len = SDL_min(sizeof(buf), remain); const int br = read(this->hidden->audio_fd, buf, len); if (br <= 0) { - return; /* oh well. */ + return; /* oh well. */ } remain -= br; } } -static void -NETBSDAUDIO_CloseDevice(_THIS) +static void NETBSDAUDIO_CloseDevice(_THIS) { if (this->hidden->audio_fd >= 0) { close(this->hidden->audio_fd); @@ -201,99 +192,111 @@ NETBSDAUDIO_CloseDevice(_THIS) SDL_free(this->hidden); } -static int -NETBSDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) +static int NETBSDAUDIO_OpenDevice(_THIS, const char *devname) { - SDL_AudioFormat format = 0; - audio_info_t info; + SDL_bool iscapture = this->iscapture; + SDL_AudioFormat test_format; + int encoding = AUDIO_ENCODING_NONE; + audio_info_t info, hwinfo; struct audio_prinfo *prinfo = iscapture ? &info.record : &info.play; /* We don't care what the devname is...we'll try to open anything. */ /* ...but default to first name in the list... */ - if (devname == NULL) { + if (!devname) { devname = SDL_GetAudioDeviceName(0, iscapture); - if (devname == NULL) { + if (!devname) { return SDL_SetError("No such audio device"); } } /* Initialize all variables that we clean on shutdown */ - this->hidden = (struct SDL_PrivateAudioData *) - SDL_malloc((sizeof *this->hidden)); - if (this->hidden == NULL) { + this->hidden = (struct SDL_PrivateAudioData *) SDL_malloc(sizeof(*this->hidden)); + if (!this->hidden) { return SDL_OutOfMemory(); } SDL_zerop(this->hidden); /* Open the audio device */ - this->hidden->audio_fd = open(devname, iscapture ? O_RDONLY : O_WRONLY); + this->hidden->audio_fd = open(devname, (iscapture ? O_RDONLY : O_WRONLY) | O_CLOEXEC); if (this->hidden->audio_fd < 0) { return SDL_SetError("Couldn't open %s: %s", devname, strerror(errno)); } AUDIO_INITINFO(&info); - prinfo->encoding = AUDIO_ENCODING_NONE; - - for (format = SDL_FirstAudioFormat(this->spec.format); format;) { - switch (format) { - case AUDIO_U8: - prinfo->encoding = AUDIO_ENCODING_ULINEAR; - prinfo->precision = 8; - break; - case AUDIO_S8: - prinfo->encoding = AUDIO_ENCODING_SLINEAR; - prinfo->precision = 8; - break; - case AUDIO_S16LSB: - prinfo->encoding = AUDIO_ENCODING_SLINEAR_LE; - prinfo->precision = 16; - break; - case AUDIO_S16MSB: - prinfo->encoding = AUDIO_ENCODING_SLINEAR_BE; - prinfo->precision = 16; - break; - case AUDIO_U16LSB: - prinfo->encoding = AUDIO_ENCODING_ULINEAR_LE; - prinfo->precision = 16; - break; - case AUDIO_U16MSB: - prinfo->encoding = AUDIO_ENCODING_ULINEAR_BE; - prinfo->precision = 16; - break; - } - if (prinfo->encoding != AUDIO_ENCODING_NONE) { - break; - } - format = SDL_NextAudioFormat(); +#ifdef AUDIO_GETFORMAT /* Introduced in NetBSD 9.0 */ + if (ioctl(this->hidden->audio_fd, AUDIO_GETFORMAT, &hwinfo) != -1) { + /* + * Use the device's native sample rate so the kernel doesn't have to + * resample. + */ + this->spec.freq = iscapture ? hwinfo.record.sample_rate : hwinfo.play.sample_rate; } +#endif - if (prinfo->encoding == AUDIO_ENCODING_NONE) { - return SDL_SetError("No supported encoding for 0x%x", this->spec.format); - } - - this->spec.format = format; - - /* Calculate spec parameters based on our chosen format */ - SDL_CalculateAudioSpec(&this->spec); - - info.mode = iscapture ? AUMODE_RECORD : AUMODE_PLAY; - info.blocksize = this->spec.size; - info.hiwat = 5; - info.lowat = 3; prinfo->sample_rate = this->spec.freq; prinfo->channels = this->spec.channels; - (void) ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info); - (void) ioctl(this->hidden->audio_fd, AUDIO_GETINFO, &info); + for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) { + switch (test_format) { + case AUDIO_U8: + encoding = AUDIO_ENCODING_ULINEAR; + break; + case AUDIO_S8: + encoding = AUDIO_ENCODING_SLINEAR; + break; + case AUDIO_S16LSB: + encoding = AUDIO_ENCODING_SLINEAR_LE; + break; + case AUDIO_S16MSB: + encoding = AUDIO_ENCODING_SLINEAR_BE; + break; + case AUDIO_U16LSB: + encoding = AUDIO_ENCODING_ULINEAR_LE; + break; + case AUDIO_U16MSB: + encoding = AUDIO_ENCODING_ULINEAR_BE; + break; + case AUDIO_S32LSB: + encoding = AUDIO_ENCODING_SLINEAR_LE; + break; + case AUDIO_S32MSB: + encoding = AUDIO_ENCODING_SLINEAR_BE; + break; + default: + continue; + } + break; + } + + if (!test_format) { + return SDL_SetError("%s: Unsupported audio format", "netbsd"); + } + prinfo->encoding = encoding; + prinfo->precision = SDL_AUDIO_BITSIZE(test_format); + + info.hiwat = 5; + info.lowat = 3; + if (ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info) < 0) { + return SDL_SetError("AUDIO_SETINFO failed for %s: %s", devname, strerror(errno)); + } + + if (ioctl(this->hidden->audio_fd, AUDIO_GETINFO, &info) < 0) { + return SDL_SetError("AUDIO_GETINFO failed for %s: %s", devname, strerror(errno)); + } + + /* Final spec used for the device. */ + this->spec.format = test_format; this->spec.freq = prinfo->sample_rate; this->spec.channels = prinfo->channels; + SDL_CalculateAudioSpec(&this->spec); + if (!iscapture) { /* Allocate mixing buffer */ this->hidden->mixlen = this->spec.size; - this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen); - if (this->hidden->mixbuf == NULL) { + this->hidden->mixbuf = (Uint8 *)SDL_malloc(this->hidden->mixlen); + if (!this->hidden->mixbuf) { return SDL_OutOfMemory(); } SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size); @@ -305,8 +308,7 @@ NETBSDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) return 0; } -static int -NETBSDAUDIO_Init(SDL_AudioDriverImpl * impl) +static SDL_bool NETBSDAUDIO_Init(SDL_AudioDriverImpl *impl) { /* Set the function pointers */ impl->DetectDevices = NETBSDAUDIO_DetectDevices; @@ -318,14 +320,13 @@ NETBSDAUDIO_Init(SDL_AudioDriverImpl * impl) impl->FlushCapture = NETBSDAUDIO_FlushCapture; impl->HasCaptureSupport = SDL_TRUE; - impl->AllowsArbitraryDeviceNames = 1; + impl->AllowsArbitraryDeviceNames = SDL_TRUE; - return 1; /* this audio target is available. */ + return SDL_TRUE; /* this audio target is available. */ } - AudioBootStrap NETBSDAUDIO_bootstrap = { - "netbsd", "NetBSD audio", NETBSDAUDIO_Init, 0 + "netbsd", "NetBSD audio", NETBSDAUDIO_Init, SDL_FALSE }; #endif /* SDL_AUDIO_DRIVER_NETBSD */ diff --git a/SDL2-2.0.12/src/audio/netbsd/SDL_netbsdaudio.h b/SDL2-2.30.5/src/audio/netbsd/SDL_netbsdaudio.h similarity index 88% rename from SDL2-2.0.12/src/audio/netbsd/SDL_netbsdaudio.h rename to SDL2-2.30.5/src/audio/netbsd/SDL_netbsdaudio.h index cc58fec..81fd4e6 100644 --- a/SDL2-2.0.12/src/audio/netbsd/SDL_netbsdaudio.h +++ b/SDL2-2.30.5/src/audio/netbsd/SDL_netbsdaudio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -25,7 +25,7 @@ #include "../SDL_sysaudio.h" -#define _THIS SDL_AudioDevice *this +#define _THIS SDL_AudioDevice *this struct SDL_PrivateAudioData { @@ -41,7 +41,7 @@ struct SDL_PrivateAudioData float next_frame; }; -#define FUDGE_TICKS 10 /* The scheduler overhead ticks per frame */ +#define FUDGE_TICKS 10 /* The scheduler overhead ticks per frame */ #endif /* SDL_netbsdaudio_h_ */ diff --git a/SDL2-2.0.12/src/audio/openslES/SDL_openslES.c b/SDL2-2.30.5/src/audio/openslES/SDL_openslES.c similarity index 73% rename from SDL2-2.0.12/src/audio/openslES/SDL_openslES.c rename to SDL2-2.30.5/src/audio/openslES/SDL_openslES.c index b4b5506..d93fb5a 100644 --- a/SDL2-2.0.12/src/audio/openslES/SDL_openslES.c +++ b/SDL2-2.30.5/src/audio/openslES/SDL_openslES.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,13 +20,12 @@ */ #include "../../SDL_internal.h" -#if SDL_AUDIO_DRIVER_OPENSLES +#ifdef SDL_AUDIO_DRIVER_OPENSLES /* For more discussion of low latency audio on Android, see this: https://googlesamples.github.io/android-audio-high-performance/guides/opensl_es.html */ -#include "SDL_assert.h" #include "SDL_audio.h" #include "../SDL_audio_c.h" #include "../../core/android/SDL_android.h" @@ -39,9 +38,9 @@ #include #if 0 -#define LOG_TAG "SDL_openslES" -#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) -#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) +#define LOG_TAG "SDL_openslES" +#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) +#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) //#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE,LOG_TAG,__VA_ARGS__) #define LOGV(...) #else @@ -71,36 +70,36 @@ #define SL_SPEAKER_TOP_BACK_RIGHT ((SLuint32) 0x00020000) */ #define SL_ANDROID_SPEAKER_STEREO (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT) -#define SL_ANDROID_SPEAKER_QUAD (SL_ANDROID_SPEAKER_STEREO | SL_SPEAKER_BACK_LEFT | SL_SPEAKER_BACK_RIGHT) -#define SL_ANDROID_SPEAKER_5DOT1 (SL_ANDROID_SPEAKER_QUAD | SL_SPEAKER_FRONT_CENTER | SL_SPEAKER_LOW_FREQUENCY) -#define SL_ANDROID_SPEAKER_7DOT1 (SL_ANDROID_SPEAKER_5DOT1 | SL_SPEAKER_SIDE_LEFT | SL_SPEAKER_SIDE_RIGHT) +#define SL_ANDROID_SPEAKER_QUAD (SL_ANDROID_SPEAKER_STEREO | SL_SPEAKER_BACK_LEFT | SL_SPEAKER_BACK_RIGHT) +#define SL_ANDROID_SPEAKER_5DOT1 (SL_ANDROID_SPEAKER_QUAD | SL_SPEAKER_FRONT_CENTER | SL_SPEAKER_LOW_FREQUENCY) +#define SL_ANDROID_SPEAKER_7DOT1 (SL_ANDROID_SPEAKER_5DOT1 | SL_SPEAKER_SIDE_LEFT | SL_SPEAKER_SIDE_RIGHT) /* engine interfaces */ -static SLObjectItf engineObject; -static SLEngineItf engineEngine; +static SLObjectItf engineObject = NULL; +static SLEngineItf engineEngine = NULL; /* output mix interfaces */ -static SLObjectItf outputMixObject; +static SLObjectItf outputMixObject = NULL; /* buffer queue player interfaces */ -static SLObjectItf bqPlayerObject; -static SLPlayItf bqPlayerPlay; -static SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue; +static SLObjectItf bqPlayerObject = NULL; +static SLPlayItf bqPlayerPlay = NULL; +static SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue = NULL; #if 0 static SLVolumeItf bqPlayerVolume; #endif /* recorder interfaces */ -static SLObjectItf recorderObject; -static SLRecordItf recorderRecord; -static SLAndroidSimpleBufferQueueItf recorderBufferQueue; +static SLObjectItf recorderObject = NULL; +static SLRecordItf recorderRecord = NULL; +static SLAndroidSimpleBufferQueueItf recorderBufferQueue = NULL; #if 0 static const char *sldevaudiorecorderstr = "SLES Audio Recorder"; static const char *sldevaudioplayerstr = "SLES Audio Player"; -#define SLES_DEV_AUDIO_RECORDER sldevaudiorecorderstr -#define SLES_DEV_AUDIO_PLAYER sldevaudioplayerstr +#define SLES_DEV_AUDIO_RECORDER sldevaudiorecorderstr +#define SLES_DEV_AUDIO_PLAYER sldevaudioplayerstr static void openslES_DetectDevices( int iscapture ) { LOGI( "openSLES_DetectDevices()" ); @@ -129,9 +128,10 @@ static void openslES_DestroyEngine(void) } } -static int -openslES_CreateEngine(void) +static int openslES_CreateEngine(void) { + const SLInterfaceID ids[1] = { SL_IID_VOLUME }; + const SLboolean req[1] = { SL_BOOLEAN_FALSE }; SLresult result; LOGI("openSLES_CreateEngine()"); @@ -161,8 +161,6 @@ openslES_CreateEngine(void) LOGI("EngineGetInterface OK"); /* create output mix */ - const SLInterfaceID ids[1] = { SL_IID_VOLUME }; - const SLboolean req[1] = { SL_BOOLEAN_FALSE }; result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 1, ids, req); if (SL_RESULT_SUCCESS != result) { LOGE("CreateOutputMix failed: %d", result); @@ -184,17 +182,15 @@ error: } /* this callback handler is called every time a buffer finishes recording */ -static void -bqRecorderCallback(SLAndroidSimpleBufferQueueItf bq, void *context) +static void bqRecorderCallback(SLAndroidSimpleBufferQueueItf bq, void *context) { - struct SDL_PrivateAudioData *audiodata = (struct SDL_PrivateAudioData *) context; + struct SDL_PrivateAudioData *audiodata = (struct SDL_PrivateAudioData *)context; LOGV("SLES: Recording Callback"); SDL_SemPost(audiodata->playsem); } -static void -openslES_DestroyPCMRecorder(_THIS) +static void openslES_DestroyPCMRecorder(_THIS) { struct SDL_PrivateAudioData *audiodata = this->hidden; SLresult result; @@ -225,11 +221,16 @@ openslES_DestroyPCMRecorder(_THIS) } } -static int -openslES_CreatePCMRecorder(_THIS) +static int openslES_CreatePCMRecorder(_THIS) { struct SDL_PrivateAudioData *audiodata = this->hidden; SLDataFormat_PCM format_pcm; + SLDataLocator_AndroidSimpleBufferQueue loc_bufq; + SLDataSink audioSnk; + SLDataLocator_IODevice loc_dev; + SLDataSource audioSrc; + const SLInterfaceID ids[1] = { SL_IID_ANDROIDSIMPLEBUFFERQUEUE }; + const SLboolean req[1] = { SL_BOOLEAN_TRUE }; SLresult result; int i; @@ -247,35 +248,34 @@ openslES_CreatePCMRecorder(_THIS) SDL_CalculateAudioSpec(&this->spec); LOGI("Try to open %u hz %u bit chan %u %s samples %u", - this->spec.freq, SDL_AUDIO_BITSIZE(this->spec.format), - this->spec.channels, (this->spec.format & 0x1000) ? "BE" : "LE", this->spec.samples); + this->spec.freq, SDL_AUDIO_BITSIZE(this->spec.format), + this->spec.channels, (this->spec.format & 0x1000) ? "BE" : "LE", this->spec.samples); /* configure audio source */ - SLDataLocator_IODevice loc_dev = {SL_DATALOCATOR_IODEVICE, SL_IODEVICE_AUDIOINPUT, SL_DEFAULTDEVICEID_AUDIOINPUT, NULL}; - SLDataSource audioSrc = {&loc_dev, NULL}; + loc_dev.locatorType = SL_DATALOCATOR_IODEVICE; + loc_dev.deviceType = SL_IODEVICE_AUDIOINPUT; + loc_dev.deviceID = SL_DEFAULTDEVICEID_AUDIOINPUT; + loc_dev.device = NULL; + audioSrc.pLocator = &loc_dev; + audioSrc.pFormat = NULL; /* configure audio sink */ - SLDataLocator_AndroidSimpleBufferQueue loc_bufq = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, NUM_BUFFERS }; + loc_bufq.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE; + loc_bufq.numBuffers = NUM_BUFFERS; - format_pcm.formatType = SL_DATAFORMAT_PCM; - format_pcm.numChannels = this->spec.channels; - format_pcm.samplesPerSec = this->spec.freq * 1000; /* / kilo Hz to milli Hz */ + format_pcm.formatType = SL_DATAFORMAT_PCM; + format_pcm.numChannels = this->spec.channels; + format_pcm.samplesPerSec = this->spec.freq * 1000; /* / kilo Hz to milli Hz */ format_pcm.bitsPerSample = SDL_AUDIO_BITSIZE(this->spec.format); format_pcm.containerSize = SDL_AUDIO_BITSIZE(this->spec.format); - format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN; - format_pcm.channelMask = SL_SPEAKER_FRONT_CENTER; + format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN; + format_pcm.channelMask = SL_SPEAKER_FRONT_CENTER; - SLDataSink audioSnk = { &loc_bufq, &format_pcm }; + audioSnk.pLocator = &loc_bufq; + audioSnk.pFormat = &format_pcm; /* create audio recorder */ /* (requires the RECORD_AUDIO permission) */ - const SLInterfaceID ids[1] = { - SL_IID_ANDROIDSIMPLEBUFFERQUEUE, - }; - const SLboolean req[1] = { - SL_BOOLEAN_TRUE, - }; - result = (*engineEngine)->CreateAudioRecorder(engineEngine, &recorderObject, &audioSrc, &audioSnk, 1, ids, req); if (SL_RESULT_SUCCESS != result) { LOGE("CreateAudioRecorder failed: %d", result); @@ -319,8 +319,8 @@ openslES_CreatePCMRecorder(_THIS) } /* Create the sound buffers */ - audiodata->mixbuff = (Uint8 *) SDL_malloc(NUM_BUFFERS * this->spec.size); - if (audiodata->mixbuff == NULL) { + audiodata->mixbuff = (Uint8 *)SDL_malloc(NUM_BUFFERS * this->spec.size); + if (!audiodata->mixbuff) { LOGE("mixbuffer allocate - out of memory"); goto failed; } @@ -355,24 +355,19 @@ openslES_CreatePCMRecorder(_THIS) return 0; failed: - - openslES_DestroyPCMRecorder(this); - return SDL_SetError("Open device failed!"); } /* this callback handler is called every time a buffer finishes playing */ -static void -bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context) +static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context) { - struct SDL_PrivateAudioData *audiodata = (struct SDL_PrivateAudioData *) context; + struct SDL_PrivateAudioData *audiodata = (struct SDL_PrivateAudioData *)context; LOGV("SLES: Playback Callback"); SDL_SemPost(audiodata->playsem); } -static void -openslES_DestroyPCMPlayer(_THIS) +static void openslES_DestroyPCMPlayer(_THIS) { struct SDL_PrivateAudioData *audiodata = this->hidden; SLresult result; @@ -387,7 +382,6 @@ openslES_DestroyPCMPlayer(_THIS) /* destroy buffer queue audio player object, and invalidate all associated interfaces */ if (bqPlayerObject != NULL) { - (*bqPlayerObject)->Destroy(bqPlayerObject); bqPlayerObject = NULL; @@ -405,11 +399,17 @@ openslES_DestroyPCMPlayer(_THIS) } } -static int -openslES_CreatePCMPlayer(_THIS) +static int openslES_CreatePCMPlayer(_THIS) { struct SDL_PrivateAudioData *audiodata = this->hidden; + SLDataLocator_AndroidSimpleBufferQueue loc_bufq; SLDataFormat_PCM format_pcm; + SLAndroidDataFormat_PCM_EX format_pcm_ex; + SLDataSource audioSrc; + SLDataSink audioSnk; + SLDataLocator_OutputMix loc_outmix; + const SLInterfaceID ids[2] = { SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_VOLUME }; + const SLboolean req[2] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_FALSE }; SLresult result; int i; @@ -417,39 +417,39 @@ openslES_CreatePCMPlayer(_THIS) it can be done as described here: https://developer.android.com/ndk/guides/audio/opensl/android-extensions.html#floating-point */ -#if 1 - /* Just go with signed 16-bit audio as it's the most compatible */ - this->spec.format = AUDIO_S16SYS; -#else - SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format); - while (test_format != 0) { - if (SDL_AUDIO_ISSIGNED(test_format) && SDL_AUDIO_ISINT(test_format)) { - break; + if (SDL_GetAndroidSDKVersion() >= 21) { + SDL_AudioFormat test_format; + for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) { + if (SDL_AUDIO_ISSIGNED(test_format)) { + break; + } } - test_format = SDL_NextAudioFormat(); - } - if (test_format == 0) { - /* Didn't find a compatible format : */ - LOGI( "No compatible audio format, using signed 16-bit audio" ); - test_format = AUDIO_S16SYS; + if (!test_format) { + /* Didn't find a compatible format : */ + LOGI("No compatible audio format, using signed 16-bit audio"); + test_format = AUDIO_S16SYS; + } + this->spec.format = test_format; + } else { + /* Just go with signed 16-bit audio as it's the most compatible */ + this->spec.format = AUDIO_S16SYS; } - this->spec.format = test_format; -#endif /* Update the fragment size as size in bytes */ SDL_CalculateAudioSpec(&this->spec); - LOGI("Try to open %u hz %u bit chan %u %s samples %u", - this->spec.freq, SDL_AUDIO_BITSIZE(this->spec.format), - this->spec.channels, (this->spec.format & 0x1000) ? "BE" : "LE", this->spec.samples); + LOGI("Try to open %u hz %s %u bit chan %u %s samples %u", + this->spec.freq, SDL_AUDIO_ISFLOAT(this->spec.format) ? "float" : "pcm", SDL_AUDIO_BITSIZE(this->spec.format), + this->spec.channels, (this->spec.format & 0x1000) ? "BE" : "LE", this->spec.samples); /* configure audio source */ - SLDataLocator_AndroidSimpleBufferQueue loc_bufq = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, NUM_BUFFERS }; + loc_bufq.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE; + loc_bufq.numBuffers = NUM_BUFFERS; - format_pcm.formatType = SL_DATAFORMAT_PCM; - format_pcm.numChannels = this->spec.channels; - format_pcm.samplesPerSec = this->spec.freq * 1000; /* / kilo Hz to milli Hz */ + format_pcm.formatType = SL_DATAFORMAT_PCM; + format_pcm.numChannels = this->spec.channels; + format_pcm.samplesPerSec = this->spec.freq * 1000; /* / kilo Hz to milli Hz */ format_pcm.bitsPerSample = SDL_AUDIO_BITSIZE(this->spec.format); format_pcm.containerSize = SDL_AUDIO_BITSIZE(this->spec.format); @@ -459,8 +459,7 @@ openslES_CreatePCMPlayer(_THIS) format_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN; } - switch (this->spec.channels) - { + switch (this->spec.channels) { case 1: format_pcm.channelMask = SL_SPEAKER_FRONT_LEFT; break; @@ -492,23 +491,28 @@ openslES_CreatePCMPlayer(_THIS) break; } - SLDataSource audioSrc = { &loc_bufq, &format_pcm }; + if (SDL_AUDIO_ISFLOAT(this->spec.format)) { + /* Copy all setup into PCM EX structure */ + format_pcm_ex.formatType = SL_ANDROID_DATAFORMAT_PCM_EX; + format_pcm_ex.endianness = format_pcm.endianness; + format_pcm_ex.channelMask = format_pcm.channelMask; + format_pcm_ex.numChannels = format_pcm.numChannels; + format_pcm_ex.sampleRate = format_pcm.samplesPerSec; + format_pcm_ex.bitsPerSample = format_pcm.bitsPerSample; + format_pcm_ex.containerSize = format_pcm.containerSize; + format_pcm_ex.representation = SL_ANDROID_PCM_REPRESENTATION_FLOAT; + } + + audioSrc.pLocator = &loc_bufq; + audioSrc.pFormat = SDL_AUDIO_ISFLOAT(this->spec.format) ? (void *)&format_pcm_ex : (void *)&format_pcm; /* configure audio sink */ - SLDataLocator_OutputMix loc_outmix = { SL_DATALOCATOR_OUTPUTMIX, outputMixObject }; - SLDataSink audioSnk = { &loc_outmix, NULL }; + loc_outmix.locatorType = SL_DATALOCATOR_OUTPUTMIX; + loc_outmix.outputMix = outputMixObject; + audioSnk.pLocator = &loc_outmix; + audioSnk.pFormat = NULL; /* create audio player */ - const SLInterfaceID ids[2] = { - SL_IID_ANDROIDSIMPLEBUFFERQUEUE, - SL_IID_VOLUME - }; - - const SLboolean req[2] = { - SL_BOOLEAN_TRUE, - SL_BOOLEAN_FALSE, - }; - result = (*engineEngine)->CreateAudioPlayer(engineEngine, &bqPlayerObject, &audioSrc, &audioSnk, 2, ids, req); if (SL_RESULT_SUCCESS != result) { LOGE("CreateAudioPlayer failed: %d", result); @@ -561,8 +565,8 @@ openslES_CreatePCMPlayer(_THIS) } /* Create the sound buffers */ - audiodata->mixbuff = (Uint8 *) SDL_malloc(NUM_BUFFERS * this->spec.size); - if (audiodata->mixbuff == NULL) { + audiodata->mixbuff = (Uint8 *)SDL_malloc(NUM_BUFFERS * this->spec.size); + if (!audiodata->mixbuff) { LOGE("mixbuffer allocate - out of memory"); goto failed; } @@ -581,31 +585,41 @@ openslES_CreatePCMPlayer(_THIS) return 0; failed: - - openslES_DestroyPCMPlayer(this); - - return SDL_SetError("Open device failed!"); + return -1; } -static int -openslES_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) +static int openslES_OpenDevice(_THIS, const char *devname) { - this->hidden = (struct SDL_PrivateAudioData *) SDL_calloc(1, (sizeof *this->hidden)); - if (this->hidden == NULL) { + this->hidden = (struct SDL_PrivateAudioData *)SDL_calloc(1, sizeof(*this->hidden)); + if (!this->hidden) { return SDL_OutOfMemory(); } - if (iscapture) { + if (this->iscapture) { LOGI("openslES_OpenDevice() %s for capture", devname); return openslES_CreatePCMRecorder(this); } else { + int ret; LOGI("openslES_OpenDevice() %s for playing", devname); - return openslES_CreatePCMPlayer(this); + ret = openslES_CreatePCMPlayer(this); + if (ret < 0) { + /* Another attempt to open the device with a lower frequency */ + if (this->spec.freq > 48000) { + openslES_DestroyPCMPlayer(this); + this->spec.freq = 48000; + ret = openslES_CreatePCMPlayer(this); + } + } + + if (ret == 0) { + return 0; + } else { + return SDL_SetError("Open device failed!"); + } } } -static void -openslES_WaitDevice(_THIS) +static void openslES_WaitDevice(_THIS) { struct SDL_PrivateAudioData *audiodata = this->hidden; @@ -615,8 +629,7 @@ openslES_WaitDevice(_THIS) SDL_SemWait(audiodata->playsem); } -static void -openslES_PlayDevice(_THIS) +static void openslES_PlayDevice(_THIS) { struct SDL_PrivateAudioData *audiodata = this->hidden; SLresult result; @@ -650,8 +663,7 @@ openslES_PlayDevice(_THIS) /* */ /* okay.. */ -static Uint8 * -openslES_GetDeviceBuf(_THIS) +static Uint8 *openslES_GetDeviceBuf(_THIS) { struct SDL_PrivateAudioData *audiodata = this->hidden; @@ -659,8 +671,7 @@ openslES_GetDeviceBuf(_THIS) return audiodata->pmixbuff[audiodata->next_buffer]; } -static int -openslES_CaptureFromDevice(_THIS, void *buffer, int buflen) +static int openslES_CaptureFromDevice(_THIS, void *buffer, int buflen) { struct SDL_PrivateAudioData *audiodata = this->hidden; SLresult result; @@ -687,8 +698,7 @@ openslES_CaptureFromDevice(_THIS, void *buffer, int buflen) return this->spec.size; } -static void -openslES_CloseDevice(_THIS) +static void openslES_CloseDevice(_THIS) { /* struct SDL_PrivateAudioData *audiodata = this->hidden; */ @@ -703,40 +713,39 @@ openslES_CloseDevice(_THIS) SDL_free(this->hidden); } -static int -openslES_Init(SDL_AudioDriverImpl * impl) +static SDL_bool openslES_Init(SDL_AudioDriverImpl *impl) { LOGI("openslES_Init() called"); if (!openslES_CreateEngine()) { - return 0; + return SDL_FALSE; } LOGI("openslES_Init() - set pointers"); /* Set the function pointers */ /* impl->DetectDevices = openslES_DetectDevices; */ - impl->OpenDevice = openslES_OpenDevice; - impl->WaitDevice = openslES_WaitDevice; - impl->PlayDevice = openslES_PlayDevice; - impl->GetDeviceBuf = openslES_GetDeviceBuf; + impl->OpenDevice = openslES_OpenDevice; + impl->WaitDevice = openslES_WaitDevice; + impl->PlayDevice = openslES_PlayDevice; + impl->GetDeviceBuf = openslES_GetDeviceBuf; impl->CaptureFromDevice = openslES_CaptureFromDevice; - impl->CloseDevice = openslES_CloseDevice; - impl->Deinitialize = openslES_DestroyEngine; + impl->CloseDevice = openslES_CloseDevice; + impl->Deinitialize = openslES_DestroyEngine; /* and the capabilities */ - impl->HasCaptureSupport = 1; - impl->OnlyHasDefaultOutputDevice = 1; - impl->OnlyHasDefaultCaptureDevice = 1; + impl->HasCaptureSupport = SDL_TRUE; + impl->OnlyHasDefaultOutputDevice = SDL_TRUE; + impl->OnlyHasDefaultCaptureDevice = SDL_TRUE; LOGI("openslES_Init() - success"); /* this audio target is available. */ - return 1; + return SDL_TRUE; } AudioBootStrap openslES_bootstrap = { - "openslES", "opensl ES audio driver", openslES_Init, 0 + "openslES", "opensl ES audio driver", openslES_Init, SDL_FALSE }; void openslES_ResumeDevices(void) diff --git a/SDL2-2.0.12/src/audio/openslES/SDL_openslES.h b/SDL2-2.30.5/src/audio/openslES/SDL_openslES.h similarity index 83% rename from SDL2-2.0.12/src/audio/openslES/SDL_openslES.h rename to SDL2-2.30.5/src/audio/openslES/SDL_openslES.h index 542870a..b9943d8 100644 --- a/SDL2-2.0.12/src/audio/openslES/SDL_openslES.h +++ b/SDL2-2.30.5/src/audio/openslES/SDL_openslES.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,15 +26,15 @@ #include "../SDL_sysaudio.h" /* Hidden "this" pointer for the audio functions */ -#define _THIS SDL_AudioDevice *this +#define _THIS SDL_AudioDevice *this -#define NUM_BUFFERS 2 /* -- Don't lower this! */ +#define NUM_BUFFERS 2 /* -- Don't lower this! */ struct SDL_PrivateAudioData { - Uint8 *mixbuff; - int next_buffer; - Uint8 *pmixbuff[NUM_BUFFERS]; + Uint8 *mixbuff; + int next_buffer; + Uint8 *pmixbuff[NUM_BUFFERS]; SDL_sem *playsem; }; diff --git a/SDL2-2.30.5/src/audio/os2/SDL_os2audio.c b/SDL2-2.30.5/src/audio/os2/SDL_os2audio.c new file mode 100644 index 0000000..c61c641 --- /dev/null +++ b/SDL2-2.30.5/src/audio/os2/SDL_os2audio.c @@ -0,0 +1,601 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_AUDIO_DRIVER_OS2 + +/* Allow access to a raw mixing buffer */ + +#include "../../core/os2/SDL_os2.h" + +#include "SDL_audio.h" +#include "../SDL_audio_c.h" +#include "SDL_os2audio.h" + +static PMCI_MIX_BUFFER _getNextBuffer(SDL_PrivateAudioData *pAData, PMCI_MIX_BUFFER pBuffer) +{ + PMCI_MIX_BUFFER pFirstBuffer = &pAData->aMixBuffers[0]; + PMCI_MIX_BUFFER pLastBuffer = &pAData->aMixBuffers[pAData->cMixBuffers -1]; + return (pBuffer == pLastBuffer ? pFirstBuffer : pBuffer+1); +} + +static ULONG _getEnvULong(const char *name, ULONG ulMax, ULONG ulDefault) +{ + ULONG ulValue; + char* end; + char* envval = SDL_getenv(name); + + if (!envval) + return ulDefault; + + ulValue = SDL_strtoul(envval, &end, 10); + return (end == envval) || (ulValue > ulMax)? ulDefault : ulMax; +} + +static int _MCIError(const char *func, ULONG ulResult) +{ + CHAR acBuf[128]; + mciGetErrorString(ulResult, acBuf, sizeof(acBuf)); + return SDL_SetError("[%s] %s", func, acBuf); +} + +static void _mixIOError(const char *function, ULONG ulRC) +{ + debug_os2("%s() - failed, rc = 0x%lX (%s)", + function, ulRC, + (ulRC == MCIERR_INVALID_MODE) ? "Mixer mode does not match request" : + (ulRC == MCIERR_INVALID_BUFFER) ? "Caller sent an invalid buffer" : "unknown"); +} + +static LONG APIENTRY cbAudioWriteEvent(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer, + ULONG ulFlags) +{ + SDL_AudioDevice *_this = (SDL_AudioDevice *)pBuffer->ulUserParm; + SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)_this->hidden; + ULONG ulRC; + + debug_os2("cbAudioWriteEvent: ulStatus = %lu, pBuffer = %p, ulFlags = %#lX",ulStatus,pBuffer,ulFlags); + + if (pAData->ulState == 2) + { + return 0; + } + + if (ulFlags != MIX_WRITE_COMPLETE) { + debug_os2("flags = 0x%lX", ulFlags); + return 0; + } + + pAData->pDrainBuffer = pBuffer; + ulRC = pAData->stMCIMixSetup.pmixWrite(pAData->stMCIMixSetup.ulMixHandle, + pAData->pDrainBuffer, 1); + if (ulRC != MCIERR_SUCCESS) { + _mixIOError("pmixWrite", ulRC); + return 0; + } + + ulRC = DosPostEventSem(pAData->hevBuf); + if (ulRC != NO_ERROR && ulRC != ERROR_ALREADY_POSTED) { + debug_os2("DosPostEventSem(), rc = %lu", ulRC); + } + + return 1; /* return value doesn't seem to matter. */ +} + +static LONG APIENTRY cbAudioReadEvent(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer, + ULONG ulFlags) +{ + SDL_AudioDevice *_this = (SDL_AudioDevice *)pBuffer->ulUserParm; + SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)_this->hidden; + ULONG ulRC; + + debug_os2("cbAudioReadEvent: ulStatus = %lu, pBuffer = %p, ulFlags = %#lX",ulStatus,pBuffer,ulFlags); + + if (pAData->ulState == 2) + { + return 0; + } + + if (ulFlags != MIX_READ_COMPLETE) { + debug_os2("flags = 0x%lX", ulFlags); + return 0; + } + + pAData->pFillBuffer = pBuffer; + if (pAData->pFillBuffer == pAData->aMixBuffers) + { + ulRC = pAData->stMCIMixSetup.pmixRead(pAData->stMCIMixSetup.ulMixHandle, + pAData->pFillBuffer, pAData->cMixBuffers); + if (ulRC != MCIERR_SUCCESS) { + _mixIOError("pmixRead", ulRC); + return 0; + } + } + + ulRC = DosPostEventSem(pAData->hevBuf); + if (ulRC != NO_ERROR && ulRC != ERROR_ALREADY_POSTED) { + debug_os2("DosPostEventSem(), rc = %lu", ulRC); + } + + return 1; +} + + +static void OS2_DetectDevices(void) +{ + MCI_SYSINFO_PARMS stMCISysInfo; + CHAR acBuf[256]; + ULONG ulDevicesNum; + MCI_SYSINFO_LOGDEVICE stLogDevice; + MCI_SYSINFO_PARMS stSysInfoParams; + ULONG ulRC; + ULONG ulNumber; + MCI_GETDEVCAPS_PARMS stDevCapsParams; + MCI_OPEN_PARMS stMCIOpen; + MCI_GENERIC_PARMS stMCIGenericParams; + + SDL_memset(&stMCISysInfo, 0, sizeof(stMCISysInfo)); + acBuf[0] = '\0'; + stMCISysInfo.pszReturn = acBuf; + stMCISysInfo.ulRetSize = sizeof(acBuf); + stMCISysInfo.usDeviceType = MCI_DEVTYPE_AUDIO_AMPMIX; + ulRC = mciSendCommand(0, MCI_SYSINFO, MCI_WAIT | MCI_SYSINFO_QUANTITY, + &stMCISysInfo, 0); + if (LOUSHORT(ulRC) != MCIERR_SUCCESS) { + debug_os2("MCI_SYSINFO, MCI_SYSINFO_QUANTITY - failed, rc = 0x%hX", LOUSHORT(ulRC)); + return; + } + + ulDevicesNum = SDL_strtoul(stMCISysInfo.pszReturn, NULL, 10); + + for (ulNumber = 1; ulNumber <= ulDevicesNum; + ulNumber++) { + /* Get device install name. */ + stSysInfoParams.ulNumber = ulNumber; + stSysInfoParams.pszReturn = acBuf; + stSysInfoParams.ulRetSize = sizeof(acBuf); + stSysInfoParams.usDeviceType = MCI_DEVTYPE_AUDIO_AMPMIX; + ulRC = mciSendCommand(0, MCI_SYSINFO, MCI_WAIT | MCI_SYSINFO_INSTALLNAME, + &stSysInfoParams, 0); + if (LOUSHORT(ulRC) != MCIERR_SUCCESS) { + debug_os2("MCI_SYSINFO, MCI_SYSINFO_INSTALLNAME - failed, rc = 0x%hX", LOUSHORT(ulRC)); + continue; + } + + /* Get textual product description. */ + stSysInfoParams.ulItem = MCI_SYSINFO_QUERY_DRIVER; + stSysInfoParams.pSysInfoParm = &stLogDevice; + SDL_strlcpy(stLogDevice.szInstallName, stSysInfoParams.pszReturn, MAX_DEVICE_NAME); + ulRC = mciSendCommand(0, MCI_SYSINFO, MCI_WAIT | MCI_SYSINFO_ITEM, + &stSysInfoParams, 0); + if (LOUSHORT(ulRC) != MCIERR_SUCCESS) { + debug_os2("MCI_SYSINFO, MCI_SYSINFO_ITEM - failed, rc = 0x%hX", LOUSHORT(ulRC)); + continue; + } + + SDL_AddAudioDevice(0, stLogDevice.szProductInfo, NULL, (void *)ulNumber); + + /* Open audio device for querying its capabilities */ + /* at this point we HAVE TO OPEN the waveaudio device and not the ampmix device */ + /* because only the waveaudio device (tied to the ampmix device) supports querying for playback/record capability */ + SDL_memset(&stMCIOpen, 0, sizeof(stMCIOpen)); + stMCIOpen.pszDeviceType = (PSZ)MAKEULONG(MCI_DEVTYPE_WAVEFORM_AUDIO,LOUSHORT(ulNumber)); + ulRC = mciSendCommand(0, MCI_OPEN,MCI_WAIT | MCI_OPEN_TYPE_ID | MCI_OPEN_SHAREABLE,&stMCIOpen, 0); + if (LOUSHORT(ulRC) != MCIERR_SUCCESS) { + debug_os2("MCI_OPEN (getDevCaps) - failed"); + continue; + } + + /* check for recording capability */ + SDL_memset(&stDevCapsParams, 0, sizeof(stDevCapsParams)); + stDevCapsParams.ulItem = MCI_GETDEVCAPS_CAN_RECORD; + ulRC = mciSendCommand(stMCIOpen.usDeviceID, MCI_GETDEVCAPS, MCI_WAIT | MCI_GETDEVCAPS_ITEM, + &stDevCapsParams, 0); + if (LOUSHORT(ulRC) != MCIERR_SUCCESS) { + debug_os2("MCI_GETDEVCAPS, MCI_GETDEVCAPS_ITEM - failed, rc = 0x%hX", LOUSHORT(ulRC)); + } + else { + if (stDevCapsParams.ulReturn) { + SDL_AddAudioDevice(1, stLogDevice.szProductInfo, NULL, (void *)(ulNumber | 0x80000000)); + } + } + + /* close the audio device, we are done querying its capabilities */ + SDL_memset(&stMCIGenericParams, 0, sizeof(stMCIGenericParams)); + ulRC = mciSendCommand(stMCIOpen.usDeviceID, MCI_CLOSE, MCI_WAIT, + &stMCIGenericParams, 0); + if (LOUSHORT(ulRC) != MCIERR_SUCCESS) { + debug_os2("MCI_CLOSE (getDevCaps) - failed"); + } + } +} + +static void OS2_WaitDevice(_THIS) +{ + SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)_this->hidden; + ULONG ulRC; + + debug_os2("Enter"); + + /* Wait for an audio chunk to finish */ + ulRC = DosWaitEventSem(pAData->hevBuf, 5000); + if (ulRC != NO_ERROR) { + debug_os2("DosWaitEventSem(), rc = %lu", ulRC); + } +} + +static Uint8 *OS2_GetDeviceBuf(_THIS) +{ + SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)_this->hidden; + + debug_os2("Enter"); + + return (Uint8 *) pAData->pFillBuffer->pBuffer; +} + +static void OS2_PlayDevice(_THIS) +{ + SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)_this->hidden; + ULONG ulRC; + PMCI_MIX_BUFFER pMixBuffer = NULL; + + debug_os2("Enter"); + + pMixBuffer = pAData->pDrainBuffer; + pAData->pFillBuffer = _getNextBuffer(pAData, pAData->pFillBuffer); + if (!pAData->ulState && pAData->pFillBuffer != pMixBuffer) + { + /* + * this buffer was filled but we have not yet filled all buffers + * so just signal event sem so that OS2_WaitDevice does not need + * to block + */ + ulRC = DosPostEventSem(pAData->hevBuf); + } + + if (!pAData->ulState && (pAData->pFillBuffer == pMixBuffer) ) + { + debug_os2("!hasStarted"); + pAData->ulState = 1; + + /* Write buffers to kick off the amp mixer */ + ulRC = pAData->stMCIMixSetup.pmixWrite(pAData->stMCIMixSetup.ulMixHandle, + pMixBuffer, pAData->cMixBuffers); + + if (ulRC != MCIERR_SUCCESS) { + _mixIOError("pmixWrite", ulRC); + } + } +} + +static int OS2_CaptureFromDevice(_THIS,void *buffer,int buflen) +{ + SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)_this->hidden; + ULONG ulRC; + PMCI_MIX_BUFFER pMixBuffer = NULL; + int len = 0; + + if (!pAData->ulState) + { + pAData->ulState = 1; + ulRC = pAData->stMCIMixSetup.pmixRead(pAData->stMCIMixSetup.ulMixHandle, + pAData->aMixBuffers, pAData->cMixBuffers); + if (ulRC != MCIERR_SUCCESS) { + _mixIOError("pmixRead", ulRC); + return -1; + } + } + + /* Wait for an audio chunk to finish */ + ulRC = DosWaitEventSem(pAData->hevBuf, 5000); + if (ulRC != NO_ERROR) + { + debug_os2("DosWaitEventSem(), rc = %lu", ulRC); + return -1; + } + + pMixBuffer = pAData->pDrainBuffer; + len = SDL_min((int)pMixBuffer->ulBufferLength, buflen); + SDL_memcpy(buffer,pMixBuffer->pBuffer, len); + pAData->pDrainBuffer = _getNextBuffer(pAData, pMixBuffer); + + debug_os2("buflen = %u, ulBufferLength = %lu",buflen,pMixBuffer->ulBufferLength); + + return len; +} + +static void OS2_FlushCapture(_THIS) +{ + SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)_this->hidden; + ULONG ulIdx; + + debug_os2("Enter"); + + /* Fill all device buffers with data */ + for (ulIdx = 0; ulIdx < pAData->cMixBuffers; ulIdx++) { + pAData->aMixBuffers[ulIdx].ulFlags = 0; + pAData->aMixBuffers[ulIdx].ulBufferLength = _this->spec.size; + pAData->aMixBuffers[ulIdx].ulUserParm = (ULONG)_this; + + SDL_memset(((PMCI_MIX_BUFFER)pAData->aMixBuffers)[ulIdx].pBuffer, + _this->spec.silence, _this->spec.size); + } + pAData->pFillBuffer = pAData->aMixBuffers; + pAData->pDrainBuffer = pAData->aMixBuffers; +} + + +static void OS2_CloseDevice(_THIS) +{ + SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)_this->hidden; + MCI_GENERIC_PARMS sMCIGenericParms; + ULONG ulRC; + + debug_os2("Enter"); + + if (!pAData) + return; + + pAData->ulState = 2; + + /* Close up audio */ + if (pAData->usDeviceId != (USHORT)~0) { /* Device is open. */ + SDL_zero(sMCIGenericParms); + + ulRC = mciSendCommand(pAData->usDeviceId, MCI_STOP, + MCI_WAIT, + &sMCIGenericParms, 0); + if (LOUSHORT(ulRC) != MCIERR_SUCCESS) { + debug_os2("MCI_STOP - failed" ); + } + + if (pAData->stMCIMixSetup.ulBitsPerSample != 0) { /* Mixer was initialized. */ + ulRC = mciSendCommand(pAData->usDeviceId, MCI_MIXSETUP, + MCI_WAIT | MCI_MIXSETUP_DEINIT, + &pAData->stMCIMixSetup, 0); + if (LOUSHORT(ulRC) != MCIERR_SUCCESS) { + debug_os2("MCI_MIXSETUP, MCI_MIXSETUP_DEINIT - failed"); + } + } + + if (pAData->cMixBuffers != 0) { /* Buffers was allocated. */ + MCI_BUFFER_PARMS stMCIBuffer; + + stMCIBuffer.ulBufferSize = pAData->aMixBuffers[0].ulBufferLength; + stMCIBuffer.ulNumBuffers = pAData->cMixBuffers; + stMCIBuffer.pBufList = pAData->aMixBuffers; + + ulRC = mciSendCommand(pAData->usDeviceId, MCI_BUFFER, + MCI_WAIT | MCI_DEALLOCATE_MEMORY, &stMCIBuffer, 0); + if (LOUSHORT(ulRC) != MCIERR_SUCCESS) { + debug_os2("MCI_BUFFER, MCI_DEALLOCATE_MEMORY - failed"); + } + } + + ulRC = mciSendCommand(pAData->usDeviceId, MCI_CLOSE, MCI_WAIT, + &sMCIGenericParms, 0); + if (LOUSHORT(ulRC) != MCIERR_SUCCESS) { + debug_os2("MCI_CLOSE - failed"); + } + } + + if (pAData->hevBuf != NULLHANDLE) + DosCloseEventSem(pAData->hevBuf); + + SDL_free(pAData); +} + +static int OS2_OpenDevice(_THIS, const char *devname) +{ + SDL_PrivateAudioData *pAData; + SDL_AudioFormat test_format; + MCI_AMP_OPEN_PARMS stMCIAmpOpen; + MCI_BUFFER_PARMS stMCIBuffer; + ULONG ulRC; + ULONG ulIdx; + BOOL new_freq; + ULONG ulHandle = (ULONG)_this->handle; + SDL_bool iscapture = _this->iscapture; + + new_freq = FALSE; + SDL_zero(stMCIAmpOpen); + SDL_zero(stMCIBuffer); + + for (test_format = SDL_FirstAudioFormat(_this->spec.format); test_format; test_format = SDL_NextAudioFormat()) { + if (test_format == AUDIO_U8 || test_format == AUDIO_S16) + break; + } + if (!test_format) { + debug_os2("Unsupported audio format, AUDIO_S16 used"); + test_format = AUDIO_S16; + } + + pAData = (SDL_PrivateAudioData *) SDL_calloc(1, sizeof(struct SDL_PrivateAudioData)); + if (!pAData) + return SDL_OutOfMemory(); + _this->hidden = pAData; + + ulRC = DosCreateEventSem(NULL, &pAData->hevBuf, DCE_AUTORESET, TRUE); + if (ulRC != NO_ERROR) { + debug_os2("DosCreateEventSem() failed, rc = %lu", ulRC); + return -1; + } + + /* Open audio device */ + stMCIAmpOpen.usDeviceID = 0; + stMCIAmpOpen.pszDeviceType = (PSZ)MAKEULONG(MCI_DEVTYPE_AUDIO_AMPMIX,LOUSHORT(ulHandle)); + ulRC = mciSendCommand(0, MCI_OPEN, + (_getEnvULong("SDL_AUDIO_SHARE", 1, 0) != 0)? + MCI_WAIT | MCI_OPEN_TYPE_ID | MCI_OPEN_SHAREABLE : + MCI_WAIT | MCI_OPEN_TYPE_ID, + &stMCIAmpOpen, 0); + if (LOUSHORT(ulRC) != MCIERR_SUCCESS) { + DosCloseEventSem(pAData->hevBuf); + pAData->usDeviceId = (USHORT)~0; + return _MCIError("MCI_OPEN", ulRC); + } + pAData->usDeviceId = stMCIAmpOpen.usDeviceID; + + if (iscapture) { + MCI_CONNECTOR_PARMS stMCIConnector; + MCI_AMP_SET_PARMS stMCIAmpSet; + BOOL fLineIn = _getEnvULong("SDL_AUDIO_LINEIN", 1, 0); + + /* Set particular connector. */ + SDL_zero(stMCIConnector); + stMCIConnector.ulConnectorType = (fLineIn)? MCI_LINE_IN_CONNECTOR : + MCI_MICROPHONE_CONNECTOR; + mciSendCommand(stMCIAmpOpen.usDeviceID, MCI_CONNECTOR, + MCI_WAIT | MCI_ENABLE_CONNECTOR | + MCI_CONNECTOR_TYPE, &stMCIConnector, 0); + + /* Disable monitor. */ + SDL_zero(stMCIAmpSet); + stMCIAmpSet.ulItem = MCI_AMP_SET_MONITOR; + mciSendCommand(stMCIAmpOpen.usDeviceID, MCI_SET, + MCI_WAIT | MCI_SET_OFF | MCI_SET_ITEM, + &stMCIAmpSet, 0); + + /* Set record volume. */ + stMCIAmpSet.ulLevel = _getEnvULong("SDL_AUDIO_RECVOL", 100, 90); + stMCIAmpSet.ulItem = MCI_AMP_SET_AUDIO; + stMCIAmpSet.ulAudio = MCI_SET_AUDIO_ALL; /* Both cnannels. */ + stMCIAmpSet.ulValue = (fLineIn) ? MCI_LINE_IN_CONNECTOR : + MCI_MICROPHONE_CONNECTOR ; + + mciSendCommand(stMCIAmpOpen.usDeviceID, MCI_SET, + MCI_WAIT | MCI_SET_AUDIO | MCI_AMP_SET_GAIN, + &stMCIAmpSet, 0); + } + + _this->spec.format = test_format; + _this->spec.channels = _this->spec.channels > 1 ? 2 : 1; + if (_this->spec.freq < 8000) { + _this->spec.freq = 8000; + new_freq = TRUE; + } else if (_this->spec.freq > 48000) { + _this->spec.freq = 48000; + new_freq = TRUE; + } + + /* Setup mixer. */ + pAData->stMCIMixSetup.ulFormatTag = MCI_WAVE_FORMAT_PCM; + pAData->stMCIMixSetup.ulBitsPerSample = SDL_AUDIO_BITSIZE(test_format); + pAData->stMCIMixSetup.ulSamplesPerSec = _this->spec.freq; + pAData->stMCIMixSetup.ulChannels = _this->spec.channels; + pAData->stMCIMixSetup.ulDeviceType = MCI_DEVTYPE_WAVEFORM_AUDIO; + if (!iscapture) { + pAData->stMCIMixSetup.ulFormatMode= MCI_PLAY; + pAData->stMCIMixSetup.pmixEvent = cbAudioWriteEvent; + } else { + pAData->stMCIMixSetup.ulFormatMode= MCI_RECORD; + pAData->stMCIMixSetup.pmixEvent = cbAudioReadEvent; + } + + ulRC = mciSendCommand(pAData->usDeviceId, MCI_MIXSETUP, + MCI_WAIT | MCI_MIXSETUP_INIT, &pAData->stMCIMixSetup, 0); + if (LOUSHORT(ulRC) != MCIERR_SUCCESS && _this->spec.freq > 44100) { + new_freq = TRUE; + pAData->stMCIMixSetup.ulSamplesPerSec = 44100; + _this->spec.freq = 44100; + ulRC = mciSendCommand(pAData->usDeviceId, MCI_MIXSETUP, + MCI_WAIT | MCI_MIXSETUP_INIT, &pAData->stMCIMixSetup, 0); + } + + debug_os2("Setup mixer [BPS: %lu, Freq.: %lu, Channels: %lu]: %s", + pAData->stMCIMixSetup.ulBitsPerSample, + pAData->stMCIMixSetup.ulSamplesPerSec, + pAData->stMCIMixSetup.ulChannels, + (ulRC == MCIERR_SUCCESS)? "SUCCESS" : "FAIL"); + + if (ulRC != MCIERR_SUCCESS) { + pAData->stMCIMixSetup.ulBitsPerSample = 0; + return _MCIError("MCI_MIXSETUP", ulRC); + } + + if (_this->spec.samples == 0 || new_freq == TRUE) { + /* also see SDL_audio.c:prepare_audiospec() */ + /* Pick a default of ~46 ms at desired frequency */ + Uint32 samples = (_this->spec.freq / 1000) * 46; + Uint32 power2 = 1; + while (power2 < samples) { + power2 <<= 1; + } + _this->spec.samples = power2; + } + /* Update the fragment size as size in bytes */ + SDL_CalculateAudioSpec(&_this->spec); + + /* Allocate memory buffers */ + stMCIBuffer.ulBufferSize = _this->spec.size;/* (_this->spec.freq / 1000) * 100 */ + stMCIBuffer.ulNumBuffers = NUM_BUFFERS; + stMCIBuffer.pBufList = pAData->aMixBuffers; + + ulRC = mciSendCommand(pAData->usDeviceId, MCI_BUFFER, + MCI_WAIT | MCI_ALLOCATE_MEMORY, &stMCIBuffer, 0); + if (LOUSHORT(ulRC) != MCIERR_SUCCESS) { + return _MCIError("MCI_BUFFER", ulRC); + } + pAData->cMixBuffers = stMCIBuffer.ulNumBuffers; + _this->spec.size = stMCIBuffer.ulBufferSize; + + debug_os2("%s, number of mix buffers: %lu",iscapture ? "capture": "play",pAData->cMixBuffers); + + /* Fill all device buffers with data */ + for (ulIdx = 0; ulIdx < stMCIBuffer.ulNumBuffers; ulIdx++) { + pAData->aMixBuffers[ulIdx].ulFlags = 0; + pAData->aMixBuffers[ulIdx].ulBufferLength = stMCIBuffer.ulBufferSize; + pAData->aMixBuffers[ulIdx].ulUserParm = (ULONG)_this; + + SDL_memset(((PMCI_MIX_BUFFER)stMCIBuffer.pBufList)[ulIdx].pBuffer, + _this->spec.silence, stMCIBuffer.ulBufferSize); + } + pAData->pFillBuffer = pAData->aMixBuffers; + pAData->pDrainBuffer = pAData->aMixBuffers; + + return 0; +} + + +static SDL_bool OS2_Init(SDL_AudioDriverImpl * impl) +{ + /* Set the function pointers */ + impl->DetectDevices = OS2_DetectDevices; + impl->OpenDevice = OS2_OpenDevice; + impl->PlayDevice = OS2_PlayDevice; + impl->WaitDevice = OS2_WaitDevice; + impl->GetDeviceBuf = OS2_GetDeviceBuf; + impl->CloseDevice = OS2_CloseDevice; + impl->CaptureFromDevice = OS2_CaptureFromDevice ; + impl->FlushCapture = OS2_FlushCapture; + impl->HasCaptureSupport = SDL_TRUE; + + return SDL_TRUE; /* this audio target is available. */ +} + + +AudioBootStrap OS2AUDIO_bootstrap = { + "DART", "OS/2 DART", OS2_Init, SDL_FALSE +}; + +#endif /* SDL_AUDIO_DRIVER_OS2 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/audio/os2/SDL_os2audio.h b/SDL2-2.30.5/src/audio/os2/SDL_os2audio.h new file mode 100644 index 0000000..41f091f --- /dev/null +++ b/SDL2-2.30.5/src/audio/os2/SDL_os2audio.h @@ -0,0 +1,55 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifndef SDL_os2mm_h_ +#define SDL_os2mm_h_ + +#include "../SDL_sysaudio.h" + +#define INCL_OS2MM +#define INCL_PM +#define INCL_DOS +#define INCL_DOSERRORS +#include +#include + +/* Hidden "this" pointer for the audio functions */ +#define _THIS SDL_AudioDevice *_this + +#define NUM_BUFFERS 3 + +typedef struct SDL_PrivateAudioData +{ + USHORT usDeviceId; + BYTE _pad[2]; + MCI_MIXSETUP_PARMS stMCIMixSetup; + HEV hevBuf; + PMCI_MIX_BUFFER pFillBuffer; + PMCI_MIX_BUFFER pDrainBuffer; + ULONG ulState; + ULONG cMixBuffers; + MCI_MIX_BUFFER aMixBuffers[NUM_BUFFERS]; +} SDL_PrivateAudioData; + +#endif /* SDL_os2mm_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/audio/paudio/SDL_paudio.c b/SDL2-2.30.5/src/audio/paudio/SDL_paudio.c similarity index 83% rename from SDL2-2.0.12/src/audio/paudio/SDL_paudio.c rename to SDL2-2.30.5/src/audio/paudio/SDL_paudio.c index 7d5f1a0..b82ec8e 100644 --- a/SDL2-2.0.12/src/audio/paudio/SDL_paudio.c +++ b/SDL2-2.30.5/src/audio/paudio/SDL_paudio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_AUDIO_DRIVER_PAUDIO +#ifdef SDL_AUDIO_DRIVER_PAUDIO /* Allow access to a raw mixing buffer */ @@ -69,8 +69,7 @@ static char devsettings[][3] = { {'\0', '\0', '\0'} }; -static int -OpenUserDefinedDevice(char *path, int maxlen, int flags) +static int OpenUserDefinedDevice(char *path, int maxlen, int flags) { const char *audiodev; int fd; @@ -79,19 +78,18 @@ OpenUserDefinedDevice(char *path, int maxlen, int flags) if ((audiodev = SDL_getenv("SDL_PATH_DSP")) == NULL) { audiodev = SDL_getenv("AUDIODEV"); } - if (audiodev == NULL) { + if (!audiodev) { return -1; } fd = open(audiodev, flags, 0); - if (path != NULL) { + if (path) { SDL_strlcpy(path, audiodev, maxlen); path[maxlen - 1] = '\0'; } return fd; } -static int -OpenAudioPath(char *path, int maxlen, int flags, int classic) +static int OpenAudioPath(char *path, int maxlen, int flags, int classic) { struct stat sb; int cycle = 0; @@ -112,7 +110,7 @@ OpenAudioPath(char *path, int maxlen, int flags, int classic) if (stat(audiopath, &sb) == 0) { fd = open(audiopath, flags, 0); if (fd >= 0) { - if (path != NULL) { + if (path) { SDL_strlcpy(path, audiopath, maxlen); } return fd; @@ -123,8 +121,7 @@ OpenAudioPath(char *path, int maxlen, int flags, int classic) } /* This function waits until it is possible to write a full sound buffer */ -static void -PAUDIO_WaitDevice(_THIS) +static void PAUDIO_WaitDevice(_THIS) { fd_set fdset; @@ -156,7 +153,7 @@ PAUDIO_WaitDevice(_THIS) #ifdef DEBUG_AUDIO fprintf(stderr, "Waiting for audio to get ready\n"); #endif - if (SDL_IOReady(this->hidden->audio_fd, SDL_TRUE, timeoutMS) <= 0) { + if (SDL_IOReady(this->hidden->audio_fd, SDL_IOR_WRITE, timeoutMS) <= 0) { /* * In general we should never print to the screen, * but in this case we have no other way of letting @@ -176,8 +173,7 @@ PAUDIO_WaitDevice(_THIS) } } -static void -PAUDIO_PlayDevice(_THIS) +static void PAUDIO_PlayDevice(_THIS) { int written = 0; const Uint8 *mixbuf = this->hidden->mixbuf; @@ -206,14 +202,12 @@ PAUDIO_PlayDevice(_THIS) #endif } -static Uint8 * -PAUDIO_GetDeviceBuf(_THIS) +static Uint8 *PAUDIO_GetDeviceBuf(_THIS) { return this->hidden->mixbuf; } -static void -PAUDIO_CloseDevice(_THIS) +static void PAUDIO_CloseDevice(_THIS) { if (this->hidden->audio_fd >= 0) { close(this->hidden->audio_fd); @@ -222,13 +216,12 @@ PAUDIO_CloseDevice(_THIS) SDL_free(this->hidden); } -static int -PAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) +static int PAUDIO_OpenDevice(_THIS, const char *devname) { const char *workaround = SDL_getenv("SDL_DSP_NOSELECT"); char audiodev[1024]; const char *err = NULL; - int format; + int flags; int bytes_per_sample; SDL_AudioFormat test_format; audio_init paud_init; @@ -238,9 +231,8 @@ PAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) int fd = -1; /* Initialize all variables that we clean on shutdown */ - this->hidden = (struct SDL_PrivateAudioData *) - SDL_malloc((sizeof *this->hidden)); - if (this->hidden == NULL) { + this->hidden = (struct SDL_PrivateAudioData *)SDL_malloc(sizeof(*this->hidden)); + if (!this->hidden) { return SDL_OutOfMemory(); } SDL_zerop(this->hidden); @@ -316,63 +308,44 @@ PAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) paud_init.channels = this->spec.channels; /* Try for a closest match on audio format */ - format = 0; - for (test_format = SDL_FirstAudioFormat(this->spec.format); - !format && test_format;) { + for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) { #ifdef DEBUG_AUDIO fprintf(stderr, "Trying format 0x%4.4x\n", test_format); #endif switch (test_format) { case AUDIO_U8: - bytes_per_sample = 1; - paud_init.bits_per_sample = 8; - paud_init.flags = TWOS_COMPLEMENT | FIXED; - format = 1; + flags = TWOS_COMPLEMENT | FIXED; break; case AUDIO_S8: - bytes_per_sample = 1; - paud_init.bits_per_sample = 8; - paud_init.flags = SIGNED | TWOS_COMPLEMENT | FIXED; - format = 1; + flags = SIGNED | TWOS_COMPLEMENT | FIXED; break; case AUDIO_S16LSB: - bytes_per_sample = 2; - paud_init.bits_per_sample = 16; - paud_init.flags = SIGNED | TWOS_COMPLEMENT | FIXED; - format = 1; + flags = SIGNED | TWOS_COMPLEMENT | FIXED; break; case AUDIO_S16MSB: - bytes_per_sample = 2; - paud_init.bits_per_sample = 16; - paud_init.flags = BIG_ENDIAN | SIGNED | TWOS_COMPLEMENT | FIXED; - format = 1; + flags = BIG_ENDIAN | SIGNED | TWOS_COMPLEMENT | FIXED; break; case AUDIO_U16LSB: - bytes_per_sample = 2; - paud_init.bits_per_sample = 16; - paud_init.flags = TWOS_COMPLEMENT | FIXED; - format = 1; + flags = TWOS_COMPLEMENT | FIXED; break; case AUDIO_U16MSB: - bytes_per_sample = 2; - paud_init.bits_per_sample = 16; - paud_init.flags = BIG_ENDIAN | TWOS_COMPLEMENT | FIXED; - format = 1; + flags = BIG_ENDIAN | TWOS_COMPLEMENT | FIXED; break; default: - break; - } - if (!format) { - test_format = SDL_NextAudioFormat(); + continue; } + break; } - if (format == 0) { + if (!test_format) { #ifdef DEBUG_AUDIO fprintf(stderr, "Couldn't find any hardware audio formats\n"); #endif - return SDL_SetError("Couldn't find any hardware audio formats"); + return SDL_SetError("%s: Unsupported audio format", "paud"); } this->spec.format = test_format; + paud_init.bits_per_sample = SDL_AUDIO_BITSIZE(test_format); + bytes_per_sample = SDL_AUDIO_BITSIZE(test_format) / 8; + paud_init.flags = flags; /* * We know the buffer size and the max number of subsequent writes @@ -406,34 +379,31 @@ PAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) if (ioctl(fd, AUDIO_INIT, &paud_init) < 0) { switch (paud_init.rc) { case 1: - err = "Couldn't set audio format: DSP can't do play requests"; + err = "DSP can't do play requests"; break; case 2: - err = "Couldn't set audio format: DSP can't do record requests"; + err = "DSP can't do record requests"; break; case 4: - err = "Couldn't set audio format: request was invalid"; + err = "request was invalid"; break; case 5: - err = "Couldn't set audio format: conflict with open's flags"; + err = "conflict with open's flags"; break; case 6: - err = "Couldn't set audio format: out of DSP MIPS or memory"; + err = "out of DSP MIPS or memory"; break; default: - err = "Couldn't set audio format: not documented in sys/audio.h"; + err = "not documented in sys/audio.h"; break; } - } - - if (err != NULL) { - return SDL_SetError("Paudio: %s", err); + return SDL_SetError("paud: Couldn't set audio format (%s)", err); } /* Allocate mixing buffer */ this->hidden->mixlen = this->spec.size; this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen); - if (this->hidden->mixbuf == NULL) { + if (!this->hidden->mixbuf) { return SDL_OutOfMemory(); } SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size); @@ -475,7 +445,7 @@ PAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) } /* Check to see if we need to use SDL_IOReady() workaround */ - if (workaround != NULL) { + if (workaround) { this->hidden->frame_ticks = (float) (this->spec.samples * 1000) / this->spec.freq; this->hidden->next_frame = SDL_GetTicks() + this->hidden->frame_ticks; @@ -485,30 +455,29 @@ PAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) return 0; } -static int -PAUDIO_Init(SDL_AudioDriverImpl * impl) +static SDL_bool PAUDIO_Init(SDL_AudioDriverImpl * impl) { /* !!! FIXME: not right for device enum? */ int fd = OpenAudioPath(NULL, 0, OPEN_FLAGS, 0); if (fd < 0) { SDL_SetError("PAUDIO: Couldn't open audio device"); - return 0; + return SDL_FALSE; } close(fd); /* Set the function pointers */ impl->OpenDevice = PAUDIO_OpenDevice; impl->PlayDevice = PAUDIO_PlayDevice; - impl->PlayDevice = PAUDIO_WaitDevice; + impl->WaitDevice = PAUDIO_WaitDevice; impl->GetDeviceBuf = PAUDIO_GetDeviceBuf; impl->CloseDevice = PAUDIO_CloseDevice; - impl->OnlyHasDefaultOutputDevice = 1; /* !!! FIXME: add device enum! */ + impl->OnlyHasDefaultOutputDevice = SDL_TRUE; /* !!! FIXME: add device enum! */ - return 1; /* this audio target is available. */ + return SDL_TRUE; /* this audio target is available. */ } AudioBootStrap PAUDIO_bootstrap = { - "paud", "AIX Paudio", PAUDIO_Init, 0 + "paud", "AIX Paudio", PAUDIO_Init, SDL_FALSE }; #endif /* SDL_AUDIO_DRIVER_PAUDIO */ diff --git a/SDL2-2.0.12/src/audio/paudio/SDL_paudio.h b/SDL2-2.30.5/src/audio/paudio/SDL_paudio.h similarity index 96% rename from SDL2-2.0.12/src/audio/paudio/SDL_paudio.h rename to SDL2-2.30.5/src/audio/paudio/SDL_paudio.h index b3c3d03..7c870ca 100644 --- a/SDL2-2.0.12/src/audio/paudio/SDL_paudio.h +++ b/SDL2-2.30.5/src/audio/paudio/SDL_paudio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.30.5/src/audio/pipewire/SDL_pipewire.c b/SDL2-2.30.5/src/audio/pipewire/SDL_pipewire.c new file mode 100644 index 0000000..4fbe9af --- /dev/null +++ b/SDL2-2.30.5/src/audio/pipewire/SDL_pipewire.c @@ -0,0 +1,1387 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_hints.h" + +#ifdef SDL_AUDIO_DRIVER_PIPEWIRE + +#include "SDL_audio.h" +#include "SDL_loadso.h" +#include "SDL_pipewire.h" + +#include +#include +#include + +/* + * The following keys are defined for compatability when building against older versions of Pipewire + * prior to their introduction and can be removed if the minimum required Pipewire build version is + * increased to or beyond their point of introduction. + */ + +/* + * Introduced in 0.3.22 + * Taken from /src/pipewire/keys.h + */ +#ifndef PW_KEY_CONFIG_NAME +#define PW_KEY_CONFIG_NAME "config.name" +#endif + +/* + * Introduced in 0.3.33 + * Taken from src/pipewire/keys.h + */ +#ifndef PW_KEY_NODE_RATE +#define PW_KEY_NODE_RATE "node.rate" +#endif + +/* + * Introduced in 0.3.44 + * Taken from src/pipewire/keys.h + */ +#ifndef PW_KEY_TARGET_OBJECT +#define PW_KEY_TARGET_OBJECT "target.object" +#endif + +/* + * This seems to be a sane lower limit as Pipewire + * uses it in several of it's own modules. + */ +#define PW_MIN_SAMPLES 32 /* About 0.67ms at 48kHz */ +#define PW_BASE_CLOCK_RATE 48000 + +#define PW_POD_BUFFER_LENGTH 1024 +#define PW_THREAD_NAME_BUFFER_LENGTH 128 +#define PW_MAX_IDENTIFIER_LENGTH 256 + +enum PW_READY_FLAGS +{ + PW_READY_FLAG_BUFFER_ADDED = 0x1, + PW_READY_FLAG_STREAM_READY = 0x2, + PW_READY_FLAG_ALL_BITS = 0x3 +}; + +#define PW_ID_TO_HANDLE(x) (void *)((uintptr_t)x) +#define PW_HANDLE_TO_ID(x) (uint32_t)((uintptr_t)x) + +static SDL_bool pipewire_initialized = SDL_FALSE; + +/* Pipewire entry points */ +static const char *(*PIPEWIRE_pw_get_library_version)(void); +static void (*PIPEWIRE_pw_init)(int *, char ***); +static void (*PIPEWIRE_pw_deinit)(void); +static struct pw_thread_loop *(*PIPEWIRE_pw_thread_loop_new)(const char *, const struct spa_dict *); +static void (*PIPEWIRE_pw_thread_loop_destroy)(struct pw_thread_loop *); +static void (*PIPEWIRE_pw_thread_loop_stop)(struct pw_thread_loop *); +static struct pw_loop *(*PIPEWIRE_pw_thread_loop_get_loop)(struct pw_thread_loop *); +static void (*PIPEWIRE_pw_thread_loop_lock)(struct pw_thread_loop *); +static void (*PIPEWIRE_pw_thread_loop_unlock)(struct pw_thread_loop *); +static void (*PIPEWIRE_pw_thread_loop_signal)(struct pw_thread_loop *, bool); +static void (*PIPEWIRE_pw_thread_loop_wait)(struct pw_thread_loop *); +static int (*PIPEWIRE_pw_thread_loop_start)(struct pw_thread_loop *); +static struct pw_context *(*PIPEWIRE_pw_context_new)(struct pw_loop *, struct pw_properties *, size_t); +static void (*PIPEWIRE_pw_context_destroy)(struct pw_context *); +static struct pw_core *(*PIPEWIRE_pw_context_connect)(struct pw_context *, struct pw_properties *, size_t); +static void (*PIPEWIRE_pw_proxy_add_object_listener)(struct pw_proxy *, struct spa_hook *, const void *, void *); +static void *(*PIPEWIRE_pw_proxy_get_user_data)(struct pw_proxy *); +static void (*PIPEWIRE_pw_proxy_destroy)(struct pw_proxy *); +static int (*PIPEWIRE_pw_core_disconnect)(struct pw_core *); +static struct pw_stream *(*PIPEWIRE_pw_stream_new_simple)(struct pw_loop *, const char *, struct pw_properties *, + const struct pw_stream_events *, void *); +static void (*PIPEWIRE_pw_stream_destroy)(struct pw_stream *); +static int (*PIPEWIRE_pw_stream_connect)(struct pw_stream *, enum pw_direction, uint32_t, enum pw_stream_flags, + const struct spa_pod **, uint32_t); +static enum pw_stream_state (*PIPEWIRE_pw_stream_get_state)(struct pw_stream *stream, const char **error); +static struct pw_buffer *(*PIPEWIRE_pw_stream_dequeue_buffer)(struct pw_stream *); +static int (*PIPEWIRE_pw_stream_queue_buffer)(struct pw_stream *, struct pw_buffer *); +static struct pw_properties *(*PIPEWIRE_pw_properties_new)(const char *, ...)SPA_SENTINEL; +static int (*PIPEWIRE_pw_properties_set)(struct pw_properties *, const char *, const char *); +static int (*PIPEWIRE_pw_properties_setf)(struct pw_properties *, const char *, const char *, ...) SPA_PRINTF_FUNC(3, 4); + +static int pipewire_version_major; +static int pipewire_version_minor; +static int pipewire_version_patch; + +#ifdef SDL_AUDIO_DRIVER_PIPEWIRE_DYNAMIC + +static const char *pipewire_library = SDL_AUDIO_DRIVER_PIPEWIRE_DYNAMIC; +static void *pipewire_handle = NULL; + +static int pipewire_dlsym(const char *fn, void **addr) +{ + *addr = SDL_LoadFunction(pipewire_handle, fn); + if (!*addr) { + /* Don't call SDL_SetError(): SDL_LoadFunction already did. */ + return 0; + } + + return 1; +} + +#define SDL_PIPEWIRE_SYM(x) \ + if (!pipewire_dlsym(#x, (void **)(char *)&PIPEWIRE_##x)) { \ + return -1; \ + } + +static int load_pipewire_library() +{ + pipewire_handle = SDL_LoadObject(pipewire_library); + return pipewire_handle ? 0 : -1; +} + +static void unload_pipewire_library() +{ + if (pipewire_handle) { + SDL_UnloadObject(pipewire_handle); + pipewire_handle = NULL; + } +} + +#else + +#define SDL_PIPEWIRE_SYM(x) PIPEWIRE_##x = x + +static int load_pipewire_library() +{ + return 0; +} + +static void unload_pipewire_library() +{ /* Nothing to do */ +} + +#endif /* SDL_AUDIO_DRIVER_PIPEWIRE_DYNAMIC */ + +static int load_pipewire_syms() +{ + SDL_PIPEWIRE_SYM(pw_get_library_version); + SDL_PIPEWIRE_SYM(pw_init); + SDL_PIPEWIRE_SYM(pw_deinit); + SDL_PIPEWIRE_SYM(pw_thread_loop_new); + SDL_PIPEWIRE_SYM(pw_thread_loop_destroy); + SDL_PIPEWIRE_SYM(pw_thread_loop_stop); + SDL_PIPEWIRE_SYM(pw_thread_loop_get_loop); + SDL_PIPEWIRE_SYM(pw_thread_loop_lock); + SDL_PIPEWIRE_SYM(pw_thread_loop_unlock); + SDL_PIPEWIRE_SYM(pw_thread_loop_signal); + SDL_PIPEWIRE_SYM(pw_thread_loop_wait); + SDL_PIPEWIRE_SYM(pw_thread_loop_start); + SDL_PIPEWIRE_SYM(pw_context_new); + SDL_PIPEWIRE_SYM(pw_context_destroy); + SDL_PIPEWIRE_SYM(pw_context_connect); + SDL_PIPEWIRE_SYM(pw_proxy_add_object_listener); + SDL_PIPEWIRE_SYM(pw_proxy_get_user_data); + SDL_PIPEWIRE_SYM(pw_proxy_destroy); + SDL_PIPEWIRE_SYM(pw_core_disconnect); + SDL_PIPEWIRE_SYM(pw_stream_new_simple); + SDL_PIPEWIRE_SYM(pw_stream_destroy); + SDL_PIPEWIRE_SYM(pw_stream_connect); + SDL_PIPEWIRE_SYM(pw_stream_get_state); + SDL_PIPEWIRE_SYM(pw_stream_dequeue_buffer); + SDL_PIPEWIRE_SYM(pw_stream_queue_buffer); + SDL_PIPEWIRE_SYM(pw_properties_new); + SDL_PIPEWIRE_SYM(pw_properties_set); + SDL_PIPEWIRE_SYM(pw_properties_setf); + + return 0; +} + +SDL_FORCE_INLINE SDL_bool pipewire_version_at_least(int major, int minor, int patch) +{ + return (pipewire_version_major >= major) && + (pipewire_version_major > major || pipewire_version_minor >= minor) && + (pipewire_version_major > major || pipewire_version_minor > minor || pipewire_version_patch >= patch); +} + +static int init_pipewire_library() +{ + if (!load_pipewire_library()) { + if (!load_pipewire_syms()) { + int nargs; + const char *version = PIPEWIRE_pw_get_library_version(); + nargs = SDL_sscanf(version, "%d.%d.%d", &pipewire_version_major, &pipewire_version_minor, &pipewire_version_patch); + if (nargs < 3) { + return -1; + } + + /* SDL can build against 0.3.20, but requires 0.3.24 */ + if (pipewire_version_at_least(0, 3, 24)) { + PIPEWIRE_pw_init(NULL, NULL); + return 0; + } + } + } + + return -1; +} + +static void deinit_pipewire_library() +{ + PIPEWIRE_pw_deinit(); + unload_pipewire_library(); +} + +/* A generic Pipewire node object used for enumeration. */ +struct node_object +{ + struct spa_list link; + + Uint32 id; + int seq; + SDL_bool persist; + + /* + * NOTE: If used, this is *must* be allocated with SDL_malloc() or similar + * as SDL_free() will be called on it when the node_object is destroyed. + * + * If ownership of the referenced memory is transferred, this must be set + * to NULL or the memory will be freed when the node_object is destroyed. + */ + void *userdata; + + struct pw_proxy *proxy; + struct spa_hook node_listener; + struct spa_hook core_listener; +}; + +/* A sink/source node used for stream I/O. */ +struct io_node +{ + struct spa_list link; + + Uint32 id; + SDL_bool is_capture; + SDL_AudioSpec spec; + + const char *name; /* Friendly name */ + const char *path; /* OS identifier (i.e. ALSA endpoint) */ + + char buf[]; /* Buffer to hold the name and path strings. */ +}; + +/* The global hotplug thread and associated objects. */ +static struct pw_thread_loop *hotplug_loop; +static struct pw_core *hotplug_core; +static struct pw_context *hotplug_context; +static struct pw_registry *hotplug_registry; +static struct spa_hook hotplug_registry_listener; +static struct spa_hook hotplug_core_listener; +static struct spa_list hotplug_pending_list; +static struct spa_list hotplug_io_list; +static int hotplug_init_seq_val; +static SDL_bool hotplug_init_complete; +static SDL_bool hotplug_events_enabled; + +static char *pipewire_default_sink_id = NULL; +static char *pipewire_default_source_id = NULL; + +/* The active node list */ +static SDL_bool io_list_check_add(struct io_node *node) +{ + struct io_node *n; + SDL_bool ret = SDL_TRUE; + + /* See if the node is already in the list */ + spa_list_for_each (n, &hotplug_io_list, link) { + if (n->id == node->id) { + ret = SDL_FALSE; + goto dup_found; + } + } + + /* Add to the list if the node doesn't already exist */ + spa_list_append(&hotplug_io_list, &node->link); + + if (hotplug_events_enabled) { + SDL_AddAudioDevice(node->is_capture, node->name, &node->spec, PW_ID_TO_HANDLE(node->id)); + } + +dup_found: + + return ret; +} + +static void io_list_remove(Uint32 id) +{ + struct io_node *n, *temp; + + /* Find and remove the node from the list */ + spa_list_for_each_safe (n, temp, &hotplug_io_list, link) { + if (n->id == id) { + spa_list_remove(&n->link); + + if (hotplug_events_enabled) { + SDL_RemoveAudioDevice(n->is_capture, PW_ID_TO_HANDLE(id)); + } + + SDL_free(n); + + break; + } + } +} + +static void io_list_sort() +{ + struct io_node *default_sink = NULL, *default_source = NULL; + struct io_node *n, *temp; + + /* Find and move the default nodes to the beginning of the list */ + spa_list_for_each_safe (n, temp, &hotplug_io_list, link) { + if (pipewire_default_sink_id && SDL_strcmp(n->path, pipewire_default_sink_id) == 0) { + default_sink = n; + spa_list_remove(&n->link); + } else if (pipewire_default_source_id && SDL_strcmp(n->path, pipewire_default_source_id) == 0) { + default_source = n; + spa_list_remove(&n->link); + } + } + + if (default_source) { + spa_list_prepend(&hotplug_io_list, &default_source->link); + } + + if (default_sink) { + spa_list_prepend(&hotplug_io_list, &default_sink->link); + } +} + +static void io_list_clear() +{ + struct io_node *n, *temp; + + spa_list_for_each_safe (n, temp, &hotplug_io_list, link) { + spa_list_remove(&n->link); + SDL_free(n); + } +} + +static struct io_node *io_list_get_by_id(Uint32 id) +{ + struct io_node *n, *temp; + spa_list_for_each_safe (n, temp, &hotplug_io_list, link) { + if (n->id == id) { + return n; + } + } + return NULL; +} + +static struct io_node *io_list_get_by_path(char *path) +{ + struct io_node *n, *temp; + spa_list_for_each_safe (n, temp, &hotplug_io_list, link) { + if (SDL_strcmp(n->path, path) == 0) { + return n; + } + } + return NULL; +} + +static void node_object_destroy(struct node_object *node) +{ + SDL_assert(node != NULL); + + spa_list_remove(&node->link); + spa_hook_remove(&node->node_listener); + spa_hook_remove(&node->core_listener); + SDL_free(node->userdata); + PIPEWIRE_pw_proxy_destroy(node->proxy); +} + +/* The pending node list */ +static void pending_list_add(struct node_object *node) +{ + SDL_assert(node != NULL); + spa_list_append(&hotplug_pending_list, &node->link); +} + +static void pending_list_remove(Uint32 id) +{ + struct node_object *node, *temp; + + spa_list_for_each_safe (node, temp, &hotplug_pending_list, link) { + if (node->id == id) { + node_object_destroy(node); + } + } +} + +static void pending_list_clear() +{ + struct node_object *node, *temp; + + spa_list_for_each_safe (node, temp, &hotplug_pending_list, link) { + node_object_destroy(node); + } +} + +static void *node_object_new(Uint32 id, const char *type, Uint32 version, const void *funcs, const struct pw_core_events *core_events) +{ + struct pw_proxy *proxy; + struct node_object *node; + + /* Create the proxy object */ + proxy = pw_registry_bind(hotplug_registry, id, type, version, sizeof(struct node_object)); + if (!proxy) { + SDL_SetError("Pipewire: Failed to create proxy object (%i)", errno); + return NULL; + } + + node = PIPEWIRE_pw_proxy_get_user_data(proxy); + SDL_zerop(node); + + node->id = id; + node->proxy = proxy; + + /* Add the callbacks */ + pw_core_add_listener(hotplug_core, &node->core_listener, core_events, node); + PIPEWIRE_pw_proxy_add_object_listener(node->proxy, &node->node_listener, funcs, node); + + /* Add the node to the active list */ + pending_list_add(node); + + return node; +} + +/* Core sync points */ +static void core_events_hotplug_init_callback(void *object, uint32_t id, int seq) +{ + if (id == PW_ID_CORE && seq == hotplug_init_seq_val) { + /* This core listener is no longer needed. */ + spa_hook_remove(&hotplug_core_listener); + + /* Signal that the initial I/O list is populated */ + hotplug_init_complete = SDL_TRUE; + PIPEWIRE_pw_thread_loop_signal(hotplug_loop, false); + } +} + +static void core_events_interface_callback(void *object, uint32_t id, int seq) +{ + struct node_object *node = object; + struct io_node *io = node->userdata; + + if (id == PW_ID_CORE && seq == node->seq) { + /* + * Move the I/O node to the connected list. + * On success, the list owns the I/O node object. + */ + if (io_list_check_add(io)) { + node->userdata = NULL; + } + + node_object_destroy(node); + } +} + +static void core_events_metadata_callback(void *object, uint32_t id, int seq) +{ + struct node_object *node = object; + + if (id == PW_ID_CORE && seq == node->seq && !node->persist) { + node_object_destroy(node); + } +} + +static const struct pw_core_events hotplug_init_core_events = { PW_VERSION_CORE_EVENTS, .done = core_events_hotplug_init_callback }; +static const struct pw_core_events interface_core_events = { PW_VERSION_CORE_EVENTS, .done = core_events_interface_callback }; +static const struct pw_core_events metadata_core_events = { PW_VERSION_CORE_EVENTS, .done = core_events_metadata_callback }; + +static void hotplug_core_sync(struct node_object *node) +{ + /* + * Node sync events *must* come before the hotplug init sync events or the initial + * I/O list will be incomplete when the main hotplug sync point is hit. + */ + if (node) { + node->seq = pw_core_sync(hotplug_core, PW_ID_CORE, node->seq); + } + + if (!hotplug_init_complete) { + hotplug_init_seq_val = pw_core_sync(hotplug_core, PW_ID_CORE, hotplug_init_seq_val); + } +} + +/* Helpers for retrieving values from params */ +static SDL_bool get_range_param(const struct spa_pod *param, Uint32 key, int *def, int *min, int *max) +{ + const struct spa_pod_prop *prop; + struct spa_pod *value; + Uint32 n_values, choice; + + prop = spa_pod_find_prop(param, NULL, key); + + if (prop && prop->value.type == SPA_TYPE_Choice) { + value = spa_pod_get_values(&prop->value, &n_values, &choice); + + if (n_values == 3 && choice == SPA_CHOICE_Range) { + Uint32 *v = SPA_POD_BODY(value); + + if (v) { + if (def) { + *def = (int)v[0]; + } + if (min) { + *min = (int)v[1]; + } + if (max) { + *max = (int)v[2]; + } + + return SDL_TRUE; + } + } + } + + return SDL_FALSE; +} + +static SDL_bool get_int_param(const struct spa_pod *param, Uint32 key, int *val) +{ + const struct spa_pod_prop *prop; + Sint32 v; + + prop = spa_pod_find_prop(param, NULL, key); + + if (prop && spa_pod_get_int(&prop->value, &v) == 0) { + if (val) { + *val = (int)v; + } + + return SDL_TRUE; + } + + return SDL_FALSE; +} + +/* Interface node callbacks */ +static void node_event_info(void *object, const struct pw_node_info *info) +{ + struct node_object *node = object; + struct io_node *io = node->userdata; + const char *prop_val; + Uint32 i; + + if (info) { + prop_val = spa_dict_lookup(info->props, PW_KEY_AUDIO_CHANNELS); + if (prop_val) { + io->spec.channels = (Uint8)SDL_atoi(prop_val); + } + + /* Need to parse the parameters to get the sample rate */ + for (i = 0; i < info->n_params; ++i) { + pw_node_enum_params(node->proxy, 0, info->params[i].id, 0, 0, NULL); + } + + hotplug_core_sync(node); + } +} + +static void node_event_param(void *object, int seq, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) +{ + struct node_object *node = object; + struct io_node *io = node->userdata; + + /* Get the default frequency */ + if (io->spec.freq == 0) { + get_range_param(param, SPA_FORMAT_AUDIO_rate, &io->spec.freq, NULL, NULL); + } + + /* + * The channel count should have come from the node properties, + * but it is stored here as well. If one failed, try the other. + */ + if (io->spec.channels == 0) { + int channels; + if (get_int_param(param, SPA_FORMAT_AUDIO_channels, &channels)) { + io->spec.channels = (Uint8)channels; + } + } +} + +static const struct pw_node_events interface_node_events = { PW_VERSION_NODE_EVENTS, .info = node_event_info, + .param = node_event_param }; + +static char *get_name_from_json(const char *json) +{ + struct spa_json parser[2]; + char key[7]; /* "name" */ + char value[PW_MAX_IDENTIFIER_LENGTH]; + spa_json_init(&parser[0], json, SDL_strlen(json)); + if (spa_json_enter_object(&parser[0], &parser[1]) <= 0) { + /* Not actually JSON */ + return NULL; + } + if (spa_json_get_string(&parser[1], key, sizeof(key)) <= 0) { + /* Not actually a key/value pair */ + return NULL; + } + if (spa_json_get_string(&parser[1], value, sizeof(value)) <= 0) { + /* Somehow had a key with no value? */ + return NULL; + } + return SDL_strdup(value); +} + +/* Metadata node callback */ +static int metadata_property(void *object, Uint32 subject, const char *key, const char *type, const char *value) +{ + struct node_object *node = object; + + if (subject == PW_ID_CORE && key && value) { + if (!SDL_strcmp(key, "default.audio.sink")) { + if (pipewire_default_sink_id) { + SDL_free(pipewire_default_sink_id); + } + pipewire_default_sink_id = get_name_from_json(value); + node->persist = SDL_TRUE; + } else if (!SDL_strcmp(key, "default.audio.source")) { + if (pipewire_default_source_id) { + SDL_free(pipewire_default_source_id); + } + pipewire_default_source_id = get_name_from_json(value); + node->persist = SDL_TRUE; + } + } + + return 0; +} + +static const struct pw_metadata_events metadata_node_events = { PW_VERSION_METADATA_EVENTS, .property = metadata_property }; + +/* Global registry callbacks */ +static void registry_event_global_callback(void *object, uint32_t id, uint32_t permissions, const char *type, uint32_t version, + const struct spa_dict *props) +{ + struct node_object *node; + + /* We're only interested in interface and metadata nodes. */ + if (!SDL_strcmp(type, PW_TYPE_INTERFACE_Node)) { + const char *media_class = spa_dict_lookup(props, PW_KEY_MEDIA_CLASS); + + if (media_class) { + const char *node_desc; + const char *node_path; + struct io_node *io; + SDL_bool is_capture; + int desc_buffer_len; + int path_buffer_len; + + /* Just want sink and capture */ + if (!SDL_strcasecmp(media_class, "Audio/Sink")) { + is_capture = SDL_FALSE; + } else if (!SDL_strcasecmp(media_class, "Audio/Source")) { + is_capture = SDL_TRUE; + } else { + return; + } + + node_desc = spa_dict_lookup(props, PW_KEY_NODE_DESCRIPTION); + node_path = spa_dict_lookup(props, PW_KEY_NODE_NAME); + + if (node_desc && node_path) { + node = node_object_new(id, type, version, &interface_node_events, &interface_core_events); + if (!node) { + SDL_SetError("Pipewire: Failed to allocate interface node"); + return; + } + + /* Allocate and initialize the I/O node information struct */ + desc_buffer_len = SDL_strlen(node_desc) + 1; + path_buffer_len = SDL_strlen(node_path) + 1; + node->userdata = io = SDL_calloc(1, sizeof(struct io_node) + desc_buffer_len + path_buffer_len); + if (!io) { + node_object_destroy(node); + SDL_OutOfMemory(); + return; + } + + /* Begin setting the node properties */ + io->id = id; + io->is_capture = is_capture; + io->spec.format = AUDIO_F32; /* Pipewire uses floats internally, other formats require conversion. */ + io->name = io->buf; + io->path = io->buf + desc_buffer_len; + SDL_strlcpy(io->buf, node_desc, desc_buffer_len); + SDL_strlcpy(io->buf + desc_buffer_len, node_path, path_buffer_len); + + /* Update sync points */ + hotplug_core_sync(node); + } + } + } else if (!SDL_strcmp(type, PW_TYPE_INTERFACE_Metadata)) { + node = node_object_new(id, type, version, &metadata_node_events, &metadata_core_events); + if (!node) { + SDL_SetError("Pipewire: Failed to allocate metadata node"); + return; + } + + /* Update sync points */ + hotplug_core_sync(node); + } +} + +static void registry_event_remove_callback(void *object, uint32_t id) +{ + io_list_remove(id); + pending_list_remove(id); +} + +static const struct pw_registry_events registry_events = { PW_VERSION_REGISTRY_EVENTS, .global = registry_event_global_callback, + .global_remove = registry_event_remove_callback }; + +/* The hotplug thread */ +static int hotplug_loop_init() +{ + int res; + + spa_list_init(&hotplug_pending_list); + spa_list_init(&hotplug_io_list); + + hotplug_loop = PIPEWIRE_pw_thread_loop_new("SDLAudioHotplug", NULL); + if (!hotplug_loop) { + return SDL_SetError("Pipewire: Failed to create hotplug detection loop (%i)", errno); + } + + hotplug_context = PIPEWIRE_pw_context_new(PIPEWIRE_pw_thread_loop_get_loop(hotplug_loop), NULL, 0); + if (!hotplug_context) { + return SDL_SetError("Pipewire: Failed to create hotplug detection context (%i)", errno); + } + + hotplug_core = PIPEWIRE_pw_context_connect(hotplug_context, NULL, 0); + if (!hotplug_core) { + return SDL_SetError("Pipewire: Failed to connect hotplug detection context (%i)", errno); + } + + hotplug_registry = pw_core_get_registry(hotplug_core, PW_VERSION_REGISTRY, 0); + if (!hotplug_registry) { + return SDL_SetError("Pipewire: Failed to acquire hotplug detection registry (%i)", errno); + } + + spa_zero(hotplug_registry_listener); + pw_registry_add_listener(hotplug_registry, &hotplug_registry_listener, ®istry_events, NULL); + + spa_zero(hotplug_core_listener); + pw_core_add_listener(hotplug_core, &hotplug_core_listener, &hotplug_init_core_events, NULL); + + hotplug_init_seq_val = pw_core_sync(hotplug_core, PW_ID_CORE, 0); + + res = PIPEWIRE_pw_thread_loop_start(hotplug_loop); + if (res != 0) { + return SDL_SetError("Pipewire: Failed to start hotplug detection loop"); + } + + return 0; +} + +static void hotplug_loop_destroy() +{ + if (hotplug_loop) { + PIPEWIRE_pw_thread_loop_stop(hotplug_loop); + } + + pending_list_clear(); + io_list_clear(); + + hotplug_init_complete = SDL_FALSE; + hotplug_events_enabled = SDL_FALSE; + + if (pipewire_default_sink_id) { + SDL_free(pipewire_default_sink_id); + pipewire_default_sink_id = NULL; + } + if (pipewire_default_source_id) { + SDL_free(pipewire_default_source_id); + pipewire_default_source_id = NULL; + } + + if (hotplug_registry) { + PIPEWIRE_pw_proxy_destroy((struct pw_proxy *)hotplug_registry); + hotplug_registry = NULL; + } + + if (hotplug_core) { + PIPEWIRE_pw_core_disconnect(hotplug_core); + hotplug_core = NULL; + } + + if (hotplug_context) { + PIPEWIRE_pw_context_destroy(hotplug_context); + hotplug_context = NULL; + } + + if (hotplug_loop) { + PIPEWIRE_pw_thread_loop_destroy(hotplug_loop); + hotplug_loop = NULL; + } +} + +static void PIPEWIRE_DetectDevices() +{ + struct io_node *io; + + PIPEWIRE_pw_thread_loop_lock(hotplug_loop); + + /* Wait until the initial registry enumeration is complete */ + if (!hotplug_init_complete) { + PIPEWIRE_pw_thread_loop_wait(hotplug_loop); + } + + /* Sort the I/O list so the default source/sink are listed first */ + io_list_sort(); + + spa_list_for_each (io, &hotplug_io_list, link) { + SDL_AddAudioDevice(io->is_capture, io->name, &io->spec, PW_ID_TO_HANDLE(io->id)); + } + + hotplug_events_enabled = SDL_TRUE; + + PIPEWIRE_pw_thread_loop_unlock(hotplug_loop); +} + +/* Channel maps that match the order in SDL_Audio.h */ +static const enum spa_audio_channel PIPEWIRE_channel_map_1[] = { SPA_AUDIO_CHANNEL_MONO }; +static const enum spa_audio_channel PIPEWIRE_channel_map_2[] = { SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR }; +static const enum spa_audio_channel PIPEWIRE_channel_map_3[] = { SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR, SPA_AUDIO_CHANNEL_LFE }; +static const enum spa_audio_channel PIPEWIRE_channel_map_4[] = { SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR, SPA_AUDIO_CHANNEL_RL, + SPA_AUDIO_CHANNEL_RR }; +static const enum spa_audio_channel PIPEWIRE_channel_map_5[] = { SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR, SPA_AUDIO_CHANNEL_FC, + SPA_AUDIO_CHANNEL_RL, SPA_AUDIO_CHANNEL_RR }; +static const enum spa_audio_channel PIPEWIRE_channel_map_6[] = { SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR, SPA_AUDIO_CHANNEL_FC, + SPA_AUDIO_CHANNEL_LFE, SPA_AUDIO_CHANNEL_RL, SPA_AUDIO_CHANNEL_RR }; +static const enum spa_audio_channel PIPEWIRE_channel_map_7[] = { SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR, SPA_AUDIO_CHANNEL_FC, + SPA_AUDIO_CHANNEL_LFE, SPA_AUDIO_CHANNEL_RC, SPA_AUDIO_CHANNEL_RL, + SPA_AUDIO_CHANNEL_RR }; +static const enum spa_audio_channel PIPEWIRE_channel_map_8[] = { SPA_AUDIO_CHANNEL_FL, SPA_AUDIO_CHANNEL_FR, SPA_AUDIO_CHANNEL_FC, + SPA_AUDIO_CHANNEL_LFE, SPA_AUDIO_CHANNEL_RL, SPA_AUDIO_CHANNEL_RR, + SPA_AUDIO_CHANNEL_SL, SPA_AUDIO_CHANNEL_SR }; + +#define COPY_CHANNEL_MAP(c) SDL_memcpy(info->position, PIPEWIRE_channel_map_##c, sizeof(PIPEWIRE_channel_map_##c)) + +static void initialize_spa_info(const SDL_AudioSpec *spec, struct spa_audio_info_raw *info) +{ + info->channels = spec->channels; + info->rate = spec->freq; + + switch (spec->channels) { + case 1: + COPY_CHANNEL_MAP(1); + break; + case 2: + COPY_CHANNEL_MAP(2); + break; + case 3: + COPY_CHANNEL_MAP(3); + break; + case 4: + COPY_CHANNEL_MAP(4); + break; + case 5: + COPY_CHANNEL_MAP(5); + break; + case 6: + COPY_CHANNEL_MAP(6); + break; + case 7: + COPY_CHANNEL_MAP(7); + break; + case 8: + COPY_CHANNEL_MAP(8); + break; + } + + /* Pipewire natively supports all of SDL's sample formats */ + switch (spec->format) { + case AUDIO_U8: + info->format = SPA_AUDIO_FORMAT_U8; + break; + case AUDIO_S8: + info->format = SPA_AUDIO_FORMAT_S8; + break; + case AUDIO_U16LSB: + info->format = SPA_AUDIO_FORMAT_U16_LE; + break; + case AUDIO_S16LSB: + info->format = SPA_AUDIO_FORMAT_S16_LE; + break; + case AUDIO_U16MSB: + info->format = SPA_AUDIO_FORMAT_U16_BE; + break; + case AUDIO_S16MSB: + info->format = SPA_AUDIO_FORMAT_S16_BE; + break; + case AUDIO_S32LSB: + info->format = SPA_AUDIO_FORMAT_S32_LE; + break; + case AUDIO_S32MSB: + info->format = SPA_AUDIO_FORMAT_S32_BE; + break; + case AUDIO_F32LSB: + info->format = SPA_AUDIO_FORMAT_F32_LE; + break; + case AUDIO_F32MSB: + info->format = SPA_AUDIO_FORMAT_F32_BE; + break; + } +} + +static void output_callback(void *data) +{ + struct pw_buffer *pw_buf; + struct spa_buffer *spa_buf; + Uint8 *dst; + + _THIS = (SDL_AudioDevice *)data; + struct pw_stream *stream = this->hidden->stream; + + /* Shutting down, don't do anything */ + if (SDL_AtomicGet(&this->shutdown)) { + return; + } + + /* See if a buffer is available */ + pw_buf = PIPEWIRE_pw_stream_dequeue_buffer(stream); + if (!pw_buf) { + return; + } + + spa_buf = pw_buf->buffer; + + if (spa_buf->datas[0].data == NULL) { + return; + } + + /* + * If the device is disabled, write silence to the stream buffer + * and run the callback with the work buffer to keep the callback + * firing regularly in case the audio is being used as a timer. + */ + SDL_LockMutex(this->mixer_lock); + if (!SDL_AtomicGet(&this->paused)) { + if (SDL_AtomicGet(&this->enabled)) { + dst = spa_buf->datas[0].data; + } else { + dst = this->work_buffer; + SDL_memset(spa_buf->datas[0].data, this->spec.silence, this->spec.size); + } + + if (!this->stream) { + this->callbackspec.callback(this->callbackspec.userdata, dst, this->callbackspec.size); + } else { + int got; + + /* Fire the callback until we have enough to fill a buffer */ + while (SDL_AudioStreamAvailable(this->stream) < this->spec.size) { + this->callbackspec.callback(this->callbackspec.userdata, this->work_buffer, this->callbackspec.size); + SDL_AudioStreamPut(this->stream, this->work_buffer, this->callbackspec.size); + } + + got = SDL_AudioStreamGet(this->stream, dst, this->spec.size); + SDL_assert(got == this->spec.size); + } + } else { + SDL_memset(spa_buf->datas[0].data, this->spec.silence, this->spec.size); + } + SDL_UnlockMutex(this->mixer_lock); + + spa_buf->datas[0].chunk->offset = 0; + spa_buf->datas[0].chunk->stride = this->hidden->stride; + spa_buf->datas[0].chunk->size = this->spec.size; + + PIPEWIRE_pw_stream_queue_buffer(stream, pw_buf); +} + +static void input_callback(void *data) +{ + struct pw_buffer *pw_buf; + struct spa_buffer *spa_buf; + Uint8 *src; + _THIS = (SDL_AudioDevice *)data; + struct pw_stream *stream = this->hidden->stream; + + /* Shutting down, don't do anything */ + if (SDL_AtomicGet(&this->shutdown)) { + return; + } + + pw_buf = PIPEWIRE_pw_stream_dequeue_buffer(stream); + if (!pw_buf) { + return; + } + + spa_buf = pw_buf->buffer; + (src = (Uint8 *)spa_buf->datas[0].data); + if (!src) { + return; + } + + if (!SDL_AtomicGet(&this->paused)) { + /* Calculate the offset and data size */ + const Uint32 offset = SPA_MIN(spa_buf->datas[0].chunk->offset, spa_buf->datas[0].maxsize); + const Uint32 size = SPA_MIN(spa_buf->datas[0].chunk->size, spa_buf->datas[0].maxsize - offset); + + src += offset; + + /* Fill the buffer with silence if the stream is disabled. */ + if (!SDL_AtomicGet(&this->enabled)) { + SDL_memset(src, this->callbackspec.silence, size); + } + + /* Pipewire can vary the latency, so buffer all incoming data */ + SDL_WriteToDataQueue(this->hidden->buffer, src, size); + + while (SDL_CountDataQueue(this->hidden->buffer) >= this->callbackspec.size) { + SDL_ReadFromDataQueue(this->hidden->buffer, this->work_buffer, this->callbackspec.size); + + SDL_LockMutex(this->mixer_lock); + this->callbackspec.callback(this->callbackspec.userdata, this->work_buffer, this->callbackspec.size); + SDL_UnlockMutex(this->mixer_lock); + } + } else if (this->hidden->buffer) { /* Flush the buffer when paused */ + if (SDL_CountDataQueue(this->hidden->buffer) != 0) { + SDL_ClearDataQueue(this->hidden->buffer, this->hidden->input_buffer_packet_size); + } + } + + PIPEWIRE_pw_stream_queue_buffer(stream, pw_buf); +} + +static void stream_add_buffer_callback(void *data, struct pw_buffer *buffer) +{ + _THIS = data; + + if (this->iscapture == SDL_FALSE) { + /* + * Clamp the output spec samples and size to the max size of the Pipewire buffer. + * If they exceed the maximum size of the Pipewire buffer, double buffering will be used. + */ + if (this->spec.size > buffer->buffer->datas[0].maxsize) { + this->spec.samples = buffer->buffer->datas[0].maxsize / this->hidden->stride; + this->spec.size = buffer->buffer->datas[0].maxsize; + } + } else if (!this->hidden->buffer) { + /* + * The latency of source nodes can change, so buffering is always required. + * + * Ensure that the intermediate input buffer is large enough to hold the requested + * application packet size or a full buffer of data from Pipewire, whichever is larger. + * + * A packet size of 2 periods should be more than is ever needed. + */ + this->hidden->input_buffer_packet_size = SPA_MAX(this->spec.size, buffer->buffer->datas[0].maxsize) * 2; + this->hidden->buffer = SDL_NewDataQueue(this->hidden->input_buffer_packet_size, this->hidden->input_buffer_packet_size); + } + + this->hidden->stream_init_status |= PW_READY_FLAG_BUFFER_ADDED; + PIPEWIRE_pw_thread_loop_signal(this->hidden->loop, false); +} + +static void stream_state_changed_callback(void *data, enum pw_stream_state old, enum pw_stream_state state, const char *error) +{ + _THIS = data; + + if (state == PW_STREAM_STATE_STREAMING) { + this->hidden->stream_init_status |= PW_READY_FLAG_STREAM_READY; + } + + if (state == PW_STREAM_STATE_STREAMING || state == PW_STREAM_STATE_ERROR) { + PIPEWIRE_pw_thread_loop_signal(this->hidden->loop, false); + } +} + +static const struct pw_stream_events stream_output_events = { PW_VERSION_STREAM_EVENTS, + .state_changed = stream_state_changed_callback, + .add_buffer = stream_add_buffer_callback, + .process = output_callback }; +static const struct pw_stream_events stream_input_events = { PW_VERSION_STREAM_EVENTS, + .state_changed = stream_state_changed_callback, + .add_buffer = stream_add_buffer_callback, + .process = input_callback }; + +static int PIPEWIRE_OpenDevice(_THIS, const char *devname) +{ + /* + * NOTE: The PW_STREAM_FLAG_RT_PROCESS flag can be set to call the stream + * processing callback from the realtime thread. However, it comes with some + * caveats: no file IO, allocations, locking or other blocking operations + * must occur in the mixer callback. As this cannot be guaranteed when the + * callback is in the calling application, this flag is omitted. + */ + static const enum pw_stream_flags STREAM_FLAGS = PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_MAP_BUFFERS; + + char thread_name[PW_THREAD_NAME_BUFFER_LENGTH]; + Uint8 pod_buffer[PW_POD_BUFFER_LENGTH]; + struct spa_pod_builder b = SPA_POD_BUILDER_INIT(pod_buffer, sizeof(pod_buffer)); + struct spa_audio_info_raw spa_info = { 0 }; + const struct spa_pod *params = NULL; + struct SDL_PrivateAudioData *priv; + struct pw_properties *props; + const char *app_name, *stream_name, *stream_role, *error; + Uint32 node_id = !this->handle ? PW_ID_ANY : PW_HANDLE_TO_ID(this->handle); + SDL_bool iscapture = this->iscapture; + int res; + + /* Clamp the period size to sane values */ + const int min_period = PW_MIN_SAMPLES * SPA_MAX(this->spec.freq / PW_BASE_CLOCK_RATE, 1); + + /* Get the hints for the application name, stream name and role */ + app_name = SDL_GetHint(SDL_HINT_AUDIO_DEVICE_APP_NAME); + if (!app_name || *app_name == '\0') { + app_name = SDL_GetHint(SDL_HINT_APP_NAME); + if (!app_name || *app_name == '\0') { + app_name = "SDL Application"; + } + } + + stream_name = SDL_GetHint(SDL_HINT_AUDIO_DEVICE_STREAM_NAME); + if (!stream_name || *stream_name == '\0') { + stream_name = "Audio Stream"; + } + + /* + * 'Music' is the default used internally by Pipewire and it's modules, + * but 'Game' seems more appropriate for the majority of SDL applications. + */ + stream_role = SDL_GetHint(SDL_HINT_AUDIO_DEVICE_STREAM_ROLE); + if (!stream_role || *stream_role == '\0') { + stream_role = "Game"; + } + + /* Initialize the Pipewire stream info from the SDL audio spec */ + initialize_spa_info(&this->spec, &spa_info); + params = spa_format_audio_raw_build(&b, SPA_PARAM_EnumFormat, &spa_info); + if (!params) { + return SDL_SetError("Pipewire: Failed to set audio format parameters"); + } + + priv = SDL_calloc(1, sizeof(struct SDL_PrivateAudioData)); + this->hidden = priv; + if (!priv) { + return SDL_OutOfMemory(); + } + + /* Size of a single audio frame in bytes */ + priv->stride = (SDL_AUDIO_BITSIZE(this->spec.format) >> 3) * this->spec.channels; + + if (this->spec.samples < min_period) { + this->spec.samples = min_period; + this->spec.size = this->spec.samples * priv->stride; + } + + (void)SDL_snprintf(thread_name, sizeof(thread_name), "SDLAudio%c%ld", (iscapture) ? 'C' : 'P', (long)this->handle); + priv->loop = PIPEWIRE_pw_thread_loop_new(thread_name, NULL); + if (!priv->loop) { + return SDL_SetError("Pipewire: Failed to create stream loop (%i)", errno); + } + + /* Load the realtime module so Pipewire can set the loop thread to the appropriate priority. */ + props = PIPEWIRE_pw_properties_new(PW_KEY_CONFIG_NAME, "client-rt.conf", NULL); + if (!props) { + return SDL_SetError("Pipewire: Failed to create stream context properties (%i)", errno); + } + + priv->context = PIPEWIRE_pw_context_new(PIPEWIRE_pw_thread_loop_get_loop(priv->loop), props, 0); + if (!priv->context) { + return SDL_SetError("Pipewire: Failed to create stream context (%i)", errno); + } + + props = PIPEWIRE_pw_properties_new(NULL, NULL); + if (!props) { + return SDL_SetError("Pipewire: Failed to create stream properties (%i)", errno); + } + + PIPEWIRE_pw_properties_set(props, PW_KEY_MEDIA_TYPE, "Audio"); + PIPEWIRE_pw_properties_set(props, PW_KEY_MEDIA_CATEGORY, iscapture ? "Capture" : "Playback"); + PIPEWIRE_pw_properties_set(props, PW_KEY_MEDIA_ROLE, stream_role); + PIPEWIRE_pw_properties_set(props, PW_KEY_APP_NAME, app_name); + PIPEWIRE_pw_properties_set(props, PW_KEY_NODE_NAME, stream_name); + PIPEWIRE_pw_properties_set(props, PW_KEY_NODE_DESCRIPTION, stream_name); + PIPEWIRE_pw_properties_setf(props, PW_KEY_NODE_LATENCY, "%u/%i", this->spec.samples, this->spec.freq); + PIPEWIRE_pw_properties_setf(props, PW_KEY_NODE_RATE, "1/%u", this->spec.freq); + PIPEWIRE_pw_properties_set(props, PW_KEY_NODE_ALWAYS_PROCESS, "true"); + + /* + * Pipewire 0.3.44 introduced PW_KEY_TARGET_OBJECT that takes either a path + * (PW_KEY_NODE_NAME) or node serial number (PE_KEY_OBJECT_SERIAL) to connect + * the stream to its target. The target_id parameter in pw_stream_connect() is + * now deprecated and should always be PW_ID_ANY. + */ + if (pipewire_version_at_least(0, 3, 44)) { + if (node_id != PW_ID_ANY) { + const struct io_node *node; + + PIPEWIRE_pw_thread_loop_lock(hotplug_loop); + node = io_list_get_by_id(node_id); + if (node) { + PIPEWIRE_pw_properties_set(props, PW_KEY_TARGET_OBJECT, node->path); + } + PIPEWIRE_pw_thread_loop_unlock(hotplug_loop); + + node_id = PW_ID_ANY; + } + } + + /* Create the new stream */ + priv->stream = PIPEWIRE_pw_stream_new_simple(PIPEWIRE_pw_thread_loop_get_loop(priv->loop), stream_name, props, + iscapture ? &stream_input_events : &stream_output_events, this); + if (!priv->stream) { + return SDL_SetError("Pipewire: Failed to create stream (%i)", errno); + } + + res = PIPEWIRE_pw_stream_connect(priv->stream, iscapture ? PW_DIRECTION_INPUT : PW_DIRECTION_OUTPUT, node_id, STREAM_FLAGS, + ¶ms, 1); + if (res != 0) { + return SDL_SetError("Pipewire: Failed to connect stream"); + } + + res = PIPEWIRE_pw_thread_loop_start(priv->loop); + if (res != 0) { + return SDL_SetError("Pipewire: Failed to start stream loop"); + } + + /* Wait until all init flags are set or the stream has failed. */ + PIPEWIRE_pw_thread_loop_lock(priv->loop); + while (priv->stream_init_status != PW_READY_FLAG_ALL_BITS && + PIPEWIRE_pw_stream_get_state(priv->stream, NULL) != PW_STREAM_STATE_ERROR) { + PIPEWIRE_pw_thread_loop_wait(priv->loop); + } + PIPEWIRE_pw_thread_loop_unlock(priv->loop); + + if (PIPEWIRE_pw_stream_get_state(priv->stream, &error) == PW_STREAM_STATE_ERROR) { + return SDL_SetError("Pipewire: Stream error: %s", error); + } + + /* If this is a capture stream, make sure the intermediate buffer was successfully allocated. */ + if (iscapture && !priv->buffer) { + return SDL_SetError("Pipewire: Failed to allocate source buffer"); + } + + return 0; +} + +static void PIPEWIRE_CloseDevice(_THIS) +{ + if (this->hidden->loop) { + PIPEWIRE_pw_thread_loop_stop(this->hidden->loop); + } + + if (this->hidden->stream) { + PIPEWIRE_pw_stream_destroy(this->hidden->stream); + } + + if (this->hidden->context) { + PIPEWIRE_pw_context_destroy(this->hidden->context); + } + + if (this->hidden->loop) { + PIPEWIRE_pw_thread_loop_destroy(this->hidden->loop); + } + + if (this->hidden->buffer) { + SDL_FreeDataQueue(this->hidden->buffer); + } + + SDL_free(this->hidden); +} + +static int PIPEWIRE_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture) +{ + struct io_node *node; + char *target; + int ret = 0; + + PIPEWIRE_pw_thread_loop_lock(hotplug_loop); + + if (iscapture) { + if (!pipewire_default_source_id) { + ret = SDL_SetError("PipeWire could not find a default source"); + goto failed; + } + target = pipewire_default_source_id; + } else { + if (!pipewire_default_sink_id) { + ret = SDL_SetError("PipeWire could not find a default sink"); + goto failed; + } + target = pipewire_default_sink_id; + } + + node = io_list_get_by_path(target); + if (!node) { + ret = SDL_SetError("PipeWire device list is out of sync with defaults"); + goto failed; + } + + if (name) { + *name = SDL_strdup(node->name); + } + SDL_copyp(spec, &node->spec); + +failed: + PIPEWIRE_pw_thread_loop_unlock(hotplug_loop); + return ret; +} + +static void PIPEWIRE_Deinitialize() +{ + if (pipewire_initialized) { + hotplug_loop_destroy(); + deinit_pipewire_library(); + pipewire_initialized = SDL_FALSE; + } +} + +static SDL_bool PIPEWIRE_Init(SDL_AudioDriverImpl *impl) +{ + if (!pipewire_initialized) { + if (init_pipewire_library() < 0) { + return SDL_FALSE; + } + + pipewire_initialized = SDL_TRUE; + + if (hotplug_loop_init() < 0) { + PIPEWIRE_Deinitialize(); + return SDL_FALSE; + } + } + + /* Set the function pointers */ + impl->DetectDevices = PIPEWIRE_DetectDevices; + impl->OpenDevice = PIPEWIRE_OpenDevice; + impl->CloseDevice = PIPEWIRE_CloseDevice; + impl->Deinitialize = PIPEWIRE_Deinitialize; + impl->GetDefaultAudioInfo = PIPEWIRE_GetDefaultAudioInfo; + + impl->HasCaptureSupport = SDL_TRUE; + impl->ProvidesOwnCallbackThread = SDL_TRUE; + impl->SupportsNonPow2Samples = SDL_TRUE; + + return SDL_TRUE; +} + +AudioBootStrap PIPEWIRE_bootstrap = { "pipewire", "Pipewire", PIPEWIRE_Init, SDL_FALSE }; + +#endif /* SDL_AUDIO_DRIVER_PIPEWIRE */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/audio/pipewire/SDL_pipewire.h b/SDL2-2.30.5/src/audio/pipewire/SDL_pipewire.h new file mode 100644 index 0000000..cf5817b --- /dev/null +++ b/SDL2-2.30.5/src/audio/pipewire/SDL_pipewire.h @@ -0,0 +1,47 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifndef SDL_pipewire_h_ +#define SDL_pipewire_h_ + +#include "../SDL_sysaudio.h" +#include + +/* Hidden "this" pointer for the audio functions */ +#define _THIS SDL_AudioDevice *this + +struct SDL_PrivateAudioData +{ + struct pw_thread_loop *loop; + struct pw_stream *stream; + struct pw_context *context; + struct SDL_DataQueue *buffer; + + size_t input_buffer_packet_size; + Sint32 stride; /* Bytes-per-frame */ + int stream_init_status; +}; + +#endif /* SDL_pipewire_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/audio/ps2/SDL_ps2audio.c b/SDL2-2.30.5/src/audio/ps2/SDL_ps2audio.c new file mode 100644 index 0000000..da5c5d3 --- /dev/null +++ b/SDL2-2.30.5/src/audio/ps2/SDL_ps2audio.c @@ -0,0 +1,177 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +/* Output audio to nowhere... */ + +#include "SDL_timer.h" +#include "SDL_audio.h" +#include "../SDL_audio_c.h" +#include "SDL_ps2audio.h" + +#include +#include +#include +#include + +/* The tag name used by PS2 audio */ +#define PS2AUDIO_DRIVER_NAME "ps2" + +static int PS2AUDIO_OpenDevice(_THIS, const char *devname) +{ + int i, mixlen; + struct audsrv_fmt_t format; + + this->hidden = (struct SDL_PrivateAudioData *) + SDL_malloc(sizeof(*this->hidden)); + if (!this->hidden) { + return SDL_OutOfMemory(); + } + SDL_zerop(this->hidden); + + /* These are the native supported audio PS2 configs */ + switch (this->spec.freq) { + case 11025: + case 12000: + case 22050: + case 24000: + case 32000: + case 44100: + case 48000: + this->spec.freq = this->spec.freq; + break; + default: + this->spec.freq = 48000; + break; + } + + this->spec.samples = 512; + this->spec.channels = this->spec.channels == 1 ? 1 : 2; + this->spec.format = this->spec.format == AUDIO_S8 ? AUDIO_S8 : AUDIO_S16; + + SDL_CalculateAudioSpec(&this->spec); + + format.bits = this->spec.format == AUDIO_S8 ? 8 : 16; + format.freq = this->spec.freq; + format.channels = this->spec.channels; + + this->hidden->channel = audsrv_set_format(&format); + audsrv_set_volume(MAX_VOLUME); + + if (this->hidden->channel < 0) { + free(this->hidden->rawbuf); + this->hidden->rawbuf = NULL; + return SDL_SetError("Couldn't reserve hardware channel"); + } + + /* Update the fragment size as size in bytes. */ + SDL_CalculateAudioSpec(&this->spec); + + /* Allocate the mixing buffer. Its size and starting address must + be a multiple of 64 bytes. Our sample count is already a multiple of + 64, so spec->size should be a multiple of 64 as well. */ + mixlen = this->spec.size * NUM_BUFFERS; + this->hidden->rawbuf = (Uint8 *)memalign(64, mixlen); + if (!this->hidden->rawbuf) { + return SDL_SetError("Couldn't allocate mixing buffer"); + } + + SDL_memset(this->hidden->rawbuf, 0, mixlen); + for (i = 0; i < NUM_BUFFERS; i++) { + this->hidden->mixbufs[i] = &this->hidden->rawbuf[i * this->spec.size]; + } + + this->hidden->next_buffer = 0; + return 0; +} + +static void PS2AUDIO_PlayDevice(_THIS) +{ + uint8_t *mixbuf = this->hidden->mixbufs[this->hidden->next_buffer]; + audsrv_play_audio((char *)mixbuf, this->spec.size); + + this->hidden->next_buffer = (this->hidden->next_buffer + 1) % NUM_BUFFERS; +} + +/* This function waits until it is possible to write a full sound buffer */ +static void PS2AUDIO_WaitDevice(_THIS) +{ + audsrv_wait_audio(this->spec.size); +} + +static Uint8 *PS2AUDIO_GetDeviceBuf(_THIS) +{ + return this->hidden->mixbufs[this->hidden->next_buffer]; +} + +static void PS2AUDIO_CloseDevice(_THIS) +{ + if (this->hidden->channel >= 0) { + audsrv_stop_audio(); + this->hidden->channel = -1; + } + + if (this->hidden->rawbuf) { + free(this->hidden->rawbuf); + this->hidden->rawbuf = NULL; + } +} + +static void PS2AUDIO_ThreadInit(_THIS) +{ + /* Increase the priority of this audio thread by 1 to put it + ahead of other SDL threads. */ + int32_t thid; + ee_thread_status_t status; + thid = GetThreadId(); + if (ReferThreadStatus(GetThreadId(), &status) == 0) { + ChangeThreadPriority(thid, status.current_priority - 1); + } +} + +static void PS2AUDIO_Deinitialize(void) +{ + deinit_audio_driver(); +} + +static SDL_bool PS2AUDIO_Init(SDL_AudioDriverImpl *impl) +{ + if (init_audio_driver() < 0) { + return SDL_FALSE; + } + + /* Set the function pointers */ + impl->OpenDevice = PS2AUDIO_OpenDevice; + impl->PlayDevice = PS2AUDIO_PlayDevice; + impl->WaitDevice = PS2AUDIO_WaitDevice; + impl->GetDeviceBuf = PS2AUDIO_GetDeviceBuf; + impl->CloseDevice = PS2AUDIO_CloseDevice; + impl->ThreadInit = PS2AUDIO_ThreadInit; + impl->Deinitialize = PS2AUDIO_Deinitialize; + impl->OnlyHasDefaultOutputDevice = SDL_TRUE; + return SDL_TRUE; /* this audio target is available. */ +} + +AudioBootStrap PS2AUDIO_bootstrap = { + "ps2", "PS2 audio driver", PS2AUDIO_Init, SDL_FALSE +}; + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/audio/ps2/SDL_ps2audio.h b/SDL2-2.30.5/src/audio/ps2/SDL_ps2audio.h new file mode 100644 index 0000000..5f5989d --- /dev/null +++ b/SDL2-2.30.5/src/audio/ps2/SDL_ps2audio.h @@ -0,0 +1,46 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifndef SDL_ps2audio_h_ +#define SDL_ps2audio_h_ + +#include "../SDL_sysaudio.h" + +/* Hidden "this" pointer for the audio functions */ +#define _THIS SDL_AudioDevice *this + +#define NUM_BUFFERS 2 + +struct SDL_PrivateAudioData +{ + /* The hardware output channel. */ + int channel; + /* The raw allocated mixing buffer. */ + Uint8 *rawbuf; + /* Individual mixing buffers. */ + Uint8 *mixbufs[NUM_BUFFERS]; + /* Index of the next available mixing buffer. */ + int next_buffer; +}; + +#endif /* SDL_ps2audio_h_ */ +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/audio/psp/SDL_pspaudio.c b/SDL2-2.30.5/src/audio/psp/SDL_pspaudio.c similarity index 57% rename from SDL2-2.0.12/src/audio/psp/SDL_pspaudio.c rename to SDL2-2.30.5/src/audio/psp/SDL_pspaudio.c index bd27d35..30e1c23 100644 --- a/SDL2-2.0.12/src/audio/psp/SDL_pspaudio.c +++ b/SDL2-2.30.5/src/audio/psp/SDL_pspaudio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,12 +20,12 @@ */ #include "../../SDL_internal.h" -#if SDL_AUDIO_DRIVER_PSP +#ifdef SDL_AUDIO_DRIVER_PSP #include #include #include -#include +#include /* memalign() */ #include "SDL_audio.h" #include "SDL_error.h" @@ -39,30 +39,66 @@ #include /* The tag name used by PSP audio */ -#define PSPAUDIO_DRIVER_NAME "psp" +#define PSPAUDIO_DRIVER_NAME "psp" -static int -PSPAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) +static inline SDL_bool isBasicAudioConfig(const SDL_AudioSpec *spec) +{ + return spec->freq == 44100; +} + +static int PSPAUDIO_OpenDevice(_THIS, const char *devname) { int format, mixlen, i; + this->hidden = (struct SDL_PrivateAudioData *) SDL_malloc(sizeof(*this->hidden)); - if (this->hidden == NULL) { + if (!this->hidden) { return SDL_OutOfMemory(); } SDL_zerop(this->hidden); - switch (this->spec.format & 0xff) { - case 8: - case 16: - this->spec.format = AUDIO_S16LSB; + + /* device only natively supports S16LSB */ + this->spec.format = AUDIO_S16LSB; + + /* PSP has some limitations with the Audio. It fully supports 44.1KHz (Mono & Stereo), + however with frequencies differents than 44.1KHz, it just supports Stereo, + so a resampler must be done for these scenarios */ + if (isBasicAudioConfig(&this->spec)) { + /* The sample count must be a multiple of 64. */ + this->spec.samples = PSP_AUDIO_SAMPLE_ALIGN(this->spec.samples); + /* The number of channels (1 or 2). */ + this->spec.channels = this->spec.channels == 1 ? 1 : 2; + format = this->spec.channels == 1 ? PSP_AUDIO_FORMAT_MONO : PSP_AUDIO_FORMAT_STEREO; + this->hidden->channel = sceAudioChReserve(PSP_AUDIO_NEXT_CHANNEL, this->spec.samples, format); + } else { + /* 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11050, 8000 */ + switch (this->spec.freq) { + case 8000: + case 11025: + case 12000: + case 16000: + case 22050: + case 24000: + case 32000: + case 44100: + case 48000: + this->spec.freq = this->spec.freq; break; default: - return SDL_SetError("Unsupported audio format"); + this->spec.freq = 48000; + break; + } + /* The number of samples to output in one output call (min 17, max 4111). */ + this->spec.samples = this->spec.samples < 17 ? 17 : (this->spec.samples > 4111 ? 4111 : this->spec.samples); + this->spec.channels = 2; /* we're forcing the hardware to stereo. */ + this->hidden->channel = sceAudioSRCChReserve(this->spec.samples, this->spec.freq, 2); } - /* The sample count must be a multiple of 64. */ - this->spec.samples = PSP_AUDIO_SAMPLE_ALIGN(this->spec.samples); - this->spec.freq = 44100; + if (this->hidden->channel < 0) { + free(this->hidden->rawbuf); + this->hidden->rawbuf = NULL; + return SDL_SetError("Couldn't reserve hardware channel"); + } /* Update the fragment size as size in bytes. */ SDL_CalculateAudioSpec(&this->spec); @@ -71,26 +107,12 @@ PSPAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) be a multiple of 64 bytes. Our sample count is already a multiple of 64, so spec->size should be a multiple of 64 as well. */ mixlen = this->spec.size * NUM_BUFFERS; - this->hidden->rawbuf = (Uint8 *) memalign(64, mixlen); - if (this->hidden->rawbuf == NULL) { + this->hidden->rawbuf = (Uint8 *)memalign(64, mixlen); + if (!this->hidden->rawbuf) { return SDL_SetError("Couldn't allocate mixing buffer"); } - /* Setup the hardware channel. */ - if (this->spec.channels == 1) { - format = PSP_AUDIO_FORMAT_MONO; - } else { - this->spec.channels = 2; - format = PSP_AUDIO_FORMAT_STEREO; - } - this->hidden->channel = sceAudioChReserve(PSP_AUDIO_NEXT_CHANNEL, this->spec.samples, format); - if (this->hidden->channel < 0) { - free(this->hidden->rawbuf); - this->hidden->rawbuf = NULL; - return SDL_SetError("Couldn't reserve hardware channel"); - } - - memset(this->hidden->rawbuf, 0, mixlen); + SDL_memset(this->hidden->rawbuf, 0, mixlen); for (i = 0; i < NUM_BUFFERS; i++) { this->hidden->mixbufs[i] = &this->hidden->rawbuf[i * this->spec.size]; } @@ -102,9 +124,9 @@ PSPAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) static void PSPAUDIO_PlayDevice(_THIS) { Uint8 *mixbuf = this->hidden->mixbufs[this->hidden->next_buffer]; - - if (this->spec.channels == 1) { - sceAudioOutputBlocking(this->hidden->channel, PSP_AUDIO_VOLUME_MAX, mixbuf); + if (!isBasicAudioConfig(&this->spec)) { + SDL_assert(this->spec.channels == 2); + sceAudioSRCOutputBlocking(PSP_AUDIO_VOLUME_MAX, mixbuf); } else { sceAudioOutputPannedBlocking(this->hidden->channel, PSP_AUDIO_VOLUME_MAX, PSP_AUDIO_VOLUME_MAX, mixbuf); } @@ -117,6 +139,7 @@ static void PSPAUDIO_WaitDevice(_THIS) { /* Because we block when sending audio, there's no need for this function to do anything. */ } + static Uint8 *PSPAUDIO_GetDeviceBuf(_THIS) { return this->hidden->mixbufs[this->hidden->next_buffer]; @@ -125,10 +148,18 @@ static Uint8 *PSPAUDIO_GetDeviceBuf(_THIS) static void PSPAUDIO_CloseDevice(_THIS) { if (this->hidden->channel >= 0) { - sceAudioChRelease(this->hidden->channel); + if (!isBasicAudioConfig(&this->spec)) { + sceAudioSRCChRelease(); + } else { + sceAudioChRelease(this->hidden->channel); + } + this->hidden->channel = -1; + } + + if (this->hidden->rawbuf) { + free(this->hidden->rawbuf); + this->hidden->rawbuf = NULL; } - free(this->hidden->rawbuf); /* this uses memalign(), not SDL_malloc(). */ - SDL_free(this->hidden); } static void PSPAUDIO_ThreadInit(_THIS) @@ -144,9 +175,7 @@ static void PSPAUDIO_ThreadInit(_THIS) } } - -static int -PSPAUDIO_Init(SDL_AudioDriverImpl * impl) +static SDL_bool PSPAUDIO_Init(SDL_AudioDriverImpl *impl) { /* Set the function pointers */ impl->OpenDevice = PSPAUDIO_OpenDevice; @@ -157,25 +186,18 @@ PSPAUDIO_Init(SDL_AudioDriverImpl * impl) impl->ThreadInit = PSPAUDIO_ThreadInit; /* PSP audio device */ - impl->OnlyHasDefaultOutputDevice = 1; -/* - impl->HasCaptureSupport = 1; - - impl->OnlyHasDefaultCaptureDevice = 1; -*/ + impl->OnlyHasDefaultOutputDevice = SDL_TRUE; /* - impl->DetectDevices = DSOUND_DetectDevices; - impl->Deinitialize = DSOUND_Deinitialize; + impl->HasCaptureSupport = SDL_TRUE; + impl->OnlyHasDefaultCaptureDevice = SDL_TRUE; */ - return 1; /* this audio target is available. */ + return SDL_TRUE; /* this audio target is available. */ } AudioBootStrap PSPAUDIO_bootstrap = { - "psp", "PSP audio driver", PSPAUDIO_Init, 0 + "psp", "PSP audio driver", PSPAUDIO_Init, SDL_FALSE }; - /* SDL_AUDI */ - #endif /* SDL_AUDIO_DRIVER_PSP */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/audio/psp/SDL_pspaudio.h b/SDL2-2.30.5/src/audio/psp/SDL_pspaudio.h similarity index 84% rename from SDL2-2.0.12/src/audio/psp/SDL_pspaudio.h rename to SDL2-2.30.5/src/audio/psp/SDL_pspaudio.h index 58a0c1c..ba35102 100644 --- a/SDL2-2.0.12/src/audio/psp/SDL_pspaudio.h +++ b/SDL2-2.30.5/src/audio/psp/SDL_pspaudio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -25,19 +25,20 @@ #include "../SDL_sysaudio.h" /* Hidden "this" pointer for the audio functions */ -#define _THIS SDL_AudioDevice *this +#define _THIS SDL_AudioDevice *this #define NUM_BUFFERS 2 -struct SDL_PrivateAudioData { +struct SDL_PrivateAudioData +{ /* The hardware output channel. */ - int channel; + int channel; /* The raw allocated mixing buffer. */ - Uint8 *rawbuf; + Uint8 *rawbuf; /* Individual mixing buffers. */ - Uint8 *mixbufs[NUM_BUFFERS]; + Uint8 *mixbufs[NUM_BUFFERS]; /* Index of the next available mixing buffer. */ - int next_buffer; + int next_buffer; }; #endif /* SDL_pspaudio_h_ */ diff --git a/SDL2-2.30.5/src/audio/pulseaudio/SDL_pulseaudio.c b/SDL2-2.30.5/src/audio/pulseaudio/SDL_pulseaudio.c new file mode 100644 index 0000000..5e2bb6f --- /dev/null +++ b/SDL2-2.30.5/src/audio/pulseaudio/SDL_pulseaudio.c @@ -0,0 +1,996 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_hints.h" + +#ifdef SDL_AUDIO_DRIVER_PULSEAUDIO + +/* Allow access to a raw mixing buffer */ + +#ifdef HAVE_SIGNAL_H +#include +#endif +#include +#include + +#include "SDL_timer.h" +#include "SDL_audio.h" +#include "../SDL_audio_c.h" +#include "SDL_pulseaudio.h" +#include "SDL_loadso.h" +#include "../../thread/SDL_systhread.h" + +/* should we include monitors in the device list? Set at SDL_Init time */ +static SDL_bool include_monitors = SDL_FALSE; + +static pa_threaded_mainloop *pulseaudio_threaded_mainloop = NULL; +static pa_context *pulseaudio_context = NULL; +static SDL_Thread *pulseaudio_hotplug_thread = NULL; +static SDL_atomic_t pulseaudio_hotplug_thread_active; + +/* These are the OS identifiers (i.e. ALSA strings)... */ +static char *default_sink_path = NULL; +static char *default_source_path = NULL; +/* ... and these are the descriptions we use in GetDefaultAudioInfo. */ +static char *default_sink_name = NULL; +static char *default_source_name = NULL; + + +static const char *(*PULSEAUDIO_pa_get_library_version)(void); +static pa_channel_map *(*PULSEAUDIO_pa_channel_map_init_auto)( + pa_channel_map *, unsigned, pa_channel_map_def_t); +static const char *(*PULSEAUDIO_pa_strerror)(int); + +static pa_threaded_mainloop *(*PULSEAUDIO_pa_threaded_mainloop_new)(void); +static void (*PULSEAUDIO_pa_threaded_mainloop_set_name)(pa_threaded_mainloop *, const char *); +static pa_mainloop_api *(*PULSEAUDIO_pa_threaded_mainloop_get_api)(pa_threaded_mainloop *); +static int (*PULSEAUDIO_pa_threaded_mainloop_start)(pa_threaded_mainloop *); +static void (*PULSEAUDIO_pa_threaded_mainloop_stop)(pa_threaded_mainloop *); +static void (*PULSEAUDIO_pa_threaded_mainloop_lock)(pa_threaded_mainloop *); +static void (*PULSEAUDIO_pa_threaded_mainloop_unlock)(pa_threaded_mainloop *); +static void (*PULSEAUDIO_pa_threaded_mainloop_wait)(pa_threaded_mainloop *); +static void (*PULSEAUDIO_pa_threaded_mainloop_signal)(pa_threaded_mainloop *, int); +static void (*PULSEAUDIO_pa_threaded_mainloop_free)(pa_threaded_mainloop *); + +static pa_operation_state_t (*PULSEAUDIO_pa_operation_get_state)( + const pa_operation *); +static void (*PULSEAUDIO_pa_operation_cancel)(pa_operation *); +static void (*PULSEAUDIO_pa_operation_unref)(pa_operation *); + +static pa_context *(*PULSEAUDIO_pa_context_new)(pa_mainloop_api *, + const char *); +static void (*PULSEAUDIO_pa_context_set_state_callback)(pa_context *, pa_context_notify_cb_t, void *); +static int (*PULSEAUDIO_pa_context_connect)(pa_context *, const char *, + pa_context_flags_t, const pa_spawn_api *); +static pa_operation *(*PULSEAUDIO_pa_context_get_sink_info_list)(pa_context *, pa_sink_info_cb_t, void *); +static pa_operation *(*PULSEAUDIO_pa_context_get_source_info_list)(pa_context *, pa_source_info_cb_t, void *); +static pa_operation *(*PULSEAUDIO_pa_context_get_sink_info_by_index)(pa_context *, uint32_t, pa_sink_info_cb_t, void *); +static pa_operation *(*PULSEAUDIO_pa_context_get_source_info_by_index)(pa_context *, uint32_t, pa_source_info_cb_t, void *); +static pa_context_state_t (*PULSEAUDIO_pa_context_get_state)(const pa_context *); +static pa_operation *(*PULSEAUDIO_pa_context_subscribe)(pa_context *, pa_subscription_mask_t, pa_context_success_cb_t, void *); +static void (*PULSEAUDIO_pa_context_set_subscribe_callback)(pa_context *, pa_context_subscribe_cb_t, void *); +static void (*PULSEAUDIO_pa_context_disconnect)(pa_context *); +static void (*PULSEAUDIO_pa_context_unref)(pa_context *); + +static pa_stream *(*PULSEAUDIO_pa_stream_new)(pa_context *, const char *, + const pa_sample_spec *, const pa_channel_map *); +static void (*PULSEAUDIO_pa_stream_set_state_callback)(pa_stream *, pa_stream_notify_cb_t, void *); +static int (*PULSEAUDIO_pa_stream_connect_playback)(pa_stream *, const char *, + const pa_buffer_attr *, pa_stream_flags_t, const pa_cvolume *, pa_stream *); +static int (*PULSEAUDIO_pa_stream_connect_record)(pa_stream *, const char *, + const pa_buffer_attr *, pa_stream_flags_t); +static pa_stream_state_t (*PULSEAUDIO_pa_stream_get_state)(const pa_stream *); +static size_t (*PULSEAUDIO_pa_stream_writable_size)(const pa_stream *); +static size_t (*PULSEAUDIO_pa_stream_readable_size)(const pa_stream *); +static int (*PULSEAUDIO_pa_stream_write)(pa_stream *, const void *, size_t, + pa_free_cb_t, int64_t, pa_seek_mode_t); +static pa_operation *(*PULSEAUDIO_pa_stream_drain)(pa_stream *, + pa_stream_success_cb_t, void *); +static int (*PULSEAUDIO_pa_stream_peek)(pa_stream *, const void **, size_t *); +static int (*PULSEAUDIO_pa_stream_drop)(pa_stream *); +static pa_operation *(*PULSEAUDIO_pa_stream_flush)(pa_stream *, + pa_stream_success_cb_t, void *); +static int (*PULSEAUDIO_pa_stream_disconnect)(pa_stream *); +static void (*PULSEAUDIO_pa_stream_unref)(pa_stream *); +static void (*PULSEAUDIO_pa_stream_set_write_callback)(pa_stream *, pa_stream_request_cb_t, void *); +static void (*PULSEAUDIO_pa_stream_set_read_callback)(pa_stream *, pa_stream_request_cb_t, void *); +static pa_operation *(*PULSEAUDIO_pa_context_get_server_info)(pa_context *, pa_server_info_cb_t, void *); + +static int load_pulseaudio_syms(void); + +#ifdef SDL_AUDIO_DRIVER_PULSEAUDIO_DYNAMIC + +static const char *pulseaudio_library = SDL_AUDIO_DRIVER_PULSEAUDIO_DYNAMIC; +static void *pulseaudio_handle = NULL; + +static int load_pulseaudio_sym(const char *fn, void **addr) +{ + *addr = SDL_LoadFunction(pulseaudio_handle, fn); + if (!*addr) { + /* Don't call SDL_SetError(): SDL_LoadFunction already did. */ + return 0; + } + + return 1; +} + +/* cast funcs to char* first, to please GCC's strict aliasing rules. */ +#define SDL_PULSEAUDIO_SYM(x) \ + if (!load_pulseaudio_sym(#x, (void **)(char *)&PULSEAUDIO_##x)) \ + return -1 + +static void UnloadPulseAudioLibrary(void) +{ + if (pulseaudio_handle) { + SDL_UnloadObject(pulseaudio_handle); + pulseaudio_handle = NULL; + } +} + +static int LoadPulseAudioLibrary(void) +{ + int retval = 0; + if (!pulseaudio_handle) { + pulseaudio_handle = SDL_LoadObject(pulseaudio_library); + if (!pulseaudio_handle) { + retval = -1; + /* Don't call SDL_SetError(): SDL_LoadObject already did. */ + } else { + retval = load_pulseaudio_syms(); + if (retval < 0) { + UnloadPulseAudioLibrary(); + } + } + } + return retval; +} + +#else + +#define SDL_PULSEAUDIO_SYM(x) PULSEAUDIO_##x = x + +static void UnloadPulseAudioLibrary(void) +{ +} + +static int LoadPulseAudioLibrary(void) +{ + load_pulseaudio_syms(); + return 0; +} + +#endif /* SDL_AUDIO_DRIVER_PULSEAUDIO_DYNAMIC */ + +static int load_pulseaudio_syms(void) +{ + SDL_PULSEAUDIO_SYM(pa_get_library_version); + SDL_PULSEAUDIO_SYM(pa_threaded_mainloop_new); + SDL_PULSEAUDIO_SYM(pa_threaded_mainloop_get_api); + SDL_PULSEAUDIO_SYM(pa_threaded_mainloop_start); + SDL_PULSEAUDIO_SYM(pa_threaded_mainloop_stop); + SDL_PULSEAUDIO_SYM(pa_threaded_mainloop_lock); + SDL_PULSEAUDIO_SYM(pa_threaded_mainloop_unlock); + SDL_PULSEAUDIO_SYM(pa_threaded_mainloop_wait); + SDL_PULSEAUDIO_SYM(pa_threaded_mainloop_signal); + SDL_PULSEAUDIO_SYM(pa_threaded_mainloop_free); + SDL_PULSEAUDIO_SYM(pa_operation_get_state); + SDL_PULSEAUDIO_SYM(pa_operation_cancel); + SDL_PULSEAUDIO_SYM(pa_operation_unref); + SDL_PULSEAUDIO_SYM(pa_context_new); + SDL_PULSEAUDIO_SYM(pa_context_set_state_callback); + SDL_PULSEAUDIO_SYM(pa_context_connect); + SDL_PULSEAUDIO_SYM(pa_context_get_sink_info_list); + SDL_PULSEAUDIO_SYM(pa_context_get_source_info_list); + SDL_PULSEAUDIO_SYM(pa_context_get_sink_info_by_index); + SDL_PULSEAUDIO_SYM(pa_context_get_source_info_by_index); + SDL_PULSEAUDIO_SYM(pa_context_get_state); + SDL_PULSEAUDIO_SYM(pa_context_subscribe); + SDL_PULSEAUDIO_SYM(pa_context_set_subscribe_callback); + SDL_PULSEAUDIO_SYM(pa_context_disconnect); + SDL_PULSEAUDIO_SYM(pa_context_unref); + SDL_PULSEAUDIO_SYM(pa_stream_new); + SDL_PULSEAUDIO_SYM(pa_stream_set_state_callback); + SDL_PULSEAUDIO_SYM(pa_stream_connect_playback); + SDL_PULSEAUDIO_SYM(pa_stream_connect_record); + SDL_PULSEAUDIO_SYM(pa_stream_get_state); + SDL_PULSEAUDIO_SYM(pa_stream_writable_size); + SDL_PULSEAUDIO_SYM(pa_stream_readable_size); + SDL_PULSEAUDIO_SYM(pa_stream_write); + SDL_PULSEAUDIO_SYM(pa_stream_drain); + SDL_PULSEAUDIO_SYM(pa_stream_disconnect); + SDL_PULSEAUDIO_SYM(pa_stream_peek); + SDL_PULSEAUDIO_SYM(pa_stream_drop); + SDL_PULSEAUDIO_SYM(pa_stream_flush); + SDL_PULSEAUDIO_SYM(pa_stream_unref); + SDL_PULSEAUDIO_SYM(pa_channel_map_init_auto); + SDL_PULSEAUDIO_SYM(pa_strerror); + SDL_PULSEAUDIO_SYM(pa_stream_set_write_callback); + SDL_PULSEAUDIO_SYM(pa_stream_set_read_callback); + SDL_PULSEAUDIO_SYM(pa_context_get_server_info); + + /* optional */ +#ifdef SDL_AUDIO_DRIVER_PULSEAUDIO_DYNAMIC + load_pulseaudio_sym("pa_threaded_mainloop_set_name", (void **)(char *)&PULSEAUDIO_pa_threaded_mainloop_set_name); +#elif (PA_PROTOCOL_VERSION >= 29) + PULSEAUDIO_pa_threaded_mainloop_set_name = pa_threaded_mainloop_set_name; +#else + PULSEAUDIO_pa_threaded_mainloop_set_name = NULL; +#endif + + return 0; +} + +static SDL_INLINE int squashVersion(const int major, const int minor, const int patch) +{ + return ((major & 0xFF) << 16) | ((minor & 0xFF) << 8) | (patch & 0xFF); +} + +/* Workaround for older pulse: pa_context_new() must have non-NULL appname */ +static const char *getAppName(void) +{ + const char *retval = SDL_GetHint(SDL_HINT_AUDIO_DEVICE_APP_NAME); + if (retval && *retval) { + return retval; + } + retval = SDL_GetHint(SDL_HINT_APP_NAME); + if (retval && *retval) { + return retval; + } else { + const char *verstr = PULSEAUDIO_pa_get_library_version(); + retval = "SDL Application"; /* the "oh well" default. */ + if (verstr) { + int maj, min, patch; + if (SDL_sscanf(verstr, "%d.%d.%d", &maj, &min, &patch) == 3) { + if (squashVersion(maj, min, patch) >= squashVersion(0, 9, 15)) { + retval = NULL; /* 0.9.15+ handles NULL correctly. */ + } + } + } + } + return retval; +} + +/* This function assume you are holding `mainloop`'s lock and that `o` has a callback that will signal pulseaudio_threaded_mainloop. + The caller may optionally call pa_threaded_mainloop_accept() if the signal is blocking. The operation is + unref'd in here, assuming you did the work in the callback and just want to know it's done, though. */ +static void WaitForPulseOperation(pa_operation *o) +{ + /* This checks for NO errors currently. Either fix that, check results elsewhere, or do things you don't care about. */ + SDL_assert(pulseaudio_threaded_mainloop != NULL); + if (o) { + while (PULSEAUDIO_pa_operation_get_state(o) == PA_OPERATION_RUNNING) { + PULSEAUDIO_pa_threaded_mainloop_wait(pulseaudio_threaded_mainloop); /* this releases the lock and blocks on an internal condition variable. */ + } + PULSEAUDIO_pa_operation_unref(o); + } +} + +static void DisconnectFromPulseServer(void) +{ + if (pulseaudio_threaded_mainloop) { + PULSEAUDIO_pa_threaded_mainloop_stop(pulseaudio_threaded_mainloop); + } + if (pulseaudio_context) { + PULSEAUDIO_pa_context_disconnect(pulseaudio_context); + PULSEAUDIO_pa_context_unref(pulseaudio_context); + pulseaudio_context = NULL; + } + if (pulseaudio_threaded_mainloop) { + PULSEAUDIO_pa_threaded_mainloop_free(pulseaudio_threaded_mainloop); + pulseaudio_threaded_mainloop = NULL; + } +} + +static void PulseContextStateChangeCallback(pa_context *context, void *userdata) +{ + PULSEAUDIO_pa_threaded_mainloop_signal(pulseaudio_threaded_mainloop, 0); /* just signal any waiting code, it can look up the details. */ +} + +static int ConnectToPulseServer(void) +{ + pa_mainloop_api *mainloop_api = NULL; + int state = 0; + + SDL_assert(pulseaudio_threaded_mainloop == NULL); + SDL_assert(pulseaudio_context == NULL); + + /* Set up a new main loop */ + if (!(pulseaudio_threaded_mainloop = PULSEAUDIO_pa_threaded_mainloop_new())) { + return SDL_SetError("pa_threaded_mainloop_new() failed"); + } + + if (PULSEAUDIO_pa_threaded_mainloop_set_name) { + PULSEAUDIO_pa_threaded_mainloop_set_name(pulseaudio_threaded_mainloop, "PulseMainloop"); + } + + if (PULSEAUDIO_pa_threaded_mainloop_start(pulseaudio_threaded_mainloop) < 0) { + PULSEAUDIO_pa_threaded_mainloop_free(pulseaudio_threaded_mainloop); + pulseaudio_threaded_mainloop = NULL; + return SDL_SetError("pa_threaded_mainloop_start() failed"); + } + + PULSEAUDIO_pa_threaded_mainloop_lock(pulseaudio_threaded_mainloop); + + mainloop_api = PULSEAUDIO_pa_threaded_mainloop_get_api(pulseaudio_threaded_mainloop); + SDL_assert(mainloop_api != NULL); /* this never fails, right? */ + + pulseaudio_context = PULSEAUDIO_pa_context_new(mainloop_api, getAppName()); + if (!pulseaudio_context) { + SDL_SetError("pa_context_new() failed"); + goto failed; + } + + PULSEAUDIO_pa_context_set_state_callback(pulseaudio_context, PulseContextStateChangeCallback, NULL); + + /* Connect to the PulseAudio server */ + if (PULSEAUDIO_pa_context_connect(pulseaudio_context, NULL, 0, NULL) < 0) { + SDL_SetError("Could not setup connection to PulseAudio"); + goto failed; + } + + state = PULSEAUDIO_pa_context_get_state(pulseaudio_context); + while (PA_CONTEXT_IS_GOOD(state) && (state != PA_CONTEXT_READY)) { + PULSEAUDIO_pa_threaded_mainloop_wait(pulseaudio_threaded_mainloop); + state = PULSEAUDIO_pa_context_get_state(pulseaudio_context); + } + + if (state != PA_CONTEXT_READY) { + return SDL_SetError("Could not connect to PulseAudio"); + goto failed; + } + + PULSEAUDIO_pa_threaded_mainloop_unlock(pulseaudio_threaded_mainloop); + + return 0; /* connected and ready! */ + +failed: + PULSEAUDIO_pa_threaded_mainloop_unlock(pulseaudio_threaded_mainloop); + DisconnectFromPulseServer(); + return -1; +} + +/* This function waits until it is possible to write a full sound buffer */ +static void PULSEAUDIO_WaitDevice(_THIS) +{ + /* this is a no-op; we wait in PULSEAUDIO_PlayDevice now. */ +} + +static void WriteCallback(pa_stream *p, size_t nbytes, void *userdata) +{ + struct SDL_PrivateAudioData *h = (struct SDL_PrivateAudioData *)userdata; + /*printf("PULSEAUDIO WRITE CALLBACK! nbytes=%u\n", (unsigned int) nbytes);*/ + h->bytes_requested += nbytes; + PULSEAUDIO_pa_threaded_mainloop_signal(pulseaudio_threaded_mainloop, 0); +} + +static void PULSEAUDIO_PlayDevice(_THIS) +{ + struct SDL_PrivateAudioData *h = this->hidden; + int available = h->mixlen; + int written = 0; + int cpy; + + /*printf("PULSEAUDIO PLAYDEVICE START! mixlen=%d\n", available);*/ + + PULSEAUDIO_pa_threaded_mainloop_lock(pulseaudio_threaded_mainloop); + + while (SDL_AtomicGet(&this->enabled) && (available > 0)) { + cpy = SDL_min(h->bytes_requested, available); + if (cpy) { + if (PULSEAUDIO_pa_stream_write(h->stream, h->mixbuf + written, cpy, NULL, 0LL, PA_SEEK_RELATIVE) < 0) { + SDL_OpenedAudioDeviceDisconnected(this); + break; + } + /*printf("PULSEAUDIO FEED! nbytes=%u\n", (unsigned int) cpy);*/ + h->bytes_requested -= cpy; + written += cpy; + available -= cpy; + } + + if (available > 0) { + /* let WriteCallback fire if necessary. */ + /*printf("PULSEAUDIO WAIT IN PLAYDEVICE!\n");*/ + PULSEAUDIO_pa_threaded_mainloop_wait(pulseaudio_threaded_mainloop); + + if ((PULSEAUDIO_pa_context_get_state(pulseaudio_context) != PA_CONTEXT_READY) || (PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY)) { + /*printf("PULSEAUDIO DEVICE FAILURE IN PLAYDEVICE!\n");*/ + SDL_OpenedAudioDeviceDisconnected(this); + break; + } + } + } + + PULSEAUDIO_pa_threaded_mainloop_unlock(pulseaudio_threaded_mainloop); + + /*printf("PULSEAUDIO PLAYDEVICE END! written=%d\n", written);*/ +} + +static Uint8 *PULSEAUDIO_GetDeviceBuf(_THIS) +{ + return this->hidden->mixbuf; +} + +static void ReadCallback(pa_stream *p, size_t nbytes, void *userdata) +{ + /*printf("PULSEAUDIO READ CALLBACK! nbytes=%u\n", (unsigned int) nbytes);*/ + PULSEAUDIO_pa_threaded_mainloop_signal(pulseaudio_threaded_mainloop, 0); /* the capture code queries what it needs, we just need to signal to end any wait */ +} + +static int PULSEAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen) +{ + struct SDL_PrivateAudioData *h = this->hidden; + const void *data = NULL; + size_t nbytes = 0; + int retval = 0; + + PULSEAUDIO_pa_threaded_mainloop_lock(pulseaudio_threaded_mainloop); + + while (SDL_AtomicGet(&this->enabled)) { + if (h->capturebuf) { + const int cpy = SDL_min(buflen, h->capturelen); + SDL_memcpy(buffer, h->capturebuf, cpy); + /*printf("PULSEAUDIO: fed %d captured bytes\n", cpy);*/ + h->capturebuf += cpy; + h->capturelen -= cpy; + if (h->capturelen == 0) { + h->capturebuf = NULL; + PULSEAUDIO_pa_stream_drop(h->stream); /* done with this fragment. */ + } + retval = cpy; /* new data, return it. */ + break; + } + + while (SDL_AtomicGet(&this->enabled) && (PULSEAUDIO_pa_stream_readable_size(h->stream) == 0)) { + PULSEAUDIO_pa_threaded_mainloop_wait(pulseaudio_threaded_mainloop); + if ((PULSEAUDIO_pa_context_get_state(pulseaudio_context) != PA_CONTEXT_READY) || (PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY)) { + /*printf("PULSEAUDIO DEVICE FAILURE IN CAPTUREFROMDEVICE!\n");*/ + SDL_OpenedAudioDeviceDisconnected(this); + retval = -1; + break; + } + } + + if ((retval == -1) || !SDL_AtomicGet(&this->enabled)) { /* in case this happened while we were blocking. */ + retval = -1; + break; + } + + /* a new fragment is available! */ + PULSEAUDIO_pa_stream_peek(h->stream, &data, &nbytes); + SDL_assert(nbytes > 0); + /* If data == NULL, then the buffer had a hole, ignore that */ + if (!data) { + PULSEAUDIO_pa_stream_drop(h->stream); /* drop this fragment. */ + } else { + /* store this fragment's data, start feeding it to SDL. */ + /*printf("PULSEAUDIO: captured %d new bytes\n", (int) nbytes);*/ + h->capturebuf = (const Uint8 *)data; + h->capturelen = nbytes; + } + } + + PULSEAUDIO_pa_threaded_mainloop_unlock(pulseaudio_threaded_mainloop); + + return retval; +} + +static void PULSEAUDIO_FlushCapture(_THIS) +{ + struct SDL_PrivateAudioData *h = this->hidden; + const void *data = NULL; + size_t nbytes = 0; + + PULSEAUDIO_pa_threaded_mainloop_lock(pulseaudio_threaded_mainloop); + + if (h->capturebuf) { + PULSEAUDIO_pa_stream_drop(h->stream); + h->capturebuf = NULL; + h->capturelen = 0; + } + + while (SDL_AtomicGet(&this->enabled) && (PULSEAUDIO_pa_stream_readable_size(h->stream) > 0)) { + PULSEAUDIO_pa_threaded_mainloop_wait(pulseaudio_threaded_mainloop); + if ((PULSEAUDIO_pa_context_get_state(pulseaudio_context) != PA_CONTEXT_READY) || (PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY)) { + /*printf("PULSEAUDIO DEVICE FAILURE IN FLUSHCAPTURE!\n");*/ + SDL_OpenedAudioDeviceDisconnected(this); + break; + } + + if (PULSEAUDIO_pa_stream_readable_size(h->stream) > 0) { + /* a new fragment is available! Just dump it. */ + PULSEAUDIO_pa_stream_peek(h->stream, &data, &nbytes); + PULSEAUDIO_pa_stream_drop(h->stream); /* drop this fragment. */ + } + } + + PULSEAUDIO_pa_threaded_mainloop_unlock(pulseaudio_threaded_mainloop); +} + +static void PULSEAUDIO_CloseDevice(_THIS) +{ + PULSEAUDIO_pa_threaded_mainloop_lock(pulseaudio_threaded_mainloop); + + if (this->hidden->stream) { + if (this->hidden->capturebuf) { + PULSEAUDIO_pa_stream_drop(this->hidden->stream); + } + PULSEAUDIO_pa_stream_disconnect(this->hidden->stream); + PULSEAUDIO_pa_stream_unref(this->hidden->stream); + } + + PULSEAUDIO_pa_threaded_mainloop_unlock(pulseaudio_threaded_mainloop); + + SDL_free(this->hidden->mixbuf); + SDL_free(this->hidden->device_name); + SDL_free(this->hidden); +} + +static void SinkDeviceNameCallback(pa_context *c, const pa_sink_info *i, int is_last, void *data) +{ + if (i) { + char **devname = (char **)data; + *devname = SDL_strdup(i->name); + } + PULSEAUDIO_pa_threaded_mainloop_signal(pulseaudio_threaded_mainloop, 0); +} + +static void SourceDeviceNameCallback(pa_context *c, const pa_source_info *i, int is_last, void *data) +{ + if (i) { + char **devname = (char **)data; + *devname = SDL_strdup(i->name); + } + PULSEAUDIO_pa_threaded_mainloop_signal(pulseaudio_threaded_mainloop, 0); +} + +static SDL_bool FindDeviceName(struct SDL_PrivateAudioData *h, const SDL_bool iscapture, void *handle) +{ + const uint32_t idx = ((uint32_t)((intptr_t)handle)) - 1; + + if (!handle) { /* NULL == default device. */ + return SDL_TRUE; + } + + if (iscapture) { + WaitForPulseOperation(PULSEAUDIO_pa_context_get_source_info_by_index(pulseaudio_context, idx, SourceDeviceNameCallback, &h->device_name)); + } else { + WaitForPulseOperation(PULSEAUDIO_pa_context_get_sink_info_by_index(pulseaudio_context, idx, SinkDeviceNameCallback, &h->device_name)); + } + + return h->device_name != NULL; +} + +static void PulseStreamStateChangeCallback(pa_stream *stream, void *userdata) +{ + PULSEAUDIO_pa_threaded_mainloop_signal(pulseaudio_threaded_mainloop, 0); /* just signal any waiting code, it can look up the details. */ +} + +static int PULSEAUDIO_OpenDevice(_THIS, const char *devname) +{ + struct SDL_PrivateAudioData *h = NULL; + SDL_AudioFormat test_format; + pa_sample_spec paspec; + pa_buffer_attr paattr; + pa_channel_map pacmap; + pa_stream_flags_t flags = 0; + SDL_bool iscapture = this->iscapture; + int format = PA_SAMPLE_INVALID; + int retval = 0; + + SDL_assert(pulseaudio_threaded_mainloop != NULL); + SDL_assert(pulseaudio_context != NULL); + + /* Initialize all variables that we clean on shutdown */ + h = this->hidden = (struct SDL_PrivateAudioData *)SDL_malloc(sizeof(*this->hidden)); + if (!this->hidden) { + return SDL_OutOfMemory(); + } + SDL_zerop(this->hidden); + + /* Try for a closest match on audio format */ + for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) { +#ifdef DEBUG_AUDIO + fprintf(stderr, "Trying format 0x%4.4x\n", test_format); +#endif + switch (test_format) { + case AUDIO_U8: + format = PA_SAMPLE_U8; + break; + case AUDIO_S16LSB: + format = PA_SAMPLE_S16LE; + break; + case AUDIO_S16MSB: + format = PA_SAMPLE_S16BE; + break; + case AUDIO_S32LSB: + format = PA_SAMPLE_S32LE; + break; + case AUDIO_S32MSB: + format = PA_SAMPLE_S32BE; + break; + case AUDIO_F32LSB: + format = PA_SAMPLE_FLOAT32LE; + break; + case AUDIO_F32MSB: + format = PA_SAMPLE_FLOAT32BE; + break; + default: + continue; + } + break; + } + if (!test_format) { + return SDL_SetError("pulseaudio: Unsupported audio format"); + } + this->spec.format = test_format; + paspec.format = format; + + /* Calculate the final parameters for this audio specification */ + SDL_CalculateAudioSpec(&this->spec); + + /* Allocate mixing buffer */ + if (!iscapture) { + h->mixlen = this->spec.size; + h->mixbuf = (Uint8 *)SDL_malloc(h->mixlen); + if (!h->mixbuf) { + return SDL_OutOfMemory(); + } + SDL_memset(h->mixbuf, this->spec.silence, this->spec.size); + } + + paspec.channels = this->spec.channels; + paspec.rate = this->spec.freq; + + /* Reduced prebuffering compared to the defaults. */ + paattr.fragsize = this->spec.size; + paattr.tlength = h->mixlen; + paattr.prebuf = -1; + paattr.maxlength = -1; + paattr.minreq = -1; + flags |= PA_STREAM_ADJUST_LATENCY; + + PULSEAUDIO_pa_threaded_mainloop_lock(pulseaudio_threaded_mainloop); + + if (!FindDeviceName(h, iscapture, this->handle)) { + retval = SDL_SetError("Requested PulseAudio sink/source missing?"); + } else { + const char *name = SDL_GetHint(SDL_HINT_AUDIO_DEVICE_STREAM_NAME); + /* The SDL ALSA output hints us that we use Windows' channel mapping */ + /* https://bugzilla.libsdl.org/show_bug.cgi?id=110 */ + PULSEAUDIO_pa_channel_map_init_auto(&pacmap, this->spec.channels, + PA_CHANNEL_MAP_WAVEEX); + + h->stream = PULSEAUDIO_pa_stream_new( + pulseaudio_context, + (name && *name) ? name : "Audio Stream", /* stream description */ + &paspec, /* sample format spec */ + &pacmap /* channel map */ + ); + + if (!h->stream) { + retval = SDL_SetError("Could not set up PulseAudio stream"); + } else { + int rc; + + PULSEAUDIO_pa_stream_set_state_callback(h->stream, PulseStreamStateChangeCallback, NULL); + /* now that we have multi-device support, don't move a stream from + a device that was unplugged to something else, unless we're default. */ + if (h->device_name) { + flags |= PA_STREAM_DONT_MOVE; + } + + if (iscapture) { + PULSEAUDIO_pa_stream_set_read_callback(h->stream, ReadCallback, h); + rc = PULSEAUDIO_pa_stream_connect_record(h->stream, h->device_name, &paattr, flags); + } else { + PULSEAUDIO_pa_stream_set_write_callback(h->stream, WriteCallback, h); + rc = PULSEAUDIO_pa_stream_connect_playback(h->stream, h->device_name, &paattr, flags, NULL, NULL); + } + + if (rc < 0) { + retval = SDL_SetError("Could not connect PulseAudio stream"); + } else { + int state = PULSEAUDIO_pa_stream_get_state(h->stream); + while (PA_STREAM_IS_GOOD(state) && (state != PA_STREAM_READY)) { + PULSEAUDIO_pa_threaded_mainloop_wait(pulseaudio_threaded_mainloop); + state = PULSEAUDIO_pa_stream_get_state(h->stream); + } + + if (!PA_STREAM_IS_GOOD(state)) { + retval = SDL_SetError("Could not connect PulseAudio stream"); + } + } + } + } + + PULSEAUDIO_pa_threaded_mainloop_unlock(pulseaudio_threaded_mainloop); + + /* We're (hopefully) ready to rock and roll. :-) */ + return retval; +} + + +/* device handles are device index + 1, cast to void*, so we never pass a NULL. */ + +static SDL_AudioFormat PulseFormatToSDLFormat(pa_sample_format_t format) +{ + switch (format) { + case PA_SAMPLE_U8: + return AUDIO_U8; + case PA_SAMPLE_S16LE: + return AUDIO_S16LSB; + case PA_SAMPLE_S16BE: + return AUDIO_S16MSB; + case PA_SAMPLE_S32LE: + return AUDIO_S32LSB; + case PA_SAMPLE_S32BE: + return AUDIO_S32MSB; + case PA_SAMPLE_FLOAT32LE: + return AUDIO_F32LSB; + case PA_SAMPLE_FLOAT32BE: + return AUDIO_F32MSB; + default: + return 0; + } +} + +/* This is called when PulseAudio adds an output ("sink") device. */ +static void SinkInfoCallback(pa_context *c, const pa_sink_info *i, int is_last, void *data) +{ + SDL_AudioSpec spec; + SDL_bool add = (SDL_bool)((intptr_t)data); + if (i) { + spec.freq = i->sample_spec.rate; + spec.channels = i->sample_spec.channels; + spec.format = PulseFormatToSDLFormat(i->sample_spec.format); + spec.silence = 0; + spec.samples = 0; + spec.size = 0; + spec.callback = NULL; + spec.userdata = NULL; + + if (add) { + SDL_AddAudioDevice(SDL_FALSE, i->description, &spec, (void *)((intptr_t)i->index + 1)); + } + + if (default_sink_path && SDL_strcmp(i->name, default_sink_path) == 0) { + if (default_sink_name) { + SDL_free(default_sink_name); + } + default_sink_name = SDL_strdup(i->description); + } + } + PULSEAUDIO_pa_threaded_mainloop_signal(pulseaudio_threaded_mainloop, 0); +} + +/* This is called when PulseAudio adds a capture ("source") device. */ +static void SourceInfoCallback(pa_context *c, const pa_source_info *i, int is_last, void *data) +{ + SDL_AudioSpec spec; + SDL_bool add = (SDL_bool)((intptr_t)data); + if (i) { + /* Maybe skip "monitor" sources. These are just output from other sinks. */ + if (include_monitors || (i->monitor_of_sink == PA_INVALID_INDEX)) { + spec.freq = i->sample_spec.rate; + spec.channels = i->sample_spec.channels; + spec.format = PulseFormatToSDLFormat(i->sample_spec.format); + spec.silence = 0; + spec.samples = 0; + spec.size = 0; + spec.callback = NULL; + spec.userdata = NULL; + + if (add) { + SDL_AddAudioDevice(SDL_TRUE, i->description, &spec, (void *)((intptr_t)i->index + 1)); + } + + if (default_source_path && SDL_strcmp(i->name, default_source_path) == 0) { + if (default_source_name) { + SDL_free(default_source_name); + } + default_source_name = SDL_strdup(i->description); + } + } + } + PULSEAUDIO_pa_threaded_mainloop_signal(pulseaudio_threaded_mainloop, 0); +} + +static void ServerInfoCallback(pa_context *c, const pa_server_info *i, void *data) +{ + SDL_free(default_sink_path); + SDL_free(default_source_path); + default_sink_path = SDL_strdup(i->default_sink_name); + default_source_path = SDL_strdup(i->default_source_name); + PULSEAUDIO_pa_threaded_mainloop_signal(pulseaudio_threaded_mainloop, 0); +} + +/* This is called when PulseAudio has a device connected/removed/changed. */ +static void HotplugCallback(pa_context *c, pa_subscription_event_type_t t, uint32_t idx, void *data) +{ + const SDL_bool added = ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW); + const SDL_bool removed = ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE); + const SDL_bool changed = ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_CHANGE); + + if (added || removed || changed) { /* we only care about add/remove events. */ + const SDL_bool sink = ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SINK); + const SDL_bool source = ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SOURCE); + + /* adds need sink details from the PulseAudio server. Another callback... */ + /* (just unref all these operations right away, because we aren't going to wait on them and their callbacks will handle any work, so they can free as soon as that happens.) */ + if ((added || changed) && sink) { + if (changed) { + PULSEAUDIO_pa_operation_unref(PULSEAUDIO_pa_context_get_server_info(pulseaudio_context, ServerInfoCallback, NULL)); + } + PULSEAUDIO_pa_operation_unref(PULSEAUDIO_pa_context_get_sink_info_by_index(pulseaudio_context, idx, SinkInfoCallback, (void *)((intptr_t)added))); + } else if ((added || changed) && source) { + if (changed) { + PULSEAUDIO_pa_operation_unref(PULSEAUDIO_pa_context_get_server_info(pulseaudio_context, ServerInfoCallback, NULL)); + } + PULSEAUDIO_pa_operation_unref(PULSEAUDIO_pa_context_get_source_info_by_index(pulseaudio_context, idx, SourceInfoCallback, (void *)((intptr_t)added))); + } else if (removed && (sink || source)) { + /* removes we can handle just with the device index. */ + SDL_RemoveAudioDevice(source != 0, (void *)((intptr_t)idx + 1)); + } + } + PULSEAUDIO_pa_threaded_mainloop_signal(pulseaudio_threaded_mainloop, 0); +} + +/* this runs as a thread while the Pulse target is initialized to catch hotplug events. */ +static int SDLCALL HotplugThread(void *data) +{ + pa_operation *op; + + SDL_SetThreadPriority(SDL_THREAD_PRIORITY_LOW); + PULSEAUDIO_pa_threaded_mainloop_lock(pulseaudio_threaded_mainloop); + PULSEAUDIO_pa_context_set_subscribe_callback(pulseaudio_context, HotplugCallback, NULL); + + /* don't WaitForPulseOperation on the subscription; when it's done we'll be able to get hotplug events, but waiting doesn't changing anything. */ + op = PULSEAUDIO_pa_context_subscribe(pulseaudio_context, PA_SUBSCRIPTION_MASK_SINK | PA_SUBSCRIPTION_MASK_SOURCE, NULL, NULL); + + SDL_SemPost(data); + + while (SDL_AtomicGet(&pulseaudio_hotplug_thread_active)) { + PULSEAUDIO_pa_threaded_mainloop_wait(pulseaudio_threaded_mainloop); + if (op && PULSEAUDIO_pa_operation_get_state(op) != PA_OPERATION_RUNNING) { + PULSEAUDIO_pa_operation_unref(op); + op = NULL; + } + } + + if (op) { + PULSEAUDIO_pa_operation_unref(op); + } + + PULSEAUDIO_pa_context_set_subscribe_callback(pulseaudio_context, NULL, NULL); + PULSEAUDIO_pa_threaded_mainloop_unlock(pulseaudio_threaded_mainloop); + return 0; +} + +static void PULSEAUDIO_DetectDevices() +{ + SDL_sem *ready_sem = SDL_CreateSemaphore(0); + + PULSEAUDIO_pa_threaded_mainloop_lock(pulseaudio_threaded_mainloop); + WaitForPulseOperation(PULSEAUDIO_pa_context_get_server_info(pulseaudio_context, ServerInfoCallback, NULL)); + WaitForPulseOperation(PULSEAUDIO_pa_context_get_sink_info_list(pulseaudio_context, SinkInfoCallback, (void *)((intptr_t)SDL_TRUE))); + WaitForPulseOperation(PULSEAUDIO_pa_context_get_source_info_list(pulseaudio_context, SourceInfoCallback, (void *)((intptr_t)SDL_TRUE))); + PULSEAUDIO_pa_threaded_mainloop_unlock(pulseaudio_threaded_mainloop); + + /* ok, we have a sane list, let's set up hotplug notifications now... */ + SDL_AtomicSet(&pulseaudio_hotplug_thread_active, 1); + pulseaudio_hotplug_thread = SDL_CreateThreadInternal(HotplugThread, "PulseHotplug", 256 * 1024, ready_sem); /* !!! FIXME: this can probably survive in significantly less stack space. */ + SDL_SemWait(ready_sem); + SDL_DestroySemaphore(ready_sem); +} + +static int PULSEAUDIO_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture) +{ + int i; + int numdevices; + + char *target; + if (iscapture) { + if (!default_source_name) { + return SDL_SetError("PulseAudio could not find a default source"); + } + target = default_source_name; + } else { + if (!default_sink_name) { + return SDL_SetError("PulseAudio could not find a default sink"); + } + target = default_sink_name; + } + + numdevices = SDL_GetNumAudioDevices(iscapture); + for (i = 0; i < numdevices; i += 1) { + if (SDL_strcmp(SDL_GetAudioDeviceName(i, iscapture), target) == 0) { + if (name) { + *name = SDL_strdup(target); + } + SDL_GetAudioDeviceSpec(i, iscapture, spec); + return 0; + } + } + return SDL_SetError("Could not find default PulseAudio device"); +} + +static void PULSEAUDIO_Deinitialize(void) +{ + if (pulseaudio_hotplug_thread) { + PULSEAUDIO_pa_threaded_mainloop_lock(pulseaudio_threaded_mainloop); + SDL_AtomicSet(&pulseaudio_hotplug_thread_active, 0); + PULSEAUDIO_pa_threaded_mainloop_signal(pulseaudio_threaded_mainloop, 0); + PULSEAUDIO_pa_threaded_mainloop_unlock(pulseaudio_threaded_mainloop); + SDL_WaitThread(pulseaudio_hotplug_thread, NULL); + pulseaudio_hotplug_thread = NULL; + } + + DisconnectFromPulseServer(); + + SDL_free(default_sink_path); + default_sink_path = NULL; + SDL_free(default_source_path); + default_source_path = NULL; + SDL_free(default_sink_name); + default_sink_name = NULL; + SDL_free(default_source_name); + default_source_name = NULL; + + UnloadPulseAudioLibrary(); +} + +static SDL_bool PULSEAUDIO_Init(SDL_AudioDriverImpl *impl) +{ + if (LoadPulseAudioLibrary() < 0) { + return SDL_FALSE; + } else if (ConnectToPulseServer() < 0) { + UnloadPulseAudioLibrary(); + return SDL_FALSE; + } + + include_monitors = SDL_GetHintBoolean(SDL_HINT_AUDIO_INCLUDE_MONITORS, SDL_FALSE); + + /* Set the function pointers */ + impl->DetectDevices = PULSEAUDIO_DetectDevices; + impl->OpenDevice = PULSEAUDIO_OpenDevice; + impl->PlayDevice = PULSEAUDIO_PlayDevice; + impl->WaitDevice = PULSEAUDIO_WaitDevice; + impl->GetDeviceBuf = PULSEAUDIO_GetDeviceBuf; + impl->CloseDevice = PULSEAUDIO_CloseDevice; + impl->Deinitialize = PULSEAUDIO_Deinitialize; + impl->CaptureFromDevice = PULSEAUDIO_CaptureFromDevice; + impl->FlushCapture = PULSEAUDIO_FlushCapture; + impl->GetDefaultAudioInfo = PULSEAUDIO_GetDefaultAudioInfo; + + impl->HasCaptureSupport = SDL_TRUE; + impl->SupportsNonPow2Samples = SDL_TRUE; + + return SDL_TRUE; /* this audio target is available. */ +} + +AudioBootStrap PULSEAUDIO_bootstrap = { + "pulseaudio", "PulseAudio", PULSEAUDIO_Init, SDL_FALSE +}; + +#endif /* SDL_AUDIO_DRIVER_PULSEAUDIO */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/audio/pulseaudio/SDL_pulseaudio.h b/SDL2-2.30.5/src/audio/pulseaudio/SDL_pulseaudio.h similarity index 89% rename from SDL2-2.0.12/src/audio/pulseaudio/SDL_pulseaudio.h rename to SDL2-2.30.5/src/audio/pulseaudio/SDL_pulseaudio.h index 2c51eb6..b4ad382 100644 --- a/SDL2-2.0.12/src/audio/pulseaudio/SDL_pulseaudio.h +++ b/SDL2-2.30.5/src/audio/pulseaudio/SDL_pulseaudio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,7 +23,7 @@ #ifndef SDL_pulseaudio_h_ #define SDL_pulseaudio_h_ -#include +#include #include "../SDL_sysaudio.h" @@ -35,14 +35,14 @@ struct SDL_PrivateAudioData char *device_name; /* pulseaudio structures */ - pa_mainloop *mainloop; - pa_context *context; pa_stream *stream; /* Raw mixing buffer */ Uint8 *mixbuf; int mixlen; + int bytes_requested; /* bytes of data the hardware wants _now_. */ + const Uint8 *capturebuf; int capturelen; }; diff --git a/SDL2-2.0.12/src/audio/qsa/SDL_qsa_audio.c b/SDL2-2.30.5/src/audio/qsa/SDL_qsa_audio.c similarity index 85% rename from SDL2-2.0.12/src/audio/qsa/SDL_qsa_audio.c rename to SDL2-2.30.5/src/audio/qsa/SDL_qsa_audio.c index 4276e07..be0532c 100644 --- a/SDL2-2.0.12/src/audio/qsa/SDL_qsa_audio.c +++ b/SDL2-2.30.5/src/audio/qsa/SDL_qsa_audio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -30,7 +30,7 @@ #include "../../SDL_internal.h" -#if SDL_AUDIO_DRIVER_QSA +#ifdef SDL_AUDIO_DRIVER_QSA #include #include @@ -74,15 +74,13 @@ uint32_t qsa_playback_devices; QSA_Device qsa_capture_device[QSA_MAX_DEVICES]; uint32_t qsa_capture_devices; -static SDL_INLINE int -QSA_SetError(const char *fn, int status) +static int QSA_SetError(const char *fn, int status) { return SDL_SetError("QSA: %s() failed: %s", fn, snd_strerror(status)); } /* !!! FIXME: does this need to be here? Does the SDL version not work? */ -static void -QSA_ThreadInit(_THIS) +static void QSA_ThreadInit(_THIS) { /* Increase default 10 priority to 25 to avoid jerky sound */ struct sched_param param; @@ -93,8 +91,7 @@ QSA_ThreadInit(_THIS) } /* PCM channel parameters initialize function */ -static void -QSA_InitAudioParams(snd_pcm_channel_params_t * cpars) +static void QSA_InitAudioParams(snd_pcm_channel_params_t * cpars) { SDL_zerop(cpars); cpars->channel = SND_PCM_CHANNEL_PLAYBACK; @@ -111,22 +108,23 @@ QSA_InitAudioParams(snd_pcm_channel_params_t * cpars) } /* This function waits until it is possible to write a full sound buffer */ -static void -QSA_WaitDevice(_THIS) +static void QSA_WaitDevice(_THIS) { int result; /* Setup timeout for playing one fragment equal to 2 seconds */ - /* If timeout occured than something wrong with hardware or driver */ + /* If timeout occurred than something wrong with hardware or driver */ /* For example, Vortex 8820 audio driver stucks on second DAC because */ /* it doesn't exist ! */ - result = SDL_IOReady(this->hidden->audio_fd, !this->hidden->iscapture, 2 * 1000); + result = SDL_IOReady(this->hidden->audio_fd, + this->iscapture ? SDL_IOR_READ : SDL_IOR_WRITE, + 2 * 1000); switch (result) { case -1: SDL_SetError("QSA: SDL_IOReady() failed: %s", strerror(errno)); break; case 0: - SDL_SetError("QSA: timeout on buffer waiting occured"); + SDL_SetError("QSA: timeout on buffer waiting occurred"); this->hidden->timeout_on_wait = 1; break; default: @@ -135,8 +133,7 @@ QSA_WaitDevice(_THIS) } } -static void -QSA_PlayDevice(_THIS) +static void QSA_PlayDevice(_THIS) { snd_pcm_channel_status_t cstatus; int written; @@ -178,7 +175,7 @@ QSA_PlayDevice(_THIS) } else { if ((errno == EINVAL) || (errno == EIO)) { SDL_zero(cstatus); - if (!this->hidden->iscapture) { + if (!this->iscapture) { cstatus.channel = SND_PCM_CHANNEL_PLAYBACK; } else { cstatus.channel = SND_PCM_CHANNEL_CAPTURE; @@ -194,7 +191,7 @@ QSA_PlayDevice(_THIS) if ((cstatus.status == SND_PCM_STATUS_UNDERRUN) || (cstatus.status == SND_PCM_STATUS_READY)) { - if (!this->hidden->iscapture) { + if (!this->iscapture) { status = snd_pcm_plugin_prepare(this->hidden-> audio_handle, @@ -228,17 +225,16 @@ QSA_PlayDevice(_THIS) } } -static Uint8 * -QSA_GetDeviceBuf(_THIS) +static Uint8 *QSA_GetDeviceBuf(_THIS) { return this->hidden->pcm_buf; } -static void -QSA_CloseDevice(_THIS) +static void QSA_CloseDevice(_THIS) { - if (this->hidden->audio_handle != NULL) { - if (!this->hidden->iscapture) { + if (this->hidden->audio_handle) { +#if _NTO_VERSION < 710 + if (!this->iscapture) { /* Finish playing available samples */ snd_pcm_plugin_flush(this->hidden->audio_handle, SND_PCM_CHANNEL_PLAYBACK); @@ -247,6 +243,7 @@ QSA_CloseDevice(_THIS) snd_pcm_plugin_flush(this->hidden->audio_handle, SND_PCM_CHANNEL_CAPTURE); } +#endif snd_pcm_close(this->hidden->audio_handle); } @@ -254,14 +251,13 @@ QSA_CloseDevice(_THIS) SDL_free(this->hidden); } -static int -QSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) +static int QSA_OpenDevice(_THIS, const char *devname) { - const QSA_Device *device = (const QSA_Device *) handle; + const QSA_Device *device = (const QSA_Device *) this->handle; + SDL_bool iscapture = this->iscapture; int status = 0; int format = 0; - SDL_AudioFormat test_format = 0; - int found = 0; + SDL_AudioFormat test_format; snd_pcm_channel_setup_t csetup; snd_pcm_channel_params_t cparams; @@ -271,17 +267,14 @@ QSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) (sizeof (struct SDL_PrivateAudioData))); - if (this->hidden == NULL) { + if (!this->hidden) { return SDL_OutOfMemory(); } /* Initialize channel transfer parameters to default */ QSA_InitAudioParams(&cparams); - /* Initialize channel direction: capture or playback */ - this->hidden->iscapture = iscapture ? SDL_TRUE : SDL_FALSE; - - if (device != NULL) { + if (device) { /* Open requested audio device */ this->hidden->deviceno = device->deviceno; this->hidden->cardno = device->cardno; @@ -303,89 +296,49 @@ QSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) } /* Try for a closest match on audio format */ - format = 0; - /* can't use format as SND_PCM_SFMT_U8 = 0 in qsa */ - found = 0; - - for (test_format = SDL_FirstAudioFormat(this->spec.format); !found;) { + for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) { /* if match found set format to equivalent QSA format */ switch (test_format) { case AUDIO_U8: - { - format = SND_PCM_SFMT_U8; - found = 1; - } + format = SND_PCM_SFMT_U8; break; case AUDIO_S8: - { - format = SND_PCM_SFMT_S8; - found = 1; - } + format = SND_PCM_SFMT_S8; break; case AUDIO_S16LSB: - { - format = SND_PCM_SFMT_S16_LE; - found = 1; - } + format = SND_PCM_SFMT_S16_LE; break; case AUDIO_S16MSB: - { - format = SND_PCM_SFMT_S16_BE; - found = 1; - } + format = SND_PCM_SFMT_S16_BE; break; case AUDIO_U16LSB: - { - format = SND_PCM_SFMT_U16_LE; - found = 1; - } + format = SND_PCM_SFMT_U16_LE; break; case AUDIO_U16MSB: - { - format = SND_PCM_SFMT_U16_BE; - found = 1; - } + format = SND_PCM_SFMT_U16_BE; break; case AUDIO_S32LSB: - { - format = SND_PCM_SFMT_S32_LE; - found = 1; - } + format = SND_PCM_SFMT_S32_LE; break; case AUDIO_S32MSB: - { - format = SND_PCM_SFMT_S32_BE; - found = 1; - } + format = SND_PCM_SFMT_S32_BE; break; case AUDIO_F32LSB: - { - format = SND_PCM_SFMT_FLOAT_LE; - found = 1; - } + format = SND_PCM_SFMT_FLOAT_LE; break; case AUDIO_F32MSB: - { - format = SND_PCM_SFMT_FLOAT_BE; - found = 1; - } + format = SND_PCM_SFMT_FLOAT_BE; break; default: - { - break; - } - } - - if (!found) { - test_format = SDL_NextAudioFormat(); + continue; } + break; } - /* assumes test_format not 0 on success */ - if (test_format == 0) { - return SDL_SetError("QSA: Couldn't find any hardware audio formats"); + /* can't use format as SND_PCM_SFMT_U8 = 0 in qsa */ + if (!test_format) { + return SDL_SetError("%s: Unsupported audio format", "qsa"); } - this->spec.format = test_format; /* Set the audio format */ @@ -405,7 +358,7 @@ QSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) /* Make sure channel is setup right one last time */ SDL_zero(csetup); - if (!this->hidden->iscapture) { + if (!this->iscapture) { csetup.channel = SND_PCM_CHANNEL_PLAYBACK; } else { csetup.channel = SND_PCM_CHANNEL_CAPTURE; @@ -434,14 +387,14 @@ QSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) */ this->hidden->pcm_buf = (Uint8 *) SDL_malloc(this->hidden->pcm_len); - if (this->hidden->pcm_buf == NULL) { + if (!this->hidden->pcm_buf) { return SDL_OutOfMemory(); } SDL_memset(this->hidden->pcm_buf, this->spec.silence, this->hidden->pcm_len); /* get the file descriptor */ - if (!this->hidden->iscapture) { + if (!this->iscapture) { this->hidden->audio_fd = snd_pcm_file_descriptor(this->hidden->audio_handle, SND_PCM_CHANNEL_PLAYBACK); @@ -456,7 +409,7 @@ QSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) } /* Prepare an audio channel */ - if (!this->hidden->iscapture) { + if (!this->iscapture) { /* Prepare audio playback */ status = snd_pcm_plugin_prepare(this->hidden->audio_handle, @@ -476,8 +429,7 @@ QSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) return 0; } -static void -QSA_DetectDevices(void) +static void QSA_DetectDevices(void) { uint32_t it; uint32_t cards; @@ -528,7 +480,11 @@ QSA_DetectDevices(void) devices; status = snd_pcm_close(handle); if (status == EOK) { - SDL_AddAudioDevice(SDL_FALSE, qsa_playback_device[qsa_playback_devices].name, &qsa_playback_device[qsa_playback_devices]); + /* Note that spec is NULL, because we are required to open the device before + * acquiring the mix format, making this information inaccessible at + * enumeration time + */ + SDL_AddAudioDevice(SDL_FALSE, qsa_playback_device[qsa_playback_devices].name, NULL, &qsa_playback_device[qsa_playback_devices]); qsa_playback_devices++; } } else { @@ -586,7 +542,11 @@ QSA_DetectDevices(void) devices; status = snd_pcm_close(handle); if (status == EOK) { - SDL_AddAudioDevice(SDL_TRUE, qsa_capture_device[qsa_capture_devices].name, &qsa_capture_device[qsa_capture_devices]); + /* Note that spec is NULL, because we are required to open the device before + * acquiring the mix format, making this information inaccessible at + * enumeration time + */ + SDL_AddAudioDevice(SDL_TRUE, qsa_capture_device[qsa_capture_devices].name, NULL, &qsa_capture_device[qsa_capture_devices]); qsa_capture_devices++; } } else { @@ -614,8 +574,7 @@ QSA_DetectDevices(void) } } -static void -QSA_Deinitialize(void) +static void QSA_Deinitialize(void) { /* Clear devices array on shutdown */ /* !!! FIXME: we zero these on init...any reason to do it here? */ @@ -625,8 +584,7 @@ QSA_Deinitialize(void) qsa_capture_devices = 0; } -static int -QSA_Init(SDL_AudioDriverImpl * impl) +static SDL_bool QSA_Init(SDL_AudioDriverImpl * impl) { /* Clear devices array */ SDL_zeroa(qsa_playback_device); @@ -645,20 +603,14 @@ QSA_Init(SDL_AudioDriverImpl * impl) impl->GetDeviceBuf = QSA_GetDeviceBuf; impl->CloseDevice = QSA_CloseDevice; impl->Deinitialize = QSA_Deinitialize; - impl->LockDevice = NULL; - impl->UnlockDevice = NULL; - impl->ProvidesOwnCallbackThread = 0; - impl->SkipMixerLock = 0; - impl->HasCaptureSupport = 1; - impl->OnlyHasDefaultOutputDevice = 0; - impl->OnlyHasDefaultCaptureDevice = 0; + impl->HasCaptureSupport = SDL_TRUE; - return 1; /* this audio target is available. */ + return SDL_TRUE; /* this audio target is available. */ } AudioBootStrap QSAAUDIO_bootstrap = { - "qsa", "QNX QSA Audio", QSA_Init, 0 + "qsa", "QNX QSA Audio", QSA_Init, SDL_FALSE }; #endif /* SDL_AUDIO_DRIVER_QSA */ diff --git a/SDL2-2.0.12/src/audio/qsa/SDL_qsa_audio.h b/SDL2-2.30.5/src/audio/qsa/SDL_qsa_audio.h similarity index 93% rename from SDL2-2.0.12/src/audio/qsa/SDL_qsa_audio.h rename to SDL2-2.30.5/src/audio/qsa/SDL_qsa_audio.h index 2340617..1e69f26 100644 --- a/SDL2-2.0.12/src/audio/qsa/SDL_qsa_audio.h +++ b/SDL2-2.30.5/src/audio/qsa/SDL_qsa_audio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -33,9 +33,6 @@ struct SDL_PrivateAudioData { - /* SDL capture state */ - SDL_bool iscapture; - /* The audio device handle */ int cardno; int deviceno; diff --git a/SDL2-2.0.12/src/audio/sndio/SDL_sndioaudio.c b/SDL2-2.30.5/src/audio/sndio/SDL_sndioaudio.c similarity index 72% rename from SDL2-2.0.12/src/audio/sndio/SDL_sndioaudio.c rename to SDL2-2.30.5/src/audio/sndio/SDL_sndioaudio.c index 41a6c43..499b847 100644 --- a/SDL2-2.0.12/src/audio/sndio/SDL_sndioaudio.c +++ b/SDL2-2.30.5/src/audio/sndio/SDL_sndioaudio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -21,11 +21,11 @@ #include "../../SDL_internal.h" -#if SDL_AUDIO_DRIVER_SNDIO +#ifdef SDL_AUDIO_DRIVER_SNDIO /* OpenBSD sndio target */ -#if HAVE_STDIO_H +#ifdef HAVE_STDIO_H #include #endif @@ -52,7 +52,7 @@ #define SIO_DEVANY "default" #endif -static struct sio_hdl * (*SNDIO_sio_open)(const char *, unsigned int, int); +static struct sio_hdl *(*SNDIO_sio_open)(const char *, unsigned int, int); static void (*SNDIO_sio_close)(struct sio_hdl *); static int (*SNDIO_sio_setpar)(struct sio_hdl *, struct sio_par *); static int (*SNDIO_sio_getpar)(struct sio_hdl *, struct sio_par *); @@ -70,11 +70,10 @@ static void (*SNDIO_sio_initpar)(struct sio_par *); static const char *sndio_library = SDL_AUDIO_DRIVER_SNDIO_DYNAMIC; static void *sndio_handle = NULL; -static int -load_sndio_sym(const char *fn, void **addr) +static int load_sndio_sym(const char *fn, void **addr) { *addr = SDL_LoadFunction(sndio_handle, fn); - if (*addr == NULL) { + if (!*addr) { /* Don't call SDL_SetError(): SDL_LoadFunction already did. */ return 0; } @@ -83,14 +82,14 @@ load_sndio_sym(const char *fn, void **addr) } /* cast funcs to char* first, to please GCC's strict aliasing rules. */ -#define SDL_SNDIO_SYM(x) \ - if (!load_sndio_sym(#x, (void **) (char *) &SNDIO_##x)) return -1 +#define SDL_SNDIO_SYM(x) \ + if (!load_sndio_sym(#x, (void **)(char *)&SNDIO_##x)) \ + return -1 #else #define SDL_SNDIO_SYM(x) SNDIO_##x = x #endif -static int -load_sndio_syms(void) +static int load_sndio_syms(void) { SDL_SNDIO_SYM(sio_open); SDL_SNDIO_SYM(sio_close); @@ -112,22 +111,20 @@ load_sndio_syms(void) #ifdef SDL_AUDIO_DRIVER_SNDIO_DYNAMIC -static void -UnloadSNDIOLibrary(void) +static void UnloadSNDIOLibrary(void) { - if (sndio_handle != NULL) { + if (sndio_handle) { SDL_UnloadObject(sndio_handle); sndio_handle = NULL; } } -static int -LoadSNDIOLibrary(void) +static int LoadSNDIOLibrary(void) { int retval = 0; - if (sndio_handle == NULL) { + if (!sndio_handle) { sndio_handle = SDL_LoadObject(sndio_library); - if (sndio_handle == NULL) { + if (!sndio_handle) { retval = -1; /* Don't call SDL_SetError(): SDL_LoadObject already did. */ } else { @@ -142,13 +139,11 @@ LoadSNDIOLibrary(void) #else -static void -UnloadSNDIOLibrary(void) +static void UnloadSNDIOLibrary(void) { } -static int -LoadSNDIOLibrary(void) +static int LoadSNDIOLibrary(void) { load_sndio_syms(); return 0; @@ -156,24 +151,19 @@ LoadSNDIOLibrary(void) #endif /* SDL_AUDIO_DRIVER_SNDIO_DYNAMIC */ - - - -static void -SNDIO_WaitDevice(_THIS) +static void SNDIO_WaitDevice(_THIS) { /* no-op; SNDIO_sio_write() blocks if necessary. */ } -static void -SNDIO_PlayDevice(_THIS) +static void SNDIO_PlayDevice(_THIS) { const int written = SNDIO_sio_write(this->hidden->dev, this->hidden->mixbuf, this->hidden->mixlen); /* If we couldn't write, assume fatal error for now */ - if ( written == 0 ) { + if (written == 0) { SDL_OpenedAudioDeviceDisconnected(this); } #ifdef DEBUG_AUDIO @@ -181,8 +171,7 @@ SNDIO_PlayDevice(_THIS) #endif } -static int -SNDIO_CaptureFromDevice(_THIS, void *buffer, int buflen) +static int SNDIO_CaptureFromDevice(_THIS, void *buffer, int buflen) { size_t r; int revents; @@ -191,8 +180,8 @@ SNDIO_CaptureFromDevice(_THIS, void *buffer, int buflen) /* Emulate a blocking read */ r = SNDIO_sio_read(this->hidden->dev, buffer, buflen); while (r == 0 && !SNDIO_sio_eof(this->hidden->dev)) { - if ((nfds = SNDIO_sio_pollfd(this->hidden->dev, this->hidden->pfd, POLLIN)) <= 0 - || poll(this->hidden->pfd, nfds, INFTIM) < 0) { + nfds = SNDIO_sio_pollfd(this->hidden->dev, this->hidden->pfd, POLLIN); + if (nfds <= 0 || poll(this->hidden->pfd, nfds, INFTIM) < 0) { return -1; } revents = SNDIO_sio_revents(this->hidden->dev, this->hidden->pfd); @@ -203,11 +192,10 @@ SNDIO_CaptureFromDevice(_THIS, void *buffer, int buflen) break; } } - return (int) r; + return (int)r; } -static void -SNDIO_FlushCapture(_THIS) +static void SNDIO_FlushCapture(_THIS) { char buf[512]; @@ -216,19 +204,17 @@ SNDIO_FlushCapture(_THIS) } } -static Uint8 * -SNDIO_GetDeviceBuf(_THIS) +static Uint8 *SNDIO_GetDeviceBuf(_THIS) { return this->hidden->mixbuf; } -static void -SNDIO_CloseDevice(_THIS) +static void SNDIO_CloseDevice(_THIS) { - if ( this->hidden->pfd != NULL ) { + if (this->hidden->pfd) { SDL_free(this->hidden->pfd); } - if ( this->hidden->dev != NULL ) { + if (this->hidden->dev) { SNDIO_sio_stop(this->hidden->dev); SNDIO_sio_close(this->hidden->dev); } @@ -236,16 +222,15 @@ SNDIO_CloseDevice(_THIS) SDL_free(this->hidden); } -static int -SNDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) +static int SNDIO_OpenDevice(_THIS, const char *devname) { - SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format); + SDL_AudioFormat test_format; struct sio_par par; - int status; + SDL_bool iscapture = this->iscapture; this->hidden = (struct SDL_PrivateAudioData *) SDL_malloc(sizeof(*this->hidden)); - if (this->hidden == NULL) { + if (!this->hidden) { return SDL_OutOfMemory(); } SDL_zerop(this->hidden); @@ -253,16 +238,18 @@ SNDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) this->hidden->mixlen = this->spec.size; /* Capture devices must be non-blocking for SNDIO_FlushCapture */ - if ((this->hidden->dev = - SNDIO_sio_open(devname != NULL ? devname : SIO_DEVANY, - iscapture ? SIO_REC : SIO_PLAY, iscapture)) == NULL) { + this->hidden->dev = SNDIO_sio_open(devname ? devname : SIO_DEVANY, + iscapture ? SIO_REC : SIO_PLAY, iscapture); + if (!this->hidden->dev) { return SDL_SetError("sio_open() failed"); } /* Allocate the pollfd array for capture devices */ - if (iscapture && (this->hidden->pfd = - SDL_malloc(sizeof(struct pollfd) * SNDIO_sio_nfds(this->hidden->dev))) == NULL) { - return SDL_OutOfMemory(); + if (iscapture) { + this->hidden->pfd = SDL_malloc(sizeof(struct pollfd) * SNDIO_sio_nfds(this->hidden->dev)); + if (!this->hidden->pfd) { + return SDL_OutOfMemory(); + } } SNDIO_sio_initpar(&par); @@ -273,8 +260,7 @@ SNDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) par.appbufsz = par.round * 2; /* Try for a closest match on audio format */ - status = -1; - while (test_format && (status < 0)) { + for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) { if (!SDL_AUDIO_ISFLOAT(test_format)) { par.le = SDL_AUDIO_ISLITTLEENDIAN(test_format) ? 1 : 0; par.sig = SDL_AUDIO_ISSIGNED(test_format) ? 1 : 0; @@ -290,34 +276,32 @@ SNDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) continue; } if ((par.bits == 8 * par.bps) || (par.msb)) { - status = 0; break; } } - test_format = SDL_NextAudioFormat(); } - if (status < 0) { - return SDL_SetError("sndio: Couldn't find any hardware audio formats"); + if (!test_format) { + return SDL_SetError("%s: Unsupported audio format", "sndio"); } - if ((par.bps == 4) && (par.sig) && (par.le)) + if ((par.bps == 4) && (par.sig) && (par.le)) { this->spec.format = AUDIO_S32LSB; - else if ((par.bps == 4) && (par.sig) && (!par.le)) + } else if ((par.bps == 4) && (par.sig) && (!par.le)) { this->spec.format = AUDIO_S32MSB; - else if ((par.bps == 2) && (par.sig) && (par.le)) + } else if ((par.bps == 2) && (par.sig) && (par.le)) { this->spec.format = AUDIO_S16LSB; - else if ((par.bps == 2) && (par.sig) && (!par.le)) + } else if ((par.bps == 2) && (par.sig) && (!par.le)) { this->spec.format = AUDIO_S16MSB; - else if ((par.bps == 2) && (!par.sig) && (par.le)) + } else if ((par.bps == 2) && (!par.sig) && (par.le)) { this->spec.format = AUDIO_U16LSB; - else if ((par.bps == 2) && (!par.sig) && (!par.le)) + } else if ((par.bps == 2) && (!par.sig) && (!par.le)) { this->spec.format = AUDIO_U16MSB; - else if ((par.bps == 1) && (par.sig)) + } else if ((par.bps == 1) && (par.sig)) { this->spec.format = AUDIO_S8; - else if ((par.bps == 1) && (!par.sig)) + } else if ((par.bps == 1) && (!par.sig)) { this->spec.format = AUDIO_U8; - else { + } else { return SDL_SetError("sndio: Got unsupported hardware audio format."); } @@ -330,8 +314,8 @@ SNDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) /* Allocate mixing buffer */ this->hidden->mixlen = this->spec.size; - this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen); - if (this->hidden->mixbuf == NULL) { + this->hidden->mixbuf = (Uint8 *)SDL_malloc(this->hidden->mixlen); + if (!this->hidden->mixbuf) { return SDL_OutOfMemory(); } SDL_memset(this->hidden->mixbuf, this->spec.silence, this->hidden->mixlen); @@ -344,17 +328,21 @@ SNDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) return 0; } -static void -SNDIO_Deinitialize(void) +static void SNDIO_Deinitialize(void) { UnloadSNDIOLibrary(); } -static int -SNDIO_Init(SDL_AudioDriverImpl * impl) +static void SNDIO_DetectDevices(void) +{ + SDL_AddAudioDevice(SDL_FALSE, DEFAULT_OUTPUT_DEVNAME, NULL, (void *)0x1); + SDL_AddAudioDevice(SDL_TRUE, DEFAULT_INPUT_DEVNAME, NULL, (void *)0x2); +} + +static SDL_bool SNDIO_Init(SDL_AudioDriverImpl *impl) { if (LoadSNDIOLibrary() < 0) { - return 0; + return SDL_FALSE; } /* Set the function pointers */ @@ -366,15 +354,16 @@ SNDIO_Init(SDL_AudioDriverImpl * impl) impl->CaptureFromDevice = SNDIO_CaptureFromDevice; impl->FlushCapture = SNDIO_FlushCapture; impl->Deinitialize = SNDIO_Deinitialize; + impl->DetectDevices = SNDIO_DetectDevices; - impl->AllowsArbitraryDeviceNames = 1; + impl->AllowsArbitraryDeviceNames = SDL_TRUE; impl->HasCaptureSupport = SDL_TRUE; - return 1; /* this audio target is available. */ + return SDL_TRUE; /* this audio target is available. */ } AudioBootStrap SNDIO_bootstrap = { - "sndio", "OpenBSD sndio", SNDIO_Init, 0 + "sndio", "OpenBSD sndio", SNDIO_Init, SDL_FALSE }; #endif /* SDL_AUDIO_DRIVER_SNDIO */ diff --git a/SDL2-2.0.12/src/audio/sndio/SDL_sndioaudio.h b/SDL2-2.30.5/src/audio/sndio/SDL_sndioaudio.h similarity index 93% rename from SDL2-2.0.12/src/audio/sndio/SDL_sndioaudio.h rename to SDL2-2.30.5/src/audio/sndio/SDL_sndioaudio.h index 7197661..ffd4df8 100644 --- a/SDL2-2.0.12/src/audio/sndio/SDL_sndioaudio.h +++ b/SDL2-2.30.5/src/audio/sndio/SDL_sndioaudio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -29,7 +29,7 @@ #include "../SDL_sysaudio.h" /* Hidden "this" pointer for the audio functions */ -#define _THIS SDL_AudioDevice *this +#define _THIS SDL_AudioDevice *this struct SDL_PrivateAudioData { diff --git a/SDL2-2.0.12/src/audio/sun/SDL_sunaudio.c b/SDL2-2.30.5/src/audio/sun/SDL_sunaudio.c similarity index 92% rename from SDL2-2.0.12/src/audio/sun/SDL_sunaudio.c rename to SDL2-2.30.5/src/audio/sun/SDL_sunaudio.c index e018f60..442cf2b 100644 --- a/SDL2-2.0.12/src/audio/sun/SDL_sunaudio.c +++ b/SDL2-2.30.5/src/audio/sun/SDL_sunaudio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_AUDIO_DRIVER_SUNAUDIO +#ifdef SDL_AUDIO_DRIVER_SUNAUDIO /* Allow access to a raw mixing buffer */ @@ -55,15 +55,13 @@ static Uint8 snd2au(int sample); /* Audio driver bootstrap functions */ -static void -SUNAUDIO_DetectDevices(void) +static void SUNAUDIO_DetectDevices(void) { SDL_EnumUnixAudioDevices(1, (int (*)(int)) NULL); } #ifdef DEBUG_AUDIO -void -CheckUnderflow(_THIS) +void CheckUnderflow(_THIS) { #ifdef AUDIO_GETBUFINFO audio_info_t info; @@ -78,8 +76,7 @@ CheckUnderflow(_THIS) } #endif -static void -SUNAUDIO_WaitDevice(_THIS) +static void SUNAUDIO_WaitDevice(_THIS) { #ifdef AUDIO_GETBUFINFO #define SLEEP_FUDGE 10 /* 10 ms scheduling fudge factor */ @@ -98,12 +95,11 @@ SUNAUDIO_WaitDevice(_THIS) } } #else - SDL_IOReady(this->hidden->audio_fd, SDL_TRUE, -1); + SDL_IOReady(this->hidden->audio_fd, SDL_IOR_WRITE, -1); #endif } -static void -SUNAUDIO_PlayDevice(_THIS) +static void SUNAUDIO_PlayDevice(_THIS) { /* Write the audio data */ if (this->hidden->ulaw_only) { @@ -170,14 +166,12 @@ SUNAUDIO_PlayDevice(_THIS) } } -static Uint8 * -SUNAUDIO_GetDeviceBuf(_THIS) +static Uint8 *SUNAUDIO_GetDeviceBuf(_THIS) { return (this->hidden->mixbuf); } -static void -SUNAUDIO_CloseDevice(_THIS) +static void SUNAUDIO_CloseDevice(_THIS) { SDL_free(this->hidden->ulaw_buf); if (this->hidden->audio_fd >= 0) { @@ -187,12 +181,12 @@ SUNAUDIO_CloseDevice(_THIS) SDL_free(this->hidden); } -static int -SUNAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) +static int SUNAUDIO_OpenDevice(_THIS, const char *devname) { #ifdef AUDIO_SETINFO int enc; #endif + SDL_bool iscapture = this->iscapture; int desired_freq = 0; const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT); SDL_AudioFormat format = 0; @@ -200,17 +194,16 @@ SUNAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) /* We don't care what the devname is...we'll try to open anything. */ /* ...but default to first name in the list... */ - if (devname == NULL) { + if (!devname) { devname = SDL_GetAudioDeviceName(0, iscapture); - if (devname == NULL) { + if (!devname) { return SDL_SetError("No such audio device"); } } /* Initialize all variables that we clean on shutdown */ - this->hidden = (struct SDL_PrivateAudioData *) - SDL_malloc((sizeof *this->hidden)); - if (this->hidden == NULL) { + this->hidden = (struct SDL_PrivateAudioData *)SDL_malloc(sizeof(*this->hidden)); + if (!this->hidden) { return SDL_OutOfMemory(); } SDL_zerop(this->hidden); @@ -288,7 +281,7 @@ SUNAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) break; /* try again */ case AUDIO_ENCODING_LINEAR: - /* linear 16bit didn't work either, resort to -law */ + /* linear 16bit didn't work either, resort to �-law */ enc = AUDIO_ENCODING_ULAW; this->spec.channels = 1; this->spec.freq = 8000; @@ -312,7 +305,7 @@ SUNAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) (this->spec.freq / 8); this->hidden->frequency = 8; this->hidden->ulaw_buf = (Uint8 *) SDL_malloc(this->hidden->fragsize); - if (this->hidden->ulaw_buf == NULL) { + if (!this->hidden->ulaw_buf) { return SDL_OutOfMemory(); } this->spec.channels = 1; @@ -332,7 +325,7 @@ SUNAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) /* Allocate mixing buffer */ this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->spec.size); - if (this->hidden->mixbuf == NULL) { + if (!this->hidden->mixbuf) { return SDL_OutOfMemory(); } SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size); @@ -359,8 +352,7 @@ SUNAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) /* provided "as is" without express or implied warranty. */ /************************************************************************/ -static Uint8 -snd2au(int sample) +static Uint8 snd2au(int sample) { int mask; @@ -394,8 +386,7 @@ snd2au(int sample) return (mask & sample); } -static int -SUNAUDIO_Init(SDL_AudioDriverImpl * impl) +static SDL_bool SUNAUDIO_Init(SDL_AudioDriverImpl * impl) { /* Set the function pointers */ impl->DetectDevices = SUNAUDIO_DetectDevices; @@ -405,13 +396,13 @@ SUNAUDIO_Init(SDL_AudioDriverImpl * impl) impl->GetDeviceBuf = SUNAUDIO_GetDeviceBuf; impl->CloseDevice = SUNAUDIO_CloseDevice; - impl->AllowsArbitraryDeviceNames = 1; + impl->AllowsArbitraryDeviceNames = SDL_TRUE; - return 1; /* this audio target is available. */ + return SDL_TRUE; /* this audio target is available. */ } AudioBootStrap SUNAUDIO_bootstrap = { - "audio", "UNIX /dev/audio interface", SUNAUDIO_Init, 0 + "audio", "UNIX /dev/audio interface", SUNAUDIO_Init, SDL_FALSE }; #endif /* SDL_AUDIO_DRIVER_SUNAUDIO */ diff --git a/SDL2-2.0.12/src/audio/sun/SDL_sunaudio.h b/SDL2-2.30.5/src/audio/sun/SDL_sunaudio.h similarity index 96% rename from SDL2-2.0.12/src/audio/sun/SDL_sunaudio.h rename to SDL2-2.30.5/src/audio/sun/SDL_sunaudio.h index 16f3b4f..0952543 100644 --- a/SDL2-2.0.12/src/audio/sun/SDL_sunaudio.h +++ b/SDL2-2.30.5/src/audio/sun/SDL_sunaudio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.30.5/src/audio/vita/SDL_vitaaudio.c b/SDL2-2.30.5/src/audio/vita/SDL_vitaaudio.c new file mode 100644 index 0000000..bd87323 --- /dev/null +++ b/SDL2-2.30.5/src/audio/vita/SDL_vitaaudio.c @@ -0,0 +1,221 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_AUDIO_DRIVER_VITA + +#include +#include +#include +#include /* memalign() */ + +#include "SDL_audio.h" +#include "SDL_error.h" +#include "SDL_timer.h" +#include "../SDL_audio_c.h" +#include "../SDL_audiodev_c.h" +#include "../SDL_sysaudio.h" +#include "SDL_vitaaudio.h" + +#include +#include +#include + +#define SCE_AUDIO_SAMPLE_ALIGN(s) (((s) + 63) & ~63) +#define SCE_AUDIO_MAX_VOLUME 0x8000 + +static int VITAAUD_OpenCaptureDevice(_THIS) +{ + this->spec.freq = 16000; + this->spec.samples = 512; + this->spec.channels = 1; + + SDL_CalculateAudioSpec(&this->spec); + + this->hidden->port = sceAudioInOpenPort(SCE_AUDIO_IN_PORT_TYPE_VOICE, 512, 16000, SCE_AUDIO_IN_PARAM_FORMAT_S16_MONO); + + if (this->hidden->port < 0) { + return SDL_SetError("Couldn't open audio in port: %x", this->hidden->port); + } + + return 0; +} + +static int VITAAUD_OpenDevice(_THIS, const char *devname) +{ + int format, mixlen, i, port = SCE_AUDIO_OUT_PORT_TYPE_MAIN; + int vols[2] = { SCE_AUDIO_MAX_VOLUME, SCE_AUDIO_MAX_VOLUME }; + SDL_AudioFormat test_format; + + this->hidden = (struct SDL_PrivateAudioData *) + SDL_malloc(sizeof(*this->hidden)); + if (!this->hidden) { + return SDL_OutOfMemory(); + } + SDL_memset(this->hidden, 0, sizeof(*this->hidden)); + + for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) { + if (test_format == AUDIO_S16LSB) { + this->spec.format = test_format; + break; + } + } + + if (!test_format) { + return SDL_SetError("Unsupported audio format"); + } + + if (this->iscapture) { + return VITAAUD_OpenCaptureDevice(this); + } + + /* The sample count must be a multiple of 64. */ + this->spec.samples = SCE_AUDIO_SAMPLE_ALIGN(this->spec.samples); + + /* Update the fragment size as size in bytes. */ + SDL_CalculateAudioSpec(&this->spec); + + /* Allocate the mixing buffer. Its size and starting address must + be a multiple of 64 bytes. Our sample count is already a multiple of + 64, so spec->size should be a multiple of 64 as well. */ + mixlen = this->spec.size * NUM_BUFFERS; + this->hidden->rawbuf = (Uint8 *)memalign(64, mixlen); + if (!this->hidden->rawbuf) { + return SDL_SetError("Couldn't allocate mixing buffer"); + } + + /* Setup the hardware channel. */ + if (this->spec.channels == 1) { + format = SCE_AUDIO_OUT_MODE_MONO; + } else { + format = SCE_AUDIO_OUT_MODE_STEREO; + } + + if (this->spec.freq < 48000) { + port = SCE_AUDIO_OUT_PORT_TYPE_BGM; + } + + this->hidden->port = sceAudioOutOpenPort(port, this->spec.samples, this->spec.freq, format); + if (this->hidden->port < 0) { + free(this->hidden->rawbuf); + this->hidden->rawbuf = NULL; + return SDL_SetError("Couldn't open audio out port: %x", this->hidden->port); + } + + sceAudioOutSetVolume(this->hidden->port, SCE_AUDIO_VOLUME_FLAG_L_CH | SCE_AUDIO_VOLUME_FLAG_R_CH, vols); + + SDL_memset(this->hidden->rawbuf, 0, mixlen); + for (i = 0; i < NUM_BUFFERS; i++) { + this->hidden->mixbufs[i] = &this->hidden->rawbuf[i * this->spec.size]; + } + + this->hidden->next_buffer = 0; + return 0; +} + +static void VITAAUD_PlayDevice(_THIS) +{ + Uint8 *mixbuf = this->hidden->mixbufs[this->hidden->next_buffer]; + + sceAudioOutOutput(this->hidden->port, mixbuf); + + this->hidden->next_buffer = (this->hidden->next_buffer + 1) % NUM_BUFFERS; +} + +/* This function waits until it is possible to write a full sound buffer */ +static void VITAAUD_WaitDevice(_THIS) +{ + /* Because we block when sending audio, there's no need for this function to do anything. */ +} + +static Uint8 *VITAAUD_GetDeviceBuf(_THIS) +{ + return this->hidden->mixbufs[this->hidden->next_buffer]; +} + +static void VITAAUD_CloseDevice(_THIS) +{ + if (this->hidden->port >= 0) { + if (this->iscapture) { + sceAudioInReleasePort(this->hidden->port); + } else { + sceAudioOutReleasePort(this->hidden->port); + } + this->hidden->port = -1; + } + + if (!this->iscapture && this->hidden->rawbuf) { + free(this->hidden->rawbuf); /* this uses memalign(), not SDL_malloc(). */ + this->hidden->rawbuf = NULL; + } +} + +static int VITAAUD_CaptureFromDevice(_THIS, void *buffer, int buflen) +{ + int ret; + SDL_assert(buflen == this->spec.size); + ret = sceAudioInInput(this->hidden->port, buffer); + if (ret < 0) { + return SDL_SetError("Failed to capture from device: %x", ret); + } + return this->spec.size; +} + +static void VITAAUD_ThreadInit(_THIS) +{ + /* Increase the priority of this audio thread by 1 to put it + ahead of other SDL threads. */ + SceUID thid; + SceKernelThreadInfo info; + thid = sceKernelGetThreadId(); + info.size = sizeof(SceKernelThreadInfo); + if (sceKernelGetThreadInfo(thid, &info) == 0) { + sceKernelChangeThreadPriority(thid, info.currentPriority - 1); + } +} + +static SDL_bool VITAAUD_Init(SDL_AudioDriverImpl *impl) +{ + /* Set the function pointers */ + impl->OpenDevice = VITAAUD_OpenDevice; + impl->PlayDevice = VITAAUD_PlayDevice; + impl->WaitDevice = VITAAUD_WaitDevice; + impl->GetDeviceBuf = VITAAUD_GetDeviceBuf; + impl->CloseDevice = VITAAUD_CloseDevice; + impl->ThreadInit = VITAAUD_ThreadInit; + + impl->CaptureFromDevice = VITAAUD_CaptureFromDevice; + + /* and the capabilities */ + impl->HasCaptureSupport = SDL_TRUE; + impl->OnlyHasDefaultOutputDevice = SDL_TRUE; + impl->OnlyHasDefaultCaptureDevice = SDL_TRUE; + + return SDL_TRUE; /* this audio target is available. */ +} + +AudioBootStrap VITAAUD_bootstrap = { + "vita", "VITA audio driver", VITAAUD_Init, SDL_FALSE +}; + +#endif /* SDL_AUDIO_DRIVER_VITA */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/audio/vita/SDL_vitaaudio.h b/SDL2-2.30.5/src/audio/vita/SDL_vitaaudio.h new file mode 100644 index 0000000..cb0aba8 --- /dev/null +++ b/SDL2-2.30.5/src/audio/vita/SDL_vitaaudio.h @@ -0,0 +1,46 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#ifndef _SDL_vitaaudio_h +#define _SDL_vitaaudio_h + +#include "../SDL_sysaudio.h" + +/* Hidden "this" pointer for the audio functions */ +#define _THIS SDL_AudioDevice *this + +#define NUM_BUFFERS 2 + +struct SDL_PrivateAudioData +{ + /* The hardware input/output port. */ + int port; + /* The raw allocated mixing buffer. */ + Uint8 *rawbuf; + /* Individual mixing buffers. */ + Uint8 *mixbufs[NUM_BUFFERS]; + /* Index of the next available mixing buffer. */ + int next_buffer; +}; + +#endif /* _SDL_vitaaudio_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/audio/wasapi/SDL_wasapi.c b/SDL2-2.30.5/src/audio/wasapi/SDL_wasapi.c similarity index 58% rename from SDL2-2.0.12/src/audio/wasapi/SDL_wasapi.c rename to SDL2-2.30.5/src/audio/wasapi/SDL_wasapi.c index 622a05c..cf90efc 100644 --- a/SDL2-2.0.12/src/audio/wasapi/SDL_wasapi.c +++ b/SDL2-2.30.5/src/audio/wasapi/SDL_wasapi.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -18,151 +18,44 @@ misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ - #include "../../SDL_internal.h" -#if SDL_AUDIO_DRIVER_WASAPI +#ifdef SDL_AUDIO_DRIVER_WASAPI #include "../../core/windows/SDL_windows.h" +#include "../../core/windows/SDL_immdevice.h" #include "SDL_audio.h" #include "SDL_timer.h" #include "../SDL_audio_c.h" #include "../SDL_sysaudio.h" -#include "SDL_assert.h" -#include "SDL_log.h" #define COBJMACROS -#include #include #include "SDL_wasapi.h" -/* This constant isn't available on MinGW-w64 */ +/* These constants aren't available in older SDKs */ #ifndef AUDCLNT_STREAMFLAGS_RATEADJUST -#define AUDCLNT_STREAMFLAGS_RATEADJUST 0x00100000 +#define AUDCLNT_STREAMFLAGS_RATEADJUST 0x00100000 +#endif +#ifndef AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY +#define AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY 0x08000000 +#endif +#ifndef AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM +#define AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM 0x80000000 #endif -/* these increment as default devices change. Opened default devices pick up changes in their threads. */ -SDL_atomic_t WASAPI_DefaultPlaybackGeneration; -SDL_atomic_t WASAPI_DefaultCaptureGeneration; - -/* This is a list of device id strings we have inflight, so we have consistent pointers to the same device. */ -typedef struct DevIdList -{ - WCHAR *str; - struct DevIdList *next; -} DevIdList; - -static DevIdList *deviceid_list = NULL; - /* Some GUIDs we need to know without linking to libraries that aren't available before Vista. */ -static const IID SDL_IID_IAudioRenderClient = { 0xf294acfc, 0x3146, 0x4483,{ 0xa7, 0xbf, 0xad, 0xdc, 0xa7, 0xc2, 0x60, 0xe2 } }; -static const IID SDL_IID_IAudioCaptureClient = { 0xc8adbd64, 0xe71e, 0x48a0,{ 0xa4, 0xde, 0x18, 0x5c, 0x39, 0x5c, 0xd3, 0x17 } }; -static const GUID SDL_KSDATAFORMAT_SUBTYPE_PCM = { 0x00000001, 0x0000, 0x0010,{ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } }; -static const GUID SDL_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = { 0x00000003, 0x0000, 0x0010,{ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } }; - -static SDL_bool -WStrEqual(const WCHAR *a, const WCHAR *b) -{ - while (*a) { - if (*a != *b) { - return SDL_FALSE; - } - a++; - b++; - } - return *b == 0; -} - -static size_t -WStrLen(const WCHAR *wstr) -{ - size_t retval = 0; - if (wstr) { - while (*(wstr++)) { - retval++; - } - } - return retval; -} - -static WCHAR * -WStrDupe(const WCHAR *wstr) -{ - const size_t len = (WStrLen(wstr) + 1) * sizeof (WCHAR); - WCHAR *retval = (WCHAR *) SDL_malloc(len); - if (retval) { - SDL_memcpy(retval, wstr, len); - } - return retval; -} +static const IID SDL_IID_IAudioRenderClient = { 0xf294acfc, 0x3146, 0x4483, { 0xa7, 0xbf, 0xad, 0xdc, 0xa7, 0xc2, 0x60, 0xe2 } }; +static const IID SDL_IID_IAudioCaptureClient = { 0xc8adbd64, 0xe71e, 0x48a0, { 0xa4, 0xde, 0x18, 0x5c, 0x39, 0x5c, 0xd3, 0x17 } }; -void -WASAPI_RemoveDevice(const SDL_bool iscapture, LPCWSTR devid) -{ - DevIdList *i; - DevIdList *next; - DevIdList *prev = NULL; - for (i = deviceid_list; i; i = next) { - next = i->next; - if (WStrEqual(i->str, devid)) { - if (prev) { - prev->next = next; - } else { - deviceid_list = next; - } - SDL_RemoveAudioDevice(iscapture, i->str); - SDL_free(i->str); - SDL_free(i); - } - prev = i; - } -} - -void -WASAPI_AddDevice(const SDL_bool iscapture, const char *devname, LPCWSTR devid) -{ - DevIdList *devidlist; - - /* You can have multiple endpoints on a device that are mutually exclusive ("Speakers" vs "Line Out" or whatever). - In a perfect world, things that are unplugged won't be in this collection. The only gotcha is probably for - phones and tablets, where you might have an internal speaker and a headphone jack and expect both to be - available and switch automatically. (!!! FIXME...?) */ - - /* see if we already have this one. */ - for (devidlist = deviceid_list; devidlist; devidlist = devidlist->next) { - if (WStrEqual(devidlist->str, devid)) { - return; /* we already have this. */ - } - } - - devidlist = (DevIdList *) SDL_malloc(sizeof (*devidlist)); - if (!devidlist) { - return; /* oh well. */ - } - - devid = WStrDupe(devid); - if (!devid) { - SDL_free(devidlist); - return; /* oh well. */ - } - - devidlist->str = (WCHAR *) devid; - devidlist->next = deviceid_list; - deviceid_list = devidlist; - - SDL_AddAudioDevice(iscapture, devname, (void *) devid); -} - -static void -WASAPI_DetectDevices(void) +static void WASAPI_DetectDevices(void) { WASAPI_EnumerateEndpoints(); } -static SDL_INLINE SDL_bool -WasapiFailed(_THIS, const HRESULT err) +static SDL_INLINE SDL_bool WasapiFailed(_THIS, const HRESULT err) { if (err == S_OK) { return SDL_FALSE; @@ -179,50 +72,49 @@ WasapiFailed(_THIS, const HRESULT err) return SDL_TRUE; } -static int -UpdateAudioStream(_THIS, const SDL_AudioSpec *oldspec) +static int UpdateAudioStream(_THIS, const SDL_AudioSpec *oldspec) { /* Since WASAPI requires us to handle all audio conversion, and our device format might have changed, we might have to add/remove/change the audio stream that the higher level uses to convert data, so SDL keeps firing the callback as if nothing happened here. */ - if ( (this->callbackspec.channels == this->spec.channels) && - (this->callbackspec.format == this->spec.format) && - (this->callbackspec.freq == this->spec.freq) && - (this->callbackspec.samples == this->spec.samples) ) { + if ((this->callbackspec.channels == this->spec.channels) && + (this->callbackspec.format == this->spec.format) && + (this->callbackspec.freq == this->spec.freq) && + (this->callbackspec.samples == this->spec.samples)) { /* no need to buffer/convert in an AudioStream! */ SDL_FreeAudioStream(this->stream); this->stream = NULL; - } else if ( (oldspec->channels == this->spec.channels) && - (oldspec->format == this->spec.format) && - (oldspec->freq == this->spec.freq) ) { + } else if ((oldspec->channels == this->spec.channels) && + (oldspec->format == this->spec.format) && + (oldspec->freq == this->spec.freq)) { /* The existing audio stream is okay to keep using. */ } else { /* replace the audiostream for new format */ SDL_FreeAudioStream(this->stream); if (this->iscapture) { this->stream = SDL_NewAudioStream(this->spec.format, - this->spec.channels, this->spec.freq, - this->callbackspec.format, - this->callbackspec.channels, - this->callbackspec.freq); + this->spec.channels, this->spec.freq, + this->callbackspec.format, + this->callbackspec.channels, + this->callbackspec.freq); } else { this->stream = SDL_NewAudioStream(this->callbackspec.format, - this->callbackspec.channels, - this->callbackspec.freq, this->spec.format, - this->spec.channels, this->spec.freq); + this->callbackspec.channels, + this->callbackspec.freq, this->spec.format, + this->spec.channels, this->spec.freq); } if (!this->stream) { - return -1; + return -1; /* SDL_NewAudioStream should have called SDL_SetError. */ } } /* make sure our scratch buffer can cover the new device spec. */ if (this->spec.size > this->work_buffer_len) { - Uint8 *ptr = (Uint8 *) SDL_realloc(this->work_buffer, this->spec.size); - if (ptr == NULL) { + Uint8 *ptr = (Uint8 *)SDL_realloc(this->work_buffer, this->spec.size); + if (!ptr) { return SDL_OutOfMemory(); } this->work_buffer = ptr; @@ -232,16 +124,14 @@ UpdateAudioStream(_THIS, const SDL_AudioSpec *oldspec) return 0; } - static void ReleaseWasapiDevice(_THIS); -static SDL_bool -RecoverWasapiDevice(_THIS) +static SDL_bool RecoverWasapiDevice(_THIS) { - ReleaseWasapiDevice(this); /* dump the lost device's handles. */ + ReleaseWasapiDevice(this); /* dump the lost device's handles. */ if (this->hidden->default_device_generation) { - this->hidden->default_device_generation = SDL_AtomicGet(this->iscapture ? &WASAPI_DefaultCaptureGeneration : &WASAPI_DefaultPlaybackGeneration); + this->hidden->default_device_generation = SDL_AtomicGet(this->iscapture ? &SDL_IMMDevice_DefaultCaptureGeneration : &SDL_IMMDevice_DefaultPlaybackGeneration); } /* this can fail for lots of reasons, but the most likely is we had a @@ -256,26 +146,25 @@ RecoverWasapiDevice(_THIS) this->hidden->device_lost = SDL_FALSE; - return SDL_TRUE; /* okay, carry on with new device details! */ + return SDL_TRUE; /* okay, carry on with new device details! */ } -static SDL_bool -RecoverWasapiIfLost(_THIS) +static SDL_bool RecoverWasapiIfLost(_THIS) { const int generation = this->hidden->default_device_generation; SDL_bool lost = this->hidden->device_lost; if (!SDL_AtomicGet(&this->enabled)) { - return SDL_FALSE; /* already failed. */ + return SDL_FALSE; /* already failed. */ } if (!this->hidden->client) { - return SDL_TRUE; /* still waiting for activation. */ + return SDL_TRUE; /* still waiting for activation. */ } if (!lost && (generation > 0)) { /* is a default device? */ - const int newgen = SDL_AtomicGet(this->iscapture ? &WASAPI_DefaultCaptureGeneration : &WASAPI_DefaultPlaybackGeneration); - if (generation != newgen) { /* the desired default device was changed, jump over to it. */ + const int newgen = SDL_AtomicGet(this->iscapture ? &SDL_IMMDevice_DefaultCaptureGeneration : &SDL_IMMDevice_DefaultPlaybackGeneration); + if (generation != newgen) { /* the desired default device was changed, jump over to it. */ lost = SDL_TRUE; } } @@ -283,33 +172,35 @@ RecoverWasapiIfLost(_THIS) return lost ? RecoverWasapiDevice(this) : SDL_TRUE; } -static Uint8 * -WASAPI_GetDeviceBuf(_THIS) +static void WASAPI_WaitDevice(_THIS); + +static Uint8 *WASAPI_GetDeviceBuf(_THIS) { /* get an endpoint buffer from WASAPI. */ BYTE *buffer = NULL; while (RecoverWasapiIfLost(this) && this->hidden->render) { - if (!WasapiFailed(this, IAudioRenderClient_GetBuffer(this->hidden->render, this->spec.samples, &buffer))) { - return (Uint8 *) buffer; + const HRESULT ret = IAudioRenderClient_GetBuffer(this->hidden->render, this->spec.samples, &buffer); + if (ret == AUDCLNT_E_BUFFER_TOO_LARGE) { + WASAPI_WaitDevice(this); /* see if we can wait on the buffer to drain some more first... */ + } else if (!WasapiFailed(this, ret)) { + return (Uint8 *)buffer; } SDL_assert(buffer == NULL); } - return (Uint8 *) buffer; + return (Uint8 *)buffer; } -static void -WASAPI_PlayDevice(_THIS) +static void WASAPI_PlayDevice(_THIS) { - if (this->hidden->render != NULL) { /* definitely activated? */ + if (this->hidden->render) { /* definitely activated? */ /* WasapiFailed() will mark the device for reacquisition or removal elsewhere. */ WasapiFailed(this, IAudioRenderClient_ReleaseBuffer(this->hidden->render, this->spec.samples, 0)); } } -static void -WASAPI_WaitDevice(_THIS) +static void WASAPI_WaitDevice(_THIS) { while (RecoverWasapiIfLost(this) && this->hidden->client && this->hidden->event) { DWORD waitResult = WaitForSingleObjectEx(this->hidden->event, 200, FALSE); @@ -318,8 +209,14 @@ WASAPI_WaitDevice(_THIS) UINT32 padding = 0; if (!WasapiFailed(this, IAudioClient_GetCurrentPadding(this->hidden->client, &padding))) { /*SDL_Log("WASAPI EVENT! padding=%u maxpadding=%u", (unsigned int)padding, (unsigned int)maxpadding);*/ - if (padding <= maxpadding) { - break; + if (this->iscapture) { + if (padding > 0) { + break; + } + } else { + if (padding <= maxpadding) { + break; + } } } } else if (waitResult != WAIT_TIMEOUT) { @@ -330,8 +227,7 @@ WASAPI_WaitDevice(_THIS) } } -static int -WASAPI_CaptureFromDevice(_THIS, void *buffer, int buflen) +static int WASAPI_CaptureFromDevice(_THIS, void *buffer, int buflen) { SDL_AudioStream *stream = this->hidden->capturestream; const int avail = SDL_AudioStreamAvailable(stream); @@ -363,7 +259,7 @@ WASAPI_CaptureFromDevice(_THIS, void *buffer, int buflen) if ((ret == AUDCLNT_S_BUFFER_EMPTY) || !frames) { WASAPI_WaitDevice(this); } else if (ret == S_OK) { - const int total = ((int) frames) * this->hidden->framesize; + const int total = ((int)frames) * this->hidden->framesize; const int cpy = SDL_min(buflen, total); const int leftover = total - cpy; const SDL_bool silent = (flags & AUDCLNT_BUFFERFLAGS_SILENT) ? SDL_TRUE : SDL_FALSE; @@ -373,15 +269,15 @@ WASAPI_CaptureFromDevice(_THIS, void *buffer, int buflen) } else { SDL_memcpy(buffer, ptr, cpy); } - + if (leftover > 0) { ptr += cpy; if (silent) { - SDL_memset(ptr, this->spec.silence, leftover); /* I guess this is safe? */ + SDL_memset(ptr, this->spec.silence, leftover); /* I guess this is safe? */ } if (SDL_AudioStreamPut(stream, ptr, leftover) == -1) { - return -1; /* uhoh, out of memory, etc. Kill device. :( */ + return -1; /* uhoh, out of memory, etc. Kill device. :( */ } } @@ -392,40 +288,37 @@ WASAPI_CaptureFromDevice(_THIS, void *buffer, int buflen) } } - return -1; /* unrecoverable error. */ + return -1; /* unrecoverable error. */ } -static void -WASAPI_FlushCapture(_THIS) +static void WASAPI_FlushCapture(_THIS) { BYTE *ptr = NULL; UINT32 frames = 0; DWORD flags = 0; if (!this->hidden->capture) { - return; /* not activated yet? */ + return; /* not activated yet? */ } /* just read until we stop getting packets, throwing them away. */ while (SDL_TRUE) { const HRESULT ret = IAudioCaptureClient_GetBuffer(this->hidden->capture, &ptr, &frames, &flags, NULL, NULL); if (ret == AUDCLNT_S_BUFFER_EMPTY) { - break; /* no more buffered data; we're done. */ + break; /* no more buffered data; we're done. */ } else if (WasapiFailed(this, ret)) { - break; /* failed for some other reason, abort. */ + break; /* failed for some other reason, abort. */ } else if (WasapiFailed(this, IAudioCaptureClient_ReleaseBuffer(this->hidden->capture, frames))) { - break; /* something broke. */ + break; /* something broke. */ } } SDL_AudioStreamClear(this->hidden->capturestream); } -static void -ReleaseWasapiDevice(_THIS) +static void ReleaseWasapiDevice(_THIS) { if (this->hidden->client) { IAudioClient_Stop(this->hidden->client); - IAudioClient_SetEventHandle(this->hidden->client, NULL); IAudioClient_Release(this->hidden->client); this->hidden->client = NULL; } @@ -461,20 +354,17 @@ ReleaseWasapiDevice(_THIS) } } -static void -WASAPI_CloseDevice(_THIS) +static void WASAPI_CloseDevice(_THIS) { WASAPI_UnrefDevice(this); } -void -WASAPI_RefDevice(_THIS) +void WASAPI_RefDevice(_THIS) { SDL_AtomicIncRef(&this->hidden->refcount); } -void -WASAPI_UnrefDevice(_THIS) +void WASAPI_UnrefDevice(_THIS) { if (!SDL_AtomicDecRef(&this->hidden->refcount)) { return; @@ -486,13 +376,17 @@ WASAPI_UnrefDevice(_THIS) our callback thread. We do that in WASAPI_ThreadDeinit(). (likewise for this->hidden->coinitialized). */ ReleaseWasapiDevice(this); + + if (SDL_ThreadID() == this->hidden->open_threadid) { + WIN_CoUninitialize(); /* if you closed from a different thread than you opened, sorry, it's a leak. We can't help you. */ + } + SDL_free(this->hidden->devid); SDL_free(this->hidden); } /* This is called once a device is activated, possibly asynchronously. */ -int -WASAPI_PrepDevice(_THIS, const SDL_bool updatestream) +int WASAPI_PrepDevice(_THIS, const SDL_bool updatestream) { /* !!! FIXME: we could request an exclusive mode stream, which is lower latency; !!! it will write into the kernel's audio buffer directly instead of @@ -507,27 +401,26 @@ WASAPI_PrepDevice(_THIS, const SDL_bool updatestream) !!! do in any case. */ const SDL_AudioSpec oldspec = this->spec; const AUDCLNT_SHAREMODE sharemode = AUDCLNT_SHAREMODE_SHARED; - UINT32 bufsize = 0; /* this is in sample frames, not samples, not bytes. */ - REFERENCE_TIME duration = 0; + UINT32 bufsize = 0; /* this is in sample frames, not samples, not bytes. */ + REFERENCE_TIME default_period = 0; IAudioClient *client = this->hidden->client; IAudioRenderClient *render = NULL; IAudioCaptureClient *capture = NULL; WAVEFORMATEX *waveformat = NULL; - SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format); + SDL_AudioFormat test_format; SDL_AudioFormat wasapi_format = 0; - SDL_bool valid_format = SDL_FALSE; HRESULT ret = S_OK; DWORD streamflags = 0; SDL_assert(client != NULL); -#ifdef __WINRT__ /* CreateEventEx() arrived in Vista, so we need an #ifdef for XP. */ +#if defined(__WINRT__) || defined(__GDK__) /* CreateEventEx() arrived in Vista, so we need an #ifdef for XP. */ this->hidden->event = CreateEventEx(NULL, NULL, 0, EVENT_ALL_ACCESS); #else this->hidden->event = CreateEventW(NULL, 0, 0, NULL); #endif - if (this->hidden->event == NULL) { + if (!this->hidden->event) { return WIN_SetError("WASAPI can't create an event handle"); } @@ -539,59 +432,43 @@ WASAPI_PrepDevice(_THIS, const SDL_bool updatestream) SDL_assert(waveformat != NULL); this->hidden->waveformat = waveformat; - this->spec.channels = (Uint8) waveformat->nChannels; + this->spec.channels = (Uint8)waveformat->nChannels; /* Make sure we have a valid format that we can convert to whatever WASAPI wants. */ - if ((waveformat->wFormatTag == WAVE_FORMAT_IEEE_FLOAT) && (waveformat->wBitsPerSample == 32)) { - wasapi_format = AUDIO_F32SYS; - } else if ((waveformat->wFormatTag == WAVE_FORMAT_PCM) && (waveformat->wBitsPerSample == 16)) { - wasapi_format = AUDIO_S16SYS; - } else if ((waveformat->wFormatTag == WAVE_FORMAT_PCM) && (waveformat->wBitsPerSample == 32)) { - wasapi_format = AUDIO_S32SYS; - } else if (waveformat->wFormatTag == WAVE_FORMAT_EXTENSIBLE) { - const WAVEFORMATEXTENSIBLE *ext = (const WAVEFORMATEXTENSIBLE *) waveformat; - if ((SDL_memcmp(&ext->SubFormat, &SDL_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, sizeof (GUID)) == 0) && (waveformat->wBitsPerSample == 32)) { - wasapi_format = AUDIO_F32SYS; - } else if ((SDL_memcmp(&ext->SubFormat, &SDL_KSDATAFORMAT_SUBTYPE_PCM, sizeof (GUID)) == 0) && (waveformat->wBitsPerSample == 16)) { - wasapi_format = AUDIO_S16SYS; - } else if ((SDL_memcmp(&ext->SubFormat, &SDL_KSDATAFORMAT_SUBTYPE_PCM, sizeof (GUID)) == 0) && (waveformat->wBitsPerSample == 32)) { - wasapi_format = AUDIO_S32SYS; - } - } + wasapi_format = WaveFormatToSDLFormat(waveformat); - while ((!valid_format) && (test_format)) { + for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) { if (test_format == wasapi_format) { this->spec.format = test_format; - valid_format = SDL_TRUE; break; } - test_format = SDL_NextAudioFormat(); } - if (!valid_format) { - return SDL_SetError("WASAPI: Unsupported audio format"); + if (!test_format) { + return SDL_SetError("%s: Unsupported audio format", "wasapi"); } - ret = IAudioClient_GetDevicePeriod(client, NULL, &duration); + ret = IAudioClient_GetDevicePeriod(client, &default_period, NULL); if (FAILED(ret)) { return WIN_SetErrorFromHRESULT("WASAPI can't determine minimum device period", ret); } - /* favor WASAPI's resampler over our own, in Win7+. */ + /* we've gotten reports that WASAPI's resampler introduces distortions, but in the short term + it fixes some other WASAPI-specific quirks we haven't quite tracked down. + Refer to bug #6326 for the immediate concern. */ +#if 0 + this->spec.freq = waveformat->nSamplesPerSec; /* force sampling rate so our resampler kicks in, if necessary. */ +#else + /* favor WASAPI's resampler over our own */ if (this->spec.freq != waveformat->nSamplesPerSec) { - /* RATEADJUST only works with output devices in share mode, and is available in Win7 and later.*/ - if (WIN_IsWindows7OrGreater() && !this->iscapture && (sharemode == AUDCLNT_SHAREMODE_SHARED)) { - streamflags |= AUDCLNT_STREAMFLAGS_RATEADJUST; - waveformat->nSamplesPerSec = this->spec.freq; - waveformat->nAvgBytesPerSec = waveformat->nSamplesPerSec * waveformat->nChannels * (waveformat->wBitsPerSample / 8); - } - else { - this->spec.freq = waveformat->nSamplesPerSec; /* force sampling rate so our resampler kicks in. */ - } + streamflags |= (AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM | AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY); + waveformat->nSamplesPerSec = this->spec.freq; + waveformat->nAvgBytesPerSec = waveformat->nSamplesPerSec * waveformat->nChannels * (waveformat->wBitsPerSample / 8); } +#endif streamflags |= AUDCLNT_STREAMFLAGS_EVENTCALLBACK; - ret = IAudioClient_Initialize(client, sharemode, streamflags, duration, sharemode == AUDCLNT_SHAREMODE_SHARED ? 0 : duration, waveformat, NULL); + ret = IAudioClient_Initialize(client, sharemode, streamflags, 0, 0, waveformat, NULL); if (FAILED(ret)) { return WIN_SetErrorFromHRESULT("WASAPI can't initialize audio client", ret); } @@ -606,9 +483,17 @@ WASAPI_PrepDevice(_THIS, const SDL_bool updatestream) return WIN_SetErrorFromHRESULT("WASAPI can't determine buffer size", ret); } - this->spec.samples = (Uint16) bufsize; - if (!this->iscapture) { - this->spec.samples /= 2; /* fill half of the DMA buffer on each run. */ + /* Match the callback size to the period size to cut down on the number of + interrupts waited for in each call to WaitDevice */ + { + const float period_millis = default_period / 10000.0f; + const float period_frames = period_millis * this->spec.freq / 1000.0f; + this->spec.samples = (Uint16)SDL_ceilf(period_frames); + } + + /* regardless of what we calculated for the period size, clamp it to the expected hardware buffer size. */ + if (this->spec.samples > bufsize) { + this->spec.samples = bufsize; } /* Update the fragment size as size in bytes */ @@ -619,10 +504,10 @@ WASAPI_PrepDevice(_THIS, const SDL_bool updatestream) if (this->iscapture) { this->hidden->capturestream = SDL_NewAudioStream(this->spec.format, this->spec.channels, this->spec.freq, this->spec.format, this->spec.channels, this->spec.freq); if (!this->hidden->capturestream) { - return -1; /* already set SDL_Error */ + return -1; /* already set SDL_Error */ } - ret = IAudioClient_GetService(client, &SDL_IID_IAudioCaptureClient, (void**) &capture); + ret = IAudioClient_GetService(client, &SDL_IID_IAudioCaptureClient, (void **)&capture); if (FAILED(ret)) { return WIN_SetErrorFromHRESULT("WASAPI can't get capture client service", ret); } @@ -634,9 +519,9 @@ WASAPI_PrepDevice(_THIS, const SDL_bool updatestream) return WIN_SetErrorFromHRESULT("WASAPI can't start capture", ret); } - WASAPI_FlushCapture(this); /* MSDN says you should flush capture endpoint right after startup. */ + WASAPI_FlushCapture(this); /* MSDN says you should flush capture endpoint right after startup. */ } else { - ret = IAudioClient_GetService(client, &SDL_IID_IAudioRenderClient, (void**) &render); + ret = IAudioClient_GetService(client, &SDL_IID_IAudioRenderClient, (void **)&render); if (FAILED(ret)) { return WIN_SetErrorFromHRESULT("WASAPI can't get render client service", ret); } @@ -650,41 +535,41 @@ WASAPI_PrepDevice(_THIS, const SDL_bool updatestream) } if (updatestream) { - if (UpdateAudioStream(this, &oldspec) == -1) { - return -1; - } + return UpdateAudioStream(this, &oldspec); } - return 0; /* good to go. */ + return 0; /* good to go. */ } - -static int -WASAPI_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) +static int WASAPI_OpenDevice(_THIS, const char *devname) { - LPCWSTR devid = (LPCWSTR) handle; + LPCWSTR devid = (LPCWSTR)this->handle; /* Initialize all variables that we clean on shutdown */ - this->hidden = (struct SDL_PrivateAudioData *) - SDL_malloc((sizeof *this->hidden)); - if (this->hidden == NULL) { + this->hidden = (struct SDL_PrivateAudioData *) SDL_malloc(sizeof(*this->hidden)); + if (!this->hidden) { return SDL_OutOfMemory(); } SDL_zerop(this->hidden); - WASAPI_RefDevice(this); /* so CloseDevice() will unref to zero. */ + WASAPI_RefDevice(this); /* so CloseDevice() will unref to zero. */ - if (!devid) { /* is default device? */ - this->hidden->default_device_generation = SDL_AtomicGet(iscapture ? &WASAPI_DefaultCaptureGeneration : &WASAPI_DefaultPlaybackGeneration); + if (FAILED(WIN_CoInitialize())) { /* WASAPI uses COM, we need to make sure it's initialized. You have to close the device from the same thread!! */ + return SDL_SetError("WIN_CoInitialize failed during WASAPI device open"); + } + this->hidden->open_threadid = SDL_ThreadID(); /* set this _after_ coinitialize so we don't uninit if device fails at the wrong moment. */ + + if (!devid) { /* is default device? */ + this->hidden->default_device_generation = SDL_AtomicGet(this->iscapture ? &SDL_IMMDevice_DefaultCaptureGeneration : &SDL_IMMDevice_DefaultPlaybackGeneration); } else { - this->hidden->devid = WStrDupe(devid); + this->hidden->devid = SDL_wcsdup(devid); if (!this->hidden->devid) { return SDL_OutOfMemory(); } } if (WASAPI_ActivateDevice(this, SDL_FALSE) == -1) { - return -1; /* already set error. */ + return -1; /* already set error. */ } /* Ready, but waiting for async device activation. @@ -698,55 +583,31 @@ WASAPI_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) return 0; } -static void -WASAPI_ThreadInit(_THIS) +static void WASAPI_ThreadInit(_THIS) { WASAPI_PlatformThreadInit(this); } -static void -WASAPI_ThreadDeinit(_THIS) +static void WASAPI_ThreadDeinit(_THIS) { WASAPI_PlatformThreadDeinit(this); } -void -WASAPI_BeginLoopIteration(_THIS) +static void WASAPI_Deinitialize(void) { - /* no-op. */ -} - -static void -WASAPI_Deinitialize(void) -{ - DevIdList *devidlist; - DevIdList *next; - WASAPI_PlatformDeinit(); - - for (devidlist = deviceid_list; devidlist; devidlist = next) { - next = devidlist->next; - SDL_free(devidlist->str); - SDL_free(devidlist); - } - deviceid_list = NULL; } -static int -WASAPI_Init(SDL_AudioDriverImpl * impl) +static SDL_bool WASAPI_Init(SDL_AudioDriverImpl *impl) { - SDL_AtomicSet(&WASAPI_DefaultPlaybackGeneration, 1); - SDL_AtomicSet(&WASAPI_DefaultCaptureGeneration, 1); - if (WASAPI_PlatformInit() == -1) { - return 0; + return SDL_FALSE; } /* Set the function pointers */ impl->DetectDevices = WASAPI_DetectDevices; impl->ThreadInit = WASAPI_ThreadInit; impl->ThreadDeinit = WASAPI_ThreadDeinit; - impl->BeginLoopIteration = WASAPI_BeginLoopIteration; impl->OpenDevice = WASAPI_OpenDevice; impl->PlayDevice = WASAPI_PlayDevice; impl->WaitDevice = WASAPI_WaitDevice; @@ -755,15 +616,17 @@ WASAPI_Init(SDL_AudioDriverImpl * impl) impl->FlushCapture = WASAPI_FlushCapture; impl->CloseDevice = WASAPI_CloseDevice; impl->Deinitialize = WASAPI_Deinitialize; - impl->HasCaptureSupport = 1; + impl->GetDefaultAudioInfo = WASAPI_GetDefaultAudioInfo; + impl->HasCaptureSupport = SDL_TRUE; + impl->SupportsNonPow2Samples = SDL_TRUE; - return 1; /* this audio target is available. */ + return SDL_TRUE; /* this audio target is available. */ } AudioBootStrap WASAPI_bootstrap = { - "wasapi", "WASAPI", WASAPI_Init, 0 + "wasapi", "WASAPI", WASAPI_Init, SDL_FALSE }; -#endif /* SDL_AUDIO_DRIVER_WASAPI */ +#endif /* SDL_AUDIO_DRIVER_WASAPI */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/audio/wasapi/SDL_wasapi.h b/SDL2-2.30.5/src/audio/wasapi/SDL_wasapi.h similarity index 83% rename from SDL2-2.0.12/src/audio/wasapi/SDL_wasapi.h rename to SDL2-2.30.5/src/audio/wasapi/SDL_wasapi.h index 59a0884..804e0b7 100644 --- a/SDL2-2.0.12/src/audio/wasapi/SDL_wasapi.h +++ b/SDL2-2.30.5/src/audio/wasapi/SDL_wasapi.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -47,6 +47,7 @@ struct SDL_PrivateAudioData SDL_AudioStream *capturestream; HANDLE event; HANDLE task; + SDL_threadID open_threadid; SDL_bool coinitialized; int framesize; int default_device_generation; @@ -55,26 +56,20 @@ struct SDL_PrivateAudioData SDL_atomic_t just_activated; }; -/* these increment as default devices change. Opened default devices pick up changes in their threads. */ -extern SDL_atomic_t WASAPI_DefaultPlaybackGeneration; -extern SDL_atomic_t WASAPI_DefaultCaptureGeneration; - /* win32 and winrt implementations call into these. */ int WASAPI_PrepDevice(_THIS, const SDL_bool updatestream); void WASAPI_RefDevice(_THIS); void WASAPI_UnrefDevice(_THIS); -void WASAPI_AddDevice(const SDL_bool iscapture, const char *devname, LPCWSTR devid); -void WASAPI_RemoveDevice(const SDL_bool iscapture, LPCWSTR devid); /* These are functions that are implemented differently for Windows vs WinRT. */ int WASAPI_PlatformInit(void); void WASAPI_PlatformDeinit(void); void WASAPI_EnumerateEndpoints(void); +int WASAPI_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture); int WASAPI_ActivateDevice(_THIS, const SDL_bool isrecovery); void WASAPI_PlatformThreadInit(_THIS); void WASAPI_PlatformThreadDeinit(_THIS); void WASAPI_PlatformDeleteActivationHandler(void *handler); -void WASAPI_BeginLoopIteration(_THIS); #ifdef __cplusplus } diff --git a/SDL2-2.30.5/src/audio/wasapi/SDL_wasapi_win32.c b/SDL2-2.30.5/src/audio/wasapi/SDL_wasapi_win32.c new file mode 100644 index 0000000..88823c5 --- /dev/null +++ b/SDL2-2.30.5/src/audio/wasapi/SDL_wasapi_win32.c @@ -0,0 +1,153 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +/* This is code that Windows uses to talk to WASAPI-related system APIs. + This is for non-WinRT desktop apps. The C++/CX implementation of these + functions, exclusive to WinRT, are in SDL_wasapi_winrt.cpp. + The code in SDL_wasapi.c is used by both standard Windows and WinRT builds + to deal with audio and calls into these functions. */ + +#if defined(SDL_AUDIO_DRIVER_WASAPI) && !defined(__WINRT__) + +#include "../../core/windows/SDL_windows.h" +#include "../../core/windows/SDL_immdevice.h" +#include "SDL_audio.h" +#include "SDL_timer.h" +#include "../SDL_audio_c.h" +#include "../SDL_sysaudio.h" + +#include + +#include "SDL_wasapi.h" + +/* handle to Avrt.dll--Vista and later!--for flagging the callback thread as "Pro Audio" (low latency). */ +static HMODULE libavrt = NULL; +typedef HANDLE(WINAPI *pfnAvSetMmThreadCharacteristicsW)(LPCWSTR, LPDWORD); +typedef BOOL(WINAPI *pfnAvRevertMmThreadCharacteristics)(HANDLE); +static pfnAvSetMmThreadCharacteristicsW pAvSetMmThreadCharacteristicsW = NULL; +static pfnAvRevertMmThreadCharacteristics pAvRevertMmThreadCharacteristics = NULL; + +/* Some GUIDs we need to know without linking to libraries that aren't available before Vista. */ +static const IID SDL_IID_IAudioClient = { 0x1cb9ad4c, 0xdbfa, 0x4c32, { 0xb1, 0x78, 0xc2, 0xf5, 0x68, 0xa7, 0x03, 0xb2 } }; + +int WASAPI_PlatformInit(void) +{ + if (SDL_IMMDevice_Init() < 0) { + return -1; /* This is set by SDL_IMMDevice_Init */ + } + + libavrt = LoadLibrary(TEXT("avrt.dll")); /* this library is available in Vista and later. No WinXP, so have to LoadLibrary to use it for now! */ + if (libavrt) { + pAvSetMmThreadCharacteristicsW = (pfnAvSetMmThreadCharacteristicsW)GetProcAddress(libavrt, "AvSetMmThreadCharacteristicsW"); + pAvRevertMmThreadCharacteristics = (pfnAvRevertMmThreadCharacteristics)GetProcAddress(libavrt, "AvRevertMmThreadCharacteristics"); + } + + return 0; +} + +void WASAPI_PlatformDeinit(void) +{ + if (libavrt) { + FreeLibrary(libavrt); + libavrt = NULL; + } + + pAvSetMmThreadCharacteristicsW = NULL; + pAvRevertMmThreadCharacteristics = NULL; + + SDL_IMMDevice_Quit(); +} + +void WASAPI_PlatformThreadInit(_THIS) +{ + /* this thread uses COM. */ + if (SUCCEEDED(WIN_CoInitialize())) { /* can't report errors, hope it worked! */ + this->hidden->coinitialized = SDL_TRUE; + } + + /* Set this thread to very high "Pro Audio" priority. */ + if (pAvSetMmThreadCharacteristicsW) { + DWORD idx = 0; + this->hidden->task = pAvSetMmThreadCharacteristicsW(L"Pro Audio", &idx); + } +} + +void WASAPI_PlatformThreadDeinit(_THIS) +{ + /* Set this thread back to normal priority. */ + if (this->hidden->task && pAvRevertMmThreadCharacteristics) { + pAvRevertMmThreadCharacteristics(this->hidden->task); + this->hidden->task = NULL; + } + + if (this->hidden->coinitialized) { + WIN_CoUninitialize(); + this->hidden->coinitialized = SDL_FALSE; + } +} + +int WASAPI_ActivateDevice(_THIS, const SDL_bool isrecovery) +{ + IMMDevice *device = NULL; + HRESULT ret; + + if (SDL_IMMDevice_Get(this->hidden->devid, &device, this->iscapture) < 0) { + this->hidden->client = NULL; + return -1; /* This is already set by SDL_IMMDevice_Get */ + } + + /* this is not async in standard win32, yay! */ + ret = IMMDevice_Activate(device, &SDL_IID_IAudioClient, CLSCTX_ALL, NULL, (void **)&this->hidden->client); + IMMDevice_Release(device); + + if (FAILED(ret)) { + SDL_assert(this->hidden->client == NULL); + return WIN_SetErrorFromHRESULT("WASAPI can't activate audio endpoint", ret); + } + + SDL_assert(this->hidden->client != NULL); + if (WASAPI_PrepDevice(this, isrecovery) == -1) { /* not async, fire it right away. */ + return -1; + } + + return 0; /* good to go. */ +} + +void WASAPI_EnumerateEndpoints(void) +{ + SDL_IMMDevice_EnumerateEndpoints(SDL_FALSE); +} + +int WASAPI_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture) +{ + return SDL_IMMDevice_GetDefaultAudioInfo(name, spec, iscapture); +} + +void WASAPI_PlatformDeleteActivationHandler(void *handler) +{ + /* not asynchronous. */ + SDL_assert(!"This function should have only been called on WinRT."); +} + +#endif /* SDL_AUDIO_DRIVER_WASAPI && !defined(__WINRT__) */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/audio/wasapi/SDL_wasapi_winrt.cpp b/SDL2-2.30.5/src/audio/wasapi/SDL_wasapi_winrt.cpp new file mode 100644 index 0000000..26f4838 --- /dev/null +++ b/SDL2-2.30.5/src/audio/wasapi/SDL_wasapi_winrt.cpp @@ -0,0 +1,431 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +// This is C++/CX code that the WinRT port uses to talk to WASAPI-related +// system APIs. The C implementation of these functions, for non-WinRT apps, +// is in SDL_wasapi_win32.c. The code in SDL_wasapi.c is used by both standard +// Windows and WinRT builds to deal with audio and calls into these functions. + +#if defined(SDL_AUDIO_DRIVER_WASAPI) && defined(__WINRT__) + +#include +#include +#include +#include +#include +#include + +extern "C" { +#include "../../core/windows/SDL_windows.h" +#include "SDL_audio.h" +#include "SDL_timer.h" +#include "../SDL_audio_c.h" +#include "../SDL_sysaudio.h" +} + +#define COBJMACROS +#include +#include + +#include "SDL_wasapi.h" + +using namespace Windows::Devices::Enumeration; +using namespace Windows::Media::Devices; +using namespace Windows::Foundation; +using namespace Microsoft::WRL; + +static Platform::String ^ SDL_PKEY_AudioEngine_DeviceFormat = L"{f19f064d-082c-4e27-bc73-6882a1bb8e4c} 0"; + +static void WASAPI_AddDevice(const SDL_bool iscapture, const char *devname, WAVEFORMATEXTENSIBLE *fmt, LPCWSTR devid); +static void WASAPI_RemoveDevice(const SDL_bool iscapture, LPCWSTR devid); +extern "C" { +SDL_atomic_t SDL_IMMDevice_DefaultPlaybackGeneration; +SDL_atomic_t SDL_IMMDevice_DefaultCaptureGeneration; +} + +/* This is a list of device id strings we have inflight, so we have consistent pointers to the same device. */ +typedef struct DevIdList +{ + WCHAR *str; + struct DevIdList *next; +} DevIdList; + +static DevIdList *deviceid_list = NULL; + +class SDL_WasapiDeviceEventHandler +{ + public: + SDL_WasapiDeviceEventHandler(const SDL_bool _iscapture); + ~SDL_WasapiDeviceEventHandler(); + void OnDeviceAdded(DeviceWatcher ^ sender, DeviceInformation ^ args); + void OnDeviceRemoved(DeviceWatcher ^ sender, DeviceInformationUpdate ^ args); + void OnDeviceUpdated(DeviceWatcher ^ sender, DeviceInformationUpdate ^ args); + void OnEnumerationCompleted(DeviceWatcher ^ sender, Platform::Object ^ args); + void OnDefaultRenderDeviceChanged(Platform::Object ^ sender, DefaultAudioRenderDeviceChangedEventArgs ^ args); + void OnDefaultCaptureDeviceChanged(Platform::Object ^ sender, DefaultAudioCaptureDeviceChangedEventArgs ^ args); + SDL_semaphore *completed; + + private: + const SDL_bool iscapture; + DeviceWatcher ^ watcher; + Windows::Foundation::EventRegistrationToken added_handler; + Windows::Foundation::EventRegistrationToken removed_handler; + Windows::Foundation::EventRegistrationToken updated_handler; + Windows::Foundation::EventRegistrationToken completed_handler; + Windows::Foundation::EventRegistrationToken default_changed_handler; +}; + +SDL_WasapiDeviceEventHandler::SDL_WasapiDeviceEventHandler(const SDL_bool _iscapture) + : iscapture(_iscapture), completed(SDL_CreateSemaphore(0)) +{ + if (!completed) + return; // uhoh. + + Platform::String ^ selector = _iscapture ? MediaDevice::GetAudioCaptureSelector() : MediaDevice::GetAudioRenderSelector(); + Platform::Collections::Vector properties; + properties.Append(SDL_PKEY_AudioEngine_DeviceFormat); + watcher = DeviceInformation::CreateWatcher(selector, properties.GetView()); + if (!watcher) + return; // uhoh. + + // !!! FIXME: this doesn't need a lambda here, I think, if I make SDL_WasapiDeviceEventHandler a proper C++/CX class. --ryan. + added_handler = watcher->Added += ref new TypedEventHandler([this](DeviceWatcher ^ sender, DeviceInformation ^ args) { OnDeviceAdded(sender, args); }); + removed_handler = watcher->Removed += ref new TypedEventHandler([this](DeviceWatcher ^ sender, DeviceInformationUpdate ^ args) { OnDeviceRemoved(sender, args); }); + updated_handler = watcher->Updated += ref new TypedEventHandler([this](DeviceWatcher ^ sender, DeviceInformationUpdate ^ args) { OnDeviceUpdated(sender, args); }); + completed_handler = watcher->EnumerationCompleted += ref new TypedEventHandler([this](DeviceWatcher ^ sender, Platform::Object ^ args) { OnEnumerationCompleted(sender, args); }); + if (iscapture) { + default_changed_handler = MediaDevice::DefaultAudioCaptureDeviceChanged += ref new TypedEventHandler([this](Platform::Object ^ sender, DefaultAudioCaptureDeviceChangedEventArgs ^ args) { OnDefaultCaptureDeviceChanged(sender, args); }); + } else { + default_changed_handler = MediaDevice::DefaultAudioRenderDeviceChanged += ref new TypedEventHandler([this](Platform::Object ^ sender, DefaultAudioRenderDeviceChangedEventArgs ^ args) { OnDefaultRenderDeviceChanged(sender, args); }); + } + watcher->Start(); +} + +SDL_WasapiDeviceEventHandler::~SDL_WasapiDeviceEventHandler() +{ + if (watcher) { + watcher->Added -= added_handler; + watcher->Removed -= removed_handler; + watcher->Updated -= updated_handler; + watcher->EnumerationCompleted -= completed_handler; + watcher->Stop(); + watcher = nullptr; + } + if (completed) { + SDL_DestroySemaphore(completed); + completed = nullptr; + } + + if (iscapture) { + MediaDevice::DefaultAudioCaptureDeviceChanged -= default_changed_handler; + } else { + MediaDevice::DefaultAudioRenderDeviceChanged -= default_changed_handler; + } +} + +void SDL_WasapiDeviceEventHandler::OnDeviceAdded(DeviceWatcher ^ sender, DeviceInformation ^ info) +{ + SDL_assert(sender == this->watcher); + char *utf8dev = WIN_StringToUTF8(info->Name->Data()); + if (utf8dev) { + WAVEFORMATEXTENSIBLE fmt; + Platform::Object ^ obj = info->Properties->Lookup(SDL_PKEY_AudioEngine_DeviceFormat); + if (obj) { + IPropertyValue ^ property = (IPropertyValue ^) obj; + Platform::Array ^ data; + property->GetUInt8Array(&data); + SDL_memcpy(&fmt, data->Data, SDL_min(data->Length, sizeof(WAVEFORMATEXTENSIBLE))); + } else { + SDL_zero(fmt); + } + + WASAPI_AddDevice(this->iscapture, utf8dev, &fmt, info->Id->Data()); + SDL_free(utf8dev); + } +} + +void SDL_WasapiDeviceEventHandler::OnDeviceRemoved(DeviceWatcher ^ sender, DeviceInformationUpdate ^ info) +{ + SDL_assert(sender == this->watcher); + WASAPI_RemoveDevice(this->iscapture, info->Id->Data()); +} + +void SDL_WasapiDeviceEventHandler::OnDeviceUpdated(DeviceWatcher ^ sender, DeviceInformationUpdate ^ args) +{ + SDL_assert(sender == this->watcher); +} + +void SDL_WasapiDeviceEventHandler::OnEnumerationCompleted(DeviceWatcher ^ sender, Platform::Object ^ args) +{ + SDL_assert(sender == this->watcher); + SDL_SemPost(this->completed); +} + +void SDL_WasapiDeviceEventHandler::OnDefaultRenderDeviceChanged(Platform::Object ^ sender, DefaultAudioRenderDeviceChangedEventArgs ^ args) +{ + SDL_assert(!this->iscapture); + SDL_AtomicAdd(&SDL_IMMDevice_DefaultPlaybackGeneration, 1); +} + +void SDL_WasapiDeviceEventHandler::OnDefaultCaptureDeviceChanged(Platform::Object ^ sender, DefaultAudioCaptureDeviceChangedEventArgs ^ args) +{ + SDL_assert(this->iscapture); + SDL_AtomicAdd(&SDL_IMMDevice_DefaultCaptureGeneration, 1); +} + +static SDL_WasapiDeviceEventHandler *playback_device_event_handler; +static SDL_WasapiDeviceEventHandler *capture_device_event_handler; + +int WASAPI_PlatformInit(void) +{ + SDL_AtomicSet(&SDL_IMMDevice_DefaultPlaybackGeneration, 1); + SDL_AtomicSet(&SDL_IMMDevice_DefaultCaptureGeneration, 1); + return 0; +} + +void WASAPI_PlatformDeinit(void) +{ + DevIdList *devidlist; + DevIdList *next; + + delete playback_device_event_handler; + playback_device_event_handler = nullptr; + delete capture_device_event_handler; + capture_device_event_handler = nullptr; + + for (devidlist = deviceid_list; devidlist; devidlist = next) { + next = devidlist->next; + SDL_free(devidlist->str); + SDL_free(devidlist); + } + deviceid_list = NULL; +} + +void WASAPI_EnumerateEndpoints(void) +{ + // DeviceWatchers will fire an Added event for each existing device at + // startup, so we don't need to enumerate them separately before + // listening for updates. + playback_device_event_handler = new SDL_WasapiDeviceEventHandler(SDL_FALSE); + capture_device_event_handler = new SDL_WasapiDeviceEventHandler(SDL_TRUE); + SDL_SemWait(playback_device_event_handler->completed); + SDL_SemWait(capture_device_event_handler->completed); +} + +struct SDL_WasapiActivationHandler : public RuntimeClass, FtmBase, IActivateAudioInterfaceCompletionHandler> +{ + SDL_WasapiActivationHandler() : device(nullptr) {} + STDMETHOD(ActivateCompleted) + (IActivateAudioInterfaceAsyncOperation *operation); + SDL_AudioDevice *device; +}; + +HRESULT +SDL_WasapiActivationHandler::ActivateCompleted(IActivateAudioInterfaceAsyncOperation *async) +{ + // Just set a flag, since we're probably in a different thread. We'll pick it up and init everything on our own thread to prevent races. + SDL_AtomicSet(&device->hidden->just_activated, 1); + WASAPI_UnrefDevice(device); + return S_OK; +} + +void WASAPI_PlatformDeleteActivationHandler(void *handler) +{ + ((SDL_WasapiActivationHandler *)handler)->Release(); +} + +int WASAPI_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture) +{ + return SDL_Unsupported(); +} + +int WASAPI_ActivateDevice(_THIS, const SDL_bool isrecovery) +{ + LPCWSTR devid = _this->hidden->devid; + Platform::String ^ defdevid; + + if (devid == nullptr) { + defdevid = _this->iscapture ? MediaDevice::GetDefaultAudioCaptureId(AudioDeviceRole::Default) : MediaDevice::GetDefaultAudioRenderId(AudioDeviceRole::Default); + if (defdevid) { + devid = defdevid->Data(); + } + } + + SDL_AtomicSet(&_this->hidden->just_activated, 0); + + ComPtr handler = Make(); + if (handler == nullptr) { + return SDL_SetError("Failed to allocate WASAPI activation handler"); + } + + handler.Get()->AddRef(); // we hold a reference after ComPtr destructs on return, causing a Release, and Release ourselves in WASAPI_PlatformDeleteActivationHandler(), etc. + handler.Get()->device = _this; + _this->hidden->activation_handler = handler.Get(); + + WASAPI_RefDevice(_this); /* completion handler will unref it. */ + IActivateAudioInterfaceAsyncOperation *async = nullptr; + const HRESULT ret = ActivateAudioInterfaceAsync(devid, __uuidof(IAudioClient), nullptr, handler.Get(), &async); + + if (FAILED(ret) || async == nullptr) { + if (async != nullptr) { + async->Release(); + } + handler.Get()->Release(); + WASAPI_UnrefDevice(_this); + return WIN_SetErrorFromHRESULT("WASAPI can't activate requested audio endpoint", ret); + } + + /* Spin until the async operation is complete. + * If we don't PrepDevice before leaving this function, the bug list gets LONG: + * - device.spec is not filled with the correct information + * - The 'obtained' spec will be wrong for ALLOW_CHANGE properties + * - SDL_AudioStreams will/will not be allocated at the right time + * - SDL_assert(device->callbackspec.size == device->spec.size) will fail + * - When the assert is ignored, skipping or a buffer overflow will occur + */ + while (!SDL_AtomicCAS(&_this->hidden->just_activated, 1, 0)) { + SDL_Delay(1); + } + + HRESULT activateRes = S_OK; + IUnknown *iunknown = nullptr; + const HRESULT getActivateRes = async->GetActivateResult(&activateRes, &iunknown); + async->Release(); + if (FAILED(getActivateRes)) { + return WIN_SetErrorFromHRESULT("Failed to get WASAPI activate result", getActivateRes); + } else if (FAILED(activateRes)) { + return WIN_SetErrorFromHRESULT("Failed to activate WASAPI device", activateRes); + } + + iunknown->QueryInterface(IID_PPV_ARGS(&_this->hidden->client)); + if (!_this->hidden->client) { + return SDL_SetError("Failed to query WASAPI client interface"); + } + + if (WASAPI_PrepDevice(_this, isrecovery) == -1) { + return -1; + } + + return 0; +} + +void WASAPI_PlatformThreadInit(_THIS) +{ + // !!! FIXME: set this thread to "Pro Audio" priority. +} + +void WASAPI_PlatformThreadDeinit(_THIS) +{ + // !!! FIXME: set this thread to "Pro Audio" priority. +} + +/* Everything below was copied from SDL_wasapi.c, before it got moved to SDL_immdevice.c! */ + +static const GUID SDL_KSDATAFORMAT_SUBTYPE_PCM = { 0x00000001, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } }; +static const GUID SDL_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = { 0x00000003, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } }; + +extern "C" SDL_AudioFormat +WaveFormatToSDLFormat(WAVEFORMATEX *waveformat) +{ + if ((waveformat->wFormatTag == WAVE_FORMAT_IEEE_FLOAT) && (waveformat->wBitsPerSample == 32)) { + return AUDIO_F32SYS; + } else if ((waveformat->wFormatTag == WAVE_FORMAT_PCM) && (waveformat->wBitsPerSample == 16)) { + return AUDIO_S16SYS; + } else if ((waveformat->wFormatTag == WAVE_FORMAT_PCM) && (waveformat->wBitsPerSample == 32)) { + return AUDIO_S32SYS; + } else if (waveformat->wFormatTag == WAVE_FORMAT_EXTENSIBLE) { + const WAVEFORMATEXTENSIBLE *ext = (const WAVEFORMATEXTENSIBLE *)waveformat; + if ((SDL_memcmp(&ext->SubFormat, &SDL_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, sizeof(GUID)) == 0) && (waveformat->wBitsPerSample == 32)) { + return AUDIO_F32SYS; + } else if ((SDL_memcmp(&ext->SubFormat, &SDL_KSDATAFORMAT_SUBTYPE_PCM, sizeof(GUID)) == 0) && (waveformat->wBitsPerSample == 16)) { + return AUDIO_S16SYS; + } else if ((SDL_memcmp(&ext->SubFormat, &SDL_KSDATAFORMAT_SUBTYPE_PCM, sizeof(GUID)) == 0) && (waveformat->wBitsPerSample == 32)) { + return AUDIO_S32SYS; + } + } + return 0; +} + +static void WASAPI_RemoveDevice(const SDL_bool iscapture, LPCWSTR devid) +{ + DevIdList *i; + DevIdList *next; + DevIdList *prev = NULL; + for (i = deviceid_list; i; i = next) { + next = i->next; + if (SDL_wcscmp(i->str, devid) == 0) { + if (prev) { + prev->next = next; + } else { + deviceid_list = next; + } + SDL_RemoveAudioDevice(iscapture, i->str); + SDL_free(i->str); + SDL_free(i); + } else { + prev = i; + } + } +} + +static void WASAPI_AddDevice(const SDL_bool iscapture, const char *devname, WAVEFORMATEXTENSIBLE *fmt, LPCWSTR devid) +{ + DevIdList *devidlist; + SDL_AudioSpec spec; + + /* You can have multiple endpoints on a device that are mutually exclusive ("Speakers" vs "Line Out" or whatever). + In a perfect world, things that are unplugged won't be in this collection. The only gotcha is probably for + phones and tablets, where you might have an internal speaker and a headphone jack and expect both to be + available and switch automatically. (!!! FIXME...?) */ + + /* see if we already have this one. */ + for (devidlist = deviceid_list; devidlist; devidlist = devidlist->next) { + if (SDL_wcscmp(devidlist->str, devid) == 0) { + return; /* we already have this. */ + } + } + + devidlist = (DevIdList *)SDL_malloc(sizeof(*devidlist)); + if (!devidlist) { + return; /* oh well. */ + } + + devid = SDL_wcsdup(devid); + if (!devid) { + SDL_free(devidlist); + return; /* oh well. */ + } + + devidlist->str = (WCHAR *)devid; + devidlist->next = deviceid_list; + deviceid_list = devidlist; + + SDL_zero(spec); + spec.channels = (Uint8)fmt->Format.nChannels; + spec.freq = fmt->Format.nSamplesPerSec; + spec.format = WaveFormatToSDLFormat((WAVEFORMATEX *)fmt); + SDL_AddAudioDevice(iscapture, devname, &spec, (void *)devid); +} + +#endif // SDL_AUDIO_DRIVER_WASAPI && defined(__WINRT__) + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/audio/winmm/SDL_winmm.c b/SDL2-2.30.5/src/audio/winmm/SDL_winmm.c similarity index 83% rename from SDL2-2.0.12/src/audio/winmm/SDL_winmm.c rename to SDL2-2.30.5/src/audio/winmm/SDL_winmm.c index e9890d6..47cb4ba 100644 --- a/SDL2-2.0.12/src/audio/winmm/SDL_winmm.c +++ b/SDL2-2.30.5/src/audio/winmm/SDL_winmm.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,14 +20,13 @@ */ #include "../../SDL_internal.h" -#if SDL_AUDIO_DRIVER_WINMM +#ifdef SDL_AUDIO_DRIVER_WINMM /* Allow access to a raw mixing buffer */ #include "../../core/windows/SDL_windows.h" #include -#include "SDL_assert.h" #include "SDL_timer.h" #include "SDL_audio.h" #include "../SDL_audio_c.h" @@ -36,7 +35,7 @@ /* MinGW32 mmsystem.h doesn't include these structures */ #if defined(__MINGW32__) && defined(_MMSYSTEM_H) -typedef struct tagWAVEINCAPS2W +typedef struct tagWAVEINCAPS2W { WORD wMid; WORD wPid; @@ -76,12 +75,19 @@ static void DetectWave##typ##Devs(void) { \ const UINT iscapture = iscap ? 1 : 0; \ const UINT devcount = wave##typ##GetNumDevs(); \ capstyp##2W caps; \ + SDL_AudioSpec spec; \ UINT i; \ + SDL_zero(spec); \ for (i = 0; i < devcount; i++) { \ if (wave##typ##GetDevCaps(i,(LP##capstyp##W)&caps,sizeof(caps))==MMSYSERR_NOERROR) { \ char *name = WIN_LookupAudioDeviceName(caps.szPname,&caps.NameGuid); \ if (name != NULL) { \ - SDL_AddAudioDevice((int) iscapture, name, (void *) ((size_t) i+1)); \ + /* Note that freq/format are not filled in, as this information \ + * is not provided by the caps struct! At best, we get possible \ + * sample formats, but not an _active_ format. \ + */ \ + spec.channels = (Uint8)caps.wChannels; \ + SDL_AddAudioDevice((int) iscapture, name, &spec, (void *) ((size_t) i+1)); \ SDL_free(name); \ } \ } \ @@ -91,16 +97,13 @@ static void DetectWave##typ##Devs(void) { \ DETECT_DEV_IMPL(SDL_FALSE, Out, WAVEOUTCAPS) DETECT_DEV_IMPL(SDL_TRUE, In, WAVEINCAPS) -static void -WINMM_DetectDevices(void) +static void WINMM_DetectDevices(void) { DetectWaveInDevs(); DetectWaveOutDevs(); } -static void CALLBACK -CaptureSound(HWAVEIN hwi, UINT uMsg, DWORD_PTR dwInstance, - DWORD_PTR dwParam1, DWORD_PTR dwParam2) +static void CALLBACK CaptureSound(HWAVEIN hwi, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) { SDL_AudioDevice *this = (SDL_AudioDevice *) dwInstance; @@ -114,9 +117,7 @@ CaptureSound(HWAVEIN hwi, UINT uMsg, DWORD_PTR dwInstance, /* The Win32 callback for filling the WAVE device */ -static void CALLBACK -FillSound(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, - DWORD_PTR dwParam1, DWORD_PTR dwParam2) +static void CALLBACK FillSound(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) { SDL_AudioDevice *this = (SDL_AudioDevice *) dwInstance; @@ -128,8 +129,7 @@ FillSound(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, ReleaseSemaphore(this->hidden->audio_sem, 1, NULL); } -static int -SetMMerror(char *function, MMRESULT code) +static int SetMMerror(const char *function, MMRESULT code) { int len; char errbuf[MAXERRORLENGTH]; @@ -145,22 +145,19 @@ SetMMerror(char *function, MMRESULT code) return SDL_SetError("%s", errbuf); } -static void -WINMM_WaitDevice(_THIS) +static void WINMM_WaitDevice(_THIS) { /* Wait for an audio chunk to finish */ WaitForSingleObject(this->hidden->audio_sem, INFINITE); } -static Uint8 * -WINMM_GetDeviceBuf(_THIS) +static Uint8 *WINMM_GetDeviceBuf(_THIS) { return (Uint8 *) (this->hidden-> wavebuf[this->hidden->next_buffer].lpData); } -static void -WINMM_PlayDevice(_THIS) +static void WINMM_PlayDevice(_THIS) { /* Queue it up */ waveOutWrite(this->hidden->hout, @@ -169,8 +166,7 @@ WINMM_PlayDevice(_THIS) this->hidden->next_buffer = (this->hidden->next_buffer + 1) % NUM_BUFFERS; } -static int -WINMM_CaptureFromDevice(_THIS, void *buffer, int buflen) +static int WINMM_CaptureFromDevice(_THIS, void *buffer, int buflen) { const int nextbuf = this->hidden->next_buffer; MMRESULT result; @@ -186,7 +182,7 @@ WINMM_CaptureFromDevice(_THIS, void *buffer, int buflen) /* requeue the buffer that just finished. */ result = waveInAddBuffer(this->hidden->hin, &this->hidden->wavebuf[nextbuf], - sizeof (this->hidden->wavebuf[nextbuf])); + sizeof(this->hidden->wavebuf[nextbuf])); if (result != MMSYSERR_NOERROR) { return -1; /* uhoh! Disable the device. */ } @@ -196,8 +192,7 @@ WINMM_CaptureFromDevice(_THIS, void *buffer, int buflen) return this->spec.size; } -static void -WINMM_FlushCapture(_THIS) +static void WINMM_FlushCapture(_THIS) { /* Wait for an audio chunk to finish */ if (WaitForSingleObject(this->hidden->audio_sem, 0) == WAIT_OBJECT_0) { @@ -205,13 +200,12 @@ WINMM_FlushCapture(_THIS) /* requeue the buffer that just finished without reading from it. */ waveInAddBuffer(this->hidden->hin, &this->hidden->wavebuf[nextbuf], - sizeof (this->hidden->wavebuf[nextbuf])); + sizeof(this->hidden->wavebuf[nextbuf])); this->hidden->next_buffer = (nextbuf + 1) % NUM_BUFFERS; } } -static void -WINMM_CloseDevice(_THIS) +static void WINMM_CloseDevice(_THIS) { int i; @@ -223,7 +217,7 @@ WINMM_CloseDevice(_THIS) if (this->hidden->wavebuf[i].dwUser != 0xFFFF) { waveOutUnprepareHeader(this->hidden->hout, &this->hidden->wavebuf[i], - sizeof (this->hidden->wavebuf[i])); + sizeof(this->hidden->wavebuf[i])); } } @@ -238,7 +232,7 @@ WINMM_CloseDevice(_THIS) if (this->hidden->wavebuf[i].dwUser != 0xFFFF) { waveInUnprepareHeader(this->hidden->hin, &this->hidden->wavebuf[i], - sizeof (this->hidden->wavebuf[i])); + sizeof(this->hidden->wavebuf[i])); } } waveInClose(this->hidden->hin); @@ -252,8 +246,7 @@ WINMM_CloseDevice(_THIS) SDL_free(this->hidden); } -static SDL_bool -PrepWaveFormat(_THIS, UINT devId, WAVEFORMATEX *pfmt, const int iscapture) +static SDL_bool PrepWaveFormat(_THIS, UINT devId, WAVEFORMATEX *pfmt, const int iscapture) { SDL_zerop(pfmt); @@ -276,26 +269,25 @@ PrepWaveFormat(_THIS, UINT devId, WAVEFORMATEX *pfmt, const int iscapture) } } -static int -WINMM_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) +static int WINMM_OpenDevice(_THIS, const char *devname) { - SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format); - int valid_datatype = 0; + SDL_AudioFormat test_format; + SDL_bool iscapture = this->iscapture; + void *handle = this->handle; MMRESULT result; WAVEFORMATEX waveformat; UINT devId = WAVE_MAPPER; /* WAVE_MAPPER == choose system's default */ UINT i; - if (handle != NULL) { /* specific device requested? */ + if (handle) { /* specific device requested? */ /* -1 because we increment the original value to avoid NULL. */ const size_t val = ((size_t) handle) - 1; devId = (UINT) val; } /* Initialize all variables that we clean on shutdown */ - this->hidden = (struct SDL_PrivateAudioData *) - SDL_malloc((sizeof *this->hidden)); - if (this->hidden == NULL) { + this->hidden = (struct SDL_PrivateAudioData *)SDL_malloc(sizeof(*this->hidden)); + if (!this->hidden) { return SDL_OutOfMemory(); } SDL_zerop(this->hidden); @@ -307,7 +299,7 @@ WINMM_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) if (this->spec.channels > 2) this->spec.channels = 2; /* !!! FIXME: is this right? */ - while ((!valid_datatype) && (test_format)) { + for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) { switch (test_format) { case AUDIO_U8: case AUDIO_S16: @@ -315,20 +307,17 @@ WINMM_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) case AUDIO_F32: this->spec.format = test_format; if (PrepWaveFormat(this, devId, &waveformat, iscapture)) { - valid_datatype = 1; - } else { - test_format = SDL_NextAudioFormat(); + break; } - break; - + continue; default: - test_format = SDL_NextAudioFormat(); - break; + continue; } + break; } - if (!valid_datatype) { - return SDL_SetError("Unsupported audio format"); + if (!test_format) { + return SDL_SetError("%s: Unsupported audio format", "winmm"); } /* Update the fragment size as size in bytes */ @@ -357,7 +346,7 @@ WINMM_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) if (iscapture) { WAVEINCAPS caps; result = waveInGetDevCaps((UINT) this->hidden->hout, - &caps, sizeof (caps)); + &caps, sizeof(caps)); if (result != MMSYSERR_NOERROR) { return SetMMerror("waveInGetDevCaps()", result); } @@ -376,14 +365,14 @@ WINMM_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) /* Create the audio buffer semaphore */ this->hidden->audio_sem = CreateSemaphore(NULL, iscapture ? 0 : NUM_BUFFERS - 1, NUM_BUFFERS, NULL); - if (this->hidden->audio_sem == NULL) { + if (!this->hidden->audio_sem) { return SDL_SetError("Couldn't create semaphore"); } /* Create the sound buffers */ this->hidden->mixbuf = (Uint8 *) SDL_malloc(NUM_BUFFERS * this->spec.size); - if (this->hidden->mixbuf == NULL) { + if (!this->hidden->mixbuf) { return SDL_OutOfMemory(); } @@ -428,9 +417,7 @@ WINMM_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) return 0; /* Ready to go! */ } - -static int -WINMM_Init(SDL_AudioDriverImpl * impl) +static SDL_bool WINMM_Init(SDL_AudioDriverImpl * impl) { /* Set the function pointers */ impl->DetectDevices = WINMM_DetectDevices; @@ -444,11 +431,11 @@ WINMM_Init(SDL_AudioDriverImpl * impl) impl->HasCaptureSupport = SDL_TRUE; - return 1; /* this audio target is available. */ + return SDL_TRUE; /* this audio target is available. */ } AudioBootStrap WINMM_bootstrap = { - "winmm", "Windows Waveform Audio", WINMM_Init, 0 + "winmm", "Windows Waveform Audio", WINMM_Init, SDL_FALSE }; #endif /* SDL_AUDIO_DRIVER_WINMM */ diff --git a/SDL2-2.0.12/src/audio/winmm/SDL_winmm.h b/SDL2-2.30.5/src/audio/winmm/SDL_winmm.h similarity index 96% rename from SDL2-2.0.12/src/audio/winmm/SDL_winmm.h rename to SDL2-2.30.5/src/audio/winmm/SDL_winmm.h index c07bf09..8d0744a 100644 --- a/SDL2-2.0.12/src/audio/winmm/SDL_winmm.h +++ b/SDL2-2.30.5/src/audio/winmm/SDL_winmm.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/core/android/SDL_android.c b/SDL2-2.30.5/src/core/android/SDL_android.c similarity index 68% rename from SDL2-2.0.12/src/core/android/SDL_android.c rename to SDL2-2.30.5/src/core/android/SDL_android.c index 9dd961d..60620d8 100644 --- a/SDL2-2.0.12/src/core/android/SDL_android.c +++ b/SDL2-2.30.5/src/core/android/SDL_android.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -19,21 +19,19 @@ 3. This notice may not be removed or altered from any source distribution. */ #include "../../SDL_internal.h" + #include "SDL_stdinc.h" -#include "SDL_assert.h" #include "SDL_atomic.h" #include "SDL_hints.h" -#include "SDL_log.h" #include "SDL_main.h" #include "SDL_timer.h" +#include "SDL_version.h" #ifdef __ANDROID__ #include "SDL_system.h" #include "SDL_android.h" -#include "keyinfotable.h" - #include "../../events/SDL_events_c.h" #include "../../video/android/SDL_androidkeyboard.h" #include "../../video/android/SDL_androidmouse.h" @@ -44,229 +42,248 @@ #include "../../haptic/android/SDL_syshaptic_c.h" #include +#include +#include #include #include #include #include #include -#define SDL_JAVA_PREFIX org_libsdl_app -#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) +#define SDL_JAVA_PREFIX org_libsdl_app +#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) /* Audio encoding definitions */ -#define ENCODING_PCM_8BIT 3 -#define ENCODING_PCM_16BIT 2 -#define ENCODING_PCM_FLOAT 4 +#define ENCODING_PCM_8BIT 3 +#define ENCODING_PCM_16BIT 2 +#define ENCODING_PCM_FLOAT 4 /* Java class SDLActivity */ +JNIEXPORT jstring JNICALL SDL_JAVA_INTERFACE(nativeGetVersion)( + JNIEnv *env, jclass cls); + JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)( - JNIEnv *env, jclass cls); + JNIEnv *env, jclass cls); JNIEXPORT int JNICALL SDL_JAVA_INTERFACE(nativeRunMain)( - JNIEnv *env, jclass cls, - jstring library, jstring function, jobject array); + JNIEnv *env, jclass cls, + jstring library, jstring function, jobject array); JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeDropFile)( - JNIEnv *env, jclass jcls, - jstring filename); + JNIEnv *env, jclass jcls, + jstring filename); JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetScreenResolution)( - JNIEnv *env, jclass jcls, - jint surfaceWidth, jint surfaceHeight, - jint deviceWidth, jint deviceHeight, jint format, jfloat rate); + JNIEnv *env, jclass jcls, + jint surfaceWidth, jint surfaceHeight, + jint deviceWidth, jint deviceHeight, jfloat rate); JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeResize)( - JNIEnv *env, jclass cls); + JNIEnv *env, jclass cls); JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceCreated)( - JNIEnv *env, jclass jcls); + JNIEnv *env, jclass jcls); JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceChanged)( - JNIEnv *env, jclass jcls); + JNIEnv *env, jclass jcls); JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceDestroyed)( - JNIEnv *env, jclass jcls); + JNIEnv *env, jclass jcls); JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeKeyDown)( - JNIEnv *env, jclass jcls, - jint keycode); + JNIEnv *env, jclass jcls, + jint keycode); JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeKeyUp)( - JNIEnv *env, jclass jcls, - jint keycode); + JNIEnv *env, jclass jcls, + jint keycode); JNIEXPORT jboolean JNICALL SDL_JAVA_INTERFACE(onNativeSoftReturnKey)( - JNIEnv *env, jclass jcls); + JNIEnv *env, jclass jcls); JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeKeyboardFocusLost)( - JNIEnv *env, jclass jcls); + JNIEnv *env, jclass jcls); JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeTouch)( - JNIEnv *env, jclass jcls, - jint touch_device_id_in, jint pointer_finger_id_in, - jint action, jfloat x, jfloat y, jfloat p); + JNIEnv *env, jclass jcls, + jint touch_device_id_in, jint pointer_finger_id_in, + jint action, jfloat x, jfloat y, jfloat p); JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeMouse)( - JNIEnv *env, jclass jcls, - jint button, jint action, jfloat x, jfloat y, jboolean relative); + JNIEnv *env, jclass jcls, + jint button, jint action, jfloat x, jfloat y, jboolean relative); JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeAccel)( - JNIEnv *env, jclass jcls, - jfloat x, jfloat y, jfloat z); + JNIEnv *env, jclass jcls, + jfloat x, jfloat y, jfloat z); JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeClipboardChanged)( - JNIEnv *env, jclass jcls); + JNIEnv *env, jclass jcls); JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeLowMemory)( - JNIEnv *env, jclass cls); + JNIEnv *env, jclass cls); + +JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeLocaleChanged)( + JNIEnv *env, jclass cls); JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSendQuit)( - JNIEnv *env, jclass cls); + JNIEnv *env, jclass cls); JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeQuit)( - JNIEnv *env, jclass cls); + JNIEnv *env, jclass cls); JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativePause)( - JNIEnv *env, jclass cls); + JNIEnv *env, jclass cls); JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeResume)( - JNIEnv *env, jclass cls); + JNIEnv *env, jclass cls); JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeFocusChanged)( - JNIEnv *env, jclass cls, jboolean hasFocus); + JNIEnv *env, jclass cls, jboolean hasFocus); JNIEXPORT jstring JNICALL SDL_JAVA_INTERFACE(nativeGetHint)( - JNIEnv *env, jclass cls, - jstring name); + JNIEnv *env, jclass cls, + jstring name); + +JNIEXPORT jboolean JNICALL SDL_JAVA_INTERFACE(nativeGetHintBoolean)( + JNIEnv *env, jclass cls, + jstring name, jboolean default_value); JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetenv)( - JNIEnv *env, jclass cls, - jstring name, jstring value); + JNIEnv *env, jclass cls, + jstring name, jstring value); JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeOrientationChanged)( - JNIEnv *env, jclass cls, - jint orientation); + JNIEnv *env, jclass cls, + jint orientation); JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeAddTouch)( - JNIEnv* env, jclass cls, - jint touchId, jstring name); + JNIEnv *env, jclass cls, + jint touchId, jstring name); JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativePermissionResult)( - JNIEnv* env, jclass cls, - jint requestCode, jboolean result); + JNIEnv *env, jclass cls, + jint requestCode, jboolean result); static JNINativeMethod SDLActivity_tab[] = { - { "nativeSetupJNI", "()I", SDL_JAVA_INTERFACE(nativeSetupJNI) }, - { "nativeRunMain", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)I", SDL_JAVA_INTERFACE(nativeRunMain) }, - { "onNativeDropFile", "(Ljava/lang/String;)V", SDL_JAVA_INTERFACE(onNativeDropFile) }, - { "nativeSetScreenResolution", "(IIIIIF)V", SDL_JAVA_INTERFACE(nativeSetScreenResolution) }, - { "onNativeResize", "()V", SDL_JAVA_INTERFACE(onNativeResize) }, - { "onNativeSurfaceCreated", "()V", SDL_JAVA_INTERFACE(onNativeSurfaceCreated) }, - { "onNativeSurfaceChanged", "()V", SDL_JAVA_INTERFACE(onNativeSurfaceChanged) }, - { "onNativeSurfaceDestroyed", "()V", SDL_JAVA_INTERFACE(onNativeSurfaceDestroyed) }, - { "onNativeKeyDown", "(I)V", SDL_JAVA_INTERFACE(onNativeKeyDown) }, - { "onNativeKeyUp", "(I)V", SDL_JAVA_INTERFACE(onNativeKeyUp) }, - { "onNativeSoftReturnKey", "()Z", SDL_JAVA_INTERFACE(onNativeSoftReturnKey) }, - { "onNativeKeyboardFocusLost", "()V", SDL_JAVA_INTERFACE(onNativeKeyboardFocusLost) }, - { "onNativeTouch", "(IIIFFF)V", SDL_JAVA_INTERFACE(onNativeTouch) }, - { "onNativeMouse", "(IIFFZ)V", SDL_JAVA_INTERFACE(onNativeMouse) }, - { "onNativeAccel", "(FFF)V", SDL_JAVA_INTERFACE(onNativeAccel) }, - { "onNativeClipboardChanged", "()V", SDL_JAVA_INTERFACE(onNativeClipboardChanged) }, - { "nativeLowMemory", "()V", SDL_JAVA_INTERFACE(nativeLowMemory) }, - { "nativeSendQuit", "()V", SDL_JAVA_INTERFACE(nativeSendQuit) }, - { "nativeQuit", "()V", SDL_JAVA_INTERFACE(nativeQuit) }, - { "nativePause", "()V", SDL_JAVA_INTERFACE(nativePause) }, - { "nativeResume", "()V", SDL_JAVA_INTERFACE(nativeResume) }, - { "nativeFocusChanged", "(Z)V", SDL_JAVA_INTERFACE(nativeFocusChanged) }, - { "nativeGetHint", "(Ljava/lang/String;)Ljava/lang/String;", SDL_JAVA_INTERFACE(nativeGetHint) }, - { "nativeSetenv", "(Ljava/lang/String;Ljava/lang/String;)V", SDL_JAVA_INTERFACE(nativeSetenv) }, + { "nativeGetVersion", "()Ljava/lang/String;", SDL_JAVA_INTERFACE(nativeGetVersion) }, + { "nativeSetupJNI", "()I", SDL_JAVA_INTERFACE(nativeSetupJNI) }, + { "nativeRunMain", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)I", SDL_JAVA_INTERFACE(nativeRunMain) }, + { "onNativeDropFile", "(Ljava/lang/String;)V", SDL_JAVA_INTERFACE(onNativeDropFile) }, + { "nativeSetScreenResolution", "(IIIIF)V", SDL_JAVA_INTERFACE(nativeSetScreenResolution) }, + { "onNativeResize", "()V", SDL_JAVA_INTERFACE(onNativeResize) }, + { "onNativeSurfaceCreated", "()V", SDL_JAVA_INTERFACE(onNativeSurfaceCreated) }, + { "onNativeSurfaceChanged", "()V", SDL_JAVA_INTERFACE(onNativeSurfaceChanged) }, + { "onNativeSurfaceDestroyed", "()V", SDL_JAVA_INTERFACE(onNativeSurfaceDestroyed) }, + { "onNativeKeyDown", "(I)V", SDL_JAVA_INTERFACE(onNativeKeyDown) }, + { "onNativeKeyUp", "(I)V", SDL_JAVA_INTERFACE(onNativeKeyUp) }, + { "onNativeSoftReturnKey", "()Z", SDL_JAVA_INTERFACE(onNativeSoftReturnKey) }, + { "onNativeKeyboardFocusLost", "()V", SDL_JAVA_INTERFACE(onNativeKeyboardFocusLost) }, + { "onNativeTouch", "(IIIFFF)V", SDL_JAVA_INTERFACE(onNativeTouch) }, + { "onNativeMouse", "(IIFFZ)V", SDL_JAVA_INTERFACE(onNativeMouse) }, + { "onNativeAccel", "(FFF)V", SDL_JAVA_INTERFACE(onNativeAccel) }, + { "onNativeClipboardChanged", "()V", SDL_JAVA_INTERFACE(onNativeClipboardChanged) }, + { "nativeLowMemory", "()V", SDL_JAVA_INTERFACE(nativeLowMemory) }, + { "onNativeLocaleChanged", "()V", SDL_JAVA_INTERFACE(onNativeLocaleChanged) }, + { "nativeSendQuit", "()V", SDL_JAVA_INTERFACE(nativeSendQuit) }, + { "nativeQuit", "()V", SDL_JAVA_INTERFACE(nativeQuit) }, + { "nativePause", "()V", SDL_JAVA_INTERFACE(nativePause) }, + { "nativeResume", "()V", SDL_JAVA_INTERFACE(nativeResume) }, + { "nativeFocusChanged", "(Z)V", SDL_JAVA_INTERFACE(nativeFocusChanged) }, + { "nativeGetHint", "(Ljava/lang/String;)Ljava/lang/String;", SDL_JAVA_INTERFACE(nativeGetHint) }, + { "nativeGetHintBoolean", "(Ljava/lang/String;Z)Z", SDL_JAVA_INTERFACE(nativeGetHintBoolean) }, + { "nativeSetenv", "(Ljava/lang/String;Ljava/lang/String;)V", SDL_JAVA_INTERFACE(nativeSetenv) }, { "onNativeOrientationChanged", "(I)V", SDL_JAVA_INTERFACE(onNativeOrientationChanged) }, - { "nativeAddTouch", "(ILjava/lang/String;)V", SDL_JAVA_INTERFACE(nativeAddTouch) }, - { "nativePermissionResult", "(IZ)V", SDL_JAVA_INTERFACE(nativePermissionResult) } + { "nativeAddTouch", "(ILjava/lang/String;)V", SDL_JAVA_INTERFACE(nativeAddTouch) }, + { "nativePermissionResult", "(IZ)V", SDL_JAVA_INTERFACE(nativePermissionResult) } }; /* Java class SDLInputConnection */ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeCommitText)( - JNIEnv *env, jclass cls, - jstring text, jint newCursorPosition); + JNIEnv *env, jclass cls, + jstring text, jint newCursorPosition); JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeGenerateScancodeForUnichar)( - JNIEnv *env, jclass cls, - jchar chUnicode); - -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeSetComposingText)( - JNIEnv *env, jclass cls, - jstring text, jint newCursorPosition); + JNIEnv *env, jclass cls, + jchar chUnicode); static JNINativeMethod SDLInputConnection_tab[] = { - { "nativeCommitText", "(Ljava/lang/String;I)V", SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeCommitText) }, - { "nativeGenerateScancodeForUnichar", "(C)V", SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeGenerateScancodeForUnichar) }, - { "nativeSetComposingText", "(Ljava/lang/String;I)V", SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeSetComposingText) } + { "nativeCommitText", "(Ljava/lang/String;I)V", SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeCommitText) }, + { "nativeGenerateScancodeForUnichar", "(C)V", SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeGenerateScancodeForUnichar) } }; /* Java class SDLAudioManager */ JNIEXPORT void JNICALL SDL_JAVA_AUDIO_INTERFACE(nativeSetupJNI)( - JNIEnv *env, jclass jcls); + JNIEnv *env, jclass jcls); + +JNIEXPORT void JNICALL + SDL_JAVA_AUDIO_INTERFACE(addAudioDevice)(JNIEnv *env, jclass jcls, jboolean is_capture, + jint device_id); + +JNIEXPORT void JNICALL + SDL_JAVA_AUDIO_INTERFACE(removeAudioDevice)(JNIEnv *env, jclass jcls, jboolean is_capture, + jint device_id); static JNINativeMethod SDLAudioManager_tab[] = { - { "nativeSetupJNI", "()I", SDL_JAVA_AUDIO_INTERFACE(nativeSetupJNI) } + { "nativeSetupJNI", "()I", SDL_JAVA_AUDIO_INTERFACE(nativeSetupJNI) }, + { "addAudioDevice", "(ZI)V", SDL_JAVA_AUDIO_INTERFACE(addAudioDevice) }, + { "removeAudioDevice", "(ZI)V", SDL_JAVA_AUDIO_INTERFACE(removeAudioDevice) } }; /* Java class SDLControllerManager */ JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeSetupJNI)( - JNIEnv *env, jclass jcls); + JNIEnv *env, jclass jcls); JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativePadDown)( - JNIEnv *env, jclass jcls, - jint device_id, jint keycode); + 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); + 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); + 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); + 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 vendor_id, jint product_id, - jboolean is_accelerometer, jint button_mask, jint naxes, jint nhats, jint nballs); + JNIEnv *env, jclass jcls, + jint device_id, jstring device_name, jstring device_desc, jint vendor_id, jint product_id, + jboolean is_accelerometer, jint button_mask, jint naxes, jint axis_mask, jint nhats, jint nballs); JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveJoystick)( - JNIEnv *env, jclass jcls, - jint device_id); + 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); + 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); + JNIEnv *env, jclass jcls, + jint device_id); static JNINativeMethod SDLControllerManager_tab[] = { - { "nativeSetupJNI", "()I", SDL_JAVA_CONTROLLER_INTERFACE(nativeSetupJNI) }, - { "onNativePadDown", "(II)I", SDL_JAVA_CONTROLLER_INTERFACE(onNativePadDown) }, - { "onNativePadUp", "(II)I", SDL_JAVA_CONTROLLER_INTERFACE(onNativePadUp) }, - { "onNativeJoy", "(IIF)V", SDL_JAVA_CONTROLLER_INTERFACE(onNativeJoy) }, - { "onNativeHat", "(IIII)V", SDL_JAVA_CONTROLLER_INTERFACE(onNativeHat) }, - { "nativeAddJoystick", "(ILjava/lang/String;Ljava/lang/String;IIZIIII)I", SDL_JAVA_CONTROLLER_INTERFACE(nativeAddJoystick) }, - { "nativeRemoveJoystick", "(I)I", SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveJoystick) }, - { "nativeAddHaptic", "(ILjava/lang/String;)I", SDL_JAVA_CONTROLLER_INTERFACE(nativeAddHaptic) }, - { "nativeRemoveHaptic", "(I)I", SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveHaptic) } + { "nativeSetupJNI", "()I", SDL_JAVA_CONTROLLER_INTERFACE(nativeSetupJNI) }, + { "onNativePadDown", "(II)I", SDL_JAVA_CONTROLLER_INTERFACE(onNativePadDown) }, + { "onNativePadUp", "(II)I", SDL_JAVA_CONTROLLER_INTERFACE(onNativePadUp) }, + { "onNativeJoy", "(IIF)V", SDL_JAVA_CONTROLLER_INTERFACE(onNativeJoy) }, + { "onNativeHat", "(IIII)V", SDL_JAVA_CONTROLLER_INTERFACE(onNativeHat) }, + { "nativeAddJoystick", "(ILjava/lang/String;Ljava/lang/String;IIZIIIII)I", SDL_JAVA_CONTROLLER_INTERFACE(nativeAddJoystick) }, + { "nativeRemoveJoystick", "(I)I", SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveJoystick) }, + { "nativeAddHaptic", "(ILjava/lang/String;)I", SDL_JAVA_CONTROLLER_INTERFACE(nativeAddHaptic) }, + { "nativeRemoveHaptic", "(I)I", SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveHaptic) } }; - /* Uncomment this to log messages entering and exiting methods in this file */ /* #define DEBUG_JNI */ @@ -277,7 +294,6 @@ static void checkJNIReady(void); *******************************************************************************/ #include - /******************************************************************************* Globals *******************************************************************************/ @@ -293,6 +309,7 @@ static jmethodID midClipboardGetText; static jmethodID midClipboardHasText; static jmethodID midClipboardSetText; static jmethodID midCreateCustomCursor; +static jmethodID midDestroyCustomCursor; static jmethodID midGetContext; static jmethodID midGetDisplayDPI; static jmethodID midGetManifestEnvironmentVariables; @@ -305,14 +322,14 @@ static jmethodID midIsScreenKeyboardShown; static jmethodID midIsTablet; static jmethodID midManualBackButton; static jmethodID midMinimizeWindow; -static jmethodID midOpenAPKExpansionInputStream; +static jmethodID midOpenURL; static jmethodID midRequestPermission; +static jmethodID midShowToast; static jmethodID midSendMessage; static jmethodID midSetActivityTitle; static jmethodID midSetCustomCursor; static jmethodID midSetOrientation; static jmethodID midSetRelativeMouseEnabled; -static jmethodID midSetSurfaceViewFormat; static jmethodID midSetSystemCursor; static jmethodID midSetWindowStyle; static jmethodID midShouldMinimizeOnFocusLoss; @@ -323,6 +340,8 @@ static jmethodID midSupportsRelativeMouse; static jclass mAudioManagerClass; /* method signatures */ +static jmethodID midGetAudioOutputDevices; +static jmethodID midGetAudioInputDevices; static jmethodID midAudioOpen; static jmethodID midAudioWriteByteBuffer; static jmethodID midAudioWriteShortBuffer; @@ -354,6 +373,12 @@ static SDL_bool bHasEnvironmentVariables; static SDL_atomic_t bPermissionRequestPending; static SDL_bool bPermissionRequestResult; +/* Android AssetManager */ +static void Internal_Android_Create_AssetManager(void); +static void Internal_Android_Destroy_AssetManager(void); +static AAssetManager *asset_manager = NULL; +static jobject javaAssetManagerRef = 0; + /******************************************************************************* Functions called by JNI *******************************************************************************/ @@ -381,8 +406,8 @@ static SDL_bool bPermissionRequestResult; */ /* Set local storage value */ -static int -Android_JNI_SetEnv(JNIEnv *env) { +static int Android_JNI_SetEnv(JNIEnv *env) +{ int status = pthread_setspecific(mThreadKey, env); if (status < 0) { __android_log_print(ANDROID_LOG_ERROR, "SDL", "Failed pthread_setspecific() in Android_JNI_SetEnv() (err=%d)", status); @@ -391,16 +416,16 @@ Android_JNI_SetEnv(JNIEnv *env) { } /* Get local storage value */ -JNIEnv* Android_JNI_GetEnv(void) +JNIEnv *Android_JNI_GetEnv(void) { /* Get JNIEnv from the Thread local storage */ JNIEnv *env = pthread_getspecific(mThreadKey); - if (env == NULL) { + if (!env) { /* If it fails, try to attach ! (e.g the thread isn't created with SDL_CreateThread() */ int status; /* There should be a JVM */ - if (mJavaVM == NULL) { + if (!mJavaVM) { __android_log_print(ANDROID_LOG_ERROR, "SDL", "Failed, there is no JavaVM"); return NULL; } @@ -429,7 +454,7 @@ int Android_JNI_SetupThread(void) int status; /* There should be a JVM */ - if (mJavaVM == NULL) { + if (!mJavaVM) { __android_log_print(ANDROID_LOG_ERROR, "SDL", "Failed, there is no JavaVM"); return 0; } @@ -451,20 +476,18 @@ int Android_JNI_SetupThread(void) } /* Destructor called for each thread where mThreadKey is not NULL */ -static void -Android_JNI_ThreadDestroyed(void *value) +static void Android_JNI_ThreadDestroyed(void *value) { /* The thread is being destroyed, detach it from the Java VM and set the mThreadKey value to NULL as required */ - JNIEnv *env = (JNIEnv *) value; - if (env != NULL) { + JNIEnv *env = (JNIEnv *)value; + if (env) { (*mJavaVM)->DetachCurrentThread(mJavaVM); Android_JNI_SetEnv(NULL); } } /* Creation of local storage mThreadKey */ -static void -Android_JNI_CreateKey(void) +static void Android_JNI_CreateKey(void) { int status = pthread_key_create(&mThreadKey, Android_JNI_ThreadDestroyed); if (status < 0) { @@ -472,8 +495,7 @@ Android_JNI_CreateKey(void) } } -static void -Android_JNI_CreateKey_once(void) +static void Android_JNI_CreateKey_once(void) { int status = pthread_once(&key_once, Android_JNI_CreateKey); if (status < 0) { @@ -481,11 +503,10 @@ Android_JNI_CreateKey_once(void) } } -static void -register_methods(JNIEnv *env, const char *classname, JNINativeMethod *methods, int nb) +static void register_methods(JNIEnv *env, const char *classname, JNINativeMethod *methods, int nb) { jclass clazz = (*env)->FindClass(env, classname); - if (clazz == NULL || (*env)->RegisterNatives(env, clazz, methods, nb) < 0) { + if (!clazz || (*env)->RegisterNatives(env, clazz, methods, nb) < 0) { __android_log_print(ANDROID_LOG_ERROR, "SDL", "Failed to register methods of %s", classname); return; } @@ -494,9 +515,10 @@ register_methods(JNIEnv *env, const char *classname, JNINativeMethod *methods, i /* Library init */ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { - mJavaVM = vm; JNIEnv *env = NULL; + mJavaVM = vm; + if ((*mJavaVM)->GetEnv(mJavaVM, (void **)&env, JNI_VERSION_1_4) != JNI_OK) { __android_log_print(ANDROID_LOG_ERROR, "SDL", "Failed to get JNI Env"); return JNI_VERSION_1_4; @@ -520,6 +542,16 @@ void checkJNIReady(void) SDL_SetMainReady(); } +/* Get SDL version -- called before SDL_main() to verify JNI bindings */ +JNIEXPORT jstring JNICALL SDL_JAVA_INTERFACE(nativeGetVersion)(JNIEnv *env, jclass cls) +{ + char version[128]; + + SDL_snprintf(version, sizeof(version), "%d.%d.%d", SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL); + + return (*env)->NewStringUTF(env, version); +} + /* Activity initialization -- called before SDL_main() to initialize JNI bindings */ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv *env, jclass cls) { @@ -534,29 +566,28 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv *env, jclass cl /* Save JNIEnv of SDLActivity */ Android_JNI_SetEnv(env); - if (mJavaVM == NULL) { + if (!mJavaVM) { __android_log_print(ANDROID_LOG_ERROR, "SDL", "failed to found a JavaVM"); } /* Use a mutex to prevent concurrency issues between Java Activity and Native thread code, when using 'Android_Window'. * (Eg. Java sending Touch events, while native code is destroying the main SDL_Window. ) */ - if (Android_ActivityMutex == NULL) { + if (!Android_ActivityMutex) { Android_ActivityMutex = SDL_CreateMutex(); /* Could this be created twice if onCreate() is called a second time ? */ } - if (Android_ActivityMutex == NULL) { + if (!Android_ActivityMutex) { __android_log_print(ANDROID_LOG_ERROR, "SDL", "failed to create Android_ActivityMutex mutex"); } - Android_PauseSem = SDL_CreateSemaphore(0); - if (Android_PauseSem == NULL) { + if (!Android_PauseSem) { __android_log_print(ANDROID_LOG_ERROR, "SDL", "failed to create Android_PauseSem semaphore"); } Android_ResumeSem = SDL_CreateSemaphore(0); - if (Android_ResumeSem == NULL) { + if (!Android_ResumeSem) { __android_log_print(ANDROID_LOG_ERROR, "SDL", "failed to create Android_ResumeSem semaphore"); } @@ -566,36 +597,38 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv *env, jclass cl midClipboardHasText = (*env)->GetStaticMethodID(env, mActivityClass, "clipboardHasText", "()Z"); midClipboardSetText = (*env)->GetStaticMethodID(env, mActivityClass, "clipboardSetText", "(Ljava/lang/String;)V"); midCreateCustomCursor = (*env)->GetStaticMethodID(env, mActivityClass, "createCustomCursor", "([IIIII)I"); - midGetContext = (*env)->GetStaticMethodID(env, mActivityClass, "getContext","()Landroid/content/Context;"); + midDestroyCustomCursor = (*env)->GetStaticMethodID(env, mActivityClass, "destroyCustomCursor", "(I)V"); + midGetContext = (*env)->GetStaticMethodID(env, mActivityClass, "getContext", "()Landroid/content/Context;"); midGetDisplayDPI = (*env)->GetStaticMethodID(env, mActivityClass, "getDisplayDPI", "()Landroid/util/DisplayMetrics;"); midGetManifestEnvironmentVariables = (*env)->GetStaticMethodID(env, mActivityClass, "getManifestEnvironmentVariables", "()Z"); - midGetNativeSurface = (*env)->GetStaticMethodID(env, mActivityClass, "getNativeSurface","()Landroid/view/Surface;"); + midGetNativeSurface = (*env)->GetStaticMethodID(env, mActivityClass, "getNativeSurface", "()Landroid/view/Surface;"); midInitTouch = (*env)->GetStaticMethodID(env, mActivityClass, "initTouch", "()V"); - midIsAndroidTV = (*env)->GetStaticMethodID(env, mActivityClass, "isAndroidTV","()Z"); + midIsAndroidTV = (*env)->GetStaticMethodID(env, mActivityClass, "isAndroidTV", "()Z"); midIsChromebook = (*env)->GetStaticMethodID(env, mActivityClass, "isChromebook", "()Z"); midIsDeXMode = (*env)->GetStaticMethodID(env, mActivityClass, "isDeXMode", "()Z"); - midIsScreenKeyboardShown = (*env)->GetStaticMethodID(env, mActivityClass, "isScreenKeyboardShown","()Z"); + midIsScreenKeyboardShown = (*env)->GetStaticMethodID(env, mActivityClass, "isScreenKeyboardShown", "()Z"); midIsTablet = (*env)->GetStaticMethodID(env, mActivityClass, "isTablet", "()Z"); midManualBackButton = (*env)->GetStaticMethodID(env, mActivityClass, "manualBackButton", "()V"); - midMinimizeWindow = (*env)->GetStaticMethodID(env, mActivityClass, "minimizeWindow","()V"); - midOpenAPKExpansionInputStream = (*env)->GetStaticMethodID(env, mActivityClass, "openAPKExpansionInputStream", "(Ljava/lang/String;)Ljava/io/InputStream;"); + midMinimizeWindow = (*env)->GetStaticMethodID(env, mActivityClass, "minimizeWindow", "()V"); + midOpenURL = (*env)->GetStaticMethodID(env, mActivityClass, "openURL", "(Ljava/lang/String;)I"); midRequestPermission = (*env)->GetStaticMethodID(env, mActivityClass, "requestPermission", "(Ljava/lang/String;I)V"); + midShowToast = (*env)->GetStaticMethodID(env, mActivityClass, "showToast", "(Ljava/lang/String;IIII)I"); midSendMessage = (*env)->GetStaticMethodID(env, mActivityClass, "sendMessage", "(II)Z"); - midSetActivityTitle = (*env)->GetStaticMethodID(env, mActivityClass, "setActivityTitle","(Ljava/lang/String;)Z"); + midSetActivityTitle = (*env)->GetStaticMethodID(env, mActivityClass, "setActivityTitle", "(Ljava/lang/String;)Z"); midSetCustomCursor = (*env)->GetStaticMethodID(env, mActivityClass, "setCustomCursor", "(I)Z"); - midSetOrientation = (*env)->GetStaticMethodID(env, mActivityClass, "setOrientation","(IIZLjava/lang/String;)V"); + midSetOrientation = (*env)->GetStaticMethodID(env, mActivityClass, "setOrientation", "(IIZLjava/lang/String;)V"); midSetRelativeMouseEnabled = (*env)->GetStaticMethodID(env, mActivityClass, "setRelativeMouseEnabled", "(Z)Z"); - midSetSurfaceViewFormat = (*env)->GetStaticMethodID(env, mActivityClass, "setSurfaceViewFormat","(I)V"); midSetSystemCursor = (*env)->GetStaticMethodID(env, mActivityClass, "setSystemCursor", "(I)Z"); - midSetWindowStyle = (*env)->GetStaticMethodID(env, mActivityClass, "setWindowStyle","(Z)V"); - midShouldMinimizeOnFocusLoss = (*env)->GetStaticMethodID(env, mActivityClass, "shouldMinimizeOnFocusLoss","()Z"); - midShowTextInput = (*env)->GetStaticMethodID(env, mActivityClass, "showTextInput", "(IIII)Z"); + midSetWindowStyle = (*env)->GetStaticMethodID(env, mActivityClass, "setWindowStyle", "(Z)V"); + midShouldMinimizeOnFocusLoss = (*env)->GetStaticMethodID(env, mActivityClass, "shouldMinimizeOnFocusLoss", "()Z"); + midShowTextInput = (*env)->GetStaticMethodID(env, mActivityClass, "showTextInput", "(IIII)Z"); midSupportsRelativeMouse = (*env)->GetStaticMethodID(env, mActivityClass, "supportsRelativeMouse", "()Z"); if (!midClipboardGetText || !midClipboardHasText || !midClipboardSetText || !midCreateCustomCursor || + !midDestroyCustomCursor || !midGetContext || !midGetDisplayDPI || !midGetManifestEnvironmentVariables || @@ -608,14 +641,14 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv *env, jclass cl !midIsTablet || !midManualBackButton || !midMinimizeWindow || - !midOpenAPKExpansionInputStream || + !midOpenURL || !midRequestPermission || + !midShowToast || !midSendMessage || !midSetActivityTitle || !midSetCustomCursor || !midSetOrientation || !midSetRelativeMouseEnabled || - !midSetSurfaceViewFormat || !midSetSystemCursor || !midSetWindowStyle || !midShouldMinimizeOnFocusLoss || @@ -634,32 +667,42 @@ JNIEXPORT void JNICALL SDL_JAVA_AUDIO_INTERFACE(nativeSetupJNI)(JNIEnv *env, jcl mAudioManagerClass = (jclass)((*env)->NewGlobalRef(env, cls)); + midGetAudioOutputDevices = (*env)->GetStaticMethodID(env, mAudioManagerClass, + "getAudioOutputDevices", + "()[I"); + midGetAudioInputDevices = (*env)->GetStaticMethodID(env, mAudioManagerClass, + "getAudioInputDevices", + "()[I"); midAudioOpen = (*env)->GetStaticMethodID(env, mAudioManagerClass, - "audioOpen", "(IIII)[I"); + "audioOpen", "(IIIII)[I"); midAudioWriteByteBuffer = (*env)->GetStaticMethodID(env, mAudioManagerClass, - "audioWriteByteBuffer", "([B)V"); + "audioWriteByteBuffer", "([B)V"); midAudioWriteShortBuffer = (*env)->GetStaticMethodID(env, mAudioManagerClass, - "audioWriteShortBuffer", "([S)V"); + "audioWriteShortBuffer", "([S)V"); midAudioWriteFloatBuffer = (*env)->GetStaticMethodID(env, mAudioManagerClass, - "audioWriteFloatBuffer", "([F)V"); + "audioWriteFloatBuffer", "([F)V"); midAudioClose = (*env)->GetStaticMethodID(env, mAudioManagerClass, - "audioClose", "()V"); + "audioClose", "()V"); midCaptureOpen = (*env)->GetStaticMethodID(env, mAudioManagerClass, - "captureOpen", "(IIII)[I"); + "captureOpen", "(IIIII)[I"); midCaptureReadByteBuffer = (*env)->GetStaticMethodID(env, mAudioManagerClass, - "captureReadByteBuffer", "([BZ)I"); + "captureReadByteBuffer", "([BZ)I"); midCaptureReadShortBuffer = (*env)->GetStaticMethodID(env, mAudioManagerClass, - "captureReadShortBuffer", "([SZ)I"); + "captureReadShortBuffer", "([SZ)I"); midCaptureReadFloatBuffer = (*env)->GetStaticMethodID(env, mAudioManagerClass, - "captureReadFloatBuffer", "([FZ)I"); + "captureReadFloatBuffer", "([FZ)I"); midCaptureClose = (*env)->GetStaticMethodID(env, mAudioManagerClass, - "captureClose", "()V"); + "captureClose", "()V"); midAudioSetThreadPriority = (*env)->GetStaticMethodID(env, mAudioManagerClass, - "audioSetThreadPriority", "(ZI)V"); + "audioSetThreadPriority", "(ZI)V"); - if (!midAudioOpen || !midAudioWriteByteBuffer || !midAudioWriteShortBuffer || !midAudioWriteFloatBuffer || !midAudioClose || - !midCaptureOpen || !midCaptureReadByteBuffer || !midCaptureReadShortBuffer || !midCaptureReadFloatBuffer || !midCaptureClose || !midAudioSetThreadPriority) { - __android_log_print(ANDROID_LOG_WARN, "SDL", "Missing some Java callbacks, do you have the latest version of SDLAudioManager.java?"); + if (!midGetAudioOutputDevices || !midGetAudioInputDevices || !midAudioOpen || + !midAudioWriteByteBuffer || !midAudioWriteShortBuffer || !midAudioWriteFloatBuffer || + !midAudioClose || + !midCaptureOpen || !midCaptureReadByteBuffer || !midCaptureReadShortBuffer || + !midCaptureReadFloatBuffer || !midCaptureClose || !midAudioSetThreadPriority) { + __android_log_print(ANDROID_LOG_WARN, "SDL", + "Missing some Java callbacks, do you have the latest version of SDLAudioManager.java?"); } checkJNIReady(); @@ -673,13 +716,13 @@ JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeSetupJNI)(JNIEnv *env mControllerManagerClass = (jclass)((*env)->NewGlobalRef(env, cls)); midPollInputDevices = (*env)->GetStaticMethodID(env, mControllerManagerClass, - "pollInputDevices", "()V"); + "pollInputDevices", "()V"); midPollHapticDevices = (*env)->GetStaticMethodID(env, mControllerManagerClass, - "pollHapticDevices", "()V"); + "pollHapticDevices", "()V"); midHapticRun = (*env)->GetStaticMethodID(env, mControllerManagerClass, - "hapticRun", "(IFI)V"); + "hapticRun", "(IFI)V"); midHapticStop = (*env)->GetStaticMethodID(env, mControllerManagerClass, - "hapticStop", "(I)V"); + "hapticStop", "(I)V"); if (!midPollInputDevices || !midPollHapticDevices || !midHapticRun || !midHapticStop) { __android_log_print(ANDROID_LOG_WARN, "SDL", "Missing some Java callbacks, do you have the latest version of SDLControllerManager.java?"); @@ -706,7 +749,7 @@ JNIEXPORT int JNICALL SDL_JAVA_INTERFACE(nativeRunMain)(JNIEnv *env, jclass cls, library_file = (*env)->GetStringUTFChars(env, library, NULL); library_handle = dlopen(library_file, RTLD_GLOBAL); - if (!library_handle) { + if (library_handle == NULL) { /* When deploying android app bundle format uncompressed native libs may not extract from apk to filesystem. In this case we should use lib name without path. https://bugzilla.libsdl.org/show_bug.cgi?id=4739 */ const char *library_name = SDL_strrchr(library_file, '/'); @@ -731,7 +774,7 @@ JNIEXPORT int JNICALL SDL_JAVA_INTERFACE(nativeRunMain)(JNIEnv *env, jclass cls, /* Prepare the arguments. */ len = (*env)->GetArrayLength(env, array); - argv = SDL_small_alloc(char *, 1 + len + 1, &isstack); /* !!! FIXME: check for NULL */ + argv = SDL_small_alloc(char *, 1 + len + 1, &isstack); /* !!! FIXME: check for NULL */ argc = 0; /* Use the name "app_process" so PHYSFS_platformCalcBaseDir() works. https://bitbucket.org/MartinFelis/love-android-sdl2/issue/23/release-build-crash-on-start @@ -749,14 +792,13 @@ JNIEXPORT int JNICALL SDL_JAVA_INTERFACE(nativeRunMain)(JNIEnv *env, jclass cls, } (*env)->DeleteLocalRef(env, string); } - if (!arg) { + if (arg == NULL) { arg = SDL_strdup(""); } argv[argc++] = arg; } argv[argc] = NULL; - /* Run the application. */ status = SDL_main(argc, argv); @@ -790,8 +832,8 @@ JNIEXPORT int JNICALL SDL_JAVA_INTERFACE(nativeRunMain)(JNIEnv *env, jclass cls, /* Drop file */ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeDropFile)( - JNIEnv *env, jclass jcls, - jstring filename) + JNIEnv *env, jclass jcls, + jstring filename) { const char *path = (*env)->GetStringUTFChars(env, filename, NULL); SDL_SendDropFile(NULL, path); @@ -800,16 +842,19 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeDropFile)( } /* Lock / Unlock Mutex */ -void Android_ActivityMutex_Lock() { +void Android_ActivityMutex_Lock() +{ SDL_LockMutex(Android_ActivityMutex); } -void Android_ActivityMutex_Unlock() { +void Android_ActivityMutex_Unlock() +{ SDL_UnlockMutex(Android_ActivityMutex); } /* Lock the Mutex when the Activity is in its 'Running' state */ -void Android_ActivityMutex_Lock_Running() { +void Android_ActivityMutex_Lock_Running() +{ int pauseSignaled = 0; int resumeSignaled = 0; @@ -829,25 +874,24 @@ retry: /* Set screen resolution */ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetScreenResolution)( - JNIEnv *env, jclass jcls, - jint surfaceWidth, jint surfaceHeight, - jint deviceWidth, jint deviceHeight, jint format, jfloat rate) + JNIEnv *env, jclass jcls, + jint surfaceWidth, jint surfaceHeight, + jint deviceWidth, jint deviceHeight, jfloat rate) { SDL_LockMutex(Android_ActivityMutex); - Android_SetScreenResolution(surfaceWidth, surfaceHeight, deviceWidth, deviceHeight, format, rate); + Android_SetScreenResolution(surfaceWidth, surfaceHeight, deviceWidth, deviceHeight, rate); SDL_UnlockMutex(Android_ActivityMutex); } /* Resize */ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeResize)( - JNIEnv *env, jclass jcls) + JNIEnv *env, jclass jcls) { SDL_LockMutex(Android_ActivityMutex); - if (Android_Window) - { + if (Android_Window) { Android_SendResize(Android_Window); } @@ -855,15 +899,14 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeResize)( } JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeOrientationChanged)( - JNIEnv *env, jclass jcls, - jint orientation) + JNIEnv *env, jclass jcls, + jint orientation) { SDL_LockMutex(Android_ActivityMutex); displayOrientation = (SDL_DisplayOrientation)orientation; - if (Android_Window) - { + if (Android_Window) { SDL_VideoDisplay *display = SDL_GetDisplay(0); SDL_SendDisplayEvent(display, SDL_DISPLAYEVENT_ORIENTATION, orientation); } @@ -872,68 +915,92 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeOrientationChanged)( } JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeAddTouch)( - JNIEnv* env, jclass cls, - jint touchId, jstring name) + JNIEnv *env, jclass cls, + jint touchId, jstring name) { const char *utfname = (*env)->GetStringUTFChars(env, name, NULL); - SDL_AddTouch((SDL_TouchID) touchId, SDL_TOUCH_DEVICE_DIRECT, utfname); + SDL_AddTouch((SDL_TouchID)touchId, SDL_TOUCH_DEVICE_DIRECT, utfname); (*env)->ReleaseStringUTFChars(env, name, utfname); } JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativePermissionResult)( - JNIEnv* env, jclass cls, - jint requestCode, jboolean result) + JNIEnv *env, jclass cls, + jint requestCode, jboolean result) { bPermissionRequestResult = result; SDL_AtomicSet(&bPermissionRequestPending, SDL_FALSE); } +extern void SDL_AddAudioDevice(const SDL_bool iscapture, const char *name, SDL_AudioSpec *spec, void *handle); +extern void SDL_RemoveAudioDevice(const SDL_bool iscapture, void *handle); + +JNIEXPORT void JNICALL +SDL_JAVA_AUDIO_INTERFACE(addAudioDevice)(JNIEnv *env, jclass jcls, jboolean is_capture, + jint device_id) +{ + if (SDL_GetCurrentAudioDriver() != NULL) { + char device_name[64]; + SDL_snprintf(device_name, sizeof(device_name), "%d", device_id); + SDL_Log("Adding device with name %s, capture %d", device_name, is_capture); + SDL_AddAudioDevice(is_capture, SDL_strdup(device_name), NULL, (void *)((size_t)device_id + 1)); + } +} + +JNIEXPORT void JNICALL +SDL_JAVA_AUDIO_INTERFACE(removeAudioDevice)(JNIEnv *env, jclass jcls, jboolean is_capture, + jint device_id) +{ + if (SDL_GetCurrentAudioDriver() != NULL) { + SDL_Log("Removing device with handle %d, capture %d", device_id + 1, is_capture); + SDL_RemoveAudioDevice(is_capture, (void *)((size_t)device_id + 1)); + } +} + /* Paddown */ JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativePadDown)( - JNIEnv *env, jclass jcls, - jint device_id, jint keycode) + JNIEnv *env, jclass jcls, + jint device_id, jint keycode) { return Android_OnPadDown(device_id, keycode); } /* Padup */ JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativePadUp)( - JNIEnv *env, jclass jcls, - jint device_id, jint keycode) + JNIEnv *env, jclass jcls, + jint device_id, jint keycode) { return Android_OnPadUp(device_id, keycode); } /* Joy */ JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativeJoy)( - JNIEnv *env, jclass jcls, - jint device_id, jint axis, jfloat value) + JNIEnv *env, jclass jcls, + jint device_id, jint axis, jfloat value) { Android_OnJoy(device_id, axis, value); } /* POV Hat */ JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativeHat)( - JNIEnv *env, jclass jcls, - jint device_id, jint hat_id, jint x, jint y) + JNIEnv *env, jclass jcls, + jint device_id, jint hat_id, jint x, jint y) { Android_OnHat(device_id, hat_id, x, y); } - JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeAddJoystick)( - JNIEnv *env, jclass jcls, - jint device_id, jstring device_name, jstring device_desc, - jint vendor_id, jint product_id, jboolean is_accelerometer, - jint button_mask, jint naxes, jint nhats, jint nballs) + JNIEnv *env, jclass jcls, + jint device_id, jstring device_name, jstring device_desc, + jint vendor_id, jint product_id, jboolean is_accelerometer, + jint button_mask, jint naxes, jint axis_mask, jint nhats, jint nballs) { int retval; const char *name = (*env)->GetStringUTFChars(env, device_name, NULL); const char *desc = (*env)->GetStringUTFChars(env, device_desc, NULL); - retval = Android_AddJoystick(device_id, name, desc, vendor_id, product_id, is_accelerometer ? SDL_TRUE : SDL_FALSE, button_mask, naxes, nhats, nballs); + retval = Android_AddJoystick(device_id, name, desc, vendor_id, product_id, is_accelerometer ? SDL_TRUE : SDL_FALSE, button_mask, naxes, axis_mask, nhats, nballs); (*env)->ReleaseStringUTFChars(env, device_name, name); (*env)->ReleaseStringUTFChars(env, device_desc, desc); @@ -942,8 +1009,8 @@ JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeAddJoystick)( } JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveJoystick)( - JNIEnv *env, jclass jcls, - jint device_id) + JNIEnv *env, jclass jcls, + jint device_id) { return Android_RemoveJoystick(device_id); } @@ -972,9 +1039,8 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceCreated)(JNIEnv *env, j { SDL_LockMutex(Android_ActivityMutex); - if (Android_Window) - { - SDL_WindowData *data = (SDL_WindowData *) Android_Window->driverdata; + if (Android_Window) { + SDL_WindowData *data = (SDL_WindowData *)Android_Window->driverdata; data->native_window = Android_JNI_GetNativeWindow(); if (data->native_window == NULL) { @@ -990,18 +1056,19 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceChanged)(JNIEnv *env, j { SDL_LockMutex(Android_ActivityMutex); - if (Android_Window) - { +#ifdef SDL_VIDEO_OPENGL_EGL + if (Android_Window) { SDL_VideoDevice *_this = SDL_GetVideoDevice(); - SDL_WindowData *data = (SDL_WindowData *) Android_Window->driverdata; + SDL_WindowData *data = (SDL_WindowData *)Android_Window->driverdata; /* If the surface has been previously destroyed by onNativeSurfaceDestroyed, recreate it here */ if (data->egl_surface == EGL_NO_SURFACE) { - data->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) data->native_window); + data->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType)data->native_window); } /* GL Context handling is done in the event loop because this function is run from the Java thread */ } +#endif SDL_UnlockMutex(Android_ActivityMutex); } @@ -1015,13 +1082,12 @@ retry: SDL_LockMutex(Android_ActivityMutex); - if (Android_Window) - { + if (Android_Window) { SDL_VideoDevice *_this = SDL_GetVideoDevice(); - SDL_WindowData *data = (SDL_WindowData *) Android_Window->driverdata; + SDL_WindowData *data = (SDL_WindowData *)Android_Window->driverdata; /* Wait for Main thread being paused and context un-activated to release 'egl_surface' */ - if (! data->backup_done) { + if (!data->backup_done) { nb_attempt -= 1; if (nb_attempt == 0) { SDL_SetError("Try to release egl_surface with context probably still active"); @@ -1032,10 +1098,12 @@ retry: } } +#ifdef SDL_VIDEO_OPENGL_EGL if (data->egl_surface != EGL_NO_SURFACE) { SDL_EGL_DestroySurface(_this, data->egl_surface); data->egl_surface = EGL_NO_SURFACE; } +#endif if (data->native_window) { ANativeWindow_release(data->native_window); @@ -1050,23 +1118,23 @@ retry: /* Keydown */ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeKeyDown)( - JNIEnv *env, jclass jcls, - jint keycode) + JNIEnv *env, jclass jcls, + jint keycode) { Android_OnKeyDown(keycode); } /* Keyup */ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeKeyUp)( - JNIEnv *env, jclass jcls, - jint keycode) + JNIEnv *env, jclass jcls, + jint keycode) { Android_OnKeyUp(keycode); } /* Virtual keyboard return key might stop text input */ JNIEXPORT jboolean JNICALL SDL_JAVA_INTERFACE(onNativeSoftReturnKey)( - JNIEnv *env, jclass jcls) + JNIEnv *env, jclass jcls) { if (SDL_GetHintBoolean(SDL_HINT_RETURN_KEY_HIDES_IME, SDL_FALSE)) { SDL_StopTextInput(); @@ -1077,18 +1145,17 @@ JNIEXPORT jboolean JNICALL SDL_JAVA_INTERFACE(onNativeSoftReturnKey)( /* Keyboard Focus Lost */ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeKeyboardFocusLost)( - JNIEnv *env, jclass jcls) + JNIEnv *env, jclass jcls) { /* Calling SDL_StopTextInput will take care of hiding the keyboard and cleaning up the DummyText widget */ SDL_StopTextInput(); } - /* Touch */ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeTouch)( - JNIEnv *env, jclass jcls, - jint touch_device_id_in, jint pointer_finger_id_in, - jint action, jfloat x, jfloat y, jfloat p) + JNIEnv *env, jclass jcls, + jint touch_device_id_in, jint pointer_finger_id_in, + jint action, jfloat x, jfloat y, jfloat p) { SDL_LockMutex(Android_ActivityMutex); @@ -1099,8 +1166,8 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeTouch)( /* Mouse */ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeMouse)( - JNIEnv *env, jclass jcls, - jint button, jint action, jfloat x, jfloat y, jboolean relative) + JNIEnv *env, jclass jcls, + jint button, jint action, jfloat x, jfloat y, jboolean relative) { SDL_LockMutex(Android_ActivityMutex); @@ -1111,8 +1178,8 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeMouse)( /* Accelerometer */ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeAccel)( - JNIEnv *env, jclass jcls, - jfloat x, jfloat y, jfloat z) + JNIEnv *env, jclass jcls, + jfloat x, jfloat y, jfloat z) { fLastAccelerometer[0] = x; fLastAccelerometer[1] = y; @@ -1122,21 +1189,29 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeAccel)( /* Clipboard */ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeClipboardChanged)( - JNIEnv *env, jclass jcls) + JNIEnv *env, jclass jcls) { SDL_SendClipboardUpdate(); } /* Low memory */ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeLowMemory)( - JNIEnv *env, jclass cls) + JNIEnv *env, jclass cls) { SDL_SendAppEvent(SDL_APP_LOWMEMORY); } +/* Locale + * requires android:configChanges="layoutDirection|locale" in AndroidManifest.xml */ +JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeLocaleChanged)( + JNIEnv *env, jclass cls) +{ + SDL_SendAppEvent(SDL_LOCALECHANGED); +} + /* Send Quit event to "SDLThread" thread */ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSendQuit)( - JNIEnv *env, jclass cls) + JNIEnv *env, jclass cls) { /* Discard previous events. The user should have handled state storage * in SDL_APP_WILLENTERBACKGROUND. After nativeSendQuit() is called, no @@ -1156,7 +1231,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSendQuit)( /* Activity ends */ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeQuit)( - JNIEnv *env, jclass cls) + JNIEnv *env, jclass cls) { const char *str; @@ -1175,6 +1250,8 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeQuit)( Android_ResumeSem = NULL; } + Internal_Android_Destroy_AssetManager(); + str = SDL_GetError(); if (str && str[0]) { __android_log_print(ANDROID_LOG_ERROR, "SDL", "SDLActivity thread ends (error=%s)", str); @@ -1185,7 +1262,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeQuit)( /* Pause */ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativePause)( - JNIEnv *env, jclass cls) + JNIEnv *env, jclass cls) { __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "nativePause()"); @@ -1196,7 +1273,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativePause)( /* Resume */ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeResume)( - JNIEnv *env, jclass cls) + JNIEnv *env, jclass cls) { __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "nativeResume()"); @@ -1208,7 +1285,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeResume)( } JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeFocusChanged)( - JNIEnv *env, jclass cls, jboolean hasFocus) + JNIEnv *env, jclass cls, jboolean hasFocus) { SDL_LockMutex(Android_ActivityMutex); @@ -1221,8 +1298,8 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeFocusChanged)( } JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeCommitText)( - JNIEnv *env, jclass cls, - jstring text, jint newCursorPosition) + JNIEnv *env, jclass cls, + jstring text, jint newCursorPosition) { const char *utftext = (*env)->GetStringUTFChars(env, text, NULL); @@ -1232,48 +1309,15 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeCommitText)( } JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeGenerateScancodeForUnichar)( - JNIEnv *env, jclass cls, - jchar chUnicode) + JNIEnv *env, jclass cls, + jchar chUnicode) { - SDL_Scancode code = SDL_SCANCODE_UNKNOWN; - uint16_t mod = 0; - - /* We do not care about bigger than 127. */ - if (chUnicode < 127) { - AndroidKeyInfo info = unicharToAndroidKeyInfoTable[chUnicode]; - code = info.code; - mod = info.mod; - } - - if (mod & KMOD_SHIFT) { - /* If character uses shift, press shift down */ - SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_LSHIFT); - } - - /* send a keydown and keyup even for the character */ - SDL_SendKeyboardKey(SDL_PRESSED, code); - SDL_SendKeyboardKey(SDL_RELEASED, code); - - if (mod & KMOD_SHIFT) { - /* If character uses shift, press shift back up */ - SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LSHIFT); - } -} - -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeSetComposingText)( - JNIEnv *env, jclass cls, - jstring text, jint newCursorPosition) -{ - const char *utftext = (*env)->GetStringUTFChars(env, text, NULL); - - SDL_SendEditingText(utftext, 0, 0); - - (*env)->ReleaseStringUTFChars(env, text, utftext); + SDL_SendKeyboardUnicodeKey(chUnicode); } JNIEXPORT jstring JNICALL SDL_JAVA_INTERFACE(nativeGetHint)( - JNIEnv *env, jclass cls, - jstring name) + JNIEnv *env, jclass cls, + jstring name) { const char *utfname = (*env)->GetStringUTFChars(env, name, NULL); const char *hint = SDL_GetHint(utfname); @@ -1284,9 +1328,22 @@ JNIEXPORT jstring JNICALL SDL_JAVA_INTERFACE(nativeGetHint)( return result; } +JNIEXPORT jboolean JNICALL SDL_JAVA_INTERFACE(nativeGetHintBoolean)( + JNIEnv *env, jclass cls, + jstring name, jboolean default_value) +{ + jboolean result; + + const char *utfname = (*env)->GetStringUTFChars(env, name, NULL); + result = SDL_GetHintBoolean(utfname, default_value); + (*env)->ReleaseStringUTFChars(env, name, utfname); + + return result; +} + JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetenv)( - JNIEnv *env, jclass cls, - jstring name, jstring value) + JNIEnv *env, jclass cls, + jstring name, jstring value) { const char *utfname = (*env)->GetStringUTFChars(env, name, NULL); const char *utfvalue = (*env)->GetStringUTFChars(env, value, NULL); @@ -1295,7 +1352,6 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetenv)( (*env)->ReleaseStringUTFChars(env, name, utfname); (*env)->ReleaseStringUTFChars(env, value, utfvalue); - } /******************************************************************************* @@ -1344,7 +1400,7 @@ static void LocalReferenceHolder_Cleanup(struct LocalReferenceHolder *refholder) } } -ANativeWindow* Android_JNI_GetNativeWindow(void) +ANativeWindow *Android_JNI_GetNativeWindow(void) { ANativeWindow *anw = NULL; jobject s; @@ -1359,26 +1415,6 @@ ANativeWindow* Android_JNI_GetNativeWindow(void) return anw; } -void Android_JNI_SetSurfaceViewFormat(int format) -{ - JNIEnv *env = Android_JNI_GetEnv(); - int new_format = 0; - - /* Format from android/native_window.h, - * convert to temporary arbitrary values, - * then to java PixelFormat */ - if (format == WINDOW_FORMAT_RGBA_8888) { - new_format = 1; - } else if (format == WINDOW_FORMAT_RGBX_8888) { - new_format = 2; - } else if (format == WINDOW_FORMAT_RGB_565) { - /* Default */ - new_format = 0; - } - - (*env)->CallStaticVoidMethod(env, mActivityClass, midSetSurfaceViewFormat, new_format); -} - void Android_JNI_SetActivityTitle(const char *title) { JNIEnv *env = Android_JNI_GetEnv(); @@ -1399,7 +1435,7 @@ void Android_JNI_SetOrientation(int w, int h, int resizable, const char *hint) JNIEnv *env = Android_JNI_GetEnv(); jstring jhint = (*env)->NewStringUTF(env, (hint ? hint : "")); - (*env)->CallStaticVoidMethod(env, mActivityClass, midSetOrientation, w, h, (resizable? 1 : 0), jhint); + (*env)->CallStaticVoidMethod(env, mActivityClass, midSetOrientation, w, h, (resizable ? 1 : 0), jhint); (*env)->DeleteLocalRef(env, jhint); } @@ -1440,7 +1476,57 @@ static void *audioBufferPinned = NULL; static int captureBufferFormat = 0; static jobject captureBuffer = NULL; -int Android_JNI_OpenAudioDevice(int iscapture, SDL_AudioSpec *spec) +static void Android_JNI_GetAudioDevices(int *devices, int *length, int max_len, int is_input) +{ + JNIEnv *env = Android_JNI_GetEnv(); + jintArray result; + + if (is_input) { + result = (*env)->CallStaticObjectMethod(env, mAudioManagerClass, midGetAudioInputDevices); + } else { + result = (*env)->CallStaticObjectMethod(env, mAudioManagerClass, midGetAudioOutputDevices); + } + + *length = (*env)->GetArrayLength(env, result); + + *length = SDL_min(*length, max_len); + + (*env)->GetIntArrayRegion(env, result, 0, *length, devices); +} + +void Android_DetectDevices(void) +{ + int inputs[100]; + int outputs[100]; + int inputs_length = 0; + int outputs_length = 0; + + SDL_zeroa(inputs); + + Android_JNI_GetAudioDevices(inputs, &inputs_length, 100, 1 /* input devices */); + + for (int i = 0; i < inputs_length; ++i) { + int device_id = inputs[i]; + char device_name[64]; + SDL_snprintf(device_name, sizeof(device_name), "%d", device_id); + SDL_Log("Adding input device with name %s", device_name); + SDL_AddAudioDevice(SDL_TRUE, SDL_strdup(device_name), NULL, (void *)((size_t)device_id + 1)); + } + + SDL_zeroa(outputs); + + Android_JNI_GetAudioDevices(outputs, &outputs_length, 100, 0 /* output devices */); + + for (int i = 0; i < outputs_length; ++i) { + int device_id = outputs[i]; + char device_name[64]; + SDL_snprintf(device_name, sizeof(device_name), "%d", device_id); + SDL_Log("Adding output device with name %s", device_name); + SDL_AddAudioDevice(SDL_FALSE, SDL_strdup(device_name), NULL, (void *)((size_t)device_id + 1)); + } +} + +int Android_JNI_OpenAudioDevice(int iscapture, int device_id, SDL_AudioSpec *spec) { int audioformat; jobject jbufobj = NULL; @@ -1466,12 +1552,12 @@ int Android_JNI_OpenAudioDevice(int iscapture, SDL_AudioSpec *spec) if (iscapture) { __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device for capture"); - result = (*env)->CallStaticObjectMethod(env, mAudioManagerClass, midCaptureOpen, spec->freq, audioformat, spec->channels, spec->samples); + result = (*env)->CallStaticObjectMethod(env, mAudioManagerClass, midCaptureOpen, spec->freq, audioformat, spec->channels, spec->samples, device_id); } else { __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device for output"); - result = (*env)->CallStaticObjectMethod(env, mAudioManagerClass, midAudioOpen, spec->freq, audioformat, spec->channels, spec->samples); + result = (*env)->CallStaticObjectMethod(env, mAudioManagerClass, midAudioOpen, spec->freq, audioformat, spec->channels, spec->samples, device_id); } - if (result == NULL) { + if (!result) { /* Error during audio initialization, error printed from Java */ return SDL_SetError("Java-side initialization failed"); } @@ -1505,37 +1591,34 @@ int Android_JNI_OpenAudioDevice(int iscapture, SDL_AudioSpec *spec) * Android >= 4.2 due to a "stale global reference" error. So now we allocate this buffer directly from this side. */ switch (audioformat) { case ENCODING_PCM_8BIT: - { - jbyteArray audioBufferLocal = (*env)->NewByteArray(env, spec->samples * spec->channels); - if (audioBufferLocal) { - jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal); - (*env)->DeleteLocalRef(env, audioBufferLocal); - } + { + jbyteArray audioBufferLocal = (*env)->NewByteArray(env, spec->samples * spec->channels); + if (audioBufferLocal) { + jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal); + (*env)->DeleteLocalRef(env, audioBufferLocal); } - break; + } break; case ENCODING_PCM_16BIT: - { - jshortArray audioBufferLocal = (*env)->NewShortArray(env, spec->samples * spec->channels); - if (audioBufferLocal) { - jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal); - (*env)->DeleteLocalRef(env, audioBufferLocal); - } + { + jshortArray audioBufferLocal = (*env)->NewShortArray(env, spec->samples * spec->channels); + if (audioBufferLocal) { + jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal); + (*env)->DeleteLocalRef(env, audioBufferLocal); } - break; + } break; case ENCODING_PCM_FLOAT: - { - jfloatArray audioBufferLocal = (*env)->NewFloatArray(env, spec->samples * spec->channels); - if (audioBufferLocal) { - jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal); - (*env)->DeleteLocalRef(env, audioBufferLocal); - } + { + jfloatArray audioBufferLocal = (*env)->NewFloatArray(env, spec->samples * spec->channels); + if (audioBufferLocal) { + jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal); + (*env)->DeleteLocalRef(env, audioBufferLocal); } - break; + } break; default: return SDL_SetError("Unexpected audio format from Java: %d\n", audioformat); } - if (jbufobj == NULL) { + if (!jbufobj) { __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: could not allocate an audio buffer"); return SDL_OutOfMemory(); } @@ -1588,7 +1671,6 @@ int Android_JNI_GetDisplayDPI(float *ddpi, float *xdpi, float *ydpi) float nativeYdpi = (*env)->GetFloatField(env, jDisplayObj, fidYdpi); int nativeDdpi = (*env)->GetIntField(env, jDisplayObj, fidDdpi); - (*env)->DeleteLocalRef(env, jDisplayObj); (*env)->DeleteLocalRef(env, jDisplayClass); @@ -1605,7 +1687,7 @@ int Android_JNI_GetDisplayDPI(float *ddpi, float *xdpi, float *ydpi) return 0; } -void * Android_JNI_GetAudioBuffer(void) +void *Android_JNI_GetAudioBuffer(void) { return audioBufferPinned; } @@ -1681,7 +1763,7 @@ int Android_JNI_CaptureAudioBuffer(void *buffer, int buflen) void Android_JNI_FlushCapturedAudio(void) { JNIEnv *env = Android_JNI_GetEnv(); -#if 0 /* !!! FIXME: this needs API 23, or it'll do blocking reads and never end. */ +#if 0 /* !!! FIXME: this needs API 23, or it'll do blocking reads and never end. */ switch (captureBufferFormat) { case ENCODING_PCM_8BIT: { @@ -1797,397 +1879,122 @@ static SDL_bool Android_JNI_ExceptionOccurred(SDL_bool silent) return SDL_FALSE; } -static int Internal_Android_JNI_FileOpen(SDL_RWops *ctx) +static void Internal_Android_Create_AssetManager() { + struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__); - - int result = 0; - + JNIEnv *env = Android_JNI_GetEnv(); jmethodID mid; jobject context; - jobject assetManager; - jobject inputStream; - jclass channels; - jobject readableByteChannel; - jstring fileNameJString; - jobject fd; - jclass fdCls; - jfieldID descriptor; + jobject javaAssetManager; - JNIEnv *env = Android_JNI_GetEnv(); if (!LocalReferenceHolder_Init(&refs, env)) { - goto failure; + LocalReferenceHolder_Cleanup(&refs); + return; } - fileNameJString = (jstring)ctx->hidden.androidio.fileNameRef; - ctx->hidden.androidio.position = 0; - /* context = SDLActivity.getContext(); */ context = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetContext); - /* assetManager = context.getAssets(); */ + /* javaAssetManager = context.getAssets(); */ mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, context), - "getAssets", "()Landroid/content/res/AssetManager;"); - assetManager = (*env)->CallObjectMethod(env, context, mid); + "getAssets", "()Landroid/content/res/AssetManager;"); + javaAssetManager = (*env)->CallObjectMethod(env, context, mid); - /* First let's try opening the file to obtain an AssetFileDescriptor. - * This method reads the files directly from the APKs using standard *nix calls - */ - mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, assetManager), "openFd", "(Ljava/lang/String;)Landroid/content/res/AssetFileDescriptor;"); - inputStream = (*env)->CallObjectMethod(env, assetManager, mid, fileNameJString); - if (Android_JNI_ExceptionOccurred(SDL_TRUE)) { - goto fallback; - } - - mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, inputStream), "getStartOffset", "()J"); - ctx->hidden.androidio.offset = (long)(*env)->CallLongMethod(env, inputStream, mid); - if (Android_JNI_ExceptionOccurred(SDL_TRUE)) { - goto fallback; - } - - mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, inputStream), "getDeclaredLength", "()J"); - ctx->hidden.androidio.size = (long)(*env)->CallLongMethod(env, inputStream, mid); - if (Android_JNI_ExceptionOccurred(SDL_TRUE)) { - goto fallback; - } - - mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, inputStream), "getFileDescriptor", "()Ljava/io/FileDescriptor;"); - fd = (*env)->CallObjectMethod(env, inputStream, mid); - fdCls = (*env)->GetObjectClass(env, fd); - descriptor = (*env)->GetFieldID(env, fdCls, "descriptor", "I"); - ctx->hidden.androidio.fd = (*env)->GetIntField(env, fd, descriptor); - ctx->hidden.androidio.assetFileDescriptorRef = (*env)->NewGlobalRef(env, inputStream); - - /* Seek to the correct offset in the file. */ - lseek(ctx->hidden.androidio.fd, (off_t)ctx->hidden.androidio.offset, SEEK_SET); - - if (0) { -fallback: - /* Disabled log message because of spam on the Nexus 7 */ - /* __android_log_print(ANDROID_LOG_DEBUG, "SDL", "Falling back to legacy InputStream method for opening file"); */ - - /* Try the old method using InputStream */ - ctx->hidden.androidio.assetFileDescriptorRef = NULL; - - /* inputStream = assetManager.open(); */ - mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, assetManager), - "open", "(Ljava/lang/String;I)Ljava/io/InputStream;"); - inputStream = (*env)->CallObjectMethod(env, assetManager, mid, fileNameJString, 1 /* ACCESS_RANDOM */); - if (Android_JNI_ExceptionOccurred(SDL_FALSE)) { - /* Try fallback to APK expansion files */ - inputStream = (*env)->CallStaticObjectMethod(env, 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. - */ - if (Android_JNI_ExceptionOccurred(SDL_FALSE) || !inputStream) { - goto failure; - } - } - - ctx->hidden.androidio.inputStreamRef = (*env)->NewGlobalRef(env, inputStream); - - /* Despite all the visible documentation on [Asset]InputStream claiming - * that the .available() method is not guaranteed to return the entire file - * size, comments in /samples//ApiDemos/src/com/example/ ... - * android/apis/content/ReadAsset.java imply that Android's - * AssetInputStream.available() /will/ always return the total file size - */ - - /* size = inputStream.available(); */ - mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, inputStream), - "available", "()I"); - ctx->hidden.androidio.size = (long)(*env)->CallIntMethod(env, inputStream, mid); - if (Android_JNI_ExceptionOccurred(SDL_FALSE)) { - goto failure; - } - - /* readableByteChannel = Channels.newChannel(inputStream); */ - channels = (*env)->FindClass(env, "java/nio/channels/Channels"); - mid = (*env)->GetStaticMethodID(env, channels, - "newChannel", - "(Ljava/io/InputStream;)Ljava/nio/channels/ReadableByteChannel;"); - readableByteChannel = (*env)->CallStaticObjectMethod( - env, channels, mid, inputStream); - if (Android_JNI_ExceptionOccurred(SDL_FALSE)) { - goto failure; - } - - ctx->hidden.androidio.readableByteChannelRef = - (*env)->NewGlobalRef(env, readableByteChannel); - - /* Store .read id for reading purposes */ - mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, readableByteChannel), - "read", "(Ljava/nio/ByteBuffer;)I"); - ctx->hidden.androidio.readMethod = mid; - } - - if (0) { -failure: - result = -1; - - (*env)->DeleteGlobalRef(env, (jobject)ctx->hidden.androidio.fileNameRef); - - if(ctx->hidden.androidio.inputStreamRef != NULL) { - (*env)->DeleteGlobalRef(env, (jobject)ctx->hidden.androidio.inputStreamRef); - } - - if(ctx->hidden.androidio.readableByteChannelRef != NULL) { - (*env)->DeleteGlobalRef(env, (jobject)ctx->hidden.androidio.readableByteChannelRef); - } - - if(ctx->hidden.androidio.assetFileDescriptorRef != NULL) { - (*env)->DeleteGlobalRef(env, (jobject)ctx->hidden.androidio.assetFileDescriptorRef); - } + /** + * Given a Dalvik AssetManager object, obtain the corresponding native AAssetManager + * object. Note that the caller is responsible for obtaining and holding a VM reference + * to the jobject to prevent its being garbage collected while the native object is + * in use. + */ + javaAssetManagerRef = (*env)->NewGlobalRef(env, javaAssetManager); + asset_manager = AAssetManager_fromJava(env, javaAssetManagerRef); + if (!asset_manager) { + (*env)->DeleteGlobalRef(env, javaAssetManagerRef); + Android_JNI_ExceptionOccurred(SDL_TRUE); } LocalReferenceHolder_Cleanup(&refs); - return result; +} + +static void Internal_Android_Destroy_AssetManager() +{ + JNIEnv *env = Android_JNI_GetEnv(); + + if (asset_manager) { + (*env)->DeleteGlobalRef(env, javaAssetManagerRef); + asset_manager = NULL; + } } int Android_JNI_FileOpen(SDL_RWops *ctx, - const char *fileName, const char *mode) + const char *fileName, const char *mode) { - struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__); - JNIEnv *env = Android_JNI_GetEnv(); - int retval; - jstring fileNameJString; + AAsset *asset = NULL; + ctx->hidden.androidio.asset = NULL; - if (!LocalReferenceHolder_Init(&refs, env)) { - LocalReferenceHolder_Cleanup(&refs); - return -1; + if (!asset_manager) { + Internal_Android_Create_AssetManager(); } - if (!ctx) { - LocalReferenceHolder_Cleanup(&refs); - return -1; + if (!asset_manager) { + return SDL_SetError("Couldn't create asset manager"); } - fileNameJString = (*env)->NewStringUTF(env, fileName); - ctx->hidden.androidio.fileNameRef = (*env)->NewGlobalRef(env, fileNameJString); - ctx->hidden.androidio.inputStreamRef = NULL; - ctx->hidden.androidio.readableByteChannelRef = NULL; - ctx->hidden.androidio.readMethod = NULL; - ctx->hidden.androidio.assetFileDescriptorRef = NULL; + asset = AAssetManager_open(asset_manager, fileName, AASSET_MODE_UNKNOWN); + if (!asset) { + return SDL_SetError("Couldn't open asset '%s'", fileName); + } - retval = Internal_Android_JNI_FileOpen(ctx); - LocalReferenceHolder_Cleanup(&refs); - return retval; + ctx->hidden.androidio.asset = (void *)asset; + return 0; } size_t Android_JNI_FileRead(SDL_RWops *ctx, void *buffer, - size_t size, size_t maxnum) + size_t size, size_t maxnum) { - struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__); + size_t result; + AAsset *asset = (AAsset *)ctx->hidden.androidio.asset; + result = AAsset_read(asset, buffer, size * maxnum); - if (ctx->hidden.androidio.assetFileDescriptorRef) { - size_t bytesMax = size * maxnum; - size_t result; - if (ctx->hidden.androidio.size != -1 /* UNKNOWN_LENGTH */ && ctx->hidden.androidio.position + bytesMax > ctx->hidden.androidio.size) { - bytesMax = ctx->hidden.androidio.size - ctx->hidden.androidio.position; - } - result = read(ctx->hidden.androidio.fd, buffer, bytesMax ); - if (result > 0) { - ctx->hidden.androidio.position += result; - LocalReferenceHolder_Cleanup(&refs); - return result / size; - } - LocalReferenceHolder_Cleanup(&refs); - return 0; + if (result > 0) { + /* Number of chuncks */ + return result / size; } else { - jlong bytesRemaining = (jlong) (size * maxnum); - jlong bytesMax = (jlong) (ctx->hidden.androidio.size - ctx->hidden.androidio.position); - int bytesRead = 0; - JNIEnv *env; - jobject readableByteChannel; - jmethodID readMethod; - jobject byteBuffer; - - /* Don't read more bytes than those that remain in the file, otherwise we get an exception */ - if (bytesRemaining > bytesMax) bytesRemaining = bytesMax; - - env = Android_JNI_GetEnv(); - if (!LocalReferenceHolder_Init(&refs, env)) { - LocalReferenceHolder_Cleanup(&refs); - return 0; - } - - readableByteChannel = (jobject)ctx->hidden.androidio.readableByteChannelRef; - readMethod = (jmethodID)ctx->hidden.androidio.readMethod; - byteBuffer = (*env)->NewDirectByteBuffer(env, buffer, bytesRemaining); - - while (bytesRemaining > 0) { - /* result = readableByteChannel.read(...); */ - int result = (*env)->CallIntMethod(env, readableByteChannel, readMethod, byteBuffer); - - if (Android_JNI_ExceptionOccurred(SDL_FALSE)) { - LocalReferenceHolder_Cleanup(&refs); - return 0; - } - - if (result < 0) { - break; - } - - bytesRemaining -= result; - bytesRead += result; - ctx->hidden.androidio.position += result; - } - LocalReferenceHolder_Cleanup(&refs); - return bytesRead / size; + /* Error or EOF */ + return result; } } size_t Android_JNI_FileWrite(SDL_RWops *ctx, const void *buffer, - size_t size, size_t num) + size_t size, size_t num) { SDL_SetError("Cannot write to Android package filesystem"); return 0; } -static int Internal_Android_JNI_FileClose(SDL_RWops *ctx, SDL_bool release) -{ - struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__); - - int result = 0; - JNIEnv *env = Android_JNI_GetEnv(); - - if (!LocalReferenceHolder_Init(&refs, env)) { - LocalReferenceHolder_Cleanup(&refs); - return SDL_SetError("Failed to allocate enough JVM local references"); - } - - if (ctx) { - if (release) { - (*env)->DeleteGlobalRef(env, (jobject)ctx->hidden.androidio.fileNameRef); - } - - if (ctx->hidden.androidio.assetFileDescriptorRef) { - jobject inputStream = (jobject)ctx->hidden.androidio.assetFileDescriptorRef; - jmethodID mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, inputStream), - "close", "()V"); - (*env)->CallVoidMethod(env, inputStream, mid); - (*env)->DeleteGlobalRef(env, (jobject)ctx->hidden.androidio.assetFileDescriptorRef); - if (Android_JNI_ExceptionOccurred(SDL_FALSE)) { - result = -1; - } - } - else { - jobject inputStream = (jobject)ctx->hidden.androidio.inputStreamRef; - - /* inputStream.close(); */ - jmethodID mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, inputStream), - "close", "()V"); - (*env)->CallVoidMethod(env, inputStream, mid); - (*env)->DeleteGlobalRef(env, (jobject)ctx->hidden.androidio.inputStreamRef); - (*env)->DeleteGlobalRef(env, (jobject)ctx->hidden.androidio.readableByteChannelRef); - if (Android_JNI_ExceptionOccurred(SDL_FALSE)) { - result = -1; - } - } - - if (release) { - SDL_FreeRW(ctx); - } - } - - LocalReferenceHolder_Cleanup(&refs); - return result; -} - - Sint64 Android_JNI_FileSize(SDL_RWops *ctx) { - return ctx->hidden.androidio.size; + off64_t result; + AAsset *asset = (AAsset *)ctx->hidden.androidio.asset; + result = AAsset_getLength64(asset); + return result; } Sint64 Android_JNI_FileSeek(SDL_RWops *ctx, Sint64 offset, int whence) { - if (ctx->hidden.androidio.assetFileDescriptorRef) { - off_t ret; - switch (whence) { - case RW_SEEK_SET: - if (ctx->hidden.androidio.size != -1 /* UNKNOWN_LENGTH */ && offset > ctx->hidden.androidio.size) offset = ctx->hidden.androidio.size; - offset += ctx->hidden.androidio.offset; - break; - case RW_SEEK_CUR: - offset += ctx->hidden.androidio.position; - if (ctx->hidden.androidio.size != -1 /* UNKNOWN_LENGTH */ && offset > ctx->hidden.androidio.size) offset = ctx->hidden.androidio.size; - offset += ctx->hidden.androidio.offset; - break; - case RW_SEEK_END: - offset = ctx->hidden.androidio.offset + ctx->hidden.androidio.size + offset; - break; - default: - return SDL_SetError("Unknown value for 'whence'"); - } - - ret = lseek(ctx->hidden.androidio.fd, (off_t)offset, SEEK_SET); - if (ret == -1) return -1; - ctx->hidden.androidio.position = ret - ctx->hidden.androidio.offset; - } else { - Sint64 newPosition; - Sint64 movement; - - switch (whence) { - case RW_SEEK_SET: - newPosition = offset; - break; - case RW_SEEK_CUR: - newPosition = ctx->hidden.androidio.position + offset; - break; - case RW_SEEK_END: - newPosition = ctx->hidden.androidio.size + offset; - break; - default: - return SDL_SetError("Unknown value for 'whence'"); - } - - /* Validate the new position */ - if (newPosition < 0) { - return SDL_Error(SDL_EFSEEK); - } - if (newPosition > ctx->hidden.androidio.size) { - newPosition = ctx->hidden.androidio.size; - } - - movement = newPosition - ctx->hidden.androidio.position; - if (movement > 0) { - unsigned char buffer[4096]; - - /* The easy case where we're seeking forwards */ - while (movement > 0) { - Sint64 amount = sizeof (buffer); - size_t result; - if (amount > movement) { - amount = movement; - } - result = Android_JNI_FileRead(ctx, buffer, 1, (size_t)amount); - if (result <= 0) { - /* Failed to read/skip the required amount, so fail */ - return -1; - } - - movement -= result; - } - - } else if (movement < 0) { - /* We can't seek backwards so we have to reopen the file and seek */ - /* forwards which obviously isn't very efficient */ - Internal_Android_JNI_FileClose(ctx, SDL_FALSE); - Internal_Android_JNI_FileOpen(ctx); - Android_JNI_FileSeek(ctx, newPosition, RW_SEEK_SET); - } - } - - return ctx->hidden.androidio.position; - + off64_t result; + AAsset *asset = (AAsset *)ctx->hidden.androidio.asset; + result = AAsset_seek64(asset, offset, whence); + return result; } int Android_JNI_FileClose(SDL_RWops *ctx) { - return Internal_Android_JNI_FileClose(ctx, SDL_TRUE); + AAsset *asset = (AAsset *)ctx->hidden.androidio.asset; + AAsset_close(asset); + return 0; } int Android_JNI_SetClipboardText(const char *text) @@ -2199,7 +2006,7 @@ int Android_JNI_SetClipboardText(const char *text) return 0; } -char* Android_JNI_GetClipboardText(void) +char *Android_JNI_GetClipboardText(void) { JNIEnv *env = Android_JNI_GetEnv(); char *text = NULL; @@ -2215,7 +2022,7 @@ char* Android_JNI_GetClipboardText(void) (*env)->DeleteLocalRef(env, string); } - return (text == NULL) ? SDL_strdup("") : text; + return (!text) ? SDL_strdup("") : text; } SDL_bool Android_JNI_HasClipboardText(void) @@ -2248,7 +2055,6 @@ int Android_JNI_GetPowerInfo(int *plugged, int *charged, int *battery, int *seco return -1; } - /* context = SDLActivity.getContext(); */ context = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetContext); @@ -2271,18 +2077,18 @@ int Android_JNI_GetPowerInfo(int *plugged, int *charged, int *battery, int *seco imid = (*env)->GetMethodID(env, cls, "getIntExtra", "(Ljava/lang/String;I)I"); /* Watch out for C89 scoping rules because of the macro */ -#define GET_INT_EXTRA(var, key) \ - int var; \ - iname = (*env)->NewStringUTF(env, key); \ +#define GET_INT_EXTRA(var, key) \ + int var; \ + iname = (*env)->NewStringUTF(env, key); \ (var) = (*env)->CallIntMethod(env, intent, imid, iname, -1); \ (*env)->DeleteLocalRef(env, iname); bmid = (*env)->GetMethodID(env, cls, "getBooleanExtra", "(Ljava/lang/String;Z)Z"); /* Watch out for C89 scoping rules because of the macro */ -#define GET_BOOL_EXTRA(var, key) \ - int var; \ - bname = (*env)->NewStringUTF(env, key); \ +#define GET_BOOL_EXTRA(var, key) \ + int var; \ + bname = (*env)->NewStringUTF(env, key); \ (var) = (*env)->CallBooleanMethod(env, intent, bmid, bname, JNI_FALSE); \ (*env)->DeleteLocalRef(env, bname); @@ -2347,8 +2153,9 @@ int Android_JNI_GetPowerInfo(int *plugged, int *charged, int *battery, int *seco } /* Add all touch devices */ -void Android_JNI_InitTouch() { - JNIEnv *env = Android_JNI_GetEnv(); +void Android_JNI_InitTouch() +{ + JNIEnv *env = Android_JNI_GetEnv(); (*env)->CallStaticVoidMethod(env, mActivityClass, midInitTouch); } @@ -2377,7 +2184,15 @@ void Android_JNI_HapticStop(int device_id) } /* See SDLActivity.java for constants. */ -#define COMMAND_SET_KEEP_SCREEN_ON 5 +#define COMMAND_SET_KEEP_SCREEN_ON 5 + +int SDL_AndroidSendMessage(Uint32 command, int param) +{ + if (command >= 0x8000) { + return Android_JNI_SendMessage(command, param); + } + return -1; +} /* sends message to be handled on the UI event dispatch thread */ int Android_JNI_SendMessage(int command, int param) @@ -2393,17 +2208,17 @@ void Android_JNI_SuspendScreenSaver(SDL_bool suspend) Android_JNI_SendMessage(COMMAND_SET_KEEP_SCREEN_ON, (suspend == SDL_FALSE) ? 0 : 1); } -void Android_JNI_ShowTextInput(SDL_Rect *inputRect) +void Android_JNI_ShowScreenKeyboard(SDL_Rect *inputRect) { JNIEnv *env = Android_JNI_GetEnv(); (*env)->CallStaticBooleanMethod(env, mActivityClass, midShowTextInput, - inputRect->x, - inputRect->y, - inputRect->w, - inputRect->h ); + inputRect->x, + inputRect->y, + inputRect->w, + inputRect->h); } -void Android_JNI_HideTextInput(void) +void Android_JNI_HideScreenKeyboard(void) { /* has to match Activity constant */ const int COMMAND_TEXTEDIT_HIDE = 3; @@ -2418,7 +2233,6 @@ SDL_bool Android_JNI_IsScreenKeyboardShown(void) return is_shown; } - int Android_JNI_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) { JNIEnv *env; @@ -2447,7 +2261,7 @@ int Android_JNI_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *bu button_flags = (*env)->NewIntArray(env, messageboxdata->numbuttons); button_ids = (*env)->NewIntArray(env, messageboxdata->numbuttons); button_texts = (*env)->NewObjectArray(env, messageboxdata->numbuttons, - clazz, NULL); + clazz, NULL); for (i = 0; i < messageboxdata->numbuttons; ++i) { const SDL_MessageBoxButtonData *sdlButton; @@ -2487,15 +2301,15 @@ int Android_JNI_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *bu clazz = (*env)->GetObjectClass(env, context); mid = (*env)->GetMethodID(env, clazz, - "messageboxShowMessageBox", "(ILjava/lang/String;Ljava/lang/String;[I[I[Ljava/lang/String;[I)I"); + "messageboxShowMessageBox", "(ILjava/lang/String;Ljava/lang/String;[I[I[Ljava/lang/String;[I)I"); *buttonid = (*env)->CallIntMethod(env, context, mid, - messageboxdata->flags, - title, - message, - button_flags, - button_ids, - button_texts, - colors); + messageboxdata->flags, + title, + message, + button_flags, + button_ids, + button_texts, + colors); (*env)->DeleteLocalRef(env, context); (*env)->DeleteLocalRef(env, clazz); @@ -2541,7 +2355,7 @@ int SDL_GetAndroidSDKVersion(void) { static int sdk_version; if (!sdk_version) { - char sdk[PROP_VALUE_MAX] = {0}; + char sdk[PROP_VALUE_MAX] = { 0 }; if (__system_property_get("ro.build.version.sdk", sdk) != 0) { sdk_version = SDL_atoi(sdk); } @@ -2579,7 +2393,7 @@ void SDL_AndroidBackButton(void) (*env)->CallStaticVoidMethod(env, mActivityClass, midManualBackButton); } -const char * SDL_AndroidGetInternalStoragePath(void) +const char *SDL_AndroidGetInternalStoragePath(void) { static char *s_AndroidInternalFilesPath = NULL; @@ -2607,7 +2421,7 @@ const char * SDL_AndroidGetInternalStoragePath(void) /* fileObj = context.getFilesDir(); */ mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, context), - "getFilesDir", "()Ljava/io/File;"); + "getFilesDir", "()Ljava/io/File;"); fileObject = (*env)->CallObjectMethod(env, context, mid); if (!fileObject) { SDL_SetError("Couldn't get internal directory"); @@ -2617,7 +2431,7 @@ const char * SDL_AndroidGetInternalStoragePath(void) /* path = fileObject.getCanonicalPath(); */ mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, fileObject), - "getCanonicalPath", "()Ljava/lang/String;"); + "getCanonicalPath", "()Ljava/lang/String;"); pathString = (jstring)(*env)->CallObjectMethod(env, fileObject, mid); if (Android_JNI_ExceptionOccurred(SDL_FALSE)) { LocalReferenceHolder_Cleanup(&refs); @@ -2650,7 +2464,7 @@ int SDL_AndroidGetExternalStorageState(void) cls = (*env)->FindClass(env, "android/os/Environment"); mid = (*env)->GetStaticMethodID(env, cls, - "getExternalStorageState", "()Ljava/lang/String;"); + "getExternalStorageState", "()Ljava/lang/String;"); stateString = (jstring)(*env)->CallStaticObjectMethod(env, cls, mid); state = (*env)->GetStringUTFChars(env, stateString, NULL); @@ -2672,7 +2486,7 @@ int SDL_AndroidGetExternalStorageState(void) return stateFlags; } -const char * SDL_AndroidGetExternalStoragePath(void) +const char *SDL_AndroidGetExternalStoragePath(void) { static char *s_AndroidExternalFilesPath = NULL; @@ -2695,7 +2509,7 @@ const char * SDL_AndroidGetExternalStoragePath(void) /* fileObj = context.getExternalFilesDir(); */ mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, context), - "getExternalFilesDir", "(Ljava/lang/String;)Ljava/io/File;"); + "getExternalFilesDir", "(Ljava/lang/String;)Ljava/io/File;"); fileObject = (*env)->CallObjectMethod(env, context, mid, NULL); if (!fileObject) { SDL_SetError("Couldn't get external directory"); @@ -2705,7 +2519,7 @@ const char * SDL_AndroidGetExternalStoragePath(void) /* path = fileObject.getAbsolutePath(); */ mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, fileObject), - "getAbsolutePath", "()Ljava/lang/String;"); + "getAbsolutePath", "()Ljava/lang/String;"); pathString = (jstring)(*env)->CallObjectMethod(env, fileObject, mid); path = (*env)->GetStringUTFChars(env, pathString, NULL); @@ -2717,6 +2531,16 @@ const char * SDL_AndroidGetExternalStoragePath(void) return s_AndroidExternalFilesPath; } +SDL_bool SDL_AndroidRequestPermission(const char *permission) +{ + return Android_JNI_RequestPermission(permission); +} + +int SDL_AndroidShowToast(const char *message, int duration, int gravity, int xOffset, int yOffset) +{ + return Android_JNI_ShowToast(message, duration, gravity, xOffset, yOffset); +} + void Android_JNI_GetManifestEnvironmentVariables(void) { if (!mActivityClass || !midGetManifestEnvironmentVariables) { @@ -2749,6 +2573,11 @@ int Android_JNI_CreateCustomCursor(SDL_Surface *surface, int hot_x, int hot_y) return custom_cursor; } +void Android_JNI_DestroyCustomCursor(int cursorID) +{ + JNIEnv *env = Android_JNI_GetEnv(); + (*env)->CallStaticVoidMethod(env, mActivityClass, midDestroyCustomCursor, cursorID); +} SDL_bool Android_JNI_SetCustomCursor(int cursorID) { @@ -2777,23 +2606,102 @@ SDL_bool Android_JNI_SetRelativeMouseEnabled(SDL_bool enabled) SDL_bool Android_JNI_RequestPermission(const char *permission) { JNIEnv *env = Android_JNI_GetEnv(); - const int requestCode = 1; + jstring jpermission; + const int requestCode = 1; - /* Wait for any pending request on another thread */ - while (SDL_AtomicGet(&bPermissionRequestPending) == SDL_TRUE) { - SDL_Delay(10); - } - SDL_AtomicSet(&bPermissionRequestPending, SDL_TRUE); + /* Wait for any pending request on another thread */ + while (SDL_AtomicGet(&bPermissionRequestPending) == SDL_TRUE) { + SDL_Delay(10); + } + SDL_AtomicSet(&bPermissionRequestPending, SDL_TRUE); - jstring jpermission = (*env)->NewStringUTF(env, permission); + jpermission = (*env)->NewStringUTF(env, permission); (*env)->CallStaticVoidMethod(env, mActivityClass, midRequestPermission, jpermission, requestCode); (*env)->DeleteLocalRef(env, jpermission); - /* Wait for the request to complete */ - while (SDL_AtomicGet(&bPermissionRequestPending) == SDL_TRUE) { - SDL_Delay(10); - } - return bPermissionRequestResult; + /* Wait for the request to complete */ + while (SDL_AtomicGet(&bPermissionRequestPending) == SDL_TRUE) { + SDL_Delay(10); + } + return bPermissionRequestResult; +} + +/* Show toast notification */ +int Android_JNI_ShowToast(const char *message, int duration, int gravity, int xOffset, int yOffset) +{ + int result = 0; + JNIEnv *env = Android_JNI_GetEnv(); + jstring jmessage = (*env)->NewStringUTF(env, message); + result = (*env)->CallStaticIntMethod(env, mActivityClass, midShowToast, jmessage, duration, gravity, xOffset, yOffset); + (*env)->DeleteLocalRef(env, jmessage); + return result; +} + +int Android_JNI_GetLocale(char *buf, size_t buflen) +{ + AConfiguration *cfg; + + SDL_assert(buflen > 6); + + /* Need to re-create the asset manager if locale has changed (SDL_LOCALECHANGED) */ + Internal_Android_Destroy_AssetManager(); + + if (!asset_manager) { + Internal_Android_Create_AssetManager(); + } + + if (!asset_manager) { + return -1; + } + + cfg = AConfiguration_new(); + if (!cfg) { + return -1; + } + + { + char language[2] = {}; + char country[2] = {}; + size_t id = 0; + + AConfiguration_fromAssetManager(cfg, asset_manager); + AConfiguration_getLanguage(cfg, language); + AConfiguration_getCountry(cfg, country); + + /* copy language (not null terminated) */ + if (language[0]) { + buf[id++] = language[0]; + if (language[1]) { + buf[id++] = language[1]; + } + } + + buf[id++] = '_'; + + /* copy country (not null terminated) */ + if (country[0]) { + buf[id++] = country[0]; + if (country[1]) { + buf[id++] = country[1]; + } + } + + buf[id++] = '\0'; + SDL_assert(id <= buflen); + } + + AConfiguration_delete(cfg); + + return 0; +} + +int Android_JNI_OpenURL(const char *url) +{ + JNIEnv *env = Android_JNI_GetEnv(); + jstring jurl = (*env)->NewStringUTF(env, url); + const int ret = (*env)->CallStaticIntMethod(env, mActivityClass, midOpenURL, jurl); + (*env)->DeleteLocalRef(env, jurl); + return ret; } #endif /* __ANDROID__ */ diff --git a/SDL2-2.0.12/src/core/android/SDL_android.h b/SDL2-2.30.5/src/core/android/SDL_android.h similarity index 82% rename from SDL2-2.0.12/src/core/android/SDL_android.h rename to SDL2-2.30.5/src/core/android/SDL_android.h index 9f3f3cc..20d1fc5 100644 --- a/SDL2-2.0.12/src/core/android/SDL_android.h +++ b/SDL2-2.30.5/src/core/android/SDL_android.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -43,18 +43,18 @@ extern void Android_JNI_MinizeWindow(void); extern SDL_bool Android_JNI_ShouldMinimizeOnFocusLoss(void); extern SDL_bool Android_JNI_GetAccelerometerValues(float values[3]); -extern void Android_JNI_ShowTextInput(SDL_Rect *inputRect); -extern void Android_JNI_HideTextInput(void); +extern void Android_JNI_ShowScreenKeyboard(SDL_Rect *inputRect); +extern void Android_JNI_HideScreenKeyboard(void); extern SDL_bool Android_JNI_IsScreenKeyboardShown(void); -extern ANativeWindow* Android_JNI_GetNativeWindow(void); -extern void Android_JNI_SetSurfaceViewFormat(int format); +extern ANativeWindow *Android_JNI_GetNativeWindow(void); extern SDL_DisplayOrientation Android_JNI_GetDisplayOrientation(void); extern int Android_JNI_GetDisplayDPI(float *ddpi, float *xdpi, float *ydpi); /* Audio support */ -extern int Android_JNI_OpenAudioDevice(int iscapture, SDL_AudioSpec *spec); -extern void* Android_JNI_GetAudioBuffer(void); +extern void Android_DetectDevices(void); +extern int Android_JNI_OpenAudioDevice(int iscapture, int device_id, SDL_AudioSpec *spec); +extern void *Android_JNI_GetAudioBuffer(void); extern void Android_JNI_WriteAudioBuffer(void); extern int Android_JNI_CaptureAudioBuffer(void *buffer, int buflen); extern void Android_JNI_FlushCapturedAudio(void); @@ -78,12 +78,12 @@ int Android_JNI_FileClose(SDL_RWops* ctx); void Android_JNI_GetManifestEnvironmentVariables(void); /* Clipboard support */ -int Android_JNI_SetClipboardText(const char* text); -char* Android_JNI_GetClipboardText(void); +int Android_JNI_SetClipboardText(const char *text); +char *Android_JNI_GetClipboardText(void); SDL_bool Android_JNI_HasClipboardText(void); /* Power support */ -int Android_JNI_GetPowerInfo(int* plugged, int* charged, int* battery, int* seconds, int* percent); +int Android_JNI_GetPowerInfo(int *plugged, int *charged, int *battery, int *seconds, int *percent); /* Joystick support */ void Android_JNI_PollInputDevices(void); @@ -104,11 +104,14 @@ void Android_JNI_InitTouch(void); JNIEnv *Android_JNI_GetEnv(void); int Android_JNI_SetupThread(void); +/* Locale */ +int Android_JNI_GetLocale(char *buf, size_t buflen); + /* Generic messages */ int Android_JNI_SendMessage(int command, int param); /* Init */ -JNIEXPORT void JNICALL SDL_Android_Init(JNIEnv* mEnv, jclass cls); +JNIEXPORT void JNICALL SDL_Android_Init(JNIEnv *mEnv, jclass cls); /* MessageBox */ #include "SDL_messagebox.h" @@ -116,6 +119,7 @@ int Android_JNI_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *bu /* Cursor support */ int Android_JNI_CreateCustomCursor(SDL_Surface *surface, int hot_x, int hot_y); +void Android_JNI_DestroyCustomCursor(int cursorID); SDL_bool Android_JNI_SetCustomCursor(int cursorID); SDL_bool Android_JNI_SetSystemCursor(int cursorID); @@ -126,6 +130,11 @@ SDL_bool Android_JNI_SetRelativeMouseEnabled(SDL_bool enabled); /* Request permission */ SDL_bool Android_JNI_RequestPermission(const char *permission); +/* Show toast notification */ +int Android_JNI_ShowToast(const char *message, int duration, int gravity, int xOffset, int yOffset); + +int Android_JNI_OpenURL(const char *url); + int SDL_GetAndroidSDKVersion(void); SDL_bool SDL_IsAndroidTablet(void); diff --git a/SDL2-2.30.5/src/core/freebsd/SDL_evdev_kbd_default_keyaccmap.h b/SDL2-2.30.5/src/core/freebsd/SDL_evdev_kbd_default_keyaccmap.h new file mode 100644 index 0000000..8cb7430 --- /dev/null +++ b/SDL2-2.30.5/src/core/freebsd/SDL_evdev_kbd_default_keyaccmap.h @@ -0,0 +1,167 @@ +#include + +/* *INDENT-OFF* */ /* clang-format off */ +/* + * Automatically generated from /usr/share/vt/keymaps/us.acc.kbd. + * DO NOT EDIT! + */ +static keymap_t keymap_default_us_acc = { 0x6d, { +/* alt + * scan cntrl alt alt cntrl + * code base shift cntrl shift alt shift cntrl shift spcl flgs + * --------------------------------------------------------------------------- + */ +/*00*/{{ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, }, 0xFF,0x00 }, +/*01*/{{ 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, DBG, DBG, }, 0x03,0x00 }, +/*02*/{{ '1', '!', NOP, NOP, '1', '!', NOP, NOP, }, 0x33,0x00 }, +/*03*/{{ '2', '@', 0x00, 0x00, '2', '@', 0x00, 0x00, }, 0x00,0x00 }, +/*04*/{{ '3', '#', NOP, NOP, '3', '#', NOP, NOP, }, 0x33,0x00 }, +/*05*/{{ '4', '$', NOP, NOP, '4', '$', NOP, NOP, }, 0x33,0x00 }, +/*06*/{{ '5', '%', NOP, NOP, '5', '%', NOP, NOP, }, 0x33,0x00 }, +/*07*/{{ '6', '^', 0x1E, 0x1E, '6', DCIR, 0x1E, 0x1E, }, 0x04,0x00 }, +/*08*/{{ '7', '&', NOP, NOP, '7', '&', NOP, NOP, }, 0x33,0x00 }, +/*09*/{{ '8', '*', NOP, NOP, '8', DRIN, NOP, NOP, }, 0x37,0x00 }, +/*0a*/{{ '9', '(', NOP, NOP, '9', '(', NOP, NOP, }, 0x33,0x00 }, +/*0b*/{{ '0', ')', NOP, NOP, '0', ')', NOP, NOP, }, 0x33,0x00 }, +/*0c*/{{ '-', '_', 0x1F, 0x1F, '-', '_', 0x1F, 0x1F, }, 0x00,0x00 }, +/*0d*/{{ '=', '+', NOP, NOP, '=', '+', NOP, NOP, }, 0x33,0x00 }, +/*0e*/{{ 0x08, 0x08, 0x7F, 0x7F, 0x08, 0x08, 0x7F, 0x7F, }, 0x00,0x00 }, +/*0f*/{{ 0x09, BTAB, NEXT, NEXT, 0x09, BTAB, NOP, NOP, }, 0x77,0x00 }, +/*10*/{{ 'q', 'Q', 0x11, 0x11, 'q', 'Q', 0x11, 0x11, }, 0x00,0x01 }, +/*11*/{{ 'w', 'W', 0x17, 0x17, 'w', 'W', 0x17, 0x17, }, 0x00,0x01 }, +/*12*/{{ 'e', 'E', 0x05, 0x05, 'e', 'E', 0x05, 0x05, }, 0x00,0x01 }, +/*13*/{{ 'r', 'R', 0x12, 0x12, 'r', 'R', 0x12, 0x12, }, 0x00,0x01 }, +/*14*/{{ 't', 'T', 0x14, 0x14, 't', 'T', 0x14, 0x14, }, 0x00,0x01 }, +/*15*/{{ 'y', 'Y', 0x19, 0x19, 'y', 'Y', 0x19, 0x19, }, 0x00,0x01 }, +/*16*/{{ 'u', 'U', 0x15, 0x15, 'u', 'U', 0x15, 0x15, }, 0x00,0x01 }, +/*17*/{{ 'i', 'I', 0x09, 0x09, 'i', 'I', 0x09, 0x09, }, 0x00,0x01 }, +/*18*/{{ 'o', 'O', 0x0F, 0x0F, 'o', 'O', 0x0F, 0x0F, }, 0x00,0x01 }, +/*19*/{{ 'p', 'P', 0x10, 0x10, 'p', 'P', 0x10, 0x10, }, 0x00,0x01 }, +/*1a*/{{ '[', '{', 0x1B, 0x1B, '[', '{', 0x1B, 0x1B, }, 0x00,0x00 }, +/*1b*/{{ ']', '}', 0x1D, 0x1D, ']', '}', 0x1D, 0x1D, }, 0x00,0x00 }, +/*1c*/{{ 0x0D, 0x0D, 0x0A, 0x0A, 0x0D, 0x0D, 0x0A, 0x0A, }, 0x00,0x00 }, +/*1d*/{{ LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, }, 0xFF,0x00 }, +/*1e*/{{ 'a', 'A', 0x01, 0x01, 'a', 'A', 0x01, 0x01, }, 0x00,0x01 }, +/*1f*/{{ 's', 'S', 0x13, 0x13, 's', 'S', 0x13, 0x13, }, 0x00,0x01 }, +/*20*/{{ 'd', 'D', 0x04, 0x04, 'd', 'D', 0x04, 0x04, }, 0x00,0x01 }, +/*21*/{{ 'f', 'F', 0x06, 0x06, 'f', 'F', 0x06, 0x06, }, 0x00,0x01 }, +/*22*/{{ 'g', 'G', 0x07, 0x07, 'g', 'G', 0x07, 0x07, }, 0x00,0x01 }, +/*23*/{{ 'h', 'H', 0x08, 0x08, 'h', 'H', 0x08, 0x08, }, 0x00,0x01 }, +/*24*/{{ 'j', 'J', 0x0A, 0x0A, 'j', 'J', 0x0A, 0x0A, }, 0x00,0x01 }, +/*25*/{{ 'k', 'K', 0x0B, 0x0B, 'k', 'K', 0x0B, 0x0B, }, 0x00,0x01 }, +/*26*/{{ 'l', 'L', 0x0C, 0x0C, 'l', 'L', 0x0C, 0x0C, }, 0x00,0x01 }, +/*27*/{{ ';', ':', NOP, NOP, ';', ':', NOP, NOP, }, 0x33,0x00 }, +/*28*/{{ '\'', '"', NOP, NOP, DACU, DUML, NOP, NOP, }, 0x3F,0x00 }, +/*29*/{{ '`', '~', NOP, NOP, DGRA, DTIL, NOP, NOP, }, 0x3F,0x00 }, +/*2a*/{{ LSH, LSH, LSH, LSH, LSH, LSH, LSH, LSH, }, 0xFF,0x00 }, +/*2b*/{{ '\\', '|', 0x1C, 0x1C, '\\', '|', 0x1C, 0x1C, }, 0x00,0x00 }, +/*2c*/{{ 'z', 'Z', 0x1A, 0x1A, 'z', 'Z', 0x1A, 0x1A, }, 0x00,0x01 }, +/*2d*/{{ 'x', 'X', 0x18, 0x18, 'x', 'X', 0x18, 0x18, }, 0x00,0x01 }, +/*2e*/{{ 'c', 'C', 0x03, 0x03, 'c', 'C', 0x03, 0x03, }, 0x00,0x01 }, +/*2f*/{{ 'v', 'V', 0x16, 0x16, 'v', 'V', 0x16, 0x16, }, 0x00,0x01 }, +/*30*/{{ 'b', 'B', 0x02, 0x02, 'b', 'B', 0x02, 0x02, }, 0x00,0x01 }, +/*31*/{{ 'n', 'N', 0x0E, 0x0E, 'n', 'N', 0x0E, 0x0E, }, 0x00,0x01 }, +/*32*/{{ 'm', 'M', 0x0D, 0x0D, 'm', 'M', 0x0D, 0x0D, }, 0x00,0x01 }, +/*33*/{{ ',', '<', NOP, NOP, DCED, '<', NOP, NOP, }, 0x3B,0x00 }, +/*34*/{{ '.', '>', NOP, NOP, '.', '>', NOP, NOP, }, 0x33,0x00 }, +/*35*/{{ '/', '?', NOP, NOP, '/', '?', NOP, NOP, }, 0x33,0x00 }, +/*36*/{{ RSH, RSH, RSH, RSH, RSH, RSH, RSH, RSH, }, 0xFF,0x00 }, +/*37*/{{ '*', '*', '*', '*', '*', '*', '*', '*', }, 0x00,0x00 }, +/*38*/{{ LALT, LALT, LALT, LALT, LALT, LALT, LALT, LALT, }, 0xFF,0x00 }, +/*39*/{{ ' ', ' ', 0x00, 0x00, ' ', ' ', SUSP, SUSP, }, 0x03,0x00 }, +/*3a*/{{ CLK, CLK, CLK, CLK, CLK, CLK, CLK, CLK, }, 0xFF,0x00 }, +/*3b*/{{ F( 1), F(13), F(25), F(37), S( 1), S(11), S( 1), S(11),}, 0xFF,0x00 }, +/*3c*/{{ F( 2), F(14), F(26), F(38), S( 2), S(12), S( 2), S(12),}, 0xFF,0x00 }, +/*3d*/{{ F( 3), F(15), F(27), F(39), S( 3), S(13), S( 3), S(13),}, 0xFF,0x00 }, +/*3e*/{{ F( 4), F(16), F(28), F(40), S( 4), S(14), S( 4), S(14),}, 0xFF,0x00 }, +/*3f*/{{ F( 5), F(17), F(29), F(41), S( 5), S(15), S( 5), S(15),}, 0xFF,0x00 }, +/*40*/{{ F( 6), F(18), F(30), F(42), S( 6), S(16), S( 6), S(16),}, 0xFF,0x00 }, +/*41*/{{ F( 7), F(19), F(31), F(43), S( 7), S( 7), S( 7), S( 7),}, 0xFF,0x00 }, +/*42*/{{ F( 8), F(20), F(32), F(44), S( 8), S( 8), S( 8), S( 8),}, 0xFF,0x00 }, +/*43*/{{ F( 9), F(21), F(33), F(45), S( 9), S( 9), S( 9), S( 9),}, 0xFF,0x00 }, +/*44*/{{ F(10), F(22), F(34), F(46), S(10), S(10), S(10), S(10),}, 0xFF,0x00 }, +/*45*/{{ NLK, NLK, NLK, NLK, NLK, NLK, NLK, NLK, }, 0xFF,0x00 }, +/*46*/{{ SLK, SLK, SLK, SLK, SLK, SLK, SLK, SLK, }, 0xFF,0x00 }, +/*47*/{{ F(49), '7', '7', '7', '7', '7', '7', '7', }, 0x80,0x02 }, +/*48*/{{ F(50), '8', '8', '8', '8', '8', '8', '8', }, 0x80,0x02 }, +/*49*/{{ F(51), '9', '9', '9', '9', '9', '9', '9', }, 0x80,0x02 }, +/*4a*/{{ F(52), '-', '-', '-', '-', '-', '-', '-', }, 0x80,0x02 }, +/*4b*/{{ F(53), '4', '4', '4', '4', '4', '4', '4', }, 0x80,0x02 }, +/*4c*/{{ F(54), '5', '5', '5', '5', '5', '5', '5', }, 0x80,0x02 }, +/*4d*/{{ F(55), '6', '6', '6', '6', '6', '6', '6', }, 0x80,0x02 }, +/*4e*/{{ F(56), '+', '+', '+', '+', '+', '+', '+', }, 0x80,0x02 }, +/*4f*/{{ F(57), '1', '1', '1', '1', '1', '1', '1', }, 0x80,0x02 }, +/*50*/{{ F(58), '2', '2', '2', '2', '2', '2', '2', }, 0x80,0x02 }, +/*51*/{{ F(59), '3', '3', '3', '3', '3', '3', '3', }, 0x80,0x02 }, +/*52*/{{ F(60), '0', '0', '0', '0', '0', '0', '0', }, 0x80,0x02 }, +/*53*/{{ 0x7F, '.', '.', '.', '.', '.', RBT, RBT, }, 0x03,0x02 }, +/*54*/{{ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, }, 0xFF,0x00 }, +/*55*/{{ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, }, 0xFF,0x00 }, +/*56*/{{ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, }, 0xFF,0x00 }, +/*57*/{{ F(11), F(23), F(35), F(47), S(11), S(11), S(11), S(11),}, 0xFF,0x00 }, +/*58*/{{ F(12), F(24), F(36), F(48), S(12), S(12), S(12), S(12),}, 0xFF,0x00 }, +/*59*/{{ 0x0D, 0x0D, 0x0A, 0x0A, 0x0D, 0x0D, 0x0A, 0x0A, }, 0x00,0x00 }, +/*5a*/{{ RCTR, RCTR, RCTR, RCTR, RCTR, RCTR, RCTR, RCTR, }, 0xFF,0x00 }, +/*5b*/{{ '/', '/', '/', '/', '/', '/', '/', '/', }, 0x00,0x02 }, +/*5c*/{{ NEXT, NEXT, NOP, NOP, DBG, DBG, DBG, DBG, }, 0xFF,0x00 }, +/*5d*/{{ RALT, RALT, RALT, RALT, RALT, RALT, RALT, RALT, }, 0xFF,0x00 }, +/*5e*/{{ F(49), F(49), F(49), F(49), F(49), F(49), F(49), F(49),}, 0xFF,0x00 }, +/*5f*/{{ F(50), F(50), F(50), F(50), F(50), F(50), F(50), F(50),}, 0xFF,0x00 }, +/*60*/{{ F(51), F(51), F(51), F(51), F(51), F(51), F(51), F(51),}, 0xFF,0x00 }, +/*61*/{{ F(53), F(53), F(53), F(53), F(53), F(53), F(53), F(53),}, 0xFF,0x00 }, +/*62*/{{ F(55), F(55), F(55), F(55), F(55), F(55), F(55), F(55),}, 0xFF,0x00 }, +/*63*/{{ F(57), F(57), F(57), F(57), F(57), F(57), F(57), F(57),}, 0xFF,0x00 }, +/*64*/{{ F(58), F(58), F(58), F(58), F(58), F(58), F(58), F(58),}, 0xFF,0x00 }, +/*65*/{{ F(59), F(59), F(59), F(59), F(59), F(59), F(59), F(59),}, 0xFF,0x00 }, +/*66*/{{ F(60), F(60), F(60), F(60), F(60), F(60), F(60), F(60),}, 0xFF,0x00 }, +/*67*/{{ F(61), F(61), F(61), F(61), F(61), F(61), RBT, F(61),}, 0xFF,0x00 }, +/*68*/{{ SPSC, SPSC, SUSP, SUSP, NOP, NOP, SUSP, SUSP, }, 0xFF,0x00 }, +/*69*/{{ F(62), F(62), F(62), F(62), F(62), F(62), F(62), F(62),}, 0xFF,0x00 }, +/*6a*/{{ F(63), F(63), F(63), F(63), F(63), F(63), F(63), F(63),}, 0xFF,0x00 }, +/*6b*/{{ F(64), F(64), F(64), F(64), F(64), F(64), F(64), F(64),}, 0xFF,0x00 }, +/*6c*/{{ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP, }, 0xFF,0x00 }, +} }; + +static accentmap_t accentmap_default_us_acc = { 11, { + /* dgra=0 */ + { '`', { { 'a',0xe0 }, { 'A',0xc0 }, { 'e',0xe8 }, { 'E',0xc8 }, + { 'i',0xec }, { 'I',0xcc }, { 'o',0xf2 }, { 'O',0xd2 }, + { 'u',0xf9 }, { 'U',0xd9 }, }, }, + /* dacu=1 */ + { 0xb4, { { 'a',0xe1 }, { 'A',0xc1 }, { 'e',0xe9 }, { 'E',0xc9 }, + { 'i',0xed }, { 'I',0xcd }, { 'o',0xf3 }, { 'O',0xd3 }, + { 'u',0xfa }, { 'U',0xda }, { 'y',0xfd }, { 'Y',0xdd }, }, }, + /* dcir=2 */ + { '^', { { 'a',0xe2 }, { 'A',0xc2 }, { 'e',0xea }, { 'E',0xca }, + { 'i',0xee }, { 'I',0xce }, { 'o',0xf4 }, { 'O',0xd4 }, + { 'u',0xfb }, { 'U',0xdb }, }, }, + /* dtil=3 */ + { '~', { { 'a',0xe3 }, { 'A',0xc3 }, { 'n',0xf1 }, { 'N',0xd1 }, + { 'o',0xf5 }, { 'O',0xd5 }, }, }, + /* dmac=4 */ + { 0x00 }, + /* dbre=5 */ + { 0x00 }, + /* ddot=6 */ + { 0x00 }, + /* duml=7 */ + { 0xa8, { { 'a',0xe4 }, { 'A',0xc4 }, { 'e',0xeb }, { 'E',0xcb }, + { 'i',0xef }, { 'I',0xcf }, { 'o',0xf6 }, { 'O',0xd6 }, + { 'u',0xfc }, { 'U',0xdc }, { 'y',0xff }, }, }, + /* dsla=8 */ + { 0x00 }, + /* drin=9 */ + { 0xb0, { { 'a',0xe5 }, { 'A',0xc5 }, }, }, + /* dced=10 */ + { 0xb8, { { 'c',0xe7 }, { 'C',0xc7 }, }, }, + /* dapo=11 */ + { 0x00 }, + /* ddac=12 */ + { 0x00 }, + /* dogo=13 */ + { 0x00 }, + /* dcar=14 */ + { 0x00 }, +} }; + +/* *INDENT-ON* */ /* clang-format on */ diff --git a/SDL2-2.30.5/src/core/freebsd/SDL_evdev_kbd_freebsd.c b/SDL2-2.30.5/src/core/freebsd/SDL_evdev_kbd_freebsd.c new file mode 100644 index 0000000..a3c3456 --- /dev/null +++ b/SDL2-2.30.5/src/core/freebsd/SDL_evdev_kbd_freebsd.c @@ -0,0 +1,613 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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 "../linux/SDL_evdev_kbd.h" +#include "SDL_hints.h" + +#ifdef SDL_INPUT_FBSDKBIO + +/* This logic is adapted from drivers/tty/vt/keyboard.c in the Linux kernel source, slightly modified to work with FreeBSD */ + +#include +#include +#include +#include +#include + +#include + +#include "../../events/SDL_events_c.h" +#include "SDL_evdev_kbd_default_keyaccmap.h" + +typedef void(fn_handler_fn)(SDL_EVDEV_keyboard_state *kbd); + +/* + * Keyboard State + */ + +struct SDL_EVDEV_keyboard_state +{ + int console_fd; + int keyboard_fd; + unsigned long old_kbd_mode; + unsigned short **key_maps; + keymap_t *key_map; + keyboard_info_t *kbInfo; + unsigned char shift_down[4]; /* shift state counters.. */ + SDL_bool dead_key_next; + int npadch; /* -1 or number assembled on pad */ + accentmap_t *accents; + unsigned int diacr; + SDL_bool rep; /* flag telling character repeat */ + unsigned char lockstate; + unsigned char ledflagstate; + char shift_state; + char text[128]; + unsigned int text_len; +}; + +static int SDL_EVDEV_kbd_load_keymaps(SDL_EVDEV_keyboard_state *kbd) +{ + return ioctl(kbd->keyboard_fd, GIO_KEYMAP, kbd->key_map) >= 0; +} + +static SDL_EVDEV_keyboard_state *kbd_cleanup_state = NULL; +static int kbd_cleanup_sigactions_installed = 0; +static int kbd_cleanup_atexit_installed = 0; + +static struct sigaction old_sigaction[NSIG]; + +static int fatal_signals[] = { + /* Handlers for SIGTERM and SIGINT are installed in SDL_QuitInit. */ + SIGHUP, SIGQUIT, SIGILL, SIGABRT, + SIGFPE, SIGSEGV, SIGPIPE, SIGBUS, + SIGSYS +}; + +static void kbd_cleanup(void) +{ + struct mouse_info mData; + SDL_EVDEV_keyboard_state *kbd = kbd_cleanup_state; + if (!kbd) { + return; + } + kbd_cleanup_state = NULL; + SDL_zero(mData); + mData.operation = MOUSE_SHOW; + ioctl(kbd->keyboard_fd, KDSKBMODE, kbd->old_kbd_mode); + if (kbd->keyboard_fd != kbd->console_fd) { + close(kbd->keyboard_fd); + } + ioctl(kbd->console_fd, CONS_SETKBD, (unsigned long)(kbd->kbInfo->kb_index)); + ioctl(kbd->console_fd, CONS_MOUSECTL, &mData); +} + +void SDL_EVDEV_kbd_reraise_signal(int sig) +{ + raise(sig); +} + +siginfo_t *SDL_EVDEV_kdb_cleanup_siginfo = NULL; +void *SDL_EVDEV_kdb_cleanup_ucontext = NULL; + +static void kbd_cleanup_signal_action(int signum, siginfo_t *info, void *ucontext) +{ + struct sigaction *old_action_p = &(old_sigaction[signum]); + sigset_t sigset; + + /* Restore original signal handler before going any further. */ + sigaction(signum, old_action_p, NULL); + + /* Unmask current signal. */ + sigemptyset(&sigset); + sigaddset(&sigset, signum); + sigprocmask(SIG_UNBLOCK, &sigset, NULL); + + /* Save original signal info and context for archeologists. */ + SDL_EVDEV_kdb_cleanup_siginfo = info; + SDL_EVDEV_kdb_cleanup_ucontext = ucontext; + + /* Restore keyboard. */ + kbd_cleanup(); + + /* Reraise signal. */ + SDL_EVDEV_kbd_reraise_signal(signum); +} + +static void kbd_unregister_emerg_cleanup() +{ + int tabidx, signum; + + kbd_cleanup_state = NULL; + + if (!kbd_cleanup_sigactions_installed) { + return; + } + kbd_cleanup_sigactions_installed = 0; + + for (tabidx = 0; tabidx < sizeof(fatal_signals) / sizeof(fatal_signals[0]); ++tabidx) { + struct sigaction *old_action_p; + struct sigaction cur_action; + signum = fatal_signals[tabidx]; + old_action_p = &(old_sigaction[signum]); + + /* Examine current signal action */ + if (sigaction(signum, NULL, &cur_action)) { + continue; + } + + /* Check if action installed and not modifed */ + if (!(cur_action.sa_flags & SA_SIGINFO) || cur_action.sa_sigaction != &kbd_cleanup_signal_action) { + continue; + } + + /* Restore original action */ + sigaction(signum, old_action_p, NULL); + } +} + +static void kbd_cleanup_atexit(void) +{ + /* Restore keyboard. */ + kbd_cleanup(); + + /* Try to restore signal handlers in case shared library is being unloaded */ + kbd_unregister_emerg_cleanup(); +} + +static void kbd_register_emerg_cleanup(SDL_EVDEV_keyboard_state *kbd) +{ + int tabidx, signum; + + if (kbd_cleanup_state) { + return; + } + kbd_cleanup_state = kbd; + + if (!kbd_cleanup_atexit_installed) { + /* Since glibc 2.2.3, atexit() (and on_exit(3)) can be used within a shared library to establish + * functions that are called when the shared library is unloaded. + * -- man atexit(3) + */ + atexit(kbd_cleanup_atexit); + kbd_cleanup_atexit_installed = 1; + } + + if (kbd_cleanup_sigactions_installed) { + return; + } + kbd_cleanup_sigactions_installed = 1; + + for (tabidx = 0; tabidx < sizeof(fatal_signals) / sizeof(fatal_signals[0]); ++tabidx) { + struct sigaction *old_action_p; + struct sigaction new_action; + signum = fatal_signals[tabidx]; + old_action_p = &(old_sigaction[signum]); + if (sigaction(signum, NULL, old_action_p)) { + continue; + } + + /* Skip SIGHUP and SIGPIPE if handler is already installed + * - assume the handler will do the cleanup + */ + if ((signum == SIGHUP || signum == SIGPIPE) && (old_action_p->sa_handler != SIG_DFL || (void (*)(int))old_action_p->sa_sigaction != SIG_DFL)) { + continue; + } + + new_action = *old_action_p; + new_action.sa_flags |= SA_SIGINFO; + new_action.sa_sigaction = &kbd_cleanup_signal_action; + sigaction(signum, &new_action, NULL); + } +} + +SDL_EVDEV_keyboard_state *SDL_EVDEV_kbd_init(void) +{ + SDL_EVDEV_keyboard_state *kbd; + struct mouse_info mData; + char flag_state; + char *devicePath; + + SDL_zero(mData); + mData.operation = MOUSE_HIDE; + kbd = (SDL_EVDEV_keyboard_state *)SDL_calloc(1, sizeof(SDL_EVDEV_keyboard_state)); + if (!kbd) { + return NULL; + } + + kbd->npadch = -1; + + /* This might fail if we're not connected to a tty (e.g. on the Steam Link) */ + kbd->keyboard_fd = kbd->console_fd = open("/dev/tty", O_RDONLY | O_CLOEXEC); + + kbd->shift_state = 0; + + kbd->accents = SDL_calloc(sizeof(accentmap_t), 1); + kbd->key_map = SDL_calloc(sizeof(keymap_t), 1); + kbd->kbInfo = SDL_calloc(sizeof(keyboard_info_t), 1); + + ioctl(kbd->console_fd, KDGKBINFO, kbd->kbInfo); + ioctl(kbd->console_fd, CONS_MOUSECTL, &mData); + + if (ioctl(kbd->console_fd, KDGKBSTATE, &flag_state) == 0) { + kbd->ledflagstate = flag_state; + } + + if (ioctl(kbd->console_fd, GIO_DEADKEYMAP, kbd->accents) < 0) { + SDL_free(kbd->accents); + kbd->accents = &accentmap_default_us_acc; + } + + if (ioctl(kbd->console_fd, KDGKBMODE, &kbd->old_kbd_mode) == 0) { + /* Set the keyboard in XLATE mode and load the keymaps */ + ioctl(kbd->console_fd, KDSKBMODE, (unsigned long)(K_XLATE)); + if (!SDL_EVDEV_kbd_load_keymaps(kbd)) { + SDL_free(kbd->key_map); + kbd->key_map = &keymap_default_us_acc; + } + /* Allow inhibiting keyboard mute with env. variable for debugging etc. */ + if (SDL_getenv("SDL_INPUT_FREEBSD_KEEP_KBD") == NULL) { + /* Take keyboard from console and open the actual keyboard device. + * Ensures that the keystrokes do not leak through to the console. + */ + ioctl(kbd->console_fd, CONS_RELKBD, 1ul); + SDL_asprintf(&devicePath, "/dev/kbd%d", kbd->kbInfo->kb_index); + kbd->keyboard_fd = open(devicePath, O_WRONLY | O_CLOEXEC); + if (kbd->keyboard_fd == -1) { + // Give keyboard back. + ioctl(kbd->console_fd, CONS_SETKBD, (unsigned long)(kbd->kbInfo->kb_index)); + kbd->keyboard_fd = kbd->console_fd; + } + + /* Make sure to restore keyboard if application fails to call + * SDL_Quit before exit or fatal signal is raised. + */ + if (!SDL_GetHintBoolean(SDL_HINT_NO_SIGNAL_HANDLERS, SDL_FALSE)) { + kbd_register_emerg_cleanup(kbd); + } + SDL_free(devicePath); + } else + kbd->keyboard_fd = kbd->console_fd; + } + + return kbd; +} + +void SDL_EVDEV_kbd_quit(SDL_EVDEV_keyboard_state *kbd) +{ + struct mouse_info mData; + + if (!kbd) { + return; + } + SDL_zero(mData); + mData.operation = MOUSE_SHOW; + ioctl(kbd->console_fd, CONS_MOUSECTL, &mData); + + kbd_unregister_emerg_cleanup(); + + if (kbd->keyboard_fd >= 0) { + /* Restore the original keyboard mode */ + ioctl(kbd->keyboard_fd, KDSKBMODE, kbd->old_kbd_mode); + + close(kbd->keyboard_fd); + if (kbd->console_fd != kbd->keyboard_fd && kbd->console_fd >= 0) { + // Give back keyboard. + ioctl(kbd->console_fd, CONS_SETKBD, (unsigned long)(kbd->kbInfo->kb_index)); + } + kbd->console_fd = kbd->keyboard_fd = -1; + } + + SDL_free(kbd); +} + +void SDL_EVDEV_kbd_set_muted(SDL_EVDEV_keyboard_state *state, SDL_bool muted) +{ +} + +void SDL_EVDEV_kbd_set_vt_switch_callbacks(SDL_EVDEV_keyboard_state *state, void (*release_callback)(void*), void *release_callback_data, void (*acquire_callback)(void*), void *acquire_callback_data) +{ +} + +void SDL_EVDEV_kbd_update(SDL_EVDEV_keyboard_state *state) +{ +} + +/* + * Helper Functions. + */ +static void put_queue(SDL_EVDEV_keyboard_state *kbd, uint c) +{ + /* c is already part of a UTF-8 sequence and safe to add as a character */ + if (kbd->text_len < (sizeof(kbd->text) - 1)) { + kbd->text[kbd->text_len++] = (char)c; + } +} + +static void put_utf8(SDL_EVDEV_keyboard_state *kbd, uint c) +{ + if (c < 0x80) + /* 0******* */ + put_queue(kbd, c); + else if (c < 0x800) { + /* 110***** 10****** */ + put_queue(kbd, 0xc0 | (c >> 6)); + put_queue(kbd, 0x80 | (c & 0x3f)); + } else if (c < 0x10000) { + if (c >= 0xD800 && c < 0xE000) { + return; + } + if (c == 0xFFFF) { + return; + } + /* 1110**** 10****** 10****** */ + put_queue(kbd, 0xe0 | (c >> 12)); + put_queue(kbd, 0x80 | ((c >> 6) & 0x3f)); + put_queue(kbd, 0x80 | (c & 0x3f)); + } else if (c < 0x110000) { + /* 11110*** 10****** 10****** 10****** */ + put_queue(kbd, 0xf0 | (c >> 18)); + put_queue(kbd, 0x80 | ((c >> 12) & 0x3f)); + put_queue(kbd, 0x80 | ((c >> 6) & 0x3f)); + put_queue(kbd, 0x80 | (c & 0x3f)); + } +} + +/* + * We have a combining character DIACR here, followed by the character CH. + * If the combination occurs in the table, return the corresponding value. + * Otherwise, if CH is a space or equals DIACR, return DIACR. + * Otherwise, conclude that DIACR was not combining after all, + * queue it and return CH. + */ +static unsigned int handle_diacr(SDL_EVDEV_keyboard_state *kbd, unsigned int ch) +{ + unsigned int d = kbd->diacr; + unsigned int i, j; + + kbd->diacr = 0; + + for (i = 0; i < kbd->accents->n_accs; i++) { + if (kbd->accents->acc[i].accchar == d) { + for (j = 0; j < NUM_ACCENTCHARS; ++j) { + if (kbd->accents->acc[i].map[j][0] == 0) { /* end of table */ + break; + } + if (kbd->accents->acc[i].map[j][0] == ch) { + return kbd->accents->acc[i].map[j][1]; + } + } + } + } + + if (ch == ' ' || ch == d) { + put_utf8(kbd, d); + return 0; + } + put_utf8(kbd, d); + + return ch; +} + +static int vc_kbd_led(SDL_EVDEV_keyboard_state *kbd, int flag) +{ + return (kbd->ledflagstate & flag) != 0; +} + +static void chg_vc_kbd_led(SDL_EVDEV_keyboard_state *kbd, int flag) +{ + kbd->ledflagstate ^= flag; + ioctl(kbd->keyboard_fd, KDSKBSTATE, (unsigned long)(kbd->ledflagstate)); +} + +/* + * Special function handlers + */ + +static void k_self(SDL_EVDEV_keyboard_state *kbd, unsigned int value, char up_flag) +{ + if (up_flag) { + return; /* no action, if this is a key release */ + } + + if (kbd->diacr) { + value = handle_diacr(kbd, value); + } + + if (kbd->dead_key_next) { + kbd->dead_key_next = SDL_FALSE; + kbd->diacr = value; + return; + } + put_utf8(kbd, value); +} + +static void k_deadunicode(SDL_EVDEV_keyboard_state *kbd, unsigned int value, char up_flag) +{ + if (up_flag) + return; + + kbd->diacr = (kbd->diacr ? handle_diacr(kbd, value) : value); +} + +static void k_shift(SDL_EVDEV_keyboard_state *kbd, unsigned char value, char up_flag) +{ + int old_state = kbd->shift_state; + + if (kbd->rep) + return; + + if (up_flag) { + /* + * handle the case that two shift or control + * keys are depressed simultaneously + */ + if (kbd->shift_down[value]) { + kbd->shift_down[value]--; + } + } else + kbd->shift_down[value]++; + + if (kbd->shift_down[value]) + kbd->shift_state |= (1 << value); + else + kbd->shift_state &= ~(1 << value); + + /* kludge */ + if (up_flag && kbd->shift_state != old_state && kbd->npadch != -1) { + put_utf8(kbd, kbd->npadch); + kbd->npadch = -1; + } +} + +void SDL_EVDEV_kbd_keycode(SDL_EVDEV_keyboard_state *kbd, unsigned int keycode, int down) +{ + keymap_t key_map; + struct keyent_t keysym; + unsigned int final_key_state; + unsigned int map_from_key_sym; + + if (!kbd) { + return; + } + + key_map = *kbd->key_map; + + kbd->rep = (down == 2); + + if (keycode < NUM_KEYS) { + if (keycode >= 89 && keycode <= 95) { + /* These constitute unprintable language-related keys, so ignore them. */ + return; + } + if (keycode > 95) { + keycode -= 7; + } + if (vc_kbd_led(kbd, ALKED) || (kbd->shift_state & 0x8)) { + keycode += ALTGR_OFFSET; + } + keysym = key_map.key[keycode]; + } else { + return; + } + + final_key_state = kbd->shift_state & 0x7; + if ((keysym.flgs & FLAG_LOCK_C) && vc_kbd_led(kbd, LED_CAP)) { + final_key_state ^= 0x1; + } + if ((keysym.flgs & FLAG_LOCK_N) && vc_kbd_led(kbd, LED_NUM)) { + final_key_state ^= 0x1; + } + + map_from_key_sym = keysym.map[final_key_state]; + if ((keysym.spcl & (0x80 >> final_key_state)) || (map_from_key_sym & SPCLKEY)) { + /* Special function.*/ + if (map_from_key_sym == 0) + return; /* Nothing to do. */ + if (map_from_key_sym & SPCLKEY) { + map_from_key_sym &= ~SPCLKEY; + } + if (map_from_key_sym >= F_ACC && map_from_key_sym <= L_ACC) { + /* Accent function.*/ + unsigned int accent_index = map_from_key_sym - F_ACC; + if (kbd->accents->acc[accent_index].accchar != 0) { + k_deadunicode(kbd, kbd->accents->acc[accent_index].accchar, !down); + } + } else { + switch (map_from_key_sym) { + case ASH: /* alt/meta shift */ + k_shift(kbd, 3, down == 0); + break; + case LSHA: /* left shift + alt lock */ + case RSHA: /* right shift + alt lock */ + if (down == 0) { + chg_vc_kbd_led(kbd, ALKED); + } + case LSH: /* left shift */ + case RSH: /* right shift */ + k_shift(kbd, 0, down == 0); + break; + case LCTRA: /* left ctrl + alt lock */ + case RCTRA: /* right ctrl + alt lock */ + if (down == 0) { + chg_vc_kbd_led(kbd, ALKED); + } + case LCTR: /* left ctrl */ + case RCTR: /* right ctrl */ + k_shift(kbd, 1, down == 0); + break; + case LALTA: /* left alt + alt lock */ + case RALTA: /* right alt + alt lock */ + if (down == 0) { + chg_vc_kbd_led(kbd, ALKED); + } + case LALT: /* left alt */ + case RALT: /* right alt */ + k_shift(kbd, 2, down == 0); + break; + case ALK: /* alt lock */ + if (down == 1) { + chg_vc_kbd_led(kbd, ALKED); + } + break; + case CLK: /* caps lock*/ + if (down == 1) { + chg_vc_kbd_led(kbd, CLKED); + } + break; + case NLK: /* num lock */ + if (down == 1) { + chg_vc_kbd_led(kbd, NLKED); + } + break; + case SLK: /* scroll lock */ + if (down == 1) { + chg_vc_kbd_led(kbd, SLKED); + } + break; + default: + return; + } + } + } else { + if (map_from_key_sym == '\n' || map_from_key_sym == '\r') { + if (kbd->diacr) { + kbd->diacr = 0; + return; + } + } + if (map_from_key_sym >= ' ' && map_from_key_sym != 127) { + k_self(kbd, map_from_key_sym, !down); + } + } + + if (kbd->text_len > 0) { + kbd->text[kbd->text_len] = '\0'; + SDL_SendKeyboardText(kbd->text); + kbd->text_len = 0; + } +} + +#endif /* SDL_INPUT_FBSDKBIO */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/core/gdk/SDL_gdk.cpp b/SDL2-2.30.5/src/core/gdk/SDL_gdk.cpp new file mode 100644 index 0000000..0699568 --- /dev/null +++ b/SDL2-2.30.5/src/core/gdk/SDL_gdk.cpp @@ -0,0 +1,262 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +extern "C" { +#include "SDL_system.h" +#include "../windows/SDL_windows.h" +#include "SDL_messagebox.h" +#include "SDL_main.h" +#include "SDL_events.h" +#include "../../events/SDL_events_c.h" +} +#include +#include +#include /* CommandLineToArgvW() */ +#include + +static XTaskQueueHandle GDK_GlobalTaskQueue; + +PAPPSTATE_REGISTRATION hPLM = {}; +PAPPCONSTRAIN_REGISTRATION hCPLM = {}; +HANDLE plmSuspendComplete = nullptr; + +extern "C" DECLSPEC int +SDL_GDKGetTaskQueue(XTaskQueueHandle *outTaskQueue) +{ + /* If this is the first call, first create the global task queue. */ + if (!GDK_GlobalTaskQueue) { + HRESULT hr; + + hr = XTaskQueueCreate(XTaskQueueDispatchMode::ThreadPool, + XTaskQueueDispatchMode::Manual, + &GDK_GlobalTaskQueue); + if (FAILED(hr)) { + return SDL_SetError("[GDK] Could not create global task queue"); + } + + /* The initial call gets the non-duplicated handle so they can clean it up */ + *outTaskQueue = GDK_GlobalTaskQueue; + } else { + /* Duplicate the global task queue handle into outTaskQueue */ + if (FAILED(XTaskQueueDuplicateHandle(GDK_GlobalTaskQueue, outTaskQueue))) { + return SDL_SetError("[GDK] Unable to acquire global task queue"); + } + } + + return 0; +} + +extern "C" void +GDK_DispatchTaskQueue(void) +{ + /* If there is no global task queue, don't do anything. + * This gives the option to opt-out for those who want to handle everything themselves. + */ + if (GDK_GlobalTaskQueue) { + /* Dispatch any callbacks which are ready. */ + while (XTaskQueueDispatch(GDK_GlobalTaskQueue, XTaskQueuePort::Completion, 0)) + ; + } +} + +/* Pop up an out of memory message, returns to Windows */ +extern "C" static BOOL +OutOfMemory(void) +{ + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal Error", "Out of memory - aborting", NULL); + return FALSE; +} + +/* Gets the arguments with GetCommandLine, converts them to argc and argv + and calls SDL_main */ +extern "C" DECLSPEC int +SDL_GDKRunApp(SDL_main_func mainFunction, void *reserved) +{ + LPWSTR *argvw; + char **argv; + int i, argc, result; + HRESULT hr; + XTaskQueueHandle taskQueue; + + argvw = CommandLineToArgvW(GetCommandLineW(), &argc); + if (argvw == NULL) { + return OutOfMemory(); + } + + /* Note that we need to be careful about how we allocate/free memory here. + * If the application calls SDL_SetMemoryFunctions(), we can't rely on + * SDL_free() to use the same allocator after SDL_main() returns. + */ + + /* Parse it into argv and argc */ + argv = (char **)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (argc + 1) * sizeof(*argv)); + if (argv == NULL) { + return OutOfMemory(); + } + for (i = 0; i < argc; ++i) { + DWORD len; + char *arg = WIN_StringToUTF8W(argvw[i]); + if (arg == NULL) { + return OutOfMemory(); + } + len = (DWORD)SDL_strlen(arg); + argv[i] = (char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len + 1); + if (!argv[i]) { + return OutOfMemory(); + } + SDL_memcpy(argv[i], arg, len); + SDL_free(arg); + } + argv[i] = NULL; + LocalFree(argvw); + + hr = XGameRuntimeInitialize(); + + if (SUCCEEDED(hr) && SDL_GDKGetTaskQueue(&taskQueue) == 0) { + Uint32 titleid = 0; + char scidBuffer[64]; + XblInitArgs xblArgs; + + XTaskQueueSetCurrentProcessTaskQueue(taskQueue); + + /* Try to get the title ID and initialize Xbox Live */ + hr = XGameGetXboxTitleId(&titleid); + if (SUCCEEDED(hr)) { + SDL_zero(xblArgs); + xblArgs.queue = taskQueue; + SDL_snprintf(scidBuffer, 64, "00000000-0000-0000-0000-0000%08X", titleid); + xblArgs.scid = scidBuffer; + hr = XblInitialize(&xblArgs); + } else { + SDL_SetError("[GDK] Unable to get titleid. Will not call XblInitialize. Check MicrosoftGame.config!"); + } + + SDL_SetMainReady(); + + /* Register suspend/resume handling */ + plmSuspendComplete = CreateEventEx(nullptr, nullptr, 0, EVENT_MODIFY_STATE | SYNCHRONIZE); + if (!plmSuspendComplete) { + SDL_SetError("[GDK] Unable to create plmSuspendComplete event"); + return -1; + } + auto rascn = [](BOOLEAN quiesced, PVOID context) { + SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "[GDK] in RegisterAppStateChangeNotification handler"); + if (quiesced) { + ResetEvent(plmSuspendComplete); + SDL_SendAppEvent(SDL_APP_DIDENTERBACKGROUND); + + // To defer suspension, we must wait to exit this callback. + // IMPORTANT: The app must call SDL_GDKSuspendComplete() to release this lock. + (void)WaitForSingleObject(plmSuspendComplete, INFINITE); + + SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "[GDK] in RegisterAppStateChangeNotification handler: plmSuspendComplete event signaled."); + } else { + SDL_SendAppEvent(SDL_APP_WILLENTERFOREGROUND); + } + }; + if (RegisterAppStateChangeNotification(rascn, NULL, &hPLM)) { + SDL_SetError("[GDK] Unable to call RegisterAppStateChangeNotification"); + return -1; + } + + /* Register constrain/unconstrain handling */ + auto raccn = [](BOOLEAN constrained, PVOID context) { + SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "[GDK] in RegisterAppConstrainedChangeNotification handler"); + SDL_VideoDevice *_this = SDL_GetVideoDevice(); + if (_this) { + if (constrained) { + SDL_SetKeyboardFocus(NULL); + } else { + SDL_SetKeyboardFocus(_this->windows); + } + } + }; + if (RegisterAppConstrainedChangeNotification(raccn, NULL, &hCPLM)) { + SDL_SetError("[GDK] Unable to call RegisterAppConstrainedChangeNotification"); + return -1; + } + + /* Run the application main() code */ + result = mainFunction(argc, argv); + + /* Unregister suspend/resume handling */ + UnregisterAppStateChangeNotification(hPLM); + CloseHandle(plmSuspendComplete); + + /* Unregister constrain/unconstrain handling */ + UnregisterAppConstrainedChangeNotification(hCPLM); + + /* !!! FIXME: This follows the docs exactly, but for some reason still leaks handles on exit? */ + /* Terminate the task queue and dispatch any pending tasks */ + XTaskQueueTerminate(taskQueue, false, nullptr, nullptr); + while (XTaskQueueDispatch(taskQueue, XTaskQueuePort::Completion, 0)) + ; + + XTaskQueueCloseHandle(taskQueue); + + XGameRuntimeUninitialize(); + } else { +#ifdef __WINGDK__ + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal Error", "[GDK] Could not initialize - aborting", NULL); +#else + SDL_assert_always(0 && "[GDK] Could not initialize - aborting"); +#endif + result = -1; + } + + /* Free argv, to avoid memory leak */ + for (i = 0; i < argc; ++i) { + HeapFree(GetProcessHeap(), 0, argv[i]); + } + HeapFree(GetProcessHeap(), 0, argv); + + return result; +} + +extern "C" DECLSPEC void +SDL_GDKSuspendComplete() +{ + if (plmSuspendComplete) { + SetEvent(plmSuspendComplete); + } +} + +extern "C" DECLSPEC int +SDL_GDKGetDefaultUser(XUserHandle *outUserHandle) +{ + XAsyncBlock block = { 0 }; + HRESULT result; + + if (FAILED(result = XUserAddAsync(XUserAddOptions::AddDefaultUserAllowingUI, &block))) { + return WIN_SetErrorFromHRESULT("XUserAddAsync", result); + } + + do { + result = XUserAddResult(&block, outUserHandle); + } while (result == E_PENDING); + if (FAILED(result)) { + return WIN_SetErrorFromHRESULT("XUserAddResult", result); + } + + return 0; +} + diff --git a/SDL2-2.30.5/src/core/gdk/SDL_gdk.h b/SDL2-2.30.5/src/core/gdk/SDL_gdk.h new file mode 100644 index 0000000..75f13ab --- /dev/null +++ b/SDL2-2.30.5/src/core/gdk/SDL_gdk.h @@ -0,0 +1,24 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +/* This is called from WIN_PumpEvents on GDK */ +extern void GDK_DispatchTaskQueue(void); diff --git a/SDL2-2.30.5/src/core/linux/SDL_dbus.c b/SDL2-2.30.5/src/core/linux/SDL_dbus.c new file mode 100644 index 0000000..7d706c2 --- /dev/null +++ b/SDL2-2.30.5/src/core/linux/SDL_dbus.c @@ -0,0 +1,603 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_hints.h" +#include "SDL_dbus.h" +#include "SDL_atomic.h" +#include "SDL_sandbox.h" +#include "../../stdlib/SDL_vacopy.h" + +#ifdef SDL_USE_LIBDBUS +/* we never link directly to libdbus. */ +#include "SDL_loadso.h" +static const char *dbus_library = "libdbus-1.so.3"; +static void *dbus_handle = NULL; +static char *inhibit_handle = NULL; +static unsigned int screensaver_cookie = 0; +static SDL_DBusContext dbus; + +static int LoadDBUSSyms(void) +{ +#define SDL_DBUS_SYM2_OPTIONAL(x, y) \ + dbus.x = SDL_LoadFunction(dbus_handle, #y) + +#define SDL_DBUS_SYM2(x, y) \ + if (!(dbus.x = SDL_LoadFunction(dbus_handle, #y))) \ + return -1 + +#define SDL_DBUS_SYM(x) \ + SDL_DBUS_SYM2(x, dbus_##x) + +#define SDL_DBUS_SYM_OPTIONAL(x) \ + SDL_DBUS_SYM2_OPTIONAL(x, dbus_##x) + + SDL_DBUS_SYM(bus_get_private); + SDL_DBUS_SYM(bus_register); + SDL_DBUS_SYM(bus_add_match); + SDL_DBUS_SYM(connection_open_private); + SDL_DBUS_SYM(connection_set_exit_on_disconnect); + SDL_DBUS_SYM(connection_get_is_connected); + SDL_DBUS_SYM(connection_add_filter); + SDL_DBUS_SYM(connection_try_register_object_path); + SDL_DBUS_SYM(connection_send); + SDL_DBUS_SYM(connection_send_with_reply_and_block); + SDL_DBUS_SYM(connection_close); + SDL_DBUS_SYM(connection_ref); + SDL_DBUS_SYM(connection_unref); + SDL_DBUS_SYM(connection_flush); + SDL_DBUS_SYM(connection_read_write); + SDL_DBUS_SYM(connection_dispatch); + SDL_DBUS_SYM(message_is_signal); + SDL_DBUS_SYM(message_new_method_call); + SDL_DBUS_SYM(message_append_args); + SDL_DBUS_SYM(message_append_args_valist); + SDL_DBUS_SYM(message_iter_init_append); + SDL_DBUS_SYM(message_iter_open_container); + SDL_DBUS_SYM(message_iter_append_basic); + SDL_DBUS_SYM(message_iter_close_container); + SDL_DBUS_SYM(message_get_args); + SDL_DBUS_SYM(message_get_args_valist); + SDL_DBUS_SYM(message_iter_init); + SDL_DBUS_SYM(message_iter_next); + SDL_DBUS_SYM(message_iter_get_basic); + SDL_DBUS_SYM(message_iter_get_arg_type); + SDL_DBUS_SYM(message_iter_recurse); + SDL_DBUS_SYM(message_unref); + SDL_DBUS_SYM(threads_init_default); + SDL_DBUS_SYM(error_init); + SDL_DBUS_SYM(error_is_set); + SDL_DBUS_SYM(error_free); + SDL_DBUS_SYM(get_local_machine_id); + SDL_DBUS_SYM_OPTIONAL(try_get_local_machine_id); + SDL_DBUS_SYM(free); + SDL_DBUS_SYM(free_string_array); + SDL_DBUS_SYM(shutdown); + +#undef SDL_DBUS_SYM +#undef SDL_DBUS_SYM2 + + return 0; +} + +static void UnloadDBUSLibrary(void) +{ + if (dbus_handle) { + SDL_UnloadObject(dbus_handle); + dbus_handle = NULL; + } +} + +static int LoadDBUSLibrary(void) +{ + int retval = 0; + if (!dbus_handle) { + dbus_handle = SDL_LoadObject(dbus_library); + if (!dbus_handle) { + retval = -1; + /* Don't call SDL_SetError(): SDL_LoadObject already did. */ + } else { + retval = LoadDBUSSyms(); + if (retval < 0) { + UnloadDBUSLibrary(); + } + } + } + + return retval; +} + +static SDL_SpinLock spinlock_dbus_init = 0; + +/* you must hold spinlock_dbus_init before calling this! */ +static void SDL_DBus_Init_Spinlocked(void) +{ + static SDL_bool is_dbus_available = SDL_TRUE; + if (!is_dbus_available) { + return; /* don't keep trying if this fails. */ + } + + if (!dbus.session_conn) { + DBusError err; + + if (LoadDBUSLibrary() == -1) { + is_dbus_available = SDL_FALSE; /* can't load at all? Don't keep trying. */ + return; + } + + if (!dbus.threads_init_default()) { + is_dbus_available = SDL_FALSE; + return; + } + + dbus.error_init(&err); + /* session bus is required */ + + dbus.session_conn = dbus.bus_get_private(DBUS_BUS_SESSION, &err); + if (dbus.error_is_set(&err)) { + dbus.error_free(&err); + SDL_DBus_Quit(); + is_dbus_available = SDL_FALSE; + return; /* oh well */ + } + dbus.connection_set_exit_on_disconnect(dbus.session_conn, 0); + + /* system bus is optional */ + dbus.system_conn = dbus.bus_get_private(DBUS_BUS_SYSTEM, &err); + if (!dbus.error_is_set(&err)) { + dbus.connection_set_exit_on_disconnect(dbus.system_conn, 0); + } + + dbus.error_free(&err); + } +} + +void SDL_DBus_Init(void) +{ + SDL_AtomicLock(&spinlock_dbus_init); /* make sure two threads can't init at same time, since this can happen before SDL_Init. */ + SDL_DBus_Init_Spinlocked(); + SDL_AtomicUnlock(&spinlock_dbus_init); +} + +void SDL_DBus_Quit(void) +{ + if (dbus.system_conn) { + dbus.connection_close(dbus.system_conn); + dbus.connection_unref(dbus.system_conn); + } + if (dbus.session_conn) { + dbus.connection_close(dbus.session_conn); + dbus.connection_unref(dbus.session_conn); + } + + if (SDL_GetHintBoolean(SDL_HINT_SHUTDOWN_DBUS_ON_QUIT, SDL_FALSE)) { + if (dbus.shutdown) { + dbus.shutdown(); + } + } + + SDL_zero(dbus); + UnloadDBUSLibrary(); + SDL_free(inhibit_handle); + inhibit_handle = NULL; +} + +SDL_DBusContext *SDL_DBus_GetContext(void) +{ + if (!dbus_handle || !dbus.session_conn) { + SDL_DBus_Init(); + } + + return (dbus_handle && dbus.session_conn) ? &dbus : NULL; +} + +static SDL_bool SDL_DBus_CallMethodInternal(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, va_list ap) +{ + SDL_bool retval = SDL_FALSE; + + if (conn) { + DBusMessage *msg = dbus.message_new_method_call(node, path, interface, method); + if (msg) { + int firstarg; + va_list ap_reply; + va_copy(ap_reply, ap); /* copy the arg list so we don't compete with D-Bus for it */ + firstarg = va_arg(ap, int); + if ((firstarg == DBUS_TYPE_INVALID) || dbus.message_append_args_valist(msg, firstarg, ap)) { + DBusMessage *reply = dbus.connection_send_with_reply_and_block(conn, msg, 300, NULL); + if (reply) { + /* skip any input args, get to output args. */ + while ((firstarg = va_arg(ap_reply, int)) != DBUS_TYPE_INVALID) { + /* we assume D-Bus already validated all this. */ + { + void *dumpptr = va_arg(ap_reply, void *); + (void)dumpptr; + } + if (firstarg == DBUS_TYPE_ARRAY) { + { + const int dumpint = va_arg(ap_reply, int); + (void)dumpint; + } + } + } + firstarg = va_arg(ap_reply, int); + if ((firstarg == DBUS_TYPE_INVALID) || dbus.message_get_args_valist(reply, NULL, firstarg, ap_reply)) { + retval = SDL_TRUE; + } + dbus.message_unref(reply); + } + } + va_end(ap_reply); + dbus.message_unref(msg); + } + } + + return retval; +} + +SDL_bool SDL_DBus_CallMethodOnConnection(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, ...) +{ + SDL_bool retval; + va_list ap; + va_start(ap, method); + retval = SDL_DBus_CallMethodInternal(conn, node, path, interface, method, ap); + va_end(ap); + return retval; +} + +SDL_bool SDL_DBus_CallMethod(const char *node, const char *path, const char *interface, const char *method, ...) +{ + SDL_bool retval; + va_list ap; + va_start(ap, method); + retval = SDL_DBus_CallMethodInternal(dbus.session_conn, node, path, interface, method, ap); + va_end(ap); + return retval; +} + +static SDL_bool SDL_DBus_CallVoidMethodInternal(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, va_list ap) +{ + SDL_bool retval = SDL_FALSE; + + if (conn) { + DBusMessage *msg = dbus.message_new_method_call(node, path, interface, method); + if (msg) { + int firstarg = va_arg(ap, int); + if ((firstarg == DBUS_TYPE_INVALID) || dbus.message_append_args_valist(msg, firstarg, ap)) { + if (dbus.connection_send(conn, msg, NULL)) { + dbus.connection_flush(conn); + retval = SDL_TRUE; + } + } + + dbus.message_unref(msg); + } + } + + return retval; +} + +static SDL_bool SDL_DBus_CallWithBasicReply(DBusConnection *conn, DBusMessage *msg, const int expectedtype, void *result) +{ + SDL_bool retval = SDL_FALSE; + + DBusMessage *reply = dbus.connection_send_with_reply_and_block(conn, msg, 300, NULL); + if (reply) { + DBusMessageIter iter, actual_iter; + dbus.message_iter_init(reply, &iter); + if (dbus.message_iter_get_arg_type(&iter) == DBUS_TYPE_VARIANT) { + dbus.message_iter_recurse(&iter, &actual_iter); + } else { + actual_iter = iter; + } + + if (dbus.message_iter_get_arg_type(&actual_iter) == expectedtype) { + dbus.message_iter_get_basic(&actual_iter, result); + retval = SDL_TRUE; + } + + dbus.message_unref(reply); + } + + return retval; +} + +SDL_bool SDL_DBus_CallVoidMethodOnConnection(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, ...) +{ + SDL_bool retval; + va_list ap; + va_start(ap, method); + retval = SDL_DBus_CallVoidMethodInternal(conn, node, path, interface, method, ap); + va_end(ap); + return retval; +} + +SDL_bool SDL_DBus_CallVoidMethod(const char *node, const char *path, const char *interface, const char *method, ...) +{ + SDL_bool retval; + va_list ap; + va_start(ap, method); + retval = SDL_DBus_CallVoidMethodInternal(dbus.session_conn, node, path, interface, method, ap); + va_end(ap); + return retval; +} + +SDL_bool SDL_DBus_QueryPropertyOnConnection(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *property, const int expectedtype, void *result) +{ + SDL_bool retval = SDL_FALSE; + + if (conn) { + DBusMessage *msg = dbus.message_new_method_call(node, path, "org.freedesktop.DBus.Properties", "Get"); + if (msg) { + if (dbus.message_append_args(msg, DBUS_TYPE_STRING, &interface, DBUS_TYPE_STRING, &property, DBUS_TYPE_INVALID)) { + retval = SDL_DBus_CallWithBasicReply(conn, msg, expectedtype, result); + } + dbus.message_unref(msg); + } + } + + return retval; +} + +SDL_bool SDL_DBus_QueryProperty(const char *node, const char *path, const char *interface, const char *property, const int expectedtype, void *result) +{ + return SDL_DBus_QueryPropertyOnConnection(dbus.session_conn, node, path, interface, property, expectedtype, result); +} + +void SDL_DBus_ScreensaverTickle(void) +{ + if (screensaver_cookie == 0 && !inhibit_handle) { /* no need to tickle if we're inhibiting. */ + /* org.gnome.ScreenSaver is the legacy interface, but it'll either do nothing or just be a second harmless tickle on newer systems, so we leave it for now. */ + SDL_DBus_CallVoidMethod("org.gnome.ScreenSaver", "/org/gnome/ScreenSaver", "org.gnome.ScreenSaver", "SimulateUserActivity", DBUS_TYPE_INVALID); + SDL_DBus_CallVoidMethod("org.freedesktop.ScreenSaver", "/org/freedesktop/ScreenSaver", "org.freedesktop.ScreenSaver", "SimulateUserActivity", DBUS_TYPE_INVALID); + } +} + +static SDL_bool SDL_DBus_AppendDictWithKeyValue(DBusMessageIter *iterInit, const char *key, const char *value) +{ + DBusMessageIter iterDict, iterEntry, iterValue; + + if (!dbus.message_iter_open_container(iterInit, DBUS_TYPE_ARRAY, "{sv}", &iterDict)) { + goto failed; + } + + if (!dbus.message_iter_open_container(&iterDict, DBUS_TYPE_DICT_ENTRY, NULL, &iterEntry)) { + goto failed; + } + + if (!dbus.message_iter_append_basic(&iterEntry, DBUS_TYPE_STRING, &key)) { + goto failed; + } + + if (!dbus.message_iter_open_container(&iterEntry, DBUS_TYPE_VARIANT, DBUS_TYPE_STRING_AS_STRING, &iterValue)) { + goto failed; + } + + if (!dbus.message_iter_append_basic(&iterValue, DBUS_TYPE_STRING, &value)) { + goto failed; + } + + if (!dbus.message_iter_close_container(&iterEntry, &iterValue) || !dbus.message_iter_close_container(&iterDict, &iterEntry) || !dbus.message_iter_close_container(iterInit, &iterDict)) { + goto failed; + } + + return SDL_TRUE; + +failed: + /* message_iter_abandon_container_if_open() and message_iter_abandon_container() might be + * missing if libdbus is too old. Instead, we just return without cleaning up any eventual + * open container */ + return SDL_FALSE; +} + +SDL_bool SDL_DBus_ScreensaverInhibit(SDL_bool inhibit) +{ + const char *default_inhibit_reason = "Playing a game"; + + if ((inhibit && (screensaver_cookie != 0 || inhibit_handle)) || (!inhibit && (screensaver_cookie == 0 && !inhibit_handle))) { + return SDL_TRUE; + } + + if (!dbus.session_conn) { + /* We either lost connection to the session bus or were not able to + * load the D-Bus library at all. */ + return SDL_FALSE; + } + + if (SDL_DetectSandbox() != SDL_SANDBOX_NONE) { + const char *bus_name = "org.freedesktop.portal.Desktop"; + const char *path = "/org/freedesktop/portal/desktop"; + const char *interface = "org.freedesktop.portal.Inhibit"; + const char *window = ""; /* As a future improvement we could gather the X11 XID or Wayland surface identifier */ + static const unsigned int INHIBIT_IDLE = 8; /* Taken from the portal API reference */ + DBusMessageIter iterInit; + + if (inhibit) { + DBusMessage *msg; + SDL_bool retval = SDL_FALSE; + const char *key = "reason"; + const char *reply = NULL; + const char *reason = SDL_GetHint(SDL_HINT_SCREENSAVER_INHIBIT_ACTIVITY_NAME); + if (!reason || !reason[0]) { + reason = default_inhibit_reason; + } + + msg = dbus.message_new_method_call(bus_name, path, interface, "Inhibit"); + if (!msg) { + return SDL_FALSE; + } + + if (!dbus.message_append_args(msg, DBUS_TYPE_STRING, &window, DBUS_TYPE_UINT32, &INHIBIT_IDLE, DBUS_TYPE_INVALID)) { + dbus.message_unref(msg); + return SDL_FALSE; + } + + dbus.message_iter_init_append(msg, &iterInit); + if (!SDL_DBus_AppendDictWithKeyValue(&iterInit, key, reason)) { + dbus.message_unref(msg); + return SDL_FALSE; + } + + if (SDL_DBus_CallWithBasicReply(dbus.session_conn, msg, DBUS_TYPE_OBJECT_PATH, &reply)) { + inhibit_handle = SDL_strdup(reply); + retval = SDL_TRUE; + } + + dbus.message_unref(msg); + return retval; + } else { + if (!SDL_DBus_CallVoidMethod(bus_name, inhibit_handle, "org.freedesktop.portal.Request", "Close", DBUS_TYPE_INVALID)) { + return SDL_FALSE; + } + SDL_free(inhibit_handle); + inhibit_handle = NULL; + } + } else { + const char *bus_name = "org.freedesktop.ScreenSaver"; + const char *path = "/org/freedesktop/ScreenSaver"; + const char *interface = "org.freedesktop.ScreenSaver"; + + if (inhibit) { + const char *app = SDL_GetHint(SDL_HINT_APP_NAME); + const char *reason = SDL_GetHint(SDL_HINT_SCREENSAVER_INHIBIT_ACTIVITY_NAME); + if (!app || !app[0]) { + app = "My SDL application"; + } + if (!reason || !reason[0]) { + reason = default_inhibit_reason; + } + + if (!SDL_DBus_CallMethod(bus_name, path, interface, "Inhibit", + DBUS_TYPE_STRING, &app, DBUS_TYPE_STRING, &reason, DBUS_TYPE_INVALID, + DBUS_TYPE_UINT32, &screensaver_cookie, DBUS_TYPE_INVALID)) { + return SDL_FALSE; + } + return (screensaver_cookie != 0) ? SDL_TRUE : SDL_FALSE; + } else { + if (!SDL_DBus_CallVoidMethod(bus_name, path, interface, "UnInhibit", DBUS_TYPE_UINT32, &screensaver_cookie, DBUS_TYPE_INVALID)) { + return SDL_FALSE; + } + screensaver_cookie = 0; + } + } + + return SDL_TRUE; +} + +/* + * Get the machine ID if possible. Result must be freed with dbus->free(). + */ +char *SDL_DBus_GetLocalMachineId(void) +{ + DBusError err; + char *result; + + dbus.error_init(&err); + + if (dbus.try_get_local_machine_id) { + /* Available since dbus 1.12.0, has proper error-handling */ + result = dbus.try_get_local_machine_id(&err); + } else { + /* Available since time immemorial, but has no error-handling: + * if the machine ID can't be read, many versions of libdbus will + * treat that as a fatal mis-installation and abort() */ + result = dbus.get_local_machine_id(); + } + + if (result) { + return result; + } + + if (dbus.error_is_set(&err)) { + SDL_SetError("%s: %s", err.name, err.message); + dbus.error_free(&err); + } else { + SDL_SetError("Error getting D-Bus machine ID"); + } + + return NULL; +} + +/* + * Convert file drops with mime type "application/vnd.portal.filetransfer" to file paths + * Result must be freed with dbus->free_string_array(). + * https://flatpak.github.io/xdg-desktop-portal/#gdbus-method-org-freedesktop-portal-FileTransfer.RetrieveFiles + */ +char **SDL_DBus_DocumentsPortalRetrieveFiles(const char *key, int *path_count) +{ + DBusError err; + DBusMessageIter iter, iterDict; + char **paths = NULL; + DBusMessage *reply = NULL; + DBusMessage *msg = dbus.message_new_method_call("org.freedesktop.portal.Documents", /* Node */ + "/org/freedesktop/portal/documents", /* Path */ + "org.freedesktop.portal.FileTransfer", /* Interface */ + "RetrieveFiles"); /* Method */ + + /* Make sure we have a connection to the dbus session bus */ + if (!SDL_DBus_GetContext() || !dbus.session_conn) { + /* We either cannot connect to the session bus or were unable to + * load the D-Bus library at all. */ + return NULL; + } + + dbus.error_init(&err); + + /* First argument is a "application/vnd.portal.filetransfer" key from a DnD or clipboard event */ + if (!dbus.message_append_args(msg, DBUS_TYPE_STRING, &key, DBUS_TYPE_INVALID)) { + SDL_OutOfMemory(); + dbus.message_unref(msg); + goto failed; + } + + /* Second argument is a variant dictionary for options. + * The spec doesn't define any entries yet so it's empty. */ + dbus.message_iter_init_append(msg, &iter); + if (!dbus.message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &iterDict) || + !dbus.message_iter_close_container(&iter, &iterDict)) { + SDL_OutOfMemory(); + dbus.message_unref(msg); + goto failed; + } + + reply = dbus.connection_send_with_reply_and_block(dbus.session_conn, msg, DBUS_TIMEOUT_USE_DEFAULT, &err); + dbus.message_unref(msg); + + if (reply) { + dbus.message_get_args(reply, &err, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &paths, path_count, DBUS_TYPE_INVALID); + dbus.message_unref(reply); + } + + if (paths) { + return paths; + } + +failed: + if (dbus.error_is_set(&err)) { + SDL_SetError("%s: %s", err.name, err.message); + dbus.error_free(&err); + } else { + SDL_SetError("Error retrieving paths for documents portal \"%s\"", key); + } + + return NULL; +} +#endif + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/core/linux/SDL_dbus.h b/SDL2-2.30.5/src/core/linux/SDL_dbus.h similarity index 81% rename from SDL2-2.0.12/src/core/linux/SDL_dbus.h rename to SDL2-2.30.5/src/core/linux/SDL_dbus.h index 6967cc9..572ea47 100644 --- a/SDL2-2.0.12/src/core/linux/SDL_dbus.h +++ b/SDL2-2.30.5/src/core/linux/SDL_dbus.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -29,43 +29,54 @@ #include "SDL_stdinc.h" #include +#ifndef DBUS_TIMEOUT_USE_DEFAULT +#define DBUS_TIMEOUT_USE_DEFAULT -1 +#endif -typedef struct SDL_DBusContext { +typedef struct SDL_DBusContext +{ DBusConnection *session_conn; DBusConnection *system_conn; DBusConnection *(*bus_get_private)(DBusBusType, DBusError *); dbus_bool_t (*bus_register)(DBusConnection *, DBusError *); void (*bus_add_match)(DBusConnection *, const char *, DBusError *); - DBusConnection * (*connection_open_private)(const char *, DBusError *); + DBusConnection *(*connection_open_private)(const char *, DBusError *); void (*connection_set_exit_on_disconnect)(DBusConnection *, dbus_bool_t); dbus_bool_t (*connection_get_is_connected)(DBusConnection *); dbus_bool_t (*connection_add_filter)(DBusConnection *, DBusHandleMessageFunction, void *, DBusFreeFunction); dbus_bool_t (*connection_try_register_object_path)(DBusConnection *, const char *, - const DBusObjectPathVTable *, void *, DBusError *); + const DBusObjectPathVTable *, void *, DBusError *); dbus_bool_t (*connection_send)(DBusConnection *, DBusMessage *, dbus_uint32_t *); DBusMessage *(*connection_send_with_reply_and_block)(DBusConnection *, DBusMessage *, int, DBusError *); void (*connection_close)(DBusConnection *); + void (*connection_ref)(DBusConnection *); void (*connection_unref)(DBusConnection *); void (*connection_flush)(DBusConnection *); dbus_bool_t (*connection_read_write)(DBusConnection *, int); DBusDispatchStatus (*connection_dispatch)(DBusConnection *); - dbus_bool_t (*message_is_signal)(DBusMessage *, const char *, const char *); + dbus_bool_t (*message_is_signal)(DBusMessage *, const char *, const char *); DBusMessage *(*message_new_method_call)(const char *, const char *, const char *, const char *); dbus_bool_t (*message_append_args)(DBusMessage *, int, ...); dbus_bool_t (*message_append_args_valist)(DBusMessage *, int, va_list); + void (*message_iter_init_append)(DBusMessage *, DBusMessageIter *); + dbus_bool_t (*message_iter_open_container)(DBusMessageIter *, int, const char *, DBusMessageIter *); + dbus_bool_t (*message_iter_append_basic)(DBusMessageIter *, int, const void *); + dbus_bool_t (*message_iter_close_container)(DBusMessageIter *, DBusMessageIter *); dbus_bool_t (*message_get_args)(DBusMessage *, DBusError *, int, ...); dbus_bool_t (*message_get_args_valist)(DBusMessage *, DBusError *, int, va_list); dbus_bool_t (*message_iter_init)(DBusMessage *, DBusMessageIter *); dbus_bool_t (*message_iter_next)(DBusMessageIter *); void (*message_iter_get_basic)(DBusMessageIter *, void *); int (*message_iter_get_arg_type)(DBusMessageIter *); - void (*message_iter_recurse)(DBusMessageIter *, DBusMessageIter *); + void (*message_iter_recurse)(DBusMessageIter *, DBusMessageIter *); void (*message_unref)(DBusMessage *); + dbus_bool_t (*threads_init_default)(void); void (*error_init)(DBusError *); dbus_bool_t (*error_is_set)(const DBusError *); void (*error_free)(DBusError *); char *(*get_local_machine_id)(void); + char *(*try_get_local_machine_id)(DBusError *); void (*free)(void *); void (*free_string_array)(char **); void (*shutdown)(void); @@ -74,7 +85,7 @@ typedef struct SDL_DBusContext { extern void SDL_DBus_Init(void); extern void SDL_DBus_Quit(void); -extern SDL_DBusContext * SDL_DBus_GetContext(void); +extern SDL_DBusContext *SDL_DBus_GetContext(void); /* These use the built-in Session connection. */ extern SDL_bool SDL_DBus_CallMethod(const char *node, const char *path, const char *interface, const char *method, ...); @@ -89,6 +100,10 @@ extern SDL_bool SDL_DBus_QueryPropertyOnConnection(DBusConnection *conn, const c extern void SDL_DBus_ScreensaverTickle(void); extern SDL_bool SDL_DBus_ScreensaverInhibit(SDL_bool inhibit); +extern char *SDL_DBus_GetLocalMachineId(void); + +extern char **SDL_DBus_DocumentsPortalRetrieveFiles(const char *key, int *files_count); + #endif /* HAVE_DBUS_DBUS_H */ #endif /* SDL_dbus_h_ */ diff --git a/SDL2-2.0.12/src/core/linux/SDL_evdev.c b/SDL2-2.30.5/src/core/linux/SDL_evdev.c similarity index 63% rename from SDL2-2.0.12/src/core/linux/SDL_evdev.c rename to SDL2-2.30.5/src/core/linux/SDL_evdev.c index f7c376a..e3b836c 100644 --- a/SDL2-2.0.12/src/core/linux/SDL_evdev.c +++ b/SDL2-2.30.5/src/core/linux/SDL_evdev.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,7 +23,7 @@ #ifdef SDL_INPUT_LINUXEV /* This is based on the linux joystick driver */ -/* References: https://www.kernel.org/doc/Documentation/input/input.txt +/* References: https://www.kernel.org/doc/Documentation/input/input.txt * https://www.kernel.org/doc/Documentation/input/event-codes.txt * /usr/include/linux/input.h * The evtest application is also useful to debug the protocol @@ -39,11 +39,11 @@ #include #include "SDL.h" -#include "SDL_assert.h" #include "SDL_endian.h" #include "SDL_scancode.h" #include "../../events/SDL_events_c.h" -#include "../../events/scancodes_linux.h" /* adds linux_scancode_table */ +#include "../../events/SDL_scancode_tables_c.h" +#include "../../core/linux/SDL_evdev_capabilities.h" #include "../../core/linux/SDL_udev.h" /* These are not defined in older Linux kernel headers */ @@ -51,27 +51,33 @@ #define SYN_DROPPED 3 #endif #ifndef ABS_MT_SLOT -#define ABS_MT_SLOT 0x2f -#define ABS_MT_POSITION_X 0x35 -#define ABS_MT_POSITION_Y 0x36 -#define ABS_MT_TRACKING_ID 0x39 -#define ABS_MT_PRESSURE 0x3a +#define ABS_MT_SLOT 0x2f +#define ABS_MT_POSITION_X 0x35 +#define ABS_MT_POSITION_Y 0x36 +#define ABS_MT_TRACKING_ID 0x39 +#define ABS_MT_PRESSURE 0x3a +#endif +#ifndef REL_WHEEL_HI_RES +#define REL_WHEEL_HI_RES 0x0b +#define REL_HWHEEL_HI_RES 0x0c #endif typedef struct SDL_evdevlist_item { char *path; int fd; + int udev_class; /* TODO: use this for every device, not just touchscreen */ - int out_of_sync; + SDL_bool out_of_sync; /* TODO: expand on this to have data for every possible class (mouse, keyboard, touchpad, etc.). Also there's probably some things in here we can pull out to the SDL_evdevlist_item i.e. name */ - int is_touchscreen; - struct { - char* name; + SDL_bool is_touchscreen; + struct + { + char *name; int min_x, max_x, range_x; int min_y, max_y, range_y; @@ -79,8 +85,10 @@ typedef struct SDL_evdevlist_item int max_slots; int current_slot; - struct { - enum { + struct + { + enum + { EVDEV_TOUCH_SLOTDELTA_NONE = 0, EVDEV_TOUCH_SLOTDELTA_DOWN, EVDEV_TOUCH_SLOTDELTA_UP, @@ -88,9 +96,18 @@ typedef struct SDL_evdevlist_item } delta; int tracking_id; int x, y, pressure; - } * slots; + } *slots; - } * touchscreen_data; + } *touchscreen_data; + + /* Mouse state */ + SDL_bool high_res_wheel; + SDL_bool high_res_hwheel; + SDL_bool relative_mouse; + int mouse_x, mouse_y; + int mouse_wheel, mouse_hwheel; + int min_x, max_x, range_x; + int min_y, max_y, range_y; struct SDL_evdevlist_item *next; } SDL_evdevlist_item; @@ -112,41 +129,46 @@ static SDL_Scancode SDL_EVDEV_translate_keycode(int keycode); static void SDL_EVDEV_sync_device(SDL_evdevlist_item *item); static int SDL_EVDEV_device_removed(const char *dev_path); -#if SDL_USE_LIBUDEV static int SDL_EVDEV_device_added(const char *dev_path, int udev_class); -static void SDL_EVDEV_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_class, - const char *dev_path); +#ifdef SDL_USE_LIBUDEV +static void SDL_EVDEV_udev_callback(SDL_UDEV_deviceevent udev_event, int udev_class, const char *dev_path); #endif /* SDL_USE_LIBUDEV */ static Uint8 EVDEV_MouseButtons[] = { - SDL_BUTTON_LEFT, /* BTN_LEFT 0x110 */ - SDL_BUTTON_RIGHT, /* BTN_RIGHT 0x111 */ - SDL_BUTTON_MIDDLE, /* BTN_MIDDLE 0x112 */ - SDL_BUTTON_X1, /* BTN_SIDE 0x113 */ - SDL_BUTTON_X2, /* BTN_EXTRA 0x114 */ - SDL_BUTTON_X2 + 1, /* BTN_FORWARD 0x115 */ - SDL_BUTTON_X2 + 2, /* BTN_BACK 0x116 */ - SDL_BUTTON_X2 + 3 /* BTN_TASK 0x117 */ + SDL_BUTTON_LEFT, /* BTN_LEFT 0x110 */ + SDL_BUTTON_RIGHT, /* BTN_RIGHT 0x111 */ + SDL_BUTTON_MIDDLE, /* BTN_MIDDLE 0x112 */ + SDL_BUTTON_X1, /* BTN_SIDE 0x113 */ + SDL_BUTTON_X2, /* BTN_EXTRA 0x114 */ + SDL_BUTTON_X2 + 1, /* BTN_FORWARD 0x115 */ + SDL_BUTTON_X2 + 2, /* BTN_BACK 0x116 */ + SDL_BUTTON_X2 + 3 /* BTN_TASK 0x117 */ }; -static int -SDL_EVDEV_SetRelativeMouseMode(SDL_bool enabled) +static int SDL_EVDEV_SetRelativeMouseMode(SDL_bool enabled) { /* Mice already send relative events through this interface */ return 0; } - -int -SDL_EVDEV_Init(void) +static void SDL_EVDEV_UpdateKeyboardMute(void) { - if (_this == NULL) { - _this = (SDL_EVDEV_PrivateData*)SDL_calloc(1, sizeof(*_this)); - if (_this == NULL) { + if (SDL_EVDEV_GetDeviceCount(SDL_UDEV_DEVICE_KEYBOARD) > 0) { + SDL_EVDEV_kbd_set_muted(_this->kbd, SDL_TRUE); + } else { + SDL_EVDEV_kbd_set_muted(_this->kbd, SDL_FALSE); + } +} + +int SDL_EVDEV_Init(void) +{ + if (!_this) { + _this = (SDL_EVDEV_PrivateData *)SDL_calloc(1, sizeof(*_this)); + if (!_this) { return SDL_OutOfMemory(); } -#if SDL_USE_LIBUDEV +#ifdef SDL_USE_LIBUDEV if (SDL_UDEV_Init() < 0) { SDL_free(_this); _this = NULL; @@ -164,10 +186,35 @@ SDL_EVDEV_Init(void) /* Force a scan to build the initial device list */ SDL_UDEV_Scan(); #else - /* TODO: Scan the devices manually, like a caveman */ + { + /* Allow the user to specify a list of devices explicitly of + the form: + deviceclass:path[,deviceclass:path[,...]] + where device class is an integer representing the + SDL_UDEV_deviceclass and path is the full path to + the event device. */ + const char *devices = SDL_getenv("SDL_EVDEV_DEVICES"); + if (devices) { + /* Assume this is the old use of the env var and it is not in + ROM. */ + char *rest = (char *)devices; + char *spec; + while ((spec = SDL_strtokr(rest, ",", &rest))) { + char *endofcls = 0; + long cls = SDL_strtol(spec, &endofcls, 0); + if (endofcls) { + SDL_EVDEV_device_added(endofcls + 1, cls); + } + } + } else { + /* TODO: Scan the devices manually, like a caveman */ + } + } #endif /* SDL_USE_LIBUDEV */ _this->kbd = SDL_EVDEV_kbd_init(); + + SDL_EVDEV_UpdateKeyboardMute(); } SDL_GetMouse()->SetRelativeMouseMode = SDL_EVDEV_SetRelativeMouseMode; @@ -177,28 +224,27 @@ SDL_EVDEV_Init(void) return 0; } -void -SDL_EVDEV_Quit(void) +void SDL_EVDEV_Quit(void) { - if (_this == NULL) { + if (!_this) { return; } _this->ref_count -= 1; if (_this->ref_count < 1) { -#if SDL_USE_LIBUDEV +#ifdef SDL_USE_LIBUDEV SDL_UDEV_DelCallback(SDL_EVDEV_udev_callback); SDL_UDEV_Quit(); #endif /* SDL_USE_LIBUDEV */ - SDL_EVDEV_kbd_quit(_this->kbd); - /* Remove existing devices */ - while(_this->first != NULL) { + while (_this->first) { SDL_EVDEV_device_removed(_this->first->path); } + SDL_EVDEV_kbd_quit(_this->kbd); + SDL_assert(_this->first == NULL); SDL_assert(_this->last == NULL); SDL_assert(_this->num_devices == 0); @@ -208,22 +254,26 @@ SDL_EVDEV_Quit(void) } } -#if SDL_USE_LIBUDEV +#ifdef SDL_USE_LIBUDEV static void SDL_EVDEV_udev_callback(SDL_UDEV_deviceevent udev_event, int udev_class, - const char* dev_path) + const char *dev_path) { - if (dev_path == NULL) { + if (!dev_path) { return; } - switch(udev_event) { + switch (udev_event) { case SDL_UDEV_DEVICEADDED: - if (!(udev_class & (SDL_UDEV_DEVICE_MOUSE | SDL_UDEV_DEVICE_KEYBOARD | - SDL_UDEV_DEVICE_TOUCHSCREEN))) + if (!(udev_class & (SDL_UDEV_DEVICE_MOUSE | SDL_UDEV_DEVICE_KEYBOARD | SDL_UDEV_DEVICE_TOUCHSCREEN | SDL_UDEV_DEVICE_TOUCHPAD))) { return; + } + + if (udev_class & SDL_UDEV_DEVICE_JOYSTICK) { + return; + } SDL_EVDEV_device_added(dev_path, udev_class); - break; + break; case SDL_UDEV_DEVICEREMOVED: SDL_EVDEV_device_removed(dev_path); break; @@ -233,8 +283,28 @@ static void SDL_EVDEV_udev_callback(SDL_UDEV_deviceevent udev_event, int udev_cl } #endif /* SDL_USE_LIBUDEV */ -void -SDL_EVDEV_Poll(void) +void SDL_EVDEV_SetVTSwitchCallbacks(void (*release_callback)(void*), void *release_callback_data, + void (*acquire_callback)(void*), void *acquire_callback_data) +{ + SDL_EVDEV_kbd_set_vt_switch_callbacks(_this->kbd, + release_callback, release_callback_data, + acquire_callback, acquire_callback_data); +} + +int SDL_EVDEV_GetDeviceCount(int device_class) +{ + SDL_evdevlist_item *item; + int count = 0; + + for (item = _this->first; item; item = item->next) { + if ((item->udev_class & device_class) == device_class) { + ++count; + } + } + return count; +} + +void SDL_EVDEV_Poll(void) { struct input_event events[32]; int i, j, len; @@ -248,14 +318,16 @@ SDL_EVDEV_Poll(void) return; } -#if SDL_USE_LIBUDEV +#ifdef SDL_USE_LIBUDEV SDL_UDEV_Poll(); #endif + SDL_EVDEV_kbd_update(_this->kbd); + mouse = SDL_GetMouse(); - for (item = _this->first; item != NULL; item = item->next) { - while ((len = read(item->fd, events, (sizeof events))) > 0) { + for (item = _this->first; item; item = item->next) { + while ((len = read(item->fd, events, sizeof(events))) > 0) { len /= sizeof(events[0]); for (i = 0; i < len; ++i) { /* special handling for touchscreen, that should eventually be @@ -270,9 +342,9 @@ SDL_EVDEV_Poll(void) if (events[i].code >= BTN_MOUSE && events[i].code < BTN_MOUSE + SDL_arraysize(EVDEV_MouseButtons)) { mouse_button = events[i].code - BTN_MOUSE; if (events[i].value == 0) { - SDL_SendMouseButton(mouse->focus, mouse->mouseID, SDL_RELEASED, EVDEV_MouseButtons[mouse_button]); + SDL_SendMouseButton(mouse->focus, (SDL_MouseID)item->fd, SDL_RELEASED, EVDEV_MouseButtons[mouse_button]); } else if (events[i].value == 1) { - SDL_SendMouseButton(mouse->focus, mouse->mouseID, SDL_PRESSED, EVDEV_MouseButtons[mouse_button]); + SDL_SendMouseButton(mouse->focus, (SDL_MouseID)item->fd, SDL_PRESSED, EVDEV_MouseButtons[mouse_button]); } break; } @@ -283,10 +355,11 @@ SDL_EVDEV_Poll(void) next finger after earlist is released) */ if (item->is_touchscreen && events[i].code == BTN_TOUCH) { if (item->touchscreen_data->max_slots == 1) { - if (events[i].value) + if (events[i].value) { item->touchscreen_data->slots[0].delta = EVDEV_TOUCH_SLOTDELTA_DOWN; - else + } else { item->touchscreen_data->slots[0].delta = EVDEV_TOUCH_SLOTDELTA_UP; + } } break; } @@ -303,15 +376,17 @@ SDL_EVDEV_Poll(void) SDL_EVDEV_kbd_keycode(_this->kbd, events[i].code, events[i].value); break; case EV_ABS: - switch(events[i].code) { + switch (events[i].code) { case ABS_MT_SLOT: - if (!item->is_touchscreen) /* FIXME: temp hack */ + if (!item->is_touchscreen) { /* FIXME: temp hack */ break; + } item->touchscreen_data->current_slot = events[i].value; break; case ABS_MT_TRACKING_ID: - if (!item->is_touchscreen) /* FIXME: temp hack */ + if (!item->is_touchscreen) { /* FIXME: temp hack */ break; + } if (events[i].value >= 0) { item->touchscreen_data->slots[item->touchscreen_data->current_slot].tracking_id = events[i].value; item->touchscreen_data->slots[item->touchscreen_data->current_slot].delta = EVDEV_TOUCH_SLOTDELTA_DOWN; @@ -320,24 +395,27 @@ SDL_EVDEV_Poll(void) } break; case ABS_MT_POSITION_X: - if (!item->is_touchscreen) /* FIXME: temp hack */ + if (!item->is_touchscreen) { /* FIXME: temp hack */ break; + } item->touchscreen_data->slots[item->touchscreen_data->current_slot].x = events[i].value; if (item->touchscreen_data->slots[item->touchscreen_data->current_slot].delta == EVDEV_TOUCH_SLOTDELTA_NONE) { item->touchscreen_data->slots[item->touchscreen_data->current_slot].delta = EVDEV_TOUCH_SLOTDELTA_MOVE; } break; case ABS_MT_POSITION_Y: - if (!item->is_touchscreen) /* FIXME: temp hack */ + if (!item->is_touchscreen) { /* FIXME: temp hack */ break; + } item->touchscreen_data->slots[item->touchscreen_data->current_slot].y = events[i].value; if (item->touchscreen_data->slots[item->touchscreen_data->current_slot].delta == EVDEV_TOUCH_SLOTDELTA_NONE) { item->touchscreen_data->slots[item->touchscreen_data->current_slot].delta = EVDEV_TOUCH_SLOTDELTA_MOVE; } break; case ABS_MT_PRESSURE: - if (!item->is_touchscreen) /* FIXME: temp hack */ + if (!item->is_touchscreen) { /* FIXME: temp hack */ break; + } item->touchscreen_data->slots[item->touchscreen_data->current_slot].pressure = events[i].value; if (item->touchscreen_data->slots[item->touchscreen_data->current_slot].delta == EVDEV_TOUCH_SLOTDELTA_NONE) { item->touchscreen_data->slots[item->touchscreen_data->current_slot].delta = EVDEV_TOUCH_SLOTDELTA_MOVE; @@ -345,37 +423,57 @@ SDL_EVDEV_Poll(void) break; case ABS_X: if (item->is_touchscreen) { - if (item->touchscreen_data->max_slots != 1) + if (item->touchscreen_data->max_slots != 1) { break; + } item->touchscreen_data->slots[0].x = events[i].value; - } else - SDL_SendMouseMotion(mouse->focus, mouse->mouseID, SDL_FALSE, events[i].value, mouse->y); + } else if (!item->relative_mouse) { + item->mouse_x = events[i].value; + } break; case ABS_Y: if (item->is_touchscreen) { - if (item->touchscreen_data->max_slots != 1) + if (item->touchscreen_data->max_slots != 1) { break; + } item->touchscreen_data->slots[0].y = events[i].value; - } else - SDL_SendMouseMotion(mouse->focus, mouse->mouseID, SDL_FALSE, mouse->x, events[i].value); + } else if (!item->relative_mouse) { + item->mouse_y = events[i].value; + } break; default: break; } break; case EV_REL: - switch(events[i].code) { + switch (events[i].code) { case REL_X: - SDL_SendMouseMotion(mouse->focus, mouse->mouseID, SDL_TRUE, events[i].value, 0); + if (item->relative_mouse) { + item->mouse_x += events[i].value; + } break; case REL_Y: - SDL_SendMouseMotion(mouse->focus, mouse->mouseID, SDL_TRUE, 0, events[i].value); + if (item->relative_mouse) { + item->mouse_y += events[i].value; + } break; case REL_WHEEL: - SDL_SendMouseWheel(mouse->focus, mouse->mouseID, 0, events[i].value, SDL_MOUSEWHEEL_NORMAL); + if (!item->high_res_wheel) { + item->mouse_wheel += events[i].value; + } + break; + case REL_WHEEL_HI_RES: + SDL_assert(item->high_res_wheel); + item->mouse_wheel += events[i].value; break; case REL_HWHEEL: - SDL_SendMouseWheel(mouse->focus, mouse->mouseID, events[i].value, 0, SDL_MOUSEWHEEL_NORMAL); + if (!item->high_res_hwheel) { + item->mouse_hwheel += events[i].value; + } + break; + case REL_HWHEEL_HI_RES: + SDL_assert(item->high_res_hwheel); + item->mouse_hwheel += events[i].value; break; default: break; @@ -384,18 +482,42 @@ SDL_EVDEV_Poll(void) case EV_SYN: switch (events[i].code) { case SYN_REPORT: - if (!item->is_touchscreen) /* FIXME: temp hack */ - break; + /* Send mouse axis changes together to ensure consistency and reduce event processing overhead */ + if (item->relative_mouse) { + if (item->mouse_x != 0 || item->mouse_y != 0) { + SDL_SendMouseMotion(mouse->focus, (SDL_MouseID)item->fd, item->relative_mouse, item->mouse_x, item->mouse_y); + item->mouse_x = item->mouse_y = 0; + } + } else if (item->range_x > 0 && item->range_y > 0) { + /* TODO: test with multiple display scenarios */ + SDL_DisplayMode mode; + SDL_GetCurrentDisplayMode(0, &mode); + SDL_SendMouseMotion(mouse->focus, (SDL_MouseID)item->fd, item->relative_mouse, + (item->mouse_x - item->min_x) * mode.w / item->range_x, + (item->mouse_y - item->min_y) * mode.h / item->range_y); + } - for(j = 0; j < item->touchscreen_data->max_slots; j++) { + if (item->mouse_wheel != 0 || item->mouse_hwheel != 0) { + SDL_SendMouseWheel(mouse->focus, (SDL_MouseID)item->fd, + item->mouse_hwheel / (item->high_res_hwheel ? 120.0f : 1.0f), + item->mouse_wheel / (item->high_res_wheel ? 120.0f : 1.0f), + SDL_MOUSEWHEEL_NORMAL); + item->mouse_wheel = item->mouse_hwheel = 0; + } + + if (!item->is_touchscreen) { /* FIXME: temp hack */ + break; + } + + for (j = 0; j < item->touchscreen_data->max_slots; j++) { norm_x = (float)(item->touchscreen_data->slots[j].x - item->touchscreen_data->min_x) / - (float)item->touchscreen_data->range_x; + (float)item->touchscreen_data->range_x; norm_y = (float)(item->touchscreen_data->slots[j].y - item->touchscreen_data->min_y) / - (float)item->touchscreen_data->range_y; + (float)item->touchscreen_data->range_y; if (item->touchscreen_data->range_pressure > 0) { norm_pressure = (float)(item->touchscreen_data->slots[j].pressure - item->touchscreen_data->min_pressure) / - (float)item->touchscreen_data->range_pressure; + (float)item->touchscreen_data->range_pressure; } else { /* This touchscreen does not support pressure */ norm_pressure = 1.0f; @@ -404,7 +526,7 @@ SDL_EVDEV_Poll(void) /* FIXME: the touch's window shouldn't be null, but * the coordinate space of touch positions needs to * be window-relative in that case. */ - switch(item->touchscreen_data->slots[j].delta) { + switch (item->touchscreen_data->slots[j].delta) { case EVDEV_TOUCH_SLOTDELTA_DOWN: SDL_SendTouch(item->fd, item->touchscreen_data->slots[j].tracking_id, NULL, SDL_TRUE, norm_x, norm_y, norm_pressure); item->touchscreen_data->slots[j].delta = EVDEV_TOUCH_SLOTDELTA_NONE; @@ -423,12 +545,14 @@ SDL_EVDEV_Poll(void) } } - if (item->out_of_sync) - item->out_of_sync = 0; + if (item->out_of_sync) { + item->out_of_sync = SDL_FALSE; + } break; case SYN_DROPPED: - if (item->is_touchscreen) - item->out_of_sync = 1; + if (item->is_touchscreen) { + item->out_of_sync = SDL_TRUE; + } SDL_EVDEV_sync_device(item); break; default: @@ -437,49 +561,73 @@ SDL_EVDEV_Poll(void) break; } } - } + } } } -static SDL_Scancode -SDL_EVDEV_translate_keycode(int keycode) +static SDL_Scancode SDL_EVDEV_translate_keycode(int keycode) { - SDL_Scancode scancode = SDL_SCANCODE_UNKNOWN; + SDL_Scancode scancode = SDL_GetScancodeFromTable(SDL_SCANCODE_TABLE_LINUX, keycode); - if (keycode < SDL_arraysize(linux_scancode_table)) { - scancode = linux_scancode_table[keycode]; - - if (scancode == SDL_SCANCODE_UNKNOWN) { - /* BTN_TOUCH is handled elsewhere, but we might still end up here if - you get an unexpected BTN_TOUCH from something SDL believes is not - a touch device. In this case, we'd rather not get a misleading - SDL_Log message about an unknown key. */ - if (keycode != BTN_TOUCH) { - SDL_Log("The key you just pressed is not recognized by SDL. To help " +#ifdef DEBUG_SCANCODES + if (scancode == SDL_SCANCODE_UNKNOWN) { + /* BTN_TOUCH is handled elsewhere, but we might still end up here if + you get an unexpected BTN_TOUCH from something SDL believes is not + a touch device. In this case, we'd rather not get a misleading + SDL_Log message about an unknown key. */ + if (keycode != BTN_TOUCH) { + SDL_Log("The key you just pressed is not recognized by SDL. To help " "get this fixed, please report this to the SDL forums/mailing list " - " EVDEV KeyCode %d", keycode); - } + " EVDEV KeyCode %d", + keycode); } } +#endif /* DEBUG_SCANCODES */ return scancode; } -#ifdef SDL_USE_LIBUDEV -static int -SDL_EVDEV_init_touchscreen(SDL_evdevlist_item* item) +static int SDL_EVDEV_init_mouse(SDL_evdevlist_item *item, int udev_class) +{ + int ret; + struct input_absinfo abs_info; + + ret = ioctl(item->fd, EVIOCGABS(ABS_X), &abs_info); + if (ret < 0) { + // no absolute mode info, continue + return 0; + } + item->min_x = abs_info.minimum; + item->max_x = abs_info.maximum; + item->range_x = abs_info.maximum - abs_info.minimum; + + ret = ioctl(item->fd, EVIOCGABS(ABS_Y), &abs_info); + if (ret < 0) { + // no absolute mode info, continue + return 0; + } + item->min_y = abs_info.minimum; + item->max_y = abs_info.maximum; + item->range_y = abs_info.maximum - abs_info.minimum; + + return 0; +} + +static int SDL_EVDEV_init_touchscreen(SDL_evdevlist_item *item, int udev_class) { int ret, i; unsigned long xreq, yreq; char name[64]; struct input_absinfo abs_info; - if (!item->is_touchscreen) + if (!item->is_touchscreen) { return 0; + } item->touchscreen_data = SDL_calloc(1, sizeof(*item->touchscreen_data)); - if (item->touchscreen_data == NULL) + if (!item->touchscreen_data) { return SDL_OutOfMemory(); + } ret = ioctl(item->fd, EVIOCGNAME(sizeof(name)), name); if (ret < 0) { @@ -488,7 +636,7 @@ SDL_EVDEV_init_touchscreen(SDL_evdevlist_item* item) } item->touchscreen_data->name = SDL_strdup(name); - if (item->touchscreen_data->name == NULL) { + if (!item->touchscreen_data->name) { SDL_free(item->touchscreen_data); return SDL_OutOfMemory(); } @@ -543,19 +691,19 @@ SDL_EVDEV_init_touchscreen(SDL_evdevlist_item* item) item->touchscreen_data->slots = SDL_calloc( item->touchscreen_data->max_slots, sizeof(*item->touchscreen_data->slots)); - if (item->touchscreen_data->slots == NULL) { + if (!item->touchscreen_data->slots) { SDL_free(item->touchscreen_data->name); SDL_free(item->touchscreen_data); return SDL_OutOfMemory(); } - for(i = 0; i < item->touchscreen_data->max_slots; i++) { + for (i = 0; i < item->touchscreen_data->max_slots; i++) { item->touchscreen_data->slots[i].tracking_id = -1; } ret = SDL_AddTouch(item->fd, /* I guess our fd is unique enough */ - SDL_TOUCH_DEVICE_DIRECT, - item->touchscreen_data->name); + (udev_class & SDL_UDEV_DEVICE_TOUCHPAD) ? SDL_TOUCH_DEVICE_INDIRECT_ABSOLUTE : SDL_TOUCH_DEVICE_DIRECT, + item->touchscreen_data->name); if (ret < 0) { SDL_free(item->touchscreen_data->slots); SDL_free(item->touchscreen_data->name); @@ -565,12 +713,12 @@ SDL_EVDEV_init_touchscreen(SDL_evdevlist_item* item) return 0; } -#endif /* SDL_USE_LIBUDEV */ -static void -SDL_EVDEV_destroy_touchscreen(SDL_evdevlist_item* item) { - if (!item->is_touchscreen) +static void SDL_EVDEV_destroy_touchscreen(SDL_evdevlist_item *item) +{ + if (!item->is_touchscreen) { return; + } SDL_DelTouch(item->fd); SDL_free(item->touchscreen_data->slots); @@ -578,8 +726,7 @@ SDL_EVDEV_destroy_touchscreen(SDL_evdevlist_item* item) { SDL_free(item->touchscreen_data); } -static void -SDL_EVDEV_sync_device(SDL_evdevlist_item *item) +static void SDL_EVDEV_sync_device(SDL_evdevlist_item *item) { #ifdef EVIOCGMTSLOTS int i, ret; @@ -592,23 +739,24 @@ SDL_EVDEV_sync_device(SDL_evdevlist_item *item) * * this is the structure we're trying to emulate */ - Uint32* mt_req_code; - Sint32* mt_req_values; + Uint32 *mt_req_code; + Sint32 *mt_req_values; size_t mt_req_size; /* TODO: sync devices other than touchscreen */ - if (!item->is_touchscreen) - return; - - mt_req_size = sizeof(*mt_req_code) + - sizeof(*mt_req_values) * item->touchscreen_data->max_slots; - - mt_req_code = SDL_calloc(1, mt_req_size); - if (mt_req_code == NULL) { + if (!item->is_touchscreen) { return; } - mt_req_values = (Sint32*)mt_req_code + 1; + mt_req_size = sizeof(*mt_req_code) + + sizeof(*mt_req_values) * item->touchscreen_data->max_slots; + + mt_req_code = SDL_calloc(1, mt_req_size); + if (!mt_req_code) { + return; + } + + mt_req_values = (Sint32 *)mt_req_code + 1; *mt_req_code = ABS_MT_TRACKING_ID; ret = ioctl(item->fd, EVIOCGMTSLOTS(mt_req_size), mt_req_code); @@ -616,7 +764,7 @@ SDL_EVDEV_sync_device(SDL_evdevlist_item *item) SDL_free(mt_req_code); return; } - for(i = 0; i < item->touchscreen_data->max_slots; i++) { + for (i = 0; i < item->touchscreen_data->max_slots; i++) { /* * This doesn't account for the very edge case of the user removing their * finger and replacing it on the screen during the time we're out of sync, @@ -631,7 +779,7 @@ SDL_EVDEV_sync_device(SDL_evdevlist_item *item) item->touchscreen_data->slots[i].tracking_id = mt_req_values[i]; item->touchscreen_data->slots[i].delta = EVDEV_TOUCH_SLOTDELTA_DOWN; } else if (item->touchscreen_data->slots[i].tracking_id >= 0 && - mt_req_values[i] < 0) { + mt_req_values[i] < 0) { item->touchscreen_data->slots[i].tracking_id = -1; item->touchscreen_data->slots[i].delta = EVDEV_TOUCH_SLOTDELTA_UP; } @@ -643,7 +791,7 @@ SDL_EVDEV_sync_device(SDL_evdevlist_item *item) SDL_free(mt_req_code); return; } - for(i = 0; i < item->touchscreen_data->max_slots; i++) { + for (i = 0; i < item->touchscreen_data->max_slots; i++) { if (item->touchscreen_data->slots[i].tracking_id >= 0 && item->touchscreen_data->slots[i].x != mt_req_values[i]) { item->touchscreen_data->slots[i].x = mt_req_values[i]; @@ -661,7 +809,7 @@ SDL_EVDEV_sync_device(SDL_evdevlist_item *item) SDL_free(mt_req_code); return; } - for(i = 0; i < item->touchscreen_data->max_slots; i++) { + for (i = 0; i < item->touchscreen_data->max_slots; i++) { if (item->touchscreen_data->slots[i].tracking_id >= 0 && item->touchscreen_data->slots[i].y != mt_req_values[i]) { item->touchscreen_data->slots[i].y = mt_req_values[i]; @@ -679,7 +827,7 @@ SDL_EVDEV_sync_device(SDL_evdevlist_item *item) SDL_free(mt_req_code); return; } - for(i = 0; i < item->touchscreen_data->max_slots; i++) { + for (i = 0; i < item->touchscreen_data->max_slots; i++) { if (item->touchscreen_data->slots[i].tracking_id >= 0 && item->touchscreen_data->slots[i].pressure != mt_req_values[i]) { item->touchscreen_data->slots[i].pressure = mt_req_values[i]; @@ -703,49 +851,66 @@ SDL_EVDEV_sync_device(SDL_evdevlist_item *item) #endif /* EVIOCGMTSLOTS */ } -#if SDL_USE_LIBUDEV -static int -SDL_EVDEV_device_added(const char *dev_path, int udev_class) +static int SDL_EVDEV_device_added(const char *dev_path, int udev_class) { int ret; SDL_evdevlist_item *item; + unsigned long relbit[NBITS(REL_MAX)] = { 0 }; /* Check to make sure it's not already in list. */ - for (item = _this->first; item != NULL; item = item->next) { + for (item = _this->first; item; item = item->next) { if (SDL_strcmp(dev_path, item->path) == 0) { - return -1; /* already have this one */ + return -1; /* already have this one */ } } - item = (SDL_evdevlist_item *) SDL_calloc(1, sizeof (SDL_evdevlist_item)); - if (item == NULL) { + item = (SDL_evdevlist_item *)SDL_calloc(1, sizeof(SDL_evdevlist_item)); + if (!item) { return SDL_OutOfMemory(); } - item->fd = open(dev_path, O_RDONLY | O_NONBLOCK); + item->fd = open(dev_path, O_RDONLY | O_NONBLOCK | O_CLOEXEC); if (item->fd < 0) { SDL_free(item); return SDL_SetError("Unable to open %s", dev_path); } item->path = SDL_strdup(dev_path); - if (item->path == NULL) { + if (!item->path) { close(item->fd); SDL_free(item); return SDL_OutOfMemory(); } - if (udev_class & SDL_UDEV_DEVICE_TOUCHSCREEN) { - item->is_touchscreen = 1; + item->udev_class = udev_class; - if ((ret = SDL_EVDEV_init_touchscreen(item)) < 0) { + if (ioctl(item->fd, EVIOCGBIT(EV_REL, sizeof(relbit)), relbit) >= 0) { + item->relative_mouse = test_bit(REL_X, relbit) && test_bit(REL_Y, relbit); + item->high_res_wheel = test_bit(REL_WHEEL_HI_RES, relbit); + item->high_res_hwheel = test_bit(REL_HWHEEL_HI_RES, relbit); + } + + /* For now, we just treat a touchpad like a touchscreen */ + if (udev_class & (SDL_UDEV_DEVICE_TOUCHSCREEN | SDL_UDEV_DEVICE_TOUCHPAD)) { + item->is_touchscreen = SDL_TRUE; + ret = SDL_EVDEV_init_touchscreen(item, udev_class); + if (ret < 0) { close(item->fd); + SDL_free(item->path); + SDL_free(item); + return ret; + } + } else if (udev_class & SDL_UDEV_DEVICE_MOUSE) { + ret = SDL_EVDEV_init_mouse(item, udev_class); + if (ret < 0) { + close(item->fd); + SDL_free(item->path); SDL_free(item); return ret; } } - if (_this->last == NULL) { + if (!_this->last) { _this->first = _this->last = item; } else { _this->last->next = item; @@ -754,20 +919,20 @@ SDL_EVDEV_device_added(const char *dev_path, int udev_class) SDL_EVDEV_sync_device(item); + SDL_EVDEV_UpdateKeyboardMute(); + return _this->num_devices++; } -#endif /* SDL_USE_LIBUDEV */ -static int -SDL_EVDEV_device_removed(const char *dev_path) +static int SDL_EVDEV_device_removed(const char *dev_path) { SDL_evdevlist_item *item; SDL_evdevlist_item *prev = NULL; - for (item = _this->first; item != NULL; item = item->next) { + for (item = _this->first; item; item = item->next) { /* found it, remove it. */ if (SDL_strcmp(dev_path, item->path) == 0) { - if (prev != NULL) { + if (prev) { prev->next = item->next; } else { SDL_assert(_this->first == item); @@ -782,6 +947,7 @@ SDL_EVDEV_device_removed(const char *dev_path) close(item->fd); SDL_free(item->path); SDL_free(item); + SDL_EVDEV_UpdateKeyboardMute(); _this->num_devices--; return 0; } @@ -791,7 +957,6 @@ SDL_EVDEV_device_removed(const char *dev_path) return -1; } - #endif /* SDL_INPUT_LINUXEV */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/core/linux/SDL_evdev.h b/SDL2-2.30.5/src/core/linux/SDL_evdev.h similarity index 78% rename from SDL2-2.0.12/src/core/linux/SDL_evdev.h rename to SDL2-2.30.5/src/core/linux/SDL_evdev.h index c572633..c3e9c53 100644 --- a/SDL2-2.0.12/src/core/linux/SDL_evdev.h +++ b/SDL2-2.30.5/src/core/linux/SDL_evdev.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -30,6 +30,9 @@ extern int SDL_EVDEV_Init(void); extern void SDL_EVDEV_Quit(void); +extern void SDL_EVDEV_SetVTSwitchCallbacks(void (*release_callback)(void*), void *release_callback_data, + void (*acquire_callback)(void*), void *acquire_callback_data); +extern int SDL_EVDEV_GetDeviceCount(int device_class); extern void SDL_EVDEV_Poll(void); #endif /* SDL_INPUT_LINUXEV */ diff --git a/SDL2-2.30.5/src/core/linux/SDL_evdev_capabilities.c b/SDL2-2.30.5/src/core/linux/SDL_evdev_capabilities.c new file mode 100644 index 0000000..e1b5d74 --- /dev/null +++ b/SDL2-2.30.5/src/core/linux/SDL_evdev_capabilities.c @@ -0,0 +1,150 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 2020 Collabora Ltd. + + 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_evdev_capabilities.h" + +#ifdef HAVE_LINUX_INPUT_H + +/* missing defines in older Linux kernel headers */ +#ifndef BTN_TRIGGER_HAPPY +#define BTN_TRIGGER_HAPPY 0x2c0 +#endif +#ifndef BTN_DPAD_UP +#define BTN_DPAD_UP 0x220 +#endif +#ifndef KEY_ALS_TOGGLE +#define KEY_ALS_TOGGLE 0x230 +#endif + +extern int +SDL_EVDEV_GuessDeviceClass(const unsigned long bitmask_ev[NBITS(EV_MAX)], + const unsigned long bitmask_abs[NBITS(ABS_MAX)], + const unsigned long bitmask_key[NBITS(KEY_MAX)], + const unsigned long bitmask_rel[NBITS(REL_MAX)]) +{ + struct range + { + unsigned start; + unsigned end; + }; + + /* key code ranges above BTN_MISC (start is inclusive, stop is exclusive)*/ + static const struct range high_key_blocks[] = { + { KEY_OK, BTN_DPAD_UP }, + { KEY_ALS_TOGGLE, BTN_TRIGGER_HAPPY } + }; + + int devclass = 0; + unsigned long keyboard_mask; + + /* X, Y, Z axes but no buttons probably means an accelerometer */ + if (test_bit(EV_ABS, bitmask_ev) && + test_bit(ABS_X, bitmask_abs) && + test_bit(ABS_Y, bitmask_abs) && + test_bit(ABS_Z, bitmask_abs) && + !test_bit(EV_KEY, bitmask_ev)) { + return SDL_UDEV_DEVICE_ACCELEROMETER; + } + + /* RX, RY, RZ axes but no buttons also probably means an accelerometer */ + if (test_bit(EV_ABS, bitmask_ev) && + test_bit(ABS_RX, bitmask_abs) && + test_bit(ABS_RY, bitmask_abs) && + test_bit(ABS_RZ, bitmask_abs) && + !test_bit(EV_KEY, bitmask_ev)) { + return SDL_UDEV_DEVICE_ACCELEROMETER; + } + + if (test_bit(EV_ABS, bitmask_ev) && + test_bit(ABS_X, bitmask_abs) && test_bit(ABS_Y, bitmask_abs)) { + if (test_bit(BTN_STYLUS, bitmask_key) || test_bit(BTN_TOOL_PEN, bitmask_key)) { + ; /* ID_INPUT_TABLET */ + } else if (test_bit(BTN_TOOL_FINGER, bitmask_key) && !test_bit(BTN_TOOL_PEN, bitmask_key)) { + devclass |= SDL_UDEV_DEVICE_TOUCHPAD; /* ID_INPUT_TOUCHPAD */ + } else if (test_bit(BTN_MOUSE, bitmask_key)) { + devclass |= SDL_UDEV_DEVICE_MOUSE; /* ID_INPUT_MOUSE */ + } else if (test_bit(BTN_TOUCH, bitmask_key)) { + /* TODO: better determining between touchscreen and multitouch touchpad, + see https://github.com/systemd/systemd/blob/master/src/udev/udev-builtin-input_id.c */ + devclass |= SDL_UDEV_DEVICE_TOUCHSCREEN; /* ID_INPUT_TOUCHSCREEN */ + } + + if (test_bit(BTN_TRIGGER, bitmask_key) || + test_bit(BTN_A, bitmask_key) || + test_bit(BTN_1, bitmask_key) || + test_bit(ABS_RX, bitmask_abs) || + test_bit(ABS_RY, bitmask_abs) || + test_bit(ABS_RZ, bitmask_abs) || + test_bit(ABS_THROTTLE, bitmask_abs) || + test_bit(ABS_RUDDER, bitmask_abs) || + test_bit(ABS_WHEEL, bitmask_abs) || + test_bit(ABS_GAS, bitmask_abs) || + test_bit(ABS_BRAKE, bitmask_abs)) { + devclass |= SDL_UDEV_DEVICE_JOYSTICK; /* ID_INPUT_JOYSTICK */ + } + } + + if (test_bit(EV_REL, bitmask_ev) && + test_bit(REL_X, bitmask_rel) && test_bit(REL_Y, bitmask_rel) && + test_bit(BTN_MOUSE, bitmask_key)) { + devclass |= SDL_UDEV_DEVICE_MOUSE; /* ID_INPUT_MOUSE */ + } + + if (test_bit(EV_KEY, bitmask_ev)) { + unsigned i; + unsigned long found = 0; + + for (i = 0; i < BTN_MISC / BITS_PER_LONG; ++i) { + found |= bitmask_key[i]; + } + /* If there are no keys in the lower block, check the higher blocks */ + if (!found) { + unsigned block; + for (block = 0; block < (sizeof(high_key_blocks) / sizeof(struct range)); ++block) { + for (i = high_key_blocks[block].start; i < high_key_blocks[block].end; ++i) { + if (test_bit(i, bitmask_key)) { + found = 1; + break; + } + } + } + } + + if (found > 0) { + devclass |= SDL_UDEV_DEVICE_KEYBOARD; /* ID_INPUT_KEY */ + } + } + + /* the first 32 bits are ESC, numbers, and Q to D; if we have any of + * those, consider it a keyboard device; do not test KEY_RESERVED, though */ + keyboard_mask = 0xFFFFFFFE; + if ((bitmask_key[0] & keyboard_mask) != 0) { + devclass |= SDL_UDEV_DEVICE_KEYBOARD; /* ID_INPUT_KEYBOARD */ + } + + return devclass; +} + +#endif /* HAVE_LINUX_INPUT_H */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/core/linux/SDL_evdev_capabilities.h b/SDL2-2.30.5/src/core/linux/SDL_evdev_capabilities.h new file mode 100644 index 0000000..8d3830a --- /dev/null +++ b/SDL2-2.30.5/src/core/linux/SDL_evdev_capabilities.h @@ -0,0 +1,59 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 2020 Collabora Ltd. + + 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" + +#ifndef SDL_evdev_capabilities_h_ +#define SDL_evdev_capabilities_h_ + +#ifdef HAVE_LINUX_INPUT_H + +#include + +/* A device can be any combination of these classes */ +typedef enum +{ + SDL_UDEV_DEVICE_UNKNOWN = 0x0000, + SDL_UDEV_DEVICE_MOUSE = 0x0001, + SDL_UDEV_DEVICE_KEYBOARD = 0x0002, + SDL_UDEV_DEVICE_JOYSTICK = 0x0004, + SDL_UDEV_DEVICE_SOUND = 0x0008, + SDL_UDEV_DEVICE_TOUCHSCREEN = 0x0010, + SDL_UDEV_DEVICE_ACCELEROMETER = 0x0020, + SDL_UDEV_DEVICE_TOUCHPAD = 0x0040 +} SDL_UDEV_deviceclass; + +#define BITS_PER_LONG (sizeof(unsigned long) * 8) +#define NBITS(x) ((((x)-1) / BITS_PER_LONG) + 1) +#define EVDEV_OFF(x) ((x) % BITS_PER_LONG) +#define EVDEV_LONG(x) ((x) / BITS_PER_LONG) +#define test_bit(bit, array) ((array[EVDEV_LONG(bit)] >> EVDEV_OFF(bit)) & 1) + +extern int SDL_EVDEV_GuessDeviceClass(const unsigned long bitmask_ev[NBITS(EV_MAX)], + const unsigned long bitmask_abs[NBITS(ABS_MAX)], + const unsigned long bitmask_key[NBITS(KEY_MAX)], + const unsigned long bitmask_rel[NBITS(REL_MAX)]); + +#endif /* HAVE_LINUX_INPUT_H */ + +#endif /* SDL_evdev_capabilities_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/core/linux/SDL_evdev_kbd.c b/SDL2-2.30.5/src/core/linux/SDL_evdev_kbd.c similarity index 60% rename from SDL2-2.0.12/src/core/linux/SDL_evdev_kbd.c rename to SDL2-2.30.5/src/core/linux/SDL_evdev_kbd.c index 979ad5f..0aaefa0 100644 --- a/SDL2-2.0.12/src/core/linux/SDL_evdev_kbd.c +++ b/SDL2-2.30.5/src/core/linux/SDL_evdev_kbd.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -53,33 +53,31 @@ * Handler Tables. */ -#define K_HANDLERS\ - k_self, k_fn, k_spec, k_pad,\ - k_dead, k_cons, k_cur, k_shift,\ - k_meta, k_ascii, k_lock, k_lowercase,\ - k_slock, k_dead2, k_brl, k_ignore +#define K_HANDLERS \ + k_self, k_fn, k_spec, k_pad, \ + k_dead, k_cons, k_cur, k_shift, \ + k_meta, k_ascii, k_lock, k_lowercase, \ + k_slock, k_dead2, k_brl, k_ignore -typedef void (k_handler_fn)(SDL_EVDEV_keyboard_state *kbd, unsigned char value, char up_flag); +typedef void(k_handler_fn)(SDL_EVDEV_keyboard_state *kbd, unsigned char value, char up_flag); static k_handler_fn K_HANDLERS; static k_handler_fn *k_handler[16] = { K_HANDLERS }; -typedef void (fn_handler_fn)(SDL_EVDEV_keyboard_state *kbd); +typedef void(fn_handler_fn)(SDL_EVDEV_keyboard_state *kbd); static void fn_enter(SDL_EVDEV_keyboard_state *kbd); static void fn_caps_toggle(SDL_EVDEV_keyboard_state *kbd); static void fn_caps_on(SDL_EVDEV_keyboard_state *kbd); static void fn_num(SDL_EVDEV_keyboard_state *kbd); static void fn_compose(SDL_EVDEV_keyboard_state *kbd); -static fn_handler_fn *fn_handler[] = -{ - NULL, fn_enter, NULL, NULL, - NULL, NULL, NULL, fn_caps_toggle, - fn_num, NULL, NULL, NULL, - NULL, fn_caps_on, fn_compose, NULL, - NULL, NULL, NULL, fn_num +static fn_handler_fn *fn_handler[] = { + NULL, fn_enter, NULL, NULL, + NULL, NULL, NULL, fn_caps_toggle, + fn_num, NULL, NULL, NULL, + NULL, fn_caps_on, fn_compose, NULL, + NULL, NULL, NULL, fn_num }; - /* * Keyboard State */ @@ -87,20 +85,25 @@ static fn_handler_fn *fn_handler[] = struct SDL_EVDEV_keyboard_state { int console_fd; + SDL_bool muted; int old_kbd_mode; unsigned short **key_maps; - unsigned char shift_down[NR_SHIFT]; /* shift state counters.. */ + unsigned char shift_down[NR_SHIFT]; /* shift state counters.. */ SDL_bool dead_key_next; - int npadch; /* -1 or number assembled on pad */ + int npadch; /* -1 or number assembled on pad */ struct kbdiacrs *accents; unsigned int diacr; - SDL_bool rep; /* flag telling character repeat */ + SDL_bool rep; /* flag telling character repeat */ unsigned char lockstate; unsigned char slockstate; unsigned char ledflagstate; char shift_state; char text[128]; unsigned int text_len; + void (*vt_release_callback)(void *); + void *vt_release_callback_data; + void (*vt_acquire_callback)(void *); + void *vt_acquire_callback_data; }; #ifdef DUMP_ACCENTS @@ -114,7 +117,7 @@ static void SDL_EVDEV_dump_accents(SDL_EVDEV_keyboard_state *kbd) for (i = 0; i < kbd->accents->kb_cnt; ++i) { struct kbdiacr *diacr = &kbd->accents->kbdiacr[i]; printf(" { 0x%.2x, 0x%.2x, 0x%.2x },\n", - diacr->diacr, diacr->base, diacr->result); + diacr->diacr, diacr->base, diacr->result); } while (i < 256) { printf(" { 0x00, 0x00, 0x00 },\n"); @@ -134,7 +137,7 @@ static void SDL_EVDEV_dump_keymap(SDL_EVDEV_keyboard_state *kbd) if (kbd->key_maps[i]) { printf("static unsigned short default_key_map_%d[NR_KEYS] = {", i); for (j = 0; j < NR_KEYS; ++j) { - if ((j%8) == 0) { + if ((j % 8) == 0) { printf("\n "); } printf("0x%.4x, ", kbd->key_maps[i][j]); @@ -155,63 +158,23 @@ static void SDL_EVDEV_dump_keymap(SDL_EVDEV_keyboard_state *kbd) } #endif /* DUMP_KEYMAP */ -static int SDL_EVDEV_kbd_load_keymaps(SDL_EVDEV_keyboard_state *kbd) -{ - int i, j; - - kbd->key_maps = (unsigned short **)SDL_calloc(MAX_NR_KEYMAPS, sizeof(unsigned short *)); - if (!kbd->key_maps) { - return -1; - } - - for (i = 0; i < MAX_NR_KEYMAPS; ++i) { - struct kbentry kbe; - - kbe.kb_table = i; - kbe.kb_index = 0; - if (ioctl(kbd->console_fd, KDGKBENT, &kbe) < 0) { - return -1; - } - - if (kbe.kb_value == K_NOSUCHMAP) { - continue; - } - - kbd->key_maps[i] = (unsigned short *)SDL_malloc(NR_KEYS * sizeof(unsigned short)); - if (!kbd->key_maps[i]) { - return -1; - } - - for (j = 0; j < NR_KEYS; ++j) { - kbe.kb_table = i; - kbe.kb_index = j; - if (ioctl(kbd->console_fd, KDGKBENT, &kbe) < 0) { - return -1; - } - kbd->key_maps[i][j] = (kbe.kb_value ^ 0xf000); - } - } - return 0; -} - -static SDL_EVDEV_keyboard_state * kbd_cleanup_state = NULL; +static SDL_EVDEV_keyboard_state *kbd_cleanup_state = NULL; static int kbd_cleanup_sigactions_installed = 0; static int kbd_cleanup_atexit_installed = 0; static struct sigaction old_sigaction[NSIG]; -static int fatal_signals[] = -{ +static int fatal_signals[] = { /* Handlers for SIGTERM and SIGINT are installed in SDL_QuitInit. */ - SIGHUP, SIGQUIT, SIGILL, SIGABRT, - SIGFPE, SIGSEGV, SIGPIPE, SIGBUS, + SIGHUP, SIGQUIT, SIGILL, SIGABRT, + SIGFPE, SIGSEGV, SIGPIPE, SIGBUS, SIGSYS }; static void kbd_cleanup(void) { - SDL_EVDEV_keyboard_state* kbd = kbd_cleanup_state; - if (kbd == NULL) { + SDL_EVDEV_keyboard_state *kbd = kbd_cleanup_state; + if (!kbd) { return; } kbd_cleanup_state = NULL; @@ -219,18 +182,17 @@ static void kbd_cleanup(void) ioctl(kbd->console_fd, KDSKBMODE, kbd->old_kbd_mode); } -void -SDL_EVDEV_kbd_reraise_signal(int sig) +static void SDL_EVDEV_kbd_reraise_signal(int sig) { - raise(sig); + (void)raise(sig); } -siginfo_t* SDL_EVDEV_kdb_cleanup_siginfo = NULL; -void* SDL_EVDEV_kdb_cleanup_ucontext = NULL; +siginfo_t *SDL_EVDEV_kdb_cleanup_siginfo = NULL; +void *SDL_EVDEV_kdb_cleanup_ucontext = NULL; -static void kbd_cleanup_signal_action(int signum, siginfo_t* info, void* ucontext) +static void kbd_cleanup_signal_action(int signum, siginfo_t *info, void *ucontext) { - struct sigaction* old_action_p = &(old_sigaction[signum]); + struct sigaction *old_action_p = &(old_sigaction[signum]); sigset_t sigset; /* Restore original signal handler before going any further. */ @@ -264,19 +226,20 @@ static void kbd_unregister_emerg_cleanup() kbd_cleanup_sigactions_installed = 0; for (tabidx = 0; tabidx < sizeof(fatal_signals) / sizeof(fatal_signals[0]); ++tabidx) { - struct sigaction* old_action_p; + struct sigaction *old_action_p; struct sigaction cur_action; signum = fatal_signals[tabidx]; old_action_p = &(old_sigaction[signum]); /* Examine current signal action */ - if (sigaction(signum, NULL, &cur_action)) + if (sigaction(signum, NULL, &cur_action)) { continue; + } /* Check if action installed and not modifed */ - if (!(cur_action.sa_flags & SA_SIGINFO) - || cur_action.sa_sigaction != &kbd_cleanup_signal_action) + if (!(cur_action.sa_flags & SA_SIGINFO) || cur_action.sa_sigaction != &kbd_cleanup_signal_action) { continue; + } /* Restore original action */ sigaction(signum, old_action_p, NULL); @@ -292,11 +255,11 @@ static void kbd_cleanup_atexit(void) kbd_unregister_emerg_cleanup(); } -static void kbd_register_emerg_cleanup(SDL_EVDEV_keyboard_state * kbd) +static void kbd_register_emerg_cleanup(SDL_EVDEV_keyboard_state *kbd) { int tabidx, signum; - if (kbd_cleanup_state != NULL) { + if (kbd_cleanup_state) { return; } kbd_cleanup_state = kbd; @@ -306,7 +269,7 @@ static void kbd_register_emerg_cleanup(SDL_EVDEV_keyboard_state * kbd) * functions that are called when the shared library is unloaded. * -- man atexit(3) */ - atexit(kbd_cleanup_atexit); + (void)atexit(kbd_cleanup_atexit); kbd_cleanup_atexit_installed = 1; } @@ -316,20 +279,20 @@ static void kbd_register_emerg_cleanup(SDL_EVDEV_keyboard_state * kbd) kbd_cleanup_sigactions_installed = 1; for (tabidx = 0; tabidx < sizeof(fatal_signals) / sizeof(fatal_signals[0]); ++tabidx) { - struct sigaction* old_action_p; + struct sigaction *old_action_p; struct sigaction new_action; - signum = fatal_signals[tabidx]; + signum = fatal_signals[tabidx]; old_action_p = &(old_sigaction[signum]); - if (sigaction(signum, NULL, old_action_p)) + if (sigaction(signum, NULL, old_action_p)) { continue; + } /* Skip SIGHUP and SIGPIPE if handler is already installed * - assume the handler will do the cleanup */ - if ((signum == SIGHUP || signum == SIGPIPE) - && (old_action_p->sa_handler != SIG_DFL - || (void (*)(int))old_action_p->sa_sigaction != SIG_DFL)) + if ((signum == SIGHUP || signum == SIGPIPE) && (old_action_p->sa_handler != SIG_DFL || (void (*)(int))old_action_p->sa_sigaction != SIG_DFL)) { continue; + } new_action = *old_action_p; new_action.sa_flags |= SA_SIGINFO; @@ -338,23 +301,146 @@ static void kbd_register_emerg_cleanup(SDL_EVDEV_keyboard_state * kbd) } } -SDL_EVDEV_keyboard_state * -SDL_EVDEV_kbd_init(void) +enum { + VT_SIGNAL_NONE, + VT_SIGNAL_RELEASE, + VT_SIGNAL_ACQUIRE, +}; +static int vt_release_signal; +static int vt_acquire_signal; +static SDL_atomic_t vt_signal_pending; + +typedef void (*signal_handler)(int signum); + +static void kbd_vt_release_signal_action(int signum) +{ + SDL_AtomicSet(&vt_signal_pending, VT_SIGNAL_RELEASE); +} + +static void kbd_vt_acquire_signal_action(int signum) +{ + SDL_AtomicSet(&vt_signal_pending, VT_SIGNAL_ACQUIRE); +} + +static SDL_bool setup_vt_signal(int signum, signal_handler handler) +{ + struct sigaction *old_action_p; + struct sigaction new_action; + old_action_p = &(old_sigaction[signum]); + SDL_zero(new_action); + new_action.sa_handler = handler; + new_action.sa_flags = SA_RESTART; + if (sigaction(signum, &new_action, old_action_p) < 0) { + return SDL_FALSE; + } + if (old_action_p->sa_handler != SIG_DFL) { + /* This signal is already in use */ + sigaction(signum, old_action_p, NULL); + return SDL_FALSE; + } + return SDL_TRUE; +} + +static int find_free_signal(signal_handler handler) +{ +#ifdef SIGRTMIN + int i; + + for (i = SIGRTMIN + 2; i <= SIGRTMAX; ++i) { + if (setup_vt_signal(i, handler)) { + return i; + } + } +#endif + if (setup_vt_signal(SIGUSR1, handler)) { + return SIGUSR1; + } + if (setup_vt_signal(SIGUSR2, handler)) { + return SIGUSR2; + } + return 0; +} + +static void kbd_vt_quit(int console_fd) +{ + struct vt_mode mode; + + if (vt_release_signal) { + sigaction(vt_release_signal, &old_sigaction[vt_release_signal], NULL); + vt_release_signal = 0; + } + if (vt_acquire_signal) { + sigaction(vt_acquire_signal, &old_sigaction[vt_acquire_signal], NULL); + vt_acquire_signal = 0; + } + + SDL_zero(mode); + mode.mode = VT_AUTO; + ioctl(console_fd, VT_SETMODE, &mode); +} + +static int kbd_vt_init(int console_fd) +{ + struct vt_mode mode; + + vt_release_signal = find_free_signal(kbd_vt_release_signal_action); + vt_acquire_signal = find_free_signal(kbd_vt_acquire_signal_action); + if (!vt_release_signal || !vt_acquire_signal) { + kbd_vt_quit(console_fd); + return -1; + } + + SDL_zero(mode); + mode.mode = VT_PROCESS; + mode.relsig = vt_release_signal; + mode.acqsig = vt_acquire_signal; + mode.frsig = SIGIO; + if (ioctl(console_fd, VT_SETMODE, &mode) < 0) { + kbd_vt_quit(console_fd); + return -1; + } + return 0; +} + +static void kbd_vt_update(SDL_EVDEV_keyboard_state *state) +{ + int signal_pending = SDL_AtomicGet(&vt_signal_pending); + if (signal_pending != VT_SIGNAL_NONE) { + if (signal_pending == VT_SIGNAL_RELEASE) { + if (state->vt_release_callback) { + state->vt_release_callback(state->vt_release_callback_data); + } + ioctl(state->console_fd, VT_RELDISP, 1); + } else { + if (state->vt_acquire_callback) { + state->vt_acquire_callback(state->vt_acquire_callback_data); + } + ioctl(state->console_fd, VT_RELDISP, VT_ACKACQ); + } + SDL_AtomicCAS(&vt_signal_pending, signal_pending, VT_SIGNAL_NONE); + } +} + +SDL_EVDEV_keyboard_state *SDL_EVDEV_kbd_init(void) { SDL_EVDEV_keyboard_state *kbd; - int i; char flag_state; - char shift_state[ sizeof (long) ] = {TIOCL_GETSHIFTSTATE, 0}; + char kbtype; + char shift_state[sizeof(long)] = { TIOCL_GETSHIFTSTATE, 0 }; kbd = (SDL_EVDEV_keyboard_state *)SDL_calloc(1, sizeof(*kbd)); if (!kbd) { return NULL; } - kbd->npadch = -1; - /* This might fail if we're not connected to a tty (e.g. on the Steam Link) */ - kbd->console_fd = open("/dev/tty", O_RDONLY); + kbd->console_fd = open("/dev/tty", O_RDONLY | O_CLOEXEC); + if (!((ioctl(kbd->console_fd, KDGKBTYPE, &kbtype) == 0) && ((kbtype == KB_101) || (kbtype == KB_84)))) { + close(kbd->console_fd); + kbd->console_fd = -1; + } + + kbd->npadch = -1; if (ioctl(kbd->console_fd, TIOCLINUX, shift_state) == 0) { kbd->shift_state = *shift_state; @@ -365,79 +451,99 @@ SDL_EVDEV_kbd_init(void) } kbd->accents = &default_accents; - if (ioctl(kbd->console_fd, KDGKBDIACR, kbd->accents) < 0) { - /* No worries, we'll use the default accent table */ - } - kbd->key_maps = default_key_maps; + if (ioctl(kbd->console_fd, KDGKBMODE, &kbd->old_kbd_mode) == 0) { /* Set the keyboard in UNICODE mode and load the keymaps */ ioctl(kbd->console_fd, KDSKBMODE, K_UNICODE); + } - if (SDL_EVDEV_kbd_load_keymaps(kbd) < 0) { - for (i = 0; i < MAX_NR_KEYMAPS; ++i) { - if (kbd->key_maps[i]) { - SDL_free(kbd->key_maps[i]); - } - } - SDL_free(kbd->key_maps); + kbd_vt_init(kbd->console_fd); - kbd->key_maps = default_key_maps; - } + return kbd; +} +void SDL_EVDEV_kbd_set_muted(SDL_EVDEV_keyboard_state *state, SDL_bool muted) +{ + if (!state) { + return; + } + + if (muted == state->muted) { + return; + } + + if (muted) { /* Allow inhibiting keyboard mute with env. variable for debugging etc. */ - if (getenv("SDL_INPUT_LINUX_KEEP_KBD") == NULL) { + if (SDL_getenv("SDL_INPUT_LINUX_KEEP_KBD") == NULL) { /* Mute the keyboard so keystrokes only generate evdev events * and do not leak through to the console */ - ioctl(kbd->console_fd, KDSKBMODE, K_OFF); + ioctl(state->console_fd, KDSKBMODE, K_OFF); /* Make sure to restore keyboard if application fails to call * SDL_Quit before exit or fatal signal is raised. */ if (!SDL_GetHintBoolean(SDL_HINT_NO_SIGNAL_HANDLERS, SDL_FALSE)) { - kbd_register_emerg_cleanup(kbd); + kbd_register_emerg_cleanup(state); } } - } + } else { + kbd_unregister_emerg_cleanup(); -#ifdef DUMP_ACCENTS - SDL_EVDEV_dump_accents(kbd); -#endif -#ifdef DUMP_KEYMAP - SDL_EVDEV_dump_keymap(kbd); -#endif - return kbd; + /* Restore the original keyboard mode */ + ioctl(state->console_fd, KDSKBMODE, state->old_kbd_mode); + } + state->muted = muted; } -void -SDL_EVDEV_kbd_quit(SDL_EVDEV_keyboard_state *kbd) +void SDL_EVDEV_kbd_set_vt_switch_callbacks(SDL_EVDEV_keyboard_state *state, void (*release_callback)(void*), void *release_callback_data, void (*acquire_callback)(void*), void *acquire_callback_data) { - if (!kbd) { + if (!state) { return; } - kbd_unregister_emerg_cleanup(); + state->vt_release_callback = release_callback; + state->vt_release_callback_data = release_callback_data; + state->vt_acquire_callback = acquire_callback; + state->vt_acquire_callback_data = acquire_callback_data; +} - if (kbd->console_fd >= 0) { - /* Restore the original keyboard mode */ - ioctl(kbd->console_fd, KDSKBMODE, kbd->old_kbd_mode); - - close(kbd->console_fd); - kbd->console_fd = -1; +void SDL_EVDEV_kbd_update(SDL_EVDEV_keyboard_state *state) +{ + if (!state) { + return; } - if (kbd->key_maps && kbd->key_maps != default_key_maps) { + kbd_vt_update(state); +} + +void SDL_EVDEV_kbd_quit(SDL_EVDEV_keyboard_state *state) +{ + if (!state) { + return; + } + + SDL_EVDEV_kbd_set_muted(state, SDL_FALSE); + + kbd_vt_quit(state->console_fd); + + if (state->console_fd >= 0) { + close(state->console_fd); + state->console_fd = -1; + } + + if (state->key_maps && state->key_maps != default_key_maps) { int i; for (i = 0; i < MAX_NR_KEYMAPS; ++i) { - if (kbd->key_maps[i]) { - SDL_free(kbd->key_maps[i]); + if (state->key_maps[i]) { + SDL_free(state->key_maps[i]); } } - SDL_free(kbd->key_maps); + SDL_free(state->key_maps); } - SDL_free(kbd); + SDL_free(state); } /* @@ -446,25 +552,26 @@ SDL_EVDEV_kbd_quit(SDL_EVDEV_keyboard_state *kbd) static void put_queue(SDL_EVDEV_keyboard_state *kbd, uint c) { /* c is already part of a UTF-8 sequence and safe to add as a character */ - if (kbd->text_len < (sizeof(kbd->text)-1)) { + if (kbd->text_len < (sizeof(kbd->text) - 1)) { kbd->text[kbd->text_len++] = (char)c; } } static void put_utf8(SDL_EVDEV_keyboard_state *kbd, uint c) { - if (c < 0x80) - /* 0******* */ - put_queue(kbd, c); - else if (c < 0x800) { + if (c < 0x80) { + put_queue(kbd, c); /* 0******* */ + } else if (c < 0x800) { /* 110***** 10****** */ put_queue(kbd, 0xc0 | (c >> 6)); put_queue(kbd, 0x80 | (c & 0x3f)); } else if (c < 0x10000) { - if (c >= 0xD800 && c < 0xE000) + if (c >= 0xD800 && c < 0xE000) { return; - if (c == 0xFFFF) + } + if (c == 0xFFFF) { return; + } /* 1110**** 10****** 10****** */ put_queue(kbd, 0xe0 | (c >> 12)); put_queue(kbd, 0x80 | ((c >> 6) & 0x3f)); @@ -492,6 +599,11 @@ static unsigned int handle_diacr(SDL_EVDEV_keyboard_state *kbd, unsigned int ch) kbd->diacr = 0; + if (kbd->console_fd >= 0) + if (ioctl(kbd->console_fd, KDGKBDIACR, kbd->accents) < 0) { + /* No worries, we'll use the default accent table */ + } + for (i = 0; i < kbd->accents->kb_cnt; i++) { if (kbd->accents->kbdiacr[i].diacr == d && kbd->accents->kbdiacr[i].base == ch) { @@ -499,8 +611,9 @@ static unsigned int handle_diacr(SDL_EVDEV_keyboard_state *kbd, unsigned int ch) } } - if (ch == ' ' || ch == d) + if (ch == ' ' || ch == d) { return d; + } put_utf8(kbd, d); @@ -554,24 +667,27 @@ static void fn_enter(SDL_EVDEV_keyboard_state *kbd) static void fn_caps_toggle(SDL_EVDEV_keyboard_state *kbd) { - if (kbd->rep) + if (kbd->rep) { return; + } chg_vc_kbd_led(kbd, K_CAPSLOCK); } static void fn_caps_on(SDL_EVDEV_keyboard_state *kbd) { - if (kbd->rep) + if (kbd->rep) { return; + } set_vc_kbd_led(kbd, K_CAPSLOCK); } static void fn_num(SDL_EVDEV_keyboard_state *kbd) { - if (!kbd->rep) + if (!kbd->rep) { chg_vc_kbd_led(kbd, K_NUMLOCK); + } } static void fn_compose(SDL_EVDEV_keyboard_state *kbd) @@ -589,12 +705,15 @@ static void k_ignore(SDL_EVDEV_keyboard_state *kbd, unsigned char value, char up static void k_spec(SDL_EVDEV_keyboard_state *kbd, unsigned char value, char up_flag) { - if (up_flag) + if (up_flag) { return; - if (value >= SDL_arraysize(fn_handler)) + } + if (value >= SDL_arraysize(fn_handler)) { return; - if (fn_handler[value]) + } + if (fn_handler[value]) { fn_handler[value](kbd); + } } static void k_lowercase(SDL_EVDEV_keyboard_state *kbd, unsigned char value, char up_flag) @@ -603,11 +722,13 @@ static void k_lowercase(SDL_EVDEV_keyboard_state *kbd, unsigned char value, char static void k_self(SDL_EVDEV_keyboard_state *kbd, unsigned char value, char up_flag) { - if (up_flag) - return; /* no action, if this is a key release */ + if (up_flag) { + return; /* no action, if this is a key release */ + } - if (kbd->diacr) + if (kbd->diacr) { value = handle_diacr(kbd, value); + } if (kbd->dead_key_next) { kbd->dead_key_next = SDL_FALSE; @@ -619,15 +740,16 @@ static void k_self(SDL_EVDEV_keyboard_state *kbd, unsigned char value, char up_f static void k_deadunicode(SDL_EVDEV_keyboard_state *kbd, unsigned int value, char up_flag) { - if (up_flag) + if (up_flag) { return; + } kbd->diacr = (kbd->diacr ? handle_diacr(kbd, value) : value); } static void k_dead(SDL_EVDEV_keyboard_state *kbd, unsigned char value, char up_flag) { - const unsigned char ret_diacr[NR_DEAD] = {'`', '\'', '^', '~', '"', ',' }; + const unsigned char ret_diacr[NR_DEAD] = { '`', '\'', '^', '~', '"', ',' }; k_deadunicode(kbd, ret_diacr[value], up_flag); } @@ -653,8 +775,9 @@ static void k_pad(SDL_EVDEV_keyboard_state *kbd, unsigned char value, char up_fl { static const char pad_chars[] = "0123456789+-*/\015,.?()#"; - if (up_flag) - return; /* no action, if this is a key release */ + if (up_flag) { + return; /* no action, if this is a key release */ + } if (!vc_kbd_led(kbd, K_NUMLOCK)) { /* unprintable action */ @@ -668,16 +791,18 @@ static void k_shift(SDL_EVDEV_keyboard_state *kbd, unsigned char value, char up_ { int old_state = kbd->shift_state; - if (kbd->rep) + if (kbd->rep) { return; + } /* * Mimic typewriter: * a CapsShift key acts like Shift but undoes CapsLock */ if (value == KVAL(K_CAPSSHIFT)) { value = KVAL(K_SHIFT); - if (!up_flag) + if (!up_flag) { clr_vc_kbd_led(kbd, K_CAPSLOCK); + } } if (up_flag) { @@ -685,15 +810,18 @@ static void k_shift(SDL_EVDEV_keyboard_state *kbd, unsigned char value, char up_ * handle the case that two shift or control * keys are depressed simultaneously */ - if (kbd->shift_down[value]) + if (kbd->shift_down[value]) { kbd->shift_down[value]--; - } else + } + } else { kbd->shift_down[value]++; + } - if (kbd->shift_down[value]) + if (kbd->shift_down[value]) { kbd->shift_state |= (1 << value); - else + } else { kbd->shift_state &= ~(1 << value); + } /* kludge */ if (up_flag && kbd->shift_state != old_state && kbd->npadch != -1) { @@ -710,8 +838,9 @@ static void k_ascii(SDL_EVDEV_keyboard_state *kbd, unsigned char value, char up_ { int base; - if (up_flag) + if (up_flag) { return; + } if (value < 10) { /* decimal input of code, while Alt depressed */ @@ -722,16 +851,18 @@ static void k_ascii(SDL_EVDEV_keyboard_state *kbd, unsigned char value, char up_ base = 16; } - if (kbd->npadch == -1) + if (kbd->npadch == -1) { kbd->npadch = value; - else + } else { kbd->npadch = kbd->npadch * base + value; + } } static void k_lock(SDL_EVDEV_keyboard_state *kbd, unsigned char value, char up_flag) { - if (up_flag || kbd->rep) + if (up_flag || kbd->rep) { return; + } chg_vc_kbd_lock(kbd, value); } @@ -739,8 +870,9 @@ static void k_lock(SDL_EVDEV_keyboard_state *kbd, unsigned char value, char up_f static void k_slock(SDL_EVDEV_keyboard_state *kbd, unsigned char value, char up_flag) { k_shift(kbd, value, up_flag); - if (up_flag || kbd->rep) + if (up_flag || kbd->rep) { return; + } chg_vc_kbd_slock(kbd, value); /* try to make Alt, oops, AltGr and such work */ @@ -754,32 +886,41 @@ static void k_brl(SDL_EVDEV_keyboard_state *kbd, unsigned char value, char up_fl { } -void -SDL_EVDEV_kbd_keycode(SDL_EVDEV_keyboard_state *kbd, unsigned int keycode, int down) +void SDL_EVDEV_kbd_keycode(SDL_EVDEV_keyboard_state *state, unsigned int keycode, int down) { unsigned char shift_final; unsigned char type; unsigned short *key_map; unsigned short keysym; - if (!kbd) { + if (!state) { return; } - kbd->rep = (down == 2); + state->rep = (down == 2); - shift_final = (kbd->shift_state | kbd->slockstate) ^ kbd->lockstate; - key_map = kbd->key_maps[shift_final]; + shift_final = (state->shift_state | state->slockstate) ^ state->lockstate; + key_map = state->key_maps[shift_final]; if (!key_map) { /* Unsupported shift state (e.g. ctrl = 4, alt = 8), just reset to the default state */ - kbd->shift_state = 0; - kbd->slockstate = 0; - kbd->lockstate = 0; + state->shift_state = 0; + state->slockstate = 0; + state->lockstate = 0; return; } if (keycode < NR_KEYS) { - keysym = key_map[keycode]; + if (state->console_fd < 0) { + keysym = key_map[keycode]; + } else { + struct kbentry kbe; + kbe.kb_table = shift_final; + kbe.kb_index = keycode; + if (ioctl(state->console_fd, KDGKBENT, &kbe) == 0) + keysym = (kbe.kb_value ^ 0xf000); + else + return; + } } else { return; } @@ -788,7 +929,7 @@ SDL_EVDEV_kbd_keycode(SDL_EVDEV_keyboard_state *kbd, unsigned int keycode, int d if (type < 0xf0) { if (down) { - put_utf8(kbd, keysym); + put_utf8(state, keysym); } } else { type -= 0xf0; @@ -797,43 +938,61 @@ SDL_EVDEV_kbd_keycode(SDL_EVDEV_keyboard_state *kbd, unsigned int keycode, int d if (type == KT_LETTER) { type = KT_LATIN; - if (vc_kbd_led(kbd, K_CAPSLOCK)) { - key_map = kbd->key_maps[shift_final ^ (1 << KG_SHIFT)]; + if (vc_kbd_led(state, K_CAPSLOCK)) { + shift_final = shift_final ^ (1 << KG_SHIFT); + key_map = state->key_maps[shift_final]; if (key_map) { - keysym = key_map[keycode]; + if (state->console_fd < 0) { + keysym = key_map[keycode]; + } else { + struct kbentry kbe; + kbe.kb_table = shift_final; + kbe.kb_index = keycode; + if (ioctl(state->console_fd, KDGKBENT, &kbe) == 0) + keysym = (kbe.kb_value ^ 0xf000); + } } } } - (*k_handler[type])(kbd, keysym & 0xff, !down); + (*k_handler[type])(state, keysym & 0xff, !down); if (type != KT_SLOCK) { - kbd->slockstate = 0; + state->slockstate = 0; } } - if (kbd->text_len > 0) { - kbd->text[kbd->text_len] = '\0'; - SDL_SendKeyboardText(kbd->text); - kbd->text_len = 0; + if (state->text_len > 0) { + state->text[state->text_len] = '\0'; + SDL_SendKeyboardText(state->text); + state->text_len = 0; } } -#else /* !SDL_INPUT_LINUXKD */ +#elif !defined(SDL_INPUT_FBSDKBIO) /* !SDL_INPUT_LINUXKD */ -SDL_EVDEV_keyboard_state * -SDL_EVDEV_kbd_init(void) +SDL_EVDEV_keyboard_state *SDL_EVDEV_kbd_init(void) { return NULL; } -void -SDL_EVDEV_kbd_keycode(SDL_EVDEV_keyboard_state *state, unsigned int keycode, int down) +void SDL_EVDEV_kbd_set_muted(SDL_EVDEV_keyboard_state *state, SDL_bool muted) { } -void -SDL_EVDEV_kbd_quit(SDL_EVDEV_keyboard_state *state) +void SDL_EVDEV_kbd_set_vt_switch_callbacks(SDL_EVDEV_keyboard_state *state, void (*release_callback)(void*), void *release_callback_data, void (*acquire_callback)(void*), void *acquire_callback_data) +{ +} + +void SDL_EVDEV_kbd_update(SDL_EVDEV_keyboard_state *state) +{ +} + +void SDL_EVDEV_kbd_keycode(SDL_EVDEV_keyboard_state *state, unsigned int keycode, int down) +{ +} + +void SDL_EVDEV_kbd_quit(SDL_EVDEV_keyboard_state *state) { } diff --git a/SDL2-2.0.12/src/core/linux/SDL_evdev_kbd.h b/SDL2-2.30.5/src/core/linux/SDL_evdev_kbd.h similarity index 75% rename from SDL2-2.0.12/src/core/linux/SDL_evdev_kbd.h rename to SDL2-2.30.5/src/core/linux/SDL_evdev_kbd.h index 0b276ec..52a4778 100644 --- a/SDL2-2.0.12/src/core/linux/SDL_evdev_kbd.h +++ b/SDL2-2.30.5/src/core/linux/SDL_evdev_kbd.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,6 +26,9 @@ struct SDL_EVDEV_keyboard_state; typedef struct SDL_EVDEV_keyboard_state SDL_EVDEV_keyboard_state; extern SDL_EVDEV_keyboard_state *SDL_EVDEV_kbd_init(void); +extern void SDL_EVDEV_kbd_set_muted(SDL_EVDEV_keyboard_state *state, SDL_bool muted); +extern void SDL_EVDEV_kbd_set_vt_switch_callbacks(SDL_EVDEV_keyboard_state *state, void (*release_callback)(void*), void *release_callback_data, void (*acquire_callback)(void*), void *acquire_callback_data); +extern void SDL_EVDEV_kbd_update(SDL_EVDEV_keyboard_state *state); extern void SDL_EVDEV_kbd_keycode(SDL_EVDEV_keyboard_state *state, unsigned int keycode, int down); extern void SDL_EVDEV_kbd_quit(SDL_EVDEV_keyboard_state *state); diff --git a/SDL2-2.0.12/src/core/linux/SDL_evdev_kbd_default_accents.h b/SDL2-2.30.5/src/core/linux/SDL_evdev_kbd_default_accents.h similarity index 99% rename from SDL2-2.0.12/src/core/linux/SDL_evdev_kbd_default_accents.h rename to SDL2-2.30.5/src/core/linux/SDL_evdev_kbd_default_accents.h index 01caaa2..d0d5234 100644 --- a/SDL2-2.0.12/src/core/linux/SDL_evdev_kbd_default_accents.h +++ b/SDL2-2.30.5/src/core/linux/SDL_evdev_kbd_default_accents.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/core/linux/SDL_evdev_kbd_default_keymap.h b/SDL2-2.30.5/src/core/linux/SDL_evdev_kbd_default_keymap.h similarity index 99% rename from SDL2-2.0.12/src/core/linux/SDL_evdev_kbd_default_keymap.h rename to SDL2-2.30.5/src/core/linux/SDL_evdev_kbd_default_keymap.h index 84cf8fa..d744a54 100644 --- a/SDL2-2.0.12/src/core/linux/SDL_evdev_kbd_default_keymap.h +++ b/SDL2-2.30.5/src/core/linux/SDL_evdev_kbd_default_keymap.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -19,6 +19,8 @@ 3. This notice may not be removed or altered from any source distribution. */ +/* *INDENT-OFF* */ /* clang-format off */ + static unsigned short default_key_map_0[NR_KEYS] = { 0xf200, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, 0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf07f, 0xf009, @@ -4374,6 +4376,8 @@ static unsigned short default_key_map_127[NR_KEYS] = { }; #endif /* INCLUDE_EXTENDED_KEYMAP */ +/* *INDENT-ON* */ /* clang-format on */ + static unsigned short *default_key_maps[MAX_NR_KEYMAPS] = { default_key_map_0, default_key_map_1, @@ -4504,7 +4508,7 @@ static unsigned short *default_key_maps[MAX_NR_KEYMAPS] = { default_key_map_125, default_key_map_126, default_key_map_127, -#else /* !INCLUDE_EXTENDED_KEYMAP */ +#else /* !INCLUDE_EXTENDED_KEYMAP */ NULL, NULL, NULL, diff --git a/SDL2-2.30.5/src/core/linux/SDL_fcitx.c b/SDL2-2.30.5/src/core/linux/SDL_fcitx.c new file mode 100644 index 0000000..f948fc9 --- /dev/null +++ b/SDL2-2.30.5/src/core/linux/SDL_fcitx.c @@ -0,0 +1,491 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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 + +#include "SDL_fcitx.h" +#include "SDL_keycode.h" +#include "SDL_keyboard.h" +#include "../../events/SDL_keyboard_c.h" +#include "SDL_dbus.h" +#include "SDL_syswm.h" +#ifdef SDL_VIDEO_DRIVER_X11 +# include "../../video/x11/SDL_x11video.h" +#endif +#include "SDL_hints.h" + +#define FCITX_DBUS_SERVICE "org.freedesktop.portal.Fcitx" + +#define FCITX_IM_DBUS_PATH "/org/freedesktop/portal/inputmethod" + +#define FCITX_IM_DBUS_INTERFACE "org.fcitx.Fcitx.InputMethod1" +#define FCITX_IC_DBUS_INTERFACE "org.fcitx.Fcitx.InputContext1" + +#define DBUS_TIMEOUT 500 + +typedef struct _FcitxClient +{ + SDL_DBusContext *dbus; + + char *ic_path; + + int id; + + SDL_Rect cursor_rect; +} FcitxClient; + +static FcitxClient fcitx_client; + +static char *GetAppName() +{ +#if defined(__LINUX__) || defined(__FREEBSD__) + char *spot; + char procfile[1024]; + char linkfile[1024]; + int linksize; + +#if defined(__LINUX__) + (void)SDL_snprintf(procfile, sizeof(procfile), "/proc/%d/exe", getpid()); +#elif defined(__FREEBSD__) + (void)SDL_snprintf(procfile, sizeof(procfile), "/proc/%d/file", getpid()); +#endif + linksize = readlink(procfile, linkfile, sizeof(linkfile) - 1); + if (linksize > 0) { + linkfile[linksize] = '\0'; + spot = SDL_strrchr(linkfile, '/'); + if (spot) { + return SDL_strdup(spot + 1); + } else { + return SDL_strdup(linkfile); + } + } +#endif /* __LINUX__ || __FREEBSD__ */ + + return SDL_strdup("SDL_App"); +} + +static size_t Fcitx_GetPreeditString(SDL_DBusContext *dbus, + DBusMessage *msg, + char **ret, + Sint32 *start_pos, + Sint32 *end_pos) +{ + char *text = NULL, *subtext; + size_t text_bytes = 0; + DBusMessageIter iter, array, sub; + Sint32 p_start_pos = -1; + Sint32 p_end_pos = -1; + + dbus->message_iter_init(msg, &iter); + /* Message type is a(si)i, we only need string part */ + if (dbus->message_iter_get_arg_type(&iter) == DBUS_TYPE_ARRAY) { + size_t pos = 0; + /* First pass: calculate string length */ + dbus->message_iter_recurse(&iter, &array); + while (dbus->message_iter_get_arg_type(&array) == DBUS_TYPE_STRUCT) { + dbus->message_iter_recurse(&array, &sub); + subtext = NULL; + if (dbus->message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING) { + dbus->message_iter_get_basic(&sub, &subtext); + if (subtext && *subtext) { + text_bytes += SDL_strlen(subtext); + } + } + dbus->message_iter_next(&sub); + if (dbus->message_iter_get_arg_type(&sub) == DBUS_TYPE_INT32 && p_end_pos == -1) { + /* Type is a bit field defined as follows: */ + /* bit 3: Underline, bit 4: HighLight, bit 5: DontCommit, */ + /* bit 6: Bold, bit 7: Strike, bit 8: Italic */ + Sint32 type; + dbus->message_iter_get_basic(&sub, &type); + /* We only consider highlight */ + if (type & (1 << 4)) { + if (p_start_pos == -1) { + p_start_pos = pos; + } + } else if (p_start_pos != -1 && p_end_pos == -1) { + p_end_pos = pos; + } + } + dbus->message_iter_next(&array); + if (subtext && *subtext) { + pos += SDL_utf8strlen(subtext); + } + } + if (p_start_pos != -1 && p_end_pos == -1) { + p_end_pos = pos; + } + if (text_bytes) { + text = SDL_malloc(text_bytes + 1); + } + + if (text) { + char *pivot = text; + /* Second pass: join all the sub string */ + dbus->message_iter_recurse(&iter, &array); + while (dbus->message_iter_get_arg_type(&array) == DBUS_TYPE_STRUCT) { + dbus->message_iter_recurse(&array, &sub); + if (dbus->message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING) { + dbus->message_iter_get_basic(&sub, &subtext); + if (subtext && *subtext) { + size_t length = SDL_strlen(subtext); + SDL_strlcpy(pivot, subtext, length + 1); + pivot += length; + } + } + dbus->message_iter_next(&array); + } + } else { + text_bytes = 0; + } + } + + *ret = text; + *start_pos = p_start_pos; + *end_pos = p_end_pos; + return text_bytes; +} + +static Sint32 Fcitx_GetPreeditCursorByte(SDL_DBusContext *dbus, DBusMessage *msg) +{ + Sint32 byte = -1; + DBusMessageIter iter; + + dbus->message_iter_init(msg, &iter); + + dbus->message_iter_next(&iter); + + if (dbus->message_iter_get_arg_type(&iter) != DBUS_TYPE_INT32) { + return -1; + } + + dbus->message_iter_get_basic(&iter, &byte); + + return byte; +} + +static DBusHandlerResult DBus_MessageFilter(DBusConnection *conn, DBusMessage *msg, void *data) +{ + SDL_DBusContext *dbus = (SDL_DBusContext *)data; + + if (dbus->message_is_signal(msg, FCITX_IC_DBUS_INTERFACE, "CommitString")) { + DBusMessageIter iter; + const char *text = NULL; + + dbus->message_iter_init(msg, &iter); + dbus->message_iter_get_basic(&iter, &text); + + if (text && *text) { + char buf[SDL_TEXTINPUTEVENT_TEXT_SIZE]; + size_t text_bytes = SDL_strlen(text), i = 0; + + while (i < text_bytes) { + size_t sz = SDL_utf8strlcpy(buf, text + i, sizeof(buf)); + SDL_SendKeyboardText(buf); + + i += sz; + } + } + + return DBUS_HANDLER_RESULT_HANDLED; + } + + if (dbus->message_is_signal(msg, FCITX_IC_DBUS_INTERFACE, "UpdateFormattedPreedit")) { + char *text = NULL; + Sint32 start_pos, end_pos; + size_t text_bytes = Fcitx_GetPreeditString(dbus, msg, &text, &start_pos, &end_pos); + if (text_bytes) { + if (SDL_GetHintBoolean(SDL_HINT_IME_SUPPORT_EXTENDED_TEXT, SDL_FALSE)) { + if (start_pos == -1) { + Sint32 byte_pos = Fcitx_GetPreeditCursorByte(dbus, msg); + start_pos = byte_pos >= 0 ? SDL_utf8strnlen(text, byte_pos) : -1; + } + SDL_SendEditingText(text, start_pos, end_pos >= 0 ? end_pos - start_pos : -1); + } else { + char buf[SDL_TEXTEDITINGEVENT_TEXT_SIZE]; + size_t i = 0; + size_t cursor = 0; + while (i < text_bytes) { + const size_t sz = SDL_utf8strlcpy(buf, text + i, sizeof(buf)); + const size_t chars = SDL_utf8strlen(buf); + + SDL_SendEditingText(buf, cursor, chars); + + i += sz; + cursor += chars; + } + } + SDL_free(text); + } else { + SDL_SendEditingText("", 0, 0); + } + + SDL_Fcitx_UpdateTextRect(NULL); + return DBUS_HANDLER_RESULT_HANDLED; + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static void FcitxClientICCallMethod(FcitxClient *client, const char *method) +{ + if (!client->ic_path) { + return; + } + SDL_DBus_CallVoidMethod(FCITX_DBUS_SERVICE, client->ic_path, FCITX_IC_DBUS_INTERFACE, method, DBUS_TYPE_INVALID); +} + +static void SDLCALL Fcitx_SetCapabilities(void *data, + const char *name, + const char *old_val, + const char *internal_editing) +{ + FcitxClient *client = (FcitxClient *)data; + Uint64 caps = 0; + if (!client->ic_path) { + return; + } + + if (!(internal_editing && *internal_editing == '1')) { + caps |= (1 << 1); /* Preedit Flag */ + caps |= (1 << 4); /* Formatted Preedit Flag */ + } + + SDL_DBus_CallVoidMethod(FCITX_DBUS_SERVICE, client->ic_path, FCITX_IC_DBUS_INTERFACE, "SetCapability", DBUS_TYPE_UINT64, &caps, DBUS_TYPE_INVALID); +} + +static SDL_bool FcitxCreateInputContext(SDL_DBusContext *dbus, const char *appname, char **ic_path) +{ + const char *program = "program"; + SDL_bool retval = SDL_FALSE; + + if (dbus && dbus->session_conn) { + DBusMessage *msg = dbus->message_new_method_call(FCITX_DBUS_SERVICE, FCITX_IM_DBUS_PATH, FCITX_IM_DBUS_INTERFACE, "CreateInputContext"); + if (msg) { + DBusMessage *reply = NULL; + DBusMessageIter args, array, sub; + dbus->message_iter_init_append(msg, &args); + dbus->message_iter_open_container(&args, DBUS_TYPE_ARRAY, "(ss)", &array); + dbus->message_iter_open_container(&array, DBUS_TYPE_STRUCT, 0, &sub); + dbus->message_iter_append_basic(&sub, DBUS_TYPE_STRING, &program); + dbus->message_iter_append_basic(&sub, DBUS_TYPE_STRING, &appname); + dbus->message_iter_close_container(&array, &sub); + dbus->message_iter_close_container(&args, &array); + reply = dbus->connection_send_with_reply_and_block(dbus->session_conn, msg, 300, NULL); + if (reply) { + if (dbus->message_get_args(reply, NULL, DBUS_TYPE_OBJECT_PATH, ic_path, DBUS_TYPE_INVALID)) { + retval = SDL_TRUE; + } + dbus->message_unref(reply); + } + dbus->message_unref(msg); + } + } + return retval; +} + +static SDL_bool FcitxClientCreateIC(FcitxClient *client) +{ + char *appname = GetAppName(); + char *ic_path = NULL; + SDL_DBusContext *dbus = client->dbus; + + /* SDL_DBus_CallMethod cannot handle a(ss) type, call dbus function directly */ + if (!FcitxCreateInputContext(dbus, appname, &ic_path)) { + ic_path = NULL; /* just in case. */ + } + + SDL_free(appname); + + if (ic_path) { + SDL_free(client->ic_path); + client->ic_path = SDL_strdup(ic_path); + + dbus->bus_add_match(dbus->session_conn, + "type='signal', interface='org.fcitx.Fcitx.InputContext1'", + NULL); + dbus->connection_add_filter(dbus->session_conn, + &DBus_MessageFilter, dbus, + NULL); + dbus->connection_flush(dbus->session_conn); + + SDL_AddHintCallback(SDL_HINT_IME_INTERNAL_EDITING, Fcitx_SetCapabilities, client); + return SDL_TRUE; + } + + return SDL_FALSE; +} + +static Uint32 Fcitx_ModState(void) +{ + Uint32 fcitx_mods = 0; + SDL_Keymod sdl_mods = SDL_GetModState(); + + if (sdl_mods & KMOD_SHIFT) { + fcitx_mods |= (1 << 0); + } + if (sdl_mods & KMOD_CAPS) { + fcitx_mods |= (1 << 1); + } + if (sdl_mods & KMOD_CTRL) { + fcitx_mods |= (1 << 2); + } + if (sdl_mods & KMOD_ALT) { + fcitx_mods |= (1 << 3); + } + if (sdl_mods & KMOD_NUM) { + fcitx_mods |= (1 << 4); + } + if (sdl_mods & KMOD_MODE) { + fcitx_mods |= (1 << 7); + } + if (sdl_mods & KMOD_LGUI) { + fcitx_mods |= (1 << 6); + } + if (sdl_mods & KMOD_RGUI) { + fcitx_mods |= (1 << 28); + } + + return fcitx_mods; +} + +SDL_bool SDL_Fcitx_Init() +{ + fcitx_client.dbus = SDL_DBus_GetContext(); + + fcitx_client.cursor_rect.x = -1; + fcitx_client.cursor_rect.y = -1; + fcitx_client.cursor_rect.w = 0; + fcitx_client.cursor_rect.h = 0; + + return FcitxClientCreateIC(&fcitx_client); +} + +void SDL_Fcitx_Quit() +{ + FcitxClientICCallMethod(&fcitx_client, "DestroyIC"); + if (fcitx_client.ic_path) { + SDL_free(fcitx_client.ic_path); + fcitx_client.ic_path = NULL; + } +} + +void SDL_Fcitx_SetFocus(SDL_bool focused) +{ + if (focused) { + FcitxClientICCallMethod(&fcitx_client, "FocusIn"); + } else { + FcitxClientICCallMethod(&fcitx_client, "FocusOut"); + } +} + +void SDL_Fcitx_Reset(void) +{ + FcitxClientICCallMethod(&fcitx_client, "Reset"); +} + +SDL_bool SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state) +{ + Uint32 mod_state = Fcitx_ModState(); + Uint32 handled = SDL_FALSE; + Uint32 is_release = (state == SDL_RELEASED); + Uint32 event_time = 0; + + if (!fcitx_client.ic_path) { + return SDL_FALSE; + } + + if (SDL_DBus_CallMethod(FCITX_DBUS_SERVICE, fcitx_client.ic_path, FCITX_IC_DBUS_INTERFACE, "ProcessKeyEvent", + DBUS_TYPE_UINT32, &keysym, DBUS_TYPE_UINT32, &keycode, DBUS_TYPE_UINT32, &mod_state, DBUS_TYPE_BOOLEAN, &is_release, DBUS_TYPE_UINT32, &event_time, DBUS_TYPE_INVALID, + DBUS_TYPE_BOOLEAN, &handled, DBUS_TYPE_INVALID)) { + if (handled) { + SDL_Fcitx_UpdateTextRect(NULL); + return SDL_TRUE; + } + } + + return SDL_FALSE; +} + +void SDL_Fcitx_UpdateTextRect(const SDL_Rect *rect) +{ + SDL_Window *focused_win = NULL; + SDL_SysWMinfo info; + int x = 0, y = 0; + SDL_Rect *cursor = &fcitx_client.cursor_rect; + + if (rect) { + SDL_copyp(cursor, rect); + } + + focused_win = SDL_GetKeyboardFocus(); + if (!focused_win) { + return; + } + + SDL_VERSION(&info.version); + if (!SDL_GetWindowWMInfo(focused_win, &info)) { + return; + } + + SDL_GetWindowPosition(focused_win, &x, &y); + +#ifdef SDL_VIDEO_DRIVER_X11 + if (info.subsystem == SDL_SYSWM_X11) { + SDL_DisplayData *displaydata = (SDL_DisplayData *) SDL_GetDisplayForWindow(focused_win)->driverdata; + + Display *x_disp = info.info.x11.display; + Window x_win = info.info.x11.window; + int x_screen = displaydata->screen; + Window unused; + X11_XTranslateCoordinates(x_disp, x_win, RootWindow(x_disp, x_screen), 0, 0, &x, &y, &unused); + } +#endif + + if (cursor->x == -1 && cursor->y == -1 && cursor->w == 0 && cursor->h == 0) { + /* move to bottom left */ + int w = 0, h = 0; + SDL_GetWindowSize(focused_win, &w, &h); + cursor->x = 0; + cursor->y = h; + } + + x += cursor->x; + y += cursor->y; + + SDL_DBus_CallVoidMethod(FCITX_DBUS_SERVICE, fcitx_client.ic_path, FCITX_IC_DBUS_INTERFACE, "SetCursorRect", + DBUS_TYPE_INT32, &x, DBUS_TYPE_INT32, &y, DBUS_TYPE_INT32, &cursor->w, DBUS_TYPE_INT32, &cursor->h, DBUS_TYPE_INVALID); +} + +void SDL_Fcitx_PumpEvents(void) +{ + SDL_DBusContext *dbus = fcitx_client.dbus; + DBusConnection *conn = dbus->session_conn; + + dbus->connection_read_write(conn, 0); + + while (dbus->connection_dispatch(conn) == DBUS_DISPATCH_DATA_REMAINS) { + /* Do nothing, actual work happens in DBus_MessageFilter */ + } +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/core/linux/SDL_fcitx.h b/SDL2-2.30.5/src/core/linux/SDL_fcitx.h similarity index 90% rename from SDL2-2.0.12/src/core/linux/SDL_fcitx.h rename to SDL2-2.30.5/src/core/linux/SDL_fcitx.h index bb725bb..4a893f2 100644 --- a/SDL2-2.0.12/src/core/linux/SDL_fcitx.h +++ b/SDL2-2.30.5/src/core/linux/SDL_fcitx.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -31,8 +31,8 @@ extern SDL_bool SDL_Fcitx_Init(void); extern void SDL_Fcitx_Quit(void); extern void SDL_Fcitx_SetFocus(SDL_bool focused); extern void SDL_Fcitx_Reset(void); -extern SDL_bool SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode); -extern void SDL_Fcitx_UpdateTextRect(SDL_Rect *rect); +extern SDL_bool SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state); +extern void SDL_Fcitx_UpdateTextRect(const SDL_Rect *rect); extern void SDL_Fcitx_PumpEvents(void); #endif /* SDL_fcitx_h_ */ diff --git a/SDL2-2.30.5/src/core/linux/SDL_ibus.c b/SDL2-2.30.5/src/core/linux/SDL_ibus.c new file mode 100644 index 0000000..31179d4 --- /dev/null +++ b/SDL2-2.30.5/src/core/linux/SDL_ibus.c @@ -0,0 +1,765 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef HAVE_IBUS_IBUS_H +#include "SDL.h" +#include "SDL_hints.h" +#include "SDL_syswm.h" +#include "SDL_ibus.h" +#include "SDL_dbus.h" +#include "../../video/SDL_sysvideo.h" +#include "../../events/SDL_keyboard_c.h" + +#ifdef SDL_VIDEO_DRIVER_X11 + #include "../../video/x11/SDL_x11video.h" +#endif + +#include +#include +#include + +static const char IBUS_PATH[] = "/org/freedesktop/IBus"; + +static const char IBUS_SERVICE[] = "org.freedesktop.IBus"; +static const char IBUS_INTERFACE[] = "org.freedesktop.IBus"; +static const char IBUS_INPUT_INTERFACE[] = "org.freedesktop.IBus.InputContext"; + +static const char IBUS_PORTAL_SERVICE[] = "org.freedesktop.portal.IBus"; +static const char IBUS_PORTAL_INTERFACE[] = "org.freedesktop.IBus.Portal"; +static const char IBUS_PORTAL_INPUT_INTERFACE[] = "org.freedesktop.IBus.InputContext"; + +static const char *ibus_service = NULL; +static const char *ibus_interface = NULL; +static const char *ibus_input_interface = NULL; +static char *input_ctx_path = NULL; +static SDL_Rect ibus_cursor_rect = { 0, 0, 0, 0 }; +static DBusConnection *ibus_conn = NULL; +static SDL_bool ibus_is_portal_interface = SDL_FALSE; +static char *ibus_addr_file = NULL; +static int inotify_fd = -1, inotify_wd = -1; + +static Uint32 IBus_ModState(void) +{ + Uint32 ibus_mods = 0; + SDL_Keymod sdl_mods = SDL_GetModState(); + + /* Not sure about MOD3, MOD4 and HYPER mappings */ + if (sdl_mods & KMOD_LSHIFT) { + ibus_mods |= IBUS_SHIFT_MASK; + } + if (sdl_mods & KMOD_CAPS) { + ibus_mods |= IBUS_LOCK_MASK; + } + if (sdl_mods & KMOD_LCTRL) { + ibus_mods |= IBUS_CONTROL_MASK; + } + if (sdl_mods & KMOD_LALT) { + ibus_mods |= IBUS_MOD1_MASK; + } + if (sdl_mods & KMOD_NUM) { + ibus_mods |= IBUS_MOD2_MASK; + } + if (sdl_mods & KMOD_MODE) { + ibus_mods |= IBUS_MOD5_MASK; + } + if (sdl_mods & KMOD_LGUI) { + ibus_mods |= IBUS_SUPER_MASK; + } + if (sdl_mods & KMOD_RGUI) { + ibus_mods |= IBUS_META_MASK; + } + + return ibus_mods; +} + +static SDL_bool IBus_EnterVariant(DBusConnection *conn, DBusMessageIter *iter, SDL_DBusContext *dbus, + DBusMessageIter *inside, const char *struct_id, size_t id_size) +{ + DBusMessageIter sub; + if (dbus->message_iter_get_arg_type(iter) != DBUS_TYPE_VARIANT) { + return SDL_FALSE; + } + + dbus->message_iter_recurse(iter, &sub); + + if (dbus->message_iter_get_arg_type(&sub) != DBUS_TYPE_STRUCT) { + return SDL_FALSE; + } + + dbus->message_iter_recurse(&sub, inside); + + if (dbus->message_iter_get_arg_type(inside) != DBUS_TYPE_STRING) { + return SDL_FALSE; + } + + dbus->message_iter_get_basic(inside, &struct_id); + if (!struct_id || SDL_strncmp(struct_id, struct_id, id_size) != 0) { + return SDL_FALSE; + } + return SDL_TRUE; +} + +static SDL_bool IBus_GetDecorationPosition(DBusConnection *conn, DBusMessageIter *iter, SDL_DBusContext *dbus, + Uint32 *start_pos, Uint32 *end_pos) +{ + DBusMessageIter sub1, sub2, array; + + if (!IBus_EnterVariant(conn, iter, dbus, &sub1, "IBusText", sizeof("IBusText"))) { + return SDL_FALSE; + } + + dbus->message_iter_next(&sub1); + dbus->message_iter_next(&sub1); + dbus->message_iter_next(&sub1); + + if (!IBus_EnterVariant(conn, &sub1, dbus, &sub2, "IBusAttrList", sizeof("IBusAttrList"))) { + return SDL_FALSE; + } + + dbus->message_iter_next(&sub2); + dbus->message_iter_next(&sub2); + + if (dbus->message_iter_get_arg_type(&sub2) != DBUS_TYPE_ARRAY) { + return SDL_FALSE; + } + + dbus->message_iter_recurse(&sub2, &array); + + while (dbus->message_iter_get_arg_type(&array) == DBUS_TYPE_VARIANT) { + DBusMessageIter sub; + if (IBus_EnterVariant(conn, &array, dbus, &sub, "IBusAttribute", sizeof("IBusAttribute"))) { + Uint32 type; + + dbus->message_iter_next(&sub); + dbus->message_iter_next(&sub); + + /* From here on, the structure looks like this: */ + /* Uint32 type: 1=underline, 2=foreground, 3=background */ + /* Uint32 value: for underline it's 0=NONE, 1=SINGLE, 2=DOUBLE, */ + /* 3=LOW, 4=ERROR */ + /* for foreground and background it's a color */ + /* Uint32 start_index: starting position for the style (utf8-char) */ + /* Uint32 end_index: end position for the style (utf8-char) */ + + dbus->message_iter_get_basic(&sub, &type); + /* We only use the background type to determine the selection */ + if (type == 3) { + Uint32 start = -1; + dbus->message_iter_next(&sub); + dbus->message_iter_next(&sub); + if (dbus->message_iter_get_arg_type(&sub) == DBUS_TYPE_UINT32) { + dbus->message_iter_get_basic(&sub, &start); + dbus->message_iter_next(&sub); + if (dbus->message_iter_get_arg_type(&sub) == DBUS_TYPE_UINT32) { + dbus->message_iter_get_basic(&sub, end_pos); + *start_pos = start; + return SDL_TRUE; + } + } + } + } + dbus->message_iter_next(&array); + } + return SDL_FALSE; +} + +static const char *IBus_GetVariantText(DBusConnection *conn, DBusMessageIter *iter, SDL_DBusContext *dbus) +{ + /* The text we need is nested weirdly, use dbus-monitor to see the structure better */ + const char *text = NULL; + DBusMessageIter sub; + + if (!IBus_EnterVariant(conn, iter, dbus, &sub, "IBusText", sizeof("IBusText"))) { + return NULL; + } + + dbus->message_iter_next(&sub); + dbus->message_iter_next(&sub); + + if (dbus->message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING) { + return NULL; + } + dbus->message_iter_get_basic(&sub, &text); + + return text; +} + +static SDL_bool IBus_GetVariantCursorPos(DBusConnection *conn, DBusMessageIter *iter, SDL_DBusContext *dbus, + Uint32 *pos) +{ + dbus->message_iter_next(iter); + + if (dbus->message_iter_get_arg_type(iter) != DBUS_TYPE_UINT32) { + return SDL_FALSE; + } + + dbus->message_iter_get_basic(iter, pos); + + return SDL_TRUE; +} + +static DBusHandlerResult IBus_MessageHandler(DBusConnection *conn, DBusMessage *msg, void *user_data) +{ + SDL_DBusContext *dbus = (SDL_DBusContext *)user_data; + + if (dbus->message_is_signal(msg, ibus_input_interface, "CommitText")) { + DBusMessageIter iter; + const char *text; + + dbus->message_iter_init(msg, &iter); + text = IBus_GetVariantText(conn, &iter, dbus); + + if (text && *text) { + char buf[SDL_TEXTINPUTEVENT_TEXT_SIZE]; + size_t text_bytes = SDL_strlen(text), i = 0; + + while (i < text_bytes) { + size_t sz = SDL_utf8strlcpy(buf, text + i, sizeof(buf)); + SDL_SendKeyboardText(buf); + + i += sz; + } + } + + return DBUS_HANDLER_RESULT_HANDLED; + } + + if (dbus->message_is_signal(msg, ibus_input_interface, "UpdatePreeditText")) { + DBusMessageIter iter; + const char *text; + + dbus->message_iter_init(msg, &iter); + text = IBus_GetVariantText(conn, &iter, dbus); + + if (text) { + if (SDL_GetHintBoolean(SDL_HINT_IME_SUPPORT_EXTENDED_TEXT, SDL_FALSE)) { + Uint32 pos, start_pos, end_pos; + SDL_bool has_pos = SDL_FALSE; + SDL_bool has_dec_pos = SDL_FALSE; + + dbus->message_iter_init(msg, &iter); + has_dec_pos = IBus_GetDecorationPosition(conn, &iter, dbus, &start_pos, &end_pos); + if (!has_dec_pos) { + dbus->message_iter_init(msg, &iter); + has_pos = IBus_GetVariantCursorPos(conn, &iter, dbus, &pos); + } + + if (has_dec_pos) { + SDL_SendEditingText(text, start_pos, end_pos - start_pos); + } else if (has_pos) { + SDL_SendEditingText(text, pos, -1); + } else { + SDL_SendEditingText(text, -1, -1); + } + } else { + char buf[SDL_TEXTEDITINGEVENT_TEXT_SIZE]; + size_t text_bytes = SDL_strlen(text), i = 0; + size_t cursor = 0; + + do { + const size_t sz = SDL_utf8strlcpy(buf, text + i, sizeof(buf)); + const size_t chars = SDL_utf8strlen(buf); + + SDL_SendEditingText(buf, cursor, chars); + i += sz; + cursor += chars; + } while (i < text_bytes); + } + } + + SDL_IBus_UpdateTextRect(NULL); + + return DBUS_HANDLER_RESULT_HANDLED; + } + + if (dbus->message_is_signal(msg, ibus_input_interface, "HidePreeditText")) { + SDL_SendEditingText("", 0, 0); + return DBUS_HANDLER_RESULT_HANDLED; + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static char *IBus_ReadAddressFromFile(const char *file_path) +{ + char addr_buf[1024]; + SDL_bool success = SDL_FALSE; + FILE *addr_file; + + addr_file = fopen(file_path, "r"); + if (!addr_file) { + return NULL; + } + + while (fgets(addr_buf, sizeof(addr_buf), addr_file)) { + if (SDL_strncmp(addr_buf, "IBUS_ADDRESS=", sizeof("IBUS_ADDRESS=") - 1) == 0) { + size_t sz = SDL_strlen(addr_buf); + if (addr_buf[sz - 1] == '\n') { + addr_buf[sz - 1] = 0; + } + if (addr_buf[sz - 2] == '\r') { + addr_buf[sz - 2] = 0; + } + success = SDL_TRUE; + break; + } + } + + (void)fclose(addr_file); + + if (success) { + return SDL_strdup(addr_buf + (sizeof("IBUS_ADDRESS=") - 1)); + } else { + return NULL; + } +} + +static char *IBus_GetDBusAddressFilename(void) +{ + SDL_DBusContext *dbus; + const char *disp_env; + char config_dir[PATH_MAX]; + char *display = NULL; + const char *addr; + const char *conf_env; + char *key; + char file_path[PATH_MAX]; + const char *host; + char *disp_num, *screen_num; + + if (ibus_addr_file) { + return SDL_strdup(ibus_addr_file); + } + + dbus = SDL_DBus_GetContext(); + if (!dbus) { + return NULL; + } + + /* Use this environment variable if it exists. */ + addr = SDL_getenv("IBUS_ADDRESS"); + if (addr && *addr) { + return SDL_strdup(addr); + } + + /* Otherwise, we have to get the hostname, display, machine id, config dir + and look up the address from a filepath using all those bits, eek. */ + disp_env = SDL_getenv("DISPLAY"); + + if (!disp_env || !*disp_env) { + display = SDL_strdup(":0.0"); + } else { + display = SDL_strdup(disp_env); + } + + host = display; + disp_num = SDL_strrchr(display, ':'); + screen_num = SDL_strrchr(display, '.'); + + if (!disp_num) { + SDL_free(display); + return NULL; + } + + *disp_num = 0; + disp_num++; + + if (screen_num) { + *screen_num = 0; + } + + if (!*host) { + const char *session = SDL_getenv("XDG_SESSION_TYPE"); + if (session && SDL_strcmp(session, "wayland") == 0) { + host = "unix-wayland"; + } else { + host = "unix"; + } + } + + SDL_memset(config_dir, 0, sizeof(config_dir)); + + conf_env = SDL_getenv("XDG_CONFIG_HOME"); + if (conf_env && *conf_env) { + SDL_strlcpy(config_dir, conf_env, sizeof(config_dir)); + } else { + const char *home_env = SDL_getenv("HOME"); + if (!home_env || !*home_env) { + SDL_free(display); + return NULL; + } + (void)SDL_snprintf(config_dir, sizeof(config_dir), "%s/.config", home_env); + } + + key = SDL_DBus_GetLocalMachineId(); + + if (!key) { + SDL_free(display); + return NULL; + } + + SDL_memset(file_path, 0, sizeof(file_path)); + (void)SDL_snprintf(file_path, sizeof(file_path), "%s/ibus/bus/%s-%s-%s", + config_dir, key, host, disp_num); + dbus->free(key); + SDL_free(display); + + return SDL_strdup(file_path); +} + +static SDL_bool IBus_CheckConnection(SDL_DBusContext *dbus); + +static void SDLCALL IBus_SetCapabilities(void *data, const char *name, const char *old_val, + const char *internal_editing) +{ + SDL_DBusContext *dbus = SDL_DBus_GetContext(); + + if (IBus_CheckConnection(dbus)) { + Uint32 caps = IBUS_CAP_FOCUS; + if (!(internal_editing && *internal_editing == '1')) { + caps |= IBUS_CAP_PREEDIT_TEXT; + } + + SDL_DBus_CallVoidMethodOnConnection(ibus_conn, ibus_service, input_ctx_path, ibus_input_interface, "SetCapabilities", + DBUS_TYPE_UINT32, &caps, DBUS_TYPE_INVALID); + } +} + +static SDL_bool IBus_SetupConnection(SDL_DBusContext *dbus, const char *addr) +{ + const char *client_name = "SDL2_Application"; + const char *path = NULL; + SDL_bool result = SDL_FALSE; + DBusObjectPathVTable ibus_vtable; + + SDL_zero(ibus_vtable); + ibus_vtable.message_function = &IBus_MessageHandler; + + /* try the portal interface first. Modern systems have this in general, + and sandbox things like FlakPak and Snaps, etc, require it. */ + + ibus_is_portal_interface = SDL_TRUE; + ibus_service = IBUS_PORTAL_SERVICE; + ibus_interface = IBUS_PORTAL_INTERFACE; + ibus_input_interface = IBUS_PORTAL_INPUT_INTERFACE; + ibus_conn = dbus->session_conn; + + result = SDL_DBus_CallMethodOnConnection(ibus_conn, ibus_service, IBUS_PATH, ibus_interface, "CreateInputContext", + DBUS_TYPE_STRING, &client_name, DBUS_TYPE_INVALID, + DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID); + if (!result) { + ibus_is_portal_interface = SDL_FALSE; + ibus_service = IBUS_SERVICE; + ibus_interface = IBUS_INTERFACE; + ibus_input_interface = IBUS_INPUT_INTERFACE; + ibus_conn = dbus->connection_open_private(addr, NULL); + + if (!ibus_conn) { + return SDL_FALSE; /* oh well. */ + } + + dbus->connection_flush(ibus_conn); + + if (!dbus->bus_register(ibus_conn, NULL)) { + ibus_conn = NULL; + return SDL_FALSE; + } + + dbus->connection_flush(ibus_conn); + + result = SDL_DBus_CallMethodOnConnection(ibus_conn, ibus_service, IBUS_PATH, ibus_interface, "CreateInputContext", + DBUS_TYPE_STRING, &client_name, DBUS_TYPE_INVALID, + DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID); + } else { + /* re-using dbus->session_conn */ + dbus->connection_ref(ibus_conn); + } + + if (result) { + char matchstr[128]; + (void)SDL_snprintf(matchstr, sizeof(matchstr), "type='signal',interface='%s'", ibus_input_interface); + SDL_free(input_ctx_path); + input_ctx_path = SDL_strdup(path); + SDL_AddHintCallback(SDL_HINT_IME_INTERNAL_EDITING, IBus_SetCapabilities, NULL); + dbus->bus_add_match(ibus_conn, matchstr, NULL); + dbus->connection_try_register_object_path(ibus_conn, input_ctx_path, &ibus_vtable, dbus, NULL); + dbus->connection_flush(ibus_conn); + } + + SDL_IBus_SetFocus(SDL_GetKeyboardFocus() != NULL); + SDL_IBus_UpdateTextRect(NULL); + + return result; +} + +static SDL_bool IBus_CheckConnection(SDL_DBusContext *dbus) +{ + if (!dbus) { + return SDL_FALSE; + } + + if (ibus_conn && dbus->connection_get_is_connected(ibus_conn)) { + return SDL_TRUE; + } + + if (inotify_fd > 0 && inotify_wd > 0) { + char buf[1024]; + ssize_t readsize = read(inotify_fd, buf, sizeof(buf)); + if (readsize > 0) { + + char *p; + SDL_bool file_updated = SDL_FALSE; + + for (p = buf; p < buf + readsize; /**/) { + struct inotify_event *event = (struct inotify_event *)p; + if (event->len > 0) { + char *addr_file_no_path = SDL_strrchr(ibus_addr_file, '/'); + if (!addr_file_no_path) { + return SDL_FALSE; + } + + if (SDL_strcmp(addr_file_no_path + 1, event->name) == 0) { + file_updated = SDL_TRUE; + break; + } + } + + p += sizeof(struct inotify_event) + event->len; + } + + if (file_updated) { + char *addr = IBus_ReadAddressFromFile(ibus_addr_file); + if (addr) { + SDL_bool result = IBus_SetupConnection(dbus, addr); + SDL_free(addr); + return result; + } + } + } + } + + return SDL_FALSE; +} + +SDL_bool SDL_IBus_Init(void) +{ + SDL_bool result = SDL_FALSE; + SDL_DBusContext *dbus = SDL_DBus_GetContext(); + + if (dbus) { + char *addr_file = IBus_GetDBusAddressFilename(); + char *addr; + char *addr_file_dir; + + if (!addr_file) { + return SDL_FALSE; + } + + addr = IBus_ReadAddressFromFile(addr_file); + if (!addr) { + SDL_free(addr_file); + return SDL_FALSE; + } + + if (ibus_addr_file) { + SDL_free(ibus_addr_file); + } + ibus_addr_file = SDL_strdup(addr_file); + + if (inotify_fd < 0) { + inotify_fd = inotify_init(); + fcntl(inotify_fd, F_SETFL, O_NONBLOCK); + } + + addr_file_dir = SDL_strrchr(addr_file, '/'); + if (addr_file_dir) { + *addr_file_dir = 0; + } + + inotify_wd = inotify_add_watch(inotify_fd, addr_file, IN_CREATE | IN_MODIFY); + SDL_free(addr_file); + + result = IBus_SetupConnection(dbus, addr); + SDL_free(addr); + + /* don't use the addr_file if using the portal interface. */ + if (result && ibus_is_portal_interface) { + if (inotify_fd > 0) { + if (inotify_wd > 0) { + inotify_rm_watch(inotify_fd, inotify_wd); + inotify_wd = -1; + } + close(inotify_fd); + inotify_fd = -1; + } + } + } + + return result; +} + +void SDL_IBus_Quit(void) +{ + SDL_DBusContext *dbus; + + if (input_ctx_path) { + SDL_free(input_ctx_path); + input_ctx_path = NULL; + } + + if (ibus_addr_file) { + SDL_free(ibus_addr_file); + ibus_addr_file = NULL; + } + + dbus = SDL_DBus_GetContext(); + + /* if using portal, ibus_conn == session_conn; don't release it here. */ + if (dbus && ibus_conn && !ibus_is_portal_interface) { + dbus->connection_close(ibus_conn); + dbus->connection_unref(ibus_conn); + } + + ibus_conn = NULL; + ibus_service = NULL; + ibus_interface = NULL; + ibus_input_interface = NULL; + ibus_is_portal_interface = SDL_FALSE; + + if (inotify_fd > 0 && inotify_wd > 0) { + inotify_rm_watch(inotify_fd, inotify_wd); + inotify_wd = -1; + } + + /* !!! FIXME: should we close(inotify_fd) here? */ + + SDL_DelHintCallback(SDL_HINT_IME_INTERNAL_EDITING, IBus_SetCapabilities, NULL); + + SDL_memset(&ibus_cursor_rect, 0, sizeof(ibus_cursor_rect)); +} + +static void IBus_SimpleMessage(const char *method) +{ + SDL_DBusContext *dbus = SDL_DBus_GetContext(); + + if ((input_ctx_path) && (IBus_CheckConnection(dbus))) { + SDL_DBus_CallVoidMethodOnConnection(ibus_conn, ibus_service, input_ctx_path, ibus_input_interface, method, DBUS_TYPE_INVALID); + } +} + +void SDL_IBus_SetFocus(SDL_bool focused) +{ + const char *method = focused ? "FocusIn" : "FocusOut"; + IBus_SimpleMessage(method); +} + +void SDL_IBus_Reset(void) +{ + IBus_SimpleMessage("Reset"); +} + +SDL_bool SDL_IBus_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state) +{ + Uint32 result = 0; + SDL_DBusContext *dbus = SDL_DBus_GetContext(); + + if (IBus_CheckConnection(dbus)) { + Uint32 mods = IBus_ModState(); + Uint32 ibus_keycode = keycode - 8; + if (state == SDL_RELEASED) { + mods |= (1 << 30); // IBUS_RELEASE_MASK + } + if (!SDL_DBus_CallMethodOnConnection(ibus_conn, ibus_service, input_ctx_path, ibus_input_interface, "ProcessKeyEvent", + DBUS_TYPE_UINT32, &keysym, DBUS_TYPE_UINT32, &ibus_keycode, DBUS_TYPE_UINT32, &mods, DBUS_TYPE_INVALID, + DBUS_TYPE_BOOLEAN, &result, DBUS_TYPE_INVALID)) { + result = 0; + } + } + + SDL_IBus_UpdateTextRect(NULL); + + return result ? SDL_TRUE : SDL_FALSE; +} + +void SDL_IBus_UpdateTextRect(const SDL_Rect *rect) +{ + SDL_Window *focused_win; + SDL_SysWMinfo info; + int x = 0, y = 0; + SDL_DBusContext *dbus; + + if (rect) { + SDL_memcpy(&ibus_cursor_rect, rect, sizeof(ibus_cursor_rect)); + } + + focused_win = SDL_GetKeyboardFocus(); + if (!focused_win) { + return; + } + + SDL_VERSION(&info.version); + if (!SDL_GetWindowWMInfo(focused_win, &info)) { + return; + } + + SDL_GetWindowPosition(focused_win, &x, &y); + +#ifdef SDL_VIDEO_DRIVER_X11 + if (info.subsystem == SDL_SYSWM_X11) { + SDL_DisplayData *displaydata = (SDL_DisplayData *) SDL_GetDisplayForWindow(focused_win)->driverdata; + + Display *x_disp = info.info.x11.display; + Window x_win = info.info.x11.window; + int x_screen = displaydata->screen; + Window unused; + + X11_XTranslateCoordinates(x_disp, x_win, RootWindow(x_disp, x_screen), 0, 0, &x, &y, &unused); + } +#endif + + x += ibus_cursor_rect.x; + y += ibus_cursor_rect.y; + + dbus = SDL_DBus_GetContext(); + + if (IBus_CheckConnection(dbus)) { + SDL_DBus_CallVoidMethodOnConnection(ibus_conn, ibus_service, input_ctx_path, ibus_input_interface, "SetCursorLocation", + DBUS_TYPE_INT32, &x, DBUS_TYPE_INT32, &y, DBUS_TYPE_INT32, &ibus_cursor_rect.w, DBUS_TYPE_INT32, &ibus_cursor_rect.h, DBUS_TYPE_INVALID); + } +} + +void SDL_IBus_PumpEvents(void) +{ + SDL_DBusContext *dbus = SDL_DBus_GetContext(); + + if (IBus_CheckConnection(dbus)) { + dbus->connection_read_write(ibus_conn, 0); + + while (dbus->connection_dispatch(ibus_conn) == DBUS_DISPATCH_DATA_REMAINS) { + /* Do nothing, actual work happens in IBus_MessageHandler */ + } + } +} + +#endif + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/core/linux/SDL_ibus.h b/SDL2-2.30.5/src/core/linux/SDL_ibus.h similarity index 89% rename from SDL2-2.0.12/src/core/linux/SDL_ibus.h rename to SDL2-2.30.5/src/core/linux/SDL_ibus.h index d3b85e3..a4ea140 100644 --- a/SDL2-2.0.12/src/core/linux/SDL_ibus.h +++ b/SDL2-2.30.5/src/core/linux/SDL_ibus.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -40,14 +40,14 @@ extern void SDL_IBus_Reset(void); /* Sends a keypress event to IBus, returns SDL_TRUE if IBus used this event to update its candidate list or change input methods. PumpEvents should be - called some time after this, to recieve the TextInput / TextEditing event back. */ -extern SDL_bool SDL_IBus_ProcessKeyEvent(Uint32 keysym, Uint32 keycode); + called some time after this, to receive the TextInput / TextEditing event back. */ +extern SDL_bool SDL_IBus_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state); -/* Update the position of IBus' candidate list. If rect is NULL then this will +/* Update the position of IBus' candidate list. If rect is NULL then this will just reposition it relative to the focused window's new position. */ -extern void SDL_IBus_UpdateTextRect(SDL_Rect *window_relative_rect); +extern void SDL_IBus_UpdateTextRect(const SDL_Rect *window_relative_rect); -/* Checks DBus for new IBus events, and calls SDL_SendKeyboardText / +/* Checks DBus for new IBus events, and calls SDL_SendKeyboardText / SDL_SendEditingText for each event it finds */ extern void SDL_IBus_PumpEvents(void); diff --git a/SDL2-2.0.12/src/core/linux/SDL_ime.c b/SDL2-2.30.5/src/core/linux/SDL_ime.c similarity index 76% rename from SDL2-2.0.12/src/core/linux/SDL_ime.c rename to SDL2-2.30.5/src/core/linux/SDL_ime.c index 8c9a474..6c28e5f 100644 --- a/SDL2-2.0.12/src/core/linux/SDL_ime.c +++ b/SDL2-2.30.5/src/core/linux/SDL_ime.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -18,18 +18,19 @@ 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_ime.h" #include "SDL_ibus.h" #include "SDL_fcitx.h" -typedef SDL_bool (*_SDL_IME_Init)(); -typedef void (*_SDL_IME_Quit)(); +typedef SDL_bool (*_SDL_IME_Init)(void); +typedef void (*_SDL_IME_Quit)(void); typedef void (*_SDL_IME_SetFocus)(SDL_bool); -typedef void (*_SDL_IME_Reset)(); -typedef SDL_bool (*_SDL_IME_ProcessKeyEvent)(Uint32, Uint32); -typedef void (*_SDL_IME_UpdateTextRect)(SDL_Rect *); -typedef void (*_SDL_IME_PumpEvents)(); +typedef void (*_SDL_IME_Reset)(void); +typedef SDL_bool (*_SDL_IME_ProcessKeyEvent)(Uint32, Uint32, Uint8 state); +typedef void (*_SDL_IME_UpdateTextRect)(const SDL_Rect *); +typedef void (*_SDL_IME_PumpEvents)(void); static _SDL_IME_Init SDL_IME_Init_Real = NULL; static _SDL_IME_Quit SDL_IME_Quit_Real = NULL; @@ -39,22 +40,22 @@ static _SDL_IME_ProcessKeyEvent SDL_IME_ProcessKeyEvent_Real = NULL; static _SDL_IME_UpdateTextRect SDL_IME_UpdateTextRect_Real = NULL; static _SDL_IME_PumpEvents SDL_IME_PumpEvents_Real = NULL; -static void -InitIME() +static void InitIME() { static SDL_bool inited = SDL_FALSE; -#ifdef HAVE_FCITX_FRONTEND_H +#ifdef HAVE_FCITX const char *im_module = SDL_getenv("SDL_IM_MODULE"); const char *xmodifiers = SDL_getenv("XMODIFIERS"); #endif - if (inited == SDL_TRUE) + if (inited == SDL_TRUE) { return; + } inited = SDL_TRUE; /* See if fcitx IME support is being requested */ -#ifdef HAVE_FCITX_FRONTEND_H +#ifdef HAVE_FCITX if (!SDL_IME_Init_Real && ((im_module && SDL_strcmp(im_module, "fcitx") == 0) || (!im_module && xmodifiers && SDL_strstr(xmodifiers, "@im=fcitx") != NULL))) { @@ -66,7 +67,7 @@ InitIME() SDL_IME_UpdateTextRect_Real = SDL_Fcitx_UpdateTextRect; SDL_IME_PumpEvents_Real = SDL_Fcitx_PumpEvents; } -#endif /* HAVE_FCITX_FRONTEND_H */ +#endif /* HAVE_FCITX */ /* default to IBus */ #ifdef HAVE_IBUS_IBUS_H @@ -82,8 +83,7 @@ InitIME() #endif /* HAVE_IBUS_IBUS_H */ } -SDL_bool -SDL_IME_Init(void) +SDL_bool SDL_IME_Init(void) { InitIME(); @@ -105,48 +105,48 @@ SDL_IME_Init(void) return SDL_FALSE; } -void -SDL_IME_Quit(void) +void SDL_IME_Quit(void) { - if (SDL_IME_Quit_Real) + if (SDL_IME_Quit_Real) { SDL_IME_Quit_Real(); + } } -void -SDL_IME_SetFocus(SDL_bool focused) +void SDL_IME_SetFocus(SDL_bool focused) { - if (SDL_IME_SetFocus_Real) + if (SDL_IME_SetFocus_Real) { SDL_IME_SetFocus_Real(focused); + } } -void -SDL_IME_Reset(void) +void SDL_IME_Reset(void) { - if (SDL_IME_Reset_Real) + if (SDL_IME_Reset_Real) { SDL_IME_Reset_Real(); + } } -SDL_bool -SDL_IME_ProcessKeyEvent(Uint32 keysym, Uint32 keycode) +SDL_bool SDL_IME_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state) { - if (SDL_IME_ProcessKeyEvent_Real) - return SDL_IME_ProcessKeyEvent_Real(keysym, keycode); + if (SDL_IME_ProcessKeyEvent_Real) { + return SDL_IME_ProcessKeyEvent_Real(keysym, keycode, state); + } return SDL_FALSE; } -void -SDL_IME_UpdateTextRect(SDL_Rect *rect) +void SDL_IME_UpdateTextRect(const SDL_Rect *rect) { - if (SDL_IME_UpdateTextRect_Real) + if (SDL_IME_UpdateTextRect_Real) { SDL_IME_UpdateTextRect_Real(rect); + } } -void -SDL_IME_PumpEvents() +void SDL_IME_PumpEvents() { - if (SDL_IME_PumpEvents_Real) + if (SDL_IME_PumpEvents_Real) { SDL_IME_PumpEvents_Real(); + } } /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/core/linux/SDL_ime.h b/SDL2-2.30.5/src/core/linux/SDL_ime.h similarity index 90% rename from SDL2-2.0.12/src/core/linux/SDL_ime.h rename to SDL2-2.30.5/src/core/linux/SDL_ime.h index bc03a1a..0c1e2d0 100644 --- a/SDL2-2.0.12/src/core/linux/SDL_ime.h +++ b/SDL2-2.30.5/src/core/linux/SDL_ime.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -31,8 +31,8 @@ extern SDL_bool SDL_IME_Init(void); extern void SDL_IME_Quit(void); extern void SDL_IME_SetFocus(SDL_bool focused); extern void SDL_IME_Reset(void); -extern SDL_bool SDL_IME_ProcessKeyEvent(Uint32 keysym, Uint32 keycode); -extern void SDL_IME_UpdateTextRect(SDL_Rect *rect); +extern SDL_bool SDL_IME_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state); +extern void SDL_IME_UpdateTextRect(const SDL_Rect *rect); extern void SDL_IME_PumpEvents(void); #endif /* SDL_ime_h_ */ diff --git a/SDL2-2.30.5/src/core/linux/SDL_sandbox.c b/SDL2-2.30.5/src/core/linux/SDL_sandbox.c new file mode 100644 index 0000000..e93e183 --- /dev/null +++ b/SDL2-2.30.5/src/core/linux/SDL_sandbox.c @@ -0,0 +1,47 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 2022 Collabora Ltd. + + 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_sandbox.h" + +#include + +SDL_Sandbox SDL_DetectSandbox(void) +{ + if (access("/.flatpak-info", F_OK) == 0) { + return SDL_SANDBOX_FLATPAK; + } + + /* For Snap, we check multiple variables because they might be set for + * unrelated reasons. This is the same thing WebKitGTK does. */ + if (SDL_getenv("SNAP") != NULL && SDL_getenv("SNAP_NAME") != NULL && SDL_getenv("SNAP_REVISION") != NULL) { + return SDL_SANDBOX_SNAP; + } + + if (access("/run/host/container-manager", F_OK) == 0) { + return SDL_SANDBOX_UNKNOWN_CONTAINER; + } + + return SDL_SANDBOX_NONE; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/core/linux/SDL_sandbox.h b/SDL2-2.30.5/src/core/linux/SDL_sandbox.h new file mode 100644 index 0000000..4e66918 --- /dev/null +++ b/SDL2-2.30.5/src/core/linux/SDL_sandbox.h @@ -0,0 +1,39 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 2022 Collabora Ltd. + + 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. +*/ + +#ifndef SDL_SANDBOX_H +#define SDL_SANDBOX_H + +typedef enum +{ + SDL_SANDBOX_NONE = 0, + SDL_SANDBOX_UNKNOWN_CONTAINER, + SDL_SANDBOX_FLATPAK, + SDL_SANDBOX_SNAP, +} SDL_Sandbox; + +/* Return the sandbox type currently in use, if any */ +SDL_Sandbox SDL_DetectSandbox(void); + +#endif /* SDL_SANDBOX_H */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/core/linux/SDL_threadprio.c b/SDL2-2.30.5/src/core/linux/SDL_threadprio.c new file mode 100644 index 0000000..80d448e --- /dev/null +++ b/SDL2-2.30.5/src/core/linux/SDL_threadprio.c @@ -0,0 +1,352 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef __LINUX__ + +#include "SDL_error.h" +#include "SDL_stdinc.h" +#include "SDL_thread.h" + +#ifndef SDL_THREADS_DISABLED +#include +#include +#include +#include +#include "SDL_system.h" + +/* RLIMIT_RTTIME requires kernel >= 2.6.25 and is in glibc >= 2.14 */ +#ifndef RLIMIT_RTTIME +#define RLIMIT_RTTIME 15 +#endif +/* SCHED_RESET_ON_FORK is in kernel >= 2.6.32. */ +#ifndef SCHED_RESET_ON_FORK +#define SCHED_RESET_ON_FORK 0x40000000 +#endif + +#include "SDL_dbus.h" + +#ifdef SDL_USE_LIBDBUS +#include + +/* d-bus queries to org.freedesktop.RealtimeKit1. */ +#define RTKIT_DBUS_NODE "org.freedesktop.RealtimeKit1" +#define RTKIT_DBUS_PATH "/org/freedesktop/RealtimeKit1" +#define RTKIT_DBUS_INTERFACE "org.freedesktop.RealtimeKit1" + +/* d-bus queries to the XDG portal interface to RealtimeKit1 */ +#define XDG_PORTAL_DBUS_NODE "org.freedesktop.portal.Desktop" +#define XDG_PORTAL_DBUS_PATH "/org/freedesktop/portal/desktop" +#define XDG_PORTAL_DBUS_INTERFACE "org.freedesktop.portal.Realtime" + +static SDL_bool rtkit_use_session_conn; +static const char *rtkit_dbus_node; +static const char *rtkit_dbus_path; +static const char *rtkit_dbus_interface; + +static pthread_once_t rtkit_initialize_once = PTHREAD_ONCE_INIT; +static Sint32 rtkit_min_nice_level = -20; +static Sint32 rtkit_max_realtime_priority = 99; +static Sint64 rtkit_max_rttime_usec = 200000; + +/* + * Checking that the RTTimeUSecMax property exists and is an int64 confirms that: + * - The desktop portal exists and supports the realtime interface. + * - The realtime interface is new enough to have the required bug fixes applied. + */ +static SDL_bool realtime_portal_supported(DBusConnection *conn) +{ + Sint64 res; + return SDL_DBus_QueryPropertyOnConnection(conn, XDG_PORTAL_DBUS_NODE, XDG_PORTAL_DBUS_PATH, XDG_PORTAL_DBUS_INTERFACE, + "RTTimeUSecMax", DBUS_TYPE_INT64, &res); +} + +static void set_rtkit_interface() +{ + SDL_DBusContext *dbus = SDL_DBus_GetContext(); + + /* xdg-desktop-portal works in all instances, so check for it first. */ + if (dbus && realtime_portal_supported(dbus->session_conn)) { + rtkit_use_session_conn = SDL_TRUE; + rtkit_dbus_node = XDG_PORTAL_DBUS_NODE; + rtkit_dbus_path = XDG_PORTAL_DBUS_PATH; + rtkit_dbus_interface = XDG_PORTAL_DBUS_INTERFACE; + } else { /* Fall back to the standard rtkit interface in all other cases. */ + rtkit_use_session_conn = SDL_FALSE; + rtkit_dbus_node = RTKIT_DBUS_NODE; + rtkit_dbus_path = RTKIT_DBUS_PATH; + rtkit_dbus_interface = RTKIT_DBUS_INTERFACE; + } +} + +static DBusConnection *get_rtkit_dbus_connection() +{ + SDL_DBusContext *dbus = SDL_DBus_GetContext(); + + if (dbus) { + return rtkit_use_session_conn ? dbus->session_conn : dbus->system_conn; + } + + return NULL; +} + +static void rtkit_initialize() +{ + DBusConnection *dbus_conn; + + set_rtkit_interface(); + dbus_conn = get_rtkit_dbus_connection(); + + /* Try getting minimum nice level: this is often greater than PRIO_MIN (-20). */ + if (!dbus_conn || !SDL_DBus_QueryPropertyOnConnection(dbus_conn, rtkit_dbus_node, rtkit_dbus_path, rtkit_dbus_interface, "MinNiceLevel", + DBUS_TYPE_INT32, &rtkit_min_nice_level)) { + rtkit_min_nice_level = -20; + } + + /* Try getting maximum realtime priority: this can be less than the POSIX default (99). */ + if (!dbus_conn || !SDL_DBus_QueryPropertyOnConnection(dbus_conn, rtkit_dbus_node, rtkit_dbus_path, rtkit_dbus_interface, "MaxRealtimePriority", + DBUS_TYPE_INT32, &rtkit_max_realtime_priority)) { + rtkit_max_realtime_priority = 99; + } + + /* Try getting maximum rttime allowed by rtkit: exceeding this value will result in SIGKILL */ + if (!dbus_conn || !SDL_DBus_QueryPropertyOnConnection(dbus_conn, rtkit_dbus_node, rtkit_dbus_path, rtkit_dbus_interface, "RTTimeUSecMax", + DBUS_TYPE_INT64, &rtkit_max_rttime_usec)) { + rtkit_max_rttime_usec = 200000; + } +} + +static SDL_bool rtkit_initialize_realtime_thread() +{ + // Following is an excerpt from rtkit README that outlines the requirements + // a thread must meet before making rtkit requests: + // + // * Only clients with RLIMIT_RTTIME set will get RT scheduling + // + // * RT scheduling will only be handed out to processes with + // SCHED_RESET_ON_FORK set to guarantee that the scheduling + // settings cannot 'leak' to child processes, thus making sure + // that 'RT fork bombs' cannot be used to bypass RLIMIT_RTTIME + // and take the system down. + // + // * Limits are enforced on all user controllable resources, only + // a maximum number of users, processes, threads can request RT + // scheduling at the same time. + // + // * Only a limited number of threads may be made RT in a + // specific time frame. + // + // * Client authorization is verified with PolicyKit + + int err; + struct rlimit rlimit; + int nLimit = RLIMIT_RTTIME; + pid_t nPid = 0; // self + int nSchedPolicy = sched_getscheduler(nPid) | SCHED_RESET_ON_FORK; + struct sched_param schedParam; + + SDL_zero(schedParam); + + // Requirement #1: Set RLIMIT_RTTIME + err = getrlimit(nLimit, &rlimit); + if (err) { + return SDL_FALSE; + } + + // Current rtkit allows a max of 200ms right now + rlimit.rlim_max = rtkit_max_rttime_usec; + rlimit.rlim_cur = rlimit.rlim_max / 2; + err = setrlimit(nLimit, &rlimit); + if (err) { + return SDL_FALSE; + } + + // Requirement #2: Add SCHED_RESET_ON_FORK to the scheduler policy + err = sched_getparam(nPid, &schedParam); + if (err) { + return SDL_FALSE; + } + + err = sched_setscheduler(nPid, nSchedPolicy, &schedParam); + if (err) { + return SDL_FALSE; + } + + return SDL_TRUE; +} + +static SDL_bool rtkit_setpriority_nice(pid_t thread, int nice_level) +{ + DBusConnection *dbus_conn; + Uint64 pid = (Uint64)getpid(); + Uint64 tid = (Uint64)thread; + Sint32 nice = (Sint32)nice_level; + + pthread_once(&rtkit_initialize_once, rtkit_initialize); + dbus_conn = get_rtkit_dbus_connection(); + + if (nice < rtkit_min_nice_level) { + nice = rtkit_min_nice_level; + } + + if (!dbus_conn || !SDL_DBus_CallMethodOnConnection(dbus_conn, + rtkit_dbus_node, rtkit_dbus_path, rtkit_dbus_interface, "MakeThreadHighPriorityWithPID", + DBUS_TYPE_UINT64, &pid, DBUS_TYPE_UINT64, &tid, DBUS_TYPE_INT32, &nice, DBUS_TYPE_INVALID, + DBUS_TYPE_INVALID)) { + return SDL_FALSE; + } + return SDL_TRUE; +} + +static SDL_bool rtkit_setpriority_realtime(pid_t thread, int rt_priority) +{ + DBusConnection *dbus_conn; + Uint64 pid = (Uint64)getpid(); + Uint64 tid = (Uint64)thread; + Uint32 priority = (Uint32)rt_priority; + + pthread_once(&rtkit_initialize_once, rtkit_initialize); + dbus_conn = get_rtkit_dbus_connection(); + + if (priority > rtkit_max_realtime_priority) { + priority = rtkit_max_realtime_priority; + } + + // We always perform the thread state changes necessary for rtkit. + // This wastes some system calls if the state is already set but + // typically code sets a thread priority and leaves it so it's + // not expected that this wasted effort will be an issue. + // We also do not quit if this fails, we let the rtkit request + // go through to determine whether it really needs to fail or not. + rtkit_initialize_realtime_thread(); + + if (!dbus_conn || !SDL_DBus_CallMethodOnConnection(dbus_conn, + rtkit_dbus_node, rtkit_dbus_path, rtkit_dbus_interface, "MakeThreadRealtimeWithPID", + DBUS_TYPE_UINT64, &pid, DBUS_TYPE_UINT64, &tid, DBUS_TYPE_UINT32, &priority, DBUS_TYPE_INVALID, + DBUS_TYPE_INVALID)) { + return SDL_FALSE; + } + return SDL_TRUE; +} +#else + +#define rtkit_max_realtime_priority 99 + +#endif /* dbus */ +#endif /* threads */ + +/* this is a public symbol, so it has to exist even if threads are disabled. */ +int SDL_LinuxSetThreadPriority(Sint64 threadID, int priority) +{ +#ifdef SDL_THREADS_DISABLED + return SDL_Unsupported(); +#else + if (setpriority(PRIO_PROCESS, (id_t)threadID, priority) == 0) { + return 0; + } + +#ifdef SDL_USE_LIBDBUS + /* Note that this fails you most likely: + * Have your process's scheduler incorrectly configured. + See the requirements at: + http://git.0pointer.net/rtkit.git/tree/README#n16 + * Encountered dbus/polkit security restrictions. Note + that the RealtimeKit1 dbus endpoint is inaccessible + over ssh connections for most common distro configs. + You might want to check your local config for details: + /usr/share/polkit-1/actions/org.freedesktop.RealtimeKit1.policy + + README and sample code at: http://git.0pointer.net/rtkit.git + */ + if (rtkit_setpriority_nice((pid_t)threadID, priority)) { + return 0; + } +#endif + + return SDL_SetError("setpriority() failed"); +#endif +} + +/* this is a public symbol, so it has to exist even if threads are disabled. */ +int SDL_LinuxSetThreadPriorityAndPolicy(Sint64 threadID, int sdlPriority, int schedPolicy) +{ +#ifdef SDL_THREADS_DISABLED + return SDL_Unsupported(); +#else + int osPriority; + + if (schedPolicy == SCHED_RR || schedPolicy == SCHED_FIFO) { + if (sdlPriority == SDL_THREAD_PRIORITY_LOW) { + osPriority = 1; + } else if (sdlPriority == SDL_THREAD_PRIORITY_HIGH) { + osPriority = rtkit_max_realtime_priority * 3 / 4; + } else if (sdlPriority == SDL_THREAD_PRIORITY_TIME_CRITICAL) { + osPriority = rtkit_max_realtime_priority; + } else { + osPriority = rtkit_max_realtime_priority / 2; + } + } else { + if (sdlPriority == SDL_THREAD_PRIORITY_LOW) { + osPriority = 19; + } else if (sdlPriority == SDL_THREAD_PRIORITY_HIGH) { + osPriority = -10; + } else if (sdlPriority == SDL_THREAD_PRIORITY_TIME_CRITICAL) { + osPriority = -20; + } else { + osPriority = 0; + } + + if (setpriority(PRIO_PROCESS, (id_t)threadID, osPriority) == 0) { + return 0; + } + } + +#ifdef SDL_USE_LIBDBUS + /* Note that this fails you most likely: + * Have your process's scheduler incorrectly configured. + See the requirements at: + http://git.0pointer.net/rtkit.git/tree/README#n16 + * Encountered dbus/polkit security restrictions. Note + that the RealtimeKit1 dbus endpoint is inaccessible + over ssh connections for most common distro configs. + You might want to check your local config for details: + /usr/share/polkit-1/actions/org.freedesktop.RealtimeKit1.policy + + README and sample code at: http://git.0pointer.net/rtkit.git + */ + if (schedPolicy == SCHED_RR || schedPolicy == SCHED_FIFO) { + if (rtkit_setpriority_realtime((pid_t)threadID, osPriority)) { + return 0; + } + } else { + if (rtkit_setpriority_nice((pid_t)threadID, osPriority)) { + return 0; + } + } +#endif + + return SDL_SetError("setpriority() failed"); +#endif +} + +#endif /* __LINUX__ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/core/linux/SDL_udev.c b/SDL2-2.30.5/src/core/linux/SDL_udev.c similarity index 68% rename from SDL2-2.0.12/src/core/linux/SDL_udev.c rename to SDL2-2.30.5/src/core/linux/SDL_udev.c index 9c9e950..5bdfc0d 100644 --- a/SDL2-2.0.12/src/core/linux/SDL_udev.c +++ b/SDL2-2.30.5/src/core/linux/SDL_udev.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -18,8 +18,9 @@ misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ +#include "../../SDL_internal.h" -/* +/* * To list the properties of a device, try something like: * udevadm info -a -n snd/hwC0D0 (for a sound card) * udevadm info --query=all -n input/event3 (for a keyboard, mouse, etc) @@ -30,8 +31,10 @@ #ifdef SDL_USE_LIBUDEV #include +#include #include "SDL_assert.h" +#include "SDL_evdev_capabilities.h" #include "SDL_loadso.h" #include "SDL_timer.h" #include "SDL_hints.h" @@ -45,13 +48,15 @@ static _THIS = NULL; static SDL_bool SDL_UDEV_load_sym(const char *fn, void **addr); static int SDL_UDEV_load_syms(void); static SDL_bool SDL_UDEV_hotplug_update_available(void); +static void get_caps(struct udev_device *dev, struct udev_device *pdev, const char *attr, unsigned long *bitmask, size_t bitmask_len); +static int guess_device_class(struct udev_device *dev); +static int device_class(struct udev_device *dev); static void device_event(SDL_UDEV_deviceevent type, struct udev_device *dev); -static SDL_bool -SDL_UDEV_load_sym(const char *fn, void **addr) +static SDL_bool SDL_UDEV_load_sym(const char *fn, void **addr) { *addr = SDL_LoadFunction(_this->udev_handle, fn); - if (*addr == NULL) { + if (!*addr) { /* Don't call SDL_SetError(): SDL_LoadFunction already did. */ return SDL_FALSE; } @@ -59,12 +64,12 @@ SDL_UDEV_load_sym(const char *fn, void **addr) return SDL_TRUE; } -static int -SDL_UDEV_load_syms(void) +static int SDL_UDEV_load_syms(void) { - /* cast funcs to char* first, to please GCC's strict aliasing rules. */ - #define SDL_UDEV_SYM(x) \ - if (!SDL_UDEV_load_sym(#x, (void **) (char *) & _this->syms.x)) return -1 +/* cast funcs to char* first, to please GCC's strict aliasing rules. */ +#define SDL_UDEV_SYM(x) \ + if (!SDL_UDEV_load_sym(#x, (void **)(char *)&_this->syms.x)) \ + return -1 SDL_UDEV_SYM(udev_device_get_action); SDL_UDEV_SYM(udev_device_get_devnode); @@ -92,133 +97,127 @@ SDL_UDEV_load_syms(void) SDL_UDEV_SYM(udev_unref); SDL_UDEV_SYM(udev_device_new_from_devnum); SDL_UDEV_SYM(udev_device_get_devnum); - #undef SDL_UDEV_SYM +#undef SDL_UDEV_SYM return 0; } -static SDL_bool -SDL_UDEV_hotplug_update_available(void) +static SDL_bool SDL_UDEV_hotplug_update_available(void) { - if (_this->udev_mon != NULL) { + if (_this->udev_mon) { const int fd = _this->syms.udev_monitor_get_fd(_this->udev_mon); - if (SDL_IOReady(fd, SDL_FALSE, 0)) { + if (SDL_IOReady(fd, SDL_IOR_READ, 0)) { return SDL_TRUE; } } return SDL_FALSE; } - -int -SDL_UDEV_Init(void) +int SDL_UDEV_Init(void) { int retval = 0; - - if (_this == NULL) { - _this = (SDL_UDEV_PrivateData *) SDL_calloc(1, sizeof(*_this)); - if(_this == NULL) { + + if (!_this) { + _this = (SDL_UDEV_PrivateData *)SDL_calloc(1, sizeof(*_this)); + if (!_this) { return SDL_OutOfMemory(); } - + retval = SDL_UDEV_LoadLibrary(); if (retval < 0) { SDL_UDEV_Quit(); return retval; } - - /* Set up udev monitoring + + /* Set up udev monitoring * Listen for input devices (mouse, keyboard, joystick, etc) and sound devices */ - + _this->udev = _this->syms.udev_new(); - if (_this->udev == NULL) { + if (!_this->udev) { SDL_UDEV_Quit(); return SDL_SetError("udev_new() failed"); } _this->udev_mon = _this->syms.udev_monitor_new_from_netlink(_this->udev, "udev"); - if (_this->udev_mon == NULL) { + if (!_this->udev_mon) { SDL_UDEV_Quit(); return SDL_SetError("udev_monitor_new_from_netlink() failed"); } - + _this->syms.udev_monitor_filter_add_match_subsystem_devtype(_this->udev_mon, "input", NULL); _this->syms.udev_monitor_filter_add_match_subsystem_devtype(_this->udev_mon, "sound", NULL); _this->syms.udev_monitor_enable_receiving(_this->udev_mon); - + /* Do an initial scan of existing devices */ SDL_UDEV_Scan(); - } - + _this->ref_count += 1; - + return retval; } -void -SDL_UDEV_Quit(void) +void SDL_UDEV_Quit(void) { SDL_UDEV_CallbackList *item; - - if (_this == NULL) { + + if (!_this) { return; } - + _this->ref_count -= 1; - + if (_this->ref_count < 1) { - - if (_this->udev_mon != NULL) { + + if (_this->udev_mon) { _this->syms.udev_monitor_unref(_this->udev_mon); _this->udev_mon = NULL; } - if (_this->udev != NULL) { + if (_this->udev) { _this->syms.udev_unref(_this->udev); _this->udev = NULL; } - + /* Remove existing devices */ - while (_this->first != NULL) { + while (_this->first) { item = _this->first; _this->first = _this->first->next; SDL_free(item); } - + SDL_UDEV_UnloadLibrary(); SDL_free(_this); _this = NULL; } } -void -SDL_UDEV_Scan(void) +void SDL_UDEV_Scan(void) { struct udev_enumerate *enumerate = NULL; struct udev_list_entry *devs = NULL; - struct udev_list_entry *item = NULL; - - if (_this == NULL) { + struct udev_list_entry *item = NULL; + + if (!_this) { return; } - + enumerate = _this->syms.udev_enumerate_new(_this->udev); - if (enumerate == NULL) { + if (!enumerate) { SDL_UDEV_Quit(); SDL_SetError("udev_enumerate_new() failed"); return; } - + _this->syms.udev_enumerate_add_match_subsystem(enumerate, "input"); _this->syms.udev_enumerate_add_match_subsystem(enumerate, "sound"); - + _this->syms.udev_enumerate_scan_devices(enumerate); devs = _this->syms.udev_enumerate_get_list_entry(enumerate); for (item = devs; item; item = _this->syms.udev_list_entry_get_next(item)) { const char *path = _this->syms.udev_list_entry_get_name(item); struct udev_device *dev = _this->syms.udev_device_new_from_syspath(_this->udev, path); - if (dev != NULL) { + if (dev) { device_event(SDL_UDEV_DEVICEADDED, dev); _this->syms.udev_device_unref(dev); } @@ -227,29 +226,83 @@ SDL_UDEV_Scan(void) _this->syms.udev_enumerate_unref(enumerate); } - -void -SDL_UDEV_UnloadLibrary(void) +SDL_bool SDL_UDEV_GetProductInfo(const char *device_path, Uint16 *vendor, Uint16 *product, Uint16 *version, int *class) { - if (_this == NULL) { + struct stat statbuf; + char type; + struct udev_device *dev; + const char* val; + int class_temp; + + if (!_this) { + return SDL_FALSE; + } + + if (stat(device_path, &statbuf) == -1) { + return SDL_FALSE; + } + + if (S_ISBLK(statbuf.st_mode)) { + type = 'b'; + } + else if (S_ISCHR(statbuf.st_mode)) { + type = 'c'; + } + else { + return SDL_FALSE; + } + + dev = _this->syms.udev_device_new_from_devnum(_this->udev, type, statbuf.st_rdev); + + if (!dev) { + return SDL_FALSE; + } + + val = _this->syms.udev_device_get_property_value(dev, "ID_VENDOR_ID"); + if (val) { + *vendor = (Uint16)SDL_strtol(val, NULL, 16); + } + + val = _this->syms.udev_device_get_property_value(dev, "ID_MODEL_ID"); + if (val) { + *product = (Uint16)SDL_strtol(val, NULL, 16); + } + + val = _this->syms.udev_device_get_property_value(dev, "ID_REVISION"); + if (val) { + *version = (Uint16)SDL_strtol(val, NULL, 16); + } + + class_temp = device_class(dev); + if (class_temp) { + *class = class_temp; + } + + _this->syms.udev_device_unref(dev); + + return SDL_TRUE; +} + +void SDL_UDEV_UnloadLibrary(void) +{ + if (!_this) { return; } - - if (_this->udev_handle != NULL) { + + if (_this->udev_handle) { SDL_UnloadObject(_this->udev_handle); _this->udev_handle = NULL; } } -int -SDL_UDEV_LoadLibrary(void) +int SDL_UDEV_LoadLibrary(void) { int retval = 0, i; - - if (_this == NULL) { + + if (!_this) { return SDL_SetError("UDEV not initialized"); } - + /* See if there is a udev library already loaded */ if (SDL_UDEV_load_syms() == 0) { return 0; @@ -257,9 +310,9 @@ SDL_UDEV_LoadLibrary(void) #ifdef SDL_UDEV_DYNAMIC /* Check for the build environment's libudev first */ - if (_this->udev_handle == NULL) { + if (!_this->udev_handle) { _this->udev_handle = SDL_LoadObject(SDL_UDEV_DYNAMIC); - if (_this->udev_handle != NULL) { + if (_this->udev_handle) { retval = SDL_UDEV_load_syms(); if (retval < 0) { SDL_UDEV_UnloadLibrary(); @@ -268,21 +321,20 @@ SDL_UDEV_LoadLibrary(void) } #endif - if (_this->udev_handle == NULL) { - for( i = 0 ; i < SDL_arraysize(SDL_UDEV_LIBS); i++) { + if (!_this->udev_handle) { + for (i = 0; i < SDL_arraysize(SDL_UDEV_LIBS); i++) { _this->udev_handle = SDL_LoadObject(SDL_UDEV_LIBS[i]); - if (_this->udev_handle != NULL) { + if (_this->udev_handle) { retval = SDL_UDEV_load_syms(); if (retval < 0) { SDL_UDEV_UnloadLibrary(); - } - else { + } else { break; } } } - - if (_this->udev_handle == NULL) { + + if (!_this->udev_handle) { retval = -1; /* Don't call SDL_SetError(): SDL_LoadObject already did. */ } @@ -291,12 +343,6 @@ SDL_UDEV_LoadLibrary(void) return retval; } -#define BITS_PER_LONG (sizeof(unsigned long) * 8) -#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1) -#define OFF(x) ((x)%BITS_PER_LONG) -#define LONG(x) ((x)/BITS_PER_LONG) -#define test_bit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1) - static void get_caps(struct udev_device *dev, struct udev_device *pdev, const char *attr, unsigned long *bitmask, size_t bitmask_len) { const char *value; @@ -305,7 +351,7 @@ static void get_caps(struct udev_device *dev, struct udev_device *pdev, const ch int i; unsigned long v; - SDL_memset(bitmask, 0, bitmask_len*sizeof(*bitmask)); + SDL_memset(bitmask, 0, bitmask_len * sizeof(*bitmask)); value = _this->syms.udev_device_get_sysattr_value(pdev, attr); if (!value) { return; @@ -314,7 +360,7 @@ static void get_caps(struct udev_device *dev, struct udev_device *pdev, const ch SDL_strlcpy(text, value, sizeof(text)); i = 0; while ((word = SDL_strrchr(text, ' ')) != NULL) { - v = SDL_strtoul(word+1, NULL, 16); + v = SDL_strtoul(word + 1, NULL, 16); if (i < bitmask_len) { bitmask[i] = v; } @@ -327,16 +373,13 @@ static void get_caps(struct udev_device *dev, struct udev_device *pdev, const ch } } -static int -guess_device_class(struct udev_device *dev) +static int guess_device_class(struct udev_device *dev) { - int devclass = 0; struct udev_device *pdev; unsigned long bitmask_ev[NBITS(EV_MAX)]; unsigned long bitmask_abs[NBITS(ABS_MAX)]; unsigned long bitmask_key[NBITS(KEY_MAX)]; unsigned long bitmask_rel[NBITS(REL_MAX)]; - unsigned long keyboard_mask; /* walk up the parental chain until we find the real input device; the * argument is very likely a subdevice of this, like eventN */ @@ -353,191 +396,164 @@ guess_device_class(struct udev_device *dev) get_caps(dev, pdev, "capabilities/rel", bitmask_rel, SDL_arraysize(bitmask_rel)); get_caps(dev, pdev, "capabilities/key", bitmask_key, SDL_arraysize(bitmask_key)); - if (test_bit(EV_ABS, bitmask_ev) && - test_bit(ABS_X, bitmask_abs) && test_bit(ABS_Y, bitmask_abs)) { - if (test_bit(BTN_STYLUS, bitmask_key) || test_bit(BTN_TOOL_PEN, bitmask_key)) { - ; /* ID_INPUT_TABLET */ - } else if (test_bit(BTN_TOOL_FINGER, bitmask_key) && !test_bit(BTN_TOOL_PEN, bitmask_key)) { - ; /* ID_INPUT_TOUCHPAD */ - } else if (test_bit(BTN_MOUSE, bitmask_key)) { - devclass |= SDL_UDEV_DEVICE_MOUSE; /* ID_INPUT_MOUSE */ - } else if (test_bit(BTN_TOUCH, bitmask_key)) { - /* TODO: better determining between touchscreen and multitouch touchpad, - see https://github.com/systemd/systemd/blob/master/src/udev/udev-builtin-input_id.c */ - devclass |= SDL_UDEV_DEVICE_TOUCHSCREEN; /* ID_INPUT_TOUCHSCREEN */ - } - - if (test_bit(BTN_TRIGGER, bitmask_key) || - test_bit(BTN_A, bitmask_key) || - test_bit(BTN_1, bitmask_key) || - test_bit(ABS_RX, bitmask_abs) || - test_bit(ABS_RY, bitmask_abs) || - test_bit(ABS_RZ, bitmask_abs) || - test_bit(ABS_THROTTLE, bitmask_abs) || - test_bit(ABS_RUDDER, bitmask_abs) || - test_bit(ABS_WHEEL, bitmask_abs) || - test_bit(ABS_GAS, bitmask_abs) || - test_bit(ABS_BRAKE, bitmask_abs)) { - devclass |= SDL_UDEV_DEVICE_JOYSTICK; /* ID_INPUT_JOYSTICK */ - } - } - - if (test_bit(EV_REL, bitmask_ev) && - test_bit(REL_X, bitmask_rel) && test_bit(REL_Y, bitmask_rel) && - test_bit(BTN_MOUSE, bitmask_key)) { - devclass |= SDL_UDEV_DEVICE_MOUSE; /* ID_INPUT_MOUSE */ - } - - /* the first 32 bits are ESC, numbers, and Q to D; if we have any of - * those, consider it a keyboard device; do not test KEY_RESERVED, though */ - keyboard_mask = 0xFFFFFFFE; - if ((bitmask_key[0] & keyboard_mask) != 0) - devclass |= SDL_UDEV_DEVICE_KEYBOARD; /* ID_INPUT_KEYBOARD */ - - return devclass; + return SDL_EVDEV_GuessDeviceClass(&bitmask_ev[0], + &bitmask_abs[0], + &bitmask_key[0], + &bitmask_rel[0]); } -static void -device_event(SDL_UDEV_deviceevent type, struct udev_device *dev) +static int device_class(struct udev_device *dev) { const char *subsystem; const char *val = NULL; int devclass = 0; - const char *path; - SDL_UDEV_CallbackList *item; - - path = _this->syms.udev_device_get_devnode(dev); - if (path == NULL) { - return; - } - + subsystem = _this->syms.udev_device_get_subsystem(dev); + if (!subsystem) { + return 0; + } + if (SDL_strcmp(subsystem, "sound") == 0) { devclass = SDL_UDEV_DEVICE_SOUND; } else if (SDL_strcmp(subsystem, "input") == 0) { /* udev rules reference: http://cgit.freedesktop.org/systemd/systemd/tree/src/udev/udev-builtin-input_id.c */ - + val = _this->syms.udev_device_get_property_value(dev, "ID_INPUT_JOYSTICK"); - if (val != NULL && SDL_strcmp(val, "1") == 0 ) { + if (val && SDL_strcmp(val, "1") == 0) { devclass |= SDL_UDEV_DEVICE_JOYSTICK; } val = _this->syms.udev_device_get_property_value(dev, "ID_INPUT_ACCELEROMETER"); if (SDL_GetHintBoolean(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, SDL_TRUE) && - val != NULL && SDL_strcmp(val, "1") == 0 ) { + val && SDL_strcmp(val, "1") == 0) { devclass |= SDL_UDEV_DEVICE_JOYSTICK; - } - + } + val = _this->syms.udev_device_get_property_value(dev, "ID_INPUT_MOUSE"); - if (val != NULL && SDL_strcmp(val, "1") == 0 ) { + if (val && SDL_strcmp(val, "1") == 0) { devclass |= SDL_UDEV_DEVICE_MOUSE; } - + val = _this->syms.udev_device_get_property_value(dev, "ID_INPUT_TOUCHSCREEN"); - if (val != NULL && SDL_strcmp(val, "1") == 0 ) { + if (val && SDL_strcmp(val, "1") == 0) { devclass |= SDL_UDEV_DEVICE_TOUCHSCREEN; } /* The undocumented rule is: - All devices with keys get ID_INPUT_KEY - From this subset, if they have ESC, numbers, and Q to D, it also gets ID_INPUT_KEYBOARD - + Ref: http://cgit.freedesktop.org/systemd/systemd/tree/src/udev/udev-builtin-input_id.c#n183 */ val = _this->syms.udev_device_get_property_value(dev, "ID_INPUT_KEY"); - if (val != NULL && SDL_strcmp(val, "1") == 0 ) { + if (val && SDL_strcmp(val, "1") == 0) { devclass |= SDL_UDEV_DEVICE_KEYBOARD; } if (devclass == 0) { /* Fall back to old style input classes */ val = _this->syms.udev_device_get_property_value(dev, "ID_CLASS"); - if (val != NULL) { + if (val) { if (SDL_strcmp(val, "joystick") == 0) { devclass = SDL_UDEV_DEVICE_JOYSTICK; } else if (SDL_strcmp(val, "mouse") == 0) { devclass = SDL_UDEV_DEVICE_MOUSE; } else if (SDL_strcmp(val, "kbd") == 0) { devclass = SDL_UDEV_DEVICE_KEYBOARD; - } else { - return; } } else { /* We could be linked with libudev on a system that doesn't have udev running */ devclass = guess_device_class(dev); } } - } else { + } + + return devclass; +} + +static void device_event(SDL_UDEV_deviceevent type, struct udev_device *dev) +{ + int devclass = 0; + const char *path; + SDL_UDEV_CallbackList *item; + + path = _this->syms.udev_device_get_devnode(dev); + if (!path) { return; } - + + devclass = device_class(dev); + if (!devclass) { + return; + } + /* Process callbacks */ - for (item = _this->first; item != NULL; item = item->next) { + for (item = _this->first; item; item = item->next) { item->callback(type, devclass, path); } } -void -SDL_UDEV_Poll(void) +void SDL_UDEV_Poll(void) { struct udev_device *dev = NULL; const char *action = NULL; - if (_this == NULL) { + if (!_this) { return; } while (SDL_UDEV_hotplug_update_available()) { dev = _this->syms.udev_monitor_receive_device(_this->udev_mon); - if (dev == NULL) { + if (!dev) { break; } action = _this->syms.udev_device_get_action(dev); - if (SDL_strcmp(action, "add") == 0) { - /* Wait for the device to finish initialization */ - SDL_Delay(100); - - device_event(SDL_UDEV_DEVICEADDED, dev); - } else if (SDL_strcmp(action, "remove") == 0) { - device_event(SDL_UDEV_DEVICEREMOVED, dev); + if (action) { + if (SDL_strcmp(action, "add") == 0) { + device_event(SDL_UDEV_DEVICEADDED, dev); + } else if (SDL_strcmp(action, "remove") == 0) { + device_event(SDL_UDEV_DEVICEREMOVED, dev); + } } - + _this->syms.udev_device_unref(dev); } } -int -SDL_UDEV_AddCallback(SDL_UDEV_Callback cb) +int SDL_UDEV_AddCallback(SDL_UDEV_Callback cb) { SDL_UDEV_CallbackList *item; - item = (SDL_UDEV_CallbackList *) SDL_calloc(1, sizeof (SDL_UDEV_CallbackList)); - if (item == NULL) { + item = (SDL_UDEV_CallbackList *)SDL_calloc(1, sizeof(SDL_UDEV_CallbackList)); + if (!item) { return SDL_OutOfMemory(); } - + item->callback = cb; - if (_this->last == NULL) { + if (!_this->last) { _this->first = _this->last = item; } else { _this->last->next = item; _this->last = item; } - + return 1; } -void -SDL_UDEV_DelCallback(SDL_UDEV_Callback cb) +void SDL_UDEV_DelCallback(SDL_UDEV_Callback cb) { SDL_UDEV_CallbackList *item; SDL_UDEV_CallbackList *prev = NULL; - for (item = _this->first; item != NULL; item = item->next) { + if (!_this) { + return; + } + + for (item = _this->first; item; item = item->next) { /* found it, remove it. */ if (item->callback == cb) { - if (prev != NULL) { + if (prev) { prev->next = item->next; } else { SDL_assert(_this->first == item); @@ -551,11 +567,9 @@ SDL_UDEV_DelCallback(SDL_UDEV_Callback cb) } prev = item; } - } -const SDL_UDEV_Symbols * -SDL_UDEV_GetUdevSyms(void) +const SDL_UDEV_Symbols *SDL_UDEV_GetUdevSyms(void) { if (SDL_UDEV_Init() < 0) { SDL_SetError("Could not initialize UDEV"); @@ -565,8 +579,7 @@ SDL_UDEV_GetUdevSyms(void) return &_this->syms; } -void -SDL_UDEV_ReleaseUdevSyms(void) +void SDL_UDEV_ReleaseUdevSyms(void) { SDL_UDEV_Quit(); } diff --git a/SDL2-2.0.12/src/core/linux/SDL_udev.h b/SDL2-2.30.5/src/core/linux/SDL_udev.h similarity index 85% rename from SDL2-2.0.12/src/core/linux/SDL_udev.h rename to SDL2-2.30.5/src/core/linux/SDL_udev.h index e610853..1489a85 100644 --- a/SDL2-2.0.12/src/core/linux/SDL_udev.h +++ b/SDL2-2.30.5/src/core/linux/SDL_udev.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -24,7 +24,7 @@ #ifndef SDL_udev_h_ #define SDL_udev_h_ -#if HAVE_LIBUDEV_H +#if defined(HAVE_LIBUDEV_H) && defined(HAVE_LINUX_INPUT_H) #ifndef SDL_USE_LIBUDEV #define SDL_USE_LIBUDEV 1 @@ -46,25 +46,16 @@ typedef enum SDL_UDEV_DEVICEREMOVED } SDL_UDEV_deviceevent; -/* A device can be any combination of these classes */ -typedef enum -{ - SDL_UDEV_DEVICE_UNKNOWN = 0x0000, - SDL_UDEV_DEVICE_MOUSE = 0x0001, - SDL_UDEV_DEVICE_KEYBOARD = 0x0002, - SDL_UDEV_DEVICE_JOYSTICK = 0x0004, - SDL_UDEV_DEVICE_SOUND = 0x0008, - SDL_UDEV_DEVICE_TOUCHSCREEN = 0x0010 -} SDL_UDEV_deviceclass; - typedef void (*SDL_UDEV_Callback)(SDL_UDEV_deviceevent udev_type, int udev_class, const char *devpath); -typedef struct SDL_UDEV_CallbackList { +typedef struct SDL_UDEV_CallbackList +{ SDL_UDEV_Callback callback; struct SDL_UDEV_CallbackList *next; } SDL_UDEV_CallbackList; -typedef struct SDL_UDEV_Symbols { +typedef struct SDL_UDEV_Symbols +{ const char *(*udev_device_get_action)(struct udev_device *); const char *(*udev_device_get_devnode)(struct udev_device *); const char *(*udev_device_get_subsystem)(struct udev_device *); @@ -89,8 +80,8 @@ typedef struct SDL_UDEV_Symbols { void (*udev_monitor_unref)(struct udev_monitor *); struct udev *(*udev_new)(void); void (*udev_unref)(struct udev *); - struct udev_device * (*udev_device_new_from_devnum)(struct udev *udev, char type, dev_t devnum); - dev_t (*udev_device_get_devnum) (struct udev_device *udev_device); + struct udev_device *(*udev_device_new_from_devnum)(struct udev *udev, char type, dev_t devnum); + dev_t (*udev_device_get_devnum)(struct udev_device *udev_device); } SDL_UDEV_Symbols; typedef struct SDL_UDEV_PrivateData @@ -101,7 +92,7 @@ typedef struct SDL_UDEV_PrivateData struct udev_monitor *udev_mon; int ref_count; SDL_UDEV_CallbackList *first, *last; - + /* Function pointers */ SDL_UDEV_Symbols syms; } SDL_UDEV_PrivateData; @@ -112,13 +103,13 @@ extern void SDL_UDEV_UnloadLibrary(void); extern int SDL_UDEV_LoadLibrary(void); extern void SDL_UDEV_Poll(void); extern void SDL_UDEV_Scan(void); +extern SDL_bool SDL_UDEV_GetProductInfo(const char *device_path, Uint16 *vendor, Uint16 *product, Uint16 *version, int *class); extern int SDL_UDEV_AddCallback(SDL_UDEV_Callback cb); extern void SDL_UDEV_DelCallback(SDL_UDEV_Callback cb); extern const SDL_UDEV_Symbols *SDL_UDEV_GetUdevSyms(void); extern void SDL_UDEV_ReleaseUdevSyms(void); - -#endif /* HAVE_LIBUDEV_H */ +#endif /* HAVE_LIBUDEV_H && HAVE_LINUX_INPUT_H */ #endif /* SDL_udev_h_ */ diff --git a/SDL2-2.30.5/src/core/openbsd/SDL_wscons.h b/SDL2-2.30.5/src/core/openbsd/SDL_wscons.h new file mode 100644 index 0000000..40e102d --- /dev/null +++ b/SDL2-2.30.5/src/core/openbsd/SDL_wscons.h @@ -0,0 +1,25 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +void SDL_WSCONS_Init(); +void SDL_WSCONS_Quit(); + +void SDL_WSCONS_PumpEvents(); diff --git a/SDL2-2.30.5/src/core/openbsd/SDL_wscons_kbd.c b/SDL2-2.30.5/src/core/openbsd/SDL_wscons_kbd.c new file mode 100644 index 0000000..975ba82 --- /dev/null +++ b/SDL2-2.30.5/src/core/openbsd/SDL_wscons_kbd.c @@ -0,0 +1,933 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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 +#include +#include "SDL_scancode.h" +#include "SDL_events.h" +#include "SDL_keyboard.h" +#include "SDL_wscons.h" +#include "SDL_log.h" +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../events/SDL_events_c.h" + +#ifdef __NetBSD__ +#define KS_GROUP_Ascii KS_GROUP_Plain +#define KS_Cmd_ScrollBack KS_Cmd_ScrollFastUp +#define KS_Cmd_ScrollFwd KS_Cmd_ScrollFastDown +#endif + +#define RETIFIOCTLERR(x) \ + if (x == -1) { \ + free(input); \ + input = NULL; \ + return NULL; \ + } + +typedef struct SDL_WSCONS_mouse_input_data SDL_WSCONS_mouse_input_data; +extern SDL_WSCONS_mouse_input_data *SDL_WSCONS_Init_Mouse(); +extern void updateMouse(SDL_WSCONS_mouse_input_data *input); +extern void SDL_WSCONS_Quit_Mouse(SDL_WSCONS_mouse_input_data *input); + +/* Conversion table courtesy of /usr/src/sys/dev/wscons/wskbdutil.c */ +static const unsigned char latin1_to_upper[256] = { + /* 0 8 1 9 2 a 3 b 4 c 5 d 6 e 7 f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 2 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 2 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 3 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 3 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 4 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 4 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 5 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 5 */ + 0x00, 'A', 'B', 'C', 'D', 'E', 'F', 'G', /* 6 */ + 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', /* 6 */ + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', /* 7 */ + 'X', 'Y', 'Z', 0x00, 0x00, 0x00, 0x00, 0x00, /* 7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 9 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 9 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* c */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* c */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* d */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* d */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* e */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* e */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0x00, /* f */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0x00, /* f */ +}; + +/* Compose table courtesy of /usr/src/sys/dev/wscons/wskbdutil.c */ +static struct SDL_wscons_compose_tab_s +{ + keysym_t elem[2]; + keysym_t result; +} compose_tab[] = { + { { KS_plus, KS_plus }, KS_numbersign }, + { { KS_a, KS_a }, KS_at }, + { { KS_parenleft, KS_parenleft }, KS_bracketleft }, + { { KS_slash, KS_slash }, KS_backslash }, + { { KS_parenright, KS_parenright }, KS_bracketright }, + { { KS_parenleft, KS_minus }, KS_braceleft }, + { { KS_slash, KS_minus }, KS_bar }, + { { KS_parenright, KS_minus }, KS_braceright }, + { { KS_exclam, KS_exclam }, KS_exclamdown }, + { { KS_c, KS_slash }, KS_cent }, + { { KS_l, KS_minus }, KS_sterling }, + { { KS_y, KS_minus }, KS_yen }, + { { KS_s, KS_o }, KS_section }, + { { KS_x, KS_o }, KS_currency }, + { { KS_c, KS_o }, KS_copyright }, + { { KS_less, KS_less }, KS_guillemotleft }, + { { KS_greater, KS_greater }, KS_guillemotright }, + { { KS_question, KS_question }, KS_questiondown }, + { { KS_dead_acute, KS_space }, KS_apostrophe }, + { { KS_dead_grave, KS_space }, KS_grave }, + { { KS_dead_tilde, KS_space }, KS_asciitilde }, + { { KS_dead_circumflex, KS_space }, KS_asciicircum }, + { { KS_dead_diaeresis, KS_space }, KS_quotedbl }, + { { KS_dead_cedilla, KS_space }, KS_comma }, + { { KS_dead_circumflex, KS_A }, KS_Acircumflex }, + { { KS_dead_diaeresis, KS_A }, KS_Adiaeresis }, + { { KS_dead_grave, KS_A }, KS_Agrave }, + { { KS_dead_abovering, KS_A }, KS_Aring }, + { { KS_dead_tilde, KS_A }, KS_Atilde }, + { { KS_dead_cedilla, KS_C }, KS_Ccedilla }, + { { KS_dead_acute, KS_E }, KS_Eacute }, + { { KS_dead_circumflex, KS_E }, KS_Ecircumflex }, + { { KS_dead_diaeresis, KS_E }, KS_Ediaeresis }, + { { KS_dead_grave, KS_E }, KS_Egrave }, + { { KS_dead_acute, KS_I }, KS_Iacute }, + { { KS_dead_circumflex, KS_I }, KS_Icircumflex }, + { { KS_dead_diaeresis, KS_I }, KS_Idiaeresis }, + { { KS_dead_grave, KS_I }, KS_Igrave }, + { { KS_dead_tilde, KS_N }, KS_Ntilde }, + { { KS_dead_acute, KS_O }, KS_Oacute }, + { { KS_dead_circumflex, KS_O }, KS_Ocircumflex }, + { { KS_dead_diaeresis, KS_O }, KS_Odiaeresis }, + { { KS_dead_grave, KS_O }, KS_Ograve }, + { { KS_dead_tilde, KS_O }, KS_Otilde }, + { { KS_dead_acute, KS_U }, KS_Uacute }, + { { KS_dead_circumflex, KS_U }, KS_Ucircumflex }, + { { KS_dead_diaeresis, KS_U }, KS_Udiaeresis }, + { { KS_dead_grave, KS_U }, KS_Ugrave }, + { { KS_dead_acute, KS_Y }, KS_Yacute }, + { { KS_dead_acute, KS_a }, KS_aacute }, + { { KS_dead_circumflex, KS_a }, KS_acircumflex }, + { { KS_dead_diaeresis, KS_a }, KS_adiaeresis }, + { { KS_dead_grave, KS_a }, KS_agrave }, + { { KS_dead_abovering, KS_a }, KS_aring }, + { { KS_dead_tilde, KS_a }, KS_atilde }, + { { KS_dead_cedilla, KS_c }, KS_ccedilla }, + { { KS_dead_acute, KS_e }, KS_eacute }, + { { KS_dead_circumflex, KS_e }, KS_ecircumflex }, + { { KS_dead_diaeresis, KS_e }, KS_ediaeresis }, + { { KS_dead_grave, KS_e }, KS_egrave }, + { { KS_dead_acute, KS_i }, KS_iacute }, + { { KS_dead_circumflex, KS_i }, KS_icircumflex }, + { { KS_dead_diaeresis, KS_i }, KS_idiaeresis }, + { { KS_dead_grave, KS_i }, KS_igrave }, + { { KS_dead_tilde, KS_n }, KS_ntilde }, + { { KS_dead_acute, KS_o }, KS_oacute }, + { { KS_dead_circumflex, KS_o }, KS_ocircumflex }, + { { KS_dead_diaeresis, KS_o }, KS_odiaeresis }, + { { KS_dead_grave, KS_o }, KS_ograve }, + { { KS_dead_tilde, KS_o }, KS_otilde }, + { { KS_dead_acute, KS_u }, KS_uacute }, + { { KS_dead_circumflex, KS_u }, KS_ucircumflex }, + { { KS_dead_diaeresis, KS_u }, KS_udiaeresis }, + { { KS_dead_grave, KS_u }, KS_ugrave }, + { { KS_dead_acute, KS_y }, KS_yacute }, + { { KS_dead_diaeresis, KS_y }, KS_ydiaeresis }, + { { KS_quotedbl, KS_A }, KS_Adiaeresis }, + { { KS_quotedbl, KS_E }, KS_Ediaeresis }, + { { KS_quotedbl, KS_I }, KS_Idiaeresis }, + { { KS_quotedbl, KS_O }, KS_Odiaeresis }, + { { KS_quotedbl, KS_U }, KS_Udiaeresis }, + { { KS_quotedbl, KS_a }, KS_adiaeresis }, + { { KS_quotedbl, KS_e }, KS_ediaeresis }, + { { KS_quotedbl, KS_i }, KS_idiaeresis }, + { { KS_quotedbl, KS_o }, KS_odiaeresis }, + { { KS_quotedbl, KS_u }, KS_udiaeresis }, + { { KS_quotedbl, KS_y }, KS_ydiaeresis }, + { { KS_acute, KS_A }, KS_Aacute }, + { { KS_asciicircum, KS_A }, KS_Acircumflex }, + { { KS_grave, KS_A }, KS_Agrave }, + { { KS_asterisk, KS_A }, KS_Aring }, + { { KS_asciitilde, KS_A }, KS_Atilde }, + { { KS_cedilla, KS_C }, KS_Ccedilla }, + { { KS_acute, KS_E }, KS_Eacute }, + { { KS_asciicircum, KS_E }, KS_Ecircumflex }, + { { KS_grave, KS_E }, KS_Egrave }, + { { KS_acute, KS_I }, KS_Iacute }, + { { KS_asciicircum, KS_I }, KS_Icircumflex }, + { { KS_grave, KS_I }, KS_Igrave }, + { { KS_asciitilde, KS_N }, KS_Ntilde }, + { { KS_acute, KS_O }, KS_Oacute }, + { { KS_asciicircum, KS_O }, KS_Ocircumflex }, + { { KS_grave, KS_O }, KS_Ograve }, + { { KS_asciitilde, KS_O }, KS_Otilde }, + { { KS_acute, KS_U }, KS_Uacute }, + { { KS_asciicircum, KS_U }, KS_Ucircumflex }, + { { KS_grave, KS_U }, KS_Ugrave }, + { { KS_acute, KS_Y }, KS_Yacute }, + { { KS_acute, KS_a }, KS_aacute }, + { { KS_asciicircum, KS_a }, KS_acircumflex }, + { { KS_grave, KS_a }, KS_agrave }, + { { KS_asterisk, KS_a }, KS_aring }, + { { KS_asciitilde, KS_a }, KS_atilde }, + { { KS_cedilla, KS_c }, KS_ccedilla }, + { { KS_acute, KS_e }, KS_eacute }, + { { KS_asciicircum, KS_e }, KS_ecircumflex }, + { { KS_grave, KS_e }, KS_egrave }, + { { KS_acute, KS_i }, KS_iacute }, + { { KS_asciicircum, KS_i }, KS_icircumflex }, + { { KS_grave, KS_i }, KS_igrave }, + { { KS_asciitilde, KS_n }, KS_ntilde }, + { { KS_acute, KS_o }, KS_oacute }, + { { KS_asciicircum, KS_o }, KS_ocircumflex }, + { { KS_grave, KS_o }, KS_ograve }, + { { KS_asciitilde, KS_o }, KS_otilde }, + { { KS_acute, KS_u }, KS_uacute }, + { { KS_asciicircum, KS_u }, KS_ucircumflex }, + { { KS_grave, KS_u }, KS_ugrave }, + { { KS_acute, KS_y }, KS_yacute }, +#ifndef __NetBSD__ + { { KS_dead_caron, KS_space }, KS_L2_caron }, + { { KS_dead_caron, KS_S }, KS_L2_Scaron }, + { { KS_dead_caron, KS_Z }, KS_L2_Zcaron }, + { { KS_dead_caron, KS_s }, KS_L2_scaron }, + { { KS_dead_caron, KS_z }, KS_L2_zcaron } +#endif +}; + +static keysym_t ksym_upcase(keysym_t ksym) +{ + if (ksym >= KS_f1 && ksym <= KS_f20) { + return KS_F1 - KS_f1 + ksym; + } + + if (KS_GROUP(ksym) == KS_GROUP_Ascii && ksym <= 0xff && latin1_to_upper[ksym] != 0x00) { + return latin1_to_upper[ksym]; + } + + return ksym; +} +static struct wscons_keycode_to_SDL +{ + keysym_t sourcekey; + SDL_Scancode targetKey; +} conversion_table[] = { + { KS_Menu, SDL_SCANCODE_APPLICATION }, + { KS_Up, SDL_SCANCODE_UP }, + { KS_Down, SDL_SCANCODE_DOWN }, + { KS_Left, SDL_SCANCODE_LEFT }, + { KS_Right, SDL_SCANCODE_RIGHT }, + { KS_Hold_Screen, SDL_SCANCODE_SCROLLLOCK }, + { KS_Num_Lock, SDL_SCANCODE_NUMLOCKCLEAR }, + { KS_Caps_Lock, SDL_SCANCODE_CAPSLOCK }, + { KS_BackSpace, SDL_SCANCODE_BACKSPACE }, + { KS_space, SDL_SCANCODE_SPACE }, + { KS_Delete, SDL_SCANCODE_BACKSPACE }, + { KS_Home, SDL_SCANCODE_HOME }, + { KS_End, SDL_SCANCODE_END }, + { KS_Pause, SDL_SCANCODE_PAUSE }, + { KS_Print_Screen, SDL_SCANCODE_PRINTSCREEN }, + { KS_Insert, SDL_SCANCODE_INSERT }, + { KS_Escape, SDL_SCANCODE_ESCAPE }, + { KS_Return, SDL_SCANCODE_RETURN }, + { KS_Linefeed, SDL_SCANCODE_RETURN }, + { KS_KP_Delete, SDL_SCANCODE_DELETE }, + { KS_KP_Insert, SDL_SCANCODE_INSERT }, + { KS_Control_L, SDL_SCANCODE_LCTRL }, + { KS_Control_R, SDL_SCANCODE_RCTRL }, + { KS_Shift_L, SDL_SCANCODE_LSHIFT }, + { KS_Shift_R, SDL_SCANCODE_RSHIFT }, + { KS_Alt_L, SDL_SCANCODE_LALT }, + { KS_Alt_R, SDL_SCANCODE_RALT }, + { KS_grave, SDL_SCANCODE_GRAVE }, + + { KS_KP_0, SDL_SCANCODE_KP_0 }, + { KS_KP_1, SDL_SCANCODE_KP_1 }, + { KS_KP_2, SDL_SCANCODE_KP_2 }, + { KS_KP_3, SDL_SCANCODE_KP_3 }, + { KS_KP_4, SDL_SCANCODE_KP_4 }, + { KS_KP_5, SDL_SCANCODE_KP_5 }, + { KS_KP_6, SDL_SCANCODE_KP_6 }, + { KS_KP_7, SDL_SCANCODE_KP_7 }, + { KS_KP_8, SDL_SCANCODE_KP_8 }, + { KS_KP_9, SDL_SCANCODE_KP_9 }, + { KS_KP_Enter, SDL_SCANCODE_KP_ENTER }, + { KS_KP_Multiply, SDL_SCANCODE_KP_MULTIPLY }, + { KS_KP_Add, SDL_SCANCODE_KP_PLUS }, + { KS_KP_Subtract, SDL_SCANCODE_KP_MINUS }, + { KS_KP_Divide, SDL_SCANCODE_KP_DIVIDE }, + { KS_KP_Up, SDL_SCANCODE_UP }, + { KS_KP_Down, SDL_SCANCODE_DOWN }, + { KS_KP_Left, SDL_SCANCODE_LEFT }, + { KS_KP_Right, SDL_SCANCODE_RIGHT }, + { KS_KP_Equal, SDL_SCANCODE_KP_EQUALS }, + { KS_f1, SDL_SCANCODE_F1 }, + { KS_f2, SDL_SCANCODE_F2 }, + { KS_f3, SDL_SCANCODE_F3 }, + { KS_f4, SDL_SCANCODE_F4 }, + { KS_f5, SDL_SCANCODE_F5 }, + { KS_f6, SDL_SCANCODE_F6 }, + { KS_f7, SDL_SCANCODE_F7 }, + { KS_f8, SDL_SCANCODE_F8 }, + { KS_f9, SDL_SCANCODE_F9 }, + { KS_f10, SDL_SCANCODE_F10 }, + { KS_f11, SDL_SCANCODE_F11 }, + { KS_f12, SDL_SCANCODE_F12 }, + { KS_f13, SDL_SCANCODE_F13 }, + { KS_f14, SDL_SCANCODE_F14 }, + { KS_f15, SDL_SCANCODE_F15 }, + { KS_f16, SDL_SCANCODE_F16 }, + { KS_f17, SDL_SCANCODE_F17 }, + { KS_f18, SDL_SCANCODE_F18 }, + { KS_f19, SDL_SCANCODE_F19 }, + { KS_f20, SDL_SCANCODE_F20 }, +#if !defined(__NetBSD__) + { KS_f21, SDL_SCANCODE_F21 }, + { KS_f22, SDL_SCANCODE_F22 }, + { KS_f23, SDL_SCANCODE_F23 }, + { KS_f24, SDL_SCANCODE_F24 }, +#endif + { KS_Meta_L, SDL_SCANCODE_LGUI }, + { KS_Meta_R, SDL_SCANCODE_RGUI }, + { KS_Zenkaku_Hankaku, SDL_SCANCODE_LANG5 }, + { KS_Hiragana_Katakana, SDL_SCANCODE_INTERNATIONAL2 }, + { KS_yen, SDL_SCANCODE_INTERNATIONAL3 }, + { KS_Henkan, SDL_SCANCODE_INTERNATIONAL4 }, + { KS_Muhenkan, SDL_SCANCODE_INTERNATIONAL5 }, + { KS_KP_Prior, SDL_SCANCODE_PRIOR }, + + { KS_a, SDL_SCANCODE_A }, + { KS_b, SDL_SCANCODE_B }, + { KS_c, SDL_SCANCODE_C }, + { KS_d, SDL_SCANCODE_D }, + { KS_e, SDL_SCANCODE_E }, + { KS_f, SDL_SCANCODE_F }, + { KS_g, SDL_SCANCODE_G }, + { KS_h, SDL_SCANCODE_H }, + { KS_i, SDL_SCANCODE_I }, + { KS_j, SDL_SCANCODE_J }, + { KS_k, SDL_SCANCODE_K }, + { KS_l, SDL_SCANCODE_L }, + { KS_m, SDL_SCANCODE_M }, + { KS_n, SDL_SCANCODE_N }, + { KS_o, SDL_SCANCODE_O }, + { KS_p, SDL_SCANCODE_P }, + { KS_q, SDL_SCANCODE_Q }, + { KS_r, SDL_SCANCODE_R }, + { KS_s, SDL_SCANCODE_S }, + { KS_t, SDL_SCANCODE_T }, + { KS_u, SDL_SCANCODE_U }, + { KS_v, SDL_SCANCODE_V }, + { KS_w, SDL_SCANCODE_W }, + { KS_x, SDL_SCANCODE_X }, + { KS_y, SDL_SCANCODE_Y }, + { KS_z, SDL_SCANCODE_Z }, + + { KS_0, SDL_SCANCODE_0 }, + { KS_1, SDL_SCANCODE_1 }, + { KS_2, SDL_SCANCODE_2 }, + { KS_3, SDL_SCANCODE_3 }, + { KS_4, SDL_SCANCODE_4 }, + { KS_5, SDL_SCANCODE_5 }, + { KS_6, SDL_SCANCODE_6 }, + { KS_7, SDL_SCANCODE_7 }, + { KS_8, SDL_SCANCODE_8 }, + { KS_9, SDL_SCANCODE_9 }, + { KS_minus, SDL_SCANCODE_MINUS }, + { KS_equal, SDL_SCANCODE_EQUALS }, + { KS_Tab, SDL_SCANCODE_TAB }, + { KS_KP_Tab, SDL_SCANCODE_KP_TAB }, + { KS_apostrophe, SDL_SCANCODE_APOSTROPHE }, + { KS_bracketleft, SDL_SCANCODE_LEFTBRACKET }, + { KS_bracketright, SDL_SCANCODE_RIGHTBRACKET }, + { KS_semicolon, SDL_SCANCODE_SEMICOLON }, + { KS_comma, SDL_SCANCODE_COMMA }, + { KS_period, SDL_SCANCODE_PERIOD }, + { KS_slash, SDL_SCANCODE_SLASH }, + { KS_backslash, SDL_SCANCODE_BACKSLASH } +}; + +typedef struct +{ + int fd; + struct wskbd_map_data keymap; + int ledstate; + int origledstate; + int shiftstate[4]; + int shiftheldstate[8]; + int lockheldstate[5]; + kbd_t encoding; + char text[128]; + unsigned int text_len; + keysym_t composebuffer[2]; + unsigned char composelen; + int type; +} SDL_WSCONS_input_data; + +static SDL_WSCONS_input_data *inputs[4] = { NULL, NULL, NULL, NULL }; +static SDL_WSCONS_mouse_input_data *mouseInputData = NULL; +#define IS_CONTROL_HELD (input->shiftstate[2] > 0) +#define IS_ALT_HELD (input->shiftstate[1] > 0) +#define IS_SHIFT_HELD ((input->shiftstate[0] > 0) || (input->ledstate & (1 << 5))) + +#define IS_ALTGR_MODE ((input->ledstate & (1 << 4)) || (input->shiftstate[3] > 0)) +#define IS_NUMLOCK_ON (input->ledstate & LED_NUM) +#define IS_SCROLLLOCK_ON (input->ledstate & LED_SCR) +#define IS_CAPSLOCK_ON (input->ledstate & LED_CAP) +static SDL_WSCONS_input_data *SDL_WSCONS_Init_Keyboard(const char *dev) +{ +#ifdef WSKBDIO_SETVERSION + int version = WSKBDIO_EVENT_VERSION; +#endif + SDL_WSCONS_input_data *input = (SDL_WSCONS_input_data *)SDL_calloc(1, sizeof(SDL_WSCONS_input_data)); + + if (!input) { + return input; + } + input->fd = open(dev, O_RDWR | O_NONBLOCK | O_CLOEXEC); + if (input->fd == -1) { + free(input); + input = NULL; + return NULL; + } + input->keymap.map = SDL_calloc(sizeof(struct wscons_keymap), KS_NUMKEYCODES); + if (!input->keymap.map) { + free(input); + return NULL; + } + input->keymap.maplen = KS_NUMKEYCODES; + RETIFIOCTLERR(ioctl(input->fd, WSKBDIO_GETMAP, &input->keymap)); + RETIFIOCTLERR(ioctl(input->fd, WSKBDIO_GETLEDS, &input->ledstate)); + input->origledstate = input->ledstate; + RETIFIOCTLERR(ioctl(input->fd, WSKBDIO_GETENCODING, &input->encoding)); + RETIFIOCTLERR(ioctl(input->fd, WSKBDIO_GTYPE, &input->type)); +#ifdef WSKBDIO_SETVERSION + RETIFIOCTLERR(ioctl(input->fd, WSKBDIO_SETVERSION, &version)); +#endif + return input; +} + +void SDL_WSCONS_Init() +{ + inputs[0] = SDL_WSCONS_Init_Keyboard("/dev/wskbd0"); + inputs[1] = SDL_WSCONS_Init_Keyboard("/dev/wskbd1"); + inputs[2] = SDL_WSCONS_Init_Keyboard("/dev/wskbd2"); + inputs[3] = SDL_WSCONS_Init_Keyboard("/dev/wskbd3"); + + mouseInputData = SDL_WSCONS_Init_Mouse(); + return; +} + +void SDL_WSCONS_Quit() +{ + int i = 0; + SDL_WSCONS_input_data *input = NULL; + + SDL_WSCONS_Quit_Mouse(mouseInputData); + mouseInputData = NULL; + for (i = 0; i < 4; i++) { + input = inputs[i]; + if (input) { + if (input->fd != -1 && input->fd != 0) { + ioctl(input->fd, WSKBDIO_SETLEDS, &input->origledstate); + close(input->fd); + input->fd = -1; + } + free(input); + input = NULL; + } + inputs[i] = NULL; + } +} + +static void put_queue(SDL_WSCONS_input_data *kbd, uint c) +{ + /* c is already part of a UTF-8 sequence and safe to add as a character */ + if (kbd->text_len < (sizeof(kbd->text) - 1)) { + kbd->text[kbd->text_len++] = (char)(c); + } +} + +static void put_utf8(SDL_WSCONS_input_data *input, uint c) +{ + if (c < 0x80) + /* 0******* */ + put_queue(input, c); + else if (c < 0x800) { + /* 110***** 10****** */ + put_queue(input, 0xc0 | (c >> 6)); + put_queue(input, 0x80 | (c & 0x3f)); + } else if (c < 0x10000) { + if (c >= 0xD800 && c <= 0xF500) { + return; + } + if (c == 0xFFFF) { + return; + } + /* 1110**** 10****** 10****** */ + put_queue(input, 0xe0 | (c >> 12)); + put_queue(input, 0x80 | ((c >> 6) & 0x3f)); + put_queue(input, 0x80 | (c & 0x3f)); + } else if (c < 0x110000) { + /* 11110*** 10****** 10****** 10****** */ + put_queue(input, 0xf0 | (c >> 18)); + put_queue(input, 0x80 | ((c >> 12) & 0x3f)); + put_queue(input, 0x80 | ((c >> 6) & 0x3f)); + put_queue(input, 0x80 | (c & 0x3f)); + } +} + +static void Translate_to_text(SDL_WSCONS_input_data *input, keysym_t ksym) +{ + if (KS_GROUP(ksym) == KS_GROUP_Keypad) { + if (SDL_isprint(ksym & 0xFF)) { + ksym &= 0xFF; + } + } + switch (ksym) { + case KS_Escape: + case KS_Delete: + case KS_BackSpace: + case KS_Return: + case KS_Linefeed: + /* All of these are unprintable characters. Ignore them */ + break; + default: + put_utf8(input, ksym); + break; + } + if (input->text_len > 0) { + input->text[input->text_len] = '\0'; + SDL_SendKeyboardText(input->text); + /*SDL_memset(input->text, 0, sizeof(input->text));*/ + input->text_len = 0; + input->text[0] = 0; + } +} + +static void Translate_to_keycode(SDL_WSCONS_input_data *input, int type, keysym_t ksym) +{ + struct wscons_keymap keyDesc = input->keymap.map[ksym]; + keysym_t *group = &keyDesc.group1[KS_GROUP(keyDesc.group1[0]) == KS_GROUP_Keypad && IS_NUMLOCK_ON ? !IS_SHIFT_HELD : 0]; + int i = 0; + + /* Check command first, then group[0]*/ + switch (keyDesc.command) { + case KS_Cmd_ScrollBack: + { + SDL_SendKeyboardKey(type == WSCONS_EVENT_KEY_DOWN ? SDL_PRESSED : SDL_RELEASED, SDL_SCANCODE_PAGEUP); + return; + } + case KS_Cmd_ScrollFwd: + { + SDL_SendKeyboardKey(type == WSCONS_EVENT_KEY_DOWN ? SDL_PRESSED : SDL_RELEASED, SDL_SCANCODE_PAGEDOWN); + return; + } + } + for (i = 0; i < sizeof(conversion_table) / sizeof(struct wscons_keycode_to_SDL); i++) { + if (conversion_table[i].sourcekey == group[0]) { + SDL_SendKeyboardKey(type == WSCONS_EVENT_KEY_DOWN ? SDL_PRESSED : SDL_RELEASED, conversion_table[i].targetKey); + return; + } + } + SDL_SendKeyboardKey(type == WSCONS_EVENT_KEY_DOWN ? SDL_PRESSED : SDL_RELEASED, SDL_SCANCODE_UNKNOWN); +} + +static void updateKeyboard(SDL_WSCONS_input_data *input) +{ + struct wscons_event events[64]; + int type; + int n, i, gindex, acc_i; + keysym_t *group; + keysym_t ksym, result; + + if (!input) { + return; + } + if ((n = read(input->fd, events, sizeof(events))) > 0) { + n /= sizeof(struct wscons_event); + for (i = 0; i < n; i++) { + type = events[i].type; + switch (type) { + case WSCONS_EVENT_KEY_DOWN: + { + switch (input->keymap.map[events[i].value].group1[0]) { + case KS_Hold_Screen: + { + if (input->lockheldstate[0] >= 1) { + break; + } + input->ledstate ^= LED_SCR; + ioctl(input->fd, WSKBDIO_SETLEDS, &input->ledstate); + input->lockheldstate[0] = 1; + break; + } + case KS_Num_Lock: + { + if (input->lockheldstate[1] >= 1) { + break; + } + input->ledstate ^= LED_NUM; + ioctl(input->fd, WSKBDIO_SETLEDS, &input->ledstate); + input->lockheldstate[1] = 1; + break; + } + case KS_Caps_Lock: + { + if (input->lockheldstate[2] >= 1) { + break; + } + input->ledstate ^= LED_CAP; + ioctl(input->fd, WSKBDIO_SETLEDS, &input->ledstate); + input->lockheldstate[2] = 1; + break; + } +#ifndef __NetBSD__ + case KS_Mode_Lock: + { + if (input->lockheldstate[3] >= 1) { + break; + } + input->ledstate ^= 1 << 4; + ioctl(input->fd, WSKBDIO_SETLEDS, &input->ledstate); + input->lockheldstate[3] = 1; + break; + } +#endif + case KS_Shift_Lock: + { + if (input->lockheldstate[4] >= 1) { + break; + } + input->ledstate ^= 1 << 5; + ioctl(input->fd, WSKBDIO_SETLEDS, &input->ledstate); + input->lockheldstate[4] = 1; + break; + } + case KS_Shift_L: + { + if (input->shiftheldstate[0]) { + break; + } + input->shiftstate[0]++; + input->shiftheldstate[0] = 1; + break; + } + case KS_Shift_R: + { + if (input->shiftheldstate[1]) { + break; + } + input->shiftstate[0]++; + input->shiftheldstate[1] = 1; + break; + } + case KS_Alt_L: + { + if (input->shiftheldstate[2]) { + break; + } + input->shiftstate[1]++; + input->shiftheldstate[2] = 1; + break; + } + case KS_Alt_R: + { + if (input->shiftheldstate[3]) { + break; + } + input->shiftstate[1]++; + input->shiftheldstate[3] = 1; + break; + } + case KS_Control_L: + { + if (input->shiftheldstate[4]) { + break; + } + input->shiftstate[2]++; + input->shiftheldstate[4] = 1; + break; + } + case KS_Control_R: + { + if (input->shiftheldstate[5]) { + break; + } + input->shiftstate[2]++; + input->shiftheldstate[5] = 1; + break; + } + case KS_Mode_switch: + { + if (input->shiftheldstate[6]) { + break; + } + input->shiftstate[3]++; + input->shiftheldstate[6] = 1; + break; + } + } + } break; + case WSCONS_EVENT_KEY_UP: + { + switch (input->keymap.map[events[i].value].group1[0]) { + case KS_Hold_Screen: + { + if (input->lockheldstate[0]) { + input->lockheldstate[0] = 0; + } + } break; + case KS_Num_Lock: + { + if (input->lockheldstate[1]) { + input->lockheldstate[1] = 0; + } + } break; + case KS_Caps_Lock: + { + if (input->lockheldstate[2]) { + input->lockheldstate[2] = 0; + } + } break; +#ifndef __NetBSD__ + case KS_Mode_Lock: + { + if (input->lockheldstate[3]) { + input->lockheldstate[3] = 0; + } + } break; +#endif + case KS_Shift_Lock: + { + if (input->lockheldstate[4]) { + input->lockheldstate[4] = 0; + } + } break; + case KS_Shift_L: + { + input->shiftheldstate[0] = 0; + if (input->shiftstate[0]) { + input->shiftstate[0]--; + } + break; + } + case KS_Shift_R: + { + input->shiftheldstate[1] = 0; + if (input->shiftstate[0]) { + input->shiftstate[0]--; + } + break; + } + case KS_Alt_L: + { + input->shiftheldstate[2] = 0; + if (input->shiftstate[1]) { + input->shiftstate[1]--; + } + break; + } + case KS_Alt_R: + { + input->shiftheldstate[3] = 0; + if (input->shiftstate[1]) { + input->shiftstate[1]--; + } + break; + } + case KS_Control_L: + { + input->shiftheldstate[4] = 0; + if (input->shiftstate[2]) { + input->shiftstate[2]--; + } + break; + } + case KS_Control_R: + { + input->shiftheldstate[5] = 0; + if (input->shiftstate[2]) { + input->shiftstate[2]--; + } + break; + } + case KS_Mode_switch: + { + input->shiftheldstate[6] = 0; + if (input->shiftstate[3]) { + input->shiftstate[3]--; + } + break; + } + } + } break; + case WSCONS_EVENT_ALL_KEYS_UP: + for (i = 0; i < SDL_NUM_SCANCODES; i++) { + SDL_SendKeyboardKey(SDL_RELEASED, i); + } + break; + } + + if (input->type == WSKBD_TYPE_USB && events[i].value <= 0xE7) + SDL_SendKeyboardKey(type == WSCONS_EVENT_KEY_DOWN ? SDL_PRESSED : SDL_RELEASED, (SDL_Scancode)events[i].value); + else + Translate_to_keycode(input, type, events[i].value); + + if (type == WSCONS_EVENT_KEY_UP) { + continue; + } + + if (IS_ALTGR_MODE && !IS_CONTROL_HELD) + group = &input->keymap.map[events[i].value].group2[0]; + else + group = &input->keymap.map[events[i].value].group1[0]; + + if (IS_NUMLOCK_ON && KS_GROUP(group[1]) == KS_GROUP_Keypad) { + gindex = !IS_SHIFT_HELD; + ksym = group[gindex]; + } else { + if (IS_CAPSLOCK_ON && !IS_SHIFT_HELD) { + gindex = 0; + ksym = ksym_upcase(group[0]); + } else { + gindex = IS_SHIFT_HELD; + ksym = group[gindex]; + } + } + result = KS_voidSymbol; + + switch (KS_GROUP(ksym)) { + case KS_GROUP_Ascii: + case KS_GROUP_Keypad: + case KS_GROUP_Function: + result = ksym; + break; + case KS_GROUP_Mod: + if (ksym == KS_Multi_key) { + input->ledstate |= WSKBD_LED_COMPOSE; + ioctl(input->fd, WSKBDIO_SETLEDS, &input->ledstate); + input->composelen = 2; + input->composebuffer[0] = input->composebuffer[1] = 0; + } + break; + case KS_GROUP_Dead: + if (input->composelen == 0) { + input->ledstate |= WSKBD_LED_COMPOSE; + ioctl(input->fd, WSKBDIO_SETLEDS, &input->ledstate); + input->composelen = 1; + input->composebuffer[0] = ksym; + input->composebuffer[1] = 0; + } else + result = ksym; + break; + } + if (result == KS_voidSymbol) { + continue; + } + + if (input->composelen > 0) { + if (input->composelen == 2 && group == &input->keymap.map[events[i].value].group2[0]) { + if (input->keymap.map[events[i].value].group2[gindex] == input->keymap.map[events[i].value].group1[gindex]) { + input->composelen = 0; + input->composebuffer[0] = input->composebuffer[1] = 0; + } + } + + if (input->composelen != 0) { + input->composebuffer[2 - input->composelen] = result; + if (--input->composelen == 0) { + result = KS_voidSymbol; + input->ledstate &= ~WSKBD_LED_COMPOSE; + ioctl(input->fd, WSKBDIO_SETLEDS, &input->ledstate); + for (acc_i = 0; acc_i < SDL_arraysize(compose_tab); acc_i++) { + if ((compose_tab[acc_i].elem[0] == input->composebuffer[0] && compose_tab[acc_i].elem[1] == input->composebuffer[1]) || (compose_tab[acc_i].elem[0] == input->composebuffer[1] && compose_tab[acc_i].elem[1] == input->composebuffer[0])) { + result = compose_tab[acc_i].result; + break; + } + } + } else + continue; + } + } + + if (KS_GROUP(result) == KS_GROUP_Ascii) { + if (IS_CONTROL_HELD) { + if ((result >= KS_at && result <= KS_z) || result == KS_space) { + result = result & 0x1f; + } else if (result == KS_2) { + result = 0x00; + } else if (result >= KS_3 && result <= KS_7) { + result = KS_Escape + (result - KS_3); + } else if (result == KS_8) { + result = KS_Delete; + } + } + if (IS_ALT_HELD) { + if (input->encoding & KB_METAESC) { + Translate_to_keycode(input, WSCONS_EVENT_KEY_DOWN, KS_Escape); + Translate_to_text(input, result); + continue; + } else { + result |= 0x80; + } + } + } + Translate_to_text(input, result); + continue; + } + } +} + +void SDL_WSCONS_PumpEvents() +{ + int i = 0; + for (i = 0; i < 4; i++) { + updateKeyboard(inputs[i]); + } + if (mouseInputData) { + updateMouse(mouseInputData); + } +} diff --git a/SDL2-2.30.5/src/core/openbsd/SDL_wscons_mouse.c b/SDL2-2.30.5/src/core/openbsd/SDL_wscons_mouse.c new file mode 100644 index 0000000..5a8664c --- /dev/null +++ b/SDL2-2.30.5/src/core/openbsd/SDL_wscons_mouse.c @@ -0,0 +1,134 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_events.h" +#include +#include +#include +#include +#include +#include + +#include "../../events/SDL_mouse_c.h" + +typedef struct SDL_WSCONS_mouse_input_data +{ + int fd; +} SDL_WSCONS_mouse_input_data; + +SDL_WSCONS_mouse_input_data *SDL_WSCONS_Init_Mouse() +{ +#ifdef WSMOUSEIO_SETVERSION + int version = WSMOUSE_EVENT_VERSION; +#endif + SDL_WSCONS_mouse_input_data *mouseInputData = SDL_calloc(1, sizeof(SDL_WSCONS_mouse_input_data)); + + if (!mouseInputData) { + return NULL; + } + mouseInputData->fd = open("/dev/wsmouse", O_RDWR | O_NONBLOCK | O_CLOEXEC); + if (mouseInputData->fd == -1) { + free(mouseInputData); + return NULL; + } +#ifdef WSMOUSEIO_SETMODE + ioctl(mouseInputData->fd, WSMOUSEIO_SETMODE, WSMOUSE_COMPAT); +#endif +#ifdef WSMOUSEIO_SETVERSION + ioctl(mouseInputData->fd, WSMOUSEIO_SETVERSION, &version); +#endif + return mouseInputData; +} + +void updateMouse(SDL_WSCONS_mouse_input_data *inputData) +{ + struct wscons_event events[64]; + int type; + int n, i; + SDL_Mouse *mouse = SDL_GetMouse(); + + if ((n = read(inputData->fd, events, sizeof(events))) > 0) { + n /= sizeof(struct wscons_event); + for (i = 0; i < n; i++) { + type = events[i].type; + switch (type) { + case WSCONS_EVENT_MOUSE_DOWN: + { + switch (events[i].value) { + case 0: /* Left Mouse Button. */ + SDL_SendMouseButton(mouse->focus, mouse->mouseID, SDL_PRESSED, SDL_BUTTON_LEFT); + break; + case 1: /* Middle Mouse Button. */ + SDL_SendMouseButton(mouse->focus, mouse->mouseID, SDL_PRESSED, SDL_BUTTON_MIDDLE); + break; + case 2: /* Right Mouse Button. */ + SDL_SendMouseButton(mouse->focus, mouse->mouseID, SDL_PRESSED, SDL_BUTTON_RIGHT); + break; + } + } break; + case WSCONS_EVENT_MOUSE_UP: + { + switch (events[i].value) { + case 0: /* Left Mouse Button. */ + SDL_SendMouseButton(mouse->focus, mouse->mouseID, SDL_RELEASED, SDL_BUTTON_LEFT); + break; + case 1: /* Middle Mouse Button. */ + SDL_SendMouseButton(mouse->focus, mouse->mouseID, SDL_RELEASED, SDL_BUTTON_MIDDLE); + break; + case 2: /* Right Mouse Button. */ + SDL_SendMouseButton(mouse->focus, mouse->mouseID, SDL_RELEASED, SDL_BUTTON_RIGHT); + break; + } + } break; + case WSCONS_EVENT_MOUSE_DELTA_X: + { + SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 1, events[i].value, 0); + break; + } + case WSCONS_EVENT_MOUSE_DELTA_Y: + { + SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 1, 0, -events[i].value); + break; + } + case WSCONS_EVENT_MOUSE_DELTA_W: + { + SDL_SendMouseWheel(mouse->focus, mouse->mouseID, events[i].value, 0, SDL_MOUSEWHEEL_NORMAL); + break; + } + case WSCONS_EVENT_MOUSE_DELTA_Z: + { + SDL_SendMouseWheel(mouse->focus, mouse->mouseID, 0, -events[i].value, SDL_MOUSEWHEEL_NORMAL); + break; + } + } + } + } +} + +void SDL_WSCONS_Quit_Mouse(SDL_WSCONS_mouse_input_data *inputData) +{ + if (!inputData) { + return; + } + close(inputData->fd); + free(inputData); +} diff --git a/SDL2-2.30.5/src/core/os2/SDL_os2.c b/SDL2-2.30.5/src/core/os2/SDL_os2.c new file mode 100644 index 0000000..76ad59d --- /dev/null +++ b/SDL2-2.30.5/src/core/os2/SDL_os2.c @@ -0,0 +1,38 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#if defined(__OS2__) + +#include "SDL_os2.h" + +/* SDL_OS2Quit() will be called from SDL_QuitSubSystem() */ +void SDL_OS2Quit(void) +{ + /* Unload DLL used for iconv. We can do it at any time and use iconv again - + * dynamic library will be loaded on first call iconv_open() (see geniconv). */ + libiconv_clean(); +} + +#endif + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/core/os2/SDL_os2.h b/SDL2-2.30.5/src/core/os2/SDL_os2.h new file mode 100644 index 0000000..9f88c70 --- /dev/null +++ b/SDL2-2.30.5/src/core/os2/SDL_os2.h @@ -0,0 +1,57 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ +#ifndef SDL_os2_h_ +#define SDL_os2_h_ + +#include "SDL_log.h" +#include "SDL_stdinc.h" + +#ifdef OS2DEBUG +#if (OS2DEBUG-0 >= 2) +# define debug_os2(s,...) SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, \ + __func__ "(): " ##s, ##__VA_ARGS__) +#else +# define debug_os2(s,...) printf(__func__ "(): " ##s "\n", ##__VA_ARGS__) +#endif + +#else /* no debug */ + +# define debug_os2(s,...) do {} while (0) + +#endif /* OS2DEBUG */ + +#if defined(HAVE_ICONV) && defined(HAVE_ICONV_H) +#define OS2_SysToUTF8(S) SDL_iconv_string("UTF-8", "", (char *)(S), SDL_strlen(S)+1) +#define OS2_UTF8ToSys(S) SDL_iconv_string("", "UTF-8", (char *)(S), SDL_strlen(S)+1) +#define libiconv_clean() do {} while(0) +#else +/* StrUTF8New() - geniconv/sys2utf8.c */ +#include "geniconv/geniconv.h" +#define OS2_SysToUTF8(S) StrUTF8New(1, (S), SDL_strlen((S)) + 1) +#define OS2_UTF8ToSys(S) StrUTF8New(0, (char *)(S), SDL_strlen((S)) + 1) +#endif + +/* SDL_OS2Quit() will be called from SDL_QuitSubSystem() */ +void SDL_OS2Quit(void); + +#endif /* SDL_os2_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/core/os2/geniconv/geniconv.c b/SDL2-2.30.5/src/core/os2/geniconv/geniconv.c new file mode 100644 index 0000000..df9c7c7 --- /dev/null +++ b/SDL2-2.30.5/src/core/os2/geniconv/geniconv.c @@ -0,0 +1,161 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +/* + Universal iconv implementation for OS/2. + + Andrey Vasilkin, 2016. +*/ + +#define INCL_DOSMODULEMGR /* Module Manager */ +#define INCL_DOSERRORS /* Error values */ +#include + +#include "geniconv.h" + +/*#define DEBUG*/ +#ifdef DEBUG +# include +# define iconv_debug(s,...) printf(__func__"(): "##s"\n" ,##__VA_ARGS__) +#else +# define iconv_debug(s,...) do {} while (0) +#endif + +/* Exports from os2iconv.c */ +extern iconv_t _System os2_iconv_open (const char* tocode, const char* fromcode); +extern size_t _System os2_iconv (iconv_t cd, + char **inbuf, size_t *inbytesleft, + char **outbuf, size_t *outbytesleft); +extern int _System os2_iconv_close (iconv_t cd); + +/* Functions pointers */ +typedef iconv_t (_System *FNICONV_OPEN)(const char*, const char*); +typedef size_t (_System *FNICONV) (iconv_t, char **, size_t *, char **, size_t *); +typedef int (_System *FNICONV_CLOSE)(iconv_t); + +static HMODULE hmIconv = NULLHANDLE; +static FNICONV_OPEN fn_iconv_open = os2_iconv_open; +static FNICONV fn_iconv = os2_iconv; +static FNICONV_CLOSE fn_iconv_close = os2_iconv_close; + +static int geniconv_init = 0; + + +static BOOL _loadDLL(const char *dllname, + const char *sym_iconvopen, + const char *sym_iconv, + const char *sym_iconvclose) +{ + ULONG rc; + char error[256]; + + rc = DosLoadModule(error, sizeof(error), dllname, &hmIconv); + if (rc != NO_ERROR) { + iconv_debug("DLL %s not loaded: %s", dllname, error); + return FALSE; + } + + rc = DosQueryProcAddr(hmIconv, 0, sym_iconvopen, (PFN *)&fn_iconv_open); + if (rc != NO_ERROR) { + iconv_debug("Error: cannot find entry %s in %s", sym_iconvopen, dllname); + goto fail; + } + + rc = DosQueryProcAddr(hmIconv, 0, sym_iconv, (PFN *)&fn_iconv); + if (rc != NO_ERROR) { + iconv_debug("Error: cannot find entry %s in %s", sym_iconv, dllname); + goto fail; + } + + rc = DosQueryProcAddr(hmIconv, 0, sym_iconvclose, (PFN *)&fn_iconv_close); + if (rc != NO_ERROR) { + iconv_debug("Error: cannot find entry %s in %s", sym_iconvclose, dllname); + goto fail; + } + + iconv_debug("DLL %s used", dllname); + return TRUE; + + fail: + DosFreeModule(hmIconv); + hmIconv = NULLHANDLE; + return FALSE; +} + +static void _init(void) +{ + if (geniconv_init) { + return; /* Already initialized */ + } + + geniconv_init = 1; + + /* Try to load kiconv.dll, iconv2.dll or iconv.dll */ + if (!_loadDLL("KICONV", "_libiconv_open", "_libiconv", "_libiconv_close") && + !_loadDLL("ICONV2", "_libiconv_open", "_libiconv", "_libiconv_close") && + !_loadDLL("ICONV", "_iconv_open", "_iconv", "_iconv_close") ) { + /* No DLL was loaded - use OS/2 conversion objects API */ + iconv_debug("Uni*() API used"); + fn_iconv_open = os2_iconv_open; + fn_iconv = os2_iconv; + fn_iconv_close = os2_iconv_close; + } +} + + +/* Public routines. + * ---------------- + */ + +/* function to unload the used iconv dynamic library */ +void libiconv_clean(void) +{ + geniconv_init = 0; + + /* reset the function pointers. */ + fn_iconv_open = os2_iconv_open; + fn_iconv = os2_iconv; + fn_iconv_close = os2_iconv_close; + + if (hmIconv != NULLHANDLE) { + DosFreeModule(hmIconv); + hmIconv = NULLHANDLE; + } +} + +iconv_t libiconv_open(const char* tocode, const char* fromcode) +{ + _init(); + return fn_iconv_open(tocode, fromcode); +} + +size_t libiconv(iconv_t cd, char* * inbuf, size_t *inbytesleft, + char* * outbuf, size_t *outbytesleft) +{ + return fn_iconv(cd, inbuf, inbytesleft, outbuf, outbytesleft); +} + +int libiconv_close(iconv_t cd) +{ + return fn_iconv_close(cd); +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/core/os2/geniconv/geniconv.h b/SDL2-2.30.5/src/core/os2/geniconv/geniconv.h new file mode 100644 index 0000000..463255b --- /dev/null +++ b/SDL2-2.30.5/src/core/os2/geniconv/geniconv.h @@ -0,0 +1,85 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +/* + Universal iconv implementation for OS/2. + + Andrey Vasilkin, 2016. +*/ + +#ifndef GENICONV_H +#define GENICONV_H + +#include "iconv.h" + +#ifdef iconv_open +#undef iconv_open +#endif +#define iconv_open libiconv_open + +#ifdef iconv +#undef iconv +#endif +#define iconv libiconv + +#ifdef iconv_close +#undef iconv_close +#endif +#define iconv_close libiconv_close + +#define iconv_clean libiconv_clean + +/* Non-standard function for iconv to unload the used dynamic library */ +void libiconv_clean(void); + +iconv_t libiconv_open (const char *tocode, const char *fromcode); +int libiconv_close(iconv_t cd); +size_t libiconv (iconv_t cd, char **inbuf, size_t *inbytesleft, + char **outbuf, size_t *outbytesleft); + +/* System codepage <-> UTF-8 + * + * StrUTF8() + * Converts string from system cp to UTF-8 (to_utf8 is not 0) or from UTF-8 to + * the system cp (to_utf8 is 0). Converted ASCIIZ string will be placed at the + * buffer dst, up to c_dst - 1 (for sys->utf8) or 2 (for utf8->sys) bytes. + * Returns the number of bytes written into dst, not counting the terminating + * 0 byte(s) or -1 on error. + */ +int StrUTF8(int to_utf8, char *dst, int c_dst, char *src, int c_src); + +/* StrUTF8New() + * Converts string from system cp to UTF-8 (to_utf8 is not 0) or from UTF-8 + * to the system cp (to_utf8 is 0). Memory for the new string is obtained by + * using libc malloc(). + * Returns converted string, terminating two bytes 0 is appended to the result. + * Returns null on error. + */ +char *StrUTF8New(int to_utf8, char *str, int c_str); + +/* StrUTF8Free() + * Deallocates the memory block allocated by StrUTF8New() (just libc free()). + */ +void StrUTF8Free(char *str); + +#endif /* GENICONV_H */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/core/os2/geniconv/iconv.h b/SDL2-2.30.5/src/core/os2/geniconv/iconv.h new file mode 100644 index 0000000..b336dab --- /dev/null +++ b/SDL2-2.30.5/src/core/os2/geniconv/iconv.h @@ -0,0 +1,21 @@ +#ifndef ICONV_H_ /* minimal iconv.h header based on public knowledge */ +#define ICONV_H_ + +#include /* size_t */ +#include + +typedef void *iconv_t; + +#ifdef __cplusplus +extern "C" { +#endif + +extern iconv_t iconv_open(const char *, const char *); +extern size_t iconv(iconv_t, char **, size_t *, char **, size_t *); +extern int iconv_close(iconv_t); + +#ifdef __cplusplus +} +#endif + +#endif /* ICONV_H_ */ diff --git a/SDL2-2.30.5/src/core/os2/geniconv/os2cp.c b/SDL2-2.30.5/src/core/os2/geniconv/os2cp.c new file mode 100644 index 0000000..36d808e --- /dev/null +++ b/SDL2-2.30.5/src/core/os2/geniconv/os2cp.c @@ -0,0 +1,416 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#define INCL_DOSNLS +#define INCL_DOSERRORS +#include + +#include "os2cp.h" + +#ifndef GENICONV_STANDALONE +#include "../../../SDL_internal.h" +#else +#include +#include +#define SDL_isspace isspace +#define SDL_strchr strchr +#define SDL_memcpy memcpy +#define SDL_strupr strupr +#define SDL_strcmp strcmp +#endif + +typedef struct _CP2NAME { + ULONG ulCode; + PSZ pszName; +} CP2NAME; + +typedef struct _NAME2CP { + PSZ pszName; + ULONG ulCode; +} NAME2CP; + +static CP2NAME aCP2Name[] = { + {367, "ANSI_X3.4-1968"}, + {813, "ECMA-118"}, + {819, "CP819"}, + {850, "850"}, + {862, "862"}, + {866, "866"}, + {874, "ISO-IR-166"}, + {878, "KOI8-R"}, + {896, "JISX0201-1976"}, + {901, "ISO-8859-13"}, + {912, "ISO-8859-2"}, + {913, "ISO-8859-3"}, + {914, "ISO-8859-4"}, + {915, "CYRILLIC"}, + {920, "ISO-8859-9"}, + {923, "ISO-8859-15"}, + {943, "MS_KANJI"}, + {954, "EUC-JP"}, + {964, "EUC-TW"}, + {970, "EUC-KR"}, + {1051, "HP-ROMAN8"}, + {1089, "ARABIC"}, + {1129, "VISCII"}, + {1168, "KOI8-U"}, + {1200, "ISO-10646-UCS-2"}, + {1202, "UTF-16LE"}, + {1204, "UCS-2BE"}, + {1208, "UTF-8"}, + {1232, "UTF-32BE"}, + {1234, "UTF-32LE"}, + {1236, "ISO-10646-UCS-4"}, + {1250, "CP1250"}, + {1251, "CP1251"}, + {1252, "CP1252"}, + {1253, "CP1253"}, + {1254, "CP1254"}, + {1255, "CP1255"}, + {1256, "CP1256"}, + {1257, "CP1257"}, + {1275, "MAC"}, + {1383, "CN-GB"}, + {1386, "GBK"}, + {1392, "GB18030"}, + {62210, "HEBREW"} +}; + +static NAME2CP aName2CP[] = { + {"850", 850}, + {"862", 862}, + {"866", 866}, + {"ANSI_X3.4-1968", 367}, + {"ANSI_X3.4-1986", 367}, + {"ARABIC", 1089}, + {"ASCII", 367}, + {"ASMO-708", 1089}, + {"CN-GB", 1383}, + {"CP1250", 1250}, + {"CP1251", 1251}, + {"CP1252", 1252}, + {"CP1253", 1253}, + {"CP1254", 1254}, + {"CP1255", 1255}, + {"CP1256", 1256}, + {"CP1257", 1257}, + {"CP367", 367}, + {"CP819", 819}, + {"CP850", 850}, + {"CP862", 862}, + {"CP866", 866}, + {"CP936", 1386}, + {"CSASCII", 367}, + {"CSEUCKR", 970}, + {"CSEUCPKDFMTJAPANESE", 954}, + {"CSEUCTW", 964}, + {"CSGB2312", 1383}, + {"CSHALFWIDTHKATAKANA", 896}, + {"CSHPROMAN8", 1051}, + {"CSIBM866", 866}, + {"CSISOLATIN1", 819}, + {"CSISOLATIN2", 912}, + {"CSISOLATIN3", 913}, + {"CSISOLATIN4", 914}, + {"CSISOLATIN5", 920}, + {"CSISOLATINARABIC", 1089}, + {"CSISOLATINCYRILLIC", 915}, + {"CSISOLATINGREEK", 813}, + {"CSISOLATINHEBREW", 62210}, + {"CSKOI8R", 878}, + {"CSKSC56011987", 970}, + {"CSMACINTOSH", 1275}, + {"CSPC850MULTILINGUAL", 850}, + {"CSPC862LATINHEBREW", 862}, + {"CSSHIFTJIS", 943}, + {"CSUCS4", 1236}, + {"CSUNICODE", 1200}, + {"CSUNICODE11", 1204}, + {"CSVISCII", 1129}, + {"CYRILLIC", 915}, + {"ECMA-114", 1089}, + {"ECMA-118", 813}, + {"ELOT_928", 813}, + {"EUC-CN", 1383}, + {"EUC-JP", 954}, + {"EUC-KR", 970}, + {"EUC-TW", 964}, + {"EUCCN", 1383}, + {"EUCJP", 954}, + {"EUCKR", 970}, + {"EUCTW", 964}, + {"EXTENDED_UNIX_CODE_PACKED_FORMAT_FOR_JAPANESE", 954}, + {"GB18030", 1392}, + {"GB2312", 1383}, + {"GBK", 1386}, + {"GREEK", 813}, + {"GREEK8", 813}, + {"HEBREW", 62210}, + {"HP-ROMAN8", 1051}, + {"IBM367", 367}, + {"IBM819", 819}, + {"IBM850", 850}, + {"IBM862", 862}, + {"IBM866", 866}, + {"ISO-10646-UCS-2", 1200}, + {"ISO-10646-UCS-4", 1236}, + {"ISO-8859-1", 819}, + {"ISO-8859-13", 901}, + {"ISO-8859-15", 923}, + {"ISO-8859-2", 912}, + {"ISO-8859-3", 913}, + {"ISO-8859-4", 914}, + {"ISO-8859-5", 915}, + {"ISO-8859-6", 1089}, + {"ISO-8859-7", 813}, + {"ISO-8859-8", 62210}, + {"ISO-8859-9", 920}, + {"ISO-IR-100", 819}, + {"ISO-IR-101", 912}, + {"ISO-IR-109", 913}, + {"ISO-IR-110", 914}, + {"ISO-IR-126", 813}, + {"ISO-IR-127", 1089}, + {"ISO-IR-138", 62210}, + {"ISO-IR-144", 915}, + {"ISO-IR-148", 920}, + {"ISO-IR-149", 970}, + {"ISO-IR-166", 874}, + {"ISO-IR-179", 901}, + {"ISO-IR-203", 923}, + {"ISO-IR-6", 367}, + {"ISO646-US", 367}, + {"ISO8859-1", 819}, + {"ISO8859-13", 901}, + {"ISO8859-15", 923}, + {"ISO8859-2", 912}, + {"ISO8859-3", 913}, + {"ISO8859-4", 914}, + {"ISO8859-5", 915}, + {"ISO8859-6", 1089}, + {"ISO8859-7", 813}, + {"ISO8859-8", 62210}, + {"ISO8859-9", 920}, + {"ISO_646.IRV:1991", 367}, + {"ISO_8859-1", 819}, + {"ISO_8859-13", 901}, + {"ISO_8859-15", 923}, + {"ISO_8859-15:1998", 923}, + {"ISO_8859-1:1987", 819}, + {"ISO_8859-2", 912}, + {"ISO_8859-2:1987", 912}, + {"ISO_8859-3", 913}, + {"ISO_8859-3:1988", 913}, + {"ISO_8859-4", 914}, + {"ISO_8859-4:1988", 914}, + {"ISO_8859-5", 915}, + {"ISO_8859-5:1988", 915}, + {"ISO_8859-6", 1089}, + {"ISO_8859-6:1987", 1089}, + {"ISO_8859-7", 813}, + {"ISO_8859-7:1987", 813}, + {"ISO_8859-7:2003", 813}, + {"ISO_8859-8", 62210}, + {"ISO_8859-8:1988", 62210}, + {"ISO_8859-9", 920}, + {"ISO_8859-9:1989", 920}, + {"JISX0201-1976", 896}, + {"JIS_X0201", 896}, + {"KOI8-R", 878}, + {"KOI8-U", 1168}, + {"KOREAN", 970}, + {"KSC_5601", 970}, + {"KS_C_5601-1987", 970}, + {"KS_C_5601-1989", 970}, + {"L1", 819}, + {"L2", 912}, + {"L3", 913}, + {"L4", 914}, + {"L5", 920}, + {"L7", 901}, + {"LATIN-9", 923}, + {"LATIN1", 819}, + {"LATIN2", 912}, + {"LATIN3", 913}, + {"LATIN4", 914}, + {"LATIN5", 920}, + {"LATIN7", 901}, + {"MAC", 1275}, + {"MACINTOSH", 1275}, + {"MACROMAN", 1275}, + {"MS-ANSI", 1252}, + {"MS-ARAB", 1256}, + {"MS-CYRL", 1251}, + {"MS-EE", 1250}, + {"MS-GREEK", 1253}, + {"MS-HEBR", 1255}, + {"MS-TURK", 1254}, + {"MS936", 1386}, + {"MS_KANJI", 943}, + {"R8", 1051}, + {"ROMAN8", 1051}, + {"SHIFT-JIS", 943}, + {"SHIFT_JIS", 943}, + {"SJIS", 943}, + {"TIS-620", 874}, + {"TIS620", 874}, + {"TIS620-0", 874}, + {"TIS620.2529-1", 874}, + {"TIS620.2533-0", 874}, + {"TIS620.2533-1", 874}, + {"UCS-2", 1200}, + {"UCS-2BE", 1204}, + {"UCS-4", 1236}, + {"UNICODE-1-1", 1204}, + {"UNICODEBIG", 1204}, + {"US", 367}, + {"US-ASCII", 367}, + {"UTF-16", 1204}, + {"UTF-16BE", 1200}, + {"UTF-16LE", 1202}, + {"UTF-32", 1236}, + {"UTF-32BE", 1232}, + {"UTF-32LE", 1234}, + {"UTF-8", 1208}, + {"VISCII", 1129}, + {"VISCII1.1-1", 1129}, + {"WINBALTRIM", 1257}, + {"WINDOWS-1250", 1250}, + {"WINDOWS-1251", 1251}, + {"WINDOWS-1252", 1252}, + {"WINDOWS-1253", 1253}, + {"WINDOWS-1254", 1254}, + {"WINDOWS-1255", 1255}, + {"WINDOWS-1256", 1256}, + {"WINDOWS-1257", 1257}, + {"WINDOWS-936", 1386}, + {"X0201", 896} +}; + +char *os2cpToName(unsigned long cp) +{ + ULONG ulLo = 0; + ULONG ulHi = (sizeof(aCP2Name) / sizeof(struct _CP2NAME)) - 1; + ULONG ulNext; + LONG lFound = -1; + + if (cp == SYSTEM_CP) { + ULONG aulCP[3]; + ULONG cCP; + if (DosQueryCp(sizeof(aulCP), aulCP, &cCP) != NO_ERROR) { + return NULL; + } + cp = aulCP[0]; + } + + if (aCP2Name[0].ulCode > cp || aCP2Name[ulHi].ulCode < cp) { + return NULL; + } + if (aCP2Name[0].ulCode == cp) { + return aCP2Name[0].pszName; + } + if (aCP2Name[ulHi].ulCode == cp) { + return aCP2Name[ulHi].pszName; + } + + while ((ulHi - ulLo) > 1) { + ulNext = (ulLo + ulHi) / 2; + + if (aCP2Name[ulNext].ulCode < cp) { + ulLo = ulNext; + } else if (aCP2Name[ulNext].ulCode > cp) { + ulHi = ulNext; + } else { + lFound = ulNext; + break; + } + } + + return (lFound == -1)? NULL : aCP2Name[lFound].pszName; +} + +unsigned long os2cpFromName(char *cp) +{ + ULONG ulLo = 0; + ULONG ulHi = (sizeof(aName2CP) / sizeof(struct _NAME2CP)) - 1; + ULONG ulNext; + LONG lFound = -1; + LONG lCmp; + PCHAR pcEnd; + CHAR acBuf[64]; + + if (!cp) { + ULONG aulCP[3]; + ULONG cCP; + return (DosQueryCp(sizeof(aulCP), aulCP, &cCP) != NO_ERROR)? 0 : aulCP[0]; + } + + while (SDL_isspace((unsigned char) *cp)) { + cp++; + } + + pcEnd = SDL_strchr(cp, ' '); + if (!pcEnd) { + pcEnd = SDL_strchr(cp, '\0'); + } + ulNext = pcEnd - cp; + if (ulNext >= sizeof(acBuf)) { + return 0; + } + + SDL_memcpy(acBuf, cp, ulNext); + acBuf[ulNext] = '\0'; + SDL_strupr(acBuf); + + lCmp = SDL_strcmp(aName2CP[0].pszName, acBuf); + if (lCmp > 0) { + return 0; + } + if (lCmp == 0) { + return aName2CP[0].ulCode; + } + + lCmp = SDL_strcmp(aName2CP[ulHi].pszName, acBuf); + if (lCmp < 0) { + return 0; + } + if (lCmp == 0) { + return aName2CP[ulHi].ulCode; + } + + while ((ulHi - ulLo) > 1) { + ulNext = (ulLo + ulHi) / 2; + + lCmp = SDL_strcmp(aName2CP[ulNext].pszName, acBuf); + if (lCmp < 0) { + ulLo = ulNext; + } else if (lCmp > 0) { + ulHi = ulNext; + } else { + lFound = ulNext; + break; + } + } + + return (lFound == -1)? 0 : aName2CP[lFound].ulCode; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/core/os2/geniconv/os2cp.h b/SDL2-2.30.5/src/core/os2/geniconv/os2cp.h new file mode 100644 index 0000000..7024e9d --- /dev/null +++ b/SDL2-2.30.5/src/core/os2/geniconv/os2cp.h @@ -0,0 +1,32 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#ifndef OS2CP_H +#define OS2CP_H 1 + +#define SYSTEM_CP 0 + +char *os2cpToName(unsigned long cp); +unsigned long os2cpFromName(char *cp); + +#endif /* OS2CP_H */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/core/os2/geniconv/os2iconv.c b/SDL2-2.30.5/src/core/os2/geniconv/os2iconv.c new file mode 100644 index 0000000..4c6a024 --- /dev/null +++ b/SDL2-2.30.5/src/core/os2/geniconv/os2iconv.c @@ -0,0 +1,286 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +/* + Implementation iconv via OS/2 conversion objects API. + + Andrey Vasilkin. +*/ + +#define ICONV_THREAD_SAFE 1 + +#include "geniconv.h" +#define _ULS_CALLCONV_ +#define CALLCONV _System +#include +#ifdef ICONV_THREAD_SAFE +#define INCL_DOSSEMAPHORES +#define INCL_DOSERRORS +#include +#endif + +#include "os2cp.h" + +#ifndef GENICONV_STANDALONE +#include "../../../SDL_internal.h" +#else +#include +#include +#include +#if !defined(min) +#define min(a, b) (((a) < (b)) ? (a) : (b)) +#endif +#define SDL_min min +#define SDL_strcasecmp stricmp +#define SDL_snprintf _snprintf +#define SDL_malloc malloc +#define SDL_free free +#define SDL_memcpy memcpy +#endif + +#define MAX_CP_NAME_LEN 64 + +typedef struct iuconv_obj { + UconvObject uo_tocode; + UconvObject uo_fromcode; + int buf_len; + UniChar *buf; +#ifdef ICONV_THREAD_SAFE + HMTX hMtx; +#endif +} iuconv_obj; + + +static int _createUconvObj(const char *code, UconvObject *uobj) +{ + UniChar uc_code[MAX_CP_NAME_LEN]; + int i; + const unsigned char *ch = + (const unsigned char *)code; + + if (!code) + uc_code[0] = 0; + else { + for (i = 0; i < MAX_CP_NAME_LEN; i++) { + uc_code[i] = (unsigned short)*ch; + if (! (*ch)) + break; + ch++; + } + } + + return UniCreateUconvObject(uc_code, uobj); +} + +static int uconv_open(const char *code, UconvObject *uobj) +{ + int rc; + + if (!SDL_strcasecmp(code, "UTF-16")) { + *uobj = NULL; + return ULS_SUCCESS; + } + + rc = _createUconvObj(code, uobj); + if (rc != ULS_SUCCESS) { + unsigned long cp = os2cpFromName((char *)code); + char cp_name[16]; + if (cp != 0 && SDL_snprintf(cp_name, sizeof(cp_name), "IBM-%u", cp) > 0) { + rc = _createUconvObj(cp_name, uobj); + } + } + + return rc; +} + + +iconv_t _System os2_iconv_open(const char* tocode, const char* fromcode) +{ + UconvObject uo_tocode; + UconvObject uo_fromcode; + int rc; + iuconv_obj *iuobj; + + if (!tocode) { + tocode = ""; + } + if (!fromcode) { + fromcode = ""; + } + + if (SDL_strcasecmp(tocode, fromcode) != 0) { + rc = uconv_open(fromcode, &uo_fromcode); + if (rc != ULS_SUCCESS) { + errno = EINVAL; + return (iconv_t)(-1); + } + rc = uconv_open(tocode, &uo_tocode); + if (rc != ULS_SUCCESS) { + UniFreeUconvObject(uo_fromcode); + errno = EINVAL; + return (iconv_t)(-1); + } + } else { + uo_tocode = NULL; + uo_fromcode = NULL; + } + + iuobj = (iuconv_obj *) SDL_malloc(sizeof(iuconv_obj)); + iuobj->uo_tocode = uo_tocode; + iuobj->uo_fromcode = uo_fromcode; + iuobj->buf_len = 0; + iuobj->buf = NULL; +#ifdef ICONV_THREAD_SAFE + DosCreateMutexSem(NULL, &iuobj->hMtx, 0, FALSE); +#endif + + return iuobj; +} + +size_t _System os2_iconv(iconv_t cd, + char **inbuf, size_t *inbytesleft , + char **outbuf, size_t *outbytesleft) +{ + UconvObject uo_tocode = ((iuconv_obj *)(cd))->uo_tocode; + UconvObject uo_fromcode = ((iuconv_obj *)(cd))->uo_fromcode; + size_t nonIdenticalConv = 0; + UniChar *uc_buf; + size_t uc_buf_len; + UniChar **uc_str; + size_t *uc_str_len; + int rc; + size_t ret = (size_t)(-1); + + if (!uo_tocode && !uo_fromcode) { + uc_buf_len = SDL_min(*inbytesleft, *outbytesleft); + SDL_memcpy(*outbuf, *inbuf, uc_buf_len); + *inbytesleft -= uc_buf_len; + *outbytesleft -= uc_buf_len; + outbuf += uc_buf_len; + inbuf += uc_buf_len; + return uc_buf_len; + } + +#ifdef ICONV_THREAD_SAFE + DosRequestMutexSem(((iuconv_obj *)(cd))->hMtx, SEM_INDEFINITE_WAIT); +#endif + + if (uo_tocode && uo_fromcode && (((iuconv_obj *)cd)->buf_len >> 1) < *inbytesleft) { + if (((iuconv_obj *)cd)->buf != NULL) { + SDL_free(((iuconv_obj *)cd)->buf); + } + ((iuconv_obj *)cd)->buf_len = *inbytesleft << 1; + ((iuconv_obj *)cd)->buf = (UniChar *) SDL_malloc(((iuconv_obj *)cd)->buf_len); + } + + if (uo_fromcode) { + if (uo_tocode) { + uc_buf = ((iuconv_obj *)cd)->buf; + uc_buf_len = ((iuconv_obj *)cd)->buf_len; + uc_str = &uc_buf; + } else { + uc_str = (UniChar **)outbuf; + uc_buf_len = *outbytesleft; + } + uc_buf_len = uc_buf_len >> 1; + uc_str_len = &uc_buf_len; + rc = UniUconvToUcs(uo_fromcode, (void **)inbuf, inbytesleft, + uc_str, uc_str_len, &nonIdenticalConv); + uc_buf_len = uc_buf_len << 1; + if (!uo_tocode) { + *outbytesleft = uc_buf_len; + } + + if (rc != ULS_SUCCESS) { + errno = EILSEQ; + goto done; + } else if (*inbytesleft && !*uc_str_len) { + errno = E2BIG; + goto done; + } + + if (!uo_tocode) { + return nonIdenticalConv; + } + + uc_buf = ((iuconv_obj *)cd)->buf; + uc_buf_len = ((iuconv_obj *)cd)->buf_len - uc_buf_len; + uc_str = &uc_buf; + uc_str_len = &uc_buf_len; + } else { + uc_str = (UniChar **)inbuf; + uc_str_len = inbytesleft; + } + + *uc_str_len = *uc_str_len>>1; + rc = UniUconvFromUcs(uo_tocode, uc_str, uc_str_len, (void **)outbuf, + outbytesleft, &nonIdenticalConv); + if (rc != ULS_SUCCESS) { + switch (rc) { + case ULS_BUFFERFULL: + errno = E2BIG; + break; + case ULS_ILLEGALSEQUENCE: + errno = EILSEQ; + break; + case ULS_INVALID: + errno = EINVAL; + break; + } + goto done; + } else if (*uc_str_len && !*outbytesleft) { + errno = E2BIG; + goto done; + } + + ret = nonIdenticalConv; + +done: + +#ifdef ICONV_THREAD_SAFE + DosReleaseMutexSem(((iuconv_obj *)cd)->hMtx); +#endif + return ret; +} + +int _System os2_iconv_close(iconv_t cd) +{ + if (!cd) return 0; + +#ifdef ICONV_THREAD_SAFE + DosCloseMutexSem(((iuconv_obj *)cd)->hMtx); +#endif + if (((iuconv_obj *)cd)->uo_tocode != NULL) { + UniFreeUconvObject(((iuconv_obj *)cd)->uo_tocode); + } + if (((iuconv_obj *)cd)->uo_fromcode != NULL) { + UniFreeUconvObject(((iuconv_obj *)cd)->uo_fromcode); + } + + if (((iuconv_obj *)cd)->buf != NULL) { + SDL_free(((iuconv_obj *)cd)->buf); + } + SDL_free(cd); + + return 0; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/core/os2/geniconv/sys2utf8.c b/SDL2-2.30.5/src/core/os2/geniconv/sys2utf8.c new file mode 100644 index 0000000..75dd7dd --- /dev/null +++ b/SDL2-2.30.5/src/core/os2/geniconv/sys2utf8.c @@ -0,0 +1,119 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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 "geniconv.h" + +#ifndef GENICONV_STANDALONE +#include "../../../SDL_internal.h" +#else +#include +#define SDL_malloc malloc +#define SDL_realloc realloc +#define SDL_free free +#endif + +int StrUTF8(int to_utf8, char *dst, int c_dst, char *src, int c_src) +{ + size_t rc; + char *dststart = dst; + iconv_t cd; + char *tocp, *fromcp; + int err = 0; + + if (c_dst < 4) { + return -1; + } + + if (to_utf8) { + tocp = "UTF-8"; + fromcp = ""; + } else { + tocp = ""; + fromcp = "UTF-8"; + } + + cd = iconv_open(tocp, fromcp); + if (cd == (iconv_t)-1) { + return -1; + } + + while (c_src > 0) { + rc = iconv(cd, &src, (size_t *)&c_src, &dst, (size_t *)&c_dst); + if (rc == (size_t)-1) { + if (errno == EILSEQ) { + /* Try to skip invalid character */ + src++; + c_src--; + continue; + } + + err = 1; + break; + } + } + + iconv_close(cd); + + /* Write trailing ZERO (1 byte for UTF-8, 2 bytes for the system cp) */ + if (to_utf8) { + if (c_dst < 1) { + dst--; + err = 1; /* The destination buffer overflow */ + } + *dst = '\0'; + } else { + if (c_dst < 2) { + dst -= (c_dst == 0) ? 2 : 1; + err = 1; /* The destination buffer overflow */ + } + *((short *)dst) = '\0'; + } + + return (err) ? -1 : (dst - dststart); +} + +char *StrUTF8New(int to_utf8, char *str, int c_str) +{ + int c_newstr = (((c_str > 4) ? c_str : 4) + 1) * 2; + char * newstr = (char *) SDL_malloc(c_newstr); + + if (!newstr) { + return NULL; + } + + c_newstr = StrUTF8(to_utf8, newstr, c_newstr, str, c_str); + if (c_newstr != -1) { + str = (char *) SDL_realloc(newstr, c_newstr + ((to_utf8) ? 1 : sizeof(short))); + if (str) { + return str; + } + } + + SDL_free(newstr); + return NULL; +} + +void StrUTF8Free(char *str) +{ + SDL_free(str); +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/core/os2/geniconv/test.c b/SDL2-2.30.5/src/core/os2/geniconv/test.c new file mode 100644 index 0000000..2fe19ac --- /dev/null +++ b/SDL2-2.30.5/src/core/os2/geniconv/test.c @@ -0,0 +1,69 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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 +#include +#include +#include "geniconv.h" + +int main(void) +{ + char acBuf[128]; + char *inbuf = "\xf4\xc5\xd3\xd4\x20\x2d\x20\xd0\xd2\xcf\xd7\xc5\xd2\xcb\xc1"; /* KOI8-R encoding of "Тест - проверка" */ + size_t inbytesleft = strlen(inbuf); + char *outbuf = acBuf; + size_t outbytesleft = sizeof(acBuf); + iconv_t ic; + + /* KOI8 -> system cp */ + ic = iconv_open("", "KOI8-R"); + if (ic == (iconv_t)(-1)) { + puts("iconv_open() fail"); + return 1; + } + + iconv(ic, &inbuf, &inbytesleft, &outbuf, &outbytesleft); + printf("KOI8-R to system cp: %s\n", acBuf); + + iconv_close(ic); + + /* System cp -> UTF-8 -> system cp: */ + + /* System cp -> UTF-8 by StrUTF8New() */ + inbuf = StrUTF8New(1, acBuf, strlen(acBuf)); + + /* UTF-8 -> system cp. by StrUTF8() */ + if (StrUTF8(0, acBuf, sizeof(acBuf), inbuf, strlen(inbuf)) == -1) { + puts("StrUTF8() failed"); + } else { + printf("system cp. -> UTF-8 -> system cp.: %s\n", acBuf); + } + + free(inbuf); + + /* Unload used DLL */ + iconv_clean(); + + puts("Done."); + return 0; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/core/os2/iconv2.lbc b/SDL2-2.30.5/src/core/os2/iconv2.lbc new file mode 100644 index 0000000..d9c6875 --- /dev/null +++ b/SDL2-2.30.5/src/core/os2/iconv2.lbc @@ -0,0 +1,4 @@ +# OpenWatcom exports file for libiconv +++'libiconv'.'ICONV2'..'_libiconv' +++'libiconv_close'.'ICONV2'..'_libiconv_close' +++'libiconv_open'.'ICONV2'..'_libiconv_open' diff --git a/SDL2-2.0.12/src/core/unix/SDL_poll.c b/SDL2-2.30.5/src/core/unix/SDL_poll.c similarity index 81% rename from SDL2-2.0.12/src/core/unix/SDL_poll.c rename to SDL2-2.30.5/src/core/unix/SDL_poll.c index 4b286ba..1a34c57 100644 --- a/SDL2-2.0.12/src/core/unix/SDL_poll.c +++ b/SDL2-2.30.5/src/core/unix/SDL_poll.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -21,7 +21,6 @@ #include "../../SDL_internal.h" -#include "SDL_assert.h" #include "SDL_poll.h" #ifdef HAVE_POLL @@ -33,23 +32,24 @@ #endif #include - -int -SDL_IOReady(int fd, SDL_bool forWrite, int timeoutMS) +int SDL_IOReady(int fd, int flags, int timeoutMS) { int result; + SDL_assert(flags & (SDL_IOR_READ | SDL_IOR_WRITE)); + /* Note: We don't bother to account for elapsed time if we get EINTR */ - do - { + do { #ifdef HAVE_POLL struct pollfd info; info.fd = fd; - if (forWrite) { - info.events = POLLOUT; - } else { - info.events = POLLIN | POLLPRI; + info.events = 0; + if (flags & SDL_IOR_READ) { + info.events |= POLLIN | POLLPRI; + } + if (flags & SDL_IOR_WRITE) { + info.events |= POLLOUT; } result = poll(&info, 1, timeoutMS); #else @@ -60,15 +60,16 @@ SDL_IOReady(int fd, SDL_bool forWrite, int timeoutMS) /* If this assert triggers we'll corrupt memory here */ SDL_assert(fd >= 0 && fd < FD_SETSIZE); - if (forWrite) { - FD_ZERO(&wfdset); - FD_SET(fd, &wfdset); - wfdp = &wfdset; - } else { + if (flags & SDL_IOR_READ) { FD_ZERO(&rfdset); FD_SET(fd, &rfdset); rfdp = &rfdset; } + if (flags & SDL_IOR_WRITE) { + FD_ZERO(&wfdset); + FD_SET(fd, &wfdset); + wfdp = &wfdset; + } if (timeoutMS >= 0) { tv.tv_sec = timeoutMS / 1000; @@ -79,7 +80,7 @@ SDL_IOReady(int fd, SDL_bool forWrite, int timeoutMS) result = select(fd + 1, rfdp, wfdp, NULL, tvp); #endif /* HAVE_POLL */ - } while ( result < 0 && errno == EINTR ); + } while (result < 0 && errno == EINTR && !(flags & SDL_IOR_NO_RETRY)); return result; } diff --git a/SDL2-2.0.12/src/core/unix/SDL_poll.h b/SDL2-2.30.5/src/core/unix/SDL_poll.h similarity index 82% rename from SDL2-2.0.12/src/core/unix/SDL_poll.h rename to SDL2-2.30.5/src/core/unix/SDL_poll.h index 8248a7b..67e52ec 100644 --- a/SDL2-2.0.12/src/core/unix/SDL_poll.h +++ b/SDL2-2.30.5/src/core/unix/SDL_poll.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,8 +26,11 @@ #include "SDL_stdinc.h" +#define SDL_IOR_READ 0x1 +#define SDL_IOR_WRITE 0x2 +#define SDL_IOR_NO_RETRY 0x4 -extern int SDL_IOReady(int fd, SDL_bool forWrite, int timeoutMS); +extern int SDL_IOReady(int fd, int flags, int timeoutMS); #endif /* SDL_poll_h_ */ diff --git a/SDL2-2.0.12/src/core/windows/SDL_directx.h b/SDL2-2.30.5/src/core/windows/SDL_directx.h similarity index 76% rename from SDL2-2.0.12/src/core/windows/SDL_directx.h rename to SDL2-2.30.5/src/core/windows/SDL_directx.h index feab3b9..98c63ec 100644 --- a/SDL2-2.0.12/src/core/windows/SDL_directx.h +++ b/SDL2-2.30.5/src/core/windows/SDL_directx.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -30,7 +30,7 @@ #ifndef WIN32 #define WIN32 #endif -#undef WINNT +#undef WINNT /* Far pointers don't exist in 32-bit code */ #ifndef FAR @@ -39,35 +39,35 @@ /* Error codes not yet included in Win32 API header files */ #ifndef MAKE_HRESULT -#define MAKE_HRESULT(sev,fac,code) \ - ((HRESULT)(((unsigned long)(sev)<<31) | ((unsigned long)(fac)<<16) | ((unsigned long)(code)))) +#define MAKE_HRESULT(sev, fac, code) \ + ((HRESULT)(((unsigned long)(sev) << 31) | ((unsigned long)(fac) << 16) | ((unsigned long)(code)))) #endif #ifndef S_OK -#define S_OK (HRESULT)0x00000000L +#define S_OK (HRESULT)0x00000000L #endif #ifndef SUCCEEDED -#define SUCCEEDED(x) ((HRESULT)(x) >= 0) +#define SUCCEEDED(x) ((HRESULT)(x) >= 0) #endif #ifndef FAILED -#define FAILED(x) ((HRESULT)(x)<0) +#define FAILED(x) ((HRESULT)(x) < 0) #endif #ifndef E_FAIL -#define E_FAIL (HRESULT)0x80000008L +#define E_FAIL (HRESULT)0x80000008L #endif #ifndef E_NOINTERFACE -#define E_NOINTERFACE (HRESULT)0x80004002L +#define E_NOINTERFACE (HRESULT)0x80004002L #endif #ifndef E_OUTOFMEMORY -#define E_OUTOFMEMORY (HRESULT)0x8007000EL +#define E_OUTOFMEMORY (HRESULT)0x8007000EL #endif #ifndef E_INVALIDARG -#define E_INVALIDARG (HRESULT)0x80070057L +#define E_INVALIDARG (HRESULT)0x80070057L #endif #ifndef E_NOTIMPL -#define E_NOTIMPL (HRESULT)0x80004001L +#define E_NOTIMPL (HRESULT)0x80004001L #endif #ifndef REGDB_E_CLASSNOTREG #define REGDB_E_CLASSNOTREG (HRESULT)0x80040154L @@ -75,16 +75,16 @@ /* Severity codes */ #ifndef SEVERITY_ERROR -#define SEVERITY_ERROR 1 +#define SEVERITY_ERROR 1 #endif /* Error facility codes */ #ifndef FACILITY_WIN32 -#define FACILITY_WIN32 7 +#define FACILITY_WIN32 7 #endif #ifndef FIELD_OFFSET -#define FIELD_OFFSET(type, field) ((LONG)&(((type *)0)->field)) +#define FIELD_OFFSET(type, field) ((LONG) & (((type *)0)->field)) #endif /* DirectX headers (if it isn't included, I haven't tested it yet) @@ -103,7 +103,10 @@ #ifdef HAVE_DINPUT_H #include #else -typedef struct { int unused; } DIDEVICEINSTANCE; +typedef struct +{ + int unused; +} DIDEVICEINSTANCE; #endif #endif /* SDL_directx_h_ */ diff --git a/SDL2-2.30.5/src/core/windows/SDL_hid.c b/SDL2-2.30.5/src/core/windows/SDL_hid.c new file mode 100644 index 0000000..60b9d14 --- /dev/null +++ b/SDL2-2.30.5/src/core/windows/SDL_hid.c @@ -0,0 +1,86 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifndef __WINRT__ + +#include "SDL_hid.h" + +HidD_GetString_t SDL_HidD_GetManufacturerString; +HidD_GetString_t SDL_HidD_GetProductString; +HidP_GetCaps_t SDL_HidP_GetCaps; +HidP_GetButtonCaps_t SDL_HidP_GetButtonCaps; +HidP_GetValueCaps_t SDL_HidP_GetValueCaps; +HidP_MaxDataListLength_t SDL_HidP_MaxDataListLength; +HidP_GetData_t SDL_HidP_GetData; + +static HMODULE s_pHIDDLL = 0; +static int s_HIDDLLRefCount = 0; + +int WIN_LoadHIDDLL(void) +{ + if (s_pHIDDLL) { + SDL_assert(s_HIDDLLRefCount > 0); + s_HIDDLLRefCount++; + return 0; /* already loaded */ + } + + s_pHIDDLL = LoadLibrary(TEXT("hid.dll")); + if (!s_pHIDDLL) { + return -1; + } + + SDL_assert(s_HIDDLLRefCount == 0); + s_HIDDLLRefCount = 1; + + SDL_HidD_GetManufacturerString = (HidD_GetString_t)GetProcAddress(s_pHIDDLL, "HidD_GetManufacturerString"); + SDL_HidD_GetProductString = (HidD_GetString_t)GetProcAddress(s_pHIDDLL, "HidD_GetProductString"); + SDL_HidP_GetCaps = (HidP_GetCaps_t)GetProcAddress(s_pHIDDLL, "HidP_GetCaps"); + SDL_HidP_GetButtonCaps = (HidP_GetButtonCaps_t)GetProcAddress(s_pHIDDLL, "HidP_GetButtonCaps"); + SDL_HidP_GetValueCaps = (HidP_GetValueCaps_t)GetProcAddress(s_pHIDDLL, "HidP_GetValueCaps"); + SDL_HidP_MaxDataListLength = (HidP_MaxDataListLength_t)GetProcAddress(s_pHIDDLL, "HidP_MaxDataListLength"); + SDL_HidP_GetData = (HidP_GetData_t)GetProcAddress(s_pHIDDLL, "HidP_GetData"); + if (!SDL_HidD_GetManufacturerString || !SDL_HidD_GetProductString || + !SDL_HidP_GetCaps || !SDL_HidP_GetButtonCaps || + !SDL_HidP_GetValueCaps || !SDL_HidP_MaxDataListLength || !SDL_HidP_GetData) { + WIN_UnloadHIDDLL(); + return -1; + } + + return 0; +} + +void WIN_UnloadHIDDLL(void) +{ + if (s_pHIDDLL) { + SDL_assert(s_HIDDLLRefCount > 0); + if (--s_HIDDLLRefCount == 0) { + FreeLibrary(s_pHIDDLL); + s_pHIDDLL = NULL; + } + } else { + SDL_assert(s_HIDDLLRefCount == 0); + } +} + +#endif /* !__WINRT__ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/core/windows/SDL_hid.h b/SDL2-2.30.5/src/core/windows/SDL_hid.h new file mode 100644 index 0000000..f75ea24 --- /dev/null +++ b/SDL2-2.30.5/src/core/windows/SDL_hid.h @@ -0,0 +1,215 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifndef SDL_hid_h_ +#define SDL_hid_h_ + +#include "SDL_windows.h" + +#ifndef __WINRT__ + +typedef LONG NTSTATUS; +typedef USHORT USAGE; +typedef struct _HIDP_PREPARSED_DATA *PHIDP_PREPARSED_DATA; + +typedef struct _HIDD_ATTRIBUTES +{ + ULONG Size; + USHORT VendorID; + USHORT ProductID; + USHORT VersionNumber; +} HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES; + +typedef enum +{ + HidP_Input = 0, + HidP_Output = 1, + HidP_Feature = 2 +} HIDP_REPORT_TYPE; + +typedef struct +{ + USAGE UsagePage; + UCHAR ReportID; + BOOLEAN IsAlias; + USHORT BitField; + USHORT LinkCollection; + USAGE LinkUsage; + USAGE LinkUsagePage; + BOOLEAN IsRange; + BOOLEAN IsStringRange; + BOOLEAN IsDesignatorRange; + BOOLEAN IsAbsolute; + ULONG Reserved[10]; + union + { + struct + { + USAGE UsageMin; + USAGE UsageMax; + USHORT StringMin; + USHORT StringMax; + USHORT DesignatorMin; + USHORT DesignatorMax; + USHORT DataIndexMin; + USHORT DataIndexMax; + } Range; + struct + { + USAGE Usage; + USAGE Reserved1; + USHORT StringIndex; + USHORT Reserved2; + USHORT DesignatorIndex; + USHORT Reserved3; + USHORT DataIndex; + USHORT Reserved4; + } NotRange; + }; +} HIDP_BUTTON_CAPS, *PHIDP_BUTTON_CAPS; + +typedef struct +{ + USAGE UsagePage; + UCHAR ReportID; + BOOLEAN IsAlias; + USHORT BitField; + USHORT LinkCollection; + USAGE LinkUsage; + USAGE LinkUsagePage; + BOOLEAN IsRange; + BOOLEAN IsStringRange; + BOOLEAN IsDesignatorRange; + BOOLEAN IsAbsolute; + BOOLEAN HasNull; + UCHAR Reserved; + USHORT BitSize; + USHORT ReportCount; + USHORT Reserved2[5]; + ULONG UnitsExp; + ULONG Units; + LONG LogicalMin; + LONG LogicalMax; + LONG PhysicalMin; + LONG PhysicalMax; + union + { + struct + { + USAGE UsageMin; + USAGE UsageMax; + USHORT StringMin; + USHORT StringMax; + USHORT DesignatorMin; + USHORT DesignatorMax; + USHORT DataIndexMin; + USHORT DataIndexMax; + } Range; + struct + { + USAGE Usage; + USAGE Reserved1; + USHORT StringIndex; + USHORT Reserved2; + USHORT DesignatorIndex; + USHORT Reserved3; + USHORT DataIndex; + USHORT Reserved4; + } NotRange; + }; +} HIDP_VALUE_CAPS, *PHIDP_VALUE_CAPS; + +typedef struct +{ + USAGE Usage; + USAGE UsagePage; + USHORT InputReportByteLength; + USHORT OutputReportByteLength; + USHORT FeatureReportByteLength; + USHORT Reserved[17]; + USHORT NumberLinkCollectionNodes; + USHORT NumberInputButtonCaps; + USHORT NumberInputValueCaps; + USHORT NumberInputDataIndices; + USHORT NumberOutputButtonCaps; + USHORT NumberOutputValueCaps; + USHORT NumberOutputDataIndices; + USHORT NumberFeatureButtonCaps; + USHORT NumberFeatureValueCaps; + USHORT NumberFeatureDataIndices; +} HIDP_CAPS, *PHIDP_CAPS; + +typedef struct +{ + USHORT DataIndex; + USHORT Reserved; + union + { + ULONG RawValue; + BOOLEAN On; + }; +} HIDP_DATA, *PHIDP_DATA; + +#define HIDP_ERROR_CODES(p1, p2) ((NTSTATUS)(((p1) << 28) | (0x11 << 16) | (p2))) +#define HIDP_STATUS_SUCCESS HIDP_ERROR_CODES(0x0, 0x0000) +#define HIDP_STATUS_NULL HIDP_ERROR_CODES(0x8, 0x0001) +#define HIDP_STATUS_INVALID_PREPARSED_DATA HIDP_ERROR_CODES(0xC, 0x0001) +#define HIDP_STATUS_INVALID_REPORT_TYPE HIDP_ERROR_CODES(0xC, 0x0002) +#define HIDP_STATUS_INVALID_REPORT_LENGTH HIDP_ERROR_CODES(0xC, 0x0003) +#define HIDP_STATUS_USAGE_NOT_FOUND HIDP_ERROR_CODES(0xC, 0x0004) +#define HIDP_STATUS_VALUE_OUT_OF_RANGE HIDP_ERROR_CODES(0xC, 0x0005) +#define HIDP_STATUS_BAD_LOG_PHY_VALUES HIDP_ERROR_CODES(0xC, 0x0006) +#define HIDP_STATUS_BUFFER_TOO_SMALL HIDP_ERROR_CODES(0xC, 0x0007) +#define HIDP_STATUS_INTERNAL_ERROR HIDP_ERROR_CODES(0xC, 0x0008) +#define HIDP_STATUS_I8042_TRANS_UNKNOWN HIDP_ERROR_CODES(0xC, 0x0009) +#define HIDP_STATUS_INCOMPATIBLE_REPORT_ID HIDP_ERROR_CODES(0xC, 0x000A) +#define HIDP_STATUS_NOT_VALUE_ARRAY HIDP_ERROR_CODES(0xC, 0x000B) +#define HIDP_STATUS_IS_VALUE_ARRAY HIDP_ERROR_CODES(0xC, 0x000C) +#define HIDP_STATUS_DATA_INDEX_NOT_FOUND HIDP_ERROR_CODES(0xC, 0x000D) +#define HIDP_STATUS_DATA_INDEX_OUT_OF_RANGE HIDP_ERROR_CODES(0xC, 0x000E) +#define HIDP_STATUS_BUTTON_NOT_PRESSED HIDP_ERROR_CODES(0xC, 0x000F) +#define HIDP_STATUS_REPORT_DOES_NOT_EXIST HIDP_ERROR_CODES(0xC, 0x0010) +#define HIDP_STATUS_NOT_IMPLEMENTED HIDP_ERROR_CODES(0xC, 0x0020) + +extern int WIN_LoadHIDDLL(void); +extern void WIN_UnloadHIDDLL(void); + +typedef BOOLEAN(WINAPI *HidD_GetString_t)(HANDLE HidDeviceObject, PVOID Buffer, ULONG BufferLength); +typedef NTSTATUS(WINAPI *HidP_GetCaps_t)(PHIDP_PREPARSED_DATA PreparsedData, PHIDP_CAPS Capabilities); +typedef NTSTATUS(WINAPI *HidP_GetButtonCaps_t)(HIDP_REPORT_TYPE ReportType, PHIDP_BUTTON_CAPS ButtonCaps, PUSHORT ButtonCapsLength, PHIDP_PREPARSED_DATA PreparsedData); +typedef NTSTATUS(WINAPI *HidP_GetValueCaps_t)(HIDP_REPORT_TYPE ReportType, PHIDP_VALUE_CAPS ValueCaps, PUSHORT ValueCapsLength, PHIDP_PREPARSED_DATA PreparsedData); +typedef ULONG(WINAPI *HidP_MaxDataListLength_t)(HIDP_REPORT_TYPE ReportType, PHIDP_PREPARSED_DATA PreparsedData); +typedef NTSTATUS(WINAPI *HidP_GetData_t)(HIDP_REPORT_TYPE ReportType, PHIDP_DATA DataList, PULONG DataLength, PHIDP_PREPARSED_DATA PreparsedData, PCHAR Report, ULONG ReportLength); + +extern HidD_GetString_t SDL_HidD_GetManufacturerString; +extern HidD_GetString_t SDL_HidD_GetProductString; +extern HidP_GetCaps_t SDL_HidP_GetCaps; +extern HidP_GetButtonCaps_t SDL_HidP_GetButtonCaps; +extern HidP_GetValueCaps_t SDL_HidP_GetValueCaps; +extern HidP_MaxDataListLength_t SDL_HidP_MaxDataListLength; +extern HidP_GetData_t SDL_HidP_GetData; + +#endif /* !__WINRT__ */ + +#endif /* SDL_hid_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/core/windows/SDL_immdevice.c b/SDL2-2.30.5/src/core/windows/SDL_immdevice.c new file mode 100644 index 0000000..a8e8b45 --- /dev/null +++ b/SDL2-2.30.5/src/core/windows/SDL_immdevice.c @@ -0,0 +1,543 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#if (defined(__WIN32__) || defined(__GDK__)) && defined(HAVE_MMDEVICEAPI_H) + +#include "SDL_windows.h" +#include "SDL_immdevice.h" +#include "SDL_timer.h" +#include "../../audio/SDL_sysaudio.h" +#include /* For CLSIDFromString */ + +static const ERole SDL_IMMDevice_role = eConsole; /* !!! FIXME: should this be eMultimedia? Should be a hint? */ + +/* This is global to the WASAPI target, to handle hotplug and default device lookup. */ +static IMMDeviceEnumerator *enumerator = NULL; + +/* PropVariantInit() is an inline function/macro in PropIdl.h that calls the C runtime's memset() directly. Use ours instead, to avoid dependency. */ +#ifdef PropVariantInit +#undef PropVariantInit +#endif +#define PropVariantInit(p) SDL_zerop(p) + +/* Some GUIDs we need to know without linking to libraries that aren't available before Vista. */ +/* *INDENT-OFF* */ /* clang-format off */ +static const CLSID SDL_CLSID_MMDeviceEnumerator = { 0xbcde0395, 0xe52f, 0x467c,{ 0x8e, 0x3d, 0xc4, 0x57, 0x92, 0x91, 0x69, 0x2e } }; +static const IID SDL_IID_IMMDeviceEnumerator = { 0xa95664d2, 0x9614, 0x4f35,{ 0xa7, 0x46, 0xde, 0x8d, 0xb6, 0x36, 0x17, 0xe6 } }; +static const IID SDL_IID_IMMNotificationClient = { 0x7991eec9, 0x7e89, 0x4d85,{ 0x83, 0x90, 0x6c, 0x70, 0x3c, 0xec, 0x60, 0xc0 } }; +static const IID SDL_IID_IMMEndpoint = { 0x1be09788, 0x6894, 0x4089,{ 0x85, 0x86, 0x9a, 0x2a, 0x6c, 0x26, 0x5a, 0xc5 } }; +static const PROPERTYKEY SDL_PKEY_Device_FriendlyName = { { 0xa45c254e, 0xdf1c, 0x4efd,{ 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, } }, 14 }; +static const PROPERTYKEY SDL_PKEY_AudioEngine_DeviceFormat = { { 0xf19f064d, 0x82c, 0x4e27,{ 0xbc, 0x73, 0x68, 0x82, 0xa1, 0xbb, 0x8e, 0x4c, } }, 0 }; +static const PROPERTYKEY SDL_PKEY_AudioEndpoint_GUID = { { 0x1da5d803, 0xd492, 0x4edd,{ 0x8c, 0x23, 0xe0, 0xc0, 0xff, 0xee, 0x7f, 0x0e, } }, 4 }; +static const GUID SDL_KSDATAFORMAT_SUBTYPE_PCM = { 0x00000001, 0x0000, 0x0010,{ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } }; +static const GUID SDL_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = { 0x00000003, 0x0000, 0x0010,{ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } }; +/* *INDENT-ON* */ /* clang-format on */ + +/* these increment as default devices change. Opened default devices pick up changes in their threads. */ +SDL_atomic_t SDL_IMMDevice_DefaultPlaybackGeneration; +SDL_atomic_t SDL_IMMDevice_DefaultCaptureGeneration; + +static void GetMMDeviceInfo(IMMDevice *device, char **utf8dev, WAVEFORMATEXTENSIBLE *fmt, GUID *guid) +{ + /* PKEY_Device_FriendlyName gives you "Speakers (SoundBlaster Pro)" which drives me nuts. I'd rather it be + "SoundBlaster Pro (Speakers)" but I guess that's developers vs users. Windows uses the FriendlyName in + its own UIs, like Volume Control, etc. */ + IPropertyStore *props = NULL; + *utf8dev = NULL; + SDL_zerop(fmt); + if (SUCCEEDED(IMMDevice_OpenPropertyStore(device, STGM_READ, &props))) { + PROPVARIANT var; + PropVariantInit(&var); + if (SUCCEEDED(IPropertyStore_GetValue(props, &SDL_PKEY_Device_FriendlyName, &var))) { + *utf8dev = WIN_StringToUTF8W(var.pwszVal); + } + PropVariantClear(&var); + if (SUCCEEDED(IPropertyStore_GetValue(props, &SDL_PKEY_AudioEngine_DeviceFormat, &var))) { + SDL_memcpy(fmt, var.blob.pBlobData, SDL_min(var.blob.cbSize, sizeof(WAVEFORMATEXTENSIBLE))); + } + PropVariantClear(&var); + if (SUCCEEDED(IPropertyStore_GetValue(props, &SDL_PKEY_AudioEndpoint_GUID, &var))) { + CLSIDFromString(var.pwszVal, guid); + } + PropVariantClear(&var); + IPropertyStore_Release(props); + } +} + +/* This is a list of device id strings we have inflight, so we have consistent pointers to the same device. */ +typedef struct DevIdList +{ + LPWSTR str; + LPGUID guid; + struct DevIdList *next; +} DevIdList; + +static DevIdList *deviceid_list = NULL; + +static void SDL_IMMDevice_Remove(const SDL_bool iscapture, LPCWSTR devid, SDL_bool useguid) +{ + DevIdList *i; + DevIdList *next; + DevIdList *prev = NULL; + for (i = deviceid_list; i; i = next) { + next = i->next; + if (SDL_wcscmp(i->str, devid) == 0) { + if (prev) { + prev->next = next; + } else { + deviceid_list = next; + } + SDL_RemoveAudioDevice(iscapture, useguid ? ((void *)i->guid) : ((void *)i->str)); + SDL_free(i->str); + SDL_free(i); + } else { + prev = i; + } + } +} + +static void SDL_IMMDevice_Add(const SDL_bool iscapture, const char *devname, WAVEFORMATEXTENSIBLE *fmt, LPCWSTR devid, GUID *dsoundguid, SDL_bool useguid) +{ + DevIdList *devidlist; + SDL_AudioSpec spec; + LPWSTR devidcopy; + LPGUID cpyguid; + LPVOID driverdata; + + /* You can have multiple endpoints on a device that are mutually exclusive ("Speakers" vs "Line Out" or whatever). + In a perfect world, things that are unplugged won't be in this collection. The only gotcha is probably for + phones and tablets, where you might have an internal speaker and a headphone jack and expect both to be + available and switch automatically. (!!! FIXME...?) */ + + /* see if we already have this one. */ + for (devidlist = deviceid_list; devidlist; devidlist = devidlist->next) { + if (SDL_wcscmp(devidlist->str, devid) == 0) { + return; /* we already have this. */ + } + } + + devidlist = (DevIdList *)SDL_malloc(sizeof(*devidlist)); + if (!devidlist) { + return; /* oh well. */ + } + + devidcopy = SDL_wcsdup(devid); + if (!devidcopy) { + SDL_free(devidlist); + return; /* oh well. */ + } + + if (useguid) { + /* This is freed by DSOUND_FreeDeviceData! */ + cpyguid = (LPGUID)SDL_malloc(sizeof(GUID)); + if (!cpyguid) { + SDL_free(devidlist); + SDL_free(devidcopy); + return; /* oh well. */ + } + SDL_memcpy(cpyguid, dsoundguid, sizeof(GUID)); + driverdata = cpyguid; + } else { + cpyguid = NULL; + driverdata = devidcopy; + } + + devidlist->str = devidcopy; + devidlist->guid = cpyguid; + devidlist->next = deviceid_list; + deviceid_list = devidlist; + + SDL_zero(spec); + spec.channels = (Uint8)fmt->Format.nChannels; + spec.freq = fmt->Format.nSamplesPerSec; + spec.format = WaveFormatToSDLFormat((WAVEFORMATEX *)fmt); + SDL_AddAudioDevice(iscapture, devname, &spec, driverdata); +} + +/* We need a COM subclass of IMMNotificationClient for hotplug support, which is + easy in C++, but we have to tapdance more to make work in C. + Thanks to this page for coaching on how to make this work: + https://www.codeproject.com/Articles/13601/COM-in-plain-C */ + +typedef struct SDLMMNotificationClient +{ + const IMMNotificationClientVtbl *lpVtbl; + SDL_atomic_t refcount; + SDL_bool useguid; +} SDLMMNotificationClient; + +static HRESULT STDMETHODCALLTYPE SDLMMNotificationClient_QueryInterface(IMMNotificationClient *this, REFIID iid, void **ppv) +{ + if ((WIN_IsEqualIID(iid, &IID_IUnknown)) || (WIN_IsEqualIID(iid, &SDL_IID_IMMNotificationClient))) { + *ppv = this; + this->lpVtbl->AddRef(this); + return S_OK; + } + + *ppv = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE SDLMMNotificationClient_AddRef(IMMNotificationClient *ithis) +{ + SDLMMNotificationClient *this = (SDLMMNotificationClient *)ithis; + return (ULONG)(SDL_AtomicIncRef(&this->refcount) + 1); +} + +static ULONG STDMETHODCALLTYPE SDLMMNotificationClient_Release(IMMNotificationClient *ithis) +{ + /* this is a static object; we don't ever free it. */ + SDLMMNotificationClient *this = (SDLMMNotificationClient *)ithis; + const ULONG retval = SDL_AtomicDecRef(&this->refcount); + if (retval == 0) { + SDL_AtomicSet(&this->refcount, 0); /* uhh... */ + return 0; + } + return retval - 1; +} + +/* These are the entry points called when WASAPI device endpoints change. */ +static HRESULT STDMETHODCALLTYPE SDLMMNotificationClient_OnDefaultDeviceChanged(IMMNotificationClient *ithis, EDataFlow flow, ERole role, LPCWSTR pwstrDeviceId) +{ + if (role != SDL_IMMDevice_role) { + return S_OK; /* ignore it. */ + } + + /* Increment the "generation," so opened devices will pick this up in their threads. */ + switch (flow) { + case eRender: + SDL_AtomicAdd(&SDL_IMMDevice_DefaultPlaybackGeneration, 1); + break; + + case eCapture: + SDL_AtomicAdd(&SDL_IMMDevice_DefaultCaptureGeneration, 1); + break; + + case eAll: + SDL_AtomicAdd(&SDL_IMMDevice_DefaultPlaybackGeneration, 1); + SDL_AtomicAdd(&SDL_IMMDevice_DefaultCaptureGeneration, 1); + break; + + default: + SDL_assert(!"uhoh, unexpected OnDefaultDeviceChange flow!"); + break; + } + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE SDLMMNotificationClient_OnDeviceAdded(IMMNotificationClient *ithis, LPCWSTR pwstrDeviceId) +{ + /* we ignore this; devices added here then progress to ACTIVE, if appropriate, in + OnDeviceStateChange, making that a better place to deal with device adds. More + importantly: the first time you plug in a USB audio device, this callback will + fire, but when you unplug it, it isn't removed (it's state changes to NOTPRESENT). + Plugging it back in won't fire this callback again. */ + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE SDLMMNotificationClient_OnDeviceRemoved(IMMNotificationClient *ithis, LPCWSTR pwstrDeviceId) +{ + /* See notes in OnDeviceAdded handler about why we ignore this. */ + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE SDLMMNotificationClient_OnDeviceStateChanged(IMMNotificationClient *ithis, LPCWSTR pwstrDeviceId, DWORD dwNewState) +{ + IMMDevice *device = NULL; + + if (SUCCEEDED(IMMDeviceEnumerator_GetDevice(enumerator, pwstrDeviceId, &device))) { + IMMEndpoint *endpoint = NULL; + if (SUCCEEDED(IMMDevice_QueryInterface(device, &SDL_IID_IMMEndpoint, (void **)&endpoint))) { + EDataFlow flow; + if (SUCCEEDED(IMMEndpoint_GetDataFlow(endpoint, &flow))) { + const SDL_bool iscapture = (flow == eCapture); + const SDLMMNotificationClient *client = (SDLMMNotificationClient *)ithis; + if (dwNewState == DEVICE_STATE_ACTIVE) { + char *utf8dev; + WAVEFORMATEXTENSIBLE fmt; + GUID dsoundguid; + GetMMDeviceInfo(device, &utf8dev, &fmt, &dsoundguid); + if (utf8dev) { + SDL_IMMDevice_Add(iscapture, utf8dev, &fmt, pwstrDeviceId, &dsoundguid, client->useguid); + SDL_free(utf8dev); + } + } else { + SDL_IMMDevice_Remove(iscapture, pwstrDeviceId, client->useguid); + } + } + IMMEndpoint_Release(endpoint); + } + IMMDevice_Release(device); + } + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE SDLMMNotificationClient_OnPropertyValueChanged(IMMNotificationClient *this, LPCWSTR pwstrDeviceId, const PROPERTYKEY key) +{ + return S_OK; /* we don't care about these. */ +} + +static const IMMNotificationClientVtbl notification_client_vtbl = { + SDLMMNotificationClient_QueryInterface, + SDLMMNotificationClient_AddRef, + SDLMMNotificationClient_Release, + SDLMMNotificationClient_OnDeviceStateChanged, + SDLMMNotificationClient_OnDeviceAdded, + SDLMMNotificationClient_OnDeviceRemoved, + SDLMMNotificationClient_OnDefaultDeviceChanged, + SDLMMNotificationClient_OnPropertyValueChanged +}; + +static SDLMMNotificationClient notification_client = { ¬ification_client_vtbl, { 1 } }; + +int SDL_IMMDevice_Init(void) +{ + HRESULT ret; + + SDL_AtomicSet(&SDL_IMMDevice_DefaultPlaybackGeneration, 1); + SDL_AtomicSet(&SDL_IMMDevice_DefaultCaptureGeneration, 1); + + /* just skip the discussion with COM here. */ + if (!WIN_IsWindowsVistaOrGreater()) { + return SDL_SetError("WASAPI support requires Windows Vista or later"); + } + + if (FAILED(WIN_CoInitialize())) { + return SDL_SetError("WASAPI: CoInitialize() failed"); + } + + ret = CoCreateInstance(&SDL_CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &SDL_IID_IMMDeviceEnumerator, (LPVOID *)&enumerator); + if (FAILED(ret)) { + WIN_CoUninitialize(); + return WIN_SetErrorFromHRESULT("WASAPI CoCreateInstance(MMDeviceEnumerator)", ret); + } + return 0; +} + +void SDL_IMMDevice_Quit(void) +{ + DevIdList *devidlist; + DevIdList *next; + + if (enumerator) { + IMMDeviceEnumerator_UnregisterEndpointNotificationCallback(enumerator, (IMMNotificationClient *)¬ification_client); + IMMDeviceEnumerator_Release(enumerator); + enumerator = NULL; + } + + WIN_CoUninitialize(); + + for (devidlist = deviceid_list; devidlist; devidlist = next) { + next = devidlist->next; + SDL_free(devidlist->str); + SDL_free(devidlist); + } + deviceid_list = NULL; +} + +int SDL_IMMDevice_Get(LPCWSTR devid, IMMDevice **device, SDL_bool iscapture) +{ + const Uint64 timeout = SDL_GetTicks64() + 8000; /* intel's audio drivers can fail for up to EIGHT SECONDS after a device is connected or we wake from sleep. */ + HRESULT ret; + + SDL_assert(device != NULL); + + while (SDL_TRUE) { + if (!devid) { + const EDataFlow dataflow = iscapture ? eCapture : eRender; + ret = IMMDeviceEnumerator_GetDefaultAudioEndpoint(enumerator, dataflow, SDL_IMMDevice_role, device); + } else { + ret = IMMDeviceEnumerator_GetDevice(enumerator, devid, device); + } + + if (SUCCEEDED(ret)) { + break; + } + + if (ret == E_NOTFOUND) { + const Uint64 now = SDL_GetTicks64(); + if (timeout > now) { + const Uint64 ticksleft = timeout - now; + SDL_Delay((Uint32)SDL_min(ticksleft, 300)); /* wait awhile and try again. */ + continue; + } + } + + return WIN_SetErrorFromHRESULT("WASAPI can't find requested audio endpoint", ret); + } + return 0; +} + +typedef struct +{ + LPWSTR devid; + char *devname; + WAVEFORMATEXTENSIBLE fmt; + GUID dsoundguid; +} EndpointItem; + +static int SDLCALL sort_endpoints(const void *_a, const void *_b) +{ + LPWSTR a = ((const EndpointItem *)_a)->devid; + LPWSTR b = ((const EndpointItem *)_b)->devid; + if (!a && !b) { + return 0; + } else if (!a && b) { + return -1; + } else if (a && !b) { + return 1; + } + + while (SDL_TRUE) { + if (*a < *b) { + return -1; + } else if (*a > *b) { + return 1; + } else if (*a == 0) { + break; + } + a++; + b++; + } + + return 0; +} + +static void EnumerateEndpointsForFlow(const SDL_bool iscapture) +{ + IMMDeviceCollection *collection = NULL; + EndpointItem *items; + UINT i, total; + + /* Note that WASAPI separates "adapter devices" from "audio endpoint devices" + ...one adapter device ("SoundBlaster Pro") might have multiple endpoint devices ("Speakers", "Line-Out"). */ + + if (FAILED(IMMDeviceEnumerator_EnumAudioEndpoints(enumerator, iscapture ? eCapture : eRender, DEVICE_STATE_ACTIVE, &collection))) { + return; + } + + if (FAILED(IMMDeviceCollection_GetCount(collection, &total))) { + IMMDeviceCollection_Release(collection); + return; + } + + items = (EndpointItem *)SDL_calloc(total, sizeof(EndpointItem)); + if (!items) { + return; /* oh well. */ + } + + for (i = 0; i < total; i++) { + EndpointItem *item = items + i; + IMMDevice *device = NULL; + if (SUCCEEDED(IMMDeviceCollection_Item(collection, i, &device))) { + if (SUCCEEDED(IMMDevice_GetId(device, &item->devid))) { + GetMMDeviceInfo(device, &item->devname, &item->fmt, &item->dsoundguid); + } + IMMDevice_Release(device); + } + } + + /* sort the list of devices by their guid so list is consistent between runs */ + SDL_qsort(items, total, sizeof(*items), sort_endpoints); + + /* Send the sorted list on to the SDL's higher level. */ + for (i = 0; i < total; i++) { + EndpointItem *item = items + i; + if ((item->devid) && (item->devname)) { + SDL_IMMDevice_Add(iscapture, item->devname, &item->fmt, item->devid, &item->dsoundguid, notification_client.useguid); + } + SDL_free(item->devname); + CoTaskMemFree(item->devid); + } + + SDL_free(items); + IMMDeviceCollection_Release(collection); +} + +void SDL_IMMDevice_EnumerateEndpoints(SDL_bool useguid) +{ + notification_client.useguid = useguid; + + EnumerateEndpointsForFlow(SDL_FALSE); /* playback */ + EnumerateEndpointsForFlow(SDL_TRUE); /* capture */ + + /* if this fails, we just won't get hotplug events. Carry on anyhow. */ + IMMDeviceEnumerator_RegisterEndpointNotificationCallback(enumerator, (IMMNotificationClient *)¬ification_client); +} + +int SDL_IMMDevice_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture) +{ + WAVEFORMATEXTENSIBLE fmt; + IMMDevice *device = NULL; + char *filler; + GUID morefiller; + const EDataFlow dataflow = iscapture ? eCapture : eRender; + HRESULT ret = IMMDeviceEnumerator_GetDefaultAudioEndpoint(enumerator, dataflow, SDL_IMMDevice_role, &device); + + if (FAILED(ret)) { + SDL_assert(device == NULL); + return WIN_SetErrorFromHRESULT("WASAPI can't find default audio endpoint", ret); + } + + if (!name) { + name = &filler; + } + + SDL_zero(fmt); + GetMMDeviceInfo(device, name, &fmt, &morefiller); + IMMDevice_Release(device); + + if (name == &filler) { + SDL_free(filler); + } + + SDL_zerop(spec); + spec->channels = (Uint8)fmt.Format.nChannels; + spec->freq = fmt.Format.nSamplesPerSec; + spec->format = WaveFormatToSDLFormat((WAVEFORMATEX *)&fmt); + return 0; +} + +SDL_AudioFormat WaveFormatToSDLFormat(WAVEFORMATEX *waveformat) +{ + if ((waveformat->wFormatTag == WAVE_FORMAT_IEEE_FLOAT) && (waveformat->wBitsPerSample == 32)) { + return AUDIO_F32SYS; + } else if ((waveformat->wFormatTag == WAVE_FORMAT_PCM) && (waveformat->wBitsPerSample == 16)) { + return AUDIO_S16SYS; + } else if ((waveformat->wFormatTag == WAVE_FORMAT_PCM) && (waveformat->wBitsPerSample == 32)) { + return AUDIO_S32SYS; + } else if (waveformat->wFormatTag == WAVE_FORMAT_EXTENSIBLE) { + const WAVEFORMATEXTENSIBLE *ext = (const WAVEFORMATEXTENSIBLE *)waveformat; + if ((SDL_memcmp(&ext->SubFormat, &SDL_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, sizeof(GUID)) == 0) && (waveformat->wBitsPerSample == 32)) { + return AUDIO_F32SYS; + } else if ((SDL_memcmp(&ext->SubFormat, &SDL_KSDATAFORMAT_SUBTYPE_PCM, sizeof(GUID)) == 0) && (waveformat->wBitsPerSample == 16)) { + return AUDIO_S16SYS; + } else if ((SDL_memcmp(&ext->SubFormat, &SDL_KSDATAFORMAT_SUBTYPE_PCM, sizeof(GUID)) == 0) && (waveformat->wBitsPerSample == 32)) { + return AUDIO_S32SYS; + } + } + return 0; +} + +#endif /* (defined(__WIN32__) || defined(__GDK__)) && HAVE_MMDEVICEAPI_H */ diff --git a/SDL2-2.30.5/src/core/windows/SDL_immdevice.h b/SDL2-2.30.5/src/core/windows/SDL_immdevice.h new file mode 100644 index 0000000..b15b903 --- /dev/null +++ b/SDL2-2.30.5/src/core/windows/SDL_immdevice.h @@ -0,0 +1,44 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#ifndef SDL_IMMDEVICE_H +#define SDL_IMMDEVICE_H + +#include "SDL_atomic.h" +#include "SDL_audio.h" + +#define COBJMACROS +#include +#include + +int SDL_IMMDevice_Init(void); +void SDL_IMMDevice_Quit(void); +int SDL_IMMDevice_Get(LPCWSTR devid, IMMDevice **device, SDL_bool iscapture); +void SDL_IMMDevice_EnumerateEndpoints(SDL_bool useguid); +int SDL_IMMDevice_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture); + +SDL_AudioFormat WaveFormatToSDLFormat(WAVEFORMATEX *waveformat); + +/* these increment as default devices change. Opened default devices pick up changes in their threads. */ +extern SDL_atomic_t SDL_IMMDevice_DefaultPlaybackGeneration; +extern SDL_atomic_t SDL_IMMDevice_DefaultCaptureGeneration; + +#endif /* SDL_IMMDEVICE_H */ diff --git a/SDL2-2.30.5/src/core/windows/SDL_windows.c b/SDL2-2.30.5/src/core/windows/SDL_windows.c new file mode 100644 index 0000000..1da9418 --- /dev/null +++ b/SDL2-2.30.5/src/core/windows/SDL_windows.c @@ -0,0 +1,386 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#if defined(__WIN32__) || defined(__WINRT__) || defined(__GDK__) + +#include "SDL_windows.h" +#include "SDL_error.h" +#include "SDL_system.h" + +#include /* for CoInitialize/CoUninitialize (Win32 only) */ +#if defined(HAVE_ROAPI_H) +#include /* For RoInitialize/RoUninitialize (Win32 only) */ +#else +typedef enum RO_INIT_TYPE +{ + RO_INIT_SINGLETHREADED = 0, + RO_INIT_MULTITHREADED = 1 +} RO_INIT_TYPE; +#endif + +#ifndef _WIN32_WINNT_VISTA +#define _WIN32_WINNT_VISTA 0x0600 +#endif +#ifndef _WIN32_WINNT_WIN7 +#define _WIN32_WINNT_WIN7 0x0601 +#endif +#ifndef _WIN32_WINNT_WIN8 +#define _WIN32_WINNT_WIN8 0x0602 +#endif + +#ifndef LOAD_LIBRARY_SEARCH_SYSTEM32 +#define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800 +#endif + +/* Sets an error message based on an HRESULT */ +int WIN_SetErrorFromHRESULT(const char *prefix, HRESULT hr) +{ + TCHAR buffer[1024]; + char *message; + TCHAR *p = buffer; + DWORD c = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, hr, 0, + buffer, SDL_arraysize(buffer), NULL); + buffer[c] = 0; + /* kill CR/LF that FormatMessage() sticks at the end */ + while (*p) { + if (*p == '\r') { + *p = 0; + break; + } + ++p; + } + message = WIN_StringToUTF8(buffer); + SDL_SetError("%s%s%s", prefix ? prefix : "", prefix ? ": " : "", message); + SDL_free(message); + return -1; +} + +/* Sets an error message based on GetLastError() */ +int WIN_SetError(const char *prefix) +{ + return WIN_SetErrorFromHRESULT(prefix, GetLastError()); +} + +HRESULT +WIN_CoInitialize(void) +{ + /* SDL handles any threading model, so initialize with the default, which + is compatible with OLE and if that doesn't work, try multi-threaded mode. + + If you need multi-threaded mode, call CoInitializeEx() before SDL_Init() + */ +#ifdef __WINRT__ + /* DLudwig: On WinRT, it is assumed that COM was initialized in main(). + CoInitializeEx is available (not CoInitialize though), however + on WinRT, main() is typically declared with the [MTAThread] + attribute, which, AFAIK, should initialize COM. + */ + return S_OK; +#elif defined(__XBOXONE__) || defined(__XBOXSERIES__) + /* On Xbox, there's no need to call CoInitializeEx (and it's not implemented) */ + return S_OK; +#else + HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + if (hr == RPC_E_CHANGED_MODE) { + hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); + } + + /* S_FALSE means success, but someone else already initialized. */ + /* You still need to call CoUninitialize in this case! */ + if (hr == S_FALSE) { + return S_OK; + } + + return hr; +#endif +} + +void WIN_CoUninitialize(void) +{ +#ifndef __WINRT__ + CoUninitialize(); +#endif +} + +#ifndef __WINRT__ +void *WIN_LoadComBaseFunction(const char *name) +{ + static SDL_bool s_bLoaded; + static HMODULE s_hComBase; + + if (!s_bLoaded) { + s_hComBase = LoadLibraryEx(TEXT("combase.dll"), NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); + s_bLoaded = SDL_TRUE; + } + if (s_hComBase) { + return GetProcAddress(s_hComBase, name); + } else { + return NULL; + } +} +#endif + +HRESULT +WIN_RoInitialize(void) +{ +#ifdef __WINRT__ + return S_OK; +#else + typedef HRESULT(WINAPI * RoInitialize_t)(RO_INIT_TYPE initType); + RoInitialize_t RoInitializeFunc = (RoInitialize_t)WIN_LoadComBaseFunction("RoInitialize"); + if (RoInitializeFunc) { + /* RO_INIT_SINGLETHREADED is equivalent to COINIT_APARTMENTTHREADED */ + HRESULT hr = RoInitializeFunc(RO_INIT_SINGLETHREADED); + if (hr == RPC_E_CHANGED_MODE) { + hr = RoInitializeFunc(RO_INIT_MULTITHREADED); + } + + /* S_FALSE means success, but someone else already initialized. */ + /* You still need to call RoUninitialize in this case! */ + if (hr == S_FALSE) { + return S_OK; + } + + return hr; + } else { + return E_NOINTERFACE; + } +#endif +} + +void WIN_RoUninitialize(void) +{ +#ifndef __WINRT__ + typedef void(WINAPI * RoUninitialize_t)(void); + RoUninitialize_t RoUninitializeFunc = (RoUninitialize_t)WIN_LoadComBaseFunction("RoUninitialize"); + if (RoUninitializeFunc) { + RoUninitializeFunc(); + } +#endif +} + +#if !defined(__WINRT__) && !defined(__XBOXONE__) && !defined(__XBOXSERIES__) +static BOOL IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor) +{ + OSVERSIONINFOEXW osvi; + DWORDLONG const dwlConditionMask = VerSetConditionMask( + VerSetConditionMask( + VerSetConditionMask( + 0, VER_MAJORVERSION, VER_GREATER_EQUAL), + VER_MINORVERSION, VER_GREATER_EQUAL), + VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); + + SDL_zero(osvi); + osvi.dwOSVersionInfoSize = sizeof(osvi); + osvi.dwMajorVersion = wMajorVersion; + osvi.dwMinorVersion = wMinorVersion; + osvi.wServicePackMajor = wServicePackMajor; + + return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE; +} +#endif + +BOOL WIN_IsWindowsVistaOrGreater(void) +{ +#if defined(__WINRT__) || defined(__XBOXONE__) || defined(__XBOXSERIES__) + return TRUE; +#else + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 0); +#endif +} + +BOOL WIN_IsWindows7OrGreater(void) +{ +#if defined(__WINRT__) || defined(__XBOXONE__) || defined(__XBOXSERIES__) + return TRUE; +#else + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), LOBYTE(_WIN32_WINNT_WIN7), 0); +#endif +} + +BOOL WIN_IsWindows8OrGreater(void) +{ +#if defined(__WINRT__) || defined(__XBOXONE__) || defined(__XBOXSERIES__) + return TRUE; +#else + return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN8), LOBYTE(_WIN32_WINNT_WIN8), 0); +#endif +} + +/* +WAVExxxCAPS gives you 31 bytes for the device name, and just truncates if it's +longer. However, since WinXP, you can use the WAVExxxCAPS2 structure, which +will give you a name GUID. The full name is in the Windows Registry under +that GUID, located here: HKLM\System\CurrentControlSet\Control\MediaCategories + +Note that drivers can report GUID_NULL for the name GUID, in which case, +Windows makes a best effort to fill in those 31 bytes in the usual place. +This info summarized from MSDN: + +http://web.archive.org/web/20131027093034/http://msdn.microsoft.com/en-us/library/windows/hardware/ff536382(v=vs.85).aspx + +Always look this up in the registry if possible, because the strings are +different! At least on Win10, I see "Yeti Stereo Microphone" in the +Registry, and a unhelpful "Microphone(Yeti Stereo Microph" in winmm. Sigh. + +(Also, DirectSound shouldn't be limited to 32 chars, but its device enum +has the same problem.) + +WASAPI doesn't need this. This is just for DirectSound/WinMM. +*/ +char *WIN_LookupAudioDeviceName(const WCHAR *name, const GUID *guid) +{ +#if defined(__WINRT__) || defined(__XBOXONE__) || defined(__XBOXSERIES__) + return WIN_StringToUTF8(name); /* No registry access on WinRT/UWP and Xbox, go with what we've got. */ +#else + static const GUID nullguid = { 0 }; + const unsigned char *ptr; + char keystr[128]; + WCHAR *strw = NULL; + SDL_bool rc; + HKEY hkey; + DWORD len = 0; + char *retval = NULL; + + if (WIN_IsEqualGUID(guid, &nullguid)) { + return WIN_StringToUTF8(name); /* No GUID, go with what we've got. */ + } + + ptr = (const unsigned char *)guid; + (void)SDL_snprintf(keystr, sizeof(keystr), + "System\\CurrentControlSet\\Control\\MediaCategories\\{%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X}", + ptr[3], ptr[2], ptr[1], ptr[0], ptr[5], ptr[4], ptr[7], ptr[6], + ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13], ptr[14], ptr[15]); + + strw = WIN_UTF8ToString(keystr); + rc = (RegOpenKeyExW(HKEY_LOCAL_MACHINE, strw, 0, KEY_QUERY_VALUE, &hkey) == ERROR_SUCCESS); + SDL_free(strw); + if (!rc) { + return WIN_StringToUTF8(name); /* oh well. */ + } + + rc = (RegQueryValueExW(hkey, L"Name", NULL, NULL, NULL, &len) == ERROR_SUCCESS); + if (!rc) { + RegCloseKey(hkey); + return WIN_StringToUTF8(name); /* oh well. */ + } + + strw = (WCHAR *)SDL_malloc(len + sizeof(WCHAR)); + if (!strw) { + RegCloseKey(hkey); + return WIN_StringToUTF8(name); /* oh well. */ + } + + rc = (RegQueryValueExW(hkey, L"Name", NULL, NULL, (LPBYTE)strw, &len) == ERROR_SUCCESS); + RegCloseKey(hkey); + if (!rc) { + SDL_free(strw); + return WIN_StringToUTF8(name); /* oh well. */ + } + + strw[len / 2] = 0; /* make sure it's null-terminated. */ + + retval = WIN_StringToUTF8(strw); + SDL_free(strw); + return retval ? retval : WIN_StringToUTF8(name); +#endif /* if __WINRT__ / else */ +} + +BOOL WIN_IsEqualGUID(const GUID *a, const GUID *b) +{ + return SDL_memcmp(a, b, sizeof(*a)) == 0; +} + +BOOL WIN_IsEqualIID(REFIID a, REFIID b) +{ + return SDL_memcmp(a, b, sizeof(*a)) == 0; +} + +void WIN_RECTToRect(const RECT *winrect, SDL_Rect *sdlrect) +{ + sdlrect->x = winrect->left; + sdlrect->w = (winrect->right - winrect->left) + 1; + sdlrect->y = winrect->top; + sdlrect->h = (winrect->bottom - winrect->top) + 1; +} + +void WIN_RectToRECT(const SDL_Rect *sdlrect, RECT *winrect) +{ + winrect->left = sdlrect->x; + winrect->right = sdlrect->x + sdlrect->w - 1; + winrect->top = sdlrect->y; + winrect->bottom = sdlrect->y + sdlrect->h - 1; +} + +BOOL WIN_IsRectEmpty(const RECT *rect) +{ + /* Calculating this manually because UWP and Xbox do not support Win32 IsRectEmpty. */ + return (rect->right <= rect->left) || (rect->bottom <= rect->top); +} +#endif /* defined(__WIN32__) || defined(__WINRT__) || defined(__GDK__) */ + +/* + * Public APIs + */ +#if !defined(SDL_VIDEO_DRIVER_WINDOWS) + +#if defined(__WIN32__) || defined(__GDK__) +int SDL_RegisterApp(const char *name, Uint32 style, void *hInst) +{ + (void)name; + (void)style; + (void)hInst; + return 0; +} + +void SDL_UnregisterApp(void) +{ +} + +void SDL_SetWindowsMessageHook(SDL_WindowsMessageHook callback, void *userdata) +{ +} +#endif /* __WIN32__ || __GDK__ */ + +#if defined(__WIN32__) || defined(__WINGDK__) +int SDL_Direct3D9GetAdapterIndex(int displayIndex) +{ + (void)displayIndex; + return 0; /* D3DADAPTER_DEFAULT */ +} + +SDL_bool SDL_DXGIGetOutputInfo(int displayIndex, int *adapterIndex, int *outputIndex) +{ + (void)displayIndex; + if (adapterIndex) { + *adapterIndex = -1; + } + if (outputIndex) { + *outputIndex = -1; + } + return SDL_FALSE; +} +#endif /* __WIN32__ || __WINGDK__ */ + +#endif /* !SDL_VIDEO_DRIVER_WINDOWS */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/core/windows/SDL_windows.h b/SDL2-2.30.5/src/core/windows/SDL_windows.h new file mode 100644 index 0000000..2bd6257 --- /dev/null +++ b/SDL2-2.30.5/src/core/windows/SDL_windows.h @@ -0,0 +1,169 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +/* This is an include file for windows.h with the SDL build settings */ + +#ifndef _INCLUDED_WINDOWS_H +#define _INCLUDED_WINDOWS_H + +#if defined(__WIN32__) +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN 1 +#endif +#ifndef STRICT +#define STRICT 1 +#endif +#ifndef UNICODE +#define UNICODE 1 +#endif +#undef WINVER +#undef _WIN32_WINNT +#if SDL_VIDEO_RENDER_D3D12 +#define _WIN32_WINNT 0xA00 /* For D3D12, 0xA00 is required */ +#elif defined(HAVE_SHELLSCALINGAPI_H) +#define _WIN32_WINNT 0x603 /* For DPI support */ +#else +#define _WIN32_WINNT 0x501 /* Need 0x410 for AlphaBlend() and 0x500 for EnumDisplayDevices(), 0x501 for raw input */ +#endif +#define WINVER _WIN32_WINNT + +#elif defined(__WINGDK__) +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN 1 +#endif +#ifndef STRICT +#define STRICT 1 +#endif +#ifndef UNICODE +#define UNICODE 1 +#endif +#undef WINVER +#undef _WIN32_WINNT +#define _WIN32_WINNT 0xA00 +#define WINVER _WIN32_WINNT + +#elif defined(__XBOXONE__) || defined(__XBOXSERIES__) +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN 1 +#endif +#ifndef STRICT +#define STRICT 1 +#endif +#ifndef UNICODE +#define UNICODE 1 +#endif +#undef WINVER +#undef _WIN32_WINNT +#define _WIN32_WINNT 0xA00 +#define WINVER _WIN32_WINNT +#endif + +/* See https://github.com/libsdl-org/SDL/pull/7607 */ +/* force_align_arg_pointer attribute requires gcc >= 4.2.x. */ +#if defined(__clang__) +#define HAVE_FORCE_ALIGN_ARG_POINTER +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2)) +#define HAVE_FORCE_ALIGN_ARG_POINTER +#endif +#if defined(__GNUC__) && defined(__i386__) && defined(HAVE_FORCE_ALIGN_ARG_POINTER) +#define MINGW32_FORCEALIGN __attribute__((force_align_arg_pointer)) +#else +#define MINGW32_FORCEALIGN +#endif + +#include +#include /* for REFIID with broken mingw.org headers */ + +#include "SDL_rect.h" + +/* Routines to convert from UTF8 to native Windows text */ +#define WIN_StringToUTF8W(S) SDL_iconv_string("UTF-8", "UTF-16LE", (const char *)(S), (SDL_wcslen(S) + 1) * sizeof(WCHAR)) +#define WIN_UTF8ToStringW(S) (WCHAR *)SDL_iconv_string("UTF-16LE", "UTF-8", (const char *)(S), SDL_strlen(S) + 1) +/* !!! FIXME: UTF8ToString() can just be a SDL_strdup() here. */ +#define WIN_StringToUTF8A(S) SDL_iconv_string("UTF-8", "ASCII", (const char *)(S), (SDL_strlen(S) + 1)) +#define WIN_UTF8ToStringA(S) SDL_iconv_string("ASCII", "UTF-8", (const char *)(S), SDL_strlen(S) + 1) +#if UNICODE +#define WIN_StringToUTF8 WIN_StringToUTF8W +#define WIN_UTF8ToString WIN_UTF8ToStringW +#define SDL_tcslen SDL_wcslen +#define SDL_tcsstr SDL_wcsstr +#else +#define WIN_StringToUTF8 WIN_StringToUTF8A +#define WIN_UTF8ToString WIN_UTF8ToStringA +#define SDL_tcslen SDL_strlen +#define SDL_tcsstr SDL_strstr +#endif + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Sets an error message based on a given HRESULT */ +extern int WIN_SetErrorFromHRESULT(const char *prefix, HRESULT hr); + +/* Sets an error message based on GetLastError(). Always return -1. */ +extern int WIN_SetError(const char *prefix); + +#if !defined(__WINRT__) +/* Load a function from combase.dll */ +void *WIN_LoadComBaseFunction(const char *name); +#endif + +/* Wrap up the oddities of CoInitialize() into a common function. */ +extern HRESULT WIN_CoInitialize(void); +extern void WIN_CoUninitialize(void); + +/* Wrap up the oddities of RoInitialize() into a common function. */ +extern HRESULT WIN_RoInitialize(void); +extern void WIN_RoUninitialize(void); + +/* Returns SDL_TRUE if we're running on Windows Vista and newer */ +extern BOOL WIN_IsWindowsVistaOrGreater(void); + +/* Returns SDL_TRUE if we're running on Windows 7 and newer */ +extern BOOL WIN_IsWindows7OrGreater(void); + +/* Returns SDL_TRUE if we're running on Windows 8 and newer */ +extern BOOL WIN_IsWindows8OrGreater(void); + +/* You need to SDL_free() the result of this call. */ +extern char *WIN_LookupAudioDeviceName(const WCHAR *name, const GUID *guid); + +/* Checks to see if two GUID are the same. */ +extern BOOL WIN_IsEqualGUID(const GUID *a, const GUID *b); +extern BOOL WIN_IsEqualIID(REFIID a, REFIID b); + +/* Convert between SDL_rect and RECT */ +extern void WIN_RECTToRect(const RECT *winrect, SDL_Rect *sdlrect); +extern void WIN_RectToRECT(const SDL_Rect *sdlrect, RECT *winrect); + +/* Returns SDL_TRUE if the rect is empty */ +extern BOOL WIN_IsRectEmpty(const RECT *rect); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif + +#endif /* _INCLUDED_WINDOWS_H */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/core/windows/SDL_xinput.c b/SDL2-2.30.5/src/core/windows/SDL_xinput.c similarity index 66% rename from SDL2-2.0.12/src/core/windows/SDL_xinput.c rename to SDL2-2.30.5/src/core/windows/SDL_xinput.c index 06d54aa..053473e 100644 --- a/SDL2-2.0.12/src/core/windows/SDL_xinput.c +++ b/SDL2-2.30.5/src/core/windows/SDL_xinput.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,26 +20,26 @@ */ #include "../../SDL_internal.h" -#include "SDL_assert.h" #include "SDL_xinput.h" - -#ifdef HAVE_XINPUT_H +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif XInputGetState_t SDL_XInputGetState = NULL; XInputSetState_t SDL_XInputSetState = NULL; XInputGetCapabilities_t SDL_XInputGetCapabilities = NULL; +XInputGetCapabilitiesEx_t SDL_XInputGetCapabilitiesEx = NULL; XInputGetBatteryInformation_t SDL_XInputGetBatteryInformation = NULL; DWORD SDL_XInputVersion = 0; -static HANDLE s_pXInputDLL = 0; +static HMODULE s_pXInputDLL = NULL; static int s_XInputDLLRefCount = 0; +#if defined(__WINRT__) || defined(__XBOXONE__) || defined(__XBOXSERIES__) -#ifdef __WINRT__ - -int -WIN_LoadXInputDLL(void) +int WIN_LoadXInputDLL(void) { /* Getting handles to system dlls (via LoadLibrary and its variants) is not * supported on WinRT, thus, pointers to XInput's functions can't be @@ -64,36 +64,38 @@ WIN_LoadXInputDLL(void) return 0; } -void -WIN_UnloadXInputDLL(void) +void WIN_UnloadXInputDLL(void) { } -#else /* !__WINRT__ */ +#else /* !(defined(__WINRT__) || defined(__XBOXONE__) || defined(__XBOXSERIES__)) */ -int -WIN_LoadXInputDLL(void) +int WIN_LoadXInputDLL(void) { DWORD version = 0; if (s_pXInputDLL) { SDL_assert(s_XInputDLLRefCount > 0); s_XInputDLLRefCount++; - return 0; /* already loaded */ + return 0; /* already loaded */ } + /* NOTE: Don't load XinputUap.dll + * This is XInput emulation over Windows.Gaming.Input, and has all the + * limitations of that API (no devices at startup, no background input, etc.) + */ version = (1 << 16) | 4; - s_pXInputDLL = LoadLibrary(L"XInput1_4.dll"); /* 1.4 Ships with Windows 8. */ + s_pXInputDLL = LoadLibrary(TEXT("XInput1_4.dll")); /* 1.4 Ships with Windows 8. */ if (!s_pXInputDLL) { version = (1 << 16) | 3; - s_pXInputDLL = LoadLibrary(L"XInput1_3.dll"); /* 1.3 can be installed as a redistributable component. */ + s_pXInputDLL = LoadLibrary(TEXT("XInput1_3.dll")); /* 1.3 can be installed as a redistributable component. */ } if (!s_pXInputDLL) { - s_pXInputDLL = LoadLibrary(L"bin\\XInput1_3.dll"); + s_pXInputDLL = LoadLibrary(TEXT("bin\\XInput1_3.dll")); } if (!s_pXInputDLL) { /* "9.1.0" Ships with Vista and Win7, and is more limited than 1.3+ (e.g. XInputGetStateEx is not available.) */ - s_pXInputDLL = LoadLibrary(L"XInput9_1_0.dll"); + s_pXInputDLL = LoadLibrary(TEXT("XInput9_1_0.dll")); } if (!s_pXInputDLL) { return -1; @@ -104,13 +106,15 @@ WIN_LoadXInputDLL(void) s_XInputDLLRefCount = 1; /* 100 is the ordinal for _XInputGetStateEx, which returns the same struct as XinputGetState, but with extra data in wButtons for the guide button, we think... */ - SDL_XInputGetState = (XInputGetState_t)GetProcAddress((HMODULE)s_pXInputDLL, (LPCSTR)100); + SDL_XInputGetState = (XInputGetState_t)GetProcAddress(s_pXInputDLL, (LPCSTR)100); if (!SDL_XInputGetState) { - SDL_XInputGetState = (XInputGetState_t)GetProcAddress((HMODULE)s_pXInputDLL, "XInputGetState"); + SDL_XInputGetState = (XInputGetState_t)GetProcAddress(s_pXInputDLL, "XInputGetState"); } - SDL_XInputSetState = (XInputSetState_t)GetProcAddress((HMODULE)s_pXInputDLL, "XInputSetState"); - SDL_XInputGetCapabilities = (XInputGetCapabilities_t)GetProcAddress((HMODULE)s_pXInputDLL, "XInputGetCapabilities"); - SDL_XInputGetBatteryInformation = (XInputGetBatteryInformation_t)GetProcAddress( (HMODULE)s_pXInputDLL, "XInputGetBatteryInformation" ); + SDL_XInputSetState = (XInputSetState_t)GetProcAddress(s_pXInputDLL, "XInputSetState"); + SDL_XInputGetCapabilities = (XInputGetCapabilities_t)GetProcAddress(s_pXInputDLL, "XInputGetCapabilities"); + /* 108 is the ordinal for _XInputGetCapabilitiesEx, which additionally returns VID/PID of the controller. */ + SDL_XInputGetCapabilitiesEx = (XInputGetCapabilitiesEx_t)GetProcAddress(s_pXInputDLL, (LPCSTR)108); + SDL_XInputGetBatteryInformation = (XInputGetBatteryInformation_t)GetProcAddress(s_pXInputDLL, "XInputGetBatteryInformation"); if (!SDL_XInputGetState || !SDL_XInputSetState || !SDL_XInputGetCapabilities) { WIN_UnloadXInputDLL(); return -1; @@ -119,8 +123,7 @@ WIN_LoadXInputDLL(void) return 0; } -void -WIN_UnloadXInputDLL(void) +void WIN_UnloadXInputDLL(void) { if (s_pXInputDLL) { SDL_assert(s_XInputDLLRefCount > 0); @@ -134,6 +137,10 @@ WIN_UnloadXInputDLL(void) } #endif /* __WINRT__ */ -#endif /* HAVE_XINPUT_H */ + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/core/windows/SDL_xinput.h b/SDL2-2.30.5/src/core/windows/SDL_xinput.h new file mode 100644 index 0000000..efdb862 --- /dev/null +++ b/SDL2-2.30.5/src/core/windows/SDL_xinput.h @@ -0,0 +1,278 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifndef SDL_xinput_h_ +#define SDL_xinput_h_ + +#include "SDL_windows.h" + +#ifdef HAVE_XINPUT_H +#if defined(__XBOXONE__) || defined(__XBOXSERIES__) +/* Xbox supports an XInput wrapper which is a C++-only header... */ +#include /* Required to compile with recent MSVC... */ +#include +using namespace XInputOnGameInput; +#else +#include +#endif +#endif /* HAVE_XINPUT_H */ + +#ifndef XUSER_MAX_COUNT +#define XUSER_MAX_COUNT 4 +#endif +#ifndef XUSER_INDEX_ANY +#define XUSER_INDEX_ANY 0x000000FF +#endif +#ifndef XINPUT_CAPS_FFB_SUPPORTED +#define XINPUT_CAPS_FFB_SUPPORTED 0x0001 +#endif +#ifndef XINPUT_CAPS_WIRELESS +#define XINPUT_CAPS_WIRELESS 0x0002 +#endif + +#ifndef XINPUT_DEVSUBTYPE_UNKNOWN +#define XINPUT_DEVSUBTYPE_UNKNOWN 0x00 +#endif +#ifndef XINPUT_DEVSUBTYPE_GAMEPAD +#define XINPUT_DEVSUBTYPE_GAMEPAD 0x01 +#endif +#ifndef XINPUT_DEVSUBTYPE_WHEEL +#define XINPUT_DEVSUBTYPE_WHEEL 0x02 +#endif +#ifndef XINPUT_DEVSUBTYPE_ARCADE_STICK +#define XINPUT_DEVSUBTYPE_ARCADE_STICK 0x03 +#endif +#ifndef XINPUT_DEVSUBTYPE_FLIGHT_STICK +#define XINPUT_DEVSUBTYPE_FLIGHT_STICK 0x04 +#endif +#ifndef XINPUT_DEVSUBTYPE_DANCE_PAD +#define XINPUT_DEVSUBTYPE_DANCE_PAD 0x05 +#endif +#ifndef XINPUT_DEVSUBTYPE_GUITAR +#define XINPUT_DEVSUBTYPE_GUITAR 0x06 +#endif +#ifndef XINPUT_DEVSUBTYPE_GUITAR_ALTERNATE +#define XINPUT_DEVSUBTYPE_GUITAR_ALTERNATE 0x07 +#endif +#ifndef XINPUT_DEVSUBTYPE_DRUM_KIT +#define XINPUT_DEVSUBTYPE_DRUM_KIT 0x08 +#endif +#ifndef XINPUT_DEVSUBTYPE_GUITAR_BASS +#define XINPUT_DEVSUBTYPE_GUITAR_BASS 0x0B +#endif +#ifndef XINPUT_DEVSUBTYPE_ARCADE_PAD +#define XINPUT_DEVSUBTYPE_ARCADE_PAD 0x13 +#endif + +#ifndef XINPUT_FLAG_GAMEPAD +#define XINPUT_FLAG_GAMEPAD 0x01 +#endif + +#ifndef XINPUT_GAMEPAD_DPAD_UP +#define XINPUT_GAMEPAD_DPAD_UP 0x0001 +#endif +#ifndef XINPUT_GAMEPAD_DPAD_DOWN +#define XINPUT_GAMEPAD_DPAD_DOWN 0x0002 +#endif +#ifndef XINPUT_GAMEPAD_DPAD_LEFT +#define XINPUT_GAMEPAD_DPAD_LEFT 0x0004 +#endif +#ifndef XINPUT_GAMEPAD_DPAD_RIGHT +#define XINPUT_GAMEPAD_DPAD_RIGHT 0x0008 +#endif +#ifndef XINPUT_GAMEPAD_START +#define XINPUT_GAMEPAD_START 0x0010 +#endif +#ifndef XINPUT_GAMEPAD_BACK +#define XINPUT_GAMEPAD_BACK 0x0020 +#endif +#ifndef XINPUT_GAMEPAD_LEFT_THUMB +#define XINPUT_GAMEPAD_LEFT_THUMB 0x0040 +#endif +#ifndef XINPUT_GAMEPAD_RIGHT_THUMB +#define XINPUT_GAMEPAD_RIGHT_THUMB 0x0080 +#endif +#ifndef XINPUT_GAMEPAD_LEFT_SHOULDER +#define XINPUT_GAMEPAD_LEFT_SHOULDER 0x0100 +#endif +#ifndef XINPUT_GAMEPAD_RIGHT_SHOULDER +#define XINPUT_GAMEPAD_RIGHT_SHOULDER 0x0200 +#endif +#ifndef XINPUT_GAMEPAD_A +#define XINPUT_GAMEPAD_A 0x1000 +#endif +#ifndef XINPUT_GAMEPAD_B +#define XINPUT_GAMEPAD_B 0x2000 +#endif +#ifndef XINPUT_GAMEPAD_X +#define XINPUT_GAMEPAD_X 0x4000 +#endif +#ifndef XINPUT_GAMEPAD_Y +#define XINPUT_GAMEPAD_Y 0x8000 +#endif + +#ifndef XINPUT_GAMEPAD_GUIDE +#define XINPUT_GAMEPAD_GUIDE 0x0400 +#endif + +#ifndef BATTERY_DEVTYPE_GAMEPAD +#define BATTERY_DEVTYPE_GAMEPAD 0x00 +#endif + +#ifndef BATTERY_TYPE_DISCONNECTED +#define BATTERY_TYPE_DISCONNECTED 0x00 +#endif +#ifndef BATTERY_TYPE_WIRED +#define BATTERY_TYPE_WIRED 0x01 +#endif +#ifndef BATTERY_TYPE_UNKNOWN +#define BATTERY_TYPE_UNKNOWN 0xFF +#endif +#ifndef BATTERY_LEVEL_EMPTY +#define BATTERY_LEVEL_EMPTY 0x00 +#endif +#ifndef BATTERY_LEVEL_LOW +#define BATTERY_LEVEL_LOW 0x01 +#endif +#ifndef BATTERY_LEVEL_MEDIUM +#define BATTERY_LEVEL_MEDIUM 0x02 +#endif +#ifndef BATTERY_LEVEL_FULL +#define BATTERY_LEVEL_FULL 0x03 +#endif + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* typedef's for XInput structs we use */ + + +/* This is the same as XINPUT_BATTERY_INFORMATION, but always defined instead of just if WIN32_WINNT >= _WIN32_WINNT_WIN8 */ +typedef struct +{ + BYTE BatteryType; + BYTE BatteryLevel; +} XINPUT_BATTERY_INFORMATION_EX; + +#ifndef HAVE_XINPUT_H + +typedef struct +{ + WORD wButtons; + BYTE bLeftTrigger; + BYTE bRightTrigger; + SHORT sThumbLX; + SHORT sThumbLY; + SHORT sThumbRX; + SHORT sThumbRY; +} XINPUT_GAMEPAD; + +typedef struct +{ + DWORD dwPacketNumber; + XINPUT_GAMEPAD Gamepad; +} XINPUT_STATE; + +typedef struct +{ + WORD wLeftMotorSpeed; + WORD wRightMotorSpeed; +} XINPUT_VIBRATION; + +typedef struct +{ + BYTE Type; + BYTE SubType; + WORD Flags; + XINPUT_GAMEPAD Gamepad; + XINPUT_VIBRATION Vibration; +} XINPUT_CAPABILITIES; + +#endif /* HAVE_XINPUT_H */ + +/* This struct is not defined in XInput headers. */ +typedef struct +{ + XINPUT_CAPABILITIES Capabilities; + WORD VendorId; + WORD ProductId; + WORD ProductVersion; + WORD unk1; + DWORD unk2; +} SDL_XINPUT_CAPABILITIES_EX; + +/* Forward decl's for XInput API's we load dynamically and use if available */ +typedef DWORD(WINAPI *XInputGetState_t)( + DWORD dwUserIndex, /* [in] Index of the gamer associated with the device */ + XINPUT_STATE *pState /* [out] Receives the current state */ +); + +typedef DWORD(WINAPI *XInputSetState_t)( + DWORD dwUserIndex, /* [in] Index of the gamer associated with the device */ + XINPUT_VIBRATION *pVibration /* [in, out] The vibration information to send to the controller */ +); + +typedef DWORD(WINAPI *XInputGetCapabilities_t)( + DWORD dwUserIndex, /* [in] Index of the gamer associated with the device */ + DWORD dwFlags, /* [in] Input flags that identify the device type */ + XINPUT_CAPABILITIES *pCapabilities /* [out] Receives the capabilities */ +); + +/* Only available in XInput 1.4 that is shipped with Windows 8 and newer. */ +typedef DWORD(WINAPI *XInputGetCapabilitiesEx_t)( + DWORD dwReserved, /* [in] Must be 1 */ + DWORD dwUserIndex, /* [in] Index of the gamer associated with the device */ + DWORD dwFlags, /* [in] Input flags that identify the device type */ + SDL_XINPUT_CAPABILITIES_EX *pCapabilitiesEx /* [out] Receives the capabilities */ +); + +typedef DWORD(WINAPI *XInputGetBatteryInformation_t)( + DWORD dwUserIndex, + BYTE devType, + XINPUT_BATTERY_INFORMATION_EX *pBatteryInformation); + +extern int WIN_LoadXInputDLL(void); +extern void WIN_UnloadXInputDLL(void); + +extern XInputGetState_t SDL_XInputGetState; +extern XInputSetState_t SDL_XInputSetState; +extern XInputGetCapabilities_t SDL_XInputGetCapabilities; +extern XInputGetCapabilitiesEx_t SDL_XInputGetCapabilitiesEx; +extern XInputGetBatteryInformation_t SDL_XInputGetBatteryInformation; +extern DWORD SDL_XInputVersion; /* ((major << 16) & 0xFF00) | (minor & 0xFF) */ + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif + +#define XINPUTGETSTATE SDL_XInputGetState +#define XINPUTSETSTATE SDL_XInputSetState +#define XINPUTGETCAPABILITIES SDL_XInputGetCapabilities +#define XINPUTGETCAPABILITIESEX SDL_XInputGetCapabilitiesEx +#define XINPUTGETBATTERYINFORMATION SDL_XInputGetBatteryInformation + +#endif /* SDL_xinput_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/core/winrt/SDL_winrtapp_common.cpp b/SDL2-2.30.5/src/core/winrt/SDL_winrtapp_common.cpp similarity index 73% rename from SDL2-2.0.12/src/core/winrt/SDL_winrtapp_common.cpp rename to SDL2-2.30.5/src/core/winrt/SDL_winrtapp_common.cpp index fdbeff4..9d16492 100644 --- a/SDL2-2.0.12/src/core/winrt/SDL_winrtapp_common.cpp +++ b/SDL2-2.30.5/src/core/winrt/SDL_winrtapp_common.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -30,7 +30,7 @@ int (*WINRT_SDLAppEntryPoint)(int, char **) = NULL; extern "C" DECLSPEC int -SDL_WinRTRunApp(SDL_main_func mainFunction, void * xamlBackgroundPanel) +SDL_WinRTRunApp(SDL_main_func mainFunction, void *xamlBackgroundPanel) { if (xamlBackgroundPanel) { return SDL_WinRTInitXAMLApp(mainFunction, xamlBackgroundPanel); @@ -42,23 +42,17 @@ SDL_WinRTRunApp(SDL_main_func mainFunction, void * xamlBackgroundPanel) } } - extern "C" DECLSPEC SDL_WinRT_DeviceFamily SDL_WinRTGetDeviceFamily() { -#if NTDDI_VERSION >= NTDDI_WIN10 /* !!! FIXME: I have no idea if this is the right test. This is a UWP API, I think. Older windows should...just return "mobile"? I don't know. --ryan. */ - Platform::String^ deviceFamily = Windows::System::Profile::AnalyticsInfo::VersionInfo->DeviceFamily; +#if NTDDI_VERSION >= NTDDI_WIN10 /* !!! FIXME: I have no idea if this is the right test. This is a UWP API, I think. Older windows should...just return "mobile"? I don't know. --ryan. */ + Platform::String ^ deviceFamily = Windows::System::Profile::AnalyticsInfo::VersionInfo->DeviceFamily; - if (deviceFamily->Equals("Windows.Desktop")) - { + if (deviceFamily->Equals("Windows.Desktop")) { return SDL_WINRT_DEVICEFAMILY_DESKTOP; - } - else if (deviceFamily->Equals("Windows.Mobile")) - { + } else if (deviceFamily->Equals("Windows.Mobile")) { return SDL_WINRT_DEVICEFAMILY_MOBILE; - } - else if (deviceFamily->Equals("Windows.Xbox")) - { + } else if (deviceFamily->Equals("Windows.Xbox")) { return SDL_WINRT_DEVICEFAMILY_XBOX; } #endif diff --git a/SDL2-2.0.12/src/core/winrt/SDL_winrtapp_common.h b/SDL2-2.30.5/src/core/winrt/SDL_winrtapp_common.h similarity index 95% rename from SDL2-2.0.12/src/core/winrt/SDL_winrtapp_common.h rename to SDL2-2.30.5/src/core/winrt/SDL_winrtapp_common.h index 373f210..fdc8294 100644 --- a/SDL2-2.0.12/src/core/winrt/SDL_winrtapp_common.h +++ b/SDL2-2.30.5/src/core/winrt/SDL_winrtapp_common.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/core/winrt/SDL_winrtapp_direct3d.cpp b/SDL2-2.30.5/src/core/winrt/SDL_winrtapp_direct3d.cpp similarity index 62% rename from SDL2-2.0.12/src/core/winrt/SDL_winrtapp_direct3d.cpp rename to SDL2-2.30.5/src/core/winrt/SDL_winrtapp_direct3d.cpp index a4ddc2f..0115c5d 100644 --- a/SDL2-2.0.12/src/core/winrt/SDL_winrtapp_direct3d.cpp +++ b/SDL2-2.30.5/src/core/winrt/SDL_winrtapp_direct3d.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,13 +20,6 @@ */ #include "../../SDL_internal.h" -/* Standard C++11 includes */ -#include -#include -#include -using namespace std; - - /* Windows includes */ #include "ppltasks.h" using namespace concurrency; @@ -40,22 +33,18 @@ using namespace Windows::System; using namespace Windows::UI::Core; using namespace Windows::UI::Input; -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP +#if SDL_WINAPI_FAMILY_PHONE using namespace Windows::Phone::UI::Input; #endif - /* SDL includes */ extern "C" { -#include "SDL_assert.h" #include "SDL_events.h" #include "SDL_hints.h" -#include "SDL_log.h" #include "SDL_main.h" #include "SDL_stdinc.h" #include "SDL_render.h" #include "../../video/SDL_sysvideo.h" -//#include "../../SDL_hints_c.h" #include "../../events/SDL_events_c.h" #include "../../events/SDL_keyboard_c.h" #include "../../events/SDL_mouse_c.h" @@ -69,20 +58,18 @@ extern "C" { #include "SDL_winrtapp_common.h" #include "SDL_winrtapp_direct3d.h" -#if SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED +#if SDL_VIDEO_RENDER_D3D11 /* Calling IDXGIDevice3::Trim on the active Direct3D 11.x device is necessary * when Windows 8.1 apps are about to get suspended. */ extern "C" void D3D11_Trim(SDL_Renderer *); #endif - // Compile-time debugging options: // To enable, uncomment; to disable, comment them out. -//#define LOG_POINTER_EVENTS 1 -//#define LOG_WINDOW_EVENTS 1 -//#define LOG_ORIENTATION_EVENTS 1 - +// #define LOG_POINTER_EVENTS 1 +// #define LOG_WINDOW_EVENTS 1 +// #define LOG_ORIENTATION_EVENTS 1 // HACK, DLudwig: record a reference to the global, WinRT 'app'/view. // SDL/WinRT will use this throughout its code. @@ -95,19 +82,18 @@ SDL_WinRTApp ^ SDL_WinRTGlobalApp = nullptr; ref class SDLApplicationSource sealed : Windows::ApplicationModel::Core::IFrameworkViewSource { -public: - virtual Windows::ApplicationModel::Core::IFrameworkView^ CreateView(); + public: + virtual Windows::ApplicationModel::Core::IFrameworkView ^ CreateView(); }; -IFrameworkView^ SDLApplicationSource::CreateView() +IFrameworkView ^ SDLApplicationSource::CreateView() { // TODO, WinRT: see if this function (CreateView) can ever get called // more than once. For now, just prevent it from ever assigning // SDL_WinRTGlobalApp more than once. SDL_assert(!SDL_WinRTGlobalApp); SDL_WinRTApp ^ app = ref new SDL_WinRTApp(); - if (!SDL_WinRTGlobalApp) - { + if (!SDL_WinRTGlobalApp) { SDL_WinRTGlobalApp = app; } return app; @@ -121,83 +107,20 @@ int SDL_WinRTInitNonXAMLApp(int (*mainFunction)(int, char **)) return 0; } -static void SDLCALL -WINRT_SetDisplayOrientationsPreference(void *userdata, const char *name, const char *oldValue, const char *newValue) -{ - SDL_assert(SDL_strcmp(name, SDL_HINT_ORIENTATIONS) == 0); - - /* HACK: prevent SDL from altering an app's .appxmanifest-set orientation - * from being changed on startup, by detecting when SDL_HINT_ORIENTATIONS - * is getting registered. - * - * TODO, WinRT: consider reading in an app's .appxmanifest file, and apply its orientation when 'newValue == NULL'. - */ - if ((oldValue == NULL) && (newValue == NULL)) { - return; - } - - // Start with no orientation flags, then add each in as they're parsed - // from newValue. - unsigned int orientationFlags = 0; - if (newValue) { - std::istringstream tokenizer(newValue); - while (!tokenizer.eof()) { - std::string orientationName; - std::getline(tokenizer, orientationName, ' '); - if (orientationName == "LandscapeLeft") { - orientationFlags |= (unsigned int) DisplayOrientations::LandscapeFlipped; - } else if (orientationName == "LandscapeRight") { - orientationFlags |= (unsigned int) DisplayOrientations::Landscape; - } else if (orientationName == "Portrait") { - orientationFlags |= (unsigned int) DisplayOrientations::Portrait; - } else if (orientationName == "PortraitUpsideDown") { - orientationFlags |= (unsigned int) DisplayOrientations::PortraitFlipped; - } - } - } - - // If no valid orientation flags were specified, use a reasonable set of defaults: - if (!orientationFlags) { - // TODO, WinRT: consider seeing if an app's default orientation flags can be found out via some API call(s). - orientationFlags = (unsigned int) ( \ - DisplayOrientations::Landscape | - DisplayOrientations::LandscapeFlipped | - DisplayOrientations::Portrait | - DisplayOrientations::PortraitFlipped); - } - - // Set the orientation/rotation preferences. Please note that this does - // not constitute a 100%-certain lock of a given set of possible - // orientations. According to Microsoft's documentation on WinRT [1] - // when a device is not capable of being rotated, Windows may ignore - // the orientation preferences, and stick to what the device is capable of - // displaying. - // - // [1] Documentation on the 'InitialRotationPreference' setting for a - // Windows app's manifest file describes how some orientation/rotation - // preferences may be ignored. See - // http://msdn.microsoft.com/en-us/library/windows/apps/hh700343.aspx - // for details. Microsoft's "Display orientation sample" also gives an - // outline of how Windows treats device rotation - // (http://code.msdn.microsoft.com/Display-Orientation-Sample-19a58e93). - WINRT_DISPLAY_PROPERTY(AutoRotationPreferences) = (DisplayOrientations) orientationFlags; -} - -static void -WINRT_ProcessWindowSizeChange() // TODO: Pass an SDL_Window-identifying thing into WINRT_ProcessWindowSizeChange() +static void WINRT_ProcessWindowSizeChange() // TODO: Pass an SDL_Window-identifying thing into WINRT_ProcessWindowSizeChange() { CoreWindow ^ coreWindow = CoreWindow::GetForCurrentThread(); if (coreWindow) { if (WINRT_GlobalSDLWindow) { - SDL_Window * window = WINRT_GlobalSDLWindow; - SDL_WindowData * data = (SDL_WindowData *) window->driverdata; + SDL_Window *window = WINRT_GlobalSDLWindow; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; int x = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Left); int y = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Top); int w = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Width); int h = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Height); -#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) && (NTDDI_VERSION == NTDDI_WIN8) +#if SDL_WINAPI_FAMILY_PHONE && (NTDDI_VERSION == NTDDI_WIN8) /* WinPhone 8.0 always keeps its native window size in portrait, regardless of orientation. This changes in WinPhone 8.1, in which the native window's size changes along with @@ -209,12 +132,13 @@ WINRT_ProcessWindowSizeChange() // TODO: Pass an SDL_Window-identifying thing in */ const DisplayOrientations currentOrientation = WINRT_DISPLAY_PROPERTY(CurrentOrientation); switch (currentOrientation) { - case DisplayOrientations::Landscape: - case DisplayOrientations::LandscapeFlipped: { - int tmp = w; - w = h; - h = tmp; - } break; + case DisplayOrientations::Landscape: + case DisplayOrientations::LandscapeFlipped: + { + int tmp = w; + w = h; + h = tmp; + } break; } #endif @@ -235,25 +159,24 @@ WINRT_ProcessWindowSizeChange() // TODO: Pass an SDL_Window-identifying thing in } } -SDL_WinRTApp::SDL_WinRTApp() : - m_windowClosed(false), - m_windowVisible(true) +SDL_WinRTApp::SDL_WinRTApp() : m_windowClosed(false), + m_windowVisible(true) { } -void SDL_WinRTApp::Initialize(CoreApplicationView^ applicationView) +void SDL_WinRTApp::Initialize(CoreApplicationView ^ applicationView) { applicationView->Activated += - ref new TypedEventHandler(this, &SDL_WinRTApp::OnAppActivated); + ref new TypedEventHandler(this, &SDL_WinRTApp::OnAppActivated); CoreApplication::Suspending += - ref new EventHandler(this, &SDL_WinRTApp::OnSuspending); + ref new EventHandler(this, &SDL_WinRTApp::OnSuspending); CoreApplication::Resuming += - ref new EventHandler(this, &SDL_WinRTApp::OnResuming); + ref new EventHandler(this, &SDL_WinRTApp::OnResuming); CoreApplication::Exiting += - ref new EventHandler(this, &SDL_WinRTApp::OnExiting); + ref new EventHandler(this, &SDL_WinRTApp::OnExiting); #if NTDDI_VERSION >= NTDDI_WIN10 /* HACK ALERT! Xbox One doesn't seem to detect gamepads unless something @@ -262,44 +185,43 @@ void SDL_WinRTApp::Initialize(CoreApplicationView^ applicationView) sure that gamepad detection works later on, if requested. */ Windows::Gaming::Input::Gamepad::GamepadAdded += - ref new Windows::Foundation::EventHandler( - this, &SDL_WinRTApp::OnGamepadAdded - ); + ref new Windows::Foundation::EventHandler( + this, &SDL_WinRTApp::OnGamepadAdded); #endif } #if NTDDI_VERSION > NTDDI_WIN8 -void SDL_WinRTApp::OnOrientationChanged(DisplayInformation^ sender, Object^ args) +void SDL_WinRTApp::OnOrientationChanged(DisplayInformation ^ sender, Object ^ args) #else -void SDL_WinRTApp::OnOrientationChanged(Object^ sender) +void SDL_WinRTApp::OnOrientationChanged(Object ^ sender) #endif { -#if LOG_ORIENTATION_EVENTS==1 +#if LOG_ORIENTATION_EVENTS == 1 { - CoreWindow^ window = CoreWindow::GetForCurrentThread(); + CoreWindow ^ window = CoreWindow::GetForCurrentThread(); if (window) { SDL_Log("%s, current orientation=%d, native orientation=%d, auto rot. pref=%d, CoreWindow Bounds={%f,%f,%f,%f}\n", - __FUNCTION__, - WINRT_DISPLAY_PROPERTY(CurrentOrientation), - WINRT_DISPLAY_PROPERTY(NativeOrientation), - WINRT_DISPLAY_PROPERTY(AutoRotationPreferences), - window->Bounds.X, - window->Bounds.Y, - window->Bounds.Width, - window->Bounds.Height); + __FUNCTION__, + WINRT_DISPLAY_PROPERTY(CurrentOrientation), + WINRT_DISPLAY_PROPERTY(NativeOrientation), + WINRT_DISPLAY_PROPERTY(AutoRotationPreferences), + window->Bounds.X, + window->Bounds.Y, + window->Bounds.Width, + window->Bounds.Height); } else { SDL_Log("%s, current orientation=%d, native orientation=%d, auto rot. pref=%d\n", - __FUNCTION__, - WINRT_DISPLAY_PROPERTY(CurrentOrientation), - WINRT_DISPLAY_PROPERTY(NativeOrientation), - WINRT_DISPLAY_PROPERTY(AutoRotationPreferences)); + __FUNCTION__, + WINRT_DISPLAY_PROPERTY(CurrentOrientation), + WINRT_DISPLAY_PROPERTY(NativeOrientation), + WINRT_DISPLAY_PROPERTY(AutoRotationPreferences)); } } #endif WINRT_ProcessWindowSizeChange(); -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP +#if SDL_WINAPI_FAMILY_PHONE // HACK: Make sure that orientation changes // lead to the Direct3D renderer's viewport getting updated: // @@ -309,132 +231,132 @@ void SDL_WinRTApp::OnOrientationChanged(Object^ sender) // I'm not currently sure why this is, but it seems to work fine. -- David L. // // TODO, WinRT: do more extensive research into why orientation changes on Win 8.x don't need D3D changes, or if they might, in some cases - SDL_Window * window = WINRT_GlobalSDLWindow; + SDL_Window *window = WINRT_GlobalSDLWindow; if (window) { - SDL_WindowData * data = (SDL_WindowData *)window->driverdata; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; int w = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Width); int h = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Height); SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_SIZE_CHANGED, w, h); } #endif - } -void SDL_WinRTApp::SetWindow(CoreWindow^ window) +void SDL_WinRTApp::SetWindow(CoreWindow ^ window) { -#if LOG_WINDOW_EVENTS==1 +#if LOG_WINDOW_EVENTS == 1 SDL_Log("%s, current orientation=%d, native orientation=%d, auto rot. pref=%d, window bounds={%f, %f, %f,%f}\n", - __FUNCTION__, - WINRT_DISPLAY_PROPERTY(CurrentOrientation), - WINRT_DISPLAY_PROPERTY(NativeOrientation), - WINRT_DISPLAY_PROPERTY(AutoRotationPreferences), - window->Bounds.X, - window->Bounds.Y, - window->Bounds.Width, - window->Bounds.Height); + __FUNCTION__, + WINRT_DISPLAY_PROPERTY(CurrentOrientation), + WINRT_DISPLAY_PROPERTY(NativeOrientation), + WINRT_DISPLAY_PROPERTY(AutoRotationPreferences), + window->Bounds.X, + window->Bounds.Y, + window->Bounds.Width, + window->Bounds.Height); #endif - window->SizeChanged += - ref new TypedEventHandler(this, &SDL_WinRTApp::OnWindowSizeChanged); + window->SizeChanged += + ref new TypedEventHandler(this, &SDL_WinRTApp::OnWindowSizeChanged); window->VisibilityChanged += - ref new TypedEventHandler(this, &SDL_WinRTApp::OnVisibilityChanged); + ref new TypedEventHandler(this, &SDL_WinRTApp::OnVisibilityChanged); window->Activated += - ref new TypedEventHandler(this, &SDL_WinRTApp::OnWindowActivated); + ref new TypedEventHandler(this, &SDL_WinRTApp::OnWindowActivated); - window->Closed += - ref new TypedEventHandler(this, &SDL_WinRTApp::OnWindowClosed); + window->Closed += + ref new TypedEventHandler(this, &SDL_WinRTApp::OnWindowClosed); -#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP +#if !SDL_WINAPI_FAMILY_PHONE window->PointerCursor = ref new CoreCursor(CoreCursorType::Arrow, 0); #endif window->PointerPressed += - ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerPressed); + ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerPressed); window->PointerMoved += - ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerMoved); + ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerMoved); window->PointerReleased += - ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerReleased); + ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerReleased); window->PointerEntered += - ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerEntered); + ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerEntered); window->PointerExited += - ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerExited); + ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerExited); window->PointerWheelChanged += - ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerWheelChanged); + ref new TypedEventHandler(this, &SDL_WinRTApp::OnPointerWheelChanged); -#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP +#if !SDL_WINAPI_FAMILY_PHONE // Retrieves relative-only mouse movements: Windows::Devices::Input::MouseDevice::GetForCurrentView()->MouseMoved += - ref new TypedEventHandler(this, &SDL_WinRTApp::OnMouseMoved); + ref new TypedEventHandler(this, &SDL_WinRTApp::OnMouseMoved); #endif window->KeyDown += - ref new TypedEventHandler(this, &SDL_WinRTApp::OnKeyDown); + ref new TypedEventHandler(this, &SDL_WinRTApp::OnKeyDown); window->KeyUp += - ref new TypedEventHandler(this, &SDL_WinRTApp::OnKeyUp); + ref new TypedEventHandler(this, &SDL_WinRTApp::OnKeyUp); window->CharacterReceived += - ref new TypedEventHandler(this, &SDL_WinRTApp::OnCharacterReceived); + ref new TypedEventHandler(this, &SDL_WinRTApp::OnCharacterReceived); #if NTDDI_VERSION >= NTDDI_WIN10 Windows::UI::Core::SystemNavigationManager::GetForCurrentView()->BackRequested += - ref new EventHandler(this, &SDL_WinRTApp::OnBackButtonPressed); -#elif WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP + ref new EventHandler(this, &SDL_WinRTApp::OnBackButtonPressed); +#elif SDL_WINAPI_FAMILY_PHONE HardwareButtons::BackPressed += - ref new EventHandler(this, &SDL_WinRTApp::OnBackButtonPressed); + ref new EventHandler(this, &SDL_WinRTApp::OnBackButtonPressed); #endif #if NTDDI_VERSION > NTDDI_WIN8 DisplayInformation::GetForCurrentView()->OrientationChanged += - ref new TypedEventHandler(this, &SDL_WinRTApp::OnOrientationChanged); + ref new TypedEventHandler(this, &SDL_WinRTApp::OnOrientationChanged); #else DisplayProperties::OrientationChanged += ref new DisplayPropertiesEventHandler(this, &SDL_WinRTApp::OnOrientationChanged); #endif - // Register the hint, SDL_HINT_ORIENTATIONS, with SDL. - // TODO, WinRT: see if an app's default orientation can be found out via WinRT API(s), then set the initial value of SDL_HINT_ORIENTATIONS accordingly. - SDL_AddHintCallback(SDL_HINT_ORIENTATIONS, WINRT_SetDisplayOrientationsPreference, NULL); - -#if (WINAPI_FAMILY == WINAPI_FAMILY_APP) && (NTDDI_VERSION < NTDDI_WIN10) // for Windows 8/8.1/RT apps... (and not Phone apps) +#if (WINAPI_FAMILY == WINAPI_FAMILY_APP) && (NTDDI_VERSION < NTDDI_WIN10) // for Windows 8/8.1/RT apps... (and not Phone apps) // Make sure we know when a user has opened the app's settings pane. // This is needed in order to display a privacy policy, which needs // to be done for network-enabled apps, as per Windows Store requirements. using namespace Windows::UI::ApplicationSettings; SettingsPane::GetForCurrentView()->CommandsRequested += - ref new TypedEventHandler - (this, &SDL_WinRTApp::OnSettingsPaneCommandsRequested); + ref new TypedEventHandler(this, &SDL_WinRTApp::OnSettingsPaneCommandsRequested); #endif } -void SDL_WinRTApp::Load(Platform::String^ entryPoint) +void SDL_WinRTApp::Load(Platform::String ^ entryPoint) { } void SDL_WinRTApp::Run() { SDL_SetMainReady(); - if (WINRT_SDLAppEntryPoint) - { + if (WINRT_SDLAppEntryPoint) { // TODO, WinRT: pass the C-style main() a reasonably realistic // representation of command line arguments. - int argc = 0; - char **argv = NULL; + int argc = 1; + char **argv = (char **)SDL_malloc(2 * sizeof(*argv)); + if (!argv) { + return; + } + argv[0] = SDL_strdup("WinRTApp"); + argv[1] = NULL; WINRT_SDLAppEntryPoint(argc, argv); + SDL_free(argv[0]); + SDL_free(argv); } } static bool IsSDLWindowEventPending(SDL_WindowEventID windowEventID) { SDL_Event events[128]; - const int count = SDL_PeepEvents(events, sizeof(events)/sizeof(SDL_Event), SDL_PEEKEVENT, SDL_WINDOWEVENT, SDL_WINDOWEVENT); + const int count = SDL_PeepEvents(events, sizeof(events) / sizeof(SDL_Event), SDL_PEEKEVENT, SDL_WINDOWEVENT, SDL_WINDOWEVENT); for (int i = 0; i < count; ++i) { if (events[i].window.event == windowEventID) { return true; @@ -449,7 +371,7 @@ bool SDL_WinRTApp::ShouldWaitForAppResumeEvents() if (m_windowVisible) { return false; } - + /* Don't wait until the window-hide events finish processing. * Do note that if an app-suspend event is sent (as indicated * by SDL_APP_WILLENTERBACKGROUND and SDL_APP_DIDENTERBACKGROUND @@ -498,17 +420,17 @@ void SDL_WinRTApp::Uninitialize() #if (WINAPI_FAMILY == WINAPI_FAMILY_APP) && (NTDDI_VERSION < NTDDI_WIN10) void SDL_WinRTApp::OnSettingsPaneCommandsRequested( - Windows::UI::ApplicationSettings::SettingsPane ^p, - Windows::UI::ApplicationSettings::SettingsPaneCommandsRequestedEventArgs ^args) + Windows::UI::ApplicationSettings::SettingsPane ^ p, + Windows::UI::ApplicationSettings::SettingsPaneCommandsRequestedEventArgs ^ args) { using namespace Platform; using namespace Windows::UI::ApplicationSettings; using namespace Windows::UI::Popups; - String ^privacyPolicyURL = nullptr; // a URL to an app's Privacy Policy - String ^privacyPolicyLabel = nullptr; // label/link text - const char *tmpHintValue = NULL; // SDL_GetHint-retrieved value, used immediately - wchar_t *tmpStr = NULL; // used for UTF8 to UCS2 conversion + String ^ privacyPolicyURL = nullptr; // a URL to an app's Privacy Policy + String ^ privacyPolicyLabel = nullptr; // label/link text + const char *tmpHintValue = NULL; // SDL_GetHint-retrieved value, used immediately + wchar_t *tmpStr = NULL; // used for UTF8 to UCS2 conversion // Setup a 'Privacy Policy' link, if one is available (via SDL_GetHint): tmpHintValue = SDL_GetHint(SDL_HINT_WINRT_PRIVACY_POLICY_URL); @@ -532,39 +454,39 @@ void SDL_WinRTApp::OnSettingsPaneCommandsRequested( // Register the link, along with a handler to be called if and when it is // clicked: auto cmd = ref new SettingsCommand(L"privacyPolicy", privacyPolicyLabel, - ref new UICommandInvokedHandler([=](IUICommand ^) { - Windows::System::Launcher::LaunchUriAsync(ref new Uri(privacyPolicyURL)); - })); + ref new UICommandInvokedHandler([=](IUICommand ^) { + Windows::System::Launcher::LaunchUriAsync(ref new Uri(privacyPolicyURL)); + })); args->Request->ApplicationCommands->Append(cmd); } } #endif // if (WINAPI_FAMILY == WINAPI_FAMILY_APP) && (NTDDI_VERSION < NTDDI_WIN10) -void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ args) +void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow ^ sender, WindowSizeChangedEventArgs ^ args) { -#if LOG_WINDOW_EVENTS==1 +#if LOG_WINDOW_EVENTS == 1 SDL_Log("%s, size={%f,%f}, bounds={%f,%f,%f,%f}, current orientation=%d, native orientation=%d, auto rot. pref=%d, WINRT_GlobalSDLWindow?=%s\n", - __FUNCTION__, - args->Size.Width, args->Size.Height, - sender->Bounds.X, sender->Bounds.Y, sender->Bounds.Width, sender->Bounds.Height, - WINRT_DISPLAY_PROPERTY(CurrentOrientation), - WINRT_DISPLAY_PROPERTY(NativeOrientation), - WINRT_DISPLAY_PROPERTY(AutoRotationPreferences), - (WINRT_GlobalSDLWindow ? "yes" : "no")); + __FUNCTION__, + args->Size.Width, args->Size.Height, + sender->Bounds.X, sender->Bounds.Y, sender->Bounds.Width, sender->Bounds.Height, + WINRT_DISPLAY_PROPERTY(CurrentOrientation), + WINRT_DISPLAY_PROPERTY(NativeOrientation), + WINRT_DISPLAY_PROPERTY(AutoRotationPreferences), + (WINRT_GlobalSDLWindow ? "yes" : "no")); #endif WINRT_ProcessWindowSizeChange(); } -void SDL_WinRTApp::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args) +void SDL_WinRTApp::OnVisibilityChanged(CoreWindow ^ sender, VisibilityChangedEventArgs ^ args) { -#if LOG_WINDOW_EVENTS==1 +#if LOG_WINDOW_EVENTS == 1 SDL_Log("%s, visible?=%s, bounds={%f,%f,%f,%f}, WINRT_GlobalSDLWindow?=%s\n", - __FUNCTION__, - (args->Visible ? "yes" : "no"), - sender->Bounds.X, sender->Bounds.Y, - sender->Bounds.Width, sender->Bounds.Height, - (WINRT_GlobalSDLWindow ? "yes" : "no")); + __FUNCTION__, + (args->Visible ? "yes" : "no"), + sender->Bounds.X, sender->Bounds.Y, + sender->Bounds.Width, sender->Bounds.Height, + (WINRT_GlobalSDLWindow ? "yes" : "no")); #endif m_windowVisible = args->Visible; @@ -595,12 +517,12 @@ void SDL_WinRTApp::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEven } } -void SDL_WinRTApp::OnWindowActivated(CoreWindow^ sender, WindowActivatedEventArgs^ args) +void SDL_WinRTApp::OnWindowActivated(CoreWindow ^ sender, WindowActivatedEventArgs ^ args) { -#if LOG_WINDOW_EVENTS==1 +#if LOG_WINDOW_EVENTS == 1 SDL_Log("%s, WINRT_GlobalSDLWindow?=%s\n\n", - __FUNCTION__, - (WINRT_GlobalSDLWindow ? "yes" : "no")); + __FUNCTION__, + (WINRT_GlobalSDLWindow ? "yes" : "no")); #endif /* There's no property in Win 8.x to tell whether a window is active or @@ -610,14 +532,14 @@ void SDL_WinRTApp::OnWindowActivated(CoreWindow^ sender, WindowActivatedEventArg */ sender->CustomProperties->Insert("SDLHelperWindowActivationState", args->WindowActivationState); - SDL_Window * window = WINRT_GlobalSDLWindow; + SDL_Window *window = WINRT_GlobalSDLWindow; if (window) { if (args->WindowActivationState != CoreWindowActivationState::Deactivated) { SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SHOWN, 0, 0); if (SDL_GetKeyboardFocus() != window) { SDL_SetKeyboardFocus(window); } - + /* Send a mouse-motion event as appropriate. This doesn't work when called from OnPointerEntered, at least not in WinRT CoreWindow apps (as OnPointerEntered doesn't @@ -627,19 +549,19 @@ void SDL_WinRTApp::OnWindowActivated(CoreWindow^ sender, WindowActivatedEventArg Don't do it on WinPhone 8.0 though, as CoreWindow's 'PointerPosition' property isn't available. */ -#if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) || (NTDDI_VERSION >= NTDDI_WINBLUE) +#if !SDL_WINAPI_FAMILY_PHONE || (NTDDI_VERSION >= NTDDI_WINBLUE) Point cursorPos = WINRT_TransformCursorPosition(window, sender->PointerPosition, TransformToSDLWindowSize); SDL_SendMouseMotion(window, 0, 0, (int)cursorPos.X, (int)cursorPos.Y); #endif /* TODO, WinRT: see if the Win32 bugfix from https://hg.libsdl.org/SDL/rev/d278747da408 needs to be applied (on window activation) */ - //WIN_CheckAsyncMouseRelease(data); + // WIN_CheckAsyncMouseRelease(data); /* TODO, WinRT: implement clipboard support, if possible */ ///* // * FIXME: Update keyboard state // */ - //WIN_CheckClipboardUpdate(data->videodata); + // WIN_CheckClipboardUpdate(data->videodata); // HACK: Resetting the mouse-cursor here seems to fix // https://bugzilla.libsdl.org/show_bug.cgi?id=3217, whereby a @@ -657,20 +579,20 @@ void SDL_WinRTApp::OnWindowActivated(CoreWindow^ sender, WindowActivatedEventArg } } -void SDL_WinRTApp::OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args) +void SDL_WinRTApp::OnWindowClosed(CoreWindow ^ sender, CoreWindowEventArgs ^ args) { -#if LOG_WINDOW_EVENTS==1 +#if LOG_WINDOW_EVENTS == 1 SDL_Log("%s\n", __FUNCTION__); #endif m_windowClosed = true; } -void SDL_WinRTApp::OnAppActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args) +void SDL_WinRTApp::OnAppActivated(CoreApplicationView ^ applicationView, IActivatedEventArgs ^ args) { CoreWindow::GetForCurrentThread()->Activate(); } -void SDL_WinRTApp::OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ args) +void SDL_WinRTApp::OnSuspending(Platform::Object ^ sender, SuspendingEventArgs ^ args) { // Save app state asynchronously after requesting a deferral. Holding a deferral // indicates that the application is busy performing suspending operations. Be @@ -686,9 +608,8 @@ void SDL_WinRTApp::OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ a // this could be important. SDL_SendAppEvent(SDL_APP_WILLENTERBACKGROUND); - SuspendingDeferral^ deferral = args->SuspendingOperation->GetDeferral(); - create_task([this, deferral]() - { + SuspendingDeferral ^ deferral = args->SuspendingOperation->GetDeferral(); + create_task([this, deferral]() { // Send an app did-enter-background event immediately to observers. // CoreDispatcher::ProcessEvents, which is the backbone on which // SDL_WinRTApp::PumpEvents is built, will not return to its caller @@ -701,9 +622,9 @@ void SDL_WinRTApp::OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ a // Let the Direct3D 11 renderer prepare for the app to be backgrounded. // This is necessary for Windows 8.1, possibly elsewhere in the future. // More details at: http://msdn.microsoft.com/en-us/library/windows/apps/Hh994929.aspx -#if SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED +#if SDL_VIDEO_RENDER_D3D11 if (WINRT_GlobalSDLWindow) { - SDL_Renderer * renderer = SDL_GetRenderer(WINRT_GlobalSDLWindow); + SDL_Renderer *renderer = SDL_GetRenderer(WINRT_GlobalSDLWindow); if (renderer && (SDL_strcmp(renderer->info.name, "direct3d11") == 0)) { D3D11_Trim(renderer); } @@ -714,7 +635,7 @@ void SDL_WinRTApp::OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ a }); } -void SDL_WinRTApp::OnResuming(Platform::Object^ sender, Platform::Object^ args) +void SDL_WinRTApp::OnResuming(Platform::Object ^ sender, Platform::Object ^ args) { // Restore any data or state that was unloaded on suspend. By default, data // and state are persisted when resuming from suspend. Note that these events @@ -723,26 +644,28 @@ void SDL_WinRTApp::OnResuming(Platform::Object^ sender, Platform::Object^ args) SDL_SendAppEvent(SDL_APP_DIDENTERFOREGROUND); } -void SDL_WinRTApp::OnExiting(Platform::Object^ sender, Platform::Object^ args) +void SDL_WinRTApp::OnExiting(Platform::Object ^ sender, Platform::Object ^ args) { SDL_SendAppEvent(SDL_APP_TERMINATING); } -static void -WINRT_LogPointerEvent(const char * header, Windows::UI::Core::PointerEventArgs ^ args, Windows::Foundation::Point transformedPoint) +static void WINRT_LogPointerEvent(const char *header, Windows::UI::Core::PointerEventArgs ^ args, Windows::Foundation::Point transformedPoint) { + Uint8 button, pressed; Windows::UI::Input::PointerPoint ^ pt = args->CurrentPoint; - SDL_Log("%s: Position={%f,%f}, Transformed Pos={%f, %f}, MouseWheelDelta=%d, FrameId=%d, PointerId=%d, SDL button=%d\n", - header, - pt->Position.X, pt->Position.Y, - transformedPoint.X, transformedPoint.Y, - pt->Properties->MouseWheelDelta, - pt->FrameId, - pt->PointerId, - WINRT_GetSDLButtonForPointerPoint(pt)); + WINRT_GetSDLButtonForPointerPoint(pt, &button, &pressed); + SDL_Log("%s: Position={%f,%f}, Transformed Pos={%f, %f}, MouseWheelDelta=%d, FrameId=%d, PointerId=%d, SDL button=%d pressed=%d\n", + header, + pt->Position.X, pt->Position.Y, + transformedPoint.X, transformedPoint.Y, + pt->Properties->MouseWheelDelta, + pt->FrameId, + pt->PointerId, + button, + pressed); } -void SDL_WinRTApp::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args) +void SDL_WinRTApp::OnPointerPressed(CoreWindow ^ sender, PointerEventArgs ^ args) { #if LOG_POINTER_EVENTS WINRT_LogPointerEvent("pointer pressed", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize)); @@ -751,7 +674,7 @@ void SDL_WinRTApp::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args) WINRT_ProcessPointerPressedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); } -void SDL_WinRTApp::OnPointerMoved(CoreWindow^ sender, PointerEventArgs^ args) +void SDL_WinRTApp::OnPointerMoved(CoreWindow ^ sender, PointerEventArgs ^ args) { #if LOG_POINTER_EVENTS WINRT_LogPointerEvent("pointer moved", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize)); @@ -760,16 +683,16 @@ void SDL_WinRTApp::OnPointerMoved(CoreWindow^ sender, PointerEventArgs^ args) WINRT_ProcessPointerMovedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); } -void SDL_WinRTApp::OnPointerReleased(CoreWindow^ sender, PointerEventArgs^ args) +void SDL_WinRTApp::OnPointerReleased(CoreWindow ^ sender, PointerEventArgs ^ args) { #if LOG_POINTER_EVENTS WINRT_LogPointerEvent("pointer released", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize)); #endif - + WINRT_ProcessPointerReleasedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); } -void SDL_WinRTApp::OnPointerEntered(CoreWindow^ sender, PointerEventArgs^ args) +void SDL_WinRTApp::OnPointerEntered(CoreWindow ^ sender, PointerEventArgs ^ args) { #if LOG_POINTER_EVENTS WINRT_LogPointerEvent("pointer entered", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize)); @@ -778,7 +701,7 @@ void SDL_WinRTApp::OnPointerEntered(CoreWindow^ sender, PointerEventArgs^ args) WINRT_ProcessPointerEnteredEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); } -void SDL_WinRTApp::OnPointerExited(CoreWindow^ sender, PointerEventArgs^ args) +void SDL_WinRTApp::OnPointerExited(CoreWindow ^ sender, PointerEventArgs ^ args) { #if LOG_POINTER_EVENTS WINRT_LogPointerEvent("pointer exited", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize)); @@ -787,7 +710,7 @@ void SDL_WinRTApp::OnPointerExited(CoreWindow^ sender, PointerEventArgs^ args) WINRT_ProcessPointerExitedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); } -void SDL_WinRTApp::OnPointerWheelChanged(CoreWindow^ sender, PointerEventArgs^ args) +void SDL_WinRTApp::OnPointerWheelChanged(CoreWindow ^ sender, PointerEventArgs ^ args) { #if LOG_POINTER_EVENTS WINRT_LogPointerEvent("pointer wheel changed", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize)); @@ -796,22 +719,22 @@ void SDL_WinRTApp::OnPointerWheelChanged(CoreWindow^ sender, PointerEventArgs^ a WINRT_ProcessPointerWheelChangedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint); } -void SDL_WinRTApp::OnMouseMoved(MouseDevice^ mouseDevice, MouseEventArgs^ args) +void SDL_WinRTApp::OnMouseMoved(MouseDevice ^ mouseDevice, MouseEventArgs ^ args) { WINRT_ProcessMouseMovedEvent(WINRT_GlobalSDLWindow, args); } -void SDL_WinRTApp::OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args) +void SDL_WinRTApp::OnKeyDown(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::KeyEventArgs ^ args) { WINRT_ProcessKeyDownEvent(args); } -void SDL_WinRTApp::OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args) +void SDL_WinRTApp::OnKeyUp(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::KeyEventArgs ^ args) { WINRT_ProcessKeyUpEvent(args); } -void SDL_WinRTApp::OnCharacterReceived(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::CharacterReceivedEventArgs^ args) +void SDL_WinRTApp::OnCharacterReceived(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::CharacterReceivedEventArgs ^ args) { WINRT_ProcessCharacterReceivedEvent(args); } @@ -828,13 +751,13 @@ static void WINRT_OnBackButtonPressed(BackButtonEventArgs ^ args) } #if NTDDI_VERSION >= NTDDI_WIN10 -void SDL_WinRTApp::OnBackButtonPressed(Platform::Object^ sender, Windows::UI::Core::BackRequestedEventArgs^ args) +void SDL_WinRTApp::OnBackButtonPressed(Platform::Object ^ sender, Windows::UI::Core::BackRequestedEventArgs ^ args) { WINRT_OnBackButtonPressed(args); } -#elif WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP -void SDL_WinRTApp::OnBackButtonPressed(Platform::Object^ sender, Windows::Phone::UI::Input::BackPressedEventArgs^ args) +#elif SDL_WINAPI_FAMILY_PHONE +void SDL_WinRTApp::OnBackButtonPressed(Platform::Object ^ sender, Windows::Phone::UI::Input::BackPressedEventArgs ^ args) { WINRT_OnBackButtonPressed(args); @@ -842,7 +765,7 @@ void SDL_WinRTApp::OnBackButtonPressed(Platform::Object^ sender, Windows::Phone: #endif #if NTDDI_VERSION >= NTDDI_WIN10 -void SDL_WinRTApp::OnGamepadAdded(Platform::Object ^sender, Windows::Gaming::Input::Gamepad ^gamepad) +void SDL_WinRTApp::OnGamepadAdded(Platform::Object ^ sender, Windows::Gaming::Input::Gamepad ^ gamepad) { /* HACK ALERT: Nothing needs to be done here, as this method currently only exists to allow something to be registered with Win10's diff --git a/SDL2-2.30.5/src/core/winrt/SDL_winrtapp_direct3d.h b/SDL2-2.30.5/src/core/winrt/SDL_winrtapp_direct3d.h new file mode 100644 index 0000000..fcd6ab7 --- /dev/null +++ b/SDL2-2.30.5/src/core/winrt/SDL_winrtapp_direct3d.h @@ -0,0 +1,93 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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 + +extern int SDL_WinRTInitNonXAMLApp(int (*mainFunction)(int, char **)); + +ref class SDL_WinRTApp sealed : public Windows::ApplicationModel::Core::IFrameworkView +{ + public: + SDL_WinRTApp(); + + // IFrameworkView Methods. + virtual void Initialize(Windows::ApplicationModel::Core::CoreApplicationView ^ applicationView); + virtual void SetWindow(Windows::UI::Core::CoreWindow ^ window); + virtual void Load(Platform::String ^ entryPoint); + virtual void Run(); + virtual void Uninitialize(); + + internal : + // SDL-specific methods + void + PumpEvents(); + + protected: + bool ShouldWaitForAppResumeEvents(); + + // Event Handlers. + +#if (WINAPI_FAMILY == WINAPI_FAMILY_APP) && (NTDDI_VERSION < NTDDI_WIN10) // for Windows 8/8.1/RT apps... (and not Phone apps) + void OnSettingsPaneCommandsRequested( + Windows::UI::ApplicationSettings::SettingsPane ^ p, + Windows::UI::ApplicationSettings::SettingsPaneCommandsRequestedEventArgs ^ args); +#endif // if (WINAPI_FAMILY == WINAPI_FAMILY_APP) && (NTDDI_VERSION < NTDDI_WIN10) + +#if NTDDI_VERSION > NTDDI_WIN8 + void OnOrientationChanged(Windows::Graphics::Display::DisplayInformation ^ sender, Platform::Object ^ args); +#else + void OnOrientationChanged(Platform::Object ^ sender); +#endif + void OnWindowSizeChanged(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::WindowSizeChangedEventArgs ^ args); + void OnLogicalDpiChanged(Platform::Object ^ sender); + void OnAppActivated(Windows::ApplicationModel::Core::CoreApplicationView ^ applicationView, Windows::ApplicationModel::Activation::IActivatedEventArgs ^ args); + void OnSuspending(Platform::Object ^ sender, Windows::ApplicationModel::SuspendingEventArgs ^ args); + void OnResuming(Platform::Object ^ sender, Platform::Object ^ args); + void OnExiting(Platform::Object ^ sender, Platform::Object ^ args); + void OnWindowActivated(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::WindowActivatedEventArgs ^ args); + void OnWindowClosed(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::CoreWindowEventArgs ^ args); + void OnVisibilityChanged(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::VisibilityChangedEventArgs ^ args); + void OnPointerPressed(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::PointerEventArgs ^ args); + void OnPointerReleased(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::PointerEventArgs ^ args); + void OnPointerWheelChanged(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::PointerEventArgs ^ args); + void OnPointerMoved(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::PointerEventArgs ^ args); + void OnPointerEntered(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::PointerEventArgs ^ args); + void OnPointerExited(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::PointerEventArgs ^ args); + void OnMouseMoved(Windows::Devices::Input::MouseDevice ^ mouseDevice, Windows::Devices::Input::MouseEventArgs ^ args); + void OnKeyDown(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::KeyEventArgs ^ args); + void OnKeyUp(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::KeyEventArgs ^ args); + void OnCharacterReceived(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::CharacterReceivedEventArgs ^ args); + +#if NTDDI_VERSION >= NTDDI_WIN10 + void OnBackButtonPressed(Platform::Object ^ sender, Windows::UI::Core::BackRequestedEventArgs ^ args); +#elif SDL_WINAPI_FAMILY_PHONE + void OnBackButtonPressed(Platform::Object ^ sender, Windows::Phone::UI::Input::BackPressedEventArgs ^ args); +#endif + +#if NTDDI_VERSION >= NTDDI_WIN10 + void OnGamepadAdded(Platform::Object ^ sender, Windows::Gaming::Input::Gamepad ^ gamepad); +#endif + + private: + bool m_windowClosed; + bool m_windowVisible; +}; + +extern SDL_WinRTApp ^ SDL_WinRTGlobalApp; diff --git a/SDL2-2.0.12/src/core/winrt/SDL_winrtapp_xaml.cpp b/SDL2-2.30.5/src/core/winrt/SDL_winrtapp_xaml.cpp similarity index 73% rename from SDL2-2.0.12/src/core/winrt/SDL_winrtapp_xaml.cpp rename to SDL2-2.30.5/src/core/winrt/SDL_winrtapp_xaml.cpp index b9dd1e2..9174f0d 100644 --- a/SDL2-2.0.12/src/core/winrt/SDL_winrtapp_xaml.cpp +++ b/SDL2-2.30.5/src/core/winrt/SDL_winrtapp_xaml.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -27,7 +27,6 @@ #include #endif - /* SDL includes */ #include "../../SDL_internal.h" #include "SDL.h" @@ -36,72 +35,60 @@ #include "SDL_winrtapp_common.h" #include "SDL_winrtapp_xaml.h" - - /* SDL-internal globals: */ SDL_bool WINRT_XAMLWasEnabled = SDL_FALSE; #if WINAPI_FAMILY == WINAPI_FAMILY_APP -extern "C" -ISwapChainBackgroundPanelNative * WINRT_GlobalSwapChainBackgroundPanelNative = NULL; -static Windows::Foundation::EventRegistrationToken WINRT_XAMLAppEventToken; +extern "C" ISwapChainBackgroundPanelNative *WINRT_GlobalSwapChainBackgroundPanelNative = NULL; +static Windows::Foundation::EventRegistrationToken WINRT_XAMLAppEventToken; #endif - /* * Input event handlers (XAML) */ #if WINAPI_FAMILY == WINAPI_FAMILY_APP -static void -WINRT_OnPointerPressedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args) +static void WINRT_OnPointerPressedViaXAML(Platform::Object ^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs ^ args) { WINRT_ProcessPointerPressedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr)); } -static void -WINRT_OnPointerMovedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args) +static void WINRT_OnPointerMovedViaXAML(Platform::Object ^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs ^ args) { WINRT_ProcessPointerMovedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr)); } -static void -WINRT_OnPointerReleasedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args) +static void WINRT_OnPointerReleasedViaXAML(Platform::Object ^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs ^ args) { WINRT_ProcessPointerReleasedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr)); } -static void -WINRT_OnPointerWheelChangedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args) +static void WINRT_OnPointerWheelChangedViaXAML(Platform::Object ^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs ^ args) { WINRT_ProcessPointerWheelChangedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr)); } #endif // WINAPI_FAMILY == WINAPI_FAMILY_APP - /* * XAML-to-SDL Rendering Callback */ #if WINAPI_FAMILY == WINAPI_FAMILY_APP -static void -WINRT_OnRenderViaXAML(_In_ Platform::Object^ sender, _In_ Platform::Object^ args) +static void WINRT_OnRenderViaXAML(_In_ Platform::Object ^ sender, _In_ Platform::Object ^ args) { WINRT_CycleXAMLThread(); } #endif // WINAPI_FAMILY == WINAPI_FAMILY_APP - /* * SDL + XAML Initialization */ -int -SDL_WinRTInitXAMLApp(int (*mainFunction)(int, char **), void * backgroundPanelAsIInspectable) +int SDL_WinRTInitXAMLApp(int (*mainFunction)(int, char **), void *backgroundPanelAsIInspectable) { -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP +#if SDL_WINAPI_FAMILY_PHONE return SDL_SetError("XAML support is not yet available in Windows Phone."); #else // Declare C++/CX namespaces: @@ -114,13 +101,13 @@ SDL_WinRTInitXAMLApp(int (*mainFunction)(int, char **), void * backgroundPanelAs using namespace Windows::UI::Xaml::Media; // Make sure we have a valid XAML element (to draw onto): - if ( ! backgroundPanelAsIInspectable) { - return SDL_SetError("'backgroundPanelAsIInspectable' can't be NULL"); + if (!backgroundPanelAsIInspectable) { + return SDL_InvalidParamError("backgroundPanelAsIInspectable"); } - Platform::Object ^ backgroundPanel = reinterpret_cast((IInspectable *) backgroundPanelAsIInspectable); - SwapChainBackgroundPanel ^swapChainBackgroundPanel = dynamic_cast(backgroundPanel); - if ( ! swapChainBackgroundPanel) { + Platform::Object ^ backgroundPanel = reinterpret_cast((IInspectable *)backgroundPanelAsIInspectable); + SwapChainBackgroundPanel ^ swapChainBackgroundPanel = dynamic_cast(backgroundPanel); + if (!swapChainBackgroundPanel) { return SDL_SetError("An unknown or unsupported type of XAML control was specified."); } @@ -131,10 +118,10 @@ SDL_WinRTInitXAMLApp(int (*mainFunction)(int, char **), void * backgroundPanelAs swapChainBackgroundPanel->PointerMoved += ref new PointerEventHandler(WINRT_OnPointerMovedViaXAML); // Setup for rendering: - IInspectable *panelInspectable = (IInspectable*) reinterpret_cast(swapChainBackgroundPanel); + IInspectable *panelInspectable = (IInspectable *)reinterpret_cast(swapChainBackgroundPanel); panelInspectable->QueryInterface(__uuidof(ISwapChainBackgroundPanelNative), (void **)&WINRT_GlobalSwapChainBackgroundPanelNative); - WINRT_XAMLAppEventToken = CompositionTarget::Rendering::add(ref new EventHandler(WINRT_OnRenderViaXAML)); + WINRT_XAMLAppEventToken = CompositionTarget::Rendering::add(ref new EventHandler(WINRT_OnRenderViaXAML)); // Make sure the app is ready to call the SDL-centric main() function: WINRT_SDLAppEntryPoint = mainFunction; @@ -156,5 +143,5 @@ SDL_WinRTInitXAMLApp(int (*mainFunction)(int, char **), void * backgroundPanelAs // All done, for now. return 0; -#endif // WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP / else +#endif // SDL_WINAPI_FAMILY_PHONE / else } diff --git a/SDL2-2.0.12/src/core/winrt/SDL_winrtapp_xaml.h b/SDL2-2.30.5/src/core/winrt/SDL_winrtapp_xaml.h similarity index 91% rename from SDL2-2.0.12/src/core/winrt/SDL_winrtapp_xaml.h rename to SDL2-2.30.5/src/core/winrt/SDL_winrtapp_xaml.h index f998e84..b414753 100644 --- a/SDL2-2.0.12/src/core/winrt/SDL_winrtapp_xaml.h +++ b/SDL2-2.30.5/src/core/winrt/SDL_winrtapp_xaml.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -27,7 +27,7 @@ #ifdef __cplusplus extern SDL_bool WINRT_XAMLWasEnabled; -extern int SDL_WinRTInitXAMLApp(int (*mainFunction)(int, char **), void * backgroundPanelAsIInspectable); +extern int SDL_WinRTInitXAMLApp(int (*mainFunction)(int, char **), void *backgroundPanelAsIInspectable); #endif // ifdef __cplusplus #endif // SDL_winrtapp_xaml_h_ diff --git a/SDL2-2.0.12/src/cpuinfo/SDL_cpuinfo.c b/SDL2-2.30.5/src/cpuinfo/SDL_cpuinfo.c similarity index 50% rename from SDL2-2.0.12/src/cpuinfo/SDL_cpuinfo.c rename to SDL2-2.30.5/src/cpuinfo/SDL_cpuinfo.c index 9cecb4f..34aa424 100644 --- a/SDL2-2.0.12/src/cpuinfo/SDL_cpuinfo.c +++ b/SDL2-2.30.5/src/cpuinfo/SDL_cpuinfo.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -24,10 +24,11 @@ #include "../SDL_internal.h" #endif -#if defined(__WIN32__) || defined(__WINRT__) +#if defined(__WIN32__) || defined(__WINRT__) || defined(__GDK__) #include "../core/windows/SDL_windows.h" #endif #if defined(__OS2__) +#undef HAVE_SYSCTLBYNAME #define INCL_DOS #include #ifndef QSV_NUMPROCESSORS @@ -50,10 +51,13 @@ #if defined(__MACOSX__) && (defined(__ppc__) || defined(__ppc64__)) #include /* For AltiVec check */ #elif defined(__OpenBSD__) && defined(__powerpc__) -#include +#include #include /* For AltiVec check */ #include -#elif SDL_ALTIVEC_BLITTERS && HAVE_SETJMP +#elif defined(__FreeBSD__) && defined(__powerpc__) +#include +#include +#elif defined(SDL_ALTIVEC_BLITTERS) && defined(HAVE_SETJMP) #include #include #endif @@ -62,7 +66,13 @@ #include #endif -#if (defined(__LINUX__) || defined(__ANDROID__)) && defined(__ARM_ARCH) +#if (defined(__LINUX__) || defined(__ANDROID__)) && defined(__arm__) +#include +#include +#include +#include +#include + /*#include */ #ifndef AT_HWCAP #define AT_HWCAP 16 @@ -70,24 +80,17 @@ #ifndef AT_PLATFORM #define AT_PLATFORM 15 #endif -/* Prevent compilation error when including elf.h would also try to define AT_* as an enum */ -#ifndef AT_NULL -#define AT_NULL 0 -#endif #ifndef HWCAP_NEON #define HWCAP_NEON (1 << 12) #endif -#if defined HAVE_GETAUXVAL -#include -#else -#include -#endif #endif -#if defined(__ANDROID__) && defined(__ARM_ARCH) && !defined(HAVE_GETAUXVAL) -#if __ARM_ARCH < 8 +#if defined(__ANDROID__) && defined(__arm__) && !defined(HAVE_GETAUXVAL) #include #endif + +#if defined(HAVE_GETAUXVAL) || defined(HAVE_ELF_AUX_INFO) +#include #endif #ifdef __RISCOS__ @@ -95,41 +98,49 @@ #include #endif -#define CPU_HAS_RDTSC (1 << 0) -#define CPU_HAS_ALTIVEC (1 << 1) -#define CPU_HAS_MMX (1 << 2) -#define CPU_HAS_3DNOW (1 << 3) -#define CPU_HAS_SSE (1 << 4) -#define CPU_HAS_SSE2 (1 << 5) -#define CPU_HAS_SSE3 (1 << 6) -#define CPU_HAS_SSE41 (1 << 7) -#define CPU_HAS_SSE42 (1 << 8) -#define CPU_HAS_AVX (1 << 9) -#define CPU_HAS_AVX2 (1 << 10) -#define CPU_HAS_NEON (1 << 11) -#define CPU_HAS_AVX512F (1 << 12) -#define CPU_HAS_ARM_SIMD (1 << 13) +#ifdef __PS2__ +#include +#endif -#if SDL_ALTIVEC_BLITTERS && HAVE_SETJMP && !__MACOSX__ && !__OpenBSD__ +#define CPU_HAS_RDTSC (1 << 0) +#define CPU_HAS_ALTIVEC (1 << 1) +#define CPU_HAS_MMX (1 << 2) +#define CPU_HAS_3DNOW (1 << 3) +#define CPU_HAS_SSE (1 << 4) +#define CPU_HAS_SSE2 (1 << 5) +#define CPU_HAS_SSE3 (1 << 6) +#define CPU_HAS_SSE41 (1 << 7) +#define CPU_HAS_SSE42 (1 << 8) +#define CPU_HAS_AVX (1 << 9) +#define CPU_HAS_AVX2 (1 << 10) +#define CPU_HAS_NEON (1 << 11) +#define CPU_HAS_AVX512F (1 << 12) +#define CPU_HAS_ARM_SIMD (1 << 13) +#define CPU_HAS_LSX (1 << 14) +#define CPU_HAS_LASX (1 << 15) + +#define CPU_CFG2 0x2 +#define CPU_CFG2_LSX (1 << 6) +#define CPU_CFG2_LASX (1 << 7) + +#if defined(SDL_ALTIVEC_BLITTERS) && defined(HAVE_SETJMP) && !defined(__MACOSX__) && !defined(__OpenBSD__) && !defined(__FreeBSD__) /* This is the brute force way of detecting instruction sets... the idea is borrowed from the libmpeg2 library - thanks! */ static jmp_buf jmpbuf; -static void -illegal_instruction(int sig) +static void illegal_instruction(int sig) { longjmp(jmpbuf, 1); } #endif /* HAVE_SETJMP */ -static int -CPU_haveCPUID(void) +static int CPU_haveCPUID(void) { int has_CPUID = 0; -/* *INDENT-OFF* */ +/* *INDENT-OFF* */ /* clang-format off */ #ifndef SDL_CPUINFO_DISABLED -#if defined(__GNUC__) && defined(i386) +#if (defined(__GNUC__) || defined(__llvm__)) && defined(__i386__) __asm__ ( " pushfl # Get original EFLAGS \n" " popl %%eax \n" @@ -147,8 +158,8 @@ CPU_haveCPUID(void) : : "%eax", "%ecx" ); -#elif defined(__GNUC__) && defined(__x86_64__) -/* Technically, if this is being compiled under __x86_64__ then it has +#elif (defined(__GNUC__) || defined(__llvm__)) && defined(__x86_64__) +/* Technically, if this is being compiled under __x86_64__ then it has CPUid by definition. But it's nice to be able to prove it. :) */ __asm__ ( " pushfq # Get original EFLAGS \n" @@ -216,28 +227,30 @@ done: ); #endif #endif -/* *INDENT-ON* */ +/* *INDENT-ON* */ /* clang-format on */ return has_CPUID; } -#if defined(__GNUC__) && defined(i386) -#define cpuid(func, a, b, c, d) \ - __asm__ __volatile__ ( \ -" pushl %%ebx \n" \ -" xorl %%ecx,%%ecx \n" \ -" cpuid \n" \ -" movl %%ebx, %%esi \n" \ -" popl %%ebx \n" : \ - "=a" (a), "=S" (b), "=c" (c), "=d" (d) : "a" (func)) -#elif defined(__GNUC__) && defined(__x86_64__) -#define cpuid(func, a, b, c, d) \ - __asm__ __volatile__ ( \ -" pushq %%rbx \n" \ -" xorq %%rcx,%%rcx \n" \ -" cpuid \n" \ -" movq %%rbx, %%rsi \n" \ -" popq %%rbx \n" : \ - "=a" (a), "=S" (b), "=c" (c), "=d" (d) : "a" (func)) +#if (defined(__GNUC__) || defined(__llvm__)) && defined(__i386__) +#define cpuid(func, a, b, c, d) \ + __asm__ __volatile__( \ + " pushl %%ebx \n" \ + " xorl %%ecx,%%ecx \n" \ + " cpuid \n" \ + " movl %%ebx, %%esi \n" \ + " popl %%ebx \n" \ + : "=a"(a), "=S"(b), "=c"(c), "=d"(d) \ + : "a"(func)) +#elif (defined(__GNUC__) || defined(__llvm__)) && defined(__x86_64__) +#define cpuid(func, a, b, c, d) \ + __asm__ __volatile__( \ + " pushq %%rbx \n" \ + " xorq %%rcx,%%rcx \n" \ + " cpuid \n" \ + " movq %%rbx, %%rsi \n" \ + " popq %%rbx \n" \ + : "=a"(a), "=S"(b), "=c"(c), "=d"(d) \ + : "a"(func)) #elif (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__) #define cpuid(func, a, b, c, d) \ __asm { \ @@ -247,21 +260,28 @@ done: __asm mov a, eax \ __asm mov b, ebx \ __asm mov c, ecx \ - __asm mov d, edx \ -} -#elif defined(_MSC_VER) && defined(_M_X64) -#define cpuid(func, a, b, c, d) \ -{ \ - int CPUInfo[4]; \ - __cpuid(CPUInfo, func); \ - a = CPUInfo[0]; \ - b = CPUInfo[1]; \ - c = CPUInfo[2]; \ - d = CPUInfo[3]; \ -} + __asm mov d, edx \ + } +#elif (defined(_MSC_VER) && defined(_M_X64)) +/* Use __cpuidex instead of __cpuid because ICL does not clear ecx register */ +#define cpuid(func, a, b, c, d) \ + { \ + int CPUInfo[4]; \ + __cpuidex(CPUInfo, func, 0); \ + a = CPUInfo[0]; \ + b = CPUInfo[1]; \ + c = CPUInfo[2]; \ + d = CPUInfo[3]; \ + } #else #define cpuid(func, a, b, c, d) \ - do { a = b = c = d = 0; (void) a; (void) b; (void) c; (void) d; } while (0) + do { \ + a = b = c = d = 0; \ + (void)a; \ + (void)b; \ + (void)c; \ + (void)d; \ + } while (0) #endif static int CPU_CPUIDFeatures[4]; @@ -269,8 +289,7 @@ static int CPU_CPUIDMaxFunction = 0; static SDL_bool CPU_OSSavesYMM = SDL_FALSE; static SDL_bool CPU_OSSavesZMM = SDL_FALSE; -static void -CPU_calcCPUIDFeatures(void) +static void CPU_calcCPUIDFeatures(void) { static SDL_bool checked = SDL_FALSE; if (!checked) { @@ -289,17 +308,20 @@ CPU_calcCPUIDFeatures(void) /* Check to make sure we can call xgetbv */ if (c & 0x08000000) { /* Call xgetbv to see if YMM (etc) register state is saved */ -#if defined(__GNUC__) && (defined(i386) || defined(__x86_64__)) - __asm__(".byte 0x0f, 0x01, 0xd0" : "=a" (a) : "c" (0) : "%edx"); +#if (defined(__GNUC__) || defined(__llvm__)) && (defined(__i386__) || defined(__x86_64__)) + __asm__(".byte 0x0f, 0x01, 0xd0" + : "=a"(a) + : "c"(0) + : "%edx"); #elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) && (_MSC_FULL_VER >= 160040219) /* VS2010 SP1 */ a = (int)_xgetbv(0); #elif (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__) __asm - { + { xor ecx, ecx _asm _emit 0x0f _asm _emit 0x01 _asm _emit 0xd0 mov a, eax - } + } #endif CPU_OSSavesYMM = ((a & 6) == 6) ? SDL_TRUE : SDL_FALSE; CPU_OSSavesZMM = (CPU_OSSavesYMM && ((a & 0xe0) == 0xe0)) ? SDL_TRUE : SDL_FALSE; @@ -309,8 +331,7 @@ CPU_calcCPUIDFeatures(void) } } -static int -CPU_haveAltiVec(void) +static int CPU_haveAltiVec(void) { volatile int altivec = 0; #ifndef SDL_CPUINFO_DISABLED @@ -323,13 +344,20 @@ CPU_haveAltiVec(void) int hasVectorUnit = 0; size_t length = sizeof(hasVectorUnit); int error = sysctl(selectors, 2, &hasVectorUnit, &length, NULL, 0); - if (0 == error) + if (0 == error) { altivec = (hasVectorUnit != 0); -#elif SDL_ALTIVEC_BLITTERS && HAVE_SETJMP - void (*handler) (int sig); + } +#elif defined(__FreeBSD__) && defined(__powerpc__) + unsigned long cpufeatures = 0; + elf_aux_info(AT_HWCAP, &cpufeatures, sizeof(cpufeatures)); + altivec = cpufeatures & PPC_FEATURE_HAS_ALTIVEC; + return altivec; +#elif defined(SDL_ALTIVEC_BLITTERS) && defined(HAVE_SETJMP) + void (*handler)(int sig); handler = signal(SIGILL, illegal_instruction); if (setjmp(jmpbuf) == 0) { - asm volatile ("mtspr 256, %0\n\t" "vand %%v0, %%v0, %%v0"::"r" (-1)); + asm volatile("mtspr 256, %0\n\t" + "vand %%v0, %%v0, %%v0" ::"r"(-1)); altivec = 1; } signal(SIGILL, handler); @@ -338,45 +366,33 @@ CPU_haveAltiVec(void) return altivec; } -#if defined(__ARM_ARCH) && (__ARM_ARCH >= 6) -static int -CPU_haveARMSIMD(void) +#if (defined(__ARM_ARCH) && (__ARM_ARCH >= 6)) || defined(__aarch64__) +static int CPU_haveARMSIMD(void) { - return 1; + return 1; } #elif !defined(__arm__) -static int -CPU_haveARMSIMD(void) +static int CPU_haveARMSIMD(void) { - return 0; + return 0; } #elif defined(__LINUX__) -#include -#include -#include -#include -#include - -static int -CPU_haveARMSIMD(void) +static int CPU_haveARMSIMD(void) { int arm_simd = 0; int fd; - fd = open("/proc/self/auxv", O_RDONLY); - if (fd >= 0) - { + fd = open("/proc/self/auxv", O_RDONLY | O_CLOEXEC); + if (fd >= 0) { Elf32_auxv_t aux; - while (read(fd, &aux, sizeof aux) == sizeof aux) - { - if (aux.a_type == AT_PLATFORM) - { - const char *plat = (const char *) aux.a_un.a_val; + while (read(fd, &aux, sizeof(aux)) == sizeof(aux)) { + if (aux.a_type == AT_PLATFORM) { + const char *plat = (const char *)aux.a_un.a_val; if (plat) { - arm_simd = strncmp(plat, "v6l", 3) == 0 || - strncmp(plat, "v7l", 3) == 0; + arm_simd = SDL_strncmp(plat, "v6l", 3) == 0 || + SDL_strncmp(plat, "v7l", 3) == 0; } } } @@ -386,46 +402,47 @@ CPU_haveARMSIMD(void) } #elif defined(__RISCOS__) - -static int -CPU_haveARMSIMD(void) +static int CPU_haveARMSIMD(void) { - _kernel_swi_regs regs; - regs.r[0] = 0; - if (_kernel_swi(OS_PlatformFeatures, ®s, ®s) != NULL) - return 0; + _kernel_swi_regs regs; + regs.r[0] = 0; + if (_kernel_swi(OS_PlatformFeatures, ®s, ®s) != NULL) { + return 0; + } - if (!(regs.r[0] & (1<<31))) - return 0; + if (!(regs.r[0] & (1 << 31))) { + return 0; + } - regs.r[0] = 34; - regs.r[1] = 29; - if (_kernel_swi(OS_PlatformFeatures, ®s, ®s) != NULL) - return 0; + regs.r[0] = 34; + regs.r[1] = 29; + if (_kernel_swi(OS_PlatformFeatures, ®s, ®s) != NULL) { + return 0; + } - return regs.r[0]; + return regs.r[0]; } #else -static int -CPU_haveARMSIMD(void) +static int CPU_haveARMSIMD(void) { #warning SDL_HasARMSIMD is not implemented for this ARM platform. Write me. return 0; } #endif -#if defined(__LINUX__) && defined(__ARM_ARCH) && !defined(HAVE_GETAUXVAL) -static int -readProcAuxvForNeon(void) +#if defined(__LINUX__) && defined(__arm__) && !defined(HAVE_GETAUXVAL) +static int readProcAuxvForNeon(void) { int neon = 0; - int kv[2]; - const int fd = open("/proc/self/auxv", O_RDONLY); - if (fd != -1) { - while (read(fd, kv, sizeof (kv)) == sizeof (kv)) { - if (kv[0] == AT_HWCAP) { - neon = ((kv[1] & HWCAP_NEON) == HWCAP_NEON); + int fd; + + fd = open("/proc/self/auxv", O_RDONLY | O_CLOEXEC); + if (fd >= 0) { + Elf32_auxv_t aux; + while (read(fd, &aux, sizeof(aux)) == sizeof(aux)) { + if (aux.a_type == AT_HWCAP) { + neon = (aux.a_un.a_val & HWCAP_NEON) == HWCAP_NEON; break; } } @@ -435,34 +452,45 @@ readProcAuxvForNeon(void) } #endif -static int -CPU_haveNEON(void) +static int CPU_haveNEON(void) { /* The way you detect NEON is a privileged instruction on ARM, so you have query the OS kernel in a platform-specific way. :/ */ #if defined(SDL_CPUINFO_DISABLED) - return 0; /* disabled */ -#elif (defined(__WINDOWS__) || defined(__WINRT__)) && (defined(_M_ARM) || defined(_M_ARM64)) + return 0; /* disabled */ +#elif (defined(__WINDOWS__) || defined(__WINRT__) || defined(__GDK__)) && (defined(_M_ARM) || defined(_M_ARM64)) /* Visual Studio, for ARM, doesn't define __ARM_ARCH. Handle this first. */ /* Seems to have been removed */ -# if !defined(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE) -# define PF_ARM_NEON_INSTRUCTIONS_AVAILABLE 19 -# endif -/* All WinRT ARM devices are required to support NEON, but just in case. */ +#if !defined(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE) +#define PF_ARM_NEON_INSTRUCTIONS_AVAILABLE 19 +#endif + /* All WinRT ARM devices are required to support NEON, but just in case. */ return IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE) != 0; -#elif defined(__ARM_ARCH) && (__ARM_ARCH >= 8) - return 1; /* ARMv8 always has non-optional NEON support. */ +#elif (defined(__ARM_ARCH) && (__ARM_ARCH >= 8)) || defined(__aarch64__) + return 1; /* ARMv8 always has non-optional NEON support. */ +#elif defined(__VITA__) + return 1; +#elif defined(__3DS__) + return 0; #elif defined(__APPLE__) && defined(__ARM_ARCH) && (__ARM_ARCH >= 7) /* (note that sysctlbyname("hw.optional.neon") doesn't work!) */ - return 1; /* all Apple ARMv7 chips and later have NEON. */ + return 1; /* all Apple ARMv7 chips and later have NEON. */ #elif defined(__APPLE__) - return 0; /* assume anything else from Apple doesn't have NEON. */ + return 0; /* assume anything else from Apple doesn't have NEON. */ #elif !defined(__arm__) - return 0; /* not an ARM CPU at all. */ + return 0; /* not an ARM CPU at all. */ +#elif defined(__OpenBSD__) + return 1; /* OpenBSD only supports ARMv7 CPUs that have NEON. */ +#elif defined(HAVE_ELF_AUX_INFO) + unsigned long hasneon = 0; + if (elf_aux_info(AT_HWCAP, (void *)&hasneon, (int)sizeof(hasneon)) != 0) { + return 0; + } + return ((hasneon & HWCAP_NEON) == HWCAP_NEON); #elif defined(__QNXNTO__) return SYSPAGE_ENTRY(cpuinfo)->flags & ARM_CPU_FLAG_NEON; #elif (defined(__LINUX__) || defined(__ANDROID__)) && defined(HAVE_GETAUXVAL) - return ((getauxval(AT_HWCAP) & HWCAP_NEON) == HWCAP_NEON); + return (getauxval(AT_HWCAP) & HWCAP_NEON) == HWCAP_NEON; #elif defined(__LINUX__) return readProcAuxvForNeon(); #elif defined(__ANDROID__) @@ -471,7 +499,7 @@ CPU_haveNEON(void) AndroidCpuFamily cpu_family = android_getCpuFamily(); if (cpu_family == ANDROID_CPU_FAMILY_ARM) { uint64_t cpu_features = android_getCpuFeatures(); - if ((cpu_features & ANDROID_CPU_ARM_FEATURE_NEON) != 0) { + if (cpu_features & ANDROID_CPU_ARM_FEATURE_NEON) { return 1; } } @@ -481,7 +509,7 @@ CPU_haveNEON(void) /* Use the VFPSupport_Features SWI to access the MVFR registers */ { _kernel_swi_regs regs; - regs.r[0] = 0; + regs.r[0] = 0; if (_kernel_swi(VFPSupport_Features, ®s, ®s) == NULL) { if ((regs.r[2] & 0xFFF000) == 0x111000) { return 1; @@ -495,57 +523,145 @@ CPU_haveNEON(void) #endif } -static int +static int CPU_readCPUCFG(void) +{ + uint32_t cfg2 = 0; +#if defined __loongarch__ + __asm__ volatile( + "cpucfg %0, %1 \n\t" + : "+&r"(cfg2) + : "r"(CPU_CFG2)); +#endif + return cfg2; +} + +#define CPU_haveLSX() (CPU_readCPUCFG() & CPU_CFG2_LSX) +#define CPU_haveLASX() (CPU_readCPUCFG() & CPU_CFG2_LASX) + +#if defined(__e2k__) +inline int CPU_have3DNow(void) { - if (CPU_CPUIDMaxFunction > 0) { /* that is, do we have CPUID at all? */ +#if defined(__3dNOW__) + return 1; +#else + return 0; +#endif +} +#else +static int CPU_have3DNow(void) +{ + if (CPU_CPUIDMaxFunction > 0) { /* that is, do we have CPUID at all? */ int a, b, c, d; cpuid(0x80000000, a, b, c, d); if (a >= 0x80000001) { cpuid(0x80000001, a, b, c, d); - return (d & 0x80000000); + return d & 0x80000000; } } return 0; } +#endif +#if defined(__e2k__) +#define CPU_haveRDTSC() (0) +#if defined(__MMX__) +#define CPU_haveMMX() (1) +#else +#define CPU_haveMMX() (0) +#endif +#if defined(__SSE__) +#define CPU_haveSSE() (1) +#else +#define CPU_haveSSE() (0) +#endif +#if defined(__SSE2__) +#define CPU_haveSSE2() (1) +#else +#define CPU_haveSSE2() (0) +#endif +#if defined(__SSE3__) +#define CPU_haveSSE3() (1) +#else +#define CPU_haveSSE3() (0) +#endif +#if defined(__SSE4_1__) +#define CPU_haveSSE41() (1) +#else +#define CPU_haveSSE41() (0) +#endif +#if defined(__SSE4_2__) +#define CPU_haveSSE42() (1) +#else +#define CPU_haveSSE42() (0) +#endif +#if defined(__AVX__) +#define CPU_haveAVX() (1) +#else +#define CPU_haveAVX() (0) +#endif +#else #define CPU_haveRDTSC() (CPU_CPUIDFeatures[3] & 0x00000010) -#define CPU_haveMMX() (CPU_CPUIDFeatures[3] & 0x00800000) -#define CPU_haveSSE() (CPU_CPUIDFeatures[3] & 0x02000000) -#define CPU_haveSSE2() (CPU_CPUIDFeatures[3] & 0x04000000) -#define CPU_haveSSE3() (CPU_CPUIDFeatures[2] & 0x00000001) +#define CPU_haveMMX() (CPU_CPUIDFeatures[3] & 0x00800000) +#define CPU_haveSSE() (CPU_CPUIDFeatures[3] & 0x02000000) +#define CPU_haveSSE2() (CPU_CPUIDFeatures[3] & 0x04000000) +#define CPU_haveSSE3() (CPU_CPUIDFeatures[2] & 0x00000001) #define CPU_haveSSE41() (CPU_CPUIDFeatures[2] & 0x00080000) #define CPU_haveSSE42() (CPU_CPUIDFeatures[2] & 0x00100000) -#define CPU_haveAVX() (CPU_OSSavesYMM && (CPU_CPUIDFeatures[2] & 0x10000000)) +#define CPU_haveAVX() (CPU_OSSavesYMM && (CPU_CPUIDFeatures[2] & 0x10000000)) +#endif -static int +#if defined(__e2k__) +inline int CPU_haveAVX2(void) +{ +#if defined(__AVX2__) + return 1; +#else + return 0; +#endif +} +#else +static int CPU_haveAVX2(void) { if (CPU_OSSavesYMM && (CPU_CPUIDMaxFunction >= 7)) { int a, b, c, d; - (void) a; (void) b; (void) c; (void) d; /* compiler warnings... */ + (void)a; + (void)b; + (void)c; + (void)d; /* compiler warnings... */ cpuid(7, a, b, c, d); - return (b & 0x00000020); + return b & 0x00000020; } return 0; } +#endif -static int +#if defined(__e2k__) +inline int CPU_haveAVX512F(void) +{ + return 0; +} +#else +static int CPU_haveAVX512F(void) { if (CPU_OSSavesZMM && (CPU_CPUIDMaxFunction >= 7)) { int a, b, c, d; - (void) a; (void) b; (void) c; (void) d; /* compiler warnings... */ + (void)a; + (void)b; + (void)c; + (void)d; /* compiler warnings... */ cpuid(7, a, b, c, d); - return (b & 0x00010000); + return b & 0x00010000; } return 0; } +#endif static int SDL_CPUCount = 0; -int -SDL_GetCPUCount(void) +int SDL_GetCPUCount(void) { if (!SDL_CPUCount) { #ifndef SDL_CPUINFO_DISABLED @@ -560,7 +676,7 @@ SDL_GetCPUCount(void) sysctlbyname("hw.ncpu", &SDL_CPUCount, &size, NULL, 0); } #endif -#ifdef __WIN32__ +#if defined(__WIN32__) || defined(__GDK__) if (SDL_CPUCount <= 0) { SYSTEM_INFO info; GetSystemInfo(&info); @@ -582,33 +698,52 @@ SDL_GetCPUCount(void) return SDL_CPUCount; } -/* Oh, such a sweet sweet trick, just not very useful. :) */ -static const char * +#if defined(__e2k__) +inline const char * SDL_GetCPUType(void) { static char SDL_CPUType[13]; + SDL_strlcpy(SDL_CPUType, "E2K MACHINE", sizeof(SDL_CPUType)); + + return SDL_CPUType; +} +#else +/* Oh, such a sweet sweet trick, just not very useful. :) */ +static const char *SDL_GetCPUType(void) +{ + static char SDL_CPUType[13]; + if (!SDL_CPUType[0]) { int i = 0; CPU_calcCPUIDFeatures(); - if (CPU_CPUIDMaxFunction > 0) { /* do we have CPUID at all? */ + if (CPU_CPUIDMaxFunction > 0) { /* do we have CPUID at all? */ int a, b, c, d; cpuid(0x00000000, a, b, c, d); - (void) a; - SDL_CPUType[i++] = (char)(b & 0xff); b >>= 8; - SDL_CPUType[i++] = (char)(b & 0xff); b >>= 8; - SDL_CPUType[i++] = (char)(b & 0xff); b >>= 8; + (void)a; + SDL_CPUType[i++] = (char)(b & 0xff); + b >>= 8; + SDL_CPUType[i++] = (char)(b & 0xff); + b >>= 8; + SDL_CPUType[i++] = (char)(b & 0xff); + b >>= 8; SDL_CPUType[i++] = (char)(b & 0xff); - SDL_CPUType[i++] = (char)(d & 0xff); d >>= 8; - SDL_CPUType[i++] = (char)(d & 0xff); d >>= 8; - SDL_CPUType[i++] = (char)(d & 0xff); d >>= 8; + SDL_CPUType[i++] = (char)(d & 0xff); + d >>= 8; + SDL_CPUType[i++] = (char)(d & 0xff); + d >>= 8; + SDL_CPUType[i++] = (char)(d & 0xff); + d >>= 8; SDL_CPUType[i++] = (char)(d & 0xff); - SDL_CPUType[i++] = (char)(c & 0xff); c >>= 8; - SDL_CPUType[i++] = (char)(c & 0xff); c >>= 8; - SDL_CPUType[i++] = (char)(c & 0xff); c >>= 8; + SDL_CPUType[i++] = (char)(c & 0xff); + c >>= 8; + SDL_CPUType[i++] = (char)(c & 0xff); + c >>= 8; + SDL_CPUType[i++] = (char)(c & 0xff); + c >>= 8; SDL_CPUType[i++] = (char)(c & 0xff); } if (!SDL_CPUType[0]) { @@ -617,73 +752,131 @@ SDL_GetCPUType(void) } return SDL_CPUType; } +#endif - -#ifdef TEST_MAIN /* !!! FIXME: only used for test at the moment. */ -static const char * +#ifdef TEST_MAIN /* !!! FIXME: only used for test at the moment. */ +#if defined(__e2k__) +inline const char * SDL_GetCPUName(void) { static char SDL_CPUName[48]; + SDL_strlcpy(SDL_CPUName, __builtin_cpu_name(), sizeof(SDL_CPUName)); + + return SDL_CPUName; +} +#else +static const char *SDL_GetCPUName(void) +{ + static char SDL_CPUName[48]; + if (!SDL_CPUName[0]) { int i = 0; int a, b, c, d; CPU_calcCPUIDFeatures(); - if (CPU_CPUIDMaxFunction > 0) { /* do we have CPUID at all? */ + if (CPU_CPUIDMaxFunction > 0) { /* do we have CPUID at all? */ cpuid(0x80000000, a, b, c, d); if (a >= 0x80000004) { cpuid(0x80000002, a, b, c, d); - SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8; - SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8; - SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8; - SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8; - SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8; - SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8; - SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8; - SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8; - SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8; - SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8; - SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8; - SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8; - SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8; - SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8; - SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8; - SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8; + SDL_CPUName[i++] = (char)(a & 0xff); + a >>= 8; + SDL_CPUName[i++] = (char)(a & 0xff); + a >>= 8; + SDL_CPUName[i++] = (char)(a & 0xff); + a >>= 8; + SDL_CPUName[i++] = (char)(a & 0xff); + a >>= 8; + SDL_CPUName[i++] = (char)(b & 0xff); + b >>= 8; + SDL_CPUName[i++] = (char)(b & 0xff); + b >>= 8; + SDL_CPUName[i++] = (char)(b & 0xff); + b >>= 8; + SDL_CPUName[i++] = (char)(b & 0xff); + b >>= 8; + SDL_CPUName[i++] = (char)(c & 0xff); + c >>= 8; + SDL_CPUName[i++] = (char)(c & 0xff); + c >>= 8; + SDL_CPUName[i++] = (char)(c & 0xff); + c >>= 8; + SDL_CPUName[i++] = (char)(c & 0xff); + c >>= 8; + SDL_CPUName[i++] = (char)(d & 0xff); + d >>= 8; + SDL_CPUName[i++] = (char)(d & 0xff); + d >>= 8; + SDL_CPUName[i++] = (char)(d & 0xff); + d >>= 8; + SDL_CPUName[i++] = (char)(d & 0xff); + d >>= 8; cpuid(0x80000003, a, b, c, d); - SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8; - SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8; - SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8; - SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8; - SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8; - SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8; - SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8; - SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8; - SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8; - SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8; - SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8; - SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8; - SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8; - SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8; - SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8; - SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8; + SDL_CPUName[i++] = (char)(a & 0xff); + a >>= 8; + SDL_CPUName[i++] = (char)(a & 0xff); + a >>= 8; + SDL_CPUName[i++] = (char)(a & 0xff); + a >>= 8; + SDL_CPUName[i++] = (char)(a & 0xff); + a >>= 8; + SDL_CPUName[i++] = (char)(b & 0xff); + b >>= 8; + SDL_CPUName[i++] = (char)(b & 0xff); + b >>= 8; + SDL_CPUName[i++] = (char)(b & 0xff); + b >>= 8; + SDL_CPUName[i++] = (char)(b & 0xff); + b >>= 8; + SDL_CPUName[i++] = (char)(c & 0xff); + c >>= 8; + SDL_CPUName[i++] = (char)(c & 0xff); + c >>= 8; + SDL_CPUName[i++] = (char)(c & 0xff); + c >>= 8; + SDL_CPUName[i++] = (char)(c & 0xff); + c >>= 8; + SDL_CPUName[i++] = (char)(d & 0xff); + d >>= 8; + SDL_CPUName[i++] = (char)(d & 0xff); + d >>= 8; + SDL_CPUName[i++] = (char)(d & 0xff); + d >>= 8; + SDL_CPUName[i++] = (char)(d & 0xff); + d >>= 8; cpuid(0x80000004, a, b, c, d); - SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8; - SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8; - SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8; - SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8; - SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8; - SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8; - SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8; - SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8; - SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8; - SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8; - SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8; - SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8; - SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8; - SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8; - SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8; - SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8; + SDL_CPUName[i++] = (char)(a & 0xff); + a >>= 8; + SDL_CPUName[i++] = (char)(a & 0xff); + a >>= 8; + SDL_CPUName[i++] = (char)(a & 0xff); + a >>= 8; + SDL_CPUName[i++] = (char)(a & 0xff); + a >>= 8; + SDL_CPUName[i++] = (char)(b & 0xff); + b >>= 8; + SDL_CPUName[i++] = (char)(b & 0xff); + b >>= 8; + SDL_CPUName[i++] = (char)(b & 0xff); + b >>= 8; + SDL_CPUName[i++] = (char)(b & 0xff); + b >>= 8; + SDL_CPUName[i++] = (char)(c & 0xff); + c >>= 8; + SDL_CPUName[i++] = (char)(c & 0xff); + c >>= 8; + SDL_CPUName[i++] = (char)(c & 0xff); + c >>= 8; + SDL_CPUName[i++] = (char)(c & 0xff); + c >>= 8; + SDL_CPUName[i++] = (char)(d & 0xff); + d >>= 8; + SDL_CPUName[i++] = (char)(d & 0xff); + d >>= 8; + SDL_CPUName[i++] = (char)(d & 0xff); + d >>= 8; + SDL_CPUName[i++] = (char)(d & 0xff); + d >>= 8; } } if (!SDL_CPUName[0]) { @@ -693,19 +886,22 @@ SDL_GetCPUName(void) return SDL_CPUName; } #endif +#endif -int -SDL_GetCPUCacheLineSize(void) +int SDL_GetCPUCacheLineSize(void) { const char *cpuType = SDL_GetCPUType(); int a, b, c, d; - (void) a; (void) b; (void) c; (void) d; - if (SDL_strcmp(cpuType, "GenuineIntel") == 0) { + (void)a; + (void)b; + (void)c; + (void)d; + if (SDL_strcmp(cpuType, "GenuineIntel") == 0 || SDL_strcmp(cpuType, "CentaurHauls") == 0 || SDL_strcmp(cpuType, " Shanghai ") == 0) { cpuid(0x00000001, a, b, c, d); - return (((b >> 8) & 0xff) * 8); + return ((b >> 8) & 0xff) * 8; } else if (SDL_strcmp(cpuType, "AuthenticAMD") == 0 || SDL_strcmp(cpuType, "HygonGenuine") == 0) { cpuid(0x80000005, a, b, c, d); - return (c & 0xff); + return c & 0xff; } else { /* Just make a guess here... */ return SDL_CACHELINE_SIZE; @@ -715,13 +911,12 @@ SDL_GetCPUCacheLineSize(void) static Uint32 SDL_CPUFeatures = 0xFFFFFFFF; static Uint32 SDL_SIMDAlignment = 0xFFFFFFFF; -static Uint32 -SDL_GetCPUFeatures(void) +static Uint32 SDL_GetCPUFeatures(void) { if (SDL_CPUFeatures == 0xFFFFFFFF) { CPU_calcCPUIDFeatures(); SDL_CPUFeatures = 0; - SDL_SIMDAlignment = sizeof(void *); /* a good safe base value */ + SDL_SIMDAlignment = sizeof(void *); /* a good safe base value */ if (CPU_haveRDTSC()) { SDL_CPUFeatures |= CPU_HAS_RDTSC; } @@ -777,6 +972,14 @@ SDL_GetCPUFeatures(void) SDL_CPUFeatures |= CPU_HAS_NEON; SDL_SIMDAlignment = SDL_max(SDL_SIMDAlignment, 16); } + if (CPU_haveLSX()) { + SDL_CPUFeatures |= CPU_HAS_LSX; + SDL_SIMDAlignment = SDL_max(SDL_SIMDAlignment, 16); + } + if (CPU_haveLASX()) { + SDL_CPUFeatures |= CPU_HAS_LASX; + SDL_SIMDAlignment = SDL_max(SDL_SIMDAlignment, 32); + } } return SDL_CPUFeatures; } @@ -788,117 +991,116 @@ SDL_bool SDL_HasRDTSC(void) return CPU_FEATURE_AVAILABLE(CPU_HAS_RDTSC); } -SDL_bool -SDL_HasAltiVec(void) +SDL_bool SDL_HasAltiVec(void) { return CPU_FEATURE_AVAILABLE(CPU_HAS_ALTIVEC); } -SDL_bool -SDL_HasMMX(void) +SDL_bool SDL_HasMMX(void) { return CPU_FEATURE_AVAILABLE(CPU_HAS_MMX); } -SDL_bool -SDL_Has3DNow(void) +SDL_bool SDL_Has3DNow(void) { return CPU_FEATURE_AVAILABLE(CPU_HAS_3DNOW); } -SDL_bool -SDL_HasSSE(void) +SDL_bool SDL_HasSSE(void) { return CPU_FEATURE_AVAILABLE(CPU_HAS_SSE); } -SDL_bool -SDL_HasSSE2(void) +SDL_bool SDL_HasSSE2(void) { return CPU_FEATURE_AVAILABLE(CPU_HAS_SSE2); } -SDL_bool -SDL_HasSSE3(void) +SDL_bool SDL_HasSSE3(void) { return CPU_FEATURE_AVAILABLE(CPU_HAS_SSE3); } -SDL_bool -SDL_HasSSE41(void) +SDL_bool SDL_HasSSE41(void) { return CPU_FEATURE_AVAILABLE(CPU_HAS_SSE41); } -SDL_bool -SDL_HasSSE42(void) +SDL_bool SDL_HasSSE42(void) { return CPU_FEATURE_AVAILABLE(CPU_HAS_SSE42); } -SDL_bool -SDL_HasAVX(void) +SDL_bool SDL_HasAVX(void) { return CPU_FEATURE_AVAILABLE(CPU_HAS_AVX); } -SDL_bool -SDL_HasAVX2(void) +SDL_bool SDL_HasAVX2(void) { return CPU_FEATURE_AVAILABLE(CPU_HAS_AVX2); } -SDL_bool -SDL_HasAVX512F(void) +SDL_bool SDL_HasAVX512F(void) { return CPU_FEATURE_AVAILABLE(CPU_HAS_AVX512F); } -SDL_bool -SDL_HasARMSIMD(void) +SDL_bool SDL_HasARMSIMD(void) { return CPU_FEATURE_AVAILABLE(CPU_HAS_ARM_SIMD); } -SDL_bool -SDL_HasNEON(void) +SDL_bool SDL_HasNEON(void) { return CPU_FEATURE_AVAILABLE(CPU_HAS_NEON); } +SDL_bool SDL_HasLSX(void) +{ + return CPU_FEATURE_AVAILABLE(CPU_HAS_LSX); +} + +SDL_bool SDL_HasLASX(void) +{ + return CPU_FEATURE_AVAILABLE(CPU_HAS_LASX); +} + static int SDL_SystemRAM = 0; -int -SDL_GetSystemRAM(void) +int SDL_GetSystemRAM(void) { if (!SDL_SystemRAM) { #ifndef SDL_CPUINFO_DISABLED #if defined(HAVE_SYSCONF) && defined(_SC_PHYS_PAGES) && defined(_SC_PAGESIZE) if (SDL_SystemRAM <= 0) { - SDL_SystemRAM = (int)((Sint64)sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE) / (1024*1024)); + SDL_SystemRAM = (int)((Sint64)sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE) / (1024 * 1024)); } #endif #ifdef HAVE_SYSCTLBYNAME if (SDL_SystemRAM <= 0) { -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) -#ifdef HW_REALMEM - int mib[2] = {CTL_HW, HW_REALMEM}; +#ifdef HW_PHYSMEM64 + /* (64-bit): NetBSD since 2003, OpenBSD */ + int mib[2] = { CTL_HW, HW_PHYSMEM64 }; +#elif defined(HW_REALMEM) + /* (64-bit): FreeBSD since 2005, DragonFly */ + int mib[2] = { CTL_HW, HW_REALMEM }; +#elif defined(HW_MEMSIZE) + /* (64-bit): Darwin */ + int mib[2] = { CTL_HW, HW_MEMSIZE }; #else - /* might only report up to 2 GiB */ - int mib[2] = {CTL_HW, HW_PHYSMEM}; -#endif /* HW_REALMEM */ -#else - int mib[2] = {CTL_HW, HW_MEMSIZE}; -#endif /* __FreeBSD__ || __FreeBSD_kernel__ */ + /* (32-bit): very old BSD, might only report up to 2 GiB */ + int mib[2] = { CTL_HW, HW_PHYSMEM }; +#endif /* HW_PHYSMEM64 */ Uint64 memsize = 0; size_t len = sizeof(memsize); - + if (sysctl(mib, 2, &memsize, &len, NULL, 0) == 0) { - SDL_SystemRAM = (int)(memsize / (1024*1024)); + SDL_SystemRAM = (int)(memsize / (1024 * 1024)); } } #endif -#ifdef __WIN32__ +#if defined(__WIN32__) || defined(__GDK__) if (SDL_SystemRAM <= 0) { MEMORYSTATUSEX stat; stat.dwLength = sizeof(stat); @@ -923,56 +1125,121 @@ SDL_GetSystemRAM(void) } } #endif +#ifdef __VITA__ + if (SDL_SystemRAM <= 0) { + /* Vita has 512MiB on SoC, that's split into 256MiB(+109MiB in extended memory mode) for app + +26MiB of physically continuous memory, +112MiB of CDRAM(VRAM) + system reserved memory. */ + SDL_SystemRAM = 536870912; + } +#endif +#ifdef __PS2__ + if (SDL_SystemRAM <= 0) { + /* PlayStation 2 has 32MiB however there are some special models with 64 and 128 */ + SDL_SystemRAM = GetMemorySize(); + } +#endif #endif } return SDL_SystemRAM; } - -size_t -SDL_SIMDGetAlignment(void) +size_t SDL_SIMDGetAlignment(void) { if (SDL_SIMDAlignment == 0xFFFFFFFF) { - SDL_GetCPUFeatures(); /* make sure this has been calculated */ + SDL_GetCPUFeatures(); /* make sure this has been calculated */ } SDL_assert(SDL_SIMDAlignment != 0); return SDL_SIMDAlignment; } -void * -SDL_SIMDAlloc(const size_t len) +void *SDL_SIMDAlloc(const size_t len) { const size_t alignment = SDL_SIMDGetAlignment(); - const size_t padding = alignment - (len % alignment); - const size_t padded = (padding != alignment) ? (len + padding) : len; + const size_t padding = (alignment - (len % alignment)) % alignment; Uint8 *retval = NULL; - Uint8 *ptr = (Uint8 *) SDL_malloc(padded + alignment + sizeof (void *)); + Uint8 *ptr; + size_t to_allocate; + + /* alignment + padding + sizeof(void *) is bounded (a few hundred + * bytes max), so no need to check for overflow within that argument */ + if (SDL_size_add_overflow(len, alignment + padding + sizeof(void *), &to_allocate)) { + return NULL; + } + + ptr = (Uint8 *)SDL_malloc(to_allocate); if (ptr) { - /* store the actual malloc pointer right before our aligned pointer. */ - retval = ptr + sizeof (void *); - retval += alignment - (((size_t) retval) % alignment); - *(((void **) retval) - 1) = ptr; + /* store the actual allocated pointer right before our aligned pointer. */ + retval = ptr + sizeof(void *); + retval += alignment - (((size_t)retval) % alignment); + *(((void **)retval) - 1) = ptr; } return retval; } -void -SDL_SIMDFree(void *ptr) +void *SDL_SIMDRealloc(void *mem, const size_t len) { - if (ptr) { - void **realptr = (void **) ptr; - realptr--; - SDL_free(*(((void **) ptr) - 1)); + const size_t alignment = SDL_SIMDGetAlignment(); + const size_t padding = (alignment - (len % alignment)) % alignment; + Uint8 *retval = (Uint8 *)mem; + void *oldmem = mem; + size_t memdiff = 0, ptrdiff; + Uint8 *ptr; + size_t to_allocate; + + /* alignment + padding + sizeof(void *) is bounded (a few hundred + * bytes max), so no need to check for overflow within that argument */ + if (SDL_size_add_overflow(len, alignment + padding + sizeof(void *), &to_allocate)) { + return NULL; } + + if (mem) { + mem = *(((void **)mem) - 1); + + /* Check the delta between the real pointer and user pointer */ + memdiff = ((size_t)oldmem) - ((size_t)mem); + } + + ptr = (Uint8 *)SDL_realloc(mem, to_allocate); + + if (!ptr) { + return NULL; /* Out of memory, bail! */ + } + + /* Store the actual allocated pointer right before our aligned pointer. */ + retval = ptr + sizeof(void *); + retval += alignment - (((size_t)retval) % alignment); + + /* Make sure the delta is the same! */ + if (mem) { + ptrdiff = ((size_t)retval) - ((size_t)ptr); + if (memdiff != ptrdiff) { /* Delta has changed, copy to new offset! */ + oldmem = (void *)(((uintptr_t)ptr) + memdiff); + + /* Even though the data past the old `len` is undefined, this is the + * only length value we have, and it guarantees that we copy all the + * previous memory anyhow. + */ + SDL_memmove(retval, oldmem, len); + } + } + + /* Actually store the allocated pointer, finally. */ + *(((void **)retval) - 1) = ptr; + return retval; } +void SDL_SIMDFree(void *ptr) +{ + if (ptr) { + SDL_free(*(((void **)ptr) - 1)); + } +} #ifdef TEST_MAIN #include -int -main() +int main() { printf("CPU count: %d\n", SDL_GetCPUCount()); printf("CPU type: %s\n", SDL_GetCPUType()); @@ -992,6 +1259,8 @@ main() printf("AVX-512F: %d\n", SDL_HasAVX512F()); printf("ARM SIMD: %d\n", SDL_HasARMSIMD()); printf("NEON: %d\n", SDL_HasNEON()); + printf("LSX: %d\n", SDL_HasLSX()); + printf("LASX: %d\n", SDL_HasLASX()); printf("RAM: %d MB\n", SDL_GetSystemRAM()); return 0; } diff --git a/SDL2-2.30.5/src/dynapi/SDL2.exports b/SDL2-2.30.5/src/dynapi/SDL2.exports new file mode 100644 index 0000000..5b67182 --- /dev/null +++ b/SDL2-2.30.5/src/dynapi/SDL2.exports @@ -0,0 +1,874 @@ +# Windows exports file for Watcom +# DO NOT EDIT THIS FILE BY HAND. It is autogenerated by gendynapi.pl. +++'_SDL_DYNAPI_entry'.'SDL2.dll'.'SDL_DYNAPI_entry' +++'_SDL_SetError'.'SDL2.dll'.'SDL_SetError' +++'_SDL_Log'.'SDL2.dll'.'SDL_Log' +++'_SDL_LogVerbose'.'SDL2.dll'.'SDL_LogVerbose' +++'_SDL_LogDebug'.'SDL2.dll'.'SDL_LogDebug' +++'_SDL_LogInfo'.'SDL2.dll'.'SDL_LogInfo' +++'_SDL_LogWarn'.'SDL2.dll'.'SDL_LogWarn' +++'_SDL_LogError'.'SDL2.dll'.'SDL_LogError' +++'_SDL_LogCritical'.'SDL2.dll'.'SDL_LogCritical' +++'_SDL_LogMessage'.'SDL2.dll'.'SDL_LogMessage' +++'_SDL_sscanf'.'SDL2.dll'.'SDL_sscanf' +++'_SDL_snprintf'.'SDL2.dll'.'SDL_snprintf' +++'_SDL_CreateThread'.'SDL2.dll'.'SDL_CreateThread' +++'_SDL_RWFromFP'.'SDL2.dll'.'SDL_RWFromFP' +++'_SDL_RegisterApp'.'SDL2.dll'.'SDL_RegisterApp' +++'_SDL_UnregisterApp'.'SDL2.dll'.'SDL_UnregisterApp' +++'_SDL_Direct3D9GetAdapterIndex'.'SDL2.dll'.'SDL_Direct3D9GetAdapterIndex' +++'_SDL_RenderGetD3D9Device'.'SDL2.dll'.'SDL_RenderGetD3D9Device' +# ++'_SDL_iPhoneSetAnimationCallback'.'SDL2.dll'.'SDL_iPhoneSetAnimationCallback' +# ++'_SDL_iPhoneSetEventPump'.'SDL2.dll'.'SDL_iPhoneSetEventPump' +# ++'_SDL_AndroidGetJNIEnv'.'SDL2.dll'.'SDL_AndroidGetJNIEnv' +# ++'_SDL_AndroidGetActivity'.'SDL2.dll'.'SDL_AndroidGetActivity' +# ++'_SDL_AndroidGetInternalStoragePath'.'SDL2.dll'.'SDL_AndroidGetInternalStoragePath' +# ++'_SDL_AndroidGetExternalStorageState'.'SDL2.dll'.'SDL_AndroidGetExternalStorageState' +# ++'_SDL_AndroidGetExternalStoragePath'.'SDL2.dll'.'SDL_AndroidGetExternalStoragePath' +++'_SDL_Init'.'SDL2.dll'.'SDL_Init' +++'_SDL_InitSubSystem'.'SDL2.dll'.'SDL_InitSubSystem' +++'_SDL_QuitSubSystem'.'SDL2.dll'.'SDL_QuitSubSystem' +++'_SDL_WasInit'.'SDL2.dll'.'SDL_WasInit' +++'_SDL_Quit'.'SDL2.dll'.'SDL_Quit' +++'_SDL_ReportAssertion'.'SDL2.dll'.'SDL_ReportAssertion' +++'_SDL_SetAssertionHandler'.'SDL2.dll'.'SDL_SetAssertionHandler' +++'_SDL_GetAssertionReport'.'SDL2.dll'.'SDL_GetAssertionReport' +++'_SDL_ResetAssertionReport'.'SDL2.dll'.'SDL_ResetAssertionReport' +++'_SDL_AtomicTryLock'.'SDL2.dll'.'SDL_AtomicTryLock' +++'_SDL_AtomicLock'.'SDL2.dll'.'SDL_AtomicLock' +++'_SDL_AtomicUnlock'.'SDL2.dll'.'SDL_AtomicUnlock' +++'_SDL_AtomicCAS'.'SDL2.dll'.'SDL_AtomicCAS' +++'_SDL_AtomicSet'.'SDL2.dll'.'SDL_AtomicSet' +++'_SDL_AtomicGet'.'SDL2.dll'.'SDL_AtomicGet' +++'_SDL_AtomicAdd'.'SDL2.dll'.'SDL_AtomicAdd' +++'_SDL_AtomicCASPtr'.'SDL2.dll'.'SDL_AtomicCASPtr' +++'_SDL_AtomicSetPtr'.'SDL2.dll'.'SDL_AtomicSetPtr' +++'_SDL_AtomicGetPtr'.'SDL2.dll'.'SDL_AtomicGetPtr' +++'_SDL_GetNumAudioDrivers'.'SDL2.dll'.'SDL_GetNumAudioDrivers' +++'_SDL_GetAudioDriver'.'SDL2.dll'.'SDL_GetAudioDriver' +++'_SDL_AudioInit'.'SDL2.dll'.'SDL_AudioInit' +++'_SDL_AudioQuit'.'SDL2.dll'.'SDL_AudioQuit' +++'_SDL_GetCurrentAudioDriver'.'SDL2.dll'.'SDL_GetCurrentAudioDriver' +++'_SDL_OpenAudio'.'SDL2.dll'.'SDL_OpenAudio' +++'_SDL_GetNumAudioDevices'.'SDL2.dll'.'SDL_GetNumAudioDevices' +++'_SDL_GetAudioDeviceName'.'SDL2.dll'.'SDL_GetAudioDeviceName' +++'_SDL_OpenAudioDevice'.'SDL2.dll'.'SDL_OpenAudioDevice' +++'_SDL_GetAudioStatus'.'SDL2.dll'.'SDL_GetAudioStatus' +++'_SDL_GetAudioDeviceStatus'.'SDL2.dll'.'SDL_GetAudioDeviceStatus' +++'_SDL_PauseAudio'.'SDL2.dll'.'SDL_PauseAudio' +++'_SDL_PauseAudioDevice'.'SDL2.dll'.'SDL_PauseAudioDevice' +++'_SDL_LoadWAV_RW'.'SDL2.dll'.'SDL_LoadWAV_RW' +++'_SDL_FreeWAV'.'SDL2.dll'.'SDL_FreeWAV' +++'_SDL_BuildAudioCVT'.'SDL2.dll'.'SDL_BuildAudioCVT' +++'_SDL_ConvertAudio'.'SDL2.dll'.'SDL_ConvertAudio' +++'_SDL_MixAudio'.'SDL2.dll'.'SDL_MixAudio' +++'_SDL_MixAudioFormat'.'SDL2.dll'.'SDL_MixAudioFormat' +++'_SDL_LockAudio'.'SDL2.dll'.'SDL_LockAudio' +++'_SDL_LockAudioDevice'.'SDL2.dll'.'SDL_LockAudioDevice' +++'_SDL_UnlockAudio'.'SDL2.dll'.'SDL_UnlockAudio' +++'_SDL_UnlockAudioDevice'.'SDL2.dll'.'SDL_UnlockAudioDevice' +++'_SDL_CloseAudio'.'SDL2.dll'.'SDL_CloseAudio' +++'_SDL_CloseAudioDevice'.'SDL2.dll'.'SDL_CloseAudioDevice' +++'_SDL_SetClipboardText'.'SDL2.dll'.'SDL_SetClipboardText' +++'_SDL_GetClipboardText'.'SDL2.dll'.'SDL_GetClipboardText' +++'_SDL_HasClipboardText'.'SDL2.dll'.'SDL_HasClipboardText' +++'_SDL_GetCPUCount'.'SDL2.dll'.'SDL_GetCPUCount' +++'_SDL_GetCPUCacheLineSize'.'SDL2.dll'.'SDL_GetCPUCacheLineSize' +++'_SDL_HasRDTSC'.'SDL2.dll'.'SDL_HasRDTSC' +++'_SDL_HasAltiVec'.'SDL2.dll'.'SDL_HasAltiVec' +++'_SDL_HasMMX'.'SDL2.dll'.'SDL_HasMMX' +++'_SDL_Has3DNow'.'SDL2.dll'.'SDL_Has3DNow' +++'_SDL_HasSSE'.'SDL2.dll'.'SDL_HasSSE' +++'_SDL_HasSSE2'.'SDL2.dll'.'SDL_HasSSE2' +++'_SDL_HasSSE3'.'SDL2.dll'.'SDL_HasSSE3' +++'_SDL_HasSSE41'.'SDL2.dll'.'SDL_HasSSE41' +++'_SDL_HasSSE42'.'SDL2.dll'.'SDL_HasSSE42' +++'_SDL_GetSystemRAM'.'SDL2.dll'.'SDL_GetSystemRAM' +++'_SDL_GetError'.'SDL2.dll'.'SDL_GetError' +++'_SDL_ClearError'.'SDL2.dll'.'SDL_ClearError' +++'_SDL_Error'.'SDL2.dll'.'SDL_Error' +++'_SDL_PumpEvents'.'SDL2.dll'.'SDL_PumpEvents' +++'_SDL_PeepEvents'.'SDL2.dll'.'SDL_PeepEvents' +++'_SDL_HasEvent'.'SDL2.dll'.'SDL_HasEvent' +++'_SDL_HasEvents'.'SDL2.dll'.'SDL_HasEvents' +++'_SDL_FlushEvent'.'SDL2.dll'.'SDL_FlushEvent' +++'_SDL_FlushEvents'.'SDL2.dll'.'SDL_FlushEvents' +++'_SDL_PollEvent'.'SDL2.dll'.'SDL_PollEvent' +++'_SDL_WaitEvent'.'SDL2.dll'.'SDL_WaitEvent' +++'_SDL_WaitEventTimeout'.'SDL2.dll'.'SDL_WaitEventTimeout' +++'_SDL_PushEvent'.'SDL2.dll'.'SDL_PushEvent' +++'_SDL_SetEventFilter'.'SDL2.dll'.'SDL_SetEventFilter' +++'_SDL_GetEventFilter'.'SDL2.dll'.'SDL_GetEventFilter' +++'_SDL_AddEventWatch'.'SDL2.dll'.'SDL_AddEventWatch' +++'_SDL_DelEventWatch'.'SDL2.dll'.'SDL_DelEventWatch' +++'_SDL_FilterEvents'.'SDL2.dll'.'SDL_FilterEvents' +++'_SDL_EventState'.'SDL2.dll'.'SDL_EventState' +++'_SDL_RegisterEvents'.'SDL2.dll'.'SDL_RegisterEvents' +++'_SDL_GetBasePath'.'SDL2.dll'.'SDL_GetBasePath' +++'_SDL_GetPrefPath'.'SDL2.dll'.'SDL_GetPrefPath' +++'_SDL_GameControllerAddMapping'.'SDL2.dll'.'SDL_GameControllerAddMapping' +++'_SDL_GameControllerMappingForGUID'.'SDL2.dll'.'SDL_GameControllerMappingForGUID' +++'_SDL_GameControllerMapping'.'SDL2.dll'.'SDL_GameControllerMapping' +++'_SDL_IsGameController'.'SDL2.dll'.'SDL_IsGameController' +++'_SDL_GameControllerNameForIndex'.'SDL2.dll'.'SDL_GameControllerNameForIndex' +++'_SDL_GameControllerOpen'.'SDL2.dll'.'SDL_GameControllerOpen' +++'_SDL_GameControllerName'.'SDL2.dll'.'SDL_GameControllerName' +++'_SDL_GameControllerGetAttached'.'SDL2.dll'.'SDL_GameControllerGetAttached' +++'_SDL_GameControllerGetJoystick'.'SDL2.dll'.'SDL_GameControllerGetJoystick' +++'_SDL_GameControllerEventState'.'SDL2.dll'.'SDL_GameControllerEventState' +++'_SDL_GameControllerUpdate'.'SDL2.dll'.'SDL_GameControllerUpdate' +++'_SDL_GameControllerGetAxisFromString'.'SDL2.dll'.'SDL_GameControllerGetAxisFromString' +++'_SDL_GameControllerGetStringForAxis'.'SDL2.dll'.'SDL_GameControllerGetStringForAxis' +++'_SDL_GameControllerGetBindForAxis'.'SDL2.dll'.'SDL_GameControllerGetBindForAxis' +++'_SDL_GameControllerGetAxis'.'SDL2.dll'.'SDL_GameControllerGetAxis' +++'_SDL_GameControllerGetButtonFromString'.'SDL2.dll'.'SDL_GameControllerGetButtonFromString' +++'_SDL_GameControllerGetStringForButton'.'SDL2.dll'.'SDL_GameControllerGetStringForButton' +++'_SDL_GameControllerGetBindForButton'.'SDL2.dll'.'SDL_GameControllerGetBindForButton' +++'_SDL_GameControllerGetButton'.'SDL2.dll'.'SDL_GameControllerGetButton' +++'_SDL_GameControllerClose'.'SDL2.dll'.'SDL_GameControllerClose' +++'_SDL_RecordGesture'.'SDL2.dll'.'SDL_RecordGesture' +++'_SDL_SaveAllDollarTemplates'.'SDL2.dll'.'SDL_SaveAllDollarTemplates' +++'_SDL_SaveDollarTemplate'.'SDL2.dll'.'SDL_SaveDollarTemplate' +++'_SDL_LoadDollarTemplates'.'SDL2.dll'.'SDL_LoadDollarTemplates' +++'_SDL_NumHaptics'.'SDL2.dll'.'SDL_NumHaptics' +++'_SDL_HapticName'.'SDL2.dll'.'SDL_HapticName' +++'_SDL_HapticOpen'.'SDL2.dll'.'SDL_HapticOpen' +++'_SDL_HapticOpened'.'SDL2.dll'.'SDL_HapticOpened' +++'_SDL_HapticIndex'.'SDL2.dll'.'SDL_HapticIndex' +++'_SDL_MouseIsHaptic'.'SDL2.dll'.'SDL_MouseIsHaptic' +++'_SDL_HapticOpenFromMouse'.'SDL2.dll'.'SDL_HapticOpenFromMouse' +++'_SDL_JoystickIsHaptic'.'SDL2.dll'.'SDL_JoystickIsHaptic' +++'_SDL_HapticOpenFromJoystick'.'SDL2.dll'.'SDL_HapticOpenFromJoystick' +++'_SDL_HapticClose'.'SDL2.dll'.'SDL_HapticClose' +++'_SDL_HapticNumEffects'.'SDL2.dll'.'SDL_HapticNumEffects' +++'_SDL_HapticNumEffectsPlaying'.'SDL2.dll'.'SDL_HapticNumEffectsPlaying' +++'_SDL_HapticQuery'.'SDL2.dll'.'SDL_HapticQuery' +++'_SDL_HapticNumAxes'.'SDL2.dll'.'SDL_HapticNumAxes' +++'_SDL_HapticEffectSupported'.'SDL2.dll'.'SDL_HapticEffectSupported' +++'_SDL_HapticNewEffect'.'SDL2.dll'.'SDL_HapticNewEffect' +++'_SDL_HapticUpdateEffect'.'SDL2.dll'.'SDL_HapticUpdateEffect' +++'_SDL_HapticRunEffect'.'SDL2.dll'.'SDL_HapticRunEffect' +++'_SDL_HapticStopEffect'.'SDL2.dll'.'SDL_HapticStopEffect' +++'_SDL_HapticDestroyEffect'.'SDL2.dll'.'SDL_HapticDestroyEffect' +++'_SDL_HapticGetEffectStatus'.'SDL2.dll'.'SDL_HapticGetEffectStatus' +++'_SDL_HapticSetGain'.'SDL2.dll'.'SDL_HapticSetGain' +++'_SDL_HapticSetAutocenter'.'SDL2.dll'.'SDL_HapticSetAutocenter' +++'_SDL_HapticPause'.'SDL2.dll'.'SDL_HapticPause' +++'_SDL_HapticUnpause'.'SDL2.dll'.'SDL_HapticUnpause' +++'_SDL_HapticStopAll'.'SDL2.dll'.'SDL_HapticStopAll' +++'_SDL_HapticRumbleSupported'.'SDL2.dll'.'SDL_HapticRumbleSupported' +++'_SDL_HapticRumbleInit'.'SDL2.dll'.'SDL_HapticRumbleInit' +++'_SDL_HapticRumblePlay'.'SDL2.dll'.'SDL_HapticRumblePlay' +++'_SDL_HapticRumbleStop'.'SDL2.dll'.'SDL_HapticRumbleStop' +++'_SDL_SetHintWithPriority'.'SDL2.dll'.'SDL_SetHintWithPriority' +++'_SDL_SetHint'.'SDL2.dll'.'SDL_SetHint' +++'_SDL_GetHint'.'SDL2.dll'.'SDL_GetHint' +++'_SDL_AddHintCallback'.'SDL2.dll'.'SDL_AddHintCallback' +++'_SDL_DelHintCallback'.'SDL2.dll'.'SDL_DelHintCallback' +++'_SDL_ClearHints'.'SDL2.dll'.'SDL_ClearHints' +++'_SDL_NumJoysticks'.'SDL2.dll'.'SDL_NumJoysticks' +++'_SDL_JoystickNameForIndex'.'SDL2.dll'.'SDL_JoystickNameForIndex' +++'_SDL_JoystickOpen'.'SDL2.dll'.'SDL_JoystickOpen' +++'_SDL_JoystickName'.'SDL2.dll'.'SDL_JoystickName' +++'_SDL_JoystickGetDeviceGUID'.'SDL2.dll'.'SDL_JoystickGetDeviceGUID' +++'_SDL_JoystickGetGUID'.'SDL2.dll'.'SDL_JoystickGetGUID' +++'_SDL_JoystickGetGUIDString'.'SDL2.dll'.'SDL_JoystickGetGUIDString' +++'_SDL_JoystickGetGUIDFromString'.'SDL2.dll'.'SDL_JoystickGetGUIDFromString' +++'_SDL_JoystickGetAttached'.'SDL2.dll'.'SDL_JoystickGetAttached' +++'_SDL_JoystickInstanceID'.'SDL2.dll'.'SDL_JoystickInstanceID' +++'_SDL_JoystickNumAxes'.'SDL2.dll'.'SDL_JoystickNumAxes' +++'_SDL_JoystickNumBalls'.'SDL2.dll'.'SDL_JoystickNumBalls' +++'_SDL_JoystickNumHats'.'SDL2.dll'.'SDL_JoystickNumHats' +++'_SDL_JoystickNumButtons'.'SDL2.dll'.'SDL_JoystickNumButtons' +++'_SDL_JoystickUpdate'.'SDL2.dll'.'SDL_JoystickUpdate' +++'_SDL_JoystickEventState'.'SDL2.dll'.'SDL_JoystickEventState' +++'_SDL_JoystickGetAxis'.'SDL2.dll'.'SDL_JoystickGetAxis' +++'_SDL_JoystickGetHat'.'SDL2.dll'.'SDL_JoystickGetHat' +++'_SDL_JoystickGetBall'.'SDL2.dll'.'SDL_JoystickGetBall' +++'_SDL_JoystickGetButton'.'SDL2.dll'.'SDL_JoystickGetButton' +++'_SDL_JoystickClose'.'SDL2.dll'.'SDL_JoystickClose' +++'_SDL_GetKeyboardFocus'.'SDL2.dll'.'SDL_GetKeyboardFocus' +++'_SDL_GetKeyboardState'.'SDL2.dll'.'SDL_GetKeyboardState' +++'_SDL_GetModState'.'SDL2.dll'.'SDL_GetModState' +++'_SDL_SetModState'.'SDL2.dll'.'SDL_SetModState' +++'_SDL_GetKeyFromScancode'.'SDL2.dll'.'SDL_GetKeyFromScancode' +++'_SDL_GetScancodeFromKey'.'SDL2.dll'.'SDL_GetScancodeFromKey' +++'_SDL_GetScancodeName'.'SDL2.dll'.'SDL_GetScancodeName' +++'_SDL_GetScancodeFromName'.'SDL2.dll'.'SDL_GetScancodeFromName' +++'_SDL_GetKeyName'.'SDL2.dll'.'SDL_GetKeyName' +++'_SDL_GetKeyFromName'.'SDL2.dll'.'SDL_GetKeyFromName' +++'_SDL_StartTextInput'.'SDL2.dll'.'SDL_StartTextInput' +++'_SDL_IsTextInputActive'.'SDL2.dll'.'SDL_IsTextInputActive' +++'_SDL_StopTextInput'.'SDL2.dll'.'SDL_StopTextInput' +++'_SDL_SetTextInputRect'.'SDL2.dll'.'SDL_SetTextInputRect' +++'_SDL_HasScreenKeyboardSupport'.'SDL2.dll'.'SDL_HasScreenKeyboardSupport' +++'_SDL_IsScreenKeyboardShown'.'SDL2.dll'.'SDL_IsScreenKeyboardShown' +++'_SDL_LoadObject'.'SDL2.dll'.'SDL_LoadObject' +++'_SDL_LoadFunction'.'SDL2.dll'.'SDL_LoadFunction' +++'_SDL_UnloadObject'.'SDL2.dll'.'SDL_UnloadObject' +++'_SDL_LogSetAllPriority'.'SDL2.dll'.'SDL_LogSetAllPriority' +++'_SDL_LogSetPriority'.'SDL2.dll'.'SDL_LogSetPriority' +++'_SDL_LogGetPriority'.'SDL2.dll'.'SDL_LogGetPriority' +++'_SDL_LogResetPriorities'.'SDL2.dll'.'SDL_LogResetPriorities' +++'_SDL_LogMessageV'.'SDL2.dll'.'SDL_LogMessageV' +++'_SDL_LogGetOutputFunction'.'SDL2.dll'.'SDL_LogGetOutputFunction' +++'_SDL_LogSetOutputFunction'.'SDL2.dll'.'SDL_LogSetOutputFunction' +++'_SDL_SetMainReady'.'SDL2.dll'.'SDL_SetMainReady' +++'_SDL_ShowMessageBox'.'SDL2.dll'.'SDL_ShowMessageBox' +++'_SDL_ShowSimpleMessageBox'.'SDL2.dll'.'SDL_ShowSimpleMessageBox' +++'_SDL_GetMouseFocus'.'SDL2.dll'.'SDL_GetMouseFocus' +++'_SDL_GetMouseState'.'SDL2.dll'.'SDL_GetMouseState' +++'_SDL_GetRelativeMouseState'.'SDL2.dll'.'SDL_GetRelativeMouseState' +++'_SDL_WarpMouseInWindow'.'SDL2.dll'.'SDL_WarpMouseInWindow' +++'_SDL_SetRelativeMouseMode'.'SDL2.dll'.'SDL_SetRelativeMouseMode' +++'_SDL_GetRelativeMouseMode'.'SDL2.dll'.'SDL_GetRelativeMouseMode' +++'_SDL_CreateCursor'.'SDL2.dll'.'SDL_CreateCursor' +++'_SDL_CreateColorCursor'.'SDL2.dll'.'SDL_CreateColorCursor' +++'_SDL_CreateSystemCursor'.'SDL2.dll'.'SDL_CreateSystemCursor' +++'_SDL_SetCursor'.'SDL2.dll'.'SDL_SetCursor' +++'_SDL_GetCursor'.'SDL2.dll'.'SDL_GetCursor' +++'_SDL_GetDefaultCursor'.'SDL2.dll'.'SDL_GetDefaultCursor' +++'_SDL_FreeCursor'.'SDL2.dll'.'SDL_FreeCursor' +++'_SDL_ShowCursor'.'SDL2.dll'.'SDL_ShowCursor' +++'_SDL_CreateMutex'.'SDL2.dll'.'SDL_CreateMutex' +++'_SDL_LockMutex'.'SDL2.dll'.'SDL_LockMutex' +++'_SDL_TryLockMutex'.'SDL2.dll'.'SDL_TryLockMutex' +++'_SDL_UnlockMutex'.'SDL2.dll'.'SDL_UnlockMutex' +++'_SDL_DestroyMutex'.'SDL2.dll'.'SDL_DestroyMutex' +++'_SDL_CreateSemaphore'.'SDL2.dll'.'SDL_CreateSemaphore' +++'_SDL_DestroySemaphore'.'SDL2.dll'.'SDL_DestroySemaphore' +++'_SDL_SemWait'.'SDL2.dll'.'SDL_SemWait' +++'_SDL_SemTryWait'.'SDL2.dll'.'SDL_SemTryWait' +++'_SDL_SemWaitTimeout'.'SDL2.dll'.'SDL_SemWaitTimeout' +++'_SDL_SemPost'.'SDL2.dll'.'SDL_SemPost' +++'_SDL_SemValue'.'SDL2.dll'.'SDL_SemValue' +++'_SDL_CreateCond'.'SDL2.dll'.'SDL_CreateCond' +++'_SDL_DestroyCond'.'SDL2.dll'.'SDL_DestroyCond' +++'_SDL_CondSignal'.'SDL2.dll'.'SDL_CondSignal' +++'_SDL_CondBroadcast'.'SDL2.dll'.'SDL_CondBroadcast' +++'_SDL_CondWait'.'SDL2.dll'.'SDL_CondWait' +++'_SDL_CondWaitTimeout'.'SDL2.dll'.'SDL_CondWaitTimeout' +++'_SDL_GetPixelFormatName'.'SDL2.dll'.'SDL_GetPixelFormatName' +++'_SDL_PixelFormatEnumToMasks'.'SDL2.dll'.'SDL_PixelFormatEnumToMasks' +++'_SDL_MasksToPixelFormatEnum'.'SDL2.dll'.'SDL_MasksToPixelFormatEnum' +++'_SDL_AllocFormat'.'SDL2.dll'.'SDL_AllocFormat' +++'_SDL_FreeFormat'.'SDL2.dll'.'SDL_FreeFormat' +++'_SDL_AllocPalette'.'SDL2.dll'.'SDL_AllocPalette' +++'_SDL_SetPixelFormatPalette'.'SDL2.dll'.'SDL_SetPixelFormatPalette' +++'_SDL_SetPaletteColors'.'SDL2.dll'.'SDL_SetPaletteColors' +++'_SDL_FreePalette'.'SDL2.dll'.'SDL_FreePalette' +++'_SDL_MapRGB'.'SDL2.dll'.'SDL_MapRGB' +++'_SDL_MapRGBA'.'SDL2.dll'.'SDL_MapRGBA' +++'_SDL_GetRGB'.'SDL2.dll'.'SDL_GetRGB' +++'_SDL_GetRGBA'.'SDL2.dll'.'SDL_GetRGBA' +++'_SDL_CalculateGammaRamp'.'SDL2.dll'.'SDL_CalculateGammaRamp' +++'_SDL_GetPlatform'.'SDL2.dll'.'SDL_GetPlatform' +++'_SDL_GetPowerInfo'.'SDL2.dll'.'SDL_GetPowerInfo' +++'_SDL_HasIntersection'.'SDL2.dll'.'SDL_HasIntersection' +++'_SDL_IntersectRect'.'SDL2.dll'.'SDL_IntersectRect' +++'_SDL_UnionRect'.'SDL2.dll'.'SDL_UnionRect' +++'_SDL_EnclosePoints'.'SDL2.dll'.'SDL_EnclosePoints' +++'_SDL_IntersectRectAndLine'.'SDL2.dll'.'SDL_IntersectRectAndLine' +++'_SDL_GetNumRenderDrivers'.'SDL2.dll'.'SDL_GetNumRenderDrivers' +++'_SDL_GetRenderDriverInfo'.'SDL2.dll'.'SDL_GetRenderDriverInfo' +++'_SDL_CreateWindowAndRenderer'.'SDL2.dll'.'SDL_CreateWindowAndRenderer' +++'_SDL_CreateRenderer'.'SDL2.dll'.'SDL_CreateRenderer' +++'_SDL_CreateSoftwareRenderer'.'SDL2.dll'.'SDL_CreateSoftwareRenderer' +++'_SDL_GetRenderer'.'SDL2.dll'.'SDL_GetRenderer' +++'_SDL_GetRendererInfo'.'SDL2.dll'.'SDL_GetRendererInfo' +++'_SDL_GetRendererOutputSize'.'SDL2.dll'.'SDL_GetRendererOutputSize' +++'_SDL_CreateTexture'.'SDL2.dll'.'SDL_CreateTexture' +++'_SDL_CreateTextureFromSurface'.'SDL2.dll'.'SDL_CreateTextureFromSurface' +++'_SDL_QueryTexture'.'SDL2.dll'.'SDL_QueryTexture' +++'_SDL_SetTextureColorMod'.'SDL2.dll'.'SDL_SetTextureColorMod' +++'_SDL_GetTextureColorMod'.'SDL2.dll'.'SDL_GetTextureColorMod' +++'_SDL_SetTextureAlphaMod'.'SDL2.dll'.'SDL_SetTextureAlphaMod' +++'_SDL_GetTextureAlphaMod'.'SDL2.dll'.'SDL_GetTextureAlphaMod' +++'_SDL_SetTextureBlendMode'.'SDL2.dll'.'SDL_SetTextureBlendMode' +++'_SDL_GetTextureBlendMode'.'SDL2.dll'.'SDL_GetTextureBlendMode' +++'_SDL_UpdateTexture'.'SDL2.dll'.'SDL_UpdateTexture' +++'_SDL_UpdateYUVTexture'.'SDL2.dll'.'SDL_UpdateYUVTexture' +++'_SDL_LockTexture'.'SDL2.dll'.'SDL_LockTexture' +++'_SDL_UnlockTexture'.'SDL2.dll'.'SDL_UnlockTexture' +++'_SDL_RenderTargetSupported'.'SDL2.dll'.'SDL_RenderTargetSupported' +++'_SDL_SetRenderTarget'.'SDL2.dll'.'SDL_SetRenderTarget' +++'_SDL_GetRenderTarget'.'SDL2.dll'.'SDL_GetRenderTarget' +++'_SDL_RenderSetLogicalSize'.'SDL2.dll'.'SDL_RenderSetLogicalSize' +++'_SDL_RenderGetLogicalSize'.'SDL2.dll'.'SDL_RenderGetLogicalSize' +++'_SDL_RenderSetViewport'.'SDL2.dll'.'SDL_RenderSetViewport' +++'_SDL_RenderGetViewport'.'SDL2.dll'.'SDL_RenderGetViewport' +++'_SDL_RenderSetClipRect'.'SDL2.dll'.'SDL_RenderSetClipRect' +++'_SDL_RenderGetClipRect'.'SDL2.dll'.'SDL_RenderGetClipRect' +++'_SDL_RenderSetScale'.'SDL2.dll'.'SDL_RenderSetScale' +++'_SDL_RenderGetScale'.'SDL2.dll'.'SDL_RenderGetScale' +++'_SDL_SetRenderDrawColor'.'SDL2.dll'.'SDL_SetRenderDrawColor' +++'_SDL_GetRenderDrawColor'.'SDL2.dll'.'SDL_GetRenderDrawColor' +++'_SDL_SetRenderDrawBlendMode'.'SDL2.dll'.'SDL_SetRenderDrawBlendMode' +++'_SDL_GetRenderDrawBlendMode'.'SDL2.dll'.'SDL_GetRenderDrawBlendMode' +++'_SDL_RenderClear'.'SDL2.dll'.'SDL_RenderClear' +++'_SDL_RenderDrawPoint'.'SDL2.dll'.'SDL_RenderDrawPoint' +++'_SDL_RenderDrawPoints'.'SDL2.dll'.'SDL_RenderDrawPoints' +++'_SDL_RenderDrawLine'.'SDL2.dll'.'SDL_RenderDrawLine' +++'_SDL_RenderDrawLines'.'SDL2.dll'.'SDL_RenderDrawLines' +++'_SDL_RenderDrawRect'.'SDL2.dll'.'SDL_RenderDrawRect' +++'_SDL_RenderDrawRects'.'SDL2.dll'.'SDL_RenderDrawRects' +++'_SDL_RenderFillRect'.'SDL2.dll'.'SDL_RenderFillRect' +++'_SDL_RenderFillRects'.'SDL2.dll'.'SDL_RenderFillRects' +++'_SDL_RenderCopy'.'SDL2.dll'.'SDL_RenderCopy' +++'_SDL_RenderCopyEx'.'SDL2.dll'.'SDL_RenderCopyEx' +++'_SDL_RenderReadPixels'.'SDL2.dll'.'SDL_RenderReadPixels' +++'_SDL_RenderPresent'.'SDL2.dll'.'SDL_RenderPresent' +++'_SDL_DestroyTexture'.'SDL2.dll'.'SDL_DestroyTexture' +++'_SDL_DestroyRenderer'.'SDL2.dll'.'SDL_DestroyRenderer' +++'_SDL_GL_BindTexture'.'SDL2.dll'.'SDL_GL_BindTexture' +++'_SDL_GL_UnbindTexture'.'SDL2.dll'.'SDL_GL_UnbindTexture' +++'_SDL_RWFromFile'.'SDL2.dll'.'SDL_RWFromFile' +++'_SDL_RWFromMem'.'SDL2.dll'.'SDL_RWFromMem' +++'_SDL_RWFromConstMem'.'SDL2.dll'.'SDL_RWFromConstMem' +++'_SDL_AllocRW'.'SDL2.dll'.'SDL_AllocRW' +++'_SDL_FreeRW'.'SDL2.dll'.'SDL_FreeRW' +++'_SDL_ReadU8'.'SDL2.dll'.'SDL_ReadU8' +++'_SDL_ReadLE16'.'SDL2.dll'.'SDL_ReadLE16' +++'_SDL_ReadBE16'.'SDL2.dll'.'SDL_ReadBE16' +++'_SDL_ReadLE32'.'SDL2.dll'.'SDL_ReadLE32' +++'_SDL_ReadBE32'.'SDL2.dll'.'SDL_ReadBE32' +++'_SDL_ReadLE64'.'SDL2.dll'.'SDL_ReadLE64' +++'_SDL_ReadBE64'.'SDL2.dll'.'SDL_ReadBE64' +++'_SDL_WriteU8'.'SDL2.dll'.'SDL_WriteU8' +++'_SDL_WriteLE16'.'SDL2.dll'.'SDL_WriteLE16' +++'_SDL_WriteBE16'.'SDL2.dll'.'SDL_WriteBE16' +++'_SDL_WriteLE32'.'SDL2.dll'.'SDL_WriteLE32' +++'_SDL_WriteBE32'.'SDL2.dll'.'SDL_WriteBE32' +++'_SDL_WriteLE64'.'SDL2.dll'.'SDL_WriteLE64' +++'_SDL_WriteBE64'.'SDL2.dll'.'SDL_WriteBE64' +++'_SDL_CreateShapedWindow'.'SDL2.dll'.'SDL_CreateShapedWindow' +++'_SDL_IsShapedWindow'.'SDL2.dll'.'SDL_IsShapedWindow' +++'_SDL_SetWindowShape'.'SDL2.dll'.'SDL_SetWindowShape' +++'_SDL_GetShapedWindowMode'.'SDL2.dll'.'SDL_GetShapedWindowMode' +++'_SDL_malloc'.'SDL2.dll'.'SDL_malloc' +++'_SDL_calloc'.'SDL2.dll'.'SDL_calloc' +++'_SDL_realloc'.'SDL2.dll'.'SDL_realloc' +++'_SDL_free'.'SDL2.dll'.'SDL_free' +++'_SDL_getenv'.'SDL2.dll'.'SDL_getenv' +++'_SDL_setenv'.'SDL2.dll'.'SDL_setenv' +++'_SDL_qsort'.'SDL2.dll'.'SDL_qsort' +++'_SDL_abs'.'SDL2.dll'.'SDL_abs' +++'_SDL_isdigit'.'SDL2.dll'.'SDL_isdigit' +++'_SDL_isspace'.'SDL2.dll'.'SDL_isspace' +++'_SDL_toupper'.'SDL2.dll'.'SDL_toupper' +++'_SDL_tolower'.'SDL2.dll'.'SDL_tolower' +++'_SDL_memset'.'SDL2.dll'.'SDL_memset' +++'_SDL_memcpy'.'SDL2.dll'.'SDL_memcpy' +++'_SDL_memmove'.'SDL2.dll'.'SDL_memmove' +++'_SDL_memcmp'.'SDL2.dll'.'SDL_memcmp' +++'_SDL_wcslen'.'SDL2.dll'.'SDL_wcslen' +++'_SDL_wcslcpy'.'SDL2.dll'.'SDL_wcslcpy' +++'_SDL_wcslcat'.'SDL2.dll'.'SDL_wcslcat' +++'_SDL_strlen'.'SDL2.dll'.'SDL_strlen' +++'_SDL_strlcpy'.'SDL2.dll'.'SDL_strlcpy' +++'_SDL_utf8strlcpy'.'SDL2.dll'.'SDL_utf8strlcpy' +++'_SDL_strlcat'.'SDL2.dll'.'SDL_strlcat' +++'_SDL_strdup'.'SDL2.dll'.'SDL_strdup' +++'_SDL_strrev'.'SDL2.dll'.'SDL_strrev' +++'_SDL_strupr'.'SDL2.dll'.'SDL_strupr' +++'_SDL_strlwr'.'SDL2.dll'.'SDL_strlwr' +++'_SDL_strchr'.'SDL2.dll'.'SDL_strchr' +++'_SDL_strrchr'.'SDL2.dll'.'SDL_strrchr' +++'_SDL_strstr'.'SDL2.dll'.'SDL_strstr' +++'_SDL_itoa'.'SDL2.dll'.'SDL_itoa' +++'_SDL_uitoa'.'SDL2.dll'.'SDL_uitoa' +++'_SDL_ltoa'.'SDL2.dll'.'SDL_ltoa' +++'_SDL_ultoa'.'SDL2.dll'.'SDL_ultoa' +++'_SDL_lltoa'.'SDL2.dll'.'SDL_lltoa' +++'_SDL_ulltoa'.'SDL2.dll'.'SDL_ulltoa' +++'_SDL_atoi'.'SDL2.dll'.'SDL_atoi' +++'_SDL_atof'.'SDL2.dll'.'SDL_atof' +++'_SDL_strtol'.'SDL2.dll'.'SDL_strtol' +++'_SDL_strtoul'.'SDL2.dll'.'SDL_strtoul' +++'_SDL_strtoll'.'SDL2.dll'.'SDL_strtoll' +++'_SDL_strtoull'.'SDL2.dll'.'SDL_strtoull' +++'_SDL_strtod'.'SDL2.dll'.'SDL_strtod' +++'_SDL_strcmp'.'SDL2.dll'.'SDL_strcmp' +++'_SDL_strncmp'.'SDL2.dll'.'SDL_strncmp' +++'_SDL_strcasecmp'.'SDL2.dll'.'SDL_strcasecmp' +++'_SDL_strncasecmp'.'SDL2.dll'.'SDL_strncasecmp' +++'_SDL_vsnprintf'.'SDL2.dll'.'SDL_vsnprintf' +++'_SDL_acos'.'SDL2.dll'.'SDL_acos' +++'_SDL_asin'.'SDL2.dll'.'SDL_asin' +++'_SDL_atan'.'SDL2.dll'.'SDL_atan' +++'_SDL_atan2'.'SDL2.dll'.'SDL_atan2' +++'_SDL_ceil'.'SDL2.dll'.'SDL_ceil' +++'_SDL_copysign'.'SDL2.dll'.'SDL_copysign' +++'_SDL_cos'.'SDL2.dll'.'SDL_cos' +++'_SDL_cosf'.'SDL2.dll'.'SDL_cosf' +++'_SDL_fabs'.'SDL2.dll'.'SDL_fabs' +++'_SDL_floor'.'SDL2.dll'.'SDL_floor' +++'_SDL_log'.'SDL2.dll'.'SDL_log' +++'_SDL_pow'.'SDL2.dll'.'SDL_pow' +++'_SDL_scalbn'.'SDL2.dll'.'SDL_scalbn' +++'_SDL_sin'.'SDL2.dll'.'SDL_sin' +++'_SDL_sinf'.'SDL2.dll'.'SDL_sinf' +++'_SDL_sqrt'.'SDL2.dll'.'SDL_sqrt' +++'_SDL_iconv_open'.'SDL2.dll'.'SDL_iconv_open' +++'_SDL_iconv_close'.'SDL2.dll'.'SDL_iconv_close' +++'_SDL_iconv'.'SDL2.dll'.'SDL_iconv' +++'_SDL_iconv_string'.'SDL2.dll'.'SDL_iconv_string' +++'_SDL_CreateRGBSurface'.'SDL2.dll'.'SDL_CreateRGBSurface' +++'_SDL_CreateRGBSurfaceFrom'.'SDL2.dll'.'SDL_CreateRGBSurfaceFrom' +++'_SDL_FreeSurface'.'SDL2.dll'.'SDL_FreeSurface' +++'_SDL_SetSurfacePalette'.'SDL2.dll'.'SDL_SetSurfacePalette' +++'_SDL_LockSurface'.'SDL2.dll'.'SDL_LockSurface' +++'_SDL_UnlockSurface'.'SDL2.dll'.'SDL_UnlockSurface' +++'_SDL_LoadBMP_RW'.'SDL2.dll'.'SDL_LoadBMP_RW' +++'_SDL_SaveBMP_RW'.'SDL2.dll'.'SDL_SaveBMP_RW' +++'_SDL_SetSurfaceRLE'.'SDL2.dll'.'SDL_SetSurfaceRLE' +++'_SDL_SetColorKey'.'SDL2.dll'.'SDL_SetColorKey' +++'_SDL_GetColorKey'.'SDL2.dll'.'SDL_GetColorKey' +++'_SDL_SetSurfaceColorMod'.'SDL2.dll'.'SDL_SetSurfaceColorMod' +++'_SDL_GetSurfaceColorMod'.'SDL2.dll'.'SDL_GetSurfaceColorMod' +++'_SDL_SetSurfaceAlphaMod'.'SDL2.dll'.'SDL_SetSurfaceAlphaMod' +++'_SDL_GetSurfaceAlphaMod'.'SDL2.dll'.'SDL_GetSurfaceAlphaMod' +++'_SDL_SetSurfaceBlendMode'.'SDL2.dll'.'SDL_SetSurfaceBlendMode' +++'_SDL_GetSurfaceBlendMode'.'SDL2.dll'.'SDL_GetSurfaceBlendMode' +++'_SDL_SetClipRect'.'SDL2.dll'.'SDL_SetClipRect' +++'_SDL_GetClipRect'.'SDL2.dll'.'SDL_GetClipRect' +++'_SDL_ConvertSurface'.'SDL2.dll'.'SDL_ConvertSurface' +++'_SDL_ConvertSurfaceFormat'.'SDL2.dll'.'SDL_ConvertSurfaceFormat' +++'_SDL_ConvertPixels'.'SDL2.dll'.'SDL_ConvertPixels' +++'_SDL_FillRect'.'SDL2.dll'.'SDL_FillRect' +++'_SDL_FillRects'.'SDL2.dll'.'SDL_FillRects' +++'_SDL_UpperBlit'.'SDL2.dll'.'SDL_UpperBlit' +++'_SDL_LowerBlit'.'SDL2.dll'.'SDL_LowerBlit' +++'_SDL_SoftStretch'.'SDL2.dll'.'SDL_SoftStretch' +++'_SDL_UpperBlitScaled'.'SDL2.dll'.'SDL_UpperBlitScaled' +++'_SDL_LowerBlitScaled'.'SDL2.dll'.'SDL_LowerBlitScaled' +++'_SDL_GetWindowWMInfo'.'SDL2.dll'.'SDL_GetWindowWMInfo' +++'_SDL_GetThreadName'.'SDL2.dll'.'SDL_GetThreadName' +++'_SDL_ThreadID'.'SDL2.dll'.'SDL_ThreadID' +++'_SDL_GetThreadID'.'SDL2.dll'.'SDL_GetThreadID' +++'_SDL_SetThreadPriority'.'SDL2.dll'.'SDL_SetThreadPriority' +++'_SDL_WaitThread'.'SDL2.dll'.'SDL_WaitThread' +++'_SDL_DetachThread'.'SDL2.dll'.'SDL_DetachThread' +++'_SDL_TLSCreate'.'SDL2.dll'.'SDL_TLSCreate' +++'_SDL_TLSGet'.'SDL2.dll'.'SDL_TLSGet' +++'_SDL_TLSSet'.'SDL2.dll'.'SDL_TLSSet' +++'_SDL_GetTicks'.'SDL2.dll'.'SDL_GetTicks' +++'_SDL_GetPerformanceCounter'.'SDL2.dll'.'SDL_GetPerformanceCounter' +++'_SDL_GetPerformanceFrequency'.'SDL2.dll'.'SDL_GetPerformanceFrequency' +++'_SDL_Delay'.'SDL2.dll'.'SDL_Delay' +++'_SDL_AddTimer'.'SDL2.dll'.'SDL_AddTimer' +++'_SDL_RemoveTimer'.'SDL2.dll'.'SDL_RemoveTimer' +++'_SDL_GetNumTouchDevices'.'SDL2.dll'.'SDL_GetNumTouchDevices' +++'_SDL_GetTouchDevice'.'SDL2.dll'.'SDL_GetTouchDevice' +++'_SDL_GetNumTouchFingers'.'SDL2.dll'.'SDL_GetNumTouchFingers' +++'_SDL_GetTouchFinger'.'SDL2.dll'.'SDL_GetTouchFinger' +++'_SDL_GetVersion'.'SDL2.dll'.'SDL_GetVersion' +++'_SDL_GetRevision'.'SDL2.dll'.'SDL_GetRevision' +++'_SDL_GetRevisionNumber'.'SDL2.dll'.'SDL_GetRevisionNumber' +++'_SDL_GetNumVideoDrivers'.'SDL2.dll'.'SDL_GetNumVideoDrivers' +++'_SDL_GetVideoDriver'.'SDL2.dll'.'SDL_GetVideoDriver' +++'_SDL_VideoInit'.'SDL2.dll'.'SDL_VideoInit' +++'_SDL_VideoQuit'.'SDL2.dll'.'SDL_VideoQuit' +++'_SDL_GetCurrentVideoDriver'.'SDL2.dll'.'SDL_GetCurrentVideoDriver' +++'_SDL_GetNumVideoDisplays'.'SDL2.dll'.'SDL_GetNumVideoDisplays' +++'_SDL_GetDisplayName'.'SDL2.dll'.'SDL_GetDisplayName' +++'_SDL_GetDisplayBounds'.'SDL2.dll'.'SDL_GetDisplayBounds' +++'_SDL_GetDisplayDPI'.'SDL2.dll'.'SDL_GetDisplayDPI' +++'_SDL_GetNumDisplayModes'.'SDL2.dll'.'SDL_GetNumDisplayModes' +++'_SDL_GetDisplayMode'.'SDL2.dll'.'SDL_GetDisplayMode' +++'_SDL_GetDesktopDisplayMode'.'SDL2.dll'.'SDL_GetDesktopDisplayMode' +++'_SDL_GetCurrentDisplayMode'.'SDL2.dll'.'SDL_GetCurrentDisplayMode' +++'_SDL_GetClosestDisplayMode'.'SDL2.dll'.'SDL_GetClosestDisplayMode' +++'_SDL_GetWindowDisplayIndex'.'SDL2.dll'.'SDL_GetWindowDisplayIndex' +++'_SDL_SetWindowDisplayMode'.'SDL2.dll'.'SDL_SetWindowDisplayMode' +++'_SDL_GetWindowDisplayMode'.'SDL2.dll'.'SDL_GetWindowDisplayMode' +++'_SDL_GetWindowPixelFormat'.'SDL2.dll'.'SDL_GetWindowPixelFormat' +++'_SDL_CreateWindow'.'SDL2.dll'.'SDL_CreateWindow' +++'_SDL_CreateWindowFrom'.'SDL2.dll'.'SDL_CreateWindowFrom' +++'_SDL_GetWindowID'.'SDL2.dll'.'SDL_GetWindowID' +++'_SDL_GetWindowFromID'.'SDL2.dll'.'SDL_GetWindowFromID' +++'_SDL_GetWindowFlags'.'SDL2.dll'.'SDL_GetWindowFlags' +++'_SDL_SetWindowTitle'.'SDL2.dll'.'SDL_SetWindowTitle' +++'_SDL_GetWindowTitle'.'SDL2.dll'.'SDL_GetWindowTitle' +++'_SDL_SetWindowIcon'.'SDL2.dll'.'SDL_SetWindowIcon' +++'_SDL_SetWindowData'.'SDL2.dll'.'SDL_SetWindowData' +++'_SDL_GetWindowData'.'SDL2.dll'.'SDL_GetWindowData' +++'_SDL_SetWindowPosition'.'SDL2.dll'.'SDL_SetWindowPosition' +++'_SDL_GetWindowPosition'.'SDL2.dll'.'SDL_GetWindowPosition' +++'_SDL_SetWindowSize'.'SDL2.dll'.'SDL_SetWindowSize' +++'_SDL_GetWindowSize'.'SDL2.dll'.'SDL_GetWindowSize' +++'_SDL_SetWindowMinimumSize'.'SDL2.dll'.'SDL_SetWindowMinimumSize' +++'_SDL_GetWindowMinimumSize'.'SDL2.dll'.'SDL_GetWindowMinimumSize' +++'_SDL_SetWindowMaximumSize'.'SDL2.dll'.'SDL_SetWindowMaximumSize' +++'_SDL_GetWindowMaximumSize'.'SDL2.dll'.'SDL_GetWindowMaximumSize' +++'_SDL_SetWindowBordered'.'SDL2.dll'.'SDL_SetWindowBordered' +++'_SDL_ShowWindow'.'SDL2.dll'.'SDL_ShowWindow' +++'_SDL_HideWindow'.'SDL2.dll'.'SDL_HideWindow' +++'_SDL_RaiseWindow'.'SDL2.dll'.'SDL_RaiseWindow' +++'_SDL_MaximizeWindow'.'SDL2.dll'.'SDL_MaximizeWindow' +++'_SDL_MinimizeWindow'.'SDL2.dll'.'SDL_MinimizeWindow' +++'_SDL_RestoreWindow'.'SDL2.dll'.'SDL_RestoreWindow' +++'_SDL_SetWindowFullscreen'.'SDL2.dll'.'SDL_SetWindowFullscreen' +++'_SDL_GetWindowSurface'.'SDL2.dll'.'SDL_GetWindowSurface' +++'_SDL_UpdateWindowSurface'.'SDL2.dll'.'SDL_UpdateWindowSurface' +++'_SDL_UpdateWindowSurfaceRects'.'SDL2.dll'.'SDL_UpdateWindowSurfaceRects' +++'_SDL_SetWindowGrab'.'SDL2.dll'.'SDL_SetWindowGrab' +++'_SDL_GetWindowGrab'.'SDL2.dll'.'SDL_GetWindowGrab' +++'_SDL_SetWindowBrightness'.'SDL2.dll'.'SDL_SetWindowBrightness' +++'_SDL_GetWindowBrightness'.'SDL2.dll'.'SDL_GetWindowBrightness' +++'_SDL_SetWindowGammaRamp'.'SDL2.dll'.'SDL_SetWindowGammaRamp' +++'_SDL_GetWindowGammaRamp'.'SDL2.dll'.'SDL_GetWindowGammaRamp' +++'_SDL_DestroyWindow'.'SDL2.dll'.'SDL_DestroyWindow' +++'_SDL_IsScreenSaverEnabled'.'SDL2.dll'.'SDL_IsScreenSaverEnabled' +++'_SDL_EnableScreenSaver'.'SDL2.dll'.'SDL_EnableScreenSaver' +++'_SDL_DisableScreenSaver'.'SDL2.dll'.'SDL_DisableScreenSaver' +++'_SDL_GL_LoadLibrary'.'SDL2.dll'.'SDL_GL_LoadLibrary' +++'_SDL_GL_GetProcAddress'.'SDL2.dll'.'SDL_GL_GetProcAddress' +++'_SDL_GL_UnloadLibrary'.'SDL2.dll'.'SDL_GL_UnloadLibrary' +++'_SDL_GL_ExtensionSupported'.'SDL2.dll'.'SDL_GL_ExtensionSupported' +++'_SDL_GL_SetAttribute'.'SDL2.dll'.'SDL_GL_SetAttribute' +++'_SDL_GL_GetAttribute'.'SDL2.dll'.'SDL_GL_GetAttribute' +++'_SDL_GL_CreateContext'.'SDL2.dll'.'SDL_GL_CreateContext' +++'_SDL_GL_MakeCurrent'.'SDL2.dll'.'SDL_GL_MakeCurrent' +++'_SDL_GL_GetCurrentWindow'.'SDL2.dll'.'SDL_GL_GetCurrentWindow' +++'_SDL_GL_GetCurrentContext'.'SDL2.dll'.'SDL_GL_GetCurrentContext' +++'_SDL_GL_GetDrawableSize'.'SDL2.dll'.'SDL_GL_GetDrawableSize' +++'_SDL_GL_SetSwapInterval'.'SDL2.dll'.'SDL_GL_SetSwapInterval' +++'_SDL_GL_GetSwapInterval'.'SDL2.dll'.'SDL_GL_GetSwapInterval' +++'_SDL_GL_SwapWindow'.'SDL2.dll'.'SDL_GL_SwapWindow' +++'_SDL_GL_DeleteContext'.'SDL2.dll'.'SDL_GL_DeleteContext' +++'_SDL_vsscanf'.'SDL2.dll'.'SDL_vsscanf' +++'_SDL_GameControllerAddMappingsFromRW'.'SDL2.dll'.'SDL_GameControllerAddMappingsFromRW' +++'_SDL_GL_ResetAttributes'.'SDL2.dll'.'SDL_GL_ResetAttributes' +++'_SDL_HasAVX'.'SDL2.dll'.'SDL_HasAVX' +++'_SDL_GetDefaultAssertionHandler'.'SDL2.dll'.'SDL_GetDefaultAssertionHandler' +++'_SDL_GetAssertionHandler'.'SDL2.dll'.'SDL_GetAssertionHandler' +++'_SDL_DXGIGetOutputInfo'.'SDL2.dll'.'SDL_DXGIGetOutputInfo' +++'_SDL_RenderIsClipEnabled'.'SDL2.dll'.'SDL_RenderIsClipEnabled' +# ++'_SDL_WinRTRunApp'.'SDL2.dll'.'SDL_WinRTRunApp' +++'_SDL_WarpMouseGlobal'.'SDL2.dll'.'SDL_WarpMouseGlobal' +# ++'_SDL_WinRTGetFSPathUNICODE'.'SDL2.dll'.'SDL_WinRTGetFSPathUNICODE' +# ++'_SDL_WinRTGetFSPathUTF8'.'SDL2.dll'.'SDL_WinRTGetFSPathUTF8' +++'_SDL_sqrtf'.'SDL2.dll'.'SDL_sqrtf' +++'_SDL_tan'.'SDL2.dll'.'SDL_tan' +++'_SDL_tanf'.'SDL2.dll'.'SDL_tanf' +++'_SDL_CaptureMouse'.'SDL2.dll'.'SDL_CaptureMouse' +++'_SDL_SetWindowHitTest'.'SDL2.dll'.'SDL_SetWindowHitTest' +++'_SDL_GetGlobalMouseState'.'SDL2.dll'.'SDL_GetGlobalMouseState' +++'_SDL_HasAVX2'.'SDL2.dll'.'SDL_HasAVX2' +++'_SDL_QueueAudio'.'SDL2.dll'.'SDL_QueueAudio' +++'_SDL_GetQueuedAudioSize'.'SDL2.dll'.'SDL_GetQueuedAudioSize' +++'_SDL_ClearQueuedAudio'.'SDL2.dll'.'SDL_ClearQueuedAudio' +++'_SDL_GetGrabbedWindow'.'SDL2.dll'.'SDL_GetGrabbedWindow' +++'_SDL_SetWindowsMessageHook'.'SDL2.dll'.'SDL_SetWindowsMessageHook' +++'_SDL_JoystickCurrentPowerLevel'.'SDL2.dll'.'SDL_JoystickCurrentPowerLevel' +++'_SDL_GameControllerFromInstanceID'.'SDL2.dll'.'SDL_GameControllerFromInstanceID' +++'_SDL_JoystickFromInstanceID'.'SDL2.dll'.'SDL_JoystickFromInstanceID' +++'_SDL_GetDisplayUsableBounds'.'SDL2.dll'.'SDL_GetDisplayUsableBounds' +++'_SDL_GetWindowBordersSize'.'SDL2.dll'.'SDL_GetWindowBordersSize' +++'_SDL_SetWindowOpacity'.'SDL2.dll'.'SDL_SetWindowOpacity' +++'_SDL_GetWindowOpacity'.'SDL2.dll'.'SDL_GetWindowOpacity' +++'_SDL_SetWindowInputFocus'.'SDL2.dll'.'SDL_SetWindowInputFocus' +++'_SDL_SetWindowModalFor'.'SDL2.dll'.'SDL_SetWindowModalFor' +++'_SDL_RenderSetIntegerScale'.'SDL2.dll'.'SDL_RenderSetIntegerScale' +++'_SDL_RenderGetIntegerScale'.'SDL2.dll'.'SDL_RenderGetIntegerScale' +++'_SDL_DequeueAudio'.'SDL2.dll'.'SDL_DequeueAudio' +++'_SDL_SetWindowResizable'.'SDL2.dll'.'SDL_SetWindowResizable' +++'_SDL_CreateRGBSurfaceWithFormat'.'SDL2.dll'.'SDL_CreateRGBSurfaceWithFormat' +++'_SDL_CreateRGBSurfaceWithFormatFrom'.'SDL2.dll'.'SDL_CreateRGBSurfaceWithFormatFrom' +++'_SDL_GetHintBoolean'.'SDL2.dll'.'SDL_GetHintBoolean' +++'_SDL_JoystickGetDeviceVendor'.'SDL2.dll'.'SDL_JoystickGetDeviceVendor' +++'_SDL_JoystickGetDeviceProduct'.'SDL2.dll'.'SDL_JoystickGetDeviceProduct' +++'_SDL_JoystickGetDeviceProductVersion'.'SDL2.dll'.'SDL_JoystickGetDeviceProductVersion' +++'_SDL_JoystickGetVendor'.'SDL2.dll'.'SDL_JoystickGetVendor' +++'_SDL_JoystickGetProduct'.'SDL2.dll'.'SDL_JoystickGetProduct' +++'_SDL_JoystickGetProductVersion'.'SDL2.dll'.'SDL_JoystickGetProductVersion' +++'_SDL_GameControllerGetVendor'.'SDL2.dll'.'SDL_GameControllerGetVendor' +++'_SDL_GameControllerGetProduct'.'SDL2.dll'.'SDL_GameControllerGetProduct' +++'_SDL_GameControllerGetProductVersion'.'SDL2.dll'.'SDL_GameControllerGetProductVersion' +++'_SDL_HasNEON'.'SDL2.dll'.'SDL_HasNEON' +++'_SDL_GameControllerNumMappings'.'SDL2.dll'.'SDL_GameControllerNumMappings' +++'_SDL_GameControllerMappingForIndex'.'SDL2.dll'.'SDL_GameControllerMappingForIndex' +++'_SDL_JoystickGetAxisInitialState'.'SDL2.dll'.'SDL_JoystickGetAxisInitialState' +++'_SDL_JoystickGetDeviceType'.'SDL2.dll'.'SDL_JoystickGetDeviceType' +++'_SDL_JoystickGetType'.'SDL2.dll'.'SDL_JoystickGetType' +++'_SDL_MemoryBarrierReleaseFunction'.'SDL2.dll'.'SDL_MemoryBarrierReleaseFunction' +++'_SDL_MemoryBarrierAcquireFunction'.'SDL2.dll'.'SDL_MemoryBarrierAcquireFunction' +++'_SDL_JoystickGetDeviceInstanceID'.'SDL2.dll'.'SDL_JoystickGetDeviceInstanceID' +++'_SDL_utf8strlen'.'SDL2.dll'.'SDL_utf8strlen' +++'_SDL_LoadFile_RW'.'SDL2.dll'.'SDL_LoadFile_RW' +++'_SDL_wcscmp'.'SDL2.dll'.'SDL_wcscmp' +++'_SDL_ComposeCustomBlendMode'.'SDL2.dll'.'SDL_ComposeCustomBlendMode' +++'_SDL_DuplicateSurface'.'SDL2.dll'.'SDL_DuplicateSurface' +++'_SDL_Vulkan_LoadLibrary'.'SDL2.dll'.'SDL_Vulkan_LoadLibrary' +++'_SDL_Vulkan_GetVkGetInstanceProcAddr'.'SDL2.dll'.'SDL_Vulkan_GetVkGetInstanceProcAddr' +++'_SDL_Vulkan_UnloadLibrary'.'SDL2.dll'.'SDL_Vulkan_UnloadLibrary' +++'_SDL_Vulkan_GetInstanceExtensions'.'SDL2.dll'.'SDL_Vulkan_GetInstanceExtensions' +++'_SDL_Vulkan_CreateSurface'.'SDL2.dll'.'SDL_Vulkan_CreateSurface' +++'_SDL_Vulkan_GetDrawableSize'.'SDL2.dll'.'SDL_Vulkan_GetDrawableSize' +++'_SDL_LockJoysticks'.'SDL2.dll'.'SDL_LockJoysticks' +++'_SDL_UnlockJoysticks'.'SDL2.dll'.'SDL_UnlockJoysticks' +++'_SDL_GetMemoryFunctions'.'SDL2.dll'.'SDL_GetMemoryFunctions' +++'_SDL_SetMemoryFunctions'.'SDL2.dll'.'SDL_SetMemoryFunctions' +++'_SDL_GetNumAllocations'.'SDL2.dll'.'SDL_GetNumAllocations' +++'_SDL_NewAudioStream'.'SDL2.dll'.'SDL_NewAudioStream' +++'_SDL_AudioStreamPut'.'SDL2.dll'.'SDL_AudioStreamPut' +++'_SDL_AudioStreamGet'.'SDL2.dll'.'SDL_AudioStreamGet' +++'_SDL_AudioStreamClear'.'SDL2.dll'.'SDL_AudioStreamClear' +++'_SDL_AudioStreamAvailable'.'SDL2.dll'.'SDL_AudioStreamAvailable' +++'_SDL_FreeAudioStream'.'SDL2.dll'.'SDL_FreeAudioStream' +++'_SDL_AudioStreamFlush'.'SDL2.dll'.'SDL_AudioStreamFlush' +++'_SDL_acosf'.'SDL2.dll'.'SDL_acosf' +++'_SDL_asinf'.'SDL2.dll'.'SDL_asinf' +++'_SDL_atanf'.'SDL2.dll'.'SDL_atanf' +++'_SDL_atan2f'.'SDL2.dll'.'SDL_atan2f' +++'_SDL_ceilf'.'SDL2.dll'.'SDL_ceilf' +++'_SDL_copysignf'.'SDL2.dll'.'SDL_copysignf' +++'_SDL_fabsf'.'SDL2.dll'.'SDL_fabsf' +++'_SDL_floorf'.'SDL2.dll'.'SDL_floorf' +++'_SDL_logf'.'SDL2.dll'.'SDL_logf' +++'_SDL_powf'.'SDL2.dll'.'SDL_powf' +++'_SDL_scalbnf'.'SDL2.dll'.'SDL_scalbnf' +++'_SDL_fmod'.'SDL2.dll'.'SDL_fmod' +++'_SDL_fmodf'.'SDL2.dll'.'SDL_fmodf' +++'_SDL_SetYUVConversionMode'.'SDL2.dll'.'SDL_SetYUVConversionMode' +++'_SDL_GetYUVConversionMode'.'SDL2.dll'.'SDL_GetYUVConversionMode' +++'_SDL_GetYUVConversionModeForResolution'.'SDL2.dll'.'SDL_GetYUVConversionModeForResolution' +++'_SDL_RenderGetMetalLayer'.'SDL2.dll'.'SDL_RenderGetMetalLayer' +++'_SDL_RenderGetMetalCommandEncoder'.'SDL2.dll'.'SDL_RenderGetMetalCommandEncoder' +# ++'_SDL_IsAndroidTV'.'SDL2.dll'.'SDL_IsAndroidTV' +# ++'_SDL_WinRTGetDeviceFamily'.'SDL2.dll'.'SDL_WinRTGetDeviceFamily' +++'_SDL_log10'.'SDL2.dll'.'SDL_log10' +++'_SDL_log10f'.'SDL2.dll'.'SDL_log10f' +++'_SDL_GameControllerMappingForDeviceIndex'.'SDL2.dll'.'SDL_GameControllerMappingForDeviceIndex' +# ++'_SDL_LinuxSetThreadPriority'.'SDL2.dll'.'SDL_LinuxSetThreadPriority' +++'_SDL_HasAVX512F'.'SDL2.dll'.'SDL_HasAVX512F' +# ++'_SDL_IsChromebook'.'SDL2.dll'.'SDL_IsChromebook' +# ++'_SDL_IsDeXMode'.'SDL2.dll'.'SDL_IsDeXMode' +# ++'_SDL_AndroidBackButton'.'SDL2.dll'.'SDL_AndroidBackButton' +++'_SDL_exp'.'SDL2.dll'.'SDL_exp' +++'_SDL_expf'.'SDL2.dll'.'SDL_expf' +++'_SDL_wcsdup'.'SDL2.dll'.'SDL_wcsdup' +++'_SDL_GameControllerRumble'.'SDL2.dll'.'SDL_GameControllerRumble' +++'_SDL_JoystickRumble'.'SDL2.dll'.'SDL_JoystickRumble' +++'_SDL_NumSensors'.'SDL2.dll'.'SDL_NumSensors' +++'_SDL_SensorGetDeviceName'.'SDL2.dll'.'SDL_SensorGetDeviceName' +++'_SDL_SensorGetDeviceType'.'SDL2.dll'.'SDL_SensorGetDeviceType' +++'_SDL_SensorGetDeviceNonPortableType'.'SDL2.dll'.'SDL_SensorGetDeviceNonPortableType' +++'_SDL_SensorGetDeviceInstanceID'.'SDL2.dll'.'SDL_SensorGetDeviceInstanceID' +++'_SDL_SensorOpen'.'SDL2.dll'.'SDL_SensorOpen' +++'_SDL_SensorFromInstanceID'.'SDL2.dll'.'SDL_SensorFromInstanceID' +++'_SDL_SensorGetName'.'SDL2.dll'.'SDL_SensorGetName' +++'_SDL_SensorGetType'.'SDL2.dll'.'SDL_SensorGetType' +++'_SDL_SensorGetNonPortableType'.'SDL2.dll'.'SDL_SensorGetNonPortableType' +++'_SDL_SensorGetInstanceID'.'SDL2.dll'.'SDL_SensorGetInstanceID' +++'_SDL_SensorGetData'.'SDL2.dll'.'SDL_SensorGetData' +++'_SDL_SensorClose'.'SDL2.dll'.'SDL_SensorClose' +++'_SDL_SensorUpdate'.'SDL2.dll'.'SDL_SensorUpdate' +++'_SDL_IsTablet'.'SDL2.dll'.'SDL_IsTablet' +++'_SDL_GetDisplayOrientation'.'SDL2.dll'.'SDL_GetDisplayOrientation' +++'_SDL_HasColorKey'.'SDL2.dll'.'SDL_HasColorKey' +++'_SDL_CreateThreadWithStackSize'.'SDL2.dll'.'SDL_CreateThreadWithStackSize' +++'_SDL_JoystickGetDevicePlayerIndex'.'SDL2.dll'.'SDL_JoystickGetDevicePlayerIndex' +++'_SDL_JoystickGetPlayerIndex'.'SDL2.dll'.'SDL_JoystickGetPlayerIndex' +++'_SDL_GameControllerGetPlayerIndex'.'SDL2.dll'.'SDL_GameControllerGetPlayerIndex' +++'_SDL_RenderFlush'.'SDL2.dll'.'SDL_RenderFlush' +++'_SDL_RenderDrawPointF'.'SDL2.dll'.'SDL_RenderDrawPointF' +++'_SDL_RenderDrawPointsF'.'SDL2.dll'.'SDL_RenderDrawPointsF' +++'_SDL_RenderDrawLineF'.'SDL2.dll'.'SDL_RenderDrawLineF' +++'_SDL_RenderDrawLinesF'.'SDL2.dll'.'SDL_RenderDrawLinesF' +++'_SDL_RenderDrawRectF'.'SDL2.dll'.'SDL_RenderDrawRectF' +++'_SDL_RenderDrawRectsF'.'SDL2.dll'.'SDL_RenderDrawRectsF' +++'_SDL_RenderFillRectF'.'SDL2.dll'.'SDL_RenderFillRectF' +++'_SDL_RenderFillRectsF'.'SDL2.dll'.'SDL_RenderFillRectsF' +++'_SDL_RenderCopyF'.'SDL2.dll'.'SDL_RenderCopyF' +++'_SDL_RenderCopyExF'.'SDL2.dll'.'SDL_RenderCopyExF' +++'_SDL_GetTouchDeviceType'.'SDL2.dll'.'SDL_GetTouchDeviceType' +# ++'_SDL_UIKitRunApp'.'SDL2.dll'.'SDL_UIKitRunApp' +++'_SDL_SIMDGetAlignment'.'SDL2.dll'.'SDL_SIMDGetAlignment' +++'_SDL_SIMDAlloc'.'SDL2.dll'.'SDL_SIMDAlloc' +++'_SDL_SIMDFree'.'SDL2.dll'.'SDL_SIMDFree' +++'_SDL_RWsize'.'SDL2.dll'.'SDL_RWsize' +++'_SDL_RWseek'.'SDL2.dll'.'SDL_RWseek' +++'_SDL_RWtell'.'SDL2.dll'.'SDL_RWtell' +++'_SDL_RWread'.'SDL2.dll'.'SDL_RWread' +++'_SDL_RWwrite'.'SDL2.dll'.'SDL_RWwrite' +++'_SDL_RWclose'.'SDL2.dll'.'SDL_RWclose' +++'_SDL_LoadFile'.'SDL2.dll'.'SDL_LoadFile' +++'_SDL_Metal_CreateView'.'SDL2.dll'.'SDL_Metal_CreateView' +++'_SDL_Metal_DestroyView'.'SDL2.dll'.'SDL_Metal_DestroyView' +++'_SDL_LockTextureToSurface'.'SDL2.dll'.'SDL_LockTextureToSurface' +++'_SDL_HasARMSIMD'.'SDL2.dll'.'SDL_HasARMSIMD' +++'_SDL_strtokr'.'SDL2.dll'.'SDL_strtokr' +++'_SDL_wcsstr'.'SDL2.dll'.'SDL_wcsstr' +++'_SDL_wcsncmp'.'SDL2.dll'.'SDL_wcsncmp' +++'_SDL_GameControllerTypeForIndex'.'SDL2.dll'.'SDL_GameControllerTypeForIndex' +++'_SDL_GameControllerGetType'.'SDL2.dll'.'SDL_GameControllerGetType' +++'_SDL_GameControllerFromPlayerIndex'.'SDL2.dll'.'SDL_GameControllerFromPlayerIndex' +++'_SDL_GameControllerSetPlayerIndex'.'SDL2.dll'.'SDL_GameControllerSetPlayerIndex' +++'_SDL_JoystickFromPlayerIndex'.'SDL2.dll'.'SDL_JoystickFromPlayerIndex' +++'_SDL_JoystickSetPlayerIndex'.'SDL2.dll'.'SDL_JoystickSetPlayerIndex' +++'_SDL_SetTextureScaleMode'.'SDL2.dll'.'SDL_SetTextureScaleMode' +++'_SDL_GetTextureScaleMode'.'SDL2.dll'.'SDL_GetTextureScaleMode' +++'_SDL_OnApplicationWillTerminate'.'SDL2.dll'.'SDL_OnApplicationWillTerminate' +++'_SDL_OnApplicationDidReceiveMemoryWarning'.'SDL2.dll'.'SDL_OnApplicationDidReceiveMemoryWarning' +++'_SDL_OnApplicationWillResignActive'.'SDL2.dll'.'SDL_OnApplicationWillResignActive' +++'_SDL_OnApplicationDidEnterBackground'.'SDL2.dll'.'SDL_OnApplicationDidEnterBackground' +++'_SDL_OnApplicationWillEnterForeground'.'SDL2.dll'.'SDL_OnApplicationWillEnterForeground' +++'_SDL_OnApplicationDidBecomeActive'.'SDL2.dll'.'SDL_OnApplicationDidBecomeActive' +# ++'_SDL_OnApplicationDidChangeStatusBarOrientation'.'SDL2.dll'.'SDL_OnApplicationDidChangeStatusBarOrientation' +# ++'_SDL_GetAndroidSDKVersion'.'SDL2.dll'.'SDL_GetAndroidSDKVersion' +++'_SDL_isupper'.'SDL2.dll'.'SDL_isupper' +++'_SDL_islower'.'SDL2.dll'.'SDL_islower' +++'_SDL_JoystickAttachVirtual'.'SDL2.dll'.'SDL_JoystickAttachVirtual' +++'_SDL_JoystickDetachVirtual'.'SDL2.dll'.'SDL_JoystickDetachVirtual' +++'_SDL_JoystickIsVirtual'.'SDL2.dll'.'SDL_JoystickIsVirtual' +++'_SDL_JoystickSetVirtualAxis'.'SDL2.dll'.'SDL_JoystickSetVirtualAxis' +++'_SDL_JoystickSetVirtualButton'.'SDL2.dll'.'SDL_JoystickSetVirtualButton' +++'_SDL_JoystickSetVirtualHat'.'SDL2.dll'.'SDL_JoystickSetVirtualHat' +++'_SDL_GetErrorMsg'.'SDL2.dll'.'SDL_GetErrorMsg' +++'_SDL_LockSensors'.'SDL2.dll'.'SDL_LockSensors' +++'_SDL_UnlockSensors'.'SDL2.dll'.'SDL_UnlockSensors' +++'_SDL_Metal_GetLayer'.'SDL2.dll'.'SDL_Metal_GetLayer' +++'_SDL_Metal_GetDrawableSize'.'SDL2.dll'.'SDL_Metal_GetDrawableSize' +++'_SDL_trunc'.'SDL2.dll'.'SDL_trunc' +++'_SDL_truncf'.'SDL2.dll'.'SDL_truncf' +++'_SDL_GetPreferredLocales'.'SDL2.dll'.'SDL_GetPreferredLocales' +++'_SDL_SIMDRealloc'.'SDL2.dll'.'SDL_SIMDRealloc' +# ++'_SDL_AndroidRequestPermission'.'SDL2.dll'.'SDL_AndroidRequestPermission' +++'_SDL_OpenURL'.'SDL2.dll'.'SDL_OpenURL' +++'_SDL_HasSurfaceRLE'.'SDL2.dll'.'SDL_HasSurfaceRLE' +++'_SDL_GameControllerHasLED'.'SDL2.dll'.'SDL_GameControllerHasLED' +++'_SDL_GameControllerSetLED'.'SDL2.dll'.'SDL_GameControllerSetLED' +++'_SDL_JoystickHasLED'.'SDL2.dll'.'SDL_JoystickHasLED' +++'_SDL_JoystickSetLED'.'SDL2.dll'.'SDL_JoystickSetLED' +++'_SDL_GameControllerRumbleTriggers'.'SDL2.dll'.'SDL_GameControllerRumbleTriggers' +++'_SDL_JoystickRumbleTriggers'.'SDL2.dll'.'SDL_JoystickRumbleTriggers' +++'_SDL_GameControllerHasAxis'.'SDL2.dll'.'SDL_GameControllerHasAxis' +++'_SDL_GameControllerHasButton'.'SDL2.dll'.'SDL_GameControllerHasButton' +++'_SDL_GameControllerGetNumTouchpads'.'SDL2.dll'.'SDL_GameControllerGetNumTouchpads' +++'_SDL_GameControllerGetNumTouchpadFingers'.'SDL2.dll'.'SDL_GameControllerGetNumTouchpadFingers' +++'_SDL_GameControllerGetTouchpadFinger'.'SDL2.dll'.'SDL_GameControllerGetTouchpadFinger' +++'_SDL_crc32'.'SDL2.dll'.'SDL_crc32' +++'_SDL_GameControllerGetSerial'.'SDL2.dll'.'SDL_GameControllerGetSerial' +++'_SDL_JoystickGetSerial'.'SDL2.dll'.'SDL_JoystickGetSerial' +++'_SDL_GameControllerHasSensor'.'SDL2.dll'.'SDL_GameControllerHasSensor' +++'_SDL_GameControllerSetSensorEnabled'.'SDL2.dll'.'SDL_GameControllerSetSensorEnabled' +++'_SDL_GameControllerIsSensorEnabled'.'SDL2.dll'.'SDL_GameControllerIsSensorEnabled' +++'_SDL_GameControllerGetSensorData'.'SDL2.dll'.'SDL_GameControllerGetSensorData' +++'_SDL_wcscasecmp'.'SDL2.dll'.'SDL_wcscasecmp' +++'_SDL_wcsncasecmp'.'SDL2.dll'.'SDL_wcsncasecmp' +++'_SDL_round'.'SDL2.dll'.'SDL_round' +++'_SDL_roundf'.'SDL2.dll'.'SDL_roundf' +++'_SDL_lround'.'SDL2.dll'.'SDL_lround' +++'_SDL_lroundf'.'SDL2.dll'.'SDL_lroundf' +++'_SDL_SoftStretchLinear'.'SDL2.dll'.'SDL_SoftStretchLinear' +++'_SDL_RenderGetD3D11Device'.'SDL2.dll'.'SDL_RenderGetD3D11Device' +++'_SDL_UpdateNVTexture'.'SDL2.dll'.'SDL_UpdateNVTexture' +++'_SDL_SetWindowKeyboardGrab'.'SDL2.dll'.'SDL_SetWindowKeyboardGrab' +++'_SDL_SetWindowMouseGrab'.'SDL2.dll'.'SDL_SetWindowMouseGrab' +++'_SDL_GetWindowKeyboardGrab'.'SDL2.dll'.'SDL_GetWindowKeyboardGrab' +++'_SDL_GetWindowMouseGrab'.'SDL2.dll'.'SDL_GetWindowMouseGrab' +++'_SDL_isalpha'.'SDL2.dll'.'SDL_isalpha' +++'_SDL_isalnum'.'SDL2.dll'.'SDL_isalnum' +++'_SDL_isblank'.'SDL2.dll'.'SDL_isblank' +++'_SDL_iscntrl'.'SDL2.dll'.'SDL_iscntrl' +++'_SDL_isxdigit'.'SDL2.dll'.'SDL_isxdigit' +++'_SDL_ispunct'.'SDL2.dll'.'SDL_ispunct' +++'_SDL_isprint'.'SDL2.dll'.'SDL_isprint' +++'_SDL_isgraph'.'SDL2.dll'.'SDL_isgraph' +# ++'_SDL_AndroidShowToast'.'SDL2.dll'.'SDL_AndroidShowToast' +++'_SDL_GetAudioDeviceSpec'.'SDL2.dll'.'SDL_GetAudioDeviceSpec' +++'_SDL_TLSCleanup'.'SDL2.dll'.'SDL_TLSCleanup' +++'_SDL_SetWindowAlwaysOnTop'.'SDL2.dll'.'SDL_SetWindowAlwaysOnTop' +++'_SDL_FlashWindow'.'SDL2.dll'.'SDL_FlashWindow' +++'_SDL_GameControllerSendEffect'.'SDL2.dll'.'SDL_GameControllerSendEffect' +++'_SDL_JoystickSendEffect'.'SDL2.dll'.'SDL_JoystickSendEffect' +++'_SDL_GameControllerGetSensorDataRate'.'SDL2.dll'.'SDL_GameControllerGetSensorDataRate' +++'_SDL_SetTextureUserData'.'SDL2.dll'.'SDL_SetTextureUserData' +++'_SDL_GetTextureUserData'.'SDL2.dll'.'SDL_GetTextureUserData' +++'_SDL_RenderGeometry'.'SDL2.dll'.'SDL_RenderGeometry' +++'_SDL_RenderGeometryRaw'.'SDL2.dll'.'SDL_RenderGeometryRaw' +++'_SDL_RenderSetVSync'.'SDL2.dll'.'SDL_RenderSetVSync' +++'_SDL_asprintf'.'SDL2.dll'.'SDL_asprintf' +++'_SDL_vasprintf'.'SDL2.dll'.'SDL_vasprintf' +++'_SDL_GetWindowICCProfile'.'SDL2.dll'.'SDL_GetWindowICCProfile' +++'_SDL_GetTicks64'.'SDL2.dll'.'SDL_GetTicks64' +# ++'_SDL_LinuxSetThreadPriorityAndPolicy'.'SDL2.dll'.'SDL_LinuxSetThreadPriorityAndPolicy' +++'_SDL_GameControllerGetAppleSFSymbolsNameForButton'.'SDL2.dll'.'SDL_GameControllerGetAppleSFSymbolsNameForButton' +++'_SDL_GameControllerGetAppleSFSymbolsNameForAxis'.'SDL2.dll'.'SDL_GameControllerGetAppleSFSymbolsNameForAxis' +++'_SDL_hid_init'.'SDL2.dll'.'SDL_hid_init' +++'_SDL_hid_exit'.'SDL2.dll'.'SDL_hid_exit' +++'_SDL_hid_device_change_count'.'SDL2.dll'.'SDL_hid_device_change_count' +++'_SDL_hid_enumerate'.'SDL2.dll'.'SDL_hid_enumerate' +++'_SDL_hid_free_enumeration'.'SDL2.dll'.'SDL_hid_free_enumeration' +++'_SDL_hid_open'.'SDL2.dll'.'SDL_hid_open' +++'_SDL_hid_open_path'.'SDL2.dll'.'SDL_hid_open_path' +++'_SDL_hid_write'.'SDL2.dll'.'SDL_hid_write' +++'_SDL_hid_read_timeout'.'SDL2.dll'.'SDL_hid_read_timeout' +++'_SDL_hid_read'.'SDL2.dll'.'SDL_hid_read' +++'_SDL_hid_set_nonblocking'.'SDL2.dll'.'SDL_hid_set_nonblocking' +++'_SDL_hid_send_feature_report'.'SDL2.dll'.'SDL_hid_send_feature_report' +++'_SDL_hid_get_feature_report'.'SDL2.dll'.'SDL_hid_get_feature_report' +++'_SDL_hid_close'.'SDL2.dll'.'SDL_hid_close' +++'_SDL_hid_get_manufacturer_string'.'SDL2.dll'.'SDL_hid_get_manufacturer_string' +++'_SDL_hid_get_product_string'.'SDL2.dll'.'SDL_hid_get_product_string' +++'_SDL_hid_get_serial_number_string'.'SDL2.dll'.'SDL_hid_get_serial_number_string' +++'_SDL_hid_get_indexed_string'.'SDL2.dll'.'SDL_hid_get_indexed_string' +++'_SDL_SetWindowMouseRect'.'SDL2.dll'.'SDL_SetWindowMouseRect' +++'_SDL_GetWindowMouseRect'.'SDL2.dll'.'SDL_GetWindowMouseRect' +++'_SDL_RenderWindowToLogical'.'SDL2.dll'.'SDL_RenderWindowToLogical' +++'_SDL_RenderLogicalToWindow'.'SDL2.dll'.'SDL_RenderLogicalToWindow' +++'_SDL_JoystickHasRumble'.'SDL2.dll'.'SDL_JoystickHasRumble' +++'_SDL_JoystickHasRumbleTriggers'.'SDL2.dll'.'SDL_JoystickHasRumbleTriggers' +++'_SDL_GameControllerHasRumble'.'SDL2.dll'.'SDL_GameControllerHasRumble' +++'_SDL_GameControllerHasRumbleTriggers'.'SDL2.dll'.'SDL_GameControllerHasRumbleTriggers' +++'_SDL_hid_ble_scan'.'SDL2.dll'.'SDL_hid_ble_scan' +++'_SDL_PremultiplyAlpha'.'SDL2.dll'.'SDL_PremultiplyAlpha' +# ++'_SDL_AndroidSendMessage'.'SDL2.dll'.'SDL_AndroidSendMessage' +++'_SDL_GetTouchName'.'SDL2.dll'.'SDL_GetTouchName' +++'_SDL_ClearComposition'.'SDL2.dll'.'SDL_ClearComposition' +++'_SDL_IsTextInputShown'.'SDL2.dll'.'SDL_IsTextInputShown' +++'_SDL_HasIntersectionF'.'SDL2.dll'.'SDL_HasIntersectionF' +++'_SDL_IntersectFRect'.'SDL2.dll'.'SDL_IntersectFRect' +++'_SDL_UnionFRect'.'SDL2.dll'.'SDL_UnionFRect' +++'_SDL_EncloseFPoints'.'SDL2.dll'.'SDL_EncloseFPoints' +++'_SDL_IntersectFRectAndLine'.'SDL2.dll'.'SDL_IntersectFRectAndLine' +++'_SDL_RenderGetWindow'.'SDL2.dll'.'SDL_RenderGetWindow' +++'_SDL_bsearch'.'SDL2.dll'.'SDL_bsearch' +++'_SDL_GameControllerPathForIndex'.'SDL2.dll'.'SDL_GameControllerPathForIndex' +++'_SDL_GameControllerPath'.'SDL2.dll'.'SDL_GameControllerPath' +++'_SDL_JoystickPathForIndex'.'SDL2.dll'.'SDL_JoystickPathForIndex' +++'_SDL_JoystickPath'.'SDL2.dll'.'SDL_JoystickPath' +++'_SDL_JoystickAttachVirtualEx'.'SDL2.dll'.'SDL_JoystickAttachVirtualEx' +++'_SDL_GameControllerGetFirmwareVersion'.'SDL2.dll'.'SDL_GameControllerGetFirmwareVersion' +++'_SDL_JoystickGetFirmwareVersion'.'SDL2.dll'.'SDL_JoystickGetFirmwareVersion' +++'_SDL_GUIDToString'.'SDL2.dll'.'SDL_GUIDToString' +++'_SDL_GUIDFromString'.'SDL2.dll'.'SDL_GUIDFromString' +++'_SDL_HasLSX'.'SDL2.dll'.'SDL_HasLSX' +++'_SDL_HasLASX'.'SDL2.dll'.'SDL_HasLASX' +++'_SDL_RenderGetD3D12Device'.'SDL2.dll'.'SDL_RenderGetD3D12Device' +++'_SDL_utf8strnlen'.'SDL2.dll'.'SDL_utf8strnlen' +# ++'_SDL_GDKGetTaskQueue'.'SDL2.dll'.'SDL_GDKGetTaskQueue' +# ++'_SDL_GDKRunApp'.'SDL2.dll'.'SDL_GDKRunApp' +++'_SDL_GetOriginalMemoryFunctions'.'SDL2.dll'.'SDL_GetOriginalMemoryFunctions' +++'_SDL_ResetKeyboard'.'SDL2.dll'.'SDL_ResetKeyboard' +++'_SDL_GetDefaultAudioInfo'.'SDL2.dll'.'SDL_GetDefaultAudioInfo' +++'_SDL_GetPointDisplayIndex'.'SDL2.dll'.'SDL_GetPointDisplayIndex' +++'_SDL_GetRectDisplayIndex'.'SDL2.dll'.'SDL_GetRectDisplayIndex' +++'_SDL_ResetHint'.'SDL2.dll'.'SDL_ResetHint' +++'_SDL_crc16'.'SDL2.dll'.'SDL_crc16' +++'_SDL_GetWindowSizeInPixels'.'SDL2.dll'.'SDL_GetWindowSizeInPixels' +++'_SDL_GetJoystickGUIDInfo'.'SDL2.dll'.'SDL_GetJoystickGUIDInfo' +++'_SDL_SetPrimarySelectionText'.'SDL2.dll'.'SDL_SetPrimarySelectionText' +++'_SDL_GetPrimarySelectionText'.'SDL2.dll'.'SDL_GetPrimarySelectionText' +++'_SDL_HasPrimarySelectionText'.'SDL2.dll'.'SDL_HasPrimarySelectionText' +++'_SDL_GameControllerGetSensorDataWithTimestamp'.'SDL2.dll'.'SDL_GameControllerGetSensorDataWithTimestamp' +++'_SDL_SensorGetDataWithTimestamp'.'SDL2.dll'.'SDL_SensorGetDataWithTimestamp' +++'_SDL_ResetHints'.'SDL2.dll'.'SDL_ResetHints' +++'_SDL_strcasestr'.'SDL2.dll'.'SDL_strcasestr' +# ++'_SDL_GDKSuspendComplete'.'SDL2.dll'.'SDL_GDKSuspendComplete' +++'_SDL_HasWindowSurface'.'SDL2.dll'.'SDL_HasWindowSurface' +++'_SDL_DestroyWindowSurface'.'SDL2.dll'.'SDL_DestroyWindowSurface' +# ++'_SDL_GDKGetDefaultUser'.'SDL2.dll'.'SDL_GDKGetDefaultUser' +++'_SDL_GameControllerGetSteamHandle'.'SDL2.dll'.'SDL_GameControllerGetSteamHandle' diff --git a/SDL2-2.30.5/src/dynapi/SDL_dynapi.c b/SDL2-2.30.5/src/dynapi/SDL_dynapi.c new file mode 100644 index 0000000..861f88a --- /dev/null +++ b/SDL2-2.30.5/src/dynapi/SDL_dynapi.c @@ -0,0 +1,525 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_dynapi.h" + +#if SDL_DYNAMIC_API + +#define SDL_DYNAMIC_API_ENVVAR "SDL_DYNAMIC_API" + +#if defined(__OS2__) +#define INCL_DOS +#define INCL_DOSERRORS +#include +#include +#endif + +#include "SDL.h" + +/* These headers have system specific definitions, so aren't included above */ +#include "SDL_syswm.h" +#include "SDL_vulkan.h" + +/* This is the version of the dynamic API. This doesn't match the SDL version + and should not change until there's been a major revamp in API/ABI. + So 2.0.5 adds functions over 2.0.4? This number doesn't change; + the sizeof(jump_table) changes instead. But 2.1.0 changes how a function + works in an incompatible way or removes a function? This number changes, + since sizeof(jump_table) isn't sufficient anymore. It's likely + we'll forget to bump every time we add a function, so this is the + failsafe switch for major API change decisions. Respect it and use it + sparingly. */ +#define SDL_DYNAPI_VERSION 1 + +#ifdef __cplusplus +extern "C" { +#endif + +static void SDL_InitDynamicAPI(void); + +/* BE CAREFUL CALLING ANY SDL CODE IN HERE, IT WILL BLOW UP. + Even self-contained stuff might call SDL_Error and break everything. */ + +/* behold, the macro salsa! */ + +/* !!! FIXME: ...disabled...until we write it. :) */ +#define DISABLE_JUMP_MAGIC 1 + +#if DISABLE_JUMP_MAGIC +/* Can't use the macro for varargs nonsense. This is atrocious. */ +#define SDL_DYNAPI_VARARGS_LOGFN(_static, name, initcall, logname, prio) \ + _static void SDLCALL SDL_Log##logname##name(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) \ + { \ + va_list ap; \ + initcall; \ + va_start(ap, fmt); \ + jump_table.SDL_LogMessageV(category, SDL_LOG_PRIORITY_##prio, fmt, ap); \ + va_end(ap); \ + } + +#define SDL_DYNAPI_VARARGS(_static, name, initcall) \ + _static int SDLCALL SDL_SetError##name(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) \ + { \ + char buf[128], *str = buf; \ + int result; \ + va_list ap; \ + initcall; \ + va_start(ap, fmt); \ + result = jump_table.SDL_vsnprintf(buf, sizeof(buf), fmt, ap); \ + va_end(ap); \ + if (result >= 0 && (size_t)result >= sizeof(buf)) { \ + size_t len = (size_t)result + 1; \ + str = (char *)jump_table.SDL_malloc(len); \ + if (str) { \ + va_start(ap, fmt); \ + result = jump_table.SDL_vsnprintf(str, len, fmt, ap); \ + va_end(ap); \ + } \ + } \ + if (result >= 0) { \ + result = jump_table.SDL_SetError("%s", str); \ + } \ + if (str != buf) { \ + jump_table.SDL_free(str); \ + } \ + return result; \ + } \ + _static int SDLCALL SDL_sscanf##name(const char *buf, SDL_SCANF_FORMAT_STRING const char *fmt, ...) \ + { \ + int retval; \ + va_list ap; \ + initcall; \ + va_start(ap, fmt); \ + retval = jump_table.SDL_vsscanf(buf, fmt, ap); \ + va_end(ap); \ + return retval; \ + } \ + _static int SDLCALL SDL_snprintf##name(SDL_OUT_Z_CAP(maxlen) char *buf, size_t maxlen, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) \ + { \ + int retval; \ + va_list ap; \ + initcall; \ + va_start(ap, fmt); \ + retval = jump_table.SDL_vsnprintf(buf, maxlen, fmt, ap); \ + va_end(ap); \ + return retval; \ + } \ + _static int SDLCALL SDL_asprintf##name(char **strp, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) \ + { \ + int retval; \ + va_list ap; \ + initcall; \ + va_start(ap, fmt); \ + retval = jump_table.SDL_vasprintf(strp, fmt, ap); \ + va_end(ap); \ + return retval; \ + } \ + _static void SDLCALL SDL_Log##name(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) \ + { \ + va_list ap; \ + initcall; \ + va_start(ap, fmt); \ + jump_table.SDL_LogMessageV(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, fmt, ap); \ + va_end(ap); \ + } \ + _static void SDLCALL SDL_LogMessage##name(int category, SDL_LogPriority priority, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) \ + { \ + va_list ap; \ + initcall; \ + va_start(ap, fmt); \ + jump_table.SDL_LogMessageV(category, priority, fmt, ap); \ + va_end(ap); \ + } \ + SDL_DYNAPI_VARARGS_LOGFN(_static, name, initcall, Verbose, VERBOSE) \ + SDL_DYNAPI_VARARGS_LOGFN(_static, name, initcall, Debug, DEBUG) \ + SDL_DYNAPI_VARARGS_LOGFN(_static, name, initcall, Info, INFO) \ + SDL_DYNAPI_VARARGS_LOGFN(_static, name, initcall, Warn, WARN) \ + SDL_DYNAPI_VARARGS_LOGFN(_static, name, initcall, Error, ERROR) \ + SDL_DYNAPI_VARARGS_LOGFN(_static, name, initcall, Critical, CRITICAL) +#endif + +/* Typedefs for function pointers for jump table, and predeclare funcs */ +/* The DEFAULT funcs will init jump table and then call real function. */ +/* The REAL funcs are the actual functions, name-mangled to not clash. */ +#define SDL_DYNAPI_PROC(rc, fn, params, args, ret) \ + typedef rc (SDLCALL *SDL_DYNAPIFN_##fn) params;\ + static rc SDLCALL fn##_DEFAULT params; \ + extern rc SDLCALL fn##_REAL params; +#include "SDL_dynapi_procs.h" +#undef SDL_DYNAPI_PROC + +/* The jump table! */ +typedef struct +{ +#define SDL_DYNAPI_PROC(rc, fn, params, args, ret) SDL_DYNAPIFN_##fn fn; +#include "SDL_dynapi_procs.h" +#undef SDL_DYNAPI_PROC +} SDL_DYNAPI_jump_table; + +/* Predeclare the default functions for initializing the jump table. */ +#define SDL_DYNAPI_PROC(rc, fn, params, args, ret) static rc SDLCALL fn##_DEFAULT params; +#include "SDL_dynapi_procs.h" +#undef SDL_DYNAPI_PROC + +/* The actual jump table. */ +static SDL_DYNAPI_jump_table jump_table = { +#define SDL_DYNAPI_PROC(rc, fn, params, args, ret) fn##_DEFAULT, +#include "SDL_dynapi_procs.h" +#undef SDL_DYNAPI_PROC +}; + +/* Default functions init the function table then call right thing. */ +#if DISABLE_JUMP_MAGIC +#define SDL_DYNAPI_PROC(rc, fn, params, args, ret) \ + static rc SDLCALL fn##_DEFAULT params \ + { \ + SDL_InitDynamicAPI(); \ + ret jump_table.fn args; \ + } +#define SDL_DYNAPI_PROC_NO_VARARGS +#include "SDL_dynapi_procs.h" +#undef SDL_DYNAPI_PROC +#undef SDL_DYNAPI_PROC_NO_VARARGS +SDL_DYNAPI_VARARGS(static, _DEFAULT, SDL_InitDynamicAPI()) +#else +/* !!! FIXME: need the jump magic. */ +#error Write me. +#endif + +/* Public API functions to jump into the jump table. */ +#if DISABLE_JUMP_MAGIC +#define SDL_DYNAPI_PROC(rc, fn, params, args, ret) \ + rc SDLCALL fn params \ + { \ + ret jump_table.fn args; \ + } +#define SDL_DYNAPI_PROC_NO_VARARGS +#include "SDL_dynapi_procs.h" +#undef SDL_DYNAPI_PROC +#undef SDL_DYNAPI_PROC_NO_VARARGS +SDL_DYNAPI_VARARGS(, , ) +#else +/* !!! FIXME: need the jump magic. */ +#error Write me. +#endif + +#define ENABLE_SDL_CALL_LOGGING 0 +#if ENABLE_SDL_CALL_LOGGING +static int SDLCALL SDL_SetError_LOGSDLCALLS(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) +{ + char buf[512]; /* !!! FIXME: dynamic allocation */ + va_list ap; + SDL_Log_REAL("SDL2CALL SDL_SetError"); + va_start(ap, fmt); + SDL_vsnprintf_REAL(buf, sizeof(buf), fmt, ap); + va_end(ap); + return SDL_SetError_REAL("%s", buf); +} +static int SDLCALL SDL_sscanf_LOGSDLCALLS(const char *buf, SDL_SCANF_FORMAT_STRING const char *fmt, ...) +{ + int retval; + va_list ap; + SDL_Log_REAL("SDL2CALL SDL_sscanf"); + va_start(ap, fmt); + retval = SDL_vsscanf_REAL(buf, fmt, ap); + va_end(ap); + return retval; +} +static int SDLCALL SDL_snprintf_LOGSDLCALLS(SDL_OUT_Z_CAP(maxlen) char *buf, size_t maxlen, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) +{ + int retval; + va_list ap; + SDL_Log_REAL("SDL2CALL SDL_snprintf"); + va_start(ap, fmt); + retval = SDL_vsnprintf_REAL(buf, maxlen, fmt, ap); + va_end(ap); + return retval; +} +static int SDLCALL SDL_asprintf_LOGSDLCALLS(char **strp, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) +{ + int retval; + va_list ap; + SDL_Log_REAL("SDL2CALL SDL_asprintf"); + va_start(ap, fmt); + retval = SDL_vasprintf_REAL(strp, fmt, ap); + va_end(ap); + return retval; +} +static void SDLCALL SDL_Log_LOGSDLCALLS(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) +{ + va_list ap; + SDL_Log_REAL("SDL2CALL SDL_Log"); + va_start(ap, fmt); + SDL_LogMessageV_REAL(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, fmt, ap); + va_end(ap); +} +static void SDLCALL SDL_LogMessage_LOGSDLCALLS(int category, SDL_LogPriority priority, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) +{ + va_list ap; + SDL_Log_REAL("SDL2CALL SDL_LogMessage"); + va_start(ap, fmt); + SDL_LogMessageV_REAL(category, priority, fmt, ap); + va_end(ap); +} +#define SDL_DYNAPI_VARARGS_LOGFN_LOGSDLCALLS(logname, prio) \ + static void SDLCALL SDL_Log##logname##_LOGSDLCALLS(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) { \ + va_list ap; va_start(ap, fmt); \ + SDL_Log_REAL("SDL2CALL SDL_Log%s", #logname); \ + SDL_LogMessageV_REAL(category, SDL_LOG_PRIORITY_##prio, fmt, ap); \ + va_end(ap); \ + } +SDL_DYNAPI_VARARGS_LOGFN_LOGSDLCALLS(Verbose, VERBOSE) +SDL_DYNAPI_VARARGS_LOGFN_LOGSDLCALLS(Debug, DEBUG) +SDL_DYNAPI_VARARGS_LOGFN_LOGSDLCALLS(Info, INFO) +SDL_DYNAPI_VARARGS_LOGFN_LOGSDLCALLS(Warn, WARN) +SDL_DYNAPI_VARARGS_LOGFN_LOGSDLCALLS(Error, ERROR) +SDL_DYNAPI_VARARGS_LOGFN_LOGSDLCALLS(Critical, CRITICAL) +#define SDL_DYNAPI_PROC(rc,fn,params,args,ret) \ + rc SDLCALL fn##_LOGSDLCALLS params { SDL_Log_REAL("SDL2CALL %s", #fn); ret fn##_REAL args; } +#define SDL_DYNAPI_PROC_NO_VARARGS +#include "SDL_dynapi_procs.h" +#undef SDL_DYNAPI_PROC +#undef SDL_DYNAPI_PROC_NO_VARARGS +#endif + +/* we make this a static function so we can call the correct one without the + system's dynamic linker resolving to the wrong version of this. */ +static Sint32 initialize_jumptable(Uint32 apiver, void *table, Uint32 tablesize) +{ + SDL_DYNAPI_jump_table *output_jump_table = (SDL_DYNAPI_jump_table *)table; + + if (apiver != SDL_DYNAPI_VERSION) { + /* !!! FIXME: can maybe handle older versions? */ + return -1; /* not compatible. */ + } else if (tablesize > sizeof(jump_table)) { + return -1; /* newer version of SDL with functions we can't provide. */ + } + +/* Init our jump table first. */ +#if ENABLE_SDL_CALL_LOGGING + { + const char *env = SDL_getenv_REAL("SDL_DYNAPI_LOG_CALLS"); + const SDL_bool log_calls = (env && SDL_atoi_REAL(env)); + if (log_calls) { +#define SDL_DYNAPI_PROC(rc, fn, params, args, ret) jump_table.fn = fn##_LOGSDLCALLS; +#include "SDL_dynapi_procs.h" +#undef SDL_DYNAPI_PROC + } else { +#define SDL_DYNAPI_PROC(rc, fn, params, args, ret) jump_table.fn = fn##_REAL; +#include "SDL_dynapi_procs.h" +#undef SDL_DYNAPI_PROC + } + } +#else +#define SDL_DYNAPI_PROC(rc, fn, params, args, ret) jump_table.fn = fn##_REAL; +#include "SDL_dynapi_procs.h" +#undef SDL_DYNAPI_PROC +#endif + + /* Then the external table... */ + if (output_jump_table != &jump_table) { + jump_table.SDL_memcpy(output_jump_table, &jump_table, tablesize); + } + + /* Safe to call SDL functions now; jump table is initialized! */ + + return 0; /* success! */ +} + +/* Here's the exported entry point that fills in the jump table. */ +/* Use specific types when an "int" might suffice to keep this sane. */ +typedef Sint32 (SDLCALL *SDL_DYNAPI_ENTRYFN)(Uint32 apiver, void *table, Uint32 tablesize); +extern DECLSPEC Sint32 SDLCALL SDL_DYNAPI_entry(Uint32, void *, Uint32); + +Sint32 SDL_DYNAPI_entry(Uint32 apiver, void *table, Uint32 tablesize) +{ + return initialize_jumptable(apiver, table, tablesize); +} + +#ifdef __cplusplus +} +#endif + +/* Obviously we can't use SDL_LoadObject() to load SDL. :) */ +/* Also obviously, we never close the loaded library. */ +#if defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN 1 +#endif +#include +static SDL_INLINE void *get_sdlapi_entry(const char *fname, const char *sym) +{ + HMODULE lib = LoadLibraryA(fname); + void *retval = NULL; + if (lib) { + retval = (void *) GetProcAddress(lib, sym); + if (!retval) { + FreeLibrary(lib); + } + } + return retval; +} + +#elif defined(unix) || defined(__unix__) || defined(__APPLE__) || defined(__HAIKU__) || defined(__QNX__) +#include +static SDL_INLINE void *get_sdlapi_entry(const char *fname, const char *sym) +{ + void *lib = dlopen(fname, RTLD_NOW | RTLD_LOCAL); + void *retval = NULL; + if (lib) { + retval = dlsym(lib, sym); + if (!retval) { + dlclose(lib); + } + } + return retval; +} + +#elif defined(__OS2__) +static SDL_INLINE void *get_sdlapi_entry(const char *fname, const char *sym) +{ + HMODULE hmodule; + PFN retval = NULL; + char error[256]; + if (DosLoadModule(error, sizeof(error), fname, &hmodule) == NO_ERROR) { + if (DosQueryProcAddr(hmodule, 0, sym, &retval) != NO_ERROR) { + DosFreeModule(hmodule); + } + } + return (void *)retval; +} + +#else +#error Please define your platform. +#endif + +static void dynapi_warn(const char *msg) +{ + const char *caption = "SDL Dynamic API Failure!"; +/* SDL_ShowSimpleMessageBox() is a too heavy for here. */ +#if (defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__)) && !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + MessageBoxA(NULL, msg, caption, MB_OK | MB_ICONERROR); +#elif defined(HAVE_STDIO_H) + fprintf(stderr, "\n\n%s\n%s\n\n", caption, msg); + fflush(stderr); +#endif +} + +/* This is not declared in any header, although it is shared between some + parts of SDL, because we don't want anything calling it without an + extremely good reason. */ +#ifdef __cplusplus +extern "C" { +#endif +extern SDL_NORETURN void SDL_ExitProcess(int exitcode); +#if defined(__WATCOMC__) +#pragma aux SDL_ExitProcess aborts; +#endif +#ifdef __cplusplus +} +#endif + +static void SDL_InitDynamicAPILocked(void) +{ + char *libname = SDL_getenv_REAL(SDL_DYNAMIC_API_ENVVAR); + SDL_DYNAPI_ENTRYFN entry = NULL; /* funcs from here by default. */ + SDL_bool use_internal = SDL_TRUE; + + if (libname) { + while (*libname && !entry) { + char *ptr = libname; + while (SDL_TRUE) { + const char ch = *ptr; + if ((ch == ',') || (ch == '\0')) { + *ptr = '\0'; + entry = (SDL_DYNAPI_ENTRYFN)get_sdlapi_entry(libname, "SDL_DYNAPI_entry"); + *ptr = ch; + libname = (ch == '\0') ? ptr : (ptr + 1); + break; + } else { + ptr++; + } + } + } + if (!entry) { + dynapi_warn("Couldn't load an overriding SDL library. Please fix or remove the " SDL_DYNAMIC_API_ENVVAR " environment variable. Using the default SDL."); + /* Just fill in the function pointers from this library, later. */ + } + } + + if (entry) { + if (entry(SDL_DYNAPI_VERSION, &jump_table, sizeof(jump_table)) < 0) { + dynapi_warn("Couldn't override SDL library. Using a newer SDL build might help. Please fix or remove the " SDL_DYNAMIC_API_ENVVAR " environment variable. Using the default SDL."); + /* Just fill in the function pointers from this library, later. */ + } else { + use_internal = SDL_FALSE; /* We overrode SDL! Don't use the internal version! */ + } + } + + /* Just fill in the function pointers from this library. */ + if (use_internal) { + if (initialize_jumptable(SDL_DYNAPI_VERSION, &jump_table, sizeof(jump_table)) < 0) { + /* Now we're screwed. Should definitely abort now. */ + dynapi_warn("Failed to initialize internal SDL dynapi. As this would otherwise crash, we have to abort now."); + SDL_ExitProcess(86); + } + } + + /* we intentionally never close the newly-loaded lib, of course. */ +} + +static void SDL_InitDynamicAPI(void) +{ + /* So the theory is that every function in the jump table defaults to + * calling this function, and then replaces itself with a version that + * doesn't call this function anymore. But it's possible that, in an + * extreme corner case, you can have a second thread hit this function + * while the jump table is being initialized by the first. + * In this case, a spinlock is really painful compared to what spinlocks + * _should_ be used for, but this would only happen once, and should be + * insanely rare, as you would have to spin a thread outside of SDL (as + * SDL_CreateThread() would also call this function before building the + * new thread). + */ + static SDL_bool already_initialized = SDL_FALSE; + + /* SDL_AtomicLock calls SDL mutex functions to emulate if + SDL_ATOMIC_DISABLED, which we can't do here, so in such a + configuration, you're on your own. */ + #ifndef SDL_ATOMIC_DISABLED + static SDL_SpinLock lock = 0; + SDL_AtomicLock_REAL(&lock); + #endif + + if (!already_initialized) { + SDL_InitDynamicAPILocked(); + already_initialized = SDL_TRUE; + } + + #ifndef SDL_ATOMIC_DISABLED + SDL_AtomicUnlock_REAL(&lock); + #endif +} + +#endif /* SDL_DYNAMIC_API */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/dynapi/SDL_dynapi.h b/SDL2-2.30.5/src/dynapi/SDL_dynapi.h similarity index 70% rename from SDL2-2.0.12/src/dynapi/SDL_dynapi.h rename to SDL2-2.30.5/src/dynapi/SDL_dynapi.h index 764e5d9..95b20aa 100644 --- a/SDL2-2.0.12/src/dynapi/SDL_dynapi.h +++ b/SDL2-2.30.5/src/dynapi/SDL_dynapi.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -35,7 +35,7 @@ updated SDL can transparently take advantage of them, but your program will not without this feature. Think hard before turning it off. */ -#ifdef SDL_DYNAMIC_API /* Tried to force it on the command line? */ +#ifdef SDL_DYNAMIC_API /* Tried to force it on the command line? */ #error Nope, you have to edit this file to force this off. #endif @@ -43,20 +43,32 @@ #include "TargetConditionals.h" #endif -#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE /* probably not useful on iOS. */ +#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE /* probably not useful on iOS. */ +#define SDL_DYNAMIC_API 0 +#elif defined(__ANDROID__) /* probably not useful on Android. */ #define SDL_DYNAMIC_API 0 #elif defined(__native_client__) && __native_client__ /* probably not useful on NACL. */ #define SDL_DYNAMIC_API 0 #elif defined(__EMSCRIPTEN__) && __EMSCRIPTEN__ /* probably not useful on Emscripten. */ #define SDL_DYNAMIC_API 0 -#elif defined(SDL_BUILDING_WINRT) && SDL_BUILDING_WINRT /* probably not useful on WinRT, given current .dll loading restrictions */ +#elif defined(SDL_BUILDING_WINRT) && SDL_BUILDING_WINRT /* probably not useful on WinRT, given current .dll loading restrictions */ +#define SDL_DYNAMIC_API 0 +#elif defined(__PS2__) #define SDL_DYNAMIC_API 0 #elif defined(__PSP__) && __PSP__ #define SDL_DYNAMIC_API 0 #elif defined(__riscos__) && __riscos__ /* probably not useful on RISC OS, since dlopen() can't be used when using static linking. */ #define SDL_DYNAMIC_API 0 -#elif defined(__clang_analyzer__) -#define SDL_DYNAMIC_API 0 /* Turn off for static analysis, so reports are more clear. */ +#elif defined(__clang_analyzer__) || defined(SDL_THREAD_SAFETY_ANALYSIS) +#define SDL_DYNAMIC_API 0 /* Turn off for static analysis, so reports are more clear. */ +#elif defined(__VITA__) +#define SDL_DYNAMIC_API 0 /* vitasdk doesn't support dynamic linking */ +#elif defined(__NGAGE__) +#define SDL_DYNAMIC_API 0 /* The N-Gage doesn't support dynamic linking either */ +#elif defined(__3DS__) +#define SDL_DYNAMIC_API 0 /* devkitARM doesn't support dynamic linking */ +#elif defined(DYNAPI_NEEDS_DLOPEN) && !defined(HAVE_DLOPEN) +#define SDL_DYNAMIC_API 0 /* we need dlopen(), but don't have it.... */ #endif /* everyone else. This is where we turn on the API if nothing forced it off. */ diff --git a/SDL2-2.0.12/src/dynapi/SDL_dynapi_overrides.h b/SDL2-2.30.5/src/dynapi/SDL_dynapi_overrides.h similarity index 81% rename from SDL2-2.0.12/src/dynapi/SDL_dynapi_overrides.h rename to SDL2-2.30.5/src/dynapi/SDL_dynapi_overrides.h index a5b4d6a..f57c522 100644 --- a/SDL2-2.0.12/src/dynapi/SDL_dynapi_overrides.h +++ b/SDL2-2.30.5/src/dynapi/SDL_dynapi_overrides.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -439,8 +439,6 @@ #define SDL_iconv_close SDL_iconv_close_REAL #define SDL_iconv SDL_iconv_REAL #define SDL_iconv_string SDL_iconv_string_REAL -#define SDL_CreateRGBSurfaceWithFormat SDL_CreateRGBSurfaceWithFormat_REAL -#define SDL_CreateRGBSurfaceWithFormatFrom SDL_CreateRGBSurfaceWithFormatFrom_REAL #define SDL_CreateRGBSurface SDL_CreateRGBSurface_REAL #define SDL_CreateRGBSurfaceFrom SDL_CreateRGBSurfaceFrom_REAL #define SDL_FreeSurface SDL_FreeSurface_REAL @@ -577,7 +575,6 @@ #define SDL_WarpMouseGlobal SDL_WarpMouseGlobal_REAL #define SDL_WinRTGetFSPathUNICODE SDL_WinRTGetFSPathUNICODE_REAL #define SDL_WinRTGetFSPathUTF8 SDL_WinRTGetFSPathUTF8_REAL -#define SDL_WinRTRunApp SDL_WinRTRunApp_REAL #define SDL_sqrtf SDL_sqrtf_REAL #define SDL_tan SDL_tan_REAL #define SDL_tanf SDL_tanf_REAL @@ -749,3 +746,155 @@ #define SDL_GetAndroidSDKVersion SDL_GetAndroidSDKVersion_REAL #define SDL_isupper SDL_isupper_REAL #define SDL_islower SDL_islower_REAL +#define SDL_JoystickAttachVirtual SDL_JoystickAttachVirtual_REAL +#define SDL_JoystickDetachVirtual SDL_JoystickDetachVirtual_REAL +#define SDL_JoystickIsVirtual SDL_JoystickIsVirtual_REAL +#define SDL_JoystickSetVirtualAxis SDL_JoystickSetVirtualAxis_REAL +#define SDL_JoystickSetVirtualButton SDL_JoystickSetVirtualButton_REAL +#define SDL_JoystickSetVirtualHat SDL_JoystickSetVirtualHat_REAL +#define SDL_GetErrorMsg SDL_GetErrorMsg_REAL +#define SDL_LockSensors SDL_LockSensors_REAL +#define SDL_UnlockSensors SDL_UnlockSensors_REAL +#define SDL_Metal_GetLayer SDL_Metal_GetLayer_REAL +#define SDL_Metal_GetDrawableSize SDL_Metal_GetDrawableSize_REAL +#define SDL_trunc SDL_trunc_REAL +#define SDL_truncf SDL_truncf_REAL +#define SDL_GetPreferredLocales SDL_GetPreferredLocales_REAL +#define SDL_SIMDRealloc SDL_SIMDRealloc_REAL +#define SDL_AndroidRequestPermission SDL_AndroidRequestPermission_REAL +#define SDL_OpenURL SDL_OpenURL_REAL +#define SDL_HasSurfaceRLE SDL_HasSurfaceRLE_REAL +#define SDL_GameControllerHasLED SDL_GameControllerHasLED_REAL +#define SDL_GameControllerSetLED SDL_GameControllerSetLED_REAL +#define SDL_JoystickHasLED SDL_JoystickHasLED_REAL +#define SDL_JoystickSetLED SDL_JoystickSetLED_REAL +#define SDL_GameControllerRumbleTriggers SDL_GameControllerRumbleTriggers_REAL +#define SDL_JoystickRumbleTriggers SDL_JoystickRumbleTriggers_REAL +#define SDL_GameControllerHasAxis SDL_GameControllerHasAxis_REAL +#define SDL_GameControllerHasButton SDL_GameControllerHasButton_REAL +#define SDL_GameControllerGetNumTouchpads SDL_GameControllerGetNumTouchpads_REAL +#define SDL_GameControllerGetNumTouchpadFingers SDL_GameControllerGetNumTouchpadFingers_REAL +#define SDL_GameControllerGetTouchpadFinger SDL_GameControllerGetTouchpadFinger_REAL +#define SDL_crc32 SDL_crc32_REAL +#define SDL_GameControllerGetSerial SDL_GameControllerGetSerial_REAL +#define SDL_JoystickGetSerial SDL_JoystickGetSerial_REAL +#define SDL_GameControllerHasSensor SDL_GameControllerHasSensor_REAL +#define SDL_GameControllerSetSensorEnabled SDL_GameControllerSetSensorEnabled_REAL +#define SDL_GameControllerIsSensorEnabled SDL_GameControllerIsSensorEnabled_REAL +#define SDL_GameControllerGetSensorData SDL_GameControllerGetSensorData_REAL +#define SDL_wcscasecmp SDL_wcscasecmp_REAL +#define SDL_wcsncasecmp SDL_wcsncasecmp_REAL +#define SDL_round SDL_round_REAL +#define SDL_roundf SDL_roundf_REAL +#define SDL_lround SDL_lround_REAL +#define SDL_lroundf SDL_lroundf_REAL +#define SDL_SoftStretchLinear SDL_SoftStretchLinear_REAL +#define SDL_RenderGetD3D11Device SDL_RenderGetD3D11Device_REAL +#define SDL_UpdateNVTexture SDL_UpdateNVTexture_REAL +#define SDL_SetWindowKeyboardGrab SDL_SetWindowKeyboardGrab_REAL +#define SDL_SetWindowMouseGrab SDL_SetWindowMouseGrab_REAL +#define SDL_GetWindowKeyboardGrab SDL_GetWindowKeyboardGrab_REAL +#define SDL_GetWindowMouseGrab SDL_GetWindowMouseGrab_REAL +#define SDL_isalpha SDL_isalpha_REAL +#define SDL_isalnum SDL_isalnum_REAL +#define SDL_isblank SDL_isblank_REAL +#define SDL_iscntrl SDL_iscntrl_REAL +#define SDL_isxdigit SDL_isxdigit_REAL +#define SDL_ispunct SDL_ispunct_REAL +#define SDL_isprint SDL_isprint_REAL +#define SDL_isgraph SDL_isgraph_REAL +#define SDL_AndroidShowToast SDL_AndroidShowToast_REAL +#define SDL_GetAudioDeviceSpec SDL_GetAudioDeviceSpec_REAL +#define SDL_TLSCleanup SDL_TLSCleanup_REAL +#define SDL_SetWindowAlwaysOnTop SDL_SetWindowAlwaysOnTop_REAL +#define SDL_FlashWindow SDL_FlashWindow_REAL +#define SDL_GameControllerSendEffect SDL_GameControllerSendEffect_REAL +#define SDL_JoystickSendEffect SDL_JoystickSendEffect_REAL +#define SDL_GameControllerGetSensorDataRate SDL_GameControllerGetSensorDataRate_REAL +#define SDL_SetTextureUserData SDL_SetTextureUserData_REAL +#define SDL_GetTextureUserData SDL_GetTextureUserData_REAL +#define SDL_RenderGeometry SDL_RenderGeometry_REAL +#define SDL_RenderGeometryRaw SDL_RenderGeometryRaw_REAL +#define SDL_RenderSetVSync SDL_RenderSetVSync_REAL +#define SDL_asprintf SDL_asprintf_REAL +#define SDL_vasprintf SDL_vasprintf_REAL +#define SDL_GetWindowICCProfile SDL_GetWindowICCProfile_REAL +#define SDL_GetTicks64 SDL_GetTicks64_REAL +#define SDL_LinuxSetThreadPriorityAndPolicy SDL_LinuxSetThreadPriorityAndPolicy_REAL +#define SDL_GameControllerGetAppleSFSymbolsNameForButton SDL_GameControllerGetAppleSFSymbolsNameForButton_REAL +#define SDL_GameControllerGetAppleSFSymbolsNameForAxis SDL_GameControllerGetAppleSFSymbolsNameForAxis_REAL +#define SDL_hid_init SDL_hid_init_REAL +#define SDL_hid_exit SDL_hid_exit_REAL +#define SDL_hid_device_change_count SDL_hid_device_change_count_REAL +#define SDL_hid_enumerate SDL_hid_enumerate_REAL +#define SDL_hid_free_enumeration SDL_hid_free_enumeration_REAL +#define SDL_hid_open SDL_hid_open_REAL +#define SDL_hid_open_path SDL_hid_open_path_REAL +#define SDL_hid_write SDL_hid_write_REAL +#define SDL_hid_read_timeout SDL_hid_read_timeout_REAL +#define SDL_hid_read SDL_hid_read_REAL +#define SDL_hid_set_nonblocking SDL_hid_set_nonblocking_REAL +#define SDL_hid_send_feature_report SDL_hid_send_feature_report_REAL +#define SDL_hid_get_feature_report SDL_hid_get_feature_report_REAL +#define SDL_hid_close SDL_hid_close_REAL +#define SDL_hid_get_manufacturer_string SDL_hid_get_manufacturer_string_REAL +#define SDL_hid_get_product_string SDL_hid_get_product_string_REAL +#define SDL_hid_get_serial_number_string SDL_hid_get_serial_number_string_REAL +#define SDL_hid_get_indexed_string SDL_hid_get_indexed_string_REAL +#define SDL_SetWindowMouseRect SDL_SetWindowMouseRect_REAL +#define SDL_GetWindowMouseRect SDL_GetWindowMouseRect_REAL +#define SDL_RenderWindowToLogical SDL_RenderWindowToLogical_REAL +#define SDL_RenderLogicalToWindow SDL_RenderLogicalToWindow_REAL +#define SDL_JoystickHasRumble SDL_JoystickHasRumble_REAL +#define SDL_JoystickHasRumbleTriggers SDL_JoystickHasRumbleTriggers_REAL +#define SDL_GameControllerHasRumble SDL_GameControllerHasRumble_REAL +#define SDL_GameControllerHasRumbleTriggers SDL_GameControllerHasRumbleTriggers_REAL +#define SDL_hid_ble_scan SDL_hid_ble_scan_REAL +#define SDL_PremultiplyAlpha SDL_PremultiplyAlpha_REAL +#define SDL_AndroidSendMessage SDL_AndroidSendMessage_REAL +#define SDL_GetTouchName SDL_GetTouchName_REAL +#define SDL_ClearComposition SDL_ClearComposition_REAL +#define SDL_IsTextInputShown SDL_IsTextInputShown_REAL +#define SDL_HasIntersectionF SDL_HasIntersectionF_REAL +#define SDL_IntersectFRect SDL_IntersectFRect_REAL +#define SDL_UnionFRect SDL_UnionFRect_REAL +#define SDL_EncloseFPoints SDL_EncloseFPoints_REAL +#define SDL_IntersectFRectAndLine SDL_IntersectFRectAndLine_REAL +#define SDL_RenderGetWindow SDL_RenderGetWindow_REAL +#define SDL_bsearch SDL_bsearch_REAL +#define SDL_GameControllerPathForIndex SDL_GameControllerPathForIndex_REAL +#define SDL_GameControllerPath SDL_GameControllerPath_REAL +#define SDL_JoystickPathForIndex SDL_JoystickPathForIndex_REAL +#define SDL_JoystickPath SDL_JoystickPath_REAL +#define SDL_JoystickAttachVirtualEx SDL_JoystickAttachVirtualEx_REAL +#define SDL_GameControllerGetFirmwareVersion SDL_GameControllerGetFirmwareVersion_REAL +#define SDL_JoystickGetFirmwareVersion SDL_JoystickGetFirmwareVersion_REAL +#define SDL_GUIDToString SDL_GUIDToString_REAL +#define SDL_GUIDFromString SDL_GUIDFromString_REAL +#define SDL_HasLSX SDL_HasLSX_REAL +#define SDL_HasLASX SDL_HasLASX_REAL +#define SDL_RenderGetD3D12Device SDL_RenderGetD3D12Device_REAL +#define SDL_utf8strnlen SDL_utf8strnlen_REAL +#define SDL_GDKGetTaskQueue SDL_GDKGetTaskQueue_REAL +#define SDL_GDKRunApp SDL_GDKRunApp_REAL +#define SDL_GetOriginalMemoryFunctions SDL_GetOriginalMemoryFunctions_REAL +#define SDL_ResetKeyboard SDL_ResetKeyboard_REAL +#define SDL_GetDefaultAudioInfo SDL_GetDefaultAudioInfo_REAL +#define SDL_GetPointDisplayIndex SDL_GetPointDisplayIndex_REAL +#define SDL_GetRectDisplayIndex SDL_GetRectDisplayIndex_REAL +#define SDL_ResetHint SDL_ResetHint_REAL +#define SDL_crc16 SDL_crc16_REAL +#define SDL_GetWindowSizeInPixels SDL_GetWindowSizeInPixels_REAL +#define SDL_GetJoystickGUIDInfo SDL_GetJoystickGUIDInfo_REAL +#define SDL_SetPrimarySelectionText SDL_SetPrimarySelectionText_REAL +#define SDL_GetPrimarySelectionText SDL_GetPrimarySelectionText_REAL +#define SDL_HasPrimarySelectionText SDL_HasPrimarySelectionText_REAL +#define SDL_GameControllerGetSensorDataWithTimestamp SDL_GameControllerGetSensorDataWithTimestamp_REAL +#define SDL_SensorGetDataWithTimestamp SDL_SensorGetDataWithTimestamp_REAL +#define SDL_ResetHints SDL_ResetHints_REAL +#define SDL_strcasestr SDL_strcasestr_REAL +#define SDL_GDKSuspendComplete SDL_GDKSuspendComplete_REAL +#define SDL_HasWindowSurface SDL_HasWindowSurface_REAL +#define SDL_DestroyWindowSurface SDL_DestroyWindowSurface_REAL +#define SDL_GDKGetDefaultUser SDL_GDKGetDefaultUser_REAL +#define SDL_GameControllerGetSteamHandle SDL_GameControllerGetSteamHandle_REAL diff --git a/SDL2-2.0.12/src/dynapi/SDL_dynapi_procs.h b/SDL2-2.30.5/src/dynapi/SDL_dynapi_procs.h similarity index 79% rename from SDL2-2.0.12/src/dynapi/SDL_dynapi_procs.h rename to SDL2-2.30.5/src/dynapi/SDL_dynapi_procs.h index 404a5e7..7f5d325 100644 --- a/SDL2-2.0.12/src/dynapi/SDL_dynapi_procs.h +++ b/SDL2-2.30.5/src/dynapi/SDL_dynapi_procs.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -30,7 +30,7 @@ */ /* direct jump magic can use these, the rest needs special code. */ -#if !SDL_DYNAPI_PROC_NO_VARARGS +#ifndef SDL_DYNAPI_PROC_NO_VARARGS SDL_DYNAPI_PROC(int,SDL_SetError,(SDL_PRINTF_FORMAT_STRING const char *a, ...),(a),return) SDL_DYNAPI_PROC(void,SDL_Log,(SDL_PRINTF_FORMAT_STRING const char *a, ...),(a),) SDL_DYNAPI_PROC(void,SDL_LogVerbose,(int a, SDL_PRINTF_FORMAT_STRING const char *b, ...),(a,b),) @@ -48,7 +48,7 @@ SDL_DYNAPI_PROC(int,SDL_snprintf,(SDL_OUT_Z_CAP(b) char *a, size_t b, SDL_PRINTF #undef SDL_CreateThread #endif -#if defined(__WIN32__) +#if defined(__WIN32__) || defined(__GDK__) SDL_DYNAPI_PROC(SDL_Thread*,SDL_CreateThread,(SDL_ThreadFunction a, const char *b, void *c, pfnSDL_CurrentBeginThread d, pfnSDL_CurrentEndThread e),(a,b,c,d,e),return) #elif defined(__OS2__) SDL_DYNAPI_PROC(SDL_Thread*,SDL_CreateThread,(SDL_ThreadFunction a, const char *b, void *c, pfnSDL_CurrentBeginThread d, pfnSDL_CurrentEndThread e),(a,b,c,d,e),return) @@ -62,15 +62,18 @@ SDL_DYNAPI_PROC(SDL_RWops*,SDL_RWFromFP,(FILE *a, SDL_bool b),(a,b),return) SDL_DYNAPI_PROC(SDL_RWops*,SDL_RWFromFP,(void *a, SDL_bool b),(a,b),return) #endif -#ifdef __WIN32__ -SDL_DYNAPI_PROC(int,SDL_RegisterApp,(char *a, Uint32 b, void *c),(a,b,c),return) +#if defined(__WIN32__) || defined(__GDK__) +SDL_DYNAPI_PROC(int,SDL_RegisterApp,(const char *a, Uint32 b, void *c),(a,b,c),return) SDL_DYNAPI_PROC(void,SDL_UnregisterApp,(void),(),) +#endif + +#if defined(__WIN32__) || defined(__WINGDK__) SDL_DYNAPI_PROC(int,SDL_Direct3D9GetAdapterIndex,(int a),(a),return) SDL_DYNAPI_PROC(IDirect3DDevice9*,SDL_RenderGetD3D9Device,(SDL_Renderer *a),(a),return) #endif #ifdef __IPHONEOS__ -SDL_DYNAPI_PROC(int,SDL_iPhoneSetAnimationCallback,(SDL_Window *a, int b, void c, void *d),(a,b,c,d),return) +SDL_DYNAPI_PROC(int,SDL_iPhoneSetAnimationCallback,(SDL_Window *a, int b, void (SDLCALL *c)(void *), void *d),(a,b,c,d),return) SDL_DYNAPI_PROC(void,SDL_iPhoneSetEventPump,(SDL_bool a),(a),) #endif @@ -87,9 +90,9 @@ SDL_DYNAPI_PROC(int,SDL_InitSubSystem,(Uint32 a),(a),return) SDL_DYNAPI_PROC(void,SDL_QuitSubSystem,(Uint32 a),(a),) SDL_DYNAPI_PROC(Uint32,SDL_WasInit,(Uint32 a),(a),return) SDL_DYNAPI_PROC(void,SDL_Quit,(void),(),) -SDL_DYNAPI_PROC(SDL_assert_state,SDL_ReportAssertion,(SDL_assert_data *a, const char *b, const char *c, int d),(a,b,c,d),return) +SDL_DYNAPI_PROC(SDL_AssertState,SDL_ReportAssertion,(SDL_AssertData *a, const char *b, const char *c, int d),(a,b,c,d),return) SDL_DYNAPI_PROC(void,SDL_SetAssertionHandler,(SDL_AssertionHandler a, void *b),(a,b),) -SDL_DYNAPI_PROC(const SDL_assert_data*,SDL_GetAssertionReport,(void),(),return) +SDL_DYNAPI_PROC(const SDL_AssertData*,SDL_GetAssertionReport,(void),(),return) SDL_DYNAPI_PROC(void,SDL_ResetAssertionReport,(void),(),) SDL_DYNAPI_PROC(SDL_bool,SDL_AtomicTryLock,(SDL_SpinLock *a),(a),return) SDL_DYNAPI_PROC(void,SDL_AtomicLock,(SDL_SpinLock *a),(a),) @@ -257,7 +260,7 @@ SDL_DYNAPI_PROC(SDL_Keycode,SDL_GetKeyFromName,(const char *a),(a),return) SDL_DYNAPI_PROC(void,SDL_StartTextInput,(void),(),) SDL_DYNAPI_PROC(SDL_bool,SDL_IsTextInputActive,(void),(),return) SDL_DYNAPI_PROC(void,SDL_StopTextInput,(void),(),) -SDL_DYNAPI_PROC(void,SDL_SetTextInputRect,(SDL_Rect *a),(a),) +SDL_DYNAPI_PROC(void,SDL_SetTextInputRect,(const SDL_Rect *a),(a),) SDL_DYNAPI_PROC(SDL_bool,SDL_HasScreenKeyboardSupport,(void),(),return) SDL_DYNAPI_PROC(SDL_bool,SDL_IsScreenKeyboardShown,(SDL_Window *a),(a),return) SDL_DYNAPI_PROC(void*,SDL_LoadObject,(const char *a),(a),return) @@ -408,7 +411,7 @@ SDL_DYNAPI_PROC(void*,SDL_realloc,(void *a, size_t b),(a,b),return) SDL_DYNAPI_PROC(void,SDL_free,(void *a),(a),) SDL_DYNAPI_PROC(char*,SDL_getenv,(const char *a),(a),return) SDL_DYNAPI_PROC(int,SDL_setenv,(const char *a, const char *b, int c),(a,b,c),return) -SDL_DYNAPI_PROC(void,SDL_qsort,(void *a, size_t b, size_t c, int (*d)(const void *, const void *)),(a,b,c,d),) +SDL_DYNAPI_PROC(void,SDL_qsort,(void *a, size_t b, size_t c, int (SDLCALL *d)(const void *, const void *)),(a,b,c,d),) SDL_DYNAPI_PROC(int,SDL_abs,(int a),(a),return) SDL_DYNAPI_PROC(int,SDL_isdigit,(int a),(a),return) SDL_DYNAPI_PROC(int,SDL_isspace,(int a),(a),return) @@ -508,7 +511,7 @@ SDL_DYNAPI_PROC(void,SDL_WaitThread,(SDL_Thread *a, int *b),(a,b),) SDL_DYNAPI_PROC(void,SDL_DetachThread,(SDL_Thread *a),(a),) SDL_DYNAPI_PROC(SDL_TLSID,SDL_TLSCreate,(void),(),return) SDL_DYNAPI_PROC(void*,SDL_TLSGet,(SDL_TLSID a),(a),return) -SDL_DYNAPI_PROC(int,SDL_TLSSet,(SDL_TLSID a, const void *b, void (*c)(void*)),(a,b,c),return) +SDL_DYNAPI_PROC(int,SDL_TLSSet,(SDL_TLSID a, const void *b, void (SDLCALL *c)(void*)),(a,b,c),return) SDL_DYNAPI_PROC(Uint32,SDL_GetTicks,(void),(),return) SDL_DYNAPI_PROC(Uint64,SDL_GetPerformanceCounter,(void),(),return) SDL_DYNAPI_PROC(Uint64,SDL_GetPerformanceFrequency,(void),(),return) @@ -599,12 +602,12 @@ SDL_DYNAPI_PROC(void,SDL_GL_ResetAttributes,(void),(),) SDL_DYNAPI_PROC(SDL_bool,SDL_HasAVX,(void),(),return) SDL_DYNAPI_PROC(SDL_AssertionHandler,SDL_GetDefaultAssertionHandler,(void),(),return) SDL_DYNAPI_PROC(SDL_AssertionHandler,SDL_GetAssertionHandler,(void **a),(a),return) -#ifdef __WIN32__ +#if defined(__WIN32__) || defined(__WINGDK__) SDL_DYNAPI_PROC(SDL_bool,SDL_DXGIGetOutputInfo,(int a,int *b, int *c),(a,b,c),return) #endif SDL_DYNAPI_PROC(SDL_bool,SDL_RenderIsClipEnabled,(SDL_Renderer *a),(a),return) #ifdef __WINRT__ -SDL_DYNAPI_PROC(int,SDL_WinRTRunApp,(int a, char **b, void *c),(a,b,c),return) +SDL_DYNAPI_PROC(int,SDL_WinRTRunApp,(SDL_main_func a, void *b),(a,b),return) SDL_DYNAPI_PROC(const wchar_t*,SDL_WinRTGetFSPathUNICODE,(SDL_WinRT_Path a),(a),return) SDL_DYNAPI_PROC(const char*,SDL_WinRTGetFSPathUTF8,(SDL_WinRT_Path a),(a),return) #endif @@ -620,7 +623,7 @@ SDL_DYNAPI_PROC(int,SDL_QueueAudio,(SDL_AudioDeviceID a, const void *b, Uint32 c SDL_DYNAPI_PROC(Uint32,SDL_GetQueuedAudioSize,(SDL_AudioDeviceID a),(a),return) SDL_DYNAPI_PROC(void,SDL_ClearQueuedAudio,(SDL_AudioDeviceID a),(a),) SDL_DYNAPI_PROC(SDL_Window*,SDL_GetGrabbedWindow,(void),(),return) -#ifdef __WIN32__ +#if defined(__WIN32__) || defined(__GDK__) SDL_DYNAPI_PROC(void,SDL_SetWindowsMessageHook,(SDL_WindowsMessageHook a, void *b),(a,b),) #endif SDL_DYNAPI_PROC(int,SDL_GetDisplayDPI,(int a, float *b, float *c, float *d),(a,b,c,d),return) @@ -744,7 +747,7 @@ SDL_DYNAPI_PROC(SDL_bool,SDL_HasColorKey,(SDL_Surface *a),(a),return) #undef SDL_CreateThreadWithStackSize #endif -#if defined(__WIN32__) +#if defined(__WIN32__) || defined(__GDK__) SDL_DYNAPI_PROC(SDL_Thread*,SDL_CreateThreadWithStackSize,(SDL_ThreadFunction a, const char *b, const size_t c, void *d, pfnSDL_CurrentBeginThread e, pfnSDL_CurrentEndThread f),(a,b,c,d,e,f),return) #elif defined(__OS2__) SDL_DYNAPI_PROC(SDL_Thread*,SDL_CreateThreadWithStackSize,(SDL_ThreadFunction a, const char *b, const size_t c, void *d, pfnSDL_CurrentBeginThread e, pfnSDL_CurrentEndThread f),(a,b,c,d,e,f),return) @@ -768,7 +771,7 @@ SDL_DYNAPI_PROC(int,SDL_RenderCopyF,(SDL_Renderer *a, SDL_Texture *b, const SDL_ SDL_DYNAPI_PROC(int,SDL_RenderCopyExF,(SDL_Renderer *a, SDL_Texture *b, const SDL_Rect *c, const SDL_FRect *d, const double e, const SDL_FPoint *f, const SDL_RendererFlip g),(a,b,c,d,e,f,g),return) SDL_DYNAPI_PROC(SDL_TouchDeviceType,SDL_GetTouchDeviceType,(SDL_TouchID a),(a),return) #ifdef __IPHONEOS__ -SDL_DYNAPI_PROC(int,SDL_UIKitRunApp,(int a, char *b, SDL_main_func c),(a,b,c),return) +SDL_DYNAPI_PROC(int,SDL_UIKitRunApp,(int a, char *b[], SDL_main_func c),(a,b,c),return) #endif SDL_DYNAPI_PROC(size_t,SDL_SIMDGetAlignment,(void),(),return) SDL_DYNAPI_PROC(void*,SDL_SIMDAlloc,(const size_t a),(a),return) @@ -809,3 +812,176 @@ SDL_DYNAPI_PROC(int,SDL_GetAndroidSDKVersion,(void),(),return) #endif SDL_DYNAPI_PROC(int,SDL_isupper,(int a),(a),return) SDL_DYNAPI_PROC(int,SDL_islower,(int a),(a),return) +SDL_DYNAPI_PROC(int,SDL_JoystickAttachVirtual,(SDL_JoystickType a, int b, int c, int d),(a,b,c,d),return) +SDL_DYNAPI_PROC(int,SDL_JoystickDetachVirtual,(int a),(a),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_JoystickIsVirtual,(int a),(a),return) +SDL_DYNAPI_PROC(int,SDL_JoystickSetVirtualAxis,(SDL_Joystick *a, int b, Sint16 c),(a,b,c),return) +SDL_DYNAPI_PROC(int,SDL_JoystickSetVirtualButton,(SDL_Joystick *a, int b, Uint8 c),(a,b,c),return) +SDL_DYNAPI_PROC(int,SDL_JoystickSetVirtualHat,(SDL_Joystick *a, int b, Uint8 c),(a,b,c),return) +SDL_DYNAPI_PROC(char*,SDL_GetErrorMsg,(char *a, int b),(a,b),return) +SDL_DYNAPI_PROC(void,SDL_LockSensors,(void),(),) +SDL_DYNAPI_PROC(void,SDL_UnlockSensors,(void),(),) +SDL_DYNAPI_PROC(void*,SDL_Metal_GetLayer,(SDL_MetalView a),(a),return) +SDL_DYNAPI_PROC(void,SDL_Metal_GetDrawableSize,(SDL_Window *a, int *b, int *c),(a,b,c),) +SDL_DYNAPI_PROC(double,SDL_trunc,(double a),(a),return) +SDL_DYNAPI_PROC(float,SDL_truncf,(float a),(a),return) +SDL_DYNAPI_PROC(SDL_Locale *,SDL_GetPreferredLocales,(void),(),return) +SDL_DYNAPI_PROC(void*,SDL_SIMDRealloc,(void *a, const size_t b),(a, b),return) +#ifdef __ANDROID__ +SDL_DYNAPI_PROC(SDL_bool,SDL_AndroidRequestPermission,(const char *a),(a),return) +#endif +SDL_DYNAPI_PROC(int,SDL_OpenURL,(const char *a),(a),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_HasSurfaceRLE,(SDL_Surface *a),(a),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_GameControllerHasLED,(SDL_GameController *a),(a),return) +SDL_DYNAPI_PROC(int,SDL_GameControllerSetLED,(SDL_GameController *a, Uint8 b, Uint8 c, Uint8 d),(a,b,c,d),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_JoystickHasLED,(SDL_Joystick *a),(a),return) +SDL_DYNAPI_PROC(int,SDL_JoystickSetLED,(SDL_Joystick *a, Uint8 b, Uint8 c, Uint8 d),(a,b,c,d),return) +SDL_DYNAPI_PROC(int,SDL_GameControllerRumbleTriggers,(SDL_GameController *a, Uint16 b, Uint16 c, Uint32 d),(a,b,c,d),return) +SDL_DYNAPI_PROC(int,SDL_JoystickRumbleTriggers,(SDL_Joystick *a, Uint16 b, Uint16 c, Uint32 d),(a,b,c,d),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_GameControllerHasAxis,(SDL_GameController *a, SDL_GameControllerAxis b),(a,b),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_GameControllerHasButton,(SDL_GameController *a, SDL_GameControllerButton b),(a,b),return) +SDL_DYNAPI_PROC(int,SDL_GameControllerGetNumTouchpads,(SDL_GameController *a),(a),return) +SDL_DYNAPI_PROC(int,SDL_GameControllerGetNumTouchpadFingers,(SDL_GameController *a, int b),(a,b),return) +SDL_DYNAPI_PROC(int,SDL_GameControllerGetTouchpadFinger,(SDL_GameController *a, int b, int c, Uint8 *d, float *e, float *f, float *g),(a,b,c,d,e,f,g),return) +SDL_DYNAPI_PROC(Uint32,SDL_crc32,(Uint32 a, const void *b, size_t c),(a,b,c),return) +SDL_DYNAPI_PROC(const char*,SDL_GameControllerGetSerial,(SDL_GameController *a),(a),return) +SDL_DYNAPI_PROC(const char*,SDL_JoystickGetSerial,(SDL_Joystick *a),(a),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_GameControllerHasSensor,(SDL_GameController *a, SDL_SensorType b),(a,b),return) +SDL_DYNAPI_PROC(int,SDL_GameControllerSetSensorEnabled,(SDL_GameController *a, SDL_SensorType b, SDL_bool c),(a,b,c),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_GameControllerIsSensorEnabled,(SDL_GameController *a, SDL_SensorType b),(a,b),return) +SDL_DYNAPI_PROC(int,SDL_GameControllerGetSensorData,(SDL_GameController *a, SDL_SensorType b, float *c, int d),(a,b,c,d),return) +SDL_DYNAPI_PROC(int,SDL_wcscasecmp,(const wchar_t *a, const wchar_t *b),(a,b),return) +SDL_DYNAPI_PROC(int,SDL_wcsncasecmp,(const wchar_t *a, const wchar_t *b, size_t c),(a,b,c),return) +SDL_DYNAPI_PROC(double,SDL_round,(double a),(a),return) +SDL_DYNAPI_PROC(float,SDL_roundf,(float a),(a),return) +SDL_DYNAPI_PROC(long,SDL_lround,(double a),(a),return) +SDL_DYNAPI_PROC(long,SDL_lroundf,(float a),(a),return) +SDL_DYNAPI_PROC(int,SDL_SoftStretchLinear,(SDL_Surface *a, const SDL_Rect *b, SDL_Surface *c, const SDL_Rect *d),(a,b,c,d),return) +#if defined(__WIN32__) || defined(__WINGDK__) +SDL_DYNAPI_PROC(ID3D11Device*,SDL_RenderGetD3D11Device,(SDL_Renderer *a),(a),return) +#endif +SDL_DYNAPI_PROC(int,SDL_UpdateNVTexture,(SDL_Texture *a, const SDL_Rect *b, const Uint8 *c, int d, const Uint8 *e, int f),(a,b,c,d,e,f),return) +SDL_DYNAPI_PROC(void,SDL_SetWindowKeyboardGrab,(SDL_Window *a, SDL_bool b),(a,b),) +SDL_DYNAPI_PROC(void,SDL_SetWindowMouseGrab,(SDL_Window *a, SDL_bool b),(a,b),) +SDL_DYNAPI_PROC(SDL_bool,SDL_GetWindowKeyboardGrab,(SDL_Window *a),(a),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_GetWindowMouseGrab,(SDL_Window *a),(a),return) +SDL_DYNAPI_PROC(int,SDL_isalpha,(int a),(a),return) +SDL_DYNAPI_PROC(int,SDL_isalnum,(int a),(a),return) +SDL_DYNAPI_PROC(int,SDL_isblank,(int a),(a),return) +SDL_DYNAPI_PROC(int,SDL_iscntrl,(int a),(a),return) +SDL_DYNAPI_PROC(int,SDL_isxdigit,(int a),(a),return) +SDL_DYNAPI_PROC(int,SDL_ispunct,(int a),(a),return) +SDL_DYNAPI_PROC(int,SDL_isprint,(int a),(a),return) +SDL_DYNAPI_PROC(int,SDL_isgraph,(int a),(a),return) +#ifdef __ANDROID__ +SDL_DYNAPI_PROC(int,SDL_AndroidShowToast,(const char *a, int b, int c, int d, int e),(a,b,c,d,e),return) +#endif +SDL_DYNAPI_PROC(int,SDL_GetAudioDeviceSpec,(int a, int b, SDL_AudioSpec *c),(a,b,c),return) +SDL_DYNAPI_PROC(void,SDL_TLSCleanup,(void),(),) +SDL_DYNAPI_PROC(void,SDL_SetWindowAlwaysOnTop,(SDL_Window *a, SDL_bool b),(a,b),) +SDL_DYNAPI_PROC(int,SDL_FlashWindow,(SDL_Window *a, SDL_FlashOperation b),(a,b),return) +SDL_DYNAPI_PROC(int,SDL_GameControllerSendEffect,(SDL_GameController *a, const void *b, int c),(a,b,c),return) +SDL_DYNAPI_PROC(int,SDL_JoystickSendEffect,(SDL_Joystick *a, const void *b, int c),(a,b,c),return) +SDL_DYNAPI_PROC(float,SDL_GameControllerGetSensorDataRate,(SDL_GameController *a, SDL_SensorType b),(a,b),return) +SDL_DYNAPI_PROC(int,SDL_SetTextureUserData,(SDL_Texture *a, void *b),(a,b),return) +SDL_DYNAPI_PROC(void*,SDL_GetTextureUserData,(SDL_Texture *a),(a),return) +SDL_DYNAPI_PROC(int,SDL_RenderGeometry,(SDL_Renderer *a, SDL_Texture *b, const SDL_Vertex *c, int d, const int *e, int f),(a,b,c,d,e,f),return) +SDL_DYNAPI_PROC(int,SDL_RenderGeometryRaw,(SDL_Renderer *a, SDL_Texture *b, const float *c, int d, const SDL_Color *e, int f, const float *g, int h, int i, const void *j, int k, int l),(a,b,c,d,e,f,g,h,i,j,k,l),return) +SDL_DYNAPI_PROC(int,SDL_RenderSetVSync,(SDL_Renderer *a, int b),(a,b),return) +#ifndef SDL_DYNAPI_PROC_NO_VARARGS +SDL_DYNAPI_PROC(int,SDL_asprintf,(char **a, SDL_PRINTF_FORMAT_STRING const char *b, ...),(a,b),return) +#endif +SDL_DYNAPI_PROC(int,SDL_vasprintf,(char **a, const char *b, va_list c),(a,b,c),return) +SDL_DYNAPI_PROC(void*,SDL_GetWindowICCProfile,(SDL_Window *a, size_t *b),(a,b),return) +SDL_DYNAPI_PROC(Uint64,SDL_GetTicks64,(void),(),return) +#ifdef __LINUX__ +SDL_DYNAPI_PROC(int,SDL_LinuxSetThreadPriorityAndPolicy,(Sint64 a, int b, int c),(a,b,c),return) +#endif +SDL_DYNAPI_PROC(const char*,SDL_GameControllerGetAppleSFSymbolsNameForButton,(SDL_GameController *a, SDL_GameControllerButton b),(a,b),return) +SDL_DYNAPI_PROC(const char*,SDL_GameControllerGetAppleSFSymbolsNameForAxis,(SDL_GameController *a, SDL_GameControllerAxis b),(a,b),return) +SDL_DYNAPI_PROC(int,SDL_hid_init,(void),(),return) +SDL_DYNAPI_PROC(int,SDL_hid_exit,(void),(),return) +SDL_DYNAPI_PROC(Uint32,SDL_hid_device_change_count,(void),(),return) +SDL_DYNAPI_PROC(SDL_hid_device_info*,SDL_hid_enumerate,(unsigned short a, unsigned short b),(a,b),return) +SDL_DYNAPI_PROC(void,SDL_hid_free_enumeration,(SDL_hid_device_info *a),(a),) +SDL_DYNAPI_PROC(SDL_hid_device*,SDL_hid_open,(unsigned short a, unsigned short b, const wchar_t *c),(a,b,c),return) +SDL_DYNAPI_PROC(SDL_hid_device*,SDL_hid_open_path,(const char *a, int b),(a,b),return) +SDL_DYNAPI_PROC(int,SDL_hid_write,(SDL_hid_device *a, const unsigned char *b, size_t c),(a,b,c),return) +SDL_DYNAPI_PROC(int,SDL_hid_read_timeout,(SDL_hid_device *a, unsigned char *b, size_t c, int d),(a,b,c,d),return) +SDL_DYNAPI_PROC(int,SDL_hid_read,(SDL_hid_device *a, unsigned char *b, size_t c),(a,b,c),return) +SDL_DYNAPI_PROC(int,SDL_hid_set_nonblocking,(SDL_hid_device *a, int b),(a,b),return) +SDL_DYNAPI_PROC(int,SDL_hid_send_feature_report,(SDL_hid_device *a, const unsigned char *b, size_t c),(a,b,c),return) +SDL_DYNAPI_PROC(int,SDL_hid_get_feature_report,(SDL_hid_device *a, unsigned char *b, size_t c),(a,b,c),return) +SDL_DYNAPI_PROC(void,SDL_hid_close,(SDL_hid_device *a),(a),) +SDL_DYNAPI_PROC(int,SDL_hid_get_manufacturer_string,(SDL_hid_device *a, wchar_t *b, size_t c),(a,b,c),return) +SDL_DYNAPI_PROC(int,SDL_hid_get_product_string,(SDL_hid_device *a, wchar_t *b, size_t c),(a,b,c),return) +SDL_DYNAPI_PROC(int,SDL_hid_get_serial_number_string,(SDL_hid_device *a, wchar_t *b, size_t c),(a,b,c),return) +SDL_DYNAPI_PROC(int,SDL_hid_get_indexed_string,(SDL_hid_device *a, int b, wchar_t *c, size_t d),(a,b,c,d),return) +SDL_DYNAPI_PROC(int,SDL_SetWindowMouseRect,(SDL_Window *a, const SDL_Rect *b),(a,b),return) +SDL_DYNAPI_PROC(const SDL_Rect*,SDL_GetWindowMouseRect,(SDL_Window *a),(a),return) +SDL_DYNAPI_PROC(void,SDL_RenderWindowToLogical,(SDL_Renderer *a, int b, int c, float *d, float *e),(a,b,c,d,e),) +SDL_DYNAPI_PROC(void,SDL_RenderLogicalToWindow,(SDL_Renderer *a, float b, float c, int *d, int *e),(a,b,c,d,e),) +SDL_DYNAPI_PROC(SDL_bool,SDL_JoystickHasRumble,(SDL_Joystick *a),(a),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_JoystickHasRumbleTriggers,(SDL_Joystick *a),(a),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_GameControllerHasRumble,(SDL_GameController *a),(a),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_GameControllerHasRumbleTriggers,(SDL_GameController *a),(a),return) +SDL_DYNAPI_PROC(void,SDL_hid_ble_scan,(SDL_bool a),(a),) +SDL_DYNAPI_PROC(int,SDL_PremultiplyAlpha,(int a, int b, Uint32 c, const void *d, int e, Uint32 f, void *g, int h),(a,b,c,d,e,f,g,h),return) +#ifdef __ANDROID__ +SDL_DYNAPI_PROC(int,SDL_AndroidSendMessage,(Uint32 a, int b),(a,b),return) +#endif +SDL_DYNAPI_PROC(const char*,SDL_GetTouchName,(int a),(a),return) +SDL_DYNAPI_PROC(void,SDL_ClearComposition,(void),(),) +SDL_DYNAPI_PROC(SDL_bool,SDL_IsTextInputShown,(void),(),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_HasIntersectionF,(const SDL_FRect *a, const SDL_FRect *b),(a,b),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_IntersectFRect,(const SDL_FRect *a, const SDL_FRect *b, SDL_FRect *c),(a,b,c),return) +SDL_DYNAPI_PROC(void,SDL_UnionFRect,(const SDL_FRect *a, const SDL_FRect *b, SDL_FRect *c),(a,b,c),) +SDL_DYNAPI_PROC(SDL_bool,SDL_EncloseFPoints,(const SDL_FPoint *a, int b, const SDL_FRect *c, SDL_FRect *d),(a,b,c,d),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_IntersectFRectAndLine,(const SDL_FRect *a, float *b, float *c, float *d, float *e),(a,b,c,d,e),return) +SDL_DYNAPI_PROC(SDL_Window*,SDL_RenderGetWindow,(SDL_Renderer *a),(a),return) +SDL_DYNAPI_PROC(void*,SDL_bsearch,(const void *a, const void *b, size_t c, size_t d, int (SDLCALL *e)(const void *, const void *)),(a,b,c,d,e),return) +SDL_DYNAPI_PROC(const char*,SDL_GameControllerPathForIndex,(int a),(a),return) +SDL_DYNAPI_PROC(const char*,SDL_GameControllerPath,(SDL_GameController *a),(a),return) +SDL_DYNAPI_PROC(const char*,SDL_JoystickPathForIndex,(int a),(a),return) +SDL_DYNAPI_PROC(const char*,SDL_JoystickPath,(SDL_Joystick *a),(a),return) +SDL_DYNAPI_PROC(int,SDL_JoystickAttachVirtualEx,(const SDL_VirtualJoystickDesc *a),(a),return) +SDL_DYNAPI_PROC(Uint16,SDL_GameControllerGetFirmwareVersion,(SDL_GameController *a),(a),return) +SDL_DYNAPI_PROC(Uint16,SDL_JoystickGetFirmwareVersion,(SDL_Joystick *a),(a),return) +SDL_DYNAPI_PROC(void,SDL_GUIDToString,(SDL_GUID a, char *b, int c),(a,b,c),) +SDL_DYNAPI_PROC(SDL_GUID,SDL_GUIDFromString,(const char *a),(a),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_HasLSX,(void),(),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_HasLASX,(void),(),return) +#if defined(__WIN32__) || defined(__GDK__) +SDL_DYNAPI_PROC(ID3D12Device*,SDL_RenderGetD3D12Device,(SDL_Renderer *a),(a),return) +#endif +SDL_DYNAPI_PROC(size_t,SDL_utf8strnlen,(const char *a, size_t b),(a,b),return) + +#if defined(__GDK__) +SDL_DYNAPI_PROC(int,SDL_GDKGetTaskQueue,(XTaskQueueHandle *a),(a),return) +SDL_DYNAPI_PROC(int,SDL_GDKRunApp,(SDL_main_func a, void *b),(a,b),return) +#endif +SDL_DYNAPI_PROC(void,SDL_GetOriginalMemoryFunctions,(SDL_malloc_func *a, SDL_calloc_func *b, SDL_realloc_func *c, SDL_free_func *d),(a,b,c,d),) +SDL_DYNAPI_PROC(void,SDL_ResetKeyboard,(void),(),) +SDL_DYNAPI_PROC(int,SDL_GetDefaultAudioInfo,(char **a, SDL_AudioSpec *b, int c),(a,b,c),return) +SDL_DYNAPI_PROC(int,SDL_GetPointDisplayIndex,(const SDL_Point *a),(a),return) +SDL_DYNAPI_PROC(int,SDL_GetRectDisplayIndex,(const SDL_Rect *a),(a),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_ResetHint,(const char *a),(a),return) +SDL_DYNAPI_PROC(Uint16,SDL_crc16,(Uint16 a, const void *b, size_t c),(a,b,c),return) +SDL_DYNAPI_PROC(void,SDL_GetWindowSizeInPixels,(SDL_Window *a, int *b, int *c),(a,b,c),) +SDL_DYNAPI_PROC(void,SDL_GetJoystickGUIDInfo,(SDL_JoystickGUID a, Uint16 *b, Uint16 *c, Uint16 *d, Uint16 *e),(a,b,c,d,e),) +SDL_DYNAPI_PROC(int,SDL_SetPrimarySelectionText,(const char *a),(a),return) +SDL_DYNAPI_PROC(char*,SDL_GetPrimarySelectionText,(void),(),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_HasPrimarySelectionText,(void),(),return) +SDL_DYNAPI_PROC(int,SDL_GameControllerGetSensorDataWithTimestamp,(SDL_GameController *a, SDL_SensorType b, Uint64 *c, float *d, int e),(a,b,c,d,e),return) +SDL_DYNAPI_PROC(int,SDL_SensorGetDataWithTimestamp,(SDL_Sensor *a, Uint64 *b, float *c, int d),(a,b,c,d),return) +SDL_DYNAPI_PROC(void,SDL_ResetHints,(void),(),) +SDL_DYNAPI_PROC(char*,SDL_strcasestr,(const char *a, const char *b),(a,b),return) +#if defined(__GDK__) +SDL_DYNAPI_PROC(void,SDL_GDKSuspendComplete,(void),(),) +#endif +SDL_DYNAPI_PROC(SDL_bool,SDL_HasWindowSurface,(SDL_Window *a),(a),return) +SDL_DYNAPI_PROC(int,SDL_DestroyWindowSurface,(SDL_Window *a),(a),return) +#if defined(__GDK__) +SDL_DYNAPI_PROC(int,SDL_GDKGetDefaultUser,(XUserHandle *a),(a),return) +#endif +SDL_DYNAPI_PROC(Uint64,SDL_GameControllerGetSteamHandle,(SDL_GameController *a),(a),return) diff --git a/SDL2-2.0.12/src/dynapi/gendynapi.pl b/SDL2-2.30.5/src/dynapi/gendynapi.pl similarity index 82% rename from SDL2-2.0.12/src/dynapi/gendynapi.pl rename to SDL2-2.30.5/src/dynapi/gendynapi.pl index ee65e6b..dad2bc4 100644 --- a/SDL2-2.0.12/src/dynapi/gendynapi.pl +++ b/SDL2-2.30.5/src/dynapi/gendynapi.pl @@ -1,7 +1,7 @@ #!/usr/bin/perl -w # Simple DirectMedia Layer -# Copyright (C) 1997-2020 Sam Lantinga +# Copyright (C) 1997-2024 Sam Lantinga # # This software is provided 'as-is', without any express or implied # warranty. In no event will the authors be held liable for any damages @@ -21,7 +21,7 @@ # WHAT IS THIS? # When you add a public API to SDL, please run this script, make sure the -# output looks sane (hg diff, it adds to existing files), and commit it. +# output looks sane (git diff, it adds to existing files), and commit it. # It keeps the dynamic API jump table operating correctly. # If you wanted this to be readable, you shouldn't have used perl. @@ -33,6 +33,7 @@ use File::Basename; chdir(dirname(__FILE__) . '/../..'); my $sdl_dynapi_procs_h = "src/dynapi/SDL_dynapi_procs.h"; my $sdl_dynapi_overrides_h = "src/dynapi/SDL_dynapi_overrides.h"; +my $sdl2_exports = "src/dynapi/SDL2.exports"; my %existing = (); if (-f $sdl_dynapi_procs_h) { @@ -47,6 +48,7 @@ if (-f $sdl_dynapi_procs_h) { open(SDL_DYNAPI_PROCS_H, '>>', $sdl_dynapi_procs_h) or die("Can't open $sdl_dynapi_procs_h: $!\n"); open(SDL_DYNAPI_OVERRIDES_H, '>>', $sdl_dynapi_overrides_h) or die("Can't open $sdl_dynapi_overrides_h: $!\n"); +open(SDL2_EXPORTS, '>>', $sdl2_exports) or die("Can't open $sdl2_exports: $!\n"); opendir(HEADERS, 'include') or die("Can't open include dir: $!\n"); while (my $d = readdir(HEADERS)) { @@ -55,7 +57,7 @@ while (my $d = readdir(HEADERS)) { open(HEADER, '<', $header) or die("Can't open $header: $!\n"); while (
) { chomp; - next if not /\A\s*extern\s+DECLSPEC/; + next if not /\A\s*extern\s+(SDL_DEPRECATED\s+|)DECLSPEC/; my $decl = "$_ "; if (not $decl =~ /\)\s*;/) { while (
) { @@ -70,13 +72,13 @@ while (my $d = readdir(HEADERS)) { $decl =~ s/\s+\Z//; #print("DECL: [$decl]\n"); - if ($decl =~ /\A\s*extern\s+DECLSPEC\s+(const\s+|)(unsigned\s+|)(.*?)\s*(\*?)\s*SDLCALL\s+(.*?)\s*\((.*?)\);/) { - my $rc = "$1$2$3$4"; - my $fn = $5; + if ($decl =~ /\A\s*extern\s+(SDL_DEPRECATED\s+|)DECLSPEC\s+(const\s+|)(unsigned\s+|)(.*?)\s*(\*?)\s*SDLCALL\s+(.*?)\s*\((.*?)\);/) { + my $rc = "$2$3$4$5"; + my $fn = $6; next if $existing{$fn}; # already slotted into the jump table. - my @params = split(',', $6); + my @params = split(',', $7); #print("rc == '$rc', fn == '$fn', params == '$params'\n"); @@ -107,13 +109,19 @@ while (my $d = readdir(HEADERS)) { $type =~ s/\s*\*\Z/*/g; $type =~ s/\s*(\*+)\Z/ $1/; #print("SPLIT: ($type, $var)\n"); + my $var_array_suffix = ""; + # parse array suffix + if ($var =~ /\A.*(\[.*\])\Z/) { + #print("PARSED ARRAY SUFFIX: [$1] of '$var'\n"); + $var_array_suffix = $1; + } my $name = chr(ord('a') + $i); if ($i > 0) { $paramstr .= ', '; $argstr .= ','; } my $spc = ($type =~ /\*\Z/) ? '' : ' '; - $paramstr .= "$type$spc$name"; + $paramstr .= "$type$spc$name$var_array_suffix"; $argstr .= "$name"; } $i++; @@ -127,15 +135,18 @@ while (my $d = readdir(HEADERS)) { print("NEW: $decl\n"); print SDL_DYNAPI_PROCS_H "SDL_DYNAPI_PROC($rc,$fn,$paramstr,$argstr,$retstr)\n"; print SDL_DYNAPI_OVERRIDES_H "#define $fn ${fn}_REAL\n"; + print SDL2_EXPORTS "++'_${fn}'.'SDL2.dll'.'${fn}'\n"; } else { print("Failed to parse decl [$decl]!\n"); } } close(HEADER); } + closedir(HEADERS); close(SDL_DYNAPI_PROCS_H); close(SDL_DYNAPI_OVERRIDES_H); +close(SDL2_EXPORTS); # vi: set ts=4 sw=4 expandtab: diff --git a/SDL2-2.0.12/src/events/SDL_clipboardevents.c b/SDL2-2.30.5/src/events/SDL_clipboardevents.c similarity index 92% rename from SDL2-2.0.12/src/events/SDL_clipboardevents.c rename to SDL2-2.30.5/src/events/SDL_clipboardevents.c index c3c0f19..68b9a76 100644 --- a/SDL2-2.0.12/src/events/SDL_clipboardevents.c +++ b/SDL2-2.30.5/src/events/SDL_clipboardevents.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,9 +26,7 @@ #include "SDL_events_c.h" #include "SDL_clipboardevents_c.h" - -int -SDL_SendClipboardUpdate(void) +int SDL_SendClipboardUpdate(void) { int posted; @@ -40,7 +38,7 @@ SDL_SendClipboardUpdate(void) posted = (SDL_PushEvent(&event) > 0); } - return (posted); + return posted; } /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/events/SDL_clipboardevents_c.h b/SDL2-2.30.5/src/events/SDL_clipboardevents_c.h similarity index 94% rename from SDL2-2.0.12/src/events/SDL_clipboardevents_c.h rename to SDL2-2.30.5/src/events/SDL_clipboardevents_c.h index cae62b7..77e2e42 100644 --- a/SDL2-2.0.12/src/events/SDL_clipboardevents_c.h +++ b/SDL2-2.30.5/src/events/SDL_clipboardevents_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/events/SDL_displayevents.c b/SDL2-2.30.5/src/events/SDL_displayevents.c similarity index 91% rename from SDL2-2.0.12/src/events/SDL_displayevents.c rename to SDL2-2.30.5/src/events/SDL_displayevents.c index 9bb556c..9777d5d 100644 --- a/SDL2-2.0.12/src/events/SDL_displayevents.c +++ b/SDL2-2.30.5/src/events/SDL_displayevents.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -25,9 +25,7 @@ #include "SDL_events.h" #include "SDL_events_c.h" - -int -SDL_SendDisplayEvent(SDL_VideoDisplay *display, Uint8 displayevent, int data1) +int SDL_SendDisplayEvent(SDL_VideoDisplay *display, Uint8 displayevent, int data1) { int posted; @@ -54,7 +52,7 @@ SDL_SendDisplayEvent(SDL_VideoDisplay *display, Uint8 displayevent, int data1) posted = (SDL_PushEvent(&event) > 0); } - return (posted); + return posted; } /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/events/SDL_displayevents_c.h b/SDL2-2.30.5/src/events/SDL_displayevents_c.h similarity index 94% rename from SDL2-2.0.12/src/events/SDL_displayevents_c.h rename to SDL2-2.30.5/src/events/SDL_displayevents_c.h index 961a544..d2e2b57 100644 --- a/SDL2-2.0.12/src/events/SDL_displayevents_c.h +++ b/SDL2-2.30.5/src/events/SDL_displayevents_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/events/SDL_dropevents.c b/SDL2-2.30.5/src/events/SDL_dropevents.c similarity index 86% rename from SDL2-2.0.12/src/events/SDL_dropevents.c rename to SDL2-2.30.5/src/events/SDL_dropevents.c index a60fb0d..7c7cc56 100644 --- a/SDL2-2.0.12/src/events/SDL_dropevents.c +++ b/SDL2-2.30.5/src/events/SDL_dropevents.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,11 +26,9 @@ #include "SDL_events_c.h" #include "SDL_dropevents_c.h" -#include "../video/SDL_sysvideo.h" /* for SDL_Window internals. */ +#include "../video/SDL_sysvideo.h" /* for SDL_Window internals. */ - -static int -SDL_SendDrop(SDL_Window *window, const SDL_EventType evtype, const char *data) +static int SDL_SendDrop(SDL_Window *window, const SDL_EventType evtype, const char *data) { static SDL_bool app_is_dropping = SDL_FALSE; int posted = 0; @@ -76,23 +74,19 @@ SDL_SendDrop(SDL_Window *window, const SDL_EventType evtype, const char *data) return posted; } -int -SDL_SendDropFile(SDL_Window *window, const char *file) +int SDL_SendDropFile(SDL_Window *window, const char *file) { return SDL_SendDrop(window, SDL_DROPFILE, file); } -int -SDL_SendDropText(SDL_Window *window, const char *text) +int SDL_SendDropText(SDL_Window *window, const char *text) { return SDL_SendDrop(window, SDL_DROPTEXT, text); } -int -SDL_SendDropComplete(SDL_Window *window) +int SDL_SendDropComplete(SDL_Window *window) { return SDL_SendDrop(window, SDL_DROPCOMPLETE, NULL); } - /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/events/SDL_dropevents_c.h b/SDL2-2.30.5/src/events/SDL_dropevents_c.h similarity index 95% rename from SDL2-2.0.12/src/events/SDL_dropevents_c.h rename to SDL2-2.30.5/src/events/SDL_dropevents_c.h index 7c0599a..83177a8 100644 --- a/SDL2-2.0.12/src/events/SDL_dropevents_c.h +++ b/SDL2-2.30.5/src/events/SDL_dropevents_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.30.5/src/events/SDL_events.c b/SDL2-2.30.5/src/events/SDL_events.c new file mode 100644 index 0000000..b432703 --- /dev/null +++ b/SDL2-2.30.5/src/events/SDL_events.c @@ -0,0 +1,1444 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +/* General event handling code for SDL */ + +#include "SDL.h" +#include "SDL_events.h" +#include "SDL_thread.h" +#include "SDL_events_c.h" +#include "../SDL_hints_c.h" +#include "../timer/SDL_timer_c.h" +#ifndef SDL_JOYSTICK_DISABLED +#include "../joystick/SDL_joystick_c.h" +#endif +#include "../video/SDL_sysvideo.h" +#include "SDL_syswm.h" + +/* An arbitrary limit so we don't have unbounded growth */ +#define SDL_MAX_QUEUED_EVENTS 65535 + +/* Determines how often we wake to call SDL_PumpEvents() in SDL_WaitEventTimeout_Device() */ +#define PERIODIC_POLL_INTERVAL_MS 3000 + +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; +static SDL_atomic_t SDL_sentinel_pending; + +typedef struct +{ + Uint32 bits[8]; +} SDL_DisabledEventBlock; + +static SDL_DisabledEventBlock *SDL_disabled_events[256]; +static Uint32 SDL_userevents = SDL_USEREVENT; + +/* Private data -- event queue */ +typedef struct _SDL_EventEntry +{ + SDL_Event event; + SDL_SysWMmsg msg; + struct _SDL_EventEntry *prev; + struct _SDL_EventEntry *next; +} SDL_EventEntry; + +typedef struct _SDL_SysWMEntry +{ + SDL_SysWMmsg msg; + struct _SDL_SysWMEntry *next; +} SDL_SysWMEntry; + +static struct +{ + SDL_mutex *lock; + SDL_bool active; + SDL_atomic_t count; + int max_events_seen; + SDL_EventEntry *head; + SDL_EventEntry *tail; + SDL_EventEntry *free; + SDL_SysWMEntry *wmmsg_used; + SDL_SysWMEntry *wmmsg_free; +} SDL_EventQ = { NULL, SDL_FALSE, { 0 }, 0, NULL, NULL, NULL, NULL, NULL }; + +#ifndef SDL_JOYSTICK_DISABLED + +static SDL_bool SDL_update_joysticks = SDL_TRUE; + +static void SDL_CalculateShouldUpdateJoysticks(SDL_bool hint_value) +{ + if (hint_value && + (!SDL_disabled_events[SDL_JOYAXISMOTION >> 8] || SDL_JoystickEventState(SDL_QUERY))) { + SDL_update_joysticks = SDL_TRUE; + } else { + SDL_update_joysticks = SDL_FALSE; + } +} + +static void SDLCALL SDL_AutoUpdateJoysticksChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + SDL_CalculateShouldUpdateJoysticks(SDL_GetStringBoolean(hint, SDL_TRUE)); +} + +#endif /* !SDL_JOYSTICK_DISABLED */ + +#ifndef SDL_SENSOR_DISABLED + +static SDL_bool SDL_update_sensors = SDL_TRUE; + +static void SDL_CalculateShouldUpdateSensors(SDL_bool hint_value) +{ + if (hint_value && + !SDL_disabled_events[SDL_SENSORUPDATE >> 8]) { + SDL_update_sensors = SDL_TRUE; + } else { + SDL_update_sensors = SDL_FALSE; + } +} + +static void SDLCALL SDL_AutoUpdateSensorsChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + SDL_CalculateShouldUpdateSensors(SDL_GetStringBoolean(hint, SDL_TRUE)); +} + +#endif /* !SDL_SENSOR_DISABLED */ + +static void SDLCALL SDL_PollSentinelChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + (void)SDL_EventState(SDL_POLLSENTINEL, SDL_GetStringBoolean(hint, SDL_TRUE) ? SDL_ENABLE : SDL_DISABLE); +} + +/** + * Verbosity of logged events as defined in SDL_HINT_EVENT_LOGGING: + * - 0: (default) no logging + * - 1: logging of most events + * - 2: as above, plus mouse and finger motion + * - 3: as above, plus SDL_SysWMEvents + */ +static int SDL_EventLoggingVerbosity = 0; + +static void SDLCALL SDL_EventLoggingChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + SDL_EventLoggingVerbosity = (hint && *hint) ? SDL_clamp(SDL_atoi(hint), 0, 3) : 0; +} + +static void SDL_LogEvent(const SDL_Event *event) +{ + char name[64]; + char details[128]; + + /* sensor/mouse/finger motion are spammy, ignore these if they aren't demanded. */ + if ((SDL_EventLoggingVerbosity < 2) && + ((event->type == SDL_MOUSEMOTION) || + (event->type == SDL_FINGERMOTION) || + (event->type == SDL_CONTROLLERTOUCHPADMOTION) || + (event->type == SDL_CONTROLLERSENSORUPDATE) || + (event->type == SDL_SENSORUPDATE))) { + return; + } + + /* window manager events are even more spammy, and don't provide much useful info. */ + if ((SDL_EventLoggingVerbosity < 3) && (event->type == SDL_SYSWMEVENT)) { + return; + } + +/* this is to make (void)SDL_snprintf() calls cleaner. */ +#define uint unsigned int + + name[0] = '\0'; + details[0] = '\0'; + + /* !!! FIXME: This code is kinda ugly, sorry. */ + + if ((event->type >= SDL_USEREVENT) && (event->type <= SDL_LASTEVENT)) { + char plusstr[16]; + SDL_strlcpy(name, "SDL_USEREVENT", sizeof(name)); + if (event->type > SDL_USEREVENT) { + (void)SDL_snprintf(plusstr, sizeof(plusstr), "+%u", ((uint)event->type) - SDL_USEREVENT); + } else { + plusstr[0] = '\0'; + } + (void)SDL_snprintf(details, sizeof(details), "%s (timestamp=%u windowid=%u code=%d data1=%p data2=%p)", + plusstr, (uint)event->user.timestamp, (uint)event->user.windowID, + (int)event->user.code, event->user.data1, event->user.data2); + } + + switch (event->type) { +#define SDL_EVENT_CASE(x) \ + case x: \ + SDL_strlcpy(name, #x, sizeof(name)); + SDL_EVENT_CASE(SDL_FIRSTEVENT) + SDL_strlcpy(details, " (THIS IS PROBABLY A BUG!)", sizeof(details)); + break; + SDL_EVENT_CASE(SDL_QUIT) + (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u)", (uint)event->quit.timestamp); + break; + SDL_EVENT_CASE(SDL_APP_TERMINATING) + break; + SDL_EVENT_CASE(SDL_APP_LOWMEMORY) + break; + SDL_EVENT_CASE(SDL_APP_WILLENTERBACKGROUND) + break; + SDL_EVENT_CASE(SDL_APP_DIDENTERBACKGROUND) + break; + SDL_EVENT_CASE(SDL_APP_WILLENTERFOREGROUND) + break; + SDL_EVENT_CASE(SDL_APP_DIDENTERFOREGROUND) + break; + SDL_EVENT_CASE(SDL_LOCALECHANGED) + break; + SDL_EVENT_CASE(SDL_KEYMAPCHANGED) + break; + SDL_EVENT_CASE(SDL_CLIPBOARDUPDATE) + break; + SDL_EVENT_CASE(SDL_RENDER_TARGETS_RESET) + break; + SDL_EVENT_CASE(SDL_RENDER_DEVICE_RESET) + break; + + SDL_EVENT_CASE(SDL_DISPLAYEVENT) + { + char name2[64]; + switch (event->display.event) { + case SDL_DISPLAYEVENT_NONE: + SDL_strlcpy(name2, "SDL_DISPLAYEVENT_NONE (THIS IS PROBABLY A BUG!)", sizeof(name2)); + break; +#define SDL_DISPLAYEVENT_CASE(x) \ + case x: \ + SDL_strlcpy(name2, #x, sizeof(name2)); \ + break + SDL_DISPLAYEVENT_CASE(SDL_DISPLAYEVENT_ORIENTATION); + SDL_DISPLAYEVENT_CASE(SDL_DISPLAYEVENT_CONNECTED); + SDL_DISPLAYEVENT_CASE(SDL_DISPLAYEVENT_DISCONNECTED); + SDL_DISPLAYEVENT_CASE(SDL_DISPLAYEVENT_MOVED); +#undef SDL_DISPLAYEVENT_CASE + default: + SDL_strlcpy(name2, "UNKNOWN (bug? fixme?)", sizeof(name2)); + break; + } + (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u display=%u event=%s data1=%d)", + (uint)event->display.timestamp, (uint)event->display.display, name2, (int)event->display.data1); + break; + } + + SDL_EVENT_CASE(SDL_WINDOWEVENT) + { + char name2[64]; + switch (event->window.event) { + case SDL_WINDOWEVENT_NONE: + SDL_strlcpy(name2, "SDL_WINDOWEVENT_NONE (THIS IS PROBABLY A BUG!)", sizeof(name2)); + break; +#define SDL_WINDOWEVENT_CASE(x) \ + case x: \ + SDL_strlcpy(name2, #x, sizeof(name2)); \ + break + SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_SHOWN); + SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_HIDDEN); + SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_EXPOSED); + SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_MOVED); + SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_RESIZED); + SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_SIZE_CHANGED); + SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_MINIMIZED); + SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_MAXIMIZED); + SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_RESTORED); + SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_ENTER); + SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_LEAVE); + SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_FOCUS_GAINED); + SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_FOCUS_LOST); + SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_CLOSE); + SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_TAKE_FOCUS); + SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_HIT_TEST); + SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_ICCPROF_CHANGED); + SDL_WINDOWEVENT_CASE(SDL_WINDOWEVENT_DISPLAY_CHANGED); +#undef SDL_WINDOWEVENT_CASE + default: + SDL_strlcpy(name2, "UNKNOWN (bug? fixme?)", sizeof(name2)); + break; + } + (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u event=%s data1=%d data2=%d)", + (uint)event->window.timestamp, (uint)event->window.windowID, name2, (int)event->window.data1, (int)event->window.data2); + break; + } + + SDL_EVENT_CASE(SDL_SYSWMEVENT) + /* !!! FIXME: we don't delve further at the moment. */ + (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u)", (uint)event->syswm.timestamp); + break; + +#define PRINT_KEY_EVENT(event) \ + (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u state=%s repeat=%s scancode=%u keycode=%u mod=%u)", \ + (uint)event->key.timestamp, (uint)event->key.windowID, \ + event->key.state == SDL_PRESSED ? "pressed" : "released", \ + event->key.repeat ? "true" : "false", \ + (uint)event->key.keysym.scancode, \ + (uint)event->key.keysym.sym, \ + (uint)event->key.keysym.mod) + SDL_EVENT_CASE(SDL_KEYDOWN) + PRINT_KEY_EVENT(event); + break; + SDL_EVENT_CASE(SDL_KEYUP) + PRINT_KEY_EVENT(event); + break; +#undef PRINT_KEY_EVENT + + SDL_EVENT_CASE(SDL_TEXTEDITING) + (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u text='%s' start=%d length=%d)", + (uint)event->edit.timestamp, (uint)event->edit.windowID, + event->edit.text, (int)event->edit.start, (int)event->edit.length); + break; + + SDL_EVENT_CASE(SDL_TEXTINPUT) + (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u text='%s')", (uint)event->text.timestamp, (uint)event->text.windowID, event->text.text); + break; + + SDL_EVENT_CASE(SDL_MOUSEMOTION) + (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u which=%u state=%u x=%d y=%d xrel=%d yrel=%d)", + (uint)event->motion.timestamp, (uint)event->motion.windowID, + (uint)event->motion.which, (uint)event->motion.state, + (int)event->motion.x, (int)event->motion.y, + (int)event->motion.xrel, (int)event->motion.yrel); + break; + +#define PRINT_MBUTTON_EVENT(event) \ + (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u which=%u button=%u state=%s clicks=%u x=%d y=%d)", \ + (uint)event->button.timestamp, (uint)event->button.windowID, \ + (uint)event->button.which, (uint)event->button.button, \ + event->button.state == SDL_PRESSED ? "pressed" : "released", \ + (uint)event->button.clicks, (int)event->button.x, (int)event->button.y) + SDL_EVENT_CASE(SDL_MOUSEBUTTONDOWN) + PRINT_MBUTTON_EVENT(event); + break; + SDL_EVENT_CASE(SDL_MOUSEBUTTONUP) + PRINT_MBUTTON_EVENT(event); + break; +#undef PRINT_MBUTTON_EVENT + + SDL_EVENT_CASE(SDL_MOUSEWHEEL) + (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u which=%u x=%d y=%d preciseX=%f preciseY=%f direction=%s)", + (uint)event->wheel.timestamp, (uint)event->wheel.windowID, + (uint)event->wheel.which, (int)event->wheel.x, (int)event->wheel.y, + event->wheel.preciseX, event->wheel.preciseY, + event->wheel.direction == SDL_MOUSEWHEEL_NORMAL ? "normal" : "flipped"); + break; + + SDL_EVENT_CASE(SDL_JOYAXISMOTION) + (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%d axis=%u value=%d)", + (uint)event->jaxis.timestamp, (int)event->jaxis.which, + (uint)event->jaxis.axis, (int)event->jaxis.value); + break; + + SDL_EVENT_CASE(SDL_JOYBALLMOTION) + (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%d ball=%u xrel=%d yrel=%d)", + (uint)event->jball.timestamp, (int)event->jball.which, + (uint)event->jball.ball, (int)event->jball.xrel, (int)event->jball.yrel); + break; + + SDL_EVENT_CASE(SDL_JOYHATMOTION) + (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%d hat=%u value=%u)", + (uint)event->jhat.timestamp, (int)event->jhat.which, + (uint)event->jhat.hat, (uint)event->jhat.value); + break; + +#define PRINT_JBUTTON_EVENT(event) \ + (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%d button=%u state=%s)", \ + (uint)event->jbutton.timestamp, (int)event->jbutton.which, \ + (uint)event->jbutton.button, event->jbutton.state == SDL_PRESSED ? "pressed" : "released") + SDL_EVENT_CASE(SDL_JOYBUTTONDOWN) + PRINT_JBUTTON_EVENT(event); + break; + SDL_EVENT_CASE(SDL_JOYBUTTONUP) + PRINT_JBUTTON_EVENT(event); + break; +#undef PRINT_JBUTTON_EVENT + +#define PRINT_JOYDEV_EVENT(event) (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%d)", (uint)event->jdevice.timestamp, (int)event->jdevice.which) + SDL_EVENT_CASE(SDL_JOYDEVICEADDED) + PRINT_JOYDEV_EVENT(event); + break; + SDL_EVENT_CASE(SDL_JOYDEVICEREMOVED) + PRINT_JOYDEV_EVENT(event); + break; +#undef PRINT_JOYDEV_EVENT + + SDL_EVENT_CASE(SDL_CONTROLLERAXISMOTION) + (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%d axis=%u value=%d)", + (uint)event->caxis.timestamp, (int)event->caxis.which, + (uint)event->caxis.axis, (int)event->caxis.value); + break; + +#define PRINT_CBUTTON_EVENT(event) \ + (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%d button=%u state=%s)", \ + (uint)event->cbutton.timestamp, (int)event->cbutton.which, \ + (uint)event->cbutton.button, event->cbutton.state == SDL_PRESSED ? "pressed" : "released") + SDL_EVENT_CASE(SDL_CONTROLLERBUTTONDOWN) + PRINT_CBUTTON_EVENT(event); + break; + SDL_EVENT_CASE(SDL_CONTROLLERBUTTONUP) + PRINT_CBUTTON_EVENT(event); + break; +#undef PRINT_CBUTTON_EVENT + +#define PRINT_CONTROLLERDEV_EVENT(event) (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%d)", (uint)event->cdevice.timestamp, (int)event->cdevice.which) + SDL_EVENT_CASE(SDL_CONTROLLERDEVICEADDED) + PRINT_CONTROLLERDEV_EVENT(event); + break; + SDL_EVENT_CASE(SDL_CONTROLLERDEVICEREMOVED) + PRINT_CONTROLLERDEV_EVENT(event); + break; + SDL_EVENT_CASE(SDL_CONTROLLERDEVICEREMAPPED) + PRINT_CONTROLLERDEV_EVENT(event); + break; + SDL_EVENT_CASE(SDL_CONTROLLERSTEAMHANDLEUPDATED) + PRINT_CONTROLLERDEV_EVENT(event); + break; +#undef PRINT_CONTROLLERDEV_EVENT + +#define PRINT_CTOUCHPAD_EVENT(event) \ + (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%d touchpad=%d finger=%d x=%f y=%f pressure=%f)", \ + (uint)event->ctouchpad.timestamp, (int)event->ctouchpad.which, \ + (int)event->ctouchpad.touchpad, (int)event->ctouchpad.finger, \ + event->ctouchpad.x, event->ctouchpad.y, event->ctouchpad.pressure) + SDL_EVENT_CASE(SDL_CONTROLLERTOUCHPADDOWN) + PRINT_CTOUCHPAD_EVENT(event); + break; + SDL_EVENT_CASE(SDL_CONTROLLERTOUCHPADUP) + PRINT_CTOUCHPAD_EVENT(event); + break; + SDL_EVENT_CASE(SDL_CONTROLLERTOUCHPADMOTION) + PRINT_CTOUCHPAD_EVENT(event); + break; +#undef PRINT_CTOUCHPAD_EVENT + + SDL_EVENT_CASE(SDL_CONTROLLERSENSORUPDATE) + (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%d sensor=%d data[0]=%f data[1]=%f data[2]=%f)", + (uint)event->csensor.timestamp, (int)event->csensor.which, (int)event->csensor.sensor, + event->csensor.data[0], event->csensor.data[1], event->csensor.data[2]); + break; + +#define PRINT_FINGER_EVENT(event) \ + (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u touchid=%" SDL_PRIs64 " fingerid=%" SDL_PRIs64 " x=%f y=%f dx=%f dy=%f pressure=%f)", \ + (uint)event->tfinger.timestamp, event->tfinger.touchId, \ + event->tfinger.fingerId, event->tfinger.x, event->tfinger.y, \ + event->tfinger.dx, event->tfinger.dy, event->tfinger.pressure) + SDL_EVENT_CASE(SDL_FINGERDOWN) + PRINT_FINGER_EVENT(event); + break; + SDL_EVENT_CASE(SDL_FINGERUP) + PRINT_FINGER_EVENT(event); + break; + SDL_EVENT_CASE(SDL_FINGERMOTION) + PRINT_FINGER_EVENT(event); + break; +#undef PRINT_FINGER_EVENT + +#define PRINT_DOLLAR_EVENT(event) \ + (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u touchid=%" SDL_PRIs64 " gestureid=%" SDL_PRIs64 " numfingers=%u error=%f x=%f y=%f)", \ + (uint)event->dgesture.timestamp, event->dgesture.touchId, \ + event->dgesture.gestureId, (uint)event->dgesture.numFingers, \ + event->dgesture.error, event->dgesture.x, event->dgesture.y) + SDL_EVENT_CASE(SDL_DOLLARGESTURE) + PRINT_DOLLAR_EVENT(event); + break; + SDL_EVENT_CASE(SDL_DOLLARRECORD) + PRINT_DOLLAR_EVENT(event); + break; +#undef PRINT_DOLLAR_EVENT + + SDL_EVENT_CASE(SDL_MULTIGESTURE) + (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u touchid=%" SDL_PRIs64 " dtheta=%f ddist=%f x=%f y=%f numfingers=%u)", + (uint)event->mgesture.timestamp, event->mgesture.touchId, + event->mgesture.dTheta, event->mgesture.dDist, + event->mgesture.x, event->mgesture.y, (uint)event->mgesture.numFingers); + break; + +#define PRINT_DROP_EVENT(event) (void)SDL_snprintf(details, sizeof(details), " (file='%s' timestamp=%u windowid=%u)", event->drop.file, (uint)event->drop.timestamp, (uint)event->drop.windowID) + SDL_EVENT_CASE(SDL_DROPFILE) + PRINT_DROP_EVENT(event); + break; + SDL_EVENT_CASE(SDL_DROPTEXT) + PRINT_DROP_EVENT(event); + break; + SDL_EVENT_CASE(SDL_DROPBEGIN) + PRINT_DROP_EVENT(event); + break; + SDL_EVENT_CASE(SDL_DROPCOMPLETE) + PRINT_DROP_EVENT(event); + break; +#undef PRINT_DROP_EVENT + +#define PRINT_AUDIODEV_EVENT(event) (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%u iscapture=%s)", (uint)event->adevice.timestamp, (uint)event->adevice.which, event->adevice.iscapture ? "true" : "false") + SDL_EVENT_CASE(SDL_AUDIODEVICEADDED) + PRINT_AUDIODEV_EVENT(event); + break; + SDL_EVENT_CASE(SDL_AUDIODEVICEREMOVED) + PRINT_AUDIODEV_EVENT(event); + break; +#undef PRINT_AUDIODEV_EVENT + + SDL_EVENT_CASE(SDL_SENSORUPDATE) + (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%d data[0]=%f data[1]=%f data[2]=%f data[3]=%f data[4]=%f data[5]=%f)", + (uint)event->sensor.timestamp, (int)event->sensor.which, + event->sensor.data[0], event->sensor.data[1], event->sensor.data[2], + event->sensor.data[3], event->sensor.data[4], event->sensor.data[5]); + break; + +#undef SDL_EVENT_CASE + + case SDL_POLLSENTINEL: + /* No logging necessary for this one */ + break; + + default: + if (!name[0]) { + SDL_strlcpy(name, "UNKNOWN", sizeof(name)); + (void)SDL_snprintf(details, sizeof(details), " #%u! (Bug? FIXME?)", (uint)event->type); + } + break; + } + + if (name[0]) { + SDL_Log("SDL EVENT: %s%s", name, details); + } + +#undef uint +} + +/* Public functions */ + +void SDL_StopEventLoop(void) +{ + const char *report = SDL_GetHint("SDL_EVENT_QUEUE_STATISTICS"); + int i; + SDL_EventEntry *entry; + SDL_SysWMEntry *wmmsg; + + SDL_LockMutex(SDL_EventQ.lock); + + SDL_EventQ.active = SDL_FALSE; + + if (report && SDL_atoi(report)) { + SDL_Log("SDL EVENT QUEUE: Maximum events in-flight: %d\n", + SDL_EventQ.max_events_seen); + } + + /* Clean out EventQ */ + for (entry = SDL_EventQ.head; entry;) { + SDL_EventEntry *next = entry->next; + SDL_free(entry); + entry = next; + } + for (entry = SDL_EventQ.free; entry;) { + SDL_EventEntry *next = entry->next; + SDL_free(entry); + entry = next; + } + for (wmmsg = SDL_EventQ.wmmsg_used; wmmsg;) { + SDL_SysWMEntry *next = wmmsg->next; + SDL_free(wmmsg); + wmmsg = next; + } + for (wmmsg = SDL_EventQ.wmmsg_free; wmmsg;) { + SDL_SysWMEntry *next = wmmsg->next; + SDL_free(wmmsg); + wmmsg = next; + } + + SDL_AtomicSet(&SDL_EventQ.count, 0); + SDL_EventQ.max_events_seen = 0; + SDL_EventQ.head = NULL; + SDL_EventQ.tail = NULL; + SDL_EventQ.free = NULL; + SDL_EventQ.wmmsg_used = NULL; + SDL_EventQ.wmmsg_free = NULL; + SDL_AtomicSet(&SDL_sentinel_pending, 0); + + /* Clear disabled event state */ + for (i = 0; i < SDL_arraysize(SDL_disabled_events); ++i) { + SDL_free(SDL_disabled_events[i]); + SDL_disabled_events[i] = NULL; + } + + if (SDL_event_watchers_lock) { + SDL_DestroyMutex(SDL_event_watchers_lock); + SDL_event_watchers_lock = NULL; + } + if (SDL_event_watchers) { + SDL_free(SDL_event_watchers); + SDL_event_watchers = NULL; + SDL_event_watchers_count = 0; + } + SDL_zero(SDL_EventOK); + + SDL_UnlockMutex(SDL_EventQ.lock); + + if (SDL_EventQ.lock) { + SDL_DestroyMutex(SDL_EventQ.lock); + SDL_EventQ.lock = NULL; + } +} + +/* This function (and associated calls) may be called more than once */ +int SDL_StartEventLoop(void) +{ + /* We'll leave the event queue alone, since we might have gotten + some important events at launch (like SDL_DROPFILE) + + FIXME: Does this introduce any other bugs with events at startup? + */ + + /* Create the lock and set ourselves active */ +#ifndef SDL_THREADS_DISABLED + if (!SDL_EventQ.lock) { + SDL_EventQ.lock = SDL_CreateMutex(); + if (SDL_EventQ.lock == NULL) { + return -1; + } + } + SDL_LockMutex(SDL_EventQ.lock); + + if (SDL_event_watchers_lock == NULL) { + SDL_event_watchers_lock = SDL_CreateMutex(); + if (SDL_event_watchers_lock == NULL) { + SDL_UnlockMutex(SDL_EventQ.lock); + return -1; + } + } +#endif /* !SDL_THREADS_DISABLED */ + + /* Process most event types */ + (void)SDL_EventState(SDL_TEXTINPUT, SDL_DISABLE); + (void)SDL_EventState(SDL_TEXTEDITING, SDL_DISABLE); + (void)SDL_EventState(SDL_SYSWMEVENT, SDL_DISABLE); +#if 0 /* Leave these events enabled so apps can respond to items being dragged onto them at startup */ + (void)SDL_EventState(SDL_DROPFILE, SDL_DISABLE); + (void)SDL_EventState(SDL_DROPTEXT, SDL_DISABLE); +#endif + + SDL_EventQ.active = SDL_TRUE; + SDL_UnlockMutex(SDL_EventQ.lock); + return 0; +} + +/* Add an event to the event queue -- called with the queue locked */ +static int SDL_AddEvent(SDL_Event *event) +{ + SDL_EventEntry *entry; + const int initial_count = SDL_AtomicGet(&SDL_EventQ.count); + int final_count; + + if (initial_count >= SDL_MAX_QUEUED_EVENTS) { + SDL_SetError("Event queue is full (%d events)", initial_count); + return 0; + } + + if (SDL_EventQ.free == NULL) { + entry = (SDL_EventEntry *)SDL_malloc(sizeof(*entry)); + if (entry == NULL) { + return 0; + } + } else { + entry = SDL_EventQ.free; + SDL_EventQ.free = entry->next; + } + + if (SDL_EventLoggingVerbosity > 0) { + SDL_LogEvent(event); + } + + entry->event = *event; + if (event->type == SDL_POLLSENTINEL) { + SDL_AtomicAdd(&SDL_sentinel_pending, 1); + } else if (event->type == SDL_SYSWMEVENT) { + entry->msg = *event->syswm.msg; + entry->event.syswm.msg = &entry->msg; + } + + if (SDL_EventQ.tail) { + SDL_EventQ.tail->next = entry; + entry->prev = SDL_EventQ.tail; + SDL_EventQ.tail = entry; + entry->next = NULL; + } else { + SDL_assert(!SDL_EventQ.head); + SDL_EventQ.head = entry; + SDL_EventQ.tail = entry; + entry->prev = NULL; + entry->next = NULL; + } + + final_count = SDL_AtomicAdd(&SDL_EventQ.count, 1) + 1; + if (final_count > SDL_EventQ.max_events_seen) { + SDL_EventQ.max_events_seen = final_count; + } + + return 1; +} + +/* Remove an event from the queue -- called with the queue locked */ +static void SDL_CutEvent(SDL_EventEntry *entry) +{ + if (entry->prev) { + entry->prev->next = entry->next; + } + if (entry->next) { + entry->next->prev = entry->prev; + } + + if (entry == SDL_EventQ.head) { + SDL_assert(entry->prev == NULL); + SDL_EventQ.head = entry->next; + } + if (entry == SDL_EventQ.tail) { + SDL_assert(entry->next == NULL); + SDL_EventQ.tail = entry->prev; + } + + if (entry->event.type == SDL_POLLSENTINEL) { + SDL_AtomicAdd(&SDL_sentinel_pending, -1); + } + + entry->next = SDL_EventQ.free; + SDL_EventQ.free = entry; + SDL_assert(SDL_AtomicGet(&SDL_EventQ.count) > 0); + SDL_AtomicAdd(&SDL_EventQ.count, -1); +} + +static int SDL_SendWakeupEvent(void) +{ + SDL_VideoDevice *_this = SDL_GetVideoDevice(); + if (_this == NULL || !_this->SendWakeupEvent) { + return 0; + } + + SDL_LockMutex(_this->wakeup_lock); + { + if (_this->wakeup_window) { + _this->SendWakeupEvent(_this, _this->wakeup_window); + + /* No more wakeup events needed until we enter a new wait */ + _this->wakeup_window = NULL; + } + } + SDL_UnlockMutex(_this->wakeup_lock); + + return 0; +} + +/* Lock the event queue, take a peep at it, and unlock it */ +static int SDL_PeepEventsInternal(SDL_Event *events, int numevents, SDL_eventaction action, + Uint32 minType, Uint32 maxType, SDL_bool include_sentinel) +{ + int i, used, sentinels_expected = 0; + + /* Lock the event queue */ + used = 0; + + SDL_LockMutex(SDL_EventQ.lock); + { + /* Don't look after we've quit */ + if (!SDL_EventQ.active) { + /* We get a few spurious events at shutdown, so don't warn then */ + if (action == SDL_GETEVENT) { + SDL_SetError("The event system has been shut down"); + } + SDL_UnlockMutex(SDL_EventQ.lock); + return -1; + } + if (action == SDL_ADDEVENT) { + for (i = 0; i < numevents; ++i) { + used += SDL_AddEvent(&events[i]); + } + } else { + SDL_EventEntry *entry, *next; + SDL_SysWMEntry *wmmsg, *wmmsg_next; + Uint32 type; + + if (action == SDL_GETEVENT) { + /* Clean out any used wmmsg data + FIXME: Do we want to retain the data for some period of time? + */ + for (wmmsg = SDL_EventQ.wmmsg_used; wmmsg; wmmsg = wmmsg_next) { + wmmsg_next = wmmsg->next; + wmmsg->next = SDL_EventQ.wmmsg_free; + SDL_EventQ.wmmsg_free = wmmsg; + } + SDL_EventQ.wmmsg_used = NULL; + } + + for (entry = SDL_EventQ.head; entry && (events == NULL || used < numevents); entry = next) { + next = entry->next; + type = entry->event.type; + if (minType <= type && type <= maxType) { + if (events) { + events[used] = entry->event; + if (entry->event.type == SDL_SYSWMEVENT) { + /* We need to copy the wmmsg somewhere safe. + For now we'll guarantee it's valid at least until + the next call to SDL_PeepEvents() + */ + if (SDL_EventQ.wmmsg_free) { + wmmsg = SDL_EventQ.wmmsg_free; + SDL_EventQ.wmmsg_free = wmmsg->next; + } else { + wmmsg = (SDL_SysWMEntry *)SDL_malloc(sizeof(*wmmsg)); + } + wmmsg->msg = *entry->event.syswm.msg; + wmmsg->next = SDL_EventQ.wmmsg_used; + SDL_EventQ.wmmsg_used = wmmsg; + events[used].syswm.msg = &wmmsg->msg; + } + + if (action == SDL_GETEVENT) { + SDL_CutEvent(entry); + } + } + if (type == SDL_POLLSENTINEL) { + /* Special handling for the sentinel event */ + if (!include_sentinel) { + /* Skip it, we don't want to include it */ + continue; + } + if (events == NULL || action != SDL_GETEVENT) { + ++sentinels_expected; + } + if (SDL_AtomicGet(&SDL_sentinel_pending) > sentinels_expected) { + /* Skip it, there's another one pending */ + continue; + } + } + ++used; + } + } + } + } + SDL_UnlockMutex(SDL_EventQ.lock); + + if (used > 0 && action == SDL_ADDEVENT) { + SDL_SendWakeupEvent(); + } + + return used; +} +int SDL_PeepEvents(SDL_Event *events, int numevents, SDL_eventaction action, + Uint32 minType, Uint32 maxType) +{ + return SDL_PeepEventsInternal(events, numevents, action, minType, maxType, SDL_FALSE); +} + +SDL_bool SDL_HasEvent(Uint32 type) +{ + return SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, type, type) > 0; +} + +SDL_bool SDL_HasEvents(Uint32 minType, Uint32 maxType) +{ + return SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, minType, maxType) > 0; +} + +void SDL_FlushEvent(Uint32 type) +{ + SDL_FlushEvents(type, type); +} + +void SDL_FlushEvents(Uint32 minType, Uint32 maxType) +{ + SDL_EventEntry *entry, *next; + Uint32 type; + /* !!! FIXME: we need to manually SDL_free() the strings in TEXTINPUT and + drag'n'drop events if we're flushing them without passing them to the + app, but I don't know if this is the right place to do that. */ + + /* Make sure the events are current */ +#if 0 + /* Actually, we can't do this since we might be flushing while processing + a resize event, and calling this might trigger further resize events. + */ + SDL_PumpEvents(); +#endif + + /* Lock the event queue */ + SDL_LockMutex(SDL_EventQ.lock); + { + /* Don't look after we've quit */ + if (!SDL_EventQ.active) { + SDL_UnlockMutex(SDL_EventQ.lock); + return; + } + for (entry = SDL_EventQ.head; entry; entry = next) { + next = entry->next; + type = entry->event.type; + if (minType <= type && type <= maxType) { + SDL_CutEvent(entry); + } + } + } + SDL_UnlockMutex(SDL_EventQ.lock); +} + +/* Run the system dependent event loops */ +static void SDL_PumpEventsInternal(SDL_bool push_sentinel) +{ + SDL_VideoDevice *_this = SDL_GetVideoDevice(); + + /* Release any keys held down from last frame */ + SDL_ReleaseAutoReleaseKeys(); + + /* Get events from the video subsystem */ + if (_this) { + _this->PumpEvents(_this); + } + +#ifndef SDL_JOYSTICK_DISABLED + /* Check for joystick state change */ + if (SDL_update_joysticks) { + SDL_JoystickUpdate(); + } +#endif + +#ifndef SDL_SENSOR_DISABLED + /* Check for sensor state change */ + if (SDL_update_sensors) { + SDL_SensorUpdate(); + } +#endif + + SDL_SendPendingSignalEvents(); /* in case we had a signal handler fire, etc. */ + + if (push_sentinel && SDL_GetEventState(SDL_POLLSENTINEL) == SDL_ENABLE) { + SDL_Event sentinel; + + /* Make sure we don't already have a sentinel in the queue, and add one to the end */ + if (SDL_AtomicGet(&SDL_sentinel_pending) > 0) { + SDL_PeepEventsInternal(&sentinel, 1, SDL_GETEVENT, SDL_POLLSENTINEL, SDL_POLLSENTINEL, SDL_TRUE); + } + + SDL_zero(sentinel); + sentinel.type = SDL_POLLSENTINEL; + SDL_PushEvent(&sentinel); + } +} + +void SDL_PumpEvents(void) +{ + SDL_PumpEventsInternal(SDL_FALSE); +} + +/* Public functions */ + +int SDL_PollEvent(SDL_Event *event) +{ + return SDL_WaitEventTimeout(event, 0); +} + +static SDL_bool SDL_events_need_periodic_poll(void) +{ + SDL_bool need_periodic_poll = SDL_FALSE; + +#ifndef SDL_JOYSTICK_DISABLED + need_periodic_poll = + SDL_WasInit(SDL_INIT_JOYSTICK) && SDL_update_joysticks; +#endif + +#ifndef SDL_SENSOR_DISABLED + need_periodic_poll = need_periodic_poll || + (SDL_WasInit(SDL_INIT_SENSOR) && SDL_update_sensors); +#endif + + return need_periodic_poll; +} + +static int SDL_WaitEventTimeout_Device(_THIS, SDL_Window *wakeup_window, SDL_Event *event, Uint32 start, int timeout) +{ + int loop_timeout = timeout; + SDL_bool need_periodic_poll = SDL_events_need_periodic_poll(); + + for (;;) { + /* Pump events on entry and each time we wake to ensure: + a) All pending events are batch processed after waking up from a wait + b) Waiting can be completely skipped if events are already available to be pumped + c) Periodic processing that takes place in some platform PumpEvents() functions happens + d) Signals received in WaitEventTimeout() are turned into SDL events + */ + int status; + SDL_PumpEventsInternal(SDL_TRUE); + + SDL_LockMutex(_this->wakeup_lock); + { + status = SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT); + /* If status == 0 we are going to block so wakeup will be needed. */ + if (status == 0) { + _this->wakeup_window = wakeup_window; + } else { + _this->wakeup_window = NULL; + } + } + SDL_UnlockMutex(_this->wakeup_lock); + + if (status < 0) { + /* Got an error: return */ + break; + } + if (status > 0) { + /* There is an event, we can return. */ + return 1; + } + /* No events found in the queue, call WaitEventTimeout to wait for an event. */ + if (timeout > 0) { + Uint32 elapsed = SDL_GetTicks() - start; + if (elapsed >= (Uint32)timeout) { + /* Set wakeup_window to NULL without holding the lock. */ + _this->wakeup_window = NULL; + return 0; + } + loop_timeout = (int)((Uint32)timeout - elapsed); + } + if (need_periodic_poll) { + if (loop_timeout >= 0) { + loop_timeout = SDL_min(loop_timeout, PERIODIC_POLL_INTERVAL_MS); + } else { + loop_timeout = PERIODIC_POLL_INTERVAL_MS; + } + } + status = _this->WaitEventTimeout(_this, loop_timeout); + /* Set wakeup_window to NULL without holding the lock. */ + _this->wakeup_window = NULL; + if (status == 0 && need_periodic_poll && loop_timeout == PERIODIC_POLL_INTERVAL_MS) { + /* We may have woken up to poll. Try again */ + continue; + } else if (status <= 0) { + /* There is either an error or the timeout is elapsed: return */ + return status; + } + /* An event was found and pumped into the SDL events queue. Continue the loop + to let SDL_PeepEvents pick it up .*/ + } + return 0; +} + +static SDL_bool SDL_events_need_polling(void) +{ + SDL_bool need_polling = SDL_FALSE; + +#ifndef SDL_JOYSTICK_DISABLED + need_polling = + SDL_WasInit(SDL_INIT_JOYSTICK) && + SDL_update_joysticks && + (SDL_NumJoysticks() > 0); +#endif + +#ifndef SDL_SENSOR_DISABLED + need_polling = need_polling || + (SDL_WasInit(SDL_INIT_SENSOR) && SDL_update_sensors && (SDL_NumSensors() > 0)); +#endif + + return need_polling; +} + +static SDL_Window *SDL_find_active_window(SDL_VideoDevice *_this) +{ + SDL_Window *window; + for (window = _this->windows; window; window = window->next) { + if (!window->is_destroying) { + return window; + } + } + return NULL; +} + +int SDL_WaitEvent(SDL_Event *event) +{ + return SDL_WaitEventTimeout(event, -1); +} + +int SDL_WaitEventTimeout(SDL_Event *event, int timeout) +{ + SDL_VideoDevice *_this = SDL_GetVideoDevice(); + SDL_Window *wakeup_window; + Uint32 start, expiration; + SDL_bool include_sentinel = (timeout == 0) ? SDL_TRUE : SDL_FALSE; + int result; + + /* If there isn't a poll sentinel event pending, pump events and add one */ + if (SDL_AtomicGet(&SDL_sentinel_pending) == 0) { + SDL_PumpEventsInternal(SDL_TRUE); + } + + /* First check for existing events */ + result = SDL_PeepEventsInternal(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT, include_sentinel); + if (result < 0) { + return 0; + } + if (include_sentinel) { + if (event) { + if (event->type == SDL_POLLSENTINEL) { + /* Reached the end of a poll cycle, and not willing to wait */ + return 0; + } + } else { + /* Need to peek the next event to check for sentinel */ + SDL_Event dummy; + + if (SDL_PeepEventsInternal(&dummy, 1, SDL_PEEKEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT, SDL_TRUE) && + dummy.type == SDL_POLLSENTINEL) { + SDL_PeepEventsInternal(&dummy, 1, SDL_GETEVENT, SDL_POLLSENTINEL, SDL_POLLSENTINEL, SDL_TRUE); + /* Reached the end of a poll cycle, and not willing to wait */ + return 0; + } + } + } + if (result == 0) { + if (timeout == 0) { + /* No events available, and not willing to wait */ + return 0; + } + } else { + /* Has existing events */ + return 1; + } + /* We should have completely handled timeout == 0 above */ + SDL_assert(timeout != 0); + + if (timeout > 0) { + start = SDL_GetTicks(); + expiration = start + timeout; + } else { + start = 0; + expiration = 0; + } + + if (_this && _this->WaitEventTimeout && _this->SendWakeupEvent && !SDL_events_need_polling()) { + /* Look if a shown window is available to send the wakeup event. */ + wakeup_window = SDL_find_active_window(_this); + if (wakeup_window) { + int status = SDL_WaitEventTimeout_Device(_this, wakeup_window, event, start, timeout); + + /* There may be implementation-defined conditions where the backend cannot + reliably wait for the next event. If that happens, fall back to polling. */ + if (status >= 0) { + return status; + } + } + } + + for (;;) { + SDL_PumpEventsInternal(SDL_TRUE); + switch (SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) { + case -1: + return 0; + case 0: + if (timeout > 0 && SDL_TICKS_PASSED(SDL_GetTicks(), expiration)) { + /* Timeout expired and no events */ + return 0; + } + SDL_Delay(1); + break; + default: + /* Has events */ + return 1; + } + } +} + +int SDL_PushEvent(SDL_Event *event) +{ + event->common.timestamp = SDL_GetTicks(); + + if (SDL_EventOK.callback || SDL_event_watchers_count > 0) { + SDL_LockMutex(SDL_event_watchers_lock); + { + if (SDL_EventOK.callback && !SDL_EventOK.callback(SDL_EventOK.userdata, event)) { + SDL_UnlockMutex(SDL_event_watchers_lock); + return 0; + } + + if (SDL_event_watchers_count > 0) { + /* 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_memmove(&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; + } + } + } + SDL_UnlockMutex(SDL_event_watchers_lock); + } + + if (SDL_PeepEvents(event, 1, SDL_ADDEVENT, 0, 0) <= 0) { + return -1; + } + + SDL_GestureProcessEvent(event); + + return 1; +} + +void SDL_SetEventFilter(SDL_EventFilter filter, void *userdata) +{ + SDL_LockMutex(SDL_event_watchers_lock); + { + /* Set filter and discard pending events */ + SDL_EventOK.callback = filter; + SDL_EventOK.userdata = userdata; + SDL_FlushEvents(SDL_FIRSTEVENT, SDL_LASTEVENT); + } + SDL_UnlockMutex(SDL_event_watchers_lock); +} + +SDL_bool SDL_GetEventFilter(SDL_EventFilter *filter, void **userdata) +{ + SDL_EventWatcher event_ok; + + SDL_LockMutex(SDL_event_watchers_lock); + { + event_ok = SDL_EventOK; + } + SDL_UnlockMutex(SDL_event_watchers_lock); + + if (filter) { + *filter = event_ok.callback; + } + if (userdata) { + *userdata = event_ok.userdata; + } + return event_ok.callback ? SDL_TRUE : SDL_FALSE; +} + +void SDL_AddEventWatch(SDL_EventFilter filter, void *userdata) +{ + SDL_LockMutex(SDL_event_watchers_lock); + { + 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; + watcher->removed = SDL_FALSE; + ++SDL_event_watchers_count; + } + } + SDL_UnlockMutex(SDL_event_watchers_lock); +} + +void SDL_DelEventWatch(SDL_EventFilter filter, void *userdata) +{ + SDL_LockMutex(SDL_event_watchers_lock); + { + int i; + + for (i = 0; i < SDL_event_watchers_count; ++i) { + if (SDL_event_watchers[i].callback == filter && SDL_event_watchers[i].userdata == userdata) { + 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_memmove(&SDL_event_watchers[i], &SDL_event_watchers[i + 1], (SDL_event_watchers_count - i) * sizeof(SDL_event_watchers[i])); + } + } + break; + } + } + } + SDL_UnlockMutex(SDL_event_watchers_lock); +} + +void SDL_FilterEvents(SDL_EventFilter filter, void *userdata) +{ + SDL_LockMutex(SDL_EventQ.lock); + { + SDL_EventEntry *entry, *next; + for (entry = SDL_EventQ.head; entry; entry = next) { + next = entry->next; + if (!filter(userdata, &entry->event)) { + SDL_CutEvent(entry); + } + } + } + SDL_UnlockMutex(SDL_EventQ.lock); +} + +Uint8 SDL_EventState(Uint32 type, int state) +{ + const SDL_bool isde = (state == SDL_DISABLE) || (state == SDL_ENABLE); + Uint8 current_state; + Uint8 hi = ((type >> 8) & 0xff); + Uint8 lo = (type & 0xff); + + if (SDL_disabled_events[hi] && + (SDL_disabled_events[hi]->bits[lo / 32] & (1 << (lo & 31)))) { + current_state = SDL_DISABLE; + } else { + current_state = SDL_ENABLE; + } + + if (isde && state != current_state) { + if (state == SDL_DISABLE) { + /* Disable this event type and discard pending events */ + if (!SDL_disabled_events[hi]) { + SDL_disabled_events[hi] = (SDL_DisabledEventBlock *)SDL_calloc(1, sizeof(SDL_DisabledEventBlock)); + } + /* Out of memory, nothing we can do... */ + if (SDL_disabled_events[hi]) { + SDL_disabled_events[hi]->bits[lo / 32] |= (1 << (lo & 31)); + SDL_FlushEvent(type); + } + } else { // state == SDL_ENABLE + SDL_disabled_events[hi]->bits[lo / 32] &= ~(1 << (lo & 31)); + } + +#ifndef SDL_JOYSTICK_DISABLED + SDL_CalculateShouldUpdateJoysticks(SDL_GetHintBoolean(SDL_HINT_AUTO_UPDATE_JOYSTICKS, SDL_TRUE)); +#endif +#ifndef SDL_SENSOR_DISABLED + SDL_CalculateShouldUpdateSensors(SDL_GetHintBoolean(SDL_HINT_AUTO_UPDATE_SENSORS, SDL_TRUE)); +#endif + } + + /* turn off drag'n'drop support if we've disabled the events. + This might change some UI details at the OS level. */ + if (isde && ((type == SDL_DROPFILE) || (type == SDL_DROPTEXT))) { + SDL_ToggleDragAndDropSupport(); + } + + return current_state; +} + +Uint32 SDL_RegisterEvents(int numevents) +{ + Uint32 event_base; + + if ((numevents > 0) && (SDL_userevents + numevents <= SDL_LASTEVENT)) { + event_base = SDL_userevents; + SDL_userevents += numevents; + } else { + event_base = (Uint32)-1; + } + return event_base; +} + +int SDL_SendAppEvent(SDL_EventType eventType) +{ + int posted; + + posted = 0; + if (SDL_GetEventState(eventType) == SDL_ENABLE) { + SDL_Event event; + event.type = eventType; + posted = (SDL_PushEvent(&event) > 0); + } + return posted; +} + +int SDL_SendSysWMEvent(SDL_SysWMmsg *message) +{ + int posted; + + posted = 0; + if (SDL_GetEventState(SDL_SYSWMEVENT) == SDL_ENABLE) { + SDL_Event event; + SDL_memset(&event, 0, sizeof(event)); + event.type = SDL_SYSWMEVENT; + event.syswm.msg = message; + posted = (SDL_PushEvent(&event) > 0); + } + /* Update internal event state */ + return posted; +} + +int SDL_SendKeymapChangedEvent(void) +{ + return SDL_SendAppEvent(SDL_KEYMAPCHANGED); +} + +int SDL_SendLocaleChangedEvent(void) +{ + return SDL_SendAppEvent(SDL_LOCALECHANGED); +} + +int SDL_EventsInit(void) +{ +#ifndef SDL_JOYSTICK_DISABLED + SDL_AddHintCallback(SDL_HINT_AUTO_UPDATE_JOYSTICKS, SDL_AutoUpdateJoysticksChanged, NULL); +#endif +#ifndef SDL_SENSOR_DISABLED + SDL_AddHintCallback(SDL_HINT_AUTO_UPDATE_SENSORS, SDL_AutoUpdateSensorsChanged, NULL); +#endif + SDL_AddHintCallback(SDL_HINT_EVENT_LOGGING, SDL_EventLoggingChanged, NULL); + SDL_AddHintCallback(SDL_HINT_POLL_SENTINEL, SDL_PollSentinelChanged, NULL); + if (SDL_StartEventLoop() < 0) { + SDL_DelHintCallback(SDL_HINT_EVENT_LOGGING, SDL_EventLoggingChanged, NULL); + return -1; + } + + SDL_QuitInit(); + + return 0; +} + +void SDL_EventsQuit(void) +{ + SDL_QuitQuit(); + SDL_StopEventLoop(); + SDL_DelHintCallback(SDL_HINT_POLL_SENTINEL, SDL_PollSentinelChanged, NULL); + SDL_DelHintCallback(SDL_HINT_EVENT_LOGGING, SDL_EventLoggingChanged, NULL); +#ifndef SDL_JOYSTICK_DISABLED + SDL_DelHintCallback(SDL_HINT_AUTO_UPDATE_JOYSTICKS, SDL_AutoUpdateJoysticksChanged, NULL); +#endif +#ifndef SDL_SENSOR_DISABLED + SDL_DelHintCallback(SDL_HINT_AUTO_UPDATE_SENSORS, SDL_AutoUpdateSensorsChanged, NULL); +#endif +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/events/SDL_events_c.h b/SDL2-2.30.5/src/events/SDL_events_c.h similarity index 92% rename from SDL2-2.0.12/src/events/SDL_events_c.h rename to SDL2-2.30.5/src/events/SDL_events_c.h index 2d9680c..6a9cf4c 100644 --- a/SDL2-2.0.12/src/events/SDL_events_c.h +++ b/SDL2-2.30.5/src/events/SDL_events_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -44,8 +44,9 @@ extern void SDL_StopEventLoop(void); extern void SDL_QuitInterrupt(void); extern int SDL_SendAppEvent(SDL_EventType eventType); -extern int SDL_SendSysWMEvent(SDL_SysWMmsg * message); +extern int SDL_SendSysWMEvent(SDL_SysWMmsg *message); extern int SDL_SendKeymapChangedEvent(void); +extern int SDL_SendLocaleChangedEvent(void); extern int SDL_SendQuit(void); diff --git a/SDL2-2.0.12/src/events/SDL_gesture.c b/SDL2-2.30.5/src/events/SDL_gesture.c similarity index 66% rename from SDL2-2.0.12/src/events/SDL_gesture.c rename to SDL2-2.30.5/src/events/SDL_gesture.c index a8fe166..63362c0 100644 --- a/SDL2-2.0.12/src/events/SDL_gesture.c +++ b/SDL2-2.30.5/src/events/SDL_gesture.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -32,7 +32,7 @@ #include */ -/* TODO: Replace with malloc */ +/* TODO: Replace with SDL_malloc */ #define MAXPATHSIZE 1024 @@ -41,27 +41,31 @@ #define DOLLARNPOINTS 64 #if defined(ENABLE_DOLLAR) -# define DOLLARSIZE 256 -# define PHI 0.618033989 +#define DOLLARSIZE 256 +#define PHI 0.618033989 #endif -typedef struct { - float x,y; +typedef struct +{ + float x, y; } SDL_FloatPoint; -typedef struct { +typedef struct +{ float length; int numPoints; SDL_FloatPoint p[MAXPATHSIZE]; } SDL_DollarPath; -typedef struct { +typedef struct +{ SDL_FloatPoint path[DOLLARNPOINTS]; - unsigned long hash; + Sint64 hash; } SDL_DollarTemplate; -typedef struct { +typedef struct +{ SDL_TouchID id; SDL_FloatPoint centroid; SDL_DollarPath dollarPath; @@ -92,38 +96,40 @@ static void PrintPath(SDL_FloatPoint *path) int SDL_RecordGesture(SDL_TouchID touchId) { int i; - if (touchId < 0) recordAll = SDL_TRUE; + if (touchId < 0) { + recordAll = SDL_TRUE; + } for (i = 0; i < SDL_numGestureTouches; i++) { if ((touchId < 0) || (SDL_gestureTouch[i].id == touchId)) { SDL_gestureTouch[i].recording = SDL_TRUE; - if (touchId >= 0) + if (touchId >= 0) { return 1; + } } } - return (touchId < 0); + return touchId < 0; } -void SDL_GestureQuit() +void SDL_GestureQuit(void) { SDL_free(SDL_gestureTouch); SDL_gestureTouch = NULL; } -static unsigned long SDL_HashDollar(SDL_FloatPoint* points) +static unsigned long SDL_HashDollar(SDL_FloatPoint *points) { unsigned long hash = 5381; int i; for (i = 0; i < DOLLARNPOINTS; i++) { - hash = ((hash<<5) + hash) + (unsigned long)points[i].x; - hash = ((hash<<5) + hash) + (unsigned long)points[i].y; + hash = ((hash << 5) + hash) + (unsigned long)points[i].x; + hash = ((hash << 5) + hash) + (unsigned long)points[i].y; } return hash; } - static int SaveTemplate(SDL_DollarTemplate *templ, SDL_RWops *dst) { - if (dst == NULL) { + if (!dst) { return 0; } @@ -132,7 +138,7 @@ static int SaveTemplate(SDL_DollarTemplate *templ, SDL_RWops *dst) #if SDL_BYTEORDER == SDL_LIL_ENDIAN if (SDL_RWwrite(dst, templ->path, - sizeof(templ->path[0]),DOLLARNPOINTS) != DOLLARNPOINTS) { + sizeof(templ->path[0]), DOLLARNPOINTS) != DOLLARNPOINTS) { return 0; } #else @@ -146,7 +152,7 @@ static int SaveTemplate(SDL_DollarTemplate *templ, SDL_RWops *dst) } if (SDL_RWwrite(dst, copy.path, - sizeof(copy.path[0]),DOLLARNPOINTS) != DOLLARNPOINTS) { + sizeof(copy.path[0]), DOLLARNPOINTS) != DOLLARNPOINTS) { return 0; } } @@ -155,12 +161,11 @@ static int SaveTemplate(SDL_DollarTemplate *templ, SDL_RWops *dst) return 1; } - int SDL_SaveAllDollarTemplates(SDL_RWops *dst) { - int i,j,rtrn = 0; + int i, j, rtrn = 0; for (i = 0; i < SDL_numGestureTouches; i++) { - SDL_GestureTouch* touch = &SDL_gestureTouch[i]; + SDL_GestureTouch *touch = &SDL_gestureTouch[i]; for (j = 0; j < touch->numDollarTemplates; j++) { rtrn += SaveTemplate(&touch->dollarTemplate[j], dst); } @@ -170,9 +175,9 @@ int SDL_SaveAllDollarTemplates(SDL_RWops *dst) int SDL_SaveDollarTemplate(SDL_GestureID gestureId, SDL_RWops *dst) { - int i,j; + int i, j; for (i = 0; i < SDL_numGestureTouches; i++) { - SDL_GestureTouch* touch = &SDL_gestureTouch[i]; + SDL_GestureTouch *touch = &SDL_gestureTouch[i]; for (j = 0; j < touch->numDollarTemplates; j++) { if (touch->dollarTemplate[j].hash == gestureId) { return SaveTemplate(&touch->dollarTemplate[j], dst); @@ -184,9 +189,9 @@ int SDL_SaveDollarTemplate(SDL_GestureID gestureId, SDL_RWops *dst) /* path is an already sampled set of points Returns the index of the gesture on success, or -1 */ -static int SDL_AddDollarGesture_one(SDL_GestureTouch* inTouch, SDL_FloatPoint* path) +static int SDL_AddDollarGesture_one(SDL_GestureTouch *inTouch, SDL_FloatPoint *path) { - SDL_DollarTemplate* dollarTemplate; + SDL_DollarTemplate *dollarTemplate; SDL_DollarTemplate *templ; int index; @@ -194,31 +199,34 @@ static int SDL_AddDollarGesture_one(SDL_GestureTouch* inTouch, SDL_FloatPoint* p dollarTemplate = (SDL_DollarTemplate *)SDL_realloc(inTouch->dollarTemplate, (index + 1) * - sizeof(SDL_DollarTemplate)); + sizeof(SDL_DollarTemplate)); if (!dollarTemplate) { return SDL_OutOfMemory(); } inTouch->dollarTemplate = dollarTemplate; templ = &inTouch->dollarTemplate[index]; - SDL_memcpy(templ->path, path, DOLLARNPOINTS*sizeof(SDL_FloatPoint)); + SDL_memcpy(templ->path, path, DOLLARNPOINTS * sizeof(SDL_FloatPoint)); templ->hash = SDL_HashDollar(templ->path); inTouch->numDollarTemplates++; return index; } -static int SDL_AddDollarGesture(SDL_GestureTouch* inTouch, SDL_FloatPoint* path) +static int SDL_AddDollarGesture(SDL_GestureTouch *inTouch, SDL_FloatPoint *path) { int index = -1; int i = 0; - if (inTouch == NULL) { - if (SDL_numGestureTouches == 0) return SDL_SetError("no gesture touch devices registered"); + if (!inTouch) { + if (SDL_numGestureTouches == 0) { + return SDL_SetError("no gesture touch devices registered"); + } for (i = 0; i < SDL_numGestureTouches; i++) { inTouch = &SDL_gestureTouch[i]; index = SDL_AddDollarGesture_one(inTouch, path); - if (index < 0) + if (index < 0) { return -1; + } } /* Use the index of the last one added. */ return index; @@ -228,16 +236,18 @@ static int SDL_AddDollarGesture(SDL_GestureTouch* inTouch, SDL_FloatPoint* path) int SDL_LoadDollarTemplates(SDL_TouchID touchId, SDL_RWops *src) { - int i,loaded = 0; + int i, loaded = 0; SDL_GestureTouch *touch = NULL; - if (src == NULL) return 0; + if (!src) { + return 0; + } if (touchId >= 0) { for (i = 0; i < SDL_numGestureTouches; i++) { if (SDL_gestureTouch[i].id == touchId) { touch = &SDL_gestureTouch[i]; } } - if (touch == NULL) { + if (!touch) { return SDL_SetError("given touch id not found"); } } @@ -245,7 +255,7 @@ int SDL_LoadDollarTemplates(SDL_TouchID touchId, SDL_RWops *src) while (1) { SDL_DollarTemplate templ; - if (SDL_RWread(src,templ.path,sizeof(templ.path[0]),DOLLARNPOINTS) < DOLLARNPOINTS) { + if (SDL_RWread(src, templ.path, sizeof(templ.path[0]), DOLLARNPOINTS) < DOLLARNPOINTS) { if (loaded == 0) { return SDL_SetError("could not read any dollar gesture from rwops"); } @@ -262,16 +272,16 @@ int SDL_LoadDollarTemplates(SDL_TouchID touchId, SDL_RWops *src) if (touchId >= 0) { /* printf("Adding loaded gesture to 1 touch\n"); */ - if (SDL_AddDollarGesture(touch, templ.path) >= 0) + if (SDL_AddDollarGesture(touch, templ.path) >= 0) { loaded++; - } - else { + } + } else { /* printf("Adding to: %i touches\n",SDL_numGestureTouches); */ for (i = 0; i < SDL_numGestureTouches; i++) { touch = &SDL_gestureTouch[i]; /* printf("Adding loaded gesture to + touches\n"); */ /* TODO: What if this fails? */ - SDL_AddDollarGesture(touch,templ.path); + SDL_AddDollarGesture(touch, templ.path); } loaded++; } @@ -280,9 +290,8 @@ int SDL_LoadDollarTemplates(SDL_TouchID touchId, SDL_RWops *src) return loaded; } - #if defined(ENABLE_DOLLAR) -static float dollarDifference(SDL_FloatPoint* points,SDL_FloatPoint* templ,float ang) +static float dollarDifference(SDL_FloatPoint *points, SDL_FloatPoint *templ, float ang) { /* SDL_FloatPoint p[DOLLARNPOINTS]; */ float dist = 0; @@ -291,14 +300,13 @@ static float dollarDifference(SDL_FloatPoint* points,SDL_FloatPoint* templ,float for (i = 0; i < DOLLARNPOINTS; i++) { p.x = (float)(points[i].x * SDL_cos(ang) - points[i].y * SDL_sin(ang)); p.y = (float)(points[i].x * SDL_sin(ang) + points[i].y * SDL_cos(ang)); - dist += (float)(SDL_sqrt((p.x-templ[i].x)*(p.x-templ[i].x)+ - (p.y-templ[i].y)*(p.y-templ[i].y))); + dist += (float)(SDL_sqrt((p.x - templ[i].x) * (p.x - templ[i].x) + + (p.y - templ[i].y) * (p.y - templ[i].y))); } - return dist/DOLLARNPOINTS; - + return dist / DOLLARNPOINTS; } -static float bestDollarDifference(SDL_FloatPoint* points,SDL_FloatPoint* templ) +static float bestDollarDifference(SDL_FloatPoint *points, SDL_FloatPoint *templ) { /*------------BEGIN DOLLAR BLACKBOX------------------ -TRANSLATED DIRECTLY FROM PSUDEO-CODE AVAILABLE AT- @@ -316,15 +324,14 @@ static float bestDollarDifference(SDL_FloatPoint* points,SDL_FloatPoint* templ) tb = x2; x2 = x1; f2 = f1; - x1 = (float)(PHI*ta + (1-PHI)*tb); - f1 = dollarDifference(points,templ,x1); - } - else { + x1 = (float)(PHI * ta + (1 - PHI) * tb); + f1 = dollarDifference(points, templ, x1); + } else { ta = x1; x1 = x2; f1 = f2; - x2 = (float)((1-PHI)*ta + PHI*tb); - f2 = dollarDifference(points,templ,x2); + x2 = (float)((1 - PHI) * ta + PHI * tb); + f2 = dollarDifference(points, templ, x2); } } /* @@ -333,47 +340,48 @@ static float bestDollarDifference(SDL_FloatPoint* points,SDL_FloatPoint* templ) else if (f1 > f2) printf("Min angle (x2): %f\n",x2); */ - return SDL_min(f1,f2); + return SDL_min(f1, f2); } /* DollarPath contains raw points, plus (possibly) the calculated length */ -static int dollarNormalize(const SDL_DollarPath *path,SDL_FloatPoint *points, SDL_bool is_recording) +static int dollarNormalize(const SDL_DollarPath *path, SDL_FloatPoint *points, SDL_bool is_recording) { int i; float interval; float dist; int numPoints = 0; SDL_FloatPoint centroid; - float xmin,xmax,ymin,ymax; + float xmin, xmax, ymin, ymax; float ang; - float w,h; + float w, h; float length = path->length; /* Calculate length if it hasn't already been done */ if (length <= 0) { - for (i=1;i < path->numPoints; i++) { - float dx = path->p[i ].x - path->p[i-1].x; - float dy = path->p[i ].y - path->p[i-1].y; - length += (float)(SDL_sqrt(dx*dx+dy*dy)); + for (i = 1; i < path->numPoints; i++) { + float dx = path->p[i].x - path->p[i - 1].x; + float dy = path->p[i].y - path->p[i - 1].y; + length += (float)(SDL_sqrt(dx * dx + dy * dy)); } } /* Resample */ - interval = length/(DOLLARNPOINTS - 1); + interval = length / (DOLLARNPOINTS - 1); dist = interval; - centroid.x = 0;centroid.y = 0; + centroid.x = 0; + centroid.y = 0; /* printf("(%f,%f)\n",path->p[path->numPoints-1].x,path->p[path->numPoints-1].y); */ for (i = 1; i < path->numPoints; i++) { - float d = (float)(SDL_sqrt((path->p[i-1].x-path->p[i].x)*(path->p[i-1].x-path->p[i].x)+ - (path->p[i-1].y-path->p[i].y)*(path->p[i-1].y-path->p[i].y))); + float d = (float)(SDL_sqrt((path->p[i - 1].x - path->p[i].x) * (path->p[i - 1].x - path->p[i].x) + + (path->p[i - 1].y - path->p[i].y) * (path->p[i - 1].y - path->p[i].y))); /* printf("d = %f dist = %f/%f\n",d,dist,interval); */ while (dist + d > interval) { - points[numPoints].x = path->p[i-1].x + - ((interval-dist)/d)*(path->p[i].x-path->p[i-1].x); - points[numPoints].y = path->p[i-1].y + - ((interval-dist)/d)*(path->p[i].y-path->p[i-1].y); + points[numPoints].x = path->p[i - 1].x + + ((interval - dist) / d) * (path->p[i].x - path->p[i - 1].x); + points[numPoints].y = path->p[i - 1].y + + ((interval - dist) / d) * (path->p[i].y - path->p[i - 1].y); centroid.x += points[numPoints].x; centroid.y += points[numPoints].y; numPoints++; @@ -382,14 +390,14 @@ static int dollarNormalize(const SDL_DollarPath *path,SDL_FloatPoint *points, SD } dist += d; } - if (numPoints < DOLLARNPOINTS-1) { + if (numPoints < DOLLARNPOINTS - 1) { if (is_recording) { SDL_SetError("ERROR: NumPoints = %i", numPoints); } return 0; } /* copy the last point */ - points[DOLLARNPOINTS-1] = path->p[path->numPoints-1]; + points[DOLLARNPOINTS - 1] = path->p[path->numPoints - 1]; numPoints = DOLLARNPOINTS; centroid.x /= numPoints; @@ -405,33 +413,40 @@ static int dollarNormalize(const SDL_DollarPath *path,SDL_FloatPoint *points, SD ang = (float)(SDL_atan2(centroid.y - points[0].y, centroid.x - points[0].x)); - for (i = 0; i xmax) xmax = points[i].x; - if (points[i].y < ymin) ymin = points[i].y; - if (points[i].y > ymax) ymax = points[i].y; + if (points[i].x < xmin) { + xmin = points[i].x; + } + if (points[i].x > xmax) { + xmax = points[i].x; + } + if (points[i].y < ymin) { + ymin = points[i].y; + } + if (points[i].y > ymax) { + ymax = points[i].y; + } } /* Scale points to DOLLARSIZE, and translate to the origin */ - w = xmax-xmin; - h = ymax-ymin; + w = xmax - xmin; + h = ymax - ymin; - for (i=0; inumDollarTemplates; i++) { - float diff = bestDollarDifference(points,touch->dollarTemplate[i].path); - if (diff < bestDiff) {bestDiff = diff; *bestTempl = i;} + float diff = bestDollarDifference(points, touch->dollarTemplate[i].path); + if (diff < bestDiff) { + bestDiff = diff; + *bestTempl = i; + } } return bestDiff; } @@ -455,7 +473,7 @@ int SDL_GestureAddTouch(SDL_TouchID touchId) { SDL_GestureTouch *gestureTouch = (SDL_GestureTouch *)SDL_realloc(SDL_gestureTouch, (SDL_numGestureTouches + 1) * - sizeof(SDL_GestureTouch)); + sizeof(SDL_GestureTouch)); if (!gestureTouch) { return SDL_OutOfMemory(); @@ -487,22 +505,25 @@ int SDL_GestureDelTouch(SDL_TouchID touchId) SDL_zero(SDL_gestureTouch[i]); SDL_numGestureTouches--; - SDL_memcpy(&SDL_gestureTouch[i], &SDL_gestureTouch[SDL_numGestureTouches], sizeof(SDL_gestureTouch[i])); + if (i != SDL_numGestureTouches) { + SDL_copyp(&SDL_gestureTouch[i], &SDL_gestureTouch[SDL_numGestureTouches]); + } return 0; } -static SDL_GestureTouch * SDL_GetGestureTouch(SDL_TouchID id) +static SDL_GestureTouch *SDL_GetGestureTouch(SDL_TouchID id) { int i; for (i = 0; i < SDL_numGestureTouches; i++) { /* printf("%i ?= %i\n",SDL_gestureTouch[i].id,id); */ - if (SDL_gestureTouch[i].id == id) + if (SDL_gestureTouch[i].id == id) { return &SDL_gestureTouch[i]; + } } return NULL; } -static void SDL_SendGestureMulti(SDL_GestureTouch* touch,float dTheta,float dDist) +static void SDL_SendGestureMulti(SDL_GestureTouch *touch, float dTheta, float dDist) { if (SDL_GetEventState(SDL_MULTIGESTURE) == SDL_ENABLE) { SDL_Event event; @@ -518,8 +539,8 @@ static void SDL_SendGestureMulti(SDL_GestureTouch* touch,float dTheta,float dDis } #if defined(ENABLE_DOLLAR) -static void SDL_SendGestureDollar(SDL_GestureTouch* touch, - SDL_GestureID gestureId,float error) +static void SDL_SendGestureDollar(SDL_GestureTouch *touch, + SDL_GestureID gestureId, float error) { if (SDL_GetEventState(SDL_DOLLARGESTURE) == SDL_ENABLE) { SDL_Event event; @@ -535,7 +556,7 @@ static void SDL_SendGestureDollar(SDL_GestureTouch* touch, } } -static void SDL_SendDollarRecord(SDL_GestureTouch* touch,SDL_GestureID gestureId) +static void SDL_SendDollarRecord(SDL_GestureTouch *touch, SDL_GestureID gestureId) { if (SDL_GetEventState(SDL_DOLLARRECORD) == SDL_ENABLE) { SDL_Event event; @@ -547,10 +568,9 @@ static void SDL_SendDollarRecord(SDL_GestureTouch* touch,SDL_GestureID gestureId } #endif - -void SDL_GestureProcessEvent(SDL_Event* event) +void SDL_GestureProcessEvent(SDL_Event *event) { - float x,y; + float x, y; #if defined(ENABLE_DOLLAR) int index; int i; @@ -566,10 +586,12 @@ void SDL_GestureProcessEvent(SDL_Event* event) if (event->type == SDL_FINGERMOTION || event->type == SDL_FINGERDOWN || event->type == SDL_FINGERUP) { - SDL_GestureTouch* inTouch = SDL_GetGestureTouch(event->tfinger.touchId); + SDL_GestureTouch *inTouch = SDL_GetGestureTouch(event->tfinger.touchId); /* Shouldn't be possible */ - if (inTouch == NULL) return; + if (!inTouch) { + return; + } x = event->tfinger.x; y = event->tfinger.y; @@ -588,55 +610,54 @@ void SDL_GestureProcessEvent(SDL_Event* event) dollarNormalize(&inTouch->dollarPath, path, SDL_TRUE); /* PrintPath(path); */ if (recordAll) { - index = SDL_AddDollarGesture(NULL,path); - for (i = 0; i < SDL_numGestureTouches; i++) + index = SDL_AddDollarGesture(NULL, path); + for (i = 0; i < SDL_numGestureTouches; i++) { SDL_gestureTouch[i].recording = SDL_FALSE; - } - else { - index = SDL_AddDollarGesture(inTouch,path); + } + } else { + index = SDL_AddDollarGesture(inTouch, path); } if (index >= 0) { - SDL_SendDollarRecord(inTouch,inTouch->dollarTemplate[index].hash); + SDL_SendDollarRecord(inTouch, inTouch->dollarTemplate[index].hash); + } else { + SDL_SendDollarRecord(inTouch, -1); } - else { - SDL_SendDollarRecord(inTouch,-1); - } - } - else { + } else { int bestTempl; float error; error = dollarRecognize(&inTouch->dollarPath, - &bestTempl,inTouch); - if (bestTempl >= 0){ + &bestTempl, inTouch); + if (bestTempl >= 0) { /* Send Event */ - unsigned long gestureId = inTouch->dollarTemplate[bestTempl].hash; - SDL_SendGestureDollar(inTouch,gestureId,error); + Sint64 gestureId = inTouch->dollarTemplate[bestTempl].hash; + SDL_SendGestureDollar(inTouch, gestureId, error); /* printf ("%s\n",);("Dollar error: %f\n",error); */ } } #endif /* inTouch->gestureLast[j] = inTouch->gestureLast[inTouch->numDownFingers]; */ if (inTouch->numDownFingers > 0) { - inTouch->centroid.x = (inTouch->centroid.x*(inTouch->numDownFingers+1)- - x)/inTouch->numDownFingers; - inTouch->centroid.y = (inTouch->centroid.y*(inTouch->numDownFingers+1)- - y)/inTouch->numDownFingers; + inTouch->centroid.x = (inTouch->centroid.x * (inTouch->numDownFingers + 1) - + x) / + inTouch->numDownFingers; + inTouch->centroid.y = (inTouch->centroid.y * (inTouch->numDownFingers + 1) - + y) / + inTouch->numDownFingers; } - } - else if (event->type == SDL_FINGERMOTION) { + } else if (event->type == SDL_FINGERMOTION) { float dx = event->tfinger.dx; float dy = event->tfinger.dy; #if defined(ENABLE_DOLLAR) - SDL_DollarPath* path = &inTouch->dollarPath; + SDL_DollarPath *path = &inTouch->dollarPath; if (path->numPoints < MAXPATHSIZE) { path->p[path->numPoints].x = inTouch->centroid.x; path->p[path->numPoints].y = inTouch->centroid.y; pathDx = - (path->p[path->numPoints].x-path->p[path->numPoints-1].x); + (path->p[path->numPoints].x - path->p[path->numPoints - 1].x); pathDy = - (path->p[path->numPoints].y-path->p[path->numPoints-1].y); - path->length += (float)SDL_sqrt(pathDx*pathDx + pathDy*pathDy); + (path->p[path->numPoints].y - path->p[path->numPoints - 1].y); + path->length += (float)SDL_sqrt(pathDx * pathDx + pathDy * pathDy); path->numPoints++; } #endif @@ -644,32 +665,36 @@ void SDL_GestureProcessEvent(SDL_Event* event) lastP.y = y - dy; lastCentroid = inTouch->centroid; - inTouch->centroid.x += dx/inTouch->numDownFingers; - inTouch->centroid.y += dy/inTouch->numDownFingers; + inTouch->centroid.x += dx / inTouch->numDownFingers; + inTouch->centroid.y += dy / inTouch->numDownFingers; /* printf("Centrid : (%f,%f)\n",inTouch->centroid.x,inTouch->centroid.y); */ if (inTouch->numDownFingers > 1) { SDL_FloatPoint lv; /* Vector from centroid to last x,y position */ - SDL_FloatPoint v; /* Vector from centroid to current x,y position */ + SDL_FloatPoint v; /* Vector from centroid to current x,y position */ /* lv = inTouch->gestureLast[j].cv; */ lv.x = lastP.x - lastCentroid.x; lv.y = lastP.y - lastCentroid.y; - lDist = (float)SDL_sqrt(lv.x*lv.x + lv.y*lv.y); + lDist = (float)SDL_sqrt(lv.x * lv.x + lv.y * lv.y); /* printf("lDist = %f\n",lDist); */ v.x = x - inTouch->centroid.x; v.y = y - inTouch->centroid.y; /* inTouch->gestureLast[j].cv = v; */ - Dist = (float)SDL_sqrt(v.x*v.x+v.y*v.y); + Dist = (float)SDL_sqrt(v.x * v.x + v.y * v.y); /* SDL_cos(dTheta) = (v . lv)/(|v| * |lv|) */ /* Normalize Vectors to simplify angle calculation */ - lv.x/=lDist; - lv.y/=lDist; - v.x/=Dist; - v.y/=Dist; - dtheta = (float)SDL_atan2(lv.x*v.y - lv.y*v.x,lv.x*v.x + lv.y*v.y); + lv.x /= lDist; + lv.y /= lDist; + v.x /= Dist; + v.y /= Dist; + dtheta = (float)SDL_atan2(lv.x * v.y - lv.y * v.x, lv.x * v.x + lv.y * v.y); dDist = (Dist - lDist); - if (lDist == 0) {dDist = 0;dtheta = 0;} /* To avoid impossible values */ + if (lDist == 0) { + /* To avoid impossible values */ + dDist = 0; + dtheta = 0; + } /* inTouch->gestureLast[j].dDist = dDist; inTouch->gestureLast[j].dtheta = dtheta; @@ -681,9 +706,8 @@ void SDL_GestureProcessEvent(SDL_Event* event) knob.ang += dtheta; printf("thetaSum = %f, distSum = %f\n",gdtheta,gdDist); printf("id: %i dTheta = %f, dDist = %f\n",j,dtheta,dDist); */ - SDL_SendGestureMulti(inTouch,dtheta,dDist); - } - else { + SDL_SendGestureMulti(inTouch, dtheta, dDist); + } else { /* inTouch->gestureLast[j].dDist = 0; inTouch->gestureLast[j].dtheta = 0; inTouch->gestureLast[j].cv.x = 0; @@ -693,14 +717,15 @@ void SDL_GestureProcessEvent(SDL_Event* event) inTouch->gestureLast[j].f.p.y = y; break; pressure? */ - } - else if (event->type == SDL_FINGERDOWN) { + } else if (event->type == SDL_FINGERDOWN) { inTouch->numDownFingers++; - inTouch->centroid.x = (inTouch->centroid.x*(inTouch->numDownFingers - 1)+ - x)/inTouch->numDownFingers; - inTouch->centroid.y = (inTouch->centroid.y*(inTouch->numDownFingers - 1)+ - y)/inTouch->numDownFingers; + inTouch->centroid.x = (inTouch->centroid.x * (inTouch->numDownFingers - 1) + + x) / + inTouch->numDownFingers; + inTouch->centroid.y = (inTouch->centroid.y * (inTouch->numDownFingers - 1) + + y) / + inTouch->numDownFingers; /* printf("Finger Down: (%f,%f). Centroid: (%f,%f\n",x,y, inTouch->centroid.x,inTouch->centroid.y); */ diff --git a/SDL2-2.0.12/src/events/SDL_gesture_c.h b/SDL2-2.30.5/src/events/SDL_gesture_c.h similarity index 91% rename from SDL2-2.0.12/src/events/SDL_gesture_c.h rename to SDL2-2.30.5/src/events/SDL_gesture_c.h index 13a1020..04320d5 100644 --- a/SDL2-2.0.12/src/events/SDL_gesture_c.h +++ b/SDL2-2.30.5/src/events/SDL_gesture_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,7 +26,7 @@ extern int SDL_GestureAddTouch(SDL_TouchID touchId); extern int SDL_GestureDelTouch(SDL_TouchID touchId); -extern void SDL_GestureProcessEvent(SDL_Event* event); +extern void SDL_GestureProcessEvent(SDL_Event *event); extern void SDL_GestureQuit(void); diff --git a/SDL2-2.30.5/src/events/SDL_keyboard.c b/SDL2-2.30.5/src/events/SDL_keyboard.c new file mode 100644 index 0000000..58a95c9 --- /dev/null +++ b/SDL2-2.30.5/src/events/SDL_keyboard.c @@ -0,0 +1,1303 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +/* General keyboard handling code for SDL */ + +#include "SDL_hints.h" +#include "SDL_timer.h" +#include "SDL_events.h" +#include "SDL_events_c.h" +#include "../video/SDL_sysvideo.h" +#include "scancodes_ascii.h" + +/* #define DEBUG_KEYBOARD */ + +/* Global keyboard information */ + +#define KEYBOARD_HARDWARE 0x01 +#define KEYBOARD_VIRTUAL 0x02 +#define KEYBOARD_AUTORELEASE 0x04 + +typedef struct SDL_Keyboard SDL_Keyboard; + +struct SDL_Keyboard +{ + /* Data common to all keyboards */ + SDL_Window *focus; + Uint16 modstate; + Uint8 keysource[SDL_NUM_SCANCODES]; + Uint8 keystate[SDL_NUM_SCANCODES]; + SDL_Keycode keymap[SDL_NUM_SCANCODES]; + SDL_bool autorelease_pending; + Uint32 hardware_timestamp; +}; + +static SDL_Keyboard SDL_keyboard; + +static const SDL_Keycode SDL_default_keymap[SDL_NUM_SCANCODES] = { + /* 0 */ 0, + /* 1 */ 0, + /* 2 */ 0, + /* 3 */ 0, + /* 4 */ 'a', + /* 5 */ 'b', + /* 6 */ 'c', + /* 7 */ 'd', + /* 8 */ 'e', + /* 9 */ 'f', + /* 10 */ 'g', + /* 11 */ 'h', + /* 12 */ 'i', + /* 13 */ 'j', + /* 14 */ 'k', + /* 15 */ 'l', + /* 16 */ 'm', + /* 17 */ 'n', + /* 18 */ 'o', + /* 19 */ 'p', + /* 20 */ 'q', + /* 21 */ 'r', + /* 22 */ 's', + /* 23 */ 't', + /* 24 */ 'u', + /* 25 */ 'v', + /* 26 */ 'w', + /* 27 */ 'x', + /* 28 */ 'y', + /* 29 */ 'z', + /* 30 */ '1', + /* 31 */ '2', + /* 32 */ '3', + /* 33 */ '4', + /* 34 */ '5', + /* 35 */ '6', + /* 36 */ '7', + /* 37 */ '8', + /* 38 */ '9', + /* 39 */ '0', + /* 40 */ SDLK_RETURN, + /* 41 */ SDLK_ESCAPE, + /* 42 */ SDLK_BACKSPACE, + /* 43 */ SDLK_TAB, + /* 44 */ SDLK_SPACE, + /* 45 */ '-', + /* 46 */ '=', + /* 47 */ '[', + /* 48 */ ']', + /* 49 */ '\\', + /* 50 */ '#', + /* 51 */ ';', + /* 52 */ '\'', + /* 53 */ '`', + /* 54 */ ',', + /* 55 */ '.', + /* 56 */ '/', + /* 57 */ SDLK_CAPSLOCK, + /* 58 */ SDLK_F1, + /* 59 */ SDLK_F2, + /* 60 */ SDLK_F3, + /* 61 */ SDLK_F4, + /* 62 */ SDLK_F5, + /* 63 */ SDLK_F6, + /* 64 */ SDLK_F7, + /* 65 */ SDLK_F8, + /* 66 */ SDLK_F9, + /* 67 */ SDLK_F10, + /* 68 */ SDLK_F11, + /* 69 */ SDLK_F12, + /* 70 */ SDLK_PRINTSCREEN, + /* 71 */ SDLK_SCROLLLOCK, + /* 72 */ SDLK_PAUSE, + /* 73 */ SDLK_INSERT, + /* 74 */ SDLK_HOME, + /* 75 */ SDLK_PAGEUP, + /* 76 */ SDLK_DELETE, + /* 77 */ SDLK_END, + /* 78 */ SDLK_PAGEDOWN, + /* 79 */ SDLK_RIGHT, + /* 80 */ SDLK_LEFT, + /* 81 */ SDLK_DOWN, + /* 82 */ SDLK_UP, + /* 83 */ SDLK_NUMLOCKCLEAR, + /* 84 */ SDLK_KP_DIVIDE, + /* 85 */ SDLK_KP_MULTIPLY, + /* 86 */ SDLK_KP_MINUS, + /* 87 */ SDLK_KP_PLUS, + /* 88 */ SDLK_KP_ENTER, + /* 89 */ SDLK_KP_1, + /* 90 */ SDLK_KP_2, + /* 91 */ SDLK_KP_3, + /* 92 */ SDLK_KP_4, + /* 93 */ SDLK_KP_5, + /* 94 */ SDLK_KP_6, + /* 95 */ SDLK_KP_7, + /* 96 */ SDLK_KP_8, + /* 97 */ SDLK_KP_9, + /* 98 */ SDLK_KP_0, + /* 99 */ SDLK_KP_PERIOD, + /* 100 */ 0, + /* 101 */ SDLK_APPLICATION, + /* 102 */ SDLK_POWER, + /* 103 */ SDLK_KP_EQUALS, + /* 104 */ SDLK_F13, + /* 105 */ SDLK_F14, + /* 106 */ SDLK_F15, + /* 107 */ SDLK_F16, + /* 108 */ SDLK_F17, + /* 109 */ SDLK_F18, + /* 110 */ SDLK_F19, + /* 111 */ SDLK_F20, + /* 112 */ SDLK_F21, + /* 113 */ SDLK_F22, + /* 114 */ SDLK_F23, + /* 115 */ SDLK_F24, + /* 116 */ SDLK_EXECUTE, + /* 117 */ SDLK_HELP, + /* 118 */ SDLK_MENU, + /* 119 */ SDLK_SELECT, + /* 120 */ SDLK_STOP, + /* 121 */ SDLK_AGAIN, + /* 122 */ SDLK_UNDO, + /* 123 */ SDLK_CUT, + /* 124 */ SDLK_COPY, + /* 125 */ SDLK_PASTE, + /* 126 */ SDLK_FIND, + /* 127 */ SDLK_MUTE, + /* 128 */ SDLK_VOLUMEUP, + /* 129 */ SDLK_VOLUMEDOWN, + /* 130 */ 0, + /* 131 */ 0, + /* 132 */ 0, + /* 133 */ SDLK_KP_COMMA, + /* 134 */ SDLK_KP_EQUALSAS400, + /* 135 */ 0, + /* 136 */ 0, + /* 137 */ 0, + /* 138 */ 0, + /* 139 */ 0, + /* 140 */ 0, + /* 141 */ 0, + /* 142 */ 0, + /* 143 */ 0, + /* 144 */ 0, + /* 145 */ 0, + /* 146 */ 0, + /* 147 */ 0, + /* 148 */ 0, + /* 149 */ 0, + /* 150 */ 0, + /* 151 */ 0, + /* 152 */ 0, + /* 153 */ SDLK_ALTERASE, + /* 154 */ SDLK_SYSREQ, + /* 155 */ SDLK_CANCEL, + /* 156 */ SDLK_CLEAR, + /* 157 */ SDLK_PRIOR, + /* 158 */ SDLK_RETURN2, + /* 159 */ SDLK_SEPARATOR, + /* 160 */ SDLK_OUT, + /* 161 */ SDLK_OPER, + /* 162 */ SDLK_CLEARAGAIN, + /* 163 */ SDLK_CRSEL, + /* 164 */ SDLK_EXSEL, + /* 165 */ 0, + /* 166 */ 0, + /* 167 */ 0, + /* 168 */ 0, + /* 169 */ 0, + /* 170 */ 0, + /* 171 */ 0, + /* 172 */ 0, + /* 173 */ 0, + /* 174 */ 0, + /* 175 */ 0, + /* 176 */ SDLK_KP_00, + /* 177 */ SDLK_KP_000, + /* 178 */ SDLK_THOUSANDSSEPARATOR, + /* 179 */ SDLK_DECIMALSEPARATOR, + /* 180 */ SDLK_CURRENCYUNIT, + /* 181 */ SDLK_CURRENCYSUBUNIT, + /* 182 */ SDLK_KP_LEFTPAREN, + /* 183 */ SDLK_KP_RIGHTPAREN, + /* 184 */ SDLK_KP_LEFTBRACE, + /* 185 */ SDLK_KP_RIGHTBRACE, + /* 186 */ SDLK_KP_TAB, + /* 187 */ SDLK_KP_BACKSPACE, + /* 188 */ SDLK_KP_A, + /* 189 */ SDLK_KP_B, + /* 190 */ SDLK_KP_C, + /* 191 */ SDLK_KP_D, + /* 192 */ SDLK_KP_E, + /* 193 */ SDLK_KP_F, + /* 194 */ SDLK_KP_XOR, + /* 195 */ SDLK_KP_POWER, + /* 196 */ SDLK_KP_PERCENT, + /* 197 */ SDLK_KP_LESS, + /* 198 */ SDLK_KP_GREATER, + /* 199 */ SDLK_KP_AMPERSAND, + /* 200 */ SDLK_KP_DBLAMPERSAND, + /* 201 */ SDLK_KP_VERTICALBAR, + /* 202 */ SDLK_KP_DBLVERTICALBAR, + /* 203 */ SDLK_KP_COLON, + /* 204 */ SDLK_KP_HASH, + /* 205 */ SDLK_KP_SPACE, + /* 206 */ SDLK_KP_AT, + /* 207 */ SDLK_KP_EXCLAM, + /* 208 */ SDLK_KP_MEMSTORE, + /* 209 */ SDLK_KP_MEMRECALL, + /* 210 */ SDLK_KP_MEMCLEAR, + /* 211 */ SDLK_KP_MEMADD, + /* 212 */ SDLK_KP_MEMSUBTRACT, + /* 213 */ SDLK_KP_MEMMULTIPLY, + /* 214 */ SDLK_KP_MEMDIVIDE, + /* 215 */ SDLK_KP_PLUSMINUS, + /* 216 */ SDLK_KP_CLEAR, + /* 217 */ SDLK_KP_CLEARENTRY, + /* 218 */ SDLK_KP_BINARY, + /* 219 */ SDLK_KP_OCTAL, + /* 220 */ SDLK_KP_DECIMAL, + /* 221 */ SDLK_KP_HEXADECIMAL, + /* 222 */ 0, + /* 223 */ 0, + /* 224 */ SDLK_LCTRL, + /* 225 */ SDLK_LSHIFT, + /* 226 */ SDLK_LALT, + /* 227 */ SDLK_LGUI, + /* 228 */ SDLK_RCTRL, + /* 229 */ SDLK_RSHIFT, + /* 230 */ SDLK_RALT, + /* 231 */ SDLK_RGUI, + /* 232 */ 0, + /* 233 */ 0, + /* 234 */ 0, + /* 235 */ 0, + /* 236 */ 0, + /* 237 */ 0, + /* 238 */ 0, + /* 239 */ 0, + /* 240 */ 0, + /* 241 */ 0, + /* 242 */ 0, + /* 243 */ 0, + /* 244 */ 0, + /* 245 */ 0, + /* 246 */ 0, + /* 247 */ 0, + /* 248 */ 0, + /* 249 */ 0, + /* 250 */ 0, + /* 251 */ 0, + /* 252 */ 0, + /* 253 */ 0, + /* 254 */ 0, + /* 255 */ 0, + /* 256 */ 0, + /* 257 */ SDLK_MODE, + /* 258 */ SDLK_AUDIONEXT, + /* 259 */ SDLK_AUDIOPREV, + /* 260 */ SDLK_AUDIOSTOP, + /* 261 */ SDLK_AUDIOPLAY, + /* 262 */ SDLK_AUDIOMUTE, + /* 263 */ SDLK_MEDIASELECT, + /* 264 */ SDLK_WWW, + /* 265 */ SDLK_MAIL, + /* 266 */ SDLK_CALCULATOR, + /* 267 */ SDLK_COMPUTER, + /* 268 */ SDLK_AC_SEARCH, + /* 269 */ SDLK_AC_HOME, + /* 270 */ SDLK_AC_BACK, + /* 271 */ SDLK_AC_FORWARD, + /* 272 */ SDLK_AC_STOP, + /* 273 */ SDLK_AC_REFRESH, + /* 274 */ SDLK_AC_BOOKMARKS, + /* 275 */ SDLK_BRIGHTNESSDOWN, + /* 276 */ SDLK_BRIGHTNESSUP, + /* 277 */ SDLK_DISPLAYSWITCH, + /* 278 */ SDLK_KBDILLUMTOGGLE, + /* 279 */ SDLK_KBDILLUMDOWN, + /* 280 */ SDLK_KBDILLUMUP, + /* 281 */ SDLK_EJECT, + /* 282 */ SDLK_SLEEP, + /* 283 */ SDLK_APP1, + /* 284 */ SDLK_APP2, + /* 285 */ SDLK_AUDIOREWIND, + /* 286 */ SDLK_AUDIOFASTFORWARD, + /* 287 */ SDLK_SOFTLEFT, + /* 288 */ SDLK_SOFTRIGHT, + /* 289 */ SDLK_CALL, + /* 290 */ SDLK_ENDCALL, +}; + +static const char *SDL_scancode_names[SDL_NUM_SCANCODES] = { + /* 0 */ NULL, + /* 1 */ NULL, + /* 2 */ NULL, + /* 3 */ NULL, + /* 4 */ "A", + /* 5 */ "B", + /* 6 */ "C", + /* 7 */ "D", + /* 8 */ "E", + /* 9 */ "F", + /* 10 */ "G", + /* 11 */ "H", + /* 12 */ "I", + /* 13 */ "J", + /* 14 */ "K", + /* 15 */ "L", + /* 16 */ "M", + /* 17 */ "N", + /* 18 */ "O", + /* 19 */ "P", + /* 20 */ "Q", + /* 21 */ "R", + /* 22 */ "S", + /* 23 */ "T", + /* 24 */ "U", + /* 25 */ "V", + /* 26 */ "W", + /* 27 */ "X", + /* 28 */ "Y", + /* 29 */ "Z", + /* 30 */ "1", + /* 31 */ "2", + /* 32 */ "3", + /* 33 */ "4", + /* 34 */ "5", + /* 35 */ "6", + /* 36 */ "7", + /* 37 */ "8", + /* 38 */ "9", + /* 39 */ "0", + /* 40 */ "Return", + /* 41 */ "Escape", + /* 42 */ "Backspace", + /* 43 */ "Tab", + /* 44 */ "Space", + /* 45 */ "-", + /* 46 */ "=", + /* 47 */ "[", + /* 48 */ "]", + /* 49 */ "\\", + /* 50 */ "#", + /* 51 */ ";", + /* 52 */ "'", + /* 53 */ "`", + /* 54 */ ",", + /* 55 */ ".", + /* 56 */ "/", + /* 57 */ "CapsLock", + /* 58 */ "F1", + /* 59 */ "F2", + /* 60 */ "F3", + /* 61 */ "F4", + /* 62 */ "F5", + /* 63 */ "F6", + /* 64 */ "F7", + /* 65 */ "F8", + /* 66 */ "F9", + /* 67 */ "F10", + /* 68 */ "F11", + /* 69 */ "F12", + /* 70 */ "PrintScreen", + /* 71 */ "ScrollLock", + /* 72 */ "Pause", + /* 73 */ "Insert", + /* 74 */ "Home", + /* 75 */ "PageUp", + /* 76 */ "Delete", + /* 77 */ "End", + /* 78 */ "PageDown", + /* 79 */ "Right", + /* 80 */ "Left", + /* 81 */ "Down", + /* 82 */ "Up", + /* 83 */ "Numlock", + /* 84 */ "Keypad /", + /* 85 */ "Keypad *", + /* 86 */ "Keypad -", + /* 87 */ "Keypad +", + /* 88 */ "Keypad Enter", + /* 89 */ "Keypad 1", + /* 90 */ "Keypad 2", + /* 91 */ "Keypad 3", + /* 92 */ "Keypad 4", + /* 93 */ "Keypad 5", + /* 94 */ "Keypad 6", + /* 95 */ "Keypad 7", + /* 96 */ "Keypad 8", + /* 97 */ "Keypad 9", + /* 98 */ "Keypad 0", + /* 99 */ "Keypad .", + /* 100 */ NULL, + /* 101 */ "Application", + /* 102 */ "Power", + /* 103 */ "Keypad =", + /* 104 */ "F13", + /* 105 */ "F14", + /* 106 */ "F15", + /* 107 */ "F16", + /* 108 */ "F17", + /* 109 */ "F18", + /* 110 */ "F19", + /* 111 */ "F20", + /* 112 */ "F21", + /* 113 */ "F22", + /* 114 */ "F23", + /* 115 */ "F24", + /* 116 */ "Execute", + /* 117 */ "Help", + /* 118 */ "Menu", + /* 119 */ "Select", + /* 120 */ "Stop", + /* 121 */ "Again", + /* 122 */ "Undo", + /* 123 */ "Cut", + /* 124 */ "Copy", + /* 125 */ "Paste", + /* 126 */ "Find", + /* 127 */ "Mute", + /* 128 */ "VolumeUp", + /* 129 */ "VolumeDown", + /* 130 */ NULL, + /* 131 */ NULL, + /* 132 */ NULL, + /* 133 */ "Keypad ,", + /* 134 */ "Keypad = (AS400)", + /* 135 */ NULL, + /* 136 */ NULL, + /* 137 */ NULL, + /* 138 */ NULL, + /* 139 */ NULL, + /* 140 */ NULL, + /* 141 */ NULL, + /* 142 */ NULL, + /* 143 */ NULL, + /* 144 */ NULL, + /* 145 */ NULL, + /* 146 */ NULL, + /* 147 */ NULL, + /* 148 */ NULL, + /* 149 */ NULL, + /* 150 */ NULL, + /* 151 */ NULL, + /* 152 */ NULL, + /* 153 */ "AltErase", + /* 154 */ "SysReq", + /* 155 */ "Cancel", + /* 156 */ "Clear", + /* 157 */ "Prior", + /* 158 */ "Return", + /* 159 */ "Separator", + /* 160 */ "Out", + /* 161 */ "Oper", + /* 162 */ "Clear / Again", + /* 163 */ "CrSel", + /* 164 */ "ExSel", + /* 165 */ NULL, + /* 166 */ NULL, + /* 167 */ NULL, + /* 168 */ NULL, + /* 169 */ NULL, + /* 170 */ NULL, + /* 171 */ NULL, + /* 172 */ NULL, + /* 173 */ NULL, + /* 174 */ NULL, + /* 175 */ NULL, + /* 176 */ "Keypad 00", + /* 177 */ "Keypad 000", + /* 178 */ "ThousandsSeparator", + /* 179 */ "DecimalSeparator", + /* 180 */ "CurrencyUnit", + /* 181 */ "CurrencySubUnit", + /* 182 */ "Keypad (", + /* 183 */ "Keypad )", + /* 184 */ "Keypad {", + /* 185 */ "Keypad }", + /* 186 */ "Keypad Tab", + /* 187 */ "Keypad Backspace", + /* 188 */ "Keypad A", + /* 189 */ "Keypad B", + /* 190 */ "Keypad C", + /* 191 */ "Keypad D", + /* 192 */ "Keypad E", + /* 193 */ "Keypad F", + /* 194 */ "Keypad XOR", + /* 195 */ "Keypad ^", + /* 196 */ "Keypad %", + /* 197 */ "Keypad <", + /* 198 */ "Keypad >", + /* 199 */ "Keypad &", + /* 200 */ "Keypad &&", + /* 201 */ "Keypad |", + /* 202 */ "Keypad ||", + /* 203 */ "Keypad :", + /* 204 */ "Keypad #", + /* 205 */ "Keypad Space", + /* 206 */ "Keypad @", + /* 207 */ "Keypad !", + /* 208 */ "Keypad MemStore", + /* 209 */ "Keypad MemRecall", + /* 210 */ "Keypad MemClear", + /* 211 */ "Keypad MemAdd", + /* 212 */ "Keypad MemSubtract", + /* 213 */ "Keypad MemMultiply", + /* 214 */ "Keypad MemDivide", + /* 215 */ "Keypad +/-", + /* 216 */ "Keypad Clear", + /* 217 */ "Keypad ClearEntry", + /* 218 */ "Keypad Binary", + /* 219 */ "Keypad Octal", + /* 220 */ "Keypad Decimal", + /* 221 */ "Keypad Hexadecimal", + /* 222 */ NULL, + /* 223 */ NULL, + /* 224 */ "Left Ctrl", + /* 225 */ "Left Shift", + /* 226 */ "Left Alt", + /* 227 */ "Left GUI", + /* 228 */ "Right Ctrl", + /* 229 */ "Right Shift", + /* 230 */ "Right Alt", + /* 231 */ "Right GUI", + /* 232 */ NULL, + /* 233 */ NULL, + /* 234 */ NULL, + /* 235 */ NULL, + /* 236 */ NULL, + /* 237 */ NULL, + /* 238 */ NULL, + /* 239 */ NULL, + /* 240 */ NULL, + /* 241 */ NULL, + /* 242 */ NULL, + /* 243 */ NULL, + /* 244 */ NULL, + /* 245 */ NULL, + /* 246 */ NULL, + /* 247 */ NULL, + /* 248 */ NULL, + /* 249 */ NULL, + /* 250 */ NULL, + /* 251 */ NULL, + /* 252 */ NULL, + /* 253 */ NULL, + /* 254 */ NULL, + /* 255 */ NULL, + /* 256 */ NULL, + /* 257 */ "ModeSwitch", + /* 258 */ "AudioNext", + /* 259 */ "AudioPrev", + /* 260 */ "AudioStop", + /* 261 */ "AudioPlay", + /* 262 */ "AudioMute", + /* 263 */ "MediaSelect", + /* 264 */ "WWW", + /* 265 */ "Mail", + /* 266 */ "Calculator", + /* 267 */ "Computer", + /* 268 */ "AC Search", + /* 269 */ "AC Home", + /* 270 */ "AC Back", + /* 271 */ "AC Forward", + /* 272 */ "AC Stop", + /* 273 */ "AC Refresh", + /* 274 */ "AC Bookmarks", + /* 275 */ "BrightnessDown", + /* 276 */ "BrightnessUp", + /* 277 */ "DisplaySwitch", + /* 278 */ "KBDIllumToggle", + /* 279 */ "KBDIllumDown", + /* 280 */ "KBDIllumUp", + /* 281 */ "Eject", + /* 282 */ "Sleep", + /* 283 */ "App1", + /* 284 */ "App2", + /* 285 */ "AudioRewind", + /* 286 */ "AudioFastForward", + /* 287 */ "SoftLeft", + /* 288 */ "SoftRight", + /* 289 */ "Call", + /* 290 */ "EndCall", +}; + +/* Taken from SDL_iconv() */ +char *SDL_UCS4ToUTF8(Uint32 ch, char *dst) +{ + Uint8 *p = (Uint8 *)dst; + if (ch <= 0x7F) { + *p = (Uint8)ch; + ++dst; + } else if (ch <= 0x7FF) { + p[0] = 0xC0 | (Uint8)((ch >> 6) & 0x1F); + p[1] = 0x80 | (Uint8)(ch & 0x3F); + dst += 2; + } else if (ch <= 0xFFFF) { + p[0] = 0xE0 | (Uint8)((ch >> 12) & 0x0F); + p[1] = 0x80 | (Uint8)((ch >> 6) & 0x3F); + p[2] = 0x80 | (Uint8)(ch & 0x3F); + dst += 3; + } else { + p[0] = 0xF0 | (Uint8)((ch >> 18) & 0x07); + p[1] = 0x80 | (Uint8)((ch >> 12) & 0x3F); + p[2] = 0x80 | (Uint8)((ch >> 6) & 0x3F); + p[3] = 0x80 | (Uint8)(ch & 0x3F); + dst += 4; + } + return dst; +} + +/* Public functions */ +int SDL_KeyboardInit(void) +{ + /* Set the default keymap */ + SDL_SetKeymap(0, SDL_default_keymap, SDL_NUM_SCANCODES, SDL_FALSE); + return 0; +} + +void SDL_ResetKeyboard(void) +{ + SDL_Keyboard *keyboard = &SDL_keyboard; + SDL_Scancode scancode; + +#ifdef DEBUG_KEYBOARD + printf("Resetting keyboard\n"); +#endif + for (scancode = (SDL_Scancode)0; scancode < SDL_NUM_SCANCODES; ++scancode) { + if (keyboard->keystate[scancode] == SDL_PRESSED) { + SDL_SendKeyboardKey(SDL_RELEASED, scancode); + } + } +} + +void SDL_GetDefaultKeymap(SDL_Keycode *keymap) +{ + SDL_memcpy(keymap, SDL_default_keymap, sizeof(SDL_default_keymap)); +} + +void SDL_SetKeymap(int start, const SDL_Keycode *keys, int length, SDL_bool send_event) +{ + SDL_Keyboard *keyboard = &SDL_keyboard; + SDL_Scancode scancode; + SDL_Keycode normalized_keymap[SDL_NUM_SCANCODES]; + SDL_bool is_azerty = SDL_FALSE; + + if (start < 0 || start + length > SDL_NUM_SCANCODES) { + return; + } + + if (start > 0) { + SDL_memcpy(&normalized_keymap[0], &keyboard->keymap[0], sizeof(*keys) * start); + } + + SDL_memcpy(&normalized_keymap[start], keys, sizeof(*keys) * length); + + if (start + length < SDL_NUM_SCANCODES) { + int offset = start + length; + SDL_memcpy(&normalized_keymap[offset], &keyboard->keymap[offset], sizeof(*keys) * (SDL_NUM_SCANCODES - offset)); + } + + /* On AZERTY layouts the number keys are technically symbols, but users (and games) + * always think of them and view them in UI as number keys, so remap them here. + */ + if (normalized_keymap[SDL_SCANCODE_0] < SDLK_0 || normalized_keymap[SDL_SCANCODE_0] > SDLK_9) { + is_azerty = SDL_TRUE; + for (scancode = SDL_SCANCODE_1; scancode <= SDL_SCANCODE_9; ++scancode) { + if (normalized_keymap[scancode] >= SDLK_0 && normalized_keymap[scancode] <= SDLK_9) { + /* There's a number on this row, it's not AZERTY */ + is_azerty = SDL_FALSE; + break; + } + } + } + if (is_azerty) { + normalized_keymap[SDL_SCANCODE_0] = SDLK_0; + for (scancode = SDL_SCANCODE_1; scancode <= SDL_SCANCODE_9; ++scancode) { + normalized_keymap[scancode] = SDLK_1 + (scancode - SDL_SCANCODE_1); + } + } + + /* If the mapping didn't really change, we're done here */ + if (!SDL_memcmp(&keyboard->keymap[start], &normalized_keymap[start], sizeof(*keys) * length)) { + return; + } + + SDL_memcpy(&keyboard->keymap[start], &normalized_keymap[start], sizeof(*keys) * length); + + if (send_event) { + SDL_SendKeymapChangedEvent(); + } +} + +void SDL_SetScancodeName(SDL_Scancode scancode, const char *name) +{ + if (scancode >= SDL_NUM_SCANCODES) { + return; + } + SDL_scancode_names[scancode] = name; +} + +SDL_Window *SDL_GetKeyboardFocus(void) +{ + SDL_Keyboard *keyboard = &SDL_keyboard; + + return keyboard->focus; +} + +void SDL_SetKeyboardFocus(SDL_Window *window) +{ + SDL_Keyboard *keyboard = &SDL_keyboard; + + if (keyboard->focus && !window) { + /* We won't get anymore keyboard messages, so reset keyboard state */ + SDL_ResetKeyboard(); + } + + /* See if the current window has lost focus */ + if (keyboard->focus && keyboard->focus != window) { + + /* new window shouldn't think it has mouse captured. */ + SDL_assert(window == NULL || !(window->flags & SDL_WINDOW_MOUSE_CAPTURE)); + + /* old window must lose an existing mouse capture. */ + if (keyboard->focus->flags & SDL_WINDOW_MOUSE_CAPTURE) { + SDL_CaptureMouse(SDL_FALSE); /* drop the capture. */ + SDL_UpdateMouseCapture(SDL_TRUE); + SDL_assert(!(keyboard->focus->flags & SDL_WINDOW_MOUSE_CAPTURE)); + } + + SDL_SendWindowEvent(keyboard->focus, SDL_WINDOWEVENT_FOCUS_LOST, + 0, 0); + + /* Ensures IME compositions are committed */ + if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) { + SDL_VideoDevice *video = SDL_GetVideoDevice(); + if (video && video->StopTextInput) { + video->StopTextInput(video); + } + } + } + + keyboard->focus = window; + + if (keyboard->focus) { + SDL_SendWindowEvent(keyboard->focus, SDL_WINDOWEVENT_FOCUS_GAINED, + 0, 0); + + if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) { + SDL_VideoDevice *video = SDL_GetVideoDevice(); + if (video && video->StartTextInput) { + video->StartTextInput(video); + } + } + } +} + +static int SDL_SendKeyboardKeyInternal(Uint8 source, Uint8 state, SDL_Scancode scancode, SDL_Keycode keycode) +{ + SDL_Keyboard *keyboard = &SDL_keyboard; + int posted; + SDL_Keymod modifier; + Uint32 type; + Uint8 repeat = SDL_FALSE; + + if (scancode == SDL_SCANCODE_UNKNOWN || scancode >= SDL_NUM_SCANCODES) { + return 0; + } + +#ifdef DEBUG_KEYBOARD + printf("The '%s' key has been %s\n", SDL_GetScancodeName(scancode), + state == SDL_PRESSED ? "pressed" : "released"); +#endif + + /* Figure out what type of event this is */ + switch (state) { + case SDL_PRESSED: + type = SDL_KEYDOWN; + break; + case SDL_RELEASED: + type = SDL_KEYUP; + break; + default: + /* Invalid state -- bail */ + return 0; + } + + /* Drop events that don't change state */ + if (state) { + if (keyboard->keystate[scancode]) { + if (!(keyboard->keysource[scancode] & source)) { + keyboard->keysource[scancode] |= source; + return 0; + } + repeat = SDL_TRUE; + } + keyboard->keysource[scancode] |= source; + } else { + if (!keyboard->keystate[scancode]) { + return 0; + } + keyboard->keysource[scancode] = 0; + } + + /* Update internal keyboard state */ + keyboard->keystate[scancode] = state; + + if (keycode == SDLK_UNKNOWN) { + keycode = keyboard->keymap[scancode]; + } + + if (source == KEYBOARD_HARDWARE) { + keyboard->hardware_timestamp = SDL_GetTicks(); + } else if (source == KEYBOARD_AUTORELEASE) { + keyboard->autorelease_pending = SDL_TRUE; + } + + /* Update modifiers state if applicable */ + switch (keycode) { + case SDLK_LCTRL: + modifier = KMOD_LCTRL; + break; + case SDLK_RCTRL: + modifier = KMOD_RCTRL; + break; + case SDLK_LSHIFT: + modifier = KMOD_LSHIFT; + break; + case SDLK_RSHIFT: + modifier = KMOD_RSHIFT; + break; + case SDLK_LALT: + modifier = KMOD_LALT; + break; + case SDLK_RALT: + modifier = KMOD_RALT; + break; + case SDLK_LGUI: + modifier = KMOD_LGUI; + break; + case SDLK_RGUI: + modifier = KMOD_RGUI; + break; + case SDLK_MODE: + modifier = KMOD_MODE; + break; + default: + modifier = KMOD_NONE; + break; + } + if (SDL_KEYDOWN == type) { + switch (keycode) { + case SDLK_NUMLOCKCLEAR: + keyboard->modstate ^= KMOD_NUM; + break; + case SDLK_CAPSLOCK: + keyboard->modstate ^= KMOD_CAPS; + break; + case SDLK_SCROLLLOCK: + keyboard->modstate ^= KMOD_SCROLL; + break; + default: + keyboard->modstate |= modifier; + break; + } + } else { + keyboard->modstate &= ~modifier; + } + + /* Post the event, if desired */ + posted = 0; + if (SDL_GetEventState(type) == SDL_ENABLE) { + SDL_Event event; + event.key.type = type; + event.key.state = state; + event.key.repeat = repeat; + event.key.keysym.scancode = scancode; + event.key.keysym.sym = keycode; + event.key.keysym.mod = keyboard->modstate; + event.key.windowID = keyboard->focus ? keyboard->focus->id : 0; + posted = (SDL_PushEvent(&event) > 0); + } + + /* If the keyboard is grabbed and the grabbed window is in full-screen, + minimize the window when we receive Alt+Tab, unless the application + has explicitly opted out of this behavior. */ + if (keycode == SDLK_TAB && + state == SDL_PRESSED && + (keyboard->modstate & KMOD_ALT) && + keyboard->focus && + (keyboard->focus->flags & SDL_WINDOW_KEYBOARD_GRABBED) && + (keyboard->focus->flags & SDL_WINDOW_FULLSCREEN) && + SDL_GetHintBoolean(SDL_HINT_ALLOW_ALT_TAB_WHILE_GRABBED, SDL_TRUE)) { + /* We will temporarily forfeit our grab by minimizing our window, + allowing the user to escape the application */ + SDL_MinimizeWindow(keyboard->focus); + } + + return posted; +} + +int SDL_SendKeyboardUnicodeKey(Uint32 ch) +{ + SDL_Scancode code = SDL_SCANCODE_UNKNOWN; + uint16_t mod = 0; + + if (ch < SDL_arraysize(SDL_ASCIIKeyInfoTable)) { + code = SDL_ASCIIKeyInfoTable[ch].code; + mod = SDL_ASCIIKeyInfoTable[ch].mod; + } + + if (mod & KMOD_SHIFT) { + /* If the character uses shift, press shift down */ + SDL_SendKeyboardKeyInternal(KEYBOARD_VIRTUAL, SDL_PRESSED, SDL_SCANCODE_LSHIFT, SDLK_UNKNOWN); + } + + /* Send a keydown and keyup for the character */ + SDL_SendKeyboardKeyInternal(KEYBOARD_VIRTUAL, SDL_PRESSED, code, SDLK_UNKNOWN); + SDL_SendKeyboardKeyInternal(KEYBOARD_VIRTUAL, SDL_RELEASED, code, SDLK_UNKNOWN); + + if (mod & KMOD_SHIFT) { + /* If the character uses shift, release shift */ + SDL_SendKeyboardKeyInternal(KEYBOARD_VIRTUAL, SDL_RELEASED, SDL_SCANCODE_LSHIFT, SDLK_UNKNOWN); + } + return 0; +} + +int SDL_SendVirtualKeyboardKey(Uint8 state, SDL_Scancode scancode) +{ + return SDL_SendKeyboardKeyInternal(KEYBOARD_VIRTUAL, state, scancode, SDLK_UNKNOWN); +} + +int SDL_SendKeyboardKey(Uint8 state, SDL_Scancode scancode) +{ + return SDL_SendKeyboardKeyInternal(KEYBOARD_HARDWARE, state, scancode, SDLK_UNKNOWN); +} + +int SDL_SendKeyboardKeyAndKeycode(Uint8 state, SDL_Scancode scancode, SDL_Keycode keycode) +{ + return SDL_SendKeyboardKeyInternal(KEYBOARD_HARDWARE, state, scancode, keycode); +} + +int SDL_SendKeyboardKeyAutoRelease(SDL_Scancode scancode) +{ + return SDL_SendKeyboardKeyInternal(KEYBOARD_AUTORELEASE, SDL_PRESSED, scancode, SDLK_UNKNOWN); +} + +void SDL_ReleaseAutoReleaseKeys(void) +{ + SDL_Keyboard *keyboard = &SDL_keyboard; + SDL_Scancode scancode; + + if (keyboard->autorelease_pending) { + for (scancode = SDL_SCANCODE_UNKNOWN; scancode < SDL_NUM_SCANCODES; ++scancode) { + if (keyboard->keysource[scancode] == KEYBOARD_AUTORELEASE) { + SDL_SendKeyboardKeyInternal(KEYBOARD_AUTORELEASE, SDL_RELEASED, scancode, SDLK_UNKNOWN); + } + } + keyboard->autorelease_pending = SDL_FALSE; + } + + if (keyboard->hardware_timestamp) { + /* Keep hardware keyboard "active" for 250 ms */ + if (SDL_TICKS_PASSED(SDL_GetTicks(), keyboard->hardware_timestamp + 250)) { + keyboard->hardware_timestamp = 0; + } + } +} + +SDL_bool SDL_HardwareKeyboardKeyPressed(void) +{ + SDL_Keyboard *keyboard = &SDL_keyboard; + SDL_Scancode scancode; + + for (scancode = SDL_SCANCODE_UNKNOWN; scancode < SDL_NUM_SCANCODES; ++scancode) { + if (keyboard->keysource[scancode] & KEYBOARD_HARDWARE) { + return SDL_TRUE; + } + } + + return keyboard->hardware_timestamp ? SDL_TRUE : SDL_FALSE; +} + +int SDL_SendKeyboardText(const char *text) +{ + SDL_Keyboard *keyboard = &SDL_keyboard; + int posted; + + /* Don't post text events for unprintable characters */ + if ((unsigned char)*text < ' ' || *text == 127) { + return 0; + } + + /* Post the event, if desired */ + posted = 0; + if (SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE) { + SDL_Event event; + size_t pos = 0, advance, length = SDL_strlen(text); + + event.text.type = SDL_TEXTINPUT; + event.text.windowID = keyboard->focus ? keyboard->focus->id : 0; + while (pos < length) { + advance = SDL_utf8strlcpy(event.text.text, text + pos, SDL_arraysize(event.text.text)); + if (!advance) { + break; + } + pos += advance; + posted |= (SDL_PushEvent(&event) > 0); + } + } + return posted; +} + +int SDL_SendEditingText(const char *text, int start, int length) +{ + SDL_Keyboard *keyboard = &SDL_keyboard; + int posted; + + /* Post the event, if desired */ + posted = 0; + if (SDL_GetEventState(SDL_TEXTEDITING) == SDL_ENABLE) { + SDL_Event event; + + if (SDL_GetHintBoolean(SDL_HINT_IME_SUPPORT_EXTENDED_TEXT, SDL_FALSE) && + SDL_strlen(text) >= SDL_arraysize(event.text.text)) { + event.editExt.type = SDL_TEXTEDITING_EXT; + event.editExt.windowID = keyboard->focus ? keyboard->focus->id : 0; + event.editExt.text = text ? SDL_strdup(text) : NULL; + event.editExt.start = start; + event.editExt.length = length; + } else { + event.edit.type = SDL_TEXTEDITING; + event.edit.windowID = keyboard->focus ? keyboard->focus->id : 0; + event.edit.start = start; + event.edit.length = length; + SDL_utf8strlcpy(event.edit.text, text, SDL_arraysize(event.edit.text)); + } + + posted = (SDL_PushEvent(&event) > 0); + } + return posted; +} + +void SDL_KeyboardQuit(void) +{ +} + +const Uint8 *SDL_GetKeyboardState(int *numkeys) +{ + SDL_Keyboard *keyboard = &SDL_keyboard; + + if (numkeys != (int *)0) { + *numkeys = SDL_NUM_SCANCODES; + } + return keyboard->keystate; +} + +SDL_Keymod SDL_GetModState(void) +{ + SDL_Keyboard *keyboard = &SDL_keyboard; + + return (SDL_Keymod)keyboard->modstate; +} + +void SDL_SetModState(SDL_Keymod modstate) +{ + SDL_Keyboard *keyboard = &SDL_keyboard; + + keyboard->modstate = modstate; +} + +/* Note that SDL_ToggleModState() is not a public API. SDL_SetModState() is. */ +void SDL_ToggleModState(const SDL_Keymod modstate, const SDL_bool toggle) +{ + SDL_Keyboard *keyboard = &SDL_keyboard; + if (toggle) { + keyboard->modstate |= modstate; + } else { + keyboard->modstate &= ~modstate; + } +} + +SDL_Keycode SDL_GetKeyFromScancode(SDL_Scancode scancode) +{ + SDL_Keyboard *keyboard = &SDL_keyboard; + + if (((int)scancode) < SDL_SCANCODE_UNKNOWN || scancode >= SDL_NUM_SCANCODES) { + SDL_InvalidParamError("scancode"); + return 0; + } + + return keyboard->keymap[scancode]; +} + +SDL_Keycode SDL_GetDefaultKeyFromScancode(SDL_Scancode scancode) +{ + if (((int)scancode) < SDL_SCANCODE_UNKNOWN || scancode >= SDL_NUM_SCANCODES) { + SDL_InvalidParamError("scancode"); + return 0; + } + + return SDL_default_keymap[scancode]; +} + +SDL_Scancode SDL_GetScancodeFromKey(SDL_Keycode key) +{ + SDL_Keyboard *keyboard = &SDL_keyboard; + SDL_Scancode scancode; + + for (scancode = SDL_SCANCODE_UNKNOWN; scancode < SDL_NUM_SCANCODES; + ++scancode) { + if (keyboard->keymap[scancode] == key) { + return scancode; + } + } + return SDL_SCANCODE_UNKNOWN; +} + +const char *SDL_GetScancodeName(SDL_Scancode scancode) +{ + const char *name; + if (((int)scancode) < SDL_SCANCODE_UNKNOWN || scancode >= SDL_NUM_SCANCODES) { + SDL_InvalidParamError("scancode"); + return ""; + } + + name = SDL_scancode_names[scancode]; + if (name) { + return name; + } + + return ""; +} + +SDL_Scancode SDL_GetScancodeFromName(const char *name) +{ + int i; + + if (!name || !*name) { + SDL_InvalidParamError("name"); + return SDL_SCANCODE_UNKNOWN; + } + + for (i = 0; i < SDL_arraysize(SDL_scancode_names); ++i) { + if (!SDL_scancode_names[i]) { + continue; + } + if (SDL_strcasecmp(name, SDL_scancode_names[i]) == 0) { + return (SDL_Scancode)i; + } + } + + SDL_InvalidParamError("name"); + return SDL_SCANCODE_UNKNOWN; +} + +const char *SDL_GetKeyName(SDL_Keycode key) +{ + static char name[8]; + char *end; + + if (key & SDLK_SCANCODE_MASK) { + return SDL_GetScancodeName((SDL_Scancode)(key & ~SDLK_SCANCODE_MASK)); + } + + switch (key) { + case SDLK_RETURN: + return SDL_GetScancodeName(SDL_SCANCODE_RETURN); + case SDLK_ESCAPE: + return SDL_GetScancodeName(SDL_SCANCODE_ESCAPE); + case SDLK_BACKSPACE: + return SDL_GetScancodeName(SDL_SCANCODE_BACKSPACE); + case SDLK_TAB: + return SDL_GetScancodeName(SDL_SCANCODE_TAB); + case SDLK_SPACE: + return SDL_GetScancodeName(SDL_SCANCODE_SPACE); + case SDLK_DELETE: + return SDL_GetScancodeName(SDL_SCANCODE_DELETE); + default: + /* Unaccented letter keys on latin keyboards are normally + labeled in upper case (and probably on others like Greek or + Cyrillic too, so if you happen to know for sure, please + adapt this). */ + if (key >= 'a' && key <= 'z') { + key -= 32; + } + + end = SDL_UCS4ToUTF8((Uint32)key, name); + *end = '\0'; + return name; + } +} + +SDL_Keycode SDL_GetKeyFromName(const char *name) +{ + SDL_Keycode key; + + /* Check input */ + if (!name) { + return SDLK_UNKNOWN; + } + + /* If it's a single UTF-8 character, then that's the keycode itself */ + key = *(const unsigned char *)name; + if (key >= 0xF0) { + if (SDL_strlen(name) == 4) { + int i = 0; + key = (Uint16)(name[i] & 0x07) << 18; + key |= (Uint16)(name[++i] & 0x3F) << 12; + key |= (Uint16)(name[++i] & 0x3F) << 6; + key |= (Uint16)(name[++i] & 0x3F); + return key; + } + return SDLK_UNKNOWN; + } else if (key >= 0xE0) { + if (SDL_strlen(name) == 3) { + int i = 0; + key = (Uint16)(name[i] & 0x0F) << 12; + key |= (Uint16)(name[++i] & 0x3F) << 6; + key |= (Uint16)(name[++i] & 0x3F); + return key; + } + return SDLK_UNKNOWN; + } else if (key >= 0xC0) { + if (SDL_strlen(name) == 2) { + int i = 0; + key = (Uint16)(name[i] & 0x1F) << 6; + key |= (Uint16)(name[++i] & 0x3F); + return key; + } + return SDLK_UNKNOWN; + } else { + if (SDL_strlen(name) == 1) { + if (key >= 'A' && key <= 'Z') { + key += 32; + } + return key; + } + + /* Get the scancode for this name, and the associated keycode */ + return SDL_default_keymap[SDL_GetScancodeFromName(name)]; + } +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/events/SDL_keyboard_c.h b/SDL2-2.30.5/src/events/SDL_keyboard_c.h similarity index 62% rename from SDL2-2.0.12/src/events/SDL_keyboard_c.h rename to SDL2-2.30.5/src/events/SDL_keyboard_c.h index 1faf3e2..4c5cd2f 100644 --- a/SDL2-2.0.12/src/events/SDL_keyboard_c.h +++ b/SDL2-2.30.5/src/events/SDL_keyboard_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -29,14 +29,14 @@ /* Initialize the keyboard subsystem */ extern int SDL_KeyboardInit(void); -/* Clear the state of the keyboard */ -extern void SDL_ResetKeyboard(void); - /* Get the default keymap */ -extern void SDL_GetDefaultKeymap(SDL_Keycode * keymap); +extern void SDL_GetDefaultKeymap(SDL_Keycode *keymap); + +/* Get the default key code for a scancode */ +extern SDL_Keycode SDL_GetDefaultKeyFromScancode(SDL_Scancode scancode); /* Set the mapping of scancode to key codes */ -extern void SDL_SetKeymap(int start, SDL_Keycode * keys, int length); +extern void SDL_SetKeymap(int start, const SDL_Keycode *keys, int length, SDL_bool send_event); /* Set a platform-dependent key name, overriding the default platform-agnostic name. Encoded as UTF-8. The string is not copied, thus the pointer given to @@ -45,16 +45,35 @@ extern void SDL_SetKeymap(int start, SDL_Keycode * keys, int length); extern void SDL_SetScancodeName(SDL_Scancode scancode, const char *name); /* Set the keyboard focus window */ -extern void SDL_SetKeyboardFocus(SDL_Window * window); +extern void SDL_SetKeyboardFocus(SDL_Window *window); + +/* Send a character from an on-screen keyboard as scancode and modifier key events, + currently assuming ASCII characters on a US keyboard layout + */ +extern int SDL_SendKeyboardUnicodeKey(Uint32 ch); + +/* Send a key from a virtual key source, like an on-screen keyboard */ +extern int SDL_SendVirtualKeyboardKey(Uint8 state, SDL_Scancode scancode); /* Send a keyboard key event */ extern int SDL_SendKeyboardKey(Uint8 state, SDL_Scancode scancode); +extern int SDL_SendKeyboardKeyAutoRelease(SDL_Scancode scancode); + +/* This is for platforms that don't know the keymap but can report scancode and keycode directly. + Most platforms should prefer to optionally call SDL_SetKeymap and then use SDL_SendKeyboardKey. */ +extern int SDL_SendKeyboardKeyAndKeycode(Uint8 state, SDL_Scancode scancode, SDL_Keycode keycode); + +/* Release all the autorelease keys */ +extern void SDL_ReleaseAutoReleaseKeys(void); + +/* Return true if any hardware key is pressed */ +extern SDL_bool SDL_HardwareKeyboardKeyPressed(void); /* Send keyboard text input */ extern int SDL_SendKeyboardText(const char *text); /* Send editing text for selected range from start to end */ -extern int SDL_SendEditingText(const char *text, int start, int end); +extern int SDL_SendEditingText(const char *text, int start, int length); /* Shutdown the keyboard subsystem */ extern void SDL_KeyboardQuit(void); diff --git a/SDL2-2.30.5/src/events/SDL_keysym_to_scancode.c b/SDL2-2.30.5/src/events/SDL_keysym_to_scancode.c new file mode 100644 index 0000000..ddf4ae3 --- /dev/null +++ b/SDL2-2.30.5/src/events/SDL_keysym_to_scancode.c @@ -0,0 +1,440 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#if defined(SDL_VIDEO_DRIVER_WAYLAND) || defined(SDL_VIDEO_DRIVER_X11) + +#include "SDL_keyboard_c.h" +#include "SDL_scancode_tables_c.h" + +/* *INDENT-OFF* */ /* clang-format off */ +static const struct { + Uint32 keysym; + SDL_Scancode scancode; +} KeySymToSDLScancode[] = { + { 0xFF9C, SDL_SCANCODE_KP_1 }, /* XK_KP_End */ + { 0xFF99, SDL_SCANCODE_KP_2 }, /* XK_KP_Down */ + { 0xFF9B, SDL_SCANCODE_KP_3 }, /* XK_KP_Next */ + { 0xFF96, SDL_SCANCODE_KP_4 }, /* XK_KP_Left */ + { 0xFF9D, SDL_SCANCODE_KP_5 }, /* XK_KP_Begin */ + { 0xFF98, SDL_SCANCODE_KP_6 }, /* XK_KP_Right */ + { 0xFF95, SDL_SCANCODE_KP_7 }, /* XK_KP_Home */ + { 0xFF97, SDL_SCANCODE_KP_8 }, /* XK_KP_Up */ + { 0xFF9A, SDL_SCANCODE_KP_9 }, /* XK_KP_Prior */ + { 0xFF9E, SDL_SCANCODE_KP_0 }, /* XK_KP_Insert */ + { 0xFF9F, SDL_SCANCODE_KP_PERIOD }, /* XK_KP_Delete */ + { 0xFF62, SDL_SCANCODE_EXECUTE }, /* XK_Execute */ + { 0xFFEE, SDL_SCANCODE_APPLICATION }, /* XK_Hyper_R */ + { 0xFE03, SDL_SCANCODE_RALT }, /* XK_ISO_Level3_Shift */ + { 0xFFEB, SDL_SCANCODE_LGUI }, /* XK_Super_L */ + { 0xFFEC, SDL_SCANCODE_RGUI }, /* XK_Super_R */ + { 0xFF7E, SDL_SCANCODE_MODE }, /* XK_Mode_switch */ + { 0x1008FF65, SDL_SCANCODE_MENU }, /* XF86MenuKB */ + { 0x1008FF81, SDL_SCANCODE_F13 }, /* XF86Tools */ + { 0x1008FF45, SDL_SCANCODE_F14 }, /* XF86Launch5 */ + { 0x1008FF46, SDL_SCANCODE_F15 }, /* XF86Launch6 */ + { 0x1008FF47, SDL_SCANCODE_F16 }, /* XF86Launch7 */ + { 0x1008FF48, SDL_SCANCODE_F17 }, /* XF86Launch8 */ + { 0x1008FF49, SDL_SCANCODE_F18 }, /* XF86Launch9 */ +}; + +/* This is a mapping from X keysym to Linux keycode */ +static const Uint32 LinuxKeycodeKeysyms[] = { + /* 0, 0x000 */ 0x0, /* NoSymbol */ + /* 1, 0x001 */ 0xFF1B, /* Escape */ + /* 2, 0x002 */ 0x31, /* 1 */ + /* 3, 0x003 */ 0x32, /* 2 */ + /* 4, 0x004 */ 0x33, /* 3 */ + /* 5, 0x005 */ 0x34, /* 4 */ + /* 6, 0x006 */ 0x35, /* 5 */ + /* 7, 0x007 */ 0x36, /* 6 */ + /* 8, 0x008 */ 0x37, /* 7 */ + /* 9, 0x009 */ 0x38, /* 8 */ + /* 10, 0x00a */ 0x39, /* 9 */ + /* 11, 0x00b */ 0x30, /* 0 */ + /* 12, 0x00c */ 0x2D, /* minus */ + /* 13, 0x00d */ 0x3D, /* equal */ + /* 14, 0x00e */ 0xFF08, /* BackSpace */ + /* 15, 0x00f */ 0xFF09, /* Tab */ + /* 16, 0x010 */ 0x71, /* q */ + /* 17, 0x011 */ 0x77, /* w */ + /* 18, 0x012 */ 0x65, /* e */ + /* 19, 0x013 */ 0x72, /* r */ + /* 20, 0x014 */ 0x74, /* t */ + /* 21, 0x015 */ 0x79, /* y */ + /* 22, 0x016 */ 0x75, /* u */ + /* 23, 0x017 */ 0x69, /* i */ + /* 24, 0x018 */ 0x6F, /* o */ + /* 25, 0x019 */ 0x70, /* p */ + /* 26, 0x01a */ 0x5B, /* bracketleft */ + /* 27, 0x01b */ 0x5D, /* bracketright */ + /* 28, 0x01c */ 0xFF0D, /* Return */ + /* 29, 0x01d */ 0xFFE3, /* Control_L */ + /* 30, 0x01e */ 0x61, /* a */ + /* 31, 0x01f */ 0x73, /* s */ + /* 32, 0x020 */ 0x64, /* d */ + /* 33, 0x021 */ 0x66, /* f */ + /* 34, 0x022 */ 0x67, /* g */ + /* 35, 0x023 */ 0x68, /* h */ + /* 36, 0x024 */ 0x6A, /* j */ + /* 37, 0x025 */ 0x6B, /* k */ + /* 38, 0x026 */ 0x6C, /* l */ + /* 39, 0x027 */ 0x3B, /* semicolon */ + /* 40, 0x028 */ 0x27, /* apostrophe */ + /* 41, 0x029 */ 0x60, /* grave */ + /* 42, 0x02a */ 0xFFE1, /* Shift_L */ + /* 43, 0x02b */ 0x5C, /* backslash */ + /* 44, 0x02c */ 0x7A, /* z */ + /* 45, 0x02d */ 0x78, /* x */ + /* 46, 0x02e */ 0x63, /* c */ + /* 47, 0x02f */ 0x76, /* v */ + /* 48, 0x030 */ 0x62, /* b */ + /* 49, 0x031 */ 0x6E, /* n */ + /* 50, 0x032 */ 0x6D, /* m */ + /* 51, 0x033 */ 0x2C, /* comma */ + /* 52, 0x034 */ 0x2E, /* period */ + /* 53, 0x035 */ 0x2F, /* slash */ + /* 54, 0x036 */ 0xFFE2, /* Shift_R */ + /* 55, 0x037 */ 0xFFAA, /* KP_Multiply */ + /* 56, 0x038 */ 0xFFE9, /* Alt_L */ + /* 57, 0x039 */ 0x20, /* space */ + /* 58, 0x03a */ 0xFFE5, /* Caps_Lock */ + /* 59, 0x03b */ 0xFFBE, /* F1 */ + /* 60, 0x03c */ 0xFFBF, /* F2 */ + /* 61, 0x03d */ 0xFFC0, /* F3 */ + /* 62, 0x03e */ 0xFFC1, /* F4 */ + /* 63, 0x03f */ 0xFFC2, /* F5 */ + /* 64, 0x040 */ 0xFFC3, /* F6 */ + /* 65, 0x041 */ 0xFFC4, /* F7 */ + /* 66, 0x042 */ 0xFFC5, /* F8 */ + /* 67, 0x043 */ 0xFFC6, /* F9 */ + /* 68, 0x044 */ 0xFFC7, /* F10 */ + /* 69, 0x045 */ 0xFF7F, /* Num_Lock */ + /* 70, 0x046 */ 0xFF14, /* Scroll_Lock */ + /* 71, 0x047 */ 0xFFB7, /* KP_7 */ + /* 72, 0x048 */ 0XFFB8, /* KP_8 */ + /* 73, 0x049 */ 0XFFB9, /* KP_9 */ + /* 74, 0x04a */ 0xFFAD, /* KP_Subtract */ + /* 75, 0x04b */ 0xFFB4, /* KP_4 */ + /* 76, 0x04c */ 0xFFB5, /* KP_5 */ + /* 77, 0x04d */ 0xFFB6, /* KP_6 */ + /* 78, 0x04e */ 0xFFAB, /* KP_Add */ + /* 79, 0x04f */ 0xFFB1, /* KP_1 */ + /* 80, 0x050 */ 0xFFB2, /* KP_2 */ + /* 81, 0x051 */ 0xFFB3, /* KP_3 */ + /* 82, 0x052 */ 0xFFB0, /* KP_0 */ + /* 83, 0x053 */ 0xFFAE, /* KP_Decimal */ + /* 84, 0x054 */ 0x0, /* NoSymbol */ + /* 85, 0x055 */ 0x0, /* NoSymbol */ + /* 86, 0x056 */ 0x3C, /* less */ + /* 87, 0x057 */ 0xFFC8, /* F11 */ + /* 88, 0x058 */ 0xFFC9, /* F12 */ + /* 89, 0x059 */ 0x0, /* NoSymbol */ + /* 90, 0x05a */ 0xFF26, /* Katakana */ + /* 91, 0x05b */ 0xFF25, /* Hiragana */ + /* 92, 0x05c */ 0xFF23, /* Henkan_Mode */ + /* 93, 0x05d */ 0xFF27, /* Hiragana_Katakana */ + /* 94, 0x05e */ 0xFF22, /* Muhenkan */ + /* 95, 0x05f */ 0x0, /* NoSymbol */ + /* 96, 0x060 */ 0xFF8D, /* KP_Enter */ + /* 97, 0x061 */ 0xFFE4, /* Control_R */ + /* 98, 0x062 */ 0xFFAF, /* KP_Divide */ + /* 99, 0x063 */ 0xFF15, /* Sys_Req */ + /* 100, 0x064 */ 0xFFEA, /* Alt_R */ + /* 101, 0x065 */ 0xFF0A, /* Linefeed */ + /* 102, 0x066 */ 0xFF50, /* Home */ + /* 103, 0x067 */ 0xFF52, /* Up */ + /* 104, 0x068 */ 0xFF55, /* Prior */ + /* 105, 0x069 */ 0xFF51, /* Left */ + /* 106, 0x06a */ 0xFF53, /* Right */ + /* 107, 0x06b */ 0xFF57, /* End */ + /* 108, 0x06c */ 0xFF54, /* Down */ + /* 109, 0x06d */ 0xFF56, /* Next */ + /* 110, 0x06e */ 0xFF63, /* Insert */ + /* 111, 0x06f */ 0xFFFF, /* Delete */ + /* 112, 0x070 */ 0x0, /* NoSymbol */ + /* 113, 0x071 */ 0x1008FF12, /* XF86AudioMute */ + /* 114, 0x072 */ 0x1008FF11, /* XF86AudioLowerVolume */ + /* 115, 0x073 */ 0x1008FF13, /* XF86AudioRaiseVolume */ + /* 116, 0x074 */ 0x1008FF2A, /* XF86PowerOff */ + /* 117, 0x075 */ 0xFFBD, /* KP_Equal */ + /* 118, 0x076 */ 0xB1, /* plusminus */ + /* 119, 0x077 */ 0xFF13, /* Pause */ + /* 120, 0x078 */ 0x1008FF4A, /* XF86LaunchA */ + /* 121, 0x079 */ 0xFFAC, /* KP_Separator */ + /* 122, 0x07a */ 0xFF31, /* Hangul */ + /* 123, 0x07b */ 0xFF34, /* Hangul_Hanja */ + /* 124, 0x07c */ 0x0, /* NoSymbol */ + /* 125, 0x07d */ 0xFFE7, /* Meta_L */ + /* 126, 0x07e */ 0xFFE8, /* Meta_R */ + /* 127, 0x07f */ 0xFF67, /* Menu */ + /* 128, 0x080 */ 0x00, /* NoSymbol */ + /* 129, 0x081 */ 0xFF66, /* Redo */ + /* 130, 0x082 */ 0x1005FF70, /* SunProps */ + /* 131, 0x083 */ 0xFF65, /* Undo */ + /* 132, 0x084 */ 0x1005FF71, /* SunFront */ + /* 133, 0x085 */ 0x1008FF57, /* XF86Copy */ + /* 134, 0x086 */ 0x1008FF6B, /* XF86Open */ + /* 135, 0x087 */ 0x1008FF6D, /* XF86Paste */ + /* 136, 0x088 */ 0xFF68, /* Find */ + /* 137, 0x089 */ 0x1008FF58, /* XF86Cut */ + /* 138, 0x08a */ 0xFF6A, /* Help */ + /* 139, 0x08b */ 0xFF67, /* Menu */ + /* 140, 0x08c */ 0x1008FF1D, /* XF86Calculator */ + /* 141, 0x08d */ 0x0, /* NoSymbol */ + /* 142, 0x08e */ 0x1008FF2F, /* XF86Sleep */ + /* 143, 0x08f */ 0x1008FF2B, /* XF86WakeUp */ + /* 144, 0x090 */ 0x1008FF5D, /* XF86Explorer */ + /* 145, 0x091 */ 0x1008FF7B, /* XF86Send */ + /* 146, 0x092 */ 0x0, /* NoSymbol */ + /* 147, 0x093 */ 0x1008FF8A, /* XF86Xfer */ + /* 148, 0x094 */ 0x1008FF41, /* XF86Launch1 */ + /* 149, 0x095 */ 0x1008FF42, /* XF86Launch2 */ + /* 150, 0x096 */ 0x1008FF2E, /* XF86WWW */ + /* 151, 0x097 */ 0x1008FF5A, /* XF86DOS */ + /* 152, 0x098 */ 0x1008FF2D, /* XF86ScreenSaver */ + /* 153, 0x099 */ 0x1008FF74, /* XF86RotateWindows */ + /* 154, 0x09a */ 0x1008FF7F, /* XF86TaskPane */ + /* 155, 0x09b */ 0x1008FF19, /* XF86Mail */ + /* 156, 0x09c */ 0x1008FF30, /* XF86Favorites */ + /* 157, 0x09d */ 0x1008FF33, /* XF86MyComputer */ + /* 158, 0x09e */ 0x1008FF26, /* XF86Back */ + /* 159, 0x09f */ 0x1008FF27, /* XF86Forward */ + /* 160, 0x0a0 */ 0x0, /* NoSymbol */ + /* 161, 0x0a1 */ 0x1008FF2C, /* XF86Eject */ + /* 162, 0x0a2 */ 0x1008FF2C, /* XF86Eject */ + /* 163, 0x0a3 */ 0x1008FF17, /* XF86AudioNext */ + /* 164, 0x0a4 */ 0x1008FF14, /* XF86AudioPlay */ + /* 165, 0x0a5 */ 0x1008FF16, /* XF86AudioPrev */ + /* 166, 0x0a6 */ 0x1008FF15, /* XF86AudioStop */ + /* 167, 0x0a7 */ 0x1008FF1C, /* XF86AudioRecord */ + /* 168, 0x0a8 */ 0x1008FF3E, /* XF86AudioRewind */ + /* 169, 0x0a9 */ 0x1008FF6E, /* XF86Phone */ + /* 170, 0x0aa */ 0x0, /* NoSymbol */ + /* 171, 0x0ab */ 0x1008FF81, /* XF86Tools */ + /* 172, 0x0ac */ 0x1008FF18, /* XF86HomePage */ + /* 173, 0x0ad */ 0x1008FF73, /* XF86Reload */ + /* 174, 0x0ae */ 0x1008FF56, /* XF86Close */ + /* 175, 0x0af */ 0x0, /* NoSymbol */ + /* 176, 0x0b0 */ 0x0, /* NoSymbol */ + /* 177, 0x0b1 */ 0x1008FF78, /* XF86ScrollUp */ + /* 178, 0x0b2 */ 0x1008FF79, /* XF86ScrollDown */ + /* 179, 0x0b3 */ 0x0, /* NoSymbol */ + /* 180, 0x0b4 */ 0x0, /* NoSymbol */ + /* 181, 0x0b5 */ 0x1008FF68, /* XF86New */ + /* 182, 0x0b6 */ 0xFF66, /* Redo */ + /* 183, 0x0b7 */ 0xFFCA, /* F13 */ + /* 184, 0x0b8 */ 0xFFCB, /* F14 */ + /* 185, 0x0b9 */ 0xFFCC, /* F15 */ + /* 186, 0x0ba */ 0xFFCD, /* F16 */ + /* 187, 0x0bb */ 0xFFCE, /* F17 */ + /* 188, 0x0bc */ 0xFFCF, /* F18 */ + /* 189, 0x0bd */ 0xFFD0, /* F19 */ + /* 190, 0x0be */ 0xFFD1, /* F20 */ + /* 191, 0x0bf */ 0xFFD2, /* F21 */ + /* 192, 0x0c0 */ 0xFFD3, /* F22 */ + /* 193, 0x0c1 */ 0xFFD4, /* F23 */ + /* 194, 0x0c2 */ 0xFFD5, /* F24 */ + /* 195, 0x0c3 */ 0x0, /* NoSymbol */ + /* 196, 0x0c4 */ 0x0, /* NoSymbol */ + /* 197, 0x0c5 */ 0x0, /* NoSymbol */ + /* 198, 0x0c6 */ 0x0, /* NoSymbol */ + /* 199, 0x0c7 */ 0x0, /* NoSymbol */ + /* 200, 0x0c8 */ 0x1008FF14, /* XF86AudioPlay */ + /* 201, 0x0c9 */ 0x1008FF31, /* XF86AudioPause */ + /* 202, 0x0ca */ 0x1008FF43, /* XF86Launch3 */ + /* 203, 0x0cb */ 0x1008FF44, /* XF86Launch4 */ + /* 204, 0x0cc */ 0x1008FF4B, /* XF86LaunchB */ + /* 205, 0x0cd */ 0x1008FFA7, /* XF86Suspend */ + /* 206, 0x0ce */ 0x1008FF56, /* XF86Close */ + /* 207, 0x0cf */ 0x1008FF14, /* XF86AudioPlay */ + /* 208, 0x0d0 */ 0x1008FF97, /* XF86AudioForward */ + /* 209, 0x0d1 */ 0x0, /* NoSymbol */ + /* 210, 0x0d2 */ 0xFF61, /* Print */ + /* 211, 0x0d3 */ 0x0, /* NoSymbol */ + /* 212, 0x0d4 */ 0x1008FF8F, /* XF86WebCam */ + /* 213, 0x0d5 */ 0x1008FFB6, /* XF86AudioPreset */ + /* 214, 0x0d6 */ 0x0, /* NoSymbol */ + /* 215, 0x0d7 */ 0x1008FF19, /* XF86Mail */ + /* 216, 0x0d8 */ 0x1008FF8E, /* XF86Messenger */ + /* 217, 0x0d9 */ 0x1008FF1B, /* XF86Search */ + /* 218, 0x0da */ 0x1008FF5F, /* XF86Go */ + /* 219, 0x0db */ 0x1008FF3C, /* XF86Finance */ + /* 220, 0x0dc */ 0x1008FF5E, /* XF86Game */ + /* 221, 0x0dd */ 0x1008FF36, /* XF86Shop */ + /* 222, 0x0de */ 0x0, /* NoSymbol */ + /* 223, 0x0df */ 0xFF69, /* Cancel */ + /* 224, 0x0e0 */ 0x1008FF03, /* XF86MonBrightnessDown */ + /* 225, 0x0e1 */ 0x1008FF02, /* XF86MonBrightnessUp */ + /* 226, 0x0e2 */ 0x1008FF32, /* XF86AudioMedia */ + /* 227, 0x0e3 */ 0x1008FF59, /* XF86Display */ + /* 228, 0x0e4 */ 0x1008FF04, /* XF86KbdLightOnOff */ + /* 229, 0x0e5 */ 0x1008FF06, /* XF86KbdBrightnessDown */ + /* 230, 0x0e6 */ 0x1008FF05, /* XF86KbdBrightnessUp */ + /* 231, 0x0e7 */ 0x1008FF7B, /* XF86Send */ + /* 232, 0x0e8 */ 0x1008FF72, /* XF86Reply */ + /* 233, 0x0e9 */ 0x1008FF90, /* XF86MailForward */ + /* 234, 0x0ea */ 0x1008FF77, /* XF86Save */ + /* 235, 0x0eb */ 0x1008FF5B, /* XF86Documents */ + /* 236, 0x0ec */ 0x1008FF93, /* XF86Battery */ + /* 237, 0x0ed */ 0x1008FF94, /* XF86Bluetooth */ + /* 238, 0x0ee */ 0x1008FF95, /* XF86WLAN */ + /* 239, 0x0ef */ 0x1008FF96, /* XF86UWB */ + /* 240, 0x0f0 */ 0x0, /* NoSymbol */ + /* 241, 0x0f1 */ 0x1008FE22, /* XF86Next_VMode */ + /* 242, 0x0f2 */ 0x1008FE23, /* XF86Prev_VMode */ + /* 243, 0x0f3 */ 0x1008FF07, /* XF86MonBrightnessCycle */ + /* 244, 0x0f4 */ 0x100810F4, /* XF86BrightnessAuto */ + /* 245, 0x0f5 */ 0x100810F5, /* XF86DisplayOff */ + /* 246, 0x0f6 */ 0x1008FFB4, /* XF86WWAN */ + /* 247, 0x0f7 */ 0x1008FFB5, /* XF86RFKill */ +}; + +#if 0 /* Here is a script to generate the ExtendedLinuxKeycodeKeysyms table */ +#!/bin/bash + +function process_line +{ + sym=$(echo "$1" | awk '{print $3}') + code=$(echo "$1" | sed 's,.*_EVDEVK(\(0x[0-9A-Fa-f]*\)).*,\1,') + value=$(grep -E "#define ${sym}\s" -R /usr/include/X11 | awk '{print $3}') + printf " { 0x%.8X, 0x%.3x }, /* $sym */\n" $value $code +} + +grep -F "/* Use: " /usr/include/xkbcommon/xkbcommon-keysyms.h | grep -F _EVDEVK | while read line; do + process_line "$line" +done +#endif + +static const struct { + Uint32 keysym; + int linux_keycode; +} ExtendedLinuxKeycodeKeysyms[] = { + { 0x1008FF2C, 0x0a2 }, /* XF86XK_Eject */ + { 0x1008FF68, 0x0b5 }, /* XF86XK_New */ + { 0x0000FF66, 0x0b6 }, /* XK_Redo */ + { 0x1008FF4B, 0x0cc }, /* XF86XK_LaunchB */ + { 0x1008FF59, 0x0e3 }, /* XF86XK_Display */ + { 0x1008FF04, 0x0e4 }, /* XF86XK_KbdLightOnOff */ + { 0x1008FF06, 0x0e5 }, /* XF86XK_KbdBrightnessDown */ + { 0x1008FF05, 0x0e6 }, /* XF86XK_KbdBrightnessUp */ + { 0x1008FF7B, 0x0e7 }, /* XF86XK_Send */ + { 0x1008FF72, 0x0e8 }, /* XF86XK_Reply */ + { 0x1008FF90, 0x0e9 }, /* XF86XK_MailForward */ + { 0x1008FF77, 0x0ea }, /* XF86XK_Save */ + { 0x1008FF5B, 0x0eb }, /* XF86XK_Documents */ + { 0x1008FF93, 0x0ec }, /* XF86XK_Battery */ + { 0x1008FF94, 0x0ed }, /* XF86XK_Bluetooth */ + { 0x1008FF95, 0x0ee }, /* XF86XK_WLAN */ + { 0x1008FF96, 0x0ef }, /* XF86XK_UWB */ + { 0x1008FE22, 0x0f1 }, /* XF86XK_Next_VMode */ + { 0x1008FE23, 0x0f2 }, /* XF86XK_Prev_VMode */ + { 0x1008FF07, 0x0f3 }, /* XF86XK_MonBrightnessCycle */ + { 0x1008FFB4, 0x0f6 }, /* XF86XK_WWAN */ + { 0x1008FFB5, 0x0f7 }, /* XF86XK_RFKill */ + { 0x1008FFB2, 0x0f8 }, /* XF86XK_AudioMicMute */ + { 0x1008FF9C, 0x173 }, /* XF86XK_CycleAngle */ + { 0x1008FFB8, 0x174 }, /* XF86XK_FullScreen */ + { 0x1008FF87, 0x189 }, /* XF86XK_Video */ + { 0x1008FF20, 0x18d }, /* XF86XK_Calendar */ + { 0x1008FF99, 0x19a }, /* XF86XK_AudioRandomPlay */ + { 0x1008FF5E, 0x1a1 }, /* XF86XK_Game */ + { 0x1008FF8B, 0x1a2 }, /* XF86XK_ZoomIn */ + { 0x1008FF8C, 0x1a3 }, /* XF86XK_ZoomOut */ + { 0x1008FF89, 0x1a5 }, /* XF86XK_Word */ + { 0x1008FF5C, 0x1a7 }, /* XF86XK_Excel */ + { 0x1008FF69, 0x1ab }, /* XF86XK_News */ + { 0x1008FF8E, 0x1ae }, /* XF86XK_Messenger */ + { 0x1008FF61, 0x1b1 }, /* XF86XK_LogOff */ + { 0x00000024, 0x1b2 }, /* XK_dollar */ + { 0x000020AC, 0x1b3 }, /* XK_EuroSign */ + { 0x1008FF9D, 0x1b4 }, /* XF86XK_FrameBack */ + { 0x1008FF9E, 0x1b5 }, /* XF86XK_FrameForward */ + { 0x0000FFF1, 0x1f1 }, /* XK_braille_dot_1 */ + { 0x0000FFF2, 0x1f2 }, /* XK_braille_dot_2 */ + { 0x0000FFF3, 0x1f3 }, /* XK_braille_dot_3 */ + { 0x0000FFF4, 0x1f4 }, /* XK_braille_dot_4 */ + { 0x0000FFF5, 0x1f5 }, /* XK_braille_dot_5 */ + { 0x0000FFF6, 0x1f6 }, /* XK_braille_dot_6 */ + { 0x0000FFF7, 0x1f7 }, /* XK_braille_dot_7 */ + { 0x0000FFF8, 0x1f8 }, /* XK_braille_dot_8 */ + { 0x0000FFF9, 0x1f9 }, /* XK_braille_dot_9 */ + { 0x0000FFF1, 0x1fa }, /* XK_braille_dot_1 */ + { 0x1008FFA9, 0x212 }, /* XF86XK_TouchpadToggle */ + { 0x1008FFB0, 0x213 }, /* XF86XK_TouchpadOn */ + { 0x1008FFB1, 0x214 }, /* XF86XK_TouchpadOff */ + { 0x1008FFB7, 0x231 }, /* XF86XK_RotationLockToggle */ + { 0x0000FE08, 0x248 }, /* XK_ISO_Next_Group */ +}; +/* *INDENT-ON* */ /* clang-format on */ + +SDL_Scancode SDL_GetScancodeFromKeySym(Uint32 keysym, Uint32 keycode) +{ + int i; + Uint32 linux_keycode = 0; + + /* First check our custom list */ + for (i = 0; i < SDL_arraysize(KeySymToSDLScancode); ++i) { + if (keysym == KeySymToSDLScancode[i].keysym) { + return KeySymToSDLScancode[i].scancode; + } + } + + if (keysym >= 0x41 && keysym <= 0x5a) { + /* Normalize alphabetic keysyms to the lowercase form */ + keysym += 0x20; + } else if (keysym >= 0x10081000 && keysym <= 0x10081FFF) { + /* The rest of the keysyms map to Linux keycodes, so use that mapping + * Per xkbcommon-keysyms.h, this is actually a linux keycode. + */ + linux_keycode = (keysym - 0x10081000); + } + if (!linux_keycode) { + /* See if this keysym is an exact match in our table */ + i = (keycode - 8); + if (i >= 0 && i < SDL_arraysize(LinuxKeycodeKeysyms) && keysym == LinuxKeycodeKeysyms[i]) { + linux_keycode = i; + } else { + /* Scan the table for this keysym */ + for (i = 0; i < SDL_arraysize(LinuxKeycodeKeysyms); ++i) { + if (keysym == LinuxKeycodeKeysyms[i]) { + linux_keycode = i; + break; + } + } + } + } + if (!linux_keycode) { + /* Scan the extended table for this keysym */ + for (i = 0; i < SDL_arraysize(ExtendedLinuxKeycodeKeysyms); ++i) { + if (keysym == ExtendedLinuxKeycodeKeysyms[i].keysym) { + linux_keycode = ExtendedLinuxKeycodeKeysyms[i].linux_keycode; + break; + } + } + } + return SDL_GetScancodeFromTable(SDL_SCANCODE_TABLE_LINUX, linux_keycode); +} + +#endif /* SDL_VIDEO_DRIVER_WAYLAND */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/events/SDL_keysym_to_scancode_c.h b/SDL2-2.30.5/src/events/SDL_keysym_to_scancode_c.h new file mode 100644 index 0000000..11e2d37 --- /dev/null +++ b/SDL2-2.30.5/src/events/SDL_keysym_to_scancode_c.h @@ -0,0 +1,32 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#ifndef SDL_keysym_to_scancode_c_h_ +#define SDL_keysym_to_scancode_c_h_ + +#include "SDL_scancode.h" + +/* This function only correctly maps letters and numbers for keyboards in US QWERTY layout */ +extern SDL_Scancode SDL_GetScancodeFromKeySym(Uint32 keysym, Uint32 keycode); + +#endif /* SDL_keysym_to_scancode_c_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/events/SDL_mouse.c b/SDL2-2.30.5/src/events/SDL_mouse.c similarity index 51% rename from SDL2-2.0.12/src/events/SDL_mouse.c rename to SDL2-2.30.5/src/events/SDL_mouse.c index 5d6f7dc..b133832 100644 --- a/SDL2-2.0.12/src/events/SDL_mouse.c +++ b/SDL2-2.30.5/src/events/SDL_mouse.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -22,15 +22,18 @@ /* General mouse handling code for SDL */ -#include "SDL_assert.h" #include "SDL_hints.h" #include "SDL_timer.h" #include "SDL_events.h" #include "SDL_events_c.h" #include "../SDL_hints_c.h" #include "../video/SDL_sysvideo.h" -#ifdef __WIN32__ -#include "../core/windows/SDL_windows.h" // For GetDoubleClickTime() +#if defined(__WIN32__) || defined(__GDK__) +#include "../core/windows/SDL_windows.h" // For GetDoubleClickTime() +#endif +#if defined(__OS2__) +#define INCL_WIN +#include #endif /* #define DEBUG_MOUSE */ @@ -41,71 +44,98 @@ static SDL_Mouse SDL_mouse; /* for mapping mouse events to touch */ static SDL_bool track_mouse_down = SDL_FALSE; -static int -SDL_PrivateSendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relative, int x, int y); +static int SDL_PrivateSendMouseMotion(SDL_Window *window, SDL_MouseID mouseID, int relative, int x, int y); -static void SDLCALL -SDL_MouseDoubleClickTimeChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +static void SDLCALL SDL_MouseDoubleClickTimeChanged(void *userdata, const char *name, const char *oldValue, const char *hint) { SDL_Mouse *mouse = (SDL_Mouse *)userdata; if (hint && *hint) { mouse->double_click_time = SDL_atoi(hint); } else { -#ifdef __WIN32__ +#if defined(__WIN32__) || defined(__WINGDK__) mouse->double_click_time = GetDoubleClickTime(); +#elif defined(__OS2__) + mouse->double_click_time = WinQuerySysValue(HWND_DESKTOP, SV_DBLCLKTIME); #else mouse->double_click_time = 500; #endif } } -static void SDLCALL -SDL_MouseDoubleClickRadiusChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +static void SDLCALL SDL_MouseDoubleClickRadiusChanged(void *userdata, const char *name, const char *oldValue, const char *hint) { SDL_Mouse *mouse = (SDL_Mouse *)userdata; if (hint && *hint) { mouse->double_click_radius = SDL_atoi(hint); } else { - mouse->double_click_radius = 32; /* 32 pixels seems about right for touch interfaces */ + mouse->double_click_radius = 32; /* 32 pixels seems about right for touch interfaces */ } } -static void SDLCALL -SDL_MouseNormalSpeedScaleChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +static void SDLCALL SDL_MouseNormalSpeedScaleChanged(void *userdata, const char *name, const char *oldValue, const char *hint) { SDL_Mouse *mouse = (SDL_Mouse *)userdata; if (hint && *hint) { + mouse->enable_normal_speed_scale = SDL_TRUE; mouse->normal_speed_scale = (float)SDL_atof(hint); } else { + mouse->enable_normal_speed_scale = SDL_FALSE; mouse->normal_speed_scale = 1.0f; } } -static void SDLCALL -SDL_MouseRelativeSpeedScaleChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +static void SDLCALL SDL_MouseRelativeSpeedScaleChanged(void *userdata, const char *name, const char *oldValue, const char *hint) { SDL_Mouse *mouse = (SDL_Mouse *)userdata; if (hint && *hint) { + mouse->enable_relative_speed_scale = SDL_TRUE; mouse->relative_speed_scale = (float)SDL_atof(hint); } else { + mouse->enable_relative_speed_scale = SDL_FALSE; mouse->relative_speed_scale = 1.0f; } } -static void SDLCALL -SDL_TouchMouseEventsChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +static void SDLCALL SDL_MouseRelativeSystemScaleChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + SDL_Mouse *mouse = (SDL_Mouse *)userdata; + + mouse->enable_relative_system_scale = SDL_GetStringBoolean(hint, SDL_FALSE); +} + +static void SDLCALL SDL_TouchMouseEventsChanged(void *userdata, const char *name, const char *oldValue, const char *hint) { SDL_Mouse *mouse = (SDL_Mouse *)userdata; mouse->touch_mouse_events = SDL_GetStringBoolean(hint, SDL_TRUE); } -static void SDLCALL -SDL_MouseTouchEventsChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +#if defined(__vita__) +static void SDLCALL SDL_VitaTouchMouseDeviceChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + SDL_Mouse *mouse = (SDL_Mouse *)userdata; + if (hint) { + switch (*hint) { + default: + case '0': + mouse->vita_touch_mouse_device = 0; + break; + case '1': + mouse->vita_touch_mouse_device = 1; + break; + case '2': + mouse->vita_touch_mouse_device = 2; + break; + } + } +} +#endif + +static void SDLCALL SDL_MouseTouchEventsChanged(void *userdata, const char *name, const char *oldValue, const char *hint) { SDL_Mouse *mouse = (SDL_Mouse *)userdata; SDL_bool default_value; @@ -122,9 +152,33 @@ SDL_MouseTouchEventsChanged(void *userdata, const char *name, const char *oldVal } } +static void SDLCALL SDL_MouseAutoCaptureChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + SDL_Mouse *mouse = (SDL_Mouse *)userdata; + SDL_bool auto_capture = SDL_GetStringBoolean(hint, SDL_TRUE); + + if (auto_capture != mouse->auto_capture) { + mouse->auto_capture = auto_capture; + SDL_UpdateMouseCapture(SDL_FALSE); + } +} + +static void SDLCALL SDL_MouseRelativeWarpMotionChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + SDL_Mouse *mouse = (SDL_Mouse *)userdata; + + mouse->relative_mode_warp_motion = SDL_GetStringBoolean(hint, SDL_FALSE); +} + +static void SDLCALL SDL_MouseRelativeCursorVisibleChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + SDL_Mouse *mouse = (SDL_Mouse *)userdata; + + mouse->relative_mode_cursor_visible = SDL_GetStringBoolean(hint, SDL_FALSE); +} + /* Public functions */ -int -SDL_MouseInit(void) +int SDL_MousePreInit(void) { SDL_Mouse *mouse = SDL_GetMouse(); @@ -142,65 +196,146 @@ SDL_MouseInit(void) SDL_AddHintCallback(SDL_HINT_MOUSE_RELATIVE_SPEED_SCALE, SDL_MouseRelativeSpeedScaleChanged, mouse); + SDL_AddHintCallback(SDL_HINT_MOUSE_RELATIVE_SYSTEM_SCALE, + SDL_MouseRelativeSystemScaleChanged, mouse); + SDL_AddHintCallback(SDL_HINT_TOUCH_MOUSE_EVENTS, SDL_TouchMouseEventsChanged, mouse); +#if defined(__vita__) + SDL_AddHintCallback(SDL_HINT_VITA_TOUCH_MOUSE_DEVICE, + SDL_VitaTouchMouseDeviceChanged, mouse); +#endif + SDL_AddHintCallback(SDL_HINT_MOUSE_TOUCH_EVENTS, SDL_MouseTouchEventsChanged, mouse); + SDL_AddHintCallback(SDL_HINT_MOUSE_AUTO_CAPTURE, + SDL_MouseAutoCaptureChanged, mouse); + + SDL_AddHintCallback(SDL_HINT_MOUSE_RELATIVE_WARP_MOTION, + SDL_MouseRelativeWarpMotionChanged, mouse); + + SDL_AddHintCallback(SDL_HINT_MOUSE_RELATIVE_CURSOR_VISIBLE, + SDL_MouseRelativeCursorVisibleChanged, mouse); + mouse->was_touch_mouse_events = SDL_FALSE; /* no touch to mouse movement event pending */ mouse->cursor_shown = SDL_TRUE; - return (0); + return 0; } -void -SDL_SetDefaultCursor(SDL_Cursor * cursor) +void SDL_MousePostInit(void) { SDL_Mouse *mouse = SDL_GetMouse(); + /* Create a dummy mouse cursor for video backends that don't support true cursors, + * so that mouse grab and focus functionality will work. + */ + if (!mouse->def_cursor) { + SDL_Surface *surface = SDL_CreateRGBSurface(0, 1, 1, 32, 0xFF, 0xFF, 0xFF, 0xFF); + if (surface) { + SDL_memset(surface->pixels, 0, (size_t)surface->h * surface->pitch); + SDL_SetDefaultCursor(SDL_CreateColorCursor(surface, 0, 0)); + SDL_FreeSurface(surface); + } + } +} + +void SDL_SetDefaultCursor(SDL_Cursor *cursor) +{ + SDL_Mouse *mouse = SDL_GetMouse(); + + if (cursor == mouse->def_cursor) { + return; + } + + if (mouse->def_cursor) { + SDL_Cursor *default_cursor = mouse->def_cursor; + SDL_Cursor *prev, *curr; + + if (mouse->cur_cursor == mouse->def_cursor) { + mouse->cur_cursor = NULL; + } + mouse->def_cursor = NULL; + + for (prev = NULL, curr = mouse->cursors; curr; + prev = curr, curr = curr->next) { + if (curr == default_cursor) { + if (prev) { + prev->next = curr->next; + } else { + mouse->cursors = curr->next; + } + + break; + } + } + + if (mouse->FreeCursor && default_cursor->driverdata) { + mouse->FreeCursor(default_cursor); + } else { + SDL_free(default_cursor); + } + } + mouse->def_cursor = cursor; + if (!mouse->cur_cursor) { SDL_SetCursor(cursor); } } -SDL_Mouse * -SDL_GetMouse(void) +SDL_Mouse *SDL_GetMouse(void) { return &SDL_mouse; } -SDL_Window * -SDL_GetMouseFocus(void) +static Uint32 GetButtonState(SDL_Mouse *mouse, SDL_bool include_touch) +{ + int i; + Uint32 buttonstate = 0; + + for (i = 0; i < mouse->num_sources; ++i) { + if (include_touch || mouse->sources[i].mouseID != SDL_TOUCH_MOUSEID) { + buttonstate |= mouse->sources[i].buttonstate; + } + } + return buttonstate; +} + +SDL_Window *SDL_GetMouseFocus(void) { SDL_Mouse *mouse = SDL_GetMouse(); return mouse->focus; } +/* TODO RECONNECT: Hello from the Wayland video driver! + * This was once removed from SDL, but it's been added back in comment form + * because we will need it when Wayland adds compositor reconnect support. + * If you need this before we do, great! Otherwise, leave this alone, we'll + * uncomment it at the right time. + * -flibit + */ #if 0 -void -SDL_ResetMouse(void) +void SDL_ResetMouse(void) { SDL_Mouse *mouse = SDL_GetMouse(); - Uint8 i; + Uint32 buttonState = GetButtonState(mouse, SDL_FALSE); + int i; -#ifdef DEBUG_MOUSE - printf("Resetting mouse\n"); -#endif - for (i = 1; i <= sizeof(mouse->buttonstate)*8; ++i) { - if (mouse->buttonstate & SDL_BUTTON(i)) { + for (i = 1; i <= sizeof(buttonState)*8; ++i) { + if (buttonState & SDL_BUTTON(i)) { SDL_SendMouseButton(mouse->focus, mouse->mouseID, SDL_RELEASED, i); } } - SDL_assert(mouse->buttonstate == 0); + SDL_assert(GetButtonState(mouse, SDL_FALSE) == 0); } -#endif +#endif /* 0 */ -void -SDL_SetMouseFocus(SDL_Window * window) +void SDL_SetMouseFocus(SDL_Window *window) { SDL_Mouse *mouse = SDL_GetMouse(); @@ -237,13 +372,12 @@ SDL_SetMouseFocus(SDL_Window * window) } /* Check to see if we need to synthesize focus events */ -static SDL_bool -SDL_UpdateMouseFocus(SDL_Window * window, int x, int y, Uint32 buttonstate, SDL_bool send_mouse_motion) +static SDL_bool SDL_UpdateMouseFocus(SDL_Window *window, int x, int y, Uint32 buttonstate, SDL_bool send_mouse_motion) { SDL_Mouse *mouse = SDL_GetMouse(); SDL_bool inWindow = SDL_TRUE; - if (window && ((window->flags & SDL_WINDOW_MOUSE_CAPTURE) == 0)) { + if (window && !(window->flags & SDL_WINDOW_MOUSE_CAPTURE)) { int w, h; SDL_GetWindowSize(window, &w, &h); if (x < 0 || y < 0 || x >= w || y >= h) { @@ -251,23 +385,10 @@ SDL_UpdateMouseFocus(SDL_Window * window, int x, int y, Uint32 buttonstate, SDL_ } } -/* Linux doesn't give you mouse events outside your window unless you grab - the pointer. - - Windows doesn't give you mouse events outside your window unless you call - SetCapture(). - - Both of these are slightly scary changes, so for now we'll punt and if the - mouse leaves the window you'll lose mouse focus and reset button state. -*/ -#ifdef SUPPORT_DRAG_OUTSIDE_WINDOW - if (!inWindow && !buttonstate) { -#else if (!inWindow) { -#endif if (window == mouse->focus) { #ifdef DEBUG_MOUSE - printf("Mouse left window, synthesizing move & focus lost event\n"); + SDL_Log("Mouse left window, synthesizing move & focus lost event\n"); #endif if (send_mouse_motion) { SDL_PrivateSendMouseMotion(window, mouse->mouseID, 0, x, y); @@ -279,7 +400,7 @@ SDL_UpdateMouseFocus(SDL_Window * window, int x, int y, Uint32 buttonstate, SDL_ if (window != mouse->focus) { #ifdef DEBUG_MOUSE - printf("Mouse entered window, synthesizing focus gain & move event\n"); + SDL_Log("Mouse entered window, synthesizing focus gain & move event\n"); #endif SDL_SetMouseFocus(window); if (send_mouse_motion) { @@ -289,12 +410,11 @@ SDL_UpdateMouseFocus(SDL_Window * window, int x, int y, Uint32 buttonstate, SDL_ return SDL_TRUE; } -int -SDL_SendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relative, int x, int y) +int SDL_SendMouseMotion(SDL_Window *window, SDL_MouseID mouseID, int relative, int x, int y) { if (window && !relative) { SDL_Mouse *mouse = SDL_GetMouse(); - if (!SDL_UpdateMouseFocus(window, x, y, mouse->buttonstate, (mouseID == SDL_TOUCH_MOUSEID) ? SDL_FALSE : SDL_TRUE)) { + if (!SDL_UpdateMouseFocus(window, x, y, GetButtonState(mouse, SDL_TRUE), (mouseID == SDL_TOUCH_MOUSEID) ? SDL_FALSE : SDL_TRUE)) { return 0; } } @@ -302,10 +422,12 @@ SDL_SendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relative, int return SDL_PrivateSendMouseMotion(window, mouseID, relative, x, y); } -static int -GetScaledMouseDelta(float scale, int value, float *accum) +static int GetScaledMouseDelta(float scale, int value, float *accum) { - if (scale != 1.0f) { + if (value && scale != 1.0f) { + if ((value > 0) != (*accum > 0)) { + *accum = 0.0f; + } *accum += scale * value; if (*accum >= 0.0f) { value = (int)SDL_floor(*accum); @@ -317,13 +439,103 @@ GetScaledMouseDelta(float scale, int value, float *accum) return value; } -static int -SDL_PrivateSendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relative, int x, int y) +static float CalculateSystemScale(SDL_Mouse *mouse, const int *x, const int *y) +{ + int i; + int n = mouse->num_system_scale_values; + float *v = mouse->system_scale_values; + float speed, coef, scale; + + /* If we're using a single scale value, return that */ + if (n == 1) { + return v[0]; + } + + speed = SDL_sqrtf((float)(*x * *x) + (*y * *y)); + for (i = 0; i < (n - 2); i += 2) { + if (speed < v[i + 2]) { + break; + } + } + if (i == (n - 2)) { + scale = v[n - 1]; + } else if (speed <= v[i]) { + scale = v[i + 1]; + } else { + coef = (speed - v[i]) / (v[i + 2] - v[i]); + scale = v[i + 1] + (coef * (v[i + 3] - v[i + 1])); + } + SDL_Log("speed = %.2f, scale = %.2f\n", speed, scale); + return scale; +} + +/* You can set either a single scale, or a set of {speed, scale} values in ascending order */ +int SDL_SetMouseSystemScale(int num_values, const float *values) +{ + SDL_Mouse *mouse = SDL_GetMouse(); + float *v; + + if (num_values == mouse->num_system_scale_values && + SDL_memcmp(values, mouse->system_scale_values, num_values * sizeof(*values)) == 0) { + /* Nothing has changed */ + return 0; + } + + if (num_values < 1) { + return SDL_SetError("You must have at least one scale value"); + } + + if (num_values > 1) { + /* Validate the values */ + int i; + + if (num_values < 4 || (num_values % 2) != 0) { + return SDL_SetError("You must pass a set of {speed, scale} values"); + } + + for (i = 0; i < (num_values - 2); i += 2) { + if (values[i] >= values[i + 2]) { + return SDL_SetError("Speed values must be in ascending order"); + } + } + } + + v = (float *)SDL_realloc(mouse->system_scale_values, num_values * sizeof(*values)); + if (!v) { + return SDL_OutOfMemory(); + } + SDL_memcpy(v, values, num_values * sizeof(*values)); + + mouse->num_system_scale_values = num_values; + mouse->system_scale_values = v; + return 0; +} + +static void GetScaledMouseDeltas(SDL_Mouse *mouse, int *x, int *y) +{ + if (mouse->relative_mode) { + if (mouse->enable_relative_speed_scale) { + *x = GetScaledMouseDelta(mouse->relative_speed_scale, *x, &mouse->scale_accum_x); + *y = GetScaledMouseDelta(mouse->relative_speed_scale, *y, &mouse->scale_accum_y); + } else if (mouse->enable_relative_system_scale && mouse->num_system_scale_values > 0) { + float relative_system_scale = CalculateSystemScale(mouse, x, y); + *x = GetScaledMouseDelta(relative_system_scale, *x, &mouse->scale_accum_x); + *y = GetScaledMouseDelta(relative_system_scale, *y, &mouse->scale_accum_y); + } + } else { + if (mouse->enable_normal_speed_scale) { + *x = GetScaledMouseDelta(mouse->normal_speed_scale, *x, &mouse->scale_accum_x); + *y = GetScaledMouseDelta(mouse->normal_speed_scale, *y, &mouse->scale_accum_y); + } + } +} + +static int SDL_PrivateSendMouseMotion(SDL_Window *window, SDL_MouseID mouseID, int relative, int x, int y) { SDL_Mouse *mouse = SDL_GetMouse(); int posted; - int xrel; - int yrel; + int xrel = 0; + int yrel = 0; /* SDL_HINT_MOUSE_TOUCH_EVENTS: controlling whether mouse events should generate synthetic touch events */ if (mouse->mouse_touch_events) { @@ -351,42 +563,45 @@ SDL_PrivateSendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relativ if (x == center_x && y == center_y) { mouse->last_x = center_x; mouse->last_y = center_y; - return 0; + if (!mouse->relative_mode_warp_motion) { + return 0; + } + } else { + if (window && (window->flags & SDL_WINDOW_INPUT_FOCUS)) { + if (mouse->WarpMouse) { + mouse->WarpMouse(window, center_x, center_y); + } else { + SDL_PrivateSendMouseMotion(window, mouseID, 0, center_x, center_y); + } + } } - SDL_WarpMouseInWindow(window, center_x, center_y); } if (relative) { - if (mouse->relative_mode) { - x = GetScaledMouseDelta(mouse->relative_speed_scale, x, &mouse->scale_accum_x); - y = GetScaledMouseDelta(mouse->relative_speed_scale, y, &mouse->scale_accum_y); - } else { - x = GetScaledMouseDelta(mouse->normal_speed_scale, x, &mouse->scale_accum_x); - y = GetScaledMouseDelta(mouse->normal_speed_scale, y, &mouse->scale_accum_y); - } + GetScaledMouseDeltas(mouse, &x, &y); xrel = x; yrel = y; x = (mouse->last_x + xrel); y = (mouse->last_y + yrel); - } else { + } else if (mouse->has_position) { xrel = x - mouse->last_x; yrel = y - mouse->last_y; } /* Ignore relative motion when first positioning the mouse */ if (!mouse->has_position) { - xrel = 0; - yrel = 0; + mouse->x = x; + mouse->y = y; mouse->has_position = SDL_TRUE; - } else if (!xrel && !yrel) { /* Drop events that don't change state */ + } else if (!xrel && !yrel) { /* Drop events that don't change state */ #ifdef DEBUG_MOUSE - printf("Mouse event didn't change state - dropped!\n"); + SDL_Log("Mouse event didn't change state - dropped!\n"); #endif return 0; } /* Ignore relative motion positioning the first touch */ - if (mouseID == SDL_TOUCH_MOUSEID && !mouse->buttonstate) { + if (mouseID == SDL_TOUCH_MOUSEID && !GetButtonState(mouse, SDL_TRUE)) { xrel = 0; yrel = 0; } @@ -402,26 +617,43 @@ SDL_PrivateSendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relativ /* make sure that the pointers find themselves inside the windows, unless we have the mouse captured. */ - if (window && ((window->flags & SDL_WINDOW_MOUSE_CAPTURE) == 0)) { - int x_max = 0, y_max = 0; + if (window && !(window->flags & SDL_WINDOW_MOUSE_CAPTURE)) { + int x_min = 0, x_max = 0; + int y_min = 0, y_max = 0; + const SDL_Rect *confine = SDL_GetWindowMouseRect(window); - /* !!! FIXME: shouldn't this be (window) instead of (mouse->focus)? */ - SDL_GetWindowSize(mouse->focus, &x_max, &y_max); + SDL_GetWindowSize(window, &x_max, &y_max); --x_max; --y_max; + if (confine) { + SDL_Rect window_rect; + SDL_Rect mouse_rect; + + window_rect.x = 0; + window_rect.y = 0; + window_rect.w = x_max + 1; + window_rect.h = y_max + 1; + if (SDL_IntersectRect(confine, &window_rect, &mouse_rect)) { + x_min = mouse_rect.x; + y_min = mouse_rect.y; + x_max = x_min + mouse_rect.w - 1; + y_max = y_min + mouse_rect.h - 1; + } + } + if (mouse->x > x_max) { mouse->x = x_max; } - if (mouse->x < 0) { - mouse->x = 0; + if (mouse->x < x_min) { + mouse->x = x_min; } if (mouse->y > y_max) { mouse->y = y_max; } - if (mouse->y < 0) { - mouse->y = 0; + if (mouse->y < y_min) { + mouse->y = y_min; } } @@ -442,8 +674,8 @@ SDL_PrivateSendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relativ event.motion.windowID = mouse->focus ? mouse->focus->id : 0; event.motion.which = mouseID; /* Set us pending (or clear during a normal mouse movement event) as having triggered */ - mouse->was_touch_mouse_events = (mouseID == SDL_TOUCH_MOUSEID)? SDL_TRUE : SDL_FALSE; - event.motion.state = mouse->buttonstate; + mouse->was_touch_mouse_events = (mouseID == SDL_TOUCH_MOUSEID) ? SDL_TRUE : SDL_FALSE; + event.motion.state = GetButtonState(mouse, SDL_TRUE); event.motion.x = mouse->x; event.motion.y = mouse->y; event.motion.xrel = xrel; @@ -461,6 +693,30 @@ SDL_PrivateSendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relativ return posted; } +static SDL_MouseInputSource *GetMouseInputSource(SDL_Mouse *mouse, SDL_MouseID mouseID) +{ + SDL_MouseInputSource *source, *sources; + int i; + + for (i = 0; i < mouse->num_sources; ++i) { + source = &mouse->sources[i]; + if (source->mouseID == mouseID) { + return source; + } + } + + sources = (SDL_MouseInputSource *)SDL_realloc(mouse->sources, (mouse->num_sources + 1) * sizeof(*mouse->sources)); + if (sources) { + mouse->sources = sources; + ++mouse->num_sources; + source = &sources[mouse->num_sources - 1]; + source->mouseID = mouseID; + source->buttonstate = 0; + return source; + } + return NULL; +} + static SDL_MouseClickState *GetMouseClickState(SDL_Mouse *mouse, Uint8 button) { if (button >= mouse->num_clickstates) { @@ -479,13 +735,19 @@ static SDL_MouseClickState *GetMouseClickState(SDL_Mouse *mouse, Uint8 button) return &mouse->clickstate[button]; } -static int -SDL_PrivateSendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state, Uint8 button, int clicks) +static int SDL_PrivateSendMouseButton(SDL_Window *window, SDL_MouseID mouseID, Uint8 state, Uint8 button, int clicks) { SDL_Mouse *mouse = SDL_GetMouse(); int posted; Uint32 type; - Uint32 buttonstate = mouse->buttonstate; + Uint32 buttonstate; + SDL_MouseInputSource *source; + + source = GetMouseInputSource(mouse, mouseID); + if (!source) { + return 0; + } + buttonstate = source->buttonstate; /* SDL_HINT_MOUSE_TOUCH_EVENTS: controlling whether mouse events should generate synthetic touch events */ if (mouse->mouse_touch_events) { @@ -530,11 +792,11 @@ SDL_PrivateSendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state SDL_UpdateMouseFocus(window, mouse->x, mouse->y, buttonstate, SDL_TRUE); } - if (buttonstate == mouse->buttonstate) { + if (buttonstate == source->buttonstate) { /* Ignore this event, no state change */ return 0; } - mouse->buttonstate = buttonstate; + source->buttonstate = buttonstate; if (clicks < 0) { SDL_MouseClickState *clickstate = GetMouseClickState(mouse, button); @@ -569,7 +831,7 @@ SDL_PrivateSendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state event.button.which = mouseID; event.button.state = state; event.button.button = button; - event.button.clicks = (Uint8) SDL_min(clicks, 255); + event.button.clicks = (Uint8)SDL_min(clicks, 255); event.button.x = mouse->x; event.button.y = mouse->y; posted = (SDL_PushEvent(&event) > 0); @@ -580,24 +842,26 @@ SDL_PrivateSendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state SDL_UpdateMouseFocus(window, mouse->x, mouse->y, buttonstate, SDL_TRUE); } + /* Automatically capture the mouse while buttons are pressed */ + if (mouse->auto_capture) { + SDL_UpdateMouseCapture(SDL_FALSE); + } + return posted; } -int -SDL_SendMouseButtonClicks(SDL_Window * window, SDL_MouseID mouseID, Uint8 state, Uint8 button, int clicks) +int SDL_SendMouseButtonClicks(SDL_Window *window, SDL_MouseID mouseID, Uint8 state, Uint8 button, int clicks) { clicks = SDL_max(clicks, 0); return SDL_PrivateSendMouseButton(window, mouseID, state, button, clicks); } -int -SDL_SendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state, Uint8 button) +int SDL_SendMouseButton(SDL_Window *window, SDL_MouseID mouseID, Uint8 state, Uint8 button) { return SDL_PrivateSendMouseButton(window, mouseID, state, button, -1); } -int -SDL_SendMouseWheel(SDL_Window * window, SDL_MouseID mouseID, float x, float y, SDL_MouseWheelDirection direction) +int SDL_SendMouseWheel(SDL_Window *window, SDL_MouseID mouseID, float x, float y, SDL_MouseWheelDirection direction) { SDL_Mouse *mouse = SDL_GetMouse(); int posted; @@ -611,20 +875,38 @@ SDL_SendMouseWheel(SDL_Window * window, SDL_MouseID mouseID, float x, float y, S return 0; } + if (x > 0.0f) { + if (mouse->accumulated_wheel_x < 0.0f) { + mouse->accumulated_wheel_x = 0.0f; + } + } else if (x < 0.0f) { + if (mouse->accumulated_wheel_x > 0.0f) { + mouse->accumulated_wheel_x = 0.0f; + } + } mouse->accumulated_wheel_x += x; - if (mouse->accumulated_wheel_x > 0) { + if (mouse->accumulated_wheel_x > 0.0f) { integral_x = (int)SDL_floor(mouse->accumulated_wheel_x); - } else if (mouse->accumulated_wheel_x < 0) { + } else if (mouse->accumulated_wheel_x < 0.0f) { integral_x = (int)SDL_ceil(mouse->accumulated_wheel_x); } else { integral_x = 0; } mouse->accumulated_wheel_x -= integral_x; + if (y > 0.0f) { + if (mouse->accumulated_wheel_y < 0.0f) { + mouse->accumulated_wheel_y = 0.0f; + } + } else if (y < 0.0f) { + if (mouse->accumulated_wheel_y > 0.0f) { + mouse->accumulated_wheel_y = 0.0f; + } + } mouse->accumulated_wheel_y += y; - if (mouse->accumulated_wheel_y > 0) { + if (mouse->accumulated_wheel_y > 0.0f) { integral_y = (int)SDL_floor(mouse->accumulated_wheel_y); - } else if (mouse->accumulated_wheel_y < 0) { + } else if (mouse->accumulated_wheel_y < 0.0f) { integral_y = (int)SDL_ceil(mouse->accumulated_wheel_y); } else { integral_y = 0; @@ -638,26 +920,26 @@ SDL_SendMouseWheel(SDL_Window * window, SDL_MouseID mouseID, float x, float y, S event.type = SDL_MOUSEWHEEL; event.wheel.windowID = mouse->focus ? mouse->focus->id : 0; event.wheel.which = mouseID; -#if 0 /* Uncomment this when it goes in for SDL 2.1 */ - event.wheel.preciseX = x; - event.wheel.preciseY = y; -#endif event.wheel.x = integral_x; event.wheel.y = integral_y; + event.wheel.preciseX = x; + event.wheel.preciseY = y; event.wheel.direction = (Uint32)direction; + event.wheel.mouseX = mouse->x; + event.wheel.mouseY = mouse->y; posted = (SDL_PushEvent(&event) > 0); } return posted; } -void -SDL_MouseQuit(void) +void SDL_MouseQuit(void) { SDL_Cursor *cursor, *next; SDL_Mouse *mouse = SDL_GetMouse(); if (mouse->CaptureMouse) { SDL_CaptureMouse(SDL_FALSE); + SDL_UpdateMouseCapture(SDL_TRUE); } SDL_SetRelativeMouseMode(SDL_FALSE); SDL_ShowCursor(1); @@ -676,20 +958,56 @@ SDL_MouseQuit(void) mouse->def_cursor = NULL; } + if (mouse->sources) { + SDL_free(mouse->sources); + mouse->sources = NULL; + } + mouse->num_sources = 0; + if (mouse->clickstate) { SDL_free(mouse->clickstate); mouse->clickstate = NULL; } + mouse->num_clickstates = 0; + + if (mouse->system_scale_values) { + SDL_free(mouse->system_scale_values); + mouse->system_scale_values = NULL; + } + mouse->num_system_scale_values = 0; + + SDL_DelHintCallback(SDL_HINT_MOUSE_DOUBLE_CLICK_TIME, + SDL_MouseDoubleClickTimeChanged, mouse); + + SDL_DelHintCallback(SDL_HINT_MOUSE_DOUBLE_CLICK_RADIUS, + SDL_MouseDoubleClickRadiusChanged, mouse); SDL_DelHintCallback(SDL_HINT_MOUSE_NORMAL_SPEED_SCALE, SDL_MouseNormalSpeedScaleChanged, mouse); SDL_DelHintCallback(SDL_HINT_MOUSE_RELATIVE_SPEED_SCALE, SDL_MouseRelativeSpeedScaleChanged, mouse); + + SDL_DelHintCallback(SDL_HINT_MOUSE_RELATIVE_SYSTEM_SCALE, + SDL_MouseRelativeSystemScaleChanged, mouse); + + SDL_DelHintCallback(SDL_HINT_TOUCH_MOUSE_EVENTS, + SDL_TouchMouseEventsChanged, mouse); + + SDL_DelHintCallback(SDL_HINT_MOUSE_TOUCH_EVENTS, + SDL_MouseTouchEventsChanged, mouse); + + SDL_DelHintCallback(SDL_HINT_MOUSE_AUTO_CAPTURE, + SDL_MouseAutoCaptureChanged, mouse); + + SDL_DelHintCallback(SDL_HINT_MOUSE_RELATIVE_WARP_MOTION, + SDL_MouseRelativeWarpMotionChanged, mouse); + + SDL_DelHintCallback(SDL_HINT_MOUSE_RELATIVE_CURSOR_VISIBLE, + SDL_MouseRelativeCursorVisibleChanged, mouse); } -Uint32 -SDL_GetMouseState(int *x, int *y) +Uint32 SDL_GetMouseState(int *x, int *y) { SDL_Mouse *mouse = SDL_GetMouse(); @@ -699,11 +1017,10 @@ SDL_GetMouseState(int *x, int *y) if (y) { *y = mouse->y; } - return mouse->buttonstate; + return GetButtonState(mouse, SDL_TRUE); } -Uint32 -SDL_GetRelativeMouseState(int *x, int *y) +Uint32 SDL_GetRelativeMouseState(int *x, int *y) { SDL_Mouse *mouse = SDL_GetMouse(); @@ -715,54 +1032,83 @@ SDL_GetRelativeMouseState(int *x, int *y) } mouse->xdelta = 0; mouse->ydelta = 0; - return mouse->buttonstate; + return GetButtonState(mouse, SDL_TRUE); } -Uint32 -SDL_GetGlobalMouseState(int *x, int *y) -{ - SDL_Mouse *mouse = SDL_GetMouse(); - int tmpx, tmpy; - - /* make sure these are never NULL for the backend implementations... */ - if (!x) { - x = &tmpx; - } - if (!y) { - y = &tmpy; - } - - *x = *y = 0; - - if (!mouse->GetGlobalMouseState) { - return 0; - } - - return mouse->GetGlobalMouseState(x, y); -} - -void -SDL_WarpMouseInWindow(SDL_Window * window, int x, int y) +Uint32 SDL_GetGlobalMouseState(int *x, int *y) { SDL_Mouse *mouse = SDL_GetMouse(); - if (window == NULL) { + if (mouse->GetGlobalMouseState) { + int tmpx, tmpy; + + /* make sure these are never NULL for the backend implementations... */ + if (!x) { + x = &tmpx; + } + if (!y) { + y = &tmpy; + } + + *x = *y = 0; + + return mouse->GetGlobalMouseState(x, y); + } else { + return SDL_GetMouseState(x, y); + } +} + +void SDL_PerformWarpMouseInWindow(SDL_Window *window, int x, int y, SDL_bool ignore_relative_mode) +{ + SDL_Mouse *mouse = SDL_GetMouse(); + + if (!window) { window = mouse->focus; } - if (window == NULL) { + if (!window) { return; } - if (mouse->WarpMouse) { + if ((window->flags & SDL_WINDOW_MINIMIZED) == SDL_WINDOW_MINIMIZED) { + return; + } + + /* Ignore the previous position when we warp */ + mouse->last_x = x; + mouse->last_y = y; + mouse->has_position = SDL_FALSE; + + if (mouse->relative_mode && !ignore_relative_mode) { + /* 2.0.22 made warping in relative mode actually functional, which + * surprised many applications that weren't expecting the additional + * mouse motion. + * + * So for now, warping in relative mode adjusts the absolution position + * but doesn't generate motion events, unless SDL_HINT_MOUSE_RELATIVE_WARP_MOTION is set. + */ + if (!mouse->relative_mode_warp_motion) { + mouse->x = x; + mouse->y = y; + mouse->has_position = SDL_TRUE; + return; + } + } + + if (mouse->WarpMouse && + (!mouse->relative_mode || mouse->relative_mode_warp)) { mouse->WarpMouse(window, x, y); } else { - SDL_SendMouseMotion(window, mouse->mouseID, 0, x, y); + SDL_PrivateSendMouseMotion(window, mouse->mouseID, 0, x, y); } } -int -SDL_WarpMouseGlobal(int x, int y) +void SDL_WarpMouseInWindow(SDL_Window *window, int x, int y) +{ + SDL_PerformWarpMouseInWindow(window, x, y, SDL_FALSE); +} + +int SDL_WarpMouseGlobal(int x, int y) { SDL_Mouse *mouse = SDL_GetMouse(); @@ -773,8 +1119,7 @@ SDL_WarpMouseGlobal(int x, int y) return SDL_Unsupported(); } -static SDL_bool -ShouldUseRelativeModeWarp(SDL_Mouse *mouse) +static SDL_bool ShouldUseRelativeModeWarp(SDL_Mouse *mouse) { if (!mouse->WarpMouse) { /* Need this functionality for relative mode warp implementation */ @@ -784,8 +1129,7 @@ ShouldUseRelativeModeWarp(SDL_Mouse *mouse) return SDL_GetHintBoolean(SDL_HINT_MOUSE_RELATIVE_MODE_WARP, SDL_FALSE); } -int -SDL_SetRelativeMouseMode(SDL_bool enabled) +int SDL_SetRelativeMouseMode(SDL_bool enabled) { SDL_Mouse *mouse = SDL_GetMouse(); SDL_Window *focusWindow = SDL_GetKeyboardFocus(); @@ -812,77 +1156,127 @@ SDL_SetRelativeMouseMode(SDL_bool enabled) mouse->scale_accum_x = 0.0f; mouse->scale_accum_y = 0.0f; - if (enabled && focusWindow) { - /* Center it in the focused window to prevent clicks from going through - * to background windows. - */ - SDL_SetMouseFocus(focusWindow); - SDL_WarpMouseInWindow(focusWindow, focusWindow->w/2, focusWindow->h/2); + if (enabled) { + /* Update cursor visibility before we potentially warp the mouse */ + SDL_SetCursor(NULL); } - if (mouse->focus) { - SDL_UpdateWindowGrab(mouse->focus); + if (enabled && focusWindow) { + SDL_SetMouseFocus(focusWindow); + + if (mouse->relative_mode_warp) { + SDL_PerformWarpMouseInWindow(focusWindow, focusWindow->w / 2, focusWindow->h / 2, SDL_TRUE); + } + } + + if (focusWindow) { + SDL_UpdateWindowGrab(focusWindow); /* Put the cursor back to where the application expects it */ if (!enabled) { - SDL_WarpMouseInWindow(mouse->focus, mouse->x, mouse->y); + SDL_PerformWarpMouseInWindow(focusWindow, mouse->x, mouse->y, SDL_TRUE); } + + SDL_UpdateMouseCapture(SDL_FALSE); + } + + if (!enabled) { + /* Update cursor visibility after we restore the mouse position */ + SDL_SetCursor(NULL); } /* Flush pending mouse motion - ideally we would pump events, but that's not always safe */ SDL_FlushEvent(SDL_MOUSEMOTION); - /* Update cursor visibility */ - SDL_SetCursor(NULL); - return 0; } -SDL_bool -SDL_GetRelativeMouseMode() +SDL_bool SDL_GetRelativeMouseMode(void) { SDL_Mouse *mouse = SDL_GetMouse(); return mouse->relative_mode; } -int -SDL_CaptureMouse(SDL_bool enabled) +int SDL_UpdateMouseCapture(SDL_bool force_release) +{ + SDL_Mouse *mouse = SDL_GetMouse(); + SDL_Window *capture_window = NULL; + + if (!mouse->CaptureMouse) { + return 0; + } + + if (!force_release) { + if (SDL_GetMessageBoxCount() == 0 && + (mouse->capture_desired || (mouse->auto_capture && GetButtonState(mouse, SDL_FALSE) != 0))) { + if (!mouse->relative_mode) { + capture_window = SDL_GetKeyboardFocus(); + } + } + } + + if (capture_window != mouse->capture_window) { + /* We can get here recursively on Windows, so make sure we complete + * all of the window state operations before we change the capture state + * (e.g. https://github.com/libsdl-org/SDL/pull/5608) + */ + SDL_Window *previous_capture = mouse->capture_window; + + if (previous_capture) { + previous_capture->flags &= ~SDL_WINDOW_MOUSE_CAPTURE; + } + + if (capture_window) { + capture_window->flags |= SDL_WINDOW_MOUSE_CAPTURE; + } + + mouse->capture_window = capture_window; + + if (mouse->CaptureMouse(capture_window) < 0) { + /* CaptureMouse() will have set an error, just restore the state */ + if (previous_capture) { + previous_capture->flags |= SDL_WINDOW_MOUSE_CAPTURE; + } + if (capture_window) { + capture_window->flags &= ~SDL_WINDOW_MOUSE_CAPTURE; + } + mouse->capture_window = previous_capture; + + return -1; + } + } + return 0; +} + +int SDL_CaptureMouse(SDL_bool enabled) { SDL_Mouse *mouse = SDL_GetMouse(); - SDL_Window *focusWindow; - SDL_bool isCaptured; if (!mouse->CaptureMouse) { return SDL_Unsupported(); } - focusWindow = SDL_GetKeyboardFocus(); - - isCaptured = focusWindow && (focusWindow->flags & SDL_WINDOW_MOUSE_CAPTURE); - if (isCaptured == enabled) { - return 0; /* already done! */ +#if defined(__WIN32__) || defined(__WINGDK__) + /* Windows mouse capture is tied to the current thread, and must be called + * from the thread that created the window being captured. Since we update + * the mouse capture state from the event processing, any application state + * changes must be processed on that thread as well. + */ + if (!SDL_OnVideoThread()) { + return SDL_SetError("SDL_CaptureMouse() must be called on the main thread"); } +#endif /* defined(__WIN32__) || defined(__WINGDK__) */ - if (enabled) { - if (!focusWindow) { - return SDL_SetError("No window has focus"); - } else if (mouse->CaptureMouse(focusWindow) == -1) { - return -1; /* CaptureMouse() should call SetError */ - } - focusWindow->flags |= SDL_WINDOW_MOUSE_CAPTURE; - } else { - if (mouse->CaptureMouse(NULL) == -1) { - return -1; /* CaptureMouse() should call SetError */ - } - focusWindow->flags &= ~SDL_WINDOW_MOUSE_CAPTURE; + if (enabled && SDL_GetKeyboardFocus() == NULL) { + return SDL_SetError("No window has focus"); } + mouse->capture_desired = enabled; - return 0; + return SDL_UpdateMouseCapture(SDL_FALSE); } -SDL_Cursor * -SDL_CreateCursor(const Uint8 * data, const Uint8 * mask, +SDL_Cursor *SDL_CreateCursor(const Uint8 *data, const Uint8 *mask, int w, int h, int hot_x, int hot_y) { SDL_Surface *surface; @@ -907,7 +1301,7 @@ SDL_CreateCursor(const Uint8 * data, const Uint8 * mask, return NULL; } for (y = 0; y < h; ++y) { - pixel = (Uint32 *) ((Uint8 *) surface->pixels + y * surface->pitch); + pixel = (Uint32 *)((Uint8 *)surface->pixels + y * surface->pitch); for (x = 0; x < w; ++x) { if ((x % 8) == 0) { datab = *data++; @@ -930,20 +1324,14 @@ SDL_CreateCursor(const Uint8 * data, const Uint8 * mask, return cursor; } -SDL_Cursor * -SDL_CreateColorCursor(SDL_Surface *surface, int hot_x, int hot_y) +SDL_Cursor *SDL_CreateColorCursor(SDL_Surface *surface, int hot_x, int hot_y) { SDL_Mouse *mouse = SDL_GetMouse(); SDL_Surface *temp = NULL; SDL_Cursor *cursor; if (!surface) { - SDL_SetError("Passed NULL cursor surface"); - return NULL; - } - - if (!mouse->CreateCursor) { - SDL_SetError("Cursors are not currently supported"); + SDL_InvalidParamError("surface"); return NULL; } @@ -962,7 +1350,15 @@ SDL_CreateColorCursor(SDL_Surface *surface, int hot_x, int hot_y) surface = temp; } - cursor = mouse->CreateCursor(surface, hot_x, hot_y); + if (mouse->CreateCursor) { + cursor = mouse->CreateCursor(surface, hot_x, hot_y); + } else { + cursor = SDL_calloc(1, sizeof(*cursor)); + if (!cursor) { + SDL_OutOfMemory(); + } + } + if (cursor) { cursor->next = mouse->cursors; mouse->cursors = cursor; @@ -973,8 +1369,7 @@ SDL_CreateColorCursor(SDL_Surface *surface, int hot_x, int hot_y) return cursor; } -SDL_Cursor * -SDL_CreateSystemCursor(SDL_SystemCursor id) +SDL_Cursor *SDL_CreateSystemCursor(SDL_SystemCursor id) { SDL_Mouse *mouse = SDL_GetMouse(); SDL_Cursor *cursor; @@ -997,11 +1392,15 @@ SDL_CreateSystemCursor(SDL_SystemCursor id) if this is desired for any reason. This is used when setting the video mode and when the SDL window gains the mouse focus. */ -void -SDL_SetCursor(SDL_Cursor * cursor) +void SDL_SetCursor(SDL_Cursor *cursor) { SDL_Mouse *mouse = SDL_GetMouse(); + /* Return immediately if setting the cursor to the currently set one (fixes #7151) */ + if (cursor == mouse->cur_cursor) { + return; + } + /* Set the new cursor */ if (cursor) { /* Make sure the cursor is still valid for this mouse */ @@ -1026,7 +1425,7 @@ SDL_SetCursor(SDL_Cursor * cursor) } } - if (cursor && mouse->cursor_shown && !mouse->relative_mode) { + if (cursor && mouse->cursor_shown && (!mouse->relative_mode || mouse->relative_mode_cursor_visible)) { if (mouse->ShowCursor) { mouse->ShowCursor(cursor); } @@ -1037,8 +1436,7 @@ SDL_SetCursor(SDL_Cursor * cursor) } } -SDL_Cursor * -SDL_GetCursor(void) +SDL_Cursor *SDL_GetCursor(void) { SDL_Mouse *mouse = SDL_GetMouse(); @@ -1048,8 +1446,7 @@ SDL_GetCursor(void) return mouse->cur_cursor; } -SDL_Cursor * -SDL_GetDefaultCursor(void) +SDL_Cursor *SDL_GetDefaultCursor(void) { SDL_Mouse *mouse = SDL_GetMouse(); @@ -1059,8 +1456,7 @@ SDL_GetDefaultCursor(void) return mouse->def_cursor; } -void -SDL_FreeCursor(SDL_Cursor * cursor) +void SDL_FreeCursor(SDL_Cursor *cursor) { SDL_Mouse *mouse = SDL_GetMouse(); SDL_Cursor *curr, *prev; @@ -1087,14 +1483,15 @@ SDL_FreeCursor(SDL_Cursor * cursor) if (mouse->FreeCursor) { mouse->FreeCursor(curr); + } else { + SDL_free(curr); } return; } } } -int -SDL_ShowCursor(int toggle) +int SDL_ShowCursor(int toggle) { SDL_Mouse *mouse = SDL_GetMouse(); SDL_bool shown; diff --git a/SDL2-2.0.12/src/events/SDL_mouse_c.h b/SDL2-2.30.5/src/events/SDL_mouse_c.h similarity index 56% rename from SDL2-2.0.12/src/events/SDL_mouse_c.h rename to SDL2-2.30.5/src/events/SDL_mouse_c.h index 2592dc7..db1c6c4 100644 --- a/SDL2-2.0.12/src/events/SDL_mouse_c.h +++ b/SDL2-2.30.5/src/events/SDL_mouse_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -33,6 +33,12 @@ struct SDL_Cursor void *driverdata; }; +typedef struct +{ + SDL_MouseID mouseID; + Uint32 buttonstate; +} SDL_MouseInputSource; + typedef struct { int last_x, last_y; @@ -43,34 +49,34 @@ typedef struct typedef struct { /* Create a cursor from a surface */ - SDL_Cursor *(*CreateCursor) (SDL_Surface * surface, int hot_x, int hot_y); + SDL_Cursor *(*CreateCursor)(SDL_Surface *surface, int hot_x, int hot_y); /* Create a system cursor */ - SDL_Cursor *(*CreateSystemCursor) (SDL_SystemCursor id); + SDL_Cursor *(*CreateSystemCursor)(SDL_SystemCursor id); /* Show the specified cursor, or hide if cursor is NULL */ - int (*ShowCursor) (SDL_Cursor * cursor); + int (*ShowCursor)(SDL_Cursor *cursor); /* This is called when a mouse motion event occurs */ - void (*MoveCursor) (SDL_Cursor * cursor); + void (*MoveCursor)(SDL_Cursor *cursor); /* Free a window manager cursor */ - void (*FreeCursor) (SDL_Cursor * cursor); + void (*FreeCursor)(SDL_Cursor *cursor); /* Warp the mouse to (x,y) within a window */ - void (*WarpMouse) (SDL_Window * window, int x, int y); + void (*WarpMouse)(SDL_Window *window, int x, int y); /* Warp the mouse to (x,y) in screen space */ - int (*WarpMouseGlobal) (int x, int y); + int (*WarpMouseGlobal)(int x, int y); /* Set relative mode */ - int (*SetRelativeMouseMode) (SDL_bool enabled); + int (*SetRelativeMouseMode)(SDL_bool enabled); /* Set mouse capture */ - int (*CaptureMouse) (SDL_Window * window); + int (*CaptureMouse)(SDL_Window *window); /* Get absolute mouse coordinates. (x) and (y) are never NULL and set to zero before call. */ - Uint32 (*GetGlobalMouseState) (int *x, int *y); + Uint32 (*GetGlobalMouseState)(int *x, int *y); /* Data common to all mice */ SDL_MouseID mouseID; @@ -79,15 +85,21 @@ typedef struct int y; int xdelta; int ydelta; - int last_x, last_y; /* the last reported x and y coordinates */ + int last_x, last_y; /* the last reported x and y coordinates */ float accumulated_wheel_x; float accumulated_wheel_y; - Uint32 buttonstate; SDL_bool has_position; SDL_bool relative_mode; SDL_bool relative_mode_warp; + SDL_bool relative_mode_warp_motion; + SDL_bool relative_mode_cursor_visible; + SDL_bool enable_normal_speed_scale; float normal_speed_scale; + SDL_bool enable_relative_speed_scale; float relative_speed_scale; + SDL_bool enable_relative_system_scale; + int num_system_scale_values; + float *system_scale_values; float scale_accum_x; float scale_accum_y; Uint32 double_click_time; @@ -95,6 +107,16 @@ typedef struct SDL_bool touch_mouse_events; SDL_bool mouse_touch_events; SDL_bool was_touch_mouse_events; /* Was a touch-mouse event pending? */ +#if defined(__vita__) + Uint8 vita_touch_mouse_device; +#endif + SDL_bool auto_capture; + SDL_bool capture_desired; + SDL_Window *capture_window; + + /* Data for input source state */ + int num_sources; + SDL_MouseInputSource *sources; /* Data for double-click tracking */ int num_clickstates; @@ -109,30 +131,44 @@ typedef struct void *driverdata; } SDL_Mouse; - /* Initialize the mouse subsystem */ -extern int SDL_MouseInit(void); +extern int SDL_MousePreInit(void); +extern void SDL_MousePostInit(void); /* Get the mouse state structure */ SDL_Mouse *SDL_GetMouse(void); /* Set the default mouse cursor */ -extern void SDL_SetDefaultCursor(SDL_Cursor * cursor); +extern void SDL_SetDefaultCursor(SDL_Cursor *cursor); /* Set the mouse focus window */ -extern void SDL_SetMouseFocus(SDL_Window * window); +extern void SDL_SetMouseFocus(SDL_Window *window); + +/* Update the mouse capture window */ +extern int SDL_UpdateMouseCapture(SDL_bool force_release); + +/* You can set either a single scale, or a set of {speed, scale} values in sorted order */ +extern int SDL_SetMouseSystemScale(int num_values, const float *values); /* Send a mouse motion event */ -extern int SDL_SendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relative, int x, int y); +extern int SDL_SendMouseMotion(SDL_Window *window, SDL_MouseID mouseID, int relative, int x, int y); /* Send a mouse button event */ -extern int SDL_SendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state, Uint8 button); +extern int SDL_SendMouseButton(SDL_Window *window, SDL_MouseID mouseID, Uint8 state, Uint8 button); /* Send a mouse button event with a click count */ -extern int SDL_SendMouseButtonClicks(SDL_Window * window, SDL_MouseID mouseID, Uint8 state, Uint8 button, int clicks); +extern int SDL_SendMouseButtonClicks(SDL_Window *window, SDL_MouseID mouseID, Uint8 state, Uint8 button, int clicks); /* Send a mouse wheel event */ -extern int SDL_SendMouseWheel(SDL_Window * window, SDL_MouseID mouseID, float x, float y, SDL_MouseWheelDirection direction); +extern int SDL_SendMouseWheel(SDL_Window *window, SDL_MouseID mouseID, float x, float y, SDL_MouseWheelDirection direction); + +/* Warp the mouse within the window, potentially overriding relative mode */ +extern void SDL_PerformWarpMouseInWindow(SDL_Window *window, int x, int y, SDL_bool ignore_relative_mode); + +/* TODO RECONNECT: Set mouse state to "zero" */ +#if 0 +extern void SDL_ResetMouse(void); +#endif /* 0 */ /* Shutdown the mouse subsystem */ extern void SDL_MouseQuit(void); diff --git a/SDL2-2.0.12/src/events/SDL_quit.c b/SDL2-2.30.5/src/events/SDL_quit.c similarity index 76% rename from SDL2-2.0.12/src/events/SDL_quit.c rename to SDL2-2.30.5/src/events/SDL_quit.c index 1260c1d..cd629a9 100644 --- a/SDL2-2.0.12/src/events/SDL_quit.c +++ b/SDL2-2.30.5/src/events/SDL_quit.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -19,8 +19,8 @@ 3. This notice may not be removed or altered from any source distribution. */ #include "../SDL_internal.h" + #include "SDL_hints.h" -#include "SDL_assert.h" /* General quit handling code for SDL */ @@ -47,66 +47,63 @@ static SDL_bool send_backgrounding_pending = SDL_FALSE; static SDL_bool send_foregrounding_pending = SDL_FALSE; #endif -static void -SDL_HandleSIG(int sig) +static void SDL_HandleSIG(int sig) { /* Reset the signal handler */ - signal(sig, SDL_HandleSIG); + (void)signal(sig, SDL_HandleSIG); /* Send a quit event next time the event loop pumps. */ - /* We can't send it in signal handler; malloc() might be interrupted! */ + /* We can't send it in signal handler; SDL_malloc() might be interrupted! */ if ((sig == SIGINT) || (sig == SIGTERM)) { send_quit_pending = SDL_TRUE; } - #ifdef SDL_BACKGROUNDING_SIGNAL +#ifdef SDL_BACKGROUNDING_SIGNAL else if (sig == SDL_BACKGROUNDING_SIGNAL) { send_backgrounding_pending = SDL_TRUE; } - #endif +#endif - #ifdef SDL_FOREGROUNDING_SIGNAL +#ifdef SDL_FOREGROUNDING_SIGNAL else if (sig == SDL_FOREGROUNDING_SIGNAL) { send_foregrounding_pending = SDL_TRUE; } - #endif +#endif } -static void -SDL_EventSignal_Init(const int sig) +static void SDL_EventSignal_Init(const int sig) { #ifdef HAVE_SIGACTION struct sigaction action; sigaction(sig, NULL, &action); #ifdef HAVE_SA_SIGACTION - if ( action.sa_handler == SIG_DFL && (void (*)(int))action.sa_sigaction == SIG_DFL ) { + if (action.sa_handler == SIG_DFL && (void (*)(int))action.sa_sigaction == SIG_DFL) { #else - if ( action.sa_handler == SIG_DFL ) { + if (action.sa_handler == SIG_DFL) { #endif action.sa_handler = SDL_HandleSIG; sigaction(sig, &action, NULL); } -#elif HAVE_SIGNAL_H - void (*ohandler) (int) = signal(sig, SDL_HandleSIG); +#elif defined(HAVE_SIGNAL_H) + void (*ohandler)(int) = signal(sig, SDL_HandleSIG); if (ohandler != SIG_DFL) { signal(sig, ohandler); } #endif } -static void -SDL_EventSignal_Quit(const int sig) +static void SDL_EventSignal_Quit(const int sig) { #ifdef HAVE_SIGACTION struct sigaction action; sigaction(sig, NULL, &action); - if ( action.sa_handler == SDL_HandleSIG ) { + if (action.sa_handler == SDL_HandleSIG) { action.sa_handler = SIG_DFL; sigaction(sig, &action, NULL); } -#elif HAVE_SIGNAL_H - void (*ohandler) (int) = signal(sig, SIG_DFL); +#elif defined(HAVE_SIGNAL_H) + void (*ohandler)(int) = signal(sig, SIG_DFL); if (ohandler != SDL_HandleSIG) { signal(sig, ohandler); } @@ -114,44 +111,41 @@ SDL_EventSignal_Quit(const int sig) } /* Public functions */ -static int -SDL_QuitInit_Internal(void) +static int SDL_QuitInit_Internal(void) { /* Both SIGINT and SIGTERM are translated into quit interrupts */ /* and SDL can be built to simulate iOS/Android semantics with arbitrary signals. */ SDL_EventSignal_Init(SIGINT); SDL_EventSignal_Init(SIGTERM); - #ifdef SDL_BACKGROUNDING_SIGNAL +#ifdef SDL_BACKGROUNDING_SIGNAL SDL_EventSignal_Init(SDL_BACKGROUNDING_SIGNAL); - #endif +#endif - #ifdef SDL_FOREGROUNDING_SIGNAL +#ifdef SDL_FOREGROUNDING_SIGNAL SDL_EventSignal_Init(SDL_FOREGROUNDING_SIGNAL); - #endif +#endif /* That's it! */ return 0; } -static void -SDL_QuitQuit_Internal(void) +static void SDL_QuitQuit_Internal(void) { SDL_EventSignal_Quit(SIGINT); SDL_EventSignal_Quit(SIGTERM); - #ifdef SDL_BACKGROUNDING_SIGNAL +#ifdef SDL_BACKGROUNDING_SIGNAL SDL_EventSignal_Quit(SDL_BACKGROUNDING_SIGNAL); - #endif +#endif - #ifdef SDL_FOREGROUNDING_SIGNAL +#ifdef SDL_FOREGROUNDING_SIGNAL SDL_EventSignal_Quit(SDL_FOREGROUNDING_SIGNAL); - #endif +#endif } #endif -int -SDL_QuitInit(void) +int SDL_QuitInit(void) { #ifdef HAVE_SIGNAL_SUPPORT if (!SDL_GetHintBoolean(SDL_HINT_NO_SIGNAL_HANDLERS, SDL_FALSE)) { @@ -161,8 +155,7 @@ SDL_QuitInit(void) return 0; } -void -SDL_QuitQuit(void) +void SDL_QuitQuit(void) { #ifdef HAVE_SIGNAL_SUPPORT if (!disable_signals) { @@ -171,8 +164,7 @@ SDL_QuitQuit(void) #endif } -void -SDL_SendPendingSignalEvents(void) +void SDL_SendPendingSignalEvents(void) { #ifdef HAVE_SIGNAL_SUPPORT if (send_quit_pending) { @@ -180,25 +172,24 @@ SDL_SendPendingSignalEvents(void) SDL_assert(!send_quit_pending); } - #ifdef SDL_BACKGROUNDING_SIGNAL +#ifdef SDL_BACKGROUNDING_SIGNAL if (send_backgrounding_pending) { send_backgrounding_pending = SDL_FALSE; SDL_OnApplicationWillResignActive(); } - #endif +#endif - #ifdef SDL_FOREGROUNDING_SIGNAL +#ifdef SDL_FOREGROUNDING_SIGNAL if (send_foregrounding_pending) { send_foregrounding_pending = SDL_FALSE; SDL_OnApplicationDidBecomeActive(); } - #endif +#endif #endif } /* This function returns 1 if it's okay to close the application window */ -int -SDL_SendQuit(void) +int SDL_SendQuit(void) { #ifdef HAVE_SIGNAL_SUPPORT send_quit_pending = SDL_FALSE; diff --git a/SDL2-2.30.5/src/events/SDL_scancode_tables.c b/SDL2-2.30.5/src/events/SDL_scancode_tables.c new file mode 100644 index 0000000..db6d861 --- /dev/null +++ b/SDL2-2.30.5/src/events/SDL_scancode_tables.c @@ -0,0 +1,73 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#if defined(SDL_INPUT_LINUXEV) || defined(SDL_VIDEO_DRIVER_DIRECTFB) || defined(SDL_VIDEO_DRIVER_WAYLAND) || defined(SDL_VIDEO_DRIVER_X11) + +#include "SDL_scancode_tables_c.h" + +#include "scancodes_darwin.h" +#include "scancodes_linux.h" +#include "scancodes_xfree86.h" + +static const struct +{ + SDL_ScancodeTable table; + SDL_Scancode const *scancodes; + int num_entries; +} SDL_scancode_tables[] = { + { SDL_SCANCODE_TABLE_DARWIN, darwin_scancode_table, SDL_arraysize(darwin_scancode_table) }, + { SDL_SCANCODE_TABLE_LINUX, linux_scancode_table, SDL_arraysize(linux_scancode_table) }, + { SDL_SCANCODE_TABLE_XFREE86_1, xfree86_scancode_table, SDL_arraysize(xfree86_scancode_table) }, + { SDL_SCANCODE_TABLE_XFREE86_2, xfree86_scancode_table2, SDL_arraysize(xfree86_scancode_table2) }, + { SDL_SCANCODE_TABLE_XVNC, xvnc_scancode_table, SDL_arraysize(xvnc_scancode_table) }, +}; + +const SDL_Scancode *SDL_GetScancodeTable(SDL_ScancodeTable table, int *num_entries) +{ + int i; + + for (i = 0; i < SDL_arraysize(SDL_scancode_tables); ++i) { + if (table == SDL_scancode_tables[i].table) { + *num_entries = SDL_scancode_tables[i].num_entries; + return SDL_scancode_tables[i].scancodes; + } + } + + *num_entries = 0; + return NULL; +} + +SDL_Scancode SDL_GetScancodeFromTable(SDL_ScancodeTable table, int keycode) +{ + SDL_Scancode scancode = SDL_SCANCODE_UNKNOWN; + int num_entries; + const SDL_Scancode *scancodes = SDL_GetScancodeTable(table, &num_entries); + + if (keycode >= 0 && keycode < num_entries) { + scancode = scancodes[keycode]; + } + return scancode; +} + +#endif /* SDL_INPUT_LINUXEV || SDL_VIDEO_DRIVER_DIRECTFB || SDL_VIDEO_DRIVER_WAYLAND || SDL_VIDEO_DRIVER_X11 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/events/SDL_scancode_tables_c.h b/SDL2-2.30.5/src/events/SDL_scancode_tables_c.h new file mode 100644 index 0000000..481e7a5 --- /dev/null +++ b/SDL2-2.30.5/src/events/SDL_scancode_tables_c.h @@ -0,0 +1,37 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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 "../../include/SDL_scancode.h" + +typedef enum +{ + SDL_SCANCODE_TABLE_DARWIN, + SDL_SCANCODE_TABLE_LINUX, + SDL_SCANCODE_TABLE_XFREE86_1, + SDL_SCANCODE_TABLE_XFREE86_2, + SDL_SCANCODE_TABLE_XVNC, +} SDL_ScancodeTable; + +extern const SDL_Scancode *SDL_GetScancodeTable(SDL_ScancodeTable table, int *num_entries); +extern SDL_Scancode SDL_GetScancodeFromTable(SDL_ScancodeTable table, int keycode); + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/events/SDL_touch.c b/SDL2-2.30.5/src/events/SDL_touch.c similarity index 75% rename from SDL2-2.0.12/src/events/SDL_touch.c rename to SDL2-2.30.5/src/events/SDL_touch.c index 5cc7ea3..b5ec77b 100644 --- a/SDL2-2.0.12/src/events/SDL_touch.c +++ b/SDL2-2.30.5/src/events/SDL_touch.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -22,12 +22,10 @@ /* General touch handling code for SDL */ -#include "SDL_assert.h" #include "SDL_events.h" #include "SDL_events_c.h" #include "../video/SDL_sysvideo.h" - static int SDL_num_touch = 0; static SDL_Touch **SDL_touchDevices = NULL; @@ -38,24 +36,21 @@ static SDL_Touch **SDL_touchDevices = NULL; #if SYNTHESIZE_TOUCH_TO_MOUSE static SDL_bool finger_touching = SDL_FALSE; static SDL_FingerID track_fingerid; -static SDL_TouchID track_touchid; +static SDL_TouchID track_touchid; #endif /* Public functions */ -int -SDL_TouchInit(void) +int SDL_TouchInit(void) { - return (0); + return 0; } -int -SDL_GetNumTouchDevices(void) +int SDL_GetNumTouchDevices(void) { return SDL_num_touch; } -SDL_TouchID -SDL_GetTouchDevice(int index) +SDL_TouchID SDL_GetTouchDevice(int index) { if (index < 0 || index >= SDL_num_touch) { SDL_SetError("Unknown touch device index %d", index); @@ -64,8 +59,16 @@ SDL_GetTouchDevice(int index) return SDL_touchDevices[index]->id; } -static int -SDL_GetTouchIndex(SDL_TouchID id) +const char *SDL_GetTouchName(int index) +{ + if (index < 0 || index >= SDL_num_touch) { + SDL_SetError("Unknown touch device"); + return NULL; + } + return SDL_touchDevices[index]->name; +} + +static int SDL_GetTouchIndex(SDL_TouchID id) { int index; SDL_Touch *touch; @@ -79,24 +82,22 @@ SDL_GetTouchIndex(SDL_TouchID id) return -1; } -SDL_Touch * -SDL_GetTouch(SDL_TouchID id) +SDL_Touch *SDL_GetTouch(SDL_TouchID id) { int index = SDL_GetTouchIndex(id); if (index < 0 || index >= SDL_num_touch) { if (SDL_GetVideoDevice()->ResetTouch != NULL) { - SDL_SetError("Unknown touch id %d, resetting", (int) id); + SDL_SetError("Unknown touch id %d, resetting", (int)id); (SDL_GetVideoDevice()->ResetTouch)(SDL_GetVideoDevice()); } else { - SDL_SetError("Unknown touch device id %d, cannot reset", (int) id); + SDL_SetError("Unknown touch device id %d, cannot reset", (int)id); } return NULL; } return SDL_touchDevices[index]; } -SDL_TouchDeviceType -SDL_GetTouchDeviceType(SDL_TouchID id) +SDL_TouchDeviceType SDL_GetTouchDeviceType(SDL_TouchID id) { SDL_Touch *touch = SDL_GetTouch(id); if (touch) { @@ -105,8 +106,7 @@ SDL_GetTouchDeviceType(SDL_TouchID id) return SDL_TOUCH_DEVICE_INVALID; } -static int -SDL_GetFingerIndex(const SDL_Touch * touch, SDL_FingerID fingerid) +static int SDL_GetFingerIndex(const SDL_Touch *touch, SDL_FingerID fingerid) { int index; for (index = 0; index < touch->num_fingers; ++index) { @@ -117,8 +117,7 @@ SDL_GetFingerIndex(const SDL_Touch * touch, SDL_FingerID fingerid) return -1; } -static SDL_Finger * -SDL_GetFinger(const SDL_Touch * touch, SDL_FingerID id) +static SDL_Finger *SDL_GetFinger(const SDL_Touch *touch, SDL_FingerID id) { int index = SDL_GetFingerIndex(touch, id); if (index < 0 || index >= touch->num_fingers) { @@ -127,8 +126,7 @@ SDL_GetFinger(const SDL_Touch * touch, SDL_FingerID id) return touch->fingers[index]; } -int -SDL_GetNumTouchFingers(SDL_TouchID touchID) +int SDL_GetNumTouchFingers(SDL_TouchID touchID) { SDL_Touch *touch = SDL_GetTouch(touchID); if (touch) { @@ -137,8 +135,7 @@ SDL_GetNumTouchFingers(SDL_TouchID touchID) return 0; } -SDL_Finger * -SDL_GetTouchFinger(SDL_TouchID touchID, int index) +SDL_Finger *SDL_GetTouchFinger(SDL_TouchID touchID, int index) { SDL_Touch *touch = SDL_GetTouch(touchID); if (!touch) { @@ -151,8 +148,7 @@ SDL_GetTouchFinger(SDL_TouchID touchID, int index) return touch->fingers[index]; } -int -SDL_AddTouch(SDL_TouchID touchID, SDL_TouchDeviceType type, const char *name) +int SDL_AddTouch(SDL_TouchID touchID, SDL_TouchDeviceType type, const char *name) { SDL_Touch **touchDevices; int index; @@ -163,8 +159,8 @@ SDL_AddTouch(SDL_TouchID touchID, SDL_TouchDeviceType type, const char *name) } /* Add the touch to the list of touch */ - touchDevices = (SDL_Touch **) SDL_realloc(SDL_touchDevices, - (SDL_num_touch + 1) * sizeof(*touchDevices)); + touchDevices = (SDL_Touch **)SDL_realloc(SDL_touchDevices, + (SDL_num_touch + 1) * sizeof(*touchDevices)); if (!touchDevices) { return SDL_OutOfMemory(); } @@ -172,7 +168,7 @@ SDL_AddTouch(SDL_TouchID touchID, SDL_TouchDeviceType type, const char *name) SDL_touchDevices = touchDevices; index = SDL_num_touch; - SDL_touchDevices[index] = (SDL_Touch *) SDL_malloc(sizeof(*SDL_touchDevices[index])); + SDL_touchDevices[index] = (SDL_Touch *)SDL_malloc(sizeof(*SDL_touchDevices[index])); if (!SDL_touchDevices[index]) { return SDL_OutOfMemory(); } @@ -186,6 +182,7 @@ SDL_AddTouch(SDL_TouchID touchID, SDL_TouchDeviceType type, const char *name) SDL_touchDevices[index]->num_fingers = 0; SDL_touchDevices[index]->max_fingers = 0; SDL_touchDevices[index]->fingers = NULL; + SDL_touchDevices[index]->name = SDL_strdup(name ? name : ""); /* Record this touch device for gestures */ /* We could do this on the fly in the gesture code if we wanted */ @@ -194,14 +191,13 @@ SDL_AddTouch(SDL_TouchID touchID, SDL_TouchDeviceType type, const char *name) return index; } -static int -SDL_AddFinger(SDL_Touch *touch, SDL_FingerID fingerid, float x, float y, float pressure) +static int SDL_AddFinger(SDL_Touch *touch, SDL_FingerID fingerid, float x, float y, float pressure) { SDL_Finger *finger; if (touch->num_fingers == touch->max_fingers) { SDL_Finger **new_fingers; - new_fingers = (SDL_Finger **)SDL_realloc(touch->fingers, (touch->max_fingers+1)*sizeof(*touch->fingers)); + new_fingers = (SDL_Finger **)SDL_realloc(touch->fingers, (touch->max_fingers + 1) * sizeof(*touch->fingers)); if (!new_fingers) { return SDL_OutOfMemory(); } @@ -221,8 +217,7 @@ SDL_AddFinger(SDL_Touch *touch, SDL_FingerID fingerid, float x, float y, float p return 0; } -static int -SDL_DelFinger(SDL_Touch* touch, SDL_FingerID fingerid) +static int SDL_DelFinger(SDL_Touch *touch, SDL_FingerID fingerid) { SDL_Finger *temp; @@ -238,15 +233,14 @@ SDL_DelFinger(SDL_Touch* touch, SDL_FingerID fingerid) return 0; } -int -SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window * window, - SDL_bool down, float x, float y, float pressure) +int SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window *window, + SDL_bool down, float x, float y, float pressure) { int posted; SDL_Finger *finger; SDL_Mouse *mouse; - SDL_Touch* touch = SDL_GetTouch(id); + SDL_Touch *touch = SDL_GetTouch(id); if (!touch) { return -1; } @@ -255,8 +249,13 @@ SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window * window, #if SYNTHESIZE_TOUCH_TO_MOUSE /* SDL_HINT_TOUCH_MOUSE_EVENTS: controlling whether touch events should generate synthetic mouse events */ + /* SDL_HINT_VITA_TOUCH_MOUSE_DEVICE: controlling which touchpad should generate synthetic mouse events, PSVita-only */ { +#if defined(__vita__) + if (mouse->touch_mouse_events && ((mouse->vita_touch_mouse_device == id) || (mouse->vita_touch_mouse_device == 2))) { +#else if (mouse->touch_mouse_events) { +#endif /* FIXME: maybe we should only restrict to a few SDL_TouchDeviceType */ if (id != SDL_MOUSE_TOUCHID) { if (window) { @@ -264,10 +263,18 @@ SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window * window, if (finger_touching == SDL_FALSE) { int pos_x = (int)(x * (float)window->w); int pos_y = (int)(y * (float)window->h); - if (pos_x < 0) pos_x = 0; - if (pos_x > window->w - 1) pos_x = window->w - 1; - if (pos_y < 0) pos_y = 0; - if (pos_y > window->h - 1) pos_y = window->h - 1; + if (pos_x < 0) { + pos_x = 0; + } + if (pos_x > window->w - 1) { + pos_x = window->w - 1; + } + if (pos_y < 0) { + pos_y = 0; + } + if (pos_y > window->h - 1) { + pos_y = window->h - 1; + } SDL_SendMouseMotion(window, SDL_TOUCH_MOUSEID, 0, pos_x, pos_y); SDL_SendMouseButton(window, SDL_TOUCH_MOUSEID, SDL_PRESSED, SDL_BUTTON_LEFT); } @@ -303,8 +310,9 @@ SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window * window, finger = SDL_GetFinger(touch, fingerid); if (down) { if (finger) { - /* This finger is already down */ - return 0; + /* This finger is already down. + Assume the finger-up for the previous touch was lost, and send it. */ + SDL_SendTouch(id, fingerid, window, SDL_FALSE, x, y, pressure); } if (SDL_AddFinger(touch, fingerid, x, y, pressure) < 0) { @@ -352,9 +360,8 @@ SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window * window, return posted; } -int -SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window * window, - float x, float y, float pressure) +int SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window *window, + float x, float y, float pressure) { SDL_Touch *touch; SDL_Finger *finger; @@ -378,10 +385,18 @@ SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window * window, if (finger_touching == SDL_TRUE && track_touchid == id && track_fingerid == fingerid) { int pos_x = (int)(x * (float)window->w); int pos_y = (int)(y * (float)window->h); - if (pos_x < 0) pos_x = 0; - if (pos_x > window->w - 1) pos_x = window->w - 1; - if (pos_y < 0) pos_y = 0; - if (pos_y > window->h - 1) pos_y = window->h - 1; + if (pos_x < 0) { + pos_x = 0; + } + if (pos_x > window->w - 1) { + pos_x = window->w - 1; + } + if (pos_y < 0) { + pos_y = 0; + } + if (pos_y > window->h - 1) { + pos_y = window->h - 1; + } SDL_SendMouseMotion(window, SDL_TOUCH_MOUSEID, 0, pos_x, pos_y); } } @@ -397,7 +412,7 @@ SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window * window, } } - finger = SDL_GetFinger(touch,fingerid); + finger = SDL_GetFinger(touch, fingerid); if (!finger) { return SDL_SendTouch(id, fingerid, window, SDL_TRUE, x, y, pressure); } @@ -437,13 +452,18 @@ SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window * window, return posted; } -void -SDL_DelTouch(SDL_TouchID id) +void SDL_DelTouch(SDL_TouchID id) { - int i; - int index = SDL_GetTouchIndex(id); - SDL_Touch *touch = SDL_GetTouch(id); + int i, index; + SDL_Touch *touch; + if (SDL_num_touch == 0) { + /* We've already cleaned up, we won't find this device */ + return; + } + + index = SDL_GetTouchIndex(id); + touch = SDL_GetTouch(id); if (!touch) { return; } @@ -452,6 +472,7 @@ SDL_DelTouch(SDL_TouchID id) SDL_free(touch->fingers[i]); } SDL_free(touch->fingers); + SDL_free(touch->name); SDL_free(touch); SDL_num_touch--; @@ -461,12 +482,11 @@ SDL_DelTouch(SDL_TouchID id) SDL_GestureDelTouch(id); } -void -SDL_TouchQuit(void) +void SDL_TouchQuit(void) { int i; - for (i = SDL_num_touch; i--; ) { + for (i = SDL_num_touch; i--;) { SDL_DelTouch(SDL_touchDevices[i]->id); } SDL_assert(SDL_num_touch == 0); diff --git a/SDL2-2.0.12/src/events/SDL_touch_c.h b/SDL2-2.30.5/src/events/SDL_touch_c.h similarity index 93% rename from SDL2-2.0.12/src/events/SDL_touch_c.h rename to SDL2-2.30.5/src/events/SDL_touch_c.h index ed5dda2..85f1f90 100644 --- a/SDL2-2.0.12/src/events/SDL_touch_c.h +++ b/SDL2-2.30.5/src/events/SDL_touch_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -30,10 +30,10 @@ typedef struct SDL_Touch SDL_TouchDeviceType type; int num_fingers; int max_fingers; - SDL_Finger** fingers; + SDL_Finger **fingers; + char *name; } SDL_Touch; - /* Initialize the touch subsystem */ extern int SDL_TouchInit(void); @@ -44,11 +44,11 @@ extern int SDL_AddTouch(SDL_TouchID id, SDL_TouchDeviceType type, const char *na extern SDL_Touch *SDL_GetTouch(SDL_TouchID id); /* Send a touch down/up event for a touch */ -extern int SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window * window, +extern int SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window *window, SDL_bool down, float x, float y, float pressure); /* Send a touch motion event for a touch */ -extern int SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window * window, +extern int SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window *window, float x, float y, float pressure); /* Remove a touch */ diff --git a/SDL2-2.0.12/src/events/SDL_windowevents.c b/SDL2-2.30.5/src/events/SDL_windowevents.c similarity index 75% rename from SDL2-2.0.12/src/events/SDL_windowevents.c rename to SDL2-2.30.5/src/events/SDL_windowevents.c index 50e544b..2ef1e74 100644 --- a/SDL2-2.0.12/src/events/SDL_windowevents.c +++ b/SDL2-2.30.5/src/events/SDL_windowevents.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -25,25 +25,35 @@ #include "SDL_events.h" #include "SDL_events_c.h" #include "SDL_mouse_c.h" +#include "SDL_hints.h" - -static int SDLCALL -RemovePendingSizeChangedAndResizedEvents(void * userdata, SDL_Event *event) +typedef struct RemovePendingSizeChangedAndResizedEvents_Data { - SDL_Event *new_event = (SDL_Event *)userdata; + const SDL_Event *new_event; + SDL_bool saw_resized; +} RemovePendingSizeChangedAndResizedEvents_Data; + +static int SDLCALL RemovePendingSizeChangedAndResizedEvents(void *_userdata, SDL_Event *event) +{ + RemovePendingSizeChangedAndResizedEvents_Data *userdata = (RemovePendingSizeChangedAndResizedEvents_Data *)_userdata; + const SDL_Event *new_event = userdata->new_event; if (event->type == SDL_WINDOWEVENT && (event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED || event->window.event == SDL_WINDOWEVENT_RESIZED) && event->window.windowID == new_event->window.windowID) { + + if (event->window.event == SDL_WINDOWEVENT_RESIZED) { + userdata->saw_resized = SDL_TRUE; + } + /* We're about to post a new size event, drop the old one */ return 0; } return 1; } -static int SDLCALL -RemovePendingMoveEvents(void * userdata, SDL_Event *event) +static int SDLCALL RemovePendingMoveEvents(void *userdata, SDL_Event *event) { SDL_Event *new_event = (SDL_Event *)userdata; @@ -56,8 +66,7 @@ RemovePendingMoveEvents(void * userdata, SDL_Event *event) return 1; } -static int SDLCALL -RemovePendingExposedEvents(void * userdata, SDL_Event *event) +static int SDLCALL RemovePendingExposedEvents(void *userdata, SDL_Event *event) { SDL_Event *new_event = (SDL_Event *)userdata; @@ -70,9 +79,8 @@ RemovePendingExposedEvents(void * userdata, SDL_Event *event) return 1; } -int -SDL_SendWindowEvent(SDL_Window * window, Uint8 windowevent, int data1, - int data2) +int SDL_SendWindowEvent(SDL_Window *window, Uint8 windowevent, int data1, + int data2) { int posted; @@ -110,6 +118,7 @@ SDL_SendWindowEvent(SDL_Window * window, Uint8 windowevent, int data1, } window->x = data1; window->y = data2; + SDL_OnWindowMoved(window); break; case SDL_WINDOWEVENT_RESIZED: if (!(window->flags & SDL_WINDOW_FULLSCREEN)) { @@ -187,7 +196,18 @@ SDL_SendWindowEvent(SDL_Window * window, Uint8 windowevent, int data1, /* Fixes queue overflow with resize events that aren't processed */ if (windowevent == SDL_WINDOWEVENT_SIZE_CHANGED) { - SDL_FilterEvents(RemovePendingSizeChangedAndResizedEvents, &event); + /* !!! FIXME: in SDL3, let's make RESIZED/SIZE_CHANGED into one event with a flag to distinguish between them, and remove all this tapdancing. */ + RemovePendingSizeChangedAndResizedEvents_Data userdata; + userdata.new_event = &event; + userdata.saw_resized = SDL_FALSE; + SDL_FilterEvents(RemovePendingSizeChangedAndResizedEvents, &userdata); + if (userdata.saw_resized) { /* if there was a pending resize, make sure one at the new dimensions remains. */ + event.window.event = SDL_WINDOWEVENT_RESIZED; + if (SDL_PushEvent(&event) <= 0) { + return 0; /* oh well. */ + } + event.window.event = SDL_WINDOWEVENT_SIZE_CHANGED; /* then push the actual event next. */ + } } if (windowevent == SDL_WINDOWEVENT_MOVED) { SDL_FilterEvents(RemovePendingMoveEvents, &event); @@ -199,13 +219,14 @@ SDL_SendWindowEvent(SDL_Window * window, Uint8 windowevent, int data1, } if (windowevent == SDL_WINDOWEVENT_CLOSE) { - if ( !window->prev && !window->next ) { - /* This is the last window in the list so send the SDL_QUIT event */ - SDL_SendQuit(); + if (!window->prev && !window->next) { + if (SDL_GetHintBoolean(SDL_HINT_QUIT_ON_LAST_WINDOW_CLOSE, SDL_TRUE)) { + SDL_SendQuit(); /* This is the last window in the list so send the SDL_QUIT event */ + } } } - return (posted); + return posted; } /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/events/SDL_windowevents_c.h b/SDL2-2.30.5/src/events/SDL_windowevents_c.h similarity index 89% rename from SDL2-2.0.12/src/events/SDL_windowevents_c.h rename to SDL2-2.30.5/src/events/SDL_windowevents_c.h index 6223907..cf7fc3a 100644 --- a/SDL2-2.0.12/src/events/SDL_windowevents_c.h +++ b/SDL2-2.30.5/src/events/SDL_windowevents_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,7 +23,7 @@ #ifndef SDL_windowevents_c_h_ #define SDL_windowevents_c_h_ -extern int SDL_SendWindowEvent(SDL_Window * window, Uint8 windowevent, +extern int SDL_SendWindowEvent(SDL_Window *window, Uint8 windowevent, int data1, int data2); #endif /* SDL_windowevents_c_h_ */ diff --git a/SDL2-2.0.12/src/events/blank_cursor.h b/SDL2-2.30.5/src/events/blank_cursor.h similarity index 88% rename from SDL2-2.0.12/src/events/blank_cursor.h rename to SDL2-2.30.5/src/events/blank_cursor.h index dbeb90c..1c317b7 100644 --- a/SDL2-2.0.12/src/events/blank_cursor.h +++ b/SDL2-2.30.5/src/events/blank_cursor.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -22,10 +22,10 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * A default blank 8x8 cursor */ -#define BLANK_CWIDTH 8 -#define BLANK_CHEIGHT 8 -#define BLANK_CHOTX 0 -#define BLANK_CHOTY 0 +#define BLANK_CWIDTH 8 +#define BLANK_CHEIGHT 8 +#define BLANK_CHOTX 0 +#define BLANK_CHOTY 0 static const unsigned char blank_cdata[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; static const unsigned char blank_cmask[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; diff --git a/SDL2-2.0.12/src/events/default_cursor.h b/SDL2-2.30.5/src/events/default_cursor.h similarity index 97% rename from SDL2-2.0.12/src/events/default_cursor.h rename to SDL2-2.30.5/src/events/default_cursor.h index 6e468bd..3eecf6c 100644 --- a/SDL2-2.0.12/src/events/default_cursor.h +++ b/SDL2-2.30.5/src/events/default_cursor.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -27,7 +27,7 @@ #define DEFAULT_CHOTX 0 #define DEFAULT_CHOTY 0 -/* Added a real MacOS cursor, at the request of Luc-Olivier de Charrire */ +/* Added a real MacOS cursor, at the request of Luc-Olivier de Charrière */ #define USE_MACOS_CURSOR #ifdef USE_MACOS_CURSOR @@ -111,4 +111,5 @@ static const unsigned char default_cmask[] = { }; #endif /* USE_MACOS_CURSOR */ + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/x11/imKStoUCS.c b/SDL2-2.30.5/src/events/imKStoUCS.c similarity index 99% rename from SDL2-2.0.12/src/video/x11/imKStoUCS.c rename to SDL2-2.30.5/src/events/imKStoUCS.c index 40e2242..d851dc1 100644 --- a/SDL2-2.0.12/src/video/x11/imKStoUCS.c +++ b/SDL2-2.30.5/src/events/imKStoUCS.c @@ -24,10 +24,9 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include "../../SDL_internal.h" +#include "../SDL_internal.h" -#if SDL_VIDEO_DRIVER_X11 -#include +#if defined(SDL_VIDEO_DRIVER_X11) || defined(SDL_VIDEO_DRIVER_WAYLAND) #include "imKStoUCS.h" static unsigned short const keysym_to_unicode_1a1_1ff[] = { @@ -294,7 +293,7 @@ static unsigned short const keysym_to_unicode_20a0_20ac[] = { }; unsigned int -X11_KeySymToUcs4(KeySym keysym) +SDL_KeySymToUcs4(Uint32 keysym) { /* 'Unicode keysym' */ if ((keysym & 0xff000000) == 0x01000000) diff --git a/SDL2-2.0.12/src/video/x11/imKStoUCS.h b/SDL2-2.30.5/src/events/imKStoUCS.h similarity index 96% rename from SDL2-2.0.12/src/video/x11/imKStoUCS.h rename to SDL2-2.30.5/src/events/imKStoUCS.h index fe4381d..485ace5 100644 --- a/SDL2-2.0.12/src/video/x11/imKStoUCS.h +++ b/SDL2-2.30.5/src/events/imKStoUCS.h @@ -27,6 +27,6 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -extern unsigned int X11_KeySymToUcs4(KeySym keysym); +extern unsigned int SDL_KeySymToUcs4(Uint32 keysym); #endif /* _imKStoUCS_h */ diff --git a/SDL2-2.30.5/src/events/scancodes_ascii.h b/SDL2-2.30.5/src/events/scancodes_ascii.h new file mode 100644 index 0000000..a4a0ecc --- /dev/null +++ b/SDL2-2.30.5/src/events/scancodes_ascii.h @@ -0,0 +1,170 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_scancode.h" +#include "SDL_keycode.h" + +/* + This file is used to convert between characters passed in from an ASCII + virtual keyboard in US layout and tuples of SDL_Scancode and SDL_keymods. + + For example ASCIIKeyInfoTable['a'] would give you the scan code and keymod + for lower case a. +*/ + +typedef struct +{ + SDL_Scancode code; + uint16_t mod; +} ASCIIKeyInfo; + +static ASCIIKeyInfo SDL_ASCIIKeyInfoTable[] = { + /* 0 */ { SDL_SCANCODE_UNKNOWN, 0 }, + /* 1 */ { SDL_SCANCODE_UNKNOWN, 0 }, + /* 2 */ { SDL_SCANCODE_UNKNOWN, 0 }, + /* 3 */ { SDL_SCANCODE_UNKNOWN, 0 }, + /* 4 */ { SDL_SCANCODE_UNKNOWN, 0 }, + /* 5 */ { SDL_SCANCODE_UNKNOWN, 0 }, + /* 6 */ { SDL_SCANCODE_UNKNOWN, 0 }, + /* 7 */ { SDL_SCANCODE_UNKNOWN, 0 }, + /* 8 */ { SDL_SCANCODE_BACKSPACE, 0 }, + /* 9 */ { SDL_SCANCODE_UNKNOWN, 0 }, + /* 10 */ { SDL_SCANCODE_RETURN, 0 }, + /* 11 */ { SDL_SCANCODE_UNKNOWN, 0 }, + /* 12 */ { SDL_SCANCODE_UNKNOWN, 0 }, + /* 13 */ { SDL_SCANCODE_RETURN, 0 }, + /* 14 */ { SDL_SCANCODE_UNKNOWN, 0 }, + /* 15 */ { SDL_SCANCODE_UNKNOWN, 0 }, + /* 16 */ { SDL_SCANCODE_UNKNOWN, 0 }, + /* 17 */ { SDL_SCANCODE_UNKNOWN, 0 }, + /* 18 */ { SDL_SCANCODE_UNKNOWN, 0 }, + /* 19 */ { SDL_SCANCODE_UNKNOWN, 0 }, + /* 20 */ { SDL_SCANCODE_UNKNOWN, 0 }, + /* 21 */ { SDL_SCANCODE_UNKNOWN, 0 }, + /* 22 */ { SDL_SCANCODE_UNKNOWN, 0 }, + /* 23 */ { SDL_SCANCODE_UNKNOWN, 0 }, + /* 24 */ { SDL_SCANCODE_UNKNOWN, 0 }, + /* 25 */ { SDL_SCANCODE_UNKNOWN, 0 }, + /* 26 */ { SDL_SCANCODE_UNKNOWN, 0 }, + /* 27 */ { SDL_SCANCODE_UNKNOWN, 0 }, + /* 28 */ { SDL_SCANCODE_UNKNOWN, 0 }, + /* 29 */ { SDL_SCANCODE_UNKNOWN, 0 }, + /* 30 */ { SDL_SCANCODE_UNKNOWN, 0 }, + /* 31 */ { SDL_SCANCODE_UNKNOWN, 0 }, + /* 32 */ { SDL_SCANCODE_SPACE, 0 }, + /* 33 */ { SDL_SCANCODE_1, KMOD_SHIFT }, /* plus shift modifier '!' */ + /* 34 */ { SDL_SCANCODE_APOSTROPHE, KMOD_SHIFT }, /* plus shift modifier '"' */ + /* 35 */ { SDL_SCANCODE_3, KMOD_SHIFT }, /* plus shift modifier '#' */ + /* 36 */ { SDL_SCANCODE_4, KMOD_SHIFT }, /* plus shift modifier '$' */ + /* 37 */ { SDL_SCANCODE_5, KMOD_SHIFT }, /* plus shift modifier '%' */ + /* 38 */ { SDL_SCANCODE_7, KMOD_SHIFT }, /* plus shift modifier '&' */ + /* 39 */ { SDL_SCANCODE_APOSTROPHE, 0 }, /* ''' */ + /* 40 */ { SDL_SCANCODE_9, KMOD_SHIFT }, /* plus shift modifier '(' */ + /* 41 */ { SDL_SCANCODE_0, KMOD_SHIFT }, /* plus shift modifier ')' */ + /* 42 */ { SDL_SCANCODE_8, KMOD_SHIFT }, /* '*' */ + /* 43 */ { SDL_SCANCODE_EQUALS, KMOD_SHIFT }, /* plus shift modifier '+' */ + /* 44 */ { SDL_SCANCODE_COMMA, 0 }, /* ',' */ + /* 45 */ { SDL_SCANCODE_MINUS, 0 }, /* '-' */ + /* 46 */ { SDL_SCANCODE_PERIOD, 0 }, /* '.' */ + /* 47 */ { SDL_SCANCODE_SLASH, 0 }, /* '/' */ + /* 48 */ { SDL_SCANCODE_0, 0 }, + /* 49 */ { SDL_SCANCODE_1, 0 }, + /* 50 */ { SDL_SCANCODE_2, 0 }, + /* 51 */ { SDL_SCANCODE_3, 0 }, + /* 52 */ { SDL_SCANCODE_4, 0 }, + /* 53 */ { SDL_SCANCODE_5, 0 }, + /* 54 */ { SDL_SCANCODE_6, 0 }, + /* 55 */ { SDL_SCANCODE_7, 0 }, + /* 56 */ { SDL_SCANCODE_8, 0 }, + /* 57 */ { SDL_SCANCODE_9, 0 }, + /* 58 */ { SDL_SCANCODE_SEMICOLON, KMOD_SHIFT }, /* plus shift modifier ';' */ + /* 59 */ { SDL_SCANCODE_SEMICOLON, 0 }, + /* 60 */ { SDL_SCANCODE_COMMA, KMOD_SHIFT }, /* plus shift modifier '<' */ + /* 61 */ { SDL_SCANCODE_EQUALS, 0 }, + /* 62 */ { SDL_SCANCODE_PERIOD, KMOD_SHIFT }, /* plus shift modifier '>' */ + /* 63 */ { SDL_SCANCODE_SLASH, KMOD_SHIFT }, /* plus shift modifier '?' */ + /* 64 */ { SDL_SCANCODE_2, KMOD_SHIFT }, /* plus shift modifier '@' */ + /* 65 */ { SDL_SCANCODE_A, KMOD_SHIFT }, /* all the following need shift modifiers */ + /* 66 */ { SDL_SCANCODE_B, KMOD_SHIFT }, + /* 67 */ { SDL_SCANCODE_C, KMOD_SHIFT }, + /* 68 */ { SDL_SCANCODE_D, KMOD_SHIFT }, + /* 69 */ { SDL_SCANCODE_E, KMOD_SHIFT }, + /* 70 */ { SDL_SCANCODE_F, KMOD_SHIFT }, + /* 71 */ { SDL_SCANCODE_G, KMOD_SHIFT }, + /* 72 */ { SDL_SCANCODE_H, KMOD_SHIFT }, + /* 73 */ { SDL_SCANCODE_I, KMOD_SHIFT }, + /* 74 */ { SDL_SCANCODE_J, KMOD_SHIFT }, + /* 75 */ { SDL_SCANCODE_K, KMOD_SHIFT }, + /* 76 */ { SDL_SCANCODE_L, KMOD_SHIFT }, + /* 77 */ { SDL_SCANCODE_M, KMOD_SHIFT }, + /* 78 */ { SDL_SCANCODE_N, KMOD_SHIFT }, + /* 79 */ { SDL_SCANCODE_O, KMOD_SHIFT }, + /* 80 */ { SDL_SCANCODE_P, KMOD_SHIFT }, + /* 81 */ { SDL_SCANCODE_Q, KMOD_SHIFT }, + /* 82 */ { SDL_SCANCODE_R, KMOD_SHIFT }, + /* 83 */ { SDL_SCANCODE_S, KMOD_SHIFT }, + /* 84 */ { SDL_SCANCODE_T, KMOD_SHIFT }, + /* 85 */ { SDL_SCANCODE_U, KMOD_SHIFT }, + /* 86 */ { SDL_SCANCODE_V, KMOD_SHIFT }, + /* 87 */ { SDL_SCANCODE_W, KMOD_SHIFT }, + /* 88 */ { SDL_SCANCODE_X, KMOD_SHIFT }, + /* 89 */ { SDL_SCANCODE_Y, KMOD_SHIFT }, + /* 90 */ { SDL_SCANCODE_Z, KMOD_SHIFT }, + /* 91 */ { SDL_SCANCODE_LEFTBRACKET, 0 }, + /* 92 */ { SDL_SCANCODE_BACKSLASH, 0 }, + /* 93 */ { SDL_SCANCODE_RIGHTBRACKET, 0 }, + /* 94 */ { SDL_SCANCODE_6, KMOD_SHIFT }, /* plus shift modifier '^' */ + /* 95 */ { SDL_SCANCODE_MINUS, KMOD_SHIFT }, /* plus shift modifier '_' */ + /* 96 */ { SDL_SCANCODE_GRAVE, KMOD_SHIFT }, /* '`' */ + /* 97 */ { SDL_SCANCODE_A, 0 }, + /* 98 */ { SDL_SCANCODE_B, 0 }, + /* 99 */ { SDL_SCANCODE_C, 0 }, + /* 100 */ { SDL_SCANCODE_D, 0 }, + /* 101 */ { SDL_SCANCODE_E, 0 }, + /* 102 */ { SDL_SCANCODE_F, 0 }, + /* 103 */ { SDL_SCANCODE_G, 0 }, + /* 104 */ { SDL_SCANCODE_H, 0 }, + /* 105 */ { SDL_SCANCODE_I, 0 }, + /* 106 */ { SDL_SCANCODE_J, 0 }, + /* 107 */ { SDL_SCANCODE_K, 0 }, + /* 108 */ { SDL_SCANCODE_L, 0 }, + /* 109 */ { SDL_SCANCODE_M, 0 }, + /* 110 */ { SDL_SCANCODE_N, 0 }, + /* 111 */ { SDL_SCANCODE_O, 0 }, + /* 112 */ { SDL_SCANCODE_P, 0 }, + /* 113 */ { SDL_SCANCODE_Q, 0 }, + /* 114 */ { SDL_SCANCODE_R, 0 }, + /* 115 */ { SDL_SCANCODE_S, 0 }, + /* 116 */ { SDL_SCANCODE_T, 0 }, + /* 117 */ { SDL_SCANCODE_U, 0 }, + /* 118 */ { SDL_SCANCODE_V, 0 }, + /* 119 */ { SDL_SCANCODE_W, 0 }, + /* 120 */ { SDL_SCANCODE_X, 0 }, + /* 121 */ { SDL_SCANCODE_Y, 0 }, + /* 122 */ { SDL_SCANCODE_Z, 0 }, + /* 123 */ { SDL_SCANCODE_LEFTBRACKET, KMOD_SHIFT }, /* plus shift modifier '{' */ + /* 124 */ { SDL_SCANCODE_BACKSLASH, KMOD_SHIFT }, /* plus shift modifier '|' */ + /* 125 */ { SDL_SCANCODE_RIGHTBRACKET, KMOD_SHIFT }, /* plus shift modifier '}' */ + /* 126 */ { SDL_SCANCODE_GRAVE, KMOD_SHIFT }, /* plus shift modifier '~' */ + /* 127 */ { SDL_SCANCODE_BACKSPACE, KMOD_SHIFT } +}; + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/events/scancodes_darwin.h b/SDL2-2.30.5/src/events/scancodes_darwin.h similarity index 97% rename from SDL2-2.0.12/src/events/scancodes_darwin.h rename to SDL2-2.30.5/src/events/scancodes_darwin.h index 8b7b530..de23de4 100644 --- a/SDL2-2.0.12/src/events/scancodes_darwin.h +++ b/SDL2-2.30.5/src/events/scancodes_darwin.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -25,7 +25,7 @@ - Apple USB keyboard driver source - experimentation on various ADB and USB ISO keyboards and one ADB ANSI keyboard */ -/* *INDENT-OFF* */ +/* *INDENT-OFF* */ /* clang-format off */ static const SDL_Scancode darwin_scancode_table[] = { /* 0 */ SDL_SCANCODE_A, /* 1 */ SDL_SCANCODE_S, @@ -156,4 +156,6 @@ static const SDL_Scancode darwin_scancode_table[] = { /* 126 */ SDL_SCANCODE_UP, /* 127 */ SDL_SCANCODE_POWER }; -/* *INDENT-ON* */ +/* *INDENT-ON* */ /* clang-format on */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/events/scancodes_linux.h b/SDL2-2.30.5/src/events/scancodes_linux.h new file mode 100644 index 0000000..03d84a9 --- /dev/null +++ b/SDL2-2.30.5/src/events/scancodes_linux.h @@ -0,0 +1,850 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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 "../../include/SDL_scancode.h" + +/* Linux virtual key code to SDL_Keycode mapping table + Sources: + - Linux kernel source input.h +*/ +/* *INDENT-OFF* */ /* clang-format off */ +static SDL_Scancode const linux_scancode_table[] = { + /* 0, 0x000 */ SDL_SCANCODE_UNKNOWN, /* KEY_RESERVED */ + /* 1, 0x001 */ SDL_SCANCODE_ESCAPE, /* KEY_ESC */ + /* 2, 0x002 */ SDL_SCANCODE_1, /* KEY_1 */ + /* 3, 0x003 */ SDL_SCANCODE_2, /* KEY_2 */ + /* 4, 0x004 */ SDL_SCANCODE_3, /* KEY_3 */ + /* 5, 0x005 */ SDL_SCANCODE_4, /* KEY_4 */ + /* 6, 0x006 */ SDL_SCANCODE_5, /* KEY_5 */ + /* 7, 0x007 */ SDL_SCANCODE_6, /* KEY_6 */ + /* 8, 0x008 */ SDL_SCANCODE_7, /* KEY_7 */ + /* 9, 0x009 */ SDL_SCANCODE_8, /* KEY_8 */ + /* 10, 0x00a */ SDL_SCANCODE_9, /* KEY_9 */ + /* 11, 0x00b */ SDL_SCANCODE_0, /* KEY_0 */ + /* 12, 0x00c */ SDL_SCANCODE_MINUS, /* KEY_MINUS */ + /* 13, 0x00d */ SDL_SCANCODE_EQUALS, /* KEY_EQUAL */ + /* 14, 0x00e */ SDL_SCANCODE_BACKSPACE, /* KEY_BACKSPACE */ + /* 15, 0x00f */ SDL_SCANCODE_TAB, /* KEY_TAB */ + /* 16, 0x010 */ SDL_SCANCODE_Q, /* KEY_Q */ + /* 17, 0x011 */ SDL_SCANCODE_W, /* KEY_W */ + /* 18, 0x012 */ SDL_SCANCODE_E, /* KEY_E */ + /* 19, 0x013 */ SDL_SCANCODE_R, /* KEY_R */ + /* 20, 0x014 */ SDL_SCANCODE_T, /* KEY_T */ + /* 21, 0x015 */ SDL_SCANCODE_Y, /* KEY_Y */ + /* 22, 0x016 */ SDL_SCANCODE_U, /* KEY_U */ + /* 23, 0x017 */ SDL_SCANCODE_I, /* KEY_I */ + /* 24, 0x018 */ SDL_SCANCODE_O, /* KEY_O */ + /* 25, 0x019 */ SDL_SCANCODE_P, /* KEY_P */ + /* 26, 0x01a */ SDL_SCANCODE_LEFTBRACKET, /* KEY_LEFTBRACE */ + /* 27, 0x01b */ SDL_SCANCODE_RIGHTBRACKET, /* KEY_RIGHTBRACE */ + /* 28, 0x01c */ SDL_SCANCODE_RETURN, /* KEY_ENTER */ + /* 29, 0x01d */ SDL_SCANCODE_LCTRL, /* KEY_LEFTCTRL */ + /* 30, 0x01e */ SDL_SCANCODE_A, /* KEY_A */ + /* 31, 0x01f */ SDL_SCANCODE_S, /* KEY_S */ + /* 32, 0x020 */ SDL_SCANCODE_D, /* KEY_D */ + /* 33, 0x021 */ SDL_SCANCODE_F, /* KEY_F */ + /* 34, 0x022 */ SDL_SCANCODE_G, /* KEY_G */ + /* 35, 0x023 */ SDL_SCANCODE_H, /* KEY_H */ + /* 36, 0x024 */ SDL_SCANCODE_J, /* KEY_J */ + /* 37, 0x025 */ SDL_SCANCODE_K, /* KEY_K */ + /* 38, 0x026 */ SDL_SCANCODE_L, /* KEY_L */ + /* 39, 0x027 */ SDL_SCANCODE_SEMICOLON, /* KEY_SEMICOLON */ + /* 40, 0x028 */ SDL_SCANCODE_APOSTROPHE, /* KEY_APOSTROPHE */ + /* 41, 0x029 */ SDL_SCANCODE_GRAVE, /* KEY_GRAVE */ + /* 42, 0x02a */ SDL_SCANCODE_LSHIFT, /* KEY_LEFTSHIFT */ + /* 43, 0x02b */ SDL_SCANCODE_BACKSLASH, /* KEY_BACKSLASH */ + /* 44, 0x02c */ SDL_SCANCODE_Z, /* KEY_Z */ + /* 45, 0x02d */ SDL_SCANCODE_X, /* KEY_X */ + /* 46, 0x02e */ SDL_SCANCODE_C, /* KEY_C */ + /* 47, 0x02f */ SDL_SCANCODE_V, /* KEY_V */ + /* 48, 0x030 */ SDL_SCANCODE_B, /* KEY_B */ + /* 49, 0x031 */ SDL_SCANCODE_N, /* KEY_N */ + /* 50, 0x032 */ SDL_SCANCODE_M, /* KEY_M */ + /* 51, 0x033 */ SDL_SCANCODE_COMMA, /* KEY_COMMA */ + /* 52, 0x034 */ SDL_SCANCODE_PERIOD, /* KEY_DOT */ + /* 53, 0x035 */ SDL_SCANCODE_SLASH, /* KEY_SLASH */ + /* 54, 0x036 */ SDL_SCANCODE_RSHIFT, /* KEY_RIGHTSHIFT */ + /* 55, 0x037 */ SDL_SCANCODE_KP_MULTIPLY, /* KEY_KPASTERISK */ + /* 56, 0x038 */ SDL_SCANCODE_LALT, /* KEY_LEFTALT */ + /* 57, 0x039 */ SDL_SCANCODE_SPACE, /* KEY_SPACE */ + /* 58, 0x03a */ SDL_SCANCODE_CAPSLOCK, /* KEY_CAPSLOCK */ + /* 59, 0x03b */ SDL_SCANCODE_F1, /* KEY_F1 */ + /* 60, 0x03c */ SDL_SCANCODE_F2, /* KEY_F2 */ + /* 61, 0x03d */ SDL_SCANCODE_F3, /* KEY_F3 */ + /* 62, 0x03e */ SDL_SCANCODE_F4, /* KEY_F4 */ + /* 63, 0x03f */ SDL_SCANCODE_F5, /* KEY_F5 */ + /* 64, 0x040 */ SDL_SCANCODE_F6, /* KEY_F6 */ + /* 65, 0x041 */ SDL_SCANCODE_F7, /* KEY_F7 */ + /* 66, 0x042 */ SDL_SCANCODE_F8, /* KEY_F8 */ + /* 67, 0x043 */ SDL_SCANCODE_F9, /* KEY_F9 */ + /* 68, 0x044 */ SDL_SCANCODE_F10, /* KEY_F10 */ + /* 69, 0x045 */ SDL_SCANCODE_NUMLOCKCLEAR, /* KEY_NUMLOCK */ + /* 70, 0x046 */ SDL_SCANCODE_SCROLLLOCK, /* KEY_SCROLLLOCK */ + /* 71, 0x047 */ SDL_SCANCODE_KP_7, /* KEY_KP7 */ + /* 72, 0x048 */ SDL_SCANCODE_KP_8, /* KEY_KP8 */ + /* 73, 0x049 */ SDL_SCANCODE_KP_9, /* KEY_KP9 */ + /* 74, 0x04a */ SDL_SCANCODE_KP_MINUS, /* KEY_KPMINUS */ + /* 75, 0x04b */ SDL_SCANCODE_KP_4, /* KEY_KP4 */ + /* 76, 0x04c */ SDL_SCANCODE_KP_5, /* KEY_KP5 */ + /* 77, 0x04d */ SDL_SCANCODE_KP_6, /* KEY_KP6 */ + /* 78, 0x04e */ SDL_SCANCODE_KP_PLUS, /* KEY_KPPLUS */ + /* 79, 0x04f */ SDL_SCANCODE_KP_1, /* KEY_KP1 */ + /* 80, 0x050 */ SDL_SCANCODE_KP_2, /* KEY_KP2 */ + /* 81, 0x051 */ SDL_SCANCODE_KP_3, /* KEY_KP3 */ + /* 82, 0x052 */ SDL_SCANCODE_KP_0, /* KEY_KP0 */ + /* 83, 0x053 */ SDL_SCANCODE_KP_PERIOD, /* KEY_KPDOT */ + /* 84, 0x054 */ SDL_SCANCODE_UNKNOWN, + /* 85, 0x055 */ SDL_SCANCODE_LANG5, /* KEY_ZENKAKUHANKAKU */ + /* 86, 0x056 */ SDL_SCANCODE_NONUSBACKSLASH, /* KEY_102ND */ + /* 87, 0x057 */ SDL_SCANCODE_F11, /* KEY_F11 */ + /* 88, 0x058 */ SDL_SCANCODE_F12, /* KEY_F12 */ + /* 89, 0x059 */ SDL_SCANCODE_INTERNATIONAL1, /* KEY_RO */ + /* 90, 0x05a */ SDL_SCANCODE_LANG3, /* KEY_KATAKANA */ + /* 91, 0x05b */ SDL_SCANCODE_LANG4, /* KEY_HIRAGANA */ + /* 92, 0x05c */ SDL_SCANCODE_INTERNATIONAL4, /* KEY_HENKAN */ + /* 93, 0x05d */ SDL_SCANCODE_INTERNATIONAL2, /* KEY_KATAKANAHIRAGANA */ + /* 94, 0x05e */ SDL_SCANCODE_INTERNATIONAL5, /* KEY_MUHENKAN */ + /* 95, 0x05f */ SDL_SCANCODE_INTERNATIONAL5, /* KEY_KPJPCOMMA */ + /* 96, 0x060 */ SDL_SCANCODE_KP_ENTER, /* KEY_KPENTER */ + /* 97, 0x061 */ SDL_SCANCODE_RCTRL, /* KEY_RIGHTCTRL */ + /* 98, 0x062 */ SDL_SCANCODE_KP_DIVIDE, /* KEY_KPSLASH */ + /* 99, 0x063 */ SDL_SCANCODE_SYSREQ, /* KEY_SYSRQ */ + /* 100, 0x064 */ SDL_SCANCODE_RALT, /* KEY_RIGHTALT */ + /* 101, 0x065 */ SDL_SCANCODE_UNKNOWN, /* KEY_LINEFEED */ + /* 102, 0x066 */ SDL_SCANCODE_HOME, /* KEY_HOME */ + /* 103, 0x067 */ SDL_SCANCODE_UP, /* KEY_UP */ + /* 104, 0x068 */ SDL_SCANCODE_PAGEUP, /* KEY_PAGEUP */ + /* 105, 0x069 */ SDL_SCANCODE_LEFT, /* KEY_LEFT */ + /* 106, 0x06a */ SDL_SCANCODE_RIGHT, /* KEY_RIGHT */ + /* 107, 0x06b */ SDL_SCANCODE_END, /* KEY_END */ + /* 108, 0x06c */ SDL_SCANCODE_DOWN, /* KEY_DOWN */ + /* 109, 0x06d */ SDL_SCANCODE_PAGEDOWN, /* KEY_PAGEDOWN */ + /* 110, 0x06e */ SDL_SCANCODE_INSERT, /* KEY_INSERT */ + /* 111, 0x06f */ SDL_SCANCODE_DELETE, /* KEY_DELETE */ + /* 112, 0x070 */ SDL_SCANCODE_UNKNOWN, /* KEY_MACRO */ + /* 113, 0x071 */ SDL_SCANCODE_MUTE, /* KEY_MUTE */ + /* 114, 0x072 */ SDL_SCANCODE_VOLUMEDOWN, /* KEY_VOLUMEDOWN */ + /* 115, 0x073 */ SDL_SCANCODE_VOLUMEUP, /* KEY_VOLUMEUP */ + /* 116, 0x074 */ SDL_SCANCODE_POWER, /* KEY_POWER */ + /* 117, 0x075 */ SDL_SCANCODE_KP_EQUALS, /* KEY_KPEQUAL */ + /* 118, 0x076 */ SDL_SCANCODE_KP_PLUSMINUS, /* KEY_KPPLUSMINUS */ + /* 119, 0x077 */ SDL_SCANCODE_PAUSE, /* KEY_PAUSE */ + /* 120, 0x078 */ SDL_SCANCODE_UNKNOWN, /* KEY_SCALE */ + /* 121, 0x079 */ SDL_SCANCODE_KP_COMMA, /* KEY_KPCOMMA */ + /* 122, 0x07a */ SDL_SCANCODE_LANG1, /* KEY_HANGEUL */ + /* 123, 0x07b */ SDL_SCANCODE_LANG2, /* KEY_HANJA */ + /* 124, 0x07c */ SDL_SCANCODE_INTERNATIONAL3, /* KEY_YEN */ + /* 125, 0x07d */ SDL_SCANCODE_LGUI, /* KEY_LEFTMETA */ + /* 126, 0x07e */ SDL_SCANCODE_RGUI, /* KEY_RIGHTMETA */ + /* 127, 0x07f */ SDL_SCANCODE_APPLICATION, /* KEY_COMPOSE */ + /* 128, 0x080 */ SDL_SCANCODE_STOP, /* KEY_STOP */ + /* 129, 0x081 */ SDL_SCANCODE_AGAIN, /* KEY_AGAIN */ + /* 130, 0x082 */ SDL_SCANCODE_UNKNOWN, /* KEY_PROPS */ + /* 131, 0x083 */ SDL_SCANCODE_UNDO, /* KEY_UNDO */ + /* 132, 0x084 */ SDL_SCANCODE_UNKNOWN, /* KEY_FRONT */ + /* 133, 0x085 */ SDL_SCANCODE_COPY, /* KEY_COPY */ + /* 134, 0x086 */ SDL_SCANCODE_UNKNOWN, /* KEY_OPEN */ + /* 135, 0x087 */ SDL_SCANCODE_PASTE, /* KEY_PASTE */ + /* 136, 0x088 */ SDL_SCANCODE_FIND, /* KEY_FIND */ + /* 137, 0x089 */ SDL_SCANCODE_CUT, /* KEY_CUT */ + /* 138, 0x08a */ SDL_SCANCODE_HELP, /* KEY_HELP */ + /* 139, 0x08b */ SDL_SCANCODE_MENU, /* KEY_MENU */ + /* 140, 0x08c */ SDL_SCANCODE_CALCULATOR, /* KEY_CALC */ + /* 141, 0x08d */ SDL_SCANCODE_UNKNOWN, /* KEY_SETUP */ + /* 142, 0x08e */ SDL_SCANCODE_SLEEP, /* KEY_SLEEP */ + /* 143, 0x08f */ SDL_SCANCODE_UNKNOWN, /* KEY_WAKEUP */ + /* 144, 0x090 */ SDL_SCANCODE_UNKNOWN, /* KEY_FILE */ + /* 145, 0x091 */ SDL_SCANCODE_UNKNOWN, /* KEY_SENDFILE */ + /* 146, 0x092 */ SDL_SCANCODE_UNKNOWN, /* KEY_DELETEFILE */ + /* 147, 0x093 */ SDL_SCANCODE_UNKNOWN, /* KEY_XFER */ + /* 148, 0x094 */ SDL_SCANCODE_APP1, /* KEY_PROG1 */ + /* 149, 0x095 */ SDL_SCANCODE_APP2, /* KEY_PROG2 */ + /* 150, 0x096 */ SDL_SCANCODE_WWW, /* KEY_WWW */ + /* 151, 0x097 */ SDL_SCANCODE_UNKNOWN, /* KEY_MSDOS */ + /* 152, 0x098 */ SDL_SCANCODE_UNKNOWN, /* KEY_COFFEE */ + /* 153, 0x099 */ SDL_SCANCODE_UNKNOWN, /* KEY_ROTATE_DISPLAY */ + /* 154, 0x09a */ SDL_SCANCODE_UNKNOWN, /* KEY_CYCLEWINDOWS */ + /* 155, 0x09b */ SDL_SCANCODE_MAIL, /* KEY_MAIL */ + /* 156, 0x09c */ SDL_SCANCODE_AC_BOOKMARKS, /* KEY_BOOKMARKS */ + /* 157, 0x09d */ SDL_SCANCODE_COMPUTER, /* KEY_COMPUTER */ + /* 158, 0x09e */ SDL_SCANCODE_AC_BACK, /* KEY_BACK */ + /* 159, 0x09f */ SDL_SCANCODE_AC_FORWARD, /* KEY_FORWARD */ + /* 160, 0x0a0 */ SDL_SCANCODE_UNKNOWN, /* KEY_CLOSECD */ + /* 161, 0x0a1 */ SDL_SCANCODE_EJECT, /* KEY_EJECTCD */ + /* 162, 0x0a2 */ SDL_SCANCODE_EJECT, /* KEY_EJECTCLOSECD */ + /* 163, 0x0a3 */ SDL_SCANCODE_AUDIONEXT, /* KEY_NEXTSONG */ + /* 164, 0x0a4 */ SDL_SCANCODE_AUDIOPLAY, /* KEY_PLAYPAUSE */ + /* 165, 0x0a5 */ SDL_SCANCODE_AUDIOPREV, /* KEY_PREVIOUSSONG */ + /* 166, 0x0a6 */ SDL_SCANCODE_AUDIOSTOP, /* KEY_STOPCD */ + /* 167, 0x0a7 */ SDL_SCANCODE_UNKNOWN, /* KEY_RECORD */ + /* 168, 0x0a8 */ SDL_SCANCODE_AUDIOREWIND, /* KEY_REWIND */ + /* 169, 0x0a9 */ SDL_SCANCODE_UNKNOWN, /* KEY_PHONE */ + /* 170, 0x0aa */ SDL_SCANCODE_UNKNOWN, /* KEY_ISO */ + /* 171, 0x0ab */ SDL_SCANCODE_UNKNOWN, /* KEY_CONFIG */ + /* 172, 0x0ac */ SDL_SCANCODE_AC_HOME, /* KEY_HOMEPAGE */ + /* 173, 0x0ad */ SDL_SCANCODE_AC_REFRESH, /* KEY_REFRESH */ + /* 174, 0x0ae */ SDL_SCANCODE_UNKNOWN, /* KEY_EXIT */ + /* 175, 0x0af */ SDL_SCANCODE_UNKNOWN, /* KEY_MOVE */ + /* 176, 0x0b0 */ SDL_SCANCODE_UNKNOWN, /* KEY_EDIT */ + /* 177, 0x0b1 */ SDL_SCANCODE_UNKNOWN, /* KEY_SCROLLUP */ + /* 178, 0x0b2 */ SDL_SCANCODE_UNKNOWN, /* KEY_SCROLLDOWN */ + /* 179, 0x0b3 */ SDL_SCANCODE_KP_LEFTPAREN, /* KEY_KPLEFTPAREN */ + /* 180, 0x0b4 */ SDL_SCANCODE_KP_RIGHTPAREN, /* KEY_KPRIGHTPAREN */ + /* 181, 0x0b5 */ SDL_SCANCODE_UNKNOWN, /* KEY_NEW */ + /* 182, 0x0b6 */ SDL_SCANCODE_AGAIN, /* KEY_REDO */ + /* 183, 0x0b7 */ SDL_SCANCODE_F13, /* KEY_F13 */ + /* 184, 0x0b8 */ SDL_SCANCODE_F14, /* KEY_F14 */ + /* 185, 0x0b9 */ SDL_SCANCODE_F15, /* KEY_F15 */ + /* 186, 0x0ba */ SDL_SCANCODE_F16, /* KEY_F16 */ + /* 187, 0x0bb */ SDL_SCANCODE_F17, /* KEY_F17 */ + /* 188, 0x0bc */ SDL_SCANCODE_F18, /* KEY_F18 */ + /* 189, 0x0bd */ SDL_SCANCODE_F19, /* KEY_F19 */ + /* 190, 0x0be */ SDL_SCANCODE_F20, /* KEY_F20 */ + /* 191, 0x0bf */ SDL_SCANCODE_F21, /* KEY_F21 */ + /* 192, 0x0c0 */ SDL_SCANCODE_F22, /* KEY_F22 */ + /* 193, 0x0c1 */ SDL_SCANCODE_F23, /* KEY_F23 */ + /* 194, 0x0c2 */ SDL_SCANCODE_F24, /* KEY_F24 */ + /* 195, 0x0c3 */ SDL_SCANCODE_UNKNOWN, + /* 196, 0x0c4 */ SDL_SCANCODE_UNKNOWN, + /* 197, 0x0c5 */ SDL_SCANCODE_UNKNOWN, + /* 198, 0x0c6 */ SDL_SCANCODE_UNKNOWN, + /* 199, 0x0c7 */ SDL_SCANCODE_UNKNOWN, + /* 200, 0x0c8 */ SDL_SCANCODE_AUDIOPLAY, /* KEY_PLAYCD */ + /* 201, 0x0c9 */ SDL_SCANCODE_UNKNOWN, /* KEY_PAUSECD */ + /* 202, 0x0ca */ SDL_SCANCODE_UNKNOWN, /* KEY_PROG3 */ + /* 203, 0x0cb */ SDL_SCANCODE_UNKNOWN, /* KEY_PROG4 */ + /* 204, 0x0cc */ SDL_SCANCODE_UNKNOWN, /* KEY_ALL_APPLICATIONS */ + /* 205, 0x0cd */ SDL_SCANCODE_UNKNOWN, /* KEY_SUSPEND */ + /* 206, 0x0ce */ SDL_SCANCODE_UNKNOWN, /* KEY_CLOSE */ + /* 207, 0x0cf */ SDL_SCANCODE_AUDIOPLAY, /* KEY_PLAY */ + /* 208, 0x0d0 */ SDL_SCANCODE_AUDIOFASTFORWARD, /* KEY_FASTFORWARD */ + /* 209, 0x0d1 */ SDL_SCANCODE_UNKNOWN, /* KEY_BASSBOOST */ + /* 210, 0x0d2 */ SDL_SCANCODE_PRINTSCREEN, /* KEY_PRINT */ + /* 211, 0x0d3 */ SDL_SCANCODE_UNKNOWN, /* KEY_HP */ + /* 212, 0x0d4 */ SDL_SCANCODE_UNKNOWN, /* KEY_CAMERA */ + /* 213, 0x0d5 */ SDL_SCANCODE_UNKNOWN, /* KEY_SOUND */ + /* 214, 0x0d6 */ SDL_SCANCODE_UNKNOWN, /* KEY_QUESTION */ + /* 215, 0x0d7 */ SDL_SCANCODE_MAIL, /* KEY_EMAIL */ + /* 216, 0x0d8 */ SDL_SCANCODE_UNKNOWN, /* KEY_CHAT */ + /* 217, 0x0d9 */ SDL_SCANCODE_AC_SEARCH, /* KEY_SEARCH */ + /* 218, 0x0da */ SDL_SCANCODE_UNKNOWN, /* KEY_CONNECT */ + /* 219, 0x0db */ SDL_SCANCODE_UNKNOWN, /* KEY_FINANCE */ + /* 220, 0x0dc */ SDL_SCANCODE_UNKNOWN, /* KEY_SPORT */ + /* 221, 0x0dd */ SDL_SCANCODE_UNKNOWN, /* KEY_SHOP */ + /* 222, 0x0de */ SDL_SCANCODE_ALTERASE, /* KEY_ALTERASE */ + /* 223, 0x0df */ SDL_SCANCODE_CANCEL, /* KEY_CANCEL */ + /* 224, 0x0e0 */ SDL_SCANCODE_BRIGHTNESSDOWN, /* KEY_BRIGHTNESSDOWN */ + /* 225, 0x0e1 */ SDL_SCANCODE_BRIGHTNESSUP, /* KEY_BRIGHTNESSUP */ + /* 226, 0x0e2 */ SDL_SCANCODE_MEDIASELECT, /* KEY_MEDIA */ + /* 227, 0x0e3 */ SDL_SCANCODE_DISPLAYSWITCH, /* KEY_SWITCHVIDEOMODE */ + /* 228, 0x0e4 */ SDL_SCANCODE_KBDILLUMTOGGLE, /* KEY_KBDILLUMTOGGLE */ + /* 229, 0x0e5 */ SDL_SCANCODE_KBDILLUMDOWN, /* KEY_KBDILLUMDOWN */ + /* 230, 0x0e6 */ SDL_SCANCODE_KBDILLUMUP, /* KEY_KBDILLUMUP */ + /* 231, 0x0e7 */ SDL_SCANCODE_UNKNOWN, /* KEY_SEND */ + /* 232, 0x0e8 */ SDL_SCANCODE_UNKNOWN, /* KEY_REPLY */ + /* 233, 0x0e9 */ SDL_SCANCODE_UNKNOWN, /* KEY_FORWARDMAIL */ + /* 234, 0x0ea */ SDL_SCANCODE_UNKNOWN, /* KEY_SAVE */ + /* 235, 0x0eb */ SDL_SCANCODE_UNKNOWN, /* KEY_DOCUMENTS */ + /* 236, 0x0ec */ SDL_SCANCODE_UNKNOWN, /* KEY_BATTERY */ + /* 237, 0x0ed */ SDL_SCANCODE_UNKNOWN, /* KEY_BLUETOOTH */ + /* 238, 0x0ee */ SDL_SCANCODE_UNKNOWN, /* KEY_WLAN */ + /* 239, 0x0ef */ SDL_SCANCODE_UNKNOWN, /* KEY_UWB */ + /* 240, 0x0f0 */ SDL_SCANCODE_UNKNOWN, /* KEY_UNKNOWN */ + /* 241, 0x0f1 */ SDL_SCANCODE_UNKNOWN, /* KEY_VIDEO_NEXT */ + /* 242, 0x0f2 */ SDL_SCANCODE_UNKNOWN, /* KEY_VIDEO_PREV */ + /* 243, 0x0f3 */ SDL_SCANCODE_UNKNOWN, /* KEY_BRIGHTNESS_CYCLE */ + /* 244, 0x0f4 */ SDL_SCANCODE_UNKNOWN, /* KEY_BRIGHTNESS_AUTO */ + /* 245, 0x0f5 */ SDL_SCANCODE_UNKNOWN, /* KEY_DISPLAY_OFF */ + /* 246, 0x0f6 */ SDL_SCANCODE_UNKNOWN, /* KEY_WWAN */ + /* 247, 0x0f7 */ SDL_SCANCODE_UNKNOWN, /* KEY_RFKILL */ + /* 248, 0x0f8 */ SDL_SCANCODE_UNKNOWN, /* KEY_MICMUTE */ + /* 249, 0x0f9 */ SDL_SCANCODE_UNKNOWN, + /* 250, 0x0fa */ SDL_SCANCODE_UNKNOWN, + /* 251, 0x0fb */ SDL_SCANCODE_UNKNOWN, + /* 252, 0x0fc */ SDL_SCANCODE_UNKNOWN, + /* 253, 0x0fd */ SDL_SCANCODE_UNKNOWN, + /* 254, 0x0fe */ SDL_SCANCODE_UNKNOWN, + /* 255, 0x0ff */ SDL_SCANCODE_UNKNOWN, +#if 0 /* We don't have any mapped scancodes after this point (yet) */ + /* 256, 0x100 */ SDL_SCANCODE_UNKNOWN, + /* 257, 0x101 */ SDL_SCANCODE_UNKNOWN, + /* 258, 0x102 */ SDL_SCANCODE_UNKNOWN, + /* 259, 0x103 */ SDL_SCANCODE_UNKNOWN, + /* 260, 0x104 */ SDL_SCANCODE_UNKNOWN, + /* 261, 0x105 */ SDL_SCANCODE_UNKNOWN, + /* 262, 0x106 */ SDL_SCANCODE_UNKNOWN, + /* 263, 0x107 */ SDL_SCANCODE_UNKNOWN, + /* 264, 0x108 */ SDL_SCANCODE_UNKNOWN, + /* 265, 0x109 */ SDL_SCANCODE_UNKNOWN, + /* 266, 0x10a */ SDL_SCANCODE_UNKNOWN, + /* 267, 0x10b */ SDL_SCANCODE_UNKNOWN, + /* 268, 0x10c */ SDL_SCANCODE_UNKNOWN, + /* 269, 0x10d */ SDL_SCANCODE_UNKNOWN, + /* 270, 0x10e */ SDL_SCANCODE_UNKNOWN, + /* 271, 0x10f */ SDL_SCANCODE_UNKNOWN, + /* 272, 0x110 */ SDL_SCANCODE_UNKNOWN, + /* 273, 0x111 */ SDL_SCANCODE_UNKNOWN, + /* 274, 0x112 */ SDL_SCANCODE_UNKNOWN, + /* 275, 0x113 */ SDL_SCANCODE_UNKNOWN, + /* 276, 0x114 */ SDL_SCANCODE_UNKNOWN, + /* 277, 0x115 */ SDL_SCANCODE_UNKNOWN, + /* 278, 0x116 */ SDL_SCANCODE_UNKNOWN, + /* 279, 0x117 */ SDL_SCANCODE_UNKNOWN, + /* 280, 0x118 */ SDL_SCANCODE_UNKNOWN, + /* 281, 0x119 */ SDL_SCANCODE_UNKNOWN, + /* 282, 0x11a */ SDL_SCANCODE_UNKNOWN, + /* 283, 0x11b */ SDL_SCANCODE_UNKNOWN, + /* 284, 0x11c */ SDL_SCANCODE_UNKNOWN, + /* 285, 0x11d */ SDL_SCANCODE_UNKNOWN, + /* 286, 0x11e */ SDL_SCANCODE_UNKNOWN, + /* 287, 0x11f */ SDL_SCANCODE_UNKNOWN, + /* 288, 0x120 */ SDL_SCANCODE_UNKNOWN, + /* 289, 0x121 */ SDL_SCANCODE_UNKNOWN, + /* 290, 0x122 */ SDL_SCANCODE_UNKNOWN, + /* 291, 0x123 */ SDL_SCANCODE_UNKNOWN, + /* 292, 0x124 */ SDL_SCANCODE_UNKNOWN, + /* 293, 0x125 */ SDL_SCANCODE_UNKNOWN, + /* 294, 0x126 */ SDL_SCANCODE_UNKNOWN, + /* 295, 0x127 */ SDL_SCANCODE_UNKNOWN, + /* 296, 0x128 */ SDL_SCANCODE_UNKNOWN, + /* 297, 0x129 */ SDL_SCANCODE_UNKNOWN, + /* 298, 0x12a */ SDL_SCANCODE_UNKNOWN, + /* 299, 0x12b */ SDL_SCANCODE_UNKNOWN, + /* 300, 0x12c */ SDL_SCANCODE_UNKNOWN, + /* 301, 0x12d */ SDL_SCANCODE_UNKNOWN, + /* 302, 0x12e */ SDL_SCANCODE_UNKNOWN, + /* 303, 0x12f */ SDL_SCANCODE_UNKNOWN, + /* 304, 0x130 */ SDL_SCANCODE_UNKNOWN, + /* 305, 0x131 */ SDL_SCANCODE_UNKNOWN, + /* 306, 0x132 */ SDL_SCANCODE_UNKNOWN, + /* 307, 0x133 */ SDL_SCANCODE_UNKNOWN, + /* 308, 0x134 */ SDL_SCANCODE_UNKNOWN, + /* 309, 0x135 */ SDL_SCANCODE_UNKNOWN, + /* 310, 0x136 */ SDL_SCANCODE_UNKNOWN, + /* 311, 0x137 */ SDL_SCANCODE_UNKNOWN, + /* 312, 0x138 */ SDL_SCANCODE_UNKNOWN, + /* 313, 0x139 */ SDL_SCANCODE_UNKNOWN, + /* 314, 0x13a */ SDL_SCANCODE_UNKNOWN, + /* 315, 0x13b */ SDL_SCANCODE_UNKNOWN, + /* 316, 0x13c */ SDL_SCANCODE_UNKNOWN, + /* 317, 0x13d */ SDL_SCANCODE_UNKNOWN, + /* 318, 0x13e */ SDL_SCANCODE_UNKNOWN, + /* 319, 0x13f */ SDL_SCANCODE_UNKNOWN, + /* 320, 0x140 */ SDL_SCANCODE_UNKNOWN, + /* 321, 0x141 */ SDL_SCANCODE_UNKNOWN, + /* 322, 0x142 */ SDL_SCANCODE_UNKNOWN, + /* 323, 0x143 */ SDL_SCANCODE_UNKNOWN, + /* 324, 0x144 */ SDL_SCANCODE_UNKNOWN, + /* 325, 0x145 */ SDL_SCANCODE_UNKNOWN, + /* 326, 0x146 */ SDL_SCANCODE_UNKNOWN, + /* 327, 0x147 */ SDL_SCANCODE_UNKNOWN, + /* 328, 0x148 */ SDL_SCANCODE_UNKNOWN, + /* 329, 0x149 */ SDL_SCANCODE_UNKNOWN, + /* 330, 0x14a */ SDL_SCANCODE_UNKNOWN, + /* 331, 0x14b */ SDL_SCANCODE_UNKNOWN, + /* 332, 0x14c */ SDL_SCANCODE_UNKNOWN, + /* 333, 0x14d */ SDL_SCANCODE_UNKNOWN, + /* 334, 0x14e */ SDL_SCANCODE_UNKNOWN, + /* 335, 0x14f */ SDL_SCANCODE_UNKNOWN, + /* 336, 0x150 */ SDL_SCANCODE_UNKNOWN, + /* 337, 0x151 */ SDL_SCANCODE_UNKNOWN, + /* 338, 0x152 */ SDL_SCANCODE_UNKNOWN, + /* 339, 0x153 */ SDL_SCANCODE_UNKNOWN, + /* 340, 0x154 */ SDL_SCANCODE_UNKNOWN, + /* 341, 0x155 */ SDL_SCANCODE_UNKNOWN, + /* 342, 0x156 */ SDL_SCANCODE_UNKNOWN, + /* 343, 0x157 */ SDL_SCANCODE_UNKNOWN, + /* 344, 0x158 */ SDL_SCANCODE_UNKNOWN, + /* 345, 0x159 */ SDL_SCANCODE_UNKNOWN, + /* 346, 0x15a */ SDL_SCANCODE_UNKNOWN, + /* 347, 0x15b */ SDL_SCANCODE_UNKNOWN, + /* 348, 0x15c */ SDL_SCANCODE_UNKNOWN, + /* 349, 0x15d */ SDL_SCANCODE_UNKNOWN, + /* 350, 0x15e */ SDL_SCANCODE_UNKNOWN, + /* 351, 0x15f */ SDL_SCANCODE_UNKNOWN, + /* 352, 0x160 */ SDL_SCANCODE_UNKNOWN, /* KEY_OK */ + /* 353, 0x161 */ SDL_SCANCODE_UNKNOWN, /* KEY_SELECT */ + /* 354, 0x162 */ SDL_SCANCODE_UNKNOWN, /* KEY_GOTO */ + /* 355, 0x163 */ SDL_SCANCODE_UNKNOWN, /* KEY_CLEAR */ + /* 356, 0x164 */ SDL_SCANCODE_UNKNOWN, /* KEY_POWER2 */ + /* 357, 0x165 */ SDL_SCANCODE_UNKNOWN, /* KEY_OPTION */ + /* 358, 0x166 */ SDL_SCANCODE_UNKNOWN, /* KEY_INFO */ + /* 359, 0x167 */ SDL_SCANCODE_UNKNOWN, /* KEY_TIME */ + /* 360, 0x168 */ SDL_SCANCODE_UNKNOWN, /* KEY_VENDOR */ + /* 361, 0x169 */ SDL_SCANCODE_UNKNOWN, /* KEY_ARCHIVE */ + /* 362, 0x16a */ SDL_SCANCODE_UNKNOWN, /* KEY_PROGRAM */ + /* 363, 0x16b */ SDL_SCANCODE_UNKNOWN, /* KEY_CHANNEL */ + /* 364, 0x16c */ SDL_SCANCODE_UNKNOWN, /* KEY_FAVORITES */ + /* 365, 0x16d */ SDL_SCANCODE_UNKNOWN, /* KEY_EPG */ + /* 366, 0x16e */ SDL_SCANCODE_UNKNOWN, /* KEY_PVR */ + /* 367, 0x16f */ SDL_SCANCODE_UNKNOWN, /* KEY_MHP */ + /* 368, 0x170 */ SDL_SCANCODE_UNKNOWN, /* KEY_LANGUAGE */ + /* 369, 0x171 */ SDL_SCANCODE_UNKNOWN, /* KEY_TITLE */ + /* 370, 0x172 */ SDL_SCANCODE_UNKNOWN, /* KEY_SUBTITLE */ + /* 371, 0x173 */ SDL_SCANCODE_UNKNOWN, /* KEY_ANGLE */ + /* 372, 0x174 */ SDL_SCANCODE_UNKNOWN, /* KEY_FULL_SCREEN */ + /* 373, 0x175 */ SDL_SCANCODE_UNKNOWN, /* KEY_MODE */ + /* 374, 0x176 */ SDL_SCANCODE_UNKNOWN, /* KEY_KEYBOARD */ + /* 375, 0x177 */ SDL_SCANCODE_UNKNOWN, /* KEY_ASPECT_RATIO */ + /* 376, 0x178 */ SDL_SCANCODE_UNKNOWN, /* KEY_PC */ + /* 377, 0x179 */ SDL_SCANCODE_UNKNOWN, /* KEY_TV */ + /* 378, 0x17a */ SDL_SCANCODE_UNKNOWN, /* KEY_TV2 */ + /* 379, 0x17b */ SDL_SCANCODE_UNKNOWN, /* KEY_VCR */ + /* 380, 0x17c */ SDL_SCANCODE_UNKNOWN, /* KEY_VCR2 */ + /* 381, 0x17d */ SDL_SCANCODE_UNKNOWN, /* KEY_SAT */ + /* 382, 0x17e */ SDL_SCANCODE_UNKNOWN, /* KEY_SAT2 */ + /* 383, 0x17f */ SDL_SCANCODE_UNKNOWN, /* KEY_CD */ + /* 384, 0x180 */ SDL_SCANCODE_UNKNOWN, /* KEY_TAPE */ + /* 385, 0x181 */ SDL_SCANCODE_UNKNOWN, /* KEY_RADIO */ + /* 386, 0x182 */ SDL_SCANCODE_UNKNOWN, /* KEY_TUNER */ + /* 387, 0x183 */ SDL_SCANCODE_UNKNOWN, /* KEY_PLAYER */ + /* 388, 0x184 */ SDL_SCANCODE_UNKNOWN, /* KEY_TEXT */ + /* 389, 0x185 */ SDL_SCANCODE_UNKNOWN, /* KEY_DVD */ + /* 390, 0x186 */ SDL_SCANCODE_UNKNOWN, /* KEY_AUX */ + /* 391, 0x187 */ SDL_SCANCODE_UNKNOWN, /* KEY_MP3 */ + /* 392, 0x188 */ SDL_SCANCODE_UNKNOWN, /* KEY_AUDIO */ + /* 393, 0x189 */ SDL_SCANCODE_UNKNOWN, /* KEY_VIDEO */ + /* 394, 0x18a */ SDL_SCANCODE_UNKNOWN, /* KEY_DIRECTORY */ + /* 395, 0x18b */ SDL_SCANCODE_UNKNOWN, /* KEY_LIST */ + /* 396, 0x18c */ SDL_SCANCODE_UNKNOWN, /* KEY_MEMO */ + /* 397, 0x18d */ SDL_SCANCODE_UNKNOWN, /* KEY_CALENDAR */ + /* 398, 0x18e */ SDL_SCANCODE_UNKNOWN, /* KEY_RED */ + /* 399, 0x18f */ SDL_SCANCODE_UNKNOWN, /* KEY_GREEN */ + /* 400, 0x190 */ SDL_SCANCODE_UNKNOWN, /* KEY_YELLOW */ + /* 401, 0x191 */ SDL_SCANCODE_UNKNOWN, /* KEY_BLUE */ + /* 402, 0x192 */ SDL_SCANCODE_UNKNOWN, /* KEY_CHANNELUP */ + /* 403, 0x193 */ SDL_SCANCODE_UNKNOWN, /* KEY_CHANNELDOWN */ + /* 404, 0x194 */ SDL_SCANCODE_UNKNOWN, /* KEY_FIRST */ + /* 405, 0x195 */ SDL_SCANCODE_UNKNOWN, /* KEY_LAST */ + /* 406, 0x196 */ SDL_SCANCODE_UNKNOWN, /* KEY_AB */ + /* 407, 0x197 */ SDL_SCANCODE_UNKNOWN, /* KEY_NEXT */ + /* 408, 0x198 */ SDL_SCANCODE_UNKNOWN, /* KEY_RESTART */ + /* 409, 0x199 */ SDL_SCANCODE_UNKNOWN, /* KEY_SLOW */ + /* 410, 0x19a */ SDL_SCANCODE_UNKNOWN, /* KEY_SHUFFLE */ + /* 411, 0x19b */ SDL_SCANCODE_UNKNOWN, /* KEY_BREAK */ + /* 412, 0x19c */ SDL_SCANCODE_UNKNOWN, /* KEY_PREVIOUS */ + /* 413, 0x19d */ SDL_SCANCODE_UNKNOWN, /* KEY_DIGITS */ + /* 414, 0x19e */ SDL_SCANCODE_UNKNOWN, /* KEY_TEEN */ + /* 415, 0x19f */ SDL_SCANCODE_UNKNOWN, /* KEY_TWEN */ + /* 416, 0x1a0 */ SDL_SCANCODE_UNKNOWN, /* KEY_VIDEOPHONE */ + /* 417, 0x1a1 */ SDL_SCANCODE_UNKNOWN, /* KEY_GAMES */ + /* 418, 0x1a2 */ SDL_SCANCODE_UNKNOWN, /* KEY_ZOOMIN */ + /* 419, 0x1a3 */ SDL_SCANCODE_UNKNOWN, /* KEY_ZOOMOUT */ + /* 420, 0x1a4 */ SDL_SCANCODE_UNKNOWN, /* KEY_ZOOMRESET */ + /* 421, 0x1a5 */ SDL_SCANCODE_UNKNOWN, /* KEY_WORDPROCESSOR */ + /* 422, 0x1a6 */ SDL_SCANCODE_UNKNOWN, /* KEY_EDITOR */ + /* 423, 0x1a7 */ SDL_SCANCODE_UNKNOWN, /* KEY_SPREADSHEET */ + /* 424, 0x1a8 */ SDL_SCANCODE_UNKNOWN, /* KEY_GRAPHICSEDITOR */ + /* 425, 0x1a9 */ SDL_SCANCODE_UNKNOWN, /* KEY_PRESENTATION */ + /* 426, 0x1aa */ SDL_SCANCODE_UNKNOWN, /* KEY_DATABASE */ + /* 427, 0x1ab */ SDL_SCANCODE_UNKNOWN, /* KEY_NEWS */ + /* 428, 0x1ac */ SDL_SCANCODE_UNKNOWN, /* KEY_VOICEMAIL */ + /* 429, 0x1ad */ SDL_SCANCODE_UNKNOWN, /* KEY_ADDRESSBOOK */ + /* 430, 0x1ae */ SDL_SCANCODE_UNKNOWN, /* KEY_MESSENGER */ + /* 431, 0x1af */ SDL_SCANCODE_UNKNOWN, /* KEY_DISPLAYTOGGLE */ + /* 432, 0x1b0 */ SDL_SCANCODE_UNKNOWN, /* KEY_SPELLCHECK */ + /* 433, 0x1b1 */ SDL_SCANCODE_UNKNOWN, /* KEY_LOGOFF */ + /* 434, 0x1b2 */ SDL_SCANCODE_UNKNOWN, /* KEY_DOLLAR */ + /* 435, 0x1b3 */ SDL_SCANCODE_UNKNOWN, /* KEY_EURO */ + /* 436, 0x1b4 */ SDL_SCANCODE_UNKNOWN, /* KEY_FRAMEBACK */ + /* 437, 0x1b5 */ SDL_SCANCODE_UNKNOWN, /* KEY_FRAMEFORWARD */ + /* 438, 0x1b6 */ SDL_SCANCODE_UNKNOWN, /* KEY_CONTEXT_MENU */ + /* 439, 0x1b7 */ SDL_SCANCODE_UNKNOWN, /* KEY_MEDIA_REPEAT */ + /* 440, 0x1b8 */ SDL_SCANCODE_UNKNOWN, /* KEY_10CHANNELSUP */ + /* 441, 0x1b9 */ SDL_SCANCODE_UNKNOWN, /* KEY_10CHANNELSDOWN */ + /* 442, 0x1ba */ SDL_SCANCODE_UNKNOWN, /* KEY_IMAGES */ + /* 443, 0x1bb */ SDL_SCANCODE_UNKNOWN, + /* 444, 0x1bc */ SDL_SCANCODE_UNKNOWN, /* KEY_NOTIFICATION_CENTER */ + /* 445, 0x1bd */ SDL_SCANCODE_UNKNOWN, /* KEY_PICKUP_PHONE */ + /* 446, 0x1be */ SDL_SCANCODE_UNKNOWN, /* KEY_HANGUP_PHONE */ + /* 447, 0x1bf */ SDL_SCANCODE_UNKNOWN, + /* 448, 0x1c0 */ SDL_SCANCODE_UNKNOWN, /* KEY_DEL_EOL */ + /* 449, 0x1c1 */ SDL_SCANCODE_UNKNOWN, /* KEY_DEL_EOS */ + /* 450, 0x1c2 */ SDL_SCANCODE_UNKNOWN, /* KEY_INS_LINE */ + /* 451, 0x1c3 */ SDL_SCANCODE_UNKNOWN, /* KEY_DEL_LINE */ + /* 452, 0x1c4 */ SDL_SCANCODE_UNKNOWN, + /* 453, 0x1c5 */ SDL_SCANCODE_UNKNOWN, + /* 454, 0x1c6 */ SDL_SCANCODE_UNKNOWN, + /* 455, 0x1c7 */ SDL_SCANCODE_UNKNOWN, + /* 456, 0x1c8 */ SDL_SCANCODE_UNKNOWN, + /* 457, 0x1c9 */ SDL_SCANCODE_UNKNOWN, + /* 458, 0x1ca */ SDL_SCANCODE_UNKNOWN, + /* 459, 0x1cb */ SDL_SCANCODE_UNKNOWN, + /* 460, 0x1cc */ SDL_SCANCODE_UNKNOWN, + /* 461, 0x1cd */ SDL_SCANCODE_UNKNOWN, + /* 462, 0x1ce */ SDL_SCANCODE_UNKNOWN, + /* 463, 0x1cf */ SDL_SCANCODE_UNKNOWN, + /* 464, 0x1d0 */ SDL_SCANCODE_UNKNOWN, /* KEY_FN */ + /* 465, 0x1d1 */ SDL_SCANCODE_UNKNOWN, /* KEY_FN_ESC */ + /* 466, 0x1d2 */ SDL_SCANCODE_UNKNOWN, /* KEY_FN_F1 */ + /* 467, 0x1d3 */ SDL_SCANCODE_UNKNOWN, /* KEY_FN_F2 */ + /* 468, 0x1d4 */ SDL_SCANCODE_UNKNOWN, /* KEY_FN_F3 */ + /* 469, 0x1d5 */ SDL_SCANCODE_UNKNOWN, /* KEY_FN_F4 */ + /* 470, 0x1d6 */ SDL_SCANCODE_UNKNOWN, /* KEY_FN_F5 */ + /* 471, 0x1d7 */ SDL_SCANCODE_UNKNOWN, /* KEY_FN_F6 */ + /* 472, 0x1d8 */ SDL_SCANCODE_UNKNOWN, /* KEY_FN_F7 */ + /* 473, 0x1d9 */ SDL_SCANCODE_UNKNOWN, /* KEY_FN_F8 */ + /* 474, 0x1da */ SDL_SCANCODE_UNKNOWN, /* KEY_FN_F9 */ + /* 475, 0x1db */ SDL_SCANCODE_UNKNOWN, /* KEY_FN_F10 */ + /* 476, 0x1dc */ SDL_SCANCODE_UNKNOWN, /* KEY_FN_F11 */ + /* 477, 0x1dd */ SDL_SCANCODE_UNKNOWN, /* KEY_FN_F12 */ + /* 478, 0x1de */ SDL_SCANCODE_UNKNOWN, /* KEY_FN_1 */ + /* 479, 0x1df */ SDL_SCANCODE_UNKNOWN, /* KEY_FN_2 */ + /* 480, 0x1e0 */ SDL_SCANCODE_UNKNOWN, /* KEY_FN_D */ + /* 481, 0x1e1 */ SDL_SCANCODE_UNKNOWN, /* KEY_FN_E */ + /* 482, 0x1e2 */ SDL_SCANCODE_UNKNOWN, /* KEY_FN_F */ + /* 483, 0x1e3 */ SDL_SCANCODE_UNKNOWN, /* KEY_FN_S */ + /* 484, 0x1e4 */ SDL_SCANCODE_UNKNOWN, /* KEY_FN_B */ + /* 485, 0x1e5 */ SDL_SCANCODE_UNKNOWN, /* KEY_FN_RIGHT_SHIFT */ + /* 486, 0x1e6 */ SDL_SCANCODE_UNKNOWN, + /* 487, 0x1e7 */ SDL_SCANCODE_UNKNOWN, + /* 488, 0x1e8 */ SDL_SCANCODE_UNKNOWN, + /* 489, 0x1e9 */ SDL_SCANCODE_UNKNOWN, + /* 490, 0x1ea */ SDL_SCANCODE_UNKNOWN, + /* 491, 0x1eb */ SDL_SCANCODE_UNKNOWN, + /* 492, 0x1ec */ SDL_SCANCODE_UNKNOWN, + /* 493, 0x1ed */ SDL_SCANCODE_UNKNOWN, + /* 494, 0x1ee */ SDL_SCANCODE_UNKNOWN, + /* 495, 0x1ef */ SDL_SCANCODE_UNKNOWN, + /* 496, 0x1f0 */ SDL_SCANCODE_UNKNOWN, + /* 497, 0x1f1 */ SDL_SCANCODE_UNKNOWN, /* KEY_BRL_DOT1 */ + /* 498, 0x1f2 */ SDL_SCANCODE_UNKNOWN, /* KEY_BRL_DOT2 */ + /* 499, 0x1f3 */ SDL_SCANCODE_UNKNOWN, /* KEY_BRL_DOT3 */ + /* 500, 0x1f4 */ SDL_SCANCODE_UNKNOWN, /* KEY_BRL_DOT4 */ + /* 501, 0x1f5 */ SDL_SCANCODE_UNKNOWN, /* KEY_BRL_DOT5 */ + /* 502, 0x1f6 */ SDL_SCANCODE_UNKNOWN, /* KEY_BRL_DOT6 */ + /* 503, 0x1f7 */ SDL_SCANCODE_UNKNOWN, /* KEY_BRL_DOT7 */ + /* 504, 0x1f8 */ SDL_SCANCODE_UNKNOWN, /* KEY_BRL_DOT8 */ + /* 505, 0x1f9 */ SDL_SCANCODE_UNKNOWN, /* KEY_BRL_DOT9 */ + /* 506, 0x1fa */ SDL_SCANCODE_UNKNOWN, /* KEY_BRL_DOT10 */ + /* 507, 0x1fb */ SDL_SCANCODE_UNKNOWN, + /* 508, 0x1fc */ SDL_SCANCODE_UNKNOWN, + /* 509, 0x1fd */ SDL_SCANCODE_UNKNOWN, + /* 510, 0x1fe */ SDL_SCANCODE_UNKNOWN, + /* 511, 0x1ff */ SDL_SCANCODE_UNKNOWN, + /* 512, 0x200 */ SDL_SCANCODE_UNKNOWN, /* KEY_NUMERIC_0 */ + /* 513, 0x201 */ SDL_SCANCODE_UNKNOWN, /* KEY_NUMERIC_1 */ + /* 514, 0x202 */ SDL_SCANCODE_UNKNOWN, /* KEY_NUMERIC_2 */ + /* 515, 0x203 */ SDL_SCANCODE_UNKNOWN, /* KEY_NUMERIC_3 */ + /* 516, 0x204 */ SDL_SCANCODE_UNKNOWN, /* KEY_NUMERIC_4 */ + /* 517, 0x205 */ SDL_SCANCODE_UNKNOWN, /* KEY_NUMERIC_5 */ + /* 518, 0x206 */ SDL_SCANCODE_UNKNOWN, /* KEY_NUMERIC_6 */ + /* 519, 0x207 */ SDL_SCANCODE_UNKNOWN, /* KEY_NUMERIC_7 */ + /* 520, 0x208 */ SDL_SCANCODE_UNKNOWN, /* KEY_NUMERIC_8 */ + /* 521, 0x209 */ SDL_SCANCODE_UNKNOWN, /* KEY_NUMERIC_9 */ + /* 522, 0x20a */ SDL_SCANCODE_UNKNOWN, /* KEY_NUMERIC_STAR */ + /* 523, 0x20b */ SDL_SCANCODE_UNKNOWN, /* KEY_NUMERIC_POUND */ + /* 524, 0x20c */ SDL_SCANCODE_UNKNOWN, /* KEY_NUMERIC_A */ + /* 525, 0x20d */ SDL_SCANCODE_UNKNOWN, /* KEY_NUMERIC_B */ + /* 526, 0x20e */ SDL_SCANCODE_UNKNOWN, /* KEY_NUMERIC_C */ + /* 527, 0x20f */ SDL_SCANCODE_UNKNOWN, /* KEY_NUMERIC_D */ + /* 528, 0x210 */ SDL_SCANCODE_UNKNOWN, /* KEY_CAMERA_FOCUS */ + /* 529, 0x211 */ SDL_SCANCODE_UNKNOWN, /* KEY_WPS_BUTTON */ + /* 530, 0x212 */ SDL_SCANCODE_UNKNOWN, /* KEY_TOUCHPAD_TOGGLE */ + /* 531, 0x213 */ SDL_SCANCODE_UNKNOWN, /* KEY_TOUCHPAD_ON */ + /* 532, 0x214 */ SDL_SCANCODE_UNKNOWN, /* KEY_TOUCHPAD_OFF */ + /* 533, 0x215 */ SDL_SCANCODE_UNKNOWN, /* KEY_CAMERA_ZOOMIN */ + /* 534, 0x216 */ SDL_SCANCODE_UNKNOWN, /* KEY_CAMERA_ZOOMOUT */ + /* 535, 0x217 */ SDL_SCANCODE_UNKNOWN, /* KEY_CAMERA_UP */ + /* 536, 0x218 */ SDL_SCANCODE_UNKNOWN, /* KEY_CAMERA_DOWN */ + /* 537, 0x219 */ SDL_SCANCODE_UNKNOWN, /* KEY_CAMERA_LEFT */ + /* 538, 0x21a */ SDL_SCANCODE_UNKNOWN, /* KEY_CAMERA_RIGHT */ + /* 539, 0x21b */ SDL_SCANCODE_UNKNOWN, /* KEY_ATTENDANT_ON */ + /* 540, 0x21c */ SDL_SCANCODE_UNKNOWN, /* KEY_ATTENDANT_OFF */ + /* 541, 0x21d */ SDL_SCANCODE_UNKNOWN, /* KEY_ATTENDANT_TOGGLE */ + /* 542, 0x21e */ SDL_SCANCODE_UNKNOWN, /* KEY_LIGHTS_TOGGLE */ + /* 543, 0x21f */ SDL_SCANCODE_UNKNOWN, + /* 544, 0x220 */ SDL_SCANCODE_UNKNOWN, + /* 545, 0x221 */ SDL_SCANCODE_UNKNOWN, + /* 546, 0x222 */ SDL_SCANCODE_UNKNOWN, + /* 547, 0x223 */ SDL_SCANCODE_UNKNOWN, + /* 548, 0x224 */ SDL_SCANCODE_UNKNOWN, + /* 549, 0x225 */ SDL_SCANCODE_UNKNOWN, + /* 550, 0x226 */ SDL_SCANCODE_UNKNOWN, + /* 551, 0x227 */ SDL_SCANCODE_UNKNOWN, + /* 552, 0x228 */ SDL_SCANCODE_UNKNOWN, + /* 553, 0x229 */ SDL_SCANCODE_UNKNOWN, + /* 554, 0x22a */ SDL_SCANCODE_UNKNOWN, + /* 555, 0x22b */ SDL_SCANCODE_UNKNOWN, + /* 556, 0x22c */ SDL_SCANCODE_UNKNOWN, + /* 557, 0x22d */ SDL_SCANCODE_UNKNOWN, + /* 558, 0x22e */ SDL_SCANCODE_UNKNOWN, + /* 559, 0x22f */ SDL_SCANCODE_UNKNOWN, + /* 560, 0x230 */ SDL_SCANCODE_UNKNOWN, /* KEY_ALS_TOGGLE */ + /* 561, 0x231 */ SDL_SCANCODE_UNKNOWN, /* KEY_ROTATE_LOCK_TOGGLE */ + /* 562, 0x232 */ SDL_SCANCODE_UNKNOWN, + /* 563, 0x233 */ SDL_SCANCODE_UNKNOWN, + /* 564, 0x234 */ SDL_SCANCODE_UNKNOWN, + /* 565, 0x235 */ SDL_SCANCODE_UNKNOWN, + /* 566, 0x236 */ SDL_SCANCODE_UNKNOWN, + /* 567, 0x237 */ SDL_SCANCODE_UNKNOWN, + /* 568, 0x238 */ SDL_SCANCODE_UNKNOWN, + /* 569, 0x239 */ SDL_SCANCODE_UNKNOWN, + /* 570, 0x23a */ SDL_SCANCODE_UNKNOWN, + /* 571, 0x23b */ SDL_SCANCODE_UNKNOWN, + /* 572, 0x23c */ SDL_SCANCODE_UNKNOWN, + /* 573, 0x23d */ SDL_SCANCODE_UNKNOWN, + /* 574, 0x23e */ SDL_SCANCODE_UNKNOWN, + /* 575, 0x23f */ SDL_SCANCODE_UNKNOWN, + /* 576, 0x240 */ SDL_SCANCODE_UNKNOWN, /* KEY_BUTTONCONFIG */ + /* 577, 0x241 */ SDL_SCANCODE_UNKNOWN, /* KEY_TASKMANAGER */ + /* 578, 0x242 */ SDL_SCANCODE_UNKNOWN, /* KEY_JOURNAL */ + /* 579, 0x243 */ SDL_SCANCODE_UNKNOWN, /* KEY_CONTROLPANEL */ + /* 580, 0x244 */ SDL_SCANCODE_UNKNOWN, /* KEY_APPSELECT */ + /* 581, 0x245 */ SDL_SCANCODE_UNKNOWN, /* KEY_SCREENSAVER */ + /* 582, 0x246 */ SDL_SCANCODE_UNKNOWN, /* KEY_VOICECOMMAND */ + /* 583, 0x247 */ SDL_SCANCODE_UNKNOWN, /* KEY_ASSISTANT */ + /* 584, 0x248 */ SDL_SCANCODE_UNKNOWN, /* KEY_KBD_LAYOUT_NEXT */ + /* 585, 0x249 */ SDL_SCANCODE_UNKNOWN, /* KEY_EMOJI_PICKER */ + /* 586, 0x24a */ SDL_SCANCODE_UNKNOWN, /* KEY_DICTATE */ + /* 587, 0x24b */ SDL_SCANCODE_UNKNOWN, + /* 588, 0x24c */ SDL_SCANCODE_UNKNOWN, + /* 589, 0x24d */ SDL_SCANCODE_UNKNOWN, + /* 590, 0x24e */ SDL_SCANCODE_UNKNOWN, + /* 591, 0x24f */ SDL_SCANCODE_UNKNOWN, + /* 592, 0x250 */ SDL_SCANCODE_UNKNOWN, /* KEY_BRIGHTNESS_MIN */ + /* 593, 0x251 */ SDL_SCANCODE_UNKNOWN, /* KEY_BRIGHTNESS_MAX */ + /* 594, 0x252 */ SDL_SCANCODE_UNKNOWN, + /* 595, 0x253 */ SDL_SCANCODE_UNKNOWN, + /* 596, 0x254 */ SDL_SCANCODE_UNKNOWN, + /* 597, 0x255 */ SDL_SCANCODE_UNKNOWN, + /* 598, 0x256 */ SDL_SCANCODE_UNKNOWN, + /* 599, 0x257 */ SDL_SCANCODE_UNKNOWN, + /* 600, 0x258 */ SDL_SCANCODE_UNKNOWN, + /* 601, 0x259 */ SDL_SCANCODE_UNKNOWN, + /* 602, 0x25a */ SDL_SCANCODE_UNKNOWN, + /* 603, 0x25b */ SDL_SCANCODE_UNKNOWN, + /* 604, 0x25c */ SDL_SCANCODE_UNKNOWN, + /* 605, 0x25d */ SDL_SCANCODE_UNKNOWN, + /* 606, 0x25e */ SDL_SCANCODE_UNKNOWN, + /* 607, 0x25f */ SDL_SCANCODE_UNKNOWN, + /* 608, 0x260 */ SDL_SCANCODE_UNKNOWN, /* KEY_KBDINPUTASSIST_PREV */ + /* 609, 0x261 */ SDL_SCANCODE_UNKNOWN, /* KEY_KBDINPUTASSIST_NEXT */ + /* 610, 0x262 */ SDL_SCANCODE_UNKNOWN, /* KEY_KBDINPUTASSIST_PREVGROUP */ + /* 611, 0x263 */ SDL_SCANCODE_UNKNOWN, /* KEY_KBDINPUTASSIST_NEXTGROUP */ + /* 612, 0x264 */ SDL_SCANCODE_UNKNOWN, /* KEY_KBDINPUTASSIST_ACCEPT */ + /* 613, 0x265 */ SDL_SCANCODE_UNKNOWN, /* KEY_KBDINPUTASSIST_CANCEL */ + /* 614, 0x266 */ SDL_SCANCODE_UNKNOWN, /* KEY_RIGHT_UP */ + /* 615, 0x267 */ SDL_SCANCODE_UNKNOWN, /* KEY_RIGHT_DOWN */ + /* 616, 0x268 */ SDL_SCANCODE_UNKNOWN, /* KEY_LEFT_UP */ + /* 617, 0x269 */ SDL_SCANCODE_UNKNOWN, /* KEY_LEFT_DOWN */ + /* 618, 0x26a */ SDL_SCANCODE_UNKNOWN, /* KEY_ROOT_MENU */ + /* 619, 0x26b */ SDL_SCANCODE_UNKNOWN, /* KEY_MEDIA_TOP_MENU */ + /* 620, 0x26c */ SDL_SCANCODE_UNKNOWN, /* KEY_NUMERIC_11 */ + /* 621, 0x26d */ SDL_SCANCODE_UNKNOWN, /* KEY_NUMERIC_12 */ + /* 622, 0x26e */ SDL_SCANCODE_UNKNOWN, /* KEY_AUDIO_DESC */ + /* 623, 0x26f */ SDL_SCANCODE_UNKNOWN, /* KEY_3D_MODE */ + /* 624, 0x270 */ SDL_SCANCODE_UNKNOWN, /* KEY_NEXT_FAVORITE */ + /* 625, 0x271 */ SDL_SCANCODE_UNKNOWN, /* KEY_STOP_RECORD */ + /* 626, 0x272 */ SDL_SCANCODE_UNKNOWN, /* KEY_PAUSE_RECORD */ + /* 627, 0x273 */ SDL_SCANCODE_UNKNOWN, /* KEY_VOD */ + /* 628, 0x274 */ SDL_SCANCODE_UNKNOWN, /* KEY_UNMUTE */ + /* 629, 0x275 */ SDL_SCANCODE_UNKNOWN, /* KEY_FASTREVERSE */ + /* 630, 0x276 */ SDL_SCANCODE_UNKNOWN, /* KEY_SLOWREVERSE */ + /* 631, 0x277 */ SDL_SCANCODE_UNKNOWN, /* KEY_DATA */ + /* 632, 0x278 */ SDL_SCANCODE_UNKNOWN, /* KEY_ONSCREEN_KEYBOARD */ + /* 633, 0x279 */ SDL_SCANCODE_UNKNOWN, /* KEY_PRIVACY_SCREEN_TOGGLE */ + /* 634, 0x27a */ SDL_SCANCODE_UNKNOWN, /* KEY_SELECTIVE_SCREENSHOT */ + /* 635, 0x27b */ SDL_SCANCODE_UNKNOWN, + /* 636, 0x27c */ SDL_SCANCODE_UNKNOWN, + /* 637, 0x27d */ SDL_SCANCODE_UNKNOWN, + /* 638, 0x27e */ SDL_SCANCODE_UNKNOWN, + /* 639, 0x27f */ SDL_SCANCODE_UNKNOWN, + /* 640, 0x280 */ SDL_SCANCODE_UNKNOWN, + /* 641, 0x281 */ SDL_SCANCODE_UNKNOWN, + /* 642, 0x282 */ SDL_SCANCODE_UNKNOWN, + /* 643, 0x283 */ SDL_SCANCODE_UNKNOWN, + /* 644, 0x284 */ SDL_SCANCODE_UNKNOWN, + /* 645, 0x285 */ SDL_SCANCODE_UNKNOWN, + /* 646, 0x286 */ SDL_SCANCODE_UNKNOWN, + /* 647, 0x287 */ SDL_SCANCODE_UNKNOWN, + /* 648, 0x288 */ SDL_SCANCODE_UNKNOWN, + /* 649, 0x289 */ SDL_SCANCODE_UNKNOWN, + /* 650, 0x28a */ SDL_SCANCODE_UNKNOWN, + /* 651, 0x28b */ SDL_SCANCODE_UNKNOWN, + /* 652, 0x28c */ SDL_SCANCODE_UNKNOWN, + /* 653, 0x28d */ SDL_SCANCODE_UNKNOWN, + /* 654, 0x28e */ SDL_SCANCODE_UNKNOWN, + /* 655, 0x28f */ SDL_SCANCODE_UNKNOWN, + /* 656, 0x290 */ SDL_SCANCODE_UNKNOWN, /* KEY_MACRO1 */ + /* 657, 0x291 */ SDL_SCANCODE_UNKNOWN, /* KEY_MACRO2 */ + /* 658, 0x292 */ SDL_SCANCODE_UNKNOWN, /* KEY_MACRO3 */ + /* 659, 0x293 */ SDL_SCANCODE_UNKNOWN, /* KEY_MACRO4 */ + /* 660, 0x294 */ SDL_SCANCODE_UNKNOWN, /* KEY_MACRO5 */ + /* 661, 0x295 */ SDL_SCANCODE_UNKNOWN, /* KEY_MACRO6 */ + /* 662, 0x296 */ SDL_SCANCODE_UNKNOWN, /* KEY_MACRO7 */ + /* 663, 0x297 */ SDL_SCANCODE_UNKNOWN, /* KEY_MACRO8 */ + /* 664, 0x298 */ SDL_SCANCODE_UNKNOWN, /* KEY_MACRO9 */ + /* 665, 0x299 */ SDL_SCANCODE_UNKNOWN, /* KEY_MACRO10 */ + /* 666, 0x29a */ SDL_SCANCODE_UNKNOWN, /* KEY_MACRO11 */ + /* 667, 0x29b */ SDL_SCANCODE_UNKNOWN, /* KEY_MACRO12 */ + /* 668, 0x29c */ SDL_SCANCODE_UNKNOWN, /* KEY_MACRO13 */ + /* 669, 0x29d */ SDL_SCANCODE_UNKNOWN, /* KEY_MACRO14 */ + /* 670, 0x29e */ SDL_SCANCODE_UNKNOWN, /* KEY_MACRO15 */ + /* 671, 0x29f */ SDL_SCANCODE_UNKNOWN, /* KEY_MACRO16 */ + /* 672, 0x2a0 */ SDL_SCANCODE_UNKNOWN, /* KEY_MACRO17 */ + /* 673, 0x2a1 */ SDL_SCANCODE_UNKNOWN, /* KEY_MACRO18 */ + /* 674, 0x2a2 */ SDL_SCANCODE_UNKNOWN, /* KEY_MACRO19 */ + /* 675, 0x2a3 */ SDL_SCANCODE_UNKNOWN, /* KEY_MACRO20 */ + /* 676, 0x2a4 */ SDL_SCANCODE_UNKNOWN, /* KEY_MACRO21 */ + /* 677, 0x2a5 */ SDL_SCANCODE_UNKNOWN, /* KEY_MACRO22 */ + /* 678, 0x2a6 */ SDL_SCANCODE_UNKNOWN, /* KEY_MACRO23 */ + /* 679, 0x2a7 */ SDL_SCANCODE_UNKNOWN, /* KEY_MACRO24 */ + /* 680, 0x2a8 */ SDL_SCANCODE_UNKNOWN, /* KEY_MACRO25 */ + /* 681, 0x2a9 */ SDL_SCANCODE_UNKNOWN, /* KEY_MACRO26 */ + /* 682, 0x2aa */ SDL_SCANCODE_UNKNOWN, /* KEY_MACRO27 */ + /* 683, 0x2ab */ SDL_SCANCODE_UNKNOWN, /* KEY_MACRO28 */ + /* 684, 0x2ac */ SDL_SCANCODE_UNKNOWN, /* KEY_MACRO29 */ + /* 685, 0x2ad */ SDL_SCANCODE_UNKNOWN, /* KEY_MACRO30 */ + /* 686, 0x2ae */ SDL_SCANCODE_UNKNOWN, + /* 687, 0x2af */ SDL_SCANCODE_UNKNOWN, + /* 688, 0x2b0 */ SDL_SCANCODE_UNKNOWN, /* KEY_MACRO_RECORD_START */ + /* 689, 0x2b1 */ SDL_SCANCODE_UNKNOWN, /* KEY_MACRO_RECORD_STOP */ + /* 690, 0x2b2 */ SDL_SCANCODE_UNKNOWN, /* KEY_MACRO_PRESET_CYCLE */ + /* 691, 0x2b3 */ SDL_SCANCODE_UNKNOWN, /* KEY_MACRO_PRESET1 */ + /* 692, 0x2b4 */ SDL_SCANCODE_UNKNOWN, /* KEY_MACRO_PRESET2 */ + /* 693, 0x2b5 */ SDL_SCANCODE_UNKNOWN, /* KEY_MACRO_PRESET3 */ + /* 694, 0x2b6 */ SDL_SCANCODE_UNKNOWN, + /* 695, 0x2b7 */ SDL_SCANCODE_UNKNOWN, + /* 696, 0x2b8 */ SDL_SCANCODE_UNKNOWN, /* KEY_KBD_LCD_MENU1 */ + /* 697, 0x2b9 */ SDL_SCANCODE_UNKNOWN, /* KEY_KBD_LCD_MENU2 */ + /* 698, 0x2ba */ SDL_SCANCODE_UNKNOWN, /* KEY_KBD_LCD_MENU3 */ + /* 699, 0x2bb */ SDL_SCANCODE_UNKNOWN, /* KEY_KBD_LCD_MENU4 */ + /* 700, 0x2bc */ SDL_SCANCODE_UNKNOWN, /* KEY_KBD_LCD_MENU5 */ + /* 701, 0x2bd */ SDL_SCANCODE_UNKNOWN, + /* 702, 0x2be */ SDL_SCANCODE_UNKNOWN, + /* 703, 0x2bf */ SDL_SCANCODE_UNKNOWN, + /* 704, 0x2c0 */ SDL_SCANCODE_UNKNOWN, + /* 705, 0x2c1 */ SDL_SCANCODE_UNKNOWN, + /* 706, 0x2c2 */ SDL_SCANCODE_UNKNOWN, + /* 707, 0x2c3 */ SDL_SCANCODE_UNKNOWN, + /* 708, 0x2c4 */ SDL_SCANCODE_UNKNOWN, + /* 709, 0x2c5 */ SDL_SCANCODE_UNKNOWN, + /* 710, 0x2c6 */ SDL_SCANCODE_UNKNOWN, + /* 711, 0x2c7 */ SDL_SCANCODE_UNKNOWN, + /* 712, 0x2c8 */ SDL_SCANCODE_UNKNOWN, + /* 713, 0x2c9 */ SDL_SCANCODE_UNKNOWN, + /* 714, 0x2ca */ SDL_SCANCODE_UNKNOWN, + /* 715, 0x2cb */ SDL_SCANCODE_UNKNOWN, + /* 716, 0x2cc */ SDL_SCANCODE_UNKNOWN, + /* 717, 0x2cd */ SDL_SCANCODE_UNKNOWN, + /* 718, 0x2ce */ SDL_SCANCODE_UNKNOWN, + /* 719, 0x2cf */ SDL_SCANCODE_UNKNOWN, + /* 720, 0x2d0 */ SDL_SCANCODE_UNKNOWN, + /* 721, 0x2d1 */ SDL_SCANCODE_UNKNOWN, + /* 722, 0x2d2 */ SDL_SCANCODE_UNKNOWN, + /* 723, 0x2d3 */ SDL_SCANCODE_UNKNOWN, + /* 724, 0x2d4 */ SDL_SCANCODE_UNKNOWN, + /* 725, 0x2d5 */ SDL_SCANCODE_UNKNOWN, + /* 726, 0x2d6 */ SDL_SCANCODE_UNKNOWN, + /* 727, 0x2d7 */ SDL_SCANCODE_UNKNOWN, + /* 728, 0x2d8 */ SDL_SCANCODE_UNKNOWN, + /* 729, 0x2d9 */ SDL_SCANCODE_UNKNOWN, + /* 730, 0x2da */ SDL_SCANCODE_UNKNOWN, + /* 731, 0x2db */ SDL_SCANCODE_UNKNOWN, + /* 732, 0x2dc */ SDL_SCANCODE_UNKNOWN, + /* 733, 0x2dd */ SDL_SCANCODE_UNKNOWN, + /* 734, 0x2de */ SDL_SCANCODE_UNKNOWN, + /* 735, 0x2df */ SDL_SCANCODE_UNKNOWN, + /* 736, 0x2e0 */ SDL_SCANCODE_UNKNOWN, + /* 737, 0x2e1 */ SDL_SCANCODE_UNKNOWN, + /* 738, 0x2e2 */ SDL_SCANCODE_UNKNOWN, + /* 739, 0x2e3 */ SDL_SCANCODE_UNKNOWN, + /* 740, 0x2e4 */ SDL_SCANCODE_UNKNOWN, + /* 741, 0x2e5 */ SDL_SCANCODE_UNKNOWN, + /* 742, 0x2e6 */ SDL_SCANCODE_UNKNOWN, + /* 743, 0x2e7 */ SDL_SCANCODE_UNKNOWN, + /* 744, 0x2e8 */ SDL_SCANCODE_UNKNOWN, + /* 745, 0x2e9 */ SDL_SCANCODE_UNKNOWN, + /* 746, 0x2ea */ SDL_SCANCODE_UNKNOWN, + /* 747, 0x2eb */ SDL_SCANCODE_UNKNOWN, + /* 748, 0x2ec */ SDL_SCANCODE_UNKNOWN, + /* 749, 0x2ed */ SDL_SCANCODE_UNKNOWN, + /* 750, 0x2ee */ SDL_SCANCODE_UNKNOWN, + /* 751, 0x2ef */ SDL_SCANCODE_UNKNOWN, + /* 752, 0x2f0 */ SDL_SCANCODE_UNKNOWN, + /* 753, 0x2f1 */ SDL_SCANCODE_UNKNOWN, + /* 754, 0x2f2 */ SDL_SCANCODE_UNKNOWN, + /* 755, 0x2f3 */ SDL_SCANCODE_UNKNOWN, + /* 756, 0x2f4 */ SDL_SCANCODE_UNKNOWN, + /* 757, 0x2f5 */ SDL_SCANCODE_UNKNOWN, + /* 758, 0x2f6 */ SDL_SCANCODE_UNKNOWN, + /* 759, 0x2f7 */ SDL_SCANCODE_UNKNOWN, + /* 760, 0x2f8 */ SDL_SCANCODE_UNKNOWN, + /* 761, 0x2f9 */ SDL_SCANCODE_UNKNOWN, + /* 762, 0x2fa */ SDL_SCANCODE_UNKNOWN, + /* 763, 0x2fb */ SDL_SCANCODE_UNKNOWN, + /* 764, 0x2fc */ SDL_SCANCODE_UNKNOWN, + /* 765, 0x2fd */ SDL_SCANCODE_UNKNOWN, + /* 766, 0x2fe */ SDL_SCANCODE_UNKNOWN, + /* 767, 0x2ff */ SDL_SCANCODE_UNKNOWN, /* KEY_MAX */ +#endif /* 0 */ +}; + +#if 0 /* A shell script to update the Linux key names in this file */ +#!/bin/bash + +function get_keyname +{ + value=$(echo "$1" | awk '{print $3}') + grep -F KEY_ /usr/include/linux/input-event-codes.h | while read line; do + read -ra fields <<<"$line" + if [ "${fields[2]}" = "$value" ]; then + echo "${fields[1]}" + return + fi + done +} + +grep -F SDL_SCANCODE scancodes_linux.h | while read line; do + if [ $(echo "$line" | awk '{print NF}') -eq 5 ]; then + name=$(get_keyname "$line") + if [ "$name" != "" ]; then + echo " $line /* $name */" + continue + fi + fi + echo " $line" +done +#endif /* end script */ + +#if 0 /* A shell script to get comments from the Linux header for these keys */ +#!/bin/bash + +function get_comment +{ + name=$(echo "$1" | awk '{print $7}') + if [ "$name" != "" ]; then + grep -E "$name\s" /usr/include/linux/input-event-codes.h | grep -F "/*" | sed 's,[^/]*/,/,' + fi +} + +grep -F SDL_SCANCODE scancodes_linux.h | while read line; do + comment=$(get_comment "$line") + if [ "$comment" != "" ]; then + echo " $line $comment" + fi +done +#endif /* end script */ + + +/* *INDENT-ON* */ /* clang-format on */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/events/scancodes_windows.h b/SDL2-2.30.5/src/events/scancodes_windows.h similarity index 95% rename from SDL2-2.0.12/src/events/scancodes_windows.h rename to SDL2-2.30.5/src/events/scancodes_windows.h index 3ff6121..e902e76 100644 --- a/SDL2-2.0.12/src/events/scancodes_windows.h +++ b/SDL2-2.30.5/src/events/scancodes_windows.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,7 +23,7 @@ /* Windows scancode to SDL scancode mapping table */ /* derived from Microsoft scan code document, http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/scancode.doc */ -/* *INDENT-OFF* */ +/* *INDENT-OFF* */ /* clang-format off */ static const SDL_Scancode windows_scancode_table[] = { /* 0 1 2 3 4 5 6 7 */ @@ -52,4 +52,6 @@ static const SDL_Scancode windows_scancode_table[] = SDL_SCANCODE_INTERNATIONAL2, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_INTERNATIONAL1, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, /* 7 */ SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_INTERNATIONAL4, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_INTERNATIONAL5, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_INTERNATIONAL3, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN /* 7 */ }; -/* *INDENT-ON* */ +/* *INDENT-ON* */ /* clang-format on */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/events/scancodes_xfree86.h b/SDL2-2.30.5/src/events/scancodes_xfree86.h new file mode 100644 index 0000000..20d02fe --- /dev/null +++ b/SDL2-2.30.5/src/events/scancodes_xfree86.h @@ -0,0 +1,523 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#ifndef scancodes_xfree86_h_ +#define scancodes_xfree86_h_ + +#include "../../include/SDL_scancode.h" + +/* XFree86 key code to SDL scancode mapping table + Sources: + - atKeyNames.h from XFree86 source code +*/ +/* *INDENT-OFF* */ /* clang-format off */ +static const SDL_Scancode xfree86_scancode_table[] = { + /* 0 */ SDL_SCANCODE_UNKNOWN, + /* 1 */ SDL_SCANCODE_ESCAPE, + /* 2 */ SDL_SCANCODE_1, + /* 3 */ SDL_SCANCODE_2, + /* 4 */ SDL_SCANCODE_3, + /* 5 */ SDL_SCANCODE_4, + /* 6 */ SDL_SCANCODE_5, + /* 7 */ SDL_SCANCODE_6, + /* 8 */ SDL_SCANCODE_7, + /* 9 */ SDL_SCANCODE_8, + /* 10 */ SDL_SCANCODE_9, + /* 11 */ SDL_SCANCODE_0, + /* 12 */ SDL_SCANCODE_MINUS, + /* 13 */ SDL_SCANCODE_EQUALS, + /* 14 */ SDL_SCANCODE_BACKSPACE, + /* 15 */ SDL_SCANCODE_TAB, + /* 16 */ SDL_SCANCODE_Q, + /* 17 */ SDL_SCANCODE_W, + /* 18 */ SDL_SCANCODE_E, + /* 19 */ SDL_SCANCODE_R, + /* 20 */ SDL_SCANCODE_T, + /* 21 */ SDL_SCANCODE_Y, + /* 22 */ SDL_SCANCODE_U, + /* 23 */ SDL_SCANCODE_I, + /* 24 */ SDL_SCANCODE_O, + /* 25 */ SDL_SCANCODE_P, + /* 26 */ SDL_SCANCODE_LEFTBRACKET, + /* 27 */ SDL_SCANCODE_RIGHTBRACKET, + /* 28 */ SDL_SCANCODE_RETURN, + /* 29 */ SDL_SCANCODE_LCTRL, + /* 30 */ SDL_SCANCODE_A, + /* 31 */ SDL_SCANCODE_S, + /* 32 */ SDL_SCANCODE_D, + /* 33 */ SDL_SCANCODE_F, + /* 34 */ SDL_SCANCODE_G, + /* 35 */ SDL_SCANCODE_H, + /* 36 */ SDL_SCANCODE_J, + /* 37 */ SDL_SCANCODE_K, + /* 38 */ SDL_SCANCODE_L, + /* 39 */ SDL_SCANCODE_SEMICOLON, + /* 40 */ SDL_SCANCODE_APOSTROPHE, + /* 41 */ SDL_SCANCODE_GRAVE, + /* 42 */ SDL_SCANCODE_LSHIFT, + /* 43 */ SDL_SCANCODE_BACKSLASH, + /* 44 */ SDL_SCANCODE_Z, + /* 45 */ SDL_SCANCODE_X, + /* 46 */ SDL_SCANCODE_C, + /* 47 */ SDL_SCANCODE_V, + /* 48 */ SDL_SCANCODE_B, + /* 49 */ SDL_SCANCODE_N, + /* 50 */ SDL_SCANCODE_M, + /* 51 */ SDL_SCANCODE_COMMA, + /* 52 */ SDL_SCANCODE_PERIOD, + /* 53 */ SDL_SCANCODE_SLASH, + /* 54 */ SDL_SCANCODE_RSHIFT, + /* 55 */ SDL_SCANCODE_KP_MULTIPLY, + /* 56 */ SDL_SCANCODE_LALT, + /* 57 */ SDL_SCANCODE_SPACE, + /* 58 */ SDL_SCANCODE_CAPSLOCK, + /* 59 */ SDL_SCANCODE_F1, + /* 60 */ SDL_SCANCODE_F2, + /* 61 */ SDL_SCANCODE_F3, + /* 62 */ SDL_SCANCODE_F4, + /* 63 */ SDL_SCANCODE_F5, + /* 64 */ SDL_SCANCODE_F6, + /* 65 */ SDL_SCANCODE_F7, + /* 66 */ SDL_SCANCODE_F8, + /* 67 */ SDL_SCANCODE_F9, + /* 68 */ SDL_SCANCODE_F10, + /* 69 */ SDL_SCANCODE_NUMLOCKCLEAR, + /* 70 */ SDL_SCANCODE_SCROLLLOCK, + /* 71 */ SDL_SCANCODE_KP_7, + /* 72 */ SDL_SCANCODE_KP_8, + /* 73 */ SDL_SCANCODE_KP_9, + /* 74 */ SDL_SCANCODE_KP_MINUS, + /* 75 */ SDL_SCANCODE_KP_4, + /* 76 */ SDL_SCANCODE_KP_5, + /* 77 */ SDL_SCANCODE_KP_6, + /* 78 */ SDL_SCANCODE_KP_PLUS, + /* 79 */ SDL_SCANCODE_KP_1, + /* 80 */ SDL_SCANCODE_KP_2, + /* 81 */ SDL_SCANCODE_KP_3, + /* 82 */ SDL_SCANCODE_KP_0, + /* 83 */ SDL_SCANCODE_KP_PERIOD, + /* 84 */ SDL_SCANCODE_SYSREQ, + /* 85 */ SDL_SCANCODE_MODE, + /* 86 */ SDL_SCANCODE_NONUSBACKSLASH, + /* 87 */ SDL_SCANCODE_F11, + /* 88 */ SDL_SCANCODE_F12, + /* 89 */ SDL_SCANCODE_HOME, + /* 90 */ SDL_SCANCODE_UP, + /* 91 */ SDL_SCANCODE_PAGEUP, + /* 92 */ SDL_SCANCODE_LEFT, + /* 93 */ SDL_SCANCODE_BRIGHTNESSDOWN, /* on PowerBook G4 / KEY_Begin */ + /* 94 */ SDL_SCANCODE_RIGHT, + /* 95 */ SDL_SCANCODE_END, + /* 96 */ SDL_SCANCODE_DOWN, + /* 97 */ SDL_SCANCODE_PAGEDOWN, + /* 98 */ SDL_SCANCODE_INSERT, + /* 99 */ SDL_SCANCODE_DELETE, + /* 100 */ SDL_SCANCODE_KP_ENTER, + /* 101 */ SDL_SCANCODE_RCTRL, + /* 102 */ SDL_SCANCODE_PAUSE, + /* 103 */ SDL_SCANCODE_PRINTSCREEN, + /* 104 */ SDL_SCANCODE_KP_DIVIDE, + /* 105 */ SDL_SCANCODE_RALT, + /* 106 */ SDL_SCANCODE_UNKNOWN, /* BREAK */ + /* 107 */ SDL_SCANCODE_LGUI, + /* 108 */ SDL_SCANCODE_RGUI, + /* 109 */ SDL_SCANCODE_APPLICATION, + /* 110 */ SDL_SCANCODE_F13, + /* 111 */ SDL_SCANCODE_F14, + /* 112 */ SDL_SCANCODE_F15, + /* 113 */ SDL_SCANCODE_F16, + /* 114 */ SDL_SCANCODE_F17, + /* 115 */ SDL_SCANCODE_INTERNATIONAL1, /* \_ */ + /* 116 */ SDL_SCANCODE_UNKNOWN, /* is translated to XK_ISO_Level3_Shift by my X server, but I have no keyboard that generates this code, so I don't know what the correct SDL_SCANCODE_* for it is */ + /* 117 */ SDL_SCANCODE_UNKNOWN, + /* 118 */ SDL_SCANCODE_KP_EQUALS, + /* 119 */ SDL_SCANCODE_UNKNOWN, + /* 120 */ SDL_SCANCODE_UNKNOWN, + /* 121 */ SDL_SCANCODE_INTERNATIONAL4, /* Henkan_Mode */ + /* 122 */ SDL_SCANCODE_UNKNOWN, + /* 123 */ SDL_SCANCODE_INTERNATIONAL5, /* Muhenkan */ + /* 124 */ SDL_SCANCODE_UNKNOWN, + /* 125 */ SDL_SCANCODE_INTERNATIONAL3, /* Yen */ + /* 126 */ SDL_SCANCODE_UNKNOWN, + /* 127 */ SDL_SCANCODE_UNKNOWN, + /* 128 */ SDL_SCANCODE_UNKNOWN, + /* 129 */ SDL_SCANCODE_UNKNOWN, + /* 130 */ SDL_SCANCODE_UNKNOWN, + /* 131 */ SDL_SCANCODE_UNKNOWN, + /* 132 */ SDL_SCANCODE_POWER, + /* 133 */ SDL_SCANCODE_MUTE, + /* 134 */ SDL_SCANCODE_VOLUMEDOWN, + /* 135 */ SDL_SCANCODE_VOLUMEUP, + /* 136 */ SDL_SCANCODE_HELP, + /* 137 */ SDL_SCANCODE_STOP, + /* 138 */ SDL_SCANCODE_AGAIN, + /* 139 */ SDL_SCANCODE_UNKNOWN, /* PROPS */ + /* 140 */ SDL_SCANCODE_UNDO, + /* 141 */ SDL_SCANCODE_UNKNOWN, /* FRONT */ + /* 142 */ SDL_SCANCODE_COPY, + /* 143 */ SDL_SCANCODE_UNKNOWN, /* OPEN */ + /* 144 */ SDL_SCANCODE_PASTE, + /* 145 */ SDL_SCANCODE_FIND, + /* 146 */ SDL_SCANCODE_CUT, +}; + +/* This is largely identical to the Linux keycode mapping */ +static const SDL_Scancode xfree86_scancode_table2[] = { + /* 0, 0x000 */ SDL_SCANCODE_UNKNOWN, /* NoSymbol */ + /* 1, 0x001 */ SDL_SCANCODE_ESCAPE, /* Escape */ + /* 2, 0x002 */ SDL_SCANCODE_1, /* 1 */ + /* 3, 0x003 */ SDL_SCANCODE_2, /* 2 */ + /* 4, 0x004 */ SDL_SCANCODE_3, /* 3 */ + /* 5, 0x005 */ SDL_SCANCODE_4, /* 4 */ + /* 6, 0x006 */ SDL_SCANCODE_5, /* 5 */ + /* 7, 0x007 */ SDL_SCANCODE_6, /* 6 */ + /* 8, 0x008 */ SDL_SCANCODE_7, /* 7 */ + /* 9, 0x009 */ SDL_SCANCODE_8, /* 8 */ + /* 10, 0x00a */ SDL_SCANCODE_9, /* 9 */ + /* 11, 0x00b */ SDL_SCANCODE_0, /* 0 */ + /* 12, 0x00c */ SDL_SCANCODE_MINUS, /* minus */ + /* 13, 0x00d */ SDL_SCANCODE_EQUALS, /* equal */ + /* 14, 0x00e */ SDL_SCANCODE_BACKSPACE, /* BackSpace */ + /* 15, 0x00f */ SDL_SCANCODE_TAB, /* Tab */ + /* 16, 0x010 */ SDL_SCANCODE_Q, /* q */ + /* 17, 0x011 */ SDL_SCANCODE_W, /* w */ + /* 18, 0x012 */ SDL_SCANCODE_E, /* e */ + /* 19, 0x013 */ SDL_SCANCODE_R, /* r */ + /* 20, 0x014 */ SDL_SCANCODE_T, /* t */ + /* 21, 0x015 */ SDL_SCANCODE_Y, /* y */ + /* 22, 0x016 */ SDL_SCANCODE_U, /* u */ + /* 23, 0x017 */ SDL_SCANCODE_I, /* i */ + /* 24, 0x018 */ SDL_SCANCODE_O, /* o */ + /* 25, 0x019 */ SDL_SCANCODE_P, /* p */ + /* 26, 0x01a */ SDL_SCANCODE_LEFTBRACKET, /* bracketleft */ + /* 27, 0x01b */ SDL_SCANCODE_RIGHTBRACKET, /* bracketright */ + /* 28, 0x01c */ SDL_SCANCODE_RETURN, /* Return */ + /* 29, 0x01d */ SDL_SCANCODE_LCTRL, /* Control_L */ + /* 30, 0x01e */ SDL_SCANCODE_A, /* a */ + /* 31, 0x01f */ SDL_SCANCODE_S, /* s */ + /* 32, 0x020 */ SDL_SCANCODE_D, /* d */ + /* 33, 0x021 */ SDL_SCANCODE_F, /* f */ + /* 34, 0x022 */ SDL_SCANCODE_G, /* g */ + /* 35, 0x023 */ SDL_SCANCODE_H, /* h */ + /* 36, 0x024 */ SDL_SCANCODE_J, /* j */ + /* 37, 0x025 */ SDL_SCANCODE_K, /* k */ + /* 38, 0x026 */ SDL_SCANCODE_L, /* l */ + /* 39, 0x027 */ SDL_SCANCODE_SEMICOLON, /* semicolon */ + /* 40, 0x028 */ SDL_SCANCODE_APOSTROPHE, /* apostrophe */ + /* 41, 0x029 */ SDL_SCANCODE_GRAVE, /* grave */ + /* 42, 0x02a */ SDL_SCANCODE_LSHIFT, /* Shift_L */ + /* 43, 0x02b */ SDL_SCANCODE_BACKSLASH, /* backslash */ + /* 44, 0x02c */ SDL_SCANCODE_Z, /* z */ + /* 45, 0x02d */ SDL_SCANCODE_X, /* x */ + /* 46, 0x02e */ SDL_SCANCODE_C, /* c */ + /* 47, 0x02f */ SDL_SCANCODE_V, /* v */ + /* 48, 0x030 */ SDL_SCANCODE_B, /* b */ + /* 49, 0x031 */ SDL_SCANCODE_N, /* n */ + /* 50, 0x032 */ SDL_SCANCODE_M, /* m */ + /* 51, 0x033 */ SDL_SCANCODE_COMMA, /* comma */ + /* 52, 0x034 */ SDL_SCANCODE_PERIOD, /* period */ + /* 53, 0x035 */ SDL_SCANCODE_SLASH, /* slash */ + /* 54, 0x036 */ SDL_SCANCODE_RSHIFT, /* Shift_R */ + /* 55, 0x037 */ SDL_SCANCODE_KP_MULTIPLY, /* KP_Multiply */ + /* 56, 0x038 */ SDL_SCANCODE_LALT, /* Alt_L */ + /* 57, 0x039 */ SDL_SCANCODE_SPACE, /* space */ + /* 58, 0x03a */ SDL_SCANCODE_CAPSLOCK, /* Caps_Lock */ + /* 59, 0x03b */ SDL_SCANCODE_F1, /* F1 */ + /* 60, 0x03c */ SDL_SCANCODE_F2, /* F2 */ + /* 61, 0x03d */ SDL_SCANCODE_F3, /* F3 */ + /* 62, 0x03e */ SDL_SCANCODE_F4, /* F4 */ + /* 63, 0x03f */ SDL_SCANCODE_F5, /* F5 */ + /* 64, 0x040 */ SDL_SCANCODE_F6, /* F6 */ + /* 65, 0x041 */ SDL_SCANCODE_F7, /* F7 */ + /* 66, 0x042 */ SDL_SCANCODE_F8, /* F8 */ + /* 67, 0x043 */ SDL_SCANCODE_F9, /* F9 */ + /* 68, 0x044 */ SDL_SCANCODE_F10, /* F10 */ + /* 69, 0x045 */ SDL_SCANCODE_NUMLOCKCLEAR, /* Num_Lock */ + /* 70, 0x046 */ SDL_SCANCODE_SCROLLLOCK, /* Scroll_Lock */ + /* 71, 0x047 */ SDL_SCANCODE_KP_7, /* KP_Home */ + /* 72, 0x048 */ SDL_SCANCODE_KP_8, /* KP_Up */ + /* 73, 0x049 */ SDL_SCANCODE_KP_9, /* KP_Prior */ + /* 74, 0x04a */ SDL_SCANCODE_KP_MINUS, /* KP_Subtract */ + /* 75, 0x04b */ SDL_SCANCODE_KP_4, /* KP_Left */ + /* 76, 0x04c */ SDL_SCANCODE_KP_5, /* KP_Begin */ + /* 77, 0x04d */ SDL_SCANCODE_KP_6, /* KP_Right */ + /* 78, 0x04e */ SDL_SCANCODE_KP_PLUS, /* KP_Add */ + /* 79, 0x04f */ SDL_SCANCODE_KP_1, /* KP_End */ + /* 80, 0x050 */ SDL_SCANCODE_KP_2, /* KP_Down */ + /* 81, 0x051 */ SDL_SCANCODE_KP_3, /* KP_Next */ + /* 82, 0x052 */ SDL_SCANCODE_KP_0, /* KP_Insert */ + /* 83, 0x053 */ SDL_SCANCODE_KP_PERIOD, /* KP_Delete */ + /* 84, 0x054 */ SDL_SCANCODE_RALT, /* ISO_Level3_Shift */ + /* 85, 0x055 */ SDL_SCANCODE_MODE, /* ???? */ + /* 86, 0x056 */ SDL_SCANCODE_NONUSBACKSLASH, /* less */ + /* 87, 0x057 */ SDL_SCANCODE_F11, /* F11 */ + /* 88, 0x058 */ SDL_SCANCODE_F12, /* F12 */ + /* 89, 0x059 */ SDL_SCANCODE_INTERNATIONAL1, /* \_ */ + /* 90, 0x05a */ SDL_SCANCODE_LANG3, /* Katakana */ + /* 91, 0x05b */ SDL_SCANCODE_LANG4, /* Hiragana */ + /* 92, 0x05c */ SDL_SCANCODE_INTERNATIONAL4, /* Henkan_Mode */ + /* 93, 0x05d */ SDL_SCANCODE_INTERNATIONAL2, /* Hiragana_Katakana */ + /* 94, 0x05e */ SDL_SCANCODE_INTERNATIONAL5, /* Muhenkan */ + /* 95, 0x05f */ SDL_SCANCODE_UNKNOWN, /* NoSymbol */ + /* 96, 0x060 */ SDL_SCANCODE_KP_ENTER, /* KP_Enter */ + /* 97, 0x061 */ SDL_SCANCODE_RCTRL, /* Control_R */ + /* 98, 0x062 */ SDL_SCANCODE_KP_DIVIDE, /* KP_Divide */ + /* 99, 0x063 */ SDL_SCANCODE_PRINTSCREEN, /* Print */ + /* 100, 0x064 */ SDL_SCANCODE_RALT, /* ISO_Level3_Shift, ALTGR, RALT */ + /* 101, 0x065 */ SDL_SCANCODE_UNKNOWN, /* Linefeed */ + /* 102, 0x066 */ SDL_SCANCODE_HOME, /* Home */ + /* 103, 0x067 */ SDL_SCANCODE_UP, /* Up */ + /* 104, 0x068 */ SDL_SCANCODE_PAGEUP, /* Prior */ + /* 105, 0x069 */ SDL_SCANCODE_LEFT, /* Left */ + /* 106, 0x06a */ SDL_SCANCODE_RIGHT, /* Right */ + /* 107, 0x06b */ SDL_SCANCODE_END, /* End */ + /* 108, 0x06c */ SDL_SCANCODE_DOWN, /* Down */ + /* 109, 0x06d */ SDL_SCANCODE_PAGEDOWN, /* Next */ + /* 110, 0x06e */ SDL_SCANCODE_INSERT, /* Insert */ + /* 111, 0x06f */ SDL_SCANCODE_DELETE, /* Delete */ + /* 112, 0x070 */ SDL_SCANCODE_UNKNOWN, /* NoSymbol */ + /* 113, 0x071 */ SDL_SCANCODE_MUTE, /* XF86AudioMute */ + /* 114, 0x072 */ SDL_SCANCODE_VOLUMEDOWN, /* XF86AudioLowerVolume */ + /* 115, 0x073 */ SDL_SCANCODE_VOLUMEUP, /* XF86AudioRaiseVolume */ + /* 116, 0x074 */ SDL_SCANCODE_POWER, /* XF86PowerOff */ + /* 117, 0x075 */ SDL_SCANCODE_KP_EQUALS, /* KP_Equal */ + /* 118, 0x076 */ SDL_SCANCODE_KP_PLUSMINUS, /* plusminus */ + /* 119, 0x077 */ SDL_SCANCODE_PAUSE, /* Pause */ + /* 120, 0x078 */ SDL_SCANCODE_UNKNOWN, /* XF86LaunchA */ + /* 121, 0x079 */ SDL_SCANCODE_KP_PERIOD, /* KP_Decimal */ + /* 122, 0x07a */ SDL_SCANCODE_LANG1, /* Hangul */ + /* 123, 0x07b */ SDL_SCANCODE_LANG2, /* Hangul_Hanja */ + /* 124, 0x07c */ SDL_SCANCODE_INTERNATIONAL3, /* Yen */ + /* 125, 0x07d */ SDL_SCANCODE_LGUI, /* Super_L */ + /* 126, 0x07e */ SDL_SCANCODE_RGUI, /* Super_R */ + /* 127, 0x07f */ SDL_SCANCODE_APPLICATION, /* Menu */ + /* 128, 0x080 */ SDL_SCANCODE_CANCEL, /* Cancel */ + /* 129, 0x081 */ SDL_SCANCODE_AGAIN, /* Redo */ + /* 130, 0x082 */ SDL_SCANCODE_UNKNOWN, /* SunProps */ + /* 131, 0x083 */ SDL_SCANCODE_UNDO, /* Undo */ + /* 132, 0x084 */ SDL_SCANCODE_UNKNOWN, /* SunFront */ + /* 133, 0x085 */ SDL_SCANCODE_COPY, /* XF86Copy */ + /* 134, 0x086 */ SDL_SCANCODE_UNKNOWN, /* SunOpen, XF86Open */ + /* 135, 0x087 */ SDL_SCANCODE_PASTE, /* XF86Paste */ + /* 136, 0x088 */ SDL_SCANCODE_FIND, /* Find */ + /* 137, 0x089 */ SDL_SCANCODE_CUT, /* XF86Cut */ + /* 138, 0x08a */ SDL_SCANCODE_HELP, /* Help */ + /* 139, 0x08b */ SDL_SCANCODE_MENU, /* XF86MenuKB */ + /* 140, 0x08c */ SDL_SCANCODE_CALCULATOR, /* XF86Calculator */ + /* 141, 0x08d */ SDL_SCANCODE_UNKNOWN, /* NoSymbol */ + /* 142, 0x08e */ SDL_SCANCODE_SLEEP, /* XF86Sleep */ + /* 143, 0x08f */ SDL_SCANCODE_UNKNOWN, /* XF86WakeUp */ + /* 144, 0x090 */ SDL_SCANCODE_UNKNOWN, /* XF86Explorer */ + /* 145, 0x091 */ SDL_SCANCODE_UNKNOWN, /* XF86Send */ + /* 146, 0x092 */ SDL_SCANCODE_UNKNOWN, /* NoSymbol */ + /* 147, 0x093 */ SDL_SCANCODE_UNKNOWN, /* XF86Xfer */ + /* 148, 0x094 */ SDL_SCANCODE_APP1, /* XF86Launch1 */ + /* 149, 0x095 */ SDL_SCANCODE_APP2, /* XF86Launch2 */ + /* 150, 0x096 */ SDL_SCANCODE_WWW, /* XF86WWW */ + /* 151, 0x097 */ SDL_SCANCODE_UNKNOWN, /* XF86DOS */ + /* 152, 0x098 */ SDL_SCANCODE_UNKNOWN, /* XF86ScreenSaver */ + /* 153, 0x099 */ SDL_SCANCODE_UNKNOWN, /* XF86RotateWindows */ + /* 154, 0x09a */ SDL_SCANCODE_UNKNOWN, /* XF86TaskPane */ + /* 155, 0x09b */ SDL_SCANCODE_MAIL, /* XF86Mail */ + /* 156, 0x09c */ SDL_SCANCODE_AC_BOOKMARKS, /* XF86Favorites */ + /* 157, 0x09d */ SDL_SCANCODE_COMPUTER, /* XF86MyComputer */ + /* 158, 0x09e */ SDL_SCANCODE_AC_BACK, /* XF86Back */ + /* 159, 0x09f */ SDL_SCANCODE_AC_FORWARD, /* XF86Forward */ + /* 160, 0x0a0 */ SDL_SCANCODE_UNKNOWN, /* NoSymbol */ + /* 161, 0x0a1 */ SDL_SCANCODE_EJECT, /* XF86Eject */ + /* 162, 0x0a2 */ SDL_SCANCODE_EJECT, /* XF86Eject */ + /* 163, 0x0a3 */ SDL_SCANCODE_AUDIONEXT, /* XF86AudioNext */ + /* 164, 0x0a4 */ SDL_SCANCODE_AUDIOPLAY, /* XF86AudioPlay */ + /* 165, 0x0a5 */ SDL_SCANCODE_AUDIOPREV, /* XF86AudioPrev */ + /* 166, 0x0a6 */ SDL_SCANCODE_AUDIOSTOP, /* XF86AudioStop */ + /* 167, 0x0a7 */ SDL_SCANCODE_UNKNOWN, /* XF86AudioRecord */ + /* 168, 0x0a8 */ SDL_SCANCODE_AUDIOREWIND, /* XF86AudioRewind */ + /* 169, 0x0a9 */ SDL_SCANCODE_UNKNOWN, /* XF86Phone */ + /* 170, 0x0aa */ SDL_SCANCODE_UNKNOWN, /* NoSymbol */ + /* 171, 0x0ab */ SDL_SCANCODE_F13, /* XF86Tools */ + /* 172, 0x0ac */ SDL_SCANCODE_AC_HOME, /* XF86HomePage */ + /* 173, 0x0ad */ SDL_SCANCODE_AC_REFRESH, /* XF86Reload */ + /* 174, 0x0ae */ SDL_SCANCODE_UNKNOWN, /* XF86Close */ + /* 175, 0x0af */ SDL_SCANCODE_UNKNOWN, /* NoSymbol */ + /* 176, 0x0b0 */ SDL_SCANCODE_UNKNOWN, /* NoSymbol */ + /* 177, 0x0b1 */ SDL_SCANCODE_UNKNOWN, /* XF86ScrollUp */ + /* 178, 0x0b2 */ SDL_SCANCODE_UNKNOWN, /* XF86ScrollDown */ + /* 179, 0x0b3 */ SDL_SCANCODE_KP_LEFTPAREN, /* parenleft */ + /* 180, 0x0b4 */ SDL_SCANCODE_KP_RIGHTPAREN, /* parenright */ + /* 181, 0x0b5 */ SDL_SCANCODE_UNKNOWN, /* XF86New */ + /* 182, 0x0b6 */ SDL_SCANCODE_AGAIN, /* Redo */ + /* 183, 0x0b7 */ SDL_SCANCODE_F13, /* XF86Tools */ + /* 184, 0x0b8 */ SDL_SCANCODE_F14, /* XF86Launch5 */ + /* 185, 0x0b9 */ SDL_SCANCODE_F15, /* XF86Launch6 */ + /* 186, 0x0ba */ SDL_SCANCODE_F16, /* XF86Launch7 */ + /* 187, 0x0bb */ SDL_SCANCODE_F17, /* XF86Launch8 */ + /* 188, 0x0bc */ SDL_SCANCODE_F18, /* XF86Launch9 */ + /* 189, 0x0bd */ SDL_SCANCODE_F19, /* NoSymbol */ + /* 190, 0x0be */ SDL_SCANCODE_F20, /* XF86AudioMicMute */ + /* 191, 0x0bf */ SDL_SCANCODE_UNKNOWN, /* XF86TouchpadToggle */ + /* 192, 0x0c0 */ SDL_SCANCODE_UNKNOWN, /* XF86TouchpadOn */ + /* 193, 0x0c1 */ SDL_SCANCODE_UNKNOWN, /* XF86TouchpadOff */ + /* 194, 0x0c2 */ SDL_SCANCODE_UNKNOWN, /* NoSymbol */ + /* 195, 0x0c3 */ SDL_SCANCODE_MODE, /* Mode_switch */ + /* 196, 0x0c4 */ SDL_SCANCODE_UNKNOWN, /* NoSymbol */ + /* 197, 0x0c5 */ SDL_SCANCODE_UNKNOWN, /* NoSymbol */ + /* 198, 0x0c6 */ SDL_SCANCODE_UNKNOWN, /* NoSymbol */ + /* 199, 0x0c7 */ SDL_SCANCODE_UNKNOWN, /* NoSymbol */ + /* 200, 0x0c8 */ SDL_SCANCODE_AUDIOPLAY, /* XF86AudioPlay */ + /* 201, 0x0c9 */ SDL_SCANCODE_UNKNOWN, /* XF86AudioPause */ + /* 202, 0x0ca */ SDL_SCANCODE_UNKNOWN, /* XF86Launch3 */ + /* 203, 0x0cb */ SDL_SCANCODE_UNKNOWN, /* XF86Launch4 */ + /* 204, 0x0cc */ SDL_SCANCODE_UNKNOWN, /* XF86LaunchB */ + /* 205, 0x0cd */ SDL_SCANCODE_UNKNOWN, /* XF86Suspend */ + /* 206, 0x0ce */ SDL_SCANCODE_UNKNOWN, /* XF86Close */ + /* 207, 0x0cf */ SDL_SCANCODE_AUDIOPLAY, /* XF86AudioPlay */ + /* 208, 0x0d0 */ SDL_SCANCODE_AUDIOFASTFORWARD, /* XF86AudioForward */ + /* 209, 0x0d1 */ SDL_SCANCODE_UNKNOWN, /* NoSymbol */ + /* 210, 0x0d2 */ SDL_SCANCODE_PRINTSCREEN, /* Print */ + /* 211, 0x0d3 */ SDL_SCANCODE_UNKNOWN, /* NoSymbol */ + /* 212, 0x0d4 */ SDL_SCANCODE_UNKNOWN, /* XF86WebCam */ + /* 213, 0x0d5 */ SDL_SCANCODE_UNKNOWN, /* XF86AudioPreset */ + /* 214, 0x0d6 */ SDL_SCANCODE_UNKNOWN, /* NoSymbol */ + /* 215, 0x0d7 */ SDL_SCANCODE_MAIL, /* XF86Mail */ + /* 216, 0x0d8 */ SDL_SCANCODE_UNKNOWN, /* XF86Messenger */ + /* 217, 0x0d9 */ SDL_SCANCODE_AC_SEARCH, /* XF86Search */ + /* 218, 0x0da */ SDL_SCANCODE_UNKNOWN, /* XF86Go */ + /* 219, 0x0db */ SDL_SCANCODE_UNKNOWN, /* XF86Finance */ + /* 220, 0x0dc */ SDL_SCANCODE_UNKNOWN, /* XF86Game */ + /* 221, 0x0dd */ SDL_SCANCODE_UNKNOWN, /* XF86Shop */ + /* 222, 0x0de */ SDL_SCANCODE_UNKNOWN, /* NoSymbol */ + /* 223, 0x0df */ SDL_SCANCODE_CANCEL, /* Cancel */ + /* 224, 0x0e0 */ SDL_SCANCODE_BRIGHTNESSDOWN, /* XF86MonBrightnessDown */ + /* 225, 0x0e1 */ SDL_SCANCODE_BRIGHTNESSUP, /* XF86MonBrightnessUp */ + /* 226, 0x0e2 */ SDL_SCANCODE_MEDIASELECT, /* XF86AudioMedia */ + /* 227, 0x0e3 */ SDL_SCANCODE_DISPLAYSWITCH, /* XF86Display */ + /* 228, 0x0e4 */ SDL_SCANCODE_KBDILLUMTOGGLE, /* XF86KbdLightOnOff */ + /* 229, 0x0e5 */ SDL_SCANCODE_KBDILLUMDOWN, /* XF86KbdBrightnessDown */ + /* 230, 0x0e6 */ SDL_SCANCODE_KBDILLUMUP, /* XF86KbdBrightnessUp */ + /* 231, 0x0e7 */ SDL_SCANCODE_UNKNOWN, /* XF86Send */ + /* 232, 0x0e8 */ SDL_SCANCODE_UNKNOWN, /* XF86Reply */ + /* 233, 0x0e9 */ SDL_SCANCODE_UNKNOWN, /* XF86MailForward */ + /* 234, 0x0ea */ SDL_SCANCODE_UNKNOWN, /* XF86Save */ + /* 235, 0x0eb */ SDL_SCANCODE_UNKNOWN, /* XF86Documents */ + /* 236, 0x0ec */ SDL_SCANCODE_UNKNOWN, /* XF86Battery */ + /* 237, 0x0ed */ SDL_SCANCODE_UNKNOWN, /* XF86Bluetooth */ + /* 238, 0x0ee */ SDL_SCANCODE_UNKNOWN, /* XF86WLAN */ + /* 239, 0x0ef */ SDL_SCANCODE_UNKNOWN, /* XF86UWB */ + /* 240, 0x0f0 */ SDL_SCANCODE_UNKNOWN, /* NoSymbol */ + /* 241, 0x0f1 */ SDL_SCANCODE_UNKNOWN, /* XF86Next_VMode */ + /* 242, 0x0f2 */ SDL_SCANCODE_UNKNOWN, /* XF86Prev_VMode */ + /* 243, 0x0f3 */ SDL_SCANCODE_UNKNOWN, /* XF86MonBrightnessCycle */ + /* 244, 0x0f4 */ SDL_SCANCODE_UNKNOWN, /* XF86BrightnessAuto */ + /* 245, 0x0f5 */ SDL_SCANCODE_UNKNOWN, /* XF86DisplayOff */ + /* 246, 0x0f6 */ SDL_SCANCODE_UNKNOWN, /* XF86WWAN */ + /* 247, 0x0f7 */ SDL_SCANCODE_UNKNOWN, /* XF86RFKill */ +}; + +/* Xvnc / Xtightvnc scancodes from xmodmap -pk */ +static const SDL_Scancode xvnc_scancode_table[] = { + /* 0 */ SDL_SCANCODE_LCTRL, + /* 1 */ SDL_SCANCODE_RCTRL, + /* 2 */ SDL_SCANCODE_LSHIFT, + /* 3 */ SDL_SCANCODE_RSHIFT, + /* 4 */ SDL_SCANCODE_UNKNOWN, /* Meta_L */ + /* 5 */ SDL_SCANCODE_UNKNOWN, /* Meta_R */ + /* 6 */ SDL_SCANCODE_LALT, + /* 7 */ SDL_SCANCODE_RALT, + /* 8 */ SDL_SCANCODE_SPACE, + /* 9 */ SDL_SCANCODE_0, + /* 10 */ SDL_SCANCODE_1, + /* 11 */ SDL_SCANCODE_2, + /* 12 */ SDL_SCANCODE_3, + /* 13 */ SDL_SCANCODE_4, + /* 14 */ SDL_SCANCODE_5, + /* 15 */ SDL_SCANCODE_6, + /* 16 */ SDL_SCANCODE_7, + /* 17 */ SDL_SCANCODE_8, + /* 18 */ SDL_SCANCODE_9, + /* 19 */ SDL_SCANCODE_MINUS, + /* 20 */ SDL_SCANCODE_EQUALS, + /* 21 */ SDL_SCANCODE_LEFTBRACKET, + /* 22 */ SDL_SCANCODE_RIGHTBRACKET, + /* 23 */ SDL_SCANCODE_SEMICOLON, + /* 24 */ SDL_SCANCODE_APOSTROPHE, + /* 25 */ SDL_SCANCODE_GRAVE, + /* 26 */ SDL_SCANCODE_COMMA, + /* 27 */ SDL_SCANCODE_PERIOD, + /* 28 */ SDL_SCANCODE_SLASH, + /* 29 */ SDL_SCANCODE_BACKSLASH, + /* 30 */ SDL_SCANCODE_A, + /* 31 */ SDL_SCANCODE_B, + /* 32 */ SDL_SCANCODE_C, + /* 33 */ SDL_SCANCODE_D, + /* 34 */ SDL_SCANCODE_E, + /* 35 */ SDL_SCANCODE_F, + /* 36 */ SDL_SCANCODE_G, + /* 37 */ SDL_SCANCODE_H, + /* 38 */ SDL_SCANCODE_I, + /* 39 */ SDL_SCANCODE_J, + /* 40 */ SDL_SCANCODE_K, + /* 41 */ SDL_SCANCODE_L, + /* 42 */ SDL_SCANCODE_M, + /* 43 */ SDL_SCANCODE_N, + /* 44 */ SDL_SCANCODE_O, + /* 45 */ SDL_SCANCODE_P, + /* 46 */ SDL_SCANCODE_Q, + /* 47 */ SDL_SCANCODE_R, + /* 48 */ SDL_SCANCODE_S, + /* 49 */ SDL_SCANCODE_T, + /* 50 */ SDL_SCANCODE_U, + /* 51 */ SDL_SCANCODE_V, + /* 52 */ SDL_SCANCODE_W, + /* 53 */ SDL_SCANCODE_X, + /* 54 */ SDL_SCANCODE_Y, + /* 55 */ SDL_SCANCODE_Z, + /* 56 */ SDL_SCANCODE_BACKSPACE, + /* 57 */ SDL_SCANCODE_RETURN, + /* 58 */ SDL_SCANCODE_TAB, + /* 59 */ SDL_SCANCODE_ESCAPE, + /* 60 */ SDL_SCANCODE_DELETE, + /* 61 */ SDL_SCANCODE_HOME, + /* 62 */ SDL_SCANCODE_END, + /* 63 */ SDL_SCANCODE_PAGEUP, + /* 64 */ SDL_SCANCODE_PAGEDOWN, + /* 65 */ SDL_SCANCODE_UP, + /* 66 */ SDL_SCANCODE_DOWN, + /* 67 */ SDL_SCANCODE_LEFT, + /* 68 */ SDL_SCANCODE_RIGHT, + /* 69 */ SDL_SCANCODE_F1, + /* 70 */ SDL_SCANCODE_F2, + /* 71 */ SDL_SCANCODE_F3, + /* 72 */ SDL_SCANCODE_F4, + /* 73 */ SDL_SCANCODE_F5, + /* 74 */ SDL_SCANCODE_F6, + /* 75 */ SDL_SCANCODE_F7, + /* 76 */ SDL_SCANCODE_F8, + /* 77 */ SDL_SCANCODE_F9, + /* 78 */ SDL_SCANCODE_F10, + /* 79 */ SDL_SCANCODE_F11, + /* 80 */ SDL_SCANCODE_F12, +}; + +#endif /* scancodes_xfree86_h_ */ + +/* *INDENT-ON* */ /* clang-format on */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/file/SDL_rwops.c b/SDL2-2.30.5/src/file/SDL_rwops.c similarity index 69% rename from SDL2-2.0.12/src/file/SDL_rwops.c rename to SDL2-2.30.5/src/file/SDL_rwops.c index 2dc986b..bf47ba7 100644 --- a/SDL2-2.0.12/src/file/SDL_rwops.c +++ b/SDL2-2.30.5/src/file/SDL_rwops.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -30,14 +30,14 @@ #include "../SDL_internal.h" -#if defined(__WIN32__) +#if defined(__WIN32__) || defined(__GDK__) #include "../core/windows/SDL_windows.h" #endif #ifdef HAVE_STDIO_H #include +#include #endif - #ifdef HAVE_LIMITS_H #include #endif @@ -53,16 +53,20 @@ #include "cocoa/SDL_rwopsbundlesupport.h" #endif /* __APPLE__ */ +#ifdef __3DS__ +#include "n3ds/SDL_rwopsromfs.h" +#endif /* __3DS__ */ + #ifdef __ANDROID__ #include "../core/android/SDL_android.h" #include "SDL_system.h" #endif -#if __NACL__ +#ifdef __NACL__ #include "nacl_io/nacl_io.h" #endif -#ifdef __WIN32__ +#if defined(__WIN32__) || defined(__GDK__) /* Functions to read/write Win32 API file pointers */ @@ -70,21 +74,23 @@ #define INVALID_SET_FILE_POINTER 0xFFFFFFFF #endif -#define READAHEAD_BUFFER_SIZE 1024 +#define READAHEAD_BUFFER_SIZE 1024 -static int SDLCALL -windows_file_open(SDL_RWops * context, const char *filename, const char *mode) +static int SDLCALL windows_file_open(SDL_RWops *context, const char *filename, const char *mode) { +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) UINT old_error_mode; +#endif HANDLE h; DWORD r_right, w_right; DWORD must_exist, truncate; int a_mode; - if (!context) - return -1; /* failed (invalid call) */ + if (!context) { + return -1; /* failed (invalid call) */ + } - context->hidden.windowsio.h = INVALID_HANDLE_VALUE; /* mark this as unusable */ + context->hidden.windowsio.h = INVALID_HANDLE_VALUE; /* mark this as unusable */ context->hidden.windowsio.buffer.data = NULL; context->hidden.windowsio.buffer.size = 0; context->hidden.windowsio.buffer.left = 0; @@ -98,23 +104,25 @@ windows_file_open(SDL_RWops * context, const char *filename, const char *mode) must_exist = (SDL_strchr(mode, 'r') != NULL) ? OPEN_EXISTING : 0; truncate = (SDL_strchr(mode, 'w') != NULL) ? CREATE_ALWAYS : 0; - r_right = (SDL_strchr(mode, '+') != NULL - || must_exist) ? GENERIC_READ : 0; + r_right = (SDL_strchr(mode, '+') != NULL || must_exist) ? GENERIC_READ : 0; a_mode = (SDL_strchr(mode, 'a') != NULL) ? OPEN_ALWAYS : 0; - w_right = (a_mode || SDL_strchr(mode, '+') - || truncate) ? GENERIC_WRITE : 0; + w_right = (a_mode || SDL_strchr(mode, '+') || truncate) ? GENERIC_WRITE : 0; - if (!r_right && !w_right) /* inconsistent mode */ - return -1; /* failed (invalid call) */ + if (!r_right && !w_right) { + return -1; /* inconsistent mode */ + } + /* failed (invalid call) */ context->hidden.windowsio.buffer.data = - (char *) SDL_malloc(READAHEAD_BUFFER_SIZE); + (char *)SDL_malloc(READAHEAD_BUFFER_SIZE); if (!context->hidden.windowsio.buffer.data) { return SDL_OutOfMemory(); } +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) /* Do not open a dialog box if failure */ old_error_mode = SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS); +#endif { LPTSTR tstr = WIN_UTF8ToString(filename); @@ -125,23 +133,24 @@ windows_file_open(SDL_RWops * context, const char *filename, const char *mode) SDL_free(tstr); } +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) /* restore old behavior */ SetErrorMode(old_error_mode); +#endif if (h == INVALID_HANDLE_VALUE) { SDL_free(context->hidden.windowsio.buffer.data); context->hidden.windowsio.buffer.data = NULL; SDL_SetError("Couldn't open %s", filename); - return -2; /* failed (CreateFile) */ + return -2; /* failed (CreateFile) */ } context->hidden.windowsio.h = h; context->hidden.windowsio.append = a_mode ? SDL_TRUE : SDL_FALSE; - return 0; /* ok */ + return 0; /* ok */ } -static Sint64 SDLCALL -windows_file_size(SDL_RWops * context) +static Sint64 SDLCALL windows_file_size(SDL_RWops *context) { LARGE_INTEGER size; @@ -156,8 +165,7 @@ windows_file_size(SDL_RWops * context) return size.QuadPart; } -static Sint64 SDLCALL -windows_file_seek(SDL_RWops * context, Sint64 offset, int whence) +static Sint64 SDLCALL windows_file_seek(SDL_RWops *context, Sint64 offset, int whence) { DWORD windowswhence; LARGE_INTEGER windowsoffset; @@ -194,7 +202,7 @@ windows_file_seek(SDL_RWops * context, Sint64 offset, int whence) } static size_t SDLCALL -windows_file_read(SDL_RWops * context, void *ptr, size_t size, size_t maxnum) +windows_file_read(SDL_RWops *context, void *ptr, size_t size, size_t maxnum) { size_t total_need; size_t total_read = 0; @@ -203,14 +211,14 @@ windows_file_read(SDL_RWops * context, void *ptr, size_t size, size_t maxnum) total_need = size * maxnum; - if (!context || context->hidden.windowsio.h == INVALID_HANDLE_VALUE - || !total_need) + if (!context || context->hidden.windowsio.h == INVALID_HANDLE_VALUE || !total_need) { return 0; + } if (context->hidden.windowsio.buffer.left > 0) { - void *data = (char *) context->hidden.windowsio.buffer.data + - context->hidden.windowsio.buffer.size - - context->hidden.windowsio.buffer.left; + void *data = (char *)context->hidden.windowsio.buffer.data + + context->hidden.windowsio.buffer.size - + context->hidden.windowsio.buffer.left; read_ahead = SDL_min(total_need, context->hidden.windowsio.buffer.left); SDL_memcpy(ptr, data, read_ahead); @@ -219,37 +227,35 @@ windows_file_read(SDL_RWops * context, void *ptr, size_t size, size_t maxnum) if (read_ahead == total_need) { return maxnum; } - ptr = (char *) ptr + read_ahead; + ptr = (char *)ptr + read_ahead; total_need -= read_ahead; total_read += read_ahead; } if (total_need < READAHEAD_BUFFER_SIZE) { - if (!ReadFile - (context->hidden.windowsio.h, context->hidden.windowsio.buffer.data, - READAHEAD_BUFFER_SIZE, &byte_read, NULL)) { + if (!ReadFile(context->hidden.windowsio.h, context->hidden.windowsio.buffer.data, + READAHEAD_BUFFER_SIZE, &byte_read, NULL)) { SDL_Error(SDL_EFREAD); return 0; } - read_ahead = SDL_min(total_need, (int) byte_read); + read_ahead = SDL_min(total_need, (int)byte_read); SDL_memcpy(ptr, context->hidden.windowsio.buffer.data, read_ahead); context->hidden.windowsio.buffer.size = byte_read; context->hidden.windowsio.buffer.left = byte_read - read_ahead; total_read += read_ahead; } else { - if (!ReadFile - (context->hidden.windowsio.h, ptr, (DWORD)total_need, &byte_read, NULL)) { + if (!ReadFile(context->hidden.windowsio.h, ptr, (DWORD)total_need, &byte_read, NULL)) { SDL_Error(SDL_EFREAD); return 0; } total_read += byte_read; } - return (total_read / size); + return total_read / size; } static size_t SDLCALL -windows_file_write(SDL_RWops * context, const void *ptr, size_t size, - size_t num) +windows_file_write(SDL_RWops *context, const void *ptr, size_t size, + size_t num) { size_t total_bytes; @@ -258,9 +264,9 @@ windows_file_write(SDL_RWops * context, const void *ptr, size_t size, total_bytes = size * num; - if (!context || context->hidden.windowsio.h == INVALID_HANDLE_VALUE - || total_bytes <= 0 || !size) + if (!context || context->hidden.windowsio.h == INVALID_HANDLE_VALUE || !size || !total_bytes) { return 0; + } if (context->hidden.windowsio.buffer.left) { SetFilePointer(context->hidden.windowsio.h, @@ -271,15 +277,15 @@ windows_file_write(SDL_RWops * context, const void *ptr, size_t size, /* if in append mode, we must go to the EOF before write */ if (context->hidden.windowsio.append) { - if (SetFilePointer(context->hidden.windowsio.h, 0L, NULL, FILE_END) == - INVALID_SET_FILE_POINTER) { + LARGE_INTEGER windowsoffset; + windowsoffset.QuadPart = 0; + if (!SetFilePointerEx(context->hidden.windowsio.h, windowsoffset, &windowsoffset, FILE_END)) { SDL_Error(SDL_EFWRITE); return 0; } } - if (!WriteFile - (context->hidden.windowsio.h, ptr, (DWORD)total_bytes, &byte_written, NULL)) { + if (!WriteFile(context->hidden.windowsio.h, ptr, (DWORD)total_bytes, &byte_written, NULL)) { SDL_Error(SDL_EFWRITE); return 0; } @@ -288,14 +294,13 @@ windows_file_write(SDL_RWops * context, const void *ptr, size_t size, return nwritten; } -static int SDLCALL -windows_file_close(SDL_RWops * context) +static int SDLCALL windows_file_close(SDL_RWops *context) { if (context) { if (context->hidden.windowsio.h != INVALID_HANDLE_VALUE) { CloseHandle(context->hidden.windowsio.h); - context->hidden.windowsio.h = INVALID_HANDLE_VALUE; /* to be sure */ + context->hidden.windowsio.h = INVALID_HANDLE_VALUE; /* to be sure */ } SDL_free(context->hidden.windowsio.buffer.data); context->hidden.windowsio.buffer.data = NULL; @@ -303,17 +308,17 @@ windows_file_close(SDL_RWops * context) } return 0; } -#endif /* __WIN32__ */ +#endif /* defined(__WIN32__) || defined(__GDK__) */ #ifdef HAVE_STDIO_H #ifdef HAVE_FOPEN64 -#define fopen fopen64 +#define fopen fopen64 #endif #ifdef HAVE_FSEEKO64 #define fseek_off_t off64_t -#define fseek fseeko64 -#define ftell ftello64 +#define fseek fseeko64 +#define ftell ftello64 #elif defined(HAVE_FSEEKO) #if defined(OFF_MIN) && defined(OFF_MAX) #define FSEEK_OFF_MIN OFF_MIN @@ -326,15 +331,15 @@ windows_file_close(SDL_RWops * context) * and eliminate the dead code if off_t has 64 bits. */ #define FSEEK_OFF_MAX (((((off_t)1 << (sizeof(off_t) * CHAR_BIT - 2)) - 1) << 1) + 1) -#define FSEEK_OFF_MIN (-(FSEEK_OFF_MAX) - 1) +#define FSEEK_OFF_MIN (-(FSEEK_OFF_MAX)-1) #endif #define fseek_off_t off_t -#define fseek fseeko -#define ftell ftello +#define fseek fseeko +#define ftell ftello #elif defined(HAVE__FSEEKI64) #define fseek_off_t __int64 -#define fseek _fseeki64 -#define ftell _ftelli64 +#define fseek _fseeki64 +#define ftell _ftelli64 #else #ifdef HAVE_LIMITS_H #define FSEEK_OFF_MIN LONG_MIN @@ -360,8 +365,7 @@ stdio_size(SDL_RWops * context) return size; } -static Sint64 SDLCALL -stdio_seek(SDL_RWops * context, Sint64 offset, int whence) +static Sint64 SDLCALL stdio_seek(SDL_RWops *context, Sint64 offset, int whence) { int stdiowhence; @@ -396,7 +400,7 @@ stdio_seek(SDL_RWops * context, Sint64 offset, int whence) } static size_t SDLCALL -stdio_read(SDL_RWops * context, void *ptr, size_t size, size_t maxnum) +stdio_read(SDL_RWops *context, void *ptr, size_t size, size_t maxnum) { size_t nread; @@ -408,7 +412,7 @@ stdio_read(SDL_RWops * context, void *ptr, size_t size, size_t maxnum) } static size_t SDLCALL -stdio_write(SDL_RWops * context, const void *ptr, size_t size, size_t num) +stdio_write(SDL_RWops *context, const void *ptr, size_t size, size_t num) { size_t nwrote; @@ -419,8 +423,7 @@ stdio_write(SDL_RWops * context, const void *ptr, size_t size, size_t num) return nwrote; } -static int SDLCALL -stdio_close(SDL_RWops * context) +static int SDLCALL stdio_close(SDL_RWops *context) { int status = 0; if (context) { @@ -438,14 +441,12 @@ stdio_close(SDL_RWops * context) /* Functions to read/write memory pointers */ -static Sint64 SDLCALL -mem_size(SDL_RWops * context) +static Sint64 SDLCALL mem_size(SDL_RWops *context) { return (Sint64)(context->hidden.mem.stop - context->hidden.mem.base); } -static Sint64 SDLCALL -mem_seek(SDL_RWops * context, Sint64 offset, int whence) +static Sint64 SDLCALL mem_seek(SDL_RWops *context, Sint64 offset, int whence) { Uint8 *newpos; @@ -473,14 +474,13 @@ mem_seek(SDL_RWops * context, Sint64 offset, int whence) } static size_t SDLCALL -mem_read(SDL_RWops * context, void *ptr, size_t size, size_t maxnum) +mem_read(SDL_RWops *context, void *ptr, size_t size, size_t maxnum) { size_t total_bytes; size_t mem_available; total_bytes = (maxnum * size); - if ((maxnum <= 0) || (size <= 0) - || ((total_bytes / maxnum) != size)) { + if (!maxnum || !size || ((total_bytes / maxnum) != size)) { return 0; } @@ -492,11 +492,11 @@ mem_read(SDL_RWops * context, void *ptr, size_t size, size_t maxnum) SDL_memcpy(ptr, context->hidden.mem.here, total_bytes); context->hidden.mem.here += total_bytes; - return (total_bytes / size); + return total_bytes / size; } static size_t SDLCALL -mem_write(SDL_RWops * context, const void *ptr, size_t size, size_t num) +mem_write(SDL_RWops *context, const void *ptr, size_t size, size_t num) { if ((context->hidden.mem.here + (num * size)) > context->hidden.mem.stop) { num = (context->hidden.mem.stop - context->hidden.mem.here) / size; @@ -507,14 +507,13 @@ mem_write(SDL_RWops * context, const void *ptr, size_t size, size_t num) } static size_t SDLCALL -mem_writeconst(SDL_RWops * context, const void *ptr, size_t size, size_t num) +mem_writeconst(SDL_RWops *context, const void *ptr, size_t size, size_t num) { SDL_SetError("Can't write to read-only memory"); return 0; } -static int SDLCALL -mem_close(SDL_RWops * context) +static int SDLCALL mem_close(SDL_RWops *context) { if (context) { SDL_FreeRW(context); @@ -522,11 +521,28 @@ mem_close(SDL_RWops * context) return 0; } - /* Functions to create SDL_RWops structures from various data sources */ -SDL_RWops * -SDL_RWFromFile(const char *file, const char *mode) +#if defined(HAVE_STDIO_H) && !(defined(__WIN32__) || defined(__GDK__)) +static SDL_bool IsRegularFileOrPipe(FILE *f) +{ + #ifdef __WINRT__ + struct __stat64 st; + if (_fstat64(_fileno(f), &st) < 0 || + !((st.st_mode & _S_IFMT) == _S_IFREG || (st.st_mode & _S_IFMT) == _S_IFIFO)) { + return SDL_FALSE; + } + #else + struct stat st; + if (fstat(fileno(f), &st) < 0 || !(S_ISREG(st.st_mode) || S_ISFIFO(st.st_mode))) { + return SDL_FALSE; + } + #endif + return SDL_TRUE; +} +#endif + +SDL_RWops *SDL_RWFromFile(const char *file, const char *mode) { SDL_RWops *rwops = NULL; if (!file || !*file || !mode || !*mode) { @@ -539,6 +555,11 @@ SDL_RWFromFile(const char *file, const char *mode) if (*file == '/') { FILE *fp = fopen(file, mode); if (fp) { + if (!IsRegularFileOrPipe(fp)) { + fclose(fp); + SDL_SetError("%s is not a regular file or pipe", file); + return NULL; + } return SDL_RWFromFP(fp, 1); } } else { @@ -554,6 +575,11 @@ SDL_RWFromFile(const char *file, const char *mode) fp = fopen(path, mode); SDL_stack_free(path); if (fp) { + if (!IsRegularFileOrPipe(fp)) { + fclose(fp); + SDL_SetError("%s is not a regular file or pipe", path); + return NULL; + } return SDL_RWFromFP(fp, 1); } } @@ -562,8 +588,10 @@ SDL_RWFromFile(const char *file, const char *mode) /* Try to open the file from the asset system */ rwops = SDL_AllocRW(); - if (!rwops) - return NULL; /* SDL_SetError already setup by SDL_AllocRW() */ + if (!rwops) { + return NULL; /* SDL_SetError already setup by SDL_AllocRW() */ + } + if (Android_JNI_FileOpen(rwops, file, mode) < 0) { SDL_FreeRW(rwops); return NULL; @@ -575,10 +603,12 @@ SDL_RWFromFile(const char *file, const char *mode) rwops->close = Android_JNI_FileClose; rwops->type = SDL_RWOPS_JNIFILE; -#elif defined(__WIN32__) +#elif defined(__WIN32__) || defined(__GDK__) rwops = SDL_AllocRW(); - if (!rwops) - return NULL; /* SDL_SetError already setup by SDL_AllocRW() */ + if (!rwops) { + return NULL; /* SDL_SetError already setup by SDL_AllocRW() */ + } + if (windows_file_open(rwops, file, mode) < 0) { SDL_FreeRW(rwops); return NULL; @@ -589,19 +619,24 @@ SDL_RWFromFile(const char *file, const char *mode) rwops->write = windows_file_write; rwops->close = windows_file_close; rwops->type = SDL_RWOPS_WINFILE; - -#elif HAVE_STDIO_H +#elif defined(HAVE_STDIO_H) { - #ifdef __APPLE__ +#if defined(__APPLE__) && !defined(SDL_FILE_DISABLED) // TODO: add dummy? FILE *fp = SDL_OpenFPFromBundleOrFallback(file, mode); - #elif __WINRT__ +#elif defined(__WINRT__) FILE *fp = NULL; fopen_s(&fp, file, mode); - #else +#elif defined(__3DS__) + FILE *fp = N3DS_FileOpen(file, mode); +#else FILE *fp = fopen(file, mode); - #endif - if (fp == NULL) { +#endif + if (!fp) { SDL_SetError("Couldn't open %s", file); + } else if (!IsRegularFileOrPipe(fp)) { + fclose(fp); + fp = NULL; + SDL_SetError("%s is not a regular file or pipe", file); } else { rwops = SDL_RWFromFP(fp, SDL_TRUE); } @@ -614,13 +649,12 @@ SDL_RWFromFile(const char *file, const char *mode) } #ifdef HAVE_STDIO_H -SDL_RWops * -SDL_RWFromFP(FILE * fp, SDL_bool autoclose) +SDL_RWops *SDL_RWFromFP(FILE * fp, SDL_bool autoclose) { SDL_RWops *rwops = NULL; rwops = SDL_AllocRW(); - if (rwops != NULL) { + if (rwops) { rwops->size = stdio_size; rwops->seek = stdio_seek; rwops->read = stdio_read; @@ -633,35 +667,33 @@ SDL_RWFromFP(FILE * fp, SDL_bool autoclose) return rwops; } #else -SDL_RWops * -SDL_RWFromFP(void * fp, SDL_bool autoclose) +SDL_RWops *SDL_RWFromFP(void * fp, SDL_bool autoclose) { SDL_SetError("SDL not compiled with stdio support"); return NULL; } #endif /* HAVE_STDIO_H */ -SDL_RWops * -SDL_RWFromMem(void *mem, int size) +SDL_RWops *SDL_RWFromMem(void *mem, int size) { SDL_RWops *rwops = NULL; if (!mem) { - SDL_InvalidParamError("mem"); - return rwops; + SDL_InvalidParamError("mem"); + return rwops; } - if (!size) { - SDL_InvalidParamError("size"); - return rwops; + if (size <= 0) { + SDL_InvalidParamError("size"); + return rwops; } rwops = SDL_AllocRW(); - if (rwops != NULL) { + if (rwops) { rwops->size = mem_size; rwops->seek = mem_seek; rwops->read = mem_read; rwops->write = mem_write; rwops->close = mem_close; - rwops->hidden.mem.base = (Uint8 *) mem; + rwops->hidden.mem.base = (Uint8 *)mem; rwops->hidden.mem.here = rwops->hidden.mem.base; rwops->hidden.mem.stop = rwops->hidden.mem.base + size; rwops->type = SDL_RWOPS_MEMORY; @@ -669,27 +701,26 @@ SDL_RWFromMem(void *mem, int size) return rwops; } -SDL_RWops * -SDL_RWFromConstMem(const void *mem, int size) +SDL_RWops *SDL_RWFromConstMem(const void *mem, int size) { SDL_RWops *rwops = NULL; if (!mem) { - SDL_InvalidParamError("mem"); - return rwops; + SDL_InvalidParamError("mem"); + return rwops; } - if (!size) { - SDL_InvalidParamError("size"); - return rwops; + if (size <= 0) { + SDL_InvalidParamError("size"); + return rwops; } rwops = SDL_AllocRW(); - if (rwops != NULL) { + if (rwops) { rwops->size = mem_size; rwops->seek = mem_seek; rwops->read = mem_read; rwops->write = mem_writeconst; rwops->close = mem_close; - rwops->hidden.mem.base = (Uint8 *) mem; + rwops->hidden.mem.base = (Uint8 *)mem; rwops->hidden.mem.here = rwops->hidden.mem.base; rwops->hidden.mem.stop = rwops->hidden.mem.base + size; rwops->type = SDL_RWOPS_MEMORY_RO; @@ -697,13 +728,12 @@ SDL_RWFromConstMem(const void *mem, int size) return rwops; } -SDL_RWops * -SDL_AllocRW(void) +SDL_RWops *SDL_AllocRW(void) { SDL_RWops *area; - area = (SDL_RWops *) SDL_malloc(sizeof *area); - if (area == NULL) { + area = (SDL_RWops *)SDL_malloc(sizeof(*area)); + if (!area) { SDL_OutOfMemory(); } else { area->type = SDL_RWOPS_UNKNOWN; @@ -711,24 +741,22 @@ SDL_AllocRW(void) return area; } -void -SDL_FreeRW(SDL_RWops * area) +void SDL_FreeRW(SDL_RWops *area) { SDL_free(area); } /* Load all the data from an SDL data stream */ -void * -SDL_LoadFile_RW(SDL_RWops * src, size_t *datasize, int freesrc) +void *SDL_LoadFile_RW(SDL_RWops *src, size_t *datasize, int freesrc) { - const int FILE_CHUNK_SIZE = 1024; + static const Sint64 FILE_CHUNK_SIZE = 1024; Sint64 size; - size_t size_read, size_total; + size_t size_read, size_total = 0; void *data = NULL, *newdata; if (!src) { SDL_InvalidParamError("src"); - return NULL; + goto done; } size = SDL_RWsize(src); @@ -736,8 +764,11 @@ SDL_LoadFile_RW(SDL_RWops * src, size_t *datasize, int freesrc) size = FILE_CHUNK_SIZE; } data = SDL_malloc((size_t)(size + 1)); + if (!data) { + SDL_OutOfMemory(); + goto done; + } - size_total = 0; for (;;) { if ((((Sint64)size_total) + FILE_CHUNK_SIZE) > size) { size = (size_total + FILE_CHUNK_SIZE); @@ -751,45 +782,41 @@ SDL_LoadFile_RW(SDL_RWops * src, size_t *datasize, int freesrc) data = newdata; } - size_read = SDL_RWread(src, (char *)data+size_total, 1, (size_t)(size-size_total)); + size_read = SDL_RWread(src, (char *)data + size_total, 1, (size_t)(size - size_total)); if (size_read == 0) { break; } size_total += size_read; } - if (datasize) { - *datasize = size_total; - } ((char *)data)[size_total] = '\0'; done: + if (datasize) { + *datasize = size_total; + } if (freesrc && src) { SDL_RWclose(src); } return data; } -void * -SDL_LoadFile(const char *file, size_t *datasize) +void *SDL_LoadFile(const char *file, size_t *datasize) { - return SDL_LoadFile_RW(SDL_RWFromFile(file, "rb"), datasize, 1); + return SDL_LoadFile_RW(SDL_RWFromFile(file, "rb"), datasize, 1); } -Sint64 -SDL_RWsize(SDL_RWops *context) +Sint64 SDL_RWsize(SDL_RWops *context) { return context->size(context); } -Sint64 -SDL_RWseek(SDL_RWops *context, Sint64 offset, int whence) +Sint64 SDL_RWseek(SDL_RWops *context, Sint64 offset, int whence) { return context->seek(context, offset, whence); } -Sint64 -SDL_RWtell(SDL_RWops *context) +Sint64 SDL_RWtell(SDL_RWops *context) { return context->seek(context, 0, RW_SEEK_CUR); } @@ -806,123 +833,115 @@ SDL_RWwrite(SDL_RWops *context, const void *ptr, size_t size, size_t num) return context->write(context, ptr, size, num); } -int -SDL_RWclose(SDL_RWops *context) +int SDL_RWclose(SDL_RWops *context) { return context->close(context); } /* Functions for dynamically reading and writing endian-specific values */ -Uint8 -SDL_ReadU8(SDL_RWops * src) +Uint8 SDL_ReadU8(SDL_RWops *src) { Uint8 value = 0; - SDL_RWread(src, &value, sizeof (value), 1); + SDL_RWread(src, &value, sizeof(value), 1); return value; } -Uint16 -SDL_ReadLE16(SDL_RWops * src) +Uint16 SDL_ReadLE16(SDL_RWops *src) { Uint16 value = 0; - SDL_RWread(src, &value, sizeof (value), 1); + SDL_RWread(src, &value, sizeof(value), 1); return SDL_SwapLE16(value); } -Uint16 -SDL_ReadBE16(SDL_RWops * src) +Uint16 SDL_ReadBE16(SDL_RWops *src) { Uint16 value = 0; - SDL_RWread(src, &value, sizeof (value), 1); + SDL_RWread(src, &value, sizeof(value), 1); return SDL_SwapBE16(value); } -Uint32 -SDL_ReadLE32(SDL_RWops * src) +Uint32 SDL_ReadLE32(SDL_RWops *src) { Uint32 value = 0; - SDL_RWread(src, &value, sizeof (value), 1); + SDL_RWread(src, &value, sizeof(value), 1); return SDL_SwapLE32(value); } -Uint32 -SDL_ReadBE32(SDL_RWops * src) +Uint32 SDL_ReadBE32(SDL_RWops *src) { Uint32 value = 0; - SDL_RWread(src, &value, sizeof (value), 1); + SDL_RWread(src, &value, sizeof(value), 1); return SDL_SwapBE32(value); } -Uint64 -SDL_ReadLE64(SDL_RWops * src) +Uint64 SDL_ReadLE64(SDL_RWops *src) { Uint64 value = 0; - SDL_RWread(src, &value, sizeof (value), 1); + SDL_RWread(src, &value, sizeof(value), 1); return SDL_SwapLE64(value); } -Uint64 -SDL_ReadBE64(SDL_RWops * src) +Uint64 SDL_ReadBE64(SDL_RWops *src) { Uint64 value = 0; - SDL_RWread(src, &value, sizeof (value), 1); + SDL_RWread(src, &value, sizeof(value), 1); return SDL_SwapBE64(value); } size_t -SDL_WriteU8(SDL_RWops * dst, Uint8 value) +SDL_WriteU8(SDL_RWops *dst, Uint8 value) { - return SDL_RWwrite(dst, &value, sizeof (value), 1); + return SDL_RWwrite(dst, &value, sizeof(value), 1); } size_t -SDL_WriteLE16(SDL_RWops * dst, Uint16 value) +SDL_WriteLE16(SDL_RWops *dst, Uint16 value) { const Uint16 swapped = SDL_SwapLE16(value); - return SDL_RWwrite(dst, &swapped, sizeof (swapped), 1); + return SDL_RWwrite(dst, &swapped, sizeof(swapped), 1); } size_t -SDL_WriteBE16(SDL_RWops * dst, Uint16 value) +SDL_WriteBE16(SDL_RWops *dst, Uint16 value) { const Uint16 swapped = SDL_SwapBE16(value); - return SDL_RWwrite(dst, &swapped, sizeof (swapped), 1); + return SDL_RWwrite(dst, &swapped, sizeof(swapped), 1); } size_t -SDL_WriteLE32(SDL_RWops * dst, Uint32 value) +SDL_WriteLE32(SDL_RWops *dst, Uint32 value) { const Uint32 swapped = SDL_SwapLE32(value); - return SDL_RWwrite(dst, &swapped, sizeof (swapped), 1); + return SDL_RWwrite(dst, &swapped, sizeof(swapped), 1); } size_t -SDL_WriteBE32(SDL_RWops * dst, Uint32 value) +SDL_WriteBE32(SDL_RWops *dst, Uint32 value) { const Uint32 swapped = SDL_SwapBE32(value); - return SDL_RWwrite(dst, &swapped, sizeof (swapped), 1); + return SDL_RWwrite(dst, &swapped, sizeof(swapped), 1); } size_t -SDL_WriteLE64(SDL_RWops * dst, Uint64 value) +SDL_WriteLE64(SDL_RWops *dst, Uint64 value) { const Uint64 swapped = SDL_SwapLE64(value); - return SDL_RWwrite(dst, &swapped, sizeof (swapped), 1); + return SDL_RWwrite(dst, &swapped, sizeof(swapped), 1); } size_t -SDL_WriteBE64(SDL_RWops * dst, Uint64 value) +SDL_WriteBE64(SDL_RWops *dst, Uint64 value) { const Uint64 swapped = SDL_SwapBE64(value); - return SDL_RWwrite(dst, &swapped, sizeof (swapped), 1); + return SDL_RWwrite(dst, &swapped, sizeof(swapped), 1); } /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/file/cocoa/SDL_rwopsbundlesupport.h b/SDL2-2.30.5/src/file/cocoa/SDL_rwopsbundlesupport.h similarity index 89% rename from SDL2-2.0.12/src/file/cocoa/SDL_rwopsbundlesupport.h rename to SDL2-2.30.5/src/file/cocoa/SDL_rwopsbundlesupport.h index 4a25727..c57ce45 100644 --- a/SDL2-2.0.12/src/file/cocoa/SDL_rwopsbundlesupport.h +++ b/SDL2-2.30.5/src/file/cocoa/SDL_rwopsbundlesupport.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -25,6 +25,6 @@ #ifndef SDL_rwopsbundlesupport_h #define SDL_rwopsbundlesupport_h -FILE* SDL_OpenFPFromBundleOrFallback(const char *file, const char *mode); +FILE *SDL_OpenFPFromBundleOrFallback(const char *file, const char *mode); #endif #endif diff --git a/SDL2-2.0.12/src/file/cocoa/SDL_rwopsbundlesupport.m b/SDL2-2.30.5/src/file/cocoa/SDL_rwopsbundlesupport.m similarity index 59% rename from SDL2-2.0.12/src/file/cocoa/SDL_rwopsbundlesupport.m rename to SDL2-2.30.5/src/file/cocoa/SDL_rwopsbundlesupport.m index 2a3c1a3..1fdce06 100644 --- a/SDL2-2.0.12/src/file/cocoa/SDL_rwopsbundlesupport.m +++ b/SDL2-2.30.5/src/file/cocoa/SDL_rwopsbundlesupport.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -32,30 +32,35 @@ but we would somehow need to know what the bundle identifiers we need to search are. Also, note the bundle layouts are different for iPhone and Mac. */ -FILE* SDL_OpenFPFromBundleOrFallback(const char *file, const char *mode) -{ @autoreleasepool +FILE *SDL_OpenFPFromBundleOrFallback(const char *file, const char *mode) { - FILE* fp = NULL; + @autoreleasepool { + FILE *fp = NULL; + NSFileManager *file_manager; + NSString *resource_path; + NSString *ns_string_file_component; + NSString *full_path_with_file_to_try; - /* If the file mode is writable, skip all the bundle stuff because generally the bundle is read-only. */ - if(strcmp("r", mode) && strcmp("rb", mode)) { - return fopen(file, mode); + /* If the file mode is writable, skip all the bundle stuff because generally the bundle is read-only. */ + if (SDL_strchr(mode, 'r') == NULL) { + return fopen(file, mode); + } + + file_manager = [NSFileManager defaultManager]; + resource_path = [[NSBundle mainBundle] resourcePath]; + + ns_string_file_component = [file_manager stringWithFileSystemRepresentation:file length:strlen(file)]; + + full_path_with_file_to_try = [resource_path stringByAppendingPathComponent:ns_string_file_component]; + if ([file_manager fileExistsAtPath:full_path_with_file_to_try]) { + fp = fopen([full_path_with_file_to_try fileSystemRepresentation], mode); + } else { + fp = fopen(file, mode); + } + + return fp; } - - NSFileManager* file_manager = [NSFileManager defaultManager]; - NSString* resource_path = [[NSBundle mainBundle] resourcePath]; - - NSString* ns_string_file_component = [file_manager stringWithFileSystemRepresentation:file length:strlen(file)]; - - NSString* full_path_with_file_to_try = [resource_path stringByAppendingPathComponent:ns_string_file_component]; - if([file_manager fileExistsAtPath:full_path_with_file_to_try]) { - fp = fopen([full_path_with_file_to_try fileSystemRepresentation], mode); - } else { - fp = fopen(file, mode); - } - - return fp; -}} +} #endif /* __APPLE__ */ diff --git a/SDL2-2.30.5/src/file/n3ds/SDL_rwopsromfs.c b/SDL2-2.30.5/src/file/n3ds/SDL_rwopsromfs.c new file mode 100644 index 0000000..9ca81a1 --- /dev/null +++ b/SDL2-2.30.5/src/file/n3ds/SDL_rwopsromfs.c @@ -0,0 +1,92 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_rwopsromfs.h" +#include "SDL_error.h" + +/* Checks if the mode is a kind of reading */ +static SDL_bool IsReadMode(const char *mode); + +/* Checks if the file starts with the given prefix */ +static SDL_bool HasPrefix(const char *file, const char *prefix); + +static FILE *TryOpenFile(const char *file, const char *mode); +static FILE *TryOpenInRomfs(const char *file, const char *mode); + +/* Nintendo 3DS applications may embed resources in the executable. The + resources are stored in a special read-only partition prefixed with + 'romfs:/'. As such, when opening a file, we should first try the romfs + unless sdmc is specifically mentionned. +*/ +FILE *N3DS_FileOpen(const char *file, const char *mode) +{ + /* romfs are read-only */ + if (!IsReadMode(mode)) { + return fopen(file, mode); + } + + /* If the path has an explicit prefix, we skip the guess work */ + if (HasPrefix(file, "romfs:/") || HasPrefix(file, "sdmc:/")) { + return fopen(file, mode); + } + + return TryOpenFile(file, mode); +} + +static SDL_bool IsReadMode(const char *mode) +{ + return SDL_strchr(mode, 'r') != NULL; +} + +static SDL_bool HasPrefix(const char *file, const char *prefix) +{ + return SDL_strncmp(prefix, file, SDL_strlen(prefix)) == 0; +} + +static FILE *TryOpenFile(const char *file, const char *mode) +{ + FILE *fp = NULL; + + fp = TryOpenInRomfs(file, mode); + if (!fp) { + fp = fopen(file, mode); + } + + return fp; +} + +static FILE *TryOpenInRomfs(const char *file, const char *mode) +{ + FILE *fp = NULL; + char *prefixed_filepath = NULL; + + if (SDL_asprintf(&prefixed_filepath, "romfs:/%s", file) < 0) { + SDL_OutOfMemory(); + return NULL; + } + + fp = fopen(prefixed_filepath, mode); + + SDL_free(prefixed_filepath); + return fp; +} + +/* vi: set sts=4 ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/file/n3ds/SDL_rwopsromfs.h b/SDL2-2.30.5/src/file/n3ds/SDL_rwopsromfs.h new file mode 100644 index 0000000..1ec1567 --- /dev/null +++ b/SDL2-2.30.5/src/file/n3ds/SDL_rwopsromfs.h @@ -0,0 +1,30 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifndef SDL_rwopsromfs_h_ +#define SDL_rwopsromfs_h_ + +FILE *N3DS_FileOpen(const char *file, const char *mode); + +#endif /* SDL_rwopsromfs_h_ */ + +/* vi: set sts=4 ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/filesystem/android/SDL_sysfilesystem.c b/SDL2-2.30.5/src/filesystem/android/SDL_sysfilesystem.c similarity index 89% rename from SDL2-2.0.12/src/filesystem/android/SDL_sysfilesystem.c rename to SDL2-2.30.5/src/filesystem/android/SDL_sysfilesystem.c index 1936bbc..5e37298 100644 --- a/SDL2-2.0.12/src/filesystem/android/SDL_sysfilesystem.c +++ b/SDL2-2.30.5/src/filesystem/android/SDL_sysfilesystem.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -32,20 +32,18 @@ #include "SDL_system.h" -char * -SDL_GetBasePath(void) +char *SDL_GetBasePath(void) { /* The current working directory is / on Android */ SDL_Unsupported(); return NULL; } -char * -SDL_GetPrefPath(const char *org, const char *app) +char *SDL_GetPrefPath(const char *org, const char *app) { const char *path = SDL_AndroidGetInternalStoragePath(); if (path) { - size_t pathlen = SDL_strlen(path)+2; + size_t pathlen = SDL_strlen(path) + 2; char *fullpath = (char *)SDL_malloc(pathlen); if (!fullpath) { SDL_OutOfMemory(); diff --git a/SDL2-2.30.5/src/filesystem/cocoa/SDL_sysfilesystem.m b/SDL2-2.30.5/src/filesystem/cocoa/SDL_sysfilesystem.m new file mode 100644 index 0000000..3d48ef6 --- /dev/null +++ b/SDL2-2.30.5/src/filesystem/cocoa/SDL_sysfilesystem.m @@ -0,0 +1,139 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_FILESYSTEM_COCOA + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* System dependent filesystem routines */ + +#include +#include +#include + +#include "SDL_error.h" +#include "SDL_stdinc.h" +#include "SDL_filesystem.h" + +char *SDL_GetBasePath(void) +{ + @autoreleasepool { + NSBundle *bundle = [NSBundle mainBundle]; + const char *baseType = [[[bundle infoDictionary] objectForKey:@"SDL_FILESYSTEM_BASE_DIR_TYPE"] UTF8String]; + const char *base = NULL; + char *retval = NULL; + + if (baseType == NULL) { + baseType = "resource"; + } + if (SDL_strcasecmp(baseType, "bundle") == 0) { + base = [[bundle bundlePath] fileSystemRepresentation]; + } else if (SDL_strcasecmp(baseType, "parent") == 0) { + base = [[[bundle bundlePath] stringByDeletingLastPathComponent] fileSystemRepresentation]; + } else { + /* this returns the exedir for non-bundled and the resourceDir for bundled apps */ + base = [[bundle resourcePath] fileSystemRepresentation]; + } + + if (base) { + const size_t len = SDL_strlen(base) + 2; + retval = (char *)SDL_malloc(len); + if (retval == NULL) { + SDL_OutOfMemory(); + } else { + SDL_snprintf(retval, len, "%s/", base); + } + } + + return retval; + } +} + +char *SDL_GetPrefPath(const char *org, const char *app) +{ + @autoreleasepool { + char *retval = NULL; + NSArray *array; + + if (!app) { + SDL_InvalidParamError("app"); + return NULL; + } + if (!org) { + org = ""; + } + +#if !TARGET_OS_TV + array = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES); +#else + /* tvOS does not have persistent local storage! + * The only place on-device where we can store data is + * a cache directory that the OS can empty at any time. + * + * It's therefore very likely that save data will be erased + * between sessions. If you want your app's save data to + * actually stick around, you'll need to use iCloud storage. + */ + { + static SDL_bool shown = SDL_FALSE; + if (!shown) { + shown = SDL_TRUE; + SDL_LogCritical(SDL_LOG_CATEGORY_SYSTEM, "tvOS does not have persistent local storage! Use iCloud storage if you want your data to persist between sessions.\n"); + } + } + + array = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); +#endif /* !TARGET_OS_TV */ + + if ([array count] > 0) { /* we only want the first item in the list. */ + NSString *str = [array objectAtIndex:0]; + const char *base = [str fileSystemRepresentation]; + if (base) { + const size_t len = SDL_strlen(base) + SDL_strlen(org) + SDL_strlen(app) + 4; + retval = (char *)SDL_malloc(len); + if (retval == NULL) { + SDL_OutOfMemory(); + } else { + char *ptr; + if (*org) { + SDL_snprintf(retval, len, "%s/%s/%s/", base, org, app); + } else { + SDL_snprintf(retval, len, "%s/%s/", base, app); + } + for (ptr = retval + 1; *ptr; ptr++) { + if (*ptr == '/') { + *ptr = '\0'; + mkdir(retval, 0700); + *ptr = '/'; + } + } + mkdir(retval, 0700); + } + } + } + + return retval; + } +} + +#endif /* SDL_FILESYSTEM_COCOA */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/filesystem/dummy/SDL_sysfilesystem.c b/SDL2-2.30.5/src/filesystem/dummy/SDL_sysfilesystem.c similarity index 90% rename from SDL2-2.0.12/src/filesystem/dummy/SDL_sysfilesystem.c rename to SDL2-2.30.5/src/filesystem/dummy/SDL_sysfilesystem.c index 9106ee0..0243cce 100644 --- a/SDL2-2.0.12/src/filesystem/dummy/SDL_sysfilesystem.c +++ b/SDL2-2.30.5/src/filesystem/dummy/SDL_sysfilesystem.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -28,15 +28,13 @@ #include "SDL_error.h" #include "SDL_filesystem.h" -char * -SDL_GetBasePath(void) +char *SDL_GetBasePath(void) { SDL_Unsupported(); return NULL; } -char * -SDL_GetPrefPath(const char *org, const char *app) +char *SDL_GetPrefPath(const char *org, const char *app) { SDL_Unsupported(); return NULL; diff --git a/SDL2-2.0.12/src/filesystem/emscripten/SDL_sysfilesystem.c b/SDL2-2.30.5/src/filesystem/emscripten/SDL_sysfilesystem.c similarity index 82% rename from SDL2-2.0.12/src/filesystem/emscripten/SDL_sysfilesystem.c rename to SDL2-2.30.5/src/filesystem/emscripten/SDL_sysfilesystem.c index 06248c4..3163972 100644 --- a/SDL2-2.0.12/src/filesystem/emscripten/SDL_sysfilesystem.c +++ b/SDL2-2.30.5/src/filesystem/emscripten/SDL_sysfilesystem.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -32,18 +32,17 @@ #include -char * -SDL_GetBasePath(void) +char *SDL_GetBasePath(void) { char *retval = "/"; return SDL_strdup(retval); } -char * -SDL_GetPrefPath(const char *org, const char *app) +char *SDL_GetPrefPath(const char *org, const char *app) { const char *append = "/libsdl/"; char *retval; + char *ptr = NULL; size_t len = 0; if (!app) { @@ -55,7 +54,7 @@ SDL_GetPrefPath(const char *org, const char *app) } len = SDL_strlen(append) + SDL_strlen(org) + SDL_strlen(app) + 3; - retval = (char *) SDL_malloc(len); + retval = (char *)SDL_malloc(len); if (!retval) { SDL_OutOfMemory(); return NULL; @@ -67,7 +66,18 @@ SDL_GetPrefPath(const char *org, const char *app) SDL_snprintf(retval, len, "%s%s/", append, app); } + for (ptr = retval + 1; *ptr; ptr++) { + if (*ptr == '/') { + *ptr = '\0'; + if (mkdir(retval, 0700) != 0 && errno != EEXIST) { + goto error; + } + *ptr = '/'; + } + } + if (mkdir(retval, 0700) != 0 && errno != EEXIST) { + error: SDL_SetError("Couldn't create directory '%s': '%s'", retval, strerror(errno)); SDL_free(retval); return NULL; diff --git a/SDL2-2.30.5/src/filesystem/gdk/SDL_sysfilesystem.cpp b/SDL2-2.30.5/src/filesystem/gdk/SDL_sysfilesystem.cpp new file mode 100644 index 0000000..22cc9c2 --- /dev/null +++ b/SDL2-2.30.5/src/filesystem/gdk/SDL_sysfilesystem.cpp @@ -0,0 +1,138 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* System dependent filesystem routines */ + +#include "../../core/windows/SDL_windows.h" +#include "SDL_hints.h" +#include "SDL_system.h" +#include "SDL_filesystem.h" +#include + +char * +SDL_GetBasePath(void) +{ + /* NOTE: This function is a UTF8 version of the Win32 SDL_GetBasePath()! + * The GDK actually _recommends_ the 'A' functions over the 'W' functions :o + */ + DWORD buflen = 128; + CHAR *path = NULL; + DWORD len = 0; + int i; + + while (SDL_TRUE) { + void *ptr = SDL_realloc(path, buflen * sizeof(CHAR)); + if (!ptr) { + SDL_free(path); + SDL_OutOfMemory(); + return NULL; + } + + path = (CHAR *)ptr; + + len = GetModuleFileNameA(NULL, path, buflen); + /* if it truncated, then len >= buflen - 1 */ + /* if there was enough room (or failure), len < buflen - 1 */ + if (len < buflen - 1) { + break; + } + + /* buffer too small? Try again. */ + buflen *= 2; + } + + if (len == 0) { + SDL_free(path); + WIN_SetError("Couldn't locate our .exe"); + return NULL; + } + + for (i = len - 1; i > 0; i--) { + if (path[i] == '\\') { + break; + } + } + + SDL_assert(i > 0); /* Should have been an absolute path. */ + path[i + 1] = '\0'; /* chop off filename. */ + + return path; +} + +char * +SDL_GetPrefPath(const char *org, const char *app) +{ + XUserHandle user = NULL; + XAsyncBlock block = { 0 }; + char *folderPath; + HRESULT result; + const char *csid = SDL_GetHint("SDL_GDK_SERVICE_CONFIGURATION_ID"); + + if (!app) { + SDL_InvalidParamError("app"); + return NULL; + } + + /* This should be set before calling SDL_GetPrefPath! */ + if (!csid) { + SDL_LogWarn(SDL_LOG_CATEGORY_SYSTEM, "Set SDL_GDK_SERVICE_CONFIGURATION_ID before calling SDL_GetPrefPath!"); + return SDL_strdup("T:\\"); + } + + if (SDL_GDKGetDefaultUser(&user) < 0) { + /* Error already set, just return */ + return NULL; + } + + if (FAILED(result = XGameSaveFilesGetFolderWithUiAsync(user, csid, &block))) { + WIN_SetErrorFromHRESULT("XGameSaveFilesGetFolderWithUiAsync", result); + return NULL; + } + + folderPath = (char*) SDL_malloc(MAX_PATH); + do { + result = XGameSaveFilesGetFolderWithUiResult(&block, MAX_PATH, folderPath); + } while (result == E_PENDING); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT("XGameSaveFilesGetFolderWithUiResult", result); + SDL_free(folderPath); + return NULL; + } + + /* We aren't using 'app' here because the container rules are a lot more + * strict than the NTFS rules, so it will most likely be invalid :( + */ + SDL_strlcat(folderPath, "\\SDLPrefPath\\", MAX_PATH); + if (CreateDirectoryA(folderPath, NULL) == FALSE) { + if (GetLastError() != ERROR_ALREADY_EXISTS) { + WIN_SetError("CreateDirectoryA"); + SDL_free(folderPath); + return NULL; + } + } + return folderPath; +} + + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/filesystem/haiku/SDL_sysfilesystem.cc b/SDL2-2.30.5/src/filesystem/haiku/SDL_sysfilesystem.cc similarity index 94% rename from SDL2-2.0.12/src/filesystem/haiku/SDL_sysfilesystem.cc rename to SDL2-2.30.5/src/filesystem/haiku/SDL_sysfilesystem.cc index e8c630e..5585c48 100644 --- a/SDL2-2.0.12/src/filesystem/haiku/SDL_sysfilesystem.cc +++ b/SDL2-2.30.5/src/filesystem/haiku/SDL_sysfilesystem.cc @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -32,11 +32,9 @@ #include "SDL_error.h" #include "SDL_stdinc.h" -#include "SDL_assert.h" #include "SDL_filesystem.h" -char * -SDL_GetBasePath(void) +char *SDL_GetBasePath(void) { image_info info; int32 cookie = 0; @@ -70,8 +68,7 @@ SDL_GetBasePath(void) } -char * -SDL_GetPrefPath(const char *org, const char *app) +char *SDL_GetPrefPath(const char *org, const char *app) { // !!! FIXME: is there a better way to do this? const char *home = SDL_getenv("HOME"); diff --git a/SDL2-2.30.5/src/filesystem/n3ds/SDL_sysfilesystem.c b/SDL2-2.30.5/src/filesystem/n3ds/SDL_sysfilesystem.c new file mode 100644 index 0000000..fe46076 --- /dev/null +++ b/SDL2-2.30.5/src/filesystem/n3ds/SDL_sysfilesystem.c @@ -0,0 +1,89 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_FILESYSTEM_N3DS + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* System dependent filesystem routines */ + +#include <3ds.h> +#include +#include + +#include "SDL_error.h" +#include "SDL_filesystem.h" + +SDL_FORCE_INLINE char *MakePrefPath(const char *app); +SDL_FORCE_INLINE int CreatePrefPathDir(const char *pref); + +char *SDL_GetBasePath(void) +{ + char *base_path = SDL_strdup("romfs:/"); + return base_path; +} + +char *SDL_GetPrefPath(const char *org, const char *app) +{ + char *pref_path = NULL; + if (!app) { + SDL_InvalidParamError("app"); + return NULL; + } + + pref_path = MakePrefPath(app); + if (!pref_path) { + return NULL; + } + + if (CreatePrefPathDir(pref_path) < 0) { + SDL_free(pref_path); + return NULL; + } + + return pref_path; +} + +SDL_FORCE_INLINE char * +MakePrefPath(const char *app) +{ + char *pref_path; + if (SDL_asprintf(&pref_path, "sdmc:/3ds/%s/", app) < 0) { + SDL_OutOfMemory(); + return NULL; + } + return pref_path; +} + +SDL_FORCE_INLINE int +CreatePrefPathDir(const char *pref) +{ + int result = mkdir(pref, 0666); + + if (result == -1 && errno != EEXIST) { + return SDL_SetError("Failed to create '%s' (%s)", pref, strerror(errno)); + } + return 0; +} + +#endif /* SDL_FILESYSTEM_N3DS */ + +/* vi: set sts=4 ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/filesystem/nacl/SDL_sysfilesystem.c b/SDL2-2.30.5/src/filesystem/nacl/SDL_sysfilesystem.c similarity index 88% rename from SDL2-2.0.12/src/filesystem/nacl/SDL_sysfilesystem.c rename to SDL2-2.30.5/src/filesystem/nacl/SDL_sysfilesystem.c index cfdffd4..1ef34dd 100644 --- a/SDL2-2.0.12/src/filesystem/nacl/SDL_sysfilesystem.c +++ b/SDL2-2.30.5/src/filesystem/nacl/SDL_sysfilesystem.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -24,15 +24,13 @@ #ifdef SDL_FILESYSTEM_NACL -char * -SDL_GetBasePath(void) +char *SDL_GetBasePath(void) { SDL_Unsupported(); return NULL; } -char * -SDL_GetPrefPath(const char *org, const char *app) +char *SDL_GetPrefPath(const char *org, const char *app) { SDL_Unsupported(); return NULL; diff --git a/SDL2-2.30.5/src/filesystem/os2/SDL_sysfilesystem.c b/SDL2-2.30.5/src/filesystem/os2/SDL_sysfilesystem.c new file mode 100644 index 0000000..4e9597f --- /dev/null +++ b/SDL2-2.30.5/src/filesystem/os2/SDL_sysfilesystem.c @@ -0,0 +1,129 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_FILESYSTEM_OS2 + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* System dependent filesystem routines */ + +#include "../../core/os2/SDL_os2.h" +#include "SDL_error.h" +#include "SDL_filesystem.h" + +#define INCL_DOSFILEMGR +#define INCL_DOSPROCESS +#define INCL_DOSMODULEMGR +#define INCL_DOSERRORS +#include + + +char *SDL_GetBasePath(void) +{ + PTIB tib; + PPIB pib; + ULONG ulRC = DosGetInfoBlocks(&tib, &pib); + PCHAR pcEnd; + CHAR acBuf[CCHMAXPATH]; + + if (ulRC != NO_ERROR) { + SDL_SetError("Can't get process information block (E%lu)", ulRC); + return NULL; + } + + ulRC = DosQueryModuleName(pib->pib_hmte, sizeof(acBuf), acBuf); + if (ulRC != NO_ERROR) { + SDL_SetError("Can't query the module name (E%lu)", ulRC); + return NULL; + } + + pcEnd = SDL_strrchr(acBuf, '\\'); + if (pcEnd != NULL) + pcEnd[1] = '\0'; + else { + if (acBuf[1] == ':') /* e.g. "C:FOO" */ + acBuf[2] = '\0'; + else { + SDL_SetError("No path in module name"); + return NULL; + } + } + + return OS2_SysToUTF8(acBuf); +} + +char *SDL_GetPrefPath(const char *org, const char *app) +{ + PSZ pszPath; + CHAR acBuf[CCHMAXPATH]; + int lPosApp, lPosOrg; + PSZ pszApp, pszOrg; + + if (!app) { + SDL_InvalidParamError("app"); + return NULL; + } + + pszPath = SDL_getenv("HOME"); + if (!pszPath) { + pszPath = SDL_getenv("ETC"); + if (!pszPath) { + SDL_SetError("HOME or ETC environment not set"); + return NULL; + } + } + + if (!org) { + lPosApp = SDL_snprintf(acBuf, sizeof(acBuf) - 1, "%s", pszPath); + } else { + pszOrg = OS2_UTF8ToSys(org); + if (!pszOrg) { + SDL_OutOfMemory(); + return NULL; + } + lPosApp = SDL_snprintf(acBuf, sizeof(acBuf) - 1, "%s\\%s", pszPath, pszOrg); + SDL_free(pszOrg); + } + if (lPosApp < 0) + return NULL; + + DosCreateDir(acBuf, NULL); + + pszApp = OS2_UTF8ToSys(app); + if (!pszApp) { + SDL_OutOfMemory(); + return NULL; + } + + lPosOrg = SDL_snprintf(&acBuf[lPosApp], sizeof(acBuf) - lPosApp - 1, "\\%s", pszApp); + SDL_free(pszApp); + if (lPosOrg < 0) + return NULL; + + DosCreateDir(acBuf, NULL); + *((PUSHORT)&acBuf[lPosApp + lPosOrg]) = (USHORT)'\0\\'; + + return OS2_SysToUTF8(acBuf); +} + +#endif /* SDL_FILESYSTEM_OS2 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/filesystem/ps2/SDL_sysfilesystem.c b/SDL2-2.30.5/src/filesystem/ps2/SDL_sysfilesystem.c new file mode 100644 index 0000000..6b64466 --- /dev/null +++ b/SDL2-2.30.5/src/filesystem/ps2/SDL_sysfilesystem.c @@ -0,0 +1,110 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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 +#include + +#if defined(SDL_FILESYSTEM_PS2) + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* System dependent filesystem routines */ + +#include "SDL_error.h" +#include "SDL_filesystem.h" + +char *SDL_GetBasePath(void) +{ + char *retval; + size_t len; + char cwd[FILENAME_MAX]; + + getcwd(cwd, sizeof(cwd)); + len = SDL_strlen(cwd) + 1; + retval = (char *)SDL_malloc(len); + if (retval) { + SDL_memcpy(retval, cwd, len); + } + + return retval; +} + +/* Do a recursive mkdir of parents folders */ +static void recursive_mkdir(const char *dir) +{ + char tmp[FILENAME_MAX]; + char *base = SDL_GetBasePath(); + char *p = NULL; + size_t len; + + snprintf(tmp, sizeof(tmp), "%s", dir); + len = strlen(tmp); + if (tmp[len - 1] == '/') { + tmp[len - 1] = 0; + } + + for (p = tmp + 1; *p; p++) { + if (*p == '/') { + *p = 0; + // Just creating subfolders from current path + if (strstr(tmp, base) != NULL) { + mkdir(tmp, S_IRWXU); + } + + *p = '/'; + } + } + + free(base); + mkdir(tmp, S_IRWXU); +} + +char *SDL_GetPrefPath(const char *org, const char *app) +{ + char *retval = NULL; + size_t len; + char *base = SDL_GetBasePath(); + if (!app) { + SDL_InvalidParamError("app"); + return NULL; + } + if (!org) { + org = ""; + } + + len = SDL_strlen(base) + SDL_strlen(org) + SDL_strlen(app) + 4; + retval = (char *)SDL_malloc(len); + + if (*org) { + SDL_snprintf(retval, len, "%s%s/%s/", base, org, app); + } else { + SDL_snprintf(retval, len, "%s%s/", base, app); + } + free(base); + + recursive_mkdir(retval); + + return retval; +} + +#endif /* SDL_FILESYSTEM_PS2 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/filesystem/psp/SDL_sysfilesystem.c b/SDL2-2.30.5/src/filesystem/psp/SDL_sysfilesystem.c new file mode 100644 index 0000000..7ed87e0 --- /dev/null +++ b/SDL2-2.30.5/src/filesystem/psp/SDL_sysfilesystem.c @@ -0,0 +1,77 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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 +#include + +#if defined(SDL_FILESYSTEM_PSP) + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* System dependent filesystem routines */ + +#include "SDL_error.h" +#include "SDL_filesystem.h" + +char *SDL_GetBasePath(void) +{ + char *retval = NULL; + size_t len; + char cwd[FILENAME_MAX]; + + getcwd(cwd, sizeof(cwd)); + len = SDL_strlen(cwd) + 2; + retval = (char *)SDL_malloc(len); + SDL_snprintf(retval, len, "%s/", cwd); + + return retval; +} + +char *SDL_GetPrefPath(const char *org, const char *app) +{ + char *retval = NULL; + size_t len; + char *base = SDL_GetBasePath(); + if (!app) { + SDL_InvalidParamError("app"); + return NULL; + } + if (!org) { + org = ""; + } + + len = SDL_strlen(base) + SDL_strlen(org) + SDL_strlen(app) + 4; + retval = (char *)SDL_malloc(len); + + if (*org) { + SDL_snprintf(retval, len, "%s%s/%s/", base, org, app); + } else { + SDL_snprintf(retval, len, "%s%s/", base, app); + } + free(base); + + mkdir(retval, 0755); + return retval; +} + +#endif /* SDL_FILESYSTEM_PSP */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/filesystem/riscos/SDL_sysfilesystem.c b/SDL2-2.30.5/src/filesystem/riscos/SDL_sysfilesystem.c new file mode 100644 index 0000000..4617895 --- /dev/null +++ b/SDL2-2.30.5/src/filesystem/riscos/SDL_sysfilesystem.c @@ -0,0 +1,208 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_FILESYSTEM_RISCOS + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* System dependent filesystem routines */ + +#include +#include +#include + +#include "SDL_error.h" +#include "SDL_stdinc.h" +#include "SDL_filesystem.h" + +/* Wrapper around __unixify_std that uses SDL's memory allocators */ +static char *SDL_unixify_std(const char *ro_path, char *buffer, size_t buf_len, int filetype) +{ + const char *const in_buf = buffer; /* = NULL if we allocate the buffer. */ + + if (!buffer) { + /* This matches the logic in __unixify, with an additional byte for the + * extra path separator. + */ + buf_len = SDL_strlen(ro_path) + 14 + 1; + buffer = SDL_malloc(buf_len); + + if (!buffer) { + SDL_OutOfMemory(); + return NULL; + } + } + + if (!__unixify_std(ro_path, buffer, buf_len, filetype)) { + if (!in_buf) { + SDL_free(buffer); + } + + SDL_SetError("Could not convert '%s' to a Unix-style path", ro_path); + return NULL; + } + + /* HACK: It's necessary to add an extra path separator here since SDL's API + * requires it, however paths with trailing separators aren't normally valid + * on RISC OS. + */ + if (__get_riscosify_control() & __RISCOSIFY_NO_PROCESS) + SDL_strlcat(buffer, ".", buf_len); + else + SDL_strlcat(buffer, "/", buf_len); + + return buffer; +} + +static char *canonicalisePath(const char *path, const char *pathVar) +{ + _kernel_oserror *error; + _kernel_swi_regs regs; + char *buf; + + regs.r[0] = 37; + regs.r[1] = (int)path; + regs.r[2] = 0; + regs.r[3] = (int)pathVar; + regs.r[4] = 0; + regs.r[5] = 0; + error = _kernel_swi(OS_FSControl, ®s, ®s); + if (error) { + SDL_SetError("Couldn't canonicalise path: %s", error->errmess); + return NULL; + } + + regs.r[5] = 1 - regs.r[5]; + buf = SDL_malloc(regs.r[5]); + if (!buf) { + SDL_OutOfMemory(); + return NULL; + } + regs.r[2] = (int)buf; + error = _kernel_swi(OS_FSControl, ®s, ®s); + if (error) { + SDL_SetError("Couldn't canonicalise path: %s", error->errmess); + SDL_free(buf); + return NULL; + } + + return buf; +} + +static _kernel_oserror *createDirectoryRecursive(char *path) +{ + char *ptr = NULL; + _kernel_oserror *error; + _kernel_swi_regs regs; + regs.r[0] = 8; + regs.r[1] = (int)path; + regs.r[2] = 0; + + for (ptr = path + 1; *ptr; ptr++) { + if (*ptr == '.') { + *ptr = '\0'; + error = _kernel_swi(OS_File, ®s, ®s); + *ptr = '.'; + if (error) { + return error; + } + } + } + return _kernel_swi(OS_File, ®s, ®s); +} + +char *SDL_GetBasePath(void) +{ + _kernel_swi_regs regs; + _kernel_oserror *error; + char *canon, *ptr, *retval; + + error = _kernel_swi(OS_GetEnv, ®s, ®s); + if (error) { + return NULL; + } + + canon = canonicalisePath((const char *)regs.r[0], "Run$Path"); + if (!canon) { + return NULL; + } + + /* chop off filename. */ + ptr = SDL_strrchr(canon, '.'); + if (ptr) { + *ptr = '\0'; + } + + retval = SDL_unixify_std(canon, NULL, 0, __RISCOSIFY_FILETYPE_NOTSPECIFIED); + SDL_free(canon); + return retval; +} + +char *SDL_GetPrefPath(const char *org, const char *app) +{ + char *canon, *dir, *retval; + size_t len; + _kernel_oserror *error; + + if (!app) { + SDL_InvalidParamError("app"); + return NULL; + } + if (!org) { + org = ""; + } + + canon = canonicalisePath("", "Run$Path"); + if (!canon) { + return NULL; + } + + len = SDL_strlen(canon) + SDL_strlen(org) + SDL_strlen(app) + 4; + dir = (char *)SDL_malloc(len); + if (!dir) { + SDL_OutOfMemory(); + SDL_free(canon); + return NULL; + } + + if (*org) { + SDL_snprintf(dir, len, "%s.%s.%s", canon, org, app); + } else { + SDL_snprintf(dir, len, "%s.%s", canon, app); + } + + SDL_free(canon); + + error = createDirectoryRecursive(dir); + if (error) { + SDL_SetError("Couldn't create directory: %s", error->errmess); + SDL_free(dir); + return NULL; + } + + retval = SDL_unixify_std(dir, NULL, 0, __RISCOSIFY_FILETYPE_NOTSPECIFIED); + SDL_free(dir); + return retval; +} + +#endif /* SDL_FILESYSTEM_RISCOS */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/filesystem/unix/SDL_sysfilesystem.c b/SDL2-2.30.5/src/filesystem/unix/SDL_sysfilesystem.c similarity index 53% rename from SDL2-2.0.12/src/filesystem/unix/SDL_sysfilesystem.c rename to SDL2-2.30.5/src/filesystem/unix/SDL_sysfilesystem.c index f2dc846..c69a991 100644 --- a/SDL2-2.0.12/src/filesystem/unix/SDL_sysfilesystem.c +++ b/SDL2-2.30.5/src/filesystem/unix/SDL_sysfilesystem.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -45,17 +45,15 @@ /* QNX's /proc/self/exefile is a text file and not a symlink. */ #if !defined(__QNXNTO__) -static char * -readSymLink(const char *path) +static char *readSymLink(const char *path) { char *retval = NULL; ssize_t len = 64; ssize_t rc = -1; - while (1) - { - char *ptr = (char *) SDL_realloc(retval, (size_t) len); - if (ptr == NULL) { + while (1) { + char *ptr = (char *)SDL_realloc(retval, (size_t)len); + if (!ptr) { SDL_OutOfMemory(); break; } @@ -64,13 +62,13 @@ readSymLink(const char *path) rc = readlink(path, retval, len); if (rc == -1) { - break; /* not a symlink, i/o error, etc. */ + break; /* not a symlink, i/o error, etc. */ } else if (rc < len) { - retval[rc] = '\0'; /* readlink doesn't null-terminate. */ - return retval; /* we're good to go. */ + retval[rc] = '\0'; /* readlink doesn't null-terminate. */ + return retval; /* we're good to go. */ } - len *= 2; /* grow buffer, try again. */ + len *= 2; /* grow buffer, try again. */ } SDL_free(retval); @@ -78,14 +76,65 @@ readSymLink(const char *path) } #endif -char * -SDL_GetBasePath(void) + +#if defined(__OPENBSD__) +static char *search_path_for_binary(const char *bin) +{ + char *envr = SDL_getenv("PATH"); + size_t alloc_size; + char *exe = NULL; + char *start = envr; + char *ptr; + + if (!envr) { + SDL_SetError("No $PATH set"); + return NULL; + } + + envr = SDL_strdup(envr); + if (!envr) { + SDL_OutOfMemory(); + return NULL; + } + + SDL_assert(bin != NULL); + + alloc_size = SDL_strlen(bin) + SDL_strlen(envr) + 2; + exe = (char *)SDL_malloc(alloc_size); + + do { + ptr = SDL_strchr(start, ':'); /* find next $PATH separator. */ + if (ptr != start) { + if (ptr) { + *ptr = '\0'; + } + + /* build full binary path... */ + SDL_snprintf(exe, alloc_size, "%s%s%s", start, (ptr && (ptr[-1] == '/')) ? "" : "/", bin); + + if (access(exe, X_OK) == 0) { /* Exists as executable? We're done. */ + SDL_free(envr); + return exe; + } + } + start = ptr + 1; /* start points to beginning of next element. */ + } while (ptr); + + SDL_free(envr); + SDL_free(exe); + + SDL_SetError("Process not found in $PATH"); + return NULL; /* doesn't exist in path. */ +} +#endif + +char *SDL_GetBasePath(void) { char *retval = NULL; #if defined(__FREEBSD__) char fullpath[PATH_MAX]; - size_t buflen = sizeof (fullpath); + size_t buflen = sizeof(fullpath); const int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 }; if (sysctl(mib, SDL_arraysize(mib), fullpath, &buflen, NULL, 0) != -1) { retval = SDL_strdup(fullpath); @@ -96,31 +145,62 @@ SDL_GetBasePath(void) } #endif #if defined(__OPENBSD__) - char **retvalargs; + /* Please note that this will fail if the process was launched with a relative path and $PWD + the cwd have changed, or argv is altered. So don't do that. Or add a new sysctl to OpenBSD. */ + char **cmdline; size_t len; const int mib[] = { CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_ARGV }; if (sysctl(mib, 4, NULL, &len, NULL, 0) != -1) { - retvalargs = SDL_malloc(len); - if (!retvalargs) { + char *exe, *pwddst; + char *realpathbuf = (char *)SDL_malloc(PATH_MAX + 1); + if (!realpathbuf) { SDL_OutOfMemory(); return NULL; } - sysctl(mib, 4, retvalargs, &len, NULL, 0); - retval = SDL_malloc(PATH_MAX + 1); - if (retval) - realpath(retvalargs[0], retval); - SDL_free(retvalargs); - } -#endif -#if defined(__SOLARIS__) - const char *path = getexecname(); - if ((path != NULL) && (path[0] == '/')) { /* must be absolute path... */ - retval = SDL_strdup(path); - if (!retval) { + cmdline = SDL_malloc(len); + if (!cmdline) { + SDL_free(realpathbuf); SDL_OutOfMemory(); return NULL; } + + sysctl(mib, 4, cmdline, &len, NULL, 0); + + exe = cmdline[0]; + pwddst = NULL; + if (SDL_strchr(exe, '/') == NULL) { /* not a relative or absolute path, check $PATH for it */ + exe = search_path_for_binary(cmdline[0]); + } else { + if (exe && *exe == '.') { + const char *pwd = SDL_getenv("PWD"); + if (pwd && *pwd) { + SDL_asprintf(&pwddst, "%s/%s", pwd, exe); + } + } + } + + if (exe) { + if (!pwddst) { + if (realpath(exe, realpathbuf) != NULL) { + retval = realpathbuf; + } + } else { + if (realpath(pwddst, realpathbuf) != NULL) { + retval = realpathbuf; + } + SDL_free(pwddst); + } + + if (exe != cmdline[0]) { + SDL_free(exe); + } + } + + if (!retval) { + SDL_free(realpathbuf); + } + + SDL_free(cmdline); } #endif @@ -133,48 +213,63 @@ SDL_GetBasePath(void) retval = readSymLink("/proc/curproc/file"); #elif defined(__NETBSD__) retval = readSymLink("/proc/curproc/exe"); +#elif defined(__SOLARIS__) + retval = readSymLink("/proc/self/path/a.out"); #elif defined(__QNXNTO__) retval = SDL_LoadFile("/proc/self/exefile", NULL); #else - retval = readSymLink("/proc/self/exe"); /* linux. */ - if (retval == NULL) { + retval = readSymLink("/proc/self/exe"); /* linux. */ + if (!retval) { /* older kernels don't have /proc/self ... try PID version... */ char path[64]; const int rc = SDL_snprintf(path, sizeof(path), - "/proc/%llu/exe", - (unsigned long long) getpid()); - if ( (rc > 0) && (rc < sizeof(path)) ) { + "/proc/%llu/exe", + (unsigned long long)getpid()); + if ((rc > 0) && (rc < sizeof(path))) { retval = readSymLink(path); } } #endif } +#if defined(__SOLARIS__) /* try this as a fallback if /proc didn't pan out */ + if (!retval) { + const char *path = getexecname(); + if ((path != NULL) && (path[0] == '/')) { /* must be absolute path... */ + retval = SDL_strdup(path); + if (!retval) { + SDL_OutOfMemory(); + return NULL; + } + } + } +#endif + /* If we had access to argv[0] here, we could check it for a path, or troll through $PATH looking for it, too. */ - if (retval != NULL) { /* chop off filename. */ + if (retval) { /* chop off filename. */ char *ptr = SDL_strrchr(retval, '/'); - if (ptr != NULL) { - *(ptr+1) = '\0'; - } else { /* shouldn't happen, but just in case... */ + if (ptr) { + *(ptr + 1) = '\0'; + } else { /* shouldn't happen, but just in case... */ SDL_free(retval); retval = NULL; } } - if (retval != NULL) { + if (retval) { /* try to shrink buffer... */ - char *ptr = (char *) SDL_realloc(retval, strlen(retval) + 1); - if (ptr != NULL) - retval = ptr; /* oh well if it failed. */ + char *ptr = (char *)SDL_realloc(retval, SDL_strlen(retval) + 1); + if (ptr) { + retval = ptr; /* oh well if it failed. */ + } } return retval; } -char * -SDL_GetPrefPath(const char *org, const char *app) +char *SDL_GetPrefPath(const char *org, const char *app) { /* * We use XDG's base directory spec, even if you're not on Linux. @@ -211,32 +306,34 @@ SDL_GetPrefPath(const char *org, const char *app) } len = SDL_strlen(envr); - if (envr[len - 1] == '/') + if (envr[len - 1] == '/') { append += 1; + } len += SDL_strlen(append) + SDL_strlen(org) + SDL_strlen(app) + 3; - retval = (char *) SDL_malloc(len); + retval = (char *)SDL_malloc(len); if (!retval) { SDL_OutOfMemory(); return NULL; } if (*org) { - SDL_snprintf(retval, len, "%s%s%s/%s/", envr, append, org, app); + (void)SDL_snprintf(retval, len, "%s%s%s/%s/", envr, append, org, app); } else { - SDL_snprintf(retval, len, "%s%s%s/", envr, append, app); + (void)SDL_snprintf(retval, len, "%s%s%s/", envr, append, app); } - for (ptr = retval+1; *ptr; ptr++) { + for (ptr = retval + 1; *ptr; ptr++) { if (*ptr == '/') { *ptr = '\0'; - if (mkdir(retval, 0700) != 0 && errno != EEXIST) + if (mkdir(retval, 0700) != 0 && errno != EEXIST) { goto error; + } *ptr = '/'; } } if (mkdir(retval, 0700) != 0 && errno != EEXIST) { -error: + error: SDL_SetError("Couldn't create directory '%s': '%s'", retval, strerror(errno)); SDL_free(retval); return NULL; diff --git a/SDL2-2.30.5/src/filesystem/vita/SDL_sysfilesystem.c b/SDL2-2.30.5/src/filesystem/vita/SDL_sysfilesystem.c new file mode 100644 index 0000000..eb7e159 --- /dev/null +++ b/SDL2-2.30.5/src/filesystem/vita/SDL_sysfilesystem.c @@ -0,0 +1,93 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_FILESYSTEM_VITA + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* System dependent filesystem routines */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "SDL_error.h" +#include "SDL_stdinc.h" +#include "SDL_filesystem.h" +#include "SDL_rwops.h" + +char *SDL_GetBasePath(void) +{ + const char *basepath = "app0:/"; + char *retval = SDL_strdup(basepath); + return retval; +} + +char *SDL_GetPrefPath(const char *org, const char *app) +{ + const char *envr = "ux0:/data/"; + char *retval = NULL; + char *ptr = NULL; + size_t len = 0; + + if (!app) { + SDL_InvalidParamError("app"); + return NULL; + } + if (!org) { + org = ""; + } + + len = SDL_strlen(envr); + + len += SDL_strlen(org) + SDL_strlen(app) + 3; + retval = (char *)SDL_malloc(len); + if (!retval) { + SDL_OutOfMemory(); + return NULL; + } + + if (*org) { + SDL_snprintf(retval, len, "%s%s/%s/", envr, org, app); + } else { + SDL_snprintf(retval, len, "%s%s/", envr, app); + } + + for (ptr = retval + 1; *ptr; ptr++) { + if (*ptr == '/') { + *ptr = '\0'; + sceIoMkdir(retval, 0777); + *ptr = '/'; + } + } + sceIoMkdir(retval, 0777); + + return retval; +} + +#endif /* SDL_FILESYSTEM_VITA */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/filesystem/windows/SDL_sysfilesystem.c b/SDL2-2.30.5/src/filesystem/windows/SDL_sysfilesystem.c similarity index 69% rename from SDL2-2.0.12/src/filesystem/windows/SDL_sysfilesystem.c rename to SDL2-2.30.5/src/filesystem/windows/SDL_sysfilesystem.c index c4e7d83..a653291 100644 --- a/SDL2-2.0.12/src/filesystem/windows/SDL_sysfilesystem.c +++ b/SDL2-2.30.5/src/filesystem/windows/SDL_sysfilesystem.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -28,48 +28,32 @@ #include "../../core/windows/SDL_windows.h" #include -#include "SDL_assert.h" #include "SDL_error.h" #include "SDL_stdinc.h" #include "SDL_filesystem.h" -char * -SDL_GetBasePath(void) +char *SDL_GetBasePath(void) { - typedef DWORD (WINAPI *GetModuleFileNameExW_t)(HANDLE, HMODULE, LPWSTR, DWORD); - GetModuleFileNameExW_t pGetModuleFileNameExW; DWORD buflen = 128; WCHAR *path = NULL; - HANDLE psapi = LoadLibrary(L"psapi.dll"); char *retval = NULL; DWORD len = 0; int i; - if (!psapi) { - WIN_SetError("Couldn't load psapi.dll"); - return NULL; - } - - pGetModuleFileNameExW = (GetModuleFileNameExW_t)GetProcAddress(psapi, "GetModuleFileNameExW"); - if (!pGetModuleFileNameExW) { - WIN_SetError("Couldn't find GetModuleFileNameExW"); - FreeLibrary(psapi); - return NULL; - } - while (SDL_TRUE) { - void *ptr = SDL_realloc(path, buflen * sizeof (WCHAR)); + void *ptr = SDL_realloc(path, buflen * sizeof(WCHAR)); if (!ptr) { SDL_free(path); - FreeLibrary(psapi); SDL_OutOfMemory(); return NULL; } - path = (WCHAR *) ptr; + path = (WCHAR *)ptr; - len = pGetModuleFileNameExW(GetCurrentProcess(), NULL, path, buflen); - if (len != buflen) { + len = GetModuleFileNameW(NULL, path, buflen); + /* if it truncated, then len >= buflen - 1 */ + /* if there was enough room (or failure), len < buflen - 1 */ + if (len < buflen - 1) { break; } @@ -77,31 +61,28 @@ SDL_GetBasePath(void) buflen *= 2; } - FreeLibrary(psapi); - if (len == 0) { SDL_free(path); WIN_SetError("Couldn't locate our .exe"); return NULL; } - for (i = len-1; i > 0; i--) { + for (i = len - 1; i > 0; i--) { if (path[i] == '\\') { break; } } - SDL_assert(i > 0); /* Should have been an absolute path. */ - path[i+1] = '\0'; /* chop off filename. */ + SDL_assert(i > 0); /* Should have been an absolute path. */ + path[i + 1] = '\0'; /* chop off filename. */ - retval = WIN_StringToUTF8(path); + retval = WIN_StringToUTF8W(path); SDL_free(path); return retval; } -char * -SDL_GetPrefPath(const char *org, const char *app) +char *SDL_GetPrefPath(const char *org, const char *app) { /* * Vista and later has a new API for this, but SHGetFolderPath works there, @@ -113,8 +94,8 @@ SDL_GetPrefPath(const char *org, const char *app) WCHAR path[MAX_PATH]; char *retval = NULL; - WCHAR* worg = NULL; - WCHAR* wapp = NULL; + WCHAR *worg = NULL; + WCHAR *wapp = NULL; size_t new_wpath_len = 0; BOOL api_result = FALSE; @@ -131,20 +112,20 @@ SDL_GetPrefPath(const char *org, const char *app) return NULL; } - worg = WIN_UTF8ToString(org); - if (worg == NULL) { + worg = WIN_UTF8ToStringW(org); + if (!worg) { SDL_OutOfMemory(); return NULL; } - wapp = WIN_UTF8ToString(app); - if (wapp == NULL) { + wapp = WIN_UTF8ToStringW(app); + if (!wapp) { SDL_free(worg); SDL_OutOfMemory(); return NULL; } - new_wpath_len = lstrlenW(worg) + lstrlenW(wapp) + lstrlenW(path) + 3; + new_wpath_len = SDL_wcslen(worg) + SDL_wcslen(wapp) + SDL_wcslen(path) + 3; if ((new_wpath_len + 1) > MAX_PATH) { SDL_free(worg); @@ -154,8 +135,8 @@ SDL_GetPrefPath(const char *org, const char *app) } if (*worg) { - lstrcatW(path, L"\\"); - lstrcatW(path, worg); + SDL_wcslcat(path, L"\\", SDL_arraysize(path)); + SDL_wcslcat(path, worg, SDL_arraysize(path)); } SDL_free(worg); @@ -168,8 +149,8 @@ SDL_GetPrefPath(const char *org, const char *app) } } - lstrcatW(path, L"\\"); - lstrcatW(path, wapp); + SDL_wcslcat(path, L"\\", SDL_arraysize(path)); + SDL_wcslcat(path, wapp, SDL_arraysize(path)); SDL_free(wapp); api_result = CreateDirectoryW(path, NULL); @@ -180,9 +161,9 @@ SDL_GetPrefPath(const char *org, const char *app) } } - lstrcatW(path, L"\\"); + SDL_wcslcat(path, L"\\", SDL_arraysize(path)); - retval = WIN_StringToUTF8(path); + retval = WIN_StringToUTF8W(path); return retval; } diff --git a/SDL2-2.0.12/src/filesystem/winrt/SDL_sysfilesystem.cpp b/SDL2-2.30.5/src/filesystem/winrt/SDL_sysfilesystem.cpp similarity index 71% rename from SDL2-2.0.12/src/filesystem/winrt/SDL_sysfilesystem.cpp rename to SDL2-2.30.5/src/filesystem/winrt/SDL_sysfilesystem.cpp index 6685f1c..85cfd19 100644 --- a/SDL2-2.0.12/src/filesystem/winrt/SDL_sysfilesystem.cpp +++ b/SDL2-2.30.5/src/filesystem/winrt/SDL_sysfilesystem.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -21,7 +21,7 @@ #include "../../SDL_internal.h" /* TODO, WinRT: remove the need to compile this with C++/CX (/ZW) extensions, and if possible, without C++ at all -*/ + */ #ifdef __WINRT__ @@ -44,46 +44,55 @@ extern "C" const wchar_t * SDL_WinRTGetFSPathUNICODE(SDL_WinRT_Path pathType) { switch (pathType) { - case SDL_WINRT_PATH_INSTALLED_LOCATION: - { - static wstring path; - if (path.empty()) { + case SDL_WINRT_PATH_INSTALLED_LOCATION: + { + static wstring path; + if (path.empty()) { +#if defined(NTDDI_WIN10_19H1) && (NTDDI_VERSION >= NTDDI_WIN10_19H1) && (WINAPI_FAMILY == WINAPI_FAMILY_PC_APP) /* Only PC supports mods */ + /* Windows 1903 supports mods, via the EffectiveLocation API */ + if (Windows::Foundation::Metadata::ApiInformation::IsApiContractPresent("Windows.Foundation.UniversalApiContract", 8, 0)) { + path = Windows::ApplicationModel::Package::Current->EffectiveLocation->Path->Data(); + } else { path = Windows::ApplicationModel::Package::Current->InstalledLocation->Path->Data(); } - return path.c_str(); +#else + path = Windows::ApplicationModel::Package::Current->InstalledLocation->Path->Data(); +#endif } + return path.c_str(); + } - case SDL_WINRT_PATH_LOCAL_FOLDER: - { - static wstring path; - if (path.empty()) { - path = ApplicationData::Current->LocalFolder->Path->Data(); - } - return path.c_str(); + case SDL_WINRT_PATH_LOCAL_FOLDER: + { + static wstring path; + if (path.empty()) { + path = ApplicationData::Current->LocalFolder->Path->Data(); } + return path.c_str(); + } -#if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) || (NTDDI_VERSION > NTDDI_WIN8) - case SDL_WINRT_PATH_ROAMING_FOLDER: - { - static wstring path; - if (path.empty()) { - path = ApplicationData::Current->RoamingFolder->Path->Data(); - } - return path.c_str(); +#if !SDL_WINAPI_FAMILY_PHONE || (NTDDI_VERSION > NTDDI_WIN8) + case SDL_WINRT_PATH_ROAMING_FOLDER: + { + static wstring path; + if (path.empty()) { + path = ApplicationData::Current->RoamingFolder->Path->Data(); } + return path.c_str(); + } - case SDL_WINRT_PATH_TEMP_FOLDER: - { - static wstring path; - if (path.empty()) { - path = ApplicationData::Current->TemporaryFolder->Path->Data(); - } - return path.c_str(); + case SDL_WINRT_PATH_TEMP_FOLDER: + { + static wstring path; + if (path.empty()) { + path = ApplicationData::Current->TemporaryFolder->Path->Data(); } + return path.c_str(); + } #endif - default: - break; + default: + break; } SDL_Unsupported(); @@ -101,12 +110,12 @@ SDL_WinRTGetFSPathUTF8(SDL_WinRT_Path pathType) return searchResult->second.c_str(); } - const wchar_t * ucs2Path = SDL_WinRTGetFSPathUNICODE(pathType); + const wchar_t *ucs2Path = SDL_WinRTGetFSPathUNICODE(pathType); if (!ucs2Path) { return NULL; } - char * utf8Path = WIN_StringToUTF8(ucs2Path); + char *utf8Path = WIN_StringToUTF8(ucs2Path); utf8Paths[pathType] = utf8Path; SDL_free(utf8Path); return utf8Paths[pathType].c_str(); @@ -115,9 +124,9 @@ SDL_WinRTGetFSPathUTF8(SDL_WinRT_Path pathType) extern "C" char * SDL_GetBasePath(void) { - const char * srcPath = SDL_WinRTGetFSPathUTF8(SDL_WINRT_PATH_INSTALLED_LOCATION); + const char *srcPath = SDL_WinRTGetFSPathUTF8(SDL_WINRT_PATH_INSTALLED_LOCATION); size_t destPathLen; - char * destPath = NULL; + char *destPath = NULL; if (!srcPath) { SDL_SetError("Couldn't locate our basepath: %s", SDL_GetError()); @@ -125,7 +134,7 @@ SDL_GetBasePath(void) } destPathLen = SDL_strlen(srcPath) + 2; - destPath = (char *) SDL_malloc(destPathLen); + destPath = (char *)SDL_malloc(destPathLen); if (!destPath) { SDL_OutOfMemory(); return NULL; @@ -144,11 +153,11 @@ SDL_GetPrefPath(const char *org, const char *app) * without violating Microsoft's app-store requirements. */ - const WCHAR * srcPath = NULL; + const WCHAR *srcPath = NULL; WCHAR path[MAX_PATH]; char *retval = NULL; - WCHAR* worg = NULL; - WCHAR* wapp = NULL; + WCHAR *worg = NULL; + WCHAR *wapp = NULL; size_t new_wpath_len = 0; BOOL api_result = FALSE; @@ -161,7 +170,7 @@ SDL_GetPrefPath(const char *org, const char *app) } srcPath = SDL_WinRTGetFSPathUNICODE(SDL_WINRT_PATH_LOCAL_FOLDER); - if ( ! srcPath) { + if (!srcPath) { SDL_SetError("Unable to find a source path"); return NULL; } @@ -173,13 +182,13 @@ SDL_GetPrefPath(const char *org, const char *app) SDL_wcslcpy(path, srcPath, SDL_arraysize(path)); worg = WIN_UTF8ToString(org); - if (worg == NULL) { + if (!worg) { SDL_OutOfMemory(); return NULL; } wapp = WIN_UTF8ToString(app); - if (wapp == NULL) { + if (!wapp) { SDL_free(worg); SDL_OutOfMemory(); return NULL; diff --git a/SDL2-2.0.12/src/haptic/SDL_haptic.c b/SDL2-2.30.5/src/haptic/SDL_haptic.c similarity index 73% rename from SDL2-2.0.12/src/haptic/SDL_haptic.c rename to SDL2-2.30.5/src/haptic/SDL_haptic.c index 14713a8..256d667 100644 --- a/SDL2-2.0.12/src/haptic/SDL_haptic.c +++ b/SDL2-2.30.5/src/haptic/SDL_haptic.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,20 +23,18 @@ #include "SDL_syshaptic.h" #include "SDL_haptic_c.h" #include "../joystick/SDL_joystick_c.h" /* For SDL_PrivateJoystickValid */ -#include "SDL_assert.h" /* Global for SDL_windowshaptic.c */ -#if (defined(SDL_HAPTIC_DINPUT) && SDL_HAPTIC_DINPUT) || (defined(SDL_HAPTIC_XINPUT) && SDL_HAPTIC_XINPUT) +#if defined(SDL_HAPTIC_DINPUT) || defined(SDL_HAPTIC_XINPUT) SDL_Haptic *SDL_haptics = NULL; -#else +#else static SDL_Haptic *SDL_haptics = NULL; #endif /* * Initializes the Haptic devices. */ -int -SDL_HapticInit(void) +int SDL_HapticInit(void) { int status; @@ -48,21 +46,18 @@ SDL_HapticInit(void) return status; } - /* * Checks to see if the haptic device is valid */ -static int -ValidHaptic(SDL_Haptic * haptic) +static int ValidHaptic(SDL_Haptic *haptic) { int valid; SDL_Haptic *hapticlist; valid = 0; - if (haptic != NULL) { + if (haptic) { hapticlist = SDL_haptics; - while ( hapticlist ) - { + while (hapticlist) { if (hapticlist == haptic) { valid = 1; break; @@ -79,22 +74,18 @@ ValidHaptic(SDL_Haptic * haptic) return valid; } - /* * Returns the number of available devices. */ -int -SDL_NumHaptics(void) +int SDL_NumHaptics(void) { return SDL_SYS_NumHaptics(); } - /* * Gets the name of a Haptic device by index. */ -const char * -SDL_HapticName(int device_index) +const char *SDL_HapticName(int device_index) { if ((device_index < 0) || (device_index >= SDL_NumHaptics())) { SDL_SetError("Haptic: There are %d haptic devices available", @@ -104,12 +95,10 @@ SDL_HapticName(int device_index) return SDL_SYS_HapticName(device_index); } - /* * Opens a Haptic device. */ -SDL_Haptic * -SDL_HapticOpen(int device_index) +SDL_Haptic *SDL_HapticOpen(int device_index) { SDL_Haptic *haptic; SDL_Haptic *hapticlist; @@ -122,10 +111,9 @@ SDL_HapticOpen(int device_index) hapticlist = SDL_haptics; /* If the haptic is already open, return it - * TODO: Should we create haptic instance IDs like the Joystick API? - */ - while ( hapticlist ) - { + * TODO: Should we create haptic instance IDs like the Joystick API? + */ + while (hapticlist) { if (device_index == hapticlist->index) { haptic = hapticlist; ++haptic->ref_count; @@ -135,14 +123,14 @@ SDL_HapticOpen(int device_index) } /* Create the haptic device */ - haptic = (SDL_Haptic *) SDL_malloc((sizeof *haptic)); - if (haptic == NULL) { + haptic = (SDL_Haptic *)SDL_malloc(sizeof(*haptic)); + if (!haptic) { SDL_OutOfMemory(); return NULL; } /* Initialize the haptic device */ - SDL_memset(haptic, 0, (sizeof *haptic)); + SDL_memset(haptic, 0, sizeof(*haptic)); haptic->rumble_id = -1; haptic->index = device_index; if (SDL_SYS_HapticOpen(haptic) < 0) { @@ -157,20 +145,20 @@ SDL_HapticOpen(int device_index) SDL_haptics = haptic; /* Disable autocenter and set gain to max. */ - if (haptic->supported & SDL_HAPTIC_GAIN) + if (haptic->supported & SDL_HAPTIC_GAIN) { SDL_HapticSetGain(haptic, 100); - if (haptic->supported & SDL_HAPTIC_AUTOCENTER) + } + if (haptic->supported & SDL_HAPTIC_AUTOCENTER) { SDL_HapticSetAutocenter(haptic, 0); + } return haptic; } - /* * Returns 1 if the device has been opened. */ -int -SDL_HapticOpened(int device_index) +int SDL_HapticOpened(int device_index) { int opened; SDL_Haptic *hapticlist; @@ -185,9 +173,8 @@ SDL_HapticOpened(int device_index) opened = 0; hapticlist = SDL_haptics; /* TODO Should this use an instance ID? */ - while ( hapticlist ) - { - if (hapticlist->index == (Uint8) device_index) { + while (hapticlist) { + if (hapticlist->index == (Uint8)device_index) { opened = 1; break; } @@ -196,12 +183,10 @@ SDL_HapticOpened(int device_index) return opened; } - /* * Returns the index to a haptic device. */ -int -SDL_HapticIndex(SDL_Haptic * haptic) +int SDL_HapticIndex(SDL_Haptic *haptic) { if (!ValidHaptic(haptic)) { return -1; @@ -210,24 +195,21 @@ SDL_HapticIndex(SDL_Haptic * haptic) return haptic->index; } - /* * Returns SDL_TRUE if mouse is haptic, SDL_FALSE if it isn't. */ -int -SDL_MouseIsHaptic(void) +int SDL_MouseIsHaptic(void) { - if (SDL_SYS_HapticMouse() < 0) + if (SDL_SYS_HapticMouse() < 0) { return SDL_FALSE; + } return SDL_TRUE; } - /* * Returns the haptic device if mouse is haptic or NULL elsewise. */ -SDL_Haptic * -SDL_HapticOpenFromMouse(void) +SDL_Haptic *SDL_HapticOpenFromMouse(void) { int device_index; @@ -241,36 +223,38 @@ SDL_HapticOpenFromMouse(void) return SDL_HapticOpen(device_index); } - /* * Returns SDL_TRUE if joystick has haptic features. */ -int -SDL_JoystickIsHaptic(SDL_Joystick * joystick) +int SDL_JoystickIsHaptic(SDL_Joystick *joystick) { int ret; - /* Must be a valid joystick */ - if (!SDL_PrivateJoystickValid(joystick)) { - return -1; + SDL_LockJoysticks(); + { + /* Must be a valid joystick */ + if (!SDL_PrivateJoystickValid(joystick)) { + SDL_UnlockJoysticks(); + return -1; + } + + ret = SDL_SYS_JoystickIsHaptic(joystick); + } + SDL_UnlockJoysticks(); + + if (ret > 0) { + return SDL_TRUE; + } else if (ret == 0) { + return SDL_FALSE; } - ret = SDL_SYS_JoystickIsHaptic(joystick); - - if (ret > 0) - return SDL_TRUE; - else if (ret == 0) - return SDL_FALSE; - else - return -1; + return -1; } - /* * Opens a haptic device from a joystick. */ -SDL_Haptic * -SDL_HapticOpenFromJoystick(SDL_Joystick * joystick) +SDL_Haptic *SDL_HapticOpenFromJoystick(SDL_Joystick *joystick) { SDL_Haptic *haptic; SDL_Haptic *hapticlist; @@ -282,45 +266,53 @@ SDL_HapticOpenFromJoystick(SDL_Joystick * joystick) return NULL; } - /* Must be a valid joystick */ - if (!SDL_PrivateJoystickValid(joystick)) { - SDL_SetError("Haptic: Joystick isn't valid."); - return NULL; - } - - /* Joystick must be haptic */ - if (SDL_SYS_JoystickIsHaptic(joystick) <= 0) { - SDL_SetError("Haptic: Joystick isn't a haptic device."); - return NULL; - } - - hapticlist = SDL_haptics; - /* Check to see if joystick's haptic is already open */ - while ( hapticlist ) + SDL_LockJoysticks(); { - if (SDL_SYS_JoystickSameHaptic(hapticlist, joystick)) { - haptic = hapticlist; - ++haptic->ref_count; - return haptic; + /* Must be a valid joystick */ + if (!SDL_PrivateJoystickValid(joystick)) { + SDL_SetError("Haptic: Joystick isn't valid."); + SDL_UnlockJoysticks(); + return NULL; } - hapticlist = hapticlist->next; - } - /* Create the haptic device */ - haptic = (SDL_Haptic *) SDL_malloc((sizeof *haptic)); - if (haptic == NULL) { - SDL_OutOfMemory(); - return NULL; - } + /* Joystick must be haptic */ + if (SDL_SYS_JoystickIsHaptic(joystick) <= 0) { + SDL_SetError("Haptic: Joystick isn't a haptic device."); + SDL_UnlockJoysticks(); + return NULL; + } - /* Initialize the haptic device */ - SDL_memset(haptic, 0, sizeof(SDL_Haptic)); - haptic->rumble_id = -1; - if (SDL_SYS_HapticOpenFromJoystick(haptic, joystick) < 0) { - SDL_SetError("Haptic: SDL_SYS_HapticOpenFromJoystick failed."); - SDL_free(haptic); - return NULL; + hapticlist = SDL_haptics; + /* Check to see if joystick's haptic is already open */ + while (hapticlist) { + if (SDL_SYS_JoystickSameHaptic(hapticlist, joystick)) { + haptic = hapticlist; + ++haptic->ref_count; + SDL_UnlockJoysticks(); + return haptic; + } + hapticlist = hapticlist->next; + } + + /* Create the haptic device */ + haptic = (SDL_Haptic *)SDL_malloc(sizeof(*haptic)); + if (!haptic) { + SDL_OutOfMemory(); + SDL_UnlockJoysticks(); + return NULL; + } + + /* Initialize the haptic device */ + SDL_memset(haptic, 0, sizeof(SDL_Haptic)); + haptic->rumble_id = -1; + if (SDL_SYS_HapticOpenFromJoystick(haptic, joystick) < 0) { + SDL_SetError("Haptic: SDL_SYS_HapticOpenFromJoystick failed."); + SDL_free(haptic); + SDL_UnlockJoysticks(); + return NULL; + } } + SDL_UnlockJoysticks(); /* Add haptic to list */ ++haptic->ref_count; @@ -331,12 +323,10 @@ SDL_HapticOpenFromJoystick(SDL_Joystick * joystick) return haptic; } - /* * Closes a SDL_Haptic device. */ -void -SDL_HapticClose(SDL_Haptic * haptic) +void SDL_HapticClose(SDL_Haptic *haptic) { int i; SDL_Haptic *hapticlist; @@ -363,17 +353,12 @@ SDL_HapticClose(SDL_Haptic * haptic) /* Remove from the list */ hapticlist = SDL_haptics; hapticlistprev = NULL; - while ( hapticlist ) - { - if (haptic == hapticlist) - { - if ( hapticlistprev ) - { + while (hapticlist) { + if (haptic == hapticlist) { + if (hapticlistprev) { /* unlink this entry */ hapticlistprev->next = hapticlist->next; - } - else - { + } else { SDL_haptics = haptic->next; } @@ -390,8 +375,7 @@ SDL_HapticClose(SDL_Haptic * haptic) /* * Cleans up after the subsystem. */ -void -SDL_HapticQuit(void) +void SDL_HapticQuit(void) { while (SDL_haptics) { SDL_HapticClose(SDL_haptics); @@ -403,8 +387,7 @@ SDL_HapticQuit(void) /* * Returns the number of effects a haptic device has. */ -int -SDL_HapticNumEffects(SDL_Haptic * haptic) +int SDL_HapticNumEffects(SDL_Haptic *haptic) { if (!ValidHaptic(haptic)) { return -1; @@ -413,12 +396,10 @@ SDL_HapticNumEffects(SDL_Haptic * haptic) return haptic->neffects; } - /* * Returns the number of effects a haptic device can play. */ -int -SDL_HapticNumEffectsPlaying(SDL_Haptic * haptic) +int SDL_HapticNumEffectsPlaying(SDL_Haptic *haptic) { if (!ValidHaptic(haptic)) { return -1; @@ -427,12 +408,10 @@ SDL_HapticNumEffectsPlaying(SDL_Haptic * haptic) return haptic->nplaying; } - /* * Returns supported effects by the device. */ -unsigned int -SDL_HapticQuery(SDL_Haptic * haptic) +unsigned int SDL_HapticQuery(SDL_Haptic *haptic) { if (!ValidHaptic(haptic)) { return 0; /* same as if no effects were supported */ @@ -441,12 +420,10 @@ SDL_HapticQuery(SDL_Haptic * haptic) return haptic->supported; } - /* * Returns the number of axis on the device. */ -int -SDL_HapticNumAxes(SDL_Haptic * haptic) +int SDL_HapticNumAxes(SDL_Haptic *haptic) { if (!ValidHaptic(haptic)) { return -1; @@ -458,23 +435,22 @@ SDL_HapticNumAxes(SDL_Haptic * haptic) /* * Checks to see if the device can support the effect. */ -int -SDL_HapticEffectSupported(SDL_Haptic * haptic, SDL_HapticEffect * effect) +int SDL_HapticEffectSupported(SDL_Haptic *haptic, SDL_HapticEffect *effect) { if (!ValidHaptic(haptic)) { return -1; } - if ((haptic->supported & effect->type) != 0) + if ((haptic->supported & effect->type) != 0) { return SDL_TRUE; + } return SDL_FALSE; } /* * Creates a new haptic effect. */ -int -SDL_HapticNewEffect(SDL_Haptic * haptic, SDL_HapticEffect * effect) +int SDL_HapticNewEffect(SDL_Haptic *haptic, SDL_HapticEffect *effect) { int i; @@ -493,9 +469,8 @@ SDL_HapticNewEffect(SDL_Haptic * haptic, SDL_HapticEffect * effect) if (haptic->effects[i].hweffect == NULL) { /* Now let the backend create the real effect */ - if (SDL_SYS_HapticNewEffect(haptic, &haptic->effects[i], effect) - != 0) { - return -1; /* Backend failed to create effect */ + if (SDL_SYS_HapticNewEffect(haptic, &haptic->effects[i], effect) != 0) { + return -1; /* Backend failed to create effect */ } SDL_memcpy(&haptic->effects[i].effect, effect, @@ -510,8 +485,7 @@ SDL_HapticNewEffect(SDL_Haptic * haptic, SDL_HapticEffect * effect) /* * Checks to see if an effect is valid. */ -static int -ValidEffect(SDL_Haptic * haptic, int effect) +static int ValidEffect(SDL_Haptic *haptic, int effect) { if ((effect < 0) || (effect >= haptic->neffects)) { SDL_SetError("Haptic: Invalid effect identifier."); @@ -523,9 +497,8 @@ ValidEffect(SDL_Haptic * haptic, int effect) /* * Updates an effect. */ -int -SDL_HapticUpdateEffect(SDL_Haptic * haptic, int effect, - SDL_HapticEffect * data) +int SDL_HapticUpdateEffect(SDL_Haptic *haptic, int effect, + SDL_HapticEffect *data) { if (!ValidHaptic(haptic) || !ValidEffect(haptic, effect)) { return -1; @@ -547,20 +520,17 @@ SDL_HapticUpdateEffect(SDL_Haptic * haptic, int effect, return 0; } - /* * Runs the haptic effect on the device. */ -int -SDL_HapticRunEffect(SDL_Haptic * haptic, int effect, Uint32 iterations) +int SDL_HapticRunEffect(SDL_Haptic *haptic, int effect, Uint32 iterations) { if (!ValidHaptic(haptic) || !ValidEffect(haptic, effect)) { return -1; } /* Run the effect */ - if (SDL_SYS_HapticRunEffect(haptic, &haptic->effects[effect], iterations) - < 0) { + if (SDL_SYS_HapticRunEffect(haptic, &haptic->effects[effect], iterations) < 0) { return -1; } @@ -570,8 +540,7 @@ SDL_HapticRunEffect(SDL_Haptic * haptic, int effect, Uint32 iterations) /* * Stops the haptic effect on the device. */ -int -SDL_HapticStopEffect(SDL_Haptic * haptic, int effect) +int SDL_HapticStopEffect(SDL_Haptic *haptic, int effect) { if (!ValidHaptic(haptic) || !ValidEffect(haptic, effect)) { return -1; @@ -588,8 +557,7 @@ SDL_HapticStopEffect(SDL_Haptic * haptic, int effect) /* * Gets rid of a haptic effect. */ -void -SDL_HapticDestroyEffect(SDL_Haptic * haptic, int effect) +void SDL_HapticDestroyEffect(SDL_Haptic *haptic, int effect) { if (!ValidHaptic(haptic) || !ValidEffect(haptic, effect)) { return; @@ -606,14 +574,13 @@ SDL_HapticDestroyEffect(SDL_Haptic * haptic, int effect) /* * Gets the status of a haptic effect. */ -int -SDL_HapticGetEffectStatus(SDL_Haptic * haptic, int effect) +int SDL_HapticGetEffectStatus(SDL_Haptic *haptic, int effect) { if (!ValidHaptic(haptic) || !ValidEffect(haptic, effect)) { return -1; } - if ((haptic->supported & SDL_HAPTIC_STATUS) == 0) { + if (!(haptic->supported & SDL_HAPTIC_STATUS)) { return SDL_SetError("Haptic: Device does not support status queries."); } @@ -623,8 +590,7 @@ SDL_HapticGetEffectStatus(SDL_Haptic * haptic, int effect) /* * Sets the global gain of the device. */ -int -SDL_HapticSetGain(SDL_Haptic * haptic, int gain) +int SDL_HapticSetGain(SDL_Haptic *haptic, int gain) { const char *env; int real_gain, max_gain; @@ -633,7 +599,7 @@ SDL_HapticSetGain(SDL_Haptic * haptic, int gain) return -1; } - if ((haptic->supported & SDL_HAPTIC_GAIN) == 0) { + if (!(haptic->supported & SDL_HAPTIC_GAIN)) { return SDL_SetError("Haptic: Device does not support setting gain."); } @@ -643,14 +609,15 @@ SDL_HapticSetGain(SDL_Haptic * haptic, int gain) /* We use the envvar to get the maximum gain. */ env = SDL_getenv("SDL_HAPTIC_GAIN_MAX"); - if (env != NULL) { + if (env) { max_gain = SDL_atoi(env); /* Check for sanity. */ - if (max_gain < 0) + if (max_gain < 0) { max_gain = 0; - else if (max_gain > 100) + } else if (max_gain > 100) { max_gain = 100; + } /* We'll scale it linearly with SDL_HAPTIC_GAIN_MAX */ real_gain = (gain * max_gain) / 100; @@ -668,14 +635,13 @@ SDL_HapticSetGain(SDL_Haptic * haptic, int gain) /* * Makes the device autocenter, 0 disables. */ -int -SDL_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter) +int SDL_HapticSetAutocenter(SDL_Haptic *haptic, int autocenter) { if (!ValidHaptic(haptic)) { return -1; } - if ((haptic->supported & SDL_HAPTIC_AUTOCENTER) == 0) { + if (!(haptic->supported & SDL_HAPTIC_AUTOCENTER)) { return SDL_SetError("Haptic: Device does not support setting autocenter."); } @@ -693,14 +659,13 @@ SDL_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter) /* * Pauses the haptic device. */ -int -SDL_HapticPause(SDL_Haptic * haptic) +int SDL_HapticPause(SDL_Haptic *haptic) { if (!ValidHaptic(haptic)) { return -1; } - if ((haptic->supported & SDL_HAPTIC_PAUSE) == 0) { + if (!(haptic->supported & SDL_HAPTIC_PAUSE)) { return SDL_SetError("Haptic: Device does not support setting pausing."); } @@ -710,15 +675,14 @@ SDL_HapticPause(SDL_Haptic * haptic) /* * Unpauses the haptic device. */ -int -SDL_HapticUnpause(SDL_Haptic * haptic) +int SDL_HapticUnpause(SDL_Haptic *haptic) { if (!ValidHaptic(haptic)) { return -1; } - if ((haptic->supported & SDL_HAPTIC_PAUSE) == 0) { - return 0; /* Not going to be paused, so we pretend it's unpaused. */ + if (!(haptic->supported & SDL_HAPTIC_PAUSE)) { + return 0; /* Not going to be paused, so we pretend it's unpaused. */ } return SDL_SYS_HapticUnpause(haptic); @@ -727,8 +691,7 @@ SDL_HapticUnpause(SDL_Haptic * haptic) /* * Stops all the currently playing effects. */ -int -SDL_HapticStopAll(SDL_Haptic * haptic) +int SDL_HapticStopAll(SDL_Haptic *haptic) { if (!ValidHaptic(haptic)) { return -1; @@ -740,22 +703,20 @@ SDL_HapticStopAll(SDL_Haptic * haptic) /* * Checks to see if rumble is supported. */ -int -SDL_HapticRumbleSupported(SDL_Haptic * haptic) +int SDL_HapticRumbleSupported(SDL_Haptic *haptic) { if (!ValidHaptic(haptic)) { return -1; } /* Most things can use SINE, but XInput only has LEFTRIGHT. */ - return ((haptic->supported & (SDL_HAPTIC_SINE|SDL_HAPTIC_LEFTRIGHT)) != 0); + return (haptic->supported & (SDL_HAPTIC_SINE | SDL_HAPTIC_LEFTRIGHT)) != 0; } /* * Initializes the haptic device for simple rumble playback. */ -int -SDL_HapticRumbleInit(SDL_Haptic * haptic) +int SDL_HapticRumbleInit(SDL_Haptic *haptic) { SDL_HapticEffect *efx = &haptic->rumble_effect; @@ -777,7 +738,7 @@ SDL_HapticRumbleInit(SDL_Haptic * haptic) efx->periodic.length = 5000; efx->periodic.attack_length = 0; efx->periodic.fade_length = 0; - } else if (haptic->supported & SDL_HAPTIC_LEFTRIGHT) { /* XInput? */ + } else if (haptic->supported & SDL_HAPTIC_LEFTRIGHT) { /* XInput? */ efx->type = SDL_HAPTIC_LEFTRIGHT; efx->leftright.length = 5000; efx->leftright.large_magnitude = 0x4000; @@ -796,8 +757,7 @@ SDL_HapticRumbleInit(SDL_Haptic * haptic) /* * Runs simple rumble on a haptic device */ -int -SDL_HapticRumblePlay(SDL_Haptic * haptic, float strength, Uint32 length) +int SDL_HapticRumblePlay(SDL_Haptic *haptic, float strength, Uint32 length) { SDL_HapticEffect *efx; Sint16 magnitude; @@ -816,7 +776,7 @@ SDL_HapticRumblePlay(SDL_Haptic * haptic, float strength, Uint32 length) } else if (strength < 0.0f) { strength = 0.0f; } - magnitude = (Sint16)(32767.0f*strength); + magnitude = (Sint16)(32767.0f * strength); efx = &haptic->rumble_effect; if (efx->type == SDL_HAPTIC_SINE) { @@ -839,8 +799,7 @@ SDL_HapticRumblePlay(SDL_Haptic * haptic, float strength, Uint32 length) /* * Stops the simple rumble on a haptic device. */ -int -SDL_HapticRumbleStop(SDL_Haptic * haptic) +int SDL_HapticRumbleStop(SDL_Haptic *haptic) { if (!ValidHaptic(haptic)) { return -1; diff --git a/SDL2-2.0.12/src/haptic/SDL_haptic_c.h b/SDL2-2.30.5/src/haptic/SDL_haptic_c.h similarity index 94% rename from SDL2-2.0.12/src/haptic/SDL_haptic_c.h rename to SDL2-2.30.5/src/haptic/SDL_haptic_c.h index 5534bfd..a1b1ed7 100644 --- a/SDL2-2.0.12/src/haptic/SDL_haptic_c.h +++ b/SDL2-2.30.5/src/haptic/SDL_haptic_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/haptic/SDL_syshaptic.h b/SDL2-2.30.5/src/haptic/SDL_syshaptic.h similarity index 63% rename from SDL2-2.0.12/src/haptic/SDL_syshaptic.h rename to SDL2-2.30.5/src/haptic/SDL_syshaptic.h index 737bbd1..31f37dd 100644 --- a/SDL2-2.0.12/src/haptic/SDL_syshaptic.h +++ b/SDL2-2.30.5/src/haptic/SDL_syshaptic.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,11 +26,15 @@ #include "SDL_haptic.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif struct haptic_effect { - SDL_HapticEffect effect; /* The current event */ - struct haptic_hweffect *hweffect; /* The hardware behind the event */ + SDL_HapticEffect effect; /* The current event */ + struct haptic_hweffect *hweffect; /* The hardware behind the event */ }; /* @@ -38,20 +42,20 @@ struct haptic_effect */ struct _SDL_Haptic { - Uint8 index; /* Stores index it is attached to */ + Uint8 index; /* Stores index it is attached to */ - struct haptic_effect *effects; /* Allocated effects */ - int neffects; /* Maximum amount of effects */ - int nplaying; /* Maximum amount of effects to play at the same time */ - unsigned int supported; /* Supported effects */ - int naxes; /* Number of axes on the device. */ + struct haptic_effect *effects; /* Allocated effects */ + int neffects; /* Maximum amount of effects */ + int nplaying; /* Maximum amount of effects to play at the same time */ + unsigned int supported; /* Supported effects */ + int naxes; /* Number of axes on the device. */ - struct haptic_hwdata *hwdata; /* Driver dependent */ - int ref_count; /* Count for multiple opens */ + struct haptic_hwdata *hwdata; /* Driver dependent */ + int ref_count; /* Count for multiple opens */ - int rumble_id; /* ID of rumble effect for simple rumble API. */ + int rumble_id; /* ID of rumble effect for simple rumble API. */ SDL_HapticEffect rumble_effect; /* Rumble effect. */ - struct _SDL_Haptic *next; /* pointer to next haptic we have allocated */ + struct _SDL_Haptic *next; /* pointer to next haptic we have allocated */ }; /* @@ -75,7 +79,7 @@ extern const char *SDL_SYS_HapticName(int index); * * Returns 0 on success, -1 on error. */ -extern int SDL_SYS_HapticOpen(SDL_Haptic * haptic); +extern int SDL_SYS_HapticOpen(SDL_Haptic *haptic); /* * Returns the index of the haptic core pointer or -1 if none is found. @@ -88,7 +92,7 @@ int SDL_SYS_HapticMouse(void); * Returns >0 if haptic capabilities are detected, 0 if haptic * capabilities aren't detected and -1 on error. */ -extern int SDL_SYS_JoystickIsHaptic(SDL_Joystick * joystick); +extern int SDL_SYS_JoystickIsHaptic(SDL_Joystick *joystick); /* * Opens the haptic device for usage using the same device as @@ -96,20 +100,20 @@ extern int SDL_SYS_JoystickIsHaptic(SDL_Joystick * joystick); * * Returns 0 on success, -1 on error. */ -extern int SDL_SYS_HapticOpenFromJoystick(SDL_Haptic * haptic, - SDL_Joystick * joystick); +extern int SDL_SYS_HapticOpenFromJoystick(SDL_Haptic *haptic, + SDL_Joystick *joystick); /* * Checks to see if haptic device and joystick device are the same. * * Returns 1 if they are the same, 0 if they aren't. */ -extern int SDL_SYS_JoystickSameHaptic(SDL_Haptic * haptic, - SDL_Joystick * joystick); +extern int SDL_SYS_JoystickSameHaptic(SDL_Haptic *haptic, + SDL_Joystick *joystick); /* * Closes a haptic device after usage. */ -extern void SDL_SYS_HapticClose(SDL_Haptic * haptic); +extern void SDL_SYS_HapticClose(SDL_Haptic *haptic); /* * Performs a cleanup on the haptic subsystem. @@ -122,9 +126,9 @@ extern void SDL_SYS_HapticQuit(void); * * Returns 0 on success, -1 on error. */ -extern int SDL_SYS_HapticNewEffect(SDL_Haptic * haptic, +extern int SDL_SYS_HapticNewEffect(SDL_Haptic *haptic, struct haptic_effect *effect, - SDL_HapticEffect * base); + SDL_HapticEffect *base); /* * Updates the haptic effect on the haptic device using data @@ -132,16 +136,16 @@ extern int SDL_SYS_HapticNewEffect(SDL_Haptic * haptic, * * Returns 0 on success, -1 on error. */ -extern int SDL_SYS_HapticUpdateEffect(SDL_Haptic * haptic, +extern int SDL_SYS_HapticUpdateEffect(SDL_Haptic *haptic, struct haptic_effect *effect, - SDL_HapticEffect * data); + SDL_HapticEffect *data); /* * Runs the effect on the haptic device. * * Returns 0 on success, -1 on error. */ -extern int SDL_SYS_HapticRunEffect(SDL_Haptic * haptic, +extern int SDL_SYS_HapticRunEffect(SDL_Haptic *haptic, struct haptic_effect *effect, Uint32 iterations); @@ -150,13 +154,13 @@ extern int SDL_SYS_HapticRunEffect(SDL_Haptic * haptic, * * Returns 0 on success, -1 on error. */ -extern int SDL_SYS_HapticStopEffect(SDL_Haptic * haptic, +extern int SDL_SYS_HapticStopEffect(SDL_Haptic *haptic, struct haptic_effect *effect); /* * Cleanups up the effect on the haptic device. */ -extern void SDL_SYS_HapticDestroyEffect(SDL_Haptic * haptic, +extern void SDL_SYS_HapticDestroyEffect(SDL_Haptic *haptic, struct haptic_effect *effect); /* @@ -165,7 +169,7 @@ extern void SDL_SYS_HapticDestroyEffect(SDL_Haptic * haptic, * Returns 0 if device is stopped, >0 if device is playing and * -1 on error. */ -extern int SDL_SYS_HapticGetEffectStatus(SDL_Haptic * haptic, +extern int SDL_SYS_HapticGetEffectStatus(SDL_Haptic *haptic, struct haptic_effect *effect); /* @@ -173,35 +177,40 @@ extern int SDL_SYS_HapticGetEffectStatus(SDL_Haptic * haptic, * * Returns 0 on success, -1 on error. */ -extern int SDL_SYS_HapticSetGain(SDL_Haptic * haptic, int gain); +extern int SDL_SYS_HapticSetGain(SDL_Haptic *haptic, int gain); /* * Sets the autocenter feature of the haptic device. * * Returns 0 on success, -1 on error. */ -extern int SDL_SYS_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter); +extern int SDL_SYS_HapticSetAutocenter(SDL_Haptic *haptic, int autocenter); /* * Pauses the haptic device. * * Returns 0 on success, -1 on error. */ -extern int SDL_SYS_HapticPause(SDL_Haptic * haptic); +extern int SDL_SYS_HapticPause(SDL_Haptic *haptic); /* * Unpauses the haptic device. * * Returns 0 on success, -1 on error. */ -extern int SDL_SYS_HapticUnpause(SDL_Haptic * haptic); +extern int SDL_SYS_HapticUnpause(SDL_Haptic *haptic); /* * Stops all the currently playing haptic effects on the device. * * Returns 0 on success, -1 on error. */ -extern int SDL_SYS_HapticStopAll(SDL_Haptic * haptic); +extern int SDL_SYS_HapticStopAll(SDL_Haptic *haptic); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif #endif /* SDL_syshaptic_h_ */ diff --git a/SDL2-2.0.12/src/haptic/android/SDL_syshaptic.c b/SDL2-2.30.5/src/haptic/android/SDL_syshaptic.c similarity index 60% rename from SDL2-2.0.12/src/haptic/android/SDL_syshaptic.c rename to SDL2-2.30.5/src/haptic/android/SDL_syshaptic.c index 9e47880..15fbdd2 100644 --- a/SDL2-2.0.12/src/haptic/android/SDL_syshaptic.c +++ b/SDL2-2.30.5/src/haptic/android/SDL_syshaptic.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -22,7 +22,6 @@ #ifdef SDL_HAPTIC_ANDROID -#include "SDL_assert.h" #include "SDL_timer.h" #include "SDL_syshaptic_c.h" #include "../SDL_syshaptic.h" @@ -45,9 +44,7 @@ static SDL_hapticlist_item *SDL_hapticlist = NULL; static SDL_hapticlist_item *SDL_hapticlist_tail = NULL; static int numhaptics = 0; - -int -SDL_SYS_HapticInit(void) +int SDL_SYS_HapticInit(void) { /* Support for device connect/disconnect is API >= 16 only, * so we poll every three seconds @@ -58,17 +55,15 @@ SDL_SYS_HapticInit(void) timeout = SDL_GetTicks() + 3000; Android_JNI_PollHapticDevices(); } - return (numhaptics); + return numhaptics; } -int -SDL_SYS_NumHaptics(void) +int SDL_SYS_NumHaptics(void) { - return (numhaptics); + return numhaptics; } -static SDL_hapticlist_item * -HapticByOrder(int index) +static SDL_hapticlist_item *HapticByOrder(int index) { SDL_hapticlist_item *item = SDL_hapticlist; if ((index < 0) || (index >= numhaptics)) { @@ -82,11 +77,10 @@ HapticByOrder(int index) return item; } -static SDL_hapticlist_item * -HapticByDevId (int device_id) +static SDL_hapticlist_item *HapticByDevId(int device_id) { SDL_hapticlist_item *item; - for (item = SDL_hapticlist; item != NULL; item = item->next) { + for (item = SDL_hapticlist; item; item = item->next) { if (device_id == item->device_id) { /*SDL_Log("=+=+=+=+=+= HapticByDevId id [%d]", device_id);*/ return item; @@ -95,26 +89,23 @@ HapticByDevId (int device_id) return NULL; } -const char * -SDL_SYS_HapticName(int index) +const char *SDL_SYS_HapticName(int index) { SDL_hapticlist_item *item = HapticByOrder(index); - if (item == NULL ) { + if (!item) { SDL_SetError("No such device"); return NULL; } return item->name; } - -static SDL_hapticlist_item * -OpenHaptic(SDL_Haptic *haptic, SDL_hapticlist_item *item) +static SDL_hapticlist_item *OpenHaptic(SDL_Haptic *haptic, SDL_hapticlist_item *item) { - if (item == NULL ) { + if (!item) { SDL_SetError("No such device"); return NULL; } - if (item->haptic != NULL) { + if (item->haptic) { SDL_SetError("Haptic already opened"); return NULL; } @@ -125,75 +116,59 @@ OpenHaptic(SDL_Haptic *haptic, SDL_hapticlist_item *item) haptic->supported = SDL_HAPTIC_LEFTRIGHT; haptic->neffects = 1; haptic->nplaying = haptic->neffects; - haptic->effects = (struct haptic_effect *)SDL_malloc (sizeof (struct haptic_effect) * haptic->neffects); - if (haptic->effects == NULL) { + haptic->effects = (struct haptic_effect *)SDL_malloc(sizeof(struct haptic_effect) * haptic->neffects); + if (!haptic->effects) { SDL_OutOfMemory(); return NULL; } - SDL_memset(haptic->effects, 0, sizeof (struct haptic_effect) * haptic->neffects); + SDL_memset(haptic->effects, 0, sizeof(struct haptic_effect) * haptic->neffects); return item; } -static SDL_hapticlist_item * -OpenHapticByOrder(SDL_Haptic *haptic, int index) +static SDL_hapticlist_item *OpenHapticByOrder(SDL_Haptic *haptic, int index) { - return OpenHaptic (haptic, HapticByOrder(index)); + return OpenHaptic(haptic, HapticByOrder(index)); } -static SDL_hapticlist_item * -OpenHapticByDevId(SDL_Haptic *haptic, int device_id) +static SDL_hapticlist_item *OpenHapticByDevId(SDL_Haptic *haptic, int device_id) { - return OpenHaptic (haptic, HapticByDevId(device_id)); + return OpenHaptic(haptic, HapticByDevId(device_id)); } -int -SDL_SYS_HapticOpen(SDL_Haptic *haptic) +int SDL_SYS_HapticOpen(SDL_Haptic *haptic) { - return (OpenHapticByOrder(haptic, haptic->index) == NULL ? -1 : 0); + return OpenHapticByOrder(haptic, haptic->index) == NULL ? -1 : 0; } - -int -SDL_SYS_HapticMouse(void) +int SDL_SYS_HapticMouse(void) { - return 0; + return -1; } - -int -SDL_SYS_JoystickIsHaptic(SDL_Joystick *joystick) +int SDL_SYS_JoystickIsHaptic(SDL_Joystick *joystick) { SDL_hapticlist_item *item; item = HapticByDevId(((joystick_hwdata *)joystick->hwdata)->device_id); - return (item != NULL) ? 1 : 0; + return (item) ? 1 : 0; } - -int -SDL_SYS_HapticOpenFromJoystick(SDL_Haptic *haptic, SDL_Joystick *joystick) +int SDL_SYS_HapticOpenFromJoystick(SDL_Haptic *haptic, SDL_Joystick *joystick) { - return (OpenHapticByDevId(haptic, ((joystick_hwdata *)joystick->hwdata)->device_id) == NULL ? -1 : 0); + return OpenHapticByDevId(haptic, ((joystick_hwdata *)joystick->hwdata)->device_id) == NULL ? -1 : 0; } - -int -SDL_SYS_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick) +int SDL_SYS_JoystickSameHaptic(SDL_Haptic *haptic, SDL_Joystick *joystick) { - return (((SDL_hapticlist_item *)haptic->hwdata)->device_id == ((joystick_hwdata *)joystick->hwdata)->device_id ? 1 : 0); + return ((SDL_hapticlist_item *)haptic->hwdata)->device_id == ((joystick_hwdata *)joystick->hwdata)->device_id ? 1 : 0; } - -void -SDL_SYS_HapticClose(SDL_Haptic * haptic) +void SDL_SYS_HapticClose(SDL_Haptic *haptic) { ((SDL_hapticlist_item *)haptic->hwdata)->haptic = NULL; haptic->hwdata = NULL; - return; } - -void -SDL_SYS_HapticQuit(void) +void SDL_SYS_HapticQuit(void) { /* We don't have any way to scan for joysticks (and their vibrators) at init, so don't wipe the list * of joysticks here in case this is a reinit. @@ -213,111 +188,87 @@ SDL_SYS_HapticQuit(void) #endif } - -int -SDL_SYS_HapticNewEffect(SDL_Haptic * haptic, - struct haptic_effect *effect, SDL_HapticEffect * base) +int SDL_SYS_HapticNewEffect(SDL_Haptic *haptic, + struct haptic_effect *effect, SDL_HapticEffect *base) { return 0; } - -int -SDL_SYS_HapticUpdateEffect(SDL_Haptic * haptic, - struct haptic_effect *effect, - SDL_HapticEffect * data) +int SDL_SYS_HapticUpdateEffect(SDL_Haptic *haptic, + struct haptic_effect *effect, + SDL_HapticEffect *data) { return 0; } - -int -SDL_SYS_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect, - Uint32 iterations) +int SDL_SYS_HapticRunEffect(SDL_Haptic *haptic, struct haptic_effect *effect, + Uint32 iterations) { float large = effect->effect.leftright.large_magnitude / 32767.0f; float small = effect->effect.leftright.small_magnitude / 32767.0f; float total = (large * 0.6f) + (small * 0.4f); - Android_JNI_HapticRun (((SDL_hapticlist_item *)haptic->hwdata)->device_id, total, effect->effect.leftright.length); + Android_JNI_HapticRun(((SDL_hapticlist_item *)haptic->hwdata)->device_id, total, effect->effect.leftright.length); return 0; } - -int -SDL_SYS_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect *effect) +int SDL_SYS_HapticStopEffect(SDL_Haptic *haptic, struct haptic_effect *effect) { - Android_JNI_HapticStop (((SDL_hapticlist_item *)haptic->hwdata)->device_id); + Android_JNI_HapticStop(((SDL_hapticlist_item *)haptic->hwdata)->device_id); return 0; } - -void -SDL_SYS_HapticDestroyEffect(SDL_Haptic * haptic, struct haptic_effect *effect) +void SDL_SYS_HapticDestroyEffect(SDL_Haptic *haptic, struct haptic_effect *effect) { - return; } - -int -SDL_SYS_HapticGetEffectStatus(SDL_Haptic * haptic, - struct haptic_effect *effect) +int SDL_SYS_HapticGetEffectStatus(SDL_Haptic *haptic, struct haptic_effect *effect) { return 0; } - -int -SDL_SYS_HapticSetGain(SDL_Haptic * haptic, int gain) +int SDL_SYS_HapticSetGain(SDL_Haptic *haptic, int gain) { return 0; } - -int -SDL_SYS_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter) +int SDL_SYS_HapticSetAutocenter(SDL_Haptic *haptic, int autocenter) { return 0; } -int -SDL_SYS_HapticPause(SDL_Haptic * haptic) +int SDL_SYS_HapticPause(SDL_Haptic *haptic) { return 0; } -int -SDL_SYS_HapticUnpause(SDL_Haptic * haptic) +int SDL_SYS_HapticUnpause(SDL_Haptic *haptic) { return 0; } -int -SDL_SYS_HapticStopAll(SDL_Haptic * haptic) +int SDL_SYS_HapticStopAll(SDL_Haptic *haptic) { return 0; } - - -int -Android_AddHaptic(int device_id, const char *name) +int Android_AddHaptic(int device_id, const char *name) { SDL_hapticlist_item *item; - item = (SDL_hapticlist_item *) SDL_calloc(1, sizeof (SDL_hapticlist_item)); - if (item == NULL) { + item = (SDL_hapticlist_item *)SDL_calloc(1, sizeof(SDL_hapticlist_item)); + if (!item) { return -1; } item->device_id = device_id; - item->name = SDL_strdup (name); - if (item->name == NULL) { - SDL_free (item); + item->name = SDL_strdup(name); + if (!item->name) { + SDL_free(item); return -1; } - if (SDL_hapticlist_tail == NULL) { + if (!SDL_hapticlist_tail) { SDL_hapticlist = SDL_hapticlist_tail = item; } else { SDL_hapticlist_tail->next = item; @@ -328,18 +279,17 @@ Android_AddHaptic(int device_id, const char *name) return numhaptics; } -int -Android_RemoveHaptic(int device_id) +int Android_RemoveHaptic(int device_id) { SDL_hapticlist_item *item; SDL_hapticlist_item *prev = NULL; - for (item = SDL_hapticlist; item != NULL; item = item->next) { + for (item = SDL_hapticlist; item; item = item->next) { /* found it, remove it. */ if (device_id == item->device_id) { const int retval = item->haptic ? item->haptic->index : -1; - if (prev != NULL) { + if (prev) { prev->next = item->next; } else { SDL_assert(SDL_hapticlist == item); @@ -362,7 +312,6 @@ Android_RemoveHaptic(int device_id) return -1; } - #endif /* SDL_HAPTIC_ANDROID */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/haptic/android/SDL_syshaptic_c.h b/SDL2-2.30.5/src/haptic/android/SDL_syshaptic_c.h similarity index 100% rename from SDL2-2.0.12/src/haptic/android/SDL_syshaptic_c.h rename to SDL2-2.30.5/src/haptic/android/SDL_syshaptic_c.h diff --git a/SDL2-2.0.12/src/haptic/darwin/SDL_syshaptic.c b/SDL2-2.30.5/src/haptic/darwin/SDL_syshaptic.c similarity index 82% rename from SDL2-2.0.12/src/haptic/darwin/SDL_syshaptic.c rename to SDL2-2.30.5/src/haptic/darwin/SDL_syshaptic.c index ecbd2bd..d33e4d6 100644 --- a/SDL2-2.0.12/src/haptic/darwin/SDL_syshaptic.c +++ b/SDL2-2.30.5/src/haptic/darwin/SDL_syshaptic.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -22,13 +22,12 @@ #ifdef SDL_HAPTIC_IOKIT -#include "SDL_assert.h" #include "SDL_stdinc.h" #include "SDL_haptic.h" #include "../SDL_syshaptic.h" #include "SDL_joystick.h" #include "../../joystick/SDL_sysjoystick.h" /* For the real SDL_Joystick */ -#include "../../joystick/darwin/SDL_sysjoystick_c.h" /* For joystick hwdata */ +#include "../../joystick/darwin/SDL_iokitjoystick_c.h" /* For joystick hwdata */ #include "SDL_syshaptic_c.h" #include @@ -38,7 +37,7 @@ #include #ifndef IO_OBJECT_NULL -#define IO_OBJECT_NULL ((io_service_t)0) +#define IO_OBJECT_NULL ((io_service_t)0) #endif /* @@ -46,10 +45,10 @@ */ typedef struct SDL_hapticlist_item { - char name[256]; /* Name of the device. */ + char name[256]; /* Name of the device. */ - io_service_t dev; /* Node we use to create the device. */ - SDL_Haptic *haptic; /* Haptic currently associated with it. */ + io_service_t dev; /* Node we use to create the device. */ + SDL_Haptic *haptic; /* Haptic currently associated with it. */ /* Usage pages for determining if it's a mouse or not. */ long usage; @@ -58,30 +57,28 @@ typedef struct SDL_hapticlist_item struct SDL_hapticlist_item *next; } SDL_hapticlist_item; - /* * Haptic system hardware data. */ struct haptic_hwdata { - FFDeviceObjectReference device; /* Hardware device. */ + FFDeviceObjectReference device; /* Hardware device. */ UInt8 axes[3]; }; - /* * Haptic system effect data. */ struct haptic_hweffect { - FFEffectObjectReference ref; /* Reference. */ - struct FFEFFECT effect; /* Hardware effect. */ + FFEffectObjectReference ref; /* Reference. */ + struct FFEFFECT effect; /* Hardware effect. */ }; /* * Prototypes. */ -static void SDL_SYS_HapticFreeFFEFFECT(FFEFFECT * effect, int type); +static void SDL_SYS_HapticFreeFFEFFECT(FFEFFECT *effect, int type); static int HIDGetDeviceProduct(io_service_t dev, char *name); static SDL_hapticlist_item *SDL_hapticlist = NULL; @@ -91,8 +88,7 @@ static int numhaptics = -1; /* * Like strerror but for force feedback errors. */ -static const char * -FFStrError(unsigned int err) +static const char *FFStrError(unsigned int err) { switch (err) { case FFERR_DEVICEFULL: @@ -144,12 +140,10 @@ FFStrError(unsigned int err) } } - /* * Initializes the haptic subsystem. */ -int -SDL_SYS_HapticInit(void) +int SDL_SYS_HapticInit(void) { IOReturn result; io_iterator_t iter; @@ -163,18 +157,18 @@ SDL_SYS_HapticInit(void) /* Get HID devices. */ match = IOServiceMatching(kIOHIDDeviceKey); - if (match == NULL) { + if (!match) { return SDL_SetError("Haptic: Failed to get IOServiceMatching."); } /* Now search I/O Registry for matching devices. */ - result = IOServiceGetMatchingServices(kIOMasterPortDefault, match, &iter); + result = IOServiceGetMatchingServices(kIOMainPortDefault, match, &iter); if (result != kIOReturnSuccess) { return SDL_SetError("Haptic: Couldn't create a HID object iterator."); } /* IOServiceGetMatchingServices consumes dictionary. */ - if (!IOIteratorIsValid(iter)) { /* No iterator. */ + if (!IOIteratorIsValid(iter)) { /* No iterator. */ return 0; } @@ -188,14 +182,12 @@ SDL_SYS_HapticInit(void) return numhaptics; } -int -SDL_SYS_NumHaptics(void) +int SDL_SYS_NumHaptics(void) { return numhaptics; } -static SDL_hapticlist_item * -HapticByDevIndex(int device_index) +static SDL_hapticlist_item *HapticByDevIndex(int device_index) { SDL_hapticlist_item *item = SDL_hapticlist; @@ -212,8 +204,7 @@ HapticByDevIndex(int device_index) return item; } -int -MacHaptic_MaybeAddDevice( io_object_t device ) +int MacHaptic_MaybeAddDevice(io_object_t device) { IOReturn result; CFMutableDictionaryRef hidProperties; @@ -230,16 +221,15 @@ MacHaptic_MaybeAddDevice( io_object_t device ) } /* Make sure we don't already have it */ - for (item = SDL_hapticlist; item ; item = item->next) - { - if (IOObjectIsEqualTo((io_object_t) item->dev, device)) { + for (item = SDL_hapticlist; item; item = item->next) { + if (IOObjectIsEqualTo((io_object_t)item->dev, device)) { /* Already added */ return -1; } } item = (SDL_hapticlist_item *)SDL_calloc(1, sizeof(SDL_hapticlist_item)); - if (item == NULL) { + if (!item) { return SDL_SetError("Could not allocate haptic storage"); } @@ -275,7 +265,7 @@ MacHaptic_MaybeAddDevice( io_object_t device ) CFRelease(hidProperties); } - if (SDL_hapticlist_tail == NULL) { + if (!SDL_hapticlist_tail) { SDL_hapticlist = SDL_hapticlist_tail = item; } else { SDL_hapticlist_tail->next = item; @@ -288,8 +278,7 @@ MacHaptic_MaybeAddDevice( io_object_t device ) return numhaptics; } -int -MacHaptic_MaybeRemoveDevice( io_object_t device ) +int MacHaptic_MaybeRemoveDevice(io_object_t device) { SDL_hapticlist_item *item; SDL_hapticlist_item *prev = NULL; @@ -298,12 +287,12 @@ MacHaptic_MaybeRemoveDevice( io_object_t device ) return -1; /* not initialized. ignore this. */ } - for (item = SDL_hapticlist; item != NULL; item = item->next) { + for (item = SDL_hapticlist; item; item = item->next) { /* found it, remove it. */ - if (IOObjectIsEqualTo((io_object_t) item->dev, device)) { + if (IOObjectIsEqualTo((io_object_t)item->dev, device)) { const int retval = item->haptic ? item->haptic->index : -1; - if (prev != NULL) { + if (prev) { prev->next = item->next; } else { SDL_assert(SDL_hapticlist == item); @@ -330,8 +319,7 @@ MacHaptic_MaybeRemoveDevice( io_object_t device ) /* * Return the name of a haptic device, does not need to be opened. */ -const char * -SDL_SYS_HapticName(int index) +const char *SDL_SYS_HapticName(int index) { SDL_hapticlist_item *item; item = HapticByDevIndex(index); @@ -341,8 +329,7 @@ SDL_SYS_HapticName(int index) /* * Gets the device's product name. */ -static int -HIDGetDeviceProduct(io_service_t dev, char *name) +static int HIDGetDeviceProduct(io_service_t dev, char *name) { CFMutableDictionaryRef hidProperties, usbProperties; io_registry_entry_t parent1, parent2; @@ -360,20 +347,19 @@ HIDGetDeviceProduct(io_service_t dev, char *name) * get dictionary for USB properties: step up two levels and get CF dictionary for USB properties */ if ((KERN_SUCCESS == - IORegistryEntryGetParentEntry(dev, kIOServicePlane, &parent1)) - && (KERN_SUCCESS == - IORegistryEntryGetParentEntry(parent1, kIOServicePlane, &parent2)) - && (KERN_SUCCESS == - IORegistryEntryCreateCFProperties(parent2, &usbProperties, - kCFAllocatorDefault, - kNilOptions))) { + IORegistryEntryGetParentEntry(dev, kIOServicePlane, &parent1)) && + (KERN_SUCCESS == + IORegistryEntryGetParentEntry(parent1, kIOServicePlane, &parent2)) && + (KERN_SUCCESS == + IORegistryEntryCreateCFProperties(parent2, &usbProperties, + kCFAllocatorDefault, + kNilOptions))) { if (usbProperties) { CFTypeRef refCF = 0; /* get device info * try hid dictionary first, if fail then go to USB dictionary */ - /* Get product name */ refCF = CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDProductKey)); if (!refCF) { @@ -406,14 +392,13 @@ HIDGetDeviceProduct(io_service_t dev, char *name) return 0; } - -#define FF_TEST(ff, s) \ -if (features.supportedEffects & (ff)) supported |= (s) +#define FF_TEST(ff, s) \ + if (features.supportedEffects & (ff)) \ + supported |= (s) /* * Gets supported features. */ -static unsigned int -GetSupportedFeatures(SDL_Haptic * haptic) +static unsigned int GetSupportedFeatures(SDL_Haptic *haptic) { HRESULT ret; FFDeviceObjectReference device; @@ -465,9 +450,8 @@ GetSupportedFeatures(SDL_Haptic * haptic) if (ret == FF_OK) { supported |= SDL_HAPTIC_AUTOCENTER; } else if (ret != FFERR_UNSUPPORTED) { - return SDL_SetError - ("Haptic: Unable to get if device supports autocenter: %s.", - FFStrError(ret)); + return SDL_SetError("Haptic: Unable to get if device supports autocenter: %s.", + FFStrError(ret)); } /* Check for axes, we have an artificial limit on axes */ @@ -483,12 +467,10 @@ GetSupportedFeatures(SDL_Haptic * haptic) return 0; } - /* * Opens the haptic device from the file descriptor. */ -static int -SDL_SYS_HapticOpenFromService(SDL_Haptic * haptic, io_service_t service) +static int SDL_SYS_HapticOpenFromService(SDL_Haptic *haptic, io_service_t service) { HRESULT ret; int ret2; @@ -496,7 +478,7 @@ SDL_SYS_HapticOpenFromService(SDL_Haptic * haptic, io_service_t service) /* Allocate the hwdata */ haptic->hwdata = (struct haptic_hwdata *) SDL_malloc(sizeof(*haptic->hwdata)); - if (haptic->hwdata == NULL) { + if (!haptic->hwdata) { SDL_OutOfMemory(); goto creat_err; } @@ -516,7 +498,6 @@ SDL_SYS_HapticOpenFromService(SDL_Haptic * haptic, io_service_t service) goto open_err; } - /* Reset and then enable actuators. */ ret = FFDeviceSendForceFeedbackCommand(haptic->hwdata->device, FFSFFC_RESET); @@ -532,11 +513,10 @@ SDL_SYS_HapticOpenFromService(SDL_Haptic * haptic, io_service_t service) goto open_err; } - /* Allocate effects memory. */ haptic->effects = (struct haptic_effect *) SDL_malloc(sizeof(struct haptic_effect) * haptic->neffects); - if (haptic->effects == NULL) { + if (!haptic->effects) { SDL_OutOfMemory(); goto open_err; } @@ -547,23 +527,20 @@ SDL_SYS_HapticOpenFromService(SDL_Haptic * haptic, io_service_t service) return 0; /* Error handling */ - open_err: +open_err: FFReleaseDevice(haptic->hwdata->device); - creat_err: - if (haptic->hwdata != NULL) { +creat_err: + if (haptic->hwdata) { SDL_free(haptic->hwdata); haptic->hwdata = NULL; } return -1; - } - /* * Opens a haptic device for usage. */ -int -SDL_SYS_HapticOpen(SDL_Haptic * haptic) +int SDL_SYS_HapticOpen(SDL_Haptic *haptic) { SDL_hapticlist_item *item; item = HapticByDevIndex(haptic->index); @@ -571,12 +548,10 @@ SDL_SYS_HapticOpen(SDL_Haptic * haptic) return SDL_SYS_HapticOpenFromService(haptic, item->dev); } - /* * Opens a haptic device from first mouse it finds for usage. */ -int -SDL_SYS_HapticMouse(void) +int SDL_SYS_HapticMouse(void) { int device_index = 0; SDL_hapticlist_item *item; @@ -592,70 +567,70 @@ SDL_SYS_HapticMouse(void) return -1; } - /* * Checks to see if a joystick has haptic features. */ -int -SDL_SYS_JoystickIsHaptic(SDL_Joystick * joystick) +int SDL_SYS_JoystickIsHaptic(SDL_Joystick *joystick) { +#ifdef SDL_JOYSTICK_IOKIT if (joystick->driver != &SDL_DARWIN_JoystickDriver) { return SDL_FALSE; } if (joystick->hwdata->ffservice != 0) { return SDL_TRUE; } +#endif return SDL_FALSE; } - /* * Checks to see if the haptic device and joystick are in reality the same. */ -int -SDL_SYS_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick) +int SDL_SYS_JoystickSameHaptic(SDL_Haptic *haptic, SDL_Joystick *joystick) { +#ifdef SDL_JOYSTICK_IOKIT if (joystick->driver != &SDL_DARWIN_JoystickDriver) { return 0; } - if (IOObjectIsEqualTo((io_object_t) ((size_t)haptic->hwdata->device), + if (IOObjectIsEqualTo((io_object_t)((size_t)haptic->hwdata->device), joystick->hwdata->ffservice)) { return 1; } +#endif return 0; } - /* * Opens a SDL_Haptic from a SDL_Joystick. */ -int -SDL_SYS_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick) +int SDL_SYS_HapticOpenFromJoystick(SDL_Haptic *haptic, SDL_Joystick *joystick) { +#ifdef SDL_JOYSTICK_IOKIT int device_index = 0; SDL_hapticlist_item *item; - + if (joystick->driver != &SDL_DARWIN_JoystickDriver) { return -1; } for (item = SDL_hapticlist; item; item = item->next) { - if (IOObjectIsEqualTo((io_object_t) item->dev, - joystick->hwdata->ffservice)) { - haptic->index = device_index; - break; + if (IOObjectIsEqualTo((io_object_t)item->dev, + joystick->hwdata->ffservice)) { + haptic->index = device_index; + break; } ++device_index; } return SDL_SYS_HapticOpenFromService(haptic, joystick->hwdata->ffservice); +#else + return -1; +#endif } - /* * Closes the haptic device. */ -void -SDL_SYS_HapticClose(SDL_Haptic * haptic) +void SDL_SYS_HapticClose(SDL_Haptic *haptic) { if (haptic->hwdata) { @@ -673,12 +648,10 @@ SDL_SYS_HapticClose(SDL_Haptic * haptic) } } - /* * Clean up after system specific haptic stuff */ -void -SDL_SYS_HapticQuit(void) +void SDL_SYS_HapticQuit(void) { SDL_hapticlist_item *item; SDL_hapticlist_item *next = NULL; @@ -698,12 +671,10 @@ SDL_SYS_HapticQuit(void) SDL_hapticlist_tail = NULL; } - /* * Converts an SDL trigger button to an FFEFFECT trigger button. */ -static DWORD -FFGetTriggerButton(Uint16 button) +static DWORD FFGetTriggerButton(Uint16 button) { DWORD dwTriggerButton; @@ -716,25 +687,23 @@ FFGetTriggerButton(Uint16 button) return dwTriggerButton; } - /* * Sets the direction. */ -static int -SDL_SYS_SetDirection(FFEFFECT * effect, SDL_HapticDirection * dir, int naxes) +static int SDL_SYS_SetDirection(FFEFFECT *effect, SDL_HapticDirection *dir, int naxes) { LONG *rglDir; /* Handle no axes a part. */ if (naxes == 0) { - effect->dwFlags |= FFEFF_SPHERICAL; /* Set as default. */ + effect->dwFlags |= FFEFF_SPHERICAL; /* Set as default. */ effect->rglDirection = NULL; return 0; } /* Has axes. */ rglDir = SDL_malloc(sizeof(LONG) * naxes); - if (rglDir == NULL) { + if (!rglDir) { return SDL_OutOfMemory(); } SDL_memset(rglDir, 0, sizeof(LONG) * naxes); @@ -765,27 +734,29 @@ SDL_SYS_SetDirection(FFEFFECT * effect, SDL_HapticDirection * dir, int naxes) rglDir[2] = dir->dir[2]; } return 0; + case SDL_HAPTIC_STEERING_AXIS: + effect->dwFlags |= FFEFF_CARTESIAN; + rglDir[0] = 0; + return 0; default: return SDL_SetError("Haptic: Unknown direction type."); } } - /* Clamps and converts. */ -#define CCONVERT(x) (((x) > 0x7FFF) ? 10000 : ((x)*10000) / 0x7FFF) +#define CCONVERT(x) (((x) > 0x7FFF) ? 10000 : ((x)*10000) / 0x7FFF) /* Just converts. */ -#define CONVERT(x) (((x)*10000) / 0x7FFF) +#define CONVERT(x) (((x)*10000) / 0x7FFF) /* * Creates the FFEFFECT from a SDL_HapticEffect. */ -static int -SDL_SYS_ToFFEFFECT(SDL_Haptic * haptic, FFEFFECT * dest, SDL_HapticEffect * src) +static int SDL_SYS_ToFFEFFECT(SDL_Haptic *haptic, FFEFFECT *dest, SDL_HapticEffect *src) { int i; FFCONSTANTFORCE *constant = NULL; FFPERIODIC *periodic = NULL; - FFCONDITION *condition = NULL; /* Actually an array of conditions - one per axis. */ + FFCONDITION *condition = NULL; /* Actually an array of conditions - one per axis. */ FFRAMPFORCE *ramp = NULL; FFCUSTOMFORCE *custom = NULL; FFENVELOPE *envelope = NULL; @@ -798,28 +769,32 @@ SDL_SYS_ToFFEFFECT(SDL_Haptic * haptic, FFEFFECT * dest, SDL_HapticEffect * src) /* Set global stuff. */ SDL_memset(dest, 0, sizeof(FFEFFECT)); - dest->dwSize = sizeof(FFEFFECT); /* Set the structure size. */ - dest->dwSamplePeriod = 0; /* Not used by us. */ - dest->dwGain = 10000; /* Gain is set globally, not locally. */ - dest->dwFlags = FFEFF_OBJECTOFFSETS; /* Seems obligatory. */ + dest->dwSize = sizeof(FFEFFECT); /* Set the structure size. */ + dest->dwSamplePeriod = 0; /* Not used by us. */ + dest->dwGain = 10000; /* Gain is set globally, not locally. */ + dest->dwFlags = FFEFF_OBJECTOFFSETS; /* Seems obligatory. */ /* Envelope. */ envelope = SDL_malloc(sizeof(FFENVELOPE)); - if (envelope == NULL) { + if (!envelope) { return SDL_OutOfMemory(); } SDL_memset(envelope, 0, sizeof(FFENVELOPE)); dest->lpEnvelope = envelope; - envelope->dwSize = sizeof(FFENVELOPE); /* Always should be this. */ + envelope->dwSize = sizeof(FFENVELOPE); /* Always should be this. */ /* Axes. */ - dest->cAxes = haptic->naxes; + if (src->constant.direction.type == SDL_HAPTIC_STEERING_AXIS) { + dest->cAxes = 1; + } else { + dest->cAxes = haptic->naxes; + } if (dest->cAxes > 0) { axes = SDL_malloc(sizeof(DWORD) * dest->cAxes); - if (axes == NULL) { + if (!axes) { return SDL_OutOfMemory(); } - axes[0] = haptic->hwdata->axes[0]; /* Always at least one axis. */ + axes[0] = haptic->hwdata->axes[0]; /* Always at least one axis. */ if (dest->cAxes > 1) { axes[1] = haptic->hwdata->axes[1]; } @@ -829,13 +804,12 @@ SDL_SYS_ToFFEFFECT(SDL_Haptic * haptic, FFEFFECT * dest, SDL_HapticEffect * src) dest->rgdwAxes = axes; } - /* The big type handling switch, even bigger then Linux's version. */ switch (src->type) { case SDL_HAPTIC_CONSTANT: hap_constant = &src->constant; constant = SDL_malloc(sizeof(FFCONSTANTFORCE)); - if (constant == NULL) { + if (!constant) { return SDL_OutOfMemory(); } SDL_memset(constant, 0, sizeof(FFCONSTANTFORCE)); @@ -849,17 +823,15 @@ SDL_SYS_ToFFEFFECT(SDL_Haptic * haptic, FFEFFECT * dest, SDL_HapticEffect * src) dest->dwDuration = hap_constant->length * 1000; /* In microseconds. */ dest->dwTriggerButton = FFGetTriggerButton(hap_constant->button); dest->dwTriggerRepeatInterval = hap_constant->interval; - dest->dwStartDelay = hap_constant->delay * 1000; /* In microseconds. */ + dest->dwStartDelay = hap_constant->delay * 1000; /* In microseconds. */ /* Direction. */ - if (SDL_SYS_SetDirection(dest, &hap_constant->direction, dest->cAxes) - < 0) { + if (SDL_SYS_SetDirection(dest, &hap_constant->direction, dest->cAxes) < 0) { return -1; } /* Envelope */ - if ((hap_constant->attack_length == 0) - && (hap_constant->fade_length == 0)) { + if ((hap_constant->attack_length == 0) && (hap_constant->fade_length == 0)) { SDL_free(envelope); dest->lpEnvelope = NULL; } else { @@ -879,7 +851,7 @@ SDL_SYS_ToFFEFFECT(SDL_Haptic * haptic, FFEFFECT * dest, SDL_HapticEffect * src) case SDL_HAPTIC_SAWTOOTHDOWN: hap_periodic = &src->periodic; periodic = SDL_malloc(sizeof(FFPERIODIC)); - if (periodic == NULL) { + if (!periodic) { return SDL_OutOfMemory(); } SDL_memset(periodic, 0, sizeof(FFPERIODIC)); @@ -887,8 +859,8 @@ SDL_SYS_ToFFEFFECT(SDL_Haptic * haptic, FFEFFECT * dest, SDL_HapticEffect * src) /* Specifics */ periodic->dwMagnitude = CONVERT(SDL_abs(hap_periodic->magnitude)); periodic->lOffset = CONVERT(hap_periodic->offset); - periodic->dwPhase = - (hap_periodic->phase + (hap_periodic->magnitude < 0 ? 18000 : 0)) % 36000; + periodic->dwPhase = + (hap_periodic->phase + (hap_periodic->magnitude < 0 ? 18000 : 0)) % 36000; periodic->dwPeriod = hap_periodic->period * 1000; dest->cbTypeSpecificParams = sizeof(FFPERIODIC); dest->lpvTypeSpecificParams = periodic; @@ -897,17 +869,15 @@ SDL_SYS_ToFFEFFECT(SDL_Haptic * haptic, FFEFFECT * dest, SDL_HapticEffect * src) dest->dwDuration = hap_periodic->length * 1000; /* In microseconds. */ dest->dwTriggerButton = FFGetTriggerButton(hap_periodic->button); dest->dwTriggerRepeatInterval = hap_periodic->interval; - dest->dwStartDelay = hap_periodic->delay * 1000; /* In microseconds. */ + dest->dwStartDelay = hap_periodic->delay * 1000; /* In microseconds. */ /* Direction. */ - if (SDL_SYS_SetDirection(dest, &hap_periodic->direction, dest->cAxes) - < 0) { + if (SDL_SYS_SetDirection(dest, &hap_periodic->direction, dest->cAxes) < 0) { return -1; } /* Envelope */ - if ((hap_periodic->attack_length == 0) - && (hap_periodic->fade_length == 0)) { + if ((hap_periodic->attack_length == 0) && (hap_periodic->fade_length == 0)) { SDL_free(envelope); dest->lpEnvelope = NULL; } else { @@ -926,7 +896,7 @@ SDL_SYS_ToFFEFFECT(SDL_Haptic * haptic, FFEFFECT * dest, SDL_HapticEffect * src) hap_condition = &src->condition; if (dest->cAxes > 0) { condition = SDL_malloc(sizeof(FFCONDITION) * dest->cAxes); - if (condition == NULL) { + if (!condition) { return SDL_OutOfMemory(); } SDL_memset(condition, 0, sizeof(FFCONDITION)); @@ -950,14 +920,13 @@ SDL_SYS_ToFFEFFECT(SDL_Haptic * haptic, FFEFFECT * dest, SDL_HapticEffect * src) dest->lpvTypeSpecificParams = condition; /* Generics */ - dest->dwDuration = hap_condition->length * 1000; /* In microseconds. */ + dest->dwDuration = hap_condition->length * 1000; /* In microseconds. */ dest->dwTriggerButton = FFGetTriggerButton(hap_condition->button); dest->dwTriggerRepeatInterval = hap_condition->interval; - dest->dwStartDelay = hap_condition->delay * 1000; /* In microseconds. */ + dest->dwStartDelay = hap_condition->delay * 1000; /* In microseconds. */ /* Direction. */ - if (SDL_SYS_SetDirection(dest, &hap_condition->direction, dest->cAxes) - < 0) { + if (SDL_SYS_SetDirection(dest, &hap_condition->direction, dest->cAxes) < 0) { return -1; } @@ -970,7 +939,7 @@ SDL_SYS_ToFFEFFECT(SDL_Haptic * haptic, FFEFFECT * dest, SDL_HapticEffect * src) case SDL_HAPTIC_RAMP: hap_ramp = &src->ramp; ramp = SDL_malloc(sizeof(FFRAMPFORCE)); - if (ramp == NULL) { + if (!ramp) { return SDL_OutOfMemory(); } SDL_memset(ramp, 0, sizeof(FFRAMPFORCE)); @@ -982,10 +951,10 @@ SDL_SYS_ToFFEFFECT(SDL_Haptic * haptic, FFEFFECT * dest, SDL_HapticEffect * src) dest->lpvTypeSpecificParams = ramp; /* Generics */ - dest->dwDuration = hap_ramp->length * 1000; /* In microseconds. */ + dest->dwDuration = hap_ramp->length * 1000; /* In microseconds. */ dest->dwTriggerButton = FFGetTriggerButton(hap_ramp->button); dest->dwTriggerRepeatInterval = hap_ramp->interval; - dest->dwStartDelay = hap_ramp->delay * 1000; /* In microseconds. */ + dest->dwStartDelay = hap_ramp->delay * 1000; /* In microseconds. */ /* Direction. */ if (SDL_SYS_SetDirection(dest, &hap_ramp->direction, dest->cAxes) < 0) { @@ -1008,7 +977,7 @@ SDL_SYS_ToFFEFFECT(SDL_Haptic * haptic, FFEFFECT * dest, SDL_HapticEffect * src) case SDL_HAPTIC_CUSTOM: hap_custom = &src->custom; custom = SDL_malloc(sizeof(FFCUSTOMFORCE)); - if (custom == NULL) { + if (!custom) { return SDL_OutOfMemory(); } SDL_memset(custom, 0, sizeof(FFCUSTOMFORCE)); @@ -1019,17 +988,17 @@ SDL_SYS_ToFFEFFECT(SDL_Haptic * haptic, FFEFFECT * dest, SDL_HapticEffect * src) custom->cSamples = hap_custom->samples; custom->rglForceData = SDL_malloc(sizeof(LONG) * custom->cSamples * custom->cChannels); - for (i = 0; i < hap_custom->samples * hap_custom->channels; i++) { /* Copy data. */ + for (i = 0; i < hap_custom->samples * hap_custom->channels; i++) { /* Copy data. */ custom->rglForceData[i] = CCONVERT(hap_custom->data[i]); } dest->cbTypeSpecificParams = sizeof(FFCUSTOMFORCE); dest->lpvTypeSpecificParams = custom; /* Generics */ - dest->dwDuration = hap_custom->length * 1000; /* In microseconds. */ + dest->dwDuration = hap_custom->length * 1000; /* In microseconds. */ dest->dwTriggerButton = FFGetTriggerButton(hap_custom->button); dest->dwTriggerRepeatInterval = hap_custom->interval; - dest->dwStartDelay = hap_custom->delay * 1000; /* In microseconds. */ + dest->dwStartDelay = hap_custom->delay * 1000; /* In microseconds. */ /* Direction. */ if (SDL_SYS_SetDirection(dest, &hap_custom->direction, dest->cAxes) < @@ -1038,8 +1007,7 @@ SDL_SYS_ToFFEFFECT(SDL_Haptic * haptic, FFEFFECT * dest, SDL_HapticEffect * src) } /* Envelope */ - if ((hap_custom->attack_length == 0) - && (hap_custom->fade_length == 0)) { + if ((hap_custom->attack_length == 0) && (hap_custom->fade_length == 0)) { SDL_free(envelope); dest->lpEnvelope = NULL; } else { @@ -1051,7 +1019,6 @@ SDL_SYS_ToFFEFFECT(SDL_Haptic * haptic, FFEFFECT * dest, SDL_HapticEffect * src) break; - default: return SDL_SetError("Haptic: Unknown effect type."); } @@ -1059,12 +1026,10 @@ SDL_SYS_ToFFEFFECT(SDL_Haptic * haptic, FFEFFECT * dest, SDL_HapticEffect * src) return 0; } - /* * Frees an FFEFFECT allocated by SDL_SYS_ToFFEFFECT. */ -static void -SDL_SYS_HapticFreeFFEFFECT(FFEFFECT * effect, int type) +static void SDL_SYS_HapticFreeFFEFFECT(FFEFFECT *effect, int type) { FFCUSTOMFORCE *custom; @@ -1072,9 +1037,9 @@ SDL_SYS_HapticFreeFFEFFECT(FFEFFECT * effect, int type) effect->lpEnvelope = NULL; SDL_free(effect->rgdwAxes); effect->rgdwAxes = NULL; - if (effect->lpvTypeSpecificParams != NULL) { - if (type == SDL_HAPTIC_CUSTOM) { /* Must free the custom data. */ - custom = (FFCUSTOMFORCE *) effect->lpvTypeSpecificParams; + if (effect->lpvTypeSpecificParams) { + if (type == SDL_HAPTIC_CUSTOM) { /* Must free the custom data. */ + custom = (FFCUSTOMFORCE *)effect->lpvTypeSpecificParams; SDL_free(custom->rglForceData); custom->rglForceData = NULL; } @@ -1085,7 +1050,6 @@ SDL_SYS_HapticFreeFFEFFECT(FFEFFECT * effect, int type) effect->rglDirection = NULL; } - /* * Gets the effect type from the generic SDL haptic effect wrapper. */ @@ -1099,9 +1063,9 @@ SDL_SYS_HapticEffectType(Uint16 type) case SDL_HAPTIC_RAMP: return kFFEffectType_RampForce_ID; - /* !!! FIXME: put this back when we have more bits in 2.1 */ - /* case SDL_HAPTIC_SQUARE: - return kFFEffectType_Square_ID; */ + /* !!! FIXME: put this back when we have more bits in 2.1 */ + /* case SDL_HAPTIC_SQUARE: + return kFFEffectType_Square_ID; */ case SDL_HAPTIC_SINE: return kFFEffectType_Sine_ID; @@ -1136,13 +1100,11 @@ SDL_SYS_HapticEffectType(Uint16 type) } } - /* * Creates a new haptic effect. */ -int -SDL_SYS_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect *effect, - SDL_HapticEffect * base) +int SDL_SYS_HapticNewEffect(SDL_Haptic *haptic, struct haptic_effect *effect, + SDL_HapticEffect *base) { HRESULT ret; CFUUIDRef type; @@ -1150,14 +1112,14 @@ SDL_SYS_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect *effect, /* Alloc the effect. */ effect->hweffect = (struct haptic_hweffect *) SDL_malloc(sizeof(struct haptic_hweffect)); - if (effect->hweffect == NULL) { + if (!effect->hweffect) { SDL_OutOfMemory(); goto err_hweffect; } /* Get the type. */ type = SDL_SYS_HapticEffectType(base->type); - if (type == NULL) { + if (!type) { goto err_hweffect; } @@ -1177,22 +1139,20 @@ SDL_SYS_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect *effect, return 0; - err_effectdone: +err_effectdone: SDL_SYS_HapticFreeFFEFFECT(&effect->hweffect->effect, base->type); - err_hweffect: +err_hweffect: SDL_free(effect->hweffect); effect->hweffect = NULL; return -1; } - /* * Updates an effect. */ -int -SDL_SYS_HapticUpdateEffect(SDL_Haptic * haptic, - struct haptic_effect *effect, - SDL_HapticEffect * data) +int SDL_SYS_HapticUpdateEffect(SDL_Haptic *haptic, + struct haptic_effect *effect, + SDL_HapticEffect *data) { HRESULT ret; FFEffectParameterFlag flags; @@ -1207,11 +1167,11 @@ SDL_SYS_HapticUpdateEffect(SDL_Haptic * haptic, /* Set the flags. Might be worthwhile to diff temp with loaded effect and * only change those parameters. */ flags = FFEP_DIRECTION | - FFEP_DURATION | - FFEP_ENVELOPE | - FFEP_STARTDELAY | - FFEP_TRIGGERBUTTON | - FFEP_TRIGGERREPEATINTERVAL | FFEP_TYPESPECIFICPARAMS; + FFEP_DURATION | + FFEP_ENVELOPE | + FFEP_STARTDELAY | + FFEP_TRIGGERBUTTON | + FFEP_TRIGGERREPEATINTERVAL | FFEP_TYPESPECIFICPARAMS; /* Create the actual effect. */ ret = FFEffectSetParameters(effect->hweffect->ref, &temp, flags); @@ -1226,18 +1186,16 @@ SDL_SYS_HapticUpdateEffect(SDL_Haptic * haptic, return 0; - err_update: +err_update: SDL_SYS_HapticFreeFFEFFECT(&temp, data->type); return -1; } - /* * Runs an effect. */ -int -SDL_SYS_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect, - Uint32 iterations) +int SDL_SYS_HapticRunEffect(SDL_Haptic *haptic, struct haptic_effect *effect, + Uint32 iterations) { HRESULT ret; Uint32 iter; @@ -1245,8 +1203,9 @@ SDL_SYS_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect, /* Check if it's infinite. */ if (iterations == SDL_HAPTIC_INFINITY) { iter = FF_INFINITE; - } else + } else { iter = iterations; + } /* Run the effect. */ ret = FFEffectStart(effect->hweffect->ref, iter, 0); @@ -1258,12 +1217,10 @@ SDL_SYS_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect, return 0; } - /* * Stops an effect. */ -int -SDL_SYS_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect *effect) +int SDL_SYS_HapticStopEffect(SDL_Haptic *haptic, struct haptic_effect *effect) { HRESULT ret; @@ -1276,12 +1233,10 @@ SDL_SYS_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect *effect) return 0; } - /* * Frees the effect. */ -void -SDL_SYS_HapticDestroyEffect(SDL_Haptic * haptic, struct haptic_effect *effect) +void SDL_SYS_HapticDestroyEffect(SDL_Haptic *haptic, struct haptic_effect *effect) { HRESULT ret; @@ -1296,13 +1251,11 @@ SDL_SYS_HapticDestroyEffect(SDL_Haptic * haptic, struct haptic_effect *effect) effect->hweffect = NULL; } - /* * Gets the status of a haptic effect. */ -int -SDL_SYS_HapticGetEffectStatus(SDL_Haptic * haptic, - struct haptic_effect *effect) +int SDL_SYS_HapticGetEffectStatus(SDL_Haptic *haptic, + struct haptic_effect *effect) { HRESULT ret; FFEffectStatusFlag status; @@ -1317,15 +1270,13 @@ SDL_SYS_HapticGetEffectStatus(SDL_Haptic * haptic, if (status == 0) { return SDL_FALSE; } - return SDL_TRUE; /* Assume it's playing or emulated. */ + return SDL_TRUE; /* Assume it's playing or emulated. */ } - /* * Sets the gain. */ -int -SDL_SYS_HapticSetGain(SDL_Haptic * haptic, int gain) +int SDL_SYS_HapticSetGain(SDL_Haptic *haptic, int gain) { HRESULT ret; Uint32 val; @@ -1340,12 +1291,10 @@ SDL_SYS_HapticSetGain(SDL_Haptic * haptic, int gain) return 0; } - /* * Sets the autocentering. */ -int -SDL_SYS_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter) +int SDL_SYS_HapticSetAutocenter(SDL_Haptic *haptic, int autocenter) { HRESULT ret; Uint32 val; @@ -1367,12 +1316,10 @@ SDL_SYS_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter) return 0; } - /* * Pauses the device. */ -int -SDL_SYS_HapticPause(SDL_Haptic * haptic) +int SDL_SYS_HapticPause(SDL_Haptic *haptic) { HRESULT ret; @@ -1385,12 +1332,10 @@ SDL_SYS_HapticPause(SDL_Haptic * haptic) return 0; } - /* * Unpauses the device. */ -int -SDL_SYS_HapticUnpause(SDL_Haptic * haptic) +int SDL_SYS_HapticUnpause(SDL_Haptic *haptic) { HRESULT ret; @@ -1403,12 +1348,10 @@ SDL_SYS_HapticUnpause(SDL_Haptic * haptic) return 0; } - /* * Stops all currently playing effects. */ -int -SDL_SYS_HapticStopAll(SDL_Haptic * haptic) +int SDL_SYS_HapticStopAll(SDL_Haptic *haptic) { HRESULT ret; diff --git a/SDL2-2.30.5/src/haptic/darwin/SDL_syshaptic_c.h b/SDL2-2.30.5/src/haptic/darwin/SDL_syshaptic_c.h new file mode 100644 index 0000000..49b54bb --- /dev/null +++ b/SDL2-2.30.5/src/haptic/darwin/SDL_syshaptic_c.h @@ -0,0 +1,31 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +/* Things named "Master" were renamed to "Main" in macOS 12.0's SDK. */ +#include +#if MAC_OS_X_VERSION_MIN_REQUIRED < 120000 +#define kIOMainPortDefault kIOMasterPortDefault +#endif + +extern int MacHaptic_MaybeAddDevice(io_object_t device); +extern int MacHaptic_MaybeRemoveDevice(io_object_t device); + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/haptic/dummy/SDL_syshaptic.c b/SDL2-2.30.5/src/haptic/dummy/SDL_syshaptic.c similarity index 55% rename from SDL2-2.0.12/src/haptic/dummy/SDL_syshaptic.c rename to SDL2-2.30.5/src/haptic/dummy/SDL_syshaptic.c index c9f983c..861aa6e 100644 --- a/SDL2-2.0.12/src/haptic/dummy/SDL_syshaptic.c +++ b/SDL2-2.30.5/src/haptic/dummy/SDL_syshaptic.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -25,158 +25,119 @@ #include "SDL_haptic.h" #include "../SDL_syshaptic.h" - -static int -SDL_SYS_LogicError(void) +static int SDL_SYS_LogicError(void) { return SDL_SetError("Logic error: No haptic devices available."); } - -int -SDL_SYS_HapticInit(void) +int SDL_SYS_HapticInit(void) { return 0; } -int -SDL_SYS_NumHaptics(void) +int SDL_SYS_NumHaptics(void) { return 0; } -const char * -SDL_SYS_HapticName(int index) +const char *SDL_SYS_HapticName(int index) { SDL_SYS_LogicError(); return NULL; } - -int -SDL_SYS_HapticOpen(SDL_Haptic * haptic) +int SDL_SYS_HapticOpen(SDL_Haptic *haptic) { return SDL_SYS_LogicError(); } - -int -SDL_SYS_HapticMouse(void) +int SDL_SYS_HapticMouse(void) { return -1; } - -int -SDL_SYS_JoystickIsHaptic(SDL_Joystick * joystick) +int SDL_SYS_JoystickIsHaptic(SDL_Joystick *joystick) { return 0; } - -int -SDL_SYS_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick) +int SDL_SYS_HapticOpenFromJoystick(SDL_Haptic *haptic, SDL_Joystick *joystick) { return SDL_SYS_LogicError(); } - -int -SDL_SYS_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick) +int SDL_SYS_JoystickSameHaptic(SDL_Haptic *haptic, SDL_Joystick *joystick) { return 0; } - -void -SDL_SYS_HapticClose(SDL_Haptic * haptic) +void SDL_SYS_HapticClose(SDL_Haptic *haptic) { return; } - -void -SDL_SYS_HapticQuit(void) +void SDL_SYS_HapticQuit(void) { return; } - -int -SDL_SYS_HapticNewEffect(SDL_Haptic * haptic, - struct haptic_effect *effect, SDL_HapticEffect * base) +int SDL_SYS_HapticNewEffect(SDL_Haptic *haptic, + struct haptic_effect *effect, SDL_HapticEffect *base) { return SDL_SYS_LogicError(); } - -int -SDL_SYS_HapticUpdateEffect(SDL_Haptic * haptic, - struct haptic_effect *effect, - SDL_HapticEffect * data) +int SDL_SYS_HapticUpdateEffect(SDL_Haptic *haptic, + struct haptic_effect *effect, + SDL_HapticEffect *data) { return SDL_SYS_LogicError(); } - -int -SDL_SYS_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect, - Uint32 iterations) +int SDL_SYS_HapticRunEffect(SDL_Haptic *haptic, struct haptic_effect *effect, + Uint32 iterations) { return SDL_SYS_LogicError(); } - -int -SDL_SYS_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect *effect) +int SDL_SYS_HapticStopEffect(SDL_Haptic *haptic, struct haptic_effect *effect) { return SDL_SYS_LogicError(); } - -void -SDL_SYS_HapticDestroyEffect(SDL_Haptic * haptic, struct haptic_effect *effect) +void SDL_SYS_HapticDestroyEffect(SDL_Haptic *haptic, struct haptic_effect *effect) { SDL_SYS_LogicError(); return; } - -int -SDL_SYS_HapticGetEffectStatus(SDL_Haptic * haptic, - struct haptic_effect *effect) +int SDL_SYS_HapticGetEffectStatus(SDL_Haptic *haptic, + struct haptic_effect *effect) { return SDL_SYS_LogicError(); } - -int -SDL_SYS_HapticSetGain(SDL_Haptic * haptic, int gain) +int SDL_SYS_HapticSetGain(SDL_Haptic *haptic, int gain) { return SDL_SYS_LogicError(); } - -int -SDL_SYS_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter) +int SDL_SYS_HapticSetAutocenter(SDL_Haptic *haptic, int autocenter) { return SDL_SYS_LogicError(); } -int -SDL_SYS_HapticPause(SDL_Haptic * haptic) +int SDL_SYS_HapticPause(SDL_Haptic *haptic) { return SDL_SYS_LogicError(); } -int -SDL_SYS_HapticUnpause(SDL_Haptic * haptic) +int SDL_SYS_HapticUnpause(SDL_Haptic *haptic) { return SDL_SYS_LogicError(); } -int -SDL_SYS_HapticStopAll(SDL_Haptic * haptic) +int SDL_SYS_HapticStopAll(SDL_Haptic *haptic) { return SDL_SYS_LogicError(); } diff --git a/SDL2-2.0.12/src/haptic/linux/SDL_syshaptic.c b/SDL2-2.30.5/src/haptic/linux/SDL_syshaptic.c similarity index 75% rename from SDL2-2.0.12/src/haptic/linux/SDL_syshaptic.c rename to SDL2-2.30.5/src/haptic/linux/SDL_syshaptic.c index c18b7a0..a21c118 100644 --- a/SDL2-2.0.12/src/haptic/linux/SDL_syshaptic.c +++ b/SDL2-2.30.5/src/haptic/linux/SDL_syshaptic.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -22,21 +22,20 @@ #ifdef SDL_HAPTIC_LINUX -#include "SDL_assert.h" #include "SDL_haptic.h" #include "../SDL_syshaptic.h" #include "SDL_joystick.h" #include "../../joystick/SDL_sysjoystick.h" /* For the real SDL_Joystick */ #include "../../joystick/linux/SDL_sysjoystick_c.h" /* For joystick hwdata */ +#include "../../core/linux/SDL_evdev_capabilities.h" #include "../../core/linux/SDL_udev.h" -#include /* close */ -#include /* Force feedback linux stuff. */ -#include /* O_RDWR */ -#include /* INT_MAX */ -#include /* errno, strerror */ -#include /* atan2 */ -#include /* stat */ +#include /* close */ +#include /* Force feedback linux stuff. */ +#include /* O_RDWR */ +#include /* INT_MAX */ +#include /* errno, strerror */ +#include /* stat */ /* Just in case. */ #ifndef M_PI @@ -47,7 +46,7 @@ #define MAX_HAPTICS 32 /* It's doubtful someone has more then 32 evdev */ static int MaybeAddDevice(const char *path); -#if SDL_USE_LIBUDEV +#ifdef SDL_USE_LIBUDEV static int MaybeRemoveDevice(const char *path); static void haptic_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_class, const char *devpath); #endif /* SDL_USE_LIBUDEV */ @@ -57,45 +56,42 @@ static void haptic_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_class, */ typedef struct SDL_hapticlist_item { - char *fname; /* Dev path name (like /dev/input/event1) */ - SDL_Haptic *haptic; /* Associated haptic. */ + char *fname; /* Dev path name (like /dev/input/event1) */ + SDL_Haptic *haptic; /* Associated haptic. */ dev_t dev_num; struct SDL_hapticlist_item *next; } SDL_hapticlist_item; - /* * Haptic system hardware data. */ struct haptic_hwdata { - int fd; /* File descriptor of the device. */ - char *fname; /* Points to the name in SDL_hapticlist. */ + int fd; /* File descriptor of the device. */ + char *fname; /* Points to the name in SDL_hapticlist. */ }; - /* * Haptic system effect data. */ struct haptic_hweffect { - struct ff_effect effect; /* The linux kernel effect structure. */ + struct ff_effect effect; /* The linux kernel effect structure. */ }; static SDL_hapticlist_item *SDL_hapticlist = NULL; static SDL_hapticlist_item *SDL_hapticlist_tail = NULL; static int numhaptics = 0; -#define test_bit(nr, addr) \ - (((1UL << ((nr) & 31)) & (((const unsigned int *) addr)[(nr) >> 5])) != 0) -#define EV_TEST(ev,f) \ - if (test_bit((ev), features)) ret |= (f); +#define EV_TEST(ev, f) \ + if (test_bit((ev), features)) { \ + ret |= (f); \ + } /* * Test whether a device has haptic properties. * Returns available properties or 0 if there are none. */ -static int -EV_IsHaptic(int fd) +static int EV_IsHaptic(int fd) { unsigned int ret; unsigned long features[1 + FF_MAX / sizeof(unsigned long)]; @@ -129,12 +125,10 @@ EV_IsHaptic(int fd) return ret; } - /* * Tests whether a device is a mouse or not. */ -static int -EV_IsMouse(int fd) +static int EV_IsMouse(int fd) { unsigned long argp[40]; @@ -154,8 +148,7 @@ EV_IsMouse(int fd) /* * Initializes the haptic subsystem by finding available devices. */ -int -SDL_SYS_HapticInit(void) +int SDL_SYS_HapticInit(void) { const char joydev_pattern[] = "/dev/input/event%d"; char path[PATH_MAX]; @@ -167,17 +160,16 @@ SDL_SYS_HapticInit(void) */ i = 0; for (j = 0; j < MAX_HAPTICS; ++j) { - - snprintf(path, PATH_MAX, joydev_pattern, i++); + (void)SDL_snprintf(path, PATH_MAX, joydev_pattern, i++); MaybeAddDevice(path); } -#if SDL_USE_LIBUDEV +#ifdef SDL_USE_LIBUDEV if (SDL_UDEV_Init() < 0) { return SDL_SetError("Could not initialize UDEV"); } - if ( SDL_UDEV_AddCallback(haptic_udev_callback) < 0) { + if (SDL_UDEV_AddCallback(haptic_udev_callback) < 0) { SDL_UDEV_Quit(); return SDL_SetError("Could not setup haptic <-> udev callback"); } @@ -189,14 +181,12 @@ SDL_SYS_HapticInit(void) return numhaptics; } -int -SDL_SYS_NumHaptics(void) +int SDL_SYS_NumHaptics(void) { return numhaptics; } -static SDL_hapticlist_item * -HapticByDevIndex(int device_index) +static SDL_hapticlist_item *HapticByDevIndex(int device_index) { SDL_hapticlist_item *item = SDL_hapticlist; @@ -213,39 +203,36 @@ HapticByDevIndex(int device_index) return item; } -#if SDL_USE_LIBUDEV +#ifdef SDL_USE_LIBUDEV static void haptic_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_class, const char *devpath) { - if (devpath == NULL || !(udev_class & SDL_UDEV_DEVICE_JOYSTICK)) { + if (!devpath || !(udev_class & SDL_UDEV_DEVICE_JOYSTICK)) { return; } - switch( udev_type ) - { - case SDL_UDEV_DEVICEADDED: - MaybeAddDevice(devpath); - break; + switch (udev_type) { + case SDL_UDEV_DEVICEADDED: + MaybeAddDevice(devpath); + break; - case SDL_UDEV_DEVICEREMOVED: - MaybeRemoveDevice(devpath); - break; + case SDL_UDEV_DEVICEREMOVED: + MaybeRemoveDevice(devpath); + break; - default: - break; + default: + break; } - } #endif /* SDL_USE_LIBUDEV */ -static int -MaybeAddDevice(const char *path) +static int MaybeAddDevice(const char *path) { struct stat sb; int fd; int success; SDL_hapticlist_item *item; - if (path == NULL) { + if (!path) { return -1; } @@ -255,14 +242,14 @@ MaybeAddDevice(const char *path) } /* check for duplicates */ - for (item = SDL_hapticlist; item != NULL; item = item->next) { + for (item = SDL_hapticlist; item; item = item->next) { if (item->dev_num == sb.st_rdev) { - return -1; /* duplicate. */ + return -1; /* duplicate. */ } } /* try to open */ - fd = open(path, O_RDWR, 0); + fd = open(path, O_RDWR | O_CLOEXEC, 0); if (fd < 0) { return -1; } @@ -278,13 +265,13 @@ MaybeAddDevice(const char *path) return -1; } - item = (SDL_hapticlist_item *) SDL_calloc(1, sizeof (SDL_hapticlist_item)); - if (item == NULL) { + item = (SDL_hapticlist_item *)SDL_calloc(1, sizeof(SDL_hapticlist_item)); + if (!item) { return -1; } item->fname = SDL_strdup(path); - if (item->fname == NULL) { + if (!item->fname) { SDL_free(item); return -1; } @@ -292,7 +279,7 @@ MaybeAddDevice(const char *path) item->dev_num = sb.st_rdev; /* TODO: should we add instance IDs? */ - if (SDL_hapticlist_tail == NULL) { + if (!SDL_hapticlist_tail) { SDL_hapticlist = SDL_hapticlist_tail = item; } else { SDL_hapticlist_tail->next = item; @@ -306,23 +293,22 @@ MaybeAddDevice(const char *path) return numhaptics; } -#if SDL_USE_LIBUDEV -static int -MaybeRemoveDevice(const char* path) +#ifdef SDL_USE_LIBUDEV +static int MaybeRemoveDevice(const char *path) { SDL_hapticlist_item *item; SDL_hapticlist_item *prev = NULL; - if (path == NULL) { + if (!path) { return -1; } - for (item = SDL_hapticlist; item != NULL; item = item->next) { + for (item = SDL_hapticlist; item; item = item->next) { /* found it, remove it. */ if (SDL_strcmp(path, item->fname) == 0) { const int retval = item->haptic ? item->haptic->index : -1; - if (prev != NULL) { + if (prev) { prev->next = item->next; } else { SDL_assert(SDL_hapticlist == item); @@ -350,8 +336,7 @@ MaybeRemoveDevice(const char* path) /* * Gets the name from a file descriptor. */ -static const char * -SDL_SYS_HapticNameFromFD(int fd) +static const char *SDL_SYS_HapticNameFromFD(int fd) { static char namebuf[128]; @@ -363,12 +348,10 @@ SDL_SYS_HapticNameFromFD(int fd) return namebuf; } - /* * Return the name of a haptic device, does not need to be opened. */ -const char * -SDL_SYS_HapticName(int index) +const char *SDL_SYS_HapticName(int index) { SDL_hapticlist_item *item; int fd; @@ -377,12 +360,12 @@ SDL_SYS_HapticName(int index) item = HapticByDevIndex(index); /* Open the haptic device. */ name = NULL; - fd = open(item->fname, O_RDONLY, 0); + fd = open(item->fname, O_RDONLY | O_CLOEXEC, 0); if (fd >= 0) { name = SDL_SYS_HapticNameFromFD(fd); - if (name == NULL) { + if (!name) { /* No name found, return device character device */ name = item->fname; } @@ -392,17 +375,15 @@ SDL_SYS_HapticName(int index) return name; } - /* * Opens the haptic device from the file descriptor. */ -static int -SDL_SYS_HapticOpenFromFD(SDL_Haptic * haptic, int fd) +static int SDL_SYS_HapticOpenFromFD(SDL_Haptic *haptic, int fd) { /* Allocate the hwdata */ haptic->hwdata = (struct haptic_hwdata *) SDL_malloc(sizeof(*haptic->hwdata)); - if (haptic->hwdata == NULL) { + if (!haptic->hwdata) { SDL_OutOfMemory(); goto open_err; } @@ -411,7 +392,7 @@ SDL_SYS_HapticOpenFromFD(SDL_Haptic * haptic, int fd) /* Set the data. */ haptic->hwdata->fd = fd; haptic->supported = EV_IsHaptic(fd); - haptic->naxes = 2; /* Hardcoded for now, not sure if it's possible to find out. */ + haptic->naxes = 2; /* Hardcoded for now, not sure if it's possible to find out. */ /* Set the effects */ if (ioctl(fd, EVIOCGEFFECTS, &haptic->neffects) < 0) { @@ -419,10 +400,10 @@ SDL_SYS_HapticOpenFromFD(SDL_Haptic * haptic, int fd) strerror(errno)); goto open_err; } - haptic->nplaying = haptic->neffects; /* Linux makes no distinction. */ + haptic->nplaying = haptic->neffects; /* Linux makes no distinction. */ haptic->effects = (struct haptic_effect *) SDL_malloc(sizeof(struct haptic_effect) * haptic->neffects); - if (haptic->effects == NULL) { + if (!haptic->effects) { SDL_OutOfMemory(); goto open_err; } @@ -433,21 +414,19 @@ SDL_SYS_HapticOpenFromFD(SDL_Haptic * haptic, int fd) return 0; /* Error handling */ - open_err: +open_err: close(fd); - if (haptic->hwdata != NULL) { + if (haptic->hwdata) { SDL_free(haptic->hwdata); haptic->hwdata = NULL; } return -1; } - /* * Opens a haptic device for usage. */ -int -SDL_SYS_HapticOpen(SDL_Haptic * haptic) +int SDL_SYS_HapticOpen(SDL_Haptic *haptic) { int fd; int ret; @@ -455,7 +434,7 @@ SDL_SYS_HapticOpen(SDL_Haptic * haptic) item = HapticByDevIndex(haptic->index); /* Open the character device */ - fd = open(item->fname, O_RDWR, 0); + fd = open(item->fname, O_RDWR | O_CLOEXEC, 0); if (fd < 0) { return SDL_SetError("Haptic: Unable to open %s: %s", item->fname, strerror(errno)); @@ -468,16 +447,14 @@ SDL_SYS_HapticOpen(SDL_Haptic * haptic) } /* Set the fname. */ - haptic->hwdata->fname = SDL_strdup( item->fname ); + haptic->hwdata->fname = SDL_strdup(item->fname); return 0; } - /* * Opens a haptic device from first mouse it finds for usage. */ -int -SDL_SYS_HapticMouse(void) +int SDL_SYS_HapticMouse(void) { int fd; int device_index = 0; @@ -485,7 +462,7 @@ SDL_SYS_HapticMouse(void) for (item = SDL_hapticlist; item; item = item->next) { /* Open the device. */ - fd = open(item->fname, O_RDWR, 0); + fd = open(item->fname, O_RDWR | O_CLOEXEC, 0); if (fd < 0) { return SDL_SetError("Haptic: Unable to open %s: %s", item->fname, strerror(errno)); @@ -505,26 +482,32 @@ SDL_SYS_HapticMouse(void) return -1; } - /* * Checks to see if a joystick has haptic features. */ -int -SDL_SYS_JoystickIsHaptic(SDL_Joystick * joystick) +int SDL_SYS_JoystickIsHaptic(SDL_Joystick *joystick) { - if (joystick->driver != &SDL_LINUX_JoystickDriver) { - return 0; - } - return EV_IsHaptic(joystick->hwdata->fd); -} +#ifdef SDL_JOYSTICK_LINUX + SDL_AssertJoysticksLocked(); + if (joystick->driver != &SDL_LINUX_JoystickDriver) { + return SDL_FALSE; + } + if (EV_IsHaptic(joystick->hwdata->fd)) { + return SDL_TRUE; + } +#endif + return SDL_FALSE; +} /* * Checks to see if the haptic device and joystick are in reality the same. */ -int -SDL_SYS_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick) +int SDL_SYS_JoystickSameHaptic(SDL_Haptic *haptic, SDL_Joystick *joystick) { +#ifdef SDL_JOYSTICK_LINUX + SDL_AssertJoysticksLocked(); + if (joystick->driver != &SDL_LINUX_JoystickDriver) { return 0; } @@ -533,21 +516,23 @@ SDL_SYS_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick) if (SDL_strcmp(joystick->hwdata->fname, haptic->hwdata->fname) == 0) { return 1; } +#endif return 0; } - /* * Opens a SDL_Haptic from a SDL_Joystick. */ -int -SDL_SYS_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick) +int SDL_SYS_HapticOpenFromJoystick(SDL_Haptic *haptic, SDL_Joystick *joystick) { +#ifdef SDL_JOYSTICK_LINUX int device_index = 0; int fd; int ret; SDL_hapticlist_item *item; - + + SDL_AssertJoysticksLocked(); + if (joystick->driver != &SDL_LINUX_JoystickDriver) { return -1; } @@ -564,7 +549,7 @@ SDL_SYS_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick) return SDL_SetError("Haptic: Joystick doesn't have Haptic capabilities"); } - fd = open(joystick->hwdata->fname, O_RDWR, 0); + fd = open(joystick->hwdata->fname, O_RDWR | O_CLOEXEC, 0); if (fd < 0) { return SDL_SetError("Haptic: Unable to open %s: %s", joystick->hwdata->fname, strerror(errno)); @@ -574,17 +559,18 @@ SDL_SYS_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick) return -1; } - haptic->hwdata->fname = SDL_strdup( joystick->hwdata->fname ); + haptic->hwdata->fname = SDL_strdup(joystick->hwdata->fname); return 0; +#else + return -1; +#endif } - /* * Closes the haptic device. */ -void -SDL_SYS_HapticClose(SDL_Haptic * haptic) +void SDL_SYS_HapticClose(SDL_Haptic *haptic) { if (haptic->hwdata) { @@ -606,12 +592,10 @@ SDL_SYS_HapticClose(SDL_Haptic * haptic) SDL_memset(haptic, 0, sizeof(SDL_Haptic)); } - /* * Clean up after system specific haptic stuff */ -void -SDL_SYS_HapticQuit(void) +void SDL_SYS_HapticQuit(void) { SDL_hapticlist_item *item = NULL; SDL_hapticlist_item *next = NULL; @@ -624,7 +608,7 @@ SDL_SYS_HapticQuit(void) SDL_free(item); } -#if SDL_USE_LIBUDEV +#ifdef SDL_USE_LIBUDEV SDL_UDEV_DelCallback(haptic_udev_callback); SDL_UDEV_Quit(); #endif /* SDL_USE_LIBUDEV */ @@ -634,12 +618,10 @@ SDL_SYS_HapticQuit(void) SDL_hapticlist_tail = NULL; } - /* * Converts an SDL button to a ff_trigger button. */ -static Uint16 -SDL_SYS_ToButton(Uint16 button) +static Uint16 SDL_SYS_ToButton(Uint16 button) { Uint16 ff_button; @@ -656,58 +638,45 @@ SDL_SYS_ToButton(Uint16 button) return ff_button; } - /* * Initializes the ff_effect usable direction from a SDL_HapticDirection. */ -static int -SDL_SYS_ToDirection(Uint16 *dest, SDL_HapticDirection * src) +static int SDL_SYS_ToDirection(Uint16 *dest, SDL_HapticDirection *src) { Uint32 tmp; switch (src->type) { case SDL_HAPTIC_POLAR: - /* Linux directions start from south. - (and range from 0 to 0xFFFF) - Quoting include/linux/input.h, line 926: - Direction of the effect is encoded as follows: - 0 deg -> 0x0000 (down) - 90 deg -> 0x4000 (left) - 180 deg -> 0x8000 (up) - 270 deg -> 0xC000 (right) - The force pulls into the direction specified by Linux directions, - i.e. the opposite convention of SDL directions. - */ tmp = ((src->dir[0] % 36000) * 0x8000) / 18000; /* convert to range [0,0xFFFF] */ - *dest = (Uint16) tmp; + *dest = (Uint16)tmp; break; case SDL_HAPTIC_SPHERICAL: - /* - We convert to polar, because that's the only supported direction on Linux. - The first value of a spherical direction is practically the same as a - Polar direction, except that we have to add 90 degrees. It is the angle - from EAST {1,0} towards SOUTH {0,1}. - --> add 9000 - --> finally convert to [0,0xFFFF] as in case SDL_HAPTIC_POLAR. - */ - tmp = ((src->dir[0]) + 9000) % 36000; /* Convert to polars */ - tmp = (tmp * 0x8000) / 18000; /* convert to range [0,0xFFFF] */ - *dest = (Uint16) tmp; + /* + We convert to polar, because that's the only supported direction on Linux. + The first value of a spherical direction is practically the same as a + Polar direction, except that we have to add 90 degrees. It is the angle + from EAST {1,0} towards SOUTH {0,1}. + --> add 9000 + --> finally convert to [0,0xFFFF] as in case SDL_HAPTIC_POLAR. + */ + tmp = ((src->dir[0]) + 9000) % 36000; /* Convert to polars */ + tmp = (tmp * 0x8000) / 18000; /* convert to range [0,0xFFFF] */ + *dest = (Uint16)tmp; break; case SDL_HAPTIC_CARTESIAN: - if (!src->dir[1]) + if (!src->dir[1]) { *dest = (src->dir[0] >= 0 ? 0x4000 : 0xC000); - else if (!src->dir[0]) + } else if (!src->dir[0]) { *dest = (src->dir[1] >= 0 ? 0x8000 : 0); - else { + } else { float f = SDL_atan2(src->dir[1], src->dir[0]); /* Ideally we'd use fixed point math instead of floats... */ /* - atan2 takes the parameters: Y-axis-value and X-axis-value (in that order) + SDL_atan2 takes the parameters: Y-axis-value and X-axis-value (in that order) - Y-axis-value is the second coordinate (from center to SOUTH) - X-axis-value is the first coordinate (from center to EAST) - We add 36000, because atan2 also returns negative values. Then we practically + We add 36000, because SDL_atan2 also returns negative values. Then we practically have the first spherical value. Therefore we proceed as in case SDL_HAPTIC_SPHERICAL and add another 9000 to get the polar value. --> add 45000 in total @@ -715,10 +684,12 @@ SDL_SYS_ToDirection(Uint16 *dest, SDL_HapticDirection * src) */ tmp = (((Sint32) (f * 18000. / M_PI)) + 45000) % 36000; tmp = (tmp * 0x8000) / 18000; /* convert to range [0,0xFFFF] */ - *dest = (Uint16) tmp; + *dest = (Uint16)tmp; } break; - + case SDL_HAPTIC_STEERING_AXIS: + *dest = 0x4000; + break; default: return SDL_SetError("Haptic: Unsupported direction type."); } @@ -726,14 +697,12 @@ SDL_SYS_ToDirection(Uint16 *dest, SDL_HapticDirection * src) return 0; } - -#define CLAMP(x) (((x) > 32767) ? 32767 : x) +#define CLAMP(x) (((x) > 32767) ? 32767 : x) /* * Initializes the Linux effect struct from a haptic_effect. * Values above 32767 (for unsigned) are unspecified so we must clamp. */ -static int -SDL_SYS_ToFFEffect(struct ff_effect *dest, SDL_HapticEffect * src) +static int SDL_SYS_ToFFEffect(struct ff_effect *dest, SDL_HapticEffect *src) { SDL_HapticConstant *constant; SDL_HapticPeriodic *periodic; @@ -750,12 +719,12 @@ SDL_SYS_ToFFEffect(struct ff_effect *dest, SDL_HapticEffect * src) /* Header */ dest->type = FF_CONSTANT; - if (SDL_SYS_ToDirection(&dest->direction, &constant->direction) == -1) + if (SDL_SYS_ToDirection(&dest->direction, &constant->direction) == -1) { return -1; + } /* Replay */ - dest->replay.length = (constant->length == SDL_HAPTIC_INFINITY) ? - 0 : CLAMP(constant->length); + dest->replay.length = (constant->length == SDL_HAPTIC_INFINITY) ? 0 : CLAMP(constant->length); dest->replay.delay = CLAMP(constant->delay); /* Trigger */ @@ -785,12 +754,12 @@ SDL_SYS_ToFFEffect(struct ff_effect *dest, SDL_HapticEffect * src) /* Header */ dest->type = FF_PERIODIC; - if (SDL_SYS_ToDirection(&dest->direction, &periodic->direction) == -1) + if (SDL_SYS_ToDirection(&dest->direction, &periodic->direction) == -1) { return -1; + } /* Replay */ - dest->replay.length = (periodic->length == SDL_HAPTIC_INFINITY) ? - 0 : CLAMP(periodic->length); + dest->replay.length = (periodic->length == SDL_HAPTIC_INFINITY) ? 0 : CLAMP(periodic->length); dest->replay.delay = CLAMP(periodic->delay); /* Trigger */ @@ -798,17 +767,18 @@ SDL_SYS_ToFFEffect(struct ff_effect *dest, SDL_HapticEffect * src) dest->trigger.interval = CLAMP(periodic->interval); /* Periodic */ - if (periodic->type == SDL_HAPTIC_SINE) + if (periodic->type == SDL_HAPTIC_SINE) { dest->u.periodic.waveform = FF_SINE; - /* !!! FIXME: put this back when we have more bits in 2.1 */ - /* else if (periodic->type == SDL_HAPTIC_SQUARE) - dest->u.periodic.waveform = FF_SQUARE; */ - else if (periodic->type == SDL_HAPTIC_TRIANGLE) + /* !!! FIXME: put this back when we have more bits in 2.1 */ + /* else if (periodic->type == SDL_HAPTIC_SQUARE) + dest->u.periodic.waveform = FF_SQUARE; */ + } else if (periodic->type == SDL_HAPTIC_TRIANGLE) { dest->u.periodic.waveform = FF_TRIANGLE; - else if (periodic->type == SDL_HAPTIC_SAWTOOTHUP) + } else if (periodic->type == SDL_HAPTIC_SAWTOOTHUP) { dest->u.periodic.waveform = FF_SAW_UP; - else if (periodic->type == SDL_HAPTIC_SAWTOOTHDOWN) + } else if (periodic->type == SDL_HAPTIC_SAWTOOTHDOWN) { dest->u.periodic.waveform = FF_SAW_DOWN; + } dest->u.periodic.period = CLAMP(periodic->period); dest->u.periodic.magnitude = periodic->magnitude; dest->u.periodic.offset = periodic->offset; @@ -832,19 +802,20 @@ SDL_SYS_ToFFEffect(struct ff_effect *dest, SDL_HapticEffect * src) condition = &src->condition; /* Header */ - if (condition->type == SDL_HAPTIC_SPRING) + if (condition->type == SDL_HAPTIC_SPRING) { dest->type = FF_SPRING; - else if (condition->type == SDL_HAPTIC_DAMPER) + } else if (condition->type == SDL_HAPTIC_DAMPER) { dest->type = FF_DAMPER; - else if (condition->type == SDL_HAPTIC_INERTIA) + } else if (condition->type == SDL_HAPTIC_INERTIA) { dest->type = FF_INERTIA; - else if (condition->type == SDL_HAPTIC_FRICTION) + } else if (condition->type == SDL_HAPTIC_FRICTION) { dest->type = FF_FRICTION; - dest->direction = 0; /* Handled by the condition-specifics. */ + } + + dest->direction = 0; /* Handled by the condition-specifics. */ /* Replay */ - dest->replay.length = (condition->length == SDL_HAPTIC_INFINITY) ? - 0 : CLAMP(condition->length); + dest->replay.length = (condition->length == SDL_HAPTIC_INFINITY) ? 0 : CLAMP(condition->length); dest->replay.delay = CLAMP(condition->delay); /* Trigger */ @@ -878,12 +849,12 @@ SDL_SYS_ToFFEffect(struct ff_effect *dest, SDL_HapticEffect * src) /* Header */ dest->type = FF_RAMP; - if (SDL_SYS_ToDirection(&dest->direction, &ramp->direction) == -1) + if (SDL_SYS_ToDirection(&dest->direction, &ramp->direction) == -1) { return -1; + } /* Replay */ - dest->replay.length = (ramp->length == SDL_HAPTIC_INFINITY) ? - 0 : CLAMP(ramp->length); + dest->replay.length = (ramp->length == SDL_HAPTIC_INFINITY) ? 0 : CLAMP(ramp->length); dest->replay.delay = CLAMP(ramp->delay); /* Trigger */ @@ -910,8 +881,7 @@ SDL_SYS_ToFFEffect(struct ff_effect *dest, SDL_HapticEffect * src) dest->direction = 0; /* Replay */ - dest->replay.length = (leftright->length == SDL_HAPTIC_INFINITY) ? - 0 : CLAMP(leftright->length); + dest->replay.length = (leftright->length == SDL_HAPTIC_INFINITY) ? 0 : CLAMP(leftright->length); /* Trigger */ dest->trigger.button = 0; @@ -923,7 +893,6 @@ SDL_SYS_ToFFEffect(struct ff_effect *dest, SDL_HapticEffect * src) break; - default: return SDL_SetError("Haptic: Unknown effect type."); } @@ -931,20 +900,18 @@ SDL_SYS_ToFFEffect(struct ff_effect *dest, SDL_HapticEffect * src) return 0; } - /* * Creates a new haptic effect. */ -int -SDL_SYS_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect *effect, - SDL_HapticEffect * base) +int SDL_SYS_HapticNewEffect(SDL_Haptic *haptic, struct haptic_effect *effect, + SDL_HapticEffect *base) { struct ff_effect *linux_effect; /* Allocate the hardware effect */ effect->hweffect = (struct haptic_hweffect *) SDL_malloc(sizeof(struct haptic_hweffect)); - if (effect->hweffect == NULL) { + if (!effect->hweffect) { return SDL_OutOfMemory(); } @@ -953,7 +920,7 @@ SDL_SYS_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect *effect, if (SDL_SYS_ToFFEffect(linux_effect, base) != 0) { goto new_effect_err; } - linux_effect->id = -1; /* Have the kernel give it an id */ + linux_effect->id = -1; /* Have the kernel give it an id */ /* Upload the effect */ if (ioctl(haptic->hwdata->fd, EVIOCSFF, linux_effect) < 0) { @@ -964,23 +931,21 @@ SDL_SYS_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect *effect, return 0; - new_effect_err: +new_effect_err: SDL_free(effect->hweffect); effect->hweffect = NULL; return -1; } - /* * Updates an effect. * * Note: Dynamically updating the direction can in some cases force * the effect to restart and run once. */ -int -SDL_SYS_HapticUpdateEffect(SDL_Haptic * haptic, - struct haptic_effect *effect, - SDL_HapticEffect * data) +int SDL_SYS_HapticUpdateEffect(SDL_Haptic *haptic, + struct haptic_effect *effect, + SDL_HapticEffect *data) { struct ff_effect linux_effect; @@ -1003,13 +968,11 @@ SDL_SYS_HapticUpdateEffect(SDL_Haptic * haptic, return effect->hweffect->effect.id; } - /* * Runs an effect. */ -int -SDL_SYS_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect, - Uint32 iterations) +int SDL_SYS_HapticRunEffect(SDL_Haptic *haptic, struct haptic_effect *effect, + Uint32 iterations) { struct input_event run; @@ -1019,19 +982,17 @@ SDL_SYS_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect, /* We don't actually have infinity here, so we just do INT_MAX which is pretty damn close. */ run.value = (iterations > INT_MAX) ? INT_MAX : iterations; - if (write(haptic->hwdata->fd, (const void *) &run, sizeof(run)) < 0) { + if (write(haptic->hwdata->fd, (const void *)&run, sizeof(run)) < 0) { return SDL_SetError("Haptic: Unable to run the effect: %s", strerror(errno)); } return 0; } - /* * Stops an effect. */ -int -SDL_SYS_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect *effect) +int SDL_SYS_HapticStopEffect(SDL_Haptic *haptic, struct haptic_effect *effect) { struct input_event stop; @@ -1039,7 +1000,7 @@ SDL_SYS_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect *effect) stop.code = effect->hweffect->effect.id; stop.value = 0; - if (write(haptic->hwdata->fd, (const void *) &stop, sizeof(stop)) < 0) { + if (write(haptic->hwdata->fd, (const void *)&stop, sizeof(stop)) < 0) { return SDL_SetError("Haptic: Unable to stop the effect: %s", strerror(errno)); } @@ -1047,12 +1008,10 @@ SDL_SYS_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect *effect) return 0; } - /* * Frees the effect. */ -void -SDL_SYS_HapticDestroyEffect(SDL_Haptic * haptic, struct haptic_effect *effect) +void SDL_SYS_HapticDestroyEffect(SDL_Haptic *haptic, struct haptic_effect *effect) { if (ioctl(haptic->hwdata->fd, EVIOCRMFF, effect->hweffect->effect.id) < 0) { SDL_SetError("Haptic: Error removing the effect from the device: %s", @@ -1062,15 +1021,13 @@ SDL_SYS_HapticDestroyEffect(SDL_Haptic * haptic, struct haptic_effect *effect) effect->hweffect = NULL; } - /* * Gets the status of a haptic effect. */ -int -SDL_SYS_HapticGetEffectStatus(SDL_Haptic * haptic, - struct haptic_effect *effect) +int SDL_SYS_HapticGetEffectStatus(SDL_Haptic *haptic, + struct haptic_effect *effect) { -#if 0 /* Not supported atm. */ +#if 0 /* Not supported atm. */ struct input_event ie; ie.type = EV_FF; @@ -1087,12 +1044,10 @@ SDL_SYS_HapticGetEffectStatus(SDL_Haptic * haptic, return -1; } - /* * Sets the gain. */ -int -SDL_SYS_HapticSetGain(SDL_Haptic * haptic, int gain) +int SDL_SYS_HapticSetGain(SDL_Haptic *haptic, int gain) { struct input_event ie; @@ -1107,12 +1062,10 @@ SDL_SYS_HapticSetGain(SDL_Haptic * haptic, int gain) return 0; } - /* * Sets the autocentering. */ -int -SDL_SYS_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter) +int SDL_SYS_HapticSetAutocenter(SDL_Haptic *haptic, int autocenter) { struct input_event ie; @@ -1127,32 +1080,26 @@ SDL_SYS_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter) return 0; } - /* * Pausing is not supported atm by linux. */ -int -SDL_SYS_HapticPause(SDL_Haptic * haptic) +int SDL_SYS_HapticPause(SDL_Haptic *haptic) { return -1; } - /* * Unpausing is not supported atm by linux. */ -int -SDL_SYS_HapticUnpause(SDL_Haptic * haptic) +int SDL_SYS_HapticUnpause(SDL_Haptic *haptic) { return -1; } - /* * Stops all the currently playing effects. */ -int -SDL_SYS_HapticStopAll(SDL_Haptic * haptic) +int SDL_SYS_HapticStopAll(SDL_Haptic *haptic) { int i, ret; @@ -1161,8 +1108,7 @@ SDL_SYS_HapticStopAll(SDL_Haptic * haptic) if (haptic->effects[i].hweffect != NULL) { ret = SDL_SYS_HapticStopEffect(haptic, &haptic->effects[i]); if (ret < 0) { - return SDL_SetError - ("Haptic: Error while trying to stop all playing effects."); + return SDL_SetError("Haptic: Error while trying to stop all playing effects."); } } } diff --git a/SDL2-2.0.12/src/haptic/windows/SDL_dinputhaptic.c b/SDL2-2.30.5/src/haptic/windows/SDL_dinputhaptic.c similarity index 72% rename from SDL2-2.0.12/src/haptic/windows/SDL_dinputhaptic.c rename to SDL2-2.30.5/src/haptic/windows/SDL_dinputhaptic.c index cccc74f..2214915 100644 --- a/SDL2-2.0.12/src/haptic/windows/SDL_dinputhaptic.c +++ b/SDL2-2.30.5/src/haptic/windows/SDL_dinputhaptic.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,12 +20,14 @@ */ #include "../../SDL_internal.h" +#include "SDL.h" #include "SDL_error.h" #include "SDL_haptic.h" #include "../SDL_syshaptic.h" -#if SDL_HAPTIC_DINPUT +#ifdef SDL_HAPTIC_DINPUT +#include "SDL_hints.h" #include "SDL_stdinc.h" #include "SDL_timer.h" #include "SDL_windowshaptic_c.h" @@ -35,8 +37,11 @@ /* * External stuff. */ +#ifdef SDL_VIDEO_DRIVER_WINDOWS extern HWND SDL_HelperWindow; - +#else +static const HWND SDL_HelperWindow = NULL; +#endif /* * Internal stuff. @@ -44,41 +49,39 @@ extern HWND SDL_HelperWindow; static SDL_bool coinitialized = SDL_FALSE; static LPDIRECTINPUT8 dinput = NULL; - /* * Like SDL_SetError but for DX error codes. */ -static int -DI_SetError(const char *str, HRESULT err) +static int DI_SetError(const char *str, HRESULT err) { - /* - SDL_SetError("Haptic: %s - %s: %s", str, - DXGetErrorString8A(err), DXGetErrorDescription8A(err)); - */ return SDL_SetError("Haptic error %s", str); } /* * Callback to find the haptic devices. */ -static BOOL CALLBACK -EnumHapticsCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext) +static BOOL CALLBACK EnumHapticsCallback(const DIDEVICEINSTANCE *pdidInstance, VOID *pContext) { - (void) pContext; - SDL_DINPUT_MaybeAddDevice(pdidInstance); - return DIENUM_CONTINUE; /* continue enumerating */ + (void)pContext; + SDL_DINPUT_HapticMaybeAddDevice(pdidInstance); + return DIENUM_CONTINUE; /* continue enumerating */ } -int -SDL_DINPUT_HapticInit(void) +int SDL_DINPUT_HapticInit(void) { HRESULT ret; HINSTANCE instance; + DWORD devClass; - if (dinput != NULL) { /* Already open. */ + if (dinput != NULL) { /* Already open. */ return SDL_SetError("Haptic: SubSystem already open."); } + if (!SDL_GetHintBoolean(SDL_HINT_DIRECTINPUT_ENABLED, SDL_TRUE)) { + /* In some environments, IDirectInput8_Initialize / _EnumDevices can take a minute even with no controllers. */ + return 0; + } + ret = WIN_CoInitialize(); if (FAILED(ret)) { return DI_SetError("Coinitialize", ret); @@ -87,7 +90,7 @@ SDL_DINPUT_HapticInit(void) coinitialized = SDL_TRUE; ret = CoCreateInstance(&CLSID_DirectInput8, NULL, CLSCTX_INPROC_SERVER, - &IID_IDirectInput8, (LPVOID)& dinput); + &IID_IDirectInput8, (LPVOID *)&dinput); if (FAILED(ret)) { SDL_SYS_HapticQuit(); return DI_SetError("CoCreateInstance", ret); @@ -95,10 +98,10 @@ SDL_DINPUT_HapticInit(void) /* Because we used CoCreateInstance, we need to Initialize it, first. */ instance = GetModuleHandle(NULL); - if (instance == NULL) { + if (!instance) { SDL_SYS_HapticQuit(); return SDL_SetError("GetModuleHandle() failed with error code %lu.", - GetLastError()); + GetLastError()); } ret = IDirectInput8_Initialize(dinput, instance, DIRECTINPUT_VERSION); if (FAILED(ret)) { @@ -107,21 +110,28 @@ SDL_DINPUT_HapticInit(void) } /* Look for haptic devices. */ - ret = IDirectInput8_EnumDevices(dinput, - 0, - EnumHapticsCallback, - NULL, - DIEDFL_FORCEFEEDBACK | - DIEDFL_ATTACHEDONLY); - if (FAILED(ret)) { - SDL_SYS_HapticQuit(); - return DI_SetError("Enumerating DirectInput devices", ret); + for (devClass = DI8DEVCLASS_DEVICE; devClass <= DI8DEVCLASS_GAMECTRL; devClass++) { + if (devClass == DI8DEVCLASS_GAMECTRL && SDL_WasInit(SDL_INIT_JOYSTICK)) { + /* The joystick subsystem will manage adding DInput joystick haptic devices */ + continue; + } + + ret = IDirectInput8_EnumDevices(dinput, + devClass, + EnumHapticsCallback, + NULL, + DIEDFL_FORCEFEEDBACK | + DIEDFL_ATTACHEDONLY); + if (FAILED(ret)) { + SDL_SYS_HapticQuit(); + return DI_SetError("Enumerating DirectInput devices", ret); + } } + return 0; } -int -SDL_DINPUT_MaybeAddDevice(const DIDEVICEINSTANCE * pdidInstance) +int SDL_DINPUT_HapticMaybeAddDevice(const DIDEVICEINSTANCE *pdidInstance) { HRESULT ret; LPDIRECTINPUTDEVICE8 device; @@ -129,14 +139,14 @@ SDL_DINPUT_MaybeAddDevice(const DIDEVICEINSTANCE * pdidInstance) DIDEVCAPS capabilities; SDL_hapticlist_item *item = NULL; - if (dinput == NULL) { - return -1; /* not initialized. We'll pick these up on enumeration if we init later. */ + if (!dinput) { + return -1; /* not initialized. We'll pick these up on enumeration if we init later. */ } /* Make sure we don't already have it */ for (item = SDL_hapticlist; item; item = item->next) { if ((!item->bXInputHaptic) && (SDL_memcmp(&item->instance, pdidInstance, sizeof(*pdidInstance)) == 0)) { - return -1; /* Already added */ + return -1; /* Already added */ } } @@ -158,11 +168,11 @@ SDL_DINPUT_MaybeAddDevice(const DIDEVICEINSTANCE * pdidInstance) } if ((capabilities.dwFlags & needflags) != needflags) { - return -1; /* not a device we can use. */ + return -1; /* not a device we can use. */ } item = (SDL_hapticlist_item *)SDL_calloc(1, sizeof(SDL_hapticlist_item)); - if (item == NULL) { + if (!item) { return SDL_OutOfMemory(); } @@ -179,17 +189,16 @@ SDL_DINPUT_MaybeAddDevice(const DIDEVICEINSTANCE * pdidInstance) return SDL_SYS_AddHapticDevice(item); } -int -SDL_DINPUT_MaybeRemoveDevice(const DIDEVICEINSTANCE * pdidInstance) +int SDL_DINPUT_HapticMaybeRemoveDevice(const DIDEVICEINSTANCE *pdidInstance) { SDL_hapticlist_item *item; SDL_hapticlist_item *prev = NULL; - if (dinput == NULL) { - return -1; /* not initialized, ignore this. */ + if (!dinput) { + return -1; /* not initialized, ignore this. */ } - for (item = SDL_hapticlist; item != NULL; item = item->next) { + for (item = SDL_hapticlist; item; item = item->next) { if (!item->bXInputHaptic && SDL_memcmp(&item->instance, pdidInstance, sizeof(*pdidInstance)) == 0) { /* found it, remove it. */ return SDL_SYS_RemoveHapticDevice(prev, item); @@ -202,10 +211,9 @@ SDL_DINPUT_MaybeRemoveDevice(const DIDEVICEINSTANCE * pdidInstance) /* * Callback to get supported axes. */ -static BOOL CALLBACK -DI_DeviceObjectCallback(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID pvRef) +static BOOL CALLBACK DI_DeviceObjectCallback(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID pvRef) { - SDL_Haptic *haptic = (SDL_Haptic *) pvRef; + SDL_Haptic *haptic = (SDL_Haptic *)pvRef; if ((dev->dwType & DIDFT_AXIS) && (dev->dwFlags & DIDOI_FFACTUATOR)) { const GUID *guid = &dev->guidType; @@ -223,7 +231,7 @@ DI_DeviceObjectCallback(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID pvRef) } else if (WIN_IsEqualGUID(guid, &GUID_RzAxis)) { offset = DIJOFS_RZ; } else { - return DIENUM_CONTINUE; /* can't use this, go on. */ + return DIENUM_CONTINUE; /* can't use this, go on. */ } haptic->hwdata->axes[haptic->naxes] = offset; @@ -241,14 +249,13 @@ DI_DeviceObjectCallback(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID pvRef) /* * Callback to get all supported effects. */ -#define EFFECT_TEST(e,s) \ -if (WIN_IsEqualGUID(&pei->guid, &(e))) \ - haptic->supported |= (s) -static BOOL CALLBACK -DI_EffectCallback(LPCDIEFFECTINFO pei, LPVOID pv) +#define EFFECT_TEST(e, s) \ + if (WIN_IsEqualGUID(&pei->guid, &(e))) \ + haptic->supported |= (s) +static BOOL CALLBACK DI_EffectCallback(LPCDIEFFECTINFO pei, LPVOID pv) { /* Prepare the haptic device. */ - SDL_Haptic *haptic = (SDL_Haptic *) pv; + SDL_Haptic *haptic = (SDL_Haptic *)pv; /* Get supported. */ EFFECT_TEST(GUID_Spring, SDL_HAPTIC_SPRING); @@ -279,15 +286,14 @@ DI_EffectCallback(LPCDIEFFECTINFO pei, LPVOID pv) * - Reset actuators. * - Get supported features. */ -static int -SDL_DINPUT_HapticOpenFromDevice(SDL_Haptic * haptic, LPDIRECTINPUTDEVICE8 device8, SDL_bool is_joystick) +static int SDL_DINPUT_HapticOpenFromDevice(SDL_Haptic *haptic, LPDIRECTINPUTDEVICE8 device8, SDL_bool is_joystick) { HRESULT ret; DIPROPDWORD dipdw; /* Allocate the hwdata */ haptic->hwdata = (struct haptic_hwdata *)SDL_malloc(sizeof(*haptic->hwdata)); - if (haptic->hwdata == NULL) { + if (!haptic->hwdata) { return SDL_OutOfMemory(); } SDL_memset(haptic->hwdata, 0, sizeof(*haptic->hwdata)); @@ -303,12 +309,12 @@ SDL_DINPUT_HapticOpenFromDevice(SDL_Haptic * haptic, LPDIRECTINPUTDEVICE8 device !!! FIXME: to work, and that's probably the common case. Still, !!! FIXME: ideally, We need to unify the opening code. */ - if (!is_joystick) { /* if is_joystick, we already set this up elsewhere. */ + if (!is_joystick) { /* if is_joystick, we already set this up elsewhere. */ /* Grab it exclusively to use force feedback stuff. */ ret = IDirectInputDevice8_SetCooperativeLevel(haptic->hwdata->device, SDL_HelperWindow, DISCL_EXCLUSIVE | - DISCL_BACKGROUND); + DISCL_BACKGROUND); if (FAILED(ret)) { DI_SetError("Setting cooperative level to exclusive", ret); goto acquire_err; @@ -322,7 +328,6 @@ SDL_DINPUT_HapticOpenFromDevice(SDL_Haptic * haptic, LPDIRECTINPUTDEVICE8 device goto acquire_err; } - /* Acquire the device. */ ret = IDirectInputDevice8_Acquire(haptic->hwdata->device); if (FAILED(ret)) { @@ -364,7 +369,7 @@ SDL_DINPUT_HapticOpenFromDevice(SDL_Haptic * haptic, LPDIRECTINPUTDEVICE8 device DI_SetError("Enumerating supported effects", ret); goto acquire_err; } - if (haptic->supported == 0) { /* Error since device supports nothing. */ + if (haptic->supported == 0) { /* Error since device supports nothing. */ SDL_SetError("Haptic: Internal error on finding supported effects."); goto acquire_err; } @@ -377,7 +382,7 @@ SDL_DINPUT_HapticOpenFromDevice(SDL_Haptic * haptic, LPDIRECTINPUTDEVICE8 device dipdw.dwData = 10000; ret = IDirectInputDevice8_SetProperty(haptic->hwdata->device, DIPROP_FFGAIN, &dipdw.diph); - if (!FAILED(ret)) { /* Gain is supported. */ + if (!FAILED(ret)) { /* Gain is supported. */ haptic->supported |= SDL_HAPTIC_GAIN; } dipdw.diph.dwObj = 0; @@ -385,7 +390,7 @@ SDL_DINPUT_HapticOpenFromDevice(SDL_Haptic * haptic, LPDIRECTINPUTDEVICE8 device dipdw.dwData = DIPROPAUTOCENTER_OFF; ret = IDirectInputDevice8_SetProperty(haptic->hwdata->device, DIPROP_AUTOCENTER, &dipdw.diph); - if (!FAILED(ret)) { /* Autocenter is supported. */ + if (!FAILED(ret)) { /* Autocenter is supported. */ haptic->supported |= SDL_HAPTIC_AUTOCENTER; } @@ -393,16 +398,16 @@ SDL_DINPUT_HapticOpenFromDevice(SDL_Haptic * haptic, LPDIRECTINPUTDEVICE8 device haptic->supported |= SDL_HAPTIC_STATUS | SDL_HAPTIC_PAUSE; /* Check maximum effects. */ - haptic->neffects = 128; /* This is not actually supported as thus under windows, - there is no way to tell the number of EFFECTS that a - device can hold, so we'll just use a "random" number - instead and put warnings in SDL_haptic.h */ - haptic->nplaying = 128; /* Even more impossible to get this then neffects. */ + haptic->neffects = 128; /* This is not actually supported as thus under windows, + there is no way to tell the number of EFFECTS that a + device can hold, so we'll just use a "random" number + instead and put warnings in SDL_haptic.h */ + haptic->nplaying = 128; /* Even more impossible to get this then neffects. */ /* Prepare effects memory. */ haptic->effects = (struct haptic_effect *) SDL_malloc(sizeof(struct haptic_effect) * haptic->neffects); - if (haptic->effects == NULL) { + if (!haptic->effects) { SDL_OutOfMemory(); goto acquire_err; } @@ -413,46 +418,32 @@ SDL_DINPUT_HapticOpenFromDevice(SDL_Haptic * haptic, LPDIRECTINPUTDEVICE8 device return 0; /* Error handling */ - acquire_err: +acquire_err: IDirectInputDevice8_Unacquire(haptic->hwdata->device); return -1; } -int -SDL_DINPUT_HapticOpen(SDL_Haptic * haptic, SDL_hapticlist_item *item) +int SDL_DINPUT_HapticOpen(SDL_Haptic *haptic, SDL_hapticlist_item *item) { HRESULT ret; LPDIRECTINPUTDEVICE8 device; - LPDIRECTINPUTDEVICE8 device8; /* Open the device */ ret = IDirectInput8_CreateDevice(dinput, &item->instance.guidInstance, - &device, NULL); + &device, NULL); if (FAILED(ret)) { DI_SetError("Creating DirectInput device", ret); return -1; } - /* Now get the IDirectInputDevice8 interface, instead. */ - ret = IDirectInputDevice8_QueryInterface(device, - &IID_IDirectInputDevice8, - (LPVOID *)&device8); - /* Done with the temporary one now. */ - IDirectInputDevice8_Release(device); - if (FAILED(ret)) { - DI_SetError("Querying DirectInput interface", ret); - return -1; - } - - if (SDL_DINPUT_HapticOpenFromDevice(haptic, device8, SDL_FALSE) < 0) { - IDirectInputDevice8_Release(device8); + if (SDL_DINPUT_HapticOpenFromDevice(haptic, device, SDL_FALSE) < 0) { + IDirectInputDevice8_Release(device); return -1; } return 0; } -int -SDL_DINPUT_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick) +int SDL_DINPUT_JoystickSameHaptic(SDL_Haptic *haptic, SDL_Joystick *joystick) { HRESULT ret; DIDEVICEINSTANCE hap_instance, joy_instance; @@ -462,12 +453,12 @@ SDL_DINPUT_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick) /* Get the device instances. */ ret = IDirectInputDevice8_GetDeviceInfo(haptic->hwdata->device, - &hap_instance); + &hap_instance); if (FAILED(ret)) { return 0; } ret = IDirectInputDevice8_GetDeviceInfo(joystick->hwdata->InputDevice, - &joy_instance); + &joy_instance); if (FAILED(ret)) { return 0; } @@ -475,8 +466,7 @@ SDL_DINPUT_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick) return WIN_IsEqualGUID(&hap_instance.guidInstance, &joy_instance.guidInstance); } -int -SDL_DINPUT_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick) +int SDL_DINPUT_HapticOpenFromJoystick(SDL_Haptic *haptic, SDL_Joystick *joystick) { SDL_hapticlist_item *item; int index = 0; @@ -490,7 +480,7 @@ SDL_DINPUT_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick) } /* Since it comes from a joystick we have to try to match it with a haptic device on our haptic list. */ - for (item = SDL_hapticlist; item != NULL; item = item->next) { + for (item = SDL_hapticlist; item; item = item->next) { if (!item->bXInputHaptic && WIN_IsEqualGUID(&item->instance.guidInstance, &joy_instance.guidInstance)) { haptic->index = index; return SDL_DINPUT_HapticOpenFromDevice(haptic, joystick->hwdata->InputDevice, SDL_TRUE); @@ -498,12 +488,10 @@ SDL_DINPUT_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick) ++index; } - SDL_SetError("Couldn't find joystick in haptic device list"); - return -1; + return SDL_SetError("Couldn't find joystick in haptic device list"); } -void -SDL_DINPUT_HapticClose(SDL_Haptic * haptic) +void SDL_DINPUT_HapticClose(SDL_Haptic *haptic) { IDirectInputDevice8_Unacquire(haptic->hwdata->device); @@ -513,8 +501,7 @@ SDL_DINPUT_HapticClose(SDL_Haptic * haptic) } } -void -SDL_DINPUT_HapticQuit(void) +void SDL_DINPUT_HapticQuit(void) { if (dinput != NULL) { IDirectInput8_Release(dinput); @@ -530,8 +517,7 @@ SDL_DINPUT_HapticQuit(void) /* * Converts an SDL trigger button to an DIEFFECT trigger button. */ -static DWORD -DIGetTriggerButton(Uint16 button) +static DWORD DIGetTriggerButton(Uint16 button) { DWORD dwTriggerButton; @@ -544,25 +530,23 @@ DIGetTriggerButton(Uint16 button) return dwTriggerButton; } - /* * Sets the direction. */ -static int -SDL_SYS_SetDirection(DIEFFECT * effect, SDL_HapticDirection * dir, int naxes) +static int SDL_SYS_SetDirection(DIEFFECT *effect, SDL_HapticDirection *dir, int naxes) { LONG *rglDir; /* Handle no axes a part. */ if (naxes == 0) { - effect->dwFlags |= DIEFF_SPHERICAL; /* Set as default. */ + effect->dwFlags |= DIEFF_SPHERICAL; /* Set as default. */ effect->rglDirection = NULL; return 0; } /* Has axes. */ rglDir = SDL_malloc(sizeof(LONG) * naxes); - if (rglDir == NULL) { + if (!rglDir) { return SDL_OutOfMemory(); } SDL_memset(rglDir, 0, sizeof(LONG) * naxes); @@ -576,18 +560,26 @@ SDL_SYS_SetDirection(DIEFFECT * effect, SDL_HapticDirection * dir, int naxes) case SDL_HAPTIC_CARTESIAN: effect->dwFlags |= DIEFF_CARTESIAN; rglDir[0] = dir->dir[0]; - if (naxes > 1) + if (naxes > 1) { rglDir[1] = dir->dir[1]; - if (naxes > 2) + } + if (naxes > 2) { rglDir[2] = dir->dir[2]; + } return 0; case SDL_HAPTIC_SPHERICAL: effect->dwFlags |= DIEFF_SPHERICAL; rglDir[0] = dir->dir[0]; - if (naxes > 1) + if (naxes > 1) { rglDir[1] = dir->dir[1]; - if (naxes > 2) + } + if (naxes > 2) { rglDir[2] = dir->dir[2]; + } + return 0; + case SDL_HAPTIC_STEERING_AXIS: + effect->dwFlags |= DIEFF_CARTESIAN; + rglDir[0] = 0; return 0; default: @@ -596,20 +588,19 @@ SDL_SYS_SetDirection(DIEFFECT * effect, SDL_HapticDirection * dir, int naxes) } /* Clamps and converts. */ -#define CCONVERT(x) (((x) > 0x7FFF) ? 10000 : ((x)*10000) / 0x7FFF) +#define CCONVERT(x) (((x) > 0x7FFF) ? 10000 : ((x)*10000) / 0x7FFF) /* Just converts. */ -#define CONVERT(x) (((x)*10000) / 0x7FFF) +#define CONVERT(x) (((x)*10000) / 0x7FFF) /* * Creates the DIEFFECT from a SDL_HapticEffect. */ -static int -SDL_SYS_ToDIEFFECT(SDL_Haptic * haptic, DIEFFECT * dest, - SDL_HapticEffect * src) +static int SDL_SYS_ToDIEFFECT(SDL_Haptic *haptic, DIEFFECT *dest, + SDL_HapticEffect *src) { int i; DICONSTANTFORCE *constant; DIPERIODIC *periodic; - DICONDITION *condition; /* Actually an array of conditions - one per axis. */ + DICONDITION *condition; /* Actually an array of conditions - one per axis. */ DIRAMPFORCE *ramp; DICUSTOMFORCE *custom; DIENVELOPE *envelope; @@ -622,28 +613,32 @@ SDL_SYS_ToDIEFFECT(SDL_Haptic * haptic, DIEFFECT * dest, /* Set global stuff. */ SDL_memset(dest, 0, sizeof(DIEFFECT)); - dest->dwSize = sizeof(DIEFFECT); /* Set the structure size. */ - dest->dwSamplePeriod = 0; /* Not used by us. */ - dest->dwGain = 10000; /* Gain is set globally, not locally. */ - dest->dwFlags = DIEFF_OBJECTOFFSETS; /* Seems obligatory. */ + dest->dwSize = sizeof(DIEFFECT); /* Set the structure size. */ + dest->dwSamplePeriod = 0; /* Not used by us. */ + dest->dwGain = 10000; /* Gain is set globally, not locally. */ + dest->dwFlags = DIEFF_OBJECTOFFSETS; /* Seems obligatory. */ /* Envelope. */ envelope = SDL_malloc(sizeof(DIENVELOPE)); - if (envelope == NULL) { + if (!envelope) { return SDL_OutOfMemory(); } SDL_memset(envelope, 0, sizeof(DIENVELOPE)); dest->lpEnvelope = envelope; - envelope->dwSize = sizeof(DIENVELOPE); /* Always should be this. */ + envelope->dwSize = sizeof(DIENVELOPE); /* Always should be this. */ /* Axes. */ - dest->cAxes = haptic->naxes; + if (src->constant.direction.type == SDL_HAPTIC_STEERING_AXIS) { + dest->cAxes = 1; + } else { + dest->cAxes = haptic->naxes; + } if (dest->cAxes > 0) { axes = SDL_malloc(sizeof(DWORD) * dest->cAxes); - if (axes == NULL) { + if (!axes) { return SDL_OutOfMemory(); } - axes[0] = haptic->hwdata->axes[0]; /* Always at least one axis. */ + axes[0] = haptic->hwdata->axes[0]; /* Always at least one axis. */ if (dest->cAxes > 1) { axes[1] = haptic->hwdata->axes[1]; } @@ -658,7 +653,7 @@ SDL_SYS_ToDIEFFECT(SDL_Haptic * haptic, DIEFFECT * dest, case SDL_HAPTIC_CONSTANT: hap_constant = &src->constant; constant = SDL_malloc(sizeof(DICONSTANTFORCE)); - if (constant == NULL) { + if (!constant) { return SDL_OutOfMemory(); } SDL_memset(constant, 0, sizeof(DICONSTANTFORCE)); @@ -669,10 +664,10 @@ SDL_SYS_ToDIEFFECT(SDL_Haptic * haptic, DIEFFECT * dest, dest->lpvTypeSpecificParams = constant; /* Generics */ - dest->dwDuration = hap_constant->length * 1000; /* In microseconds. */ + dest->dwDuration = hap_constant->length * 1000UL; /* In microseconds. */ dest->dwTriggerButton = DIGetTriggerButton(hap_constant->button); dest->dwTriggerRepeatInterval = hap_constant->interval; - dest->dwStartDelay = hap_constant->delay * 1000; /* In microseconds. */ + dest->dwStartDelay = hap_constant->delay * 1000UL; /* In microseconds. */ /* Direction. */ if (SDL_SYS_SetDirection(dest, &hap_constant->direction, dest->cAxes) < 0) { @@ -680,15 +675,14 @@ SDL_SYS_ToDIEFFECT(SDL_Haptic * haptic, DIEFFECT * dest, } /* Envelope */ - if ((hap_constant->attack_length == 0) - && (hap_constant->fade_length == 0)) { + if ((hap_constant->attack_length == 0) && (hap_constant->fade_length == 0)) { SDL_free(dest->lpEnvelope); dest->lpEnvelope = NULL; } else { envelope->dwAttackLevel = CCONVERT(hap_constant->attack_level); - envelope->dwAttackTime = hap_constant->attack_length * 1000; + envelope->dwAttackTime = hap_constant->attack_length * 1000UL; envelope->dwFadeLevel = CCONVERT(hap_constant->fade_level); - envelope->dwFadeTime = hap_constant->fade_length * 1000; + envelope->dwFadeTime = hap_constant->fade_length * 1000UL; } break; @@ -701,7 +695,7 @@ SDL_SYS_ToDIEFFECT(SDL_Haptic * haptic, DIEFFECT * dest, case SDL_HAPTIC_SAWTOOTHDOWN: hap_periodic = &src->periodic; periodic = SDL_malloc(sizeof(DIPERIODIC)); - if (periodic == NULL) { + if (!periodic) { return SDL_OutOfMemory(); } SDL_memset(periodic, 0, sizeof(DIPERIODIC)); @@ -709,34 +703,32 @@ SDL_SYS_ToDIEFFECT(SDL_Haptic * haptic, DIEFFECT * dest, /* Specifics */ periodic->dwMagnitude = CONVERT(SDL_abs(hap_periodic->magnitude)); periodic->lOffset = CONVERT(hap_periodic->offset); - periodic->dwPhase = - (hap_periodic->phase + (hap_periodic->magnitude < 0 ? 18000 : 0)) % 36000; + periodic->dwPhase = + (hap_periodic->phase + (hap_periodic->magnitude < 0 ? 18000 : 0)) % 36000; periodic->dwPeriod = hap_periodic->period * 1000; dest->cbTypeSpecificParams = sizeof(DIPERIODIC); dest->lpvTypeSpecificParams = periodic; /* Generics */ - dest->dwDuration = hap_periodic->length * 1000; /* In microseconds. */ + dest->dwDuration = hap_periodic->length * 1000UL; /* In microseconds. */ dest->dwTriggerButton = DIGetTriggerButton(hap_periodic->button); dest->dwTriggerRepeatInterval = hap_periodic->interval; - dest->dwStartDelay = hap_periodic->delay * 1000; /* In microseconds. */ + dest->dwStartDelay = hap_periodic->delay * 1000UL; /* In microseconds. */ /* Direction. */ - if (SDL_SYS_SetDirection(dest, &hap_periodic->direction, dest->cAxes) - < 0) { + if (SDL_SYS_SetDirection(dest, &hap_periodic->direction, dest->cAxes) < 0) { return -1; } /* Envelope */ - if ((hap_periodic->attack_length == 0) - && (hap_periodic->fade_length == 0)) { + if ((hap_periodic->attack_length == 0) && (hap_periodic->fade_length == 0)) { SDL_free(dest->lpEnvelope); dest->lpEnvelope = NULL; } else { envelope->dwAttackLevel = CCONVERT(hap_periodic->attack_level); - envelope->dwAttackTime = hap_periodic->attack_length * 1000; + envelope->dwAttackTime = hap_periodic->attack_length * 1000UL; envelope->dwFadeLevel = CCONVERT(hap_periodic->fade_level); - envelope->dwFadeTime = hap_periodic->fade_length * 1000; + envelope->dwFadeTime = hap_periodic->fade_length * 1000UL; } break; @@ -747,13 +739,13 @@ SDL_SYS_ToDIEFFECT(SDL_Haptic * haptic, DIEFFECT * dest, case SDL_HAPTIC_FRICTION: hap_condition = &src->condition; condition = SDL_malloc(sizeof(DICONDITION) * dest->cAxes); - if (condition == NULL) { + if (!condition) { return SDL_OutOfMemory(); } SDL_memset(condition, 0, sizeof(DICONDITION)); /* Specifics */ - for (i = 0; i < (int) dest->cAxes; i++) { + for (i = 0; i < (int)dest->cAxes; i++) { condition[i].lOffset = CONVERT(hap_condition->center[i]); condition[i].lPositiveCoefficient = CONVERT(hap_condition->right_coeff[i]); @@ -769,14 +761,13 @@ SDL_SYS_ToDIEFFECT(SDL_Haptic * haptic, DIEFFECT * dest, dest->lpvTypeSpecificParams = condition; /* Generics */ - dest->dwDuration = hap_condition->length * 1000; /* In microseconds. */ + dest->dwDuration = hap_condition->length * 1000UL; /* In microseconds. */ dest->dwTriggerButton = DIGetTriggerButton(hap_condition->button); dest->dwTriggerRepeatInterval = hap_condition->interval; - dest->dwStartDelay = hap_condition->delay * 1000; /* In microseconds. */ + dest->dwStartDelay = hap_condition->delay * 1000UL; /* In microseconds. */ /* Direction. */ - if (SDL_SYS_SetDirection(dest, &hap_condition->direction, dest->cAxes) - < 0) { + if (SDL_SYS_SetDirection(dest, &hap_condition->direction, dest->cAxes) < 0) { return -1; } @@ -789,7 +780,7 @@ SDL_SYS_ToDIEFFECT(SDL_Haptic * haptic, DIEFFECT * dest, case SDL_HAPTIC_RAMP: hap_ramp = &src->ramp; ramp = SDL_malloc(sizeof(DIRAMPFORCE)); - if (ramp == NULL) { + if (!ramp) { return SDL_OutOfMemory(); } SDL_memset(ramp, 0, sizeof(DIRAMPFORCE)); @@ -801,10 +792,10 @@ SDL_SYS_ToDIEFFECT(SDL_Haptic * haptic, DIEFFECT * dest, dest->lpvTypeSpecificParams = ramp; /* Generics */ - dest->dwDuration = hap_ramp->length * 1000; /* In microseconds. */ + dest->dwDuration = hap_ramp->length * 1000UL; /* In microseconds. */ dest->dwTriggerButton = DIGetTriggerButton(hap_ramp->button); dest->dwTriggerRepeatInterval = hap_ramp->interval; - dest->dwStartDelay = hap_ramp->delay * 1000; /* In microseconds. */ + dest->dwStartDelay = hap_ramp->delay * 1000UL; /* In microseconds. */ /* Direction. */ if (SDL_SYS_SetDirection(dest, &hap_ramp->direction, dest->cAxes) < 0) { @@ -817,9 +808,9 @@ SDL_SYS_ToDIEFFECT(SDL_Haptic * haptic, DIEFFECT * dest, dest->lpEnvelope = NULL; } else { envelope->dwAttackLevel = CCONVERT(hap_ramp->attack_level); - envelope->dwAttackTime = hap_ramp->attack_length * 1000; + envelope->dwAttackTime = hap_ramp->attack_length * 1000UL; envelope->dwFadeLevel = CCONVERT(hap_ramp->fade_level); - envelope->dwFadeTime = hap_ramp->fade_length * 1000; + envelope->dwFadeTime = hap_ramp->fade_length * 1000UL; } break; @@ -827,28 +818,28 @@ SDL_SYS_ToDIEFFECT(SDL_Haptic * haptic, DIEFFECT * dest, case SDL_HAPTIC_CUSTOM: hap_custom = &src->custom; custom = SDL_malloc(sizeof(DICUSTOMFORCE)); - if (custom == NULL) { + if (!custom) { return SDL_OutOfMemory(); } SDL_memset(custom, 0, sizeof(DICUSTOMFORCE)); /* Specifics */ custom->cChannels = hap_custom->channels; - custom->dwSamplePeriod = hap_custom->period * 1000; + custom->dwSamplePeriod = hap_custom->period * 1000UL; custom->cSamples = hap_custom->samples; custom->rglForceData = SDL_malloc(sizeof(LONG) * custom->cSamples * custom->cChannels); - for (i = 0; i < hap_custom->samples * hap_custom->channels; i++) { /* Copy data. */ + for (i = 0; i < hap_custom->samples * hap_custom->channels; i++) { /* Copy data. */ custom->rglForceData[i] = CCONVERT(hap_custom->data[i]); } dest->cbTypeSpecificParams = sizeof(DICUSTOMFORCE); dest->lpvTypeSpecificParams = custom; /* Generics */ - dest->dwDuration = hap_custom->length * 1000; /* In microseconds. */ + dest->dwDuration = hap_custom->length * 1000UL; /* In microseconds. */ dest->dwTriggerButton = DIGetTriggerButton(hap_custom->button); dest->dwTriggerRepeatInterval = hap_custom->interval; - dest->dwStartDelay = hap_custom->delay * 1000; /* In microseconds. */ + dest->dwStartDelay = hap_custom->delay * 1000UL; /* In microseconds. */ /* Direction. */ if (SDL_SYS_SetDirection(dest, &hap_custom->direction, dest->cAxes) < 0) { @@ -856,15 +847,14 @@ SDL_SYS_ToDIEFFECT(SDL_Haptic * haptic, DIEFFECT * dest, } /* Envelope */ - if ((hap_custom->attack_length == 0) - && (hap_custom->fade_length == 0)) { + if ((hap_custom->attack_length == 0) && (hap_custom->fade_length == 0)) { SDL_free(dest->lpEnvelope); dest->lpEnvelope = NULL; } else { envelope->dwAttackLevel = CCONVERT(hap_custom->attack_level); - envelope->dwAttackTime = hap_custom->attack_length * 1000; + envelope->dwAttackTime = hap_custom->attack_length * 1000UL; envelope->dwFadeLevel = CCONVERT(hap_custom->fade_level); - envelope->dwFadeTime = hap_custom->fade_length * 1000; + envelope->dwFadeTime = hap_custom->fade_length * 1000UL; } break; @@ -876,12 +866,10 @@ SDL_SYS_ToDIEFFECT(SDL_Haptic * haptic, DIEFFECT * dest, return 0; } - /* * Frees an DIEFFECT allocated by SDL_SYS_ToDIEFFECT. */ -static void -SDL_SYS_HapticFreeDIEFFECT(DIEFFECT * effect, int type) +static void SDL_SYS_HapticFreeDIEFFECT(DIEFFECT *effect, int type) { DICUSTOMFORCE *custom; @@ -889,9 +877,9 @@ SDL_SYS_HapticFreeDIEFFECT(DIEFFECT * effect, int type) effect->lpEnvelope = NULL; SDL_free(effect->rgdwAxes); effect->rgdwAxes = NULL; - if (effect->lpvTypeSpecificParams != NULL) { - if (type == SDL_HAPTIC_CUSTOM) { /* Must free the custom data. */ - custom = (DICUSTOMFORCE *) effect->lpvTypeSpecificParams; + if (effect->lpvTypeSpecificParams) { + if (type == SDL_HAPTIC_CUSTOM) { /* Must free the custom data. */ + custom = (DICUSTOMFORCE *)effect->lpvTypeSpecificParams; SDL_free(custom->rglForceData); custom->rglForceData = NULL; } @@ -905,8 +893,8 @@ SDL_SYS_HapticFreeDIEFFECT(DIEFFECT * effect, int type) /* * Gets the effect type from the generic SDL haptic effect wrapper. */ -static REFGUID -SDL_SYS_HapticEffectType(SDL_HapticEffect * effect) +/* NOLINTNEXTLINE(readability-const-return-type): Can't fix Windows' headers */ +static REFGUID SDL_SYS_HapticEffectType(SDL_HapticEffect *effect) { switch (effect->type) { case SDL_HAPTIC_CONSTANT: @@ -915,9 +903,9 @@ SDL_SYS_HapticEffectType(SDL_HapticEffect * effect) case SDL_HAPTIC_RAMP: return &GUID_RampForce; - /* !!! FIXME: put this back when we have more bits in 2.1 */ - /* case SDL_HAPTIC_SQUARE: - return &GUID_Square; */ + /* !!! FIXME: put this back when we have more bits in 2.1 */ + /* case SDL_HAPTIC_SQUARE: + return &GUID_Square; */ case SDL_HAPTIC_SINE: return &GUID_Sine; @@ -950,15 +938,13 @@ SDL_SYS_HapticEffectType(SDL_HapticEffect * effect) return NULL; } } -int -SDL_DINPUT_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect *effect, SDL_HapticEffect * base) +int SDL_DINPUT_HapticNewEffect(SDL_Haptic *haptic, struct haptic_effect *effect, SDL_HapticEffect *base) { HRESULT ret; REFGUID type = SDL_SYS_HapticEffectType(base); - if (type == NULL) { - SDL_SetError("Haptic: Unknown effect type."); - return -1; + if (!type) { + return SDL_SetError("Haptic: Unknown effect type."); } /* Get the effect. */ @@ -968,8 +954,8 @@ SDL_DINPUT_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect *effect, SD /* Create the actual effect. */ ret = IDirectInputDevice8_CreateEffect(haptic->hwdata->device, type, - &effect->hweffect->effect, - &effect->hweffect->ref, NULL); + &effect->hweffect->effect, + &effect->hweffect->ref, NULL); if (FAILED(ret)) { DI_SetError("Unable to create effect", ret); goto err_effectdone; @@ -982,8 +968,7 @@ err_effectdone: return -1; } -int -SDL_DINPUT_HapticUpdateEffect(SDL_Haptic * haptic, struct haptic_effect *effect, SDL_HapticEffect * data) +int SDL_DINPUT_HapticUpdateEffect(SDL_Haptic *haptic, struct haptic_effect *effect, SDL_HapticEffect *data) { HRESULT ret; DWORD flags; @@ -996,13 +981,13 @@ SDL_DINPUT_HapticUpdateEffect(SDL_Haptic * haptic, struct haptic_effect *effect, } /* Set the flags. Might be worthwhile to diff temp with loaded effect and - * only change those parameters. */ + * only change those parameters. */ flags = DIEP_DIRECTION | - DIEP_DURATION | - DIEP_ENVELOPE | - DIEP_STARTDELAY | - DIEP_TRIGGERBUTTON | - DIEP_TRIGGERREPEATINTERVAL | DIEP_TYPESPECIFICPARAMS; + DIEP_DURATION | + DIEP_ENVELOPE | + DIEP_STARTDELAY | + DIEP_TRIGGERBUTTON | + DIEP_TRIGGERREPEATINTERVAL | DIEP_TYPESPECIFICPARAMS; /* Create the actual effect. */ ret = @@ -1036,8 +1021,7 @@ err_update: return -1; } -int -SDL_DINPUT_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect, Uint32 iterations) +int SDL_DINPUT_HapticRunEffect(SDL_Haptic *haptic, struct haptic_effect *effect, Uint32 iterations) { HRESULT ret; DWORD iter; @@ -1057,8 +1041,7 @@ SDL_DINPUT_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect, Ui return 0; } -int -SDL_DINPUT_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect *effect) +int SDL_DINPUT_HapticStopEffect(SDL_Haptic *haptic, struct haptic_effect *effect) { HRESULT ret; @@ -1069,8 +1052,7 @@ SDL_DINPUT_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect *effect) return 0; } -void -SDL_DINPUT_HapticDestroyEffect(SDL_Haptic * haptic, struct haptic_effect *effect) +void SDL_DINPUT_HapticDestroyEffect(SDL_Haptic *haptic, struct haptic_effect *effect) { HRESULT ret; @@ -1081,8 +1063,7 @@ SDL_DINPUT_HapticDestroyEffect(SDL_Haptic * haptic, struct haptic_effect *effect SDL_SYS_HapticFreeDIEFFECT(&effect->hweffect->effect, effect->effect.type); } -int -SDL_DINPUT_HapticGetEffectStatus(SDL_Haptic * haptic, struct haptic_effect *effect) +int SDL_DINPUT_HapticGetEffectStatus(SDL_Haptic *haptic, struct haptic_effect *effect) { HRESULT ret; DWORD status; @@ -1092,13 +1073,13 @@ SDL_DINPUT_HapticGetEffectStatus(SDL_Haptic * haptic, struct haptic_effect *effe return DI_SetError("Getting effect status", ret); } - if (status == 0) + if (status == 0) { return SDL_FALSE; + } return SDL_TRUE; } -int -SDL_DINPUT_HapticSetGain(SDL_Haptic * haptic, int gain) +int SDL_DINPUT_HapticSetGain(SDL_Haptic *haptic, int gain) { HRESULT ret; DIPROPDWORD dipdw; @@ -1108,19 +1089,18 @@ SDL_DINPUT_HapticSetGain(SDL_Haptic * haptic, int gain) dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); dipdw.diph.dwObj = 0; dipdw.diph.dwHow = DIPH_DEVICE; - dipdw.dwData = gain * 100; /* 0 to 10,000 */ + dipdw.dwData = (DWORD)gain * 100; /* 0 to 10,000 */ /* Try to set the autocenter. */ ret = IDirectInputDevice8_SetProperty(haptic->hwdata->device, - DIPROP_FFGAIN, &dipdw.diph); + DIPROP_FFGAIN, &dipdw.diph); if (FAILED(ret)) { return DI_SetError("Setting gain", ret); } return 0; } -int -SDL_DINPUT_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter) +int SDL_DINPUT_HapticSetAutocenter(SDL_Haptic *haptic, int autocenter) { HRESULT ret; DIPROPDWORD dipdw; @@ -1130,54 +1110,50 @@ SDL_DINPUT_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter) dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); dipdw.diph.dwObj = 0; dipdw.diph.dwHow = DIPH_DEVICE; - dipdw.dwData = (autocenter == 0) ? DIPROPAUTOCENTER_OFF : - DIPROPAUTOCENTER_ON; + dipdw.dwData = (autocenter == 0) ? DIPROPAUTOCENTER_OFF : DIPROPAUTOCENTER_ON; /* Try to set the autocenter. */ ret = IDirectInputDevice8_SetProperty(haptic->hwdata->device, - DIPROP_AUTOCENTER, &dipdw.diph); + DIPROP_AUTOCENTER, &dipdw.diph); if (FAILED(ret)) { return DI_SetError("Setting autocenter", ret); } return 0; } -int -SDL_DINPUT_HapticPause(SDL_Haptic * haptic) +int SDL_DINPUT_HapticPause(SDL_Haptic *haptic) { HRESULT ret; /* Pause the device. */ ret = IDirectInputDevice8_SendForceFeedbackCommand(haptic->hwdata->device, - DISFFC_PAUSE); + DISFFC_PAUSE); if (FAILED(ret)) { return DI_SetError("Pausing the device", ret); } return 0; } -int -SDL_DINPUT_HapticUnpause(SDL_Haptic * haptic) +int SDL_DINPUT_HapticUnpause(SDL_Haptic *haptic) { HRESULT ret; /* Unpause the device. */ ret = IDirectInputDevice8_SendForceFeedbackCommand(haptic->hwdata->device, - DISFFC_CONTINUE); + DISFFC_CONTINUE); if (FAILED(ret)) { return DI_SetError("Pausing the device", ret); } return 0; } -int -SDL_DINPUT_HapticStopAll(SDL_Haptic * haptic) +int SDL_DINPUT_HapticStopAll(SDL_Haptic *haptic) { HRESULT ret; /* Try to stop the effects. */ ret = IDirectInputDevice8_SendForceFeedbackCommand(haptic->hwdata->device, - DISFFC_STOPALL); + DISFFC_STOPALL); if (FAILED(ret)) { return DI_SetError("Stopping the device", ret); } @@ -1189,113 +1165,94 @@ SDL_DINPUT_HapticStopAll(SDL_Haptic * haptic) typedef struct DIDEVICEINSTANCE DIDEVICEINSTANCE; typedef struct SDL_hapticlist_item SDL_hapticlist_item; -int -SDL_DINPUT_HapticInit(void) +int SDL_DINPUT_HapticInit(void) { return 0; } -int -SDL_DINPUT_MaybeAddDevice(const DIDEVICEINSTANCE * pdidInstance) +int SDL_DINPUT_HapticMaybeAddDevice(const DIDEVICEINSTANCE *pdidInstance) { return SDL_Unsupported(); } -int -SDL_DINPUT_MaybeRemoveDevice(const DIDEVICEINSTANCE * pdidInstance) +int SDL_DINPUT_HapticMaybeRemoveDevice(const DIDEVICEINSTANCE *pdidInstance) { return SDL_Unsupported(); } -int -SDL_DINPUT_HapticOpen(SDL_Haptic * haptic, SDL_hapticlist_item *item) +int SDL_DINPUT_HapticOpen(SDL_Haptic *haptic, SDL_hapticlist_item *item) { return SDL_Unsupported(); } -int -SDL_DINPUT_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick) +int SDL_DINPUT_JoystickSameHaptic(SDL_Haptic *haptic, SDL_Joystick *joystick) { return SDL_Unsupported(); } -int -SDL_DINPUT_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick) +int SDL_DINPUT_HapticOpenFromJoystick(SDL_Haptic *haptic, SDL_Joystick *joystick) { return SDL_Unsupported(); } -void -SDL_DINPUT_HapticClose(SDL_Haptic * haptic) +void SDL_DINPUT_HapticClose(SDL_Haptic *haptic) { } -void -SDL_DINPUT_HapticQuit(void) +void SDL_DINPUT_HapticQuit(void) { } -int -SDL_DINPUT_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect *effect, SDL_HapticEffect * base) +int SDL_DINPUT_HapticNewEffect(SDL_Haptic *haptic, struct haptic_effect *effect, SDL_HapticEffect *base) { return SDL_Unsupported(); } -int -SDL_DINPUT_HapticUpdateEffect(SDL_Haptic * haptic, struct haptic_effect *effect, SDL_HapticEffect * data) +int SDL_DINPUT_HapticUpdateEffect(SDL_Haptic *haptic, struct haptic_effect *effect, SDL_HapticEffect *data) { return SDL_Unsupported(); } -int -SDL_DINPUT_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect, Uint32 iterations) +int SDL_DINPUT_HapticRunEffect(SDL_Haptic *haptic, struct haptic_effect *effect, Uint32 iterations) { return SDL_Unsupported(); } -int -SDL_DINPUT_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect *effect) +int SDL_DINPUT_HapticStopEffect(SDL_Haptic *haptic, struct haptic_effect *effect) { return SDL_Unsupported(); } -void -SDL_DINPUT_HapticDestroyEffect(SDL_Haptic * haptic, struct haptic_effect *effect) +void SDL_DINPUT_HapticDestroyEffect(SDL_Haptic *haptic, struct haptic_effect *effect) { } -int -SDL_DINPUT_HapticGetEffectStatus(SDL_Haptic * haptic, struct haptic_effect *effect) +int SDL_DINPUT_HapticGetEffectStatus(SDL_Haptic *haptic, struct haptic_effect *effect) { return SDL_Unsupported(); } -int -SDL_DINPUT_HapticSetGain(SDL_Haptic * haptic, int gain) +int SDL_DINPUT_HapticSetGain(SDL_Haptic *haptic, int gain) { return SDL_Unsupported(); } -int -SDL_DINPUT_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter) +int SDL_DINPUT_HapticSetAutocenter(SDL_Haptic *haptic, int autocenter) { return SDL_Unsupported(); } -int -SDL_DINPUT_HapticPause(SDL_Haptic * haptic) +int SDL_DINPUT_HapticPause(SDL_Haptic *haptic) { return SDL_Unsupported(); } -int -SDL_DINPUT_HapticUnpause(SDL_Haptic * haptic) +int SDL_DINPUT_HapticUnpause(SDL_Haptic *haptic) { return SDL_Unsupported(); } -int -SDL_DINPUT_HapticStopAll(SDL_Haptic * haptic) +int SDL_DINPUT_HapticStopAll(SDL_Haptic *haptic) { return SDL_Unsupported(); } diff --git a/SDL2-2.30.5/src/haptic/windows/SDL_dinputhaptic_c.h b/SDL2-2.30.5/src/haptic/windows/SDL_dinputhaptic_c.h new file mode 100644 index 0000000..b84fd71 --- /dev/null +++ b/SDL2-2.30.5/src/haptic/windows/SDL_dinputhaptic_c.h @@ -0,0 +1,56 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_haptic.h" +#include "SDL_windowshaptic_c.h" + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +extern int SDL_DINPUT_HapticInit(void); +extern int SDL_DINPUT_HapticMaybeAddDevice(const DIDEVICEINSTANCE *pdidInstance); +extern int SDL_DINPUT_HapticMaybeRemoveDevice(const DIDEVICEINSTANCE *pdidInstance); +extern int SDL_DINPUT_HapticOpen(SDL_Haptic *haptic, SDL_hapticlist_item *item); +extern int SDL_DINPUT_JoystickSameHaptic(SDL_Haptic *haptic, SDL_Joystick *joystick); +extern int SDL_DINPUT_HapticOpenFromJoystick(SDL_Haptic *haptic, SDL_Joystick *joystick); +extern void SDL_DINPUT_HapticClose(SDL_Haptic *haptic); +extern void SDL_DINPUT_HapticQuit(void); +extern int SDL_DINPUT_HapticNewEffect(SDL_Haptic *haptic, struct haptic_effect *effect, SDL_HapticEffect *base); +extern int SDL_DINPUT_HapticUpdateEffect(SDL_Haptic *haptic, struct haptic_effect *effect, SDL_HapticEffect *data); +extern int SDL_DINPUT_HapticRunEffect(SDL_Haptic *haptic, struct haptic_effect *effect, Uint32 iterations); +extern int SDL_DINPUT_HapticStopEffect(SDL_Haptic *haptic, struct haptic_effect *effect); +extern void SDL_DINPUT_HapticDestroyEffect(SDL_Haptic *haptic, struct haptic_effect *effect); +extern int SDL_DINPUT_HapticGetEffectStatus(SDL_Haptic *haptic, struct haptic_effect *effect); +extern int SDL_DINPUT_HapticSetGain(SDL_Haptic *haptic, int gain); +extern int SDL_DINPUT_HapticSetAutocenter(SDL_Haptic *haptic, int autocenter); +extern int SDL_DINPUT_HapticPause(SDL_Haptic *haptic); +extern int SDL_DINPUT_HapticUnpause(SDL_Haptic *haptic); +extern int SDL_DINPUT_HapticStopAll(SDL_Haptic *haptic); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/haptic/windows/SDL_windowshaptic.c b/SDL2-2.30.5/src/haptic/windows/SDL_windowshaptic.c similarity index 76% rename from SDL2-2.0.12/src/haptic/windows/SDL_windowshaptic.c rename to SDL2-2.30.5/src/haptic/windows/SDL_windowshaptic.c index 6488d50..1992a06 100644 --- a/SDL2-2.0.12/src/haptic/windows/SDL_windowshaptic.c +++ b/SDL2-2.30.5/src/haptic/windows/SDL_windowshaptic.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,9 +20,8 @@ */ #include "../../SDL_internal.h" -#if SDL_HAPTIC_DINPUT || SDL_HAPTIC_XINPUT +#if defined(SDL_HAPTIC_DINPUT) || defined(SDL_HAPTIC_XINPUT) -#include "SDL_assert.h" #include "SDL_thread.h" #include "SDL_mutex.h" #include "SDL_timer.h" @@ -38,6 +37,10 @@ #include "SDL_dinputhaptic_c.h" #include "SDL_xinputhaptic_c.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif /* * Internal stuff. @@ -46,26 +49,39 @@ SDL_hapticlist_item *SDL_hapticlist = NULL; static SDL_hapticlist_item *SDL_hapticlist_tail = NULL; static int numhaptics = 0; - /* * Initializes the haptic subsystem. */ -int -SDL_SYS_HapticInit(void) +int SDL_SYS_HapticInit(void) { + JoyStick_DeviceData *device; + if (SDL_DINPUT_HapticInit() < 0) { return -1; } if (SDL_XINPUT_HapticInit() < 0) { return -1; } + + /* The joystick subsystem will usually be initialized before haptics, + * so the initial HapticMaybeAddDevice() calls from the joystick + * subsystem will arrive too early to create haptic devices. We will + * invoke those callbacks again here to pick up any joysticks that + * were added prior to haptics initialization. */ + for (device = SYS_Joystick; device; device = device->pNext) { + if (device->bXInputDevice) { + SDL_XINPUT_HapticMaybeAddDevice(device->XInputUserId); + } else { + SDL_DINPUT_HapticMaybeAddDevice(&device->dxdevice); + } + } + return numhaptics; } -int -SDL_SYS_AddHapticDevice(SDL_hapticlist_item *item) +int SDL_SYS_AddHapticDevice(SDL_hapticlist_item *item) { - if (SDL_hapticlist_tail == NULL) { + if (!SDL_hapticlist_tail) { SDL_hapticlist = SDL_hapticlist_tail = item; } else { SDL_hapticlist_tail->next = item; @@ -78,11 +94,10 @@ SDL_SYS_AddHapticDevice(SDL_hapticlist_item *item) return numhaptics; } -int -SDL_SYS_RemoveHapticDevice(SDL_hapticlist_item *prev, SDL_hapticlist_item *item) +int SDL_SYS_RemoveHapticDevice(SDL_hapticlist_item *prev, SDL_hapticlist_item *item) { const int retval = item->haptic ? item->haptic->index : -1; - if (prev != NULL) { + if (prev) { prev->next = item->next; } else { SDL_assert(SDL_hapticlist == item); @@ -97,14 +112,12 @@ SDL_SYS_RemoveHapticDevice(SDL_hapticlist_item *prev, SDL_hapticlist_item *item) return retval; } -int -SDL_SYS_NumHaptics(void) +int SDL_SYS_NumHaptics(void) { return numhaptics; } -static SDL_hapticlist_item * -HapticByDevIndex(int device_index) +static SDL_hapticlist_item *HapticByDevIndex(int device_index) { SDL_hapticlist_item *item = SDL_hapticlist; @@ -123,8 +136,7 @@ HapticByDevIndex(int device_index) /* * Return the name of a haptic device, does not need to be opened. */ -const char * -SDL_SYS_HapticName(int index) +const char *SDL_SYS_HapticName(int index) { SDL_hapticlist_item *item = HapticByDevIndex(index); return item->name; @@ -133,8 +145,7 @@ SDL_SYS_HapticName(int index) /* * Opens a haptic device for usage. */ -int -SDL_SYS_HapticOpen(SDL_Haptic * haptic) +int SDL_SYS_HapticOpen(SDL_Haptic *haptic) { SDL_hapticlist_item *item = HapticByDevIndex(haptic->index); if (item->bXInputHaptic) { @@ -144,19 +155,17 @@ SDL_SYS_HapticOpen(SDL_Haptic * haptic) } } - /* * Opens a haptic device from first mouse it finds for usage. */ -int -SDL_SYS_HapticMouse(void) +int SDL_SYS_HapticMouse(void) { -#if SDL_HAPTIC_DINPUT +#ifdef SDL_HAPTIC_DINPUT SDL_hapticlist_item *item; int index = 0; /* Grab the first mouse haptic device we find. */ - for (item = SDL_hapticlist; item != NULL; item = item->next) { + for (item = SDL_hapticlist; item; item = item->next) { if (item->capabilities.dwDevType == DI8DEVCLASS_POINTER) { return index; } @@ -166,22 +175,20 @@ SDL_SYS_HapticMouse(void) return -1; } - /* * Checks to see if a joystick has haptic features. */ -int -SDL_SYS_JoystickIsHaptic(SDL_Joystick * joystick) +int SDL_SYS_JoystickIsHaptic(SDL_Joystick *joystick) { if (joystick->driver != &SDL_WINDOWS_JoystickDriver) { return 0; } -#if SDL_HAPTIC_XINPUT +#ifdef SDL_HAPTIC_XINPUT if (joystick->hwdata->bXInputHaptic) { return 1; } #endif -#if SDL_HAPTIC_DINPUT +#ifdef SDL_HAPTIC_DINPUT if (joystick->hwdata->Capabilities.dwFlags & DIDC_FORCEFEEDBACK) { return 1; } @@ -192,14 +199,13 @@ SDL_SYS_JoystickIsHaptic(SDL_Joystick * joystick) /* * Checks to see if the haptic device and joystick are in reality the same. */ -int -SDL_SYS_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick) +int SDL_SYS_JoystickSameHaptic(SDL_Haptic *haptic, SDL_Joystick *joystick) { if (joystick->driver != &SDL_WINDOWS_JoystickDriver) { return 0; } if (joystick->hwdata->bXInputHaptic != haptic->hwdata->bXInputHaptic) { - return 0; /* one is XInput, one is not; not the same device. */ + return 0; /* one is XInput, one is not; not the same device. */ } else if (joystick->hwdata->bXInputHaptic) { return SDL_XINPUT_JoystickSameHaptic(haptic, joystick); } else { @@ -210,8 +216,7 @@ SDL_SYS_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick) /* * Opens a SDL_Haptic from a SDL_Joystick. */ -int -SDL_SYS_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick) +int SDL_SYS_HapticOpenFromJoystick(SDL_Haptic *haptic, SDL_Joystick *joystick) { SDL_assert(joystick->driver == &SDL_WINDOWS_JoystickDriver); @@ -225,8 +230,7 @@ SDL_SYS_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick) /* * Closes the haptic device. */ -void -SDL_SYS_HapticClose(SDL_Haptic * haptic) +void SDL_SYS_HapticClose(SDL_Haptic *haptic) { if (haptic->hwdata) { @@ -251,8 +255,7 @@ SDL_SYS_HapticClose(SDL_Haptic * haptic) /* * Clean up after system specific haptic stuff */ -void -SDL_SYS_HapticQuit(void) +void SDL_SYS_HapticQuit(void) { SDL_hapticlist_item *item; SDL_hapticlist_item *next = NULL; @@ -288,16 +291,15 @@ SDL_SYS_HapticQuit(void) /* * Creates a new haptic effect. */ -int -SDL_SYS_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect *effect, - SDL_HapticEffect * base) +int SDL_SYS_HapticNewEffect(SDL_Haptic *haptic, struct haptic_effect *effect, + SDL_HapticEffect *base) { int result; /* Alloc the effect. */ effect->hweffect = (struct haptic_hweffect *) SDL_malloc(sizeof(struct haptic_hweffect)); - if (effect->hweffect == NULL) { + if (!effect->hweffect) { SDL_OutOfMemory(); return -1; } @@ -318,10 +320,9 @@ SDL_SYS_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect *effect, /* * Updates an effect. */ -int -SDL_SYS_HapticUpdateEffect(SDL_Haptic * haptic, - struct haptic_effect *effect, - SDL_HapticEffect * data) +int SDL_SYS_HapticUpdateEffect(SDL_Haptic *haptic, + struct haptic_effect *effect, + SDL_HapticEffect *data) { if (haptic->hwdata->bXInputHaptic) { return SDL_XINPUT_HapticUpdateEffect(haptic, effect, data); @@ -333,9 +334,8 @@ SDL_SYS_HapticUpdateEffect(SDL_Haptic * haptic, /* * Runs an effect. */ -int -SDL_SYS_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect, - Uint32 iterations) +int SDL_SYS_HapticRunEffect(SDL_Haptic *haptic, struct haptic_effect *effect, + Uint32 iterations) { if (haptic->hwdata->bXInputHaptic) { return SDL_XINPUT_HapticRunEffect(haptic, effect, iterations); @@ -347,8 +347,7 @@ SDL_SYS_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect, /* * Stops an effect. */ -int -SDL_SYS_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect *effect) +int SDL_SYS_HapticStopEffect(SDL_Haptic *haptic, struct haptic_effect *effect) { if (haptic->hwdata->bXInputHaptic) { return SDL_XINPUT_HapticStopEffect(haptic, effect); @@ -360,8 +359,7 @@ SDL_SYS_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect *effect) /* * Frees the effect. */ -void -SDL_SYS_HapticDestroyEffect(SDL_Haptic * haptic, struct haptic_effect *effect) +void SDL_SYS_HapticDestroyEffect(SDL_Haptic *haptic, struct haptic_effect *effect) { if (haptic->hwdata->bXInputHaptic) { SDL_XINPUT_HapticDestroyEffect(haptic, effect); @@ -375,9 +373,8 @@ SDL_SYS_HapticDestroyEffect(SDL_Haptic * haptic, struct haptic_effect *effect) /* * Gets the status of a haptic effect. */ -int -SDL_SYS_HapticGetEffectStatus(SDL_Haptic * haptic, - struct haptic_effect *effect) +int SDL_SYS_HapticGetEffectStatus(SDL_Haptic *haptic, + struct haptic_effect *effect) { if (haptic->hwdata->bXInputHaptic) { return SDL_XINPUT_HapticGetEffectStatus(haptic, effect); @@ -389,8 +386,7 @@ SDL_SYS_HapticGetEffectStatus(SDL_Haptic * haptic, /* * Sets the gain. */ -int -SDL_SYS_HapticSetGain(SDL_Haptic * haptic, int gain) +int SDL_SYS_HapticSetGain(SDL_Haptic *haptic, int gain) { if (haptic->hwdata->bXInputHaptic) { return SDL_XINPUT_HapticSetGain(haptic, gain); @@ -402,8 +398,7 @@ SDL_SYS_HapticSetGain(SDL_Haptic * haptic, int gain) /* * Sets the autocentering. */ -int -SDL_SYS_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter) +int SDL_SYS_HapticSetAutocenter(SDL_Haptic *haptic, int autocenter) { if (haptic->hwdata->bXInputHaptic) { return SDL_XINPUT_HapticSetAutocenter(haptic, autocenter); @@ -415,8 +410,7 @@ SDL_SYS_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter) /* * Pauses the device. */ -int -SDL_SYS_HapticPause(SDL_Haptic * haptic) +int SDL_SYS_HapticPause(SDL_Haptic *haptic) { if (haptic->hwdata->bXInputHaptic) { return SDL_XINPUT_HapticPause(haptic); @@ -428,8 +422,7 @@ SDL_SYS_HapticPause(SDL_Haptic * haptic) /* * Pauses the device. */ -int -SDL_SYS_HapticUnpause(SDL_Haptic * haptic) +int SDL_SYS_HapticUnpause(SDL_Haptic *haptic) { if (haptic->hwdata->bXInputHaptic) { return SDL_XINPUT_HapticUnpause(haptic); @@ -441,8 +434,7 @@ SDL_SYS_HapticUnpause(SDL_Haptic * haptic) /* * Stops all the playing effects on the device. */ -int -SDL_SYS_HapticStopAll(SDL_Haptic * haptic) +int SDL_SYS_HapticStopAll(SDL_Haptic *haptic) { if (haptic->hwdata->bXInputHaptic) { return SDL_XINPUT_HapticStopAll(haptic); @@ -451,6 +443,11 @@ SDL_SYS_HapticStopAll(SDL_Haptic * haptic) } } +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif + #endif /* SDL_HAPTIC_DINPUT || SDL_HAPTIC_XINPUT */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/haptic/windows/SDL_windowshaptic_c.h b/SDL2-2.30.5/src/haptic/windows/SDL_windowshaptic_c.h similarity index 72% rename from SDL2-2.0.12/src/haptic/windows/SDL_windowshaptic_c.h rename to SDL2-2.30.5/src/haptic/windows/SDL_windowshaptic_c.h index 5f00b7e..e5d45d5 100644 --- a/SDL2-2.0.12/src/haptic/windows/SDL_windowshaptic_c.h +++ b/SDL2-2.30.5/src/haptic/windows/SDL_windowshaptic_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -28,52 +28,58 @@ #include "../../core/windows/SDL_directx.h" #include "../../core/windows/SDL_xinput.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + /* * Haptic system hardware data. */ struct haptic_hwdata { -#if SDL_HAPTIC_DINPUT +#ifdef SDL_HAPTIC_DINPUT LPDIRECTINPUTDEVICE8 device; #endif - DWORD axes[3]; /* Axes to use. */ - SDL_bool is_joystick; /* Device is loaded as joystick. */ - Uint8 bXInputHaptic; /* Supports force feedback via XInput. */ - Uint8 userid; /* XInput userid index for this joystick */ + DWORD axes[3]; /* Axes to use. */ + SDL_bool is_joystick; /* Device is loaded as joystick. */ + Uint8 bXInputHaptic; /* Supports force feedback via XInput. */ + Uint8 userid; /* XInput userid index for this joystick */ SDL_Thread *thread; SDL_mutex *mutex; Uint32 stopTicks; SDL_atomic_t stopThread; }; - /* * Haptic system effect data. */ +#if defined(SDL_HAPTIC_DINPUT) || defined(SDL_HAPTIC_XINPUT) struct haptic_hweffect { -#if SDL_HAPTIC_DINPUT +#ifdef SDL_HAPTIC_DINPUT DIEFFECT effect; LPDIRECTINPUTEFFECT ref; #endif -#if SDL_HAPTIC_XINPUT +#ifdef SDL_HAPTIC_XINPUT XINPUT_VIBRATION vibration; #endif }; +#endif /* -* List of available haptic devices. -*/ + * List of available haptic devices. + */ typedef struct SDL_hapticlist_item { char *name; SDL_Haptic *haptic; -#if SDL_HAPTIC_DINPUT +#ifdef SDL_HAPTIC_DINPUT DIDEVICEINSTANCE instance; DIDEVCAPS capabilities; #endif SDL_bool bXInputHaptic; /* Supports force feedback via XInput. */ - Uint8 userid; /* XInput userid index for this joystick */ + Uint8 userid; /* XInput userid index for this joystick */ struct SDL_hapticlist_item *next; } SDL_hapticlist_item; @@ -82,7 +88,11 @@ extern SDL_hapticlist_item *SDL_hapticlist; extern int SDL_SYS_AddHapticDevice(SDL_hapticlist_item *item); extern int SDL_SYS_RemoveHapticDevice(SDL_hapticlist_item *prev, SDL_hapticlist_item *item); +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif + #endif /* SDL_windowshaptic_c_h_ */ /* vi: set ts=4 sw=4 expandtab: */ - diff --git a/SDL2-2.0.12/src/haptic/windows/SDL_xinputhaptic.c b/SDL2-2.30.5/src/haptic/windows/SDL_xinputhaptic.c similarity index 66% rename from SDL2-2.0.12/src/haptic/windows/SDL_xinputhaptic.c rename to SDL2-2.30.5/src/haptic/windows/SDL_xinputhaptic.c index 97168f8..0066412 100644 --- a/SDL2-2.0.12/src/haptic/windows/SDL_xinputhaptic.c +++ b/SDL2-2.30.5/src/haptic/windows/SDL_xinputhaptic.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,13 +20,13 @@ */ #include "../../SDL_internal.h" +#include "SDL.h" #include "SDL_error.h" #include "SDL_haptic.h" #include "../SDL_syshaptic.h" -#if SDL_HAPTIC_XINPUT +#ifdef SDL_HAPTIC_XINPUT -#include "SDL_assert.h" #include "SDL_hints.h" #include "SDL_timer.h" #include "SDL_windowshaptic_c.h" @@ -35,30 +35,33 @@ #include "../../joystick/windows/SDL_windowsjoystick_c.h" #include "../../thread/SDL_systhread.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + /* * Internal stuff. */ static SDL_bool loaded_xinput = SDL_FALSE; - -int -SDL_XINPUT_HapticInit(void) +int SDL_XINPUT_HapticInit(void) { if (SDL_GetHintBoolean(SDL_HINT_XINPUT_ENABLED, SDL_TRUE)) { - loaded_xinput = (WIN_LoadXInputDLL() == 0); + loaded_xinput = (WIN_LoadXInputDLL() == 0) ? SDL_TRUE : SDL_FALSE; } - if (loaded_xinput) { + /* If the joystick subsystem is active, it will manage adding XInput haptic devices */ + if (loaded_xinput && !SDL_WasInit(SDL_INIT_JOYSTICK)) { DWORD i; for (i = 0; i < XUSER_MAX_COUNT; i++) { - SDL_XINPUT_MaybeAddDevice(i); + SDL_XINPUT_HapticMaybeAddDevice(i); } } return 0; } -int -SDL_XINPUT_MaybeAddDevice(const DWORD dwUserid) +int SDL_XINPUT_HapticMaybeAddDevice(const DWORD dwUserid) { const Uint8 userid = (Uint8)dwUserid; SDL_hapticlist_item *item; @@ -71,17 +74,17 @@ SDL_XINPUT_MaybeAddDevice(const DWORD dwUserid) /* Make sure we don't already have it */ for (item = SDL_hapticlist; item; item = item->next) { if (item->bXInputHaptic && item->userid == userid) { - return -1; /* Already added */ + return -1; /* Already added */ } } SDL_zero(state); if (XINPUTSETSTATE(dwUserid, &state) != ERROR_SUCCESS) { - return -1; /* no force feedback on this device. */ + return -1; /* no force feedback on this device. */ } item = (SDL_hapticlist_item *)SDL_malloc(sizeof(SDL_hapticlist_item)); - if (item == NULL) { + if (!item) { return SDL_OutOfMemory(); } @@ -90,7 +93,7 @@ SDL_XINPUT_MaybeAddDevice(const DWORD dwUserid) /* !!! FIXME: I'm not bothering to query for a real name right now (can we even?) */ { char buf[64]; - SDL_snprintf(buf, sizeof(buf), "XInput Controller #%u", (unsigned int)(userid + 1)); + (void)SDL_snprintf(buf, sizeof(buf), "XInput Controller #%u", userid + 1); item->name = SDL_strdup(buf); } @@ -106,8 +109,7 @@ SDL_XINPUT_MaybeAddDevice(const DWORD dwUserid) return SDL_SYS_AddHapticDevice(item); } -int -SDL_XINPUT_MaybeRemoveDevice(const DWORD dwUserid) +int SDL_XINPUT_HapticMaybeRemoveDevice(const DWORD dwUserid) { const Uint8 userid = (Uint8)dwUserid; SDL_hapticlist_item *item; @@ -117,7 +119,7 @@ SDL_XINPUT_MaybeRemoveDevice(const DWORD dwUserid) return -1; } - for (item = SDL_hapticlist; item != NULL; item = item->next) { + for (item = SDL_hapticlist; item; item = item->next) { if (item->bXInputHaptic && item->userid == userid) { /* found it, remove it. */ return SDL_SYS_RemoveHapticDevice(prev, item); @@ -141,10 +143,9 @@ SDL_XINPUT_MaybeRemoveDevice(const DWORD dwUserid) * Mostly, this is here to get rumbling to work, and all the other features * are absent in the XInput path for now. :( */ -static int SDLCALL -SDL_RunXInputHaptic(void *arg) +static int SDLCALL SDL_RunXInputHaptic(void *arg) { - struct haptic_hwdata *hwdata = (struct haptic_hwdata *) arg; + struct haptic_hwdata *hwdata = (struct haptic_hwdata *)arg; while (!SDL_AtomicGet(&hwdata->stopThread)) { SDL_Delay(50); @@ -163,11 +164,10 @@ SDL_RunXInputHaptic(void *arg) return 0; } -static int -SDL_XINPUT_HapticOpenFromUserIndex(SDL_Haptic *haptic, const Uint8 userid) +static int SDL_XINPUT_HapticOpenFromUserIndex(SDL_Haptic *haptic, const Uint8 userid) { char threadName[32]; - XINPUT_VIBRATION vibration = { 0, 0 }; /* stop any current vibration */ + XINPUT_VIBRATION vibration = { 0, 0 }; /* stop any current vibration */ XINPUTSETSTATE(userid, &vibration); haptic->supported = SDL_HAPTIC_LEFTRIGHT; @@ -178,15 +178,15 @@ SDL_XINPUT_HapticOpenFromUserIndex(SDL_Haptic *haptic, const Uint8 userid) /* Prepare effects memory. */ haptic->effects = (struct haptic_effect *) SDL_malloc(sizeof(struct haptic_effect) * haptic->neffects); - if (haptic->effects == NULL) { + if (!haptic->effects) { return SDL_OutOfMemory(); } /* Clear the memory */ SDL_memset(haptic->effects, 0, - sizeof(struct haptic_effect) * haptic->neffects); + sizeof(struct haptic_effect) * haptic->neffects); - haptic->hwdata = (struct haptic_hwdata *) SDL_malloc(sizeof(*haptic->hwdata)); - if (haptic->hwdata == NULL) { + haptic->hwdata = (struct haptic_hwdata *)SDL_malloc(sizeof(*haptic->hwdata)); + if (!haptic->hwdata) { SDL_free(haptic->effects); haptic->effects = NULL; return SDL_OutOfMemory(); @@ -197,17 +197,17 @@ SDL_XINPUT_HapticOpenFromUserIndex(SDL_Haptic *haptic, const Uint8 userid) haptic->hwdata->userid = userid; haptic->hwdata->mutex = SDL_CreateMutex(); - if (haptic->hwdata->mutex == NULL) { + if (!haptic->hwdata->mutex) { SDL_free(haptic->effects); SDL_free(haptic->hwdata); haptic->effects = NULL; return SDL_SetError("Couldn't create XInput haptic mutex"); } - SDL_snprintf(threadName, sizeof(threadName), "SDLXInputDev%d", (int)userid); + (void)SDL_snprintf(threadName, sizeof(threadName), "SDLXInputDev%d", userid); haptic->hwdata->thread = SDL_CreateThreadInternal(SDL_RunXInputHaptic, threadName, 64 * 1024, haptic->hwdata); - if (haptic->hwdata->thread == NULL) { + if (!haptic->hwdata->thread) { SDL_DestroyMutex(haptic->hwdata->mutex); SDL_free(haptic->effects); SDL_free(haptic->hwdata); @@ -218,26 +218,23 @@ SDL_XINPUT_HapticOpenFromUserIndex(SDL_Haptic *haptic, const Uint8 userid) return 0; } -int -SDL_XINPUT_HapticOpen(SDL_Haptic * haptic, SDL_hapticlist_item *item) +int SDL_XINPUT_HapticOpen(SDL_Haptic *haptic, SDL_hapticlist_item *item) { return SDL_XINPUT_HapticOpenFromUserIndex(haptic, item->userid); } -int -SDL_XINPUT_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick) +int SDL_XINPUT_JoystickSameHaptic(SDL_Haptic *haptic, SDL_Joystick *joystick) { - return (haptic->hwdata->userid == joystick->hwdata->userid); + return haptic->hwdata->userid == joystick->hwdata->userid; } -int -SDL_XINPUT_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick) +int SDL_XINPUT_HapticOpenFromJoystick(SDL_Haptic *haptic, SDL_Joystick *joystick) { SDL_hapticlist_item *item; int index = 0; /* Since it comes from a joystick we have to try to match it with a haptic device on our haptic list. */ - for (item = SDL_hapticlist; item != NULL; item = item->next) { + for (item = SDL_hapticlist; item; item = item->next) { if (item->bXInputHaptic && item->userid == joystick->hwdata->userid) { haptic->index = index; return SDL_XINPUT_HapticOpenFromUserIndex(haptic, joystick->hwdata->userid); @@ -245,20 +242,17 @@ SDL_XINPUT_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick) ++index; } - SDL_SetError("Couldn't find joystick in haptic device list"); - return -1; + return SDL_SetError("Couldn't find joystick in haptic device list"); } -void -SDL_XINPUT_HapticClose(SDL_Haptic * haptic) +void SDL_XINPUT_HapticClose(SDL_Haptic *haptic) { SDL_AtomicSet(&haptic->hwdata->stopThread, 1); SDL_WaitThread(haptic->hwdata->thread, NULL); SDL_DestroyMutex(haptic->hwdata->mutex); } -void -SDL_XINPUT_HapticQuit(void) +void SDL_XINPUT_HapticQuit(void) { if (loaded_xinput) { WIN_UnloadXInputDLL(); @@ -266,15 +260,13 @@ SDL_XINPUT_HapticQuit(void) } } -int -SDL_XINPUT_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect *effect, SDL_HapticEffect * base) +int SDL_XINPUT_HapticNewEffect(SDL_Haptic *haptic, struct haptic_effect *effect, SDL_HapticEffect *base) { - SDL_assert(base->type == SDL_HAPTIC_LEFTRIGHT); /* should catch this at higher level */ + SDL_assert(base->type == SDL_HAPTIC_LEFTRIGHT); /* should catch this at higher level */ return SDL_XINPUT_HapticUpdateEffect(haptic, effect, base); } -int -SDL_XINPUT_HapticUpdateEffect(SDL_Haptic * haptic, struct haptic_effect *effect, SDL_HapticEffect * data) +int SDL_XINPUT_HapticUpdateEffect(SDL_Haptic *haptic, struct haptic_effect *effect, SDL_HapticEffect *data) { XINPUT_VIBRATION *vib = &effect->hweffect->vibration; SDL_assert(data->type == SDL_HAPTIC_LEFTRIGHT); @@ -282,18 +274,17 @@ SDL_XINPUT_HapticUpdateEffect(SDL_Haptic * haptic, struct haptic_effect *effect, vib->wLeftMotorSpeed = data->leftright.large_magnitude * 2; vib->wRightMotorSpeed = data->leftright.small_magnitude * 2; SDL_LockMutex(haptic->hwdata->mutex); - if (haptic->hwdata->stopTicks) { /* running right now? Update it. */ + if (haptic->hwdata->stopTicks) { /* running right now? Update it. */ XINPUTSETSTATE(haptic->hwdata->userid, vib); } SDL_UnlockMutex(haptic->hwdata->mutex); return 0; } -int -SDL_XINPUT_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect, Uint32 iterations) +int SDL_XINPUT_HapticRunEffect(SDL_Haptic *haptic, struct haptic_effect *effect, Uint32 iterations) { XINPUT_VIBRATION *vib = &effect->hweffect->vibration; - SDL_assert(effect->effect.type == SDL_HAPTIC_LEFTRIGHT); /* should catch this at higher level */ + SDL_assert(effect->effect.type == SDL_HAPTIC_LEFTRIGHT); /* should catch this at higher level */ SDL_LockMutex(haptic->hwdata->mutex); if (effect->effect.leftright.length == SDL_HAPTIC_INFINITY || iterations == SDL_HAPTIC_INFINITY) { haptic->hwdata->stopTicks = SDL_HAPTIC_INFINITY; @@ -302,15 +293,14 @@ SDL_XINPUT_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect, Ui } else { haptic->hwdata->stopTicks = SDL_GetTicks() + (effect->effect.leftright.length * iterations); if ((haptic->hwdata->stopTicks == SDL_HAPTIC_INFINITY) || (haptic->hwdata->stopTicks == 0)) { - haptic->hwdata->stopTicks = 1; /* fix edge cases. */ + haptic->hwdata->stopTicks = 1; /* fix edge cases. */ } } SDL_UnlockMutex(haptic->hwdata->mutex); return (XINPUTSETSTATE(haptic->hwdata->userid, vib) == ERROR_SUCCESS) ? 0 : -1; } -int -SDL_XINPUT_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect *effect) +int SDL_XINPUT_HapticStopEffect(SDL_Haptic *haptic, struct haptic_effect *effect) { XINPUT_VIBRATION vibration = { 0, 0 }; SDL_LockMutex(haptic->hwdata->mutex); @@ -319,44 +309,37 @@ SDL_XINPUT_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect *effect) return (XINPUTSETSTATE(haptic->hwdata->userid, &vibration) == ERROR_SUCCESS) ? 0 : -1; } -void -SDL_XINPUT_HapticDestroyEffect(SDL_Haptic * haptic, struct haptic_effect *effect) +void SDL_XINPUT_HapticDestroyEffect(SDL_Haptic *haptic, struct haptic_effect *effect) { SDL_XINPUT_HapticStopEffect(haptic, effect); } -int -SDL_XINPUT_HapticGetEffectStatus(SDL_Haptic * haptic, struct haptic_effect *effect) +int SDL_XINPUT_HapticGetEffectStatus(SDL_Haptic *haptic, struct haptic_effect *effect) { return SDL_Unsupported(); } -int -SDL_XINPUT_HapticSetGain(SDL_Haptic * haptic, int gain) +int SDL_XINPUT_HapticSetGain(SDL_Haptic *haptic, int gain) { return SDL_Unsupported(); } -int -SDL_XINPUT_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter) +int SDL_XINPUT_HapticSetAutocenter(SDL_Haptic *haptic, int autocenter) { return SDL_Unsupported(); } -int -SDL_XINPUT_HapticPause(SDL_Haptic * haptic) +int SDL_XINPUT_HapticPause(SDL_Haptic *haptic) { return SDL_Unsupported(); } -int -SDL_XINPUT_HapticUnpause(SDL_Haptic * haptic) +int SDL_XINPUT_HapticUnpause(SDL_Haptic *haptic) { return SDL_Unsupported(); } -int -SDL_XINPUT_HapticStopAll(SDL_Haptic * haptic) +int SDL_XINPUT_HapticStopAll(SDL_Haptic *haptic) { XINPUT_VIBRATION vibration = { 0, 0 }; SDL_LockMutex(haptic->hwdata->mutex); @@ -365,119 +348,105 @@ SDL_XINPUT_HapticStopAll(SDL_Haptic * haptic) return (XINPUTSETSTATE(haptic->hwdata->userid, &vibration) == ERROR_SUCCESS) ? 0 : -1; } +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif + #else /* !SDL_HAPTIC_XINPUT */ #include "../../core/windows/SDL_windows.h" typedef struct SDL_hapticlist_item SDL_hapticlist_item; -int -SDL_XINPUT_HapticInit(void) +int SDL_XINPUT_HapticInit(void) { return 0; } -int -SDL_XINPUT_MaybeAddDevice(const DWORD dwUserid) +int SDL_XINPUT_HapticMaybeAddDevice(const DWORD dwUserid) { return SDL_Unsupported(); } -int -SDL_XINPUT_MaybeRemoveDevice(const DWORD dwUserid) +int SDL_XINPUT_HapticMaybeRemoveDevice(const DWORD dwUserid) { return SDL_Unsupported(); } -int -SDL_XINPUT_HapticOpen(SDL_Haptic * haptic, SDL_hapticlist_item *item) +int SDL_XINPUT_HapticOpen(SDL_Haptic *haptic, SDL_hapticlist_item *item) { return SDL_Unsupported(); } -int -SDL_XINPUT_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick) +int SDL_XINPUT_JoystickSameHaptic(SDL_Haptic *haptic, SDL_Joystick *joystick) { return SDL_Unsupported(); } -int -SDL_XINPUT_HapticOpenFromJoystick(SDL_Haptic * haptic, SDL_Joystick * joystick) +int SDL_XINPUT_HapticOpenFromJoystick(SDL_Haptic *haptic, SDL_Joystick *joystick) { return SDL_Unsupported(); } -void -SDL_XINPUT_HapticClose(SDL_Haptic * haptic) +void SDL_XINPUT_HapticClose(SDL_Haptic *haptic) { } -void -SDL_XINPUT_HapticQuit(void) +void SDL_XINPUT_HapticQuit(void) { } -int -SDL_XINPUT_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect *effect, SDL_HapticEffect * base) +int SDL_XINPUT_HapticNewEffect(SDL_Haptic *haptic, struct haptic_effect *effect, SDL_HapticEffect *base) { return SDL_Unsupported(); } -int -SDL_XINPUT_HapticUpdateEffect(SDL_Haptic * haptic, struct haptic_effect *effect, SDL_HapticEffect * data) +int SDL_XINPUT_HapticUpdateEffect(SDL_Haptic *haptic, struct haptic_effect *effect, SDL_HapticEffect *data) { return SDL_Unsupported(); } -int -SDL_XINPUT_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect, Uint32 iterations) +int SDL_XINPUT_HapticRunEffect(SDL_Haptic *haptic, struct haptic_effect *effect, Uint32 iterations) { return SDL_Unsupported(); } -int -SDL_XINPUT_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect *effect) +int SDL_XINPUT_HapticStopEffect(SDL_Haptic *haptic, struct haptic_effect *effect) { return SDL_Unsupported(); } -void -SDL_XINPUT_HapticDestroyEffect(SDL_Haptic * haptic, struct haptic_effect *effect) +void SDL_XINPUT_HapticDestroyEffect(SDL_Haptic *haptic, struct haptic_effect *effect) { } -int -SDL_XINPUT_HapticGetEffectStatus(SDL_Haptic * haptic, struct haptic_effect *effect) +int SDL_XINPUT_HapticGetEffectStatus(SDL_Haptic *haptic, struct haptic_effect *effect) { return SDL_Unsupported(); } -int -SDL_XINPUT_HapticSetGain(SDL_Haptic * haptic, int gain) +int SDL_XINPUT_HapticSetGain(SDL_Haptic *haptic, int gain) { return SDL_Unsupported(); } -int -SDL_XINPUT_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter) +int SDL_XINPUT_HapticSetAutocenter(SDL_Haptic *haptic, int autocenter) { return SDL_Unsupported(); } -int -SDL_XINPUT_HapticPause(SDL_Haptic * haptic) +int SDL_XINPUT_HapticPause(SDL_Haptic *haptic) { return SDL_Unsupported(); } -int -SDL_XINPUT_HapticUnpause(SDL_Haptic * haptic) +int SDL_XINPUT_HapticUnpause(SDL_Haptic *haptic) { return SDL_Unsupported(); } -int -SDL_XINPUT_HapticStopAll(SDL_Haptic * haptic) +int SDL_XINPUT_HapticStopAll(SDL_Haptic *haptic) { return SDL_Unsupported(); } diff --git a/SDL2-2.30.5/src/haptic/windows/SDL_xinputhaptic_c.h b/SDL2-2.30.5/src/haptic/windows/SDL_xinputhaptic_c.h new file mode 100644 index 0000000..071d3e4 --- /dev/null +++ b/SDL2-2.30.5/src/haptic/windows/SDL_xinputhaptic_c.h @@ -0,0 +1,56 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_haptic.h" +#include "SDL_windowshaptic_c.h" + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +extern int SDL_XINPUT_HapticInit(void); +extern int SDL_XINPUT_HapticMaybeAddDevice(const DWORD dwUserid); +extern int SDL_XINPUT_HapticMaybeRemoveDevice(const DWORD dwUserid); +extern int SDL_XINPUT_HapticOpen(SDL_Haptic *haptic, SDL_hapticlist_item *item); +extern int SDL_XINPUT_JoystickSameHaptic(SDL_Haptic *haptic, SDL_Joystick *joystick); +extern int SDL_XINPUT_HapticOpenFromJoystick(SDL_Haptic *haptic, SDL_Joystick *joystick); +extern void SDL_XINPUT_HapticClose(SDL_Haptic *haptic); +extern void SDL_XINPUT_HapticQuit(void); +extern int SDL_XINPUT_HapticNewEffect(SDL_Haptic *haptic, struct haptic_effect *effect, SDL_HapticEffect *base); +extern int SDL_XINPUT_HapticUpdateEffect(SDL_Haptic *haptic, struct haptic_effect *effect, SDL_HapticEffect *data); +extern int SDL_XINPUT_HapticRunEffect(SDL_Haptic *haptic, struct haptic_effect *effect, Uint32 iterations); +extern int SDL_XINPUT_HapticStopEffect(SDL_Haptic *haptic, struct haptic_effect *effect); +extern void SDL_XINPUT_HapticDestroyEffect(SDL_Haptic *haptic, struct haptic_effect *effect); +extern int SDL_XINPUT_HapticGetEffectStatus(SDL_Haptic *haptic, struct haptic_effect *effect); +extern int SDL_XINPUT_HapticSetGain(SDL_Haptic *haptic, int gain); +extern int SDL_XINPUT_HapticSetAutocenter(SDL_Haptic *haptic, int autocenter); +extern int SDL_XINPUT_HapticPause(SDL_Haptic *haptic); +extern int SDL_XINPUT_HapticUnpause(SDL_Haptic *haptic); +extern int SDL_XINPUT_HapticStopAll(SDL_Haptic *haptic); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/hidapi/AUTHORS.txt b/SDL2-2.30.5/src/hidapi/AUTHORS.txt similarity index 100% rename from SDL2-2.0.12/src/hidapi/AUTHORS.txt rename to SDL2-2.30.5/src/hidapi/AUTHORS.txt diff --git a/SDL2-2.0.12/src/hidapi/HACKING.txt b/SDL2-2.30.5/src/hidapi/HACKING.txt similarity index 100% rename from SDL2-2.0.12/src/hidapi/HACKING.txt rename to SDL2-2.30.5/src/hidapi/HACKING.txt diff --git a/SDL2-2.0.12/src/hidapi/LICENSE-bsd.txt b/SDL2-2.30.5/src/hidapi/LICENSE-bsd.txt similarity index 100% rename from SDL2-2.0.12/src/hidapi/LICENSE-bsd.txt rename to SDL2-2.30.5/src/hidapi/LICENSE-bsd.txt diff --git a/SDL2-2.0.12/src/hidapi/LICENSE-gpl3.txt b/SDL2-2.30.5/src/hidapi/LICENSE-gpl3.txt similarity index 100% rename from SDL2-2.0.12/src/hidapi/LICENSE-gpl3.txt rename to SDL2-2.30.5/src/hidapi/LICENSE-gpl3.txt diff --git a/SDL2-2.0.12/src/hidapi/LICENSE-orig.txt b/SDL2-2.30.5/src/hidapi/LICENSE-orig.txt similarity index 100% rename from SDL2-2.0.12/src/hidapi/LICENSE-orig.txt rename to SDL2-2.30.5/src/hidapi/LICENSE-orig.txt diff --git a/SDL2-2.0.12/src/hidapi/LICENSE.txt b/SDL2-2.30.5/src/hidapi/LICENSE.txt similarity index 100% rename from SDL2-2.0.12/src/hidapi/LICENSE.txt rename to SDL2-2.30.5/src/hidapi/LICENSE.txt diff --git a/SDL2-2.0.12/src/hidapi/Makefile.am b/SDL2-2.30.5/src/hidapi/Makefile.am similarity index 100% rename from SDL2-2.0.12/src/hidapi/Makefile.am rename to SDL2-2.30.5/src/hidapi/Makefile.am diff --git a/SDL2-2.0.12/src/hidapi/README.txt b/SDL2-2.30.5/src/hidapi/README.txt similarity index 100% rename from SDL2-2.0.12/src/hidapi/README.txt rename to SDL2-2.30.5/src/hidapi/README.txt diff --git a/SDL2-2.30.5/src/hidapi/SDL_hidapi.c b/SDL2-2.30.5/src/hidapi/SDL_hidapi.c new file mode 100644 index 0000000..ef95977 --- /dev/null +++ b/SDL2-2.30.5/src/hidapi/SDL_hidapi.c @@ -0,0 +1,1693 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +/* Original hybrid wrapper for Linux by Valve Software. Their original notes: + * + * The libusb version doesn't support Bluetooth, but not all Linux + * distributions allow access to /dev/hidraw* + * + * This merges the two, at a small performance cost, until distributions + * have granted access to /dev/hidraw* + */ +#include "../SDL_internal.h" + +#include "SDL_hidapi.h" +#include "SDL_hidapi_c.h" +#include "SDL_loadso.h" +#include "SDL_thread.h" +#include "SDL_timer.h" + +#ifndef SDL_HIDAPI_DISABLED + +#if defined(__WIN32__) || defined(__WINGDK__) +#include "../core/windows/SDL_windows.h" +#endif + +#if defined(__MACOSX__) +#include +#include +#include +#include +#include +#include +/* Things named "Master" were renamed to "Main" in macOS 12.0's SDK. */ +#if MAC_OS_X_VERSION_MIN_REQUIRED < 120000 +#define kIOMainPortDefault kIOMasterPortDefault +#endif +#endif + +#include "../core/linux/SDL_udev.h" +#ifdef SDL_USE_LIBUDEV +#include "../core/linux/SDL_sandbox.h" +#include +#endif + +#ifdef HAVE_INOTIFY +#include /* errno, strerror */ +#include +#include /* For the definition of NAME_MAX */ +#include +#include /* just in case we didn't use that SDL_USE_LIBUDEV block... */ +#endif + +#if defined(SDL_USE_LIBUDEV) || defined(HAVE_INOTIFY) +#include +#endif + +#if defined(SDL_USE_LIBUDEV) +typedef enum +{ + ENUMERATION_UNSET, + ENUMERATION_LIBUDEV, + ENUMERATION_FALLBACK +} LinuxEnumerationMethod; + +static LinuxEnumerationMethod linux_enumeration_method = ENUMERATION_UNSET; +#endif + +#if defined(HAVE_INOTIFY) +static int inotify_fd = -1; +#endif + +#if defined(SDL_USE_LIBUDEV) +static const SDL_UDEV_Symbols *usyms = NULL; +#endif + +static struct +{ + SDL_bool m_bInitialized; + Uint32 m_unDeviceChangeCounter; + SDL_bool m_bCanGetNotifications; + Uint32 m_unLastDetect; + +#if defined(__WIN32__) || defined(__WINGDK__) + SDL_threadID m_nThreadID; + WNDCLASSEXA m_wndClass; + HWND m_hwndMsg; + HDEVNOTIFY m_hNotify; + double m_flLastWin32MessageCheck; +#endif + +#if defined(__MACOSX__) + IONotificationPortRef m_notificationPort; + mach_port_t m_notificationMach; +#endif + +#if defined(SDL_USE_LIBUDEV) + struct udev *m_pUdev; + struct udev_monitor *m_pUdevMonitor; + int m_nUdevFd; +#endif +} SDL_HIDAPI_discovery; + +#if defined(__WIN32__) || defined(__WINGDK__) +struct _DEV_BROADCAST_HDR +{ + DWORD dbch_size; + DWORD dbch_devicetype; + DWORD dbch_reserved; +}; + +typedef struct _DEV_BROADCAST_DEVICEINTERFACE_A +{ + DWORD dbcc_size; + DWORD dbcc_devicetype; + DWORD dbcc_reserved; + GUID dbcc_classguid; + char dbcc_name[1]; +} DEV_BROADCAST_DEVICEINTERFACE_A, *PDEV_BROADCAST_DEVICEINTERFACE_A; + +typedef struct _DEV_BROADCAST_HDR DEV_BROADCAST_HDR; +#define DBT_DEVICEARRIVAL 0x8000 /* system detected a new device */ +#define DBT_DEVICEREMOVECOMPLETE 0x8004 /* device was removed from the system */ +#define DBT_DEVTYP_DEVICEINTERFACE 0x00000005 /* device interface class */ +#define DBT_DEVNODES_CHANGED 0x0007 +#define DBT_CONFIGCHANGED 0x0018 +#define DBT_DEVICETYPESPECIFIC 0x8005 /* type specific event */ +#define DBT_DEVINSTSTARTED 0x8008 /* device installed and started */ + +#include +DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, 0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED); + +static LRESULT CALLBACK ControllerWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) { + case WM_DEVICECHANGE: + switch (wParam) { + case DBT_DEVICEARRIVAL: + case DBT_DEVICEREMOVECOMPLETE: + if (((DEV_BROADCAST_HDR *)lParam)->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) { + ++SDL_HIDAPI_discovery.m_unDeviceChangeCounter; + } + break; + } + return TRUE; + } + + return DefWindowProc(hwnd, message, wParam, lParam); +} +#endif /* defined(__WIN32__) || defined(__WINGDK__) */ + +#if defined(__MACOSX__) +static void CallbackIOServiceFunc(void *context, io_iterator_t portIterator) +{ + /* Must drain the iterator, or we won't receive new notifications */ + io_object_t entry; + while ((entry = IOIteratorNext(portIterator)) != 0) { + IOObjectRelease(entry); + ++SDL_HIDAPI_discovery.m_unDeviceChangeCounter; + } +} +#endif /* __MACOSX__ */ + +#ifdef HAVE_INOTIFY +#ifdef HAVE_INOTIFY_INIT1 +static int SDL_inotify_init1(void) +{ + return inotify_init1(IN_NONBLOCK | IN_CLOEXEC); +} +#else +static int SDL_inotify_init1(void) +{ + int fd = inotify_init(); + if (fd < 0) { + return -1; + } + fcntl(fd, F_SETFL, O_NONBLOCK); + fcntl(fd, F_SETFD, FD_CLOEXEC); + return fd; +} +#endif + +static int StrHasPrefix(const char *string, const char *prefix) +{ + return SDL_strncmp(string, prefix, SDL_strlen(prefix)) == 0; +} + +static int StrIsInteger(const char *string) +{ + const char *p; + + if (*string == '\0') { + return 0; + } + + for (p = string; *p != '\0'; p++) { + if (*p < '0' || *p > '9') { + return 0; + } + } + + return 1; +} +#endif /* HAVE_INOTIFY */ + +static void HIDAPI_InitializeDiscovery(void) +{ + SDL_HIDAPI_discovery.m_bInitialized = SDL_TRUE; + SDL_HIDAPI_discovery.m_unDeviceChangeCounter = 1; + SDL_HIDAPI_discovery.m_bCanGetNotifications = SDL_FALSE; + SDL_HIDAPI_discovery.m_unLastDetect = 0; + +#if defined(__WIN32__) || defined(__WINGDK__) + SDL_HIDAPI_discovery.m_nThreadID = SDL_ThreadID(); + + SDL_zero(SDL_HIDAPI_discovery.m_wndClass); + SDL_HIDAPI_discovery.m_wndClass.hInstance = GetModuleHandle(NULL); + SDL_HIDAPI_discovery.m_wndClass.lpszClassName = "SDL_HIDAPI_DEVICE_DETECTION"; + SDL_HIDAPI_discovery.m_wndClass.lpfnWndProc = ControllerWndProc; /* This function is called by windows */ + SDL_HIDAPI_discovery.m_wndClass.cbSize = sizeof(WNDCLASSEX); + + RegisterClassExA(&SDL_HIDAPI_discovery.m_wndClass); + SDL_HIDAPI_discovery.m_hwndMsg = CreateWindowExA(0, "SDL_HIDAPI_DEVICE_DETECTION", NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL); + + { + DEV_BROADCAST_DEVICEINTERFACE_A devBroadcast; + + SDL_zero(devBroadcast); + devBroadcast.dbcc_size = sizeof(devBroadcast); + devBroadcast.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; + devBroadcast.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE; + + /* DEVICE_NOTIFY_ALL_INTERFACE_CLASSES is important, makes GUID_DEVINTERFACE_USB_DEVICE ignored, + * but that seems to be necessary to get a notice after each individual usb input device actually + * installs, rather than just as the composite device is seen. + */ + SDL_HIDAPI_discovery.m_hNotify = RegisterDeviceNotification(SDL_HIDAPI_discovery.m_hwndMsg, &devBroadcast, DEVICE_NOTIFY_WINDOW_HANDLE | DEVICE_NOTIFY_ALL_INTERFACE_CLASSES); + SDL_HIDAPI_discovery.m_bCanGetNotifications = (SDL_HIDAPI_discovery.m_hNotify != 0); + } +#endif /* defined(__WIN32__) || defined(__WINGDK__) */ + +#if defined(__MACOSX__) + SDL_HIDAPI_discovery.m_notificationPort = IONotificationPortCreate(kIOMainPortDefault); + if (SDL_HIDAPI_discovery.m_notificationPort) { + { + io_iterator_t portIterator = 0; + io_object_t entry; + IOReturn result = IOServiceAddMatchingNotification( + SDL_HIDAPI_discovery.m_notificationPort, + kIOFirstMatchNotification, + IOServiceMatching(kIOHIDDeviceKey), + CallbackIOServiceFunc, NULL, &portIterator); + + if (result == 0) { + /* Must drain the existing iterator, or we won't receive new notifications */ + while ((entry = IOIteratorNext(portIterator)) != 0) { + IOObjectRelease(entry); + } + } else { + IONotificationPortDestroy(SDL_HIDAPI_discovery.m_notificationPort); + SDL_HIDAPI_discovery.m_notificationPort = nil; + } + } + { + io_iterator_t portIterator = 0; + io_object_t entry; + IOReturn result = IOServiceAddMatchingNotification( + SDL_HIDAPI_discovery.m_notificationPort, + kIOTerminatedNotification, + IOServiceMatching(kIOHIDDeviceKey), + CallbackIOServiceFunc, NULL, &portIterator); + + if (result == 0) { + /* Must drain the existing iterator, or we won't receive new notifications */ + while ((entry = IOIteratorNext(portIterator)) != 0) { + IOObjectRelease(entry); + } + } else { + IONotificationPortDestroy(SDL_HIDAPI_discovery.m_notificationPort); + SDL_HIDAPI_discovery.m_notificationPort = nil; + } + } + } + + SDL_HIDAPI_discovery.m_notificationMach = MACH_PORT_NULL; + if (SDL_HIDAPI_discovery.m_notificationPort) { + SDL_HIDAPI_discovery.m_notificationMach = IONotificationPortGetMachPort(SDL_HIDAPI_discovery.m_notificationPort); + } + + SDL_HIDAPI_discovery.m_bCanGetNotifications = (SDL_HIDAPI_discovery.m_notificationMach != MACH_PORT_NULL); + +#endif /* __MACOSX__ */ + +#if defined(SDL_USE_LIBUDEV) + if (linux_enumeration_method == ENUMERATION_LIBUDEV) { + SDL_HIDAPI_discovery.m_pUdev = NULL; + SDL_HIDAPI_discovery.m_pUdevMonitor = NULL; + SDL_HIDAPI_discovery.m_nUdevFd = -1; + + usyms = SDL_UDEV_GetUdevSyms(); + if (usyms != NULL) { + SDL_HIDAPI_discovery.m_pUdev = usyms->udev_new(); + if (SDL_HIDAPI_discovery.m_pUdev != NULL) { + SDL_HIDAPI_discovery.m_pUdevMonitor = usyms->udev_monitor_new_from_netlink(SDL_HIDAPI_discovery.m_pUdev, "udev"); + if (SDL_HIDAPI_discovery.m_pUdevMonitor != NULL) { + usyms->udev_monitor_enable_receiving(SDL_HIDAPI_discovery.m_pUdevMonitor); + SDL_HIDAPI_discovery.m_nUdevFd = usyms->udev_monitor_get_fd(SDL_HIDAPI_discovery.m_pUdevMonitor); + SDL_HIDAPI_discovery.m_bCanGetNotifications = SDL_TRUE; + } + } + } + } else +#endif /* SDL_USE_LIBUDEV */ + { +#if defined(HAVE_INOTIFY) + inotify_fd = SDL_inotify_init1(); + + if (inotify_fd < 0) { + SDL_LogWarn(SDL_LOG_CATEGORY_INPUT, + "Unable to initialize inotify, falling back to polling: %s", + strerror(errno)); + return; + } + + /* We need to watch for attribute changes in addition to + * creation, because when a device is first created, it has + * permissions that we can't read. When udev chmods it to + * something that we maybe *can* read, we'll get an + * IN_ATTRIB event to tell us. */ + if (inotify_add_watch(inotify_fd, "/dev", + IN_CREATE | IN_DELETE | IN_MOVE | IN_ATTRIB) < 0) { + close(inotify_fd); + inotify_fd = -1; + SDL_LogWarn(SDL_LOG_CATEGORY_INPUT, + "Unable to add inotify watch, falling back to polling: %s", + strerror(errno)); + return; + } + + SDL_HIDAPI_discovery.m_bCanGetNotifications = SDL_TRUE; +#endif /* HAVE_INOTIFY */ + } +} + +static void HIDAPI_UpdateDiscovery(void) +{ + if (!SDL_HIDAPI_discovery.m_bInitialized) { + HIDAPI_InitializeDiscovery(); + } + + if (!SDL_HIDAPI_discovery.m_bCanGetNotifications) { + const Uint32 SDL_HIDAPI_DETECT_INTERVAL_MS = 3000; /* Update every 3 seconds */ + Uint32 now = SDL_GetTicks(); + if (!SDL_HIDAPI_discovery.m_unLastDetect || SDL_TICKS_PASSED(now, SDL_HIDAPI_discovery.m_unLastDetect + SDL_HIDAPI_DETECT_INTERVAL_MS)) { + ++SDL_HIDAPI_discovery.m_unDeviceChangeCounter; + SDL_HIDAPI_discovery.m_unLastDetect = now; + } + return; + } + +#if defined(__WIN32__) || defined(__WINGDK__) +#if 0 /* just let the usual SDL_PumpEvents loop dispatch these, fixing bug 4286. --ryan. */ + /* We'll only get messages on the same thread that created the window */ + if (SDL_ThreadID() == SDL_HIDAPI_discovery.m_nThreadID) { + MSG msg; + while (PeekMessage(&msg, SDL_HIDAPI_discovery.m_hwndMsg, 0, 0, PM_NOREMOVE)) { + if (GetMessageA(&msg, SDL_HIDAPI_discovery.m_hwndMsg, 0, 0) != 0) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + } +#endif +#endif /* defined(__WIN32__) || defined(__WINGDK__) */ + +#if defined(__MACOSX__) + if (SDL_HIDAPI_discovery.m_notificationPort) { + struct + { + mach_msg_header_t hdr; + char payload[4096]; + } msg; + while (mach_msg(&msg.hdr, MACH_RCV_MSG | MACH_RCV_TIMEOUT, 0, sizeof(msg), SDL_HIDAPI_discovery.m_notificationMach, 0, MACH_PORT_NULL) == KERN_SUCCESS) { + IODispatchCalloutFromMessage(NULL, &msg.hdr, SDL_HIDAPI_discovery.m_notificationPort); + } + } +#endif + +#if defined(SDL_USE_LIBUDEV) + if (linux_enumeration_method == ENUMERATION_LIBUDEV) { + if (SDL_HIDAPI_discovery.m_nUdevFd >= 0) { + /* Drain all notification events. + * We don't expect a lot of device notifications so just + * do a new discovery on any kind or number of notifications. + * This could be made more restrictive if necessary. + */ + for (;;) { + struct pollfd PollUdev; + struct udev_device *pUdevDevice; + + PollUdev.fd = SDL_HIDAPI_discovery.m_nUdevFd; + PollUdev.events = POLLIN; + if (poll(&PollUdev, 1, 0) != 1) { + break; + } + + pUdevDevice = usyms->udev_monitor_receive_device(SDL_HIDAPI_discovery.m_pUdevMonitor); + if (pUdevDevice) { + const char *action = NULL; + action = usyms->udev_device_get_action(pUdevDevice); + if (action == NULL || SDL_strcmp(action, "add") == 0 || SDL_strcmp(action, "remove") == 0) { + ++SDL_HIDAPI_discovery.m_unDeviceChangeCounter; + } + usyms->udev_device_unref(pUdevDevice); + } + } + } + } else +#endif /* SDL_USE_LIBUDEV */ + { +#if defined(HAVE_INOTIFY) + if (inotify_fd >= 0) { + union + { + struct inotify_event event; + char storage[4096]; + char enough_for_inotify[sizeof(struct inotify_event) + NAME_MAX + 1]; + } buf; + ssize_t bytes; + size_t remain = 0; + size_t len; + + bytes = read(inotify_fd, &buf, sizeof(buf)); + + if (bytes > 0) { + remain = (size_t)bytes; + } + + while (remain > 0) { + if (buf.event.len > 0) { + if (StrHasPrefix(buf.event.name, "hidraw") && + StrIsInteger(buf.event.name + SDL_strlen("hidraw"))) { + ++SDL_HIDAPI_discovery.m_unDeviceChangeCounter; + /* We found an hidraw change. We still continue to + * drain the inotify fd to avoid leaving old + * notifications in the queue. */ + } + } + + len = sizeof(struct inotify_event) + buf.event.len; + remain -= len; + + if (remain != 0) { + SDL_memmove(&buf.storage[0], &buf.storage[len], remain); + } + } + } +#endif /* HAVE_INOTIFY */ + } +} + +static void HIDAPI_ShutdownDiscovery(void) +{ + if (!SDL_HIDAPI_discovery.m_bInitialized) { + return; + } + +#if defined(__WIN32__) || defined(__WINGDK__) + if (SDL_HIDAPI_discovery.m_hNotify) { + UnregisterDeviceNotification(SDL_HIDAPI_discovery.m_hNotify); + } + + if (SDL_HIDAPI_discovery.m_hwndMsg) { + DestroyWindow(SDL_HIDAPI_discovery.m_hwndMsg); + } + + UnregisterClassA(SDL_HIDAPI_discovery.m_wndClass.lpszClassName, SDL_HIDAPI_discovery.m_wndClass.hInstance); +#endif + +#if defined(__MACOSX__) + if (SDL_HIDAPI_discovery.m_notificationPort) { + IONotificationPortDestroy(SDL_HIDAPI_discovery.m_notificationPort); + } +#endif + +#if defined(SDL_USE_LIBUDEV) + if (linux_enumeration_method == ENUMERATION_LIBUDEV) { + if (usyms) { + if (SDL_HIDAPI_discovery.m_pUdevMonitor) { + usyms->udev_monitor_unref(SDL_HIDAPI_discovery.m_pUdevMonitor); + } + if (SDL_HIDAPI_discovery.m_pUdev) { + usyms->udev_unref(SDL_HIDAPI_discovery.m_pUdev); + } + SDL_UDEV_ReleaseUdevSyms(); + usyms = NULL; + } + } else +#endif /* SDL_USE_LIBUDEV */ + { +#if defined(HAVE_INOTIFY) + if (inotify_fd >= 0) { + close(inotify_fd); + inotify_fd = -1; + } +#endif + } + + SDL_HIDAPI_discovery.m_bInitialized = SDL_FALSE; +} + +/* Platform HIDAPI Implementation */ + +#define hid_device PLATFORM_hid_device +#define hid_device_ PLATFORM_hid_device_ +#define hid_init PLATFORM_hid_init +#define hid_exit PLATFORM_hid_exit +#define hid_enumerate PLATFORM_hid_enumerate +#define hid_free_enumeration PLATFORM_hid_free_enumeration +#define hid_open PLATFORM_hid_open +#define hid_open_path PLATFORM_hid_open_path +#define hid_write PLATFORM_hid_write +#define hid_read_timeout PLATFORM_hid_read_timeout +#define hid_read PLATFORM_hid_read +#define hid_set_nonblocking PLATFORM_hid_set_nonblocking +#define hid_send_feature_report PLATFORM_hid_send_feature_report +#define hid_get_feature_report PLATFORM_hid_get_feature_report +#define hid_close PLATFORM_hid_close +#define hid_get_manufacturer_string PLATFORM_hid_get_manufacturer_string +#define hid_get_product_string PLATFORM_hid_get_product_string +#define hid_get_serial_number_string PLATFORM_hid_get_serial_number_string +#define hid_get_indexed_string PLATFORM_hid_get_indexed_string +#define hid_error PLATFORM_hid_error +#define new_hid_device PLATFORM_new_hid_device +#define free_hid_device PLATFORM_free_hid_device +#define input_report PLATFORM_input_report +#define return_data PLATFORM_return_data +#define make_path PLATFORM_make_path +#define read_thread PLATFORM_read_thread + +#undef HIDAPI_H__ +#ifdef __LINUX__ + +#ifdef SDL_USE_LIBUDEV +static const SDL_UDEV_Symbols *udev_ctx = NULL; + +#define udev_device_get_sysattr_value udev_ctx->udev_device_get_sysattr_value +#define udev_new udev_ctx->udev_new +#define udev_unref udev_ctx->udev_unref +#define udev_device_new_from_devnum udev_ctx->udev_device_new_from_devnum +#define udev_device_get_parent_with_subsystem_devtype udev_ctx->udev_device_get_parent_with_subsystem_devtype +#define udev_device_unref udev_ctx->udev_device_unref +#define udev_enumerate_new udev_ctx->udev_enumerate_new +#define udev_enumerate_add_match_subsystem udev_ctx->udev_enumerate_add_match_subsystem +#define udev_enumerate_scan_devices udev_ctx->udev_enumerate_scan_devices +#define udev_enumerate_get_list_entry udev_ctx->udev_enumerate_get_list_entry +#define udev_list_entry_get_name udev_ctx->udev_list_entry_get_name +#define udev_device_new_from_syspath udev_ctx->udev_device_new_from_syspath +#define udev_device_get_devnode udev_ctx->udev_device_get_devnode +#define udev_list_entry_get_next udev_ctx->udev_list_entry_get_next +#define udev_enumerate_unref udev_ctx->udev_enumerate_unref + +#include "linux/hid.c" +#define HAVE_PLATFORM_BACKEND +#endif /* SDL_USE_LIBUDEV */ + +#elif defined(__MACOSX__) +#include "mac/hid.c" +#define HAVE_PLATFORM_BACKEND +#define udev_ctx 1 +#elif defined(__WINDOWS__) || defined(__WINGDK__) +#include "windows/hid.c" +#define HAVE_PLATFORM_BACKEND +#define udev_ctx 1 +#elif defined(__ANDROID__) +/* The implementation for Android is in a separate .cpp file */ +#include "hidapi/hidapi.h" +#define HAVE_PLATFORM_BACKEND 1 +#define udev_ctx 1 +#elif defined(__IPHONEOS__) || defined(__TVOS__) +/* The implementation for iOS and tvOS is in a separate .m file */ +#include "hidapi/hidapi.h" +#define HAVE_PLATFORM_BACKEND 1 +#define udev_ctx 1 +#endif + +#undef hid_device +#undef hid_device_ +#undef hid_init +#undef hid_exit +#undef hid_enumerate +#undef hid_free_enumeration +#undef hid_open +#undef hid_open_path +#undef hid_write +#undef hid_read_timeout +#undef hid_read +#undef hid_set_nonblocking +#undef hid_send_feature_report +#undef hid_get_feature_report +#undef hid_close +#undef hid_get_manufacturer_string +#undef hid_get_product_string +#undef hid_get_serial_number_string +#undef hid_get_indexed_string +#undef hid_error +#undef new_hid_device +#undef free_hid_device +#undef input_report +#undef return_data +#undef make_path +#undef read_thread + +#ifdef SDL_JOYSTICK_HIDAPI_STEAMXBOX +#define HAVE_DRIVER_BACKEND 1 +#else +#define HAVE_DRIVER_BACKEND 0 +#endif + +#if HAVE_DRIVER_BACKEND + +/* DRIVER HIDAPI Implementation */ + +#define hid_device DRIVER_hid_device +#define hid_device_ DRIVER_hid_device_ +#define hid_init DRIVER_hid_init +#define hid_exit DRIVER_hid_exit +#define hid_enumerate DRIVER_hid_enumerate +#define hid_free_enumeration DRIVER_hid_free_enumeration +#define hid_open DRIVER_hid_open +#define hid_open_path DRIVER_hid_open_path +#define hid_write DRIVER_hid_write +#define hid_read_timeout DRIVER_hid_read_timeout +#define hid_read DRIVER_hid_read +#define hid_set_nonblocking DRIVER_hid_set_nonblocking +#define hid_send_feature_report DRIVER_hid_send_feature_report +#define hid_get_feature_report DRIVER_hid_get_feature_report +#define hid_close DRIVER_hid_close +#define hid_get_manufacturer_string DRIVER_hid_get_manufacturer_string +#define hid_get_product_string DRIVER_hid_get_product_string +#define hid_get_serial_number_string DRIVER_hid_get_serial_number_string +#define hid_get_indexed_string DRIVER_hid_get_indexed_string +#define hid_error DRIVER_hid_error + +#ifdef SDL_JOYSTICK_HIDAPI_STEAMXBOX +#undef HIDAPI_H__ +#include "steamxbox/hid.c" +#else +#error Need a driver hid.c for this platform! +#endif + +#undef hid_device +#undef hid_device_ +#undef hid_init +#undef hid_exit +#undef hid_enumerate +#undef hid_free_enumeration +#undef hid_open +#undef hid_open_path +#undef hid_write +#undef hid_read_timeout +#undef hid_read +#undef hid_set_nonblocking +#undef hid_send_feature_report +#undef hid_get_feature_report +#undef hid_close +#undef hid_get_manufacturer_string +#undef hid_get_product_string +#undef hid_get_serial_number_string +#undef hid_get_indexed_string +#undef hid_error + +#endif /* HAVE_DRIVER_BACKEND */ + +#ifdef HAVE_LIBUSB +/* libusb HIDAPI Implementation */ + +/* Include this now, for our dynamically-loaded libusb context */ +#include + +static struct +{ + void *libhandle; + + /* *INDENT-OFF* */ /* clang-format off */ + int (LIBUSB_CALL *init)(libusb_context **ctx); + void (LIBUSB_CALL *exit)(libusb_context *ctx); + ssize_t (LIBUSB_CALL *get_device_list)(libusb_context *ctx, libusb_device ***list); + void (LIBUSB_CALL *free_device_list)(libusb_device **list, int unref_devices); + int (LIBUSB_CALL *get_device_descriptor)(libusb_device *dev, struct libusb_device_descriptor *desc); + int (LIBUSB_CALL *get_active_config_descriptor)(libusb_device *dev, struct libusb_config_descriptor **config); + int (LIBUSB_CALL *get_config_descriptor)( + libusb_device *dev, + uint8_t config_index, + struct libusb_config_descriptor **config + ); + void (LIBUSB_CALL *free_config_descriptor)(struct libusb_config_descriptor *config); + uint8_t (LIBUSB_CALL *get_bus_number)(libusb_device *dev); + uint8_t (LIBUSB_CALL *get_device_address)(libusb_device *dev); + int (LIBUSB_CALL *open)(libusb_device *dev, libusb_device_handle **dev_handle); + void (LIBUSB_CALL *close)(libusb_device_handle *dev_handle); + int (LIBUSB_CALL *claim_interface)(libusb_device_handle *dev_handle, int interface_number); + int (LIBUSB_CALL *release_interface)(libusb_device_handle *dev_handle, int interface_number); + int (LIBUSB_CALL *kernel_driver_active)(libusb_device_handle *dev_handle, int interface_number); + int (LIBUSB_CALL *detach_kernel_driver)(libusb_device_handle *dev_handle, int interface_number); + int (LIBUSB_CALL *attach_kernel_driver)(libusb_device_handle *dev_handle, int interface_number); + int (LIBUSB_CALL *set_interface_alt_setting)(libusb_device_handle *dev, int interface_number, int alternate_setting); + struct libusb_transfer * (LIBUSB_CALL *alloc_transfer)(int iso_packets); + int (LIBUSB_CALL *submit_transfer)(struct libusb_transfer *transfer); + int (LIBUSB_CALL *cancel_transfer)(struct libusb_transfer *transfer); + void (LIBUSB_CALL *free_transfer)(struct libusb_transfer *transfer); + int (LIBUSB_CALL *control_transfer)( + libusb_device_handle *dev_handle, + uint8_t request_type, + uint8_t bRequest, + uint16_t wValue, + uint16_t wIndex, + unsigned char *data, + uint16_t wLength, + unsigned int timeout + ); + int (LIBUSB_CALL *interrupt_transfer)( + libusb_device_handle *dev_handle, + unsigned char endpoint, + unsigned char *data, + int length, + int *actual_length, + unsigned int timeout + ); + int (LIBUSB_CALL *handle_events)(libusb_context *ctx); + int (LIBUSB_CALL *handle_events_completed)(libusb_context *ctx, int *completed); + const char * (LIBUSB_CALL *error_name)(int errcode); +/* *INDENT-ON* */ /* clang-format on */ + +} libusb_ctx; + +#define libusb_init libusb_ctx.init +#define libusb_exit libusb_ctx.exit +#define libusb_get_device_list libusb_ctx.get_device_list +#define libusb_free_device_list libusb_ctx.free_device_list +#define libusb_get_device_descriptor libusb_ctx.get_device_descriptor +#define libusb_get_active_config_descriptor libusb_ctx.get_active_config_descriptor +#define libusb_get_config_descriptor libusb_ctx.get_config_descriptor +#define libusb_free_config_descriptor libusb_ctx.free_config_descriptor +#define libusb_get_bus_number libusb_ctx.get_bus_number +#define libusb_get_device_address libusb_ctx.get_device_address +#define libusb_open libusb_ctx.open +#define libusb_close libusb_ctx.close +#define libusb_claim_interface libusb_ctx.claim_interface +#define libusb_release_interface libusb_ctx.release_interface +#define libusb_kernel_driver_active libusb_ctx.kernel_driver_active +#define libusb_detach_kernel_driver libusb_ctx.detach_kernel_driver +#define libusb_attach_kernel_driver libusb_ctx.attach_kernel_driver +#define libusb_set_interface_alt_setting libusb_ctx.set_interface_alt_setting +#define libusb_alloc_transfer libusb_ctx.alloc_transfer +#define libusb_submit_transfer libusb_ctx.submit_transfer +#define libusb_cancel_transfer libusb_ctx.cancel_transfer +#define libusb_free_transfer libusb_ctx.free_transfer +#define libusb_control_transfer libusb_ctx.control_transfer +#define libusb_interrupt_transfer libusb_ctx.interrupt_transfer +#define libusb_handle_events libusb_ctx.handle_events +#define libusb_handle_events_completed libusb_ctx.handle_events_completed +#define libusb_error_name libusb_ctx.error_name + +#define hid_device LIBUSB_hid_device +#define hid_device_ LIBUSB_hid_device_ +#define hid_init LIBUSB_hid_init +#define hid_exit LIBUSB_hid_exit +#define hid_enumerate LIBUSB_hid_enumerate +#define hid_free_enumeration LIBUSB_hid_free_enumeration +#define hid_open LIBUSB_hid_open +#define hid_open_path LIBUSB_hid_open_path +#define hid_write LIBUSB_hid_write +#define hid_read_timeout LIBUSB_hid_read_timeout +#define hid_read LIBUSB_hid_read +#define hid_set_nonblocking LIBUSB_hid_set_nonblocking +#define hid_send_feature_report LIBUSB_hid_send_feature_report +#define hid_get_feature_report LIBUSB_hid_get_feature_report +#define hid_close LIBUSB_hid_close +#define hid_get_manufacturer_string LIBUSB_hid_get_manufacturer_string +#define hid_get_product_string LIBUSB_hid_get_product_string +#define hid_get_serial_number_string LIBUSB_hid_get_serial_number_string +#define hid_get_indexed_string LIBUSB_hid_get_indexed_string +#define hid_error LIBUSB_hid_error +#define new_hid_device LIBUSB_new_hid_device +#define free_hid_device LIBUSB_free_hid_device +#define input_report LIBUSB_input_report +#define return_data LIBUSB_return_data +#define make_path LIBUSB_make_path +#define read_thread LIBUSB_read_thread + +#ifndef __FreeBSD__ +/* this is awkwardly inlined, so we need to re-implement it here + * so we can override the libusb_control_transfer call */ +static int SDL_libusb_get_string_descriptor(libusb_device_handle *dev, + uint8_t descriptor_index, uint16_t lang_id, + unsigned char *data, int length) +{ + return libusb_control_transfer(dev, LIBUSB_ENDPOINT_IN | 0x0, LIBUSB_REQUEST_GET_DESCRIPTOR, (LIBUSB_DT_STRING << 8) | descriptor_index, lang_id, + data, (uint16_t)length, 1000); /* Endpoint 0 IN */ +} +#define libusb_get_string_descriptor SDL_libusb_get_string_descriptor +#endif /* __FreeBSD__ */ + +#undef HIDAPI_H__ +#include "libusb/hid.c" + +#undef libusb_init +#undef libusb_exit +#undef libusb_get_device_list +#undef libusb_free_device_list +#undef libusb_get_device_descriptor +#undef libusb_get_active_config_descriptor +#undef libusb_get_config_descriptor +#undef libusb_free_config_descriptor +#undef libusb_get_bus_number +#undef libusb_get_device_address +#undef libusb_open +#undef libusb_close +#undef libusb_claim_interface +#undef libusb_release_interface +#undef libusb_kernel_driver_active +#undef libusb_detach_kernel_driver +#undef libusb_attach_kernel_driver +#undef libusb_set_interface_alt_setting +#undef libusb_alloc_transfer +#undef libusb_submit_transfer +#undef libusb_cancel_transfer +#undef libusb_free_transfer +#undef libusb_control_transfer +#undef libusb_interrupt_transfer +#undef libusb_handle_events +#undef libusb_handle_events_completed +#undef libusb_error_name + +#undef hid_device +#undef hid_device_ +#undef hid_init +#undef hid_exit +#undef hid_enumerate +#undef hid_free_enumeration +#undef hid_open +#undef hid_open_path +#undef hid_write +#undef hid_read_timeout +#undef hid_read +#undef hid_set_nonblocking +#undef hid_send_feature_report +#undef hid_get_feature_report +#undef hid_close +#undef hid_get_manufacturer_string +#undef hid_get_product_string +#undef hid_get_serial_number_string +#undef hid_get_indexed_string +#undef hid_error +#undef new_hid_device +#undef free_hid_device +#undef input_report +#undef return_data +#undef make_path +#undef read_thread + +/* If the platform has any backend other than libusb, try to avoid using + * libusb as the main backend for devices, since it detaches drivers and + * therefore makes devices inaccessible to the rest of the OS. + * + * We do this by whitelisting devices we know to be accessible _exclusively_ + * via libusb; these are typically devices that look like HIDs but have a + * quirk that requires direct access to the hardware. + */ +static const struct { + Uint16 vendor; + Uint16 product; +} SDL_libusb_whitelist[] = { + { 0x057e, 0x0337 } /* Nintendo WUP-028, Wii U/Switch GameCube Adapter */ +}; + +static SDL_bool +IsInWhitelist(Uint16 vendor, Uint16 product) +{ + int i; + for (i = 0; i < SDL_arraysize(SDL_libusb_whitelist); i += 1) { + if (vendor == SDL_libusb_whitelist[i].vendor && + product == SDL_libusb_whitelist[i].product) { + return SDL_TRUE; + } + } + return SDL_FALSE; +} + +#if defined(HAVE_PLATFORM_BACKEND) || HAVE_DRIVER_BACKEND +static const SDL_bool use_libusb_whitelist_default = SDL_TRUE; +#else +static const SDL_bool use_libusb_whitelist_default = SDL_FALSE; +#endif /* HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND */ +static SDL_bool use_libusb_whitelist = use_libusb_whitelist_default; + +#endif /* HAVE_LIBUSB */ + +#endif /* !SDL_HIDAPI_DISABLED */ + +/* Shared HIDAPI Implementation */ + +struct hidapi_backend +{ + int (*hid_write)(void *device, const unsigned char *data, size_t length); + int (*hid_read_timeout)(void *device, unsigned char *data, size_t length, int milliseconds); + int (*hid_read)(void *device, unsigned char *data, size_t length); + int (*hid_set_nonblocking)(void *device, int nonblock); + int (*hid_send_feature_report)(void *device, const unsigned char *data, size_t length); + int (*hid_get_feature_report)(void *device, unsigned char *data, size_t length); + void (*hid_close)(void *device); + int (*hid_get_manufacturer_string)(void *device, wchar_t *string, size_t maxlen); + int (*hid_get_product_string)(void *device, wchar_t *string, size_t maxlen); + int (*hid_get_serial_number_string)(void *device, wchar_t *string, size_t maxlen); + int (*hid_get_indexed_string)(void *device, int string_index, wchar_t *string, size_t maxlen); + const wchar_t *(*hid_error)(void *device); +}; + +#ifdef HAVE_PLATFORM_BACKEND +static const struct hidapi_backend PLATFORM_Backend = { + (void *)PLATFORM_hid_write, + (void *)PLATFORM_hid_read_timeout, + (void *)PLATFORM_hid_read, + (void *)PLATFORM_hid_set_nonblocking, + (void *)PLATFORM_hid_send_feature_report, + (void *)PLATFORM_hid_get_feature_report, + (void *)PLATFORM_hid_close, + (void *)PLATFORM_hid_get_manufacturer_string, + (void *)PLATFORM_hid_get_product_string, + (void *)PLATFORM_hid_get_serial_number_string, + (void *)PLATFORM_hid_get_indexed_string, + (void *)PLATFORM_hid_error +}; +#endif /* HAVE_PLATFORM_BACKEND */ + +#if HAVE_DRIVER_BACKEND +static const struct hidapi_backend DRIVER_Backend = { + (void *)DRIVER_hid_write, + (void *)DRIVER_hid_read_timeout, + (void *)DRIVER_hid_read, + (void *)DRIVER_hid_set_nonblocking, + (void *)DRIVER_hid_send_feature_report, + (void *)DRIVER_hid_get_feature_report, + (void *)DRIVER_hid_close, + (void *)DRIVER_hid_get_manufacturer_string, + (void *)DRIVER_hid_get_product_string, + (void *)DRIVER_hid_get_serial_number_string, + (void *)DRIVER_hid_get_indexed_string, + (void *)DRIVER_hid_error +}; +#endif /* HAVE_DRIVER_BACKEND */ + +#ifdef HAVE_LIBUSB +static const struct hidapi_backend LIBUSB_Backend = { + (void *)LIBUSB_hid_write, + (void *)LIBUSB_hid_read_timeout, + (void *)LIBUSB_hid_read, + (void *)LIBUSB_hid_set_nonblocking, + (void *)LIBUSB_hid_send_feature_report, + (void *)LIBUSB_hid_get_feature_report, + (void *)LIBUSB_hid_close, + (void *)LIBUSB_hid_get_manufacturer_string, + (void *)LIBUSB_hid_get_product_string, + (void *)LIBUSB_hid_get_serial_number_string, + (void *)LIBUSB_hid_get_indexed_string, + (void *)LIBUSB_hid_error +}; +#endif /* HAVE_LIBUSB */ + +struct SDL_hid_device_ +{ + const void *magic; + void *device; + const struct hidapi_backend *backend; +}; +static char device_magic; + +#if defined(HAVE_PLATFORM_BACKEND) || HAVE_DRIVER_BACKEND || defined(HAVE_LIBUSB) + +static SDL_hid_device *CreateHIDDeviceWrapper(void *device, const struct hidapi_backend *backend) +{ + SDL_hid_device *wrapper = (SDL_hid_device *)SDL_malloc(sizeof(*wrapper)); + wrapper->magic = &device_magic; + wrapper->device = device; + wrapper->backend = backend; + return wrapper; +} + +#endif /* HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || HAVE_LIBUSB */ + +static void DeleteHIDDeviceWrapper(SDL_hid_device *device) +{ + device->magic = NULL; + SDL_free(device); +} + +#define CHECK_DEVICE_MAGIC(device, retval) \ + if (!device || device->magic != &device_magic) { \ + SDL_SetError("Invalid device"); \ + return retval; \ + } + +#ifndef SDL_HIDAPI_DISABLED +#if defined(HAVE_PLATFORM_BACKEND) || HAVE_DRIVER_BACKEND || defined(HAVE_LIBUSB) + +#define COPY_IF_EXISTS(var) \ + if (pSrc->var != NULL) { \ + pDst->var = SDL_strdup(pSrc->var); \ + } else { \ + pDst->var = NULL; \ + } +#define WCOPY_IF_EXISTS(var) \ + if (pSrc->var != NULL) { \ + pDst->var = SDL_wcsdup(pSrc->var); \ + } else { \ + pDst->var = NULL; \ + } + +static void CopyHIDDeviceInfo(struct SDL_hid_device_info *pSrc, struct SDL_hid_device_info *pDst) +{ + COPY_IF_EXISTS(path) + pDst->vendor_id = pSrc->vendor_id; + pDst->product_id = pSrc->product_id; + WCOPY_IF_EXISTS(serial_number) + pDst->release_number = pSrc->release_number; + WCOPY_IF_EXISTS(manufacturer_string) + WCOPY_IF_EXISTS(product_string) + pDst->usage_page = pSrc->usage_page; + pDst->usage = pSrc->usage; + pDst->interface_number = pSrc->interface_number; + pDst->interface_class = pSrc->interface_class; + pDst->interface_subclass = pSrc->interface_subclass; + pDst->interface_protocol = pSrc->interface_protocol; + pDst->next = NULL; +} + +#undef COPY_IF_EXISTS +#undef WCOPY_IF_EXISTS + +#endif /* HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || HAVE_LIBUSB */ +#endif /* !SDL_HIDAPI_DISABLED */ + +static int SDL_hidapi_refcount = 0; + +static void SDL_SetHIDAPIError(const wchar_t *error) +{ + if (error) { + char *error_utf8 = SDL_iconv_wchar_utf8(error); + if (error_utf8) { + SDL_SetError("%s", error_utf8); + SDL_free(error_utf8); + } + } +} + +int SDL_hid_init(void) +{ + int attempts = 0, success = 0; + + if (SDL_hidapi_refcount > 0) { + ++SDL_hidapi_refcount; + return 0; + } + +#if defined(SDL_USE_LIBUDEV) + if (SDL_getenv("SDL_HIDAPI_JOYSTICK_DISABLE_UDEV") != NULL) { + SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, + "udev disabled by SDL_HIDAPI_JOYSTICK_DISABLE_UDEV"); + linux_enumeration_method = ENUMERATION_FALLBACK; + } else if (SDL_DetectSandbox() != SDL_SANDBOX_NONE) { + SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, + "Container detected, disabling HIDAPI udev integration"); + linux_enumeration_method = ENUMERATION_FALLBACK; + } else { + SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, + "Using udev for HIDAPI joystick device discovery"); + linux_enumeration_method = ENUMERATION_LIBUDEV; + } +#endif + +#ifdef HAVE_LIBUSB + use_libusb_whitelist = SDL_GetHintBoolean("SDL_HIDAPI_LIBUSB_WHITELIST", + use_libusb_whitelist_default); + if (SDL_getenv("SDL_HIDAPI_DISABLE_LIBUSB") != NULL) { + SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, + "libusb disabled by SDL_HIDAPI_DISABLE_LIBUSB"); + libusb_ctx.libhandle = NULL; + } else { + ++attempts; +#ifdef SDL_LIBUSB_DYNAMIC + libusb_ctx.libhandle = SDL_LoadObject(SDL_LIBUSB_DYNAMIC); +#else + libusb_ctx.libhandle = (void *)1; +#endif + if (libusb_ctx.libhandle != NULL) { + SDL_bool loaded = SDL_TRUE; +#ifdef SDL_LIBUSB_DYNAMIC +#define LOAD_LIBUSB_SYMBOL(func) \ + if (!(libusb_ctx.func = SDL_LoadFunction(libusb_ctx.libhandle, "libusb_" #func))) { \ + loaded = SDL_FALSE; \ + } +#else +#define LOAD_LIBUSB_SYMBOL(func) \ + libusb_ctx.func = libusb_##func; +#endif + LOAD_LIBUSB_SYMBOL(init) + LOAD_LIBUSB_SYMBOL(exit) + LOAD_LIBUSB_SYMBOL(get_device_list) + LOAD_LIBUSB_SYMBOL(free_device_list) + LOAD_LIBUSB_SYMBOL(get_device_descriptor) + LOAD_LIBUSB_SYMBOL(get_active_config_descriptor) + LOAD_LIBUSB_SYMBOL(get_config_descriptor) + LOAD_LIBUSB_SYMBOL(free_config_descriptor) + LOAD_LIBUSB_SYMBOL(get_bus_number) + LOAD_LIBUSB_SYMBOL(get_device_address) + LOAD_LIBUSB_SYMBOL(open) + LOAD_LIBUSB_SYMBOL(close) + LOAD_LIBUSB_SYMBOL(claim_interface) + LOAD_LIBUSB_SYMBOL(release_interface) + LOAD_LIBUSB_SYMBOL(kernel_driver_active) + LOAD_LIBUSB_SYMBOL(detach_kernel_driver) + LOAD_LIBUSB_SYMBOL(attach_kernel_driver) + LOAD_LIBUSB_SYMBOL(set_interface_alt_setting) + LOAD_LIBUSB_SYMBOL(alloc_transfer) + LOAD_LIBUSB_SYMBOL(submit_transfer) + LOAD_LIBUSB_SYMBOL(cancel_transfer) + LOAD_LIBUSB_SYMBOL(free_transfer) + LOAD_LIBUSB_SYMBOL(control_transfer) + LOAD_LIBUSB_SYMBOL(interrupt_transfer) + LOAD_LIBUSB_SYMBOL(handle_events) + LOAD_LIBUSB_SYMBOL(handle_events_completed) + LOAD_LIBUSB_SYMBOL(error_name) +#undef LOAD_LIBUSB_SYMBOL + + if (!loaded) { +#ifdef SDL_LIBUSB_DYNAMIC + SDL_UnloadObject(libusb_ctx.libhandle); +#endif + libusb_ctx.libhandle = NULL; + /* SDL_LogWarn(SDL_LOG_CATEGORY_INPUT, SDL_LIBUSB_DYNAMIC " found but could not load function"); */ + } else if (LIBUSB_hid_init() < 0) { +#ifdef SDL_LIBUSB_DYNAMIC + SDL_UnloadObject(libusb_ctx.libhandle); +#endif + libusb_ctx.libhandle = NULL; + } else { + ++success; + } + } + } +#endif /* HAVE_LIBUSB */ + +#ifdef HAVE_PLATFORM_BACKEND + ++attempts; +#ifdef __LINUX__ + udev_ctx = SDL_UDEV_GetUdevSyms(); +#endif /* __LINUX __ */ + if (udev_ctx && PLATFORM_hid_init() == 0) { + ++success; + } +#endif /* HAVE_PLATFORM_BACKEND */ + + if (attempts > 0 && success == 0) { + return -1; + } + + ++SDL_hidapi_refcount; + return 0; +} + +int SDL_hid_exit(void) +{ + int result = 0; + + if (SDL_hidapi_refcount == 0) { + return 0; + } + --SDL_hidapi_refcount; + if (SDL_hidapi_refcount > 0) { + return 0; + } + SDL_hidapi_refcount = 0; + +#ifndef SDL_HIDAPI_DISABLED + HIDAPI_ShutdownDiscovery(); +#endif + +#ifdef HAVE_PLATFORM_BACKEND + if (udev_ctx) { + result |= PLATFORM_hid_exit(); + } +#ifdef __LINUX__ + SDL_UDEV_ReleaseUdevSyms(); +#endif /* __LINUX __ */ +#endif /* HAVE_PLATFORM_BACKEND */ + +#ifdef HAVE_LIBUSB + if (libusb_ctx.libhandle) { + result |= LIBUSB_hid_exit(); +#ifdef SDL_LIBUSB_DYNAMIC + SDL_UnloadObject(libusb_ctx.libhandle); +#endif + libusb_ctx.libhandle = NULL; + } +#endif /* HAVE_LIBUSB */ + + return result; +} + +Uint32 SDL_hid_device_change_count(void) +{ + Uint32 counter = 0; + +#ifndef SDL_HIDAPI_DISABLED + if (SDL_hidapi_refcount == 0 && SDL_hid_init() != 0) { + return 0; + } + + HIDAPI_UpdateDiscovery(); + + if (SDL_HIDAPI_discovery.m_unDeviceChangeCounter == 0) { + /* Counter wrapped! */ + ++SDL_HIDAPI_discovery.m_unDeviceChangeCounter; + } + counter = SDL_HIDAPI_discovery.m_unDeviceChangeCounter; + +#endif /* !SDL_HIDAPI_DISABLED */ + + return counter; +} + +struct SDL_hid_device_info *SDL_hid_enumerate(unsigned short vendor_id, unsigned short product_id) +{ +#if defined(HAVE_PLATFORM_BACKEND) || HAVE_DRIVER_BACKEND || defined(HAVE_LIBUSB) +#ifdef HAVE_LIBUSB + struct SDL_hid_device_info *usb_devs = NULL; + struct SDL_hid_device_info *usb_dev; +#endif +#if HAVE_DRIVER_BACKEND + struct SDL_hid_device_info *driver_devs = NULL; + struct SDL_hid_device_info *driver_dev; +#endif +#ifdef HAVE_PLATFORM_BACKEND + struct SDL_hid_device_info *raw_devs = NULL; + struct SDL_hid_device_info *raw_dev; +#endif + struct SDL_hid_device_info *devs = NULL, *last = NULL, *new_dev; + + if (SDL_hidapi_refcount == 0 && SDL_hid_init() != 0) { + return NULL; + } + +#ifdef HAVE_LIBUSB + if (libusb_ctx.libhandle) { + usb_devs = LIBUSB_hid_enumerate(vendor_id, product_id); +#ifdef DEBUG_HIDAPI + SDL_Log("libusb devices found:"); +#endif + for (usb_dev = usb_devs; usb_dev; usb_dev = usb_dev->next) { + if (use_libusb_whitelist) { + if (!IsInWhitelist(usb_dev->vendor_id, usb_dev->product_id)) { +#ifdef DEBUG_HIDAPI + SDL_Log("Device was not in libusb whitelist: %ls %ls 0x%.4hx 0x%.4hx", + usb_dev->manufacturer_string, usb_dev->product_string, + usb_dev->vendor_id, usb_dev->product_id); +#endif /* DEBUG_HIDAPI */ + continue; + } + } + new_dev = (struct SDL_hid_device_info *)SDL_malloc(sizeof(struct SDL_hid_device_info)); + if (new_dev == NULL) { + LIBUSB_hid_free_enumeration(usb_devs); + SDL_hid_free_enumeration(devs); + SDL_OutOfMemory(); + return NULL; + } + CopyHIDDeviceInfo(usb_dev, new_dev); +#ifdef DEBUG_HIDAPI + SDL_Log(" - %ls %ls 0x%.4hx 0x%.4hx", + usb_dev->manufacturer_string, usb_dev->product_string, + usb_dev->vendor_id, usb_dev->product_id); +#endif + + if (last != NULL) { + last->next = new_dev; + } else { + devs = new_dev; + } + last = new_dev; + } + } +#endif /* HAVE_LIBUSB */ + +#if HAVE_DRIVER_BACKEND + driver_devs = DRIVER_hid_enumerate(vendor_id, product_id); + for (driver_dev = driver_devs; driver_dev; driver_dev = driver_dev->next) { + new_dev = (struct SDL_hid_device_info *)SDL_malloc(sizeof(struct SDL_hid_device_info)); + CopyHIDDeviceInfo(driver_dev, new_dev); + + if (last != NULL) { + last->next = new_dev; + } else { + devs = new_dev; + } + last = new_dev; + } +#endif /* HAVE_DRIVER_BACKEND */ + +#ifdef HAVE_PLATFORM_BACKEND + if (udev_ctx) { + raw_devs = PLATFORM_hid_enumerate(vendor_id, product_id); +#ifdef DEBUG_HIDAPI + SDL_Log("hidraw devices found:"); +#endif + for (raw_dev = raw_devs; raw_dev; raw_dev = raw_dev->next) { + SDL_bool bFound = SDL_FALSE; +#ifdef DEBUG_HIDAPI + SDL_Log(" - %ls %ls 0x%.4hx 0x%.4hx", + raw_dev->manufacturer_string, raw_dev->product_string, + raw_dev->vendor_id, raw_dev->product_id); +#endif +#ifdef HAVE_LIBUSB + for (usb_dev = usb_devs; usb_dev; usb_dev = usb_dev->next) { + if (raw_dev->vendor_id == usb_dev->vendor_id && + raw_dev->product_id == usb_dev->product_id && + (raw_dev->interface_number < 0 || raw_dev->interface_number == usb_dev->interface_number)) { + bFound = SDL_TRUE; + break; + } + } +#endif +#if HAVE_DRIVER_BACKEND + for (driver_dev = driver_devs; driver_dev; driver_dev = driver_dev->next) { + if (raw_dev->vendor_id == driver_dev->vendor_id && + raw_dev->product_id == driver_dev->product_id && + (raw_dev->interface_number < 0 || raw_dev->interface_number == driver_dev->interface_number)) { + bFound = SDL_TRUE; + break; + } + } +#endif + if (!bFound) { + new_dev = (struct SDL_hid_device_info *)SDL_malloc(sizeof(struct SDL_hid_device_info)); + if (new_dev == NULL) { +#ifdef HAVE_LIBUSB + if (libusb_ctx.libhandle) { + LIBUSB_hid_free_enumeration(usb_devs); + } +#endif + PLATFORM_hid_free_enumeration(raw_devs); + SDL_hid_free_enumeration(devs); + SDL_OutOfMemory(); + return NULL; + } + CopyHIDDeviceInfo(raw_dev, new_dev); + new_dev->next = NULL; + + if (last != NULL) { + last->next = new_dev; + } else { + devs = new_dev; + } + last = new_dev; + } + } + PLATFORM_hid_free_enumeration(raw_devs); + } +#endif /* HAVE_PLATFORM_BACKEND */ + +#ifdef HAVE_LIBUSB + if (libusb_ctx.libhandle) { + LIBUSB_hid_free_enumeration(usb_devs); + } +#endif + return devs; + +#else + return NULL; +#endif /* HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || HAVE_LIBUSB */ +} + +void SDL_hid_free_enumeration(struct SDL_hid_device_info *devs) +{ + while (devs) { + struct SDL_hid_device_info *next = devs->next; + SDL_free(devs->path); + SDL_free(devs->serial_number); + SDL_free(devs->manufacturer_string); + SDL_free(devs->product_string); + SDL_free(devs); + devs = next; + } +} + +SDL_hid_device *SDL_hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number) +{ +#if defined(HAVE_PLATFORM_BACKEND) || HAVE_DRIVER_BACKEND || defined(HAVE_LIBUSB) + void *pDevice = NULL; + + if (SDL_hidapi_refcount == 0 && SDL_hid_init() != 0) { + return NULL; + } + +#ifdef HAVE_PLATFORM_BACKEND + if (udev_ctx) { + pDevice = PLATFORM_hid_open(vendor_id, product_id, serial_number); + if (pDevice != NULL) { + return CreateHIDDeviceWrapper(pDevice, &PLATFORM_Backend); + } + } +#endif /* HAVE_PLATFORM_BACKEND */ + +#if HAVE_DRIVER_BACKEND + pDevice = DRIVER_hid_open(vendor_id, product_id, serial_number); + if (pDevice != NULL) { + return CreateHIDDeviceWrapper(pDevice, &DRIVER_Backend); + } +#endif /* HAVE_DRIVER_BACKEND */ + +#ifdef HAVE_LIBUSB + if (libusb_ctx.libhandle != NULL) { + pDevice = LIBUSB_hid_open(vendor_id, product_id, serial_number); + if (pDevice != NULL) { + return CreateHIDDeviceWrapper(pDevice, &LIBUSB_Backend); + } + } +#endif /* HAVE_LIBUSB */ + +#endif /* HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || HAVE_LIBUSB */ + + return NULL; +} + +SDL_hid_device *SDL_hid_open_path(const char *path, int bExclusive /* = false */) +{ +#if defined(HAVE_PLATFORM_BACKEND) || HAVE_DRIVER_BACKEND || defined(HAVE_LIBUSB) + void *pDevice = NULL; + + if (SDL_hidapi_refcount == 0 && SDL_hid_init() != 0) { + return NULL; + } + +#ifdef HAVE_PLATFORM_BACKEND + if (udev_ctx) { + pDevice = PLATFORM_hid_open_path(path, bExclusive); + if (pDevice != NULL) { + return CreateHIDDeviceWrapper(pDevice, &PLATFORM_Backend); + } + } +#endif /* HAVE_PLATFORM_BACKEND */ + +#if HAVE_DRIVER_BACKEND + pDevice = DRIVER_hid_open_path(path, bExclusive); + if (pDevice != NULL) { + return CreateHIDDeviceWrapper(pDevice, &DRIVER_Backend); + } +#endif /* HAVE_DRIVER_BACKEND */ + +#ifdef HAVE_LIBUSB + if (libusb_ctx.libhandle != NULL) { + pDevice = LIBUSB_hid_open_path(path, bExclusive); + if (pDevice != NULL) { + return CreateHIDDeviceWrapper(pDevice, &LIBUSB_Backend); + } + } +#endif /* HAVE_LIBUSB */ + +#endif /* HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || HAVE_LIBUSB */ + + return NULL; +} + +int SDL_hid_write(SDL_hid_device *device, const unsigned char *data, size_t length) +{ + int result; + + CHECK_DEVICE_MAGIC(device, -1); + + result = device->backend->hid_write(device->device, data, length); + if (result < 0) { + SDL_SetHIDAPIError(device->backend->hid_error(device->device)); + } + return result; +} + +int SDL_hid_read_timeout(SDL_hid_device *device, unsigned char *data, size_t length, int milliseconds) +{ + int result; + + CHECK_DEVICE_MAGIC(device, -1); + + result = device->backend->hid_read_timeout(device->device, data, length, milliseconds); + if (result < 0) { + SDL_SetHIDAPIError(device->backend->hid_error(device->device)); + } + return result; +} + +int SDL_hid_read(SDL_hid_device *device, unsigned char *data, size_t length) +{ + int result; + + CHECK_DEVICE_MAGIC(device, -1); + + result = device->backend->hid_read(device->device, data, length); + if (result < 0) { + SDL_SetHIDAPIError(device->backend->hid_error(device->device)); + } + return result; +} + +int SDL_hid_set_nonblocking(SDL_hid_device *device, int nonblock) +{ + int result; + + CHECK_DEVICE_MAGIC(device, -1); + + result = device->backend->hid_set_nonblocking(device->device, nonblock); + if (result < 0) { + SDL_SetHIDAPIError(device->backend->hid_error(device->device)); + } + return result; +} + +int SDL_hid_send_feature_report(SDL_hid_device *device, const unsigned char *data, size_t length) +{ + int result; + + CHECK_DEVICE_MAGIC(device, -1); + + result = device->backend->hid_send_feature_report(device->device, data, length); + if (result < 0) { + SDL_SetHIDAPIError(device->backend->hid_error(device->device)); + } + return result; +} + +int SDL_hid_get_feature_report(SDL_hid_device *device, unsigned char *data, size_t length) +{ + int result; + + CHECK_DEVICE_MAGIC(device, -1); + + result = device->backend->hid_get_feature_report(device->device, data, length); + if (result < 0) { + SDL_SetHIDAPIError(device->backend->hid_error(device->device)); + } + return result; +} + +void SDL_hid_close(SDL_hid_device *device) +{ + CHECK_DEVICE_MAGIC(device, ); + + device->backend->hid_close(device->device); + DeleteHIDDeviceWrapper(device); +} + +int SDL_hid_get_manufacturer_string(SDL_hid_device *device, wchar_t *string, size_t maxlen) +{ + int result; + + CHECK_DEVICE_MAGIC(device, -1); + + result = device->backend->hid_get_manufacturer_string(device->device, string, maxlen); + if (result < 0) { + SDL_SetHIDAPIError(device->backend->hid_error(device->device)); + } + return result; +} + +int SDL_hid_get_product_string(SDL_hid_device *device, wchar_t *string, size_t maxlen) +{ + int result; + + CHECK_DEVICE_MAGIC(device, -1); + + result = device->backend->hid_get_product_string(device->device, string, maxlen); + if (result < 0) { + SDL_SetHIDAPIError(device->backend->hid_error(device->device)); + } + return result; +} + +int SDL_hid_get_serial_number_string(SDL_hid_device *device, wchar_t *string, size_t maxlen) +{ + int result; + + CHECK_DEVICE_MAGIC(device, -1); + + result = device->backend->hid_get_serial_number_string(device->device, string, maxlen); + if (result < 0) { + SDL_SetHIDAPIError(device->backend->hid_error(device->device)); + } + return result; +} + +int SDL_hid_get_indexed_string(SDL_hid_device *device, int string_index, wchar_t *string, size_t maxlen) +{ + int result; + + CHECK_DEVICE_MAGIC(device, -1); + + result = device->backend->hid_get_indexed_string(device->device, string_index, string, maxlen); + if (result < 0) { + SDL_SetHIDAPIError(device->backend->hid_error(device->device)); + } + return result; +} + +void SDL_hid_ble_scan(SDL_bool active) +{ +#if !defined(SDL_HIDAPI_DISABLED) && (defined(__IPHONEOS__) || defined(__TVOS__)) + hid_ble_scan(active); +#endif +} + +#ifdef HAVE_ENABLE_GAMECUBE_ADAPTORS +/* This is needed to enable input for Nyko and EVORETRO GameCube adaptors */ +void SDL_EnableGameCubeAdaptors(void) +{ +#ifdef HAVE_LIBUSB + libusb_context *context = NULL; + libusb_device **devs = NULL; + libusb_device_handle *handle = NULL; + struct libusb_device_descriptor desc; + ssize_t i, num_devs; + int kernel_detached = 0; + + if (libusb_ctx.libhandle == NULL) { + return; + } + + if (libusb_ctx.init(&context) == 0) { + num_devs = libusb_ctx.get_device_list(context, &devs); + for (i = 0; i < num_devs; ++i) { + if (libusb_ctx.get_device_descriptor(devs[i], &desc) != 0) { + continue; + } + + if (desc.idVendor != 0x057e || desc.idProduct != 0x0337) { + continue; + } + + if (libusb_ctx.open(devs[i], &handle) != 0) { + continue; + } + + if (libusb_ctx.kernel_driver_active(handle, 0)) { + if (libusb_ctx.detach_kernel_driver(handle, 0) == 0) { + kernel_detached = 1; + } + } + + if (libusb_ctx.claim_interface(handle, 0) == 0) { + libusb_ctx.control_transfer(handle, 0x21, 11, 0x0001, 0, NULL, 0, 1000); + libusb_ctx.release_interface(handle, 0); + } + + if (kernel_detached) { + libusb_ctx.attach_kernel_driver(handle, 0); + } + + libusb_ctx.close(handle); + } + + libusb_ctx.free_device_list(devs, 1); + + libusb_ctx.exit(context); + } +#endif /* HAVE_LIBUSB */ +} +#endif /* HAVE_ENABLE_GAMECUBE_ADAPTORS */ + +/* vi: set sts=4 ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/hidapi/SDL_hidapi_c.h b/SDL2-2.30.5/src/hidapi/SDL_hidapi_c.h new file mode 100644 index 0000000..51fe013 --- /dev/null +++ b/SDL2-2.30.5/src/hidapi/SDL_hidapi_c.h @@ -0,0 +1,35 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_JOYSTICK_HIDAPI + +#ifdef HAVE_LIBUSB +#define HAVE_ENABLE_GAMECUBE_ADAPTORS +#endif + +#ifdef HAVE_ENABLE_GAMECUBE_ADAPTORS +extern void SDL_EnableGameCubeAdaptors(void); +#endif + +#endif /* SDL_JOYSTICK_HIDAPI */ + +/* vi: set sts=4 ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/hidapi/android/hid.cpp b/SDL2-2.30.5/src/hidapi/android/hid.cpp similarity index 71% rename from SDL2-2.0.12/src/hidapi/android/hid.cpp rename to SDL2-2.30.5/src/hidapi/android/hid.cpp index dd0edf1..3b050a6 100644 --- a/SDL2-2.0.12/src/hidapi/android/hid.cpp +++ b/SDL2-2.30.5/src/hidapi/android/hid.cpp @@ -1,17 +1,33 @@ -//=================== Copyright Valve Corporation, All rights reserved. ======= -// +/* + Simple DirectMedia Layer + Copyright (C) 2021 Valve Corporation + + 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" + // Purpose: A wrapper implementing "HID" API for Android // // This layer glues the hidapi API to Android's USB and BLE stack. -// -//============================================================================= + +// Common to stub version and non-stub version of functions #include #include -#include -#include // For ETIMEDOUT and ECONNRESET -#include // For malloc() and free() -#include // For memcpy() #define TAG "hidapi" @@ -31,6 +47,35 @@ #define CONCAT2(prefix, class, function) Java_ ## prefix ## _ ## class ## _ ## function #define HID_DEVICE_MANAGER_JAVA_INTERFACE(function) CONCAT1(SDL_JAVA_PREFIX, HIDDeviceManager, function) + +#ifndef SDL_HIDAPI_DISABLED + +#include "SDL_hints.h" +#include "../../core/android/SDL_android.h" + +#define hid_init PLATFORM_hid_init +#define hid_exit PLATFORM_hid_exit +#define hid_enumerate PLATFORM_hid_enumerate +#define hid_free_enumeration PLATFORM_hid_free_enumeration +#define hid_open PLATFORM_hid_open +#define hid_open_path PLATFORM_hid_open_path +#define hid_write PLATFORM_hid_write +#define hid_read_timeout PLATFORM_hid_read_timeout +#define hid_read PLATFORM_hid_read +#define hid_set_nonblocking PLATFORM_hid_set_nonblocking +#define hid_send_feature_report PLATFORM_hid_send_feature_report +#define hid_get_feature_report PLATFORM_hid_get_feature_report +#define hid_close PLATFORM_hid_close +#define hid_get_manufacturer_string PLATFORM_hid_get_manufacturer_string +#define hid_get_product_string PLATFORM_hid_get_product_string +#define hid_get_serial_number_string PLATFORM_hid_get_serial_number_string +#define hid_get_indexed_string PLATFORM_hid_get_indexed_string +#define hid_error PLATFORM_hid_error + +#include +#include // For ETIMEDOUT and ECONNRESET +#include // For malloc() and free() + #include "../hidapi/hidapi.h" typedef uint32_t uint32; @@ -154,7 +199,7 @@ public: } m_nSize = nSize; - memcpy( m_pData, pData, nSize ); + SDL_memcpy( m_pData, pData, nSize ); } void clear() @@ -269,9 +314,9 @@ private: static jbyteArray NewByteArray( JNIEnv* env, const uint8_t *pData, size_t nDataLen ) { - jbyteArray array = env->NewByteArray( nDataLen ); + jbyteArray array = env->NewByteArray( (jsize)nDataLen ); jbyte *pBuf = env->GetByteArrayElements( array, NULL ); - memcpy( pBuf, pData, nDataLen ); + SDL_memcpy( pBuf, pData, nDataLen ); env->ReleaseByteArrayElements( array, pBuf, 0 ); return array; @@ -282,7 +327,7 @@ static char *CreateStringFromJString( JNIEnv *env, const jstring &sString ) size_t nLength = env->GetStringUTFLength( sString ); const char *pjChars = env->GetStringUTFChars( sString, NULL ); char *psString = (char*)malloc( nLength + 1 ); - memcpy( psString, pjChars, nLength ); + SDL_memcpy( psString, pjChars, nLength ); psString[ nLength ] = '\0'; env->ReleaseStringUTFChars( sString, pjChars ); return psString; @@ -305,9 +350,9 @@ static wchar_t *CreateWStringFromJString( JNIEnv *env, const jstring &sString ) static wchar_t *CreateWStringFromWString( const wchar_t *pwSrc ) { - size_t nLength = wcslen( pwSrc ); + size_t nLength = SDL_wcslen( pwSrc ); wchar_t *pwString = (wchar_t*)malloc( ( nLength + 1 ) * sizeof( wchar_t ) ); - memcpy( pwString, pwSrc, nLength * sizeof( wchar_t ) ); + SDL_memcpy( pwString, pwSrc, nLength * sizeof( wchar_t ) ); pwString[ nLength ] = '\0'; return pwString; } @@ -316,7 +361,7 @@ static hid_device_info *CopyHIDDeviceInfo( const hid_device_info *pInfo ) { hid_device_info *pCopy = new hid_device_info; *pCopy = *pInfo; - pCopy->path = strdup( pInfo->path ); + pCopy->path = SDL_strdup( pInfo->path ); pCopy->product_string = CreateWStringFromWString( pInfo->product_string ); pCopy->manufacturer_string = CreateWStringFromWString( pInfo->manufacturer_string ); pCopy->serial_number = CreateWStringFromWString( pInfo->serial_number ); @@ -334,17 +379,49 @@ static void FreeHIDDeviceInfo( hid_device_info *pInfo ) static jclass g_HIDDeviceManagerCallbackClass; static jobject g_HIDDeviceManagerCallbackHandler; +static jmethodID g_midHIDDeviceManagerInitialize; static jmethodID g_midHIDDeviceManagerOpen; static jmethodID g_midHIDDeviceManagerSendOutputReport; static jmethodID g_midHIDDeviceManagerSendFeatureReport; static jmethodID g_midHIDDeviceManagerGetFeatureReport; static jmethodID g_midHIDDeviceManagerClose; +static bool g_initialized = false; static uint64_t get_timespec_ms( const struct timespec &ts ) { return (uint64_t)ts.tv_sec * 1000 + ts.tv_nsec / 1000000; } +static void ExceptionCheck( JNIEnv *env, const char *pszClassName, const char *pszMethodName ) +{ + if ( env->ExceptionCheck() ) + { + // Get our exception + jthrowable jExcept = env->ExceptionOccurred(); + + // Clear the exception so we can call JNI again + env->ExceptionClear(); + + // Get our exception message + jclass jExceptClass = env->GetObjectClass( jExcept ); + jmethodID jMessageMethod = env->GetMethodID( jExceptClass, "getMessage", "()Ljava/lang/String;" ); + jstring jMessage = (jstring)( env->CallObjectMethod( jExcept, jMessageMethod ) ); + const char *pszMessage = env->GetStringUTFChars( jMessage, NULL ); + + // ...and log it. + LOGE( "%s%s%s threw an exception: %s", + pszClassName ? pszClassName : "", + pszClassName ? "::" : "", + pszMethodName, pszMessage ); + + // Cleanup + env->ReleaseStringUTFChars( jMessage, pszMessage ); + env->DeleteLocalRef( jMessage ); + env->DeleteLocalRef( jExceptClass ); + env->DeleteLocalRef( jExcept ); + } +} + class CHIDDevice { public: @@ -404,29 +481,7 @@ public: void ExceptionCheck( JNIEnv *env, const char *pszMethodName ) { - if ( env->ExceptionCheck() ) - { - // Get our exception - jthrowable jExcept = env->ExceptionOccurred(); - - // Clear the exception so we can call JNI again - env->ExceptionClear(); - - // Get our exception message - jclass jExceptClass = env->GetObjectClass( jExcept ); - jmethodID jMessageMethod = env->GetMethodID( jExceptClass, "getMessage", "()Ljava/lang/String;" ); - jstring jMessage = (jstring)( env->CallObjectMethod( jExcept, jMessageMethod ) ); - const char *pszMessage = env->GetStringUTFChars( jMessage, NULL ); - - // ...and log it. - LOGE( "CHIDDevice::%s threw an exception: %s", pszMethodName, pszMessage ); - - // Cleanup - env->ReleaseStringUTFChars( jMessage, pszMessage ); - env->DeleteLocalRef( jMessage ); - env->DeleteLocalRef( jExceptClass ); - env->DeleteLocalRef( jExcept ); - } + ::ExceptionCheck( env, "CHIDDevice", pszMethodName ); } bool BOpen() @@ -436,6 +491,12 @@ public: g_JVM->AttachCurrentThread( &env, NULL ); pthread_setspecific( g_ThreadKey, (void*)env ); + if ( !g_HIDDeviceManagerCallbackHandler ) + { + LOGV( "Device open without callback handler" ); + return false; + } + m_bIsWaitingForOpen = false; m_bOpenResult = env->CallBooleanMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerOpen, m_nId ); ExceptionCheck( env, "BOpen" ); @@ -521,12 +582,12 @@ public: if ( m_bIsBLESteamController ) { data[0] = 0x03; - memcpy( data + 1, buffer.data(), nDataLen ); + SDL_memcpy( data + 1, buffer.data(), nDataLen ); ++nDataLen; } else { - memcpy( data, buffer.data(), nDataLen ); + SDL_memcpy( data, buffer.data(), nDataLen ); } m_vecData.pop_front(); @@ -535,7 +596,7 @@ public: // data[0], data[1], data[2], data[3], // data[4], data[5], data[6], data[7]); - return nDataLen; + return (int)nDataLen; } int SendOutputReport( const unsigned char *pData, size_t nDataLen ) @@ -545,11 +606,18 @@ public: g_JVM->AttachCurrentThread( &env, NULL ); pthread_setspecific( g_ThreadKey, (void*)env ); - jbyteArray pBuf = NewByteArray( env, pData, nDataLen ); - int nRet = env->CallIntMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerSendOutputReport, m_nId, pBuf ); - ExceptionCheck( env, "SendOutputReport" ); - - env->DeleteLocalRef( pBuf ); + int nRet = -1; + if ( g_HIDDeviceManagerCallbackHandler ) + { + jbyteArray pBuf = NewByteArray( env, pData, nDataLen ); + nRet = env->CallIntMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerSendOutputReport, m_nId, pBuf ); + ExceptionCheck( env, "SendOutputReport" ); + env->DeleteLocalRef( pBuf ); + } + else + { + LOGV( "SendOutputReport without callback handler" ); + } return nRet; } @@ -560,10 +628,18 @@ public: g_JVM->AttachCurrentThread( &env, NULL ); pthread_setspecific( g_ThreadKey, (void*)env ); - jbyteArray pBuf = NewByteArray( env, pData, nDataLen ); - int nRet = env->CallIntMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerSendFeatureReport, m_nId, pBuf ); - ExceptionCheck( env, "SendFeatureReport" ); - env->DeleteLocalRef( pBuf ); + int nRet = -1; + if ( g_HIDDeviceManagerCallbackHandler ) + { + jbyteArray pBuf = NewByteArray( env, pData, nDataLen ); + nRet = env->CallIntMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerSendFeatureReport, m_nId, pBuf ); + ExceptionCheck( env, "SendFeatureReport" ); + env->DeleteLocalRef( pBuf ); + } + else + { + LOGV( "SendFeatureReport without callback handler" ); + } return nRet; } @@ -587,6 +663,12 @@ public: g_JVM->AttachCurrentThread( &env, NULL ); pthread_setspecific( g_ThreadKey, (void*)env ); + if ( !g_HIDDeviceManagerCallbackHandler ) + { + LOGV( "GetFeatureReport without callback handler" ); + return -1; + } + { hid_mutex_guard cvl( &m_cvLock ); if ( m_bIsWaitingForFeatureReport ) @@ -642,11 +724,11 @@ public: } size_t uBytesToCopy = m_featureReport.size() > nDataLen ? nDataLen : m_featureReport.size(); - memcpy( pData, m_featureReport.data(), uBytesToCopy ); + SDL_memcpy( pData, m_featureReport.data(), uBytesToCopy ); m_featureReport.clear(); LOGV( "=== Got %u bytes", uBytesToCopy ); - return uBytesToCopy; + return (int)uBytesToCopy; } } @@ -657,9 +739,12 @@ public: g_JVM->AttachCurrentThread( &env, NULL ); pthread_setspecific( g_ThreadKey, (void*)env ); - env->CallVoidMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerClose, m_nId ); - ExceptionCheck( env, "Close" ); - + if ( g_HIDDeviceManagerCallbackHandler ) + { + env->CallVoidMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerClose, m_nId ); + ExceptionCheck( env, "Close" ); + } + hid_mutex_guard dataLock( &m_dataLock ); m_vecData.clear(); @@ -785,6 +870,11 @@ JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceRegisterCallba if ( objClass ) { g_HIDDeviceManagerCallbackClass = reinterpret_cast< jclass >( env->NewGlobalRef( objClass ) ); + g_midHIDDeviceManagerInitialize = env->GetMethodID( g_HIDDeviceManagerCallbackClass, "initialize", "(ZZ)Z" ); + if ( !g_midHIDDeviceManagerInitialize ) + { + __android_log_print(ANDROID_LOG_ERROR, TAG, "HIDDeviceRegisterCallback: callback class missing initialize" ); + } g_midHIDDeviceManagerOpen = env->GetMethodID( g_HIDDeviceManagerCallbackClass, "openDevice", "(I)Z" ); if ( !g_midHIDDeviceManagerOpen ) { @@ -824,6 +914,7 @@ JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceReleaseCallbac g_HIDDeviceManagerCallbackClass = NULL; env->DeleteGlobalRef( g_HIDDeviceManagerCallbackHandler ); g_HIDDeviceManagerCallbackHandler = NULL; + g_initialized = false; } } @@ -833,7 +924,7 @@ JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceConnected)(JNI LOGV( "HIDDeviceConnected() id=%d VID/PID = %.4x/%.4x, interface %d\n", nDeviceID, nVendorId, nProductId, nInterface ); hid_device_info *pInfo = new hid_device_info; - memset( pInfo, 0, sizeof( *pInfo ) ); + SDL_memset( pInfo, 0, sizeof( *pInfo ) ); pInfo->path = CreateStringFromJString( env, sIdentifier ); pInfo->vendor_id = nVendorId; pInfo->product_id = nProductId; @@ -958,18 +1049,61 @@ extern "C" int hid_init(void) { + if ( !g_initialized ) + { + // HIDAPI doesn't work well with Android < 4.3 + if (SDL_GetAndroidSDKVersion() >= 18) { + // Make sure thread is attached to JVM/env + JNIEnv *env; + g_JVM->AttachCurrentThread( &env, NULL ); + pthread_setspecific( g_ThreadKey, (void*)env ); + + if ( !g_HIDDeviceManagerCallbackHandler ) + { + LOGV( "hid_init() without callback handler" ); + return -1; + } + + // Bluetooth is currently only used for Steam Controllers, so check that hint + // before initializing Bluetooth, which will prompt the user for permission. + bool init_usb = true; + bool init_bluetooth = false; + if (SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_STEAM, SDL_FALSE)) { + if (SDL_GetAndroidSDKVersion() < 31 || + Android_JNI_RequestPermission("android.permission.BLUETOOTH_CONNECT")) { + init_bluetooth = true; + } + } + env->CallBooleanMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerInitialize, init_usb, init_bluetooth ); + ExceptionCheck( env, NULL, "hid_init" ); + } + g_initialized = true; // Regardless of result, so it's only called once + } return 0; } struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id) { struct hid_device_info *root = NULL; + const char *hint = SDL_GetHint(SDL_HINT_HIDAPI_IGNORE_DEVICES); + hid_mutex_guard l( &g_DevicesMutex ); for ( hid_device_ref pDevice = g_Devices; pDevice; pDevice = pDevice->next ) { const hid_device_info *info = pDevice->GetDeviceInfo(); - if ( ( vendor_id == 0 && product_id == 0 ) || - ( vendor_id == info->vendor_id && product_id == info->product_id ) ) + + /* See if there are any devices we should skip in enumeration */ + if (hint) { + char vendor_match[16], product_match[16]; + SDL_snprintf(vendor_match, sizeof(vendor_match), "0x%.4x/0x0000", info->vendor_id); + SDL_snprintf(product_match, sizeof(product_match), "0x%.4x/0x%.4x", info->vendor_id, info->product_id); + if (SDL_strcasestr(hint, vendor_match) || SDL_strcasestr(hint, product_match)) { + continue; + } + } + + if ( ( vendor_id == 0x0 || info->vendor_id == vendor_id ) && + ( product_id == 0x0 || info->product_id == product_id ) ) { hid_device_info *dev = CopyHIDDeviceInfo( info ); dev->next = root; @@ -1005,7 +1139,7 @@ HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path, int bEx hid_mutex_guard l( &g_DevicesMutex ); for ( hid_device_ref pCurr = g_Devices; pCurr; pCurr = pCurr->next ) { - if ( strcmp( pCurr->GetDeviceInfo()->path, path ) == 0 ) + if ( SDL_strcmp( pCurr->GetDeviceInfo()->path, path ) == 0 ) { hid_device *pValue = pCurr->GetDevice(); if ( pValue ) @@ -1042,7 +1176,32 @@ int HID_API_EXPORT HID_API_CALL hid_write(hid_device *device, const unsigned ch return -1; // Controller was disconnected } -// TODO: Implement timeout? +static uint32_t getms() +{ + struct timeval now; + + gettimeofday(&now, NULL); + return (uint32_t)(now.tv_sec * 1000 + now.tv_usec / 1000); +} + +static void delayms(uint32_t ms) +{ + int was_error; + + struct timespec elapsed, tv; + + /* Set the timeout interval */ + elapsed.tv_sec = ms / 1000; + elapsed.tv_nsec = (ms % 1000) * 1000000; + do { + errno = 0; + + tv.tv_sec = elapsed.tv_sec; + tv.tv_nsec = elapsed.tv_nsec; + was_error = nanosleep(&tv, &elapsed); + } while (was_error && (errno == EINTR)); +} + int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *device, unsigned char *data, size_t length, int milliseconds) { if ( device ) @@ -1051,7 +1210,17 @@ int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *device, unsigned ch hid_device_ref pDevice = FindDevice( device->m_nId ); if ( pDevice ) { - return pDevice->GetInput( data, length ); + int nResult = pDevice->GetInput( data, length ); + if ( nResult == 0 && milliseconds > 0 ) + { + uint32_t start = getms(); + do + { + delayms( 1 ); + nResult = pDevice->GetInput( data, length ); + } while ( nResult == 0 && ( getms() - start ) < milliseconds ); + } + return nResult; } LOGV( "controller was disconnected" ); } @@ -1183,3 +1352,80 @@ int hid_exit(void) } } + +#else + +extern "C" +JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceRegisterCallback)(JNIEnv *env, jobject thiz); + +extern "C" +JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceReleaseCallback)(JNIEnv *env, jobject thiz); + +extern "C" +JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceConnected)(JNIEnv *env, jobject thiz, int nDeviceID, jstring sIdentifier, int nVendorId, int nProductId, jstring sSerialNumber, int nReleaseNumber, jstring sManufacturer, jstring sProduct, int nInterface, int nInterfaceClass, int nInterfaceSubclass, int nInterfaceProtocol ); + +extern "C" +JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceOpenPending)(JNIEnv *env, jobject thiz, int nDeviceID); + +extern "C" +JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceOpenResult)(JNIEnv *env, jobject thiz, int nDeviceID, bool bOpened); + +extern "C" +JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceDisconnected)(JNIEnv *env, jobject thiz, int nDeviceID); + +extern "C" +JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceInputReport)(JNIEnv *env, jobject thiz, int nDeviceID, jbyteArray value); + +extern "C" +JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceFeatureReport)(JNIEnv *env, jobject thiz, int nDeviceID, jbyteArray value); + + +extern "C" +JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceRegisterCallback)(JNIEnv *env, jobject thiz ) +{ + LOGV("Stub HIDDeviceRegisterCallback()"); +} + +extern "C" +JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceReleaseCallback)(JNIEnv *env, jobject thiz) +{ + LOGV("Stub HIDDeviceReleaseCallback()"); +} + +extern "C" +JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceConnected)(JNIEnv *env, jobject thiz, int nDeviceID, jstring sIdentifier, int nVendorId, int nProductId, jstring sSerialNumber, int nReleaseNumber, jstring sManufacturer, jstring sProduct, int nInterface, int nInterfaceClass, int nInterfaceSubclass, int nInterfaceProtocol ) +{ + LOGV("Stub HIDDeviceConnected() id=%d VID/PID = %.4x/%.4x, interface %d\n", nDeviceID, nVendorId, nProductId, nInterface); +} + +extern "C" +JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceOpenPending)(JNIEnv *env, jobject thiz, int nDeviceID) +{ + LOGV("Stub HIDDeviceOpenPending() id=%d\n", nDeviceID); +} + +extern "C" +JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceOpenResult)(JNIEnv *env, jobject thiz, int nDeviceID, bool bOpened) +{ + LOGV("Stub HIDDeviceOpenResult() id=%d, result=%s\n", nDeviceID, bOpened ? "true" : "false"); +} + +extern "C" +JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceDisconnected)(JNIEnv *env, jobject thiz, int nDeviceID) +{ + LOGV("Stub HIDDeviceDisconnected() id=%d\n", nDeviceID); +} + +extern "C" +JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceInputReport)(JNIEnv *env, jobject thiz, int nDeviceID, jbyteArray value) +{ + LOGV("Stub HIDDeviceInput() id=%d len=%u\n", nDeviceID, nBufSize); +} + +extern "C" +JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceFeatureReport)(JNIEnv *env, jobject thiz, int nDeviceID, jbyteArray value) +{ + LOGV("Stub HIDDeviceFeatureReport() id=%d len=%u\n", nDeviceID, nBufSize); +} + +#endif /* SDL_HIDAPI_DISABLED */ diff --git a/SDL2-2.0.12/src/hidapi/android/jni/Android.mk b/SDL2-2.30.5/src/hidapi/android/jni/Android.mk similarity index 100% rename from SDL2-2.0.12/src/hidapi/android/jni/Android.mk rename to SDL2-2.30.5/src/hidapi/android/jni/Android.mk diff --git a/SDL2-2.0.12/src/hidapi/android/jni/Application.mk b/SDL2-2.30.5/src/hidapi/android/jni/Application.mk similarity index 100% rename from SDL2-2.0.12/src/hidapi/android/jni/Application.mk rename to SDL2-2.30.5/src/hidapi/android/jni/Application.mk diff --git a/SDL2-2.0.12/src/hidapi/android/project.properties b/SDL2-2.30.5/src/hidapi/android/project.properties similarity index 100% rename from SDL2-2.0.12/src/hidapi/android/project.properties rename to SDL2-2.30.5/src/hidapi/android/project.properties diff --git a/SDL2-2.0.12/src/hidapi/bootstrap b/SDL2-2.30.5/src/hidapi/bootstrap similarity index 100% rename from SDL2-2.0.12/src/hidapi/bootstrap rename to SDL2-2.30.5/src/hidapi/bootstrap diff --git a/SDL2-2.0.12/src/hidapi/configure.ac b/SDL2-2.30.5/src/hidapi/configure.ac similarity index 100% rename from SDL2-2.0.12/src/hidapi/configure.ac rename to SDL2-2.30.5/src/hidapi/configure.ac diff --git a/SDL2-2.0.12/src/hidapi/doxygen/Doxyfile b/SDL2-2.30.5/src/hidapi/doxygen/Doxyfile similarity index 100% rename from SDL2-2.0.12/src/hidapi/doxygen/Doxyfile rename to SDL2-2.30.5/src/hidapi/doxygen/Doxyfile diff --git a/SDL2-2.0.12/src/hidapi/hidapi/hidapi.h b/SDL2-2.30.5/src/hidapi/hidapi/hidapi.h similarity index 86% rename from SDL2-2.0.12/src/hidapi/hidapi/hidapi.h rename to SDL2-2.30.5/src/hidapi/hidapi/hidapi.h index 2c66319..1114aef 100644 --- a/SDL2-2.0.12/src/hidapi/hidapi/hidapi.h +++ b/SDL2-2.30.5/src/hidapi/hidapi/hidapi.h @@ -29,7 +29,12 @@ #include -#if defined(_WIN32) && !defined(NAMESPACE) && (0) /* SDL: don't export hidapi syms */ +#ifdef SDL_hidapi_h_ +#define SDL_HIDAPI_IMPLEMENTATION +#define hid_device_info SDL_hid_device_info +#endif + +#if defined(_WIN32) && !defined(NAMESPACE) && !defined(SDL_HIDAPI_IMPLEMENTATION) /* SDL: don't export hidapi syms */ #define HID_API_EXPORT __declspec(dllexport) #define HID_API_CALL #else @@ -53,6 +58,7 @@ namespace NAMESPACE { struct hid_device_; typedef struct hid_device_ hid_device; /**< opaque hidapi structure */ +#ifndef SDL_HIDAPI_IMPLEMENTATION /** hidapi info structure */ struct hid_device_info { /** Platform-specific device path */ @@ -77,9 +83,11 @@ namespace NAMESPACE { (Windows/Mac only).*/ unsigned short usage; /** The USB interface which this logical device - represents. Valid on both Linux implementations - in all cases, and valid on the Windows implementation - only if the device contains more than one interface. */ + represents. + + * Valid on both Linux implementations in all cases. + * Valid on the Windows implementation only if the device + contains more than one interface. */ int interface_number; /** Additional information about the USB interface. @@ -91,6 +99,7 @@ namespace NAMESPACE { /** Pointer to the next device */ struct hid_device_info *next; }; +#endif /* !SDL_HIDAPI_IMPLEMENTATION */ /** @brief Initialize the HIDAPI library. @@ -101,7 +110,7 @@ namespace NAMESPACE { needed. This function should be called at the beginning of execution however, if there is a chance of HIDAPI handles being opened by different threads simultaneously. - + @ingroup API @returns @@ -139,7 +148,7 @@ namespace NAMESPACE { @returns This function returns a pointer to a linked list of type - struct #hid_device, containing information about the HID devices + struct #hid_device_info, containing information about the HID devices attached to the system, or NULL in the case of failure. Free this linked list by calling hid_free_enumeration(). */ @@ -205,7 +214,7 @@ namespace NAMESPACE { the Control Endpoint (Endpoint 0). @ingroup API - @param device A device handle returned from hid_open(). + @param dev A device handle returned from hid_open(). @param data The data to send, including the report number as the first byte. @param length The length in bytes of the data to send. @@ -214,7 +223,7 @@ namespace NAMESPACE { This function returns the actual number of bytes written and -1 on error. */ - int HID_API_EXPORT HID_API_CALL hid_write(hid_device *device, const unsigned char *data, size_t length); + int HID_API_EXPORT HID_API_CALL hid_write(hid_device *dev, const unsigned char *data, size_t length); /** @brief Read an Input report from a HID device with timeout. @@ -223,7 +232,7 @@ namespace NAMESPACE { contain the Report number if the device uses numbered reports. @ingroup API - @param device A device handle returned from hid_open(). + @param dev A device handle returned from hid_open(). @param data A buffer to put the read data into. @param length The number of bytes to read. For devices with multiple reports, make sure to read an extra byte for @@ -235,7 +244,7 @@ namespace NAMESPACE { -1 on error. If no packet was available to be read within the timeout period, this function returns 0. */ - int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *device, unsigned char *data, size_t length, int milliseconds); + int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds); /** @brief Read an Input report from a HID device. @@ -244,7 +253,7 @@ namespace NAMESPACE { contain the Report number if the device uses numbered reports. @ingroup API - @param device A device handle returned from hid_open(). + @param dev A device handle returned from hid_open(). @param data A buffer to put the read data into. @param length The number of bytes to read. For devices with multiple reports, make sure to read an extra byte for @@ -255,7 +264,7 @@ namespace NAMESPACE { -1 on error. If no packet was available to be read and the handle is in non-blocking mode, this function returns 0. */ - int HID_API_EXPORT HID_API_CALL hid_read(hid_device *device, unsigned char *data, size_t length); + int HID_API_EXPORT HID_API_CALL hid_read(hid_device *dev, unsigned char *data, size_t length); /** @brief Set the device handle to be non-blocking. @@ -267,7 +276,7 @@ namespace NAMESPACE { Nonblocking can be turned on and off at any time. @ingroup API - @param device A device handle returned from hid_open(). + @param dev A device handle returned from hid_open(). @param nonblock enable or not the nonblocking reads - 1 to enable nonblocking - 0 to disable nonblocking. @@ -275,7 +284,7 @@ namespace NAMESPACE { @returns This function returns 0 on success and -1 on error. */ - int HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *device, int nonblock); + int HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *dev, int nonblock); /** @brief Send a Feature report to the device. @@ -293,7 +302,7 @@ namespace NAMESPACE { in would be 17. @ingroup API - @param device A device handle returned from hid_open(). + @param dev A device handle returned from hid_open(). @param data The data to send, including the report number as the first byte. @param length The length in bytes of the data to send, including @@ -303,7 +312,7 @@ namespace NAMESPACE { This function returns the actual number of bytes written and -1 on error. */ - int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *device, const unsigned char *data, size_t length); + int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length); /** @brief Get a feature report from a HID device. @@ -314,7 +323,7 @@ namespace NAMESPACE { start in data[1]. @ingroup API - @param device A device handle returned from hid_open(). + @param dev A device handle returned from hid_open(). @param data A buffer to put the read data into, including the Report ID. Set the first byte of @p data[] to the Report ID of the report to be read, or set it to zero @@ -328,55 +337,55 @@ namespace NAMESPACE { one for the report ID (which is still in the first byte), or -1 on error. */ - int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *device, unsigned char *data, size_t length); + int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length); /** @brief Close a HID device. @ingroup API - @param device A device handle returned from hid_open(). + @param dev A device handle returned from hid_open(). */ - void HID_API_EXPORT HID_API_CALL hid_close(hid_device *device); + void HID_API_EXPORT HID_API_CALL hid_close(hid_device *dev); /** @brief Get The Manufacturer String from a HID device. @ingroup API - @param device A device handle returned from hid_open(). + @param dev A device handle returned from hid_open(). @param string A wide string buffer to put the data into. @param maxlen The length of the buffer in multiples of wchar_t. @returns This function returns 0 on success and -1 on error. */ - int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *device, wchar_t *string, size_t maxlen); + int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen); /** @brief Get The Product String from a HID device. @ingroup API - @param device A device handle returned from hid_open(). + @param dev A device handle returned from hid_open(). @param string A wide string buffer to put the data into. @param maxlen The length of the buffer in multiples of wchar_t. @returns This function returns 0 on success and -1 on error. */ - int HID_API_EXPORT_CALL hid_get_product_string(hid_device *device, wchar_t *string, size_t maxlen); + int HID_API_EXPORT_CALL hid_get_product_string(hid_device *dev, wchar_t *string, size_t maxlen); /** @brief Get The Serial Number String from a HID device. @ingroup API - @param device A device handle returned from hid_open(). + @param dev A device handle returned from hid_open(). @param string A wide string buffer to put the data into. @param maxlen The length of the buffer in multiples of wchar_t. @returns This function returns 0 on success and -1 on error. */ - int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *device, wchar_t *string, size_t maxlen); + int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *string, size_t maxlen); /** @brief Get a string from a HID device, based on its string index. @ingroup API - @param device A device handle returned from hid_open(). + @param dev A device handle returned from hid_open(). @param string_index The index of the string to get. @param string A wide string buffer to put the data into. @param maxlen The length of the buffer in multiples of wchar_t. @@ -384,18 +393,22 @@ namespace NAMESPACE { @returns This function returns 0 on success and -1 on error. */ - int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *device, int string_index, wchar_t *string, size_t maxlen); + int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen); /** @brief Get a string describing the last error which occurred. @ingroup API - @param device A device handle returned from hid_open(). + @param dev A device handle returned from hid_open(). @returns This function returns a string containing the last error which occurred or NULL if none has occurred. */ - HID_API_EXPORT const wchar_t* HID_API_CALL hid_error(hid_device *device); + HID_API_EXPORT const wchar_t* HID_API_CALL hid_error(hid_device *dev); + +#if defined(__IPHONEOS__) || defined(__TVOS__) + HID_API_EXPORT void HID_API_CALL hid_ble_scan(int active); +#endif #if defined(__cplusplus) && !defined(NAMESPACE) } diff --git a/SDL2-2.0.12/src/hidapi/hidtest/Makefile.am b/SDL2-2.30.5/src/hidapi/hidtest/Makefile.am similarity index 100% rename from SDL2-2.0.12/src/hidapi/hidtest/Makefile.am rename to SDL2-2.30.5/src/hidapi/hidtest/Makefile.am diff --git a/SDL2-2.0.12/src/hidapi/hidtest/hidtest.cpp b/SDL2-2.30.5/src/hidapi/hidtest/hidtest.cpp similarity index 100% rename from SDL2-2.0.12/src/hidapi/hidtest/hidtest.cpp rename to SDL2-2.30.5/src/hidapi/hidtest/hidtest.cpp diff --git a/SDL2-2.0.12/src/hidapi/ios/Makefile-manual b/SDL2-2.30.5/src/hidapi/ios/Makefile-manual similarity index 100% rename from SDL2-2.0.12/src/hidapi/ios/Makefile-manual rename to SDL2-2.30.5/src/hidapi/ios/Makefile-manual diff --git a/SDL2-2.0.12/src/hidapi/ios/Makefile.am b/SDL2-2.30.5/src/hidapi/ios/Makefile.am similarity index 100% rename from SDL2-2.0.12/src/hidapi/ios/Makefile.am rename to SDL2-2.30.5/src/hidapi/ios/Makefile.am diff --git a/SDL2-2.0.12/src/hidapi/ios/hid.m b/SDL2-2.30.5/src/hidapi/ios/hid.m similarity index 83% rename from SDL2-2.0.12/src/hidapi/ios/hid.m rename to SDL2-2.30.5/src/hidapi/ios/hid.m index 504a994..636d0f0 100644 --- a/SDL2-2.0.12/src/hidapi/ios/hid.m +++ b/SDL2-2.30.5/src/hidapi/ios/hid.m @@ -1,11 +1,47 @@ -//======== Copyright (c) 2017 Valve Corporation, All rights reserved. ========= -// -// Purpose: HID device abstraction temporary stub -// -//============================================================================= +/* + Simple DirectMedia Layer + Copyright (C) 2021 Valve Corporation + + 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" -#ifdef SDL_JOYSTICK_HIDAPI +#ifndef SDL_HIDAPI_DISABLED + +#include "SDL_hints.h" + +#define hid_init PLATFORM_hid_init +#define hid_exit PLATFORM_hid_exit +#define hid_enumerate PLATFORM_hid_enumerate +#define hid_free_enumeration PLATFORM_hid_free_enumeration +#define hid_open PLATFORM_hid_open +#define hid_open_path PLATFORM_hid_open_path +#define hid_write PLATFORM_hid_write +#define hid_read_timeout PLATFORM_hid_read_timeout +#define hid_read PLATFORM_hid_read +#define hid_set_nonblocking PLATFORM_hid_set_nonblocking +#define hid_send_feature_report PLATFORM_hid_send_feature_report +#define hid_get_feature_report PLATFORM_hid_get_feature_report +#define hid_close PLATFORM_hid_close +#define hid_get_manufacturer_string PLATFORM_hid_get_manufacturer_string +#define hid_get_product_string PLATFORM_hid_get_product_string +#define hid_get_serial_number_string PLATFORM_hid_get_serial_number_string +#define hid_get_indexed_string PLATFORM_hid_get_indexed_string +#define hid_error PLATFORM_hid_error #include #include @@ -95,7 +131,7 @@ static void RingBuffer_init( RingBuffer *this ) this->_last = 0; pthread_mutex_init( &this->accessLock, 0 ); } - + static bool RingBuffer_write( RingBuffer *this, const uint8_t *src ) { pthread_mutex_lock( &this->accessLock ); @@ -193,24 +229,29 @@ typedef enum sharedInstance = [HIDBLEManager new]; sharedInstance.nPendingScans = 0; sharedInstance.nPendingPairs = 0; - - [[NSNotificationCenter defaultCenter] addObserver:sharedInstance selector:@selector(appWillResignActiveNotification:) name: UIApplicationWillResignActiveNotification object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:sharedInstance selector:@selector(appDidBecomeActiveNotification:) name:UIApplicationDidBecomeActiveNotification object:nil]; - // receive reports on a high-priority serial-queue. optionally put writes on the serial queue to avoid logical - // race conditions talking to the controller from multiple threads, although BLE fragmentation/assembly means - // that we can still screw this up. - // most importantly we need to consume reports at a high priority to avoid the OS thinking we aren't really - // listening to the BLE device, as iOS on slower devices may stop delivery of packets to the app WITHOUT ACTUALLY - // DISCONNECTING FROM THE DEVICE if we don't react quickly enough to their delivery. - // see also the error-handling states in the peripheral delegate to re-open the device if it gets closed - sharedInstance.bleSerialQueue = dispatch_queue_create( "com.valvesoftware.steamcontroller.ble", DISPATCH_QUEUE_SERIAL ); - dispatch_set_target_queue( sharedInstance.bleSerialQueue, dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_HIGH, 0 ) ); + // Bluetooth is currently only used for Steam Controllers, so check that hint + // before initializing Bluetooth, which will prompt the user for permission. + if ( SDL_GetHintBoolean( SDL_HINT_JOYSTICK_HIDAPI_STEAM, SDL_FALSE ) ) + { + [[NSNotificationCenter defaultCenter] addObserver:sharedInstance selector:@selector(appWillResignActiveNotification:) name: UIApplicationWillResignActiveNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:sharedInstance selector:@selector(appDidBecomeActiveNotification:) name:UIApplicationDidBecomeActiveNotification object:nil]; - // creating a CBCentralManager will always trigger a future centralManagerDidUpdateState: - // where any scanning gets started or connecting to existing peripherals happens, it's never already in a - // powered-on state for a newly launched application. - sharedInstance.centralManager = [[CBCentralManager alloc] initWithDelegate:sharedInstance queue:sharedInstance.bleSerialQueue]; + // receive reports on a high-priority serial-queue. optionally put writes on the serial queue to avoid logical + // race conditions talking to the controller from multiple threads, although BLE fragmentation/assembly means + // that we can still screw this up. + // most importantly we need to consume reports at a high priority to avoid the OS thinking we aren't really + // listening to the BLE device, as iOS on slower devices may stop delivery of packets to the app WITHOUT ACTUALLY + // DISCONNECTING FROM THE DEVICE if we don't react quickly enough to their delivery. + // see also the error-handling states in the peripheral delegate to re-open the device if it gets closed + sharedInstance.bleSerialQueue = dispatch_queue_create( "com.valvesoftware.steamcontroller.ble", DISPATCH_QUEUE_SERIAL ); + dispatch_set_target_queue( sharedInstance.bleSerialQueue, dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_HIGH, 0 ) ); + + // creating a CBCentralManager will always trigger a future centralManagerDidUpdateState: + // where any scanning gets started or connecting to existing peripherals happens, it's never already in a + // powered-on state for a newly launched application. + sharedInstance.centralManager = [[CBCentralManager alloc] initWithDelegate:sharedInstance queue:sharedInstance.bleSerialQueue]; + } sharedInstance.deviceMap = [[NSMapTable alloc] initWithKeyOptions:NSMapTableWeakMemory valueOptions:NSMapTableStrongMemory capacity:4]; }); return sharedInstance; @@ -249,16 +290,21 @@ typedef enum { static uint64_t s_unLastUpdateTick = 0; static mach_timebase_info_data_t s_timebase_info; - + + if ( self.centralManager == nil ) + { + return 0; + } + if (s_timebase_info.denom == 0) { mach_timebase_info( &s_timebase_info ); } - + uint64_t ticksNow = mach_approximate_time(); if ( !bForce && ( ( (ticksNow - s_unLastUpdateTick) * s_timebase_info.numer ) / s_timebase_info.denom ) < (5ull * NSEC_PER_SEC) ) return (int)self.deviceMap.count; - + // we can see previously connected BLE peripherals but can't connect until the CBCentralManager // is fully powered up - only do work when we are in that state if ( self.centralManager.state != CBManagerStatePoweredOn ) @@ -266,7 +312,7 @@ typedef enum // only update our last-check-time if we actually did work, otherwise there can be a long delay during initial power-up s_unLastUpdateTick = mach_approximate_time(); - + // if a pair is in-flight, the central manager may still give it back via retrieveConnected... and // cause the SDL layer to attempt to initialize it while some of its endpoints haven't yet been established if ( self.nPendingPairs > 0 ) @@ -278,7 +324,7 @@ typedef enum // we already know this peripheral if ( [self.deviceMap objectForKey: peripheral] != nil ) continue; - + NSLog( @"connected peripheral: %@", peripheral ); if ( [peripheral.name isEqualToString:@"SteamController"] ) { @@ -295,6 +341,11 @@ typedef enum // manual API for folks to start & stop scanning - (void)startScan:(int)duration { + if ( self.centralManager == nil ) + { + return; + } + NSLog( @"BLE: requesting scan for %d seconds", duration ); @synchronized (self) { @@ -314,6 +365,11 @@ typedef enum - (void)stopScan { + if ( self.centralManager == nil ) + { + return; + } + NSLog( @"BLE: stopping scan" ); @synchronized (self) { @@ -336,7 +392,7 @@ typedef enum case CBCentralManagerStatePoweredOn: { NSLog( @"CoreBluetooth BLE hardware is powered on and ready" ); - + // at startup, if we have no already attached peripherals, do a 20s scan for new unpaired devices, // otherwise callers should occaisionally do additional scans. we don't want to continuously be // scanning because it drains battery, causes other nearby people to have a hard time pairing their @@ -352,23 +408,23 @@ typedef enum } break; } - + case CBCentralManagerStatePoweredOff: NSLog( @"CoreBluetooth BLE hardware is powered off" ); break; - + case CBCentralManagerStateUnauthorized: NSLog( @"CoreBluetooth BLE state is unauthorized" ); break; - + case CBCentralManagerStateUnknown: NSLog( @"CoreBluetooth BLE state is unknown" ); break; - + case CBCentralManagerStateUnsupported: NSLog( @"CoreBluetooth BLE hardware is unsupported on this platform" ); break; - + case CBCentralManagerStateResetting: NSLog( @"CoreBluetooth BLE manager is resetting" ); break; @@ -393,7 +449,7 @@ typedef enum { NSString *localName = [advertisementData objectForKey:CBAdvertisementDataLocalNameKey]; NSString *log = [NSString stringWithFormat:@"Found '%@'", localName]; - + if ( [localName isEqualToString:@"SteamController"] ) { NSLog( @"%@ : %@ - %@", log, peripheral, advertisementData ); @@ -419,7 +475,7 @@ typedef enum // Core Bluetooth devices calling back on event boundaries of their run-loops. so annoying. -static void process_pending_events() +static void process_pending_events(void) { CFRunLoopRunResult res; do @@ -496,7 +552,7 @@ static void process_pending_events() { #if FEATURE_REPORT_LOGGING uint8_t *reportBytes = (uint8_t *)report; - + NSLog( @"HIDBLE:send_feature_report (%02zu/19) [%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x]", GetBluetoothSegmentSize( report->segment ), reportBytes[1], reportBytes[2], reportBytes[3], reportBytes[4], reportBytes[5], reportBytes[6], reportBytes[7], reportBytes[8], reportBytes[9], reportBytes[10], reportBytes[11], reportBytes[12], @@ -512,7 +568,7 @@ static void process_pending_events() // fire-and-forget - we are going to not wait for the response here because all Steam Controller BLE send_feature_report's are ignored, // except errors. [_bleSteamController writeValue:[NSData dataWithBytes:&report->segment length:sendSize] forCharacteristic:_bleCharacteristicReport type:CBCharacteristicWriteWithResponse]; - + // pretend we received a result anybody cares about return 19; @@ -522,18 +578,18 @@ static void process_pending_events() _waitStateForWriteFeatureReport = BLEDeviceWaitState_Waiting; [_bleSteamController writeValue:[NSData dataWithBytes:&report->segment length:sendSize ] forCharacteristic:_bleCharacteristicReport type:CBCharacteristicWriteWithResponse]; - + while ( _waitStateForWriteFeatureReport == BLEDeviceWaitState_Waiting ) { process_pending_events(); } - + if ( _waitStateForWriteFeatureReport == BLEDeviceWaitState_Error ) { _waitStateForWriteFeatureReport = BLEDeviceWaitState_None; return -1; } - + _waitStateForWriteFeatureReport = BLEDeviceWaitState_None; return 19; #endif @@ -543,20 +599,20 @@ static void process_pending_events() { _waitStateForReadFeatureReport = BLEDeviceWaitState_Waiting; [_bleSteamController readValueForCharacteristic:_bleCharacteristicReport]; - + while ( _waitStateForReadFeatureReport == BLEDeviceWaitState_Waiting ) process_pending_events(); - + if ( _waitStateForReadFeatureReport == BLEDeviceWaitState_Error ) { _waitStateForReadFeatureReport = BLEDeviceWaitState_None; return -1; } - + memcpy( buffer, _featureReport, sizeof(_featureReport) ); - + _waitStateForReadFeatureReport = BLEDeviceWaitState_None; - + #if FEATURE_REPORT_LOGGING NSLog( @"HIDBLE:get_feature_report (19) [%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x]", buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6], @@ -601,7 +657,7 @@ static void process_pending_events() for (CBCharacteristic *aChar in service.characteristics) { NSLog( @"Found Characteristic %@", aChar ); - + if ( [aChar.UUID isEqual:[CBUUID UUIDWithString:VALVE_INPUT_CHAR]] ) { self.bleCharacteristicInput = aChar; @@ -648,7 +704,7 @@ static void process_pending_events() else if ( [characteristic.UUID isEqual:_bleCharacteristicReport.UUID] ) { memset( _featureReport, 0, sizeof(_featureReport) ); - + if ( error != nil ) { NSLog( @"HIDBLE: get_feature_report error: %@", error ); @@ -709,7 +765,7 @@ int HID_API_EXPORT HID_API_CALL hid_exit(void) return 0; } -void HID_API_EXPORT HID_API_CALL hid_ble_scan( bool bStart ) +void HID_API_EXPORT HID_API_CALL hid_ble_scan( int bStart ) { HIDBLEManager *bleManager = HIDBLEManager.sharedInstance; if ( bStart ) @@ -722,19 +778,24 @@ void HID_API_EXPORT HID_API_CALL hid_ble_scan( bool bStart ) } } -hid_device * HID_API_EXPORT hid_open_path( const char *path, int bExclusive /* = false */ ) +HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number) +{ + return NULL; +} + +HID_API_EXPORT hid_device * HID_API_CALL hid_open_path( const char *path, int bExclusive /* = false */ ) { hid_device *result = NULL; NSString *nssPath = [NSString stringWithUTF8String:path]; HIDBLEManager *bleManager = HIDBLEManager.sharedInstance; NSEnumerator *devices = [bleManager.deviceMap objectEnumerator]; - + for ( HIDBLEDevice *device in devices ) { // we have the device but it hasn't found its service or characteristics until it is connected if ( !device.ready || !device.connected || !device.bleCharacteristicInput ) continue; - + if ( [device.bleSteamController.identifier.UUIDString isEqualToString:nssPath] ) { result = (hid_device *)malloc( sizeof( hid_device ) ); @@ -768,16 +829,27 @@ int HID_API_EXPORT hid_set_nonblocking(hid_device *dev, int nonblock) { /* All Nonblocking operation is handled by the library. */ dev->blocking = !nonblock; - + return 0; } struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short product_id) { @autoreleasepool { struct hid_device_info *root = NULL; - - if ( ( vendor_id == 0 && product_id == 0 ) || - ( vendor_id == VALVE_USB_VID && product_id == D0G_BLE2_PID ) ) + const char *hint = SDL_GetHint(SDL_HINT_HIDAPI_IGNORE_DEVICES); + + /* See if there are any devices we should skip in enumeration */ + if (hint) { + char vendor_match[16], product_match[16]; + SDL_snprintf(vendor_match, sizeof(vendor_match), "0x%.4x/0x0000", VALVE_USB_VID); + SDL_snprintf(product_match, sizeof(product_match), "0x%.4x/0x%.4x", VALVE_USB_VID, D0G_BLE2_PID); + if (SDL_strcasestr(hint, vendor_match) || SDL_strcasestr(hint, product_match)) { + return NULL; + } + } + + if ( ( vendor_id == 0 || vendor_id == VALVE_USB_VID ) && + ( product_id == 0 || product_id == D0G_BLE2_PID ) ) { HIDBLEManager *bleManager = HIDBLEManager.sharedInstance; [bleManager updateConnectedSteamControllers:false]; @@ -836,6 +908,11 @@ int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *s return 0; } +int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen) +{ + return -1; +} + int HID_API_EXPORT hid_write(hid_device *dev, const unsigned char *data, size_t length) { HIDBLEDevice *device_handle = (__bridge HIDBLEDevice *)dev->device_handle; @@ -876,7 +953,7 @@ int HID_API_EXPORT hid_get_feature_report(hid_device *dev, unsigned char *data, return -1; size_t written = [device_handle get_feature_report:data[0] into:data]; - + return written == length-1 ? (int)length : (int)written; } @@ -896,7 +973,7 @@ int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t if ( !device_handle.connected ) return -1; - + if ( milliseconds != 0 ) { NSLog( @"hid_read_timeout with non-zero wait" ); @@ -912,4 +989,9 @@ int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t return result; } -#endif /* SDL_JOYSTICK_HIDAPI */ +HID_API_EXPORT const wchar_t* HID_API_CALL hid_error(hid_device *dev) +{ + return NULL; +} + +#endif /* !SDL_HIDAPI_DISABLED */ diff --git a/SDL2-2.0.12/src/hidapi/libusb/Makefile-manual b/SDL2-2.30.5/src/hidapi/libusb/Makefile-manual similarity index 100% rename from SDL2-2.0.12/src/hidapi/libusb/Makefile-manual rename to SDL2-2.30.5/src/hidapi/libusb/Makefile-manual diff --git a/SDL2-2.0.12/src/hidapi/libusb/Makefile.am b/SDL2-2.30.5/src/hidapi/libusb/Makefile.am similarity index 100% rename from SDL2-2.0.12/src/hidapi/libusb/Makefile.am rename to SDL2-2.30.5/src/hidapi/libusb/Makefile.am diff --git a/SDL2-2.0.12/src/hidapi/libusb/Makefile.freebsd b/SDL2-2.30.5/src/hidapi/libusb/Makefile.freebsd similarity index 100% rename from SDL2-2.0.12/src/hidapi/libusb/Makefile.freebsd rename to SDL2-2.30.5/src/hidapi/libusb/Makefile.freebsd diff --git a/SDL2-2.0.12/src/hidapi/libusb/Makefile.linux b/SDL2-2.30.5/src/hidapi/libusb/Makefile.linux similarity index 100% rename from SDL2-2.0.12/src/hidapi/libusb/Makefile.linux rename to SDL2-2.30.5/src/hidapi/libusb/Makefile.linux diff --git a/SDL2-2.0.12/src/hidapi/libusb/hid.c b/SDL2-2.30.5/src/hidapi/libusb/hid.c similarity index 79% rename from SDL2-2.0.12/src/hidapi/libusb/hid.c rename to SDL2-2.30.5/src/hidapi/libusb/hid.c index 90ca815..7da8a95 100644 --- a/SDL2-2.0.12/src/hidapi/libusb/hid.c +++ b/SDL2-2.30.5/src/hidapi/libusb/hid.c @@ -28,15 +28,62 @@ */ #include "../../SDL_internal.h" -#include "SDL_thread.h" +#include "../../thread/SDL_systhread.h" +#include "SDL_hints.h" #include "SDL_mutex.h" +#include "SDL_thread.h" -#ifdef SDL_JOYSTICK_HIDAPI +#ifdef realloc +#undef realloc +#endif +#define realloc SDL_realloc +#ifdef snprintf +#undef snprintf +#endif +#define snprintf SDL_snprintf +#ifdef strdup +#undef strdup +#endif +#define strdup SDL_strdup +#ifdef strncpy +#undef strncpy +#endif +#define strncpy SDL_strlcpy +#ifdef tolower +#undef tolower +#endif +#define tolower SDL_tolower +#ifdef wcsncpy +#undef wcsncpy +#endif +#define wcsncpy SDL_wcslcpy + +#ifndef HAVE_WCSDUP +#ifdef HAVE__WCSDUP +#define wcsdup _wcsdup +#else +#define wcsdup _dupwcs +static wchar_t *_dupwcs(const wchar_t *src) +{ + wchar_t *dst = NULL; + if (src) { + size_t len = SDL_wcslen(src) + 1; + len *= sizeof(wchar_t); + dst = (wchar_t *) malloc(len); + if (dst) memcpy(dst, src, len); + } + return dst; +} +#endif +#endif /* HAVE_WCSDUP */ #include +#ifndef _WIN32 +#define HAVE_SETLOCALE #include /* setlocale */ +#endif -#include "hidapi.h" +#include "../hidapi/hidapi.h" #ifdef NAMESPACE namespace NAMESPACE @@ -57,12 +104,8 @@ typedef struct _SDL_ThreadBarrier static int SDL_CreateThreadBarrier(SDL_ThreadBarrier *barrier, Uint32 count) { - if (barrier == NULL) { - return SDL_SetError("barrier must be non-NULL"); - } - if (count == 0) { - return SDL_SetError("count must be > 0"); - } + SDL_assert(barrier != NULL); + SDL_assert(count != 0); barrier->mutex = SDL_CreateMutex(); if (barrier->mutex == NULL) { @@ -157,9 +200,13 @@ struct hid_device_ { SDL_cond *condition; SDL_ThreadBarrier barrier; /* Ensures correct startup sequence */ int shutdown_thread; - int cancelled; + int transfer_loop_finished; struct libusb_transfer *transfer; + /* Quirks */ + int skip_output_report_id; + int no_output_reports_on_intr_ep; + /* List of received input reports. */ struct input_report *input_reports; }; @@ -196,7 +243,6 @@ static void free_hid_device(hid_device *dev) /*TODO: Implement this function on hidapi/libusb.. */ static void register_error(hid_device *dev, const char *op) { - } #endif @@ -276,7 +322,7 @@ static int get_usage(uint8_t *report_descriptor, size_t size, /* Can't ever happen since size_code is & 0x3 */ data_len = 0; break; - }; + } key_size = 1; } @@ -320,7 +366,6 @@ static inline int libusb_get_string_descriptor(libusb_device_handle *dev, (LIBUSB_DT_STRING << 8) | descriptor_index, lang_id, data, (uint16_t) length, 1000); } - #endif @@ -373,12 +418,16 @@ static int is_language_supported(libusb_device_handle *dev, uint16_t lang) /* This function returns a newly allocated wide string containing the USB device string numbered by the index. The returned string must be freed by using free(). */ +#if defined(__OS2__) /* don't use iconv on OS/2: no support for wchar_t. */ +#define NO_ICONV +#endif static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx) { char buf[512]; int len; wchar_t *str = NULL; +#if !defined(NO_ICONV) wchar_t wbuf[256]; SDL_iconv_t ic; size_t inbytes; @@ -386,6 +435,9 @@ static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx) size_t res; const char *inptr; char *outptr; +#else + int i; +#endif /* Determine which language to use. */ uint16_t lang; @@ -402,6 +454,23 @@ static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx) if (len < 0) return NULL; +#if defined(NO_ICONV) /* original hidapi code for NO_ICONV : */ + + /* Bionic does not have wchar_t iconv support, so it + has to be done manually. The following code will only work for + code points that can be represented as a single UTF-16 character, + and will incorrectly convert any code points which require more + than one UTF-16 character. + + Skip over the first character (2-bytes). */ + len -= 2; + str = (wchar_t*) malloc((len / 2 + 1) * sizeof(wchar_t)); + for (i = 0; i < len / 2; i++) { + str[i] = buf[i * 2 + 2] | (buf[i * 2 + 3] << 8); + } + str[len / 2] = 0x00000000; + +#else /* buf does not need to be explicitly NULL-terminated because it is only passed into iconv() which does not need it. */ @@ -434,10 +503,116 @@ static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx) err: SDL_iconv_close(ic); +#endif return str; } +struct usb_string_cache_entry { + uint16_t vid; + uint16_t pid; + wchar_t *vendor; + wchar_t *product; +}; + +static struct usb_string_cache_entry *usb_string_cache = NULL; +static size_t usb_string_cache_size = 0; +static size_t usb_string_cache_insert_pos = 0; + +static int usb_string_cache_grow() +{ + struct usb_string_cache_entry *new_cache; + size_t allocSize; + size_t new_cache_size; + + new_cache_size = usb_string_cache_size + 8; + allocSize = sizeof(struct usb_string_cache_entry) * new_cache_size; + new_cache = (struct usb_string_cache_entry *)realloc(usb_string_cache, allocSize); + if (!new_cache) + return -1; + + usb_string_cache = new_cache; + usb_string_cache_size = new_cache_size; + + return 0; +} + +static void usb_string_cache_destroy() +{ + size_t i; + for (i = 0; i < usb_string_cache_insert_pos; i++) { + free(usb_string_cache[i].vendor); + free(usb_string_cache[i].product); + } + free(usb_string_cache); + + usb_string_cache = NULL; + usb_string_cache_size = 0; + usb_string_cache_insert_pos = 0; +} + +static struct usb_string_cache_entry *usb_string_cache_insert() +{ + struct usb_string_cache_entry *new_entry = NULL; + if (usb_string_cache_insert_pos >= usb_string_cache_size) { + if (usb_string_cache_grow() < 0) + return NULL; + } + new_entry = &usb_string_cache[usb_string_cache_insert_pos]; + usb_string_cache_insert_pos++; + return new_entry; +} + +static int usb_string_can_cache(uint16_t vid, uint16_t pid) +{ + if (!vid || !pid) { + /* We can't cache these, they aren't unique */ + return 0; + } + + if (vid == 0x0f0d && pid == 0x00dc) { + /* HORI reuses this VID/PID for many different products */ + return 0; + } + + /* We can cache these strings */ + return 1; +} + +static const struct usb_string_cache_entry *usb_string_cache_find(struct libusb_device_descriptor *desc, struct libusb_device_handle *handle) +{ + struct usb_string_cache_entry *entry = NULL; + size_t i; + + /* Search for existing string cache entry */ + for (i = 0; i < usb_string_cache_insert_pos; i++) { + entry = &usb_string_cache[i]; + if (entry->vid != desc->idVendor) + continue; + if (entry->pid != desc->idProduct) + continue; + return entry; + } + + /* Not found, create one. */ + entry = usb_string_cache_insert(); + if (!entry) + return NULL; + + entry->vid = desc->idVendor; + entry->pid = desc->idProduct; + if (desc->iManufacturer > 0) + entry->vendor = get_usb_string(handle, desc->iManufacturer); + else + entry->vendor = NULL; + if (desc->iProduct > 0) + entry->product = get_usb_string(handle, desc->iProduct); + else + entry->product = NULL; + + return entry; +} + static char *make_path(libusb_device *dev, int interface_number) { char str[64]; @@ -454,16 +629,18 @@ static char *make_path(libusb_device *dev, int interface_number) int HID_API_EXPORT hid_init(void) { if (!usb_context) { - const char *locale; - /* Init Libusb */ if (libusb_init(&usb_context)) return -1; +#ifdef HAVE_SETLOCALE /* Set the locale if it's not set. */ - locale = setlocale(LC_CTYPE, NULL); - if (!locale) - setlocale(LC_CTYPE, ""); + { + const char *locale = setlocale(LC_CTYPE, NULL); + if (!locale) + setlocale(LC_CTYPE, ""); + } +#endif } return 0; @@ -471,6 +648,8 @@ int HID_API_EXPORT hid_init(void) int HID_API_EXPORT hid_exit(void) { + usb_string_cache_destroy(); + if (usb_context) { libusb_exit(usb_context); usb_context = NULL; @@ -504,8 +683,13 @@ static int is_xbox360(unsigned short vendor_id, const struct libusb_interface_de 0x15e4, /* Numark */ 0x162e, /* Joytech */ 0x1689, /* Razer Onza */ + 0x1949, /* Lab126, Inc. */ 0x1bad, /* Harmonix */ + 0x20d6, /* PowerA */ 0x24c6, /* PowerA */ + 0x2c22, /* Qanba */ + 0x2dc8, /* 8BitDo */ + 0x9886, /* ASTRO Gaming */ }; if (intf_desc->bInterfaceClass == LIBUSB_CLASS_VENDOR_SPEC && @@ -524,17 +708,24 @@ static int is_xbox360(unsigned short vendor_id, const struct libusb_interface_de static int is_xboxone(unsigned short vendor_id, const struct libusb_interface_descriptor *intf_desc) { - static const int XB1_IFACE_SUBCLASS = 71; - static const int XB1_IFACE_PROTOCOL = 208; - static const int SUPPORTED_VENDORS[] = { - 0x045e, /* Microsoft */ - 0x0738, /* Mad Catz */ - 0x0e6f, /* PDP */ - 0x0f0d, /* Hori */ - 0x1532, /* Razer Wildcat */ - 0x24c6, /* PowerA */ - 0x2e24, /* Hyperkin */ - }; + static const int XB1_IFACE_SUBCLASS = 71; + static const int XB1_IFACE_PROTOCOL = 208; + static const int SUPPORTED_VENDORS[] = { + 0x03f0, /* HP */ + 0x044f, /* Thrustmaster */ + 0x045e, /* Microsoft */ + 0x0738, /* Mad Catz */ + 0x0b05, /* ASUS */ + 0x0e6f, /* PDP */ + 0x0f0d, /* Hori */ + 0x10f5, /* Turtle Beach */ + 0x1532, /* Razer Wildcat */ + 0x20d6, /* PowerA */ + 0x24c6, /* PowerA */ + 0x2dc8, /* 8BitDo */ + 0x2e24, /* Hyperkin */ + 0x3537, /* GameSir */ + }; if (intf_desc->bInterfaceNumber == 0 && intf_desc->bInterfaceClass == LIBUSB_CLASS_VENDOR_SPEC && @@ -552,6 +743,8 @@ static int is_xboxone(unsigned short vendor_id, const struct libusb_interface_de static int should_enumerate_interface(unsigned short vendor_id, const struct libusb_interface_descriptor *intf_desc) { + //printf("Checking interface 0x%x %d/%d/%d/%d\n", vendor_id, intf_desc->bInterfaceNumber, intf_desc->bInterfaceClass, intf_desc->bInterfaceSubClass, intf_desc->bInterfaceProtocol); + if (intf_desc->bInterfaceClass == LIBUSB_CLASS_HID) return 1; @@ -576,6 +769,7 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, struct hid_device_info *root = NULL; /* return object */ struct hid_device_info *cur_dev = NULL; + const char *hint = SDL_GetHint(SDL_HINT_HIDAPI_IGNORE_DEVICES); if(hid_init() < 0) return NULL; @@ -593,10 +787,21 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short dev_vid = desc.idVendor; unsigned short dev_pid = desc.idProduct; + /* See if there are any devices we should skip in enumeration */ + if (hint) { + char vendor_match[16], product_match[16]; + SDL_snprintf(vendor_match, sizeof(vendor_match), "0x%.4x/0x0000", dev_vid); + SDL_snprintf(product_match, sizeof(product_match), "0x%.4x/0x%.4x", dev_vid, dev_pid); + if (SDL_strcasestr(hint, vendor_match) || SDL_strcasestr(hint, product_match)) { + continue; + } + } + res = libusb_get_active_config_descriptor(dev, &conf_desc); if (res < 0) libusb_get_config_descriptor(dev, 0, &conf_desc); if (conf_desc) { + for (j = 0; j < conf_desc->bNumInterfaces; j++) { const struct libusb_interface *intf = &conf_desc->interface[j]; for (k = 0; k < intf->num_altsetting; k++) { @@ -612,6 +817,7 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, if (res >= 0) { struct hid_device_info *tmp; + const struct usb_string_cache_entry *string_cache; /* VID/PID match. Create the record. */ tmp = (struct hid_device_info*) calloc(1, sizeof(struct hid_device_info)); @@ -633,12 +839,24 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, get_usb_string(handle, desc.iSerialNumber); /* Manufacturer and Product strings */ - if (desc.iManufacturer > 0) - cur_dev->manufacturer_string = - get_usb_string(handle, desc.iManufacturer); - if (desc.iProduct > 0) - cur_dev->product_string = - get_usb_string(handle, desc.iProduct); + if (usb_string_can_cache(dev_vid, dev_pid)) { + string_cache = usb_string_cache_find(&desc, handle); + if (string_cache) { + if (string_cache->vendor) { + cur_dev->manufacturer_string = wcsdup(string_cache->vendor); + } + if (string_cache->product) { + cur_dev->product_string = wcsdup(string_cache->product); + } + } + } else { + if (desc.iManufacturer > 0) + cur_dev->manufacturer_string = + get_usb_string(handle, desc.iManufacturer); + if (desc.iProduct > 0) + cur_dev->product_string = + get_usb_string(handle, desc.iProduct); + } #ifdef INVASIVE_GET_USAGE { @@ -783,7 +1001,7 @@ hid_device * hid_open(unsigned short vendor_id, unsigned short product_id, const return handle; } -static void read_callback(struct libusb_transfer *transfer) +static void LIBUSB_CALL read_callback(struct libusb_transfer *transfer) { hid_device *dev = (hid_device *)transfer->user_data; int res; @@ -825,13 +1043,9 @@ static void read_callback(struct libusb_transfer *transfer) } else if (transfer->status == LIBUSB_TRANSFER_CANCELLED) { dev->shutdown_thread = 1; - dev->cancelled = 1; - return; } else if (transfer->status == LIBUSB_TRANSFER_NO_DEVICE) { dev->shutdown_thread = 1; - dev->cancelled = 1; - return; } else if (transfer->status == LIBUSB_TRANSFER_TIMED_OUT) { //LOG("Timeout (normal)\n"); @@ -840,18 +1054,24 @@ static void read_callback(struct libusb_transfer *transfer) LOG("Unknown transfer code: %d\n", transfer->status); } + if (dev->shutdown_thread) { + dev->transfer_loop_finished = 1; + return; + } + /* Re-submit the transfer object. */ res = libusb_submit_transfer(transfer); if (res != 0) { LOG("Unable to submit URB. libusb error code: %d\n", res); dev->shutdown_thread = 1; - dev->cancelled = 1; + dev->transfer_loop_finished = 1; } } -static int read_thread(void *param) +static int SDLCALL read_thread(void *param) { + int res; hid_device *dev = (hid_device *)param; uint8_t *buf; const size_t length = dev->input_ep_max_packet_size; @@ -870,14 +1090,18 @@ static int read_thread(void *param) /* Make the first submission. Further submissions are made from inside read_callback() */ - libusb_submit_transfer(dev->transfer); + res = libusb_submit_transfer(dev->transfer); + if(res < 0) { + LOG("libusb_submit_transfer failed: %d %s. Stopping read_thread from running\n", res, libusb_error_name(res)); + dev->shutdown_thread = 1; + dev->transfer_loop_finished = 1; + } /* Notify the main thread that the read thread is up and running. */ SDL_WaitThreadBarrier(&dev->barrier); /* Handle all the events. */ while (!dev->shutdown_thread) { - int res; res = libusb_handle_events(usb_context); if (res < 0) { /* There was an error. */ @@ -888,6 +1112,7 @@ static int read_thread(void *param) res != LIBUSB_ERROR_TIMEOUT && res != LIBUSB_ERROR_OVERFLOW && res != LIBUSB_ERROR_INTERRUPTED) { + dev->shutdown_thread = 1; break; } } @@ -897,8 +1122,8 @@ static int read_thread(void *param) if no transfers are pending, but that's OK. */ libusb_cancel_transfer(dev->transfer); - while (!dev->cancelled) - libusb_handle_events_completed(usb_context, &dev->cancelled); + while (!dev->transfer_loop_finished) + libusb_handle_events_completed(usb_context, &dev->transfer_loop_finished); /* Now that the read thread is stopping, Wake any threads which are waiting on data (in hid_read_timeout()). Do this under a mutex to @@ -920,40 +1145,78 @@ static int read_thread(void *param) return 0; } -static void init_xboxone(libusb_device_handle *device_handle, struct libusb_config_descriptor *conf_desc) +static void init_xbox360(libusb_device_handle *device_handle, unsigned short idVendor, unsigned short idProduct, struct libusb_config_descriptor *conf_desc) { - static const int XB1_IFACE_SUBCLASS = 71; - static const int XB1_IFACE_PROTOCOL = 208; + if ((idVendor == 0x05ac && idProduct == 0x055b) /* Gamesir-G3w */ || + idVendor == 0x0f0d /* Hori Xbox controllers */) { + unsigned char data[20]; + + /* The HORIPAD FPS for Nintendo Switch requires this to enable input reports. + This VID/PID is also shared with other HORI controllers, but they all seem + to be fine with this as well. + */ + libusb_control_transfer(device_handle, 0xC1, 0x01, 0x100, 0x0, data, sizeof(data), 100); + } +} + +static void init_xboxone(libusb_device_handle *device_handle, unsigned short idVendor, unsigned short idProduct, struct libusb_config_descriptor *conf_desc) +{ + static const int VENDOR_MICROSOFT = 0x045e; + static const int XB1_IFACE_SUBCLASS = 71; + static const int XB1_IFACE_PROTOCOL = 208; int j, k, res; for (j = 0; j < conf_desc->bNumInterfaces; j++) { const struct libusb_interface *intf = &conf_desc->interface[j]; for (k = 0; k < intf->num_altsetting; k++) { - const struct libusb_interface_descriptor *intf_desc; - intf_desc = &intf->altsetting[k]; - - if (intf_desc->bInterfaceNumber != 0 && - intf_desc->bAlternateSetting == 0 && - intf_desc->bInterfaceClass == LIBUSB_CLASS_VENDOR_SPEC && + const struct libusb_interface_descriptor *intf_desc = &intf->altsetting[k]; + if (intf_desc->bInterfaceClass == LIBUSB_CLASS_VENDOR_SPEC && intf_desc->bInterfaceSubClass == XB1_IFACE_SUBCLASS && intf_desc->bInterfaceProtocol == XB1_IFACE_PROTOCOL) { - res = libusb_claim_interface(device_handle, intf_desc->bInterfaceNumber); - if (res < 0) { - LOG("can't claim interface %d: %d\n", intf_desc->bInterfaceNumber, res); - continue; + int bSetAlternateSetting = 0; + + /* Newer Microsoft Xbox One controllers have a high speed alternate setting */ + if (idVendor == VENDOR_MICROSOFT && + intf_desc->bInterfaceNumber == 0 && intf_desc->bAlternateSetting == 1) { + bSetAlternateSetting = 1; + } else if (intf_desc->bInterfaceNumber != 0 && intf_desc->bAlternateSetting == 0) { + bSetAlternateSetting = 1; } - res = libusb_set_interface_alt_setting(device_handle, intf_desc->bInterfaceNumber, intf_desc->bAlternateSetting); - if (res < 0) { - LOG("xbox init: can't set alt setting %d: %d\n", intf_desc->bInterfaceNumber, res); - } + if (bSetAlternateSetting) { + res = libusb_claim_interface(device_handle, intf_desc->bInterfaceNumber); + if (res < 0) { + LOG("can't claim interface %d: %d\n", intf_desc->bInterfaceNumber, res); + continue; + } - libusb_release_interface(device_handle, intf_desc->bInterfaceNumber); + LOG("Setting alternate setting for VID/PID 0x%x/0x%x interface %d to %d\n", idVendor, idProduct, intf_desc->bInterfaceNumber, intf_desc->bAlternateSetting); + + res = libusb_set_interface_alt_setting(device_handle, intf_desc->bInterfaceNumber, intf_desc->bAlternateSetting); + if (res < 0) { + LOG("xbox init: can't set alt setting %d: %d\n", intf_desc->bInterfaceNumber, res); + } + + libusb_release_interface(device_handle, intf_desc->bInterfaceNumber); + } } } } } +static void calculate_device_quirks(hid_device *dev, unsigned short idVendor, unsigned short idProduct) +{ + static const int VENDOR_SONY = 0x054c; + static const int PRODUCT_PS3_CONTROLLER = 0x0268; + static const int PRODUCT_NAVIGATION_CONTROLLER = 0x042f; + + if (idVendor == VENDOR_SONY && + (idProduct == PRODUCT_PS3_CONTROLLER || idProduct == PRODUCT_NAVIGATION_CONTROLLER)) { + dev->skip_output_report_id = 1; + dev->no_output_reports_on_intr_ep = 1; + } +} + hid_device * HID_API_EXPORT hid_open_path(const char *path, int bExclusive) { hid_device *dev = NULL; @@ -982,9 +1245,9 @@ hid_device * HID_API_EXPORT hid_open_path(const char *path, int bExclusive) libusb_get_config_descriptor(usb_dev, 0, &conf_desc); if (!conf_desc) continue; - for (j = 0; j < conf_desc->bNumInterfaces; j++) { + for (j = 0; j < conf_desc->bNumInterfaces && !good_open; j++) { const struct libusb_interface *intf = &conf_desc->interface[j]; - for (k = 0; k < intf->num_altsetting; k++) { + for (k = 0; k < intf->num_altsetting && !good_open; k++) { const struct libusb_interface_descriptor *intf_desc; intf_desc = &intf->altsetting[k]; if (should_enumerate_interface(desc.idVendor, intf_desc)) { @@ -1028,9 +1291,14 @@ hid_device * HID_API_EXPORT hid_open_path(const char *path, int bExclusive) break; } + /* Initialize XBox 360 controllers */ + if (is_xbox360(desc.idVendor, intf_desc)) { + init_xbox360(dev->device_handle, desc.idVendor, desc.idProduct, conf_desc); + } + /* Initialize XBox One controllers */ if (is_xboxone(desc.idVendor, intf_desc)) { - init_xboxone(dev->device_handle, conf_desc); + init_xboxone(dev->device_handle, desc.idVendor, desc.idProduct, conf_desc); } /* Store off the string descriptor indexes */ @@ -1074,7 +1342,9 @@ hid_device * HID_API_EXPORT hid_open_path(const char *path, int bExclusive) } } - dev->thread = SDL_CreateThread(read_thread, NULL, dev); + calculate_device_quirks(dev, desc.idVendor, desc.idProduct); + + dev->thread = SDL_CreateThreadInternal(read_thread, "libusb", 0, dev); /* Wait here for the read thread to be initialized. */ SDL_WaitThreadBarrier(&dev->barrier); @@ -1106,11 +1376,11 @@ int HID_API_EXPORT hid_write(hid_device *dev, const unsigned char *data, size_t { int res; - if (dev->output_endpoint <= 0) { + if (dev->output_endpoint <= 0 || dev->no_output_reports_on_intr_ep) { int report_number = data[0]; int skipped_report_id = 0; - if (report_number == 0x0) { + if (report_number == 0x0 || dev->skip_output_report_id) { data++; length--; skipped_report_id = 1; @@ -1173,21 +1443,21 @@ static void cleanup_mutex(void *param) } #endif - int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds) { - int bytes_read = -1; - #if 0 int transferred; int res = libusb_interrupt_transfer(dev->device_handle, dev->input_endpoint, data, length, &transferred, 5000); LOG("transferred: %d\n", transferred); return transferred; #endif + int bytes_read; SDL_LockMutex(dev->mutex); /* TODO: pthread_cleanup SDL? */ + bytes_read = -1; + /* There's an input report queued up. Return it. */ if (dev->input_reports) { /* Return the first one */ @@ -1341,6 +1611,7 @@ void HID_API_EXPORT hid_close(hid_device *dev) /* Clean up the Transfer objects allocated in read_thread(). */ free(dev->transfer->buffer); + dev->transfer->buffer = NULL; libusb_free_transfer(dev->transfer); /* release the interface */ @@ -1552,13 +1823,15 @@ static struct lang_map_entry lang_map[] = { uint16_t get_usb_code_for_current_locale(void) { - char *locale; + char *locale = NULL; char search_string[64]; char *ptr; struct lang_map_entry *lang; /* Get the current locale. */ +#ifdef HAVE_SETLOCALE locale = setlocale(0, NULL); +#endif if (!locale) return 0x0; @@ -1620,5 +1893,3 @@ uint16_t get_usb_code_for_current_locale(void) #ifdef NAMESPACE } #endif - -#endif /* SDL_JOYSTICK_HIDAPI */ diff --git a/SDL2-2.0.12/src/hidapi/libusb/hidusb.cpp b/SDL2-2.30.5/src/hidapi/libusb/hidusb.cpp similarity index 100% rename from SDL2-2.0.12/src/hidapi/libusb/hidusb.cpp rename to SDL2-2.30.5/src/hidapi/libusb/hidusb.cpp diff --git a/SDL2-2.0.12/src/hidapi/linux/Makefile-manual b/SDL2-2.30.5/src/hidapi/linux/Makefile-manual similarity index 100% rename from SDL2-2.0.12/src/hidapi/linux/Makefile-manual rename to SDL2-2.30.5/src/hidapi/linux/Makefile-manual diff --git a/SDL2-2.0.12/src/hidapi/linux/Makefile.am b/SDL2-2.30.5/src/hidapi/linux/Makefile.am similarity index 100% rename from SDL2-2.0.12/src/hidapi/linux/Makefile.am rename to SDL2-2.30.5/src/hidapi/linux/Makefile.am diff --git a/SDL2-2.0.12/src/hidapi/linux/README.txt b/SDL2-2.30.5/src/hidapi/linux/README.txt similarity index 97% rename from SDL2-2.0.12/src/hidapi/linux/README.txt rename to SDL2-2.30.5/src/hidapi/linux/README.txt index 8006694..c187590 100644 --- a/SDL2-2.0.12/src/hidapi/linux/README.txt +++ b/SDL2-2.30.5/src/hidapi/linux/README.txt @@ -39,7 +39,7 @@ Bugs (hidraw implementation only): ----------------------------------- On Kernel versions < 2.6.34, if your device uses numbered reports, an extra byte will be returned at the beginning of all reports returned from read() -for hidraw devices. This is worked around in the libary. No action should be +for hidraw devices. This is worked around in the library. No action should be necessary in the client library. On Kernel versions < 2.6.35, reports will only be sent using a Set_Report diff --git a/SDL2-2.0.12/src/hidapi/linux/hid.c b/SDL2-2.30.5/src/hidapi/linux/hid.c similarity index 89% rename from SDL2-2.0.12/src/hidapi/linux/hid.c rename to SDL2-2.30.5/src/hidapi/linux/hid.c index 2cc2d8b..8c3aeae 100644 --- a/SDL2-2.0.12/src/hidapi/linux/hid.c +++ b/SDL2-2.30.5/src/hidapi/linux/hid.c @@ -22,7 +22,7 @@ ********************************************************/ #include "../../SDL_internal.h" -#ifdef SDL_JOYSTICK_HIDAPI +#include "SDL_hints.h" #ifndef _GNU_SOURCE #define _GNU_SOURCE /* needed for wcsdup() before glibc 2.10 */ @@ -50,7 +50,7 @@ #include #include -#include "hidapi.h" +#include "../hidapi/hidapi.h" #ifdef NAMESPACE namespace NAMESPACE @@ -86,7 +86,7 @@ struct hid_device_ { int device_handle; int blocking; int uses_numbered_reports; - int is_bluetooth; + int needs_ble_hack; }; @@ -119,7 +119,7 @@ static hid_device *new_hid_device(void) dev->device_handle = -1; dev->blocking = 1; dev->uses_numbered_reports = 0; - dev->is_bluetooth = 0; + dev->needs_ble_hack = 0; return dev; } @@ -200,7 +200,7 @@ static int uses_numbered_reports(__u8 *report_descriptor, __u32 size) { /* Can't ever happen since size_code is & 0x3 */ data_len = 0; break; - }; + } key_size = 1; } @@ -217,11 +217,11 @@ static int uses_numbered_reports(__u8 *report_descriptor, __u32 size) { * strings pointed to by serial_number_utf8 and product_name_utf8 after use. */ static int -parse_uevent_info(const char *uevent, int *bus_type, +parse_uevent_info(const char *uevent, unsigned *bus_type, unsigned short *vendor_id, unsigned short *product_id, char **serial_number_utf8, char **product_name_utf8) { - char *tmp = strdup(uevent); + char *tmp; char *saveptr = NULL; char *line; char *key; @@ -231,6 +231,15 @@ parse_uevent_info(const char *uevent, int *bus_type, int found_serial = 0; int found_name = 0; + if (!uevent) { + return 0; + } + + tmp = strdup(uevent); + if (!tmp) { + return 0; + } + line = strtok_r(tmp, "\n", &saveptr); while (line != NULL) { /* line: "KEY=value" */ @@ -269,12 +278,12 @@ next_line: return (found_id && found_name && found_serial); } -static int is_bluetooth(hid_device *dev) +static int is_BLE(hid_device *dev) { struct udev *udev; struct udev_device *udev_dev, *hid_dev; struct stat s; - int ret = -1; + int ret; /* Create the udev object */ udev = udev_new(); @@ -284,13 +293,13 @@ static int is_bluetooth(hid_device *dev) } /* Get the dev_t (major/minor numbers) from the file handle. */ - ret = fstat(dev->device_handle, &s); - if (-1 == ret) { + if (fstat(dev->device_handle, &s) < 0) { udev_unref(udev); - return ret; + return -1; } /* Open a udev device from the dev_t. 'c' means character device. */ + ret = 0; udev_dev = udev_device_new_from_devnum(udev, 'c', s.st_rdev); if (udev_dev) { hid_dev = udev_device_get_parent_with_subsystem_devtype( @@ -298,13 +307,13 @@ static int is_bluetooth(hid_device *dev) "hid", NULL); if (hid_dev) { - unsigned short dev_vid; - unsigned short dev_pid; - int bus_type; + unsigned short dev_vid = 0; + unsigned short dev_pid = 0; + unsigned bus_type = 0; char *serial_number_utf8 = NULL; char *product_name_utf8 = NULL; - ret = parse_uevent_info( + parse_uevent_info( udev_device_get_sysattr_value(hid_dev, "uevent"), &bus_type, &dev_vid, @@ -314,7 +323,12 @@ static int is_bluetooth(hid_device *dev) free(serial_number_utf8); free(product_name_utf8); - ret = (bus_type == BUS_BLUETOOTH); + if (bus_type == BUS_BLUETOOTH) { + /* Right now the Steam Controller is the only BLE device that we send feature reports to */ + if (dev_vid == 0x28de /* Valve */) { + ret = 1; + } + } /* hid_dev doesn't need to be (and can't be) unref'd. I'm not sure why, but it'll throw double-free() errors. */ @@ -327,15 +341,14 @@ static int is_bluetooth(hid_device *dev) return ret; } - static int get_device_string(hid_device *dev, enum device_string_id key, wchar_t *string, size_t maxlen) { struct udev *udev; struct udev_device *udev_dev, *parent, *hid_dev; struct stat s; int ret = -1; - char *serial_number_utf8 = NULL; - char *product_name_utf8 = NULL; + char *serial_number_utf8 = NULL; + char *product_name_utf8 = NULL; char *tmp; /* Create the udev object */ @@ -361,7 +374,7 @@ static int get_device_string(hid_device *dev, enum device_string_id key, wchar_t if (hid_dev) { unsigned short dev_vid; unsigned short dev_pid; - int bus_type; + unsigned bus_type; size_t retm; ret = parse_uevent_info( @@ -429,8 +442,8 @@ static int get_device_string(hid_device *dev, enum device_string_id key, wchar_t } end: - free(serial_number_utf8); - free(product_name_utf8); + free(serial_number_utf8); + free(product_name_utf8); udev_device_unref(udev_dev); /* parent and hid_dev don't need to be (and can't be) unref'd. @@ -470,6 +483,7 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, struct hid_device_info *root = NULL; /* return object */ struct hid_device_info *cur_dev = NULL; struct hid_device_info *prev_dev = NULL; /* previous device */ + const char *hint = SDL_GetHint(SDL_HINT_HIDAPI_IGNORE_DEVICES); hid_init(); @@ -499,7 +513,7 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short dev_pid; char *serial_number_utf8 = NULL; char *product_name_utf8 = NULL; - int bus_type; + unsigned bus_type; int result; /* Get the filename of the /sys entry for the device @@ -541,6 +555,16 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, goto next; } + /* See if there are any devices we should skip in enumeration */ + if (hint) { + char vendor_match[16], product_match[16]; + SDL_snprintf(vendor_match, sizeof(vendor_match), "0x%.4x/0x0000", dev_vid); + SDL_snprintf(product_match, sizeof(product_match), "0x%.4x/0x%.4x", dev_vid, dev_pid); + if (SDL_strcasestr(hint, vendor_match) || SDL_strcasestr(hint, product_match)) { + continue; + } + } + /* Check the VID/PID against the arguments */ if ((vendor_id == 0x0 || vendor_id == dev_vid) && (product_id == 0x0 || product_id == dev_pid)) { @@ -705,6 +729,8 @@ hid_device * hid_open(unsigned short vendor_id, unsigned short product_id, const hid_device * HID_API_EXPORT hid_open_path(const char *path, int bExclusive) { + const int MAX_ATTEMPTS = 10; + int attempt; hid_device *dev = NULL; hid_init(); @@ -712,10 +738,18 @@ hid_device * HID_API_EXPORT hid_open_path(const char *path, int bExclusive) dev = new_hid_device(); /* OPEN HERE */ - dev->device_handle = open(path, O_RDWR); + for (attempt = 1; attempt <= MAX_ATTEMPTS; ++attempt) { + dev->device_handle = open(path, O_RDWR | O_CLOEXEC); + if (dev->device_handle < 0 && errno == EACCES) { + /* udev might be setting up permissions, wait a bit and try again */ + usleep(1 * 1000); + continue; + } + break; + } /* If we have a good handle, return it. */ - if (dev->device_handle > 0) { + if (dev->device_handle >= 0) { /* Get the report descriptor */ int res, desc_size = 0; @@ -741,7 +775,7 @@ hid_device * HID_API_EXPORT hid_open_path(const char *path, int bExclusive) rpt_desc.size); } - dev->is_bluetooth = (is_bluetooth(dev) == 1); + dev->needs_ble_hack = (is_BLE(dev) == 1); return dev; } @@ -824,34 +858,47 @@ int HID_API_EXPORT hid_set_nonblocking(hid_device *dev, int nonblock) return 0; /* Success */ } - int HID_API_EXPORT hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length) { + static const int MAX_RETRIES = 50; + int retry; int res; - res = ioctl(dev->device_handle, HIDIOCSFEATURE(length), data); - if (res < 0) - perror("ioctl (SFEATURE)"); + for (retry = 0; retry < MAX_RETRIES; ++retry) { + res = ioctl(dev->device_handle, HIDIOCSFEATURE(length), data); + if (res < 0 && errno == EPIPE) { + /* Try again... */ + continue; + } + if (res < 0) + perror("ioctl (SFEATURE)"); + break; + } return res; } int HID_API_EXPORT hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length) { int res; + unsigned char report = data[0]; - /* It looks like HIDIOCGFEATURE() on Bluetooth devices doesn't return the report number */ - if (dev->is_bluetooth) { - data[1] = data[0]; - ++data; - --length; - } res = ioctl(dev->device_handle, HIDIOCGFEATURE(length), data); - if (res < 0) - perror("ioctl (GFEATURE)"); - else if (dev->is_bluetooth) - ++res; - + if (res < 0) { + /* perror("ioctl (GFEATURE)"); */ + } else if (dev->needs_ble_hack) { + /* Versions of BlueZ before 5.56 don't include the report in the data, + * and versions of BlueZ >= 5.56 include 2 copies of the report. + * We'll fix it so that there is a single copy of the report in both cases + */ + if (data[0] == report && data[1] == report) { + memmove(&data[0], &data[1], res); + } else if (data[0] != report) { + memmove(&data[1], &data[0], res); + data[0] = report; + ++res; + } + } return res; } @@ -882,6 +929,10 @@ int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *s int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen) { + (void)dev; + (void)string_index; + (void)string; + (void)maxlen; return -1; } @@ -894,5 +945,3 @@ HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev) #ifdef NAMESPACE } #endif - -#endif /* SDL_JOYSTICK_HIDAPI */ diff --git a/SDL2-2.0.12/src/hidapi/linux/hidraw.cpp b/SDL2-2.30.5/src/hidapi/linux/hidraw.cpp similarity index 100% rename from SDL2-2.0.12/src/hidapi/linux/hidraw.cpp rename to SDL2-2.30.5/src/hidapi/linux/hidraw.cpp diff --git a/SDL2-2.0.12/src/hidapi/m4/ax_pthread.m4 b/SDL2-2.30.5/src/hidapi/m4/ax_pthread.m4 similarity index 100% rename from SDL2-2.0.12/src/hidapi/m4/ax_pthread.m4 rename to SDL2-2.30.5/src/hidapi/m4/ax_pthread.m4 diff --git a/SDL2-2.0.12/src/hidapi/m4/pkg.m4 b/SDL2-2.30.5/src/hidapi/m4/pkg.m4 similarity index 100% rename from SDL2-2.0.12/src/hidapi/m4/pkg.m4 rename to SDL2-2.30.5/src/hidapi/m4/pkg.m4 diff --git a/SDL2-2.0.12/src/hidapi/mac/Makefile-manual b/SDL2-2.30.5/src/hidapi/mac/Makefile-manual similarity index 100% rename from SDL2-2.0.12/src/hidapi/mac/Makefile-manual rename to SDL2-2.30.5/src/hidapi/mac/Makefile-manual diff --git a/SDL2-2.0.12/src/hidapi/mac/Makefile.am b/SDL2-2.30.5/src/hidapi/mac/Makefile.am similarity index 100% rename from SDL2-2.0.12/src/hidapi/mac/Makefile.am rename to SDL2-2.30.5/src/hidapi/mac/Makefile.am diff --git a/SDL2-2.0.12/src/hidapi/mac/hid.c b/SDL2-2.30.5/src/hidapi/mac/hid.c similarity index 86% rename from SDL2-2.0.12/src/hidapi/mac/hid.c rename to SDL2-2.30.5/src/hidapi/mac/hid.c index 70a2fb0..bbb5c62 100644 --- a/SDL2-2.0.12/src/hidapi/mac/hid.c +++ b/SDL2-2.30.5/src/hidapi/mac/hid.c @@ -21,7 +21,7 @@ ********************************************************/ #include "../../SDL_internal.h" -#ifdef SDL_JOYSTICK_HIDAPI +#include "SDL_hints.h" /* See Apple Technical Note TN2187 for details on IOHidManager. */ @@ -33,7 +33,9 @@ #include #include -#include "hidapi.h" +#include "../hidapi/hidapi.h" + +#define VALVE_USB_VID 0x28DE /* Barrier implementation because Mac OSX doesn't have pthread_barrier. It also doesn't have clock_gettime(). So much for POSIX and SUSv2. @@ -156,11 +158,12 @@ static hid_device *new_hid_device(void) static void free_hid_device(hid_device *dev) { + struct input_report *rpt; if (!dev) return; /* Delete any input reports still left over. */ - struct input_report *rpt = dev->input_reports; + rpt = dev->input_reports; while (rpt) { struct input_report *next = rpt->next; free(rpt->data); @@ -251,20 +254,21 @@ static int get_string_property(IOHIDDeviceRef device, CFStringRef prop, wchar_t if (!len) return 0; - + + if (CFGetTypeID(prop) != CFStringGetTypeID()) + return 0; + str = (CFStringRef)IOHIDDeviceGetProperty(device, prop); buf[0] = 0; - if (str) { - len --; - - CFIndex str_len = CFStringGetLength(str); + if (str && CFGetTypeID(str) == CFStringGetTypeID()) { + CFIndex used_buf_len, chars_copied; CFRange range; + CFIndex str_len = CFStringGetLength(str); + len --; range.location = 0; range.length = (str_len > len)? len: str_len; - CFIndex used_buf_len; - CFIndex chars_copied; chars_copied = CFStringGetBytes(str, range, kCFStringEncodingUTF32LE, @@ -288,19 +292,20 @@ static int get_string_property_utf8(IOHIDDeviceRef device, CFStringRef prop, cha if (!len) return 0; + if (CFGetTypeID(prop) != CFStringGetTypeID()) + return 0; + str = (CFStringRef)IOHIDDeviceGetProperty(device, prop); buf[0] = 0; - if (str) { - len--; - - CFIndex str_len = CFStringGetLength(str); + if (str && CFGetTypeID(str) == CFStringGetTypeID()) { + CFIndex used_buf_len, chars_copied; CFRange range; + CFIndex str_len = CFStringGetLength(str); + len--; range.location = 0; range.length = (str_len > len)? len: str_len; - CFIndex used_buf_len; - CFIndex chars_copied; chars_copied = CFStringGetBytes(str, range, kCFStringEncodingUTF8, @@ -392,20 +397,86 @@ static void hid_device_removal_callback(void *context, IOReturn result, } } +static CFDictionaryRef +create_usage_match(const UInt32 page, const UInt32 usage, int *okay) +{ + CFDictionaryRef retval = NULL; + CFNumberRef pageNumRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &page); + CFNumberRef usageNumRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage); + const void *keys[2] = { (void *) CFSTR(kIOHIDDeviceUsagePageKey), (void *) CFSTR(kIOHIDDeviceUsageKey) }; + const void *vals[2] = { (void *) pageNumRef, (void *) usageNumRef }; + + if (pageNumRef && usageNumRef) { + retval = CFDictionaryCreate(kCFAllocatorDefault, keys, vals, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + } + + if (pageNumRef) { + CFRelease(pageNumRef); + } + if (usageNumRef) { + CFRelease(usageNumRef); + } + + if (!retval) { + *okay = 0; + } + + return retval; +} + +static CFDictionaryRef +create_vendor_match(const UInt32 vendor, int *okay) +{ + CFDictionaryRef retval = NULL; + CFNumberRef vidNumRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &vendor); + const void *keys[1] = { (void *) CFSTR(kIOHIDVendorIDKey) }; + const void *vals[1] = { (void *) vidNumRef }; + + if (vidNumRef) { + retval = CFDictionaryCreate(kCFAllocatorDefault, keys, vals, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFRelease(vidNumRef); + } + + if (!retval) { + *okay = 0; + } + + return retval; +} + /* Initialize the IOHIDManager. Return 0 for success and -1 for failure. */ static int init_hid_manager(void) { + int okay = 1; + const void *vals[] = { + (void *) create_usage_match(kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick, &okay), + (void *) create_usage_match(kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad, &okay), + (void *) create_usage_match(kHIDPage_GenericDesktop, kHIDUsage_GD_MultiAxisController, &okay), + (void *) create_vendor_match(VALVE_USB_VID, &okay), + }; + const size_t numElements = SDL_arraysize(vals); + CFArrayRef matchingArray = okay ? CFArrayCreate(kCFAllocatorDefault, vals, numElements, &kCFTypeArrayCallBacks) : NULL; + size_t i; + + for (i = 0; i < numElements; i++) { + if (vals[i]) { + CFRelease((CFTypeRef) vals[i]); + } + } /* Initialize all the HID Manager Objects */ hid_mgr = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); if (hid_mgr) { - IOHIDManagerSetDeviceMatching(hid_mgr, NULL); + IOHIDManagerSetDeviceMatchingMultiple(hid_mgr, matchingArray); IOHIDManagerScheduleWithRunLoop(hid_mgr, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); IOHIDManagerRegisterDeviceRemovalCallback(hid_mgr, hid_device_removal_callback, NULL); - return 0; } - return -1; + if (matchingArray != NULL) { + CFRelease(matchingArray); + } + + return hid_mgr ? 0 : -1; } /* Initialize the IOHIDManager if necessary. This is the public function, and @@ -445,7 +516,10 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, struct hid_device_info *root = NULL; // return object struct hid_device_info *cur_dev = NULL; CFIndex num_devices; + CFSetRef device_set; + IOHIDDeviceRef *device_array; int i; + const char *hint = SDL_GetHint(SDL_HINT_HIDAPI_IGNORE_DEVICES); /* Set up the HID Manager if it hasn't been done */ if (hid_init() < 0) @@ -455,7 +529,7 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, process_pending_events(); /* Get a list of the Devices */ - CFSetRef device_set = IOHIDManagerCopyDevices(hid_mgr); + device_set = IOHIDManagerCopyDevices(hid_mgr); if (!device_set) return NULL; @@ -465,7 +539,7 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, CFRelease(device_set); return NULL; } - IOHIDDeviceRef *device_array = (IOHIDDeviceRef*)calloc(num_devices, sizeof(IOHIDDeviceRef)); + device_array = (IOHIDDeviceRef*)calloc(num_devices, sizeof(IOHIDDeviceRef)); CFSetGetValues(device_set, (const void **) device_array); /* Iterate over each device, making an entry for it. */ @@ -482,15 +556,35 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, continue; } +#if 0 // Prefer direct HID support as that has extended functionality +#if defined(SDL_JOYSTICK_MFI) + // We want to prefer Game Controller support where available, + // as Apple will likely be requiring that for supported devices. + extern SDL_bool IOS_SupportedHIDDevice(IOHIDDeviceRef device); + if (IOS_SupportedHIDDevice(dev)) { + continue; + } +#endif +#endif + dev_vid = get_vendor_id(dev); dev_pid = get_product_id(dev); + /* See if there are any devices we should skip in enumeration */ + if (hint) { + char vendor_match[16], product_match[16]; + SDL_snprintf(vendor_match, sizeof(vendor_match), "0x%.4x/0x0000", dev_vid); + SDL_snprintf(product_match, sizeof(product_match), "0x%.4x/0x%.4x", dev_vid, dev_pid); + if (SDL_strcasestr(hint, vendor_match) || SDL_strcasestr(hint, product_match)) { + continue; + } + } + /* Check the VID/PID against the arguments */ - if ((vendor_id == 0x0 && product_id == 0x0) || - (vendor_id == dev_vid && product_id == dev_pid)) { + if ((vendor_id == 0x0 || dev_vid == vendor_id) && + (product_id == 0x0 || dev_pid == product_id)) { struct hid_device_info *tmp; - size_t len; - + /* VID/PID match. Create the record. */ tmp = (struct hid_device_info *)calloc(1, sizeof(struct hid_device_info)); if (cur_dev) { @@ -507,7 +601,7 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, /* Fill out the record */ cur_dev->next = NULL; - len = make_path(dev, cbuf, sizeof(cbuf)); + make_path(dev, cbuf, sizeof(cbuf)); cur_dev->path = strdup(cbuf); /* Serial Number */ @@ -651,13 +745,14 @@ static void perform_signal_callback(void *context) static void *read_thread(void *param) { hid_device *dev = (hid_device *)param; + CFRunLoopSourceContext ctx; + SInt32 code; /* Move the device's run loop to this thread. */ IOHIDDeviceScheduleWithRunLoop(dev->device_handle, CFRunLoopGetCurrent(), dev->run_loop_mode); /* Create the RunLoopSource which is used to signal the event loop to stop when hid_close() is called. */ - CFRunLoopSourceContext ctx; memset(&ctx, 0, sizeof(ctx)); ctx.version = 0; ctx.info = dev; @@ -674,11 +769,10 @@ static void *read_thread(void *param) /* Run the Event Loop. CFRunLoopRunInMode() will dispatch HID input reports into the hid_report_callback(). */ - SInt32 code; while (!dev->shutdown_thread && !dev->disconnected) { code = CFRunLoopRunInMode(dev->run_loop_mode, 1000/*sec*/, FALSE); /* Return if the device has been disconnected */ - if (code == kCFRunLoopRunFinished) { + if (code == kCFRunLoopRunFinished || code == kCFRunLoopRunStopped) { dev->disconnected = 1; break; } @@ -714,35 +808,41 @@ static void *read_thread(void *param) hid_device * HID_API_EXPORT hid_open_path(const char *path, int bExclusive) { - int i; + int i; hid_device *dev = NULL; CFIndex num_devices; - + CFSetRef device_set; + IOHIDDeviceRef *device_array; + dev = new_hid_device(); /* Set up the HID Manager if it hasn't been done */ if (hid_init() < 0) return NULL; - + +#if 0 /* We have a path because the IOHIDManager is already updated */ /* give the IOHIDManager a chance to update itself */ process_pending_events(); - - CFSetRef device_set = IOHIDManagerCopyDevices(hid_mgr); +#endif + + device_set = IOHIDManagerCopyDevices(hid_mgr); + if (!device_set) + return NULL; num_devices = CFSetGetCount(device_set); - IOHIDDeviceRef *device_array = (IOHIDDeviceRef *)calloc(num_devices, sizeof(IOHIDDeviceRef)); + device_array = (IOHIDDeviceRef *)calloc(num_devices, sizeof(IOHIDDeviceRef)); CFSetGetValues(device_set, (const void **) device_array); for (i = 0; i < num_devices; i++) { char cbuf[BUF_LEN]; - size_t len; IOHIDDeviceRef os_dev = device_array[i]; - len = make_path(os_dev, cbuf, sizeof(cbuf)); + make_path(os_dev, cbuf, sizeof(cbuf)); if (!strcmp(cbuf, path)) { // Matched Paths. Open this Device. IOReturn ret = IOHIDDeviceOpen(os_dev, kIOHIDOptionsTypeNone); if (ret == kIOReturnSuccess) { char str[32]; + struct hid_device_list_node *node; free(device_array); CFRelease(device_set); @@ -750,11 +850,12 @@ hid_device * HID_API_EXPORT hid_open_path(const char *path, int bExclusive) /* Create the buffers for receiving data */ dev->max_input_report_len = (CFIndex) get_max_report_length(os_dev); + SDL_assert(dev->max_input_report_len > 0); dev->input_report_buf = (uint8_t *)calloc(dev->max_input_report_len, sizeof(uint8_t)); /* Create the Run Loop Mode for this device. printing the reference seems to work. */ - sprintf(str, "HIDAPI_%p", os_dev); + snprintf(str, sizeof(str), "HIDAPI_%p", os_dev); dev->run_loop_mode = CFStringCreateWithCString(NULL, str, kCFStringEncodingASCII); @@ -763,7 +864,7 @@ hid_device * HID_API_EXPORT hid_open_path(const char *path, int bExclusive) os_dev, dev->input_report_buf, dev->max_input_report_len, &hid_report_callback, dev); - struct hid_device_list_node *node = (struct hid_device_list_node *)calloc(1, sizeof(struct hid_device_list_node)); + node = (struct hid_device_list_node *)calloc(1, sizeof(struct hid_device_list_node)); node->dev = dev; node->next = device_list; device_list = node; @@ -853,11 +954,16 @@ static int return_data(hid_device *dev, unsigned char *data, size_t length) /* Copy the data out of the linked list item (rpt) into the return buffer (data), and delete the liked list item. */ struct input_report *rpt = dev->input_reports; - size_t len = (length < rpt->len)? length: rpt->len; - memcpy(data, rpt->data, len); - dev->input_reports = rpt->next; - free(rpt->data); - free(rpt); + size_t len = 0; + if (rpt != NULL) { + len = (length < rpt->len)? length: rpt->len; + if (data != NULL) { + memcpy(data, rpt->data, len); + } + dev->input_reports = rpt->next; + free(rpt->data); + free(rpt); + } return (int)len; } @@ -998,13 +1104,13 @@ int HID_API_EXPORT hid_get_feature_report(hid_device *dev, unsigned char *data, { CFIndex len = length; IOReturn res; - + int skipped_report_id = 0, report_number; + /* Return if the device has been unplugged. */ if (dev->disconnected) return -1; - int skipped_report_id = 0; - int report_number = data[0]; + report_number = data[0]; if (report_number == 0x0) { /* Offset the return buffer by 1, so that the report ID will remain in byte 0. */ @@ -1173,5 +1279,3 @@ int main(void) return 0; } #endif - -#endif /* SDL_JOYSTICK_HIDAPI */ diff --git a/SDL2-2.0.12/src/hidapi/pc/hidapi-hidraw.pc.in b/SDL2-2.30.5/src/hidapi/pc/hidapi-hidraw.pc.in similarity index 100% rename from SDL2-2.0.12/src/hidapi/pc/hidapi-hidraw.pc.in rename to SDL2-2.30.5/src/hidapi/pc/hidapi-hidraw.pc.in diff --git a/SDL2-2.0.12/src/hidapi/pc/hidapi-libusb.pc.in b/SDL2-2.30.5/src/hidapi/pc/hidapi-libusb.pc.in similarity index 100% rename from SDL2-2.0.12/src/hidapi/pc/hidapi-libusb.pc.in rename to SDL2-2.30.5/src/hidapi/pc/hidapi-libusb.pc.in diff --git a/SDL2-2.0.12/src/hidapi/pc/hidapi.pc.in b/SDL2-2.30.5/src/hidapi/pc/hidapi.pc.in similarity index 100% rename from SDL2-2.0.12/src/hidapi/pc/hidapi.pc.in rename to SDL2-2.30.5/src/hidapi/pc/hidapi.pc.in diff --git a/SDL2-2.0.12/src/hidapi/testgui/Makefile-manual b/SDL2-2.30.5/src/hidapi/testgui/Makefile-manual similarity index 100% rename from SDL2-2.0.12/src/hidapi/testgui/Makefile-manual rename to SDL2-2.30.5/src/hidapi/testgui/Makefile-manual diff --git a/SDL2-2.0.12/src/hidapi/testgui/Makefile.am b/SDL2-2.30.5/src/hidapi/testgui/Makefile.am similarity index 100% rename from SDL2-2.0.12/src/hidapi/testgui/Makefile.am rename to SDL2-2.30.5/src/hidapi/testgui/Makefile.am diff --git a/SDL2-2.0.12/src/hidapi/testgui/Makefile.freebsd b/SDL2-2.30.5/src/hidapi/testgui/Makefile.freebsd similarity index 100% rename from SDL2-2.0.12/src/hidapi/testgui/Makefile.freebsd rename to SDL2-2.30.5/src/hidapi/testgui/Makefile.freebsd diff --git a/SDL2-2.0.12/src/hidapi/testgui/Makefile.linux b/SDL2-2.30.5/src/hidapi/testgui/Makefile.linux similarity index 100% rename from SDL2-2.0.12/src/hidapi/testgui/Makefile.linux rename to SDL2-2.30.5/src/hidapi/testgui/Makefile.linux diff --git a/SDL2-2.0.12/src/hidapi/testgui/Makefile.mac b/SDL2-2.30.5/src/hidapi/testgui/Makefile.mac similarity index 100% rename from SDL2-2.0.12/src/hidapi/testgui/Makefile.mac rename to SDL2-2.30.5/src/hidapi/testgui/Makefile.mac diff --git a/SDL2-2.0.12/src/hidapi/testgui/Makefile.mingw b/SDL2-2.30.5/src/hidapi/testgui/Makefile.mingw similarity index 100% rename from SDL2-2.0.12/src/hidapi/testgui/Makefile.mingw rename to SDL2-2.30.5/src/hidapi/testgui/Makefile.mingw diff --git a/SDL2-2.0.12/src/hidapi/testgui/TestGUI.app.in/Contents/Info.plist b/SDL2-2.30.5/src/hidapi/testgui/TestGUI.app.in/Contents/Info.plist similarity index 100% rename from SDL2-2.0.12/src/hidapi/testgui/TestGUI.app.in/Contents/Info.plist rename to SDL2-2.30.5/src/hidapi/testgui/TestGUI.app.in/Contents/Info.plist diff --git a/SDL2-2.0.12/src/hidapi/testgui/TestGUI.app.in/Contents/PkgInfo b/SDL2-2.30.5/src/hidapi/testgui/TestGUI.app.in/Contents/PkgInfo similarity index 100% rename from SDL2-2.0.12/src/hidapi/testgui/TestGUI.app.in/Contents/PkgInfo rename to SDL2-2.30.5/src/hidapi/testgui/TestGUI.app.in/Contents/PkgInfo diff --git a/SDL2-2.0.12/src/hidapi/testgui/TestGUI.app.in/Contents/Resources/English.lproj/InfoPlist.strings b/SDL2-2.30.5/src/hidapi/testgui/TestGUI.app.in/Contents/Resources/English.lproj/InfoPlist.strings similarity index 100% rename from SDL2-2.0.12/src/hidapi/testgui/TestGUI.app.in/Contents/Resources/English.lproj/InfoPlist.strings rename to SDL2-2.30.5/src/hidapi/testgui/TestGUI.app.in/Contents/Resources/English.lproj/InfoPlist.strings diff --git a/SDL2-2.0.12/src/hidapi/testgui/TestGUI.app.in/Contents/Resources/Signal11.icns b/SDL2-2.30.5/src/hidapi/testgui/TestGUI.app.in/Contents/Resources/Signal11.icns similarity index 100% rename from SDL2-2.0.12/src/hidapi/testgui/TestGUI.app.in/Contents/Resources/Signal11.icns rename to SDL2-2.30.5/src/hidapi/testgui/TestGUI.app.in/Contents/Resources/Signal11.icns diff --git a/SDL2-2.0.12/src/hidapi/testgui/copy_to_bundle.sh b/SDL2-2.30.5/src/hidapi/testgui/copy_to_bundle.sh similarity index 100% rename from SDL2-2.0.12/src/hidapi/testgui/copy_to_bundle.sh rename to SDL2-2.30.5/src/hidapi/testgui/copy_to_bundle.sh diff --git a/SDL2-2.0.12/src/hidapi/testgui/mac_support.cpp b/SDL2-2.30.5/src/hidapi/testgui/mac_support.cpp similarity index 100% rename from SDL2-2.0.12/src/hidapi/testgui/mac_support.cpp rename to SDL2-2.30.5/src/hidapi/testgui/mac_support.cpp diff --git a/SDL2-2.0.12/src/hidapi/testgui/mac_support.h b/SDL2-2.30.5/src/hidapi/testgui/mac_support.h similarity index 100% rename from SDL2-2.0.12/src/hidapi/testgui/mac_support.h rename to SDL2-2.30.5/src/hidapi/testgui/mac_support.h diff --git a/SDL2-2.0.12/src/hidapi/testgui/mac_support_cocoa.m b/SDL2-2.30.5/src/hidapi/testgui/mac_support_cocoa.m similarity index 100% rename from SDL2-2.0.12/src/hidapi/testgui/mac_support_cocoa.m rename to SDL2-2.30.5/src/hidapi/testgui/mac_support_cocoa.m diff --git a/SDL2-2.0.12/src/hidapi/testgui/start.sh b/SDL2-2.30.5/src/hidapi/testgui/start.sh similarity index 100% rename from SDL2-2.0.12/src/hidapi/testgui/start.sh rename to SDL2-2.30.5/src/hidapi/testgui/start.sh diff --git a/SDL2-2.0.12/src/hidapi/testgui/test.cpp b/SDL2-2.30.5/src/hidapi/testgui/test.cpp similarity index 100% rename from SDL2-2.0.12/src/hidapi/testgui/test.cpp rename to SDL2-2.30.5/src/hidapi/testgui/test.cpp diff --git a/SDL2-2.0.12/src/hidapi/testgui/testgui.sln b/SDL2-2.30.5/src/hidapi/testgui/testgui.sln similarity index 100% rename from SDL2-2.0.12/src/hidapi/testgui/testgui.sln rename to SDL2-2.30.5/src/hidapi/testgui/testgui.sln diff --git a/SDL2-2.0.12/src/hidapi/testgui/testgui.vcproj b/SDL2-2.30.5/src/hidapi/testgui/testgui.vcproj similarity index 100% rename from SDL2-2.0.12/src/hidapi/testgui/testgui.vcproj rename to SDL2-2.30.5/src/hidapi/testgui/testgui.vcproj diff --git a/SDL2-2.0.12/src/hidapi/udev/99-hid.rules b/SDL2-2.30.5/src/hidapi/udev/99-hid.rules similarity index 100% rename from SDL2-2.0.12/src/hidapi/udev/99-hid.rules rename to SDL2-2.30.5/src/hidapi/udev/99-hid.rules diff --git a/SDL2-2.0.12/src/hidapi/windows/Makefile-manual b/SDL2-2.30.5/src/hidapi/windows/Makefile-manual similarity index 100% rename from SDL2-2.0.12/src/hidapi/windows/Makefile-manual rename to SDL2-2.30.5/src/hidapi/windows/Makefile-manual diff --git a/SDL2-2.0.12/src/hidapi/windows/Makefile.am b/SDL2-2.30.5/src/hidapi/windows/Makefile.am similarity index 100% rename from SDL2-2.0.12/src/hidapi/windows/Makefile.am rename to SDL2-2.30.5/src/hidapi/windows/Makefile.am diff --git a/SDL2-2.0.12/src/hidapi/windows/Makefile.mingw b/SDL2-2.30.5/src/hidapi/windows/Makefile.mingw similarity index 100% rename from SDL2-2.0.12/src/hidapi/windows/Makefile.mingw rename to SDL2-2.30.5/src/hidapi/windows/Makefile.mingw diff --git a/SDL2-2.0.12/src/hidapi/windows/ddk_build/hidapi.def b/SDL2-2.30.5/src/hidapi/windows/ddk_build/hidapi.def similarity index 100% rename from SDL2-2.0.12/src/hidapi/windows/ddk_build/hidapi.def rename to SDL2-2.30.5/src/hidapi/windows/ddk_build/hidapi.def diff --git a/SDL2-2.0.12/src/hidapi/windows/ddk_build/sources b/SDL2-2.30.5/src/hidapi/windows/ddk_build/sources similarity index 100% rename from SDL2-2.0.12/src/hidapi/windows/ddk_build/sources rename to SDL2-2.30.5/src/hidapi/windows/ddk_build/sources diff --git a/SDL2-2.0.12/src/hidapi/windows/hid.c b/SDL2-2.30.5/src/hidapi/windows/hid.c similarity index 81% rename from SDL2-2.0.12/src/hidapi/windows/hid.c rename to SDL2-2.30.5/src/hidapi/windows/hid.c index b76b91b..3d8a230 100644 --- a/SDL2-2.0.12/src/hidapi/windows/hid.c +++ b/SDL2-2.30.5/src/hidapi/windows/hid.c @@ -21,10 +21,14 @@ ********************************************************/ #include "../../SDL_internal.h" -#ifdef SDL_JOYSTICK_HIDAPI +#include "SDL_hints.h" #include +#ifndef _WIN32_WINNT_WIN8 +#define _WIN32_WINNT_WIN8 0x0602 +#endif + #if 0 /* can cause redefinition errors on some toolchains */ #ifdef __MINGW32__ #include @@ -41,22 +45,6 @@ typedef LONG NTSTATUS; #endif -/* SDL C runtime functions */ -#include "SDL_stdinc.h" - -#define calloc SDL_calloc -#define free SDL_free -#define malloc SDL_malloc -#define memcpy SDL_memcpy -#define memset SDL_memset -#define strcmp SDL_strcmp -#define strlen SDL_strlen -#define strncpy SDL_strlcpy -#define strstr SDL_strstr -#define strtol SDL_strtol -#define wcscmp SDL_wcscmp -#define _wcsdup SDL_wcsdup - /* The maximum number of characters that can be passed into the HidD_Get*String() functions without it failing.*/ #define MAX_STRING_WCHARS 0xFFF @@ -68,6 +56,13 @@ typedef LONG NTSTATUS; report that we've seen is ~200-250ms so let's double that */ #define HID_WRITE_TIMEOUT_MILLISECONDS 500 +/* We will only enumerate devices that match these usages */ +#define USAGE_PAGE_GENERIC_DESKTOP 0x0001 +#define USAGE_JOYSTICK 0x0004 +#define USAGE_GAMEPAD 0x0005 +#define USAGE_MULTIAXISCONTROLLER 0x0008 +#define USB_VENDOR_VALVE 0x28de + #ifdef __cplusplus extern "C" { #endif @@ -86,18 +81,33 @@ extern "C" { } /* extern "C" */ #endif -#include -#include - - #include "../hidapi/hidapi.h" +/*#include */ +/*#include */ + +/* SDL C runtime functions */ +#include "SDL_stdinc.h" + +#define calloc SDL_calloc +#define free SDL_free +#define malloc SDL_malloc +#define memcpy SDL_memcpy +#define memset SDL_memset +#define strcmp SDL_strcmp +#define strlen SDL_strlen +#define strstr SDL_strstr +#define strtol SDL_strtol +#define wcscmp SDL_wcscmp +#define _wcsdup SDL_wcsdup + + #undef MIN #define MIN(x,y) ((x) < (y)? (x): (y)) #ifdef _MSC_VER - /* Thanks Microsoft, but I know how to use strncpy(). */ - #pragma warning(disable:4996) + /* Yes, we have some unreferenced formal parameters */ + #pragma warning(disable:4100) #endif #ifdef __cplusplus @@ -169,8 +179,29 @@ struct hid_device_ { char *read_buf; OVERLAPPED ol; OVERLAPPED write_ol; + BOOL use_hid_write_output_report; }; +static BOOL +IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor) +{ + OSVERSIONINFOEXW osvi; + DWORDLONG const dwlConditionMask = VerSetConditionMask( + VerSetConditionMask( + VerSetConditionMask( + 0, VER_MAJORVERSION, VER_GREATER_EQUAL ), + VER_MINORVERSION, VER_GREATER_EQUAL ), + VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL ); + + memset(&osvi, 0, sizeof(osvi)); + osvi.dwOSVersionInfoSize = sizeof( osvi ); + osvi.dwMajorVersion = wMajorVersion; + osvi.dwMinorVersion = wMinorVersion; + osvi.wServicePackMajor = wServicePackMajor; + + return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE; +} + static hid_device *new_hid_device() { hid_device *dev = (hid_device*) calloc(1, sizeof(hid_device)); @@ -235,7 +266,7 @@ static void register_error(hid_device *device, const char *op) #ifndef HIDAPI_USE_DDK static int lookup_functions() { - lib_handle = LoadLibraryA("hid.dll"); + lib_handle = LoadLibrary(TEXT("hid.dll")); if (lib_handle) { #define RESOLVE(x) x = (x##_)GetProcAddress(lib_handle, #x); if (!x) return -1; RESOLVE(HidD_GetAttributes); @@ -307,25 +338,27 @@ int HID_API_EXPORT hid_exit(void) int hid_blacklist(unsigned short vendor_id, unsigned short product_id) { - // Corsair Gaming keyboard - Causes deadlock when asking for device details - if ( vendor_id == 0x1B1C && product_id == 0x1B3D ) - { - return 1; - } + size_t i; + static const struct { unsigned short vid; unsigned short pid; } known_bad[] = { + /* Causes deadlock when asking for device details... */ + { 0x1B1C, 0x1B3D }, /* Corsair Gaming keyboard */ + { 0x1532, 0x0109 }, /* Razer Lycosa Gaming keyboard */ + { 0x1532, 0x010B }, /* Razer Arctosa Gaming keyboard */ + { 0x045E, 0x0822 }, /* Microsoft Precision Mouse */ + { 0x0D8C, 0x0014 }, /* Sharkoon Skiller SGH2 headset */ + { 0x1CCF, 0x0000 }, /* All Konami Amusement Devices */ - // SPEEDLINK COMPETITION PRO - turns into an Android controller when enumerated - if ( vendor_id == 0x0738 && product_id == 0x2217 ) - { - return 1; - } + /* Turns into an Android controller when enumerated... */ + { 0x0738, 0x2217 } /* SPEEDLINK COMPETITION PRO */ + }; - // Sound BlasterX G1 - Causes 10 second stalls when asking for manufacturer's string - if ( vendor_id == 0x041E && product_id == 0x3249 ) - { - return 1; - } + for (i = 0; i < (sizeof(known_bad)/sizeof(known_bad[0])); i++) { + if ((vendor_id == known_bad[i].vid) && (product_id == known_bad[i].pid || known_bad[i].pid == 0x0000)) { + return 1; + } + } - return 0; + return 0; } struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id) @@ -341,6 +374,7 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor SP_DEVICE_INTERFACE_DETAIL_DATA_A *device_interface_detail_data = NULL; HDEVINFO device_info_set = INVALID_HANDLE_VALUE; int device_index = 0; + const char *hint = SDL_GetHint(SDL_HINT_HIDAPI_IGNORE_DEVICES); if (hid_init() < 0) return NULL; @@ -402,6 +436,11 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor goto cont; } + /* XInput devices don't get real HID reports and are better handled by the raw input driver */ + if (strstr(device_interface_detail_data->DevicePath, "&ig_") != NULL) { + goto cont; + } + /* Make sure this device is of Setup Class "HIDClass" and has a driver bound to it. */ /* In the main HIDAPI tree this is a loop which will erroneously open @@ -444,7 +483,7 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor if (write_handle == INVALID_HANDLE_VALUE) { /* Unable to open the device. */ //register_error(dev, "CreateFile"); - goto cont_close; + goto cont; } @@ -453,6 +492,16 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor HidD_GetAttributes(write_handle, &attrib); //wprintf(L"Product/Vendor: %x %x\n", attrib.ProductID, attrib.VendorID); + /* See if there are any devices we should skip in enumeration */ + if (hint) { + char vendor_match[16], product_match[16]; + SDL_snprintf(vendor_match, sizeof(vendor_match), "0x%.4x/0x0000", attrib.VendorID); + SDL_snprintf(product_match, sizeof(product_match), "0x%.4x/0x%.4x", attrib.VendorID, attrib.ProductID); + if (SDL_strcasestr(hint, vendor_match) || SDL_strcasestr(hint, product_match)) { + continue; + } + } + /* Check the VID/PID to see if we should add this device to the enumeration list. */ if ((vendor_id == 0x0 || attrib.VendorID == vendor_id) && @@ -469,6 +518,30 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor wchar_t wstr[WSTR_LEN]; /* TODO: Determine Size */ size_t len; + /* Get the Usage Page and Usage for this device. */ + hidp_res = HidD_GetPreparsedData(write_handle, &pp_data); + if (hidp_res) { + nt_res = HidP_GetCaps(pp_data, &caps); + HidD_FreePreparsedData(pp_data); + if (nt_res != HIDP_STATUS_SUCCESS) { + goto cont_close; + } + } + else { + goto cont_close; + } + + /* SDL Modification: Ignore the device if it's not a gamepad. This limits compatibility + risk from devices that may respond poorly to our string queries below. */ + if (attrib.VendorID != USB_VENDOR_VALVE) { + if (caps.UsagePage != USAGE_PAGE_GENERIC_DESKTOP) { + goto cont_close; + } + if (caps.Usage != USAGE_JOYSTICK && caps.Usage != USAGE_GAMEPAD && caps.Usage != USAGE_MULTIAXISCONTROLLER) { + goto cont_close; + } + } + /* VID/PID match. Create the record. */ tmp = (struct hid_device_info*) calloc(1, sizeof(struct hid_device_info)); if (cur_dev) { @@ -478,27 +551,16 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor root = tmp; } cur_dev = tmp; - - /* Get the Usage Page and Usage for this device. */ - hidp_res = HidD_GetPreparsedData(write_handle, &pp_data); - if (hidp_res) { - nt_res = HidP_GetCaps(pp_data, &caps); - if (nt_res == HIDP_STATUS_SUCCESS) { - cur_dev->usage_page = caps.UsagePage; - cur_dev->usage = caps.Usage; - } - - HidD_FreePreparsedData(pp_data); - } /* Fill out the record */ + cur_dev->usage_page = caps.UsagePage; + cur_dev->usage = caps.Usage; cur_dev->next = NULL; str = device_interface_detail_data->DevicePath; if (str) { len = strlen(str); cur_dev->path = (char*) calloc(len+1, sizeof(char)); - strncpy(cur_dev->path, str, len+1); - cur_dev->path[len] = '\0'; + memcpy(cur_dev->path, str, len+1); } else cur_dev->path = NULL; @@ -666,6 +728,11 @@ HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path, int bEx dev->input_report_length = caps.InputReportByteLength; HidD_FreePreparsedData(pp_data); + /* On Windows 7, we need to use hid_write_output_report() over Bluetooth */ + if (dev->output_report_length > 512) { + dev->use_hid_write_output_report = !IsWindowsVersionOrGreater( HIBYTE( _WIN32_WINNT_WIN8 ), LOBYTE( _WIN32_WINNT_WIN8 ), 0 ); + } + dev->read_buf = (char*) malloc(dev->input_report_length); return dev; @@ -691,9 +758,12 @@ static int hid_write_timeout(hid_device *dev, const unsigned char *data, size_t { DWORD bytes_written; BOOL res; - size_t stashed_length = length; unsigned char *buf; + if (dev->use_hid_write_output_report) { + return hid_write_output_report(dev, data, length); + } + /* Make sure the right number of bytes are passed to WriteFile. Windows expects the number of bytes which are in the _longest_ report (plus one for the report number) bytes even if the data is a report @@ -711,41 +781,35 @@ static int hid_write_timeout(hid_device *dev, const unsigned char *data, size_t memset(buf + length, 0, dev->output_report_length - length); length = dev->output_report_length; } - if (length > 512) - { - return hid_write_output_report( dev, data, stashed_length ); - } - else - { - res = WriteFile( dev->device_handle, buf, ( DWORD ) length, NULL, &dev->write_ol ); - if (!res) { - if (GetLastError() != ERROR_IO_PENDING) { - /* WriteFile() failed. Return error. */ - register_error(dev, "WriteFile"); - bytes_written = (DWORD) -1; - goto end_of_function; - } - } - /* Wait here until the write is done. This makes - hid_write() synchronous. */ - res = WaitForSingleObject(dev->write_ol.hEvent, milliseconds); - if (res != WAIT_OBJECT_0) - { - // There was a Timeout. - bytes_written = (DWORD) -1; - register_error(dev, "WriteFile/WaitForSingleObject Timeout"); - goto end_of_function; - } - - res = GetOverlappedResult(dev->device_handle, &dev->write_ol, &bytes_written, FALSE/*F=don't_wait*/); - if (!res) { - /* The Write operation failed. */ + res = WriteFile( dev->device_handle, buf, ( DWORD ) length, NULL, &dev->write_ol ); + if (!res) { + if (GetLastError() != ERROR_IO_PENDING) { + /* WriteFile() failed. Return error. */ register_error(dev, "WriteFile"); bytes_written = (DWORD) -1; goto end_of_function; } } + + /* Wait here until the write is done. This makes hid_write() synchronous. */ + res = WaitForSingleObject(dev->write_ol.hEvent, milliseconds); + if (res != WAIT_OBJECT_0) + { + // There was a Timeout. + bytes_written = (DWORD) -1; + register_error(dev, "WriteFile/WaitForSingleObject Timeout"); + goto end_of_function; + } + + res = GetOverlappedResult(dev->device_handle, &dev->write_ol, &bytes_written, FALSE/*F=don't_wait*/); + if (!res) { + /* The Write operation failed. */ + register_error(dev, "WriteFile"); + bytes_written = (DWORD) -1; + goto end_of_function; + } + end_of_function: if (buf != data) free(buf); @@ -785,20 +849,19 @@ int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char } } - if (milliseconds >= 0) { - /* See if there is any data yet. */ - res = WaitForSingleObject(ev, milliseconds); - if (res != WAIT_OBJECT_0) { - /* There was no data this time. Return zero bytes available, - but leave the Overlapped I/O running. */ - return 0; - } + /* See if there is any data yet. */ + res = WaitForSingleObject(ev, milliseconds >= 0 ? milliseconds : INFINITE); + if (res != WAIT_OBJECT_0) { + /* There was no data this time. Return zero bytes available, + but leave the Overlapped I/O running. */ + return 0; } - /* Either WaitForSingleObject() told us that ReadFile has completed, or - we are in non-blocking mode. Get the number of bytes read. The actual - data has been copied to the data[] array which was passed to ReadFile(). */ - res = GetOverlappedResult(dev->device_handle, &dev->ol, &bytes_read, TRUE/*wait*/); + /* Get the number of bytes read. The actual data has been copied to the data[] + array which was passed to ReadFile(). We must not wait here because we've + already waited on our event above, and since it's auto-reset, it will have + been reset back to unsignalled by now. */ + res = GetOverlappedResult(dev->device_handle, &dev->ol, &bytes_read, FALSE/*don't wait*/); /* Set pending back to false, even if GetOverlappedResult() returned error. */ dev->read_pending = FALSE; @@ -891,21 +954,29 @@ int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *dev, unsigned return -1; } - /* bytes_returned does not include the first byte which contains the - report ID. The data buffer actually contains one more byte than - bytes_returned. */ - bytes_returned++; - - return bytes_returned; #endif } void HID_API_EXPORT HID_API_CALL hid_close(hid_device *dev) { + typedef BOOL (WINAPI *CancelIoEx_t)(HANDLE hFile, LPOVERLAPPED lpOverlapped); + CancelIoEx_t CancelIoExFunc = (CancelIoEx_t)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "CancelIoEx"); + if (!dev) return; - CancelIo(dev->device_handle); + + if (CancelIoExFunc) { + CancelIoExFunc(dev->device_handle, NULL); + } else { + /* Windows XP, this will only cancel I/O on the current thread */ + CancelIo(dev->device_handle); + } + if (dev->read_pending) { + DWORD bytes_read = 0; + + GetOverlappedResult(dev->device_handle, &dev->ol, &bytes_read, TRUE/*wait*/); + } free_hid_device(dev); } @@ -973,23 +1044,23 @@ HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev) /*#define S11*/ #define P32 #ifdef S11 - unsigned short VendorID = 0xa0a0; + unsigned short VendorID = 0xa0a0; unsigned short ProductID = 0x0001; #endif #ifdef P32 - unsigned short VendorID = 0x04d8; + unsigned short VendorID = 0x04d8; unsigned short ProductID = 0x3f; #endif #ifdef PICPGM - unsigned short VendorID = 0x04d8; - unsigned short ProductID = 0x0033; + unsigned short VendorID = 0x04d8; + unsigned short ProductID = 0x0033; #endif int __cdecl main(int argc, char* argv[]) { - int res; + int i, res; unsigned char buf[65]; UNREFERENCED_PARAMETER(argc); @@ -1025,7 +1096,7 @@ int __cdecl main(int argc, char* argv[]) printf("Unable to read()\n"); /* Print out the returned buffer. */ - for (int i = 0; i < 4; i++) + for (i = 0; i < 4; i++) printf("buf[%d]: %d\n", i, buf[i]); return 0; @@ -1035,5 +1106,3 @@ int __cdecl main(int argc, char* argv[]) #ifdef __cplusplus } /* extern "C" */ #endif - -#endif /* SDL_JOYSTICK_HIDAPI */ diff --git a/SDL2-2.0.12/src/hidapi/windows/hidapi.sln b/SDL2-2.30.5/src/hidapi/windows/hidapi.sln similarity index 100% rename from SDL2-2.0.12/src/hidapi/windows/hidapi.sln rename to SDL2-2.30.5/src/hidapi/windows/hidapi.sln diff --git a/SDL2-2.0.12/src/hidapi/windows/hidapi.vcproj b/SDL2-2.30.5/src/hidapi/windows/hidapi.vcproj similarity index 100% rename from SDL2-2.0.12/src/hidapi/windows/hidapi.vcproj rename to SDL2-2.30.5/src/hidapi/windows/hidapi.vcproj diff --git a/SDL2-2.0.12/src/hidapi/windows/hidtest.vcproj b/SDL2-2.30.5/src/hidapi/windows/hidtest.vcproj similarity index 100% rename from SDL2-2.0.12/src/hidapi/windows/hidtest.vcproj rename to SDL2-2.30.5/src/hidapi/windows/hidtest.vcproj diff --git a/SDL2-2.30.5/src/joystick/SDL_gamecontroller.c b/SDL2-2.30.5/src/joystick/SDL_gamecontroller.c new file mode 100644 index 0000000..410c985 --- /dev/null +++ b/SDL2-2.30.5/src/joystick/SDL_gamecontroller.c @@ -0,0 +1,3276 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +/* This is the game controller API for Simple DirectMedia Layer */ + +#include "SDL_events.h" +#include "SDL_hints.h" +#include "SDL_timer.h" +#include "SDL_sysjoystick.h" +#include "SDL_joystick_c.h" +#include "SDL_steam_virtual_gamepad.h" +#include "SDL_gamecontrollerdb.h" +#include "controller_type.h" +#include "usb_ids.h" +#include "hidapi/SDL_hidapi_nintendo.h" + +#ifndef SDL_EVENTS_DISABLED +#include "../events/SDL_events_c.h" +#endif + +#if defined(__ANDROID__) +#include "SDL_system.h" +#endif + +/* Many controllers turn the center button into an instantaneous button press */ +#define SDL_MINIMUM_GUIDE_BUTTON_DELAY_MS 250 + +#define SDL_CONTROLLER_CRC_FIELD "crc:" +#define SDL_CONTROLLER_CRC_FIELD_SIZE 4 /* hard-coded for speed */ +#define SDL_CONTROLLER_TYPE_FIELD "type:" +#define SDL_CONTROLLER_TYPE_FIELD_SIZE SDL_strlen(SDL_CONTROLLER_TYPE_FIELD) +#define SDL_CONTROLLER_PLATFORM_FIELD "platform:" +#define SDL_CONTROLLER_PLATFORM_FIELD_SIZE SDL_strlen(SDL_CONTROLLER_PLATFORM_FIELD) +#define SDL_CONTROLLER_HINT_FIELD "hint:" +#define SDL_CONTROLLER_HINT_FIELD_SIZE SDL_strlen(SDL_CONTROLLER_HINT_FIELD) +#define SDL_CONTROLLER_SDKGE_FIELD "sdk>=:" +#define SDL_CONTROLLER_SDKGE_FIELD_SIZE SDL_strlen(SDL_CONTROLLER_SDKGE_FIELD) +#define SDL_CONTROLLER_SDKLE_FIELD "sdk<=:" +#define SDL_CONTROLLER_SDKLE_FIELD_SIZE SDL_strlen(SDL_CONTROLLER_SDKLE_FIELD) + +/* a list of currently opened game controllers */ +static SDL_GameController *SDL_gamecontrollers SDL_GUARDED_BY(SDL_joystick_lock) = NULL; + +typedef struct +{ + SDL_GameControllerBindType inputType; + union + { + int button; + + struct + { + int axis; + int axis_min; + int axis_max; + } axis; + + struct + { + int hat; + int hat_mask; + } hat; + + } input; + + SDL_GameControllerBindType outputType; + union + { + SDL_GameControllerButton button; + + struct + { + SDL_GameControllerAxis axis; + int axis_min; + int axis_max; + } axis; + + } output; + +} SDL_ExtendedGameControllerBind; + +/* our hard coded list of mapping support */ +typedef enum +{ + SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT, + SDL_CONTROLLER_MAPPING_PRIORITY_API, + SDL_CONTROLLER_MAPPING_PRIORITY_USER, +} SDL_ControllerMappingPriority; + +#define _guarded SDL_GUARDED_BY(SDL_joystick_lock) + +typedef struct _ControllerMapping_t +{ + SDL_JoystickGUID guid _guarded; + char *name _guarded; + char *mapping _guarded; + SDL_ControllerMappingPriority priority _guarded; + struct _ControllerMapping_t *next _guarded; +} ControllerMapping_t; + +#undef _guarded + +static SDL_JoystickGUID s_zeroGUID; +static ControllerMapping_t *s_pSupportedControllers SDL_GUARDED_BY(SDL_joystick_lock) = NULL; +static ControllerMapping_t *s_pDefaultMapping SDL_GUARDED_BY(SDL_joystick_lock) = NULL; +static ControllerMapping_t *s_pXInputMapping SDL_GUARDED_BY(SDL_joystick_lock) = NULL; +static char gamecontroller_magic; + +#define _guarded SDL_GUARDED_BY(SDL_joystick_lock) + +/* The SDL game controller structure */ +struct _SDL_GameController +{ + const void *magic _guarded; + + SDL_Joystick *joystick _guarded; /* underlying joystick device */ + int ref_count _guarded; + + const char *name _guarded; + SDL_GameControllerType type _guarded; + ControllerMapping_t *mapping _guarded; + int num_bindings _guarded; + SDL_ExtendedGameControllerBind *bindings _guarded; + SDL_ExtendedGameControllerBind **last_match_axis _guarded; + Uint8 *last_hat_mask _guarded; + Uint32 guide_button_down _guarded; + + struct _SDL_GameController *next _guarded; /* pointer to next game controller we have allocated */ +}; + +#undef _guarded + +#define CHECK_GAMECONTROLLER_MAGIC(gamecontroller, retval) \ + if (!gamecontroller || gamecontroller->magic != &gamecontroller_magic || \ + !SDL_PrivateJoystickValid(gamecontroller->joystick)) { \ + SDL_InvalidParamError("gamecontroller"); \ + SDL_UnlockJoysticks(); \ + return retval; \ + } + +static SDL_vidpid_list SDL_allowed_controllers = { + SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES_EXCEPT, 0, 0, NULL, + NULL, 0, 0, NULL, + 0, NULL, + SDL_FALSE +}; +static SDL_vidpid_list SDL_ignored_controllers = { + SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES, 0, 0, NULL, + NULL, 0, 0, NULL, + 0, NULL, + SDL_FALSE +}; + +static ControllerMapping_t *SDL_PrivateAddMappingForGUID(SDL_JoystickGUID jGUID, const char *mappingString, SDL_bool *existing, SDL_ControllerMappingPriority priority); +static int SDL_PrivateGameControllerAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis, Sint16 value); +static int SDL_PrivateGameControllerButton(SDL_GameController *gamecontroller, SDL_GameControllerButton button, Uint8 state); + +static SDL_bool HasSameOutput(SDL_ExtendedGameControllerBind *a, SDL_ExtendedGameControllerBind *b) +{ + if (a->outputType != b->outputType) { + return SDL_FALSE; + } + + if (a->outputType == SDL_CONTROLLER_BINDTYPE_AXIS) { + return a->output.axis.axis == b->output.axis.axis; + } else { + return a->output.button == b->output.button; + } +} + +static void ResetOutput(SDL_GameController *gamecontroller, SDL_ExtendedGameControllerBind *bind) +{ + if (bind->outputType == SDL_CONTROLLER_BINDTYPE_AXIS) { + SDL_PrivateGameControllerAxis(gamecontroller, bind->output.axis.axis, 0); + } else { + SDL_PrivateGameControllerButton(gamecontroller, bind->output.button, SDL_RELEASED); + } +} + +static void HandleJoystickAxis(SDL_GameController *gamecontroller, int axis, int value) +{ + int i; + SDL_ExtendedGameControllerBind *last_match; + SDL_ExtendedGameControllerBind *match = NULL; + + SDL_AssertJoysticksLocked(); + + last_match = gamecontroller->last_match_axis[axis]; + for (i = 0; i < gamecontroller->num_bindings; ++i) { + SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i]; + if (binding->inputType == SDL_CONTROLLER_BINDTYPE_AXIS && + axis == binding->input.axis.axis) { + if (binding->input.axis.axis_min < binding->input.axis.axis_max) { + if (value >= binding->input.axis.axis_min && + value <= binding->input.axis.axis_max) { + match = binding; + break; + } + } else { + if (value >= binding->input.axis.axis_max && + value <= binding->input.axis.axis_min) { + match = binding; + break; + } + } + } + } + + if (last_match && (!match || !HasSameOutput(last_match, match))) { + /* Clear the last input that this axis generated */ + ResetOutput(gamecontroller, last_match); + } + + if (match) { + if (match->outputType == SDL_CONTROLLER_BINDTYPE_AXIS) { + if (match->input.axis.axis_min != match->output.axis.axis_min || match->input.axis.axis_max != match->output.axis.axis_max) { + float normalized_value = (float)(value - match->input.axis.axis_min) / (match->input.axis.axis_max - match->input.axis.axis_min); + value = match->output.axis.axis_min + (int)(normalized_value * (match->output.axis.axis_max - match->output.axis.axis_min)); + } + SDL_PrivateGameControllerAxis(gamecontroller, match->output.axis.axis, (Sint16)value); + } else { + Uint8 state; + int threshold = match->input.axis.axis_min + (match->input.axis.axis_max - match->input.axis.axis_min) / 2; + if (match->input.axis.axis_max < match->input.axis.axis_min) { + state = (value <= threshold) ? SDL_PRESSED : SDL_RELEASED; + } else { + state = (value >= threshold) ? SDL_PRESSED : SDL_RELEASED; + } + SDL_PrivateGameControllerButton(gamecontroller, match->output.button, state); + } + } + gamecontroller->last_match_axis[axis] = match; +} + +static void HandleJoystickButton(SDL_GameController *gamecontroller, int button, Uint8 state) +{ + int i; + + SDL_AssertJoysticksLocked(); + + for (i = 0; i < gamecontroller->num_bindings; ++i) { + SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i]; + if (binding->inputType == SDL_CONTROLLER_BINDTYPE_BUTTON && + button == binding->input.button) { + if (binding->outputType == SDL_CONTROLLER_BINDTYPE_AXIS) { + int value = state ? binding->output.axis.axis_max : binding->output.axis.axis_min; + SDL_PrivateGameControllerAxis(gamecontroller, binding->output.axis.axis, (Sint16)value); + } else { + SDL_PrivateGameControllerButton(gamecontroller, binding->output.button, state); + } + break; + } + } +} + +static void HandleJoystickHat(SDL_GameController *gamecontroller, int hat, Uint8 value) +{ + int i; + Uint8 last_mask, changed_mask; + + SDL_AssertJoysticksLocked(); + + last_mask = gamecontroller->last_hat_mask[hat]; + changed_mask = (last_mask ^ value); + for (i = 0; i < gamecontroller->num_bindings; ++i) { + SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i]; + if (binding->inputType == SDL_CONTROLLER_BINDTYPE_HAT && hat == binding->input.hat.hat) { + if ((changed_mask & binding->input.hat.hat_mask) != 0) { + if (value & binding->input.hat.hat_mask) { + if (binding->outputType == SDL_CONTROLLER_BINDTYPE_AXIS) { + SDL_PrivateGameControllerAxis(gamecontroller, binding->output.axis.axis, (Sint16)binding->output.axis.axis_max); + } else { + SDL_PrivateGameControllerButton(gamecontroller, binding->output.button, SDL_PRESSED); + } + } else { + ResetOutput(gamecontroller, binding); + } + } + } + } + gamecontroller->last_hat_mask[hat] = value; +} + +/* The joystick layer will _also_ send events to recenter before disconnect, + but it has to make (sometimes incorrect) guesses at what being "centered" + is. The game controller layer, however, can set a definite logical idle + position, so set them all here. If we happened to already be at the + center thanks to the joystick layer or idle hands, this won't generate + duplicate events. */ +static void RecenterGameController(SDL_GameController *gamecontroller) +{ + SDL_GameControllerButton button; + SDL_GameControllerAxis axis; + + for (button = (SDL_GameControllerButton)0; button < SDL_CONTROLLER_BUTTON_MAX; button++) { + if (SDL_GameControllerGetButton(gamecontroller, button)) { + SDL_PrivateGameControllerButton(gamecontroller, button, SDL_RELEASED); + } + } + + for (axis = (SDL_GameControllerAxis)0; axis < SDL_CONTROLLER_AXIS_MAX; axis++) { + if (SDL_GameControllerGetAxis(gamecontroller, axis) != 0) { + SDL_PrivateGameControllerAxis(gamecontroller, axis, 0); + } + } +} + +/* + * Event filter to fire controller events from joystick ones + */ +static int SDLCALL SDL_GameControllerEventWatcher(void *userdata, SDL_Event *event) +{ + SDL_GameController *controller; + + switch (event->type) { + case SDL_JOYAXISMOTION: + { + SDL_AssertJoysticksLocked(); + + for (controller = SDL_gamecontrollers; controller; controller = controller->next) { + if (controller->joystick->instance_id == event->jaxis.which) { + HandleJoystickAxis(controller, event->jaxis.axis, event->jaxis.value); + break; + } + } + } break; + case SDL_JOYBUTTONDOWN: + case SDL_JOYBUTTONUP: + { + SDL_AssertJoysticksLocked(); + + for (controller = SDL_gamecontrollers; controller; controller = controller->next) { + if (controller->joystick->instance_id == event->jbutton.which) { + HandleJoystickButton(controller, event->jbutton.button, event->jbutton.state); + break; + } + } + } break; + case SDL_JOYHATMOTION: + { + SDL_AssertJoysticksLocked(); + + for (controller = SDL_gamecontrollers; controller; controller = controller->next) { + if (controller->joystick->instance_id == event->jhat.which) { + HandleJoystickHat(controller, event->jhat.hat, event->jhat.value); + break; + } + } + } break; + case SDL_JOYDEVICEADDED: + { + if (SDL_IsGameController(event->jdevice.which)) { + SDL_Event deviceevent; + deviceevent.type = SDL_CONTROLLERDEVICEADDED; + deviceevent.cdevice.which = event->jdevice.which; + SDL_PushEvent(&deviceevent); + } + } break; + case SDL_JOYDEVICEREMOVED: + { + SDL_AssertJoysticksLocked(); + + for (controller = SDL_gamecontrollers; controller; controller = controller->next) { + if (controller->joystick->instance_id == event->jdevice.which) { + RecenterGameController(controller); + break; + } + } + + /* We don't know if this was a game controller, so go ahead and send an event */ + { + SDL_Event deviceevent; + + deviceevent.type = SDL_CONTROLLERDEVICEREMOVED; + deviceevent.cdevice.which = event->jdevice.which; + SDL_PushEvent(&deviceevent); + } + } break; + default: + break; + } + + return 1; +} + +#ifdef __ANDROID__ +/* + * Helper function to guess at a mapping based on the elements reported for this controller + */ +static ControllerMapping_t *SDL_CreateMappingForAndroidController(SDL_JoystickGUID guid) +{ + const int face_button_mask = ((1 << SDL_CONTROLLER_BUTTON_A) | + (1 << SDL_CONTROLLER_BUTTON_B) | + (1 << SDL_CONTROLLER_BUTTON_X) | + (1 << SDL_CONTROLLER_BUTTON_Y)); + SDL_bool existing; + char mapping_string[1024]; + int button_mask; + int axis_mask; + + button_mask = SDL_SwapLE16(*(Uint16 *)(&guid.data[sizeof(guid.data) - 4])); + axis_mask = SDL_SwapLE16(*(Uint16 *)(&guid.data[sizeof(guid.data) - 2])); + if (!button_mask && !axis_mask) { + /* Accelerometer, shouldn't have a game controller mapping */ + return NULL; + } + if (!(button_mask & face_button_mask)) { + /* We don't know what buttons or axes are supported, don't make up a mapping */ + return NULL; + } + + SDL_strlcpy(mapping_string, "none,*,", sizeof(mapping_string)); + + if (button_mask & (1 << SDL_CONTROLLER_BUTTON_A)) { + SDL_strlcat(mapping_string, "a:b0,", sizeof(mapping_string)); + } + if (button_mask & (1 << SDL_CONTROLLER_BUTTON_B)) { + SDL_strlcat(mapping_string, "b:b1,", sizeof(mapping_string)); + } else if (button_mask & (1 << SDL_CONTROLLER_BUTTON_BACK)) { + /* Use the back button as "B" for easy UI navigation with TV remotes */ + SDL_strlcat(mapping_string, "b:b4,", sizeof(mapping_string)); + button_mask &= ~(1 << SDL_CONTROLLER_BUTTON_BACK); + } + if (button_mask & (1 << SDL_CONTROLLER_BUTTON_X)) { + SDL_strlcat(mapping_string, "x:b2,", sizeof(mapping_string)); + } + if (button_mask & (1 << SDL_CONTROLLER_BUTTON_Y)) { + SDL_strlcat(mapping_string, "y:b3,", sizeof(mapping_string)); + } + if (button_mask & (1 << SDL_CONTROLLER_BUTTON_BACK)) { + SDL_strlcat(mapping_string, "back:b4,", sizeof(mapping_string)); + } + if (button_mask & (1 << SDL_CONTROLLER_BUTTON_GUIDE)) { + /* The guide button generally isn't functional (or acts as a home button) on most Android controllers before Android 11 */ + if (SDL_GetAndroidSDKVersion() >= 30 /* Android 11 */) { + SDL_strlcat(mapping_string, "guide:b5,", sizeof(mapping_string)); + } + } + if (button_mask & (1 << SDL_CONTROLLER_BUTTON_START)) { + SDL_strlcat(mapping_string, "start:b6,", sizeof(mapping_string)); + } + if (button_mask & (1 << SDL_CONTROLLER_BUTTON_LEFTSTICK)) { + SDL_strlcat(mapping_string, "leftstick:b7,", sizeof(mapping_string)); + } + if (button_mask & (1 << SDL_CONTROLLER_BUTTON_RIGHTSTICK)) { + SDL_strlcat(mapping_string, "rightstick:b8,", sizeof(mapping_string)); + } + if (button_mask & (1 << SDL_CONTROLLER_BUTTON_LEFTSHOULDER)) { + SDL_strlcat(mapping_string, "leftshoulder:b9,", sizeof(mapping_string)); + } + if (button_mask & (1 << SDL_CONTROLLER_BUTTON_RIGHTSHOULDER)) { + SDL_strlcat(mapping_string, "rightshoulder:b10,", sizeof(mapping_string)); + } + if (button_mask & (1 << SDL_CONTROLLER_BUTTON_DPAD_UP)) { + SDL_strlcat(mapping_string, "dpup:b11,", sizeof(mapping_string)); + } + if (button_mask & (1 << SDL_CONTROLLER_BUTTON_DPAD_DOWN)) { + SDL_strlcat(mapping_string, "dpdown:b12,", sizeof(mapping_string)); + } + if (button_mask & (1 << SDL_CONTROLLER_BUTTON_DPAD_LEFT)) { + SDL_strlcat(mapping_string, "dpleft:b13,", sizeof(mapping_string)); + } + if (button_mask & (1 << SDL_CONTROLLER_BUTTON_DPAD_RIGHT)) { + SDL_strlcat(mapping_string, "dpright:b14,", sizeof(mapping_string)); + } + if (axis_mask & (1 << SDL_CONTROLLER_AXIS_LEFTX)) { + SDL_strlcat(mapping_string, "leftx:a0,", sizeof(mapping_string)); + } + if (axis_mask & (1 << SDL_CONTROLLER_AXIS_LEFTY)) { + SDL_strlcat(mapping_string, "lefty:a1,", sizeof(mapping_string)); + } + if (axis_mask & (1 << SDL_CONTROLLER_AXIS_RIGHTX)) { + SDL_strlcat(mapping_string, "rightx:a2,", sizeof(mapping_string)); + } + if (axis_mask & (1 << SDL_CONTROLLER_AXIS_RIGHTY)) { + SDL_strlcat(mapping_string, "righty:a3,", sizeof(mapping_string)); + } + if (axis_mask & (1 << SDL_CONTROLLER_AXIS_TRIGGERLEFT)) { + SDL_strlcat(mapping_string, "lefttrigger:a4,", sizeof(mapping_string)); + } + if (axis_mask & (1 << SDL_CONTROLLER_AXIS_TRIGGERRIGHT)) { + SDL_strlcat(mapping_string, "righttrigger:a5,", sizeof(mapping_string)); + } + + return SDL_PrivateAddMappingForGUID(guid, mapping_string, &existing, SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT); +} +#endif /* __ANDROID__ */ + +/* + * Helper function to guess at a mapping for HIDAPI controllers + */ +static ControllerMapping_t *SDL_CreateMappingForHIDAPIController(SDL_JoystickGUID guid) +{ + SDL_bool existing; + char mapping_string[1024]; + Uint16 vendor; + Uint16 product; + + SDL_strlcpy(mapping_string, "none,*,", sizeof(mapping_string)); + + SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL, NULL); + + if ((vendor == USB_VENDOR_NINTENDO && product == USB_PRODUCT_NINTENDO_GAMECUBE_ADAPTER) || + (vendor == USB_VENDOR_DRAGONRISE && + (product == USB_PRODUCT_EVORETRO_GAMECUBE_ADAPTER1 || + product == USB_PRODUCT_EVORETRO_GAMECUBE_ADAPTER2))) { + /* GameCube driver has 12 buttons and 6 axes */ + SDL_strlcat(mapping_string, "a:b0,b:b1,dpdown:b6,dpleft:b4,dpright:b5,dpup:b7,lefttrigger:a4,leftx:a0,lefty:a1~,rightshoulder:b9,righttrigger:a5,rightx:a2,righty:a3~,start:b8,x:b2,y:b3,", sizeof(mapping_string)); + } else if (vendor == USB_VENDOR_NINTENDO && + (guid.data[15] == k_eSwitchDeviceInfoControllerType_HVCLeft || + guid.data[15] == k_eSwitchDeviceInfoControllerType_HVCRight || + guid.data[15] == k_eSwitchDeviceInfoControllerType_NESLeft || + guid.data[15] == k_eSwitchDeviceInfoControllerType_NESRight || + guid.data[15] == k_eSwitchDeviceInfoControllerType_SNES || + guid.data[15] == k_eSwitchDeviceInfoControllerType_N64 || + guid.data[15] == k_eSwitchDeviceInfoControllerType_SEGA_Genesis || + guid.data[15] == k_eWiiExtensionControllerType_None || + guid.data[15] == k_eWiiExtensionControllerType_Nunchuk || + guid.data[15] == k_eSwitchDeviceInfoControllerType_JoyConLeft || + guid.data[15] == k_eSwitchDeviceInfoControllerType_JoyConRight)) { + switch (guid.data[15]) { + case k_eSwitchDeviceInfoControllerType_HVCLeft: + SDL_strlcat(mapping_string, "a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,rightshoulder:b10,start:b6,", sizeof(mapping_string)); + break; + case k_eSwitchDeviceInfoControllerType_HVCRight: + SDL_strlcat(mapping_string, "a:b0,b:b1,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,rightshoulder:b10,", sizeof(mapping_string)); + break; + case k_eSwitchDeviceInfoControllerType_NESLeft: + case k_eSwitchDeviceInfoControllerType_NESRight: + SDL_strlcat(mapping_string, "a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,rightshoulder:b10,start:b6,", sizeof(mapping_string)); + break; + case k_eSwitchDeviceInfoControllerType_SNES: + SDL_strlcat(mapping_string, "a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,lefttrigger:a4,rightshoulder:b10,righttrigger:a5,start:b6,x:b2,y:b3,", sizeof(mapping_string)); + break; + case k_eSwitchDeviceInfoControllerType_N64: + SDL_strlcat(mapping_string, "a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a5,start:b6,x:b2,y:b3,misc1:b15,", sizeof(mapping_string)); + break; + case k_eSwitchDeviceInfoControllerType_SEGA_Genesis: + SDL_strlcat(mapping_string, "a:b0,b:b1,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,rightshoulder:b10,righttrigger:a5,start:b6,x:b2,y:b3,misc1:b15,", sizeof(mapping_string)); + break; + case k_eWiiExtensionControllerType_None: + SDL_strlcat(mapping_string, "a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,start:b6,x:b2,y:b3,", sizeof(mapping_string)); + break; + case k_eWiiExtensionControllerType_Nunchuk: + { + /* FIXME: Should we map this to the left or right side? */ + const SDL_bool map_nunchuck_left_side = SDL_TRUE; + + if (map_nunchuck_left_side) { + SDL_strlcat(mapping_string, "a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,lefttrigger:a4,leftx:a0,lefty:a1,start:b6,x:b2,y:b3,", sizeof(mapping_string)); + } else { + SDL_strlcat(mapping_string, "a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,rightshoulder:b9,righttrigger:a4,rightx:a0,righty:a1,start:b6,x:b2,y:b3,", sizeof(mapping_string)); + } + } break; + default: + if (SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_VERTICAL_JOY_CONS, SDL_FALSE)) { + /* Vertical mode */ + if (guid.data[15] == k_eSwitchDeviceInfoControllerType_JoyConLeft) { + SDL_strlcat(mapping_string, "back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,misc1:b15,paddle2:b17,paddle4:b19,", sizeof(mapping_string)); + } else { + SDL_strlcat(mapping_string, "a:b0,b:b1,guide:b5,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,paddle1:b16,paddle3:b18,", sizeof(mapping_string)); + } + } else { + /* Mini gamepad mode */ + if (guid.data[15] == k_eSwitchDeviceInfoControllerType_JoyConLeft) { + SDL_strlcat(mapping_string, "a:b0,b:b1,guide:b5,leftshoulder:b9,leftstick:b7,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b2,y:b3,paddle2:b17,paddle4:b19,", sizeof(mapping_string)); + } else { + SDL_strlcat(mapping_string, "a:b0,b:b1,guide:b5,leftshoulder:b9,leftstick:b7,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b2,y:b3,paddle1:b16,paddle3:b18,", sizeof(mapping_string)); + } + } + break; + } + } else { + /* All other controllers have the standard set of 19 buttons and 6 axes */ + SDL_strlcat(mapping_string, "a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,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,", sizeof(mapping_string)); + + if (SDL_IsJoystickXboxSeriesX(vendor, product)) { + /* XBox Series X Controllers have a share button under the guide button */ + SDL_strlcat(mapping_string, "misc1:b15,", sizeof(mapping_string)); + } else if (SDL_IsJoystickXboxOneElite(vendor, product)) { + /* XBox One Elite Controllers have 4 back paddle buttons */ + SDL_strlcat(mapping_string, "paddle1:b15,paddle2:b17,paddle3:b16,paddle4:b18,", sizeof(mapping_string)); + } else if (SDL_IsJoystickSteamController(vendor, product)) { + /* Steam controllers have 2 back paddle buttons */ + SDL_strlcat(mapping_string, "paddle1:b16,paddle2:b15,", sizeof(mapping_string)); + } else if (SDL_IsJoystickNintendoSwitchJoyConPair(vendor, product)) { + /* The Nintendo Switch Joy-Con combined controller has a share button and paddles */ + SDL_strlcat(mapping_string, "misc1:b15,paddle1:b16,paddle2:b17,paddle3:b18,paddle4:b19,", sizeof(mapping_string)); + } else { + switch (SDL_GetJoystickGameControllerTypeFromGUID(guid, NULL)) { + case SDL_CONTROLLER_TYPE_PS4: + /* PS4 controllers have an additional touchpad button */ + SDL_strlcat(mapping_string, "touchpad:b15,", sizeof(mapping_string)); + break; + case SDL_CONTROLLER_TYPE_PS5: + /* PS5 controllers have a microphone button and an additional touchpad button */ + SDL_strlcat(mapping_string, "touchpad:b15,misc1:b16,", sizeof(mapping_string)); + /* DualSense Edge controllers have paddles */ + if (SDL_IsJoystickDualSenseEdge(vendor, product)) { + SDL_strlcat(mapping_string, "paddle1:b20,paddle2:b19,paddle3:b18,paddle4:b17,", sizeof(mapping_string)); + } + break; + case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO: + /* Nintendo Switch Pro controllers have a screenshot button */ + SDL_strlcat(mapping_string, "misc1:b15,", sizeof(mapping_string)); + break; + case SDL_CONTROLLER_TYPE_AMAZON_LUNA: + /* Amazon Luna Controller has a mic button under the guide button */ + SDL_strlcat(mapping_string, "misc1:b15,", sizeof(mapping_string)); + break; + case SDL_CONTROLLER_TYPE_GOOGLE_STADIA: + /* The Google Stadia controller has a share button and a Google Assistant button */ + SDL_strlcat(mapping_string, "misc1:b15,", sizeof(mapping_string)); + break; + case SDL_CONTROLLER_TYPE_NVIDIA_SHIELD: + /* The NVIDIA SHIELD controller has a share button between back and start buttons */ + SDL_strlcat(mapping_string, "misc1:b15,", sizeof(mapping_string)); + + if (product == USB_PRODUCT_NVIDIA_SHIELD_CONTROLLER_V103) { + /* The original SHIELD controller has a touchpad as well */ + SDL_strlcat(mapping_string, "touchpad:b16,", sizeof(mapping_string)); + } + break; + default: + if (vendor == 0 && product == 0) { + /* This is a Bluetooth Nintendo Switch Pro controller */ + SDL_strlcat(mapping_string, "misc1:b15,", sizeof(mapping_string)); + } + break; + } + } + } + + return SDL_PrivateAddMappingForGUID(guid, mapping_string, &existing, SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT); +} + +/* + * Helper function to guess at a mapping for RAWINPUT controllers + */ +static ControllerMapping_t *SDL_CreateMappingForRAWINPUTController(SDL_JoystickGUID guid) +{ + SDL_bool existing; + char mapping_string[1024]; + + SDL_strlcpy(mapping_string, "none,*,", sizeof(mapping_string)); + SDL_strlcat(mapping_string, "a:b0,b:b1,x:b2,y:b3,back:b6,guide:b10,start:b7,leftstick:b8,rightstick:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,", sizeof(mapping_string)); + + return SDL_PrivateAddMappingForGUID(guid, mapping_string, &existing, SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT); +} + +/* + * Helper function to guess at a mapping for WGI controllers + */ +static ControllerMapping_t *SDL_CreateMappingForWGIController(SDL_JoystickGUID guid) +{ + SDL_bool existing; + char mapping_string[1024]; + + if (guid.data[15] != SDL_JOYSTICK_TYPE_GAMECONTROLLER) { + return NULL; + } + + SDL_strlcpy(mapping_string, "none,*,", sizeof(mapping_string)); + SDL_strlcat(mapping_string, "a:b0,b:b1,x:b2,y:b3,back:b6,start:b7,leftstick:b8,rightstick:b9,leftshoulder:b4,rightshoulder:b5,dpup:b10,dpdown:b12,dpleft:b13,dpright:b11,leftx:a1,lefty:a0~,rightx:a3,righty:a2~,lefttrigger:a4,righttrigger:a5,", sizeof(mapping_string)); + + return SDL_PrivateAddMappingForGUID(guid, mapping_string, &existing, SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT); +} + +/* + * Helper function to scan the mappings database for a controller with the specified GUID + */ +static ControllerMapping_t *SDL_PrivateMatchControllerMappingForGUID(SDL_JoystickGUID guid, SDL_bool match_version) +{ + ControllerMapping_t *mapping, *best_match = NULL; + Uint16 crc = 0; + + SDL_AssertJoysticksLocked(); + + SDL_GetJoystickGUIDInfo(guid, NULL, NULL, NULL, &crc); + + /* Clear the CRC from the GUID for matching, the mappings never include it in the GUID */ + SDL_SetJoystickGUIDCRC(&guid, 0); + + if (!match_version) { + SDL_SetJoystickGUIDVersion(&guid, 0); + } + + for (mapping = s_pSupportedControllers; mapping; mapping = mapping->next) { + SDL_JoystickGUID mapping_guid; + + if (SDL_memcmp(&mapping->guid, &s_zeroGUID, sizeof(mapping->guid)) == 0) { + continue; + } + + SDL_memcpy(&mapping_guid, &mapping->guid, sizeof(mapping_guid)); + if (!match_version) { + SDL_SetJoystickGUIDVersion(&mapping_guid, 0); + } + + if (SDL_memcmp(&guid, &mapping_guid, sizeof(guid)) == 0) { + const char *crc_string = SDL_strstr(mapping->mapping, SDL_CONTROLLER_CRC_FIELD); + if (crc_string) { + Uint16 mapping_crc = (Uint16)SDL_strtol(crc_string + SDL_CONTROLLER_CRC_FIELD_SIZE, NULL, 16); + + if (mapping_crc != crc) { + /* This mapping specified a CRC and they don't match */ + continue; + } + + /* An exact match, including CRC */ + return mapping; + } + + + if (!best_match) { + best_match = mapping; + } + } + } + return best_match; +} + +/* + * Helper function to scan the mappings database for a controller with the specified GUID + */ +static ControllerMapping_t *SDL_PrivateGetControllerMappingForGUID(SDL_JoystickGUID guid, SDL_bool adding_mapping) +{ + ControllerMapping_t *mapping; + + mapping = SDL_PrivateMatchControllerMappingForGUID(guid, SDL_TRUE); + if (mapping) { + return mapping; + } + + if (adding_mapping) { + /* We didn't find an existing mapping */ + return NULL; + } + + /* Try harder to get the best match, or create a mapping */ + + if (SDL_JoystickGUIDUsesVersion(guid)) { + /* Try again, ignoring the version */ + mapping = SDL_PrivateMatchControllerMappingForGUID(guid, SDL_FALSE); + if (mapping) { + return mapping; + } + } + +#ifdef SDL_JOYSTICK_XINPUT + if (SDL_IsJoystickXInput(guid)) { + /* This is an XInput device */ + return s_pXInputMapping; + } +#endif + if (SDL_IsJoystickHIDAPI(guid)) { + mapping = SDL_CreateMappingForHIDAPIController(guid); + } else if (SDL_IsJoystickRAWINPUT(guid)) { + mapping = SDL_CreateMappingForRAWINPUTController(guid); + } else if (SDL_IsJoystickWGI(guid)) { + mapping = SDL_CreateMappingForWGIController(guid); + } else if (SDL_IsJoystickVirtual(guid)) { + /* We'll pick up a robust mapping in VIRTUAL_JoystickGetGamepadMapping */ +#ifdef __ANDROID__ + } else { + mapping = SDL_CreateMappingForAndroidController(guid); +#endif + } + return mapping; +} + +static const char *map_StringForGameControllerType[] = { + "unknown", + "xbox360", + "xboxone", + "ps3", + "ps4", + "switchpro", + "virtual", + "ps5", + "amazonluna", + "googlestadia", + "nvidiashield", + "joyconleft", + "joyconright", + "joyconpair" +}; +SDL_COMPILE_TIME_ASSERT(map_StringForGameControllerType, SDL_arraysize(map_StringForGameControllerType) == SDL_CONTROLLER_TYPE_MAX); + +/* + * convert a string to its enum equivalent + */ +SDL_GameControllerType SDL_GetGameControllerTypeFromString(const char *str) +{ + int i; + + if (!str || str[0] == '\0') { + return SDL_CONTROLLER_TYPE_UNKNOWN; + } + + if (*str == '+' || *str == '-') { + ++str; + } + + for (i = 0; i < SDL_arraysize(map_StringForGameControllerType); ++i) { + if (SDL_strcasecmp(str, map_StringForGameControllerType[i]) == 0) { + return (SDL_GameControllerType)i; + } + } + return SDL_CONTROLLER_TYPE_UNKNOWN; +} + +static const char *map_StringForControllerAxis[] = { + "leftx", + "lefty", + "rightx", + "righty", + "lefttrigger", + "righttrigger", + NULL +}; + +/* + * convert a string to its enum equivalent + */ +SDL_GameControllerAxis SDL_GameControllerGetAxisFromString(const char *str) +{ + int entry; + + if (str == NULL || str[0] == '\0') { + return SDL_CONTROLLER_AXIS_INVALID; + } + + if (*str == '+' || *str == '-') { + ++str; + } + + for (entry = 0; map_StringForControllerAxis[entry]; ++entry) { + if (SDL_strcasecmp(str, map_StringForControllerAxis[entry]) == 0) { + return (SDL_GameControllerAxis)entry; + } + } + return SDL_CONTROLLER_AXIS_INVALID; +} + +/* + * convert an enum to its string equivalent + */ +const char *SDL_GameControllerGetStringForAxis(SDL_GameControllerAxis axis) +{ + if (axis > SDL_CONTROLLER_AXIS_INVALID && axis < SDL_CONTROLLER_AXIS_MAX) { + return map_StringForControllerAxis[axis]; + } + return NULL; +} + +static const char *map_StringForControllerButton[] = { + "a", + "b", + "x", + "y", + "back", + "guide", + "start", + "leftstick", + "rightstick", + "leftshoulder", + "rightshoulder", + "dpup", + "dpdown", + "dpleft", + "dpright", + "misc1", + "paddle1", + "paddle2", + "paddle3", + "paddle4", + "touchpad", + NULL +}; + +/* + * convert a string to its enum equivalent + */ +SDL_GameControllerButton SDL_GameControllerGetButtonFromString(const char *str) +{ + int entry; + if (str == NULL || str[0] == '\0') { + return SDL_CONTROLLER_BUTTON_INVALID; + } + + for (entry = 0; map_StringForControllerButton[entry]; ++entry) { + if (SDL_strcasecmp(str, map_StringForControllerButton[entry]) == 0) { + return (SDL_GameControllerButton)entry; + } + } + return SDL_CONTROLLER_BUTTON_INVALID; +} + +/* + * convert an enum to its string equivalent + */ +const char *SDL_GameControllerGetStringForButton(SDL_GameControllerButton button) +{ + if (button > SDL_CONTROLLER_BUTTON_INVALID && button < SDL_CONTROLLER_BUTTON_MAX) { + return map_StringForControllerButton[button]; + } + return NULL; +} + +/* + * given a controller button name and a joystick name update our mapping structure with it + */ +static void SDL_PrivateGameControllerParseElement(SDL_GameController *gamecontroller, const char *szGameButton, const char *szJoystickButton) +{ + SDL_ExtendedGameControllerBind bind; + SDL_GameControllerButton button; + SDL_GameControllerAxis axis; + SDL_bool invert_input = SDL_FALSE; + char half_axis_input = 0; + char half_axis_output = 0; + + SDL_AssertJoysticksLocked(); + + if (*szGameButton == '+' || *szGameButton == '-') { + half_axis_output = *szGameButton++; + } + + axis = SDL_GameControllerGetAxisFromString(szGameButton); + button = SDL_GameControllerGetButtonFromString(szGameButton); + if (axis != SDL_CONTROLLER_AXIS_INVALID) { + bind.outputType = SDL_CONTROLLER_BINDTYPE_AXIS; + bind.output.axis.axis = axis; + if (axis == SDL_CONTROLLER_AXIS_TRIGGERLEFT || axis == SDL_CONTROLLER_AXIS_TRIGGERRIGHT) { + bind.output.axis.axis_min = 0; + bind.output.axis.axis_max = SDL_JOYSTICK_AXIS_MAX; + } else { + if (half_axis_output == '+') { + bind.output.axis.axis_min = 0; + bind.output.axis.axis_max = SDL_JOYSTICK_AXIS_MAX; + } else if (half_axis_output == '-') { + bind.output.axis.axis_min = 0; + bind.output.axis.axis_max = SDL_JOYSTICK_AXIS_MIN; + } else { + bind.output.axis.axis_min = SDL_JOYSTICK_AXIS_MIN; + bind.output.axis.axis_max = SDL_JOYSTICK_AXIS_MAX; + } + } + } else if (button != SDL_CONTROLLER_BUTTON_INVALID) { + bind.outputType = SDL_CONTROLLER_BINDTYPE_BUTTON; + bind.output.button = button; + } else { + SDL_SetError("Unexpected controller element %s", szGameButton); + return; + } + + if (*szJoystickButton == '+' || *szJoystickButton == '-') { + half_axis_input = *szJoystickButton++; + } + if (szJoystickButton[SDL_strlen(szJoystickButton) - 1] == '~') { + invert_input = SDL_TRUE; + } + + if (szJoystickButton[0] == 'a' && SDL_isdigit((unsigned char)szJoystickButton[1])) { + bind.inputType = SDL_CONTROLLER_BINDTYPE_AXIS; + bind.input.axis.axis = SDL_atoi(&szJoystickButton[1]); + if (half_axis_input == '+') { + bind.input.axis.axis_min = 0; + bind.input.axis.axis_max = SDL_JOYSTICK_AXIS_MAX; + } else if (half_axis_input == '-') { + bind.input.axis.axis_min = 0; + bind.input.axis.axis_max = SDL_JOYSTICK_AXIS_MIN; + } else { + bind.input.axis.axis_min = SDL_JOYSTICK_AXIS_MIN; + bind.input.axis.axis_max = SDL_JOYSTICK_AXIS_MAX; + } + if (invert_input) { + int tmp = bind.input.axis.axis_min; + bind.input.axis.axis_min = bind.input.axis.axis_max; + bind.input.axis.axis_max = tmp; + } + } else if (szJoystickButton[0] == 'b' && SDL_isdigit((unsigned char)szJoystickButton[1])) { + bind.inputType = SDL_CONTROLLER_BINDTYPE_BUTTON; + bind.input.button = SDL_atoi(&szJoystickButton[1]); + } else if (szJoystickButton[0] == 'h' && SDL_isdigit((unsigned char)szJoystickButton[1]) && + szJoystickButton[2] == '.' && SDL_isdigit((unsigned char)szJoystickButton[3])) { + int hat = SDL_atoi(&szJoystickButton[1]); + int mask = SDL_atoi(&szJoystickButton[3]); + bind.inputType = SDL_CONTROLLER_BINDTYPE_HAT; + bind.input.hat.hat = hat; + bind.input.hat.hat_mask = mask; + } else { + SDL_SetError("Unexpected joystick element: %s", szJoystickButton); + return; + } + + ++gamecontroller->num_bindings; + gamecontroller->bindings = (SDL_ExtendedGameControllerBind *)SDL_realloc(gamecontroller->bindings, gamecontroller->num_bindings * sizeof(*gamecontroller->bindings)); + if (!gamecontroller->bindings) { + gamecontroller->num_bindings = 0; + SDL_OutOfMemory(); + return; + } + gamecontroller->bindings[gamecontroller->num_bindings - 1] = bind; +} + +/* + * given a controller mapping string update our mapping object + */ +static void SDL_PrivateGameControllerParseControllerConfigString(SDL_GameController *gamecontroller, const char *pchString) +{ + char szGameButton[20]; + char szJoystickButton[20]; + SDL_bool bGameButton = SDL_TRUE; + int i = 0; + const char *pchPos = pchString; + + SDL_zeroa(szGameButton); + SDL_zeroa(szJoystickButton); + + while (pchPos && *pchPos) { + if (*pchPos == ':') { + i = 0; + bGameButton = SDL_FALSE; + } else if (*pchPos == ' ') { + + } else if (*pchPos == ',') { + i = 0; + bGameButton = SDL_TRUE; + SDL_PrivateGameControllerParseElement(gamecontroller, szGameButton, szJoystickButton); + SDL_zeroa(szGameButton); + SDL_zeroa(szJoystickButton); + + } else if (bGameButton) { + if (i >= sizeof(szGameButton)) { + szGameButton[sizeof(szGameButton) - 1] = '\0'; + SDL_SetError("Button name too large: %s", szGameButton); + return; + } + szGameButton[i] = *pchPos; + i++; + } else { + if (i >= sizeof(szJoystickButton)) { + szJoystickButton[sizeof(szJoystickButton) - 1] = '\0'; + SDL_SetError("Joystick button name too large: %s", szJoystickButton); + return; + } + szJoystickButton[i] = *pchPos; + i++; + } + pchPos++; + } + + /* No more values if the string was terminated by a comma. Don't report an error. */ + if (szGameButton[0] != '\0' || szJoystickButton[0] != '\0') { + SDL_PrivateGameControllerParseElement(gamecontroller, szGameButton, szJoystickButton); + } +} + +static void SDL_UpdateGameControllerType(SDL_GameController *gamecontroller) +{ + char *type_string, *comma; + + SDL_AssertJoysticksLocked(); + + gamecontroller->type = SDL_CONTROLLER_TYPE_UNKNOWN; + + type_string = SDL_strstr(gamecontroller->mapping->mapping, SDL_CONTROLLER_TYPE_FIELD); + if (type_string) { + type_string += SDL_CONTROLLER_TYPE_FIELD_SIZE; + comma = SDL_strchr(type_string, ','); + if (comma) { + *comma = '\0'; + gamecontroller->type = SDL_GetGameControllerTypeFromString(type_string); + *comma = ','; + } else { + gamecontroller->type = SDL_GetGameControllerTypeFromString(type_string); + } + } + if (gamecontroller->type == SDL_CONTROLLER_TYPE_UNKNOWN) { + gamecontroller->type = SDL_GetJoystickGameControllerTypeFromGUID(SDL_JoystickGetGUID(gamecontroller->joystick), SDL_JoystickName(gamecontroller->joystick)); + } +} + +/* + * Make a new button mapping struct + */ +static void SDL_PrivateLoadButtonMapping(SDL_GameController *gamecontroller, ControllerMapping_t *pControllerMapping) +{ + int i; + + SDL_AssertJoysticksLocked(); + + gamecontroller->name = pControllerMapping->name; + gamecontroller->num_bindings = 0; + gamecontroller->mapping = pControllerMapping; + if (gamecontroller->joystick->naxes != 0 && gamecontroller->last_match_axis) { + SDL_memset(gamecontroller->last_match_axis, 0, gamecontroller->joystick->naxes * sizeof(*gamecontroller->last_match_axis)); + } + + SDL_PrivateGameControllerParseControllerConfigString(gamecontroller, pControllerMapping->mapping); + + SDL_UpdateGameControllerType(gamecontroller); + + /* Set the zero point for triggers */ + for (i = 0; i < gamecontroller->num_bindings; ++i) { + SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i]; + if (binding->inputType == SDL_CONTROLLER_BINDTYPE_AXIS && + binding->outputType == SDL_CONTROLLER_BINDTYPE_AXIS && + (binding->output.axis.axis == SDL_CONTROLLER_AXIS_TRIGGERLEFT || + binding->output.axis.axis == SDL_CONTROLLER_AXIS_TRIGGERRIGHT)) { + if (binding->input.axis.axis < gamecontroller->joystick->naxes) { + gamecontroller->joystick->axes[binding->input.axis.axis].value = + gamecontroller->joystick->axes[binding->input.axis.axis].zero = (Sint16)binding->input.axis.axis_min; + } + } + } +} + +/* + * grab the guid string from a mapping string + */ +static char *SDL_PrivateGetControllerGUIDFromMappingString(const char *pMapping) +{ + const char *pFirstComma = SDL_strchr(pMapping, ','); + if (pFirstComma) { + char *pchGUID = SDL_malloc(pFirstComma - pMapping + 1); + if (!pchGUID) { + SDL_OutOfMemory(); + return NULL; + } + SDL_memcpy(pchGUID, pMapping, pFirstComma - pMapping); + pchGUID[pFirstComma - pMapping] = '\0'; + + /* Convert old style GUIDs to the new style in 2.0.5 */ +#if defined(__WIN32__) || defined(__WINGDK__) + if (SDL_strlen(pchGUID) == 32 && + SDL_memcmp(&pchGUID[20], "504944564944", 12) == 0) { + SDL_memcpy(&pchGUID[20], "000000000000", 12); + SDL_memcpy(&pchGUID[16], &pchGUID[4], 4); + SDL_memcpy(&pchGUID[8], &pchGUID[0], 4); + SDL_memcpy(&pchGUID[0], "03000000", 8); + } +#elif defined(__MACOSX__) + if (SDL_strlen(pchGUID) == 32 && + SDL_memcmp(&pchGUID[4], "000000000000", 12) == 0 && + SDL_memcmp(&pchGUID[20], "000000000000", 12) == 0) { + SDL_memcpy(&pchGUID[20], "000000000000", 12); + SDL_memcpy(&pchGUID[8], &pchGUID[0], 4); + SDL_memcpy(&pchGUID[0], "03000000", 8); + } +#endif + return pchGUID; + } + return NULL; +} + +/* + * grab the name string from a mapping string + */ +static char *SDL_PrivateGetControllerNameFromMappingString(const char *pMapping) +{ + const char *pFirstComma, *pSecondComma; + char *pchName; + + pFirstComma = SDL_strchr(pMapping, ','); + if (!pFirstComma) { + return NULL; + } + + pSecondComma = SDL_strchr(pFirstComma + 1, ','); + if (!pSecondComma) { + return NULL; + } + + pchName = SDL_malloc(pSecondComma - pFirstComma); + if (!pchName) { + SDL_OutOfMemory(); + return NULL; + } + SDL_memcpy(pchName, pFirstComma + 1, pSecondComma - pFirstComma); + pchName[pSecondComma - pFirstComma - 1] = 0; + return pchName; +} + +/* + * grab the button mapping string from a mapping string + */ +static char *SDL_PrivateGetControllerMappingFromMappingString(const char *pMapping) +{ + const char *pFirstComma, *pSecondComma; + + pFirstComma = SDL_strchr(pMapping, ','); + if (!pFirstComma) { + return NULL; + } + + pSecondComma = SDL_strchr(pFirstComma + 1, ','); + if (!pSecondComma) { + return NULL; + } + + return SDL_strdup(pSecondComma + 1); /* mapping is everything after the 3rd comma */ +} + +/* + * Helper function to refresh a mapping + */ +static void SDL_PrivateGameControllerRefreshMapping(ControllerMapping_t *pControllerMapping) +{ + SDL_GameController *controller; + + SDL_AssertJoysticksLocked(); + + for (controller = SDL_gamecontrollers; controller; controller = controller->next) { + if (controller->mapping == pControllerMapping) { + SDL_PrivateLoadButtonMapping(controller, pControllerMapping); + + { + SDL_Event event; + event.type = SDL_CONTROLLERDEVICEREMAPPED; + event.cdevice.which = controller->joystick->instance_id; + SDL_PushEvent(&event); + } + } + } +} + +/* + * Helper function to add a mapping for a guid + */ +static ControllerMapping_t *SDL_PrivateAddMappingForGUID(SDL_JoystickGUID jGUID, const char *mappingString, SDL_bool *existing, SDL_ControllerMappingPriority priority) +{ + char *pchName; + char *pchMapping; + ControllerMapping_t *pControllerMapping; + Uint16 crc; + + SDL_AssertJoysticksLocked(); + + pchName = SDL_PrivateGetControllerNameFromMappingString(mappingString); + if (!pchName) { + SDL_SetError("Couldn't parse name from %s", mappingString); + return NULL; + } + + pchMapping = SDL_PrivateGetControllerMappingFromMappingString(mappingString); + if (!pchMapping) { + SDL_free(pchName); + SDL_SetError("Couldn't parse %s", mappingString); + return NULL; + } + + /* Fix up the GUID and the mapping with the CRC, if needed */ + SDL_GetJoystickGUIDInfo(jGUID, NULL, NULL, NULL, &crc); + if (crc) { + /* Make sure the mapping has the CRC */ + char *new_mapping; + char *crc_end = ""; + char *crc_string = SDL_strstr(pchMapping, SDL_CONTROLLER_CRC_FIELD); + if (crc_string) { + crc_end = SDL_strchr(crc_string, ','); + if (crc_end) { + ++crc_end; + } else { + crc_end = ""; + } + *crc_string = '\0'; + } + + if (SDL_asprintf(&new_mapping, "%s%s%.4x,%s", pchMapping, SDL_CONTROLLER_CRC_FIELD, crc, crc_end) >= 0) { + SDL_free(pchMapping); + pchMapping = new_mapping; + } + } else { + /* Make sure the GUID has the CRC, for matching purposes */ + char *crc_string = SDL_strstr(pchMapping, SDL_CONTROLLER_CRC_FIELD); + if (crc_string) { + crc = (Uint16)SDL_strtol(crc_string + SDL_CONTROLLER_CRC_FIELD_SIZE, NULL, 16); + if (crc) { + SDL_SetJoystickGUIDCRC(&jGUID, crc); + } + } + } + + pControllerMapping = SDL_PrivateGetControllerMappingForGUID(jGUID, SDL_TRUE); + if (pControllerMapping) { + /* Only overwrite the mapping if the priority is the same or higher. */ + if (pControllerMapping->priority <= priority) { + /* Update existing mapping */ + SDL_free(pControllerMapping->name); + pControllerMapping->name = pchName; + SDL_free(pControllerMapping->mapping); + pControllerMapping->mapping = pchMapping; + pControllerMapping->priority = priority; + /* refresh open controllers */ + SDL_PrivateGameControllerRefreshMapping(pControllerMapping); + } else { + SDL_free(pchName); + SDL_free(pchMapping); + } + *existing = SDL_TRUE; + } else { + pControllerMapping = SDL_malloc(sizeof(*pControllerMapping)); + if (!pControllerMapping) { + SDL_free(pchName); + SDL_free(pchMapping); + SDL_OutOfMemory(); + return NULL; + } + /* Clear the CRC, we've already added it to the mapping */ + if (crc) { + SDL_SetJoystickGUIDCRC(&jGUID, 0); + } + pControllerMapping->guid = jGUID; + pControllerMapping->name = pchName; + pControllerMapping->mapping = pchMapping; + pControllerMapping->next = NULL; + pControllerMapping->priority = priority; + + if (s_pSupportedControllers) { + /* Add the mapping to the end of the list */ + ControllerMapping_t *pCurrMapping, *pPrevMapping; + + for (pPrevMapping = s_pSupportedControllers, pCurrMapping = pPrevMapping->next; + pCurrMapping; + pPrevMapping = pCurrMapping, pCurrMapping = pCurrMapping->next) { + /* continue; */ + } + pPrevMapping->next = pControllerMapping; + } else { + s_pSupportedControllers = pControllerMapping; + } + *existing = SDL_FALSE; + } + return pControllerMapping; +} + +/* + * Helper function to determine pre-calculated offset to certain joystick mappings + */ +static ControllerMapping_t *SDL_PrivateGetControllerMappingForNameAndGUID(const char *name, SDL_JoystickGUID guid) +{ + ControllerMapping_t *mapping; + + SDL_AssertJoysticksLocked(); + + mapping = SDL_PrivateGetControllerMappingForGUID(guid, SDL_FALSE); +#ifdef __LINUX__ + if (!mapping && name) { + if (SDL_strstr(name, "Xbox 360 Wireless Receiver")) { + /* The Linux driver xpad.c maps the wireless dpad to buttons */ + SDL_bool existing; + mapping = SDL_PrivateAddMappingForGUID(guid, + "none,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,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,", + &existing, SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT); + } + } +#endif /* __LINUX__ */ + + return mapping; +} + +static void SDL_PrivateAppendToMappingString(char *mapping_string, + size_t mapping_string_len, + const char *input_name, + SDL_InputMapping *mapping) +{ + char buffer[16]; + if (mapping->kind == EMappingKind_None) { + return; + } + + SDL_strlcat(mapping_string, input_name, mapping_string_len); + SDL_strlcat(mapping_string, ":", mapping_string_len); + switch (mapping->kind) { + case EMappingKind_Button: + (void)SDL_snprintf(buffer, sizeof(buffer), "b%i", mapping->target); + break; + case EMappingKind_Axis: + (void)SDL_snprintf(buffer, sizeof(buffer), "%sa%i%s", + mapping->half_axis_positive ? "+" : + mapping->half_axis_negative ? "-" : "", + mapping->target, + mapping->axis_reversed ? "~" : ""); + break; + case EMappingKind_Hat: + (void)SDL_snprintf(buffer, sizeof(buffer), "h%i.%i", mapping->target >> 4, mapping->target & 0x0F); + break; + default: + SDL_assert(SDL_FALSE); + } + + SDL_strlcat(mapping_string, buffer, mapping_string_len); + SDL_strlcat(mapping_string, ",", mapping_string_len); +} + +static ControllerMapping_t *SDL_PrivateGenerateAutomaticControllerMapping(const char *name, + SDL_JoystickGUID guid, + SDL_GamepadMapping *raw_map) +{ + SDL_bool existing; + char name_string[128]; + char mapping[1024]; + + /* Remove any commas in the name */ + SDL_strlcpy(name_string, name, sizeof(name_string)); + { + char *spot; + for (spot = name_string; *spot; ++spot) { + if (*spot == ',') { + *spot = ' '; + } + } + } + (void)SDL_snprintf(mapping, sizeof(mapping), "none,%s,", name_string); + SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "a", &raw_map->a); + SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "b", &raw_map->b); + SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "x", &raw_map->x); + SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "y", &raw_map->y); + SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "back", &raw_map->back); + SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "guide", &raw_map->guide); + SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "start", &raw_map->start); + SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "leftstick", &raw_map->leftstick); + SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "rightstick", &raw_map->rightstick); + SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "leftshoulder", &raw_map->leftshoulder); + SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "rightshoulder", &raw_map->rightshoulder); + SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "dpup", &raw_map->dpup); + SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "dpdown", &raw_map->dpdown); + SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "dpleft", &raw_map->dpleft); + SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "dpright", &raw_map->dpright); + SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "misc1", &raw_map->misc1); + SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "paddle1", &raw_map->paddle1); + SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "paddle2", &raw_map->paddle2); + SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "paddle3", &raw_map->paddle3); + SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "paddle4", &raw_map->paddle4); + SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "leftx", &raw_map->leftx); + SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "lefty", &raw_map->lefty); + SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "rightx", &raw_map->rightx); + SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "righty", &raw_map->righty); + SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "lefttrigger", &raw_map->lefttrigger); + SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "righttrigger", &raw_map->righttrigger); + SDL_PrivateAppendToMappingString(mapping, sizeof(mapping), "touchpad", &raw_map->touchpad); + + return SDL_PrivateAddMappingForGUID(guid, mapping, &existing, SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT); +} + +static ControllerMapping_t *SDL_PrivateGetControllerMapping(int device_index) +{ + const char *name; + SDL_JoystickGUID guid; + ControllerMapping_t *mapping; + + SDL_AssertJoysticksLocked(); + + if ((device_index < 0) || (device_index >= SDL_NumJoysticks())) { + SDL_SetError("There are %d joysticks available", SDL_NumJoysticks()); + return NULL; + } + + name = SDL_JoystickNameForIndex(device_index); + guid = SDL_JoystickGetDeviceGUID(device_index); + mapping = SDL_PrivateGetControllerMappingForNameAndGUID(name, guid); + if (!mapping) { + SDL_GamepadMapping raw_map; + + SDL_zero(raw_map); + if (SDL_PrivateJoystickGetAutoGamepadMapping(device_index, &raw_map)) { + mapping = SDL_PrivateGenerateAutomaticControllerMapping(name, guid, &raw_map); + } + } + + if (!mapping) { + mapping = s_pDefaultMapping; + } + return mapping; +} + +/* + * Add or update an entry into the Mappings Database + */ +int SDL_GameControllerAddMappingsFromRW(SDL_RWops *rw, int freerw) +{ + const char *platform = SDL_GetPlatform(); + int controllers = 0; + char *buf, *line, *line_end, *tmp, *comma, line_platform[64]; + size_t db_size, platform_len; + + if (!rw) { + return SDL_SetError("Invalid RWops"); + } + db_size = (size_t)SDL_RWsize(rw); + + buf = (char *)SDL_malloc(db_size + 1); + if (!buf) { + if (freerw) { + SDL_RWclose(rw); + } + return SDL_SetError("Could not allocate space to read DB into memory"); + } + + if (SDL_RWread(rw, buf, db_size, 1) != 1) { + if (freerw) { + SDL_RWclose(rw); + } + SDL_free(buf); + return SDL_SetError("Could not read DB"); + } + + if (freerw) { + SDL_RWclose(rw); + } + + buf[db_size] = '\0'; + line = buf; + + while (line < buf + db_size) { + line_end = SDL_strchr(line, '\n'); + if (line_end) { + *line_end = '\0'; + } else { + line_end = buf + db_size; + } + + /* Extract and verify the platform */ + tmp = SDL_strstr(line, SDL_CONTROLLER_PLATFORM_FIELD); + if (tmp) { + tmp += SDL_CONTROLLER_PLATFORM_FIELD_SIZE; + comma = SDL_strchr(tmp, ','); + if (comma) { + platform_len = comma - tmp + 1; + if (platform_len + 1 < SDL_arraysize(line_platform)) { + SDL_strlcpy(line_platform, tmp, platform_len); + if (SDL_strncasecmp(line_platform, platform, platform_len) == 0 && + SDL_GameControllerAddMapping(line) > 0) { + controllers++; + } + } + } + } + + line = line_end + 1; + } + + SDL_free(buf); + return controllers; +} + +/* + * Add or update an entry into the Mappings Database with a priority + */ +static int SDL_PrivateGameControllerAddMapping(const char *mappingString, SDL_ControllerMappingPriority priority) +{ + char *pchGUID; + SDL_JoystickGUID jGUID; + SDL_bool is_default_mapping = SDL_FALSE; + SDL_bool is_xinput_mapping = SDL_FALSE; + SDL_bool existing = SDL_FALSE; + ControllerMapping_t *pControllerMapping; + + SDL_AssertJoysticksLocked(); + + if (!mappingString) { + return SDL_InvalidParamError("mappingString"); + } + + { /* Extract and verify the hint field */ + const char *tmp; + + tmp = SDL_strstr(mappingString, SDL_CONTROLLER_HINT_FIELD); + if (tmp) { + SDL_bool default_value, value, negate; + int len; + char hint[128]; + + tmp += SDL_CONTROLLER_HINT_FIELD_SIZE; + + if (*tmp == '!') { + negate = SDL_TRUE; + ++tmp; + } else { + negate = SDL_FALSE; + } + + len = 0; + while (*tmp && *tmp != ',' && *tmp != ':' && len < (sizeof(hint) - 1)) { + hint[len++] = *tmp++; + } + hint[len] = '\0'; + + if (tmp[0] == ':' && tmp[1] == '=') { + tmp += 2; + default_value = SDL_atoi(tmp); + } else { + default_value = SDL_FALSE; + } + + value = SDL_GetHintBoolean(hint, default_value); + if (negate) { + value = !value; + } + if (!value) { + return 0; + } + } + } + +#ifdef ANDROID + { /* Extract and verify the SDK version */ + const char *tmp; + + tmp = SDL_strstr(mappingString, SDL_CONTROLLER_SDKGE_FIELD); + if (tmp) { + tmp += SDL_CONTROLLER_SDKGE_FIELD_SIZE; + if (!(SDL_GetAndroidSDKVersion() >= SDL_atoi(tmp))) { + return SDL_SetError("SDK version %d < minimum version %d", SDL_GetAndroidSDKVersion(), SDL_atoi(tmp)); + } + } + tmp = SDL_strstr(mappingString, SDL_CONTROLLER_SDKLE_FIELD); + if (tmp) { + tmp += SDL_CONTROLLER_SDKLE_FIELD_SIZE; + if (!(SDL_GetAndroidSDKVersion() <= SDL_atoi(tmp))) { + return SDL_SetError("SDK version %d > maximum version %d", SDL_GetAndroidSDKVersion(), SDL_atoi(tmp)); + } + } + } +#endif + + pchGUID = SDL_PrivateGetControllerGUIDFromMappingString(mappingString); + if (!pchGUID) { + return SDL_SetError("Couldn't parse GUID from %s", mappingString); + } + if (!SDL_strcasecmp(pchGUID, "default")) { + is_default_mapping = SDL_TRUE; + } else if (!SDL_strcasecmp(pchGUID, "xinput")) { + is_xinput_mapping = SDL_TRUE; + } + jGUID = SDL_JoystickGetGUIDFromString(pchGUID); + SDL_free(pchGUID); + + pControllerMapping = SDL_PrivateAddMappingForGUID(jGUID, mappingString, &existing, priority); + if (!pControllerMapping) { + return -1; + } + + if (existing) { + return 0; + } else { + if (is_default_mapping) { + s_pDefaultMapping = pControllerMapping; + } else if (is_xinput_mapping) { + s_pXInputMapping = pControllerMapping; + } + return 1; + } +} + +/* + * Add or update an entry into the Mappings Database + */ +int SDL_GameControllerAddMapping(const char *mappingString) +{ + int retval; + + SDL_LockJoysticks(); + { + retval = SDL_PrivateGameControllerAddMapping(mappingString, SDL_CONTROLLER_MAPPING_PRIORITY_API); + } + SDL_UnlockJoysticks(); + + return retval; +} + +/* + * Get the number of mappings installed + */ +int SDL_GameControllerNumMappings(void) +{ + int num_mappings = 0; + + SDL_LockJoysticks(); + { + ControllerMapping_t *mapping; + + for (mapping = s_pSupportedControllers; mapping; mapping = mapping->next) { + if (SDL_memcmp(&mapping->guid, &s_zeroGUID, sizeof(mapping->guid)) == 0) { + continue; + } + ++num_mappings; + } + } + SDL_UnlockJoysticks(); + + return num_mappings; +} + +/* + * Create a mapping string for a mapping + */ +static char *CreateMappingString(ControllerMapping_t *mapping, SDL_JoystickGUID guid) +{ + char *pMappingString, *pPlatformString; + char pchGUID[33]; + size_t needed; + const char *platform = SDL_GetPlatform(); + + SDL_AssertJoysticksLocked(); + + SDL_JoystickGetGUIDString(guid, pchGUID, sizeof(pchGUID)); + + /* allocate enough memory for GUID + ',' + name + ',' + mapping + \0 */ + needed = SDL_strlen(pchGUID) + 1 + SDL_strlen(mapping->name) + 1 + SDL_strlen(mapping->mapping) + 1; + + if (!SDL_strstr(mapping->mapping, SDL_CONTROLLER_PLATFORM_FIELD)) { + /* add memory for ',' + platform:PLATFORM */ + if (mapping->mapping[SDL_strlen(mapping->mapping) - 1] != ',') { + needed += 1; + } + needed += SDL_CONTROLLER_PLATFORM_FIELD_SIZE + SDL_strlen(platform); + } + + pMappingString = SDL_malloc(needed); + if (!pMappingString) { + SDL_OutOfMemory(); + return NULL; + } + + (void)SDL_snprintf(pMappingString, needed, "%s,%s,%s", pchGUID, mapping->name, mapping->mapping); + + if (!SDL_strstr(mapping->mapping, SDL_CONTROLLER_PLATFORM_FIELD)) { + if (mapping->mapping[SDL_strlen(mapping->mapping) - 1] != ',') { + SDL_strlcat(pMappingString, ",", needed); + } + SDL_strlcat(pMappingString, SDL_CONTROLLER_PLATFORM_FIELD, needed); + SDL_strlcat(pMappingString, platform, needed); + } + + /* Make sure multiple platform strings haven't made their way into the mapping */ + pPlatformString = SDL_strstr(pMappingString, SDL_CONTROLLER_PLATFORM_FIELD); + if (pPlatformString) { + pPlatformString = SDL_strstr(pPlatformString + 1, SDL_CONTROLLER_PLATFORM_FIELD); + if (pPlatformString) { + *pPlatformString = '\0'; + } + } + return pMappingString; +} + +/* + * Get the mapping at a particular index. + */ +char *SDL_GameControllerMappingForIndex(int mapping_index) +{ + char *retval = NULL; + + SDL_LockJoysticks(); + { + ControllerMapping_t *mapping; + + for (mapping = s_pSupportedControllers; mapping; mapping = mapping->next) { + if (SDL_memcmp(&mapping->guid, &s_zeroGUID, sizeof(mapping->guid)) == 0) { + continue; + } + if (mapping_index == 0) { + retval = CreateMappingString(mapping, mapping->guid); + break; + } + --mapping_index; + } + } + SDL_UnlockJoysticks(); + + if (!retval) { + SDL_SetError("Mapping not available"); + } + return retval; +} + +/* + * Get the mapping string for this GUID + */ +char *SDL_GameControllerMappingForGUID(SDL_JoystickGUID guid) +{ + char *retval; + + SDL_LockJoysticks(); + { + ControllerMapping_t *mapping = SDL_PrivateGetControllerMappingForGUID(guid, SDL_FALSE); + if (mapping) { + retval = CreateMappingString(mapping, guid); + } else { + SDL_SetError("Mapping not available"); + retval = NULL; + } + } + SDL_UnlockJoysticks(); + + return retval; +} + +/* + * Get the mapping string for this device + */ +char *SDL_GameControllerMapping(SDL_GameController *gamecontroller) +{ + char *retval; + + SDL_LockJoysticks(); + { + CHECK_GAMECONTROLLER_MAGIC(gamecontroller, NULL); + + retval = CreateMappingString(gamecontroller->mapping, gamecontroller->joystick->guid); + } + SDL_UnlockJoysticks(); + + return retval; +} + +static void SDL_GameControllerLoadHints(void) +{ + const char *hint = SDL_GetHint(SDL_HINT_GAMECONTROLLERCONFIG); + if (hint && hint[0]) { + size_t nchHints = SDL_strlen(hint); + char *pUserMappings = SDL_malloc(nchHints + 1); + char *pTempMappings = pUserMappings; + SDL_memcpy(pUserMappings, hint, nchHints); + pUserMappings[nchHints] = '\0'; + while (pUserMappings) { + char *pchNewLine = NULL; + + pchNewLine = SDL_strchr(pUserMappings, '\n'); + if (pchNewLine) { + *pchNewLine = '\0'; + } + + SDL_PrivateGameControllerAddMapping(pUserMappings, SDL_CONTROLLER_MAPPING_PRIORITY_USER); + + if (pchNewLine) { + pUserMappings = pchNewLine + 1; + } else { + pUserMappings = NULL; + } + } + SDL_free(pTempMappings); + } +} + +/* + * Fill the given buffer with the expected controller mapping filepath. + * Usually this will just be SDL_HINT_GAMECONTROLLERCONFIG_FILE, but for + * Android, we want to get the internal storage path. + */ +static SDL_bool SDL_GetControllerMappingFilePath(char *path, size_t size) +{ + const char *hint = SDL_GetHint(SDL_HINT_GAMECONTROLLERCONFIG_FILE); + if (hint && *hint) { + return SDL_strlcpy(path, hint, size) < size; + } + +#if 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; + + SDL_AssertJoysticksLocked(); + + pMappingString = s_ControllerMappings[i]; + while (pMappingString) { + SDL_PrivateGameControllerAddMapping(pMappingString, SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT); + + i++; + pMappingString = s_ControllerMappings[i]; + } + + if (SDL_GetControllerMappingFilePath(szControllerMapPath, sizeof(szControllerMapPath))) { + SDL_GameControllerAddMappingsFromFile(szControllerMapPath); + } + + /* load in any user supplied config */ + SDL_GameControllerLoadHints(); + + SDL_LoadVIDPIDList(&SDL_allowed_controllers); + SDL_LoadVIDPIDList(&SDL_ignored_controllers); + + return 0; +} + +int SDL_GameControllerInit(void) +{ + int i; + + /* watch for joy events and fire controller ones if needed */ + SDL_AddEventWatch(SDL_GameControllerEventWatcher, NULL); + + /* Send added events for controllers currently attached */ + for (i = 0; i < SDL_NumJoysticks(); ++i) { + if (SDL_IsGameController(i)) { + SDL_Event deviceevent; + deviceevent.type = SDL_CONTROLLERDEVICEADDED; + deviceevent.cdevice.which = i; + SDL_PushEvent(&deviceevent); + } + } + + return 0; +} + +/* + * Get the implementation dependent name of a controller + */ +const char *SDL_GameControllerNameForIndex(int joystick_index) +{ + const char *retval = NULL; + + SDL_LockJoysticks(); + { + ControllerMapping_t *mapping = SDL_PrivateGetControllerMapping(joystick_index); + if (mapping) { + if (SDL_strcmp(mapping->name, "*") == 0) { + retval = SDL_JoystickNameForIndex(joystick_index); + } else { + retval = mapping->name; + } + } + } + SDL_UnlockJoysticks(); + + return retval; +} + +/* + * Get the implementation dependent path of a controller + */ +const char *SDL_GameControllerPathForIndex(int joystick_index) +{ + const char *retval = NULL; + + SDL_LockJoysticks(); + { + ControllerMapping_t *mapping = SDL_PrivateGetControllerMapping(joystick_index); + if (mapping) { + retval = SDL_JoystickPathForIndex(joystick_index); + } + } + SDL_UnlockJoysticks(); + + return retval; +} + +/** + * Get the type of a game controller. + */ +SDL_GameControllerType SDL_GameControllerTypeForIndex(int joystick_index) +{ + SDL_JoystickGUID joystick_guid = SDL_JoystickGetDeviceGUID(joystick_index); + const char *mapping = SDL_GameControllerMappingForGUID(joystick_guid); + char *type_string, *comma; + SDL_GameControllerType type; + if (mapping) { + type_string = SDL_strstr(mapping, SDL_CONTROLLER_TYPE_FIELD); + if (type_string) { + type_string += SDL_CONTROLLER_TYPE_FIELD_SIZE; + comma = SDL_strchr(type_string, ','); + if (comma) { + *comma = '\0'; + type = SDL_GetGameControllerTypeFromString(type_string); + *comma = ','; + } else { + type = SDL_GetGameControllerTypeFromString(type_string); + } + return type; + } + } + return SDL_GetJoystickGameControllerTypeFromGUID(joystick_guid, SDL_JoystickNameForIndex(joystick_index)); +} + +/** + * Get the mapping of a game controller. + * This can be called before any controllers are opened. + * If no mapping can be found, this function returns NULL. + */ +char *SDL_GameControllerMappingForDeviceIndex(int joystick_index) +{ + char *retval = NULL; + + SDL_LockJoysticks(); + { + ControllerMapping_t *mapping = SDL_PrivateGetControllerMapping(joystick_index); + if (mapping) { + SDL_JoystickGUID guid; + char pchGUID[33]; + size_t needed; + guid = SDL_JoystickGetDeviceGUID(joystick_index); + SDL_JoystickGetGUIDString(guid, pchGUID, sizeof(pchGUID)); + /* allocate enough memory for GUID + ',' + name + ',' + mapping + \0 */ + needed = SDL_strlen(pchGUID) + 1 + SDL_strlen(mapping->name) + 1 + SDL_strlen(mapping->mapping) + 1; + retval = (char *)SDL_malloc(needed); + if (retval) { + (void)SDL_snprintf(retval, needed, "%s,%s,%s", pchGUID, mapping->name, mapping->mapping); + } else { + SDL_OutOfMemory(); + } + } + } + SDL_UnlockJoysticks(); + return retval; +} + +/* + * Return 1 if the joystick with this name and GUID is a supported controller + */ +SDL_bool SDL_IsGameControllerNameAndGUID(const char *name, SDL_JoystickGUID guid) +{ + SDL_bool retval; + + SDL_LockJoysticks(); + { + if (s_pDefaultMapping || SDL_PrivateGetControllerMappingForNameAndGUID(name, guid) != NULL) { + retval = SDL_TRUE; + } else { + retval = SDL_FALSE; + } + } + SDL_UnlockJoysticks(); + + return retval; +} + +/* + * Return 1 if the joystick at this device index is a supported controller + */ +SDL_bool SDL_IsGameController(int joystick_index) +{ + SDL_bool retval; + + SDL_LockJoysticks(); + { + if (SDL_PrivateGetControllerMapping(joystick_index) != NULL) { + retval = SDL_TRUE; + } else { + retval = SDL_FALSE; + } + } + SDL_UnlockJoysticks(); + + return retval; +} + +#if defined(__LINUX__) +static SDL_bool SDL_endswith(const char *string, const char *suffix) +{ + size_t string_length = string ? SDL_strlen(string) : 0; + size_t suffix_length = suffix ? SDL_strlen(suffix) : 0; + + if (suffix_length > 0 && suffix_length <= string_length) { + if (SDL_memcmp(string + string_length - suffix_length, suffix, suffix_length) == 0) { + return SDL_TRUE; + } + } + return SDL_FALSE; +} +#endif + +/* + * Return 1 if the game controller should be ignored by SDL + */ +SDL_bool SDL_ShouldIgnoreGameController(const char *name, SDL_JoystickGUID guid) +{ + Uint16 vendor; + Uint16 product; + Uint16 version; + +#if defined(__LINUX__) + if (SDL_endswith(name, " Motion Sensors")) { + /* Don't treat the PS3 and PS4 motion controls as a separate game controller */ + return SDL_TRUE; + } + if (SDL_strncmp(name, "Nintendo ", 9) == 0 && SDL_strstr(name, " IMU") != NULL) { + /* Don't treat the Nintendo IMU as a separate game controller */ + return SDL_TRUE; + } + if (SDL_endswith(name, " Accelerometer") || + SDL_endswith(name, " IR") || + SDL_endswith(name, " Motion Plus") || + SDL_endswith(name, " Nunchuk")) { + /* Don't treat the Wii extension controls as a separate game controller */ + return SDL_TRUE; + } +#endif + + if (name && SDL_strcmp(name, "uinput-fpc") == 0) { + /* The Google Pixel fingerprint sensor reports itself as a joystick */ + return SDL_TRUE; + } + + if (SDL_allowed_controllers.num_included_entries == 0 && + SDL_ignored_controllers.num_included_entries == 0) { + return SDL_FALSE; + } + + SDL_GetJoystickGUIDInfo(guid, &vendor, &product, &version, NULL); + + if (SDL_GetHintBoolean("SDL_GAMECONTROLLER_ALLOW_STEAM_VIRTUAL_GAMEPAD", SDL_FALSE)) { + /* We shouldn't ignore Steam's virtual gamepad since it's using the hints to filter out the real controllers so it can remap input for the virtual controller */ + /* https://partner.steamgames.com/doc/features/steam_controller/steam_input_gamepad_emulation_bestpractices */ + SDL_bool bSteamVirtualGamepad = SDL_FALSE; +#if defined(__LINUX__) + bSteamVirtualGamepad = (vendor == USB_VENDOR_VALVE && product == USB_PRODUCT_STEAM_VIRTUAL_GAMEPAD); +#elif defined(__MACOSX__) + bSteamVirtualGamepad = (vendor == USB_VENDOR_MICROSOFT && product == USB_PRODUCT_XBOX360_WIRED_CONTROLLER && version == 1); +#elif defined(__WIN32__) + /* We can't tell on Windows, but Steam will block others in input hooks */ + bSteamVirtualGamepad = SDL_TRUE; +#endif + if (bSteamVirtualGamepad) { + return SDL_FALSE; + } + } + + if (SDL_allowed_controllers.num_included_entries > 0) { + if (SDL_VIDPIDInList(vendor, product, &SDL_allowed_controllers)) { + return SDL_FALSE; + } + return SDL_TRUE; + } else { + if (SDL_VIDPIDInList(vendor, product, &SDL_ignored_controllers)) { + return SDL_TRUE; + } + return SDL_FALSE; + } +} + +/* + * Open a controller for use - the index passed as an argument refers to + * the N'th controller on the system. This index is the value which will + * identify this controller in future controller events. + * + * This function returns a controller identifier, or NULL if an error occurred. + */ +SDL_GameController *SDL_GameControllerOpen(int joystick_index) +{ + SDL_JoystickID instance_id; + SDL_GameController *gamecontroller; + SDL_GameController *gamecontrollerlist; + ControllerMapping_t *pSupportedController = NULL; + + SDL_LockJoysticks(); + + gamecontrollerlist = SDL_gamecontrollers; + /* If the controller is already open, return it */ + instance_id = SDL_JoystickGetDeviceInstanceID(joystick_index); + while (gamecontrollerlist) { + if (instance_id == gamecontrollerlist->joystick->instance_id) { + gamecontroller = gamecontrollerlist; + ++gamecontroller->ref_count; + SDL_UnlockJoysticks(); + return gamecontroller; + } + gamecontrollerlist = gamecontrollerlist->next; + } + + /* Find a controller mapping */ + pSupportedController = SDL_PrivateGetControllerMapping(joystick_index); + if (!pSupportedController) { + SDL_SetError("Couldn't find mapping for device (%d)", joystick_index); + SDL_UnlockJoysticks(); + return NULL; + } + + /* Create and initialize the controller */ + gamecontroller = (SDL_GameController *)SDL_calloc(1, sizeof(*gamecontroller)); + if (!gamecontroller) { + SDL_OutOfMemory(); + SDL_UnlockJoysticks(); + return NULL; + } + gamecontroller->magic = &gamecontroller_magic; + + gamecontroller->joystick = SDL_JoystickOpen(joystick_index); + if (!gamecontroller->joystick) { + SDL_free(gamecontroller); + SDL_UnlockJoysticks(); + return NULL; + } + + if (gamecontroller->joystick->naxes) { + gamecontroller->last_match_axis = (SDL_ExtendedGameControllerBind **)SDL_calloc(gamecontroller->joystick->naxes, sizeof(*gamecontroller->last_match_axis)); + if (!gamecontroller->last_match_axis) { + SDL_OutOfMemory(); + SDL_JoystickClose(gamecontroller->joystick); + SDL_free(gamecontroller); + SDL_UnlockJoysticks(); + return NULL; + } + } + if (gamecontroller->joystick->nhats) { + gamecontroller->last_hat_mask = (Uint8 *)SDL_calloc(gamecontroller->joystick->nhats, sizeof(*gamecontroller->last_hat_mask)); + if (!gamecontroller->last_hat_mask) { + SDL_OutOfMemory(); + SDL_JoystickClose(gamecontroller->joystick); + SDL_free(gamecontroller->last_match_axis); + SDL_free(gamecontroller); + SDL_UnlockJoysticks(); + return NULL; + } + } + + SDL_PrivateLoadButtonMapping(gamecontroller, pSupportedController); + + /* Add the controller to list */ + ++gamecontroller->ref_count; + /* Link the controller in the list */ + gamecontroller->next = SDL_gamecontrollers; + SDL_gamecontrollers = gamecontroller; + + SDL_UnlockJoysticks(); + + return gamecontroller; +} + +/* + * Manually pump for controller updates. + */ +void SDL_GameControllerUpdate(void) +{ + /* Just for API completeness; the joystick API does all the work. */ + SDL_JoystickUpdate(); +} + +/** + * Return whether a game controller has a given axis + */ +SDL_bool SDL_GameControllerHasAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis) +{ + SDL_GameControllerButtonBind bind; + + SDL_LockJoysticks(); + { + CHECK_GAMECONTROLLER_MAGIC(gamecontroller, SDL_FALSE); + + bind = SDL_GameControllerGetBindForAxis(gamecontroller, axis); + } + SDL_UnlockJoysticks(); + + return (bind.bindType != SDL_CONTROLLER_BINDTYPE_NONE) ? SDL_TRUE : SDL_FALSE; +} + +/* + * Get the current state of an axis control on a controller + */ +Sint16 SDL_GameControllerGetAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis) +{ + Sint16 retval = 0; + + SDL_LockJoysticks(); + { + int i; + + CHECK_GAMECONTROLLER_MAGIC(gamecontroller, 0); + + for (i = 0; i < gamecontroller->num_bindings; ++i) { + SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i]; + if (binding->outputType == SDL_CONTROLLER_BINDTYPE_AXIS && binding->output.axis.axis == axis) { + int value = 0; + SDL_bool valid_input_range; + SDL_bool valid_output_range; + + if (binding->inputType == SDL_CONTROLLER_BINDTYPE_AXIS) { + value = SDL_JoystickGetAxis(gamecontroller->joystick, binding->input.axis.axis); + if (binding->input.axis.axis_min < binding->input.axis.axis_max) { + valid_input_range = (value >= binding->input.axis.axis_min && value <= binding->input.axis.axis_max); + } else { + valid_input_range = (value >= binding->input.axis.axis_max && value <= binding->input.axis.axis_min); + } + if (valid_input_range) { + if (binding->input.axis.axis_min != binding->output.axis.axis_min || binding->input.axis.axis_max != binding->output.axis.axis_max) { + float normalized_value = (float)(value - binding->input.axis.axis_min) / (binding->input.axis.axis_max - binding->input.axis.axis_min); + value = binding->output.axis.axis_min + (int)(normalized_value * (binding->output.axis.axis_max - binding->output.axis.axis_min)); + } + } else { + value = 0; + } + } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_BUTTON) { + value = SDL_JoystickGetButton(gamecontroller->joystick, binding->input.button); + if (value == SDL_PRESSED) { + value = binding->output.axis.axis_max; + } + } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_HAT) { + int hat_mask = SDL_JoystickGetHat(gamecontroller->joystick, binding->input.hat.hat); + if (hat_mask & binding->input.hat.hat_mask) { + value = binding->output.axis.axis_max; + } + } + + if (binding->output.axis.axis_min < binding->output.axis.axis_max) { + valid_output_range = (value >= binding->output.axis.axis_min && value <= binding->output.axis.axis_max); + } else { + valid_output_range = (value >= binding->output.axis.axis_max && value <= binding->output.axis.axis_min); + } + /* If the value is zero, there might be another binding that makes it non-zero */ + if (value != 0 && valid_output_range) { + retval = (Sint16)value; + break; + } + } + } + } + SDL_UnlockJoysticks(); + + return retval; +} + +/** + * Return whether a game controller has a given button + */ +SDL_bool SDL_GameControllerHasButton(SDL_GameController *gamecontroller, SDL_GameControllerButton button) +{ + SDL_GameControllerButtonBind bind; + + SDL_LockJoysticks(); + { + CHECK_GAMECONTROLLER_MAGIC(gamecontroller, SDL_FALSE); + + bind = SDL_GameControllerGetBindForButton(gamecontroller, button); + } + SDL_UnlockJoysticks(); + + return (bind.bindType != SDL_CONTROLLER_BINDTYPE_NONE) ? SDL_TRUE : SDL_FALSE; +} + +/* + * Get the current state of a button on a controller + */ +Uint8 SDL_GameControllerGetButton(SDL_GameController *gamecontroller, SDL_GameControllerButton button) +{ + Uint8 retval = SDL_RELEASED; + + SDL_LockJoysticks(); + { + int i; + + CHECK_GAMECONTROLLER_MAGIC(gamecontroller, 0); + + for (i = 0; i < gamecontroller->num_bindings; ++i) { + SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i]; + if (binding->outputType == SDL_CONTROLLER_BINDTYPE_BUTTON && binding->output.button == button) { + if (binding->inputType == SDL_CONTROLLER_BINDTYPE_AXIS) { + SDL_bool valid_input_range; + + int value = SDL_JoystickGetAxis(gamecontroller->joystick, binding->input.axis.axis); + int threshold = binding->input.axis.axis_min + (binding->input.axis.axis_max - binding->input.axis.axis_min) / 2; + if (binding->input.axis.axis_min < binding->input.axis.axis_max) { + valid_input_range = (value >= binding->input.axis.axis_min && value <= binding->input.axis.axis_max); + if (valid_input_range) { + retval = (value >= threshold) ? SDL_PRESSED : SDL_RELEASED; + break; + } + } else { + valid_input_range = (value >= binding->input.axis.axis_max && value <= binding->input.axis.axis_min); + if (valid_input_range) { + retval = (value <= threshold) ? SDL_PRESSED : SDL_RELEASED; + break; + } + } + } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_BUTTON) { + retval = SDL_JoystickGetButton(gamecontroller->joystick, binding->input.button); + break; + } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_HAT) { + int hat_mask = SDL_JoystickGetHat(gamecontroller->joystick, binding->input.hat.hat); + retval = (hat_mask & binding->input.hat.hat_mask) ? SDL_PRESSED : SDL_RELEASED; + break; + } + } + } + } + SDL_UnlockJoysticks(); + + return retval; +} + +/** + * Get the number of touchpads on a game controller. + */ +int SDL_GameControllerGetNumTouchpads(SDL_GameController *gamecontroller) +{ + int retval = 0; + + SDL_LockJoysticks(); + { + SDL_Joystick *joystick = SDL_GameControllerGetJoystick(gamecontroller); + if (joystick) { + retval = joystick->ntouchpads; + } + } + SDL_UnlockJoysticks(); + + return retval; +} + +/** + * Get the number of supported simultaneous fingers on a touchpad on a game controller. + */ +int SDL_GameControllerGetNumTouchpadFingers(SDL_GameController *gamecontroller, int touchpad) +{ + int retval = 0; + + SDL_LockJoysticks(); + { + SDL_Joystick *joystick = SDL_GameControllerGetJoystick(gamecontroller); + if (joystick) { + if (touchpad >= 0 && touchpad < joystick->ntouchpads) { + retval = joystick->touchpads[touchpad].nfingers; + } else { + retval = SDL_InvalidParamError("touchpad"); + } + } + } + SDL_UnlockJoysticks(); + + return retval; +} + +/** + * Get the current state of a finger on a touchpad on a game controller. + */ +int SDL_GameControllerGetTouchpadFinger(SDL_GameController *gamecontroller, int touchpad, int finger, Uint8 *state, float *x, float *y, float *pressure) +{ + int retval = -1; + + SDL_LockJoysticks(); + { + SDL_Joystick *joystick = SDL_GameControllerGetJoystick(gamecontroller); + if (joystick) { + if (touchpad >= 0 && touchpad < joystick->ntouchpads) { + SDL_JoystickTouchpadInfo *touchpad_info = &joystick->touchpads[touchpad]; + if (finger >= 0 && finger < touchpad_info->nfingers) { + SDL_JoystickTouchpadFingerInfo *info = &touchpad_info->fingers[finger]; + + if (state) { + *state = info->state; + } + if (x) { + *x = info->x; + } + if (y) { + *y = info->y; + } + if (pressure) { + *pressure = info->pressure; + } + retval = 0; + } else { + retval = SDL_InvalidParamError("finger"); + } + } else { + retval = SDL_InvalidParamError("touchpad"); + } + } + } + SDL_UnlockJoysticks(); + + return retval; +} + +/** + * Return whether a game controller has a particular sensor. + */ +SDL_bool SDL_GameControllerHasSensor(SDL_GameController *gamecontroller, SDL_SensorType type) +{ + SDL_bool retval = SDL_FALSE; + + SDL_LockJoysticks(); + { + SDL_Joystick *joystick = SDL_GameControllerGetJoystick(gamecontroller); + if (joystick) { + int i; + for (i = 0; i < joystick->nsensors; ++i) { + if (joystick->sensors[i].type == type) { + retval = SDL_TRUE; + break; + } + } + } + } + SDL_UnlockJoysticks(); + + return retval; +} + +/* + * Set whether data reporting for a game controller sensor is enabled + */ +int SDL_GameControllerSetSensorEnabled(SDL_GameController *gamecontroller, SDL_SensorType type, SDL_bool enabled) +{ + SDL_LockJoysticks(); + { + SDL_Joystick *joystick = SDL_GameControllerGetJoystick(gamecontroller); + if (joystick) { + int i; + for (i = 0; i < joystick->nsensors; ++i) { + SDL_JoystickSensorInfo *sensor = &joystick->sensors[i]; + + if (sensor->type == type) { + if (sensor->enabled == enabled) { + SDL_UnlockJoysticks(); + return 0; + } + + if (enabled) { + if (joystick->nsensors_enabled == 0) { + if (joystick->driver->SetSensorsEnabled(joystick, SDL_TRUE) < 0) { + SDL_UnlockJoysticks(); + return -1; + } + } + ++joystick->nsensors_enabled; + } else { + if (joystick->nsensors_enabled == 1) { + if (joystick->driver->SetSensorsEnabled(joystick, SDL_FALSE) < 0) { + SDL_UnlockJoysticks(); + return -1; + } + } + --joystick->nsensors_enabled; + } + + sensor->enabled = enabled; + SDL_UnlockJoysticks(); + return 0; + } + } + } + } + SDL_UnlockJoysticks(); + + return SDL_Unsupported(); +} + +/* + * Query whether sensor data reporting is enabled for a game controller + */ +SDL_bool SDL_GameControllerIsSensorEnabled(SDL_GameController *gamecontroller, SDL_SensorType type) +{ + SDL_bool retval = SDL_FALSE; + + SDL_LockJoysticks(); + { + SDL_Joystick *joystick = SDL_GameControllerGetJoystick(gamecontroller); + if (joystick) { + int i; + for (i = 0; i < joystick->nsensors; ++i) { + if (joystick->sensors[i].type == type) { + retval = joystick->sensors[i].enabled; + break; + } + } + } + } + SDL_UnlockJoysticks(); + + return retval; +} + +/* + * Get the data rate of a game controller sensor. + */ +float SDL_GameControllerGetSensorDataRate(SDL_GameController *gamecontroller, SDL_SensorType type) +{ + float retval = 0.0f; + + SDL_LockJoysticks(); + { + SDL_Joystick *joystick = SDL_GameControllerGetJoystick(gamecontroller); + if (joystick) { + int i; + for (i = 0; i < joystick->nsensors; ++i) { + SDL_JoystickSensorInfo *sensor = &joystick->sensors[i]; + + if (sensor->type == type) { + retval = sensor->rate; + break; + } + } + } + } + SDL_UnlockJoysticks(); + + return retval; +} + +/* + * Get the current state of a game controller sensor. + */ +int SDL_GameControllerGetSensorData(SDL_GameController *gamecontroller, SDL_SensorType type, float *data, int num_values) +{ + return SDL_GameControllerGetSensorDataWithTimestamp(gamecontroller, type, NULL, data, num_values); +} + +/* + * Get the current state of a game controller sensor. + */ +int SDL_GameControllerGetSensorDataWithTimestamp(SDL_GameController *gamecontroller, SDL_SensorType type, Uint64 *timestamp, float *data, int num_values) +{ + SDL_LockJoysticks(); + { + SDL_Joystick *joystick = SDL_GameControllerGetJoystick(gamecontroller); + if (joystick) { + int i; + for (i = 0; i < joystick->nsensors; ++i) { + SDL_JoystickSensorInfo *sensor = &joystick->sensors[i]; + + if (sensor->type == type) { + num_values = SDL_min(num_values, SDL_arraysize(sensor->data)); + SDL_memcpy(data, sensor->data, num_values * sizeof(*data)); + if (timestamp) { + *timestamp = sensor->timestamp_us; + } + SDL_UnlockJoysticks(); + return 0; + } + } + } + } + SDL_UnlockJoysticks(); + + return SDL_Unsupported(); +} + +const char *SDL_GameControllerName(SDL_GameController *gamecontroller) +{ + const char *retval = NULL; + + SDL_LockJoysticks(); + { + CHECK_GAMECONTROLLER_MAGIC(gamecontroller, NULL); + + if (SDL_strcmp(gamecontroller->name, "*") == 0 || + gamecontroller->joystick->steam_handle != 0) { + retval = SDL_JoystickName(gamecontroller->joystick); + } else { + retval = gamecontroller->name; + } + } + SDL_UnlockJoysticks(); + + return retval; +} + +const char *SDL_GameControllerPath(SDL_GameController *gamecontroller) +{ + SDL_Joystick *joystick = SDL_GameControllerGetJoystick(gamecontroller); + + if (!joystick) { + return NULL; + } + return SDL_JoystickPath(joystick); +} + +SDL_GameControllerType SDL_GameControllerGetType(SDL_GameController *gamecontroller) +{ + SDL_GameControllerType type = SDL_CONTROLLER_TYPE_UNKNOWN; + SDL_Joystick *joystick; + const SDL_SteamVirtualGamepadInfo *info; + + SDL_LockJoysticks(); + { + CHECK_GAMECONTROLLER_MAGIC(gamecontroller, SDL_CONTROLLER_TYPE_UNKNOWN); + + joystick = gamecontroller->joystick; + info = SDL_GetJoystickInstanceVirtualGamepadInfo(joystick->instance_id); + if (info) { + type = info->type; + } else if (gamecontroller->type != SDL_CONTROLLER_TYPE_UNKNOWN) { + type = gamecontroller->type; + } else { + type = SDL_GetJoystickGameControllerTypeFromGUID(SDL_JoystickGetGUID(joystick), SDL_JoystickName(joystick)); + } + } + SDL_UnlockJoysticks(); + + return type; +} + +int SDL_GameControllerGetPlayerIndex(SDL_GameController *gamecontroller) +{ + SDL_Joystick *joystick = SDL_GameControllerGetJoystick(gamecontroller); + + if (!joystick) { + return -1; + } + return SDL_JoystickGetPlayerIndex(joystick); +} + +/** + * Set the player index of an opened game controller + */ +void SDL_GameControllerSetPlayerIndex(SDL_GameController *gamecontroller, int player_index) +{ + SDL_Joystick *joystick = SDL_GameControllerGetJoystick(gamecontroller); + + if (!joystick) { + return; + } + SDL_JoystickSetPlayerIndex(joystick, player_index); +} + +Uint16 SDL_GameControllerGetVendor(SDL_GameController *gamecontroller) +{ + SDL_Joystick *joystick = SDL_GameControllerGetJoystick(gamecontroller); + + if (!joystick) { + return 0; + } + return SDL_JoystickGetVendor(joystick); +} + +Uint16 SDL_GameControllerGetProduct(SDL_GameController *gamecontroller) +{ + SDL_Joystick *joystick = SDL_GameControllerGetJoystick(gamecontroller); + + if (!joystick) { + return 0; + } + return SDL_JoystickGetProduct(joystick); +} + +Uint16 SDL_GameControllerGetProductVersion(SDL_GameController *gamecontroller) +{ + SDL_Joystick *joystick = SDL_GameControllerGetJoystick(gamecontroller); + + if (!joystick) { + return 0; + } + return SDL_JoystickGetProductVersion(joystick); +} + +Uint16 SDL_GameControllerGetFirmwareVersion(SDL_GameController *gamecontroller) +{ + SDL_Joystick *joystick = SDL_GameControllerGetJoystick(gamecontroller); + + if (!joystick) { + return 0; + } + return SDL_JoystickGetFirmwareVersion(joystick); +} + +const char * SDL_GameControllerGetSerial(SDL_GameController *gamecontroller) +{ + SDL_Joystick *joystick = SDL_GameControllerGetJoystick(gamecontroller); + + if (!joystick) { + return NULL; + } + return SDL_JoystickGetSerial(joystick); +} + +Uint64 SDL_GameControllerGetSteamHandle(SDL_GameController *gamecontroller) +{ + Uint64 handle = 0; + + SDL_LockJoysticks(); + { + CHECK_GAMECONTROLLER_MAGIC(gamecontroller, 0); + + handle = gamecontroller->joystick->steam_handle; + } + SDL_UnlockJoysticks(); + + return handle; +} + +/* + * Return if the controller in question is currently attached to the system, + * \return 0 if not plugged in, 1 if still present. + */ +SDL_bool SDL_GameControllerGetAttached(SDL_GameController *gamecontroller) +{ + SDL_Joystick *joystick = SDL_GameControllerGetJoystick(gamecontroller); + + if (!joystick) { + return SDL_FALSE; + } + return SDL_JoystickGetAttached(joystick); +} + +/* + * Get the joystick for this controller + */ +SDL_Joystick *SDL_GameControllerGetJoystick(SDL_GameController *gamecontroller) +{ + SDL_Joystick *joystick; + + SDL_LockJoysticks(); + { + CHECK_GAMECONTROLLER_MAGIC(gamecontroller, NULL); + + joystick = gamecontroller->joystick; + } + SDL_UnlockJoysticks(); + + return joystick; +} + +/* + * Return the SDL_GameController associated with an instance id. + */ +SDL_GameController *SDL_GameControllerFromInstanceID(SDL_JoystickID joyid) +{ + SDL_GameController *gamecontroller; + + SDL_LockJoysticks(); + gamecontroller = SDL_gamecontrollers; + while (gamecontroller) { + if (gamecontroller->joystick->instance_id == joyid) { + SDL_UnlockJoysticks(); + return gamecontroller; + } + gamecontroller = gamecontroller->next; + } + SDL_UnlockJoysticks(); + return NULL; +} + +/** + * Return the SDL_GameController associated with a player index. + */ +SDL_GameController *SDL_GameControllerFromPlayerIndex(int player_index) +{ + SDL_GameController *retval = NULL; + + SDL_LockJoysticks(); + { + SDL_Joystick *joystick = SDL_JoystickFromPlayerIndex(player_index); + if (joystick) { + retval = SDL_GameControllerFromInstanceID(joystick->instance_id); + } + } + SDL_UnlockJoysticks(); + + return retval; +} + +/* + * Get the SDL joystick layer binding for this controller axis mapping + */ +SDL_GameControllerButtonBind SDL_GameControllerGetBindForAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis) +{ + SDL_GameControllerButtonBind bind; + + SDL_zero(bind); + + SDL_LockJoysticks(); + { + CHECK_GAMECONTROLLER_MAGIC(gamecontroller, bind); + + if (axis != SDL_CONTROLLER_AXIS_INVALID) { + int i; + for (i = 0; i < gamecontroller->num_bindings; ++i) { + SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i]; + if (binding->outputType == SDL_CONTROLLER_BINDTYPE_AXIS && binding->output.axis.axis == axis) { + bind.bindType = binding->inputType; + if (binding->inputType == SDL_CONTROLLER_BINDTYPE_AXIS) { + /* FIXME: There might be multiple axes bound now that we have axis ranges... */ + bind.value.axis = binding->input.axis.axis; + } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_BUTTON) { + bind.value.button = binding->input.button; + } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_HAT) { + bind.value.hat.hat = binding->input.hat.hat; + bind.value.hat.hat_mask = binding->input.hat.hat_mask; + } + break; + } + } + } + } + SDL_UnlockJoysticks(); + + return bind; +} + +/* + * Get the SDL joystick layer binding for this controller button mapping + */ +SDL_GameControllerButtonBind SDL_GameControllerGetBindForButton(SDL_GameController *gamecontroller, SDL_GameControllerButton button) +{ + SDL_GameControllerButtonBind bind; + + SDL_zero(bind); + + SDL_LockJoysticks(); + { + CHECK_GAMECONTROLLER_MAGIC(gamecontroller, bind); + + if (button != SDL_CONTROLLER_BUTTON_INVALID) { + int i; + for (i = 0; i < gamecontroller->num_bindings; ++i) { + SDL_ExtendedGameControllerBind *binding = &gamecontroller->bindings[i]; + if (binding->outputType == SDL_CONTROLLER_BINDTYPE_BUTTON && binding->output.button == button) { + bind.bindType = binding->inputType; + if (binding->inputType == SDL_CONTROLLER_BINDTYPE_AXIS) { + bind.value.axis = binding->input.axis.axis; + } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_BUTTON) { + bind.value.button = binding->input.button; + } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_HAT) { + bind.value.hat.hat = binding->input.hat.hat; + bind.value.hat.hat_mask = binding->input.hat.hat_mask; + } + break; + } + } + } + } + SDL_UnlockJoysticks(); + + return bind; +} + +int SDL_GameControllerRumble(SDL_GameController *gamecontroller, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms) +{ + SDL_Joystick *joystick = SDL_GameControllerGetJoystick(gamecontroller); + + if (!joystick) { + return -1; + } + return SDL_JoystickRumble(joystick, low_frequency_rumble, high_frequency_rumble, duration_ms); +} + +int SDL_GameControllerRumbleTriggers(SDL_GameController *gamecontroller, Uint16 left_rumble, Uint16 right_rumble, Uint32 duration_ms) +{ + SDL_Joystick *joystick = SDL_GameControllerGetJoystick(gamecontroller); + + if (!joystick) { + return -1; + } + return SDL_JoystickRumbleTriggers(joystick, left_rumble, right_rumble, duration_ms); +} + +SDL_bool SDL_GameControllerHasLED(SDL_GameController *gamecontroller) +{ + SDL_Joystick *joystick = SDL_GameControllerGetJoystick(gamecontroller); + + if (!joystick) { + return SDL_FALSE; + } + return SDL_JoystickHasLED(joystick); +} + +SDL_bool SDL_GameControllerHasRumble(SDL_GameController *gamecontroller) +{ + SDL_Joystick *joystick = SDL_GameControllerGetJoystick(gamecontroller); + + if (!joystick) { + return SDL_FALSE; + } + return SDL_JoystickHasRumble(joystick); +} + +SDL_bool SDL_GameControllerHasRumbleTriggers(SDL_GameController *gamecontroller) +{ + SDL_Joystick *joystick = SDL_GameControllerGetJoystick(gamecontroller); + + if (!joystick) { + return SDL_FALSE; + } + return SDL_JoystickHasRumbleTriggers(joystick); +} + +int SDL_GameControllerSetLED(SDL_GameController *gamecontroller, Uint8 red, Uint8 green, Uint8 blue) +{ + SDL_Joystick *joystick = SDL_GameControllerGetJoystick(gamecontroller); + + if (!joystick) { + return -1; + } + return SDL_JoystickSetLED(joystick, red, green, blue); +} + +int SDL_GameControllerSendEffect(SDL_GameController *gamecontroller, const void *data, int size) +{ + SDL_Joystick *joystick = SDL_GameControllerGetJoystick(gamecontroller); + + if (!joystick) { + return -1; + } + return SDL_JoystickSendEffect(joystick, data, size); +} + +void SDL_GameControllerClose(SDL_GameController *gamecontroller) +{ + SDL_GameController *gamecontrollerlist, *gamecontrollerlistprev; + + SDL_LockJoysticks(); + + if (!gamecontroller || gamecontroller->magic != &gamecontroller_magic) { + SDL_UnlockJoysticks(); + return; + } + + /* First decrement ref count */ + if (--gamecontroller->ref_count > 0) { + SDL_UnlockJoysticks(); + return; + } + + SDL_JoystickClose(gamecontroller->joystick); + + gamecontrollerlist = SDL_gamecontrollers; + gamecontrollerlistprev = NULL; + while (gamecontrollerlist) { + if (gamecontroller == gamecontrollerlist) { + if (gamecontrollerlistprev) { + /* unlink this entry */ + gamecontrollerlistprev->next = gamecontrollerlist->next; + } else { + SDL_gamecontrollers = gamecontroller->next; + } + break; + } + gamecontrollerlistprev = gamecontrollerlist; + gamecontrollerlist = gamecontrollerlist->next; + } + + gamecontroller->magic = NULL; + SDL_free(gamecontroller->bindings); + SDL_free(gamecontroller->last_match_axis); + SDL_free(gamecontroller->last_hat_mask); + SDL_free(gamecontroller); + + SDL_UnlockJoysticks(); +} + +/* + * Quit the controller subsystem + */ +void SDL_GameControllerQuit(void) +{ + SDL_LockJoysticks(); + while (SDL_gamecontrollers) { + SDL_gamecontrollers->ref_count = 1; + SDL_GameControllerClose(SDL_gamecontrollers); + } + SDL_UnlockJoysticks(); +} + +void SDL_GameControllerQuitMappings(void) +{ + ControllerMapping_t *pControllerMap; + + SDL_AssertJoysticksLocked(); + + while (s_pSupportedControllers) { + pControllerMap = s_pSupportedControllers; + s_pSupportedControllers = s_pSupportedControllers->next; + SDL_free(pControllerMap->name); + SDL_free(pControllerMap->mapping); + SDL_free(pControllerMap); + } + + SDL_DelEventWatch(SDL_GameControllerEventWatcher, NULL); + + SDL_FreeVIDPIDList(&SDL_allowed_controllers); + SDL_FreeVIDPIDList(&SDL_ignored_controllers); +} + +/* + * Event filter to transform joystick events into appropriate game controller ones + */ +static int SDL_PrivateGameControllerAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis, Sint16 value) +{ + int posted; + + SDL_AssertJoysticksLocked(); + + /* translate the event, if desired */ + posted = 0; +#ifndef SDL_EVENTS_DISABLED + if (SDL_GetEventState(SDL_CONTROLLERAXISMOTION) == SDL_ENABLE) { + SDL_Event event; + event.type = SDL_CONTROLLERAXISMOTION; + event.caxis.which = gamecontroller->joystick->instance_id; + event.caxis.axis = axis; + event.caxis.value = value; + posted = SDL_PushEvent(&event) == 1; + } +#endif /* !SDL_EVENTS_DISABLED */ + return posted; +} + +/* + * Event filter to transform joystick events into appropriate game controller ones + */ +static int SDL_PrivateGameControllerButton(SDL_GameController *gamecontroller, SDL_GameControllerButton button, Uint8 state) +{ + int posted; +#ifndef SDL_EVENTS_DISABLED + SDL_Event event; + + SDL_AssertJoysticksLocked(); + + if (button == SDL_CONTROLLER_BUTTON_INVALID) { + return 0; + } + + switch (state) { + case SDL_PRESSED: + event.type = SDL_CONTROLLERBUTTONDOWN; + break; + case SDL_RELEASED: + event.type = SDL_CONTROLLERBUTTONUP; + break; + default: + /* Invalid state -- bail */ + return 0; + } +#endif /* !SDL_EVENTS_DISABLED */ + + if (button == SDL_CONTROLLER_BUTTON_GUIDE) { + Uint32 now = SDL_GetTicks(); + if (state == SDL_PRESSED) { + gamecontroller->guide_button_down = now; + + if (gamecontroller->joystick->delayed_guide_button) { + /* Skip duplicate press */ + return 0; + } + } else { + if (!SDL_TICKS_PASSED(now, gamecontroller->guide_button_down + SDL_MINIMUM_GUIDE_BUTTON_DELAY_MS)) { + gamecontroller->joystick->delayed_guide_button = SDL_TRUE; + return 0; + } + gamecontroller->joystick->delayed_guide_button = SDL_FALSE; + } + } + + /* translate the event, if desired */ + posted = 0; +#ifndef SDL_EVENTS_DISABLED + if (SDL_GetEventState(event.type) == SDL_ENABLE) { + event.cbutton.which = gamecontroller->joystick->instance_id; + event.cbutton.button = button; + event.cbutton.state = state; + posted = SDL_PushEvent(&event) == 1; + } +#endif /* !SDL_EVENTS_DISABLED */ + return posted; +} + +/* + * Turn off controller events + */ +int SDL_GameControllerEventState(int state) +{ +#ifdef SDL_EVENTS_DISABLED + return SDL_IGNORE; +#else + const Uint32 event_list[] = { + SDL_CONTROLLERAXISMOTION, + SDL_CONTROLLERBUTTONDOWN, + SDL_CONTROLLERBUTTONUP, + SDL_CONTROLLERDEVICEADDED, + SDL_CONTROLLERDEVICEREMOVED, + SDL_CONTROLLERDEVICEREMAPPED, + SDL_CONTROLLERTOUCHPADDOWN, + SDL_CONTROLLERTOUCHPADMOTION, + SDL_CONTROLLERTOUCHPADUP, + SDL_CONTROLLERSENSORUPDATE, + }; + unsigned int i; + + switch (state) { + case SDL_QUERY: + state = SDL_IGNORE; + for (i = 0; i < SDL_arraysize(event_list); ++i) { + state = SDL_EventState(event_list[i], SDL_QUERY); + if (state == SDL_ENABLE) { + break; + } + } + break; + default: + for (i = 0; i < SDL_arraysize(event_list); ++i) { + (void)SDL_EventState(event_list[i], state); + } + break; + } + return state; +#endif /* SDL_EVENTS_DISABLED */ +} + +void SDL_GameControllerHandleDelayedGuideButton(SDL_Joystick *joystick) +{ + SDL_GameController *controller; + + SDL_AssertJoysticksLocked(); + + for (controller = SDL_gamecontrollers; controller; controller = controller->next) { + if (controller->joystick == joystick) { + SDL_PrivateGameControllerButton(controller, SDL_CONTROLLER_BUTTON_GUIDE, SDL_RELEASED); + break; + } + } +} + +const char *SDL_GameControllerGetAppleSFSymbolsNameForButton(SDL_GameController *gamecontroller, SDL_GameControllerButton button) +{ +#if defined(SDL_JOYSTICK_MFI) + const char *IOS_GameControllerGetAppleSFSymbolsNameForButton(SDL_GameController * gamecontroller, SDL_GameControllerButton button); + const char *retval; + + SDL_LockJoysticks(); + { + CHECK_GAMECONTROLLER_MAGIC(gamecontroller, NULL); + + retval = IOS_GameControllerGetAppleSFSymbolsNameForButton(gamecontroller, button); + } + SDL_UnlockJoysticks(); + + if (retval && *retval) { + return retval; + } +#endif + return NULL; +} + +const char *SDL_GameControllerGetAppleSFSymbolsNameForAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis) +{ +#if defined(SDL_JOYSTICK_MFI) + const char *IOS_GameControllerGetAppleSFSymbolsNameForAxis(SDL_GameController * gamecontroller, SDL_GameControllerAxis axis); + const char *retval; + + SDL_LockJoysticks(); + { + CHECK_GAMECONTROLLER_MAGIC(gamecontroller, NULL); + + retval = IOS_GameControllerGetAppleSFSymbolsNameForAxis(gamecontroller, axis); + } + SDL_UnlockJoysticks(); + + if (retval && *retval) { + return retval; + } +#endif + return NULL; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/joystick/SDL_gamecontrollerdb.h b/SDL2-2.30.5/src/joystick/SDL_gamecontrollerdb.h similarity index 59% rename from SDL2-2.0.12/src/joystick/SDL_gamecontrollerdb.h rename to SDL2-2.30.5/src/joystick/SDL_gamecontrollerdb.h index 45379da..2297921 100644 --- a/SDL2-2.0.12/src/joystick/SDL_gamecontrollerdb.h +++ b/SDL2-2.30.5/src/joystick/SDL_gamecontrollerdb.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,35 +20,80 @@ */ #include "../SDL_internal.h" - /* Default mappings we support The easiest way to generate a new mapping is to start Steam in Big Picture mode, configure your joystick and then look in config/config.vdf in your Steam installation directory for the "SDL_GamepadBind" entry. - + Alternatively, you can use the app located in test/controllermap */ -static const char *s_ControllerMappings [] = -{ -#if SDL_JOYSTICK_XINPUT - "xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", +static const char *s_ControllerMappings[] = { +#ifdef SDL_JOYSTICK_XINPUT + "xinput,*,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", #endif -#if SDL_JOYSTICK_DINPUT +#ifdef SDL_JOYSTICK_WGI + "03000000491900001904000000007700,Amazon Luna Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,", + "03000000d11800000094000000007700,Google Stadia 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:a5,leftx:a0,lefty:a1,misc1:b12,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,", + "030000007e0500000920000000007701,Nintendo Switch Pro Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "030000007e0500000920000000007701,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,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,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "030000004c050000c405000000007701,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", + "030000004c050000e60c000000007700,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b14,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", + "0300000032150000000a000000007703,Razer Atrox Arcade Stick,a:b0,b:b1,dpdown:b12,dpleft:b13,dpright:b11,dpup:b10,leftshoulder:b4,lefttrigger:b8,rightshoulder:b5,righttrigger:b9,x:b2,y:b3,", + "03000000de280000ff11000000007701,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:b12,dpleft:b13,dpright:b11,dpup:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a4,leftx:a1,lefty:a0~,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a2~,start:b7,x:b2,y:b3,", +#endif +#ifdef SDL_JOYSTICK_DINPUT "03000000fa2d00000100000000000000,3DRUDDER,leftx:a0,lefty:a1,rightx:a5,righty:a2,", - "03000000c82d00000090000000000000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,", - "03000000c82d00001038000000000000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,", - "03000000c82d00000650000000000000,8BitDo M30 GamePad,a:b0,b:b1,back:b10,guide:b2,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,start:b11,x:b3,y:b4,", - "03000000c82d00005106000000000000,8BitDo M30 GamePad,a:b0,b:b1,back:b10,guide:b2,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,start:b11,x:b3,y:b4,", - "030000003512000012ab000000000000,8BitDo NES30 GamePad,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,", - "03000000022000000090000000000000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,", - "03000000203800000900000000000000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,", - "03000000c82d00000060000000000000,8BitDo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,", - "03000000c82d00000061000000000000,8BitDo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,", - "03000000102800000900000000000000,8BitDo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,", - "03000000c82d00000160000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,", - "03000000a00500003232000000000000,8BitDo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,", - "03000000c82d00002038000000000000,8BitDo,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,", + "03000000c82d00000090000000000000,8BitDo FC30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000090000000000000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00001038000000000000,8BitDo FC30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00001038000000000000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000650000000000000,8BitDo M30 Gamepad,a:b0,b:b1,back:b10,guide:b2,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000650000000000000,8BitDo M30 Gamepad,a:b1,b:b0,back:b10,guide:b2,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00005106000000000000,8BitDo M30 Gamepad,a:b0,b:b1,back:b10,guide:b2,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00005106000000000000,8BitDo M30 Gamepad,a:b1,b:b0,back:b10,guide:b2,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00001590000000000000,8BitDo N30 Pro 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00001590000000000000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00006528000000000000,8BitDo N30 Pro 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00006528000000000000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "030000003512000012ab000000000000,8BitDo NES30 Gamepad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "030000003512000012ab000000000000,8BitDo NES30 Gamepad,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000022000000090000000000000,8BitDo NES30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000022000000090000000000000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000203800000900000000000000,8BitDo NES30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000203800000900000000000000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00002038000000000000,8BitDo NES30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00002038000000000000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000660000000000000,8BitDo Pro 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000660000000000000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000060000000000000,8BitDo SF30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000060000000000000,8BitDo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000061000000000000,8BitDo SF30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000061000000000000,8BitDo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000102800000900000000000000,8BitDo SFC30 Gamepad,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000102800000900000000000000,8BitDo SFC30 Gamepad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00001290000000000000,8BitDo SN30 Gamepad,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00001290000000000000,8BitDo SN30 Gamepad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00006228000000000000,8BitDo SN30 Gamepad,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00006228000000000000,8BitDo SN30 Gamepad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000260000000000000,8BitDo SN30 Pro+,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000260000000000000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000261000000000000,8BitDo SN30 Pro+,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000261000000000000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000160000000000000,8BitDo SN30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000160000000000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "030000003512000020ab000000000000,8BitDo SNES30 Gamepad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "030000003512000020ab000000000000,8BitDo SNES30 Gamepad,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00001130000000000000,8BitDo Ultimate Wired Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,misc1:b26,paddle1:b24,paddle2:b25,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,", + "03000000c82d00001330000000000000,8BitDo Ultimate Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,misc1:b26,paddle1:b23,paddle2:b19,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,", + "03000000c82d00001890000000000000,8BitDo Zero 2,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00001890000000000000,8BitDo Zero 2,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00003032000000000000,8BitDo Zero 2,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00003032000000000000,8BitDo Zero 2,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000a00500003232000000000000,8BitDo Zero Gamepad,a:b0,b:b1,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000a00500003232000000000000,8BitDo Zero Gamepad,a:b1,b:b0,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000050b00000579000000000000,ASUS ROG Kunai 3 Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,", + "03000000050b00000679000000000000,ASUS ROG Kunai 3 Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,misc1:b15,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,", "030000008f0e00001200000000000000,Acme GA-02,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,", "03000000fa190000f0ff000000000000,Acteck AGJ-3200,a:b2,b:b1,back:b8,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:a2,righty:a3,start:b9,x:b3,y:b0,", "03000000341a00003608000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", @@ -59,6 +104,7 @@ static const char *s_ControllerMappings [] = "030000006f0e00001901000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "030000006f0e00001a01000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "03000000d62000001d57000000000000,Airflo PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", + "03000000491900001904000000000000,Amazon Luna Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,", "03000000d62000002a79000000000000,BDA PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "03000000d81d00000b00000000000000,BUFFALO BSGP1601 Series ,a:b5,b:b3,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b13,x:b4,y:b2,", "03000000d6200000e557000000000000,Batarang,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", @@ -79,6 +125,7 @@ static const char *s_ControllerMappings [] = "03000000260900008888000000000000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a4,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,", "03000000a306000022f6000000000000,Cyborg V.3 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,", "03000000451300000830000000000000,Defender Game Racer X7,a:b0,b:b1,back:b8,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:a2,righty:a3,start:b9,x:b2,y:b3,", + "03000000790000000600000000000000,Defender Joystick Cobra R4,crc:c77a,a:b2,b:b1,back:b8,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:a2~,righty:a3~,start:b9,x:b3,y:b0,", "03000000791d00000103000000000000,Dual Box WII,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,", "03000000bd12000002e0000000000000,Dual USB Vibration Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,", "030000006f0e00003001000000000000,EA SPORTS PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", @@ -88,19 +135,19 @@ static const char *s_ControllerMappings [] = "03000000b80500000610000000000000,Elecom Gamepad,a:b2,b:b3,back:b8,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:a2,righty:a3,start:b9,x:b0,y:b1,", "03000000852100000201000000000000,FF-GP1,a:b1,b:b2,back:b8,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:a2,righty:a3,start:b9,x:b0,y:b3,", "030000000d0f00002700000000000000,FIGHTING STICK V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,", - "030000000d0f00008700000000000000,Fighting Stick mini 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,", - "030000000d0f00008800000000000000,Fighting Stick mini 4,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,", - "78696e70757403000000000000000000,Fightstick TES,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,", - "03000000790000000600000000000000,G-Shark GS-GP702,a:b2,b:b1,back:b8,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:a2,righty:a4,start:b9,x:b3,y:b0,", + "03000000790000000600000000000000,G-Shark GS-GP702,crc:8e4f,a:b2,b:b1,back:b8,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:a2,righty:a3,start:b9,x:b3,y:b0,", "030000008f0e00000d31000000000000,GAMEPAD 3 TURBO,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "03000000300f00000b01000000000000,GGE909 Recoil Pad,a:b2,b:b1,back:b8,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:b9,x:b3,y:b0,", "03000000790000002201000000000000,Game Controller for PC,a:b2,b:b1,back:b8,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:a2,righty:a3,start:b9,x:b3,y:b0,", "0300000066f700000100000000000000,Game VIB Joystick,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,start:b11,x:b0,y:b1,", - "03000000280400000140000000000000,GamePad Pro USB,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,", + "03000000491900000204000000000000,GameSir T4 Pro,crc:1aa4,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,", "03000000ac0500003d03000000000000,GameSir,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,", "03000000ac0500004d04000000000000,GameSir,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,", + "03000000ac0500001a06000000000000,GameSir-T3 2.02,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,", "03000000ffff00000000000000000000,GameStop Gamepad,a:b0,b:b1,back:b8,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:a2,righty:a3,start:b9,x:b2,y:b3,", + "03000000c01100000140000000000000,GameStop PS4 Fun Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "03000000260900002625000000000000,Gamecube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,lefttrigger:a4,leftx:a0,lefty:a1,righttrigger:a5,rightx:a2,righty:a3,start:b7,x:b2,y:b3,", + "03000000280400000140000000000000,Gamepad Pro USB,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,", "030000005c1a00003330000000000000,Genius MaxFire Grandias 12V,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b2,y:b3,", "030000008305000031b0000000000000,Genius Maxfire Blaze 3,a:b0,b:b1,back:b8,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:a2,righty:a3,start:b9,x:b2,y:b3,", "03000000451300000010000000000000,Genius Maxfire Grandias 12,a:b0,b:b1,back:b8,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:a2,righty:a3,start:b9,x:b2,y:b3,", @@ -109,9 +156,12 @@ static const char *s_ControllerMappings [] = "03000000f0250000c383000000000000,Gioteck VX2 Controller,a:b2,b:b1,back:b8,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:a2,righty:a3,start:b9,x:b3,y:b0,", "03000000f0250000c483000000000000,Gioteck VX2 Controller,a:b2,b:b1,back:b8,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:a2,righty:a3,start:b9,x:b3,y:b0,", "03000000f0250000c283000000000000,Gioteck,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,", + "03000000d11800000094000000000000,Google Stadia Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b11,rightx:a3,righty:a4,start:b9,x:b2,y:b3,", "03000000632500002605000000000000,HJD-X,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,", "030000000d0f00008400000000000000,HORI Fighting Commander,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "030000000d0f00008500000000000000,HORI Fighting Commander,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", + "030000000d0f00008800000000000000,HORI Fighting Stick mini 4 (PS3),a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,", + "030000000d0f00008700000000000000,HORI Fighting Stick mini 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,", "030000000d0f00006e00000000000000,HORIPAD 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "030000000d0f00006600000000000000,HORIPAD 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "030000000d0f0000ee00000000000000,HORIPAD mini4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", @@ -125,6 +175,7 @@ static const char *s_ControllerMappings [] = "030000000d0f00000900000000000000,Hori Pad 3 Turbo,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "030000000d0f00005400000000000000,Hori Pad 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "030000000d0f00004d00000000000000,Hori Pad A,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", + "030000000d0f00009200000000000000,Hori Pokken Tournament DX Pro Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,", "030000000d0f0000c100000000000000,Horipad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "030000008f0e00001330000000000000,HuiJia SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b9,x:b3,y:b0,", "030000006f0e00002401000000000000,INJUSTICE FightStick PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,", @@ -141,10 +192,13 @@ static const char *s_ControllerMappings [] = "030000006d04000016c2000000000000,Logitech Dual Action,a:b1,b:b2,back:b8,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:a2,righty:a3,start:b9,x:b0,y:b3,", "030000006d04000018c2000000000000,Logitech F510 Gamepad,a:b1,b:b2,back:b8,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:a2,righty:a3,start:b9,x:b0,y:b3,", "030000006d04000019c2000000000000,Logitech F710 Gamepad,a:b1,b:b2,back:b8,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:a2,righty:a3,start:b9,x:b0,y:b3,", /* Guide button doesn't seem to be sent in DInput mode. */ + "030000006d0400001ac2000000000000,Logitech Precision Gamepad,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,", "03000000380700008081000000000000,MADCATZ SFV Arcade FightStick Alpha PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", - "03000000380700006382000000000000,MLG GamePad PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", + "03000000380700006382000000000000,MLG Gamepad PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "03000000c62400002a89000000000000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,", "03000000c62400002b89000000000000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,", + "03000000c62400001a89000000000000,MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,", + "03000000c62400001b89000000000000,MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,", "03000000250900006688000000000000,MP-8866 Super Dual Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,", "03000000380700006652000000000000,Mad Catz C.T.R.L.R,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,", "03000000380700005032000000000000,Mad Catz FightPad PRO (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", @@ -161,7 +215,6 @@ static const char *s_ControllerMappings [] = "03000000380700003888000000000000,Madcatz Arcade Fightstick TE S+ PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "030000002a0600001024000000000000,Matricom,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b2,y:b3,", "03000000250900000128000000000000,Mayflash Arcade Stick,a:b1,b:b2,back:b8,leftshoulder:b0,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b7,start:b9,x:b5,y:b6,", - "03000000790000004318000000000000,Mayflash GameCube Controller Adapter,a:b1,b:b2,back:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b0,leftshoulder:b4,leftstick:b0,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b0,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,", "03000000790000004418000000000000,Mayflash GameCube Controller,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,", "030000008f0e00001030000000000000,Mayflash USB Adapter for original Sega Saturn controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b5,rightshoulder:b2,righttrigger:b7,start:b9,x:b3,y:b4,", "0300000025090000e803000000000000,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,", @@ -170,9 +223,13 @@ static const char *s_ControllerMappings [] = "030000006b140000010c000000000000,NACON GC-400ES,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,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,", "030000001008000001e5000000000000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b6,start:b9,x:b3,y:b0,", "03000000152000000182000000000000,NGDS,a:b2,b:b1,back:b8,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:a4,start:b9,x:b3,y:b0,", - "030000004b120000014d000000000000,NYKO AIRFLO,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:a3,leftstick:a0,lefttrigger:b6,rightshoulder:b5,rightstick:a2,righttrigger:b7,start:b9,x:b2,y:b3,", + "030000005509000000b4000000000000,NVIDIA Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", + "030000004b120000014d000000000000,NYKO AIRFLO EX,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,", + "03000000790000004318000000000000,Nintendo GameCube Controller,a:b1,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000790000004318000000000000,Nintendo GameCube Controller,a:b1,b:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", "03000000bd12000015d0000000000000,Nintendo Retrolink USB Super SNES Classic Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,", - "030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,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,", + "030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,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,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", "030000000d0500000308000000000000,Nostromo N45,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,", "03000000d62000006d57000000000000,OPP PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "03000000362800000100000000000000,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:b13,rightx:a3,righty:a4,x:b1,y:b2,", @@ -197,8 +254,9 @@ static const char *s_ControllerMappings [] = "030000003807000056a8000000000000,PS3 RF pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "03000000100000008200000000000000,PS360+ v1.66,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:h0.4,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,", "030000004c050000a00b000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", - "030000004c050000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", + "030000004c050000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,touchpad:b13,x:b0,y:b3,", "030000004c050000cc09000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", + "030000004c050000e60c000000000000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "030000008f0e00000300000000000000,Piranha xtreme,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,", "03000000d62000006dca000000000000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "03000000d62000009557000000000000,Pro Elite PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", @@ -209,11 +267,19 @@ static const char *s_ControllerMappings [] = "03000000300f00001611000000000000,QanBa Arcade JoyStick 4018,a:b1,b:b2,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,", "03000000300f00001210000000000000,QanBa Joystick Plus,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b2,y:b3,", "03000000341a00000104000000000000,QanBa Joystick Q4RAF,a:b5,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b0,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b7,start:b9,x:b1,y:b2,", - "03000000222c00000223000000000000,Qanba Obsidian Arcade Joystick PS3 Mode,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", - "03000000222c00000023000000000000,Qanba Obsidian Arcade Joystick PS4 Mode,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", + "03000000222c00000025000000000000,Qanba Dragon Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", + "03000000222c00000223000000000000,Qanba Obsidian Arcade Joystick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", + "03000000222c00000023000000000000,Qanba Obsidian Arcade Joystick (PS4),a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "030000000d0f00001100000000000000,REAL ARCADE PRO.3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,", "030000000d0f00007000000000000000,REAL ARCADE PRO.4 VLX,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,", "030000000d0f00002200000000000000,REAL ARCADE Pro.V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", + "03000000050b00005819000000000000,ROG Chakram Core,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,", + "03000000050b0000181a000000000000,ROG Chakram X,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,", + "03000000050b00001a1a000000000000,ROG Chakram X,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,", + "03000000050b00001c1a000000000000,ROG Chakram X,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,", + "03000000050b0000e318000000000000,ROG Chakram,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,", + "03000000050b0000e518000000000000,ROG Chakram,a:b1,b:b0,leftx:a0,lefty:a1,x:b2,y:b3,", + "030000000d0f0000ad00000000000000,RX Gamepad,a:b0,b:b4,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b3,rightshoulder:b6,start:b9,x:b2,y:b1,", "03000000321500000003000000000000,Razer Hydra,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "03000000321500000204000000000000,Razer Panthera (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "03000000321500000104000000000000,Razer Panthera (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", @@ -229,15 +295,19 @@ static const char *s_ControllerMappings [] = "030000000d0f00005c00000000000000,Real Arcade Pro.V4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "0300000000f000000300000000000000,RetroUSB.com RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,", "0300000000f00000f100000000000000,RetroUSB.com Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,", - "03000000790000001100000000000000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,", + "03000000790000001100000000000000,Retrolink SNES Controller,a:b1,b:b2,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b9,x:b0,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000790000001100000000000000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "030000006b140000130d000000000000,Revolution Pro Controller 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "030000006b140000010d000000000000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "030000006f0e00001e01000000000000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "030000006f0e00002801000000000000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "030000006f0e00002f01000000000000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "03000000341a00000208000000000000,SL-6555-SBK,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:-a4,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a3,righty:a2,start:b7,x:b2,y:b3,", "03000000341a00000908000000000000,SL-6566,a:b0,b:b1,back:b8,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:a2,righty:a3,start:b9,x:b2,y:b3,", + "03000000790000000600000000000000,SPEEDLINK STRIKE Gamepad,crc:5811,a:b2,b:b1,back:b8,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:a2,righty:a4,start:b9,x:b3,y:b0,", "03000000790000001c18000000000000,STK-7024X,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,", "03000000ff1100003133000000000000,SVEN X-PAD,a:b2,b:b3,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a4,start:b5,x:b0,y:b1,", + "03000000457500002211000000000000,SZMY-POWER PC Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "03000000a306000023f6000000000000,Saitek Cyborg V.1 Game pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,", "03000000a30600001af5000000000000,Saitek Cyborg,a:b1,b:b2,back:b8,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:a4,start:b9,x:b0,y:b3,", "03000000300f00001201000000000000,Saitek Dual Analog Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,", @@ -249,11 +319,12 @@ static const char *s_ControllerMappings [] = "03000000a30600002106000000000000,Saitek PS1000,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,", "03000000a306000020f6000000000000,Saitek PS2700,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,", "03000000300f00001101000000000000,Saitek Rumble Pad,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,", + "03000000790000000600000000000000,Sanwa Supply JY-P76USV,crc:20f0,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b2,y:b3,", "0300000000050000289b000000000000,Saturn_Adapter_2.0,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,", "030000009b2800000500000000000000,Saturn_Adapter_2.0,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,", "030000008f0e00000800000000000000,SpeedLink Strike FX,a:b2,b:b1,back:b8,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:a2,righty:a3,start:b9,x:b3,y:b0,", "03000000c01100000591000000000000,Speedlink Torid,a:b2,b:b1,back:b8,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:a2,righty:a3,start:b9,x:b3,y:b0,", - "03000000d11800000094000000000000,Stadia Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b11,rightx:a3,righty:a4,start:b9,x:b2,y:b3,", + "03000000de280000ff11000000000000,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "03000000110100003114000000000000,SteelSeries Stratus Duo,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,", "03000000381000001814000000000000,SteelSeries Stratus XL,a:b0,b:b1,back:b18,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b19,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b2,y:b3,", "03000000110100001914000000000000,SteelSeries,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:,leftstick:b13,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:,rightstick:b14,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b3,y:b4,", @@ -261,6 +332,7 @@ static const char *s_ControllerMappings [] = "030000004f04000007d0000000000000,T Mini Wireless,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "03000000fa1900000706000000000000,Team 5,a:b2,b:b1,back:b8,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:a2,righty:a3,start:b9,x:b3,y:b0,", "03000000b50700001203000000000000,Techmobility X6-38V,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,", + "030000004f0400000ed0000000000000,ThrustMaster eSwap PRO Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "030000004f04000015b3000000000000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,", "030000004f04000023b3000000000000,Thrustmaster Dual Trigger 3-in-1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "030000004f04000004b3000000000000,Thrustmaster Firestorm Dual Power 3,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,", @@ -271,50 +343,92 @@ static const char *s_ControllerMappings [] = "03000000b80500000210000000000000,Trust Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,", "03000000d90400000200000000000000,TwinShock PS2,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,", "03000000300f00000701000000000000,USB 4-Axis 12-Button Gamepad,a:b2,b:b1,back:b8,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:b9,x:b3,y:b0,", + "03000000341a00002308000000000000,USB Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,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,", + "030000006b1400000203000000000000,USB Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,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,", + "03000000790000000a00000000000000,USB Gamepad,a:b2,b:b1,back:b8,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:a2,righty:a4,start:b9,x:b3,y:b0,", + "03000000f0250000c183000000000000,USB Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", + "03000000ff1100004133000000000000,USB Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a4,righty:a2,start:b9,x:b3,y:b0,", "03000000632500002305000000000000,USB Vibration Joystick (BM),a:b2,b:b1,back:b8,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:a2,righty:a3,start:b9,x:b3,y:b0,", - "03000000341a00002308000000000000,USB gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,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,", - "030000005509000000b4000000000000,USB gamepad,a:b10,b:b11,back:b5,dpdown:b1,dpleft:b2,dpright:b3,dpup:b0,guide:b14,leftshoulder:b8,leftstick:b6,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b7,righttrigger:a5,rightx:a2,righty:a3,start:b4,x:b12,y:b13,", - "030000006b1400000203000000000000,USB gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,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,", - "03000000790000000a00000000000000,USB gamepad,a:b2,b:b1,back:b8,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:a2,righty:a4,start:b9,x:b3,y:b0,", - "03000000f0250000c183000000000000,USB gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", - "03000000ff1100004133000000000000,USB gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a4,righty:a2,start:b9,x:b3,y:b0,", "03000000790000001b18000000000000,Venom Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,", "030000006f0e00000302000000000000,Victrix Pro Fight Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,", "030000006f0e00000702000000000000,Victrix Pro Fight Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,", "03000000450c00002043000000000000,XEOX Gamepad SL-6556-BK,a:b0,b:b1,back:b8,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:a2,righty:a3,start:b9,x:b2,y:b3,", "03000000341a00000608000000000000,Xeox,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,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,", "03000000172700004431000000000000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a7,rightx:a2,righty:a5,start:b11,x:b3,y:b4,", + "03000000c0160000e105000000000000,Xin-Mo Dual Arcade,crc:2246,a:b1,b:b2,back:b9,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,rightshoulder:b4,righttrigger:b5,start:b8,x:b0,y:b3,", /* Ultimate Atari Fight Stick */ "03000000790000004f18000000000000,ZD-T Android,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,", + "03000000120c0000101e000000000000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "03000000d81d00000f00000000000000,iBUFFALO BSGP1204 Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,", "03000000d81d00001000000000000000,iBUFFALO BSGP1204P Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,", - "03000000830500006020000000000000,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,", + "03000000830500006020000000000000,iBuffalo SNES Controller,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000830500006020000000000000,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,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", "030000004f04000003d0000000000000,run'n'drive,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b7,leftshoulder:a3,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:a4,rightstick:b11,righttrigger:b5,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "03000000101c0000171c000000000000,uRage Gamepad,a:b2,b:b1,back:b8,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:a2,righty:a3,start:b9,x:b3,y:b0,", #endif #if defined(__MACOSX__) - "03000000c82d00000090000001000000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,", - "03000000c82d00001038000000010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,", - "03000000c82d00000650000001000000,8BitDo M30 GamePad,a:b0,b:b1,back:b10,guide:b2,leftshoulder:b6,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a5,start:b11,x:b3,y:b4,", - "03000000c82d00005106000000010000,8BitDo M30 GamePad,a:b0,b:b1,back:b10,guide:b2,leftshoulder:b6,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,start:b11,x:b3,y:b4,", - "030000003512000012ab000001000000,8BitDo NES30 GamePad,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,", - "03000000022000000090000001000000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,", - "03000000203800000900000000010000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,", - "03000000102800000900000000000000,8BitDo SFC30 GamePad Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,", - "03000000c82d00000160000001000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,", - "03000000a00500003232000008010000,8BitDo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,", - "03000000a00500003232000009010000,8BitDo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,", + "03000000c82d00000090000001000000,8BitDo FC30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000090000001000000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00001038000000010000,8BitDo FC30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00001038000000010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000650000001000000,8BitDo M30 Gamepad,a:b0,b:b1,back:b10,guide:b2,leftshoulder:b6,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a5,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000650000001000000,8BitDo M30 Gamepad,a:b1,b:b0,back:b10,guide:b2,leftshoulder:b6,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a5,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00005106000000010000,8BitDo M30 Gamepad,a:b0,b:b1,back:b10,guide:b2,leftshoulder:b6,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00005106000000010000,8BitDo M30 Gamepad,a:b1,b:b0,back:b10,guide:b2,leftshoulder:b6,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00001590000001000000,8BitDo N30 Pro 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00001590000001000000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00006528000000010000,8BitDo N30 Pro 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00006528000000010000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "030000003512000012ab000001000000,8BitDo NES30 Gamepad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "030000003512000012ab000001000000,8BitDo NES30 Gamepad,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000022000000090000001000000,8BitDo NES30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000022000000090000001000000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000203800000900000000010000,8BitDo NES30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000203800000900000000010000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000660000000020000,8BitDo Pro 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000660000000020000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000102800000900000000000000,8BitDo SFC30 Gamepad,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000102800000900000000000000,8BitDo SFC30 Gamepad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00001290000001000000,8BitDo SN30 Gamepad,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00001290000001000000,8BitDo SN30 Gamepad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000260000001000000,8BitDo SN30 Pro+,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000260000001000000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000261000000010000,8BitDo SN30 Pro+,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000261000000010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000160000001000000,8BitDo SN30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000160000001000000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00001130000000020000,8BitDo Ultimate Wired Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b26,paddle1:b24,paddle2:b25,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", + "03000000c82d00001330000000020000,8BitDo Ultimate Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b26,paddle1:b23,paddle2:b19,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", + "03000000c82d00001890000001000000,8BitDo Zero 2,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00001890000001000000,8BitDo Zero 2,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00003032000000010000,8BitDo Zero 2,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00003032000000010000,8BitDo Zero 2,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000a00500003232000008010000,8BitDo Zero Gamepad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000a00500003232000008010000,8BitDo Zero Gamepad,a:b1,b:b2,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000a00500003232000009010000,8BitDo Zero Gamepad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000a00500003232000009010000,8BitDo Zero Gamepad,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000050b00000579000000010000,ASUS ROG Kunai 3 Gamepad,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b14,leftshoulder:b6,leftstick:b15,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b42,paddle1:b9,paddle2:b11,rightshoulder:b7,rightstick:b16,righttrigger:a4,rightx:a2,righty:a3,start:b13,x:b3,y:b4,", + "03000000050b00000679000000010000,ASUS ROG Kunai 3 Gamepad,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b14,leftshoulder:b6,leftstick:b15,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b23,rightshoulder:b7,rightstick:b16,righttrigger:a4,rightx:a2,righty:a3,start:b13,x:b3,y:b4,", + "03000000491900001904000001010000,Amazon Luna Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,", + "03000000710100001904000000010000,Amazon Luna Controller,a:b0,b:b1,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", + "03000000c62400001a89000000010000,BDA MOGA XP5-X Plus,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b14,leftshoulder:b6,leftstick:b15,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b16,righttrigger:a4,rightx:a2,righty:a3,start:b13,x:b3,y:b4,", + "03000000c62400001b89000000010000,BDA MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", "03000000d62000002a79000000010000,BDA PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "030000008305000031b0000000000000,Cideko AK08b,a:b1,b:b2,back:b8,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:a2,righty:a3,start:b9,x:b0,y:b3,", "03000000260900008888000088020000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,", "03000000a306000022f6000001030000,Cyborg V.3 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,", "030000000d0f00008400000000010000,Fighting Commander,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "030000000d0f00008500000000010000,Fighting Commander,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", - "03000000790000000600000000000000,G-Shark GP-702,a:b2,b:b1,back:b8,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:a4,start:b9,x:b3,y:b0,", + "03000000ac0500001a06000002020000,GameSir-T3 2.02,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", "0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,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:a2,righty:a3,start:b9,x:b2,y:b3,", + "03000000c01100000140000000010000,GameStop PS4 Fun Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "03000000ad1b000001f9000000000000,Gamestop BB-070 X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,", + "03000000d11800000094000000010000,Google Stadia 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:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,", "030000000d0f00005f00000000000000,HORI Fighting Commander 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "030000000d0f00005e00000000000000,HORI Fighting Commander 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", + "030000000d0f00008800000000010000,HORI Fighting Stick mini 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,", + "030000000d0f00008700000000010000,HORI Fighting Stick mini 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,", "030000000d0f00004d00000000000000,HORI Gem Pad 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", + "030000000d0f0000aa00000072050000,HORI Real Arcade Pro,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,", "030000000d0f00006e00000000010000,HORIPAD 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "030000000d0f00006600000000010000,HORIPAD 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "030000000d0f00006600000000000000,HORIPAD FPS PLUS 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", @@ -340,7 +454,10 @@ static const char *s_ControllerMappings [] = "03000000790000000018000000000000,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b4,b:b8,back:b32,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b16,leftstick:b40,lefttrigger:b24,leftx:a0,lefty:a4,rightshoulder:b20,rightstick:b44,righttrigger:b28,rightx:a8,righty:a12,start:b36,x:b0,y:b12,", "030000001008000001e5000006010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b6,start:b9,x:b3,y:b0,", "03000000550900001472000025050000,NVIDIA Controller v01.04,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,", + "030000004b120000014d000000010000,NYKO AIRFLO EX,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,", "030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,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,", + "050000007e05000009200000ff070000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000007e05000009200000ff070000,Nintendo Switch Pro Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", "030000006f0e00000901000002010000,PDP Versus Fighting Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,", "030000004c0500006802000000000000,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,", "030000004c0500006802000000010000,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,", @@ -348,7 +465,9 @@ static const char *s_ControllerMappings [] = "030000004c050000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "030000004c050000c405000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "030000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", + "050000004c050000e60c000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "030000008f0e00000300000000000000,Piranha xtreme,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,", + "03000000222c00000225000000010000,Qanba Dragon Arcade Joystick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "030000008916000000fd000000000000,Razer Onza TE,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,", "03000000321500000204000000010000,Razer Panthera (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "03000000321500000104000000010000,Razer Panthera (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", @@ -358,20 +477,24 @@ static const char *s_ControllerMappings [] = "03000000321500000009000000020000,Razer Serval,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:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,", "0300000032150000030a000000000000,Razer Wildcat,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,", "03000000790000001100000000000000,Retrolink Classic Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a3,lefty:a4,rightshoulder:b5,start:b9,x:b3,y:b0,", - "03000000790000001100000006010000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,", + "03000000790000001100000006010000,Retrolink SNES Controller,a:b1,b:b2,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b9,x:b0,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000790000001100000006010000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a4,dpleft:-a3,dpright:+a3,dpup:-a4,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "030000006b140000130d000000010000,Revolution Pro Controller 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "030000006b140000010d000000010000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "030000003512000021ab000000000000,SFC30 Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,", + "03000000457500002211000000010000,SZMY-POWER PC Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "03000000b40400000a01000000000000,Sega Saturn USB Gamepad,a:b0,b:b1,back:b5,guide:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,x:b3,y:b4,", "03000000811700007e05000000000000,Sega Saturn,a:b2,b:b4,dpdown:b16,dpleft:b15,dpright:b14,dpup:b17,leftshoulder:b8,lefttrigger:a5,leftx:a0,lefty:a2,rightshoulder:b9,righttrigger:a4,start:b13,x:b0,y:b6,", "030000004c050000cc09000000000000,Sony DualShock 4 V2,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "030000004c050000a00b000000000000,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", - "03000000d11800000094000000010000,Stadia 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:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,", "030000005e0400008e02000001000000,Steam Virtual Gamepad,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,", + "050000004e696d6275732b0000000000,SteelSeries Nimbus+,a:b0,b:b1,back:b15,dpdown:b11,dpleft:b13,dpright:b12,dpup:b10,guide:b16,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3~,start:b14,x:b2,y:b3,", "03000000110100002014000000000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b12,x:b2,y:b3,", "03000000110100002014000001000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,x:b2,y:b3,", "03000000381000002014000001000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,x:b2,y:b3,", "03000000110100001714000000000000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,start:b12,x:b2,y:b3,", "03000000110100001714000020010000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,start:b12,x:b2,y:b3,", + "030000004f0400000ed0000000020000,ThrustMaster eSwap PRO Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "030000004f04000015b3000000000000,Thrustmaster Dual Analog 3.2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,", "030000004f04000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,", "03000000bd12000015d0000000000000,Tomee SNES USB Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,", @@ -387,64 +510,135 @@ static const char *s_ControllerMappings [] = "030000005e040000d102000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,", "030000005e040000dd02000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,", "030000005e040000e302000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,", + "030000005e040000200b000011050000,Xbox Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", "030000005e040000e002000000000000,Xbox Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "030000005e040000e002000003090000,Xbox Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "030000005e040000ea02000000000000,Xbox Wireless Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,", "030000005e040000fd02000003090000,Xbox Wireless Controller,a:b0,b:b1,back:b16,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", "03000000172700004431000029010000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,", + "03000000c0160000e105000000040000,Xin-Mo Dual Arcade,crc:82d5,a:b2,b:b4,back:b18,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,rightshoulder:b8,righttrigger:b10,start:b16,x:b0,y:b6,", /* Ultimate Atari Fight Stick */ "03000000120c0000100e000000010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", - "03000000830500006020000000010000,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,", + "03000000120c0000101e000000010000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", + "03000000830500006020000000010000,iBuffalo SNES Controller,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000830500006020000000010000,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,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", "03000000830500006020000000000000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,", #endif -#if defined(__LINUX__) - "03000000c82d00000090000011010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,", - "05000000c82d00001038000000010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,", - "03000000c82d00000650000011010000,8BitDo M30 GamePad,a:b0,b:b1,back:b10,guide:b2,leftshoulder:b6,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a5,start:b11,x:b3,y:b4,", - "05000000c82d00005106000000010000,8BitDo M30 gamepad,a:b0,b:b1,back:b10,guide:b2,leftshoulder:b6,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,start:b11,x:b3,y:b4,", - "030000003512000012ab000010010000,8BitDo NES30 GamePad,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,", - "03000000022000000090000011010000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,", - "03000000c82d00000190000011010000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,", - "05000000203800000900000000010000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,", - "05000000c82d00002038000000010000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,", - "05000000c82d00000061000000010000,8BitDo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,", - "05000000102800000900000000010000,8BitDo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,", - "05000000c82d00003028000000010000,8BitDo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,", - "03000000c82d00000160000011010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,", - "05000000a00500003232000001000000,8BitDo Zero GamePad,a:b0,b:b1,back:b10,dpdown:b122,dpleft:b119,dpright:b120,dpup:b117,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,", - "05000000a00500003232000008010000,8BitDo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,", +#if defined(SDL_JOYSTICK_LINUX) || defined(__OpenBSD__) + "03000000c82d00000090000011010000,8BitDo FC30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000090000011010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d00001038000000010000,8BitDo FC30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d00001038000000010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000650000011010000,8BitDo M30 Gamepad,a:b0,b:b1,back:b10,guide:b2,leftshoulder:b6,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a5,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d00005106000000010000,8BitDo M30 Gamepad,a:b1,b:b0,back:b10,guide:b2,leftshoulder:b6,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00001590000011010000,8BitDo N30 Pro 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00001590000011010000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d00006528000000010000,8BitDo N30 Pro 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d00006528000000010000,8BitDo N30 Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "030000003512000012ab000010010000,8BitDo NES30 Gamepad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "030000003512000012ab000010010000,8BitDo NES30 Gamepad,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000022000000090000011010000,8BitDo NES30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000022000000090000011010000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000190000011010000,8BitDo NES30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000190000011010000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000203800000900000000010000,8BitDo NES30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000203800000900000000010000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d00002038000000010000,8BitDo NES30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d00002038000000010000,8BitDo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000020000000000000,8BitDo Pro 2 Wired Controller for Xbox,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,", + "06000000c82d00000020000006010000,8BitDo Pro 2 Wired Controller for Xbox,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,", + "03000000c82d00000660000011010000,8BitDo Pro 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000660000011010000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d00000660000000010000,8BitDo Pro 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d00000660000000010000,8BitDo Pro 2,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d00000061000000010000,8BitDo SF30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d00000061000000010000,8BitDo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000102800000900000000010000,8BitDo SFC30 Gamepad,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000102800000900000000010000,8BitDo SFC30 Gamepad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d00003028000000010000,8BitDo SFC30 Gamepad,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d00003028000000010000,8BitDo SFC30 Gamepad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000260000011010000,8BitDo SN30 Pro+,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000260000011010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d00000261000000010000,8BitDo SN30 Pro+,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d00000261000000010000,8BitDo SN30 Pro+,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000160000011010000,8BitDo SN30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000160000011010000,8BitDo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "030000003512000020ab000010010000,8BitDo SNES30 Gamepad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "030000003512000020ab000010010000,8BitDo SNES30 Gamepad,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000202800000900000000010000,8BitDo SNES30 Gamepad,a:b0,b:b1,back:b10,dpdown:b122,dpleft:b119,dpright:b120,dpup:b117,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000202800000900000000010000,8BitDo SNES30 Gamepad,a:b1,b:b0,back:b10,dpdown:b122,dpleft:b119,dpright:b120,dpup:b117,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00001130000011010000,8BitDo Ultimate Wired Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b26,paddle1:b24,paddle2:b25,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", + "03000000c82d00001330000011010000,8BitDo Ultimate Wireless Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b26,paddle1:b23,paddle2:b19,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", + "03000000c82d00001890000011010000,8BitDo Zero 2,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00001890000011010000,8BitDo Zero 2,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d00003032000000010000,8BitDo Zero 2,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d00003032000000010000,8BitDo Zero 2,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000a00500003232000001000000,8BitDo Zero Gamepad,a:b0,b:b1,back:b10,dpdown:b122,dpleft:b119,dpright:b120,dpup:b117,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000a00500003232000001000000,8BitDo Zero Gamepad,a:b1,b:b0,back:b10,dpdown:b122,dpleft:b119,dpright:b120,dpup:b117,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000a00500003232000008010000,8BitDo Zero Gamepad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000a00500003232000008010000,8BitDo Zero Gamepad,a:b1,b:b0,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00000031000011010000,8Bitdo Receiver,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,", + "03000000c82d00001290000011010000,8Bitdo SN30 Gamepad,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000c82d00001290000011010000,8Bitdo SN30 Gamepad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d00006228000000010000,8Bitdo SN30 Gamepad,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d00006228000000010000,8Bitdo SN30 Gamepad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", "05000000050b00000045000031000000,ASUS Gamepad,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,", "05000000050b00000045000040000000,ASUS Gamepad,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,", + "03000000050b00000579000011010000,ASUS ROG Kunai 3 Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b36,paddle1:b52,paddle2:b53,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", + "05000000050b00000679000000010000,ASUS ROG Kunai 3 Gamepad,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b21,paddle1:b22,paddle2:b23,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", "030000006f0e00003901000020060000,Afterglow Controller for Xbox 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,", "030000006f0e00003901000000430000,Afterglow Prismatic 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,", "030000006f0e00001302000000010000,Afterglow,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,", "03000000100000008200000011010000,Akishop Customs PS360+ v1.66,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,", + "05000000491900000204000021000000,Amazon Fire Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b17,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b12,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", + "03000000491900001904000011010000,Amazon Luna Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b9,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b7,x:b2,y:b3,", + "05000000710100001904000000010000,Amazon Luna Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", + "03000000790000003018000011010000,Arcade Fightstick F300,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,", + "03000000503200000110000000000000,Atari Classic Controller,a:b0,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,x:b1,", + "05000000503200000110000000000000,Atari Classic Controller,a:b0,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b4,start:b3,x:b1,", + "03000000503200000210000000000000,Atari Game Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a4,rightx:a2,righty:a3,start:b8,x:b2,y:b3,", + "05000000503200000210000000000000,Atari Game 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:b3,y:b2,", + "05000000503200000210000000000000128804098,Atari Game 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:b3,y:b2,", + "030000005e0400008e02000047010000,Atari Xbox 360 Game 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,", + "03000000c62400001b89000011010000,BDA MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", "03000000d62000002a79000011010000,BDA PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", + "03000000120c0000f70e000011010000,Brook Universal Fighting Board,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:,lefty:,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:,righty:,start:b9,x:b0,y:b3,", "03000000b40400000a01000000010000,CYPRESS USB Gamepad,a:b0,b:b1,back:b5,guide:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,x:b3,y:b4,", "03000000ffff0000ffff000000010000,Chinese-made Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,", "03000000e82000006058000001010000,Cideko AK08b,a:b2,b:b1,back:b8,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:a2,righty:a3,start:b9,x:b3,y:b0,", "03000000260900008888000000010000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,", "03000000a306000022f6000011010000,Cyborg V.3 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,", - "03000000790000000600000010010000,DragonRise Inc. Generic USB Joystick,a:b2,b:b1,back:b8,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:a4,start:b9,x:b3,y:b0,", + "050000004c050000f20d000000010000,DualSense Edge Wireless Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "030000006f0e00003001000001010000,EA Sports PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", + "03000000790000001100000010010000,Elecom Gamepad,crc:e86c,a:b2,b:b3,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b0,y:b1,", "0300000079000000d418000000010000,GPD Win 2 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,", - "0500000047532067616d657061640000,GS gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,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,", + "0500000047532067616d657061640000,GS Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,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,", "03000000341a000005f7000010010000,GameCube {HuiJia USB box},a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,", "03000000bc2000000055000011010000,GameSir G3w,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", + "0500000049190000020400001b010000,GameSir T4 Pro,crc:8283,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b23,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", + "03000000ac0500001a06000011010000,GameSir-T3 2.02,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", "0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,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:a2,righty:a3,start:b9,x:b2,y:b3,", + "03000000c01100000140000011010000,GameStop PS4 Fun Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "030000006f0e00000104000000010000,Gamestop Logic3 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,", "030000008f0e00000800000010010000,Gasia Co. Ltd PS(R) Gamepad,a:b2,b:b1,back:b8,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:a2,righty:a3,start:b9,x:b3,y:b0,", "030000006f0e00001304000000010000,Generic X-Box pad,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,", "03000000f0250000c183000010010000,Goodbetterbest Ltd USB Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", - "03000000280400000140000000010000,Gravis GamePad Pro USB ,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,", - "030000008f0e00000610000000010000,GreenAsia Electronics 4Axes 12Keys GamePad ,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,", + "03000000d11800000094000011010000,Google Stadia 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:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,", + "05000000d11800000094000000010000,Google Stadia 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:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,", + "03000000280400000140000000010000,Gravis Gamepad Pro USB ,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,", + "030000008f0e00000610000000010000,GreenAsia Electronics 4Axes 12Keys Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,", "030000008f0e00001200000010010000,GreenAsia Inc. USB Joystick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,", "03000000c9110000f055000011010000,HJC Game GAMEPAD,a:b0,b:b1,back:b8,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:a2,righty:a3,start:b9,x:b2,y:b3,", "030000000d0f00001000000011010000,HORI CO. LTD. FIGHTING STICK 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,", "030000000d0f00002200000011010000,HORI CO. LTD. REAL ARCADE Pro.V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,", "030000000d0f00006a00000011010000,HORI CO. LTD. Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "030000000d0f00006b00000011010000,HORI CO. LTD. Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", + "030000000d0f00005001000009040000,HORI Fighting Commander OCTA,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,", "030000000d0f00008400000011010000,HORI Fighting Commander,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "030000000d0f00008500000010010000,HORI Fighting Commander,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", + "030000000d0f00008800000011010000,HORI Fighting Stick mini 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,", + "030000000d0f00008700000011010000,HORI Fighting Stick mini 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,rightshoulder:b5,rightstick:b11,righttrigger:a4,start:b9,x:b0,y:b3,", + "030000000d0f0000d800000072056800,HORI Real Arcade Pro S,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,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,", + "030000000d0f0000aa00000011010000,HORI Real Arcade Pro,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,", "030000000d0f00006e00000011010000,HORIPAD 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "030000000d0f00006600000011010000,HORIPAD 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "030000000d0f00006700000001010000,HORIPAD 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,", @@ -458,10 +652,12 @@ static const char *s_ControllerMappings [] = "03000000242e00008816000001010000,Hyperkin X91,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,", "03000000d80400008200000003000000,IMS PCU#0 Gamepad Interface,a:b1,b:b0,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b5,x:b3,y:b2,", "03000000fd0500000030000000010000,InterAct GoPad I-73000 (Fighting Game Layout),a:b3,b:b4,back:b6,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,start:b7,x:b0,y:b1,", + "05000000491900000204000000000000,Ipega PG-9087S,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", "030000006e0500000320000010010000,JC-U3613M - DirectInput Mode,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,", "03000000300f00001001000010010000,Jess Tech Dual Analog Rumble Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,", "03000000ba2200002010000001010000,Jess Technology USB Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,", "030000006f0e00000103000000020000,Logic3 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,", + "030000006d040000d1ca000011010000,Logitech Chillstream,a:b1,b:b2,back:b8,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:a2,righty:a3,start:b9,x:b0,y:b3,", "030000006d04000019c2000010010000,Logitech Cordless RumblePad 2,a:b1,b:b2,back:b8,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:a2,righty:a3,start:b9,x:b0,y:b3,", "030000006d04000016c2000010010000,Logitech Dual Action,a:b1,b:b2,back:b8,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:a2,righty:a3,start:b9,x:b0,y:b3,", "030000006d04000016c2000011010000,Logitech Dual Action,a:b1,b:b2,back:b8,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:a2,righty:a3,start:b9,x:b0,y:b3,", @@ -469,11 +665,11 @@ static const char *s_ControllerMappings [] = "030000006d0400001ec2000020200000,Logitech F510 Gamepad (XInput),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,", "030000006d04000019c2000011010000,Logitech F710 Gamepad (DInput),a:b1,b:b2,back:b8,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:a2,righty:a3,start:b9,x:b0,y:b3,", /* Guide button doesn't seem to be sent in DInput mode. */ "030000006d0400001fc2000005030000,Logitech F710 Gamepad (XInput),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,", - "030000006d04000015c2000010010000,Logitech Logitech Extreme 3D,a:b0,b:b4,back:b6,guide:b8,leftshoulder:b9,leftstick:h0.8,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:h0.2,start:b7,x:b2,y:b5,", "030000006d04000018c2000010010000,Logitech RumblePad 2,a:b1,b:b2,back:b8,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:a2,righty:a3,start:b9,x:b0,y:b3,", "030000006d04000011c2000010010000,Logitech WingMan Cordless RumblePad,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b10,rightx:a3,righty:a4,start:b8,x:b3,y:b4,", "03000000c62400002b89000011010000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", "05000000c62400002a89000000010000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b22,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", + "05000000c62400001a89000000010000,MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", "03000000250900006688000000010000,MP-8866 Super Dual Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,", "05000000380700006652000025010000,Mad Catz C.T.R.L.R ,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "03000000380700005032000011010000,Mad Catz FightPad PRO (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", @@ -497,16 +693,41 @@ static const char *s_ControllerMappings [] = "030000005e040000d102000001010000,Microsoft X-Box One pad,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,", "030000005e0400008502000000010000,Microsoft X-Box pad (Japan),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,", "030000005e0400008902000021010000,Microsoft X-Box pad v2 (US),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,", + "030000005e0400008902000020010000,Microsoft Xbox Controller S,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,", "05000000d6200000ad0d000001000000,Moga Pro,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", "030000006b140000010c000010010000,NACON GC-400ES,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,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,", "030000001008000001e5000010010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b6,start:b9,x:b3,y:b0,", "03000000550900001472000011010000,NVIDIA Controller v01.04,a:b0,b:b1,back:b14,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b17,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,", "03000000550900001072000011010000,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b8,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,", + "030000004b120000014d000000010000,NYKO AIRFLO EX,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,", "03000000451300000830000010010000,NYKO CORE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", - "03000000790000004318000010010000,Nintendo GameCube Controller,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,", - "030000007e0500003703000000016800,Nintendo GameCube Controller,a:b0,b:b2,dpdown:b6,dpleft:b4,dpright:b5,dpup:b7,lefttrigger:a4,leftx:a0,lefty:a1~,rightshoulder:b9,righttrigger:a5,rightx:a2,righty:a3~,start:b8,x:b1,y:b3,", - "050000007e0500000920000001000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,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,", - "050000007e0500003003000001000000,Nintendo Wii Remote Pro Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,", + "03000000790000004318000010010000,Nintendo GameCube Controller,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000790000004318000010010000,Nintendo GameCube Controller,a:b1,b:b0,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000007e0500000620000001800000,Nintendo Switch Joy-Con (L),a:b15,b:b16,guide:b4,leftshoulder:b6,leftstick:b12,leftx:a1,lefty:a0~,rightshoulder:b8,start:b9,x:b17,y:b14,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000007e0500000620000001800000,Nintendo Switch Joy-Con (L),a:b16,b:b15,guide:b4,leftshoulder:b6,leftstick:b12,leftx:a1,lefty:a0~,rightshoulder:b8,start:b9,x:b14,y:b17,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "060000007e0500000620000000000000,Nintendo Switch Joy-Con (L/R),a:b1,b:b0,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "060000007e0500000620000000000000,Nintendo Switch Joy-Con (L/R),a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "060000007e0500000820000000000000,Nintendo Switch Joy-Con (L/R),a:b1,b:b0,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "060000007e0500000820000000000000,Nintendo Switch Joy-Con (L/R),a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000007e0500000720000001800000,Nintendo Switch Joy-Con (R),a:b2,b:b1,guide:b9,leftshoulder:b4,leftstick:b10,leftx:a1~,lefty:a0,rightshoulder:b6,start:b8,x:b3,y:b0,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000007e0500000720000001800000,Nintendo Switch Joy-Con (R),a:b1,b:b2,guide:b9,leftshoulder:b4,leftstick:b10,leftx:a1~,lefty:a0,rightshoulder:b6,start:b8,x:b0,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000d620000013a7000011010000,Nintendo Switch PowerA Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000d620000013a7000011010000,Nintendo Switch PowerA Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000d620000011a7000011010000,Nintendo Switch PowerA Core Plus Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000d620000011a7000011010000,Nintendo Switch PowerA Core Plus Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "030000007e0500000920000011810000,Nintendo Switch Pro Controller,a:b1,b:b0,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "030000007e0500000920000011810000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,misc1:b4,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000004c69632050726f20436f6e00,Nintendo Switch Pro Controller,crc:15b7,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000004c69632050726f20436f6e00,Nintendo Switch Pro Controller,crc:15b7,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000007e0500000920000001000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,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,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000007e0500000920000001000000,Nintendo Switch Pro Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000007e0500000920000001800000,Nintendo Switch Pro Controller,a:b1,b:b0,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000007e0500000920000001800000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000007e0500000603000000060000,Nintendo Wii Remote Classic Controller,crc:0d8a,a:b0,b:b1,back:b10,dpdown:b14,dpleft:b12,dpright:b13,dpup:b11,guide:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,start:b9,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000007e0500000603000000060000,Nintendo Wii Remote Classic Controller,crc:0d8a,a:b1,b:b0,back:b10,dpdown:b14,dpleft:b12,dpright:b13,dpup:b11,guide:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,start:b9,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000007e0500003003000001000000,Nintendo Wii Remote Pro Controller,a:b1,b:b0,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000007e0500003003000001000000,Nintendo Wii Remote Pro Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000007e0500000603000000060000,Nintendo Wii Remote,crc:60be,a:b1,b:b0,back:b4,dpdown:b8,dpleft:b6,dpright:b7,dpup:b5,guide:b2,start:b3,x:b9,y:b10,", "05000000010000000100000003000000,Nintendo Wiimote,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,", "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,", @@ -540,11 +761,23 @@ static const char *s_ControllerMappings [] = "050000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "050000004c050000cc09000000810000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,", "050000004c050000cc09000001800000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,", + "030000004c050000e60c000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", + "030000004c050000e60c000011010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", + "030000004c050000e60c000011810000,PS5 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,", + "050000004c050000e60c000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,misc1:b13,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", + "050000004c050000e60c000000810000,PS5 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,", "030000004c050000da0c000011010000,Playstation 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,", + "03000000c62400003a54000001010000,PowerA XBox One Controller,a:b0,b:b1,back:b6,dpdown:h0.7,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,", "03000000c62400000053000000010000,PowerA,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,", "03000000300f00001211000011010000,QanBa Arcade JoyStick,a:b2,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b9,x:b1,y:b3,", + "03000000222c00000225000011010000,Qanba Dragon Arcade Joystick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", + "03000000222c00000025000011010000,Qanba Dragon Arcade Joystick (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", + "03000000222c00001020000011010000,Qanba Drone 2 Arcade Joystick (PS5),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", + "03000000222c00001220000011010000,Qanba Drone 2 Arcade Joystick (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", + "03000000222c00000020000011010000,Qanba Drone Arcade Joystick (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,rightshoulder:b5,righttrigger:a4,start:b9,x:b0,y:b3,", + "03000000222c00000223000011010000,Qanba Obsidian Arcade Joystick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", + "03000000222c00000023000011010000,Qanba Obsidian Arcade Joystick (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "030000008916000001fd000024010000,Razer Onza Classic Edition,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,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,", - "030000008916000000fd000024010000,Razer Onza Tournament Edition,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,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,", "03000000321500000204000011010000,Razer Panthera (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "03000000321500000104000011010000,Razer Panthera (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "03000000321500000010000011010000,Razer RAIJU,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", @@ -557,13 +790,16 @@ static const char *s_ControllerMappings [] = "050000003215000000090000163a0000,Razer Serval,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:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,", "0300000032150000030a000001010000,Razer Wildcat,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,", "0300000000f000000300000000010000,RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,", - "03000000790000001100000010010000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,", + "03000000790000001100000010010000,Retrolink SNES Controller,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b0,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "03000000790000001100000010010000,Retrolink SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b3,y:b0,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "030000006b140000130d000011010000,Revolution Pro Controller 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "030000006b140000010d000011010000,Revolution Pro Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "030000006f0e00001e01000011010000,Rock Candy PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "030000006f0e00004601000001010000,Rock Candy Xbox One Controller,a:b0,b:b1,back:b6,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,", "030000006f0e00001f01000000010000,Rock Candy,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,", "03000000632500007505000010010000,SHANWAN PS3/PC Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,", "03000000341a00000908000010010000,SL-6566,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,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,", + "03000000457500002211000010010000,SZMY-POWER PC Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", "03000000a306000023f6000011010000,Saitek Cyborg V.1 Game Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,", "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,", "03000000a30600000c04000011010000,Saitek P2900 Wireless Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b12,x:b0,y:b3,", @@ -576,20 +812,27 @@ static const char *s_ControllerMappings [] = "03000000250900000500000000010000,Sony PS2 pad with SmartJoy adapter,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,", "030000005e0400008e02000020200000,SpeedLink XEOX Pro Analog Gamepad pad,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,", "030000005e0400008e02000073050000,Speedlink TORID Wireless 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,", - "03000000d11800000094000011010000,Stadia 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:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,", - "03000000de2800000112000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,", - "03000000de2800000211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,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,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,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,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,", + "03000000de2800000112000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:+a5,dpleft:-a4,dpright:+a4,dpup:-a5,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,paddle1:b15,paddle2:b16,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a3,start:b11,x:b4,y:b5,", + "03000000de2800000211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,", + "03000000de2800000211000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:+a5,dpleft:-a4,dpright:+a4,dpup:-a5,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,paddle1:b15,paddle2:b16,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a3,start:b11,x:b4,y:b5,", + "03000000de2800004211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,", + "03000000de2800004211000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:+a5,dpleft:-a4,dpright:+a4,dpup:-a5,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,paddle1:b15,paddle2:b16,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a3,start:b11,x:b4,y:b5,", "03000000de280000fc11000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,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,", - "05000000de2800000212000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,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,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,", - "05000000de2800000611000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,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,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,", + "05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,", + "05000000de2800000611000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,", + "03000000de2800000512000011010000,Steam Deck,a:b3,b:b4,back:b11,dpdown:b17,dpleft:b18,dpright:b19,dpup:b16,guide:b13,leftshoulder:b7,leftstick:b14,lefttrigger:a9,leftx:a0,lefty:a1,misc1:b2,paddle1:b21,paddle2:b20,paddle3:b23,paddle4:b22,rightshoulder:b8,rightstick:b15,righttrigger:a8,rightx:a2,righty:a3,start:b12,x:b5,y:b6,", + "03000000de2800000512000000016800,Steam Deck,a:b0,b:b1,x:b2,y:b3,back:b4,guide:b5,start:b6,leftstick:b7,rightstick:b8,leftshoulder:b9,rightshoulder:b10,dpup:b11,dpdown:b12,dpleft:b13,dpright:b14,misc1:b15,paddle1:b16,paddle2:b17,paddle3:b18,paddle4:b19,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,", "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,", "0500000011010000311400001b010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b32,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", + "05000000110100001914000009010000,SteelSeries Stratus XL,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b18,leftshoulder:b6,leftstick:b13,lefttrigger:+a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:+a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", "03000000ad1b000038f0000090040000,Street Fighter IV FightStick TE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "03000000666600000488000000010000,Super Joy Box 5 Pro,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,", "0300000000f00000f100000000010000,Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,", + "030000004f0400000ed0000011010000,ThrustMaster eSwap PRO Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "030000004f04000020b3000010010000,Thrustmaster 2 in 1 DT,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,", + "030000004f04000015b3000001010000,Thrustmaster Dual Analog 3.2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,", "030000004f04000015b3000010010000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,", "030000004f04000023b3000000010000,Thrustmaster Dual Trigger 3-in-1,a:b1,b:b2,back:b8,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:a2,righty:a5,start:b9,x:b0,y:b3,", "030000004f04000000b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,", @@ -600,7 +843,6 @@ static const char *s_ControllerMappings [] = "03000000100800000100000010010000,Twin USB PS2 Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,", "03000000100800000300000010010000,USB Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,", "03000000790000001100000000010000,USB Gamepad1,a:b2,b:b1,back:b8,dpdown:a0,dpleft:a1,dpright:a2,dpup:a4,start:b9,", - "03000000790000000600000007010000,USB gamepad,a:b2,b:b1,back:b8,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:a4,start:b9,x:b3,y:b0,", "05000000ac0500003232000001000000,VR-BOX,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b2,y:b3,", "030000006f0e00000302000011010000,Victrix Pro Fight Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,", "030000006f0e00000702000011010000,Victrix Pro Fight Stick for PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,", @@ -611,63 +853,149 @@ static const char *s_ControllerMappings [] = "030000005e040000a102000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,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,", "030000005e040000a102000007010000,X360 Wireless 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,", "03000000450c00002043000010010000,XEOX Gamepad SL-6556-BK,a:b0,b:b1,back:b8,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:a2,righty:a3,start:b9,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,", "0000000058626f782033363020576900,Xbox 360 Wireless Controller,a:b0,b:b1,back:b14,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,guide:b7,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,", "030000005e040000a102000014010000,Xbox 360 Wireless Receiver (XBOX),a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,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,", "0000000058626f782047616d65706100,Xbox Gamepad (userspace driver),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:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,", - "050000005e040000050b000002090000,Xbox One Elite Series 2,a:b0,b:b1,back:b136,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", - "050000005e040000050b000003090000,Xbox One Elite Series 2,a:b0,b:b1,back:b121,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", - "030000005e040000ea02000000000000,Xbox One Wireless 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,", - "030000005e040000ea02000001030000,Xbox One Wireless 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,", "050000005e040000e002000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "050000005e040000fd02000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,guide:b16,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", "05000000172700004431000029010000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,", - "03000000c0160000e105000001010000,Xin-Mo Xin-Mo Dual Arcade,a:b4,b:b3,back:b6,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b9,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b1,y:b0,", + "03000000c0160000e105000010010000,Xin-Mo Dual Arcade,crc:82d5,a:b1,b:b2,back:b9,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,rightshoulder:b4,righttrigger:b5,start:b8,x:b0,y:b3,", /* Ultimate Atari Fight Stick */ "03000000120c0000100e000011010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", + "03000000120c0000101e000011010000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "03000000666600006706000000010000,boom PSX to PC Converter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,", - "030000000d0f00000d00000000010000,hori,a:b0,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b3,leftx:b4,lefty:b5,rightshoulder:b7,start:b9,x:b1,y:b2,", - "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,", + "03000000830500006020000010010000,iBuffalo SNES Controller,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "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,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", "050000006964726f69643a636f6e0000,idroid:con,a:b1,b:b2,back:b8,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:a2,righty:a3,start:b9,x:b0,y:b3,", "03000000b50700001503000010010000,impact,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,", + "030000009b2800008000000020020000,raphnet technologies 1-player WUSBMote v2.2,a:b1,b:b4,back:b2,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,leftshoulder:b6,rightshoulder:b7,start:b3,x:b0,y:b5,", "030000009b2800000300000001010000,raphnet.net 4nes4snes v1.5,a:b0,b:b4,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,", #endif +#if defined(__OpenBSD__) + "030000004c050000c405000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", + "030000004c050000e60c000000010000,PS5 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", + "030000005e0400008e02000010010000,Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1~,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4~,start:b7,x:b2,y:b3,", +#endif #if defined(__ANDROID__) - "05000000d6020000e5890000dfff3f00,GPD XD Plus,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,", + "05000000c82d000006500000ffff3f00,8BitDo M30 Gamepad,a:b0,b:b1,back:b4,guide:b17,leftshoulder:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a4,start:b6,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000006500000ffff3f00,8BitDo M30 Gamepad,a:b1,b:b0,back:b4,guide:b17,leftshoulder:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a4,start:b6,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000051060000ffff3f00,8BitDo M30 Gamepad,a:b0,b:b1,back:b4,guide:b17,leftshoulder:b9,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a5,start:b6,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000051060000ffff3f00,8BitDo M30 Gamepad,a:b1,b:b0,back:b4,guide:b17,leftshoulder:b9,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a5,start:b6,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000015900000ffff3f00,8BitDo N30 Pro 2,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000015900000ffff3f00,8BitDo N30 Pro 2,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000065280000ffff3f00,8BitDo N30 Pro 2,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b17,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,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000065280000ffff3f00,8BitDo N30 Pro 2,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b17,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000000220000000900000ffff3f00,8BitDo NES30 Pro,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,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,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000000220000000900000ffff3f00,8BitDo NES30 Pro,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000002038000009000000ffff3f00,8BitDo NES30 Pro,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,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,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000002038000009000000ffff3f00,8BitDo NES30 Pro,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000000600000ffff3f00,8BitDo SF30 Pro,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:b15,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b16,rightx:a2,righty:a3,start:b6,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000000600000ffff3f00,8BitDo SF30 Pro,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:b15,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b16,rightx:a2,righty:a3,start:b6,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000000610000ffff3f00,8BitDo SF30 Pro,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,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,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000000610000ffff3f00,8BitDo SF30 Pro,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000012900000ffff3f00,8BitDo SN30 Gamepad,a:b0,b:b1,back:b4,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000012900000ffff3f00,8BitDo SN30 Gamepad,a:b1,b:b0,back:b4,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000062280000ffff3f00,8BitDo SN30 Gamepad,a:b0,b:b1,back:b4,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000062280000ffff3f00,8BitDo SN30 Gamepad,a:b1,b:b0,back:b4,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000002600000ffff0f00,8BitDo SN30 Pro+,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b17,leftshoulder:b9,leftstick:b7,lefttrigger:b15,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b16,rightx:a2,righty:a3,start:b6,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000002600000ffff0f00,8BitDo SN30 Pro+,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b17,leftshoulder:b9,leftstick:b7,lefttrigger:b15,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b16,rightx:a2,righty:a3,start:b6,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000001600000ffff3f00,8BitDo SN30 Pro,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000001600000ffff3f00,8BitDo SN30 Pro,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000002028000009000000ffff3f00,8BitDo SNES30 Gamepad,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,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,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000002028000009000000ffff3f00,8BitDo SNES30 Gamepad,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000003512000020ab000000780f00,8BitDo SNES30 Gamepad,a:b20,b:b21,back:b30,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b26,rightshoulder:b27,start:b31,x:b23,y:b24,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000003512000020ab000000780f00,8BitDo SNES30 Gamepad,a:b21,b:b20,back:b30,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b26,rightshoulder:b27,start:b31,x:b24,y:b23,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000018900000ffff0f00,8BitDo Zero 2,a:b0,b:b1,back:b4,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000018900000ffff0f00,8BitDo Zero 2,a:b1,b:b0,back:b4,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000030320000ffff0f00,8BitDo Zero 2,a:b0,b:b1,back:b4,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000c82d000030320000ffff0f00,8BitDo Zero 2,a:b1,b:b0,back:b4,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "05000000d6020000e5890000dfff3f80,GPD XD Plus,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a3,rightx:a4,righty:a5,start:b6,x:b2,y:b3,", "0500000031366332860c44aadfff0f00,GS Gamepad,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:b15,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b16,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", "05000000bc20000000550000ffff3f00,GameSir G3w,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", "050000005509000003720000cf7f3f00,NVIDIA Controller v01.01,a:b0,b:b1,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,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,", "050000005509000010720000ffff3f00,NVIDIA Controller v01.03,a:b0,b:b1,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,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,", - "050000005509000014720000df7f3f00,NVIDIA Controller v01.04,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,", - "050000007e05000009200000ffff0f00,Nintendo Switch Pro Controller,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:b15,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b16,rightx:a2,righty:a3,sdk>=:29,start:b6,x:b3,y:b2,", - "050000007e05000009200000ffff0f00,Nintendo Switch Pro Controller,a:b0,b:b1,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:b10,rightx:a2,righty:a3,sdk<=:28,start:b16,x:b17,y:b2,", /* Extremely slow in Bluetooth mode on Android */ + "050000005509000014720000df7f3f80,NVIDIA Controller v01.04,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a3,rightx:a4,righty:a5,start:b6,x:b2,y:b3,", + "050000007e05000009200000ffff0f00,Nintendo Switch Pro Controller,a:b1,b:b0,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:b15,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b16,rightx:a2,righty:a3,start:b6,x:b3,y:b2,sdk>=:29,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000007e05000009200000ffff0f00,Nintendo Switch Pro Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:b15,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b16,rightx:a2,righty:a3,start:b6,x:b2,y:b3,sdk>=:29,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000007e05000009200000ffff0f00,Nintendo Switch Pro Controller,a:b0,b:b1,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:b10,rightx:a2,righty:a3,start:b16,x:b17,y:b2,sdk<=:28,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", /* Extremely slow in Bluetooth mode on Android */ + "050000007e05000009200000ffff0f00,Nintendo Switch Pro Controller,a:b1,b:b0,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:b10,rightx:a2,righty:a3,start:b16,x:b2,y:b17,sdk<=:28,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", /* Extremely slow in Bluetooth mode on Android */ "050000004c05000068020000dfff3f00,PS3 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,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,", - "030000004c050000cc09000000006800,PS4 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,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,", - "050000004c050000c4050000fffe3f00,PS4 Controller,a:b1,b:b17,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,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,", - "050000004c050000cc090000fffe3f00,PS4 Controller,a:b1,b:b17,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,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,", + "050000004c050000c405000000783f00,PS4 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,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,", + "050000004c050000c4050000fffe3f80,PS4 Controller,a:b1,b:b17,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:+a3,rightx:a4,righty:a5,start:b16,x:b0,y:b2,", + "050000004c050000c4050000ffff3f00,PS4 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,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,", + "050000004c050000cc090000fffe3f80,PS4 Controller,a:b1,b:b17,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:a3,rightx:a4,righty:a5,start:b16,x:b0,y:b2,", "050000004c050000cc090000ffff3f00,PS4 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,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,", + "050000004c050000e60c0000fffe3f80,PS5 Controller,a:b1,b:b17,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:a3,rightx:a4,righty:a5,start:b16,x:b0,y:b2,", + "050000004c050000e60c0000ffff3f00,PS5 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,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,", + "05000000f8270000bf0b0000ffff3f00,Razer Kishi,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,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,", "050000003215000005070000ffff3f00,Razer Raiju Mobile,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,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,", "050000003215000007070000ffff3f00,Razer Raiju Mobile,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,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,", "050000003215000000090000bf7f3f00,Razer Serval,a:b0,b:b1,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,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,", - "05000000de2800000611000001000000,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,", - "050000005e040000e00200000ffe3f00,Xbox One Wireless Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b3,leftstick:b15,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b16,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b17,y:b2,", + "050000004f0400000ed00000fffe3f00,ThrustMaster eSwap PRO Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", + "050000005e0400008e02000000783f00,Xbox 360 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,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,", + "050000005e040000000b000000783f80,Xbox One Elite 2 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,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,", + "050000005e040000050b0000ffff3f00,Xbox One Elite 2 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a6,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", + "050000005e040000e002000000783f00,Xbox One S Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,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,", + "050000005e040000ea02000000783f00,Xbox One S Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,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,", + "050000005e040000fd020000ff7f3f00,Xbox One S Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,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,", + "050000005e040000e00200000ffe3f80,Xbox One Wireless Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b3,leftstick:b15,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b16,righttrigger:a5,rightx:a2,righty:a3,start:b10,x:b17,y:b2,", "050000005e040000fd020000ffff3f00,Xbox One Wireless Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,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,", - "050000005e04000091020000ff073f00,Xbox Wireless Controller,a:b0,b:b1,back:b4,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,", /* The DPAD doesn't seem to work on this controller on Android TV? */ - "050000001727000044310000ffff3f00,XiaoMi Game Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a6,rightx:a2,righty:a5,start:b6,x:b2,y:b3,", - "0500000083050000602000000ffe0000,iBuffalo USB 2-axis 8-button Gamepad,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b15,rightshoulder:b16,start:b10,x:b2,y:b3,", + "050000005e040000120b000000783f80,Xbox Series X Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,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,", + "050000005e040000130b0000ffff3f00,Xbox Series X Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,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,", + "050000005e04000091020000ff073f80,Xbox Wireless Controller,a:b0,b:b1,back:b4,guide:b5,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,", /* The DPAD doesn't seem to work on this controller on Android TV? */ + "050000001727000044310000ffff3f80,XiaoMi Game Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a6,rightx:a4,righty:a5,start:b6,x:b2,y:b3,", + "0500000083050000602000000ffe0000,iBuffalo SNES Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b15,rightshoulder:b16,start:b10,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "0500000083050000602000000ffe0000,iBuffalo SNES Controller,a:b1,b:b0,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b15,rightshoulder:b16,start:b10,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", #endif -#if defined(SDL_JOYSTICK_MFI) +#ifdef SDL_JOYSTICK_MFI "05000000ac050000010000004f066d01,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,x:b2,y:b3,", "05000000ac05000001000000cf076d01,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b2,y:b3,", + "05000000ac05000001000000df076d01,*,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,", + "05000000ac05000001000000ff076d01,*,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,", "05000000ac050000020000004f066d02,*,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,rightshoulder:b5,x:b2,y:b3,", - "050000004c050000cc090000df070000,DUALSHOCK 4 Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,", + "050000008a35000003010000ff070000,Backbone One,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,", + "050000008a35000004010000ff070000,Backbone One,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,", + "050000007e050000062000000f060000,Nintendo Switch Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b2,b:b0,leftshoulder:b4,rightshoulder:b5,x:b3,y:b1,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000007e050000062000000f060000,Nintendo Switch Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b2,leftshoulder:b4,rightshoulder:b5,x:b1,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000007e050000062000004f060000,Nintendo Switch Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b2,b:b0,guide:b6,leftshoulder:b4,rightshoulder:b5,x:b3,y:b1,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000007e050000062000004f060000,Nintendo Switch Joy-Con (L),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b2,guide:b6,leftshoulder:b4,rightshoulder:b5,x:b1,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000007e05000008200000df070000,Nintendo Switch Joy-Con (L/R),a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000007e05000008200000df070000,Nintendo Switch Joy-Con (L/R),a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000007e050000072000000f060000,Nintendo Switch Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b2,b:b0,leftshoulder:b4,rightshoulder:b5,x:b3,y:b1,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000007e050000072000000f060000,Nintendo Switch Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b2,leftshoulder:b4,rightshoulder:b5,x:b1,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000007e050000072000004f060000,Nintendo Switch Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b2,b:b0,guide:b6,leftshoulder:b4,rightshoulder:b5,x:b3,y:b1,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000007e050000072000004f060000,Nintendo Switch Joy-Con (R),+leftx:h0.2,+lefty:h0.4,-leftx:h0.8,-lefty:h0.1,a:b0,b:b2,guide:b6,leftshoulder:b4,rightshoulder:b5,x:b1,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000007e05000009200000df870000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b10,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000007e05000009200000df870000,Nintendo Switch Pro Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b10,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000007e05000009200000ff870000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000007e05000009200000ff870000,Nintendo Switch Pro Controller,a:b1,b:b0,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000004c050000cc090000df070000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,", + "050000004c050000cc090000df870001,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,", + "050000004c050000cc090000ff070000,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,", + "050000004c050000cc090000ff870001,PS4 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,touchpad:b11,x:b2,y:b3,", + "050000004c050000e60c0000df870000,PS5 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,touchpad:b10,x:b2,y:b3,", + "050000004c050000e60c0000ff870000,PS5 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,touchpad:b11,x:b2,y:b3,", "05000000ac0500000300000043006d03,Remote,a:b0,b:b2,leftx:a0,lefty:a1,", - "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,", - "05000000de2800000611000001000000,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,", + "050000005e040000050b0000df070001,Xbox Elite Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b10,paddle2:b12,paddle3:b11,paddle4:b13,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,", + "050000005e040000050b0000ff070001,Xbox Elite Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b13,paddle3:b12,paddle4:b14,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,", + "050000005e040000130b0000df870001,Xbox Series X Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b10,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,", + "050000005e040000130b0000ff870001,Xbox Series X Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,misc1:b11,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,", "050000005e040000e0020000df070000,Xbox Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b2,y:b3,", + "050000005e040000e0020000ff070000,Xbox Wireless Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b10,x:b2,y:b3,", #endif -#if defined(SDL_JOYSTICK_EMSCRIPTEN) +#ifdef SDL_JOYSTICK_EMSCRIPTEN "default,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,", +#endif +#ifdef SDL_JOYSTICK_PS2 + "0000000050533220436f6e74726f6c00,PS2 Controller,crc:ed87,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,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,", +#endif +#ifdef SDL_JOYSTICK_PSP + "00000000505350206275696c74696e00,PSP builtin joypad,crc:bb86,a:b2,b:b1,back:b10,dpdown:b6,dpleft:b7,dpright:b9,dpup:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,", +#endif +#ifdef SDL_JOYSTICK_VITA + "0000000050535669746120436f6e7400,PSVita Controller,crc:d598,a:b2,b:b1,back:b10,dpdown:b6,dpleft:b7,dpright:b9,dpup:b8,leftshoulder:b4,leftstick:b14,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b15,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,", +#endif +#ifdef SDL_JOYSTICK_N3DS + "000000004e696e74656e646f20334400,Nintendo 3DS,crc:3210,a:b0,b:b1,back:b2,dpdown:b7,dpleft:b5,dpright:b4,dpup:b6,leftshoulder:b9,lefttrigger:b14,leftx:a0,lefty:a1,rightshoulder:b8,righttrigger:b15,rightx:a2,righty:a3,start:b3,x:b10,y:b11,", #endif "hidapi,*,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,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,", NULL diff --git a/SDL2-2.30.5/src/joystick/SDL_joystick.c b/SDL2-2.30.5/src/joystick/SDL_joystick.c new file mode 100644 index 0000000..0884cf9 --- /dev/null +++ b/SDL2-2.30.5/src/joystick/SDL_joystick.c @@ -0,0 +1,3577 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +/* This is the joystick API for Simple DirectMedia Layer */ + +#include "SDL.h" +#include "SDL_atomic.h" +#include "SDL_events.h" +#include "SDL_sysjoystick.h" +#include "SDL_hints.h" +#include "../SDL_hints_c.h" +#include "SDL_steam_virtual_gamepad.h" + +#ifndef SDL_EVENTS_DISABLED +#include "../events/SDL_events_c.h" +#endif +#include "../video/SDL_sysvideo.h" +#include "hidapi/SDL_hidapijoystick_c.h" + +/* This is included in only one place because it has a large static list of controllers */ +#include "controller_type.h" + +#if defined(__WIN32__) || defined(__WINGDK__) +/* Needed for checking for input remapping programs */ +#include "../core/windows/SDL_windows.h" + +#undef UNICODE /* We want ASCII functions */ +#include +#endif + +#ifdef SDL_JOYSTICK_VIRTUAL +#include "./virtual/SDL_virtualjoystick_c.h" +#endif + +static SDL_JoystickDriver *SDL_joystick_drivers[] = { +#ifdef SDL_JOYSTICK_HIDAPI /* Before WINDOWS_ driver, as WINDOWS wants to check if this driver is handling things */ + &SDL_HIDAPI_JoystickDriver, +#endif +#ifdef SDL_JOYSTICK_RAWINPUT /* Before WINDOWS_ driver, as WINDOWS wants to check if this driver is handling things */ + &SDL_RAWINPUT_JoystickDriver, +#endif +#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT) /* Before WGI driver, as WGI wants to check if this driver is handling things */ + &SDL_WINDOWS_JoystickDriver, +#endif +#if defined(SDL_JOYSTICK_WGI) + &SDL_WGI_JoystickDriver, +#endif +#if defined(SDL_JOYSTICK_WINMM) + &SDL_WINMM_JoystickDriver, +#endif +#ifdef SDL_JOYSTICK_LINUX + &SDL_LINUX_JoystickDriver, +#endif +#ifdef SDL_JOYSTICK_IOKIT + &SDL_DARWIN_JoystickDriver, +#endif +#if (defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__TVOS__)) && !defined(SDL_JOYSTICK_DISABLED) + &SDL_IOS_JoystickDriver, +#endif +#ifdef SDL_JOYSTICK_ANDROID + &SDL_ANDROID_JoystickDriver, +#endif +#ifdef SDL_JOYSTICK_EMSCRIPTEN + &SDL_EMSCRIPTEN_JoystickDriver, +#endif +#ifdef SDL_JOYSTICK_HAIKU + &SDL_HAIKU_JoystickDriver, +#endif +#ifdef SDL_JOYSTICK_USBHID /* !!! FIXME: "USBHID" is a generic name, and doubly-confusing with HIDAPI next to it. This is the *BSD interface, rename this. */ + &SDL_BSD_JoystickDriver, +#endif +#ifdef SDL_JOYSTICK_OS2 + &SDL_OS2_JoystickDriver, +#endif +#ifdef SDL_JOYSTICK_PS2 + &SDL_PS2_JoystickDriver, +#endif +#ifdef SDL_JOYSTICK_PSP + &SDL_PSP_JoystickDriver, +#endif +#ifdef SDL_JOYSTICK_VIRTUAL + &SDL_VIRTUAL_JoystickDriver, +#endif +#ifdef SDL_JOYSTICK_VITA + &SDL_VITA_JoystickDriver, +#endif +#ifdef SDL_JOYSTICK_N3DS + &SDL_N3DS_JoystickDriver +#endif +#if defined(SDL_JOYSTICK_DUMMY) || defined(SDL_JOYSTICK_DISABLED) + &SDL_DUMMY_JoystickDriver +#endif +}; + +#ifndef SDL_THREAD_SAFETY_ANALYSIS +static +#endif +SDL_mutex *SDL_joystick_lock = NULL; /* This needs to support recursive locks */ +static SDL_atomic_t SDL_joystick_lock_pending; +static int SDL_joysticks_locked; +static SDL_bool SDL_joysticks_initialized; +static SDL_bool SDL_joysticks_quitting = SDL_FALSE; +static SDL_Joystick *SDL_joysticks SDL_GUARDED_BY(SDL_joystick_lock) = NULL; +static SDL_atomic_t SDL_next_joystick_instance_id SDL_GUARDED_BY(SDL_joystick_lock); +static int SDL_joystick_player_count SDL_GUARDED_BY(SDL_joystick_lock) = 0; +static SDL_JoystickID *SDL_joystick_players SDL_GUARDED_BY(SDL_joystick_lock) = NULL; +static SDL_bool SDL_joystick_allows_background_events = SDL_FALSE; +char SDL_joystick_magic; + +static Uint32 initial_arcadestick_devices[] = { + MAKE_VIDPID(0x0079, 0x181a), /* Venom Arcade Stick */ + MAKE_VIDPID(0x0079, 0x181b), /* Venom Arcade Stick */ + MAKE_VIDPID(0x0c12, 0x0ef6), /* Hitbox Arcade Stick */ + MAKE_VIDPID(0x0e6f, 0x0109), /* PDP Versus Fighting Pad */ + MAKE_VIDPID(0x0f0d, 0x0016), /* Hori Real Arcade Pro.EX */ + MAKE_VIDPID(0x0f0d, 0x001b), /* Hori Real Arcade Pro VX */ + MAKE_VIDPID(0x0f0d, 0x0063), /* Hori Real Arcade Pro Hayabusa (USA) Xbox One */ + MAKE_VIDPID(0x0f0d, 0x006a), /* Real Arcade Pro 4 */ + MAKE_VIDPID(0x0f0d, 0x0078), /* Hori Real Arcade Pro V Kai Xbox One */ + MAKE_VIDPID(0x0f0d, 0x008a), /* HORI Real Arcade Pro 4 */ + MAKE_VIDPID(0x0f0d, 0x008c), /* Hori Real Arcade Pro 4 */ + MAKE_VIDPID(0x0f0d, 0x00aa), /* HORI Real Arcade Pro V Hayabusa in Switch Mode */ + MAKE_VIDPID(0x0f0d, 0x00ed), /* Hori Fighting Stick mini 4 kai */ + MAKE_VIDPID(0x0f0d, 0x011c), /* Hori Fighting Stick α in PS4 Mode */ + MAKE_VIDPID(0x0f0d, 0x011e), /* Hori Fighting Stick α in PC Mode */ + MAKE_VIDPID(0x0f0d, 0x0184), /* Hori Fighting Stick α in PS5 Mode */ + MAKE_VIDPID(0x146b, 0x0604), /* NACON Daija Arcade Stick */ + MAKE_VIDPID(0x1532, 0x0a00), /* Razer Atrox Arcade Stick */ + MAKE_VIDPID(0x1bad, 0xf03d), /* Street Fighter IV Arcade Stick TE - Chun Li */ + MAKE_VIDPID(0x1bad, 0xf502), /* Hori Real Arcade Pro.VX SA */ + MAKE_VIDPID(0x1bad, 0xf504), /* Hori Real Arcade Pro. EX */ + MAKE_VIDPID(0x1bad, 0xf506), /* Hori Real Arcade Pro.EX Premium VLX */ + MAKE_VIDPID(0x20d6, 0xa715), /* PowerA Nintendo Switch Fusion Arcade Stick */ + MAKE_VIDPID(0x24c6, 0x5000), /* Razer Atrox Arcade Stick */ + MAKE_VIDPID(0x24c6, 0x5501), /* Hori Real Arcade Pro VX-SA */ + MAKE_VIDPID(0x24c6, 0x550e), /* Hori Real Arcade Pro V Kai 360 */ + MAKE_VIDPID(0x2c22, 0x2300), /* Qanba Obsidian Arcade Joystick in PS4 Mode */ + MAKE_VIDPID(0x2c22, 0x2302), /* Qanba Obsidian Arcade Joystick in PS3 Mode */ + MAKE_VIDPID(0x2c22, 0x2303), /* Qanba Obsidian Arcade Joystick in PC Mode */ + MAKE_VIDPID(0x2c22, 0x2500), /* Qanba Dragon Arcade Joystick in PS4 Mode */ + MAKE_VIDPID(0x2c22, 0x2502), /* Qanba Dragon Arcade Joystick in PS3 Mode */ + MAKE_VIDPID(0x2c22, 0x2503), /* Qanba Dragon Arcade Joystick in PC Mode */ +}; +static SDL_vidpid_list arcadestick_devices = { + SDL_HINT_JOYSTICK_ARCADESTICK_DEVICES, 0, 0, NULL, + SDL_HINT_JOYSTICK_ARCADESTICK_DEVICES_EXCLUDED, 0, 0, NULL, + SDL_arraysize(initial_arcadestick_devices), initial_arcadestick_devices, + SDL_FALSE +}; + +/* This list is taken from: + https://raw.githubusercontent.com/denilsonsa/udev-joystick-blacklist/master/generate_rules.py + */ +static Uint32 initial_blacklist_devices[] = { + /* Microsoft Microsoft Wireless Optical Desktop 2.10 */ + /* Microsoft Wireless Desktop - Comfort Edition */ + MAKE_VIDPID(0x045e, 0x009d), + + /* Microsoft Microsoft Digital Media Pro Keyboard */ + /* Microsoft Corp. Digital Media Pro Keyboard */ + MAKE_VIDPID(0x045e, 0x00b0), + + /* Microsoft Microsoft Digital Media Keyboard */ + /* Microsoft Corp. Digital Media Keyboard 1.0A */ + MAKE_VIDPID(0x045e, 0x00b4), + + /* Microsoft Microsoft Digital Media Keyboard 3000 */ + MAKE_VIDPID(0x045e, 0x0730), + + /* Microsoft Microsoft 2.4GHz Transceiver v6.0 */ + /* Microsoft Microsoft 2.4GHz Transceiver v8.0 */ + /* Microsoft Corp. Nano Transceiver v1.0 for Bluetooth */ + /* Microsoft Wireless Mobile Mouse 1000 */ + /* Microsoft Wireless Desktop 3000 */ + MAKE_VIDPID(0x045e, 0x0745), + + /* Microsoft SideWinder(TM) 2.4GHz Transceiver */ + MAKE_VIDPID(0x045e, 0x0748), + + /* Microsoft Corp. Wired Keyboard 600 */ + MAKE_VIDPID(0x045e, 0x0750), + + /* Microsoft Corp. Sidewinder X4 keyboard */ + MAKE_VIDPID(0x045e, 0x0768), + + /* Microsoft Corp. Arc Touch Mouse Transceiver */ + MAKE_VIDPID(0x045e, 0x0773), + + /* Microsoft 2.4GHz Transceiver v9.0 */ + /* Microsoft Nano Transceiver v2.1 */ + /* Microsoft Sculpt Ergonomic Keyboard (5KV-00001) */ + MAKE_VIDPID(0x045e, 0x07a5), + + /* Microsoft Nano Transceiver v1.0 */ + /* Microsoft Wireless Keyboard 800 */ + MAKE_VIDPID(0x045e, 0x07b2), + + /* Microsoft Nano Transceiver v2.0 */ + MAKE_VIDPID(0x045e, 0x0800), + + MAKE_VIDPID(0x046d, 0xc30a), /* Logitech, Inc. iTouch Composite keboard */ + + MAKE_VIDPID(0x04d9, 0xa0df), /* Tek Syndicate Mouse (E-Signal USB Gaming Mouse) */ + + /* List of Wacom devices at: http://linuxwacom.sourceforge.net/wiki/index.php/Device_IDs */ + MAKE_VIDPID(0x056a, 0x0010), /* Wacom ET-0405 Graphire */ + MAKE_VIDPID(0x056a, 0x0011), /* Wacom ET-0405A Graphire2 (4x5) */ + MAKE_VIDPID(0x056a, 0x0012), /* Wacom ET-0507A Graphire2 (5x7) */ + MAKE_VIDPID(0x056a, 0x0013), /* Wacom CTE-430 Graphire3 (4x5) */ + MAKE_VIDPID(0x056a, 0x0014), /* Wacom CTE-630 Graphire3 (6x8) */ + MAKE_VIDPID(0x056a, 0x0015), /* Wacom CTE-440 Graphire4 (4x5) */ + MAKE_VIDPID(0x056a, 0x0016), /* Wacom CTE-640 Graphire4 (6x8) */ + MAKE_VIDPID(0x056a, 0x0017), /* Wacom CTE-450 Bamboo Fun (4x5) */ + MAKE_VIDPID(0x056a, 0x0018), /* Wacom CTE-650 Bamboo Fun 6x8 */ + MAKE_VIDPID(0x056a, 0x0019), /* Wacom CTE-631 Bamboo One */ + MAKE_VIDPID(0x056a, 0x00d1), /* Wacom Bamboo Pen and Touch CTH-460 */ + MAKE_VIDPID(0x056a, 0x030e), /* Wacom Intuos Pen (S) CTL-480 */ + + MAKE_VIDPID(0x09da, 0x054f), /* A4 Tech Co., G7 750 mouse */ + MAKE_VIDPID(0x09da, 0x1410), /* A4 Tech Co., Ltd Bloody AL9 mouse */ + MAKE_VIDPID(0x09da, 0x3043), /* A4 Tech Co., Ltd Bloody R8A Gaming Mouse */ + MAKE_VIDPID(0x09da, 0x31b5), /* A4 Tech Co., Ltd Bloody TL80 Terminator Laser Gaming Mouse */ + MAKE_VIDPID(0x09da, 0x3997), /* A4 Tech Co., Ltd Bloody RT7 Terminator Wireless */ + MAKE_VIDPID(0x09da, 0x3f8b), /* A4 Tech Co., Ltd Bloody V8 mouse */ + MAKE_VIDPID(0x09da, 0x51f4), /* Modecom MC-5006 Keyboard */ + MAKE_VIDPID(0x09da, 0x5589), /* A4 Tech Co., Ltd Terminator TL9 Laser Gaming Mouse */ + MAKE_VIDPID(0x09da, 0x7b22), /* A4 Tech Co., Ltd Bloody V5 */ + MAKE_VIDPID(0x09da, 0x7f2d), /* A4 Tech Co., Ltd Bloody R3 mouse */ + MAKE_VIDPID(0x09da, 0x8090), /* A4 Tech Co., Ltd X-718BK Oscar Optical Gaming Mouse */ + MAKE_VIDPID(0x09da, 0x9033), /* A4 Tech Co., X7 X-705K */ + MAKE_VIDPID(0x09da, 0x9066), /* A4 Tech Co., Sharkoon Fireglider Optical */ + MAKE_VIDPID(0x09da, 0x9090), /* A4 Tech Co., Ltd XL-730K / XL-750BK / XL-755BK Laser Mouse */ + MAKE_VIDPID(0x09da, 0x90c0), /* A4 Tech Co., Ltd X7 G800V keyboard */ + MAKE_VIDPID(0x09da, 0xf012), /* A4 Tech Co., Ltd Bloody V7 mouse */ + MAKE_VIDPID(0x09da, 0xf32a), /* A4 Tech Co., Ltd Bloody B540 keyboard */ + MAKE_VIDPID(0x09da, 0xf613), /* A4 Tech Co., Ltd Bloody V2 mouse */ + MAKE_VIDPID(0x09da, 0xf624), /* A4 Tech Co., Ltd Bloody B120 Keyboard */ + + MAKE_VIDPID(0x1b1c, 0x1b3c), /* Corsair Harpoon RGB gaming mouse */ + + MAKE_VIDPID(0x1d57, 0xad03), /* [T3] 2.4GHz and IR Air Mouse Remote Control */ + + MAKE_VIDPID(0x1e7d, 0x2e4a), /* Roccat Tyon Mouse */ + + MAKE_VIDPID(0x20a0, 0x422d), /* Winkeyless.kr Keyboards */ + + MAKE_VIDPID(0x2516, 0x001f), /* Cooler Master Storm Mizar Mouse */ + MAKE_VIDPID(0x2516, 0x0028), /* Cooler Master Storm Alcor Mouse */ + + /*****************************************************************/ + /* Additional entries */ + /*****************************************************************/ + + MAKE_VIDPID(0x04d9, 0x8008), /* OBINLB USB-HID Keyboard (Anne Pro II) */ + MAKE_VIDPID(0x04d9, 0x8009), /* OBINLB USB-HID Keyboard (Anne Pro II) */ + MAKE_VIDPID(0x04d9, 0xa292), /* OBINLB USB-HID Keyboard (Anne Pro II) */ + MAKE_VIDPID(0x04d9, 0xa293), /* OBINLB USB-HID Keyboard (Anne Pro II) */ + MAKE_VIDPID(0x1532, 0x0266), /* Razer Huntsman V2 Analog, non-functional DInput device */ + MAKE_VIDPID(0x1532, 0x0282), /* Razer Huntsman Mini Analog, non-functional DInput device */ + MAKE_VIDPID(0x26ce, 0x01a2), /* ASRock LED Controller */ + MAKE_VIDPID(0x20d6, 0x0002), /* PowerA Enhanced Wireless Controller for Nintendo Switch (charging port only) */ +}; +static SDL_vidpid_list blacklist_devices = { + SDL_HINT_JOYSTICK_BLACKLIST_DEVICES, 0, 0, NULL, + SDL_HINT_JOYSTICK_BLACKLIST_DEVICES_EXCLUDED, 0, 0, NULL, + SDL_arraysize(initial_blacklist_devices), initial_blacklist_devices, + SDL_FALSE +}; + +static Uint32 initial_flightstick_devices[] = { + MAKE_VIDPID(0x044f, 0x0402), /* HOTAS Warthog Joystick */ + MAKE_VIDPID(0x0738, 0x2221), /* Saitek Pro Flight X-56 Rhino Stick */ + MAKE_VIDPID(0x044f, 0xb10a), /* ThrustMaster, Inc. T.16000M Joystick */ + MAKE_VIDPID(0x046d, 0xc215), /* Logitech Extreme 3D */ + MAKE_VIDPID(0x231d, 0x0126), /* Gunfighter Mk.III ‘Space Combat Edition’ (right) */ + MAKE_VIDPID(0x231d, 0x0127), /* Gunfighter Mk.III ‘Space Combat Edition’ (left) */ + MAKE_VIDPID(0x362c, 0x0001), /* Yawman Arrow */ +}; +static SDL_vidpid_list flightstick_devices = { + SDL_HINT_JOYSTICK_FLIGHTSTICK_DEVICES, 0, 0, NULL, + SDL_HINT_JOYSTICK_FLIGHTSTICK_DEVICES_EXCLUDED, 0, 0, NULL, + SDL_arraysize(initial_flightstick_devices), initial_flightstick_devices, + SDL_FALSE +}; + +static Uint32 initial_gamecube_devices[] = { + MAKE_VIDPID(0x0e6f, 0x0185), /* PDP Wired Fight Pad Pro for Nintendo Switch */ + MAKE_VIDPID(0x20d6, 0xa711), /* PowerA Wired Controller Nintendo GameCube Style */ +}; +static SDL_vidpid_list gamecube_devices = { + SDL_HINT_JOYSTICK_GAMECUBE_DEVICES, 0, 0, NULL, + SDL_HINT_JOYSTICK_GAMECUBE_DEVICES_EXCLUDED, 0, 0, NULL, + SDL_arraysize(initial_gamecube_devices), initial_gamecube_devices, + SDL_FALSE +}; + +static Uint32 initial_rog_gamepad_mice[] = { + MAKE_VIDPID(0x0b05, 0x1906), /* ROG Pugio II */ + MAKE_VIDPID(0x0b05, 0x1958), /* ROG Chakram Core Mouse */ + MAKE_VIDPID(0x0b05, 0x18e3), /* ROG Chakram (wired) Mouse */ + MAKE_VIDPID(0x0b05, 0x18e5), /* ROG Chakram (wireless) Mouse */ + MAKE_VIDPID(0x0b05, 0x1a18), /* ROG Chakram X (wired) Mouse */ + MAKE_VIDPID(0x0b05, 0x1a1a), /* ROG Chakram X (wireless) Mouse */ + MAKE_VIDPID(0x0b05, 0x1a1c), /* ROG Chakram X (Bluetooth) Mouse */ +}; +static SDL_vidpid_list rog_gamepad_mice = { + SDL_HINT_ROG_GAMEPAD_MICE, 0, 0, NULL, + SDL_HINT_ROG_GAMEPAD_MICE_EXCLUDED, 0, 0, NULL, + SDL_arraysize(initial_rog_gamepad_mice), initial_rog_gamepad_mice, + SDL_FALSE +}; + +static Uint32 initial_throttle_devices[] = { + MAKE_VIDPID(0x044f, 0x0404), /* HOTAS Warthog Throttle */ + MAKE_VIDPID(0x0738, 0xa221), /* Saitek Pro Flight X-56 Rhino Throttle */ +}; +static SDL_vidpid_list throttle_devices = { + SDL_HINT_JOYSTICK_THROTTLE_DEVICES, 0, 0, NULL, + SDL_HINT_JOYSTICK_THROTTLE_DEVICES_EXCLUDED, 0, 0, NULL, + SDL_arraysize(initial_throttle_devices), initial_throttle_devices, + SDL_FALSE +}; + +static Uint32 initial_wheel_devices[] = { + MAKE_VIDPID(0x0079, 0x1864), /* DragonRise Inc. Wired Wheel (active mode) (also known as PXN V900 (PS3), Superdrive SV-750, or a Genesis Seaborg 400) */ + MAKE_VIDPID(0x046d, 0xc294), /* Logitech generic wheel */ + MAKE_VIDPID(0x046d, 0xc295), /* Logitech Momo Force */ + MAKE_VIDPID(0x046d, 0xc298), /* Logitech Driving Force Pro */ + MAKE_VIDPID(0x046d, 0xc299), /* Logitech G25 */ + MAKE_VIDPID(0x046d, 0xc29a), /* Logitech Driving Force GT */ + MAKE_VIDPID(0x046d, 0xc29b), /* Logitech G27 */ + MAKE_VIDPID(0x046d, 0xc24f), /* Logitech G29 (PS3) */ + MAKE_VIDPID(0x046d, 0xc260), /* Logitech G29 (PS4) */ + MAKE_VIDPID(0x046d, 0xc261), /* Logitech G920 (initial mode) */ + MAKE_VIDPID(0x046d, 0xc262), /* Logitech G920 (active mode) */ + MAKE_VIDPID(0x046d, 0xc268), /* Logitech PRO Racing Wheel (PC mode) */ + MAKE_VIDPID(0x046d, 0xc269), /* Logitech PRO Racing Wheel (PS4/PS5 mode) */ + MAKE_VIDPID(0x046d, 0xc272), /* Logitech PRO Racing Wheel for Xbox (PC mode) */ + MAKE_VIDPID(0x046d, 0xc26d), /* Logitech G923 (Xbox) */ + MAKE_VIDPID(0x046d, 0xc26e), /* Logitech G923 */ + MAKE_VIDPID(0x046d, 0xc266), /* Logitech G923 for Playstation 4 and PC (PC mode) */ + MAKE_VIDPID(0x046d, 0xc267), /* Logitech G923 for Playstation 4 and PC (PS4 mode)*/ + MAKE_VIDPID(0x046d, 0xca03), /* Logitech Momo Racing */ + MAKE_VIDPID(0x044f, 0xb65d), /* Thrustmaster Wheel FFB */ + MAKE_VIDPID(0x044f, 0xb66d), /* Thrustmaster Wheel FFB */ + MAKE_VIDPID(0x044f, 0xb677), /* Thrustmaster T150 */ + MAKE_VIDPID(0x044f, 0xb696), /* Thrustmaster T248 */ + MAKE_VIDPID(0x044f, 0xb66e), /* Thrustmaster T300RS (normal mode) */ + MAKE_VIDPID(0x044f, 0xb66f), /* Thrustmaster T300RS (advanced mode) */ + MAKE_VIDPID(0x044f, 0xb66d), /* Thrustmaster T300RS (PS4 mode) */ + MAKE_VIDPID(0x044f, 0xb65e), /* Thrustmaster T500RS */ + MAKE_VIDPID(0x044f, 0xb664), /* Thrustmaster TX (initial mode) */ + MAKE_VIDPID(0x044f, 0xb669), /* Thrustmaster TX (active mode) */ + MAKE_VIDPID(0x044f, 0xb691), /* Thrustmaster TS-XW (initial mode) */ + MAKE_VIDPID(0x044f, 0xb692), /* Thrustmaster TS-XW (active mode) */ + MAKE_VIDPID(0x0483, 0x0522), /* Simagic Wheelbase (including M10, Alpha Mini, Alpha, Alpha U) */ + MAKE_VIDPID(0x0483, 0xa355), /* VRS DirectForce Pro Wheel Base */ + MAKE_VIDPID(0x0eb7, 0x0001), /* Fanatec ClubSport Wheel Base V2 */ + MAKE_VIDPID(0x0eb7, 0x0004), /* Fanatec ClubSport Wheel Base V2.5 */ + MAKE_VIDPID(0x0eb7, 0x0005), /* Fanatec CSL Elite Wheel Base+ (PS4) */ + MAKE_VIDPID(0x0eb7, 0x0006), /* Fanatec Podium Wheel Base DD1 */ + MAKE_VIDPID(0x0eb7, 0x0007), /* Fanatec Podium Wheel Base DD2 */ + MAKE_VIDPID(0x0eb7, 0x0011), /* Fanatec Forza Motorsport (CSR Wheel / CSR Elite Wheel) */ + MAKE_VIDPID(0x0eb7, 0x0020), /* Fanatec generic wheel / CSL DD / GT DD Pro */ + MAKE_VIDPID(0x0eb7, 0x0197), /* Fanatec Porsche Wheel (Turbo / GT3 RS / Turbo S / GT3 V2 / GT2) */ + MAKE_VIDPID(0x0eb7, 0x038e), /* Fanatec ClubSport Wheel Base V1 */ + MAKE_VIDPID(0x0eb7, 0x0e03), /* Fanatec CSL Elite Wheel Base */ + MAKE_VIDPID(0x11ff, 0x0511), /* DragonRise Inc. Wired Wheel (initial mode) (also known as PXN V900 (PS3), Superdrive SV-750, or a Genesis Seaborg 400) */ + MAKE_VIDPID(0x1209, 0xffb0), /* Generic FFBoard OpenFFBoard universal forcefeedback wheel */ + MAKE_VIDPID(0x16d0, 0x0d5a), /* Simucube 1 Wheelbase */ + MAKE_VIDPID(0x16d0, 0x0d5f), /* Simucube 2 Ultimate Wheelbase */ + MAKE_VIDPID(0x16d0, 0x0d60), /* Simucube 2 Pro Wheelbase */ + MAKE_VIDPID(0x16d0, 0x0d61), /* Simucube 2 Sport Wheelbase */ + MAKE_VIDPID(0x2433, 0xf300), /* Asetek SimSports Invicta Wheelbase */ + MAKE_VIDPID(0x2433, 0xf301), /* Asetek SimSports Forte Wheelbase */ + MAKE_VIDPID(0x2433, 0xf303), /* Asetek SimSports La Prima Wheelbase */ + MAKE_VIDPID(0x2433, 0xf306), /* Asetek SimSports Tony Kannan Wheelbase */ + MAKE_VIDPID(0x3416, 0x0301), /* Cammus C5 Wheelbase */ + MAKE_VIDPID(0x346e, 0x0000), /* Moza R16/R21 Wheelbase */ + MAKE_VIDPID(0x346e, 0x0002), /* Moza R9 Wheelbase */ + MAKE_VIDPID(0x346e, 0x0004), /* Moza R5 Wheelbase */ + MAKE_VIDPID(0x346e, 0x0005), /* Moza R3 Wheelbase */ + MAKE_VIDPID(0x346e, 0x0006), /* Moza R12 Wheelbase */ +}; +static SDL_vidpid_list wheel_devices = { + SDL_HINT_JOYSTICK_WHEEL_DEVICES, 0, 0, NULL, + SDL_HINT_JOYSTICK_WHEEL_DEVICES_EXCLUDED, 0, 0, NULL, + SDL_arraysize(initial_wheel_devices), initial_wheel_devices, + SDL_FALSE +}; + +static Uint32 initial_zero_centered_devices[] = { + MAKE_VIDPID(0x0e8f, 0x3013), /* HuiJia SNES USB adapter */ + MAKE_VIDPID(0x05a0, 0x3232), /* 8Bitdo Zero Gamepad */ +}; +static SDL_vidpid_list zero_centered_devices = { + SDL_HINT_JOYSTICK_ZERO_CENTERED_DEVICES, 0, 0, NULL, + NULL, 0, 0, NULL, + SDL_arraysize(initial_zero_centered_devices), initial_zero_centered_devices, + SDL_FALSE +}; + +#define CHECK_JOYSTICK_MAGIC(joystick, retval) \ + if (!joystick || joystick->magic != &SDL_joystick_magic) { \ + SDL_InvalidParamError("joystick"); \ + SDL_UnlockJoysticks(); \ + return retval; \ + } + +SDL_bool SDL_JoysticksInitialized(void) +{ + return SDL_joysticks_initialized; +} + +SDL_bool SDL_JoysticksQuitting(void) +{ + return SDL_joysticks_quitting; +} + +void SDL_LockJoysticks(void) +{ + (void)SDL_AtomicIncRef(&SDL_joystick_lock_pending); + SDL_LockMutex(SDL_joystick_lock); + (void)SDL_AtomicDecRef(&SDL_joystick_lock_pending); + + ++SDL_joysticks_locked; +} + +void SDL_UnlockJoysticks(void) +{ + SDL_mutex *joystick_lock = SDL_joystick_lock; + SDL_bool last_unlock = SDL_FALSE; + + --SDL_joysticks_locked; + + if (!SDL_joysticks_initialized) { + if (!SDL_joysticks_locked && SDL_AtomicGet(&SDL_joystick_lock_pending) == 0) { + /* NOTE: There's a small window here where another thread could lock the mutex */ + SDL_joystick_lock = NULL; + last_unlock = SDL_TRUE; + } + } + + SDL_UnlockMutex(joystick_lock); + + /* The last unlock after joysticks are uninitialized will cleanup the mutex, + * allowing applications to lock joysticks while reinitializing the system. + */ + if (last_unlock) { + SDL_DestroyMutex(joystick_lock); + } +} + +SDL_bool SDL_JoysticksLocked(void) +{ + return (SDL_joysticks_locked > 0) ? SDL_TRUE : SDL_FALSE; +} + +void SDL_AssertJoysticksLocked(void) +{ + SDL_assert(SDL_JoysticksLocked()); +} + +/* + * Get the driver and device index for an API device index + * This should be called while the joystick lock is held, to prevent another thread from updating the list + */ +static SDL_bool SDL_GetDriverAndJoystickIndex(int device_index, SDL_JoystickDriver **driver, int *driver_index) +{ + int i, num_joysticks, total_joysticks = 0; + + SDL_AssertJoysticksLocked(); + + if (device_index >= 0) { + for (i = 0; i < SDL_arraysize(SDL_joystick_drivers); ++i) { + num_joysticks = SDL_joystick_drivers[i]->GetCount(); + if (device_index < num_joysticks) { + *driver = SDL_joystick_drivers[i]; + *driver_index = device_index; + return SDL_TRUE; + } + device_index -= num_joysticks; + total_joysticks += num_joysticks; + } + } + + SDL_SetError("There are %d joysticks available", total_joysticks); + return SDL_FALSE; +} + +static int SDL_FindFreePlayerIndex(void) +{ + int player_index; + + SDL_AssertJoysticksLocked(); + + for (player_index = 0; player_index < SDL_joystick_player_count; ++player_index) { + if (SDL_joystick_players[player_index] == -1) { + break; + } + } + return player_index; +} + +static int SDL_GetPlayerIndexForJoystickID(SDL_JoystickID instance_id) +{ + int player_index; + + SDL_AssertJoysticksLocked(); + + for (player_index = 0; player_index < SDL_joystick_player_count; ++player_index) { + if (instance_id == SDL_joystick_players[player_index]) { + break; + } + } + if (player_index == SDL_joystick_player_count) { + player_index = -1; + } + return player_index; +} + +static SDL_JoystickID SDL_GetJoystickIDForPlayerIndex(int player_index) +{ + SDL_AssertJoysticksLocked(); + + if (player_index < 0 || player_index >= SDL_joystick_player_count) { + return -1; + } + return SDL_joystick_players[player_index]; +} + +static SDL_bool SDL_SetJoystickIDForPlayerIndex(int player_index, SDL_JoystickID instance_id) +{ + SDL_JoystickID existing_instance = SDL_GetJoystickIDForPlayerIndex(player_index); + SDL_JoystickDriver *driver; + int device_index; + int existing_player_index; + + SDL_AssertJoysticksLocked(); + + if (player_index >= SDL_joystick_player_count) { + SDL_JoystickID *new_players = (SDL_JoystickID *)SDL_realloc(SDL_joystick_players, (player_index + 1) * sizeof(*SDL_joystick_players)); + if (!new_players) { + SDL_OutOfMemory(); + return SDL_FALSE; + } + + SDL_joystick_players = new_players; + SDL_memset(&SDL_joystick_players[SDL_joystick_player_count], 0xFF, (player_index - SDL_joystick_player_count + 1) * sizeof(SDL_joystick_players[0])); + SDL_joystick_player_count = player_index + 1; + } else if (player_index >= 0 && SDL_joystick_players[player_index] == instance_id) { + /* Joystick is already assigned the requested player index */ + return SDL_TRUE; + } + + /* Clear the old player index */ + existing_player_index = SDL_GetPlayerIndexForJoystickID(instance_id); + if (existing_player_index >= 0) { + SDL_joystick_players[existing_player_index] = -1; + } + + if (player_index >= 0) { + SDL_joystick_players[player_index] = instance_id; + } + + /* Update the driver with the new index */ + device_index = SDL_JoystickGetDeviceIndexFromInstanceID(instance_id); + if (SDL_GetDriverAndJoystickIndex(device_index, &driver, &device_index)) { + driver->SetDevicePlayerIndex(device_index, player_index); + } + + /* Move any existing joystick to another slot */ + if (existing_instance >= 0) { + SDL_SetJoystickIDForPlayerIndex(SDL_FindFreePlayerIndex(), existing_instance); + } + return SDL_TRUE; +} + +static void SDLCALL SDL_JoystickAllowBackgroundEventsChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + if (SDL_GetStringBoolean(hint, SDL_FALSE)) { + SDL_joystick_allows_background_events = SDL_TRUE; + } else { + SDL_joystick_allows_background_events = SDL_FALSE; + } +} + +int SDL_JoystickInit(void) +{ + int i, status; + + /* Create the joystick list lock */ + if (SDL_joystick_lock == NULL) { + SDL_joystick_lock = SDL_CreateMutex(); + } + +#ifndef SDL_EVENTS_DISABLED + if (SDL_InitSubSystem(SDL_INIT_EVENTS) < 0) { + return -1; + } +#endif /* !SDL_EVENTS_DISABLED */ + + SDL_LockJoysticks(); + + SDL_joysticks_initialized = SDL_TRUE; + + SDL_GameControllerInitMappings(); + + SDL_LoadVIDPIDList(&arcadestick_devices); + SDL_LoadVIDPIDList(&blacklist_devices); + SDL_LoadVIDPIDList(&flightstick_devices); + SDL_LoadVIDPIDList(&gamecube_devices); + SDL_LoadVIDPIDList(&rog_gamepad_mice); + SDL_LoadVIDPIDList(&throttle_devices); + SDL_LoadVIDPIDList(&wheel_devices); + SDL_LoadVIDPIDList(&zero_centered_devices); + + /* See if we should allow joystick events while in the background */ + SDL_AddHintCallback(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, + SDL_JoystickAllowBackgroundEventsChanged, NULL); + + SDL_InitSteamVirtualGamepadInfo(); + + status = -1; + for (i = 0; i < SDL_arraysize(SDL_joystick_drivers); ++i) { + if (SDL_joystick_drivers[i]->Init() >= 0) { + status = 0; + } + } + SDL_UnlockJoysticks(); + + if (status < 0) { + SDL_JoystickQuit(); + } + + return status; +} + +/* + * Count the number of joysticks attached to the system + */ +int SDL_NumJoysticks(void) +{ + int i, total_joysticks = 0; + SDL_LockJoysticks(); + for (i = 0; i < SDL_arraysize(SDL_joystick_drivers); ++i) { + total_joysticks += SDL_joystick_drivers[i]->GetCount(); + } + SDL_UnlockJoysticks(); + return total_joysticks; +} + +/* + * Return the next available joystick instance ID + * This may be called by drivers from multiple threads, unprotected by any locks + */ +SDL_JoystickID SDL_GetNextJoystickInstanceID(void) +{ + return SDL_AtomicIncRef(&SDL_next_joystick_instance_id); +} + +const SDL_SteamVirtualGamepadInfo *SDL_GetJoystickInstanceVirtualGamepadInfo(SDL_JoystickID instance_id) +{ + SDL_JoystickDriver *driver; + int device_index; + const SDL_SteamVirtualGamepadInfo *info = NULL; + + if (SDL_SteamVirtualGamepadEnabled() && + SDL_GetDriverAndJoystickIndex(SDL_JoystickGetDeviceIndexFromInstanceID(instance_id), &driver, &device_index)) { + info = SDL_GetSteamVirtualGamepadInfo(driver->GetDeviceSteamVirtualGamepadSlot(device_index)); + } + return info; +} + +/* + * Get the implementation dependent name of a joystick + */ +const char *SDL_JoystickNameForIndex(int device_index) +{ + SDL_JoystickDriver *driver; + const char *name = NULL; + const SDL_SteamVirtualGamepadInfo *info; + + SDL_LockJoysticks(); + info = SDL_GetJoystickInstanceVirtualGamepadInfo(SDL_JoystickGetDeviceInstanceID(device_index)); + if (info) { + name = info->name; + } else if (SDL_GetDriverAndJoystickIndex(device_index, &driver, &device_index)) { + name = driver->GetDeviceName(device_index); + } + SDL_UnlockJoysticks(); + + /* FIXME: Really we should reference count this name so it doesn't go away after unlock */ + return name; +} + +/* + * Get the implementation dependent path of a joystick + */ +const char *SDL_JoystickPathForIndex(int device_index) +{ + SDL_JoystickDriver *driver; + const char *path = NULL; + + SDL_LockJoysticks(); + if (SDL_GetDriverAndJoystickIndex(device_index, &driver, &device_index)) { + path = driver->GetDevicePath(device_index); + } + SDL_UnlockJoysticks(); + + /* FIXME: Really we should reference count this path so it doesn't go away after unlock */ + if (!path) { + SDL_Unsupported(); + } + return path; +} + +/* + * Get the player index of a joystick, or -1 if it's not available + */ +int SDL_JoystickGetDevicePlayerIndex(int device_index) +{ + int player_index; + + SDL_LockJoysticks(); + player_index = SDL_GetPlayerIndexForJoystickID(SDL_JoystickGetDeviceInstanceID(device_index)); + SDL_UnlockJoysticks(); + + return player_index; +} + +/* + * Return true if this joystick is known to have all axes centered at zero + * This isn't generally needed unless the joystick never generates an initial axis value near zero, + * e.g. it's emulating axes with digital buttons + */ +static SDL_bool SDL_JoystickAxesCenteredAtZero(SDL_Joystick *joystick) +{ +#ifdef __WINRT__ + return SDL_TRUE; +#else + /*printf("JOYSTICK '%s' VID/PID 0x%.4x/0x%.4x AXES: %d\n", joystick->name, vendor, product, joystick->naxes);*/ + + if (joystick->naxes == 2) { + /* Assume D-pad or thumbstick style axes are centered at 0 */ + return SDL_TRUE; + } + + return SDL_VIDPIDInList(SDL_JoystickGetVendor(joystick), SDL_JoystickGetProduct(joystick), &zero_centered_devices); +#endif /* __WINRT__ */ +} + +/* + * Open a joystick for use - the index passed as an argument refers to + * the N'th joystick on the system. This index is the value which will + * identify this joystick in future joystick events. + * + * This function returns a joystick identifier, or NULL if an error occurred. + */ +SDL_Joystick *SDL_JoystickOpen(int device_index) +{ + SDL_JoystickDriver *driver; + SDL_JoystickID instance_id; + SDL_Joystick *joystick; + SDL_Joystick *joysticklist; + const char *joystickname = NULL; + const char *joystickpath = NULL; + SDL_JoystickPowerLevel initial_power_level; + const SDL_SteamVirtualGamepadInfo *info; + + SDL_LockJoysticks(); + + if (!SDL_GetDriverAndJoystickIndex(device_index, &driver, &device_index)) { + SDL_UnlockJoysticks(); + return NULL; + } + + joysticklist = SDL_joysticks; + /* If the joystick is already open, return it + * it is important that we have a single joystick * for each instance id + */ + instance_id = driver->GetDeviceInstanceID(device_index); + while (joysticklist) { + if (instance_id == joysticklist->instance_id) { + joystick = joysticklist; + ++joystick->ref_count; + SDL_UnlockJoysticks(); + return joystick; + } + joysticklist = joysticklist->next; + } + + /* Create and initialize the joystick */ + joystick = (SDL_Joystick *)SDL_calloc(sizeof(*joystick), 1); + if (!joystick) { + SDL_OutOfMemory(); + SDL_UnlockJoysticks(); + return NULL; + } + joystick->magic = &SDL_joystick_magic; + joystick->driver = driver; + joystick->instance_id = instance_id; + joystick->attached = SDL_TRUE; + joystick->epowerlevel = SDL_JOYSTICK_POWER_UNKNOWN; + joystick->led_expiration = SDL_GetTicks(); + + if (driver->Open(joystick, device_index) < 0) { + SDL_free(joystick); + SDL_UnlockJoysticks(); + return NULL; + } + + joystickname = driver->GetDeviceName(device_index); + if (joystickname) { + joystick->name = SDL_strdup(joystickname); + } else { + joystick->name = NULL; + } + + joystickpath = driver->GetDevicePath(device_index); + if (joystickpath) { + joystick->path = SDL_strdup(joystickpath); + } else { + joystick->path = NULL; + } + + joystick->guid = driver->GetDeviceGUID(device_index); + + if (joystick->naxes > 0) { + joystick->axes = (SDL_JoystickAxisInfo *)SDL_calloc(joystick->naxes, sizeof(SDL_JoystickAxisInfo)); + } + if (joystick->nhats > 0) { + joystick->hats = (Uint8 *)SDL_calloc(joystick->nhats, sizeof(Uint8)); + } + if (joystick->nballs > 0) { + joystick->balls = (struct balldelta *)SDL_calloc(joystick->nballs, sizeof(*joystick->balls)); + } + if (joystick->nbuttons > 0) { + joystick->buttons = (Uint8 *)SDL_calloc(joystick->nbuttons, sizeof(Uint8)); + } + if (((joystick->naxes > 0) && !joystick->axes) || ((joystick->nhats > 0) && !joystick->hats) || ((joystick->nballs > 0) && !joystick->balls) || ((joystick->nbuttons > 0) && !joystick->buttons)) { + SDL_OutOfMemory(); + SDL_JoystickClose(joystick); + SDL_UnlockJoysticks(); + return NULL; + } + + /* If this joystick is known to have all zero centered axes, skip the auto-centering code */ + if (SDL_JoystickAxesCenteredAtZero(joystick)) { + int i; + + for (i = 0; i < joystick->naxes; ++i) { + joystick->axes[i].has_initial_value = SDL_TRUE; + } + } + + joystick->is_game_controller = SDL_IsGameController(device_index); + + /* Get the Steam Input API handle */ + info = SDL_GetJoystickInstanceVirtualGamepadInfo(instance_id); + if (info) { + joystick->steam_handle = info->handle; + } + + /* Add joystick to list */ + ++joystick->ref_count; + /* Link the joystick in the list */ + joystick->next = SDL_joysticks; + SDL_joysticks = joystick; + + /* send initial battery event */ + initial_power_level = joystick->epowerlevel; + joystick->epowerlevel = SDL_JOYSTICK_POWER_UNKNOWN; + SDL_PrivateJoystickBatteryLevel(joystick, initial_power_level); + + driver->Update(joystick); + + SDL_UnlockJoysticks(); + + return joystick; +} + +int SDL_JoystickAttachVirtual(SDL_JoystickType type, int naxes, int nbuttons, int nhats) +{ + SDL_VirtualJoystickDesc desc; + + SDL_zero(desc); + desc.version = SDL_VIRTUAL_JOYSTICK_DESC_VERSION; + desc.type = (Uint16)type; + desc.naxes = (Uint16)naxes; + desc.nbuttons = (Uint16)nbuttons; + desc.nhats = (Uint16)nhats; + return SDL_JoystickAttachVirtualEx(&desc); +} + +int SDL_JoystickAttachVirtualEx(const SDL_VirtualJoystickDesc *desc) +{ +#ifdef SDL_JOYSTICK_VIRTUAL + int retval; + + SDL_LockJoysticks(); + retval = SDL_JoystickAttachVirtualInner(desc); + SDL_UnlockJoysticks(); + return retval; +#else + return SDL_SetError("SDL not built with virtual-joystick support"); +#endif +} + +int SDL_JoystickDetachVirtual(int device_index) +{ +#ifdef SDL_JOYSTICK_VIRTUAL + SDL_JoystickDriver *driver; + + SDL_LockJoysticks(); + if (SDL_GetDriverAndJoystickIndex(device_index, &driver, &device_index)) { + if (driver == &SDL_VIRTUAL_JoystickDriver) { + const int retval = SDL_JoystickDetachVirtualInner(device_index); + SDL_UnlockJoysticks(); + return retval; + } + } + SDL_UnlockJoysticks(); + + return SDL_SetError("Virtual joystick not found at provided index"); +#else + return SDL_SetError("SDL not built with virtual-joystick support"); +#endif +} + +SDL_bool SDL_JoystickIsVirtual(int device_index) +{ +#ifdef SDL_JOYSTICK_VIRTUAL + SDL_JoystickDriver *driver; + int driver_device_index; + SDL_bool is_virtual = SDL_FALSE; + + SDL_LockJoysticks(); + if (SDL_GetDriverAndJoystickIndex(device_index, &driver, &driver_device_index)) { + if (driver == &SDL_VIRTUAL_JoystickDriver) { + is_virtual = SDL_TRUE; + } + } + SDL_UnlockJoysticks(); + + return is_virtual; +#else + return SDL_FALSE; +#endif +} + +int SDL_JoystickSetVirtualAxis(SDL_Joystick *joystick, int axis, Sint16 value) +{ + int retval; + + SDL_LockJoysticks(); + { + CHECK_JOYSTICK_MAGIC(joystick, -1); + +#ifdef SDL_JOYSTICK_VIRTUAL + retval = SDL_JoystickSetVirtualAxisInner(joystick, axis, value); +#else + retval = SDL_SetError("SDL not built with virtual-joystick support"); +#endif + } + SDL_UnlockJoysticks(); + + return retval; +} + +int SDL_JoystickSetVirtualButton(SDL_Joystick *joystick, int button, Uint8 value) +{ + int retval; + + SDL_LockJoysticks(); + { + CHECK_JOYSTICK_MAGIC(joystick, -1); + +#ifdef SDL_JOYSTICK_VIRTUAL + retval = SDL_JoystickSetVirtualButtonInner(joystick, button, value); +#else + retval = SDL_SetError("SDL not built with virtual-joystick support"); +#endif + } + SDL_UnlockJoysticks(); + + return retval; +} + +int SDL_JoystickSetVirtualHat(SDL_Joystick *joystick, int hat, Uint8 value) +{ + int retval; + + SDL_LockJoysticks(); + { + CHECK_JOYSTICK_MAGIC(joystick, -1); + +#ifdef SDL_JOYSTICK_VIRTUAL + retval = SDL_JoystickSetVirtualHatInner(joystick, hat, value); +#else + retval = SDL_SetError("SDL not built with virtual-joystick support"); +#endif + } + SDL_UnlockJoysticks(); + + return retval; +} + +/* + * Checks to make sure the joystick is valid. + */ +SDL_bool SDL_PrivateJoystickValid(SDL_Joystick *joystick) +{ + SDL_AssertJoysticksLocked(); + return (joystick && joystick->magic == &SDL_joystick_magic); +} + +SDL_bool SDL_PrivateJoystickGetAutoGamepadMapping(int device_index, SDL_GamepadMapping *out) +{ + SDL_JoystickDriver *driver; + SDL_bool is_ok = SDL_FALSE; + + SDL_LockJoysticks(); + if (SDL_GetDriverAndJoystickIndex(device_index, &driver, &device_index)) { + is_ok = driver->GetGamepadMapping(device_index, out); + } + SDL_UnlockJoysticks(); + + return is_ok; +} + +/* + * Get the number of multi-dimensional axis controls on a joystick + */ +int SDL_JoystickNumAxes(SDL_Joystick *joystick) +{ + int retval; + + SDL_LockJoysticks(); + { + CHECK_JOYSTICK_MAGIC(joystick, -1); + + retval = joystick->naxes; + } + SDL_UnlockJoysticks(); + + return retval; +} + +/* + * Get the number of hats on a joystick + */ +int SDL_JoystickNumHats(SDL_Joystick *joystick) +{ + int retval; + + SDL_LockJoysticks(); + { + CHECK_JOYSTICK_MAGIC(joystick, -1); + + retval = joystick->nhats; + } + SDL_UnlockJoysticks(); + + return retval; +} + +/* + * Get the number of trackballs on a joystick + */ +int SDL_JoystickNumBalls(SDL_Joystick *joystick) +{ + int retval; + + SDL_LockJoysticks(); + { + CHECK_JOYSTICK_MAGIC(joystick, -1); + + retval = joystick->nballs; + } + SDL_UnlockJoysticks(); + + return retval; +} + +/* + * Get the number of buttons on a joystick + */ +int SDL_JoystickNumButtons(SDL_Joystick *joystick) +{ + int retval; + + SDL_LockJoysticks(); + { + CHECK_JOYSTICK_MAGIC(joystick, -1); + + retval = joystick->nbuttons; + } + SDL_UnlockJoysticks(); + + return retval; +} + +/* + * Get the current state of an axis control on a joystick + */ +Sint16 SDL_JoystickGetAxis(SDL_Joystick *joystick, int axis) +{ + Sint16 state; + + SDL_LockJoysticks(); + { + CHECK_JOYSTICK_MAGIC(joystick, 0); + + if (axis < joystick->naxes) { + state = joystick->axes[axis].value; + } else { + SDL_SetError("Joystick only has %d axes", joystick->naxes); + state = 0; + } + } + SDL_UnlockJoysticks(); + + return state; +} + +/* + * Get the initial state of an axis control on a joystick + */ +SDL_bool SDL_JoystickGetAxisInitialState(SDL_Joystick *joystick, int axis, Sint16 *state) +{ + SDL_bool retval; + + SDL_LockJoysticks(); + { + CHECK_JOYSTICK_MAGIC(joystick, SDL_FALSE); + + if (axis >= joystick->naxes) { + SDL_SetError("Joystick only has %d axes", joystick->naxes); + retval = SDL_FALSE; + } else { + if (state) { + *state = joystick->axes[axis].initial_value; + } + retval = joystick->axes[axis].has_initial_value; + } + } + SDL_UnlockJoysticks(); + + return retval; +} + +/* + * Get the current state of a hat on a joystick + */ +Uint8 SDL_JoystickGetHat(SDL_Joystick *joystick, int hat) +{ + Uint8 state; + + SDL_LockJoysticks(); + { + CHECK_JOYSTICK_MAGIC(joystick, 0); + + if (hat < joystick->nhats) { + state = joystick->hats[hat]; + } else { + SDL_SetError("Joystick only has %d hats", joystick->nhats); + state = 0; + } + } + SDL_UnlockJoysticks(); + + return state; +} + +/* + * Get the ball axis change since the last poll + */ +int SDL_JoystickGetBall(SDL_Joystick *joystick, int ball, int *dx, int *dy) +{ + int retval; + + SDL_LockJoysticks(); + { + CHECK_JOYSTICK_MAGIC(joystick, -1); + + if (ball < joystick->nballs) { + if (dx) { + *dx = joystick->balls[ball].dx; + } + if (dy) { + *dy = joystick->balls[ball].dy; + } + joystick->balls[ball].dx = 0; + joystick->balls[ball].dy = 0; + retval = 0; + } else { + retval = SDL_SetError("Joystick only has %d balls", joystick->nballs); + } + } + SDL_UnlockJoysticks(); + + return retval; +} + +/* + * Get the current state of a button on a joystick + */ +Uint8 SDL_JoystickGetButton(SDL_Joystick *joystick, int button) +{ + Uint8 state; + + SDL_LockJoysticks(); + { + CHECK_JOYSTICK_MAGIC(joystick, 0); + + if (button < joystick->nbuttons) { + state = joystick->buttons[button]; + } else { + SDL_SetError("Joystick only has %d buttons", joystick->nbuttons); + state = 0; + } + } + SDL_UnlockJoysticks(); + + return state; +} + +/* + * Return if the joystick in question is currently attached to the system, + * \return SDL_FALSE if not plugged in, SDL_TRUE if still present. + */ +SDL_bool SDL_JoystickGetAttached(SDL_Joystick *joystick) +{ + SDL_bool retval; + + SDL_LockJoysticks(); + { + CHECK_JOYSTICK_MAGIC(joystick, SDL_FALSE); + + retval = joystick->attached; + } + SDL_UnlockJoysticks(); + + return retval; +} + +/* + * Get the instance id for this opened joystick + */ +SDL_JoystickID SDL_JoystickInstanceID(SDL_Joystick *joystick) +{ + SDL_JoystickID retval; + + SDL_LockJoysticks(); + { + CHECK_JOYSTICK_MAGIC(joystick, -1); + + retval = joystick->instance_id; + } + SDL_UnlockJoysticks(); + + return retval; +} + +/* + * Return the SDL_Joystick associated with an instance id. + */ +SDL_Joystick *SDL_JoystickFromInstanceID(SDL_JoystickID instance_id) +{ + SDL_Joystick *joystick; + + SDL_LockJoysticks(); + for (joystick = SDL_joysticks; joystick; joystick = joystick->next) { + if (joystick->instance_id == instance_id) { + break; + } + } + SDL_UnlockJoysticks(); + return joystick; +} + +/** + * Return the SDL_Joystick associated with a player index. + */ +SDL_Joystick *SDL_JoystickFromPlayerIndex(int player_index) +{ + SDL_JoystickID instance_id; + SDL_Joystick *joystick; + + SDL_LockJoysticks(); + instance_id = SDL_GetJoystickIDForPlayerIndex(player_index); + for (joystick = SDL_joysticks; joystick; joystick = joystick->next) { + if (joystick->instance_id == instance_id) { + break; + } + } + SDL_UnlockJoysticks(); + return joystick; +} + +/* + * Get the friendly name of this joystick + */ +const char *SDL_JoystickName(SDL_Joystick *joystick) +{ + const char *retval; + const SDL_SteamVirtualGamepadInfo *info; + + SDL_LockJoysticks(); + { + CHECK_JOYSTICK_MAGIC(joystick, NULL); + + info = SDL_GetJoystickInstanceVirtualGamepadInfo(joystick->instance_id); + if (info) { + retval = info->name; + } else { + retval = joystick->name; + } + } + SDL_UnlockJoysticks(); + + /* FIXME: Really we should reference count this name so it doesn't go away after unlock */ + return retval; +} + +/* + * Get the implementation dependent path of this joystick + */ +const char *SDL_JoystickPath(SDL_Joystick *joystick) +{ + const char *retval; + + SDL_LockJoysticks(); + { + CHECK_JOYSTICK_MAGIC(joystick, NULL); + + if (joystick->path) { + retval = joystick->path; + } else { + SDL_Unsupported(); + retval = NULL; + } + } + SDL_UnlockJoysticks(); + + return retval; +} + +/** + * Get the player index of an opened joystick, or -1 if it's not available + */ +int SDL_JoystickGetPlayerIndex(SDL_Joystick *joystick) +{ + int retval; + + SDL_LockJoysticks(); + { + CHECK_JOYSTICK_MAGIC(joystick, -1); + + retval = SDL_GetPlayerIndexForJoystickID(joystick->instance_id); + } + SDL_UnlockJoysticks(); + + return retval; +} + +/** + * Set the player index of an opened joystick + */ +void SDL_JoystickSetPlayerIndex(SDL_Joystick *joystick, int player_index) +{ + SDL_LockJoysticks(); + { + CHECK_JOYSTICK_MAGIC(joystick, ); + + SDL_SetJoystickIDForPlayerIndex(player_index, joystick->instance_id); + } + SDL_UnlockJoysticks(); +} + +int SDL_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms) +{ + int retval; + + SDL_LockJoysticks(); + { + CHECK_JOYSTICK_MAGIC(joystick, -1); + + if (low_frequency_rumble == joystick->low_frequency_rumble && + high_frequency_rumble == joystick->high_frequency_rumble) { + /* Just update the expiration */ + retval = 0; + } else { + retval = joystick->driver->Rumble(joystick, low_frequency_rumble, high_frequency_rumble); + joystick->rumble_resend = SDL_GetTicks() + SDL_RUMBLE_RESEND_MS; + if (!joystick->rumble_resend) { + joystick->rumble_resend = 1; + } + } + + if (retval == 0) { + joystick->low_frequency_rumble = low_frequency_rumble; + joystick->high_frequency_rumble = high_frequency_rumble; + + if ((low_frequency_rumble || high_frequency_rumble) && duration_ms) { + joystick->rumble_expiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS); + if (!joystick->rumble_expiration) { + joystick->rumble_expiration = 1; + } + } else { + joystick->rumble_expiration = 0; + joystick->rumble_resend = 0; + } + } + } + SDL_UnlockJoysticks(); + + return retval; +} + +int SDL_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble, Uint32 duration_ms) +{ + int retval; + + SDL_LockJoysticks(); + { + CHECK_JOYSTICK_MAGIC(joystick, -1); + + if (left_rumble == joystick->left_trigger_rumble && right_rumble == joystick->right_trigger_rumble) { + /* Just update the expiration */ + retval = 0; + } else { + retval = joystick->driver->RumbleTriggers(joystick, left_rumble, right_rumble); + } + + if (retval == 0) { + joystick->left_trigger_rumble = left_rumble; + joystick->right_trigger_rumble = right_rumble; + + if ((left_rumble || right_rumble) && duration_ms) { + joystick->trigger_rumble_expiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS); + if (!joystick->trigger_rumble_expiration) { + joystick->trigger_rumble_expiration = 1; + } + } else { + joystick->trigger_rumble_expiration = 0; + } + } + } + SDL_UnlockJoysticks(); + + return retval; +} + +SDL_bool SDL_JoystickHasLED(SDL_Joystick *joystick) +{ + SDL_bool retval; + + SDL_LockJoysticks(); + { + CHECK_JOYSTICK_MAGIC(joystick, SDL_FALSE); + + retval = (joystick->driver->GetCapabilities(joystick) & SDL_JOYCAP_LED) != 0; + } + SDL_UnlockJoysticks(); + + return retval; +} + +SDL_bool SDL_JoystickHasRumble(SDL_Joystick *joystick) +{ + SDL_bool retval; + + SDL_LockJoysticks(); + { + CHECK_JOYSTICK_MAGIC(joystick, SDL_FALSE); + + retval = (joystick->driver->GetCapabilities(joystick) & SDL_JOYCAP_RUMBLE) != 0; + } + SDL_UnlockJoysticks(); + + return retval; +} + +SDL_bool SDL_JoystickHasRumbleTriggers(SDL_Joystick *joystick) +{ + SDL_bool retval; + + SDL_LockJoysticks(); + { + CHECK_JOYSTICK_MAGIC(joystick, SDL_FALSE); + + retval = (joystick->driver->GetCapabilities(joystick) & SDL_JOYCAP_RUMBLE_TRIGGERS) != 0; + } + SDL_UnlockJoysticks(); + + return retval; +} + +int SDL_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + int retval; + SDL_bool isfreshvalue; + + SDL_LockJoysticks(); + { + CHECK_JOYSTICK_MAGIC(joystick, -1); + + isfreshvalue = red != joystick->led_red || + green != joystick->led_green || + blue != joystick->led_blue; + + if (isfreshvalue || SDL_TICKS_PASSED(SDL_GetTicks(), joystick->led_expiration)) { + retval = joystick->driver->SetLED(joystick, red, green, blue); + joystick->led_expiration = SDL_GetTicks() + SDL_LED_MIN_REPEAT_MS; + } else { + /* Avoid spamming the driver */ + retval = 0; + } + + /* Save the LED value regardless of success, so we don't spam the driver */ + joystick->led_red = red; + joystick->led_green = green; + joystick->led_blue = blue; + } + SDL_UnlockJoysticks(); + + return retval; +} + +int SDL_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) +{ + int retval; + + SDL_LockJoysticks(); + { + CHECK_JOYSTICK_MAGIC(joystick, -1); + + retval = joystick->driver->SendEffect(joystick, data, size); + } + SDL_UnlockJoysticks(); + + return retval; +} + +/* + * Close a joystick previously opened with SDL_JoystickOpen() + */ +void SDL_JoystickClose(SDL_Joystick *joystick) +{ + SDL_Joystick *joysticklist; + SDL_Joystick *joysticklistprev; + int i; + + SDL_LockJoysticks(); + { + CHECK_JOYSTICK_MAGIC(joystick, ); + + /* First decrement ref count */ + if (--joystick->ref_count > 0) { + SDL_UnlockJoysticks(); + return; + } + + if (joystick->rumble_expiration) { + SDL_JoystickRumble(joystick, 0, 0, 0); + } + if (joystick->trigger_rumble_expiration) { + SDL_JoystickRumbleTriggers(joystick, 0, 0, 0); + } + + joystick->driver->Close(joystick); + joystick->hwdata = NULL; + joystick->magic = NULL; + + joysticklist = SDL_joysticks; + joysticklistprev = NULL; + while (joysticklist) { + if (joystick == joysticklist) { + if (joysticklistprev) { + /* unlink this entry */ + joysticklistprev->next = joysticklist->next; + } else { + SDL_joysticks = joystick->next; + } + break; + } + joysticklistprev = joysticklist; + joysticklist = joysticklist->next; + } + + SDL_free(joystick->name); + SDL_free(joystick->path); + SDL_free(joystick->serial); + + /* Free the data associated with this joystick */ + SDL_free(joystick->axes); + SDL_free(joystick->hats); + SDL_free(joystick->balls); + SDL_free(joystick->buttons); + for (i = 0; i < joystick->ntouchpads; i++) { + SDL_JoystickTouchpadInfo *touchpad = &joystick->touchpads[i]; + SDL_free(touchpad->fingers); + } + SDL_free(joystick->touchpads); + SDL_free(joystick->sensors); + SDL_free(joystick); + } + SDL_UnlockJoysticks(); +} + +void SDL_JoystickQuit(void) +{ + int i; + + SDL_LockJoysticks(); + + SDL_joysticks_quitting = SDL_TRUE; + + /* Stop the event polling */ + while (SDL_joysticks) { + SDL_joysticks->ref_count = 1; + SDL_JoystickClose(SDL_joysticks); + } + + /* Quit drivers in reverse order to avoid breaking dependencies between drivers */ + for (i = SDL_arraysize(SDL_joystick_drivers) - 1; i >= 0; --i) { + SDL_joystick_drivers[i]->Quit(); + } + + if (SDL_joystick_players) { + SDL_free(SDL_joystick_players); + SDL_joystick_players = NULL; + SDL_joystick_player_count = 0; + } + +#ifndef SDL_EVENTS_DISABLED + SDL_QuitSubSystem(SDL_INIT_EVENTS); +#endif + + SDL_QuitSteamVirtualGamepadInfo(); + + SDL_DelHintCallback(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, + SDL_JoystickAllowBackgroundEventsChanged, NULL); + + SDL_FreeVIDPIDList(&arcadestick_devices); + SDL_FreeVIDPIDList(&blacklist_devices); + SDL_FreeVIDPIDList(&flightstick_devices); + SDL_FreeVIDPIDList(&gamecube_devices); + SDL_FreeVIDPIDList(&rog_gamepad_mice); + SDL_FreeVIDPIDList(&throttle_devices); + SDL_FreeVIDPIDList(&wheel_devices); + SDL_FreeVIDPIDList(&zero_centered_devices); + + SDL_GameControllerQuitMappings(); + + SDL_joysticks_quitting = SDL_FALSE; + SDL_joysticks_initialized = SDL_FALSE; + + SDL_UnlockJoysticks(); +} + +static SDL_bool SDL_PrivateJoystickShouldIgnoreEvent(void) +{ + if (SDL_joystick_allows_background_events) { + return SDL_FALSE; + } + + if (SDL_HasWindows() && SDL_GetKeyboardFocus() == NULL) { + /* We have windows but we don't have focus, ignore the event. */ + return SDL_TRUE; + } + return SDL_FALSE; +} + +/* These are global for SDL_sysjoystick.c and SDL_events.c */ + +void SDL_PrivateJoystickAddTouchpad(SDL_Joystick *joystick, int nfingers) +{ + int ntouchpads; + SDL_JoystickTouchpadInfo *touchpads; + + SDL_AssertJoysticksLocked(); + + ntouchpads = joystick->ntouchpads + 1; + touchpads = (SDL_JoystickTouchpadInfo *)SDL_realloc(joystick->touchpads, (ntouchpads * sizeof(SDL_JoystickTouchpadInfo))); + if (touchpads) { + SDL_JoystickTouchpadInfo *touchpad = &touchpads[ntouchpads - 1]; + SDL_JoystickTouchpadFingerInfo *fingers = (SDL_JoystickTouchpadFingerInfo *)SDL_calloc(nfingers, sizeof(SDL_JoystickTouchpadFingerInfo)); + + if (fingers) { + touchpad->nfingers = nfingers; + touchpad->fingers = fingers; + } else { + /* Out of memory, this touchpad won't be active */ + touchpad->nfingers = 0; + touchpad->fingers = NULL; + } + + joystick->ntouchpads = ntouchpads; + joystick->touchpads = touchpads; + } +} + +void SDL_PrivateJoystickAddSensor(SDL_Joystick *joystick, SDL_SensorType type, float rate) +{ + int nsensors; + SDL_JoystickSensorInfo *sensors; + + SDL_AssertJoysticksLocked(); + + nsensors = joystick->nsensors + 1; + sensors = (SDL_JoystickSensorInfo *)SDL_realloc(joystick->sensors, (nsensors * sizeof(SDL_JoystickSensorInfo))); + if (sensors) { + SDL_JoystickSensorInfo *sensor = &sensors[nsensors - 1]; + + SDL_zerop(sensor); + sensor->type = type; + sensor->rate = rate; + + joystick->nsensors = nsensors; + joystick->sensors = sensors; + } +} + +void SDL_PrivateJoystickAdded(SDL_JoystickID device_instance) +{ + SDL_JoystickDriver *driver; + int driver_device_index; + int player_index = -1; + int device_index = SDL_JoystickGetDeviceIndexFromInstanceID(device_instance); + if (device_index < 0) { + return; + } + + SDL_AssertJoysticksLocked(); + + if (SDL_JoysticksQuitting()) { + return; + } + + if (SDL_GetDriverAndJoystickIndex(device_index, &driver, &driver_device_index)) { + player_index = driver->GetDeviceSteamVirtualGamepadSlot(driver_device_index); + if (player_index < 0) { + player_index = driver->GetDevicePlayerIndex(driver_device_index); + } + } + if (player_index < 0 && SDL_IsGameController(device_index)) { + player_index = SDL_FindFreePlayerIndex(); + } + if (player_index >= 0) { + SDL_SetJoystickIDForPlayerIndex(player_index, device_instance); + } + +#ifndef SDL_EVENTS_DISABLED + { + SDL_Event event; + + event.type = SDL_JOYDEVICEADDED; + + if (SDL_GetEventState(event.type) == SDL_ENABLE) { + event.jdevice.which = device_index; + SDL_PushEvent(&event); + } + } +#endif /* !SDL_EVENTS_DISABLED */ +} + +#ifndef SDL_EVENTS_DISABLED +/* + * If there is an existing add event in the queue, it needs to be modified + * to have the right value for which, because the number of controllers in + * the system is now one less. + */ +static void UpdateEventsForDeviceRemoval(int device_index, Uint32 type) +{ + int i, num_events; + SDL_Event *events; + SDL_bool isstack; + + num_events = SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, type, type); + if (num_events <= 0) { + return; + } + + events = SDL_small_alloc(SDL_Event, num_events, &isstack); + if (!events) { + return; + } + + num_events = SDL_PeepEvents(events, num_events, SDL_GETEVENT, type, type); + for (i = 0; i < num_events; ++i) { + Sint32 which = -1; + switch (type) { + case SDL_JOYDEVICEADDED: + which = events[i].jdevice.which; + break; + case SDL_CONTROLLERDEVICEADDED: + which = events[i].cdevice.which; + break; + default: + break; + } + if (which < device_index) { + /* No change for index values lower than the removed device */ + } else if (which == device_index) { + /* Drop this event entirely */ + SDL_memmove(&events[i], &events[i + 1], sizeof(*events) * (num_events - (i + 1))); + --num_events; + --i; + } else { + /* Fix up the device index if greater than the removed device */ + switch (type) { + case SDL_JOYDEVICEADDED: + --events[i].jdevice.which; + break; + case SDL_CONTROLLERDEVICEADDED: + --events[i].cdevice.which; + break; + default: + break; + } + } + } + SDL_PeepEvents(events, num_events, SDL_ADDEVENT, 0, 0); + + SDL_small_free(events, isstack); +} +#endif + +void SDL_PrivateJoystickForceRecentering(SDL_Joystick *joystick) +{ + int i, j; + + SDL_AssertJoysticksLocked(); + + /* Tell the app that everything is centered/unpressed... */ + for (i = 0; i < joystick->naxes; i++) { + if (joystick->axes[i].has_initial_value) { + SDL_PrivateJoystickAxis(joystick, i, joystick->axes[i].zero); + } + } + + for (i = 0; i < joystick->nbuttons; i++) { + SDL_PrivateJoystickButton(joystick, i, SDL_RELEASED); + } + + for (i = 0; i < joystick->nhats; i++) { + SDL_PrivateJoystickHat(joystick, i, SDL_HAT_CENTERED); + } + + for (i = 0; i < joystick->ntouchpads; i++) { + SDL_JoystickTouchpadInfo *touchpad = &joystick->touchpads[i]; + + for (j = 0; j < touchpad->nfingers; ++j) { + SDL_PrivateJoystickTouchpad(joystick, i, j, SDL_RELEASED, 0.0f, 0.0f, 0.0f); + } + } +} + +void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance) +{ + SDL_Joystick *joystick = NULL; + int player_index; + int device_index; +#ifndef SDL_EVENTS_DISABLED + SDL_Event event; +#endif + + SDL_AssertJoysticksLocked(); + + /* Find this joystick... */ + device_index = 0; + for (joystick = SDL_joysticks; joystick; joystick = joystick->next) { + if (joystick->instance_id == device_instance) { + SDL_PrivateJoystickForceRecentering(joystick); + joystick->attached = SDL_FALSE; + break; + } + + ++device_index; + } + +#ifndef SDL_EVENTS_DISABLED + SDL_zero(event); + event.type = SDL_JOYDEVICEREMOVED; + + if (SDL_GetEventState(event.type) == SDL_ENABLE) { + event.jdevice.which = device_instance; + SDL_PushEvent(&event); + } + + UpdateEventsForDeviceRemoval(device_index, SDL_JOYDEVICEADDED); + UpdateEventsForDeviceRemoval(device_index, SDL_CONTROLLERDEVICEADDED); +#endif /* !SDL_EVENTS_DISABLED */ + + player_index = SDL_GetPlayerIndexForJoystickID(device_instance); + if (player_index >= 0) { + SDL_joystick_players[player_index] = -1; + } +} + +int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, Uint8 axis, Sint16 value) +{ + int posted; + SDL_JoystickAxisInfo *info; + + SDL_AssertJoysticksLocked(); + + /* Make sure we're not getting garbage or duplicate events */ + if (axis >= joystick->naxes) { + return 0; + } + + info = &joystick->axes[axis]; + if (!info->has_initial_value || + (!info->has_second_value && (info->initial_value <= -32767 || info->initial_value == 32767) && SDL_abs(value) < (SDL_JOYSTICK_AXIS_MAX / 4))) { + info->initial_value = value; + info->value = value; + info->zero = value; + info->has_initial_value = SDL_TRUE; + } else if (value == info->value && !info->sending_initial_value) { + return 0; + } else { + info->has_second_value = SDL_TRUE; + } + if (!info->sent_initial_value) { + /* Make sure we don't send motion until there's real activity on this axis */ + const int MAX_ALLOWED_JITTER = SDL_JOYSTICK_AXIS_MAX / 80; /* ShanWan PS3 controller needed 96 */ + if (SDL_abs(value - info->value) <= MAX_ALLOWED_JITTER && + !SDL_IsJoystickVirtual(joystick->guid)) { + return 0; + } + info->sent_initial_value = SDL_TRUE; + info->sending_initial_value = SDL_TRUE; + SDL_PrivateJoystickAxis(joystick, axis, info->initial_value); + info->sending_initial_value = SDL_FALSE; + } + + /* We ignore events if we don't have keyboard focus, except for centering + * events. + */ + if (SDL_PrivateJoystickShouldIgnoreEvent()) { + if (info->sending_initial_value || + (value > info->zero && value >= info->value) || + (value < info->zero && value <= info->value)) { + return 0; + } + } + + /* Update internal joystick state */ + info->value = value; + + /* Post the event, if desired */ + posted = 0; +#ifndef SDL_EVENTS_DISABLED + if (SDL_GetEventState(SDL_JOYAXISMOTION) == SDL_ENABLE) { + SDL_Event event; + event.type = SDL_JOYAXISMOTION; + event.jaxis.which = joystick->instance_id; + event.jaxis.axis = axis; + event.jaxis.value = value; + posted = SDL_PushEvent(&event) == 1; + } +#endif /* !SDL_EVENTS_DISABLED */ + return posted; +} + +int SDL_PrivateJoystickHat(SDL_Joystick *joystick, Uint8 hat, Uint8 value) +{ + int posted; + + SDL_AssertJoysticksLocked(); + + /* Make sure we're not getting garbage or duplicate events */ + if (hat >= joystick->nhats) { + return 0; + } + if (value == joystick->hats[hat]) { + return 0; + } + + /* We ignore events if we don't have keyboard focus, except for centering + * events. + */ + if (SDL_PrivateJoystickShouldIgnoreEvent()) { + if (value != SDL_HAT_CENTERED) { + return 0; + } + } + + /* Update internal joystick state */ + joystick->hats[hat] = value; + + /* Post the event, if desired */ + posted = 0; +#ifndef SDL_EVENTS_DISABLED + if (SDL_GetEventState(SDL_JOYHATMOTION) == SDL_ENABLE) { + SDL_Event event; + event.jhat.type = SDL_JOYHATMOTION; + event.jhat.which = joystick->instance_id; + event.jhat.hat = hat; + event.jhat.value = value; + posted = SDL_PushEvent(&event) == 1; + } +#endif /* !SDL_EVENTS_DISABLED */ + return posted; +} + +int SDL_PrivateJoystickBall(SDL_Joystick *joystick, Uint8 ball, Sint16 xrel, Sint16 yrel) +{ + int posted; + + SDL_AssertJoysticksLocked(); + + /* Make sure we're not getting garbage events */ + if (ball >= joystick->nballs) { + return 0; + } + + /* We ignore events if we don't have keyboard focus. */ + if (SDL_PrivateJoystickShouldIgnoreEvent()) { + return 0; + } + + /* Update internal mouse state */ + joystick->balls[ball].dx += xrel; + joystick->balls[ball].dy += yrel; + + /* Post the event, if desired */ + posted = 0; +#ifndef SDL_EVENTS_DISABLED + if (SDL_GetEventState(SDL_JOYBALLMOTION) == SDL_ENABLE) { + SDL_Event event; + event.jball.type = SDL_JOYBALLMOTION; + event.jball.which = joystick->instance_id; + event.jball.ball = ball; + event.jball.xrel = xrel; + event.jball.yrel = yrel; + posted = SDL_PushEvent(&event) == 1; + } +#endif /* !SDL_EVENTS_DISABLED */ + return posted; +} + +int SDL_PrivateJoystickButton(SDL_Joystick *joystick, Uint8 button, Uint8 state) +{ + int posted; +#ifndef SDL_EVENTS_DISABLED + SDL_Event event; + + SDL_AssertJoysticksLocked(); + + switch (state) { + case SDL_PRESSED: + event.type = SDL_JOYBUTTONDOWN; + break; + case SDL_RELEASED: + event.type = SDL_JOYBUTTONUP; + break; + default: + /* Invalid state -- bail */ + return 0; + } +#endif /* !SDL_EVENTS_DISABLED */ + + SDL_AssertJoysticksLocked(); + + /* Make sure we're not getting garbage or duplicate events */ + if (button >= joystick->nbuttons) { + return 0; + } + if (state == joystick->buttons[button]) { + return 0; + } + + /* We ignore events if we don't have keyboard focus, except for button + * release. */ + if (SDL_PrivateJoystickShouldIgnoreEvent()) { + if (state == SDL_PRESSED) { + return 0; + } + } + + /* Update internal joystick state */ + joystick->buttons[button] = state; + + /* Post the event, if desired */ + posted = 0; +#ifndef SDL_EVENTS_DISABLED + if (SDL_GetEventState(event.type) == SDL_ENABLE) { + event.jbutton.which = joystick->instance_id; + event.jbutton.button = button; + event.jbutton.state = state; + posted = SDL_PushEvent(&event) == 1; + } +#endif /* !SDL_EVENTS_DISABLED */ + return posted; +} + +static void SendSteamHandleUpdateEvents(void) +{ + SDL_Joystick *joystick; + const SDL_SteamVirtualGamepadInfo *info; + + /* Check to see if any Steam handles changed */ + for (joystick = SDL_joysticks; joystick; joystick = joystick->next) { + SDL_bool changed = SDL_FALSE; + + if (!joystick->is_game_controller) { + continue; + } + + info = SDL_GetJoystickInstanceVirtualGamepadInfo(joystick->instance_id); + if (info) { + if (joystick->steam_handle != info->handle) { + joystick->steam_handle = info->handle; + changed = SDL_TRUE; + } + } else { + if (joystick->steam_handle != 0) { + joystick->steam_handle = 0; + changed = SDL_TRUE; + } + } + if (changed) { + SDL_Event event; + + SDL_zero(event); + event.type = SDL_CONTROLLERSTEAMHANDLEUPDATED; + event.common.timestamp = 0; + event.cdevice.which = joystick->instance_id; + SDL_PushEvent(&event); + } + } +} + +void SDL_JoystickUpdate(void) +{ + int i; + Uint32 now; + SDL_Joystick *joystick; + + if (!SDL_WasInit(SDL_INIT_JOYSTICK)) { + return; + } + + SDL_LockJoysticks(); + + if (SDL_UpdateSteamVirtualGamepadInfo()) { + SendSteamHandleUpdateEvents(); + } + +#ifdef SDL_JOYSTICK_HIDAPI + /* Special function for HIDAPI devices, as a single device can provide multiple SDL_Joysticks */ + HIDAPI_UpdateDevices(); +#endif /* SDL_JOYSTICK_HIDAPI */ + + for (joystick = SDL_joysticks; joystick; joystick = joystick->next) { + if (joystick->attached) { + joystick->driver->Update(joystick); + + if (joystick->delayed_guide_button) { + SDL_GameControllerHandleDelayedGuideButton(joystick); + } + } + + now = SDL_GetTicks(); + if (joystick->rumble_expiration && + SDL_TICKS_PASSED(now, joystick->rumble_expiration)) { + SDL_JoystickRumble(joystick, 0, 0, 0); + joystick->rumble_resend = 0; + } + + if (joystick->rumble_resend && + SDL_TICKS_PASSED(now, joystick->rumble_resend)) { + joystick->driver->Rumble(joystick, joystick->low_frequency_rumble, joystick->high_frequency_rumble); + joystick->rumble_resend = now + SDL_RUMBLE_RESEND_MS; + if (joystick->rumble_resend == 0) { + joystick->rumble_resend = 1; + } + } + + if (joystick->trigger_rumble_expiration && + SDL_TICKS_PASSED(now, joystick->trigger_rumble_expiration)) { + SDL_JoystickRumbleTriggers(joystick, 0, 0, 0); + } + } + + /* this needs to happen AFTER walking the joystick list above, so that any + dangling hardware data from removed devices can be free'd + */ + for (i = 0; i < SDL_arraysize(SDL_joystick_drivers); ++i) { + SDL_joystick_drivers[i]->Detect(); + } + + SDL_UnlockJoysticks(); +} + +int SDL_JoystickEventState(int state) +{ +#ifdef SDL_EVENTS_DISABLED + return SDL_IGNORE; +#else + const Uint32 event_list[] = { + SDL_JOYAXISMOTION, SDL_JOYBALLMOTION, SDL_JOYHATMOTION, + SDL_JOYBUTTONDOWN, SDL_JOYBUTTONUP, SDL_JOYDEVICEADDED, SDL_JOYDEVICEREMOVED, + SDL_JOYBATTERYUPDATED + }; + unsigned int i; + + switch (state) { + case SDL_QUERY: + state = SDL_DISABLE; + for (i = 0; i < SDL_arraysize(event_list); ++i) { + state = SDL_EventState(event_list[i], SDL_QUERY); + if (state == SDL_ENABLE) { + break; + } + } + break; + default: + for (i = 0; i < SDL_arraysize(event_list); ++i) { + (void)SDL_EventState(event_list[i], state); + } + break; + } + return state; +#endif /* SDL_EVENTS_DISABLED */ +} + +void SDL_GetJoystickGUIDInfo(SDL_JoystickGUID guid, Uint16 *vendor, Uint16 *product, Uint16 *version, Uint16 *crc16) +{ + Uint16 *guid16 = (Uint16 *)guid.data; + Uint16 bus = SDL_SwapLE16(guid16[0]); + + if ((bus < ' ' || bus == SDL_HARDWARE_BUS_VIRTUAL) && guid16[3] == 0x0000 && guid16[5] == 0x0000) { + /* This GUID fits the standard form: + * 16-bit bus + * 16-bit CRC16 of the joystick name (can be zero) + * 16-bit vendor ID + * 16-bit zero + * 16-bit product ID + * 16-bit zero + * 16-bit version + * 8-bit driver identifier ('h' for HIDAPI, 'x' for XInput, etc.) + * 8-bit driver-dependent type info + */ + if (vendor) { + *vendor = SDL_SwapLE16(guid16[2]); + } + if (product) { + *product = SDL_SwapLE16(guid16[4]); + } + if (version) { + *version = SDL_SwapLE16(guid16[6]); + } + if (crc16) { + *crc16 = SDL_SwapLE16(guid16[1]); + } + } else if (bus < ' ' || bus == SDL_HARDWARE_BUS_VIRTUAL) { + /* This GUID fits the unknown VID/PID form: + * 16-bit bus + * 16-bit CRC16 of the joystick name (can be zero) + * 11 characters of the joystick name, null terminated + */ + if (vendor) { + *vendor = 0; + } + if (product) { + *product = 0; + } + if (version) { + *version = 0; + } + if (crc16) { + *crc16 = SDL_SwapLE16(guid16[1]); + } + } else { + if (vendor) { + *vendor = 0; + } + if (product) { + *product = 0; + } + if (version) { + *version = 0; + } + if (crc16) { + *crc16 = 0; + } + } +} + +static int PrefixMatch(const char *a, const char *b) +{ + int matchlen = 0; + while (*a && *b) { + if (SDL_tolower((unsigned char)*a++) == SDL_tolower((unsigned char)*b++)) { + ++matchlen; + } else { + break; + } + } + return matchlen; +} + +char *SDL_CreateJoystickName(Uint16 vendor, Uint16 product, const char *vendor_name, const char *product_name) +{ + static struct + { + const char *prefix; + const char *replacement; + } replacements[] = { + { "ASTRO Gaming", "ASTRO" }, + { "Bensussen Deutsch & Associates,Inc.(BDA)", "BDA" }, + { "Guangzhou Chicken Run Network Technology Co., Ltd.", "GameSir" }, + { "HORI CO.,LTD", "HORI" }, + { "HORI CO.,LTD.", "HORI" }, + { "Mad Catz Inc.", "Mad Catz" }, + { "Nintendo Co., Ltd.", "Nintendo" }, + { "NVIDIA Corporation ", "" }, + { "Performance Designed Products", "PDP" }, + { "QANBA USA, LLC", "Qanba" }, + { "QANBA USA,LLC", "Qanba" }, + { "Unknown ", "" }, + }; + const char *custom_name; + char *name; + size_t i, len; + + custom_name = GuessControllerName(vendor, product); + if (custom_name) { + return SDL_strdup(custom_name); + } + + if (!vendor_name) { + vendor_name = ""; + } + if (!product_name) { + product_name = ""; + } + + while (*vendor_name == ' ') { + ++vendor_name; + } + while (*product_name == ' ') { + ++product_name; + } + + if (*vendor_name && *product_name) { + len = (SDL_strlen(vendor_name) + 1 + SDL_strlen(product_name) + 1); + name = (char *)SDL_malloc(len); + if (name) { + (void)SDL_snprintf(name, len, "%s %s", vendor_name, product_name); + } + } else if (*product_name) { + name = SDL_strdup(product_name); + } else if (vendor || product) { + /* Couldn't find a controller name, try to give it one based on device type */ + switch (SDL_GetJoystickGameControllerTypeFromVIDPID(vendor, product, NULL, SDL_TRUE)) { + case SDL_CONTROLLER_TYPE_XBOX360: + name = SDL_strdup("Xbox 360 Controller"); + break; + case SDL_CONTROLLER_TYPE_XBOXONE: + name = SDL_strdup("Xbox One Controller"); + break; + case SDL_CONTROLLER_TYPE_PS3: + name = SDL_strdup("PS3 Controller"); + break; + case SDL_CONTROLLER_TYPE_PS4: + name = SDL_strdup("PS4 Controller"); + break; + case SDL_CONTROLLER_TYPE_PS5: + name = SDL_strdup("DualSense Wireless Controller"); + break; + case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO: + name = SDL_strdup("Nintendo Switch Pro Controller"); + break; + default: + len = (6 + 1 + 6 + 1); + name = (char *)SDL_malloc(len); + if (name) { + (void)SDL_snprintf(name, len, "0x%.4x/0x%.4x", vendor, product); + } + break; + } + } else { + name = SDL_strdup("Controller"); + } + + if (!name) { + return NULL; + } + + /* Trim trailing whitespace */ + for (len = SDL_strlen(name); (len > 0 && name[len - 1] == ' '); --len) { + /* continue */ + } + name[len] = '\0'; + + /* Compress duplicate spaces */ + for (i = 0; i < (len - 1);) { + if (name[i] == ' ' && name[i + 1] == ' ') { + SDL_memmove(&name[i], &name[i + 1], (len - i)); + --len; + } else { + ++i; + } + } + + /* Perform any manufacturer replacements */ + for (i = 0; i < SDL_arraysize(replacements); ++i) { + size_t prefixlen = SDL_strlen(replacements[i].prefix); + if (SDL_strncasecmp(name, replacements[i].prefix, prefixlen) == 0) { + size_t replacementlen = SDL_strlen(replacements[i].replacement); + if (replacementlen <= prefixlen) { + SDL_memcpy(name, replacements[i].replacement, replacementlen); + SDL_memmove(name + replacementlen, name + prefixlen, (len - prefixlen) + 1); + len -= (prefixlen - replacementlen); + } else { + /* FIXME: Need to handle the expand case by reallocating the string */ + } + break; + } + } + + /* Remove duplicate manufacturer or product in the name + * e.g. Razer Razer Raiju Tournament Edition Wired + */ + for (i = 1; i < (len - 1); ++i) { + int matchlen = PrefixMatch(name, &name[i]); + while (matchlen > 0) { + if (name[matchlen] == ' ' || name[matchlen] == '-') { + SDL_memmove(name, name + matchlen + 1, len - matchlen); + break; + } + --matchlen; + } + if (matchlen > 0) { + /* We matched the manufacturer's name and removed it */ + break; + } + } + + return name; +} + +SDL_JoystickGUID SDL_CreateJoystickGUID(Uint16 bus, Uint16 vendor, Uint16 product, Uint16 version, const char *vendor_name, const char *product_name, Uint8 driver_signature, Uint8 driver_data) +{ + SDL_JoystickGUID guid; + Uint16 *guid16 = (Uint16 *)guid.data; + Uint16 crc = 0; + + SDL_zero(guid); + + if (vendor_name && *vendor_name && product_name && *product_name) { + crc = SDL_crc16(crc, vendor_name, SDL_strlen(vendor_name)); + crc = SDL_crc16(crc, " ", 1); + crc = SDL_crc16(crc, product_name, SDL_strlen(product_name)); + } else if (product_name) { + crc = SDL_crc16(crc, product_name, SDL_strlen(product_name)); + } + + /* We only need 16 bits for each of these; space them out to fill 128. */ + /* Byteswap so devices get same GUID on little/big endian platforms. */ + *guid16++ = SDL_SwapLE16(bus); + *guid16++ = SDL_SwapLE16(crc); + + if (vendor && product) { + *guid16++ = SDL_SwapLE16(vendor); + *guid16++ = 0; + *guid16++ = SDL_SwapLE16(product); + *guid16++ = 0; + *guid16++ = SDL_SwapLE16(version); + guid.data[14] = driver_signature; + guid.data[15] = driver_data; + } else { + size_t available_space = sizeof(guid.data) - 4; + + if (driver_signature) { + available_space -= 2; + guid.data[14] = driver_signature; + guid.data[15] = driver_data; + } + SDL_strlcpy((char *)guid16, product_name, available_space); + } + return guid; +} + +SDL_JoystickGUID SDL_CreateJoystickGUIDForName(const char *name) +{ + return SDL_CreateJoystickGUID(SDL_HARDWARE_BUS_UNKNOWN, 0, 0, 0, NULL, name, 0, 0); +} + +void SDL_SetJoystickGUIDVendor(SDL_JoystickGUID *guid, Uint16 vendor) +{ + Uint16 *guid16 = (Uint16 *)guid->data; + + guid16[2] = SDL_SwapLE16(vendor); +} + +void SDL_SetJoystickGUIDProduct(SDL_JoystickGUID *guid, Uint16 product) +{ + Uint16 *guid16 = (Uint16 *)guid->data; + + guid16[4] = SDL_SwapLE16(product); +} + +void SDL_SetJoystickGUIDVersion(SDL_JoystickGUID *guid, Uint16 version) +{ + Uint16 *guid16 = (Uint16 *)guid->data; + + guid16[6] = SDL_SwapLE16(version); +} + +void SDL_SetJoystickGUIDCRC(SDL_JoystickGUID *guid, Uint16 crc) +{ + Uint16 *guid16 = (Uint16 *)guid->data; + + guid16[1] = SDL_SwapLE16(crc); +} + +SDL_GameControllerType SDL_GetJoystickGameControllerTypeFromVIDPID(Uint16 vendor, Uint16 product, const char *name, SDL_bool forUI) +{ + SDL_GameControllerType type = SDL_CONTROLLER_TYPE_UNKNOWN; + + if (vendor == 0x0000 && product == 0x0000) { + /* Some devices are only identifiable by their name */ + if (name && + (SDL_strcmp(name, "Lic Pro Controller") == 0 || + SDL_strcmp(name, "Nintendo Wireless Gamepad") == 0 || + SDL_strcmp(name, "Wireless Gamepad") == 0)) { + /* HORI or PowerA Switch Pro Controller clone */ + type = SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO; + } + + } else if (vendor == 0x0001 && product == 0x0001) { + type = SDL_CONTROLLER_TYPE_UNKNOWN; + + } else if ((vendor == USB_VENDOR_AMAZON && product == USB_PRODUCT_AMAZON_LUNA_CONTROLLER) || + (vendor == BLUETOOTH_VENDOR_AMAZON && product == BLUETOOTH_PRODUCT_LUNA_CONTROLLER)) { + type = SDL_CONTROLLER_TYPE_AMAZON_LUNA; + + } else if (vendor == USB_VENDOR_GOOGLE && product == USB_PRODUCT_GOOGLE_STADIA_CONTROLLER) { + type = SDL_CONTROLLER_TYPE_GOOGLE_STADIA; + + } else if (vendor == USB_VENDOR_NINTENDO && product == USB_PRODUCT_NINTENDO_SWITCH_JOYCON_LEFT) { + type = SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_LEFT; + + } else if (vendor == USB_VENDOR_NINTENDO && product == USB_PRODUCT_NINTENDO_SWITCH_JOYCON_RIGHT) { + if (name && SDL_strstr(name, "NES Controller") != NULL) { + /* We don't have a type for the Nintendo Online NES Controller */ + type = SDL_CONTROLLER_TYPE_UNKNOWN; + } else { + type = SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT; + } + + } else if (vendor == USB_VENDOR_NINTENDO && product == USB_PRODUCT_NINTENDO_SWITCH_JOYCON_GRIP) { + if (name && SDL_strstr(name, "(L)") != NULL) { + type = SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_LEFT; + } else { + type = SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT; + } + + } else if (vendor == USB_VENDOR_NINTENDO && product == USB_PRODUCT_NINTENDO_SWITCH_JOYCON_PAIR) { + type = SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_PAIR; + + } else if (vendor == USB_VENDOR_NVIDIA && + (product == USB_PRODUCT_NVIDIA_SHIELD_CONTROLLER_V103 || + product == USB_PRODUCT_NVIDIA_SHIELD_CONTROLLER_V104)) { + type = SDL_CONTROLLER_TYPE_NVIDIA_SHIELD; + + } else { + switch (GuessControllerType(vendor, product)) { + case k_eControllerType_XBox360Controller: + type = SDL_CONTROLLER_TYPE_XBOX360; + break; + case k_eControllerType_XBoxOneController: + type = SDL_CONTROLLER_TYPE_XBOXONE; + break; + case k_eControllerType_PS3Controller: + type = SDL_CONTROLLER_TYPE_PS3; + break; + case k_eControllerType_PS4Controller: + type = SDL_CONTROLLER_TYPE_PS4; + break; + case k_eControllerType_PS5Controller: + type = SDL_CONTROLLER_TYPE_PS5; + break; + case k_eControllerType_XInputPS4Controller: + if (forUI) { + type = SDL_CONTROLLER_TYPE_PS4; + } else { + type = SDL_CONTROLLER_TYPE_UNKNOWN; + } + break; + case k_eControllerType_SwitchProController: + case k_eControllerType_SwitchInputOnlyController: + type = SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO; + break; + case k_eControllerType_XInputSwitchController: + if (forUI) { + type = SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO; + } else { + type = SDL_CONTROLLER_TYPE_UNKNOWN; + } + break; + default: + break; + } + } + return type; +} + +SDL_GameControllerType SDL_GetJoystickGameControllerTypeFromGUID(SDL_JoystickGUID guid, const char *name) +{ + SDL_GameControllerType type; + Uint16 vendor, product; + + SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL, NULL); + type = SDL_GetJoystickGameControllerTypeFromVIDPID(vendor, product, name, SDL_TRUE); + if (type == SDL_CONTROLLER_TYPE_UNKNOWN) { + if (SDL_IsJoystickXInput(guid)) { + /* This is probably an Xbox One controller */ + return SDL_CONTROLLER_TYPE_XBOXONE; + } + if (SDL_IsJoystickVirtual(guid)) { + return SDL_CONTROLLER_TYPE_VIRTUAL; + } +#ifdef SDL_JOYSTICK_HIDAPI + if (SDL_IsJoystickHIDAPI(guid)) { + return HIDAPI_GetGameControllerTypeFromGUID(guid); + } +#endif /* SDL_JOYSTICK_HIDAPI */ + } + return type; +} + +SDL_bool SDL_JoystickGUIDUsesVersion(SDL_JoystickGUID guid) +{ + Uint16 vendor, product; + + if (SDL_IsJoystickMFI(guid)) { + /* The version bits are used as button capability mask */ + return SDL_FALSE; + } + + SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL, NULL); + if (vendor && product) { + return SDL_TRUE; + } + return SDL_FALSE; +} + +SDL_bool SDL_IsJoystickXboxOne(Uint16 vendor_id, Uint16 product_id) +{ + EControllerType eType = GuessControllerType(vendor_id, product_id); + return eType == k_eControllerType_XBoxOneController; +} + +SDL_bool SDL_IsJoystickXboxOneElite(Uint16 vendor_id, Uint16 product_id) +{ + if (vendor_id == USB_VENDOR_MICROSOFT) { + if (product_id == USB_PRODUCT_XBOX_ONE_ELITE_SERIES_1 || + product_id == USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2 || + product_id == USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2_BLUETOOTH || + product_id == USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2_BLE) { + return SDL_TRUE; + } + } + return SDL_FALSE; +} + +SDL_bool SDL_IsJoystickXboxSeriesX(Uint16 vendor_id, Uint16 product_id) +{ + if (vendor_id == USB_VENDOR_MICROSOFT) { + if (product_id == USB_PRODUCT_XBOX_SERIES_X || + product_id == USB_PRODUCT_XBOX_SERIES_X_BLE) { + return SDL_TRUE; + } + } + if (vendor_id == USB_VENDOR_PDP) { + if (product_id == USB_PRODUCT_XBOX_SERIES_X_VICTRIX_GAMBIT || + product_id == USB_PRODUCT_XBOX_SERIES_X_PDP_BLUE || + product_id == USB_PRODUCT_XBOX_SERIES_X_PDP_AFTERGLOW) { + return SDL_TRUE; + } + } + if (vendor_id == USB_VENDOR_POWERA_ALT) { + if ((product_id >= 0x2001 && product_id <= 0x201a) || + product_id == USB_PRODUCT_XBOX_SERIES_X_POWERA_FUSION_PRO2 || + product_id == USB_PRODUCT_XBOX_SERIES_X_POWERA_SPECTRA) { + return SDL_TRUE; + } + } + if (vendor_id == USB_VENDOR_HORI) { + if (product_id == USB_PRODUCT_HORI_FIGHTING_COMMANDER_OCTA_SERIES_X || + product_id == USB_PRODUCT_HORI_HORIPAD_PRO_SERIES_X) { + return SDL_TRUE; + } + } + if (vendor_id == USB_VENDOR_RAZER) { + if (product_id == USB_PRODUCT_RAZER_WOLVERINE_V2 || + product_id == USB_PRODUCT_RAZER_WOLVERINE_V2_CHROMA) { + return SDL_TRUE; + } + } + if (vendor_id == USB_VENDOR_THRUSTMASTER) { + if (product_id == USB_PRODUCT_THRUSTMASTER_ESWAPX_PRO) { + return SDL_TRUE; + } + } + if (vendor_id == USB_VENDOR_TURTLE_BEACH) { + if (product_id == USB_PRODUCT_TURTLE_BEACH_SERIES_X_REACT_R || + product_id == USB_PRODUCT_TURTLE_BEACH_SERIES_X_RECON) { + return SDL_TRUE; + } + } + if (vendor_id == USB_VENDOR_8BITDO) { + if (product_id == USB_PRODUCT_8BITDO_XBOX_CONTROLLER1 || + product_id == USB_PRODUCT_8BITDO_XBOX_CONTROLLER2) { + return SDL_TRUE; + } + } + if (vendor_id == USB_VENDOR_GAMESIR) { + if (product_id == USB_PRODUCT_GAMESIR_G7) { + return SDL_TRUE; + } + } + if (vendor_id == USB_VENDOR_ASUS) { + if (product_id == USB_PRODUCT_ROG_RAIKIRI) { + return SDL_TRUE; + } + } + return SDL_FALSE; +} + +SDL_bool SDL_IsJoystickBluetoothXboxOne(Uint16 vendor_id, Uint16 product_id) +{ + if (vendor_id == USB_VENDOR_MICROSOFT) { + if (product_id == USB_PRODUCT_XBOX_ONE_ADAPTIVE_BLUETOOTH || + product_id == USB_PRODUCT_XBOX_ONE_ADAPTIVE_BLE || + product_id == USB_PRODUCT_XBOX_ONE_S_REV1_BLUETOOTH || + product_id == USB_PRODUCT_XBOX_ONE_S_REV2_BLUETOOTH || + product_id == USB_PRODUCT_XBOX_ONE_S_REV2_BLE || + product_id == USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2_BLUETOOTH || + product_id == USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2_BLE || + product_id == USB_PRODUCT_XBOX_SERIES_X_BLE) { + return SDL_TRUE; + } + } + return SDL_FALSE; +} + +SDL_bool SDL_IsJoystickPS4(Uint16 vendor_id, Uint16 product_id) +{ + EControllerType eType = GuessControllerType(vendor_id, product_id); + return eType == k_eControllerType_PS4Controller; +} + +SDL_bool SDL_IsJoystickPS5(Uint16 vendor_id, Uint16 product_id) +{ + EControllerType eType = GuessControllerType(vendor_id, product_id); + return eType == k_eControllerType_PS5Controller; +} + +SDL_bool SDL_IsJoystickDualSenseEdge(Uint16 vendor_id, Uint16 product_id) +{ + if (vendor_id == USB_VENDOR_SONY) { + if (product_id == USB_PRODUCT_SONY_DS5_EDGE) { + return SDL_TRUE; + } + } + return SDL_FALSE; +} + +SDL_bool SDL_IsJoystickNintendoSwitchPro(Uint16 vendor_id, Uint16 product_id) +{ + EControllerType eType = GuessControllerType(vendor_id, product_id); + return eType == k_eControllerType_SwitchProController || eType == k_eControllerType_SwitchInputOnlyController; +} + +SDL_bool SDL_IsJoystickNintendoSwitchProInputOnly(Uint16 vendor_id, Uint16 product_id) +{ + EControllerType eType = GuessControllerType(vendor_id, product_id); + return eType == k_eControllerType_SwitchInputOnlyController; +} + +SDL_bool SDL_IsJoystickNintendoSwitchJoyCon(Uint16 vendor_id, Uint16 product_id) +{ + EControllerType eType = GuessControllerType(vendor_id, product_id); + return eType == k_eControllerType_SwitchJoyConLeft || eType == k_eControllerType_SwitchJoyConRight; +} + +SDL_bool SDL_IsJoystickNintendoSwitchJoyConLeft(Uint16 vendor_id, Uint16 product_id) +{ + EControllerType eType = GuessControllerType(vendor_id, product_id); + return eType == k_eControllerType_SwitchJoyConLeft; +} + +SDL_bool SDL_IsJoystickNintendoSwitchJoyConRight(Uint16 vendor_id, Uint16 product_id) +{ + EControllerType eType = GuessControllerType(vendor_id, product_id); + return eType == k_eControllerType_SwitchJoyConRight; +} + +SDL_bool SDL_IsJoystickNintendoSwitchJoyConGrip(Uint16 vendor_id, Uint16 product_id) +{ + return vendor_id == USB_VENDOR_NINTENDO && product_id == USB_PRODUCT_NINTENDO_SWITCH_JOYCON_GRIP; +} + +SDL_bool SDL_IsJoystickNintendoSwitchJoyConPair(Uint16 vendor_id, Uint16 product_id) +{ + return vendor_id == USB_VENDOR_NINTENDO && product_id == USB_PRODUCT_NINTENDO_SWITCH_JOYCON_PAIR; +} + +SDL_bool SDL_IsJoystickSteamController(Uint16 vendor_id, Uint16 product_id) +{ + EControllerType eType = GuessControllerType(vendor_id, product_id); + return eType == k_eControllerType_SteamController || eType == k_eControllerType_SteamControllerV2; +} + +SDL_bool SDL_IsJoystickSteamDeck(Uint16 vendor_id, Uint16 product_id) +{ + EControllerType eType = GuessControllerType(vendor_id, product_id); + return eType == k_eControllerType_SteamDeck; +} + +SDL_bool SDL_IsJoystickXInput(SDL_JoystickGUID guid) +{ + return (guid.data[14] == 'x') ? SDL_TRUE : SDL_FALSE; +} + +SDL_bool SDL_IsJoystickWGI(SDL_JoystickGUID guid) +{ + return (guid.data[14] == 'w') ? SDL_TRUE : SDL_FALSE; +} + +SDL_bool SDL_IsJoystickHIDAPI(SDL_JoystickGUID guid) +{ + return (guid.data[14] == 'h') ? SDL_TRUE : SDL_FALSE; +} + +SDL_bool SDL_IsJoystickMFI(SDL_JoystickGUID guid) +{ + return (guid.data[14] == 'm') ? SDL_TRUE : SDL_FALSE; +} + +SDL_bool SDL_IsJoystickRAWINPUT(SDL_JoystickGUID guid) +{ + return (guid.data[14] == 'r') ? SDL_TRUE : SDL_FALSE; +} + +SDL_bool SDL_IsJoystickVirtual(SDL_JoystickGUID guid) +{ + return (guid.data[14] == 'v') ? SDL_TRUE : SDL_FALSE; +} + +static SDL_bool SDL_IsJoystickWheel(Uint16 vendor_id, Uint16 product_id) +{ + return SDL_VIDPIDInList(vendor_id, product_id, &wheel_devices); +} + +static SDL_bool SDL_IsJoystickArcadeStick(Uint16 vendor_id, Uint16 product_id) +{ + return SDL_VIDPIDInList(vendor_id, product_id, &arcadestick_devices); +} + +static SDL_bool SDL_IsJoystickFlightStick(Uint16 vendor_id, Uint16 product_id) +{ + return SDL_VIDPIDInList(vendor_id, product_id, &flightstick_devices); +} + +static SDL_bool SDL_IsJoystickThrottle(Uint16 vendor_id, Uint16 product_id) +{ + return SDL_VIDPIDInList(vendor_id, product_id, &throttle_devices); +} + +static SDL_JoystickType SDL_GetJoystickGUIDType(SDL_JoystickGUID guid) +{ + Uint16 vendor; + Uint16 product; + + SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL, NULL); + + if (SDL_IsJoystickWheel(vendor, product)) { + return SDL_JOYSTICK_TYPE_WHEEL; + } + + if (SDL_IsJoystickArcadeStick(vendor, product)) { + return SDL_JOYSTICK_TYPE_ARCADE_STICK; + } + + if (SDL_IsJoystickFlightStick(vendor, product)) { + return SDL_JOYSTICK_TYPE_FLIGHT_STICK; + } + + if (SDL_IsJoystickThrottle(vendor, product)) { + return SDL_JOYSTICK_TYPE_THROTTLE; + } + + if (SDL_IsJoystickXInput(guid)) { + /* XInput GUID, get the type based on the XInput device subtype */ + switch (guid.data[15]) { + case 0x01: /* XINPUT_DEVSUBTYPE_GAMEPAD */ + return SDL_JOYSTICK_TYPE_GAMECONTROLLER; + case 0x02: /* XINPUT_DEVSUBTYPE_WHEEL */ + return SDL_JOYSTICK_TYPE_WHEEL; + case 0x03: /* XINPUT_DEVSUBTYPE_ARCADE_STICK */ + return SDL_JOYSTICK_TYPE_ARCADE_STICK; + case 0x04: /* XINPUT_DEVSUBTYPE_FLIGHT_STICK */ + return SDL_JOYSTICK_TYPE_FLIGHT_STICK; + case 0x05: /* XINPUT_DEVSUBTYPE_DANCE_PAD */ + return SDL_JOYSTICK_TYPE_DANCE_PAD; + case 0x06: /* XINPUT_DEVSUBTYPE_GUITAR */ + case 0x07: /* XINPUT_DEVSUBTYPE_GUITAR_ALTERNATE */ + case 0x0B: /* XINPUT_DEVSUBTYPE_GUITAR_BASS */ + return SDL_JOYSTICK_TYPE_GUITAR; + case 0x08: /* XINPUT_DEVSUBTYPE_DRUM_KIT */ + return SDL_JOYSTICK_TYPE_DRUM_KIT; + case 0x13: /* XINPUT_DEVSUBTYPE_ARCADE_PAD */ + return SDL_JOYSTICK_TYPE_ARCADE_PAD; + default: + return SDL_JOYSTICK_TYPE_UNKNOWN; + } + } + + if (SDL_IsJoystickWGI(guid)) { + return (SDL_JoystickType)guid.data[15]; + } + + if (SDL_IsJoystickVirtual(guid)) { + return (SDL_JoystickType)guid.data[15]; + } + +#ifdef SDL_JOYSTICK_HIDAPI + if (SDL_IsJoystickHIDAPI(guid)) { + return HIDAPI_GetJoystickTypeFromGUID(guid); + } +#endif /* SDL_JOYSTICK_HIDAPI */ + + if (GuessControllerType(vendor, product) != k_eControllerType_UnknownNonSteamController) { + return SDL_JOYSTICK_TYPE_GAMECONTROLLER; + } + + return SDL_JOYSTICK_TYPE_UNKNOWN; +} + +SDL_bool SDL_ShouldIgnoreJoystick(const char *name, SDL_JoystickGUID guid) +{ + Uint16 vendor; + Uint16 product; + + SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL, NULL); + + /* Check the joystick blacklist */ + if (SDL_VIDPIDInList(vendor, product, &blacklist_devices)) { + return SDL_TRUE; + } + if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_ROG_CHAKRAM, SDL_FALSE)) { + if (SDL_VIDPIDInList(vendor, product, &rog_gamepad_mice)) { + return SDL_TRUE; + } + } + + if (SDL_ShouldIgnoreGameController(name, guid)) { + return SDL_TRUE; + } + + return SDL_FALSE; +} + +/* return the guid for this index */ +SDL_JoystickGUID SDL_JoystickGetDeviceGUID(int device_index) +{ + SDL_JoystickDriver *driver; + SDL_JoystickGUID guid; + + SDL_LockJoysticks(); + if (SDL_GetDriverAndJoystickIndex(device_index, &driver, &device_index)) { + guid = driver->GetDeviceGUID(device_index); + } else { + SDL_zero(guid); + } + SDL_UnlockJoysticks(); + + return guid; +} + +Uint16 SDL_JoystickGetDeviceVendor(int device_index) +{ + Uint16 vendor; + const SDL_SteamVirtualGamepadInfo *info; + + SDL_LockJoysticks(); + info = SDL_GetJoystickInstanceVirtualGamepadInfo(SDL_JoystickGetDeviceInstanceID(device_index)); + if (info) { + vendor = info->vendor_id; + } else { + SDL_JoystickGUID guid = SDL_JoystickGetDeviceGUID(device_index); + + SDL_GetJoystickGUIDInfo(guid, &vendor, NULL, NULL, NULL); + } + SDL_UnlockJoysticks(); + + return vendor; +} + +Uint16 SDL_JoystickGetDeviceProduct(int device_index) +{ + Uint16 product; + const SDL_SteamVirtualGamepadInfo *info; + + SDL_LockJoysticks(); + info = SDL_GetJoystickInstanceVirtualGamepadInfo(SDL_JoystickGetDeviceInstanceID(device_index)); + if (info) { + product = info->product_id; + } else { + SDL_JoystickGUID guid = SDL_JoystickGetDeviceGUID(device_index); + + SDL_GetJoystickGUIDInfo(guid, NULL, &product, NULL, NULL); + } + SDL_UnlockJoysticks(); + + return product; +} + +Uint16 SDL_JoystickGetDeviceProductVersion(int device_index) +{ + Uint16 version; + SDL_JoystickGUID guid = SDL_JoystickGetDeviceGUID(device_index); + + SDL_GetJoystickGUIDInfo(guid, NULL, NULL, &version, NULL); + return version; +} + +SDL_JoystickType SDL_JoystickGetDeviceType(int device_index) +{ + SDL_JoystickType type; + SDL_JoystickGUID guid = SDL_JoystickGetDeviceGUID(device_index); + + type = SDL_GetJoystickGUIDType(guid); + if (type == SDL_JOYSTICK_TYPE_UNKNOWN) { + if (SDL_IsGameController(device_index)) { + type = SDL_JOYSTICK_TYPE_GAMECONTROLLER; + } + } + return type; +} + +SDL_JoystickID SDL_JoystickGetDeviceInstanceID(int device_index) +{ + SDL_JoystickDriver *driver; + SDL_JoystickID instance_id = -1; + + SDL_LockJoysticks(); + if (SDL_GetDriverAndJoystickIndex(device_index, &driver, &device_index)) { + instance_id = driver->GetDeviceInstanceID(device_index); + } + SDL_UnlockJoysticks(); + + return instance_id; +} + +int SDL_JoystickGetDeviceIndexFromInstanceID(SDL_JoystickID instance_id) +{ + int i, num_joysticks, device_index = -1; + + SDL_LockJoysticks(); + num_joysticks = SDL_NumJoysticks(); + for (i = 0; i < num_joysticks; ++i) { + if (SDL_JoystickGetDeviceInstanceID(i) == instance_id) { + device_index = i; + break; + } + } + SDL_UnlockJoysticks(); + + return device_index; +} + +SDL_JoystickGUID SDL_JoystickGetGUID(SDL_Joystick *joystick) +{ + SDL_JoystickGUID retval; + + SDL_LockJoysticks(); + { + static SDL_JoystickGUID emptyGUID; + + CHECK_JOYSTICK_MAGIC(joystick, emptyGUID); + + retval = joystick->guid; + } + SDL_UnlockJoysticks(); + + return retval; +} + +Uint16 SDL_JoystickGetVendor(SDL_Joystick *joystick) +{ + Uint16 vendor; + const SDL_SteamVirtualGamepadInfo *info; + + SDL_LockJoysticks(); + { + CHECK_JOYSTICK_MAGIC(joystick, 0); + + info = SDL_GetJoystickInstanceVirtualGamepadInfo(joystick->instance_id); + if (info) { + vendor = info->vendor_id; + } else { + SDL_JoystickGUID guid = SDL_JoystickGetGUID(joystick); + + SDL_GetJoystickGUIDInfo(guid, &vendor, NULL, NULL, NULL); + } + } + SDL_UnlockJoysticks(); + + return vendor; +} + +Uint16 SDL_JoystickGetProduct(SDL_Joystick *joystick) +{ + Uint16 product; + const SDL_SteamVirtualGamepadInfo *info; + + SDL_LockJoysticks(); + { + CHECK_JOYSTICK_MAGIC(joystick, 0); + + info = SDL_GetJoystickInstanceVirtualGamepadInfo(joystick->instance_id); + if (info) { + product = info->product_id; + } else { + SDL_JoystickGUID guid = SDL_JoystickGetGUID(joystick); + + SDL_GetJoystickGUIDInfo(guid, NULL, &product, NULL, NULL); + } + } + SDL_UnlockJoysticks(); + + return product; +} + +Uint16 SDL_JoystickGetProductVersion(SDL_Joystick *joystick) +{ + Uint16 version; + SDL_JoystickGUID guid = SDL_JoystickGetGUID(joystick); + + SDL_GetJoystickGUIDInfo(guid, NULL, NULL, &version, NULL); + return version; +} + +Uint16 SDL_JoystickGetFirmwareVersion(SDL_Joystick *joystick) +{ + Uint16 retval; + + SDL_LockJoysticks(); + { + CHECK_JOYSTICK_MAGIC(joystick, 0); + + retval = joystick->firmware_version; + } + SDL_UnlockJoysticks(); + + return retval; +} + +const char *SDL_JoystickGetSerial(SDL_Joystick *joystick) +{ + const char *retval; + + SDL_LockJoysticks(); + { + CHECK_JOYSTICK_MAGIC(joystick, NULL); + + retval = joystick->serial; + } + SDL_UnlockJoysticks(); + + return retval; +} + +SDL_JoystickType SDL_JoystickGetType(SDL_Joystick *joystick) +{ + SDL_JoystickType type; + SDL_JoystickGUID guid = SDL_JoystickGetGUID(joystick); + + type = SDL_GetJoystickGUIDType(guid); + if (type == SDL_JOYSTICK_TYPE_UNKNOWN) { + SDL_LockJoysticks(); + { + CHECK_JOYSTICK_MAGIC(joystick, SDL_JOYSTICK_TYPE_UNKNOWN); + + if (joystick->is_game_controller) { + type = SDL_JOYSTICK_TYPE_GAMECONTROLLER; + } + } + SDL_UnlockJoysticks(); + } + return type; +} + +/* convert the guid to a printable string */ +void SDL_JoystickGetGUIDString(SDL_JoystickGUID guid, char *pszGUID, int cbGUID) +{ + SDL_GUIDToString(guid, pszGUID, cbGUID); +} + +/* convert the string version of a joystick guid to the struct */ +SDL_JoystickGUID SDL_JoystickGetGUIDFromString(const char *pchGUID) +{ + return SDL_GUIDFromString(pchGUID); +} + +/* update the power level for this joystick */ +void SDL_PrivateJoystickBatteryLevel(SDL_Joystick *joystick, SDL_JoystickPowerLevel ePowerLevel) +{ + SDL_AssertJoysticksLocked(); + + SDL_assert(joystick->ref_count); /* make sure we are calling this only for update, not for initialization */ + if (ePowerLevel != joystick->epowerlevel) { +#ifndef SDL_EVENTS_DISABLED + if (SDL_GetEventState(SDL_JOYBATTERYUPDATED) == SDL_ENABLE) { + SDL_Event event; + event.type = SDL_JOYBATTERYUPDATED; + event.jbattery.which = joystick->instance_id; + event.jbattery.level = ePowerLevel; + SDL_PushEvent(&event); + } +#endif /* !SDL_EVENTS_DISABLED */ + joystick->epowerlevel = ePowerLevel; + } +} + +/* return its power level */ +SDL_JoystickPowerLevel SDL_JoystickCurrentPowerLevel(SDL_Joystick *joystick) +{ + SDL_JoystickPowerLevel retval; + + SDL_LockJoysticks(); + { + CHECK_JOYSTICK_MAGIC(joystick, SDL_JOYSTICK_POWER_UNKNOWN); + + retval = joystick->epowerlevel; + } + SDL_UnlockJoysticks(); + + return retval; +} + +int SDL_PrivateJoystickTouchpad(SDL_Joystick *joystick, int touchpad, int finger, Uint8 state, float x, float y, float pressure) +{ + SDL_JoystickTouchpadInfo *touchpad_info; + SDL_JoystickTouchpadFingerInfo *finger_info; + int posted; + Uint32 event_type; + + SDL_AssertJoysticksLocked(); + + if (touchpad < 0 || touchpad >= joystick->ntouchpads) { + return 0; + } + + touchpad_info = &joystick->touchpads[touchpad]; + if (finger < 0 || finger >= touchpad_info->nfingers) { + return 0; + } + + finger_info = &touchpad_info->fingers[finger]; + + if (!state) { + if (x == 0.0f && y == 0.0f) { + x = finger_info->x; + y = finger_info->y; + } + pressure = 0.0f; + } + + if (x < 0.0f) { + x = 0.0f; + } else if (x > 1.0f) { + x = 1.0f; + } + if (y < 0.0f) { + y = 0.0f; + } else if (y > 1.0f) { + y = 1.0f; + } + if (pressure < 0.0f) { + pressure = 0.0f; + } else if (pressure > 1.0f) { + pressure = 1.0f; + } + + if (state == finger_info->state) { + if (!state || + (x == finger_info->x && y == finger_info->y && pressure == finger_info->pressure)) { + return 0; + } + } + + if (state == finger_info->state) { + event_type = SDL_CONTROLLERTOUCHPADMOTION; + } else if (state) { + event_type = SDL_CONTROLLERTOUCHPADDOWN; + } else { + event_type = SDL_CONTROLLERTOUCHPADUP; + } + + /* We ignore events if we don't have keyboard focus, except for touch release */ + if (SDL_PrivateJoystickShouldIgnoreEvent()) { + if (event_type != SDL_CONTROLLERTOUCHPADUP) { + return 0; + } + } + + /* Update internal joystick state */ + finger_info->state = state; + finger_info->x = x; + finger_info->y = y; + finger_info->pressure = pressure; + + /* Post the event, if desired */ + posted = 0; +#ifndef SDL_EVENTS_DISABLED + if (SDL_GetEventState(event_type) == SDL_ENABLE) { + SDL_Event event; + event.type = event_type; + event.ctouchpad.which = joystick->instance_id; + event.ctouchpad.touchpad = touchpad; + event.ctouchpad.finger = finger; + event.ctouchpad.x = x; + event.ctouchpad.y = y; + event.ctouchpad.pressure = pressure; + posted = SDL_PushEvent(&event) == 1; + } +#endif /* !SDL_EVENTS_DISABLED */ + return posted; +} + +int SDL_PrivateJoystickSensor(SDL_Joystick *joystick, SDL_SensorType type, Uint64 timestamp_us, const float *data, int num_values) +{ + int i; + int posted = 0; + + SDL_AssertJoysticksLocked(); + + /* We ignore events if we don't have keyboard focus */ + if (SDL_PrivateJoystickShouldIgnoreEvent()) { + return 0; + } + + for (i = 0; i < joystick->nsensors; ++i) { + SDL_JoystickSensorInfo *sensor = &joystick->sensors[i]; + + if (sensor->type == type) { + if (sensor->enabled) { + num_values = SDL_min(num_values, SDL_arraysize(sensor->data)); + + /* Update internal sensor state */ + SDL_memcpy(sensor->data, data, num_values * sizeof(*data)); + sensor->timestamp_us = timestamp_us; + + /* Post the event, if desired */ +#ifndef SDL_EVENTS_DISABLED + if (SDL_GetEventState(SDL_CONTROLLERSENSORUPDATE) == SDL_ENABLE) { + SDL_Event event; + event.type = SDL_CONTROLLERSENSORUPDATE; + event.csensor.which = joystick->instance_id; + event.csensor.sensor = type; + num_values = SDL_min(num_values, SDL_arraysize(event.csensor.data)); + SDL_memset(event.csensor.data, 0, sizeof(event.csensor.data)); + SDL_memcpy(event.csensor.data, data, num_values * sizeof(*data)); + event.csensor.timestamp_us = timestamp_us; + posted = SDL_PushEvent(&event) == 1; + } +#endif /* !SDL_EVENTS_DISABLED */ + } + break; + } + } + return posted; +} + +static void SDL_LoadVIDPIDListFromHint(const char *hint, int *num_entries, int *max_entries, Uint32 **entries) +{ + Uint32 entry; + char *spot; + char *file = NULL; + + if (hint && *hint == '@') { + spot = file = (char *)SDL_LoadFile(hint + 1, NULL); + } else { + spot = (char *)hint; + } + + if (spot == NULL) { + return; + } + + while ((spot = SDL_strstr(spot, "0x")) != NULL) { + entry = (Uint16)SDL_strtol(spot, &spot, 0); + entry <<= 16; + spot = SDL_strstr(spot, "0x"); + if (spot == NULL) { + break; + } + entry |= (Uint16)SDL_strtol(spot, &spot, 0); + + if (*num_entries == *max_entries) { + int new_max_entries = *max_entries + 16; + Uint32 *new_entries = (Uint32 *)SDL_realloc(*entries, new_max_entries * sizeof(**entries)); + if (!new_entries) { + /* Out of memory, go with what we have already */ + break; + } + *entries = new_entries; + *max_entries = new_max_entries; + } + (*entries)[(*num_entries)++] = entry; + } + + if (file) { + SDL_free(file); + } +} + +void SDL_LoadVIDPIDListFromHints(SDL_vidpid_list *list, const char *included_list, const char *excluded_list) +{ + /* Empty the list */ + list->num_included_entries = 0; + list->num_excluded_entries = 0; + + /* Add the initial entries */ + if (list->num_initial_entries > 0) { + if (list->num_included_entries < list->num_initial_entries) { + Uint32 *entries = (Uint32 *)SDL_malloc(list->num_initial_entries * sizeof(*entries)); + if (entries) { + SDL_memcpy(entries, list->initial_entries, list->num_initial_entries * sizeof(*entries)); + list->included_entries = entries; + list->num_included_entries = list->num_initial_entries; + list->max_included_entries = list->num_initial_entries; + } + } + } + + /* Add the included entries from the hint */ + SDL_LoadVIDPIDListFromHint(included_list, &list->num_included_entries, &list->max_included_entries, &list->included_entries); + + /* Add the excluded entries from the hint */ + SDL_LoadVIDPIDListFromHint(excluded_list, &list->num_excluded_entries, &list->max_excluded_entries, &list->excluded_entries); +} + +static void SDLCALL SDL_VIDPIDIncludedHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + SDL_vidpid_list *list = (SDL_vidpid_list *)userdata; + const char *included_list = hint; + const char *excluded_list = NULL; + + if (!list->initialized) { + return; + } + + if (list->excluded_hint_name) { + excluded_list = SDL_GetHint(list->excluded_hint_name); + } + SDL_LoadVIDPIDListFromHints(list, included_list, excluded_list); +} + +static void SDLCALL SDL_VIDPIDExcludedHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + SDL_vidpid_list *list = (SDL_vidpid_list *)userdata; + const char *included_list = NULL; + const char *excluded_list = hint; + + if (!list->initialized) { + return; + } + + if (list->included_hint_name) { + included_list = SDL_GetHint(list->included_hint_name); + } + SDL_LoadVIDPIDListFromHints(list, included_list, excluded_list); +} + +void SDL_LoadVIDPIDList(SDL_vidpid_list *list) +{ + const char *included_list = NULL; + const char *excluded_list = NULL; + + if (list->included_hint_name) { + SDL_AddHintCallback(list->included_hint_name, SDL_VIDPIDIncludedHintChanged, list); + } + + if (list->excluded_hint_name) { + SDL_AddHintCallback(list->excluded_hint_name, SDL_VIDPIDExcludedHintChanged, list); + } + + list->initialized = SDL_TRUE; + + if (list->included_hint_name) { + included_list = SDL_GetHint(list->included_hint_name); + } + if (list->excluded_hint_name) { + excluded_list = SDL_GetHint(list->excluded_hint_name); + } + SDL_LoadVIDPIDListFromHints(list, included_list, excluded_list); +} + +SDL_bool SDL_VIDPIDInList(Uint16 vendor_id, Uint16 product_id, const SDL_vidpid_list *list) +{ + int i; + Uint32 vidpid = MAKE_VIDPID(vendor_id, product_id); + + for (i = 0; i < list->num_excluded_entries; ++i) { + if (vidpid == list->excluded_entries[i]) { + return SDL_FALSE; + } + } + for (i = 0; i < list->num_included_entries; ++i) { + if (vidpid == list->included_entries[i]) { + return SDL_TRUE; + } + } + return SDL_FALSE; +} + +void SDL_FreeVIDPIDList(SDL_vidpid_list *list) +{ + if (list->included_hint_name) { + SDL_DelHintCallback(list->included_hint_name, SDL_VIDPIDIncludedHintChanged, list); + } + + if (list->excluded_hint_name) { + SDL_DelHintCallback(list->excluded_hint_name, SDL_VIDPIDExcludedHintChanged, list); + } + + if (list->included_entries) { + SDL_free(list->included_entries); + list->included_entries = NULL; + list->num_included_entries = 0; + list->max_included_entries = 0; + } + + if (list->excluded_entries) { + SDL_free(list->excluded_entries); + list->excluded_entries = NULL; + list->num_excluded_entries = 0; + list->max_excluded_entries = 0; + } + + list->initialized = SDL_FALSE; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/joystick/SDL_joystick_c.h b/SDL2-2.30.5/src/joystick/SDL_joystick_c.h new file mode 100644 index 0000000..44d8e8c --- /dev/null +++ b/SDL2-2.30.5/src/joystick/SDL_joystick_c.h @@ -0,0 +1,275 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#ifndef SDL_joystick_c_h_ +#define SDL_joystick_c_h_ + +#include "../SDL_internal.h" + +/* Useful functions and variables from SDL_joystick.c */ +#include "SDL_gamecontroller.h" +#include "SDL_joystick.h" + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +struct _SDL_JoystickDriver; +struct SDL_SteamVirtualGamepadInfo; +extern char SDL_joystick_magic; + +/* Initialization and shutdown functions */ +extern int SDL_JoystickInit(void); +extern void SDL_JoystickQuit(void); + +/* Return whether the joystick system is currently initialized */ +extern SDL_bool SDL_JoysticksInitialized(void); + +/* Return whether the joystick system is shutting down */ +extern SDL_bool SDL_JoysticksQuitting(void); + +/* Return whether the joysticks are currently locked */ +extern SDL_bool SDL_JoysticksLocked(void); + +/* Make sure we currently have the joysticks locked */ +extern void SDL_AssertJoysticksLocked(void) SDL_ASSERT_CAPABILITY(SDL_joystick_lock); + +/* Function to get the next available joystick instance ID */ +extern SDL_JoystickID SDL_GetNextJoystickInstanceID(void); + +/* Initialization and shutdown functions */ +extern int SDL_GameControllerInitMappings(void); +extern void SDL_GameControllerQuitMappings(void); +extern int SDL_GameControllerInit(void); +extern void SDL_GameControllerQuit(void); + +/* Function to return the device index for a joystick ID, or -1 if not found */ +extern int SDL_JoystickGetDeviceIndexFromInstanceID(SDL_JoystickID instance_id); + +/* Function to standardize the name for a controller + This should be freed with SDL_free() when no longer needed + */ +extern char *SDL_CreateJoystickName(Uint16 vendor, Uint16 product, const char *vendor_name, const char *product_name); + +/* Function to create a GUID for a joystick based on the VID/PID and name */ +extern SDL_JoystickGUID SDL_CreateJoystickGUID(Uint16 bus, Uint16 vendor, Uint16 product, Uint16 version, const char *vendor_name, const char *product_name, Uint8 driver_signature, Uint8 driver_data); + +/* Function to create a GUID for a joystick based on the name, with no VID/PID information */ +extern SDL_JoystickGUID SDL_CreateJoystickGUIDForName(const char *name); + +/* Function to set the vendor field of a joystick GUID */ +extern void SDL_SetJoystickGUIDVendor(SDL_JoystickGUID *guid, Uint16 vendor); + +/* Function to set the product field of a joystick GUID */ +extern void SDL_SetJoystickGUIDProduct(SDL_JoystickGUID *guid, Uint16 product); + +/* Function to set the version field of a joystick GUID */ +extern void SDL_SetJoystickGUIDVersion(SDL_JoystickGUID *guid, Uint16 version); + +/* Function to set the CRC field of a joystick GUID */ +extern void SDL_SetJoystickGUIDCRC(SDL_JoystickGUID *guid, Uint16 crc); + +/* Function to return the type of a controller */ +extern SDL_GameControllerType SDL_GetJoystickGameControllerTypeFromVIDPID(Uint16 vendor, Uint16 product, const char *name, SDL_bool forUI); +extern SDL_GameControllerType SDL_GetJoystickGameControllerTypeFromGUID(SDL_JoystickGUID guid, const char *name); + +/* Function to return whether a joystick GUID uses the version field */ +extern SDL_bool SDL_JoystickGUIDUsesVersion(SDL_JoystickGUID guid); + +/* Function to return whether a joystick is an Xbox One controller */ +extern SDL_bool SDL_IsJoystickXboxOne(Uint16 vendor_id, Uint16 product_id); + +/* Function to return whether a joystick is an Xbox One Elite controller */ +extern SDL_bool SDL_IsJoystickXboxOneElite(Uint16 vendor_id, Uint16 product_id); + +/* Function to return whether a joystick is an Xbox Series X controller */ +extern SDL_bool SDL_IsJoystickXboxSeriesX(Uint16 vendor_id, Uint16 product_id); + +/* Function to return whether a joystick is an Xbox One controller connected via Bluetooth */ +extern SDL_bool SDL_IsJoystickBluetoothXboxOne(Uint16 vendor_id, Uint16 product_id); + +/* Function to return whether a joystick is a PS4 controller */ +extern SDL_bool SDL_IsJoystickPS4(Uint16 vendor_id, Uint16 product_id); + +/* Function to return whether a joystick is a PS5 controller */ +extern SDL_bool SDL_IsJoystickPS5(Uint16 vendor_id, Uint16 product_id); +extern SDL_bool SDL_IsJoystickDualSenseEdge(Uint16 vendor_id, Uint16 product_id); + +/* Function to return whether a joystick is a Nintendo Switch Pro controller */ +extern SDL_bool SDL_IsJoystickNintendoSwitchPro(Uint16 vendor_id, Uint16 product_id); +extern SDL_bool SDL_IsJoystickNintendoSwitchProInputOnly(Uint16 vendor_id, Uint16 product_id); +extern SDL_bool SDL_IsJoystickNintendoSwitchJoyCon(Uint16 vendor_id, Uint16 product_id); +extern SDL_bool SDL_IsJoystickNintendoSwitchJoyConLeft(Uint16 vendor_id, Uint16 product_id); +extern SDL_bool SDL_IsJoystickNintendoSwitchJoyConRight(Uint16 vendor_id, Uint16 product_id); +extern SDL_bool SDL_IsJoystickNintendoSwitchJoyConGrip(Uint16 vendor_id, Uint16 product_id); +extern SDL_bool SDL_IsJoystickNintendoSwitchJoyConPair(Uint16 vendor_id, Uint16 product_id); + +/* Function to return whether a joystick is a Steam Controller */ +extern SDL_bool SDL_IsJoystickSteamController(Uint16 vendor_id, Uint16 product_id); + +/* Function to return whether a joystick is a Steam Deck */ +extern SDL_bool SDL_IsJoystickSteamDeck(Uint16 vendor_id, Uint16 product_id); + +/* Function to return whether a joystick guid comes from the XInput driver */ +extern SDL_bool SDL_IsJoystickXInput(SDL_JoystickGUID guid); + +/* Function to return whether a joystick guid comes from the WGI driver */ +extern SDL_bool SDL_IsJoystickWGI(SDL_JoystickGUID guid); + +/* Function to return whether a joystick guid comes from the HIDAPI driver */ +extern SDL_bool SDL_IsJoystickHIDAPI(SDL_JoystickGUID guid); + +/* Function to return whether a joystick guid comes from the MFI driver */ +extern SDL_bool SDL_IsJoystickMFI(SDL_JoystickGUID guid); + +/* Function to return whether a joystick guid comes from the RAWINPUT driver */ +extern SDL_bool SDL_IsJoystickRAWINPUT(SDL_JoystickGUID guid); + +/* Function to return whether a joystick guid comes from the Virtual driver */ +extern SDL_bool SDL_IsJoystickVirtual(SDL_JoystickGUID guid); + +/* Function to return whether a joystick should be ignored */ +extern SDL_bool SDL_ShouldIgnoreJoystick(const char *name, SDL_JoystickGUID guid); + +/* Function to return whether a joystick name and GUID is a game controller */ +extern SDL_bool SDL_IsGameControllerNameAndGUID(const char *name, SDL_JoystickGUID guid); + +/* Function to return whether a game controller should be ignored */ +extern SDL_bool SDL_ShouldIgnoreGameController(const char *name, SDL_JoystickGUID guid); + +/* Handle delayed guide button on a game controller */ +extern void SDL_GameControllerHandleDelayedGuideButton(SDL_Joystick *joystick); + +/* Internal event queueing functions */ +extern void SDL_PrivateJoystickAddTouchpad(SDL_Joystick *joystick, int nfingers); +extern void SDL_PrivateJoystickAddSensor(SDL_Joystick *joystick, SDL_SensorType type, float rate); +extern void SDL_PrivateJoystickAdded(SDL_JoystickID device_instance); +extern void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance); +extern void SDL_PrivateJoystickForceRecentering(SDL_Joystick *joystick); +extern int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, + Uint8 axis, Sint16 value); +extern int SDL_PrivateJoystickBall(SDL_Joystick *joystick, + Uint8 ball, Sint16 xrel, Sint16 yrel); +extern int SDL_PrivateJoystickHat(SDL_Joystick *joystick, + Uint8 hat, Uint8 value); +extern int SDL_PrivateJoystickButton(SDL_Joystick *joystick, + Uint8 button, Uint8 state); +extern int SDL_PrivateJoystickTouchpad(SDL_Joystick *joystick, + int touchpad, int finger, Uint8 state, float x, float y, float pressure); +extern int SDL_PrivateJoystickSensor(SDL_Joystick *joystick, + SDL_SensorType type, Uint64 timestamp_us, const float *data, int num_values); +extern void SDL_PrivateJoystickBatteryLevel(SDL_Joystick *joystick, + SDL_JoystickPowerLevel ePowerLevel); + +/* Function to get the Steam virtual gamepad info for a joystick */ +extern const struct SDL_SteamVirtualGamepadInfo *SDL_GetJoystickInstanceVirtualGamepadInfo(SDL_JoystickID instance_id); + +/* Internal sanity checking functions */ +extern SDL_bool SDL_PrivateJoystickValid(SDL_Joystick *joystick); + +typedef enum +{ + EMappingKind_None, + EMappingKind_Button, + EMappingKind_Axis, + EMappingKind_Hat, +} EMappingKind; + +typedef struct _SDL_InputMapping +{ + EMappingKind kind; + Uint8 target; + SDL_bool axis_reversed; + SDL_bool half_axis_positive; + SDL_bool half_axis_negative; +} SDL_InputMapping; + +typedef struct _SDL_GamepadMapping +{ + SDL_InputMapping a; + SDL_InputMapping b; + SDL_InputMapping x; + SDL_InputMapping y; + SDL_InputMapping back; + SDL_InputMapping guide; + SDL_InputMapping start; + SDL_InputMapping leftstick; + SDL_InputMapping rightstick; + SDL_InputMapping leftshoulder; + SDL_InputMapping rightshoulder; + SDL_InputMapping dpup; + SDL_InputMapping dpdown; + SDL_InputMapping dpleft; + SDL_InputMapping dpright; + SDL_InputMapping misc1; + SDL_InputMapping paddle1; + SDL_InputMapping paddle2; + SDL_InputMapping paddle3; + SDL_InputMapping paddle4; + SDL_InputMapping leftx; + SDL_InputMapping lefty; + SDL_InputMapping rightx; + SDL_InputMapping righty; + SDL_InputMapping lefttrigger; + SDL_InputMapping righttrigger; + SDL_InputMapping touchpad; +} SDL_GamepadMapping; + +/* Function to get autodetected gamepad controller mapping from the driver */ +extern SDL_bool SDL_PrivateJoystickGetAutoGamepadMapping(int device_index, + SDL_GamepadMapping *out); + + +typedef struct +{ + const char *included_hint_name; + int num_included_entries; + int max_included_entries; + Uint32 *included_entries; + + const char *excluded_hint_name; + int num_excluded_entries; + int max_excluded_entries; + Uint32 *excluded_entries; + + int num_initial_entries; + Uint32 *initial_entries; + + SDL_bool initialized; +} SDL_vidpid_list; + +extern void SDL_LoadVIDPIDList(SDL_vidpid_list *list); +extern void SDL_LoadVIDPIDListFromHints(SDL_vidpid_list *list, const char *included_list, const char *excluded_list); +extern SDL_bool SDL_VIDPIDInList(Uint16 vendor_id, Uint16 product_id, const SDL_vidpid_list *list); +extern void SDL_FreeVIDPIDList(SDL_vidpid_list *list); + +/* This is in SDL_gamecontroller.c */ +extern SDL_GameControllerType SDL_GetGameControllerTypeFromString(const char *str); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif + +#endif /* SDL_joystick_c_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/joystick/SDL_steam_virtual_gamepad.c b/SDL2-2.30.5/src/joystick/SDL_steam_virtual_gamepad.c new file mode 100644 index 0000000..4e5255d --- /dev/null +++ b/SDL2-2.30.5/src/joystick/SDL_steam_virtual_gamepad.c @@ -0,0 +1,251 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_hints.h" +#include "SDL_timer.h" +#include "SDL_joystick_c.h" +#include "SDL_steam_virtual_gamepad.h" + +#ifdef __WIN32__ +#include "../core/windows/SDL_windows.h" +#else +#include +#include +#endif + +#define SDL_HINT_STEAM_VIRTUAL_GAMEPAD_INFO_FILE "SteamVirtualGamepadInfo" + +static char *SDL_steam_virtual_gamepad_info_file SDL_GUARDED_BY(SDL_joystick_lock) = NULL; +static Uint64 SDL_steam_virtual_gamepad_info_file_mtime SDL_GUARDED_BY(SDL_joystick_lock) = 0; +static Uint32 SDL_steam_virtual_gamepad_info_check_time SDL_GUARDED_BY(SDL_joystick_lock) = 0; +static SDL_SteamVirtualGamepadInfo **SDL_steam_virtual_gamepad_info SDL_GUARDED_BY(SDL_joystick_lock) = NULL; +static int SDL_steam_virtual_gamepad_info_count SDL_GUARDED_BY(SDL_joystick_lock) = 0; + + +static Uint64 GetFileModificationTime(const char *file) +{ + Uint64 modification_time = 0; + +#ifdef __WIN32__ + WCHAR *wFile = WIN_UTF8ToStringW(file); + if (wFile) { + HANDLE hFile = CreateFileW(wFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + if (hFile != INVALID_HANDLE_VALUE) { + FILETIME last_write_time; + if (GetFileTime(hFile, NULL, NULL, &last_write_time)) { + modification_time = last_write_time.dwHighDateTime; + modification_time <<= 32; + modification_time |= last_write_time.dwLowDateTime; + } + CloseHandle(hFile); + } + SDL_free(wFile); + } +#else + struct stat sb; + + if (stat(file, &sb) == 0) { + modification_time = (Uint64)sb.st_mtime; + } +#endif + return modification_time; +} + +static void SDL_FreeSteamVirtualGamepadInfo(void) +{ + int i; + + SDL_AssertJoysticksLocked(); + + for (i = 0; i < SDL_steam_virtual_gamepad_info_count; ++i) { + SDL_SteamVirtualGamepadInfo *entry = SDL_steam_virtual_gamepad_info[i]; + if (entry) { + SDL_free(entry->name); + SDL_free(entry); + } + } + SDL_free(SDL_steam_virtual_gamepad_info); + SDL_steam_virtual_gamepad_info = NULL; + SDL_steam_virtual_gamepad_info_count = 0; +} + +static void AddVirtualGamepadInfo(int slot, SDL_SteamVirtualGamepadInfo *info) +{ + SDL_SteamVirtualGamepadInfo *new_info; + + SDL_AssertJoysticksLocked(); + + if (slot < 0) { + return; + } + + if (slot >= SDL_steam_virtual_gamepad_info_count) { + SDL_SteamVirtualGamepadInfo **slots = (SDL_SteamVirtualGamepadInfo **)SDL_realloc(SDL_steam_virtual_gamepad_info, (slot + 1)*sizeof(*SDL_steam_virtual_gamepad_info)); + if (!slots) { + return; + } + while (SDL_steam_virtual_gamepad_info_count <= slot) { + slots[SDL_steam_virtual_gamepad_info_count++] = NULL; + } + SDL_steam_virtual_gamepad_info = slots; + } + + if (SDL_steam_virtual_gamepad_info[slot]) { + /* We already have this slot info */ + return; + } + + new_info = (SDL_SteamVirtualGamepadInfo *)SDL_malloc(sizeof(*new_info)); + if (!new_info) { + return; + } + SDL_copyp(new_info, info); + SDL_steam_virtual_gamepad_info[slot] = new_info; + SDL_zerop(info); +} + +void SDL_InitSteamVirtualGamepadInfo(void) +{ + const char *file; + + SDL_AssertJoysticksLocked(); + + file = SDL_GetHint(SDL_HINT_STEAM_VIRTUAL_GAMEPAD_INFO_FILE); + if (file && *file) { + SDL_steam_virtual_gamepad_info_file = SDL_strdup(file); + } + SDL_UpdateSteamVirtualGamepadInfo(); +} + +SDL_bool SDL_SteamVirtualGamepadEnabled(void) +{ + SDL_AssertJoysticksLocked(); + + return (SDL_steam_virtual_gamepad_info != NULL); +} + +SDL_bool SDL_UpdateSteamVirtualGamepadInfo(void) +{ + const int UPDATE_CHECK_INTERVAL_MS = 3000; + Uint32 now; + Uint64 mtime; + char *data, *end, *next, *line, *value; + size_t size; + int slot, new_slot; + SDL_SteamVirtualGamepadInfo info; + + SDL_AssertJoysticksLocked(); + + if (!SDL_steam_virtual_gamepad_info_file) { + return SDL_FALSE; + } + + now = SDL_GetTicks(); + if (SDL_steam_virtual_gamepad_info_check_time && + !SDL_TICKS_PASSED(now, (SDL_steam_virtual_gamepad_info_check_time + UPDATE_CHECK_INTERVAL_MS))) { + return SDL_FALSE; + } + SDL_steam_virtual_gamepad_info_check_time = now; + + mtime = GetFileModificationTime(SDL_steam_virtual_gamepad_info_file); + if (mtime == 0 || mtime == SDL_steam_virtual_gamepad_info_file_mtime) { + return SDL_FALSE; + } + + data = (char *)SDL_LoadFile(SDL_steam_virtual_gamepad_info_file, &size); + if (!data) { + return SDL_FALSE; + } + + SDL_FreeSteamVirtualGamepadInfo(); + + slot = -1; + SDL_zero(info); + + for (next = data, end = data + size; next < end; ) { + while (next < end && (*next == '\0' || *next == '\r' || *next == '\n')) { + ++next; + } + + line = next; + + while (next < end && (*next != '\r' && *next != '\n')) { + ++next; + } + *next = '\0'; + + if (SDL_sscanf(line, "[slot %d]", &new_slot) == 1) { + if (slot >= 0) { + AddVirtualGamepadInfo(slot, &info); + } + slot = new_slot; + } else { + value = SDL_strchr(line, '='); + if (value) { + *value++ = '\0'; + + if (SDL_strcmp(line, "name") == 0) { + SDL_free(info.name); + info.name = SDL_strdup(value); + } else if (SDL_strcmp(line, "VID") == 0) { + info.vendor_id = (Uint16)SDL_strtoul(value, NULL, 0); + } else if (SDL_strcmp(line, "PID") == 0) { + info.product_id = (Uint16)SDL_strtoul(value, NULL, 0); + } else if (SDL_strcmp(line, "type") == 0) { + info.type = SDL_GetGameControllerTypeFromString(value); + } else if (SDL_strcmp(line, "handle") == 0) { + info.handle = SDL_strtoull(value, NULL, 0); + } + } + } + } + if (slot >= 0) { + AddVirtualGamepadInfo(slot, &info); + } + SDL_free(info.name); + SDL_free(data); + + SDL_steam_virtual_gamepad_info_file_mtime = mtime; + + return SDL_TRUE; +} + +const SDL_SteamVirtualGamepadInfo *SDL_GetSteamVirtualGamepadInfo(int slot) +{ + SDL_AssertJoysticksLocked(); + + if (slot < 0 || slot >= SDL_steam_virtual_gamepad_info_count) { + return NULL; + } + return SDL_steam_virtual_gamepad_info[slot]; +} + +void SDL_QuitSteamVirtualGamepadInfo(void) +{ + SDL_AssertJoysticksLocked(); + + if (SDL_steam_virtual_gamepad_info_file) { + SDL_FreeSteamVirtualGamepadInfo(); + SDL_free(SDL_steam_virtual_gamepad_info_file); + SDL_steam_virtual_gamepad_info_file = NULL; + } +} diff --git a/SDL2-2.30.5/src/joystick/SDL_steam_virtual_gamepad.h b/SDL2-2.30.5/src/joystick/SDL_steam_virtual_gamepad.h new file mode 100644 index 0000000..415643b --- /dev/null +++ b/SDL2-2.30.5/src/joystick/SDL_steam_virtual_gamepad.h @@ -0,0 +1,36 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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 struct SDL_SteamVirtualGamepadInfo +{ + Uint64 handle; + char *name; + Uint16 vendor_id; + Uint16 product_id; + SDL_GameControllerType type; +} SDL_SteamVirtualGamepadInfo; + +void SDL_InitSteamVirtualGamepadInfo(void); +SDL_bool SDL_SteamVirtualGamepadEnabled(void); +SDL_bool SDL_UpdateSteamVirtualGamepadInfo(void); +const SDL_SteamVirtualGamepadInfo *SDL_GetSteamVirtualGamepadInfo(int slot); +void SDL_QuitSteamVirtualGamepadInfo(void); diff --git a/SDL2-2.30.5/src/joystick/SDL_sysjoystick.h b/SDL2-2.30.5/src/joystick/SDL_sysjoystick.h new file mode 100644 index 0000000..173650e --- /dev/null +++ b/SDL2-2.30.5/src/joystick/SDL_sysjoystick.h @@ -0,0 +1,264 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifndef SDL_sysjoystick_h_ +#define SDL_sysjoystick_h_ + +/* This is the system specific header for the SDL joystick API */ +#include "SDL_joystick.h" +#include "SDL_joystick_c.h" + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* The SDL joystick structure */ +typedef struct _SDL_JoystickAxisInfo +{ + Sint16 initial_value; /* Initial axis state */ + Sint16 value; /* Current axis state */ + Sint16 zero; /* Zero point on the axis (-32768 for triggers) */ + SDL_bool has_initial_value; /* Whether we've seen a value on the axis yet */ + SDL_bool has_second_value; /* Whether we've seen a second value on the axis yet */ + SDL_bool sent_initial_value; /* Whether we've sent the initial axis value */ + SDL_bool sending_initial_value; /* Whether we are sending the initial axis value */ +} SDL_JoystickAxisInfo; + +typedef struct _SDL_JoystickTouchpadFingerInfo +{ + Uint8 state; + float x; + float y; + float pressure; +} SDL_JoystickTouchpadFingerInfo; + +typedef struct _SDL_JoystickTouchpadInfo +{ + int nfingers; + SDL_JoystickTouchpadFingerInfo *fingers; +} SDL_JoystickTouchpadInfo; + +typedef struct _SDL_JoystickSensorInfo +{ + SDL_SensorType type; + SDL_bool enabled; + float rate; + float data[3]; /* If this needs to expand, update SDL_ControllerSensorEvent */ + Uint64 timestamp_us; +} SDL_JoystickSensorInfo; + +#define _guarded SDL_GUARDED_BY(SDL_joystick_lock) + +struct _SDL_Joystick +{ + const void *magic _guarded; + + SDL_JoystickID instance_id _guarded; /* Device instance, monotonically increasing from 0 */ + char *name _guarded; /* Joystick name - system dependent */ + char *path _guarded; /* Joystick path - system dependent */ + char *serial _guarded; /* Joystick serial */ + SDL_JoystickGUID guid _guarded; /* Joystick guid */ + Uint16 firmware_version _guarded; /* Firmware version, if available */ + Uint64 steam_handle _guarded; /* Steam controller API handle */ + + int naxes _guarded; /* Number of axis controls on the joystick */ + SDL_JoystickAxisInfo *axes _guarded; + + int nhats _guarded; /* Number of hats on the joystick */ + Uint8 *hats _guarded; /* Current hat states */ + + int nballs _guarded; /* Number of trackballs on the joystick */ + struct balldelta + { + int dx; + int dy; + } *balls _guarded; /* Current ball motion deltas */ + + int nbuttons _guarded; /* Number of buttons on the joystick */ + Uint8 *buttons _guarded; /* Current button states */ + + int ntouchpads _guarded; /* Number of touchpads on the joystick */ + SDL_JoystickTouchpadInfo *touchpads _guarded; /* Current touchpad states */ + + int nsensors _guarded; /* Number of sensors on the joystick */ + int nsensors_enabled _guarded; + SDL_JoystickSensorInfo *sensors _guarded; + + Uint16 low_frequency_rumble _guarded; + Uint16 high_frequency_rumble _guarded; + Uint32 rumble_expiration _guarded; + Uint32 rumble_resend _guarded; + + Uint16 left_trigger_rumble _guarded; + Uint16 right_trigger_rumble _guarded; + Uint32 trigger_rumble_expiration _guarded; + + Uint8 led_red _guarded; + Uint8 led_green _guarded; + Uint8 led_blue _guarded; + Uint32 led_expiration _guarded; + + SDL_bool attached _guarded; + SDL_bool is_game_controller _guarded; + SDL_bool delayed_guide_button _guarded; /* SDL_TRUE if this device has the guide button event delayed */ + SDL_JoystickPowerLevel epowerlevel _guarded; /* power level of this joystick, SDL_JOYSTICK_POWER_UNKNOWN if not supported */ + + struct _SDL_JoystickDriver *driver _guarded; + + struct joystick_hwdata *hwdata _guarded; /* Driver dependent information */ + + int ref_count _guarded; /* Reference count for multiple opens */ + + struct _SDL_Joystick *next _guarded; /* pointer to next joystick we have allocated */ +}; + +#undef _guarded + +/* Device bus definitions */ +#define SDL_HARDWARE_BUS_UNKNOWN 0x00 +#define SDL_HARDWARE_BUS_USB 0x03 +#define SDL_HARDWARE_BUS_BLUETOOTH 0x05 +#define SDL_HARDWARE_BUS_VIRTUAL 0xFF + +/* Joystick capability flags for GetCapabilities() */ +#define SDL_JOYCAP_LED 0x01 +#define SDL_JOYCAP_RUMBLE 0x02 +#define SDL_JOYCAP_RUMBLE_TRIGGERS 0x04 + +/* Macro to combine a USB vendor ID and product ID into a single Uint32 value */ +#define MAKE_VIDPID(VID, PID) (((Uint32)(VID)) << 16 | (PID)) + +typedef struct _SDL_JoystickDriver +{ + /* Function to scan the system for joysticks. + * Joystick 0 should be the system default joystick. + * This function should return 0, or -1 on an unrecoverable error. + */ + int (*Init)(void); + + /* Function to return the number of joystick devices plugged in right now */ + int (*GetCount)(void); + + /* Function to cause any queued joystick insertions to be processed */ + void (*Detect)(void); + + /* Function to get the device-dependent name of a joystick */ + const char *(*GetDeviceName)(int device_index); + + /* Function to get the device-dependent path of a joystick */ + const char *(*GetDevicePath)(int device_index); + + /* Function to get the Steam virtual gamepad slot of a joystick */ + int (*GetDeviceSteamVirtualGamepadSlot)(int device_index); + + /* Function to get the player index of a joystick */ + int (*GetDevicePlayerIndex)(int device_index); + + /* Function to set the player index of a joystick */ + void (*SetDevicePlayerIndex)(int device_index, int player_index); + + /* Function to return the stable GUID for a plugged in device */ + SDL_JoystickGUID (*GetDeviceGUID)(int device_index); + + /* Function to get the current instance id of the joystick located at device_index */ + SDL_JoystickID (*GetDeviceInstanceID)(int device_index); + + /* Function to open a joystick for use. + The joystick to open is specified by the device index. + This should fill the nbuttons and naxes fields of the joystick structure. + It returns 0, or -1 if there is an error. + */ + int (*Open)(SDL_Joystick *joystick, int device_index); + + /* Rumble functionality */ + int (*Rumble)(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble); + int (*RumbleTriggers)(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble); + + /* Capability detection */ + Uint32 (*GetCapabilities)(SDL_Joystick *joystick); + + /* LED functionality */ + int (*SetLED)(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue); + + /* General effects */ + int (*SendEffect)(SDL_Joystick *joystick, const void *data, int size); + + /* Sensor functionality */ + int (*SetSensorsEnabled)(SDL_Joystick *joystick, SDL_bool enabled); + + /* Function to update the state of a joystick - called as a device poll. + * This function shouldn't update the joystick structure directly, + * but instead should call SDL_PrivateJoystick*() to deliver events + * and update joystick device state. + */ + void (*Update)(SDL_Joystick *joystick); + + /* Function to close a joystick after use */ + void (*Close)(SDL_Joystick *joystick); + + /* Function to perform any system-specific joystick related cleanup */ + void (*Quit)(void); + + /* Function to get the autodetected controller mapping; returns false if there isn't any. */ + SDL_bool (*GetGamepadMapping)(int device_index, SDL_GamepadMapping *out); + +} SDL_JoystickDriver; + +/* Windows and Mac OSX has a limit of MAX_DWORD / 1000, Linux kernel has a limit of 0xFFFF */ +#define SDL_MAX_RUMBLE_DURATION_MS 0xFFFF + +/* Dualshock4 only rumbles for about 5 seconds max, resend rumble command every 2 seconds + * to make long rumble work. */ +#define SDL_RUMBLE_RESEND_MS 2000 + +#define SDL_LED_MIN_REPEAT_MS 5000 + +/* The available joystick drivers */ +extern SDL_JoystickDriver SDL_ANDROID_JoystickDriver; +extern SDL_JoystickDriver SDL_BSD_JoystickDriver; +extern SDL_JoystickDriver SDL_DARWIN_JoystickDriver; +extern SDL_JoystickDriver SDL_DUMMY_JoystickDriver; +extern SDL_JoystickDriver SDL_EMSCRIPTEN_JoystickDriver; +extern SDL_JoystickDriver SDL_HAIKU_JoystickDriver; +extern SDL_JoystickDriver SDL_HIDAPI_JoystickDriver; +extern SDL_JoystickDriver SDL_RAWINPUT_JoystickDriver; +extern SDL_JoystickDriver SDL_IOS_JoystickDriver; +extern SDL_JoystickDriver SDL_LINUX_JoystickDriver; +extern SDL_JoystickDriver SDL_VIRTUAL_JoystickDriver; +extern SDL_JoystickDriver SDL_WGI_JoystickDriver; +extern SDL_JoystickDriver SDL_WINDOWS_JoystickDriver; +extern SDL_JoystickDriver SDL_WINMM_JoystickDriver; +extern SDL_JoystickDriver SDL_OS2_JoystickDriver; +extern SDL_JoystickDriver SDL_PS2_JoystickDriver; +extern SDL_JoystickDriver SDL_PSP_JoystickDriver; +extern SDL_JoystickDriver SDL_VITA_JoystickDriver; +extern SDL_JoystickDriver SDL_N3DS_JoystickDriver; + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif + +#endif /* SDL_sysjoystick_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/joystick/android/SDL_sysjoystick.c b/SDL2-2.30.5/src/joystick/android/SDL_sysjoystick.c similarity index 58% rename from SDL2-2.0.12/src/joystick/android/SDL_sysjoystick.c rename to SDL2-2.30.5/src/joystick/android/SDL_sysjoystick.c index d0c6262..c29f738 100644 --- a/SDL2-2.0.12/src/joystick/android/SDL_sysjoystick.c +++ b/SDL2-2.30.5/src/joystick/android/SDL_sysjoystick.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -18,7 +18,6 @@ misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ - #include "../../SDL_internal.h" #ifdef SDL_JOYSTICK_ANDROID @@ -29,9 +28,7 @@ #include "SDL_joystick.h" #include "SDL_hints.h" -#include "SDL_assert.h" #include "SDL_timer.h" -#include "SDL_log.h" #include "SDL_sysjoystick_c.h" #include "../SDL_joystick_c.h" #include "../../events/SDL_keyboard_c.h" @@ -42,15 +39,15 @@ /* As of platform android-14, android/keycodes.h is missing these defines */ #ifndef AKEYCODE_BUTTON_1 -#define AKEYCODE_BUTTON_1 188 -#define AKEYCODE_BUTTON_2 189 -#define AKEYCODE_BUTTON_3 190 -#define AKEYCODE_BUTTON_4 191 -#define AKEYCODE_BUTTON_5 192 -#define AKEYCODE_BUTTON_6 193 -#define AKEYCODE_BUTTON_7 194 -#define AKEYCODE_BUTTON_8 195 -#define AKEYCODE_BUTTON_9 196 +#define AKEYCODE_BUTTON_1 188 +#define AKEYCODE_BUTTON_2 189 +#define AKEYCODE_BUTTON_3 190 +#define AKEYCODE_BUTTON_4 191 +#define AKEYCODE_BUTTON_5 192 +#define AKEYCODE_BUTTON_6 193 +#define AKEYCODE_BUTTON_7 194 +#define AKEYCODE_BUTTON_8 195 +#define AKEYCODE_BUTTON_9 196 #define AKEYCODE_BUTTON_10 197 #define AKEYCODE_BUTTON_11 198 #define AKEYCODE_BUTTON_12 199 @@ -60,150 +57,126 @@ #define AKEYCODE_BUTTON_16 203 #endif -#define ANDROID_ACCELEROMETER_NAME "Android Accelerometer" +#define ANDROID_ACCELEROMETER_NAME "Android Accelerometer" #define ANDROID_ACCELEROMETER_DEVICE_ID INT_MIN -#define ANDROID_MAX_NBUTTONS 36 +#define ANDROID_MAX_NBUTTONS 36 -static SDL_joylist_item * JoystickByDeviceId(int device_id); +static SDL_joylist_item *JoystickByDeviceId(int device_id); static SDL_joylist_item *SDL_joylist = NULL; static SDL_joylist_item *SDL_joylist_tail = NULL; static int numjoysticks = 0; - -/* Public domain CRC implementation adapted from: - http://home.thep.lu.se/~bjorn/crc/crc32_simple.c -*/ -static Uint32 crc32_for_byte(Uint32 r) -{ - int i; - for(i = 0; i < 8; ++i) { - r = (r & 1? 0: (Uint32)0xEDB88320L) ^ r >> 1; - } - return r ^ (Uint32)0xFF000000L; -} - -static Uint32 crc32(const void *data, size_t count) -{ - Uint32 crc = 0; - int i; - for(i = 0; i < count; ++i) { - crc = crc32_for_byte((Uint8)crc ^ ((const Uint8*)data)[i]) ^ crc >> 8; - } - return crc; -} - /* Function to convert Android keyCodes into SDL ones. * This code manipulation is done to get a sequential list of codes. * FIXME: This is only suited for the case where we use a fixed number of buttons determined by ANDROID_MAX_NBUTTONS */ -static int -keycode_to_SDL(int keycode) +static int keycode_to_SDL(int keycode) { /* FIXME: If this function gets too unwieldy in the future, replace with a lookup table */ int button = 0; switch (keycode) { - /* Some gamepad buttons (API 9) */ - case AKEYCODE_BUTTON_A: - button = SDL_CONTROLLER_BUTTON_A; - break; - case AKEYCODE_BUTTON_B: - button = SDL_CONTROLLER_BUTTON_B; - break; - case AKEYCODE_BUTTON_X: - button = SDL_CONTROLLER_BUTTON_X; - break; - case AKEYCODE_BUTTON_Y: - button = SDL_CONTROLLER_BUTTON_Y; - break; - case AKEYCODE_BUTTON_L1: - button = SDL_CONTROLLER_BUTTON_LEFTSHOULDER; - break; - case AKEYCODE_BUTTON_R1: - button = SDL_CONTROLLER_BUTTON_RIGHTSHOULDER; - break; - case AKEYCODE_BUTTON_THUMBL: - button = SDL_CONTROLLER_BUTTON_LEFTSTICK; - break; - case AKEYCODE_BUTTON_THUMBR: - button = SDL_CONTROLLER_BUTTON_RIGHTSTICK; - break; - case AKEYCODE_BUTTON_START: - button = SDL_CONTROLLER_BUTTON_START; - break; - case AKEYCODE_BACK: - case AKEYCODE_BUTTON_SELECT: - button = SDL_CONTROLLER_BUTTON_BACK; - break; - case AKEYCODE_BUTTON_MODE: - button = SDL_CONTROLLER_BUTTON_GUIDE; - break; - case AKEYCODE_BUTTON_L2: - button = SDL_CONTROLLER_BUTTON_MAX; /* Not supported by GameController */ - break; - case AKEYCODE_BUTTON_R2: - button = SDL_CONTROLLER_BUTTON_MAX+1; /* Not supported by GameController */ - break; - case AKEYCODE_BUTTON_C: - button = SDL_CONTROLLER_BUTTON_MAX+2; /* Not supported by GameController */ - break; - case AKEYCODE_BUTTON_Z: - button = SDL_CONTROLLER_BUTTON_MAX+3; /* Not supported by GameController */ - break; - - /* D-Pad key codes (API 1) */ - case AKEYCODE_DPAD_UP: - button = SDL_CONTROLLER_BUTTON_DPAD_UP; - break; - case AKEYCODE_DPAD_DOWN: - button = SDL_CONTROLLER_BUTTON_DPAD_DOWN; - break; - case AKEYCODE_DPAD_LEFT: - button = SDL_CONTROLLER_BUTTON_DPAD_LEFT; - break; - case AKEYCODE_DPAD_RIGHT: - button = SDL_CONTROLLER_BUTTON_DPAD_RIGHT; - break; - case AKEYCODE_DPAD_CENTER: - /* This is handled better by applications as the A button */ - /*button = SDL_CONTROLLER_BUTTON_MAX+4;*/ /* Not supported by GameController */ - button = SDL_CONTROLLER_BUTTON_A; - break; + /* Some gamepad buttons (API 9) */ + case AKEYCODE_BUTTON_A: + button = SDL_CONTROLLER_BUTTON_A; + break; + case AKEYCODE_BUTTON_B: + button = SDL_CONTROLLER_BUTTON_B; + break; + case AKEYCODE_BUTTON_X: + button = SDL_CONTROLLER_BUTTON_X; + break; + case AKEYCODE_BUTTON_Y: + button = SDL_CONTROLLER_BUTTON_Y; + break; + case AKEYCODE_BUTTON_L1: + button = SDL_CONTROLLER_BUTTON_LEFTSHOULDER; + break; + case AKEYCODE_BUTTON_R1: + button = SDL_CONTROLLER_BUTTON_RIGHTSHOULDER; + break; + case AKEYCODE_BUTTON_THUMBL: + button = SDL_CONTROLLER_BUTTON_LEFTSTICK; + break; + case AKEYCODE_BUTTON_THUMBR: + button = SDL_CONTROLLER_BUTTON_RIGHTSTICK; + break; + case AKEYCODE_MENU: + case AKEYCODE_BUTTON_START: + button = SDL_CONTROLLER_BUTTON_START; + break; + case AKEYCODE_BACK: + case AKEYCODE_BUTTON_SELECT: + button = SDL_CONTROLLER_BUTTON_BACK; + break; + case AKEYCODE_BUTTON_MODE: + button = SDL_CONTROLLER_BUTTON_GUIDE; + break; + case AKEYCODE_BUTTON_L2: + button = 15; + break; + case AKEYCODE_BUTTON_R2: + button = 16; + break; + case AKEYCODE_BUTTON_C: + button = 17; + break; + case AKEYCODE_BUTTON_Z: + button = 18; + break; - /* More gamepad buttons (API 12), these get mapped to 20...35*/ - case AKEYCODE_BUTTON_1: - case AKEYCODE_BUTTON_2: - case AKEYCODE_BUTTON_3: - case AKEYCODE_BUTTON_4: - case AKEYCODE_BUTTON_5: - case AKEYCODE_BUTTON_6: - case AKEYCODE_BUTTON_7: - case AKEYCODE_BUTTON_8: - case AKEYCODE_BUTTON_9: - case AKEYCODE_BUTTON_10: - case AKEYCODE_BUTTON_11: - case AKEYCODE_BUTTON_12: - case AKEYCODE_BUTTON_13: - case AKEYCODE_BUTTON_14: - case AKEYCODE_BUTTON_15: - case AKEYCODE_BUTTON_16: - button = keycode - AKEYCODE_BUTTON_1 + SDL_CONTROLLER_BUTTON_MAX + 5; - break; - - default: - return -1; - /* break; -Wunreachable-code-break */ + /* D-Pad key codes (API 1) */ + case AKEYCODE_DPAD_UP: + button = SDL_CONTROLLER_BUTTON_DPAD_UP; + break; + case AKEYCODE_DPAD_DOWN: + button = SDL_CONTROLLER_BUTTON_DPAD_DOWN; + break; + case AKEYCODE_DPAD_LEFT: + button = SDL_CONTROLLER_BUTTON_DPAD_LEFT; + break; + case AKEYCODE_DPAD_RIGHT: + button = SDL_CONTROLLER_BUTTON_DPAD_RIGHT; + break; + case AKEYCODE_DPAD_CENTER: + /* This is handled better by applications as the A button */ + /*button = 19;*/ + button = SDL_CONTROLLER_BUTTON_A; + break; + + /* More gamepad buttons (API 12), these get mapped to 20...35*/ + case AKEYCODE_BUTTON_1: + case AKEYCODE_BUTTON_2: + case AKEYCODE_BUTTON_3: + case AKEYCODE_BUTTON_4: + case AKEYCODE_BUTTON_5: + case AKEYCODE_BUTTON_6: + case AKEYCODE_BUTTON_7: + case AKEYCODE_BUTTON_8: + case AKEYCODE_BUTTON_9: + case AKEYCODE_BUTTON_10: + case AKEYCODE_BUTTON_11: + case AKEYCODE_BUTTON_12: + case AKEYCODE_BUTTON_13: + case AKEYCODE_BUTTON_14: + case AKEYCODE_BUTTON_15: + case AKEYCODE_BUTTON_16: + button = 20 + (keycode - AKEYCODE_BUTTON_1); + break; + + default: + return -1; + /* break; -Wunreachable-code-break */ } - - /* This is here in case future generations, probably with six fingers per hand, - * happily add new cases up above and forget to update the max number of buttons. + + /* This is here in case future generations, probably with six fingers per hand, + * happily add new cases up above and forget to update the max number of buttons. */ SDL_assert(button < ANDROID_MAX_NBUTTONS); return button; } -static SDL_Scancode -button_to_scancode(int button) +static SDL_Scancode button_to_scancode(int button) { switch (button) { case SDL_CONTROLLER_BUTTON_A: @@ -212,6 +185,8 @@ button_to_scancode(int button) return SDL_SCANCODE_ESCAPE; case SDL_CONTROLLER_BUTTON_BACK: return SDL_SCANCODE_ESCAPE; + case SDL_CONTROLLER_BUTTON_START: + return SDL_SCANCODE_MENU; case SDL_CONTROLLER_BUTTON_DPAD_UP: return SDL_SCANCODE_UP; case SDL_CONTROLLER_BUTTON_DPAD_DOWN: @@ -226,56 +201,60 @@ button_to_scancode(int button) return SDL_SCANCODE_UNKNOWN; } -int -Android_OnPadDown(int device_id, int keycode) +int Android_OnPadDown(int device_id, int keycode) { SDL_joylist_item *item; int button = keycode_to_SDL(keycode); if (button >= 0) { + SDL_LockJoysticks(); item = JoystickByDeviceId(device_id); if (item && item->joystick) { SDL_PrivateJoystickButton(item->joystick, button, SDL_PRESSED); } else { SDL_SendKeyboardKey(SDL_PRESSED, button_to_scancode(button)); } + SDL_UnlockJoysticks(); return 0; } - + return -1; } -int -Android_OnPadUp(int device_id, int keycode) +int Android_OnPadUp(int device_id, int keycode) { SDL_joylist_item *item; int button = keycode_to_SDL(keycode); if (button >= 0) { + SDL_LockJoysticks(); item = JoystickByDeviceId(device_id); if (item && item->joystick) { SDL_PrivateJoystickButton(item->joystick, button, SDL_RELEASED); } else { SDL_SendKeyboardKey(SDL_RELEASED, button_to_scancode(button)); } + SDL_UnlockJoysticks(); return 0; } - + return -1; } -int -Android_OnJoy(int device_id, int axis, float value) +int 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); + SDL_joylist_item *item; + + SDL_LockJoysticks(); + item = JoystickByDeviceId(device_id); if (item && item->joystick) { - SDL_PrivateJoystickAxis(item->joystick, axis, (Sint16) (32767.*value)); + SDL_PrivateJoystickAxis(item->joystick, axis, (Sint16)(32767. * value)); } - + SDL_UnlockJoysticks(); + return 0; } -int -Android_OnHat(int device_id, int hat_id, int x, int y) +int Android_OnHat(int device_id, int hat_id, int x, int y) { const int DPAD_UP_MASK = (1 << SDL_CONTROLLER_BUTTON_DPAD_UP); const int DPAD_DOWN_MASK = (1 << SDL_CONTROLLER_BUTTON_DPAD_DOWN); @@ -283,7 +262,10 @@ Android_OnHat(int device_id, int hat_id, int x, int y) const int DPAD_RIGHT_MASK = (1 << SDL_CONTROLLER_BUTTON_DPAD_RIGHT); if (x >= -1 && x <= 1 && y >= -1 && y <= 1) { - SDL_joylist_item *item = JoystickByDeviceId(device_id); + SDL_joylist_item *item; + + SDL_LockJoysticks(); + item = JoystickByDeviceId(device_id); if (item && item->joystick) { int dpad_state = 0; int dpad_delta; @@ -315,38 +297,37 @@ Android_OnHat(int device_id, int hat_id, int x, int y) item->dpad_state = dpad_state; } } + SDL_UnlockJoysticks(); return 0; } return -1; } - -int -Android_AddJoystick(int device_id, const char *name, const char *desc, int vendor_id, int product_id, SDL_bool is_accelerometer, int button_mask, int naxes, int nhats, int nballs) +int Android_AddJoystick(int device_id, const char *name, const char *desc, int vendor_id, int product_id, SDL_bool is_accelerometer, int button_mask, int naxes, int axis_mask, int nhats, int nballs) { SDL_joylist_item *item; SDL_JoystickGUID guid; - Uint16 *guid16 = (Uint16 *)guid.data; int i; - int axis_mask; + int result = -1; + SDL_LockJoysticks(); if (!SDL_GetHintBoolean(SDL_HINT_TV_REMOTE_AS_JOYSTICK, SDL_TRUE)) { /* Ignore devices that aren't actually controllers (e.g. remotes), they'll be handled as keyboard input */ if (naxes < 2 && nhats < 1) { - return -1; + goto done; } } - - if (JoystickByDeviceId(device_id) != NULL || name == NULL) { - return -1; + + if (JoystickByDeviceId(device_id) != NULL || !name) { + goto done; } #ifdef SDL_JOYSTICK_HIDAPI if (HIDAPI_IsDevicePresent(vendor_id, product_id, 0, name)) { /* The HIDAPI driver is taking care of this device */ - return -1; + goto done; } #endif @@ -354,22 +335,6 @@ Android_AddJoystick(int device_id, const char *name, const char *desc, int vendo SDL_Log("Joystick: %s, descriptor %s, vendor = 0x%.4x, product = 0x%.4x, %d axes, %d hats\n", name, desc, vendor_id, product_id, naxes, nhats); #endif - /* Add the available buttons and axes - The axis mask should probably come from Java where there is more information about the axes... - */ - axis_mask = 0; - if (!is_accelerometer) { - if (naxes >= 2) { - axis_mask |= ((1 << SDL_CONTROLLER_AXIS_LEFTX) | (1 << SDL_CONTROLLER_AXIS_LEFTY)); - } - if (naxes >= 4) { - axis_mask |= ((1 << SDL_CONTROLLER_AXIS_RIGHTX) | (1 << SDL_CONTROLLER_AXIS_RIGHTY)); - } - if (naxes >= 6) { - axis_mask |= ((1 << SDL_CONTROLLER_AXIS_TRIGGERLEFT) | (1 << SDL_CONTROLLER_AXIS_TRIGGERRIGHT)); - } - } - if (nhats > 0) { /* Hat is translated into DPAD buttons */ button_mask |= ((1 << SDL_CONTROLLER_BUTTON_DPAD_UP) | @@ -379,50 +344,36 @@ Android_AddJoystick(int device_id, const char *name, const char *desc, int vendo nhats = 0; } - SDL_memset(guid.data, 0, sizeof(guid.data)); + guid = SDL_CreateJoystickGUID(SDL_HARDWARE_BUS_BLUETOOTH, vendor_id, product_id, 0, NULL, desc, 0, 0); - /* We only need 16 bits for each of these; space them out to fill 128. */ - /* Byteswap so devices get same GUID on little/big endian platforms. */ - *guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_BLUETOOTH); - *guid16++ = 0; - - if (vendor_id && product_id) { - *guid16++ = SDL_SwapLE16(vendor_id); - *guid16++ = 0; - *guid16++ = SDL_SwapLE16(product_id); - *guid16++ = 0; - } else { - Uint32 crc = crc32(desc, SDL_strlen(desc)); - SDL_memcpy(guid16, desc, SDL_min(2*sizeof(*guid16), SDL_strlen(desc))); - guid16 += 2; - *(Uint32 *)guid16 = SDL_SwapLE32(crc); - guid16 += 2; + /* Update the GUID with capability bits */ + { + Uint16 *guid16 = (Uint16 *)guid.data; + guid16[6] = SDL_SwapLE16(button_mask); + guid16[7] = SDL_SwapLE16(axis_mask); } - *guid16++ = SDL_SwapLE16(button_mask); - *guid16++ = SDL_SwapLE16(axis_mask); - - item = (SDL_joylist_item *) SDL_malloc(sizeof (SDL_joylist_item)); - if (item == NULL) { - return -1; + item = (SDL_joylist_item *)SDL_malloc(sizeof(SDL_joylist_item)); + if (!item) { + goto done; } SDL_zerop(item); item->guid = guid; item->device_id = device_id; - item->name = SDL_strdup(name); - if (item->name == NULL) { - SDL_free(item); - return -1; + item->name = SDL_CreateJoystickName(vendor_id, product_id, NULL, name); + if (!item->name) { + SDL_free(item); + goto done; } - + item->is_accelerometer = is_accelerometer; if (button_mask == 0xFFFFFFFF) { item->nbuttons = ANDROID_MAX_NBUTTONS; } else { - for (i = 0; i < sizeof(button_mask)*8; ++i) { + for (i = 0; i < sizeof(button_mask) * 8; ++i) { if (button_mask & (1 << i)) { - item->nbuttons = i+1; + item->nbuttons = i + 1; } } } @@ -430,7 +381,7 @@ Android_AddJoystick(int device_id, const char *name, const char *desc, int vendo item->nhats = nhats; item->nballs = nballs; item->device_instance = SDL_GetNextJoystickInstanceID(); - if (SDL_joylist_tail == NULL) { + if (!SDL_joylist_tail) { SDL_joylist = SDL_joylist_tail = item; } else { SDL_joylist_tail->next = item; @@ -442,37 +393,44 @@ Android_AddJoystick(int device_id, const char *name, const char *desc, int vendo SDL_PrivateJoystickAdded(item->device_instance); + result = numjoysticks; + #ifdef DEBUG_JOYSTICK - SDL_Log("Added joystick %s with device_id %d", name, device_id); + SDL_Log("Added joystick %s with device_id %d", item->name, device_id); #endif - return numjoysticks; +done: + SDL_UnlockJoysticks(); + + return result; } -int -Android_RemoveJoystick(int device_id) +int Android_RemoveJoystick(int device_id) { SDL_joylist_item *item = SDL_joylist; SDL_joylist_item *prev = NULL; - + int result = -1; + + SDL_LockJoysticks(); + /* Don't call JoystickByDeviceId here or there'll be an infinite loop! */ - while (item != NULL) { + while (item) { if (item->device_id == device_id) { break; } prev = item; item = item->next; } - - if (item == NULL) { - return -1; + + if (!item) { + goto done; } if (item->joystick) { item->joystick->hwdata = NULL; } - - if (prev != NULL) { + + if (prev) { prev->next = item->next; } else { SDL_assert(SDL_joylist == item); @@ -487,39 +445,40 @@ Android_RemoveJoystick(int device_id) SDL_PrivateJoystickRemoved(item->device_instance); + result = numjoysticks; + #ifdef DEBUG_JOYSTICK SDL_Log("Removed joystick with device_id %d", device_id); #endif - + SDL_free(item->name); SDL_free(item); - return numjoysticks; -} +done: + SDL_UnlockJoysticks(); + + return result; +} static void ANDROID_JoystickDetect(void); -static int -ANDROID_JoystickInit(void) +static int ANDROID_JoystickInit(void) { ANDROID_JoystickDetect(); - + if (SDL_GetHintBoolean(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, SDL_TRUE)) { /* Default behavior, accelerometer as joystick */ - Android_AddJoystick(ANDROID_ACCELEROMETER_DEVICE_ID, ANDROID_ACCELEROMETER_NAME, ANDROID_ACCELEROMETER_NAME, 0, 0, SDL_TRUE, 0, 3, 0, 0); + Android_AddJoystick(ANDROID_ACCELEROMETER_DEVICE_ID, ANDROID_ACCELEROMETER_NAME, ANDROID_ACCELEROMETER_NAME, 0, 0, SDL_TRUE, 0, 3, 0x0003, 0, 0); } return 0; - } -static int -ANDROID_JoystickGetCount(void) +static int ANDROID_JoystickGetCount(void) { return numjoysticks; } -static void -ANDROID_JoystickDetect(void) +static void ANDROID_JoystickDetect(void) { /* Support for device connect/disconnect is API >= 16 only, * so we poll every three seconds @@ -532,8 +491,7 @@ ANDROID_JoystickDetect(void) } } -static SDL_joylist_item * -JoystickByDevIndex(int device_index) +static SDL_joylist_item *JoystickByDevIndex(int device_index) { SDL_joylist_item *item = SDL_joylist; @@ -550,22 +508,21 @@ JoystickByDevIndex(int device_index) return item; } -static SDL_joylist_item * -JoystickByDeviceId(int device_id) +static SDL_joylist_item *JoystickByDeviceId(int device_id) { SDL_joylist_item *item = SDL_joylist; - while (item != NULL) { + while (item) { if (item->device_id == device_id) { return item; } item = item->next; } - + /* Joystick not found, try adding it */ ANDROID_JoystickDetect(); - - while (item != NULL) { + + while (item) { if (item->device_id == device_id) { return item; } @@ -575,74 +532,101 @@ JoystickByDeviceId(int device_id) return NULL; } -static const char * -ANDROID_JoystickGetDeviceName(int device_index) +static const char *ANDROID_JoystickGetDeviceName(int device_index) { return JoystickByDevIndex(device_index)->name; } -static int -ANDROID_JoystickGetDevicePlayerIndex(int device_index) +static const char *ANDROID_JoystickGetDevicePath(int device_index) +{ + return NULL; +} + +static int ANDROID_JoystickGetDeviceSteamVirtualGamepadSlot(int device_index) { return -1; } -static void -ANDROID_JoystickSetDevicePlayerIndex(int device_index, int player_index) +static int ANDROID_JoystickGetDevicePlayerIndex(int device_index) +{ + return -1; +} + +static void ANDROID_JoystickSetDevicePlayerIndex(int device_index, int player_index) { } -static SDL_JoystickGUID -ANDROID_JoystickGetDeviceGUID(int device_index) +static SDL_JoystickGUID ANDROID_JoystickGetDeviceGUID(int device_index) { return JoystickByDevIndex(device_index)->guid; } -static SDL_JoystickID -ANDROID_JoystickGetDeviceInstanceID(int device_index) +static SDL_JoystickID ANDROID_JoystickGetDeviceInstanceID(int device_index) { return JoystickByDevIndex(device_index)->device_instance; } -static int -ANDROID_JoystickOpen(SDL_Joystick * joystick, int device_index) +static int ANDROID_JoystickOpen(SDL_Joystick *joystick, int device_index) { SDL_joylist_item *item = JoystickByDevIndex(device_index); - if (item == NULL) { + if (!item) { return SDL_SetError("No such device"); } - - if (item->joystick != NULL) { + + if (item->joystick) { return SDL_SetError("Joystick already opened"); } joystick->instance_id = item->device_instance; - joystick->hwdata = (struct joystick_hwdata *) item; + joystick->hwdata = (struct joystick_hwdata *)item; item->joystick = joystick; joystick->nhats = item->nhats; joystick->nballs = item->nballs; joystick->nbuttons = item->nbuttons; joystick->naxes = item->naxes; - return (0); + return 0; } -static int -ANDROID_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +static int ANDROID_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) { return SDL_Unsupported(); } -static void -ANDROID_JoystickUpdate(SDL_Joystick * joystick) +static int ANDROID_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) { - SDL_joylist_item *item = (SDL_joylist_item *) joystick->hwdata; + return SDL_Unsupported(); +} - if (item == NULL) { +static Uint32 ANDROID_JoystickGetCapabilities(SDL_Joystick *joystick) +{ + return 0; +} + +static int ANDROID_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + return SDL_Unsupported(); +} + +static int ANDROID_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + +static int ANDROID_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled) +{ + return SDL_Unsupported(); +} + +static void ANDROID_JoystickUpdate(SDL_Joystick *joystick) +{ + SDL_joylist_item *item = (SDL_joylist_item *)joystick->hwdata; + + if (!item) { return; } - + if (item->is_accelerometer) { int i; Sint16 value; @@ -663,17 +647,15 @@ ANDROID_JoystickUpdate(SDL_Joystick * joystick) } } -static void -ANDROID_JoystickClose(SDL_Joystick * joystick) +static void ANDROID_JoystickClose(SDL_Joystick *joystick) { - SDL_joylist_item *item = (SDL_joylist_item *) joystick->hwdata; + SDL_joylist_item *item = (SDL_joylist_item *)joystick->hwdata; if (item) { item->joystick = NULL; } } -static void -ANDROID_JoystickQuit(void) +static void ANDROID_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. @@ -694,21 +676,33 @@ ANDROID_JoystickQuit(void) #endif /* 0 */ } -SDL_JoystickDriver SDL_ANDROID_JoystickDriver = +static SDL_bool ANDROID_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) { + return SDL_FALSE; +} + +SDL_JoystickDriver SDL_ANDROID_JoystickDriver = { ANDROID_JoystickInit, ANDROID_JoystickGetCount, ANDROID_JoystickDetect, ANDROID_JoystickGetDeviceName, + ANDROID_JoystickGetDevicePath, + ANDROID_JoystickGetDeviceSteamVirtualGamepadSlot, ANDROID_JoystickGetDevicePlayerIndex, ANDROID_JoystickSetDevicePlayerIndex, ANDROID_JoystickGetDeviceGUID, ANDROID_JoystickGetDeviceInstanceID, ANDROID_JoystickOpen, ANDROID_JoystickRumble, + ANDROID_JoystickRumbleTriggers, + ANDROID_JoystickGetCapabilities, + ANDROID_JoystickSetLED, + ANDROID_JoystickSendEffect, + ANDROID_JoystickSetSensorsEnabled, ANDROID_JoystickUpdate, ANDROID_JoystickClose, ANDROID_JoystickQuit, + ANDROID_JoystickGetGamepadMapping }; #endif /* SDL_JOYSTICK_ANDROID */ diff --git a/SDL2-2.0.12/src/joystick/android/SDL_sysjoystick_c.h b/SDL2-2.30.5/src/joystick/android/SDL_sysjoystick_c.h similarity index 90% rename from SDL2-2.0.12/src/joystick/android/SDL_sysjoystick_c.h rename to SDL2-2.30.5/src/joystick/android/SDL_sysjoystick_c.h index 92ae64a..189bcf4 100644 --- a/SDL2-2.0.12/src/joystick/android/SDL_sysjoystick_c.h +++ b/SDL2-2.30.5/src/joystick/android/SDL_sysjoystick_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -32,7 +32,7 @@ extern int Android_OnPadDown(int device_id, int keycode); extern int Android_OnPadUp(int device_id, int keycode); extern int Android_OnJoy(int device_id, int axisnum, float value); extern int Android_OnHat(int device_id, int hat_id, int x, int y); -extern int Android_AddJoystick(int device_id, const char *name, const char *desc, int vendor_id, int product_id, SDL_bool is_accelerometer, int button_mask, int naxes, int nhats, int nballs); +extern int Android_AddJoystick(int device_id, const char *name, const char *desc, int vendor_id, int product_id, SDL_bool is_accelerometer, int button_mask, int naxes, int axis_mask, int nhats, int nballs); extern int Android_RemoveJoystick(int device_id); /* A linked list of available joysticks */ @@ -40,13 +40,13 @@ typedef struct SDL_joylist_item { int device_instance; int device_id; /* Android's device id */ - char *name; /* "SideWinder 3D Pro" or whatever */ + char *name; /* "SideWinder 3D Pro" or whatever */ SDL_JoystickGUID guid; SDL_bool is_accelerometer; SDL_Joystick *joystick; int nbuttons, naxes, nhats, nballs; int dpad_state; - + struct SDL_joylist_item *next; } SDL_joylist_item; diff --git a/SDL2-2.30.5/src/joystick/bsd/SDL_bsdjoystick.c b/SDL2-2.30.5/src/joystick/bsd/SDL_bsdjoystick.c new file mode 100644 index 0000000..3886fbf --- /dev/null +++ b/SDL2-2.30.5/src/joystick/bsd/SDL_bsdjoystick.c @@ -0,0 +1,898 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_JOYSTICK_USBHID + +/* + * Joystick driver for the uhid(4) / ujoy(4) interface found in OpenBSD, + * NetBSD and FreeBSD. + * + * Maintainer: + */ + +#include +#include + +#include +#include +#include + +#ifndef __FreeBSD_kernel_version +#define __FreeBSD_kernel_version __FreeBSD_version +#endif + +#if defined(HAVE_USB_H) +#include +#endif +#ifdef __DragonFly__ +#include +#include +#else +#include +#include +#endif + +#if defined(HAVE_USBHID_H) +#include +#elif defined(HAVE_LIBUSB_H) +#include +#elif defined(HAVE_LIBUSBHID_H) +#include +#endif + +#if defined(__FREEBSD__) || defined(__FreeBSD_kernel__) +#include +#if __FreeBSD_kernel_version > 800063 +#include +#elif defined(__DragonFly__) +#include +#endif +#include +#endif + +#ifdef SDL_HAVE_MACHINE_JOYSTICK_H +#include +#endif + +#include "SDL_joystick.h" +#include "../SDL_sysjoystick.h" +#include "../SDL_joystick_c.h" +#include "../hidapi/SDL_hidapijoystick_c.h" + +#if defined(__FREEBSD__) || SDL_HAVE_MACHINE_JOYSTICK_H || defined(__FreeBSD_kernel__) || defined(__DragonFly_) +#define SUPPORT_JOY_GAMEPORT +#endif + +#define MAX_UHID_JOYS 64 +#define MAX_JOY_JOYS 2 +#define MAX_JOYS (MAX_UHID_JOYS + MAX_JOY_JOYS) + +#ifdef __OpenBSD__ + +#define HUG_DPAD_UP 0x90 +#define HUG_DPAD_DOWN 0x91 +#define HUG_DPAD_RIGHT 0x92 +#define HUG_DPAD_LEFT 0x93 + +#define HAT_CENTERED 0x00 +#define HAT_UP 0x01 +#define HAT_RIGHT 0x02 +#define HAT_DOWN 0x04 +#define HAT_LEFT 0x08 +#define HAT_RIGHTUP (HAT_RIGHT | HAT_UP) +#define HAT_RIGHTDOWN (HAT_RIGHT | HAT_DOWN) +#define HAT_LEFTUP (HAT_LEFT | HAT_UP) +#define HAT_LEFTDOWN (HAT_LEFT | HAT_DOWN) + +/* calculate the value from the state of the dpad */ +int dpad_to_sdl(Sint32 *dpad) +{ + if (dpad[2]) { + if (dpad[0]) + return HAT_RIGHTUP; + else if (dpad[1]) + return HAT_RIGHTDOWN; + else + return HAT_RIGHT; + } else if (dpad[3]) { + if (dpad[0]) + return HAT_LEFTUP; + else if (dpad[1]) + return HAT_LEFTDOWN; + else + return HAT_LEFT; + } else if (dpad[0]) { + return HAT_UP; + } else if (dpad[1]) { + return HAT_DOWN; + } + return HAT_CENTERED; +} +#endif + +struct report +{ +#if defined(__FREEBSD__) && (__FreeBSD_kernel_version > 900000) || \ + defined(__DragonFly__) + void *buf; /* Buffer */ +#elif defined(__FREEBSD__) && (__FreeBSD_kernel_version > 800063) + struct usb_gen_descriptor *buf; /* Buffer */ +#else + struct usb_ctl_report *buf; /* Buffer */ +#endif + size_t size; /* Buffer size */ + int rid; /* Report ID */ + enum + { + SREPORT_UNINIT, + SREPORT_CLEAN, + SREPORT_DIRTY + } status; +}; + +static struct +{ + int uhid_report; + hid_kind_t kind; + const char *name; +} const repinfo[] = { + { UHID_INPUT_REPORT, hid_input, "input" }, + { UHID_OUTPUT_REPORT, hid_output, "output" }, + { UHID_FEATURE_REPORT, hid_feature, "feature" } +}; + +enum +{ + REPORT_INPUT = 0, + REPORT_OUTPUT = 1, + REPORT_FEATURE = 2 +}; + +enum +{ + JOYAXE_X, + JOYAXE_Y, + JOYAXE_Z, + JOYAXE_SLIDER, + JOYAXE_WHEEL, + JOYAXE_RX, + JOYAXE_RY, + JOYAXE_RZ, + JOYAXE_count +}; + +struct joystick_hwdata +{ + int fd; + enum + { + BSDJOY_UHID, /* uhid(4) */ + BSDJOY_JOY /* joy(4) */ + } type; + + int naxes; + int nbuttons; + int nhats; + struct report_desc *repdesc; + struct report inreport; + int axis_map[JOYAXE_count]; /* map present JOYAXE_* to 0,1,.. */ +}; + +/* A linked list of available joysticks */ +typedef struct SDL_joylist_item +{ + SDL_JoystickID device_instance; + char *path; /* "/dev/uhid0" or whatever */ + char *name; /* "SideWinder 3D Pro" or whatever */ + SDL_JoystickGUID guid; + dev_t devnum; + struct SDL_joylist_item *next; +} SDL_joylist_item; + +static SDL_joylist_item *SDL_joylist = NULL; +static SDL_joylist_item *SDL_joylist_tail = NULL; +static int numjoysticks = 0; + +static int report_alloc(struct report *, struct report_desc *, int); +static void report_free(struct report *); + +#if defined(USBHID_UCR_DATA) || (defined(__FreeBSD_kernel__) && __FreeBSD_kernel_version <= 800063) +#define REP_BUF_DATA(rep) ((rep)->buf->ucr_data) +#elif (defined(__FREEBSD__) && (__FreeBSD_kernel_version > 900000)) || \ + defined(__DragonFly__) +#define REP_BUF_DATA(rep) ((rep)->buf) +#elif (defined(__FREEBSD__) && (__FreeBSD_kernel_version > 800063)) +#define REP_BUF_DATA(rep) ((rep)->buf->ugd_data) +#else +#define REP_BUF_DATA(rep) ((rep)->buf->data) +#endif + +static int usage_to_joyaxe(int usage) +{ + int joyaxe; + switch (usage) { + case HUG_X: + joyaxe = JOYAXE_X; + break; + case HUG_Y: + joyaxe = JOYAXE_Y; + break; + case HUG_Z: + joyaxe = JOYAXE_Z; + break; + case HUG_SLIDER: + joyaxe = JOYAXE_SLIDER; + break; + case HUG_WHEEL: + joyaxe = JOYAXE_WHEEL; + break; + case HUG_RX: + joyaxe = JOYAXE_RX; + break; + case HUG_RY: + joyaxe = JOYAXE_RY; + break; + case HUG_RZ: + joyaxe = JOYAXE_RZ; + break; + default: + joyaxe = -1; + } + return joyaxe; +} + +static void FreeJoylistItem(SDL_joylist_item *item) +{ + SDL_free(item->path); + SDL_free(item->name); + SDL_free(item); +} + +static void FreeHwData(struct joystick_hwdata *hw) +{ + if (hw->type == BSDJOY_UHID) { + report_free(&hw->inreport); + + if (hw->repdesc) { + hid_dispose_report_desc(hw->repdesc); + } + } + close(hw->fd); + SDL_free(hw); +} + +static struct joystick_hwdata * +CreateHwData(const char *path) +{ + struct joystick_hwdata *hw; + struct hid_item hitem; + struct hid_data *hdata; + struct report *rep = NULL; + int fd; + int i; + + fd = open(path, O_RDONLY | O_CLOEXEC); + if (fd == -1) { + SDL_SetError("%s: %s", path, strerror(errno)); + return NULL; + } + + hw = (struct joystick_hwdata *) + SDL_calloc(1, sizeof(struct joystick_hwdata)); + if (!hw) { + close(fd); + SDL_OutOfMemory(); + return NULL; + } + hw->fd = fd; + +#ifdef SUPPORT_JOY_GAMEPORT + if (SDL_strncmp(path, "/dev/joy", 8) == 0) { + hw->type = BSDJOY_JOY; + hw->naxes = 2; + hw->nbuttons = 2; + } else +#endif + { + hw->type = BSDJOY_UHID; + { + int ax; + for (ax = 0; ax < JOYAXE_count; ax++) { + hw->axis_map[ax] = -1; + } + } + hw->repdesc = hid_get_report_desc(fd); + if (!hw->repdesc) { + SDL_SetError("%s: USB_GET_REPORT_DESC: %s", path, + strerror(errno)); + goto usberr; + } + rep = &hw->inreport; +#if defined(__FREEBSD__) && (__FreeBSD_kernel_version > 800063) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) + rep->rid = hid_get_report_id(fd); + if (rep->rid < 0) { +#else + if (ioctl(fd, USB_GET_REPORT_ID, &rep->rid) < 0) { +#endif + rep->rid = -1; /* XXX */ + } + if (report_alloc(rep, hw->repdesc, REPORT_INPUT) < 0) { + goto usberr; + } + if (rep->size <= 0) { + SDL_SetError("%s: Input report descriptor has invalid length", + path); + goto usberr; + } +#if defined(USBHID_NEW) || (defined(__FREEBSD__) && __FreeBSD_kernel_version >= 500111) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) + hdata = hid_start_parse(hw->repdesc, 1 << hid_input, rep->rid); +#else + hdata = hid_start_parse(hw->repdesc, 1 << hid_input); +#endif + if (!hdata) { + SDL_SetError("%s: Cannot start HID parser", path); + goto usberr; + } + for (i = 0; i < JOYAXE_count; i++) { + hw->axis_map[i] = -1; + } + + while (hid_get_item(hdata, &hitem) > 0) { + switch (hitem.kind) { + case hid_input: + switch (HID_PAGE(hitem.usage)) { + case HUP_GENERIC_DESKTOP: + { + int usage = HID_USAGE(hitem.usage); + int joyaxe = usage_to_joyaxe(usage); + if (joyaxe >= 0) { + hw->axis_map[joyaxe] = 1; + } else if (usage == HUG_HAT_SWITCH +#ifdef __OpenBSD__ + || usage == HUG_DPAD_UP +#endif + ) { + hw->nhats++; + } + break; + } + case HUP_BUTTON: + { + int usage = HID_USAGE(hitem.usage); + if (usage > hw->nbuttons) { + hw->nbuttons = usage; + } + } break; + default: + break; + } + break; + default: + break; + } + } + hid_end_parse(hdata); + for (i = 0; i < JOYAXE_count; i++) { + if (hw->axis_map[i] > 0) { + hw->axis_map[i] = hw->naxes++; + } + } + + if (hw->naxes == 0 && hw->nbuttons == 0 && hw->nhats == 0) { + SDL_SetError("%s: Not a joystick, ignoring", path); + goto usberr; + } + } + + /* The poll blocks the event thread. */ + fcntl(fd, F_SETFL, O_NONBLOCK); +#ifdef __NetBSD__ + /* Flush pending events */ + if (rep) { + while (read(fd, REP_BUF_DATA(rep), rep->size) == rep->size) + ; + } +#endif + + return hw; + +usberr: + FreeHwData(hw); + return NULL; +} + +static int MaybeAddDevice(const char *path) +{ + struct stat sb; + char *name = NULL; + SDL_JoystickGUID guid; + SDL_joylist_item *item; + struct joystick_hwdata *hw; + + if (!path) { + return -1; + } + + if (stat(path, &sb) == -1) { + return -1; + } + + /* Check to make sure it's not already in list. */ + for (item = SDL_joylist; item; item = item->next) { + if (sb.st_rdev == item->devnum) { + return -1; /* already have this one */ + } + } + + hw = CreateHwData(path); + if (!hw) { + return -1; + } + + if (hw->type == BSDJOY_JOY) { + name = SDL_strdup("Gameport joystick"); + guid = SDL_CreateJoystickGUIDForName(name); + } else { +#ifdef USB_GET_DEVICEINFO + struct usb_device_info di; + if (ioctl(hw->fd, USB_GET_DEVICEINFO, &di) != -1) { + name = SDL_CreateJoystickName(di.udi_vendorNo, di.udi_productNo, di.udi_vendor, di.udi_product); + guid = SDL_CreateJoystickGUID(SDL_HARDWARE_BUS_USB, di.udi_vendorNo, di.udi_productNo, di.udi_releaseNo, di.udi_vendor, di.udi_product, 0, 0); + +#ifdef SDL_JOYSTICK_HIDAPI + if (HIDAPI_IsDevicePresent(di.udi_vendorNo, di.udi_productNo, di.udi_releaseNo, name)) { + /* The HIDAPI driver is taking care of this device */ + SDL_free(name); + FreeHwData(hw); + return -1; + } +#endif + if (SDL_ShouldIgnoreJoystick(name, guid)) { + SDL_free(name); + FreeHwData(hw); + return -1; + } + } +#endif /* USB_GET_DEVICEINFO */ + } + if (!name) { + name = SDL_strdup(path); + guid = SDL_CreateJoystickGUIDForName(name); + } + FreeHwData(hw); + + item = (SDL_joylist_item *)SDL_calloc(1, sizeof(SDL_joylist_item)); + if (!item) { + SDL_free(name); + return -1; + } + + item->devnum = sb.st_rdev; + item->path = SDL_strdup(path); + item->name = name; + item->guid = guid; + + if ((!item->path) || (!item->name)) { + FreeJoylistItem(item); + return -1; + } + + item->device_instance = SDL_GetNextJoystickInstanceID(); + if (!SDL_joylist_tail) { + 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(item->device_instance); + + return numjoysticks; +} + +static int BSD_JoystickInit(void) +{ + char s[16]; + int i; + + for (i = 0; i < MAX_UHID_JOYS; i++) { +#if defined(__OpenBSD__) && (OpenBSD >= 202105) + SDL_snprintf(s, SDL_arraysize(s), "/dev/ujoy/%d", i); +#else + SDL_snprintf(s, SDL_arraysize(s), "/dev/uhid%d", i); +#endif + MaybeAddDevice(s); + } +#ifdef SUPPORT_JOY_GAMEPORT + for (i = 0; i < MAX_JOY_JOYS; i++) { + SDL_snprintf(s, SDL_arraysize(s), "/dev/joy%d", i); + MaybeAddDevice(s); + } +#endif /* SUPPORT_JOY_GAMEPORT */ + + /* Read the default USB HID usage table. */ + hid_init(NULL); + + return numjoysticks; +} + +static int BSD_JoystickGetCount(void) +{ + return numjoysticks; +} + +static void BSD_JoystickDetect(void) +{ +} + +static SDL_joylist_item *JoystickByDevIndex(int device_index) +{ + SDL_joylist_item *item = SDL_joylist; + + if ((device_index < 0) || (device_index >= numjoysticks)) { + return NULL; + } + + while (device_index > 0) { + SDL_assert(item != NULL); + device_index--; + item = item->next; + } + + return item; +} + +static const char *BSD_JoystickGetDeviceName(int device_index) +{ + return JoystickByDevIndex(device_index)->name; +} + +static const char *BSD_JoystickGetDevicePath(int device_index) +{ + return JoystickByDevIndex(device_index)->path; +} + +static int BSD_JoystickGetDeviceSteamVirtualGamepadSlot(int device_index) +{ + return -1; +} + +static int BSD_JoystickGetDevicePlayerIndex(int device_index) +{ + return -1; +} + +static void BSD_JoystickSetDevicePlayerIndex(int device_index, int player_index) +{ +} + +static SDL_JoystickGUID BSD_JoystickGetDeviceGUID(int device_index) +{ + return JoystickByDevIndex(device_index)->guid; +} + +/* Function to perform the mapping from device index to the instance id for this index */ +static SDL_JoystickID BSD_JoystickGetDeviceInstanceID(int device_index) +{ + return JoystickByDevIndex(device_index)->device_instance; +} + +static unsigned hatval_to_sdl(Sint32 hatval) +{ + static const unsigned hat_dir_map[8] = { + SDL_HAT_UP, SDL_HAT_RIGHTUP, SDL_HAT_RIGHT, SDL_HAT_RIGHTDOWN, + SDL_HAT_DOWN, SDL_HAT_LEFTDOWN, SDL_HAT_LEFT, SDL_HAT_LEFTUP + }; + unsigned result; + if ((hatval & 7) == hatval) + result = hat_dir_map[hatval]; + else + result = SDL_HAT_CENTERED; + return result; +} + +static int BSD_JoystickOpen(SDL_Joystick *joy, int device_index) +{ + SDL_joylist_item *item = JoystickByDevIndex(device_index); + struct joystick_hwdata *hw; + + if (!item) { + return SDL_SetError("No such device"); + } + + hw = CreateHwData(item->path); + if (!hw) { + return -1; + } + + joy->instance_id = item->device_instance; + joy->hwdata = hw; + joy->naxes = hw->naxes; + joy->nbuttons = hw->nbuttons; + joy->nhats = hw->nhats; + + return 0; +} + +static void BSD_JoystickUpdate(SDL_Joystick *joy) +{ + struct hid_item hitem; + struct hid_data *hdata; + struct report *rep; + int nbutton, naxe = -1; + Sint32 v; +#ifdef __OpenBSD__ + Sint32 dpad[4] = { 0, 0, 0, 0 }; +#endif + +#ifdef SUPPORT_JOY_GAMEPORT + struct joystick gameport; + static int x, y, xmin = 0xffff, ymin = 0xffff, xmax = 0, ymax = 0; + + if (joy->hwdata->type == BSDJOY_JOY) { + while (read(joy->hwdata->fd, &gameport, sizeof(gameport)) == sizeof(gameport)) { + if (SDL_abs(x - gameport.x) > 8) { + x = gameport.x; + if (x < xmin) { + xmin = x; + } + if (x > xmax) { + xmax = x; + } + if (xmin == xmax) { + xmin--; + xmax++; + } + v = (((SDL_JOYSTICK_AXIS_MAX - SDL_JOYSTICK_AXIS_MIN) * ((Sint32)x - xmin)) / (xmax - xmin)) + SDL_JOYSTICK_AXIS_MIN; + SDL_PrivateJoystickAxis(joy, 0, v); + } + if (SDL_abs(y - gameport.y) > 8) { + y = gameport.y; + if (y < ymin) { + ymin = y; + } + if (y > ymax) { + ymax = y; + } + if (ymin == ymax) { + ymin--; + ymax++; + } + v = (((SDL_JOYSTICK_AXIS_MAX - SDL_JOYSTICK_AXIS_MIN) * ((Sint32)y - ymin)) / (ymax - ymin)) + SDL_JOYSTICK_AXIS_MIN; + SDL_PrivateJoystickAxis(joy, 1, v); + } + SDL_PrivateJoystickButton(joy, 0, gameport.b1); + SDL_PrivateJoystickButton(joy, 1, gameport.b2); + } + return; + } +#endif /* SUPPORT_JOY_GAMEPORT */ + + rep = &joy->hwdata->inreport; + + while (read(joy->hwdata->fd, REP_BUF_DATA(rep), rep->size) == rep->size) { +#if defined(USBHID_NEW) || (defined(__FREEBSD__) && __FreeBSD_kernel_version >= 500111) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) + hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input, rep->rid); +#else + hdata = hid_start_parse(joy->hwdata->repdesc, 1 << hid_input); +#endif + if (!hdata) { + /*fprintf(stderr, "%s: Cannot start HID parser\n", joy->hwdata->path);*/ + continue; + } + + while (hid_get_item(hdata, &hitem) > 0) { + switch (hitem.kind) { + case hid_input: + switch (HID_PAGE(hitem.usage)) { + case HUP_GENERIC_DESKTOP: + { + int usage = HID_USAGE(hitem.usage); + int joyaxe = usage_to_joyaxe(usage); + if (joyaxe >= 0) { + naxe = joy->hwdata->axis_map[joyaxe]; + /* scaleaxe */ + v = (Sint32)hid_get_data(REP_BUF_DATA(rep), &hitem); + v = (((SDL_JOYSTICK_AXIS_MAX - SDL_JOYSTICK_AXIS_MIN) * (v - hitem.logical_minimum)) / (hitem.logical_maximum - hitem.logical_minimum)) + SDL_JOYSTICK_AXIS_MIN; + SDL_PrivateJoystickAxis(joy, naxe, v); + } else if (usage == HUG_HAT_SWITCH) { + v = (Sint32)hid_get_data(REP_BUF_DATA(rep), &hitem); + SDL_PrivateJoystickHat(joy, 0, + hatval_to_sdl(v) - + hitem.logical_minimum); + } +#ifdef __OpenBSD__ + else if (usage == HUG_DPAD_UP) { + dpad[0] = (Sint32)hid_get_data(REP_BUF_DATA(rep), &hitem); + SDL_PrivateJoystickHat(joy, 0, dpad_to_sdl(dpad)); + } else if (usage == HUG_DPAD_DOWN) { + dpad[1] = (Sint32)hid_get_data(REP_BUF_DATA(rep), &hitem); + SDL_PrivateJoystickHat(joy, 0, dpad_to_sdl(dpad)); + } else if (usage == HUG_DPAD_RIGHT) { + dpad[2] = (Sint32)hid_get_data(REP_BUF_DATA(rep), &hitem); + SDL_PrivateJoystickHat(joy, 0, dpad_to_sdl(dpad)); + } else if (usage == HUG_DPAD_LEFT) { + dpad[3] = (Sint32)hid_get_data(REP_BUF_DATA(rep), &hitem); + SDL_PrivateJoystickHat(joy, 0, dpad_to_sdl(dpad)); + } +#endif + break; + } + case HUP_BUTTON: + v = (Sint32)hid_get_data(REP_BUF_DATA(rep), &hitem); + nbutton = HID_USAGE(hitem.usage) - 1; /* SDL buttons are zero-based */ + SDL_PrivateJoystickButton(joy, nbutton, v); + break; + default: + continue; + } + break; + default: + break; + } + } + hid_end_parse(hdata); + } +} + +/* Function to close a joystick after use */ +static void BSD_JoystickClose(SDL_Joystick *joy) +{ + if (joy->hwdata) { + FreeHwData(joy->hwdata); + joy->hwdata = NULL; + } +} + +static void BSD_JoystickQuit(void) +{ + SDL_joylist_item *item = NULL; + SDL_joylist_item *next = NULL; + + for (item = SDL_joylist; item; item = next) { + next = item->next; + FreeJoylistItem(item); + } + + SDL_joylist = SDL_joylist_tail = NULL; + + numjoysticks = 0; +} + +static int report_alloc(struct report *r, struct report_desc *rd, int repind) +{ + int len; + +#ifdef __DragonFly__ + len = hid_report_size(rd, repinfo[repind].kind, r->rid); +#elif defined(__FREEBSD__) +#if (__FreeBSD_kernel_version >= 460000) || defined(__FreeBSD_kernel__) +#if (__FreeBSD_kernel_version <= 500111) + len = hid_report_size(rd, r->rid, repinfo[repind].kind); +#else + len = hid_report_size(rd, repinfo[repind].kind, r->rid); +#endif +#else + len = hid_report_size(rd, repinfo[repind].kind, &r->rid); +#endif +#else +#ifdef USBHID_NEW + len = hid_report_size(rd, repinfo[repind].kind, r->rid); +#else + len = hid_report_size(rd, repinfo[repind].kind, &r->rid); +#endif +#endif + + if (len < 0) { + return SDL_SetError("Negative HID report size"); + } + r->size = len; + + if (r->size > 0) { +#if defined(__FREEBSD__) && (__FreeBSD_kernel_version > 900000) || defined(__DragonFly__) + r->buf = SDL_malloc(r->size); +#else + r->buf = SDL_malloc(sizeof(*r->buf) - sizeof(REP_BUF_DATA(r)) + + r->size); +#endif + if (!r->buf) { + return SDL_OutOfMemory(); + } + } else { + r->buf = NULL; + } + + r->status = SREPORT_CLEAN; + return 0; +} + +static void report_free(struct report *r) +{ + SDL_free(r->buf); + r->status = SREPORT_UNINIT; +} + +static int BSD_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ + return SDL_Unsupported(); +} + +static int BSD_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) +{ + return SDL_Unsupported(); +} + +static SDL_bool BSD_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) +{ + return SDL_FALSE; +} + +static Uint32 BSD_JoystickGetCapabilities(SDL_Joystick *joystick) +{ + return 0; +} + +static int BSD_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + return SDL_Unsupported(); +} + +static int BSD_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + +static int BSD_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled) +{ + return SDL_Unsupported(); +} + +SDL_JoystickDriver SDL_BSD_JoystickDriver = { + BSD_JoystickInit, + BSD_JoystickGetCount, + BSD_JoystickDetect, + BSD_JoystickGetDeviceName, + BSD_JoystickGetDevicePath, + BSD_JoystickGetDeviceSteamVirtualGamepadSlot, + BSD_JoystickGetDevicePlayerIndex, + BSD_JoystickSetDevicePlayerIndex, + BSD_JoystickGetDeviceGUID, + BSD_JoystickGetDeviceInstanceID, + BSD_JoystickOpen, + BSD_JoystickRumble, + BSD_JoystickRumbleTriggers, + BSD_JoystickGetCapabilities, + BSD_JoystickSetLED, + BSD_JoystickSendEffect, + BSD_JoystickSetSensorsEnabled, + BSD_JoystickUpdate, + BSD_JoystickClose, + BSD_JoystickQuit, + BSD_JoystickGetGamepadMapping +}; + +#endif /* SDL_JOYSTICK_USBHID */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/joystick/check_8bitdo.sh b/SDL2-2.30.5/src/joystick/check_8bitdo.sh new file mode 100644 index 0000000..5e172db --- /dev/null +++ b/SDL2-2.30.5/src/joystick/check_8bitdo.sh @@ -0,0 +1,15 @@ +#!/bin/sh +# +# Check to make sure 8BitDo controller configurations are correct + +echo "Expected output:" +cat <<__EOF__ + "050000003512000020ab000000780f00,8BitDo SNES30 Gamepad,a:b20,b:b21,back:b30,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b26,rightshoulder:b27,start:b31,x:b23,y:b24,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + "050000003512000020ab000000780f00,8BitDo SNES30 Gamepad,a:b21,b:b20,back:b30,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b26,rightshoulder:b27,start:b31,x:b24,y:b23,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", + +__EOF__ + +echo "Actual output:" +${FGREP:-grep -F} 8BitDo SDL_gamecontrollerdb.h | ${FGREP:-grep -F} -v hint +${EGREP:-grep -E} "hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1" SDL_gamecontrollerdb.h | ${FGREP:-grep -F} -i 8bit | ${FGREP:-grep -F} -v x:b2,y:b3 | ${FGREP:-grep -F} -v x:b3,y:b4 +${EGREP:-grep -E} "hint:.SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1" SDL_gamecontrollerdb.h | ${FGREP:-grep -F} -i 8bit | ${FGREP:-grep -F} -v x:b3,y:b2 | ${FGREP:-grep -F} -v x:b4,y:b3 diff --git a/SDL2-2.0.12/src/joystick/controller_type.h b/SDL2-2.30.5/src/joystick/controller_list.h similarity index 74% rename from SDL2-2.0.12/src/joystick/controller_type.h rename to SDL2-2.30.5/src/joystick/controller_list.h index 0ea1cbf..fd77b2a 100644 --- a/SDL2-2.0.12/src/joystick/controller_type.h +++ b/SDL2-2.30.5/src/joystick/controller_list.h @@ -17,63 +17,15 @@ misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ - -#ifndef CONTROLLER_TYPE_H -#define CONTROLLER_TYPE_H -#ifdef _WIN32 -#pragma once -#endif - -//----------------------------------------------------------------------------- -// Purpose: Steam Controller models -// WARNING: DO NOT RENUMBER EXISTING VALUES - STORED IN A DATABASE -//----------------------------------------------------------------------------- -typedef enum -{ - k_eControllerType_None = -1, - k_eControllerType_Unknown = 0, - - // Steam Controllers - k_eControllerType_UnknownSteamController = 1, - k_eControllerType_SteamController = 2, - k_eControllerType_SteamControllerV2 = 3, - - // Other Controllers - k_eControllerType_UnknownNonSteamController = 30, - k_eControllerType_XBox360Controller = 31, - k_eControllerType_XBoxOneController = 32, - k_eControllerType_PS3Controller = 33, - k_eControllerType_PS4Controller = 34, - k_eControllerType_WiiController = 35, - k_eControllerType_AppleController = 36, - k_eControllerType_AndroidController = 37, - k_eControllerType_SwitchProController = 38, - k_eControllerType_SwitchJoyConLeft = 39, - k_eControllerType_SwitchJoyConRight = 40, - k_eControllerType_SwitchJoyConPair = 41, - k_eControllerType_SwitchInputOnlyController = 42, - k_eControllerType_MobileTouch = 43, - k_eControllerType_XInputSwitchController = 44, // Client-side only, used to mark Switch-compatible controllers as not supporting Switch controller protocol - k_eControllerType_LastController, // Don't add game controllers below this enumeration - this enumeration can change value - - // Keyboards and Mice - k_eControllertype_GenericKeyboard = 400, - k_eControllertype_GenericMouse = 800, -} EControllerType; - #define MAKE_CONTROLLER_ID( nVID, nPID ) (unsigned int)( (unsigned int)nVID << 16 | (unsigned int)nPID ) -typedef struct -{ - unsigned int m_unDeviceID; - EControllerType m_eControllerType; - const char *m_pszName; -} ControllerDescription_t; static const ControllerDescription_t arrControllers[] = { { MAKE_CONTROLLER_ID( 0x0079, 0x181a ), k_eControllerType_PS3Controller, NULL }, // Venom Arcade Stick { MAKE_CONTROLLER_ID( 0x0079, 0x1844 ), k_eControllerType_PS3Controller, NULL }, // From SDL { MAKE_CONTROLLER_ID( 0x044f, 0xb315 ), k_eControllerType_PS3Controller, NULL }, // Firestorm Dual Analog 3 { MAKE_CONTROLLER_ID( 0x044f, 0xd007 ), k_eControllerType_PS3Controller, NULL }, // Thrustmaster wireless 3-1 + { MAKE_CONTROLLER_ID( 0x046d, 0xcad1 ), k_eControllerType_PS3Controller, NULL }, // Logitech Chillstream + //{ MAKE_CONTROLLER_ID( 0x046d, 0xc24f ), k_eControllerType_PS3Controller, NULL }, // Logitech G29 (PS3) { MAKE_CONTROLLER_ID( 0x054c, 0x0268 ), k_eControllerType_PS3Controller, NULL }, // Sony PS3 Controller { MAKE_CONTROLLER_ID( 0x056e, 0x200f ), k_eControllerType_PS3Controller, NULL }, // From SDL { MAKE_CONTROLLER_ID( 0x056e, 0x2013 ), k_eControllerType_PS3Controller, NULL }, // JC-U4113SBK @@ -82,6 +34,7 @@ static const ControllerDescription_t arrControllers[] = { { MAKE_CONTROLLER_ID( 0x06a3, 0xf622 ), k_eControllerType_PS3Controller, NULL }, // Cyborg V3 { MAKE_CONTROLLER_ID( 0x0738, 0x3180 ), k_eControllerType_PS3Controller, NULL }, // Mad Catz Alpha PS3 mode { MAKE_CONTROLLER_ID( 0x0738, 0x3250 ), k_eControllerType_PS3Controller, NULL }, // madcats fightpad pro ps3 + { MAKE_CONTROLLER_ID( 0x0738, 0x3481 ), k_eControllerType_PS3Controller, NULL }, // Mad Catz FightStick TE 2+ PS3 { MAKE_CONTROLLER_ID( 0x0738, 0x8180 ), k_eControllerType_PS3Controller, NULL }, // Mad Catz Alpha PS4 mode (no touchpad on device) { MAKE_CONTROLLER_ID( 0x0738, 0x8838 ), k_eControllerType_PS3Controller, NULL }, // Madcatz Fightstick Pro { MAKE_CONTROLLER_ID( 0x0810, 0x0001 ), k_eControllerType_PS3Controller, NULL }, // actually ps2 - maybe break out later @@ -92,7 +45,6 @@ static const ControllerDescription_t arrControllers[] = { { MAKE_CONTROLLER_ID( 0x0e6f, 0x0109 ), k_eControllerType_PS3Controller, NULL }, // PDP Versus Fighting Pad { MAKE_CONTROLLER_ID( 0x0e6f, 0x011e ), k_eControllerType_PS3Controller, NULL }, // Rock Candy PS4 { MAKE_CONTROLLER_ID( 0x0e6f, 0x0128 ), k_eControllerType_PS3Controller, NULL }, // Rock Candy PS3 - { MAKE_CONTROLLER_ID( 0x0e6f, 0x0203 ), k_eControllerType_PS3Controller, NULL }, // Victrix Pro FS (PS4 peripheral but no trackpad/lightbar) { MAKE_CONTROLLER_ID( 0x0e6f, 0x0214 ), k_eControllerType_PS3Controller, NULL }, // afterglow ps3 { MAKE_CONTROLLER_ID( 0x0e6f, 0x1314 ), k_eControllerType_PS3Controller, NULL }, // PDP Afterglow Wireless PS3 controller { MAKE_CONTROLLER_ID( 0x0e6f, 0x6302 ), k_eControllerType_PS3Controller, NULL }, // From SDL @@ -101,18 +53,16 @@ static const ControllerDescription_t arrControllers[] = { { MAKE_CONTROLLER_ID( 0x0e8f, 0x310d ), k_eControllerType_PS3Controller, NULL }, // From SDL { MAKE_CONTROLLER_ID( 0x0f0d, 0x0009 ), k_eControllerType_PS3Controller, NULL }, // HORI BDA GP1 { MAKE_CONTROLLER_ID( 0x0f0d, 0x004d ), k_eControllerType_PS3Controller, NULL }, // Horipad 3 - { MAKE_CONTROLLER_ID( 0x0f0d, 0x005e ), k_eControllerType_PS3Controller, NULL }, // HORI Fighting commander ps4 - { MAKE_CONTROLLER_ID( 0x0f0d, 0x005f ), k_eControllerType_PS3Controller, NULL }, // HORI Fighting commander ps3 + { MAKE_CONTROLLER_ID( 0x0f0d, 0x005f ), k_eControllerType_PS3Controller, NULL }, // HORI Fighting Commander 4 PS3 { MAKE_CONTROLLER_ID( 0x0f0d, 0x006a ), k_eControllerType_PS3Controller, NULL }, // Real Arcade Pro 4 { MAKE_CONTROLLER_ID( 0x0f0d, 0x006e ), k_eControllerType_PS3Controller, NULL }, // HORI horipad4 ps3 { MAKE_CONTROLLER_ID( 0x0f0d, 0x0085 ), k_eControllerType_PS3Controller, NULL }, // HORI Fighting Commander PS3 { MAKE_CONTROLLER_ID( 0x0f0d, 0x0086 ), k_eControllerType_PS3Controller, NULL }, // HORI Fighting Commander PC (Uses the Xbox 360 protocol, but has PS3 buttons) - { MAKE_CONTROLLER_ID( 0x0f0d, 0x0087 ), k_eControllerType_PS3Controller, NULL }, // HORI fighting mini stick - { MAKE_CONTROLLER_ID( 0x0f30, 0x1100 ), k_eControllerType_PS3Controller, NULL }, // Quanba Q1 fight stick + { MAKE_CONTROLLER_ID( 0x0f0d, 0x0088 ), k_eControllerType_PS3Controller, NULL }, // HORI Fighting Stick mini 4 + { MAKE_CONTROLLER_ID( 0x0f30, 0x1100 ), k_eControllerType_PS3Controller, NULL }, // Qanba Q1 fight stick { MAKE_CONTROLLER_ID( 0x11ff, 0x3331 ), k_eControllerType_PS3Controller, NULL }, // SRXJ-PH2400 { MAKE_CONTROLLER_ID( 0x1345, 0x1000 ), k_eControllerType_PS3Controller, NULL }, // PS2 ACME GA-D5 { MAKE_CONTROLLER_ID( 0x1345, 0x6005 ), k_eControllerType_PS3Controller, NULL }, // ps2 maybe break out later - { MAKE_CONTROLLER_ID( 0x146b, 0x0603 ), k_eControllerType_PS3Controller, NULL }, // From SDL { MAKE_CONTROLLER_ID( 0x146b, 0x5500 ), k_eControllerType_PS3Controller, NULL }, // From SDL { MAKE_CONTROLLER_ID( 0x1a34, 0x0836 ), k_eControllerType_PS3Controller, NULL }, // Afterglow PS3 { MAKE_CONTROLLER_ID( 0x20bc, 0x5500 ), k_eControllerType_PS3Controller, NULL }, // ShanWan PS3 @@ -122,12 +72,15 @@ static const ControllerDescription_t arrControllers[] = { { MAKE_CONTROLLER_ID( 0x2563, 0x0575 ), k_eControllerType_PS3Controller, NULL }, // From SDL { MAKE_CONTROLLER_ID( 0x25f0, 0x83c3 ), k_eControllerType_PS3Controller, NULL }, // gioteck vx2 { MAKE_CONTROLLER_ID( 0x25f0, 0xc121 ), k_eControllerType_PS3Controller, NULL }, // - { MAKE_CONTROLLER_ID( 0x2c22, 0x2000 ), k_eControllerType_PS3Controller, NULL }, // Quanba Drone - { MAKE_CONTROLLER_ID( 0x2c22, 0x2003 ), k_eControllerType_PS3Controller, NULL }, // From SDL + { MAKE_CONTROLLER_ID( 0x2c22, 0x2003 ), k_eControllerType_PS3Controller, NULL }, // Qanba Drone + { MAKE_CONTROLLER_ID( 0x2c22, 0x2302 ), k_eControllerType_PS3Controller, NULL }, // Qanba Obsidian + { MAKE_CONTROLLER_ID( 0x2c22, 0x2502 ), k_eControllerType_PS3Controller, NULL }, // Qanba Dragon { MAKE_CONTROLLER_ID( 0x8380, 0x0003 ), k_eControllerType_PS3Controller, NULL }, // BTP 2163 { MAKE_CONTROLLER_ID( 0x8888, 0x0308 ), k_eControllerType_PS3Controller, NULL }, // Sony PS3 Controller { MAKE_CONTROLLER_ID( 0x0079, 0x181b ), k_eControllerType_PS4Controller, NULL }, // Venom Arcade Stick - XXX:this may not work and may need to be called a ps3 controller + //{ MAKE_CONTROLLER_ID( 0x046d, 0xc260 ), k_eControllerType_PS4Controller, NULL }, // Logitech G29 (PS4) + { MAKE_CONTROLLER_ID( 0x044f, 0xd00e ), k_eControllerType_PS4Controller, NULL }, // Thrustmaster Eswap Pro - No gyro and lightbar doesn't change color. Works otherwise { MAKE_CONTROLLER_ID( 0x054c, 0x05c4 ), k_eControllerType_PS4Controller, NULL }, // Sony PS4 Controller { MAKE_CONTROLLER_ID( 0x054c, 0x05c5 ), k_eControllerType_PS4Controller, NULL }, // STRIKEPAD PS4 Grip Add-on { MAKE_CONTROLLER_ID( 0x054c, 0x09cc ), k_eControllerType_PS4Controller, NULL }, // Sony PS4 Slim Controller @@ -136,21 +89,45 @@ static const ControllerDescription_t arrControllers[] = { { MAKE_CONTROLLER_ID( 0x0738, 0x8384 ), k_eControllerType_PS4Controller, NULL }, // Mad Catz FightStick TE S+ PS4 { MAKE_CONTROLLER_ID( 0x0738, 0x8480 ), k_eControllerType_PS4Controller, NULL }, // Mad Catz FightStick TE 2 PS4 { MAKE_CONTROLLER_ID( 0x0738, 0x8481 ), k_eControllerType_PS4Controller, NULL }, // Mad Catz FightStick TE 2+ PS4 - { MAKE_CONTROLLER_ID( 0x0C12, 0x0E10 ), k_eControllerType_PS4Controller, NULL }, // Armor Armor 3 Pad PS4 - { MAKE_CONTROLLER_ID( 0x0C12, 0x1CF6 ), k_eControllerType_PS4Controller, NULL }, // EMIO PS4 Elite Controller + { MAKE_CONTROLLER_ID( 0x0c12, 0x0e10 ), k_eControllerType_PS4Controller, NULL }, // Armor Armor 3 Pad PS4 + { MAKE_CONTROLLER_ID( 0x0c12, 0x0e13 ), k_eControllerType_PS4Controller, NULL }, // ZEROPLUS P4 Wired Gamepad { MAKE_CONTROLLER_ID( 0x0c12, 0x0e15 ), k_eControllerType_PS4Controller, NULL }, // Game:Pad 4 + { MAKE_CONTROLLER_ID( 0x0c12, 0x0e20 ), k_eControllerType_PS4Controller, NULL }, // Brook Mars Controller - needs FW update to show up as Ps4 controller on PC. Has Gyro but touchpad is a single button. { MAKE_CONTROLLER_ID( 0x0c12, 0x0ef6 ), k_eControllerType_PS4Controller, NULL }, // Hitbox Arcade Stick + { MAKE_CONTROLLER_ID( 0x0c12, 0x1cf6 ), k_eControllerType_PS4Controller, NULL }, // EMIO PS4 Elite Controller + { MAKE_CONTROLLER_ID( 0x0c12, 0x1e10 ), k_eControllerType_PS4Controller, NULL }, // P4 Wired Gamepad generic knock off - lightbar but not trackpad or gyro + { MAKE_CONTROLLER_ID( 0x0e6f, 0x0203 ), k_eControllerType_PS4Controller, NULL }, // Victrix Pro FS (PS4 peripheral but no trackpad/lightbar) + { MAKE_CONTROLLER_ID( 0x0e6f, 0x0207 ), k_eControllerType_PS4Controller, NULL }, // Victrix Pro FS V2 w/ Touchpad for PS4 + { MAKE_CONTROLLER_ID( 0x0e6f, 0x020a ), k_eControllerType_PS4Controller, NULL }, // Victrix Pro FS PS4/PS5 (PS4 mode) { MAKE_CONTROLLER_ID( 0x0f0d, 0x0055 ), k_eControllerType_PS4Controller, NULL }, // HORIPAD 4 FPS - { MAKE_CONTROLLER_ID( 0x0f0d, 0x0066 ), k_eControllerType_PS4Controller, NULL }, // HORIPAD 4 FPS Plus + { MAKE_CONTROLLER_ID( 0x0f0d, 0x005e ), k_eControllerType_PS4Controller, NULL }, // HORI Fighting Commander 4 PS4 + { MAKE_CONTROLLER_ID( 0x0f0d, 0x0066 ), k_eControllerType_PS4Controller, NULL }, // HORIPAD 4 FPS Plus { MAKE_CONTROLLER_ID( 0x0f0d, 0x0084 ), k_eControllerType_PS4Controller, NULL }, // HORI Fighting Commander PS4 + { MAKE_CONTROLLER_ID( 0x0f0d, 0x0087 ), k_eControllerType_PS4Controller, NULL }, // HORI Fighting Stick mini 4 { MAKE_CONTROLLER_ID( 0x0f0d, 0x008a ), k_eControllerType_PS4Controller, NULL }, // HORI Real Arcade Pro 4 { MAKE_CONTROLLER_ID( 0x0f0d, 0x009c ), k_eControllerType_PS4Controller, NULL }, // HORI TAC PRO mousething { MAKE_CONTROLLER_ID( 0x0f0d, 0x00a0 ), k_eControllerType_PS4Controller, NULL }, // HORI TAC4 mousething + { MAKE_CONTROLLER_ID( 0x0f0d, 0x00ed ), k_eControllerType_XInputPS4Controller, NULL }, // Hori Fighting Stick mini 4 kai - becomes an Xbox 360 controller on PC { MAKE_CONTROLLER_ID( 0x0f0d, 0x00ee ), k_eControllerType_PS4Controller, NULL }, // Hori mini wired https://www.playstation.com/en-us/explore/accessories/gaming-controllers/mini-wired-gamepad/ + { MAKE_CONTROLLER_ID( 0x0f0d, 0x011c ), k_eControllerType_PS4Controller, NULL }, // Hori Fighting Stick α + { MAKE_CONTROLLER_ID( 0x0f0d, 0x0123 ), k_eControllerType_PS4Controller, NULL }, // HORI Wireless Controller Light (Japan only) - only over bt- over usb is xbox and pid 0x0124 + { MAKE_CONTROLLER_ID( 0x0f0d, 0x0162 ), k_eControllerType_PS4Controller, NULL }, // HORI Fighting Commander OCTA + { MAKE_CONTROLLER_ID( 0x0f0d, 0x0164 ), k_eControllerType_XInputPS4Controller, NULL }, // HORI Fighting Commander OCTA { MAKE_CONTROLLER_ID( 0x11c0, 0x4001 ), k_eControllerType_PS4Controller, NULL }, // "PS4 Fun Controller" added from user log + { MAKE_CONTROLLER_ID( 0x146b, 0x0603 ), k_eControllerType_XInputPS4Controller, NULL }, // Nacon PS4 Compact Controller + { MAKE_CONTROLLER_ID( 0x146b, 0x0604 ), k_eControllerType_XInputPS4Controller, NULL }, // NACON Daija Arcade Stick + { MAKE_CONTROLLER_ID( 0x146b, 0x0605 ), k_eControllerType_XInputPS4Controller, NULL }, // NACON PS4 controller in Xbox mode - might also be other bigben brand xbox controllers + { MAKE_CONTROLLER_ID( 0x146b, 0x0606 ), k_eControllerType_XInputPS4Controller, NULL }, // NACON Unknown Controller + { MAKE_CONTROLLER_ID( 0x146b, 0x0609 ), k_eControllerType_XInputPS4Controller, NULL }, // NACON Wireless Controller for PS4 { MAKE_CONTROLLER_ID( 0x146b, 0x0d01 ), k_eControllerType_PS4Controller, NULL }, // Nacon Revolution Pro Controller - has gyro { MAKE_CONTROLLER_ID( 0x146b, 0x0d02 ), k_eControllerType_PS4Controller, NULL }, // Nacon Revolution Pro Controller v2 - has gyro + { MAKE_CONTROLLER_ID( 0x146b, 0x0d06 ), k_eControllerType_PS4Controller, NULL }, // NACON Asymetrical Controller Wireless Dongle -- show up as ps4 until you connect controller to it then it reboots into Xbox controller with different vvid/pid + { MAKE_CONTROLLER_ID( 0x146b, 0x0d08 ), k_eControllerType_PS4Controller, NULL }, // NACON Revolution Unlimited Wireless Dongle + { MAKE_CONTROLLER_ID( 0x146b, 0x0d09 ), k_eControllerType_PS4Controller, NULL }, // NACON Daija Fight Stick - touchpad but no gyro/rumble { MAKE_CONTROLLER_ID( 0x146b, 0x0d10 ), k_eControllerType_PS4Controller, NULL }, // NACON Revolution Infinite - has gyro + { MAKE_CONTROLLER_ID( 0x146b, 0x0d10 ), k_eControllerType_PS4Controller, NULL }, // NACON Revolution Unlimited + { MAKE_CONTROLLER_ID( 0x146b, 0x0d13 ), k_eControllerType_PS4Controller, NULL }, // NACON Revolution Pro Controller 3 + { MAKE_CONTROLLER_ID( 0x146b, 0x1103 ), k_eControllerType_PS4Controller, NULL }, // NACON Asymetrical Controller -- on windows this doesn't enumerate { MAKE_CONTROLLER_ID( 0x1532, 0X0401 ), k_eControllerType_PS4Controller, NULL }, // Razer Panthera PS4 Controller { MAKE_CONTROLLER_ID( 0x1532, 0x1000 ), k_eControllerType_PS4Controller, NULL }, // Razer Raiju PS4 Controller { MAKE_CONTROLLER_ID( 0x1532, 0x1004 ), k_eControllerType_PS4Controller, NULL }, // Razer Raiju 2 Ultimate USB @@ -159,20 +136,43 @@ static const ControllerDescription_t arrControllers[] = { { MAKE_CONTROLLER_ID( 0x1532, 0x1009 ), k_eControllerType_PS4Controller, NULL }, // Razer Raiju 2 Ultimate BT { MAKE_CONTROLLER_ID( 0x1532, 0x100A ), k_eControllerType_PS4Controller, NULL }, // Razer Raiju 2 Tournament edition BT { MAKE_CONTROLLER_ID( 0x1532, 0x1100 ), k_eControllerType_PS4Controller, NULL }, // Razer RAION Fightpad - Trackpad, no gyro, lightbar hardcoded to green - { MAKE_CONTROLLER_ID( 0x20d6, 0x792a ), k_eControllerType_PS4Controller, NULL }, // PowerA - Fusion Fight Pad + { MAKE_CONTROLLER_ID( 0x20d6, 0x792a ), k_eControllerType_PS4Controller, NULL }, // PowerA Fusion Fight Pad + { MAKE_CONTROLLER_ID( 0x2c22, 0x2000 ), k_eControllerType_PS4Controller, NULL }, // Qanba Drone + { MAKE_CONTROLLER_ID( 0x2c22, 0x2300 ), k_eControllerType_PS4Controller, NULL }, // Qanba Obsidian + { MAKE_CONTROLLER_ID( 0x2c22, 0x2303 ), k_eControllerType_XInputPS4Controller, NULL }, // Qanba Obsidian Arcade Joystick + { MAKE_CONTROLLER_ID( 0x2c22, 0x2500 ), k_eControllerType_PS4Controller, NULL }, // Qanba Dragon + { MAKE_CONTROLLER_ID( 0x2c22, 0x2503 ), k_eControllerType_XInputPS4Controller, NULL }, // Qanba Dragon Arcade Joystick + { MAKE_CONTROLLER_ID( 0x3285, 0x0d16 ), k_eControllerType_PS4Controller, NULL }, // NACON Revolution 5 Pro (PS4 mode with dongle) + { MAKE_CONTROLLER_ID( 0x3285, 0x0d17 ), k_eControllerType_PS4Controller, NULL }, // NACON Revolution 5 Pro (PS4 mode wired) { MAKE_CONTROLLER_ID( 0x7545, 0x0104 ), k_eControllerType_PS4Controller, NULL }, // Armor 3 or Level Up Cobra - At least one variant has gyro + { MAKE_CONTROLLER_ID (0x9886, 0x0024 ), k_eControllerType_XInputPS4Controller, NULL }, // Astro C40 in Xbox 360 mode { MAKE_CONTROLLER_ID( 0x9886, 0x0025 ), k_eControllerType_PS4Controller, NULL }, // Astro C40 - { MAKE_CONTROLLER_ID( 0x0e6f, 0x0207 ), k_eControllerType_PS4Controller, NULL }, // Victrix Pro Fightstick w/ Touchpad for PS4 + // Removing the Giotek because there were a bunch of help tickets from users w/ issues including from non-PS4 controller users. This VID/PID is probably used in different FW's +// { MAKE_CONTROLLER_ID( 0x7545, 0x1122 ), k_eControllerType_PS4Controller, NULL }, // Giotek VX4 - trackpad/gyro don't work. Had to not filter on interface info. Light bar is flaky, but works. + + { MAKE_CONTROLLER_ID( 0x054c, 0x0ce6 ), k_eControllerType_PS5Controller, NULL }, // Sony DualSense Controller + { MAKE_CONTROLLER_ID( 0x054c, 0x0df2 ), k_eControllerType_PS5Controller, NULL }, // Sony DualSense Edge Controller + { MAKE_CONTROLLER_ID( 0x054c, 0x0e5f ), k_eControllerType_PS5Controller, NULL }, // Access Controller for PS5 + { MAKE_CONTROLLER_ID( 0x0e6f, 0x0209 ), k_eControllerType_PS5Controller, NULL }, // Victrix Pro FS PS4/PS5 (PS5 mode) + { MAKE_CONTROLLER_ID( 0x0f0d, 0x0163 ), k_eControllerType_PS5Controller, NULL }, // HORI Fighting Commander OCTA + { MAKE_CONTROLLER_ID( 0x0f0d, 0x0184 ), k_eControllerType_PS5Controller, NULL }, // Hori Fighting Stick α + { MAKE_CONTROLLER_ID( 0x1532, 0x100b ), k_eControllerType_PS5Controller, NULL }, // Razer Wolverine V2 Pro (Wired) + { MAKE_CONTROLLER_ID( 0x1532, 0x100c ), k_eControllerType_PS5Controller, NULL }, // Razer Wolverine V2 Pro (Wireless) + { MAKE_CONTROLLER_ID( 0x1532, 0x1012 ), k_eControllerType_PS5Controller, NULL }, // Razer Kitsune + { MAKE_CONTROLLER_ID( 0x3285, 0x0d18 ), k_eControllerType_PS5Controller, NULL }, // NACON Revolution 5 Pro (PS5 mode with dongle) + { MAKE_CONTROLLER_ID( 0x3285, 0x0d19 ), k_eControllerType_PS5Controller, NULL }, // NACON Revolution 5 Pro (PS5 mode wired) + { MAKE_CONTROLLER_ID( 0x358a, 0x0104 ), k_eControllerType_PS5Controller, NULL }, // Backbone One PlayStation Edition for iOS { MAKE_CONTROLLER_ID( 0x0079, 0x0006 ), k_eControllerType_UnknownNonSteamController, NULL }, // DragonRise Generic USB PCB, sometimes configured as a PC Twin Shock Controller - looks like a DS3 but the face buttons are 1-4 instead of symbols { MAKE_CONTROLLER_ID( 0x0079, 0x18d4 ), k_eControllerType_XBox360Controller, NULL }, // GPD Win 2 X-Box Controller + { MAKE_CONTROLLER_ID( 0x03eb, 0xff02 ), k_eControllerType_XBox360Controller, NULL }, // Wooting Two { MAKE_CONTROLLER_ID( 0x044f, 0xb326 ), k_eControllerType_XBox360Controller, NULL }, // Thrustmaster Gamepad GP XID { MAKE_CONTROLLER_ID( 0x045e, 0x028e ), k_eControllerType_XBox360Controller, "Xbox 360 Controller" }, // Microsoft X-Box 360 pad { MAKE_CONTROLLER_ID( 0x045e, 0x028f ), k_eControllerType_XBox360Controller, "Xbox 360 Controller" }, // Microsoft X-Box 360 pad v2 { MAKE_CONTROLLER_ID( 0x045e, 0x0291 ), k_eControllerType_XBox360Controller, "Xbox 360 Wireless Controller" }, // Xbox 360 Wireless Receiver (XBOX) { MAKE_CONTROLLER_ID( 0x045e, 0x02a0 ), k_eControllerType_XBox360Controller, NULL }, // Microsoft X-Box 360 Big Button IR - { MAKE_CONTROLLER_ID( 0x045e, 0x02a1 ), k_eControllerType_XBox360Controller, NULL }, // Microsoft X-Box 360 pad + { MAKE_CONTROLLER_ID( 0x045e, 0x02a1 ), k_eControllerType_XBox360Controller, "Xbox 360 Wireless Controller" }, // Xbox 360 Wireless Controller with XUSB driver on Windows { MAKE_CONTROLLER_ID( 0x045e, 0x02a9 ), k_eControllerType_XBox360Controller, "Xbox 360 Wireless Controller" }, // Xbox 360 Wireless Receiver (third party knockoff) { MAKE_CONTROLLER_ID( 0x045e, 0x0719 ), k_eControllerType_XBox360Controller, "Xbox 360 Wireless Controller" }, // Xbox 360 Wireless Receiver { MAKE_CONTROLLER_ID( 0x046d, 0xc21d ), k_eControllerType_XBox360Controller, NULL }, // Logitech Gamepad F310 @@ -180,7 +180,8 @@ static const ControllerDescription_t arrControllers[] = { { MAKE_CONTROLLER_ID( 0x046d, 0xc21f ), k_eControllerType_XBox360Controller, NULL }, // Logitech Gamepad F710 { MAKE_CONTROLLER_ID( 0x046d, 0xc242 ), k_eControllerType_XBox360Controller, NULL }, // Logitech Chillstream Controller { MAKE_CONTROLLER_ID( 0x056e, 0x2004 ), k_eControllerType_XBox360Controller, NULL }, // Elecom JC-U3613M - { MAKE_CONTROLLER_ID( 0x06a3, 0xf51a ), k_eControllerType_XBox360Controller, NULL }, // Saitek P3600 +// This isn't actually an Xbox 360 controller, it just looks like one +// { MAKE_CONTROLLER_ID( 0x06a3, 0xf51a ), k_eControllerType_XBox360Controller, NULL }, // Saitek P3600 { MAKE_CONTROLLER_ID( 0x0738, 0x4716 ), k_eControllerType_XBox360Controller, NULL }, // Mad Catz Wired Xbox 360 Controller { MAKE_CONTROLLER_ID( 0x0738, 0x4718 ), k_eControllerType_XBox360Controller, NULL }, // Mad Catz Street Fighter IV FightStick SE { MAKE_CONTROLLER_ID( 0x0738, 0x4726 ), k_eControllerType_XBox360Controller, NULL }, // Mad Catz Xbox 360 Controller @@ -221,6 +222,7 @@ static const ControllerDescription_t arrControllers[] = { { MAKE_CONTROLLER_ID( 0x0f0d, 0x001b ), k_eControllerType_XBox360Controller, NULL }, // Hori Real Arcade Pro VX { MAKE_CONTROLLER_ID( 0x0f0d, 0x008c ), k_eControllerType_XBox360Controller, NULL }, // Hori Real Arcade Pro 4 { MAKE_CONTROLLER_ID( 0x0f0d, 0x00db ), k_eControllerType_XBox360Controller, "HORI Slime Controller" }, // Hori Dragon Quest Slime Controller + { MAKE_CONTROLLER_ID( 0x0f0d, 0x011e ), k_eControllerType_XBox360Controller, NULL }, // Hori Fighting Stick α { MAKE_CONTROLLER_ID( 0x1038, 0x1430 ), k_eControllerType_XBox360Controller, "SteelSeries Stratus Duo" }, // SteelSeries Stratus Duo { MAKE_CONTROLLER_ID( 0x1038, 0x1431 ), k_eControllerType_XBox360Controller, "SteelSeries Stratus Duo" }, // SteelSeries Stratus Duo { MAKE_CONTROLLER_ID( 0x1038, 0xb360 ), k_eControllerType_XBox360Controller, NULL }, // SteelSeries Nimbus/Stratus XL @@ -240,6 +242,7 @@ static const ControllerDescription_t arrControllers[] = { { MAKE_CONTROLLER_ID( 0x1689, 0xfd00 ), k_eControllerType_XBox360Controller, NULL }, // Razer Onza Tournament Edition { MAKE_CONTROLLER_ID( 0x1689, 0xfd01 ), k_eControllerType_XBox360Controller, NULL }, // Razer Onza Classic Edition { MAKE_CONTROLLER_ID( 0x1689, 0xfe00 ), k_eControllerType_XBox360Controller, NULL }, // Razer Sabertooth + { MAKE_CONTROLLER_ID( 0x1949, 0x041a ), k_eControllerType_XBox360Controller, "Amazon Luna Controller" }, // Amazon Luna Controller { MAKE_CONTROLLER_ID( 0x1bad, 0x0002 ), k_eControllerType_XBox360Controller, NULL }, // Harmonix Rock Band Guitar { MAKE_CONTROLLER_ID( 0x1bad, 0x0003 ), k_eControllerType_XBox360Controller, NULL }, // Harmonix Rock Band Drumkit { MAKE_CONTROLLER_ID( 0x1bad, 0xf016 ), k_eControllerType_XBox360Controller, NULL }, // Mad Catz Xbox 360 Controller @@ -300,15 +303,25 @@ static const ControllerDescription_t arrControllers[] = { { MAKE_CONTROLLER_ID( 0x24c6, 0xfafd ), k_eControllerType_XBox360Controller, NULL }, // Afterglow Gamepad 3 { MAKE_CONTROLLER_ID( 0x24c6, 0xfafe ), k_eControllerType_XBox360Controller, NULL }, // Rock Candy Gamepad for Xbox 360 + { MAKE_CONTROLLER_ID( 0x03f0, 0x0495 ), k_eControllerType_XBoxOneController, NULL }, // HP HyperX Clutch Gladiate + { MAKE_CONTROLLER_ID( 0x044f, 0xd012 ), k_eControllerType_XBoxOneController, NULL }, // ThrustMaster eSwap PRO Controller Xbox { MAKE_CONTROLLER_ID( 0x045e, 0x02d1 ), k_eControllerType_XBoxOneController, "Xbox One Controller" }, // Microsoft X-Box One pad { MAKE_CONTROLLER_ID( 0x045e, 0x02dd ), k_eControllerType_XBoxOneController, "Xbox One Controller" }, // Microsoft X-Box One pad (Firmware 2015) { MAKE_CONTROLLER_ID( 0x045e, 0x02e0 ), k_eControllerType_XBoxOneController, "Xbox One S Controller" }, // Microsoft X-Box One S pad (Bluetooth) { MAKE_CONTROLLER_ID( 0x045e, 0x02e3 ), k_eControllerType_XBoxOneController, "Xbox One Elite Controller" }, // Microsoft X-Box One Elite pad { MAKE_CONTROLLER_ID( 0x045e, 0x02ea ), k_eControllerType_XBoxOneController, "Xbox One S Controller" }, // Microsoft X-Box One S pad { MAKE_CONTROLLER_ID( 0x045e, 0x02fd ), k_eControllerType_XBoxOneController, "Xbox One S Controller" }, // Microsoft X-Box One S pad (Bluetooth) - { MAKE_CONTROLLER_ID( 0x045e, 0x02ff ), k_eControllerType_XBoxOneController, "Xbox One Elite Controller" }, // Microsoft X-Box One Elite pad + { MAKE_CONTROLLER_ID( 0x045e, 0x02ff ), k_eControllerType_XBoxOneController, "Xbox One Controller" }, // Microsoft X-Box One controller with XBOXGIP driver on Windows { MAKE_CONTROLLER_ID( 0x045e, 0x0b00 ), k_eControllerType_XBoxOneController, "Xbox One Elite 2 Controller" }, // Microsoft X-Box One Elite Series 2 pad +// { MAKE_CONTROLLER_ID( 0x045e, 0x0b02 ), k_eControllerType_XBoxOneController, "Xbox One Elite 2 Controller" }, // The virtual keyboard generated by XboxGip drivers for Xbox One Controllers (see https://github.com/libsdl-org/SDL/pull/5121 for details) { MAKE_CONTROLLER_ID( 0x045e, 0x0b05 ), k_eControllerType_XBoxOneController, "Xbox One Elite 2 Controller" }, // Microsoft X-Box One Elite Series 2 pad (Bluetooth) + { MAKE_CONTROLLER_ID( 0x045e, 0x0b0a ), k_eControllerType_XBoxOneController, "Xbox Adaptive Controller" }, // Microsoft X-Box Adaptive pad + { MAKE_CONTROLLER_ID( 0x045e, 0x0b0c ), k_eControllerType_XBoxOneController, "Xbox Adaptive Controller" }, // Microsoft X-Box Adaptive pad (Bluetooth) + { MAKE_CONTROLLER_ID( 0x045e, 0x0b12 ), k_eControllerType_XBoxOneController, "Xbox Series X Controller" }, // Microsoft X-Box Series X pad + { MAKE_CONTROLLER_ID( 0x045e, 0x0b13 ), k_eControllerType_XBoxOneController, "Xbox Series X Controller" }, // Microsoft X-Box Series X pad (BLE) + { MAKE_CONTROLLER_ID( 0x045e, 0x0b20 ), k_eControllerType_XBoxOneController, "Xbox One S Controller" }, // Microsoft X-Box One S pad (BLE) + { MAKE_CONTROLLER_ID( 0x045e, 0x0b21 ), k_eControllerType_XBoxOneController, "Xbox Adaptive Controller" }, // Microsoft X-Box Adaptive pad (BLE) + { MAKE_CONTROLLER_ID( 0x045e, 0x0b22 ), k_eControllerType_XBoxOneController, "Xbox One Elite 2 Controller" }, // Microsoft X-Box One Elite Series 2 pad (BLE) { MAKE_CONTROLLER_ID( 0x0738, 0x4a01 ), k_eControllerType_XBoxOneController, NULL }, // Mad Catz FightStick TE 2 { MAKE_CONTROLLER_ID( 0x0e6f, 0x0139 ), k_eControllerType_XBoxOneController, "PDP Xbox One Afterglow" }, // PDP Afterglow Wired Controller for Xbox One { MAKE_CONTROLLER_ID( 0x0e6f, 0x013B ), k_eControllerType_XBoxOneController, "PDP Xbox One Face-Off Controller" }, // PDP Face-Off Gamepad for Xbox One @@ -316,7 +329,7 @@ static const ControllerDescription_t arrControllers[] = { { MAKE_CONTROLLER_ID( 0x0e6f, 0x0145 ), k_eControllerType_XBoxOneController, "PDP MK X Fight Pad" }, // PDP MK X Fight Pad for Xbox One { MAKE_CONTROLLER_ID( 0x0e6f, 0x0146 ), k_eControllerType_XBoxOneController, "PDP Xbox One Rock Candy" }, // PDP Rock Candy Wired Controller for Xbox One { MAKE_CONTROLLER_ID( 0x0e6f, 0x015b ), k_eControllerType_XBoxOneController, "PDP Fallout 4 Vault Boy Controller" }, // PDP Fallout 4 Vault Boy Wired Controller for Xbox One - { MAKE_CONTROLLER_ID( 0x0e6f, 0x015c ), k_eControllerType_XBoxOneController, "PDP Xbox One @Play Controller" }, // PDP @Play Wired Controller for Xbox One + { MAKE_CONTROLLER_ID( 0x0e6f, 0x015c ), k_eControllerType_XBoxOneController, "PDP Xbox One @Play Controller" }, // PDP @Play Wired Controller for Xbox One { MAKE_CONTROLLER_ID( 0x0e6f, 0x015d ), k_eControllerType_XBoxOneController, "PDP Mirror's Edge Controller" }, // PDP Mirror's Edge Wired Controller for Xbox One { MAKE_CONTROLLER_ID( 0x0e6f, 0x015f ), k_eControllerType_XBoxOneController, "PDP Metallic Controller" }, // PDP Metallic Wired Controller for Xbox One { MAKE_CONTROLLER_ID( 0x0e6f, 0x0160 ), k_eControllerType_XBoxOneController, "PDP NFL Face-Off Controller" }, // PDP NFL Official Face-Off Wired Controller for Xbox One @@ -374,24 +387,57 @@ static const ControllerDescription_t arrControllers[] = { { MAKE_CONTROLLER_ID( 0x0e6f, 0x02d5 ), k_eControllerType_XBoxOneController, "PDP Xbox One Red Camo" }, // PDP Wired Controller for Xbox One - Red Camo { MAKE_CONTROLLER_ID( 0x0e6f, 0x0346 ), k_eControllerType_XBoxOneController, "PDP Xbox One RC Gamepad" }, // PDP RC Gamepad for Xbox One { MAKE_CONTROLLER_ID( 0x0e6f, 0x0446 ), k_eControllerType_XBoxOneController, "PDP Xbox One RC Gamepad" }, // PDP RC Gamepad for Xbox One + { MAKE_CONTROLLER_ID( 0x0e6f, 0x02da ), k_eControllerType_XBoxOneController, "PDP Xbox Series X Afterglow" }, // PDP Xbox Series X Afterglow + { MAKE_CONTROLLER_ID( 0x0e6f, 0x02d6 ), k_eControllerType_XBoxOneController, "Victrix Gambit Tournament Controller" }, // Victrix Gambit Tournament Controller + { MAKE_CONTROLLER_ID( 0x0e6f, 0x02d9 ), k_eControllerType_XBoxOneController, "PDP Xbox Series X Midnight Blue" }, // PDP Xbox Series X Midnight Blue { MAKE_CONTROLLER_ID( 0x0f0d, 0x0063 ), k_eControllerType_XBoxOneController, NULL }, // Hori Real Arcade Pro Hayabusa (USA) Xbox One { MAKE_CONTROLLER_ID( 0x0f0d, 0x0067 ), k_eControllerType_XBoxOneController, NULL }, // HORIPAD ONE { MAKE_CONTROLLER_ID( 0x0f0d, 0x0078 ), k_eControllerType_XBoxOneController, NULL }, // Hori Real Arcade Pro V Kai Xbox One { MAKE_CONTROLLER_ID( 0x0f0d, 0x00c5 ), k_eControllerType_XBoxOneController, NULL }, // HORI Fighting Commander + { MAKE_CONTROLLER_ID( 0x0f0d, 0x0150 ), k_eControllerType_XBoxOneController, NULL }, // HORI Fighting Commander OCTA for Xbox Series X + { MAKE_CONTROLLER_ID( 0x10f5, 0x7009 ), k_eControllerType_XBoxOneController, NULL }, // Turtle Beach Recon Controller + { MAKE_CONTROLLER_ID( 0x10f5, 0x7013 ), k_eControllerType_XBoxOneController, NULL }, // Turtle Beach REACT-R { MAKE_CONTROLLER_ID( 0x1532, 0x0a00 ), k_eControllerType_XBoxOneController, NULL }, // Razer Atrox Arcade Stick { MAKE_CONTROLLER_ID( 0x1532, 0x0a03 ), k_eControllerType_XBoxOneController, NULL }, // Razer Wildcat + { MAKE_CONTROLLER_ID( 0x1532, 0x0a14 ), k_eControllerType_XBoxOneController, NULL }, // Razer Wolverine Ultimate + { MAKE_CONTROLLER_ID( 0x1532, 0x0a15 ), k_eControllerType_XBoxOneController, NULL }, // Razer Wolverine Tournament Edition + { MAKE_CONTROLLER_ID( 0x20d6, 0x2001 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller - Black Inline + { MAKE_CONTROLLER_ID( 0x20d6, 0x2002 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Gray/White Inline + { MAKE_CONTROLLER_ID( 0x20d6, 0x2003 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Green Inline + { MAKE_CONTROLLER_ID( 0x20d6, 0x2004 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Pink inline + { MAKE_CONTROLLER_ID( 0x20d6, 0x2005 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X Wired Controller Core - Black + { MAKE_CONTROLLER_ID( 0x20d6, 0x2006 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X Wired Controller Core - White + { MAKE_CONTROLLER_ID( 0x20d6, 0x2009 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Red inline + { MAKE_CONTROLLER_ID( 0x20d6, 0x200a ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Blue inline + { MAKE_CONTROLLER_ID( 0x20d6, 0x200b ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Camo Metallic Red + { MAKE_CONTROLLER_ID( 0x20d6, 0x200c ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Camo Metallic Blue + { MAKE_CONTROLLER_ID( 0x20d6, 0x200d ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Seafoam Fade + { MAKE_CONTROLLER_ID( 0x20d6, 0x200e ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Midnight Blue + { MAKE_CONTROLLER_ID( 0x20d6, 0x200f ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Soldier Green + { MAKE_CONTROLLER_ID( 0x20d6, 0x2011 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired - Metallic Ice + { MAKE_CONTROLLER_ID( 0x20d6, 0x2012 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X Cuphead EnWired Controller - Mugman + { MAKE_CONTROLLER_ID( 0x20d6, 0x2015 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller - Blue Hint + { MAKE_CONTROLLER_ID( 0x20d6, 0x2016 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller - Green Hint + { MAKE_CONTROLLER_ID( 0x20d6, 0x2017 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Cntroller - Arctic Camo + { MAKE_CONTROLLER_ID( 0x20d6, 0x2018 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Arc Lightning + { MAKE_CONTROLLER_ID( 0x20d6, 0x2019 ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Royal Purple + { MAKE_CONTROLLER_ID( 0x20d6, 0x201a ), k_eControllerType_XBoxOneController, "PowerA Xbox Series X Controller" }, // PowerA Xbox Series X EnWired Controller Nebula + { MAKE_CONTROLLER_ID( 0x20d6, 0x4001 ), k_eControllerType_XBoxOneController, "PowerA Fusion Pro 2 Controller" }, // PowerA Fusion Pro 2 Wired Controller (Xbox Series X style) + { MAKE_CONTROLLER_ID( 0x20d6, 0x4002 ), k_eControllerType_XBoxOneController, "PowerA Spectra Infinity Controller" }, // PowerA Spectra Infinity Wired Controller (Xbox Series X style) { MAKE_CONTROLLER_ID( 0x24c6, 0x541a ), k_eControllerType_XBoxOneController, NULL }, // PowerA Xbox One Mini Wired Controller { MAKE_CONTROLLER_ID( 0x24c6, 0x542a ), k_eControllerType_XBoxOneController, NULL }, // Xbox ONE spectra - { MAKE_CONTROLLER_ID( 0x24c6, 0x543a ), k_eControllerType_XBoxOneController, "PowerA XBox One Controller" }, // PowerA Xbox ONE liquid metal controller + { MAKE_CONTROLLER_ID( 0x24c6, 0x543a ), k_eControllerType_XBoxOneController, "PowerA Xbox One Controller" }, // PowerA Xbox ONE liquid metal controller { MAKE_CONTROLLER_ID( 0x24c6, 0x551a ), k_eControllerType_XBoxOneController, NULL }, // PowerA FUSION Pro Controller { MAKE_CONTROLLER_ID( 0x24c6, 0x561a ), k_eControllerType_XBoxOneController, NULL }, // PowerA FUSION Controller { MAKE_CONTROLLER_ID( 0x24c6, 0x581a ), k_eControllerType_XBoxOneController, NULL }, // BDA XB1 Classic Controller { MAKE_CONTROLLER_ID( 0x24c6, 0x591a ), k_eControllerType_XBoxOneController, NULL }, // PowerA FUSION Pro Controller { MAKE_CONTROLLER_ID( 0x24c6, 0x592a ), k_eControllerType_XBoxOneController, NULL }, // BDA XB1 Spectra Pro { MAKE_CONTROLLER_ID( 0x24c6, 0x791a ), k_eControllerType_XBoxOneController, NULL }, // PowerA Fusion Fight Pad + { MAKE_CONTROLLER_ID( 0x2dc8, 0x2002 ), k_eControllerType_XBoxOneController, NULL }, // 8BitDo Ultimate Wired Controller for Xbox { MAKE_CONTROLLER_ID( 0x2e24, 0x0652 ), k_eControllerType_XBoxOneController, NULL }, // Hyperkin Duke { MAKE_CONTROLLER_ID( 0x2e24, 0x1618 ), k_eControllerType_XBoxOneController, NULL }, // Hyperkin Duke { MAKE_CONTROLLER_ID( 0x2e24, 0x1688 ), k_eControllerType_XBoxOneController, NULL }, // Hyperkin X91 + { MAKE_CONTROLLER_ID( 0x146b, 0x0611 ), k_eControllerType_XBoxOneController, NULL }, // Xbox Controller Mode for NACON Revolution 3 // These have been added via Minidump for unrecognized Xinput controller assert { MAKE_CONTROLLER_ID( 0x0000, 0x0000 ), k_eControllerType_XBox360Controller, NULL }, // Unknown Controller @@ -403,9 +449,8 @@ static const ControllerDescription_t arrControllers[] = { { MAKE_CONTROLLER_ID( 0x0f0d, 0x00a4 ), k_eControllerType_XBox360Controller, NULL }, // Unknown Controller { MAKE_CONTROLLER_ID( 0x0079, 0x1832 ), k_eControllerType_XBox360Controller, NULL }, // Unknown Controller { MAKE_CONTROLLER_ID( 0x0079, 0x187f ), k_eControllerType_XBox360Controller, NULL }, // Unknown Controller - { MAKE_CONTROLLER_ID( 0x0079, 0x1883 ), k_eControllerType_XBox360Controller, NULL }, // Unknown Controller + { MAKE_CONTROLLER_ID( 0x0079, 0x1883 ), k_eControllerType_XBox360Controller, NULL }, // Unknown Controller { MAKE_CONTROLLER_ID( 0x03eb, 0xff01 ), k_eControllerType_XBox360Controller, NULL }, // Unknown Controller - { MAKE_CONTROLLER_ID( 0x2c22, 0x2303 ), k_eControllerType_XBox360Controller, NULL }, // Unknown Controller { MAKE_CONTROLLER_ID( 0x0c12, 0x0ef8 ), k_eControllerType_XBox360Controller, NULL }, // Homemade fightstick based on brook pcb (with XInput driver??) { MAKE_CONTROLLER_ID( 0x046d, 0x1000 ), k_eControllerType_XBox360Controller, NULL }, // Unknown Controller { MAKE_CONTROLLER_ID( 0x1345, 0x6006 ), k_eControllerType_XBox360Controller, NULL }, // Unknown Controller @@ -428,18 +473,15 @@ static const ControllerDescription_t arrControllers[] = { { MAKE_CONTROLLER_ID( 0x2f24, 0x0050 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller { MAKE_CONTROLLER_ID( 0x2f24, 0x2e ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller - { MAKE_CONTROLLER_ID( 0x9886, 0x24 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller { MAKE_CONTROLLER_ID( 0x2f24, 0x91 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller { MAKE_CONTROLLER_ID( 0x1430, 0x719 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller { MAKE_CONTROLLER_ID( 0xf0d, 0xed ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller - { MAKE_CONTROLLER_ID( 0x3eb, 0xff02 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller { MAKE_CONTROLLER_ID( 0xf0d, 0xc0 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller { MAKE_CONTROLLER_ID( 0xe6f, 0x152 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller { MAKE_CONTROLLER_ID( 0xe6f, 0x2a7 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller { MAKE_CONTROLLER_ID( 0x46d, 0x1007 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller { MAKE_CONTROLLER_ID( 0xe6f, 0x2b8 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller { MAKE_CONTROLLER_ID( 0xe6f, 0x2a8 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller - { MAKE_CONTROLLER_ID( 0x2c22, 0x2503 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller { MAKE_CONTROLLER_ID( 0x79, 0x18a1 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller /* Added from Minidumps 10-9-19 */ @@ -449,11 +491,6 @@ static const ControllerDescription_t arrControllers[] = { { MAKE_CONTROLLER_ID( 0x1430, 0x291 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller { MAKE_CONTROLLER_ID( 0x1430, 0x2a9 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller { MAKE_CONTROLLER_ID( 0x1430, 0x70b ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller - { MAKE_CONTROLLER_ID( 0x146b, 0x604 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller - { MAKE_CONTROLLER_ID( 0x146b, 0x605 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller - { MAKE_CONTROLLER_ID( 0x146b, 0x606 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller - { MAKE_CONTROLLER_ID( 0x146b, 0x609 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller - { MAKE_CONTROLLER_ID( 0x1532, 0xa14 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller { MAKE_CONTROLLER_ID( 0x1bad, 0x28e ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller { MAKE_CONTROLLER_ID( 0x1bad, 0x2a0 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller { MAKE_CONTROLLER_ID( 0x1bad, 0x5500 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller @@ -498,17 +535,20 @@ static const ControllerDescription_t arrControllers[] = { { MAKE_CONTROLLER_ID( 0xf0d, 0xba ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller { MAKE_CONTROLLER_ID( 0xf0d, 0xd8 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller { MAKE_CONTROLLER_ID( 0xfff, 0x2a1 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller + { MAKE_CONTROLLER_ID( 0x45e, 0x867 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller + // Added 12-17-2020 + { MAKE_CONTROLLER_ID( 0x16d0, 0xf3f ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller + { MAKE_CONTROLLER_ID( 0x2f24, 0x8f ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller + { MAKE_CONTROLLER_ID( 0xe6f, 0xf501 ), k_eControllerType_XBoxOneController, NULL }, // Unknown Controller //{ MAKE_CONTROLLER_ID( 0x1949, 0x0402 ), /*android*/, NULL }, // Unknown Controller { MAKE_CONTROLLER_ID( 0x05ac, 0x0001 ), k_eControllerType_AppleController, NULL }, // MFI Extended Gamepad (generic entry for iOS/tvOS) { MAKE_CONTROLLER_ID( 0x05ac, 0x0002 ), k_eControllerType_AppleController, NULL }, // MFI Standard Gamepad (generic entry for iOS/tvOS) - // We currently don't support using a pair of Switch Joy-Con's as a single - // controller and we don't want to support using them individually for the - // time being, so these should be disabled until one of the above is true - // { MAKE_CONTROLLER_ID( 0x057e, 0x2006 ), k_eControllerType_SwitchJoyConLeft, NULL }, // Nintendo Switch Joy-Con (Left) - // { MAKE_CONTROLLER_ID( 0x057e, 0x2007 ), k_eControllerType_SwitchJoyConRight, NULL }, // Nintendo Switch Joy-Con (Right) + { MAKE_CONTROLLER_ID( 0x057e, 0x2006 ), k_eControllerType_SwitchJoyConLeft, NULL }, // Nintendo Switch Joy-Con (Left) + { MAKE_CONTROLLER_ID( 0x057e, 0x2007 ), k_eControllerType_SwitchJoyConRight, NULL }, // Nintendo Switch Joy-Con (Right) + { MAKE_CONTROLLER_ID( 0x057e, 0x2008 ), k_eControllerType_SwitchJoyConPair, NULL }, // Nintendo Switch Joy-Con (Left+Right Combined) // This same controller ID is spoofed by many 3rd-party Switch controllers. // The ones we currently know of are: @@ -517,138 +557,47 @@ static const ControllerDescription_t arrControllers[] = { // * ZhiXu Gamepad Wireless // * Sunwaytek Wireless Motion Controller for Nintendo Switch { MAKE_CONTROLLER_ID( 0x057e, 0x2009 ), k_eControllerType_SwitchProController, NULL }, // Nintendo Switch Pro Controller - + //{ MAKE_CONTROLLER_ID( 0x057e, 0x2017 ), k_eControllerType_SwitchProController, NULL }, // Nintendo Online SNES Controller + //{ MAKE_CONTROLLER_ID( 0x057e, 0x2019 ), k_eControllerType_SwitchProController, NULL }, // Nintendo Online N64 Controller + //{ MAKE_CONTROLLER_ID( 0x057e, 0x201e ), k_eControllerType_SwitchProController, NULL }, // Nintendo Online SEGA Genesis Controller + { MAKE_CONTROLLER_ID( 0x0f0d, 0x00c1 ), k_eControllerType_SwitchInputOnlyController, NULL }, // HORIPAD for Nintendo Switch { MAKE_CONTROLLER_ID( 0x0f0d, 0x0092 ), k_eControllerType_SwitchInputOnlyController, NULL }, // HORI Pokken Tournament DX Pro Pad { MAKE_CONTROLLER_ID( 0x0f0d, 0x00f6 ), k_eControllerType_SwitchProController, NULL }, // HORI Wireless Switch Pad - { MAKE_CONTROLLER_ID( 0x0f0d, 0x00dc ), k_eControllerType_XInputSwitchController, NULL }, // HORI Battle Pad. Is a Switch controller but shows up through XInput on Windows. - { MAKE_CONTROLLER_ID( 0x0e6f, 0x0185 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PDP Wired Fight Pad Pro for Nintendo Switch + // The HORIPAD S, which comes in multiple styles: + // - NSW-108, classic GameCube controller + // - NSW-244, Fighting Commander arcade pad + // - NSW-278, Hori Pad Mini gamepad + // - NSW-326, HORIPAD FPS for Nintendo Switch + // + // The first two, at least, shouldn't have their buttons remapped, and since we + // can't tell which model we're actually using, we won't do any button remapping + // for any of them. + { MAKE_CONTROLLER_ID( 0x0f0d, 0x00dc ), k_eControllerType_XInputSwitchController, NULL }, // HORIPAD S - Looks like a Switch controller but uses the Xbox 360 controller protocol { MAKE_CONTROLLER_ID( 0x0e6f, 0x0180 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PDP Faceoff Wired Pro Controller for Nintendo Switch { MAKE_CONTROLLER_ID( 0x0e6f, 0x0181 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PDP Faceoff Deluxe Wired Pro Controller for Nintendo Switch + { MAKE_CONTROLLER_ID( 0x0e6f, 0x0184 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PDP Faceoff Wired Deluxe+ Audio Controller + { MAKE_CONTROLLER_ID( 0x0e6f, 0x0185 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PDP Wired Fight Pad Pro for Nintendo Switch + { MAKE_CONTROLLER_ID( 0x0e6f, 0x0186 ), k_eControllerType_SwitchProController, NULL }, // PDP Afterglow Wireless Switch Controller - working gyro. USB is for charging only. Many later "Wireless" line devices w/ gyro also use this vid/pid + { MAKE_CONTROLLER_ID( 0x0e6f, 0x0187 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PDP Rockcandy Wired Controller + { MAKE_CONTROLLER_ID( 0x0e6f, 0x0188 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PDP Afterglow Wired Deluxe+ Audio Controller + { MAKE_CONTROLLER_ID( 0x0f0d, 0x00aa ), k_eControllerType_SwitchInputOnlyController, NULL }, // HORI Real Arcade Pro V Hayabusa in Switch Mode { MAKE_CONTROLLER_ID( 0x20d6, 0xa711 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PowerA Wired Controller Plus/PowerA Wired Controller Nintendo GameCube Style - { MAKE_CONTROLLER_ID( 0x20d6, 0xa712 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PowerA - Fusion Fight Pad - { MAKE_CONTROLLER_ID( 0x20d6, 0xa713 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PowerA - Super Mario Controller + { MAKE_CONTROLLER_ID( 0x20d6, 0xa712 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PowerA Nintendo Switch Fusion Fight Pad + { MAKE_CONTROLLER_ID( 0x20d6, 0xa713 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PowerA Super Mario Controller + { MAKE_CONTROLLER_ID( 0x20d6, 0xa714 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PowerA Nintendo Switch Spectra Controller + { MAKE_CONTROLLER_ID( 0x20d6, 0xa715 ), k_eControllerType_SwitchInputOnlyController, NULL }, // Power A Fusion Wireless Arcade Stick (USB Mode) Over BT is shows up as 057e 2009 + { MAKE_CONTROLLER_ID( 0x20d6, 0xa716 ), k_eControllerType_SwitchInputOnlyController, NULL }, // PowerA Nintendo Switch Fusion Pro Controller - USB requires toggling switch on back of device - // Valve products - don't add to public list + // Valve products { MAKE_CONTROLLER_ID( 0x0000, 0x11fb ), k_eControllerType_MobileTouch, NULL }, // Streaming mobile touch virtual controls { MAKE_CONTROLLER_ID( 0x28de, 0x1101 ), k_eControllerType_SteamController, NULL }, // Valve Legacy Steam Controller (CHELL) { MAKE_CONTROLLER_ID( 0x28de, 0x1102 ), k_eControllerType_SteamController, NULL }, // Valve wired Steam Controller (D0G) { MAKE_CONTROLLER_ID( 0x28de, 0x1105 ), k_eControllerType_SteamController, NULL }, // Valve Bluetooth Steam Controller (D0G) { MAKE_CONTROLLER_ID( 0x28de, 0x1106 ), k_eControllerType_SteamController, NULL }, // Valve Bluetooth Steam Controller (D0G) + { MAKE_CONTROLLER_ID( 0x28de, 0x11ff ), k_eControllerType_UnknownNonSteamController, NULL }, // Steam Virtual Gamepad { MAKE_CONTROLLER_ID( 0x28de, 0x1142 ), k_eControllerType_SteamController, NULL }, // Valve wireless Steam Controller { MAKE_CONTROLLER_ID( 0x28de, 0x1201 ), k_eControllerType_SteamControllerV2, NULL }, // Valve wired Steam Controller (HEADCRAB) { MAKE_CONTROLLER_ID( 0x28de, 0x1202 ), k_eControllerType_SteamControllerV2, NULL }, // Valve Bluetooth Steam Controller (HEADCRAB) + { MAKE_CONTROLLER_ID( 0x28de, 0x1205 ), k_eControllerType_SteamDeck, NULL }, // Valve Steam Deck Builtin Controller }; - -static SDL_INLINE const char *GetControllerTypeOverride( int nVID, int nPID ) -{ - const char *hint = SDL_GetHint(SDL_HINT_GAMECONTROLLERTYPE); - if (hint) { - char key[32]; - const char *spot = NULL; - - SDL_snprintf(key, sizeof(key), "0x%.4x/0x%.4x=", nVID, nPID); - spot = SDL_strstr(hint, key); - if (!spot) { - SDL_snprintf(key, sizeof(key), "0x%.4X/0x%.4X=", nVID, nPID); - spot = SDL_strstr(hint, key); - } - if (spot) { - spot += SDL_strlen(key); - if (SDL_strncmp(spot, "k_eControllerType_", 18) == 0) { - spot += 18; - } - return spot; - } - } - return NULL; -} - -static SDL_INLINE EControllerType GuessControllerType( int nVID, int nPID ) -{ -#if 0//def _DEBUG - // Verify that there are no duplicates in the controller list - // If the list were sorted, we could do this much more efficiently, as well as improve lookup speed. - static bool s_bCheckedForDuplicates; - if ( !s_bCheckedForDuplicates ) - { - s_bCheckedForDuplicates = true; - - for ( int i = 0; i < sizeof( arrControllers ) / sizeof( arrControllers[ 0 ] ); ++i ) - { - for ( int j = i + 1; j < sizeof( arrControllers ) / sizeof( arrControllers[ 0 ] ); ++j ) - { - if ( arrControllers[ i ].m_unDeviceID == arrControllers[ j ].m_unDeviceID ) - { - Log( "Duplicate controller entry found for VID 0x%.4x PID 0x%.4x\n", ( arrControllers[ i ].m_unDeviceID >> 16 ), arrControllers[ i ].m_unDeviceID & 0xFFFF ); - } - } - } - } -#endif // _DEBUG - - unsigned int unDeviceID = MAKE_CONTROLLER_ID( nVID, nPID ); - int iIndex; - - const char *pszOverride = GetControllerTypeOverride( nVID, nPID ); - if ( pszOverride ) - { - if ( SDL_strncasecmp( pszOverride, "Xbox360", 7 ) == 0 ) - { - return k_eControllerType_XBox360Controller; - } - if ( SDL_strncasecmp( pszOverride, "XboxOne", 7 ) == 0 ) - { - return k_eControllerType_XBoxOneController; - } - if ( SDL_strncasecmp( pszOverride, "PS3", 3 ) == 0 ) - { - return k_eControllerType_PS3Controller; - } - if ( SDL_strncasecmp( pszOverride, "PS4", 3 ) == 0 ) - { - return k_eControllerType_PS4Controller; - } - if ( SDL_strncasecmp( pszOverride, "SwitchPro", 9 ) == 0 ) - { - return k_eControllerType_SwitchProController; - } - if ( SDL_strncasecmp( pszOverride, "Steam", 5 ) == 0 ) - { - return k_eControllerType_SteamController; - } - return k_eControllerType_UnknownNonSteamController; - } - - for ( iIndex = 0; iIndex < sizeof( arrControllers ) / sizeof( arrControllers[0] ); ++iIndex ) - { - if ( unDeviceID == arrControllers[ iIndex ].m_unDeviceID ) - { - return arrControllers[ iIndex ].m_eControllerType; - } - } - - return k_eControllerType_UnknownNonSteamController; - -} - -static SDL_INLINE const char *GuessControllerName( int nVID, int nPID ) -{ - unsigned int unDeviceID = MAKE_CONTROLLER_ID( nVID, nPID ); - int iIndex; - for ( iIndex = 0; iIndex < sizeof( arrControllers ) / sizeof( arrControllers[0] ); ++iIndex ) - { - if ( unDeviceID == arrControllers[ iIndex ].m_unDeviceID ) - { - return arrControllers[ iIndex ].m_pszName; - } - } - - return NULL; - -} - -#undef MAKE_CONTROLLER_ID - -#endif // CONSTANTS_H - diff --git a/SDL2-2.30.5/src/joystick/controller_type.c b/SDL2-2.30.5/src/joystick/controller_type.c new file mode 100644 index 0000000..cda3586 --- /dev/null +++ b/SDL2-2.30.5/src/joystick/controller_type.c @@ -0,0 +1,144 @@ +/* + Copyright (C) Valve Corporation + + 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_hints.h" +#include "SDL_gamecontroller.h" + +#include "controller_type.h" +#include "controller_list.h" + + +static const char *GetControllerTypeOverride( int nVID, int nPID ) +{ + const char *hint = SDL_GetHint(SDL_HINT_GAMECONTROLLERTYPE); + if (hint) { + char key[32]; + const char *spot = NULL; + + SDL_snprintf(key, sizeof(key), "0x%.4x/0x%.4x=", nVID, nPID); + spot = SDL_strstr(hint, key); + if (!spot) { + SDL_snprintf(key, sizeof(key), "0x%.4X/0x%.4X=", nVID, nPID); + spot = SDL_strstr(hint, key); + } + if (spot) { + spot += SDL_strlen(key); + if (SDL_strncmp(spot, "k_eControllerType_", 18) == 0) { + spot += 18; + } + return spot; + } + } + return NULL; +} + + +EControllerType GuessControllerType( int nVID, int nPID ) +{ +#if 0//def _DEBUG + // Verify that there are no duplicates in the controller list + // If the list were sorted, we could do this much more efficiently, as well as improve lookup speed. + static bool s_bCheckedForDuplicates; + if ( !s_bCheckedForDuplicates ) + { + s_bCheckedForDuplicates = true; + int i, j; + for ( i = 0; i < sizeof( arrControllers ) / sizeof( arrControllers[ 0 ] ); ++i ) + { + for ( j = i + 1; j < sizeof( arrControllers ) / sizeof( arrControllers[ 0 ] ); ++j ) + { + if ( arrControllers[ i ].m_unDeviceID == arrControllers[ j ].m_unDeviceID ) + { + Log( "Duplicate controller entry found for VID 0x%.4x PID 0x%.4x\n", ( arrControllers[ i ].m_unDeviceID >> 16 ), arrControllers[ i ].m_unDeviceID & 0xFFFF ); + } + } + } + } +#endif // _DEBUG + + unsigned int unDeviceID = MAKE_CONTROLLER_ID( nVID, nPID ); + int iIndex; + + const char *pszOverride = GetControllerTypeOverride( nVID, nPID ); + if ( pszOverride ) + { + if ( SDL_strncasecmp( pszOverride, "Xbox360", 7 ) == 0 ) + { + return k_eControllerType_XBox360Controller; + } + if ( SDL_strncasecmp( pszOverride, "XboxOne", 7 ) == 0 ) + { + return k_eControllerType_XBoxOneController; + } + if ( SDL_strncasecmp( pszOverride, "PS3", 3 ) == 0 ) + { + return k_eControllerType_PS3Controller; + } + if ( SDL_strncasecmp( pszOverride, "PS4", 3 ) == 0 ) + { + return k_eControllerType_PS4Controller; + } + if ( SDL_strncasecmp( pszOverride, "PS5", 3 ) == 0 ) + { + return k_eControllerType_PS5Controller; + } + if ( SDL_strncasecmp( pszOverride, "SwitchPro", 9 ) == 0 ) + { + return k_eControllerType_SwitchProController; + } + if ( SDL_strncasecmp( pszOverride, "Steam", 5 ) == 0 ) + { + return k_eControllerType_SteamController; + } + return k_eControllerType_UnknownNonSteamController; + } + + for ( iIndex = 0; iIndex < sizeof( arrControllers ) / sizeof( arrControllers[0] ); ++iIndex ) + { + if ( unDeviceID == arrControllers[ iIndex ].m_unDeviceID ) + { + return arrControllers[ iIndex ].m_eControllerType; + } + } + + return k_eControllerType_UnknownNonSteamController; + +} + +const char *GuessControllerName( int nVID, int nPID ) +{ + unsigned int unDeviceID = MAKE_CONTROLLER_ID( nVID, nPID ); + int iIndex; + for ( iIndex = 0; iIndex < sizeof( arrControllers ) / sizeof( arrControllers[0] ); ++iIndex ) + { + if ( unDeviceID == arrControllers[ iIndex ].m_unDeviceID ) + { + return arrControllers[ iIndex ].m_pszName; + } + } + + return NULL; + +} + +#undef MAKE_CONTROLLER_ID + +/* vi: set ts=4 sw=4 noexpandtab: */ diff --git a/SDL2-2.30.5/src/joystick/controller_type.h b/SDL2-2.30.5/src/joystick/controller_type.h new file mode 100644 index 0000000..ead45f1 --- /dev/null +++ b/SDL2-2.30.5/src/joystick/controller_type.h @@ -0,0 +1,80 @@ +/* + Copyright (C) Valve Corporation + + 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. +*/ + +#ifndef CONTROLLER_TYPE_H +#define CONTROLLER_TYPE_H +#ifdef _WIN32 +#pragma once +#endif + +//----------------------------------------------------------------------------- +// Purpose: Steam Controller models +// WARNING: DO NOT RENUMBER EXISTING VALUES - STORED IN A DATABASE +//----------------------------------------------------------------------------- +typedef enum +{ + k_eControllerType_None = -1, + k_eControllerType_Unknown = 0, + + // Steam Controllers + k_eControllerType_UnknownSteamController = 1, + k_eControllerType_SteamController = 2, + k_eControllerType_SteamControllerV2 = 3, + k_eControllerType_SteamDeck = 4, + + // Other Controllers + k_eControllerType_UnknownNonSteamController = 30, + k_eControllerType_XBox360Controller = 31, + k_eControllerType_XBoxOneController = 32, + k_eControllerType_PS3Controller = 33, + k_eControllerType_PS4Controller = 34, + k_eControllerType_WiiController = 35, + k_eControllerType_AppleController = 36, + k_eControllerType_AndroidController = 37, + k_eControllerType_SwitchProController = 38, + k_eControllerType_SwitchJoyConLeft = 39, + k_eControllerType_SwitchJoyConRight = 40, + k_eControllerType_SwitchJoyConPair = 41, + k_eControllerType_SwitchInputOnlyController = 42, + k_eControllerType_MobileTouch = 43, + k_eControllerType_XInputSwitchController = 44, // Client-side only, used to mark Nintendo Switch style controllers as using XInput instead of the Nintendo Switch protocol + k_eControllerType_PS5Controller = 45, + k_eControllerType_XInputPS4Controller = 46, // Client-side only, used to mark DualShock 4 style controllers using XInput instead of the DualShock 4 controller protocol + k_eControllerType_LastController, // Don't add game controllers below this enumeration - this enumeration can change value + + // Keyboards and Mice + k_eControllertype_GenericKeyboard = 400, + k_eControllertype_GenericMouse = 800, +} EControllerType; + +typedef struct +{ + unsigned int m_unDeviceID; + EControllerType m_eControllerType; + const char *m_pszName; +} ControllerDescription_t; + + +extern EControllerType GuessControllerType( int nVID, int nPID ); +extern const char *GuessControllerName( int nVID, int nPID ); + +#endif // CONTROLLER_TYPE_H + +/* vi: set ts=4 sw=4 noexpandtab: */ diff --git a/SDL2-2.0.12/src/joystick/darwin/SDL_sysjoystick.c b/SDL2-2.30.5/src/joystick/darwin/SDL_iokitjoystick.c similarity index 62% rename from SDL2-2.0.12/src/joystick/darwin/SDL_sysjoystick.c rename to SDL2-2.30.5/src/joystick/darwin/SDL_iokitjoystick.c index 461a85f..493f816 100644 --- a/SDL2-2.0.12/src/joystick/darwin/SDL_sysjoystick.c +++ b/SDL2-2.30.5/src/joystick/darwin/SDL_iokitjoystick.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,14 +26,13 @@ #include "SDL_joystick.h" #include "../SDL_sysjoystick.h" #include "../SDL_joystick_c.h" -#include "SDL_sysjoystick_c.h" +#include "SDL_iokitjoystick_c.h" #include "../hidapi/SDL_hidapijoystick_c.h" -#include "../../haptic/darwin/SDL_syshaptic_c.h" /* For haptic hot plugging */ - +#include "../../haptic/darwin/SDL_syshaptic_c.h" /* For haptic hot plugging */ #define SDL_JOYSTICK_RUNLOOP_MODE CFSTR("SDLJoystick") -#define CONVERT_MAGNITUDE(x) (((x)*10000) / 0x7FFF) +#define CONVERT_MAGNITUDE(x) (((x)*10000) / 0x7FFF) /* The base object of the HID Manager API */ static IOHIDManagerRef hidman = NULL; @@ -101,8 +100,9 @@ static recDevice *GetDeviceForIndex(int device_index) recDevice *device = gpDeviceList; while (device) { if (!device->removed) { - if (device_index == 0) + if (device_index == 0) { break; + } --device_index; } @@ -111,8 +111,7 @@ static recDevice *GetDeviceForIndex(int device_index) return device; } -static void -FreeElementList(recElement *pElement) +static void FreeElementList(recElement *pElement) { while (pElement) { recElement *pElementNext = pElement->pNext; @@ -121,28 +120,47 @@ FreeElementList(recElement *pElement) } } -static recDevice * -FreeDevice(recDevice *removeDevice) +static recDevice *FreeDevice(recDevice *removeDevice) { recDevice *pDeviceNext = NULL; if (removeDevice) { if (removeDevice->deviceRef) { - IOHIDDeviceUnscheduleFromRunLoop(removeDevice->deviceRef, CFRunLoopGetCurrent(), SDL_JOYSTICK_RUNLOOP_MODE); + if (removeDevice->runLoopAttached) { + /* Calling IOHIDDeviceUnscheduleFromRunLoop without a prior, + * paired call to IOHIDDeviceScheduleWithRunLoop can lead + * to crashes in MacOS 10.14.x and earlier. This doesn't + * appear to be a problem in MacOS 10.15.x, but we'll + * do it anyways. (Part-of fix for Bug 5034) + */ + IOHIDDeviceUnscheduleFromRunLoop(removeDevice->deviceRef, CFRunLoopGetCurrent(), SDL_JOYSTICK_RUNLOOP_MODE); + } CFRelease(removeDevice->deviceRef); removeDevice->deviceRef = NULL; } + /* clear out any reference to removeDevice from an associated, + * live instance of SDL_Joystick (Part-of fix for Bug 5034) + */ + SDL_LockJoysticks(); + if (removeDevice->joystick) { + removeDevice->joystick->hwdata = NULL; + } + SDL_UnlockJoysticks(); + /* save next device prior to disposing of this device */ pDeviceNext = removeDevice->pNext; - if ( gpDeviceList == removeDevice ) { + if (gpDeviceList == removeDevice) { gpDeviceList = pDeviceNext; } else if (gpDeviceList) { - recDevice *device = gpDeviceList; - while (device->pNext != removeDevice) { - device = device->pNext; + recDevice *device; + + for (device = gpDeviceList; device; device = device->pNext) { + if (device->pNext == removeDevice) { + device->pNext = pDeviceNext; + break; + } } - device->pNext = pDeviceNext; } removeDevice->pNext = NULL; @@ -156,8 +174,7 @@ FreeDevice(recDevice *removeDevice) return pDeviceNext; } -static SDL_bool -GetHIDElementState(recDevice *pDevice, recElement *pElement, SInt32 *pValue) +static SDL_bool GetHIDElementState(recDevice *pDevice, recElement *pElement, SInt32 *pValue) { SInt32 value = 0; int returnValue = SDL_FALSE; @@ -165,7 +182,7 @@ GetHIDElementState(recDevice *pDevice, recElement *pElement, SInt32 *pValue) if (pDevice && pDevice->deviceRef && pElement) { IOHIDValueRef valueRef; if (IOHIDDeviceGetValue(pDevice->deviceRef, pElement->elementRef, &valueRef) == kIOReturnSuccess) { - value = (SInt32) IOHIDValueGetIntegerValue(valueRef); + value = (SInt32)IOHIDValueGetIntegerValue(valueRef); /* record min and max for auto calibration */ if (value < pElement->minReport) { @@ -182,30 +199,25 @@ GetHIDElementState(recDevice *pDevice, recElement *pElement, SInt32 *pValue) return returnValue; } -static SDL_bool -GetHIDScaledCalibratedState(recDevice * pDevice, recElement * pElement, SInt32 min, SInt32 max, SInt32 *pValue) +static SDL_bool GetHIDScaledCalibratedState(recDevice *pDevice, recElement *pElement, SInt32 min, SInt32 max, SInt32 *pValue) { const float deviceScale = max - min; const float readScale = pElement->maxReport - pElement->minReport; int returnValue = SDL_FALSE; - if (GetHIDElementState(pDevice, pElement, pValue)) - { + if (GetHIDElementState(pDevice, pElement, pValue)) { if (readScale == 0) { - returnValue = SDL_TRUE; /* no scaling at all */ - } - else - { + returnValue = SDL_TRUE; /* no scaling at all */ + } else { *pValue = ((*pValue - pElement->minReport) * deviceScale / readScale) + min; returnValue = SDL_TRUE; } - } + } return returnValue; } -static void -JoystickDeviceWasRemovedCallback(void *ctx, IOReturn result, void *sender) +static void JoystickDeviceWasRemovedCallback(void *ctx, IOReturn result, void *sender) { - recDevice *device = (recDevice *) ctx; + recDevice *device = (recDevice *)ctx; device->removed = SDL_TRUE; if (device->deviceRef) { // deviceRef was invalidated due to the remove @@ -225,26 +237,24 @@ JoystickDeviceWasRemovedCallback(void *ctx, IOReturn result, void *sender) device->ffdevice = NULL; device->ff_initialized = SDL_FALSE; } -#if SDL_HAPTIC_IOKIT +#ifdef SDL_HAPTIC_IOKIT MacHaptic_MaybeRemoveDevice(device->ffservice); #endif SDL_PrivateJoystickRemoved(device->instance_id); } - static void AddHIDElement(const void *value, void *parameter); /* Call AddHIDElement() on all elements in an array of IOHIDElementRefs */ -static void -AddHIDElements(CFArrayRef array, recDevice *pDevice) +static void AddHIDElements(CFArrayRef array, recDevice *pDevice) { const CFRange range = { 0, CFArrayGetCount(array) }; CFArrayApplyFunction(array, range, AddHIDElement, pDevice); } -static SDL_bool -ElementAlreadyAdded(const IOHIDElementCookie cookie, const recElement *listitem) { +static SDL_bool ElementAlreadyAdded(const IOHIDElementCookie cookie, const recElement *listitem) +{ while (listitem) { if (listitem->cookie == cookie) { return SDL_TRUE; @@ -255,11 +265,10 @@ ElementAlreadyAdded(const IOHIDElementCookie cookie, const recElement *listitem) } /* See if we care about this HID element, and if so, note it in our recDevice. */ -static void -AddHIDElement(const void *value, void *parameter) +static void AddHIDElement(const void *value, void *parameter) { - recDevice *pDevice = (recDevice *) parameter; - IOHIDElementRef refElement = (IOHIDElementRef) value; + recDevice *pDevice = (recDevice *)parameter; + IOHIDElementRef refElement = (IOHIDElementRef)value; const CFTypeID elementTypeID = refElement ? CFGetTypeID(refElement) : 0; if (refElement && (elementTypeID == IOHIDElementGetTypeID())) { @@ -271,107 +280,107 @@ AddHIDElement(const void *value, void *parameter) /* look at types of interest */ switch (IOHIDElementGetType(refElement)) { - case kIOHIDElementTypeInput_Misc: - case kIOHIDElementTypeInput_Button: - case kIOHIDElementTypeInput_Axis: { - switch (usagePage) { /* only interested in kHIDPage_GenericDesktop and kHIDPage_Button */ - case kHIDPage_GenericDesktop: - switch (usage) { - case kHIDUsage_GD_X: - case kHIDUsage_GD_Y: - case kHIDUsage_GD_Z: - case kHIDUsage_GD_Rx: - case kHIDUsage_GD_Ry: - case kHIDUsage_GD_Rz: - case kHIDUsage_GD_Slider: - case kHIDUsage_GD_Dial: - case kHIDUsage_GD_Wheel: - if (!ElementAlreadyAdded(cookie, pDevice->firstAxis)) { - element = (recElement *) SDL_calloc(1, sizeof (recElement)); - if (element) { - pDevice->axes++; - headElement = &(pDevice->firstAxis); - } - } - break; - - case kHIDUsage_GD_Hatswitch: - if (!ElementAlreadyAdded(cookie, pDevice->firstHat)) { - element = (recElement *) SDL_calloc(1, sizeof (recElement)); - if (element) { - pDevice->hats++; - headElement = &(pDevice->firstHat); - } - } - break; - case kHIDUsage_GD_DPadUp: - case kHIDUsage_GD_DPadDown: - case kHIDUsage_GD_DPadRight: - case kHIDUsage_GD_DPadLeft: - case kHIDUsage_GD_Start: - case kHIDUsage_GD_Select: - case kHIDUsage_GD_SystemMainMenu: - if (!ElementAlreadyAdded(cookie, pDevice->firstButton)) { - element = (recElement *) SDL_calloc(1, sizeof (recElement)); - if (element) { - pDevice->buttons++; - headElement = &(pDevice->firstButton); - } - } - break; + case kIOHIDElementTypeInput_Misc: + case kIOHIDElementTypeInput_Button: + case kIOHIDElementTypeInput_Axis: + { + switch (usagePage) { /* only interested in kHIDPage_GenericDesktop and kHIDPage_Button */ + case kHIDPage_GenericDesktop: + switch (usage) { + case kHIDUsage_GD_X: + case kHIDUsage_GD_Y: + case kHIDUsage_GD_Z: + case kHIDUsage_GD_Rx: + case kHIDUsage_GD_Ry: + case kHIDUsage_GD_Rz: + case kHIDUsage_GD_Slider: + case kHIDUsage_GD_Dial: + case kHIDUsage_GD_Wheel: + if (!ElementAlreadyAdded(cookie, pDevice->firstAxis)) { + element = (recElement *)SDL_calloc(1, sizeof(recElement)); + if (element) { + pDevice->axes++; + headElement = &(pDevice->firstAxis); } - break; + } + break; - case kHIDPage_Simulation: - switch (usage) { - case kHIDUsage_Sim_Rudder: - case kHIDUsage_Sim_Throttle: - case kHIDUsage_Sim_Accelerator: - case kHIDUsage_Sim_Brake: - if (!ElementAlreadyAdded(cookie, pDevice->firstAxis)) { - element = (recElement *) SDL_calloc(1, sizeof (recElement)); - if (element) { - pDevice->axes++; - headElement = &(pDevice->firstAxis); - } - } - break; - - default: - break; + case kHIDUsage_GD_Hatswitch: + if (!ElementAlreadyAdded(cookie, pDevice->firstHat)) { + element = (recElement *)SDL_calloc(1, sizeof(recElement)); + if (element) { + pDevice->hats++; + headElement = &(pDevice->firstHat); } - break; - - case kHIDPage_Button: - case kHIDPage_Consumer: /* e.g. 'pause' button on Steelseries MFi gamepads. */ - if (!ElementAlreadyAdded(cookie, pDevice->firstButton)) { - element = (recElement *) SDL_calloc(1, sizeof (recElement)); - if (element) { - pDevice->buttons++; - headElement = &(pDevice->firstButton); - } + } + break; + case kHIDUsage_GD_DPadUp: + case kHIDUsage_GD_DPadDown: + case kHIDUsage_GD_DPadRight: + case kHIDUsage_GD_DPadLeft: + case kHIDUsage_GD_Start: + case kHIDUsage_GD_Select: + case kHIDUsage_GD_SystemMainMenu: + if (!ElementAlreadyAdded(cookie, pDevice->firstButton)) { + element = (recElement *)SDL_calloc(1, sizeof(recElement)); + if (element) { + pDevice->buttons++; + headElement = &(pDevice->firstButton); } - break; - - default: - break; + } + break; } - } - break; + break; - case kIOHIDElementTypeCollection: { - CFArrayRef array = IOHIDElementGetChildren(refElement); - if (array) { - AddHIDElements(array, pDevice); + case kHIDPage_Simulation: + switch (usage) { + case kHIDUsage_Sim_Rudder: + case kHIDUsage_Sim_Throttle: + case kHIDUsage_Sim_Accelerator: + case kHIDUsage_Sim_Brake: + if (!ElementAlreadyAdded(cookie, pDevice->firstAxis)) { + element = (recElement *)SDL_calloc(1, sizeof(recElement)); + if (element) { + pDevice->axes++; + headElement = &(pDevice->firstAxis); + } + } + break; + + default: + break; } - } - break; + break; + + case kHIDPage_Button: + case kHIDPage_Consumer: /* e.g. 'pause' button on Steelseries MFi gamepads. */ + if (!ElementAlreadyAdded(cookie, pDevice->firstButton)) { + element = (recElement *)SDL_calloc(1, sizeof(recElement)); + if (element) { + pDevice->buttons++; + headElement = &(pDevice->firstButton); + } + } + break; default: break; + } + } break; + + case kIOHIDElementTypeCollection: + { + CFArrayRef array = IOHIDElementGetChildren(refElement); + if (array) { + AddHIDElements(array, pDevice); + } + } break; + + default: + break; } - if (element && headElement) { /* add to list */ + if (element && headElement) { /* add to list */ recElement *elementPrevious = NULL; recElement *elementCurrent = *headElement; while (elementCurrent && usage >= elementCurrent->usage) { @@ -389,8 +398,8 @@ AddHIDElement(const void *value, void *parameter) element->usage = usage; element->pNext = elementCurrent; - element->minReport = element->min = (SInt32) IOHIDElementGetLogicalMin(refElement); - element->maxReport = element->max = (SInt32) IOHIDElementGetLogicalMax(refElement); + element->minReport = element->min = (SInt32)IOHIDElementGetLogicalMin(refElement); + element->maxReport = element->max = (SInt32)IOHIDElementGetLogicalMax(refElement); element->cookie = IOHIDElementGetCookie(refElement); pDevice->elements++; @@ -398,20 +407,29 @@ AddHIDElement(const void *value, void *parameter) } } -static SDL_bool -GetDeviceInfo(IOHIDDeviceRef hidDevice, recDevice *pDevice) +static int GetSteamVirtualGamepadSlot(Uint16 vendor_id, Uint16 product_id, const char *product_string) +{ + int slot = -1; + + if (vendor_id == USB_VENDOR_MICROSOFT && product_id == USB_PRODUCT_XBOX360_WIRED_CONTROLLER) { + /* Gamepad name is "GamePad-N", where N is slot + 1 */ + if (SDL_sscanf(product_string, "GamePad-%d", &slot) == 1) { + slot -= 1; + } + } + return slot; +} + +static SDL_bool GetDeviceInfo(IOHIDDeviceRef hidDevice, recDevice *pDevice) { Sint32 vendor = 0; Sint32 product = 0; Sint32 version = 0; - const char *name; - const char *manufacturer_remapped; + char *name; char manufacturer_string[256]; char product_string[256]; CFTypeRef refCF = NULL; CFArrayRef array = NULL; - Uint16 *guid16 = (Uint16 *)pDevice->guid.data; - int i; /* get usage page and usage */ refCF = IOHIDDeviceGetProperty(hidDevice, CFSTR(kIOHIDPrimaryUsagePageKey)); @@ -460,61 +478,29 @@ GetDeviceInfo(IOHIDDeviceRef hidDevice, recDevice *pDevice) } /* get device name */ - name = SDL_GetCustomJoystickName(vendor, product); + refCF = IOHIDDeviceGetProperty(hidDevice, CFSTR(kIOHIDManufacturerKey)); + if ((!refCF) || (!CFStringGetCString(refCF, manufacturer_string, sizeof(manufacturer_string), kCFStringEncodingUTF8))) { + manufacturer_string[0] = '\0'; + } + refCF = IOHIDDeviceGetProperty(hidDevice, CFSTR(kIOHIDProductKey)); + if ((!refCF) || (!CFStringGetCString(refCF, product_string, sizeof(product_string), kCFStringEncodingUTF8))) { + product_string[0] = '\0'; + } + name = SDL_CreateJoystickName(vendor, product, manufacturer_string, product_string); if (name) { SDL_strlcpy(pDevice->product, name, sizeof(pDevice->product)); - } else { - refCF = IOHIDDeviceGetProperty(hidDevice, CFSTR(kIOHIDManufacturerKey)); - if ((!refCF) || (!CFStringGetCString(refCF, manufacturer_string, sizeof(manufacturer_string), kCFStringEncodingUTF8))) { - manufacturer_string[0] = '\0'; - } - refCF = IOHIDDeviceGetProperty(hidDevice, CFSTR(kIOHIDProductKey)); - if ((!refCF) || (!CFStringGetCString(refCF, product_string, sizeof(product_string), kCFStringEncodingUTF8))) { - SDL_strlcpy(product_string, "Unidentified joystick", sizeof(product_string)); - } - for (i = (int)SDL_strlen(manufacturer_string) - 1; i > 0; --i) { - if (SDL_isspace(manufacturer_string[i])) { - manufacturer_string[i] = '\0'; - } else { - break; - } - } - - manufacturer_remapped = SDL_GetCustomJoystickManufacturer(manufacturer_string); - if (manufacturer_remapped != manufacturer_string) { - SDL_strlcpy(manufacturer_string, manufacturer_remapped, sizeof(manufacturer_string)); - } - - if (SDL_strncasecmp(manufacturer_string, product_string, SDL_strlen(manufacturer_string)) == 0) { - SDL_strlcpy(pDevice->product, product_string, sizeof(pDevice->product)); - } else { - SDL_snprintf(pDevice->product, sizeof(pDevice->product), "%s %s", manufacturer_string, product_string); - } + SDL_free(name); } #ifdef SDL_JOYSTICK_HIDAPI if (HIDAPI_IsDevicePresent(vendor, product, version, pDevice->product)) { /* The HIDAPI driver is taking care of this device */ - return 0; + return SDL_FALSE; } #endif - SDL_memset(pDevice->guid.data, 0, sizeof(pDevice->guid.data)); - - if (vendor && product) { - *guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_USB); - *guid16++ = 0; - *guid16++ = SDL_SwapLE16((Uint16)vendor); - *guid16++ = 0; - *guid16++ = SDL_SwapLE16((Uint16)product); - *guid16++ = 0; - *guid16++ = SDL_SwapLE16((Uint16)version); - *guid16++ = 0; - } else { - *guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_BLUETOOTH); - *guid16++ = 0; - SDL_strlcpy((char*)guid16, pDevice->product, sizeof(pDevice->guid.data) - 4); - } + pDevice->guid = SDL_CreateJoystickGUID(SDL_HARDWARE_BUS_USB, (Uint16)vendor, (Uint16)product, (Uint16)version, manufacturer_string, product_string, 0, 0); + pDevice->steam_virtual_gamepad_slot = GetSteamVirtualGamepadSlot((Uint16)vendor, (Uint16)product, product_string); array = IOHIDDeviceCopyMatchingElements(hidDevice, NULL, kIOHIDOptionsTypeNone); if (array) { @@ -525,11 +511,18 @@ GetDeviceInfo(IOHIDDeviceRef hidDevice, recDevice *pDevice) return SDL_TRUE; } -static SDL_bool -JoystickAlreadyKnown(IOHIDDeviceRef ioHIDDeviceObject) +static SDL_bool JoystickAlreadyKnown(IOHIDDeviceRef ioHIDDeviceObject) { recDevice *i; - for (i = gpDeviceList; i != NULL; i = i->pNext) { + +#if defined(SDL_JOYSTICK_MFI) + extern SDL_bool IOS_SupportedHIDDevice(IOHIDDeviceRef device); + if (IOS_SupportedHIDDevice(ioHIDDeviceObject)) { + return SDL_TRUE; + } +#endif + + for (i = gpDeviceList; i; i = i->pNext) { if (i->deviceRef == ioHIDDeviceObject) { return SDL_TRUE; } @@ -537,12 +530,9 @@ JoystickAlreadyKnown(IOHIDDeviceRef ioHIDDeviceObject) return SDL_FALSE; } - -static void -JoystickDeviceWasAddedCallback(void *ctx, IOReturn res, void *sender, IOHIDDeviceRef ioHIDDeviceObject) +static void JoystickDeviceWasAddedCallback(void *ctx, IOReturn res, void *sender, IOHIDDeviceRef ioHIDDeviceObject) { recDevice *device; - int device_index = 0; io_service_t ioservice; if (res != kIOReturnSuccess) { @@ -550,10 +540,10 @@ JoystickDeviceWasAddedCallback(void *ctx, IOReturn res, void *sender, IOHIDDevic } if (JoystickAlreadyKnown(ioHIDDeviceObject)) { - return; /* IOKit sent us a duplicate. */ + return; /* IOKit sent us a duplicate. */ } - device = (recDevice *) SDL_calloc(1, sizeof(recDevice)); + device = (recDevice *)SDL_calloc(1, sizeof(recDevice)); if (!device) { SDL_OutOfMemory(); return; @@ -561,7 +551,7 @@ JoystickDeviceWasAddedCallback(void *ctx, IOReturn res, void *sender, IOHIDDevic if (!GetDeviceInfo(ioHIDDeviceObject, device)) { FreeDevice(device); - return; /* not a device we care about, probably. */ + return; /* not a device we care about, probably. */ } if (SDL_ShouldIgnoreJoystick(device->product, device->guid)) { @@ -572,6 +562,7 @@ JoystickDeviceWasAddedCallback(void *ctx, IOReturn res, void *sender, IOHIDDevic /* Get notified when this device is disconnected. */ IOHIDDeviceRegisterRemovalCallback(ioHIDDeviceObject, JoystickDeviceWasRemovedCallback, device); IOHIDDeviceScheduleWithRunLoop(ioHIDDeviceObject, CFRunLoopGetCurrent(), SDL_JOYSTICK_RUNLOOP_MODE); + device->runLoopAttached = SDL_TRUE; /* Allocate an instance ID for this device */ device->instance_id = SDL_GetNextJoystickInstanceID(); @@ -580,31 +571,28 @@ JoystickDeviceWasAddedCallback(void *ctx, IOReturn res, void *sender, IOHIDDevic ioservice = IOHIDDeviceGetService(ioHIDDeviceObject); if ((ioservice) && (FFIsForceFeedback(ioservice) == FF_OK)) { device->ffservice = ioservice; -#if SDL_HAPTIC_IOKIT +#ifdef SDL_HAPTIC_IOKIT MacHaptic_MaybeAddDevice(ioservice); #endif } /* Add device to the end of the list */ - if ( !gpDeviceList ) { + if (!gpDeviceList) { gpDeviceList = device; } else { recDevice *curdevice; curdevice = gpDeviceList; - while ( curdevice->pNext ) { - ++device_index; + while (curdevice->pNext) { curdevice = curdevice->pNext; } curdevice->pNext = device; - ++device_index; /* bump by one since we counted by pNext. */ } SDL_PrivateJoystickAdded(device->instance_id); } -static SDL_bool -ConfigHIDManager(CFArrayRef matchingArray) +static SDL_bool ConfigHIDManager(CFArrayRef matchingArray) { CFRunLoopRef runloop = CFRunLoopGetCurrent(); @@ -616,24 +604,22 @@ ConfigHIDManager(CFArrayRef matchingArray) IOHIDManagerRegisterDeviceMatchingCallback(hidman, JoystickDeviceWasAddedCallback, NULL); IOHIDManagerScheduleWithRunLoop(hidman, runloop, SDL_JOYSTICK_RUNLOOP_MODE); - while (CFRunLoopRunInMode(SDL_JOYSTICK_RUNLOOP_MODE,0,TRUE) == kCFRunLoopRunHandledSource) { + while (CFRunLoopRunInMode(SDL_JOYSTICK_RUNLOOP_MODE, 0, TRUE) == kCFRunLoopRunHandledSource) { /* no-op. Callback fires once per existing device. */ } /* future hotplug events will come through SDL_JOYSTICK_RUNLOOP_MODE now. */ - return SDL_TRUE; /* good to go. */ + return SDL_TRUE; /* good to go. */ } - -static CFDictionaryRef -CreateHIDDeviceMatchDictionary(const UInt32 page, const UInt32 usage, int *okay) +static CFDictionaryRef CreateHIDDeviceMatchDictionary(const UInt32 page, const UInt32 usage, int *okay) { CFDictionaryRef retval = NULL; CFNumberRef pageNumRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &page); CFNumberRef usageNumRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage); - const void *keys[2] = { (void *) CFSTR(kIOHIDDeviceUsagePageKey), (void *) CFSTR(kIOHIDDeviceUsageKey) }; - const void *vals[2] = { (void *) pageNumRef, (void *) usageNumRef }; + const void *keys[2] = { (void *)CFSTR(kIOHIDDeviceUsagePageKey), (void *)CFSTR(kIOHIDDeviceUsageKey) }; + const void *vals[2] = { (void *)pageNumRef, (void *)usageNumRef }; if (pageNumRef && usageNumRef) { retval = CFDictionaryCreate(kCFAllocatorDefault, keys, vals, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); @@ -653,15 +639,14 @@ CreateHIDDeviceMatchDictionary(const UInt32 page, const UInt32 usage, int *okay) return retval; } -static SDL_bool -CreateHIDManager(void) +static SDL_bool CreateHIDManager(void) { SDL_bool retval = SDL_FALSE; int okay = 1; const void *vals[] = { - (void *) CreateHIDDeviceMatchDictionary(kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick, &okay), - (void *) CreateHIDDeviceMatchDictionary(kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad, &okay), - (void *) CreateHIDDeviceMatchDictionary(kHIDPage_GenericDesktop, kHIDUsage_GD_MultiAxisController, &okay), + (void *)CreateHIDDeviceMatchDictionary(kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick, &okay), + (void *)CreateHIDDeviceMatchDictionary(kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad, &okay), + (void *)CreateHIDDeviceMatchDictionary(kHIDPage_GenericDesktop, kHIDUsage_GD_MultiAxisController, &okay), }; const size_t numElements = SDL_arraysize(vals); CFArrayRef array = okay ? CFArrayCreate(kCFAllocatorDefault, vals, numElements, &kCFTypeArrayCallBacks) : NULL; @@ -669,7 +654,7 @@ CreateHIDManager(void) for (i = 0; i < numElements; i++) { if (vals[i]) { - CFRelease((CFTypeRef) vals[i]); + CFRelease((CFTypeRef)vals[i]); } } @@ -684,12 +669,10 @@ CreateHIDManager(void) return retval; } - -static int -DARWIN_JoystickInit(void) +static int DARWIN_JoystickInit(void) { - if (gpDeviceList) { - return SDL_SetError("Joystick: Device list already inited."); + if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_IOKIT, SDL_TRUE)) { + return 0; } if (!CreateHIDManager()) { @@ -699,8 +682,7 @@ DARWIN_JoystickInit(void) return 0; } -static int -DARWIN_JoystickGetCount(void) +static int DARWIN_JoystickGetCount(void) { recDevice *device = gpDeviceList; int nJoySticks = 0; @@ -715,8 +697,7 @@ DARWIN_JoystickGetCount(void) return nJoySticks; } -static void -DARWIN_JoystickDetect(void) +static void DARWIN_JoystickDetect(void) { recDevice *device = gpDeviceList; while (device) { @@ -727,34 +708,42 @@ DARWIN_JoystickDetect(void) } } - /* run this after the checks above so we don't set device->removed and delete the device before - DARWIN_JoystickUpdate can run to clean up the SDL_Joystick object that owns this device */ - while (CFRunLoopRunInMode(SDL_JOYSTICK_RUNLOOP_MODE,0,TRUE) == kCFRunLoopRunHandledSource) { - /* no-op. Pending callbacks will fire in CFRunLoopRunInMode(). */ + if (hidman) { + /* run this after the checks above so we don't set device->removed and delete the device before + DARWIN_JoystickUpdate can run to clean up the SDL_Joystick object that owns this device */ + while (CFRunLoopRunInMode(SDL_JOYSTICK_RUNLOOP_MODE, 0, TRUE) == kCFRunLoopRunHandledSource) { + /* no-op. Pending callbacks will fire in CFRunLoopRunInMode(). */ + } } } -/* Function to get the device-dependent name of a joystick */ -const char * -DARWIN_JoystickGetDeviceName(int device_index) +const char *DARWIN_JoystickGetDeviceName(int device_index) { recDevice *device = GetDeviceForIndex(device_index); return device ? device->product : "UNKNOWN"; } -static int -DARWIN_JoystickGetDevicePlayerIndex(int device_index) +const char *DARWIN_JoystickGetDevicePath(int device_index) +{ + return NULL; +} + +static int DARWIN_JoystickGetDeviceSteamVirtualGamepadSlot(int device_index) +{ + recDevice *device = GetDeviceForIndex(device_index); + return device ? device->steam_virtual_gamepad_slot : -1; +} + +static int DARWIN_JoystickGetDevicePlayerIndex(int device_index) { return -1; } -static void -DARWIN_JoystickSetDevicePlayerIndex(int device_index, int player_index) +static void DARWIN_JoystickSetDevicePlayerIndex(int device_index, int player_index) { } -static SDL_JoystickGUID -DARWIN_JoystickGetDeviceGUID( int device_index ) +static SDL_JoystickGUID DARWIN_JoystickGetDeviceGUID(int device_index) { recDevice *device = GetDeviceForIndex(device_index); SDL_JoystickGUID guid; @@ -766,20 +755,19 @@ DARWIN_JoystickGetDeviceGUID( int device_index ) return guid; } -static SDL_JoystickID -DARWIN_JoystickGetDeviceInstanceID(int device_index) +static SDL_JoystickID DARWIN_JoystickGetDeviceInstanceID(int device_index) { recDevice *device = GetDeviceForIndex(device_index); return device ? device->instance_id : 0; } -static int -DARWIN_JoystickOpen(SDL_Joystick * joystick, int device_index) +static int DARWIN_JoystickOpen(SDL_Joystick *joystick, int device_index) { recDevice *device = GetDeviceForIndex(device_index); joystick->instance_id = device->instance_id; joystick->hwdata = device; + device->joystick = joystick; joystick->name = device->product; joystick->naxes = device->axes; @@ -792,8 +780,7 @@ DARWIN_JoystickOpen(SDL_Joystick * joystick, int device_index) /* * Like strerror but for force feedback errors. */ -static const char * -FFStrError(unsigned int err) +static const char *FFStrError(unsigned int err) { switch (err) { case FFERR_DEVICEFULL: @@ -845,8 +832,7 @@ FFStrError(unsigned int err) } } -static int -DARWIN_JoystickInitRumble(recDevice *device, Sint16 magnitude) +static int DARWIN_JoystickInitRumble(recDevice *device, Sint16 magnitude) { HRESULT result; @@ -875,15 +861,14 @@ DARWIN_JoystickInitRumble(recDevice *device, Sint16 magnitude) } result = FFDeviceCreateEffect(device->ffdevice, kFFEffectType_Sine_ID, - device->ffeffect, &device->ffeffect_ref); + device->ffeffect, &device->ffeffect_ref); if (result != FF_OK) { return SDL_SetError("Haptic: Unable to create effect: %s", FFStrError(result)); } return 0; } -static int -DARWIN_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +static int DARWIN_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) { HRESULT result; recDevice *device = joystick->hwdata; @@ -891,6 +876,10 @@ DARWIN_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint /* Scale and average the two rumble strengths */ Sint16 magnitude = (Sint16)(((low_frequency_rumble / 2) + (high_frequency_rumble / 2)) / 2); + if (!device) { + return SDL_SetError("Rumble failed, device disconnected"); + } + if (!device->ffservice) { return SDL_Unsupported(); } @@ -900,7 +889,7 @@ DARWIN_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint periodic->dwMagnitude = CONVERT_MAGNITUDE(magnitude); result = FFEffectSetParameters(device->ffeffect_ref, device->ffeffect, - (FFEP_DURATION | FFEP_TYPESPECIFICPARAMS)); + (FFEP_DURATION | FFEP_TYPESPECIFICPARAMS)); if (result != FF_OK) { return SDL_SetError("Unable to update rumble effect: %s", FFStrError(result)); } @@ -918,21 +907,55 @@ DARWIN_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint return 0; } -static void -DARWIN_JoystickUpdate(SDL_Joystick * joystick) +static int DARWIN_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) +{ + return SDL_Unsupported(); +} + +static Uint32 DARWIN_JoystickGetCapabilities(SDL_Joystick *joystick) +{ + recDevice *device = joystick->hwdata; + Uint32 result = 0; + + if (!device) { + return 0; + } + + if (device->ffservice) { + result |= SDL_JOYCAP_RUMBLE; + } + + return result; +} + +static int DARWIN_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + return SDL_Unsupported(); +} + +static int DARWIN_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + +static int DARWIN_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled) +{ + return SDL_Unsupported(); +} + +static void DARWIN_JoystickUpdate(SDL_Joystick *joystick) { recDevice *device = joystick->hwdata; recElement *element; SInt32 value, range; - int i; + int i, goodRead = SDL_FALSE; if (!device) { return; } - if (device->removed) { /* device was unplugged; ignore it. */ + if (device->removed) { /* device was unplugged; ignore it. */ if (joystick->hwdata) { - joystick->force_recentering = SDL_TRUE; joystick->hwdata = NULL; } return; @@ -941,7 +964,6 @@ DARWIN_JoystickUpdate(SDL_Joystick * joystick) element = device->firstAxis; i = 0; - int goodRead = SDL_FALSE; while (element) { goodRead = GetHIDScaledCalibratedState(device, element, -32768, 32767, &value); if (goodRead) { @@ -957,7 +979,7 @@ DARWIN_JoystickUpdate(SDL_Joystick * joystick) while (element) { goodRead = GetHIDElementState(device, element, &value); if (goodRead) { - if (value > 1) { /* handle pressure-sensitive buttons */ + if (value > 1) { /* handle pressure-sensitive buttons */ value = 1; } SDL_PrivateJoystickButton(joystick, i, value); @@ -969,7 +991,7 @@ DARWIN_JoystickUpdate(SDL_Joystick * joystick) element = device->firstHat; i = 0; - + while (element) { Uint8 pos = 0; @@ -977,9 +999,9 @@ DARWIN_JoystickUpdate(SDL_Joystick * joystick) goodRead = GetHIDElementState(device, element, &value); if (goodRead) { value -= element->min; - if (range == 4) { /* 4 position hatswitch - scale up value */ + if (range == 4) { /* 4 position hatswitch - scale up value */ value *= 2; - } else if (range != 8) { /* Neither a 4 nor 8 positions - fall back to default position (centered) */ + } else if (range != 8) { /* Neither a 4 nor 8 positions - fall back to default position (centered) */ value = -1; } switch (value) { @@ -1018,19 +1040,21 @@ DARWIN_JoystickUpdate(SDL_Joystick * joystick) SDL_PrivateJoystickHat(joystick, i, pos); } - + element = element->pNext; ++i; } } -static void -DARWIN_JoystickClose(SDL_Joystick * joystick) +static void DARWIN_JoystickClose(SDL_Joystick *joystick) { + recDevice *device = joystick->hwdata; + if (device) { + device->joystick = NULL; + } } -static void -DARWIN_JoystickQuit(void) +static void DARWIN_JoystickQuit(void) { while (FreeDevice(gpDeviceList)) { /* spin */ @@ -1044,21 +1068,33 @@ DARWIN_JoystickQuit(void) } } -SDL_JoystickDriver SDL_DARWIN_JoystickDriver = +static SDL_bool DARWIN_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) { + return SDL_FALSE; +} + +SDL_JoystickDriver SDL_DARWIN_JoystickDriver = { DARWIN_JoystickInit, DARWIN_JoystickGetCount, DARWIN_JoystickDetect, DARWIN_JoystickGetDeviceName, + DARWIN_JoystickGetDevicePath, + DARWIN_JoystickGetDeviceSteamVirtualGamepadSlot, DARWIN_JoystickGetDevicePlayerIndex, DARWIN_JoystickSetDevicePlayerIndex, DARWIN_JoystickGetDeviceGUID, DARWIN_JoystickGetDeviceInstanceID, DARWIN_JoystickOpen, DARWIN_JoystickRumble, + DARWIN_JoystickRumbleTriggers, + DARWIN_JoystickGetCapabilities, + DARWIN_JoystickSetLED, + DARWIN_JoystickSendEffect, + DARWIN_JoystickSetSensorsEnabled, DARWIN_JoystickUpdate, DARWIN_JoystickClose, DARWIN_JoystickQuit, + DARWIN_JoystickGetGamepadMapping }; #endif /* SDL_JOYSTICK_IOKIT */ diff --git a/SDL2-2.0.12/src/joystick/darwin/SDL_sysjoystick_c.h b/SDL2-2.30.5/src/joystick/darwin/SDL_iokitjoystick_c.h similarity index 56% rename from SDL2-2.0.12/src/joystick/darwin/SDL_sysjoystick_c.h rename to SDL2-2.30.5/src/joystick/darwin/SDL_iokitjoystick_c.h index 45a5793..095c083 100644 --- a/SDL2-2.0.12/src/joystick/darwin/SDL_sysjoystick_c.h +++ b/SDL2-2.30.5/src/joystick/darwin/SDL_iokitjoystick_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -31,46 +31,49 @@ struct recElement { IOHIDElementRef elementRef; IOHIDElementCookie cookie; - uint32_t usagePage, usage; /* HID usage */ - SInt32 min; /* reported min value possible */ - SInt32 max; /* reported max value possible */ + uint32_t usagePage, usage; /* HID usage */ + SInt32 min; /* reported min value possible */ + SInt32 max; /* reported max value possible */ /* runtime variables used for auto-calibration */ - SInt32 minReport; /* min returned value */ - SInt32 maxReport; /* max returned value */ + SInt32 minReport; /* min returned value */ + SInt32 maxReport; /* max returned value */ - struct recElement *pNext; /* next element in list */ + struct recElement *pNext; /* next element in list */ }; typedef struct recElement recElement; struct joystick_hwdata { - IOHIDDeviceRef deviceRef; /* HIDManager device handle */ - io_service_t ffservice; /* Interface for force feedback, 0 = no ff */ + IOHIDDeviceRef deviceRef; /* HIDManager device handle */ + io_service_t ffservice; /* Interface for force feedback, 0 = no ff */ FFDeviceObjectReference ffdevice; FFEFFECT *ffeffect; FFEffectObjectReference ffeffect_ref; SDL_bool ff_initialized; - char product[256]; /* name of product */ - uint32_t usage; /* usage page from IOUSBHID Parser.h which defines general usage */ - uint32_t usagePage; /* usage within above page from IOUSBHID Parser.h which defines specific usage */ + char product[256]; /* name of product */ + uint32_t usage; /* usage page from IOUSBHID Parser.h which defines general usage */ + uint32_t usagePage; /* usage within above page from IOUSBHID Parser.h which defines specific usage */ - int axes; /* number of axis (calculated, not reported by device) */ - int buttons; /* number of buttons (calculated, not reported by device) */ - int hats; /* number of hat switches (calculated, not reported by device) */ - int elements; /* number of total elements (should be total of above) (calculated, not reported by device) */ + int axes; /* number of axis (calculated, not reported by device) */ + int buttons; /* number of buttons (calculated, not reported by device) */ + int hats; /* number of hat switches (calculated, not reported by device) */ + int elements; /* number of total elements (should be total of above) (calculated, not reported by device) */ recElement *firstAxis; recElement *firstButton; recElement *firstHat; SDL_bool removed; + SDL_Joystick *joystick; + SDL_bool runLoopAttached; /* is 'deviceRef' attached to a CFRunLoop? */ int instance_id; SDL_JoystickGUID guid; + int steam_virtual_gamepad_slot; - struct joystick_hwdata *pNext; /* next device */ + struct joystick_hwdata *pNext; /* next device */ }; typedef struct joystick_hwdata recDevice; diff --git a/SDL2-2.30.5/src/joystick/dummy/SDL_sysjoystick.c b/SDL2-2.30.5/src/joystick/dummy/SDL_sysjoystick.c new file mode 100644 index 0000000..1ade8e1 --- /dev/null +++ b/SDL2-2.30.5/src/joystick/dummy/SDL_sysjoystick.c @@ -0,0 +1,159 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#if defined(SDL_JOYSTICK_DUMMY) || defined(SDL_JOYSTICK_DISABLED) + +/* This is the dummy implementation of the SDL joystick API */ + +#include "SDL_joystick.h" +#include "../SDL_sysjoystick.h" +#include "../SDL_joystick_c.h" + +static int DUMMY_JoystickInit(void) +{ + return 0; +} + +static int DUMMY_JoystickGetCount(void) +{ + return 0; +} + +static void DUMMY_JoystickDetect(void) +{ +} + +static const char *DUMMY_JoystickGetDeviceName(int device_index) +{ + return NULL; +} + +static const char *DUMMY_JoystickGetDevicePath(int device_index) +{ + return NULL; +} + +static int DUMMY_JoystickGetDeviceSteamVirtualGamepadSlot(int device_index) +{ + return -1; +} + +static int DUMMY_JoystickGetDevicePlayerIndex(int device_index) +{ + return -1; +} + +static void DUMMY_JoystickSetDevicePlayerIndex(int device_index, int player_index) +{ +} + +static SDL_JoystickGUID DUMMY_JoystickGetDeviceGUID(int device_index) +{ + SDL_JoystickGUID guid; + SDL_zero(guid); + return guid; +} + +static SDL_JoystickID DUMMY_JoystickGetDeviceInstanceID(int device_index) +{ + return -1; +} + +static int DUMMY_JoystickOpen(SDL_Joystick *joystick, int device_index) +{ + return SDL_SetError("Logic error: No joysticks available"); +} + +static int DUMMY_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ + return SDL_Unsupported(); +} + +static int DUMMY_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) +{ + return SDL_Unsupported(); +} + +static Uint32 DUMMY_JoystickGetCapabilities(SDL_Joystick *joystick) +{ + return 0; +} + +static int DUMMY_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + return SDL_Unsupported(); +} + +static int DUMMY_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + +static int DUMMY_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled) +{ + return SDL_Unsupported(); +} + +static void DUMMY_JoystickUpdate(SDL_Joystick *joystick) +{ +} + +static void DUMMY_JoystickClose(SDL_Joystick *joystick) +{ +} + +static void DUMMY_JoystickQuit(void) +{ +} + +static SDL_bool DUMMY_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) +{ + return SDL_FALSE; +} + +SDL_JoystickDriver SDL_DUMMY_JoystickDriver = { + DUMMY_JoystickInit, + DUMMY_JoystickGetCount, + DUMMY_JoystickDetect, + DUMMY_JoystickGetDeviceName, + DUMMY_JoystickGetDevicePath, + DUMMY_JoystickGetDeviceSteamVirtualGamepadSlot, + DUMMY_JoystickGetDevicePlayerIndex, + DUMMY_JoystickSetDevicePlayerIndex, + DUMMY_JoystickGetDeviceGUID, + DUMMY_JoystickGetDeviceInstanceID, + DUMMY_JoystickOpen, + DUMMY_JoystickRumble, + DUMMY_JoystickRumbleTriggers, + DUMMY_JoystickGetCapabilities, + DUMMY_JoystickSetLED, + DUMMY_JoystickSendEffect, + DUMMY_JoystickSetSensorsEnabled, + DUMMY_JoystickUpdate, + DUMMY_JoystickClose, + DUMMY_JoystickQuit, + DUMMY_JoystickGetGamepadMapping +}; + +#endif /* SDL_JOYSTICK_DUMMY || SDL_JOYSTICK_DISABLED */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/joystick/emscripten/SDL_sysjoystick.c b/SDL2-2.30.5/src/joystick/emscripten/SDL_sysjoystick.c similarity index 67% rename from SDL2-2.0.12/src/joystick/emscripten/SDL_sysjoystick.c rename to SDL2-2.30.5/src/joystick/emscripten/SDL_sysjoystick.c index 97b8a9e..a2db803 100644 --- a/SDL2-2.0.12/src/joystick/emscripten/SDL_sysjoystick.c +++ b/SDL2-2.30.5/src/joystick/emscripten/SDL_sysjoystick.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -28,46 +28,42 @@ #include "SDL_events.h" #include "SDL_joystick.h" -#include "SDL_assert.h" #include "SDL_timer.h" -#include "SDL_log.h" #include "SDL_sysjoystick_c.h" #include "../SDL_joystick_c.h" -static SDL_joylist_item * JoystickByIndex(int index); +static SDL_joylist_item *JoystickByIndex(int index); static SDL_joylist_item *SDL_joylist = NULL; static SDL_joylist_item *SDL_joylist_tail = NULL; static int numjoysticks = 0; -static int instance_counter = 0; -static EM_BOOL -Emscripten_JoyStickConnected(int eventType, const EmscriptenGamepadEvent *gamepadEvent, void *userData) +static EM_BOOL Emscripten_JoyStickConnected(int eventType, const EmscriptenGamepadEvent *gamepadEvent, void *userData) { int i; SDL_joylist_item *item; if (JoystickByIndex(gamepadEvent->index) != NULL) { - return 1; + return 1; } - item = (SDL_joylist_item *) SDL_malloc(sizeof (SDL_joylist_item)); - if (item == NULL) { + item = (SDL_joylist_item *)SDL_malloc(sizeof(SDL_joylist_item)); + if (!item) { return 1; } SDL_zerop(item); item->index = gamepadEvent->index; - item->name = SDL_strdup(gamepadEvent->id); - if ( item->name == NULL ) { + item->name = SDL_CreateJoystickName(0, 0, NULL, gamepadEvent->id); + if (!item->name) { SDL_free(item); return 1; } item->mapping = SDL_strdup(gamepadEvent->mapping); - if ( item->mapping == NULL ) { + if (!item->mapping) { SDL_free(item->name); SDL_free(item); return 1; @@ -75,20 +71,20 @@ Emscripten_JoyStickConnected(int eventType, const EmscriptenGamepadEvent *gamepa item->naxes = gamepadEvent->numAxes; item->nbuttons = gamepadEvent->numButtons; - item->device_instance = instance_counter++; + item->device_instance = SDL_GetNextJoystickInstanceID(); item->timestamp = gamepadEvent->timestamp; - for( i = 0; i < item->naxes; i++) { + for (i = 0; i < item->naxes; i++) { item->axis[i] = gamepadEvent->axis[i]; } - for( i = 0; i < item->nbuttons; i++) { + for (i = 0; i < item->nbuttons; i++) { item->analogButton[i] = gamepadEvent->analogButton[i]; item->digitalButton[i] = gamepadEvent->digitalButton[i]; } - if (SDL_joylist_tail == NULL) { + if (!SDL_joylist_tail) { SDL_joylist = SDL_joylist_tail = item; } else { SDL_joylist_tail->next = item; @@ -110,13 +106,12 @@ Emscripten_JoyStickConnected(int eventType, const EmscriptenGamepadEvent *gamepa return 1; } -static EM_BOOL -Emscripten_JoyStickDisconnected(int eventType, const EmscriptenGamepadEvent *gamepadEvent, void *userData) +static EM_BOOL Emscripten_JoyStickDisconnected(int eventType, const EmscriptenGamepadEvent *gamepadEvent, void *userData) { SDL_joylist_item *item = SDL_joylist; SDL_joylist_item *prev = NULL; - while (item != NULL) { + while (item) { if (item->index == gamepadEvent->index) { break; } @@ -124,7 +119,7 @@ Emscripten_JoyStickDisconnected(int eventType, const EmscriptenGamepadEvent *gam item = item->next; } - if (item == NULL) { + if (!item) { return 1; } @@ -132,7 +127,7 @@ Emscripten_JoyStickDisconnected(int eventType, const EmscriptenGamepadEvent *gam item->joystick->hwdata = NULL; } - if (prev != NULL) { + if (prev) { prev->next = item->next; } else { SDL_assert(SDL_joylist == item); @@ -157,8 +152,7 @@ Emscripten_JoyStickDisconnected(int eventType, const EmscriptenGamepadEvent *gam } /* Function to perform any system-specific joystick related cleanup */ -static void -EMSCRIPTEN_JoystickQuit(void) +static void EMSCRIPTEN_JoystickQuit(void) { SDL_joylist_item *item = NULL; SDL_joylist_item *next = NULL; @@ -173,7 +167,6 @@ EMSCRIPTEN_JoystickQuit(void) SDL_joylist = SDL_joylist_tail = NULL; numjoysticks = 0; - instance_counter = 0; emscripten_set_gamepadconnected_callback(NULL, 0, NULL); emscripten_set_gamepaddisconnected_callback(NULL, 0, NULL); @@ -182,8 +175,7 @@ EMSCRIPTEN_JoystickQuit(void) /* Function to scan the system for joysticks. * It should return 0, or -1 on an unrecoverable fatal error. */ -static int -EMSCRIPTEN_JoystickInit(void) +static int EMSCRIPTEN_JoystickInit(void) { int retval, i, numjs; EmscriptenGamepadEvent gamepadState; @@ -201,7 +193,7 @@ EMSCRIPTEN_JoystickInit(void) /* handle already connected gamepads */ if (numjs > 0) { - for(i = 0; i < numjs; i++) { + for (i = 0; i < numjs; i++) { retval = emscripten_get_gamepad_status(i, &gamepadState); if (retval == EMSCRIPTEN_RESULT_SUCCESS) { Emscripten_JoyStickConnected(EMSCRIPTEN_EVENT_GAMEPADCONNECTED, @@ -215,7 +207,7 @@ EMSCRIPTEN_JoystickInit(void) 0, Emscripten_JoyStickConnected); - if(retval != EMSCRIPTEN_RESULT_SUCCESS) { + if (retval != EMSCRIPTEN_RESULT_SUCCESS) { EMSCRIPTEN_JoystickQuit(); return SDL_SetError("Could not set gamepad connect callback"); } @@ -223,7 +215,7 @@ EMSCRIPTEN_JoystickInit(void) retval = emscripten_set_gamepaddisconnected_callback(NULL, 0, Emscripten_JoyStickDisconnected); - if(retval != EMSCRIPTEN_RESULT_SUCCESS) { + if (retval != EMSCRIPTEN_RESULT_SUCCESS) { EMSCRIPTEN_JoystickQuit(); return SDL_SetError("Could not set gamepad disconnect callback"); } @@ -232,8 +224,7 @@ EMSCRIPTEN_JoystickInit(void) } /* Returns item matching given SDL device index. */ -static SDL_joylist_item * -JoystickByDeviceIndex(int device_index) +static SDL_joylist_item *JoystickByDeviceIndex(int device_index) { SDL_joylist_item *item = SDL_joylist; @@ -246,8 +237,7 @@ JoystickByDeviceIndex(int device_index) } /* Returns item matching given HTML gamepad index. */ -static SDL_joylist_item * -JoystickByIndex(int index) +static SDL_joylist_item *JoystickByIndex(int index) { SDL_joylist_item *item = SDL_joylist; @@ -255,7 +245,7 @@ JoystickByIndex(int index) return NULL; } - while (item != NULL) { + while (item) { if (item->index == index) { break; } @@ -265,36 +255,40 @@ JoystickByIndex(int index) return item; } -static int -EMSCRIPTEN_JoystickGetCount(void) +static int EMSCRIPTEN_JoystickGetCount(void) { return numjoysticks; } -static void -EMSCRIPTEN_JoystickDetect(void) +static void EMSCRIPTEN_JoystickDetect(void) { } -static const char * -EMSCRIPTEN_JoystickGetDeviceName(int device_index) +static const char *EMSCRIPTEN_JoystickGetDeviceName(int device_index) { return JoystickByDeviceIndex(device_index)->name; } -static int -EMSCRIPTEN_JoystickGetDevicePlayerIndex(int device_index) +static const char *EMSCRIPTEN_JoystickGetDevicePath(int device_index) +{ + return NULL; +} + +static int EMSCRIPTEN_JoystickGetDeviceSteamVirtualGamepadSlot(int device_index) { return -1; } -static void -EMSCRIPTEN_JoystickSetDevicePlayerIndex(int device_index, int player_index) +static int EMSCRIPTEN_JoystickGetDevicePlayerIndex(int device_index) +{ + return -1; +} + +static void EMSCRIPTEN_JoystickSetDevicePlayerIndex(int device_index, int player_index) { } -static SDL_JoystickID -EMSCRIPTEN_JoystickGetDeviceInstanceID(int device_index) +static SDL_JoystickID EMSCRIPTEN_JoystickGetDeviceInstanceID(int device_index) { return JoystickByDeviceIndex(device_index)->device_instance; } @@ -304,21 +298,20 @@ EMSCRIPTEN_JoystickGetDeviceInstanceID(int device_index) This should fill the nbuttons and naxes fields of the joystick structure. It returns 0, or -1 if there is an error. */ -static int -EMSCRIPTEN_JoystickOpen(SDL_Joystick * joystick, int device_index) +static int EMSCRIPTEN_JoystickOpen(SDL_Joystick *joystick, int device_index) { SDL_joylist_item *item = JoystickByDeviceIndex(device_index); - if (item == NULL ) { + if (!item) { return SDL_SetError("No such device"); } - if (item->joystick != NULL) { + if (item->joystick) { return SDL_SetError("Joystick already opened"); } joystick->instance_id = item->device_instance; - joystick->hwdata = (struct joystick_hwdata *) item; + joystick->hwdata = (struct joystick_hwdata *)item; item->joystick = joystick; /* HTML5 Gamepad API doesn't say anything about these */ @@ -328,7 +321,7 @@ EMSCRIPTEN_JoystickOpen(SDL_Joystick * joystick, int device_index) joystick->nbuttons = item->nbuttons; joystick->naxes = item->naxes; - return (0); + return 0; } /* Function to update the state of a joystick - called as a device poll. @@ -336,22 +329,21 @@ EMSCRIPTEN_JoystickOpen(SDL_Joystick * joystick, int device_index) * but instead should call SDL_PrivateJoystick*() to deliver events * and update joystick device state. */ -static void -EMSCRIPTEN_JoystickUpdate(SDL_Joystick * joystick) +static void EMSCRIPTEN_JoystickUpdate(SDL_Joystick *joystick) { EmscriptenGamepadEvent gamepadState; - SDL_joylist_item *item = (SDL_joylist_item *) joystick->hwdata; + SDL_joylist_item *item = (SDL_joylist_item *)joystick->hwdata; int i, result, buttonState; emscripten_sample_gamepad_data(); if (item) { result = emscripten_get_gamepad_status(item->index, &gamepadState); - if( result == EMSCRIPTEN_RESULT_SUCCESS) { - if(gamepadState.timestamp == 0 || gamepadState.timestamp != item->timestamp) { - for(i = 0; i < item->nbuttons; i++) { - if(item->digitalButton[i] != gamepadState.digitalButton[i]) { - buttonState = gamepadState.digitalButton[i]? SDL_PRESSED: SDL_RELEASED; + if (result == EMSCRIPTEN_RESULT_SUCCESS) { + if (gamepadState.timestamp == 0 || gamepadState.timestamp != item->timestamp) { + for (i = 0; i < item->nbuttons; i++) { + if (item->digitalButton[i] != gamepadState.digitalButton[i]) { + buttonState = gamepadState.digitalButton[i] ? SDL_PRESSED : SDL_RELEASED; SDL_PrivateJoystickButton(item->joystick, i, buttonState); } @@ -360,11 +352,11 @@ EMSCRIPTEN_JoystickUpdate(SDL_Joystick * joystick) item->digitalButton[i] = gamepadState.digitalButton[i]; } - for(i = 0; i < item->naxes; i++) { - if(item->axis[i] != gamepadState.axis[i]) { + for (i = 0; i < item->naxes; i++) { + if (item->axis[i] != gamepadState.axis[i]) { /* do we need to do conversion? */ SDL_PrivateJoystickAxis(item->joystick, i, - (Sint16) (32767.*gamepadState.axis[i])); + (Sint16)(32767. * gamepadState.axis[i])); } /* store to compare in next update */ @@ -378,47 +370,78 @@ EMSCRIPTEN_JoystickUpdate(SDL_Joystick * joystick) } /* Function to close a joystick after use */ -static void -EMSCRIPTEN_JoystickClose(SDL_Joystick * joystick) +static void EMSCRIPTEN_JoystickClose(SDL_Joystick *joystick) { - SDL_joylist_item *item = (SDL_joylist_item *) joystick->hwdata; + SDL_joylist_item *item = (SDL_joylist_item *)joystick->hwdata; if (item) { item->joystick = NULL; } } -static SDL_JoystickGUID -EMSCRIPTEN_JoystickGetDeviceGUID(int device_index) +static SDL_JoystickGUID EMSCRIPTEN_JoystickGetDeviceGUID(int device_index) { - SDL_JoystickGUID guid; - /* the GUID is just the first 16 chars of the name for now */ + /* the GUID is just the name for now */ const char *name = EMSCRIPTEN_JoystickGetDeviceName(device_index); - SDL_zero(guid); - SDL_memcpy(&guid, name, SDL_min(sizeof(guid), SDL_strlen(name))); - return guid; + return SDL_CreateJoystickGUIDForName(name); } -static int -EMSCRIPTEN_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +static int EMSCRIPTEN_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) { return SDL_Unsupported(); } -SDL_JoystickDriver SDL_EMSCRIPTEN_JoystickDriver = +static int EMSCRIPTEN_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) { + return SDL_Unsupported(); +} + +static SDL_bool EMSCRIPTEN_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) +{ + return SDL_FALSE; +} + +static Uint32 EMSCRIPTEN_JoystickGetCapabilities(SDL_Joystick *joystick) +{ + return 0; +} + +static int EMSCRIPTEN_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + return SDL_Unsupported(); +} + +static int EMSCRIPTEN_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + +static int EMSCRIPTEN_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled) +{ + return SDL_Unsupported(); +} + +SDL_JoystickDriver SDL_EMSCRIPTEN_JoystickDriver = { EMSCRIPTEN_JoystickInit, EMSCRIPTEN_JoystickGetCount, EMSCRIPTEN_JoystickDetect, EMSCRIPTEN_JoystickGetDeviceName, + EMSCRIPTEN_JoystickGetDevicePath, + EMSCRIPTEN_JoystickGetDeviceSteamVirtualGamepadSlot, EMSCRIPTEN_JoystickGetDevicePlayerIndex, EMSCRIPTEN_JoystickSetDevicePlayerIndex, EMSCRIPTEN_JoystickGetDeviceGUID, EMSCRIPTEN_JoystickGetDeviceInstanceID, EMSCRIPTEN_JoystickOpen, EMSCRIPTEN_JoystickRumble, + EMSCRIPTEN_JoystickRumbleTriggers, + EMSCRIPTEN_JoystickGetCapabilities, + EMSCRIPTEN_JoystickSetLED, + EMSCRIPTEN_JoystickSendEffect, + EMSCRIPTEN_JoystickSetSensorsEnabled, EMSCRIPTEN_JoystickUpdate, EMSCRIPTEN_JoystickClose, EMSCRIPTEN_JoystickQuit, + EMSCRIPTEN_JoystickGetGamepadMapping }; #endif /* SDL_JOYSTICK_EMSCRIPTEN */ diff --git a/SDL2-2.0.12/src/joystick/emscripten/SDL_sysjoystick_c.h b/SDL2-2.30.5/src/joystick/emscripten/SDL_sysjoystick_c.h similarity index 77% rename from SDL2-2.0.12/src/joystick/emscripten/SDL_sysjoystick_c.h rename to SDL2-2.30.5/src/joystick/emscripten/SDL_sysjoystick_c.h index 37a45b1..6e9b649 100644 --- a/SDL2-2.0.12/src/joystick/emscripten/SDL_sysjoystick_c.h +++ b/SDL2-2.30.5/src/joystick/emscripten/SDL_sysjoystick_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -24,25 +24,24 @@ #ifdef SDL_JOYSTICK_EMSCRIPTEN #include "../SDL_sysjoystick.h" - #include /* A linked list of available joysticks */ typedef struct SDL_joylist_item { - int index; - char *name; - char *mapping; - SDL_JoystickID device_instance; - SDL_Joystick *joystick; - int nbuttons; - int naxes; - double timestamp; - double axis[64]; - double analogButton[64]; - EM_BOOL digitalButton[64]; + int index; + char *name; + char *mapping; + SDL_JoystickID device_instance; + SDL_Joystick *joystick; + int nbuttons; + int naxes; + double timestamp; + double axis[64]; + double analogButton[64]; + EM_BOOL digitalButton[64]; - struct SDL_joylist_item *next; + struct SDL_joylist_item *next; } SDL_joylist_item; typedef SDL_joylist_item joystick_hwdata; diff --git a/SDL2-2.0.12/src/joystick/haiku/SDL_haikujoystick.cc b/SDL2-2.30.5/src/joystick/haiku/SDL_haikujoystick.cc similarity index 75% rename from SDL2-2.0.12/src/joystick/haiku/SDL_haikujoystick.cc rename to SDL2-2.30.5/src/joystick/haiku/SDL_haikujoystick.cc index ae8754e..5c31363 100644 --- a/SDL2-2.0.12/src/joystick/haiku/SDL_haikujoystick.cc +++ b/SDL2-2.30.5/src/joystick/haiku/SDL_haikujoystick.cc @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -64,18 +64,17 @@ extern "C" char name[B_OS_NAME_LENGTH]; /* Search for attached joysticks */ - nports = joystick.CountDevices(); - numjoysticks = 0; - SDL_memset(SDL_joyport, 0, (sizeof SDL_joyport)); - SDL_memset(SDL_joyname, 0, (sizeof SDL_joyname)); - for (i = 0; (numjoysticks < MAX_JOYSTICKS) && (i < nports); ++i) - { + nports = joystick.CountDevices(); + numjoysticks = 0; + SDL_memset(SDL_joyport, 0, sizeof(SDL_joyport)); + SDL_memset(SDL_joyname, 0, sizeof(SDL_joyname)); + for (i = 0; (numjoysticks < MAX_JOYSTICKS) && (i < nports); ++i) { if (joystick.GetDeviceName(i, name) == B_OK) { if (joystick.Open(name) != B_ERROR) { - BString stick_name; + BString stick_name; joystick.GetControllerName(&stick_name); SDL_joyport[numjoysticks] = SDL_strdup(name); - SDL_joyname[numjoysticks] = SDL_strdup(stick_name.String()); + SDL_joyname[numjoysticks] = SDL_CreateJoystickName(0, 0, NULL, stick_name.String()); numjoysticks++; joystick.Close(); } @@ -93,18 +92,27 @@ extern "C" { } -/* Function to get the device-dependent name of a joystick */ static const char *HAIKU_JoystickGetDeviceName(int device_index) { return SDL_joyname[device_index]; } + static const char *HAIKU_JoystickGetDevicePath(int device_index) + { + return SDL_joyport[device_index]; + } + + static int HAIKU_JoystickGetDeviceSteamVirtualGamepadSlot(int device_index) + { + return -1; + } + static int HAIKU_JoystickGetDevicePlayerIndex(int device_index) { return -1; } - static void HAIKU_JoystickGetDevicePlayerIndex(int device_index, int player_index) + static void HAIKU_JoystickSetDevicePlayerIndex(int device_index, int player_index) { } @@ -114,14 +122,14 @@ extern "C" return device_index; } - static void HAIKU_JoystickClose(SDL_Joystick * joystick); + static void HAIKU_JoystickClose(SDL_Joystick *joystick); /* Function to open a joystick for use. The joystick to open is specified by the device index. This should fill the nbuttons and naxes fields of the joystick structure. It returns 0, or -1 if there is an error. */ - static int HAIKU_JoystickOpen(SDL_Joystick * joystick, int device_index) + static int HAIKU_JoystickOpen(SDL_Joystick *joystick, int device_index) { BJoystick *stick; @@ -168,7 +176,7 @@ extern "C" * but instead should call SDL_PrivateJoystick*() to deliver events * and update joystick device state. */ - static void HAIKU_JoystickUpdate(SDL_Joystick * joystick) + static void HAIKU_JoystickUpdate(SDL_Joystick *joystick) { static const Uint8 hat_map[9] = { SDL_HAT_CENTERED, @@ -217,7 +225,7 @@ extern "C" } /* Function to close a joystick after use */ - static void HAIKU_JoystickClose(SDL_Joystick * joystick) + static void HAIKU_JoystickClose(SDL_Joystick *joystick) { if (joystick->hwdata) { joystick->hwdata->stick->Close(); @@ -244,17 +252,47 @@ extern "C" SDL_joyname[0] = NULL; } - static SDL_JoystickGUID HAIKU_JoystickGetDeviceGUID( int device_index ) + static SDL_JoystickGUID HAIKU_JoystickGetDeviceGUID(int device_index) { - SDL_JoystickGUID guid; - /* the GUID is just the first 16 chars of the name for now */ - const char *name = HAIKU_JoystickGetDeviceName( device_index ); - SDL_zero( guid ); - SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) ); - return guid; + /* the GUID is just the name for now */ + const char *name = HAIKU_JoystickGetDeviceName(device_index); + return SDL_CreateJoystickGUIDForName(name); } - static int HAIKU_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) + static int HAIKU_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) + { + return SDL_Unsupported(); + } + + + static int HAIKU_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) + { + return SDL_Unsupported(); + } + + static SDL_bool + HAIKU_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) + { + return SDL_FALSE; + } + + static Uint32 HAIKU_JoystickGetCapabilities(SDL_Joystick *joystick) + { + return 0; + } + + static int HAIKU_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) + { + return SDL_Unsupported(); + } + + + static int HAIKU_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) + { + return SDL_Unsupported(); + } + + static int HAIKU_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled) { return SDL_Unsupported(); } @@ -265,15 +303,23 @@ extern "C" HAIKU_JoystickGetCount, HAIKU_JoystickDetect, HAIKU_JoystickGetDeviceName, + HAIKU_JoystickGetDevicePath, + HAIKU_JoystickGetDeviceSteamVirtualGamepadSlot, HAIKU_JoystickGetDevicePlayerIndex, HAIKU_JoystickSetDevicePlayerIndex, HAIKU_JoystickGetDeviceGUID, HAIKU_JoystickGetDeviceInstanceID, HAIKU_JoystickOpen, HAIKU_JoystickRumble, + HAIKU_JoystickRumbleTriggers, + HAIKU_JoystickGetCapabilities, + HAIKU_JoystickSetLED, + HAIKU_JoystickSendEffect, + HAIKU_JoystickSetSensorsEnabled, HAIKU_JoystickUpdate, HAIKU_JoystickClose, HAIKU_JoystickQuit, + HAIKU_JoystickGetGamepadMapping }; } // extern "C" diff --git a/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_combined.c b/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_combined.c new file mode 100644 index 0000000..94ab75c --- /dev/null +++ b/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_combined.c @@ -0,0 +1,238 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ +/* This driver supports the Nintendo Switch Joy-Cons pair controllers */ +#include "../../SDL_internal.h" + +#ifdef SDL_JOYSTICK_HIDAPI + +#include "SDL_joystick.h" +#include "SDL_gamecontroller.h" +#include "SDL_hidapijoystick_c.h" +#include "../SDL_sysjoystick.h" + +static void HIDAPI_DriverCombined_RegisterHints(SDL_HintCallback callback, void *userdata) +{ +} + +static void HIDAPI_DriverCombined_UnregisterHints(SDL_HintCallback callback, void *userdata) +{ +} + +static SDL_bool HIDAPI_DriverCombined_IsEnabled(void) +{ + return SDL_TRUE; +} + +static SDL_bool HIDAPI_DriverCombined_IsSupportedDevice(SDL_HIDAPI_Device *device, const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol) +{ + /* This is always explicitly created for combined devices */ + return SDL_FALSE; +} + +static SDL_bool HIDAPI_DriverCombined_InitDevice(SDL_HIDAPI_Device *device) +{ + return HIDAPI_JoystickConnected(device, NULL); +} + +static int HIDAPI_DriverCombined_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id) +{ + return -1; +} + +static void HIDAPI_DriverCombined_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index) +{ +} + +static SDL_bool HIDAPI_DriverCombined_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + int i; + char *serial = NULL, *new_serial; + size_t serial_length = 0, new_length; + + SDL_AssertJoysticksLocked(); + + for (i = 0; i < device->num_children; ++i) { + SDL_HIDAPI_Device *child = device->children[i]; + if (!child->driver->OpenJoystick(child, joystick)) { + while (i-- > 0) { + child = device->children[i]; + child->driver->CloseJoystick(child, joystick); + } + if (serial) { + SDL_free(serial); + } + return SDL_FALSE; + } + + /* Extend the serial number with the child serial number */ + if (joystick->serial) { + new_length = serial_length + 1 + SDL_strlen(joystick->serial); + new_serial = (char *)SDL_realloc(serial, new_length); + if (new_serial) { + if (serial) { + SDL_strlcat(new_serial, ",", new_length); + SDL_strlcat(new_serial, joystick->serial, new_length); + } else { + SDL_strlcpy(new_serial, joystick->serial, new_length); + } + serial = new_serial; + serial_length = new_length; + } + SDL_free(joystick->serial); + joystick->serial = NULL; + } + } + + /* Update the joystick with the combined serial numbers */ + if (joystick->serial) { + SDL_free(joystick->serial); + } + joystick->serial = serial; + + return SDL_TRUE; +} + +static int HIDAPI_DriverCombined_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ + int i; + int result = -1; + + for (i = 0; i < device->num_children; ++i) { + SDL_HIDAPI_Device *child = device->children[i]; + if (child->driver->RumbleJoystick(child, joystick, low_frequency_rumble, high_frequency_rumble) == 0) { + result = 0; + } + } + return result; +} + +static int HIDAPI_DriverCombined_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) +{ + int i; + int result = -1; + + for (i = 0; i < device->num_children; ++i) { + SDL_HIDAPI_Device *child = device->children[i]; + if (child->driver->RumbleJoystickTriggers(child, joystick, left_rumble, right_rumble) == 0) { + result = 0; + } + } + return result; +} + +static Uint32 HIDAPI_DriverCombined_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + int i; + Uint32 caps = 0; + + for (i = 0; i < device->num_children; ++i) { + SDL_HIDAPI_Device *child = device->children[i]; + caps |= child->driver->GetJoystickCapabilities(child, joystick); + } + return caps; +} + +static int HIDAPI_DriverCombined_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + int i; + int result = -1; + + for (i = 0; i < device->num_children; ++i) { + SDL_HIDAPI_Device *child = device->children[i]; + if (child->driver->SetJoystickLED(child, joystick, red, green, blue) == 0) { + result = 0; + } + } + return result; +} + +static int HIDAPI_DriverCombined_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + +static int HIDAPI_DriverCombined_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled) +{ + int i; + int result = -1; + + for (i = 0; i < device->num_children; ++i) { + SDL_HIDAPI_Device *child = device->children[i]; + if (child->driver->SetJoystickSensorsEnabled(child, joystick, enabled) == 0) { + result = 0; + } + } + return result; +} + +static SDL_bool HIDAPI_DriverCombined_UpdateDevice(SDL_HIDAPI_Device *device) +{ + int i; + int result = SDL_TRUE; + + for (i = 0; i < device->num_children; ++i) { + SDL_HIDAPI_Device *child = device->children[i]; + if (!child->driver->UpdateDevice(child)) { + result = SDL_FALSE; + } + } + return result; +} + +static void HIDAPI_DriverCombined_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + int i; + + for (i = 0; i < device->num_children; ++i) { + SDL_HIDAPI_Device *child = device->children[i]; + child->driver->CloseJoystick(child, joystick); + } +} + +static void HIDAPI_DriverCombined_FreeDevice(SDL_HIDAPI_Device *device) +{ +} + +SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverCombined = { + "SDL_JOYSTICK_HIDAPI_COMBINED", + SDL_TRUE, + HIDAPI_DriverCombined_RegisterHints, + HIDAPI_DriverCombined_UnregisterHints, + HIDAPI_DriverCombined_IsEnabled, + HIDAPI_DriverCombined_IsSupportedDevice, + HIDAPI_DriverCombined_InitDevice, + HIDAPI_DriverCombined_GetDevicePlayerIndex, + HIDAPI_DriverCombined_SetDevicePlayerIndex, + HIDAPI_DriverCombined_UpdateDevice, + HIDAPI_DriverCombined_OpenJoystick, + HIDAPI_DriverCombined_RumbleJoystick, + HIDAPI_DriverCombined_RumbleJoystickTriggers, + HIDAPI_DriverCombined_GetJoystickCapabilities, + HIDAPI_DriverCombined_SetJoystickLED, + HIDAPI_DriverCombined_SendJoystickEffect, + HIDAPI_DriverCombined_SetJoystickSensorsEnabled, + HIDAPI_DriverCombined_CloseJoystick, + HIDAPI_DriverCombined_FreeDevice, +}; + +#endif /* SDL_JOYSTICK_HIDAPI */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_gamecube.c b/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_gamecube.c new file mode 100644 index 0000000..53d40b9 --- /dev/null +++ b/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_gamecube.c @@ -0,0 +1,559 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_JOYSTICK_HIDAPI + +#include "SDL_events.h" +#include "SDL_timer.h" +#include "SDL_haptic.h" +#include "SDL_joystick.h" +#include "SDL_gamecontroller.h" +#include "../../SDL_hints_c.h" +#include "../SDL_sysjoystick.h" +#include "SDL_hidapijoystick_c.h" +#include "SDL_hidapi_rumble.h" +#include "../../hidapi/SDL_hidapi_c.h" + +#ifdef SDL_JOYSTICK_HIDAPI_GAMECUBE + +/* Define this if you want to log all packets from the controller */ +/*#define DEBUG_GAMECUBE_PROTOCOL*/ + +#define MAX_CONTROLLERS 4 + +typedef struct +{ + SDL_bool pc_mode; + SDL_JoystickID joysticks[MAX_CONTROLLERS]; + Uint8 wireless[MAX_CONTROLLERS]; + Uint8 min_axis[MAX_CONTROLLERS * SDL_CONTROLLER_AXIS_MAX]; + Uint8 max_axis[MAX_CONTROLLERS * SDL_CONTROLLER_AXIS_MAX]; + Uint8 rumbleAllowed[MAX_CONTROLLERS]; + Uint8 rumble[1 + MAX_CONTROLLERS]; + /* Without this variable, hid_write starts to lag a TON */ + SDL_bool rumbleUpdate; + SDL_bool m_bUseButtonLabels; + SDL_bool useRumbleBrake; +} SDL_DriverGameCube_Context; + +static void HIDAPI_DriverGameCube_RegisterHints(SDL_HintCallback callback, void *userdata) +{ + SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_GAMECUBE, callback, userdata); +} + +static void HIDAPI_DriverGameCube_UnregisterHints(SDL_HintCallback callback, void *userdata) +{ + SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_GAMECUBE, callback, userdata); +} + +static SDL_bool HIDAPI_DriverGameCube_IsEnabled(void) +{ + return SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_GAMECUBE, + SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI, + SDL_HIDAPI_DEFAULT)); +} + +static SDL_bool HIDAPI_DriverGameCube_IsSupportedDevice(SDL_HIDAPI_Device *device, const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol) +{ + if (vendor_id == USB_VENDOR_NINTENDO && product_id == USB_PRODUCT_NINTENDO_GAMECUBE_ADAPTER) { + /* Nintendo Co., Ltd. Wii U GameCube Controller Adapter */ + return SDL_TRUE; + } + if (vendor_id == USB_VENDOR_DRAGONRISE && + (product_id == USB_PRODUCT_EVORETRO_GAMECUBE_ADAPTER1 || + product_id == USB_PRODUCT_EVORETRO_GAMECUBE_ADAPTER2)) { + /* EVORETRO GameCube Controller Adapter */ + return SDL_TRUE; + } + return SDL_FALSE; +} + +static void ResetAxisRange(SDL_DriverGameCube_Context *ctx, int joystick_index) +{ + SDL_memset(&ctx->min_axis[joystick_index * SDL_CONTROLLER_AXIS_MAX], 128 - 88, SDL_CONTROLLER_AXIS_MAX); + SDL_memset(&ctx->max_axis[joystick_index * SDL_CONTROLLER_AXIS_MAX], 128 + 88, SDL_CONTROLLER_AXIS_MAX); + + /* Trigger axes may have a higher resting value */ + ctx->min_axis[joystick_index * SDL_CONTROLLER_AXIS_MAX + SDL_CONTROLLER_AXIS_TRIGGERLEFT] = 40; + ctx->min_axis[joystick_index * SDL_CONTROLLER_AXIS_MAX + SDL_CONTROLLER_AXIS_TRIGGERRIGHT] = 40; +} + +static void SDLCALL SDL_GameControllerButtonReportingHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + SDL_DriverGameCube_Context *ctx = (SDL_DriverGameCube_Context *)userdata; + ctx->m_bUseButtonLabels = SDL_GetStringBoolean(hint, SDL_TRUE); +} + +static void SDLCALL SDL_JoystickGameCubeRumbleBrakeHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + if (hint) { + SDL_DriverGameCube_Context *ctx = (SDL_DriverGameCube_Context *)userdata; + ctx->useRumbleBrake = SDL_GetStringBoolean(hint, SDL_FALSE); + } +} + +static Uint8 RemapButton(SDL_DriverGameCube_Context *ctx, Uint8 button) +{ + if (!ctx->m_bUseButtonLabels) { + /* Use button positions */ + switch (button) { + case SDL_CONTROLLER_BUTTON_B: + return SDL_CONTROLLER_BUTTON_X; + case SDL_CONTROLLER_BUTTON_X: + return SDL_CONTROLLER_BUTTON_B; + default: + break; + } + } + return button; +} + +static SDL_bool HIDAPI_DriverGameCube_InitDevice(SDL_HIDAPI_Device *device) +{ + SDL_DriverGameCube_Context *ctx; + Uint8 packet[37]; + Uint8 *curSlot; + Uint8 i; + int size; + Uint8 initMagic = 0x13; + Uint8 rumbleMagic = 0x11; + +#ifdef HAVE_ENABLE_GAMECUBE_ADAPTORS + SDL_EnableGameCubeAdaptors(); +#endif + + ctx = (SDL_DriverGameCube_Context *)SDL_calloc(1, sizeof(*ctx)); + if (!ctx) { + SDL_OutOfMemory(); + return SDL_FALSE; + } + device->context = ctx; + + ctx->joysticks[0] = -1; + ctx->joysticks[1] = -1; + ctx->joysticks[2] = -1; + ctx->joysticks[3] = -1; + ctx->rumble[0] = rumbleMagic; + ctx->useRumbleBrake = SDL_FALSE; + + if (device->vendor_id != USB_VENDOR_NINTENDO) { + ctx->pc_mode = SDL_TRUE; + } + + if (ctx->pc_mode) { + for (i = 0; i < MAX_CONTROLLERS; ++i) { + ResetAxisRange(ctx, i); + HIDAPI_JoystickConnected(device, &ctx->joysticks[i]); + } + } else { + /* This is all that's needed to initialize the device. Really! */ + if (SDL_hid_write(device->dev, &initMagic, sizeof(initMagic)) != sizeof(initMagic)) { + SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, + "HIDAPI_DriverGameCube_InitDevice(): Couldn't initialize WUP-028"); + return SDL_FALSE; + } + + /* Wait for the adapter to initialize */ + SDL_Delay(10); + + /* Add all the applicable joysticks */ + while ((size = SDL_hid_read_timeout(device->dev, packet, sizeof(packet), 0)) > 0) { +#ifdef DEBUG_GAMECUBE_PROTOCOL + HIDAPI_DumpPacket("Nintendo GameCube packet: size = %d", packet, size); +#endif + if (size < 37 || packet[0] != 0x21) { + continue; /* Nothing to do yet...? */ + } + + /* Go through all 4 slots */ + curSlot = packet + 1; + for (i = 0; i < MAX_CONTROLLERS; i += 1, curSlot += 9) { + ctx->wireless[i] = (curSlot[0] & 0x20) != 0; + + /* Only allow rumble if the adapter's second USB cable is connected */ + ctx->rumbleAllowed[i] = (curSlot[0] & 0x04) && !ctx->wireless[i]; + + if (curSlot[0] & 0x30) { /* 0x10 - Wired, 0x20 - Wireless */ + if (ctx->joysticks[i] == -1) { + ResetAxisRange(ctx, i); + HIDAPI_JoystickConnected(device, &ctx->joysticks[i]); + } + } else { + if (ctx->joysticks[i] != -1) { + HIDAPI_JoystickDisconnected(device, ctx->joysticks[i]); + ctx->joysticks[i] = -1; + } + continue; + } + } + } + } + + SDL_AddHintCallback(SDL_HINT_JOYSTICK_GAMECUBE_RUMBLE_BRAKE, + SDL_JoystickGameCubeRumbleBrakeHintChanged, ctx); + SDL_AddHintCallback(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS, + SDL_GameControllerButtonReportingHintChanged, ctx); + + HIDAPI_SetDeviceName(device, "Nintendo GameCube Controller"); + + return SDL_TRUE; +} + +static int HIDAPI_DriverGameCube_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id) +{ + SDL_DriverGameCube_Context *ctx = (SDL_DriverGameCube_Context *)device->context; + Uint8 i; + + for (i = 0; i < 4; ++i) { + if (instance_id == ctx->joysticks[i]) { + return i; + } + } + return -1; +} + +static void HIDAPI_DriverGameCube_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index) +{ +} + +static void HIDAPI_DriverGameCube_HandleJoystickPacket(SDL_HIDAPI_Device *device, SDL_DriverGameCube_Context *ctx, const Uint8 *packet, int size) +{ + SDL_Joystick *joystick; + Uint8 i, v; + Sint16 axis_value; + + if (size != 10) { + return; /* How do we handle this packet? */ + } + + i = packet[0] - 1; + if (i >= MAX_CONTROLLERS) { + return; /* How do we handle this packet? */ + } + + joystick = SDL_JoystickFromInstanceID(ctx->joysticks[i]); + if (!joystick) { + /* Hasn't been opened yet, skip */ + return; + } + +#define READ_BUTTON(off, flag, button) \ + SDL_PrivateJoystickButton( \ + joystick, \ + RemapButton(ctx, button), \ + (packet[off] & flag) ? SDL_PRESSED : SDL_RELEASED); + READ_BUTTON(1, 0x02, 0) /* A */ + READ_BUTTON(1, 0x04, 1) /* B */ + READ_BUTTON(1, 0x01, 2) /* X */ + READ_BUTTON(1, 0x08, 3) /* Y */ + READ_BUTTON(2, 0x80, 4) /* DPAD_LEFT */ + READ_BUTTON(2, 0x20, 5) /* DPAD_RIGHT */ + READ_BUTTON(2, 0x40, 6) /* DPAD_DOWN */ + READ_BUTTON(2, 0x10, 7) /* DPAD_UP */ + READ_BUTTON(2, 0x02, 8) /* START */ + READ_BUTTON(1, 0x80, 9) /* RIGHTSHOULDER */ + /* These two buttons are for the bottoms of the analog triggers. + * More than likely, you're going to want to read the axes instead! + * -flibit + */ + READ_BUTTON(1, 0x20, 10) /* TRIGGERRIGHT */ + READ_BUTTON(1, 0x10, 11) /* TRIGGERLEFT */ +#undef READ_BUTTON + +#define READ_AXIS(off, axis, invert) \ + v = invert ? (0xff - packet[off]) : packet[off]; \ + if (v < ctx->min_axis[i * SDL_CONTROLLER_AXIS_MAX + axis]) \ + ctx->min_axis[i * SDL_CONTROLLER_AXIS_MAX + axis] = v; \ + if (v > ctx->max_axis[i * SDL_CONTROLLER_AXIS_MAX + axis]) \ + ctx->max_axis[i * SDL_CONTROLLER_AXIS_MAX + axis] = v; \ + axis_value = (Sint16)HIDAPI_RemapVal(v, ctx->min_axis[i * SDL_CONTROLLER_AXIS_MAX + axis], ctx->max_axis[i * SDL_CONTROLLER_AXIS_MAX + axis], SDL_MIN_SINT16, SDL_MAX_SINT16); \ + SDL_PrivateJoystickAxis( \ + joystick, \ + axis, axis_value); + READ_AXIS(3, SDL_CONTROLLER_AXIS_LEFTX, 0) + READ_AXIS(4, SDL_CONTROLLER_AXIS_LEFTY, 1) + READ_AXIS(6, SDL_CONTROLLER_AXIS_RIGHTX, 0) + READ_AXIS(5, SDL_CONTROLLER_AXIS_RIGHTY, 1) + READ_AXIS(7, SDL_CONTROLLER_AXIS_TRIGGERLEFT, 0) + READ_AXIS(8, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, 0) +#undef READ_AXIS +} + +static void HIDAPI_DriverGameCube_HandleNintendoPacket(SDL_HIDAPI_Device *device, SDL_DriverGameCube_Context *ctx, Uint8 *packet, int size) +{ + SDL_Joystick *joystick; + Uint8 *curSlot; + Uint8 i; + Sint16 axis_value; + + if (size < 37 || packet[0] != 0x21) { + return; /* Nothing to do right now...? */ + } + + /* Go through all 4 slots */ + curSlot = packet + 1; + for (i = 0; i < MAX_CONTROLLERS; i += 1, curSlot += 9) { + ctx->wireless[i] = (curSlot[0] & 0x20) != 0; + + /* Only allow rumble if the adapter's second USB cable is connected */ + ctx->rumbleAllowed[i] = (curSlot[0] & 0x04) && !ctx->wireless[i]; + + if (curSlot[0] & 0x30) { /* 0x10 - Wired, 0x20 - Wireless */ + if (ctx->joysticks[i] == -1) { + ResetAxisRange(ctx, i); + HIDAPI_JoystickConnected(device, &ctx->joysticks[i]); + } + joystick = SDL_JoystickFromInstanceID(ctx->joysticks[i]); + + /* Hasn't been opened yet, skip */ + if (!joystick) { + continue; + } + } else { + if (ctx->joysticks[i] != -1) { + HIDAPI_JoystickDisconnected(device, ctx->joysticks[i]); + ctx->joysticks[i] = -1; + } + continue; + } + +#define READ_BUTTON(off, flag, button) \ + SDL_PrivateJoystickButton( \ + joystick, \ + RemapButton(ctx, button), \ + (curSlot[off] & flag) ? SDL_PRESSED : SDL_RELEASED); + READ_BUTTON(1, 0x01, 0) /* A */ + READ_BUTTON(1, 0x02, 1) /* B */ + READ_BUTTON(1, 0x04, 2) /* X */ + READ_BUTTON(1, 0x08, 3) /* Y */ + READ_BUTTON(1, 0x10, 4) /* DPAD_LEFT */ + READ_BUTTON(1, 0x20, 5) /* DPAD_RIGHT */ + READ_BUTTON(1, 0x40, 6) /* DPAD_DOWN */ + READ_BUTTON(1, 0x80, 7) /* DPAD_UP */ + READ_BUTTON(2, 0x01, 8) /* START */ + READ_BUTTON(2, 0x02, 9) /* RIGHTSHOULDER */ + /* These two buttons are for the bottoms of the analog triggers. + * More than likely, you're going to want to read the axes instead! + * -flibit + */ + READ_BUTTON(2, 0x04, 10) /* TRIGGERRIGHT */ + READ_BUTTON(2, 0x08, 11) /* TRIGGERLEFT */ +#undef READ_BUTTON + +#define READ_AXIS(off, axis) \ + if (curSlot[off] < ctx->min_axis[i * SDL_CONTROLLER_AXIS_MAX + axis]) \ + ctx->min_axis[i * SDL_CONTROLLER_AXIS_MAX + axis] = curSlot[off]; \ + if (curSlot[off] > ctx->max_axis[i * SDL_CONTROLLER_AXIS_MAX + axis]) \ + ctx->max_axis[i * SDL_CONTROLLER_AXIS_MAX + axis] = curSlot[off]; \ + axis_value = (Sint16)HIDAPI_RemapVal(curSlot[off], ctx->min_axis[i * SDL_CONTROLLER_AXIS_MAX + axis], ctx->max_axis[i * SDL_CONTROLLER_AXIS_MAX + axis], SDL_MIN_SINT16, SDL_MAX_SINT16); \ + SDL_PrivateJoystickAxis( \ + joystick, \ + axis, axis_value); + READ_AXIS(3, SDL_CONTROLLER_AXIS_LEFTX) + READ_AXIS(4, SDL_CONTROLLER_AXIS_LEFTY) + READ_AXIS(5, SDL_CONTROLLER_AXIS_RIGHTX) + READ_AXIS(6, SDL_CONTROLLER_AXIS_RIGHTY) + READ_AXIS(7, SDL_CONTROLLER_AXIS_TRIGGERLEFT) + READ_AXIS(8, SDL_CONTROLLER_AXIS_TRIGGERRIGHT) +#undef READ_AXIS + } +} + +static SDL_bool HIDAPI_DriverGameCube_UpdateDevice(SDL_HIDAPI_Device *device) +{ + SDL_DriverGameCube_Context *ctx = (SDL_DriverGameCube_Context *)device->context; + Uint8 packet[USB_PACKET_LENGTH]; + int size; + + /* Read input packet */ + while ((size = SDL_hid_read_timeout(device->dev, packet, sizeof(packet), 0)) > 0) { +#ifdef DEBUG_GAMECUBE_PROTOCOL + HIDAPI_DumpPacket("Nintendo GameCube packet: size = %d", packet, size); +#endif + if (ctx->pc_mode) { + HIDAPI_DriverGameCube_HandleJoystickPacket(device, ctx, packet, size); + } else { + HIDAPI_DriverGameCube_HandleNintendoPacket(device, ctx, packet, size); + } + } + + /* Write rumble packet */ + if (ctx->rumbleUpdate) { + SDL_HIDAPI_SendRumble(device, ctx->rumble, sizeof(ctx->rumble)); + ctx->rumbleUpdate = SDL_FALSE; + } + + /* If we got here, nothing bad happened! */ + return SDL_TRUE; +} + +static SDL_bool HIDAPI_DriverGameCube_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_DriverGameCube_Context *ctx = (SDL_DriverGameCube_Context *)device->context; + Uint8 i; + + SDL_AssertJoysticksLocked(); + + for (i = 0; i < MAX_CONTROLLERS; i += 1) { + if (joystick->instance_id == ctx->joysticks[i]) { + joystick->nbuttons = 12; + joystick->naxes = SDL_CONTROLLER_AXIS_MAX; + joystick->epowerlevel = ctx->wireless[i] ? SDL_JOYSTICK_POWER_UNKNOWN : SDL_JOYSTICK_POWER_WIRED; + return SDL_TRUE; + } + } + return SDL_FALSE; /* Should never get here! */ +} + +static int HIDAPI_DriverGameCube_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ + SDL_DriverGameCube_Context *ctx = (SDL_DriverGameCube_Context *)device->context; + Uint8 i, val; + + SDL_AssertJoysticksLocked(); + + if (ctx->pc_mode) { + return SDL_Unsupported(); + } + + for (i = 0; i < MAX_CONTROLLERS; i += 1) { + if (joystick->instance_id == ctx->joysticks[i]) { + if (ctx->wireless[i]) { + return SDL_SetError("Nintendo GameCube WaveBird controllers do not support rumble"); + } + if (!ctx->rumbleAllowed[i]) { + return SDL_SetError("Second USB cable for WUP-028 not connected"); + } + if (ctx->useRumbleBrake) { + if (low_frequency_rumble == 0 && high_frequency_rumble > 0) { + val = 0; /* if only low is 0 we want to do a regular stop*/ + } else if (low_frequency_rumble == 0 && high_frequency_rumble == 0) { + val = 2; /* if both frequencies are 0 we want to do a hard stop */ + } else { + val = 1; /* normal rumble */ + } + } else { + val = (low_frequency_rumble > 0 || high_frequency_rumble > 0); + } + if (val != ctx->rumble[i + 1]) { + ctx->rumble[i + 1] = val; + ctx->rumbleUpdate = SDL_TRUE; + } + return 0; + } + } + + /* Should never get here! */ + return SDL_SetError("Couldn't find joystick"); +} + +static int HIDAPI_DriverGameCube_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) +{ + return SDL_Unsupported(); +} + +static Uint32 HIDAPI_DriverGameCube_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_DriverGameCube_Context *ctx = (SDL_DriverGameCube_Context *)device->context; + Uint32 result = 0; + + SDL_AssertJoysticksLocked(); + + if (!ctx->pc_mode) { + Uint8 i; + + for (i = 0; i < MAX_CONTROLLERS; i += 1) { + if (joystick->instance_id == ctx->joysticks[i]) { + if (!ctx->wireless[i] && ctx->rumbleAllowed[i]) { + result |= SDL_JOYCAP_RUMBLE; + break; + } + } + } + } + + return result; +} + +static int HIDAPI_DriverGameCube_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + return SDL_Unsupported(); +} + +static int HIDAPI_DriverGameCube_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + +static int HIDAPI_DriverGameCube_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled) +{ + return SDL_Unsupported(); +} + +static void HIDAPI_DriverGameCube_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_DriverGameCube_Context *ctx = (SDL_DriverGameCube_Context *)device->context; + + /* Stop rumble activity */ + if (ctx->rumbleUpdate) { + SDL_HIDAPI_SendRumble(device, ctx->rumble, sizeof(ctx->rumble)); + ctx->rumbleUpdate = SDL_FALSE; + } +} + +static void HIDAPI_DriverGameCube_FreeDevice(SDL_HIDAPI_Device *device) +{ + SDL_DriverGameCube_Context *ctx = (SDL_DriverGameCube_Context *)device->context; + + SDL_DelHintCallback(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS, + SDL_GameControllerButtonReportingHintChanged, ctx); + SDL_DelHintCallback(SDL_HINT_JOYSTICK_GAMECUBE_RUMBLE_BRAKE, + SDL_JoystickGameCubeRumbleBrakeHintChanged, ctx); +} + +SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverGameCube = { + SDL_HINT_JOYSTICK_HIDAPI_GAMECUBE, + SDL_TRUE, + HIDAPI_DriverGameCube_RegisterHints, + HIDAPI_DriverGameCube_UnregisterHints, + HIDAPI_DriverGameCube_IsEnabled, + HIDAPI_DriverGameCube_IsSupportedDevice, + HIDAPI_DriverGameCube_InitDevice, + HIDAPI_DriverGameCube_GetDevicePlayerIndex, + HIDAPI_DriverGameCube_SetDevicePlayerIndex, + HIDAPI_DriverGameCube_UpdateDevice, + HIDAPI_DriverGameCube_OpenJoystick, + HIDAPI_DriverGameCube_RumbleJoystick, + HIDAPI_DriverGameCube_RumbleJoystickTriggers, + HIDAPI_DriverGameCube_GetJoystickCapabilities, + HIDAPI_DriverGameCube_SetJoystickLED, + HIDAPI_DriverGameCube_SendJoystickEffect, + HIDAPI_DriverGameCube_SetJoystickSensorsEnabled, + HIDAPI_DriverGameCube_CloseJoystick, + HIDAPI_DriverGameCube_FreeDevice, +}; + +#endif /* SDL_JOYSTICK_HIDAPI_GAMECUBE */ + +#endif /* SDL_JOYSTICK_HIDAPI */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_luna.c b/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_luna.c new file mode 100644 index 0000000..e5557c5 --- /dev/null +++ b/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_luna.c @@ -0,0 +1,451 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_JOYSTICK_HIDAPI + +#include "SDL_events.h" +#include "SDL_joystick.h" +#include "SDL_gamecontroller.h" +#include "../SDL_sysjoystick.h" +#include "SDL_hidapijoystick_c.h" +#include "SDL_hidapi_rumble.h" + +#ifdef SDL_JOYSTICK_HIDAPI_LUNA + +/* Define this if you want to log all packets from the controller */ +/*#define DEBUG_LUNA_PROTOCOL*/ + +/* Sending rumble on macOS blocks for a long time and eventually fails */ +#if !defined(__MACOSX__) +#define ENABLE_LUNA_BLUETOOTH_RUMBLE +#endif + +enum +{ + SDL_CONTROLLER_BUTTON_LUNA_MIC = 15, + SDL_CONTROLLER_NUM_LUNA_BUTTONS, +}; + +typedef struct +{ + Uint8 last_state[USB_PACKET_LENGTH]; +} SDL_DriverLuna_Context; + +static void HIDAPI_DriverLuna_RegisterHints(SDL_HintCallback callback, void *userdata) +{ + SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_LUNA, callback, userdata); +} + +static void HIDAPI_DriverLuna_UnregisterHints(SDL_HintCallback callback, void *userdata) +{ + SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_LUNA, callback, userdata); +} + +static SDL_bool HIDAPI_DriverLuna_IsEnabled(void) +{ + return SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_LUNA, SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI, SDL_HIDAPI_DEFAULT)); +} + +static SDL_bool HIDAPI_DriverLuna_IsSupportedDevice(SDL_HIDAPI_Device *device, const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol) +{ + return (type == SDL_CONTROLLER_TYPE_AMAZON_LUNA) ? SDL_TRUE : SDL_FALSE; +} + +static SDL_bool HIDAPI_DriverLuna_InitDevice(SDL_HIDAPI_Device *device) +{ + SDL_DriverLuna_Context *ctx; + + ctx = (SDL_DriverLuna_Context *)SDL_calloc(1, sizeof(*ctx)); + if (!ctx) { + SDL_OutOfMemory(); + return SDL_FALSE; + } + device->context = ctx; + + device->type = SDL_CONTROLLER_TYPE_AMAZON_LUNA; + HIDAPI_SetDeviceName(device, "Amazon Luna Controller"); + + return HIDAPI_JoystickConnected(device, NULL); +} + +static int HIDAPI_DriverLuna_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id) +{ + return -1; +} + +static void HIDAPI_DriverLuna_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index) +{ +} + +static SDL_bool HIDAPI_DriverLuna_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_DriverLuna_Context *ctx = (SDL_DriverLuna_Context *)device->context; + + SDL_AssertJoysticksLocked(); + + SDL_zeroa(ctx->last_state); + + /* Initialize the joystick capabilities */ + joystick->nbuttons = SDL_CONTROLLER_NUM_LUNA_BUTTONS; + joystick->naxes = SDL_CONTROLLER_AXIS_MAX; + joystick->epowerlevel = SDL_JOYSTICK_POWER_FULL; + + return SDL_TRUE; +} + +static int HIDAPI_DriverLuna_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ +#ifdef ENABLE_LUNA_BLUETOOTH_RUMBLE + if (device->product_id == BLUETOOTH_PRODUCT_LUNA_CONTROLLER) { + /* Same packet as on Xbox One controllers connected via Bluetooth */ + Uint8 rumble_packet[] = { 0x03, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xEB }; + + /* Magnitude is 1..100 so scale the 16-bit input here */ + rumble_packet[4] = low_frequency_rumble / 655; + rumble_packet[5] = high_frequency_rumble / 655; + + if (SDL_HIDAPI_SendRumble(device, rumble_packet, sizeof(rumble_packet)) != sizeof(rumble_packet)) { + return SDL_SetError("Couldn't send rumble packet"); + } + + return 0; + } +#endif /* ENABLE_LUNA_BLUETOOTH_RUMBLE */ + + /* There is currently no rumble packet over USB */ + return SDL_Unsupported(); +} + +static int HIDAPI_DriverLuna_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) +{ + return SDL_Unsupported(); +} + +static Uint32 HIDAPI_DriverLuna_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + Uint32 result = 0; + +#ifdef ENABLE_LUNA_BLUETOOTH_RUMBLE + if (device->product_id == BLUETOOTH_PRODUCT_LUNA_CONTROLLER) { + result |= SDL_JOYCAP_RUMBLE; + } +#endif + + return result; +} + +static int HIDAPI_DriverLuna_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + return SDL_Unsupported(); +} + +static int HIDAPI_DriverLuna_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + +static int HIDAPI_DriverLuna_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled) +{ + return SDL_Unsupported(); +} + +static void HIDAPI_DriverLuna_HandleUSBStatePacket(SDL_Joystick *joystick, SDL_DriverLuna_Context *ctx, Uint8 *data, int size) +{ + if (ctx->last_state[1] != data[1]) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_A, (data[1] & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_B, (data[1] & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_X, (data[1] & 0x04) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_Y, (data[1] & 0x08) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data[1] & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data[1] & 0x20) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data[1] & 0x40) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, (data[1] & 0x80) ? SDL_PRESSED : SDL_RELEASED); + } + if (ctx->last_state[2] != data[2]) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data[2] & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LUNA_MIC, (data[2] & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (data[2] & 0x04) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data[2] & 0x08) ? SDL_PRESSED : SDL_RELEASED); + } + + if (ctx->last_state[3] != data[3]) { + SDL_bool dpad_up = SDL_FALSE; + SDL_bool dpad_down = SDL_FALSE; + SDL_bool dpad_left = SDL_FALSE; + SDL_bool dpad_right = SDL_FALSE; + + switch (data[3] & 0xf) { + case 0: + dpad_up = SDL_TRUE; + break; + case 1: + dpad_up = SDL_TRUE; + dpad_right = SDL_TRUE; + break; + case 2: + dpad_right = SDL_TRUE; + break; + case 3: + dpad_right = SDL_TRUE; + dpad_down = SDL_TRUE; + break; + case 4: + dpad_down = SDL_TRUE; + break; + case 5: + dpad_left = SDL_TRUE; + dpad_down = SDL_TRUE; + break; + case 6: + dpad_left = SDL_TRUE; + break; + case 7: + dpad_up = SDL_TRUE; + dpad_left = SDL_TRUE; + break; + default: + break; + } + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, dpad_down); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, dpad_up); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, dpad_right); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, dpad_left); + } + +#define READ_STICK_AXIS(offset) \ + (data[offset] == 0x7f ? 0 : (Sint16)HIDAPI_RemapVal((float)data[offset], 0x00, 0xff, SDL_MIN_SINT16, SDL_MAX_SINT16)) + { + Sint16 axis = READ_STICK_AXIS(4); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis); + axis = READ_STICK_AXIS(5); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, axis); + axis = READ_STICK_AXIS(6); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, axis); + axis = READ_STICK_AXIS(7); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis); + } +#undef READ_STICK_AXIS + +#define READ_TRIGGER_AXIS(offset) \ + (Sint16) HIDAPI_RemapVal((float)data[offset], 0x00, 0xff, SDL_MIN_SINT16, SDL_MAX_SINT16) + { + Sint16 axis = READ_TRIGGER_AXIS(8); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, axis); + axis = READ_TRIGGER_AXIS(9); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, axis); + } +#undef READ_TRIGGER_AXIS + + SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state))); +} + +static void HIDAPI_DriverLuna_HandleBluetoothStatePacket(SDL_Joystick *joystick, SDL_DriverLuna_Context *ctx, Uint8 *data, int size) +{ + if (size >= 2 && data[0] == 0x02) { + /* Home button has dedicated report */ + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data[1] & 0x1) ? SDL_PRESSED : SDL_RELEASED); + return; + } + + if (size >= 2 && data[0] == 0x04) { + /* Battery level report */ + int level = data[1] * 100 / 0xFF; + if (level == 0) { + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_EMPTY); + } else if (level <= 20) { + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_LOW); + } else if (level <= 70) { + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_MEDIUM); + } else { + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_FULL); + } + + return; + } + + if (size < 17 || data[0] != 0x01) { + /* We don't know how to handle this report */ + return; + } + + if (ctx->last_state[13] != data[13]) { + SDL_bool dpad_up = SDL_FALSE; + SDL_bool dpad_down = SDL_FALSE; + SDL_bool dpad_left = SDL_FALSE; + SDL_bool dpad_right = SDL_FALSE; + + switch (data[13] & 0xf) { + case 1: + dpad_up = SDL_TRUE; + break; + case 2: + dpad_up = SDL_TRUE; + dpad_right = SDL_TRUE; + break; + case 3: + dpad_right = SDL_TRUE; + break; + case 4: + dpad_right = SDL_TRUE; + dpad_down = SDL_TRUE; + break; + case 5: + dpad_down = SDL_TRUE; + break; + case 6: + dpad_left = SDL_TRUE; + dpad_down = SDL_TRUE; + break; + case 7: + dpad_left = SDL_TRUE; + break; + case 8: + dpad_up = SDL_TRUE; + dpad_left = SDL_TRUE; + break; + default: + break; + } + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, dpad_down); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, dpad_up); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, dpad_right); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, dpad_left); + } + + if (ctx->last_state[14] != data[14]) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_A, (data[14] & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_B, (data[14] & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_X, (data[14] & 0x08) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_Y, (data[14] & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data[14] & 0x40) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data[14] & 0x80) ? SDL_PRESSED : SDL_RELEASED); + } + if (ctx->last_state[15] != data[15]) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, (data[15] & 0x08) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (data[15] & 0x20) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data[15] & 0x40) ? SDL_PRESSED : SDL_RELEASED); + } + if (ctx->last_state[16] != data[16]) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data[16] & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LUNA_MIC, (data[16] & 0x02) ? SDL_PRESSED : SDL_RELEASED); + } + +#define READ_STICK_AXIS(offset) \ + (data[offset] == 0x7f ? 0 : (Sint16)HIDAPI_RemapVal((float)data[offset], 0x00, 0xff, SDL_MIN_SINT16, SDL_MAX_SINT16)) + { + Sint16 axis = READ_STICK_AXIS(2); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis); + axis = READ_STICK_AXIS(4); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, axis); + axis = READ_STICK_AXIS(6); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, axis); + axis = READ_STICK_AXIS(8); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis); + } +#undef READ_STICK_AXIS + +#define READ_TRIGGER_AXIS(offset) \ + (Sint16) HIDAPI_RemapVal((float)((int)(((data[offset] | (data[offset + 1] << 8)) & 0x3ff) - 0x200)), 0x00 - 0x200, 0x3ff - 0x200, SDL_MIN_SINT16, SDL_MAX_SINT16) + { + Sint16 axis = READ_TRIGGER_AXIS(9); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, axis); + axis = READ_TRIGGER_AXIS(11); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, axis); + } +#undef READ_TRIGGER_AXIS + + SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state))); +} + +static SDL_bool HIDAPI_DriverLuna_UpdateDevice(SDL_HIDAPI_Device *device) +{ + SDL_DriverLuna_Context *ctx = (SDL_DriverLuna_Context *)device->context; + SDL_Joystick *joystick = NULL; + Uint8 data[USB_PACKET_LENGTH]; + int size = 0; + + if (device->num_joysticks > 0) { + joystick = SDL_JoystickFromInstanceID(device->joysticks[0]); + } else { + return SDL_FALSE; + } + + while ((size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) { +#ifdef DEBUG_LUNA_PROTOCOL + HIDAPI_DumpPacket("Amazon Luna packet: size = %d", data, size); +#endif + if (!joystick) { + continue; + } + + switch (size) { + case 10: + HIDAPI_DriverLuna_HandleUSBStatePacket(joystick, ctx, data, size); + break; + default: + HIDAPI_DriverLuna_HandleBluetoothStatePacket(joystick, ctx, data, size); + break; + } + } + + if (size < 0) { + /* Read error, device is disconnected */ + HIDAPI_JoystickDisconnected(device, device->joysticks[0]); + } + return size >= 0; +} + +static void HIDAPI_DriverLuna_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ +} + +static void HIDAPI_DriverLuna_FreeDevice(SDL_HIDAPI_Device *device) +{ +} + +SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverLuna = { + SDL_HINT_JOYSTICK_HIDAPI_LUNA, + SDL_TRUE, + HIDAPI_DriverLuna_RegisterHints, + HIDAPI_DriverLuna_UnregisterHints, + HIDAPI_DriverLuna_IsEnabled, + HIDAPI_DriverLuna_IsSupportedDevice, + HIDAPI_DriverLuna_InitDevice, + HIDAPI_DriverLuna_GetDevicePlayerIndex, + HIDAPI_DriverLuna_SetDevicePlayerIndex, + HIDAPI_DriverLuna_UpdateDevice, + HIDAPI_DriverLuna_OpenJoystick, + HIDAPI_DriverLuna_RumbleJoystick, + HIDAPI_DriverLuna_RumbleJoystickTriggers, + HIDAPI_DriverLuna_GetJoystickCapabilities, + HIDAPI_DriverLuna_SetJoystickLED, + HIDAPI_DriverLuna_SendJoystickEffect, + HIDAPI_DriverLuna_SetJoystickSensorsEnabled, + HIDAPI_DriverLuna_CloseJoystick, + HIDAPI_DriverLuna_FreeDevice, +}; + +#endif /* SDL_JOYSTICK_HIDAPI_LUNA */ + +#endif /* SDL_JOYSTICK_HIDAPI */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_nintendo.h b/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_nintendo.h new file mode 100644 index 0000000..bd8459a --- /dev/null +++ b/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_nintendo.h @@ -0,0 +1,51 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +/* These are values used in the controller type byte of the controller GUID */ + +/* These values come directly out of the hardware, so don't change them */ +typedef enum +{ + k_eSwitchDeviceInfoControllerType_Unknown = 0, + k_eSwitchDeviceInfoControllerType_JoyConLeft = 1, + k_eSwitchDeviceInfoControllerType_JoyConRight = 2, + k_eSwitchDeviceInfoControllerType_ProController = 3, + k_eSwitchDeviceInfoControllerType_LicProController = 6, + k_eSwitchDeviceInfoControllerType_HVCLeft = 7, + k_eSwitchDeviceInfoControllerType_HVCRight = 8, + k_eSwitchDeviceInfoControllerType_NESLeft = 9, + k_eSwitchDeviceInfoControllerType_NESRight = 10, + k_eSwitchDeviceInfoControllerType_SNES = 11, + k_eSwitchDeviceInfoControllerType_N64 = 12, + k_eSwitchDeviceInfoControllerType_SEGA_Genesis = 13, +} ESwitchDeviceInfoControllerType; + +/* These values are used internally but can be updated as needed */ +typedef enum +{ + k_eWiiExtensionControllerType_Unknown = 0, + k_eWiiExtensionControllerType_None = 128, + k_eWiiExtensionControllerType_Nunchuk = 129, + k_eWiiExtensionControllerType_Gamepad = 130, + k_eWiiExtensionControllerType_WiiUPro = 131, +} EWiiExtensionControllerType; + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_ps3.c b/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_ps3.c new file mode 100644 index 0000000..1b10e9f --- /dev/null +++ b/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_ps3.c @@ -0,0 +1,1001 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_JOYSTICK_HIDAPI + +#include "SDL_hints.h" +#include "SDL_events.h" +#include "SDL_timer.h" +#include "SDL_joystick.h" +#include "SDL_gamecontroller.h" +#include "../../SDL_hints_c.h" +#include "../SDL_sysjoystick.h" +#include "SDL_hidapijoystick_c.h" +#include "SDL_hidapi_rumble.h" + +#ifdef SDL_JOYSTICK_HIDAPI_PS3 + +/* Define this if you want to log all packets from the controller */ +/*#define DEBUG_PS3_PROTOCOL*/ + +#define LOAD16(A, B) (Sint16)((Uint16)(A) | (((Uint16)(B)) << 8)) + +typedef enum +{ + k_EPS3ReportIdState = 1, + k_EPS3ReportIdEffects = 1, +} EPS3ReportId; + +typedef struct +{ + SDL_HIDAPI_Device *device; + SDL_Joystick *joystick; + SDL_bool is_shanwan; + SDL_bool report_sensors; + SDL_bool effects_updated; + int player_index; + Uint8 rumble_left; + Uint8 rumble_right; + Uint8 last_state[USB_PACKET_LENGTH]; +} SDL_DriverPS3_Context; + +static int HIDAPI_DriverPS3_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *effect, int size); + +static void HIDAPI_DriverPS3_RegisterHints(SDL_HintCallback callback, void *userdata) +{ + SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_PS3, callback, userdata); +} + +static void HIDAPI_DriverPS3_UnregisterHints(SDL_HintCallback callback, void *userdata) +{ + SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_PS3, callback, userdata); +} + +static SDL_bool HIDAPI_DriverPS3_IsEnabled(void) +{ + SDL_bool default_value; + +#if defined(__MACOSX__) + /* This works well on macOS */ + default_value = SDL_TRUE; +#elif defined(__WINDOWS__) + /* You can't initialize the controller with the stock Windows drivers + * See https://github.com/ViGEm/DsHidMini as an alternative driver + */ + default_value = SDL_FALSE; +#elif defined(__LINUX__) + /* Linux drivers do a better job of managing the transition between + * USB and Bluetooth. There are also some quirks in communicating + * with PS3 controllers that have been implemented in SDL's hidapi + * for libusb, but are not possible to support using hidraw if the + * kernel doesn't already know about them. + */ + default_value = SDL_FALSE; +#else + /* Untested, default off */ + default_value = SDL_FALSE; +#endif + + if (default_value) { + default_value = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI, SDL_HIDAPI_DEFAULT); + } + return SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_PS3, default_value); +} + +static SDL_bool HIDAPI_DriverPS3_IsSupportedDevice(SDL_HIDAPI_Device *device, const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol) +{ + if (vendor_id == USB_VENDOR_SONY && product_id == USB_PRODUCT_SONY_DS3) { + return SDL_TRUE; + } + if (vendor_id == USB_VENDOR_SHANWAN && product_id == USB_PRODUCT_SHANWAN_DS3) { + return SDL_TRUE; + } + return SDL_FALSE; +} + +static int ReadFeatureReport(SDL_hid_device *dev, Uint8 report_id, Uint8 *report, size_t length) +{ + SDL_memset(report, 0, length); + report[0] = report_id; + return SDL_hid_get_feature_report(dev, report, length); +} + +static int SendFeatureReport(SDL_hid_device *dev, Uint8 *report, size_t length) +{ + return SDL_hid_send_feature_report(dev, report, length); +} + +static SDL_bool HIDAPI_DriverPS3_InitDevice(SDL_HIDAPI_Device *device) +{ + SDL_DriverPS3_Context *ctx; + SDL_bool is_shanwan = SDL_FALSE; + + if (device->vendor_id == USB_VENDOR_SONY && + SDL_strncasecmp(device->name, "ShanWan", 7) == 0) { + is_shanwan = SDL_TRUE; + } + if (device->vendor_id == USB_VENDOR_SHANWAN || + device->vendor_id == USB_VENDOR_SHANWAN_ALT) { + is_shanwan = SDL_TRUE; + } + + ctx = (SDL_DriverPS3_Context *)SDL_calloc(1, sizeof(*ctx)); + if (!ctx) { + SDL_OutOfMemory(); + return SDL_FALSE; + } + ctx->device = device; + ctx->is_shanwan = is_shanwan; + + device->context = ctx; + + /* Set the controller into report mode over Bluetooth */ + { + Uint8 data[] = { 0xf4, 0x42, 0x03, 0x00, 0x00 }; + + SendFeatureReport(device->dev, data, sizeof(data)); + } + + /* Set the controller into report mode over USB */ + { + Uint8 data[USB_PACKET_LENGTH]; + + int size = ReadFeatureReport(device->dev, 0xf2, data, 17); + if (size < 0) { + SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, + "HIDAPI_DriverPS3_InitDevice(): Couldn't read feature report 0xf2"); + return SDL_FALSE; + } +#ifdef DEBUG_PS3_PROTOCOL + HIDAPI_DumpPacket("PS3 0xF2 packet: size = %d", data, size); +#endif + size = ReadFeatureReport(device->dev, 0xf5, data, 8); + if (size < 0) { + SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, + "HIDAPI_DriverPS3_InitDevice(): Couldn't read feature report 0xf5"); + return SDL_FALSE; + } +#ifdef DEBUG_PS3_PROTOCOL + HIDAPI_DumpPacket("PS3 0xF5 packet: size = %d", data, size); +#endif + if (!ctx->is_shanwan) { + /* An output report could cause ShanWan controllers to rumble non-stop */ + SDL_hid_write(device->dev, data, 1); + } + } + + device->type = SDL_CONTROLLER_TYPE_PS3; + HIDAPI_SetDeviceName(device, "PS3 Controller"); + + return HIDAPI_JoystickConnected(device, NULL); +} + +static int HIDAPI_DriverPS3_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id) +{ + return -1; +} + +static int HIDAPI_DriverPS3_UpdateEffects(SDL_HIDAPI_Device *device) +{ + SDL_DriverPS3_Context *ctx = (SDL_DriverPS3_Context *)device->context; + + Uint8 effects[] = { + 0x01, 0xff, 0x00, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0x27, 0x10, 0x00, 0x32, + 0xff, 0x27, 0x10, 0x00, 0x32, + 0xff, 0x27, 0x10, 0x00, 0x32, + 0xff, 0x27, 0x10, 0x00, 0x32, + 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + effects[2] = ctx->rumble_right ? 1 : 0; + effects[4] = ctx->rumble_left; + + effects[9] = (0x01 << (1 + (ctx->player_index % 4))); + + return HIDAPI_DriverPS3_SendJoystickEffect(device, ctx->joystick, effects, sizeof(effects)); +} + +static void HIDAPI_DriverPS3_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index) +{ + SDL_DriverPS3_Context *ctx = (SDL_DriverPS3_Context *)device->context; + + if (!ctx) { + return; + } + + ctx->player_index = player_index; + + /* This will set the new LED state based on the new player index */ + HIDAPI_DriverPS3_UpdateEffects(device); +} + +static SDL_bool HIDAPI_DriverPS3_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_DriverPS3_Context *ctx = (SDL_DriverPS3_Context *)device->context; + + SDL_AssertJoysticksLocked(); + + ctx->joystick = joystick; + ctx->effects_updated = SDL_FALSE; + ctx->rumble_left = 0; + ctx->rumble_right = 0; + SDL_zeroa(ctx->last_state); + + /* Initialize player index (needed for setting LEDs) */ + ctx->player_index = SDL_JoystickGetPlayerIndex(joystick); + + /* Initialize the joystick capabilities */ + joystick->nbuttons = 15; + joystick->naxes = 16; + joystick->epowerlevel = SDL_JOYSTICK_POWER_WIRED; + + SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, 100.0f); + + return SDL_TRUE; +} + +static int HIDAPI_DriverPS3_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ + SDL_DriverPS3_Context *ctx = (SDL_DriverPS3_Context *)device->context; + + ctx->rumble_left = (low_frequency_rumble >> 8); + ctx->rumble_right = (high_frequency_rumble >> 8); + + return HIDAPI_DriverPS3_UpdateEffects(device); +} + +static int HIDAPI_DriverPS3_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) +{ + return SDL_Unsupported(); +} + +static Uint32 HIDAPI_DriverPS3_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + return SDL_JOYCAP_RUMBLE; +} + +static int HIDAPI_DriverPS3_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + return SDL_Unsupported(); +} + +static int HIDAPI_DriverPS3_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *effect, int size) +{ + Uint8 data[49]; + int report_size, offset; + + SDL_zeroa(data); + + data[0] = k_EPS3ReportIdEffects; + report_size = sizeof(data); + offset = 1; + SDL_memcpy(&data[offset], effect, SDL_min((sizeof(data) - offset), (size_t)size)); + + if (SDL_HIDAPI_SendRumble(device, data, report_size) != report_size) { + return SDL_SetError("Couldn't send rumble packet"); + } + return 0; +} + +static int HIDAPI_DriverPS3_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled) +{ + SDL_DriverPS3_Context *ctx = (SDL_DriverPS3_Context *)device->context; + + ctx->report_sensors = enabled; + + return 0; +} + +static float HIDAPI_DriverPS3_ScaleAccel(Sint16 value) +{ + /* Accelerometer values are in big endian order */ + value = SDL_SwapBE16(value); + return ((float)(value - 511) / 113.0f) * SDL_STANDARD_GRAVITY; +} + +static void HIDAPI_DriverPS3_HandleMiniStatePacket(SDL_Joystick *joystick, SDL_DriverPS3_Context *ctx, Uint8 *data, int size) +{ + Sint16 axis; + + if (ctx->last_state[4] != data[4]) { + SDL_bool dpad_up = SDL_FALSE; + SDL_bool dpad_down = SDL_FALSE; + SDL_bool dpad_left = SDL_FALSE; + SDL_bool dpad_right = SDL_FALSE; + + switch (data[4] & 0x0f) { + case 0: + dpad_up = SDL_TRUE; + break; + case 1: + dpad_up = SDL_TRUE; + dpad_right = SDL_TRUE; + break; + case 2: + dpad_right = SDL_TRUE; + break; + case 3: + dpad_right = SDL_TRUE; + dpad_down = SDL_TRUE; + break; + case 4: + dpad_down = SDL_TRUE; + break; + case 5: + dpad_left = SDL_TRUE; + dpad_down = SDL_TRUE; + break; + case 6: + dpad_left = SDL_TRUE; + break; + case 7: + dpad_up = SDL_TRUE; + dpad_left = SDL_TRUE; + break; + default: + break; + } + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, dpad_down); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, dpad_up); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, dpad_right); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, dpad_left); + + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_Y, (data[4] & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_B, (data[4] & 0x20) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_A, (data[4] & 0x40) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_X, (data[4] & 0x80) ? SDL_PRESSED : SDL_RELEASED); + } + + if (ctx->last_state[5] != data[5]) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data[5] & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data[5] & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, (data[5] & 0x04) ? SDL_JOYSTICK_AXIS_MAX : SDL_JOYSTICK_AXIS_MIN); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, (data[5] & 0x08) ? SDL_JOYSTICK_AXIS_MAX : SDL_JOYSTICK_AXIS_MIN); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data[5] & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, (data[5] & 0x20) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (data[5] & 0x40) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data[5] & 0x80) ? SDL_PRESSED : SDL_RELEASED); + } + + axis = ((int)data[2] * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis); + axis = ((int)data[3] * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, axis); + axis = ((int)data[0] * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, axis); + axis = ((int)data[1] * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis); + + SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state))); +} + +static void HIDAPI_DriverPS3_HandleStatePacket(SDL_Joystick *joystick, SDL_DriverPS3_Context *ctx, Uint8 *data, int size) +{ + Sint16 axis; + + if (ctx->last_state[2] != data[2]) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data[2] & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (data[2] & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data[2] & 0x04) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, (data[2] & 0x08) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, (data[2] & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, (data[2] & 0x20) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, (data[2] & 0x40) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, (data[2] & 0x80) ? SDL_PRESSED : SDL_RELEASED); + } + + if (ctx->last_state[3] != data[3]) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data[3] & 0x04) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data[3] & 0x08) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_Y, (data[3] & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_B, (data[3] & 0x20) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_A, (data[3] & 0x40) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_X, (data[3] & 0x80) ? SDL_PRESSED : SDL_RELEASED); + } + + if (ctx->last_state[4] != data[4]) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data[4] & 0x01) ? SDL_PRESSED : SDL_RELEASED); + } + + axis = ((int)data[18] * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, axis); + axis = ((int)data[19] * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, axis); + axis = ((int)data[6] * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis); + axis = ((int)data[7] * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, axis); + axis = ((int)data[8] * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, axis); + axis = ((int)data[9] * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis); + + /* Buttons are mapped as axes in the order they appear in the button enumeration */ + { + static int button_axis_offsets[] = { + 24, /* SDL_CONTROLLER_BUTTON_A */ + 23, /* SDL_CONTROLLER_BUTTON_B */ + 25, /* SDL_CONTROLLER_BUTTON_X */ + 22, /* SDL_CONTROLLER_BUTTON_Y */ + 0, /* SDL_CONTROLLER_BUTTON_BACK */ + 0, /* SDL_CONTROLLER_BUTTON_GUIDE */ + 0, /* SDL_CONTROLLER_BUTTON_START */ + 0, /* SDL_CONTROLLER_BUTTON_LEFTSTICK */ + 0, /* SDL_CONTROLLER_BUTTON_RIGHTSTICK */ + 20, /* SDL_CONTROLLER_BUTTON_LEFTSHOULDER */ + 21, /* SDL_CONTROLLER_BUTTON_RIGHTSHOULDER */ + 14, /* SDL_CONTROLLER_BUTTON_DPAD_UP */ + 16, /* SDL_CONTROLLER_BUTTON_DPAD_DOWN */ + 17, /* SDL_CONTROLLER_BUTTON_DPAD_LEFT */ + 15, /* SDL_CONTROLLER_BUTTON_DPAD_RIGHT */ + }; + int i, axis_index = 6; + + for (i = 0; i < SDL_arraysize(button_axis_offsets); ++i) { + int offset = button_axis_offsets[i]; + if (!offset) { + /* This button doesn't report as an axis */ + continue; + } + + axis = ((int)data[offset] * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, axis_index, axis); + ++axis_index; + } + } + + if (ctx->report_sensors) { + float sensor_data[3]; + + sensor_data[0] = HIDAPI_DriverPS3_ScaleAccel(LOAD16(data[41], data[42])); + sensor_data[1] = -HIDAPI_DriverPS3_ScaleAccel(LOAD16(data[45], data[46])); + sensor_data[2] = -HIDAPI_DriverPS3_ScaleAccel(LOAD16(data[43], data[44])); + SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_ACCEL, 0, sensor_data, SDL_arraysize(sensor_data)); + } + + SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state))); +} + +static SDL_bool HIDAPI_DriverPS3_UpdateDevice(SDL_HIDAPI_Device *device) +{ + SDL_DriverPS3_Context *ctx = (SDL_DriverPS3_Context *)device->context; + SDL_Joystick *joystick = NULL; + Uint8 data[USB_PACKET_LENGTH]; + int size; + + if (device->num_joysticks > 0) { + joystick = SDL_JoystickFromInstanceID(device->joysticks[0]); + } else { + return SDL_FALSE; + } + + while ((size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) { +#ifdef DEBUG_PS3_PROTOCOL + HIDAPI_DumpPacket("PS3 packet: size = %d", data, size); +#endif + if (!joystick) { + continue; + } + + if (size == 7) { + /* Seen on a ShanWan PS2 -> PS3 USB converter */ + HIDAPI_DriverPS3_HandleMiniStatePacket(joystick, ctx, data, size); + + /* Wait for the first report to set the LED state after the controller stops blinking */ + if (!ctx->effects_updated) { + HIDAPI_DriverPS3_UpdateEffects(device); + ctx->effects_updated = SDL_TRUE; + } + continue; + } + + switch (data[0]) { + case k_EPS3ReportIdState: + if (data[1] == 0xFF) { + /* Invalid data packet, ignore */ + break; + } + HIDAPI_DriverPS3_HandleStatePacket(joystick, ctx, data, size); + + /* Wait for the first report to set the LED state after the controller stops blinking */ + if (!ctx->effects_updated) { + HIDAPI_DriverPS3_UpdateEffects(device); + ctx->effects_updated = SDL_TRUE; + } + break; + default: +#ifdef DEBUG_JOYSTICK + SDL_Log("Unknown PS3 packet: 0x%.2x\n", data[0]); +#endif + break; + } + } + + if (size < 0) { + /* Read error, device is disconnected */ + HIDAPI_JoystickDisconnected(device, device->joysticks[0]); + } + return size >= 0; +} + +static void HIDAPI_DriverPS3_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_DriverPS3_Context *ctx = (SDL_DriverPS3_Context *)device->context; + + ctx->joystick = NULL; +} + +static void HIDAPI_DriverPS3_FreeDevice(SDL_HIDAPI_Device *device) +{ +} + +SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS3 = { + SDL_HINT_JOYSTICK_HIDAPI_PS3, + SDL_TRUE, + HIDAPI_DriverPS3_RegisterHints, + HIDAPI_DriverPS3_UnregisterHints, + HIDAPI_DriverPS3_IsEnabled, + HIDAPI_DriverPS3_IsSupportedDevice, + HIDAPI_DriverPS3_InitDevice, + HIDAPI_DriverPS3_GetDevicePlayerIndex, + HIDAPI_DriverPS3_SetDevicePlayerIndex, + HIDAPI_DriverPS3_UpdateDevice, + HIDAPI_DriverPS3_OpenJoystick, + HIDAPI_DriverPS3_RumbleJoystick, + HIDAPI_DriverPS3_RumbleJoystickTriggers, + HIDAPI_DriverPS3_GetJoystickCapabilities, + HIDAPI_DriverPS3_SetJoystickLED, + HIDAPI_DriverPS3_SendJoystickEffect, + HIDAPI_DriverPS3_SetJoystickSensorsEnabled, + HIDAPI_DriverPS3_CloseJoystick, + HIDAPI_DriverPS3_FreeDevice, +}; + +static SDL_bool HIDAPI_DriverPS3ThirdParty_IsEnabled(void) +{ + return SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_PS3, + SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI, + SDL_HIDAPI_DEFAULT)); +} + +static SDL_bool HIDAPI_DriverPS3ThirdParty_IsSupportedDevice(SDL_HIDAPI_Device *device, const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol) +{ + Uint8 data[USB_PACKET_LENGTH]; + int size; + + if (vendor_id == USB_VENDOR_LOGITECH && + product_id == USB_PRODUCT_LOGITECH_CHILLSTREAM) { + return SDL_TRUE; + } + + if ((type == SDL_CONTROLLER_TYPE_PS3 && vendor_id != USB_VENDOR_SONY) || + HIDAPI_SupportsPlaystationDetection(vendor_id, product_id)) { + if (device && device->dev) { + size = ReadFeatureReport(device->dev, 0x03, data, sizeof(data)); + if (size == 8 && data[2] == 0x26) { + /* Supported third party controller */ + return SDL_TRUE; + } else { + return SDL_FALSE; + } + } else { + /* Might be supported by this driver, enumerate and find out */ + return SDL_TRUE; + } + } + return SDL_FALSE; +} + +static SDL_bool HIDAPI_DriverPS3ThirdParty_InitDevice(SDL_HIDAPI_Device *device) +{ + SDL_DriverPS3_Context *ctx; + + ctx = (SDL_DriverPS3_Context *)SDL_calloc(1, sizeof(*ctx)); + if (!ctx) { + SDL_OutOfMemory(); + return SDL_FALSE; + } + ctx->device = device; + + device->context = ctx; + + device->type = SDL_CONTROLLER_TYPE_PS3; + + if (device->vendor_id == USB_VENDOR_LOGITECH && + device->product_id == USB_PRODUCT_LOGITECH_CHILLSTREAM) { + HIDAPI_SetDeviceName(device, "Logitech ChillStream"); + } + + return HIDAPI_JoystickConnected(device, NULL); +} + +static int HIDAPI_DriverPS3ThirdParty_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id) +{ + return -1; +} + +static void HIDAPI_DriverPS3ThirdParty_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index) +{ +} + +static SDL_bool HIDAPI_DriverPS3ThirdParty_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_DriverPS3_Context *ctx = (SDL_DriverPS3_Context *)device->context; + + SDL_AssertJoysticksLocked(); + + ctx->joystick = joystick; + SDL_zeroa(ctx->last_state); + + /* Initialize the joystick capabilities */ + joystick->nbuttons = 15; + joystick->naxes = 16; + joystick->epowerlevel = SDL_JOYSTICK_POWER_WIRED; + + return SDL_TRUE; +} + +static int HIDAPI_DriverPS3ThirdParty_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ + return SDL_Unsupported(); +} + +static int HIDAPI_DriverPS3ThirdParty_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) +{ + return SDL_Unsupported(); +} + +static Uint32 HIDAPI_DriverPS3ThirdParty_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + return 0; +} + +static int HIDAPI_DriverPS3ThirdParty_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + return SDL_Unsupported(); +} + +static int HIDAPI_DriverPS3ThirdParty_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *effect, int size) +{ + return SDL_Unsupported(); +} + +static int HIDAPI_DriverPS3ThirdParty_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled) +{ + return SDL_Unsupported(); +} + +static void HIDAPI_DriverPS3ThirdParty_HandleStatePacket18(SDL_Joystick *joystick, SDL_DriverPS3_Context *ctx, Uint8 *data, int size) +{ + Sint16 axis; + + if (ctx->last_state[0] != data[0]) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_X, (data[0] & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_A, (data[0] & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_B, (data[0] & 0x04) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_Y, (data[0] & 0x08) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data[0] & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data[0] & 0x20) ? SDL_PRESSED : SDL_RELEASED); + } + + if (ctx->last_state[1] != data[1]) { + SDL_bool dpad_up = SDL_FALSE; + SDL_bool dpad_down = SDL_FALSE; + SDL_bool dpad_left = SDL_FALSE; + SDL_bool dpad_right = SDL_FALSE; + + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data[1] & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, (data[1] & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (data[1] & 0x04) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data[1] & 0x08) ? SDL_PRESSED : SDL_RELEASED); + + switch (data[1] >> 4) { + case 0: + dpad_up = SDL_TRUE; + break; + case 1: + dpad_up = SDL_TRUE; + dpad_right = SDL_TRUE; + break; + case 2: + dpad_right = SDL_TRUE; + break; + case 3: + dpad_right = SDL_TRUE; + dpad_down = SDL_TRUE; + break; + case 4: + dpad_down = SDL_TRUE; + break; + case 5: + dpad_left = SDL_TRUE; + dpad_down = SDL_TRUE; + break; + case 6: + dpad_left = SDL_TRUE; + break; + case 7: + dpad_up = SDL_TRUE; + dpad_left = SDL_TRUE; + break; + default: + break; + } + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, dpad_down); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, dpad_up); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, dpad_right); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, dpad_left); + } + + axis = ((int)data[16] * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, axis); + axis = ((int)data[17] * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, axis); + axis = ((int)data[2] * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis); + axis = ((int)data[3] * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, axis); + axis = ((int)data[4] * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, axis); + axis = ((int)data[5] * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis); + + /* Buttons are mapped as axes in the order they appear in the button enumeration */ + { + static int button_axis_offsets[] = { + 12, /* SDL_GAMEPAD_BUTTON_A */ + 11, /* SDL_GAMEPAD_BUTTON_B */ + 13, /* SDL_GAMEPAD_BUTTON_X */ + 10, /* SDL_GAMEPAD_BUTTON_Y */ + 0, /* SDL_GAMEPAD_BUTTON_BACK */ + 0, /* SDL_GAMEPAD_BUTTON_GUIDE */ + 0, /* SDL_GAMEPAD_BUTTON_START */ + 0, /* SDL_GAMEPAD_BUTTON_LEFT_STICK */ + 0, /* SDL_GAMEPAD_BUTTON_RIGHT_STICK */ + 14, /* SDL_GAMEPAD_BUTTON_LEFT_SHOULDER */ + 15, /* SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER */ + 8, /* SDL_GAMEPAD_BUTTON_DPAD_UP */ + 9, /* SDL_GAMEPAD_BUTTON_DPAD_DOWN */ + 7, /* SDL_GAMEPAD_BUTTON_DPAD_LEFT */ + 6, /* SDL_GAMEPAD_BUTTON_DPAD_RIGHT */ + }; + int i, axis_index = 6; + + for (i = 0; i < SDL_arraysize(button_axis_offsets); ++i) { + int offset = button_axis_offsets[i]; + if (!offset) { + /* This button doesn't report as an axis */ + continue; + } + + axis = ((int)data[offset] * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, axis_index, axis); + ++axis_index; + } + } + + SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state))); +} + +static void HIDAPI_DriverPS3ThirdParty_HandleStatePacket19(SDL_Joystick *joystick, SDL_DriverPS3_Context *ctx, Uint8 *data, int size) +{ + Sint16 axis; + + if (ctx->last_state[0] != data[0]) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_X, (data[0] & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_A, (data[0] & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_B, (data[0] & 0x04) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_Y, (data[0] & 0x08) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data[0] & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data[0] & 0x20) ? SDL_PRESSED : SDL_RELEASED); + } + + if (ctx->last_state[1] != data[1]) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data[1] & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, (data[1] & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (data[1] & 0x04) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data[1] & 0x08) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data[1] & 0x10) ? SDL_PRESSED : SDL_RELEASED); + } + + if (ctx->device->vendor_id == USB_VENDOR_SAITEK && ctx->device->product_id == USB_PRODUCT_SAITEK_CYBORG_V3) { + /* Cyborg V.3 Rumble Pad doesn't set the dpad bits as expected, so use the axes instead */ + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, data[10] ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, data[9] ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, data[7] ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, data[8] ? SDL_PRESSED : SDL_RELEASED); + } else { + if (ctx->last_state[2] != data[2]) { + SDL_bool dpad_up = SDL_FALSE; + SDL_bool dpad_down = SDL_FALSE; + SDL_bool dpad_left = SDL_FALSE; + SDL_bool dpad_right = SDL_FALSE; + + switch (data[2] & 0x0f) { + case 0: + dpad_up = SDL_TRUE; + break; + case 1: + dpad_up = SDL_TRUE; + dpad_right = SDL_TRUE; + break; + case 2: + dpad_right = SDL_TRUE; + break; + case 3: + dpad_right = SDL_TRUE; + dpad_down = SDL_TRUE; + break; + case 4: + dpad_down = SDL_TRUE; + break; + case 5: + dpad_left = SDL_TRUE; + dpad_down = SDL_TRUE; + break; + case 6: + dpad_left = SDL_TRUE; + break; + case 7: + dpad_up = SDL_TRUE; + dpad_left = SDL_TRUE; + break; + default: + break; + } + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, dpad_down); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, dpad_up); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, dpad_right); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, dpad_left); + } + } + + axis = ((int)data[17] * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, axis); + axis = ((int)data[18] * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, axis); + axis = ((int)data[3] * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis); + axis = ((int)data[4] * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, axis); + axis = ((int)data[5] * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, axis); + axis = ((int)data[6] * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis); + + /* Buttons are mapped as axes in the order they appear in the button enumeration */ + { + static int button_axis_offsets[] = { + 13, /* SDL_CONTROLLER_BUTTON_A */ + 12, /* SDL_CONTROLLER_BUTTON_B */ + 14, /* SDL_CONTROLLER_BUTTON_X */ + 11, /* SDL_CONTROLLER_BUTTON_Y */ + 0, /* SDL_CONTROLLER_BUTTON_BACK */ + 0, /* SDL_CONTROLLER_BUTTON_GUIDE */ + 0, /* SDL_CONTROLLER_BUTTON_START */ + 0, /* SDL_CONTROLLER_BUTTON_LEFTSTICK */ + 0, /* SDL_CONTROLLER_BUTTON_RIGHTSTICK */ + 15, /* SDL_CONTROLLER_BUTTON_LEFTSHOULDER */ + 16, /* SDL_CONTROLLER_BUTTON_RIGHTSHOULDER */ + 9, /* SDL_CONTROLLER_BUTTON_DPAD_UP */ + 10, /* SDL_CONTROLLER_BUTTON_DPAD_DOWN */ + 8, /* SDL_CONTROLLER_BUTTON_DPAD_LEFT */ + 7, /* SDL_CONTROLLER_BUTTON_DPAD_RIGHT */ + }; + int i, axis_index = 6; + + for (i = 0; i < SDL_arraysize(button_axis_offsets); ++i) { + int offset = button_axis_offsets[i]; + if (!offset) { + /* This button doesn't report as an axis */ + continue; + } + + axis = ((int)data[offset] * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, axis_index, axis); + ++axis_index; + } + } + + SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state))); +} + +static SDL_bool HIDAPI_DriverPS3ThirdParty_UpdateDevice(SDL_HIDAPI_Device *device) +{ + SDL_DriverPS3_Context *ctx = (SDL_DriverPS3_Context *)device->context; + SDL_Joystick *joystick = NULL; + Uint8 data[USB_PACKET_LENGTH]; + int size; + + if (device->num_joysticks > 0) { + joystick = SDL_JoystickFromInstanceID(device->joysticks[0]); + } else { + return SDL_FALSE; + } + + while ((size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) { +#ifdef DEBUG_PS3_PROTOCOL + HIDAPI_DumpPacket("PS3 packet: size = %d", data, size); +#endif + if (!joystick) { + continue; + } + + if (size >= 19) { + HIDAPI_DriverPS3ThirdParty_HandleStatePacket19(joystick, ctx, data, size); + } else if (size == 18) { + /* This packet format was seen with the Logitech ChillStream */ + HIDAPI_DriverPS3ThirdParty_HandleStatePacket18(joystick, ctx, data, size); + } else { +#ifdef DEBUG_JOYSTICK + SDL_Log("Unknown PS3 packet, size %d\n", size); +#endif + } + } + + if (size < 0) { + /* Read error, device is disconnected */ + HIDAPI_JoystickDisconnected(device, device->joysticks[0]); + } + return size >= 0; +} + +static void HIDAPI_DriverPS3ThirdParty_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_DriverPS3_Context *ctx = (SDL_DriverPS3_Context *)device->context; + + ctx->joystick = NULL; +} + +static void HIDAPI_DriverPS3ThirdParty_FreeDevice(SDL_HIDAPI_Device *device) +{ +} + +SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS3ThirdParty = { + SDL_HINT_JOYSTICK_HIDAPI_PS3, + SDL_TRUE, + HIDAPI_DriverPS3_RegisterHints, + HIDAPI_DriverPS3_UnregisterHints, + HIDAPI_DriverPS3ThirdParty_IsEnabled, + HIDAPI_DriverPS3ThirdParty_IsSupportedDevice, + HIDAPI_DriverPS3ThirdParty_InitDevice, + HIDAPI_DriverPS3ThirdParty_GetDevicePlayerIndex, + HIDAPI_DriverPS3ThirdParty_SetDevicePlayerIndex, + HIDAPI_DriverPS3ThirdParty_UpdateDevice, + HIDAPI_DriverPS3ThirdParty_OpenJoystick, + HIDAPI_DriverPS3ThirdParty_RumbleJoystick, + HIDAPI_DriverPS3ThirdParty_RumbleJoystickTriggers, + HIDAPI_DriverPS3ThirdParty_GetJoystickCapabilities, + HIDAPI_DriverPS3ThirdParty_SetJoystickLED, + HIDAPI_DriverPS3ThirdParty_SendJoystickEffect, + HIDAPI_DriverPS3ThirdParty_SetJoystickSensorsEnabled, + HIDAPI_DriverPS3ThirdParty_CloseJoystick, + HIDAPI_DriverPS3ThirdParty_FreeDevice, +}; + +#endif /* SDL_JOYSTICK_HIDAPI_PS3 */ + +#endif /* SDL_JOYSTICK_HIDAPI */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_ps4.c b/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_ps4.c new file mode 100644 index 0000000..565431d --- /dev/null +++ b/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_ps4.c @@ -0,0 +1,1290 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ +/* This driver supports both simplified reports and the extended input reports enabled by Steam. + Code and logic contributed by Valve Corporation under the SDL zlib license. +*/ +#include "../../SDL_internal.h" + +#ifdef SDL_JOYSTICK_HIDAPI + +#include "SDL_events.h" +#include "SDL_timer.h" +#include "SDL_joystick.h" +#include "SDL_gamecontroller.h" +#include "../../SDL_hints_c.h" +#include "../SDL_sysjoystick.h" +#include "SDL_hidapijoystick_c.h" +#include "SDL_hidapi_rumble.h" + +#ifdef SDL_JOYSTICK_HIDAPI_PS4 + +/* Define this if you want to log all packets from the controller */ +/*#define DEBUG_PS4_PROTOCOL*/ + +/* Define this if you want to log calibration data */ +/*#define DEBUG_PS4_CALIBRATION*/ + +#define BLUETOOTH_DISCONNECT_TIMEOUT_MS 500 + +#define LOAD16(A, B) (Sint16)((Uint16)(A) | (((Uint16)(B)) << 8)) +#define LOAD32(A, B, C, D) ((((Uint32)(A)) << 0) | \ + (((Uint32)(B)) << 8) | \ + (((Uint32)(C)) << 16) | \ + (((Uint32)(D)) << 24)) + +typedef enum +{ + k_EPS4ReportIdUsbState = 1, + k_EPS4ReportIdUsbEffects = 5, + k_EPS4ReportIdBluetoothState1 = 17, + k_EPS4ReportIdBluetoothState2 = 18, + k_EPS4ReportIdBluetoothState3 = 19, + k_EPS4ReportIdBluetoothState4 = 20, + k_EPS4ReportIdBluetoothState5 = 21, + k_EPS4ReportIdBluetoothState6 = 22, + k_EPS4ReportIdBluetoothState7 = 23, + k_EPS4ReportIdBluetoothState8 = 24, + k_EPS4ReportIdBluetoothState9 = 25, + k_EPS4ReportIdBluetoothEffects = 17, + k_EPS4ReportIdDisconnectMessage = 226, +} EPS4ReportId; + +typedef enum +{ + k_ePS4FeatureReportIdGyroCalibration_USB = 0x02, + k_ePS4FeatureReportIdCapabilities = 0x03, + k_ePS4FeatureReportIdGyroCalibration_BT = 0x05, + k_ePS4FeatureReportIdSerialNumber = 0x12, +} EPS4FeatureReportID; + +typedef struct +{ + Uint8 ucLeftJoystickX; + Uint8 ucLeftJoystickY; + Uint8 ucRightJoystickX; + Uint8 ucRightJoystickY; + Uint8 rgucButtonsHatAndCounter[3]; + Uint8 ucTriggerLeft; + Uint8 ucTriggerRight; + Uint8 rgucTimestamp[2]; + Uint8 _rgucPad0[1]; + Uint8 rgucGyroX[2]; + Uint8 rgucGyroY[2]; + Uint8 rgucGyroZ[2]; + Uint8 rgucAccelX[2]; + Uint8 rgucAccelY[2]; + Uint8 rgucAccelZ[2]; + Uint8 _rgucPad1[5]; + Uint8 ucBatteryLevel; + Uint8 _rgucPad2[4]; + Uint8 ucTouchpadCounter1; + Uint8 rgucTouchpadData1[3]; + Uint8 ucTouchpadCounter2; + Uint8 rgucTouchpadData2[3]; +} PS4StatePacket_t; + +typedef struct +{ + Uint8 ucRumbleRight; + Uint8 ucRumbleLeft; + Uint8 ucLedRed; + Uint8 ucLedGreen; + Uint8 ucLedBlue; + Uint8 ucLedDelayOn; + Uint8 ucLedDelayOff; + Uint8 _rgucPad0[8]; + Uint8 ucVolumeLeft; + Uint8 ucVolumeRight; + Uint8 ucVolumeMic; + Uint8 ucVolumeSpeaker; +} DS4EffectsState_t; + +typedef struct +{ + Sint16 bias; + float scale; +} IMUCalibrationData; + +typedef struct +{ + SDL_HIDAPI_Device *device; + SDL_Joystick *joystick; + SDL_bool is_dongle; + SDL_bool is_nacon_dongle; + SDL_bool official_controller; + SDL_bool sensors_supported; + SDL_bool lightbar_supported; + SDL_bool vibration_supported; + SDL_bool touchpad_supported; + SDL_bool effects_supported; + SDL_bool enhanced_mode; + SDL_bool report_sensors; + SDL_bool report_touchpad; + SDL_bool hardware_calibration; + IMUCalibrationData calibration[6]; + Uint32 last_packet; + int player_index; + Uint8 rumble_left; + Uint8 rumble_right; + SDL_bool color_set; + Uint8 led_red; + Uint8 led_green; + Uint8 led_blue; + Uint16 gyro_numerator; + Uint16 gyro_denominator; + Uint16 accel_numerator; + Uint16 accel_denominator; + Uint16 last_timestamp; + Uint64 timestamp; + Uint16 valid_crc_packets; /* wrapping counter */ + PS4StatePacket_t last_state; +} SDL_DriverPS4_Context; + +static int HIDAPI_DriverPS4_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *effect, int size); + +static void HIDAPI_DriverPS4_RegisterHints(SDL_HintCallback callback, void *userdata) +{ + SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_PS4, callback, userdata); +} + +static void HIDAPI_DriverPS4_UnregisterHints(SDL_HintCallback callback, void *userdata) +{ + SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_PS4, callback, userdata); +} + +static SDL_bool HIDAPI_DriverPS4_IsEnabled(void) +{ + return SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_PS4, SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI, SDL_HIDAPI_DEFAULT)); +} + +static int ReadFeatureReport(SDL_hid_device *dev, Uint8 report_id, Uint8 *report, size_t length) +{ + SDL_memset(report, 0, length); + report[0] = report_id; + return SDL_hid_get_feature_report(dev, report, length); +} + +static SDL_bool HIDAPI_DriverPS4_IsSupportedDevice(SDL_HIDAPI_Device *device, const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol) +{ + Uint8 data[USB_PACKET_LENGTH]; + int size; + + if (type == SDL_CONTROLLER_TYPE_PS4) { + return SDL_TRUE; + } + + if (HIDAPI_SupportsPlaystationDetection(vendor_id, product_id)) { + if (device && device->dev) { + size = ReadFeatureReport(device->dev, k_ePS4FeatureReportIdCapabilities, data, sizeof(data)); + if (size == 48 && data[2] == 0x27) { + /* Supported third party controller */ + return SDL_TRUE; + } else { + return SDL_FALSE; + } + } else { + /* Might be supported by this driver, enumerate and find out */ + return SDL_TRUE; + } + } + + return SDL_FALSE; +} + +static void SetLedsForPlayerIndex(DS4EffectsState_t *effects, int player_index) +{ + /* This list is the same as what hid-sony.c uses in the Linux kernel. + The first 4 values correspond to what the PS4 assigns. + */ + static const Uint8 colors[7][3] = { + { 0x00, 0x00, 0x40 }, /* Blue */ + { 0x40, 0x00, 0x00 }, /* Red */ + { 0x00, 0x40, 0x00 }, /* Green */ + { 0x20, 0x00, 0x20 }, /* Pink */ + { 0x02, 0x01, 0x00 }, /* Orange */ + { 0x00, 0x01, 0x01 }, /* Teal */ + { 0x01, 0x01, 0x01 } /* White */ + }; + + if (player_index >= 0) { + player_index %= SDL_arraysize(colors); + } else { + player_index = 0; + } + + effects->ucLedRed = colors[player_index][0]; + effects->ucLedGreen = colors[player_index][1]; + effects->ucLedBlue = colors[player_index][2]; +} + +static SDL_bool HIDAPI_DriverPS4_InitDevice(SDL_HIDAPI_Device *device) +{ + SDL_DriverPS4_Context *ctx; + Uint8 data[USB_PACKET_LENGTH]; + int size; + char serial[18]; + SDL_JoystickType joystick_type = SDL_JOYSTICK_TYPE_GAMECONTROLLER; + + ctx = (SDL_DriverPS4_Context *)SDL_calloc(1, sizeof(*ctx)); + if (!ctx) { + SDL_OutOfMemory(); + return SDL_FALSE; + } + ctx->device = device; + + ctx->gyro_numerator = 1; + ctx->gyro_denominator = 16; + ctx->accel_numerator = 1; + ctx->accel_denominator = 8192; + + device->context = ctx; + + if (device->serial && SDL_strlen(device->serial) == 12) { + int i, j; + + j = -1; + for (i = 0; i < 12; i += 2) { + j += 1; + SDL_memcpy(&serial[j], &device->serial[i], 2); + j += 2; + serial[j] = '-'; + } + serial[j] = '\0'; + } else { + serial[0] = '\0'; + } + + /* Check for type of connection */ + ctx->is_dongle = (device->vendor_id == USB_VENDOR_SONY && device->product_id == USB_PRODUCT_SONY_DS4_DONGLE); + if (ctx->is_dongle) { + size = ReadFeatureReport(device->dev, k_ePS4FeatureReportIdSerialNumber, data, sizeof(data)); + if (size >= 7 && (data[1] || data[2] || data[3] || data[4] || data[5] || data[6])) { + (void)SDL_snprintf(serial, sizeof(serial), "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x", + data[6], data[5], data[4], data[3], data[2], data[1]); + } + device->is_bluetooth = SDL_FALSE; + ctx->enhanced_mode = SDL_TRUE; + } else if (device->vendor_id == USB_VENDOR_SONY && device->product_id == USB_PRODUCT_SONY_DS4_STRIKEPAD) { + device->is_bluetooth = SDL_FALSE; + ctx->enhanced_mode = SDL_TRUE; + + } else if (device->vendor_id == USB_VENDOR_SONY) { + /* This will fail if we're on Bluetooth */ + size = ReadFeatureReport(device->dev, k_ePS4FeatureReportIdSerialNumber, data, sizeof(data)); + if (size >= 7 && (data[1] || data[2] || data[3] || data[4] || data[5] || data[6])) { + (void)SDL_snprintf(serial, sizeof(serial), "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x", + data[6], data[5], data[4], data[3], data[2], data[1]); + device->is_bluetooth = SDL_FALSE; + ctx->enhanced_mode = SDL_TRUE; + } else { + device->is_bluetooth = SDL_TRUE; + + /* Read a report to see if we're in enhanced mode */ + size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 16); +#ifdef DEBUG_PS4_PROTOCOL + if (size > 0) { + HIDAPI_DumpPacket("PS4 first packet: size = %d", data, size); + } else { + SDL_Log("PS4 first packet: size = %d\n", size); + } +#endif + if (size > 0 && + data[0] >= k_EPS4ReportIdBluetoothState1 && + data[0] <= k_EPS4ReportIdBluetoothState9) { + ctx->enhanced_mode = SDL_TRUE; + } + } + } else { + /* Third party controllers appear to all be wired */ + device->is_bluetooth = SDL_FALSE; + ctx->enhanced_mode = SDL_TRUE; + } +#ifdef DEBUG_PS4 + SDL_Log("PS4 dongle = %s, bluetooth = %s\n", ctx->is_dongle ? "TRUE" : "FALSE", device->is_bluetooth ? "TRUE" : "FALSE"); +#endif + + if (device->vendor_id == USB_VENDOR_SONY) { + ctx->official_controller = SDL_TRUE; + ctx->sensors_supported = SDL_TRUE; + ctx->lightbar_supported = SDL_TRUE; + ctx->vibration_supported = SDL_TRUE; + ctx->touchpad_supported = SDL_TRUE; + } else { + size = ReadFeatureReport(device->dev, k_ePS4FeatureReportIdCapabilities, data, sizeof(data)); + /* Get the device capabilities */ + if (size == 48 && data[2] == 0x27) { + Uint8 capabilities = data[4]; + Uint8 device_type = data[5]; + Uint16 gyro_numerator = LOAD16(data[10], data[11]); + Uint16 gyro_denominator = LOAD16(data[12], data[13]); + Uint16 accel_numerator = LOAD16(data[14], data[15]); + Uint16 accel_denominator = LOAD16(data[16], data[17]); + +#ifdef DEBUG_PS4_PROTOCOL + HIDAPI_DumpPacket("PS4 capabilities: size = %d", data, size); +#endif + if (capabilities & 0x02) { + ctx->sensors_supported = SDL_TRUE; + } + if (capabilities & 0x04) { + ctx->lightbar_supported = SDL_TRUE; + } + if (capabilities & 0x08) { + ctx->vibration_supported = SDL_TRUE; + } + if (capabilities & 0x40) { + ctx->touchpad_supported = SDL_TRUE; + } + + switch (device_type) { + case 0x00: + joystick_type = SDL_JOYSTICK_TYPE_GAMECONTROLLER; + break; + case 0x01: + joystick_type = SDL_JOYSTICK_TYPE_GUITAR; + break; + case 0x02: + joystick_type = SDL_JOYSTICK_TYPE_DRUM_KIT; + break; + case 0x04: + joystick_type = SDL_JOYSTICK_TYPE_DANCE_PAD; + break; + case 0x06: + joystick_type = SDL_JOYSTICK_TYPE_WHEEL; + break; + case 0x07: + joystick_type = SDL_JOYSTICK_TYPE_ARCADE_STICK; + break; + case 0x08: + joystick_type = SDL_JOYSTICK_TYPE_FLIGHT_STICK; + break; + default: + joystick_type = SDL_JOYSTICK_TYPE_UNKNOWN; + break; + } + + if (gyro_numerator && gyro_denominator) { + ctx->gyro_numerator = gyro_numerator; + ctx->gyro_denominator = gyro_denominator; + } + if (accel_numerator && accel_denominator) { + ctx->accel_numerator = accel_numerator; + ctx->accel_denominator = accel_denominator; + } + } else if (device->vendor_id == USB_VENDOR_RAZER) { + /* The Razer Raiju doesn't respond to the detection protocol, but has a touchpad and vibration */ + ctx->vibration_supported = SDL_TRUE; + ctx->touchpad_supported = SDL_TRUE; + + if (device->product_id == USB_PRODUCT_RAZER_TOURNAMENT_EDITION_BLUETOOTH || + device->product_id == USB_PRODUCT_RAZER_ULTIMATE_EDITION_BLUETOOTH) { + device->is_bluetooth = SDL_TRUE; + } + } + } + ctx->effects_supported = (ctx->lightbar_supported || ctx->vibration_supported); + + if (device->vendor_id == USB_VENDOR_NACON_ALT && + device->product_id == USB_PRODUCT_NACON_REVOLUTION_5_PRO_PS4_WIRELESS) { + ctx->is_nacon_dongle = SDL_TRUE; + } + + if (device->vendor_id == USB_VENDOR_PDP && + (device->product_id == USB_PRODUCT_VICTRIX_FS_PRO || + device->product_id == USB_PRODUCT_VICTRIX_FS_PRO_V2)) { + /* The Victrix FS Pro V2 reports that it has lightbar support, + * but it doesn't respond to the effects packet, and will hang + * on reboot if we send it. + */ + ctx->effects_supported = SDL_FALSE; + } + + device->joystick_type = joystick_type; + device->type = SDL_CONTROLLER_TYPE_PS4; + if (ctx->official_controller) { + HIDAPI_SetDeviceName(device, "PS4 Controller"); + } + HIDAPI_SetDeviceSerial(device, serial); + + /* Prefer the USB device over the Bluetooth device */ + if (device->is_bluetooth) { + if (HIDAPI_HasConnectedUSBDevice(device->serial)) { + return SDL_TRUE; + } + } else { + HIDAPI_DisconnectBluetoothDevice(device->serial); + } + if ((ctx->is_dongle || ctx->is_nacon_dongle) && serial[0] == '\0') { + /* Not yet connected */ + return SDL_TRUE; + } + return HIDAPI_JoystickConnected(device, NULL); +} + +static int HIDAPI_DriverPS4_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id) +{ + return -1; +} + +static SDL_bool HIDAPI_DriverPS4_LoadOfficialCalibrationData(SDL_HIDAPI_Device *device) +{ + SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context; + int i, tries, size; + SDL_bool have_data = SDL_FALSE; + Uint8 data[USB_PACKET_LENGTH]; + + if (!ctx->official_controller) { +#ifdef DEBUG_PS4_CALIBRATION + SDL_Log("Not an official controller, ignoring calibration\n"); +#endif + return SDL_FALSE; + } + + for (tries = 0; tries < 5; ++tries) { + /* For Bluetooth controllers, this report switches them into advanced report mode */ + size = ReadFeatureReport(device->dev, k_ePS4FeatureReportIdGyroCalibration_USB, data, sizeof(data)); + if (size < 35) { +#ifdef DEBUG_PS4_CALIBRATION + SDL_Log("Short read of calibration data: %d, ignoring calibration\n", size); +#endif + return SDL_FALSE; + } + + if (device->is_bluetooth) { + size = ReadFeatureReport(device->dev, k_ePS4FeatureReportIdGyroCalibration_BT, data, sizeof(data)); + if (size < 35) { +#ifdef DEBUG_PS4_CALIBRATION + SDL_Log("Short read of calibration data: %d, ignoring calibration\n", size); +#endif + return SDL_FALSE; + } + } + + /* In some cases this report returns all zeros. Usually immediately after connection with the PS4 Dongle */ + for (i = 0; i < size; ++i) { + if (data[i]) { + have_data = SDL_TRUE; + break; + } + } + if (have_data) { + break; + } + + SDL_Delay(2); + } + + if (have_data) { + Sint16 sGyroPitchBias, sGyroYawBias, sGyroRollBias; + Sint16 sGyroPitchPlus, sGyroPitchMinus; + Sint16 sGyroYawPlus, sGyroYawMinus; + Sint16 sGyroRollPlus, sGyroRollMinus; + Sint16 sGyroSpeedPlus, sGyroSpeedMinus; + + Sint16 sAccXPlus, sAccXMinus; + Sint16 sAccYPlus, sAccYMinus; + Sint16 sAccZPlus, sAccZMinus; + + float flNumerator; + float flDenominator; + Sint16 sRange2g; + +#ifdef DEBUG_PS4_CALIBRATION + HIDAPI_DumpPacket("PS4 calibration packet: size = %d", data, size); +#endif + + sGyroPitchBias = LOAD16(data[1], data[2]); + sGyroYawBias = LOAD16(data[3], data[4]); + sGyroRollBias = LOAD16(data[5], data[6]); + + if (device->is_bluetooth || ctx->is_dongle) { + sGyroPitchPlus = LOAD16(data[7], data[8]); + sGyroYawPlus = LOAD16(data[9], data[10]); + sGyroRollPlus = LOAD16(data[11], data[12]); + sGyroPitchMinus = LOAD16(data[13], data[14]); + sGyroYawMinus = LOAD16(data[15], data[16]); + sGyroRollMinus = LOAD16(data[17], data[18]); + } else { + sGyroPitchPlus = LOAD16(data[7], data[8]); + sGyroPitchMinus = LOAD16(data[9], data[10]); + sGyroYawPlus = LOAD16(data[11], data[12]); + sGyroYawMinus = LOAD16(data[13], data[14]); + sGyroRollPlus = LOAD16(data[15], data[16]); + sGyroRollMinus = LOAD16(data[17], data[18]); + } + + sGyroSpeedPlus = LOAD16(data[19], data[20]); + sGyroSpeedMinus = LOAD16(data[21], data[22]); + + sAccXPlus = LOAD16(data[23], data[24]); + sAccXMinus = LOAD16(data[25], data[26]); + sAccYPlus = LOAD16(data[27], data[28]); + sAccYMinus = LOAD16(data[29], data[30]); + sAccZPlus = LOAD16(data[31], data[32]); + sAccZMinus = LOAD16(data[33], data[34]); + + flNumerator = (float)(sGyroSpeedPlus + sGyroSpeedMinus) * ctx->gyro_denominator / ctx->gyro_numerator; + flDenominator = (float)(SDL_abs(sGyroPitchPlus - sGyroPitchBias) + SDL_abs(sGyroPitchMinus - sGyroPitchBias)); + if (flDenominator != 0.0f) { + ctx->calibration[0].bias = sGyroPitchBias; + ctx->calibration[0].scale = flNumerator / flDenominator; + } + + flDenominator = (float)(SDL_abs(sGyroYawPlus - sGyroYawBias) + SDL_abs(sGyroYawMinus - sGyroYawBias)); + if (flDenominator != 0.0f) { + ctx->calibration[1].bias = sGyroYawBias; + ctx->calibration[1].scale = flNumerator / flDenominator; + } + + flDenominator = (float)(SDL_abs(sGyroRollPlus - sGyroRollBias) + SDL_abs(sGyroRollMinus - sGyroRollBias)); + if (flDenominator != 0.0f) { + ctx->calibration[2].bias = sGyroRollBias; + ctx->calibration[2].scale = flNumerator / flDenominator; + } + + sRange2g = sAccXPlus - sAccXMinus; + ctx->calibration[3].bias = sAccXPlus - sRange2g / 2; + ctx->calibration[3].scale = (2.0f * ctx->accel_denominator / ctx->accel_numerator) / sRange2g; + + sRange2g = sAccYPlus - sAccYMinus; + ctx->calibration[4].bias = sAccYPlus - sRange2g / 2; + ctx->calibration[4].scale = (2.0f * ctx->accel_denominator / ctx->accel_numerator) / sRange2g; + + sRange2g = sAccZPlus - sAccZMinus; + ctx->calibration[5].bias = sAccZPlus - sRange2g / 2; + ctx->calibration[5].scale = (2.0f * ctx->accel_denominator / ctx->accel_numerator) / sRange2g; + + ctx->hardware_calibration = SDL_TRUE; + for (i = 0; i < 6; ++i) { +#ifdef DEBUG_PS4_CALIBRATION + SDL_Log("calibration[%d] bias = %d, sensitivity = %f\n", i, ctx->calibration[i].bias, ctx->calibration[i].scale); +#endif + /* Some controllers have a bad calibration */ + if (SDL_abs(ctx->calibration[i].bias) > 1024 || SDL_fabs(1.0f - ctx->calibration[i].scale) > 0.5f) { +#ifdef DEBUG_PS4_CALIBRATION + SDL_Log("invalid calibration, ignoring\n"); +#endif + ctx->hardware_calibration = SDL_FALSE; + } + } + } else { +#ifdef DEBUG_PS4_CALIBRATION + SDL_Log("Calibration data not available\n"); +#endif + } + return ctx->hardware_calibration; +} + +static void HIDAPI_DriverPS4_LoadCalibrationData(SDL_HIDAPI_Device *device) +{ + SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context; + int i; + + if (!HIDAPI_DriverPS4_LoadOfficialCalibrationData(device)) { + for (i = 0; i < SDL_arraysize(ctx->calibration); ++i) { + ctx->calibration[i].bias = 0; + ctx->calibration[i].scale = 1.0f; + } + } + + /* Scale the raw data to the units expected by SDL */ + for (i = 0; i < SDL_arraysize(ctx->calibration); ++i) { + double scale = ctx->calibration[i].scale; + + if (i < 3) { + scale *= ((double)ctx->gyro_numerator / ctx->gyro_denominator) * M_PI / 180.0; + + if (device->vendor_id == USB_VENDOR_SONY && + device->product_id == USB_PRODUCT_SONY_DS4_STRIKEPAD) { + /* The Armor-X Pro seems to only deliver half the rotation it should */ + scale *= 2.0; + } + } else { + scale *= ((double)ctx->accel_numerator / ctx->accel_denominator) * SDL_STANDARD_GRAVITY; + + if (device->vendor_id == USB_VENDOR_SONY && + device->product_id == USB_PRODUCT_SONY_DS4_STRIKEPAD) { + /* The Armor-X Pro seems to only deliver half the acceleration it should, + * and in the opposite direction on all axes */ + scale *= -2.0; + } + } + ctx->calibration[i].scale = (float)scale; + } +} + +static float HIDAPI_DriverPS4_ApplyCalibrationData(SDL_DriverPS4_Context *ctx, int index, Sint16 value) +{ + IMUCalibrationData *calibration = &ctx->calibration[index]; + + return ((float)value - calibration->bias) * calibration->scale; +} + +static int HIDAPI_DriverPS4_UpdateEffects(SDL_HIDAPI_Device *device) +{ + SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context; + DS4EffectsState_t effects; + + if (!ctx->enhanced_mode || !ctx->effects_supported) { + return SDL_Unsupported(); + } + + SDL_zero(effects); + + if (ctx->vibration_supported) { + effects.ucRumbleLeft = ctx->rumble_left; + effects.ucRumbleRight = ctx->rumble_right; + } + + if (ctx->lightbar_supported) { + /* Populate the LED state with the appropriate color from our lookup table */ + if (ctx->color_set) { + effects.ucLedRed = ctx->led_red; + effects.ucLedGreen = ctx->led_green; + effects.ucLedBlue = ctx->led_blue; + } else { + SetLedsForPlayerIndex(&effects, ctx->player_index); + } + } + return HIDAPI_DriverPS4_SendJoystickEffect(device, ctx->joystick, &effects, sizeof(effects)); +} + +static void HIDAPI_DriverPS4_TickleBluetooth(SDL_HIDAPI_Device *device) +{ + SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context; + + if (ctx->enhanced_mode) { + /* This is just a dummy packet that should have no effect, since we don't set the CRC */ + Uint8 data[78]; + + SDL_zeroa(data); + + data[0] = k_EPS4ReportIdBluetoothEffects; + data[1] = 0xC0; /* Magic value HID + CRC */ + + if (SDL_HIDAPI_LockRumble() == 0) { + SDL_HIDAPI_SendRumbleAndUnlock(device, data, sizeof(data)); + } + } else { +#if 0 /* The 8BitDo Zero 2 has perfect emulation of a PS4 controllers, except it + * only sends reports when the state changes, so we can't disconnect here. + */ + /* We can't even send an invalid effects packet, or it will put the controller in enhanced mode */ + if (device->num_joysticks > 0) { + HIDAPI_JoystickDisconnected(device, device->joysticks[0]); + } +#endif + } +} + +static void HIDAPI_DriverPS4_SetEnhancedMode(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context; + + if (!ctx->enhanced_mode) { + ctx->enhanced_mode = SDL_TRUE; + + if (ctx->touchpad_supported) { + SDL_PrivateJoystickAddTouchpad(joystick, 2); + ctx->report_touchpad = SDL_TRUE; + } + if (ctx->sensors_supported) { + SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, 250.0f); + SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, 250.0f); + } + + HIDAPI_DriverPS4_UpdateEffects(device); + } +} + +static void SDLCALL SDL_PS4RumbleHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)userdata; + + /* This is a one-way trip, you can't switch the controller back to simple report mode */ + if (SDL_GetStringBoolean(hint, SDL_FALSE)) { + HIDAPI_DriverPS4_SetEnhancedMode(ctx->device, ctx->joystick); + } +} + +static void HIDAPI_DriverPS4_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index) +{ + SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context; + + if (!ctx->joystick) { + return; + } + + ctx->player_index = player_index; + + /* This will set the new LED state based on the new player index */ + HIDAPI_DriverPS4_UpdateEffects(device); +} + +static SDL_bool HIDAPI_DriverPS4_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context; + + SDL_AssertJoysticksLocked(); + + ctx->joystick = joystick; + ctx->last_packet = SDL_GetTicks(); + ctx->report_sensors = SDL_FALSE; + ctx->report_touchpad = SDL_FALSE; + ctx->rumble_left = 0; + ctx->rumble_right = 0; + ctx->color_set = SDL_FALSE; + SDL_zero(ctx->last_state); + + /* Initialize player index (needed for setting LEDs) */ + ctx->player_index = SDL_JoystickGetPlayerIndex(joystick); + + /* Initialize the joystick capabilities */ + joystick->nbuttons = ctx->touchpad_supported ? 16 : 15; + joystick->naxes = SDL_CONTROLLER_AXIS_MAX; + if (device->is_bluetooth && ctx->official_controller) { + joystick->epowerlevel = SDL_JOYSTICK_POWER_UNKNOWN; + } else if (device->is_bluetooth) { + /* We can't get the power status, assume it's full */ + joystick->epowerlevel = SDL_JOYSTICK_POWER_FULL; + } else { + joystick->epowerlevel = SDL_JOYSTICK_POWER_WIRED; + } + + if (ctx->enhanced_mode) { + /* Force initialization when opening the joystick */ + ctx->enhanced_mode = SDL_FALSE; + HIDAPI_DriverPS4_SetEnhancedMode(device, joystick); + } else { + SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE, + SDL_PS4RumbleHintChanged, ctx); + } + return SDL_TRUE; +} + +static int HIDAPI_DriverPS4_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ + SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context; + + if (!ctx->vibration_supported) { + return SDL_Unsupported(); + } + + ctx->rumble_left = (low_frequency_rumble >> 8); + ctx->rumble_right = (high_frequency_rumble >> 8); + + return HIDAPI_DriverPS4_UpdateEffects(device); +} + +static int HIDAPI_DriverPS4_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) +{ + return SDL_Unsupported(); +} + +static Uint32 HIDAPI_DriverPS4_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context; + Uint32 result = 0; + + if (ctx->enhanced_mode) { + if (ctx->lightbar_supported) { + result |= SDL_JOYCAP_LED; + } + if (ctx->vibration_supported) { + result |= SDL_JOYCAP_RUMBLE; + } + } + + return result; +} + +static int HIDAPI_DriverPS4_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context; + + if (!ctx->lightbar_supported) { + return SDL_Unsupported(); + } + + ctx->color_set = SDL_TRUE; + ctx->led_red = red; + ctx->led_green = green; + ctx->led_blue = blue; + + return HIDAPI_DriverPS4_UpdateEffects(device); +} + +static int HIDAPI_DriverPS4_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *effect, int size) +{ + SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context; + Uint8 data[78]; + int report_size, offset; + + if (!ctx->effects_supported) { + return SDL_Unsupported(); + } + + if (!ctx->enhanced_mode) { + HIDAPI_DriverPS4_SetEnhancedMode(device, joystick); + } + + SDL_zeroa(data); + + if (device->is_bluetooth && ctx->official_controller) { + data[0] = k_EPS4ReportIdBluetoothEffects; + data[1] = 0xC0 | 0x04; /* Magic value HID + CRC, also sets interval to 4ms for samples */ + data[3] = 0x03; /* 0x1 is rumble, 0x2 is lightbar, 0x4 is the blink interval */ + + report_size = 78; + offset = 6; + } else { + data[0] = k_EPS4ReportIdUsbEffects; + data[1] = 0x07; /* Magic value */ + + report_size = 32; + offset = 4; + } + + SDL_memcpy(&data[offset], effect, SDL_min((sizeof(data) - offset), (size_t)size)); + + if (device->is_bluetooth) { + /* Bluetooth reports need a CRC at the end of the packet (at least on Linux) */ + Uint8 ubHdr = 0xA2; /* hidp header is part of the CRC calculation */ + Uint32 unCRC; + unCRC = SDL_crc32(0, &ubHdr, 1); + unCRC = SDL_crc32(unCRC, data, (size_t)(report_size - sizeof(unCRC))); + SDL_memcpy(&data[report_size - sizeof(unCRC)], &unCRC, sizeof(unCRC)); + } + + if (SDL_HIDAPI_SendRumble(device, data, report_size) != report_size) { + return SDL_SetError("Couldn't send rumble packet"); + } + return 0; +} + +static int HIDAPI_DriverPS4_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled) +{ + SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context; + + if (!ctx->enhanced_mode) { + return SDL_Unsupported(); + } + + if (enabled) { + HIDAPI_DriverPS4_LoadCalibrationData(device); + } + ctx->report_sensors = enabled; + ctx->timestamp = 0; + + return 0; +} + +static void HIDAPI_DriverPS4_HandleStatePacket(SDL_Joystick *joystick, SDL_hid_device *dev, SDL_DriverPS4_Context *ctx, PS4StatePacket_t *packet, int size) +{ + static const float TOUCHPAD_SCALEX = 1.0f / 1920; + static const float TOUCHPAD_SCALEY = 1.0f / 920; /* This is noted as being 944 resolution, but 920 feels better */ + Sint16 axis; + Uint8 touchpad_state; + int touchpad_x, touchpad_y; + + if (ctx->last_state.rgucButtonsHatAndCounter[0] != packet->rgucButtonsHatAndCounter[0]) { + { + Uint8 data = (packet->rgucButtonsHatAndCounter[0] >> 4); + + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_X, (data & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_A, (data & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_B, (data & 0x04) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_Y, (data & 0x08) ? SDL_PRESSED : SDL_RELEASED); + } + { + Uint8 data = (packet->rgucButtonsHatAndCounter[0] & 0x0F); + SDL_bool dpad_up = SDL_FALSE; + SDL_bool dpad_down = SDL_FALSE; + SDL_bool dpad_left = SDL_FALSE; + SDL_bool dpad_right = SDL_FALSE; + + switch (data) { + case 0: + dpad_up = SDL_TRUE; + break; + case 1: + dpad_up = SDL_TRUE; + dpad_right = SDL_TRUE; + break; + case 2: + dpad_right = SDL_TRUE; + break; + case 3: + dpad_right = SDL_TRUE; + dpad_down = SDL_TRUE; + break; + case 4: + dpad_down = SDL_TRUE; + break; + case 5: + dpad_left = SDL_TRUE; + dpad_down = SDL_TRUE; + break; + case 6: + dpad_left = SDL_TRUE; + break; + case 7: + dpad_up = SDL_TRUE; + dpad_left = SDL_TRUE; + break; + default: + break; + } + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, dpad_down); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, dpad_up); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, dpad_right); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, dpad_left); + } + } + + if (ctx->last_state.rgucButtonsHatAndCounter[1] != packet->rgucButtonsHatAndCounter[1]) { + Uint8 data = packet->rgucButtonsHatAndCounter[1]; + + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (data & 0x40) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data & 0x80) ? SDL_PRESSED : SDL_RELEASED); + } + + /* Some fightsticks, ex: Victrix FS Pro will only this these digital trigger bits and not the analog values so this needs to run whenever the + trigger is evaluated + */ + if (packet->rgucButtonsHatAndCounter[1] & 0x0C) { + Uint8 data = packet->rgucButtonsHatAndCounter[1]; + packet->ucTriggerLeft = (data & 0x04) && packet->ucTriggerLeft == 0 ? 255 : packet->ucTriggerLeft; + packet->ucTriggerRight = (data & 0x08) && packet->ucTriggerRight == 0 ? 255 : packet->ucTriggerRight; + } + + if (ctx->last_state.rgucButtonsHatAndCounter[2] != packet->rgucButtonsHatAndCounter[2]) { + Uint8 data = (packet->rgucButtonsHatAndCounter[2] & 0x03); + + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, 15, (data & 0x02) ? SDL_PRESSED : SDL_RELEASED); + } + + axis = ((int)packet->ucTriggerLeft * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, axis); + axis = ((int)packet->ucTriggerRight * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, axis); + axis = ((int)packet->ucLeftJoystickX * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis); + axis = ((int)packet->ucLeftJoystickY * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, axis); + axis = ((int)packet->ucRightJoystickX * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, axis); + axis = ((int)packet->ucRightJoystickY * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis); + + if (size > 9 && ctx->device->is_bluetooth && ctx->official_controller) { + if (packet->ucBatteryLevel & 0x10) { + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_WIRED); + } else { + /* Battery level ranges from 0 to 10 */ + int level = (packet->ucBatteryLevel & 0xF); + if (level == 0) { + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_EMPTY); + } else if (level <= 2) { + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_LOW); + } else if (level <= 7) { + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_MEDIUM); + } else { + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_FULL); + } + } + } + + if (size > 9 && ctx->report_touchpad) { + touchpad_state = !(packet->ucTouchpadCounter1 & 0x80) ? SDL_PRESSED : SDL_RELEASED; + touchpad_x = packet->rgucTouchpadData1[0] | (((int)packet->rgucTouchpadData1[1] & 0x0F) << 8); + touchpad_y = (packet->rgucTouchpadData1[1] >> 4) | ((int)packet->rgucTouchpadData1[2] << 4); + SDL_PrivateJoystickTouchpad(joystick, 0, 0, touchpad_state, touchpad_x * TOUCHPAD_SCALEX, touchpad_y * TOUCHPAD_SCALEY, touchpad_state ? 1.0f : 0.0f); + + touchpad_state = !(packet->ucTouchpadCounter2 & 0x80) ? SDL_PRESSED : SDL_RELEASED; + touchpad_x = packet->rgucTouchpadData2[0] | (((int)packet->rgucTouchpadData2[1] & 0x0F) << 8); + touchpad_y = (packet->rgucTouchpadData2[1] >> 4) | ((int)packet->rgucTouchpadData2[2] << 4); + SDL_PrivateJoystickTouchpad(joystick, 0, 1, touchpad_state, touchpad_x * TOUCHPAD_SCALEX, touchpad_y * TOUCHPAD_SCALEY, touchpad_state ? 1.0f : 0.0f); + } + + if (size > 9 && ctx->report_sensors) { + Uint16 timestamp; + Uint64 timestamp_us; + float data[3]; + + timestamp = LOAD16(packet->rgucTimestamp[0], packet->rgucTimestamp[1]); + if (ctx->timestamp) { + Uint16 delta; + + if (ctx->last_timestamp > timestamp) { + delta = (SDL_MAX_UINT16 - ctx->last_timestamp + timestamp + 1); + } else { + delta = (timestamp - ctx->last_timestamp); + } + ctx->timestamp += delta; + } else { + ctx->timestamp = timestamp; + } + ctx->last_timestamp = timestamp; + + /* Sensor timestamp is in 5.33us units */ + timestamp_us = (ctx->timestamp * 16) / 3; + + data[0] = HIDAPI_DriverPS4_ApplyCalibrationData(ctx, 0, LOAD16(packet->rgucGyroX[0], packet->rgucGyroX[1])); + data[1] = HIDAPI_DriverPS4_ApplyCalibrationData(ctx, 1, LOAD16(packet->rgucGyroY[0], packet->rgucGyroY[1])); + data[2] = HIDAPI_DriverPS4_ApplyCalibrationData(ctx, 2, LOAD16(packet->rgucGyroZ[0], packet->rgucGyroZ[1])); + SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_GYRO, timestamp_us, data, 3); + + data[0] = HIDAPI_DriverPS4_ApplyCalibrationData(ctx, 3, LOAD16(packet->rgucAccelX[0], packet->rgucAccelX[1])); + data[1] = HIDAPI_DriverPS4_ApplyCalibrationData(ctx, 4, LOAD16(packet->rgucAccelY[0], packet->rgucAccelY[1])); + data[2] = HIDAPI_DriverPS4_ApplyCalibrationData(ctx, 5, LOAD16(packet->rgucAccelZ[0], packet->rgucAccelZ[1])); + SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_ACCEL, timestamp_us, data, 3); + } + + SDL_memcpy(&ctx->last_state, packet, sizeof(ctx->last_state)); +} + +static SDL_bool VerifyCRC(Uint8 *data, int size) +{ + Uint8 ubHdr = 0xA1; /* hidp header is part of the CRC calculation */ + Uint32 unCRC, unPacketCRC; + Uint8 *packetCRC = data + size - sizeof(unPacketCRC); + unCRC = SDL_crc32(0, &ubHdr, 1); + unCRC = SDL_crc32(unCRC, data, (size_t)(size - sizeof(unCRC))); + + unPacketCRC = LOAD32(packetCRC[0], + packetCRC[1], + packetCRC[2], + packetCRC[3]); + return (unCRC == unPacketCRC) ? SDL_TRUE : SDL_FALSE; +} + +static SDL_bool HIDAPI_DriverPS4_IsPacketValid(SDL_DriverPS4_Context *ctx, Uint8 *data, int size) +{ + switch (data[0]) { + case k_EPS4ReportIdUsbState: + if (size == 10) { + /* This is non-enhanced mode, this packet is fine */ + return SDL_TRUE; + } + + if (ctx->is_nacon_dongle && size >= (1 + sizeof(PS4StatePacket_t))) { + /* The report timestamp doesn't change when the controller isn't connected */ + PS4StatePacket_t *packet = (PS4StatePacket_t *)&data[1]; + if (SDL_memcmp(packet->rgucTimestamp, ctx->last_state.rgucTimestamp, sizeof(packet->rgucTimestamp)) == 0) { + return SDL_FALSE; + } + if (ctx->last_state.rgucAccelX[0] == 0 && ctx->last_state.rgucAccelX[1] == 0 && + ctx->last_state.rgucAccelY[0] == 0 && ctx->last_state.rgucAccelY[1] == 0 && + ctx->last_state.rgucAccelZ[0] == 0 && ctx->last_state.rgucAccelZ[1] == 0) { + /* We don't have any state to compare yet, go ahead and copy it */ + SDL_memcpy(&ctx->last_state, &data[1], sizeof(PS4StatePacket_t)); + return SDL_FALSE; + } + } + + /* In the case of a DS4 USB dongle, bit[2] of byte 31 indicates if a DS4 is actually connected (indicated by '0'). + * For non-dongle, this bit is always 0 (connected). + * This is usually the ID over USB, but the DS4v2 that started shipping with the PS4 Slim will also send this + * packet over BT with a size of 128 + */ + if (size >= 64 && !(data[31] & 0x04)) { + return SDL_TRUE; + } + break; + case k_EPS4ReportIdBluetoothState1: + case k_EPS4ReportIdBluetoothState2: + case k_EPS4ReportIdBluetoothState3: + case k_EPS4ReportIdBluetoothState4: + case k_EPS4ReportIdBluetoothState5: + case k_EPS4ReportIdBluetoothState6: + case k_EPS4ReportIdBluetoothState7: + case k_EPS4ReportIdBluetoothState8: + case k_EPS4ReportIdBluetoothState9: + /* Bluetooth state packets have two additional bytes at the beginning, the first notes if HID data is present */ + if (size >= 78 && (data[1] & 0x80)) { + if (VerifyCRC(data, 78)) { + ++ctx->valid_crc_packets; + } else { + if (ctx->valid_crc_packets > 0) { + --ctx->valid_crc_packets; + } + if (ctx->valid_crc_packets >= 3) { + /* We're generally getting valid CRC, but failed one */ + return SDL_FALSE; + } + } + return SDL_TRUE; + } + break; + default: + break; + } + return SDL_FALSE; +} + +static SDL_bool HIDAPI_DriverPS4_UpdateDevice(SDL_HIDAPI_Device *device) +{ + SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context; + SDL_Joystick *joystick = NULL; + Uint8 data[USB_PACKET_LENGTH * 2]; + int size; + int packet_count = 0; + Uint32 now = SDL_GetTicks(); + + if (device->num_joysticks > 0) { + joystick = SDL_JoystickFromInstanceID(device->joysticks[0]); + } + + while ((size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) { +#ifdef DEBUG_PS4_PROTOCOL + HIDAPI_DumpPacket("PS4 packet: size = %d", data, size); +#endif + if (!HIDAPI_DriverPS4_IsPacketValid(ctx, data, size)) { + continue; + } + + ++packet_count; + ctx->last_packet = now; + + if (!joystick) { + continue; + } + + switch (data[0]) { + case k_EPS4ReportIdUsbState: + HIDAPI_DriverPS4_HandleStatePacket(joystick, device->dev, ctx, (PS4StatePacket_t *)&data[1], size - 1); + break; + case k_EPS4ReportIdBluetoothState1: + case k_EPS4ReportIdBluetoothState2: + case k_EPS4ReportIdBluetoothState3: + case k_EPS4ReportIdBluetoothState4: + case k_EPS4ReportIdBluetoothState5: + case k_EPS4ReportIdBluetoothState6: + case k_EPS4ReportIdBluetoothState7: + case k_EPS4ReportIdBluetoothState8: + case k_EPS4ReportIdBluetoothState9: + if (!ctx->enhanced_mode) { + /* This is the extended report, we can enable effects now */ + HIDAPI_DriverPS4_SetEnhancedMode(device, joystick); + } + /* Bluetooth state packets have two additional bytes at the beginning, the first notes if HID is present */ + HIDAPI_DriverPS4_HandleStatePacket(joystick, device->dev, ctx, (PS4StatePacket_t *)&data[3], size - 3); + break; + default: +#ifdef DEBUG_JOYSTICK + SDL_Log("Unknown PS4 packet: 0x%.2x\n", data[0]); +#endif + break; + } + } + + if (device->is_bluetooth) { + if (packet_count == 0) { + /* Check to see if it looks like the device disconnected */ + if (SDL_TICKS_PASSED(now, ctx->last_packet + BLUETOOTH_DISCONNECT_TIMEOUT_MS)) { + /* Send an empty output report to tickle the Bluetooth stack */ + HIDAPI_DriverPS4_TickleBluetooth(device); + } + } else { + /* Reconnect the Bluetooth device once the USB device is gone */ + if (device->num_joysticks == 0 && + !HIDAPI_HasConnectedUSBDevice(device->serial)) { + HIDAPI_JoystickConnected(device, NULL); + } + } + } + + if (ctx->is_dongle || ctx->is_nacon_dongle) { + if (packet_count == 0) { + if (device->num_joysticks > 0) { + /* Check to see if it looks like the device disconnected */ + if (SDL_TICKS_PASSED(now, ctx->last_packet + BLUETOOTH_DISCONNECT_TIMEOUT_MS)) { + HIDAPI_JoystickDisconnected(device, device->joysticks[0]); + } + } + } else { + if (device->num_joysticks == 0) { + char serial[18]; + size = ReadFeatureReport(device->dev, k_ePS4FeatureReportIdSerialNumber, data, sizeof(data)); + if (size >= 7 && (data[1] || data[2] || data[3] || data[4] || data[5] || data[6])) { + (void)SDL_snprintf(serial, sizeof(serial), "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x", + data[6], data[5], data[4], data[3], data[2], data[1]); + HIDAPI_SetDeviceSerial(device, serial); + } + HIDAPI_JoystickConnected(device, NULL); + } + } + } + + if (packet_count == 0 && size < 0 && device->num_joysticks > 0) { + /* Read error, device is disconnected */ + HIDAPI_JoystickDisconnected(device, device->joysticks[0]); + } + return size >= 0; +} + +static void HIDAPI_DriverPS4_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context; + + SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE, + SDL_PS4RumbleHintChanged, ctx); + + ctx->joystick = NULL; +} + +static void HIDAPI_DriverPS4_FreeDevice(SDL_HIDAPI_Device *device) +{ +} + +SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS4 = { + SDL_HINT_JOYSTICK_HIDAPI_PS4, + SDL_TRUE, + HIDAPI_DriverPS4_RegisterHints, + HIDAPI_DriverPS4_UnregisterHints, + HIDAPI_DriverPS4_IsEnabled, + HIDAPI_DriverPS4_IsSupportedDevice, + HIDAPI_DriverPS4_InitDevice, + HIDAPI_DriverPS4_GetDevicePlayerIndex, + HIDAPI_DriverPS4_SetDevicePlayerIndex, + HIDAPI_DriverPS4_UpdateDevice, + HIDAPI_DriverPS4_OpenJoystick, + HIDAPI_DriverPS4_RumbleJoystick, + HIDAPI_DriverPS4_RumbleJoystickTriggers, + HIDAPI_DriverPS4_GetJoystickCapabilities, + HIDAPI_DriverPS4_SetJoystickLED, + HIDAPI_DriverPS4_SendJoystickEffect, + HIDAPI_DriverPS4_SetJoystickSensorsEnabled, + HIDAPI_DriverPS4_CloseJoystick, + HIDAPI_DriverPS4_FreeDevice, +}; + +#endif /* SDL_JOYSTICK_HIDAPI_PS4 */ + +#endif /* SDL_JOYSTICK_HIDAPI */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_ps5.c b/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_ps5.c new file mode 100644 index 0000000..dfdbc81 --- /dev/null +++ b/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_ps5.c @@ -0,0 +1,1578 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_JOYSTICK_HIDAPI + +#include "SDL_events.h" +#include "SDL_timer.h" +#include "SDL_joystick.h" +#include "SDL_gamecontroller.h" +#include "../../SDL_hints_c.h" +#include "../SDL_sysjoystick.h" +#include "SDL_hidapijoystick_c.h" +#include "SDL_hidapi_rumble.h" + +#ifdef SDL_JOYSTICK_HIDAPI_PS5 + +/* Define this if you want to log all packets from the controller */ +/*#define DEBUG_PS5_PROTOCOL*/ + +/* Define this if you want to log calibration data */ +/*#define DEBUG_PS5_CALIBRATION*/ + +#define GYRO_RES_PER_DEGREE 1024.0f +#define ACCEL_RES_PER_G 8192.0f +#define BLUETOOTH_DISCONNECT_TIMEOUT_MS 500 + +#define LOAD16(A, B) (Sint16)((Uint16)(A) | (((Uint16)(B)) << 8)) +#define LOAD32(A, B, C, D) ((((Uint32)(A)) << 0) | \ + (((Uint32)(B)) << 8) | \ + (((Uint32)(C)) << 16) | \ + (((Uint32)(D)) << 24)) + +enum +{ + SDL_CONTROLLER_BUTTON_PS5_TOUCHPAD = SDL_CONTROLLER_BUTTON_MISC1 + 1, + SDL_CONTROLLER_BUTTON_PS5_LEFT_FUNCTION, + SDL_CONTROLLER_BUTTON_PS5_RIGHT_FUNCTION, + SDL_CONTROLLER_BUTTON_PS5_LEFT_PADDLE, + SDL_CONTROLLER_BUTTON_PS5_RIGHT_PADDLE +}; + +typedef enum +{ + k_EPS5ReportIdState = 0x01, + k_EPS5ReportIdUsbEffects = 0x02, + k_EPS5ReportIdBluetoothEffects = 0x31, + k_EPS5ReportIdBluetoothState = 0x31, +} EPS5ReportId; + +typedef enum +{ + k_EPS5FeatureReportIdCapabilities = 0x03, + k_EPS5FeatureReportIdCalibration = 0x05, + k_EPS5FeatureReportIdSerialNumber = 0x09, + k_EPS5FeatureReportIdFirmwareInfo = 0x20, +} EPS5FeatureReportId; + +typedef struct +{ + Uint8 ucLeftJoystickX; + Uint8 ucLeftJoystickY; + Uint8 ucRightJoystickX; + Uint8 ucRightJoystickY; + Uint8 rgucButtonsHatAndCounter[3]; + Uint8 ucTriggerLeft; + Uint8 ucTriggerRight; +} PS5SimpleStatePacket_t; + +typedef struct +{ + Uint8 ucLeftJoystickX; /* 0 */ + Uint8 ucLeftJoystickY; /* 1 */ + Uint8 ucRightJoystickX; /* 2 */ + Uint8 ucRightJoystickY; /* 3 */ + Uint8 ucTriggerLeft; /* 4 */ + Uint8 ucTriggerRight; /* 5 */ + Uint8 ucCounter; /* 6 */ + Uint8 rgucButtonsAndHat[4]; /* 7 */ + Uint8 rgucPacketSequence[4]; /* 11 - 32 bit little endian */ + Uint8 rgucGyroX[2]; /* 15 */ + Uint8 rgucGyroY[2]; /* 17 */ + Uint8 rgucGyroZ[2]; /* 19 */ + Uint8 rgucAccelX[2]; /* 21 */ + Uint8 rgucAccelY[2]; /* 23 */ + Uint8 rgucAccelZ[2]; /* 25 */ + Uint8 rgucSensorTimestamp[4]; /* 27 - 16/32 bit little endian */ + +} PS5StatePacketCommon_t; + +typedef struct +{ + Uint8 ucLeftJoystickX; /* 0 */ + Uint8 ucLeftJoystickY; /* 1 */ + Uint8 ucRightJoystickX; /* 2 */ + Uint8 ucRightJoystickY; /* 3 */ + Uint8 ucTriggerLeft; /* 4 */ + Uint8 ucTriggerRight; /* 5 */ + Uint8 ucCounter; /* 6 */ + Uint8 rgucButtonsAndHat[4]; /* 7 */ + Uint8 rgucPacketSequence[4]; /* 11 - 32 bit little endian */ + Uint8 rgucGyroX[2]; /* 15 */ + Uint8 rgucGyroY[2]; /* 17 */ + Uint8 rgucGyroZ[2]; /* 19 */ + Uint8 rgucAccelX[2]; /* 21 */ + Uint8 rgucAccelY[2]; /* 23 */ + Uint8 rgucAccelZ[2]; /* 25 */ + Uint8 rgucSensorTimestamp[4]; /* 27 - 32 bit little endian */ + Uint8 ucSensorTemp; /* 31 */ + Uint8 ucTouchpadCounter1; /* 32 - high bit clear + counter */ + Uint8 rgucTouchpadData1[3]; /* 33 - X/Y, 12 bits per axis */ + Uint8 ucTouchpadCounter2; /* 36 - high bit clear + counter */ + Uint8 rgucTouchpadData2[3]; /* 37 - X/Y, 12 bits per axis */ + Uint8 rgucUnknown1[8]; /* 40 */ + Uint8 rgucTimer2[4]; /* 48 - 32 bit little endian */ + Uint8 ucBatteryLevel; /* 52 */ + Uint8 ucConnectState; /* 53 - 0x08 = USB, 0x01 = headphone */ + + /* There's more unknown data at the end, and a 32-bit CRC on Bluetooth */ +} PS5StatePacket_t; + +typedef struct +{ + Uint8 ucLeftJoystickX; /* 0 */ + Uint8 ucLeftJoystickY; /* 1 */ + Uint8 ucRightJoystickX; /* 2 */ + Uint8 ucRightJoystickY; /* 3 */ + Uint8 ucTriggerLeft; /* 4 */ + Uint8 ucTriggerRight; /* 5 */ + Uint8 ucCounter; /* 6 */ + Uint8 rgucButtonsAndHat[4]; /* 7 */ + Uint8 rgucPacketSequence[4]; /* 11 - 32 bit little endian */ + Uint8 rgucGyroX[2]; /* 15 */ + Uint8 rgucGyroY[2]; /* 17 */ + Uint8 rgucGyroZ[2]; /* 19 */ + Uint8 rgucAccelX[2]; /* 21 */ + Uint8 rgucAccelY[2]; /* 23 */ + Uint8 rgucAccelZ[2]; /* 25 */ + Uint8 rgucSensorTimestamp[2]; /* 27 - 16 bit little endian */ + Uint8 ucBatteryLevel; /* 29 */ + Uint8 ucUnknown; /* 30 */ + Uint8 ucTouchpadCounter1; /* 31 - high bit clear + counter */ + Uint8 rgucTouchpadData1[3]; /* 32 - X/Y, 12 bits per axis */ + Uint8 ucTouchpadCounter2; /* 35 - high bit clear + counter */ + Uint8 rgucTouchpadData2[3]; /* 36 - X/Y, 12 bits per axis */ + + /* There's more unknown data at the end, and a 32-bit CRC on Bluetooth */ +} PS5StatePacketAlt_t; + +typedef struct +{ + Uint8 ucEnableBits1; /* 0 */ + Uint8 ucEnableBits2; /* 1 */ + Uint8 ucRumbleRight; /* 2 */ + Uint8 ucRumbleLeft; /* 3 */ + Uint8 ucHeadphoneVolume; /* 4 */ + Uint8 ucSpeakerVolume; /* 5 */ + Uint8 ucMicrophoneVolume; /* 6 */ + Uint8 ucAudioEnableBits; /* 7 */ + Uint8 ucMicLightMode; /* 8 */ + Uint8 ucAudioMuteBits; /* 9 */ + Uint8 rgucRightTriggerEffect[11]; /* 10 */ + Uint8 rgucLeftTriggerEffect[11]; /* 21 */ + Uint8 rgucUnknown1[6]; /* 32 */ + Uint8 ucEnableBits3; /* 38 */ + Uint8 rgucUnknown2[2]; /* 39 */ + Uint8 ucLedAnim; /* 41 */ + Uint8 ucLedBrightness; /* 42 */ + Uint8 ucPadLights; /* 43 */ + Uint8 ucLedRed; /* 44 */ + Uint8 ucLedGreen; /* 45 */ + Uint8 ucLedBlue; /* 46 */ +} DS5EffectsState_t; + +typedef enum +{ + k_EDS5EffectRumbleStart = (1 << 0), + k_EDS5EffectRumble = (1 << 1), + k_EDS5EffectLEDReset = (1 << 2), + k_EDS5EffectLED = (1 << 3), + k_EDS5EffectPadLights = (1 << 4), + k_EDS5EffectMicLight = (1 << 5) +} EDS5Effect; + +typedef enum +{ + k_EDS5LEDResetStateNone, + k_EDS5LEDResetStatePending, + k_EDS5LEDResetStateComplete, +} EDS5LEDResetState; + +typedef struct +{ + Sint16 bias; + float sensitivity; +} IMUCalibrationData; + +typedef struct +{ + SDL_HIDAPI_Device *device; + SDL_Joystick *joystick; + SDL_bool is_nacon_dongle; + SDL_bool use_alternate_report; + SDL_bool sensors_supported; + SDL_bool lightbar_supported; + SDL_bool vibration_supported; + SDL_bool playerled_supported; + SDL_bool touchpad_supported; + SDL_bool effects_supported; + SDL_bool enhanced_mode; + SDL_bool report_sensors; + SDL_bool report_touchpad; + SDL_bool hardware_calibration; + IMUCalibrationData calibration[6]; + Uint16 firmware_version; + Uint32 last_packet; + int player_index; + SDL_bool player_lights; + Uint8 rumble_left; + Uint8 rumble_right; + SDL_bool color_set; + Uint8 led_red; + Uint8 led_green; + Uint8 led_blue; + EDS5LEDResetState led_reset_state; + Uint32 last_timestamp; + Uint64 timestamp; + union + { + PS5SimpleStatePacket_t simple; + PS5StatePacketCommon_t state; + PS5StatePacketAlt_t alt_state; + PS5StatePacket_t full_state; + Uint8 data[64]; + } last_state; +} SDL_DriverPS5_Context; + +static int HIDAPI_DriverPS5_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *effect, int size); + +static void HIDAPI_DriverPS5_RegisterHints(SDL_HintCallback callback, void *userdata) +{ + SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_PS5, callback, userdata); +} + +static void HIDAPI_DriverPS5_UnregisterHints(SDL_HintCallback callback, void *userdata) +{ + SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_PS5, callback, userdata); +} + +static SDL_bool HIDAPI_DriverPS5_IsEnabled(void) +{ + return SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_PS5, SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI, SDL_HIDAPI_DEFAULT)); +} + +static int ReadFeatureReport(SDL_hid_device *dev, Uint8 report_id, Uint8 *report, size_t length) +{ + SDL_memset(report, 0, length); + report[0] = report_id; + return SDL_hid_get_feature_report(dev, report, length); +} + +static SDL_bool HIDAPI_DriverPS5_IsSupportedDevice(SDL_HIDAPI_Device *device, const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol) +{ + Uint8 data[USB_PACKET_LENGTH]; + int size; + + if (type == SDL_CONTROLLER_TYPE_PS5) { + return SDL_TRUE; + } + + if (HIDAPI_SupportsPlaystationDetection(vendor_id, product_id)) { + if (device && device->dev) { + size = ReadFeatureReport(device->dev, k_EPS5FeatureReportIdCapabilities, data, sizeof(data)); + if (size == 48 && data[2] == 0x28) { + /* Supported third party controller */ + return SDL_TRUE; + } else { + return SDL_FALSE; + } + } else { + /* Might be supported by this driver, enumerate and find out */ + return SDL_TRUE; + } + } + return SDL_FALSE; +} + +static void SetLedsForPlayerIndex(DS5EffectsState_t *effects, int player_index) +{ + /* This list is the same as what hid-sony.c uses in the Linux kernel. + The first 4 values correspond to what the PS4 assigns. + */ + static const Uint8 colors[7][3] = { + { 0x00, 0x00, 0x40 }, /* Blue */ + { 0x40, 0x00, 0x00 }, /* Red */ + { 0x00, 0x40, 0x00 }, /* Green */ + { 0x20, 0x00, 0x20 }, /* Pink */ + { 0x20, 0x10, 0x00 }, /* Orange */ + { 0x00, 0x10, 0x10 }, /* Teal */ + { 0x10, 0x10, 0x10 } /* White */ + }; + + if (player_index >= 0) { + player_index %= SDL_arraysize(colors); + } else { + player_index = 0; + } + + effects->ucLedRed = colors[player_index][0]; + effects->ucLedGreen = colors[player_index][1]; + effects->ucLedBlue = colors[player_index][2]; +} + +static void SetLightsForPlayerIndex(DS5EffectsState_t *effects, int player_index) +{ + static const Uint8 lights[] = { + 0x04, + 0x0A, + 0x15, + 0x1B, + 0x1F + }; + + if (player_index >= 0) { + /* Bitmask, 0x1F enables all lights, 0x20 changes instantly instead of fade */ + player_index %= SDL_arraysize(lights); + effects->ucPadLights = lights[player_index] | 0x20; + } else { + effects->ucPadLights = 0x00; + } +} + +static SDL_bool HIDAPI_DriverPS5_InitDevice(SDL_HIDAPI_Device *device) +{ + SDL_DriverPS5_Context *ctx; + Uint8 data[USB_PACKET_LENGTH * 2]; + int size; + char serial[18]; + SDL_JoystickType joystick_type = SDL_JOYSTICK_TYPE_GAMECONTROLLER; + + ctx = (SDL_DriverPS5_Context *)SDL_calloc(1, sizeof(*ctx)); + if (!ctx) { + SDL_OutOfMemory(); + return SDL_FALSE; + } + ctx->device = device; + + device->context = ctx; + + if (device->serial && SDL_strlen(device->serial) == 12) { + int i, j; + + j = -1; + for (i = 0; i < 12; i += 2) { + j += 1; + SDL_memcpy(&serial[j], &device->serial[i], 2); + j += 2; + serial[j] = '-'; + } + serial[j] = '\0'; + } else { + serial[0] = '\0'; + } + + /* Read a report to see what mode we're in */ + size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 16); +#ifdef DEBUG_PS5_PROTOCOL + if (size > 0) { + HIDAPI_DumpPacket("PS5 first packet: size = %d", data, size); + } else { + SDL_Log("PS5 first packet: size = %d\n", size); + } +#endif + if (size == 64) { + /* Connected over USB */ + device->is_bluetooth = SDL_FALSE; + ctx->enhanced_mode = SDL_TRUE; + } else if (size > 0 && data[0] == k_EPS5ReportIdBluetoothEffects) { + /* Connected over Bluetooth, using enhanced reports */ + device->is_bluetooth = SDL_TRUE; + ctx->enhanced_mode = SDL_TRUE; + } else { + /* Connected over Bluetooth, using simple reports (DirectInput enabled) */ + device->is_bluetooth = SDL_TRUE; + + /* Games written prior the introduction of PS5 controller support in SDL will not be aware of + SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, but they did know SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE. + To support apps that only knew about the PS4 hint, we'll use the PS4 hint as the default. + */ + ctx->enhanced_mode = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, + SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE, SDL_FALSE)); + } + + if (ctx->enhanced_mode) { + /* Read the serial number (Bluetooth address in reverse byte order) + This will also enable enhanced reports over Bluetooth + */ + if (ReadFeatureReport(device->dev, k_EPS5FeatureReportIdSerialNumber, data, sizeof(data)) >= 7) { + (void)SDL_snprintf(serial, sizeof(serial), "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x", + data[6], data[5], data[4], data[3], data[2], data[1]); + } + + /* Read the firmware version + This will also enable enhanced reports over Bluetooth + */ + if (ReadFeatureReport(device->dev, k_EPS5FeatureReportIdFirmwareInfo, data, USB_PACKET_LENGTH) >= 46) { + ctx->firmware_version = (Uint16)data[44] | ((Uint16)data[45] << 8); + } + } + + /* Get the device capabilities */ + if (device->vendor_id == USB_VENDOR_SONY) { + ctx->sensors_supported = SDL_TRUE; + ctx->lightbar_supported = SDL_TRUE; + ctx->vibration_supported = SDL_TRUE; + ctx->playerled_supported = SDL_TRUE; + ctx->touchpad_supported = SDL_TRUE; + } else { + /* Third party controller capability request */ + size = ReadFeatureReport(device->dev, k_EPS5FeatureReportIdCapabilities, data, sizeof(data)); + if (size == 48 && data[2] == 0x28) { + Uint8 capabilities = data[4]; + Uint8 capabilities2 = data[20]; + Uint8 device_type = data[5]; + +#ifdef DEBUG_PS5_PROTOCOL + HIDAPI_DumpPacket("PS5 capabilities: size = %d", data, size); +#endif + if (capabilities & 0x02) { + ctx->sensors_supported = SDL_TRUE; + } + if (capabilities & 0x04) { + ctx->lightbar_supported = SDL_TRUE; + } + if (capabilities & 0x08) { + ctx->vibration_supported = SDL_TRUE; + } + if (capabilities & 0x40) { + ctx->touchpad_supported = SDL_TRUE; + } + if (capabilities2 & 0x80) { + ctx->playerled_supported = SDL_TRUE; + } + + switch (device_type) { + case 0x00: + joystick_type = SDL_JOYSTICK_TYPE_GAMECONTROLLER; + break; + case 0x01: + joystick_type = SDL_JOYSTICK_TYPE_GUITAR; + break; + case 0x02: + joystick_type = SDL_JOYSTICK_TYPE_DRUM_KIT; + break; + case 0x06: + joystick_type = SDL_JOYSTICK_TYPE_WHEEL; + break; + case 0x07: + joystick_type = SDL_JOYSTICK_TYPE_ARCADE_STICK; + break; + case 0x08: + joystick_type = SDL_JOYSTICK_TYPE_FLIGHT_STICK; + break; + default: + joystick_type = SDL_JOYSTICK_TYPE_UNKNOWN; + break; + } + + ctx->use_alternate_report = SDL_TRUE; + + if (device->vendor_id == USB_VENDOR_NACON_ALT && + (device->product_id == USB_PRODUCT_NACON_REVOLUTION_5_PRO_PS5_WIRED || + device->product_id == USB_PRODUCT_NACON_REVOLUTION_5_PRO_PS5_WIRELESS)) { + /* This doesn't report vibration capability, but it can do rumble */ + ctx->vibration_supported = SDL_TRUE; + } + } else if (device->vendor_id == USB_VENDOR_RAZER && + (device->product_id == USB_PRODUCT_RAZER_WOLVERINE_V2_PRO_PS5_WIRED || + device->product_id == USB_PRODUCT_RAZER_WOLVERINE_V2_PRO_PS5_WIRELESS)) { + /* The Razer Wolverine V2 Pro doesn't respond to the detection protocol, but has a touchpad and sensors and no vibration */ + ctx->sensors_supported = SDL_TRUE; + ctx->touchpad_supported = SDL_TRUE; + ctx->use_alternate_report = SDL_TRUE; + } else if (device->vendor_id == USB_VENDOR_RAZER && + device->product_id == USB_PRODUCT_RAZER_KITSUNE) { + /* The Razer Kitsune doesn't respond to the detection protocol, but has a touchpad */ + joystick_type = SDL_JOYSTICK_TYPE_ARCADE_STICK; + ctx->touchpad_supported = SDL_TRUE; + ctx->use_alternate_report = SDL_TRUE; + } + } + ctx->effects_supported = (ctx->lightbar_supported || ctx->vibration_supported || ctx->playerled_supported); + + if (device->vendor_id == USB_VENDOR_NACON_ALT && + device->product_id == USB_PRODUCT_NACON_REVOLUTION_5_PRO_PS5_WIRELESS) { + ctx->is_nacon_dongle = SDL_TRUE; + } + + device->joystick_type = joystick_type; + device->type = SDL_CONTROLLER_TYPE_PS5; + if (device->vendor_id == USB_VENDOR_SONY) { + if (SDL_IsJoystickDualSenseEdge(device->vendor_id, device->product_id)) { + HIDAPI_SetDeviceName(device, "DualSense Edge Wireless Controller"); + } else { + HIDAPI_SetDeviceName(device, "DualSense Wireless Controller"); + } + } + HIDAPI_SetDeviceSerial(device, serial); + + if (ctx->is_nacon_dongle) { + /* We don't know if this is connected yet, wait for reports */ + return SDL_TRUE; + } + + /* Prefer the USB device over the Bluetooth device */ + if (device->is_bluetooth) { + if (HIDAPI_HasConnectedUSBDevice(device->serial)) { + return SDL_TRUE; + } + } else { + HIDAPI_DisconnectBluetoothDevice(device->serial); + } + return HIDAPI_JoystickConnected(device, NULL); +} + +static int HIDAPI_DriverPS5_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id) +{ + return -1; +} + +static void HIDAPI_DriverPS5_LoadCalibrationData(SDL_HIDAPI_Device *device) +{ + SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context; + int i, size; + Uint8 data[USB_PACKET_LENGTH]; + + size = ReadFeatureReport(device->dev, k_EPS5FeatureReportIdCalibration, data, sizeof(data)); + if (size < 35) { +#ifdef DEBUG_PS5_CALIBRATION + SDL_Log("Short read of calibration data: %d, ignoring calibration\n", size); +#endif + return; + } + + { + Sint16 sGyroPitchBias, sGyroYawBias, sGyroRollBias; + Sint16 sGyroPitchPlus, sGyroPitchMinus; + Sint16 sGyroYawPlus, sGyroYawMinus; + Sint16 sGyroRollPlus, sGyroRollMinus; + Sint16 sGyroSpeedPlus, sGyroSpeedMinus; + + Sint16 sAccXPlus, sAccXMinus; + Sint16 sAccYPlus, sAccYMinus; + Sint16 sAccZPlus, sAccZMinus; + + float flNumerator; + Sint16 sRange2g; + +#ifdef DEBUG_PS5_CALIBRATION + HIDAPI_DumpPacket("PS5 calibration packet: size = %d", data, size); +#endif + + sGyroPitchBias = LOAD16(data[1], data[2]); + sGyroYawBias = LOAD16(data[3], data[4]); + sGyroRollBias = LOAD16(data[5], data[6]); + + sGyroPitchPlus = LOAD16(data[7], data[8]); + sGyroPitchMinus = LOAD16(data[9], data[10]); + sGyroYawPlus = LOAD16(data[11], data[12]); + sGyroYawMinus = LOAD16(data[13], data[14]); + sGyroRollPlus = LOAD16(data[15], data[16]); + sGyroRollMinus = LOAD16(data[17], data[18]); + + sGyroSpeedPlus = LOAD16(data[19], data[20]); + sGyroSpeedMinus = LOAD16(data[21], data[22]); + + sAccXPlus = LOAD16(data[23], data[24]); + sAccXMinus = LOAD16(data[25], data[26]); + sAccYPlus = LOAD16(data[27], data[28]); + sAccYMinus = LOAD16(data[29], data[30]); + sAccZPlus = LOAD16(data[31], data[32]); + sAccZMinus = LOAD16(data[33], data[34]); + + flNumerator = (sGyroSpeedPlus + sGyroSpeedMinus) * GYRO_RES_PER_DEGREE; + ctx->calibration[0].bias = sGyroPitchBias; + ctx->calibration[0].sensitivity = flNumerator / (sGyroPitchPlus - sGyroPitchMinus); + + ctx->calibration[1].bias = sGyroYawBias; + ctx->calibration[1].sensitivity = flNumerator / (sGyroYawPlus - sGyroYawMinus); + + ctx->calibration[2].bias = sGyroRollBias; + ctx->calibration[2].sensitivity = flNumerator / (sGyroRollPlus - sGyroRollMinus); + + sRange2g = sAccXPlus - sAccXMinus; + ctx->calibration[3].bias = sAccXPlus - sRange2g / 2; + ctx->calibration[3].sensitivity = 2.0f * ACCEL_RES_PER_G / (float)sRange2g; + + sRange2g = sAccYPlus - sAccYMinus; + ctx->calibration[4].bias = sAccYPlus - sRange2g / 2; + ctx->calibration[4].sensitivity = 2.0f * ACCEL_RES_PER_G / (float)sRange2g; + + sRange2g = sAccZPlus - sAccZMinus; + ctx->calibration[5].bias = sAccZPlus - sRange2g / 2; + ctx->calibration[5].sensitivity = 2.0f * ACCEL_RES_PER_G / (float)sRange2g; + + ctx->hardware_calibration = SDL_TRUE; + for (i = 0; i < 6; ++i) { + float divisor = (i < 3 ? 64.0f : 1.0f); +#ifdef DEBUG_PS5_CALIBRATION + SDL_Log("calibration[%d] bias = %d, sensitivity = %f\n", i, ctx->calibration[i].bias, ctx->calibration[i].sensitivity); +#endif + /* Some controllers have a bad calibration */ + if ((SDL_abs(ctx->calibration[i].bias) > 1024) || (SDL_fabs(1.0f - ctx->calibration[i].sensitivity / divisor) > 0.5f)) { +#ifdef DEBUG_PS5_CALIBRATION + SDL_Log("invalid calibration, ignoring\n"); +#endif + ctx->hardware_calibration = SDL_FALSE; + } + } + } +} + +static float HIDAPI_DriverPS5_ApplyCalibrationData(SDL_DriverPS5_Context *ctx, int index, Sint16 value) +{ + float result; + + if (ctx->hardware_calibration) { + IMUCalibrationData *calibration = &ctx->calibration[index]; + + result = (value - calibration->bias) * calibration->sensitivity; + } else if (index < 3) { + result = value * 64.f; + } else { + result = value; + } + + /* Convert the raw data to the units expected by SDL */ + if (index < 3) { + result = (result / GYRO_RES_PER_DEGREE) * (float)M_PI / 180.0f; + } else { + result = (result / ACCEL_RES_PER_G) * SDL_STANDARD_GRAVITY; + } + return result; +} + +static int HIDAPI_DriverPS5_UpdateEffects(SDL_HIDAPI_Device *device, int effect_mask) +{ + SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context; + DS5EffectsState_t effects; + + if (!ctx->enhanced_mode || !ctx->effects_supported) { + return SDL_Unsupported(); + } + + SDL_zero(effects); + + /* Make sure the Bluetooth connection sequence has completed before sending LED color change */ + if (device->is_bluetooth && + (effect_mask & (k_EDS5EffectLED | k_EDS5EffectPadLights)) != 0) { + if (ctx->led_reset_state != k_EDS5LEDResetStateComplete) { + ctx->led_reset_state = k_EDS5LEDResetStatePending; + return 0; + } + } + + if (ctx->vibration_supported) { + if (ctx->rumble_left || ctx->rumble_right) { + if (ctx->firmware_version < 0x0224) { + effects.ucEnableBits1 |= 0x01; /* Enable rumble emulation */ + + /* Shift to reduce effective rumble strength to match Xbox controllers */ + effects.ucRumbleLeft = ctx->rumble_left >> 1; + effects.ucRumbleRight = ctx->rumble_right >> 1; + } else { + effects.ucEnableBits3 |= 0x04; /* Enable improved rumble emulation on 2.24 firmware and newer */ + + effects.ucRumbleLeft = ctx->rumble_left; + effects.ucRumbleRight = ctx->rumble_right; + } + effects.ucEnableBits1 |= 0x02; /* Disable audio haptics */ + } else { + /* Leaving emulated rumble bits off will restore audio haptics */ + } + + if ((effect_mask & k_EDS5EffectRumbleStart) != 0) { + effects.ucEnableBits1 |= 0x02; /* Disable audio haptics */ + } + if ((effect_mask & k_EDS5EffectRumble) != 0) { + /* Already handled above */ + } + } + if (ctx->lightbar_supported) { + if ((effect_mask & k_EDS5EffectLEDReset) != 0) { + effects.ucEnableBits2 |= 0x08; /* Reset LED state */ + } + if ((effect_mask & k_EDS5EffectLED) != 0) { + effects.ucEnableBits2 |= 0x04; /* Enable LED color */ + + /* Populate the LED state with the appropriate color from our lookup table */ + if (ctx->color_set) { + effects.ucLedRed = ctx->led_red; + effects.ucLedGreen = ctx->led_green; + effects.ucLedBlue = ctx->led_blue; + } else { + SetLedsForPlayerIndex(&effects, ctx->player_index); + } + } + } + if (ctx->playerled_supported) { + if ((effect_mask & k_EDS5EffectPadLights) != 0) { + effects.ucEnableBits2 |= 0x10; /* Enable touchpad lights */ + + if (ctx->player_lights) { + SetLightsForPlayerIndex(&effects, ctx->player_index); + } else { + effects.ucPadLights = 0x00; + } + } + } + if ((effect_mask & k_EDS5EffectMicLight) != 0) { + effects.ucEnableBits2 |= 0x01; /* Enable microphone light */ + + effects.ucMicLightMode = 0; /* Bitmask, 0x00 = off, 0x01 = solid, 0x02 = pulse */ + } + + return HIDAPI_DriverPS5_SendJoystickEffect(device, ctx->joystick, &effects, sizeof(effects)); +} + +static void HIDAPI_DriverPS5_CheckPendingLEDReset(SDL_HIDAPI_Device *device) +{ + SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context; + SDL_bool led_reset_complete = SDL_FALSE; + + if (ctx->enhanced_mode && ctx->sensors_supported && !ctx->use_alternate_report) { + const PS5StatePacketCommon_t *packet = &ctx->last_state.state; + + /* Check the timer to make sure the Bluetooth connection LED animation is complete */ + const Uint32 connection_complete = 10200000; + Uint32 timestamp = LOAD32(packet->rgucSensorTimestamp[0], + packet->rgucSensorTimestamp[1], + packet->rgucSensorTimestamp[2], + packet->rgucSensorTimestamp[3]); + if (timestamp >= connection_complete) { + led_reset_complete = SDL_TRUE; + } + } else { + /* We don't know how to check the timer, just assume it's complete for now */ + led_reset_complete = SDL_TRUE; + } + + if (led_reset_complete) { + HIDAPI_DriverPS5_UpdateEffects(device, k_EDS5EffectLEDReset); + + ctx->led_reset_state = k_EDS5LEDResetStateComplete; + + HIDAPI_DriverPS5_UpdateEffects(device, (k_EDS5EffectLED | k_EDS5EffectPadLights)); + } +} + +static void HIDAPI_DriverPS5_TickleBluetooth(SDL_HIDAPI_Device *device) +{ + SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context; + + if (ctx->enhanced_mode) { + /* This is just a dummy packet that should have no effect, since we don't set the CRC */ + Uint8 data[78]; + + SDL_zeroa(data); + + data[0] = k_EPS5ReportIdBluetoothEffects; + data[1] = 0x02; /* Magic value */ + + if (SDL_HIDAPI_LockRumble() == 0) { + SDL_HIDAPI_SendRumbleAndUnlock(device, data, sizeof(data)); + } + } else { + /* We can't even send an invalid effects packet, or it will put the controller in enhanced mode */ + if (device->num_joysticks > 0) { + HIDAPI_JoystickDisconnected(device, device->joysticks[0]); + } + } +} + +static void HIDAPI_DriverPS5_SetEnhancedMode(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context; + + if (!ctx->enhanced_mode) { + ctx->enhanced_mode = SDL_TRUE; + + if (ctx->touchpad_supported) { + SDL_PrivateJoystickAddTouchpad(joystick, 2); + ctx->report_touchpad = SDL_TRUE; + } + if (ctx->sensors_supported) { + if (device->is_bluetooth) { + /* Bluetooth sensor update rate appears to be 1000 Hz */ + SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, 1000.0f); + SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, 1000.0f); + } else { + SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, 250.0f); + SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, 250.0f); + } + } + + /* Switch into enhanced report mode */ + HIDAPI_DriverPS5_UpdateEffects(device, 0); + + /* Update the light effects */ + HIDAPI_DriverPS5_UpdateEffects(device, (k_EDS5EffectLED | k_EDS5EffectPadLights)); + } +} + +static void SDLCALL SDL_PS5RumbleHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)userdata; + + /* This is a one-way trip, you can't switch the controller back to simple report mode */ + if (SDL_GetStringBoolean(hint, SDL_FALSE)) { + HIDAPI_DriverPS5_SetEnhancedMode(ctx->device, ctx->joystick); + } +} + +static void SDLCALL SDL_PS5PlayerLEDHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)userdata; + SDL_bool player_lights = SDL_GetStringBoolean(hint, SDL_TRUE); + + if (player_lights != ctx->player_lights) { + ctx->player_lights = player_lights; + + HIDAPI_DriverPS5_UpdateEffects(ctx->device, k_EDS5EffectPadLights); + } +} + +static void HIDAPI_DriverPS5_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index) +{ + SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context; + + if (!ctx->joystick) { + return; + } + + ctx->player_index = player_index; + + /* This will set the new LED state based on the new player index */ + HIDAPI_DriverPS5_UpdateEffects(device, (k_EDS5EffectLED | k_EDS5EffectPadLights)); +} + +static SDL_bool HIDAPI_DriverPS5_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context; + + SDL_AssertJoysticksLocked(); + + ctx->joystick = joystick; + ctx->last_packet = SDL_GetTicks(); + ctx->report_sensors = SDL_FALSE; + ctx->report_touchpad = SDL_FALSE; + ctx->rumble_left = 0; + ctx->rumble_right = 0; + ctx->color_set = SDL_FALSE; + ctx->led_reset_state = k_EDS5LEDResetStateNone; + SDL_zero(ctx->last_state); + + /* Initialize player index (needed for setting LEDs) */ + ctx->player_index = SDL_JoystickGetPlayerIndex(joystick); + ctx->player_lights = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_PS5_PLAYER_LED, SDL_TRUE); + + /* Initialize the joystick capabilities */ + if (SDL_IsJoystickDualSenseEdge(device->vendor_id, device->product_id)) { + joystick->nbuttons = 21; + } else if (ctx->touchpad_supported) { + joystick->nbuttons = 17; + } else { + joystick->nbuttons = 15; + } + joystick->naxes = SDL_CONTROLLER_AXIS_MAX; + joystick->epowerlevel = device->is_bluetooth ? SDL_JOYSTICK_POWER_UNKNOWN : SDL_JOYSTICK_POWER_WIRED; + joystick->firmware_version = ctx->firmware_version; + + if (ctx->enhanced_mode) { + /* Force initialization when opening the joystick */ + ctx->enhanced_mode = SDL_FALSE; + HIDAPI_DriverPS5_SetEnhancedMode(device, joystick); + } else { + SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, + SDL_PS5RumbleHintChanged, ctx); + } + SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_PS5_PLAYER_LED, + SDL_PS5PlayerLEDHintChanged, ctx); + + return SDL_TRUE; +} + +static int HIDAPI_DriverPS5_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ + SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context; + + if (!ctx->vibration_supported) { + return SDL_Unsupported(); + } + + if (!ctx->rumble_left && !ctx->rumble_right) { + HIDAPI_DriverPS5_UpdateEffects(device, k_EDS5EffectRumbleStart); + } + + ctx->rumble_left = (low_frequency_rumble >> 8); + ctx->rumble_right = (high_frequency_rumble >> 8); + + return HIDAPI_DriverPS5_UpdateEffects(device, k_EDS5EffectRumble); +} + +static int HIDAPI_DriverPS5_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) +{ + return SDL_Unsupported(); +} + +static Uint32 HIDAPI_DriverPS5_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context; + Uint32 result = 0; + + if (ctx->enhanced_mode) { + if (ctx->lightbar_supported) { + result |= SDL_JOYCAP_LED; + } + if (ctx->vibration_supported) { + result |= SDL_JOYCAP_RUMBLE; + } + } + + return result; +} + +static int HIDAPI_DriverPS5_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context; + + if (!ctx->lightbar_supported) { + return SDL_Unsupported(); + } + + ctx->color_set = SDL_TRUE; + ctx->led_red = red; + ctx->led_green = green; + ctx->led_blue = blue; + + return HIDAPI_DriverPS5_UpdateEffects(device, k_EDS5EffectLED); +} + +static int HIDAPI_DriverPS5_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *effect, int size) +{ + SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context; + Uint8 data[78]; + int report_size, offset; + Uint8 *pending_data; + int *pending_size; + int maximum_size; + + if (!ctx->effects_supported) { + return SDL_Unsupported(); + } + + if (!ctx->enhanced_mode) { + HIDAPI_DriverPS5_SetEnhancedMode(device, joystick); + } + + SDL_zeroa(data); + + if (device->is_bluetooth) { + data[0] = k_EPS5ReportIdBluetoothEffects; + data[1] = 0x02; /* Magic value */ + + report_size = 78; + offset = 2; + } else { + data[0] = k_EPS5ReportIdUsbEffects; + + report_size = 48; + offset = 1; + } + + SDL_memcpy(&data[offset], effect, SDL_min((sizeof(data) - offset), (size_t)size)); + + if (device->is_bluetooth) { + /* Bluetooth reports need a CRC at the end of the packet (at least on Linux) */ + Uint8 ubHdr = 0xA2; /* hidp header is part of the CRC calculation */ + Uint32 unCRC; + unCRC = SDL_crc32(0, &ubHdr, 1); + unCRC = SDL_crc32(unCRC, data, (size_t)(report_size - sizeof(unCRC))); + SDL_memcpy(&data[report_size - sizeof(unCRC)], &unCRC, sizeof(unCRC)); + } + + if (SDL_HIDAPI_LockRumble() != 0) { + return -1; + } + + /* See if we can update an existing pending request */ + if (SDL_HIDAPI_GetPendingRumbleLocked(device, &pending_data, &pending_size, &maximum_size)) { + DS5EffectsState_t *effects = (DS5EffectsState_t *)&data[offset]; + DS5EffectsState_t *pending_effects = (DS5EffectsState_t *)&pending_data[offset]; + if (report_size == *pending_size && + effects->ucEnableBits1 == pending_effects->ucEnableBits1 && + effects->ucEnableBits2 == pending_effects->ucEnableBits2) { + /* We're simply updating the data for this request */ + SDL_memcpy(pending_data, data, report_size); + SDL_HIDAPI_UnlockRumble(); + return 0; + } + } + + if (SDL_HIDAPI_SendRumbleAndUnlock(device, data, report_size) != report_size) { + return -1; + } + + return 0; +} + +static int HIDAPI_DriverPS5_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled) +{ + SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context; + + if (!ctx->enhanced_mode) { + return SDL_Unsupported(); + } + + if (enabled) { + HIDAPI_DriverPS5_LoadCalibrationData(device); + } + ctx->report_sensors = enabled; + ctx->timestamp = 0; + + return 0; +} + +static void HIDAPI_DriverPS5_HandleSimpleStatePacket(SDL_Joystick *joystick, SDL_hid_device *dev, SDL_DriverPS5_Context *ctx, PS5SimpleStatePacket_t *packet) +{ + Sint16 axis; + + if (ctx->last_state.simple.rgucButtonsHatAndCounter[0] != packet->rgucButtonsHatAndCounter[0]) { + { + Uint8 data = (packet->rgucButtonsHatAndCounter[0] >> 4); + + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_X, (data & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_A, (data & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_B, (data & 0x04) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_Y, (data & 0x08) ? SDL_PRESSED : SDL_RELEASED); + } + { + Uint8 data = (packet->rgucButtonsHatAndCounter[0] & 0x0F); + SDL_bool dpad_up = SDL_FALSE; + SDL_bool dpad_down = SDL_FALSE; + SDL_bool dpad_left = SDL_FALSE; + SDL_bool dpad_right = SDL_FALSE; + + switch (data) { + case 0: + dpad_up = SDL_TRUE; + break; + case 1: + dpad_up = SDL_TRUE; + dpad_right = SDL_TRUE; + break; + case 2: + dpad_right = SDL_TRUE; + break; + case 3: + dpad_right = SDL_TRUE; + dpad_down = SDL_TRUE; + break; + case 4: + dpad_down = SDL_TRUE; + break; + case 5: + dpad_left = SDL_TRUE; + dpad_down = SDL_TRUE; + break; + case 6: + dpad_left = SDL_TRUE; + break; + case 7: + dpad_up = SDL_TRUE; + dpad_left = SDL_TRUE; + break; + default: + break; + } + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, dpad_down); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, dpad_up); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, dpad_right); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, dpad_left); + } + } + + if (ctx->last_state.simple.rgucButtonsHatAndCounter[1] != packet->rgucButtonsHatAndCounter[1]) { + Uint8 data = packet->rgucButtonsHatAndCounter[1]; + + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (data & 0x40) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data & 0x80) ? SDL_PRESSED : SDL_RELEASED); + } + + if (ctx->last_state.simple.rgucButtonsHatAndCounter[2] != packet->rgucButtonsHatAndCounter[2]) { + Uint8 data = (packet->rgucButtonsHatAndCounter[2] & 0x03); + + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MISC1, (data & 0x02) ? SDL_PRESSED : SDL_RELEASED); + } + + if (packet->ucTriggerLeft == 0 && (packet->rgucButtonsHatAndCounter[1] & 0x04)) { + axis = SDL_JOYSTICK_AXIS_MAX; + } else { + axis = ((int)packet->ucTriggerLeft * 257) - 32768; + } + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, axis); + if (packet->ucTriggerRight == 0 && (packet->rgucButtonsHatAndCounter[1] & 0x08)) { + axis = SDL_JOYSTICK_AXIS_MAX; + } else { + axis = ((int)packet->ucTriggerRight * 257) - 32768; + } + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, axis); + axis = ((int)packet->ucLeftJoystickX * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis); + axis = ((int)packet->ucLeftJoystickY * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, axis); + axis = ((int)packet->ucRightJoystickX * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, axis); + axis = ((int)packet->ucRightJoystickY * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis); + + SDL_memcpy(&ctx->last_state.simple, packet, sizeof(ctx->last_state.simple)); +} + +static void HIDAPI_DriverPS5_HandleStatePacketCommon(SDL_Joystick *joystick, SDL_hid_device *dev, SDL_DriverPS5_Context *ctx, PS5StatePacketCommon_t *packet) +{ + Sint16 axis; + + if (ctx->last_state.state.rgucButtonsAndHat[0] != packet->rgucButtonsAndHat[0]) { + { + Uint8 data = (packet->rgucButtonsAndHat[0] >> 4); + + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_X, (data & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_A, (data & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_B, (data & 0x04) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_Y, (data & 0x08) ? SDL_PRESSED : SDL_RELEASED); + } + { + Uint8 data = (packet->rgucButtonsAndHat[0] & 0x0F); + SDL_bool dpad_up = SDL_FALSE; + SDL_bool dpad_down = SDL_FALSE; + SDL_bool dpad_left = SDL_FALSE; + SDL_bool dpad_right = SDL_FALSE; + + switch (data) { + case 0: + dpad_up = SDL_TRUE; + break; + case 1: + dpad_up = SDL_TRUE; + dpad_right = SDL_TRUE; + break; + case 2: + dpad_right = SDL_TRUE; + break; + case 3: + dpad_right = SDL_TRUE; + dpad_down = SDL_TRUE; + break; + case 4: + dpad_down = SDL_TRUE; + break; + case 5: + dpad_left = SDL_TRUE; + dpad_down = SDL_TRUE; + break; + case 6: + dpad_left = SDL_TRUE; + break; + case 7: + dpad_up = SDL_TRUE; + dpad_left = SDL_TRUE; + break; + default: + break; + } + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, dpad_down); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, dpad_up); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, dpad_right); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, dpad_left); + } + } + + if (ctx->last_state.state.rgucButtonsAndHat[1] != packet->rgucButtonsAndHat[1]) { + Uint8 data = packet->rgucButtonsAndHat[1]; + + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (data & 0x40) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data & 0x80) ? SDL_PRESSED : SDL_RELEASED); + } + + if (ctx->last_state.state.rgucButtonsAndHat[2] != packet->rgucButtonsAndHat[2]) { + Uint8 data = packet->rgucButtonsAndHat[2]; + + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MISC1, (data & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_PS5_TOUCHPAD, (data & 0x04) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_PS5_LEFT_FUNCTION, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_PS5_RIGHT_FUNCTION, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_PS5_LEFT_PADDLE, (data & 0x40) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_PS5_RIGHT_PADDLE, (data & 0x80) ? SDL_PRESSED : SDL_RELEASED); + } + + if (packet->ucTriggerLeft == 0 && (packet->rgucButtonsAndHat[1] & 0x04)) { + axis = SDL_JOYSTICK_AXIS_MAX; + } else { + axis = ((int)packet->ucTriggerLeft * 257) - 32768; + } + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, axis); + if (packet->ucTriggerRight == 0 && (packet->rgucButtonsAndHat[1] & 0x08)) { + axis = SDL_JOYSTICK_AXIS_MAX; + } else { + axis = ((int)packet->ucTriggerRight * 257) - 32768; + } + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, axis); + axis = ((int)packet->ucLeftJoystickX * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis); + axis = ((int)packet->ucLeftJoystickY * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, axis); + axis = ((int)packet->ucRightJoystickX * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, axis); + axis = ((int)packet->ucRightJoystickY * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis); + + if (ctx->report_sensors) { + float data[3]; + Uint64 timestamp_us; + + if (ctx->use_alternate_report) { + /* 16-bit timestamp */ + Uint16 timestamp; + + timestamp = LOAD16(packet->rgucSensorTimestamp[0], + packet->rgucSensorTimestamp[1]); + if (ctx->timestamp) { + Uint16 delta; + + if (ctx->last_timestamp > timestamp) { + delta = (SDL_MAX_UINT16 - ctx->last_timestamp + timestamp + 1); + } else { + delta = (timestamp - ctx->last_timestamp); + } + ctx->timestamp += delta; + } else { + ctx->timestamp = timestamp; + } + ctx->last_timestamp = timestamp; + + /* Sensor timestamp is in 1us units */ + timestamp_us = ctx->timestamp; + } else { + /* 32-bit timestamp */ + Uint32 timestamp; + + timestamp = LOAD32(packet->rgucSensorTimestamp[0], + packet->rgucSensorTimestamp[1], + packet->rgucSensorTimestamp[2], + packet->rgucSensorTimestamp[3]); + if (ctx->timestamp) { + Uint32 delta; + + if (ctx->last_timestamp > timestamp) { + delta = (SDL_MAX_UINT32 - ctx->last_timestamp + timestamp + 1); + } else { + delta = (timestamp - ctx->last_timestamp); + } + ctx->timestamp += delta; + } else { + ctx->timestamp = timestamp; + } + ctx->last_timestamp = timestamp; + + /* Sensor timestamp is in 0.33us units */ + timestamp_us = ctx->timestamp / 3; + } + + data[0] = HIDAPI_DriverPS5_ApplyCalibrationData(ctx, 0, LOAD16(packet->rgucGyroX[0], packet->rgucGyroX[1])); + data[1] = HIDAPI_DriverPS5_ApplyCalibrationData(ctx, 1, LOAD16(packet->rgucGyroY[0], packet->rgucGyroY[1])); + data[2] = HIDAPI_DriverPS5_ApplyCalibrationData(ctx, 2, LOAD16(packet->rgucGyroZ[0], packet->rgucGyroZ[1])); + SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_GYRO, timestamp_us, data, 3); + + data[0] = HIDAPI_DriverPS5_ApplyCalibrationData(ctx, 3, LOAD16(packet->rgucAccelX[0], packet->rgucAccelX[1])); + data[1] = HIDAPI_DriverPS5_ApplyCalibrationData(ctx, 4, LOAD16(packet->rgucAccelY[0], packet->rgucAccelY[1])); + data[2] = HIDAPI_DriverPS5_ApplyCalibrationData(ctx, 5, LOAD16(packet->rgucAccelZ[0], packet->rgucAccelZ[1])); + SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_ACCEL, timestamp_us, data, 3); + } +} + +static void HIDAPI_DriverPS5_HandleStatePacket(SDL_Joystick *joystick, SDL_hid_device *dev, SDL_DriverPS5_Context *ctx, PS5StatePacket_t *packet) +{ + static const float TOUCHPAD_SCALEX = 1.0f / 1920; + static const float TOUCHPAD_SCALEY = 1.0f / 1070; + Uint8 touchpad_state; + int touchpad_x, touchpad_y; + + if (ctx->report_touchpad) { + touchpad_state = !(packet->ucTouchpadCounter1 & 0x80) ? SDL_PRESSED : SDL_RELEASED; + touchpad_x = packet->rgucTouchpadData1[0] | (((int)packet->rgucTouchpadData1[1] & 0x0F) << 8); + touchpad_y = (packet->rgucTouchpadData1[1] >> 4) | ((int)packet->rgucTouchpadData1[2] << 4); + SDL_PrivateJoystickTouchpad(joystick, 0, 0, touchpad_state, touchpad_x * TOUCHPAD_SCALEX, touchpad_y * TOUCHPAD_SCALEY, touchpad_state ? 1.0f : 0.0f); + + touchpad_state = !(packet->ucTouchpadCounter2 & 0x80) ? SDL_PRESSED : SDL_RELEASED; + touchpad_x = packet->rgucTouchpadData2[0] | (((int)packet->rgucTouchpadData2[1] & 0x0F) << 8); + touchpad_y = (packet->rgucTouchpadData2[1] >> 4) | ((int)packet->rgucTouchpadData2[2] << 4); + SDL_PrivateJoystickTouchpad(joystick, 0, 1, touchpad_state, touchpad_x * TOUCHPAD_SCALEX, touchpad_y * TOUCHPAD_SCALEY, touchpad_state ? 1.0f : 0.0f); + } + + /* A check of packet->ucBatteryLevel & 0x10 should work as a check for BT vs USB but doesn't + * seem to always work. Possibly related to being 100% charged? + */ + if (!ctx->device->is_bluetooth) { + /* 0x20 set means fully charged */ + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_WIRED); + } else { + /* Battery level ranges from 0 to 10 */ + int level = (packet->ucBatteryLevel & 0xF); + if (level == 0) { + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_EMPTY); + } else if (level <= 2) { + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_LOW); + } else if (level <= 7) { + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_MEDIUM); + } else { + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_FULL); + } + } + + SDL_memcpy(&ctx->last_state, packet, sizeof(ctx->last_state)); +} + +static void HIDAPI_DriverPS5_HandleStatePacketAlt(SDL_Joystick *joystick, SDL_hid_device *dev, SDL_DriverPS5_Context *ctx, PS5StatePacketAlt_t *packet) +{ + static const float TOUCHPAD_SCALEX = 1.0f / 1920; + static const float TOUCHPAD_SCALEY = 1.0f / 1070; + Uint8 touchpad_state; + int touchpad_x, touchpad_y; + + if (ctx->report_touchpad) { + touchpad_state = !(packet->ucTouchpadCounter1 & 0x80) ? SDL_PRESSED : SDL_RELEASED; + touchpad_x = packet->rgucTouchpadData1[0] | (((int)packet->rgucTouchpadData1[1] & 0x0F) << 8); + touchpad_y = (packet->rgucTouchpadData1[1] >> 4) | ((int)packet->rgucTouchpadData1[2] << 4); + SDL_PrivateJoystickTouchpad(joystick, 0, 0, touchpad_state, touchpad_x * TOUCHPAD_SCALEX, touchpad_y * TOUCHPAD_SCALEY, touchpad_state ? 1.0f : 0.0f); + + touchpad_state = !(packet->ucTouchpadCounter2 & 0x80) ? SDL_PRESSED : SDL_RELEASED; + touchpad_x = packet->rgucTouchpadData2[0] | (((int)packet->rgucTouchpadData2[1] & 0x0F) << 8); + touchpad_y = (packet->rgucTouchpadData2[1] >> 4) | ((int)packet->rgucTouchpadData2[2] << 4); + SDL_PrivateJoystickTouchpad(joystick, 0, 1, touchpad_state, touchpad_x * TOUCHPAD_SCALEX, touchpad_y * TOUCHPAD_SCALEY, touchpad_state ? 1.0f : 0.0f); + } + + SDL_memcpy(&ctx->last_state, packet, sizeof(ctx->last_state)); +} + +static SDL_bool VerifyCRC(Uint8 *data, int size) +{ + Uint8 ubHdr = 0xA1; /* hidp header is part of the CRC calculation */ + Uint32 unCRC, unPacketCRC; + Uint8 *packetCRC = data + size - sizeof(unPacketCRC); + unCRC = SDL_crc32(0, &ubHdr, 1); + unCRC = SDL_crc32(unCRC, data, (size_t)(size - sizeof(unCRC))); + + unPacketCRC = LOAD32(packetCRC[0], + packetCRC[1], + packetCRC[2], + packetCRC[3]); + return (unCRC == unPacketCRC) ? SDL_TRUE : SDL_FALSE; +} + +static SDL_bool HIDAPI_DriverPS5_IsPacketValid(SDL_DriverPS5_Context *ctx, Uint8 *data, int size) +{ + switch (data[0]) { + case k_EPS5ReportIdState: + if (ctx->is_nacon_dongle && size >= (1 + sizeof(PS5StatePacketAlt_t))) { + /* The report timestamp doesn't change when the controller isn't connected */ + PS5StatePacketAlt_t *packet = (PS5StatePacketAlt_t *)&data[1]; + if (SDL_memcmp(packet->rgucPacketSequence, ctx->last_state.state.rgucPacketSequence, sizeof(packet->rgucPacketSequence)) == 0) { + return SDL_FALSE; + } + if (ctx->last_state.alt_state.rgucAccelX[0] == 0 && ctx->last_state.alt_state.rgucAccelX[1] == 0 && + ctx->last_state.alt_state.rgucAccelY[0] == 0 && ctx->last_state.alt_state.rgucAccelY[1] == 0 && + ctx->last_state.alt_state.rgucAccelZ[0] == 0 && ctx->last_state.alt_state.rgucAccelZ[1] == 0) { + /* We don't have any state to compare yet, go ahead and copy it */ + SDL_memcpy(&ctx->last_state, &data[1], sizeof(PS5StatePacketAlt_t)); + return SDL_FALSE; + } + } + return SDL_TRUE; + + case k_EPS5ReportIdBluetoothState: + if (VerifyCRC(data, size)) { + return SDL_TRUE; + } + break; + default: + break; + } + return SDL_FALSE; +} + +static SDL_bool HIDAPI_DriverPS5_UpdateDevice(SDL_HIDAPI_Device *device) +{ + SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context; + SDL_Joystick *joystick = NULL; + Uint8 data[USB_PACKET_LENGTH * 2]; + int size; + int packet_count = 0; + Uint32 now = SDL_GetTicks(); + + if (device->num_joysticks > 0) { + joystick = SDL_JoystickFromInstanceID(device->joysticks[0]); + } + + while ((size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) { +#ifdef DEBUG_PS5_PROTOCOL + HIDAPI_DumpPacket("PS5 packet: size = %d", data, size); +#endif + if (!HIDAPI_DriverPS5_IsPacketValid(ctx, data, size)) { + continue; + } + + ++packet_count; + ctx->last_packet = now; + + if (!joystick) { + continue; + } + + switch (data[0]) { + case k_EPS5ReportIdState: + if (size == 10 || size == 78) { + HIDAPI_DriverPS5_HandleSimpleStatePacket(joystick, device->dev, ctx, (PS5SimpleStatePacket_t *)&data[1]); + } else { + HIDAPI_DriverPS5_HandleStatePacketCommon(joystick, device->dev, ctx, (PS5StatePacketCommon_t *)&data[1]); + if (ctx->use_alternate_report) { + HIDAPI_DriverPS5_HandleStatePacketAlt(joystick, device->dev, ctx, (PS5StatePacketAlt_t *)&data[1]); + } else { + HIDAPI_DriverPS5_HandleStatePacket(joystick, device->dev, ctx, (PS5StatePacket_t *)&data[1]); + } + } + break; + case k_EPS5ReportIdBluetoothState: + if (!ctx->enhanced_mode) { + /* This is the extended report, we can enable effects now */ + HIDAPI_DriverPS5_SetEnhancedMode(device, joystick); + } + HIDAPI_DriverPS5_HandleStatePacketCommon(joystick, device->dev, ctx, (PS5StatePacketCommon_t *)&data[2]); + if (ctx->use_alternate_report) { + HIDAPI_DriverPS5_HandleStatePacketAlt(joystick, device->dev, ctx, (PS5StatePacketAlt_t *)&data[2]); + } else { + HIDAPI_DriverPS5_HandleStatePacket(joystick, device->dev, ctx, (PS5StatePacket_t *)&data[2]); + } + if (ctx->led_reset_state == k_EDS5LEDResetStatePending) { + HIDAPI_DriverPS5_CheckPendingLEDReset(device); + } + break; + default: +#ifdef DEBUG_JOYSTICK + SDL_Log("Unknown PS5 packet: 0x%.2x\n", data[0]); +#endif + break; + } + } + + if (device->is_bluetooth) { + if (packet_count == 0) { + /* Check to see if it looks like the device disconnected */ + if (SDL_TICKS_PASSED(now, ctx->last_packet + BLUETOOTH_DISCONNECT_TIMEOUT_MS)) { + /* Send an empty output report to tickle the Bluetooth stack */ + HIDAPI_DriverPS5_TickleBluetooth(device); + } + } else { + /* Reconnect the Bluetooth device once the USB device is gone */ + if (device->num_joysticks == 0 && + !HIDAPI_HasConnectedUSBDevice(device->serial)) { + HIDAPI_JoystickConnected(device, NULL); + } + } + } + + if (ctx->is_nacon_dongle) { + if (packet_count == 0) { + if (device->num_joysticks > 0) { + /* Check to see if it looks like the device disconnected */ + if (SDL_TICKS_PASSED(now, ctx->last_packet + BLUETOOTH_DISCONNECT_TIMEOUT_MS)) { + HIDAPI_JoystickDisconnected(device, device->joysticks[0]); + } + } + } else { + if (device->num_joysticks == 0) { + HIDAPI_JoystickConnected(device, NULL); + } + } + } + + if (packet_count == 0 && size < 0 && device->num_joysticks > 0) { + /* Read error, device is disconnected */ + HIDAPI_JoystickDisconnected(device, device->joysticks[0]); + } + return size >= 0; +} + +static void HIDAPI_DriverPS5_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context; + + SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, + SDL_PS5RumbleHintChanged, ctx); + + SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_PS5_PLAYER_LED, + SDL_PS5PlayerLEDHintChanged, ctx); + + ctx->joystick = NULL; +} + +static void HIDAPI_DriverPS5_FreeDevice(SDL_HIDAPI_Device *device) +{ +} + +SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS5 = { + SDL_HINT_JOYSTICK_HIDAPI_PS5, + SDL_TRUE, + HIDAPI_DriverPS5_RegisterHints, + HIDAPI_DriverPS5_UnregisterHints, + HIDAPI_DriverPS5_IsEnabled, + HIDAPI_DriverPS5_IsSupportedDevice, + HIDAPI_DriverPS5_InitDevice, + HIDAPI_DriverPS5_GetDevicePlayerIndex, + HIDAPI_DriverPS5_SetDevicePlayerIndex, + HIDAPI_DriverPS5_UpdateDevice, + HIDAPI_DriverPS5_OpenJoystick, + HIDAPI_DriverPS5_RumbleJoystick, + HIDAPI_DriverPS5_RumbleJoystickTriggers, + HIDAPI_DriverPS5_GetJoystickCapabilities, + HIDAPI_DriverPS5_SetJoystickLED, + HIDAPI_DriverPS5_SendJoystickEffect, + HIDAPI_DriverPS5_SetJoystickSensorsEnabled, + HIDAPI_DriverPS5_CloseJoystick, + HIDAPI_DriverPS5_FreeDevice, +}; + +#endif /* SDL_JOYSTICK_HIDAPI_PS5 */ + +#endif /* SDL_JOYSTICK_HIDAPI */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/joystick/hidapi/SDL_hidapi_rumble.c b/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_rumble.c similarity index 67% rename from SDL2-2.0.12/src/joystick/hidapi/SDL_hidapi_rumble.c rename to SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_rumble.c index c0d932b..2bb166e 100644 --- a/SDL2-2.0.12/src/joystick/hidapi/SDL_hidapi_rumble.c +++ b/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_rumble.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -24,18 +24,19 @@ /* Handle rumble on a separate thread so it doesn't block the application */ -#include "SDL_assert.h" #include "SDL_thread.h" +#include "SDL_timer.h" #include "SDL_hidapijoystick_c.h" #include "SDL_hidapi_rumble.h" #include "../../thread/SDL_systhread.h" - typedef struct SDL_HIDAPI_RumbleRequest { SDL_HIDAPI_Device *device; - Uint8 data[2*USB_PACKET_LENGTH]; /* need enough space for the biggest report: dualshock4 is 78 bytes */ + Uint8 data[2 * USB_PACKET_LENGTH]; /* need enough space for the biggest report: dualshock4 is 78 bytes */ int size; + SDL_HIDAPI_RumbleSentCallback callback; + void *userdata; struct SDL_HIDAPI_RumbleRequest *prev; } SDL_HIDAPI_RumbleRequest; @@ -45,15 +46,18 @@ typedef struct SDL_HIDAPI_RumbleContext SDL_atomic_t initialized; SDL_atomic_t running; SDL_Thread *thread; - SDL_mutex *lock; SDL_sem *request_sem; SDL_HIDAPI_RumbleRequest *requests_head; SDL_HIDAPI_RumbleRequest *requests_tail; } SDL_HIDAPI_RumbleContext; -static SDL_HIDAPI_RumbleContext rumble_context; +#ifndef SDL_THREAD_SAFETY_ANALYSIS +static +#endif +SDL_mutex *SDL_HIDAPI_rumble_lock; +static SDL_HIDAPI_RumbleContext rumble_context SDL_GUARDED_BY(SDL_HIDAPI_rumble_lock); -static int SDL_HIDAPI_RumbleThread(void *data) +static int SDLCALL SDL_HIDAPI_RumbleThread(void *data) { SDL_HIDAPI_RumbleContext *ctx = (SDL_HIDAPI_RumbleContext *)data; @@ -64,7 +68,7 @@ static int SDL_HIDAPI_RumbleThread(void *data) SDL_SemWait(ctx->request_sem); - SDL_LockMutex(ctx->lock); + SDL_LockMutex(SDL_HIDAPI_rumble_lock); request = ctx->requests_tail; if (request) { if (request == ctx->requests_head) { @@ -72,24 +76,34 @@ static int SDL_HIDAPI_RumbleThread(void *data) } ctx->requests_tail = request->prev; } - SDL_UnlockMutex(ctx->lock); + SDL_UnlockMutex(SDL_HIDAPI_rumble_lock); if (request) { SDL_LockMutex(request->device->dev_lock); if (request->device->dev) { - hid_write( request->device->dev, request->data, request->size ); +#ifdef DEBUG_RUMBLE + HIDAPI_DumpPacket("Rumble packet: size = %d", request->data, request->size); +#endif + SDL_hid_write(request->device->dev, request->data, request->size); } SDL_UnlockMutex(request->device->dev_lock); + if (request->callback) { + request->callback(request->userdata); + } (void)SDL_AtomicDecRef(&request->device->rumble_pending); SDL_free(request); + + /* Make sure we're not starving report reads when there's lots of rumble */ + SDL_Delay(10); } } return 0; } -static void -SDL_HIDAPI_StopRumbleThread(SDL_HIDAPI_RumbleContext *ctx) +static void SDL_HIDAPI_StopRumbleThread(SDL_HIDAPI_RumbleContext *ctx) { + SDL_HIDAPI_RumbleRequest *request; + SDL_AtomicSet(&ctx->running, SDL_FALSE); if (ctx->thread) { @@ -100,28 +114,39 @@ SDL_HIDAPI_StopRumbleThread(SDL_HIDAPI_RumbleContext *ctx) ctx->thread = NULL; } - /* This should always be called with an empty queue */ - SDL_assert(!ctx->requests_head); - SDL_assert(!ctx->requests_tail); + SDL_LockMutex(SDL_HIDAPI_rumble_lock); + while (ctx->requests_tail) { + request = ctx->requests_tail; + if (request == ctx->requests_head) { + ctx->requests_head = NULL; + } + ctx->requests_tail = request->prev; + + if (request->callback) { + request->callback(request->userdata); + } + (void)SDL_AtomicDecRef(&request->device->rumble_pending); + SDL_free(request); + } + SDL_UnlockMutex(SDL_HIDAPI_rumble_lock); if (ctx->request_sem) { SDL_DestroySemaphore(ctx->request_sem); ctx->request_sem = NULL; } - if (ctx->lock) { - SDL_DestroyMutex(ctx->lock); - ctx->lock = NULL; + if (SDL_HIDAPI_rumble_lock) { + SDL_DestroyMutex(SDL_HIDAPI_rumble_lock); + SDL_HIDAPI_rumble_lock = NULL; } SDL_AtomicSet(&ctx->initialized, SDL_FALSE); } -static int -SDL_HIDAPI_StartRumbleThread(SDL_HIDAPI_RumbleContext *ctx) +static int SDL_HIDAPI_StartRumbleThread(SDL_HIDAPI_RumbleContext *ctx) { - ctx->lock = SDL_CreateMutex(); - if (!ctx->lock) { + SDL_HIDAPI_rumble_lock = SDL_CreateMutex(); + if (!SDL_HIDAPI_rumble_lock) { SDL_HIDAPI_StopRumbleThread(ctx); return -1; } @@ -151,26 +176,36 @@ int SDL_HIDAPI_LockRumble(void) } } - return SDL_LockMutex(ctx->lock); + SDL_LockMutex(SDL_HIDAPI_rumble_lock); + return 0; } SDL_bool SDL_HIDAPI_GetPendingRumbleLocked(SDL_HIDAPI_Device *device, Uint8 **data, int **size, int *maximum_size) { SDL_HIDAPI_RumbleContext *ctx = &rumble_context; - SDL_HIDAPI_RumbleRequest *request; + SDL_HIDAPI_RumbleRequest *request, *found; + found = NULL; for (request = ctx->requests_tail; request; request = request->prev) { if (request->device == device) { - *data = request->data; - *size = &request->size; - *maximum_size = sizeof(request->data); - return SDL_TRUE; + found = request; } } + if (found) { + *data = found->data; + *size = &found->size; + *maximum_size = sizeof(found->data); + return SDL_TRUE; + } return SDL_FALSE; } int SDL_HIDAPI_SendRumbleAndUnlock(SDL_HIDAPI_Device *device, const Uint8 *data, int size) +{ + return SDL_HIDAPI_SendRumbleWithCallbackAndUnlock(device, data, size, NULL, NULL); +} + +int SDL_HIDAPI_SendRumbleWithCallbackAndUnlock(SDL_HIDAPI_Device *device, const Uint8 *data, int size, SDL_HIDAPI_RumbleSentCallback callback, void *userdata) { SDL_HIDAPI_RumbleContext *ctx = &rumble_context; SDL_HIDAPI_RumbleRequest *request; @@ -188,9 +223,11 @@ int SDL_HIDAPI_SendRumbleAndUnlock(SDL_HIDAPI_Device *device, const Uint8 *data, request->device = device; SDL_memcpy(request->data, data, size); request->size = size; + request->callback = callback; + request->userdata = userdata; SDL_AtomicIncRef(&device->rumble_pending); - + if (ctx->requests_head) { ctx->requests_head->prev = request; } else { @@ -208,9 +245,7 @@ int SDL_HIDAPI_SendRumbleAndUnlock(SDL_HIDAPI_Device *device, const Uint8 *data, void SDL_HIDAPI_UnlockRumble(void) { - SDL_HIDAPI_RumbleContext *ctx = &rumble_context; - - SDL_UnlockMutex(ctx->lock); + SDL_UnlockMutex(SDL_HIDAPI_rumble_lock); } int SDL_HIDAPI_SendRumble(SDL_HIDAPI_Device *device, const Uint8 *data, int size) @@ -219,19 +254,18 @@ int SDL_HIDAPI_SendRumble(SDL_HIDAPI_Device *device, const Uint8 *data, int size int *pending_size; int maximum_size; - if (SDL_HIDAPI_LockRumble() < 0) { + if (size <= 0) { + return SDL_SetError("Tried to send rumble with invalid size"); + } + + if (SDL_HIDAPI_LockRumble() != 0) { return -1; } /* check if there is a pending request for the device and update it */ - if (SDL_HIDAPI_GetPendingRumbleLocked(device, &pending_data, &pending_size, &maximum_size)) { - if (size > maximum_size) { - SDL_HIDAPI_UnlockRumble(); - return SDL_SetError("Couldn't send rumble, size %d is greater than %d", size, maximum_size); - } - + if (SDL_HIDAPI_GetPendingRumbleLocked(device, &pending_data, &pending_size, &maximum_size) && + size == *pending_size && data[0] == pending_data[0]) { SDL_memcpy(pending_data, data, size); - *pending_size = size; SDL_HIDAPI_UnlockRumble(); return size; } diff --git a/SDL2-2.0.12/src/joystick/hidapi/SDL_hidapi_rumble.h b/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_rumble.h similarity index 70% rename from SDL2-2.0.12/src/joystick/hidapi/SDL_hidapi_rumble.h rename to SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_rumble.h index 9b14da0..918e08c 100644 --- a/SDL2-2.0.12/src/joystick/hidapi/SDL_hidapi_rumble.h +++ b/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_rumble.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -25,10 +25,15 @@ /* Handle rumble on a separate thread so it doesn't block the application */ /* Advanced API */ -int SDL_HIDAPI_LockRumble(void); +#ifdef SDL_THREAD_SAFETY_ANALYSIS +extern SDL_mutex *SDL_HIDAPI_rumble_lock; +#endif +int SDL_HIDAPI_LockRumble(void) SDL_TRY_ACQUIRE(0, SDL_HIDAPI_rumble_lock); SDL_bool SDL_HIDAPI_GetPendingRumbleLocked(SDL_HIDAPI_Device *device, Uint8 **data, int **size, int *maximum_size); -int SDL_HIDAPI_SendRumbleAndUnlock(SDL_HIDAPI_Device *device, const Uint8 *data, int size); -void SDL_HIDAPI_UnlockRumble(void); +int SDL_HIDAPI_SendRumbleAndUnlock(SDL_HIDAPI_Device *device, const Uint8 *data, int size) SDL_RELEASE(SDL_HIDAPI_rumble_lock); +typedef void (*SDL_HIDAPI_RumbleSentCallback)(void *userdata); +int SDL_HIDAPI_SendRumbleWithCallbackAndUnlock(SDL_HIDAPI_Device *device, const Uint8 *data, int size, SDL_HIDAPI_RumbleSentCallback callback, void *userdata) SDL_RELEASE(SDL_HIDAPI_rumble_lock); +void SDL_HIDAPI_UnlockRumble(void) SDL_RELEASE(SDL_HIDAPI_rumble_lock); /* Simple API, will replace any pending rumble with the new data */ int SDL_HIDAPI_SendRumble(SDL_HIDAPI_Device *device, const Uint8 *data, int size); diff --git a/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_shield.c b/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_shield.c new file mode 100644 index 0000000..63540e6 --- /dev/null +++ b/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_shield.c @@ -0,0 +1,603 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_JOYSTICK_HIDAPI + +#include "SDL_events.h" +#include "SDL_timer.h" +#include "SDL_joystick.h" +#include "SDL_gamecontroller.h" +#include "../SDL_sysjoystick.h" +#include "SDL_hidapijoystick_c.h" +#include "SDL_hidapi_rumble.h" + +#ifdef SDL_JOYSTICK_HIDAPI_SHIELD + +/* Define this if you want to log all packets from the controller */ +/*#define DEBUG_SHIELD_PROTOCOL*/ + +#define CMD_BATTERY_STATE 0x07 +#define CMD_RUMBLE 0x39 +#define CMD_CHARGE_STATE 0x3A + +/* Milliseconds between polls of battery state */ +#define BATTERY_POLL_INTERVAL_MS 60000 + +/* Milliseconds between retransmission of rumble to keep motors running */ +#define RUMBLE_REFRESH_INTERVAL_MS 500 + +/* Reports that are too small are dropped over Bluetooth */ +#define HID_REPORT_SIZE 33 + +enum +{ + SDL_CONTROLLER_BUTTON_SHIELD_V103_TOUCHPAD = SDL_CONTROLLER_BUTTON_MISC1 + 1, + SDL_CONTROLLER_BUTTON_SHIELD_V103_MINUS, + SDL_CONTROLLER_BUTTON_SHIELD_V103_PLUS, + SDL_CONTROLLER_NUM_SHIELD_V103_BUTTONS, + + SDL_CONTROLLER_NUM_SHIELD_V104_BUTTONS = SDL_CONTROLLER_BUTTON_MISC1 + 1, +}; + +typedef enum +{ + k_ShieldReportIdControllerState = 0x01, + k_ShieldReportIdControllerTouch = 0x02, + k_ShieldReportIdCommandResponse = 0x03, + k_ShieldReportIdCommandRequest = 0x04, +} EShieldReportId; + +/* This same report structure is used for both requests and responses */ +typedef struct +{ + Uint8 report_id; + Uint8 cmd; + Uint8 seq_num; + Uint8 payload[HID_REPORT_SIZE - 3]; +} ShieldCommandReport_t; +SDL_COMPILE_TIME_ASSERT(ShieldCommandReport_t, sizeof(ShieldCommandReport_t) == HID_REPORT_SIZE); + +typedef struct +{ + Uint8 seq_num; + + SDL_JoystickPowerLevel battery_level; + SDL_bool charging; + Uint32 last_battery_query_time; + + SDL_bool rumble_report_pending; + SDL_bool rumble_update_pending; + Uint8 left_motor_amplitude; + Uint8 right_motor_amplitude; + Uint32 last_rumble_time; + + Uint8 last_state[USB_PACKET_LENGTH]; +} SDL_DriverShield_Context; + +static void HIDAPI_DriverShield_RegisterHints(SDL_HintCallback callback, void *userdata) +{ + SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_SHIELD, callback, userdata); +} + +static void HIDAPI_DriverShield_UnregisterHints(SDL_HintCallback callback, void *userdata) +{ + SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_SHIELD, callback, userdata); +} + +static SDL_bool HIDAPI_DriverShield_IsEnabled(void) +{ + return SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_SHIELD, SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI, SDL_HIDAPI_DEFAULT)); +} + +static SDL_bool HIDAPI_DriverShield_IsSupportedDevice(SDL_HIDAPI_Device *device, const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol) +{ + return (type == SDL_CONTROLLER_TYPE_NVIDIA_SHIELD) ? SDL_TRUE : SDL_FALSE; +} + +static SDL_bool HIDAPI_DriverShield_InitDevice(SDL_HIDAPI_Device *device) +{ + SDL_DriverShield_Context *ctx; + + ctx = (SDL_DriverShield_Context *)SDL_calloc(1, sizeof(*ctx)); + if (!ctx) { + SDL_OutOfMemory(); + return SDL_FALSE; + } + device->context = ctx; + + device->type = SDL_CONTROLLER_TYPE_NVIDIA_SHIELD; + HIDAPI_SetDeviceName(device, "NVIDIA SHIELD Controller"); + + return HIDAPI_JoystickConnected(device, NULL); +} + +static int HIDAPI_DriverShield_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id) +{ + return -1; +} + +static void HIDAPI_DriverShield_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index) +{ +} + +static int HIDAPI_DriverShield_SendCommand(SDL_HIDAPI_Device *device, Uint8 cmd, const void *data, int size) +{ + SDL_DriverShield_Context *ctx = (SDL_DriverShield_Context *)device->context; + ShieldCommandReport_t cmd_pkt; + + if (size > sizeof(cmd_pkt.payload)) { + return SDL_SetError("Command data exceeds HID report size"); + } + + if (SDL_HIDAPI_LockRumble() != 0) { + return -1; + } + + cmd_pkt.report_id = k_ShieldReportIdCommandRequest; + cmd_pkt.cmd = cmd; + cmd_pkt.seq_num = ctx->seq_num++; + if (data) { + SDL_memcpy(cmd_pkt.payload, data, size); + } + + /* Zero unused data in the payload */ + if (size != sizeof(cmd_pkt.payload)) { + SDL_memset(&cmd_pkt.payload[size], 0, sizeof(cmd_pkt.payload) - size); + } + + if (SDL_HIDAPI_SendRumbleAndUnlock(device, (Uint8 *)&cmd_pkt, sizeof(cmd_pkt)) != sizeof(cmd_pkt)) { + return SDL_SetError("Couldn't send command packet"); + } + + return 0; +} + +static SDL_bool HIDAPI_DriverShield_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_DriverShield_Context *ctx = (SDL_DriverShield_Context *)device->context; + + SDL_AssertJoysticksLocked(); + + ctx->rumble_report_pending = SDL_FALSE; + ctx->rumble_update_pending = SDL_FALSE; + ctx->left_motor_amplitude = 0; + ctx->right_motor_amplitude = 0; + ctx->last_rumble_time = 0; + SDL_zeroa(ctx->last_state); + + /* Initialize the joystick capabilities */ + if (device->product_id == USB_PRODUCT_NVIDIA_SHIELD_CONTROLLER_V103) { + joystick->nbuttons = SDL_CONTROLLER_NUM_SHIELD_V103_BUTTONS; + joystick->naxes = SDL_CONTROLLER_AXIS_MAX; + joystick->epowerlevel = SDL_JOYSTICK_POWER_WIRED; + + SDL_PrivateJoystickAddTouchpad(joystick, 1); + } else { + joystick->nbuttons = SDL_CONTROLLER_NUM_SHIELD_V104_BUTTONS; + joystick->naxes = SDL_CONTROLLER_AXIS_MAX; + joystick->epowerlevel = SDL_JOYSTICK_POWER_UNKNOWN; + } + + /* Request battery and charging info */ + ctx->last_battery_query_time = SDL_GetTicks(); + HIDAPI_DriverShield_SendCommand(device, CMD_CHARGE_STATE, NULL, 0); + HIDAPI_DriverShield_SendCommand(device, CMD_BATTERY_STATE, NULL, 0); + + return SDL_TRUE; +} + +static int HIDAPI_DriverShield_SendNextRumble(SDL_HIDAPI_Device *device) +{ + SDL_DriverShield_Context *ctx = device->context; + Uint8 rumble_data[3]; + + if (!ctx->rumble_update_pending) { + return 0; + } + + rumble_data[0] = 0x01; /* enable */ + rumble_data[1] = ctx->left_motor_amplitude; + rumble_data[2] = ctx->right_motor_amplitude; + + ctx->rumble_update_pending = SDL_FALSE; + ctx->last_rumble_time = SDL_GetTicks(); + + return HIDAPI_DriverShield_SendCommand(device, CMD_RUMBLE, rumble_data, sizeof(rumble_data)); +} + +static int HIDAPI_DriverShield_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ + if (device->product_id == USB_PRODUCT_NVIDIA_SHIELD_CONTROLLER_V103) { + Uint8 rumble_packet[] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + rumble_packet[2] = (low_frequency_rumble >> 8); + rumble_packet[4] = (high_frequency_rumble >> 8); + + if (SDL_HIDAPI_SendRumble(device, rumble_packet, sizeof(rumble_packet)) != sizeof(rumble_packet)) { + return SDL_SetError("Couldn't send rumble packet"); + } + return 0; + + } else { + SDL_DriverShield_Context *ctx = device->context; + + /* The rumble motors are quite intense, so tone down the intensity like the official driver does */ + ctx->left_motor_amplitude = low_frequency_rumble >> 11; + ctx->right_motor_amplitude = high_frequency_rumble >> 11; + ctx->rumble_update_pending = SDL_TRUE; + + if (ctx->rumble_report_pending) { + /* We will service this after the hardware acknowledges the previous request */ + return 0; + } + + return HIDAPI_DriverShield_SendNextRumble(device); + } +} + +static int HIDAPI_DriverShield_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) +{ + return SDL_Unsupported(); +} + +static Uint32 HIDAPI_DriverShield_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + return SDL_JOYCAP_RUMBLE; +} + +static int HIDAPI_DriverShield_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + return SDL_Unsupported(); +} + +static int HIDAPI_DriverShield_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size) +{ + const Uint8 *data_bytes = data; + + if (size > 1) { + /* Single command byte followed by a variable length payload */ + return HIDAPI_DriverShield_SendCommand(device, data_bytes[0], &data_bytes[1], size - 1); + } else if (size == 1) { + /* Single command byte with no payload */ + return HIDAPI_DriverShield_SendCommand(device, data_bytes[0], NULL, 0); + } else { + return SDL_SetError("Effect data must at least contain a command byte"); + } +} + +static int HIDAPI_DriverShield_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled) +{ + return SDL_Unsupported(); +} + +static void HIDAPI_DriverShield_HandleStatePacketV103(SDL_Joystick *joystick, SDL_DriverShield_Context *ctx, Uint8 *data, int size) +{ + if (ctx->last_state[3] != data[3]) { + SDL_bool dpad_up = SDL_FALSE; + SDL_bool dpad_down = SDL_FALSE; + SDL_bool dpad_left = SDL_FALSE; + SDL_bool dpad_right = SDL_FALSE; + + switch (data[3]) { + case 0: + dpad_up = SDL_TRUE; + break; + case 1: + dpad_up = SDL_TRUE; + dpad_right = SDL_TRUE; + break; + case 2: + dpad_right = SDL_TRUE; + break; + case 3: + dpad_right = SDL_TRUE; + dpad_down = SDL_TRUE; + break; + case 4: + dpad_down = SDL_TRUE; + break; + case 5: + dpad_left = SDL_TRUE; + dpad_down = SDL_TRUE; + break; + case 6: + dpad_left = SDL_TRUE; + break; + case 7: + dpad_up = SDL_TRUE; + dpad_left = SDL_TRUE; + break; + default: + break; + } + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, dpad_down); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, dpad_up); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, dpad_right); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, dpad_left); + } + + if (ctx->last_state[1] != data[1]) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_A, (data[1] & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_B, (data[1] & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_X, (data[1] & 0x04) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_Y, (data[1] & 0x08) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data[1] & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data[1] & 0x20) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (data[1] & 0x40) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data[1] & 0x80) ? SDL_PRESSED : SDL_RELEASED); + } + + if (ctx->last_state[2] != data[2]) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, (data[2] & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_SHIELD_V103_PLUS, (data[2] & 0x08) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_SHIELD_V103_MINUS, (data[2] & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data[2] & 0x20) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data[2] & 0x40) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MISC1, (data[2] & 0x80) ? SDL_PRESSED : SDL_RELEASED); + } + + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, SDL_SwapLE16(*(Sint16 *)&data[4]) - 0x8000); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, SDL_SwapLE16(*(Sint16 *)&data[6]) - 0x8000); + + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, SDL_SwapLE16(*(Sint16 *)&data[8]) - 0x8000); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, SDL_SwapLE16(*(Sint16 *)&data[10]) - 0x8000); + + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, SDL_SwapLE16(*(Sint16 *)&data[12]) - 0x8000); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, SDL_SwapLE16(*(Sint16 *)&data[14]) - 0x8000); + + SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state))); +} + +#undef clamp +#define clamp(val, min, max) (((val) > (max)) ? (max) : (((val) < (min)) ? (min) : (val))) + +static void HIDAPI_DriverShield_HandleTouchPacketV103(SDL_Joystick *joystick, SDL_DriverShield_Context *ctx, const Uint8 *data, int size) +{ + Uint8 touchpad_state; + float touchpad_x, touchpad_y; + + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_SHIELD_V103_TOUCHPAD, (data[1] & 0x01) ? SDL_PRESSED : SDL_RELEASED); + + /* It's a triangular pad, but just use the center as the usable touch area */ + touchpad_state = !(data[1] & 0x80) ? SDL_PRESSED : SDL_RELEASED; + touchpad_x = clamp((float)(data[2] - 0x70) / 0x50, 0.0f, 1.0f); + touchpad_y = clamp((float)(data[4] - 0x40) / 0x15, 0.0f, 1.0f); + SDL_PrivateJoystickTouchpad(joystick, 0, 0, touchpad_state, touchpad_x, touchpad_y, touchpad_state ? 1.0f : 0.0f); +} + +static void HIDAPI_DriverShield_HandleStatePacketV104(SDL_Joystick *joystick, SDL_DriverShield_Context *ctx, Uint8 *data, int size) +{ + if (size < 23) { + return; + } + + if (ctx->last_state[2] != data[2]) { + SDL_bool dpad_up = SDL_FALSE; + SDL_bool dpad_down = SDL_FALSE; + SDL_bool dpad_left = SDL_FALSE; + SDL_bool dpad_right = SDL_FALSE; + + switch (data[2]) { + case 0: + dpad_up = SDL_TRUE; + break; + case 1: + dpad_up = SDL_TRUE; + dpad_right = SDL_TRUE; + break; + case 2: + dpad_right = SDL_TRUE; + break; + case 3: + dpad_right = SDL_TRUE; + dpad_down = SDL_TRUE; + break; + case 4: + dpad_down = SDL_TRUE; + break; + case 5: + dpad_left = SDL_TRUE; + dpad_down = SDL_TRUE; + break; + case 6: + dpad_left = SDL_TRUE; + break; + case 7: + dpad_up = SDL_TRUE; + dpad_left = SDL_TRUE; + break; + default: + break; + } + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, dpad_down); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, dpad_up); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, dpad_right); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, dpad_left); + } + + if (ctx->last_state[3] != data[3]) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_A, (data[3] & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_B, (data[3] & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_X, (data[3] & 0x04) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_Y, (data[3] & 0x08) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data[3] & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data[3] & 0x20) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (data[3] & 0x40) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data[3] & 0x80) ? SDL_PRESSED : SDL_RELEASED); + } + + if (ctx->last_state[4] != data[4]) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, (data[4] & 0x01) ? SDL_PRESSED : SDL_RELEASED); + } + + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, SDL_SwapLE16(*(Sint16 *)&data[9]) - 0x8000); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, SDL_SwapLE16(*(Sint16 *)&data[11]) - 0x8000); + + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, SDL_SwapLE16(*(Sint16 *)&data[13]) - 0x8000); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, SDL_SwapLE16(*(Sint16 *)&data[15]) - 0x8000); + + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, SDL_SwapLE16(*(Sint16 *)&data[19]) - 0x8000); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, SDL_SwapLE16(*(Sint16 *)&data[21]) - 0x8000); + + if (ctx->last_state[17] != data[17]) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MISC1, (data[17] & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data[17] & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data[17] & 0x04) ? SDL_PRESSED : SDL_RELEASED); + } + + SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state))); +} + +static SDL_bool HIDAPI_DriverShield_UpdateDevice(SDL_HIDAPI_Device *device) +{ + SDL_DriverShield_Context *ctx = (SDL_DriverShield_Context *)device->context; + SDL_Joystick *joystick = NULL; + Uint8 data[USB_PACKET_LENGTH]; + int size = 0; + ShieldCommandReport_t *cmd_resp_report; + + if (device->num_joysticks > 0) { + joystick = SDL_JoystickFromInstanceID(device->joysticks[0]); + } else { + return SDL_FALSE; + } + + while ((size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) { +#ifdef DEBUG_SHIELD_PROTOCOL + HIDAPI_DumpPacket("NVIDIA SHIELD packet: size = %d", data, size); +#endif + + /* Byte 0 is HID report ID */ + switch (data[0]) { + case k_ShieldReportIdControllerState: + if (!joystick) { + break; + } + if (size == 16) { + HIDAPI_DriverShield_HandleStatePacketV103(joystick, ctx, data, size); + } else { + HIDAPI_DriverShield_HandleStatePacketV104(joystick, ctx, data, size); + } + break; + case k_ShieldReportIdControllerTouch: + if (!joystick) { + break; + } + HIDAPI_DriverShield_HandleTouchPacketV103(joystick, ctx, data, size); + break; + case k_ShieldReportIdCommandResponse: + cmd_resp_report = (ShieldCommandReport_t *)data; + switch (cmd_resp_report->cmd) { + case CMD_RUMBLE: + ctx->rumble_report_pending = SDL_FALSE; + HIDAPI_DriverShield_SendNextRumble(device); + break; + case CMD_CHARGE_STATE: + ctx->charging = cmd_resp_report->payload[0] != 0; + if (joystick) { + SDL_PrivateJoystickBatteryLevel(joystick, ctx->charging ? SDL_JOYSTICK_POWER_WIRED : ctx->battery_level); + } + break; + case CMD_BATTERY_STATE: + switch (cmd_resp_report->payload[2]) { + case 0: + ctx->battery_level = SDL_JOYSTICK_POWER_EMPTY; + break; + case 1: + ctx->battery_level = SDL_JOYSTICK_POWER_LOW; + break; + case 2: /* 40% */ + case 3: /* 60% */ + case 4: /* 80% */ + ctx->battery_level = SDL_JOYSTICK_POWER_MEDIUM; + break; + case 5: + ctx->battery_level = SDL_JOYSTICK_POWER_FULL; + break; + default: + ctx->battery_level = SDL_JOYSTICK_POWER_UNKNOWN; + break; + } + if (joystick) { + SDL_PrivateJoystickBatteryLevel(joystick, ctx->charging ? SDL_JOYSTICK_POWER_WIRED : ctx->battery_level); + } + break; + } + break; + } + } + + /* Ask for battery state again if we're due for an update */ + if (joystick && SDL_TICKS_PASSED(SDL_GetTicks(), ctx->last_battery_query_time + BATTERY_POLL_INTERVAL_MS)) { + ctx->last_battery_query_time = SDL_GetTicks(); + HIDAPI_DriverShield_SendCommand(device, CMD_BATTERY_STATE, NULL, 0); + } + + /* Retransmit rumble packets if they've lasted longer than the hardware supports */ + if ((ctx->left_motor_amplitude != 0 || ctx->right_motor_amplitude != 0) && + SDL_TICKS_PASSED(SDL_GetTicks(), ctx->last_rumble_time + RUMBLE_REFRESH_INTERVAL_MS)) { + ctx->rumble_update_pending = SDL_TRUE; + HIDAPI_DriverShield_SendNextRumble(device); + } + + if (size < 0) { + /* Read error, device is disconnected */ + HIDAPI_JoystickDisconnected(device, device->joysticks[0]); + } + return size >= 0; +} + +static void HIDAPI_DriverShield_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ +} + +static void HIDAPI_DriverShield_FreeDevice(SDL_HIDAPI_Device *device) +{ +} + +SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverShield = { + SDL_HINT_JOYSTICK_HIDAPI_SHIELD, + SDL_TRUE, + HIDAPI_DriverShield_RegisterHints, + HIDAPI_DriverShield_UnregisterHints, + HIDAPI_DriverShield_IsEnabled, + HIDAPI_DriverShield_IsSupportedDevice, + HIDAPI_DriverShield_InitDevice, + HIDAPI_DriverShield_GetDevicePlayerIndex, + HIDAPI_DriverShield_SetDevicePlayerIndex, + HIDAPI_DriverShield_UpdateDevice, + HIDAPI_DriverShield_OpenJoystick, + HIDAPI_DriverShield_RumbleJoystick, + HIDAPI_DriverShield_RumbleJoystickTriggers, + HIDAPI_DriverShield_GetJoystickCapabilities, + HIDAPI_DriverShield_SetJoystickLED, + HIDAPI_DriverShield_SendJoystickEffect, + HIDAPI_DriverShield_SetJoystickSensorsEnabled, + HIDAPI_DriverShield_CloseJoystick, + HIDAPI_DriverShield_FreeDevice, +}; + +#endif /* SDL_JOYSTICK_HIDAPI_SHIELD */ + +#endif /* SDL_JOYSTICK_HIDAPI */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_stadia.c b/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_stadia.c new file mode 100644 index 0000000..0fc6d14 --- /dev/null +++ b/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_stadia.c @@ -0,0 +1,339 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_JOYSTICK_HIDAPI + +#include "SDL_events.h" +#include "SDL_joystick.h" +#include "SDL_gamecontroller.h" +#include "../SDL_sysjoystick.h" +#include "SDL_hidapijoystick_c.h" +#include "SDL_hidapi_rumble.h" + +#ifdef SDL_JOYSTICK_HIDAPI_STADIA + +/* Define this if you want to log all packets from the controller */ +/*#define DEBUG_STADIA_PROTOCOL*/ + +enum +{ + SDL_CONTROLLER_BUTTON_STADIA_SHARE = 15, + SDL_CONTROLLER_BUTTON_STADIA_GOOGLE_ASSISTANT, + SDL_CONTROLLER_NUM_STADIA_BUTTONS, +}; + +typedef struct +{ + SDL_bool rumble_supported; + Uint8 last_state[USB_PACKET_LENGTH]; +} SDL_DriverStadia_Context; + +static void HIDAPI_DriverStadia_RegisterHints(SDL_HintCallback callback, void *userdata) +{ + SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_STADIA, callback, userdata); +} + +static void HIDAPI_DriverStadia_UnregisterHints(SDL_HintCallback callback, void *userdata) +{ + SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_STADIA, callback, userdata); +} + +static SDL_bool HIDAPI_DriverStadia_IsEnabled(void) +{ + return SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_STADIA, SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI, SDL_HIDAPI_DEFAULT)); +} + +static SDL_bool HIDAPI_DriverStadia_IsSupportedDevice(SDL_HIDAPI_Device *device, const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol) +{ + return (type == SDL_CONTROLLER_TYPE_GOOGLE_STADIA) ? SDL_TRUE : SDL_FALSE; +} + +static SDL_bool HIDAPI_DriverStadia_InitDevice(SDL_HIDAPI_Device *device) +{ + SDL_DriverStadia_Context *ctx; + + ctx = (SDL_DriverStadia_Context *)SDL_calloc(1, sizeof(*ctx)); + if (!ctx) { + SDL_OutOfMemory(); + return SDL_FALSE; + } + device->context = ctx; + + /* Check whether rumble is supported */ + { + Uint8 rumble_packet[] = { 0x05, 0x00, 0x00, 0x00, 0x00 }; + + if (SDL_hid_write(device->dev, rumble_packet, sizeof(rumble_packet)) >= 0) { + ctx->rumble_supported = SDL_TRUE; + } + } + + device->type = SDL_CONTROLLER_TYPE_GOOGLE_STADIA; + HIDAPI_SetDeviceName(device, "Google Stadia Controller"); + + return HIDAPI_JoystickConnected(device, NULL); +} + +static int HIDAPI_DriverStadia_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id) +{ + return -1; +} + +static void HIDAPI_DriverStadia_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index) +{ +} + +static SDL_bool HIDAPI_DriverStadia_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_DriverStadia_Context *ctx = (SDL_DriverStadia_Context *)device->context; + + SDL_AssertJoysticksLocked(); + + SDL_zeroa(ctx->last_state); + + /* Initialize the joystick capabilities */ + joystick->nbuttons = SDL_CONTROLLER_NUM_STADIA_BUTTONS; + joystick->naxes = SDL_CONTROLLER_AXIS_MAX; + joystick->epowerlevel = SDL_JOYSTICK_POWER_WIRED; + + return SDL_TRUE; +} + +static int HIDAPI_DriverStadia_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ + SDL_DriverStadia_Context *ctx = (SDL_DriverStadia_Context *)device->context; + + if (ctx->rumble_supported) { + Uint8 rumble_packet[] = { 0x05, 0x00, 0x00, 0x00, 0x00 }; + + + rumble_packet[1] = (low_frequency_rumble & 0xFF); + rumble_packet[2] = (low_frequency_rumble >> 8); + rumble_packet[3] = (high_frequency_rumble & 0xFF); + rumble_packet[4] = (high_frequency_rumble >> 8); + + if (SDL_HIDAPI_SendRumble(device, rumble_packet, sizeof(rumble_packet)) != sizeof(rumble_packet)) { + return SDL_SetError("Couldn't send rumble packet"); + } + return 0; + } else { + return SDL_Unsupported(); + } +} + +static int HIDAPI_DriverStadia_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) +{ + return SDL_Unsupported(); +} + +static Uint32 HIDAPI_DriverStadia_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_DriverStadia_Context *ctx = (SDL_DriverStadia_Context *)device->context; + Uint32 caps = 0; + + if (ctx->rumble_supported) { + caps |= SDL_JOYCAP_RUMBLE; + } + return caps; +} + +static int HIDAPI_DriverStadia_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + return SDL_Unsupported(); +} + +static int HIDAPI_DriverStadia_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + +static int HIDAPI_DriverStadia_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled) +{ + return SDL_Unsupported(); +} + +static void HIDAPI_DriverStadia_HandleStatePacket(SDL_Joystick *joystick, SDL_DriverStadia_Context *ctx, Uint8 *data, int size) +{ + Sint16 axis; + + // The format is the same but the original FW will send 10 bytes and January '21 FW update will send 11 + if (size < 10 || data[0] != 0x03) { + /* We don't know how to handle this report */ + return; + } + + if (ctx->last_state[1] != data[1]) { + SDL_bool dpad_up = SDL_FALSE; + SDL_bool dpad_down = SDL_FALSE; + SDL_bool dpad_left = SDL_FALSE; + SDL_bool dpad_right = SDL_FALSE; + + switch (data[1]) { + case 0: + dpad_up = SDL_TRUE; + break; + case 1: + dpad_up = SDL_TRUE; + dpad_right = SDL_TRUE; + break; + case 2: + dpad_right = SDL_TRUE; + break; + case 3: + dpad_right = SDL_TRUE; + dpad_down = SDL_TRUE; + break; + case 4: + dpad_down = SDL_TRUE; + break; + case 5: + dpad_left = SDL_TRUE; + dpad_down = SDL_TRUE; + break; + case 6: + dpad_left = SDL_TRUE; + break; + case 7: + dpad_up = SDL_TRUE; + dpad_left = SDL_TRUE; + break; + default: + break; + } + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, dpad_down); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, dpad_up); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, dpad_right); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, dpad_left); + } + + if (ctx->last_state[2] != data[2]) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data[2] & 0x40) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data[2] & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, (data[2] & 0x20) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data[2] & 0x80) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_STADIA_SHARE, (data[2] & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_STADIA_GOOGLE_ASSISTANT, (data[2] & 0x02) ? SDL_PRESSED : SDL_RELEASED); + } + + if (ctx->last_state[3] != data[3]) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_A, (data[3] & 0x40) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_B, (data[3] & 0x20) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_X, (data[3] & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_Y, (data[3] & 0x08) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data[3] & 0x04) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data[3] & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (data[3] & 0x01) ? SDL_PRESSED : SDL_RELEASED); + } + +#define READ_STICK_AXIS(offset) \ + (data[offset] == 0x80 ? 0 : (Sint16)HIDAPI_RemapVal((float)((int)data[offset] - 0x80), 0x01 - 0x80, 0xff - 0x80, SDL_MIN_SINT16, SDL_MAX_SINT16)) + { + axis = READ_STICK_AXIS(4); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis); + axis = READ_STICK_AXIS(5); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, axis); + axis = READ_STICK_AXIS(6); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, axis); + axis = READ_STICK_AXIS(7); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis); + } +#undef READ_STICK_AXIS + +#define READ_TRIGGER_AXIS(offset) \ + (Sint16)(((int)data[offset] * 257) - 32768) + { + axis = READ_TRIGGER_AXIS(8); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, axis); + axis = READ_TRIGGER_AXIS(9); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, axis); + } +#undef READ_TRIGGER_AXIS + + SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state))); +} + +static SDL_bool HIDAPI_DriverStadia_UpdateDevice(SDL_HIDAPI_Device *device) +{ + SDL_DriverStadia_Context *ctx = (SDL_DriverStadia_Context *)device->context; + SDL_Joystick *joystick = NULL; + Uint8 data[USB_PACKET_LENGTH]; + int size = 0; + + if (device->num_joysticks > 0) { + joystick = SDL_JoystickFromInstanceID(device->joysticks[0]); + } else { + return SDL_FALSE; + } + + while ((size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) { +#ifdef DEBUG_STADIA_PROTOCOL + HIDAPI_DumpPacket("Google Stadia packet: size = %d", data, size); +#endif + if (!joystick) { + continue; + } + + HIDAPI_DriverStadia_HandleStatePacket(joystick, ctx, data, size); + } + + if (size < 0) { + /* Read error, device is disconnected */ + HIDAPI_JoystickDisconnected(device, device->joysticks[0]); + } + return size >= 0; +} + +static void HIDAPI_DriverStadia_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ +} + +static void HIDAPI_DriverStadia_FreeDevice(SDL_HIDAPI_Device *device) +{ +} + +SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverStadia = { + SDL_HINT_JOYSTICK_HIDAPI_STADIA, + SDL_TRUE, + HIDAPI_DriverStadia_RegisterHints, + HIDAPI_DriverStadia_UnregisterHints, + HIDAPI_DriverStadia_IsEnabled, + HIDAPI_DriverStadia_IsSupportedDevice, + HIDAPI_DriverStadia_InitDevice, + HIDAPI_DriverStadia_GetDevicePlayerIndex, + HIDAPI_DriverStadia_SetDevicePlayerIndex, + HIDAPI_DriverStadia_UpdateDevice, + HIDAPI_DriverStadia_OpenJoystick, + HIDAPI_DriverStadia_RumbleJoystick, + HIDAPI_DriverStadia_RumbleJoystickTriggers, + HIDAPI_DriverStadia_GetJoystickCapabilities, + HIDAPI_DriverStadia_SetJoystickLED, + HIDAPI_DriverStadia_SendJoystickEffect, + HIDAPI_DriverStadia_SetJoystickSensorsEnabled, + HIDAPI_DriverStadia_CloseJoystick, + HIDAPI_DriverStadia_FreeDevice, +}; + +#endif /* SDL_JOYSTICK_HIDAPI_STADIA */ + +#endif /* SDL_JOYSTICK_HIDAPI */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_steam.c b/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_steam.c new file mode 100644 index 0000000..9f9e0e3 --- /dev/null +++ b/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_steam.c @@ -0,0 +1,1243 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_JOYSTICK_HIDAPI + +#include "SDL_events.h" +#include "SDL_timer.h" +#include "SDL_joystick.h" +#include "SDL_gamecontroller.h" +#include "../SDL_sysjoystick.h" +#include "SDL_hidapijoystick_c.h" + +#ifdef SDL_JOYSTICK_HIDAPI_STEAM + +/*****************************************************************************************************/ + +#define bool SDL_bool +#define true SDL_TRUE +#define false SDL_FALSE + +#include "steam/controller_constants.h" +#include "steam/controller_structs.h" + +typedef struct SteamControllerStateInternal_t +{ + // Controller Type for this Controller State + Uint32 eControllerType; + + // If packet num matches that on your prior call, then the controller state hasn't been changed since + // your last call and there is no need to process it + Uint32 unPacketNum; + + // bit flags for each of the buttons + Uint64 ulButtons; + + // Left pad coordinates + short sLeftPadX; + short sLeftPadY; + + // Right pad coordinates + short sRightPadX; + short sRightPadY; + + // Center pad coordinates + short sCenterPadX; + short sCenterPadY; + + // Left analog stick coordinates + short sLeftStickX; + short sLeftStickY; + + // Right analog stick coordinates + short sRightStickX; + short sRightStickY; + + unsigned short sTriggerL; + unsigned short sTriggerR; + + short sAccelX; + short sAccelY; + short sAccelZ; + + short sGyroX; + short sGyroY; + short sGyroZ; + + float sGyroQuatW; + float sGyroQuatX; + float sGyroQuatY; + float sGyroQuatZ; + + short sGyroSteeringAngle; + + unsigned short sBatteryLevel; + + // Pressure sensor data. + unsigned short sPressurePadLeft; + unsigned short sPressurePadRight; + + unsigned short sPressureBumperLeft; + unsigned short sPressureBumperRight; + + // Internal state data + short sPrevLeftPad[2]; + short sPrevLeftStick[2]; +} SteamControllerStateInternal_t; + +/* Defines for ulButtons in SteamControllerStateInternal_t */ +#define STEAM_RIGHT_TRIGGER_MASK 0x00000001 +#define STEAM_LEFT_TRIGGER_MASK 0x00000002 +#define STEAM_RIGHT_BUMPER_MASK 0x00000004 +#define STEAM_LEFT_BUMPER_MASK 0x00000008 +#define STEAM_BUTTON_0_MASK 0x00000010 /* Y */ +#define STEAM_BUTTON_1_MASK 0x00000020 /* B */ +#define STEAM_BUTTON_2_MASK 0x00000040 /* X */ +#define STEAM_BUTTON_3_MASK 0x00000080 /* A */ +#define STEAM_TOUCH_0_MASK 0x00000100 /* DPAD UP */ +#define STEAM_TOUCH_1_MASK 0x00000200 /* DPAD RIGHT */ +#define STEAM_TOUCH_2_MASK 0x00000400 /* DPAD LEFT */ +#define STEAM_TOUCH_3_MASK 0x00000800 /* DPAD DOWN */ +#define STEAM_BUTTON_MENU_MASK 0x00001000 /* SELECT */ +#define STEAM_BUTTON_STEAM_MASK 0x00002000 /* GUIDE */ +#define STEAM_BUTTON_ESCAPE_MASK 0x00004000 /* START */ +#define STEAM_BUTTON_BACK_LEFT_MASK 0x00008000 +#define STEAM_BUTTON_BACK_RIGHT_MASK 0x00010000 +#define STEAM_BUTTON_LEFTPAD_CLICKED_MASK 0x00020000 +#define STEAM_BUTTON_RIGHTPAD_CLICKED_MASK 0x00040000 +#define STEAM_LEFTPAD_FINGERDOWN_MASK 0x00080000 +#define STEAM_RIGHTPAD_FINGERDOWN_MASK 0x00100000 +#define STEAM_JOYSTICK_BUTTON_MASK 0x00400000 +#define STEAM_LEFTPAD_AND_JOYSTICK_MASK 0x00800000 + +// Look for report version 0x0001, type WIRELESS (3), length >= 1 byte +#define D0G_IS_VALID_WIRELESS_EVENT(data, len) ((len) >= 5 && (data)[0] == 1 && (data)[1] == 0 && (data)[2] == 3 && (data)[3] >= 1) +#define D0G_GET_WIRELESS_EVENT_TYPE(data) ((data)[4]) +#define D0G_WIRELESS_DISCONNECTED 1 +#define D0G_WIRELESS_ESTABLISHED 2 +#define D0G_WIRELESS_NEWLYPAIRED 3 + +#define D0G_IS_WIRELESS_DISCONNECT(data, len) (D0G_IS_VALID_WIRELESS_EVENT(data, len) && D0G_GET_WIRELESS_EVENT_TYPE(data) == D0G_WIRELESS_DISCONNECTED) + +#define MAX_REPORT_SEGMENT_PAYLOAD_SIZE 18 +/* + * SteamControllerPacketAssembler has to be used when reading output repots from controllers. + */ +typedef struct +{ + uint8_t uBuffer[MAX_REPORT_SEGMENT_PAYLOAD_SIZE * 8 + 1]; + int nExpectedSegmentNumber; + bool bIsBle; +} SteamControllerPacketAssembler; + +#undef clamp +#define clamp(val, min, max) (((val) > (max)) ? (max) : (((val) < (min)) ? (min) : (val))) + +#undef offsetof +#define offsetof(s, m) (size_t) & (((s *)0)->m) + +#ifdef DEBUG_STEAM_CONTROLLER +#define DPRINTF(format, ...) printf(format, ##__VA_ARGS__) +#define HEXDUMP(ptr, len) hexdump(ptr, len) +#else +#define DPRINTF(format, ...) +#define HEXDUMP(ptr, len) +#endif +#define printf SDL_Log + +#define MAX_REPORT_SEGMENT_SIZE (MAX_REPORT_SEGMENT_PAYLOAD_SIZE + 2) +#define CALC_REPORT_SEGMENT_NUM(index) ((index / MAX_REPORT_SEGMENT_PAYLOAD_SIZE) & 0x07) +#define REPORT_SEGMENT_DATA_FLAG 0x80 +#define REPORT_SEGMENT_LAST_FLAG 0x40 +#define BLE_REPORT_NUMBER 0x03 + +#define STEAMCONTROLLER_TRIGGER_MAX_ANALOG 26000 + +// Enable mouse mode when using the Steam Controller locally +#undef ENABLE_MOUSE_MODE + +// Wireless firmware quirk: the firmware intentionally signals "failure" when performing +// SET_FEATURE / GET_FEATURE when it actually means "pending radio roundtrip". The only +// way to make SET_FEATURE / GET_FEATURE work is to loop several times with a sleep. If +// it takes more than 50ms to get the response for SET_FEATURE / GET_FEATURE, we assume +// that the controller has failed. +#define RADIO_WORKAROUND_SLEEP_ATTEMPTS 50 +#define RADIO_WORKAROUND_SLEEP_DURATION_US 500 + +// This was defined by experimentation. 2000 seemed to work but to give that extra bit of margin, set to 3ms. +#define CONTROLLER_CONFIGURATION_DELAY_US 3000 + +static uint8_t GetSegmentHeader(int nSegmentNumber, bool bLastPacket) +{ + uint8_t header = REPORT_SEGMENT_DATA_FLAG; + header |= nSegmentNumber; + if (bLastPacket) { + header |= REPORT_SEGMENT_LAST_FLAG; + } + + return header; +} + +static void hexdump(const uint8_t *ptr, int len) +{ + int i; + for (i = 0; i < len; ++i) { + printf("%02x ", ptr[i]); + } + printf("\n"); +} + +static void ResetSteamControllerPacketAssembler(SteamControllerPacketAssembler *pAssembler) +{ + SDL_memset(pAssembler->uBuffer, 0, sizeof(pAssembler->uBuffer)); + pAssembler->nExpectedSegmentNumber = 0; +} + +static void InitializeSteamControllerPacketAssembler(SteamControllerPacketAssembler *pAssembler) +{ + /* We only support BLE devices right now */ + pAssembler->bIsBle = true; + ResetSteamControllerPacketAssembler(pAssembler); +} + +// Returns: +// <0 on error +// 0 on not ready +// Complete packet size on completion +static int WriteSegmentToSteamControllerPacketAssembler(SteamControllerPacketAssembler *pAssembler, const uint8_t *pSegment, int nSegmentLength) +{ + if (pAssembler->bIsBle) { + uint8_t uSegmentHeader = pSegment[1]; + int nSegmentNumber = uSegmentHeader & 0x07; + + HEXDUMP(pSegment, nSegmentLength); + + if (pSegment[0] != BLE_REPORT_NUMBER) { + // We may get keyboard/mouse input events until controller stops sending them + return 0; + } + + if (nSegmentLength != MAX_REPORT_SEGMENT_SIZE) { + printf("Bad segment size! %d\n", nSegmentLength); + hexdump(pSegment, nSegmentLength); + ResetSteamControllerPacketAssembler(pAssembler); + return -1; + } + + DPRINTF("GOT PACKET HEADER = 0x%x\n", uSegmentHeader); + + if (!(uSegmentHeader & REPORT_SEGMENT_DATA_FLAG)) { + // We get empty segments, just ignore them + return 0; + } + + if (nSegmentNumber != pAssembler->nExpectedSegmentNumber) { + ResetSteamControllerPacketAssembler(pAssembler); + + if (nSegmentNumber) { + // This happens occasionally + DPRINTF("Bad segment number, got %d, expected %d\n", + nSegmentNumber, pAssembler->nExpectedSegmentNumber); + return -1; + } + } + + SDL_memcpy(pAssembler->uBuffer + nSegmentNumber * MAX_REPORT_SEGMENT_PAYLOAD_SIZE, + pSegment + 2, // ignore header and report number + MAX_REPORT_SEGMENT_PAYLOAD_SIZE); + + if (uSegmentHeader & REPORT_SEGMENT_LAST_FLAG) { + pAssembler->nExpectedSegmentNumber = 0; + return (nSegmentNumber + 1) * MAX_REPORT_SEGMENT_PAYLOAD_SIZE; + } + + pAssembler->nExpectedSegmentNumber++; + } else { + // Just pass through + SDL_memcpy(pAssembler->uBuffer, + pSegment, + nSegmentLength); + return nSegmentLength; + } + + return 0; +} + +#define BLE_MAX_READ_RETRIES 8 + +static int SetFeatureReport(SDL_hid_device *dev, unsigned char uBuffer[65], int nActualDataLen) +{ + int nRet = -1; + bool bBle = true; // only wireless/BLE for now, though macOS could do wired in the future + + DPRINTF("SetFeatureReport %p %p %d\n", dev, uBuffer, nActualDataLen); + + if (bBle) { + int nSegmentNumber = 0; + uint8_t uPacketBuffer[MAX_REPORT_SEGMENT_SIZE]; + unsigned char *pBufferPtr = uBuffer + 1; + + if (nActualDataLen < 1) { + return -1; + } + + // Skip report number in data + nActualDataLen--; + + while (nActualDataLen > 0) { + int nBytesInPacket = nActualDataLen > MAX_REPORT_SEGMENT_PAYLOAD_SIZE ? MAX_REPORT_SEGMENT_PAYLOAD_SIZE : nActualDataLen; + + nActualDataLen -= nBytesInPacket; + + // Construct packet + SDL_memset(uPacketBuffer, 0, sizeof(uPacketBuffer)); + uPacketBuffer[0] = BLE_REPORT_NUMBER; + uPacketBuffer[1] = GetSegmentHeader(nSegmentNumber, nActualDataLen == 0); + SDL_memcpy(&uPacketBuffer[2], pBufferPtr, nBytesInPacket); + + pBufferPtr += nBytesInPacket; + nSegmentNumber++; + + nRet = SDL_hid_send_feature_report(dev, uPacketBuffer, sizeof(uPacketBuffer)); + DPRINTF("SetFeatureReport() ret = %d\n", nRet); + } + } + + return nRet; +} + +static int GetFeatureReport(SDL_hid_device *dev, unsigned char uBuffer[65]) +{ + int nRet = -1; + bool bBle = true; + + DPRINTF("GetFeatureReport( %p %p )\n", dev, uBuffer); + + if (bBle) { + int nRetries = 0; + uint8_t uSegmentBuffer[MAX_REPORT_SEGMENT_SIZE + 1]; + uint8_t ucBytesToRead = MAX_REPORT_SEGMENT_SIZE; + uint8_t ucDataStartOffset = 0; + + SteamControllerPacketAssembler assembler; + InitializeSteamControllerPacketAssembler(&assembler); + + // On Windows and macOS, BLE devices get 2 copies of the feature report ID, one that is removed by ReadFeatureReport, + // and one that's included in the buffer we receive. We pad the bytes to read and skip over the report ID + // if necessary. +#if defined(__WIN32__) || defined(__MACOSX__) + ++ucBytesToRead; + ++ucDataStartOffset; +#endif + + while (nRetries < BLE_MAX_READ_RETRIES) { + SDL_memset(uSegmentBuffer, 0, sizeof(uSegmentBuffer)); + uSegmentBuffer[0] = BLE_REPORT_NUMBER; + nRet = SDL_hid_get_feature_report(dev, uSegmentBuffer, ucBytesToRead); + + DPRINTF("GetFeatureReport ble ret=%d\n", nRet); + HEXDUMP(uSegmentBuffer, nRet); + + // Zero retry counter if we got data + if (nRet > 2 && (uSegmentBuffer[ucDataStartOffset + 1] & REPORT_SEGMENT_DATA_FLAG)) { + nRetries = 0; + } else { + nRetries++; + } + + if (nRet > 0) { + int nPacketLength = WriteSegmentToSteamControllerPacketAssembler(&assembler, + uSegmentBuffer + ucDataStartOffset, + nRet - ucDataStartOffset); + + if (nPacketLength > 0 && nPacketLength < 65) { + // Leave space for "report number" + uBuffer[0] = 0; + SDL_memcpy(uBuffer + 1, assembler.uBuffer, nPacketLength); + return nPacketLength; + } + } + } + printf("Could not get a full ble packet after %d retries\n", nRetries); + return -1; + } + + return nRet; +} + +static int ReadResponse(SDL_hid_device *dev, uint8_t uBuffer[65], int nExpectedResponse) +{ + int nRet = GetFeatureReport(dev, uBuffer); + + DPRINTF("ReadResponse( %p %p %d )\n", dev, uBuffer, nExpectedResponse); + + if (nRet < 0) { + return nRet; + } + + DPRINTF("ReadResponse got %d bytes of data: ", nRet); + HEXDUMP(uBuffer, nRet); + + if (uBuffer[1] != nExpectedResponse) { + return -1; + } + + return nRet; +} + +//--------------------------------------------------------------------------- +// Reset steam controller (unmap buttons and pads) and re-fetch capability bits +//--------------------------------------------------------------------------- +static bool ResetSteamController(SDL_hid_device *dev, bool bSuppressErrorSpew, uint32_t *punUpdateRateUS) +{ + // Firmware quirk: Set Feature and Get Feature requests always require a 65-byte buffer. + unsigned char buf[65]; + unsigned int i; + int res = -1; + int nSettings = 0; + int nAttributesLength; + FeatureReportMsg *msg; + uint32_t unUpdateRateUS = 9000; // Good default rate + + DPRINTF("ResetSteamController hid=%p\n", dev); + + buf[0] = 0; + buf[1] = ID_GET_ATTRIBUTES_VALUES; + res = SetFeatureReport(dev, buf, 2); + if (res < 0) { + if (!bSuppressErrorSpew) { + printf("GET_ATTRIBUTES_VALUES failed for controller %p\n", dev); + } + return false; + } + + // Retrieve GET_ATTRIBUTES_VALUES result + // Wireless controller endpoints without a connected controller will return nAttrs == 0 + res = ReadResponse(dev, buf, ID_GET_ATTRIBUTES_VALUES); + if (res < 0 || buf[1] != ID_GET_ATTRIBUTES_VALUES) { + HEXDUMP(buf, res); + if (!bSuppressErrorSpew) { + printf("Bad GET_ATTRIBUTES_VALUES response for controller %p\n", dev); + } + return false; + } + + nAttributesLength = buf[2]; + if (nAttributesLength > res) { + if (!bSuppressErrorSpew) { + printf("Bad GET_ATTRIBUTES_VALUES response for controller %p\n", dev); + } + return false; + } + + msg = (FeatureReportMsg *)&buf[1]; + for (i = 0; i < (int)msg->header.length / sizeof(ControllerAttribute); ++i) { + uint8_t unAttribute = msg->payload.getAttributes.attributes[i].attributeTag; + uint32_t unValue = msg->payload.getAttributes.attributes[i].attributeValue; + + switch (unAttribute) { + case ATTRIB_UNIQUE_ID: + break; + case ATTRIB_PRODUCT_ID: + break; + case ATTRIB_CAPABILITIES: + break; + case ATTRIB_CONNECTION_INTERVAL_IN_US: + unUpdateRateUS = unValue; + break; + default: + break; + } + } + if (punUpdateRateUS) { + *punUpdateRateUS = unUpdateRateUS; + } + + // Clear digital button mappings + buf[0] = 0; + buf[1] = ID_CLEAR_DIGITAL_MAPPINGS; + res = SetFeatureReport(dev, buf, 2); + if (res < 0) { + if (!bSuppressErrorSpew) { + printf("CLEAR_DIGITAL_MAPPINGS failed for controller %p\n", dev); + } + return false; + } + + // Reset the default settings + SDL_memset(buf, 0, 65); + buf[1] = ID_LOAD_DEFAULT_SETTINGS; + buf[2] = 0; + res = SetFeatureReport(dev, buf, 3); + if (res < 0) { + if (!bSuppressErrorSpew) { + printf("LOAD_DEFAULT_SETTINGS failed for controller %p\n", dev); + } + return false; + } + + // Apply custom settings - clear trackpad modes (cancel mouse emulation), etc +#define ADD_SETTING(SETTING, VALUE) \ + buf[3 + nSettings * 3] = SETTING; \ + buf[3 + nSettings * 3 + 1] = ((uint16_t)VALUE) & 0xFF; \ + buf[3 + nSettings * 3 + 2] = ((uint16_t)VALUE) >> 8; \ + ++nSettings; + + SDL_memset(buf, 0, 65); + buf[1] = ID_SET_SETTINGS_VALUES; + ADD_SETTING(SETTING_WIRELESS_PACKET_VERSION, 2); + ADD_SETTING(SETTING_LEFT_TRACKPAD_MODE, TRACKPAD_NONE); +#ifdef ENABLE_MOUSE_MODE + ADD_SETTING(SETTING_RIGHT_TRACKPAD_MODE, TRACKPAD_ABSOLUTE_MOUSE); + ADD_SETTING(SETTING_SMOOTH_ABSOLUTE_MOUSE, 1); + ADD_SETTING(SETTING_MOMENTUM_MAXIMUM_VELOCITY, 20000); // [0-20000] default 8000 + ADD_SETTING(SETTING_MOMENTUM_DECAY_AMMOUNT, 50); // [0-50] default 5 +#else + ADD_SETTING(SETTING_RIGHT_TRACKPAD_MODE, TRACKPAD_NONE); + ADD_SETTING(SETTING_SMOOTH_ABSOLUTE_MOUSE, 0); +#endif + buf[2] = nSettings * 3; + + res = SetFeatureReport(dev, buf, 3 + nSettings * 3); + if (res < 0) { + if (!bSuppressErrorSpew) { + printf("SET_SETTINGS failed for controller %p\n", dev); + } + return false; + } + +#ifdef ENABLE_MOUSE_MODE + // Wait for ID_CLEAR_DIGITAL_MAPPINGS to be processed on the controller + bool bMappingsCleared = false; + int iRetry; + for (iRetry = 0; iRetry < 2; ++iRetry) { + SDL_memset(buf, 0, 65); + buf[1] = ID_GET_DIGITAL_MAPPINGS; + buf[2] = 1; // one byte - requesting from index 0 + buf[3] = 0; + res = SetFeatureReport(dev, buf, 4); + if (res < 0) { + printf("GET_DIGITAL_MAPPINGS failed for controller %p\n", dev); + return false; + } + + res = ReadResponse(dev, buf, ID_GET_DIGITAL_MAPPINGS); + if (res < 0 || buf[1] != ID_GET_DIGITAL_MAPPINGS) { + printf("Bad GET_DIGITAL_MAPPINGS response for controller %p\n", dev); + return false; + } + + // If the length of the digital mappings result is not 1 (index byte, no mappings) then clearing hasn't executed + if (buf[2] == 1 && buf[3] == 0xFF) { + bMappingsCleared = true; + break; + } + usleep(CONTROLLER_CONFIGURATION_DELAY_US); + } + + if (!bMappingsCleared && !bSuppressErrorSpew) { + printf("Warning: CLEAR_DIGITAL_MAPPINGS never completed for controller %p\n", dev); + } + + // Set our new mappings + SDL_memset(buf, 0, 65); + buf[1] = ID_SET_DIGITAL_MAPPINGS; + buf[2] = 6; // 2 settings x 3 bytes + buf[3] = IO_DIGITAL_BUTTON_RIGHT_TRIGGER; + buf[4] = DEVICE_MOUSE; + buf[5] = MOUSE_BTN_LEFT; + buf[6] = IO_DIGITAL_BUTTON_LEFT_TRIGGER; + buf[7] = DEVICE_MOUSE; + buf[8] = MOUSE_BTN_RIGHT; + + res = SetFeatureReport(dev, buf, 9); + if (res < 0) { + if (!bSuppressErrorSpew) { + printf("SET_DIGITAL_MAPPINGS failed for controller %p\n", dev); + } + return false; + } +#endif // ENABLE_MOUSE_MODE + + return true; +} + +//--------------------------------------------------------------------------- +// Read from a Steam Controller +//--------------------------------------------------------------------------- +static int ReadSteamController(SDL_hid_device *dev, uint8_t *pData, int nDataSize) +{ + SDL_memset(pData, 0, nDataSize); + pData[0] = BLE_REPORT_NUMBER; // hid_read will also overwrite this with the same value, 0x03 + return SDL_hid_read(dev, pData, nDataSize); +} + +//--------------------------------------------------------------------------- +// Close a Steam Controller +//--------------------------------------------------------------------------- +static void CloseSteamController(SDL_hid_device *dev) +{ + // Switch the Steam Controller back to lizard mode so it works with the OS + unsigned char buf[65]; + int nSettings = 0; + + // Reset digital button mappings + SDL_memset(buf, 0, 65); + buf[1] = ID_SET_DEFAULT_DIGITAL_MAPPINGS; + SetFeatureReport(dev, buf, 2); + + // Reset the default settings + SDL_memset(buf, 0, 65); + buf[1] = ID_LOAD_DEFAULT_SETTINGS; + buf[2] = 0; + SetFeatureReport(dev, buf, 3); + + // Reset mouse mode for lizard mode + SDL_memset(buf, 0, 65); + buf[1] = ID_SET_SETTINGS_VALUES; + ADD_SETTING(SETTING_RIGHT_TRACKPAD_MODE, TRACKPAD_ABSOLUTE_MOUSE); + buf[2] = nSettings * 3; + SetFeatureReport(dev, buf, 3 + nSettings * 3); +} + +//--------------------------------------------------------------------------- +// Scale and clamp values to a range +//--------------------------------------------------------------------------- +static float RemapValClamped(float val, float A, float B, float C, float D) +{ + if (A == B) { + return (val - B) >= 0.0f ? D : C; + } else { + float cVal = (val - A) / (B - A); + cVal = clamp(cVal, 0.0f, 1.0f); + + return C + (D - C) * cVal; + } +} + +//--------------------------------------------------------------------------- +// Rotate the pad coordinates +//--------------------------------------------------------------------------- +static void RotatePad(int *pX, int *pY, float flAngleInRad) +{ + short int origX = *pX, origY = *pY; + + *pX = (int)(SDL_cosf(flAngleInRad) * origX - SDL_sinf(flAngleInRad) * origY); + *pY = (int)(SDL_sinf(flAngleInRad) * origX + SDL_cosf(flAngleInRad) * origY); +} +static void RotatePadShort(short *pX, short *pY, float flAngleInRad) +{ + short int origX = *pX, origY = *pY; + + *pX = (short)(SDL_cosf(flAngleInRad) * origX - SDL_sinf(flAngleInRad) * origY); + *pY = (short)(SDL_sinf(flAngleInRad) * origX + SDL_cosf(flAngleInRad) * origY); +} + +//--------------------------------------------------------------------------- +// Format the first part of the state packet +//--------------------------------------------------------------------------- +static void FormatStatePacketUntilGyro(SteamControllerStateInternal_t *pState, ValveControllerStatePacket_t *pStatePacket) +{ + int nLeftPadX; + int nLeftPadY; + int nRightPadX; + int nRightPadY; + int nPadOffset; + + // 15 degrees in rad + const float flRotationAngle = 0.261799f; + + SDL_memset(pState, 0, offsetof(SteamControllerStateInternal_t, sBatteryLevel)); + + // pState->eControllerType = m_eControllerType; + pState->eControllerType = 2; // k_eControllerType_SteamController; + pState->unPacketNum = pStatePacket->unPacketNum; + + // We have a chunk of trigger data in the packet format here, so zero it out afterwards + SDL_memcpy(&pState->ulButtons, &pStatePacket->ButtonTriggerData.ulButtons, 8); + pState->ulButtons &= ~0xFFFF000000LL; + + // The firmware uses this bit to tell us what kind of data is packed into the left two axises + if (pStatePacket->ButtonTriggerData.ulButtons & STEAM_LEFTPAD_FINGERDOWN_MASK) { + // Finger-down bit not set; "left pad" is actually trackpad + pState->sLeftPadX = pState->sPrevLeftPad[0] = pStatePacket->sLeftPadX; + pState->sLeftPadY = pState->sPrevLeftPad[1] = pStatePacket->sLeftPadY; + + if (pStatePacket->ButtonTriggerData.ulButtons & STEAM_LEFTPAD_AND_JOYSTICK_MASK) { + // The controller is interleaving both stick and pad data, both are active + pState->sLeftStickX = pState->sPrevLeftStick[0]; + pState->sLeftStickY = pState->sPrevLeftStick[1]; + } else { + // The stick is not active + pState->sPrevLeftStick[0] = 0; + pState->sPrevLeftStick[1] = 0; + } + } else { + // Finger-down bit not set; "left pad" is actually joystick + + // XXX there's a firmware bug where sometimes padX is 0 and padY is a large number (acutally the battery voltage) + // If that happens skip this packet and report last frames stick + /* + if ( m_eControllerType == k_eControllerType_SteamControllerV2 && pStatePacket->sLeftPadY > 900 ) { + pState->sLeftStickX = pState->sPrevLeftStick[0]; + pState->sLeftStickY = pState->sPrevLeftStick[1]; + } else + */ + { + pState->sPrevLeftStick[0] = pState->sLeftStickX = pStatePacket->sLeftPadX; + pState->sPrevLeftStick[1] = pState->sLeftStickY = pStatePacket->sLeftPadY; + } + /* + if (m_eControllerType == k_eControllerType_SteamControllerV2) { + UpdateV2JoystickCap(&state); + } + */ + + if (pStatePacket->ButtonTriggerData.ulButtons & STEAM_LEFTPAD_AND_JOYSTICK_MASK) { + // The controller is interleaving both stick and pad data, both are active + pState->sLeftPadX = pState->sPrevLeftPad[0]; + pState->sLeftPadY = pState->sPrevLeftPad[1]; + } else { + // The trackpad is not active + pState->sPrevLeftPad[0] = 0; + pState->sPrevLeftPad[1] = 0; + + // Old controllers send trackpad click for joystick button when trackpad is not active + if (pState->ulButtons & STEAM_BUTTON_LEFTPAD_CLICKED_MASK) { + pState->ulButtons &= ~STEAM_BUTTON_LEFTPAD_CLICKED_MASK; + pState->ulButtons |= STEAM_JOYSTICK_BUTTON_MASK; + } + } + } + + // Fingerdown bit indicates if the packed left axis data was joystick or pad, + // but if we are interleaving both, the left finger is definitely on the pad. + if (pStatePacket->ButtonTriggerData.ulButtons & STEAM_LEFTPAD_AND_JOYSTICK_MASK) { + pState->ulButtons |= STEAM_LEFTPAD_FINGERDOWN_MASK; + } + + pState->sRightPadX = pStatePacket->sRightPadX; + pState->sRightPadY = pStatePacket->sRightPadY; + + nLeftPadX = pState->sLeftPadX; + nLeftPadY = pState->sLeftPadY; + nRightPadX = pState->sRightPadX; + nRightPadY = pState->sRightPadY; + + RotatePad(&nLeftPadX, &nLeftPadY, -flRotationAngle); + RotatePad(&nRightPadX, &nRightPadY, flRotationAngle); + + if (pState->ulButtons & STEAM_LEFTPAD_FINGERDOWN_MASK) { + nPadOffset = 1000; + } else { + nPadOffset = 0; + } + + pState->sLeftPadX = clamp(nLeftPadX + nPadOffset, SDL_MIN_SINT16, SDL_MAX_SINT16); + pState->sLeftPadY = clamp(nLeftPadY + nPadOffset, SDL_MIN_SINT16, SDL_MAX_SINT16); + + nPadOffset = 0; + if (pState->ulButtons & STEAM_RIGHTPAD_FINGERDOWN_MASK) { + nPadOffset = 1000; + } else { + nPadOffset = 0; + } + + pState->sRightPadX = clamp(nRightPadX + nPadOffset, SDL_MIN_SINT16, SDL_MAX_SINT16); + pState->sRightPadY = clamp(nRightPadY + nPadOffset, SDL_MIN_SINT16, SDL_MAX_SINT16); + + pState->sTriggerL = (unsigned short)RemapValClamped((float)((pStatePacket->ButtonTriggerData.Triggers.nLeft << 7) | pStatePacket->ButtonTriggerData.Triggers.nLeft), 0, STEAMCONTROLLER_TRIGGER_MAX_ANALOG, 0, SDL_MAX_SINT16); + pState->sTriggerR = (unsigned short)RemapValClamped((float)((pStatePacket->ButtonTriggerData.Triggers.nRight << 7) | pStatePacket->ButtonTriggerData.Triggers.nRight), 0, STEAMCONTROLLER_TRIGGER_MAX_ANALOG, 0, SDL_MAX_SINT16); +} + +//--------------------------------------------------------------------------- +// Update Steam Controller state from a BLE data packet, returns true if it parsed data +//--------------------------------------------------------------------------- +static bool UpdateBLESteamControllerState(const uint8_t *pData, int nDataSize, SteamControllerStateInternal_t *pState) +{ + const float flRotationAngle = 0.261799f; + uint32_t ucOptionDataMask; + + pState->unPacketNum++; + ucOptionDataMask = (*pData++ & 0xF0); + ucOptionDataMask |= (uint32_t)(*pData++) << 8; + if (ucOptionDataMask & k_EBLEButtonChunk1) { + SDL_memcpy(&pState->ulButtons, pData, 3); + pData += 3; + } + if (ucOptionDataMask & k_EBLEButtonChunk2) { + // The middle 2 bytes of the button bits over the wire are triggers when over the wire and non-SC buttons in the internal controller state packet + pState->sTriggerL = (unsigned short)RemapValClamped((float)((pData[0] << 7) | pData[0]), 0, STEAMCONTROLLER_TRIGGER_MAX_ANALOG, 0, SDL_MAX_SINT16); + pState->sTriggerR = (unsigned short)RemapValClamped((float)((pData[1] << 7) | pData[1]), 0, STEAMCONTROLLER_TRIGGER_MAX_ANALOG, 0, SDL_MAX_SINT16); + pData += 2; + } + if (ucOptionDataMask & k_EBLEButtonChunk3) { + uint8_t *pButtonByte = (uint8_t *)&pState->ulButtons; + pButtonByte[5] = *pData++; + pButtonByte[6] = *pData++; + pButtonByte[7] = *pData++; + } + if (ucOptionDataMask & k_EBLELeftJoystickChunk) { + // This doesn't handle any of the special headcrab stuff for raw joystick which is OK for now since that FW doesn't support + // this protocol yet either + int nLength = sizeof(pState->sLeftStickX) + sizeof(pState->sLeftStickY); + SDL_memcpy(&pState->sLeftStickX, pData, nLength); + pData += nLength; + } + if (ucOptionDataMask & k_EBLELeftTrackpadChunk) { + int nLength = sizeof(pState->sLeftPadX) + sizeof(pState->sLeftPadY); + int nPadOffset; + SDL_memcpy(&pState->sLeftPadX, pData, nLength); + if (pState->ulButtons & STEAM_LEFTPAD_FINGERDOWN_MASK) { + nPadOffset = 1000; + } else { + nPadOffset = 0; + } + + RotatePadShort(&pState->sLeftPadX, &pState->sLeftPadY, -flRotationAngle); + pState->sLeftPadX = clamp(pState->sLeftPadX + nPadOffset, SDL_MIN_SINT16, SDL_MAX_SINT16); + pState->sLeftPadY = clamp(pState->sLeftPadY + nPadOffset, SDL_MIN_SINT16, SDL_MAX_SINT16); + pData += nLength; + } + if (ucOptionDataMask & k_EBLERightTrackpadChunk) { + int nLength = sizeof(pState->sRightPadX) + sizeof(pState->sRightPadY); + int nPadOffset = 0; + + SDL_memcpy(&pState->sRightPadX, pData, nLength); + + if (pState->ulButtons & STEAM_RIGHTPAD_FINGERDOWN_MASK) { + nPadOffset = 1000; + } else { + nPadOffset = 0; + } + + RotatePadShort(&pState->sRightPadX, &pState->sRightPadY, flRotationAngle); + pState->sRightPadX = clamp(pState->sRightPadX + nPadOffset, SDL_MIN_SINT16, SDL_MAX_SINT16); + pState->sRightPadY = clamp(pState->sRightPadY + nPadOffset, SDL_MIN_SINT16, SDL_MAX_SINT16); + pData += nLength; + } + if (ucOptionDataMask & k_EBLEIMUAccelChunk) { + int nLength = sizeof(pState->sAccelX) + sizeof(pState->sAccelY) + sizeof(pState->sAccelZ); + SDL_memcpy(&pState->sAccelX, pData, nLength); + pData += nLength; + } + if (ucOptionDataMask & k_EBLEIMUGyroChunk) { + int nLength = sizeof(pState->sAccelX) + sizeof(pState->sAccelY) + sizeof(pState->sAccelZ); + SDL_memcpy(&pState->sGyroX, pData, nLength); + pData += nLength; + } + if (ucOptionDataMask & k_EBLEIMUQuatChunk) { + int nLength = sizeof(pState->sGyroQuatW) + sizeof(pState->sGyroQuatX) + sizeof(pState->sGyroQuatY) + sizeof(pState->sGyroQuatZ); + SDL_memcpy(&pState->sGyroQuatW, pData, nLength); + pData += nLength; + } + return true; +} + +//--------------------------------------------------------------------------- +// Update Steam Controller state from a data packet, returns true if it parsed data +//--------------------------------------------------------------------------- +static bool UpdateSteamControllerState(const uint8_t *pData, int nDataSize, SteamControllerStateInternal_t *pState) +{ + ValveInReport_t *pInReport = (ValveInReport_t *)pData; + + if (pInReport->header.unReportVersion != k_ValveInReportMsgVersion) { + if ((pData[0] & 0x0F) == k_EBLEReportState) { + return UpdateBLESteamControllerState(pData, nDataSize, pState); + } + return false; + } + + if ((pInReport->header.ucType != ID_CONTROLLER_STATE) && + (pInReport->header.ucType != ID_CONTROLLER_BLE_STATE)) { + return false; + } + + if (pInReport->header.ucType == ID_CONTROLLER_STATE) { + ValveControllerStatePacket_t *pStatePacket = &pInReport->payload.controllerState; + + // No new data to process; indicate that we received a state packet, but otherwise do nothing. + if (pState->unPacketNum == pStatePacket->unPacketNum) { + return true; + } + + FormatStatePacketUntilGyro(pState, pStatePacket); + + pState->sAccelX = pStatePacket->sAccelX; + pState->sAccelY = pStatePacket->sAccelY; + pState->sAccelZ = pStatePacket->sAccelZ; + + pState->sGyroQuatW = pStatePacket->sGyroQuatW; + pState->sGyroQuatX = pStatePacket->sGyroQuatX; + pState->sGyroQuatY = pStatePacket->sGyroQuatY; + pState->sGyroQuatZ = pStatePacket->sGyroQuatZ; + + pState->sGyroX = pStatePacket->sGyroX; + pState->sGyroY = pStatePacket->sGyroY; + pState->sGyroZ = pStatePacket->sGyroZ; + + } else if (pInReport->header.ucType == ID_CONTROLLER_BLE_STATE) { + ValveControllerBLEStatePacket_t *pBLEStatePacket = &pInReport->payload.controllerBLEState; + ValveControllerStatePacket_t *pStatePacket = &pInReport->payload.controllerState; + + // No new data to process; indicate that we received a state packet, but otherwise do nothing. + if (pState->unPacketNum == pStatePacket->unPacketNum) { + return true; + } + + FormatStatePacketUntilGyro(pState, pStatePacket); + + switch (pBLEStatePacket->ucGyroDataType) { + case 1: + pState->sGyroQuatW = ((float)pBLEStatePacket->sGyro[0]); + pState->sGyroQuatX = ((float)pBLEStatePacket->sGyro[1]); + pState->sGyroQuatY = ((float)pBLEStatePacket->sGyro[2]); + pState->sGyroQuatZ = ((float)pBLEStatePacket->sGyro[3]); + break; + + case 2: + pState->sAccelX = pBLEStatePacket->sGyro[0]; + pState->sAccelY = pBLEStatePacket->sGyro[1]; + pState->sAccelZ = pBLEStatePacket->sGyro[2]; + break; + + case 3: + pState->sGyroX = pBLEStatePacket->sGyro[0]; + pState->sGyroY = pBLEStatePacket->sGyro[1]; + pState->sGyroZ = pBLEStatePacket->sGyro[2]; + break; + + default: + break; + } + } + + return true; +} + +/*****************************************************************************************************/ + +typedef struct +{ + SDL_bool report_sensors; + uint32_t update_rate_in_us; + Uint32 timestamp_us; + + SteamControllerPacketAssembler m_assembler; + SteamControllerStateInternal_t m_state; + SteamControllerStateInternal_t m_last_state; +} SDL_DriverSteam_Context; + +static void HIDAPI_DriverSteam_RegisterHints(SDL_HintCallback callback, void *userdata) +{ + SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_STEAM, callback, userdata); +} + +static void HIDAPI_DriverSteam_UnregisterHints(SDL_HintCallback callback, void *userdata) +{ + SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_STEAM, callback, userdata); +} + +static SDL_bool HIDAPI_DriverSteam_IsEnabled(void) +{ + return SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_STEAM, SDL_FALSE); +} + +static SDL_bool HIDAPI_DriverSteam_IsSupportedDevice(SDL_HIDAPI_Device *device, const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol) +{ + return SDL_IsJoystickSteamController(vendor_id, product_id); +} + +static SDL_bool HIDAPI_DriverSteam_InitDevice(SDL_HIDAPI_Device *device) +{ + SDL_DriverSteam_Context *ctx; + + ctx = (SDL_DriverSteam_Context *)SDL_calloc(1, sizeof(*ctx)); + if (!ctx) { + SDL_OutOfMemory(); + return SDL_FALSE; + } + device->context = ctx; + +#if defined(__WIN32__) + if (device->serial) { + /* We get a garbage serial number on Windows */ + SDL_free(device->serial); + device->serial = NULL; + } +#endif /* __WIN32__ */ + + HIDAPI_SetDeviceName(device, "Steam Controller"); + + return HIDAPI_JoystickConnected(device, NULL); +} + +static int HIDAPI_DriverSteam_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id) +{ + return -1; +} + +static void HIDAPI_DriverSteam_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index) +{ +} + +static SDL_bool HIDAPI_DriverSteam_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_DriverSteam_Context *ctx = (SDL_DriverSteam_Context *)device->context; + float update_rate_in_hz = 0.0f; + + SDL_AssertJoysticksLocked(); + + ctx->report_sensors = SDL_FALSE; + SDL_zero(ctx->m_assembler); + SDL_zero(ctx->m_state); + SDL_zero(ctx->m_last_state); + + if (!ResetSteamController(device->dev, false, &ctx->update_rate_in_us)) { + SDL_SetError("Couldn't reset controller"); + return SDL_FALSE; + } + if (ctx->update_rate_in_us > 0) { + update_rate_in_hz = 1000000.0f / ctx->update_rate_in_us; + } + + InitializeSteamControllerPacketAssembler(&ctx->m_assembler); + + /* Initialize the joystick capabilities */ + joystick->nbuttons = 17; + joystick->naxes = SDL_CONTROLLER_AXIS_MAX; + + SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, update_rate_in_hz); + SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, update_rate_in_hz); + + return SDL_TRUE; +} + +static int HIDAPI_DriverSteam_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ + /* You should use the full Steam Input API for rumble support */ + return SDL_Unsupported(); +} + +static int HIDAPI_DriverSteam_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) +{ + return SDL_Unsupported(); +} + +static Uint32 HIDAPI_DriverSteam_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + /* You should use the full Steam Input API for extended capabilities */ + return 0; +} + +static int HIDAPI_DriverSteam_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + /* You should use the full Steam Input API for LED support */ + return SDL_Unsupported(); +} + +static int HIDAPI_DriverSteam_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + +static int HIDAPI_DriverSteam_SetSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled) +{ + SDL_DriverSteam_Context *ctx = (SDL_DriverSteam_Context *)device->context; + unsigned char buf[65]; + int nSettings = 0; + + SDL_memset(buf, 0, 65); + buf[1] = ID_SET_SETTINGS_VALUES; + if (enabled) { + ADD_SETTING(SETTING_IMU_MODE, SETTING_GYRO_MODE_SEND_RAW_ACCEL | SETTING_GYRO_MODE_SEND_RAW_GYRO); + } else { + ADD_SETTING(SETTING_IMU_MODE, SETTING_GYRO_MODE_OFF); + } + buf[2] = nSettings * 3; + if (SetFeatureReport(device->dev, buf, 3 + nSettings * 3) < 0) { + return SDL_SetError("Couldn't write feature report"); + } + + ctx->report_sensors = enabled; + + return 0; +} + +static SDL_bool HIDAPI_DriverSteam_UpdateDevice(SDL_HIDAPI_Device *device) +{ + SDL_DriverSteam_Context *ctx = (SDL_DriverSteam_Context *)device->context; + SDL_Joystick *joystick = NULL; + + if (device->num_joysticks > 0) { + joystick = SDL_JoystickFromInstanceID(device->joysticks[0]); + } else { + return SDL_FALSE; + } + + for (;;) { + uint8_t data[128]; + int r, nPacketLength; + const Uint8 *pPacket; + + r = ReadSteamController(device->dev, data, sizeof(data)); + if (r == 0) { + break; + } + + if (!joystick) { + continue; + } + + nPacketLength = 0; + if (r > 0) { + nPacketLength = WriteSegmentToSteamControllerPacketAssembler(&ctx->m_assembler, data, r); + } + + pPacket = ctx->m_assembler.uBuffer; + + if (nPacketLength > 0 && UpdateSteamControllerState(pPacket, nPacketLength, &ctx->m_state)) { + if (ctx->m_state.ulButtons != ctx->m_last_state.ulButtons) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_A, + (ctx->m_state.ulButtons & STEAM_BUTTON_3_MASK) ? SDL_PRESSED : SDL_RELEASED); + + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_B, + (ctx->m_state.ulButtons & STEAM_BUTTON_1_MASK) ? SDL_PRESSED : SDL_RELEASED); + + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_X, + (ctx->m_state.ulButtons & STEAM_BUTTON_2_MASK) ? SDL_PRESSED : SDL_RELEASED); + + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_Y, + (ctx->m_state.ulButtons & STEAM_BUTTON_0_MASK) ? SDL_PRESSED : SDL_RELEASED); + + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, + (ctx->m_state.ulButtons & STEAM_LEFT_BUMPER_MASK) ? SDL_PRESSED : SDL_RELEASED); + + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, + (ctx->m_state.ulButtons & STEAM_RIGHT_BUMPER_MASK) ? SDL_PRESSED : SDL_RELEASED); + + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, + (ctx->m_state.ulButtons & STEAM_BUTTON_MENU_MASK) ? SDL_PRESSED : SDL_RELEASED); + + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, + (ctx->m_state.ulButtons & STEAM_BUTTON_ESCAPE_MASK) ? SDL_PRESSED : SDL_RELEASED); + + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, + (ctx->m_state.ulButtons & STEAM_BUTTON_STEAM_MASK) ? SDL_PRESSED : SDL_RELEASED); + + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, + (ctx->m_state.ulButtons & STEAM_JOYSTICK_BUTTON_MASK) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MISC1 + 0, + (ctx->m_state.ulButtons & STEAM_BUTTON_BACK_LEFT_MASK) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MISC1 + 1, + (ctx->m_state.ulButtons & STEAM_BUTTON_BACK_RIGHT_MASK) ? SDL_PRESSED : SDL_RELEASED); + } + { + /* Minimum distance from center of pad to register a direction */ + const int kPadDeadZone = 10000; + + /* Pad coordinates are like math grid coordinates: negative is bottom left */ + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, + (ctx->m_state.sLeftPadY > kPadDeadZone) ? SDL_PRESSED : SDL_RELEASED); + + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, + (ctx->m_state.sLeftPadY < -kPadDeadZone) ? SDL_PRESSED : SDL_RELEASED); + + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, + (ctx->m_state.sLeftPadX < -kPadDeadZone) ? SDL_PRESSED : SDL_RELEASED); + + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, + (ctx->m_state.sLeftPadX > kPadDeadZone) ? SDL_PRESSED : SDL_RELEASED); + } + + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, (int)ctx->m_state.sTriggerL * 2 - 32768); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, (int)ctx->m_state.sTriggerR * 2 - 32768); + + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, ctx->m_state.sLeftStickX); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, ~ctx->m_state.sLeftStickY); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, ctx->m_state.sRightPadX); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, ~ctx->m_state.sRightPadY); + + if (ctx->report_sensors) { + float values[3]; + + ctx->timestamp_us += ctx->update_rate_in_us; + + values[0] = (ctx->m_state.sGyroX / 32768.0f) * (2000.0f * ((float)M_PI / 180.0f)); + values[1] = (ctx->m_state.sGyroZ / 32768.0f) * (2000.0f * ((float)M_PI / 180.0f)); + values[2] = (ctx->m_state.sGyroY / 32768.0f) * (2000.0f * ((float)M_PI / 180.0f)); + SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_GYRO, ctx->timestamp_us, values, 3); + + values[0] = (ctx->m_state.sAccelX / 32768.0f) * 2.0f * SDL_STANDARD_GRAVITY; + values[1] = (ctx->m_state.sAccelZ / 32768.0f) * 2.0f * SDL_STANDARD_GRAVITY; + values[2] = (-ctx->m_state.sAccelY / 32768.0f) * 2.0f * SDL_STANDARD_GRAVITY; + SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_ACCEL, ctx->timestamp_us, values, 3); + } + + ctx->m_last_state = ctx->m_state; + } + + if (r <= 0) { + /* Failed to read from controller */ + HIDAPI_JoystickDisconnected(device, device->joysticks[0]); + return SDL_FALSE; + } + } + return SDL_TRUE; +} + +static void HIDAPI_DriverSteam_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + CloseSteamController(device->dev); +} + +static void HIDAPI_DriverSteam_FreeDevice(SDL_HIDAPI_Device *device) +{ +} + +SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSteam = { + SDL_HINT_JOYSTICK_HIDAPI_STEAM, + SDL_TRUE, + HIDAPI_DriverSteam_RegisterHints, + HIDAPI_DriverSteam_UnregisterHints, + HIDAPI_DriverSteam_IsEnabled, + HIDAPI_DriverSteam_IsSupportedDevice, + HIDAPI_DriverSteam_InitDevice, + HIDAPI_DriverSteam_GetDevicePlayerIndex, + HIDAPI_DriverSteam_SetDevicePlayerIndex, + HIDAPI_DriverSteam_UpdateDevice, + HIDAPI_DriverSteam_OpenJoystick, + HIDAPI_DriverSteam_RumbleJoystick, + HIDAPI_DriverSteam_RumbleJoystickTriggers, + HIDAPI_DriverSteam_GetJoystickCapabilities, + HIDAPI_DriverSteam_SetJoystickLED, + HIDAPI_DriverSteam_SendJoystickEffect, + HIDAPI_DriverSteam_SetSensorsEnabled, + HIDAPI_DriverSteam_CloseJoystick, + HIDAPI_DriverSteam_FreeDevice, +}; + +#endif /* SDL_JOYSTICK_HIDAPI_STEAM */ + +#endif /* SDL_JOYSTICK_HIDAPI */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_steamdeck.c b/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_steamdeck.c new file mode 100644 index 0000000..c26b3e6 --- /dev/null +++ b/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_steamdeck.c @@ -0,0 +1,425 @@ +/* + Simple DirectMedia Layer + Copyright (C) 2023 Max Maisel + + 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" + +#ifdef SDL_JOYSTICK_HIDAPI + +#include "../SDL_sysjoystick.h" +#include "SDL_events.h" +#include "SDL_hidapijoystick_c.h" + +#ifdef SDL_JOYSTICK_HIDAPI_STEAMDECK + +/*****************************************************************************************************/ + +#include "steam/controller_constants.h" +#include "steam/controller_structs.h" + +typedef enum +{ + STEAMDECK_LBUTTON_R2 = 0x00000001, + STEAMDECK_LBUTTON_L2 = 0x00000002, + STEAMDECK_LBUTTON_R = 0x00000004, + STEAMDECK_LBUTTON_L = 0x00000008, + STEAMDECK_LBUTTON_Y = 0x00000010, + STEAMDECK_LBUTTON_B = 0x00000020, + STEAMDECK_LBUTTON_X = 0x00000040, + STEAMDECK_LBUTTON_A = 0x00000080, + STEAMDECK_LBUTTON_DPAD_UP = 0x00000100, + STEAMDECK_LBUTTON_DPAD_RIGHT = 0x00000200, + STEAMDECK_LBUTTON_DPAD_LEFT = 0x00000400, + STEAMDECK_LBUTTON_DPAD_DOWN = 0x00000800, + STEAMDECK_LBUTTON_VIEW = 0x00001000, + STEAMDECK_LBUTTON_STEAM = 0x00002000, + STEAMDECK_LBUTTON_MENU = 0x00004000, + STEAMDECK_LBUTTON_L5 = 0x00008000, + STEAMDECK_LBUTTON_R5 = 0x00010000, + STEAMDECK_LBUTTON_LEFT_PAD = 0x00020000, + STEAMDECK_LBUTTON_RIGHT_PAD = 0x00040000, + STEAMDECK_LBUTTON_L3 = 0x00400000, + STEAMDECK_LBUTTON_R3 = 0x04000000, + + STEAMDECK_HBUTTON_L4 = 0x00000200, + STEAMDECK_HBUTTON_R4 = 0x00000400, + STEAMDECK_HBUTTON_QAM = 0x00040000, +} SteamDeckButtons; + +typedef struct +{ + Uint32 update_rate_us; + Uint32 sensor_timestamp_us; + Uint64 last_button_state; + Uint8 watchdog_counter; +} SDL_DriverSteamDeck_Context; + +static SDL_bool DisableDeckLizardMode(SDL_hid_device *dev) +{ + int rc; + Uint8 buffer[HID_FEATURE_REPORT_BYTES + 1] = { 0 }; + FeatureReportMsg *msg = (FeatureReportMsg *)(buffer + 1); + + msg->header.type = ID_CLEAR_DIGITAL_MAPPINGS; + + rc = SDL_hid_send_feature_report(dev, buffer, sizeof(buffer)); + if (rc != sizeof(buffer)) + return SDL_FALSE; + + msg->header.type = ID_SET_SETTINGS_VALUES; + msg->header.length = 5 * sizeof(ControllerSetting); + msg->payload.setSettingsValues.settings[0].settingNum = SETTING_SMOOTH_ABSOLUTE_MOUSE; + msg->payload.setSettingsValues.settings[0].settingValue = 0; + msg->payload.setSettingsValues.settings[1].settingNum = SETTING_LEFT_TRACKPAD_MODE; + msg->payload.setSettingsValues.settings[1].settingValue = TRACKPAD_NONE; + msg->payload.setSettingsValues.settings[2].settingNum = SETTING_RIGHT_TRACKPAD_MODE; // disable mouse + msg->payload.setSettingsValues.settings[2].settingValue = TRACKPAD_NONE; + msg->payload.setSettingsValues.settings[3].settingNum = SETTING_LEFT_TRACKPAD_CLICK_PRESSURE; // disable clicky pad + msg->payload.setSettingsValues.settings[3].settingValue = 0xFFFF; + msg->payload.setSettingsValues.settings[4].settingNum = SETTING_RIGHT_TRACKPAD_CLICK_PRESSURE; // disable clicky pad + msg->payload.setSettingsValues.settings[4].settingValue = 0xFFFF; + + rc = SDL_hid_send_feature_report(dev, buffer, sizeof(buffer)); + if (rc != sizeof(buffer)) + return SDL_FALSE; + + // There may be a lingering report read back after changing settings. + // Discard it. + SDL_hid_get_feature_report(dev, buffer, sizeof(buffer)); + + return SDL_TRUE; +} + +static SDL_bool FeedDeckLizardWatchdog(SDL_hid_device *dev) +{ + int rc; + Uint8 buffer[HID_FEATURE_REPORT_BYTES + 1] = { 0 }; + FeatureReportMsg *msg = (FeatureReportMsg *)(buffer + 1); + + msg->header.type = ID_CLEAR_DIGITAL_MAPPINGS; + + rc = SDL_hid_send_feature_report(dev, buffer, sizeof(buffer)); + if (rc != sizeof(buffer)) + return SDL_FALSE; + + msg->header.type = ID_SET_SETTINGS_VALUES; + msg->header.length = 1 * sizeof(ControllerSetting); + msg->payload.setSettingsValues.settings[0].settingNum = SETTING_RIGHT_TRACKPAD_MODE; + msg->payload.setSettingsValues.settings[0].settingValue = TRACKPAD_NONE; + + rc = SDL_hid_send_feature_report(dev, buffer, sizeof(buffer)); + if (rc != sizeof(buffer)) + return SDL_FALSE; + + // There may be a lingering report read back after changing settings. + // Discard it. + SDL_hid_get_feature_report(dev, buffer, sizeof(buffer)); + + return SDL_TRUE; +} + +/*****************************************************************************************************/ + +static void HIDAPI_DriverSteamDeck_RegisterHints(SDL_HintCallback callback, void *userdata) +{ + SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_STEAMDECK, callback, userdata); +} + +static void HIDAPI_DriverSteamDeck_UnregisterHints(SDL_HintCallback callback, void *userdata) +{ + SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_STEAMDECK, callback, userdata); +} + +static SDL_bool HIDAPI_DriverSteamDeck_IsEnabled(void) +{ + return SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_STEAMDECK, + SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI, SDL_HIDAPI_DEFAULT)); +} + +static SDL_bool HIDAPI_DriverSteamDeck_IsSupportedDevice( + SDL_HIDAPI_Device *device, + const char *name, + SDL_GameControllerType type, + Uint16 vendor_id, + Uint16 product_id, + Uint16 version, + int interface_number, + int interface_class, + int interface_subclass, + int interface_protocol) +{ + return SDL_IsJoystickSteamDeck(vendor_id, product_id); +} + +static SDL_bool HIDAPI_DriverSteamDeck_InitDevice(SDL_HIDAPI_Device *device) +{ + int size; + Uint8 data[64]; + SDL_DriverSteamDeck_Context *ctx; + + ctx = (SDL_DriverSteamDeck_Context *)SDL_calloc(1, sizeof(*ctx)); + if (ctx == NULL) { + SDL_OutOfMemory(); + return SDL_FALSE; + } + + // Always 1kHz according to USB descriptor + ctx->update_rate_us = 1000; + + device->context = ctx; + + // Read a report to see if this is the correct endpoint. + // Mouse, Keyboard and Controller have the same VID/PID but + // only the controller hidraw device receives hid reports. + size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 16); + if (size == 0) + return SDL_FALSE; + + if (!DisableDeckLizardMode(device->dev)) + return SDL_FALSE; + + HIDAPI_SetDeviceName(device, "Steam Deck"); + + return HIDAPI_JoystickConnected(device, NULL); +} + +static int HIDAPI_DriverSteamDeck_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id) +{ + return -1; +} + +static void HIDAPI_DriverSteamDeck_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index) +{ +} + +static SDL_bool HIDAPI_DriverSteamDeck_UpdateDevice(SDL_HIDAPI_Device *device) +{ + SDL_DriverSteamDeck_Context *ctx = (SDL_DriverSteamDeck_Context *)device->context; + SDL_Joystick *joystick = NULL; + int r; + uint8_t data[64]; + float values[3]; + ValveInReport_t *pInReport = (ValveInReport_t *)data; + + if (device->num_joysticks > 0) { + joystick = SDL_JoystickFromInstanceID(device->joysticks[0]); + if (joystick == NULL) { + return SDL_FALSE; + } + } else { + return SDL_FALSE; + } + + if (ctx->watchdog_counter++ > 200) { + ctx->watchdog_counter = 0; + if (!FeedDeckLizardWatchdog(device->dev)) + return SDL_FALSE; + } + + SDL_memset(data, 0, sizeof(data)); + r = SDL_hid_read(device->dev, data, sizeof(data)); + if (r == 0) { + return SDL_FALSE; + } else if (r <= 0) { + /* Failed to read from controller */ + HIDAPI_JoystickDisconnected(device, device->joysticks[0]); + return SDL_FALSE; + } + + if (!(r == 64 && pInReport->header.unReportVersion == k_ValveInReportMsgVersion && pInReport->header.ucType == ID_CONTROLLER_DECK_STATE && pInReport->header.ucLength == 64)) { + return SDL_FALSE; + } + + // Uint64 timestamp = SDL_GetTicksNS(); + + if (pInReport->payload.deckState.ulButtons != ctx->last_button_state) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_A, + (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_A) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_B, + (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_B) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_X, + (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_X) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_Y, + (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_Y) ? SDL_PRESSED : SDL_RELEASED); + + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, + (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_L) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, + (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_R) ? SDL_PRESSED : SDL_RELEASED); + + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, + (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_VIEW) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, + (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_MENU) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, + (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_STEAM) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MISC1, + (pInReport->payload.deckState.ulButtonsH & STEAMDECK_HBUTTON_QAM) ? SDL_PRESSED : SDL_RELEASED); + + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, + (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_L3) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, + (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_R3) ? SDL_PRESSED : SDL_RELEASED); + + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_PADDLE1, + (pInReport->payload.deckState.ulButtonsH & STEAMDECK_HBUTTON_R4) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_PADDLE2, + (pInReport->payload.deckState.ulButtonsH & STEAMDECK_HBUTTON_L4) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_PADDLE3, + (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_R5) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_PADDLE4, + (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_L5) ? SDL_PRESSED : SDL_RELEASED); + + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, + (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_DPAD_UP) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, + (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_DPAD_DOWN) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, + (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_DPAD_LEFT) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, + (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_DPAD_RIGHT) ? SDL_PRESSED : SDL_RELEASED); + ctx->last_button_state = pInReport->payload.deckState.ulButtons; + } + + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, + (int)pInReport->payload.deckState.sTriggerRawL * 2 - 32768); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, + (int)pInReport->payload.deckState.sTriggerRawR * 2 - 32768); + + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, + pInReport->payload.deckState.sLeftStickX); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, + -pInReport->payload.deckState.sLeftStickY); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, + pInReport->payload.deckState.sRightStickX); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, + -pInReport->payload.deckState.sRightStickY); + + ctx->sensor_timestamp_us += ctx->update_rate_us; + + values[0] = (pInReport->payload.deckState.sGyroX / 32768.0f) * (2000.0f * ((float)M_PI / 180.0f)); + values[1] = (pInReport->payload.deckState.sGyroZ / 32768.0f) * (2000.0f * ((float)M_PI / 180.0f)); + values[2] = (-pInReport->payload.deckState.sGyroY / 32768.0f) * (2000.0f * ((float)M_PI / 180.0f)); + SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_GYRO, ctx->sensor_timestamp_us, values, 3); + + values[0] = (pInReport->payload.deckState.sAccelX / 32768.0f) * 2.0f * SDL_STANDARD_GRAVITY; + values[1] = (pInReport->payload.deckState.sAccelZ / 32768.0f) * 2.0f * SDL_STANDARD_GRAVITY; + values[2] = (-pInReport->payload.deckState.sAccelY / 32768.0f) * 2.0f * SDL_STANDARD_GRAVITY; + SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_ACCEL, ctx->sensor_timestamp_us, values, 3); + + return SDL_TRUE; +} + +static SDL_bool HIDAPI_DriverSteamDeck_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_DriverSteamDeck_Context *ctx = (SDL_DriverSteamDeck_Context *)device->context; + float update_rate_in_hz = 1.0f / (float)(ctx->update_rate_us) * 1.0e6f; + + SDL_AssertJoysticksLocked(); + + // Initialize the joystick capabilities + joystick->nbuttons = 20; + joystick->naxes = SDL_CONTROLLER_AXIS_MAX; + + SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, update_rate_in_hz); + SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, update_rate_in_hz); + + return SDL_TRUE; +} + +static int HIDAPI_DriverSteamDeck_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ + int rc; + Uint8 buffer[HID_FEATURE_REPORT_BYTES + 1] = { 0 }; + FeatureReportMsg *msg = (FeatureReportMsg *)(buffer + 1); + + msg->header.type = ID_TRIGGER_RUMBLE_CMD; + msg->payload.simpleRumble.unRumbleType = 0; + msg->payload.simpleRumble.unIntensity = HAPTIC_INTENSITY_SYSTEM; + msg->payload.simpleRumble.unLeftMotorSpeed = low_frequency_rumble; + msg->payload.simpleRumble.unRightMotorSpeed = high_frequency_rumble; + msg->payload.simpleRumble.nLeftGain = 2; + msg->payload.simpleRumble.nRightGain = 0; + + rc = SDL_hid_send_feature_report(device->dev, buffer, sizeof(buffer)); + if (rc != sizeof(buffer)) + return -1; + return 0; +} + +static int HIDAPI_DriverSteamDeck_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) +{ + return SDL_Unsupported(); +} + +static Uint32 HIDAPI_DriverSteamDeck_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + return SDL_JOYCAP_RUMBLE; +} + +static int HIDAPI_DriverSteamDeck_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + return SDL_Unsupported(); +} + +static int HIDAPI_DriverSteamDeck_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + +static int HIDAPI_DriverSteamDeck_SetSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled) +{ + // On steam deck, sensors are enabled by default. Nothing to do here. + return 0; +} + +static void HIDAPI_DriverSteamDeck_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + // Lizard mode id automatically re-enabled by watchdog. Nothing to do here. +} + +static void HIDAPI_DriverSteamDeck_FreeDevice(SDL_HIDAPI_Device *device) +{ +} + +SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSteamDeck = { + SDL_HINT_JOYSTICK_HIDAPI_STEAMDECK, + SDL_TRUE, + HIDAPI_DriverSteamDeck_RegisterHints, + HIDAPI_DriverSteamDeck_UnregisterHints, + HIDAPI_DriverSteamDeck_IsEnabled, + HIDAPI_DriverSteamDeck_IsSupportedDevice, + HIDAPI_DriverSteamDeck_InitDevice, + HIDAPI_DriverSteamDeck_GetDevicePlayerIndex, + HIDAPI_DriverSteamDeck_SetDevicePlayerIndex, + HIDAPI_DriverSteamDeck_UpdateDevice, + HIDAPI_DriverSteamDeck_OpenJoystick, + HIDAPI_DriverSteamDeck_RumbleJoystick, + HIDAPI_DriverSteamDeck_RumbleJoystickTriggers, + HIDAPI_DriverSteamDeck_GetJoystickCapabilities, + HIDAPI_DriverSteamDeck_SetJoystickLED, + HIDAPI_DriverSteamDeck_SendJoystickEffect, + HIDAPI_DriverSteamDeck_SetSensorsEnabled, + HIDAPI_DriverSteamDeck_CloseJoystick, + HIDAPI_DriverSteamDeck_FreeDevice, +}; + +#endif /* SDL_JOYSTICK_HIDAPI_STEAMDECK */ + +#endif /* SDL_JOYSTICK_HIDAPI */ diff --git a/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_switch.c b/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_switch.c new file mode 100644 index 0000000..45a2260 --- /dev/null +++ b/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_switch.c @@ -0,0 +1,2419 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ +/* This driver supports the Nintendo Switch Pro controller. + Code and logic contributed by Valve Corporation under the SDL zlib license. +*/ +#include "../../SDL_internal.h" + +#ifdef SDL_JOYSTICK_HIDAPI + +#include "SDL_events.h" +#include "SDL_timer.h" +#include "SDL_joystick.h" +#include "SDL_gamecontroller.h" +#include "../../SDL_hints_c.h" +#include "../SDL_sysjoystick.h" +#include "SDL_hidapijoystick_c.h" +#include "SDL_hidapi_rumble.h" +#include "SDL_hidapi_nintendo.h" + +#ifdef SDL_JOYSTICK_HIDAPI_SWITCH + +/* Define this if you want to log all packets from the controller */ +/*#define DEBUG_SWITCH_PROTOCOL*/ + +/* Define this to get log output for rumble logic */ +/*#define DEBUG_RUMBLE*/ + +/* The initialization sequence doesn't appear to work correctly on Windows unless + the reads and writes are on the same thread. + + ... and now I can't reproduce this, so I'm leaving it in, but disabled for now. + */ +/*#define SWITCH_SYNCHRONOUS_WRITES*/ + +/* How often you can write rumble commands to the controller. + If you send commands more frequently than this, you can turn off the controller + in Bluetooth mode, or the motors can miss the command in USB mode. + */ +#define RUMBLE_WRITE_FREQUENCY_MS 30 + +/* How often you have to refresh a long duration rumble to keep the motors running */ +#define RUMBLE_REFRESH_FREQUENCY_MS 50 + +#define SWITCH_GYRO_SCALE 14.2842f +#define SWITCH_ACCEL_SCALE 4096.f + +#define SWITCH_GYRO_SCALE_OFFSET 13371.0f +#define SWITCH_GYRO_SCALE_MULT 936.0f +#define SWITCH_ACCEL_SCALE_OFFSET 16384.0f +#define SWITCH_ACCEL_SCALE_MULT 4.0f + +typedef enum +{ + k_eSwitchInputReportIDs_SubcommandReply = 0x21, + k_eSwitchInputReportIDs_FullControllerState = 0x30, + k_eSwitchInputReportIDs_FullControllerAndMcuState = 0x31, + k_eSwitchInputReportIDs_SimpleControllerState = 0x3F, + k_eSwitchInputReportIDs_CommandAck = 0x81, +} ESwitchInputReportIDs; + +typedef enum +{ + k_eSwitchOutputReportIDs_RumbleAndSubcommand = 0x01, + k_eSwitchOutputReportIDs_Rumble = 0x10, + k_eSwitchOutputReportIDs_Proprietary = 0x80, +} ESwitchOutputReportIDs; + +typedef enum +{ + k_eSwitchSubcommandIDs_BluetoothManualPair = 0x01, + k_eSwitchSubcommandIDs_RequestDeviceInfo = 0x02, + k_eSwitchSubcommandIDs_SetInputReportMode = 0x03, + k_eSwitchSubcommandIDs_SetHCIState = 0x06, + k_eSwitchSubcommandIDs_SPIFlashRead = 0x10, + k_eSwitchSubcommandIDs_SetPlayerLights = 0x30, + k_eSwitchSubcommandIDs_SetHomeLight = 0x38, + k_eSwitchSubcommandIDs_EnableIMU = 0x40, + k_eSwitchSubcommandIDs_SetIMUSensitivity = 0x41, + k_eSwitchSubcommandIDs_EnableVibration = 0x48, +} ESwitchSubcommandIDs; + +typedef enum +{ + k_eSwitchProprietaryCommandIDs_Status = 0x01, + k_eSwitchProprietaryCommandIDs_Handshake = 0x02, + k_eSwitchProprietaryCommandIDs_HighSpeed = 0x03, + k_eSwitchProprietaryCommandIDs_ForceUSB = 0x04, + k_eSwitchProprietaryCommandIDs_ClearUSB = 0x05, + k_eSwitchProprietaryCommandIDs_ResetMCU = 0x06, +} ESwitchProprietaryCommandIDs; + +#define k_unSwitchOutputPacketDataLength 49 +#define k_unSwitchMaxOutputPacketLength 64 +#define k_unSwitchBluetoothPacketLength k_unSwitchOutputPacketDataLength +#define k_unSwitchUSBPacketLength k_unSwitchMaxOutputPacketLength + +#define k_unSPIStickFactoryCalibrationStartOffset 0x603D +#define k_unSPIStickFactoryCalibrationEndOffset 0x604E +#define k_unSPIStickFactoryCalibrationLength (k_unSPIStickFactoryCalibrationEndOffset - k_unSPIStickFactoryCalibrationStartOffset + 1) + +#define k_unSPIStickUserCalibrationStartOffset 0x8010 +#define k_unSPIStickUserCalibrationEndOffset 0x8025 +#define k_unSPIStickUserCalibrationLength (k_unSPIStickUserCalibrationEndOffset - k_unSPIStickUserCalibrationStartOffset + 1) + +#define k_unSPIIMUScaleStartOffset 0x6020 +#define k_unSPIIMUScaleEndOffset 0x6037 +#define k_unSPIIMUScaleLength (k_unSPIIMUScaleEndOffset - k_unSPIIMUScaleStartOffset + 1) + +#define k_unSPIIMUUserScaleStartOffset 0x8026 +#define k_unSPIIMUUserScaleEndOffset 0x8039 +#define k_unSPIIMUUserScaleLength (k_unSPIIMUUserScaleEndOffset - k_unSPIIMUUserScaleStartOffset + 1) + +#pragma pack(1) +typedef struct +{ + Uint8 rgucButtons[2]; + Uint8 ucStickHat; + Uint8 rgucJoystickLeft[2]; + Uint8 rgucJoystickRight[2]; +} SwitchInputOnlyControllerStatePacket_t; + +typedef struct +{ + Uint8 rgucButtons[2]; + Uint8 ucStickHat; + Sint16 sJoystickLeft[2]; + Sint16 sJoystickRight[2]; +} SwitchSimpleStatePacket_t; + +typedef struct +{ + Uint8 ucCounter; + Uint8 ucBatteryAndConnection; + Uint8 rgucButtons[3]; + Uint8 rgucJoystickLeft[3]; + Uint8 rgucJoystickRight[3]; + Uint8 ucVibrationCode; +} SwitchControllerStatePacket_t; + +typedef struct +{ + SwitchControllerStatePacket_t controllerState; + + struct + { + Sint16 sAccelX; + Sint16 sAccelY; + Sint16 sAccelZ; + + Sint16 sGyroX; + Sint16 sGyroY; + Sint16 sGyroZ; + } imuState[3]; +} SwitchStatePacket_t; + +typedef struct +{ + Uint32 unAddress; + Uint8 ucLength; +} SwitchSPIOpData_t; + +typedef struct +{ + SwitchControllerStatePacket_t m_controllerState; + + Uint8 ucSubcommandAck; + Uint8 ucSubcommandID; + +#define k_unSubcommandDataBytes 35 + union + { + Uint8 rgucSubcommandData[k_unSubcommandDataBytes]; + + struct + { + SwitchSPIOpData_t opData; + Uint8 rgucReadData[k_unSubcommandDataBytes - sizeof(SwitchSPIOpData_t)]; + } spiReadData; + + struct + { + Uint8 rgucFirmwareVersion[2]; + Uint8 ucDeviceType; + Uint8 ucFiller1; + Uint8 rgucMACAddress[6]; + Uint8 ucFiller2; + Uint8 ucColorLocation; + } deviceInfo; + + struct + { + SwitchSPIOpData_t opData; + Uint8 rgucLeftCalibration[9]; + Uint8 rgucRightCalibration[9]; + } stickFactoryCalibration; + + struct + { + SwitchSPIOpData_t opData; + Uint8 rgucLeftMagic[2]; + Uint8 rgucLeftCalibration[9]; + Uint8 rgucRightMagic[2]; + Uint8 rgucRightCalibration[9]; + } stickUserCalibration; + }; +} SwitchSubcommandInputPacket_t; + +typedef struct +{ + Uint8 ucPacketType; + Uint8 ucCommandID; + Uint8 ucFiller; + + Uint8 ucDeviceType; + Uint8 rgucMACAddress[6]; +} SwitchProprietaryStatusPacket_t; + +typedef struct +{ + Uint8 rgucData[4]; +} SwitchRumbleData_t; + +typedef struct +{ + Uint8 ucPacketType; + Uint8 ucPacketNumber; + SwitchRumbleData_t rumbleData[2]; +} SwitchCommonOutputPacket_t; + +typedef struct +{ + SwitchCommonOutputPacket_t commonData; + + Uint8 ucSubcommandID; + Uint8 rgucSubcommandData[k_unSwitchOutputPacketDataLength - sizeof(SwitchCommonOutputPacket_t) - 1]; +} SwitchSubcommandOutputPacket_t; + +typedef struct +{ + Uint8 ucPacketType; + Uint8 ucProprietaryID; + + Uint8 rgucProprietaryData[k_unSwitchOutputPacketDataLength - 1 - 1]; +} SwitchProprietaryOutputPacket_t; +#pragma pack() + +typedef struct +{ + SDL_HIDAPI_Device *device; + SDL_Joystick *joystick; + SDL_bool m_bInputOnly; + SDL_bool m_bIsGameCube; + SDL_bool m_bUseButtonLabels; + SDL_bool m_bPlayerLights; + int m_nPlayerIndex; + SDL_bool m_bSyncWrite; + int m_nMaxWriteAttempts; + ESwitchDeviceInfoControllerType m_eControllerType; + Uint8 m_nInitialInputMode; + Uint8 m_nCurrentInputMode; + Uint8 m_rgucMACAddress[6]; + Uint8 m_nCommandNumber; + SwitchCommonOutputPacket_t m_RumblePacket; + Uint8 m_rgucReadBuffer[k_unSwitchMaxOutputPacketLength]; + SDL_bool m_bRumbleActive; + Uint32 m_unRumbleSent; + SDL_bool m_bRumblePending; + SDL_bool m_bRumbleZeroPending; + Uint32 m_unRumblePending; + SDL_bool m_bReportSensors; + SDL_bool m_bHasSensorData; + Uint32 m_unLastInput; + Uint32 m_unLastIMUReset; + Uint32 m_unIMUSampleTimestamp; + Uint32 m_unIMUSamples; + Uint32 m_unIMUUpdateIntervalUS; + Uint64 m_ulTimestampUS; + SDL_bool m_bVerticalMode; + + SwitchInputOnlyControllerStatePacket_t m_lastInputOnlyState; + SwitchSimpleStatePacket_t m_lastSimpleState; + SwitchStatePacket_t m_lastFullState; + + struct StickCalibrationData + { + struct + { + Sint16 sCenter; + Sint16 sMin; + Sint16 sMax; + } axis[2]; + } m_StickCalData[2]; + + struct StickExtents + { + struct + { + Sint16 sMin; + Sint16 sMax; + } axis[2]; + } m_StickExtents[2], m_SimpleStickExtents[2]; + + struct IMUScaleData + { + float fAccelScaleX; + float fAccelScaleY; + float fAccelScaleZ; + + float fGyroScaleX; + float fGyroScaleY; + float fGyroScaleZ; + } m_IMUScaleData; +} SDL_DriverSwitch_Context; + +static int ReadInput(SDL_DriverSwitch_Context *ctx) +{ + /* Make sure we don't try to read at the same time a write is happening */ + if (SDL_AtomicGet(&ctx->device->rumble_pending) > 0) { + return 0; + } + + return SDL_hid_read_timeout(ctx->device->dev, ctx->m_rgucReadBuffer, sizeof(ctx->m_rgucReadBuffer), 0); +} + +static int WriteOutput(SDL_DriverSwitch_Context *ctx, const Uint8 *data, int size) +{ +#ifdef SWITCH_SYNCHRONOUS_WRITES + return SDL_hid_write(ctx->device->dev, data, size); +#else + /* Use the rumble thread for general asynchronous writes */ + if (SDL_HIDAPI_LockRumble() != 0) { + return -1; + } + return SDL_HIDAPI_SendRumbleAndUnlock(ctx->device, data, size); +#endif /* SWITCH_SYNCHRONOUS_WRITES */ +} + +static SwitchSubcommandInputPacket_t *ReadSubcommandReply(SDL_DriverSwitch_Context *ctx, ESwitchSubcommandIDs expectedID) +{ + /* Average response time for messages is ~30ms */ + Uint32 TimeoutMs = 100; + Uint32 startTicks = SDL_GetTicks(); + + int nRead = 0; + while ((nRead = ReadInput(ctx)) != -1) { + if (nRead > 0) { + if (ctx->m_rgucReadBuffer[0] == k_eSwitchInputReportIDs_SubcommandReply) { + SwitchSubcommandInputPacket_t *reply = (SwitchSubcommandInputPacket_t *)&ctx->m_rgucReadBuffer[1]; + if (reply->ucSubcommandID == expectedID && (reply->ucSubcommandAck & 0x80)) { + return reply; + } + } + } else { + SDL_Delay(1); + } + + if (SDL_TICKS_PASSED(SDL_GetTicks(), startTicks + TimeoutMs)) { + break; + } + } + return NULL; +} + +static SDL_bool ReadProprietaryReply(SDL_DriverSwitch_Context *ctx, ESwitchProprietaryCommandIDs expectedID) +{ + /* Average response time for messages is ~30ms */ + Uint32 TimeoutMs = 100; + Uint32 startTicks = SDL_GetTicks(); + + int nRead = 0; + while ((nRead = ReadInput(ctx)) != -1) { + if (nRead > 0) { + if (ctx->m_rgucReadBuffer[0] == k_eSwitchInputReportIDs_CommandAck && ctx->m_rgucReadBuffer[1] == expectedID) { + return SDL_TRUE; + } + } else { + SDL_Delay(1); + } + + if (SDL_TICKS_PASSED(SDL_GetTicks(), startTicks + TimeoutMs)) { + break; + } + } + return SDL_FALSE; +} + +static void ConstructSubcommand(SDL_DriverSwitch_Context *ctx, ESwitchSubcommandIDs ucCommandID, Uint8 *pBuf, Uint8 ucLen, SwitchSubcommandOutputPacket_t *outPacket) +{ + SDL_memset(outPacket, 0, sizeof(*outPacket)); + + outPacket->commonData.ucPacketType = k_eSwitchOutputReportIDs_RumbleAndSubcommand; + outPacket->commonData.ucPacketNumber = ctx->m_nCommandNumber; + + SDL_memcpy(outPacket->commonData.rumbleData, ctx->m_RumblePacket.rumbleData, sizeof(ctx->m_RumblePacket.rumbleData)); + + outPacket->ucSubcommandID = ucCommandID; + if (pBuf) { + SDL_memcpy(outPacket->rgucSubcommandData, pBuf, ucLen); + } + + ctx->m_nCommandNumber = (ctx->m_nCommandNumber + 1) & 0xF; +} + +static SDL_bool WritePacket(SDL_DriverSwitch_Context *ctx, void *pBuf, Uint8 ucLen) +{ + Uint8 rgucBuf[k_unSwitchMaxOutputPacketLength]; + const size_t unWriteSize = ctx->device->is_bluetooth ? k_unSwitchBluetoothPacketLength : k_unSwitchUSBPacketLength; + + if (ucLen > k_unSwitchOutputPacketDataLength) { + return SDL_FALSE; + } + + if (ucLen < unWriteSize) { + SDL_memcpy(rgucBuf, pBuf, ucLen); + SDL_memset(rgucBuf + ucLen, 0, unWriteSize - ucLen); + pBuf = rgucBuf; + ucLen = (Uint8)unWriteSize; + } + if (ctx->m_bSyncWrite) { + return SDL_hid_write(ctx->device->dev, (Uint8 *)pBuf, ucLen) >= 0; + } else { + return WriteOutput(ctx, (Uint8 *)pBuf, ucLen) >= 0; + } +} + +static SDL_bool WriteSubcommand(SDL_DriverSwitch_Context *ctx, ESwitchSubcommandIDs ucCommandID, Uint8 *pBuf, Uint8 ucLen, SwitchSubcommandInputPacket_t **ppReply) +{ + SwitchSubcommandInputPacket_t *reply = NULL; + int nTries; + + for (nTries = 1; !reply && nTries <= ctx->m_nMaxWriteAttempts; ++nTries) { + SwitchSubcommandOutputPacket_t commandPacket; + ConstructSubcommand(ctx, ucCommandID, pBuf, ucLen, &commandPacket); + + if (!WritePacket(ctx, &commandPacket, sizeof(commandPacket))) { + continue; + } + + reply = ReadSubcommandReply(ctx, ucCommandID); + } + + if (ppReply) { + *ppReply = reply; + } + return reply != NULL; +} + +static SDL_bool WriteProprietary(SDL_DriverSwitch_Context *ctx, ESwitchProprietaryCommandIDs ucCommand, Uint8 *pBuf, Uint8 ucLen, SDL_bool waitForReply) +{ + int nTries; + + for (nTries = 1; nTries <= ctx->m_nMaxWriteAttempts; ++nTries) { + SwitchProprietaryOutputPacket_t packet; + + if ((!pBuf && ucLen > 0) || ucLen > sizeof(packet.rgucProprietaryData)) { + return SDL_FALSE; + } + + SDL_zero(packet); + packet.ucPacketType = k_eSwitchOutputReportIDs_Proprietary; + packet.ucProprietaryID = ucCommand; + if (pBuf) { + SDL_memcpy(packet.rgucProprietaryData, pBuf, ucLen); + } + + if (!WritePacket(ctx, &packet, sizeof(packet))) { + continue; + } + + if (!waitForReply || ReadProprietaryReply(ctx, ucCommand)) { + // SDL_Log("Succeeded%s after %d tries\n", ctx->m_bSyncWrite ? " (sync)" : "", nTries); + return SDL_TRUE; + } + } + // SDL_Log("Failed%s after %d tries\n", ctx->m_bSyncWrite ? " (sync)" : "", nTries); + return SDL_FALSE; +} + +static Uint8 EncodeRumbleHighAmplitude(Uint16 amplitude) +{ + /* More information about these values can be found here: + * https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering/blob/master/rumble_data_table.md + */ + Uint16 hfa[101][2] = { { 0, 0x0 }, { 514, 0x2 }, { 775, 0x4 }, { 921, 0x6 }, { 1096, 0x8 }, { 1303, 0x0a }, { 1550, 0x0c }, { 1843, 0x0e }, { 2192, 0x10 }, { 2606, 0x12 }, { 3100, 0x14 }, { 3686, 0x16 }, { 4383, 0x18 }, { 5213, 0x1a }, { 6199, 0x1c }, { 7372, 0x1e }, { 7698, 0x20 }, { 8039, 0x22 }, { 8395, 0x24 }, { 8767, 0x26 }, { 9155, 0x28 }, { 9560, 0x2a }, { 9984, 0x2c }, { 10426, 0x2e }, { 10887, 0x30 }, { 11369, 0x32 }, { 11873, 0x34 }, { 12398, 0x36 }, { 12947, 0x38 }, { 13520, 0x3a }, { 14119, 0x3c }, { 14744, 0x3e }, { 15067, 0x40 }, { 15397, 0x42 }, { 15734, 0x44 }, { 16079, 0x46 }, { 16431, 0x48 }, { 16790, 0x4a }, { 17158, 0x4c }, { 17534, 0x4e }, { 17918, 0x50 }, { 18310, 0x52 }, { 18711, 0x54 }, { 19121, 0x56 }, { 19540, 0x58 }, { 19967, 0x5a }, { 20405, 0x5c }, { 20851, 0x5e }, { 21308, 0x60 }, { 21775, 0x62 }, { 22251, 0x64 }, { 22739, 0x66 }, { 23236, 0x68 }, { 23745, 0x6a }, { 24265, 0x6c }, { 24797, 0x6e }, { 25340, 0x70 }, { 25894, 0x72 }, { 26462, 0x74 }, { 27041, 0x76 }, { 27633, 0x78 }, { 28238, 0x7a }, { 28856, 0x7c }, { 29488, 0x7e }, { 30134, 0x80 }, { 30794, 0x82 }, { 31468, 0x84 }, { 32157, 0x86 }, { 32861, 0x88 }, { 33581, 0x8a }, { 34316, 0x8c }, { 35068, 0x8e }, { 35836, 0x90 }, { 36620, 0x92 }, { 37422, 0x94 }, { 38242, 0x96 }, { 39079, 0x98 }, { 39935, 0x9a }, { 40809, 0x9c }, { 41703, 0x9e }, { 42616, 0xa0 }, { 43549, 0xa2 }, { 44503, 0xa4 }, { 45477, 0xa6 }, { 46473, 0xa8 }, { 47491, 0xaa }, { 48531, 0xac }, { 49593, 0xae }, { 50679, 0xb0 }, { 51789, 0xb2 }, { 52923, 0xb4 }, { 54082, 0xb6 }, { 55266, 0xb8 }, { 56476, 0xba }, { 57713, 0xbc }, { 58977, 0xbe }, { 60268, 0xc0 }, { 61588, 0xc2 }, { 62936, 0xc4 }, { 64315, 0xc6 }, { 65535, 0xc8 } }; + int index = 0; + for (; index < 101; index++) { + if (amplitude <= hfa[index][0]) { + return (Uint8)hfa[index][1]; + } + } + return (Uint8)hfa[100][1]; +} + +static Uint16 EncodeRumbleLowAmplitude(Uint16 amplitude) +{ + /* More information about these values can be found here: + * https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering/blob/master/rumble_data_table.md + */ + Uint16 lfa[101][2] = { { 0, 0x0040 }, { 514, 0x8040 }, { 775, 0x0041 }, { 921, 0x8041 }, { 1096, 0x0042 }, { 1303, 0x8042 }, { 1550, 0x0043 }, { 1843, 0x8043 }, { 2192, 0x0044 }, { 2606, 0x8044 }, { 3100, 0x0045 }, { 3686, 0x8045 }, { 4383, 0x0046 }, { 5213, 0x8046 }, { 6199, 0x0047 }, { 7372, 0x8047 }, { 7698, 0x0048 }, { 8039, 0x8048 }, { 8395, 0x0049 }, { 8767, 0x8049 }, { 9155, 0x004a }, { 9560, 0x804a }, { 9984, 0x004b }, { 10426, 0x804b }, { 10887, 0x004c }, { 11369, 0x804c }, { 11873, 0x004d }, { 12398, 0x804d }, { 12947, 0x004e }, { 13520, 0x804e }, { 14119, 0x004f }, { 14744, 0x804f }, { 15067, 0x0050 }, { 15397, 0x8050 }, { 15734, 0x0051 }, { 16079, 0x8051 }, { 16431, 0x0052 }, { 16790, 0x8052 }, { 17158, 0x0053 }, { 17534, 0x8053 }, { 17918, 0x0054 }, { 18310, 0x8054 }, { 18711, 0x0055 }, { 19121, 0x8055 }, { 19540, 0x0056 }, { 19967, 0x8056 }, { 20405, 0x0057 }, { 20851, 0x8057 }, { 21308, 0x0058 }, { 21775, 0x8058 }, { 22251, 0x0059 }, { 22739, 0x8059 }, { 23236, 0x005a }, { 23745, 0x805a }, { 24265, 0x005b }, { 24797, 0x805b }, { 25340, 0x005c }, { 25894, 0x805c }, { 26462, 0x005d }, { 27041, 0x805d }, { 27633, 0x005e }, { 28238, 0x805e }, { 28856, 0x005f }, { 29488, 0x805f }, { 30134, 0x0060 }, { 30794, 0x8060 }, { 31468, 0x0061 }, { 32157, 0x8061 }, { 32861, 0x0062 }, { 33581, 0x8062 }, { 34316, 0x0063 }, { 35068, 0x8063 }, { 35836, 0x0064 }, { 36620, 0x8064 }, { 37422, 0x0065 }, { 38242, 0x8065 }, { 39079, 0x0066 }, { 39935, 0x8066 }, { 40809, 0x0067 }, { 41703, 0x8067 }, { 42616, 0x0068 }, { 43549, 0x8068 }, { 44503, 0x0069 }, { 45477, 0x8069 }, { 46473, 0x006a }, { 47491, 0x806a }, { 48531, 0x006b }, { 49593, 0x806b }, { 50679, 0x006c }, { 51789, 0x806c }, { 52923, 0x006d }, { 54082, 0x806d }, { 55266, 0x006e }, { 56476, 0x806e }, { 57713, 0x006f }, { 58977, 0x806f }, { 60268, 0x0070 }, { 61588, 0x8070 }, { 62936, 0x0071 }, { 64315, 0x8071 }, { 65535, 0x0072 } }; + int index = 0; + for (; index < 101; index++) { + if (amplitude <= lfa[index][0]) { + return lfa[index][1]; + } + } + return lfa[100][1]; +} + +static void SetNeutralRumble(SwitchRumbleData_t *pRumble) +{ + pRumble->rgucData[0] = 0x00; + pRumble->rgucData[1] = 0x01; + pRumble->rgucData[2] = 0x40; + pRumble->rgucData[3] = 0x40; +} + +static void EncodeRumble(SwitchRumbleData_t *pRumble, Uint16 usHighFreq, Uint8 ucHighFreqAmp, Uint8 ucLowFreq, Uint16 usLowFreqAmp) +{ + if (ucHighFreqAmp > 0 || usLowFreqAmp > 0) { + // High-band frequency and low-band amplitude are actually nine-bits each so they + // take a bit from the high-band amplitude and low-band frequency bytes respectively + pRumble->rgucData[0] = usHighFreq & 0xFF; + pRumble->rgucData[1] = ucHighFreqAmp | ((usHighFreq >> 8) & 0x01); + + pRumble->rgucData[2] = ucLowFreq | ((usLowFreqAmp >> 8) & 0x80); + pRumble->rgucData[3] = usLowFreqAmp & 0xFF; + +#ifdef DEBUG_RUMBLE + SDL_Log("Freq: %.2X %.2X %.2X, Amp: %.2X %.2X %.2X\n", + usHighFreq & 0xFF, ((usHighFreq >> 8) & 0x01), ucLowFreq, + ucHighFreqAmp, ((usLowFreqAmp >> 8) & 0x80), usLowFreqAmp & 0xFF); +#endif + } else { + SetNeutralRumble(pRumble); + } +} + +static SDL_bool WriteRumble(SDL_DriverSwitch_Context *ctx) +{ + /* Write into m_RumblePacket rather than a temporary buffer to allow the current rumble state + * to be retained for subsequent rumble or subcommand packets sent to the controller + */ + ctx->m_RumblePacket.ucPacketType = k_eSwitchOutputReportIDs_Rumble; + ctx->m_RumblePacket.ucPacketNumber = ctx->m_nCommandNumber; + ctx->m_nCommandNumber = (ctx->m_nCommandNumber + 1) & 0xF; + + /* Refresh the rumble state periodically */ + ctx->m_unRumbleSent = SDL_GetTicks(); + + return WritePacket(ctx, (Uint8 *)&ctx->m_RumblePacket, sizeof(ctx->m_RumblePacket)); +} + +static ESwitchDeviceInfoControllerType CalculateControllerType(SDL_DriverSwitch_Context *ctx, ESwitchDeviceInfoControllerType eControllerType) +{ + SDL_HIDAPI_Device *device = ctx->device; + + /* The N64 controller reports as a Pro controller over USB */ + if (eControllerType == k_eSwitchDeviceInfoControllerType_ProController && + device->product_id == USB_PRODUCT_NINTENDO_N64_CONTROLLER) { + eControllerType = k_eSwitchDeviceInfoControllerType_N64; + } + + if (eControllerType == k_eSwitchDeviceInfoControllerType_Unknown) { + /* This might be a Joy-Con that's missing from a charging grip slot */ + if (device->product_id == USB_PRODUCT_NINTENDO_SWITCH_JOYCON_GRIP) { + if (device->interface_number == 1) { + eControllerType = k_eSwitchDeviceInfoControllerType_JoyConLeft; + } else { + eControllerType = k_eSwitchDeviceInfoControllerType_JoyConRight; + } + } + } + return eControllerType; +} + +static SDL_bool BReadDeviceInfo(SDL_DriverSwitch_Context *ctx) +{ + SwitchSubcommandInputPacket_t *reply = NULL; + + ctx->device->is_bluetooth = SDL_FALSE; + + if (WriteProprietary(ctx, k_eSwitchProprietaryCommandIDs_Status, NULL, 0, SDL_TRUE)) { + SwitchProprietaryStatusPacket_t *status = (SwitchProprietaryStatusPacket_t *)&ctx->m_rgucReadBuffer[0]; + size_t i; + + ctx->m_eControllerType = CalculateControllerType(ctx, (ESwitchDeviceInfoControllerType)status->ucDeviceType); + + for (i = 0; i < sizeof(ctx->m_rgucMACAddress); ++i) { + ctx->m_rgucMACAddress[i] = status->rgucMACAddress[sizeof(ctx->m_rgucMACAddress) - i - 1]; + } + + return SDL_TRUE; + } + + ctx->device->is_bluetooth = SDL_TRUE; + + if (WriteSubcommand(ctx, k_eSwitchSubcommandIDs_RequestDeviceInfo, NULL, 0, &reply)) { + // Byte 2: Controller ID (1=LJC, 2=RJC, 3=Pro) + ctx->m_eControllerType = CalculateControllerType(ctx, (ESwitchDeviceInfoControllerType)reply->deviceInfo.ucDeviceType); + + // Bytes 4-9: MAC address (big-endian) + SDL_memcpy(ctx->m_rgucMACAddress, reply->deviceInfo.rgucMACAddress, sizeof(ctx->m_rgucMACAddress)); + + return SDL_TRUE; + } + + return SDL_FALSE; +} + +static SDL_bool BTrySetupUSB(SDL_DriverSwitch_Context *ctx) +{ + /* We have to send a connection handshake to the controller when communicating over USB + * before we're able to send it other commands. Luckily this command is not supported + * over Bluetooth, so we can use the controller's lack of response as a way to + * determine if the connection is over USB or Bluetooth + */ + if (!WriteProprietary(ctx, k_eSwitchProprietaryCommandIDs_Handshake, NULL, 0, SDL_TRUE)) { + return SDL_FALSE; + } + if (!WriteProprietary(ctx, k_eSwitchProprietaryCommandIDs_HighSpeed, NULL, 0, SDL_TRUE)) { + /* The 8BitDo M30 and SF30 Pro don't respond to this command, but otherwise work correctly */ + /*return SDL_FALSE;*/ + } + if (!WriteProprietary(ctx, k_eSwitchProprietaryCommandIDs_Handshake, NULL, 0, SDL_TRUE)) { + /* This fails on the right Joy-Con when plugged into the charging grip */ + /*return SDL_FALSE;*/ + } + if (!WriteProprietary(ctx, k_eSwitchProprietaryCommandIDs_ForceUSB, NULL, 0, SDL_FALSE)) { + return SDL_FALSE; + } + return SDL_TRUE; +} + +static SDL_bool SetVibrationEnabled(SDL_DriverSwitch_Context *ctx, Uint8 enabled) +{ + return WriteSubcommand(ctx, k_eSwitchSubcommandIDs_EnableVibration, &enabled, sizeof(enabled), NULL); +} +static SDL_bool SetInputMode(SDL_DriverSwitch_Context *ctx, Uint8 input_mode) +{ + if (input_mode == ctx->m_nCurrentInputMode) { + return SDL_TRUE; + } else { + ctx->m_nCurrentInputMode = input_mode; + + return WriteSubcommand(ctx, k_eSwitchSubcommandIDs_SetInputReportMode, &input_mode, sizeof(input_mode), NULL); + } +} + +static SDL_bool SetHomeLED(SDL_DriverSwitch_Context *ctx, Uint8 brightness) +{ + Uint8 ucLedIntensity = 0; + Uint8 rgucBuffer[4]; + + if (brightness > 0) { + if (brightness < 65) { + ucLedIntensity = (brightness + 5) / 10; + } else { + ucLedIntensity = (Uint8)SDL_ceilf(0xF * SDL_powf((float)brightness / 100.f, 2.13f)); + } + } + + rgucBuffer[0] = (0x0 << 4) | 0x1; /* 0 mini cycles (besides first), cycle duration 8ms */ + rgucBuffer[1] = ((ucLedIntensity & 0xF) << 4) | 0x0; /* LED start intensity (0x0-0xF), 0 cycles (LED stays on at start intensity after first cycle) */ + rgucBuffer[2] = ((ucLedIntensity & 0xF) << 4) | 0x0; /* First cycle LED intensity, 0x0 intensity for second cycle */ + rgucBuffer[3] = (0x0 << 4) | 0x0; /* 8ms fade transition to first cycle, 8ms first cycle LED duration */ + + return WriteSubcommand(ctx, k_eSwitchSubcommandIDs_SetHomeLight, rgucBuffer, sizeof(rgucBuffer), NULL); +} + +static void SDLCALL SDL_HomeLEDHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + SDL_DriverSwitch_Context *ctx = (SDL_DriverSwitch_Context *)userdata; + + if (hint && *hint) { + int value; + + if (SDL_strchr(hint, '.') != NULL) { + value = (int)(100.0f * SDL_atof(hint)); + } else if (SDL_GetStringBoolean(hint, SDL_TRUE)) { + value = 100; + } else { + value = 0; + } + SetHomeLED(ctx, value); + } +} + +static void UpdateSlotLED(SDL_DriverSwitch_Context *ctx) +{ + if (!ctx->m_bInputOnly) { + Uint8 led_data = 0; + + if (ctx->m_bPlayerLights && ctx->m_nPlayerIndex >= 0) { + led_data = (1 << (ctx->m_nPlayerIndex % 4)); + } + WriteSubcommand(ctx, k_eSwitchSubcommandIDs_SetPlayerLights, &led_data, sizeof(led_data), NULL); + } +} + +static void SDLCALL SDL_PlayerLEDHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + SDL_DriverSwitch_Context *ctx = (SDL_DriverSwitch_Context *)userdata; + SDL_bool bPlayerLights = SDL_GetStringBoolean(hint, SDL_TRUE); + + if (bPlayerLights != ctx->m_bPlayerLights) { + ctx->m_bPlayerLights = bPlayerLights; + + UpdateSlotLED(ctx); + } +} + +static Uint8 GetInitialInputMode(SDL_DriverSwitch_Context *ctx) +{ + Uint8 input_mode = 0; + + if (ReadInput(ctx) > 0) { + input_mode = ctx->m_rgucReadBuffer[0]; + } + return input_mode; +} + +static Uint8 GetDefaultInputMode(SDL_DriverSwitch_Context *ctx) +{ + Uint8 input_mode; + + /* Determine the desired input mode */ + if (ctx->m_nInitialInputMode) { + input_mode = ctx->m_nInitialInputMode; + } else { + if (ctx->device->is_bluetooth) { + input_mode = k_eSwitchInputReportIDs_SimpleControllerState; + } else { + input_mode = k_eSwitchInputReportIDs_FullControllerState; + } + } + + /* The official Nintendo Switch Pro Controller supports FullControllerState over Bluetooth + * just fine. We really should use that, or else the epowerlevel code in HandleFullControllerState + * is completely pointless. We need full state if we want battery level and we only care about + * battery level over Bluetooth anyway. + */ + if (ctx->device->vendor_id == USB_VENDOR_NINTENDO) { + /* However, switching to full controller state breaks DirectInput, so let's not do that */ + #if 0 + input_mode = k_eSwitchInputReportIDs_FullControllerState; + #endif + + /* However, Joy-Con controllers switch their thumbsticks into D-pad mode in simple mode, + * so let's enable full controller state for them. + */ + if (ctx->device->product_id == USB_PRODUCT_NINTENDO_SWITCH_JOYCON_LEFT || + ctx->device->product_id == USB_PRODUCT_NINTENDO_SWITCH_JOYCON_RIGHT) { + input_mode = k_eSwitchInputReportIDs_FullControllerState; + } + } + return input_mode; +} + +static Uint8 GetSensorInputMode(SDL_DriverSwitch_Context *ctx) +{ + Uint8 input_mode; + + /* Determine the desired input mode */ + if (!ctx->m_nInitialInputMode || + ctx->m_nInitialInputMode == k_eSwitchInputReportIDs_SimpleControllerState) { + input_mode = k_eSwitchInputReportIDs_FullControllerState; + } else { + input_mode = ctx->m_nInitialInputMode; + } + return input_mode; +} + +static SDL_bool SetIMUEnabled(SDL_DriverSwitch_Context *ctx, SDL_bool enabled) +{ + Uint8 imu_data = enabled ? 1 : 0; + return WriteSubcommand(ctx, k_eSwitchSubcommandIDs_EnableIMU, &imu_data, sizeof(imu_data), NULL); +} + +static SDL_bool LoadStickCalibration(SDL_DriverSwitch_Context *ctx) +{ + Uint8 *pLeftStickCal; + Uint8 *pRightStickCal; + size_t stick, axis; + SwitchSubcommandInputPacket_t *user_reply = NULL; + SwitchSubcommandInputPacket_t *factory_reply = NULL; + SwitchSPIOpData_t readUserParams; + SwitchSPIOpData_t readFactoryParams; + + /* Read User Calibration Info */ + readUserParams.unAddress = k_unSPIStickUserCalibrationStartOffset; + readUserParams.ucLength = k_unSPIStickUserCalibrationLength; + + /* This isn't readable on all controllers, so ignore failure */ + WriteSubcommand(ctx, k_eSwitchSubcommandIDs_SPIFlashRead, (uint8_t *)&readUserParams, sizeof(readUserParams), &user_reply); + + /* Read Factory Calibration Info */ + readFactoryParams.unAddress = k_unSPIStickFactoryCalibrationStartOffset; + readFactoryParams.ucLength = k_unSPIStickFactoryCalibrationLength; + + if (!WriteSubcommand(ctx, k_eSwitchSubcommandIDs_SPIFlashRead, (uint8_t *)&readFactoryParams, sizeof(readFactoryParams), &factory_reply)) { + return SDL_FALSE; + } + + /* Automatically select the user calibration if magic bytes are set */ + if (user_reply && user_reply->stickUserCalibration.rgucLeftMagic[0] == 0xB2 && user_reply->stickUserCalibration.rgucLeftMagic[1] == 0xA1) { + pLeftStickCal = user_reply->stickUserCalibration.rgucLeftCalibration; + } else { + pLeftStickCal = factory_reply->stickFactoryCalibration.rgucLeftCalibration; + } + + if (user_reply && user_reply->stickUserCalibration.rgucRightMagic[0] == 0xB2 && user_reply->stickUserCalibration.rgucRightMagic[1] == 0xA1) { + pRightStickCal = user_reply->stickUserCalibration.rgucRightCalibration; + } else { + pRightStickCal = factory_reply->stickFactoryCalibration.rgucRightCalibration; + } + + /* Stick calibration values are 12-bits each and are packed by bit + * For whatever reason the fields are in a different order for each stick + * Left: X-Max, Y-Max, X-Center, Y-Center, X-Min, Y-Min + * Right: X-Center, Y-Center, X-Min, Y-Min, X-Max, Y-Max + */ + + /* Left stick */ + ctx->m_StickCalData[0].axis[0].sMax = ((pLeftStickCal[1] << 8) & 0xF00) | pLeftStickCal[0]; /* X Axis max above center */ + ctx->m_StickCalData[0].axis[1].sMax = (pLeftStickCal[2] << 4) | (pLeftStickCal[1] >> 4); /* Y Axis max above center */ + ctx->m_StickCalData[0].axis[0].sCenter = ((pLeftStickCal[4] << 8) & 0xF00) | pLeftStickCal[3]; /* X Axis center */ + ctx->m_StickCalData[0].axis[1].sCenter = (pLeftStickCal[5] << 4) | (pLeftStickCal[4] >> 4); /* Y Axis center */ + ctx->m_StickCalData[0].axis[0].sMin = ((pLeftStickCal[7] << 8) & 0xF00) | pLeftStickCal[6]; /* X Axis min below center */ + ctx->m_StickCalData[0].axis[1].sMin = (pLeftStickCal[8] << 4) | (pLeftStickCal[7] >> 4); /* Y Axis min below center */ + + /* Right stick */ + ctx->m_StickCalData[1].axis[0].sCenter = ((pRightStickCal[1] << 8) & 0xF00) | pRightStickCal[0]; /* X Axis center */ + ctx->m_StickCalData[1].axis[1].sCenter = (pRightStickCal[2] << 4) | (pRightStickCal[1] >> 4); /* Y Axis center */ + ctx->m_StickCalData[1].axis[0].sMin = ((pRightStickCal[4] << 8) & 0xF00) | pRightStickCal[3]; /* X Axis min below center */ + ctx->m_StickCalData[1].axis[1].sMin = (pRightStickCal[5] << 4) | (pRightStickCal[4] >> 4); /* Y Axis min below center */ + ctx->m_StickCalData[1].axis[0].sMax = ((pRightStickCal[7] << 8) & 0xF00) | pRightStickCal[6]; /* X Axis max above center */ + ctx->m_StickCalData[1].axis[1].sMax = (pRightStickCal[8] << 4) | (pRightStickCal[7] >> 4); /* Y Axis max above center */ + + /* Filter out any values that were uninitialized (0xFFF) in the SPI read */ + for (stick = 0; stick < 2; ++stick) { + for (axis = 0; axis < 2; ++axis) { + if (ctx->m_StickCalData[stick].axis[axis].sCenter == 0xFFF) { + ctx->m_StickCalData[stick].axis[axis].sCenter = 2048; + } + if (ctx->m_StickCalData[stick].axis[axis].sMax == 0xFFF) { + ctx->m_StickCalData[stick].axis[axis].sMax = (Sint16)(ctx->m_StickCalData[stick].axis[axis].sCenter * 0.7f); + } + if (ctx->m_StickCalData[stick].axis[axis].sMin == 0xFFF) { + ctx->m_StickCalData[stick].axis[axis].sMin = (Sint16)(ctx->m_StickCalData[stick].axis[axis].sCenter * 0.7f); + } + } + } + + for (stick = 0; stick < 2; ++stick) { + for (axis = 0; axis < 2; ++axis) { + ctx->m_StickExtents[stick].axis[axis].sMin = -(Sint16)(ctx->m_StickCalData[stick].axis[axis].sMin * 0.7f); + ctx->m_StickExtents[stick].axis[axis].sMax = (Sint16)(ctx->m_StickCalData[stick].axis[axis].sMax * 0.7f); + } + } + + for (stick = 0; stick < 2; ++stick) { + for (axis = 0; axis < 2; ++axis) { + ctx->m_SimpleStickExtents[stick].axis[axis].sMin = (Sint16)(SDL_MIN_SINT16 * 0.5f); + ctx->m_SimpleStickExtents[stick].axis[axis].sMax = (Sint16)(SDL_MAX_SINT16 * 0.5f); + } + } + + return SDL_TRUE; +} + +static SDL_bool LoadIMUCalibration(SDL_DriverSwitch_Context *ctx) +{ + SwitchSubcommandInputPacket_t *reply = NULL; + + /* Read Calibration Info */ + SwitchSPIOpData_t readParams; + readParams.unAddress = k_unSPIIMUScaleStartOffset; + readParams.ucLength = k_unSPIIMUScaleLength; + + if (WriteSubcommand(ctx, k_eSwitchSubcommandIDs_SPIFlashRead, (uint8_t *)&readParams, sizeof(readParams), &reply)) { + Uint8 *pIMUScale; + Sint16 sAccelRawX, sAccelRawY, sAccelRawZ, sGyroRawX, sGyroRawY, sGyroRawZ; + + /* IMU scale gives us multipliers for converting raw values to real world values */ + pIMUScale = reply->spiReadData.rgucReadData; + + sAccelRawX = (pIMUScale[1] << 8) | pIMUScale[0]; + sAccelRawY = (pIMUScale[3] << 8) | pIMUScale[2]; + sAccelRawZ = (pIMUScale[5] << 8) | pIMUScale[4]; + + sGyroRawX = (pIMUScale[13] << 8) | pIMUScale[12]; + sGyroRawY = (pIMUScale[15] << 8) | pIMUScale[14]; + sGyroRawZ = (pIMUScale[17] << 8) | pIMUScale[16]; + + /* Check for user calibration data. If it's present and set, it'll override the factory settings */ + readParams.unAddress = k_unSPIIMUUserScaleStartOffset; + readParams.ucLength = k_unSPIIMUUserScaleLength; + if (WriteSubcommand(ctx, k_eSwitchSubcommandIDs_SPIFlashRead, (uint8_t *)&readParams, sizeof(readParams), &reply) && (pIMUScale[0] | pIMUScale[1] << 8) == 0xA1B2) { + pIMUScale = reply->spiReadData.rgucReadData; + + sAccelRawX = (pIMUScale[3] << 8) | pIMUScale[2]; + sAccelRawY = (pIMUScale[5] << 8) | pIMUScale[4]; + sAccelRawZ = (pIMUScale[7] << 8) | pIMUScale[6]; + + sGyroRawX = (pIMUScale[15] << 8) | pIMUScale[14]; + sGyroRawY = (pIMUScale[17] << 8) | pIMUScale[16]; + sGyroRawZ = (pIMUScale[19] << 8) | pIMUScale[18]; + } + + /* Accelerometer scale */ + ctx->m_IMUScaleData.fAccelScaleX = SWITCH_ACCEL_SCALE_MULT / (SWITCH_ACCEL_SCALE_OFFSET - (float)sAccelRawX) * SDL_STANDARD_GRAVITY; + ctx->m_IMUScaleData.fAccelScaleY = SWITCH_ACCEL_SCALE_MULT / (SWITCH_ACCEL_SCALE_OFFSET - (float)sAccelRawY) * SDL_STANDARD_GRAVITY; + ctx->m_IMUScaleData.fAccelScaleZ = SWITCH_ACCEL_SCALE_MULT / (SWITCH_ACCEL_SCALE_OFFSET - (float)sAccelRawZ) * SDL_STANDARD_GRAVITY; + + /* Gyro scale */ + ctx->m_IMUScaleData.fGyroScaleX = SWITCH_GYRO_SCALE_MULT / (SWITCH_GYRO_SCALE_OFFSET - (float)sGyroRawX) * (float)M_PI / 180.0f; + ctx->m_IMUScaleData.fGyroScaleY = SWITCH_GYRO_SCALE_MULT / (SWITCH_GYRO_SCALE_OFFSET - (float)sGyroRawY) * (float)M_PI / 180.0f; + ctx->m_IMUScaleData.fGyroScaleZ = SWITCH_GYRO_SCALE_MULT / (SWITCH_GYRO_SCALE_OFFSET - (float)sGyroRawZ) * (float)M_PI / 180.0f; + + } else { + /* Use default values */ + const float accelScale = SDL_STANDARD_GRAVITY / SWITCH_ACCEL_SCALE; + const float gyroScale = (float)M_PI / 180.0f / SWITCH_GYRO_SCALE; + + ctx->m_IMUScaleData.fAccelScaleX = accelScale; + ctx->m_IMUScaleData.fAccelScaleY = accelScale; + ctx->m_IMUScaleData.fAccelScaleZ = accelScale; + + ctx->m_IMUScaleData.fGyroScaleX = gyroScale; + ctx->m_IMUScaleData.fGyroScaleY = gyroScale; + ctx->m_IMUScaleData.fGyroScaleZ = gyroScale; + } + return SDL_TRUE; +} + +static Sint16 ApplyStickCalibration(SDL_DriverSwitch_Context *ctx, int nStick, int nAxis, Sint16 sRawValue) +{ + sRawValue -= ctx->m_StickCalData[nStick].axis[nAxis].sCenter; + + if (sRawValue > ctx->m_StickExtents[nStick].axis[nAxis].sMax) { + ctx->m_StickExtents[nStick].axis[nAxis].sMax = sRawValue; + } + if (sRawValue < ctx->m_StickExtents[nStick].axis[nAxis].sMin) { + ctx->m_StickExtents[nStick].axis[nAxis].sMin = sRawValue; + } + + return (Sint16)HIDAPI_RemapVal(sRawValue, ctx->m_StickExtents[nStick].axis[nAxis].sMin, ctx->m_StickExtents[nStick].axis[nAxis].sMax, + SDL_MIN_SINT16, SDL_MAX_SINT16); +} + +static Sint16 ApplySimpleStickCalibration(SDL_DriverSwitch_Context *ctx, int nStick, int nAxis, Sint16 sRawValue) +{ + /* 0x8000 is the neutral value for all joystick axes */ + const Uint16 usJoystickCenter = 0x8000; + + sRawValue -= usJoystickCenter; + + if (sRawValue > ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMax) { + ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMax = sRawValue; + } + if (sRawValue < ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMin) { + ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMin = sRawValue; + } + + return (Sint16)HIDAPI_RemapVal(sRawValue, ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMin, ctx->m_SimpleStickExtents[nStick].axis[nAxis].sMax, + SDL_MIN_SINT16, SDL_MAX_SINT16); +} + +static void SDLCALL SDL_GameControllerButtonReportingHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + SDL_DriverSwitch_Context *ctx = (SDL_DriverSwitch_Context *)userdata; + ctx->m_bUseButtonLabels = SDL_GetStringBoolean(hint, SDL_TRUE); +} + +static Uint8 RemapButton(SDL_DriverSwitch_Context *ctx, Uint8 button) +{ + if (!ctx->m_bUseButtonLabels) { + /* Use button positions */ + if (ctx->m_bIsGameCube) { + switch (button) { + case SDL_CONTROLLER_BUTTON_B: + return SDL_CONTROLLER_BUTTON_X; + case SDL_CONTROLLER_BUTTON_X: + return SDL_CONTROLLER_BUTTON_B; + default: + break; + } + } else { + switch (button) { + case SDL_CONTROLLER_BUTTON_A: + return SDL_CONTROLLER_BUTTON_B; + case SDL_CONTROLLER_BUTTON_B: + return SDL_CONTROLLER_BUTTON_A; + case SDL_CONTROLLER_BUTTON_X: + return SDL_CONTROLLER_BUTTON_Y; + case SDL_CONTROLLER_BUTTON_Y: + return SDL_CONTROLLER_BUTTON_X; + default: + break; + } + } + } + return button; +} + +static int GetMaxWriteAttempts(SDL_HIDAPI_Device *device) +{ + if (device->vendor_id == USB_VENDOR_NINTENDO && + device->product_id == USB_PRODUCT_NINTENDO_SWITCH_JOYCON_GRIP) { + /* This device is a little slow and we know we're always on USB */ + return 20; + } else { + return 5; + } +} + +static ESwitchDeviceInfoControllerType ReadJoyConControllerType(SDL_HIDAPI_Device *device) +{ + ESwitchDeviceInfoControllerType eControllerType = k_eSwitchDeviceInfoControllerType_Unknown; + const int MAX_ATTEMPTS = 1; /* Don't try too long, in case this is a zombie Bluetooth controller */ + int attempts = 0; + + /* Create enough of a context to read the controller type from the device */ + SDL_DriverSwitch_Context *ctx = (SDL_DriverSwitch_Context *)SDL_calloc(1, sizeof(*ctx)); + if (ctx) { + ctx->device = device; + ctx->m_bSyncWrite = SDL_TRUE; + ctx->m_nMaxWriteAttempts = GetMaxWriteAttempts(device); + + for ( ; ; ) { + ++attempts; + device->is_bluetooth = SDL_FALSE; + if (WriteProprietary(ctx, k_eSwitchProprietaryCommandIDs_Status, NULL, 0, SDL_TRUE)) { + SwitchProprietaryStatusPacket_t *status = (SwitchProprietaryStatusPacket_t *)&ctx->m_rgucReadBuffer[0]; + + eControllerType = CalculateControllerType(ctx, (ESwitchDeviceInfoControllerType)status->ucDeviceType); + } else { + SwitchSubcommandInputPacket_t *reply = NULL; + + device->is_bluetooth = SDL_TRUE; + if (WriteSubcommand(ctx, k_eSwitchSubcommandIDs_RequestDeviceInfo, NULL, 0, &reply)) { + eControllerType = CalculateControllerType(ctx, (ESwitchDeviceInfoControllerType)reply->deviceInfo.ucDeviceType); + } + } + if (eControllerType == k_eSwitchDeviceInfoControllerType_Unknown && attempts < MAX_ATTEMPTS) { + /* Wait a bit and try again */ + SDL_Delay(100); + continue; + } + break; + } + SDL_free(ctx); + } + return eControllerType; +} + +static SDL_bool HasHomeLED(SDL_DriverSwitch_Context *ctx) +{ + Uint16 vendor_id = ctx->device->vendor_id; + Uint16 product_id = ctx->device->product_id; + + /* The Power A Nintendo Switch Pro controllers don't have a Home LED */ + if (vendor_id == 0 && product_id == 0) { + return SDL_FALSE; + } + + /* HORI Wireless Switch Pad */ + if (vendor_id == 0x0f0d && product_id == 0x00f6) { + return SDL_FALSE; + } + + /* Third party controllers don't have a home LED and will shut off if we try to set it */ + if (ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_Unknown || + ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_LicProController) { + return SDL_FALSE; + } + + /* The Nintendo Online classic controllers don't have a Home LED */ + if (vendor_id == USB_VENDOR_NINTENDO && + ctx->m_eControllerType > k_eSwitchDeviceInfoControllerType_ProController) { + return SDL_FALSE; + } + + return SDL_TRUE; +} + +static SDL_bool AlwaysUsesLabels(int vendor_id, int product_id, ESwitchDeviceInfoControllerType eControllerType) +{ + /* These controllers don't have a diamond button configuration, so always use labels */ + switch (eControllerType) { + case k_eSwitchDeviceInfoControllerType_HVCLeft: + case k_eSwitchDeviceInfoControllerType_HVCRight: + case k_eSwitchDeviceInfoControllerType_NESLeft: + case k_eSwitchDeviceInfoControllerType_NESRight: + case k_eSwitchDeviceInfoControllerType_N64: + case k_eSwitchDeviceInfoControllerType_SEGA_Genesis: + return SDL_TRUE; + default: + return SDL_FALSE; + } +} + +static SDL_bool IsGameCubeFormFactor(int vendor_id, int product_id) +{ + static Uint32 gamecube_formfactor[] = { + MAKE_VIDPID(0x0e6f, 0x0185), /* PDP Wired Fight Pad Pro for Nintendo Switch */ + MAKE_VIDPID(0x20d6, 0xa711), /* Core (Plus) Wired Controller */ + }; + Uint32 id = MAKE_VIDPID(vendor_id, product_id); + int i; + + for (i = 0; i < SDL_arraysize(gamecube_formfactor); ++i) { + if (id == gamecube_formfactor[i]) { + return SDL_TRUE; + } + } + return SDL_FALSE; +} + +static void HIDAPI_DriverNintendoClassic_RegisterHints(SDL_HintCallback callback, void *userdata) +{ + SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_NINTENDO_CLASSIC, callback, userdata); +} + +static void HIDAPI_DriverNintendoClassic_UnregisterHints(SDL_HintCallback callback, void *userdata) +{ + SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_NINTENDO_CLASSIC, callback, userdata); +} + +static SDL_bool HIDAPI_DriverNintendoClassic_IsEnabled(void) +{ + return SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_NINTENDO_CLASSIC, SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI, SDL_HIDAPI_DEFAULT)); +} + +static SDL_bool HIDAPI_DriverNintendoClassic_IsSupportedDevice(SDL_HIDAPI_Device *device, const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol) +{ + if (vendor_id == USB_VENDOR_NINTENDO) { + if (product_id == USB_PRODUCT_NINTENDO_SWITCH_JOYCON_RIGHT) { + if (SDL_strncmp(name, "NES Controller", 14) == 0 || + SDL_strncmp(name, "HVC Controller", 14) == 0) { + return SDL_TRUE; + } + } + + if (product_id == USB_PRODUCT_NINTENDO_N64_CONTROLLER) { + return SDL_TRUE; + } + + if (product_id == USB_PRODUCT_NINTENDO_SEGA_GENESIS_CONTROLLER) { + return SDL_TRUE; + } + + if (product_id == USB_PRODUCT_NINTENDO_SNES_CONTROLLER) { + return SDL_TRUE; + } + } + + return SDL_FALSE; +} + +static void HIDAPI_DriverJoyCons_RegisterHints(SDL_HintCallback callback, void *userdata) +{ + SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, callback, userdata); +} + +static void HIDAPI_DriverJoyCons_UnregisterHints(SDL_HintCallback callback, void *userdata) +{ + SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, callback, userdata); +} + +static SDL_bool HIDAPI_DriverJoyCons_IsEnabled(void) +{ + return SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI, SDL_HIDAPI_DEFAULT)); +} + +static SDL_bool HIDAPI_DriverJoyCons_IsSupportedDevice(SDL_HIDAPI_Device *device, const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol) +{ + if (vendor_id == USB_VENDOR_NINTENDO) { + if (product_id == USB_PRODUCT_NINTENDO_SWITCH_PRO && device && device->dev) { + /* This might be a Kinvoca Joy-Con that reports VID/PID as a Switch Pro controller */ + ESwitchDeviceInfoControllerType eControllerType = ReadJoyConControllerType(device); + if (eControllerType == k_eSwitchDeviceInfoControllerType_JoyConLeft || + eControllerType == k_eSwitchDeviceInfoControllerType_JoyConRight) { + return SDL_TRUE; + } + } + + if (product_id == USB_PRODUCT_NINTENDO_SWITCH_JOYCON_LEFT || + product_id == USB_PRODUCT_NINTENDO_SWITCH_JOYCON_RIGHT || + product_id == USB_PRODUCT_NINTENDO_SWITCH_JOYCON_GRIP) { + return SDL_TRUE; + } + } + return SDL_FALSE; +} + +static void HIDAPI_DriverSwitch_RegisterHints(SDL_HintCallback callback, void *userdata) +{ + SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_SWITCH, callback, userdata); +} + +static void HIDAPI_DriverSwitch_UnregisterHints(SDL_HintCallback callback, void *userdata) +{ + SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_SWITCH, callback, userdata); +} + +static SDL_bool HIDAPI_DriverSwitch_IsEnabled(void) +{ + return SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_SWITCH, SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI, SDL_HIDAPI_DEFAULT)); +} + +static SDL_bool HIDAPI_DriverSwitch_IsSupportedDevice(SDL_HIDAPI_Device *device, const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol) +{ + /* The HORI Wireless Switch Pad enumerates as a HID device when connected via USB + with the same VID/PID as when connected over Bluetooth but doesn't actually + support communication over USB. The most reliable way to block this without allowing the + controller to continually attempt to reconnect is to filter it out by manufactuer/product string. + Note that the controller does have a different product string when connected over Bluetooth. + */ + if (SDL_strcmp(name, "HORI Wireless Switch Pad") == 0) { + return SDL_FALSE; + } + + /* If it's handled by another driver, it's not handled here */ + if (HIDAPI_DriverNintendoClassic_IsSupportedDevice(device, name, type, vendor_id, product_id, version, interface_number, interface_class, interface_subclass, interface_protocol) || + HIDAPI_DriverJoyCons_IsSupportedDevice(device, name, type, vendor_id, product_id, version, interface_number, interface_class, interface_subclass, interface_protocol)) { + return SDL_FALSE; + } + + return (type == SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO) ? SDL_TRUE : SDL_FALSE; +} + +static void UpdateDeviceIdentity(SDL_HIDAPI_Device *device) +{ + SDL_DriverSwitch_Context *ctx = (SDL_DriverSwitch_Context *)device->context; + char serial[18]; + + switch (ctx->m_eControllerType) { + case k_eSwitchDeviceInfoControllerType_JoyConLeft: + HIDAPI_SetDeviceName(device, "Nintendo Switch Joy-Con (L)"); + HIDAPI_SetDeviceProduct(device, USB_VENDOR_NINTENDO, USB_PRODUCT_NINTENDO_SWITCH_JOYCON_LEFT); + device->type = SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_LEFT; + break; + case k_eSwitchDeviceInfoControllerType_JoyConRight: + HIDAPI_SetDeviceName(device, "Nintendo Switch Joy-Con (R)"); + HIDAPI_SetDeviceProduct(device, USB_VENDOR_NINTENDO, USB_PRODUCT_NINTENDO_SWITCH_JOYCON_RIGHT); + device->type = SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT; + break; + case k_eSwitchDeviceInfoControllerType_ProController: + case k_eSwitchDeviceInfoControllerType_LicProController: + HIDAPI_SetDeviceName(device, "Nintendo Switch Pro Controller"); + HIDAPI_SetDeviceProduct(device, USB_VENDOR_NINTENDO, USB_PRODUCT_NINTENDO_SWITCH_PRO); + device->type = SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO; + break; + case k_eSwitchDeviceInfoControllerType_HVCLeft: + HIDAPI_SetDeviceName(device, "Nintendo HVC Controller (1)"); + device->type = SDL_CONTROLLER_TYPE_UNKNOWN; + break; + case k_eSwitchDeviceInfoControllerType_HVCRight: + HIDAPI_SetDeviceName(device, "Nintendo HVC Controller (2)"); + device->type = SDL_CONTROLLER_TYPE_UNKNOWN; + break; + case k_eSwitchDeviceInfoControllerType_NESLeft: + HIDAPI_SetDeviceName(device, "Nintendo NES Controller (L)"); + device->type = SDL_CONTROLLER_TYPE_UNKNOWN; + break; + case k_eSwitchDeviceInfoControllerType_NESRight: + HIDAPI_SetDeviceName(device, "Nintendo NES Controller (R)"); + device->type = SDL_CONTROLLER_TYPE_UNKNOWN; + break; + case k_eSwitchDeviceInfoControllerType_SNES: + HIDAPI_SetDeviceName(device, "Nintendo SNES Controller"); + HIDAPI_SetDeviceProduct(device, USB_VENDOR_NINTENDO, USB_PRODUCT_NINTENDO_SNES_CONTROLLER); + device->type = SDL_CONTROLLER_TYPE_UNKNOWN; + break; + case k_eSwitchDeviceInfoControllerType_N64: + HIDAPI_SetDeviceName(device, "Nintendo N64 Controller"); + HIDAPI_SetDeviceProduct(device, USB_VENDOR_NINTENDO, USB_PRODUCT_NINTENDO_N64_CONTROLLER); + device->type = SDL_CONTROLLER_TYPE_UNKNOWN; + break; + case k_eSwitchDeviceInfoControllerType_SEGA_Genesis: + HIDAPI_SetDeviceName(device, "Nintendo SEGA Genesis Controller"); + HIDAPI_SetDeviceProduct(device, USB_VENDOR_NINTENDO, USB_PRODUCT_NINTENDO_SEGA_GENESIS_CONTROLLER); + device->type = SDL_CONTROLLER_TYPE_UNKNOWN; + break; + case k_eSwitchDeviceInfoControllerType_Unknown: + /* We couldn't read the device info for this controller, might not be fully compliant */ + if (device->vendor_id == USB_VENDOR_NINTENDO) { + switch (device->product_id) { + case USB_PRODUCT_NINTENDO_SWITCH_JOYCON_LEFT: + ctx->m_eControllerType = k_eSwitchDeviceInfoControllerType_JoyConLeft; + HIDAPI_SetDeviceName(device, "Nintendo Switch Joy-Con (L)"); + device->type = SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_LEFT; + break; + case USB_PRODUCT_NINTENDO_SWITCH_JOYCON_RIGHT: + ctx->m_eControllerType = k_eSwitchDeviceInfoControllerType_JoyConRight; + HIDAPI_SetDeviceName(device, "Nintendo Switch Joy-Con (R)"); + device->type = SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT; + break; + case USB_PRODUCT_NINTENDO_SWITCH_PRO: + ctx->m_eControllerType = k_eSwitchDeviceInfoControllerType_ProController; + HIDAPI_SetDeviceName(device, "Nintendo Switch Pro Controller"); + device->type = SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO; + break; + default: + break; + } + } + return; + default: + device->type = SDL_CONTROLLER_TYPE_UNKNOWN; + break; + } + device->guid.data[15] = ctx->m_eControllerType; + + (void)SDL_snprintf(serial, sizeof(serial), "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x", + ctx->m_rgucMACAddress[0], + ctx->m_rgucMACAddress[1], + ctx->m_rgucMACAddress[2], + ctx->m_rgucMACAddress[3], + ctx->m_rgucMACAddress[4], + ctx->m_rgucMACAddress[5]); + HIDAPI_SetDeviceSerial(device, serial); +} + +static SDL_bool HIDAPI_DriverSwitch_InitDevice(SDL_HIDAPI_Device *device) +{ + SDL_DriverSwitch_Context *ctx; + + ctx = (SDL_DriverSwitch_Context *)SDL_calloc(1, sizeof(*ctx)); + if (!ctx) { + SDL_OutOfMemory(); + return SDL_FALSE; + } + ctx->device = device; + device->context = ctx; + + ctx->m_nMaxWriteAttempts = GetMaxWriteAttempts(device); + ctx->m_bSyncWrite = SDL_TRUE; + + if (IsGameCubeFormFactor(device->vendor_id, device->product_id)) { + /* This is a controller shaped like a GameCube controller, with a large central A button */ + ctx->m_bIsGameCube = SDL_TRUE; + } + + /* Find out whether or not we can send output reports */ + ctx->m_bInputOnly = SDL_IsJoystickNintendoSwitchProInputOnly(device->vendor_id, device->product_id); + if (!ctx->m_bInputOnly) { + /* Initialize rumble data, important for reading device info on the MOBAPAD M073 */ + SetNeutralRumble(&ctx->m_RumblePacket.rumbleData[0]); + SetNeutralRumble(&ctx->m_RumblePacket.rumbleData[1]); + + BReadDeviceInfo(ctx); + UpdateDeviceIdentity(device); + } + + /* Prefer the USB device over the Bluetooth device */ + if (device->is_bluetooth) { + if (HIDAPI_HasConnectedUSBDevice(device->serial)) { + return SDL_TRUE; + } + } else { + HIDAPI_DisconnectBluetoothDevice(device->serial); + } + return HIDAPI_JoystickConnected(device, NULL); +} + +static int HIDAPI_DriverSwitch_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id) +{ + return -1; +} + +static void HIDAPI_DriverSwitch_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index) +{ + SDL_DriverSwitch_Context *ctx = (SDL_DriverSwitch_Context *)device->context; + + if (!ctx->joystick) { + return; + } + + ctx->m_nPlayerIndex = player_index; + + UpdateSlotLED(ctx); +} + +static SDL_bool HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_DriverSwitch_Context *ctx = (SDL_DriverSwitch_Context *)device->context; + + SDL_AssertJoysticksLocked(); + + ctx->joystick = joystick; + + ctx->m_bSyncWrite = SDL_TRUE; + + if (!ctx->m_bInputOnly) { + ctx->m_nInitialInputMode = GetInitialInputMode(ctx); + ctx->m_nCurrentInputMode = ctx->m_nInitialInputMode; + + /* Initialize rumble data */ + SetNeutralRumble(&ctx->m_RumblePacket.rumbleData[0]); + SetNeutralRumble(&ctx->m_RumblePacket.rumbleData[1]); + + if (!device->is_bluetooth) { + if (!BTrySetupUSB(ctx)) { + SDL_SetError("Couldn't setup USB mode"); + return SDL_FALSE; + } + } + + if (!LoadStickCalibration(ctx)) { + SDL_SetError("Couldn't load stick calibration"); + return SDL_FALSE; + } + + if (ctx->m_eControllerType != k_eSwitchDeviceInfoControllerType_HVCLeft && + ctx->m_eControllerType != k_eSwitchDeviceInfoControllerType_HVCRight && + ctx->m_eControllerType != k_eSwitchDeviceInfoControllerType_NESLeft && + ctx->m_eControllerType != k_eSwitchDeviceInfoControllerType_NESRight && + ctx->m_eControllerType != k_eSwitchDeviceInfoControllerType_SNES && + ctx->m_eControllerType != k_eSwitchDeviceInfoControllerType_N64 && + ctx->m_eControllerType != k_eSwitchDeviceInfoControllerType_SEGA_Genesis) { + if (LoadIMUCalibration(ctx)) { + /* Use the right sensor in the combined Joy-Con pair */ + if (!device->parent || + ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConRight) { + SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, 200.0f); + SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, 200.0f); + } + if (device->parent && + ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConLeft) { + SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO_L, 200.0f); + SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL_L, 200.0f); + } + if (device->parent && + ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConRight) { + SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO_R, 200.0f); + SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL_R, 200.0f); + } + } + } + + if (!SetVibrationEnabled(ctx, 1)) { + SDL_SetError("Couldn't enable vibration"); + return SDL_FALSE; + } + + /* Set desired input mode */ + if (!SetInputMode(ctx, GetDefaultInputMode(ctx))) { + SDL_SetError("Couldn't set input mode"); + return SDL_FALSE; + } + + /* Start sending USB reports */ + if (!device->is_bluetooth) { + /* ForceUSB doesn't generate an ACK, so don't wait for a reply */ + if (!WriteProprietary(ctx, k_eSwitchProprietaryCommandIDs_ForceUSB, NULL, 0, SDL_FALSE)) { + SDL_SetError("Couldn't start USB reports"); + return SDL_FALSE; + } + } + + /* Set the LED state */ + if (HasHomeLED(ctx)) { + if (ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConLeft || + ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConRight) { + SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_JOYCON_HOME_LED, + SDL_HomeLEDHintChanged, ctx); + } else { + SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_SWITCH_HOME_LED, + SDL_HomeLEDHintChanged, ctx); + } + } + } + + if (AlwaysUsesLabels(device->vendor_id, device->product_id, ctx->m_eControllerType)) { + ctx->m_bUseButtonLabels = SDL_TRUE; + } else { + SDL_AddHintCallback(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS, + SDL_GameControllerButtonReportingHintChanged, ctx); + } + + /* Initialize player index (needed for setting LEDs) */ + ctx->m_nPlayerIndex = SDL_JoystickGetPlayerIndex(joystick); + ctx->m_bPlayerLights = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_SWITCH_PLAYER_LED, SDL_TRUE); + UpdateSlotLED(ctx); + + SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_SWITCH_PLAYER_LED, + SDL_PlayerLEDHintChanged, ctx); + + /* Initialize the joystick capabilities */ + joystick->nbuttons = 20; + joystick->naxes = SDL_CONTROLLER_AXIS_MAX; + joystick->epowerlevel = device->is_bluetooth ? SDL_JOYSTICK_POWER_UNKNOWN : SDL_JOYSTICK_POWER_WIRED; + + /* Set up for input */ + ctx->m_bSyncWrite = SDL_FALSE; + ctx->m_unLastIMUReset = ctx->m_unLastInput = SDL_GetTicks(); + ctx->m_unIMUUpdateIntervalUS = 5 * 1000; /* Start off at 5 ms update rate */ + + /* Set up for vertical mode */ + ctx->m_bVerticalMode = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_VERTICAL_JOY_CONS, SDL_FALSE); + + return SDL_TRUE; +} + +static int HIDAPI_DriverSwitch_ActuallyRumbleJoystick(SDL_DriverSwitch_Context *ctx, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ + /* Experimentally determined rumble values. These will only matter on some controllers as tested ones + * seem to disregard these and just use any non-zero rumble values as a binary flag for constant rumble + * + * More information about these values can be found here: + * https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering/blob/master/rumble_data_table.md + */ + const Uint16 k_usHighFreq = 0x0074; + const Uint8 k_ucHighFreqAmp = EncodeRumbleHighAmplitude(high_frequency_rumble); + const Uint8 k_ucLowFreq = 0x3D; + const Uint16 k_usLowFreqAmp = EncodeRumbleLowAmplitude(low_frequency_rumble); + + if (low_frequency_rumble || high_frequency_rumble) { + EncodeRumble(&ctx->m_RumblePacket.rumbleData[0], k_usHighFreq, k_ucHighFreqAmp, k_ucLowFreq, k_usLowFreqAmp); + EncodeRumble(&ctx->m_RumblePacket.rumbleData[1], k_usHighFreq, k_ucHighFreqAmp, k_ucLowFreq, k_usLowFreqAmp); + } else { + SetNeutralRumble(&ctx->m_RumblePacket.rumbleData[0]); + SetNeutralRumble(&ctx->m_RumblePacket.rumbleData[1]); + } + + ctx->m_bRumbleActive = (low_frequency_rumble || high_frequency_rumble) ? SDL_TRUE : SDL_FALSE; + + if (!WriteRumble(ctx)) { + return SDL_SetError("Couldn't send rumble packet"); + } + return 0; +} + +static int HIDAPI_DriverSwitch_SendPendingRumble(SDL_DriverSwitch_Context *ctx) +{ + if (!SDL_TICKS_PASSED(SDL_GetTicks(), ctx->m_unRumbleSent + RUMBLE_WRITE_FREQUENCY_MS)) { + return 0; + } + + if (ctx->m_bRumblePending) { + Uint16 low_frequency_rumble = (Uint16)(ctx->m_unRumblePending >> 16); + Uint16 high_frequency_rumble = (Uint16)ctx->m_unRumblePending; + +#ifdef DEBUG_RUMBLE + SDL_Log("Sent pending rumble %d/%d, %d ms after previous rumble\n", low_frequency_rumble, high_frequency_rumble, SDL_GetTicks() - ctx->m_unRumbleSent); +#endif + ctx->m_bRumblePending = SDL_FALSE; + ctx->m_unRumblePending = 0; + + return HIDAPI_DriverSwitch_ActuallyRumbleJoystick(ctx, low_frequency_rumble, high_frequency_rumble); + } + + if (ctx->m_bRumbleZeroPending) { + ctx->m_bRumbleZeroPending = SDL_FALSE; + +#ifdef DEBUG_RUMBLE + SDL_Log("Sent pending zero rumble, %d ms after previous rumble\n", SDL_GetTicks() - ctx->m_unRumbleSent); +#endif + return HIDAPI_DriverSwitch_ActuallyRumbleJoystick(ctx, 0, 0); + } + + return 0; +} + +static int HIDAPI_DriverSwitch_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ + SDL_DriverSwitch_Context *ctx = (SDL_DriverSwitch_Context *)device->context; + + if (ctx->m_bInputOnly) { + return SDL_Unsupported(); + } + + if (device->parent) { + if (ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConLeft) { + /* Just handle low frequency rumble */ + high_frequency_rumble = 0; + } else if (ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConRight) { + /* Just handle high frequency rumble */ + low_frequency_rumble = 0; + } + } + + if (ctx->m_bRumblePending) { + if (HIDAPI_DriverSwitch_SendPendingRumble(ctx) < 0) { + return -1; + } + } + + if (!SDL_TICKS_PASSED(SDL_GetTicks(), ctx->m_unRumbleSent + RUMBLE_WRITE_FREQUENCY_MS)) { + if (low_frequency_rumble || high_frequency_rumble) { + Uint32 unRumblePending = ((Uint32)low_frequency_rumble << 16) | high_frequency_rumble; + + /* Keep the highest rumble intensity in the given interval */ + if (unRumblePending > ctx->m_unRumblePending) { + ctx->m_unRumblePending = unRumblePending; + } + ctx->m_bRumblePending = SDL_TRUE; + ctx->m_bRumbleZeroPending = SDL_FALSE; + } else { + /* When rumble is complete, turn it off */ + ctx->m_bRumbleZeroPending = SDL_TRUE; + } + return 0; + } + +#ifdef DEBUG_RUMBLE + SDL_Log("Sent rumble %d/%d\n", low_frequency_rumble, high_frequency_rumble); +#endif + + return HIDAPI_DriverSwitch_ActuallyRumbleJoystick(ctx, low_frequency_rumble, high_frequency_rumble); +} + +static int HIDAPI_DriverSwitch_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) +{ + return SDL_Unsupported(); +} + +static Uint32 HIDAPI_DriverSwitch_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_DriverSwitch_Context *ctx = (SDL_DriverSwitch_Context *)device->context; + Uint32 result = 0; + + if (ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_ProController && !ctx->m_bInputOnly) { + /* Doesn't have an RGB LED, so don't return SDL_JOYCAP_LED here */ + result |= SDL_JOYCAP_RUMBLE; + } else if (ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConLeft || + ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConRight) { + result |= SDL_JOYCAP_RUMBLE; + } + return result; +} + +static int HIDAPI_DriverSwitch_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + return SDL_Unsupported(); +} + +static int HIDAPI_DriverSwitch_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + +static int HIDAPI_DriverSwitch_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled) +{ + SDL_DriverSwitch_Context *ctx = (SDL_DriverSwitch_Context *)device->context; + Uint8 input_mode; + + if (enabled) { + input_mode = GetSensorInputMode(ctx); + } else { + input_mode = GetDefaultInputMode(ctx); + } + SetInputMode(ctx, input_mode); + + SetIMUEnabled(ctx, enabled); + ctx->m_bReportSensors = enabled; + ctx->m_unIMUSamples = 0; + ctx->m_unIMUSampleTimestamp = SDL_GetTicks(); + + return 0; +} + +static void HandleInputOnlyControllerState(SDL_Joystick *joystick, SDL_DriverSwitch_Context *ctx, SwitchInputOnlyControllerStatePacket_t *packet) +{ + Sint16 axis; + + if (packet->rgucButtons[0] != ctx->m_lastInputOnlyState.rgucButtons[0]) { + Uint8 data = packet->rgucButtons[0]; + SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_A), (data & 0x04) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_B), (data & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_X), (data & 0x08) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_Y), (data & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED); + + axis = (data & 0x40) ? 32767 : -32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, axis); + + axis = (data & 0x80) ? 32767 : -32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, axis); + } + + if (packet->rgucButtons[1] != ctx->m_lastInputOnlyState.rgucButtons[1]) { + Uint8 data = packet->rgucButtons[1]; + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, (data & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (data & 0x04) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data & 0x08) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MISC1, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED); + } + + if (packet->ucStickHat != ctx->m_lastInputOnlyState.ucStickHat) { + SDL_bool dpad_up = SDL_FALSE; + SDL_bool dpad_down = SDL_FALSE; + SDL_bool dpad_left = SDL_FALSE; + SDL_bool dpad_right = SDL_FALSE; + + switch (packet->ucStickHat) { + case 0: + dpad_up = SDL_TRUE; + break; + case 1: + dpad_up = SDL_TRUE; + dpad_right = SDL_TRUE; + break; + case 2: + dpad_right = SDL_TRUE; + break; + case 3: + dpad_right = SDL_TRUE; + dpad_down = SDL_TRUE; + break; + case 4: + dpad_down = SDL_TRUE; + break; + case 5: + dpad_left = SDL_TRUE; + dpad_down = SDL_TRUE; + break; + case 6: + dpad_left = SDL_TRUE; + break; + case 7: + dpad_up = SDL_TRUE; + dpad_left = SDL_TRUE; + break; + default: + break; + } + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, dpad_down); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, dpad_up); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, dpad_right); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, dpad_left); + } + + if (packet->rgucJoystickLeft[0] != ctx->m_lastInputOnlyState.rgucJoystickLeft[0]) { + axis = (Sint16)HIDAPI_RemapVal(packet->rgucJoystickLeft[0], SDL_MIN_UINT8, SDL_MAX_UINT8, SDL_MIN_SINT16, SDL_MAX_SINT16); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis); + } + + if (packet->rgucJoystickLeft[1] != ctx->m_lastInputOnlyState.rgucJoystickLeft[1]) { + axis = (Sint16)HIDAPI_RemapVal(packet->rgucJoystickLeft[1], SDL_MIN_UINT8, SDL_MAX_UINT8, SDL_MIN_SINT16, SDL_MAX_SINT16); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, axis); + } + + if (packet->rgucJoystickRight[0] != ctx->m_lastInputOnlyState.rgucJoystickRight[0]) { + axis = (Sint16)HIDAPI_RemapVal(packet->rgucJoystickRight[0], SDL_MIN_UINT8, SDL_MAX_UINT8, SDL_MIN_SINT16, SDL_MAX_SINT16); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, axis); + } + + if (packet->rgucJoystickRight[1] != ctx->m_lastInputOnlyState.rgucJoystickRight[1]) { + axis = (Sint16)HIDAPI_RemapVal(packet->rgucJoystickRight[1], SDL_MIN_UINT8, SDL_MAX_UINT8, SDL_MIN_SINT16, SDL_MAX_SINT16); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis); + } + + ctx->m_lastInputOnlyState = *packet; +} + +static void HandleSimpleControllerState(SDL_Joystick *joystick, SDL_DriverSwitch_Context *ctx, SwitchSimpleStatePacket_t *packet) +{ + Sint16 axis; + + if (packet->rgucButtons[0] != ctx->m_lastSimpleState.rgucButtons[0]) { + Uint8 data = packet->rgucButtons[0]; + SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_A), (data & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_B), (data & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_X), (data & 0x08) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_Y), (data & 0x04) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED); + + axis = (data & 0x40) ? 32767 : -32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, axis); + + axis = (data & 0x80) ? 32767 : -32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, axis); + } + + if (packet->rgucButtons[1] != ctx->m_lastSimpleState.rgucButtons[1]) { + Uint8 data = packet->rgucButtons[1]; + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, (data & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (data & 0x04) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data & 0x08) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MISC1, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED); + } + + if (packet->ucStickHat != ctx->m_lastSimpleState.ucStickHat) { + SDL_bool dpad_up = SDL_FALSE; + SDL_bool dpad_down = SDL_FALSE; + SDL_bool dpad_left = SDL_FALSE; + SDL_bool dpad_right = SDL_FALSE; + + switch (packet->ucStickHat) { + case 0: + dpad_up = SDL_TRUE; + break; + case 1: + dpad_up = SDL_TRUE; + dpad_right = SDL_TRUE; + break; + case 2: + dpad_right = SDL_TRUE; + break; + case 3: + dpad_right = SDL_TRUE; + dpad_down = SDL_TRUE; + break; + case 4: + dpad_down = SDL_TRUE; + break; + case 5: + dpad_left = SDL_TRUE; + dpad_down = SDL_TRUE; + break; + case 6: + dpad_left = SDL_TRUE; + break; + case 7: + dpad_up = SDL_TRUE; + dpad_left = SDL_TRUE; + break; + default: + break; + } + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, dpad_down); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, dpad_up); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, dpad_right); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, dpad_left); + } + + axis = ApplySimpleStickCalibration(ctx, 0, 0, packet->sJoystickLeft[0]); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis); + + axis = ApplySimpleStickCalibration(ctx, 0, 1, packet->sJoystickLeft[1]); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, axis); + + axis = ApplySimpleStickCalibration(ctx, 1, 0, packet->sJoystickRight[0]); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, axis); + + axis = ApplySimpleStickCalibration(ctx, 1, 1, packet->sJoystickRight[1]); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis); + + ctx->m_lastSimpleState = *packet; +} + +static void SendSensorUpdate(SDL_Joystick *joystick, SDL_DriverSwitch_Context *ctx, SDL_SensorType type, Uint64 timestamp_us, const Sint16 *values) +{ + float data[3]; + + /* Note the order of components has been shuffled to match PlayStation controllers, + * since that's our de facto standard from already supporting those controllers, and + * users will want consistent axis mappings across devices. + */ + if (type == SDL_SENSOR_GYRO || type == SDL_SENSOR_GYRO_L || type == SDL_SENSOR_GYRO_R) { + data[0] = -(ctx->m_IMUScaleData.fGyroScaleY * (float)values[1]); + data[1] = ctx->m_IMUScaleData.fGyroScaleZ * (float)values[2]; + data[2] = -(ctx->m_IMUScaleData.fGyroScaleX * (float)values[0]); + } else { + data[0] = -(ctx->m_IMUScaleData.fAccelScaleY * (float)values[1]); + data[1] = ctx->m_IMUScaleData.fAccelScaleZ * (float)values[2]; + data[2] = -(ctx->m_IMUScaleData.fAccelScaleX * (float)values[0]); + } + + /* Right Joy-Con flips some axes, so let's flip them back for consistency */ + if (ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConRight) { + data[0] = -data[0]; + data[1] = -data[1]; + } + + if (ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConLeft && + !ctx->device->parent && !ctx->m_bVerticalMode) { + /* Mini-gamepad mode, swap some axes around */ + float tmp = data[2]; + data[2] = -data[0]; + data[0] = tmp; + } + + if (ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConRight && + !ctx->device->parent && !ctx->m_bVerticalMode) { + /* Mini-gamepad mode, swap some axes around */ + float tmp = data[2]; + data[2] = data[0]; + data[0] = -tmp; + } + + SDL_PrivateJoystickSensor(joystick, type, timestamp_us, data, 3); +} + +static void HandleCombinedControllerStateL(SDL_Joystick *joystick, SDL_DriverSwitch_Context *ctx, SwitchStatePacket_t *packet) +{ + Sint16 axis; + + if (packet->controllerState.rgucButtons[1] != ctx->m_lastFullState.controllerState.rgucButtons[1]) { + Uint8 data = packet->controllerState.rgucButtons[1]; + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (data & 0x08) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MISC1, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED); + } + + if (packet->controllerState.rgucButtons[2] != ctx->m_lastFullState.controllerState.rgucButtons[2]) { + Uint8 data = packet->controllerState.rgucButtons[2]; + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, (data & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, (data & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, (data & 0x04) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, (data & 0x08) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_PADDLE4, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_PADDLE2, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data & 0x40) ? SDL_PRESSED : SDL_RELEASED); + axis = (data & 0x80) ? 32767 : -32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, axis); + } + + axis = packet->controllerState.rgucJoystickLeft[0] | ((packet->controllerState.rgucJoystickLeft[1] & 0xF) << 8); + axis = ApplyStickCalibration(ctx, 0, 0, axis); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis); + + axis = ((packet->controllerState.rgucJoystickLeft[1] & 0xF0) >> 4) | (packet->controllerState.rgucJoystickLeft[2] << 4); + axis = ApplyStickCalibration(ctx, 0, 1, axis); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, ~axis); +} + +static void HandleMiniControllerStateL(SDL_Joystick *joystick, SDL_DriverSwitch_Context *ctx, SwitchStatePacket_t *packet) +{ + Sint16 axis; + + if (packet->controllerState.rgucButtons[1] != ctx->m_lastFullState.controllerState.rgucButtons[1]) { + Uint8 data = packet->controllerState.rgucButtons[1]; + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, (data & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (data & 0x08) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED); + } + + if (packet->controllerState.rgucButtons[2] != ctx->m_lastFullState.controllerState.rgucButtons[2]) { + Uint8 data = packet->controllerState.rgucButtons[2]; + SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_A), (data & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_Y), (data & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_X), (data & 0x04) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_B), (data & 0x08) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_PADDLE2, (data & 0x40) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_PADDLE4, (data & 0x80) ? SDL_PRESSED : SDL_RELEASED); + } + + axis = packet->controllerState.rgucJoystickLeft[0] | ((packet->controllerState.rgucJoystickLeft[1] & 0xF) << 8); + axis = ApplyStickCalibration(ctx, 0, 0, axis); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, ~axis); + + axis = ((packet->controllerState.rgucJoystickLeft[1] & 0xF0) >> 4) | (packet->controllerState.rgucJoystickLeft[2] << 4); + axis = ApplyStickCalibration(ctx, 0, 1, axis); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, ~axis); +} + +static void HandleCombinedControllerStateR(SDL_Joystick *joystick, SDL_DriverSwitch_Context *ctx, SwitchStatePacket_t *packet) +{ + Sint16 axis; + + if (packet->controllerState.rgucButtons[0] != ctx->m_lastFullState.controllerState.rgucButtons[0]) { + Uint8 data = packet->controllerState.rgucButtons[0]; + SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_A), (data & 0x08) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_B), (data & 0x04) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_X), (data & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_Y), (data & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_PADDLE1, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_PADDLE3, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data & 0x40) ? SDL_PRESSED : SDL_RELEASED); + axis = (data & 0x80) ? 32767 : -32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, axis); + } + + if (packet->controllerState.rgucButtons[1] != ctx->m_lastFullState.controllerState.rgucButtons[1]) { + Uint8 data = packet->controllerState.rgucButtons[1]; + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, (data & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data & 0x04) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED); + } + + axis = packet->controllerState.rgucJoystickRight[0] | ((packet->controllerState.rgucJoystickRight[1] & 0xF) << 8); + axis = ApplyStickCalibration(ctx, 1, 0, axis); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, axis); + + axis = ((packet->controllerState.rgucJoystickRight[1] & 0xF0) >> 4) | (packet->controllerState.rgucJoystickRight[2] << 4); + axis = ApplyStickCalibration(ctx, 1, 1, axis); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, ~axis); +} + +static void HandleMiniControllerStateR(SDL_Joystick *joystick, SDL_DriverSwitch_Context *ctx, SwitchStatePacket_t *packet) +{ + Sint16 axis; + + if (packet->controllerState.rgucButtons[0] != ctx->m_lastFullState.controllerState.rgucButtons[0]) { + Uint8 data = packet->controllerState.rgucButtons[0]; + SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_B), (data & 0x08) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_Y), (data & 0x04) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_A), (data & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_X), (data & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_PADDLE1, (data & 0x40) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_PADDLE3, (data & 0x80) ? SDL_PRESSED : SDL_RELEASED); + } + + if (packet->controllerState.rgucButtons[1] != ctx->m_lastFullState.controllerState.rgucButtons[1]) { + Uint8 data = packet->controllerState.rgucButtons[1]; + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, (data & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (data & 0x04) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED); + } + + axis = packet->controllerState.rgucJoystickRight[0] | ((packet->controllerState.rgucJoystickRight[1] & 0xF) << 8); + axis = ApplyStickCalibration(ctx, 1, 0, axis); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, axis); + + axis = ((packet->controllerState.rgucJoystickRight[1] & 0xF0) >> 4) | (packet->controllerState.rgucJoystickRight[2] << 4); + axis = ApplyStickCalibration(ctx, 1, 1, axis); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis); +} + +static void HandleFullControllerState(SDL_Joystick *joystick, SDL_DriverSwitch_Context *ctx, SwitchStatePacket_t *packet) SDL_NO_THREAD_SAFETY_ANALYSIS /* We unlock and lock the device lock to be able to change IMU state */ +{ + if (ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConLeft) { + if (ctx->device->parent || ctx->m_bVerticalMode) { + HandleCombinedControllerStateL(joystick, ctx, packet); + } else { + HandleMiniControllerStateL(joystick, ctx, packet); + } + } else if (ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConRight) { + if (ctx->device->parent || ctx->m_bVerticalMode) { + HandleCombinedControllerStateR(joystick, ctx, packet); + } else { + HandleMiniControllerStateR(joystick, ctx, packet); + } + } else { + Sint16 axis; + + if (packet->controllerState.rgucButtons[0] != ctx->m_lastFullState.controllerState.rgucButtons[0]) { + Uint8 data = packet->controllerState.rgucButtons[0]; + SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_A), (data & 0x08) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_B), (data & 0x04) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_X), (data & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, RemapButton(ctx, SDL_CONTROLLER_BUTTON_Y), (data & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data & 0x40) ? SDL_PRESSED : SDL_RELEASED); + axis = (data & 0x80) ? 32767 : -32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, axis); + } + + if (packet->controllerState.rgucButtons[1] != ctx->m_lastFullState.controllerState.rgucButtons[1]) { + Uint8 data = packet->controllerState.rgucButtons[1]; + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, (data & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data & 0x04) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (data & 0x08) ? SDL_PRESSED : SDL_RELEASED); + + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MISC1, (data & 0x20) ? SDL_PRESSED : SDL_RELEASED); + } + + if (packet->controllerState.rgucButtons[2] != ctx->m_lastFullState.controllerState.rgucButtons[2]) { + Uint8 data = packet->controllerState.rgucButtons[2]; + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, (data & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, (data & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, (data & 0x04) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, (data & 0x08) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data & 0x40) ? SDL_PRESSED : SDL_RELEASED); + axis = (data & 0x80) ? 32767 : -32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, axis); + } + + axis = packet->controllerState.rgucJoystickLeft[0] | ((packet->controllerState.rgucJoystickLeft[1] & 0xF) << 8); + axis = ApplyStickCalibration(ctx, 0, 0, axis); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis); + + axis = ((packet->controllerState.rgucJoystickLeft[1] & 0xF0) >> 4) | (packet->controllerState.rgucJoystickLeft[2] << 4); + axis = ApplyStickCalibration(ctx, 0, 1, axis); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, ~axis); + + axis = packet->controllerState.rgucJoystickRight[0] | ((packet->controllerState.rgucJoystickRight[1] & 0xF) << 8); + axis = ApplyStickCalibration(ctx, 1, 0, axis); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, axis); + + axis = ((packet->controllerState.rgucJoystickRight[1] & 0xF0) >> 4) | (packet->controllerState.rgucJoystickRight[2] << 4); + axis = ApplyStickCalibration(ctx, 1, 1, axis); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, ~axis); + } + + /* High nibble of battery/connection byte is battery level, low nibble is connection status + * LSB of connection nibble is USB/Switch connection status + */ + if (packet->controllerState.ucBatteryAndConnection & 0x1) { + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_WIRED); + } else { + /* LSB of the battery nibble is used to report charging. + * The battery level is reported from 0(empty)-8(full) + */ + int level = (packet->controllerState.ucBatteryAndConnection & 0xE0) >> 4; + if (level == 0) { + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_EMPTY); + } else if (level <= 2) { + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_LOW); + } else if (level <= 6) { + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_MEDIUM); + } else { + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_FULL); + } + } + + if (ctx->m_bReportSensors) { + SDL_bool bHasSensorData = (packet->imuState[0].sAccelZ != 0 || + packet->imuState[0].sAccelY != 0 || + packet->imuState[0].sAccelX != 0); + if (bHasSensorData) { + const Uint32 IMU_UPDATE_RATE_SAMPLE_FREQUENCY = 1000; + Uint64 timestamp[3]; + + ctx->m_bHasSensorData = SDL_TRUE; + + /* We got three IMU samples, calculate the IMU update rate and timestamps */ + ctx->m_unIMUSamples += 3; + if (ctx->m_unIMUSamples >= IMU_UPDATE_RATE_SAMPLE_FREQUENCY) { + Uint32 now = SDL_GetTicks(); + Uint32 elapsed = (now - ctx->m_unIMUSampleTimestamp); + + if (elapsed > 0) { + ctx->m_unIMUUpdateIntervalUS = (elapsed * 1000) / ctx->m_unIMUSamples; + } + ctx->m_unIMUSamples = 0; + ctx->m_unIMUSampleTimestamp = now; + } + + ctx->m_ulTimestampUS += ctx->m_unIMUUpdateIntervalUS; + timestamp[0] = ctx->m_ulTimestampUS; + ctx->m_ulTimestampUS += ctx->m_unIMUUpdateIntervalUS; + timestamp[1] = ctx->m_ulTimestampUS; + ctx->m_ulTimestampUS += ctx->m_unIMUUpdateIntervalUS; + timestamp[2] = ctx->m_ulTimestampUS; + + if (!ctx->device->parent || + ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConRight) { + SendSensorUpdate(joystick, ctx, SDL_SENSOR_GYRO, timestamp[0], &packet->imuState[2].sGyroX); + SendSensorUpdate(joystick, ctx, SDL_SENSOR_ACCEL, timestamp[0], &packet->imuState[2].sAccelX); + + SendSensorUpdate(joystick, ctx, SDL_SENSOR_GYRO, timestamp[1], &packet->imuState[1].sGyroX); + SendSensorUpdate(joystick, ctx, SDL_SENSOR_ACCEL, timestamp[1], &packet->imuState[1].sAccelX); + + SendSensorUpdate(joystick, ctx, SDL_SENSOR_GYRO, timestamp[2], &packet->imuState[0].sGyroX); + SendSensorUpdate(joystick, ctx, SDL_SENSOR_ACCEL, timestamp[2], &packet->imuState[0].sAccelX); + } + + if (ctx->device->parent && + ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConLeft) { + SendSensorUpdate(joystick, ctx, SDL_SENSOR_GYRO_L, timestamp[0], &packet->imuState[2].sGyroX); + SendSensorUpdate(joystick, ctx, SDL_SENSOR_ACCEL_L, timestamp[0], &packet->imuState[2].sAccelX); + + SendSensorUpdate(joystick, ctx, SDL_SENSOR_GYRO_L, timestamp[1], &packet->imuState[1].sGyroX); + SendSensorUpdate(joystick, ctx, SDL_SENSOR_ACCEL_L, timestamp[1], &packet->imuState[1].sAccelX); + + SendSensorUpdate(joystick, ctx, SDL_SENSOR_GYRO_L, timestamp[2], &packet->imuState[0].sGyroX); + SendSensorUpdate(joystick, ctx, SDL_SENSOR_ACCEL_L, timestamp[2], &packet->imuState[0].sAccelX); + } + if (ctx->device->parent && + ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConRight) { + SendSensorUpdate(joystick, ctx, SDL_SENSOR_GYRO_R, timestamp[0], &packet->imuState[2].sGyroX); + SendSensorUpdate(joystick, ctx, SDL_SENSOR_ACCEL_R, timestamp[0], &packet->imuState[2].sAccelX); + + SendSensorUpdate(joystick, ctx, SDL_SENSOR_GYRO_R, timestamp[1], &packet->imuState[1].sGyroX); + SendSensorUpdate(joystick, ctx, SDL_SENSOR_ACCEL_R, timestamp[1], &packet->imuState[1].sAccelX); + + SendSensorUpdate(joystick, ctx, SDL_SENSOR_GYRO_R, timestamp[2], &packet->imuState[0].sGyroX); + SendSensorUpdate(joystick, ctx, SDL_SENSOR_ACCEL_R, timestamp[2], &packet->imuState[0].sAccelX); + } + + } else if (ctx->m_bHasSensorData) { + /* Uh oh, someone turned off the IMU? */ + const Uint32 IMU_RESET_DELAY_MS = 3000; + Uint32 now = SDL_GetTicks(); + + if (SDL_TICKS_PASSED(now, ctx->m_unLastIMUReset + IMU_RESET_DELAY_MS)) { + SDL_HIDAPI_Device *device = ctx->device; + + if (device->updating) { + SDL_UnlockMutex(device->dev_lock); + } + + SetIMUEnabled(ctx, SDL_TRUE); + + if (device->updating) { + SDL_LockMutex(device->dev_lock); + } + ctx->m_unLastIMUReset = now; + } + + } else { + /* We have never gotten IMU data, probably not supported on this device */ + } + } + + ctx->m_lastFullState = *packet; +} + +static SDL_bool HIDAPI_DriverSwitch_UpdateDevice(SDL_HIDAPI_Device *device) +{ + SDL_DriverSwitch_Context *ctx = (SDL_DriverSwitch_Context *)device->context; + SDL_Joystick *joystick = NULL; + int size; + int packet_count = 0; + Uint32 now = SDL_GetTicks(); + + if (device->num_joysticks > 0) { + joystick = SDL_JoystickFromInstanceID(device->joysticks[0]); + } + + while ((size = ReadInput(ctx)) > 0) { +#ifdef DEBUG_SWITCH_PROTOCOL + HIDAPI_DumpPacket("Nintendo Switch packet: size = %d", ctx->m_rgucReadBuffer, size); +#endif + ++packet_count; + ctx->m_unLastInput = now; + + if (!joystick) { + continue; + } + + if (ctx->m_rgucReadBuffer[0] == k_eSwitchInputReportIDs_SubcommandReply) { + continue; + } + + if (ctx->m_bInputOnly) { + HandleInputOnlyControllerState(joystick, ctx, (SwitchInputOnlyControllerStatePacket_t *)&ctx->m_rgucReadBuffer[0]); + } else { + ctx->m_nCurrentInputMode = ctx->m_rgucReadBuffer[0]; + + switch (ctx->m_rgucReadBuffer[0]) { + case k_eSwitchInputReportIDs_SimpleControllerState: + HandleSimpleControllerState(joystick, ctx, (SwitchSimpleStatePacket_t *)&ctx->m_rgucReadBuffer[1]); + break; + case k_eSwitchInputReportIDs_FullControllerState: + case k_eSwitchInputReportIDs_FullControllerAndMcuState: + HandleFullControllerState(joystick, ctx, (SwitchStatePacket_t *)&ctx->m_rgucReadBuffer[1]); + break; + default: + break; + } + } + } + + if (joystick) { + if (packet_count == 0) { + if (!ctx->m_bInputOnly && !device->is_bluetooth && + ctx->device->product_id != USB_PRODUCT_NINTENDO_SWITCH_JOYCON_GRIP) { + const Uint32 INPUT_WAIT_TIMEOUT_MS = 100; + if (SDL_TICKS_PASSED(now, ctx->m_unLastInput + INPUT_WAIT_TIMEOUT_MS)) { + /* Steam may have put the controller back into non-reporting mode */ + SDL_bool wasSyncWrite = ctx->m_bSyncWrite; + + ctx->m_bSyncWrite = SDL_TRUE; + WriteProprietary(ctx, k_eSwitchProprietaryCommandIDs_ForceUSB, NULL, 0, SDL_FALSE); + ctx->m_bSyncWrite = wasSyncWrite; + } + } else if (device->is_bluetooth) { + const Uint32 INPUT_WAIT_TIMEOUT_MS = 3000; + if (SDL_TICKS_PASSED(now, ctx->m_unLastInput + INPUT_WAIT_TIMEOUT_MS)) { + /* Bluetooth may have disconnected, try reopening the controller */ + size = -1; + } + } + } + + if (ctx->m_bRumblePending || ctx->m_bRumbleZeroPending) { + HIDAPI_DriverSwitch_SendPendingRumble(ctx); + } else if (ctx->m_bRumbleActive && + SDL_TICKS_PASSED(now, ctx->m_unRumbleSent + RUMBLE_REFRESH_FREQUENCY_MS)) { +#ifdef DEBUG_RUMBLE + SDL_Log("Sent continuing rumble, %d ms after previous rumble\n", now - ctx->m_unRumbleSent); +#endif + WriteRumble(ctx); + } + } + + /* Reconnect the Bluetooth device once the USB device is gone */ + if (device->num_joysticks == 0 && device->is_bluetooth && packet_count > 0 && + !HIDAPI_HasConnectedUSBDevice(device->serial)) { + HIDAPI_JoystickConnected(device, NULL); + } + + if (size < 0 && device->num_joysticks > 0) { + /* Read error, device is disconnected */ + HIDAPI_JoystickDisconnected(device, device->joysticks[0]); + } + return size >= 0; +} + +static void HIDAPI_DriverSwitch_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_DriverSwitch_Context *ctx = (SDL_DriverSwitch_Context *)device->context; + + if (!ctx->m_bInputOnly) { + /* Restore simple input mode for other applications */ + if (!ctx->m_nInitialInputMode || + ctx->m_nInitialInputMode == k_eSwitchInputReportIDs_SimpleControllerState) { + SetInputMode(ctx, k_eSwitchInputReportIDs_SimpleControllerState); + } + } + + SDL_DelHintCallback(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS, + SDL_GameControllerButtonReportingHintChanged, ctx); + + if (ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConLeft || + ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConRight) { + SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_JOYCON_HOME_LED, + SDL_HomeLEDHintChanged, ctx); + } else { + SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_SWITCH_HOME_LED, + SDL_HomeLEDHintChanged, ctx); + } + + SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_SWITCH_PLAYER_LED, + SDL_PlayerLEDHintChanged, ctx); + + ctx->joystick = NULL; +} + +static void HIDAPI_DriverSwitch_FreeDevice(SDL_HIDAPI_Device *device) +{ +} + +SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverNintendoClassic = { + SDL_HINT_JOYSTICK_HIDAPI_NINTENDO_CLASSIC, + SDL_TRUE, + HIDAPI_DriverNintendoClassic_RegisterHints, + HIDAPI_DriverNintendoClassic_UnregisterHints, + HIDAPI_DriverNintendoClassic_IsEnabled, + HIDAPI_DriverNintendoClassic_IsSupportedDevice, + HIDAPI_DriverSwitch_InitDevice, + HIDAPI_DriverSwitch_GetDevicePlayerIndex, + HIDAPI_DriverSwitch_SetDevicePlayerIndex, + HIDAPI_DriverSwitch_UpdateDevice, + HIDAPI_DriverSwitch_OpenJoystick, + HIDAPI_DriverSwitch_RumbleJoystick, + HIDAPI_DriverSwitch_RumbleJoystickTriggers, + HIDAPI_DriverSwitch_GetJoystickCapabilities, + HIDAPI_DriverSwitch_SetJoystickLED, + HIDAPI_DriverSwitch_SendJoystickEffect, + HIDAPI_DriverSwitch_SetJoystickSensorsEnabled, + HIDAPI_DriverSwitch_CloseJoystick, + HIDAPI_DriverSwitch_FreeDevice, +}; + +SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverJoyCons = { + SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, + SDL_TRUE, + HIDAPI_DriverJoyCons_RegisterHints, + HIDAPI_DriverJoyCons_UnregisterHints, + HIDAPI_DriverJoyCons_IsEnabled, + HIDAPI_DriverJoyCons_IsSupportedDevice, + HIDAPI_DriverSwitch_InitDevice, + HIDAPI_DriverSwitch_GetDevicePlayerIndex, + HIDAPI_DriverSwitch_SetDevicePlayerIndex, + HIDAPI_DriverSwitch_UpdateDevice, + HIDAPI_DriverSwitch_OpenJoystick, + HIDAPI_DriverSwitch_RumbleJoystick, + HIDAPI_DriverSwitch_RumbleJoystickTriggers, + HIDAPI_DriverSwitch_GetJoystickCapabilities, + HIDAPI_DriverSwitch_SetJoystickLED, + HIDAPI_DriverSwitch_SendJoystickEffect, + HIDAPI_DriverSwitch_SetJoystickSensorsEnabled, + HIDAPI_DriverSwitch_CloseJoystick, + HIDAPI_DriverSwitch_FreeDevice, +}; + +SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSwitch = { + SDL_HINT_JOYSTICK_HIDAPI_SWITCH, + SDL_TRUE, + HIDAPI_DriverSwitch_RegisterHints, + HIDAPI_DriverSwitch_UnregisterHints, + HIDAPI_DriverSwitch_IsEnabled, + HIDAPI_DriverSwitch_IsSupportedDevice, + HIDAPI_DriverSwitch_InitDevice, + HIDAPI_DriverSwitch_GetDevicePlayerIndex, + HIDAPI_DriverSwitch_SetDevicePlayerIndex, + HIDAPI_DriverSwitch_UpdateDevice, + HIDAPI_DriverSwitch_OpenJoystick, + HIDAPI_DriverSwitch_RumbleJoystick, + HIDAPI_DriverSwitch_RumbleJoystickTriggers, + HIDAPI_DriverSwitch_GetJoystickCapabilities, + HIDAPI_DriverSwitch_SetJoystickLED, + HIDAPI_DriverSwitch_SendJoystickEffect, + HIDAPI_DriverSwitch_SetJoystickSensorsEnabled, + HIDAPI_DriverSwitch_CloseJoystick, + HIDAPI_DriverSwitch_FreeDevice, +}; + +#endif /* SDL_JOYSTICK_HIDAPI_SWITCH */ + +#endif /* SDL_JOYSTICK_HIDAPI */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_wii.c b/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_wii.c new file mode 100644 index 0000000..3b3d994 --- /dev/null +++ b/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_wii.c @@ -0,0 +1,1685 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_JOYSTICK_HIDAPI + +#include "SDL_hints.h" +#include "SDL_events.h" +#include "SDL_timer.h" +#include "SDL_joystick.h" +#include "SDL_gamecontroller.h" +#include "../../SDL_hints_c.h" +#include "../SDL_sysjoystick.h" +#include "SDL_hidapijoystick_c.h" +#include "SDL_hidapi_rumble.h" +#include "SDL_hidapi_nintendo.h" + +#ifdef SDL_JOYSTICK_HIDAPI_WII + +/* Define this if you want to log all packets from the controller */ +/*#define DEBUG_WII_PROTOCOL*/ + +#define ENABLE_CONTINUOUS_REPORTING SDL_TRUE + +#define INPUT_WAIT_TIMEOUT_MS (3 * 1000) +#define MOTION_PLUS_UPDATE_TIME_MS (8 * 1000) +#define STATUS_UPDATE_TIME_MS (15 * 60 * 1000) + +#define WII_EXTENSION_NONE 0x2E2E +#define WII_EXTENSION_UNINITIALIZED 0xFFFF +#define WII_EXTENSION_NUNCHUK 0x0000 +#define WII_EXTENSION_GAMEPAD 0x0101 +#define WII_EXTENSION_WIIUPRO 0x0120 +#define WII_EXTENSION_MOTIONPLUS_MASK 0xF0FF +#define WII_EXTENSION_MOTIONPLUS_ID 0x0005 + +#define WII_MOTIONPLUS_MODE_NONE 0x00 +#define WII_MOTIONPLUS_MODE_STANDARD 0x04 +#define WII_MOTIONPLUS_MODE_NUNCHUK 0x05 +#define WII_MOTIONPLUS_MODE_GAMEPAD 0x07 + +typedef enum +{ + k_eWiiInputReportIDs_Status = 0x20, + k_eWiiInputReportIDs_ReadMemory = 0x21, + k_eWiiInputReportIDs_Acknowledge = 0x22, + k_eWiiInputReportIDs_ButtonData0 = 0x30, + k_eWiiInputReportIDs_ButtonData1 = 0x31, + k_eWiiInputReportIDs_ButtonData2 = 0x32, + k_eWiiInputReportIDs_ButtonData3 = 0x33, + k_eWiiInputReportIDs_ButtonData4 = 0x34, + k_eWiiInputReportIDs_ButtonData5 = 0x35, + k_eWiiInputReportIDs_ButtonData6 = 0x36, + k_eWiiInputReportIDs_ButtonData7 = 0x37, + k_eWiiInputReportIDs_ButtonDataD = 0x3D, + k_eWiiInputReportIDs_ButtonDataE = 0x3E, + k_eWiiInputReportIDs_ButtonDataF = 0x3F, +} EWiiInputReportIDs; + +typedef enum +{ + k_eWiiOutputReportIDs_Rumble = 0x10, + k_eWiiOutputReportIDs_LEDs = 0x11, + k_eWiiOutputReportIDs_DataReportingMode = 0x12, + k_eWiiOutputReportIDs_IRCameraEnable = 0x13, + k_eWiiOutputReportIDs_SpeakerEnable = 0x14, + k_eWiiOutputReportIDs_StatusRequest = 0x15, + k_eWiiOutputReportIDs_WriteMemory = 0x16, + k_eWiiOutputReportIDs_ReadMemory = 0x17, + k_eWiiOutputReportIDs_SpeakerData = 0x18, + k_eWiiOutputReportIDs_SpeakerMute = 0x19, + k_eWiiOutputReportIDs_IRCameraEnable2 = 0x1a, +} EWiiOutputReportIDs; + +typedef enum +{ + k_eWiiPlayerLEDs_P1 = 0x10, + k_eWiiPlayerLEDs_P2 = 0x20, + k_eWiiPlayerLEDs_P3 = 0x40, + k_eWiiPlayerLEDs_P4 = 0x80, +} EWiiPlayerLEDs; + +typedef enum +{ + k_eWiiCommunicationState_None, /* No special communications happening */ + k_eWiiCommunicationState_CheckMotionPlusStage1, /* Sent standard extension identify request */ + k_eWiiCommunicationState_CheckMotionPlusStage2, /* Sent Motion Plus extension identify request */ +} EWiiCommunicationState; + +typedef enum +{ + k_eWiiButtons_A = SDL_CONTROLLER_BUTTON_MISC1, + k_eWiiButtons_B, + k_eWiiButtons_One, + k_eWiiButtons_Two, + k_eWiiButtons_Plus, + k_eWiiButtons_Minus, + k_eWiiButtons_Home, + k_eWiiButtons_DPad_Up, + k_eWiiButtons_DPad_Down, + k_eWiiButtons_DPad_Left, + k_eWiiButtons_DPad_Right, + k_eWiiButtons_Max +} EWiiButtons; + +#define k_unWiiPacketDataLength 22 + +typedef struct +{ + Uint8 rgucBaseButtons[2]; + Uint8 rgucAccelerometer[3]; + Uint8 rgucExtension[21]; + SDL_bool hasBaseButtons; + SDL_bool hasAccelerometer; + Uint8 ucNExtensionBytes; +} WiiButtonData; + +typedef struct +{ + SDL_HIDAPI_Device *device; + SDL_Joystick *joystick; + EWiiCommunicationState m_eCommState; + EWiiExtensionControllerType m_eExtensionControllerType; + SDL_bool m_bUseButtonLabels; + SDL_bool m_bPlayerLights; + int m_nPlayerIndex; + SDL_bool m_bRumbleActive; + SDL_bool m_bMotionPlusPresent; + Uint8 m_ucMotionPlusMode; + SDL_bool m_bReportSensors; + Uint8 m_rgucReadBuffer[k_unWiiPacketDataLength]; + Uint32 m_unLastInput; + Uint32 m_unLastStatus; + Uint32 m_unNextMotionPlusCheck; + SDL_bool m_bDisconnected; + + struct StickCalibrationData + { + Uint16 min; + Uint16 max; + Uint16 center; + Uint16 deadzone; + } m_StickCalibrationData[6]; +} SDL_DriverWii_Context; + +static void HIDAPI_DriverWii_RegisterHints(SDL_HintCallback callback, void *userdata) +{ + SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_WII, callback, userdata); +} + +static void HIDAPI_DriverWii_UnregisterHints(SDL_HintCallback callback, void *userdata) +{ + SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_WII, callback, userdata); +} + +static SDL_bool HIDAPI_DriverWii_IsEnabled(void) +{ +#if 1 /* This doesn't work with the dolphinbar, so don't enable by default right now */ + return SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_WII, SDL_FALSE); +#else + return SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_WII, + SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI, + SDL_HIDAPI_DEFAULT)); +#endif +} + +static SDL_bool HIDAPI_DriverWii_IsSupportedDevice(SDL_HIDAPI_Device *device, const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol) +{ + if (vendor_id == USB_VENDOR_NINTENDO && + (product_id == USB_PRODUCT_NINTENDO_WII_REMOTE || + product_id == USB_PRODUCT_NINTENDO_WII_REMOTE2)) { + return SDL_TRUE; + } + return SDL_FALSE; +} + +static int ReadInput(SDL_DriverWii_Context *ctx) +{ + int size; + + /* Make sure we don't try to read at the same time a write is happening */ + if (SDL_AtomicGet(&ctx->device->rumble_pending) > 0) { + return 0; + } + + size = SDL_hid_read_timeout(ctx->device->dev, ctx->m_rgucReadBuffer, sizeof(ctx->m_rgucReadBuffer), 0); +#ifdef DEBUG_WII_PROTOCOL + if (size > 0) { + HIDAPI_DumpPacket("Wii packet: size = %d", ctx->m_rgucReadBuffer, size); + } +#endif + return size; +} + +static SDL_bool WriteOutput(SDL_DriverWii_Context *ctx, const Uint8 *data, int size, SDL_bool sync) +{ +#ifdef DEBUG_WII_PROTOCOL + if (size > 0) { + HIDAPI_DumpPacket("Wii write packet: size = %d", data, size); + } +#endif + if (sync) { + return SDL_hid_write(ctx->device->dev, data, size) >= 0; + } else { + /* Use the rumble thread for general asynchronous writes */ + if (SDL_HIDAPI_LockRumble() != 0) { + return SDL_FALSE; + } + return SDL_HIDAPI_SendRumbleAndUnlock(ctx->device, data, size) >= 0; + } +} + +static SDL_bool ReadInputSync(SDL_DriverWii_Context *ctx, EWiiInputReportIDs expectedID, SDL_bool (*isMine)(const Uint8 *)) +{ + Uint32 TimeoutMs = 250; /* Seeing successful reads after about 200 ms */ + Uint32 startTicks = SDL_GetTicks(); + + int nRead = 0; + while ((nRead = ReadInput(ctx)) != -1) { + if (nRead > 0) { + if (ctx->m_rgucReadBuffer[0] == expectedID && (!isMine || isMine(ctx->m_rgucReadBuffer))) { + return SDL_TRUE; + } + } else { + if (SDL_TICKS_PASSED(SDL_GetTicks(), startTicks + TimeoutMs)) { + break; + } + SDL_Delay(1); + } + } + SDL_SetError("Read timed out"); + return SDL_FALSE; +} + +static SDL_bool IsWriteMemoryResponse(const Uint8 *data) +{ + return data[3] == k_eWiiOutputReportIDs_WriteMemory; +} + +static SDL_bool WriteRegister(SDL_DriverWii_Context *ctx, Uint32 address, const Uint8 *data, int size, SDL_bool sync) +{ + Uint8 writeRequest[k_unWiiPacketDataLength]; + + SDL_zeroa(writeRequest); + writeRequest[0] = k_eWiiOutputReportIDs_WriteMemory; + writeRequest[1] = 0x04 | ctx->m_bRumbleActive; + writeRequest[2] = (address >> 16) & 0xff; + writeRequest[3] = (address >> 8) & 0xff; + writeRequest[4] = address & 0xff; + writeRequest[5] = size; + SDL_assert(size > 0 && size <= 16); + SDL_memcpy(writeRequest + 6, data, size); + + if (!WriteOutput(ctx, writeRequest, sizeof(writeRequest), sync)) { + return SDL_FALSE; + } + if (sync) { + /* Wait for response */ + if (!ReadInputSync(ctx, k_eWiiInputReportIDs_Acknowledge, IsWriteMemoryResponse)) { + return SDL_FALSE; + } + if (ctx->m_rgucReadBuffer[4]) { + SDL_SetError("Write memory failed: %d", ctx->m_rgucReadBuffer[4]); + return SDL_FALSE; + } + } + return SDL_TRUE; +} + +static SDL_bool ReadRegister(SDL_DriverWii_Context *ctx, Uint32 address, int size, SDL_bool sync) +{ + Uint8 readRequest[7]; + + readRequest[0] = k_eWiiOutputReportIDs_ReadMemory; + readRequest[1] = 0x04 | ctx->m_bRumbleActive; + readRequest[2] = (address >> 16) & 0xff; + readRequest[3] = (address >> 8) & 0xff; + readRequest[4] = address & 0xff; + readRequest[5] = (size >> 8) & 0xff; + readRequest[6] = size & 0xff; + + SDL_assert(size > 0 && size <= 0xffff); + + if (!WriteOutput(ctx, readRequest, sizeof(readRequest), sync)) { + return SDL_FALSE; + } + if (sync) { + SDL_assert(size <= 16); /* Only waiting for one packet is supported right now */ + /* Wait for response */ + if (!ReadInputSync(ctx, k_eWiiInputReportIDs_ReadMemory, NULL)) { + return SDL_FALSE; + } + } + return SDL_TRUE; +} + +static SDL_bool SendExtensionIdentify(SDL_DriverWii_Context *ctx, SDL_bool sync) +{ + return ReadRegister(ctx, 0xA400FE, 2, sync); +} + +static SDL_bool ParseExtensionIdentifyResponse(SDL_DriverWii_Context *ctx, Uint16 *extension) +{ + int i; + + if (ctx->m_rgucReadBuffer[0] != k_eWiiInputReportIDs_ReadMemory) { + SDL_SetError("Unexpected extension response type"); + return SDL_FALSE; + } + + if (ctx->m_rgucReadBuffer[4] != 0x00 || ctx->m_rgucReadBuffer[5] != 0xFE) { + SDL_SetError("Unexpected extension response address"); + return SDL_FALSE; + } + + if (ctx->m_rgucReadBuffer[3] != 0x10) { + Uint8 error = (ctx->m_rgucReadBuffer[3] & 0xF); + + if (error == 7) { + /* The extension memory isn't mapped */ + *extension = WII_EXTENSION_NONE; + return SDL_TRUE; + } + + if (error) { + SDL_SetError("Failed to read extension type: %d", error); + } else { + SDL_SetError("Unexpected read length when reading extension type: %d", (ctx->m_rgucReadBuffer[3] >> 4) + 1); + } + return SDL_FALSE; + } + + *extension = 0; + for (i = 6; i < 8; i++) { + *extension = *extension << 8 | ctx->m_rgucReadBuffer[i]; + } + return SDL_TRUE; +} + +static EWiiExtensionControllerType GetExtensionType(Uint16 extension_id) +{ + switch (extension_id) { + case WII_EXTENSION_NONE: + return k_eWiiExtensionControllerType_None; + case WII_EXTENSION_NUNCHUK: + return k_eWiiExtensionControllerType_Nunchuk; + case WII_EXTENSION_GAMEPAD: + return k_eWiiExtensionControllerType_Gamepad; + case WII_EXTENSION_WIIUPRO: + return k_eWiiExtensionControllerType_WiiUPro; + default: + return k_eWiiExtensionControllerType_Unknown; + } +} + +static SDL_bool SendExtensionReset(SDL_DriverWii_Context *ctx, SDL_bool sync) +{ + SDL_bool result = SDL_TRUE; + { + Uint8 data = 0x55; + result = result && WriteRegister(ctx, 0xA400F0, &data, sizeof(data), sync); + } + /* This write will fail if there is no extension connected, that's fine */ + { + Uint8 data = 0x00; + (void)WriteRegister(ctx, 0xA400FB, &data, sizeof(data), sync); + } + return result; +} + +static SDL_bool GetMotionPlusState(SDL_DriverWii_Context *ctx, SDL_bool *connected, Uint8 *mode) +{ + Uint16 extension; + + if (connected) { + *connected = SDL_FALSE; + } + if (mode) { + *mode = 0; + } + + if (ctx->m_eExtensionControllerType == k_eWiiExtensionControllerType_WiiUPro) { + /* The Wii U Pro controller never has the Motion Plus extension */ + return SDL_TRUE; + } + + if (SendExtensionIdentify(ctx, SDL_TRUE) && + ParseExtensionIdentifyResponse(ctx, &extension)) { + if ((extension & WII_EXTENSION_MOTIONPLUS_MASK) == WII_EXTENSION_MOTIONPLUS_ID) { + /* Motion Plus is currently active */ + if (connected) { + *connected = SDL_TRUE; + } + if (mode) { + *mode = (extension >> 8); + } + return SDL_TRUE; + } + } + + if (ReadRegister(ctx, 0xA600FE, 2, SDL_TRUE) && + ParseExtensionIdentifyResponse(ctx, &extension)) { + if ((extension & WII_EXTENSION_MOTIONPLUS_MASK) == WII_EXTENSION_MOTIONPLUS_ID) { + /* Motion Plus is currently connected */ + if (connected) { + *connected = SDL_TRUE; + } + } + return SDL_TRUE; + } + + /* Failed to read the register or parse the response */ + return SDL_FALSE; +} + +static SDL_bool NeedsPeriodicMotionPlusCheck(SDL_DriverWii_Context *ctx, SDL_bool status_update) +{ + if (ctx->m_eExtensionControllerType == k_eWiiExtensionControllerType_WiiUPro) { + /* The Wii U Pro controller never has the Motion Plus extension */ + return SDL_FALSE; + } + + if (ctx->m_ucMotionPlusMode != WII_MOTIONPLUS_MODE_NONE && !status_update) { + /* We'll get a status update when Motion Plus is disconnected */ + return SDL_FALSE; + } + + return SDL_TRUE; +} + +static void SchedulePeriodicMotionPlusCheck(SDL_DriverWii_Context *ctx) +{ + ctx->m_unNextMotionPlusCheck = SDL_GetTicks() + MOTION_PLUS_UPDATE_TIME_MS; + if (!ctx->m_unNextMotionPlusCheck) { + ctx->m_unNextMotionPlusCheck = 1; + } +} + +static void CheckMotionPlusConnection(SDL_DriverWii_Context *ctx) +{ + SendExtensionIdentify(ctx, SDL_FALSE); + + ctx->m_eCommState = k_eWiiCommunicationState_CheckMotionPlusStage1; +} + +static void ActivateMotionPlusWithMode(SDL_DriverWii_Context *ctx, Uint8 mode) +{ +#if defined(__LINUX__) + /* Linux drivers maintain a lot of state around the Motion Plus + * extension, so don't mess with it here. + */ +#else + WriteRegister(ctx, 0xA600FE, &mode, sizeof(mode), SDL_TRUE); + + ctx->m_ucMotionPlusMode = mode; +#endif /* LINUX */ +} + +static void ActivateMotionPlus(SDL_DriverWii_Context *ctx) +{ + Uint8 mode = WII_MOTIONPLUS_MODE_STANDARD; + + /* Pick the pass-through mode based on the connected controller */ + if (ctx->m_eExtensionControllerType == k_eWiiExtensionControllerType_Nunchuk) { + mode = WII_MOTIONPLUS_MODE_NUNCHUK; + } else if (ctx->m_eExtensionControllerType == k_eWiiExtensionControllerType_Gamepad) { + mode = WII_MOTIONPLUS_MODE_GAMEPAD; + } + ActivateMotionPlusWithMode(ctx, mode); +} + +static void DeactivateMotionPlus(SDL_DriverWii_Context *ctx) +{ + Uint8 data = 0x55; + WriteRegister(ctx, 0xA400F0, &data, sizeof(data), SDL_TRUE); + + /* Wait for the deactivation status message */ + ReadInputSync(ctx, k_eWiiInputReportIDs_Status, NULL); + + ctx->m_ucMotionPlusMode = WII_MOTIONPLUS_MODE_NONE; +} + +static void UpdatePowerLevelWii(SDL_Joystick *joystick, Uint8 batteryLevelByte) +{ + if (batteryLevelByte > 178) { + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_FULL); + } else if (batteryLevelByte > 51) { + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_MEDIUM); + } else if (batteryLevelByte > 13) { + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_LOW); + } else { + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_EMPTY); + } +} + +static void UpdatePowerLevelWiiU(SDL_Joystick *joystick, Uint8 extensionBatteryByte) +{ + SDL_bool charging = extensionBatteryByte & 0x08 ? SDL_FALSE : SDL_TRUE; + SDL_bool pluggedIn = extensionBatteryByte & 0x04 ? SDL_FALSE : SDL_TRUE; + Uint8 batteryLevel = extensionBatteryByte >> 4; + + /* Not sure if all Wii U Pro controllers act like this, but on mine + * 4, 3, and 2 are held for about 20 hours each + * 1 is held for about 6 hours + * 0 is held for about 2 hours + * No value above 4 has been observed. + */ + if (pluggedIn && !charging) { + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_WIRED); + } else if (batteryLevel >= 4) { + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_FULL); + } else if (batteryLevel > 1) { + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_MEDIUM); + } else if (batteryLevel == 1) { + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_LOW); + } else { + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_EMPTY); + } +} + +static EWiiInputReportIDs GetButtonPacketType(SDL_DriverWii_Context *ctx) +{ + switch (ctx->m_eExtensionControllerType) { + case k_eWiiExtensionControllerType_WiiUPro: + return k_eWiiInputReportIDs_ButtonDataD; + case k_eWiiExtensionControllerType_Nunchuk: + case k_eWiiExtensionControllerType_Gamepad: + if (ctx->m_bReportSensors) { + return k_eWiiInputReportIDs_ButtonData5; + } else { + return k_eWiiInputReportIDs_ButtonData2; + } + default: + if (ctx->m_bReportSensors) { + return k_eWiiInputReportIDs_ButtonData5; + } else { + return k_eWiiInputReportIDs_ButtonData0; + } + } +} + +static SDL_bool RequestButtonPacketType(SDL_DriverWii_Context *ctx, EWiiInputReportIDs type) +{ + Uint8 data[3]; + Uint8 tt = ctx->m_bRumbleActive; + + /* Continuous reporting off, tt & 4 == 0 */ + if (ENABLE_CONTINUOUS_REPORTING) { + tt |= 4; + } + + data[0] = k_eWiiOutputReportIDs_DataReportingMode; + data[1] = tt; + data[2] = type; + return WriteOutput(ctx, data, sizeof(data), SDL_FALSE); +} + +static void ResetButtonPacketType(SDL_DriverWii_Context *ctx) +{ + RequestButtonPacketType(ctx, GetButtonPacketType(ctx)); +} + +static void InitStickCalibrationData(SDL_DriverWii_Context *ctx) +{ + int i; + switch (ctx->m_eExtensionControllerType) { + case k_eWiiExtensionControllerType_WiiUPro: + for (i = 0; i < 4; i++) { + ctx->m_StickCalibrationData[i].min = 1000; + ctx->m_StickCalibrationData[i].max = 3000; + ctx->m_StickCalibrationData[i].center = 0; + ctx->m_StickCalibrationData[i].deadzone = 100; + } + break; + case k_eWiiExtensionControllerType_Gamepad: + for (i = 0; i < 4; i++) { + ctx->m_StickCalibrationData[i].min = i < 2 ? 9 : 5; + ctx->m_StickCalibrationData[i].max = i < 2 ? 54 : 26; + ctx->m_StickCalibrationData[i].center = 0; + ctx->m_StickCalibrationData[i].deadzone = i < 2 ? 4 : 2; + } + break; + case k_eWiiExtensionControllerType_Nunchuk: + for (i = 0; i < 2; i++) { + ctx->m_StickCalibrationData[i].min = 40; + ctx->m_StickCalibrationData[i].max = 215; + ctx->m_StickCalibrationData[i].center = 0; + ctx->m_StickCalibrationData[i].deadzone = 10; + } + break; + default: + break; + } +} + +static void InitializeExtension(SDL_DriverWii_Context *ctx) +{ + SendExtensionReset(ctx, SDL_TRUE); + InitStickCalibrationData(ctx); + ResetButtonPacketType(ctx); +} + +static void SDLCALL SDL_GameControllerButtonReportingHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + SDL_DriverWii_Context *ctx = (SDL_DriverWii_Context *)userdata; + ctx->m_bUseButtonLabels = SDL_GetStringBoolean(hint, SDL_TRUE); +} + +static void UpdateSlotLED(SDL_DriverWii_Context *ctx) +{ + Uint8 leds; + Uint8 data[2]; + + /* The lowest bit needs to have the rumble status */ + leds = ctx->m_bRumbleActive; + + if (ctx->m_bPlayerLights) { + /* Use the same LED codes as Smash 8-player for 5-7 */ + if (ctx->m_nPlayerIndex == 0 || ctx->m_nPlayerIndex > 3) { + leds |= k_eWiiPlayerLEDs_P1; + } + if (ctx->m_nPlayerIndex == 1 || ctx->m_nPlayerIndex == 4) { + leds |= k_eWiiPlayerLEDs_P2; + } + if (ctx->m_nPlayerIndex == 2 || ctx->m_nPlayerIndex == 5) { + leds |= k_eWiiPlayerLEDs_P3; + } + if (ctx->m_nPlayerIndex == 3 || ctx->m_nPlayerIndex == 6) { + leds |= k_eWiiPlayerLEDs_P4; + } + /* Turn on all lights for other player indexes */ + if (ctx->m_nPlayerIndex < 0 || ctx->m_nPlayerIndex > 6) { + leds |= k_eWiiPlayerLEDs_P1 | k_eWiiPlayerLEDs_P2 | k_eWiiPlayerLEDs_P3 | k_eWiiPlayerLEDs_P4; + } + } + + data[0] = k_eWiiOutputReportIDs_LEDs; + data[1] = leds; + WriteOutput(ctx, data, sizeof(data), SDL_FALSE); +} + +static void SDLCALL SDL_PlayerLEDHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + SDL_DriverWii_Context *ctx = (SDL_DriverWii_Context *)userdata; + SDL_bool bPlayerLights = SDL_GetStringBoolean(hint, SDL_TRUE); + + if (bPlayerLights != ctx->m_bPlayerLights) { + ctx->m_bPlayerLights = bPlayerLights; + + UpdateSlotLED(ctx); + } +} + +static EWiiExtensionControllerType ReadExtensionControllerType(SDL_HIDAPI_Device *device) +{ + SDL_DriverWii_Context *ctx = (SDL_DriverWii_Context *)device->context; + EWiiExtensionControllerType eExtensionControllerType = k_eWiiExtensionControllerType_Unknown; + const int MAX_ATTEMPTS = 20; + int attempts = 0; + + /* Create enough of a context to read the controller type from the device */ + for (attempts = 0; attempts < MAX_ATTEMPTS; ++attempts) { + Uint16 extension; + if (SendExtensionIdentify(ctx, SDL_TRUE) && + ParseExtensionIdentifyResponse(ctx, &extension)) { + Uint8 motion_plus_mode = 0; + if ((extension & WII_EXTENSION_MOTIONPLUS_MASK) == WII_EXTENSION_MOTIONPLUS_ID) { + motion_plus_mode = (Uint8)(extension >> 8); + } + if (motion_plus_mode || extension == WII_EXTENSION_UNINITIALIZED) { + SendExtensionReset(ctx, SDL_TRUE); + if (SendExtensionIdentify(ctx, SDL_TRUE)) { + ParseExtensionIdentifyResponse(ctx, &extension); + } + } + + eExtensionControllerType = GetExtensionType(extension); + + /* Reset the Motion Plus controller if needed */ + if (motion_plus_mode) { + ActivateMotionPlusWithMode(ctx, motion_plus_mode); + } + break; + } + } + return eExtensionControllerType; +} + +static void UpdateDeviceIdentity(SDL_HIDAPI_Device *device) +{ + SDL_DriverWii_Context *ctx = (SDL_DriverWii_Context *)device->context; + + switch (ctx->m_eExtensionControllerType) { + case k_eWiiExtensionControllerType_None: + HIDAPI_SetDeviceName(device, "Nintendo Wii Remote"); + break; + case k_eWiiExtensionControllerType_Nunchuk: + HIDAPI_SetDeviceName(device, "Nintendo Wii Remote with Nunchuk"); + break; + case k_eWiiExtensionControllerType_Gamepad: + HIDAPI_SetDeviceName(device, "Nintendo Wii Remote with Classic Controller"); + break; + case k_eWiiExtensionControllerType_WiiUPro: + HIDAPI_SetDeviceName(device, "Nintendo Wii U Pro Controller"); + break; + default: + HIDAPI_SetDeviceName(device, "Nintendo Wii Remote with Unknown Extension"); + break; + } + device->guid.data[15] = ctx->m_eExtensionControllerType; +} + +static SDL_bool HIDAPI_DriverWii_InitDevice(SDL_HIDAPI_Device *device) +{ + SDL_DriverWii_Context *ctx; + + ctx = (SDL_DriverWii_Context *)SDL_calloc(1, sizeof(*ctx)); + if (!ctx) { + SDL_OutOfMemory(); + return SDL_FALSE; + } + ctx->device = device; + device->context = ctx; + + if (device->vendor_id == USB_VENDOR_NINTENDO) { + ctx->m_eExtensionControllerType = ReadExtensionControllerType(device); + + UpdateDeviceIdentity(device); + } + return HIDAPI_JoystickConnected(device, NULL); +} + +static int HIDAPI_DriverWii_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id) +{ + return -1; +} + +static void HIDAPI_DriverWii_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index) +{ + SDL_DriverWii_Context *ctx = (SDL_DriverWii_Context *)device->context; + + if (!ctx->joystick) { + return; + } + + ctx->m_nPlayerIndex = player_index; + + UpdateSlotLED(ctx); +} + +static SDL_bool HIDAPI_DriverWii_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_DriverWii_Context *ctx = (SDL_DriverWii_Context *)device->context; + + SDL_AssertJoysticksLocked(); + + ctx->joystick = joystick; + + InitializeExtension(ctx); + + GetMotionPlusState(ctx, &ctx->m_bMotionPlusPresent, &ctx->m_ucMotionPlusMode); + + if (NeedsPeriodicMotionPlusCheck(ctx, SDL_FALSE)) { + SchedulePeriodicMotionPlusCheck(ctx); + } + + if (ctx->m_eExtensionControllerType == k_eWiiExtensionControllerType_None || + ctx->m_eExtensionControllerType == k_eWiiExtensionControllerType_Nunchuk) { + SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, 100.0f); + if (ctx->m_eExtensionControllerType == k_eWiiExtensionControllerType_Nunchuk) { + SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL_L, 100.0f); + } + + if (ctx->m_bMotionPlusPresent) { + SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, 100.0f); + } + } + + SDL_AddHintCallback(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS, + SDL_GameControllerButtonReportingHintChanged, ctx); + + /* Initialize player index (needed for setting LEDs) */ + ctx->m_nPlayerIndex = SDL_JoystickGetPlayerIndex(joystick); + ctx->m_bPlayerLights = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_WII_PLAYER_LED, SDL_TRUE); + UpdateSlotLED(ctx); + + SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_WII_PLAYER_LED, + SDL_PlayerLEDHintChanged, ctx); + + /* Initialize the joystick capabilities */ + if (ctx->m_eExtensionControllerType == k_eWiiExtensionControllerType_WiiUPro) { + joystick->nbuttons = 15; + } else { + /* Maximum is Classic Controller + Wiimote */ + joystick->nbuttons = k_eWiiButtons_Max; + } + joystick->naxes = SDL_CONTROLLER_AXIS_MAX; + + ctx->m_unLastInput = SDL_GetTicks(); + + return SDL_TRUE; +} + +static int HIDAPI_DriverWii_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ + SDL_DriverWii_Context *ctx = (SDL_DriverWii_Context *)device->context; + SDL_bool active = (low_frequency_rumble || high_frequency_rumble) ? SDL_TRUE : SDL_FALSE; + + if (active != ctx->m_bRumbleActive) { + Uint8 data[2]; + + data[0] = k_eWiiOutputReportIDs_Rumble; + data[1] = active; + WriteOutput(ctx, data, sizeof(data), SDL_FALSE); + + ctx->m_bRumbleActive = active; + } + return 0; +} + +static int HIDAPI_DriverWii_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) +{ + return SDL_Unsupported(); +} + +static Uint32 HIDAPI_DriverWii_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + return SDL_JOYCAP_RUMBLE; +} + +static int HIDAPI_DriverWii_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + return SDL_Unsupported(); +} + +static int HIDAPI_DriverWii_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + +static int HIDAPI_DriverWii_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled) +{ + SDL_DriverWii_Context *ctx = (SDL_DriverWii_Context *)device->context; + + if (enabled != ctx->m_bReportSensors) { + ctx->m_bReportSensors = enabled; + + if (ctx->m_bMotionPlusPresent) { + if (enabled) { + ActivateMotionPlus(ctx); + } else { + DeactivateMotionPlus(ctx); + } + } + + ResetButtonPacketType(ctx); + } + return 0; +} + +static void PostStickCalibrated(SDL_Joystick *joystick, struct StickCalibrationData *calibration, Uint8 axis, Uint16 data) +{ + Sint16 value = 0; + if (!calibration->center) { + /* Center on first read */ + calibration->center = data; + return; + } + if (data < calibration->min) { + calibration->min = data; + } + if (data > calibration->max) { + calibration->max = data; + } + if (data < calibration->center - calibration->deadzone) { + Uint16 zero = calibration->center - calibration->deadzone; + Uint16 range = zero - calibration->min; + Uint16 distance = zero - data; + float fvalue = (float)distance / (float)range; + value = (Sint16)(fvalue * SDL_JOYSTICK_AXIS_MIN); + } else if (data > calibration->center + calibration->deadzone) { + Uint16 zero = calibration->center + calibration->deadzone; + Uint16 range = calibration->max - zero; + Uint16 distance = data - zero; + float fvalue = (float)distance / (float)range; + value = (Sint16)(fvalue * SDL_JOYSTICK_AXIS_MAX); + } + if (axis == SDL_CONTROLLER_AXIS_LEFTY || axis == SDL_CONTROLLER_AXIS_RIGHTY) { + if (value) { + value = ~value; + } + } + SDL_PrivateJoystickAxis(joystick, axis, value); +} + +/* Send button data to SDL + *`defs` is a mapping for each bit to which button it represents. 0xFF indicates an unused bit + *`data` is the button data from the controller + *`size` is the number of bytes in `data` and the number of arrays of 8 mappings in `defs` + *`on` is the joystick value to be sent if a bit is on + *`off` is the joystick value to be sent if a bit is off + */ +static void PostPackedButtonData(SDL_Joystick *joystick, const Uint8 defs[][8], const Uint8 *data, int size, Uint8 on, Uint8 off) +{ + int i, j; + + for (i = 0; i < size; i++) { + for (j = 0; j < 8; j++) { + Uint8 button = defs[i][j]; + if (button != 0xFF) { + Uint8 state = (data[i] >> j) & 1 ? on : off; + SDL_PrivateJoystickButton(joystick, button, state); + } + } + } +} + +static const Uint8 GAMEPAD_BUTTON_DEFS[3][8] = { + { + 0xFF /* Unused */, + SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, + SDL_CONTROLLER_BUTTON_START, + SDL_CONTROLLER_BUTTON_GUIDE, + SDL_CONTROLLER_BUTTON_BACK, + SDL_CONTROLLER_BUTTON_LEFTSHOULDER, + SDL_CONTROLLER_BUTTON_DPAD_DOWN, + SDL_CONTROLLER_BUTTON_DPAD_RIGHT, + }, + { + SDL_CONTROLLER_BUTTON_DPAD_UP, + SDL_CONTROLLER_BUTTON_DPAD_LEFT, + 0xFF /* ZR */, + SDL_CONTROLLER_BUTTON_X, + SDL_CONTROLLER_BUTTON_A, + SDL_CONTROLLER_BUTTON_Y, + SDL_CONTROLLER_BUTTON_B, + 0xFF /*ZL*/, + }, + { + SDL_CONTROLLER_BUTTON_RIGHTSTICK, + SDL_CONTROLLER_BUTTON_LEFTSTICK, + 0xFF /* Charging */, + 0xFF /* Plugged In */, + 0xFF /* Unused */, + 0xFF /* Unused */, + 0xFF /* Unused */, + 0xFF /* Unused */, + } +}; + +static const Uint8 GAMEPAD_BUTTON_DEFS_POSITIONAL[3][8] = { + { + 0xFF /* Unused */, + SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, + SDL_CONTROLLER_BUTTON_START, + SDL_CONTROLLER_BUTTON_GUIDE, + SDL_CONTROLLER_BUTTON_BACK, + SDL_CONTROLLER_BUTTON_LEFTSHOULDER, + SDL_CONTROLLER_BUTTON_DPAD_DOWN, + SDL_CONTROLLER_BUTTON_DPAD_RIGHT, + }, + { + SDL_CONTROLLER_BUTTON_DPAD_UP, + SDL_CONTROLLER_BUTTON_DPAD_LEFT, + 0xFF /* ZR */, + SDL_CONTROLLER_BUTTON_Y, + SDL_CONTROLLER_BUTTON_B, + SDL_CONTROLLER_BUTTON_X, + SDL_CONTROLLER_BUTTON_A, + 0xFF /*ZL*/, + }, + { + SDL_CONTROLLER_BUTTON_RIGHTSTICK, + SDL_CONTROLLER_BUTTON_LEFTSTICK, + 0xFF /* Charging */, + 0xFF /* Plugged In */, + 0xFF /* Unused */, + 0xFF /* Unused */, + 0xFF /* Unused */, + 0xFF /* Unused */, + } +}; + +static const Uint8 MP_GAMEPAD_BUTTON_DEFS[3][8] = { + { + 0xFF /* Unused */, + SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, + SDL_CONTROLLER_BUTTON_START, + SDL_CONTROLLER_BUTTON_GUIDE, + SDL_CONTROLLER_BUTTON_BACK, + SDL_CONTROLLER_BUTTON_LEFTSHOULDER, + SDL_CONTROLLER_BUTTON_DPAD_DOWN, + SDL_CONTROLLER_BUTTON_DPAD_RIGHT, + }, + { + 0xFF /* Motion Plus data */, + 0xFF /* Motion Plus data */, + 0xFF /* ZR */, + SDL_CONTROLLER_BUTTON_X, + SDL_CONTROLLER_BUTTON_A, + SDL_CONTROLLER_BUTTON_Y, + SDL_CONTROLLER_BUTTON_B, + 0xFF /*ZL*/, + }, + { + SDL_CONTROLLER_BUTTON_RIGHTSTICK, + SDL_CONTROLLER_BUTTON_LEFTSTICK, + 0xFF /* Charging */, + 0xFF /* Plugged In */, + 0xFF /* Unused */, + 0xFF /* Unused */, + 0xFF /* Unused */, + 0xFF /* Unused */, + } +}; + +static const Uint8 MP_GAMEPAD_BUTTON_DEFS_POSITIONAL[3][8] = { + { + 0xFF /* Unused */, + SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, + SDL_CONTROLLER_BUTTON_START, + SDL_CONTROLLER_BUTTON_GUIDE, + SDL_CONTROLLER_BUTTON_BACK, + SDL_CONTROLLER_BUTTON_LEFTSHOULDER, + SDL_CONTROLLER_BUTTON_DPAD_DOWN, + SDL_CONTROLLER_BUTTON_DPAD_RIGHT, + }, + { + 0xFF /* Motion Plus data */, + 0xFF /* Motion Plus data */, + 0xFF /* ZR */, + SDL_CONTROLLER_BUTTON_Y, + SDL_CONTROLLER_BUTTON_B, + SDL_CONTROLLER_BUTTON_X, + SDL_CONTROLLER_BUTTON_A, + 0xFF /*ZL*/, + }, + { + SDL_CONTROLLER_BUTTON_RIGHTSTICK, + SDL_CONTROLLER_BUTTON_LEFTSTICK, + 0xFF /* Charging */, + 0xFF /* Plugged In */, + 0xFF /* Unused */, + 0xFF /* Unused */, + 0xFF /* Unused */, + 0xFF /* Unused */, + } +}; + +static const Uint8 MP_FIXUP_DPAD_BUTTON_DEFS[2][8] = { + { + SDL_CONTROLLER_BUTTON_DPAD_UP, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + }, + { + SDL_CONTROLLER_BUTTON_DPAD_LEFT, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + 0xFF, + } +}; + +static void HandleWiiUProButtonData(SDL_DriverWii_Context *ctx, SDL_Joystick *joystick, const WiiButtonData *data) +{ + static const Uint8 axes[] = { SDL_CONTROLLER_AXIS_LEFTX, SDL_CONTROLLER_AXIS_RIGHTX, SDL_CONTROLLER_AXIS_LEFTY, SDL_CONTROLLER_AXIS_RIGHTY }; + const Uint8(*buttons)[8] = ctx->m_bUseButtonLabels ? GAMEPAD_BUTTON_DEFS : GAMEPAD_BUTTON_DEFS_POSITIONAL; + Uint8 zl, zr; + int i; + + if (data->ucNExtensionBytes < 11) { + return; + } + + /* Buttons */ + PostPackedButtonData(joystick, buttons, data->rgucExtension + 8, 3, SDL_RELEASED, SDL_PRESSED); + + /* Triggers */ + zl = data->rgucExtension[9] & 0x80; + zr = data->rgucExtension[9] & 0x04; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, zl ? SDL_JOYSTICK_AXIS_MIN : SDL_JOYSTICK_AXIS_MAX); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, zr ? SDL_JOYSTICK_AXIS_MIN : SDL_JOYSTICK_AXIS_MAX); + + /* Sticks */ + for (i = 0; i < 4; i++) { + Uint16 value = data->rgucExtension[i * 2] | (data->rgucExtension[i * 2 + 1] << 8); + PostStickCalibrated(joystick, &ctx->m_StickCalibrationData[i], axes[i], value); + } + + /* Power */ + UpdatePowerLevelWiiU(joystick, data->rgucExtension[10]); +} + +static void HandleGamepadControllerButtonData(SDL_DriverWii_Context *ctx, SDL_Joystick *joystick, const WiiButtonData *data) +{ + const Uint8(*buttons)[8] = ctx->m_bUseButtonLabels ? ((ctx->m_ucMotionPlusMode == WII_MOTIONPLUS_MODE_GAMEPAD) ? MP_GAMEPAD_BUTTON_DEFS : GAMEPAD_BUTTON_DEFS) : ((ctx->m_ucMotionPlusMode == WII_MOTIONPLUS_MODE_GAMEPAD) ? MP_GAMEPAD_BUTTON_DEFS_POSITIONAL : GAMEPAD_BUTTON_DEFS_POSITIONAL); + Uint8 lx, ly, rx, ry, zl, zr; + + if (data->ucNExtensionBytes < 6) { + return; + } + + /* Buttons */ + PostPackedButtonData(joystick, buttons, data->rgucExtension + 4, 2, SDL_RELEASED, SDL_PRESSED); + if (ctx->m_ucMotionPlusMode == WII_MOTIONPLUS_MODE_GAMEPAD) { + PostPackedButtonData(joystick, MP_FIXUP_DPAD_BUTTON_DEFS, data->rgucExtension, 2, SDL_RELEASED, SDL_PRESSED); + } + + /* Triggers */ + zl = data->rgucExtension[5] & 0x80; + zr = data->rgucExtension[5] & 0x04; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, zl ? SDL_JOYSTICK_AXIS_MIN : SDL_JOYSTICK_AXIS_MAX); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, zr ? SDL_JOYSTICK_AXIS_MIN : SDL_JOYSTICK_AXIS_MAX); + + /* Sticks */ + if (ctx->m_ucMotionPlusMode == WII_MOTIONPLUS_MODE_GAMEPAD) { + lx = data->rgucExtension[0] & 0x3E; + ly = data->rgucExtension[1] & 0x3E; + } else { + lx = data->rgucExtension[0] & 0x3F; + ly = data->rgucExtension[1] & 0x3F; + } + rx = (data->rgucExtension[2] >> 7) | ((data->rgucExtension[1] >> 5) & 0x06) | ((data->rgucExtension[0] >> 3) & 0x18); + ry = data->rgucExtension[2] & 0x1F; + PostStickCalibrated(joystick, &ctx->m_StickCalibrationData[0], SDL_CONTROLLER_AXIS_LEFTX, lx); + PostStickCalibrated(joystick, &ctx->m_StickCalibrationData[1], SDL_CONTROLLER_AXIS_LEFTY, ly); + PostStickCalibrated(joystick, &ctx->m_StickCalibrationData[2], SDL_CONTROLLER_AXIS_RIGHTX, rx); + PostStickCalibrated(joystick, &ctx->m_StickCalibrationData[3], SDL_CONTROLLER_AXIS_RIGHTY, ry); +} + +static void HandleWiiRemoteButtonData(SDL_DriverWii_Context *ctx, SDL_Joystick *joystick, const WiiButtonData *data) +{ + static const Uint8 buttons[2][8] = { + { + k_eWiiButtons_DPad_Left, + k_eWiiButtons_DPad_Right, + k_eWiiButtons_DPad_Down, + k_eWiiButtons_DPad_Up, + k_eWiiButtons_Plus, + 0xFF /* Unused */, + 0xFF /* Unused */, + 0xFF /* Unused */, + }, + { + k_eWiiButtons_Two, + k_eWiiButtons_One, + k_eWiiButtons_B, + k_eWiiButtons_A, + k_eWiiButtons_Minus, + 0xFF /* Unused */, + 0xFF /* Unused */, + k_eWiiButtons_Home, + } + }; + if (data->hasBaseButtons) { + PostPackedButtonData(joystick, buttons, data->rgucBaseButtons, 2, SDL_PRESSED, SDL_RELEASED); + } +} + +static void HandleWiiRemoteButtonDataAsMainController(SDL_DriverWii_Context *ctx, SDL_Joystick *joystick, const WiiButtonData *data) +{ + /* Wii remote maps really badly to a normal controller + * Mapped 1 and 2 as X and Y + * Not going to attempt positional mapping + */ + static const Uint8 buttons[2][8] = { + { + SDL_CONTROLLER_BUTTON_DPAD_LEFT, + SDL_CONTROLLER_BUTTON_DPAD_RIGHT, + SDL_CONTROLLER_BUTTON_DPAD_DOWN, + SDL_CONTROLLER_BUTTON_DPAD_UP, + SDL_CONTROLLER_BUTTON_START, + 0xFF /* Unused */, + 0xFF /* Unused */, + 0xFF /* Unused */, + }, + { + SDL_CONTROLLER_BUTTON_Y, + SDL_CONTROLLER_BUTTON_X, + SDL_CONTROLLER_BUTTON_A, + SDL_CONTROLLER_BUTTON_B, + SDL_CONTROLLER_BUTTON_BACK, + 0xFF /* Unused */, + 0xFF /* Unused */, + SDL_CONTROLLER_BUTTON_GUIDE, + } + }; + if (data->hasBaseButtons) { + PostPackedButtonData(joystick, buttons, data->rgucBaseButtons, 2, SDL_PRESSED, SDL_RELEASED); + } +} + +static void HandleNunchuckButtonData(SDL_DriverWii_Context *ctx, SDL_Joystick *joystick, const WiiButtonData *data) +{ + Uint8 c_button, z_button; + + if (data->ucNExtensionBytes < 6) { + return; + } + + if (ctx->m_ucMotionPlusMode == WII_MOTIONPLUS_MODE_NUNCHUK) { + c_button = (data->rgucExtension[5] & 0x08) ? SDL_RELEASED : SDL_PRESSED; + z_button = (data->rgucExtension[5] & 0x04) ? SDL_RELEASED : SDL_PRESSED; + } else { + c_button = (data->rgucExtension[5] & 0x02) ? SDL_RELEASED : SDL_PRESSED; + z_button = (data->rgucExtension[5] & 0x01) ? SDL_RELEASED : SDL_PRESSED; + } + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, c_button); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, z_button ? SDL_JOYSTICK_AXIS_MAX : SDL_JOYSTICK_AXIS_MIN); + PostStickCalibrated(joystick, &ctx->m_StickCalibrationData[0], SDL_CONTROLLER_AXIS_LEFTX, data->rgucExtension[0]); + PostStickCalibrated(joystick, &ctx->m_StickCalibrationData[1], SDL_CONTROLLER_AXIS_LEFTY, data->rgucExtension[1]); + + if (ctx->m_bReportSensors) { + const float ACCEL_RES_PER_G = 200.0f; + Sint16 x, y, z; + float values[3]; + + x = (data->rgucExtension[2] << 2); + y = (data->rgucExtension[3] << 2); + z = (data->rgucExtension[4] << 2); + + if (ctx->m_ucMotionPlusMode == WII_MOTIONPLUS_MODE_NUNCHUK) { + x |= ((data->rgucExtension[5] >> 3) & 0x02); + y |= ((data->rgucExtension[5] >> 4) & 0x02); + z &= ~0x04; + z |= ((data->rgucExtension[5] >> 5) & 0x06); + } else { + x |= ((data->rgucExtension[5] >> 2) & 0x03); + y |= ((data->rgucExtension[5] >> 4) & 0x03); + z |= ((data->rgucExtension[5] >> 6) & 0x03); + } + + x -= 0x200; + y -= 0x200; + z -= 0x200; + + values[0] = -((float)x / ACCEL_RES_PER_G) * SDL_STANDARD_GRAVITY; + values[1] = ((float)z / ACCEL_RES_PER_G) * SDL_STANDARD_GRAVITY; + values[2] = ((float)y / ACCEL_RES_PER_G) * SDL_STANDARD_GRAVITY; + SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_ACCEL_L, 0, values, 3); + } +} + +static void HandleMotionPlusData(SDL_DriverWii_Context *ctx, SDL_Joystick *joystick, const WiiButtonData *data) +{ + if (ctx->m_bReportSensors) { + const float GYRO_RES_PER_DEGREE = 8192.0f; + int x, y, z; + float values[3]; + + x = (data->rgucExtension[0] | ((data->rgucExtension[3] << 6) & 0xFF00)) - 8192; + y = (data->rgucExtension[1] | ((data->rgucExtension[4] << 6) & 0xFF00)) - 8192; + z = (data->rgucExtension[2] | ((data->rgucExtension[5] << 6) & 0xFF00)) - 8192; + + if (data->rgucExtension[3] & 0x02) { + /* Slow rotation rate: 8192/440 units per deg/s */ + x *= 440; + } else { + /* Fast rotation rate: 8192/2000 units per deg/s */ + x *= 2000; + } + if (data->rgucExtension[4] & 0x02) { + /* Slow rotation rate: 8192/440 units per deg/s */ + y *= 440; + } else { + /* Fast rotation rate: 8192/2000 units per deg/s */ + y *= 2000; + } + if (data->rgucExtension[3] & 0x01) { + /* Slow rotation rate: 8192/440 units per deg/s */ + z *= 440; + } else { + /* Fast rotation rate: 8192/2000 units per deg/s */ + z *= 2000; + } + + values[0] = -((float)z / GYRO_RES_PER_DEGREE) * (float)M_PI / 180.0f; + values[1] = ((float)x / GYRO_RES_PER_DEGREE) * (float)M_PI / 180.0f; + values[2] = ((float)y / GYRO_RES_PER_DEGREE) * (float)M_PI / 180.0f; + SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_GYRO, 0, values, 3); + } +} + +static void HandleWiiRemoteAccelData(SDL_DriverWii_Context *ctx, SDL_Joystick *joystick, const WiiButtonData *data) +{ + const float ACCEL_RES_PER_G = 100.0f; + Sint16 x, y, z; + float values[3]; + + if (!ctx->m_bReportSensors) { + return; + } + + x = ((data->rgucAccelerometer[0] << 2) | ((data->rgucBaseButtons[0] >> 5) & 0x03)) - 0x200; + y = ((data->rgucAccelerometer[1] << 2) | ((data->rgucBaseButtons[1] >> 4) & 0x02)) - 0x200; + z = ((data->rgucAccelerometer[2] << 2) | ((data->rgucBaseButtons[1] >> 5) & 0x02)) - 0x200; + + values[0] = -((float)x / ACCEL_RES_PER_G) * SDL_STANDARD_GRAVITY; + values[1] = ((float)z / ACCEL_RES_PER_G) * SDL_STANDARD_GRAVITY; + values[2] = ((float)y / ACCEL_RES_PER_G) * SDL_STANDARD_GRAVITY; + SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_ACCEL, 0, values, 3); +} + +static void HandleButtonData(SDL_DriverWii_Context *ctx, SDL_Joystick *joystick, WiiButtonData *data) +{ + if (ctx->m_eExtensionControllerType == k_eWiiExtensionControllerType_WiiUPro) { + HandleWiiUProButtonData(ctx, joystick, data); + return; + } + + if (ctx->m_ucMotionPlusMode != WII_MOTIONPLUS_MODE_NONE && + data->ucNExtensionBytes > 5) { + if (data->rgucExtension[5] & 0x01) { + /* The data is invalid, possibly during a hotplug */ + return; + } + + if (data->rgucExtension[4] & 0x01) { + if (ctx->m_eExtensionControllerType == k_eWiiExtensionControllerType_None) { + /* Something was plugged into the extension port, reinitialize to get new state */ + ctx->m_bDisconnected = SDL_TRUE; + } + } else { + if (ctx->m_eExtensionControllerType != k_eWiiExtensionControllerType_None) { + /* Something was removed from the extension port, reinitialize to get new state */ + ctx->m_bDisconnected = SDL_TRUE; + } + } + + if (data->rgucExtension[5] & 0x02) { + HandleMotionPlusData(ctx, joystick, data); + + /* The extension data is consumed */ + data->ucNExtensionBytes = 0; + } + } + + HandleWiiRemoteButtonData(ctx, joystick, data); + switch (ctx->m_eExtensionControllerType) { + case k_eWiiExtensionControllerType_Nunchuk: + HandleNunchuckButtonData(ctx, joystick, data); + SDL_FALLTHROUGH; + case k_eWiiExtensionControllerType_None: + HandleWiiRemoteButtonDataAsMainController(ctx, joystick, data); + break; + case k_eWiiExtensionControllerType_Gamepad: + HandleGamepadControllerButtonData(ctx, joystick, data); + break; + default: + break; + } + HandleWiiRemoteAccelData(ctx, joystick, data); +} + +static void GetBaseButtons(WiiButtonData *dst, const Uint8 *src) +{ + SDL_memcpy(dst->rgucBaseButtons, src, 2); + dst->hasBaseButtons = SDL_TRUE; +} + +static void GetAccelerometer(WiiButtonData *dst, const Uint8 *src) +{ + SDL_memcpy(dst->rgucAccelerometer, src, 3); + dst->hasAccelerometer = SDL_TRUE; +} + +static void GetExtensionData(WiiButtonData *dst, const Uint8 *src, int size) +{ + SDL_bool valid_data = SDL_FALSE; + int i; + + if (size > sizeof(dst->rgucExtension)) { + size = sizeof(dst->rgucExtension); + } + + for (i = 0; i < size; ++i) { + if (src[i] != 0xFF) { + valid_data = SDL_TRUE; + break; + } + } + if (valid_data) { + SDL_memcpy(dst->rgucExtension, src, size); + dst->ucNExtensionBytes = size; + } +} + +static void HandleStatus(SDL_DriverWii_Context *ctx, SDL_Joystick *joystick) +{ + SDL_bool hadExtension = ctx->m_eExtensionControllerType != k_eWiiExtensionControllerType_None; + SDL_bool hasExtension = ctx->m_rgucReadBuffer[3] & 2 ? SDL_TRUE : SDL_FALSE; + WiiButtonData data; + SDL_zero(data); + GetBaseButtons(&data, ctx->m_rgucReadBuffer + 1); + HandleButtonData(ctx, joystick, &data); + + if (ctx->m_eExtensionControllerType != k_eWiiExtensionControllerType_WiiUPro) { + /* Wii U has separate battery level tracking */ + UpdatePowerLevelWii(joystick, ctx->m_rgucReadBuffer[6]); + } + + /* The report data format has been reset, need to update it */ + ResetButtonPacketType(ctx); + + SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, "HIDAPI Wii: Status update, extension %s\n", hasExtension ? "CONNECTED" : "DISCONNECTED"); + + /* When Motion Plus is active, we get extension connect/disconnect status + * through the Motion Plus packets. Otherwise we can use the status here. + */ + if (ctx->m_ucMotionPlusMode != WII_MOTIONPLUS_MODE_NONE) { + /* Check to make sure the Motion Plus extension state hasn't changed, + * otherwise we'll get extension connect/disconnect status through + * Motion Plus packets. + */ + if (NeedsPeriodicMotionPlusCheck(ctx, SDL_TRUE)) { + ctx->m_unNextMotionPlusCheck = SDL_GetTicks(); + } + + } else if (hadExtension != hasExtension) { + /* Reinitialize to get new state */ + ctx->m_bDisconnected = SDL_TRUE; + } +} + +static void HandleResponse(SDL_DriverWii_Context *ctx, SDL_Joystick *joystick) +{ + EWiiInputReportIDs type = ctx->m_rgucReadBuffer[0]; + WiiButtonData data; + SDL_assert(type == k_eWiiInputReportIDs_Acknowledge || type == k_eWiiInputReportIDs_ReadMemory); + SDL_zero(data); + GetBaseButtons(&data, ctx->m_rgucReadBuffer + 1); + HandleButtonData(ctx, joystick, &data); + + switch (ctx->m_eCommState) { + case k_eWiiCommunicationState_None: + break; + + case k_eWiiCommunicationState_CheckMotionPlusStage1: + case k_eWiiCommunicationState_CheckMotionPlusStage2: + { + Uint16 extension = 0; + if (ParseExtensionIdentifyResponse(ctx, &extension)) { + if ((extension & WII_EXTENSION_MOTIONPLUS_MASK) == WII_EXTENSION_MOTIONPLUS_ID) { + /* Motion Plus is currently active */ + SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, "HIDAPI Wii: Motion Plus CONNECTED (stage %d)\n", ctx->m_eCommState == k_eWiiCommunicationState_CheckMotionPlusStage1 ? 1 : 2); + + if (!ctx->m_bMotionPlusPresent) { + /* Reinitialize to get new sensor availability */ + ctx->m_bDisconnected = SDL_TRUE; + } + ctx->m_eCommState = k_eWiiCommunicationState_None; + + } else if (ctx->m_eCommState == k_eWiiCommunicationState_CheckMotionPlusStage1) { + /* Check to see if Motion Plus is present */ + ReadRegister(ctx, 0xA600FE, 2, SDL_FALSE); + + ctx->m_eCommState = k_eWiiCommunicationState_CheckMotionPlusStage2; + + } else { + /* Motion Plus is not present */ + SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, "HIDAPI Wii: Motion Plus DISCONNECTED (stage %d)\n", ctx->m_eCommState == k_eWiiCommunicationState_CheckMotionPlusStage1 ? 1 : 2); + + if (ctx->m_bMotionPlusPresent) { + /* Reinitialize to get new sensor availability */ + ctx->m_bDisconnected = SDL_TRUE; + } + ctx->m_eCommState = k_eWiiCommunicationState_None; + } + } + } break; + default: + /* Should never happen */ + break; + } +} + +static void HandleButtonPacket(SDL_DriverWii_Context *ctx, SDL_Joystick *joystick) +{ + EWiiInputReportIDs eExpectedReport = GetButtonPacketType(ctx); + WiiButtonData data; + + /* FIXME: This should see if the data format is compatible rather than equal */ + if (eExpectedReport != ctx->m_rgucReadBuffer[0]) { + SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, "HIDAPI Wii: Resetting report mode to %d\n", eExpectedReport); + RequestButtonPacketType(ctx, eExpectedReport); + } + + /* IR camera data is not supported */ + SDL_zero(data); + switch (ctx->m_rgucReadBuffer[0]) { + case k_eWiiInputReportIDs_ButtonData0: /* 30 BB BB */ + GetBaseButtons(&data, ctx->m_rgucReadBuffer + 1); + break; + case k_eWiiInputReportIDs_ButtonData1: /* 31 BB BB AA AA AA */ + case k_eWiiInputReportIDs_ButtonData3: /* 33 BB BB AA AA AA II II II II II II II II II II II II */ + GetBaseButtons(&data, ctx->m_rgucReadBuffer + 1); + GetAccelerometer(&data, ctx->m_rgucReadBuffer + 3); + break; + case k_eWiiInputReportIDs_ButtonData2: /* 32 BB BB EE EE EE EE EE EE EE EE */ + GetBaseButtons(&data, ctx->m_rgucReadBuffer + 1); + GetExtensionData(&data, ctx->m_rgucReadBuffer + 3, 8); + break; + case k_eWiiInputReportIDs_ButtonData4: /* 34 BB BB EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE */ + GetBaseButtons(&data, ctx->m_rgucReadBuffer + 1); + GetExtensionData(&data, ctx->m_rgucReadBuffer + 3, 19); + break; + case k_eWiiInputReportIDs_ButtonData5: /* 35 BB BB AA AA AA EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE */ + GetBaseButtons(&data, ctx->m_rgucReadBuffer + 1); + GetAccelerometer(&data, ctx->m_rgucReadBuffer + 3); + GetExtensionData(&data, ctx->m_rgucReadBuffer + 6, 16); + break; + case k_eWiiInputReportIDs_ButtonData6: /* 36 BB BB II II II II II II II II II II EE EE EE EE EE EE EE EE EE */ + GetBaseButtons(&data, ctx->m_rgucReadBuffer + 1); + GetExtensionData(&data, ctx->m_rgucReadBuffer + 13, 9); + break; + case k_eWiiInputReportIDs_ButtonData7: /* 37 BB BB AA AA AA II II II II II II II II II II EE EE EE EE EE EE */ + GetBaseButtons(&data, ctx->m_rgucReadBuffer + 1); + GetExtensionData(&data, ctx->m_rgucReadBuffer + 16, 6); + break; + case k_eWiiInputReportIDs_ButtonDataD: /* 3d EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE */ + GetExtensionData(&data, ctx->m_rgucReadBuffer + 1, 21); + break; + case k_eWiiInputReportIDs_ButtonDataE: + case k_eWiiInputReportIDs_ButtonDataF: + default: + SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, "HIDAPI Wii: Unsupported button data type %02x", ctx->m_rgucReadBuffer[0]); + return; + } + HandleButtonData(ctx, joystick, &data); +} + +static void HandleInput(SDL_DriverWii_Context *ctx, SDL_Joystick *joystick) +{ + EWiiInputReportIDs type = ctx->m_rgucReadBuffer[0]; + if (type == k_eWiiInputReportIDs_Status) { + HandleStatus(ctx, joystick); + } else if (type == k_eWiiInputReportIDs_Acknowledge || type == k_eWiiInputReportIDs_ReadMemory) { + HandleResponse(ctx, joystick); + } else if (type >= k_eWiiInputReportIDs_ButtonData0 && type <= k_eWiiInputReportIDs_ButtonDataF) { + HandleButtonPacket(ctx, joystick); + } else { + SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, "HIDAPI Wii: Unexpected input packet of type %x", type); + } +} + +static SDL_bool HIDAPI_DriverWii_UpdateDevice(SDL_HIDAPI_Device *device) +{ + SDL_DriverWii_Context *ctx = (SDL_DriverWii_Context *)device->context; + SDL_Joystick *joystick = NULL; + int size; + Uint32 now; + + if (device->num_joysticks > 0) { + joystick = SDL_JoystickFromInstanceID(device->joysticks[0]); + } else { + return SDL_FALSE; + } + + now = SDL_GetTicks(); + + while ((size = ReadInput(ctx)) > 0) { + if (joystick) { + HandleInput(ctx, joystick); + } + ctx->m_unLastInput = now; + } + + /* Check to see if we've lost connection to the controller. + * We have continuous reporting enabled, so this should be reliable now. + */ + { + SDL_COMPILE_TIME_ASSERT(ENABLE_CONTINUOUS_REPORTING, ENABLE_CONTINUOUS_REPORTING); + } + if (SDL_TICKS_PASSED(now, ctx->m_unLastInput + INPUT_WAIT_TIMEOUT_MS)) { + /* Bluetooth may have disconnected, try reopening the controller */ + size = -1; + } + + if (joystick) { + /* These checks aren't needed on the Wii U Pro Controller */ + if (ctx->m_eExtensionControllerType != k_eWiiExtensionControllerType_WiiUPro) { + + /* Check to see if the Motion Plus extension status has changed */ + if (ctx->m_unNextMotionPlusCheck && + SDL_TICKS_PASSED(now, ctx->m_unNextMotionPlusCheck)) { + CheckMotionPlusConnection(ctx); + if (NeedsPeriodicMotionPlusCheck(ctx, SDL_FALSE)) { + SchedulePeriodicMotionPlusCheck(ctx); + } else { + ctx->m_unNextMotionPlusCheck = 0; + } + } + + /* Request a status update periodically to make sure our battery value is up to date */ + if (!ctx->m_unLastStatus || + SDL_TICKS_PASSED(now, ctx->m_unLastStatus + STATUS_UPDATE_TIME_MS)) { + Uint8 data[2]; + + data[0] = k_eWiiOutputReportIDs_StatusRequest; + data[1] = ctx->m_bRumbleActive; + WriteOutput(ctx, data, sizeof(data), SDL_FALSE); + + ctx->m_unLastStatus = now; + } + } + } + + if (size < 0 || ctx->m_bDisconnected) { + /* Read error, device is disconnected */ + HIDAPI_JoystickDisconnected(device, device->joysticks[0]); + } + return size >= 0; +} + +static void HIDAPI_DriverWii_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_DriverWii_Context *ctx = (SDL_DriverWii_Context *)device->context; + + SDL_DelHintCallback(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS, + SDL_GameControllerButtonReportingHintChanged, ctx); + + SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_WII_PLAYER_LED, + SDL_PlayerLEDHintChanged, ctx); + + ctx->joystick = NULL; +} + +static void HIDAPI_DriverWii_FreeDevice(SDL_HIDAPI_Device *device) +{ +} + +SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverWii = { + SDL_HINT_JOYSTICK_HIDAPI_WII, + SDL_TRUE, + HIDAPI_DriverWii_RegisterHints, + HIDAPI_DriverWii_UnregisterHints, + HIDAPI_DriverWii_IsEnabled, + HIDAPI_DriverWii_IsSupportedDevice, + HIDAPI_DriverWii_InitDevice, + HIDAPI_DriverWii_GetDevicePlayerIndex, + HIDAPI_DriverWii_SetDevicePlayerIndex, + HIDAPI_DriverWii_UpdateDevice, + HIDAPI_DriverWii_OpenJoystick, + HIDAPI_DriverWii_RumbleJoystick, + HIDAPI_DriverWii_RumbleJoystickTriggers, + HIDAPI_DriverWii_GetJoystickCapabilities, + HIDAPI_DriverWii_SetJoystickLED, + HIDAPI_DriverWii_SendJoystickEffect, + HIDAPI_DriverWii_SetJoystickSensorsEnabled, + HIDAPI_DriverWii_CloseJoystick, + HIDAPI_DriverWii_FreeDevice, +}; + +#endif /* SDL_JOYSTICK_HIDAPI_WII */ + +#endif /* SDL_JOYSTICK_HIDAPI */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_xbox360.c b/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_xbox360.c new file mode 100644 index 0000000..2917fff --- /dev/null +++ b/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_xbox360.c @@ -0,0 +1,391 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_JOYSTICK_HIDAPI + +#include "SDL_events.h" +#include "SDL_timer.h" +#include "SDL_joystick.h" +#include "SDL_gamecontroller.h" +#include "../../SDL_hints_c.h" +#include "../SDL_sysjoystick.h" +#include "SDL_hidapijoystick_c.h" +#include "SDL_hidapi_rumble.h" + +#ifdef SDL_JOYSTICK_HIDAPI_XBOX360 + +/* Define this if you want to log all packets from the controller */ +/*#define DEBUG_XBOX_PROTOCOL*/ + +typedef struct +{ + SDL_HIDAPI_Device *device; + SDL_Joystick *joystick; + int player_index; + SDL_bool player_lights; + Uint8 last_state[USB_PACKET_LENGTH]; +} SDL_DriverXbox360_Context; + +static void HIDAPI_DriverXbox360_RegisterHints(SDL_HintCallback callback, void *userdata) +{ + SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_XBOX, callback, userdata); + SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_XBOX_360, callback, userdata); +} + +static void HIDAPI_DriverXbox360_UnregisterHints(SDL_HintCallback callback, void *userdata) +{ + SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_XBOX, callback, userdata); + SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_XBOX_360, callback, userdata); +} + +static SDL_bool HIDAPI_DriverXbox360_IsEnabled(void) +{ + return SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_XBOX_360, + SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_XBOX, SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI, SDL_HIDAPI_DEFAULT))); +} + +static SDL_bool HIDAPI_DriverXbox360_IsSupportedDevice(SDL_HIDAPI_Device *device, const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol) +{ + const int XB360W_IFACE_PROTOCOL = 129; /* Wireless */ + + if (vendor_id == USB_VENDOR_ASTRO && product_id == USB_PRODUCT_ASTRO_C40_XBOX360) { + /* This is the ASTRO C40 in Xbox 360 mode */ + return SDL_TRUE; + } + if (vendor_id == USB_VENDOR_NVIDIA) { + /* This is the NVIDIA Shield controller which doesn't talk Xbox controller protocol */ + return SDL_FALSE; + } + if ((vendor_id == USB_VENDOR_MICROSOFT && (product_id == 0x0291 || product_id == 0x0719)) || + (type == SDL_CONTROLLER_TYPE_XBOX360 && interface_protocol == XB360W_IFACE_PROTOCOL)) { + /* This is the wireless dongle, which talks a different protocol */ + return SDL_FALSE; + } + if (interface_number > 0) { + /* This is the chatpad or other input interface, not the Xbox 360 interface */ + return SDL_FALSE; + } +#ifdef __MACOSX__ + if (vendor_id == USB_VENDOR_MICROSOFT && product_id == USB_PRODUCT_XBOX360_WIRED_CONTROLLER && version == 1) { + /* This is the Steam Virtual Gamepad, which isn't supported by this driver */ + return SDL_FALSE; + } + /* Wired Xbox One controllers are handled by this driver, interfacing with + the 360Controller driver available from: + https://github.com/360Controller/360Controller/releases + + Bluetooth Xbox One controllers are handled by the SDL Xbox One driver + */ + if (SDL_IsJoystickBluetoothXboxOne(vendor_id, product_id)) { + return SDL_FALSE; + } + return (type == SDL_CONTROLLER_TYPE_XBOX360 || type == SDL_CONTROLLER_TYPE_XBOXONE) ? SDL_TRUE : SDL_FALSE; +#else + return (type == SDL_CONTROLLER_TYPE_XBOX360) ? SDL_TRUE : SDL_FALSE; +#endif +} + +static SDL_bool SetSlotLED(SDL_hid_device *dev, Uint8 slot, SDL_bool on) +{ + const SDL_bool blink = SDL_FALSE; + Uint8 mode = on ? ((blink ? 0x02 : 0x06) + slot) : 0; + Uint8 led_packet[] = { 0x01, 0x03, 0x00 }; + + led_packet[2] = mode; + if (SDL_hid_write(dev, led_packet, sizeof(led_packet)) != sizeof(led_packet)) { + return SDL_FALSE; + } + return SDL_TRUE; +} + +static void UpdateSlotLED(SDL_DriverXbox360_Context *ctx) +{ + if (ctx->player_lights && ctx->player_lights >= 0) { + SetSlotLED(ctx->device->dev, (ctx->player_index % 4), SDL_TRUE); + } else { + SetSlotLED(ctx->device->dev, 0, SDL_FALSE); + } +} + +static void SDLCALL SDL_PlayerLEDHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + SDL_DriverXbox360_Context *ctx = (SDL_DriverXbox360_Context *)userdata; + SDL_bool player_lights = SDL_GetStringBoolean(hint, SDL_TRUE); + + if (player_lights != ctx->player_lights) { + ctx->player_lights = player_lights; + + UpdateSlotLED(ctx); + } +} + +static SDL_bool HIDAPI_DriverXbox360_InitDevice(SDL_HIDAPI_Device *device) +{ + SDL_DriverXbox360_Context *ctx; + + ctx = (SDL_DriverXbox360_Context *)SDL_calloc(1, sizeof(*ctx)); + if (!ctx) { + SDL_OutOfMemory(); + return SDL_FALSE; + } + ctx->device = device; + + device->context = ctx; + + device->type = SDL_CONTROLLER_TYPE_XBOX360; + + return HIDAPI_JoystickConnected(device, NULL); +} + +static int HIDAPI_DriverXbox360_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id) +{ + return -1; +} + +static void HIDAPI_DriverXbox360_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index) +{ + SDL_DriverXbox360_Context *ctx = (SDL_DriverXbox360_Context *)device->context; + + if (!ctx->joystick) { + return; + } + + ctx->player_index = player_index; + + UpdateSlotLED(ctx); +} + +static SDL_bool HIDAPI_DriverXbox360_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_DriverXbox360_Context *ctx = (SDL_DriverXbox360_Context *)device->context; + + SDL_AssertJoysticksLocked(); + + ctx->joystick = joystick; + SDL_zeroa(ctx->last_state); + + /* Initialize player index (needed for setting LEDs) */ + ctx->player_index = SDL_JoystickGetPlayerIndex(joystick); + ctx->player_lights = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_XBOX_360_PLAYER_LED, SDL_TRUE); + UpdateSlotLED(ctx); + + SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_XBOX_360_PLAYER_LED, + SDL_PlayerLEDHintChanged, ctx); + + /* Initialize the joystick capabilities */ + joystick->nbuttons = 15; + joystick->naxes = SDL_CONTROLLER_AXIS_MAX; + joystick->epowerlevel = SDL_JOYSTICK_POWER_WIRED; + + return SDL_TRUE; +} + +static int HIDAPI_DriverXbox360_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ +#ifdef __MACOSX__ + if (SDL_IsJoystickBluetoothXboxOne(device->vendor_id, device->product_id)) { + Uint8 rumble_packet[] = { 0x03, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00 }; + + rumble_packet[4] = (low_frequency_rumble >> 8); + rumble_packet[5] = (high_frequency_rumble >> 8); + + if (SDL_HIDAPI_SendRumble(device, rumble_packet, sizeof(rumble_packet)) != sizeof(rumble_packet)) { + return SDL_SetError("Couldn't send rumble packet"); + } + } else { + /* On Mac OS X the 360Controller driver uses this short report, + and we need to prefix it with a magic token so hidapi passes it through untouched + */ + Uint8 rumble_packet[] = { 'M', 'A', 'G', 'I', 'C', '0', 0x00, 0x04, 0x00, 0x00 }; + + rumble_packet[6 + 2] = (low_frequency_rumble >> 8); + rumble_packet[6 + 3] = (high_frequency_rumble >> 8); + + if (SDL_HIDAPI_SendRumble(device, rumble_packet, sizeof(rumble_packet)) != sizeof(rumble_packet)) { + return SDL_SetError("Couldn't send rumble packet"); + } + } +#else + Uint8 rumble_packet[] = { 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + rumble_packet[3] = (low_frequency_rumble >> 8); + rumble_packet[4] = (high_frequency_rumble >> 8); + + if (SDL_HIDAPI_SendRumble(device, rumble_packet, sizeof(rumble_packet)) != sizeof(rumble_packet)) { + return SDL_SetError("Couldn't send rumble packet"); + } +#endif + return 0; +} + +static int HIDAPI_DriverXbox360_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) +{ + return SDL_Unsupported(); +} + +static Uint32 HIDAPI_DriverXbox360_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + /* Doesn't have an RGB LED, so don't return SDL_JOYCAP_LED here */ + return SDL_JOYCAP_RUMBLE; +} + +static int HIDAPI_DriverXbox360_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + return SDL_Unsupported(); +} + +static int HIDAPI_DriverXbox360_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + +static int HIDAPI_DriverXbox360_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled) +{ + return SDL_Unsupported(); +} + +static void HIDAPI_DriverXbox360_HandleStatePacket(SDL_Joystick *joystick, SDL_DriverXbox360_Context *ctx, Uint8 *data, int size) +{ + Sint16 axis; +#ifdef __MACOSX__ + const SDL_bool invert_y_axes = SDL_FALSE; +#else + const SDL_bool invert_y_axes = SDL_TRUE; +#endif + + if (ctx->last_state[2] != data[2]) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, (data[2] & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, (data[2] & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, (data[2] & 0x04) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, (data[2] & 0x08) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, (data[2] & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data[2] & 0x20) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (data[2] & 0x40) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data[2] & 0x80) ? SDL_PRESSED : SDL_RELEASED); + } + + if (ctx->last_state[3] != data[3]) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data[3] & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data[3] & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data[3] & 0x04) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_A, (data[3] & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_B, (data[3] & 0x20) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_X, (data[3] & 0x40) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_Y, (data[3] & 0x80) ? SDL_PRESSED : SDL_RELEASED); + } + + axis = ((int)data[4] * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, axis); + axis = ((int)data[5] * 257) - 32768; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, axis); + axis = SDL_SwapLE16(*(Sint16 *)(&data[6])); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis); + axis = SDL_SwapLE16(*(Sint16 *)(&data[8])); + if (invert_y_axes) { + axis = ~axis; + } + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, axis); + axis = SDL_SwapLE16(*(Sint16 *)(&data[10])); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, axis); + axis = SDL_SwapLE16(*(Sint16 *)(&data[12])); + if (invert_y_axes) { + axis = ~axis; + } + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis); + + SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state))); +} + +static SDL_bool HIDAPI_DriverXbox360_UpdateDevice(SDL_HIDAPI_Device *device) +{ + SDL_DriverXbox360_Context *ctx = (SDL_DriverXbox360_Context *)device->context; + SDL_Joystick *joystick = NULL; + Uint8 data[USB_PACKET_LENGTH]; + int size = 0; + + if (device->num_joysticks > 0) { + joystick = SDL_JoystickFromInstanceID(device->joysticks[0]); + } else { + return SDL_FALSE; + } + + while ((size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) { +#ifdef DEBUG_XBOX_PROTOCOL + HIDAPI_DumpPacket("Xbox 360 packet: size = %d", data, size); +#endif + if (!joystick) { + continue; + } + + if (data[0] == 0x00) { + HIDAPI_DriverXbox360_HandleStatePacket(joystick, ctx, data, size); + } + } + + if (size < 0) { + /* Read error, device is disconnected */ + HIDAPI_JoystickDisconnected(device, device->joysticks[0]); + } + return size >= 0; +} + +static void HIDAPI_DriverXbox360_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_DriverXbox360_Context *ctx = (SDL_DriverXbox360_Context *)device->context; + + SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_XBOX_360_PLAYER_LED, + SDL_PlayerLEDHintChanged, ctx); + + ctx->joystick = NULL; +} + +static void HIDAPI_DriverXbox360_FreeDevice(SDL_HIDAPI_Device *device) +{ +} + +SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360 = { + SDL_HINT_JOYSTICK_HIDAPI_XBOX_360, + SDL_TRUE, + HIDAPI_DriverXbox360_RegisterHints, + HIDAPI_DriverXbox360_UnregisterHints, + HIDAPI_DriverXbox360_IsEnabled, + HIDAPI_DriverXbox360_IsSupportedDevice, + HIDAPI_DriverXbox360_InitDevice, + HIDAPI_DriverXbox360_GetDevicePlayerIndex, + HIDAPI_DriverXbox360_SetDevicePlayerIndex, + HIDAPI_DriverXbox360_UpdateDevice, + HIDAPI_DriverXbox360_OpenJoystick, + HIDAPI_DriverXbox360_RumbleJoystick, + HIDAPI_DriverXbox360_RumbleJoystickTriggers, + HIDAPI_DriverXbox360_GetJoystickCapabilities, + HIDAPI_DriverXbox360_SetJoystickLED, + HIDAPI_DriverXbox360_SendJoystickEffect, + HIDAPI_DriverXbox360_SetJoystickSensorsEnabled, + HIDAPI_DriverXbox360_CloseJoystick, + HIDAPI_DriverXbox360_FreeDevice, +}; + +#endif /* SDL_JOYSTICK_HIDAPI_XBOX360 */ + +#endif /* SDL_JOYSTICK_HIDAPI */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/joystick/hidapi/SDL_hidapi_xbox360w.c b/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_xbox360w.c similarity index 52% rename from SDL2-2.0.12/src/joystick/hidapi/SDL_hidapi_xbox360w.c rename to SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_xbox360w.c index 13dca5e..9c44085 100644 --- a/SDL2-2.0.12/src/joystick/hidapi/SDL_hidapi_xbox360w.c +++ b/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_xbox360w.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -22,130 +22,180 @@ #ifdef SDL_JOYSTICK_HIDAPI -#include "SDL_hints.h" -#include "SDL_log.h" #include "SDL_events.h" #include "SDL_timer.h" #include "SDL_joystick.h" #include "SDL_gamecontroller.h" +#include "../../SDL_hints_c.h" #include "../SDL_sysjoystick.h" #include "SDL_hidapijoystick_c.h" #include "SDL_hidapi_rumble.h" - #ifdef SDL_JOYSTICK_HIDAPI_XBOX360 +/* Define this if you want to log all packets from the controller */ +/*#define DEBUG_XBOX_PROTOCOL*/ -typedef struct { +typedef struct +{ + SDL_HIDAPI_Device *device; SDL_bool connected; + int player_index; + SDL_bool player_lights; Uint8 last_state[USB_PACKET_LENGTH]; } SDL_DriverXbox360W_Context; +static void HIDAPI_DriverXbox360W_RegisterHints(SDL_HintCallback callback, void *userdata) +{ + SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_XBOX, callback, userdata); + SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_XBOX_360, callback, userdata); + SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_XBOX_360_WIRELESS, callback, userdata); +} -static SDL_bool -HIDAPI_DriverXbox360W_IsSupportedDevice(const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol) +static void HIDAPI_DriverXbox360W_UnregisterHints(SDL_HintCallback callback, void *userdata) +{ + SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_XBOX, callback, userdata); + SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_XBOX_360, callback, userdata); + SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_XBOX_360_WIRELESS, callback, userdata); +} + +static SDL_bool HIDAPI_DriverXbox360W_IsEnabled(void) +{ + return SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_XBOX_360_WIRELESS, + SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_XBOX_360, SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_XBOX, SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI, SDL_HIDAPI_DEFAULT)))); +} + +static SDL_bool HIDAPI_DriverXbox360W_IsSupportedDevice(SDL_HIDAPI_Device *device, const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol) { const int XB360W_IFACE_PROTOCOL = 129; /* Wireless */ - if ((vendor_id == USB_VENDOR_MICROSOFT && (product_id == 0x0291 || product_id == 0x02a9 || product_id == 0x0719)) || + if ((vendor_id == USB_VENDOR_MICROSOFT && (product_id == 0x0291 || product_id == 0x02a9 || product_id == 0x0719) && interface_protocol == 0) || (type == SDL_CONTROLLER_TYPE_XBOX360 && interface_protocol == XB360W_IFACE_PROTOCOL)) { return SDL_TRUE; } return SDL_FALSE; } -static const char * -HIDAPI_DriverXbox360W_GetDeviceName(Uint16 vendor_id, Uint16 product_id) +static SDL_bool SetSlotLED(SDL_hid_device *dev, Uint8 slot, SDL_bool on) { - return "Xbox 360 Wireless Controller"; -} + const SDL_bool blink = SDL_FALSE; + Uint8 mode = on ? ((blink ? 0x02 : 0x06) + slot) : 0; + Uint8 led_packet[] = { 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -static SDL_bool SetSlotLED(hid_device *dev, Uint8 slot) -{ - Uint8 mode = 0x02 + slot; - const Uint8 led_packet[] = { 0x00, 0x00, 0x08, (0x40 + (mode % 0x0e)), 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - - if (hid_write(dev, led_packet, sizeof(led_packet)) != sizeof(led_packet)) { + led_packet[3] = 0x40 + (mode % 0x0e); + if (SDL_hid_write(dev, led_packet, sizeof(led_packet)) != sizeof(led_packet)) { return SDL_FALSE; } return SDL_TRUE; } -static void -UpdatePowerLevel(SDL_Joystick *joystick, Uint8 level) +static void UpdateSlotLED(SDL_DriverXbox360W_Context *ctx) +{ + if (ctx->player_lights && ctx->player_lights >= 0) { + SetSlotLED(ctx->device->dev, (ctx->player_index % 4), SDL_TRUE); + } else { + SetSlotLED(ctx->device->dev, 0, SDL_FALSE); + } +} + +static void SDLCALL SDL_PlayerLEDHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + SDL_DriverXbox360W_Context *ctx = (SDL_DriverXbox360W_Context *)userdata; + SDL_bool player_lights = SDL_GetStringBoolean(hint, SDL_TRUE); + + if (player_lights != ctx->player_lights) { + ctx->player_lights = player_lights; + + UpdateSlotLED(ctx); + } +} + +static void UpdatePowerLevel(SDL_Joystick *joystick, Uint8 level) { float normalized_level = (float)level / 255.0f; if (normalized_level <= 0.05f) { - joystick->epowerlevel = SDL_JOYSTICK_POWER_EMPTY; + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_EMPTY); } else if (normalized_level <= 0.20f) { - joystick->epowerlevel = SDL_JOYSTICK_POWER_LOW; + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_LOW); } else if (normalized_level <= 0.70f) { - joystick->epowerlevel = SDL_JOYSTICK_POWER_MEDIUM; + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_MEDIUM); } else { - joystick->epowerlevel = SDL_JOYSTICK_POWER_FULL; + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_FULL); } } -static SDL_bool -HIDAPI_DriverXbox360W_InitDevice(SDL_HIDAPI_Device *device) +static SDL_bool HIDAPI_DriverXbox360W_InitDevice(SDL_HIDAPI_Device *device) { SDL_DriverXbox360W_Context *ctx; /* Requests controller presence information from the wireless dongle */ const Uint8 init_packet[] = { 0x08, 0x00, 0x0F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + HIDAPI_SetDeviceName(device, "Xbox 360 Wireless Controller"); + ctx = (SDL_DriverXbox360W_Context *)SDL_calloc(1, sizeof(*ctx)); if (!ctx) { SDL_OutOfMemory(); return SDL_FALSE; } + ctx->device = device; - device->dev = hid_open_path(device->path, 0); - if (!device->dev) { - SDL_free(ctx); - SDL_SetError("Couldn't open %s", device->path); - return SDL_FALSE; - } device->context = ctx; - if (hid_write(device->dev, init_packet, sizeof(init_packet)) != sizeof(init_packet)) { + if (SDL_hid_write(device->dev, init_packet, sizeof(init_packet)) != sizeof(init_packet)) { SDL_SetError("Couldn't write init packet"); return SDL_FALSE; } + device->type = SDL_CONTROLLER_TYPE_XBOX360; + return SDL_TRUE; } -static int -HIDAPI_DriverXbox360W_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id) +static int HIDAPI_DriverXbox360W_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id) { return -1; } -static void -HIDAPI_DriverXbox360W_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index) -{ - SetSlotLED(device->dev, (player_index % 4)); -} - -static SDL_bool -HIDAPI_DriverXbox360W_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +static void HIDAPI_DriverXbox360W_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index) { SDL_DriverXbox360W_Context *ctx = (SDL_DriverXbox360W_Context *)device->context; + if (!ctx) { + return; + } + + ctx->player_index = player_index; + + UpdateSlotLED(ctx); +} + +static SDL_bool HIDAPI_DriverXbox360W_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_DriverXbox360W_Context *ctx = (SDL_DriverXbox360W_Context *)device->context; + + SDL_AssertJoysticksLocked(); + SDL_zeroa(ctx->last_state); + /* Initialize player index (needed for setting LEDs) */ + ctx->player_index = SDL_JoystickGetPlayerIndex(joystick); + ctx->player_lights = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_XBOX_360_PLAYER_LED, SDL_TRUE); + UpdateSlotLED(ctx); + + SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_XBOX_360_PLAYER_LED, + SDL_PlayerLEDHintChanged, ctx); + /* Initialize the joystick capabilities */ - joystick->nbuttons = SDL_CONTROLLER_BUTTON_MAX; + joystick->nbuttons = 15; joystick->naxes = SDL_CONTROLLER_AXIS_MAX; joystick->epowerlevel = SDL_JOYSTICK_POWER_UNKNOWN; return SDL_TRUE; } -static int -HIDAPI_DriverXbox360W_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +static int HIDAPI_DriverXbox360W_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) { Uint8 rumble_packet[] = { 0x00, 0x01, 0x0f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; @@ -158,8 +208,33 @@ HIDAPI_DriverXbox360W_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *jo return 0; } -static void -HIDAPI_DriverXbox360W_HandleStatePacket(SDL_Joystick *joystick, hid_device *dev, SDL_DriverXbox360W_Context *ctx, Uint8 *data, int size) +static int HIDAPI_DriverXbox360W_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) +{ + return SDL_Unsupported(); +} + +static Uint32 HIDAPI_DriverXbox360W_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + /* Doesn't have an RGB LED, so don't return SDL_JOYCAP_LED here */ + return SDL_JOYCAP_RUMBLE; +} + +static int HIDAPI_DriverXbox360W_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + return SDL_Unsupported(); +} + +static int HIDAPI_DriverXbox360W_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + +static int HIDAPI_DriverXbox360W_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled) +{ + return SDL_Unsupported(); +} + +static void HIDAPI_DriverXbox360W_HandleStatePacket(SDL_Joystick *joystick, SDL_hid_device *dev, SDL_DriverXbox360W_Context *ctx, Uint8 *data, int size) { Sint16 axis; const SDL_bool invert_y_axes = SDL_TRUE; @@ -189,16 +264,16 @@ HIDAPI_DriverXbox360W_HandleStatePacket(SDL_Joystick *joystick, hid_device *dev, SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, axis); axis = ((int)data[5] * 257) - 32768; SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, axis); - axis = *(Sint16*)(&data[6]); + axis = SDL_SwapLE16(*(Sint16 *)(&data[6])); SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis); - axis = *(Sint16*)(&data[8]); + axis = SDL_SwapLE16(*(Sint16 *)(&data[8])); if (invert_y_axes) { axis = ~axis; } SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, axis); - axis = *(Sint16*)(&data[10]); + axis = SDL_SwapLE16(*(Sint16 *)(&data[10])); SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, axis); - axis = *(Sint16*)(&data[12]); + axis = SDL_SwapLE16(*(Sint16 *)(&data[12])); if (invert_y_axes) { axis = ~axis; } @@ -207,8 +282,7 @@ HIDAPI_DriverXbox360W_HandleStatePacket(SDL_Joystick *joystick, hid_device *dev, SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state))); } -static SDL_bool -HIDAPI_DriverXbox360W_UpdateDevice(SDL_HIDAPI_Device *device) +static SDL_bool HIDAPI_DriverXbox360W_UpdateDevice(SDL_HIDAPI_Device *device) { SDL_DriverXbox360W_Context *ctx = (SDL_DriverXbox360W_Context *)device->context; SDL_Joystick *joystick = NULL; @@ -219,7 +293,10 @@ HIDAPI_DriverXbox360W_UpdateDevice(SDL_HIDAPI_Device *device) joystick = SDL_JoystickFromInstanceID(device->joysticks[0]); } - while ((size = hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) { + while ((size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) { +#ifdef DEBUG_XBOX_PROTOCOL + HIDAPI_DumpPacket("Xbox 360 wireless packet: size = %d", data, size); +#endif if (size == 2 && data[0] == 0x08) { SDL_bool connected = (data[1] & 0x80) ? SDL_TRUE : SDL_FALSE; #ifdef DEBUG_JOYSTICK @@ -254,49 +331,50 @@ HIDAPI_DriverXbox360W_UpdateDevice(SDL_HIDAPI_Device *device) } } else if (size == 29 && data[0] == 0x00 && (data[1] & 0x01) == 0x01) { if (joystick) { - HIDAPI_DriverXbox360W_HandleStatePacket(joystick, device->dev, ctx, data+4, size-4); + HIDAPI_DriverXbox360W_HandleStatePacket(joystick, device->dev, ctx, data + 4, size - 4); } } } - if (joystick) { - if (size < 0) { - /* Read error, device is disconnected */ - HIDAPI_JoystickDisconnected(device, joystick->instance_id); - } + if (size < 0 && device->num_joysticks > 0) { + /* Read error, device is disconnected */ + HIDAPI_JoystickDisconnected(device, device->joysticks[0]); } - return (size >= 0); + return size >= 0; } -static void -HIDAPI_DriverXbox360W_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +static void HIDAPI_DriverXbox360W_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_DriverXbox360W_Context *ctx = (SDL_DriverXbox360W_Context *)device->context; + + SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_XBOX_360_PLAYER_LED, + SDL_PlayerLEDHintChanged, ctx); +} + +static void HIDAPI_DriverXbox360W_FreeDevice(SDL_HIDAPI_Device *device) { } -static void -HIDAPI_DriverXbox360W_FreeDevice(SDL_HIDAPI_Device *device) -{ - hid_close(device->dev); - device->dev = NULL; - - SDL_free(device->context); - device->context = NULL; -} - -SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360W = -{ - SDL_HINT_JOYSTICK_HIDAPI_XBOX, +SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360W = { + SDL_HINT_JOYSTICK_HIDAPI_XBOX_360_WIRELESS, SDL_TRUE, + HIDAPI_DriverXbox360W_RegisterHints, + HIDAPI_DriverXbox360W_UnregisterHints, + HIDAPI_DriverXbox360W_IsEnabled, HIDAPI_DriverXbox360W_IsSupportedDevice, - HIDAPI_DriverXbox360W_GetDeviceName, HIDAPI_DriverXbox360W_InitDevice, HIDAPI_DriverXbox360W_GetDevicePlayerIndex, HIDAPI_DriverXbox360W_SetDevicePlayerIndex, HIDAPI_DriverXbox360W_UpdateDevice, HIDAPI_DriverXbox360W_OpenJoystick, HIDAPI_DriverXbox360W_RumbleJoystick, + HIDAPI_DriverXbox360W_RumbleJoystickTriggers, + HIDAPI_DriverXbox360W_GetJoystickCapabilities, + HIDAPI_DriverXbox360W_SetJoystickLED, + HIDAPI_DriverXbox360W_SendJoystickEffect, + HIDAPI_DriverXbox360W_SetJoystickSensorsEnabled, HIDAPI_DriverXbox360W_CloseJoystick, - HIDAPI_DriverXbox360W_FreeDevice + HIDAPI_DriverXbox360W_FreeDevice, }; #endif /* SDL_JOYSTICK_HIDAPI_XBOX360 */ diff --git a/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_xboxone.c b/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_xboxone.c new file mode 100644 index 0000000..497234a --- /dev/null +++ b/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapi_xboxone.c @@ -0,0 +1,1357 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_JOYSTICK_HIDAPI + +#include "SDL_events.h" +#include "SDL_timer.h" +#include "SDL_joystick.h" +#include "SDL_gamecontroller.h" +#include "../../SDL_hints_c.h" +#include "../SDL_sysjoystick.h" +#include "SDL_hidapijoystick_c.h" +#include "SDL_hidapi_rumble.h" + +#ifdef SDL_JOYSTICK_HIDAPI_XBOXONE + +/* Define this if you want verbose logging of the init sequence */ +/*#define DEBUG_JOYSTICK*/ + +/* Define this if you want to log all packets from the controller */ +/*#define DEBUG_XBOX_PROTOCOL*/ + +#define CONTROLLER_NEGOTIATION_TIMEOUT_MS 300 +#define CONTROLLER_PREPARE_INPUT_TIMEOUT_MS 50 + +/* Deadzone thresholds */ +#define XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE 7849 +#define XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE 8689 +#define XINPUT_GAMEPAD_TRIGGER_THRESHOLD -25058 /* Uint8 30 scaled to Sint16 full range */ + +/* Start controller */ +static const Uint8 xboxone_init0[] = { + 0x05, 0x20, 0x03, 0x01, 0x00 +}; +/* Enable LED */ +static const Uint8 xboxone_init1[] = { + 0x0A, 0x20, 0x00, 0x03, 0x00, 0x01, 0x14 +}; +/* Some PowerA controllers need to actually start the rumble motors */ +static const Uint8 xboxone_powera_rumble_init[] = { + 0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00, + 0x1D, 0x1D, 0xFF, 0x00, 0x00 +}; +/* Setup rumble (not needed for Microsoft controllers, but it doesn't hurt) */ +static const Uint8 xboxone_init2[] = { + 0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0x00, 0xEB +}; +/* This controller passed security check */ +static const Uint8 security_passed_packet[] = { + 0x06, 0x20, 0x00, 0x02, 0x01, 0x00 +}; + +/* + * This specifies the selection of init packets that a gamepad + * will be sent on init *and* the order in which they will be + * sent. The correct sequence number will be added when the + * packet is going to be sent. + */ +typedef struct +{ + Uint16 vendor_id; + Uint16 product_id; + Uint16 exclude_vendor_id; + Uint16 exclude_product_id; + const Uint8 *data; + int size; + const Uint8 response[2]; +} SDL_DriverXboxOne_InitPacket; + +static const SDL_DriverXboxOne_InitPacket xboxone_init_packets[] = { + { 0x0000, 0x0000, 0x0000, 0x0000, xboxone_init0, sizeof(xboxone_init0), { 0x00, 0x00 } }, + { 0x0000, 0x0000, 0x0000, 0x0000, xboxone_init1, sizeof(xboxone_init1), { 0x00, 0x00 } }, + /* The PDP Rock Candy and Victrix Gambit controllers don't start sending input until they get this packet */ + { 0x0e6f, 0x0000, 0x0000, 0x0000, security_passed_packet, sizeof(security_passed_packet), { 0x00, 0x00 } }, + { 0x24c6, 0x541a, 0x0000, 0x0000, xboxone_powera_rumble_init, sizeof(xboxone_powera_rumble_init), { 0x00, 0x00 } }, + { 0x24c6, 0x542a, 0x0000, 0x0000, xboxone_powera_rumble_init, sizeof(xboxone_powera_rumble_init), { 0x00, 0x00 } }, + { 0x24c6, 0x543a, 0x0000, 0x0000, xboxone_powera_rumble_init, sizeof(xboxone_powera_rumble_init), { 0x00, 0x00 } }, + { 0x0000, 0x0000, 0x0000, 0x0000, xboxone_init2, sizeof(xboxone_init2), { 0x00, 0x00 } }, +}; + +typedef enum +{ + XBOX_ONE_INIT_STATE_START_NEGOTIATING, + XBOX_ONE_INIT_STATE_NEGOTIATING, + XBOX_ONE_INIT_STATE_PREPARE_INPUT, + XBOX_ONE_INIT_STATE_COMPLETE, +} SDL_XboxOneInitState; + +typedef enum +{ + XBOX_ONE_RUMBLE_STATE_IDLE, + XBOX_ONE_RUMBLE_STATE_QUEUED, + XBOX_ONE_RUMBLE_STATE_BUSY +} SDL_XboxOneRumbleState; + +typedef struct +{ + SDL_HIDAPI_Device *device; + Uint16 vendor_id; + Uint16 product_id; + SDL_bool bluetooth; + SDL_XboxOneInitState init_state; + int init_packet; + Uint32 start_time; + Uint8 sequence; + Uint32 send_time; + SDL_bool has_guide_packet; + SDL_bool has_color_led; + SDL_bool has_paddles; + SDL_bool has_unmapped_state; + SDL_bool has_trigger_rumble; + SDL_bool has_share_button; + Uint8 last_paddle_state; + Uint8 low_frequency_rumble; + Uint8 high_frequency_rumble; + Uint8 left_trigger_rumble; + Uint8 right_trigger_rumble; + SDL_XboxOneRumbleState rumble_state; + Uint32 rumble_time; + SDL_bool rumble_pending; + Uint8 last_state[USB_PACKET_LENGTH]; +} SDL_DriverXboxOne_Context; + +static SDL_bool ControllerHasColorLED(Uint16 vendor_id, Uint16 product_id) +{ + return vendor_id == USB_VENDOR_MICROSOFT && product_id == USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2; +} + +static SDL_bool ControllerHasPaddles(Uint16 vendor_id, Uint16 product_id) +{ + return SDL_IsJoystickXboxOneElite(vendor_id, product_id); +} + +static SDL_bool ControllerHasTriggerRumble(Uint16 vendor_id, Uint16 product_id) +{ + /* All the Microsoft Xbox One controllers have trigger rumble */ + if (vendor_id == USB_VENDOR_MICROSOFT) { + return SDL_TRUE; + } + + /* It turns out other controllers a mixed bag as to whether they support + trigger rumble or not, and when they do it's often a buzz rather than + the vibration of the Microsoft trigger rumble, so for now just pretend + that it is not available. + */ + return SDL_FALSE; +} + +static SDL_bool ControllerHasShareButton(Uint16 vendor_id, Uint16 product_id) +{ + return SDL_IsJoystickXboxSeriesX(vendor_id, product_id); +} + +static int GetHomeLEDBrightness(const char *hint) +{ + const int MAX_VALUE = 50; + int value = 20; + + if (hint && *hint) { + if (SDL_strchr(hint, '.') != NULL) { + value = (int)(MAX_VALUE * SDL_atof(hint)); + } else if (!SDL_GetStringBoolean(hint, SDL_TRUE)) { + value = 0; + } + } + return value; +} + +static void SetHomeLED(SDL_DriverXboxOne_Context *ctx, int value) +{ + Uint8 led_packet[] = { 0x0A, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00 }; + + if (value > 0) { + led_packet[5] = 0x01; + led_packet[6] = (Uint8)value; + } + SDL_HIDAPI_SendRumble(ctx->device, led_packet, sizeof(led_packet)); +} + +static void SDLCALL SDL_HomeLEDHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + SDL_DriverXboxOne_Context *ctx = (SDL_DriverXboxOne_Context *)userdata; + + if (hint && *hint) { + SetHomeLED(ctx, GetHomeLEDBrightness(hint)); + } +} + +static void SetInitState(SDL_DriverXboxOne_Context *ctx, SDL_XboxOneInitState state) +{ +#ifdef DEBUG_JOYSTICK + SDL_Log("Setting init state %d\n", state); +#endif + ctx->init_state = state; +} + +static void SendAckIfNeeded(SDL_HIDAPI_Device *device, const Uint8 *data, int size) +{ +#if defined(__WIN32__) || defined(__WINGDK__) + /* The Windows driver is taking care of acks */ +#else + if ((data[1] & 0x30) == 0x30) { + Uint8 ack_packet[] = { 0x01, 0x20, 0x00, 0x09, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + ack_packet[2] = data[2]; + ack_packet[5] = data[0]; + ack_packet[7] = data[3]; + + /* The initial ack needs 0x80 added to the response, for some reason */ + if (data[0] == 0x04 && data[1] == 0xF0) { + ack_packet[11] = 0x80; + } + +#ifdef DEBUG_XBOX_PROTOCOL + HIDAPI_DumpPacket("Xbox One sending ACK packet: size = %d", ack_packet, sizeof(ack_packet)); +#endif + if (SDL_HIDAPI_LockRumble() != 0 || + SDL_HIDAPI_SendRumbleAndUnlock(device, ack_packet, sizeof(ack_packet)) != sizeof(ack_packet)) { + SDL_SetError("Couldn't send ack packet"); + } + } +#endif /* defined(__WIN32__) || defined(__WINGDK__ */ +} + +#if 0 +static SDL_bool SendSerialRequest(SDL_HIDAPI_Device *device, SDL_DriverXboxOne_Context *ctx) +{ + Uint8 serial_packet[] = { 0x1E, 0x30, 0x07, 0x01, 0x04 }; + + ctx->send_time = SDL_GetTicks(); + + /* Request the serial number + * Sending this should be done only after the negotiation is complete. + * It will cancel the announce packet if sent before that, and will be + * ignored if sent during the negotiation. + */ + if (SDL_HIDAPI_LockRumble() != 0 || + SDL_HIDAPI_SendRumbleAndUnlock(device, serial_packet, sizeof(serial_packet)) != sizeof(serial_packet)) { + SDL_SetError("Couldn't send serial packet"); + return SDL_FALSE; + } + return SDL_TRUE; +} +#endif + +static SDL_bool ControllerNeedsNegotiation(SDL_DriverXboxOne_Context *ctx) +{ + if (ctx->vendor_id == USB_VENDOR_PDP && ctx->product_id == 0x0246) { + /* The PDP Rock Candy (PID 0x0246) doesn't send the announce packet on Linux for some reason */ + return SDL_TRUE; + } + return SDL_FALSE; +} + +static SDL_bool SendControllerInit(SDL_HIDAPI_Device *device, SDL_DriverXboxOne_Context *ctx) +{ + Uint16 vendor_id = ctx->vendor_id; + Uint16 product_id = ctx->product_id; + Uint8 init_packet[USB_PACKET_LENGTH]; + + for (; ctx->init_packet < SDL_arraysize(xboxone_init_packets); ++ctx->init_packet) { + const SDL_DriverXboxOne_InitPacket *packet = &xboxone_init_packets[ctx->init_packet]; + + if (packet->vendor_id && (vendor_id != packet->vendor_id)) { + continue; + } + + if (packet->product_id && (product_id != packet->product_id)) { + continue; + } + + if (packet->exclude_vendor_id && (vendor_id == packet->exclude_vendor_id)) { + continue; + } + + if (packet->exclude_product_id && (product_id == packet->exclude_product_id)) { + continue; + } + + SDL_memcpy(init_packet, packet->data, packet->size); + if (init_packet[0] != 0x01) { + init_packet[2] = ctx->sequence++; + } + if (init_packet[0] == 0x0A) { + /* Get the initial brightness value */ + int brightness = GetHomeLEDBrightness(SDL_GetHint(SDL_HINT_JOYSTICK_HIDAPI_XBOX_ONE_HOME_LED)); + init_packet[5] = (brightness > 0) ? 0x01 : 0x00; + init_packet[6] = (Uint8)brightness; + } +#ifdef DEBUG_XBOX_PROTOCOL + HIDAPI_DumpPacket("Xbox One sending INIT packet: size = %d", init_packet, packet->size); +#endif + ctx->send_time = SDL_GetTicks(); + + if (SDL_HIDAPI_LockRumble() != 0 || + SDL_HIDAPI_SendRumbleAndUnlock(device, init_packet, packet->size) != packet->size) { + SDL_SetError("Couldn't write Xbox One initialization packet"); + return SDL_FALSE; + } + + if (packet->response[0]) { + return SDL_TRUE; + } + + /* Wait to process the rumble packet */ + if (packet->data == xboxone_powera_rumble_init) { + SDL_Delay(10); + } + } + + /* All done with the negotiation, prepare for input! */ + SetInitState(ctx, XBOX_ONE_INIT_STATE_PREPARE_INPUT); + + return SDL_TRUE; +} + +static void HIDAPI_DriverXboxOne_RegisterHints(SDL_HintCallback callback, void *userdata) +{ + SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_XBOX, callback, userdata); + SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_XBOX_ONE, callback, userdata); +} + +static void HIDAPI_DriverXboxOne_UnregisterHints(SDL_HintCallback callback, void *userdata) +{ + SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_XBOX, callback, userdata); + SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_XBOX_ONE, callback, userdata); +} + +static SDL_bool HIDAPI_DriverXboxOne_IsEnabled(void) +{ + return SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_XBOX_ONE, + SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_XBOX, SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI, SDL_HIDAPI_DEFAULT))); +} + +static SDL_bool HIDAPI_DriverXboxOne_IsSupportedDevice(SDL_HIDAPI_Device *device, const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol) +{ +#ifdef __MACOSX__ + /* Wired Xbox One controllers are handled by the 360Controller driver */ + if (!SDL_IsJoystickBluetoothXboxOne(vendor_id, product_id)) { + return SDL_FALSE; + } +#endif + return (type == SDL_CONTROLLER_TYPE_XBOXONE) ? SDL_TRUE : SDL_FALSE; +} + +static SDL_bool HIDAPI_DriverXboxOne_InitDevice(SDL_HIDAPI_Device *device) +{ + SDL_DriverXboxOne_Context *ctx; + + ctx = (SDL_DriverXboxOne_Context *)SDL_calloc(1, sizeof(*ctx)); + if (!ctx) { + SDL_OutOfMemory(); + return SDL_FALSE; + } + ctx->device = device; + + device->context = ctx; + + ctx->vendor_id = device->vendor_id; + ctx->product_id = device->product_id; + ctx->bluetooth = SDL_IsJoystickBluetoothXboxOne(device->vendor_id, device->product_id); + ctx->start_time = SDL_GetTicks(); + ctx->sequence = 1; + ctx->has_color_led = ControllerHasColorLED(ctx->vendor_id, ctx->product_id); + ctx->has_paddles = ControllerHasPaddles(ctx->vendor_id, ctx->product_id); + ctx->has_trigger_rumble = ControllerHasTriggerRumble(ctx->vendor_id, ctx->product_id); + ctx->has_share_button = ControllerHasShareButton(ctx->vendor_id, ctx->product_id); + + /* Assume that the controller is correctly initialized when we start */ + if (ControllerNeedsNegotiation(ctx)) { + ctx->init_state = XBOX_ONE_INIT_STATE_START_NEGOTIATING; + } else { + ctx->init_state = XBOX_ONE_INIT_STATE_COMPLETE; + } + +#ifdef DEBUG_JOYSTICK + SDL_Log("Controller version: %d (0x%.4x)\n", device->version, device->version); +#endif + + device->type = SDL_CONTROLLER_TYPE_XBOXONE; + + return HIDAPI_JoystickConnected(device, NULL); +} + +static int HIDAPI_DriverXboxOne_GetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id) +{ + return -1; +} + +static void HIDAPI_DriverXboxOne_SetDevicePlayerIndex(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index) +{ +} + +static SDL_bool HIDAPI_DriverXboxOne_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_DriverXboxOne_Context *ctx = (SDL_DriverXboxOne_Context *)device->context; + + SDL_AssertJoysticksLocked(); + + ctx->low_frequency_rumble = 0; + ctx->high_frequency_rumble = 0; + ctx->left_trigger_rumble = 0; + ctx->right_trigger_rumble = 0; + ctx->rumble_state = XBOX_ONE_RUMBLE_STATE_IDLE; + ctx->rumble_time = 0; + ctx->rumble_pending = SDL_FALSE; + SDL_zeroa(ctx->last_state); + + /* Initialize the joystick capabilities */ + joystick->nbuttons = 15; + if (ctx->has_share_button) { + joystick->nbuttons += 1; + } + if (ctx->has_paddles) { + joystick->nbuttons += 4; + } + joystick->naxes = SDL_CONTROLLER_AXIS_MAX; + + if (!ctx->bluetooth) { + joystick->epowerlevel = SDL_JOYSTICK_POWER_WIRED; + } + + SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_XBOX_ONE_HOME_LED, + SDL_HomeLEDHintChanged, ctx); + return SDL_TRUE; +} + +static void HIDAPI_DriverXboxOne_RumbleSent(void *userdata) +{ + SDL_DriverXboxOne_Context *ctx = (SDL_DriverXboxOne_Context *)userdata; + ctx->rumble_time = SDL_GetTicks(); +} + +static int HIDAPI_DriverXboxOne_UpdateRumble(SDL_HIDAPI_Device *device) +{ + SDL_DriverXboxOne_Context *ctx = (SDL_DriverXboxOne_Context *)device->context; + + if (ctx->rumble_state == XBOX_ONE_RUMBLE_STATE_QUEUED) { + if (ctx->rumble_time) { + ctx->rumble_state = XBOX_ONE_RUMBLE_STATE_BUSY; + } + } + + if (ctx->rumble_state == XBOX_ONE_RUMBLE_STATE_BUSY) { + const Uint32 RUMBLE_BUSY_TIME_MS = ctx->bluetooth ? 50 : 10; + if (SDL_TICKS_PASSED(SDL_GetTicks(), ctx->rumble_time + RUMBLE_BUSY_TIME_MS)) { + ctx->rumble_time = 0; + ctx->rumble_state = XBOX_ONE_RUMBLE_STATE_IDLE; + } + } + + if (!ctx->rumble_pending) { + return 0; + } + + if (ctx->rumble_state != XBOX_ONE_RUMBLE_STATE_IDLE) { + return 0; + } + + /* We're no longer pending, even if we fail to send the rumble below */ + ctx->rumble_pending = SDL_FALSE; + + if (SDL_HIDAPI_LockRumble() != 0) { + return -1; + } + + if (ctx->bluetooth) { + Uint8 rumble_packet[] = { 0x03, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xEB }; + + rumble_packet[2] = ctx->left_trigger_rumble; + rumble_packet[3] = ctx->right_trigger_rumble; + rumble_packet[4] = ctx->low_frequency_rumble; + rumble_packet[5] = ctx->high_frequency_rumble; + + if (SDL_HIDAPI_SendRumbleWithCallbackAndUnlock(device, rumble_packet, sizeof(rumble_packet), HIDAPI_DriverXboxOne_RumbleSent, ctx) != sizeof(rumble_packet)) { + return SDL_SetError("Couldn't send rumble packet"); + } + } else { + Uint8 rumble_packet[] = { 0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xEB }; + + rumble_packet[6] = ctx->left_trigger_rumble; + rumble_packet[7] = ctx->right_trigger_rumble; + rumble_packet[8] = ctx->low_frequency_rumble; + rumble_packet[9] = ctx->high_frequency_rumble; + + if (SDL_HIDAPI_SendRumbleWithCallbackAndUnlock(device, rumble_packet, sizeof(rumble_packet), HIDAPI_DriverXboxOne_RumbleSent, ctx) != sizeof(rumble_packet)) { + return SDL_SetError("Couldn't send rumble packet"); + } + } + + ctx->rumble_state = XBOX_ONE_RUMBLE_STATE_QUEUED; + + return 0; +} + +static int HIDAPI_DriverXboxOne_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ + SDL_DriverXboxOne_Context *ctx = (SDL_DriverXboxOne_Context *)device->context; + + /* Magnitude is 1..100 so scale the 16-bit input here */ + ctx->low_frequency_rumble = low_frequency_rumble / 655; + ctx->high_frequency_rumble = high_frequency_rumble / 655; + ctx->rumble_pending = SDL_TRUE; + + return HIDAPI_DriverXboxOne_UpdateRumble(device); +} + +static int HIDAPI_DriverXboxOne_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) +{ + SDL_DriverXboxOne_Context *ctx = (SDL_DriverXboxOne_Context *)device->context; + + if (!ctx->has_trigger_rumble) { + return SDL_Unsupported(); + } + + /* Magnitude is 1..100 so scale the 16-bit input here */ + ctx->left_trigger_rumble = left_rumble / 655; + ctx->right_trigger_rumble = right_rumble / 655; + ctx->rumble_pending = SDL_TRUE; + + return HIDAPI_DriverXboxOne_UpdateRumble(device); +} + +static Uint32 HIDAPI_DriverXboxOne_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_DriverXboxOne_Context *ctx = (SDL_DriverXboxOne_Context *)device->context; + Uint32 result = 0; + + result |= SDL_JOYCAP_RUMBLE; + if (ctx->has_trigger_rumble) { + result |= SDL_JOYCAP_RUMBLE_TRIGGERS; + } + + if (ctx->has_color_led) { + result |= SDL_JOYCAP_LED; + } + + return result; +} + +static int HIDAPI_DriverXboxOne_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + SDL_DriverXboxOne_Context *ctx = (SDL_DriverXboxOne_Context *)device->context; + + if (ctx->has_color_led) { + Uint8 led_packet[] = { 0x0E, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + led_packet[5] = 0x00; /* Whiteness? Sets white intensity when RGB is 0, seems additive */ + led_packet[6] = red; + led_packet[7] = green; + led_packet[8] = blue; + + if (SDL_HIDAPI_SendRumble(device, led_packet, sizeof(led_packet)) != sizeof(led_packet)) { + return SDL_SetError("Couldn't send LED packet"); + } + return 0; + } else { + return SDL_Unsupported(); + } +} + +static int HIDAPI_DriverXboxOne_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + +static int HIDAPI_DriverXboxOne_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled) +{ + return SDL_Unsupported(); +} + +/* + * The Xbox One Elite controller with 5.13+ firmware sends the unmapped state in a separate packet. + * We can use this to send the paddle state when they aren't mapped + */ +static void HIDAPI_DriverXboxOne_HandleUnmappedStatePacket(SDL_Joystick *joystick, SDL_DriverXboxOne_Context *ctx, Uint8 *data, int size) +{ + Uint8 profile; + int paddle_index; + int button1_bit; + int button2_bit; + int button3_bit; + int button4_bit; + SDL_bool paddles_mapped; + + if (size == 21) { + /* XBox One Elite Series 2 */ + paddle_index = 18; + button1_bit = 0x01; + button2_bit = 0x02; + button3_bit = 0x04; + button4_bit = 0x08; + profile = data[19]; + + if (profile == 0) { + paddles_mapped = SDL_FALSE; + } else if (SDL_memcmp(&data[4], &ctx->last_state[4], 14) == 0) { + /* We're using a profile, but paddles aren't mapped */ + paddles_mapped = SDL_FALSE; + } else { + /* Something is mapped, we can't use the paddles */ + paddles_mapped = SDL_TRUE; + } + + } else { + /* Unknown format */ + return; + } +#ifdef DEBUG_XBOX_PROTOCOL + SDL_Log(">>> Paddles: %d,%d,%d,%d mapped = %s\n", + (data[paddle_index] & button1_bit) ? 1 : 0, + (data[paddle_index] & button2_bit) ? 1 : 0, + (data[paddle_index] & button3_bit) ? 1 : 0, + (data[paddle_index] & button4_bit) ? 1 : 0, + paddles_mapped ? "TRUE" : "FALSE"); +#endif + + if (paddles_mapped) { + /* Respect that the paddles are being used for other controls and don't pass them on to the app */ + data[paddle_index] = 0; + } + + if (ctx->last_paddle_state != data[paddle_index]) { + int nButton = SDL_CONTROLLER_BUTTON_MISC1 + ctx->has_share_button; /* Next available button */ + SDL_PrivateJoystickButton(joystick, nButton++, (data[paddle_index] & button1_bit) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, nButton++, (data[paddle_index] & button2_bit) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, nButton++, (data[paddle_index] & button3_bit) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, nButton++, (data[paddle_index] & button4_bit) ? SDL_PRESSED : SDL_RELEASED); + ctx->last_paddle_state = data[paddle_index]; + } + ctx->has_unmapped_state = SDL_TRUE; +} + +static void HIDAPI_DriverXboxOne_HandleStatePacket(SDL_Joystick *joystick, SDL_DriverXboxOne_Context *ctx, Uint8 *data, int size) +{ + Sint16 axis; + + /* Some controllers have larger packets over NDIS, but the real size is in data[3] */ + size = SDL_min(4 + data[3], size); + + /* Enable paddles on the Xbox Elite controller when connected over USB */ + if (ctx->has_paddles && !ctx->has_unmapped_state && size == 50) { + Uint8 packet[] = { 0x4d, 0x00, 0x00, 0x02, 0x07, 0x00 }; + + SDL_HIDAPI_SendRumble(ctx->device, packet, sizeof(packet)); + } + + if (ctx->last_state[4] != data[4]) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, (data[4] & 0x04) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data[4] & 0x08) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_A, (data[4] & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_B, (data[4] & 0x20) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_X, (data[4] & 0x40) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_Y, (data[4] & 0x80) ? SDL_PRESSED : SDL_RELEASED); + } + + if (ctx->last_state[5] != data[5]) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, (data[5] & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, (data[5] & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, (data[5] & 0x04) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, (data[5] & 0x08) ? SDL_PRESSED : SDL_RELEASED); + if (ctx->vendor_id == USB_VENDOR_RAZER && ctx->product_id == USB_PRODUCT_RAZER_ATROX) { + /* The Razer Atrox has the right and left shoulder bits reversed */ + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data[5] & 0x20) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data[5] & 0x10) ? SDL_PRESSED : SDL_RELEASED); + } else { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data[5] & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data[5] & 0x20) ? SDL_PRESSED : SDL_RELEASED); + } + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (data[5] & 0x40) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data[5] & 0x80) ? SDL_PRESSED : SDL_RELEASED); + } + + if (ctx->has_share_button) { + /* Xbox Series X firmware version 5.0, report is 36 bytes, share button is in byte 18 + * Xbox Series X firmware version 5.1, report is 44 bytes, share button is in byte 18 + * Xbox Series X firmware version 5.5, report is 48 bytes, share button is in byte 22 + * Victrix Gambit Tournament Controller, report is 50 bytes, share button is in byte 32 + * ThrustMaster eSwap PRO Controller Xbox, report is 64 bytes, share button is in byte 46 + */ + if (size < 48) { + if (ctx->last_state[18] != data[18]) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MISC1, (data[18] & 0x01) ? SDL_PRESSED : SDL_RELEASED); + } + } else if (size == 48) { + if (ctx->last_state[22] != data[22]) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MISC1, (data[22] & 0x01) ? SDL_PRESSED : SDL_RELEASED); + } + } else if (size == 50) { + if (ctx->last_state[32] != data[32]) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MISC1, (data[32] & 0x01) ? SDL_PRESSED : SDL_RELEASED); + } + } else if (size == 64) { + if (ctx->last_state[46] != data[46]) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MISC1, (data[46] & 0x01) ? SDL_PRESSED : SDL_RELEASED); + } + } + } + + /* Xbox One S report is 18 bytes + Xbox One Elite Series 1 report is 33 bytes, paddles in data[32], mode in data[32] & 0x10, both modes have mapped paddles by default + Paddle bits: + P3: 0x01 (A) P1: 0x02 (B) + P4: 0x04 (X) P2: 0x08 (Y) + Xbox One Elite Series 2 4.x firmware report is 38 bytes, paddles in data[18], mode in data[19], mode 0 has no mapped paddles by default + Paddle bits: + P3: 0x04 (A) P1: 0x01 (B) + P4: 0x08 (X) P2: 0x02 (Y) + Xbox One Elite Series 2 5.x firmware report is 50 bytes, paddles in data[22], mode in data[23], mode 0 has no mapped paddles by default + Paddle bits: + P3: 0x04 (A) P1: 0x01 (B) + P4: 0x08 (X) P2: 0x02 (Y) + */ + if (ctx->has_paddles && !ctx->has_unmapped_state && (size == 33 || size == 38 || size == 50)) { + int paddle_index; + int button1_bit; + int button2_bit; + int button3_bit; + int button4_bit; + SDL_bool paddles_mapped; + + if (size == 33) { + /* XBox One Elite Series 1 */ + paddle_index = 32; + button1_bit = 0x02; + button2_bit = 0x08; + button3_bit = 0x01; + button4_bit = 0x04; + + /* The mapped controller state is at offset 4, the raw state is at offset 18, compare them to see if the paddles are mapped */ + paddles_mapped = (SDL_memcmp(&data[4], &data[18], 2) != 0); + + } else if (size == 38) { + /* XBox One Elite Series 2 */ + paddle_index = 18; + button1_bit = 0x01; + button2_bit = 0x02; + button3_bit = 0x04; + button4_bit = 0x08; + paddles_mapped = (data[19] != 0); + + } else /* if (size == 50) */ { + /* XBox One Elite Series 2 */ + paddle_index = 22; + button1_bit = 0x01; + button2_bit = 0x02; + button3_bit = 0x04; + button4_bit = 0x08; + paddles_mapped = (data[23] != 0); + } +#ifdef DEBUG_XBOX_PROTOCOL + SDL_Log(">>> Paddles: %d,%d,%d,%d mapped = %s\n", + (data[paddle_index] & button1_bit) ? 1 : 0, + (data[paddle_index] & button2_bit) ? 1 : 0, + (data[paddle_index] & button3_bit) ? 1 : 0, + (data[paddle_index] & button4_bit) ? 1 : 0, + paddles_mapped ? "TRUE" : "FALSE"); +#endif + + if (paddles_mapped) { + /* Respect that the paddles are being used for other controls and don't pass them on to the app */ + data[paddle_index] = 0; + } + + if (ctx->last_paddle_state != data[paddle_index]) { + int nButton = SDL_CONTROLLER_BUTTON_MISC1 + ctx->has_share_button; /* Next available button */ + SDL_PrivateJoystickButton(joystick, nButton++, (data[paddle_index] & button1_bit) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, nButton++, (data[paddle_index] & button2_bit) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, nButton++, (data[paddle_index] & button3_bit) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, nButton++, (data[paddle_index] & button4_bit) ? SDL_PRESSED : SDL_RELEASED); + ctx->last_paddle_state = data[paddle_index]; + } + } + + axis = ((int)SDL_SwapLE16(*(Sint16 *)(&data[6])) * 64) - 32768; + if (axis == 32704) { + axis = 32767; + } + if (axis == -32768 && size == 30 && (data[22] & 0x80)) { + axis = 32767; + } + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, axis); + + axis = ((int)SDL_SwapLE16(*(Sint16 *)(&data[8])) * 64) - 32768; + if (axis == -32768 && size == 30 && (data[22] & 0x40)) { + axis = 32767; + } + if (axis == 32704) { + axis = 32767; + } + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, axis); + + axis = SDL_SwapLE16(*(Sint16 *)(&data[10])); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis); + axis = SDL_SwapLE16(*(Sint16 *)(&data[12])); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, ~axis); + axis = SDL_SwapLE16(*(Sint16 *)(&data[14])); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, axis); + axis = SDL_SwapLE16(*(Sint16 *)(&data[16])); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, ~axis); + + SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state))); + + /* We don't have the unmapped state for this packet */ + ctx->has_unmapped_state = SDL_FALSE; +} + +static void HIDAPI_DriverXboxOne_HandleStatusPacket(SDL_Joystick *joystick, SDL_DriverXboxOne_Context *ctx, Uint8 *data, int size) +{ + if (ctx->init_state < XBOX_ONE_INIT_STATE_COMPLETE) { + SetInitState(ctx, XBOX_ONE_INIT_STATE_COMPLETE); + } +} + +static void HIDAPI_DriverXboxOne_HandleModePacket(SDL_Joystick *joystick, SDL_DriverXboxOne_Context *ctx, const Uint8 *data, int size) +{ + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data[4] & 0x01) ? SDL_PRESSED : SDL_RELEASED); +} + +/* + * Xbox One S with firmware 3.1.1221 uses a 16 byte packet and the GUIDE button in a separate packet + */ +static void HIDAPI_DriverXboxOneBluetooth_HandleButtons16(SDL_Joystick *joystick, SDL_DriverXboxOne_Context *ctx, const Uint8 *data, int size) +{ + if (ctx->last_state[14] != data[14]) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_A, (data[14] & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_B, (data[14] & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_X, (data[14] & 0x04) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_Y, (data[14] & 0x08) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data[14] & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data[14] & 0x20) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data[14] & 0x40) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, (data[14] & 0x80) ? SDL_PRESSED : SDL_RELEASED); + } + + if (ctx->last_state[15] != data[15]) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (data[15] & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data[15] & 0x02) ? SDL_PRESSED : SDL_RELEASED); + } +} + +/* + * Xbox One S with firmware 4.8.1923 uses a 17 byte packet with BACK button in byte 16 and the GUIDE button in a separate packet (on Windows), or in byte 15 (on Linux) + * Xbox One S with firmware 5.x uses a 17 byte packet with BACK and GUIDE buttons in byte 15 + * Xbox One Elite Series 2 with firmware 4.7.1872 uses a 55 byte packet with BACK button in byte 16, paddles starting at byte 33, and the GUIDE button in a separate packet + * Xbox One Elite Series 2 with firmware 4.8.1908 uses a 33 byte packet with BACK button in byte 16, paddles starting at byte 17, and the GUIDE button in a separate packet + * Xbox One Elite Series 2 with firmware 5.11.3112 uses a 19 byte packet with BACK and GUIDE buttons in byte 15 + * Xbox Series X with firmware 5.5.2641 uses a 17 byte packet with BACK and GUIDE buttons in byte 15, and SHARE button in byte 17 + */ +static void HIDAPI_DriverXboxOneBluetooth_HandleButtons(SDL_Joystick *joystick, SDL_DriverXboxOne_Context *ctx, Uint8 *data, int size) +{ + if (ctx->last_state[14] != data[14]) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_A, (data[14] & 0x01) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_B, (data[14] & 0x02) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_X, (data[14] & 0x08) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_Y, (data[14] & 0x10) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, (data[14] & 0x40) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, (data[14] & 0x80) ? SDL_PRESSED : SDL_RELEASED); + } + + if (ctx->last_state[15] != data[15]) { + if (!ctx->has_guide_packet) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data[15] & 0x10) ? SDL_PRESSED : SDL_RELEASED); + } + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, (data[15] & 0x08) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, (data[15] & 0x20) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data[15] & 0x40) ? SDL_PRESSED : SDL_RELEASED); + } + + if (ctx->has_share_button) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data[15] & 0x04) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MISC1, (data[16] & 0x01) ? SDL_PRESSED : SDL_RELEASED); + } else { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, ((data[15] & 0x04) || (data[16] & 0x01)) ? SDL_PRESSED : SDL_RELEASED); + } + + /* + Paddle bits: + P3: 0x04 (A) P1: 0x01 (B) + P4: 0x08 (X) P2: 0x02 (Y) + */ + if (ctx->has_paddles && (size == 20 || size == 39 || size == 55)) { + int paddle_index; + int button1_bit; + int button2_bit; + int button3_bit; + int button4_bit; + SDL_bool paddles_mapped; + + if (size == 55) { + /* Initial firmware for the Xbox Elite Series 2 controller */ + paddle_index = 33; + button1_bit = 0x01; + button2_bit = 0x02; + button3_bit = 0x04; + button4_bit = 0x08; + paddles_mapped = (data[35] != 0); + } else if (size == 39) { + /* Updated firmware for the Xbox Elite Series 2 controller */ + paddle_index = 17; + button1_bit = 0x01; + button2_bit = 0x02; + button3_bit = 0x04; + button4_bit = 0x08; + paddles_mapped = (data[19] != 0); + } else /* if (size == 20) */ { + /* Updated firmware for the Xbox Elite Series 2 controller (5.13+) */ + paddle_index = 19; + button1_bit = 0x01; + button2_bit = 0x02; + button3_bit = 0x04; + button4_bit = 0x08; + paddles_mapped = (data[17] != 0); + } + +#ifdef DEBUG_XBOX_PROTOCOL + SDL_Log(">>> Paddles: %d,%d,%d,%d mapped = %s\n", + (data[paddle_index] & button1_bit) ? 1 : 0, + (data[paddle_index] & button2_bit) ? 1 : 0, + (data[paddle_index] & button3_bit) ? 1 : 0, + (data[paddle_index] & button4_bit) ? 1 : 0, + paddles_mapped ? "TRUE" : "FALSE"); +#endif + + if (paddles_mapped) { + /* Respect that the paddles are being used for other controls and don't pass them on to the app */ + data[paddle_index] = 0; + } + + if (ctx->last_paddle_state != data[paddle_index]) { + int nButton = SDL_CONTROLLER_BUTTON_MISC1; /* Next available button */ + SDL_PrivateJoystickButton(joystick, nButton++, (data[paddle_index] & button1_bit) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, nButton++, (data[paddle_index] & button2_bit) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, nButton++, (data[paddle_index] & button3_bit) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, nButton++, (data[paddle_index] & button4_bit) ? SDL_PRESSED : SDL_RELEASED); + ctx->last_paddle_state = data[paddle_index]; + } + } +} + +static void HIDAPI_DriverXboxOneBluetooth_HandleStatePacket(SDL_Joystick *joystick, SDL_DriverXboxOne_Context *ctx, Uint8 *data, int size) +{ + Sint16 axis; + + if (size == 16) { + /* Original Xbox One S, with separate report for guide button */ + HIDAPI_DriverXboxOneBluetooth_HandleButtons16(joystick, ctx, data, size); + } else if (size > 16) { + HIDAPI_DriverXboxOneBluetooth_HandleButtons(joystick, ctx, data, size); + } else { +#ifdef DEBUG_XBOX_PROTOCOL + SDL_Log("Unknown Bluetooth state packet format\n"); +#endif + return; + } + + if (ctx->last_state[13] != data[13]) { + SDL_bool dpad_up = SDL_FALSE; + SDL_bool dpad_down = SDL_FALSE; + SDL_bool dpad_left = SDL_FALSE; + SDL_bool dpad_right = SDL_FALSE; + + switch (data[13]) { + case 1: + dpad_up = SDL_TRUE; + break; + case 2: + dpad_up = SDL_TRUE; + dpad_right = SDL_TRUE; + break; + case 3: + dpad_right = SDL_TRUE; + break; + case 4: + dpad_right = SDL_TRUE; + dpad_down = SDL_TRUE; + break; + case 5: + dpad_down = SDL_TRUE; + break; + case 6: + dpad_left = SDL_TRUE; + dpad_down = SDL_TRUE; + break; + case 7: + dpad_left = SDL_TRUE; + break; + case 8: + dpad_up = SDL_TRUE; + dpad_left = SDL_TRUE; + break; + default: + break; + } + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, dpad_down); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, dpad_up); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, dpad_right); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, dpad_left); + } + + axis = ((int)SDL_SwapLE16(*(Sint16 *)(&data[9])) * 64) - 32768; + if (axis == 32704) { + axis = 32767; + } + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, axis); + + axis = ((int)SDL_SwapLE16(*(Sint16 *)(&data[11])) * 64) - 32768; + if (axis == 32704) { + axis = 32767; + } + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, axis); + + axis = (int)SDL_SwapLE16(*(Uint16 *)(&data[1])) - 0x8000; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis); + axis = (int)SDL_SwapLE16(*(Uint16 *)(&data[3])) - 0x8000; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, axis); + axis = (int)SDL_SwapLE16(*(Uint16 *)(&data[5])) - 0x8000; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, axis); + axis = (int)SDL_SwapLE16(*(Uint16 *)(&data[7])) - 0x8000; + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis); + + SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state))); +} + +static void HIDAPI_DriverXboxOneBluetooth_HandleGuidePacket(SDL_Joystick *joystick, SDL_DriverXboxOne_Context *ctx, const Uint8 *data, int size) +{ + ctx->has_guide_packet = SDL_TRUE; + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data[1] & 0x01) ? SDL_PRESSED : SDL_RELEASED); +} + +static void HIDAPI_DriverXboxOneBluetooth_HandleBatteryPacket(SDL_Joystick *joystick, SDL_DriverXboxOne_Context *ctx, const Uint8 *data, int size) +{ + Uint8 flags = data[1]; + SDL_bool on_usb = (((flags & 0x0C) >> 2) == 0); + + if (on_usb) { + /* Does this ever happen? */ + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_WIRED); + } else { + switch ((flags & 0x03)) { + case 0: + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_LOW); + break; + case 1: + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_MEDIUM); + break; + default: /* 2, 3 */ + SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_FULL); + break; + } + } +} + +#ifdef SET_SERIAL_AFTER_OPEN +static void HIDAPI_DriverXboxOne_HandleSerialIDPacket(SDL_Joystick *joystick, SDL_DriverXboxOne_Context *ctx, Uint8 *data, int size) +{ + char serial[29]; + int i; + + for (i = 0; i < 14; ++i) { + SDL_uitoa(data[6 + i], &serial[i * 2], 16); + } + serial[i * 2] = '\0'; + + if (!joystick->serial || SDL_strcmp(joystick->serial, serial) != 0) { +#ifdef DEBUG_JOYSTICK + SDL_Log("Setting serial number to %s\n", serial); +#endif + joystick->serial = SDL_strdup(serial); + } +} +#endif /* SET_SERIAL_AFTER_OPEN */ + +static SDL_bool HIDAPI_DriverXboxOne_UpdateInitState(SDL_HIDAPI_Device *device, SDL_DriverXboxOne_Context *ctx) +{ + SDL_XboxOneInitState prev_state; + do { + prev_state = ctx->init_state; + + switch (ctx->init_state) { + case XBOX_ONE_INIT_STATE_START_NEGOTIATING: +#if defined(__WIN32__) || defined(__WINGDK__) + /* The Windows driver is taking care of negotiation */ + SetInitState(ctx, XBOX_ONE_INIT_STATE_COMPLETE); +#else + SetInitState(ctx, XBOX_ONE_INIT_STATE_NEGOTIATING); + ctx->init_packet = 0; + if (!SendControllerInit(device, ctx)) { + return SDL_FALSE; + } +#endif + break; + case XBOX_ONE_INIT_STATE_NEGOTIATING: + if (SDL_TICKS_PASSED(SDL_GetTicks(), ctx->send_time + CONTROLLER_NEGOTIATION_TIMEOUT_MS)) { + /* We haven't heard anything, let's move on */ +#ifdef DEBUG_JOYSTICK + SDL_Log("Init sequence %d timed out after %u ms\n", ctx->init_packet, (SDL_GetTicks() - ctx->send_time)); +#endif + ++ctx->init_packet; + if (!SendControllerInit(device, ctx)) { + return SDL_FALSE; + } + } + break; + case XBOX_ONE_INIT_STATE_PREPARE_INPUT: + if (SDL_TICKS_PASSED(SDL_GetTicks(), ctx->send_time + CONTROLLER_PREPARE_INPUT_TIMEOUT_MS)) { +#ifdef DEBUG_JOYSTICK + SDL_Log("Prepare input complete after %u ms\n", (SDL_GetTicks() - ctx->send_time)); +#endif + SetInitState(ctx, XBOX_ONE_INIT_STATE_COMPLETE); + } + break; + case XBOX_ONE_INIT_STATE_COMPLETE: + break; + } + + } while (ctx->init_state != prev_state); + + return SDL_TRUE; +} + +static SDL_bool HIDAPI_DriverXboxOne_UpdateDevice(SDL_HIDAPI_Device *device) +{ + SDL_DriverXboxOne_Context *ctx = (SDL_DriverXboxOne_Context *)device->context; + SDL_Joystick *joystick = NULL; + Uint8 data[USB_PACKET_LENGTH]; + int size; + + if (device->num_joysticks > 0) { + joystick = SDL_JoystickFromInstanceID(device->joysticks[0]); + } else { + return SDL_FALSE; + } + + while ((size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) { +#ifdef DEBUG_XBOX_PROTOCOL + HIDAPI_DumpPacket("Xbox One packet: size = %d", data, size); +#endif + if (ctx->bluetooth) { + switch (data[0]) { + case 0x01: + if (!joystick) { + break; + } + if (size >= 16) { + HIDAPI_DriverXboxOneBluetooth_HandleStatePacket(joystick, ctx, data, size); + } else { +#ifdef DEBUG_JOYSTICK + SDL_Log("Unknown Xbox One Bluetooth packet size: %d\n", size); +#endif + } + break; + case 0x02: + if (!joystick) { + break; + } + HIDAPI_DriverXboxOneBluetooth_HandleGuidePacket(joystick, ctx, data, size); + break; + case 0x04: + if (!joystick) { + break; + } + HIDAPI_DriverXboxOneBluetooth_HandleBatteryPacket(joystick, ctx, data, size); + break; + default: +#ifdef DEBUG_JOYSTICK + SDL_Log("Unknown Xbox One packet: 0x%.2x\n", data[0]); +#endif + break; + } + } else { + switch (data[0]) { + case 0x01: + /* ACK packet */ + /* The data bytes are: + 0x01 0x20 NN 0x09, where NN is the packet sequence + then 0x00 + then a byte of the sequence being acked + then 0x20 + then 16-bit LE value, the size of the previous packet payload when it's a single packet + then 4 bytes of unknown data, often all zero + */ + break; + case 0x02: + /* Controller is connected and waiting for initialization */ + /* The data bytes are: + 0x02 0x20 NN 0x1c, where NN is the packet sequence + then 6 bytes of wireless MAC address + then 2 bytes padding + then 16-bit VID + then 16-bit PID + then 16-bit firmware version quartet AA.BB.CC.DD + e.g. 0x05 0x00 0x05 0x00 0x51 0x0a 0x00 0x00 + is firmware version 5.5.2641.0, and product version 0x0505 = 1285 + then 8 bytes of unknown data + */ + if (data[1] == 0x20) { +#ifdef DEBUG_JOYSTICK + SDL_Log("Controller announce after %u ms\n", (SDL_GetTicks() - ctx->start_time)); +#endif + SetInitState(ctx, XBOX_ONE_INIT_STATE_START_NEGOTIATING); + } else { + /* Possibly an announce from a device plugged into the controller */ + } + break; + case 0x03: + /* Controller status update */ + if (!joystick) { + /* We actually want to handle this packet any time it arrives */ + /*break;*/ + } + HIDAPI_DriverXboxOne_HandleStatusPacket(joystick, ctx, data, size); + break; + case 0x04: + /* Unknown chatty controller information, sent by both sides */ + break; + case 0x06: + /* Unknown chatty controller information, sent by both sides */ + break; + case 0x07: + if (!joystick) { + break; + } + HIDAPI_DriverXboxOne_HandleModePacket(joystick, ctx, data, size); + break; + case 0x0C: + if (!joystick) { + break; + } + HIDAPI_DriverXboxOne_HandleUnmappedStatePacket(joystick, ctx, data, size); + break; + case 0x1E: + /* If the packet starts with this: + 0x1E 0x30 0x07 0x10 0x04 0x00 + then the next 14 bytes are the controller serial number + e.g. 0x30 0x39 0x37 0x31 0x32 0x33 0x33 0x32 0x33 0x35 0x34 0x30 0x33 0x36 + is serial number "3039373132333332333534303336" + + The controller sends that in response to this request: + 0x1E 0x30 0x07 0x01 0x04 + */ + if (!joystick) { + break; + } +#ifdef SET_SERIAL_AFTER_OPEN + if (size == 20 && data[3] == 0x10) { + HIDAPI_DriverXboxOne_HandleSerialIDPacket(joystick, ctx, data, size); + } +#endif + break; + case 0x20: + if (ctx->init_state < XBOX_ONE_INIT_STATE_COMPLETE) { + SetInitState(ctx, XBOX_ONE_INIT_STATE_COMPLETE); + + /* Ignore the first input, it may be spurious */ +#ifdef DEBUG_JOYSTICK + SDL_Log("Controller ignoring spurious input\n"); +#endif + break; + } + if (!joystick) { + break; + } + HIDAPI_DriverXboxOne_HandleStatePacket(joystick, ctx, data, size); + break; + default: +#ifdef DEBUG_JOYSTICK + SDL_Log("Unknown Xbox One packet: 0x%.2x\n", data[0]); +#endif + break; + } + + SendAckIfNeeded(device, data, size); + + if (ctx->init_state == XBOX_ONE_INIT_STATE_NEGOTIATING) { + const SDL_DriverXboxOne_InitPacket *packet = &xboxone_init_packets[ctx->init_packet]; + + if (size >= 4 && data[0] == packet->response[0] && data[1] == packet->response[1]) { +#ifdef DEBUG_JOYSTICK + SDL_Log("Init sequence %d got response after %u ms\n", ctx->init_packet, (SDL_GetTicks() - ctx->send_time)); +#endif + ++ctx->init_packet; + SendControllerInit(device, ctx); + } + } + } + } + + HIDAPI_DriverXboxOne_UpdateInitState(device, ctx); + HIDAPI_DriverXboxOne_UpdateRumble(device); + + if (size < 0) { + /* Read error, device is disconnected */ + HIDAPI_JoystickDisconnected(device, device->joysticks[0]); + } + return size >= 0; +} + +static void HIDAPI_DriverXboxOne_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick) +{ + SDL_DriverXboxOne_Context *ctx = (SDL_DriverXboxOne_Context *)device->context; + + SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_XBOX_ONE_HOME_LED, + SDL_HomeLEDHintChanged, ctx); +} + +static void HIDAPI_DriverXboxOne_FreeDevice(SDL_HIDAPI_Device *device) +{ +} + +SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXboxOne = { + SDL_HINT_JOYSTICK_HIDAPI_XBOX_ONE, + SDL_TRUE, + HIDAPI_DriverXboxOne_RegisterHints, + HIDAPI_DriverXboxOne_UnregisterHints, + HIDAPI_DriverXboxOne_IsEnabled, + HIDAPI_DriverXboxOne_IsSupportedDevice, + HIDAPI_DriverXboxOne_InitDevice, + HIDAPI_DriverXboxOne_GetDevicePlayerIndex, + HIDAPI_DriverXboxOne_SetDevicePlayerIndex, + HIDAPI_DriverXboxOne_UpdateDevice, + HIDAPI_DriverXboxOne_OpenJoystick, + HIDAPI_DriverXboxOne_RumbleJoystick, + HIDAPI_DriverXboxOne_RumbleJoystickTriggers, + HIDAPI_DriverXboxOne_GetJoystickCapabilities, + HIDAPI_DriverXboxOne_SetJoystickLED, + HIDAPI_DriverXboxOne_SendJoystickEffect, + HIDAPI_DriverXboxOne_SetJoystickSensorsEnabled, + HIDAPI_DriverXboxOne_CloseJoystick, + HIDAPI_DriverXboxOne_FreeDevice, +}; + +#endif /* SDL_JOYSTICK_HIDAPI_XBOXONE */ + +#endif /* SDL_JOYSTICK_HIDAPI */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapijoystick.c b/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapijoystick.c new file mode 100644 index 0000000..0db0cbb --- /dev/null +++ b/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapijoystick.c @@ -0,0 +1,1684 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_JOYSTICK_HIDAPI + +#include "SDL_atomic.h" +#include "SDL_endian.h" +#include "SDL_hints.h" +#include "SDL_timer.h" +#include "SDL_joystick.h" +#include "../SDL_sysjoystick.h" +#include "SDL_hidapijoystick_c.h" +#include "SDL_hidapi_rumble.h" +#include "../../SDL_hints_c.h" + +#if defined(__WIN32__) || defined(__WINGDK__) +#include "../windows/SDL_rawinputjoystick_c.h" +#endif + +#ifdef SDL_USE_LIBUDEV +#include "../../core/linux/SDL_sandbox.h" +#endif + +struct joystick_hwdata +{ + SDL_HIDAPI_Device *device; +}; + +static SDL_HIDAPI_DeviceDriver *SDL_HIDAPI_drivers[] = { +#ifdef SDL_JOYSTICK_HIDAPI_GAMECUBE + &SDL_HIDAPI_DriverGameCube, +#endif +#ifdef SDL_JOYSTICK_HIDAPI_LUNA + &SDL_HIDAPI_DriverLuna, +#endif +#ifdef SDL_JOYSTICK_HIDAPI_SHIELD + &SDL_HIDAPI_DriverShield, +#endif +#ifdef SDL_JOYSTICK_HIDAPI_PS3 + &SDL_HIDAPI_DriverPS3, + &SDL_HIDAPI_DriverPS3ThirdParty, +#endif +#ifdef SDL_JOYSTICK_HIDAPI_PS4 + &SDL_HIDAPI_DriverPS4, +#endif +#ifdef SDL_JOYSTICK_HIDAPI_PS5 + &SDL_HIDAPI_DriverPS5, +#endif +#ifdef SDL_JOYSTICK_HIDAPI_STADIA + &SDL_HIDAPI_DriverStadia, +#endif +#ifdef SDL_JOYSTICK_HIDAPI_STEAM + &SDL_HIDAPI_DriverSteam, +#endif +#ifdef SDL_JOYSTICK_HIDAPI_STEAMDECK + &SDL_HIDAPI_DriverSteamDeck, +#endif +#ifdef SDL_JOYSTICK_HIDAPI_SWITCH + &SDL_HIDAPI_DriverNintendoClassic, + &SDL_HIDAPI_DriverJoyCons, + &SDL_HIDAPI_DriverSwitch, +#endif +#ifdef SDL_JOYSTICK_HIDAPI_WII + &SDL_HIDAPI_DriverWii, +#endif +#ifdef SDL_JOYSTICK_HIDAPI_XBOX360 + &SDL_HIDAPI_DriverXbox360, + &SDL_HIDAPI_DriverXbox360W, +#endif +#ifdef SDL_JOYSTICK_HIDAPI_XBOXONE + &SDL_HIDAPI_DriverXboxOne, +#endif +}; +static int SDL_HIDAPI_numdrivers = 0; +static SDL_SpinLock SDL_HIDAPI_spinlock; +static SDL_bool SDL_HIDAPI_hints_changed = SDL_FALSE; +static Uint32 SDL_HIDAPI_change_count = 0; +static SDL_HIDAPI_Device *SDL_HIDAPI_devices SDL_GUARDED_BY(SDL_joystick_lock); +static char SDL_HIDAPI_device_magic; +static int SDL_HIDAPI_numjoysticks = 0; +static SDL_bool SDL_HIDAPI_combine_joycons = SDL_TRUE; +static SDL_bool initialized = SDL_FALSE; +static SDL_bool shutting_down = SDL_FALSE; + +static char *HIDAPI_ConvertString(const wchar_t *wide_string) +{ + char *string = NULL; + + if (wide_string) { + string = SDL_iconv_string("UTF-8", "WCHAR_T", (char *)wide_string, (SDL_wcslen(wide_string) + 1) * sizeof(wchar_t)); + if (!string) { + switch (sizeof(wchar_t)) { + case 2: + string = SDL_iconv_string("UTF-8", "UCS-2-INTERNAL", (char *)wide_string, (SDL_wcslen(wide_string) + 1) * sizeof(wchar_t)); + break; + case 4: + string = SDL_iconv_string("UTF-8", "UCS-4-INTERNAL", (char *)wide_string, (SDL_wcslen(wide_string) + 1) * sizeof(wchar_t)); + break; + } + } + } + return string; +} + +void HIDAPI_DumpPacket(const char *prefix, const Uint8 *data, int size) +{ + int i; + char *buffer; + size_t length = SDL_strlen(prefix) + 11 * (USB_PACKET_LENGTH / 8) + (5 * USB_PACKET_LENGTH * 2) + 1 + 1; + int start = 0, amount = size; + size_t current_len; + + buffer = (char *)SDL_malloc(length); + current_len = SDL_snprintf(buffer, length, prefix, size); + for (i = start; i < start + amount; ++i) { + if ((i % 8) == 0) { + current_len += SDL_snprintf(&buffer[current_len], length - current_len, "\n%.2d: ", i); + } + current_len += SDL_snprintf(&buffer[current_len], length - current_len, " 0x%.2x", data[i]); + } + SDL_strlcat(buffer, "\n", length); + SDL_Log("%s", buffer); + SDL_free(buffer); +} + +SDL_bool HIDAPI_SupportsPlaystationDetection(Uint16 vendor, Uint16 product) +{ + /* If we already know the controller is a different type, don't try to detect it. + * This fixes a hang with the HORIPAD for Nintendo Switch (0x0f0d/0x00c1) + */ + if (SDL_GetJoystickGameControllerTypeFromVIDPID(vendor, product, NULL, SDL_FALSE) != SDL_CONTROLLER_TYPE_UNKNOWN) { + return SDL_FALSE; + } + + switch (vendor) { + case USB_VENDOR_DRAGONRISE: + return SDL_TRUE; + case USB_VENDOR_HORI: + return SDL_TRUE; + case USB_VENDOR_LOGITECH: + /* Most Logitech devices are not PlayStation controllers, and some of them + * lock up or reset when we send them the Sony third-party query feature + * report, so don't include that vendor here. Instead add devices as + * appropriate to controller_list.h + */ + return SDL_FALSE; + case USB_VENDOR_MADCATZ: + if (product == USB_PRODUCT_MADCATZ_SAITEK_SIDE_PANEL_CONTROL_DECK) { + /* This is not a Playstation compatible device */ + return SDL_FALSE; + } + return SDL_TRUE; + case USB_VENDOR_MAYFLASH: + return SDL_TRUE; + case USB_VENDOR_NACON: + case USB_VENDOR_NACON_ALT: + return SDL_TRUE; + case USB_VENDOR_PDP: + return SDL_TRUE; + case USB_VENDOR_POWERA: + return SDL_TRUE; + case USB_VENDOR_POWERA_ALT: + return SDL_TRUE; + case USB_VENDOR_QANBA: + return SDL_TRUE; + case USB_VENDOR_RAZER: + /* Most Razer devices are not PlayStation controllers, and some of them + * lock up or reset when we send them the Sony third-party query feature + * report, so don't include that vendor here. Instead add devices as + * appropriate to controller_list.h + * + * Reference: https://github.com/libsdl-org/SDL/issues/6733 + * https://github.com/libsdl-org/SDL/issues/6799 + */ + return SDL_FALSE; + case USB_VENDOR_SHANWAN: + return SDL_TRUE; + case USB_VENDOR_SHANWAN_ALT: + return SDL_TRUE; + case USB_VENDOR_THRUSTMASTER: + return SDL_TRUE; + case USB_VENDOR_ZEROPLUS: + return SDL_TRUE; + case 0x7545 /* SZ-MYPOWER */: + return SDL_TRUE; + default: + return SDL_FALSE; + } +} + +float HIDAPI_RemapVal(float val, float val_min, float val_max, float output_min, float output_max) +{ + return output_min + (output_max - output_min) * (val - val_min) / (val_max - val_min); +} + +static void HIDAPI_UpdateDeviceList(void); +static void HIDAPI_JoystickClose(SDL_Joystick *joystick); + +static SDL_GameControllerType SDL_GetJoystickGameControllerProtocol(const char *name, Uint16 vendor, Uint16 product, int interface_number, int interface_class, int interface_subclass, int interface_protocol) +{ + static const int LIBUSB_CLASS_VENDOR_SPEC = 0xFF; + static const int XB360_IFACE_SUBCLASS = 93; + static const int XB360_IFACE_PROTOCOL = 1; /* Wired */ + static const int XB360W_IFACE_PROTOCOL = 129; /* Wireless */ + static const int XBONE_IFACE_SUBCLASS = 71; + static const int XBONE_IFACE_PROTOCOL = 208; + + SDL_GameControllerType type = SDL_CONTROLLER_TYPE_UNKNOWN; + + /* This code should match the checks in libusb/hid.c and HIDDeviceManager.java */ + if (interface_class == LIBUSB_CLASS_VENDOR_SPEC && + interface_subclass == XB360_IFACE_SUBCLASS && + (interface_protocol == XB360_IFACE_PROTOCOL || + interface_protocol == XB360W_IFACE_PROTOCOL)) { + + static const int SUPPORTED_VENDORS[] = { + 0x0079, /* GPD Win 2 */ + 0x044f, /* Thrustmaster */ + 0x045e, /* Microsoft */ + 0x046d, /* Logitech */ + 0x056e, /* Elecom */ + 0x06a3, /* Saitek */ + 0x0738, /* Mad Catz */ + 0x07ff, /* Mad Catz */ + 0x0e6f, /* PDP */ + 0x0f0d, /* Hori */ + 0x1038, /* SteelSeries */ + 0x11c9, /* Nacon */ + 0x12ab, /* Unknown */ + 0x1430, /* RedOctane */ + 0x146b, /* BigBen */ + 0x1532, /* Razer */ + 0x15e4, /* Numark */ + 0x162e, /* Joytech */ + 0x1689, /* Razer Onza */ + 0x1949, /* Lab126, Inc. */ + 0x1bad, /* Harmonix */ + 0x20d6, /* PowerA */ + 0x24c6, /* PowerA */ + 0x2c22, /* Qanba */ + 0x2dc8, /* 8BitDo */ + 0x9886, /* ASTRO Gaming */ + }; + + int i; + for (i = 0; i < SDL_arraysize(SUPPORTED_VENDORS); ++i) { + if (vendor == SUPPORTED_VENDORS[i]) { + type = SDL_CONTROLLER_TYPE_XBOX360; + break; + } + } + } + + if (interface_number == 0 && + interface_class == LIBUSB_CLASS_VENDOR_SPEC && + interface_subclass == XBONE_IFACE_SUBCLASS && + interface_protocol == XBONE_IFACE_PROTOCOL) { + + static const int SUPPORTED_VENDORS[] = { + 0x03f0, /* HP */ + 0x044f, /* Thrustmaster */ + 0x045e, /* Microsoft */ + 0x0738, /* Mad Catz */ + 0x0b05, /* ASUS */ + 0x0e6f, /* PDP */ + 0x0f0d, /* Hori */ + 0x10f5, /* Turtle Beach */ + 0x1532, /* Razer */ + 0x20d6, /* PowerA */ + 0x24c6, /* PowerA */ + 0x2dc8, /* 8BitDo */ + 0x2e24, /* Hyperkin */ + 0x3537, /* GameSir */ + }; + + int i; + for (i = 0; i < SDL_arraysize(SUPPORTED_VENDORS); ++i) { + if (vendor == SUPPORTED_VENDORS[i]) { + type = SDL_CONTROLLER_TYPE_XBOXONE; + break; + } + } + } + + if (type == SDL_CONTROLLER_TYPE_UNKNOWN) { + type = SDL_GetJoystickGameControllerTypeFromVIDPID(vendor, product, name, SDL_FALSE); + } + return type; +} + +static SDL_bool HIDAPI_IsDeviceSupported(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name) +{ + int i; + SDL_GameControllerType type = SDL_GetJoystickGameControllerProtocol(name, vendor_id, product_id, -1, 0, 0, 0); + + for (i = 0; i < SDL_arraysize(SDL_HIDAPI_drivers); ++i) { + SDL_HIDAPI_DeviceDriver *driver = SDL_HIDAPI_drivers[i]; + if (driver->enabled && driver->IsSupportedDevice(NULL, name, type, vendor_id, product_id, version, -1, 0, 0, 0)) { + return SDL_TRUE; + } + } + return SDL_FALSE; +} + +static SDL_HIDAPI_DeviceDriver *HIDAPI_GetDeviceDriver(SDL_HIDAPI_Device *device) +{ + const Uint16 USAGE_PAGE_GENERIC_DESKTOP = 0x0001; + const Uint16 USAGE_JOYSTICK = 0x0004; + const Uint16 USAGE_GAMEPAD = 0x0005; + const Uint16 USAGE_MULTIAXISCONTROLLER = 0x0008; + int i; + + if (device->num_children > 0) { + return &SDL_HIDAPI_DriverCombined; + } + + if (SDL_ShouldIgnoreJoystick(device->name, device->guid)) { + return NULL; + } + + if (device->vendor_id != USB_VENDOR_VALVE) { + if (device->usage_page && device->usage_page != USAGE_PAGE_GENERIC_DESKTOP) { + return NULL; + } + if (device->usage && device->usage != USAGE_JOYSTICK && device->usage != USAGE_GAMEPAD && device->usage != USAGE_MULTIAXISCONTROLLER) { + return NULL; + } + } + + for (i = 0; i < SDL_arraysize(SDL_HIDAPI_drivers); ++i) { + SDL_HIDAPI_DeviceDriver *driver = SDL_HIDAPI_drivers[i]; + if (driver->enabled && driver->IsSupportedDevice(device, device->name, device->type, device->vendor_id, device->product_id, device->version, device->interface_number, device->interface_class, device->interface_subclass, device->interface_protocol)) { + return driver; + } + } + return NULL; +} + +static SDL_HIDAPI_Device *HIDAPI_GetDeviceByIndex(int device_index, SDL_JoystickID *pJoystickID) +{ + SDL_HIDAPI_Device *device; + + SDL_AssertJoysticksLocked(); + + for (device = SDL_HIDAPI_devices; device; device = device->next) { + if (device->parent) { + continue; + } + if (device->driver) { + if (device_index < device->num_joysticks) { + if (pJoystickID) { + *pJoystickID = device->joysticks[device_index]; + } + return device; + } + device_index -= device->num_joysticks; + } + } + return NULL; +} + +static SDL_HIDAPI_Device *HIDAPI_GetJoystickByInfo(const char *path, Uint16 vendor_id, Uint16 product_id) +{ + SDL_HIDAPI_Device *device; + + SDL_AssertJoysticksLocked(); + + for (device = SDL_HIDAPI_devices; device; device = device->next) { + if (device->vendor_id == vendor_id && device->product_id == product_id && + SDL_strcmp(device->path, path) == 0) { + break; + } + } + return device; +} + +static void HIDAPI_CleanupDeviceDriver(SDL_HIDAPI_Device *device) +{ + if (!device->driver) { + return; /* Already cleaned up */ + } + + /* Disconnect any joysticks */ + while (device->num_joysticks && device->joysticks) { + HIDAPI_JoystickDisconnected(device, device->joysticks[0]); + } + + device->driver->FreeDevice(device); + device->driver = NULL; + + SDL_LockMutex(device->dev_lock); + { + if (device->dev) { + SDL_hid_close(device->dev); + device->dev = NULL; + } + + if (device->context) { + SDL_free(device->context); + device->context = NULL; + } + } + SDL_UnlockMutex(device->dev_lock); +} + +static void HIDAPI_SetupDeviceDriver(SDL_HIDAPI_Device *device, SDL_bool *removed) SDL_NO_THREAD_SAFETY_ANALYSIS /* We unlock the joystick lock to be able to open the HID device on Android */ +{ + *removed = SDL_FALSE; + + if (device->driver) { + SDL_bool enabled; + + if (device->vendor_id == USB_VENDOR_NINTENDO && device->product_id == USB_PRODUCT_NINTENDO_SWITCH_JOYCON_PAIR) { + enabled = SDL_HIDAPI_combine_joycons; + } else { + enabled = device->driver->enabled; + } + if (device->children) { + int i; + + for (i = 0; i < device->num_children; ++i) { + SDL_HIDAPI_Device *child = device->children[i]; + if (!child->driver || !child->driver->enabled) { + enabled = SDL_FALSE; + break; + } + } + } + if (!enabled) { + HIDAPI_CleanupDeviceDriver(device); + } + return; /* Already setup */ + } + + if (HIDAPI_GetDeviceDriver(device)) { + /* We might have a device driver for this device, try opening it and see */ + if (device->num_children == 0) { + SDL_hid_device *dev; + + /* Wait a little bit for the device to initialize */ + SDL_Delay(10); + +#ifdef __ANDROID__ + /* On Android we need to leave joysticks unlocked because it calls + * out to the main thread for permissions and the main thread can + * be in the process of handling controller input. + * + * See https://github.com/libsdl-org/SDL/issues/6347 for details + */ + { + SDL_HIDAPI_Device *curr; + int lock_count = 0; + char *path = SDL_strdup(device->path); + + SDL_AssertJoysticksLocked(); + while (SDL_JoysticksLocked()) { + ++lock_count; + SDL_UnlockJoysticks(); + } + + dev = SDL_hid_open_path(path, 0); + + while (lock_count > 0) { + --lock_count; + SDL_LockJoysticks(); + } + SDL_free(path); + + /* Make sure the device didn't get removed while opening the HID path */ + for (curr = SDL_HIDAPI_devices; curr && curr != device; curr = curr->next) { + continue; + } + if (curr == NULL) { + *removed = SDL_TRUE; + if (dev) { + SDL_hid_close(dev); + } + return; + } + } +#else + /* On other platforms we want to keep the lock so other threads wait for + * us to finish opening the controller before checking to see whether the + * HIDAPI driver is handling the device. + * + * On Windows, for example, the main thread can be enumerating DirectInput + * devices while the Windows.Gaming.Input thread is calling back with a new + * controller available. + * + * See https://github.com/libsdl-org/SDL/issues/7304 for details. + */ + dev = SDL_hid_open_path(device->path, 0); +#endif + + if (dev == NULL) { + SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, + "HIDAPI_SetupDeviceDriver() couldn't open %s: %s\n", + device->path, SDL_GetError()); + return; + } + SDL_hid_set_nonblocking(dev, 1); + + device->dev = dev; + } + + device->driver = HIDAPI_GetDeviceDriver(device); + + /* Initialize the device, which may cause a connected event */ + if (device->driver && !device->driver->InitDevice(device)) { + HIDAPI_CleanupDeviceDriver(device); + } + + if (!device->driver && device->dev) { + /* No driver claimed this device, go ahead and close it */ + SDL_hid_close(device->dev); + device->dev = NULL; + } + } +} + +static void SDL_HIDAPI_UpdateDrivers(void) +{ + int i; + SDL_HIDAPI_Device *device; + SDL_bool removed; + + SDL_AssertJoysticksLocked(); + + SDL_HIDAPI_numdrivers = 0; + for (i = 0; i < SDL_arraysize(SDL_HIDAPI_drivers); ++i) { + SDL_HIDAPI_DeviceDriver *driver = SDL_HIDAPI_drivers[i]; + driver->enabled = driver->IsEnabled(); + if (driver->enabled && driver != &SDL_HIDAPI_DriverCombined) { + ++SDL_HIDAPI_numdrivers; + } + } + + removed = SDL_FALSE; + do { + for (device = SDL_HIDAPI_devices; device; device = device->next) { + HIDAPI_SetupDeviceDriver(device, &removed); + if (removed) { + break; + } + } + } while (removed); +} + +static void SDLCALL SDL_HIDAPIDriverHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + if (SDL_strcmp(name, SDL_HINT_JOYSTICK_HIDAPI_COMBINE_JOY_CONS) == 0) { + SDL_HIDAPI_combine_joycons = SDL_GetStringBoolean(hint, SDL_TRUE); + } + SDL_HIDAPI_hints_changed = SDL_TRUE; + SDL_HIDAPI_change_count = 0; +} + +static int HIDAPI_JoystickInit(void) +{ + int i; + + if (initialized) { + return 0; + } + +#if defined(SDL_USE_LIBUDEV) + if (linux_enumeration_method == ENUMERATION_UNSET) { + if (SDL_getenv("SDL_HIDAPI_JOYSTICK_DISABLE_UDEV") != NULL) { + SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, + "udev disabled by SDL_HIDAPI_JOYSTICK_DISABLE_UDEV"); + linux_enumeration_method = ENUMERATION_FALLBACK; + } else if (SDL_DetectSandbox() != SDL_SANDBOX_NONE) { + SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, + "Container detected, disabling HIDAPI udev integration"); + linux_enumeration_method = ENUMERATION_FALLBACK; + } else { + SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, + "Using udev for HIDAPI joystick device discovery"); + linux_enumeration_method = ENUMERATION_LIBUDEV; + } + } +#endif + + if (SDL_hid_init() < 0) { + return SDL_SetError("Couldn't initialize hidapi"); + } + + for (i = 0; i < SDL_arraysize(SDL_HIDAPI_drivers); ++i) { + SDL_HIDAPI_DeviceDriver *driver = SDL_HIDAPI_drivers[i]; + driver->RegisterHints(SDL_HIDAPIDriverHintChanged, driver); + } + SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_COMBINE_JOY_CONS, + SDL_HIDAPIDriverHintChanged, NULL); + SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI, + SDL_HIDAPIDriverHintChanged, NULL); + + SDL_HIDAPI_change_count = SDL_hid_device_change_count(); + HIDAPI_UpdateDeviceList(); + HIDAPI_UpdateDevices(); + + initialized = SDL_TRUE; + + return 0; +} + +static SDL_bool HIDAPI_AddJoystickInstanceToDevice(SDL_HIDAPI_Device *device, SDL_JoystickID joystickID) +{ + SDL_JoystickID *joysticks = (SDL_JoystickID *)SDL_realloc(device->joysticks, (device->num_joysticks + 1) * sizeof(*device->joysticks)); + if (!joysticks) { + return SDL_FALSE; + } + + device->joysticks = joysticks; + device->joysticks[device->num_joysticks++] = joystickID; + return SDL_TRUE; +} + +static SDL_bool HIDAPI_DelJoystickInstanceFromDevice(SDL_HIDAPI_Device *device, SDL_JoystickID joystickID) +{ + int i, size; + + for (i = 0; i < device->num_joysticks; ++i) { + if (device->joysticks[i] == joystickID) { + size = (device->num_joysticks - i - 1) * sizeof(SDL_JoystickID); + SDL_memmove(&device->joysticks[i], &device->joysticks[i + 1], size); + --device->num_joysticks; + if (device->num_joysticks == 0) { + SDL_free(device->joysticks); + device->joysticks = NULL; + } + return SDL_TRUE; + } + } + return SDL_FALSE; +} + +static SDL_bool HIDAPI_JoystickInstanceIsUnique(SDL_HIDAPI_Device *device, SDL_JoystickID joystickID) +{ + if (device->parent && device->num_joysticks == 1 && device->parent->num_joysticks == 1 && + device->joysticks[0] == device->parent->joysticks[0]) { + return SDL_FALSE; + } + return SDL_TRUE; +} + +void HIDAPI_SetDeviceName(SDL_HIDAPI_Device *device, const char *name) +{ + if (name && *name && SDL_strcmp(name, device->name) != 0) { + SDL_free(device->name); + device->name = SDL_strdup(name); + SDL_SetJoystickGUIDCRC(&device->guid, SDL_crc16(0, name, SDL_strlen(name))); + } +} + +void HIDAPI_SetDeviceProduct(SDL_HIDAPI_Device *device, Uint16 vendor_id, Uint16 product_id) +{ + /* Don't set the device product ID directly, or we'll constantly re-enumerate this device */ + device->guid = SDL_CreateJoystickGUID(device->guid.data[0], vendor_id, product_id, device->version, device->manufacturer_string, device->product_string, 'h', 0); +} + +static void HIDAPI_UpdateJoystickSerial(SDL_HIDAPI_Device *device) +{ + int i; + + for (i = 0; i < device->num_joysticks; ++i) { + SDL_Joystick *joystick = SDL_JoystickFromInstanceID(device->joysticks[i]); + if (joystick && device->serial) { + SDL_free(joystick->serial); + joystick->serial = SDL_strdup(device->serial); + } + } +} + +static SDL_bool HIDAPI_SerialIsEmpty(SDL_HIDAPI_Device *device) +{ + SDL_bool all_zeroes = SDL_TRUE; + + if (device->serial) { + const char *serial = device->serial; + for (serial = device->serial; *serial; ++serial) { + if (*serial != '0') { + all_zeroes = SDL_FALSE; + break; + } + } + } + return all_zeroes; +} + +void HIDAPI_SetDeviceSerial(SDL_HIDAPI_Device *device, const char *serial) +{ + if (serial && *serial && (!device->serial || SDL_strcmp(serial, device->serial) != 0)) { + SDL_free(device->serial); + device->serial = SDL_strdup(serial); + HIDAPI_UpdateJoystickSerial(device); + } +} + +static int wcstrcmp(const wchar_t *str1, const char *str2) +{ + int result; + + while (1) { + result = (*str1 - *str2); + if (result != 0 || *str1 == 0) { + break; + } + ++str1; + ++str2; + } + return result; +} + +static void HIDAPI_SetDeviceSerialW(SDL_HIDAPI_Device *device, const wchar_t *serial) +{ + if (serial && *serial && (!device->serial || wcstrcmp(serial, device->serial) != 0)) { + SDL_free(device->serial); + device->serial = HIDAPI_ConvertString(serial); + HIDAPI_UpdateJoystickSerial(device); + } +} + +SDL_bool HIDAPI_HasConnectedUSBDevice(const char *serial) +{ + SDL_HIDAPI_Device *device; + + SDL_AssertJoysticksLocked(); + + if (!serial) { + return SDL_FALSE; + } + + for (device = SDL_HIDAPI_devices; device; device = device->next) { + if (!device->driver) { + continue; + } + + if (device->is_bluetooth) { + continue; + } + + if (device->serial && SDL_strcmp(serial, device->serial) == 0) { + return SDL_TRUE; + } + } + return SDL_FALSE; +} + +void HIDAPI_DisconnectBluetoothDevice(const char *serial) +{ + SDL_HIDAPI_Device *device; + + SDL_AssertJoysticksLocked(); + + if (!serial) { + return; + } + + for (device = SDL_HIDAPI_devices; device; device = device->next) { + if (!device->driver) { + continue; + } + + if (!device->is_bluetooth) { + continue; + } + + if (device->serial && SDL_strcmp(serial, device->serial) == 0) { + while (device->num_joysticks && device->joysticks) { + HIDAPI_JoystickDisconnected(device, device->joysticks[0]); + } + } + } +} + +SDL_bool HIDAPI_JoystickConnected(SDL_HIDAPI_Device *device, SDL_JoystickID *pJoystickID) +{ + int i, j; + SDL_JoystickID joystickID; + + SDL_AssertJoysticksLocked(); + + for (i = 0; i < device->num_children; ++i) { + SDL_HIDAPI_Device *child = device->children[i]; + for (j = child->num_joysticks; j--;) { + HIDAPI_JoystickDisconnected(child, child->joysticks[j]); + } + } + + joystickID = SDL_GetNextJoystickInstanceID(); + HIDAPI_AddJoystickInstanceToDevice(device, joystickID); + + for (i = 0; i < device->num_children; ++i) { + SDL_HIDAPI_Device *child = device->children[i]; + HIDAPI_AddJoystickInstanceToDevice(child, joystickID); + } + + ++SDL_HIDAPI_numjoysticks; + + SDL_PrivateJoystickAdded(joystickID); + + if (pJoystickID) { + *pJoystickID = joystickID; + } + return SDL_TRUE; +} + +void HIDAPI_JoystickDisconnected(SDL_HIDAPI_Device *device, SDL_JoystickID joystickID) +{ + int i, j; + + SDL_LockJoysticks(); + + if (!HIDAPI_JoystickInstanceIsUnique(device, joystickID)) { + /* Disconnecting a child always disconnects the parent */ + device = device->parent; + } + + for (i = 0; i < device->num_joysticks; ++i) { + if (device->joysticks[i] == joystickID) { + SDL_Joystick *joystick = SDL_JoystickFromInstanceID(joystickID); + if (joystick) { + HIDAPI_JoystickClose(joystick); + } + + HIDAPI_DelJoystickInstanceFromDevice(device, joystickID); + + for (j = 0; j < device->num_children; ++j) { + SDL_HIDAPI_Device *child = device->children[j]; + HIDAPI_DelJoystickInstanceFromDevice(child, joystickID); + } + + --SDL_HIDAPI_numjoysticks; + + if (!shutting_down) { + SDL_PrivateJoystickRemoved(joystickID); + } + } + } + + /* Rescan the device list in case device state has changed */ + SDL_HIDAPI_change_count = 0; + + SDL_UnlockJoysticks(); +} + +static int HIDAPI_JoystickGetCount(void) +{ + return SDL_HIDAPI_numjoysticks; +} + +static SDL_HIDAPI_Device *HIDAPI_AddDevice(const struct SDL_hid_device_info *info, int num_children, SDL_HIDAPI_Device **children) +{ + SDL_HIDAPI_Device *device; + SDL_HIDAPI_Device *curr, *last = NULL; + SDL_bool removed; + + SDL_AssertJoysticksLocked(); + + for (curr = SDL_HIDAPI_devices, last = NULL; curr; last = curr, curr = curr->next) { + } + + device = (SDL_HIDAPI_Device *)SDL_calloc(1, sizeof(*device)); + if (!device) { + return NULL; + } + device->magic = &SDL_HIDAPI_device_magic; + device->path = SDL_strdup(info->path); + if (!device->path) { + SDL_free(device); + return NULL; + } + device->seen = SDL_TRUE; + device->vendor_id = info->vendor_id; + device->product_id = info->product_id; + device->version = info->release_number; + device->interface_number = info->interface_number; + device->interface_class = info->interface_class; + device->interface_subclass = info->interface_subclass; + device->interface_protocol = info->interface_protocol; + device->usage_page = info->usage_page; + device->usage = info->usage; + device->dev_lock = SDL_CreateMutex(); + + /* Need the device name before getting the driver to know whether to ignore this device */ + { + char *serial_number = HIDAPI_ConvertString(info->serial_number); + + device->manufacturer_string = HIDAPI_ConvertString(info->manufacturer_string); + device->product_string = HIDAPI_ConvertString(info->product_string); + device->name = SDL_CreateJoystickName(device->vendor_id, device->product_id, device->manufacturer_string, device->product_string); + + if (serial_number && *serial_number) { + device->serial = serial_number; + } else { + SDL_free(serial_number); + } + + if (!device->name) { + SDL_free(device->manufacturer_string); + SDL_free(device->product_string); + SDL_free(device->serial); + SDL_free(device->path); + SDL_free(device); + return NULL; + } + } + + /* FIXME: Is there any way to tell whether this is a Bluetooth device? */ + device->guid = SDL_CreateJoystickGUID(SDL_HARDWARE_BUS_USB, device->vendor_id, device->product_id, device->version, device->manufacturer_string, device->product_string, 'h', 0); + device->joystick_type = SDL_JOYSTICK_TYPE_GAMECONTROLLER; + device->type = SDL_GetJoystickGameControllerProtocol(device->name, device->vendor_id, device->product_id, device->interface_number, device->interface_class, device->interface_subclass, device->interface_protocol); + + if (num_children > 0) { + int i; + + device->num_children = num_children; + device->children = children; + for (i = 0; i < num_children; ++i) { + children[i]->parent = device; + } + } + + /* Add it to the list */ + if (last) { + last->next = device; + } else { + SDL_HIDAPI_devices = device; + } + + removed = SDL_FALSE; + HIDAPI_SetupDeviceDriver(device, &removed); + if (removed) { + return NULL; + } + +#ifdef DEBUG_HIDAPI + SDL_Log("Added HIDAPI device '%s' VID 0x%.4x, PID 0x%.4x, version %d, serial %s, interface %d, interface_class %d, interface_subclass %d, interface_protocol %d, usage page 0x%.4x, usage 0x%.4x, path = %s, driver = %s (%s)\n", device->name, device->vendor_id, device->product_id, device->version, + device->serial ? device->serial : "NONE", device->interface_number, device->interface_class, device->interface_subclass, device->interface_protocol, device->usage_page, device->usage, + device->path, device->driver ? device->driver->name : "NONE", device->driver && device->driver->enabled ? "ENABLED" : "DISABLED"); +#endif + + return device; +} + +static void HIDAPI_DelDevice(SDL_HIDAPI_Device *device) +{ + SDL_HIDAPI_Device *curr, *last; + int i; + + SDL_AssertJoysticksLocked(); + +#ifdef DEBUG_HIDAPI + SDL_Log("Removing HIDAPI device '%s' VID 0x%.4x, PID 0x%.4x, version %d, serial %s, interface %d, interface_class %d, interface_subclass %d, interface_protocol %d, usage page 0x%.4x, usage 0x%.4x, path = %s, driver = %s (%s)\n", device->name, device->vendor_id, device->product_id, device->version, + device->serial ? device->serial : "NONE", device->interface_number, device->interface_class, device->interface_subclass, device->interface_protocol, device->usage_page, device->usage, + device->path, device->driver ? device->driver->name : "NONE", device->driver && device->driver->enabled ? "ENABLED" : "DISABLED"); +#endif + + for (curr = SDL_HIDAPI_devices, last = NULL; curr; last = curr, curr = curr->next) { + if (curr == device) { + if (last) { + last->next = curr->next; + } else { + SDL_HIDAPI_devices = curr->next; + } + + HIDAPI_CleanupDeviceDriver(device); + + /* Make sure the rumble thread is done with this device */ + while (SDL_AtomicGet(&device->rumble_pending) > 0) { + SDL_Delay(10); + } + + for (i = 0; i < device->num_children; ++i) { + device->children[i]->parent = NULL; + } + + device->magic = NULL; + SDL_DestroyMutex(device->dev_lock); + SDL_free(device->manufacturer_string); + SDL_free(device->product_string); + SDL_free(device->serial); + SDL_free(device->name); + SDL_free(device->path); + SDL_free(device->children); + SDL_free(device); + return; + } + } +} + +static SDL_bool HIDAPI_CreateCombinedJoyCons() +{ + SDL_HIDAPI_Device *device, *combined; + SDL_HIDAPI_Device *joycons[2] = { NULL, NULL }; + + SDL_AssertJoysticksLocked(); + + if (!SDL_HIDAPI_combine_joycons) { + return SDL_FALSE; + } + + for (device = SDL_HIDAPI_devices; device; device = device->next) { + Uint16 vendor, product; + + if (!device->driver) { + /* Unsupported device */ + continue; + } + if (device->parent) { + /* This device is already part of a combined device */ + continue; + } + + SDL_GetJoystickGUIDInfo(device->guid, &vendor, &product, NULL, NULL); + + if (!joycons[0] && + (SDL_IsJoystickNintendoSwitchJoyConLeft(vendor, product) || + (SDL_IsJoystickNintendoSwitchJoyConGrip(vendor, product) && + SDL_strstr(device->name, "(L)") != NULL))) { + joycons[0] = device; + } + if (!joycons[1] && + (SDL_IsJoystickNintendoSwitchJoyConRight(vendor, product) || + (SDL_IsJoystickNintendoSwitchJoyConGrip(vendor, product) && + SDL_strstr(device->name, "(R)") != NULL))) { + joycons[1] = device; + } + if (joycons[0] && joycons[1]) { + SDL_hid_device_info info; + SDL_HIDAPI_Device **children = (SDL_HIDAPI_Device **)SDL_malloc(2 * sizeof(SDL_HIDAPI_Device *)); + if (!children) { + return SDL_FALSE; + } + children[0] = joycons[0]; + children[1] = joycons[1]; + + SDL_zero(info); + info.path = "nintendo_joycons_combined"; + info.vendor_id = USB_VENDOR_NINTENDO; + info.product_id = USB_PRODUCT_NINTENDO_SWITCH_JOYCON_PAIR; + info.interface_number = -1; + info.usage_page = USB_USAGEPAGE_GENERIC_DESKTOP; + info.usage = USB_USAGE_GENERIC_GAMEPAD; + info.manufacturer_string = L"Nintendo"; + info.product_string = L"Switch Joy-Con (L/R)"; + + combined = HIDAPI_AddDevice(&info, 2, children); + if (combined && combined->driver) { + return SDL_TRUE; + } else { + if (combined) { + HIDAPI_DelDevice(combined); + } else { + SDL_free(children); + } + return SDL_FALSE; + } + } + } + return SDL_FALSE; +} + +static void HIDAPI_UpdateDeviceList(void) +{ + SDL_HIDAPI_Device *device; + struct SDL_hid_device_info *devs, *info; + + SDL_LockJoysticks(); + + if (SDL_HIDAPI_hints_changed) { + SDL_HIDAPI_UpdateDrivers(); + SDL_HIDAPI_hints_changed = SDL_FALSE; + } + + /* Prepare the existing device list */ + for (device = SDL_HIDAPI_devices; device; device = device->next) { + if (device->children) { + continue; + } + device->seen = SDL_FALSE; + } + + /* Enumerate the devices */ + if (SDL_HIDAPI_numdrivers > 0) { + devs = SDL_hid_enumerate(0, 0); + if (devs) { + for (info = devs; info; info = info->next) { + device = HIDAPI_GetJoystickByInfo(info->path, info->vendor_id, info->product_id); + if (device) { + device->seen = SDL_TRUE; + + /* Check to see if the serial number is available now */ + if(HIDAPI_SerialIsEmpty(device)) { + HIDAPI_SetDeviceSerialW(device, info->serial_number); + } + } else { + HIDAPI_AddDevice(info, 0, NULL); + } + } + SDL_hid_free_enumeration(devs); + } + } + + /* Remove any devices that weren't seen or have been disconnected due to read errors */ +check_removed: + device = SDL_HIDAPI_devices; + while (device) { + SDL_HIDAPI_Device *next = device->next; + + if (!device->seen || + ((device->driver || device->children) && device->num_joysticks == 0 && !device->dev)) { + if (device->parent) { + /* When a child device goes away, so does the parent */ + int i; + device = device->parent; + for (i = 0; i < device->num_children; ++i) { + HIDAPI_DelDevice(device->children[i]); + } + HIDAPI_DelDevice(device); + + /* Update the device list again to pick up any children left */ + SDL_HIDAPI_change_count = 0; + + /* We deleted more than one device here, restart the loop */ + goto check_removed; + } else { + HIDAPI_DelDevice(device); + + /* Update the device list again in case this device comes back */ + SDL_HIDAPI_change_count = 0; + } + } + device = next; + } + + /* See if we can create any combined Joy-Con controllers */ + while (HIDAPI_CreateCombinedJoyCons()) { + } + + SDL_UnlockJoysticks(); +} + +static SDL_bool HIDAPI_IsEquivalentToDevice(Uint16 vendor_id, Uint16 product_id, SDL_HIDAPI_Device *device) +{ + if (vendor_id == device->vendor_id && product_id == device->product_id) { + return SDL_TRUE; + } + + if (vendor_id == USB_VENDOR_MICROSOFT) { + /* If we're looking for the wireless XBox 360 controller, also look for the dongle */ + if (product_id == USB_PRODUCT_XBOX360_XUSB_CONTROLLER && device->product_id == USB_PRODUCT_XBOX360_WIRELESS_RECEIVER) { + return SDL_TRUE; + } + + /* If we're looking for the raw input Xbox One controller, match it against any other Xbox One controller */ + if (product_id == USB_PRODUCT_XBOX_ONE_XBOXGIP_CONTROLLER && + device->type == SDL_CONTROLLER_TYPE_XBOXONE) { + return SDL_TRUE; + } + + /* If we're looking for an XInput controller, match it against any other Xbox controller */ + if (product_id == USB_PRODUCT_XBOX360_XUSB_CONTROLLER) { + if (device->type == SDL_CONTROLLER_TYPE_XBOX360 || device->type == SDL_CONTROLLER_TYPE_XBOXONE) { + return SDL_TRUE; + } + } + } + + if (vendor_id == USB_VENDOR_NVIDIA) { + /* If we're looking for the NVIDIA SHIELD controller Xbox interface, match it against any NVIDIA SHIELD controller */ + if (product_id == 0xb400 && + device->type == SDL_CONTROLLER_TYPE_NVIDIA_SHIELD) { + return SDL_TRUE; + } + } + return SDL_FALSE; +} + +SDL_bool HIDAPI_IsDeviceTypePresent(SDL_GameControllerType type) +{ + SDL_HIDAPI_Device *device; + SDL_bool result = SDL_FALSE; + + /* Make sure we're initialized, as this could be called from other drivers during startup */ + if (HIDAPI_JoystickInit() < 0) { + return SDL_FALSE; + } + + if (SDL_AtomicTryLock(&SDL_HIDAPI_spinlock)) { + HIDAPI_UpdateDeviceList(); + SDL_AtomicUnlock(&SDL_HIDAPI_spinlock); + } + + SDL_LockJoysticks(); + for (device = SDL_HIDAPI_devices; device; device = device->next) { + if (device->driver && device->type == type) { + result = SDL_TRUE; + break; + } + } + SDL_UnlockJoysticks(); + +#ifdef DEBUG_HIDAPI + SDL_Log("HIDAPI_IsDeviceTypePresent() returning %s for %d\n", result ? "true" : "false", type); +#endif + return result; +} + +SDL_bool HIDAPI_IsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name) +{ + SDL_HIDAPI_Device *device; + SDL_bool supported = SDL_FALSE; + SDL_bool result = SDL_FALSE; + + /* Make sure we're initialized, as this could be called from other drivers during startup */ + if (HIDAPI_JoystickInit() < 0) { + return SDL_FALSE; + } + + /* Only update the device list for devices we know might be supported. + If we did this for every device, it would hit the USB driver too hard and potentially + lock up the system. This won't catch devices that we support but can only detect using + USB interface details, like Xbox controllers, but hopefully the device list update is + responsive enough to catch those. + */ + supported = HIDAPI_IsDeviceSupported(vendor_id, product_id, version, name); +#if defined(SDL_JOYSTICK_HIDAPI_XBOX360) || defined(SDL_JOYSTICK_HIDAPI_XBOXONE) + if (!supported && + (SDL_strstr(name, "Xbox") || SDL_strstr(name, "X-Box") || SDL_strstr(name, "XBOX"))) { + supported = SDL_TRUE; + } +#endif /* SDL_JOYSTICK_HIDAPI_XBOX360 || SDL_JOYSTICK_HIDAPI_XBOXONE */ + if (supported) { + if (SDL_AtomicTryLock(&SDL_HIDAPI_spinlock)) { + HIDAPI_UpdateDeviceList(); + SDL_AtomicUnlock(&SDL_HIDAPI_spinlock); + } + } + + /* Note that this isn't a perfect check - there may be multiple devices with 0 VID/PID, + or a different name than we have it listed here, etc, but if we support the device + and we have something similar in our device list, mark it as present. + */ + SDL_LockJoysticks(); + for (device = SDL_HIDAPI_devices; device; device = device->next) { + if (device->driver && + HIDAPI_IsEquivalentToDevice(vendor_id, product_id, device)) { + result = SDL_TRUE; + break; + } + } + SDL_UnlockJoysticks(); + +#ifdef DEBUG_HIDAPI + SDL_Log("HIDAPI_IsDevicePresent() returning %s for 0x%.4x / 0x%.4x\n", result ? "true" : "false", vendor_id, product_id); +#endif + return result; +} + +SDL_JoystickType HIDAPI_GetJoystickTypeFromGUID(SDL_JoystickGUID guid) +{ + SDL_HIDAPI_Device *device; + SDL_JoystickType type = SDL_JOYSTICK_TYPE_UNKNOWN; + + SDL_LockJoysticks(); + for (device = SDL_HIDAPI_devices; device; device = device->next) { + if (SDL_memcmp(&guid, &device->guid, sizeof(guid)) == 0) { + type = device->joystick_type; + break; + } + } + SDL_UnlockJoysticks(); + + return type; +} + +SDL_GameControllerType HIDAPI_GetGameControllerTypeFromGUID(SDL_JoystickGUID guid) +{ + SDL_HIDAPI_Device *device; + SDL_GameControllerType type = SDL_CONTROLLER_TYPE_UNKNOWN; + + SDL_LockJoysticks(); + for (device = SDL_HIDAPI_devices; device; device = device->next) { + if (SDL_memcmp(&guid, &device->guid, sizeof(guid)) == 0) { + type = device->type; + break; + } + } + SDL_UnlockJoysticks(); + + return type; +} + +static void HIDAPI_JoystickDetect(void) +{ + if (SDL_AtomicTryLock(&SDL_HIDAPI_spinlock)) { + Uint32 count = SDL_hid_device_change_count(); + if (SDL_HIDAPI_change_count != count) { + SDL_HIDAPI_change_count = count; + HIDAPI_UpdateDeviceList(); + } + SDL_AtomicUnlock(&SDL_HIDAPI_spinlock); + } +} + +void HIDAPI_UpdateDevices(void) +{ + SDL_HIDAPI_Device *device; + + SDL_AssertJoysticksLocked(); + + /* Update the devices, which may change connected joysticks and send events */ + + /* Prepare the existing device list */ + if (SDL_AtomicTryLock(&SDL_HIDAPI_spinlock)) { + for (device = SDL_HIDAPI_devices; device; device = device->next) { + if (device->parent) { + continue; + } + if (device->driver) { + if (SDL_TryLockMutex(device->dev_lock) == 0) { + device->updating = SDL_TRUE; + device->driver->UpdateDevice(device); + device->updating = SDL_FALSE; + SDL_UnlockMutex(device->dev_lock); + } + } + } + SDL_AtomicUnlock(&SDL_HIDAPI_spinlock); + } +} + +static const char *HIDAPI_JoystickGetDeviceName(int device_index) +{ + SDL_HIDAPI_Device *device; + const char *name = NULL; + + device = HIDAPI_GetDeviceByIndex(device_index, NULL); + if (device) { + /* FIXME: The device could be freed after this name is returned... */ + name = device->name; + } + + return name; +} + +static const char *HIDAPI_JoystickGetDevicePath(int device_index) +{ + SDL_HIDAPI_Device *device; + const char *path = NULL; + + device = HIDAPI_GetDeviceByIndex(device_index, NULL); + if (device) { + /* FIXME: The device could be freed after this path is returned... */ + path = device->path; + } + + return path; +} + +static int HIDAPI_JoystickGetDeviceSteamVirtualGamepadSlot(int device_index) +{ + return -1; +} + +static int HIDAPI_JoystickGetDevicePlayerIndex(int device_index) +{ + SDL_HIDAPI_Device *device; + SDL_JoystickID instance_id; + int player_index = -1; + + device = HIDAPI_GetDeviceByIndex(device_index, &instance_id); + if (device) { + player_index = device->driver->GetDevicePlayerIndex(device, instance_id); + } + + return player_index; +} + +static void HIDAPI_JoystickSetDevicePlayerIndex(int device_index, int player_index) +{ + SDL_HIDAPI_Device *device; + SDL_JoystickID instance_id; + + device = HIDAPI_GetDeviceByIndex(device_index, &instance_id); + if (device) { + device->driver->SetDevicePlayerIndex(device, instance_id, player_index); + } +} + +static SDL_JoystickGUID HIDAPI_JoystickGetDeviceGUID(int device_index) +{ + SDL_HIDAPI_Device *device; + SDL_JoystickGUID guid; + + device = HIDAPI_GetDeviceByIndex(device_index, NULL); + if (device) { + SDL_memcpy(&guid, &device->guid, sizeof(guid)); + } else { + SDL_zero(guid); + } + + return guid; +} + +static SDL_JoystickID HIDAPI_JoystickGetDeviceInstanceID(int device_index) +{ + SDL_JoystickID joystickID = -1; + HIDAPI_GetDeviceByIndex(device_index, &joystickID); + return joystickID; +} + +static int HIDAPI_JoystickOpen(SDL_Joystick *joystick, int device_index) +{ + SDL_JoystickID joystickID = -1; + SDL_HIDAPI_Device *device = HIDAPI_GetDeviceByIndex(device_index, &joystickID); + struct joystick_hwdata *hwdata; + + SDL_AssertJoysticksLocked(); + + if (!device || !device->driver) { + /* This should never happen - validated before being called */ + return SDL_SetError("Couldn't find HIDAPI device at index %d\n", device_index); + } + + hwdata = (struct joystick_hwdata *)SDL_calloc(1, sizeof(*hwdata)); + if (!hwdata) { + return SDL_OutOfMemory(); + } + hwdata->device = device; + + /* Process any pending reports before opening the device */ + SDL_LockMutex(device->dev_lock); + device->updating = SDL_TRUE; + device->driver->UpdateDevice(device); + device->updating = SDL_FALSE; + SDL_UnlockMutex(device->dev_lock); + + /* UpdateDevice() may have called HIDAPI_JoystickDisconnected() if the device went away */ + if (device->num_joysticks == 0) { + SDL_free(hwdata); + return SDL_SetError("HIDAPI device disconnected while opening"); + } + + if (!device->driver->OpenJoystick(device, joystick)) { + /* The open failed, mark this device as disconnected and update devices */ + HIDAPI_JoystickDisconnected(device, joystickID); + SDL_free(hwdata); + return -1; + } + + if (device->serial) { + joystick->serial = SDL_strdup(device->serial); + } + + joystick->hwdata = hwdata; + return 0; +} + +static SDL_bool HIDAPI_GetJoystickDevice(SDL_Joystick *joystick, SDL_HIDAPI_Device **device) +{ + SDL_AssertJoysticksLocked(); + + if (joystick && joystick->hwdata) { + *device = joystick->hwdata->device; + if (*device && (*device)->magic == &SDL_HIDAPI_device_magic && (*device)->driver != NULL) { + return SDL_TRUE; + } + } + return SDL_FALSE; +} + +static int HIDAPI_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ + int result; + SDL_HIDAPI_Device *device = NULL; + + if (HIDAPI_GetJoystickDevice(joystick, &device)) { + result = device->driver->RumbleJoystick(device, joystick, low_frequency_rumble, high_frequency_rumble); + } else { + result = SDL_SetError("Rumble failed, device disconnected"); + } + + return result; +} + +static int HIDAPI_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) +{ + int result; + SDL_HIDAPI_Device *device = NULL; + + if (HIDAPI_GetJoystickDevice(joystick, &device)) { + result = device->driver->RumbleJoystickTriggers(device, joystick, left_rumble, right_rumble); + } else { + result = SDL_SetError("Rumble failed, device disconnected"); + } + + return result; +} + +static Uint32 HIDAPI_JoystickGetCapabilities(SDL_Joystick *joystick) +{ + Uint32 result = 0; + SDL_HIDAPI_Device *device = NULL; + + if (HIDAPI_GetJoystickDevice(joystick, &device)) { + result = device->driver->GetJoystickCapabilities(device, joystick); + } + + return result; +} + +static int HIDAPI_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + int result; + SDL_HIDAPI_Device *device = NULL; + + if (HIDAPI_GetJoystickDevice(joystick, &device)) { + result = device->driver->SetJoystickLED(device, joystick, red, green, blue); + } else { + result = SDL_SetError("SetLED failed, device disconnected"); + } + + return result; +} + +static int HIDAPI_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) +{ + int result; + SDL_HIDAPI_Device *device = NULL; + + if (HIDAPI_GetJoystickDevice(joystick, &device)) { + result = device->driver->SendJoystickEffect(device, joystick, data, size); + } else { + result = SDL_SetError("SendEffect failed, device disconnected"); + } + + return result; +} + +static int HIDAPI_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled) +{ + int result; + SDL_HIDAPI_Device *device = NULL; + + if (HIDAPI_GetJoystickDevice(joystick, &device)) { + result = device->driver->SetJoystickSensorsEnabled(device, joystick, enabled); + } else { + result = SDL_SetError("SetSensorsEnabled failed, device disconnected"); + } + + return result; +} + +static void HIDAPI_JoystickUpdate(SDL_Joystick *joystick) +{ + /* This is handled in SDL_HIDAPI_UpdateDevices() */ +} + +static void HIDAPI_JoystickClose(SDL_Joystick *joystick) SDL_NO_THREAD_SAFETY_ANALYSIS /* We unlock the device lock so rumble can complete */ +{ + SDL_AssertJoysticksLocked(); + + if (joystick->hwdata) { + SDL_HIDAPI_Device *device = joystick->hwdata->device; + int i; + + /* Wait up to 30 ms for pending rumble to complete */ + if (device->updating) { + /* Unlock the device so rumble can complete */ + SDL_UnlockMutex(device->dev_lock); + } + for (i = 0; i < 3; ++i) { + if (SDL_AtomicGet(&device->rumble_pending) > 0) { + SDL_Delay(10); + } + } + if (device->updating) { + /* Relock the device */ + SDL_LockMutex(device->dev_lock); + } + + device->driver->CloseJoystick(device, joystick); + + SDL_free(joystick->hwdata); + joystick->hwdata = NULL; + } +} + +static void HIDAPI_JoystickQuit(void) +{ + int i; + + SDL_AssertJoysticksLocked(); + + shutting_down = SDL_TRUE; + + SDL_HIDAPI_QuitRumble(); + + while (SDL_HIDAPI_devices) { + SDL_HIDAPI_Device *device = SDL_HIDAPI_devices; + if (device->parent) { + /* When a child device goes away, so does the parent */ + device = device->parent; + for (i = 0; i < device->num_children; ++i) { + HIDAPI_DelDevice(device->children[i]); + } + HIDAPI_DelDevice(device); + } else { + HIDAPI_DelDevice(device); + } + } + + /* Make sure the drivers cleaned up properly */ + SDL_assert(SDL_HIDAPI_numjoysticks == 0); + + for (i = 0; i < SDL_arraysize(SDL_HIDAPI_drivers); ++i) { + SDL_HIDAPI_DeviceDriver *driver = SDL_HIDAPI_drivers[i]; + driver->UnregisterHints(SDL_HIDAPIDriverHintChanged, driver); + } + SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI_COMBINE_JOY_CONS, + SDL_HIDAPIDriverHintChanged, NULL); + SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI, + SDL_HIDAPIDriverHintChanged, NULL); + + SDL_hid_exit(); + + SDL_HIDAPI_change_count = 0; + shutting_down = SDL_FALSE; + initialized = SDL_FALSE; +} + +static SDL_bool HIDAPI_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) +{ + return SDL_FALSE; +} + +SDL_JoystickDriver SDL_HIDAPI_JoystickDriver = { + HIDAPI_JoystickInit, + HIDAPI_JoystickGetCount, + HIDAPI_JoystickDetect, + HIDAPI_JoystickGetDeviceName, + HIDAPI_JoystickGetDevicePath, + HIDAPI_JoystickGetDeviceSteamVirtualGamepadSlot, + HIDAPI_JoystickGetDevicePlayerIndex, + HIDAPI_JoystickSetDevicePlayerIndex, + HIDAPI_JoystickGetDeviceGUID, + HIDAPI_JoystickGetDeviceInstanceID, + HIDAPI_JoystickOpen, + HIDAPI_JoystickRumble, + HIDAPI_JoystickRumbleTriggers, + HIDAPI_JoystickGetCapabilities, + HIDAPI_JoystickSetLED, + HIDAPI_JoystickSendEffect, + HIDAPI_JoystickSetSensorsEnabled, + HIDAPI_JoystickUpdate, + HIDAPI_JoystickClose, + HIDAPI_JoystickQuit, + HIDAPI_JoystickGetGamepadMapping +}; + +#endif /* SDL_JOYSTICK_HIDAPI */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapijoystick_c.h b/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapijoystick_c.h new file mode 100644 index 0000000..738c43a --- /dev/null +++ b/SDL2-2.30.5/src/joystick/hidapi/SDL_hidapijoystick_c.h @@ -0,0 +1,181 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifndef SDL_JOYSTICK_HIDAPI_H +#define SDL_JOYSTICK_HIDAPI_H + +#include "SDL_atomic.h" +#include "SDL_hints.h" +#include "SDL_mutex.h" +#include "SDL_joystick.h" +#include "SDL_gamecontroller.h" +#include "SDL_hidapi.h" +#include "../usb_ids.h" + +/* This is the full set of HIDAPI drivers available */ +#define SDL_JOYSTICK_HIDAPI_GAMECUBE +#define SDL_JOYSTICK_HIDAPI_LUNA +#define SDL_JOYSTICK_HIDAPI_PS3 +#define SDL_JOYSTICK_HIDAPI_PS4 +#define SDL_JOYSTICK_HIDAPI_PS5 +#define SDL_JOYSTICK_HIDAPI_STADIA +#define SDL_JOYSTICK_HIDAPI_STEAM /* Simple support for BLE Steam Controller, hint is disabled by default */ +#define SDL_JOYSTICK_HIDAPI_STEAMDECK +#define SDL_JOYSTICK_HIDAPI_SWITCH +#define SDL_JOYSTICK_HIDAPI_WII +#define SDL_JOYSTICK_HIDAPI_XBOX360 +#define SDL_JOYSTICK_HIDAPI_XBOXONE +#define SDL_JOYSTICK_HIDAPI_SHIELD + +/* Whether HIDAPI is enabled by default */ +#if defined(__ANDROID__) || \ + defined(__IPHONEOS__) || \ + defined(__TVOS__) +/* On Android, HIDAPI prompts for permissions and acquires exclusive access to the device, and on Apple mobile platforms it doesn't do anything except for handling Bluetooth Steam Controllers, so we'll leave it off by default. */ +#define SDL_HIDAPI_DEFAULT SDL_FALSE +#else +#define SDL_HIDAPI_DEFAULT SDL_TRUE +#endif + +/* The maximum size of a USB packet for HID devices */ +#define USB_PACKET_LENGTH 64 + +/* Forward declaration */ +struct _SDL_HIDAPI_DeviceDriver; + +typedef struct _SDL_HIDAPI_Device +{ + const void *magic; + char *name; + char *manufacturer_string; + char *product_string; + char *path; + Uint16 vendor_id; + Uint16 product_id; + Uint16 version; + char *serial; + SDL_JoystickGUID guid; + int interface_number; /* Available on Windows and Linux */ + int interface_class; + int interface_subclass; + int interface_protocol; + Uint16 usage_page; /* Available on Windows and Mac OS X */ + Uint16 usage; /* Available on Windows and Mac OS X */ + SDL_bool is_bluetooth; + SDL_JoystickType joystick_type; + SDL_GameControllerType type; + + struct _SDL_HIDAPI_DeviceDriver *driver; + void *context; + SDL_mutex *dev_lock; + SDL_hid_device *dev; + SDL_atomic_t rumble_pending; + int num_joysticks; + SDL_JoystickID *joysticks; + + /* Used during scanning for device changes */ + SDL_bool seen; + + /* Used to flag that the device is being updated */ + SDL_bool updating; + + struct _SDL_HIDAPI_Device *parent; + int num_children; + struct _SDL_HIDAPI_Device **children; + + struct _SDL_HIDAPI_Device *next; +} SDL_HIDAPI_Device; + +typedef struct _SDL_HIDAPI_DeviceDriver +{ + const char *name; + SDL_bool enabled; + void (*RegisterHints)(SDL_HintCallback callback, void *userdata); + void (*UnregisterHints)(SDL_HintCallback callback, void *userdata); + SDL_bool (*IsEnabled)(void); + SDL_bool (*IsSupportedDevice)(SDL_HIDAPI_Device *device, const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol); + SDL_bool (*InitDevice)(SDL_HIDAPI_Device *device); + int (*GetDevicePlayerIndex)(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id); + void (*SetDevicePlayerIndex)(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index); + SDL_bool (*UpdateDevice)(SDL_HIDAPI_Device *device); + SDL_bool (*OpenJoystick)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick); + int (*RumbleJoystick)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble); + int (*RumbleJoystickTriggers)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble); + Uint32 (*GetJoystickCapabilities)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick); + int (*SetJoystickLED)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue); + int (*SendJoystickEffect)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size); + int (*SetJoystickSensorsEnabled)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled); + void (*CloseJoystick)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick); + void (*FreeDevice)(SDL_HIDAPI_Device *device); + +} SDL_HIDAPI_DeviceDriver; + +/* HIDAPI device support */ +extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverCombined; +extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverGameCube; +extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverJoyCons; +extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverLuna; +extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverNintendoClassic; +extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS3; +extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS3ThirdParty; +extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS4; +extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS5; +extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverShield; +extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverStadia; +extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSteam; +extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSteamDeck; +extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSwitch; +extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverWii; +extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360; +extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360W; +extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXboxOne; + +/* Return true if a HID device is present and supported as a joystick of the given type */ +extern SDL_bool HIDAPI_IsDeviceTypePresent(SDL_GameControllerType type); + +/* Return true if a HID device is present and supported as a joystick */ +extern SDL_bool HIDAPI_IsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name); + +/* Return the type of a joystick if it's present and supported */ +extern SDL_JoystickType HIDAPI_GetJoystickTypeFromGUID(SDL_JoystickGUID guid); + +/* Return the type of a game controller if it's present and supported */ +extern SDL_GameControllerType HIDAPI_GetGameControllerTypeFromGUID(SDL_JoystickGUID guid); + +extern void HIDAPI_UpdateDevices(void); +extern void HIDAPI_SetDeviceName(SDL_HIDAPI_Device *device, const char *name); +extern void HIDAPI_SetDeviceProduct(SDL_HIDAPI_Device *device, Uint16 vendor_id, Uint16 product_id); +extern void HIDAPI_SetDeviceSerial(SDL_HIDAPI_Device *device, const char *serial); +extern SDL_bool HIDAPI_HasConnectedUSBDevice(const char *serial); +extern void HIDAPI_DisconnectBluetoothDevice(const char *serial); +extern SDL_bool HIDAPI_JoystickConnected(SDL_HIDAPI_Device *device, SDL_JoystickID *pJoystickID); +extern void HIDAPI_JoystickDisconnected(SDL_HIDAPI_Device *device, SDL_JoystickID joystickID); + +extern void HIDAPI_DumpPacket(const char *prefix, const Uint8 *data, int size); + +extern SDL_bool HIDAPI_SupportsPlaystationDetection(Uint16 vendor, Uint16 product); + +extern float HIDAPI_RemapVal(float val, float val_min, float val_max, float output_min, float output_max); + +#endif /* SDL_JOYSTICK_HIDAPI_H */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/joystick/hidapi/steam/controller_constants.h b/SDL2-2.30.5/src/joystick/hidapi/steam/controller_constants.h similarity index 82% rename from SDL2-2.0.12/src/joystick/hidapi/steam/controller_constants.h rename to SDL2-2.30.5/src/joystick/hidapi/steam/controller_constants.h index cb343ba..ab4ac2e 100644 --- a/SDL2-2.0.12/src/joystick/hidapi/steam/controller_constants.h +++ b/SDL2-2.30.5/src/joystick/hidapi/steam/controller_constants.h @@ -1,8 +1,23 @@ -//===================== Copyright (c) Valve Corporation. All Rights Reserved. ====================== -// -// Purpose: Defines constants used to communicate with Valve controllers. -// -//================================================================================================== +/* + Simple DirectMedia Layer + Copyright (C) 2021 Valve Corporation + + 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. +*/ #ifndef _CONTROLLER_CONSTANTS_ #define _CONTROLLER_CONSTANTS_ @@ -32,6 +47,8 @@ enum ValveControllerPID D0G_BLE_PID = 0x1105, D0G_BLE2_PID = 0x1106, D0GGLE_PID = 0x1142, + + JUPITER_PID = 0x1205, }; // This enum contains all of the messages exchanged between the host and the target (only add to this enum and never change the order) @@ -53,10 +70,11 @@ enum FeatureReportMessageIDs ID_SET_CONTROLLER_MODE = 0x8D, ID_LOAD_DEFAULT_SETTINGS = 0x8E, ID_TRIGGER_HAPTIC_PULSE = 0x8F, + ID_TURN_OFF_CONTROLLER = 0x9F, ID_GET_DEVICE_INFO = 0xA1, - + ID_CALIBRATE_TRACKPADS = 0xA7, ID_RESERVED_0 = 0xA8, ID_SET_SERIAL_NUMBER = 0xA9, @@ -84,6 +102,12 @@ enum FeatureReportMessageIDs ID_CHECK_GYRO_FW_LOAD = 0xC2, ID_CALIBRATE_ANALOG = 0xC3, ID_DONGLE_GET_CONNECTED_SLOTS = 0xC4, + + ID_RESET_IMU = 0xCE, + + // Deck only + ID_TRIGGER_HAPTIC_CMD = 0xEA, + ID_TRIGGER_RUMBLE_CMD = 0xEB, }; @@ -200,6 +224,32 @@ typedef enum IO_RAW_JOYSTICK_X, IO_RAW_JOYSTICK_Y, IO_GYRO_TILT_VEC, + IO_PRESSURE_LEFT_PAD, + IO_PRESSURE_RIGHT_PAD, + IO_PRESSURE_LEFT_BUMPER, + IO_PRESSURE_RIGHT_BUMPER, + IO_PRESSURE_LEFT_GRIP, + IO_PRESSURE_RIGHT_GRIP, + IO_ANALOG_LEFT_TRIGGER_THRESHOLD, + IO_ANALOG_RIGHT_TRIGGER_THRESHOLD, + IO_PRESSURE_RIGHT_PAD_THRESHOLD, + IO_PRESSURE_LEFT_PAD_THRESHOLD, + IO_PRESSURE_RIGHT_BUMPER_THRESHOLD, + IO_PRESSURE_LEFT_BUMPER_THRESHOLD, + IO_PRESSURE_RIGHT_GRIP_THRESHOLD, + IO_PRESSURE_LEFT_GRIP_THRESHOLD, + IO_PRESSURE_RIGHT_PAD_RAW, + IO_PRESSURE_LEFT_PAD_RAW, + IO_PRESSURE_RIGHT_BUMPER_RAW, + IO_PRESSURE_LEFT_BUMPER_RAW, + IO_PRESSURE_RIGHT_GRIP_RAW, + IO_PRESSURE_LEFT_GRIP_RAW, + IO_PRESSURE_RIGHT_GRIP2_THRESHOLD, + IO_PRESSURE_LEFT_GRIP2_THRESHOLD, + IO_PRESSURE_LEFT_GRIP2, + IO_PRESSURE_RIGHT_GRIP2, + IO_PRESSURE_RIGHT_GRIP2_RAW, + IO_PRESSURE_LEFT_GRIP2_RAW, IO_ANALOG_COUNT } AnalogIO; @@ -367,13 +417,15 @@ typedef enum SETTING_MOUSE_SENSITIVITY, SETTING_MOUSE_ACCELERATION, SETTING_TRACKBALL_ROTATION_ANGLE, - SETTING_HAPTIC_INTENSITY, + SETTING_HAPTIC_INTENSITY_UNUSED, SETTING_LEFT_GAMEPAD_STICK_ENABLED, SETTING_RIGHT_GAMEPAD_STICK_ENABLED, SETTING_USB_DEBUG_MODE, SETTING_LEFT_TRACKPAD_MODE, SETTING_RIGHT_TRACKPAD_MODE, SETTING_MOUSE_POINTER_ENABLED, + + // 10 SETTING_DPAD_DEADZONE, SETTING_MINIMUM_MOMENTUM_VEL, SETTING_MOMENTUM_DECAY_AMMOUNT, @@ -384,6 +436,8 @@ typedef enum SETTING_MOMENTUM_VERTICAL_DIVISOR, SETTING_MOMENTUM_MAXIMUM_VELOCITY, SETTING_TRACKPAD_Z_ON, + + // 20 SETTING_TRACKPAD_Z_OFF, SETTING_SENSITIVY_SCALE_AMMOUNT, SETTING_LEFT_TRACKPAD_SECONDARY_MODE, @@ -394,6 +448,8 @@ typedef enum SETTING_TRACKPAD_OUTER_RADIUS, SETTING_TRACKPAD_Z_ON_LEFT, SETTING_TRACKPAD_Z_OFF_LEFT, + + // 30 SETTING_TRACKPAD_OUTER_SPIN_VEL, SETTING_TRACKPAD_OUTER_SPIN_RADIUS, SETTING_TRACKPAD_OUTER_SPIN_HORIZONTAL_ONLY, @@ -404,6 +460,8 @@ typedef enum SETTING_TRACKPAD_DOUBLE_TAP_BEEP_PERIOD, SETTING_TRACKPAD_DOUBLE_TAP_BEEP_COUNT, SETTING_TRACKPAD_OUTER_RADIUS_RELEASE_ON_TRANSITION, + + // 40 SETTING_RADIAL_MODE_ANGLE, SETTING_HAPTIC_INTENSITY_MOUSE_MODE, SETTING_LEFT_DPAD_REQUIRES_CLICK, @@ -412,9 +470,48 @@ typedef enum SETTING_LED_USER_BRIGHTNESS, SETTING_ENABLE_RAW_JOYSTICK, SETTING_ENABLE_FAST_SCAN, - SETTING_GYRO_MODE, + SETTING_IMU_MODE, SETTING_WIRELESS_PACKET_VERSION, + + // 50 SETTING_SLEEP_INACTIVITY_TIMEOUT, + SETTING_TRACKPAD_NOISE_THRESHOLD, + SETTING_LEFT_TRACKPAD_CLICK_PRESSURE, + SETTING_RIGHT_TRACKPAD_CLICK_PRESSURE, + SETTING_LEFT_BUMPER_CLICK_PRESSURE, + SETTING_RIGHT_BUMPER_CLICK_PRESSURE, + SETTING_LEFT_GRIP_CLICK_PRESSURE, + SETTING_RIGHT_GRIP_CLICK_PRESSURE, + SETTING_LEFT_GRIP2_CLICK_PRESSURE, + SETTING_RIGHT_GRIP2_CLICK_PRESSURE, + + // 60 + SETTING_PRESSURE_MODE, + SETTING_CONTROLLER_TEST_MODE, + SETTING_TRIGGER_MODE, + SETTING_TRACKPAD_Z_THRESHOLD, + SETTING_FRAME_RATE, + SETTING_TRACKPAD_FILT_CTRL, + SETTING_TRACKPAD_CLIP, + SETTING_DEBUG_OUTPUT_SELECT, + SETTING_TRIGGER_THRESHOLD_PERCENT, + SETTING_TRACKPAD_FREQUENCY_HOPPING, + + // 70 + SETTING_HAPTICS_ENABLED, + SETTING_STEAM_WATCHDOG_ENABLE, + SETTING_TIMP_TOUCH_THRESHOLD_ON, + SETTING_TIMP_TOUCH_THRESHOLD_OFF, + SETTING_FREQ_HOPPING, + SETTING_TEST_CONTROL, + SETTING_HAPTIC_MASTER_GAIN_DB, + SETTING_THUMB_TOUCH_THRESH, + SETTING_DEVICE_POWER_STATUS, + SETTING_HAPTIC_INTENSITY, + + // 80 + SETTING_STABILIZER_ENABLED, + SETTING_TIMP_MODE_MTE, SETTING_COUNT, // This is a special setting value use for callbacks and should not be set/get explicitly. @@ -446,6 +543,7 @@ typedef enum HAPTIC_PULSE_NORMAL = 0x0000, HAPTIC_PULSE_HIGH_PRIORITY = 0x0001, HAPTIC_PULSE_VERY_HIGH_PRIORITY = 0x0002, + HAPTIC_PULSE_IGNORE_USER_PREFS = 0x0003, } SettingHapticPulseFlags; typedef struct diff --git a/SDL2-2.0.12/src/joystick/hidapi/steam/controller_structs.h b/SDL2-2.30.5/src/joystick/hidapi/steam/controller_structs.h similarity index 50% rename from SDL2-2.0.12/src/joystick/hidapi/steam/controller_structs.h rename to SDL2-2.30.5/src/joystick/hidapi/steam/controller_structs.h index 4ca9115..1659f74 100644 --- a/SDL2-2.0.12/src/joystick/hidapi/steam/controller_structs.h +++ b/SDL2-2.30.5/src/joystick/hidapi/steam/controller_structs.h @@ -1,13 +1,159 @@ -//===================== Copyright (c) Valve Corporation. All Rights Reserved. ====================== -// -// Purpose: Defines methods and structures used to communicate with Valve controllers. -// -//================================================================================================== +/* + Simple DirectMedia Layer + Copyright (C) 2020 Valve Corporation + + 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. +*/ #ifndef _CONTROLLER_STRUCTS_ #define _CONTROLLER_STRUCTS_ #pragma pack(1) +#define HID_FEATURE_REPORT_BYTES 64 + +// Header for all host <==> target messages +typedef struct +{ + unsigned char type; + unsigned char length; +} FeatureReportHeader; + +// Generic controller settings structure +typedef struct +{ + unsigned char settingNum; + unsigned short settingValue; +} ControllerSetting; + +// Generic controller attribute structure +typedef struct +{ + unsigned char attributeTag; + uint32_t attributeValue; +} ControllerAttribute; + +// Generic controller settings structure +typedef struct +{ + ControllerSetting settings[ ( HID_FEATURE_REPORT_BYTES - sizeof( FeatureReportHeader ) ) / sizeof( ControllerSetting ) ]; +} MsgSetSettingsValues, MsgGetSettingsValues, MsgGetSettingsDefaults, MsgGetSettingsMaxs; + +// Generic controller settings structure +typedef struct +{ + ControllerAttribute attributes[ ( HID_FEATURE_REPORT_BYTES - sizeof( FeatureReportHeader ) ) / sizeof( ControllerAttribute ) ]; +} MsgGetAttributes; + +typedef struct +{ + unsigned char attributeTag; + char attributeValue[20]; +} MsgGetStringAttribute; + +typedef struct +{ + unsigned char mode; +} MsgSetControllerMode; + +// Trigger a haptic pulse +typedef struct { + unsigned char which_pad; + unsigned short pulse_duration; + unsigned short pulse_interval; + unsigned short pulse_count; + short dBgain; + unsigned char priority; +} MsgFireHapticPulse; + +typedef struct { + uint8_t mode; +} MsgHapticSetMode; + +typedef enum { + HAPTIC_TYPE_OFF, + HAPTIC_TYPE_TICK, + HAPTIC_TYPE_CLICK, + HAPTIC_TYPE_TONE, + HAPTIC_TYPE_RUMBLE, + HAPTIC_TYPE_NOISE, + HAPTIC_TYPE_SCRIPT, + HAPTIC_TYPE_LOG_SWEEP, +} haptic_type_t; + +typedef enum { + HAPTIC_INTENSITY_SYSTEM, + HAPTIC_INTENSITY_SHORT, + HAPTIC_INTENSITY_MEDIUM, + HAPTIC_INTENSITY_LONG, + HAPTIC_INTENSITY_INSANE, +} haptic_intensity_t; + +typedef struct { + uint8_t side; // 0x01 = L, 0x02 = R, 0x03 = Both + uint8_t cmd; // 0 = Off, 1 = tick, 2 = click, 3 = tone, 4 = rumble, 5 = + // rumble_noise, 6 = script, 7 = sweep, + uint8_t ui_intensity; // 0-4 (0 = default) + int8_t dBgain; // dB Can be positive (reasonable clipping / limiting will apply) + uint16_t freq; // Frequency of tone (if applicable) + int16_t dur_ms; // Duration of tone / rumble (if applicable) (neg = infinite) + + uint16_t noise_intensity; + uint16_t lfo_freq; // Drives both tone and rumble geneators + uint8_t lfo_depth; // percentage, typically 100 + uint8_t rand_tone_gain; // Randomize each LFO cycle's gain + uint8_t script_id; // Used w/ dBgain for scripted haptics + + uint16_t lss_start_freq; // Used w/ Log Sine Sweep + uint16_t lss_end_freq; // Ditto +} MsgTriggerHaptic; + +typedef struct { + uint8_t unRumbleType; + uint16_t unIntensity; + uint16_t unLeftMotorSpeed; + uint16_t unRightMotorSpeed; + int8_t nLeftGain; + int8_t nRightGain; +} MsgSimpleRumbleCmd; + +// This is the only message struct that application code should use to interact with feature request messages. Any new +// messages should be added to the union. The structures defined here should correspond to the ones defined in +// ValveDeviceCore.cpp. +// +typedef struct +{ + FeatureReportHeader header; + union + { + MsgSetSettingsValues setSettingsValues; + MsgGetSettingsValues getSettingsValues; + MsgGetSettingsMaxs getSettingsMaxs; + MsgGetSettingsDefaults getSettingsDefaults; + MsgGetAttributes getAttributes; + MsgSetControllerMode controllerMode; + MsgFireHapticPulse fireHapticPulse; + MsgGetStringAttribute getStringAttribute; + MsgHapticSetMode hapticMode; + MsgTriggerHaptic triggerHaptic; + MsgSimpleRumbleCmd simpleRumble; + } payload; + +} FeatureReportMsg; + // Roll this version forward anytime that you are breaking compatibility of existing // message types within ValveInReport_t or the header itself. Hopefully this should // be super rare and instead you shoudl just add new message payloads to the union, @@ -25,6 +171,7 @@ typedef enum ID_CONTROLLER_DEBUG2 = 5, ID_CONTROLLER_SECONDARY_STATE = 6, ID_CONTROLLER_BLE_STATE = 7, + ID_CONTROLLER_DECK_STATE = 9, ID_CONTROLLER_MSG_COUNT } ValveInReportMessageIDs; @@ -42,12 +189,12 @@ typedef struct { // If packet num matches that on your prior call, then the controller state hasn't been changed since // your last call and there is no need to process it - uint32 unPacketNum; + Uint32 unPacketNum; // Button bitmask and trigger data. union { - uint64 ulButtons; + Uint64 ulButtons; struct { unsigned char _pad0[3]; @@ -91,12 +238,12 @@ typedef struct { // If packet num matches that on your prior call, then the controller state hasn't been changed since // your last call and there is no need to process it - uint32 unPacketNum; + Uint32 unPacketNum; // Button bitmask and trigger data. union { - uint64 ulButtons; + Uint64 ulButtons; struct { unsigned char _pad0[3]; @@ -206,6 +353,66 @@ typedef struct unsigned char ucBatteryLevel; } SteamControllerStatusEvent_t; +// Deck State payload +typedef struct +{ + // If packet num matches that on your prior call, then the controller + // state hasn't been changed since your last call and there is no need to + // process it + Uint32 unPacketNum; + + // Button bitmask and trigger data. + union + { + Uint64 ulButtons; + struct + { + Uint32 ulButtonsL; + Uint32 ulButtonsH; + }; + }; + + // Left pad coordinates + short sLeftPadX; + short sLeftPadY; + + // Right pad coordinates + short sRightPadX; + short sRightPadY; + + // Accelerometer values + short sAccelX; + short sAccelY; + short sAccelZ; + + // Gyroscope values + short sGyroX; + short sGyroY; + short sGyroZ; + + // Gyro quaternions + short sGyroQuatW; + short sGyroQuatX; + short sGyroQuatY; + short sGyroQuatZ; + + // Uncalibrated trigger values + unsigned short sTriggerRawL; + unsigned short sTriggerRawR; + + // Left stick values + short sLeftStickX; + short sLeftStickY; + + // Right stick values + short sRightStickX; + short sRightStickY; + + // Touchpad pressures + unsigned short sPressurePadLeft; + unsigned short sPressurePadRight; +} SteamDeckStatePacket_t; + typedef struct { ValveInReportHeader_t header; @@ -219,6 +426,7 @@ typedef struct ValveControllerRawTrackpadImage_t rawPadImage; SteamControllerWirelessEvent_t wirelessEvent; SteamControllerStatusEvent_t statusEvent; + SteamDeckStatePacket_t deckState; } payload; } ValveInReport_t; diff --git a/SDL2-2.30.5/src/joystick/iphoneos/SDL_mfijoystick.m b/SDL2-2.30.5/src/joystick/iphoneos/SDL_mfijoystick.m new file mode 100644 index 0000000..28ddca7 --- /dev/null +++ b/SDL2-2.30.5/src/joystick/iphoneos/SDL_mfijoystick.m @@ -0,0 +1,2215 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +/* This is the iOS implementation of the SDL joystick API */ +#include "SDL_events.h" +#include "SDL_joystick.h" +#include "SDL_hints.h" +#include "SDL_stdinc.h" +#include "SDL_timer.h" +#include "../SDL_sysjoystick.h" +#include "../SDL_joystick_c.h" +#include "../hidapi/SDL_hidapijoystick_c.h" +#include "../usb_ids.h" + +#include "SDL_mfijoystick_c.h" + +#ifndef SDL_EVENTS_DISABLED +#include "../../events/SDL_events_c.h" +#endif + +#if TARGET_OS_IOS +#define SDL_JOYSTICK_iOS_ACCELEROMETER +#import +#endif + +#if defined(__MACOSX__) +#include +#include +#ifndef NSAppKitVersionNumber10_15 +#define NSAppKitVersionNumber10_15 1894 +#endif +#endif /* __MACOSX__ */ + +#ifdef SDL_JOYSTICK_MFI +#import + +static id connectObserver = nil; +static id disconnectObserver = nil; + +#include +#include + +#ifndef __IPHONE_OS_VERSION_MAX_ALLOWED +#define __IPHONE_OS_VERSION_MAX_ALLOWED 0 +#endif + +#ifndef __APPLETV_OS_VERSION_MAX_ALLOWED +#define __APPLETV_OS_VERSION_MAX_ALLOWED 0 +#endif + +#ifndef __MAC_OS_VERSION_MAX_ALLOWED +#define __MAC_OS_VERSION_MAX_ALLOWED 0 +#endif + +/* remove compilation warnings for strict builds by defining these selectors, even though + * they are only ever used indirectly through objc_msgSend + */ +@interface GCController (SDL) +#if defined(__MACOSX__) && (__MAC_OS_X_VERSION_MAX_ALLOWED <= 101600) ++ (BOOL)supportsHIDDevice:(IOHIDDeviceRef)device; +#endif +#if !((__IPHONE_OS_VERSION_MAX_ALLOWED >= 130000) || (__APPLETV_OS_VERSION_MAX_ALLOWED >= 130000) || (__MAC_OS_VERSION_MAX_ALLOWED >= 1500000)) +@property(nonatomic, readonly) NSString *productCategory; +#endif +#if !((__IPHONE_OS_VERSION_MAX_ALLOWED >= 140500) || (__APPLETV_OS_VERSION_MAX_ALLOWED >= 140500) || (__MAC_OS_X_VERSION_MAX_ALLOWED >= 110300)) +@property(class, nonatomic, readwrite) BOOL shouldMonitorBackgroundEvents; +#endif +@end +@interface GCExtendedGamepad (SDL) +#if !((__IPHONE_OS_VERSION_MAX_ALLOWED >= 121000) || (__APPLETV_OS_VERSION_MAX_ALLOWED >= 121000) || (__MAC_OS_VERSION_MAX_ALLOWED >= 1401000)) +@property(nonatomic, readonly, nullable) GCControllerButtonInput *leftThumbstickButton; +@property(nonatomic, readonly, nullable) GCControllerButtonInput *rightThumbstickButton; +#endif +#if !((__IPHONE_OS_VERSION_MAX_ALLOWED >= 130000) || (__APPLETV_OS_VERSION_MAX_ALLOWED >= 130000) || (__MAC_OS_VERSION_MAX_ALLOWED >= 1500000)) +@property(nonatomic, readonly) GCControllerButtonInput *buttonMenu; +@property(nonatomic, readonly, nullable) GCControllerButtonInput *buttonOptions; +#endif +#if !((__IPHONE_OS_VERSION_MAX_ALLOWED >= 140000) || (__APPLETV_OS_VERSION_MAX_ALLOWED >= 140000) || (__MAC_OS_VERSION_MAX_ALLOWED > 1500000)) +@property(nonatomic, readonly, nullable) GCControllerButtonInput *buttonHome; +#endif +@end +@interface GCMicroGamepad (SDL) +#if !((__IPHONE_OS_VERSION_MAX_ALLOWED >= 130000) || (__APPLETV_OS_VERSION_MAX_ALLOWED >= 130000) || (__MAC_OS_VERSION_MAX_ALLOWED >= 1500000)) +@property(nonatomic, readonly) GCControllerButtonInput *buttonMenu; +#endif +@end + +#if (__IPHONE_OS_VERSION_MAX_ALLOWED >= 140000) || (__APPLETV_OS_VERSION_MAX_ALLOWED >= 140000) || (__MAC_OS_VERSION_MAX_ALLOWED > 1500000) || (__MAC_OS_X_VERSION_MAX_ALLOWED > 101600) +#define ENABLE_MFI_BATTERY +#define ENABLE_MFI_RUMBLE +#define ENABLE_MFI_LIGHT +#define ENABLE_MFI_SENSORS +#define ENABLE_MFI_SYSTEM_GESTURE_STATE +#define ENABLE_PHYSICAL_INPUT_PROFILE +#endif + +#ifdef ENABLE_MFI_RUMBLE +#import +#endif + +#endif /* SDL_JOYSTICK_MFI */ + +#ifdef SDL_JOYSTICK_iOS_ACCELEROMETER +static const char *accelerometerName = "iOS Accelerometer"; +static CMMotionManager *motionManager = nil; +#endif /* SDL_JOYSTICK_iOS_ACCELEROMETER */ + +static SDL_JoystickDeviceItem *deviceList = NULL; + +static int numjoysticks = 0; +int SDL_AppleTVRemoteOpenedAsJoystick = 0; + +static SDL_JoystickDeviceItem *GetDeviceForIndex(int device_index) +{ + SDL_JoystickDeviceItem *device = deviceList; + int i = 0; + + while (i < device_index) { + if (device == NULL) { + return NULL; + } + device = device->next; + i++; + } + + return device; +} + +#ifdef SDL_JOYSTICK_MFI +static BOOL IsControllerPS4(GCController *controller) +{ + if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, *)) { + if ([controller.productCategory isEqualToString:@"DualShock 4"]) { + return TRUE; + } + } else { + if ([controller.vendorName containsString:@"DUALSHOCK"]) { + return TRUE; + } + } + return FALSE; +} +static BOOL IsControllerPS5(GCController *controller) +{ + if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, *)) { + if ([controller.productCategory isEqualToString:@"DualSense"]) { + return TRUE; + } + } else { + if ([controller.vendorName containsString:@"DualSense"]) { + return TRUE; + } + } + return FALSE; +} +static BOOL IsControllerXbox(GCController *controller) +{ + if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, *)) { + if ([controller.productCategory isEqualToString:@"Xbox One"]) { + return TRUE; + } + } else { + if ([controller.vendorName containsString:@"Xbox"]) { + return TRUE; + } + } + return FALSE; +} +static BOOL IsControllerSwitchPro(GCController *controller) +{ + if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, *)) { + if ([controller.productCategory isEqualToString:@"Switch Pro Controller"]) { + return TRUE; + } + } + return FALSE; +} +static BOOL IsControllerSwitchJoyConL(GCController *controller) +{ + if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, *)) { + if ([controller.productCategory isEqualToString:@"Nintendo Switch Joy-Con (L)"]) { + return TRUE; + } + } + return FALSE; +} +static BOOL IsControllerSwitchJoyConR(GCController *controller) +{ + if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, *)) { + if ([controller.productCategory isEqualToString:@"Nintendo Switch Joy-Con (R)"]) { + return TRUE; + } + } + return FALSE; +} +static BOOL IsControllerSwitchJoyConPair(GCController *controller) +{ + if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, *)) { + if ([controller.productCategory isEqualToString:@"Nintendo Switch Joy-Con (L/R)"]) { + return TRUE; + } + } + return FALSE; +} +static BOOL IsControllerStadia(GCController *controller) +{ + if ([controller.vendorName hasPrefix:@"Stadia"]) { + return TRUE; + } + return FALSE; +} +static BOOL IsControllerBackboneOne(GCController *controller) +{ + if ([controller.vendorName hasPrefix:@"Backbone One"]) { + return TRUE; + } + return FALSE; +} +static void CheckControllerSiriRemote(GCController *controller, int *is_siri_remote) +{ + if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, *)) { + if ([controller.productCategory hasPrefix:@"Siri Remote"]) { + *is_siri_remote = 1; + SDL_sscanf(controller.productCategory.UTF8String, "Siri Remote (%i%*s Generation)", is_siri_remote); + return; + } + } + *is_siri_remote = 0; +} + +#ifdef ENABLE_PHYSICAL_INPUT_PROFILE +static BOOL ElementAlreadyHandled(SDL_JoystickDeviceItem *device, NSString *element, NSDictionary *elements) +{ + if ([element isEqualToString:@"Left Thumbstick Left"] || + [element isEqualToString:@"Left Thumbstick Right"]) { + if (elements[@"Left Thumbstick X Axis"]) { + return TRUE; + } + } + if ([element isEqualToString:@"Left Thumbstick Up"] || + [element isEqualToString:@"Left Thumbstick Down"]) { + if (elements[@"Left Thumbstick Y Axis"]) { + return TRUE; + } + } + if ([element isEqualToString:@"Right Thumbstick Left"] || + [element isEqualToString:@"Right Thumbstick Right"]) { + if (elements[@"Right Thumbstick X Axis"]) { + return TRUE; + } + } + if ([element isEqualToString:@"Right Thumbstick Up"] || + [element isEqualToString:@"Right Thumbstick Down"]) { + if (elements[@"Right Thumbstick Y Axis"]) { + return TRUE; + } + } + if (device->is_siri_remote) { + if ([element isEqualToString:@"Direction Pad Left"] || + [element isEqualToString:@"Direction Pad Right"]) { + if (elements[@"Direction Pad X Axis"]) { + return TRUE; + } + } + if ([element isEqualToString:@"Direction Pad Up"] || + [element isEqualToString:@"Direction Pad Down"]) { + if (elements[@"Direction Pad Y Axis"]) { + return TRUE; + } + } + } else { + if ([element isEqualToString:@"Direction Pad X Axis"]) { + if (elements[@"Direction Pad Left"] && + elements[@"Direction Pad Right"]) { + return TRUE; + } + } + if ([element isEqualToString:@"Direction Pad Y Axis"]) { + if (elements[@"Direction Pad Up"] && + elements[@"Direction Pad Down"]) { + return TRUE; + } + } + } + if ([element isEqualToString:@"Cardinal Direction Pad X Axis"]) { + if (elements[@"Cardinal Direction Pad Left"] && + elements[@"Cardinal Direction Pad Right"]) { + return TRUE; + } + } + if ([element isEqualToString:@"Cardinal Direction Pad Y Axis"]) { + if (elements[@"Cardinal Direction Pad Up"] && + elements[@"Cardinal Direction Pad Down"]) { + return TRUE; + } + } + if ([element isEqualToString:@"Touchpad 1 X Axis"] || + [element isEqualToString:@"Touchpad 1 Y Axis"] || + [element isEqualToString:@"Touchpad 1 Left"] || + [element isEqualToString:@"Touchpad 1 Right"] || + [element isEqualToString:@"Touchpad 1 Up"] || + [element isEqualToString:@"Touchpad 1 Down"] || + [element isEqualToString:@"Touchpad 2 X Axis"] || + [element isEqualToString:@"Touchpad 2 Y Axis"] || + [element isEqualToString:@"Touchpad 2 Left"] || + [element isEqualToString:@"Touchpad 2 Right"] || + [element isEqualToString:@"Touchpad 2 Up"] || + [element isEqualToString:@"Touchpad 2 Down"]) { + /* The touchpad is handled separately */ + return TRUE; + } + if ([element isEqualToString:@"Button Home"]) { + if (device->is_switch_joycon_pair) { + /* The Nintendo Switch JoyCon home button doesn't ever show as being held down */ + return TRUE; + } +#if TARGET_OS_TV + /* The OS uses the home button, it's not available to apps */ + return TRUE; +#endif + } + if ([element isEqualToString:@"Button Share"]) { + if (device->is_backbone_one) { + /* The Backbone app uses share button */ + return TRUE; + } + } + return FALSE; +} +#endif /* ENABLE_PHYSICAL_INPUT_PROFILE */ + +static BOOL IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controller) +{ + Uint16 vendor = 0; + Uint16 product = 0; + Uint8 subtype = 0; + Uint16 signature = 0; + const char *name = NULL; + + if (@available(macOS 11.3, iOS 14.5, tvOS 14.5, *)) { + if (!GCController.shouldMonitorBackgroundEvents) { + GCController.shouldMonitorBackgroundEvents = YES; + } + } + + /* Explicitly retain the controller because SDL_JoystickDeviceItem is a + * struct, and ARC doesn't work with structs. */ + device->controller = (__bridge GCController *)CFBridgingRetain(controller); + + if (controller.vendorName) { + name = controller.vendorName.UTF8String; + } + + if (!name) { + name = "MFi Gamepad"; + } + + device->name = SDL_CreateJoystickName(0, 0, NULL, name); + +#ifdef DEBUG_CONTROLLER_PROFILE + NSLog(@"Product name: %@\n", controller.vendorName); + NSLog(@"Product category: %@\n", controller.productCategory); + NSLog(@"Elements available:\n"); +#ifdef ENABLE_PHYSICAL_INPUT_PROFILE + if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { + NSDictionary *elements = controller.physicalInputProfile.elements; + for (id key in controller.physicalInputProfile.buttons) { + NSLog(@"\tButton: %@ (%s)\n", key, elements[key].analog ? "analog" : "digital"); + } + for (id key in controller.physicalInputProfile.axes) { + NSLog(@"\tAxis: %@\n", key); + } + for (id key in controller.physicalInputProfile.dpads) { + NSLog(@"\tHat: %@\n", key); + } + } +#endif +#endif + + device->is_xbox = IsControllerXbox(controller); + device->is_ps4 = IsControllerPS4(controller); + device->is_ps5 = IsControllerPS5(controller); + device->is_switch_pro = IsControllerSwitchPro(controller); + device->is_switch_joycon_pair = IsControllerSwitchJoyConPair(controller); + device->is_stadia = IsControllerStadia(controller); + device->is_backbone_one = IsControllerBackboneOne(controller); + device->is_switch_joyconL = IsControllerSwitchJoyConL(controller); + device->is_switch_joyconR = IsControllerSwitchJoyConR(controller); +#ifdef SDL_JOYSTICK_HIDAPI + if ((device->is_xbox && HIDAPI_IsDeviceTypePresent(SDL_CONTROLLER_TYPE_XBOXONE)) || + (device->is_ps4 && HIDAPI_IsDeviceTypePresent(SDL_CONTROLLER_TYPE_PS4)) || + (device->is_ps5 && HIDAPI_IsDeviceTypePresent(SDL_CONTROLLER_TYPE_PS5)) || + (device->is_switch_pro && HIDAPI_IsDeviceTypePresent(SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO)) || + (device->is_switch_joycon_pair && HIDAPI_IsDevicePresent(USB_VENDOR_NINTENDO, USB_PRODUCT_NINTENDO_SWITCH_JOYCON_PAIR, 0, "")) || + (device->is_stadia && HIDAPI_IsDevicePresent(USB_VENDOR_GOOGLE, USB_PRODUCT_GOOGLE_STADIA_CONTROLLER, 0, "")) || + (device->is_switch_joyconL && HIDAPI_IsDevicePresent(USB_VENDOR_NINTENDO, USB_PRODUCT_NINTENDO_SWITCH_JOYCON_LEFT, 0, "")) || + (device->is_switch_joyconR && HIDAPI_IsDevicePresent(USB_VENDOR_NINTENDO, USB_PRODUCT_NINTENDO_SWITCH_JOYCON_RIGHT, 0, ""))) { + /* The HIDAPI driver is taking care of this device */ + return FALSE; + } +#endif + CheckControllerSiriRemote(controller, &device->is_siri_remote); + + if (device->is_siri_remote && !SDL_GetHintBoolean(SDL_HINT_TV_REMOTE_AS_JOYSTICK, SDL_TRUE)) { + /* Ignore remotes, they'll be handled as keyboard input */ + return SDL_FALSE; + } + +#ifdef ENABLE_PHYSICAL_INPUT_PROFILE + if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { + if (controller.physicalInputProfile.buttons[GCInputDualShockTouchpadButton] != nil) { + device->has_dualshock_touchpad = TRUE; + } + if (controller.physicalInputProfile.buttons[GCInputXboxPaddleOne] != nil) { + device->has_xbox_paddles = TRUE; + } + if (controller.physicalInputProfile.buttons[@"Button Share"] != nil) { + device->has_xbox_share_button = TRUE; + } + } +#endif // ENABLE_PHYSICAL_INPUT_PROFILE + + if (device->is_backbone_one) { + vendor = USB_VENDOR_BACKBONE; + if (device->is_ps5) { + product = USB_PRODUCT_BACKBONE_ONE_IOS_PS5; + } else { + product = USB_PRODUCT_BACKBONE_ONE_IOS; + } + } else if (device->is_xbox) { + vendor = USB_VENDOR_MICROSOFT; + if (device->has_xbox_paddles) { + /* Assume Xbox One Elite Series 2 Controller unless/until GCController flows VID/PID */ + product = USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2_BLUETOOTH; + } else if (device->has_xbox_share_button) { + /* Assume Xbox Series X Controller unless/until GCController flows VID/PID */ + product = USB_PRODUCT_XBOX_SERIES_X_BLE; + } else { + /* Assume Xbox One S Bluetooth Controller unless/until GCController flows VID/PID */ + product = USB_PRODUCT_XBOX_ONE_S_REV1_BLUETOOTH; + } + } else if (device->is_ps4) { + /* Assume DS4 Slim unless/until GCController flows VID/PID */ + vendor = USB_VENDOR_SONY; + product = USB_PRODUCT_SONY_DS4_SLIM; + if (device->has_dualshock_touchpad) { + subtype = 1; + } + } else if (device->is_ps5) { + vendor = USB_VENDOR_SONY; + product = USB_PRODUCT_SONY_DS5; + } else if (device->is_switch_pro) { + vendor = USB_VENDOR_NINTENDO; + product = USB_PRODUCT_NINTENDO_SWITCH_PRO; + } else if (device->is_switch_joycon_pair) { + vendor = USB_VENDOR_NINTENDO; + product = USB_PRODUCT_NINTENDO_SWITCH_JOYCON_PAIR; + } else if (device->is_switch_joyconL) { + vendor = USB_VENDOR_NINTENDO; + product = USB_PRODUCT_NINTENDO_SWITCH_JOYCON_LEFT; + } else if (device->is_switch_joyconR) { + vendor = USB_VENDOR_NINTENDO; + product = USB_PRODUCT_NINTENDO_SWITCH_JOYCON_RIGHT; +#ifdef ENABLE_PHYSICAL_INPUT_PROFILE + } else if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { + vendor = USB_VENDOR_APPLE; + product = 4; + subtype = 4; +#endif + } else if (controller.extendedGamepad) { + vendor = USB_VENDOR_APPLE; + product = 1; + subtype = 1; + } else if (controller.gamepad) { + vendor = USB_VENDOR_APPLE; + product = 2; + subtype = 2; +#if TARGET_OS_TV + } else if (controller.microGamepad) { + vendor = USB_VENDOR_APPLE; + product = 3; + subtype = 3; +#endif + } else { + /* We don't know how to get input events from this device */ + return SDL_FALSE; + } + +#ifdef ENABLE_PHYSICAL_INPUT_PROFILE + if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { + NSDictionary *elements = controller.physicalInputProfile.elements; + + /* Provide both axes and analog buttons as SDL axes */ + NSArray *axes = [[[elements allKeys] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)] + filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id object, NSDictionary *bindings) { + GCControllerElement *element; + + if (ElementAlreadyHandled(device, (NSString *)object, elements)) { + return NO; + } + + element = elements[object]; + if (element.analog) { + if ([element isKindOfClass:[GCControllerAxisInput class]] || + [element isKindOfClass:[GCControllerButtonInput class]]) { + return YES; + } + } + return NO; + }]]; + NSArray *buttons = [[[elements allKeys] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)] + filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id object, NSDictionary *bindings) { + GCControllerElement *element; + + if (ElementAlreadyHandled(device, (NSString *)object, elements)) { + return NO; + } + + element = elements[object]; + if ([element isKindOfClass:[GCControllerButtonInput class]]) { + return YES; + } + return NO; + }]]; + /* Explicitly retain the arrays because SDL_JoystickDeviceItem is a + * struct, and ARC doesn't work with structs. */ + device->naxes = (int)axes.count; + device->axes = (__bridge NSArray *)CFBridgingRetain(axes); + device->nbuttons = (int)buttons.count; + device->buttons = (__bridge NSArray *)CFBridgingRetain(buttons); + subtype = 4; + +#ifdef DEBUG_CONTROLLER_PROFILE + NSLog(@"Elements used:\n", controller.vendorName); + for (id key in device->buttons) { + NSLog(@"\tButton: %@ (%s)\n", key, elements[key].analog ? "analog" : "digital"); + } + for (id key in device->axes) { + NSLog(@"\tAxis: %@\n", key); + } +#endif /* DEBUG_CONTROLLER_PROFILE */ + +#if TARGET_OS_TV + /* tvOS turns the menu button into a system gesture, so we grab it here instead */ + if (elements[GCInputButtonMenu] && !elements[@"Button Home"]) { + device->pause_button_index = [device->buttons indexOfObject:GCInputButtonMenu]; + } +#endif + } else +#endif + if (controller.extendedGamepad) { + GCExtendedGamepad *gamepad = controller.extendedGamepad; + int nbuttons = 0; + BOOL has_direct_menu = FALSE; + + /* These buttons are part of the original MFi spec */ + device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_A); + device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_B); + device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_X); + device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_Y); + device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_LEFTSHOULDER); + device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_RIGHTSHOULDER); + nbuttons += 6; + + /* These buttons are available on some newer controllers */ + if (@available(macOS 10.14.1, iOS 12.1, tvOS 12.1, *)) { + if (gamepad.leftThumbstickButton) { + device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_LEFTSTICK); + ++nbuttons; + } + if (gamepad.rightThumbstickButton) { + device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_RIGHTSTICK); + ++nbuttons; + } + } + if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, *)) { + if (gamepad.buttonOptions) { + device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_BACK); + ++nbuttons; + } + } + device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_START); + ++nbuttons; + + if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, *)) { + if (gamepad.buttonMenu) { + has_direct_menu = TRUE; + } + } +#if TARGET_OS_TV + /* The single menu button isn't very reliable, at least as of tvOS 16.1 */ + if ((device->button_mask & (1 << SDL_CONTROLLER_BUTTON_BACK)) == 0) { + has_direct_menu = FALSE; + } +#endif + if (!has_direct_menu) { + device->pause_button_index = (nbuttons - 1); + } + + device->naxes = 6; /* 2 thumbsticks and 2 triggers */ + device->nhats = 1; /* d-pad */ + device->nbuttons = nbuttons; + + } else if (controller.gamepad) { + int nbuttons = 0; + + /* These buttons are part of the original MFi spec */ + device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_A); + device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_B); + device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_X); + device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_Y); + device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_LEFTSHOULDER); + device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_RIGHTSHOULDER); + device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_START); + nbuttons += 7; + device->pause_button_index = (nbuttons - 1); + + device->naxes = 0; /* no traditional analog inputs */ + device->nhats = 1; /* d-pad */ + device->nbuttons = nbuttons; + } +#if TARGET_OS_TV + else if (controller.microGamepad) { + int nbuttons = 0; + + device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_A); + device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_X); /* Button X on microGamepad */ + device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_B); + nbuttons += 3; + device->pause_button_index = (nbuttons - 1); + + device->naxes = 2; /* treat the touch surface as two axes */ + device->nhats = 0; /* apparently the touch surface-as-dpad is buggy */ + device->nbuttons = nbuttons; + + controller.microGamepad.allowsRotation = SDL_GetHintBoolean(SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION, SDL_FALSE); + } +#endif + else { + /* We don't know how to get input events from this device */ + return SDL_FALSE; + } + + if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { + signature = 0; + signature = SDL_crc16(signature, device->name, SDL_strlen(device->name)); + for (id key in device->axes) { + const char *string = ((NSString *)key).UTF8String; + signature = SDL_crc16(signature, string, SDL_strlen(string)); + } + for (id key in device->buttons) { + const char *string = ((NSString *)key).UTF8String; + signature = SDL_crc16(signature, string, SDL_strlen(string)); + } + } else { + signature = device->button_mask; + } + device->guid = SDL_CreateJoystickGUID(SDL_HARDWARE_BUS_BLUETOOTH, vendor, product, signature, NULL, name, 'm', subtype); + + if (SDL_ShouldIgnoreJoystick(name, device->guid)) { + return SDL_FALSE; + } + + /* This will be set when the first button press of the controller is + * detected. */ + controller.playerIndex = -1; + return TRUE; +} +#endif /* SDL_JOYSTICK_MFI */ + +#if defined(SDL_JOYSTICK_iOS_ACCELEROMETER) || defined(SDL_JOYSTICK_MFI) +static void IOS_AddJoystickDevice(GCController *controller, SDL_bool accelerometer) +{ + SDL_JoystickDeviceItem *device = deviceList; + + while (device != NULL) { + if (device->controller == controller) { + return; + } + device = device->next; + } + + device = (SDL_JoystickDeviceItem *)SDL_calloc(1, sizeof(SDL_JoystickDeviceItem)); + if (device == NULL) { + return; + } + + device->accelerometer = accelerometer; + device->instance_id = SDL_GetNextJoystickInstanceID(); + device->pause_button_index = -1; + + if (accelerometer) { +#ifdef SDL_JOYSTICK_iOS_ACCELEROMETER + device->name = SDL_strdup(accelerometerName); + device->naxes = 3; /* Device acceleration in the x, y, and z axes. */ + device->nhats = 0; + device->nbuttons = 0; + + /* Use the accelerometer name as a GUID. */ + SDL_memcpy(&device->guid.data, device->name, SDL_min(sizeof(SDL_JoystickGUID), SDL_strlen(device->name))); +#else + SDL_free(device); + return; +#endif /* SDL_JOYSTICK_iOS_ACCELEROMETER */ + } else if (controller) { +#ifdef SDL_JOYSTICK_MFI + if (!IOS_AddMFIJoystickDevice(device, controller)) { + SDL_free(device->name); + SDL_free(device); + return; + } +#else + SDL_free(device); + return; +#endif /* SDL_JOYSTICK_MFI */ + } + + if (deviceList == NULL) { + deviceList = device; + } else { + SDL_JoystickDeviceItem *lastdevice = deviceList; + while (lastdevice->next != NULL) { + lastdevice = lastdevice->next; + } + lastdevice->next = device; + } + + ++numjoysticks; + + SDL_PrivateJoystickAdded(device->instance_id); +} +#endif /* SDL_JOYSTICK_iOS_ACCELEROMETER || SDL_JOYSTICK_MFI */ + +static SDL_JoystickDeviceItem *IOS_RemoveJoystickDevice(SDL_JoystickDeviceItem *device) +{ + SDL_JoystickDeviceItem *prev = NULL; + SDL_JoystickDeviceItem *next = NULL; + SDL_JoystickDeviceItem *item = deviceList; + + if (device == NULL) { + return NULL; + } + + next = device->next; + + while (item != NULL) { + if (item == device) { + break; + } + prev = item; + item = item->next; + } + + /* Unlink the device item from the device list. */ + if (prev) { + prev->next = device->next; + } else if (device == deviceList) { + deviceList = device->next; + } + + if (device->joystick) { + device->joystick->hwdata = NULL; + } + +#ifdef SDL_JOYSTICK_MFI + @autoreleasepool { + /* These were explicitly retained in the struct, so they should be explicitly released before freeing the struct. */ + if (device->controller) { + GCController *controller = CFBridgingRelease((__bridge CFTypeRef)(device->controller)); + controller.controllerPausedHandler = nil; + device->controller = nil; + } + if (device->axes) { + CFRelease((__bridge CFTypeRef)device->axes); + device->axes = nil; + } + if (device->buttons) { + CFRelease((__bridge CFTypeRef)device->buttons); + device->buttons = nil; + } + } +#endif /* SDL_JOYSTICK_MFI */ + + --numjoysticks; + + SDL_PrivateJoystickRemoved(device->instance_id); + + SDL_free(device->name); + SDL_free(device); + + return next; +} + +#if TARGET_OS_TV +static void SDLCALL SDL_AppleTVRemoteRotationHintChanged(void *udata, const char *name, const char *oldValue, const char *newValue) +{ + BOOL allowRotation = newValue != NULL && *newValue != '0'; + + @autoreleasepool { + for (GCController *controller in [GCController controllers]) { + if (controller.microGamepad) { + controller.microGamepad.allowsRotation = allowRotation; + } + } + } +} +#endif /* TARGET_OS_TV */ + +static int IOS_JoystickInit(void) +{ + if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_MFI, SDL_TRUE)) { + return 0; + } + +#if defined(__MACOSX__) +#if _SDL_HAS_BUILTIN(__builtin_available) + if (@available(macOS 10.16, *)) { + /* Continue with initialization on macOS 11+ */ + } else { + return 0; + } +#else + /* No @available, must be an older macOS version */ + return 0; +#endif +#endif + + @autoreleasepool { +#ifdef SDL_JOYSTICK_MFI + NSNotificationCenter *center; +#endif +#ifdef SDL_JOYSTICK_iOS_ACCELEROMETER + if (SDL_GetHintBoolean(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, SDL_TRUE)) { + /* Default behavior, accelerometer as joystick */ + IOS_AddJoystickDevice(nil, SDL_TRUE); + } +#endif + +#ifdef SDL_JOYSTICK_MFI + /* GameController.framework was added in iOS 7. */ + if (![GCController class]) { + return 0; + } + + /* For whatever reason, this always returns an empty array on + macOS 11.0.1 */ + for (GCController *controller in [GCController controllers]) { + IOS_AddJoystickDevice(controller, SDL_FALSE); + } + +#if TARGET_OS_TV + SDL_AddHintCallback(SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION, + SDL_AppleTVRemoteRotationHintChanged, NULL); +#endif /* TARGET_OS_TV */ + + center = [NSNotificationCenter defaultCenter]; + + connectObserver = [center addObserverForName:GCControllerDidConnectNotification + object:nil + queue:nil + usingBlock:^(NSNotification *note) { + GCController *controller = note.object; + SDL_LockJoysticks(); + IOS_AddJoystickDevice(controller, SDL_FALSE); + SDL_UnlockJoysticks(); + }]; + + disconnectObserver = [center addObserverForName:GCControllerDidDisconnectNotification + object:nil + queue:nil + usingBlock:^(NSNotification *note) { + GCController *controller = note.object; + SDL_JoystickDeviceItem *device; + SDL_LockJoysticks(); + for (device = deviceList; device != NULL; device = device->next) { + if (device->controller == controller) { + IOS_RemoveJoystickDevice(device); + break; + } + } + SDL_UnlockJoysticks(); + }]; +#endif /* SDL_JOYSTICK_MFI */ + } + + return 0; +} + +static int IOS_JoystickGetCount(void) +{ + return numjoysticks; +} + +static void IOS_JoystickDetect(void) +{ +} + +static const char *IOS_JoystickGetDeviceName(int device_index) +{ + SDL_JoystickDeviceItem *device = GetDeviceForIndex(device_index); + return device ? device->name : "Unknown"; +} + +static const char *IOS_JoystickGetDevicePath(int device_index) +{ + return NULL; +} + +static int IOS_JoystickGetDeviceSteamVirtualGamepadSlot(int device_index) +{ + return -1; +} + +static int IOS_JoystickGetDevicePlayerIndex(int device_index) +{ +#ifdef SDL_JOYSTICK_MFI + SDL_JoystickDeviceItem *device = GetDeviceForIndex(device_index); + if (device && device->controller) { + return (int)device->controller.playerIndex; + } +#endif + return -1; +} + +static void IOS_JoystickSetDevicePlayerIndex(int device_index, int player_index) +{ +#ifdef SDL_JOYSTICK_MFI + SDL_JoystickDeviceItem *device = GetDeviceForIndex(device_index); + if (device && device->controller) { + device->controller.playerIndex = player_index; + } +#endif +} + +static SDL_JoystickGUID IOS_JoystickGetDeviceGUID(int device_index) +{ + SDL_JoystickDeviceItem *device = GetDeviceForIndex(device_index); + SDL_JoystickGUID guid; + if (device) { + guid = device->guid; + } else { + SDL_zero(guid); + } + return guid; +} + +static SDL_JoystickID IOS_JoystickGetDeviceInstanceID(int device_index) +{ + SDL_JoystickDeviceItem *device = GetDeviceForIndex(device_index); + return device ? device->instance_id : -1; +} + +static int IOS_JoystickOpen(SDL_Joystick *joystick, int device_index) +{ + SDL_JoystickDeviceItem *device = GetDeviceForIndex(device_index); + if (device == NULL) { + return SDL_SetError("Could not open Joystick: no hardware device for the specified index"); + } + + joystick->hwdata = device; + joystick->instance_id = device->instance_id; + + joystick->naxes = device->naxes; + joystick->nhats = device->nhats; + joystick->nbuttons = device->nbuttons; + joystick->nballs = 0; + + if (device->has_dualshock_touchpad) { + SDL_PrivateJoystickAddTouchpad(joystick, 2); + } + + device->joystick = joystick; + + @autoreleasepool { + if (device->accelerometer) { +#ifdef SDL_JOYSTICK_iOS_ACCELEROMETER + if (motionManager == nil) { + motionManager = [[CMMotionManager alloc] init]; + } + + /* Shorter times between updates can significantly increase CPU usage. */ + motionManager.accelerometerUpdateInterval = 0.1; + [motionManager startAccelerometerUpdates]; +#endif + } else { +#ifdef SDL_JOYSTICK_MFI + if (device->pause_button_index >= 0) { + GCController *controller = device->controller; + controller.controllerPausedHandler = ^(GCController *c) { + if (joystick->hwdata) { + joystick->hwdata->pause_button_pressed = SDL_GetTicks(); + } + }; + } + +#ifdef ENABLE_MFI_SENSORS + if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { + GCController *controller = joystick->hwdata->controller; + GCMotion *motion = controller.motion; + if (motion && motion.hasRotationRate) { + SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, 0.0f); + } + if (motion && motion.hasGravityAndUserAcceleration) { + SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, 0.0f); + } + } +#endif /* ENABLE_MFI_SENSORS */ + +#ifdef ENABLE_MFI_SYSTEM_GESTURE_STATE + if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { + GCController *controller = joystick->hwdata->controller; + for (id key in controller.physicalInputProfile.buttons) { + GCControllerButtonInput *button = controller.physicalInputProfile.buttons[key]; + if ([button isBoundToSystemGesture]) { + button.preferredSystemGestureState = GCSystemGestureStateDisabled; + } + } + } +#endif /* ENABLE_MFI_SYSTEM_GESTURE_STATE */ + +#endif /* SDL_JOYSTICK_MFI */ + } + } + if (device->is_siri_remote) { + ++SDL_AppleTVRemoteOpenedAsJoystick; + } + + return 0; +} + +static void IOS_AccelerometerUpdate(SDL_Joystick *joystick) +{ +#ifdef SDL_JOYSTICK_iOS_ACCELEROMETER + const float maxgforce = SDL_IPHONE_MAX_GFORCE; + const SInt16 maxsint16 = 0x7FFF; + CMAcceleration accel; + + @autoreleasepool { + if (!motionManager.isAccelerometerActive) { + return; + } + + accel = motionManager.accelerometerData.acceleration; + } + + /* + Convert accelerometer data from floating point to Sint16, which is what + the joystick system expects. + + To do the conversion, the data is first clamped onto the interval + [-SDL_IPHONE_MAX_G_FORCE, SDL_IPHONE_MAX_G_FORCE], then the data is multiplied + by MAX_SINT16 so that it is mapped to the full range of an Sint16. + + You can customize the clamped range of this function by modifying the + SDL_IPHONE_MAX_GFORCE macro in SDL_config_iphoneos.h. + + Once converted to Sint16, the accelerometer data no longer has coherent + units. You can convert the data back to units of g-force by multiplying + it in your application's code by SDL_IPHONE_MAX_GFORCE / 0x7FFF. + */ + + /* clamp the data */ + accel.x = SDL_clamp(accel.x, -maxgforce, maxgforce); + accel.y = SDL_clamp(accel.y, -maxgforce, maxgforce); + accel.z = SDL_clamp(accel.z, -maxgforce, maxgforce); + + /* pass in data mapped to range of SInt16 */ + SDL_PrivateJoystickAxis(joystick, 0, (accel.x / maxgforce) * maxsint16); + SDL_PrivateJoystickAxis(joystick, 1, -(accel.y / maxgforce) * maxsint16); + SDL_PrivateJoystickAxis(joystick, 2, (accel.z / maxgforce) * maxsint16); +#endif /* SDL_JOYSTICK_iOS_ACCELEROMETER */ +} + +#ifdef SDL_JOYSTICK_MFI +static Uint8 IOS_MFIJoystickHatStateForDPad(GCControllerDirectionPad *dpad) +{ + Uint8 hat = 0; + + if (dpad.up.isPressed) { + hat |= SDL_HAT_UP; + } else if (dpad.down.isPressed) { + hat |= SDL_HAT_DOWN; + } + + if (dpad.left.isPressed) { + hat |= SDL_HAT_LEFT; + } else if (dpad.right.isPressed) { + hat |= SDL_HAT_RIGHT; + } + + if (hat == 0) { + return SDL_HAT_CENTERED; + } + + return hat; +} +#endif + +static void IOS_MFIJoystickUpdate(SDL_Joystick *joystick) +{ +#ifdef SDL_JOYSTICK_MFI + @autoreleasepool { + SDL_JoystickDeviceItem *device = joystick->hwdata; + GCController *controller = device->controller; + Uint8 hatstate = SDL_HAT_CENTERED; + int i; + +#if defined(DEBUG_CONTROLLER_STATE) && defined(ENABLE_PHYSICAL_INPUT_PROFILE) + if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { + if (controller.physicalInputProfile) { + for (id key in controller.physicalInputProfile.buttons) { + GCControllerButtonInput *button = controller.physicalInputProfile.buttons[key]; + if (button.isPressed) + NSLog(@"Button %@ = %s\n", key, button.isPressed ? "pressed" : "released"); + } + for (id key in controller.physicalInputProfile.axes) { + GCControllerAxisInput *axis = controller.physicalInputProfile.axes[key]; + if (axis.value != 0.0f) + NSLog(@"Axis %@ = %g\n", key, axis.value); + } + for (id key in controller.physicalInputProfile.dpads) { + GCControllerDirectionPad *dpad = controller.physicalInputProfile.dpads[key]; + if (dpad.up.isPressed || dpad.down.isPressed || dpad.left.isPressed || dpad.right.isPressed) { + NSLog(@"Hat %@ =%s%s%s%s\n", key, + dpad.up.isPressed ? " UP" : "", + dpad.down.isPressed ? " DOWN" : "", + dpad.left.isPressed ? " LEFT" : "", + dpad.right.isPressed ? " RIGHT" : ""); + } + } + } + } +#endif /* DEBUG_CONTROLLER_STATE */ + +#ifdef ENABLE_PHYSICAL_INPUT_PROFILE + if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { + NSDictionary *elements = controller.physicalInputProfile.elements; + NSDictionary *buttons = controller.physicalInputProfile.buttons; + int axis = 0; + int button = 0; + + for (id key in device->axes) { + Sint16 value; + GCControllerElement *element = elements[key]; + if ([element isKindOfClass:[GCControllerAxisInput class]]) { + value = (Sint16)([(GCControllerAxisInput *)element value] * 32767); + } else { + value = (Sint16)([(GCControllerButtonInput *)element value] * 32767); + } + SDL_PrivateJoystickAxis(joystick, axis++, value); + } + + for (id key in device->buttons) { + Uint8 value; + if (button == device->pause_button_index) { + value = (device->pause_button_pressed > 0); + } else { + value = buttons[key].isPressed; + } + SDL_PrivateJoystickButton(joystick, button++, value); + } + } else +#endif + if (controller.extendedGamepad) { + SDL_bool isstack; + GCExtendedGamepad *gamepad = controller.extendedGamepad; + + /* Axis order matches the XInput Windows mappings. */ + Sint16 axes[] = { + (Sint16)(gamepad.leftThumbstick.xAxis.value * 32767), + (Sint16)(gamepad.leftThumbstick.yAxis.value * -32767), + (Sint16)((gamepad.leftTrigger.value * 65535) - 32768), + (Sint16)(gamepad.rightThumbstick.xAxis.value * 32767), + (Sint16)(gamepad.rightThumbstick.yAxis.value * -32767), + (Sint16)((gamepad.rightTrigger.value * 65535) - 32768), + }; + + /* Button order matches the XInput Windows mappings. */ + Uint8 *buttons = SDL_small_alloc(Uint8, joystick->nbuttons, &isstack); + int button_count = 0; + + if (buttons == NULL) { + SDL_OutOfMemory(); + return; + } + + /* These buttons are part of the original MFi spec */ + buttons[button_count++] = gamepad.buttonA.isPressed; + buttons[button_count++] = gamepad.buttonB.isPressed; + buttons[button_count++] = gamepad.buttonX.isPressed; + buttons[button_count++] = gamepad.buttonY.isPressed; + buttons[button_count++] = gamepad.leftShoulder.isPressed; + buttons[button_count++] = gamepad.rightShoulder.isPressed; + + /* These buttons are available on some newer controllers */ + if (@available(macOS 10.14.1, iOS 12.1, tvOS 12.1, *)) { + if (device->button_mask & (1 << SDL_CONTROLLER_BUTTON_LEFTSTICK)) { + buttons[button_count++] = gamepad.leftThumbstickButton.isPressed; + } + if (device->button_mask & (1 << SDL_CONTROLLER_BUTTON_RIGHTSTICK)) { + buttons[button_count++] = gamepad.rightThumbstickButton.isPressed; + } + } + if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, *)) { + if (device->button_mask & (1 << SDL_CONTROLLER_BUTTON_BACK)) { + buttons[button_count++] = gamepad.buttonOptions.isPressed; + } + } + if (device->button_mask & (1 << SDL_CONTROLLER_BUTTON_START)) { + if (device->pause_button_index >= 0) { + /* Guaranteed if buttonMenu is not supported on this OS */ + buttons[button_count++] = (device->pause_button_pressed > 0); + } else { + if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, *)) { + buttons[button_count++] = gamepad.buttonMenu.isPressed; + } + } + } + + hatstate = IOS_MFIJoystickHatStateForDPad(gamepad.dpad); + + for (i = 0; i < SDL_arraysize(axes); i++) { + SDL_PrivateJoystickAxis(joystick, i, axes[i]); + } + + for (i = 0; i < button_count; i++) { + SDL_PrivateJoystickButton(joystick, i, buttons[i]); + } + + SDL_small_free(buttons, isstack); + } else if (controller.gamepad) { + SDL_bool isstack; + GCGamepad *gamepad = controller.gamepad; + + /* Button order matches the XInput Windows mappings. */ + Uint8 *buttons = SDL_small_alloc(Uint8, joystick->nbuttons, &isstack); + int button_count = 0; + + if (buttons == NULL) { + SDL_OutOfMemory(); + return; + } + + buttons[button_count++] = gamepad.buttonA.isPressed; + buttons[button_count++] = gamepad.buttonB.isPressed; + buttons[button_count++] = gamepad.buttonX.isPressed; + buttons[button_count++] = gamepad.buttonY.isPressed; + buttons[button_count++] = gamepad.leftShoulder.isPressed; + buttons[button_count++] = gamepad.rightShoulder.isPressed; + buttons[button_count++] = (device->pause_button_pressed > 0); + + hatstate = IOS_MFIJoystickHatStateForDPad(gamepad.dpad); + + for (i = 0; i < button_count; i++) { + SDL_PrivateJoystickButton(joystick, i, buttons[i]); + } + + SDL_small_free(buttons, isstack); + } +#if TARGET_OS_TV + else if (controller.microGamepad) { + GCMicroGamepad *gamepad = controller.microGamepad; + + Sint16 axes[] = { + (Sint16)(gamepad.dpad.xAxis.value * 32767), + (Sint16)(gamepad.dpad.yAxis.value * -32767), + }; + + for (i = 0; i < SDL_arraysize(axes); i++) { + SDL_PrivateJoystickAxis(joystick, i, axes[i]); + } + + Uint8 buttons[joystick->nbuttons]; + int button_count = 0; + buttons[button_count++] = gamepad.buttonA.isPressed; + buttons[button_count++] = gamepad.buttonX.isPressed; + buttons[button_count++] = (device->pause_button_pressed > 0); + + for (i = 0; i < button_count; i++) { + SDL_PrivateJoystickButton(joystick, i, buttons[i]); + } + } +#endif /* TARGET_OS_TV */ + + if (joystick->nhats > 0) { + SDL_PrivateJoystickHat(joystick, 0, hatstate); + } + + if (device->pause_button_pressed) { + /* The pause callback is instantaneous, so we extend the duration to allow "holding down" by pressing it repeatedly */ + const int PAUSE_BUTTON_PRESS_DURATION_MS = 250; + if (SDL_TICKS_PASSED(SDL_GetTicks(), device->pause_button_pressed + PAUSE_BUTTON_PRESS_DURATION_MS)) { + device->pause_button_pressed = 0; + } + } + +#ifdef ENABLE_PHYSICAL_INPUT_PROFILE + if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { + if (device->has_dualshock_touchpad) { + GCControllerDirectionPad *dpad; + + dpad = controller.physicalInputProfile.dpads[GCInputDualShockTouchpadOne]; + if (dpad.xAxis.value || dpad.yAxis.value) { + SDL_PrivateJoystickTouchpad(joystick, 0, 0, SDL_PRESSED, (1.0f + dpad.xAxis.value) * 0.5f, 1.0f - (1.0f + dpad.yAxis.value) * 0.5f, 1.0f); + } else { + SDL_PrivateJoystickTouchpad(joystick, 0, 0, SDL_RELEASED, 0.0f, 0.0f, 1.0f); + } + + dpad = controller.physicalInputProfile.dpads[GCInputDualShockTouchpadTwo]; + if (dpad.xAxis.value || dpad.yAxis.value) { + SDL_PrivateJoystickTouchpad(joystick, 0, 1, SDL_PRESSED, (1.0f + dpad.xAxis.value) * 0.5f, 1.0f - (1.0f + dpad.yAxis.value) * 0.5f, 1.0f); + } else { + SDL_PrivateJoystickTouchpad(joystick, 0, 1, SDL_RELEASED, 0.0f, 0.0f, 1.0f); + } + } + } +#endif /* ENABLE_PHYSICAL_INPUT_PROFILE */ + +#ifdef ENABLE_MFI_SENSORS + if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { + GCMotion *motion = controller.motion; + if (motion && motion.sensorsActive) { + float data[3]; + + if (motion.hasRotationRate) { + GCRotationRate rate = motion.rotationRate; + data[0] = rate.x; + data[1] = rate.z; + data[2] = -rate.y; + SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_GYRO, 0, data, 3); + } + if (motion.hasGravityAndUserAcceleration) { + GCAcceleration accel = motion.acceleration; + data[0] = -accel.x * SDL_STANDARD_GRAVITY; + data[1] = -accel.y * SDL_STANDARD_GRAVITY; + data[2] = -accel.z * SDL_STANDARD_GRAVITY; + SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_ACCEL, 0, data, 3); + } + } + } +#endif /* ENABLE_MFI_SENSORS */ + +#ifdef ENABLE_MFI_BATTERY + if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { + GCDeviceBattery *battery = controller.battery; + if (battery) { + SDL_JoystickPowerLevel ePowerLevel = SDL_JOYSTICK_POWER_UNKNOWN; + + switch (battery.batteryState) { + case GCDeviceBatteryStateDischarging: + { + float power_level = battery.batteryLevel; + if (power_level <= 0.05f) { + ePowerLevel = SDL_JOYSTICK_POWER_EMPTY; + } else if (power_level <= 0.20f) { + ePowerLevel = SDL_JOYSTICK_POWER_LOW; + } else if (power_level <= 0.70f) { + ePowerLevel = SDL_JOYSTICK_POWER_MEDIUM; + } else { + ePowerLevel = SDL_JOYSTICK_POWER_FULL; + } + } break; + case GCDeviceBatteryStateCharging: + ePowerLevel = SDL_JOYSTICK_POWER_WIRED; + break; + case GCDeviceBatteryStateFull: + ePowerLevel = SDL_JOYSTICK_POWER_FULL; + break; + default: + break; + } + + SDL_PrivateJoystickBatteryLevel(joystick, ePowerLevel); + } + } +#endif /* ENABLE_MFI_BATTERY */ + } +#endif /* SDL_JOYSTICK_MFI */ +} + +#ifdef ENABLE_MFI_RUMBLE + +@interface SDL_RumbleMotor : NSObject +@property(nonatomic, strong) CHHapticEngine *engine API_AVAILABLE(macos(10.16), ios(13.0), tvos(14.0)); +@property(nonatomic, strong) id player API_AVAILABLE(macos(10.16), ios(13.0), tvos(14.0)); +@property bool active; +@end + +@implementation SDL_RumbleMotor +{ +} + +- (void)cleanup +{ + @autoreleasepool { + if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { + if (self.player != nil) { + [self.player cancelAndReturnError:nil]; + self.player = nil; + } + if (self.engine != nil) { + [self.engine stopWithCompletionHandler:nil]; + self.engine = nil; + } + } + } +} + +- (int)setIntensity:(float)intensity +{ + @autoreleasepool { + if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { + NSError *error = nil; + CHHapticDynamicParameter *param; + + if (self.engine == nil) { + return SDL_SetError("Haptics engine was stopped"); + } + + if (intensity == 0.0f) { + if (self.player && self.active) { + [self.player stopAtTime:0 error:&error]; + } + self.active = false; + return 0; + } + + if (self.player == nil) { + CHHapticEventParameter *event_param = [[CHHapticEventParameter alloc] initWithParameterID:CHHapticEventParameterIDHapticIntensity value:1.0f]; + CHHapticEvent *event = [[CHHapticEvent alloc] initWithEventType:CHHapticEventTypeHapticContinuous parameters:[NSArray arrayWithObjects:event_param, nil] relativeTime:0 duration:GCHapticDurationInfinite]; + CHHapticPattern *pattern = [[CHHapticPattern alloc] initWithEvents:[NSArray arrayWithObject:event] parameters:[[NSArray alloc] init] error:&error]; + if (error != nil) { + return SDL_SetError("Couldn't create haptic pattern: %s", [error.localizedDescription UTF8String]); + } + + self.player = [self.engine createPlayerWithPattern:pattern error:&error]; + if (error != nil) { + return SDL_SetError("Couldn't create haptic player: %s", [error.localizedDescription UTF8String]); + } + self.active = false; + } + + param = [[CHHapticDynamicParameter alloc] initWithParameterID:CHHapticDynamicParameterIDHapticIntensityControl value:intensity relativeTime:0]; + [self.player sendParameters:[NSArray arrayWithObject:param] atTime:0 error:&error]; + if (error != nil) { + return SDL_SetError("Couldn't update haptic player: %s", [error.localizedDescription UTF8String]); + } + + if (!self.active) { + [self.player startAtTime:0 error:&error]; + self.active = true; + } + } + + return 0; + } +} + +- (id)initWithController:(GCController *)controller locality:(GCHapticsLocality)locality API_AVAILABLE(macos(10.16), ios(14.0), tvos(14.0)) +{ + @autoreleasepool { + NSError *error; + __weak __typeof(self) weakSelf; + self = [super init]; + weakSelf = self; + + self.engine = [controller.haptics createEngineWithLocality:locality]; + if (self.engine == nil) { + SDL_SetError("Couldn't create haptics engine"); + return nil; + } + + [self.engine startAndReturnError:&error]; + if (error != nil) { + SDL_SetError("Couldn't start haptics engine"); + return nil; + } + + self.engine.stoppedHandler = ^(CHHapticEngineStoppedReason stoppedReason) { + SDL_RumbleMotor *_this = weakSelf; + if (_this == nil) { + return; + } + + _this.player = nil; + _this.engine = nil; + }; + self.engine.resetHandler = ^{ + SDL_RumbleMotor *_this = weakSelf; + if (_this == nil) { + return; + } + + _this.player = nil; + [_this.engine startAndReturnError:nil]; + }; + + return self; + } +} + +@end + +@interface SDL_RumbleContext : NSObject +@property(nonatomic, strong) SDL_RumbleMotor *lowFrequencyMotor; +@property(nonatomic, strong) SDL_RumbleMotor *highFrequencyMotor; +@property(nonatomic, strong) SDL_RumbleMotor *leftTriggerMotor; +@property(nonatomic, strong) SDL_RumbleMotor *rightTriggerMotor; +@end + +@implementation SDL_RumbleContext +{ +} + +- (id)initWithLowFrequencyMotor:(SDL_RumbleMotor *)low_frequency_motor + HighFrequencyMotor:(SDL_RumbleMotor *)high_frequency_motor + LeftTriggerMotor:(SDL_RumbleMotor *)left_trigger_motor + RightTriggerMotor:(SDL_RumbleMotor *)right_trigger_motor +{ + self = [super init]; + self.lowFrequencyMotor = low_frequency_motor; + self.highFrequencyMotor = high_frequency_motor; + self.leftTriggerMotor = left_trigger_motor; + self.rightTriggerMotor = right_trigger_motor; + return self; +} + +- (int)rumbleWithLowFrequency:(Uint16)low_frequency_rumble andHighFrequency:(Uint16)high_frequency_rumble +{ + int result = 0; + + result += [self.lowFrequencyMotor setIntensity:((float)low_frequency_rumble / 65535.0f)]; + result += [self.highFrequencyMotor setIntensity:((float)high_frequency_rumble / 65535.0f)]; + return ((result < 0) ? -1 : 0); +} + +- (int)rumbleLeftTrigger:(Uint16)left_rumble andRightTrigger:(Uint16)right_rumble +{ + int result = 0; + + if (self.leftTriggerMotor && self.rightTriggerMotor) { + result += [self.leftTriggerMotor setIntensity:((float)left_rumble / 65535.0f)]; + result += [self.rightTriggerMotor setIntensity:((float)right_rumble / 65535.0f)]; + } else { + result = SDL_Unsupported(); + } + return ((result < 0) ? -1 : 0); +} + +- (void)cleanup +{ + [self.lowFrequencyMotor cleanup]; + [self.highFrequencyMotor cleanup]; +} + +@end + +static SDL_RumbleContext *IOS_JoystickInitRumble(GCController *controller) +{ + @autoreleasepool { + if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { + SDL_RumbleMotor *low_frequency_motor = [[SDL_RumbleMotor alloc] initWithController:controller locality:GCHapticsLocalityLeftHandle]; + SDL_RumbleMotor *high_frequency_motor = [[SDL_RumbleMotor alloc] initWithController:controller locality:GCHapticsLocalityRightHandle]; + SDL_RumbleMotor *left_trigger_motor = [[SDL_RumbleMotor alloc] initWithController:controller locality:GCHapticsLocalityLeftTrigger]; + SDL_RumbleMotor *right_trigger_motor = [[SDL_RumbleMotor alloc] initWithController:controller locality:GCHapticsLocalityRightTrigger]; + if (low_frequency_motor && high_frequency_motor) { + return [[SDL_RumbleContext alloc] initWithLowFrequencyMotor:low_frequency_motor + HighFrequencyMotor:high_frequency_motor + LeftTriggerMotor:left_trigger_motor + RightTriggerMotor:right_trigger_motor]; + } + } + } + return nil; +} + +#endif /* ENABLE_MFI_RUMBLE */ + +static int IOS_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ +#ifdef ENABLE_MFI_RUMBLE + SDL_JoystickDeviceItem *device = joystick->hwdata; + + if (device == NULL) { + return SDL_SetError("Controller is no longer connected"); + } + + if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { + if (!device->rumble && device->controller && device->controller.haptics) { + SDL_RumbleContext *rumble = IOS_JoystickInitRumble(device->controller); + if (rumble) { + device->rumble = (void *)CFBridgingRetain(rumble); + } + } + } + + if (device->rumble) { + SDL_RumbleContext *rumble = (__bridge SDL_RumbleContext *)device->rumble; + return [rumble rumbleWithLowFrequency:low_frequency_rumble andHighFrequency:high_frequency_rumble]; + } else { + return SDL_Unsupported(); + } +#else + return SDL_Unsupported(); +#endif +} + +static int IOS_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) +{ +#ifdef ENABLE_MFI_RUMBLE + SDL_JoystickDeviceItem *device = joystick->hwdata; + + if (device == NULL) { + return SDL_SetError("Controller is no longer connected"); + } + + if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { + if (!device->rumble && device->controller && device->controller.haptics) { + SDL_RumbleContext *rumble = IOS_JoystickInitRumble(device->controller); + if (rumble) { + device->rumble = (void *)CFBridgingRetain(rumble); + } + } + } + + if (device->rumble) { + SDL_RumbleContext *rumble = (__bridge SDL_RumbleContext *)device->rumble; + return [rumble rumbleLeftTrigger:left_rumble andRightTrigger:right_rumble]; + } else { + return SDL_Unsupported(); + } +#else + return SDL_Unsupported(); +#endif +} + +static Uint32 IOS_JoystickGetCapabilities(SDL_Joystick *joystick) +{ + Uint32 result = 0; + +#if defined(ENABLE_MFI_LIGHT) || defined(ENABLE_MFI_RUMBLE) + @autoreleasepool { + SDL_JoystickDeviceItem *device = joystick->hwdata; + + if (device == NULL) { + return 0; + } + + if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { + GCController *controller = device->controller; +#ifdef ENABLE_MFI_LIGHT + if (controller.light) { + result |= SDL_JOYCAP_LED; + } +#endif + +#ifdef ENABLE_MFI_RUMBLE + if (controller.haptics) { + for (GCHapticsLocality locality in controller.haptics.supportedLocalities) { + if ([locality isEqualToString:GCHapticsLocalityHandles]) { + result |= SDL_JOYCAP_RUMBLE; + } else if ([locality isEqualToString:GCHapticsLocalityTriggers]) { + result |= SDL_JOYCAP_RUMBLE_TRIGGERS; + } + } + } +#endif + } + } +#endif /* ENABLE_MFI_LIGHT || ENABLE_MFI_RUMBLE */ + + return result; +} + +static int IOS_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ +#ifdef ENABLE_MFI_LIGHT + @autoreleasepool { + SDL_JoystickDeviceItem *device = joystick->hwdata; + + if (device == NULL) { + return SDL_SetError("Controller is no longer connected"); + } + + if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { + GCController *controller = device->controller; + GCDeviceLight *light = controller.light; + if (light) { + light.color = [[GCColor alloc] initWithRed:(float)red / 255.0f + green:(float)green / 255.0f + blue:(float)blue / 255.0f]; + return 0; + } + } + } +#endif /* ENABLE_MFI_LIGHT */ + + return SDL_Unsupported(); +} + +static int IOS_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + +static int IOS_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled) +{ +#ifdef ENABLE_MFI_SENSORS + @autoreleasepool { + SDL_JoystickDeviceItem *device = joystick->hwdata; + + if (device == NULL) { + return SDL_SetError("Controller is no longer connected"); + } + + if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { + GCController *controller = device->controller; + GCMotion *motion = controller.motion; + if (motion) { + motion.sensorsActive = enabled ? YES : NO; + return 0; + } + } + } +#endif /* ENABLE_MFI_SENSORS */ + + return SDL_Unsupported(); +} + +static void IOS_JoystickUpdate(SDL_Joystick *joystick) +{ + SDL_JoystickDeviceItem *device = joystick->hwdata; + + if (device == NULL) { + return; + } + + if (device->accelerometer) { + IOS_AccelerometerUpdate(joystick); + } else if (device->controller) { + IOS_MFIJoystickUpdate(joystick); + } +} + +static void IOS_JoystickClose(SDL_Joystick *joystick) +{ + SDL_JoystickDeviceItem *device = joystick->hwdata; + + if (device == NULL) { + return; + } + + device->joystick = NULL; + + @autoreleasepool { +#ifdef ENABLE_MFI_RUMBLE + if (device->rumble) { + SDL_RumbleContext *rumble = (__bridge SDL_RumbleContext *)device->rumble; + + [rumble cleanup]; + CFRelease(device->rumble); + device->rumble = NULL; + } +#endif /* ENABLE_MFI_RUMBLE */ + + if (device->accelerometer) { +#ifdef SDL_JOYSTICK_iOS_ACCELEROMETER + [motionManager stopAccelerometerUpdates]; +#endif + } else if (device->controller) { +#ifdef SDL_JOYSTICK_MFI + GCController *controller = device->controller; + controller.controllerPausedHandler = nil; + controller.playerIndex = -1; + +#ifdef ENABLE_MFI_SYSTEM_GESTURE_STATE + if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { + for (id key in controller.physicalInputProfile.buttons) { + GCControllerButtonInput *button = controller.physicalInputProfile.buttons[key]; + if ([button isBoundToSystemGesture]) { + button.preferredSystemGestureState = GCSystemGestureStateEnabled; + } + } + } +#endif /* ENABLE_MFI_SYSTEM_GESTURE_STATE */ + +#endif /* SDL_JOYSTICK_MFI */ + } + } + if (device->is_siri_remote) { + --SDL_AppleTVRemoteOpenedAsJoystick; + } +} + +static void IOS_JoystickQuit(void) +{ + @autoreleasepool { +#ifdef SDL_JOYSTICK_MFI + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + + if (connectObserver) { + [center removeObserver:connectObserver name:GCControllerDidConnectNotification object:nil]; + connectObserver = nil; + } + + if (disconnectObserver) { + [center removeObserver:disconnectObserver name:GCControllerDidDisconnectNotification object:nil]; + disconnectObserver = nil; + } + +#if TARGET_OS_TV + SDL_DelHintCallback(SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION, + SDL_AppleTVRemoteRotationHintChanged, NULL); +#endif /* TARGET_OS_TV */ +#endif /* SDL_JOYSTICK_MFI */ + + while (deviceList != NULL) { + IOS_RemoveJoystickDevice(deviceList); + } + +#ifdef SDL_JOYSTICK_iOS_ACCELEROMETER + motionManager = nil; +#endif + } + + numjoysticks = 0; +} + +static SDL_bool IOS_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) +{ +#ifdef ENABLE_PHYSICAL_INPUT_PROFILE + SDL_JoystickDeviceItem *device = GetDeviceForIndex(device_index); + if (device == NULL) { + return SDL_FALSE; + } + if (device->accelerometer) { + return SDL_FALSE; + } + + if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { + int axis = 0; + int button = 0; + for (id key in device->axes) { + if ([(NSString *)key isEqualToString:@"Left Thumbstick X Axis"] || + [(NSString *)key isEqualToString:@"Direction Pad X Axis"]) { + out->leftx.kind = EMappingKind_Axis; + out->leftx.target = axis; + } else if ([(NSString *)key isEqualToString:@"Left Thumbstick Y Axis"] || + [(NSString *)key isEqualToString:@"Direction Pad Y Axis"]) { + out->lefty.kind = EMappingKind_Axis; + out->lefty.target = axis; + out->lefty.axis_reversed = SDL_TRUE; + } else if ([(NSString *)key isEqualToString:@"Right Thumbstick X Axis"]) { + out->rightx.kind = EMappingKind_Axis; + out->rightx.target = axis; + } else if ([(NSString *)key isEqualToString:@"Right Thumbstick Y Axis"]) { + out->righty.kind = EMappingKind_Axis; + out->righty.target = axis; + out->righty.axis_reversed = SDL_TRUE; + } else if ([(NSString *)key isEqualToString:GCInputLeftTrigger]) { + out->lefttrigger.kind = EMappingKind_Axis; + out->lefttrigger.target = axis; + out->lefttrigger.half_axis_positive = SDL_TRUE; + } else if ([(NSString *)key isEqualToString:GCInputRightTrigger]) { + out->righttrigger.kind = EMappingKind_Axis; + out->righttrigger.target = axis; + out->righttrigger.half_axis_positive = SDL_TRUE; + } + ++axis; + } + + for (id key in device->buttons) { + SDL_InputMapping *mapping = NULL; + + if ([(NSString *)key isEqualToString:GCInputButtonA]) { + if (device->is_siri_remote > 1) { + /* GCInputButtonA is triggered for any D-Pad press, ignore it in favor of "Button Center" */ + } else { + mapping = &out->a; + } + } else if ([(NSString *)key isEqualToString:GCInputButtonB]) { + if (device->is_switch_joyconL || device->is_switch_joyconR) { + mapping = &out->x; + } else { + mapping = &out->b; + } + } else if ([(NSString *)key isEqualToString:GCInputButtonX]) { + if (device->is_switch_joyconL || device->is_switch_joyconR) { + mapping = &out->b; + } else { + mapping = &out->x; + } + } else if ([(NSString *)key isEqualToString:GCInputButtonY]) { + mapping = &out->y; + } else if ([(NSString *)key isEqualToString:@"Direction Pad Left"]) { + mapping = &out->dpleft; + } else if ([(NSString *)key isEqualToString:@"Direction Pad Right"]) { + mapping = &out->dpright; + } else if ([(NSString *)key isEqualToString:@"Direction Pad Up"]) { + mapping = &out->dpup; + } else if ([(NSString *)key isEqualToString:@"Direction Pad Down"]) { + mapping = &out->dpdown; + } else if ([(NSString *)key isEqualToString:@"Cardinal Direction Pad Left"]) { + mapping = &out->dpleft; + } else if ([(NSString *)key isEqualToString:@"Cardinal Direction Pad Right"]) { + mapping = &out->dpright; + } else if ([(NSString *)key isEqualToString:@"Cardinal Direction Pad Up"]) { + mapping = &out->dpup; + } else if ([(NSString *)key isEqualToString:@"Cardinal Direction Pad Down"]) { + mapping = &out->dpdown; + } else if ([(NSString *)key isEqualToString:GCInputLeftShoulder]) { + mapping = &out->leftshoulder; + } else if ([(NSString *)key isEqualToString:GCInputRightShoulder]) { + mapping = &out->rightshoulder; + } else if ([(NSString *)key isEqualToString:GCInputLeftThumbstickButton]) { + mapping = &out->leftstick; + } else if ([(NSString *)key isEqualToString:GCInputRightThumbstickButton]) { + mapping = &out->rightstick; + } else if ([(NSString *)key isEqualToString:@"Button Home"]) { + mapping = &out->guide; + } else if ([(NSString *)key isEqualToString:GCInputButtonMenu]) { + if (device->is_siri_remote) { + mapping = &out->b; + } else { + mapping = &out->start; + } + } else if ([(NSString *)key isEqualToString:GCInputButtonOptions]) { + mapping = &out->back; + } else if ([(NSString *)key isEqualToString:@"Button Share"]) { + mapping = &out->misc1; + } else if ([(NSString *)key isEqualToString:GCInputXboxPaddleOne]) { + mapping = &out->paddle1; + } else if ([(NSString *)key isEqualToString:GCInputXboxPaddleTwo]) { + mapping = &out->paddle3; + } else if ([(NSString *)key isEqualToString:GCInputXboxPaddleThree]) { + mapping = &out->paddle2; + } else if ([(NSString *)key isEqualToString:GCInputXboxPaddleFour]) { + mapping = &out->paddle4; + } else if ([(NSString *)key isEqualToString:GCInputLeftTrigger]) { + mapping = &out->lefttrigger; + } else if ([(NSString *)key isEqualToString:GCInputRightTrigger]) { + mapping = &out->righttrigger; + } else if ([(NSString *)key isEqualToString:GCInputDualShockTouchpadButton]) { + mapping = &out->touchpad; + } else if ([(NSString *)key isEqualToString:@"Button Center"]) { + mapping = &out->a; + } + if (mapping && mapping->kind == EMappingKind_None) { + mapping->kind = EMappingKind_Button; + mapping->target = button; + } + ++button; + } + + return SDL_TRUE; + } +#endif /* ENABLE_PHYSICAL_INPUT_PROFILE */ + + return SDL_FALSE; +} + +#if defined(SDL_JOYSTICK_MFI) && defined(__MACOSX__) +SDL_bool IOS_SupportedHIDDevice(IOHIDDeviceRef device) +{ + if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_MFI, SDL_TRUE)) { + return SDL_FALSE; + } + + if (@available(macOS 10.16, *)) { + const int MAX_ATTEMPTS = 3; + for (int attempt = 0; attempt < MAX_ATTEMPTS; ++attempt) { + if ([GCController supportsHIDDevice:device]) { + return SDL_TRUE; + } + + /* The framework may not have seen the device yet */ + SDL_Delay(10); + } + } + return SDL_FALSE; +} +#endif + +#if defined(SDL_JOYSTICK_MFI) && defined(ENABLE_PHYSICAL_INPUT_PROFILE) +/* NOLINTNEXTLINE(readability-non-const-parameter): getCString takes a non-const char* */ +static void GetAppleSFSymbolsNameForElement(GCControllerElement *element, char *name) +{ + if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { + if (element) { + [element.sfSymbolsName getCString:name maxLength:255 encoding:NSASCIIStringEncoding]; + } + } +} + +static GCControllerDirectionPad *GetDirectionalPadForController(GCController *controller) +{ + if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { + return controller.physicalInputProfile.dpads[GCInputDirectionPad]; + } + + if (controller.extendedGamepad) { + return controller.extendedGamepad.dpad; + } + + if (controller.gamepad) { + return controller.gamepad.dpad; + } + + if (controller.microGamepad) { + return controller.microGamepad.dpad; + } + + return nil; +} +#endif /* SDL_JOYSTICK_MFI && ENABLE_PHYSICAL_INPUT_PROFILE */ + +static char elementName[256]; + +const char *IOS_GameControllerGetAppleSFSymbolsNameForButton(SDL_GameController *gamecontroller, SDL_GameControllerButton button) +{ + elementName[0] = '\0'; +#if defined(SDL_JOYSTICK_MFI) && defined(ENABLE_PHYSICAL_INPUT_PROFILE) + if (gamecontroller && SDL_GameControllerGetJoystick(gamecontroller)->driver == &SDL_IOS_JoystickDriver) { + if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { + GCController *controller = SDL_GameControllerGetJoystick(gamecontroller)->hwdata->controller; + if ([controller respondsToSelector:@selector(physicalInputProfile)]) { + NSDictionary *elements = controller.physicalInputProfile.elements; + switch (button) { + case SDL_CONTROLLER_BUTTON_A: + GetAppleSFSymbolsNameForElement(elements[GCInputButtonA], elementName); + break; + case SDL_CONTROLLER_BUTTON_B: + GetAppleSFSymbolsNameForElement(elements[GCInputButtonB], elementName); + break; + case SDL_CONTROLLER_BUTTON_X: + GetAppleSFSymbolsNameForElement(elements[GCInputButtonX], elementName); + break; + case SDL_CONTROLLER_BUTTON_Y: + GetAppleSFSymbolsNameForElement(elements[GCInputButtonY], elementName); + break; + case SDL_CONTROLLER_BUTTON_BACK: + GetAppleSFSymbolsNameForElement(elements[GCInputButtonOptions], elementName); + break; + case SDL_CONTROLLER_BUTTON_GUIDE: + GetAppleSFSymbolsNameForElement(elements[GCInputButtonHome], elementName); + break; + case SDL_CONTROLLER_BUTTON_START: + GetAppleSFSymbolsNameForElement(elements[GCInputButtonMenu], elementName); + break; + case SDL_CONTROLLER_BUTTON_LEFTSTICK: + GetAppleSFSymbolsNameForElement(elements[GCInputLeftThumbstickButton], elementName); + break; + case SDL_CONTROLLER_BUTTON_RIGHTSTICK: + GetAppleSFSymbolsNameForElement(elements[GCInputRightThumbstickButton], elementName); + break; + case SDL_CONTROLLER_BUTTON_LEFTSHOULDER: + GetAppleSFSymbolsNameForElement(elements[GCInputLeftShoulder], elementName); + break; + case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: + GetAppleSFSymbolsNameForElement(elements[GCInputRightShoulder], elementName); + break; + case SDL_CONTROLLER_BUTTON_DPAD_UP: + { + GCControllerDirectionPad *dpad = GetDirectionalPadForController(controller); + if (dpad) { + GetAppleSFSymbolsNameForElement(dpad.up, elementName); + if (SDL_strlen(elementName) == 0) { + SDL_strlcpy(elementName, "dpad.up.fill", sizeof(elementName)); + } + } + break; + } + case SDL_CONTROLLER_BUTTON_DPAD_DOWN: + { + GCControllerDirectionPad *dpad = GetDirectionalPadForController(controller); + if (dpad) { + GetAppleSFSymbolsNameForElement(dpad.down, elementName); + if (SDL_strlen(elementName) == 0) { + SDL_strlcpy(elementName, "dpad.down.fill", sizeof(elementName)); + } + } + break; + } + case SDL_CONTROLLER_BUTTON_DPAD_LEFT: + { + GCControllerDirectionPad *dpad = GetDirectionalPadForController(controller); + if (dpad) { + GetAppleSFSymbolsNameForElement(dpad.left, elementName); + if (SDL_strlen(elementName) == 0) { + SDL_strlcpy(elementName, "dpad.left.fill", sizeof(elementName)); + } + } + break; + } + case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: + { + GCControllerDirectionPad *dpad = GetDirectionalPadForController(controller); + if (dpad) { + GetAppleSFSymbolsNameForElement(dpad.right, elementName); + if (SDL_strlen(elementName) == 0) { + SDL_strlcpy(elementName, "dpad.right.fill", sizeof(elementName)); + } + } + break; + } + case SDL_CONTROLLER_BUTTON_MISC1: + GetAppleSFSymbolsNameForElement(elements[GCInputDualShockTouchpadButton], elementName); + break; + case SDL_CONTROLLER_BUTTON_PADDLE1: + GetAppleSFSymbolsNameForElement(elements[GCInputXboxPaddleOne], elementName); + break; + case SDL_CONTROLLER_BUTTON_PADDLE2: + GetAppleSFSymbolsNameForElement(elements[GCInputXboxPaddleTwo], elementName); + break; + case SDL_CONTROLLER_BUTTON_PADDLE3: + GetAppleSFSymbolsNameForElement(elements[GCInputXboxPaddleThree], elementName); + break; + case SDL_CONTROLLER_BUTTON_PADDLE4: + GetAppleSFSymbolsNameForElement(elements[GCInputXboxPaddleFour], elementName); + break; + case SDL_CONTROLLER_BUTTON_TOUCHPAD: + GetAppleSFSymbolsNameForElement(elements[GCInputDualShockTouchpadButton], elementName); + break; + default: + break; + } + } + } + } +#endif + return elementName; +} + +const char *IOS_GameControllerGetAppleSFSymbolsNameForAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis) +{ + elementName[0] = '\0'; +#if defined(SDL_JOYSTICK_MFI) && defined(ENABLE_PHYSICAL_INPUT_PROFILE) + if (gamecontroller && SDL_GameControllerGetJoystick(gamecontroller)->driver == &SDL_IOS_JoystickDriver) { + if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { + GCController *controller = SDL_GameControllerGetJoystick(gamecontroller)->hwdata->controller; + if ([controller respondsToSelector:@selector(physicalInputProfile)]) { + NSDictionary *elements = controller.physicalInputProfile.elements; + switch (axis) { + case SDL_CONTROLLER_AXIS_LEFTX: + GetAppleSFSymbolsNameForElement(elements[GCInputLeftThumbstick], elementName); + break; + case SDL_CONTROLLER_AXIS_LEFTY: + GetAppleSFSymbolsNameForElement(elements[GCInputLeftThumbstick], elementName); + break; + case SDL_CONTROLLER_AXIS_RIGHTX: + GetAppleSFSymbolsNameForElement(elements[GCInputRightThumbstick], elementName); + break; + case SDL_CONTROLLER_AXIS_RIGHTY: + GetAppleSFSymbolsNameForElement(elements[GCInputRightThumbstick], elementName); + break; + case SDL_CONTROLLER_AXIS_TRIGGERLEFT: + GetAppleSFSymbolsNameForElement(elements[GCInputLeftTrigger], elementName); + break; + case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: + GetAppleSFSymbolsNameForElement(elements[GCInputRightTrigger], elementName); + break; + default: + break; + } + } + } + } +#endif + return *elementName ? elementName : NULL; +} + +SDL_JoystickDriver SDL_IOS_JoystickDriver = { + IOS_JoystickInit, + IOS_JoystickGetCount, + IOS_JoystickDetect, + IOS_JoystickGetDeviceName, + IOS_JoystickGetDevicePath, + IOS_JoystickGetDeviceSteamVirtualGamepadSlot, + IOS_JoystickGetDevicePlayerIndex, + IOS_JoystickSetDevicePlayerIndex, + IOS_JoystickGetDeviceGUID, + IOS_JoystickGetDeviceInstanceID, + IOS_JoystickOpen, + IOS_JoystickRumble, + IOS_JoystickRumbleTriggers, + IOS_JoystickGetCapabilities, + IOS_JoystickSetLED, + IOS_JoystickSendEffect, + IOS_JoystickSetSensorsEnabled, + IOS_JoystickUpdate, + IOS_JoystickClose, + IOS_JoystickQuit, + IOS_JoystickGetGamepadMapping +}; + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/joystick/iphoneos/SDL_sysjoystick_c.h b/SDL2-2.30.5/src/joystick/iphoneos/SDL_mfijoystick_c.h similarity index 68% rename from SDL2-2.0.12/src/joystick/iphoneos/SDL_sysjoystick_c.h rename to SDL2-2.30.5/src/joystick/iphoneos/SDL_mfijoystick_c.h index 0ae00ed..84a4e71 100644 --- a/SDL2-2.0.12/src/joystick/iphoneos/SDL_sysjoystick_c.h +++ b/SDL2-2.30.5/src/joystick/iphoneos/SDL_mfijoystick_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,17 +26,19 @@ #include "SDL_stdinc.h" #include "../SDL_sysjoystick.h" +#import +#import + @class GCController; typedef struct joystick_hwdata { SDL_bool accelerometer; - SDL_bool remote; GCController __unsafe_unretained *controller; - SDL_bool uses_pause_handler; - int num_pause_presses; - Uint32 pause_button_down_time; + void *rumble; + int pause_button_index; + Uint32 pause_button_pressed; char *name; SDL_Joystick *joystick; @@ -46,7 +48,24 @@ typedef struct joystick_hwdata int naxes; int nbuttons; int nhats; - Uint16 button_mask; + Uint32 button_mask; + SDL_bool is_xbox; + SDL_bool is_ps4; + SDL_bool is_ps5; + SDL_bool is_switch_pro; + SDL_bool is_switch_joycon_pair; + SDL_bool is_switch_joyconL; + SDL_bool is_switch_joyconR; + SDL_bool is_stadia; + SDL_bool is_backbone_one; + int is_siri_remote; + + NSArray __unsafe_unretained *axes; + NSArray __unsafe_unretained *buttons; + + SDL_bool has_dualshock_touchpad; + SDL_bool has_xbox_paddles; + SDL_bool has_xbox_share_button; struct joystick_hwdata *next; } joystick_hwdata; @@ -55,5 +74,4 @@ typedef joystick_hwdata SDL_JoystickDeviceItem; #endif /* SDL_JOYSTICK_IOS_H */ - /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/joystick/linux/SDL_sysjoystick.c b/SDL2-2.30.5/src/joystick/linux/SDL_sysjoystick.c new file mode 100644 index 0000000..bb7c31c --- /dev/null +++ b/SDL2-2.30.5/src/joystick/linux/SDL_sysjoystick.c @@ -0,0 +1,2814 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_JOYSTICK_LINUX + +#ifndef SDL_INPUT_LINUXEV +#error SDL now requires a Linux 2.4+ kernel with /dev/input/event support. +#endif + +/* This is the Linux implementation of the SDL joystick API */ + +#include +#include /* errno, strerror */ +#include +#include /* For the definition of PATH_MAX */ +#ifdef HAVE_INOTIFY +#include +#endif +#include +#include +#include +#include + +#include "SDL_hints.h" +#include "SDL_joystick.h" +#include "SDL_log.h" +#include "SDL_endian.h" +#include "SDL_timer.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" +#include "../hidapi/SDL_hidapijoystick_c.h" + +/* This isn't defined in older Linux kernel headers */ +#ifndef MSC_TIMESTAMP +#define MSC_TIMESTAMP 0x05 +#endif + +#ifndef SYN_DROPPED +#define SYN_DROPPED 3 +#endif +#ifndef BTN_NORTH +#define BTN_NORTH 0x133 +#endif +#ifndef BTN_WEST +#define BTN_WEST 0x134 +#endif +#ifndef BTN_DPAD_UP +#define BTN_DPAD_UP 0x220 +#endif +#ifndef BTN_DPAD_DOWN +#define BTN_DPAD_DOWN 0x221 +#endif +#ifndef BTN_DPAD_LEFT +#define BTN_DPAD_LEFT 0x222 +#endif +#ifndef BTN_DPAD_RIGHT +#define BTN_DPAD_RIGHT 0x223 +#endif + +#ifndef BTN_TRIGGER_HAPPY +#define BTN_TRIGGER_HAPPY 0x2c0 +#define BTN_TRIGGER_HAPPY1 0x2c0 +#define BTN_TRIGGER_HAPPY2 0x2c1 +#define BTN_TRIGGER_HAPPY3 0x2c2 +#define BTN_TRIGGER_HAPPY4 0x2c3 +#define BTN_TRIGGER_HAPPY5 0x2c4 +#define BTN_TRIGGER_HAPPY6 0x2c5 +#define BTN_TRIGGER_HAPPY7 0x2c6 +#define BTN_TRIGGER_HAPPY8 0x2c7 +#define BTN_TRIGGER_HAPPY9 0x2c8 +#define BTN_TRIGGER_HAPPY10 0x2c9 +#define BTN_TRIGGER_HAPPY11 0x2ca +#define BTN_TRIGGER_HAPPY12 0x2cb +#define BTN_TRIGGER_HAPPY13 0x2cc +#define BTN_TRIGGER_HAPPY14 0x2cd +#define BTN_TRIGGER_HAPPY15 0x2ce +#define BTN_TRIGGER_HAPPY16 0x2cf +#define BTN_TRIGGER_HAPPY17 0x2d0 +#define BTN_TRIGGER_HAPPY18 0x2d1 +#define BTN_TRIGGER_HAPPY19 0x2d2 +#define BTN_TRIGGER_HAPPY20 0x2d3 +#define BTN_TRIGGER_HAPPY21 0x2d4 +#define BTN_TRIGGER_HAPPY22 0x2d5 +#define BTN_TRIGGER_HAPPY23 0x2d6 +#define BTN_TRIGGER_HAPPY24 0x2d7 +#define BTN_TRIGGER_HAPPY25 0x2d8 +#define BTN_TRIGGER_HAPPY26 0x2d9 +#define BTN_TRIGGER_HAPPY27 0x2da +#define BTN_TRIGGER_HAPPY28 0x2db +#define BTN_TRIGGER_HAPPY29 0x2dc +#define BTN_TRIGGER_HAPPY30 0x2dd +#define BTN_TRIGGER_HAPPY31 0x2de +#define BTN_TRIGGER_HAPPY32 0x2df +#define BTN_TRIGGER_HAPPY33 0x2e0 +#define BTN_TRIGGER_HAPPY34 0x2e1 +#define BTN_TRIGGER_HAPPY35 0x2e2 +#define BTN_TRIGGER_HAPPY36 0x2e3 +#define BTN_TRIGGER_HAPPY37 0x2e4 +#define BTN_TRIGGER_HAPPY38 0x2e5 +#define BTN_TRIGGER_HAPPY39 0x2e6 +#define BTN_TRIGGER_HAPPY40 0x2e7 +#endif + + +#include "../../core/linux/SDL_evdev_capabilities.h" +#include "../../core/linux/SDL_udev.h" +#include "../../core/linux/SDL_sandbox.h" + +#if 0 +#define DEBUG_INPUT_EVENTS 1 +#endif + +#if 0 +#define DEBUG_GAMEPAD_MAPPING 1 +#endif + +typedef enum +{ + ENUMERATION_UNSET, + ENUMERATION_LIBUDEV, + ENUMERATION_FALLBACK +} EnumerationMethod; + +static EnumerationMethod enumeration_method = ENUMERATION_UNSET; + +static SDL_bool IsJoystickJSNode(const char *node); +static void MaybeAddDevice(const char *path); +static void MaybeRemoveDevice(const char *path); + +/* A linked list of available joysticks */ +typedef struct SDL_joylist_item +{ + SDL_JoystickID device_instance; + char *path; /* "/dev/input/event2" or whatever */ + char *name; /* "SideWinder 3D Pro" or whatever */ + SDL_JoystickGUID guid; + dev_t devnum; + int steam_virtual_gamepad_slot; + struct joystick_hwdata *hwdata; + struct SDL_joylist_item *next; + + /* Steam Controller support */ + SDL_bool m_bSteamController; + + SDL_bool checked_mapping; + SDL_GamepadMapping *mapping; +} SDL_joylist_item; + +/* A linked list of available gamepad sensors */ +typedef struct SDL_sensorlist_item +{ + char *path; /* "/dev/input/event2" or whatever */ + dev_t devnum; + struct joystick_hwdata *hwdata; + struct SDL_sensorlist_item *next; +} SDL_sensorlist_item; + +static SDL_bool SDL_classic_joysticks = SDL_FALSE; +static SDL_joylist_item *SDL_joylist SDL_GUARDED_BY(SDL_joystick_lock) = NULL; +static SDL_joylist_item *SDL_joylist_tail SDL_GUARDED_BY(SDL_joystick_lock) = NULL; +static int numjoysticks SDL_GUARDED_BY(SDL_joystick_lock) = 0; +static SDL_sensorlist_item *SDL_sensorlist SDL_GUARDED_BY(SDL_joystick_lock) = NULL; +static int inotify_fd = -1; + +static Uint32 last_joy_detect_time; +static time_t last_input_dir_mtime; + +static void FixupDeviceInfoForMapping(int fd, struct input_id *inpid) +{ + if (inpid->vendor == 0x045e && inpid->product == 0x0b05 && inpid->version == 0x0903) { + /* This is a Microsoft Xbox One Elite Series 2 controller */ + unsigned long keybit[NBITS(KEY_MAX)] = { 0 }; + + /* The first version of the firmware duplicated all the inputs */ + if ((ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) >= 0) && + test_bit(0x2c0, keybit)) { + /* Change the version to 0x0902, so we can map it differently */ + inpid->version = 0x0902; + } + } + + /* For Atari vcs modern and classic controllers have the version reflecting + * firmware version, but the mapping stays stable so ignore + * version information */ + if (inpid->vendor == 0x3250 && (inpid->product == 0x1001 || inpid->product == 0x1002)) { + inpid->version = 0; + } +} + +#ifdef SDL_JOYSTICK_HIDAPI +static SDL_bool IsVirtualJoystick(Uint16 vendor, Uint16 product, Uint16 version, const char *name) +{ + if (vendor == USB_VENDOR_MICROSOFT && product == USB_PRODUCT_XBOX_ONE_S && version == 0 && + SDL_strcmp(name, "Xbox One S Controller") == 0) { + /* This is the virtual device created by the xow driver */ + return SDL_TRUE; + } + return SDL_FALSE; +} +#endif /* SDL_JOYSTICK_HIDAPI */ + +static SDL_bool GetSteamVirtualGamepadSlot(int fd, int *slot) +{ + char name[128]; + + if (ioctl(fd, EVIOCGNAME(sizeof(name)), name) > 0) { + const char *digits = SDL_strstr(name, "pad "); + if (digits) { + digits += 4; + if (SDL_isdigit(*digits)) { + *slot = SDL_atoi(digits); + return SDL_TRUE; + } + } + } + return SDL_FALSE; +} + +static int GuessDeviceClass(int fd) +{ + unsigned long evbit[NBITS(EV_MAX)] = { 0 }; + unsigned long keybit[NBITS(KEY_MAX)] = { 0 }; + unsigned long absbit[NBITS(ABS_MAX)] = { 0 }; + unsigned long relbit[NBITS(REL_MAX)] = { 0 }; + + if ((ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), evbit) < 0) || + (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) < 0) || + (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(relbit)), relbit) < 0) || + (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) < 0)) { + return 0; + } + + return SDL_EVDEV_GuessDeviceClass(evbit, absbit, keybit, relbit); +} + +static int GuessIsJoystick(int fd) +{ + if (GuessDeviceClass(fd) & SDL_UDEV_DEVICE_JOYSTICK) { + return 1; + } + + return 0; +} + +static int GuessIsSensor(int fd) +{ + if (GuessDeviceClass(fd) & SDL_UDEV_DEVICE_ACCELEROMETER) { + return 1; + } + + return 0; +} + +static int IsJoystick(const char *path, int *fd, char **name_return, Uint16 *vendor_return, Uint16 *product_return, SDL_JoystickGUID *guid) +{ + struct input_id inpid; + char *name; + char product_string[128]; + int class = 0; + + SDL_zero(inpid); +#ifdef SDL_USE_LIBUDEV + /* Opening input devices can generate synchronous device I/O, so avoid it if we can */ + if (SDL_UDEV_GetProductInfo(path, &inpid.vendor, &inpid.product, &inpid.version, &class) && + !(class & SDL_UDEV_DEVICE_JOYSTICK)) { + return 0; + } +#endif + + if (fd && *fd < 0) { + *fd = open(path, O_RDONLY | O_CLOEXEC, 0); + } + if (!fd || *fd < 0) { + return 0; + } + + if (ioctl(*fd, JSIOCGNAME(sizeof(product_string)), product_string) <= 0) { + /* When udev enumeration or classification, we only got joysticks here, so no need to test */ + if (enumeration_method != ENUMERATION_LIBUDEV && !class && !GuessIsJoystick(*fd)) { + return 0; + } + + /* Could have vendor and product already from udev, but should agree with evdev */ + if (ioctl(*fd, EVIOCGID, &inpid) < 0) { + return 0; + } + + if (ioctl(*fd, EVIOCGNAME(sizeof(product_string)), product_string) < 0) { + return 0; + } + } + + name = SDL_CreateJoystickName(inpid.vendor, inpid.product, NULL, product_string); + if (!name) { + return 0; + } + +#ifdef SDL_JOYSTICK_HIDAPI + if (!IsVirtualJoystick(inpid.vendor, inpid.product, inpid.version, name) && + HIDAPI_IsDevicePresent(inpid.vendor, inpid.product, inpid.version, name)) { + /* The HIDAPI driver is taking care of this device */ + SDL_free(name); + return 0; + } +#endif + + FixupDeviceInfoForMapping(*fd, &inpid); + +#ifdef DEBUG_JOYSTICK + SDL_Log("Joystick: %s, bustype = %d, vendor = 0x%.4x, product = 0x%.4x, version = %d\n", name, inpid.bustype, inpid.vendor, inpid.product, inpid.version); +#endif + + *guid = SDL_CreateJoystickGUID(inpid.bustype, inpid.vendor, inpid.product, inpid.version, NULL, product_string, 0, 0); + + if (SDL_ShouldIgnoreJoystick(name, *guid)) { + SDL_free(name); + return 0; + } + *name_return = name; + *vendor_return = inpid.vendor; + *product_return = inpid.product; + return 1; +} + +static int IsSensor(const char *path, int *fd) +{ + struct input_id inpid; + int class = 0; + + SDL_zero(inpid); +#ifdef SDL_USE_LIBUDEV + /* Opening input devices can generate synchronous device I/O, so avoid it if we can */ + if (SDL_UDEV_GetProductInfo(path, &inpid.vendor, &inpid.product, &inpid.version, &class) && + !(class & SDL_UDEV_DEVICE_ACCELEROMETER)) { + return 0; + } +#endif + + if (fd && *fd < 0) { + *fd = open(path, O_RDONLY | O_CLOEXEC, 0); + } + if (!fd || *fd < 0) { + return 0; + } + + if (!class && !GuessIsSensor(*fd)) { + return 0; + } + + if (ioctl(*fd, EVIOCGID, &inpid) < 0) { + return 0; + } + + if (inpid.vendor == USB_VENDOR_NINTENDO && inpid.product == USB_PRODUCT_NINTENDO_WII_REMOTE) { + /* Wii extension controls */ + /* These may create 3 sensor devices but we only support reading from 1: ignore them */ + return 0; + } + + return 1; +} + +#ifdef SDL_USE_LIBUDEV +static void joystick_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_class, const char *devpath) +{ + if (!devpath) { + return; + } + + switch (udev_type) { + case SDL_UDEV_DEVICEADDED: + if (!(udev_class & SDL_UDEV_DEVICE_JOYSTICK)) { + return; + } + if (SDL_classic_joysticks) { + if (!IsJoystickJSNode(devpath)) { + return; + } + } else { + if (IsJoystickJSNode(devpath)) { + return; + } + } + + /* Wait a bit for the hidraw udev node to initialize */ + SDL_Delay(10); + + MaybeAddDevice(devpath); + break; + + case SDL_UDEV_DEVICEREMOVED: + MaybeRemoveDevice(devpath); + break; + + default: + break; + } +} +#endif /* SDL_USE_LIBUDEV */ + +static void FreeJoylistItem(SDL_joylist_item *item) +{ + SDL_free(item->mapping); + SDL_free(item->path); + SDL_free(item->name); + SDL_free(item); +} + +static void FreeSensorlistItem(SDL_sensorlist_item *item) +{ + SDL_free(item->path); + SDL_free(item); +} + +static void MaybeAddDevice(const char *path) +{ + struct stat sb; + int fd = -1; + char *name = NULL; + Uint16 vendor, product; + SDL_JoystickGUID guid; + SDL_joylist_item *item; + SDL_sensorlist_item *item_sensor; + + if (!path) { + return; + } + + if (stat(path, &sb) == -1) { + return; + } + + SDL_LockJoysticks(); + + /* Check to make sure it's not already in list. */ + for (item = SDL_joylist; item; item = item->next) { + if (sb.st_rdev == item->devnum) { + goto done; /* already have this one */ + } + } + for (item_sensor = SDL_sensorlist; item_sensor; item_sensor = item_sensor->next) { + if (sb.st_rdev == item_sensor->devnum) { + goto done; /* already have this one */ + } + } + +#ifdef DEBUG_INPUT_EVENTS + SDL_Log("Checking %s\n", path); +#endif + + if (IsJoystick(path, &fd, &name, &vendor, &product, &guid)) { +#ifdef DEBUG_INPUT_EVENTS + SDL_Log("found joystick: %s\n", path); +#endif + item = (SDL_joylist_item *)SDL_calloc(1, sizeof(SDL_joylist_item)); + if (!item) { + SDL_free(name); + goto done; + } + + item->devnum = sb.st_rdev; + item->steam_virtual_gamepad_slot = -1; + item->path = SDL_strdup(path); + item->name = name; + item->guid = guid; + + if (vendor == USB_VENDOR_VALVE && + product == USB_PRODUCT_STEAM_VIRTUAL_GAMEPAD) { + GetSteamVirtualGamepadSlot(fd, &item->steam_virtual_gamepad_slot); + } + + if ((!item->path) || (!item->name)) { + FreeJoylistItem(item); + goto done; + } + + item->device_instance = SDL_GetNextJoystickInstanceID(); + if (!SDL_joylist_tail) { + 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(item->device_instance); + goto done; + } + + if (IsSensor(path, &fd)) { +#ifdef DEBUG_INPUT_EVENTS + SDL_Log("found sensor: %s\n", path); +#endif + item_sensor = (SDL_sensorlist_item *)SDL_calloc(1, sizeof(SDL_sensorlist_item)); + if (!item_sensor) { + goto done; + } + item_sensor->devnum = sb.st_rdev; + item_sensor->path = SDL_strdup(path); + + if (!item_sensor->path) { + FreeSensorlistItem(item_sensor); + goto done; + } + + item_sensor->next = SDL_sensorlist; + SDL_sensorlist = item_sensor; + goto done; + } + +done: + if (fd >= 0) { + close(fd); + } + SDL_UnlockJoysticks(); +} + +static void RemoveJoylistItem(SDL_joylist_item *item, SDL_joylist_item *prev) +{ + SDL_AssertJoysticksLocked(); + + if (item->hwdata) { + item->hwdata->item = NULL; + } + + if (prev) { + 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); + FreeJoylistItem(item); +} + +static void RemoveSensorlistItem(SDL_sensorlist_item *item, SDL_sensorlist_item *prev) +{ + SDL_AssertJoysticksLocked(); + + if (item->hwdata) { + item->hwdata->item_sensor = NULL; + } + + if (prev) { + prev->next = item->next; + } else { + SDL_assert(SDL_sensorlist == item); + SDL_sensorlist = item->next; + } + + /* Do not call SDL_PrivateJoystickRemoved here as RemoveJoylistItem will do it, + * assuming both sensor and joy item are removed at the same time */ + FreeSensorlistItem(item); +} + +static void MaybeRemoveDevice(const char *path) +{ + SDL_joylist_item *item; + SDL_joylist_item *prev = NULL; + SDL_sensorlist_item *item_sensor; + SDL_sensorlist_item *prev_sensor = NULL; + + if (!path) { + return; + } + + SDL_LockJoysticks(); + for (item = SDL_joylist; item; item = item->next) { + /* found it, remove it. */ + if (SDL_strcmp(path, item->path) == 0) { + RemoveJoylistItem(item, prev); + goto done; + } + prev = item; + } + for (item_sensor = SDL_sensorlist; item_sensor; item_sensor = item_sensor->next) { + /* found it, remove it. */ + if (SDL_strcmp(path, item_sensor->path) == 0) { + RemoveSensorlistItem(item_sensor, prev_sensor); + goto done; + } + prev_sensor = item_sensor; + } +done: + SDL_UnlockJoysticks(); +} + +static void HandlePendingRemovals(void) +{ + SDL_joylist_item *prev = NULL; + SDL_joylist_item *item = NULL; + SDL_sensorlist_item *prev_sensor = NULL; + SDL_sensorlist_item *item_sensor = NULL; + + SDL_AssertJoysticksLocked(); + + item = SDL_joylist; + while (item) { + if (item->hwdata && item->hwdata->gone) { + RemoveJoylistItem(item, prev); + + if (prev) { + item = prev->next; + } else { + item = SDL_joylist; + } + } else { + prev = item; + item = item->next; + } + } + + item_sensor = SDL_sensorlist; + while (item_sensor) { + if (item_sensor->hwdata && item_sensor->hwdata->sensor_gone) { + RemoveSensorlistItem(item_sensor, prev_sensor); + + if (prev_sensor) { + item_sensor = prev_sensor->next; + } else { + item_sensor = SDL_sensorlist; + } + } else { + prev_sensor = item_sensor; + item_sensor = item_sensor->next; + } + } +} + +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) { + return SDL_FALSE; + } + + item->path = SDL_strdup(""); + item->name = SDL_strdup(name); + item->guid = guid; + item->m_bSteamController = SDL_TRUE; + + if ((!item->path) || (!item->name)) { + FreeJoylistItem(item); + return SDL_FALSE; + } + + *device_instance = item->device_instance = SDL_GetNextJoystickInstanceID(); + SDL_LockJoysticks(); + if (!SDL_joylist_tail) { + 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(item->device_instance); + SDL_UnlockJoysticks(); + + return SDL_TRUE; +} + +static void SteamControllerDisconnectedCallback(int device_instance) +{ + SDL_joylist_item *item; + SDL_joylist_item *prev = NULL; + + SDL_LockJoysticks(); + for (item = SDL_joylist; item; item = item->next) { + /* found it, remove it. */ + if (item->device_instance == device_instance) { + RemoveJoylistItem(item, prev); + break; + } + prev = item; + } + SDL_UnlockJoysticks(); +} + +static int StrHasPrefix(const char *string, const char *prefix) +{ + return SDL_strncmp(string, prefix, SDL_strlen(prefix)) == 0; +} + +static int StrIsInteger(const char *string) +{ + const char *p; + + if (*string == '\0') { + return 0; + } + + for (p = string; *p != '\0'; p++) { + if (*p < '0' || *p > '9') { + return 0; + } + } + + return 1; +} + +static SDL_bool IsJoystickJSNode(const char *node) +{ + const char *last_slash = SDL_strrchr(node, '/'); + if (last_slash) { + node = last_slash + 1; + } + return StrHasPrefix(node, "js") && StrIsInteger(node + 2); +} + +static SDL_bool IsJoystickEventNode(const char *node) +{ + const char *last_slash = SDL_strrchr(node, '/'); + if (last_slash) { + node = last_slash + 1; + } + return StrHasPrefix(node, "event") && StrIsInteger(node + 5); +} + +static SDL_bool IsJoystickDeviceNode(const char *node) +{ + if (SDL_classic_joysticks) { + return IsJoystickJSNode(node); + } else { + return IsJoystickEventNode(node); + } +} + +#ifdef HAVE_INOTIFY +#ifdef HAVE_INOTIFY_INIT1 +static int SDL_inotify_init1(void) +{ + return inotify_init1(IN_NONBLOCK | IN_CLOEXEC); +} +#else +static int SDL_inotify_init1(void) +{ + int fd = inotify_init(); + if (fd < 0) { + return -1; + } + fcntl(fd, F_SETFL, O_NONBLOCK); + fcntl(fd, F_SETFD, FD_CLOEXEC); + return fd; +} +#endif + +static void LINUX_InotifyJoystickDetect(void) +{ + union + { + struct inotify_event event; + char storage[4096]; + char enough_for_inotify[sizeof(struct inotify_event) + NAME_MAX + 1]; + } buf; + ssize_t bytes; + size_t remain = 0; + size_t len; + char path[PATH_MAX]; + + bytes = read(inotify_fd, &buf, sizeof(buf)); + + if (bytes > 0) { + remain = (size_t)bytes; + } + + while (remain > 0) { + if (buf.event.len > 0) { + if (IsJoystickDeviceNode(buf.event.name)) { + (void)SDL_snprintf(path, SDL_arraysize(path), "/dev/input/%s", buf.event.name); + + if (buf.event.mask & (IN_CREATE | IN_MOVED_TO | IN_ATTRIB)) { + MaybeAddDevice(path); + } else if (buf.event.mask & (IN_DELETE | IN_MOVED_FROM)) { + MaybeRemoveDevice(path); + } + } + } + + len = sizeof(struct inotify_event) + buf.event.len; + remain -= len; + + if (remain != 0) { + SDL_memmove(&buf.storage[0], &buf.storage[len], remain); + } + } +} +#endif /* HAVE_INOTIFY */ + +static int get_event_joystick_index(int event) +{ + int joystick_index = -1; + int i, count; + struct dirent **entries = NULL; + char path[PATH_MAX]; + + (void)SDL_snprintf(path, SDL_arraysize(path), "/sys/class/input/event%d/device", event); + count = scandir(path, &entries, NULL, alphasort); + for (i = 0; i < count; ++i) { + if (SDL_strncmp(entries[i]->d_name, "js", 2) == 0) { + joystick_index = SDL_atoi(entries[i]->d_name + 2); + } + free(entries[i]); /* This should NOT be SDL_free() */ + } + free(entries); /* This should NOT be SDL_free() */ + + return joystick_index; +} + +/* Detect devices by reading /dev/input. In the inotify code path we + * have to do this the first time, to detect devices that already existed + * before we started; in the non-inotify code path we do this repeatedly + * (polling). */ +static int filter_entries(const struct dirent *entry) +{ + return IsJoystickDeviceNode(entry->d_name); +} +static int sort_entries(const void *_a, const void *_b) +{ + const struct dirent **a = (const struct dirent **)_a; + const struct dirent **b = (const struct dirent **)_b; + int numA, numB; + int offset; + + if (SDL_classic_joysticks) { + offset = 2; /* strlen("js") */ + numA = SDL_atoi((*a)->d_name + offset); + numB = SDL_atoi((*b)->d_name + offset); + } else { + offset = 5; /* strlen("event") */ + numA = SDL_atoi((*a)->d_name + offset); + numB = SDL_atoi((*b)->d_name + offset); + + /* See if we can get the joystick ordering */ + { + int jsA = get_event_joystick_index(numA); + int jsB = get_event_joystick_index(numB); + if (jsA >= 0 && jsB >= 0) { + numA = jsA; + numB = jsB; + } else if (jsA >= 0) { + return -1; + } else if (jsB >= 0) { + return 1; + } + } + } + return numA - numB; +} + +typedef struct +{ + char *path; + int slot; +} VirtualGamepadEntry; + +static int SDLCALL sort_virtual_gamepads(const void *_a, const void *_b) +{ + const VirtualGamepadEntry *a = (const VirtualGamepadEntry *)_a; + const VirtualGamepadEntry *b = (const VirtualGamepadEntry *)_b; + return a->slot - b->slot; +} + +static void LINUX_ScanSteamVirtualGamepads(void) +{ + int i, count; + int fd; + struct dirent **entries = NULL; + char path[PATH_MAX]; + struct input_id inpid; + int num_virtual_gamepads = 0; + int virtual_gamepad_slot; + VirtualGamepadEntry *virtual_gamepads = NULL; +#ifdef SDL_USE_LIBUDEV + int class; +#endif + + count = scandir("/dev/input", &entries, filter_entries, NULL); + for (i = 0; i < count; ++i) { + (void)SDL_snprintf(path, SDL_arraysize(path), "/dev/input/%s", entries[i]->d_name); + +#ifdef SDL_USE_LIBUDEV + /* Opening input devices can generate synchronous device I/O, so avoid it if we can */ + class = 0; + SDL_zero(inpid); + if (SDL_UDEV_GetProductInfo(path, &inpid.vendor, &inpid.product, &inpid.version, &class) && + (inpid.vendor != USB_VENDOR_VALVE || inpid.product != USB_PRODUCT_STEAM_VIRTUAL_GAMEPAD)) { + free(entries[i]); /* This should NOT be SDL_free() */ + continue; + } +#endif + fd = open(path, O_RDONLY | O_CLOEXEC, 0); + if (fd >= 0) { + if (ioctl(fd, EVIOCGID, &inpid) == 0 && + inpid.vendor == USB_VENDOR_VALVE && + inpid.product == USB_PRODUCT_STEAM_VIRTUAL_GAMEPAD && + GetSteamVirtualGamepadSlot(fd, &virtual_gamepad_slot)) { + VirtualGamepadEntry *new_virtual_gamepads = (VirtualGamepadEntry *)SDL_realloc(virtual_gamepads, (num_virtual_gamepads + 1) * sizeof(*virtual_gamepads)); + if (new_virtual_gamepads) { + VirtualGamepadEntry *entry = &new_virtual_gamepads[num_virtual_gamepads]; + entry->path = SDL_strdup(path); + entry->slot = virtual_gamepad_slot; + if (entry->path) { + virtual_gamepads = new_virtual_gamepads; + ++num_virtual_gamepads; + } else { + SDL_free(entry->path); + SDL_free(new_virtual_gamepads); + } + } + } + close(fd); + } + free(entries[i]); /* This should NOT be SDL_free() */ + } + free(entries); /* This should NOT be SDL_free() */ + + if (num_virtual_gamepads > 1) { + SDL_qsort(virtual_gamepads, num_virtual_gamepads, sizeof(*virtual_gamepads), sort_virtual_gamepads); + } + for (i = 0; i < num_virtual_gamepads; ++i) { + MaybeAddDevice(virtual_gamepads[i].path); + SDL_free(virtual_gamepads[i].path); + } + SDL_free(virtual_gamepads); +} + +static void LINUX_ScanInputDevices(void) +{ + int i, count; + struct dirent **entries = NULL; + char path[PATH_MAX]; + + count = scandir("/dev/input", &entries, filter_entries, NULL); + if (count > 1) { + SDL_qsort(entries, count, sizeof(*entries), sort_entries); + } + for (i = 0; i < count; ++i) { + (void)SDL_snprintf(path, SDL_arraysize(path), "/dev/input/%s", entries[i]->d_name); + MaybeAddDevice(path); + + free(entries[i]); /* This should NOT be SDL_free() */ + } + free(entries); /* This should NOT be SDL_free() */ +} + +static void LINUX_FallbackJoystickDetect(void) +{ + const Uint32 SDL_JOY_DETECT_INTERVAL_MS = 3000; /* Update every 3 seconds */ + Uint32 now = SDL_GetTicks(); + + if (!last_joy_detect_time || SDL_TICKS_PASSED(now, last_joy_detect_time + SDL_JOY_DETECT_INTERVAL_MS)) { + struct stat sb; + + /* Opening input devices can generate synchronous device I/O, so avoid it if we can */ + if (stat("/dev/input", &sb) == 0 && sb.st_mtime != last_input_dir_mtime) { + /* Look for Steam virtual gamepads first, and sort by Steam controller slot */ + LINUX_ScanSteamVirtualGamepads(); + + LINUX_ScanInputDevices(); + + last_input_dir_mtime = sb.st_mtime; + } + + last_joy_detect_time = now; + } +} + +static void LINUX_JoystickDetect(void) +{ +#ifdef SDL_USE_LIBUDEV + if (enumeration_method == ENUMERATION_LIBUDEV) { + SDL_UDEV_Poll(); + } else +#endif +#ifdef HAVE_INOTIFY + if (inotify_fd >= 0 && last_joy_detect_time != 0) { + LINUX_InotifyJoystickDetect(); + } else +#endif + { + LINUX_FallbackJoystickDetect(); + } + + HandlePendingRemovals(); + + SDL_UpdateSteamControllers(); +} + +static int LINUX_JoystickInit(void) +{ + const char *devices = SDL_GetHint(SDL_HINT_JOYSTICK_DEVICE); +#ifdef SDL_USE_LIBUDEV + int udev_status = SDL_UDEV_Init(); +#endif + + SDL_classic_joysticks = SDL_GetHintBoolean(SDL_HINT_LINUX_JOYSTICK_CLASSIC, SDL_FALSE); + + enumeration_method = ENUMERATION_UNSET; + + /* First see if the user specified one or more joysticks to use */ + if (devices) { + char *envcopy, *envpath, *delim; + envcopy = SDL_strdup(devices); + envpath = envcopy; + while (envpath) { + delim = SDL_strchr(envpath, ':'); + if (delim) { + *delim++ = '\0'; + } + MaybeAddDevice(envpath); + envpath = delim; + } + SDL_free(envcopy); + } + + SDL_InitSteamControllers(SteamControllerConnectedCallback, + SteamControllerDisconnectedCallback); + + /* Force immediate joystick detection if using fallback */ + last_joy_detect_time = 0; + last_input_dir_mtime = 0; + + /* Manually scan first, since we sort by device number and udev doesn't */ + LINUX_JoystickDetect(); + +#ifdef SDL_USE_LIBUDEV + if (enumeration_method == ENUMERATION_UNSET) { + if (SDL_GetHintBoolean("SDL_JOYSTICK_DISABLE_UDEV", SDL_FALSE)) { + SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, + "udev disabled by SDL_JOYSTICK_DISABLE_UDEV"); + enumeration_method = ENUMERATION_FALLBACK; + } else if (SDL_DetectSandbox() != SDL_SANDBOX_NONE) { + SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, + "Container detected, disabling udev integration"); + enumeration_method = ENUMERATION_FALLBACK; + + } else { + SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, + "Using udev for joystick device discovery"); + enumeration_method = ENUMERATION_LIBUDEV; + } + } + + if (enumeration_method == ENUMERATION_LIBUDEV) { + if (udev_status == 0) { + /* Set up the udev callback */ + if (SDL_UDEV_AddCallback(joystick_udev_callback) < 0) { + SDL_UDEV_Quit(); + return SDL_SetError("Could not set up joystick <-> udev callback"); + } + + /* Force a scan to build the initial device list */ + SDL_UDEV_Scan(); + } else { + SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, + "udev init failed, disabling udev integration"); + enumeration_method = ENUMERATION_FALLBACK; + } + } +#endif + + if (enumeration_method != ENUMERATION_LIBUDEV) { +#if defined(HAVE_INOTIFY) + inotify_fd = SDL_inotify_init1(); + + if (inotify_fd < 0) { + SDL_LogWarn(SDL_LOG_CATEGORY_INPUT, + "Unable to initialize inotify, falling back to polling: %s", + strerror(errno)); + } else { + /* We need to watch for attribute changes in addition to + * creation, because when a device is first created, it has + * permissions that we can't read. When udev chmods it to + * something that we maybe *can* read, we'll get an + * IN_ATTRIB event to tell us. */ + if (inotify_add_watch(inotify_fd, "/dev/input", + IN_CREATE | IN_DELETE | IN_MOVE | IN_ATTRIB) < 0) { + close(inotify_fd); + inotify_fd = -1; + SDL_LogWarn(SDL_LOG_CATEGORY_INPUT, + "Unable to add inotify watch, falling back to polling: %s", + strerror(errno)); + } + } +#endif /* HAVE_INOTIFY */ + } + + return 0; +} + +static int LINUX_JoystickGetCount(void) +{ + SDL_AssertJoysticksLocked(); + + return numjoysticks; +} + +static SDL_joylist_item *JoystickByDevIndex(int device_index) +{ + SDL_joylist_item *item; + + SDL_AssertJoysticksLocked(); + + if ((device_index < 0) || (device_index >= numjoysticks)) { + return NULL; + } + + item = SDL_joylist; + while (device_index > 0) { + SDL_assert(item != NULL); + device_index--; + item = item->next; + } + + return item; +} + +static const char *LINUX_JoystickGetDeviceName(int device_index) +{ + return JoystickByDevIndex(device_index)->name; +} + +static const char *LINUX_JoystickGetDevicePath(int device_index) +{ + return JoystickByDevIndex(device_index)->path; +} + +static int LINUX_JoystickGetDeviceSteamVirtualGamepadSlot(int device_index) +{ + return JoystickByDevIndex(device_index)->steam_virtual_gamepad_slot; +} + +static int LINUX_JoystickGetDevicePlayerIndex(int device_index) +{ + return -1; +} + +static void LINUX_JoystickSetDevicePlayerIndex(int device_index, int player_index) +{ +} + +static SDL_JoystickGUID LINUX_JoystickGetDeviceGUID(int device_index) +{ + return JoystickByDevIndex(device_index)->guid; +} + +/* Function to perform the mapping from device index to the instance id for this index */ +static SDL_JoystickID LINUX_JoystickGetDeviceInstanceID(int device_index) +{ + return JoystickByDevIndex(device_index)->device_instance; +} + +static int allocate_hatdata(SDL_Joystick *joystick) +{ + int i; + + SDL_AssertJoysticksLocked(); + + joystick->hwdata->hats = + (struct hwdata_hat *)SDL_malloc(joystick->nhats * + sizeof(struct hwdata_hat)); + if (!joystick->hwdata->hats) { + return -1; + } + for (i = 0; i < joystick->nhats; ++i) { + joystick->hwdata->hats[i].axis[0] = 1; + joystick->hwdata->hats[i].axis[1] = 1; + } + return 0; +} + +static int allocate_balldata(SDL_Joystick *joystick) +{ + int i; + + SDL_AssertJoysticksLocked(); + + joystick->hwdata->balls = + (struct hwdata_ball *)SDL_malloc(joystick->nballs * + sizeof(struct hwdata_ball)); + if (!joystick->hwdata->balls) { + return -1; + } + for (i = 0; i < joystick->nballs; ++i) { + joystick->hwdata->balls[i].axis[0] = 0; + joystick->hwdata->balls[i].axis[1] = 0; + } + return 0; +} + +static SDL_bool GuessIfAxesAreDigitalHat(struct input_absinfo *absinfo_x, struct input_absinfo *absinfo_y) +{ + /* A "hat" is assumed to be a digital input with at most 9 possible states + * (3 per axis: negative/zero/positive), as opposed to a true "axis" which + * can report a continuous range of possible values. Unfortunately the Linux + * joystick interface makes no distinction between digital hat axes and any + * other continuous analog axis, so we have to guess. */ + + /* If both axes are missing, they're not anything. */ + if (!absinfo_x && !absinfo_y) { + return SDL_FALSE; + } + + /* If the hint says so, treat all hats as digital. */ + if (SDL_GetHintBoolean(SDL_HINT_LINUX_DIGITAL_HATS, SDL_FALSE)) { + return SDL_TRUE; + } + + /* If both axes have ranges constrained between -1 and 1, they're definitely digital. */ + if ((!absinfo_x || (absinfo_x->minimum == -1 && absinfo_x->maximum == 1)) && (!absinfo_y || (absinfo_y->minimum == -1 && absinfo_y->maximum == 1))) { + return SDL_TRUE; + } + + /* If both axes lack fuzz, flat, and resolution values, they're probably digital. */ + if ((!absinfo_x || (!absinfo_x->fuzz && !absinfo_x->flat && !absinfo_x->resolution)) && (!absinfo_y || (!absinfo_y->fuzz && !absinfo_y->flat && !absinfo_y->resolution))) { + return SDL_TRUE; + } + + /* Otherwise, treat them as analog. */ + return SDL_FALSE; +} + +static void ConfigJoystick(SDL_Joystick *joystick, int fd, int fd_sensor) +{ + int i, t; + unsigned long keybit[NBITS(KEY_MAX)] = { 0 }; + unsigned long absbit[NBITS(ABS_MAX)] = { 0 }; + unsigned long relbit[NBITS(REL_MAX)] = { 0 }; + unsigned long ffbit[NBITS(FF_MAX)] = { 0 }; + Uint8 key_pam_size, abs_pam_size; + SDL_bool use_deadzones = SDL_GetHintBoolean(SDL_HINT_LINUX_JOYSTICK_DEADZONES, SDL_FALSE); + SDL_bool use_hat_deadzones = SDL_GetHintBoolean(SDL_HINT_LINUX_HAT_DEADZONES, SDL_TRUE); + + SDL_AssertJoysticksLocked(); + + /* See if this device uses the new unified event API */ + if ((ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) >= 0) && + (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) >= 0) && + (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(relbit)), relbit) >= 0)) { + + /* Get the number of buttons, axes, and other thingamajigs */ + for (i = BTN_JOYSTICK; i < KEY_MAX; ++i) { + if (test_bit(i, keybit)) { +#ifdef DEBUG_INPUT_EVENTS + SDL_Log("Joystick has button: 0x%x\n", i); +#endif + joystick->hwdata->key_map[i] = joystick->nbuttons; + joystick->hwdata->has_key[i] = SDL_TRUE; + ++joystick->nbuttons; + } + } + for (i = 0; i < BTN_JOYSTICK; ++i) { + if (test_bit(i, keybit)) { +#ifdef DEBUG_INPUT_EVENTS + SDL_Log("Joystick has button: 0x%x\n", i); +#endif + joystick->hwdata->key_map[i] = joystick->nbuttons; + joystick->hwdata->has_key[i] = SDL_TRUE; + ++joystick->nbuttons; + } + } + for (i = ABS_HAT0X; i <= ABS_HAT3Y; i += 2) { + int hat_x = -1; + int hat_y = -1; + struct input_absinfo absinfo_x; + struct input_absinfo absinfo_y; + if (test_bit(i, absbit)) { + hat_x = ioctl(fd, EVIOCGABS(i), &absinfo_x); + } + if (test_bit(i + 1, absbit)) { + hat_y = ioctl(fd, EVIOCGABS(i + 1), &absinfo_y); + } + if (GuessIfAxesAreDigitalHat((hat_x < 0 ? (void *)0 : &absinfo_x), + (hat_y < 0 ? (void *)0 : &absinfo_y))) { + const int hat_index = (i - ABS_HAT0X) / 2; + struct hat_axis_correct *correct = &joystick->hwdata->hat_correct[hat_index]; +#ifdef DEBUG_INPUT_EVENTS + SDL_Log("Joystick has digital hat: #%d\n", hat_index); + if (hat_x >= 0) { + SDL_Log("X Values = { val:%d, min:%d, max:%d, fuzz:%d, flat:%d, res:%d }\n", + absinfo_x.value, absinfo_x.minimum, absinfo_x.maximum, + absinfo_x.fuzz, absinfo_x.flat, absinfo_x.resolution); + } + if (hat_y >= 0) { + SDL_Log("Y Values = { val:%d, min:%d, max:%d, fuzz:%d, flat:%d, res:%d }\n", + absinfo_y.value, absinfo_y.minimum, absinfo_y.maximum, + absinfo_y.fuzz, absinfo_y.flat, absinfo_y.resolution); + } +#endif /* DEBUG_INPUT_EVENTS */ + joystick->hwdata->hats_indices[hat_index] = joystick->nhats; + joystick->hwdata->has_hat[hat_index] = SDL_TRUE; + correct->use_deadzones = use_hat_deadzones; + correct->minimum[0] = (hat_x < 0) ? -1 : absinfo_x.minimum; + correct->maximum[0] = (hat_x < 0) ? 1 : absinfo_x.maximum; + correct->minimum[1] = (hat_y < 0) ? -1 : absinfo_y.minimum; + correct->maximum[1] = (hat_y < 0) ? 1 : absinfo_y.maximum; + ++joystick->nhats; + } + } + for (i = 0; i < ABS_MAX; ++i) { + /* Skip digital hats */ + if (i >= ABS_HAT0X && i <= ABS_HAT3Y && joystick->hwdata->has_hat[(i - ABS_HAT0X) / 2]) { + continue; + } + if (test_bit(i, absbit)) { + struct input_absinfo absinfo; + struct axis_correct *correct = &joystick->hwdata->abs_correct[i]; + + if (ioctl(fd, EVIOCGABS(i), &absinfo) < 0) { + continue; + } +#ifdef DEBUG_INPUT_EVENTS + SDL_Log("Joystick has absolute axis: 0x%.2x\n", i); + SDL_Log("Values = { val:%d, min:%d, max:%d, fuzz:%d, flat:%d, res:%d }\n", + absinfo.value, absinfo.minimum, absinfo.maximum, + absinfo.fuzz, absinfo.flat, absinfo.resolution); +#endif /* DEBUG_INPUT_EVENTS */ + joystick->hwdata->abs_map[i] = joystick->naxes; + joystick->hwdata->has_abs[i] = SDL_TRUE; + + correct->minimum = absinfo.minimum; + correct->maximum = absinfo.maximum; + if (correct->minimum != correct->maximum) { + if (use_deadzones) { + correct->use_deadzones = SDL_TRUE; + correct->coef[0] = (absinfo.maximum + absinfo.minimum) - 2 * absinfo.flat; + correct->coef[1] = (absinfo.maximum + absinfo.minimum) + 2 * absinfo.flat; + t = ((absinfo.maximum - absinfo.minimum) - 4 * absinfo.flat); + if (t != 0) { + correct->coef[2] = (1 << 28) / t; + } else { + correct->coef[2] = 0; + } + } else { + float value_range = (correct->maximum - correct->minimum); + float output_range = (SDL_JOYSTICK_AXIS_MAX - SDL_JOYSTICK_AXIS_MIN); + + correct->scale = (output_range / value_range); + } + } + ++joystick->naxes; + } + } + if (test_bit(REL_X, relbit) || test_bit(REL_Y, relbit)) { + ++joystick->nballs; + } + + } else if ((ioctl(fd, JSIOCGBUTTONS, &key_pam_size, sizeof(key_pam_size)) >= 0) && + (ioctl(fd, JSIOCGAXES, &abs_pam_size, sizeof(abs_pam_size)) >= 0)) { + size_t len; + + joystick->hwdata->classic = SDL_TRUE; + + len = (KEY_MAX - BTN_MISC + 1) * sizeof(*joystick->hwdata->key_pam); + joystick->hwdata->key_pam = (Uint16 *)SDL_calloc(1, len); + if (joystick->hwdata->key_pam) { + if (ioctl(fd, JSIOCGBTNMAP, joystick->hwdata->key_pam, len) < 0) { + SDL_free(joystick->hwdata->key_pam); + joystick->hwdata->key_pam = NULL; + key_pam_size = 0; + } + } else { + key_pam_size = 0; + } + for (i = 0; i < key_pam_size; ++i) { + Uint16 code = joystick->hwdata->key_pam[i]; +#ifdef DEBUG_INPUT_EVENTS + SDL_Log("Joystick has button: 0x%x\n", code); +#endif + joystick->hwdata->key_map[code] = joystick->nbuttons; + joystick->hwdata->has_key[code] = SDL_TRUE; + ++joystick->nbuttons; + } + + len = ABS_CNT * sizeof(*joystick->hwdata->abs_pam); + joystick->hwdata->abs_pam = (Uint8 *)SDL_calloc(1, len); + if (joystick->hwdata->abs_pam) { + if (ioctl(fd, JSIOCGAXMAP, joystick->hwdata->abs_pam, len) < 0) { + SDL_free(joystick->hwdata->abs_pam); + joystick->hwdata->abs_pam = NULL; + abs_pam_size = 0; + } + } else { + abs_pam_size = 0; + } + for (i = 0; i < abs_pam_size; ++i) { + Uint8 code = joystick->hwdata->abs_pam[i]; + + // TODO: is there any way to detect analog hats in advance via this API? + if (code >= ABS_HAT0X && code <= ABS_HAT3Y) { + int hat_index = (code - ABS_HAT0X) / 2; + if (!joystick->hwdata->has_hat[hat_index]) { +#ifdef DEBUG_INPUT_EVENTS + SDL_Log("Joystick has digital hat: #%d\n", hat_index); +#endif + joystick->hwdata->hats_indices[hat_index] = joystick->nhats++; + joystick->hwdata->has_hat[hat_index] = SDL_TRUE; + joystick->hwdata->hat_correct[hat_index].minimum[0] = -1; + joystick->hwdata->hat_correct[hat_index].maximum[0] = 1; + joystick->hwdata->hat_correct[hat_index].minimum[1] = -1; + joystick->hwdata->hat_correct[hat_index].maximum[1] = 1; + } + } else { +#ifdef DEBUG_INPUT_EVENTS + SDL_Log("Joystick has absolute axis: 0x%.2x\n", code); +#endif + joystick->hwdata->abs_map[code] = joystick->naxes; + joystick->hwdata->has_abs[code] = SDL_TRUE; + ++joystick->naxes; + } + } + } + + /* Sensors are only available through the new unified event API */ + if (fd_sensor >= 0 && (ioctl(fd_sensor, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) >= 0)) { + if (test_bit(ABS_X, absbit) && test_bit(ABS_Y, absbit) && test_bit(ABS_Z, absbit)) { + joystick->hwdata->has_accelerometer = SDL_TRUE; + for (i = 0; i < 3; ++i) { + struct input_absinfo absinfo; + if (ioctl(fd_sensor, EVIOCGABS(ABS_X + i), &absinfo) < 0) { + joystick->hwdata->has_accelerometer = SDL_FALSE; + break; /* do not report an accelerometer if we can't read all axes */ + } + joystick->hwdata->accelerometer_scale[i] = absinfo.resolution; +#ifdef DEBUG_INPUT_EVENTS + SDL_Log("Joystick has accelerometer axis: 0x%.2x\n", ABS_X + i); + SDL_Log("Values = { val:%d, min:%d, max:%d, fuzz:%d, flat:%d, res:%d }\n", + absinfo.value, absinfo.minimum, absinfo.maximum, + absinfo.fuzz, absinfo.flat, absinfo.resolution); +#endif /* DEBUG_INPUT_EVENTS */ + } + } + + if (test_bit(ABS_RX, absbit) && test_bit(ABS_RY, absbit) && test_bit(ABS_RZ, absbit)) { + joystick->hwdata->has_gyro = SDL_TRUE; + for (i = 0; i < 3; ++i) { + struct input_absinfo absinfo; + if (ioctl(fd_sensor, EVIOCGABS(ABS_RX + i), &absinfo) < 0) { + joystick->hwdata->has_gyro = SDL_FALSE; + break; /* do not report a gyro if we can't read all axes */ + } + joystick->hwdata->gyro_scale[i] = absinfo.resolution; +#ifdef DEBUG_INPUT_EVENTS + SDL_Log("Joystick has gyro axis: 0x%.2x\n", ABS_RX + i); + SDL_Log("Values = { val:%d, min:%d, max:%d, fuzz:%d, flat:%d, res:%d }\n", + absinfo.value, absinfo.minimum, absinfo.maximum, + absinfo.fuzz, absinfo.flat, absinfo.resolution); +#endif /* DEBUG_INPUT_EVENTS */ + } + } + } + + /* Allocate data to keep track of these thingamajigs */ + if (joystick->nhats > 0) { + if (allocate_hatdata(joystick) < 0) { + joystick->nhats = 0; + } + } + if (joystick->nballs > 0) { + if (allocate_balldata(joystick) < 0) { + joystick->nballs = 0; + } + } + + if (ioctl(fd, EVIOCGBIT(EV_FF, sizeof(ffbit)), ffbit) >= 0) { + if (test_bit(FF_RUMBLE, ffbit)) { + joystick->hwdata->ff_rumble = SDL_TRUE; + } + if (test_bit(FF_SINE, ffbit)) { + joystick->hwdata->ff_sine = SDL_TRUE; + } + } +} + +/* This is used to do the heavy lifting for LINUX_JoystickOpen and + also LINUX_JoystickGetGamepadMapping, so we can query the hardware + without adding an opened SDL_Joystick object to the system. + This expects `joystick->hwdata` to be allocated and will not free it + on error. Returns -1 on error, 0 on success. */ +static int PrepareJoystickHwdata(SDL_Joystick *joystick, SDL_joylist_item *item, SDL_sensorlist_item *item_sensor) +{ + SDL_AssertJoysticksLocked(); + + joystick->hwdata->item = item; + joystick->hwdata->item_sensor = item_sensor; + joystick->hwdata->guid = item->guid; + joystick->hwdata->effect.id = -1; + joystick->hwdata->m_bSteamController = item->m_bSteamController; + SDL_memset(joystick->hwdata->key_map, 0xFF, sizeof(joystick->hwdata->key_map)); + SDL_memset(joystick->hwdata->abs_map, 0xFF, sizeof(joystick->hwdata->abs_map)); + + if (item->m_bSteamController) { + joystick->hwdata->fd = -1; + joystick->hwdata->fd_sensor = -1; + SDL_GetSteamControllerInputs(&joystick->nbuttons, + &joystick->naxes, + &joystick->nhats); + } else { + int fd = -1, fd_sensor = -1; + /* Try read-write first, so we can do rumble */ + fd = open(item->path, O_RDWR | O_CLOEXEC, 0); + if (fd < 0) { + /* Try read-only again, at least we'll get events in this case */ + fd = open(item->path, O_RDONLY | O_CLOEXEC, 0); + } + if (fd < 0) { + return SDL_SetError("Unable to open %s", item->path); + } + /* If opening sensor fail, continue with buttons and axes only */ + if (item_sensor) { + fd_sensor = open(item_sensor->path, O_RDONLY | O_CLOEXEC, 0); + } + + joystick->hwdata->fd = fd; + joystick->hwdata->fd_sensor = fd_sensor; + joystick->hwdata->fname = SDL_strdup(item->path); + if (!joystick->hwdata->fname) { + close(fd); + if (fd_sensor >= 0) { + close(fd_sensor); + } + return SDL_OutOfMemory(); + } + + /* Set the joystick to non-blocking read mode */ + fcntl(fd, F_SETFL, O_NONBLOCK); + if (fd_sensor >= 0) { + fcntl(fd_sensor, F_SETFL, O_NONBLOCK); + } + + /* Get the number of buttons and axes on the joystick */ + ConfigJoystick(joystick, fd, fd_sensor); + } + return 0; +} + +static SDL_sensorlist_item *GetSensor(SDL_joylist_item *item) +{ + SDL_sensorlist_item *item_sensor; + char uniq_item[128]; + int fd_item = -1; + + SDL_AssertJoysticksLocked(); + + if (!item || !SDL_sensorlist) { + return NULL; + } + + SDL_memset(uniq_item, 0, sizeof(uniq_item)); + fd_item = open(item->path, O_RDONLY | O_CLOEXEC, 0); + if (fd_item < 0) { + return NULL; + } + if (ioctl(fd_item, EVIOCGUNIQ(sizeof(uniq_item) - 1), &uniq_item) < 0) { + return NULL; + } + close(fd_item); +#ifdef DEBUG_INPUT_EVENTS + SDL_Log("Joystick UNIQ: %s\n", uniq_item); +#endif /* DEBUG_INPUT_EVENTS */ + + for (item_sensor = SDL_sensorlist; item_sensor; item_sensor = item_sensor->next) { + char uniq_sensor[128]; + int fd_sensor = -1; + if (item_sensor->hwdata) { + /* already associated with another joystick */ + continue; + } + + SDL_memset(uniq_sensor, 0, sizeof(uniq_sensor)); + fd_sensor = open(item_sensor->path, O_RDONLY | O_CLOEXEC, 0); + if (fd_sensor < 0) { + continue; + } + if (ioctl(fd_sensor, EVIOCGUNIQ(sizeof(uniq_sensor) - 1), &uniq_sensor) < 0) { + close(fd_sensor); + continue; + } + close(fd_sensor); +#ifdef DEBUG_INPUT_EVENTS + SDL_Log("Sensor UNIQ: %s\n", uniq_sensor); +#endif /* DEBUG_INPUT_EVENTS */ + + if (SDL_strcmp(uniq_item, uniq_sensor) == 0) { + return item_sensor; + } + } + return NULL; +} + +/* Function to open a joystick for use. + The joystick to open is specified by the device index. + This should fill the nbuttons and naxes fields of the joystick structure. + It returns 0, or -1 if there is an error. + */ +static int LINUX_JoystickOpen(SDL_Joystick *joystick, int device_index) +{ + SDL_joylist_item *item; + SDL_sensorlist_item *item_sensor; + + SDL_AssertJoysticksLocked(); + + item = JoystickByDevIndex(device_index); + if (!item) { + return SDL_SetError("No such device"); + } + + joystick->instance_id = item->device_instance; + joystick->hwdata = (struct joystick_hwdata *) + SDL_calloc(1, sizeof(*joystick->hwdata)); + if (!joystick->hwdata) { + return SDL_OutOfMemory(); + } + + item_sensor = GetSensor(item); + if (PrepareJoystickHwdata(joystick, item, item_sensor) == -1) { + SDL_free(joystick->hwdata); + joystick->hwdata = NULL; + return -1; /* SDL_SetError will already have been called */ + } + + SDL_assert(item->hwdata == NULL); + SDL_assert(!item_sensor || item_sensor->hwdata == NULL); + item->hwdata = joystick->hwdata; + if (item_sensor) { + item_sensor->hwdata = joystick->hwdata; + } + + /* mark joystick as fresh and ready */ + joystick->hwdata->fresh = SDL_TRUE; + + if (joystick->hwdata->has_gyro) { + SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, 0.0f); + } + if (joystick->hwdata->has_accelerometer) { + SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, 0.0f); + } + if (joystick->hwdata->fd_sensor >= 0) { + /* Don't keep fd_sensor opened while sensor is disabled */ + close(joystick->hwdata->fd_sensor); + joystick->hwdata->fd_sensor = -1; + } + + return 0; +} + +static int LINUX_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ + struct input_event event; + + SDL_AssertJoysticksLocked(); + + if (joystick->hwdata->ff_rumble) { + struct ff_effect *effect = &joystick->hwdata->effect; + + effect->type = FF_RUMBLE; + effect->replay.length = SDL_MAX_RUMBLE_DURATION_MS; + effect->u.rumble.strong_magnitude = low_frequency_rumble; + effect->u.rumble.weak_magnitude = high_frequency_rumble; + } else if (joystick->hwdata->ff_sine) { + /* Scale and average the two rumble strengths */ + Sint16 magnitude = (Sint16)(((low_frequency_rumble / 2) + (high_frequency_rumble / 2)) / 2); + struct ff_effect *effect = &joystick->hwdata->effect; + + effect->type = FF_PERIODIC; + effect->replay.length = SDL_MAX_RUMBLE_DURATION_MS; + effect->u.periodic.waveform = FF_SINE; + effect->u.periodic.magnitude = magnitude; + } else { + return SDL_Unsupported(); + } + + if (ioctl(joystick->hwdata->fd, EVIOCSFF, &joystick->hwdata->effect) < 0) { + /* The kernel may have lost this effect, try to allocate a new one */ + joystick->hwdata->effect.id = -1; + if (ioctl(joystick->hwdata->fd, EVIOCSFF, &joystick->hwdata->effect) < 0) { + return SDL_SetError("Couldn't update rumble effect: %s", strerror(errno)); + } + } + + event.type = EV_FF; + event.code = joystick->hwdata->effect.id; + event.value = 1; + if (write(joystick->hwdata->fd, &event, sizeof(event)) < 0) { + return SDL_SetError("Couldn't start rumble effect: %s", strerror(errno)); + } + return 0; +} + +static int LINUX_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) +{ + return SDL_Unsupported(); +} + +static Uint32 LINUX_JoystickGetCapabilities(SDL_Joystick *joystick) +{ + Uint32 result = 0; + + SDL_AssertJoysticksLocked(); + + if (joystick->hwdata->ff_rumble || joystick->hwdata->ff_sine) { + result |= SDL_JOYCAP_RUMBLE; + } + + return result; +} + +static int LINUX_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + return SDL_Unsupported(); +} + +static int LINUX_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + +static int LINUX_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled) +{ + SDL_AssertJoysticksLocked(); + + if (!joystick->hwdata->has_accelerometer && !joystick->hwdata->has_gyro) { + return SDL_Unsupported(); + } + if (enabled == joystick->hwdata->report_sensor) { + return 0; + } + + if (enabled) { + if (!joystick->hwdata->item_sensor) { + return SDL_SetError("Sensors unplugged."); + } + joystick->hwdata->fd_sensor = open(joystick->hwdata->item_sensor->path, O_RDONLY | O_CLOEXEC, 0); + if (joystick->hwdata->fd_sensor < 0) { + return SDL_SetError("Couldn't open sensor file %s.", joystick->hwdata->item_sensor->path); + } + fcntl(joystick->hwdata->fd_sensor, F_SETFL, O_NONBLOCK); + } else { + SDL_assert(joystick->hwdata->fd_sensor >= 0); + close(joystick->hwdata->fd_sensor); + joystick->hwdata->fd_sensor = -1; + } + + joystick->hwdata->report_sensor = enabled; + return 0; +} + +static void HandleHat(SDL_Joystick *stick, int hatidx, int axis, int value) +{ + int hatnum; + struct hwdata_hat *the_hat; + struct hat_axis_correct *correct; + const Uint8 position_map[3][3] = { + { SDL_HAT_LEFTUP, SDL_HAT_UP, SDL_HAT_RIGHTUP }, + { SDL_HAT_LEFT, SDL_HAT_CENTERED, SDL_HAT_RIGHT }, + { SDL_HAT_LEFTDOWN, SDL_HAT_DOWN, SDL_HAT_RIGHTDOWN } + }; + + SDL_AssertJoysticksLocked(); + + hatnum = stick->hwdata->hats_indices[hatidx]; + the_hat = &stick->hwdata->hats[hatnum]; + correct = &stick->hwdata->hat_correct[hatidx]; + /* Hopefully we detected any analog axes and left them as is rather than trying + * to use them as digital hats, but just in case, the deadzones here will + * prevent the slightest of twitches on an analog axis from registering as a hat + * movement. If the axes really are digital, this won't hurt since they should + * only ever be sending min, 0, or max anyway. */ + if (value < 0) { + if (value <= correct->minimum[axis]) { + correct->minimum[axis] = value; + value = 0; + } else if (!correct->use_deadzones || value < correct->minimum[axis] / 3) { + value = 0; + } else { + value = 1; + } + } else if (value > 0) { + if (value >= correct->maximum[axis]) { + correct->maximum[axis] = value; + value = 2; + } else if (!correct->use_deadzones || value > correct->maximum[axis] / 3) { + value = 2; + } else { + value = 1; + } + } else { // value == 0 + value = 1; + } + if (value != the_hat->axis[axis]) { + the_hat->axis[axis] = value; + SDL_PrivateJoystickHat(stick, hatnum, + position_map[the_hat->axis[1]][the_hat->axis[0]]); + } +} + +static void HandleBall(SDL_Joystick *stick, Uint8 ball, int axis, int value) +{ + SDL_AssertJoysticksLocked(); + + stick->hwdata->balls[ball].axis[axis] += value; +} + +static int AxisCorrect(SDL_Joystick *joystick, int which, int value) +{ + struct axis_correct *correct; + + SDL_AssertJoysticksLocked(); + + correct = &joystick->hwdata->abs_correct[which]; + if (correct->minimum != correct->maximum) { + if (correct->use_deadzones) { + value *= 2; + if (value > correct->coef[0]) { + if (value < correct->coef[1]) { + return 0; + } + value -= correct->coef[1]; + } else { + value -= correct->coef[0]; + } + value *= correct->coef[2]; + value >>= 13; + } else { + value = (int)SDL_floorf((value - correct->minimum) * correct->scale + SDL_JOYSTICK_AXIS_MIN + 0.5f); + } + } + + /* Clamp and return */ + if (value < SDL_JOYSTICK_AXIS_MIN) { + return SDL_JOYSTICK_AXIS_MIN; + } + if (value > SDL_JOYSTICK_AXIS_MAX) { + return SDL_JOYSTICK_AXIS_MAX; + } + return value; +} + +static void PollAllValues(SDL_Joystick *joystick) +{ + struct input_absinfo absinfo; + unsigned long keyinfo[NBITS(KEY_MAX)]; + int i; + + SDL_AssertJoysticksLocked(); + + /* Poll all axis */ + for (i = ABS_X; i < ABS_MAX; i++) { + /* We don't need to test for digital hats here, they won't have has_abs[] set */ + if (joystick->hwdata->has_abs[i]) { + if (ioctl(joystick->hwdata->fd, EVIOCGABS(i), &absinfo) >= 0) { + absinfo.value = AxisCorrect(joystick, i, absinfo.value); + +#ifdef DEBUG_INPUT_EVENTS + SDL_Log("Joystick : Re-read Axis %d (%d) val= %d\n", + joystick->hwdata->abs_map[i], i, absinfo.value); +#endif + SDL_PrivateJoystickAxis(joystick, + joystick->hwdata->abs_map[i], + absinfo.value); + } + } + } + + /* Poll all digital hats */ + for (i = ABS_HAT0X; i <= ABS_HAT3Y; i++) { + const int baseaxis = i - ABS_HAT0X; + const int hatidx = baseaxis / 2; + SDL_assert(hatidx < SDL_arraysize(joystick->hwdata->has_hat)); + /* We don't need to test for analog axes here, they won't have has_hat[] set */ + if (joystick->hwdata->has_hat[hatidx]) { + if (ioctl(joystick->hwdata->fd, EVIOCGABS(i), &absinfo) >= 0) { + const int hataxis = baseaxis % 2; + HandleHat(joystick, hatidx, hataxis, absinfo.value); + } + } + } + + /* Poll all buttons */ + SDL_zeroa(keyinfo); + if (ioctl(joystick->hwdata->fd, EVIOCGKEY(sizeof(keyinfo)), keyinfo) >= 0) { + for (i = 0; i < KEY_MAX; i++) { + if (joystick->hwdata->has_key[i]) { + const Uint8 value = test_bit(i, keyinfo) ? SDL_PRESSED : SDL_RELEASED; +#ifdef DEBUG_INPUT_EVENTS + SDL_Log("Joystick : Re-read Button %d (%d) val= %d\n", + joystick->hwdata->key_map[i], i, value); +#endif + SDL_PrivateJoystickButton(joystick, + joystick->hwdata->key_map[i], value); + } + } + } + + /* Joyballs are relative input, so there's no poll state. Events only! */ +} + +static void PollAllSensors(SDL_Joystick *joystick) +{ + struct input_absinfo absinfo; + int i; + + SDL_AssertJoysticksLocked(); + + SDL_assert(joystick->hwdata->fd_sensor >= 0); + + if (joystick->hwdata->has_gyro) { + float data[3] = {0.0f, 0.0f, 0.0f}; + for (i = 0; i < 3; i++) { + if (ioctl(joystick->hwdata->fd_sensor, EVIOCGABS(ABS_RX + i), &absinfo) >= 0) { + data[i] = absinfo.value * (M_PI / 180.f) / joystick->hwdata->gyro_scale[i]; +#ifdef DEBUG_INPUT_EVENTS + SDL_Log("Joystick : Re-read Gyro (axis %d) val= %f\n", i, data[i]); +#endif + } + } + SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_GYRO, joystick->hwdata->sensor_tick, data, 3); + } + if (joystick->hwdata->has_accelerometer) { + float data[3] = {0.0f, 0.0f, 0.0f}; + for (i = 0; i < 3; i++) { + if (ioctl(joystick->hwdata->fd_sensor, EVIOCGABS(ABS_X + i), &absinfo) >= 0) { + data[i] = absinfo.value * SDL_STANDARD_GRAVITY / joystick->hwdata->accelerometer_scale[i]; +#ifdef DEBUG_INPUT_EVENTS + SDL_Log("Joystick : Re-read Accelerometer (axis %d) val= %f\n", i, data[i]); +#endif + } + } + SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_ACCEL, joystick->hwdata->sensor_tick, data, 3); + } +} + +static void HandleInputEvents(SDL_Joystick *joystick) +{ + struct input_event events[32]; + int i, len, code, hat_index; + + SDL_AssertJoysticksLocked(); + + if (joystick->hwdata->fresh) { + PollAllValues(joystick); + if (joystick->hwdata->report_sensor) { + PollAllSensors(joystick); + } + joystick->hwdata->fresh = SDL_FALSE; + } + + errno = 0; + + while ((len = read(joystick->hwdata->fd, events, sizeof(events))) > 0) { + len /= sizeof(events[0]); + for (i = 0; i < len; ++i) { + code = events[i].code; + + /* If the kernel sent a SYN_DROPPED, we are supposed to ignore the + rest of the packet (the end of it signified by a SYN_REPORT) */ + if (joystick->hwdata->recovering_from_dropped && + ((events[i].type != EV_SYN) || (code != SYN_REPORT))) { + continue; + } + + switch (events[i].type) { + case EV_KEY: + SDL_PrivateJoystickButton(joystick, + joystick->hwdata->key_map[code], + events[i].value); + break; + case EV_ABS: + switch (code) { + case ABS_HAT0X: + case ABS_HAT0Y: + case ABS_HAT1X: + case ABS_HAT1Y: + case ABS_HAT2X: + case ABS_HAT2Y: + case ABS_HAT3X: + case ABS_HAT3Y: + hat_index = (code - ABS_HAT0X) / 2; + if (joystick->hwdata->has_hat[hat_index]) { + HandleHat(joystick, hat_index, code % 2, events[i].value); + break; + } + SDL_FALLTHROUGH; + default: + events[i].value = AxisCorrect(joystick, code, events[i].value); + SDL_PrivateJoystickAxis(joystick, + joystick->hwdata->abs_map[code], + events[i].value); + break; + } + break; + case EV_REL: + switch (code) { + case REL_X: + case REL_Y: + code -= REL_X; + HandleBall(joystick, code / 2, code % 2, events[i].value); + break; + default: + break; + } + break; + case EV_SYN: + switch (code) { + case SYN_DROPPED: +#ifdef DEBUG_INPUT_EVENTS + SDL_Log("Event SYN_DROPPED detected\n"); +#endif + joystick->hwdata->recovering_from_dropped = SDL_TRUE; + break; + case SYN_REPORT: + if (joystick->hwdata->recovering_from_dropped) { + joystick->hwdata->recovering_from_dropped = SDL_FALSE; + PollAllValues(joystick); /* try to sync up to current state now */ + } + break; + default: + break; + } + default: + break; + } + } + } + + if (errno == ENODEV) { + /* We have to wait until the JoystickDetect callback to remove this */ + joystick->hwdata->gone = SDL_TRUE; + errno = 0; + } + + if (joystick->hwdata->report_sensor) { + SDL_assert(joystick->hwdata->fd_sensor >= 0); + + while ((len = read(joystick->hwdata->fd_sensor, events, sizeof(events))) > 0) { + len /= sizeof(events[0]); + for (i = 0; i < len; ++i) { + unsigned int j; + struct input_event *event = &events[i]; + + code = event->code; + + /* If the kernel sent a SYN_DROPPED, we are supposed to ignore the + rest of the packet (the end of it signified by a SYN_REPORT) */ + if (joystick->hwdata->recovering_from_dropped_sensor && + ((event->type != EV_SYN) || (code != SYN_REPORT))) { + continue; + } + + switch (event->type) { + case EV_KEY: + SDL_assert(0); + break; + case EV_ABS: + switch (code) { + case ABS_X: + case ABS_Y: + case ABS_Z: + j = code - ABS_X; + joystick->hwdata->accel_data[j] = event->value * SDL_STANDARD_GRAVITY + / joystick->hwdata->accelerometer_scale[j]; + break; + case ABS_RX: + case ABS_RY: + case ABS_RZ: + j = code - ABS_RX; + joystick->hwdata->gyro_data[j] = event->value * (M_PI / 180.f) + / joystick->hwdata->gyro_scale[j]; + break; + } + break; + case EV_MSC: + if (code == MSC_TIMESTAMP) { + Sint32 tick = event->value; + Sint32 delta; + if (joystick->hwdata->last_tick < tick) { + delta = (tick - joystick->hwdata->last_tick); + } else { + delta = (SDL_MAX_SINT32 - joystick->hwdata->last_tick + tick + 1); + } + joystick->hwdata->sensor_tick += delta; + joystick->hwdata->last_tick = tick; + } + break; + case EV_SYN: + switch (code) { + case SYN_DROPPED: + #ifdef DEBUG_INPUT_EVENTS + SDL_Log("Event SYN_DROPPED detected\n"); + #endif + joystick->hwdata->recovering_from_dropped_sensor = SDL_TRUE; + break; + case SYN_REPORT: + if (joystick->hwdata->recovering_from_dropped_sensor) { + joystick->hwdata->recovering_from_dropped_sensor = SDL_FALSE; + PollAllSensors(joystick); /* try to sync up to current state now */ + } else { + SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_GYRO, + joystick->hwdata->sensor_tick, + joystick->hwdata->gyro_data, 3); + SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_ACCEL, + joystick->hwdata->sensor_tick, + joystick->hwdata->accel_data, 3); + } + break; + default: + break; + } + default: + break; + } + } + } + } + + if (errno == ENODEV) { + /* We have to wait until the JoystickDetect callback to remove this */ + joystick->hwdata->sensor_gone = SDL_TRUE; + } +} + +static void HandleClassicEvents(SDL_Joystick *joystick) +{ + struct js_event events[32]; + int i, len, code, hat_index; + + SDL_AssertJoysticksLocked(); + + joystick->hwdata->fresh = SDL_FALSE; + while ((len = read(joystick->hwdata->fd, events, sizeof(events))) > 0) { + len /= sizeof(events[0]); + for (i = 0; i < len; ++i) { + switch (events[i].type) { + case JS_EVENT_BUTTON: + code = joystick->hwdata->key_pam[events[i].number]; + SDL_PrivateJoystickButton(joystick, + joystick->hwdata->key_map[code], + events[i].value); + break; + case JS_EVENT_AXIS: + code = joystick->hwdata->abs_pam[events[i].number]; + switch (code) { + case ABS_HAT0X: + case ABS_HAT0Y: + case ABS_HAT1X: + case ABS_HAT1Y: + case ABS_HAT2X: + case ABS_HAT2Y: + case ABS_HAT3X: + case ABS_HAT3Y: + hat_index = (code - ABS_HAT0X) / 2; + if (joystick->hwdata->has_hat[hat_index]) { + HandleHat(joystick, hat_index, code % 2, events[i].value); + break; + } + SDL_FALLTHROUGH; + default: + SDL_PrivateJoystickAxis(joystick, + joystick->hwdata->abs_map[code], + events[i].value); + break; + } + } + } + } +} + +static void LINUX_JoystickUpdate(SDL_Joystick *joystick) +{ + int i; + + SDL_AssertJoysticksLocked(); + + if (joystick->hwdata->m_bSteamController) { + SDL_UpdateSteamController(joystick); + return; + } + + if (joystick->hwdata->classic) { + HandleClassicEvents(joystick); + } else { + HandleInputEvents(joystick); + } + + /* Deliver ball motion updates */ + for (i = 0; i < joystick->nballs; ++i) { + int xrel, yrel; + + xrel = joystick->hwdata->balls[i].axis[0]; + yrel = joystick->hwdata->balls[i].axis[1]; + if (xrel || yrel) { + joystick->hwdata->balls[i].axis[0] = 0; + joystick->hwdata->balls[i].axis[1] = 0; + SDL_PrivateJoystickBall(joystick, (Uint8)i, xrel, yrel); + } + } +} + +/* Function to close a joystick after use */ +static void LINUX_JoystickClose(SDL_Joystick *joystick) +{ + SDL_AssertJoysticksLocked(); + + if (joystick->hwdata) { + if (joystick->hwdata->effect.id >= 0) { + ioctl(joystick->hwdata->fd, EVIOCRMFF, joystick->hwdata->effect.id); + joystick->hwdata->effect.id = -1; + } + if (joystick->hwdata->fd >= 0) { + close(joystick->hwdata->fd); + } + if (joystick->hwdata->fd_sensor >= 0) { + close(joystick->hwdata->fd_sensor); + } + if (joystick->hwdata->item) { + joystick->hwdata->item->hwdata = NULL; + } + if (joystick->hwdata->item_sensor) { + joystick->hwdata->item_sensor->hwdata = NULL; + } + SDL_free(joystick->hwdata->key_pam); + SDL_free(joystick->hwdata->abs_pam); + SDL_free(joystick->hwdata->hats); + SDL_free(joystick->hwdata->balls); + SDL_free(joystick->hwdata->fname); + SDL_free(joystick->hwdata); + } +} + +/* Function to perform any system-specific joystick related cleanup */ +static void LINUX_JoystickQuit(void) +{ + SDL_joylist_item *item = NULL; + SDL_joylist_item *next = NULL; + SDL_sensorlist_item *item_sensor = NULL; + SDL_sensorlist_item *next_sensor = NULL; + + SDL_AssertJoysticksLocked(); + + if (inotify_fd >= 0) { + close(inotify_fd); + inotify_fd = -1; + } + + for (item = SDL_joylist; item; item = next) { + next = item->next; + FreeJoylistItem(item); + } + for (item_sensor = SDL_sensorlist; item_sensor; item_sensor = next_sensor) { + next_sensor = item_sensor->next; + FreeSensorlistItem(item_sensor); + } + + SDL_joylist = SDL_joylist_tail = NULL; + SDL_sensorlist = NULL; + + numjoysticks = 0; + +#ifdef SDL_USE_LIBUDEV + if (enumeration_method == ENUMERATION_LIBUDEV) { + SDL_UDEV_DelCallback(joystick_udev_callback); + SDL_UDEV_Quit(); + } +#endif + + SDL_QuitSteamControllers(); +} + +/* + This is based on the Linux Gamepad Specification + available at: https://www.kernel.org/doc/html/v4.15/input/gamepad.html + and the Android gamepad documentation, + https://developer.android.com/develop/ui/views/touch-and-input/game-controllers/controller-input + */ +static SDL_bool LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) +{ + SDL_Joystick *joystick; + SDL_joylist_item *item = JoystickByDevIndex(device_index); + enum { + MAPPED_TRIGGER_LEFT = 0x1, + MAPPED_TRIGGER_RIGHT = 0x2, + MAPPED_TRIGGER_BOTH = 0x3, + + MAPPED_DPAD_UP = 0x1, + MAPPED_DPAD_DOWN = 0x2, + MAPPED_DPAD_LEFT = 0x4, + MAPPED_DPAD_RIGHT = 0x8, + MAPPED_DPAD_ALL = 0xF, + }; + unsigned int mapped; + + SDL_AssertJoysticksLocked(); + + if (item->checked_mapping) { + if (item->mapping) { + SDL_memcpy(out, item->mapping, sizeof(*out)); +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Prior mapping for device %d", device_index); +#endif + return SDL_TRUE; + } else { + return SDL_FALSE; + } + } + + /* We temporarily open the device to check how it's configured. Make + a fake SDL_Joystick object to do so. */ + joystick = (SDL_Joystick *)SDL_calloc(sizeof(*joystick), 1); + if (!joystick) { + SDL_OutOfMemory(); + return SDL_FALSE; + } + joystick->magic = &SDL_joystick_magic; + SDL_memcpy(&joystick->guid, &item->guid, sizeof(item->guid)); + + joystick->hwdata = (struct joystick_hwdata *) + SDL_calloc(1, sizeof(*joystick->hwdata)); + if (!joystick->hwdata) { + SDL_free(joystick); + SDL_OutOfMemory(); + return SDL_FALSE; + } + + item->checked_mapping = SDL_TRUE; + + if (PrepareJoystickHwdata(joystick, item, NULL) == -1) { + SDL_free(joystick->hwdata); + SDL_free(joystick); + return SDL_FALSE; /* SDL_SetError will already have been called */ + } + + /* don't assign `item->hwdata` so it's not in any global state. */ + + /* it is now safe to call LINUX_JoystickClose on this fake joystick. */ + + if (!joystick->hwdata->has_key[BTN_GAMEPAD]) { + /* Not a gamepad according to the specs. */ + LINUX_JoystickClose(joystick); + SDL_free(joystick); + return SDL_FALSE; + } + + /* We have a gamepad, start filling out the mappings */ + +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapping %s (VID/PID 0x%.4x/0x%.4x)", item->name, SDL_JoystickGetVendor(joystick), SDL_JoystickGetProduct(joystick)); +#endif + + if (joystick->hwdata->has_key[BTN_A]) { + out->a.kind = EMappingKind_Button; + out->a.target = joystick->hwdata->key_map[BTN_A]; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped A to button %d (BTN_A)", out->a.target); +#endif + } + + if (joystick->hwdata->has_key[BTN_B]) { + out->b.kind = EMappingKind_Button; + out->b.target = joystick->hwdata->key_map[BTN_B]; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped B to button %d (BTN_B)", out->b.target); +#endif + } + + /* Xbox controllers use BTN_X and BTN_Y, and PS4 controllers use BTN_WEST and BTN_NORTH */ + if (SDL_JoystickGetVendor(joystick) == USB_VENDOR_SONY) { + if (joystick->hwdata->has_key[BTN_WEST]) { + out->x.kind = EMappingKind_Button; + out->x.target = joystick->hwdata->key_map[BTN_WEST]; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped X to button %d (BTN_WEST)", out->x.target); +#endif + } + + if (joystick->hwdata->has_key[BTN_NORTH]) { + out->y.kind = EMappingKind_Button; + out->y.target = joystick->hwdata->key_map[BTN_NORTH]; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped Y to button %d (BTN_NORTH)", out->y.target); +#endif + } + } else { + if (joystick->hwdata->has_key[BTN_X]) { + out->x.kind = EMappingKind_Button; + out->x.target = joystick->hwdata->key_map[BTN_X]; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped X to button %d (BTN_X)", out->x.target); +#endif + } + + if (joystick->hwdata->has_key[BTN_Y]) { + out->y.kind = EMappingKind_Button; + out->y.target = joystick->hwdata->key_map[BTN_Y]; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped Y to button %d (BTN_Y)", out->y.target); +#endif + } + } + + if (joystick->hwdata->has_key[BTN_SELECT]) { + out->back.kind = EMappingKind_Button; + out->back.target = joystick->hwdata->key_map[BTN_SELECT]; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped BACK to button %d (BTN_SELECT)", out->back.target); +#endif + } + + if (joystick->hwdata->has_key[BTN_START]) { + out->start.kind = EMappingKind_Button; + out->start.target = joystick->hwdata->key_map[BTN_START]; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped START to button %d (BTN_START)", out->start.target); +#endif + } + + if (joystick->hwdata->has_key[BTN_THUMBL]) { + out->leftstick.kind = EMappingKind_Button; + out->leftstick.target = joystick->hwdata->key_map[BTN_THUMBL]; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped LEFTSTICK to button %d (BTN_THUMBL)", out->leftstick.target); +#endif + } + + if (joystick->hwdata->has_key[BTN_THUMBR]) { + out->rightstick.kind = EMappingKind_Button; + out->rightstick.target = joystick->hwdata->key_map[BTN_THUMBR]; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped RIGHTSTICK to button %d (BTN_THUMBR)", out->rightstick.target); +#endif + } + + if (joystick->hwdata->has_key[BTN_MODE]) { + out->guide.kind = EMappingKind_Button; + out->guide.target = joystick->hwdata->key_map[BTN_MODE]; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped GUIDE to button %d (BTN_MODE)", out->guide.target); +#endif + } + + /* + According to the specs the D-Pad, the shoulder buttons and the triggers + can be digital, or analog, or both at the same time. + */ + + /* Prefer digital shoulder buttons, but settle for digital or analog hat. */ + mapped = 0; + + if (joystick->hwdata->has_key[BTN_TL]) { + out->leftshoulder.kind = EMappingKind_Button; + out->leftshoulder.target = joystick->hwdata->key_map[BTN_TL]; + mapped |= 0x1; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped LEFTSHOULDER to button %d (BTN_TL)", out->leftshoulder.target); +#endif + } + + if (joystick->hwdata->has_key[BTN_TR]) { + out->rightshoulder.kind = EMappingKind_Button; + out->rightshoulder.target = joystick->hwdata->key_map[BTN_TR]; + mapped |= 0x2; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped RIGHTSHOULDER to button %d (BTN_TR)", out->rightshoulder.target); +#endif + } + + if (mapped != 0x3 && joystick->hwdata->has_hat[1]) { + int hat = joystick->hwdata->hats_indices[1] << 4; + out->leftshoulder.kind = EMappingKind_Hat; + out->rightshoulder.kind = EMappingKind_Hat; + out->leftshoulder.target = hat | 0x4; + out->rightshoulder.target = hat | 0x2; + mapped |= 0x3; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped LEFT+RIGHTSHOULDER to hat 1 (ABS_HAT1X, ABS_HAT1Y)"); +#endif + } + + if (!(mapped & 0x1) && joystick->hwdata->has_abs[ABS_HAT1Y]) { + out->leftshoulder.kind = EMappingKind_Axis; + out->leftshoulder.target = joystick->hwdata->abs_map[ABS_HAT1Y]; + mapped |= 0x1; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped LEFTSHOULDER to axis %d (ABS_HAT1Y)", out->leftshoulder.target); +#endif + } + + if (!(mapped & 0x2) && joystick->hwdata->has_abs[ABS_HAT1X]) { + out->rightshoulder.kind = EMappingKind_Axis; + out->rightshoulder.target = joystick->hwdata->abs_map[ABS_HAT1X]; + mapped |= 0x2; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped RIGHTSHOULDER to axis %d (ABS_HAT1X)", out->rightshoulder.target); +#endif + } + + /* Prefer analog triggers, but settle for digital hat or buttons. */ + mapped = 0; + + /* Unfortunately there are several conventions for how analog triggers + * are represented as absolute axes: + * + * - Linux Gamepad Specification: + * LT = ABS_HAT2Y, RT = ABS_HAT2X + * - Android (and therefore many Bluetooth controllers): + * LT = ABS_BRAKE, RT = ABS_GAS + * - De facto standard for older Xbox and Playstation controllers: + * LT = ABS_Z, RT = ABS_RZ + * + * We try each one in turn. */ + if (joystick->hwdata->has_abs[ABS_HAT2Y]) { + /* Linux Gamepad Specification */ + out->lefttrigger.kind = EMappingKind_Axis; + out->lefttrigger.target = joystick->hwdata->abs_map[ABS_HAT2Y]; + mapped |= MAPPED_TRIGGER_LEFT; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped LEFTTRIGGER to axis %d (ABS_HAT2Y)", out->lefttrigger.target); +#endif + } else if (joystick->hwdata->has_abs[ABS_BRAKE]) { + /* Android convention */ + out->lefttrigger.kind = EMappingKind_Axis; + out->lefttrigger.target = joystick->hwdata->abs_map[ABS_BRAKE]; + mapped |= MAPPED_TRIGGER_LEFT; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped LEFTTRIGGER to axis %d (ABS_BRAKE)", out->lefttrigger.target); +#endif + } else if (joystick->hwdata->has_abs[ABS_Z]) { + /* De facto standard for Xbox 360 and Playstation gamepads */ + out->lefttrigger.kind = EMappingKind_Axis; + out->lefttrigger.target = joystick->hwdata->abs_map[ABS_Z]; + mapped |= MAPPED_TRIGGER_LEFT; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped LEFTTRIGGER to axis %d (ABS_Z)", out->lefttrigger.target); +#endif + } + + if (joystick->hwdata->has_abs[ABS_HAT2X]) { + /* Linux Gamepad Specification */ + out->righttrigger.kind = EMappingKind_Axis; + out->righttrigger.target = joystick->hwdata->abs_map[ABS_HAT2X]; + mapped |= MAPPED_TRIGGER_RIGHT; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped RIGHTTRIGGER to axis %d (ABS_HAT2X)", out->righttrigger.target); +#endif + } else if (joystick->hwdata->has_abs[ABS_GAS]) { + /* Android convention */ + out->righttrigger.kind = EMappingKind_Axis; + out->righttrigger.target = joystick->hwdata->abs_map[ABS_GAS]; + mapped |= MAPPED_TRIGGER_RIGHT; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped RIGHTTRIGGER to axis %d (ABS_GAS)", out->righttrigger.target); +#endif + } else if (joystick->hwdata->has_abs[ABS_RZ]) { + /* De facto standard for Xbox 360 and Playstation gamepads */ + out->righttrigger.kind = EMappingKind_Axis; + out->righttrigger.target = joystick->hwdata->abs_map[ABS_RZ]; + mapped |= MAPPED_TRIGGER_RIGHT; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped RIGHTTRIGGER to axis %d (ABS_RZ)", out->righttrigger.target); +#endif + } + + if (mapped != MAPPED_TRIGGER_BOTH && joystick->hwdata->has_hat[2]) { + int hat = joystick->hwdata->hats_indices[2] << 4; + out->lefttrigger.kind = EMappingKind_Hat; + out->righttrigger.kind = EMappingKind_Hat; + out->lefttrigger.target = hat | 0x4; + out->righttrigger.target = hat | 0x2; + mapped |= MAPPED_TRIGGER_BOTH; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped LEFT+RIGHTTRIGGER to hat 2 (ABS_HAT2X, ABS_HAT2Y)"); +#endif + } + + if (!(mapped & MAPPED_TRIGGER_LEFT) && joystick->hwdata->has_key[BTN_TL2]) { + out->lefttrigger.kind = EMappingKind_Button; + out->lefttrigger.target = joystick->hwdata->key_map[BTN_TL2]; + mapped |= MAPPED_TRIGGER_LEFT; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped LEFTTRIGGER to button %d (BTN_TL2)", out->lefttrigger.target); +#endif + } + + if (!(mapped & MAPPED_TRIGGER_RIGHT) && joystick->hwdata->has_key[BTN_TR2]) { + out->righttrigger.kind = EMappingKind_Button; + out->righttrigger.target = joystick->hwdata->key_map[BTN_TR2]; + mapped |= MAPPED_TRIGGER_RIGHT; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped RIGHTTRIGGER to button %d (BTN_TR2)", out->righttrigger.target); +#endif + } + + /* Prefer digital D-Pad buttons, but settle for digital or analog hat. */ + mapped = 0; + + if (joystick->hwdata->has_key[BTN_DPAD_UP]) { + out->dpup.kind = EMappingKind_Button; + out->dpup.target = joystick->hwdata->key_map[BTN_DPAD_UP]; + mapped |= MAPPED_DPAD_UP; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped DPUP to button %d (BTN_DPAD_UP)", out->dpup.target); +#endif + } + + if (joystick->hwdata->has_key[BTN_DPAD_DOWN]) { + out->dpdown.kind = EMappingKind_Button; + out->dpdown.target = joystick->hwdata->key_map[BTN_DPAD_DOWN]; + mapped |= MAPPED_DPAD_DOWN; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped DPDOWN to button %d (BTN_DPAD_DOWN)", out->dpdown.target); +#endif + } + + if (joystick->hwdata->has_key[BTN_DPAD_LEFT]) { + out->dpleft.kind = EMappingKind_Button; + out->dpleft.target = joystick->hwdata->key_map[BTN_DPAD_LEFT]; + mapped |= MAPPED_DPAD_LEFT; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped DPLEFT to button %d (BTN_DPAD_LEFT)", out->dpleft.target); +#endif + } + + if (joystick->hwdata->has_key[BTN_DPAD_RIGHT]) { + out->dpright.kind = EMappingKind_Button; + out->dpright.target = joystick->hwdata->key_map[BTN_DPAD_RIGHT]; + mapped |= MAPPED_DPAD_RIGHT; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped DPRIGHT to button %d (BTN_DPAD_RIGHT)", out->dpright.target); +#endif + } + + if (mapped != MAPPED_DPAD_ALL) { + if (joystick->hwdata->has_hat[0]) { + int hat = joystick->hwdata->hats_indices[0] << 4; + out->dpleft.kind = EMappingKind_Hat; + out->dpright.kind = EMappingKind_Hat; + out->dpup.kind = EMappingKind_Hat; + out->dpdown.kind = EMappingKind_Hat; + out->dpleft.target = hat | 0x8; + out->dpright.target = hat | 0x2; + out->dpup.target = hat | 0x1; + out->dpdown.target = hat | 0x4; + mapped |= MAPPED_DPAD_ALL; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped DPUP+DOWN+LEFT+RIGHT to hat 0 (ABS_HAT0X, ABS_HAT0Y)"); +#endif + } else if (joystick->hwdata->has_abs[ABS_HAT0X] && joystick->hwdata->has_abs[ABS_HAT0Y]) { + out->dpleft.kind = EMappingKind_Axis; + out->dpright.kind = EMappingKind_Axis; + out->dpup.kind = EMappingKind_Axis; + out->dpdown.kind = EMappingKind_Axis; + out->dpleft.target = joystick->hwdata->abs_map[ABS_HAT0X]; + out->dpright.target = joystick->hwdata->abs_map[ABS_HAT0X]; + out->dpup.target = joystick->hwdata->abs_map[ABS_HAT0Y]; + out->dpdown.target = joystick->hwdata->abs_map[ABS_HAT0Y]; + mapped |= MAPPED_DPAD_ALL; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped DPUP+DOWN to axis %d (ABS_HAT0Y)", out->dpup.target); + SDL_Log("Mapped DPLEFT+RIGHT to axis %d (ABS_HAT0X)", out->dpleft.target); +#endif + } + } + + if (joystick->hwdata->has_abs[ABS_X] && joystick->hwdata->has_abs[ABS_Y]) { + out->leftx.kind = EMappingKind_Axis; + out->lefty.kind = EMappingKind_Axis; + out->leftx.target = joystick->hwdata->abs_map[ABS_X]; + out->lefty.target = joystick->hwdata->abs_map[ABS_Y]; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped LEFTX to axis %d (ABS_X)", out->leftx.target); + SDL_Log("Mapped LEFTY to axis %d (ABS_Y)", out->lefty.target); +#endif + } + + /* The Linux Gamepad Specification uses the RX and RY axes, + * originally intended to represent X and Y rotation, as a second + * joystick. This is common for USB gamepads, and also many Bluetooth + * gamepads, particularly older ones. + * + * The Android mapping convention used by many Bluetooth controllers + * instead uses the Z axis as a secondary X axis, and the RZ axis as + * a secondary Y axis. */ + if (joystick->hwdata->has_abs[ABS_RX] && joystick->hwdata->has_abs[ABS_RY]) { + /* Linux Gamepad Specification, Xbox 360, Playstation etc. */ + out->rightx.kind = EMappingKind_Axis; + out->righty.kind = EMappingKind_Axis; + out->rightx.target = joystick->hwdata->abs_map[ABS_RX]; + out->righty.target = joystick->hwdata->abs_map[ABS_RY]; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped RIGHTX to axis %d (ABS_RX)", out->rightx.target); + SDL_Log("Mapped RIGHTY to axis %d (ABS_RY)", out->righty.target); +#endif + } else if (joystick->hwdata->has_abs[ABS_Z] && joystick->hwdata->has_abs[ABS_RZ]) { + /* Android convention */ + out->rightx.kind = EMappingKind_Axis; + out->righty.kind = EMappingKind_Axis; + out->rightx.target = joystick->hwdata->abs_map[ABS_Z]; + out->righty.target = joystick->hwdata->abs_map[ABS_RZ]; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped RIGHTX to axis %d (ABS_Z)", out->rightx.target); + SDL_Log("Mapped RIGHTY to axis %d (ABS_RZ)", out->righty.target); +#endif + } + + if (SDL_JoystickGetVendor(joystick) == USB_VENDOR_MICROSOFT) { + /* The Xbox Elite controllers have the paddles as BTN_TRIGGER_HAPPY5 - BTN_TRIGGER_HAPPY8 */ + if (joystick->hwdata->has_key[BTN_TRIGGER_HAPPY5] && + joystick->hwdata->has_key[BTN_TRIGGER_HAPPY6] && + joystick->hwdata->has_key[BTN_TRIGGER_HAPPY7] && + joystick->hwdata->has_key[BTN_TRIGGER_HAPPY8]) { + out->paddle1.kind = EMappingKind_Button; + out->paddle1.target = joystick->hwdata->key_map[BTN_TRIGGER_HAPPY5]; + out->paddle2.kind = EMappingKind_Button; + out->paddle2.target = joystick->hwdata->key_map[BTN_TRIGGER_HAPPY7]; + out->paddle3.kind = EMappingKind_Button; + out->paddle3.target = joystick->hwdata->key_map[BTN_TRIGGER_HAPPY6]; + out->paddle4.kind = EMappingKind_Button; + out->paddle4.target = joystick->hwdata->key_map[BTN_TRIGGER_HAPPY8]; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped PADDLE1 to button %d (BTN_TRIGGER_HAPPY5)", out->paddle1.target); + SDL_Log("Mapped PADDLE2 to button %d (BTN_TRIGGER_HAPPY7)", out->paddle2.target); + SDL_Log("Mapped PADDLE3 to button %d (BTN_TRIGGER_HAPPY6)", out->paddle3.target); + SDL_Log("Mapped PADDLE4 to button %d (BTN_TRIGGER_HAPPY8)", out->paddle4.target); +#endif + } + + /* The Xbox Series X controllers have the Share button as KEY_RECORD */ + if (joystick->hwdata->has_key[KEY_RECORD]) { + out->misc1.kind = EMappingKind_Button; + out->misc1.target = joystick->hwdata->key_map[KEY_RECORD]; +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Mapped MISC1 to button %d (KEY_RECORD)", out->misc1.target); +#endif + } + } + + LINUX_JoystickClose(joystick); + SDL_free(joystick); + + /* Cache the mapping for later */ + item->mapping = (SDL_GamepadMapping *)SDL_malloc(sizeof(*item->mapping)); + if (item->mapping) { + SDL_memcpy(item->mapping, out, sizeof(*out)); + } +#ifdef DEBUG_GAMEPAD_MAPPING + SDL_Log("Generated mapping for device %d", device_index); +#endif + + return SDL_TRUE; +} + +SDL_JoystickDriver SDL_LINUX_JoystickDriver = { + LINUX_JoystickInit, + LINUX_JoystickGetCount, + LINUX_JoystickDetect, + LINUX_JoystickGetDeviceName, + LINUX_JoystickGetDevicePath, + LINUX_JoystickGetDeviceSteamVirtualGamepadSlot, + LINUX_JoystickGetDevicePlayerIndex, + LINUX_JoystickSetDevicePlayerIndex, + LINUX_JoystickGetDeviceGUID, + LINUX_JoystickGetDeviceInstanceID, + LINUX_JoystickOpen, + LINUX_JoystickRumble, + LINUX_JoystickRumbleTriggers, + LINUX_JoystickGetCapabilities, + LINUX_JoystickSetLED, + LINUX_JoystickSendEffect, + LINUX_JoystickSetSensorsEnabled, + LINUX_JoystickUpdate, + LINUX_JoystickClose, + LINUX_JoystickQuit, + LINUX_JoystickGetGamepadMapping +}; + +#endif /* SDL_JOYSTICK_LINUX */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/joystick/linux/SDL_sysjoystick_c.h b/SDL2-2.30.5/src/joystick/linux/SDL_sysjoystick_c.h similarity index 61% rename from SDL2-2.0.12/src/joystick/linux/SDL_sysjoystick_c.h rename to SDL2-2.30.5/src/joystick/linux/SDL_sysjoystick_c.h index a92429b..6d6ee69 100644 --- a/SDL2-2.0.12/src/joystick/linux/SDL_sysjoystick_c.h +++ b/SDL2-2.30.5/src/joystick/linux/SDL_sysjoystick_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -25,14 +25,18 @@ #include struct SDL_joylist_item; +struct SDL_sensorlist_item; /* The private structure used to keep track of a joystick */ struct joystick_hwdata { int fd; + /* linux driver creates a separate device for gyro/accelerometer */ + int fd_sensor; struct SDL_joylist_item *item; + struct SDL_sensorlist_item *item_sensor; SDL_JoystickGUID guid; - char *fname; /* Used in haptic subsystem */ + char *fname; /* Used in haptic subsystem */ SDL_bool ff_rumble; SDL_bool ff_sine; @@ -53,21 +57,60 @@ struct joystick_hwdata /* Support for the Linux 2.4 unified input interface */ Uint8 key_map[KEY_MAX]; Uint8 abs_map[ABS_MAX]; + SDL_bool has_key[KEY_MAX]; + SDL_bool has_abs[ABS_MAX]; + SDL_bool has_accelerometer; + SDL_bool has_gyro; + + /* Support for the classic joystick interface */ + SDL_bool classic; + Uint16 *key_pam; + Uint8 *abs_pam; + struct axis_correct { - int used; + SDL_bool use_deadzones; + + /* Deadzone coefficients */ int coef[3]; + + /* Raw coordinate scale */ + int minimum; + int maximum; + float scale; } abs_correct[ABS_MAX]; - int fresh; + float accelerometer_scale[3]; + float gyro_scale[3]; + + /* Each axis is read independently, if we don't get all axis this call to + * LINUX_JoystickUpdateupdate(), store them for the next one */ + float gyro_data[3]; + float accel_data[3]; + Uint64 sensor_tick; + Sint32 last_tick; + + SDL_bool report_sensor; + SDL_bool fresh; + SDL_bool recovering_from_dropped; + SDL_bool recovering_from_dropped_sensor; /* Steam Controller support */ SDL_bool m_bSteamController; + /* 4 = (ABS_HAT3X-ABS_HAT0X)/2 (see input-event-codes.h in kernel) */ int hats_indices[4]; + SDL_bool has_hat[4]; + struct hat_axis_correct + { + SDL_bool use_deadzones; + int minimum[2]; + int maximum[2]; + } hat_correct[4]; /* Set when gamepad is pending removal due to ENODEV read error */ SDL_bool gone; + SDL_bool sensor_gone; }; #endif /* SDL_sysjoystick_c_h_ */ diff --git a/SDL2-2.30.5/src/joystick/n3ds/SDL_sysjoystick.c b/SDL2-2.30.5/src/joystick/n3ds/SDL_sysjoystick.c new file mode 100644 index 0000000..bfb1a37 --- /dev/null +++ b/SDL2-2.30.5/src/joystick/n3ds/SDL_sysjoystick.c @@ -0,0 +1,302 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_JOYSTICK_N3DS + +/* This is the N3DS implementation of the SDL joystick API */ + +#include <3ds.h> + +#include "../SDL_sysjoystick.h" +#include "SDL_events.h" + +#define NB_BUTTONS 23 + +/* + N3DS sticks values are roughly within +/-160 + which is too small to pass the jitter tolerance. + This correction is applied to axis values + so they fit better in SDL's value range. +*/ +static inline int Correct_Axis_X(int X) { + if (X > 160) { + return SDL_JOYSTICK_AXIS_MAX; + } + else if (X < -160) { + return -SDL_JOYSTICK_AXIS_MAX; + } + return (X * SDL_JOYSTICK_AXIS_MAX) / 160; +} + +/* + The Y axis needs to be flipped because SDL's "up" + is reversed compared to libctru's "up" +*/ +static inline int Correct_Axis_Y(int Y) { + return Correct_Axis_X(-Y); +} + +SDL_FORCE_INLINE void UpdateN3DSPressedButtons(SDL_Joystick *joystick); +SDL_FORCE_INLINE void UpdateN3DSReleasedButtons(SDL_Joystick *joystick); +SDL_FORCE_INLINE void UpdateN3DSCircle(SDL_Joystick *joystick); +SDL_FORCE_INLINE void UpdateN3DSCStick(SDL_Joystick *joystick); + +static int N3DS_JoystickInit(void) +{ + hidInit(); + return 0; +} + +static const char *N3DS_JoystickGetDeviceName(int device_index) +{ + return "Nintendo 3DS"; +} + +static int N3DS_JoystickGetCount(void) +{ + return 1; +} + +static SDL_JoystickGUID N3DS_JoystickGetDeviceGUID(int device_index) +{ + SDL_JoystickGUID guid = SDL_CreateJoystickGUIDForName("Nintendo 3DS"); + return guid; +} + +static SDL_JoystickID N3DS_JoystickGetDeviceInstanceID(int device_index) +{ + return device_index; +} + +static int N3DS_JoystickOpen(SDL_Joystick *joystick, int device_index) +{ + joystick->nbuttons = NB_BUTTONS; + joystick->naxes = 4; + joystick->nhats = 0; + joystick->instance_id = device_index; + + return 0; +} + +static int N3DS_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled) +{ + return SDL_Unsupported(); +} + +static void N3DS_JoystickUpdate(SDL_Joystick *joystick) +{ + UpdateN3DSPressedButtons(joystick); + UpdateN3DSReleasedButtons(joystick); + UpdateN3DSCircle(joystick); + UpdateN3DSCStick(joystick); +} + +SDL_FORCE_INLINE void +UpdateN3DSPressedButtons(SDL_Joystick *joystick) +{ + static u32 previous_state = 0; + u32 updated_down; + u32 current_state = hidKeysDown(); + updated_down = previous_state ^ current_state; + if (updated_down) { + for (Uint8 i = 0; i < joystick->nbuttons; i++) { + if (current_state & BIT(i) & updated_down) { + SDL_PrivateJoystickButton(joystick, i, SDL_PRESSED); + } + } + } + previous_state = current_state; +} + +SDL_FORCE_INLINE void +UpdateN3DSReleasedButtons(SDL_Joystick *joystick) +{ + static u32 previous_state = 0; + u32 updated_up; + u32 current_state = hidKeysUp(); + updated_up = previous_state ^ current_state; + if (updated_up) { + for (Uint8 i = 0; i < joystick->nbuttons; i++) { + if (current_state & BIT(i) & updated_up) { + SDL_PrivateJoystickButton(joystick, i, SDL_RELEASED); + } + } + } + previous_state = current_state; +} + +SDL_FORCE_INLINE void +UpdateN3DSCircle(SDL_Joystick *joystick) +{ + static circlePosition previous_state = { 0, 0 }; + circlePosition current_state; + hidCircleRead(¤t_state); + if (previous_state.dx != current_state.dx) { + SDL_PrivateJoystickAxis(joystick, + 0, + Correct_Axis_X(current_state.dx)); + } + if (previous_state.dy != current_state.dy) { + SDL_PrivateJoystickAxis(joystick, + 1, + Correct_Axis_Y(current_state.dy)); + } + previous_state = current_state; +} + +SDL_FORCE_INLINE void +UpdateN3DSCStick(SDL_Joystick *joystick) +{ + static circlePosition previous_state = { 0, 0 }; + circlePosition current_state; + hidCstickRead(¤t_state); + if (previous_state.dx != current_state.dx) { + SDL_PrivateJoystickAxis(joystick, + 2, + Correct_Axis_X(current_state.dx)); + } + if (previous_state.dy != current_state.dy) { + SDL_PrivateJoystickAxis(joystick, + 3, + Correct_Axis_Y(current_state.dy)); + } + previous_state = current_state; +} + +static void N3DS_JoystickClose(SDL_Joystick *joystick) +{ +} + +static void N3DS_JoystickQuit(void) +{ + hidExit(); +} + +static SDL_bool N3DS_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) +{ + /* There is only one possible mapping. */ + *out = (SDL_GamepadMapping){ + .a = { EMappingKind_Button, 0 }, + .b = { EMappingKind_Button, 1 }, + .x = { EMappingKind_Button, 10 }, + .y = { EMappingKind_Button, 11 }, + .back = { EMappingKind_Button, 2 }, + .guide = { EMappingKind_None, 255 }, + .start = { EMappingKind_Button, 3 }, + .leftstick = { EMappingKind_None, 255 }, + .rightstick = { EMappingKind_None, 255 }, + .leftshoulder = { EMappingKind_Button, 9 }, + .rightshoulder = { EMappingKind_Button, 8 }, + .dpup = { EMappingKind_Button, 6 }, + .dpdown = { EMappingKind_Button, 7 }, + .dpleft = { EMappingKind_Button, 5 }, + .dpright = { EMappingKind_Button, 4 }, + .misc1 = { EMappingKind_None, 255 }, + .paddle1 = { EMappingKind_None, 255 }, + .paddle2 = { EMappingKind_None, 255 }, + .paddle3 = { EMappingKind_None, 255 }, + .paddle4 = { EMappingKind_None, 255 }, + .leftx = { EMappingKind_Axis, 0 }, + .lefty = { EMappingKind_Axis, 1 }, + .rightx = { EMappingKind_Axis, 2 }, + .righty = { EMappingKind_Axis, 3 }, + .lefttrigger = { EMappingKind_Button, 14 }, + .righttrigger = { EMappingKind_Button, 15 }, + }; + return SDL_TRUE; +} + +static void N3DS_JoystickDetect(void) +{ +} + +static const char *N3DS_JoystickGetDevicePath(int device_index) +{ + return NULL; +} + +static int N3DS_JoystickGetDeviceSteamVirtualGamepadSlot(int device_index) +{ + return -1; +} + +static int N3DS_JoystickGetDevicePlayerIndex(int device_index) +{ + return -1; +} + +static void N3DS_JoystickSetDevicePlayerIndex(int device_index, int player_index) +{ +} + +static Uint32 N3DS_JoystickGetCapabilities(SDL_Joystick *joystick) +{ + return 0; +} + +static int N3DS_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ + return SDL_Unsupported(); +} + +static int N3DS_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) +{ + return SDL_Unsupported(); +} + +static int N3DS_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + return SDL_Unsupported(); +} + +static int N3DS_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + +SDL_JoystickDriver SDL_N3DS_JoystickDriver = { + .Init = N3DS_JoystickInit, + .GetCount = N3DS_JoystickGetCount, + .Detect = N3DS_JoystickDetect, + .GetDeviceName = N3DS_JoystickGetDeviceName, + .GetDevicePath = N3DS_JoystickGetDevicePath, + .GetDeviceSteamVirtualGamepadSlot = N3DS_JoystickGetDeviceSteamVirtualGamepadSlot, + .GetDevicePlayerIndex = N3DS_JoystickGetDevicePlayerIndex, + .SetDevicePlayerIndex = N3DS_JoystickSetDevicePlayerIndex, + .GetDeviceGUID = N3DS_JoystickGetDeviceGUID, + .GetDeviceInstanceID = N3DS_JoystickGetDeviceInstanceID, + .Open = N3DS_JoystickOpen, + .Rumble = N3DS_JoystickRumble, + .RumbleTriggers = N3DS_JoystickRumbleTriggers, + .GetCapabilities = N3DS_JoystickGetCapabilities, + .SetLED = N3DS_JoystickSetLED, + .SendEffect = N3DS_JoystickSendEffect, + .SetSensorsEnabled = N3DS_JoystickSetSensorsEnabled, + .Update = N3DS_JoystickUpdate, + .Close = N3DS_JoystickClose, + .Quit = N3DS_JoystickQuit, + .GetGamepadMapping = N3DS_JoystickGetGamepadMapping +}; + +#endif /* SDL_JOYSTICK_N3DS */ + +/* vi: set sts=4 ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/joystick/os2/SDL_os2joystick.c b/SDL2-2.30.5/src/joystick/os2/SDL_os2joystick.c new file mode 100644 index 0000000..8df26ff --- /dev/null +++ b/SDL2-2.30.5/src/joystick/os2/SDL_os2joystick.c @@ -0,0 +1,843 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_JOYSTICK_OS2 + +/* OS/2 Joystick driver, contributed by Daniel Caetano */ + +#define INCL_DOSDEVICES +#define INCL_DOSDEVIOCTL +#define INCL_DOSMEMMGR +#include + +/***************************************************************** + * OS/2 Joystick driver defs. Based on docs at edm2.com and in old + * drivers available at hobbes.nmsu.edu and www.os2site.com + *****************************************************************/ + +#define GAME_GET_VERSION 0x01 +#define GAME_GET_PARMS 0x02 +#define GAME_GET_CALIB 0x04 +#define GAME_GET_STATUS 0x10 + +#define IOCTL_CAT_USER 0x80 +#define GAME_PORT_GET 0x20 +#define GAME_PORT_RESET 0x60 + +#pragma pack(push,1) +typedef struct { + USHORT uJs_AxCnt, uJs_AyCnt; /* A joystick X/Y pos */ + USHORT uJs_BxCnt, uJs_ByCnt; /* B joystick X/Y pos */ + USHORT usJs_ButtonA1Cnt, usJs_ButtonA2Cnt;/* A1/A2 press cnts */ + USHORT usJs_ButtonB1Cnt, usJs_ButtonB2Cnt;/* B1/B2 press cnts */ + UCHAR ucJs_JoyStickMask; /* mask of connected joystick pots */ + UCHAR ucJs_ButtonStatus; /* bits of switches down */ + ULONG ulJs_Ticks; /* total clock ticks (60 Hz) */ +} GAME_PORT_STRUCT; +#pragma pack(pop) + +typedef struct { + USHORT useA, useB; + USHORT mode; + USHORT format; + USHORT sampDiv; + USHORT scale; + USHORT res1, res2; +} GAME_PARM_STRUCT; + +typedef struct { + SHORT x, y; +} GAME_2DPOS_STRUCT; + +typedef struct { + SHORT lower, centre, upper; +} GAME_3POS_STRUCT; + +typedef struct { + GAME_3POS_STRUCT Ax, Ay, Bx, By; +} GAME_CALIB_STRUCT; + +typedef struct { + GAME_2DPOS_STRUCT A, B; + USHORT butMask; +} GAME_DATA_STRUCT; + +typedef struct { + GAME_DATA_STRUCT curdata; + USHORT b1cnt, b2cnt, b3cnt, b4cnt; +} GAME_STATUS_STRUCT; + +/*****************************************************************/ + +#include "SDL_joystick.h" +#include "SDL_events.h" +#include "../SDL_sysjoystick.h" +#include "../SDL_joystick_c.h" + +static HFILE hJoyPort = NULLHANDLE; /* Joystick GAME$ Port Address */ +#define MAX_JOYSTICKS 2 /* Maximum of two joysticks */ +#define MAX_AXES 4 /* each joystick can have up to 4 axes */ +#define MAX_BUTTONS 8 /* 8 buttons */ +#define MAX_HATS 0 /* 0 hats - OS/2 doesn't support it */ +#define MAX_BALLS 0 /* and 0 balls - OS/2 doesn't support it */ +#define MAX_JOYNAME 128 /* Joystick name may have 128 characters */ +/* Calc Button Flag for buttons A to D */ +#define JOY_BUTTON_FLAG(n) (1< MAX_JOYSTICKS) { + maxdevs = MAX_JOYSTICKS; + } + + /* Defines min/max axes values (callibration) */ + ulDataLen = sizeof(stGameCalib); + rc = DosDevIOCtl(hJoyPort, IOCTL_CAT_USER, GAME_GET_CALIB, + NULL, 0, NULL, &stGameCalib, ulDataLen, &ulDataLen); + if (rc != 0) { + joyPortClose(&hJoyPort); + return SDL_SetError("Could not read callibration data."); + } + + /* Determine how many joysticks are active */ + numdevs = 0; /* Points no device */ + ucNewJoystickMask = 0x0F; /* read all 4 joystick axis */ + ulDataLen = sizeof(ucNewJoystickMask); + rc = DosDevIOCtl(hJoyPort, IOCTL_CAT_USER, GAME_PORT_RESET, + &ucNewJoystickMask, ulDataLen, &ulDataLen, NULL, 0, NULL); + if (rc == 0) { + ulDataLen = sizeof(stJoyStatus); + rc = DosDevIOCtl(hJoyPort, IOCTL_CAT_USER, GAME_PORT_GET, + NULL, 0, NULL, &stJoyStatus, ulDataLen, &ulDataLen); + if (rc != 0) { + joyPortClose(&hJoyPort); + return SDL_SetError("Could not call joystick port."); + } + ulLastTick = stJoyStatus.ulJs_Ticks; + while (stJoyStatus.ulJs_Ticks == ulLastTick) { + rc = DosDevIOCtl(hJoyPort, IOCTL_CAT_USER, GAME_PORT_GET, + NULL, 0, NULL, &stJoyStatus, ulDataLen, &ulDataLen); + } + if ((stJoyStatus.ucJs_JoyStickMask & 0x03) > 0) { + numdevs++; + } + if (((stJoyStatus.ucJs_JoyStickMask >> 2) & 0x03) > 0) { + numdevs++; + } + } + + if (numdevs > maxdevs) { + numdevs = maxdevs; + } + + /* If *any* joystick was detected... Let's configure SDL for them */ + if (numdevs > 0) { + /* Verify if it is a "user defined" joystick */ + if (joyGetEnv(&joycfg)) { + GAME_3POS_STRUCT * axis[4]; + axis[0] = &stGameCalib.Ax; + axis[1] = &stGameCalib.Ay; + axis[2] = &stGameCalib.Bx; + axis[3] = &stGameCalib.By; + + /* Say it has one device only (user defined is always one device only) */ + numdevs = 1; + + /* Define Device 0 as... */ + SYS_JoyData[0].id = 0; + + /* Define Number of Axes... up to 4 */ + if (joycfg.axes>MAX_AXES) { + joycfg.axes = MAX_AXES; + } + SYS_JoyData[0].axes = joycfg.axes; + + /* Define number of buttons... 8 if 2 axes, 6 if 3 axes and 4 if 4 axes */ + maxbut = MAX_BUTTONS; + if (joycfg.axes > 2) { + maxbut -= ((joycfg.axes - 2) << 1); /* MAX_BUTTONS - 2*(axes-2) */ + } + if (joycfg.buttons > maxbut) { + joycfg.buttons = maxbut; + } + SYS_JoyData[0].buttons = joycfg.buttons; + + /* Define number of hats */ + if (joycfg.hats > MAX_HATS) { + joycfg.hats = MAX_HATS; + } + SYS_JoyData[0].hats = joycfg.hats; + + /* Define number of balls */ + if (joycfg.balls > MAX_BALLS) { + joycfg.balls = MAX_BALLS; + } + SYS_JoyData[0].balls = joycfg.balls; + + /* Initialize Axes Callibration Values */ + for (i = 0; i < joycfg.axes; i++) { + SYS_JoyData[0].axes_min[i] = axis[i]->lower; + SYS_JoyData[0].axes_med[i] = axis[i]->centre; + SYS_JoyData[0].axes_max[i] = axis[i]->upper; + } + /* Initialize Buttons 5 to 8 structures */ + if (joycfg.buttons >=5 ) { + SYS_JoyData[0].buttoncalc[0] = ((axis[2]->lower + axis[3]->centre) >> 1); + } + if (joycfg.buttons >=6 ) { + SYS_JoyData[0].buttoncalc[1] = ((axis[3]->lower + axis[3]->centre) >> 1); + } + if (joycfg.buttons >=7 ) { + SYS_JoyData[0].buttoncalc[2] = ((axis[2]->upper + axis[3]->centre) >> 1); + } + if (joycfg.buttons >=8 ) { + SYS_JoyData[0].buttoncalc[3] = ((axis[3]->upper + axis[3]->centre) >> 1); + } + /* Intialize Joystick Name */ + SDL_strlcpy (SYS_JoyData[0].szDeviceName,joycfg.name, SDL_arraysize(SYS_JoyData[0].szDeviceName)); + } + /* Default Init ... autoconfig */ + else { + /* if two devices were detected... configure as Joy1 4 axis and Joy2 2 axis */ + if (numdevs == 2) { + /* Define Device 0 as 4 axes, 4 buttons */ + SYS_JoyData[0].id = 0; + SYS_JoyData[0].axes = 4; + SYS_JoyData[0].buttons = 4; + SYS_JoyData[0].hats = 0; + SYS_JoyData[0].balls = 0; + SYS_JoyData[0].axes_min[0] = stGameCalib.Ax.lower; + SYS_JoyData[0].axes_med[0] = stGameCalib.Ax.centre; + SYS_JoyData[0].axes_max[0] = stGameCalib.Ax.upper; + SYS_JoyData[0].axes_min[1] = stGameCalib.Ay.lower; + SYS_JoyData[0].axes_med[1] = stGameCalib.Ay.centre; + SYS_JoyData[0].axes_max[1] = stGameCalib.Ay.upper; + SYS_JoyData[0].axes_min[2] = stGameCalib.Bx.lower; + SYS_JoyData[0].axes_med[2] = stGameCalib.Bx.centre; + SYS_JoyData[0].axes_max[2] = stGameCalib.Bx.upper; + SYS_JoyData[0].axes_min[3] = stGameCalib.By.lower; + SYS_JoyData[0].axes_med[3] = stGameCalib.By.centre; + SYS_JoyData[0].axes_max[3] = stGameCalib.By.upper; + /* Define Device 1 as 2 axes, 2 buttons */ + SYS_JoyData[1].id = 1; + SYS_JoyData[1].axes = 2; + SYS_JoyData[1].buttons = 2; + SYS_JoyData[1].hats = 0; + SYS_JoyData[1].balls = 0; + SYS_JoyData[1].axes_min[0] = stGameCalib.Bx.lower; + SYS_JoyData[1].axes_med[0] = stGameCalib.Bx.centre; + SYS_JoyData[1].axes_max[0] = stGameCalib.Bx.upper; + SYS_JoyData[1].axes_min[1] = stGameCalib.By.lower; + SYS_JoyData[1].axes_med[1] = stGameCalib.By.centre; + SYS_JoyData[1].axes_max[1] = stGameCalib.By.upper; + } + /* One joystick only? */ + else { + /* If it is joystick A... */ + if ((stJoyStatus.ucJs_JoyStickMask & 0x03) > 0) { + /* Define Device 0 as 2 axes, 4 buttons */ + SYS_JoyData[0].id = 0; + SYS_JoyData[0].axes = 2; + SYS_JoyData[0].buttons = 4; + SYS_JoyData[0].hats = 0; + SYS_JoyData[0].balls = 0; + SYS_JoyData[0].axes_min[0] = stGameCalib.Ax.lower; + SYS_JoyData[0].axes_med[0] = stGameCalib.Ax.centre; + SYS_JoyData[0].axes_max[0] = stGameCalib.Ax.upper; + SYS_JoyData[0].axes_min[1] = stGameCalib.Ay.lower; + SYS_JoyData[0].axes_med[1] = stGameCalib.Ay.centre; + SYS_JoyData[0].axes_max[1] = stGameCalib.Ay.upper; + } + /* If not, it is joystick B */ + else { + /* Define Device 1 as 2 axes, 2 buttons */ + SYS_JoyData[0].id = 1; + SYS_JoyData[0].axes = 2; + SYS_JoyData[0].buttons = 2; + SYS_JoyData[0].hats = 0; + SYS_JoyData[0].balls = 0; + SYS_JoyData[0].axes_min[0] = stGameCalib.Bx.lower; + SYS_JoyData[0].axes_med[0] = stGameCalib.Bx.centre; + SYS_JoyData[0].axes_max[0] = stGameCalib.Bx.upper; + SYS_JoyData[0].axes_min[1] = stGameCalib.By.lower; + SYS_JoyData[0].axes_med[1] = stGameCalib.By.centre; + SYS_JoyData[0].axes_max[1] = stGameCalib.By.upper; + } + } + + /* Hack to define Joystick Port Names */ + if (numdevs > maxdevs) { + numdevs = maxdevs; + } + + for (i = 0; i < numdevs; i++) { + SDL_snprintf(SYS_JoyData[i].szDeviceName, SDL_arraysize(SYS_JoyData[i].szDeviceName), + "Default Joystick %c", 'A'+SYS_JoyData[i].id); + } + } + } + + /* Return the number of devices found */ + numjoysticks = numdevs; + return numdevs; +} + +static int OS2_NumJoysticks(void) +{ + return numjoysticks; +} + +static void OS2_JoystickDetect(void) +{ +} + +static const char *OS2_JoystickGetDeviceName(int device_index) +{ + /* No need to verify if device exists, already done in upper layer */ + return SYS_JoyData[device_index].szDeviceName; +} + +static const char *OS2_JoystickGetDevicePath(int device_index) +{ + return NULL; +} + +static int OS2_JoystickGetDeviceSteamVirtualGamepadSlot(int device_index) +{ + return -1; +} + +static int OS2_JoystickGetDevicePlayerIndex(int device_index) +{ + return -1; +} + +static void OS2_JoystickSetDevicePlayerIndex(int device_index, int player_index) +{ +} + +static SDL_JoystickGUID OS2_JoystickGetDeviceGUID(int device_index) +{ + /* the GUID is just the name for now */ + const char *name = OS2_JoystickGetDeviceName(device_index); + return SDL_CreateJoystickGUIDForName(name); +} + +static SDL_JoystickID OS2_JoystickGetDeviceInstanceID(int device_index) +{ + return device_index; +} + +/******************************************************************************/ +/* Function to open a joystick for use. */ +/* The joystick to open is specified by the device index. */ +/* This should fill the nbuttons and naxes fields of the joystick structure. */ +/* It returns 0, or -1 if there is an error. */ +/******************************************************************************/ +static int OS2_JoystickOpen(SDL_Joystick *joystick, int device_index) +{ + int index; /* Index shortcut for index in joystick structure */ + int i; /* Generic Counter */ + + /* allocate memory for system specific hardware data */ + joystick->hwdata = (struct joystick_hwdata *) SDL_calloc(1, sizeof(*joystick->hwdata)); + if (!joystick->hwdata) { + return SDL_OutOfMemory(); + } + + /* ShortCut Pointer */ + index = device_index; + joystick->instance_id = device_index; + + /* Define offsets and scales for all axes */ + joystick->hwdata->id = SYS_JoyData[index].id; + for (i = 0; i < MAX_AXES; ++i) { + if ((i < 2) || i < SYS_JoyData[index].axes) { + joystick->hwdata->transaxes[i].offset = ((SDL_JOYSTICK_AXIS_MAX + SDL_JOYSTICK_AXIS_MIN)>>1) - SYS_JoyData[index].axes_med[i]; + joystick->hwdata->transaxes[i].scale1 = (float)SDL_abs((SDL_JOYSTICK_AXIS_MIN/SYS_JoyData[index].axes_min[i])); + joystick->hwdata->transaxes[i].scale2 = (float)SDL_abs((SDL_JOYSTICK_AXIS_MAX/SYS_JoyData[index].axes_max[i])); + } else { + joystick->hwdata->transaxes[i].offset = 0; + joystick->hwdata->transaxes[i].scale1 = 1.0f; /* Just in case */ + joystick->hwdata->transaxes[i].scale2 = 1.0f; /* Just in case */ + } + } + + /* fill nbuttons, naxes, and nhats fields */ + joystick->nbuttons = SYS_JoyData[index].buttons; + joystick->naxes = SYS_JoyData[index].axes; + + /* joystick->nhats = SYS_JoyData[index].hats; */ + joystick->nhats = 0; /* No support for hats at this time */ + + /* joystick->nballs = SYS_JoyData[index].balls; */ + joystick->nballs = 0; /* No support for balls at this time */ + + return 0; +} + +static int OS2_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ + return SDL_Unsupported(); +} + +static int OS2_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) +{ + return SDL_Unsupported(); +} + +static Uint32 OS2_JoystickGetCapabilities(SDL_Joystick *joystick) +{ + return 0; +} + +static int OS2_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + return SDL_Unsupported(); +} + +static int OS2_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + +static int OS2_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled) +{ + return SDL_Unsupported(); +} + +/***************************************************************************/ +/* Function to update the state of a joystick - called as a device poll. */ +/* This function shouldn't update the joystick structure directly, */ +/* but instead should call SDL_PrivateJoystick*() to deliver events */ +/* and update joystick device state. */ +/***************************************************************************/ +static void OS2_JoystickUpdate(SDL_Joystick *joystick) +{ + APIRET rc; /* Generic OS/2 return code */ + int index; /* index shortcurt to joystick index */ + int i; /* Generic counter */ + int normbut; /* Number of buttons reported by joystick */ + int corr; /* Correction for button names */ + Sint16 value; /* Values used to update axis values */ + struct _transaxes *transaxes; /* Shortcut for Correction structure */ + Uint32 pos[MAX_AXES]; /* Vector to inform the Axis status */ + ULONG ulDataLen; /* Size of data */ + GAME_STATUS_STRUCT stGameStatus; /* Joystick Status Structure */ + + ulDataLen = sizeof(stGameStatus); + rc = DosDevIOCtl(hJoyPort, IOCTL_CAT_USER, GAME_GET_STATUS, + NULL, 0, NULL, &stGameStatus, ulDataLen, &ulDataLen); + if (rc != 0) { + SDL_SetError("Could not read joystick status."); + return; /* Could not read data */ + } + + /* Shortcut pointer */ + index = joystick->instance_id; + + /* joystick motion events */ + + if (SYS_JoyData[index].id == 0) { + pos[0] = stGameStatus.curdata.A.x; + pos[1] = stGameStatus.curdata.A.y; + if (SYS_JoyData[index].axes >= 3) { + pos[2] = stGameStatus.curdata.B.x; + } else { + pos[2] = 0; + } + if (SYS_JoyData[index].axes >= 4) { + pos[3] = stGameStatus.curdata.B.y; + } else { + pos[3] = 0; + } + /* OS/2 basic drivers do not support more than 4 axes joysticks */ + } + else if (SYS_JoyData[index].id == 1) { + pos[0] = stGameStatus.curdata.B.x; + pos[1] = stGameStatus.curdata.B.y; + pos[2] = 0; + pos[3] = 0; + } + + /* Corrects the movements using the callibration */ + transaxes = joystick->hwdata->transaxes; + for (i = 0; i < joystick->naxes; i++) { + value = pos[i] + transaxes[i].offset; + if (value < 0) { + value *= transaxes[i].scale1; + if (value > 0) { + value = SDL_JOYSTICK_AXIS_MIN; + } + } else { + value *= transaxes[i].scale2; + if (value < 0) { + value = SDL_JOYSTICK_AXIS_MAX; + } + } + SDL_PrivateJoystickAxis(joystick, (Uint8)i, (Sint16)value); + } + + /* joystick button A to D events */ + if (SYS_JoyData[index].id == 1) { + corr = 2; + } else { + corr = 0; + } + normbut = 4; /* Number of normal buttons */ + if (joystick->nbuttons < normbut) { + normbut = joystick->nbuttons; + } + for (i = corr; (i-corr) < normbut; ++i) { + /* + Button A: 1110 0000 + Button B: 1101 0000 + Button C: 1011 0000 + Button D: 0111 0000 + */ + if ((~stGameStatus.curdata.butMask)>>4 & JOY_BUTTON_FLAG(i)) { + SDL_PrivateJoystickButton(joystick, (Uint8)(i-corr), SDL_PRESSED); + } else { + SDL_PrivateJoystickButton(joystick, (Uint8)(i-corr), SDL_RELEASED); + } + } + + /* Joystick button E to H buttons */ + /* + Button E: Axis 2 X Left + Button F: Axis 2 Y Up + Button G: Axis 2 X Right + Button H: Axis 2 Y Down + */ + if (joystick->nbuttons >= 5) { + if (stGameStatus.curdata.B.x < SYS_JoyData[index].buttoncalc[0]) { + SDL_PrivateJoystickButton(joystick, (Uint8)4, SDL_PRESSED); + } else { + SDL_PrivateJoystickButton(joystick, (Uint8)4, SDL_RELEASED); + } + } + if (joystick->nbuttons >= 6) { + if (stGameStatus.curdata.B.y < SYS_JoyData[index].buttoncalc[1]) { + SDL_PrivateJoystickButton(joystick, (Uint8)5, SDL_PRESSED); + } else { + SDL_PrivateJoystickButton(joystick, (Uint8)5, SDL_RELEASED); + } + } + if (joystick->nbuttons >= 7) { + if (stGameStatus.curdata.B.x > SYS_JoyData[index].buttoncalc[2]) { + SDL_PrivateJoystickButton(joystick, (Uint8)6, SDL_PRESSED); + } else { + SDL_PrivateJoystickButton(joystick, (Uint8)6, SDL_RELEASED); + } + } + if (joystick->nbuttons >= 8) { + if (stGameStatus.curdata.B.y > SYS_JoyData[index].buttoncalc[3]) { + SDL_PrivateJoystickButton(joystick, (Uint8)7, SDL_PRESSED); + } else { + SDL_PrivateJoystickButton(joystick, (Uint8)7, SDL_RELEASED); + } + } + + /* joystick hat events */ + /* Not Supported under OS/2 */ + /* joystick ball events */ + /* Not Supported under OS/2 */ +} + +/******************************************/ +/* Function to close a joystick after use */ +/******************************************/ +static void OS2_JoystickClose(SDL_Joystick *joystick) +{ + /* free system specific hardware data */ + SDL_free(joystick->hwdata); +} + +/********************************************************************/ +/* Function to perform any system-specific joystick related cleanup */ +/********************************************************************/ +static void OS2_JoystickQuit(void) +{ + joyPortClose(&hJoyPort); +} + +static SDL_bool OS2_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) +{ + return SDL_FALSE; +} + + +/************************/ +/* OS/2 Implementations */ +/************************/ + +/*****************************************/ +/* Open Joystick Port, if not opened yet */ +/*****************************************/ +static int joyPortOpen(HFILE * hGame) +{ + APIRET rc; /* Generic Return Code */ + ULONG ulAction; /* ? */ + ULONG ulVersion; /* Version of joystick driver */ + ULONG ulDataLen; /* Size of version data */ + + /* Verifies if joyport is not already open... */ + if (*hGame != NULLHANDLE) { + return 0; + } + + /* Open GAME$ for read */ + rc = DosOpen("GAME$ ", hGame, &ulAction, 0, FILE_READONLY, + FILE_OPEN, OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE, NULL); + if (rc != 0) { + return SDL_SetError("Could not open Joystick Port."); + } + + /* Get Joystick Driver Version... must be 2.0 or higher */ + ulVersion = 0; + ulDataLen = sizeof(ulVersion); + rc = DosDevIOCtl(*hGame, IOCTL_CAT_USER, GAME_GET_VERSION, + NULL, 0, NULL, &ulVersion, ulDataLen, &ulDataLen); + if (rc != 0) { + joyPortClose(hGame); + return SDL_SetError("Could not get Joystick Driver version."); + } + if (ulVersion < 0x20) { + joyPortClose(hGame); + return SDL_SetError("Driver too old. At least IBM driver version 2.0 required."); + } + + return 0; +} + +/****************************/ +/* Close JoyPort, if opened */ +/****************************/ +static void joyPortClose(HFILE * hGame) +{ + if (*hGame != NULLHANDLE) { + DosClose(*hGame); + } + *hGame = NULLHANDLE; +} + +/***************************/ +/* Get SDL Joystick EnvVar */ +/***************************/ +static int joyGetEnv(struct _joycfg * joydata) +{ + const char *joyenv; /* Pointer to tested character */ + char tempnumber[5]; /* Temporary place to put numeric texts */ + + joyenv = SDL_getenv("SDL_OS2_JOYSTICK"); + if (!joyenv) { + return 0; + } + + /* Joystick Environment is defined! */ + while (*joyenv == ' ' && *joyenv != 0) { + joyenv++; /* jump spaces... */ + } + + /* If the string name starts with '... get if fully */ + if (*joyenv == '\'') { + joyenv++; + joyenv += joyGetData(joyenv,joydata->name,'\'',sizeof(joydata->name)); + } + /* If not, get it until the next space */ + else if (*joyenv == '\"') { + joyenv++; + joyenv += joyGetData(joyenv,joydata->name,'\"',sizeof(joydata->name)); + } + else { + joyenv += joyGetData(joyenv,joydata->name, ' ',sizeof(joydata->name)); + } + + /* Now get the number of axes */ + while (*joyenv == ' ' && *joyenv != 0) { + joyenv++; /* jump spaces... */ + } + joyenv += joyGetData(joyenv,tempnumber,' ',sizeof(tempnumber)); + joydata->axes = SDL_atoi(tempnumber); + + /* Now get the number of buttons */ + while (*joyenv == ' ' && *joyenv != 0) { + joyenv++; /* jump spaces... */ + } + joyenv += joyGetData(joyenv,tempnumber,' ',sizeof(tempnumber)); + joydata->buttons = SDL_atoi(tempnumber); + + /* Now get the number of hats */ + while (*joyenv == ' ' && *joyenv != 0) { + joyenv++; /* jump spaces... */ + } + joyenv += joyGetData(joyenv,tempnumber,' ',sizeof(tempnumber)); + joydata->hats = SDL_atoi(tempnumber); + + /* Now get the number of balls */ + while (*joyenv==' ' && *joyenv != 0) { + joyenv++; /* jump spaces... */ + } + joyenv += joyGetData(joyenv,tempnumber,' ',sizeof(tempnumber)); + joydata->balls = SDL_atoi(tempnumber); + + return 1; +} + +/************************************************************************/ +/* Get a text from in the string starting in joyenv until it finds */ +/* the stopchar or maxchars is reached. The result is placed in name. */ +/************************************************************************/ +static int joyGetData(const char *joyenv, char *name, char stopchar, size_t maxchars) +{ + char *nameptr; /* Pointer to the selected character */ + int chcnt = 0; /* Count how many characters where copied */ + + nameptr = name; + while (*joyenv!=stopchar && *joyenv != 0) { + if (nameptr < (name + (maxchars-1))) { + *nameptr = *joyenv; /* Only copy if smaller than maximum */ + nameptr++; + } + chcnt++; + joyenv++; + } + if (*joyenv == stopchar) { + joyenv++; /* Jump stopchar */ + chcnt++; + } + *nameptr = 0; /* Mark last byte */ + return chcnt; +} + +SDL_JoystickDriver SDL_OS2_JoystickDriver = { + OS2_JoystickInit, + OS2_NumJoysticks, + OS2_JoystickDetect, + OS2_JoystickGetDeviceName, + OS2_JoystickGetDevicePath, + OS2_JoystickGetDeviceSteamVirtualGamepadSlot, + OS2_JoystickGetDevicePlayerIndex, + OS2_JoystickSetDevicePlayerIndex, + OS2_JoystickGetDeviceGUID, + OS2_JoystickGetDeviceInstanceID, + OS2_JoystickOpen, + OS2_JoystickRumble, + OS2_JoystickRumbleTriggers, + OS2_JoystickGetCapabilities, + OS2_JoystickSetLED, + OS2_JoystickSendEffect, + OS2_JoystickSetSensorsEnabled, + OS2_JoystickUpdate, + OS2_JoystickClose, + OS2_JoystickQuit, + OS2_JoystickGetGamepadMapping +}; + +#endif /* SDL_JOYSTICK_OS2 */ diff --git a/SDL2-2.30.5/src/joystick/ps2/SDL_sysjoystick.c b/SDL2-2.30.5/src/joystick/ps2/SDL_sysjoystick.c new file mode 100644 index 0000000..8c0edb7 --- /dev/null +++ b/SDL2-2.30.5/src/joystick/ps2/SDL_sysjoystick.c @@ -0,0 +1,372 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_JOYSTICK_PS2 + +/* This is the PS2 implementation of the SDL joystick API */ +#include +#include +#include + +#include /* For the definition of NULL */ +#include +#include + +#include "../SDL_sysjoystick.h" +#include "../SDL_joystick_c.h" + +#include "SDL_events.h" +#include "SDL_error.h" + +#define PS2_MAX_PORT 2 /* each ps2 has 2 ports */ +#define PS2_MAX_SLOT 4 /* maximum - 4 slots in one multitap */ +#define MAX_CONTROLLERS (PS2_MAX_PORT * PS2_MAX_SLOT) +#define PS2_ANALOG_STICKS 2 +#define PS2_ANALOG_AXIS 2 +#define PS2_BUTTONS 16 +#define PS2_TOTAL_AXIS (PS2_ANALOG_STICKS * PS2_ANALOG_AXIS) + +struct JoyInfo +{ + uint8_t padBuf[256]; + uint16_t btns; + uint8_t analog_state[PS2_TOTAL_AXIS]; + uint8_t port; + uint8_t slot; + int8_t rumble_ready; + int8_t opened; +} __attribute__((aligned(64))); + +static uint8_t enabled_pads = 0; +static struct JoyInfo joyInfo[MAX_CONTROLLERS]; + +static inline int16_t convert_u8_to_s16(uint8_t val) +{ + if (val == 0) { + return -0x7fff; + } + return val * 0x0101 - 0x8000; +} + +static inline uint8_t rumble_status(uint8_t index) +{ + char actAlign[6]; + int res; + struct JoyInfo *info = &joyInfo[index]; + + if (info->rumble_ready == 0) { + actAlign[0] = 0; + actAlign[1] = 1; + actAlign[2] = 0xff; + actAlign[3] = 0xff; + actAlign[4] = 0xff; + actAlign[5] = 0xff; + + res = padSetActAlign(info->port, info->slot, actAlign); + info->rumble_ready = res <= 0 ? -1 : 1; + } + + return info->rumble_ready == 1; +} + +/* Function to scan the system for joysticks. + * Joystick 0 should be the system default joystick. + * This function should return 0, or -1 on an unrecoverable error. + */ +static int PS2_JoystickInit(void) +{ + uint32_t port = 0; + uint32_t slot = 0; + + if (init_joystick_driver(true) < 0) { + return -1; + } + + for (port = 0; port < PS2_MAX_PORT; port++) { + mtapPortOpen(port); + } + /* it can fail - we dont care, we will check it more strictly when padPortOpen */ + + for (slot = 0; slot < PS2_MAX_SLOT; slot++) { + for (port = 0; port < PS2_MAX_PORT; port++) { + /* 2 main controller ports acts the same with and without multitap + Port 0,0 -> Connector 1 - the same as Port 0 + Port 1,0 -> Connector 2 - the same as Port 1 + Port 0,1 -> Connector 3 + Port 1,1 -> Connector 4 + Port 0,2 -> Connector 5 + Port 1,2 -> Connector 6 + Port 0,3 -> Connector 7 + Port 1,3 -> Connector 8 + */ + + struct JoyInfo *info = &joyInfo[enabled_pads]; + if (padPortOpen(port, slot, (void *)info->padBuf) > 0) { + info->port = (uint8_t)port; + info->slot = (uint8_t)slot; + info->opened = 1; + enabled_pads++; + } + } + } + + return enabled_pads > 0 ? 0 : -1; +} + +/* Function to return the number of joystick devices plugged in right now */ +static int PS2_JoystickGetCount() +{ + return (int)enabled_pads; +} + +/* Function to cause any queued joystick insertions to be processed */ +static void PS2_JoystickDetect() +{ +} + +/* Function to get the device-dependent name of a joystick */ +static const char *PS2_JoystickGetDeviceName(int index) +{ + if (index >= 0 && index < enabled_pads) { + return "PS2 Controller"; + } + + SDL_SetError("No joystick available with that index"); + return NULL; +} + +/* Function to get the device-dependent path of a joystick */ +static const char *PS2_JoystickGetDevicePath(int index) +{ + return NULL; +} + +/* Function to get the Steam virtual gamepad slot of a joystick */ +static int PS2_JoystickGetDeviceSteamVirtualGamepadSlot(int device_index) +{ + return -1; +} + +/* Function to get the player index of a joystick */ +static int PS2_JoystickGetDevicePlayerIndex(int device_index) +{ + return -1; +} + +/* Function to set the player index of a joystick */ +static void PS2_JoystickSetDevicePlayerIndex(int device_index, int player_index) +{ +} + +/* Function to return the stable GUID for a plugged in device */ +static SDL_JoystickGUID PS2_JoystickGetDeviceGUID(int device_index) +{ + /* the GUID is just the name for now */ + const char *name = PS2_JoystickGetDeviceName(device_index); + return SDL_CreateJoystickGUIDForName(name); +} + +/* Function to get the current instance id of the joystick located at device_index */ +static SDL_JoystickID PS2_JoystickGetDeviceInstanceID(int device_index) +{ + return device_index; +} + +/* Function to open a joystick for use. + The joystick to open is specified by the device index. + This should fill the nbuttons and naxes fields of the joystick structure. + It returns 0, or -1 if there is an error. +*/ +static int PS2_JoystickOpen(SDL_Joystick *joystick, int device_index) +{ + int index = joystick->instance_id; + struct JoyInfo *info = &joyInfo[index]; + + if (!info->opened) { + if (padPortOpen(info->port, info->slot, (void *)info->padBuf) > 0) { + info->opened = 1; + } else { + return -1; + } + } + joystick->nbuttons = PS2_BUTTONS; + joystick->naxes = PS2_TOTAL_AXIS; + joystick->nhats = 0; + joystick->instance_id = device_index; + + return 0; +} + +/* Rumble functionality */ +static int PS2_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ + char actAlign[6]; + int res; + int index = joystick->instance_id; + struct JoyInfo *info = &joyInfo[index]; + + if (!rumble_status(index)) { + return -1; + } + + // Initial value + actAlign[0] = low_frequency_rumble >> 8; // Enable small engine + actAlign[1] = high_frequency_rumble >> 8; // Enable big engine + actAlign[2] = 0xff; + actAlign[3] = 0xff; + actAlign[4] = 0xff; + actAlign[5] = 0xff; + + res = padSetActDirect(info->port, info->slot, actAlign); + return res == 1 ? 0 : -1; +} + +/* Rumble functionality */ +static int PS2_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left, Uint16 right) +{ + return -1; +} + +/* Capability detection */ +static Uint32 PS2_JoystickGetCapabilities(SDL_Joystick *joystick) +{ + return SDL_JOYCAP_RUMBLE; +} + +/* LED functionality */ +static int PS2_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + return -1; +} + +/* General effects */ +static int PS2_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) +{ + return -1; +} + +/* Sensor functionality */ +static int PS2_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled) +{ + return -1; +} + +/* Function to update the state of a joystick - called as a device poll. + * This function shouldn't update the joystick structure directly, + * but instead should call SDL_PrivateJoystick*() to deliver events + * and update joystick device state. + */ +static void PS2_JoystickUpdate(SDL_Joystick *joystick) +{ + uint8_t i; + uint8_t previous_axis, current_axis; + uint16_t mask, previous, current; + struct padButtonStatus buttons; + uint8_t all_axis[PS2_TOTAL_AXIS]; + int index = joystick->instance_id; + struct JoyInfo *info = &joyInfo[index]; + int state = padGetState(info->port, info->slot); + + if (state != PAD_STATE_DISCONN && state != PAD_STATE_EXECCMD && state != PAD_STATE_ERROR) { + int ret = padRead(info->port, info->slot, &buttons); /* port, slot, buttons */ + if (ret != 0) { + /* Buttons */ + int32_t pressed_buttons = 0xffff ^ buttons.btns; + ; + if (info->btns != pressed_buttons) { + for (i = 0; i < PS2_BUTTONS; i++) { + mask = (1 << i); + previous = info->btns & mask; + current = pressed_buttons & mask; + if (previous != current) { + SDL_PrivateJoystickButton(joystick, i, current ? SDL_PRESSED : SDL_RELEASED); + } + } + } + info->btns = pressed_buttons; + + /* Analog */ + all_axis[0] = buttons.ljoy_h; + all_axis[1] = buttons.ljoy_v; + all_axis[2] = buttons.rjoy_h; + all_axis[3] = buttons.rjoy_v; + + for (i = 0; i < PS2_TOTAL_AXIS; i++) { + previous_axis = info->analog_state[i]; + current_axis = all_axis[i]; + if (previous_axis != current_axis) { + SDL_PrivateJoystickAxis(joystick, i, convert_u8_to_s16(current_axis)); + } + + info->analog_state[i] = current_axis; + } + } + } +} + +/* Function to close a joystick after use */ +static void PS2_JoystickClose(SDL_Joystick *joystick) +{ + int index = joystick->instance_id; + struct JoyInfo *info = &joyInfo[index]; + padPortClose(info->port, info->slot); + info->opened = 0; +} + +/* Function to perform any system-specific joystick related cleanup */ +static void PS2_JoystickQuit(void) +{ + deinit_joystick_driver(true); +} + +static SDL_bool PS2_GetGamepadMapping(int device_index, SDL_GamepadMapping *out) +{ + return SDL_FALSE; +} + +SDL_JoystickDriver SDL_PS2_JoystickDriver = { + PS2_JoystickInit, + PS2_JoystickGetCount, + PS2_JoystickDetect, + PS2_JoystickGetDeviceName, + PS2_JoystickGetDevicePath, + PS2_JoystickGetDeviceSteamVirtualGamepadSlot, + PS2_JoystickGetDevicePlayerIndex, + PS2_JoystickSetDevicePlayerIndex, + PS2_JoystickGetDeviceGUID, + PS2_JoystickGetDeviceInstanceID, + PS2_JoystickOpen, + PS2_JoystickRumble, + PS2_JoystickRumbleTriggers, + PS2_JoystickGetCapabilities, + PS2_JoystickSetLED, + PS2_JoystickSendEffect, + PS2_JoystickSetSensorsEnabled, + PS2_JoystickUpdate, + PS2_JoystickClose, + PS2_JoystickQuit, + PS2_GetGamepadMapping, +}; + +#endif /* SDL_JOYSTICK_PS2 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/joystick/psp/SDL_sysjoystick.c b/SDL2-2.30.5/src/joystick/psp/SDL_sysjoystick.c new file mode 100644 index 0000000..9b60dfe --- /dev/null +++ b/SDL2-2.30.5/src/joystick/psp/SDL_sysjoystick.c @@ -0,0 +1,289 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_JOYSTICK_PSP + +/* This is the PSP implementation of the SDL joystick API */ +#include + +#include /* For the definition of NULL */ +#include + +#include "../SDL_sysjoystick.h" +#include "../SDL_joystick_c.h" + +#include "SDL_events.h" +#include "SDL_error.h" + +/* Current pad state */ +static SceCtrlData pad = { .Lx = 0, .Ly = 0, .Buttons = 0 }; +static const enum PspCtrlButtons button_map[] = { + PSP_CTRL_TRIANGLE, PSP_CTRL_CIRCLE, PSP_CTRL_CROSS, PSP_CTRL_SQUARE, + PSP_CTRL_LTRIGGER, PSP_CTRL_RTRIGGER, + PSP_CTRL_DOWN, PSP_CTRL_LEFT, PSP_CTRL_UP, PSP_CTRL_RIGHT, + PSP_CTRL_SELECT, PSP_CTRL_START, PSP_CTRL_HOME, PSP_CTRL_HOLD +}; +static int analog_map[256]; /* Map analog inputs to -32768 -> 32767 */ + +typedef struct +{ + int x; + int y; +} point; + +/* 4 points define the bezier-curve. */ +static point a = { 0, 0 }; +static point b = { 50, 0 }; +static point c = { 78, 32767 }; +static point d = { 128, 32767 }; + +/* simple linear interpolation between two points */ +static SDL_INLINE void lerp(point *dest, point *pt_a, point *pt_b, float t) +{ + dest->x = pt_a->x + (pt_b->x - pt_a->x) * t; + dest->y = pt_a->y + (pt_b->y - pt_a->y) * t; +} + +/* evaluate a point on a bezier-curve. t goes from 0 to 1.0 */ +static int calc_bezier_y(float t) +{ + point ab, bc, cd, abbc, bccd, dest; + lerp(&ab, &a, &b, t); /* point between a and b */ + lerp(&bc, &b, &c, t); /* point between b and c */ + lerp(&cd, &c, &d, t); /* point between c and d */ + lerp(&abbc, &ab, &bc, t); /* point between ab and bc */ + lerp(&bccd, &bc, &cd, t); /* point between bc and cd */ + lerp(&dest, &abbc, &bccd, t); /* point on the bezier-curve */ + return dest.y; +} + +/* Function to scan the system for joysticks. + * Joystick 0 should be the system default joystick. + * It should return number of joysticks, or -1 on an unrecoverable fatal error. + */ +static int PSP_JoystickInit(void) +{ + int i; + + /* Setup input */ + sceCtrlSetSamplingCycle(0); + sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG); + + /* Create an accurate map from analog inputs (0 to 255) + to SDL joystick positions (-32768 to 32767) */ + for (i = 0; i < 128; i++) { + float t = (float)i / 127.0f; + analog_map[i + 128] = calc_bezier_y(t); + analog_map[127 - i] = -1 * analog_map[i + 128]; + } + + /* Fire off a joystick add event */ + SDL_PrivateJoystickAdded(0); + + return 1; +} + +static int PSP_JoystickGetCount(void) +{ + return 1; +} + +static void PSP_JoystickDetect(void) +{ +} + +/* Function to get the device-dependent name of a joystick */ +static const char *PSP_JoystickGetDeviceName(int device_index) +{ + if (device_index == 0) { + return "PSP builtin joypad"; + } + + SDL_SetError("No joystick available with that index"); + return NULL; +} + +static const char *PSP_JoystickGetDevicePath(int index) +{ + return NULL; +} + +static int PSP_JoystickGetDeviceSteamVirtualGamepadSlot(int device_index) +{ + return -1; +} + +static int PSP_JoystickGetDevicePlayerIndex(int device_index) +{ + return -1; +} + +static void PSP_JoystickSetDevicePlayerIndex(int device_index, int player_index) +{ +} + +static SDL_JoystickGUID PSP_JoystickGetDeviceGUID(int device_index) +{ + /* the GUID is just the name for now */ + const char *name = PSP_JoystickGetDeviceName(device_index); + return SDL_CreateJoystickGUIDForName(name); +} + +/* Function to perform the mapping from device index to the instance id for this index */ +static SDL_JoystickID PSP_JoystickGetDeviceInstanceID(int device_index) +{ + return device_index; +} + +/* Function to open a joystick for use. + The joystick to open is specified by the device index. + This should fill the nbuttons and naxes fields of the joystick structure. + It returns 0, or -1 if there is an error. + */ +static int PSP_JoystickOpen(SDL_Joystick *joystick, int device_index) +{ + joystick->nbuttons = SDL_arraysize(button_map); + joystick->naxes = 2; + joystick->nhats = 0; + joystick->instance_id = device_index; + + return 0; +} + +static int PSP_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ + return SDL_Unsupported(); +} + +static int PSP_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) +{ + return SDL_Unsupported(); +} + +static Uint32 PSP_JoystickGetCapabilities(SDL_Joystick *joystick) +{ + return 0; +} + +static int PSP_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + return SDL_Unsupported(); +} + +static int PSP_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + +static int PSP_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled) +{ + return SDL_Unsupported(); +} + +/* Function to update the state of a joystick - called as a device poll. + * This function shouldn't update the joystick structure directly, + * but instead should call SDL_PrivateJoystick*() to deliver events + * and update joystick device state. + */ +static void PSP_JoystickUpdate(SDL_Joystick *joystick) +{ + int i; + enum PspCtrlButtons buttons; + enum PspCtrlButtons changed; + unsigned char x, y; + static enum PspCtrlButtons old_buttons = 0; + static unsigned char old_x = 0, old_y = 0; + + if (sceCtrlPeekBufferPositive(&pad, 1) <= 0) { + return; + } + buttons = pad.Buttons; + x = pad.Lx; + y = pad.Ly; + + /* Axes */ + if (old_x != x) { + SDL_PrivateJoystickAxis(joystick, 0, analog_map[x]); + old_x = x; + } + if (old_y != y) { + SDL_PrivateJoystickAxis(joystick, 1, analog_map[y]); + old_y = y; + } + + /* Buttons */ + changed = old_buttons ^ buttons; + old_buttons = buttons; + if (changed) { + for (i = 0; i < SDL_arraysize(button_map); i++) { + if (changed & button_map[i]) { + SDL_PrivateJoystickButton( + joystick, i, + (buttons & button_map[i]) ? SDL_PRESSED : SDL_RELEASED); + } + } + } +} + +/* Function to close a joystick after use */ +static void PSP_JoystickClose(SDL_Joystick *joystick) +{ +} + +/* Function to perform any system-specific joystick related cleanup */ +static void PSP_JoystickQuit(void) +{ +} + +static SDL_bool PSP_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) +{ + return SDL_FALSE; +} + +SDL_JoystickDriver SDL_PSP_JoystickDriver = { + PSP_JoystickInit, + PSP_JoystickGetCount, + PSP_JoystickDetect, + PSP_JoystickGetDeviceName, + PSP_JoystickGetDevicePath, + PSP_JoystickGetDeviceSteamVirtualGamepadSlot, + PSP_JoystickGetDevicePlayerIndex, + PSP_JoystickSetDevicePlayerIndex, + PSP_JoystickGetDeviceGUID, + PSP_JoystickGetDeviceInstanceID, + PSP_JoystickOpen, + PSP_JoystickRumble, + PSP_JoystickRumbleTriggers, + PSP_JoystickGetCapabilities, + PSP_JoystickSetLED, + PSP_JoystickSendEffect, + PSP_JoystickSetSensorsEnabled, + PSP_JoystickUpdate, + PSP_JoystickClose, + PSP_JoystickQuit, + PSP_JoystickGetGamepadMapping +}; + +#endif /* SDL_JOYSTICK_PSP */ + +/* vim: ts=4 sw=4 + */ diff --git a/SDL2-2.30.5/src/joystick/sort_controllers.py b/SDL2-2.30.5/src/joystick/sort_controllers.py new file mode 100644 index 0000000..c97559f --- /dev/null +++ b/SDL2-2.30.5/src/joystick/sort_controllers.py @@ -0,0 +1,153 @@ +#!/usr/bin/env python3 +# +# Script to sort the game controller database entries in SDL_gamecontroller.c + +import re + + +filename = "SDL_gamecontrollerdb.h" +input = open(filename) +output = open(f"{filename}.new", "w") +parsing_controllers = False +controllers = [] +controller_guids = {} +conditionals = [] +split_pattern = re.compile(r'([^"]*")([^,]*,)([^,]*,)([^"]*)(".*)') +# BUS (1) CRC (3,2) VID (5,4) (6) PID (8,7) (9) VERSION (11,10) MISC (12) +standard_guid_pattern = re.compile(r'^([0-9a-fA-F]{4})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})(0000)([0-9a-fA-F]{2})([0-9a-fA-F]{2})(0000)([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{4},)$') + +# These chipsets are used in multiple controllers with different mappings, +# without enough unique information to differentiate them. e.g. +# https://github.com/gabomdq/SDL_GameControllerDB/issues/202 +invalid_controllers = ( + ('0079', '0006', '0000'), # DragonRise Inc. Generic USB Joystick + ('0079', '0006', '6120'), # DragonRise Inc. Generic USB Joystick + ('04b4', '2412', 'c529'), # Flydigi Vader 2, Vader 2 Pro, Apex 2, Apex 3 + ('16c0', '05e1', '0000'), # Xinmotek Controller +) + +def find_element(prefix, bindings): + i=0 + for element in bindings: + if element.startswith(prefix): + return i + i=(i + 1) + + return -1 + +def get_crc_from_entry(entry): + crc = "" + line = "".join(entry) + bindings = line.split(",") + pos = find_element("crc:", bindings) + if pos >= 0: + crc = bindings[pos][4:] + return crc + +def save_controller(line): + global controllers + match = split_pattern.match(line) + entry = [ match.group(1), match.group(2), match.group(3) ] + bindings = sorted(match.group(4).split(",")) + if (bindings[0] == ""): + bindings.pop(0) + + name = entry[2].rstrip(',') + + crc = "" + pos = find_element("crc:", bindings) + if pos >= 0: + crc = bindings[pos] + "," + bindings.pop(pos) + + guid_match = standard_guid_pattern.match(entry[1]) + if guid_match: + groups = guid_match.groups() + crc_value = groups[2] + groups[1] + vid_value = groups[4] + groups[3] + pid_value = groups[7] + groups[6] + version_value = groups[10] + groups[9] + #print("CRC: %s, VID: %s, PID: %s, VERSION: %s" % (crc_value, vid_value, pid_value, version_value)) + + if crc_value == "0000": + if crc != "": + crc_value = crc[4:-1] + else: + print("Extracting CRC from GUID of " + name) + entry[1] = groups[0] + "0000" + "".join(groups[3:]) + crc = "crc:" + crc_value + "," + + if (vid_value, pid_value, crc_value) in invalid_controllers: + print("Controller '%s' not unique, skipping" % name) + return + + pos = find_element("sdk", bindings) + if pos >= 0: + bindings.append(bindings.pop(pos)) + + pos = find_element("hint:", bindings) + if pos >= 0: + bindings.append(bindings.pop(pos)) + + entry.extend(crc) + entry.extend(",".join(bindings) + ",") + entry.append(match.group(5)) + controllers.append(entry) + + entry_id = entry[1] + get_crc_from_entry(entry) + if ',sdk' in line or ',hint:' in line: + conditionals.append(entry_id) + +def write_controllers(): + global controllers + global controller_guids + # Check for duplicates + for entry in controllers: + entry_id = entry[1] + get_crc_from_entry(entry) + if (entry_id in controller_guids and entry_id not in conditionals): + current_name = entry[2] + existing_name = controller_guids[entry_id][2] + print("Warning: entry '%s' is duplicate of entry '%s'" % (current_name, existing_name)) + + if (not current_name.startswith("(DUPE)")): + entry[2] = f"(DUPE) {current_name}" + + if (not existing_name.startswith("(DUPE)")): + controller_guids[entry_id][2] = f"(DUPE) {existing_name}" + + controller_guids[entry_id] = entry + + for entry in sorted(controllers, key=lambda entry: f"{entry[2]}-{entry[1]}"): + line = "".join(entry) + "\n" + line = line.replace("\t", " ") + if not line.endswith(",\n") and not line.endswith("*/\n") and not line.endswith(",\r\n") and not line.endswith("*/\r\n"): + print("Warning: '%s' is missing a comma at the end of the line" % (line)) + output.write(line) + + controllers = [] + controller_guids = {} + +for line in input: + if parsing_controllers: + if (line.startswith("{")): + output.write(line) + elif (line.startswith(" NULL")): + parsing_controllers = False + write_controllers() + output.write(line) + elif (line.startswith("#if")): + print(f"Parsing {line.strip()}") + output.write(line) + elif (line.startswith("#endif")): + write_controllers() + output.write(line) + else: + save_controller(line) + else: + if (line.startswith("static const char *")): + parsing_controllers = True + + output.write(line) + +output.close() +print(f"Finished writing {filename}.new") diff --git a/SDL2-2.0.12/src/joystick/steam/SDL_steamcontroller.c b/SDL2-2.30.5/src/joystick/steam/SDL_steamcontroller.c similarity index 96% rename from SDL2-2.0.12/src/joystick/steam/SDL_steamcontroller.c rename to SDL2-2.30.5/src/joystick/steam/SDL_steamcontroller.c index 82656f4..04327e3 100644 --- a/SDL2-2.0.12/src/joystick/steam/SDL_steamcontroller.c +++ b/SDL2-2.30.5/src/joystick/steam/SDL_steamcontroller.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -24,7 +24,6 @@ #include "../SDL_joystick_c.h" #include "SDL_steamcontroller.h" - void SDL_InitSteamControllers(SteamControllerConnectedCallback_t connectedCallback, SteamControllerDisconnectedCallback_t disconnectedCallback) { diff --git a/SDL2-2.0.12/src/joystick/steam/SDL_steamcontroller.h b/SDL2-2.30.5/src/joystick/steam/SDL_steamcontroller.h similarity index 96% rename from SDL2-2.0.12/src/joystick/steam/SDL_steamcontroller.h rename to SDL2-2.30.5/src/joystick/steam/SDL_steamcontroller.h index 629d687..35a7222 100644 --- a/SDL2-2.0.12/src/joystick/steam/SDL_steamcontroller.h +++ b/SDL2-2.30.5/src/joystick/steam/SDL_steamcontroller.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.30.5/src/joystick/usb_ids.h b/SDL2-2.30.5/src/joystick/usb_ids.h new file mode 100644 index 0000000..d166057 --- /dev/null +++ b/SDL2-2.30.5/src/joystick/usb_ids.h @@ -0,0 +1,179 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#ifndef usb_ids_h_ +#define usb_ids_h_ + +/* Definitions of useful USB VID/PID values */ + +#define USB_VENDOR_8BITDO 0x2dc8 +#define USB_VENDOR_AMAZON 0x1949 +#define USB_VENDOR_APPLE 0x05ac +#define USB_VENDOR_ASTRO 0x9886 +#define USB_VENDOR_ASUS 0x0b05 +#define USB_VENDOR_BACKBONE 0x358a +#define USB_VENDOR_GAMESIR 0x3537 +#define USB_VENDOR_DRAGONRISE 0x0079 +#define USB_VENDOR_GOOGLE 0x18d1 +#define USB_VENDOR_HORI 0x0f0d +#define USB_VENDOR_HYPERKIN 0x2e24 +#define USB_VENDOR_LOGITECH 0x046d +#define USB_VENDOR_MADCATZ 0x0738 +#define USB_VENDOR_MAYFLASH 0x33df +#define USB_VENDOR_MICROSOFT 0x045e +#define USB_VENDOR_NACON 0x146b +#define USB_VENDOR_NACON_ALT 0x3285 +#define USB_VENDOR_NINTENDO 0x057e +#define USB_VENDOR_NVIDIA 0x0955 +#define USB_VENDOR_PDP 0x0e6f +#define USB_VENDOR_POWERA 0x24c6 +#define USB_VENDOR_POWERA_ALT 0x20d6 +#define USB_VENDOR_QANBA 0x2c22 +#define USB_VENDOR_RAZER 0x1532 +#define USB_VENDOR_SAITEK 0x06a3 +#define USB_VENDOR_SHANWAN 0x2563 +#define USB_VENDOR_SHANWAN_ALT 0x20bc +#define USB_VENDOR_SONY 0x054c +#define USB_VENDOR_THRUSTMASTER 0x044f +#define USB_VENDOR_TURTLE_BEACH 0x10f5 +#define USB_VENDOR_VALVE 0x28de +#define USB_VENDOR_ZEROPLUS 0x0c12 + +#define USB_PRODUCT_8BITDO_XBOX_CONTROLLER1 0x2002 /* Ultimate Wired Controller for Xbox */ +#define USB_PRODUCT_8BITDO_XBOX_CONTROLLER2 0x3106 /* Ultimate Wireless / Pro 2 Wired Controller */ +#define USB_PRODUCT_AMAZON_LUNA_CONTROLLER 0x0419 +#define USB_PRODUCT_ASTRO_C40_XBOX360 0x0024 +#define USB_PRODUCT_BACKBONE_ONE_IOS 0x0103 +#define USB_PRODUCT_BACKBONE_ONE_IOS_PS5 0x0104 +#define USB_PRODUCT_GAMESIR_G7 0x1001 +#define USB_PRODUCT_GOOGLE_STADIA_CONTROLLER 0x9400 +#define USB_PRODUCT_EVORETRO_GAMECUBE_ADAPTER1 0x1843 +#define USB_PRODUCT_EVORETRO_GAMECUBE_ADAPTER2 0x1846 +#define USB_PRODUCT_HORI_FIGHTING_COMMANDER_OCTA_SERIES_X 0x0150 +#define USB_PRODUCT_HORI_HORIPAD_PRO_SERIES_X 0x014f +#define USB_PRODUCT_HORI_FIGHTING_STICK_ALPHA_PS4 0x011c +#define USB_PRODUCT_HORI_FIGHTING_STICK_ALPHA_PS5 0x0184 +#define USB_PRODUCT_LOGITECH_F310 0xc216 +#define USB_PRODUCT_LOGITECH_CHILLSTREAM 0xcad1 +#define USB_PRODUCT_MADCATZ_SAITEK_SIDE_PANEL_CONTROL_DECK 0x2218 +#define USB_PRODUCT_NACON_REVOLUTION_5_PRO_PS4_WIRELESS 0x0d16 +#define USB_PRODUCT_NACON_REVOLUTION_5_PRO_PS4_WIRED 0x0d17 +#define USB_PRODUCT_NACON_REVOLUTION_5_PRO_PS5_WIRELESS 0x0d18 +#define USB_PRODUCT_NACON_REVOLUTION_5_PRO_PS5_WIRED 0x0d19 +#define USB_PRODUCT_NINTENDO_GAMECUBE_ADAPTER 0x0337 +#define USB_PRODUCT_NINTENDO_N64_CONTROLLER 0x2019 +#define USB_PRODUCT_NINTENDO_SEGA_GENESIS_CONTROLLER 0x201e +#define USB_PRODUCT_NINTENDO_SNES_CONTROLLER 0x2017 +#define USB_PRODUCT_NINTENDO_SWITCH_JOYCON_GRIP 0x200e +#define USB_PRODUCT_NINTENDO_SWITCH_JOYCON_LEFT 0x2006 +#define USB_PRODUCT_NINTENDO_SWITCH_JOYCON_PAIR 0x2008 /* Used by joycond */ +#define USB_PRODUCT_NINTENDO_SWITCH_JOYCON_RIGHT 0x2007 +#define USB_PRODUCT_NINTENDO_SWITCH_PRO 0x2009 +#define USB_PRODUCT_NINTENDO_WII_REMOTE 0x0306 +#define USB_PRODUCT_NINTENDO_WII_REMOTE2 0x0330 +#define USB_PRODUCT_NVIDIA_SHIELD_CONTROLLER_V103 0x7210 +#define USB_PRODUCT_NVIDIA_SHIELD_CONTROLLER_V104 0x7214 +#define USB_PRODUCT_RAZER_ATROX 0x0a00 +#define USB_PRODUCT_RAZER_KITSUNE 0x1012 +#define USB_PRODUCT_RAZER_PANTHERA 0x0401 +#define USB_PRODUCT_RAZER_PANTHERA_EVO 0x1008 +#define USB_PRODUCT_RAZER_RAIJU 0x1000 +#define USB_PRODUCT_RAZER_TOURNAMENT_EDITION_USB 0x1007 +#define USB_PRODUCT_RAZER_TOURNAMENT_EDITION_BLUETOOTH 0x100a +#define USB_PRODUCT_RAZER_ULTIMATE_EDITION_USB 0x1004 +#define USB_PRODUCT_RAZER_ULTIMATE_EDITION_BLUETOOTH 0x1009 +#define USB_PRODUCT_RAZER_WOLVERINE_V2 0x0a29 +#define USB_PRODUCT_RAZER_WOLVERINE_V2_CHROMA 0x0a2e +#define USB_PRODUCT_RAZER_WOLVERINE_V2_PRO_PS5_WIRED 0x100b +#define USB_PRODUCT_RAZER_WOLVERINE_V2_PRO_PS5_WIRELESS 0x100c +#define USB_PRODUCT_RAZER_WOLVERINE_V2_PRO_XBOX_WIRED 0x1010 +#define USB_PRODUCT_RAZER_WOLVERINE_V2_PRO_XBOX_WIRELESS 0x1011 +#define USB_PRODUCT_ROG_RAIKIRI 0x1a38 +#define USB_PRODUCT_SAITEK_CYBORG_V3 0xf622 +#define USB_PRODUCT_SHANWAN_DS3 0x0523 +#define USB_PRODUCT_SONY_DS3 0x0268 +#define USB_PRODUCT_SONY_DS4 0x05c4 +#define USB_PRODUCT_SONY_DS4_DONGLE 0x0ba0 +#define USB_PRODUCT_SONY_DS4_SLIM 0x09cc +#define USB_PRODUCT_SONY_DS4_STRIKEPAD 0x05c5 +#define USB_PRODUCT_SONY_DS5 0x0ce6 +#define USB_PRODUCT_SONY_DS5_EDGE 0x0df2 +#define USB_PRODUCT_THRUSTMASTER_ESWAPX_PRO 0xd012 +#define USB_PRODUCT_TURTLE_BEACH_SERIES_X_REACT_R 0x7013 +#define USB_PRODUCT_TURTLE_BEACH_SERIES_X_RECON 0x7009 +#define USB_PRODUCT_VICTRIX_FS_PRO 0x0203 +#define USB_PRODUCT_VICTRIX_FS_PRO_V2 0x0207 +#define USB_PRODUCT_XBOX360_XUSB_CONTROLLER 0x02a1 /* XUSB driver software PID */ +#define USB_PRODUCT_XBOX360_WIRED_CONTROLLER 0x028e +#define USB_PRODUCT_XBOX360_WIRELESS_RECEIVER 0x0719 +#define USB_PRODUCT_XBOX_ONE_ADAPTIVE 0x0b0a +#define USB_PRODUCT_XBOX_ONE_ADAPTIVE_BLUETOOTH 0x0b0c +#define USB_PRODUCT_XBOX_ONE_ADAPTIVE_BLE 0x0b21 +#define USB_PRODUCT_XBOX_ONE_ELITE_SERIES_1 0x02e3 +#define USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2 0x0b00 +#define USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2_BLUETOOTH 0x0b05 +#define USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2_BLE 0x0b22 +#define USB_PRODUCT_XBOX_ONE_S 0x02ea +#define USB_PRODUCT_XBOX_ONE_S_REV1_BLUETOOTH 0x02e0 +#define USB_PRODUCT_XBOX_ONE_S_REV2_BLUETOOTH 0x02fd +#define USB_PRODUCT_XBOX_ONE_S_REV2_BLE 0x0b20 +#define USB_PRODUCT_XBOX_SERIES_X 0x0b12 +#define USB_PRODUCT_XBOX_SERIES_X_BLE 0x0b13 +#define USB_PRODUCT_XBOX_SERIES_X_VICTRIX_GAMBIT 0x02d6 +#define USB_PRODUCT_XBOX_SERIES_X_PDP_BLUE 0x02d9 +#define USB_PRODUCT_XBOX_SERIES_X_PDP_AFTERGLOW 0x02da +#define USB_PRODUCT_XBOX_SERIES_X_POWERA_FUSION_PRO2 0x4001 +#define USB_PRODUCT_XBOX_SERIES_X_POWERA_SPECTRA 0x4002 +#define USB_PRODUCT_XBOX_ONE_XBOXGIP_CONTROLLER 0x02ff /* XBOXGIP driver software PID */ +#define USB_PRODUCT_STEAM_VIRTUAL_GAMEPAD 0x11ff + +/* USB usage pages */ +#define USB_USAGEPAGE_GENERIC_DESKTOP 0x0001 +#define USB_USAGEPAGE_BUTTON 0x0009 + +/* USB usages for USAGE_PAGE_GENERIC_DESKTOP */ +#define USB_USAGE_GENERIC_POINTER 0x0001 +#define USB_USAGE_GENERIC_MOUSE 0x0002 +#define USB_USAGE_GENERIC_JOYSTICK 0x0004 +#define USB_USAGE_GENERIC_GAMEPAD 0x0005 +#define USB_USAGE_GENERIC_KEYBOARD 0x0006 +#define USB_USAGE_GENERIC_KEYPAD 0x0007 +#define USB_USAGE_GENERIC_MULTIAXISCONTROLLER 0x0008 +#define USB_USAGE_GENERIC_X 0x0030 +#define USB_USAGE_GENERIC_Y 0x0031 +#define USB_USAGE_GENERIC_Z 0x0032 +#define USB_USAGE_GENERIC_RX 0x0033 +#define USB_USAGE_GENERIC_RY 0x0034 +#define USB_USAGE_GENERIC_RZ 0x0035 +#define USB_USAGE_GENERIC_SLIDER 0x0036 +#define USB_USAGE_GENERIC_DIAL 0x0037 +#define USB_USAGE_GENERIC_WHEEL 0x0038 +#define USB_USAGE_GENERIC_HAT 0x0039 + +/* Bluetooth SIG assigned Company Identifiers + https://www.bluetooth.com/specifications/assigned-numbers/company-identifiers/ */ +#define BLUETOOTH_VENDOR_AMAZON 0x0171 + +#define BLUETOOTH_PRODUCT_LUNA_CONTROLLER 0x0419 + +#endif /* usb_ids_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/joystick/virtual/SDL_virtualjoystick.c b/SDL2-2.30.5/src/joystick/virtual/SDL_virtualjoystick.c new file mode 100644 index 0000000..e5e9b38 --- /dev/null +++ b/SDL2-2.30.5/src/joystick/virtual/SDL_virtualjoystick.c @@ -0,0 +1,750 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_JOYSTICK_VIRTUAL + +/* This is the virtual implementation of the SDL joystick API */ + +#include "SDL_endian.h" +#include "SDL_virtualjoystick_c.h" +#include "../SDL_sysjoystick.h" +#include "../SDL_joystick_c.h" + +static joystick_hwdata *g_VJoys SDL_GUARDED_BY(SDL_joystick_lock) = NULL; + +static joystick_hwdata *VIRTUAL_HWDataForIndex(int device_index) +{ + joystick_hwdata *vjoy; + + SDL_AssertJoysticksLocked(); + + for (vjoy = g_VJoys; vjoy; vjoy = vjoy->next) { + if (device_index == 0) { + break; + } + --device_index; + } + return vjoy; +} + +static void VIRTUAL_FreeHWData(joystick_hwdata *hwdata) +{ + joystick_hwdata *cur; + joystick_hwdata *prev = NULL; + + SDL_AssertJoysticksLocked(); + + if (!hwdata) { + return; + } + + /* Remove hwdata from SDL-global list */ + for (cur = g_VJoys; cur; prev = cur, cur = cur->next) { + if (hwdata == cur) { + if (prev) { + prev->next = cur->next; + } else { + g_VJoys = cur->next; + } + break; + } + } + + if (hwdata->joystick) { + hwdata->joystick->hwdata = NULL; + hwdata->joystick = NULL; + } + if (hwdata->name) { + SDL_free(hwdata->name); + hwdata->name = NULL; + } + if (hwdata->axes) { + SDL_free((void *)hwdata->axes); + hwdata->axes = NULL; + } + if (hwdata->buttons) { + SDL_free((void *)hwdata->buttons); + hwdata->buttons = NULL; + } + if (hwdata->hats) { + SDL_free(hwdata->hats); + hwdata->hats = NULL; + } + SDL_free(hwdata); +} + +int SDL_JoystickAttachVirtualInner(const SDL_VirtualJoystickDesc *desc) +{ + joystick_hwdata *hwdata = NULL; + int device_index = -1; + const char *name = NULL; + int axis_triggerleft = -1; + int axis_triggerright = -1; + + SDL_AssertJoysticksLocked(); + + if (!desc) { + return SDL_InvalidParamError("desc"); + } + if (desc->version != SDL_VIRTUAL_JOYSTICK_DESC_VERSION) { + /* Is this an old version that we can support? */ + return SDL_SetError("Unsupported virtual joystick description version %d", desc->version); + } + + hwdata = SDL_calloc(1, sizeof(joystick_hwdata)); + if (!hwdata) { + VIRTUAL_FreeHWData(hwdata); + return SDL_OutOfMemory(); + } + SDL_memcpy(&hwdata->desc, desc, sizeof(*desc)); + + if (hwdata->desc.name) { + name = hwdata->desc.name; + } else { + switch (hwdata->desc.type) { + case SDL_JOYSTICK_TYPE_GAMECONTROLLER: + name = "Virtual Controller"; + break; + case SDL_JOYSTICK_TYPE_WHEEL: + name = "Virtual Wheel"; + break; + case SDL_JOYSTICK_TYPE_ARCADE_STICK: + name = "Virtual Arcade Stick"; + break; + case SDL_JOYSTICK_TYPE_FLIGHT_STICK: + name = "Virtual Flight Stick"; + break; + case SDL_JOYSTICK_TYPE_DANCE_PAD: + name = "Virtual Dance Pad"; + break; + case SDL_JOYSTICK_TYPE_GUITAR: + name = "Virtual Guitar"; + break; + case SDL_JOYSTICK_TYPE_DRUM_KIT: + name = "Virtual Drum Kit"; + break; + case SDL_JOYSTICK_TYPE_ARCADE_PAD: + name = "Virtual Arcade Pad"; + break; + case SDL_JOYSTICK_TYPE_THROTTLE: + name = "Virtual Throttle"; + break; + default: + name = "Virtual Joystick"; + break; + } + } + hwdata->name = SDL_strdup(name); + + if (hwdata->desc.type == SDL_JOYSTICK_TYPE_GAMECONTROLLER) { + int i, axis; + + if (hwdata->desc.button_mask == 0) { + for (i = 0; i < hwdata->desc.nbuttons && i < sizeof(hwdata->desc.button_mask) * 8; ++i) { + hwdata->desc.button_mask |= (1 << i); + } + } + + if (hwdata->desc.axis_mask == 0) { + if (hwdata->desc.naxes >= 2) { + hwdata->desc.axis_mask |= ((1 << SDL_CONTROLLER_AXIS_LEFTX) | (1 << SDL_CONTROLLER_AXIS_LEFTY)); + } + if (hwdata->desc.naxes >= 4) { + hwdata->desc.axis_mask |= ((1 << SDL_CONTROLLER_AXIS_RIGHTX) | (1 << SDL_CONTROLLER_AXIS_RIGHTY)); + } + if (hwdata->desc.naxes >= 6) { + hwdata->desc.axis_mask |= ((1 << SDL_CONTROLLER_AXIS_TRIGGERLEFT) | (1 << SDL_CONTROLLER_AXIS_TRIGGERRIGHT)); + } + } + + /* Find the trigger axes */ + axis = 0; + for (i = 0; axis < hwdata->desc.naxes && i < SDL_CONTROLLER_AXIS_MAX; ++i) { + if (hwdata->desc.axis_mask & (1 << i)) { + if (i == SDL_CONTROLLER_AXIS_TRIGGERLEFT) { + axis_triggerleft = axis; + } + if (i == SDL_CONTROLLER_AXIS_TRIGGERRIGHT) { + axis_triggerright = axis; + } + ++axis; + } + } + } + + hwdata->guid = SDL_CreateJoystickGUID(SDL_HARDWARE_BUS_VIRTUAL, hwdata->desc.vendor_id, hwdata->desc.product_id, 0, NULL, name, 'v', (Uint8)hwdata->desc.type); + + /* Allocate fields for different control-types */ + if (hwdata->desc.naxes > 0) { + hwdata->axes = SDL_calloc(hwdata->desc.naxes, sizeof(Sint16)); + if (!hwdata->axes) { + VIRTUAL_FreeHWData(hwdata); + return SDL_OutOfMemory(); + } + + /* Trigger axes are at minimum value at rest */ + if (axis_triggerleft >= 0) { + hwdata->axes[axis_triggerleft] = SDL_JOYSTICK_AXIS_MIN; + } + if (axis_triggerright >= 0) { + hwdata->axes[axis_triggerright] = SDL_JOYSTICK_AXIS_MIN; + } + } + if (hwdata->desc.nbuttons > 0) { + hwdata->buttons = SDL_calloc(hwdata->desc.nbuttons, sizeof(Uint8)); + if (!hwdata->buttons) { + VIRTUAL_FreeHWData(hwdata); + return SDL_OutOfMemory(); + } + } + if (hwdata->desc.nhats > 0) { + hwdata->hats = SDL_calloc(hwdata->desc.nhats, sizeof(Uint8)); + if (!hwdata->hats) { + VIRTUAL_FreeHWData(hwdata); + return SDL_OutOfMemory(); + } + } + + /* Allocate an instance ID for this device */ + hwdata->instance_id = SDL_GetNextJoystickInstanceID(); + + /* Add virtual joystick to SDL-global lists */ + if (g_VJoys) { + joystick_hwdata *last; + + for (last = g_VJoys; last->next; last = last->next) { + } + last->next = hwdata; + } else { + g_VJoys = hwdata; + } + SDL_PrivateJoystickAdded(hwdata->instance_id); + + /* Return the new virtual-device's index */ + device_index = SDL_JoystickGetDeviceIndexFromInstanceID(hwdata->instance_id); + return device_index; +} + +int SDL_JoystickDetachVirtualInner(int device_index) +{ + SDL_JoystickID instance_id; + joystick_hwdata *hwdata = VIRTUAL_HWDataForIndex(device_index); + if (!hwdata) { + return SDL_SetError("Virtual joystick data not found"); + } + instance_id = hwdata->instance_id; + VIRTUAL_FreeHWData(hwdata); + SDL_PrivateJoystickRemoved(instance_id); + return 0; +} + +int SDL_JoystickSetVirtualAxisInner(SDL_Joystick *joystick, int axis, Sint16 value) +{ + joystick_hwdata *hwdata; + + SDL_LockJoysticks(); + + if (!joystick || !joystick->hwdata) { + SDL_UnlockJoysticks(); + return SDL_SetError("Invalid joystick"); + } + + hwdata = (joystick_hwdata *)joystick->hwdata; + if (axis < 0 || axis >= hwdata->desc.naxes) { + SDL_UnlockJoysticks(); + return SDL_SetError("Invalid axis index"); + } + + hwdata->axes[axis] = value; + + SDL_UnlockJoysticks(); + return 0; +} + +int SDL_JoystickSetVirtualButtonInner(SDL_Joystick *joystick, int button, Uint8 value) +{ + joystick_hwdata *hwdata; + + SDL_LockJoysticks(); + + if (!joystick || !joystick->hwdata) { + SDL_UnlockJoysticks(); + return SDL_SetError("Invalid joystick"); + } + + hwdata = (joystick_hwdata *)joystick->hwdata; + if (button < 0 || button >= hwdata->desc.nbuttons) { + SDL_UnlockJoysticks(); + return SDL_SetError("Invalid button index"); + } + + hwdata->buttons[button] = value; + + SDL_UnlockJoysticks(); + return 0; +} + +int SDL_JoystickSetVirtualHatInner(SDL_Joystick *joystick, int hat, Uint8 value) +{ + joystick_hwdata *hwdata; + + SDL_LockJoysticks(); + + if (!joystick || !joystick->hwdata) { + SDL_UnlockJoysticks(); + return SDL_SetError("Invalid joystick"); + } + + hwdata = (joystick_hwdata *)joystick->hwdata; + if (hat < 0 || hat >= hwdata->desc.nhats) { + SDL_UnlockJoysticks(); + return SDL_SetError("Invalid hat index"); + } + + hwdata->hats[hat] = value; + + SDL_UnlockJoysticks(); + return 0; +} + +static int VIRTUAL_JoystickInit(void) +{ + return 0; +} + +static int VIRTUAL_JoystickGetCount(void) +{ + joystick_hwdata *cur; + int count = 0; + + SDL_AssertJoysticksLocked(); + + for (cur = g_VJoys; cur; cur = cur->next) { + ++count; + } + return count; +} + +static void VIRTUAL_JoystickDetect(void) +{ +} + +static const char *VIRTUAL_JoystickGetDeviceName(int device_index) +{ + joystick_hwdata *hwdata = VIRTUAL_HWDataForIndex(device_index); + if (!hwdata) { + return NULL; + } + return hwdata->name; +} + +static const char *VIRTUAL_JoystickGetDevicePath(int device_index) +{ + return NULL; +} + +static int VIRTUAL_JoystickGetDeviceSteamVirtualGamepadSlot(int device_index) +{ + return -1; +} + +static int VIRTUAL_JoystickGetDevicePlayerIndex(int device_index) +{ + return -1; +} + +static void VIRTUAL_JoystickSetDevicePlayerIndex(int device_index, int player_index) +{ + joystick_hwdata *hwdata = VIRTUAL_HWDataForIndex(device_index); + + if (hwdata && hwdata->desc.SetPlayerIndex) { + hwdata->desc.SetPlayerIndex(hwdata->desc.userdata, player_index); + } +} + +static SDL_JoystickGUID VIRTUAL_JoystickGetDeviceGUID(int device_index) +{ + joystick_hwdata *hwdata = VIRTUAL_HWDataForIndex(device_index); + if (!hwdata) { + SDL_JoystickGUID guid; + SDL_zero(guid); + return guid; + } + return hwdata->guid; +} + +static SDL_JoystickID VIRTUAL_JoystickGetDeviceInstanceID(int device_index) +{ + joystick_hwdata *hwdata = VIRTUAL_HWDataForIndex(device_index); + if (!hwdata) { + return -1; + } + return hwdata->instance_id; +} + +static int VIRTUAL_JoystickOpen(SDL_Joystick *joystick, int device_index) +{ + joystick_hwdata *hwdata; + + SDL_AssertJoysticksLocked(); + + hwdata = VIRTUAL_HWDataForIndex(device_index); + if (!hwdata) { + return SDL_SetError("No such device"); + } + joystick->instance_id = hwdata->instance_id; + joystick->hwdata = hwdata; + joystick->naxes = hwdata->desc.naxes; + joystick->nbuttons = hwdata->desc.nbuttons; + joystick->nhats = hwdata->desc.nhats; + hwdata->joystick = joystick; + return 0; +} + +static int VIRTUAL_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ + int result; + + SDL_AssertJoysticksLocked(); + + if (joystick->hwdata) { + joystick_hwdata *hwdata = joystick->hwdata; + if (hwdata->desc.Rumble) { + result = hwdata->desc.Rumble(hwdata->desc.userdata, low_frequency_rumble, high_frequency_rumble); + } else { + result = SDL_Unsupported(); + } + } else { + result = SDL_SetError("Rumble failed, device disconnected"); + } + + return result; +} + +static int VIRTUAL_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) +{ + int result; + + SDL_AssertJoysticksLocked(); + + if (joystick->hwdata) { + joystick_hwdata *hwdata = joystick->hwdata; + if (hwdata->desc.RumbleTriggers) { + result = hwdata->desc.RumbleTriggers(hwdata->desc.userdata, left_rumble, right_rumble); + } else { + result = SDL_Unsupported(); + } + } else { + result = SDL_SetError("Rumble failed, device disconnected"); + } + + return result; +} + +static Uint32 VIRTUAL_JoystickGetCapabilities(SDL_Joystick *joystick) +{ + joystick_hwdata *hwdata; + Uint32 caps = 0; + + SDL_AssertJoysticksLocked(); + + hwdata = joystick->hwdata; + if (hwdata) { + if (hwdata->desc.Rumble) { + caps |= SDL_JOYCAP_RUMBLE; + } + if (hwdata->desc.RumbleTriggers) { + caps |= SDL_JOYCAP_RUMBLE_TRIGGERS; + } + if (hwdata->desc.SetLED) { + caps |= SDL_JOYCAP_LED; + } + } + return caps; +} + +static int VIRTUAL_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + int result; + + SDL_AssertJoysticksLocked(); + + if (joystick->hwdata) { + joystick_hwdata *hwdata = joystick->hwdata; + if (hwdata->desc.SetLED) { + result = hwdata->desc.SetLED(hwdata->desc.userdata, red, green, blue); + } else { + result = SDL_Unsupported(); + } + } else { + result = SDL_SetError("SetLED failed, device disconnected"); + } + + return result; +} + +static int VIRTUAL_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) +{ + int result; + + SDL_AssertJoysticksLocked(); + + if (joystick->hwdata) { + joystick_hwdata *hwdata = joystick->hwdata; + if (hwdata->desc.SendEffect) { + result = hwdata->desc.SendEffect(hwdata->desc.userdata, data, size); + } else { + result = SDL_Unsupported(); + } + } else { + result = SDL_SetError("SendEffect failed, device disconnected"); + } + + return result; +} + +static int VIRTUAL_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled) +{ + return SDL_Unsupported(); +} + +static void VIRTUAL_JoystickUpdate(SDL_Joystick *joystick) +{ + joystick_hwdata *hwdata; + int i; + + SDL_AssertJoysticksLocked(); + + if (!joystick) { + return; + } + if (!joystick->hwdata) { + return; + } + + hwdata = (joystick_hwdata *)joystick->hwdata; + + if (hwdata->desc.Update) { + hwdata->desc.Update(hwdata->desc.userdata); + } + + for (i = 0; i < hwdata->desc.naxes; ++i) { + SDL_PrivateJoystickAxis(joystick, i, hwdata->axes[i]); + } + for (i = 0; i < hwdata->desc.nbuttons; ++i) { + SDL_PrivateJoystickButton(joystick, i, hwdata->buttons[i]); + } + for (i = 0; i < hwdata->desc.nhats; ++i) { + SDL_PrivateJoystickHat(joystick, i, hwdata->hats[i]); + } +} + +static void VIRTUAL_JoystickClose(SDL_Joystick *joystick) +{ + SDL_AssertJoysticksLocked(); + + if (joystick->hwdata) { + joystick_hwdata *hwdata = joystick->hwdata; + hwdata->joystick = NULL; + joystick->hwdata = NULL; + } +} + +static void VIRTUAL_JoystickQuit(void) +{ + SDL_AssertJoysticksLocked(); + + while (g_VJoys) { + VIRTUAL_FreeHWData(g_VJoys); + } +} + +static SDL_bool VIRTUAL_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) +{ + joystick_hwdata *hwdata = VIRTUAL_HWDataForIndex(device_index); + int current_button = 0; + int current_axis = 0; + + if (hwdata->desc.type != SDL_JOYSTICK_TYPE_GAMECONTROLLER) { + return SDL_FALSE; + } + + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_A))) { + out->a.kind = EMappingKind_Button; + out->a.target = current_button++; + } + + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_B))) { + out->b.kind = EMappingKind_Button; + out->b.target = current_button++; + } + + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_X))) { + out->x.kind = EMappingKind_Button; + out->x.target = current_button++; + } + + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_Y))) { + out->y.kind = EMappingKind_Button; + out->y.target = current_button++; + } + + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_BACK))) { + out->back.kind = EMappingKind_Button; + out->back.target = current_button++; + } + + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_GUIDE))) { + out->guide.kind = EMappingKind_Button; + out->guide.target = current_button++; + } + + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_START))) { + out->start.kind = EMappingKind_Button; + out->start.target = current_button++; + } + + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_LEFTSTICK))) { + out->leftstick.kind = EMappingKind_Button; + out->leftstick.target = current_button++; + } + + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_RIGHTSTICK))) { + out->rightstick.kind = EMappingKind_Button; + out->rightstick.target = current_button++; + } + + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_LEFTSHOULDER))) { + out->leftshoulder.kind = EMappingKind_Button; + out->leftshoulder.target = current_button++; + } + + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_RIGHTSHOULDER))) { + out->rightshoulder.kind = EMappingKind_Button; + out->rightshoulder.target = current_button++; + } + + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_DPAD_UP))) { + out->dpup.kind = EMappingKind_Button; + out->dpup.target = current_button++; + } + + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_DPAD_DOWN))) { + out->dpdown.kind = EMappingKind_Button; + out->dpdown.target = current_button++; + } + + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_DPAD_LEFT))) { + out->dpleft.kind = EMappingKind_Button; + out->dpleft.target = current_button++; + } + + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_DPAD_RIGHT))) { + out->dpright.kind = EMappingKind_Button; + out->dpright.target = current_button++; + } + + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_MISC1))) { + out->misc1.kind = EMappingKind_Button; + out->misc1.target = current_button++; + } + + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_PADDLE1))) { + out->paddle1.kind = EMappingKind_Button; + out->paddle1.target = current_button++; + } + + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_PADDLE2))) { + out->paddle2.kind = EMappingKind_Button; + out->paddle2.target = current_button++; + } + + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_PADDLE3))) { + out->paddle3.kind = EMappingKind_Button; + out->paddle3.target = current_button++; + } + + if (current_button < hwdata->desc.nbuttons && (hwdata->desc.button_mask & (1 << SDL_CONTROLLER_BUTTON_PADDLE4))) { + out->paddle4.kind = EMappingKind_Button; + out->paddle4.target = current_button++; + } + + if (current_axis < hwdata->desc.naxes && (hwdata->desc.axis_mask & (1 << SDL_CONTROLLER_AXIS_LEFTX))) { + out->leftx.kind = EMappingKind_Axis; + out->leftx.target = current_axis++; + } + + if (current_axis < hwdata->desc.naxes && (hwdata->desc.axis_mask & (1 << SDL_CONTROLLER_AXIS_LEFTY))) { + out->lefty.kind = EMappingKind_Axis; + out->lefty.target = current_axis++; + } + + if (current_axis < hwdata->desc.naxes && (hwdata->desc.axis_mask & (1 << SDL_CONTROLLER_AXIS_RIGHTX))) { + out->rightx.kind = EMappingKind_Axis; + out->rightx.target = current_axis++; + } + + if (current_axis < hwdata->desc.naxes && (hwdata->desc.axis_mask & (1 << SDL_CONTROLLER_AXIS_RIGHTY))) { + out->righty.kind = EMappingKind_Axis; + out->righty.target = current_axis++; + } + + if (current_axis < hwdata->desc.naxes && (hwdata->desc.axis_mask & (1 << SDL_CONTROLLER_AXIS_TRIGGERLEFT))) { + out->lefttrigger.kind = EMappingKind_Axis; + out->lefttrigger.target = current_axis++; + } + + if (current_axis < hwdata->desc.naxes && (hwdata->desc.axis_mask & (1 << SDL_CONTROLLER_AXIS_TRIGGERRIGHT))) { + out->righttrigger.kind = EMappingKind_Axis; + out->righttrigger.target = current_axis++; + } + + return SDL_TRUE; +} + +SDL_JoystickDriver SDL_VIRTUAL_JoystickDriver = { + VIRTUAL_JoystickInit, + VIRTUAL_JoystickGetCount, + VIRTUAL_JoystickDetect, + VIRTUAL_JoystickGetDeviceName, + VIRTUAL_JoystickGetDevicePath, + VIRTUAL_JoystickGetDeviceSteamVirtualGamepadSlot, + VIRTUAL_JoystickGetDevicePlayerIndex, + VIRTUAL_JoystickSetDevicePlayerIndex, + VIRTUAL_JoystickGetDeviceGUID, + VIRTUAL_JoystickGetDeviceInstanceID, + VIRTUAL_JoystickOpen, + VIRTUAL_JoystickRumble, + VIRTUAL_JoystickRumbleTriggers, + VIRTUAL_JoystickGetCapabilities, + VIRTUAL_JoystickSetLED, + VIRTUAL_JoystickSendEffect, + VIRTUAL_JoystickSetSensorsEnabled, + VIRTUAL_JoystickUpdate, + VIRTUAL_JoystickClose, + VIRTUAL_JoystickQuit, + VIRTUAL_JoystickGetGamepadMapping +}; + +#endif /* SDL_JOYSTICK_VIRTUAL */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/joystick/virtual/SDL_virtualjoystick_c.h b/SDL2-2.30.5/src/joystick/virtual/SDL_virtualjoystick_c.h new file mode 100644 index 0000000..10c5cff --- /dev/null +++ b/SDL2-2.30.5/src/joystick/virtual/SDL_virtualjoystick_c.h @@ -0,0 +1,60 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifndef SDL_VIRTUALJOYSTICK_C_H +#define SDL_VIRTUALJOYSTICK_C_H + +#ifdef SDL_JOYSTICK_VIRTUAL + +#include "SDL_joystick.h" + +/** + * Data for a virtual, software-only joystick. + */ +typedef struct joystick_hwdata +{ + SDL_JoystickType type; + SDL_bool attached; + char *name; + SDL_JoystickGUID guid; + SDL_VirtualJoystickDesc desc; + Sint16 *axes; + Uint8 *buttons; + Uint8 *hats; + SDL_JoystickID instance_id; + SDL_Joystick *joystick; + + struct joystick_hwdata *next; +} joystick_hwdata; + +int SDL_JoystickAttachVirtualInner(const SDL_VirtualJoystickDesc *desc); +int SDL_JoystickDetachVirtualInner(int device_index); + +int SDL_JoystickSetVirtualAxisInner(SDL_Joystick *joystick, int axis, Sint16 value); +int SDL_JoystickSetVirtualButtonInner(SDL_Joystick *joystick, int button, Uint8 value); +int SDL_JoystickSetVirtualHatInner(SDL_Joystick *joystick, int hat, Uint8 value); + +#endif /* SDL_JOYSTICK_VIRTUAL */ + +#endif /* SDL_VIRTUALJOYSTICK_C_H */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/joystick/vita/SDL_sysjoystick.c b/SDL2-2.30.5/src/joystick/vita/SDL_sysjoystick.c new file mode 100644 index 0000000..9da62c2 --- /dev/null +++ b/SDL2-2.30.5/src/joystick/vita/SDL_sysjoystick.c @@ -0,0 +1,409 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_JOYSTICK_VITA + +/* This is the PSVita implementation of the SDL joystick API */ +#include +#include +#include + +#include /* For the definition of NULL */ +#include + +#include "../SDL_sysjoystick.h" +#include "../SDL_joystick_c.h" + +#include "SDL_events.h" +#include "SDL_error.h" +#include "SDL_thread.h" +#include "SDL_mutex.h" +#include "SDL_timer.h" + +/* Current pad state */ +static SceCtrlData pad0 = { .lx = 0, .ly = 0, .rx = 0, .ry = 0, .lt = 0, .rt = 0, .buttons = 0 }; +static SceCtrlData pad1 = { .lx = 0, .ly = 0, .rx = 0, .ry = 0, .lt = 0, .rt = 0, .buttons = 0 }; +static SceCtrlData pad2 = { .lx = 0, .ly = 0, .rx = 0, .ry = 0, .lt = 0, .rt = 0, .buttons = 0 }; +static SceCtrlData pad3 = { .lx = 0, .ly = 0, .rx = 0, .ry = 0, .lt = 0, .rt = 0, .buttons = 0 }; + +static int ext_port_map[4] = { 1, 2, 3, 4 }; // index: SDL joy number, entry: Vita port number. For external controllers + +static int SDL_numjoysticks = 1; + +static const unsigned int ext_button_map[] = { + SCE_CTRL_TRIANGLE, + SCE_CTRL_CIRCLE, + SCE_CTRL_CROSS, + SCE_CTRL_SQUARE, + SCE_CTRL_L1, + SCE_CTRL_R1, + SCE_CTRL_DOWN, + SCE_CTRL_LEFT, + SCE_CTRL_UP, + SCE_CTRL_RIGHT, + SCE_CTRL_SELECT, + SCE_CTRL_START, + SCE_CTRL_L2, + SCE_CTRL_R2, + SCE_CTRL_L3, + SCE_CTRL_R3 +}; + +static int analog_map[256]; /* Map analog inputs to -32768 -> 32767 */ + +typedef struct +{ + int x; + int y; +} point; + +/* 4 points define the bezier-curve. */ +/* The Vita has a good amount of analog travel, so use a linear curve */ +static point a = { 0, 0 }; +static point b = { 0, 0 }; +static point c = { 128, 32767 }; +static point d = { 128, 32767 }; + +/* simple linear interpolation between two points */ +static SDL_INLINE void lerp(point *dest, point *first, point *second, float t) +{ + dest->x = first->x + (second->x - first->x) * t; + dest->y = first->y + (second->y - first->y) * t; +} + +/* evaluate a point on a bezier-curve. t goes from 0 to 1.0 */ +static int calc_bezier_y(float t) +{ + point ab, bc, cd, abbc, bccd, dest; + lerp(&ab, &a, &b, t); /* point between a and b */ + lerp(&bc, &b, &c, t); /* point between b and c */ + lerp(&cd, &c, &d, t); /* point between c and d */ + lerp(&abbc, &ab, &bc, t); /* point between ab and bc */ + lerp(&bccd, &bc, &cd, t); /* point between bc and cd */ + lerp(&dest, &abbc, &bccd, t); /* point on the bezier-curve */ + return dest.y; +} + +/* Function to scan the system for joysticks. + * Joystick 0 should be the system default joystick. + * It should return number of joysticks, or -1 on an unrecoverable fatal error. + */ +int VITA_JoystickInit(void) +{ + int i; + SceCtrlPortInfo myPortInfo; + + /* Setup input */ + sceCtrlSetSamplingMode(SCE_CTRL_MODE_ANALOG_WIDE); + sceCtrlSetSamplingModeExt(SCE_CTRL_MODE_ANALOG_WIDE); + + /* Create an accurate map from analog inputs (0 to 255) + to SDL joystick positions (-32768 to 32767) */ + for (i = 0; i < 128; i++) { + float t = (float)i / 127.0f; + analog_map[i + 128] = calc_bezier_y(t); + analog_map[127 - i] = -1 * analog_map[i + 128]; + } + + // Assume we have at least one controller, even when nothing is paired + // This way the user can jump in, pair a controller + // and control things immediately even if it is paired + // after the app has already started. + + SDL_numjoysticks = 1; + SDL_PrivateJoystickAdded(0); + // How many additional paired controllers are there? + sceCtrlGetControllerPortInfo(&myPortInfo); + + // On Vita TV, port 0 and 1 are the same controller + // and that is the first one, so start at port 2 + for (i = 2; i <= 4; i++) { + if (myPortInfo.port[i] != SCE_CTRL_TYPE_UNPAIRED) { + SDL_PrivateJoystickAdded(SDL_numjoysticks); + SDL_numjoysticks++; + } + } + return SDL_numjoysticks; +} + +int VITA_JoystickGetCount() +{ + return SDL_numjoysticks; +} + +void VITA_JoystickDetect() +{ +} + +/* Function to perform the mapping from device index to the instance id for this index */ +SDL_JoystickID VITA_JoystickGetDeviceInstanceID(int device_index) +{ + return device_index; +} + +const char *VITA_JoystickGetDeviceName(int index) +{ + if (index == 0) { + return "PSVita Controller"; + } + + if (index == 1) { + return "PSVita Controller"; + } + + if (index == 2) { + return "PSVita Controller"; + } + + if (index == 3) { + return "PSVita Controller"; + } + + SDL_SetError("No joystick available with that index"); + return NULL; +} + +const char *VITA_JoystickGetDevicePath(int index) +{ + return NULL; +} + +static int VITA_JoystickGetDeviceSteamVirtualGamepadSlot(int device_index) +{ + return -1; +} + +static int VITA_JoystickGetDevicePlayerIndex(int device_index) +{ + return -1; +} + +static void VITA_JoystickSetDevicePlayerIndex(int device_index, int player_index) +{ +} + +/* Function to open a joystick for use. + The joystick to open is specified by the device index. + This should fill the nbuttons and naxes fields of the joystick structure. + It returns 0, or -1 if there is an error. + */ +int VITA_JoystickOpen(SDL_Joystick *joystick, int device_index) +{ + joystick->nbuttons = SDL_arraysize(ext_button_map); + joystick->naxes = 6; + joystick->nhats = 0; + joystick->instance_id = device_index; + + return 0; +} + +/* Function to update the state of a joystick - called as a device poll. + * This function shouldn't update the joystick structure directly, + * but instead should call SDL_PrivateJoystick*() to deliver events + * and update joystick device state. + */ +static void VITA_JoystickUpdate(SDL_Joystick *joystick) +{ + int i; + unsigned int buttons; + unsigned int changed; + unsigned char lx, ly, rx, ry, lt, rt; + static unsigned int old_buttons[] = { 0, 0, 0, 0 }; + static unsigned char old_lx[] = { 0, 0, 0, 0 }; + static unsigned char old_ly[] = { 0, 0, 0, 0 }; + static unsigned char old_rx[] = { 0, 0, 0, 0 }; + static unsigned char old_ry[] = { 0, 0, 0, 0 }; + static unsigned char old_lt[] = { 0, 0, 0, 0 }; + static unsigned char old_rt[] = { 0, 0, 0, 0 }; + SceCtrlData *pad = NULL; + + int index = (int)SDL_JoystickInstanceID(joystick); + + if (index == 0) + pad = &pad0; + else if (index == 1) + pad = &pad1; + else if (index == 2) + pad = &pad2; + else if (index == 3) + pad = &pad3; + else + return; + + if (index == 0) { + if (sceCtrlPeekBufferPositive2(ext_port_map[index], pad, 1) < 0) { + // on vita fallback to port 0 + sceCtrlPeekBufferPositive2(0, pad, 1); + } + } else { + sceCtrlPeekBufferPositive2(ext_port_map[index], pad, 1); + } + + buttons = pad->buttons; + + lx = pad->lx; + ly = pad->ly; + rx = pad->rx; + ry = pad->ry; + lt = pad->lt; + rt = pad->rt; + + // Axes + + if (old_lx[index] != lx) { + SDL_PrivateJoystickAxis(joystick, 0, analog_map[lx]); + old_lx[index] = lx; + } + if (old_ly[index] != ly) { + SDL_PrivateJoystickAxis(joystick, 1, analog_map[ly]); + old_ly[index] = ly; + } + if (old_rx[index] != rx) { + SDL_PrivateJoystickAxis(joystick, 2, analog_map[rx]); + old_rx[index] = rx; + } + if (old_ry[index] != ry) { + SDL_PrivateJoystickAxis(joystick, 3, analog_map[ry]); + old_ry[index] = ry; + } + + if (old_lt[index] != lt) { + SDL_PrivateJoystickAxis(joystick, 4, analog_map[lt]); + old_lt[index] = lt; + } + if (old_rt[index] != rt) { + SDL_PrivateJoystickAxis(joystick, 5, analog_map[rt]); + old_rt[index] = rt; + } + + // Buttons + changed = old_buttons[index] ^ buttons; + old_buttons[index] = buttons; + + if (changed) { + for (i = 0; i < SDL_arraysize(ext_button_map); i++) { + if (changed & ext_button_map[i]) { + SDL_PrivateJoystickButton( + joystick, i, + (buttons & ext_button_map[i]) ? SDL_PRESSED : SDL_RELEASED); + } + } + } +} + +/* Function to close a joystick after use */ +void VITA_JoystickClose(SDL_Joystick *joystick) +{ +} + +/* Function to perform any system-specific joystick related cleanup */ +void VITA_JoystickQuit(void) +{ +} + +SDL_JoystickGUID VITA_JoystickGetDeviceGUID(int device_index) +{ + /* the GUID is just the name for now */ + const char *name = VITA_JoystickGetDeviceName(device_index); + return SDL_CreateJoystickGUIDForName(name); +} + +static int VITA_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ + int index = (int)SDL_JoystickInstanceID(joystick); + SceCtrlActuator act; + SDL_zero(act); + + act.small = high_frequency_rumble / 256; + act.large = low_frequency_rumble / 256; + if (sceCtrlSetActuator(ext_port_map[index], &act) < 0) { + return SDL_Unsupported(); + } + return 0; +} + +static int VITA_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left, Uint16 right) +{ + return SDL_Unsupported(); +} + +static Uint32 VITA_JoystickGetCapabilities(SDL_Joystick *joystick) +{ + // always return LED and rumble supported for now + return SDL_JOYCAP_LED | SDL_JOYCAP_RUMBLE; +} + +static int VITA_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + int index = (int)SDL_JoystickInstanceID(joystick); + if (sceCtrlSetLightBar(ext_port_map[index], red, green, blue) < 0) { + return SDL_Unsupported(); + } + return 0; +} + +static int VITA_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + +static int VITA_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled) +{ + return SDL_Unsupported(); +} + +static SDL_bool VITA_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) +{ + return SDL_FALSE; +} + +SDL_JoystickDriver SDL_VITA_JoystickDriver = { + VITA_JoystickInit, + VITA_JoystickGetCount, + VITA_JoystickDetect, + VITA_JoystickGetDeviceName, + VITA_JoystickGetDevicePath, + VITA_JoystickGetDeviceSteamVirtualGamepadSlot, + VITA_JoystickGetDevicePlayerIndex, + VITA_JoystickSetDevicePlayerIndex, + VITA_JoystickGetDeviceGUID, + VITA_JoystickGetDeviceInstanceID, + + VITA_JoystickOpen, + + VITA_JoystickRumble, + VITA_JoystickRumbleTriggers, + + VITA_JoystickGetCapabilities, + VITA_JoystickSetLED, + VITA_JoystickSendEffect, + VITA_JoystickSetSensorsEnabled, + + VITA_JoystickUpdate, + VITA_JoystickClose, + VITA_JoystickQuit, + VITA_JoystickGetGamepadMapping, +}; + +#endif /* SDL_JOYSTICK_VITA */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/joystick/windows/SDL_dinputjoystick.c b/SDL2-2.30.5/src/joystick/windows/SDL_dinputjoystick.c similarity index 63% rename from SDL2-2.0.12/src/joystick/windows/SDL_dinputjoystick.c rename to SDL2-2.30.5/src/joystick/windows/SDL_dinputjoystick.c index 5c5e21e..fb46445 100644 --- a/SDL2-2.0.12/src/joystick/windows/SDL_dinputjoystick.c +++ b/SDL2-2.30.5/src/joystick/windows/SDL_dinputjoystick.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -22,41 +22,46 @@ #include "../SDL_sysjoystick.h" -#if SDL_JOYSTICK_DINPUT +#ifdef SDL_JOYSTICK_DINPUT +#include "SDL_hints.h" +#include "SDL_timer.h" #include "SDL_windowsjoystick_c.h" #include "SDL_dinputjoystick_c.h" +#include "SDL_rawinputjoystick_c.h" #include "SDL_xinputjoystick_c.h" #include "../hidapi/SDL_hidapijoystick_c.h" #ifndef DIDFT_OPTIONAL -#define DIDFT_OPTIONAL 0x80000000 +#define DIDFT_OPTIONAL 0x80000000 #endif -#define INPUT_QSIZE 32 /* Buffer up to 32 input messages */ -#define JOY_AXIS_THRESHOLD (((SDL_JOYSTICK_AXIS_MAX)-(SDL_JOYSTICK_AXIS_MIN))/100) /* 1% motion */ +#define INPUT_QSIZE 128 /* Buffer up to 128 input messages */ +#define JOY_AXIS_THRESHOLD (((SDL_JOYSTICK_AXIS_MAX) - (SDL_JOYSTICK_AXIS_MIN)) / 100) /* 1% motion */ -#define CONVERT_MAGNITUDE(x) (((x)*10000) / 0x7FFF) +#define CONVERT_MAGNITUDE(x) (((x)*10000) / 0x7FFF) /* external variables referenced. */ +#ifdef SDL_VIDEO_DRIVER_WINDOWS extern HWND SDL_HelperWindow; +#else +static const HWND SDL_HelperWindow = NULL; +#endif /* local variables */ static SDL_bool coinitialized = SDL_FALSE; static LPDIRECTINPUT8 dinput = NULL; -static PRAWINPUTDEVICELIST SDL_RawDevList = NULL; -static UINT SDL_RawDevListCount = 0; /* Taken from Wine - Thanks! */ static DIOBJECTDATAFORMAT dfDIJoystick2[] = { - { &GUID_XAxis, DIJOFS_X, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_YAxis, DIJOFS_Y, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_ZAxis, DIJOFS_Z, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_RxAxis, DIJOFS_RX, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_RyAxis, DIJOFS_RY, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_RzAxis, DIJOFS_RZ, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_Slider, DIJOFS_SLIDER(0), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_Slider, DIJOFS_SLIDER(1), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, + { &GUID_XAxis, DIJOFS_X, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTPOSITION }, + { &GUID_YAxis, DIJOFS_Y, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTPOSITION }, + { &GUID_ZAxis, DIJOFS_Z, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTPOSITION }, + { &GUID_RxAxis, DIJOFS_RX, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTPOSITION }, + { &GUID_RyAxis, DIJOFS_RY, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTPOSITION }, + { &GUID_RzAxis, DIJOFS_RZ, DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTPOSITION }, + { &GUID_Slider, DIJOFS_SLIDER(0), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTPOSITION }, + { &GUID_Slider, DIJOFS_SLIDER(1), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTPOSITION }, { &GUID_POV, DIJOFS_POV(0), DIDFT_OPTIONAL | DIDFT_POV | DIDFT_ANYINSTANCE, 0 }, { &GUID_POV, DIJOFS_POV(1), DIDFT_OPTIONAL | DIDFT_POV | DIDFT_ANYINSTANCE, 0 }, { &GUID_POV, DIJOFS_POV(2), DIDFT_OPTIONAL | DIDFT_POV | DIDFT_ANYINSTANCE, 0 }, @@ -189,30 +194,33 @@ static DIOBJECTDATAFORMAT dfDIJoystick2[] = { { NULL, DIJOFS_BUTTON(125), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 }, { NULL, DIJOFS_BUTTON(126), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 }, { NULL, DIJOFS_BUTTON(127), DIDFT_OPTIONAL | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0 }, - { &GUID_XAxis, FIELD_OFFSET(DIJOYSTATE2, lVX), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_YAxis, FIELD_OFFSET(DIJOYSTATE2, lVY), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_ZAxis, FIELD_OFFSET(DIJOYSTATE2, lVZ), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_RxAxis, FIELD_OFFSET(DIJOYSTATE2, lVRx), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_RyAxis, FIELD_OFFSET(DIJOYSTATE2, lVRy), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_RzAxis, FIELD_OFFSET(DIJOYSTATE2, lVRz), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_Slider, FIELD_OFFSET(DIJOYSTATE2, rglVSlider[0]), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_Slider, FIELD_OFFSET(DIJOYSTATE2, rglVSlider[1]), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_XAxis, FIELD_OFFSET(DIJOYSTATE2, lAX), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_YAxis, FIELD_OFFSET(DIJOYSTATE2, lAY), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_ZAxis, FIELD_OFFSET(DIJOYSTATE2, lAZ), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_RxAxis, FIELD_OFFSET(DIJOYSTATE2, lARx), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_RyAxis, FIELD_OFFSET(DIJOYSTATE2, lARy), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_RzAxis, FIELD_OFFSET(DIJOYSTATE2, lARz), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_Slider, FIELD_OFFSET(DIJOYSTATE2, rglASlider[0]), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_Slider, FIELD_OFFSET(DIJOYSTATE2, rglASlider[1]), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_XAxis, FIELD_OFFSET(DIJOYSTATE2, lFX), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_YAxis, FIELD_OFFSET(DIJOYSTATE2, lFY), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_ZAxis, FIELD_OFFSET(DIJOYSTATE2, lFZ), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_RxAxis, FIELD_OFFSET(DIJOYSTATE2, lFRx), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_RyAxis, FIELD_OFFSET(DIJOYSTATE2, lFRy), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_RzAxis, FIELD_OFFSET(DIJOYSTATE2, lFRz), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_Slider, FIELD_OFFSET(DIJOYSTATE2, rglFSlider[0]), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, - { &GUID_Slider, FIELD_OFFSET(DIJOYSTATE2, rglFSlider[1]), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0 }, + { &GUID_XAxis, FIELD_OFFSET(DIJOYSTATE2, lVX), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTVELOCITY }, + { &GUID_YAxis, FIELD_OFFSET(DIJOYSTATE2, lVY), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTVELOCITY }, + { &GUID_ZAxis, FIELD_OFFSET(DIJOYSTATE2, lVZ), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTVELOCITY }, + { &GUID_RxAxis, FIELD_OFFSET(DIJOYSTATE2, lVRx), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTVELOCITY }, + { &GUID_RyAxis, FIELD_OFFSET(DIJOYSTATE2, lVRy), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTVELOCITY }, + { &GUID_RzAxis, FIELD_OFFSET(DIJOYSTATE2, lVRz), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTVELOCITY }, + /* note: dwOfs value matches Windows */ + { &GUID_Slider, DIJOFS_SLIDER(0), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTVELOCITY }, + { &GUID_Slider, DIJOFS_SLIDER(1), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTVELOCITY }, + { &GUID_XAxis, FIELD_OFFSET(DIJOYSTATE2, lAX), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTACCEL }, + { &GUID_YAxis, FIELD_OFFSET(DIJOYSTATE2, lAY), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTACCEL }, + { &GUID_ZAxis, FIELD_OFFSET(DIJOYSTATE2, lAZ), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTACCEL }, + { &GUID_RxAxis, FIELD_OFFSET(DIJOYSTATE2, lARx), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTACCEL }, + { &GUID_RyAxis, FIELD_OFFSET(DIJOYSTATE2, lARy), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTACCEL }, + { &GUID_RzAxis, FIELD_OFFSET(DIJOYSTATE2, lARz), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTACCEL }, + /* note: dwOfs value matches Windows */ + { &GUID_Slider, DIJOFS_SLIDER(0), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTACCEL }, + { &GUID_Slider, DIJOFS_SLIDER(1), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTACCEL }, + { &GUID_XAxis, FIELD_OFFSET(DIJOYSTATE2, lFX), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTFORCE }, + { &GUID_YAxis, FIELD_OFFSET(DIJOYSTATE2, lFY), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTFORCE }, + { &GUID_ZAxis, FIELD_OFFSET(DIJOYSTATE2, lFZ), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTFORCE }, + { &GUID_RxAxis, FIELD_OFFSET(DIJOYSTATE2, lFRx), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTFORCE }, + { &GUID_RyAxis, FIELD_OFFSET(DIJOYSTATE2, lFRy), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTFORCE }, + { &GUID_RzAxis, FIELD_OFFSET(DIJOYSTATE2, lFRz), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTFORCE }, + /* note: dwOfs value matches Windows */ + { &GUID_Slider, DIJOFS_SLIDER(0), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTFORCE }, + { &GUID_Slider, DIJOFS_SLIDER(1), DIDFT_OPTIONAL | DIDFT_AXIS | DIDFT_ANYINSTANCE, DIDOI_ASPECTFORCE }, }; const DIDATAFORMAT SDL_c_dfDIJoystick2 = { @@ -225,202 +233,113 @@ const DIDATAFORMAT SDL_c_dfDIJoystick2 = { }; /* Convert a DirectInput return code to a text message */ -static int -SetDIerror(const char *function, HRESULT code) +static int SetDIerror(const char *function, HRESULT code) { - /* - return SDL_SetError("%s() [%s]: %s", function, - DXGetErrorString9A(code), DXGetErrorDescription9A(code)); - */ return SDL_SetError("%s() DirectX error 0x%8.8lx", function, code); } -#if 0 /* Microsoft recommended implementation, but slower than checking raw devices */ -#define COBJMACROS -#include -#include - -static const IID CLSID_WbemLocator = { 0x4590f811, 0x1d3a, 0x11d0,{ 0x89, 0x1f, 0x00, 0xaa, 0x00, 0x4b, 0x2e, 0x24 } }; -static const IID IID_IWbemLocator = { 0xdc12a687, 0x737f, 0x11cf,{ 0x88, 0x4d, 0x00, 0xaa, 0x00, 0x4b, 0x2e, 0x24 } }; - -static SDL_bool -WIN_IsXInputDevice(const GUID* pGuidProductFromDirectInput) +static SDL_bool SDL_IsXInputDevice(Uint16 vendor_id, Uint16 product_id, const char *hidPath) { - IWbemLocator* pIWbemLocator = NULL; - IEnumWbemClassObject* pEnumDevices = NULL; - IWbemClassObject* pDevices[20]; - IWbemServices* pIWbemServices = NULL; - BSTR bstrNamespace = NULL; - BSTR bstrDeviceID = NULL; - BSTR bstrClassName = NULL; - DWORD uReturned = 0; - SDL_bool bIsXinputDevice = SDL_FALSE; - UINT iDevice = 0; - VARIANT var; - HRESULT hr; +#if defined(SDL_JOYSTICK_XINPUT) || defined(SDL_JOYSTICK_RAWINPUT) + SDL_GameControllerType type; - SDL_zeroa(pDevices); - - // Create WMI - hr = CoCreateInstance(&CLSID_WbemLocator, - NULL, - CLSCTX_INPROC_SERVER, - &IID_IWbemLocator, - (LPVOID*)&pIWbemLocator); - if (FAILED(hr) || pIWbemLocator == NULL) - goto LCleanup; - - bstrNamespace = SysAllocString(L"\\\\.\\root\\cimv2"); if (bstrNamespace == NULL) goto LCleanup; - bstrClassName = SysAllocString(L"Win32_PNPEntity"); if (bstrClassName == NULL) goto LCleanup; - bstrDeviceID = SysAllocString(L"DeviceID"); if (bstrDeviceID == NULL) goto LCleanup; - - // Connect to WMI - hr = IWbemLocator_ConnectServer(pIWbemLocator, bstrNamespace, NULL, NULL, 0L, - 0L, NULL, NULL, &pIWbemServices); - if (FAILED(hr) || pIWbemServices == NULL) { - goto LCleanup; - } - - // Switch security level to IMPERSONATE. - CoSetProxyBlanket((IUnknown *)pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, - RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE); - - hr = IWbemServices_CreateInstanceEnum(pIWbemServices, bstrClassName, 0, NULL, &pEnumDevices); - if (FAILED(hr) || pEnumDevices == NULL) - goto LCleanup; - - // Loop over all devices - for (;;) { - // Get 20 at a time - hr = IEnumWbemClassObject_Next(pEnumDevices, 10000, SDL_arraysize(pDevices), pDevices, &uReturned); - if (FAILED(hr)) { - goto LCleanup; - } - if (uReturned == 0) { - break; - } - - for (iDevice = 0; iDevice < uReturned; iDevice++) { - // For each device, get its device ID - hr = IWbemClassObject_Get(pDevices[iDevice], bstrDeviceID, 0L, &var, NULL, NULL); - if (SUCCEEDED(hr) && var.vt == VT_BSTR && var.bstrVal != NULL) { - // Check if the device ID contains "IG_". If it does, then it's an XInput device - // This information can not be found from DirectInput - if (SDL_wcsstr(var.bstrVal, L"IG_")) { - char *bstrVal = WIN_StringToUTF8(var.bstrVal); - - // If it does, then get the VID/PID from var.bstrVal - DWORD dwPid = 0, dwVid = 0, dwVidPid; - const char *strVid, *strPid; - strVid = SDL_strstr(bstrVal, "VID_"); - if (strVid && SDL_sscanf(strVid, "VID_%4X", &dwVid) != 1) - dwVid = 0; - strPid = SDL_strstr(bstrVal, "PID_"); - if (strPid && SDL_sscanf(strPid, "PID_%4X", &dwPid) != 1) - dwPid = 0; - - SDL_free(bstrVal); - - // Compare the VID/PID to the DInput device - dwVidPid = MAKELONG(dwVid, dwPid); - if (dwVidPid == pGuidProductFromDirectInput->Data1) { - bIsXinputDevice = SDL_TRUE; - goto LCleanup; - } - } - } - IWbemClassObject_Release(pDevices[iDevice]); - } - } - -LCleanup: - if (bstrNamespace) { - SysFreeString(bstrNamespace); - } - if (bstrDeviceID) { - SysFreeString(bstrDeviceID); - } - if (bstrClassName) { - SysFreeString(bstrClassName); - } - for (iDevice = 0; iDevice < SDL_arraysize(pDevices); iDevice++) { - if (pDevices[iDevice]) { - IWbemClassObject_Release(pDevices[iDevice]); - } - } - if (pEnumDevices) { - IEnumWbemClassObject_Release(pEnumDevices); - } - if (pIWbemLocator) { - IWbemLocator_Release(pIWbemLocator); - } - if (pIWbemServices) { - IWbemServices_Release(pIWbemServices); - } - - return bIsXinputDevice; -} -#endif /* 0 */ - -static SDL_bool -SDL_IsXInputDevice(const GUID* pGuidProductFromDirectInput) -{ - UINT i; - - if (!SDL_XINPUT_Enabled()) { + /* XInput and RawInput backends will pick up XInput-compatible devices */ + if (!SDL_XINPUT_Enabled() +#ifdef SDL_JOYSTICK_RAWINPUT + && !RAWINPUT_IsEnabled() +#endif + ) { return SDL_FALSE; } - if (SDL_memcmp(&pGuidProductFromDirectInput->Data4[2], "PIDVID", 6) == 0) { - Uint16 vendor_id = (Uint16)LOWORD(pGuidProductFromDirectInput->Data1); - Uint16 product_id = (Uint16)HIWORD(pGuidProductFromDirectInput->Data1); - SDL_GameControllerType type = SDL_GetJoystickGameControllerType("", vendor_id, product_id, -1, 0, 0, 0); - if (type == SDL_CONTROLLER_TYPE_XBOX360 || - type == SDL_CONTROLLER_TYPE_XBOXONE || - (vendor_id == 0x28DE && product_id == 0x11FF)) { - return SDL_TRUE; - } + /* If device path contains "IG_" then its an XInput device */ + /* See: https://docs.microsoft.com/windows/win32/xinput/xinput-and-directinput */ + if (SDL_strstr(hidPath, "IG_") != NULL) { + return SDL_TRUE; } - /* Go through RAWINPUT (WinXP and later) to find HID devices. */ - /* Cache this if we end up using it. */ - if (SDL_RawDevList == NULL) { - if ((GetRawInputDeviceList(NULL, &SDL_RawDevListCount, sizeof(RAWINPUTDEVICELIST)) == -1) || (!SDL_RawDevListCount)) { - return SDL_FALSE; /* oh well. */ - } - - SDL_RawDevList = (PRAWINPUTDEVICELIST)SDL_malloc(sizeof(RAWINPUTDEVICELIST) * SDL_RawDevListCount); - if (SDL_RawDevList == NULL) { - SDL_OutOfMemory(); - return SDL_FALSE; - } - - if (GetRawInputDeviceList(SDL_RawDevList, &SDL_RawDevListCount, sizeof(RAWINPUTDEVICELIST)) == -1) { - SDL_free(SDL_RawDevList); - SDL_RawDevList = NULL; - return SDL_FALSE; /* oh well. */ - } - } - - for (i = 0; i < SDL_RawDevListCount; i++) { - RID_DEVICE_INFO rdi; - char devName[128]; - UINT rdiSize = sizeof(rdi); - UINT nameSize = SDL_arraysize(devName); - - rdi.cbSize = sizeof(rdi); - if ((SDL_RawDevList[i].dwType == RIM_TYPEHID) && - (GetRawInputDeviceInfoA(SDL_RawDevList[i].hDevice, RIDI_DEVICEINFO, &rdi, &rdiSize) != ((UINT)-1)) && - (MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) == ((LONG)pGuidProductFromDirectInput->Data1)) && - (GetRawInputDeviceInfoA(SDL_RawDevList[i].hDevice, RIDI_DEVICENAME, devName, &nameSize) != ((UINT)-1)) && - (SDL_strstr(devName, "IG_") != NULL)) { - return SDL_TRUE; - } + type = SDL_GetJoystickGameControllerTypeFromVIDPID(vendor_id, product_id, NULL, SDL_FALSE); + if (type == SDL_CONTROLLER_TYPE_XBOX360 || + type == SDL_CONTROLLER_TYPE_XBOXONE || + (vendor_id == USB_VENDOR_VALVE && product_id == USB_PRODUCT_STEAM_VIRTUAL_GAMEPAD)) { + return SDL_TRUE; } +#endif /* SDL_JOYSTICK_XINPUT || SDL_JOYSTICK_RAWINPUT */ return SDL_FALSE; } +static SDL_bool QueryDeviceName(LPDIRECTINPUTDEVICE8 device, char **device_name) +{ + DIPROPSTRING dipstr; + + if (!device || !device_name) { + return SDL_FALSE; + } + + dipstr.diph.dwSize = sizeof(dipstr); + dipstr.diph.dwHeaderSize = sizeof(dipstr.diph); + dipstr.diph.dwObj = 0; + dipstr.diph.dwHow = DIPH_DEVICE; + + if (FAILED(IDirectInputDevice8_GetProperty(device, DIPROP_PRODUCTNAME, &dipstr.diph))) { + return SDL_FALSE; + } + + *device_name = WIN_StringToUTF8(dipstr.wsz); + + return SDL_TRUE; +} + +static SDL_bool QueryDevicePath(LPDIRECTINPUTDEVICE8 device, char **device_path) +{ + DIPROPGUIDANDPATH dippath; + + if (!device || !device_path) { + return SDL_FALSE; + } + + dippath.diph.dwSize = sizeof(dippath); + dippath.diph.dwHeaderSize = sizeof(dippath.diph); + dippath.diph.dwObj = 0; + dippath.diph.dwHow = DIPH_DEVICE; + + if (FAILED(IDirectInputDevice8_GetProperty(device, DIPROP_GUIDANDPATH, &dippath.diph))) { + return SDL_FALSE; + } + + *device_path = WIN_StringToUTF8W(dippath.wszPath); + + /* Normalize path to upper case. */ + SDL_strupr(*device_path); + + return SDL_TRUE; +} + +static SDL_bool QueryDeviceInfo(LPDIRECTINPUTDEVICE8 device, Uint16 *vendor_id, Uint16 *product_id) +{ + DIPROPDWORD dipdw; + + if (!device || !vendor_id || !product_id) { + return SDL_FALSE; + } + + dipdw.diph.dwSize = sizeof(dipdw); + dipdw.diph.dwHeaderSize = sizeof(dipdw.diph); + dipdw.diph.dwObj = 0; + dipdw.diph.dwHow = DIPH_DEVICE; + dipdw.dwData = 0; + + if (FAILED(IDirectInputDevice8_GetProperty(device, DIPROP_VIDPID, &dipdw.diph))) { + return SDL_FALSE; + } + + *vendor_id = LOWORD(dipdw.dwData); + *product_id = HIWORD(dipdw.dwData); + + return SDL_TRUE; +} + void FreeRumbleEffectData(DIEFFECT *effect) { if (!effect) { @@ -476,12 +395,17 @@ DIEFFECT *CreateRumbleEffectData(Sint16 magnitude) return effect; } -int -SDL_DINPUT_JoystickInit(void) +int SDL_DINPUT_JoystickInit(void) { HRESULT result; HINSTANCE instance; + if (!SDL_GetHintBoolean(SDL_HINT_DIRECTINPUT_ENABLED, SDL_TRUE)) { + /* In some environments, IDirectInput8_Initialize / _EnumDevices can take a minute even with no controllers. */ + dinput = NULL; + return 0; + } + result = WIN_CoInitialize(); if (FAILED(result)) { return SetDIerror("CoInitialize", result); @@ -490,7 +414,7 @@ SDL_DINPUT_JoystickInit(void) coinitialized = SDL_TRUE; result = CoCreateInstance(&CLSID_DirectInput8, NULL, CLSCTX_INPROC_SERVER, - &IID_IDirectInput8, (LPVOID)&dinput); + &IID_IDirectInput8, (LPVOID *)&dinput); if (FAILED(result)) { return SetDIerror("CoCreateInstance", result); @@ -498,87 +422,63 @@ SDL_DINPUT_JoystickInit(void) /* Because we used CoCreateInstance, we need to Initialize it, first. */ instance = GetModuleHandle(NULL); - if (instance == NULL) { + if (!instance) { + IDirectInput8_Release(dinput); + dinput = NULL; return SDL_SetError("GetModuleHandle() failed with error code %lu.", GetLastError()); } result = IDirectInput8_Initialize(dinput, instance, DIRECTINPUT_VERSION); if (FAILED(result)) { + IDirectInput8_Release(dinput); + dinput = NULL; return SetDIerror("IDirectInput::Initialize", result); } return 0; } -/* helper function for direct input, gets called for each connected joystick */ -static BOOL CALLBACK -EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext) +static int GetSteamVirtualGamepadSlot(Uint16 vendor_id, Uint16 product_id, const char *device_path) { - JoyStick_DeviceData *pNewJoystick; + int slot = -1; + + if (vendor_id == USB_VENDOR_VALVE && + product_id == USB_PRODUCT_STEAM_VIRTUAL_GAMEPAD) { + (void)SDL_sscanf(device_path, "\\\\?\\HID#VID_28DE&PID_11FF&IG_0%d", &slot); + } + return slot; +} + +/* helper function for direct input, gets called for each connected joystick */ +static BOOL CALLBACK EnumJoystickDetectCallback(LPCDIDEVICEINSTANCE pDeviceInstance, LPVOID pContext) +{ +#define CHECK(expression) \ + { \ + if (!(expression)) \ + goto err; \ + } + JoyStick_DeviceData *pNewJoystick = NULL; JoyStick_DeviceData *pPrevJoystick = NULL; - const DWORD devtype = (pdidInstance->dwDevType & 0xFF); - Uint16 *guid16; Uint16 vendor = 0; Uint16 product = 0; Uint16 version = 0; - WCHAR hidPath[MAX_PATH]; - const char *name; + char *hidPath = NULL; + char *name = NULL; + LPDIRECTINPUTDEVICE8 device = NULL; - if (devtype == DI8DEVTYPE_SUPPLEMENTAL) { - /* Add any supplemental devices that should be ignored here */ -#define MAKE_TABLE_ENTRY(VID, PID) ((((DWORD)PID)<<16)|VID) - static DWORD ignored_devices[] = { - MAKE_TABLE_ENTRY(0, 0) - }; -#undef MAKE_TABLE_ENTRY - unsigned int i; + /* We are only supporting HID devices. */ + CHECK(pDeviceInstance->dwDevType & DIDEVTYPE_HID); - for (i = 0; i < SDL_arraysize(ignored_devices); ++i) { - if (pdidInstance->guidProduct.Data1 == ignored_devices[i]) { - return DIENUM_CONTINUE; - } - } - } + CHECK(SUCCEEDED(IDirectInput8_CreateDevice(dinput, &pDeviceInstance->guidInstance, &device, NULL))); + CHECK(QueryDeviceName(device, &name)); + CHECK(QueryDevicePath(device, &hidPath)); + CHECK(QueryDeviceInfo(device, &vendor, &product)); - if (SDL_IsXInputDevice(&pdidInstance->guidProduct)) { - return DIENUM_CONTINUE; /* ignore XInput devices here, keep going. */ - } - - { - HRESULT result; - LPDIRECTINPUTDEVICE8 device; - LPDIRECTINPUTDEVICE8 InputDevice; - DIPROPGUIDANDPATH dipdw2; - - result = IDirectInput8_CreateDevice(dinput, &(pdidInstance->guidInstance), &device, NULL); - if (FAILED(result)) { - return DIENUM_CONTINUE; /* better luck next time? */ - } - - /* Now get the IDirectInputDevice8 interface, instead. */ - result = IDirectInputDevice8_QueryInterface(device, &IID_IDirectInputDevice8, (LPVOID *)&InputDevice); - /* We are done with this object. Use the stored one from now on. */ - IDirectInputDevice8_Release(device); - if (FAILED(result)) { - return DIENUM_CONTINUE; /* better luck next time? */ - } - dipdw2.diph.dwSize = sizeof(dipdw2); - dipdw2.diph.dwHeaderSize = sizeof(dipdw2.diph); - dipdw2.diph.dwObj = 0; // device property - dipdw2.diph.dwHow = DIPH_DEVICE; - - result = IDirectInputDevice8_GetProperty(InputDevice, DIPROP_GUIDANDPATH, &dipdw2.diph); - IDirectInputDevice8_Release(InputDevice); - if (FAILED(result)) { - return DIENUM_CONTINUE; /* better luck next time? */ - } - - /* Get device path, compare that instead of GUID, additionally update GUIDs of joysticks with matching paths, in case they're not open yet. */ - SDL_wcslcpy(hidPath, dipdw2.wszPath, SDL_arraysize(hidPath)); - } + CHECK(!SDL_IsXInputDevice(vendor, product, hidPath)); pNewJoystick = *(JoyStick_DeviceData **)pContext; while (pNewJoystick) { - if (SDL_wcscmp(pNewJoystick->hidPath, hidPath) == 0) { + /* update GUIDs of joysticks with matching paths, in case they're not open yet */ + if (SDL_strcmp(pNewJoystick->path, hidPath) == 0) { /* if we are replacing the front of the list then update it */ if (pNewJoystick == *(JoyStick_DeviceData **)pContext) { *(JoyStick_DeviceData **)pContext = pNewJoystick->pNext; @@ -586,137 +486,166 @@ EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext) pPrevJoystick->pNext = pNewJoystick->pNext; } - // Update with new guid/etc, if it has changed - pNewJoystick->dxdevice = *pdidInstance; + /* Update with new guid/etc, if it has changed */ + SDL_memcpy(&pNewJoystick->dxdevice, pDeviceInstance, sizeof(DIDEVICEINSTANCE)); pNewJoystick->pNext = SYS_Joystick; SYS_Joystick = pNewJoystick; - return DIENUM_CONTINUE; /* already have this joystick loaded, just keep going */ + pNewJoystick = NULL; + CHECK(FALSE); } pPrevJoystick = pNewJoystick; pNewJoystick = pNewJoystick->pNext; } - pNewJoystick = (JoyStick_DeviceData *)SDL_malloc(sizeof(JoyStick_DeviceData)); - if (!pNewJoystick) { - return DIENUM_CONTINUE; /* better luck next time? */ - } + pNewJoystick = (JoyStick_DeviceData *)SDL_calloc(1, sizeof(JoyStick_DeviceData)); + CHECK(pNewJoystick); - SDL_zerop(pNewJoystick); - SDL_wcslcpy(pNewJoystick->hidPath, hidPath, SDL_arraysize(pNewJoystick->hidPath)); - SDL_memcpy(&pNewJoystick->dxdevice, pdidInstance, sizeof(DIDEVICEINSTANCE)); - SDL_memset(pNewJoystick->guid.data, 0, sizeof(pNewJoystick->guid.data)); + pNewJoystick->steam_virtual_gamepad_slot = GetSteamVirtualGamepadSlot(vendor, product, hidPath); + SDL_strlcpy(pNewJoystick->path, hidPath, SDL_arraysize(pNewJoystick->path)); + SDL_memcpy(&pNewJoystick->dxdevice, pDeviceInstance, sizeof(DIDEVICEINSTANCE)); - guid16 = (Uint16 *)pNewJoystick->guid.data; - if (SDL_memcmp(&pdidInstance->guidProduct.Data4[2], "PIDVID", 6) == 0) { - vendor = (Uint16)LOWORD(pdidInstance->guidProduct.Data1); - product = (Uint16)HIWORD(pdidInstance->guidProduct.Data1); - version = 0; + pNewJoystick->joystickname = SDL_CreateJoystickName(vendor, product, NULL, name); + CHECK(pNewJoystick->joystickname); - *guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_USB); - *guid16++ = 0; - *guid16++ = SDL_SwapLE16(vendor); - *guid16++ = 0; - *guid16++ = SDL_SwapLE16(product); - *guid16++ = 0; - *guid16++ = SDL_SwapLE16(version); - *guid16++ = 0; + if (vendor && product) { + pNewJoystick->guid = SDL_CreateJoystickGUID(SDL_HARDWARE_BUS_USB, vendor, product, version, NULL, name, 0, 0); } else { - *guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_BLUETOOTH); - *guid16++ = 0; - SDL_strlcpy((char*)guid16, pNewJoystick->joystickname, sizeof(pNewJoystick->guid.data) - 4); + pNewJoystick->guid = SDL_CreateJoystickGUID(SDL_HARDWARE_BUS_BLUETOOTH, vendor, product, version, NULL, name, 0, 0); } - name = SDL_GetCustomJoystickName(vendor, product); - if (name) { - pNewJoystick->joystickname = SDL_strdup(name); - } else { - pNewJoystick->joystickname = WIN_StringToUTF8(pdidInstance->tszProductName); - } - if (!pNewJoystick->joystickname) { - SDL_free(pNewJoystick); - return DIENUM_CONTINUE; /* better luck next time? */ - } - - if (SDL_strstr(pNewJoystick->joystickname, " XINPUT ") != NULL) { - /* This is a duplicate interface for a controller that will show up with XInput, - e.g. Xbox One Elite Series 2 in Bluetooth mode. - */ - SDL_free(pNewJoystick->joystickname); - SDL_free(pNewJoystick); - return DIENUM_CONTINUE; - } - - if (SDL_ShouldIgnoreJoystick(pNewJoystick->joystickname, pNewJoystick->guid)) { - SDL_free(pNewJoystick->joystickname); - SDL_free(pNewJoystick); - return DIENUM_CONTINUE; - } + CHECK(!SDL_ShouldIgnoreJoystick(pNewJoystick->joystickname, pNewJoystick->guid)); #ifdef SDL_JOYSTICK_HIDAPI - if (HIDAPI_IsDevicePresent(vendor, product, 0, pNewJoystick->joystickname)) { - /* The HIDAPI driver is taking care of this device */ - SDL_free(pNewJoystick->joystickname); - SDL_free(pNewJoystick); - return DIENUM_CONTINUE; - } + CHECK(!HIDAPI_IsDevicePresent(vendor, product, version, pNewJoystick->joystickname)); +#endif + +#ifdef SDL_JOYSTICK_RAWINPUT + CHECK(!RAWINPUT_IsDevicePresent(vendor, product, version, pNewJoystick->joystickname)); #endif WINDOWS_AddJoystickDevice(pNewJoystick); + pNewJoystick = NULL; + +err: + if (pNewJoystick) { + SDL_free(pNewJoystick->joystickname); + SDL_free(pNewJoystick); + } + + SDL_free(hidPath); + SDL_free(name); + + if (device) { + IDirectInputDevice8_Release(device); + } return DIENUM_CONTINUE; /* get next device, please */ +#undef CHECK } -void -SDL_DINPUT_JoystickDetect(JoyStick_DeviceData **pContext) +void SDL_DINPUT_JoystickDetect(JoyStick_DeviceData **pContext) { - IDirectInput8_EnumDevices(dinput, DI8DEVCLASS_GAMECTRL, EnumJoysticksCallback, pContext, DIEDFL_ATTACHEDONLY); - - if (SDL_RawDevList) { - SDL_free(SDL_RawDevList); /* in case we used this in DirectInput detection */ - SDL_RawDevList = NULL; + if (!dinput) { + return; } - SDL_RawDevListCount = 0; + + IDirectInput8_EnumDevices(dinput, DI8DEVCLASS_GAMECTRL, EnumJoystickDetectCallback, pContext, DIEDFL_ATTACHEDONLY); } -static BOOL CALLBACK -EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID pvRef) +/* helper function for direct input, gets called for each connected joystick */ +typedef struct { - SDL_Joystick *joystick = (SDL_Joystick *)pvRef; + Uint16 vendor; + Uint16 product; + SDL_bool present; +} Joystick_PresentData; + +static BOOL CALLBACK EnumJoystickPresentCallback(LPCDIDEVICEINSTANCE pDeviceInstance, LPVOID pContext) +{ +#define CHECK(expression) \ + { \ + if (!(expression)) \ + goto err; \ + } + Joystick_PresentData *pData = (Joystick_PresentData *)pContext; + Uint16 vendor = 0; + Uint16 product = 0; + LPDIRECTINPUTDEVICE8 device = NULL; + BOOL result = DIENUM_CONTINUE; + + /* We are only supporting HID devices. */ + CHECK(pDeviceInstance->dwDevType & DIDEVTYPE_HID); + + CHECK(SUCCEEDED(IDirectInput8_CreateDevice(dinput, &pDeviceInstance->guidInstance, &device, NULL))); + CHECK(QueryDeviceInfo(device, &vendor, &product)); + + if (vendor == pData->vendor && product == pData->product) { + pData->present = SDL_TRUE; + result = DIENUM_STOP; /* found it */ + } + +err: + if (device) { + IDirectInputDevice8_Release(device); + } + + return result; +#undef CHECK +} + +SDL_bool SDL_DINPUT_JoystickPresent(Uint16 vendor_id, Uint16 product_id, Uint16 version_number) +{ + Joystick_PresentData data; + + if (!dinput) { + return SDL_FALSE; + } + + data.vendor = vendor_id; + data.product = product_id; + data.present = SDL_FALSE; + IDirectInput8_EnumDevices(dinput, DI8DEVCLASS_GAMECTRL, EnumJoystickPresentCallback, &data, DIEDFL_ATTACHEDONLY); + return data.present; +} + +static BOOL CALLBACK EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE pDeviceObject, LPVOID pContext) +{ + SDL_Joystick *joystick = (SDL_Joystick *)pContext; HRESULT result; input_t *in = &joystick->hwdata->Inputs[joystick->hwdata->NumInputs]; - if (dev->dwType & DIDFT_BUTTON) { + if (pDeviceObject->dwType & DIDFT_BUTTON) { in->type = BUTTON; in->num = joystick->nbuttons; in->ofs = DIJOFS_BUTTON(in->num); joystick->nbuttons++; - } else if (dev->dwType & DIDFT_POV) { + } else if (pDeviceObject->dwType & DIDFT_POV) { in->type = HAT; in->num = joystick->nhats; in->ofs = DIJOFS_POV(in->num); joystick->nhats++; - } else if (dev->dwType & DIDFT_AXIS) { + } else if (pDeviceObject->dwType & DIDFT_AXIS) { DIPROPRANGE diprg; DIPROPDWORD dilong; in->type = AXIS; in->num = joystick->naxes; - if (!SDL_memcmp(&dev->guidType, &GUID_XAxis, sizeof(dev->guidType))) + if (SDL_memcmp(&pDeviceObject->guidType, &GUID_XAxis, sizeof(pDeviceObject->guidType)) == 0) { in->ofs = DIJOFS_X; - else if (!SDL_memcmp(&dev->guidType, &GUID_YAxis, sizeof(dev->guidType))) + } else if (SDL_memcmp(&pDeviceObject->guidType, &GUID_YAxis, sizeof(pDeviceObject->guidType)) == 0) { in->ofs = DIJOFS_Y; - else if (!SDL_memcmp(&dev->guidType, &GUID_ZAxis, sizeof(dev->guidType))) + } else if (SDL_memcmp(&pDeviceObject->guidType, &GUID_ZAxis, sizeof(pDeviceObject->guidType)) == 0) { in->ofs = DIJOFS_Z; - else if (!SDL_memcmp(&dev->guidType, &GUID_RxAxis, sizeof(dev->guidType))) + } else if (SDL_memcmp(&pDeviceObject->guidType, &GUID_RxAxis, sizeof(pDeviceObject->guidType)) == 0) { in->ofs = DIJOFS_RX; - else if (!SDL_memcmp(&dev->guidType, &GUID_RyAxis, sizeof(dev->guidType))) + } else if (SDL_memcmp(&pDeviceObject->guidType, &GUID_RyAxis, sizeof(pDeviceObject->guidType)) == 0) { in->ofs = DIJOFS_RY; - else if (!SDL_memcmp(&dev->guidType, &GUID_RzAxis, sizeof(dev->guidType))) + } else if (SDL_memcmp(&pDeviceObject->guidType, &GUID_RzAxis, sizeof(pDeviceObject->guidType)) == 0) { in->ofs = DIJOFS_RZ; - else if (!SDL_memcmp(&dev->guidType, &GUID_Slider, sizeof(dev->guidType))) { + } else if (SDL_memcmp(&pDeviceObject->guidType, &GUID_Slider, sizeof(pDeviceObject->guidType)) == 0) { in->ofs = DIJOFS_SLIDER(joystick->hwdata->NumSliders); ++joystick->hwdata->NumSliders; } else { @@ -725,29 +654,29 @@ EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID pvRef) diprg.diph.dwSize = sizeof(diprg); diprg.diph.dwHeaderSize = sizeof(diprg.diph); - diprg.diph.dwObj = dev->dwType; + diprg.diph.dwObj = pDeviceObject->dwType; diprg.diph.dwHow = DIPH_BYID; diprg.lMin = SDL_JOYSTICK_AXIS_MIN; diprg.lMax = SDL_JOYSTICK_AXIS_MAX; result = IDirectInputDevice8_SetProperty(joystick->hwdata->InputDevice, - DIPROP_RANGE, &diprg.diph); + DIPROP_RANGE, &diprg.diph); if (FAILED(result)) { - return DIENUM_CONTINUE; /* don't use this axis */ + return DIENUM_CONTINUE; /* don't use this axis */ } /* Set dead zone to 0. */ dilong.diph.dwSize = sizeof(dilong); dilong.diph.dwHeaderSize = sizeof(dilong.diph); - dilong.diph.dwObj = dev->dwType; + dilong.diph.dwObj = pDeviceObject->dwType; dilong.diph.dwHow = DIPH_BYID; dilong.dwData = 0; result = IDirectInputDevice8_SetProperty(joystick->hwdata->InputDevice, - DIPROP_DEADZONE, &dilong.diph); + DIPROP_DEADZONE, &dilong.diph); if (FAILED(result)) { - return DIENUM_CONTINUE; /* don't use this axis */ + return DIENUM_CONTINUE; /* don't use this axis */ } joystick->naxes++; @@ -759,7 +688,7 @@ EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID pvRef) joystick->hwdata->NumInputs++; if (joystick->hwdata->NumInputs == MAX_INPUTS) { - return DIENUM_STOP; /* too many */ + return DIENUM_STOP; /* too many */ } return DIENUM_CONTINUE; @@ -768,22 +697,22 @@ EnumDevObjectsCallback(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID pvRef) /* Sort using the data offset into the DInput struct. * This gives a reasonable ordering for the inputs. */ -static int -SortDevFunc(const void *a, const void *b) +static int SDLCALL SortDevFunc(const void *a, const void *b) { - const input_t *inputA = (const input_t*)a; - const input_t *inputB = (const input_t*)b; + const input_t *inputA = (const input_t *)a; + const input_t *inputB = (const input_t *)b; - if (inputA->ofs < inputB->ofs) + if (inputA->ofs < inputB->ofs) { return -1; - if (inputA->ofs > inputB->ofs) + } + if (inputA->ofs > inputB->ofs) { return 1; + } return 0; } /* Sort the input objects and recalculate the indices for each input. */ -static void -SortDevObjects(SDL_Joystick *joystick) +static void SortDevObjects(SDL_Joystick *joystick) { input_t *inputs = joystick->hwdata->Inputs; int nButtons = 0; @@ -813,11 +742,9 @@ SortDevObjects(SDL_Joystick *joystick) } } -int -SDL_DINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickdevice) +int SDL_DINPUT_JoystickOpen(SDL_Joystick *joystick, JoyStick_DeviceData *joystickdevice) { HRESULT result; - LPDIRECTINPUTDEVICE8 device; DIPROPDWORD dipdw; joystick->hwdata->buffered = SDL_TRUE; @@ -829,30 +756,19 @@ SDL_DINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickde result = IDirectInput8_CreateDevice(dinput, - &(joystickdevice->dxdevice.guidInstance), &device, NULL); + &joystickdevice->dxdevice.guidInstance, + &joystick->hwdata->InputDevice, + NULL); if (FAILED(result)) { return SetDIerror("IDirectInput::CreateDevice", result); } - /* Now get the IDirectInputDevice8 interface, instead. */ - result = IDirectInputDevice8_QueryInterface(device, - &IID_IDirectInputDevice8, - (LPVOID *)& joystick-> - hwdata->InputDevice); - /* We are done with this object. Use the stored one from now on. */ - IDirectInputDevice8_Release(device); - - if (FAILED(result)) { - return SetDIerror("IDirectInputDevice8::QueryInterface", result); - } - /* Acquire shared access. Exclusive access is required for forces, - * though. */ + * though. */ result = - IDirectInputDevice8_SetCooperativeLevel(joystick->hwdata-> - InputDevice, SDL_HelperWindow, - DISCL_EXCLUSIVE | - DISCL_BACKGROUND); + IDirectInputDevice8_SetCooperativeLevel(joystick->hwdata->InputDevice, SDL_HelperWindow, + DISCL_EXCLUSIVE | + DISCL_BACKGROUND); if (FAILED(result)) { return SetDIerror("IDirectInputDevice8::SetCooperativeLevel", result); } @@ -860,7 +776,7 @@ SDL_DINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickde /* Use the extended data structure: DIJOYSTATE2. */ result = IDirectInputDevice8_SetDataFormat(joystick->hwdata->InputDevice, - &SDL_c_dfDIJoystick2); + &SDL_c_dfDIJoystick2); if (FAILED(result)) { return SetDIerror("IDirectInputDevice8::SetDataFormat", result); } @@ -868,7 +784,7 @@ SDL_DINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickde /* Get device capabilities */ result = IDirectInputDevice8_GetCapabilities(joystick->hwdata->InputDevice, - &joystick->hwdata->Capabilities); + &joystick->hwdata->Capabilities); if (FAILED(result)) { return SetDIerror("IDirectInputDevice8::GetCapabilities", result); } @@ -882,9 +798,8 @@ SDL_DINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickde /* reset all actuators. */ result = - IDirectInputDevice8_SendForceFeedbackCommand(joystick->hwdata-> - InputDevice, - DISFFC_RESET); + IDirectInputDevice8_SendForceFeedbackCommand(joystick->hwdata->InputDevice, + DISFFC_RESET); /* Not necessarily supported, ignore if not supported. if (FAILED(result)) { @@ -899,14 +814,14 @@ SDL_DINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickde } /* Turn on auto-centering for a ForceFeedback device (until told - * otherwise). */ + * otherwise). */ dipdw.diph.dwObj = 0; dipdw.diph.dwHow = DIPH_DEVICE; dipdw.dwData = DIPROPAUTOCENTER_ON; result = IDirectInputDevice8_SetProperty(joystick->hwdata->InputDevice, - DIPROP_AUTOCENTER, &dipdw.diph); + DIPROP_AUTOCENTER, &dipdw.diph); /* Not necessarily supported, ignore if not supported. if (FAILED(result)) { @@ -917,11 +832,11 @@ SDL_DINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickde /* What buttons and axes does it have? */ IDirectInputDevice8_EnumObjects(joystick->hwdata->InputDevice, - EnumDevObjectsCallback, joystick, - DIDFT_BUTTON | DIDFT_AXIS | DIDFT_POV); + EnumDevObjectsCallback, joystick, + DIDFT_BUTTON | DIDFT_AXIS | DIDFT_POV); /* Reorder the input objects. Some devices do not report the X axis as - * the first axis, for example. */ + * the first axis, for example. */ SortDevObjects(joystick); dipdw.diph.dwObj = 0; @@ -931,7 +846,7 @@ SDL_DINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickde /* Set the buffer size */ result = IDirectInputDevice8_SetProperty(joystick->hwdata->InputDevice, - DIPROP_BUFFERSIZE, &dipdw.diph); + DIPROP_BUFFERSIZE, &dipdw.diph); if (result == DI_POLLEDDEVICE) { /* This device doesn't support buffering, so we're forced @@ -940,11 +855,20 @@ SDL_DINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickde } else if (FAILED(result)) { return SetDIerror("IDirectInputDevice8::SetProperty", result); } + joystick->hwdata->first_update = SDL_TRUE; + + /* Poll and wait for initial device state to be populated */ + result = IDirectInputDevice8_Poll(joystick->hwdata->InputDevice); + if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) { + IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice); + IDirectInputDevice8_Poll(joystick->hwdata->InputDevice); + } + SDL_Delay(50); + return 0; } -static int -SDL_DINPUT_JoystickInitRumble(SDL_Joystick * joystick, Sint16 magnitude) +static int SDL_DINPUT_JoystickInitRumble(SDL_Joystick *joystick, Sint16 magnitude) { HRESULT result; @@ -979,8 +903,7 @@ SDL_DINPUT_JoystickInitRumble(SDL_Joystick * joystick, Sint16 magnitude) return 0; } -int -SDL_DINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +int SDL_DINPUT_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) { HRESULT result; @@ -1025,8 +948,18 @@ SDL_DINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, return 0; } -static Uint8 -TranslatePOV(DWORD value) +Uint32 SDL_DINPUT_JoystickGetCapabilities(SDL_Joystick *joystick) +{ + Uint32 result = 0; + + if (joystick->hwdata->Capabilities.dwFlags & DIDC_FORCEFEEDBACK) { + result |= SDL_JOYCAP_RUMBLE; + } + + return result; +} + +static Uint8 TranslatePOV(DWORD value) { const int HAT_VALS[] = { SDL_HAT_UP, @@ -1039,81 +972,28 @@ TranslatePOV(DWORD value) SDL_HAT_UP | SDL_HAT_LEFT }; - if (LOWORD(value) == 0xFFFF) + if (LOWORD(value) == 0xFFFF) { return SDL_HAT_CENTERED; + } /* Round the value up: */ value += 4500 / 2; value %= 36000; value /= 4500; - if (value >= 8) - return SDL_HAT_CENTERED; /* shouldn't happen */ + if (value >= 8) { + return SDL_HAT_CENTERED; /* shouldn't happen */ + } return HAT_VALS[value]; } -static void -UpdateDINPUTJoystickState_Buffered(SDL_Joystick * joystick) -{ - int i; - HRESULT result; - DWORD numevents; - DIDEVICEOBJECTDATA evtbuf[INPUT_QSIZE]; - - numevents = INPUT_QSIZE; - result = - IDirectInputDevice8_GetDeviceData(joystick->hwdata->InputDevice, - sizeof(DIDEVICEOBJECTDATA), evtbuf, - &numevents, 0); - if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) { - IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice); - result = - IDirectInputDevice8_GetDeviceData(joystick->hwdata->InputDevice, - sizeof(DIDEVICEOBJECTDATA), - evtbuf, &numevents, 0); - } - - /* Handle the events or punt */ - if (FAILED(result)) { - return; - } - - for (i = 0; i < (int)numevents; ++i) { - int j; - - for (j = 0; j < joystick->hwdata->NumInputs; ++j) { - const input_t *in = &joystick->hwdata->Inputs[j]; - - if (evtbuf[i].dwOfs != in->ofs) - continue; - - switch (in->type) { - case AXIS: - SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)evtbuf[i].dwData); - break; - case BUTTON: - SDL_PrivateJoystickButton(joystick, in->num, - (Uint8)(evtbuf[i].dwData ? SDL_PRESSED : SDL_RELEASED)); - break; - case HAT: - { - Uint8 pos = TranslatePOV(evtbuf[i].dwData); - SDL_PrivateJoystickHat(joystick, in->num, pos); - } - break; - } - } - } -} - /* Function to update the state of a joystick - called as a device poll. * This function shouldn't update the joystick structure directly, * but instead should call SDL_PrivateJoystick*() to deliver events * and update joystick device state. */ -static void -UpdateDINPUTJoystickState_Polled(SDL_Joystick * joystick) +static void UpdateDINPUTJoystickState_Polled(SDL_Joystick *joystick) { DIJOYSTATE2 state; HRESULT result; @@ -1121,12 +1001,12 @@ UpdateDINPUTJoystickState_Polled(SDL_Joystick * joystick) result = IDirectInputDevice8_GetDeviceState(joystick->hwdata->InputDevice, - sizeof(DIJOYSTATE2), &state); + sizeof(DIJOYSTATE2), &state); if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) { IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice); result = IDirectInputDevice8_GetDeviceState(joystick->hwdata->InputDevice, - sizeof(DIJOYSTATE2), &state); + sizeof(DIJOYSTATE2), &state); } if (result != DI_OK) { @@ -1169,7 +1049,7 @@ UpdateDINPUTJoystickState_Polled(SDL_Joystick * joystick) case BUTTON: SDL_PrivateJoystickButton(joystick, in->num, - (Uint8)(state.rgbButtons[in->ofs - DIJOFS_BUTTON0] ? SDL_PRESSED : SDL_RELEASED)); + (Uint8)(state.rgbButtons[in->ofs - DIJOFS_BUTTON0] ? SDL_PRESSED : SDL_RELEASED)); break; case HAT: { @@ -1181,8 +1061,67 @@ UpdateDINPUTJoystickState_Polled(SDL_Joystick * joystick) } } -void -SDL_DINPUT_JoystickUpdate(SDL_Joystick * joystick) +static void UpdateDINPUTJoystickState_Buffered(SDL_Joystick *joystick) +{ + int i; + HRESULT result; + DWORD numevents; + DIDEVICEOBJECTDATA evtbuf[INPUT_QSIZE]; + + numevents = INPUT_QSIZE; + result = + IDirectInputDevice8_GetDeviceData(joystick->hwdata->InputDevice, + sizeof(DIDEVICEOBJECTDATA), evtbuf, + &numevents, 0); + if (result == DIERR_INPUTLOST || result == DIERR_NOTACQUIRED) { + IDirectInputDevice8_Acquire(joystick->hwdata->InputDevice); + result = + IDirectInputDevice8_GetDeviceData(joystick->hwdata->InputDevice, + sizeof(DIDEVICEOBJECTDATA), + evtbuf, &numevents, 0); + } + + /* Handle the events or punt */ + if (FAILED(result)) { + return; + } + + for (i = 0; i < (int)numevents; ++i) { + int j; + + for (j = 0; j < joystick->hwdata->NumInputs; ++j) { + const input_t *in = &joystick->hwdata->Inputs[j]; + + if (evtbuf[i].dwOfs != in->ofs) { + continue; + } + + switch (in->type) { + case AXIS: + SDL_PrivateJoystickAxis(joystick, in->num, (Sint16)evtbuf[i].dwData); + break; + case BUTTON: + SDL_PrivateJoystickButton(joystick, in->num, + (Uint8)(evtbuf[i].dwData ? SDL_PRESSED : SDL_RELEASED)); + break; + case HAT: + { + Uint8 pos = TranslatePOV(evtbuf[i].dwData); + SDL_PrivateJoystickHat(joystick, in->num, pos); + } break; + } + } + } + + if (result == DI_BUFFEROVERFLOW) { + /* Our buffer wasn't big enough to hold all the queued events, + * so poll the device to make sure we have the complete state. + */ + UpdateDINPUTJoystickState_Polled(joystick); + } +} + +void SDL_DINPUT_JoystickUpdate(SDL_Joystick *joystick) { HRESULT result; @@ -1192,15 +1131,21 @@ SDL_DINPUT_JoystickUpdate(SDL_Joystick * joystick) IDirectInputDevice8_Poll(joystick->hwdata->InputDevice); } - if (joystick->hwdata->buffered) { + if (joystick->hwdata->first_update) { + /* Poll to get the initial state of the joystick */ + UpdateDINPUTJoystickState_Polled(joystick); + joystick->hwdata->first_update = SDL_FALSE; + return; + } + + if (joystick->hwdata->buffered ) { UpdateDINPUTJoystickState_Buffered(joystick); } else { UpdateDINPUTJoystickState_Polled(joystick); } } -void -SDL_DINPUT_JoystickClose(SDL_Joystick * joystick) +void SDL_DINPUT_JoystickClose(SDL_Joystick *joystick) { if (joystick->hwdata->ffeffect_ref) { IDirectInputEffect_Unload(joystick->hwdata->ffeffect_ref); @@ -1215,8 +1160,7 @@ SDL_DINPUT_JoystickClose(SDL_Joystick * joystick) joystick->hwdata->ff_initialized = SDL_FALSE; } -void -SDL_DINPUT_JoystickQuit(void) +void SDL_DINPUT_JoystickQuit(void) { if (dinput != NULL) { IDirectInput8_Release(dinput); @@ -1233,41 +1177,44 @@ SDL_DINPUT_JoystickQuit(void) typedef struct JoyStick_DeviceData JoyStick_DeviceData; -int -SDL_DINPUT_JoystickInit(void) +int SDL_DINPUT_JoystickInit(void) { return 0; } -void -SDL_DINPUT_JoystickDetect(JoyStick_DeviceData **pContext) +void SDL_DINPUT_JoystickDetect(JoyStick_DeviceData **pContext) { } -int -SDL_DINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickdevice) +SDL_bool SDL_DINPUT_JoystickPresent(Uint16 vendor, Uint16 product, Uint16 version) +{ + return SDL_FALSE; +} + +int SDL_DINPUT_JoystickOpen(SDL_Joystick *joystick, JoyStick_DeviceData *joystickdevice) { return SDL_Unsupported(); } -int -SDL_DINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +int SDL_DINPUT_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) { return SDL_Unsupported(); } -void -SDL_DINPUT_JoystickUpdate(SDL_Joystick * joystick) +Uint32 SDL_DINPUT_JoystickGetCapabilities(SDL_Joystick *joystick) +{ + return 0; +} + +void SDL_DINPUT_JoystickUpdate(SDL_Joystick *joystick) { } -void -SDL_DINPUT_JoystickClose(SDL_Joystick * joystick) +void SDL_DINPUT_JoystickClose(SDL_Joystick *joystick) { } -void -SDL_DINPUT_JoystickQuit(void) +void SDL_DINPUT_JoystickQuit(void) { } diff --git a/SDL2-2.0.12/src/joystick/windows/SDL_dinputjoystick_c.h b/SDL2-2.30.5/src/joystick/windows/SDL_dinputjoystick_c.h similarity index 59% rename from SDL2-2.0.12/src/joystick/windows/SDL_dinputjoystick_c.h rename to SDL2-2.30.5/src/joystick/windows/SDL_dinputjoystick_c.h index f647e7a..8e6d233 100644 --- a/SDL2-2.0.12/src/joystick/windows/SDL_dinputjoystick_c.h +++ b/SDL2-2.30.5/src/joystick/windows/SDL_dinputjoystick_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,12 +20,24 @@ */ #include "../../SDL_internal.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + extern int SDL_DINPUT_JoystickInit(void); extern void SDL_DINPUT_JoystickDetect(JoyStick_DeviceData **pContext); -extern int SDL_DINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickdevice); -extern int SDL_DINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble); -extern void SDL_DINPUT_JoystickUpdate(SDL_Joystick * joystick); -extern void SDL_DINPUT_JoystickClose(SDL_Joystick * joystick); +extern SDL_bool SDL_DINPUT_JoystickPresent(Uint16 vendor, Uint16 product, Uint16 version); +extern int SDL_DINPUT_JoystickOpen(SDL_Joystick *joystick, JoyStick_DeviceData *joystickdevice); +extern int SDL_DINPUT_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble); +extern Uint32 SDL_DINPUT_JoystickGetCapabilities(SDL_Joystick *joystick); +extern void SDL_DINPUT_JoystickUpdate(SDL_Joystick *joystick); +extern void SDL_DINPUT_JoystickClose(SDL_Joystick *joystick); extern void SDL_DINPUT_JoystickQuit(void); +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/joystick/windows/SDL_rawinputjoystick.c b/SDL2-2.30.5/src/joystick/windows/SDL_rawinputjoystick.c new file mode 100644 index 0000000..c911efd --- /dev/null +++ b/SDL2-2.30.5/src/joystick/windows/SDL_rawinputjoystick.c @@ -0,0 +1,2217 @@ +/* + Simple DirectMedia Layer + Copyright (C) 2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. + +*/ +/* + RAWINPUT Joystick API for better handling XInput-capable devices on Windows. + + XInput is limited to 4 devices. + Windows.Gaming.Input does not get inputs from XBox One controllers when not in the foreground. + DirectInput does not get inputs from XBox One controllers when not in the foreground, nor rumble or accurate triggers. + RawInput does not get rumble or accurate triggers. + + So, combine them as best we can! +*/ +#include "../../SDL_internal.h" + +#ifdef SDL_JOYSTICK_RAWINPUT + +#include "SDL_atomic.h" +#include "SDL_endian.h" +#include "SDL_events.h" +#include "SDL_hints.h" +#include "SDL_timer.h" +#include "../usb_ids.h" +#include "../SDL_sysjoystick.h" +#include "../../core/windows/SDL_windows.h" +#include "../../core/windows/SDL_hid.h" +#include "../hidapi/SDL_hidapijoystick_c.h" + +/* SDL_JOYSTICK_RAWINPUT_XINPUT is disabled because using XInput at the same time as + raw input will turn off the Xbox Series X controller when it is connected via the + Xbox One Wireless Adapter. + */ +#ifdef HAVE_XINPUT_H +#define SDL_JOYSTICK_RAWINPUT_XINPUT +#endif +#ifdef HAVE_WINDOWS_GAMING_INPUT_H +#define SDL_JOYSTICK_RAWINPUT_WGI +#endif + +#ifdef SDL_JOYSTICK_RAWINPUT_XINPUT +#include "../../core/windows/SDL_xinput.h" +#endif + +#ifdef SDL_JOYSTICK_RAWINPUT_WGI +#include "../../core/windows/SDL_windows.h" +typedef struct WindowsGamingInputGamepadState WindowsGamingInputGamepadState; +#define GamepadButtons_GUIDE 0x40000000 +#define COBJMACROS +#include "windows.gaming.input.h" +#include +#endif + +#if defined(SDL_JOYSTICK_RAWINPUT_XINPUT) || defined(SDL_JOYSTICK_RAWINPUT_WGI) +#define SDL_JOYSTICK_RAWINPUT_MATCHING +#define SDL_JOYSTICK_RAWINPUT_MATCH_AXES +#define SDL_JOYSTICK_RAWINPUT_MATCH_TRIGGERS +#ifdef SDL_JOYSTICK_RAWINPUT_MATCH_TRIGGERS +#define SDL_JOYSTICK_RAWINPUT_MATCH_COUNT 6 // stick + trigger axes +#else +#define SDL_JOYSTICK_RAWINPUT_MATCH_COUNT 4 // stick axes +#endif +#endif + +#if 0 +#define DEBUG_RAWINPUT +#endif + +#ifndef RIDEV_EXINPUTSINK +#define RIDEV_EXINPUTSINK 0x00001000 +#define RIDEV_DEVNOTIFY 0x00002000 +#endif + +#ifndef WM_INPUT_DEVICE_CHANGE +#define WM_INPUT_DEVICE_CHANGE 0x00FE +#endif +#ifndef WM_INPUT +#define WM_INPUT 0x00FF +#endif +#ifndef GIDC_ARRIVAL +#define GIDC_ARRIVAL 1 +#define GIDC_REMOVAL 2 +#endif + +extern void WINDOWS_RAWINPUTEnabledChanged(void); +extern void WINDOWS_JoystickDetect(void); + +static SDL_bool SDL_RAWINPUT_inited = SDL_FALSE; +static SDL_bool SDL_RAWINPUT_remote_desktop = SDL_FALSE; +static int SDL_RAWINPUT_numjoysticks = 0; + +static void RAWINPUT_JoystickClose(SDL_Joystick *joystick); + +typedef struct _SDL_RAWINPUT_Device +{ + SDL_atomic_t refcount; + char *name; + char *path; + Uint16 vendor_id; + Uint16 product_id; + Uint16 version; + SDL_JoystickGUID guid; + SDL_bool is_xinput; + SDL_bool is_xboxone; + int steam_virtual_gamepad_slot; + PHIDP_PREPARSED_DATA preparsed_data; + + HANDLE hDevice; + SDL_Joystick *joystick; + SDL_JoystickID joystick_id; + + struct _SDL_RAWINPUT_Device *next; +} SDL_RAWINPUT_Device; + +struct joystick_hwdata +{ + SDL_bool is_xinput; + SDL_bool is_xboxone; + PHIDP_PREPARSED_DATA preparsed_data; + ULONG max_data_length; + HIDP_DATA *data; + USHORT *button_indices; + USHORT *axis_indices; + USHORT *hat_indices; + SDL_bool guide_hack; + SDL_bool trigger_hack; + USHORT trigger_hack_index; + +#ifdef SDL_JOYSTICK_RAWINPUT_MATCHING + Uint64 match_state; /* Lowest 16 bits for button states, higher 24 for 6 4bit axes */ + Uint32 last_state_packet; +#endif + +#ifdef SDL_JOYSTICK_RAWINPUT_XINPUT + SDL_bool xinput_enabled; + SDL_bool xinput_correlated; + Uint8 xinput_correlation_id; + Uint8 xinput_correlation_count; + Uint8 xinput_uncorrelate_count; + Uint8 xinput_slot; +#endif + +#ifdef SDL_JOYSTICK_RAWINPUT_WGI + SDL_bool wgi_correlated; + Uint8 wgi_correlation_id; + Uint8 wgi_correlation_count; + Uint8 wgi_uncorrelate_count; + WindowsGamingInputGamepadState *wgi_slot; +#endif + + SDL_RAWINPUT_Device *device; +}; +typedef struct joystick_hwdata RAWINPUT_DeviceContext; + +SDL_RAWINPUT_Device *SDL_RAWINPUT_devices; + +static const Uint16 subscribed_devices[] = { + USB_USAGE_GENERIC_GAMEPAD, + /* Don't need Joystick for any devices we're handling here (XInput-capable) + USB_USAGE_GENERIC_JOYSTICK, + USB_USAGE_GENERIC_MULTIAXISCONTROLLER, + */ +}; + +#ifdef SDL_JOYSTICK_RAWINPUT_MATCHING + +static struct +{ + Uint32 last_state_packet; + SDL_Joystick *joystick; + SDL_Joystick *last_joystick; +} guide_button_candidate; + +typedef struct WindowsMatchState +{ +#ifdef SDL_JOYSTICK_RAWINPUT_MATCH_AXES + SHORT match_axes[SDL_JOYSTICK_RAWINPUT_MATCH_COUNT]; +#endif +#ifdef SDL_JOYSTICK_RAWINPUT_XINPUT + WORD xinput_buttons; +#endif +#ifdef SDL_JOYSTICK_RAWINPUT_WGI + Uint32 wgi_buttons; +#endif + SDL_bool any_data; +} WindowsMatchState; + +static void RAWINPUT_FillMatchState(WindowsMatchState *state, Uint64 match_state) +{ +#ifdef SDL_JOYSTICK_RAWINPUT_MATCH_AXES + int ii; +#endif + + SDL_bool any_axes_data = SDL_FALSE; +#ifdef SDL_JOYSTICK_RAWINPUT_MATCH_AXES + /* SHORT state->match_axes[4] = { + (match_state & 0x000F0000) >> 4, + (match_state & 0x00F00000) >> 8, + (match_state & 0x0F000000) >> 12, + (match_state & 0xF0000000) >> 16, + }; */ + for (ii = 0; ii < 4; ii++) { + state->match_axes[ii] = (SHORT)((match_state & (0x000F0000ull << (ii * 4))) >> (4 + ii * 4)); + any_axes_data |= ((Uint32)(state->match_axes[ii] + 0x1000) > 0x2000); /* match_state bit is not 0xF, 0x1, or 0x2 */ + } +#endif /* SDL_JOYSTICK_RAWINPUT_MATCH_AXES */ +#ifdef SDL_JOYSTICK_RAWINPUT_MATCH_TRIGGERS + for (; ii < SDL_JOYSTICK_RAWINPUT_MATCH_COUNT; ii++) { + state->match_axes[ii] = (SHORT)((match_state & (0x000F0000ull << (ii * 4))) >> (4 + ii * 4)); + any_axes_data |= (state->match_axes[ii] != SDL_MIN_SINT16); + } +#endif /* SDL_JOYSTICK_RAWINPUT_MATCH_TRIGGERS */ + + state->any_data = any_axes_data; + +#ifdef SDL_JOYSTICK_RAWINPUT_XINPUT + /* Match axes by checking if the distance between the high 4 bits of axis and the 4 bits from match_state is 1 or less */ +#define XInputAxesMatch(gamepad) ( \ + (Uint32)(gamepad.sThumbLX - state->match_axes[0] + 0x1000) <= 0x2fff && \ + (Uint32)(~gamepad.sThumbLY - state->match_axes[1] + 0x1000) <= 0x2fff && \ + (Uint32)(gamepad.sThumbRX - state->match_axes[2] + 0x1000) <= 0x2fff && \ + (Uint32)(~gamepad.sThumbRY - state->match_axes[3] + 0x1000) <= 0x2fff) + /* Explicit +#define XInputAxesMatch(gamepad) (\ + SDL_abs((Sint8)((gamepad.sThumbLX & 0xF000) >> 8) - ((match_state & 0x000F0000) >> 12)) <= 0x10 && \ + SDL_abs((Sint8)((~gamepad.sThumbLY & 0xF000) >> 8) - ((match_state & 0x00F00000) >> 16)) <= 0x10 && \ + SDL_abs((Sint8)((gamepad.sThumbRX & 0xF000) >> 8) - ((match_state & 0x0F000000) >> 20)) <= 0x10 && \ + SDL_abs((Sint8)((~gamepad.sThumbRY & 0xF000) >> 8) - ((match_state & 0xF0000000) >> 24)) <= 0x10) */ + + /* Can only match trigger values if a single trigger has a value. */ +#define XInputTriggersMatch(gamepad) ( \ + ((state->match_axes[4] == SDL_MIN_SINT16) && (state->match_axes[5] == SDL_MIN_SINT16)) || \ + ((gamepad.bLeftTrigger != 0) && (gamepad.bRightTrigger != 0)) || \ + ((Uint32)((((int)gamepad.bLeftTrigger * 257) - 32768) - state->match_axes[4]) <= 0x2fff) || \ + ((Uint32)((((int)gamepad.bRightTrigger * 257) - 32768) - state->match_axes[5]) <= 0x2fff)) + + state->xinput_buttons = + /* Bitwise map .RLDUWVQTS.KYXBA -> YXBA..WVQTKSRLDU */ + (WORD)(match_state << 12 | (match_state & 0x0780) >> 1 | (match_state & 0x0010) << 1 | (match_state & 0x0040) >> 2 | (match_state & 0x7800) >> 11); + /* Explicit + ((match_state & (1<xinput_buttons) { + state->any_data = SDL_TRUE; + } +#endif + +#ifdef SDL_JOYSTICK_RAWINPUT_WGI + /* Match axes by checking if the distance between the high 4 bits of axis and the 4 bits from match_state is 1 or less */ +#define WindowsGamingInputAxesMatch(gamepad) ( \ + (Uint16)(((Sint16)(gamepad.LeftThumbstickX * SDL_MAX_SINT16) & 0xF000) - state->match_axes[0] + 0x1000) <= 0x2fff && \ + (Uint16)((~(Sint16)(gamepad.LeftThumbstickY * SDL_MAX_SINT16) & 0xF000) - state->match_axes[1] + 0x1000) <= 0x2fff && \ + (Uint16)(((Sint16)(gamepad.RightThumbstickX * SDL_MAX_SINT16) & 0xF000) - state->match_axes[2] + 0x1000) <= 0x2fff && \ + (Uint16)((~(Sint16)(gamepad.RightThumbstickY * SDL_MAX_SINT16) & 0xF000) - state->match_axes[3] + 0x1000) <= 0x2fff) + +#define WindowsGamingInputTriggersMatch(gamepad) ( \ + ((state->match_axes[4] == SDL_MIN_SINT16) && (state->match_axes[5] == SDL_MIN_SINT16)) || \ + ((gamepad.LeftTrigger == 0.0f) && (gamepad.RightTrigger == 0.0f)) || \ + ((Uint16)((((int)(gamepad.LeftTrigger * SDL_MAX_UINT16)) - 32768) - state->match_axes[4]) <= 0x2fff) || \ + ((Uint16)((((int)(gamepad.RightTrigger * SDL_MAX_UINT16)) - 32768) - state->match_axes[5]) <= 0x2fff)) + + state->wgi_buttons = + /* Bitwise map .RLD UWVQ TS.K YXBA -> ..QT WVRL DUYX BAKS */ + /* RStick/LStick (QT) RShould/LShould (WV) DPad R/L/D/U YXBA bac(K) (S)tart */ + (match_state & 0x0180) << 5 | (match_state & 0x0600) << 1 | (match_state & 0x7800) >> 5 | (match_state & 0x000F) << 2 | (match_state & 0x0010) >> 3 | (match_state & 0x0040) >> 6; + /* Explicit + ((match_state & (1<wgi_buttons) { + state->any_data = SDL_TRUE; + } +#endif +} + +#endif /* SDL_JOYSTICK_RAWINPUT_MATCHING */ + +#ifdef SDL_JOYSTICK_RAWINPUT_XINPUT + +static struct +{ + XINPUT_STATE state; + XINPUT_BATTERY_INFORMATION_EX battery; + SDL_bool connected; /* Currently has an active XInput device */ + SDL_bool used; /* Is currently mapped to an SDL device */ + Uint8 correlation_id; +} xinput_state[XUSER_MAX_COUNT]; +static SDL_bool xinput_device_change = SDL_TRUE; +static SDL_bool xinput_state_dirty = SDL_TRUE; + +static void RAWINPUT_UpdateXInput() +{ + DWORD user_index; + if (xinput_device_change) { + for (user_index = 0; user_index < XUSER_MAX_COUNT; user_index++) { + XINPUT_CAPABILITIES capabilities; + xinput_state[user_index].connected = (XINPUTGETCAPABILITIES(user_index, XINPUT_FLAG_GAMEPAD, &capabilities) == ERROR_SUCCESS) ? SDL_TRUE : SDL_FALSE; + } + xinput_device_change = SDL_FALSE; + xinput_state_dirty = SDL_TRUE; + } + if (xinput_state_dirty) { + xinput_state_dirty = SDL_FALSE; + for (user_index = 0; user_index < SDL_arraysize(xinput_state); ++user_index) { + if (xinput_state[user_index].connected) { + if (XINPUTGETSTATE(user_index, &xinput_state[user_index].state) != ERROR_SUCCESS) { + xinput_state[user_index].connected = SDL_FALSE; + } + xinput_state[user_index].battery.BatteryType = BATTERY_TYPE_UNKNOWN; + if (XINPUTGETBATTERYINFORMATION) { + XINPUTGETBATTERYINFORMATION(user_index, BATTERY_DEVTYPE_GAMEPAD, &xinput_state[user_index].battery); + } + } + } + } +} + +static void RAWINPUT_MarkXInputSlotUsed(Uint8 xinput_slot) +{ + if (xinput_slot != XUSER_INDEX_ANY) { + xinput_state[xinput_slot].used = SDL_TRUE; + } +} + +static void RAWINPUT_MarkXInputSlotFree(Uint8 xinput_slot) +{ + if (xinput_slot != XUSER_INDEX_ANY) { + xinput_state[xinput_slot].used = SDL_FALSE; + } +} +static SDL_bool RAWINPUT_MissingXInputSlot() +{ + int ii; + for (ii = 0; ii < SDL_arraysize(xinput_state); ii++) { + if (xinput_state[ii].connected && !xinput_state[ii].used) { + return SDL_TRUE; + } + } + return SDL_FALSE; +} + +static SDL_bool RAWINPUT_XInputSlotMatches(const WindowsMatchState *state, Uint8 slot_idx) +{ + if (xinput_state[slot_idx].connected) { + WORD xinput_buttons = xinput_state[slot_idx].state.Gamepad.wButtons; + if ((xinput_buttons & ~XINPUT_GAMEPAD_GUIDE) == state->xinput_buttons +#ifdef SDL_JOYSTICK_RAWINPUT_MATCH_AXES + && XInputAxesMatch(xinput_state[slot_idx].state.Gamepad) +#endif +#ifdef SDL_JOYSTICK_RAWINPUT_MATCH_TRIGGERS + && XInputTriggersMatch(xinput_state[slot_idx].state.Gamepad) +#endif + ) { + return SDL_TRUE; + } + } + return SDL_FALSE; +} + +static SDL_bool RAWINPUT_GuessXInputSlot(const WindowsMatchState *state, Uint8 *correlation_id, Uint8 *slot_idx) +{ + int user_index; + int match_count; + + /* If there is only one available slot, let's use that + * That will be right most of the time, and uncorrelation will fix any bad guesses + */ + match_count = 0; + for (user_index = 0; user_index < XUSER_MAX_COUNT; ++user_index) { + if (xinput_state[user_index].connected && !xinput_state[user_index].used) { + *slot_idx = user_index; + ++match_count; + } + } + if (match_count == 1) { + *correlation_id = ++xinput_state[*slot_idx].correlation_id; + return SDL_TRUE; + } + + *slot_idx = 0; + + match_count = 0; + for (user_index = 0; user_index < XUSER_MAX_COUNT; ++user_index) { + if (!xinput_state[user_index].used && RAWINPUT_XInputSlotMatches(state, user_index)) { + ++match_count; + *slot_idx = (Uint8)user_index; + /* Incrementing correlation_id for any match, as negative evidence for others being correlated */ + *correlation_id = ++xinput_state[user_index].correlation_id; + } + } + /* Only return a match if we match exactly one, and we have some non-zero data (buttons or axes) that matched. + Note that we're still invalidating *other* potential correlations if we have more than one match or we have no + data. */ + if (match_count == 1 && state->any_data) { + return SDL_TRUE; + } + return SDL_FALSE; +} + +#endif /* SDL_JOYSTICK_RAWINPUT_XINPUT */ + +#ifdef SDL_JOYSTICK_RAWINPUT_WGI + +typedef struct WindowsGamingInputGamepadState +{ + __x_ABI_CWindows_CGaming_CInput_CIGamepad *gamepad; + struct __x_ABI_CWindows_CGaming_CInput_CGamepadReading state; + RAWINPUT_DeviceContext *correlated_context; + SDL_bool used; /* Is currently mapped to an SDL device */ + SDL_bool connected; /* Just used during update to track disconnected */ + Uint8 correlation_id; + struct __x_ABI_CWindows_CGaming_CInput_CGamepadVibration vibration; +} WindowsGamingInputGamepadState; + +static struct +{ + WindowsGamingInputGamepadState **per_gamepad; + int per_gamepad_count; + SDL_bool initialized; + SDL_bool dirty; + SDL_bool need_device_list_update; + int ref_count; + __x_ABI_CWindows_CGaming_CInput_CIGamepadStatics *gamepad_statics; + EventRegistrationToken gamepad_added_token; + EventRegistrationToken gamepad_removed_token; +} wgi_state; + +typedef struct GamepadDelegate +{ + __FIEventHandler_1_Windows__CGaming__CInput__CGamepad iface; + SDL_atomic_t refcount; +} GamepadDelegate; + +static const IID IID_IEventHandler_Gamepad = { 0x8a7639ee, 0x624a, 0x501a, { 0xbb, 0x53, 0x56, 0x2d, 0x1e, 0xc1, 0x1b, 0x52 } }; + +static HRESULT STDMETHODCALLTYPE IEventHandler_CGamepadVtbl_QueryInterface(__FIEventHandler_1_Windows__CGaming__CInput__CGamepad *This, REFIID riid, void **ppvObject) +{ + if (!ppvObject) { + return E_INVALIDARG; + } + + *ppvObject = NULL; + if (WIN_IsEqualIID(riid, &IID_IUnknown) || WIN_IsEqualIID(riid, &IID_IAgileObject) || WIN_IsEqualIID(riid, &IID_IEventHandler_Gamepad)) { + *ppvObject = This; + __FIEventHandler_1_Windows__CGaming__CInput__CGamepad_AddRef(This); + return S_OK; + } else if (WIN_IsEqualIID(riid, &IID_IMarshal)) { + /* This seems complicated. Let's hope it doesn't happen. */ + return E_OUTOFMEMORY; + } else { + return E_NOINTERFACE; + } +} + +static ULONG STDMETHODCALLTYPE IEventHandler_CGamepadVtbl_AddRef(__FIEventHandler_1_Windows__CGaming__CInput__CGamepad *This) +{ + GamepadDelegate *self = (GamepadDelegate *)This; + return SDL_AtomicAdd(&self->refcount, 1) + 1UL; +} + +static ULONG STDMETHODCALLTYPE IEventHandler_CGamepadVtbl_Release(__FIEventHandler_1_Windows__CGaming__CInput__CGamepad *This) +{ + GamepadDelegate *self = (GamepadDelegate *)This; + int rc = SDL_AtomicAdd(&self->refcount, -1) - 1; + /* Should never free the static delegate objects */ + SDL_assert(rc > 0); + return rc; +} + +static HRESULT STDMETHODCALLTYPE IEventHandler_CGamepadVtbl_InvokeAdded(__FIEventHandler_1_Windows__CGaming__CInput__CGamepad *This, IInspectable *sender, __x_ABI_CWindows_CGaming_CInput_CIGamepad *e) +{ + wgi_state.need_device_list_update = SDL_TRUE; + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE IEventHandler_CGamepadVtbl_InvokeRemoved(__FIEventHandler_1_Windows__CGaming__CInput__CGamepad *This, IInspectable *sender, __x_ABI_CWindows_CGaming_CInput_CIGamepad *e) +{ + wgi_state.need_device_list_update = SDL_TRUE; + return S_OK; +} + +static __FIEventHandler_1_Windows__CGaming__CInput__CGamepadVtbl gamepad_added_vtbl = { + IEventHandler_CGamepadVtbl_QueryInterface, + IEventHandler_CGamepadVtbl_AddRef, + IEventHandler_CGamepadVtbl_Release, + IEventHandler_CGamepadVtbl_InvokeAdded +}; +static GamepadDelegate gamepad_added = { + { &gamepad_added_vtbl }, + { 1 } +}; + +static __FIEventHandler_1_Windows__CGaming__CInput__CGamepadVtbl gamepad_removed_vtbl = { + IEventHandler_CGamepadVtbl_QueryInterface, + IEventHandler_CGamepadVtbl_AddRef, + IEventHandler_CGamepadVtbl_Release, + IEventHandler_CGamepadVtbl_InvokeRemoved +}; +static GamepadDelegate gamepad_removed = { + { &gamepad_removed_vtbl }, + { 1 } +}; + +static void RAWINPUT_MarkWindowsGamingInputSlotUsed(WindowsGamingInputGamepadState *wgi_slot, RAWINPUT_DeviceContext *ctx) +{ + wgi_slot->used = SDL_TRUE; + wgi_slot->correlated_context = ctx; +} + +static void RAWINPUT_MarkWindowsGamingInputSlotFree(WindowsGamingInputGamepadState *wgi_slot) +{ + wgi_slot->used = SDL_FALSE; + wgi_slot->correlated_context = NULL; +} + +static SDL_bool RAWINPUT_MissingWindowsGamingInputSlot() +{ + int ii; + for (ii = 0; ii < wgi_state.per_gamepad_count; ii++) { + if (!wgi_state.per_gamepad[ii]->used) { + return SDL_TRUE; + } + } + return SDL_FALSE; +} + +static void RAWINPUT_UpdateWindowsGamingInput() +{ + int ii; + if (!wgi_state.gamepad_statics) { + return; + } + + if (!wgi_state.dirty) { + return; + } + + wgi_state.dirty = SDL_FALSE; + + if (wgi_state.need_device_list_update) { + HRESULT hr; + __FIVectorView_1_Windows__CGaming__CInput__CGamepad *gamepads; + wgi_state.need_device_list_update = SDL_FALSE; + for (ii = 0; ii < wgi_state.per_gamepad_count; ii++) { + wgi_state.per_gamepad[ii]->connected = SDL_FALSE; + } + + hr = __x_ABI_CWindows_CGaming_CInput_CIGamepadStatics_get_Gamepads(wgi_state.gamepad_statics, &gamepads); + if (SUCCEEDED(hr)) { + unsigned int num_gamepads; + + hr = __FIVectorView_1_Windows__CGaming__CInput__CGamepad_get_Size(gamepads, &num_gamepads); + if (SUCCEEDED(hr)) { + unsigned int i; + for (i = 0; i < num_gamepads; ++i) { + __x_ABI_CWindows_CGaming_CInput_CIGamepad *gamepad; + + hr = __FIVectorView_1_Windows__CGaming__CInput__CGamepad_GetAt(gamepads, i, &gamepad); + if (SUCCEEDED(hr)) { + SDL_bool found = SDL_FALSE; + int jj; + for (jj = 0; jj < wgi_state.per_gamepad_count; jj++) { + if (wgi_state.per_gamepad[jj]->gamepad == gamepad) { + found = SDL_TRUE; + wgi_state.per_gamepad[jj]->connected = SDL_TRUE; + break; + } + } + if (!found) { + /* New device, add it */ + WindowsGamingInputGamepadState *gamepad_state; + + wgi_state.per_gamepad_count++; + wgi_state.per_gamepad = SDL_realloc(wgi_state.per_gamepad, sizeof(wgi_state.per_gamepad[0]) * wgi_state.per_gamepad_count); + if (!wgi_state.per_gamepad) { + SDL_OutOfMemory(); + return; + } + gamepad_state = SDL_calloc(1, sizeof(*gamepad_state)); + if (!gamepad_state) { + SDL_OutOfMemory(); + return; + } + wgi_state.per_gamepad[wgi_state.per_gamepad_count - 1] = gamepad_state; + gamepad_state->gamepad = gamepad; + gamepad_state->connected = SDL_TRUE; + } else { + /* Already tracked */ + __x_ABI_CWindows_CGaming_CInput_CIGamepad_Release(gamepad); + } + } + } + for (ii = wgi_state.per_gamepad_count - 1; ii >= 0; ii--) { + WindowsGamingInputGamepadState *gamepad_state = wgi_state.per_gamepad[ii]; + if (!gamepad_state->connected) { + /* Device missing, must be disconnected */ + if (gamepad_state->correlated_context) { + gamepad_state->correlated_context->wgi_correlated = SDL_FALSE; + gamepad_state->correlated_context->wgi_slot = NULL; + } + __x_ABI_CWindows_CGaming_CInput_CIGamepad_Release(gamepad_state->gamepad); + SDL_free(gamepad_state); + wgi_state.per_gamepad[ii] = wgi_state.per_gamepad[wgi_state.per_gamepad_count - 1]; + --wgi_state.per_gamepad_count; + } + } + } + __FIVectorView_1_Windows__CGaming__CInput__CGamepad_Release(gamepads); + } + } /* need_device_list_update */ + + for (ii = 0; ii < wgi_state.per_gamepad_count; ii++) { + HRESULT hr = __x_ABI_CWindows_CGaming_CInput_CIGamepad_GetCurrentReading(wgi_state.per_gamepad[ii]->gamepad, &wgi_state.per_gamepad[ii]->state); + if (!SUCCEEDED(hr)) { + wgi_state.per_gamepad[ii]->connected = SDL_FALSE; /* Not used by anything, currently */ + } + } +} +static void RAWINPUT_InitWindowsGamingInput(RAWINPUT_DeviceContext *ctx) +{ + if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_WGI, SDL_TRUE)) { + return; + } + + wgi_state.ref_count++; + if (!wgi_state.initialized) { + static const IID SDL_IID_IGamepadStatics = { 0x8BBCE529, 0xD49C, 0x39E9, { 0x95, 0x60, 0xE4, 0x7D, 0xDE, 0x96, 0xB7, 0xC8 } }; + HRESULT hr; + + if (FAILED(WIN_RoInitialize())) { + return; + } + wgi_state.initialized = SDL_TRUE; + wgi_state.dirty = SDL_TRUE; + + { + typedef HRESULT(WINAPI * WindowsCreateStringReference_t)(PCWSTR sourceString, UINT32 length, HSTRING_HEADER * hstringHeader, HSTRING * string); + typedef HRESULT(WINAPI * RoGetActivationFactory_t)(HSTRING activatableClassId, REFIID iid, void **factory); + +#ifdef __WINRT__ + WindowsCreateStringReference_t WindowsCreateStringReferenceFunc = WindowsCreateStringReference; + RoGetActivationFactory_t RoGetActivationFactoryFunc = RoGetActivationFactory; +#else + WindowsCreateStringReference_t WindowsCreateStringReferenceFunc = (WindowsCreateStringReference_t)WIN_LoadComBaseFunction("WindowsCreateStringReference"); + RoGetActivationFactory_t RoGetActivationFactoryFunc = (RoGetActivationFactory_t)WIN_LoadComBaseFunction("RoGetActivationFactory"); +#endif + if (WindowsCreateStringReferenceFunc && RoGetActivationFactoryFunc) { + PCWSTR pNamespace = L"Windows.Gaming.Input.Gamepad"; + HSTRING_HEADER hNamespaceStringHeader; + HSTRING hNamespaceString; + + hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString); + if (SUCCEEDED(hr)) { + RoGetActivationFactoryFunc(hNamespaceString, &SDL_IID_IGamepadStatics, (void **)&wgi_state.gamepad_statics); + } + + if (wgi_state.gamepad_statics) { + wgi_state.need_device_list_update = SDL_TRUE; + + hr = __x_ABI_CWindows_CGaming_CInput_CIGamepadStatics_add_GamepadAdded(wgi_state.gamepad_statics, &gamepad_added.iface, &wgi_state.gamepad_added_token); + if (!SUCCEEDED(hr)) { + SDL_SetError("add_GamepadAdded() failed: 0x%lx\n", hr); + } + + hr = __x_ABI_CWindows_CGaming_CInput_CIGamepadStatics_add_GamepadRemoved(wgi_state.gamepad_statics, &gamepad_removed.iface, &wgi_state.gamepad_removed_token); + if (!SUCCEEDED(hr)) { + SDL_SetError("add_GamepadRemoved() failed: 0x%lx\n", hr); + } + } + } + } + } +} + +static SDL_bool RAWINPUT_WindowsGamingInputSlotMatches(const WindowsMatchState *state, WindowsGamingInputGamepadState *slot, SDL_bool xinput_correlated) +{ + Uint32 wgi_buttons = slot->state.Buttons; + if ((wgi_buttons & 0x3FFF) == state->wgi_buttons +#ifdef SDL_JOYSTICK_RAWINPUT_MATCH_AXES + && WindowsGamingInputAxesMatch(slot->state) +#endif +#ifdef SDL_JOYSTICK_RAWINPUT_MATCH_TRIGGERS + // Don't try to match WGI triggers if getting values from XInput + && (xinput_correlated || WindowsGamingInputTriggersMatch(slot->state)) +#endif + ) { + return SDL_TRUE; + } + return SDL_FALSE; +} + +static SDL_bool RAWINPUT_GuessWindowsGamingInputSlot(const WindowsMatchState *state, Uint8 *correlation_id, WindowsGamingInputGamepadState **slot, SDL_bool xinput_correlated) +{ + int match_count, user_index; + WindowsGamingInputGamepadState *gamepad_state = NULL; + + /* If there is only one available slot, let's use that + * That will be right most of the time, and uncorrelation will fix any bad guesses + */ + match_count = 0; + for (user_index = 0; user_index < wgi_state.per_gamepad_count; ++user_index) { + gamepad_state = wgi_state.per_gamepad[user_index]; + if (gamepad_state->connected && !gamepad_state->used) { + *slot = gamepad_state; + ++match_count; + } + } + if (match_count == 1) { + *correlation_id = ++gamepad_state->correlation_id; + return SDL_TRUE; + } + + match_count = 0; + for (user_index = 0; user_index < wgi_state.per_gamepad_count; ++user_index) { + gamepad_state = wgi_state.per_gamepad[user_index]; + if (RAWINPUT_WindowsGamingInputSlotMatches(state, gamepad_state, xinput_correlated)) { + ++match_count; + *slot = gamepad_state; + /* Incrementing correlation_id for any match, as negative evidence for others being correlated */ + *correlation_id = ++gamepad_state->correlation_id; + } + } + /* Only return a match if we match exactly one, and we have some non-zero data (buttons or axes) that matched. + Note that we're still invalidating *other* potential correlations if we have more than one match or we have no + data. */ + if (match_count == 1 && state->any_data) { + return SDL_TRUE; + } + return SDL_FALSE; +} + +static void RAWINPUT_QuitWindowsGamingInput(RAWINPUT_DeviceContext *ctx) +{ + --wgi_state.ref_count; + if (!wgi_state.ref_count && wgi_state.initialized) { + int ii; + for (ii = 0; ii < wgi_state.per_gamepad_count; ii++) { + __x_ABI_CWindows_CGaming_CInput_CIGamepad_Release(wgi_state.per_gamepad[ii]->gamepad); + } + if (wgi_state.per_gamepad) { + SDL_free(wgi_state.per_gamepad); + wgi_state.per_gamepad = NULL; + } + wgi_state.per_gamepad_count = 0; + if (wgi_state.gamepad_statics) { + __x_ABI_CWindows_CGaming_CInput_CIGamepadStatics_remove_GamepadAdded(wgi_state.gamepad_statics, wgi_state.gamepad_added_token); + __x_ABI_CWindows_CGaming_CInput_CIGamepadStatics_remove_GamepadRemoved(wgi_state.gamepad_statics, wgi_state.gamepad_removed_token); + __x_ABI_CWindows_CGaming_CInput_CIGamepadStatics_Release(wgi_state.gamepad_statics); + wgi_state.gamepad_statics = NULL; + } + WIN_RoUninitialize(); + wgi_state.initialized = SDL_FALSE; + } +} + +#endif /* SDL_JOYSTICK_RAWINPUT_WGI */ + +static SDL_RAWINPUT_Device *RAWINPUT_AcquireDevice(SDL_RAWINPUT_Device *device) +{ + SDL_AtomicIncRef(&device->refcount); + return device; +} + +static void RAWINPUT_ReleaseDevice(SDL_RAWINPUT_Device *device) +{ +#ifdef SDL_JOYSTICK_RAWINPUT_XINPUT + if (device->joystick) { + RAWINPUT_DeviceContext *ctx = device->joystick->hwdata; + + if (ctx->xinput_enabled && ctx->xinput_correlated) { + RAWINPUT_MarkXInputSlotFree(ctx->xinput_slot); + ctx->xinput_correlated = SDL_FALSE; + } + } +#endif /* SDL_JOYSTICK_RAWINPUT_XINPUT */ + + if (SDL_AtomicDecRef(&device->refcount)) { + SDL_free(device->preparsed_data); + SDL_free(device->name); + SDL_free(device->path); + SDL_free(device); + } +} + +static SDL_RAWINPUT_Device *RAWINPUT_DeviceFromHandle(HANDLE hDevice) +{ + SDL_RAWINPUT_Device *curr; + + for (curr = SDL_RAWINPUT_devices; curr; curr = curr->next) { + if (curr->hDevice == hDevice) { + return curr; + } + } + return NULL; +} + +static int GetSteamVirtualGamepadSlot(Uint16 vendor_id, Uint16 product_id, const char *device_path) +{ + int slot = -1; + + // The format for the raw input device path is documented here: + // https://partner.steamgames.com/doc/features/steam_controller/steam_input_gamepad_emulation_bestpractices + if (vendor_id == USB_VENDOR_VALVE && + product_id == USB_PRODUCT_STEAM_VIRTUAL_GAMEPAD) { + (void)SDL_sscanf(device_path, "\\\\.\\pipe\\HID#VID_045E&PID_028E&IG_00#%*X&%*X&%*X#%d#%*u", &slot); + } + return slot; +} + +static void RAWINPUT_AddDevice(HANDLE hDevice) +{ +#define CHECK(expression) \ + { \ + if (!(expression)) \ + goto err; \ + } + SDL_RAWINPUT_Device *device = NULL; + SDL_RAWINPUT_Device *curr, *last; + RID_DEVICE_INFO rdi; + UINT size; + char dev_name[MAX_PATH]; + HANDLE hFile = INVALID_HANDLE_VALUE; + + /* Make sure we're not trying to add the same device twice */ + if (RAWINPUT_DeviceFromHandle(hDevice)) { + return; + } + + /* Figure out what kind of device it is */ + size = sizeof(rdi); + CHECK(GetRawInputDeviceInfoA(hDevice, RIDI_DEVICEINFO, &rdi, &size) != (UINT)-1); + CHECK(rdi.dwType == RIM_TYPEHID); + + /* Get the device "name" (HID Path) */ + size = SDL_arraysize(dev_name); + CHECK(GetRawInputDeviceInfoA(hDevice, RIDI_DEVICENAME, dev_name, &size) != (UINT)-1); + /* Only take XInput-capable devices */ + CHECK(SDL_strstr(dev_name, "IG_") != NULL); +#ifdef SDL_JOYSTICK_HIDAPI + /* Don't take devices handled by HIDAPI */ + CHECK(!HIDAPI_IsDevicePresent((Uint16)rdi.hid.dwVendorId, (Uint16)rdi.hid.dwProductId, (Uint16)rdi.hid.dwVersionNumber, "")); +#endif + device = (SDL_RAWINPUT_Device *)SDL_calloc(1, sizeof(SDL_RAWINPUT_Device)); + CHECK(device); + device->hDevice = hDevice; + device->vendor_id = (Uint16)rdi.hid.dwVendorId; + device->product_id = (Uint16)rdi.hid.dwProductId; + device->version = (Uint16)rdi.hid.dwVersionNumber; + device->is_xinput = SDL_TRUE; + device->is_xboxone = SDL_IsJoystickXboxOne(device->vendor_id, device->product_id); + device->steam_virtual_gamepad_slot = GetSteamVirtualGamepadSlot(device->vendor_id, device->product_id, dev_name); + + /* Get HID Top-Level Collection Preparsed Data */ + size = 0; + CHECK(GetRawInputDeviceInfoA(hDevice, RIDI_PREPARSEDDATA, NULL, &size) != (UINT)-1); + device->preparsed_data = (PHIDP_PREPARSED_DATA)SDL_calloc(size, sizeof(BYTE)); + CHECK(device->preparsed_data); + CHECK(GetRawInputDeviceInfoA(hDevice, RIDI_PREPARSEDDATA, device->preparsed_data, &size) != (UINT)-1); + + hFile = CreateFileA(dev_name, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + CHECK(hFile != INVALID_HANDLE_VALUE); + + { + char *manufacturer_string = NULL; + char *product_string = NULL; + WCHAR string[128]; + + if (SDL_HidD_GetManufacturerString(hFile, string, sizeof(string))) { + manufacturer_string = WIN_StringToUTF8W(string); + } + if (SDL_HidD_GetProductString(hFile, string, sizeof(string))) { + product_string = WIN_StringToUTF8W(string); + } + + device->name = SDL_CreateJoystickName(device->vendor_id, device->product_id, manufacturer_string, product_string); + device->guid = SDL_CreateJoystickGUID(SDL_HARDWARE_BUS_USB, device->vendor_id, device->product_id, device->version, manufacturer_string, product_string, 'r', 0); + + if (manufacturer_string) { + SDL_free(manufacturer_string); + } + if (product_string) { + SDL_free(product_string); + } + } + + device->path = SDL_strdup(dev_name); + + CloseHandle(hFile); + hFile = INVALID_HANDLE_VALUE; + + device->joystick_id = SDL_GetNextJoystickInstanceID(); + +#ifdef DEBUG_RAWINPUT + SDL_Log("Adding RAWINPUT device '%s' VID 0x%.4x, PID 0x%.4x, version %d, handle 0x%.8x\n", device->name, device->vendor_id, device->product_id, device->version, device->hDevice); +#endif + + /* Add it to the list */ + RAWINPUT_AcquireDevice(device); + for (curr = SDL_RAWINPUT_devices, last = NULL; curr; last = curr, curr = curr->next) { + } + if (last) { + last->next = device; + } else { + SDL_RAWINPUT_devices = device; + } + + ++SDL_RAWINPUT_numjoysticks; + + SDL_PrivateJoystickAdded(device->joystick_id); + + return; + +err: + if (hFile != INVALID_HANDLE_VALUE) { + CloseHandle(hFile); + } + if (device) { + if (device->name) { + SDL_free(device->name); + } + if (device->path) { + SDL_free(device->path); + } + SDL_free(device); + } +#undef CHECK +} + +static void RAWINPUT_DelDevice(SDL_RAWINPUT_Device *device, SDL_bool send_event) +{ + SDL_RAWINPUT_Device *curr, *last; + for (curr = SDL_RAWINPUT_devices, last = NULL; curr; last = curr, curr = curr->next) { + if (curr == device) { + if (last) { + last->next = curr->next; + } else { + SDL_RAWINPUT_devices = curr->next; + } + --SDL_RAWINPUT_numjoysticks; + + SDL_PrivateJoystickRemoved(device->joystick_id); + +#ifdef DEBUG_RAWINPUT + SDL_Log("Removing RAWINPUT device '%s' VID 0x%.4x, PID 0x%.4x, version %d, handle %p\n", device->name, device->vendor_id, device->product_id, device->version, device->hDevice); +#endif + RAWINPUT_ReleaseDevice(device); + return; + } + } +} + +static void RAWINPUT_DetectDevices(void) +{ + UINT device_count = 0; + + if ((GetRawInputDeviceList(NULL, &device_count, sizeof(RAWINPUTDEVICELIST)) != -1) && device_count > 0) { + PRAWINPUTDEVICELIST devices = NULL; + UINT i; + + devices = (PRAWINPUTDEVICELIST)SDL_malloc(sizeof(RAWINPUTDEVICELIST) * device_count); + if (devices) { + device_count = GetRawInputDeviceList(devices, &device_count, sizeof(RAWINPUTDEVICELIST)); + if (device_count != (UINT)-1) { + for (i = 0; i < device_count; ++i) { + RAWINPUT_AddDevice(devices[i].hDevice); + } + } + SDL_free(devices); + } + } +} + +static void RAWINPUT_RemoveDevices(void) +{ + while (SDL_RAWINPUT_devices) { + RAWINPUT_DelDevice(SDL_RAWINPUT_devices, SDL_FALSE); + } + SDL_assert(SDL_RAWINPUT_numjoysticks == 0); +} + +static int RAWINPUT_JoystickInit(void) +{ + SDL_assert(!SDL_RAWINPUT_inited); + + if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_RAWINPUT, SDL_TRUE)) { + return 0; + } + + if (!WIN_IsWindowsVistaOrGreater()) { + /* According to bug 6400, this doesn't work on Windows XP */ + return -1; + } + + if (WIN_LoadHIDDLL() < 0) { + return -1; + } + + SDL_RAWINPUT_inited = SDL_TRUE; + + RAWINPUT_DetectDevices(); + + return 0; +} + +static int RAWINPUT_JoystickGetCount(void) +{ + return SDL_RAWINPUT_numjoysticks; +} + +SDL_bool RAWINPUT_IsEnabled() +{ + return SDL_RAWINPUT_inited && !SDL_RAWINPUT_remote_desktop; +} + +SDL_bool RAWINPUT_IsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name) +{ + SDL_RAWINPUT_Device *device; + + /* If we're being asked about a device, that means another API just detected one, so rescan */ +#ifdef SDL_JOYSTICK_RAWINPUT_XINPUT + xinput_device_change = SDL_TRUE; +#endif + + device = SDL_RAWINPUT_devices; + while (device) { + if (vendor_id == device->vendor_id && product_id == device->product_id) { + return SDL_TRUE; + } + + /* The Xbox 360 wireless controller shows up as product 0 in WGI. + Try to match it to a Raw Input device via name or known product ID. */ + if (vendor_id == device->vendor_id && product_id == 0 && + ((name && SDL_strstr(device->name, name) != NULL) || + (device->vendor_id == USB_VENDOR_MICROSOFT && + device->product_id == USB_PRODUCT_XBOX360_XUSB_CONTROLLER))) { + return SDL_TRUE; + } + + /* The Xbox One controller shows up as a hardcoded raw input VID/PID */ + if (name && SDL_strcmp(name, "Xbox One Game Controller") == 0 && + device->vendor_id == USB_VENDOR_MICROSOFT && + device->product_id == USB_PRODUCT_XBOX_ONE_XBOXGIP_CONTROLLER) { + return SDL_TRUE; + } + + device = device->next; + } + return SDL_FALSE; +} + +static void RAWINPUT_PostUpdate(void) +{ +#ifdef SDL_JOYSTICK_RAWINPUT_MATCHING + SDL_bool unmapped_guide_pressed = SDL_FALSE; + +#ifdef SDL_JOYSTICK_RAWINPUT_WGI + if (!wgi_state.dirty) { + int ii; + for (ii = 0; ii < wgi_state.per_gamepad_count; ii++) { + WindowsGamingInputGamepadState *gamepad_state = wgi_state.per_gamepad[ii]; + if (!gamepad_state->used && (gamepad_state->state.Buttons & GamepadButtons_GUIDE)) { + unmapped_guide_pressed = SDL_TRUE; + break; + } + } + } + wgi_state.dirty = SDL_TRUE; +#endif + +#ifdef SDL_JOYSTICK_RAWINPUT_XINPUT + if (!xinput_state_dirty) { + int ii; + for (ii = 0; ii < SDL_arraysize(xinput_state); ii++) { + if (xinput_state[ii].connected && !xinput_state[ii].used && (xinput_state[ii].state.Gamepad.wButtons & XINPUT_GAMEPAD_GUIDE)) { + unmapped_guide_pressed = SDL_TRUE; + break; + } + } + } + xinput_state_dirty = SDL_TRUE; +#endif + + if (unmapped_guide_pressed) { + if (guide_button_candidate.joystick && !guide_button_candidate.last_joystick) { + SDL_Joystick *joystick = guide_button_candidate.joystick; + RAWINPUT_DeviceContext *ctx = joystick->hwdata; + if (ctx->guide_hack) { + int guide_button = joystick->nbuttons - 1; + + SDL_PrivateJoystickButton(guide_button_candidate.joystick, guide_button, SDL_PRESSED); + } + guide_button_candidate.last_joystick = guide_button_candidate.joystick; + } + } else if (guide_button_candidate.last_joystick) { + SDL_Joystick *joystick = guide_button_candidate.last_joystick; + RAWINPUT_DeviceContext *ctx = joystick->hwdata; + if (ctx->guide_hack) { + int guide_button = joystick->nbuttons - 1; + + SDL_PrivateJoystickButton(joystick, guide_button, SDL_RELEASED); + } + guide_button_candidate.last_joystick = NULL; + } + guide_button_candidate.joystick = NULL; + +#endif /* SDL_JOYSTICK_RAWINPUT_MATCHING */ +} + +static void RAWINPUT_JoystickDetect(void) +{ + SDL_bool remote_desktop; + + if (!SDL_RAWINPUT_inited) { + return; + } + + remote_desktop = GetSystemMetrics(SM_REMOTESESSION) ? SDL_TRUE : SDL_FALSE; + if (remote_desktop != SDL_RAWINPUT_remote_desktop) { + SDL_RAWINPUT_remote_desktop = remote_desktop; + + WINDOWS_RAWINPUTEnabledChanged(); + + if (remote_desktop) { + RAWINPUT_RemoveDevices(); + WINDOWS_JoystickDetect(); + } else { + WINDOWS_JoystickDetect(); + RAWINPUT_DetectDevices(); + } + } + RAWINPUT_PostUpdate(); +} + +static SDL_RAWINPUT_Device *RAWINPUT_GetDeviceByIndex(int device_index) +{ + SDL_RAWINPUT_Device *device = SDL_RAWINPUT_devices; + while (device) { + if (device_index == 0) { + break; + } + --device_index; + device = device->next; + } + return device; +} + +static const char *RAWINPUT_JoystickGetDeviceName(int device_index) +{ + return RAWINPUT_GetDeviceByIndex(device_index)->name; +} + +static const char *RAWINPUT_JoystickGetDevicePath(int device_index) +{ + return RAWINPUT_GetDeviceByIndex(device_index)->path; +} + +static int RAWINPUT_JoystickGetDeviceSteamVirtualGamepadSlot(int device_index) +{ + return RAWINPUT_GetDeviceByIndex(device_index)->steam_virtual_gamepad_slot; +} + +static int RAWINPUT_JoystickGetDevicePlayerIndex(int device_index) +{ + return -1; +} + +static void RAWINPUT_JoystickSetDevicePlayerIndex(int device_index, int player_index) +{ +} + +static SDL_JoystickGUID RAWINPUT_JoystickGetDeviceGUID(int device_index) +{ + return RAWINPUT_GetDeviceByIndex(device_index)->guid; +} + +static SDL_JoystickID RAWINPUT_JoystickGetDeviceInstanceID(int device_index) +{ + return RAWINPUT_GetDeviceByIndex(device_index)->joystick_id; +} + +static int SDLCALL RAWINPUT_SortValueCaps(const void *A, const void *B) +{ + HIDP_VALUE_CAPS *capsA = (HIDP_VALUE_CAPS *)A; + HIDP_VALUE_CAPS *capsB = (HIDP_VALUE_CAPS *)B; + + /* Sort by Usage for single values, or UsageMax for range of values */ + return (int)capsA->NotRange.Usage - capsB->NotRange.Usage; +} + +static int RAWINPUT_JoystickOpen(SDL_Joystick *joystick, int device_index) +{ + SDL_RAWINPUT_Device *device = RAWINPUT_GetDeviceByIndex(device_index); + RAWINPUT_DeviceContext *ctx; + HIDP_CAPS caps; + HIDP_BUTTON_CAPS *button_caps; + HIDP_VALUE_CAPS *value_caps; + ULONG i; + + ctx = (RAWINPUT_DeviceContext *)SDL_calloc(1, sizeof(RAWINPUT_DeviceContext)); + if (!ctx) { + return SDL_OutOfMemory(); + } + joystick->hwdata = ctx; + + ctx->device = RAWINPUT_AcquireDevice(device); + device->joystick = joystick; + + if (device->is_xinput) { + /* We'll try to get guide button and trigger axes from XInput */ +#ifdef SDL_JOYSTICK_RAWINPUT_XINPUT + xinput_device_change = SDL_TRUE; + ctx->xinput_enabled = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_RAWINPUT_CORRELATE_XINPUT, SDL_TRUE); + if (ctx->xinput_enabled && (WIN_LoadXInputDLL() < 0 || !XINPUTGETSTATE)) { + ctx->xinput_enabled = SDL_FALSE; + } + ctx->xinput_slot = XUSER_INDEX_ANY; +#endif +#ifdef SDL_JOYSTICK_RAWINPUT_WGI + RAWINPUT_InitWindowsGamingInput(ctx); +#endif + } + + ctx->is_xinput = device->is_xinput; + ctx->is_xboxone = device->is_xboxone; +#ifdef SDL_JOYSTICK_RAWINPUT_MATCHING + ctx->match_state = 0x0000008800000000ULL; /* Trigger axes at rest */ +#endif + ctx->preparsed_data = device->preparsed_data; + ctx->max_data_length = SDL_HidP_MaxDataListLength(HidP_Input, ctx->preparsed_data); + ctx->data = (HIDP_DATA *)SDL_malloc(ctx->max_data_length * sizeof(*ctx->data)); + if (!ctx->data) { + RAWINPUT_JoystickClose(joystick); + return SDL_OutOfMemory(); + } + + if (SDL_HidP_GetCaps(ctx->preparsed_data, &caps) != HIDP_STATUS_SUCCESS) { + RAWINPUT_JoystickClose(joystick); + return SDL_SetError("Couldn't get device capabilities"); + } + + button_caps = SDL_stack_alloc(HIDP_BUTTON_CAPS, caps.NumberInputButtonCaps); + if (SDL_HidP_GetButtonCaps(HidP_Input, button_caps, &caps.NumberInputButtonCaps, ctx->preparsed_data) != HIDP_STATUS_SUCCESS) { + RAWINPUT_JoystickClose(joystick); + return SDL_SetError("Couldn't get device button capabilities"); + } + + value_caps = SDL_stack_alloc(HIDP_VALUE_CAPS, caps.NumberInputValueCaps); + if (SDL_HidP_GetValueCaps(HidP_Input, value_caps, &caps.NumberInputValueCaps, ctx->preparsed_data) != HIDP_STATUS_SUCCESS) { + RAWINPUT_JoystickClose(joystick); + return SDL_SetError("Couldn't get device value capabilities"); + } + + /* Sort the axes by usage, so X comes before Y, etc. */ + SDL_qsort(value_caps, caps.NumberInputValueCaps, sizeof(*value_caps), RAWINPUT_SortValueCaps); + + for (i = 0; i < caps.NumberInputButtonCaps; ++i) { + HIDP_BUTTON_CAPS *cap = &button_caps[i]; + + if (cap->UsagePage == USB_USAGEPAGE_BUTTON) { + int count; + + if (cap->IsRange) { + count = 1 + (cap->Range.DataIndexMax - cap->Range.DataIndexMin); + } else { + count = 1; + } + + joystick->nbuttons += count; + } + } + + if (joystick->nbuttons > 0) { + int button_index = 0; + + ctx->button_indices = (USHORT *)SDL_malloc(joystick->nbuttons * sizeof(*ctx->button_indices)); + if (!ctx->button_indices) { + RAWINPUT_JoystickClose(joystick); + return SDL_OutOfMemory(); + } + + for (i = 0; i < caps.NumberInputButtonCaps; ++i) { + HIDP_BUTTON_CAPS *cap = &button_caps[i]; + + if (cap->UsagePage == USB_USAGEPAGE_BUTTON) { + if (cap->IsRange) { + int j, count = 1 + (cap->Range.DataIndexMax - cap->Range.DataIndexMin); + + for (j = 0; j < count; ++j) { + ctx->button_indices[button_index++] = cap->Range.DataIndexMin + j; + } + } else { + ctx->button_indices[button_index++] = cap->NotRange.DataIndex; + } + } + } + } + if (ctx->is_xinput && joystick->nbuttons == 10) { + ctx->guide_hack = SDL_TRUE; + joystick->nbuttons += 1; + } + + for (i = 0; i < caps.NumberInputValueCaps; ++i) { + HIDP_VALUE_CAPS *cap = &value_caps[i]; + + if (cap->IsRange) { + continue; + } + + if (ctx->trigger_hack && cap->NotRange.Usage == USB_USAGE_GENERIC_Z) { + continue; + } + + if (cap->NotRange.Usage == USB_USAGE_GENERIC_HAT) { + joystick->nhats += 1; + continue; + } + + if (ctx->is_xinput && cap->NotRange.Usage == USB_USAGE_GENERIC_Z) { + continue; + } + + joystick->naxes += 1; + } + + if (joystick->naxes > 0) { + int axis_index = 0; + + ctx->axis_indices = (USHORT *)SDL_malloc(joystick->naxes * sizeof(*ctx->axis_indices)); + if (!ctx->axis_indices) { + RAWINPUT_JoystickClose(joystick); + return SDL_OutOfMemory(); + } + + for (i = 0; i < caps.NumberInputValueCaps; ++i) { + HIDP_VALUE_CAPS *cap = &value_caps[i]; + + if (cap->IsRange) { + continue; + } + + if (cap->NotRange.Usage == USB_USAGE_GENERIC_HAT) { + continue; + } + + if (ctx->is_xinput && cap->NotRange.Usage == USB_USAGE_GENERIC_Z) { + ctx->trigger_hack = SDL_TRUE; + ctx->trigger_hack_index = cap->NotRange.DataIndex; + continue; + } + + ctx->axis_indices[axis_index++] = cap->NotRange.DataIndex; + } + } + if (ctx->trigger_hack) { + joystick->naxes += 2; + } + + if (joystick->nhats > 0) { + int hat_index = 0; + + ctx->hat_indices = (USHORT *)SDL_malloc(joystick->nhats * sizeof(*ctx->hat_indices)); + if (!ctx->hat_indices) { + RAWINPUT_JoystickClose(joystick); + return SDL_OutOfMemory(); + } + + for (i = 0; i < caps.NumberInputValueCaps; ++i) { + HIDP_VALUE_CAPS *cap = &value_caps[i]; + + if (cap->IsRange) { + continue; + } + + if (cap->NotRange.Usage != USB_USAGE_GENERIC_HAT) { + continue; + } + + ctx->hat_indices[hat_index++] = cap->NotRange.DataIndex; + } + } + + joystick->epowerlevel = SDL_JOYSTICK_POWER_UNKNOWN; + + return 0; +} + +static int RAWINPUT_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ +#if defined(SDL_JOYSTICK_RAWINPUT_WGI) || defined(SDL_JOYSTICK_RAWINPUT_XINPUT) + RAWINPUT_DeviceContext *ctx = joystick->hwdata; +#endif + SDL_bool rumbled = SDL_FALSE; + +#ifdef SDL_JOYSTICK_RAWINPUT_XINPUT + /* Prefer XInput over WGI because it allows rumble in the background */ + if (!rumbled && ctx->xinput_correlated) { + XINPUT_VIBRATION XVibration; + + if (!XINPUTSETSTATE) { + return SDL_Unsupported(); + } + + XVibration.wLeftMotorSpeed = low_frequency_rumble; + XVibration.wRightMotorSpeed = high_frequency_rumble; + if (XINPUTSETSTATE(ctx->xinput_slot, &XVibration) == ERROR_SUCCESS) { + rumbled = SDL_TRUE; + } else { + return SDL_SetError("XInputSetState() failed"); + } + } +#endif /* SDL_JOYSTICK_RAWINPUT_XINPUT */ + +#ifdef SDL_JOYSTICK_RAWINPUT_WGI + if (!rumbled && ctx->wgi_correlated) { + WindowsGamingInputGamepadState *gamepad_state = ctx->wgi_slot; + HRESULT hr; + gamepad_state->vibration.LeftMotor = (DOUBLE)low_frequency_rumble / SDL_MAX_UINT16; + gamepad_state->vibration.RightMotor = (DOUBLE)high_frequency_rumble / SDL_MAX_UINT16; + hr = __x_ABI_CWindows_CGaming_CInput_CIGamepad_put_Vibration(gamepad_state->gamepad, gamepad_state->vibration); + if (SUCCEEDED(hr)) { + rumbled = SDL_TRUE; + } + } +#endif + + if (!rumbled) { +#if defined(SDL_JOYSTICK_RAWINPUT_WGI) || defined(SDL_JOYSTICK_RAWINPUT_XINPUT) + return SDL_SetError("Controller isn't correlated yet, try hitting a button first"); +#else + return SDL_Unsupported(); +#endif + } + return 0; +} + +static int RAWINPUT_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) +{ +#if defined(SDL_JOYSTICK_RAWINPUT_WGI) + RAWINPUT_DeviceContext *ctx = joystick->hwdata; + + if (ctx->wgi_correlated) { + WindowsGamingInputGamepadState *gamepad_state = ctx->wgi_slot; + HRESULT hr; + gamepad_state->vibration.LeftTrigger = (DOUBLE)left_rumble / SDL_MAX_UINT16; + gamepad_state->vibration.RightTrigger = (DOUBLE)right_rumble / SDL_MAX_UINT16; + hr = __x_ABI_CWindows_CGaming_CInput_CIGamepad_put_Vibration(gamepad_state->gamepad, gamepad_state->vibration); + if (!SUCCEEDED(hr)) { + return SDL_SetError("Setting vibration failed: 0x%lx\n", hr); + } + return 0; + } else { + return SDL_SetError("Controller isn't correlated yet, try hitting a button first"); + } +#else + return SDL_Unsupported(); +#endif +} + +static Uint32 RAWINPUT_JoystickGetCapabilities(SDL_Joystick *joystick) +{ + Uint32 result = 0; +#if defined(SDL_JOYSTICK_RAWINPUT_XINPUT) || defined(SDL_JOYSTICK_RAWINPUT_WGI) + RAWINPUT_DeviceContext *ctx = joystick->hwdata; + +#ifdef SDL_JOYSTICK_RAWINPUT_XINPUT + if (ctx->is_xinput) { + result |= SDL_JOYCAP_RUMBLE; + } +#endif +#ifdef SDL_JOYSTICK_RAWINPUT_WGI + if (ctx->is_xinput) { + result |= SDL_JOYCAP_RUMBLE; + + if (ctx->is_xboxone) { + result |= SDL_JOYCAP_RUMBLE_TRIGGERS; + } + } +#endif +#endif /**/ + + return result; +} + +static int RAWINPUT_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + return SDL_Unsupported(); +} + +static int RAWINPUT_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + +static int RAWINPUT_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled) +{ + return SDL_Unsupported(); +} + +static HIDP_DATA *GetData(USHORT index, HIDP_DATA *data, ULONG length) +{ + ULONG i; + + /* Check to see if the data is at the expected offset */ + if (index < length && data[index].DataIndex == index) { + return &data[index]; + } + + /* Loop through the data to find it */ + for (i = 0; i < length; ++i) { + if (data[i].DataIndex == index) { + return &data[i]; + } + } + return NULL; +} + +/* This is the packet format for Xbox 360 and Xbox One controllers on Windows, + however with this interface there is no rumble support, no guide button, + and the left and right triggers are tied together as a single axis. + + We use XInput and Windows.Gaming.Input to make up for these shortcomings. + */ +static void RAWINPUT_HandleStatePacket(SDL_Joystick *joystick, Uint8 *data, int size) +{ + RAWINPUT_DeviceContext *ctx = joystick->hwdata; +#ifdef SDL_JOYSTICK_RAWINPUT_MATCHING + /* Map new buttons and axes into game controller controls */ + static const int button_map[] = { + SDL_CONTROLLER_BUTTON_A, + SDL_CONTROLLER_BUTTON_B, + SDL_CONTROLLER_BUTTON_X, + SDL_CONTROLLER_BUTTON_Y, + SDL_CONTROLLER_BUTTON_LEFTSHOULDER, + SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, + SDL_CONTROLLER_BUTTON_BACK, + SDL_CONTROLLER_BUTTON_START, + SDL_CONTROLLER_BUTTON_LEFTSTICK, + SDL_CONTROLLER_BUTTON_RIGHTSTICK + }; +#define HAT_MASK ((1 << SDL_CONTROLLER_BUTTON_DPAD_UP) | (1 << SDL_CONTROLLER_BUTTON_DPAD_DOWN) | (1 << SDL_CONTROLLER_BUTTON_DPAD_LEFT) | (1 << SDL_CONTROLLER_BUTTON_DPAD_RIGHT)) + static const int hat_map[] = { + 0, + (1 << SDL_CONTROLLER_BUTTON_DPAD_UP), + (1 << SDL_CONTROLLER_BUTTON_DPAD_UP) | (1 << SDL_CONTROLLER_BUTTON_DPAD_RIGHT), + (1 << SDL_CONTROLLER_BUTTON_DPAD_RIGHT), + (1 << SDL_CONTROLLER_BUTTON_DPAD_DOWN) | (1 << SDL_CONTROLLER_BUTTON_DPAD_RIGHT), + (1 << SDL_CONTROLLER_BUTTON_DPAD_DOWN), + (1 << SDL_CONTROLLER_BUTTON_DPAD_DOWN) | (1 << SDL_CONTROLLER_BUTTON_DPAD_LEFT), + (1 << SDL_CONTROLLER_BUTTON_DPAD_LEFT), + (1 << SDL_CONTROLLER_BUTTON_DPAD_UP) | (1 << SDL_CONTROLLER_BUTTON_DPAD_LEFT), + 0, + }; + Uint64 match_state = ctx->match_state; + /* Update match_state with button bit, then fall through */ +#define SDL_PrivateJoystickButton(joystick, button, state) \ + if (button < SDL_arraysize(button_map)) { \ + Uint64 button_bit = 1ull << button_map[button]; \ + match_state = (match_state & ~button_bit) | (button_bit * (state)); \ + } \ + SDL_PrivateJoystickButton(joystick, button, state) +#ifdef SDL_JOYSTICK_RAWINPUT_MATCH_AXES + /* Grab high 4 bits of value, then fall through */ +#define AddAxisToMatchState(axis, value) \ + { \ + match_state = (match_state & ~(0xFull << (4 * axis + 16))) | ((value)&0xF000ull) << (4 * axis + 4); \ + } +#define SDL_PrivateJoystickAxis(joystick, axis, value) \ + if (axis < 4) \ + AddAxisToMatchState(axis, value); \ + SDL_PrivateJoystickAxis(joystick, axis, value) +#endif +#endif /* SDL_JOYSTICK_RAWINPUT_MATCHING */ + + ULONG data_length = ctx->max_data_length; + int i; + int nbuttons = joystick->nbuttons - (ctx->guide_hack * 1); + int naxes = joystick->naxes - (ctx->trigger_hack * 2); + int nhats = joystick->nhats; + Uint32 button_mask = 0; + + if (SDL_HidP_GetData(HidP_Input, ctx->data, &data_length, ctx->preparsed_data, (PCHAR)data, size) != HIDP_STATUS_SUCCESS) { + return; + } + + for (i = 0; i < nbuttons; ++i) { + HIDP_DATA *item = GetData(ctx->button_indices[i], ctx->data, data_length); + if (item && item->On) { + button_mask |= (1 << i); + } + } + for (i = 0; i < nbuttons; ++i) { + SDL_PrivateJoystickButton(joystick, i, (button_mask & (1 << i)) ? SDL_PRESSED : SDL_RELEASED); + } + + for (i = 0; i < naxes; ++i) { + HIDP_DATA *item = GetData(ctx->axis_indices[i], ctx->data, data_length); + if (item) { + Sint16 axis = (int)(Uint16)item->RawValue - 0x8000; + SDL_PrivateJoystickAxis(joystick, i, axis); + } + } + + for (i = 0; i < nhats; ++i) { + HIDP_DATA *item = GetData(ctx->hat_indices[i], ctx->data, data_length); + if (item) { + Uint8 hat = SDL_HAT_CENTERED; + const Uint8 hat_states[] = { + SDL_HAT_CENTERED, + SDL_HAT_UP, + SDL_HAT_UP | SDL_HAT_RIGHT, + SDL_HAT_RIGHT, + SDL_HAT_DOWN | SDL_HAT_RIGHT, + SDL_HAT_DOWN, + SDL_HAT_DOWN | SDL_HAT_LEFT, + SDL_HAT_LEFT, + SDL_HAT_UP | SDL_HAT_LEFT, + SDL_HAT_CENTERED, + }; + ULONG state = item->RawValue; + + if (state < SDL_arraysize(hat_states)) { +#ifdef SDL_JOYSTICK_RAWINPUT_MATCHING + match_state = (match_state & ~HAT_MASK) | hat_map[state]; +#endif + hat = hat_states[state]; + } + SDL_PrivateJoystickHat(joystick, i, hat); + } + } + +#ifdef SDL_PrivateJoystickButton +#undef SDL_PrivateJoystickButton +#endif +#ifdef SDL_PrivateJoystickAxis +#undef SDL_PrivateJoystickAxis +#endif + +#ifdef SDL_JOYSTICK_RAWINPUT_MATCH_TRIGGERS +#define AddTriggerToMatchState(axis, value) \ + { \ + int match_axis = axis + SDL_JOYSTICK_RAWINPUT_MATCH_COUNT - joystick->naxes; \ + AddAxisToMatchState(match_axis, value); \ + } +#endif /* SDL_JOYSTICK_RAWINPUT_MATCH_TRIGGERS */ + + if (ctx->trigger_hack) { + SDL_bool has_trigger_data = SDL_FALSE; + int left_trigger = joystick->naxes - 2; + int right_trigger = joystick->naxes - 1; + +#ifdef SDL_JOYSTICK_RAWINPUT_XINPUT + /* Prefer XInput over WindowsGamingInput, it continues to provide data in the background */ + if (!has_trigger_data && ctx->xinput_enabled && ctx->xinput_correlated) { + has_trigger_data = SDL_TRUE; + } +#endif /* SDL_JOYSTICK_RAWINPUT_XINPUT */ + +#ifdef SDL_JOYSTICK_RAWINPUT_WGI + if (!has_trigger_data && ctx->wgi_correlated) { + has_trigger_data = SDL_TRUE; + } +#endif /* SDL_JOYSTICK_RAWINPUT_WGI */ + +#ifndef SDL_JOYSTICK_RAWINPUT_MATCH_TRIGGERS + if (!has_trigger_data) +#endif + { + HIDP_DATA *item = GetData(ctx->trigger_hack_index, ctx->data, data_length); + if (item) { + Sint16 value = (int)(Uint16)item->RawValue - 0x8000; + Sint16 left_value = (value > 0) ? (value * 2 - 32767) : SDL_MIN_SINT16; + Sint16 right_value = (value < 0) ? (-value * 2 - 32769) : SDL_MIN_SINT16; + +#ifdef SDL_JOYSTICK_RAWINPUT_MATCH_TRIGGERS + AddTriggerToMatchState(left_trigger, left_value); + AddTriggerToMatchState(right_trigger, right_value); + if (!has_trigger_data) +#endif /* SDL_JOYSTICK_RAWINPUT_MATCH_TRIGGERS */ + { + SDL_PrivateJoystickAxis(joystick, left_trigger, left_value); + SDL_PrivateJoystickAxis(joystick, right_trigger, right_value); + } + } + } + } + +#ifdef AddAxisToMatchState +#undef AddAxisToMatchState +#endif +#ifdef AddTriggerToMatchState +#undef AddTriggerToMatchState +#endif + +#ifdef SDL_JOYSTICK_RAWINPUT_MATCHING + if (ctx->is_xinput) { + ctx->match_state = match_state; + ctx->last_state_packet = SDL_GetTicks(); + } +#endif +} + +static void RAWINPUT_UpdateOtherAPIs(SDL_Joystick *joystick) +{ +#ifdef SDL_JOYSTICK_RAWINPUT_MATCHING + RAWINPUT_DeviceContext *ctx = joystick->hwdata; + SDL_bool has_trigger_data = SDL_FALSE; + SDL_bool correlated = SDL_FALSE; + WindowsMatchState match_state_xinput; + int guide_button = joystick->nbuttons - 1; + int left_trigger = joystick->naxes - 2; + int right_trigger = joystick->naxes - 1; +#ifdef SDL_JOYSTICK_RAWINPUT_WGI + SDL_bool xinput_correlated; +#endif + + RAWINPUT_FillMatchState(&match_state_xinput, ctx->match_state); + +#ifdef SDL_JOYSTICK_RAWINPUT_WGI +#ifdef SDL_JOYSTICK_RAWINPUT_XINPUT + xinput_correlated = ctx->xinput_correlated; +#else + xinput_correlated = SDL_FALSE; +#endif + /* Parallel logic to WINDOWS_XINPUT below */ + RAWINPUT_UpdateWindowsGamingInput(); + if (ctx->wgi_correlated && + !joystick->low_frequency_rumble && !joystick->high_frequency_rumble && + !joystick->left_trigger_rumble && !joystick->right_trigger_rumble) { + /* We have been previously correlated, ensure we are still matching, see comments in XINPUT section */ + if (RAWINPUT_WindowsGamingInputSlotMatches(&match_state_xinput, ctx->wgi_slot, xinput_correlated)) { + ctx->wgi_uncorrelate_count = 0; + } else { + ++ctx->wgi_uncorrelate_count; + /* Only un-correlate if this is consistent over multiple Update() calls - the timing of polling/event + pumping can easily cause this to uncorrelate for a frame. 2 seemed reliable in my testing, but + let's set it to 5 to be safe. An incorrect un-correlation will simply result in lower precision + triggers for a frame. */ + if (ctx->wgi_uncorrelate_count >= 5) { +#ifdef DEBUG_RAWINPUT + SDL_Log("UN-Correlated joystick %d to WindowsGamingInput device #%d\n", joystick->instance_id, ctx->wgi_slot); +#endif + RAWINPUT_MarkWindowsGamingInputSlotFree(ctx->wgi_slot); + ctx->wgi_correlated = SDL_FALSE; + ctx->wgi_correlation_count = 0; + /* Force release of Guide button, it can't possibly be down on this device now. */ + /* It gets left down if we were actually correlated incorrectly and it was released on the WindowsGamingInput + device but we didn't get a state packet. */ + if (ctx->guide_hack) { + SDL_PrivateJoystickButton(joystick, guide_button, SDL_RELEASED); + } + } + } + } + if (!ctx->wgi_correlated) { + SDL_bool new_correlation_count = 0; + if (RAWINPUT_MissingWindowsGamingInputSlot()) { + Uint8 correlation_id = 0; + WindowsGamingInputGamepadState *slot_idx = NULL; + if (RAWINPUT_GuessWindowsGamingInputSlot(&match_state_xinput, &correlation_id, &slot_idx, xinput_correlated)) { + /* we match exactly one WindowsGamingInput device */ + /* Probably can do without wgi_correlation_count, just check and clear wgi_slot to NULL, unless we need + even more frames to be sure. */ + if (ctx->wgi_correlation_count && ctx->wgi_slot == slot_idx) { + /* was correlated previously, and still the same device */ + if (ctx->wgi_correlation_id + 1 == correlation_id) { + /* no one else was correlated in the meantime */ + new_correlation_count = ctx->wgi_correlation_count + 1; + if (new_correlation_count == 2) { + /* correlation stayed steady and uncontested across multiple frames, guaranteed match */ + ctx->wgi_correlated = SDL_TRUE; +#ifdef DEBUG_RAWINPUT + SDL_Log("Correlated joystick %d to WindowsGamingInput device #%d\n", joystick->instance_id, slot_idx); +#endif + correlated = SDL_TRUE; + RAWINPUT_MarkWindowsGamingInputSlotUsed(ctx->wgi_slot, ctx); + /* If the generalized Guide button was using us, it doesn't need to anymore */ + if (guide_button_candidate.joystick == joystick) { + guide_button_candidate.joystick = NULL; + } + if (guide_button_candidate.last_joystick == joystick) { + guide_button_candidate.last_joystick = NULL; + } + } + } else { + /* someone else also possibly correlated to this device, start over */ + new_correlation_count = 1; + } + } else { + /* new possible correlation */ + new_correlation_count = 1; + ctx->wgi_slot = slot_idx; + } + ctx->wgi_correlation_id = correlation_id; + } else { + /* Match multiple WindowsGamingInput devices, or none (possibly due to no buttons pressed) */ + } + } + ctx->wgi_correlation_count = new_correlation_count; + } else { + correlated = SDL_TRUE; + } +#endif /* SDL_JOYSTICK_RAWINPUT_WGI */ + +#ifdef SDL_JOYSTICK_RAWINPUT_XINPUT + /* Parallel logic to WINDOWS_GAMING_INPUT above */ + if (ctx->xinput_enabled) { + RAWINPUT_UpdateXInput(); + if (ctx->xinput_correlated && + !joystick->low_frequency_rumble && !joystick->high_frequency_rumble) { + /* We have been previously correlated, ensure we are still matching */ + /* This is required to deal with two (mostly) un-preventable mis-correlation situations: + A) Since the HID data stream does not provide an initial state (but polling XInput does), if we open + 5 controllers (#1-4 XInput mapped, #5 is not), and controller 1 had the A button down (and we don't + know), and the user presses A on controller #5, we'll see exactly 1 controller with A down (#5) and + exactly 1 XInput device with A down (#1), and incorrectly correlate. This code will then un-correlate + when A is released from either controller #1 or #5. + B) Since the app may not open all controllers, we could have a similar situation where only controller #5 + is opened, and the user holds A on controllers #1 and #5 simultaneously - again we see only 1 controller + with A down and 1 XInput device with A down, and incorrectly correlate. This should be very unusual + (only when apps do not open all controllers, yet are listening to Guide button presses, yet + for some reason want to ignore guide button presses on the un-opened controllers, yet users are + pressing buttons on the unopened controllers), and will resolve itself when either button is released + and we un-correlate. We could prevent this by processing the state packets for *all* controllers, + even un-opened ones, as that would allow more precise correlation. + */ + if (RAWINPUT_XInputSlotMatches(&match_state_xinput, ctx->xinput_slot)) { + ctx->xinput_uncorrelate_count = 0; + } else { + ++ctx->xinput_uncorrelate_count; + /* Only un-correlate if this is consistent over multiple Update() calls - the timing of polling/event + pumping can easily cause this to uncorrelate for a frame. 2 seemed reliable in my testing, but + let's set it to 5 to be safe. An incorrect un-correlation will simply result in lower precision + triggers for a frame. */ + if (ctx->xinput_uncorrelate_count >= 5) { +#ifdef DEBUG_RAWINPUT + SDL_Log("UN-Correlated joystick %d to XInput device #%d\n", joystick->instance_id, ctx->xinput_slot); +#endif + RAWINPUT_MarkXInputSlotFree(ctx->xinput_slot); + ctx->xinput_correlated = SDL_FALSE; + ctx->xinput_correlation_count = 0; + /* Force release of Guide button, it can't possibly be down on this device now. */ + /* It gets left down if we were actually correlated incorrectly and it was released on the XInput + device but we didn't get a state packet. */ + if (ctx->guide_hack) { + SDL_PrivateJoystickButton(joystick, guide_button, SDL_RELEASED); + } + } + } + } + if (!ctx->xinput_correlated) { + Uint8 new_correlation_count = 0; + if (RAWINPUT_MissingXInputSlot()) { + Uint8 correlation_id = 0; + Uint8 slot_idx = 0; + if (RAWINPUT_GuessXInputSlot(&match_state_xinput, &correlation_id, &slot_idx)) { + /* we match exactly one XInput device */ + /* Probably can do without xinput_correlation_count, just check and clear xinput_slot to ANY, unless + we need even more frames to be sure */ + if (ctx->xinput_correlation_count && ctx->xinput_slot == slot_idx) { + /* was correlated previously, and still the same device */ + if (ctx->xinput_correlation_id + 1 == correlation_id) { + /* no one else was correlated in the meantime */ + new_correlation_count = ctx->xinput_correlation_count + 1; + if (new_correlation_count == 2) { + /* correlation stayed steady and uncontested across multiple frames, guaranteed match */ + ctx->xinput_correlated = SDL_TRUE; +#ifdef DEBUG_RAWINPUT + SDL_Log("Correlated joystick %d to XInput device #%d\n", joystick->instance_id, slot_idx); +#endif + correlated = SDL_TRUE; + RAWINPUT_MarkXInputSlotUsed(ctx->xinput_slot); + /* If the generalized Guide button was using us, it doesn't need to anymore */ + if (guide_button_candidate.joystick == joystick) { + guide_button_candidate.joystick = NULL; + } + if (guide_button_candidate.last_joystick == joystick) { + guide_button_candidate.last_joystick = NULL; + } + } + } else { + /* someone else also possibly correlated to this device, start over */ + new_correlation_count = 1; + } + } else { + /* new possible correlation */ + new_correlation_count = 1; + ctx->xinput_slot = slot_idx; + } + ctx->xinput_correlation_id = correlation_id; + } else { + /* Match multiple XInput devices, or none (possibly due to no buttons pressed) */ + } + } + ctx->xinput_correlation_count = new_correlation_count; + } else { + correlated = SDL_TRUE; + } + } +#endif /* SDL_JOYSTICK_RAWINPUT_XINPUT */ + + /* Poll for trigger data once (not per-state-packet) */ +#ifdef SDL_JOYSTICK_RAWINPUT_XINPUT + /* Prefer XInput over WindowsGamingInput, it continues to provide data in the background */ + if (!has_trigger_data && ctx->xinput_enabled && ctx->xinput_correlated) { + RAWINPUT_UpdateXInput(); + if (xinput_state[ctx->xinput_slot].connected) { + XINPUT_BATTERY_INFORMATION_EX *battery_info = &xinput_state[ctx->xinput_slot].battery; + + if (ctx->guide_hack) { + SDL_PrivateJoystickButton(joystick, guide_button, (xinput_state[ctx->xinput_slot].state.Gamepad.wButtons & XINPUT_GAMEPAD_GUIDE) ? SDL_PRESSED : SDL_RELEASED); + } + if (ctx->trigger_hack) { + SDL_PrivateJoystickAxis(joystick, left_trigger, ((int)xinput_state[ctx->xinput_slot].state.Gamepad.bLeftTrigger * 257) - 32768); + SDL_PrivateJoystickAxis(joystick, right_trigger, ((int)xinput_state[ctx->xinput_slot].state.Gamepad.bRightTrigger * 257) - 32768); + } + has_trigger_data = SDL_TRUE; + + if (battery_info->BatteryType != BATTERY_TYPE_UNKNOWN && + battery_info->BatteryType != BATTERY_TYPE_DISCONNECTED) { + SDL_JoystickPowerLevel ePowerLevel = SDL_JOYSTICK_POWER_UNKNOWN; + if (battery_info->BatteryType == BATTERY_TYPE_WIRED) { + ePowerLevel = SDL_JOYSTICK_POWER_WIRED; + } else { + switch (battery_info->BatteryLevel) { + case BATTERY_LEVEL_EMPTY: + ePowerLevel = SDL_JOYSTICK_POWER_EMPTY; + break; + case BATTERY_LEVEL_LOW: + ePowerLevel = SDL_JOYSTICK_POWER_LOW; + break; + case BATTERY_LEVEL_MEDIUM: + ePowerLevel = SDL_JOYSTICK_POWER_MEDIUM; + break; + default: + case BATTERY_LEVEL_FULL: + ePowerLevel = SDL_JOYSTICK_POWER_FULL; + break; + } + } + SDL_PrivateJoystickBatteryLevel(joystick, ePowerLevel); + } + } + } +#endif /* SDL_JOYSTICK_RAWINPUT_XINPUT */ + +#ifdef SDL_JOYSTICK_RAWINPUT_WGI + if (!has_trigger_data && ctx->wgi_correlated) { + RAWINPUT_UpdateWindowsGamingInput(); /* May detect disconnect / cause uncorrelation */ + if (ctx->wgi_correlated) { /* Still connected */ + struct __x_ABI_CWindows_CGaming_CInput_CGamepadReading *state = &ctx->wgi_slot->state; + + if (ctx->guide_hack) { + SDL_PrivateJoystickButton(joystick, guide_button, (state->Buttons & GamepadButtons_GUIDE) ? SDL_PRESSED : SDL_RELEASED); + } + if (ctx->trigger_hack) { + SDL_PrivateJoystickAxis(joystick, left_trigger, ((int)(state->LeftTrigger * SDL_MAX_UINT16)) - 32768); + SDL_PrivateJoystickAxis(joystick, right_trigger, ((int)(state->RightTrigger * SDL_MAX_UINT16)) - 32768); + } + has_trigger_data = SDL_TRUE; + } + } +#endif /* SDL_JOYSTICK_RAWINPUT_WGI */ + + if (!correlated) { + if (!guide_button_candidate.joystick || + (ctx->last_state_packet && (!guide_button_candidate.last_state_packet || + SDL_TICKS_PASSED(ctx->last_state_packet, guide_button_candidate.last_state_packet)))) { + guide_button_candidate.joystick = joystick; + guide_button_candidate.last_state_packet = ctx->last_state_packet; + } + } +#endif /* SDL_JOYSTICK_RAWINPUT_MATCHING */ +} + +static void RAWINPUT_JoystickUpdate(SDL_Joystick *joystick) +{ + RAWINPUT_UpdateOtherAPIs(joystick); +} + +static void RAWINPUT_JoystickClose(SDL_Joystick *joystick) +{ + RAWINPUT_DeviceContext *ctx = joystick->hwdata; + +#ifdef SDL_JOYSTICK_RAWINPUT_MATCHING + if (guide_button_candidate.joystick == joystick) { + guide_button_candidate.joystick = NULL; + } + if (guide_button_candidate.last_joystick == joystick) { + guide_button_candidate.last_joystick = NULL; + } +#endif + + if (ctx) { + SDL_RAWINPUT_Device *device; + +#ifdef SDL_JOYSTICK_RAWINPUT_XINPUT + xinput_device_change = SDL_TRUE; + if (ctx->xinput_enabled) { + if (ctx->xinput_correlated) { + RAWINPUT_MarkXInputSlotFree(ctx->xinput_slot); + } + WIN_UnloadXInputDLL(); + } +#endif +#ifdef SDL_JOYSTICK_RAWINPUT_WGI + RAWINPUT_QuitWindowsGamingInput(ctx); +#endif + + device = ctx->device; + if (device) { + SDL_assert(device->joystick == joystick); + device->joystick = NULL; + RAWINPUT_ReleaseDevice(device); + } + + SDL_free(ctx->data); + SDL_free(ctx->button_indices); + SDL_free(ctx->axis_indices); + SDL_free(ctx->hat_indices); + SDL_free(ctx); + joystick->hwdata = NULL; + } +} + +int RAWINPUT_RegisterNotifications(HWND hWnd) +{ + int i; + RAWINPUTDEVICE rid[SDL_arraysize(subscribed_devices)]; + + if (!SDL_RAWINPUT_inited) { + return 0; + } + + for (i = 0; i < SDL_arraysize(subscribed_devices); i++) { + rid[i].usUsagePage = USB_USAGEPAGE_GENERIC_DESKTOP; + rid[i].usUsage = subscribed_devices[i]; + rid[i].dwFlags = RIDEV_DEVNOTIFY | RIDEV_INPUTSINK; /* Receive messages when in background, including device add/remove */ + rid[i].hwndTarget = hWnd; + } + + if (!RegisterRawInputDevices(rid, SDL_arraysize(rid), sizeof(RAWINPUTDEVICE))) { + return SDL_SetError("Couldn't register for raw input events"); + } + return 0; +} + +int RAWINPUT_UnregisterNotifications() +{ + int i; + RAWINPUTDEVICE rid[SDL_arraysize(subscribed_devices)]; + + if (!SDL_RAWINPUT_inited) { + return 0; + } + + for (i = 0; i < SDL_arraysize(subscribed_devices); i++) { + rid[i].usUsagePage = USB_USAGEPAGE_GENERIC_DESKTOP; + rid[i].usUsage = subscribed_devices[i]; + rid[i].dwFlags = RIDEV_REMOVE; + rid[i].hwndTarget = NULL; + } + + if (!RegisterRawInputDevices(rid, SDL_arraysize(rid), sizeof(RAWINPUTDEVICE))) { + return SDL_SetError("Couldn't unregister for raw input events"); + } + return 0; +} + +LRESULT CALLBACK +RAWINPUT_WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + LRESULT result = -1; + + if (SDL_RAWINPUT_inited) { + SDL_LockJoysticks(); + + switch (msg) { + case WM_INPUT_DEVICE_CHANGE: + { + HANDLE hDevice = (HANDLE)lParam; + switch (wParam) { + case GIDC_ARRIVAL: + RAWINPUT_AddDevice(hDevice); + break; + case GIDC_REMOVAL: + { + SDL_RAWINPUT_Device *device; + device = RAWINPUT_DeviceFromHandle(hDevice); + if (device) { + RAWINPUT_DelDevice(device, SDL_TRUE); + } + break; + } + default: + break; + } + } + result = 0; + break; + + case WM_INPUT: + { + Uint8 data[sizeof(RAWINPUTHEADER) + sizeof(RAWHID) + USB_PACKET_LENGTH]; + UINT buffer_size = SDL_arraysize(data); + + if ((int)GetRawInputData((HRAWINPUT)lParam, RID_INPUT, data, &buffer_size, sizeof(RAWINPUTHEADER)) > 0) { + PRAWINPUT raw_input = (PRAWINPUT)data; + SDL_RAWINPUT_Device *device = RAWINPUT_DeviceFromHandle(raw_input->header.hDevice); + if (device) { + SDL_Joystick *joystick = device->joystick; + if (joystick) { + RAWINPUT_HandleStatePacket(joystick, raw_input->data.hid.bRawData, raw_input->data.hid.dwSizeHid); + } + } + } + } + result = 0; + break; + } + + SDL_UnlockJoysticks(); + } + + if (result >= 0) { + return result; + } + return CallWindowProc(DefWindowProc, hWnd, msg, wParam, lParam); +} + +static void RAWINPUT_JoystickQuit(void) +{ + if (!SDL_RAWINPUT_inited) { + return; + } + + RAWINPUT_RemoveDevices(); + + WIN_UnloadHIDDLL(); + + SDL_RAWINPUT_inited = SDL_FALSE; +} + +static SDL_bool RAWINPUT_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) +{ + return SDL_FALSE; +} + +SDL_JoystickDriver SDL_RAWINPUT_JoystickDriver = { + RAWINPUT_JoystickInit, + RAWINPUT_JoystickGetCount, + RAWINPUT_JoystickDetect, + RAWINPUT_JoystickGetDeviceName, + RAWINPUT_JoystickGetDevicePath, + RAWINPUT_JoystickGetDeviceSteamVirtualGamepadSlot, + RAWINPUT_JoystickGetDevicePlayerIndex, + RAWINPUT_JoystickSetDevicePlayerIndex, + RAWINPUT_JoystickGetDeviceGUID, + RAWINPUT_JoystickGetDeviceInstanceID, + RAWINPUT_JoystickOpen, + RAWINPUT_JoystickRumble, + RAWINPUT_JoystickRumbleTriggers, + RAWINPUT_JoystickGetCapabilities, + RAWINPUT_JoystickSetLED, + RAWINPUT_JoystickSendEffect, + RAWINPUT_JoystickSetSensorsEnabled, + RAWINPUT_JoystickUpdate, + RAWINPUT_JoystickClose, + RAWINPUT_JoystickQuit, + RAWINPUT_JoystickGetGamepadMapping +}; + +#endif /* SDL_JOYSTICK_RAWINPUT */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/cocoa/SDL_cocoamousetap.h b/SDL2-2.30.5/src/joystick/windows/SDL_rawinputjoystick_c.h similarity index 62% rename from SDL2-2.0.12/src/video/cocoa/SDL_cocoamousetap.h rename to SDL2-2.30.5/src/joystick/windows/SDL_rawinputjoystick_c.h index 3a1a072..598a22d 100644 --- a/SDL2-2.0.12/src/video/cocoa/SDL_cocoamousetap.h +++ b/SDL2-2.30.5/src/joystick/windows/SDL_rawinputjoystick_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -19,16 +19,19 @@ 3. This notice may not be removed or altered from any source distribution. */ #include "../../SDL_internal.h" +#include "../../core/windows/SDL_windows.h" -#ifndef SDL_cocoamousetap_h_ -#define SDL_cocoamousetap_h_ +/* Return true if the RawInput driver is enabled */ +extern SDL_bool RAWINPUT_IsEnabled(); -#include "SDL_cocoamouse.h" +/* Return true if a RawInput device is present and supported as a joystick */ +extern SDL_bool RAWINPUT_IsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name); -extern void Cocoa_InitMouseEventTap(SDL_MouseData *driverdata); -extern void Cocoa_EnableMouseEventTap(SDL_MouseData *driverdata, SDL_bool enabled); -extern void Cocoa_QuitMouseEventTap(SDL_MouseData *driverdata); +/* Registers for input events */ +extern int RAWINPUT_RegisterNotifications(HWND hWnd); +extern int RAWINPUT_UnregisterNotifications(); -#endif /* SDL_cocoamousetap_h_ */ +/* Returns 0 if message was handled */ +extern LRESULT CALLBACK RAWINPUT_WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/joystick/windows/SDL_windows_gaming_input.c b/SDL2-2.30.5/src/joystick/windows/SDL_windows_gaming_input.c new file mode 100644 index 0000000..656f742 --- /dev/null +++ b/SDL2-2.30.5/src/joystick/windows/SDL_windows_gaming_input.c @@ -0,0 +1,1078 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_JOYSTICK_WGI + +#include "SDL_assert.h" +#include "SDL_atomic.h" +#include "SDL_endian.h" +#include "SDL_events.h" +#include "../SDL_sysjoystick.h" +#include "../hidapi/SDL_hidapijoystick_c.h" +#include "SDL_rawinputjoystick_c.h" + +#include "../../core/windows/SDL_windows.h" +#define COBJMACROS +#include "windows.gaming.input.h" +#include +#include +#include + +#ifdef ____FIReference_1_INT32_INTERFACE_DEFINED__ +/* MinGW-64 uses __FIReference_1_INT32 instead of Microsoft's __FIReference_1_int */ +#define __FIReference_1_int __FIReference_1_INT32 +#define __FIReference_1_int_get_Value __FIReference_1_INT32_get_Value +#define __FIReference_1_int_Release __FIReference_1_INT32_Release +#endif + +struct joystick_hwdata +{ + __x_ABI_CWindows_CGaming_CInput_CIRawGameController *controller; + __x_ABI_CWindows_CGaming_CInput_CIGameController *gamecontroller; + __x_ABI_CWindows_CGaming_CInput_CIGameControllerBatteryInfo *battery; + __x_ABI_CWindows_CGaming_CInput_CIGamepad *gamepad; + __x_ABI_CWindows_CGaming_CInput_CGamepadVibration vibration; + UINT64 timestamp; +}; + +typedef struct WindowsGamingInputControllerState +{ + SDL_JoystickID instance_id; + __x_ABI_CWindows_CGaming_CInput_CIRawGameController *controller; + char *name; + SDL_JoystickGUID guid; + SDL_JoystickType type; + int naxes; + int nhats; + int nbuttons; + int steam_virtual_gamepad_slot; +} WindowsGamingInputControllerState; + +static struct +{ + __x_ABI_CWindows_CGaming_CInput_CIRawGameControllerStatics *statics; + __x_ABI_CWindows_CGaming_CInput_CIArcadeStickStatics *arcade_stick_statics; + __x_ABI_CWindows_CGaming_CInput_CIArcadeStickStatics2 *arcade_stick_statics2; + __x_ABI_CWindows_CGaming_CInput_CIFlightStickStatics *flight_stick_statics; + __x_ABI_CWindows_CGaming_CInput_CIGamepadStatics *gamepad_statics; + __x_ABI_CWindows_CGaming_CInput_CIGamepadStatics2 *gamepad_statics2; + __x_ABI_CWindows_CGaming_CInput_CIRacingWheelStatics *racing_wheel_statics; + __x_ABI_CWindows_CGaming_CInput_CIRacingWheelStatics2 *racing_wheel_statics2; + EventRegistrationToken controller_added_token; + EventRegistrationToken controller_removed_token; + int controller_count; + SDL_bool ro_initialized; + WindowsGamingInputControllerState *controllers; +} wgi; + +static const IID IID_IRawGameControllerStatics = { 0xEB8D0792, 0xE95A, 0x4B19, { 0xAF, 0xC7, 0x0A, 0x59, 0xF8, 0xBF, 0x75, 0x9E } }; +static const IID IID_IRawGameController = { 0x7CAD6D91, 0xA7E1, 0x4F71, { 0x9A, 0x78, 0x33, 0xE9, 0xC5, 0xDF, 0xEA, 0x62 } }; +static const IID IID_IRawGameController2 = { 0x43C0C035, 0xBB73, 0x4756, { 0xA7, 0x87, 0x3E, 0xD6, 0xBE, 0xA6, 0x17, 0xBD } }; +static const IID IID_IEventHandler_RawGameController = { 0x00621c22, 0x42e8, 0x529f, { 0x92, 0x70, 0x83, 0x6b, 0x32, 0x93, 0x1d, 0x72 } }; +static const IID IID_IGameController = { 0x1BAF6522, 0x5F64, 0x42C5, { 0x82, 0x67, 0xB9, 0xFE, 0x22, 0x15, 0xBF, 0xBD } }; +static const IID IID_IGameControllerBatteryInfo = { 0xDCECC681, 0x3963, 0x4DA6, { 0x95, 0x5D, 0x55, 0x3F, 0x3B, 0x6F, 0x61, 0x61 } }; +static const IID IID_IArcadeStickStatics = { 0x5C37B8C8, 0x37B1, 0x4AD8, { 0x94, 0x58, 0x20, 0x0F, 0x1A, 0x30, 0x01, 0x8E } }; +static const IID IID_IArcadeStickStatics2 = { 0x52B5D744, 0xBB86, 0x445A, { 0xB5, 0x9C, 0x59, 0x6F, 0x0E, 0x2A, 0x49, 0xDF } }; +/*static const IID IID_IArcadeStick = { 0xB14A539D, 0xBEFB, 0x4C81, { 0x80, 0x51, 0x15, 0xEC, 0xF3, 0xB1, 0x30, 0x36 } };*/ +static const IID IID_IFlightStickStatics = { 0x5514924A, 0xFECC, 0x435E, { 0x83, 0xDC, 0x5C, 0xEC, 0x8A, 0x18, 0xA5, 0x20 } }; +/*static const IID IID_IFlightStick = { 0xB4A2C01C, 0xB83B, 0x4459, { 0xA1, 0xA9, 0x97, 0xB0, 0x3C, 0x33, 0xDA, 0x7C } };*/ +static const IID IID_IGamepadStatics = { 0x8BBCE529, 0xD49C, 0x39E9, { 0x95, 0x60, 0xE4, 0x7D, 0xDE, 0x96, 0xB7, 0xC8 } }; +static const IID IID_IGamepadStatics2 = { 0x42676DC5, 0x0856, 0x47C4, { 0x92, 0x13, 0xB3, 0x95, 0x50, 0x4C, 0x3A, 0x3C } }; +/*static const IID IID_IGamepad = { 0xBC7BB43C, 0x0A69, 0x3903, { 0x9E, 0x9D, 0xA5, 0x0F, 0x86, 0xA4, 0x5D, 0xE5 } };*/ +static const IID IID_IRacingWheelStatics = { 0x3AC12CD5, 0x581B, 0x4936, { 0x9F, 0x94, 0x69, 0xF1, 0xE6, 0x51, 0x4C, 0x7D } }; +static const IID IID_IRacingWheelStatics2 = { 0xE666BCAA, 0xEDFD, 0x4323, { 0xA9, 0xF6, 0x3C, 0x38, 0x40, 0x48, 0xD1, 0xED } }; +/*static const IID IID_IRacingWheel = { 0xF546656F, 0xE106, 0x4C82, { 0xA9, 0x0F, 0x55, 0x40, 0x12, 0x90, 0x4B, 0x85 } };*/ + +typedef HRESULT(WINAPI *WindowsCreateStringReference_t)(PCWSTR sourceString, UINT32 length, HSTRING_HEADER *hstringHeader, HSTRING *string); +typedef HRESULT(WINAPI *RoGetActivationFactory_t)(HSTRING activatableClassId, REFIID iid, void **factory); + + +extern SDL_bool SDL_XINPUT_Enabled(void); +extern SDL_bool SDL_DINPUT_JoystickPresent(Uint16 vendor, Uint16 product, Uint16 version); + + +static SDL_bool SDL_IsXInputDevice(Uint16 vendor, Uint16 product) +{ +#if defined(SDL_JOYSTICK_XINPUT) || defined(SDL_JOYSTICK_RAWINPUT) + PRAWINPUTDEVICELIST raw_devices = NULL; + UINT i, raw_device_count = 0; + LONG vidpid = MAKELONG(vendor, product); + + /* XInput and RawInput backends will pick up XInput-compatible devices */ + if (!SDL_XINPUT_Enabled() +#ifdef SDL_JOYSTICK_RAWINPUT + && !RAWINPUT_IsEnabled() +#endif + ) { + return SDL_FALSE; + } + + /* Go through RAWINPUT (WinXP and later) to find HID devices. */ + if ((GetRawInputDeviceList(NULL, &raw_device_count, sizeof(RAWINPUTDEVICELIST)) == -1) || (!raw_device_count)) { + return SDL_FALSE; /* oh well. */ + } + + raw_devices = (PRAWINPUTDEVICELIST)SDL_malloc(sizeof(RAWINPUTDEVICELIST) * raw_device_count); + if (!raw_devices) { + SDL_OutOfMemory(); + return SDL_FALSE; + } + + raw_device_count = GetRawInputDeviceList(raw_devices, &raw_device_count, sizeof(RAWINPUTDEVICELIST)); + if (raw_device_count == (UINT)-1) { + SDL_free(raw_devices); + raw_devices = NULL; + return SDL_FALSE; /* oh well. */ + } + + for (i = 0; i < raw_device_count; i++) { + RID_DEVICE_INFO rdi; + char devName[MAX_PATH]; + UINT rdiSize = sizeof(rdi); + UINT nameSize = SDL_arraysize(devName); + DEVINST devNode; + char devVidPidString[32]; + int j; + + rdi.cbSize = sizeof(rdi); + + if ((raw_devices[i].dwType != RIM_TYPEHID) || + (GetRawInputDeviceInfoA(raw_devices[i].hDevice, RIDI_DEVICEINFO, &rdi, &rdiSize) == ((UINT)-1)) || + (GetRawInputDeviceInfoA(raw_devices[i].hDevice, RIDI_DEVICENAME, devName, &nameSize) == ((UINT)-1)) || + (SDL_strstr(devName, "IG_") == NULL)) { + /* Skip non-XInput devices */ + continue; + } + + /* First check for a simple VID/PID match. This will work for Xbox 360 controllers. */ + if (MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) == vidpid) { + SDL_free(raw_devices); + return SDL_TRUE; + } + + /* For Xbox One controllers, Microsoft doesn't propagate the VID/PID down to the HID stack. + * We'll have to walk the device tree upwards searching for a match for our VID/PID. */ + + /* Make sure the device interface string is something we know how to parse */ + /* Example: \\?\HID#VID_045E&PID_02FF&IG_00#9&2c203035&2&0000#{4d1e55b2-f16f-11cf-88cb-001111000030} */ + if ((SDL_strstr(devName, "\\\\?\\") != devName) || (SDL_strstr(devName, "#{") == NULL)) { + continue; + } + + /* Unescape the backslashes in the string and terminate before the GUID portion */ + for (j = 0; devName[j] != '\0'; j++) { + if (devName[j] == '#') { + if (devName[j + 1] == '{') { + devName[j] = '\0'; + break; + } else { + devName[j] = '\\'; + } + } + } + + /* We'll be left with a string like this: \\?\HID\VID_045E&PID_02FF&IG_00\9&2c203035&2&0000 + * Simply skip the \\?\ prefix and we'll have a properly formed device instance ID */ + if (CM_Locate_DevNodeA(&devNode, &devName[4], CM_LOCATE_DEVNODE_NORMAL) != CR_SUCCESS) { + continue; + } + + (void)SDL_snprintf(devVidPidString, sizeof(devVidPidString), "VID_%04X&PID_%04X", vendor, product); + + while (CM_Get_Parent(&devNode, devNode, 0) == CR_SUCCESS) { + char deviceId[MAX_DEVICE_ID_LEN]; + + if ((CM_Get_Device_IDA(devNode, deviceId, SDL_arraysize(deviceId), 0) == CR_SUCCESS) && + (SDL_strstr(deviceId, devVidPidString) != NULL)) { + /* The VID/PID matched a parent device */ + SDL_free(raw_devices); + return SDL_TRUE; + } + } + } + + SDL_free(raw_devices); +#endif /* SDL_JOYSTICK_XINPUT || SDL_JOYSTICK_RAWINPUT */ + + return SDL_FALSE; +} + +static void WGI_LoadRawGameControllerStatics() +{ + WindowsCreateStringReference_t WindowsCreateStringReferenceFunc = NULL; + RoGetActivationFactory_t RoGetActivationFactoryFunc = NULL; + HRESULT hr; + +#ifdef __WINRT__ + WindowsCreateStringReferenceFunc = WindowsCreateStringReference; + RoGetActivationFactoryFunc = RoGetActivationFactory; +#else + { + WindowsCreateStringReferenceFunc = (WindowsCreateStringReference_t)WIN_LoadComBaseFunction("WindowsCreateStringReference"); + RoGetActivationFactoryFunc = (RoGetActivationFactory_t)WIN_LoadComBaseFunction("RoGetActivationFactory"); + } +#endif /* __WINRT__ */ + if (WindowsCreateStringReferenceFunc && RoGetActivationFactoryFunc) { + PCWSTR pNamespace; + HSTRING_HEADER hNamespaceStringHeader; + HSTRING hNamespaceString; + + pNamespace = L"Windows.Gaming.Input.RawGameController"; + hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString); + if (SUCCEEDED(hr)) { + hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IRawGameControllerStatics, (void **)&wgi.statics); + if (!SUCCEEDED(hr)) { + SDL_SetError("Couldn't find IRawGameControllerStatics: 0x%lx", hr); + } + } + } +} + +static void WGI_LoadOtherControllerStatics() +{ + WindowsCreateStringReference_t WindowsCreateStringReferenceFunc = NULL; + RoGetActivationFactory_t RoGetActivationFactoryFunc = NULL; + HRESULT hr; + +#ifdef __WINRT__ + WindowsCreateStringReferenceFunc = WindowsCreateStringReference; + RoGetActivationFactoryFunc = RoGetActivationFactory; +#else + { + WindowsCreateStringReferenceFunc = (WindowsCreateStringReference_t)WIN_LoadComBaseFunction("WindowsCreateStringReference"); + RoGetActivationFactoryFunc = (RoGetActivationFactory_t)WIN_LoadComBaseFunction("RoGetActivationFactory"); + } +#endif /* __WINRT__ */ + if (WindowsCreateStringReferenceFunc && RoGetActivationFactoryFunc) { + PCWSTR pNamespace; + HSTRING_HEADER hNamespaceStringHeader; + HSTRING hNamespaceString; + + pNamespace = L"Windows.Gaming.Input.ArcadeStick"; + hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString); + if (SUCCEEDED(hr)) { + hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IArcadeStickStatics, (void **)&wgi.arcade_stick_statics); + if (SUCCEEDED(hr)) { + __x_ABI_CWindows_CGaming_CInput_CIArcadeStickStatics_QueryInterface(wgi.arcade_stick_statics, &IID_IArcadeStickStatics2, (void **)&wgi.arcade_stick_statics2); + } else { + SDL_SetError("Couldn't find IID_IArcadeStickStatics: 0x%lx", hr); + } + } + + pNamespace = L"Windows.Gaming.Input.FlightStick"; + hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString); + if (SUCCEEDED(hr)) { + hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IFlightStickStatics, (void **)&wgi.flight_stick_statics); + if (!SUCCEEDED(hr)) { + SDL_SetError("Couldn't find IID_IFlightStickStatics: 0x%lx", hr); + } + } + + pNamespace = L"Windows.Gaming.Input.Gamepad"; + hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString); + if (SUCCEEDED(hr)) { + hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IGamepadStatics, (void **)&wgi.gamepad_statics); + if (SUCCEEDED(hr)) { + __x_ABI_CWindows_CGaming_CInput_CIGamepadStatics_QueryInterface(wgi.gamepad_statics, &IID_IGamepadStatics2, (void **)&wgi.gamepad_statics2); + } else { + SDL_SetError("Couldn't find IGamepadStatics: 0x%lx", hr); + } + } + + pNamespace = L"Windows.Gaming.Input.RacingWheel"; + hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString); + if (SUCCEEDED(hr)) { + hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IRacingWheelStatics, (void **)&wgi.racing_wheel_statics); + if (SUCCEEDED(hr)) { + __x_ABI_CWindows_CGaming_CInput_CIRacingWheelStatics_QueryInterface(wgi.racing_wheel_statics, &IID_IRacingWheelStatics2, (void **)&wgi.racing_wheel_statics2); + } else { + SDL_SetError("Couldn't find IRacingWheelStatics: 0x%lx", hr); + } + } + } +} + +static SDL_JoystickType GetGameControllerType(__x_ABI_CWindows_CGaming_CInput_CIGameController *gamecontroller) +{ + __x_ABI_CWindows_CGaming_CInput_CIArcadeStick *arcade_stick = NULL; + __x_ABI_CWindows_CGaming_CInput_CIFlightStick *flight_stick = NULL; + __x_ABI_CWindows_CGaming_CInput_CIGamepad *gamepad = NULL; + __x_ABI_CWindows_CGaming_CInput_CIRacingWheel *racing_wheel = NULL; + + /* Wait to initialize these interfaces until we need them. + * Initializing the gamepad interface will switch Bluetooth PS4 controllers into enhanced mode, breaking DirectInput + */ + WGI_LoadOtherControllerStatics(); + + if (wgi.gamepad_statics2 && SUCCEEDED(__x_ABI_CWindows_CGaming_CInput_CIGamepadStatics2_FromGameController(wgi.gamepad_statics2, gamecontroller, &gamepad)) && gamepad) { + __x_ABI_CWindows_CGaming_CInput_CIGamepad_Release(gamepad); + return SDL_JOYSTICK_TYPE_GAMECONTROLLER; + } + + if (wgi.arcade_stick_statics2 && SUCCEEDED(__x_ABI_CWindows_CGaming_CInput_CIArcadeStickStatics2_FromGameController(wgi.arcade_stick_statics2, gamecontroller, &arcade_stick)) && arcade_stick) { + __x_ABI_CWindows_CGaming_CInput_CIArcadeStick_Release(arcade_stick); + return SDL_JOYSTICK_TYPE_ARCADE_STICK; + } + + if (wgi.flight_stick_statics && SUCCEEDED(__x_ABI_CWindows_CGaming_CInput_CIFlightStickStatics_FromGameController(wgi.flight_stick_statics, gamecontroller, &flight_stick)) && flight_stick) { + __x_ABI_CWindows_CGaming_CInput_CIFlightStick_Release(flight_stick); + return SDL_JOYSTICK_TYPE_FLIGHT_STICK; + } + + if (wgi.racing_wheel_statics2 && SUCCEEDED(__x_ABI_CWindows_CGaming_CInput_CIRacingWheelStatics2_FromGameController(wgi.racing_wheel_statics2, gamecontroller, &racing_wheel)) && racing_wheel) { + __x_ABI_CWindows_CGaming_CInput_CIRacingWheel_Release(racing_wheel); + return SDL_JOYSTICK_TYPE_WHEEL; + } + + return SDL_JOYSTICK_TYPE_UNKNOWN; +} + +typedef struct RawGameControllerDelegate +{ + __FIEventHandler_1_Windows__CGaming__CInput__CRawGameController iface; + SDL_atomic_t refcount; +} RawGameControllerDelegate; + +static HRESULT STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_QueryInterface(__FIEventHandler_1_Windows__CGaming__CInput__CRawGameController *This, REFIID riid, void **ppvObject) +{ + if (!ppvObject) { + return E_INVALIDARG; + } + + *ppvObject = NULL; + if (WIN_IsEqualIID(riid, &IID_IUnknown) || WIN_IsEqualIID(riid, &IID_IAgileObject) || WIN_IsEqualIID(riid, &IID_IEventHandler_RawGameController)) { + *ppvObject = This; + __FIEventHandler_1_Windows__CGaming__CInput__CRawGameController_AddRef(This); + return S_OK; + } else if (WIN_IsEqualIID(riid, &IID_IMarshal)) { + /* This seems complicated. Let's hope it doesn't happen. */ + return E_OUTOFMEMORY; + } else { + return E_NOINTERFACE; + } +} + +static ULONG STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_AddRef(__FIEventHandler_1_Windows__CGaming__CInput__CRawGameController *This) +{ + RawGameControllerDelegate *self = (RawGameControllerDelegate *)This; + return SDL_AtomicAdd(&self->refcount, 1) + 1UL; +} + +static ULONG STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_Release(__FIEventHandler_1_Windows__CGaming__CInput__CRawGameController *This) +{ + RawGameControllerDelegate *self = (RawGameControllerDelegate *)This; + int rc = SDL_AtomicAdd(&self->refcount, -1) - 1; + /* Should never free the static delegate objects */ + SDL_assert(rc > 0); + return rc; +} + +static int GetSteamVirtualGamepadSlot(__x_ABI_CWindows_CGaming_CInput_CIRawGameController *controller, Uint16 vendor_id, Uint16 product_id) +{ + int slot = -1; + + if (vendor_id == USB_VENDOR_VALVE && + product_id == USB_PRODUCT_STEAM_VIRTUAL_GAMEPAD) { + __x_ABI_CWindows_CGaming_CInput_CIRawGameController2 *controller2 = NULL; + HRESULT hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameController_QueryInterface(controller, &IID_IRawGameController2, (void **)&controller2); + if (SUCCEEDED(hr)) { + HSTRING hString; + hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameController2_get_NonRoamableId(controller2, &hString); + if (SUCCEEDED(hr)) { + typedef PCWSTR(WINAPI * WindowsGetStringRawBuffer_t)(HSTRING string, UINT32 * length); + typedef HRESULT(WINAPI * WindowsDeleteString_t)(HSTRING string); + + WindowsGetStringRawBuffer_t WindowsGetStringRawBufferFunc = NULL; + WindowsDeleteString_t WindowsDeleteStringFunc = NULL; +#ifdef __WINRT__ + WindowsGetStringRawBufferFunc = WindowsGetStringRawBuffer; + WindowsDeleteStringFunc = WindowsDeleteString; +#else + { + WindowsGetStringRawBufferFunc = (WindowsGetStringRawBuffer_t)WIN_LoadComBaseFunction("WindowsGetStringRawBuffer"); + WindowsDeleteStringFunc = (WindowsDeleteString_t)WIN_LoadComBaseFunction("WindowsDeleteString"); + } +#endif /* __WINRT__ */ + if (WindowsGetStringRawBufferFunc && WindowsDeleteStringFunc) { + PCWSTR string = WindowsGetStringRawBufferFunc(hString, NULL); + if (string) { + char *id = WIN_StringToUTF8W(string); + if (id) { + (void)SDL_sscanf(id, "{wgi/nrid/:steam-%*X&%*X&%*X#%d#%*u}", &slot); + SDL_free(id); + } + } + WindowsDeleteStringFunc(hString); + } + } + __x_ABI_CWindows_CGaming_CInput_CIRawGameController2_Release(controller2); + } + } + return slot; +} + +static HRESULT STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_InvokeAdded(__FIEventHandler_1_Windows__CGaming__CInput__CRawGameController *This, IInspectable *sender, __x_ABI_CWindows_CGaming_CInput_CIRawGameController *e) +{ + HRESULT hr; + __x_ABI_CWindows_CGaming_CInput_CIRawGameController *controller = NULL; + + SDL_LockJoysticks(); + + /* We can get delayed calls to InvokeAdded() after WGI_JoystickQuit() */ + if (SDL_JoysticksQuitting() || !SDL_JoysticksInitialized()) { + SDL_UnlockJoysticks(); + return S_OK; + } + + hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameController_QueryInterface(e, &IID_IRawGameController, (void **)&controller); + if (SUCCEEDED(hr)) { + char *name = NULL; + SDL_JoystickGUID guid; + Uint16 bus = SDL_HARDWARE_BUS_USB; + Uint16 vendor = 0; + Uint16 product = 0; + Uint16 version = 0; + SDL_JoystickType type = SDL_JOYSTICK_TYPE_UNKNOWN; + __x_ABI_CWindows_CGaming_CInput_CIRawGameController2 *controller2 = NULL; + __x_ABI_CWindows_CGaming_CInput_CIGameController *gamecontroller = NULL; + SDL_bool ignore_joystick = SDL_FALSE; + + __x_ABI_CWindows_CGaming_CInput_CIRawGameController_get_HardwareVendorId(controller, &vendor); + __x_ABI_CWindows_CGaming_CInput_CIRawGameController_get_HardwareProductId(controller, &product); + + hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameController_QueryInterface(controller, &IID_IRawGameController2, (void **)&controller2); + if (SUCCEEDED(hr)) { + typedef PCWSTR(WINAPI * WindowsGetStringRawBuffer_t)(HSTRING string, UINT32 * length); + typedef HRESULT(WINAPI * WindowsDeleteString_t)(HSTRING string); + + WindowsGetStringRawBuffer_t WindowsGetStringRawBufferFunc = NULL; + WindowsDeleteString_t WindowsDeleteStringFunc = NULL; +#ifdef __WINRT__ + WindowsGetStringRawBufferFunc = WindowsGetStringRawBuffer; + WindowsDeleteStringFunc = WindowsDeleteString; +#else + { + WindowsGetStringRawBufferFunc = (WindowsGetStringRawBuffer_t)WIN_LoadComBaseFunction("WindowsGetStringRawBuffer"); + WindowsDeleteStringFunc = (WindowsDeleteString_t)WIN_LoadComBaseFunction("WindowsDeleteString"); + } +#endif /* __WINRT__ */ + if (WindowsGetStringRawBufferFunc && WindowsDeleteStringFunc) { + HSTRING hString; + hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameController2_get_DisplayName(controller2, &hString); + if (SUCCEEDED(hr)) { + PCWSTR string = WindowsGetStringRawBufferFunc(hString, NULL); + if (string) { + name = WIN_StringToUTF8W(string); + } + WindowsDeleteStringFunc(hString); + } + } + __x_ABI_CWindows_CGaming_CInput_CIRawGameController2_Release(controller2); + } + if (!name) { + name = SDL_strdup(""); + } + +#ifdef SDL_JOYSTICK_HIDAPI + if (!ignore_joystick && HIDAPI_IsDevicePresent(vendor, product, version, name)) { + ignore_joystick = SDL_TRUE; + } +#endif + +#ifdef SDL_JOYSTICK_RAWINPUT + if (!ignore_joystick && RAWINPUT_IsDevicePresent(vendor, product, version, name)) { + ignore_joystick = SDL_TRUE; + } +#endif + + if (!ignore_joystick && SDL_DINPUT_JoystickPresent(vendor, product, version)) { + ignore_joystick = SDL_TRUE; + } + + if (!ignore_joystick && SDL_IsXInputDevice(vendor, product)) { + ignore_joystick = SDL_TRUE; + } + + if (!ignore_joystick) { + hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameController_QueryInterface(controller, &IID_IGameController, (void **)&gamecontroller); + if (SUCCEEDED(hr)) { + boolean wireless; + + type = GetGameControllerType(gamecontroller); + + hr = __x_ABI_CWindows_CGaming_CInput_CIGameController_get_IsWireless(gamecontroller, &wireless); + if (SUCCEEDED(hr) && wireless) { + bus = SDL_HARDWARE_BUS_BLUETOOTH; + } + + __x_ABI_CWindows_CGaming_CInput_CIGameController_Release(gamecontroller); + } + + guid = SDL_CreateJoystickGUID(bus, vendor, product, version, NULL, name, 'w', (Uint8)type); + + if (SDL_ShouldIgnoreJoystick(name, guid)) { + ignore_joystick = SDL_TRUE; + } + } + + if (!ignore_joystick) { + /* New device, add it */ + WindowsGamingInputControllerState *controllers = SDL_realloc(wgi.controllers, sizeof(wgi.controllers[0]) * (wgi.controller_count + 1)); + if (controllers) { + WindowsGamingInputControllerState *state = &controllers[wgi.controller_count]; + SDL_JoystickID joystickID = SDL_GetNextJoystickInstanceID(); + + SDL_zerop(state); + state->instance_id = joystickID; + state->controller = controller; + state->name = name; + state->guid = guid; + state->type = type; + state->steam_virtual_gamepad_slot = GetSteamVirtualGamepadSlot(controller, vendor, product); + + __x_ABI_CWindows_CGaming_CInput_CIRawGameController_get_ButtonCount(controller, &state->nbuttons); + __x_ABI_CWindows_CGaming_CInput_CIRawGameController_get_AxisCount(controller, &state->naxes); + __x_ABI_CWindows_CGaming_CInput_CIRawGameController_get_SwitchCount(controller, &state->nhats); + + __x_ABI_CWindows_CGaming_CInput_CIRawGameController_AddRef(controller); + + ++wgi.controller_count; + wgi.controllers = controllers; + + SDL_PrivateJoystickAdded(joystickID); + } else { + SDL_free(name); + } + } else { + SDL_free(name); + } + + __x_ABI_CWindows_CGaming_CInput_CIRawGameController_Release(controller); + } + + SDL_UnlockJoysticks(); + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_InvokeRemoved(__FIEventHandler_1_Windows__CGaming__CInput__CRawGameController *This, IInspectable *sender, __x_ABI_CWindows_CGaming_CInput_CIRawGameController *e) +{ + HRESULT hr; + __x_ABI_CWindows_CGaming_CInput_CIRawGameController *controller = NULL; + + SDL_LockJoysticks(); + + /* Can we get delayed calls to InvokeRemoved() after WGI_JoystickQuit()? */ + if (!SDL_JoysticksInitialized()) { + SDL_UnlockJoysticks(); + return S_OK; + } + + hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameController_QueryInterface(e, &IID_IRawGameController, (void **)&controller); + if (SUCCEEDED(hr)) { + int i; + + for (i = 0; i < wgi.controller_count; i++) { + if (wgi.controllers[i].controller == controller) { + WindowsGamingInputControllerState *state = &wgi.controllers[i]; + SDL_JoystickID joystickID = state->instance_id; + + __x_ABI_CWindows_CGaming_CInput_CIRawGameController_Release(state->controller); + + SDL_free(state->name); + + --wgi.controller_count; + if (i < wgi.controller_count) { + SDL_memmove(&wgi.controllers[i], &wgi.controllers[i + 1], (wgi.controller_count - i) * sizeof(wgi.controllers[i])); + } + + SDL_PrivateJoystickRemoved(joystickID); + break; + } + } + + __x_ABI_CWindows_CGaming_CInput_CIRawGameController_Release(controller); + } + + SDL_UnlockJoysticks(); + + return S_OK; +} + +static __FIEventHandler_1_Windows__CGaming__CInput__CRawGameControllerVtbl controller_added_vtbl = { + IEventHandler_CRawGameControllerVtbl_QueryInterface, + IEventHandler_CRawGameControllerVtbl_AddRef, + IEventHandler_CRawGameControllerVtbl_Release, + IEventHandler_CRawGameControllerVtbl_InvokeAdded +}; +static RawGameControllerDelegate controller_added = { + { &controller_added_vtbl }, + { 1 } +}; + +static __FIEventHandler_1_Windows__CGaming__CInput__CRawGameControllerVtbl controller_removed_vtbl = { + IEventHandler_CRawGameControllerVtbl_QueryInterface, + IEventHandler_CRawGameControllerVtbl_AddRef, + IEventHandler_CRawGameControllerVtbl_Release, + IEventHandler_CRawGameControllerVtbl_InvokeRemoved +}; +static RawGameControllerDelegate controller_removed = { + { &controller_removed_vtbl }, + { 1 } +}; + +static int WGI_JoystickInit(void) +{ + HRESULT hr; + + if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_WGI, SDL_TRUE)) { + return 0; + } + + if (FAILED(WIN_RoInitialize())) { + return SDL_SetError("RoInitialize() failed"); + } + wgi.ro_initialized = SDL_TRUE; + +#ifndef __WINRT__ + { + /* There seems to be a bug in Windows where a dependency of WGI can be unloaded from memory prior to WGI itself. + * This results in Windows_Gaming_Input!GameController::~GameController() invoking an unloaded DLL and crashing. + * As a workaround, we will keep a reference to the MTA to prevent COM from unloading DLLs later. + * See https://github.com/libsdl-org/SDL/issues/5552 for more details. + */ + static PVOID cookie = NULL; + if (!cookie) { + typedef HRESULT(WINAPI * CoIncrementMTAUsage_t)(PVOID * pCookie); + CoIncrementMTAUsage_t CoIncrementMTAUsageFunc = (CoIncrementMTAUsage_t)WIN_LoadComBaseFunction("CoIncrementMTAUsage"); + if (CoIncrementMTAUsageFunc) { + if (FAILED(CoIncrementMTAUsageFunc(&cookie))) { + return SDL_SetError("CoIncrementMTAUsage() failed"); + } + } else { + /* CoIncrementMTAUsage() is present since Win8, so we should never make it here. */ + return SDL_SetError("CoIncrementMTAUsage() not found"); + } + } + } +#endif + + WGI_LoadRawGameControllerStatics(); + + if (wgi.statics) { + __FIVectorView_1_Windows__CGaming__CInput__CRawGameController *controllers; + + hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameControllerStatics_add_RawGameControllerAdded(wgi.statics, &controller_added.iface, &wgi.controller_added_token); + if (!SUCCEEDED(hr)) { + SDL_SetError("add_RawGameControllerAdded() failed: 0x%lx\n", hr); + } + + hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameControllerStatics_add_RawGameControllerRemoved(wgi.statics, &controller_removed.iface, &wgi.controller_removed_token); + if (!SUCCEEDED(hr)) { + SDL_SetError("add_RawGameControllerRemoved() failed: 0x%lx\n", hr); + } + + hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameControllerStatics_get_RawGameControllers(wgi.statics, &controllers); + if (SUCCEEDED(hr)) { + unsigned i, count = 0; + + hr = __FIVectorView_1_Windows__CGaming__CInput__CRawGameController_get_Size(controllers, &count); + if (SUCCEEDED(hr)) { + for (i = 0; i < count; ++i) { + __x_ABI_CWindows_CGaming_CInput_CIRawGameController *controller = NULL; + + hr = __FIVectorView_1_Windows__CGaming__CInput__CRawGameController_GetAt(controllers, i, &controller); + if (SUCCEEDED(hr) && controller) { + IEventHandler_CRawGameControllerVtbl_InvokeAdded(&controller_added.iface, NULL, controller); + __x_ABI_CWindows_CGaming_CInput_CIRawGameController_Release(controller); + } + } + } + + __FIVectorView_1_Windows__CGaming__CInput__CRawGameController_Release(controllers); + } + } + + return 0; +} + +static int WGI_JoystickGetCount(void) +{ + return wgi.controller_count; +} + +static void WGI_JoystickDetect(void) +{ +} + +static const char *WGI_JoystickGetDeviceName(int device_index) +{ + return wgi.controllers[device_index].name; +} + +static const char *WGI_JoystickGetDevicePath(int device_index) +{ + return NULL; +} + +static int WGI_JoystickGetDeviceSteamVirtualGamepadSlot(int device_index) +{ + return wgi.controllers[device_index].steam_virtual_gamepad_slot; +} + +static int WGI_JoystickGetDevicePlayerIndex(int device_index) +{ + return -1; +} + +static void WGI_JoystickSetDevicePlayerIndex(int device_index, int player_index) +{ +} + +static SDL_JoystickGUID WGI_JoystickGetDeviceGUID(int device_index) +{ + return wgi.controllers[device_index].guid; +} + +static SDL_JoystickID WGI_JoystickGetDeviceInstanceID(int device_index) +{ + return wgi.controllers[device_index].instance_id; +} + +static int WGI_JoystickOpen(SDL_Joystick *joystick, int device_index) +{ + WindowsGamingInputControllerState *state = &wgi.controllers[device_index]; + struct joystick_hwdata *hwdata; + boolean wireless = SDL_FALSE; + + hwdata = (struct joystick_hwdata *)SDL_calloc(1, sizeof(*hwdata)); + if (!hwdata) { + return SDL_OutOfMemory(); + } + joystick->hwdata = hwdata; + + hwdata->controller = state->controller; + __x_ABI_CWindows_CGaming_CInput_CIRawGameController_AddRef(hwdata->controller); + __x_ABI_CWindows_CGaming_CInput_CIRawGameController_QueryInterface(hwdata->controller, &IID_IGameController, (void **)&hwdata->gamecontroller); + __x_ABI_CWindows_CGaming_CInput_CIRawGameController_QueryInterface(hwdata->controller, &IID_IGameControllerBatteryInfo, (void **)&hwdata->battery); + + if (wgi.gamepad_statics2) { + __x_ABI_CWindows_CGaming_CInput_CIGamepadStatics2_FromGameController(wgi.gamepad_statics2, hwdata->gamecontroller, &hwdata->gamepad); + } + + if (hwdata->gamecontroller) { + __x_ABI_CWindows_CGaming_CInput_CIGameController_get_IsWireless(hwdata->gamecontroller, &wireless); + } + + /* Initialize the joystick capabilities */ + joystick->nbuttons = state->nbuttons; + joystick->naxes = state->naxes; + joystick->nhats = state->nhats; + joystick->epowerlevel = wireless ? SDL_JOYSTICK_POWER_UNKNOWN : SDL_JOYSTICK_POWER_WIRED; + + if (wireless && hwdata->battery) { + HRESULT hr; + __x_ABI_CWindows_CDevices_CPower_CIBatteryReport *report; + + hr = __x_ABI_CWindows_CGaming_CInput_CIGameControllerBatteryInfo_TryGetBatteryReport(hwdata->battery, &report); + if (SUCCEEDED(hr) && report) { + int full_capacity = 0, curr_capacity = 0; + __FIReference_1_int *full_capacityP, *curr_capacityP; + + hr = __x_ABI_CWindows_CDevices_CPower_CIBatteryReport_get_FullChargeCapacityInMilliwattHours(report, &full_capacityP); + if (SUCCEEDED(hr)) { + __FIReference_1_int_get_Value(full_capacityP, &full_capacity); + __FIReference_1_int_Release(full_capacityP); + } + + hr = __x_ABI_CWindows_CDevices_CPower_CIBatteryReport_get_RemainingCapacityInMilliwattHours(report, &curr_capacityP); + if (SUCCEEDED(hr)) { + __FIReference_1_int_get_Value(curr_capacityP, &curr_capacity); + __FIReference_1_int_Release(curr_capacityP); + } + + if (full_capacity > 0) { + float ratio = (float)curr_capacity / full_capacity; + + if (ratio <= 0.05f) { + joystick->epowerlevel = SDL_JOYSTICK_POWER_EMPTY; + } else if (ratio <= 0.20f) { + joystick->epowerlevel = SDL_JOYSTICK_POWER_LOW; + } else if (ratio <= 0.70f) { + joystick->epowerlevel = SDL_JOYSTICK_POWER_MEDIUM; + } else { + joystick->epowerlevel = SDL_JOYSTICK_POWER_FULL; + } + } + __x_ABI_CWindows_CDevices_CPower_CIBatteryReport_Release(report); + } + } + return 0; +} + +static int WGI_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ + struct joystick_hwdata *hwdata = joystick->hwdata; + + if (hwdata->gamepad) { + HRESULT hr; + + hwdata->vibration.LeftMotor = (DOUBLE)low_frequency_rumble / SDL_MAX_UINT16; + hwdata->vibration.RightMotor = (DOUBLE)high_frequency_rumble / SDL_MAX_UINT16; + hr = __x_ABI_CWindows_CGaming_CInput_CIGamepad_put_Vibration(hwdata->gamepad, hwdata->vibration); + if (SUCCEEDED(hr)) { + return 0; + } else { + return SDL_SetError("Setting vibration failed: 0x%lx\n", hr); + } + } else { + return SDL_Unsupported(); + } +} + +static int WGI_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) +{ + struct joystick_hwdata *hwdata = joystick->hwdata; + + if (hwdata->gamepad) { + HRESULT hr; + + hwdata->vibration.LeftTrigger = (DOUBLE)left_rumble / SDL_MAX_UINT16; + hwdata->vibration.RightTrigger = (DOUBLE)right_rumble / SDL_MAX_UINT16; + hr = __x_ABI_CWindows_CGaming_CInput_CIGamepad_put_Vibration(hwdata->gamepad, hwdata->vibration); + if (SUCCEEDED(hr)) { + return 0; + } else { + return SDL_SetError("Setting vibration failed: 0x%lx\n", hr); + } + } else { + return SDL_Unsupported(); + } +} + +static Uint32 WGI_JoystickGetCapabilities(SDL_Joystick *joystick) +{ + struct joystick_hwdata *hwdata = joystick->hwdata; + + if (hwdata->gamepad) { + /* FIXME: Can WGI even tell us if trigger rumble is supported? */ + return SDL_JOYCAP_RUMBLE | SDL_JOYCAP_RUMBLE_TRIGGERS; + } else { + return 0; + } +} + +static int WGI_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + return SDL_Unsupported(); +} + +static int WGI_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + +static int WGI_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled) +{ + return SDL_Unsupported(); +} + +static Uint8 ConvertHatValue(__x_ABI_CWindows_CGaming_CInput_CGameControllerSwitchPosition value) +{ + switch (value) { + case GameControllerSwitchPosition_Up: + return SDL_HAT_UP; + case GameControllerSwitchPosition_UpRight: + return SDL_HAT_RIGHTUP; + case GameControllerSwitchPosition_Right: + return SDL_HAT_RIGHT; + case GameControllerSwitchPosition_DownRight: + return SDL_HAT_RIGHTDOWN; + case GameControllerSwitchPosition_Down: + return SDL_HAT_DOWN; + case GameControllerSwitchPosition_DownLeft: + return SDL_HAT_LEFTDOWN; + case GameControllerSwitchPosition_Left: + return SDL_HAT_LEFT; + case GameControllerSwitchPosition_UpLeft: + return SDL_HAT_LEFTUP; + default: + return SDL_HAT_CENTERED; + } +} + +static void WGI_JoystickUpdate(SDL_Joystick *joystick) +{ + struct joystick_hwdata *hwdata = joystick->hwdata; + HRESULT hr; + UINT32 nbuttons = SDL_min(joystick->nbuttons, SDL_MAX_UINT8); + boolean *buttons = NULL; + UINT32 nhats = SDL_min(joystick->nhats, SDL_MAX_UINT8); + __x_ABI_CWindows_CGaming_CInput_CGameControllerSwitchPosition *hats = NULL; + UINT32 naxes = SDL_min(joystick->naxes, SDL_MAX_UINT8); + DOUBLE *axes = NULL; + UINT64 timestamp; + + if (nbuttons > 0) { + buttons = SDL_stack_alloc(boolean, nbuttons); + } + if (nhats > 0) { + hats = SDL_stack_alloc(__x_ABI_CWindows_CGaming_CInput_CGameControllerSwitchPosition, nhats); + } + if (naxes > 0) { + axes = SDL_stack_alloc(DOUBLE, naxes); + } + + hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameController_GetCurrentReading(hwdata->controller, nbuttons, buttons, nhats, hats, naxes, axes, ×tamp); + if (SUCCEEDED(hr) && (!timestamp || timestamp != hwdata->timestamp)) { + UINT32 i; + SDL_bool all_zero = SDL_FALSE; + + /* The axes are all zero when the application loses focus */ + if (naxes > 0) { + all_zero = SDL_TRUE; + for (i = 0; i < naxes; ++i) { + if (axes[i] != 0.0f) { + all_zero = SDL_FALSE; + break; + } + } + } + if (all_zero) { + SDL_PrivateJoystickForceRecentering(joystick); + } else { + for (i = 0; i < nbuttons; ++i) { + SDL_PrivateJoystickButton(joystick, (Uint8)i, buttons[i]); + } + for (i = 0; i < nhats; ++i) { + SDL_PrivateJoystickHat(joystick, (Uint8)i, ConvertHatValue(hats[i])); + } + for (i = 0; i < naxes; ++i) { + SDL_PrivateJoystickAxis(joystick, (Uint8)i, (Sint16)((int)(axes[i] * 65535) - 32768)); + } + } + hwdata->timestamp = timestamp; + } + + SDL_stack_free(buttons); + SDL_stack_free(hats); + SDL_stack_free(axes); +} + +static void WGI_JoystickClose(SDL_Joystick *joystick) +{ + struct joystick_hwdata *hwdata = joystick->hwdata; + + if (hwdata) { + if (hwdata->controller) { + __x_ABI_CWindows_CGaming_CInput_CIRawGameController_Release(hwdata->controller); + } + if (hwdata->gamecontroller) { + __x_ABI_CWindows_CGaming_CInput_CIGameController_Release(hwdata->gamecontroller); + } + if (hwdata->battery) { + __x_ABI_CWindows_CGaming_CInput_CIGameControllerBatteryInfo_Release(hwdata->battery); + } + if (hwdata->gamepad) { + __x_ABI_CWindows_CGaming_CInput_CIGamepad_Release(hwdata->gamepad); + } + SDL_free(hwdata); + } + joystick->hwdata = NULL; +} + +static void WGI_JoystickQuit(void) +{ + if (wgi.statics) { + while (wgi.controller_count > 0) { + IEventHandler_CRawGameControllerVtbl_InvokeRemoved(&controller_removed.iface, NULL, wgi.controllers[wgi.controller_count - 1].controller); + } + if (wgi.controllers) { + SDL_free(wgi.controllers); + } + + if (wgi.arcade_stick_statics) { + __x_ABI_CWindows_CGaming_CInput_CIArcadeStickStatics_Release(wgi.arcade_stick_statics); + } + if (wgi.arcade_stick_statics2) { + __x_ABI_CWindows_CGaming_CInput_CIArcadeStickStatics2_Release(wgi.arcade_stick_statics2); + } + if (wgi.flight_stick_statics) { + __x_ABI_CWindows_CGaming_CInput_CIFlightStickStatics_Release(wgi.flight_stick_statics); + } + if (wgi.gamepad_statics) { + __x_ABI_CWindows_CGaming_CInput_CIGamepadStatics_Release(wgi.gamepad_statics); + } + if (wgi.gamepad_statics2) { + __x_ABI_CWindows_CGaming_CInput_CIGamepadStatics2_Release(wgi.gamepad_statics2); + } + if (wgi.racing_wheel_statics) { + __x_ABI_CWindows_CGaming_CInput_CIRacingWheelStatics_Release(wgi.racing_wheel_statics); + } + if (wgi.racing_wheel_statics2) { + __x_ABI_CWindows_CGaming_CInput_CIRacingWheelStatics2_Release(wgi.racing_wheel_statics2); + } + + __x_ABI_CWindows_CGaming_CInput_CIRawGameControllerStatics_remove_RawGameControllerAdded(wgi.statics, wgi.controller_added_token); + __x_ABI_CWindows_CGaming_CInput_CIRawGameControllerStatics_remove_RawGameControllerRemoved(wgi.statics, wgi.controller_removed_token); + __x_ABI_CWindows_CGaming_CInput_CIRawGameControllerStatics_Release(wgi.statics); + } + + if (wgi.ro_initialized) { + WIN_RoUninitialize(); + } + + SDL_zero(wgi); +} + +static SDL_bool WGI_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) +{ + return SDL_FALSE; +} + +SDL_JoystickDriver SDL_WGI_JoystickDriver = { + WGI_JoystickInit, + WGI_JoystickGetCount, + WGI_JoystickDetect, + WGI_JoystickGetDeviceName, + WGI_JoystickGetDevicePath, + WGI_JoystickGetDeviceSteamVirtualGamepadSlot, + WGI_JoystickGetDevicePlayerIndex, + WGI_JoystickSetDevicePlayerIndex, + WGI_JoystickGetDeviceGUID, + WGI_JoystickGetDeviceInstanceID, + WGI_JoystickOpen, + WGI_JoystickRumble, + WGI_JoystickRumbleTriggers, + WGI_JoystickGetCapabilities, + WGI_JoystickSetLED, + WGI_JoystickSendEffect, + WGI_JoystickSetSensorsEnabled, + WGI_JoystickUpdate, + WGI_JoystickClose, + WGI_JoystickQuit, + WGI_JoystickGetGamepadMapping +}; + +#endif /* SDL_JOYSTICK_WGI */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/joystick/windows/SDL_windowsjoystick.c b/SDL2-2.30.5/src/joystick/windows/SDL_windowsjoystick.c new file mode 100644 index 0000000..49e4c59 --- /dev/null +++ b/SDL2-2.30.5/src/joystick/windows/SDL_windowsjoystick.c @@ -0,0 +1,850 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#if defined(SDL_JOYSTICK_DINPUT) || defined(SDL_JOYSTICK_XINPUT) + +/* DirectInput joystick driver; written by Glenn Maynard, based on Andrei de + * A. Formiga's WINMM driver. + * + * Hats and sliders are completely untested; the app I'm writing this for mostly + * doesn't use them and I don't own any joysticks with them. + * + * We don't bother to use event notification here. It doesn't seem to work + * with polled devices, and it's fine to call IDirectInputDevice8_GetDeviceData and + * let it return 0 events. */ + +#include "SDL_error.h" +#include "SDL_events.h" +#include "SDL_hints.h" +#include "SDL_timer.h" +#include "SDL_mutex.h" +#include "SDL_joystick.h" +#include "../SDL_sysjoystick.h" +#include "../../thread/SDL_systhread.h" +#include "../../core/windows/SDL_windows.h" +#if !defined(__WINRT__) && !defined(__XBOXONE__) && !defined(__XBOXSERIES__) +#include +#endif + +#define INITGUID /* Only set here, if set twice will cause mingw32 to break. */ +#include "SDL_windowsjoystick_c.h" +#include "SDL_dinputjoystick_c.h" +#include "SDL_xinputjoystick_c.h" +#include "SDL_rawinputjoystick_c.h" + +#include "../../haptic/windows/SDL_dinputhaptic_c.h" /* For haptic hot plugging */ +#include "../../haptic/windows/SDL_xinputhaptic_c.h" /* For haptic hot plugging */ + +#ifndef DEVICE_NOTIFY_WINDOW_HANDLE +#define DEVICE_NOTIFY_WINDOW_HANDLE 0x00000000 +#endif + +/* CM_Register_Notification definitions */ + +#define CR_SUCCESS (0x00000000) + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +DECLARE_HANDLE(HCMNOTIFICATION); +typedef HCMNOTIFICATION *PHCMNOTIFICATION; + +typedef enum _CM_NOTIFY_FILTER_TYPE +{ + CM_NOTIFY_FILTER_TYPE_DEVICEINTERFACE = 0, + CM_NOTIFY_FILTER_TYPE_DEVICEHANDLE, + CM_NOTIFY_FILTER_TYPE_DEVICEINSTANCE, + CM_NOTIFY_FILTER_TYPE_MAX +} CM_NOTIFY_FILTER_TYPE, + *PCM_NOTIFY_FILTER_TYPE; + +typedef struct _CM_NOTIFY_FILTER +{ + DWORD cbSize; + DWORD Flags; + CM_NOTIFY_FILTER_TYPE FilterType; + DWORD Reserved; + union + { + struct + { + GUID ClassGuid; + } DeviceInterface; + struct + { + HANDLE hTarget; + } DeviceHandle; + struct + { + WCHAR InstanceId[200]; + } DeviceInstance; + } u; +} CM_NOTIFY_FILTER, *PCM_NOTIFY_FILTER; + +typedef enum _CM_NOTIFY_ACTION +{ + CM_NOTIFY_ACTION_DEVICEINTERFACEARRIVAL = 0, + CM_NOTIFY_ACTION_DEVICEINTERFACEREMOVAL, + CM_NOTIFY_ACTION_DEVICEQUERYREMOVE, + CM_NOTIFY_ACTION_DEVICEQUERYREMOVEFAILED, + CM_NOTIFY_ACTION_DEVICEREMOVEPENDING, + CM_NOTIFY_ACTION_DEVICEREMOVECOMPLETE, + CM_NOTIFY_ACTION_DEVICECUSTOMEVENT, + CM_NOTIFY_ACTION_DEVICEINSTANCEENUMERATED, + CM_NOTIFY_ACTION_DEVICEINSTANCESTARTED, + CM_NOTIFY_ACTION_DEVICEINSTANCEREMOVED, + CM_NOTIFY_ACTION_MAX +} CM_NOTIFY_ACTION, + *PCM_NOTIFY_ACTION; + +typedef struct _CM_NOTIFY_EVENT_DATA +{ + CM_NOTIFY_FILTER_TYPE FilterType; + DWORD Reserved; + union + { + struct + { + GUID ClassGuid; + WCHAR SymbolicLink[ANYSIZE_ARRAY]; + } DeviceInterface; + struct + { + GUID EventGuid; + LONG NameOffset; + DWORD DataSize; + BYTE Data[ANYSIZE_ARRAY]; + } DeviceHandle; + struct + { + WCHAR InstanceId[ANYSIZE_ARRAY]; + } DeviceInstance; + } u; +} CM_NOTIFY_EVENT_DATA, *PCM_NOTIFY_EVENT_DATA; + +typedef DWORD(CALLBACK *PCM_NOTIFY_CALLBACK)(HCMNOTIFICATION hNotify, PVOID Context, CM_NOTIFY_ACTION Action, PCM_NOTIFY_EVENT_DATA EventData, DWORD EventDataSize); + +typedef DWORD(WINAPI *CM_Register_NotificationFunc)(PCM_NOTIFY_FILTER pFilter, PVOID pContext, PCM_NOTIFY_CALLBACK pCallback, PHCMNOTIFICATION pNotifyContext); +typedef DWORD(WINAPI *CM_Unregister_NotificationFunc)(HCMNOTIFICATION NotifyContext); + +/* local variables */ +static SDL_bool s_bJoystickThread = SDL_FALSE; +static SDL_bool s_bWindowsDeviceChanged = SDL_FALSE; +static SDL_cond *s_condJoystickThread = NULL; +static SDL_mutex *s_mutexJoyStickEnum = NULL; +static SDL_Thread *s_joystickThread = NULL; +static SDL_bool s_bJoystickThreadQuit = SDL_FALSE; +static GUID GUID_DEVINTERFACE_HID = { 0x4D1E55B2L, 0xF16F, 0x11CF, { 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 } }; + +JoyStick_DeviceData *SYS_Joystick; /* array to hold joystick ID values */ + +#if !defined(__WINRT__) && !defined(__XBOXONE__) && !defined(__XBOXSERIES__) +static HMODULE cfgmgr32_lib_handle; +static CM_Register_NotificationFunc CM_Register_Notification; +static CM_Unregister_NotificationFunc CM_Unregister_Notification; +static HCMNOTIFICATION s_DeviceNotificationFuncHandle; + +void WINDOWS_RAWINPUTEnabledChanged(void) +{ + s_bWindowsDeviceChanged = SDL_TRUE; +} + +static DWORD CALLBACK SDL_DeviceNotificationFunc(HCMNOTIFICATION hNotify, PVOID context, CM_NOTIFY_ACTION action, PCM_NOTIFY_EVENT_DATA eventData, DWORD event_data_size) +{ + if (action == CM_NOTIFY_ACTION_DEVICEINTERFACEARRIVAL || + action == CM_NOTIFY_ACTION_DEVICEINTERFACEREMOVAL) { + s_bWindowsDeviceChanged = SDL_TRUE; + } + return ERROR_SUCCESS; +} + +static void SDL_CleanupDeviceNotificationFunc(void) +{ + if (cfgmgr32_lib_handle) { + if (s_DeviceNotificationFuncHandle != NULL && CM_Unregister_Notification) { + CM_Unregister_Notification(s_DeviceNotificationFuncHandle); + s_DeviceNotificationFuncHandle = NULL; + } + + FreeLibrary(cfgmgr32_lib_handle); + cfgmgr32_lib_handle = NULL; + } +} + +static SDL_bool SDL_CreateDeviceNotificationFunc(void) +{ + cfgmgr32_lib_handle = LoadLibraryA("cfgmgr32.dll"); + if (cfgmgr32_lib_handle) { + CM_Register_Notification = (CM_Register_NotificationFunc)GetProcAddress(cfgmgr32_lib_handle, "CM_Register_Notification"); + CM_Unregister_Notification = (CM_Unregister_NotificationFunc)GetProcAddress(cfgmgr32_lib_handle, "CM_Unregister_Notification"); + if (CM_Register_Notification && CM_Unregister_Notification) { + CM_NOTIFY_FILTER notify_filter; + + SDL_zero(notify_filter); + notify_filter.cbSize = sizeof(notify_filter); + notify_filter.FilterType = CM_NOTIFY_FILTER_TYPE_DEVICEINTERFACE; + notify_filter.u.DeviceInterface.ClassGuid = GUID_DEVINTERFACE_HID; + if (CM_Register_Notification(¬ify_filter, NULL, SDL_DeviceNotificationFunc, &s_DeviceNotificationFuncHandle) == CR_SUCCESS) { + return SDL_TRUE; + } + } + } + + SDL_CleanupDeviceNotificationFunc(); + return SDL_FALSE; +} + +typedef struct +{ + HRESULT coinitialized; + WNDCLASSEX wincl; + HWND messageWindow; + HDEVNOTIFY hNotify; +} SDL_DeviceNotificationData; + +#define IDT_SDL_DEVICE_CHANGE_TIMER_1 1200 +#define IDT_SDL_DEVICE_CHANGE_TIMER_2 1201 + +/* windowproc for our joystick detect thread message only window, to detect any USB device addition/removal */ +static LRESULT CALLBACK SDL_PrivateJoystickDetectProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) { + case WM_DEVICECHANGE: + switch (wParam) { + case DBT_DEVICEARRIVAL: + case DBT_DEVICEREMOVECOMPLETE: + if (((DEV_BROADCAST_HDR *)lParam)->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) { + /* notify 300ms and 2 seconds later to ensure all APIs have updated status */ + SetTimer(hwnd, IDT_SDL_DEVICE_CHANGE_TIMER_1, 300, NULL); + SetTimer(hwnd, IDT_SDL_DEVICE_CHANGE_TIMER_2, 2000, NULL); + } + break; + } + return 0; + case WM_TIMER: + if (wParam == IDT_SDL_DEVICE_CHANGE_TIMER_1 || + wParam == IDT_SDL_DEVICE_CHANGE_TIMER_2) { + KillTimer(hwnd, wParam); + s_bWindowsDeviceChanged = SDL_TRUE; + return 0; + } + break; + } + +#ifdef SDL_JOYSTICK_RAWINPUT + return CallWindowProc(RAWINPUT_WindowProc, hwnd, msg, wParam, lParam); +#else + return CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam); +#endif +} + +static void SDL_CleanupDeviceNotification(SDL_DeviceNotificationData *data) +{ +#ifdef SDL_JOYSTICK_RAWINPUT + RAWINPUT_UnregisterNotifications(); +#endif + + if (data->hNotify) { + UnregisterDeviceNotification(data->hNotify); + } + + if (data->messageWindow) { + DestroyWindow(data->messageWindow); + } + + UnregisterClass(data->wincl.lpszClassName, data->wincl.hInstance); + + if (data->coinitialized == S_OK) { + WIN_CoUninitialize(); + } +} + +static int SDL_CreateDeviceNotification(SDL_DeviceNotificationData *data) +{ + DEV_BROADCAST_DEVICEINTERFACE dbh; + + SDL_zerop(data); + + data->coinitialized = WIN_CoInitialize(); + + data->wincl.hInstance = GetModuleHandle(NULL); + data->wincl.lpszClassName = TEXT("Message"); + data->wincl.lpfnWndProc = SDL_PrivateJoystickDetectProc; /* This function is called by windows */ + data->wincl.cbSize = sizeof(WNDCLASSEX); + + if (!RegisterClassEx(&data->wincl)) { + WIN_SetError("Failed to create register class for joystick autodetect"); + SDL_CleanupDeviceNotification(data); + return -1; + } + + data->messageWindow = CreateWindowEx(0, TEXT("Message"), NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL); + if (!data->messageWindow) { + WIN_SetError("Failed to create message window for joystick autodetect"); + SDL_CleanupDeviceNotification(data); + return -1; + } + + SDL_zero(dbh); + dbh.dbcc_size = sizeof(dbh); + dbh.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; + dbh.dbcc_classguid = GUID_DEVINTERFACE_HID; + + data->hNotify = RegisterDeviceNotification(data->messageWindow, &dbh, DEVICE_NOTIFY_WINDOW_HANDLE); + if (!data->hNotify) { + WIN_SetError("Failed to create notify device for joystick autodetect"); + SDL_CleanupDeviceNotification(data); + return -1; + } + +#ifdef SDL_JOYSTICK_RAWINPUT + RAWINPUT_RegisterNotifications(data->messageWindow); +#endif + return 0; +} + +static SDL_bool SDL_WaitForDeviceNotification(SDL_DeviceNotificationData *data, SDL_mutex *mutex) +{ + MSG msg; + int lastret = 1; + + if (!data->messageWindow) { + return SDL_FALSE; /* device notifications require a window */ + } + + SDL_UnlockMutex(mutex); + while (lastret > 0 && s_bWindowsDeviceChanged == SDL_FALSE) { + lastret = GetMessage(&msg, NULL, 0, 0); /* WM_QUIT causes return value of 0 */ + if (lastret > 0) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + SDL_LockMutex(mutex); + return (lastret != -1) ? SDL_TRUE : SDL_FALSE; +} + +#endif /* !defined(__WINRT__) && !defined(__XBOXONE__) && !defined(__XBOXSERIES__) */ + +#if !defined(__WINRT__) + +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) +static SDL_DeviceNotificationData s_notification_data; +#endif + +/* Function/thread to scan the system for joysticks. */ +static int SDLCALL SDL_JoystickThread(void *_data) +{ +#ifdef SDL_JOYSTICK_XINPUT + SDL_bool bOpenedXInputDevices[XUSER_MAX_COUNT]; + SDL_zeroa(bOpenedXInputDevices); +#endif + +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + if (SDL_CreateDeviceNotification(&s_notification_data) < 0) { + return -1; + } +#endif + + SDL_LockMutex(s_mutexJoyStickEnum); + while (s_bJoystickThreadQuit == SDL_FALSE) { +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + if (SDL_WaitForDeviceNotification(&s_notification_data, s_mutexJoyStickEnum) == SDL_FALSE) { +#else + { +#endif +#ifdef SDL_JOYSTICK_XINPUT + /* WM_DEVICECHANGE not working, poll for new XINPUT controllers */ + SDL_CondWaitTimeout(s_condJoystickThread, s_mutexJoyStickEnum, 1000); + if (SDL_XINPUT_Enabled() && XINPUTGETCAPABILITIES) { + /* scan for any change in XInput devices */ + Uint8 userId; + for (userId = 0; userId < XUSER_MAX_COUNT; userId++) { + XINPUT_CAPABILITIES capabilities; + const DWORD result = XINPUTGETCAPABILITIES(userId, XINPUT_FLAG_GAMEPAD, &capabilities); + const SDL_bool available = (result == ERROR_SUCCESS) ? SDL_TRUE : SDL_FALSE; + if (bOpenedXInputDevices[userId] != available) { + s_bWindowsDeviceChanged = SDL_TRUE; + bOpenedXInputDevices[userId] = available; + } + } + } +#else + /* WM_DEVICECHANGE not working, no XINPUT, no point in keeping thread alive */ + break; +#endif /* SDL_JOYSTICK_XINPUT */ + } + } + + SDL_UnlockMutex(s_mutexJoyStickEnum); + +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + SDL_CleanupDeviceNotification(&s_notification_data); +#endif + + return 1; +} + +/* spin up the thread to detect hotplug of devices */ +static int SDL_StartJoystickThread(void) +{ + s_mutexJoyStickEnum = SDL_CreateMutex(); + if (!s_mutexJoyStickEnum) { + return -1; + } + + s_condJoystickThread = SDL_CreateCond(); + if (!s_condJoystickThread) { + return -1; + } + + s_bJoystickThreadQuit = SDL_FALSE; + s_joystickThread = SDL_CreateThreadInternal(SDL_JoystickThread, "SDL_joystick", 64 * 1024, NULL); + if (!s_joystickThread) { + return -1; + } + return 0; +} + +static void SDL_StopJoystickThread(void) +{ + if (!s_joystickThread) { + return; + } + + SDL_LockMutex(s_mutexJoyStickEnum); + s_bJoystickThreadQuit = SDL_TRUE; + SDL_CondBroadcast(s_condJoystickThread); /* signal the joystick thread to quit */ + SDL_UnlockMutex(s_mutexJoyStickEnum); + PostThreadMessage(SDL_GetThreadID(s_joystickThread), WM_QUIT, 0, 0); + + /* Unlock joysticks while the joystick thread finishes processing messages */ + SDL_AssertJoysticksLocked(); + SDL_UnlockJoysticks(); + SDL_WaitThread(s_joystickThread, NULL); /* wait for it to bugger off */ + SDL_LockJoysticks(); + + SDL_DestroyCond(s_condJoystickThread); + s_condJoystickThread = NULL; + + SDL_DestroyMutex(s_mutexJoyStickEnum); + s_mutexJoyStickEnum = NULL; + + s_joystickThread = NULL; +} + +#endif /* !defined(__WINRT__) */ + +void WINDOWS_AddJoystickDevice(JoyStick_DeviceData *device) +{ + device->send_add_event = SDL_TRUE; + device->nInstanceID = SDL_GetNextJoystickInstanceID(); + device->pNext = SYS_Joystick; + SYS_Joystick = device; +} + +void WINDOWS_JoystickDetect(void); +void WINDOWS_JoystickQuit(void); + +/* 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. + */ +static int WINDOWS_JoystickInit(void) +{ + if (SDL_DINPUT_JoystickInit() < 0) { + WINDOWS_JoystickQuit(); + return -1; + } + + if (SDL_XINPUT_JoystickInit() < 0) { + WINDOWS_JoystickQuit(); + return -1; + } + + s_bWindowsDeviceChanged = SDL_TRUE; /* force a scan of the system for joysticks this first time */ + + WINDOWS_JoystickDetect(); + +#if !defined(__WINRT__) && !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + SDL_CreateDeviceNotificationFunc(); + + s_bJoystickThread = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_THREAD, SDL_FALSE); + if (s_bJoystickThread) { + if (SDL_StartJoystickThread() < 0) { + return -1; + } + } else { + if (SDL_CreateDeviceNotification(&s_notification_data) < 0) { + return -1; + } + } +#endif + +#if defined(__XBOXONE__) || defined(__XBOXSERIES__) + /* On Xbox, force create the joystick thread for device detection (since other methods don't work */ + s_bJoystickThread = SDL_TRUE; + if (SDL_StartJoystickThread() < 0) { + return -1; + } +#endif + return 0; +} + +/* return the number of joysticks that are connected right now */ +static int WINDOWS_JoystickGetCount(void) +{ + int nJoysticks = 0; + JoyStick_DeviceData *device = SYS_Joystick; + while (device) { + nJoysticks++; + device = device->pNext; + } + + return nJoysticks; +} + +/* detect any new joysticks being inserted into the system */ +void WINDOWS_JoystickDetect(void) +{ + JoyStick_DeviceData *pCurList = NULL; + + /* only enum the devices if the joystick thread told us something changed */ + if (!s_bWindowsDeviceChanged) { + return; /* thread hasn't signaled, nothing to do right now. */ + } + + if (s_mutexJoyStickEnum) { + SDL_LockMutex(s_mutexJoyStickEnum); + } + + s_bWindowsDeviceChanged = SDL_FALSE; + + pCurList = SYS_Joystick; + SYS_Joystick = NULL; + + /* Look for DirectInput joysticks, wheels, head trackers, gamepads, etc.. */ + SDL_DINPUT_JoystickDetect(&pCurList); + + /* Look for XInput devices. Do this last, so they're first in the final list. */ + SDL_XINPUT_JoystickDetect(&pCurList); + + if (s_mutexJoyStickEnum) { + SDL_UnlockMutex(s_mutexJoyStickEnum); + } + + while (pCurList) { + JoyStick_DeviceData *pListNext = NULL; + + if (pCurList->bXInputDevice) { +#ifdef SDL_HAPTIC_XINPUT + SDL_XINPUT_HapticMaybeRemoveDevice(pCurList->XInputUserId); +#endif + } else { +#ifdef SDL_HAPTIC_DINPUT + SDL_DINPUT_HapticMaybeRemoveDevice(&pCurList->dxdevice); +#endif + } + + SDL_PrivateJoystickRemoved(pCurList->nInstanceID); + + pListNext = pCurList->pNext; + SDL_free(pCurList->joystickname); + SDL_free(pCurList); + pCurList = pListNext; + } + + for (pCurList = SYS_Joystick; pCurList; pCurList = pCurList->pNext) { + if (pCurList->send_add_event) { + if (pCurList->bXInputDevice) { +#ifdef SDL_HAPTIC_XINPUT + SDL_XINPUT_HapticMaybeAddDevice(pCurList->XInputUserId); +#endif + } else { +#ifdef SDL_HAPTIC_DINPUT + SDL_DINPUT_HapticMaybeAddDevice(&pCurList->dxdevice); +#endif + } + + SDL_PrivateJoystickAdded(pCurList->nInstanceID); + + pCurList->send_add_event = SDL_FALSE; + } + } +} + +static const char *WINDOWS_JoystickGetDeviceName(int device_index) +{ + JoyStick_DeviceData *device = SYS_Joystick; + int index; + + for (index = device_index; index > 0; index--) { + device = device->pNext; + } + + return device->joystickname; +} + +static const char *WINDOWS_JoystickGetDevicePath(int device_index) +{ + JoyStick_DeviceData *device = SYS_Joystick; + int index; + + for (index = device_index; index > 0; index--) { + device = device->pNext; + } + + return device->path; +} + +static int WINDOWS_JoystickGetDeviceSteamVirtualGamepadSlot(int device_index) +{ + JoyStick_DeviceData *device = SYS_Joystick; + int index; + + for (index = device_index; index > 0; index--) { + device = device->pNext; + } + + if (device->bXInputDevice) { + /* The slot for XInput devices can change as controllers are seated */ + return SDL_XINPUT_GetSteamVirtualGamepadSlot(device->XInputUserId); + } else { + return device->steam_virtual_gamepad_slot; + } +} + +static int WINDOWS_JoystickGetDevicePlayerIndex(int device_index) +{ + JoyStick_DeviceData *device = SYS_Joystick; + int index; + + for (index = device_index; index > 0; index--) { + device = device->pNext; + } + + return device->bXInputDevice ? (int)device->XInputUserId : -1; +} + +static void WINDOWS_JoystickSetDevicePlayerIndex(int device_index, int player_index) +{ +} + +/* return the stable device guid for this device index */ +static SDL_JoystickGUID WINDOWS_JoystickGetDeviceGUID(int device_index) +{ + JoyStick_DeviceData *device = SYS_Joystick; + int index; + + for (index = device_index; index > 0; index--) { + device = device->pNext; + } + + return device->guid; +} + +/* Function to perform the mapping between current device instance and this joysticks instance id */ +static SDL_JoystickID WINDOWS_JoystickGetDeviceInstanceID(int device_index) +{ + JoyStick_DeviceData *device = SYS_Joystick; + int index; + + for (index = device_index; index > 0; index--) { + device = device->pNext; + } + + return device->nInstanceID; +} + +/* Function to open a joystick for use. + The joystick to open is specified by the device index. + This should fill the nbuttons and naxes fields of the joystick structure. + It returns 0, or -1 if there is an error. + */ +static int WINDOWS_JoystickOpen(SDL_Joystick *joystick, int device_index) +{ + JoyStick_DeviceData *device = SYS_Joystick; + int index; + + for (index = device_index; index > 0; index--) { + device = device->pNext; + } + + /* allocate memory for system specific hardware data */ + joystick->instance_id = device->nInstanceID; + joystick->hwdata = (struct joystick_hwdata *)SDL_calloc(1, sizeof(struct joystick_hwdata)); + if (!joystick->hwdata) { + return SDL_OutOfMemory(); + } + joystick->hwdata->guid = device->guid; + + if (device->bXInputDevice) { + return SDL_XINPUT_JoystickOpen(joystick, device); + } else { + return SDL_DINPUT_JoystickOpen(joystick, device); + } +} + +static int WINDOWS_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +{ + if (joystick->hwdata->bXInputDevice) { + return SDL_XINPUT_JoystickRumble(joystick, low_frequency_rumble, high_frequency_rumble); + } else { + return SDL_DINPUT_JoystickRumble(joystick, low_frequency_rumble, high_frequency_rumble); + } +} + +static int WINDOWS_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble) +{ + return SDL_Unsupported(); +} + +static Uint32 WINDOWS_JoystickGetCapabilities(SDL_Joystick *joystick) +{ + if (joystick->hwdata->bXInputDevice) { + return SDL_XINPUT_JoystickGetCapabilities(joystick); + } else { + return SDL_DINPUT_JoystickGetCapabilities(joystick); + } +} + +static int WINDOWS_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) +{ + return SDL_Unsupported(); +} + +static int WINDOWS_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size) +{ + return SDL_Unsupported(); +} + +static int WINDOWS_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled) +{ + return SDL_Unsupported(); +} + +static void WINDOWS_JoystickUpdate(SDL_Joystick *joystick) +{ + if (!joystick->hwdata) { + return; + } + + if (joystick->hwdata->bXInputDevice) { + SDL_XINPUT_JoystickUpdate(joystick); + } else { + SDL_DINPUT_JoystickUpdate(joystick); + } +} + +/* Function to close a joystick after use */ +static void WINDOWS_JoystickClose(SDL_Joystick *joystick) +{ + if (joystick->hwdata->bXInputDevice) { + SDL_XINPUT_JoystickClose(joystick); + } else { + SDL_DINPUT_JoystickClose(joystick); + } + + SDL_free(joystick->hwdata); +} + +/* Function to perform any system-specific joystick related cleanup */ +void WINDOWS_JoystickQuit(void) +{ + JoyStick_DeviceData *device = SYS_Joystick; + + while (device) { + JoyStick_DeviceData *device_next = device->pNext; + SDL_free(device->joystickname); + SDL_free(device); + device = device_next; + } + SYS_Joystick = NULL; + +#if !defined(__WINRT__) && !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + if (s_bJoystickThread) { + SDL_StopJoystickThread(); + } else { + SDL_CleanupDeviceNotification(&s_notification_data); + } + + SDL_CleanupDeviceNotificationFunc(); +#endif + +#if defined(__XBOXONE__) || defined(__XBOXSERIES__) + if (s_bJoystickThread) { + SDL_StopJoystickThread(); + } +#endif + + SDL_DINPUT_JoystickQuit(); + SDL_XINPUT_JoystickQuit(); + + s_bWindowsDeviceChanged = SDL_FALSE; +} + +static SDL_bool WINDOWS_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) +{ + return SDL_FALSE; +} + +SDL_JoystickDriver SDL_WINDOWS_JoystickDriver = { + WINDOWS_JoystickInit, + WINDOWS_JoystickGetCount, + WINDOWS_JoystickDetect, + WINDOWS_JoystickGetDeviceName, + WINDOWS_JoystickGetDevicePath, + WINDOWS_JoystickGetDeviceSteamVirtualGamepadSlot, + WINDOWS_JoystickGetDevicePlayerIndex, + WINDOWS_JoystickSetDevicePlayerIndex, + WINDOWS_JoystickGetDeviceGUID, + WINDOWS_JoystickGetDeviceInstanceID, + WINDOWS_JoystickOpen, + WINDOWS_JoystickRumble, + WINDOWS_JoystickRumbleTriggers, + WINDOWS_JoystickGetCapabilities, + WINDOWS_JoystickSetLED, + WINDOWS_JoystickSendEffect, + WINDOWS_JoystickSetSensorsEnabled, + WINDOWS_JoystickUpdate, + WINDOWS_JoystickClose, + WINDOWS_JoystickQuit, + WINDOWS_JoystickGetGamepadMapping +}; + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif + +#else + +#ifdef SDL_JOYSTICK_RAWINPUT +/* The RAWINPUT driver needs the device notification setup above */ +#error SDL_JOYSTICK_RAWINPUT requires SDL_JOYSTICK_DINPUT || defined(SDL_JOYSTICK_XINPUT) +#endif + +#endif /* SDL_JOYSTICK_DINPUT || SDL_JOYSTICK_XINPUT */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/joystick/windows/SDL_windowsjoystick_c.h b/SDL2-2.30.5/src/joystick/windows/SDL_windowsjoystick_c.h similarity index 79% rename from SDL2-2.0.12/src/joystick/windows/SDL_windowsjoystick_c.h rename to SDL2-2.30.5/src/joystick/windows/SDL_windowsjoystick_c.h index 4dbc876..18c39e8 100644 --- a/SDL2-2.0.12/src/joystick/windows/SDL_windowsjoystick_c.h +++ b/SDL2-2.30.5/src/joystick/windows/SDL_windowsjoystick_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -25,7 +25,12 @@ #include "../../core/windows/SDL_windows.h" #include "../../core/windows/SDL_directx.h" -#define MAX_INPUTS 256 /* each joystick can have up to 256 inputs */ +#define MAX_INPUTS 256 /* each joystick can have up to 256 inputs */ + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif typedef struct JoyStick_DeviceData { @@ -37,11 +42,12 @@ typedef struct JoyStick_DeviceData BYTE SubType; Uint8 XInputUserId; DIDEVICEINSTANCE dxdevice; - WCHAR hidPath[MAX_PATH]; + char path[MAX_PATH]; + int steam_virtual_gamepad_slot; struct JoyStick_DeviceData *pNext; } JoyStick_DeviceData; -extern JoyStick_DeviceData *SYS_Joystick; /* array to hold joystick ID values */ +extern JoyStick_DeviceData *SYS_Joystick; /* array to hold joystick ID values */ typedef enum Type { @@ -67,10 +73,11 @@ struct joystick_hwdata { SDL_JoystickGUID guid; -#if SDL_JOYSTICK_DINPUT +#ifdef SDL_JOYSTICK_DINPUT LPDIRECTINPUTDEVICE8 InputDevice; DIDEVCAPS Capabilities; SDL_bool buffered; + SDL_bool first_update; input_t Inputs[MAX_INPUTS]; int NumInputs; int NumSliders; @@ -81,14 +88,19 @@ struct joystick_hwdata SDL_bool bXInputDevice; /* SDL_TRUE if this device supports using the xinput API rather than DirectInput */ SDL_bool bXInputHaptic; /* Supports force feedback via XInput. */ - Uint8 userid; /* XInput userid index for this joystick */ + Uint8 userid; /* XInput userid index for this joystick */ DWORD dwPacketNumber; }; -#if SDL_JOYSTICK_DINPUT +#ifdef SDL_JOYSTICK_DINPUT extern const DIDATAFORMAT SDL_c_dfDIJoystick2; #endif extern void WINDOWS_AddJoystickDevice(JoyStick_DeviceData *device); +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/joystick/windows/SDL_xinputjoystick.c b/SDL2-2.30.5/src/joystick/windows/SDL_xinputjoystick.c similarity index 58% rename from SDL2-2.0.12/src/joystick/windows/SDL_xinputjoystick.c rename to SDL2-2.30.5/src/joystick/windows/SDL_xinputjoystick.c index c863b02..38c27d8 100644 --- a/SDL2-2.0.12/src/joystick/windows/SDL_xinputjoystick.c +++ b/SDL2-2.30.5/src/joystick/windows/SDL_xinputjoystick.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -22,36 +22,39 @@ #include "../SDL_sysjoystick.h" -#if SDL_JOYSTICK_XINPUT +#ifdef SDL_JOYSTICK_XINPUT -#include "SDL_assert.h" #include "SDL_hints.h" -#include "SDL_log.h" #include "SDL_timer.h" #include "SDL_windowsjoystick_c.h" #include "SDL_xinputjoystick_c.h" +#include "SDL_rawinputjoystick_c.h" #include "../hidapi/SDL_hidapijoystick_c.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + /* * Internal stuff. */ static SDL_bool s_bXInputEnabled = SDL_TRUE; -static char *s_arrXInputDevicePath[XUSER_MAX_COUNT]; - -static SDL_bool -SDL_XInputUseOldJoystickMapping() +static SDL_bool SDL_XInputUseOldJoystickMapping() { #ifdef __WINRT__ /* TODO: remove this __WINRT__ block, but only after integrating with UWP/WinRT's HID API */ /* FIXME: Why are Win8/10 different here? -flibit */ - return (NTDDI_VERSION < NTDDI_WIN10); + return NTDDI_VERSION < NTDDI_WIN10; +#elif defined(__XBOXONE__) || defined(__XBOXSERIES__) + return SDL_FALSE; #else static int s_XInputUseOldJoystickMapping = -1; if (s_XInputUseOldJoystickMapping < 0) { s_XInputUseOldJoystickMapping = SDL_GetHintBoolean(SDL_HINT_XINPUT_USE_OLD_JOYSTICK_MAPPING, SDL_FALSE); } - return (s_XInputUseOldJoystickMapping > 0); + return s_XInputUseOldJoystickMapping > 0; #endif } @@ -60,175 +63,127 @@ SDL_bool SDL_XINPUT_Enabled(void) return s_bXInputEnabled; } -int -SDL_XINPUT_JoystickInit(void) +int SDL_XINPUT_JoystickInit(void) { s_bXInputEnabled = SDL_GetHintBoolean(SDL_HINT_XINPUT_ENABLED, SDL_TRUE); if (s_bXInputEnabled && WIN_LoadXInputDLL() < 0) { - s_bXInputEnabled = SDL_FALSE; /* oh well. */ + s_bXInputEnabled = SDL_FALSE; /* oh well. */ } return 0; } -static char * -GetXInputName(const Uint8 userid, BYTE SubType) +static const char *GetXInputName(const Uint8 userid, BYTE SubType) { - char name[32]; + static char name[32]; if (SDL_XInputUseOldJoystickMapping()) { - SDL_snprintf(name, sizeof(name), "X360 Controller #%u", 1 + userid); + (void)SDL_snprintf(name, sizeof(name), "X360 Controller #%u", 1 + userid); } else { switch (SubType) { case XINPUT_DEVSUBTYPE_GAMEPAD: - SDL_snprintf(name, sizeof(name), "XInput Controller #%u", 1 + userid); + (void)SDL_snprintf(name, sizeof(name), "XInput Controller #%u", 1 + userid); break; case XINPUT_DEVSUBTYPE_WHEEL: - SDL_snprintf(name, sizeof(name), "XInput Wheel #%u", 1 + userid); + (void)SDL_snprintf(name, sizeof(name), "XInput Wheel #%u", 1 + userid); break; case XINPUT_DEVSUBTYPE_ARCADE_STICK: - SDL_snprintf(name, sizeof(name), "XInput ArcadeStick #%u", 1 + userid); + (void)SDL_snprintf(name, sizeof(name), "XInput ArcadeStick #%u", 1 + userid); break; case XINPUT_DEVSUBTYPE_FLIGHT_STICK: - SDL_snprintf(name, sizeof(name), "XInput FlightStick #%u", 1 + userid); + (void)SDL_snprintf(name, sizeof(name), "XInput FlightStick #%u", 1 + userid); break; case XINPUT_DEVSUBTYPE_DANCE_PAD: - SDL_snprintf(name, sizeof(name), "XInput DancePad #%u", 1 + userid); + (void)SDL_snprintf(name, sizeof(name), "XInput DancePad #%u", 1 + userid); break; case XINPUT_DEVSUBTYPE_GUITAR: case XINPUT_DEVSUBTYPE_GUITAR_ALTERNATE: case XINPUT_DEVSUBTYPE_GUITAR_BASS: - SDL_snprintf(name, sizeof(name), "XInput Guitar #%u", 1 + userid); + (void)SDL_snprintf(name, sizeof(name), "XInput Guitar #%u", 1 + userid); break; case XINPUT_DEVSUBTYPE_DRUM_KIT: - SDL_snprintf(name, sizeof(name), "XInput DrumKit #%u", 1 + userid); + (void)SDL_snprintf(name, sizeof(name), "XInput DrumKit #%u", 1 + userid); break; case XINPUT_DEVSUBTYPE_ARCADE_PAD: - SDL_snprintf(name, sizeof(name), "XInput ArcadePad #%u", 1 + userid); + (void)SDL_snprintf(name, sizeof(name), "XInput ArcadePad #%u", 1 + userid); break; default: - SDL_snprintf(name, sizeof(name), "XInput Device #%u", 1 + userid); + (void)SDL_snprintf(name, sizeof(name), "XInput Device #%u", 1 + userid); break; } } - return SDL_strdup(name); + return name; } -/* We can't really tell what device is being used for XInput, but we can guess - and we'll be correct for the case where only one device is connected. - */ -static void -GuessXInputDevice(Uint8 userid, Uint16 *pVID, Uint16 *pPID, Uint16 *pVersion) +static SDL_bool GetXInputDeviceInfo(Uint8 userid, Uint16 *pVID, Uint16 *pPID, Uint16 *pVersion) { -#ifndef __WINRT__ /* TODO: remove this ifndef __WINRT__ block, but only after integrating with UWP/WinRT's HID API */ + SDL_XINPUT_CAPABILITIES_EX capabilities; - PRAWINPUTDEVICELIST devices = NULL; - UINT i, j, device_count = 0; - - if ((GetRawInputDeviceList(NULL, &device_count, sizeof(RAWINPUTDEVICELIST)) == -1) || (!device_count)) { - return; /* oh well. */ + if (!XINPUTGETCAPABILITIESEX || XINPUTGETCAPABILITIESEX(1, userid, 0, &capabilities) != ERROR_SUCCESS) { + return SDL_FALSE; } - devices = (PRAWINPUTDEVICELIST)SDL_malloc(sizeof(RAWINPUTDEVICELIST) * device_count); - if (devices == NULL) { - return; + /* Fixup for Wireless Xbox 360 Controller */ + if (capabilities.ProductId == 0 && capabilities.Capabilities.Flags & XINPUT_CAPS_WIRELESS) { + capabilities.VendorId = USB_VENDOR_MICROSOFT; + capabilities.ProductId = USB_PRODUCT_XBOX360_XUSB_CONTROLLER; } - if (GetRawInputDeviceList(devices, &device_count, sizeof(RAWINPUTDEVICELIST)) == -1) { - SDL_free(devices); - return; /* oh well. */ + if (pVID) { + *pVID = capabilities.VendorId; } - - /* First see if we have a cached entry for this index */ - if (s_arrXInputDevicePath[userid]) { - for (i = 0; i < device_count; i++) { - RID_DEVICE_INFO rdi; - char devName[128]; - UINT rdiSize = sizeof(rdi); - UINT nameSize = SDL_arraysize(devName); - - rdi.cbSize = sizeof(rdi); - if (devices[i].dwType == RIM_TYPEHID && - GetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICEINFO, &rdi, &rdiSize) != (UINT)-1 && - GetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICENAME, devName, &nameSize) != (UINT)-1) { - if (SDL_strcmp(devName, s_arrXInputDevicePath[userid]) == 0) { - *pVID = (Uint16)rdi.hid.dwVendorId; - *pPID = (Uint16)rdi.hid.dwProductId; - *pVersion = (Uint16)rdi.hid.dwVersionNumber; - return; - } - } - } + if (pPID) { + *pPID = capabilities.ProductId; } - - for (i = 0; i < device_count; i++) { - RID_DEVICE_INFO rdi; - char devName[128]; - UINT rdiSize = sizeof(rdi); - UINT nameSize = SDL_arraysize(devName); - - rdi.cbSize = sizeof(rdi); - if (devices[i].dwType == RIM_TYPEHID && - GetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICEINFO, &rdi, &rdiSize) != (UINT)-1 && - GetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICENAME, devName, &nameSize) != (UINT)-1) { -#ifdef DEBUG_JOYSTICK - SDL_Log("Raw input device: VID = 0x%x, PID = 0x%x, %s\n", rdi.hid.dwVendorId, rdi.hid.dwProductId, devName); -#endif - if (SDL_strstr(devName, "IG_") != NULL) { - SDL_bool found = SDL_FALSE; - for (j = 0; j < SDL_arraysize(s_arrXInputDevicePath); ++j) { - if (!s_arrXInputDevicePath[j]) { - continue; - } - if (SDL_strcmp(devName, s_arrXInputDevicePath[j]) == 0) { - found = SDL_TRUE; - break; - } - } - if (found) { - /* We already have this device in our XInput device list */ - continue; - } - - /* We don't actually know if this is the right device for this - * userid, but we'll record it so we'll at least be consistent - * when the raw device list changes. - */ - *pVID = (Uint16)rdi.hid.dwVendorId; - *pPID = (Uint16)rdi.hid.dwProductId; - *pVersion = (Uint16)rdi.hid.dwVersionNumber; - if (s_arrXInputDevicePath[userid]) { - SDL_free(s_arrXInputDevicePath[userid]); - } - s_arrXInputDevicePath[userid] = SDL_strdup(devName); - return; - } - } + if (pVersion) { + *pVersion = capabilities.ProductVersion; } - SDL_free(devices); -#endif /* ifndef __WINRT__ */ - - /* The device wasn't in the raw HID device list, it's probably Bluetooth */ - *pVID = 0x045e; /* Microsoft */ - *pPID = 0x02fd; /* XBox One S Bluetooth */ - *pVersion = 0; + return SDL_TRUE; } -static void -AddXInputDevice(Uint8 userid, BYTE SubType, JoyStick_DeviceData **pContext) +int SDL_XINPUT_GetSteamVirtualGamepadSlot(Uint8 userid) { + SDL_XINPUT_CAPABILITIES_EX capabilities; + + if (XINPUTGETCAPABILITIESEX && + XINPUTGETCAPABILITIESEX(1, userid, 0, &capabilities) == ERROR_SUCCESS && + capabilities.VendorId == USB_VENDOR_VALVE && + capabilities.ProductId == USB_PRODUCT_STEAM_VIRTUAL_GAMEPAD) { + return (int)capabilities.unk2; + } + return -1; +} + +static void AddXInputDevice(Uint8 userid, BYTE SubType, JoyStick_DeviceData **pContext) +{ + const char *name = NULL; Uint16 vendor = 0; Uint16 product = 0; Uint16 version = 0; - const char *name; JoyStick_DeviceData *pPrevJoystick = NULL; JoyStick_DeviceData *pNewJoystick = *pContext; - if (SDL_XInputUseOldJoystickMapping() && SubType != XINPUT_DEVSUBTYPE_GAMEPAD) - return; +#ifdef SDL_JOYSTICK_RAWINPUT + if (RAWINPUT_IsEnabled()) { + /* The raw input driver handles more than 4 controllers, so prefer that when available */ + /* We do this check here rather than at the top of SDL_XINPUT_JoystickDetect() because + we need to check XInput state before RAWINPUT gets a hold of the device, otherwise + when a controller is connected via the wireless adapter, it will shut down at the + first subsequent XInput call. This seems like a driver stack bug? - if (SubType == XINPUT_DEVSUBTYPE_UNKNOWN) + Reference: https://github.com/libsdl-org/SDL/issues/3468 + */ return; + } +#endif + + if (SDL_XInputUseOldJoystickMapping() && SubType != XINPUT_DEVSUBTYPE_GAMEPAD) { + return; + } + + if (SubType == XINPUT_DEVSUBTYPE_UNKNOWN) { + return; + } while (pNewJoystick) { if (pNewJoystick->bXInputDevice && (pNewJoystick->XInputUserId == userid) && (pNewJoystick->SubType == SubType)) { @@ -241,7 +196,7 @@ AddXInputDevice(Uint8 userid, BYTE SubType, JoyStick_DeviceData **pContext) pNewJoystick->pNext = SYS_Joystick; SYS_Joystick = pNewJoystick; - return; /* already in the list. */ + return; /* already in the list. */ } pPrevJoystick = pNewJoystick; @@ -253,38 +208,20 @@ AddXInputDevice(Uint8 userid, BYTE SubType, JoyStick_DeviceData **pContext) return; /* better luck next time? */ } + name = GetXInputName(userid, SubType); + GetXInputDeviceInfo(userid, &vendor, &product, &version); pNewJoystick->bXInputDevice = SDL_TRUE; - if (!SDL_XInputUseOldJoystickMapping()) { - Uint16 *guid16 = (Uint16 *)pNewJoystick->guid.data; - - GuessXInputDevice(userid, &vendor, &product, &version); - - *guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_USB); - *guid16++ = 0; - *guid16++ = SDL_SwapLE16(vendor); - *guid16++ = 0; - *guid16++ = SDL_SwapLE16(product); - *guid16++ = 0; - *guid16++ = SDL_SwapLE16(version); - *guid16++ = 0; - - /* Note that this is an XInput device and what subtype it is */ - pNewJoystick->guid.data[14] = 'x'; - pNewJoystick->guid.data[15] = SubType; - } - pNewJoystick->SubType = SubType; - pNewJoystick->XInputUserId = userid; - - name = SDL_GetCustomJoystickName(vendor, product); - if (name) { - pNewJoystick->joystickname = SDL_strdup(name); - } else { - pNewJoystick->joystickname = GetXInputName(userid, SubType); - } + pNewJoystick->joystickname = SDL_CreateJoystickName(vendor, product, NULL, name); if (!pNewJoystick->joystickname) { SDL_free(pNewJoystick); return; /* better luck next time? */ } + (void)SDL_snprintf(pNewJoystick->path, sizeof(pNewJoystick->path), "XInput#%d", userid); + if (!SDL_XInputUseOldJoystickMapping()) { + pNewJoystick->guid = SDL_CreateJoystickGUID(SDL_HARDWARE_BUS_USB, vendor, product, version, NULL, name, 'x', SubType); + } + pNewJoystick->SubType = SubType; + pNewJoystick->XInputUserId = userid; if (SDL_ShouldIgnoreJoystick(pNewJoystick->joystickname, pNewJoystick->guid)) { SDL_free(pNewJoystick); @@ -292,27 +229,26 @@ AddXInputDevice(Uint8 userid, BYTE SubType, JoyStick_DeviceData **pContext) } #ifdef SDL_JOYSTICK_HIDAPI - if (HIDAPI_IsDevicePresent(vendor, product, version, pNewJoystick->joystickname)) { + /* Since we're guessing about the VID/PID, use a hard-coded VID/PID to represent XInput */ + if (HIDAPI_IsDevicePresent(USB_VENDOR_MICROSOFT, USB_PRODUCT_XBOX360_XUSB_CONTROLLER, version, pNewJoystick->joystickname)) { /* The HIDAPI driver is taking care of this device */ SDL_free(pNewJoystick); return; } #endif +#ifdef SDL_JOYSTICK_RAWINPUT + if (RAWINPUT_IsDevicePresent(vendor, product, version, pNewJoystick->joystickname)) { + /* The RAWINPUT driver is taking care of this device */ + SDL_free(pNewJoystick); + return; + } +#endif + WINDOWS_AddJoystickDevice(pNewJoystick); } -static void -DelXInputDevice(Uint8 userid) -{ - if (s_arrXInputDevicePath[userid]) { - SDL_free(s_arrXInputDevicePath[userid]); - s_arrXInputDevicePath[userid] = NULL; - } -} - -void -SDL_XINPUT_JoystickDetect(JoyStick_DeviceData **pContext) +void SDL_XINPUT_JoystickDetect(JoyStick_DeviceData **pContext) { int iuserid; @@ -326,14 +262,11 @@ SDL_XINPUT_JoystickDetect(JoyStick_DeviceData **pContext) XINPUT_CAPABILITIES capabilities; if (XINPUTGETCAPABILITIES(userid, XINPUT_FLAG_GAMEPAD, &capabilities) == ERROR_SUCCESS) { AddXInputDevice(userid, capabilities.SubType, pContext); - } else { - DelXInputDevice(userid); } } } -int -SDL_XINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickdevice) +int SDL_XINPUT_JoystickOpen(SDL_Joystick *joystick, JoyStick_DeviceData *joystickdevice) { const Uint8 userId = joystickdevice->XInputUserId; XINPUT_CAPABILITIES capabilities; @@ -352,7 +285,7 @@ SDL_XINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickde return SDL_SetError("Failed to obtain XInput device capabilities. Device disconnected?"); } SDL_zero(state); - joystick->hwdata->bXInputHaptic = (XINPUTSETSTATE(userId, &state) == ERROR_SUCCESS); + joystick->hwdata->bXInputHaptic = (XINPUTSETSTATE(userId, &state) == ERROR_SUCCESS) ? SDL_TRUE : SDL_FALSE; joystick->hwdata->userid = userId; /* The XInput API has a hard coded button/axis mapping, so we just match it */ @@ -367,8 +300,7 @@ SDL_XINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickde return 0; } -static void -UpdateXInputJoystickBatteryInformation(SDL_Joystick * joystick, XINPUT_BATTERY_INFORMATION_EX *pBatteryInformation) +static void UpdateXInputJoystickBatteryInformation(SDL_Joystick *joystick, XINPUT_BATTERY_INFORMATION_EX *pBatteryInformation) { if (pBatteryInformation->BatteryType != BATTERY_TYPE_UNKNOWN) { SDL_JoystickPowerLevel ePowerLevel = SDL_JOYSTICK_POWER_UNKNOWN; @@ -396,8 +328,7 @@ UpdateXInputJoystickBatteryInformation(SDL_Joystick * joystick, XINPUT_BATTERY_I } } -static void -UpdateXInputJoystickState_OLD(SDL_Joystick * joystick, XINPUT_STATE_EX *pXInputState, XINPUT_BATTERY_INFORMATION_EX *pBatteryInformation) +static void UpdateXInputJoystickState_OLD(SDL_Joystick *joystick, XINPUT_STATE *pXInputState, XINPUT_BATTERY_INFORMATION_EX *pBatteryInformation) { static WORD s_XInputButtons[] = { XINPUT_GAMEPAD_DPAD_UP, XINPUT_GAMEPAD_DPAD_DOWN, XINPUT_GAMEPAD_DPAD_LEFT, XINPUT_GAMEPAD_DPAD_RIGHT, @@ -416,15 +347,14 @@ UpdateXInputJoystickState_OLD(SDL_Joystick * joystick, XINPUT_STATE_EX *pXInputS SDL_PrivateJoystickAxis(joystick, 4, (Sint16)(((int)pXInputState->Gamepad.bLeftTrigger * 65535 / 255) - 32768)); SDL_PrivateJoystickAxis(joystick, 5, (Sint16)(((int)pXInputState->Gamepad.bRightTrigger * 65535 / 255) - 32768)); - for (button = 0; button < SDL_arraysize(s_XInputButtons); ++button) { + for (button = 0; button < (Uint8)SDL_arraysize(s_XInputButtons); ++button) { SDL_PrivateJoystickButton(joystick, button, (wButtons & s_XInputButtons[button]) ? SDL_PRESSED : SDL_RELEASED); } UpdateXInputJoystickBatteryInformation(joystick, pBatteryInformation); } -static void -UpdateXInputJoystickState(SDL_Joystick * joystick, XINPUT_STATE_EX *pXInputState, XINPUT_BATTERY_INFORMATION_EX *pBatteryInformation) +static void UpdateXInputJoystickState(SDL_Joystick *joystick, XINPUT_STATE *pXInputState, XINPUT_BATTERY_INFORMATION_EX *pBatteryInformation) { static WORD s_XInputButtons[] = { XINPUT_GAMEPAD_A, XINPUT_GAMEPAD_B, XINPUT_GAMEPAD_X, XINPUT_GAMEPAD_Y, @@ -443,7 +373,7 @@ UpdateXInputJoystickState(SDL_Joystick * joystick, XINPUT_STATE_EX *pXInputState SDL_PrivateJoystickAxis(joystick, 4, ~pXInputState->Gamepad.sThumbRY); SDL_PrivateJoystickAxis(joystick, 5, ((int)pXInputState->Gamepad.bRightTrigger * 257) - 32768); - for (button = 0; button < SDL_arraysize(s_XInputButtons); ++button) { + for (button = 0; button < (Uint8)SDL_arraysize(s_XInputButtons); ++button) { SDL_PrivateJoystickButton(joystick, button, (wButtons & s_XInputButtons[button]) ? SDL_PRESSED : SDL_RELEASED); } @@ -464,8 +394,7 @@ UpdateXInputJoystickState(SDL_Joystick * joystick, XINPUT_STATE_EX *pXInputState UpdateXInputJoystickBatteryInformation(joystick, pBatteryInformation); } -int -SDL_XINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +int SDL_XINPUT_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) { XINPUT_VIBRATION XVibration; @@ -481,15 +410,20 @@ SDL_XINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, return 0; } -void -SDL_XINPUT_JoystickUpdate(SDL_Joystick * joystick) +Uint32 SDL_XINPUT_JoystickGetCapabilities(SDL_Joystick *joystick) +{ + return SDL_JOYCAP_RUMBLE; +} + +void SDL_XINPUT_JoystickUpdate(SDL_Joystick *joystick) { HRESULT result; - XINPUT_STATE_EX XInputState; + XINPUT_STATE XInputState; XINPUT_BATTERY_INFORMATION_EX XBatteryInformation; - if (!XINPUTGETSTATE) + if (!XINPUTGETSTATE) { return; + } result = XINPUTGETSTATE(joystick->hwdata->userid, &XInputState); if (result == ERROR_DEVICE_NOT_CONNECTED) { @@ -501,6 +435,10 @@ SDL_XINPUT_JoystickUpdate(SDL_Joystick * joystick) result = XINPUTGETBATTERYINFORMATION(joystick->hwdata->userid, BATTERY_DEVTYPE_GAMEPAD, &XBatteryInformation); } +#if defined(__XBOXONE__) || defined(__XBOXSERIES__) + /* XInputOnGameInput doesn't ever change dwPacketNumber, so have to just update every frame */ + UpdateXInputJoystickState(joystick, &XInputState, &XBatteryInformation); +#else /* only fire events if the data changed from last time */ if (XInputState.dwPacketNumber && XInputState.dwPacketNumber != joystick->hwdata->dwPacketNumber) { if (SDL_XInputUseOldJoystickMapping()) { @@ -510,21 +448,26 @@ SDL_XINPUT_JoystickUpdate(SDL_Joystick * joystick) } joystick->hwdata->dwPacketNumber = XInputState.dwPacketNumber; } +#endif } -void -SDL_XINPUT_JoystickClose(SDL_Joystick * joystick) +void SDL_XINPUT_JoystickClose(SDL_Joystick *joystick) { } -void -SDL_XINPUT_JoystickQuit(void) +void SDL_XINPUT_JoystickQuit(void) { if (s_bXInputEnabled) { + s_bXInputEnabled = SDL_FALSE; WIN_UnloadXInputDLL(); } } +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif + #else /* !SDL_JOYSTICK_XINPUT */ typedef struct JoyStick_DeviceData JoyStick_DeviceData; @@ -534,41 +477,39 @@ SDL_bool SDL_XINPUT_Enabled(void) return SDL_FALSE; } -int -SDL_XINPUT_JoystickInit(void) +int SDL_XINPUT_JoystickInit(void) { return 0; } -void -SDL_XINPUT_JoystickDetect(JoyStick_DeviceData **pContext) +void SDL_XINPUT_JoystickDetect(JoyStick_DeviceData **pContext) { } -int -SDL_XINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickdevice) +int SDL_XINPUT_JoystickOpen(SDL_Joystick *joystick, JoyStick_DeviceData *joystickdevice) { return SDL_Unsupported(); } -int -SDL_XINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) +int SDL_XINPUT_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) { return SDL_Unsupported(); } -void -SDL_XINPUT_JoystickUpdate(SDL_Joystick * joystick) +Uint32 SDL_XINPUT_JoystickGetCapabilities(SDL_Joystick *joystick) +{ + return 0; +} + +void SDL_XINPUT_JoystickUpdate(SDL_Joystick *joystick) { } -void -SDL_XINPUT_JoystickClose(SDL_Joystick * joystick) +void SDL_XINPUT_JoystickClose(SDL_Joystick *joystick) { } -void -SDL_XINPUT_JoystickQuit(void) +void SDL_XINPUT_JoystickQuit(void) { } diff --git a/SDL2-2.0.12/src/joystick/windows/SDL_xinputjoystick_c.h b/SDL2-2.30.5/src/joystick/windows/SDL_xinputjoystick_c.h similarity index 62% rename from SDL2-2.0.12/src/joystick/windows/SDL_xinputjoystick_c.h rename to SDL2-2.30.5/src/joystick/windows/SDL_xinputjoystick_c.h index 9afd160..8eaa849 100644 --- a/SDL2-2.0.12/src/joystick/windows/SDL_xinputjoystick_c.h +++ b/SDL2-2.30.5/src/joystick/windows/SDL_xinputjoystick_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -22,13 +22,25 @@ #include "../../core/windows/SDL_xinput.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + extern SDL_bool SDL_XINPUT_Enabled(void); extern int SDL_XINPUT_JoystickInit(void); extern void SDL_XINPUT_JoystickDetect(JoyStick_DeviceData **pContext); -extern int SDL_XINPUT_JoystickOpen(SDL_Joystick * joystick, JoyStick_DeviceData *joystickdevice); -extern int SDL_XINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble); -extern void SDL_XINPUT_JoystickUpdate(SDL_Joystick * joystick); -extern void SDL_XINPUT_JoystickClose(SDL_Joystick * joystick); +extern int SDL_XINPUT_JoystickOpen(SDL_Joystick *joystick, JoyStick_DeviceData *joystickdevice); +extern int SDL_XINPUT_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble); +extern Uint32 SDL_XINPUT_JoystickGetCapabilities(SDL_Joystick *joystick); +extern void SDL_XINPUT_JoystickUpdate(SDL_Joystick *joystick); +extern void SDL_XINPUT_JoystickClose(SDL_Joystick *joystick); extern void SDL_XINPUT_JoystickQuit(void); +extern int SDL_XINPUT_GetSteamVirtualGamepadSlot(Uint8 userid); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/libm/e_atan2.c b/SDL2-2.30.5/src/libm/e_atan2.c similarity index 100% rename from SDL2-2.0.12/src/libm/e_atan2.c rename to SDL2-2.30.5/src/libm/e_atan2.c diff --git a/SDL2-2.0.12/src/libm/e_exp.c b/SDL2-2.30.5/src/libm/e_exp.c similarity index 100% rename from SDL2-2.0.12/src/libm/e_exp.c rename to SDL2-2.30.5/src/libm/e_exp.c diff --git a/SDL2-2.0.12/src/libm/e_fmod.c b/SDL2-2.30.5/src/libm/e_fmod.c similarity index 100% rename from SDL2-2.0.12/src/libm/e_fmod.c rename to SDL2-2.30.5/src/libm/e_fmod.c diff --git a/SDL2-2.0.12/src/libm/e_log.c b/SDL2-2.30.5/src/libm/e_log.c similarity index 100% rename from SDL2-2.0.12/src/libm/e_log.c rename to SDL2-2.30.5/src/libm/e_log.c diff --git a/SDL2-2.0.12/src/libm/e_log10.c b/SDL2-2.30.5/src/libm/e_log10.c similarity index 100% rename from SDL2-2.0.12/src/libm/e_log10.c rename to SDL2-2.30.5/src/libm/e_log10.c diff --git a/SDL2-2.0.12/src/libm/e_pow.c b/SDL2-2.30.5/src/libm/e_pow.c similarity index 100% rename from SDL2-2.0.12/src/libm/e_pow.c rename to SDL2-2.30.5/src/libm/e_pow.c diff --git a/SDL2-2.0.12/src/libm/e_rem_pio2.c b/SDL2-2.30.5/src/libm/e_rem_pio2.c similarity index 100% rename from SDL2-2.0.12/src/libm/e_rem_pio2.c rename to SDL2-2.30.5/src/libm/e_rem_pio2.c diff --git a/SDL2-2.0.12/src/libm/e_sqrt.c b/SDL2-2.30.5/src/libm/e_sqrt.c similarity index 100% rename from SDL2-2.0.12/src/libm/e_sqrt.c rename to SDL2-2.30.5/src/libm/e_sqrt.c diff --git a/SDL2-2.0.12/src/libm/k_cos.c b/SDL2-2.30.5/src/libm/k_cos.c similarity index 100% rename from SDL2-2.0.12/src/libm/k_cos.c rename to SDL2-2.30.5/src/libm/k_cos.c diff --git a/SDL2-2.0.12/src/libm/k_rem_pio2.c b/SDL2-2.30.5/src/libm/k_rem_pio2.c similarity index 97% rename from SDL2-2.0.12/src/libm/k_rem_pio2.c rename to SDL2-2.30.5/src/libm/k_rem_pio2.c index 3a4a588..536f359 100644 --- a/SDL2-2.0.12/src/libm/k_rem_pio2.c +++ b/SDL2-2.30.5/src/libm/k_rem_pio2.c @@ -173,8 +173,8 @@ int32_t attribute_hidden __kernel_rem_pio2(const double *x, double *y, int e0, i j = jv-jx; m = jx+jk; for(i=0;i<=m;i++,j++) f[i] = (j<0)? zero : (double) ipio2[j]; if ((m+1) < SDL_arraysize(f)) { - SDL_memset(&f[m+1], 0, sizeof (f) - ((m+1) * sizeof (f[0]))); - } + SDL_memset(&f[m+1], 0, sizeof (f) - ((m+1) * sizeof (f[0]))); + } /* compute q[0],q[1],...q[jk] */ for (i=0;i<=jk;i++) { @@ -191,8 +191,8 @@ recompute: z = q[j-1]+fw; } if (jz < SDL_arraysize(iq)) { - SDL_memset(&iq[jz], 0, sizeof (q) - (jz * sizeof (iq[0]))); - } + SDL_memset(&iq[jz], 0, sizeof (iq) - (jz * sizeof (iq[0]))); + } /* compute n */ z = scalbn(z,q0); /* actual value of z */ @@ -276,8 +276,8 @@ recompute: fq[jz-i] = fw; } if ((jz+1) < SDL_arraysize(f)) { - SDL_memset(&fq[jz+1], 0, sizeof (fq) - ((jz+1) * sizeof (fq[0]))); - } + SDL_memset(&fq[jz+1], 0, sizeof (fq) - ((jz+1) * sizeof (fq[0]))); + } /* compress fq[] into y[] */ switch(prec) { diff --git a/SDL2-2.0.12/src/libm/k_sin.c b/SDL2-2.30.5/src/libm/k_sin.c similarity index 100% rename from SDL2-2.0.12/src/libm/k_sin.c rename to SDL2-2.30.5/src/libm/k_sin.c diff --git a/SDL2-2.0.12/src/libm/k_tan.c b/SDL2-2.30.5/src/libm/k_tan.c similarity index 100% rename from SDL2-2.0.12/src/libm/k_tan.c rename to SDL2-2.30.5/src/libm/k_tan.c diff --git a/SDL2-2.0.12/src/libm/math_libm.h b/SDL2-2.30.5/src/libm/math_libm.h similarity index 96% rename from SDL2-2.0.12/src/libm/math_libm.h rename to SDL2-2.30.5/src/libm/math_libm.h index 2f26e3a..831a184 100644 --- a/SDL2-2.0.12/src/libm/math_libm.h +++ b/SDL2-2.30.5/src/libm/math_libm.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/libm/math_private.h b/SDL2-2.30.5/src/libm/math_private.h similarity index 96% rename from SDL2-2.0.12/src/libm/math_private.h rename to SDL2-2.30.5/src/libm/math_private.h index 0253555..ee67c44 100644 --- a/SDL2-2.0.12/src/libm/math_private.h +++ b/SDL2-2.30.5/src/libm/math_private.h @@ -27,7 +27,7 @@ #define libm_hidden_def(x) #define strong_alias(x, y) -#ifndef __HAIKU__ /* already defined in a system header. */ +#if !defined(__HAIKU__) && !defined(__PSP__) && !defined(__3DS__) && !defined(__PS2__) /* already defined in a system header. */ typedef unsigned int u_int32_t; #endif @@ -66,9 +66,10 @@ typedef unsigned int u_int32_t; * Math on arm is special: * For FPA, float words are always big-endian. * For VFP, floats words follow the memory system mode. + * For Maverick, float words are always little-endian. */ -#if (SDL_BYTEORDER == SDL_BIG_ENDIAN) +#if (SDL_FLOATWORDORDER == SDL_BIG_ENDIAN) typedef union { diff --git a/SDL2-2.0.12/src/libm/s_atan.c b/SDL2-2.30.5/src/libm/s_atan.c similarity index 100% rename from SDL2-2.0.12/src/libm/s_atan.c rename to SDL2-2.30.5/src/libm/s_atan.c diff --git a/SDL2-2.0.12/src/libm/s_copysign.c b/SDL2-2.30.5/src/libm/s_copysign.c similarity index 100% rename from SDL2-2.0.12/src/libm/s_copysign.c rename to SDL2-2.30.5/src/libm/s_copysign.c diff --git a/SDL2-2.0.12/src/libm/s_cos.c b/SDL2-2.30.5/src/libm/s_cos.c similarity index 100% rename from SDL2-2.0.12/src/libm/s_cos.c rename to SDL2-2.30.5/src/libm/s_cos.c diff --git a/SDL2-2.0.12/src/libm/s_fabs.c b/SDL2-2.30.5/src/libm/s_fabs.c similarity index 100% rename from SDL2-2.0.12/src/libm/s_fabs.c rename to SDL2-2.30.5/src/libm/s_fabs.c diff --git a/SDL2-2.0.12/src/libm/s_floor.c b/SDL2-2.30.5/src/libm/s_floor.c similarity index 100% rename from SDL2-2.0.12/src/libm/s_floor.c rename to SDL2-2.30.5/src/libm/s_floor.c diff --git a/SDL2-2.0.12/src/libm/s_scalbn.c b/SDL2-2.30.5/src/libm/s_scalbn.c similarity index 100% rename from SDL2-2.0.12/src/libm/s_scalbn.c rename to SDL2-2.30.5/src/libm/s_scalbn.c diff --git a/SDL2-2.0.12/src/libm/s_sin.c b/SDL2-2.30.5/src/libm/s_sin.c similarity index 100% rename from SDL2-2.0.12/src/libm/s_sin.c rename to SDL2-2.30.5/src/libm/s_sin.c diff --git a/SDL2-2.0.12/src/libm/s_tan.c b/SDL2-2.30.5/src/libm/s_tan.c similarity index 100% rename from SDL2-2.0.12/src/libm/s_tan.c rename to SDL2-2.30.5/src/libm/s_tan.c diff --git a/SDL2-2.0.12/src/loadso/dlopen/SDL_sysloadso.c b/SDL2-2.30.5/src/loadso/dlopen/SDL_sysloadso.c similarity index 72% rename from SDL2-2.0.12/src/loadso/dlopen/SDL_sysloadso.c rename to SDL2-2.30.5/src/loadso/dlopen/SDL_sysloadso.c index d4bebe1..f08209c 100644 --- a/SDL2-2.0.12/src/loadso/dlopen/SDL_sysloadso.c +++ b/SDL2-2.30.5/src/loadso/dlopen/SDL_sysloadso.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -30,56 +30,53 @@ #include "SDL_loadso.h" -#if SDL_VIDEO_DRIVER_UIKIT +#ifdef SDL_VIDEO_DRIVER_UIKIT #include "../../video/uikit/SDL_uikitvideo.h" #endif -void * -SDL_LoadObject(const char *sofile) +void *SDL_LoadObject(const char *sofile) { void *handle; const char *loaderror; -#if SDL_VIDEO_DRIVER_UIKIT +#ifdef SDL_VIDEO_DRIVER_UIKIT if (!UIKit_IsSystemVersionAtLeast(8.0)) { SDL_SetError("SDL_LoadObject requires iOS 8+"); return NULL; } #endif - handle = dlopen(sofile, RTLD_NOW|RTLD_LOCAL); + handle = dlopen(sofile, RTLD_NOW | RTLD_LOCAL); loaderror = dlerror(); - if (handle == NULL) { + if (!handle) { SDL_SetError("Failed loading %s: %s", sofile, loaderror); } - return (handle); + return handle; } -void * -SDL_LoadFunction(void *handle, const char *name) +void *SDL_LoadFunction(void *handle, const char *name) { void *symbol = dlsym(handle, name); - if (symbol == NULL) { - /* append an underscore for platforms that need that. */ + if (!symbol) { + /* prepend an underscore for platforms that need that. */ SDL_bool isstack; - size_t len = 1 + SDL_strlen(name) + 1; - char *_name = SDL_small_alloc(char, len, &isstack); + size_t len = SDL_strlen(name) + 1; + char *_name = SDL_small_alloc(char, len + 1, &isstack); _name[0] = '_'; - SDL_strlcpy(&_name[1], name, len); + SDL_memcpy(&_name[1], name, len); symbol = dlsym(handle, _name); SDL_small_free(_name, isstack); - if (symbol == NULL) { + if (!symbol) { SDL_SetError("Failed loading %s: %s", name, - (const char *) dlerror()); + (const char *)dlerror()); } } - return (symbol); + return symbol; } -void -SDL_UnloadObject(void *handle) +void SDL_UnloadObject(void *handle) { - if (handle != NULL) { + if (handle) { dlclose(handle); } } diff --git a/SDL2-2.0.12/src/loadso/dummy/SDL_sysloadso.c b/SDL2-2.30.5/src/loadso/dummy/SDL_sysloadso.c similarity index 86% rename from SDL2-2.0.12/src/loadso/dummy/SDL_sysloadso.c rename to SDL2-2.30.5/src/loadso/dummy/SDL_sysloadso.c index 559118d..b03703b 100644 --- a/SDL2-2.0.12/src/loadso/dummy/SDL_sysloadso.c +++ b/SDL2-2.30.5/src/loadso/dummy/SDL_sysloadso.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -27,24 +27,21 @@ #include "SDL_loadso.h" -void * -SDL_LoadObject(const char *sofile) +void *SDL_LoadObject(const char *sofile) { const char *loaderror = "SDL_LoadObject() not implemented"; SDL_SetError("Failed loading %s: %s", sofile, loaderror); - return (NULL); + return NULL; } -void * -SDL_LoadFunction(void *handle, const char *name) +void *SDL_LoadFunction(void *handle, const char *name) { const char *loaderror = "SDL_LoadFunction() not implemented"; SDL_SetError("Failed loading %s: %s", name, loaderror); - return (NULL); + return NULL; } -void -SDL_UnloadObject(void *handle) +void SDL_UnloadObject(void *handle) { /* no-op. */ } diff --git a/SDL2-2.30.5/src/loadso/os2/SDL_sysloadso.c b/SDL2-2.30.5/src/loadso/os2/SDL_sysloadso.c new file mode 100644 index 0000000..a48db99 --- /dev/null +++ b/SDL2-2.30.5/src/loadso/os2/SDL_sysloadso.c @@ -0,0 +1,100 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_LOADSO_OS2 + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* System dependent library loading routines */ + +#include "SDL_loadso.h" +#include "../../core/os2/SDL_os2.h" + +#define INCL_DOSMODULEMGR +#define INCL_DOSERRORS +#include + +void *SDL_LoadObject(const char *sofile) +{ + ULONG ulRC; + HMODULE hModule; + CHAR acError[256]; + PSZ pszModName; + + if (!sofile) { + SDL_InvalidParamError("sofile"); + return NULL; + } + + pszModName = OS2_UTF8ToSys(sofile); + ulRC = DosLoadModule(acError, sizeof(acError), pszModName, &hModule); + + if (ulRC != NO_ERROR && !SDL_strrchr(pszModName, '\\') && !SDL_strrchr(pszModName, '/')) { + /* strip .dll extension and retry only if name has no path. */ + size_t len = SDL_strlen(pszModName); + if (len > 4 && SDL_strcasecmp(&pszModName[len - 4], ".dll") == 0) { + pszModName[len - 4] = '\0'; + ulRC = DosLoadModule(acError, sizeof(acError), pszModName, &hModule); + } + } + if (ulRC != NO_ERROR) { + SDL_SetError("Failed loading %s: %s (E%u)", sofile, acError, ulRC); + hModule = NULLHANDLE; + } + SDL_free(pszModName); + + return (void *)hModule; +} + +void *SDL_LoadFunction(void *handle, const char *name) +{ + ULONG ulRC; + PFN pFN; + + ulRC = DosQueryProcAddr((HMODULE)handle, 0, name, &pFN); + if (ulRC != NO_ERROR) { + /* retry with an underscore prepended, e.g. for gcc-built dlls. */ + SDL_bool isstack; + size_t len = SDL_strlen(name) + 1; + char *_name = SDL_small_alloc(char, len + 1, &isstack); + _name[0] = '_'; + SDL_memcpy(&_name[1], name, len); + ulRC = DosQueryProcAddr((HMODULE)handle, 0, _name, &pFN); + SDL_small_free(_name, isstack); + } + if (ulRC != NO_ERROR) { + SDL_SetError("Failed loading procedure %s (E%u)", name, ulRC); + return NULL; + } + + return (void *)pFN; +} + +void SDL_UnloadObject(void *handle) +{ + if (handle) { + DosFreeModule((HMODULE)handle); + } +} + +#endif /* SDL_LOADSO_OS2 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/loadso/windows/SDL_sysloadso.c b/SDL2-2.30.5/src/loadso/windows/SDL_sysloadso.c similarity index 73% rename from SDL2-2.0.12/src/loadso/windows/SDL_sysloadso.c rename to SDL2-2.30.5/src/loadso/windows/SDL_sysloadso.c index 99e8360..1fcee3d 100644 --- a/SDL2-2.0.12/src/loadso/windows/SDL_sysloadso.c +++ b/SDL2-2.30.5/src/loadso/windows/SDL_sysloadso.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -29,23 +29,29 @@ #include "SDL_loadso.h" -void * -SDL_LoadObject(const char *sofile) +void *SDL_LoadObject(const char *sofile) { - LPTSTR tstr = WIN_UTF8ToString(sofile); + void *handle; + LPTSTR tstr; + + if (!sofile) { + SDL_InvalidParamError("sofile"); + return NULL; + } + tstr = WIN_UTF8ToString(sofile); #ifdef __WINRT__ - /* WinRT only publically supports LoadPackagedLibrary() for loading .dll + /* WinRT only publicly supports LoadPackagedLibrary() for loading .dll files. LoadLibrary() is a private API, and not available for apps (that can be published to MS' Windows Store.) */ - void *handle = (void *) LoadPackagedLibrary(tstr, 0); + handle = (void *)LoadPackagedLibrary(tstr, 0); #else - void *handle = (void *) LoadLibrary(tstr); + handle = (void *)LoadLibrary(tstr); #endif SDL_free(tstr); /* Generate an error message if all loads failed */ - if (handle == NULL) { + if (!handle) { char errbuf[512]; SDL_strlcpy(errbuf, "Failed loading ", SDL_arraysize(errbuf)); SDL_strlcat(errbuf, sofile, SDL_arraysize(errbuf)); @@ -54,11 +60,10 @@ SDL_LoadObject(const char *sofile) return handle; } -void * -SDL_LoadFunction(void *handle, const char *name) +void *SDL_LoadFunction(void *handle, const char *name) { - void *symbol = (void *) GetProcAddress((HMODULE) handle, name); - if (symbol == NULL) { + void *symbol = (void *)GetProcAddress((HMODULE)handle, name); + if (!symbol) { char errbuf[512]; SDL_strlcpy(errbuf, "Failed loading ", SDL_arraysize(errbuf)); SDL_strlcat(errbuf, name, SDL_arraysize(errbuf)); @@ -67,11 +72,10 @@ SDL_LoadFunction(void *handle, const char *name) return symbol; } -void -SDL_UnloadObject(void *handle) +void SDL_UnloadObject(void *handle) { - if (handle != NULL) { - FreeLibrary((HMODULE) handle); + if (handle) { + FreeLibrary((HMODULE)handle); } } diff --git a/SDL2-2.30.5/src/locale/SDL_locale.c b/SDL2-2.30.5/src/locale/SDL_locale.c new file mode 100644 index 0000000..ea3e858 --- /dev/null +++ b/SDL2-2.30.5/src/locale/SDL_locale.c @@ -0,0 +1,103 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_syslocale.h" +#include "SDL_hints.h" + +static SDL_Locale *build_locales_from_csv_string(char *csv) +{ + size_t num_locales = 1; /* at least one */ + size_t slen; + size_t alloclen; + char *ptr; + SDL_Locale *loc; + SDL_Locale *retval; + + if (!csv || !csv[0]) { + return NULL; /* nothing to report */ + } + + for (ptr = csv; *ptr; ptr++) { + if (*ptr == ',') { + num_locales++; + } + } + + num_locales++; /* one more for terminator */ + + slen = ((size_t)(ptr - csv)) + 1; /* SDL_strlen(csv) + 1 */ + alloclen = slen + (num_locales * sizeof(SDL_Locale)); + + loc = retval = (SDL_Locale *)SDL_calloc(1, alloclen); + if (!retval) { + SDL_OutOfMemory(); + return NULL; /* oh well */ + } + ptr = (char *)(retval + num_locales); + SDL_strlcpy(ptr, csv, slen); + + while (SDL_TRUE) { /* parse out the string */ + while (*ptr == ' ') { + ptr++; /* skip whitespace. */ + } + + if (*ptr == '\0') { + break; + } + loc->language = ptr++; + while (SDL_TRUE) { + const char ch = *ptr; + if (ch == '_') { + *(ptr++) = '\0'; + loc->country = ptr; + } else if (ch == ' ') { + *(ptr++) = '\0'; /* trim ending whitespace and keep going. */ + } else if (ch == ',') { + *(ptr++) = '\0'; + loc++; + break; + } else if (ch == '\0') { + loc++; + break; + } else { + ptr++; /* just keep going, still a valid string */ + } + } + } + + return retval; +} + +SDL_Locale *SDL_GetPreferredLocales(void) +{ + char locbuf[128]; /* enough for 21 "xx_YY," language strings. */ + const char *hint = SDL_GetHint(SDL_HINT_PREFERRED_LOCALES); + if (hint) { + SDL_strlcpy(locbuf, hint, sizeof(locbuf)); + } else { + SDL_zeroa(locbuf); + SDL_SYS_GetPreferredLocales(locbuf, sizeof(locbuf)); + } + return build_locales_from_csv_string(locbuf); +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/locale/SDL_syslocale.h b/SDL2-2.30.5/src/locale/SDL_syslocale.h new file mode 100644 index 0000000..3217160 --- /dev/null +++ b/SDL2-2.30.5/src/locale/SDL_syslocale.h @@ -0,0 +1,37 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +/* This is the system specific header for the SDL locale API */ + +#include "SDL_locale.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern void SDL_SYS_GetPreferredLocales(char *buf, size_t buflen); + +#ifdef __cplusplus +} +#endif + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/locale/android/SDL_syslocale.c b/SDL2-2.30.5/src/locale/android/SDL_syslocale.c new file mode 100644 index 0000000..9a447d0 --- /dev/null +++ b/SDL2-2.30.5/src/locale/android/SDL_syslocale.c @@ -0,0 +1,31 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_syslocale.h" +#include "../../core/android/SDL_android.h" + +void SDL_SYS_GetPreferredLocales(char *buf, size_t buflen) +{ + Android_JNI_GetLocale(buf, buflen); +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/locale/dummy/SDL_syslocale.c b/SDL2-2.30.5/src/locale/dummy/SDL_syslocale.c new file mode 100644 index 0000000..89a7b1d --- /dev/null +++ b/SDL2-2.30.5/src/locale/dummy/SDL_syslocale.c @@ -0,0 +1,31 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_syslocale.h" + +void SDL_SYS_GetPreferredLocales(char *buf, size_t buflen) +{ + /* dummy implementation. Caller already zero'd out buffer. */ + SDL_Unsupported(); +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/locale/emscripten/SDL_syslocale.c b/SDL2-2.30.5/src/locale/emscripten/SDL_syslocale.c new file mode 100644 index 0000000..3b148ac --- /dev/null +++ b/SDL2-2.30.5/src/locale/emscripten/SDL_syslocale.c @@ -0,0 +1,72 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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 + +#include "../../SDL_internal.h" +#include "../SDL_syslocale.h" + +void SDL_SYS_GetPreferredLocales(char *buf, size_t buflen) +{ + /* *INDENT-OFF* */ /* clang-format off */ + EM_ASM({ + var buf = $0; + var buflen = $1; + var list = undefined; + + if (navigator.languages && navigator.languages.length) { + list = navigator.languages; + } else { + var oneOfThese = navigator.userLanguage || navigator.language || navigator.browserLanguage || navigator.systemLanguage; + if (oneOfThese !== undefined) { + list = [ oneOfThese ]; + } + } + + if (list === undefined) { + return; /* we've got nothing. */ + } + + var str = ""; /* Can't do list.join() because we need to fit in buflen. */ + for (var i = 0; i < list.length; i++) { + var item = list[i]; + if ((str.length + item.length + 1) > buflen) { + break; /* don't add, we're out of space. */ + } + if (str.length > 0) { + str += ","; + } + str += item; + } + + str = str.replace(/-/g, "_"); + if (buflen > str.length) { + buflen = str.length; /* clamp to size of string. */ + } + + for (var i = 0; i < buflen; i++) { + setValue(buf + i, str.charCodeAt(i), "i8"); /* fill in C array. */ + } + }, buf, buflen); + /* *INDENT-ON* */ /* clang-format on */ +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/locale/haiku/SDL_syslocale.cc b/SDL2-2.30.5/src/locale/haiku/SDL_syslocale.cc new file mode 100644 index 0000000..016a17c --- /dev/null +++ b/SDL2-2.30.5/src/locale/haiku/SDL_syslocale.cc @@ -0,0 +1,76 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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 +#include +#include + +#include "../../SDL_internal.h" +#include "../SDL_syslocale.h" + +void SDL_SYS_GetPreferredLocales(char *buf, size_t buflen) +{ + BLocaleRoster *roster = BLocaleRoster::Default(); + roster->Refresh(); + + BMessage msg; + if (roster->GetPreferredLanguages(&msg) != B_OK) { + SDL_SetError("BLocaleRoster couldn't get preferred languages"); + return; + } + + const char *key = "language"; + type_code typ = B_ANY_TYPE; + int32 numlangs = 0; + if ((msg.GetInfo(key, &typ, &numlangs) != B_OK) || (typ != B_STRING_TYPE)) { + SDL_SetError("BLocaleRoster message was wrong"); + return; + } + + for (int32 i = 0; i < numlangs; i++) { + const char *str = NULL; + if (msg.FindString(key, i, &str) != B_OK) { + continue; + } + + const size_t len = SDL_strlen(str); + if (buflen <= len) { + break; // can't fit it, we're done. + } + + SDL_strlcpy(buf, str, buflen); + buf += len; + buflen -= len; + + if (i < (numlangs - 1)) { + if (buflen <= 1) { + break; // out of room, stop looking. + } + buf[0] = ','; // add a comma between entries. + buf[1] = '\0'; + buf++; + buflen--; + } + } +} + +/* vi: set ts=4 sw=4 expandtab: */ + diff --git a/SDL2-2.30.5/src/locale/macosx/SDL_syslocale.m b/SDL2-2.30.5/src/locale/macosx/SDL_syslocale.m new file mode 100644 index 0000000..57f40fe --- /dev/null +++ b/SDL2-2.30.5/src/locale/macosx/SDL_syslocale.m @@ -0,0 +1,77 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_syslocale.h" + +#import + +void SDL_SYS_GetPreferredLocales(char *buf, size_t buflen) +{ + @autoreleasepool { + NSArray *languages = NSLocale.preferredLanguages; + size_t numlangs = 0; + size_t i; + + numlangs = (size_t)[languages count]; + + for (i = 0; i < numlangs; i++) { + NSString *nsstr = [languages objectAtIndex:i]; + size_t len; + char *ptr; + + if (nsstr == nil) { + break; + } + + [nsstr getCString:buf maxLength:buflen encoding:NSASCIIStringEncoding]; + len = SDL_strlen(buf); + + // convert '-' to '_'... + // These are always full lang-COUNTRY, so we search from the back, + // so things like zh-Hant-CN find the right '-' to convert. + ptr = SDL_strrchr(buf, '-'); + if (ptr != NULL) { + *ptr = '_'; + } + + if (buflen <= len) { + *buf = '\0'; // drop this one and stop, we can't fit anymore. + break; + } + + buf += len; + buflen -= len; + + if (i < (numlangs - 1)) { + if (buflen <= 1) { + break; // out of room, stop looking. + } + buf[0] = ','; // add a comma between entries. + buf[1] = '\0'; + buf++; + buflen--; + } + } + } +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/locale/n3ds/SDL_syslocale.c b/SDL2-2.30.5/src/locale/n3ds/SDL_syslocale.c new file mode 100644 index 0000000..1573f28 --- /dev/null +++ b/SDL2-2.30.5/src/locale/n3ds/SDL_syslocale.c @@ -0,0 +1,57 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_syslocale.h" +#include "../../SDL_internal.h" + +#include <3ds.h> + +/* Used when the CFGU fails to work. */ +#define BAD_LOCALE 255 + +SDL_FORCE_INLINE u8 GetLocaleIndex(void); + +void SDL_SYS_GetPreferredLocales(char *buf, size_t buflen) +{ + /* The 3DS only supports these 12 languages, only one can be active at a time */ + static const char AVAILABLE_LOCALES[][6] = { "ja_JP", "en_US", "fr_FR", "de_DE", + "it_IT", "es_ES", "zh_CN", "ko_KR", + "nl_NL", "pt_PT", "ru_RU", "zh_TW" }; + u8 current_locale = GetLocaleIndex(); + if (current_locale != BAD_LOCALE) { + SDL_strlcpy(buf, AVAILABLE_LOCALES[current_locale], buflen); + } +} + +SDL_FORCE_INLINE u8 +GetLocaleIndex(void) +{ + u8 current_locale; + Result result; + if (R_FAILED(cfguInit())) { + return BAD_LOCALE; + } + result = CFGU_GetSystemLanguage(¤t_locale); + cfguExit(); + return R_SUCCEEDED(result) ? current_locale : BAD_LOCALE; +} + +/* vi: set sts=4 ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/locale/unix/SDL_syslocale.c b/SDL2-2.30.5/src/locale/unix/SDL_syslocale.c new file mode 100644 index 0000000..f1e59cc --- /dev/null +++ b/SDL2-2.30.5/src/locale/unix/SDL_syslocale.c @@ -0,0 +1,105 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_syslocale.h" + +static void normalize_locale_str(char *dst, char *str, size_t buflen) +{ + char *ptr; + + ptr = SDL_strchr(str, '.'); /* chop off encoding if specified. */ + if (ptr) { + *ptr = '\0'; + } + + ptr = SDL_strchr(str, '@'); /* chop off extra bits if specified. */ + if (ptr) { + *ptr = '\0'; + } + + /* The "C" locale isn't useful for our needs, ignore it if you see it. */ + if ((str[0] == 'C') && (str[1] == '\0')) { + return; + } + + if (*str) { + if (*dst) { + SDL_strlcat(dst, ",", buflen); /* SDL has these split by commas */ + } + SDL_strlcat(dst, str, buflen); + } +} + +static void normalize_locales(char *dst, char *src, size_t buflen) +{ + char *ptr; + + /* entries are separated by colons */ + while ((ptr = SDL_strchr(src, ':')) != NULL) { + *ptr = '\0'; + normalize_locale_str(dst, src, buflen); + src = ptr + 1; + } + normalize_locale_str(dst, src, buflen); +} + +void SDL_SYS_GetPreferredLocales(char *buf, size_t buflen) +{ + /* !!! FIXME: should we be using setlocale()? Or some D-Bus thing? */ + SDL_bool isstack; + const char *envr; + char *tmp; + + SDL_assert(buflen > 0); + tmp = SDL_small_alloc(char, buflen, &isstack); + if (!tmp) { + SDL_OutOfMemory(); + return; + } + + *tmp = '\0'; + + /* LANG is the primary locale (maybe) */ + envr = SDL_getenv("LANG"); + if (envr) { + SDL_strlcpy(tmp, envr, buflen); + } + + /* fallback languages */ + envr = SDL_getenv("LANGUAGE"); + if (envr) { + if (*tmp) { + SDL_strlcat(tmp, ":", buflen); + } + SDL_strlcat(tmp, envr, buflen); + } + + if (*tmp == '\0') { + SDL_SetError("LANG environment variable isn't set"); + } else { + normalize_locales(buf, tmp, buflen); + } + + SDL_small_free(tmp, isstack); +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/locale/vita/SDL_syslocale.c b/SDL2-2.30.5/src/locale/vita/SDL_syslocale.c new file mode 100644 index 0000000..780b9ad --- /dev/null +++ b/SDL2-2.30.5/src/locale/vita/SDL_syslocale.c @@ -0,0 +1,70 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_syslocale.h" + +#include +#include + +void SDL_SYS_GetPreferredLocales(char *buf, size_t buflen) +{ + const char *vita_locales[] = { + "ja_JP", + "en_US", + "fr_FR", + "es_ES", + "de_DE", + "it_IT", + "nl_NL", + "pt_PT", + "ru_RU", + "ko_KR", + "zh_TW", + "zh_CN", + "fi_FI", + "sv_SE", + "da_DK", + "no_NO", + "pl_PL", + "pt_BR", + "en_GB", + "tr_TR", + }; + + Sint32 language = SCE_SYSTEM_PARAM_LANG_ENGLISH_US; + SceAppUtilInitParam initParam; + SceAppUtilBootParam bootParam; + SDL_zero(initParam); + SDL_zero(bootParam); + sceAppUtilInit(&initParam, &bootParam); + sceAppUtilSystemParamGetInt(SCE_SYSTEM_PARAM_ID_LANG, &language); + + if (language < 0 || language > SCE_SYSTEM_PARAM_LANG_TURKISH) { + language = SCE_SYSTEM_PARAM_LANG_ENGLISH_US; // default to english + } + + SDL_strlcpy(buf, vita_locales[language], buflen); + + sceAppUtilShutdown(); +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/locale/windows/SDL_syslocale.c b/SDL2-2.30.5/src/locale/windows/SDL_syslocale.c new file mode 100644 index 0000000..2449b15 --- /dev/null +++ b/SDL2-2.30.5/src/locale/windows/SDL_syslocale.c @@ -0,0 +1,112 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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 "../../core/windows/SDL_windows.h" +#include "../SDL_syslocale.h" + +typedef BOOL(WINAPI *pfnGetUserPreferredUILanguages)(DWORD, PULONG, WCHAR *, PULONG); +#ifndef MUI_LANGUAGE_NAME +#define MUI_LANGUAGE_NAME 0x8 +#endif + +static pfnGetUserPreferredUILanguages pGetUserPreferredUILanguages = NULL; +static HMODULE kernel32 = 0; + +/* this is the fallback for WinXP...one language, not a list. */ +static void SDL_SYS_GetPreferredLocales_winxp(char *buf, size_t buflen) +{ + char lang[16]; + char country[16]; + + const int langrc = GetLocaleInfoA(LOCALE_USER_DEFAULT, + LOCALE_SISO639LANGNAME, + lang, sizeof(lang)); + + const int ctryrc = GetLocaleInfoA(LOCALE_USER_DEFAULT, + LOCALE_SISO3166CTRYNAME, + country, sizeof(country)); + + /* Win95 systems will fail, because they don't have LOCALE_SISO*NAME ... */ + if (langrc == 0) { + SDL_SetError("Couldn't obtain language info"); + } else { + (void)SDL_snprintf(buf, buflen, "%s%s%s", lang, ctryrc ? "_" : "", ctryrc ? country : ""); + } +} + +/* this works on Windows Vista and later. */ +static void SDL_SYS_GetPreferredLocales_vista(char *buf, size_t buflen) +{ + ULONG numlangs = 0; + WCHAR *wbuf = NULL; + ULONG wbuflen = 0; + SDL_bool isstack; + + SDL_assert(pGetUserPreferredUILanguages != NULL); + pGetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &numlangs, NULL, &wbuflen); + + wbuf = SDL_small_alloc(WCHAR, wbuflen, &isstack); + if (!wbuf) { + SDL_OutOfMemory(); + return; + } + + if (!pGetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &numlangs, wbuf, &wbuflen)) { + SDL_SYS_GetPreferredLocales_winxp(buf, buflen); /* oh well, try the fallback. */ + } else { + const ULONG endidx = (ULONG)SDL_min(buflen, wbuflen - 1); + ULONG str_start = 0; + ULONG i; + for (i = 0; i < endidx; i++) { + const char ch = (char)wbuf[i]; /* these should all be low-ASCII, safe to cast */ + if (ch == '\0') { + buf[i] = ','; /* change null separators to commas */ + str_start = i; + } else if (ch == '-') { + buf[i] = '_'; /* change '-' to '_' */ + } else { + buf[i] = ch; /* copy through as-is. */ + } + } + buf[str_start] = '\0'; /* terminate string, chop off final ',' */ + } + + SDL_small_free(wbuf, isstack); +} + +void SDL_SYS_GetPreferredLocales(char *buf, size_t buflen) +{ + if (!kernel32) { + kernel32 = GetModuleHandle(TEXT("kernel32.dll")); + if (kernel32) { + pGetUserPreferredUILanguages = (pfnGetUserPreferredUILanguages)GetProcAddress(kernel32, "GetUserPreferredUILanguages"); + } + } + + if (!pGetUserPreferredUILanguages) { + SDL_SYS_GetPreferredLocales_winxp(buf, buflen); /* this is always available */ + } else { + SDL_SYS_GetPreferredLocales_vista(buf, buflen); /* available on Vista and later. */ + } +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/locale/winrt/SDL_syslocale.c b/SDL2-2.30.5/src/locale/winrt/SDL_syslocale.c new file mode 100644 index 0000000..8fdeec7 --- /dev/null +++ b/SDL2-2.30.5/src/locale/winrt/SDL_syslocale.c @@ -0,0 +1,55 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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 + +#include "../../SDL_internal.h" +#include "../SDL_syslocale.h" + +/*using namespace Windows::Graphics::Display;*/ +#include + +void SDL_SYS_GetPreferredLocales(char *buf, size_t buflen) +{ + WCHAR wbuffer[128] = L""; + int ret = 0; + + /* !!! FIXME: do we not have GetUserPreferredUILanguages on WinPhone or UWP? */ +#if SDL_WINAPI_FAMILY_PHONE + ret = GetLocaleInfoEx(LOCALE_NAME_SYSTEM_DEFAULT, LOCALE_SNAME, wbuffer, SDL_arraysize(wbuffer)); +#else + ret = GetSystemDefaultLocaleName(wbuffer, SDL_arraysize(wbuffer)); +#endif + + if (ret > 0) { + /* Need to convert LPWSTR to LPSTR, that is wide char to char. */ + int i; + + if (((size_t)ret) >= (buflen - 1)) { + ret = (int)(buflen - 1); + } + for (i = 0; i < ret; i++) { + buf[i] = (char)wbuffer[i]; /* assume this was ASCII anyhow. */ + } + } +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/main/android/SDL_android_main.c b/SDL2-2.30.5/src/main/android/SDL_android_main.c similarity index 100% rename from SDL2-2.0.12/src/main/android/SDL_android_main.c rename to SDL2-2.30.5/src/main/android/SDL_android_main.c diff --git a/SDL2-2.0.12/src/main/dummy/SDL_dummy_main.c b/SDL2-2.30.5/src/main/dummy/SDL_dummy_main.c similarity index 70% rename from SDL2-2.0.12/src/main/dummy/SDL_dummy_main.c rename to SDL2-2.30.5/src/main/dummy/SDL_dummy_main.c index 0174136..097b210 100644 --- a/SDL2-2.0.12/src/main/dummy/SDL_dummy_main.c +++ b/SDL2-2.30.5/src/main/dummy/SDL_dummy_main.c @@ -8,18 +8,13 @@ #ifdef main #undef main -int -main(int argc, char *argv[]) +int main(int argc, char *argv[]) { - return (SDL_main(argc, argv)); + return SDL_main(argc, argv); } #else /* Nothing to do on this platform */ -int -SDL_main_stub_symbol(void); - -int -SDL_main_stub_symbol(void) +int SDL_main_stub_symbol(void) { return 0; } diff --git a/SDL2-2.30.5/src/main/gdk/SDL_gdk_main.c b/SDL2-2.30.5/src/main/gdk/SDL_gdk_main.c new file mode 100644 index 0000000..7bfd9cc --- /dev/null +++ b/SDL2-2.30.5/src/main/gdk/SDL_gdk_main.c @@ -0,0 +1,41 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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 this so we define UNICODE properly */ +#include "../../core/windows/SDL_windows.h" + +/* Include the SDL main definition header */ +#include "SDL.h" +#include "SDL_main.h" + +#ifdef main +#undef main +#endif /* main */ + +/* This is where execution begins */ +int WINAPI +WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) +{ + return SDL_GDKRunApp(SDL_main, NULL); +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/main/haiku/SDL_BApp.h b/SDL2-2.30.5/src/main/haiku/SDL_BApp.h similarity index 67% rename from SDL2-2.0.12/src/main/haiku/SDL_BApp.h rename to SDL2-2.30.5/src/main/haiku/SDL_BApp.h index 93ae0c6..284445d 100644 --- a/SDL2-2.0.12/src/main/haiku/SDL_BApp.h +++ b/SDL2-2.30.5/src/main/haiku/SDL_BApp.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -21,14 +21,15 @@ #ifndef SDL_BAPP_H #define SDL_BAPP_H +#include #include -#if SDL_VIDEO_OPENGL +#include +#ifdef SDL_VIDEO_OPENGL #include #endif #include "../../video/haiku/SDL_bkeyboard.h" - #ifdef __cplusplus extern "C" { #endif @@ -47,28 +48,27 @@ extern "C" { #include - - - /* Forward declarations */ +class SDL_BLooper; class SDL_BWin; /* Message constants */ -enum ToSDL { +enum ToSDL +{ /* Intercepted by BWindow on its way to BView */ BAPP_MOUSE_MOVED, BAPP_MOUSE_BUTTON, BAPP_MOUSE_WHEEL, BAPP_KEY, - BAPP_REPAINT, /* from _UPDATE_ */ + BAPP_REPAINT, /* from _UPDATE_ */ /* From BWindow */ - BAPP_MAXIMIZE, /* from B_ZOOM */ + BAPP_MAXIMIZE, /* from B_ZOOM */ BAPP_MINIMIZE, - BAPP_RESTORE, /* TODO: IMPLEMENT! */ + BAPP_RESTORE, /* TODO: IMPLEMENT! */ BAPP_SHOW, BAPP_HIDE, - BAPP_MOUSE_FOCUS, /* caused by MOUSE_MOVE */ - BAPP_KEYBOARD_FOCUS, /* from WINDOW_ACTIVATED */ + BAPP_MOUSE_FOCUS, /* caused by MOUSE_MOVE */ + BAPP_KEYBOARD_FOCUS, /* from WINDOW_ACTIVATED */ BAPP_WINDOW_CLOSE_REQUESTED, BAPP_WINDOW_MOVED, BAPP_WINDOW_RESIZED, @@ -76,27 +76,29 @@ enum ToSDL { }; +extern "C" SDL_BLooper *SDL_Looper; -/* Create a descendant of BApplication */ -class SDL_BApp : public BApplication { -public: - SDL_BApp(const char* signature) : - BApplication(signature) { -#if SDL_VIDEO_OPENGL + +/* Create a descendant of BLooper */ +class SDL_BLooper : public BLooper +{ + public: + SDL_BLooper(const char* name) : BLooper(name) + { +#ifdef SDL_VIDEO_OPENGL _current_context = NULL; #endif } - - virtual ~SDL_BApp() { + virtual ~SDL_BLooper() + { } - - - /* Event-handling functions */ - virtual void MessageReceived(BMessage* message) { + /* Event-handling functions */ + virtual void MessageReceived(BMessage *message) + { /* Sort out SDL-related messages */ - switch ( message->what ) { + switch (message->what) { case BAPP_MOUSE_MOVED: _HandleMouseMove(message); break; @@ -153,28 +155,33 @@ public: _HandleWindowResized(message); break; + case B_LOCALE_CHANGED: + SDL_SendLocaleChangedEvent(); + break; + case BAPP_SCREEN_CHANGED: /* TODO: Handle screen resize or workspace change */ break; default: - BApplication::MessageReceived(message); - break; + BLooper::MessageReceived(message); + break; } } /* Window creation/destruction methods */ - int32 GetID(SDL_Window *win) { + int32 GetID(SDL_Window *win) + { int32 i; - for(i = 0; i < _GetNumWindowSlots(); ++i) { - if( GetSDLWindow(i) == NULL ) { + for (i = 0; i < _GetNumWindowSlots(); ++i) { + if (GetSDLWindow(i) == NULL) { _SetSDLWindow(win, i); return i; } } /* Expand the vector if all slots are full */ - if( i == _GetNumWindowSlots() ) { + if (i == _GetNumWindowSlots()) { _PushBackWindow(win); return i; } @@ -187,14 +194,20 @@ public: there another way to do this? */ void ClearID(SDL_BWin *bwin); /* Defined in SDL_BeApp.cc */ - - SDL_Window *GetSDLWindow(int32 winID) { + SDL_Window *GetSDLWindow(int32 winID) + { return _window_map[winID]; } -#if SDL_VIDEO_OPENGL - void SetCurrentContext(BGLView *newContext) { - if(_current_context) +#ifdef SDL_VIDEO_OPENGL + BGLView *GetCurrentContext() + { + return _current_context; + } + + void SetCurrentContext(BGLView *newContext) + { + if (_current_context) _current_context->UnlockGL(); _current_context = newContext; if (_current_context) @@ -202,25 +215,26 @@ public: } #endif -private: + private: /* Event management */ - void _HandleBasicWindowEvent(BMessage *msg, int32 sdlEventType) { + void _HandleBasicWindowEvent(BMessage *msg, int32 sdlEventType) + { SDL_Window *win; int32 winID; - if( - !_GetWinID(msg, &winID) - ) { + if ( + !_GetWinID(msg, &winID)) { return; } win = GetSDLWindow(winID); SDL_SendWindowEvent(win, sdlEventType, 0, 0); } - void _HandleMouseMove(BMessage *msg) { + void _HandleMouseMove(BMessage *msg) + { SDL_Window *win; int32 winID; int32 x = 0, y = 0; - if( + if ( !_GetWinID(msg, &winID) || msg->FindInt32("x", &x) != B_OK || /* x movement */ msg->FindInt32("y", &y) != B_OK /* y movement */ @@ -229,77 +243,74 @@ private: } win = GetSDLWindow(winID); - // Simple relative mode support for mouse. - if (SDL_GetMouse()->relative_mode) { - int winWidth, winHeight, winPosX, winPosY; - SDL_GetWindowSize(win, &winWidth, &winHeight); - SDL_GetWindowPosition(win, &winPosX, &winPosY); - int dx = x - (winWidth / 2); - int dy = y - (winHeight / 2); - SDL_SendMouseMotion(win, 0, SDL_GetMouse()->relative_mode, dx, dy); - set_mouse_position((winPosX + winWidth / 2), (winPosY + winHeight / 2)); - if (!be_app->IsCursorHidden()) - be_app->HideCursor(); - } else { - SDL_SendMouseMotion(win, 0, 0, x, y); - if (SDL_ShowCursor(-1) && be_app->IsCursorHidden()) - be_app->ShowCursor(); - } - - /* Tell the application that the mouse passed over, redraw needed */ - HAIKU_UpdateWindowFramebuffer(NULL,win,NULL,-1); + // Simple relative mode support for mouse. + if (SDL_GetMouse()->relative_mode) { + int winWidth, winHeight, winPosX, winPosY; + SDL_GetWindowSize(win, &winWidth, &winHeight); + SDL_GetWindowPosition(win, &winPosX, &winPosY); + int dx = x - (winWidth / 2); + int dy = y - (winHeight / 2); + SDL_SendMouseMotion(win, 0, SDL_GetMouse()->relative_mode, dx, dy); + set_mouse_position((winPosX + winWidth / 2), (winPosY + winHeight / 2)); + if (!be_app->IsCursorHidden()) + be_app->HideCursor(); + } else { + SDL_SendMouseMotion(win, 0, 0, x, y); + if (SDL_ShowCursor(-1) && be_app->IsCursorHidden()) + be_app->ShowCursor(); + } } - void _HandleMouseButton(BMessage *msg) { + void _HandleMouseButton(BMessage *msg) + { SDL_Window *win; int32 winID; - int32 button, state; /* left/middle/right, pressed/released */ - if( + int32 button, state; /* left/middle/right, pressed/released */ + if ( !_GetWinID(msg, &winID) || msg->FindInt32("button-id", &button) != B_OK || - msg->FindInt32("button-state", &state) != B_OK - ) { + msg->FindInt32("button-state", &state) != B_OK) { return; } win = GetSDLWindow(winID); SDL_SendMouseButton(win, 0, state, button); } - void _HandleMouseWheel(BMessage *msg) { + void _HandleMouseWheel(BMessage *msg) + { SDL_Window *win; int32 winID; int32 xTicks, yTicks; - if( + if ( !_GetWinID(msg, &winID) || msg->FindInt32("xticks", &xTicks) != B_OK || - msg->FindInt32("yticks", &yTicks) != B_OK - ) { + msg->FindInt32("yticks", &yTicks) != B_OK) { return; } win = GetSDLWindow(winID); SDL_SendMouseWheel(win, 0, xTicks, -yTicks, SDL_MOUSEWHEEL_NORMAL); } - void _HandleKey(BMessage *msg) { - int32 scancode, state; /* scancode, pressed/released */ - if( + void _HandleKey(BMessage *msg) + { + int32 scancode, state; /* scancode, pressed/released */ + if ( msg->FindInt32("key-state", &state) != B_OK || - msg->FindInt32("key-scancode", &scancode) != B_OK - ) { + msg->FindInt32("key-scancode", &scancode) != B_OK) { return; } /* Make sure this isn't a repeated event (key pressed and held) */ - if(state == SDL_PRESSED && HAIKU_GetKeyState(scancode) == SDL_PRESSED) { + if (state == SDL_PRESSED && HAIKU_GetKeyState(scancode) == SDL_PRESSED) { return; } HAIKU_SetKeyState(scancode, state); SDL_SendKeyboardKey(state, HAIKU_GetScancodeFromBeKey(scancode)); - + if (state == SDL_PRESSED && SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) { const int8 *keyUtf8; ssize_t count; - if (msg->FindData("key-utf8", B_INT8_TYPE, (const void**)&keyUtf8, &count) == B_OK) { + if (msg->FindData("key-utf8", B_INT8_TYPE, (const void **)&keyUtf8, &count) == B_OK) { char text[SDL_TEXTINPUTEVENT_TEXT_SIZE]; SDL_zeroa(text); SDL_memcpy(text, keyUtf8, count); @@ -308,107 +319,108 @@ private: } } - void _HandleMouseFocus(BMessage *msg) { + void _HandleMouseFocus(BMessage *msg) + { SDL_Window *win; int32 winID; bool bSetFocus; /* If false, lose focus */ - if( + if ( !_GetWinID(msg, &winID) || - msg->FindBool("focusGained", &bSetFocus) != B_OK - ) { + msg->FindBool("focusGained", &bSetFocus) != B_OK) { return; } win = GetSDLWindow(winID); - if(bSetFocus) { + if (bSetFocus) { SDL_SetMouseFocus(win); - } else if(SDL_GetMouseFocus() == win) { + } else if (SDL_GetMouseFocus() == win) { /* Only lose all focus if this window was the current focus */ SDL_SetMouseFocus(NULL); } } - void _HandleKeyboardFocus(BMessage *msg) { + void _HandleKeyboardFocus(BMessage *msg) + { SDL_Window *win; int32 winID; bool bSetFocus; /* If false, lose focus */ - if( + if ( !_GetWinID(msg, &winID) || - msg->FindBool("focusGained", &bSetFocus) != B_OK - ) { + msg->FindBool("focusGained", &bSetFocus) != B_OK) { return; } win = GetSDLWindow(winID); - if(bSetFocus) { + if (bSetFocus) { SDL_SetKeyboardFocus(win); - } else if(SDL_GetKeyboardFocus() == win) { + } else if (SDL_GetKeyboardFocus() == win) { /* Only lose all focus if this window was the current focus */ SDL_SetKeyboardFocus(NULL); } } - void _HandleWindowMoved(BMessage *msg) { + void _HandleWindowMoved(BMessage *msg) + { SDL_Window *win; int32 winID; int32 xPos, yPos; /* Get the window id and new x/y position of the window */ - if( + if ( !_GetWinID(msg, &winID) || msg->FindInt32("window-x", &xPos) != B_OK || - msg->FindInt32("window-y", &yPos) != B_OK - ) { + msg->FindInt32("window-y", &yPos) != B_OK) { return; } win = GetSDLWindow(winID); SDL_SendWindowEvent(win, SDL_WINDOWEVENT_MOVED, xPos, yPos); } - void _HandleWindowResized(BMessage *msg) { + void _HandleWindowResized(BMessage *msg) + { SDL_Window *win; int32 winID; int32 w, h; /* Get the window id ]and new x/y position of the window */ - if( + if ( !_GetWinID(msg, &winID) || msg->FindInt32("window-w", &w) != B_OK || - msg->FindInt32("window-h", &h) != B_OK - ) { + msg->FindInt32("window-h", &h) != B_OK) { return; } win = GetSDLWindow(winID); SDL_SendWindowEvent(win, SDL_WINDOWEVENT_RESIZED, w, h); } - bool _GetWinID(BMessage *msg, int32 *winID) { + bool _GetWinID(BMessage *msg, int32 *winID) + { return msg->FindInt32("window-id", winID) == B_OK; } - - /* Vector functions: Wraps vector stuff in case we need to change implementation */ - void _SetSDLWindow(SDL_Window *win, int32 winID) { + void _SetSDLWindow(SDL_Window *win, int32 winID) + { _window_map[winID] = win; } - int32 _GetNumWindowSlots() { + int32 _GetNumWindowSlots() + { return _window_map.size(); } - - void _PopBackWindow() { + void _PopBackWindow() + { _window_map.pop_back(); } - void _PushBackWindow(SDL_Window *win) { + void _PushBackWindow(SDL_Window *win) + { _window_map.push_back(win); } - /* Members */ - std::vector _window_map; /* Keeps track of SDL_Windows by index-id */ + std::vector _window_map; /* Keeps track of SDL_Windows by index-id */ -#if SDL_VIDEO_OPENGL - BGLView *_current_context; +#ifdef SDL_VIDEO_OPENGL + BGLView *_current_context; #endif }; diff --git a/SDL2-2.0.12/src/main/haiku/SDL_BeApp.cc b/SDL2-2.30.5/src/main/haiku/SDL_BeApp.cc similarity index 63% rename from SDL2-2.0.12/src/main/haiku/SDL_BeApp.cc rename to SDL2-2.30.5/src/main/haiku/SDL_BeApp.cc index 403be82..a736a9f 100644 --- a/SDL2-2.0.12/src/main/haiku/SDL_BeApp.cc +++ b/SDL2-2.30.5/src/main/haiku/SDL_BeApp.cc @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -31,7 +31,7 @@ #include #include -#include "SDL_BApp.h" /* SDL_BApp class definition */ +#include "SDL_BApp.h" /* SDL_BLooper class definition */ #include "SDL_BeApp.h" #include "SDL_timer.h" #include "SDL_error.h" @@ -44,15 +44,40 @@ extern "C" { #include "../../thread/SDL_systhread.h" -/* Flag to tell whether or not the Be application is active or not */ +/* Flag to tell whether or not the Be application and looper are active or not */ static int SDL_BeAppActive = 0; static SDL_Thread *SDL_AppThread = NULL; +SDL_BLooper *SDL_Looper = NULL; + /* Default application signature */ -const char *signature = "application/x-SDL-executable"; +const char *SDL_signature = "application/x-SDL-executable"; -static int -StartBeApp(void *unused) + +/* Create a descendant of BApplication */ +class SDL_BApp : public BApplication { +public: + SDL_BApp(const char* signature) : + BApplication(signature) { + } + + + virtual ~SDL_BApp() { + } + + + virtual void RefsReceived(BMessage* message) { + entry_ref entryRef; + for (int32 i = 0; message->FindRef("refs", i, &entryRef) == B_OK; i++) { + BPath referencePath = BPath(&entryRef); + SDL_SendDropFile(NULL, referencePath.Path()); + } + return; + } +}; + + +static int StartBeApp(void *unused) { BApplication *App; @@ -65,48 +90,61 @@ StartBeApp(void *unused) BAppFileInfo app_info(&f); if (app_info.InitCheck() == B_OK) { char sig[B_MIME_TYPE_LENGTH]; - if (app_info.GetSignature(sig) == B_OK) - signature = strndup(sig, B_MIME_TYPE_LENGTH); + if (app_info.GetSignature(sig) == B_OK) { + SDL_signature = strndup(sig, B_MIME_TYPE_LENGTH); + } } } } - App = new SDL_BApp(signature); + App = new SDL_BApp(SDL_signature); App->Run(); delete App; - return (0); + return 0; } -/* Initialize the Be Application, if it's not already started */ -int -SDL_InitBeApp(void) -{ - /* Create the BApplication that handles appserver interaction */ - if (SDL_BeAppActive <= 0) { - SDL_AppThread = SDL_CreateThreadInternal(StartBeApp, "SDLApplication", 0, NULL); - if (SDL_AppThread == NULL) { - return SDL_SetError("Couldn't create BApplication thread"); - } - /* Change working directory to that of executable */ - app_info info; - if (B_OK == be_app->GetAppInfo(&info)) { - entry_ref ref = info.ref; - BEntry entry; - if (B_OK == entry.SetTo(&ref)) { - BPath path; - if (B_OK == path.SetTo(&entry)) { - if (B_OK == path.GetParent(&path)) { - chdir(path.Path()); - } - } - } +static int StartBeLooper() +{ + if (!be_app) { + SDL_AppThread = SDL_CreateThreadInternal(StartBeApp, "SDLApplication", 0, NULL); + if (!SDL_AppThread) { + return SDL_SetError("Couldn't create BApplication thread"); } do { SDL_Delay(10); - } while ((be_app == NULL) || be_app->IsLaunching()); + } while ((!be_app) || be_app->IsLaunching()); + } + + /* Change working directory to that of executable */ + app_info info; + if (B_OK == be_app->GetAppInfo(&info)) { + entry_ref ref = info.ref; + BEntry entry; + if (B_OK == entry.SetTo(&ref)) { + BPath path; + if (B_OK == path.SetTo(&entry)) { + if (B_OK == path.GetParent(&path)) { + chdir(path.Path()); + } + } + } + } + + SDL_Looper = new SDL_BLooper("SDLLooper"); + SDL_Looper->Run(); + return (0); +} + + +/* Initialize the Be Application, if it's not already started */ +int SDL_InitBeApp(void) +{ + /* Create the BApplication that handles appserver interaction */ + if (SDL_BeAppActive <= 0) { + StartBeLooper(); /* Mark the application active */ SDL_BeAppActive = 0; @@ -116,19 +154,21 @@ SDL_InitBeApp(void) ++SDL_BeAppActive; /* The app is running, and we're ready to go */ - return (0); + return 0; } /* Quit the Be Application, if there's nothing left to do */ -void -SDL_QuitBeApp(void) +void SDL_QuitBeApp(void) { /* Decrement the application reference count */ --SDL_BeAppActive; /* If the reference count reached zero, clean up the app */ if (SDL_BeAppActive == 0) { - if (SDL_AppThread != NULL) { + SDL_Looper->Lock(); + SDL_Looper->Quit(); + SDL_Looper = NULL; + if (SDL_AppThread) { if (be_app != NULL) { /* Not tested */ be_app->PostMessage(B_QUIT_REQUESTED); } @@ -144,10 +184,10 @@ SDL_QuitBeApp(void) #endif /* SDL_BApp functions */ -void SDL_BApp::ClearID(SDL_BWin *bwin) { +void SDL_BLooper::ClearID(SDL_BWin *bwin) { _SetSDLWindow(NULL, bwin->GetID()); int32 i = _GetNumWindowSlots() - 1; - while(i >= 0 && GetSDLWindow(i) == NULL) { + while (i >= 0 && GetSDLWindow(i) == NULL) { _PopBackWindow(); --i; } diff --git a/SDL2-2.0.12/src/main/haiku/SDL_BeApp.h b/SDL2-2.30.5/src/main/haiku/SDL_BeApp.h similarity index 93% rename from SDL2-2.0.12/src/main/haiku/SDL_BeApp.h rename to SDL2-2.30.5/src/main/haiku/SDL_BeApp.h index db92b6d..8b8cc0f 100644 --- a/SDL2-2.0.12/src/main/haiku/SDL_BeApp.h +++ b/SDL2-2.30.5/src/main/haiku/SDL_BeApp.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -32,7 +32,7 @@ extern int SDL_InitBeApp(void); extern void SDL_QuitBeApp(void); /* Be Application Signature*/ -extern const char *signature; +extern const char *SDL_signature; /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/main/n3ds/SDL_n3ds_main.c b/SDL2-2.30.5/src/main/n3ds/SDL_n3ds_main.c new file mode 100644 index 0000000..844416f --- /dev/null +++ b/SDL2-2.30.5/src/main/n3ds/SDL_n3ds_main.c @@ -0,0 +1,61 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef __3DS__ + +#include "SDL_main.h" +#include <3ds.h> + +#ifdef main +#undef main +#endif + +SDL_FORCE_INLINE void N3DS_Init(void); +SDL_FORCE_INLINE void N3DS_Quit(void); + +int main(int argc, char *argv[]) +{ + int result; + N3DS_Init(); + SDL_SetMainReady(); + result = SDL_main(argc, argv); + N3DS_Quit(); + return result; +} + +SDL_FORCE_INLINE void +N3DS_Init(void) +{ + osSetSpeedupEnable(true); + romfsInit(); +} + +SDL_FORCE_INLINE void +N3DS_Quit(void) +{ + romfsExit(); +} + +#endif /* __3DS__ */ + +/* vi: set sts=4 ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/main/nacl/SDL_nacl_main.c b/SDL2-2.30.5/src/main/nacl/SDL_nacl_main.c similarity index 91% rename from SDL2-2.0.12/src/main/nacl/SDL_nacl_main.c rename to SDL2-2.30.5/src/main/nacl/SDL_nacl_main.c index 4c223fa..174b85b 100644 --- a/SDL2-2.0.12/src/main/nacl/SDL_nacl_main.c +++ b/SDL2-2.30.5/src/main/nacl/SDL_nacl_main.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_NACL +#ifdef SDL_VIDEO_DRIVER_NACL /* Include the SDL main definition header */ #include "SDL_main.h" @@ -33,20 +33,19 @@ extern void NACL_SetScreenResolution(int width, int height, Uint32 format); -int -nacl_main(int argc, char *argv[]) +int nacl_main(int argc, char *argv[]) { int status; PSEvent* ps_event; - PP_Resource event; + PP_Resource event; struct PP_Rect rect; int ready = 0; const PPB_View *ppb_view = PSInterfaceView(); - + /* This is started in a worker thread by ppapi_simple! */ - + /* Wait for the first PSE_INSTANCE_DIDCHANGEVIEW event before starting the app */ - + PSEventSetFilter(PSE_INSTANCE_DIDCHANGEVIEW); while (!ready) { /* Process all waiting events without blocking */ @@ -65,13 +64,13 @@ nacl_main(int argc, char *argv[]) PSEventRelease(ps_event); } } - - /* Do a default httpfs mount on /, - * apps can override this by unmounting / + + /* Do a default httpfs mount on /, + * apps can override this by unmounting / * and remounting with the desired configuration */ nacl_io_init_ppapi(PSGetInstanceId(), PSGetInterface); - + umount("/"); mount( "", /* source */ @@ -79,7 +78,7 @@ nacl_main(int argc, char *argv[]) "httpfs", /* filesystemtype */ 0, /* mountflags */ ""); /* data specific to the html5fs type */ - + /* Everything is ready, start the user main function */ SDL_SetMainReady(); status = SDL_main(argc, argv); diff --git a/SDL2-2.30.5/src/main/ngage/SDL_ngage_main.cpp b/SDL2-2.30.5/src/main/ngage/SDL_ngage_main.cpp new file mode 100644 index 0000000..7439a2f --- /dev/null +++ b/SDL2-2.30.5/src/main/ngage/SDL_ngage_main.cpp @@ -0,0 +1,79 @@ +/* + SDL_ngage_main.c, originally for SDL 1.2 by Hannu Viitala +*/ +#include "../../SDL_internal.h" + +/* Include the SDL main definition header */ +#include "SDL_main.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "SDL_error.h" + +extern "C" int main(int argc, char *argv[]); + +TInt E32Main() +{ + /* Get the clean-up stack */ + CTrapCleanup *cleanup = CTrapCleanup::New(); + + /* Arrange for multi-threaded operation */ + SpawnPosixServerThread(); + + /* Get args and environment */ + int argc = 0; + char **argv = 0; + char **envp = 0; + + __crt0(argc, argv, envp); + + /* Start the application! */ + + /* Create stdlib */ + _REENT; + + /* Set process and thread priority and name */ + + RThread currentThread; + RProcess thisProcess; + TParse exeName; + exeName.Set(thisProcess.FileName(), NULL, NULL); + currentThread.Rename(exeName.Name()); + currentThread.SetProcessPriority(EPriorityLow); + currentThread.SetPriority(EPriorityMuchLess); + + /* Increase heap size */ + RHeap *newHeap = NULL; + RHeap *oldHeap = NULL; + TInt heapSize = 7500000; + int ret; + + newHeap = User::ChunkHeap(NULL, heapSize, heapSize, KMinHeapGrowBy); + + if (!newHeap) { + ret = 3; + goto cleanup; + } else { + oldHeap = User::SwitchHeap(newHeap); + /* Call stdlib main */ + SDL_SetMainReady(); + ret = SDL_main(argc, argv); + } + +cleanup: + _cleanup(); + + CloseSTDLIB(); + delete cleanup; + return ret; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/main/ps2/SDL_ps2_main.c b/SDL2-2.30.5/src/main/ps2/SDL_ps2_main.c new file mode 100644 index 0000000..b237eea --- /dev/null +++ b/SDL2-2.30.5/src/main/ps2/SDL_ps2_main.c @@ -0,0 +1,74 @@ +/* + SDL_ps2_main.c, fjtrujy@gmail.com +*/ + +#include "SDL_config.h" + +#ifdef __PS2__ + +#include "SDL_main.h" +#include "SDL_error.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + +#ifdef main +#undef main +#endif + +__attribute__((weak)) void reset_IOP() +{ + SifInitRpc(0); + while (!SifIopReset(NULL, 0)) { + } + while (!SifIopSync()) { + } +} + +static void prepare_IOP() +{ + reset_IOP(); + SifInitRpc(0); + sbv_patch_enable_lmb(); + sbv_patch_disable_prefix_check(); + sbv_patch_fileio(); +} + +static void init_drivers() +{ + init_ps2_filesystem_driver(); +} + +static void deinit_drivers() +{ + deinit_ps2_filesystem_driver(); +} + +int main(int argc, char *argv[]) +{ + int res; + char cwd[FILENAME_MAX]; + + prepare_IOP(); + init_drivers(); + + getcwd(cwd, sizeof(cwd)); + waitUntilDeviceIsReady(cwd); + + res = SDL_main(argc, argv); + + deinit_drivers(); + + return res; +} + +#endif /* _PS2 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/main/psp/SDL_psp_main.c b/SDL2-2.30.5/src/main/psp/SDL_psp_main.c similarity index 75% rename from SDL2-2.0.12/src/main/psp/SDL_psp_main.c rename to SDL2-2.30.5/src/main/psp/SDL_psp_main.c index 2ca8e44..3d083cc 100644 --- a/SDL2-2.0.12/src/main/psp/SDL_psp_main.c +++ b/SDL2-2.30.5/src/main/psp/SDL_psp_main.c @@ -7,11 +7,11 @@ #include "SDL_main.h" #include -#include -#include #include -#include -#include + +#ifdef main +#undef main +#endif /* If application's main() is redefined as SDL_main, and libSDLmain is linked, then this file will create the standard exit callback, @@ -23,11 +23,12 @@ PSP_MAIN_THREAD_STACK_SIZE, etc. */ -PSP_MODULE_INFO("SDL App", 0, 1, 1); +PSP_MODULE_INFO("SDL App", 0, 1, 0); +PSP_MAIN_THREAD_ATTR(THREAD_ATTR_VFPU | THREAD_ATTR_USER); int sdl_psp_exit_callback(int arg1, int arg2, void *common) { - exit(0); + sceKernelExitGame(); return 0; } @@ -35,7 +36,7 @@ int sdl_psp_callback_thread(SceSize args, void *argp) { int cbid; cbid = sceKernelCreateCallback("Exit Callback", - sdl_psp_exit_callback, NULL); + sdl_psp_exit_callback, NULL); sceKernelRegisterExitCallback(cbid); sceKernelSleepThreadCB(); return 0; @@ -43,22 +44,19 @@ int sdl_psp_callback_thread(SceSize args, void *argp) int sdl_psp_setup_callbacks(void) { - int thid = 0; + int thid; thid = sceKernelCreateThread("update_thread", - sdl_psp_callback_thread, 0x11, 0xFA0, 0, 0); - if(thid >= 0) + sdl_psp_callback_thread, 0x11, 0xFA0, 0, 0); + if (thid >= 0) { sceKernelStartThread(thid, 0, 0); + } return thid; } int main(int argc, char *argv[]) { - pspDebugScreenInit(); sdl_psp_setup_callbacks(); - /* Register sceKernelExitGame() to be called when we exit */ - atexit(sceKernelExitGame); - SDL_SetMainReady(); (void)SDL_main(argc, argv); diff --git a/SDL2-2.30.5/src/main/uikit/SDL_uikit_main.c b/SDL2-2.30.5/src/main/uikit/SDL_uikit_main.c new file mode 100644 index 0000000..6ce3492 --- /dev/null +++ b/SDL2-2.30.5/src/main/uikit/SDL_uikit_main.c @@ -0,0 +1,23 @@ +/* + SDL_uikit_main.c, placed in the public domain by Sam Lantinga 3/18/2019 +*/ + +/* Include the SDL main definition header */ +#include "SDL_main.h" + +#if defined(__IPHONEOS__) || defined(__TVOS__) + +#ifndef SDL_MAIN_HANDLED +#ifdef main +#undef main +#endif + +int main(int argc, char *argv[]) +{ + return SDL_UIKitRunApp(argc, argv, SDL_main); +} +#endif /* !SDL_MAIN_HANDLED */ + +#endif /* __IPHONEOS__ || __TVOS__ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/main/windows/SDL_windows_main.c b/SDL2-2.30.5/src/main/windows/SDL_windows_main.c similarity index 62% rename from SDL2-2.0.12/src/main/windows/SDL_windows_main.c rename to SDL2-2.30.5/src/main/windows/SDL_windows_main.c index f8b1041..bad49b0 100644 --- a/SDL2-2.0.12/src/main/windows/SDL_windows_main.c +++ b/SDL2-2.30.5/src/main/windows/SDL_windows_main.c @@ -16,14 +16,11 @@ #include "SDL_main.h" #ifdef main -# undef main +#undef main #endif /* main */ -#define WIN_WStringToUTF8(S) SDL_iconv_string("UTF-8", "UTF-16LE", (char *)(S), (SDL_wcslen(S)+1)*sizeof(WCHAR)) - /* Pop up an out of memory message, returns to Windows */ -static BOOL -OutOfMemory(void) +static BOOL OutOfMemory(void) { SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal Error", "Out of memory - aborting", NULL); return FALSE; @@ -31,36 +28,48 @@ OutOfMemory(void) #if defined(_MSC_VER) /* The VC++ compiler needs main/wmain defined */ -# define console_ansi_main main -# if UNICODE -# define console_wmain wmain -# endif +#define console_ansi_main main +#if UNICODE +#define console_wmain wmain +#endif #endif /* Gets the arguments with GetCommandLine, converts them to argc and argv and calls SDL_main */ -static int -main_getcmdline(void) +static int main_getcmdline(void) { LPWSTR *argvw; char **argv; int i, argc, result; argvw = CommandLineToArgvW(GetCommandLineW(), &argc); - if (argvw == NULL) { + if (!argvw) { return OutOfMemory(); } + /* Note that we need to be careful about how we allocate/free memory here. + * If the application calls SDL_SetMemoryFunctions(), we can't rely on + * SDL_free() to use the same allocator after SDL_main() returns. + */ + /* Parse it into argv and argc */ - argv = (char **)SDL_calloc(argc + 1, sizeof(*argv)); + argv = (char **)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (argc + 1) * sizeof(*argv)); if (!argv) { return OutOfMemory(); } for (i = 0; i < argc; ++i) { - argv[i] = WIN_WStringToUTF8(argvw[i]); + DWORD len; + char *arg = WIN_StringToUTF8W(argvw[i]); + if (!arg) { + return OutOfMemory(); + } + len = (DWORD)SDL_strlen(arg); + argv[i] = (char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (size_t)len + 1); if (!argv[i]) { return OutOfMemory(); } + SDL_memcpy(argv[i], arg, len); + SDL_free(arg); } argv[i] = NULL; LocalFree(argvw); @@ -72,33 +81,30 @@ main_getcmdline(void) /* Free argv, to avoid memory leak */ for (i = 0; i < argc; ++i) { - SDL_free(argv[i]); + HeapFree(GetProcessHeap(), 0, argv[i]); } - SDL_free(argv); + HeapFree(GetProcessHeap(), 0, argv); return result; } /* This is where execution begins [console apps, ansi] */ -int -console_ansi_main(int argc, char *argv[]) +int console_ansi_main(int argc, char *argv[]) { return main_getcmdline(); } - #if UNICODE /* This is where execution begins [console apps, unicode] */ -int -console_wmain(int argc, wchar_t *wargv[], wchar_t *wenvp) +int console_wmain(int argc, wchar_t *wargv[], wchar_t *wenvp) { return main_getcmdline(); } #endif /* This is where execution begins [windowed apps] */ -int WINAPI -WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) +int WINAPI MINGW32_FORCEALIGN +WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) /* NOLINT(readability-inconsistent-declaration-parameter-name) */ { return main_getcmdline(); } diff --git a/SDL2-2.0.12/src/main/windows/version.rc b/SDL2-2.30.5/src/main/windows/version.rc similarity index 69% rename from SDL2-2.0.12/src/main/windows/version.rc rename to SDL2-2.30.5/src/main/windows/version.rc index f188494..69e6a8e 100644 --- a/SDL2-2.0.12/src/main/windows/version.rc +++ b/SDL2-2.30.5/src/main/windows/version.rc @@ -1,4 +1,4 @@ - +// This file is public domain. Do what you like with it. #include "winresrc.h" LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US @@ -9,8 +9,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 2,0,12,0 - PRODUCTVERSION 2,0,12,0 + FILEVERSION 2,30,5,0 + PRODUCTVERSION 2,30,5,0 FILEFLAGSMASK 0x3fL FILEFLAGS 0x0L FILEOS 0x40004L @@ -23,12 +23,12 @@ BEGIN BEGIN VALUE "CompanyName", "\0" VALUE "FileDescription", "SDL\0" - VALUE "FileVersion", "2, 0, 12, 0\0" + VALUE "FileVersion", "2, 30, 5, 0\0" VALUE "InternalName", "SDL\0" - VALUE "LegalCopyright", "Copyright 2020 Sam Lantinga\0" + VALUE "LegalCopyright", "Copyright (C) 2024 Sam Lantinga\0" VALUE "OriginalFilename", "SDL2.dll\0" VALUE "ProductName", "Simple DirectMedia Layer\0" - VALUE "ProductVersion", "2, 0, 12, 0\0" + VALUE "ProductVersion", "2, 30, 5, 0\0" END END BLOCK "VarFileInfo" diff --git a/SDL2-2.0.12/src/main/winrt/SDL2-WinRTResource_BlankCursor.cur b/SDL2-2.30.5/src/main/winrt/SDL2-WinRTResource_BlankCursor.cur similarity index 100% rename from SDL2-2.0.12/src/main/winrt/SDL2-WinRTResource_BlankCursor.cur rename to SDL2-2.30.5/src/main/winrt/SDL2-WinRTResource_BlankCursor.cur diff --git a/SDL2-2.0.12/src/main/winrt/SDL2-WinRTResources.rc b/SDL2-2.30.5/src/main/winrt/SDL2-WinRTResources.rc similarity index 100% rename from SDL2-2.0.12/src/main/winrt/SDL2-WinRTResources.rc rename to SDL2-2.30.5/src/main/winrt/SDL2-WinRTResources.rc diff --git a/SDL2-2.0.12/src/main/winrt/SDL_winrt_main_NonXAML.cpp b/SDL2-2.30.5/src/main/winrt/SDL_winrt_main_NonXAML.cpp similarity index 98% rename from SDL2-2.0.12/src/main/winrt/SDL_winrt_main_NonXAML.cpp rename to SDL2-2.30.5/src/main/winrt/SDL_winrt_main_NonXAML.cpp index 19d2250..575a62c 100644 --- a/SDL2-2.0.12/src/main/winrt/SDL_winrt_main_NonXAML.cpp +++ b/SDL2-2.30.5/src/main/winrt/SDL_winrt_main_NonXAML.cpp @@ -40,7 +40,7 @@ is compiled with C++/CX enabled (via the /ZW compiler flag). */ #ifdef _MSC_VER -#pragma warning(disable:4447) +#pragma warning(disable : 4447) #endif /* Make sure the function to initialize the Windows Runtime gets linked in. */ diff --git a/SDL2-2.30.5/src/misc/SDL_sysurl.h b/SDL2-2.30.5/src/misc/SDL_sysurl.h new file mode 100644 index 0000000..f2a4f9b --- /dev/null +++ b/SDL2-2.30.5/src/misc/SDL_sysurl.h @@ -0,0 +1,36 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_misc.h" +#include "SDL_error.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern int SDL_SYS_OpenURL(const char *url); + +#ifdef __cplusplus +} +#endif + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/misc/SDL_url.c b/SDL2-2.30.5/src/misc/SDL_url.c new file mode 100644 index 0000000..9876bf2 --- /dev/null +++ b/SDL2-2.30.5/src/misc/SDL_url.c @@ -0,0 +1,32 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_sysurl.h" + +int SDL_OpenURL(const char *url) +{ + if (!url) { + return SDL_InvalidParamError("url"); + } + return SDL_SYS_OpenURL(url); +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/haptic/darwin/SDL_syshaptic_c.h b/SDL2-2.30.5/src/misc/android/SDL_sysurl.c similarity index 81% rename from SDL2-2.0.12/src/haptic/darwin/SDL_syshaptic_c.h rename to SDL2-2.30.5/src/misc/android/SDL_sysurl.c index ca3b7e6..e7e21d2 100644 --- a/SDL2-2.0.12/src/haptic/darwin/SDL_syshaptic_c.h +++ b/SDL2-2.30.5/src/misc/android/SDL_sysurl.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -19,8 +19,12 @@ 3. This notice may not be removed or altered from any source distribution. */ -extern int MacHaptic_MaybeAddDevice( io_object_t device ); -extern int MacHaptic_MaybeRemoveDevice( io_object_t device ); +#include "../SDL_sysurl.h" +#include "../../core/android/SDL_android.h" + +int SDL_SYS_OpenURL(const char *url) +{ + return Android_JNI_OpenURL(url); +} /* vi: set ts=4 sw=4 expandtab: */ - diff --git a/SDL2-2.30.5/src/misc/dummy/SDL_sysurl.c b/SDL2-2.30.5/src/misc/dummy/SDL_sysurl.c new file mode 100644 index 0000000..a5fa7cb --- /dev/null +++ b/SDL2-2.30.5/src/misc/dummy/SDL_sysurl.c @@ -0,0 +1,29 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_sysurl.h" + +int SDL_SYS_OpenURL(const char *url) +{ + return SDL_Unsupported(); +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/misc/emscripten/SDL_sysurl.c b/SDL2-2.30.5/src/misc/emscripten/SDL_sysurl.c new file mode 100644 index 0000000..87c1a0c --- /dev/null +++ b/SDL2-2.30.5/src/misc/emscripten/SDL_sysurl.c @@ -0,0 +1,34 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_sysurl.h" + +#include + +EM_JS_DEPS(sdlsysurl, "$UTF8ToString"); + +int SDL_SYS_OpenURL(const char *url) +{ + EM_ASM(window.open(UTF8ToString($0), "_blank"), url); + return 0; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/misc/haiku/SDL_sysurl.cc b/SDL2-2.30.5/src/misc/haiku/SDL_sysurl.cc new file mode 100644 index 0000000..85fd622 --- /dev/null +++ b/SDL2-2.30.5/src/misc/haiku/SDL_sysurl.cc @@ -0,0 +1,33 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_sysurl.h" +#include + +int SDL_SYS_OpenURL(const char *url) +{ + BUrl burl(url); + const status_t rc = burl.OpenWithPreferredApplication(false); + return (rc == B_NO_ERROR) ? 0 : SDL_SetError("URL open failed (err=%d)", (int) rc); +} + +/* vi: set ts=4 sw=4 expandtab: */ + diff --git a/SDL2-2.30.5/src/misc/ios/SDL_sysurl.m b/SDL2-2.30.5/src/misc/ios/SDL_sysurl.m new file mode 100644 index 0000000..76363b5 --- /dev/null +++ b/SDL2-2.30.5/src/misc/ios/SDL_sysurl.m @@ -0,0 +1,36 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_sysurl.h" + +#import + +int SDL_SYS_OpenURL(const char *url) +{ + @autoreleasepool { + + NSString *nsstr = [NSString stringWithUTF8String:url]; + NSURL *nsurl = [NSURL URLWithString:nsstr]; + return [[UIApplication sharedApplication] openURL:nsurl] ? 0 : -1; + } +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/misc/macosx/SDL_sysurl.m b/SDL2-2.30.5/src/misc/macosx/SDL_sysurl.m new file mode 100644 index 0000000..d6088d1 --- /dev/null +++ b/SDL2-2.30.5/src/misc/macosx/SDL_sysurl.m @@ -0,0 +1,36 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_sysurl.h" + +#import + +int SDL_SYS_OpenURL(const char *url) +{ + @autoreleasepool { + CFURLRef cfurl = CFURLCreateWithBytes(NULL, (const UInt8 *)url, SDL_strlen(url), kCFStringEncodingUTF8, NULL); + OSStatus status = LSOpenCFURLRef(cfurl, NULL); + CFRelease(cfurl); + return status == noErr ? 0 : -1; + } +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/misc/riscos/SDL_sysurl.c b/SDL2-2.30.5/src/misc/riscos/SDL_sysurl.c new file mode 100644 index 0000000..bbb78c9 --- /dev/null +++ b/SDL2-2.30.5/src/misc/riscos/SDL_sysurl.c @@ -0,0 +1,47 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_sysurl.h" + +#include +#include + +#ifndef URI_Dispatch +#define URI_Dispatch 0x4e381 +#endif + +int SDL_SYS_OpenURL(const char *url) +{ + _kernel_swi_regs regs; + _kernel_oserror *error; + + regs.r[0] = 0; + regs.r[1] = (int)url; + regs.r[2] = 0; + error = _kernel_swi(URI_Dispatch, ®s, ®s); + if (error) { + return SDL_SetError("Couldn't open given URL: %s", error->errmess); + } + + return (regs.r[0] & 1) ? SDL_SetError("Couldn't open given URL.") : 0; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/misc/unix/SDL_sysurl.c b/SDL2-2.30.5/src/misc/unix/SDL_sysurl.c new file mode 100644 index 0000000..050446d --- /dev/null +++ b/SDL2-2.30.5/src/misc/unix/SDL_sysurl.c @@ -0,0 +1,82 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_sysurl.h" + +#include +#include +#include +#include +#include +#include + +int SDL_SYS_OpenURL(const char *url) +{ + const pid_t pid1 = fork(); + if (pid1 == 0) { /* child process */ +#ifdef USE_POSIX_SPAWN + pid_t pid2; + const char *args[] = { "xdg-open", url, NULL }; + /* Clear LD_PRELOAD so Chrome opens correctly when this application is launched by Steam */ + unsetenv("LD_PRELOAD"); + if (posix_spawnp(&pid2, args[0], NULL, NULL, (char **)args, environ) == 0) { + /* Child process doesn't wait for possibly-blocking grandchild. */ + _exit(EXIT_SUCCESS); + } else { + _exit(EXIT_FAILURE); + } +#else + pid_t pid2; + /* Clear LD_PRELOAD so Chrome opens correctly when this application is launched by Steam */ + unsetenv("LD_PRELOAD"); + /* Notice this is vfork and not fork! */ + pid2 = vfork(); + if (pid2 == 0) { /* Grandchild process will try to launch the url */ + execlp("xdg-open", "xdg-open", url, NULL); + _exit(EXIT_FAILURE); + } else if (pid2 < 0) { /* There was an error forking */ + _exit(EXIT_FAILURE); + } else { + /* Child process doesn't wait for possibly-blocking grandchild. */ + _exit(EXIT_SUCCESS); + } +#endif /* USE_POSIX_SPAWN */ + } else if (pid1 < 0) { + return SDL_SetError("fork() failed: %s", strerror(errno)); + } else { + int status; + if (waitpid(pid1, &status, 0) == pid1) { + if (WIFEXITED(status)) { + if (WEXITSTATUS(status) == 0) { + return 0; /* success! */ + } else { + return SDL_SetError("xdg-open reported error or failed to launch: %d", WEXITSTATUS(status)); + } + } else { + return SDL_SetError("xdg-open failed for some reason"); + } + } else { + return SDL_SetError("Waiting on xdg-open failed: %s", strerror(errno)); + } + } +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/misc/vita/SDL_sysurl.c b/SDL2-2.30.5/src/misc/vita/SDL_sysurl.c new file mode 100644 index 0000000..fca6b2f --- /dev/null +++ b/SDL2-2.30.5/src/misc/vita/SDL_sysurl.c @@ -0,0 +1,42 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_sysurl.h" + +#include +#include + +int SDL_SYS_OpenURL(const char *url) +{ + SceAppUtilInitParam init_param; + SceAppUtilBootParam boot_param; + SceAppUtilWebBrowserParam browser_param; + SDL_zero(init_param); + SDL_zero(boot_param); + sceAppUtilInit(&init_param, &boot_param); + SDL_zero(browser_param); + browser_param.str = url; + browser_param.strlen = SDL_strlen(url); + sceAppUtilLaunchWebBrowser(&browser_param); + return 0; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/misc/windows/SDL_sysurl.c b/SDL2-2.30.5/src/misc/windows/SDL_sysurl.c new file mode 100644 index 0000000..8462bab --- /dev/null +++ b/SDL2-2.30.5/src/misc/windows/SDL_sysurl.c @@ -0,0 +1,60 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_sysurl.h" +#include "../../core/windows/SDL_windows.h" + +#include + +#if defined(__XBOXONE__) || defined(__XBOXSERIES__) +int SDL_SYS_OpenURL(const char *url) +{ + /* Not supported */ + return SDL_Unsupported(); +} +#else +/* https://msdn.microsoft.com/en-us/library/windows/desktop/bb762153%28v=vs.85%29.aspx */ +int SDL_SYS_OpenURL(const char *url) +{ + WCHAR *wurl; + HINSTANCE rc; + + /* MSDN says for safety's sake, make sure COM is initialized. */ + const HRESULT hr = WIN_CoInitialize(); + if (FAILED(hr)) { + return WIN_SetErrorFromHRESULT("CoInitialize failed", hr); + } + + wurl = WIN_UTF8ToStringW(url); + if (!wurl) { + WIN_CoUninitialize(); + return SDL_OutOfMemory(); + } + + /* Success returns value greater than 32. Less is an error. */ + rc = ShellExecuteW(NULL, L"open", wurl, NULL, NULL, SW_SHOWNORMAL); + SDL_free(wurl); + WIN_CoUninitialize(); + return (rc > ((HINSTANCE)32)) ? 0 : WIN_SetError("Couldn't open given URL."); +} +#endif + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/misc/winrt/SDL_sysurl.cpp b/SDL2-2.30.5/src/misc/winrt/SDL_sysurl.cpp new file mode 100644 index 0000000..f435ab9 --- /dev/null +++ b/SDL2-2.30.5/src/misc/winrt/SDL_sysurl.cpp @@ -0,0 +1,39 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_sysurl.h" +#include "../../core/windows/SDL_windows.h" + +int SDL_SYS_OpenURL(const char *url) +{ + WCHAR *wurl = WIN_UTF8ToStringW(url); + if (!wurl) { + return SDL_OutOfMemory(); + } + auto strurl = ref new Platform::String(wurl); + SDL_free(wurl); + + auto uri = ref new Windows::Foundation::Uri(strurl); + Windows::System::Launcher::LaunchUriAsync(uri); + return 0; // oh well, we're not waiting on an async task here. +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/power/SDL_power.c b/SDL2-2.30.5/src/power/SDL_power.c similarity index 72% rename from SDL2-2.0.12/src/power/SDL_power.c rename to SDL2-2.30.5/src/power/SDL_power.c index ca19d44..a64cace 100644 --- a/SDL2-2.0.12/src/power/SDL_power.c +++ b/SDL2-2.30.5/src/power/SDL_power.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,15 +26,13 @@ * Returns SDL_TRUE if we have a definitive answer. * SDL_FALSE to try next implementation. */ -typedef SDL_bool - (*SDL_GetPowerInfo_Impl) (SDL_PowerState * state, int *seconds, - int *percent); +typedef SDL_bool (*SDL_GetPowerInfo_Impl)(SDL_PowerState *state, int *seconds, + int *percent); #ifndef SDL_POWER_DISABLED #ifdef SDL_POWER_HARDWIRED /* This is for things that _never_ have a battery */ -static SDL_bool -SDL_GetPowerInfo_Hardwired(SDL_PowerState * state, int *seconds, int *percent) +static SDL_bool SDL_GetPowerInfo_Hardwired(SDL_PowerState *state, int *seconds, int *percent) { *seconds = -1; *percent = -1; @@ -44,34 +42,40 @@ SDL_GetPowerInfo_Hardwired(SDL_PowerState * state, int *seconds, int *percent) #endif static SDL_GetPowerInfo_Impl implementations[] = { -#ifdef SDL_POWER_LINUX /* in order of preference. More than could work. */ +#ifdef SDL_POWER_LINUX /* in order of preference. More than could work. */ SDL_GetPowerInfo_Linux_org_freedesktop_upower, SDL_GetPowerInfo_Linux_sys_class_power_supply, SDL_GetPowerInfo_Linux_proc_acpi, SDL_GetPowerInfo_Linux_proc_apm, #endif -#ifdef SDL_POWER_WINDOWS /* handles Win32, Win64, PocketPC. */ +#ifdef SDL_POWER_WINDOWS /* handles Win32, Win64, PocketPC. */ SDL_GetPowerInfo_Windows, #endif -#ifdef SDL_POWER_UIKIT /* handles iPhone/iPad/etc */ +#ifdef SDL_POWER_UIKIT /* handles iPhone/iPad/etc */ SDL_GetPowerInfo_UIKit, #endif #ifdef SDL_POWER_MACOSX /* handles Mac OS X, Darwin. */ SDL_GetPowerInfo_MacOSX, #endif -#ifdef SDL_POWER_HAIKU /* with BeOS euc.jp apm driver. Does this work on Haiku? */ +#ifdef SDL_POWER_HAIKU /* with BeOS euc.jp apm driver. Does this work on Haiku? */ SDL_GetPowerInfo_Haiku, #endif -#ifdef SDL_POWER_ANDROID /* handles Android. */ +#ifdef SDL_POWER_ANDROID /* handles Android. */ SDL_GetPowerInfo_Android, #endif -#ifdef SDL_POWER_PSP /* handles PSP. */ +#ifdef SDL_POWER_PSP /* handles PSP. */ SDL_GetPowerInfo_PSP, #endif -#ifdef SDL_POWER_WINRT /* handles WinRT */ +#ifdef SDL_POWER_VITA /* handles PSVita. */ + SDL_GetPowerInfo_VITA, +#endif +#ifdef SDL_POWER_N3DS /* handles N3DS. */ + SDL_GetPowerInfo_N3DS, +#endif +#ifdef SDL_POWER_WINRT /* handles WinRT */ SDL_GetPowerInfo_WinRT, #endif -#ifdef SDL_POWER_EMSCRIPTEN /* handles Emscripten */ +#ifdef SDL_POWER_EMSCRIPTEN /* handles Emscripten */ SDL_GetPowerInfo_Emscripten, #endif @@ -81,8 +85,7 @@ static SDL_GetPowerInfo_Impl implementations[] = { }; #endif -SDL_PowerState -SDL_GetPowerInfo(int *seconds, int *percent) +SDL_PowerState SDL_GetPowerInfo(int *seconds, int *percent) { #ifndef SDL_POWER_DISABLED const int total = sizeof(implementations) / sizeof(implementations[0]); @@ -92,10 +95,10 @@ SDL_GetPowerInfo(int *seconds, int *percent) int _seconds, _percent; /* Make these never NULL for platform-specific implementations. */ - if (seconds == NULL) { + if (!seconds) { seconds = &_seconds; } - if (percent == NULL) { + if (!percent) { percent = &_percent; } diff --git a/SDL2-2.0.12/src/power/SDL_syspower.h b/SDL2-2.30.5/src/power/SDL_syspower.h similarity index 91% rename from SDL2-2.0.12/src/power/SDL_syspower.h rename to SDL2-2.30.5/src/power/SDL_syspower.h index f28cc98..25b22fc 100644 --- a/SDL2-2.0.12/src/power/SDL_syspower.h +++ b/SDL2-2.30.5/src/power/SDL_syspower.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -38,6 +38,8 @@ SDL_bool SDL_GetPowerInfo_MacOSX(SDL_PowerState *, int *, int *); SDL_bool SDL_GetPowerInfo_Haiku(SDL_PowerState *, int *, int *); SDL_bool SDL_GetPowerInfo_Android(SDL_PowerState *, int *, int *); SDL_bool SDL_GetPowerInfo_PSP(SDL_PowerState *, int *, int *); +SDL_bool SDL_GetPowerInfo_VITA(SDL_PowerState *, int *, int *); +SDL_bool SDL_GetPowerInfo_N3DS(SDL_PowerState *, int *, int *); SDL_bool SDL_GetPowerInfo_WinRT(SDL_PowerState *, int *, int *); SDL_bool SDL_GetPowerInfo_Emscripten(SDL_PowerState *, int *, int *); diff --git a/SDL2-2.0.12/src/power/android/SDL_syspower.c b/SDL2-2.30.5/src/power/android/SDL_syspower.c similarity index 91% rename from SDL2-2.0.12/src/power/android/SDL_syspower.c rename to SDL2-2.30.5/src/power/android/SDL_syspower.c index 045925a..3da49e5 100644 --- a/SDL2-2.0.12/src/power/android/SDL_syspower.c +++ b/SDL2-2.30.5/src/power/android/SDL_syspower.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -21,15 +21,14 @@ #include "../../SDL_internal.h" #ifndef SDL_POWER_DISABLED -#if SDL_POWER_ANDROID +#ifdef SDL_POWER_ANDROID #include "SDL_power.h" #include "../SDL_syspower.h" #include "../../core/android/SDL_android.h" -SDL_bool -SDL_GetPowerInfo_Android(SDL_PowerState * state, int *seconds, int *percent) +SDL_bool SDL_GetPowerInfo_Android(SDL_PowerState *state, int *seconds, int *percent) { int battery; int plugged; diff --git a/SDL2-2.0.12/src/power/emscripten/SDL_syspower.c b/SDL2-2.30.5/src/power/emscripten/SDL_syspower.c similarity index 89% rename from SDL2-2.0.12/src/power/emscripten/SDL_syspower.c rename to SDL2-2.30.5/src/power/emscripten/SDL_syspower.c index 97afe34..aed93b0 100644 --- a/SDL2-2.0.12/src/power/emscripten/SDL_syspower.c +++ b/SDL2-2.30.5/src/power/emscripten/SDL_syspower.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -21,20 +21,20 @@ #include "../../SDL_internal.h" #ifndef SDL_POWER_DISABLED -#if SDL_POWER_EMSCRIPTEN +#ifdef SDL_POWER_EMSCRIPTEN #include #include "SDL_power.h" -SDL_bool -SDL_GetPowerInfo_Emscripten(SDL_PowerState *state, int *seconds, int *percent) +SDL_bool SDL_GetPowerInfo_Emscripten(SDL_PowerState *state, int *seconds, int *percent) { EmscriptenBatteryEvent batteryState; int haveBattery = 0; - if (emscripten_get_battery_status(&batteryState) == EMSCRIPTEN_RESULT_NOT_SUPPORTED) + if (emscripten_get_battery_status(&batteryState) == EMSCRIPTEN_RESULT_NOT_SUPPORTED) { return SDL_FALSE; + } haveBattery = batteryState.level != 1.0 || !batteryState.charging || batteryState.chargingTime != 0.0; diff --git a/SDL2-2.0.12/src/power/haiku/SDL_syspower.c b/SDL2-2.30.5/src/power/haiku/SDL_syspower.c similarity index 72% rename from SDL2-2.0.12/src/power/haiku/SDL_syspower.c rename to SDL2-2.30.5/src/power/haiku/SDL_syspower.c index 28ccdec..ec3d4b9 100644 --- a/SDL2-2.0.12/src/power/haiku/SDL_syspower.c +++ b/SDL2-2.30.5/src/power/haiku/SDL_syspower.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -24,7 +24,7 @@ /* !!! FIXME: does this thing even work on Haiku? */ #ifndef SDL_POWER_DISABLED -#if SDL_POWER_HAIKU +#ifdef SDL_POWER_HAIKU #include #include @@ -34,18 +34,17 @@ #include /* These values are from apm.h ... */ -#define APM_DEVICE_PATH "/dev/misc/apm" -#define APM_FUNC_OFFSET 0x5300 +#define APM_DEVICE_PATH "/dev/misc/apm" +#define APM_FUNC_OFFSET 0x5300 #define APM_FUNC_GET_POWER_STATUS 10 #define APM_DEVICE_ALL 1 #define APM_BIOS_CALL (B_DEVICE_OP_CODES_END + 3) #include "SDL_power.h" -SDL_bool -SDL_GetPowerInfo_Haiku(SDL_PowerState * state, int *seconds, int *percent) +SDL_bool SDL_GetPowerInfo_Haiku(SDL_PowerState *state, int *seconds, int *percent) { - const int fd = open("/dev/misc/apm", O_RDONLY); + const int fd = open("/dev/misc/apm", O_RDONLY | O_CLOEXEC); SDL_bool need_details = SDL_FALSE; uint16 regs[6]; uint8 ac_status; @@ -56,10 +55,10 @@ SDL_GetPowerInfo_Haiku(SDL_PowerState * state, int *seconds, int *percent) int rc; if (fd == -1) { - return SDL_FALSE; /* maybe some other method will work? */ + return SDL_FALSE; /* maybe some other method will work? */ } - memset(regs, '\0', sizeof(regs)); + SDL_memset(regs, '\0', sizeof(regs)); regs[0] = APM_FUNC_OFFSET + APM_FUNC_GET_POWER_STATUS; regs[1] = APM_DEVICE_ALL; rc = ioctl(fd, APM_BIOS_CALL, regs); @@ -73,10 +72,10 @@ SDL_GetPowerInfo_Haiku(SDL_PowerState * state, int *seconds, int *percent) battery_status = regs[1] & 0xFF; battery_flags = regs[2] >> 8; battery_life = regs[2] & 0xFF; - battery_time = (uint32) regs[3]; + battery_time = (uint32)regs[3]; /* in theory, _something_ should be set in battery_flags, right? */ - if (battery_flags == 0x00) { /* older APM BIOS? Less fields. */ + if (battery_flags == 0x00) { /* older APM BIOS? Less fields. */ battery_time = 0xFFFF; if (battery_status == 0xFF) { battery_flags = 0xFF; @@ -90,36 +89,36 @@ SDL_GetPowerInfo_Haiku(SDL_PowerState * state, int *seconds, int *percent) battery_time = (battery_time & 0x7FFF) * 60; } - if (battery_flags == 0xFF) { /* unknown state */ + if (battery_flags == 0xFF) { /* unknown state */ *state = SDL_POWERSTATE_UNKNOWN; - } else if (battery_flags & (1 << 7)) { /* no battery */ + } else if (battery_flags & (1 << 7)) { /* no battery */ *state = SDL_POWERSTATE_NO_BATTERY; - } else if (battery_flags & (1 << 3)) { /* charging */ + } else if (battery_flags & (1 << 3)) { /* charging */ *state = SDL_POWERSTATE_CHARGING; need_details = SDL_TRUE; } else if (ac_status == 1) { - *state = SDL_POWERSTATE_CHARGED; /* on AC, not charging. */ + *state = SDL_POWERSTATE_CHARGED; /* on AC, not charging. */ need_details = SDL_TRUE; } else { - *state = SDL_POWERSTATE_ON_BATTERY; /* not on AC. */ + *state = SDL_POWERSTATE_ON_BATTERY; /* not on AC. */ need_details = SDL_TRUE; } *percent = -1; *seconds = -1; if (need_details) { - const int pct = (int) battery_life; - const int secs = (int) battery_time; + const int pct = (int)battery_life; + const int secs = (int)battery_time; - if (pct != 255) { /* 255 == unknown */ + if (pct != 255) { /* 255 == unknown */ *percent = (pct > 100) ? 100 : pct; /* clamp between 0%, 100% */ } - if (secs != 0xFFFF) { /* 0xFFFF == unknown */ + if (secs != 0xFFFF) { /* 0xFFFF == unknown */ *seconds = secs; } } - return SDL_TRUE; /* the definitive answer if APM driver replied. */ + return SDL_TRUE; /* the definitive answer if APM driver replied. */ } #endif /* SDL_POWER_HAIKU */ diff --git a/SDL2-2.0.12/src/power/linux/SDL_syspower.c b/SDL2-2.30.5/src/power/linux/SDL_syspower.c similarity index 57% rename from SDL2-2.0.12/src/power/linux/SDL_syspower.c rename to SDL2-2.30.5/src/power/linux/SDL_syspower.c index 234119c..7899e3d 100644 --- a/SDL2-2.0.12/src/power/linux/SDL_syspower.c +++ b/SDL2-2.30.5/src/power/linux/SDL_syspower.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -21,7 +21,7 @@ #include "../../SDL_internal.h" #ifndef SDL_POWER_DISABLED -#if SDL_POWER_LINUX +#ifdef SDL_POWER_LINUX #include #include @@ -41,50 +41,48 @@ static const char *proc_acpi_battery_path = "/proc/acpi/battery"; static const char *proc_acpi_ac_adapter_path = "/proc/acpi/ac_adapter"; static const char *sys_class_power_supply_path = "/sys/class/power_supply"; -static int -open_power_file(const char *base, const char *node, const char *key) +static int open_power_file(const char *base, const char *node, const char *key) { - const size_t pathlen = strlen(base) + strlen(node) + strlen(key) + 3; - char *path = (char *) alloca(pathlen); - if (path == NULL) { - return -1; /* oh well. */ + int fd; + const size_t pathlen = SDL_strlen(base) + SDL_strlen(node) + SDL_strlen(key) + 3; + char *path = SDL_stack_alloc(char, pathlen); + if (!path) { + return -1; /* oh well. */ } - snprintf(path, pathlen, "%s/%s/%s", base, node, key); - return open(path, O_RDONLY); + (void)SDL_snprintf(path, pathlen, "%s/%s/%s", base, node, key); + fd = open(path, O_RDONLY | O_CLOEXEC); + SDL_stack_free(path); + return fd; } - -static SDL_bool -read_power_file(const char *base, const char *node, const char *key, - char *buf, size_t buflen) +static SDL_bool read_power_file(const char *base, const char *node, const char *key, + char *buf, size_t buflen) { ssize_t br = 0; const int fd = open_power_file(base, node, key); if (fd == -1) { return SDL_FALSE; } - br = read(fd, buf, buflen-1); + br = read(fd, buf, buflen - 1); close(fd); if (br < 0) { return SDL_FALSE; } - buf[br] = '\0'; /* null-terminate the string. */ + buf[br] = '\0'; /* null-terminate the string. */ return SDL_TRUE; } - -static SDL_bool -make_proc_acpi_key_val(char **_ptr, char **_key, char **_val) +static SDL_bool make_proc_acpi_key_val(char **_ptr, char **_key, char **_val) { char *ptr = *_ptr; while (*ptr == ' ') { - ptr++; /* skip whitespace. */ + ptr++; /* skip whitespace. */ } if (*ptr == '\0') { - return SDL_FALSE; /* EOF. */ + return SDL_FALSE; /* EOF. */ } *_key = ptr; @@ -94,17 +92,17 @@ make_proc_acpi_key_val(char **_ptr, char **_key, char **_val) } if (*ptr == '\0') { - return SDL_FALSE; /* (unexpected) EOF. */ + return SDL_FALSE; /* (unexpected) EOF. */ } - *(ptr++) = '\0'; /* terminate the key. */ + *(ptr++) = '\0'; /* terminate the key. */ while (*ptr == ' ') { - ptr++; /* skip whitespace. */ + ptr++; /* skip whitespace. */ } if (*ptr == '\0') { - return SDL_FALSE; /* (unexpected) EOF. */ + return SDL_FALSE; /* (unexpected) EOF. */ } *_val = ptr; @@ -114,16 +112,15 @@ make_proc_acpi_key_val(char **_ptr, char **_key, char **_val) } if (*ptr != '\0') { - *(ptr++) = '\0'; /* terminate the value. */ + *(ptr++) = '\0'; /* terminate the value. */ } - *_ptr = ptr; /* store for next time. */ + *_ptr = ptr; /* store for next time. */ return SDL_TRUE; } -static void -check_proc_acpi_battery(const char * node, SDL_bool * have_battery, - SDL_bool * charging, int *seconds, int *percent) +static void check_proc_acpi_battery(const char *node, SDL_bool *have_battery, + SDL_bool *charging, int *seconds, int *percent) { const char *base = proc_acpi_battery_path; char info[1024]; @@ -138,28 +135,28 @@ check_proc_acpi_battery(const char * node, SDL_bool * have_battery, int secs = -1; int pct = -1; - if (!read_power_file(base, node, "state", state, sizeof (state))) { + if (!read_power_file(base, node, "state", state, sizeof(state))) { return; - } else if (!read_power_file(base, node, "info", info, sizeof (info))) { + } else if (!read_power_file(base, node, "info", info, sizeof(info))) { return; } ptr = &state[0]; while (make_proc_acpi_key_val(&ptr, &key, &val)) { - if (strcmp(key, "present") == 0) { - if (strcmp(val, "yes") == 0) { + if (SDL_strcasecmp(key, "present") == 0) { + if (SDL_strcasecmp(val, "yes") == 0) { *have_battery = SDL_TRUE; } - } else if (strcmp(key, "charging state") == 0) { + } else if (SDL_strcasecmp(key, "charging state") == 0) { /* !!! FIXME: what exactly _does_ charging/discharging mean? */ - if (strcmp(val, "charging/discharging") == 0) { + if (SDL_strcasecmp(val, "charging/discharging") == 0) { charge = SDL_TRUE; - } else if (strcmp(val, "charging") == 0) { + } else if (SDL_strcasecmp(val, "charging") == 0) { charge = SDL_TRUE; } - } else if (strcmp(key, "remaining capacity") == 0) { + } else if (SDL_strcasecmp(key, "remaining capacity") == 0) { char *endptr = NULL; - const int cvt = (int) strtol(val, &endptr, 10); + const int cvt = (int)SDL_strtol(val, &endptr, 10); if (*endptr == ' ') { remaining = cvt; } @@ -168,9 +165,9 @@ check_proc_acpi_battery(const char * node, SDL_bool * have_battery, ptr = &info[0]; while (make_proc_acpi_key_val(&ptr, &key, &val)) { - if (strcmp(key, "design capacity") == 0) { + if (SDL_strcasecmp(key, "design capacity") == 0) { char *endptr = NULL; - const int cvt = (int) strtol(val, &endptr, 10); + const int cvt = (int)SDL_strtol(val, &endptr, 10); if (*endptr == ' ') { maximum = cvt; } @@ -178,7 +175,7 @@ check_proc_acpi_battery(const char * node, SDL_bool * have_battery, } if ((maximum >= 0) && (remaining >= 0)) { - pct = (int) ((((float) remaining) / ((float) maximum)) * 100.0f); + pct = (int)((((float)remaining) / ((float)maximum)) * 100.0f); if (pct < 0) { pct = 0; } else if (pct > 100) { @@ -194,7 +191,7 @@ check_proc_acpi_battery(const char * node, SDL_bool * have_battery, */ if ((secs < 0) && (*seconds < 0)) { if ((pct < 0) && (*percent < 0)) { - choose = SDL_TRUE; /* at least we know there's a battery. */ + choose = SDL_TRUE; /* at least we know there's a battery. */ } if (pct > *percent) { choose = SDL_TRUE; @@ -210,8 +207,7 @@ check_proc_acpi_battery(const char * node, SDL_bool * have_battery, } } -static void -check_proc_acpi_ac_adapter(const char * node, SDL_bool * have_ac) +static void check_proc_acpi_ac_adapter(const char *node, SDL_bool *have_ac) { const char *base = proc_acpi_ac_adapter_path; char state[256]; @@ -219,24 +215,21 @@ check_proc_acpi_ac_adapter(const char * node, SDL_bool * have_ac) char *key = NULL; char *val = NULL; - if (!read_power_file(base, node, "state", state, sizeof (state))) { + if (!read_power_file(base, node, "state", state, sizeof(state))) { return; } ptr = &state[0]; while (make_proc_acpi_key_val(&ptr, &key, &val)) { - if (strcmp(key, "state") == 0) { - if (strcmp(val, "on-line") == 0) { + if (SDL_strcasecmp(key, "state") == 0) { + if (SDL_strcasecmp(val, "on-line") == 0) { *have_ac = SDL_TRUE; } } } } - -SDL_bool -SDL_GetPowerInfo_Linux_proc_acpi(SDL_PowerState * state, - int *seconds, int *percent) +SDL_bool SDL_GetPowerInfo_Linux_proc_acpi(SDL_PowerState *state, int *seconds, int *percent) { struct dirent *dent = NULL; DIR *dirp = NULL; @@ -249,8 +242,8 @@ SDL_GetPowerInfo_Linux_proc_acpi(SDL_PowerState * state, *state = SDL_POWERSTATE_UNKNOWN; dirp = opendir(proc_acpi_battery_path); - if (dirp == NULL) { - return SDL_FALSE; /* can't use this interface. */ + if (!dirp) { + return SDL_FALSE; /* can't use this interface. */ } else { while ((dent = readdir(dirp)) != NULL) { const char *node = dent->d_name; @@ -261,8 +254,8 @@ SDL_GetPowerInfo_Linux_proc_acpi(SDL_PowerState * state, } dirp = opendir(proc_acpi_ac_adapter_path); - if (dirp == NULL) { - return SDL_FALSE; /* can't use this interface. */ + if (!dirp) { + return SDL_FALSE; /* can't use this interface. */ } else { while ((dent = readdir(dirp)) != NULL) { const char *node = dent->d_name; @@ -281,17 +274,15 @@ SDL_GetPowerInfo_Linux_proc_acpi(SDL_PowerState * state, *state = SDL_POWERSTATE_ON_BATTERY; } - return SDL_TRUE; /* definitive answer. */ + return SDL_TRUE; /* definitive answer. */ } - -static SDL_bool -next_string(char **_ptr, char **_str) +static SDL_bool next_string(char **_ptr, char **_str) { char *ptr = *_ptr; char *str; - while (*ptr == ' ') { /* skip any spaces... */ + while (*ptr == ' ') { /* skip any spaces... */ ptr++; } @@ -300,29 +291,28 @@ next_string(char **_ptr, char **_str) } str = ptr; - while ((*ptr != ' ') && (*ptr != '\n') && (*ptr != '\0')) + while ((*ptr != ' ') && (*ptr != '\n') && (*ptr != '\0')) { ptr++; + } - if (*ptr != '\0') + if (*ptr != '\0') { *(ptr++) = '\0'; + } *_str = str; *_ptr = ptr; return SDL_TRUE; } -static SDL_bool -int_string(char *str, int *val) +static SDL_bool int_string(char *str, int *val) { char *endptr = NULL; - *val = (int) strtol(str, &endptr, 0); - return ((*str != '\0') && (*endptr == '\0')); + *val = (int)SDL_strtol(str, &endptr, 0); + return (*str != '\0') && (*endptr == '\0'); } /* http://lxr.linux.no/linux+v2.6.29/drivers/char/apm-emulation.c */ -SDL_bool -SDL_GetPowerInfo_Linux_proc_apm(SDL_PowerState * state, - int *seconds, int *percent) +SDL_bool SDL_GetPowerInfo_Linux_proc_apm(SDL_PowerState *state, int *seconds, int *percent) { SDL_bool need_details = SDL_FALSE; int ac_status = 0; @@ -330,81 +320,81 @@ SDL_GetPowerInfo_Linux_proc_apm(SDL_PowerState * state, int battery_flag = 0; int battery_percent = 0; int battery_time = 0; - const int fd = open(proc_apm_path, O_RDONLY); + const int fd = open(proc_apm_path, O_RDONLY | O_CLOEXEC); char buf[128]; char *ptr = &buf[0]; char *str = NULL; ssize_t br; if (fd == -1) { - return SDL_FALSE; /* can't use this interface. */ + return SDL_FALSE; /* can't use this interface. */ } - br = read(fd, buf, sizeof (buf) - 1); + br = read(fd, buf, sizeof(buf) - 1); close(fd); if (br < 0) { return SDL_FALSE; } - buf[br] = '\0'; /* null-terminate the string. */ - if (!next_string(&ptr, &str)) { /* driver version */ + buf[br] = '\0'; /* null-terminate the string. */ + if (!next_string(&ptr, &str)) { /* driver version */ return SDL_FALSE; } - if (!next_string(&ptr, &str)) { /* BIOS version */ + if (!next_string(&ptr, &str)) { /* BIOS version */ return SDL_FALSE; } - if (!next_string(&ptr, &str)) { /* APM flags */ + if (!next_string(&ptr, &str)) { /* APM flags */ return SDL_FALSE; } - if (!next_string(&ptr, &str)) { /* AC line status */ + if (!next_string(&ptr, &str)) { /* AC line status */ return SDL_FALSE; } else if (!int_string(str, &ac_status)) { return SDL_FALSE; } - if (!next_string(&ptr, &str)) { /* battery status */ + if (!next_string(&ptr, &str)) { /* battery status */ return SDL_FALSE; } else if (!int_string(str, &battery_status)) { return SDL_FALSE; } - if (!next_string(&ptr, &str)) { /* battery flag */ + if (!next_string(&ptr, &str)) { /* battery flag */ return SDL_FALSE; } else if (!int_string(str, &battery_flag)) { return SDL_FALSE; } - if (!next_string(&ptr, &str)) { /* remaining battery life percent */ + if (!next_string(&ptr, &str)) { /* remaining battery life percent */ return SDL_FALSE; } - if (str[strlen(str) - 1] == '%') { - str[strlen(str) - 1] = '\0'; + if (str[SDL_strlen(str) - 1] == '%') { + str[SDL_strlen(str) - 1] = '\0'; } if (!int_string(str, &battery_percent)) { return SDL_FALSE; } - if (!next_string(&ptr, &str)) { /* remaining battery life time */ + if (!next_string(&ptr, &str)) { /* remaining battery life time */ return SDL_FALSE; } else if (!int_string(str, &battery_time)) { return SDL_FALSE; } - if (!next_string(&ptr, &str)) { /* remaining battery life time units */ + if (!next_string(&ptr, &str)) { /* remaining battery life time units */ return SDL_FALSE; - } else if (strcmp(str, "min") == 0) { + } else if (SDL_strcasecmp(str, "min") == 0) { battery_time *= 60; } if (battery_flag == 0xFF) { /* unknown state */ *state = SDL_POWERSTATE_UNKNOWN; - } else if (battery_flag & (1 << 7)) { /* no battery */ + } else if (battery_flag & (1 << 7)) { /* no battery */ *state = SDL_POWERSTATE_NO_BATTERY; - } else if (battery_flag & (1 << 3)) { /* charging */ + } else if (battery_flag & (1 << 3)) { /* charging */ *state = SDL_POWERSTATE_CHARGING; need_details = SDL_TRUE; } else if (ac_status == 1) { - *state = SDL_POWERSTATE_CHARGED; /* on AC, not charging. */ + *state = SDL_POWERSTATE_CHARGED; /* on AC, not charging. */ need_details = SDL_TRUE; } else { *state = SDL_POWERSTATE_ON_BATTERY; @@ -417,10 +407,10 @@ SDL_GetPowerInfo_Linux_proc_apm(SDL_PowerState * state, const int pct = battery_percent; const int secs = battery_time; - if (pct >= 0) { /* -1 == unknown */ + if (pct >= 0) { /* -1 == unknown */ *percent = (pct > 100) ? 100 : pct; /* clamp between 0%, 100% */ } - if (secs >= 0) { /* -1 == unknown */ + if (secs >= 0) { /* -1 == unknown */ *seconds = secs; } } @@ -428,8 +418,7 @@ SDL_GetPowerInfo_Linux_proc_apm(SDL_PowerState * state, return SDL_TRUE; } -SDL_bool -SDL_GetPowerInfo_Linux_sys_class_power_supply(SDL_PowerState *state, int *seconds, int *percent) +SDL_bool SDL_GetPowerInfo_Linux_sys_class_power_supply(SDL_PowerState *state, int *seconds, int *percent) { const char *base = sys_class_power_supply_path; struct dirent *dent; @@ -440,7 +429,7 @@ SDL_GetPowerInfo_Linux_sys_class_power_supply(SDL_PowerState *state, int *second return SDL_FALSE; } - *state = SDL_POWERSTATE_NO_BATTERY; /* assume we're just plugged in. */ + *state = SDL_POWERSTATE_NO_BATTERY; /* assume we're just plugged in. */ *seconds = -1; *percent = -1; @@ -455,52 +444,52 @@ SDL_GetPowerInfo_Linux_sys_class_power_supply(SDL_PowerState *state, int *second int power; if ((SDL_strcmp(name, ".") == 0) || (SDL_strcmp(name, "..") == 0)) { - continue; /* skip these, of course. */ - } else if (!read_power_file(base, name, "type", str, sizeof (str))) { - continue; /* Don't know _what_ we're looking at. Give up on it. */ - } else if (SDL_strcmp(str, "Battery\n") != 0) { - continue; /* we don't care about UPS and such. */ + continue; /* skip these, of course. */ + } else if (!read_power_file(base, name, "type", str, sizeof(str))) { + continue; /* Don't know _what_ we're looking at. Give up on it. */ + } else if (SDL_strcasecmp(str, "Battery\n") != 0) { + continue; /* we don't care about UPS and such. */ } /* if the scope is "device," it might be something like a PS4 controller reporting its own battery, and not something that powers the system. Most system batteries don't list a scope at all; we assume it's a system battery if not specified. */ - if (read_power_file(base, name, "scope", str, sizeof (str))) { - if (SDL_strcmp(str, "device\n") == 0) { - continue; /* skip external devices with their own batteries. */ + if (read_power_file(base, name, "scope", str, sizeof(str))) { + if (SDL_strcasecmp(str, "Device\n") == 0) { + continue; /* skip external devices with their own batteries. */ } } /* some drivers don't offer this, so if it's not explicitly reported assume it's present. */ - if (read_power_file(base, name, "present", str, sizeof (str)) && (SDL_strcmp(str, "0\n") == 0)) { + if (read_power_file(base, name, "present", str, sizeof(str)) && (SDL_strcmp(str, "0\n") == 0)) { st = SDL_POWERSTATE_NO_BATTERY; - } else if (!read_power_file(base, name, "status", str, sizeof (str))) { - st = SDL_POWERSTATE_UNKNOWN; /* uh oh */ - } else if (SDL_strcmp(str, "Charging\n") == 0) { + } else if (!read_power_file(base, name, "status", str, sizeof(str))) { + st = SDL_POWERSTATE_UNKNOWN; /* uh oh */ + } else if (SDL_strcasecmp(str, "Charging\n") == 0) { st = SDL_POWERSTATE_CHARGING; - } else if (SDL_strcmp(str, "Discharging\n") == 0) { + } else if (SDL_strcasecmp(str, "Discharging\n") == 0) { st = SDL_POWERSTATE_ON_BATTERY; - } else if ((SDL_strcmp(str, "Full\n") == 0) || (SDL_strcmp(str, "Not charging\n") == 0)) { + } else if ((SDL_strcasecmp(str, "Full\n") == 0) || (SDL_strcasecmp(str, "Not charging\n") == 0)) { st = SDL_POWERSTATE_CHARGED; } else { - st = SDL_POWERSTATE_UNKNOWN; /* uh oh */ + st = SDL_POWERSTATE_UNKNOWN; /* uh oh */ } - if (!read_power_file(base, name, "capacity", str, sizeof (str))) { + if (!read_power_file(base, name, "capacity", str, sizeof(str))) { pct = -1; } else { pct = SDL_atoi(str); pct = (pct > 100) ? 100 : pct; /* clamp between 0%, 100% */ } - if (read_power_file(base, name, "time_to_empty_now", str, sizeof (str))) { + if (read_power_file(base, name, "time_to_empty_now", str, sizeof(str))) { secs = SDL_atoi(str); - secs = (secs <= 0) ? -1 : secs; /* 0 == unknown */ + secs = (secs <= 0) ? -1 : secs; /* 0 == unknown */ } else if (st == SDL_POWERSTATE_ON_BATTERY) { /* energy is Watt*hours and power is Watts */ - energy = (read_power_file(base, name, "energy_now", str, sizeof (str))) ? SDL_atoi(str) : -1; - power = (read_power_file(base, name, "power_now", str, sizeof (str))) ? SDL_atoi(str) : -1; + energy = (read_power_file(base, name, "energy_now", str, sizeof(str))) ? SDL_atoi(str) : -1; + power = (read_power_file(base, name, "power_now", str, sizeof(str))) ? SDL_atoi(str) : -1; secs = (energy >= 0 && power > 0) ? (3600LL * energy) / power : -1; } else { secs = -1; @@ -512,7 +501,7 @@ SDL_GetPowerInfo_Linux_sys_class_power_supply(SDL_PowerState *state, int *second */ if ((secs < 0) && (*seconds < 0)) { if ((pct < 0) && (*percent < 0)) { - choose = SDL_TRUE; /* at least we know there's a battery. */ + choose = SDL_TRUE; /* at least we know there's a battery. */ } else if (pct > *percent) { choose = SDL_TRUE; } @@ -528,19 +517,17 @@ SDL_GetPowerInfo_Linux_sys_class_power_supply(SDL_PowerState *state, int *second } closedir(dirp); - return SDL_TRUE; /* don't look any further. */ + return SDL_TRUE; /* don't look any further. */ } - /* d-bus queries to org.freedesktop.UPower. */ -#if SDL_USE_LIBDBUS -#define UPOWER_DBUS_NODE "org.freedesktop.UPower" -#define UPOWER_DBUS_PATH "/org/freedesktop/UPower" -#define UPOWER_DBUS_INTERFACE "org.freedesktop.UPower" +#ifdef SDL_USE_LIBDBUS +#define UPOWER_DBUS_NODE "org.freedesktop.UPower" +#define UPOWER_DBUS_PATH "/org/freedesktop/UPower" +#define UPOWER_DBUS_INTERFACE "org.freedesktop.UPower" #define UPOWER_DEVICE_DBUS_INTERFACE "org.freedesktop.UPower.Device" -static void -check_upower_device(DBusConnection *conn, const char *path, SDL_PowerState *state, int *seconds, int *percent) +static void check_upower_device(DBusConnection *conn, const char *path, SDL_PowerState *state, int *seconds, int *percent) { SDL_bool choose = SDL_FALSE; SDL_PowerState st; @@ -551,41 +538,59 @@ check_upower_device(DBusConnection *conn, const char *path, SDL_PowerState *stat double d = 0.0; if (!SDL_DBus_QueryPropertyOnConnection(conn, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE, "Type", DBUS_TYPE_UINT32, &ui32)) { - return; /* Don't know _what_ we're looking at. Give up on it. */ - } else if (ui32 != 2) { /* 2==Battery*/ - return; /* we don't care about UPS and such. */ + return; /* Don't know _what_ we're looking at. Give up on it. */ + } else if (ui32 != 2) { /* 2==Battery*/ + return; /* we don't care about UPS and such. */ } else if (!SDL_DBus_QueryPropertyOnConnection(conn, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE, "PowerSupply", DBUS_TYPE_BOOLEAN, &ui32)) { return; } else if (!ui32) { - return; /* we don't care about random devices with batteries, like wireless controllers, etc */ - } else if (!SDL_DBus_QueryPropertyOnConnection(conn, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE, "IsPresent", DBUS_TYPE_BOOLEAN, &ui32)) { + return; /* we don't care about random devices with batteries, like wireless controllers, etc */ + } + + if (!SDL_DBus_QueryPropertyOnConnection(conn, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE, "IsPresent", DBUS_TYPE_BOOLEAN, &ui32)) { return; - } else if (!ui32) { + } + if (!ui32) { st = SDL_POWERSTATE_NO_BATTERY; - } else if (!SDL_DBus_QueryPropertyOnConnection(conn, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE, "State", DBUS_TYPE_UINT32, &ui32)) { - st = SDL_POWERSTATE_UNKNOWN; /* uh oh */ - } else if (ui32 == 1) { /* 1 == charging */ - st = SDL_POWERSTATE_CHARGING; - } else if ((ui32 == 2) || (ui32 == 3)) { /* 2 == discharging, 3 == empty. */ - st = SDL_POWERSTATE_ON_BATTERY; - } else if (ui32 == 4) { /* 4 == full */ - st = SDL_POWERSTATE_CHARGED; } else { - st = SDL_POWERSTATE_UNKNOWN; /* uh oh */ + /* Get updated information on the battery status + * This can occasionally fail, and we'll just return slightly stale data in that case + */ + SDL_DBus_CallMethodOnConnection(conn, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE, "Refresh", DBUS_TYPE_INVALID, DBUS_TYPE_INVALID); + + if (!SDL_DBus_QueryPropertyOnConnection(conn, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE, "State", DBUS_TYPE_UINT32, &ui32)) { + st = SDL_POWERSTATE_UNKNOWN; /* uh oh */ + } else if (ui32 == 1) { /* 1 == charging */ + st = SDL_POWERSTATE_CHARGING; + } else if ((ui32 == 2) || (ui32 == 3) || (ui32 == 6)) { + /* 2 == discharging; + * 3 == empty; + * 6 == "pending discharge" which GNOME interprets as equivalent + * to discharging */ + st = SDL_POWERSTATE_ON_BATTERY; + } else if ((ui32 == 4) || (ui32 == 5)) { + /* 4 == full; + * 5 == "pending charge" which GNOME shows as "Not charging", + * used when a battery is configured to stop charging at a + * lower than 100% threshold */ + st = SDL_POWERSTATE_CHARGED; + } else { + st = SDL_POWERSTATE_UNKNOWN; /* uh oh */ + } } if (!SDL_DBus_QueryPropertyOnConnection(conn, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE, "Percentage", DBUS_TYPE_DOUBLE, &d)) { - pct = -1; /* some old/cheap batteries don't set this property. */ + pct = -1; /* some old/cheap batteries don't set this property. */ } else { - pct = (int) d; + pct = (int)d; pct = (pct > 100) ? 100 : pct; /* clamp between 0%, 100% */ } if (!SDL_DBus_QueryPropertyOnConnection(conn, UPOWER_DBUS_NODE, path, UPOWER_DEVICE_DBUS_INTERFACE, "TimeToEmpty", DBUS_TYPE_INT64, &si64)) { secs = -1; } else { - secs = (int) si64; - secs = (secs <= 0) ? -1 : secs; /* 0 == unknown */ + secs = (int)si64; + secs = (secs <= 0) ? -1 : secs; /* 0 == unknown */ } /* @@ -594,7 +599,7 @@ check_upower_device(DBusConnection *conn, const char *path, SDL_PowerState *stat */ if ((secs < 0) && (*seconds < 0)) { if ((pct < 0) && (*percent < 0)) { - choose = SDL_TRUE; /* at least we know there's a battery. */ + choose = SDL_TRUE; /* at least we know there's a battery. */ } else if (pct > *percent) { choose = SDL_TRUE; } @@ -610,24 +615,23 @@ check_upower_device(DBusConnection *conn, const char *path, SDL_PowerState *stat } #endif -SDL_bool -SDL_GetPowerInfo_Linux_org_freedesktop_upower(SDL_PowerState *state, int *seconds, int *percent) +SDL_bool SDL_GetPowerInfo_Linux_org_freedesktop_upower(SDL_PowerState *state, int *seconds, int *percent) { SDL_bool retval = SDL_FALSE; -#if SDL_USE_LIBDBUS +#ifdef SDL_USE_LIBDBUS SDL_DBusContext *dbus = SDL_DBus_GetContext(); char **paths = NULL; int i, numpaths = 0; if (!dbus || !SDL_DBus_CallMethodOnConnection(dbus->system_conn, UPOWER_DBUS_NODE, UPOWER_DBUS_PATH, UPOWER_DBUS_INTERFACE, "EnumerateDevices", - DBUS_TYPE_INVALID, - DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &paths, &numpaths, DBUS_TYPE_INVALID)) { - return SDL_FALSE; /* try a different approach than UPower. */ + DBUS_TYPE_INVALID, + DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &paths, &numpaths, DBUS_TYPE_INVALID)) { + return SDL_FALSE; /* try a different approach than UPower. */ } - retval = SDL_TRUE; /* Clearly we can use this interface. */ - *state = SDL_POWERSTATE_NO_BATTERY; /* assume we're just plugged in. */ + retval = SDL_TRUE; /* Clearly we can use this interface. */ + *state = SDL_POWERSTATE_NO_BATTERY; /* assume we're just plugged in. */ *seconds = -1; *percent = -1; @@ -635,10 +639,8 @@ SDL_GetPowerInfo_Linux_org_freedesktop_upower(SDL_PowerState *state, int *second check_upower_device(dbus->system_conn, paths[i], state, seconds, percent); } - if (dbus) { - dbus->free_string_array(paths); - } -#endif /* SDL_USE_LIBDBUS */ + dbus->free_string_array(paths); +#endif /* SDL_USE_LIBDBUS */ return retval; } diff --git a/SDL2-2.0.12/src/power/macosx/SDL_syspower.c b/SDL2-2.30.5/src/power/macosx/SDL_syspower.c similarity index 81% rename from SDL2-2.0.12/src/power/macosx/SDL_syspower.c rename to SDL2-2.30.5/src/power/macosx/SDL_syspower.c index 86c48eb..a3881f3 100644 --- a/SDL2-2.0.12/src/power/macosx/SDL_syspower.c +++ b/SDL2-2.30.5/src/power/macosx/SDL_syspower.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -21,7 +21,7 @@ #include "../../SDL_internal.h" #ifndef SDL_POWER_DISABLED -#if SDL_POWER_MACOSX +#ifdef SDL_POWER_MACOSX #include #include @@ -30,16 +30,15 @@ #include "SDL_power.h" /* CoreFoundation is so verbose... */ -#define STRMATCH(a,b) (CFStringCompare(a, b, 0) == kCFCompareEqualTo) -#define GETVAL(k,v) \ - CFDictionaryGetValueIfPresent(dict, CFSTR(k), (const void **) v) +#define STRMATCH(a, b) (CFStringCompare(a, b, 0) == kCFCompareEqualTo) +#define GETVAL(k, v) \ + CFDictionaryGetValueIfPresent(dict, CFSTR(k), (const void **)v) /* Note that AC power sources also include a laptop battery it is charging. */ -static void -checkps(CFDictionaryRef dict, SDL_bool * have_ac, SDL_bool * have_battery, - SDL_bool * charging, int *seconds, int *percent) +static void checkps(CFDictionaryRef dict, SDL_bool *have_ac, SDL_bool *have_battery, + SDL_bool *charging, int *seconds, int *percent) { - CFStringRef strval; /* don't CFRelease() this. */ + CFStringRef strval; /* don't CFRelease() this. */ CFBooleanRef bval; CFNumberRef numval; SDL_bool charge = SDL_FALSE; @@ -50,7 +49,7 @@ checkps(CFDictionaryRef dict, SDL_bool * have_ac, SDL_bool * have_battery, int pct = -1; if ((GETVAL(kIOPSIsPresentKey, &bval)) && (bval == kCFBooleanFalse)) { - return; /* nothing to see here. */ + return; /* nothing to see here. */ } if (!GETVAL(kIOPSPowerSourceStateKey, &strval)) { @@ -60,7 +59,7 @@ checkps(CFDictionaryRef dict, SDL_bool * have_ac, SDL_bool * have_battery, if (STRMATCH(strval, CFSTR(kIOPSACPowerValue))) { is_ac = *have_ac = SDL_TRUE; } else if (!STRMATCH(strval, CFSTR(kIOPSBatteryPowerValue))) { - return; /* not a battery? */ + return; /* not a battery? */ } if ((GETVAL(kIOPSIsChargingKey, &bval)) && (bval == kCFBooleanTrue)) { @@ -72,7 +71,7 @@ checkps(CFDictionaryRef dict, SDL_bool * have_ac, SDL_bool * have_battery, CFNumberGetValue(numval, kCFNumberSInt32Type, &val); if (val > 0) { *have_battery = SDL_TRUE; - maxpct = (int) val; + maxpct = (int)val; } } @@ -81,7 +80,7 @@ checkps(CFDictionaryRef dict, SDL_bool * have_ac, SDL_bool * have_battery, CFNumberGetValue(numval, kCFNumberSInt32Type, &val); if (val > 0) { *have_battery = SDL_TRUE; - maxpct = (int) val; + maxpct = (int)val; } } @@ -91,23 +90,23 @@ checkps(CFDictionaryRef dict, SDL_bool * have_ac, SDL_bool * have_battery, /* Mac OS X reports 0 minutes until empty if you're plugged in. :( */ if ((val == 0) && (is_ac)) { - val = -1; /* !!! FIXME: calc from timeToFull and capacity? */ + val = -1; /* !!! FIXME: calc from timeToFull and capacity? */ } - secs = (int) val; + secs = (int)val; if (secs > 0) { - secs *= 60; /* value is in minutes, so convert to seconds. */ + secs *= 60; /* value is in minutes, so convert to seconds. */ } } if (GETVAL(kIOPSCurrentCapacityKey, &numval)) { SInt32 val = -1; CFNumberGetValue(numval, kCFNumberSInt32Type, &val); - pct = (int) val; + pct = (int)val; } if ((pct > 0) && (maxpct > 0)) { - pct = (int) ((((double) pct) / ((double) maxpct)) * 100.0); + pct = (int)((((double)pct) / ((double)maxpct)) * 100.0); } if (pct > 100) { @@ -120,7 +119,7 @@ checkps(CFDictionaryRef dict, SDL_bool * have_ac, SDL_bool * have_battery, */ if ((secs < 0) && (*seconds < 0)) { if ((pct < 0) && (*percent < 0)) { - choose = SDL_TRUE; /* at least we know there's a battery. */ + choose = SDL_TRUE; /* at least we know there's a battery. */ } if (pct > *percent) { choose = SDL_TRUE; @@ -139,9 +138,7 @@ checkps(CFDictionaryRef dict, SDL_bool * have_ac, SDL_bool * have_battery, #undef GETVAL #undef STRMATCH - -SDL_bool -SDL_GetPowerInfo_MacOSX(SDL_PowerState * state, int *seconds, int *percent) +SDL_bool SDL_GetPowerInfo_MacOSX(SDL_PowerState *state, int *seconds, int *percent) { CFTypeRef blob = IOPSCopyPowerSourcesInfo(); @@ -159,7 +156,7 @@ SDL_GetPowerInfo_MacOSX(SDL_PowerState * state, int *seconds, int *percent) const CFIndex total = CFArrayGetCount(list); CFIndex i; for (i = 0; i < total; i++) { - CFTypeRef ps = (CFTypeRef) CFArrayGetValueAtIndex(list, i); + CFTypeRef ps = (CFTypeRef)CFArrayGetValueAtIndex(list, i); CFDictionaryRef dict = IOPSGetPowerSourceDescription(blob, ps); if (dict != NULL) { diff --git a/SDL2-2.30.5/src/power/n3ds/SDL_syspower.c b/SDL2-2.30.5/src/power/n3ds/SDL_syspower.c new file mode 100644 index 0000000..9b5555e --- /dev/null +++ b/SDL2-2.30.5/src/power/n3ds/SDL_syspower.c @@ -0,0 +1,108 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#if !defined(SDL_POWER_DISABLED) && defined(SDL_POWER_N3DS) + +#include <3ds.h> + +#include "SDL_error.h" +#include "SDL_power.h" + +SDL_FORCE_INLINE SDL_PowerState GetPowerState(void); +SDL_FORCE_INLINE int ReadStateFromPTMU(bool *is_plugged, u8 *is_charging); +SDL_FORCE_INLINE int GetBatteryPercentage(void); + +#define BATTERY_PERCENT_REG 0xB +#define BATTERY_PERCENT_REG_SIZE 2 + +SDL_bool SDL_GetPowerInfo_N3DS(SDL_PowerState *state, int *seconds, int *percent) +{ + *state = GetPowerState(); + *percent = GetBatteryPercentage(); + *seconds = -1; /* libctru doesn't provide a way to estimate battery life */ + + return SDL_TRUE; +} + +static SDL_PowerState GetPowerState(void) +{ + bool is_plugged; + u8 is_charging; + + if (ReadStateFromPTMU(&is_plugged, &is_charging) < 0) { + return SDL_POWERSTATE_UNKNOWN; + } + + if (is_charging) { + return SDL_POWERSTATE_CHARGING; + } + + if (is_plugged) { + return SDL_POWERSTATE_CHARGED; + } + + return SDL_POWERSTATE_ON_BATTERY; +} + +static int ReadStateFromPTMU(bool *is_plugged, u8 *is_charging) +{ + if (R_FAILED(ptmuInit())) { + return SDL_SetError("Failed to initialise PTMU service"); + } + + if (R_FAILED(PTMU_GetAdapterState(is_plugged))) { + ptmuExit(); + return SDL_SetError("Failed to read adapter state"); + } + + if (R_FAILED(PTMU_GetBatteryChargeState(is_charging))) { + ptmuExit(); + return SDL_SetError("Failed to read battery charge state"); + } + + ptmuExit(); + return 0; +} + +SDL_FORCE_INLINE int +GetBatteryPercentage(void) +{ + u8 data[BATTERY_PERCENT_REG_SIZE]; + + if (R_FAILED(mcuHwcInit())) { + return SDL_SetError("Failed to initialise mcuHwc service"); + } + + if (R_FAILED(MCUHWC_ReadRegister(BATTERY_PERCENT_REG, data, BATTERY_PERCENT_REG_SIZE))) { + mcuHwcExit(); + return SDL_SetError("Failed to read battery register"); + } + + mcuHwcExit(); + + return (int)SDL_round(data[0] + data[1] / 256.0); +} + +#endif /* !SDL_POWER_DISABLED && SDL_POWER_N3DS */ + +/* vi: set sts=4 ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/power/psp/SDL_syspower.c b/SDL2-2.30.5/src/power/psp/SDL_syspower.c similarity index 80% rename from SDL2-2.0.12/src/power/psp/SDL_syspower.c rename to SDL2-2.30.5/src/power/psp/SDL_syspower.c index 6a073ed..4b9d145 100644 --- a/SDL2-2.0.12/src/power/psp/SDL_syspower.c +++ b/SDL2-2.30.5/src/power/psp/SDL_syspower.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -22,15 +22,12 @@ #include "../../SDL_internal.h" #ifndef SDL_POWER_DISABLED -#if SDL_POWER_PSP +#ifdef SDL_POWER_PSP #include "SDL_power.h" #include - -SDL_bool -SDL_GetPowerInfo_PSP(SDL_PowerState * state, int *seconds, - int *percent) +SDL_bool SDL_GetPowerInfo_PSP(SDL_PowerState *state, int *seconds, int *percent) { int battery = scePowerIsBatteryExist(); int plugged = scePowerIsPowerOnline(); @@ -47,19 +44,18 @@ SDL_GetPowerInfo_PSP(SDL_PowerState * state, int *seconds, } else if (charging) { *state = SDL_POWERSTATE_CHARGING; *percent = scePowerGetBatteryLifePercent(); - *seconds = scePowerGetBatteryLifeTime()*60; + *seconds = scePowerGetBatteryLifeTime() * 60; } else if (plugged) { *state = SDL_POWERSTATE_CHARGED; *percent = scePowerGetBatteryLifePercent(); - *seconds = scePowerGetBatteryLifeTime()*60; + *seconds = scePowerGetBatteryLifeTime() * 60; } else { *state = SDL_POWERSTATE_ON_BATTERY; *percent = scePowerGetBatteryLifePercent(); - *seconds = scePowerGetBatteryLifeTime()*60; + *seconds = scePowerGetBatteryLifeTime() * 60; } - - return SDL_TRUE; /* always the definitive answer on PSP. */ + return SDL_TRUE; /* always the definitive answer on PSP. */ } #endif /* SDL_POWER_PSP */ diff --git a/SDL2-2.0.12/src/power/uikit/SDL_syspower.h b/SDL2-2.30.5/src/power/uikit/SDL_syspower.h similarity index 86% rename from SDL2-2.0.12/src/power/uikit/SDL_syspower.h rename to SDL2-2.30.5/src/power/uikit/SDL_syspower.h index 451f452..9d5c6a8 100644 --- a/SDL2-2.0.12/src/power/uikit/SDL_syspower.h +++ b/SDL2-2.30.5/src/power/uikit/SDL_syspower.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,12 +20,12 @@ */ #include "../../SDL_internal.h" -#if SDL_POWER_UIKIT +#ifdef SDL_POWER_UIKIT #include "SDL_power.h" void SDL_UIKit_UpdateBatteryMonitoring(void); -SDL_bool SDL_GetPowerInfo_UIKit(SDL_PowerState * state, int *seconds, int *percent); +SDL_bool SDL_GetPowerInfo_UIKit(SDL_PowerState *state, int *seconds, int *percent); #endif /* SDL_POWER_UIKIT */ diff --git a/SDL2-2.0.12/src/power/uikit/SDL_syspower.m b/SDL2-2.30.5/src/power/uikit/SDL_syspower.m similarity index 87% rename from SDL2-2.0.12/src/power/uikit/SDL_syspower.m rename to SDL2-2.30.5/src/power/uikit/SDL_syspower.m index b77d99c..d366d65 100644 --- a/SDL2-2.0.12/src/power/uikit/SDL_syspower.m +++ b/SDL2-2.30.5/src/power/uikit/SDL_syspower.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -21,13 +21,12 @@ #include "../../SDL_internal.h" #ifndef SDL_POWER_DISABLED -#if SDL_POWER_UIKIT +#ifdef SDL_POWER_UIKIT #import #include "SDL_power.h" #include "SDL_timer.h" -#include "SDL_assert.h" #include "SDL_syspower.h" #if !TARGET_OS_TV @@ -35,8 +34,7 @@ static const int BATTERY_MONITORING_TIMEOUT = 3000; static Uint32 SDL_UIKitLastPowerInfoQuery = 0; -void -SDL_UIKit_UpdateBatteryMonitoring(void) +void SDL_UIKit_UpdateBatteryMonitoring(void) { if (SDL_UIKitLastPowerInfoQuery) { if (SDL_TICKS_PASSED(SDL_GetTicks(), SDL_UIKitLastPowerInfoQuery + BATTERY_MONITORING_TIMEOUT)) { @@ -48,21 +46,19 @@ SDL_UIKit_UpdateBatteryMonitoring(void) } } #else -void -SDL_UIKit_UpdateBatteryMonitoring(void) +void SDL_UIKit_UpdateBatteryMonitoring(void) { /* Do nothing. */ } #endif /* !TARGET_OS_TV */ -SDL_bool -SDL_GetPowerInfo_UIKit(SDL_PowerState * state, int *seconds, int *percent) +SDL_bool SDL_GetPowerInfo_UIKit(SDL_PowerState *state, int *seconds, int *percent) { #if TARGET_OS_TV *state = SDL_POWERSTATE_NO_BATTERY; *seconds = -1; *percent = -1; -#else /* TARGET_OS_TV */ +#else /* TARGET_OS_TV */ @autoreleasepool { UIDevice *uidev = [UIDevice currentDevice]; @@ -78,7 +74,7 @@ SDL_GetPowerInfo_UIKit(SDL_PowerState * state, int *seconds, int *percent) */ SDL_UIKitLastPowerInfoQuery = SDL_GetTicks(); - *seconds = -1; /* no API to estimate this in UIKit. */ + *seconds = -1; /* no API to estimate this in UIKit. */ switch (uidev.batteryState) { case UIDeviceBatteryStateCharging: @@ -100,7 +96,7 @@ SDL_GetPowerInfo_UIKit(SDL_PowerState * state, int *seconds, int *percent) } const float level = uidev.batteryLevel; - *percent = ( (level < 0.0f) ? -1 : ((int) ((level * 100) + 0.5f)) ); + *percent = ((level < 0.0f) ? -1 : ((int)((level * 100) + 0.5f))); } #endif /* TARGET_OS_TV */ diff --git a/SDL2-2.30.5/src/power/vita/SDL_syspower.c b/SDL2-2.30.5/src/power/vita/SDL_syspower.c new file mode 100644 index 0000000..644b72a --- /dev/null +++ b/SDL2-2.30.5/src/power/vita/SDL_syspower.c @@ -0,0 +1,64 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifndef SDL_POWER_DISABLED +#ifdef SDL_POWER_VITA + +#include "SDL_power.h" +#include + +SDL_bool SDL_GetPowerInfo_VITA(SDL_PowerState *state, int *seconds, int *percent) +{ + int battery = 1; + int plugged = scePowerIsPowerOnline(); + int charging = scePowerIsBatteryCharging(); + + *state = SDL_POWERSTATE_UNKNOWN; + *seconds = -1; + *percent = -1; + + if (!battery) { + *state = SDL_POWERSTATE_NO_BATTERY; + *seconds = -1; + *percent = -1; + } else if (charging) { + *state = SDL_POWERSTATE_CHARGING; + *percent = scePowerGetBatteryLifePercent(); + *seconds = scePowerGetBatteryLifeTime() * 60; + } else if (plugged) { + *state = SDL_POWERSTATE_CHARGED; + *percent = scePowerGetBatteryLifePercent(); + *seconds = scePowerGetBatteryLifeTime() * 60; + } else { + *state = SDL_POWERSTATE_ON_BATTERY; + *percent = scePowerGetBatteryLifePercent(); + *seconds = scePowerGetBatteryLifeTime() * 60; + } + + return SDL_TRUE; /* always the definitive answer on VITA. */ +} + +#endif /* SDL_POWER_VITA */ +#endif /* SDL_POWER_DISABLED */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/power/windows/SDL_syspower.c b/SDL2-2.30.5/src/power/windows/SDL_syspower.c similarity index 73% rename from SDL2-2.0.12/src/power/windows/SDL_syspower.c rename to SDL2-2.30.5/src/power/windows/SDL_syspower.c index 9108fe4..58fa9a8 100644 --- a/SDL2-2.0.12/src/power/windows/SDL_syspower.c +++ b/SDL2-2.30.5/src/power/windows/SDL_syspower.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -21,24 +21,22 @@ #include "../../SDL_internal.h" #ifndef SDL_POWER_DISABLED -#if SDL_POWER_WINDOWS +#ifdef SDL_POWER_WINDOWS #include "../../core/windows/SDL_windows.h" #include "SDL_power.h" -SDL_bool -SDL_GetPowerInfo_Windows(SDL_PowerState * state, int *seconds, int *percent) +SDL_bool SDL_GetPowerInfo_Windows(SDL_PowerState *state, int *seconds, int *percent) { SYSTEM_POWER_STATUS status; SDL_bool need_details = SDL_FALSE; /* This API should exist back to Win95. */ - if (!GetSystemPowerStatus(&status)) - { + if (!GetSystemPowerStatus(&status)) { /* !!! FIXME: push GetLastError() into SDL_GetError() */ *state = SDL_POWERSTATE_UNKNOWN; - } else if (status.BatteryFlag == 0xFF) { /* unknown state */ + } else if (status.BatteryFlag == 0xFF) { /* unknown state */ *state = SDL_POWERSTATE_UNKNOWN; } else if (status.BatteryFlag & (1 << 7)) { /* no battery */ *state = SDL_POWERSTATE_NO_BATTERY; @@ -46,28 +44,28 @@ SDL_GetPowerInfo_Windows(SDL_PowerState * state, int *seconds, int *percent) *state = SDL_POWERSTATE_CHARGING; need_details = SDL_TRUE; } else if (status.ACLineStatus == 1) { - *state = SDL_POWERSTATE_CHARGED; /* on AC, not charging. */ + *state = SDL_POWERSTATE_CHARGED; /* on AC, not charging. */ need_details = SDL_TRUE; } else { - *state = SDL_POWERSTATE_ON_BATTERY; /* not on AC. */ + *state = SDL_POWERSTATE_ON_BATTERY; /* not on AC. */ need_details = SDL_TRUE; } *percent = -1; *seconds = -1; if (need_details) { - const int pct = (int) status.BatteryLifePercent; - const int secs = (int) status.BatteryLifeTime; + const int pct = (int)status.BatteryLifePercent; + const int secs = (int)status.BatteryLifeTime; - if (pct != 255) { /* 255 == unknown */ + if (pct != 255) { /* 255 == unknown */ *percent = (pct > 100) ? 100 : pct; /* clamp between 0%, 100% */ } - if (secs != 0xFFFFFFFF) { /* ((DWORD)-1) == unknown */ + if (secs != 0xFFFFFFFF) { /* ((DWORD)-1) == unknown */ *seconds = secs; } } - return SDL_TRUE; /* always the definitive answer on Windows. */ + return SDL_TRUE; /* always the definitive answer on Windows. */ } #endif /* SDL_POWER_WINDOWS */ diff --git a/SDL2-2.0.12/src/power/winrt/SDL_syspower.cpp b/SDL2-2.30.5/src/power/winrt/SDL_syspower.cpp similarity index 91% rename from SDL2-2.0.12/src/power/winrt/SDL_syspower.cpp rename to SDL2-2.30.5/src/power/winrt/SDL_syspower.cpp index 227fd2f..1fc971f 100644 --- a/SDL2-2.0.12/src/power/winrt/SDL_syspower.cpp +++ b/SDL2-2.30.5/src/power/winrt/SDL_syspower.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,8 +26,7 @@ #include "SDL_power.h" extern "C" -SDL_bool -SDL_GetPowerInfo_WinRT(SDL_PowerState * state, int *seconds, int *percent) +SDL_bool SDL_GetPowerInfo_WinRT(SDL_PowerState * state, int *seconds, int *percent) { /* TODO, WinRT: Battery info is available on at least one WinRT platform (Windows Phone 8). Implement SDL_GetPowerInfo_WinRT as appropriate. */ /* Notes: diff --git a/SDL2-2.0.12/src/render/SDL_d3dmath.c b/SDL2-2.30.5/src/render/SDL_d3dmath.c similarity index 94% rename from SDL2-2.0.12/src/render/SDL_d3dmath.c rename to SDL2-2.30.5/src/render/SDL_d3dmath.c index 5acc10d..021b8c2 100644 --- a/SDL2-2.0.12/src/render/SDL_d3dmath.c +++ b/SDL2-2.30.5/src/render/SDL_d3dmath.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../SDL_internal.h" -#if (SDL_VIDEO_RENDER_D3D || SDL_VIDEO_RENDER_D3D11) && !SDL_RENDER_DISABLED +#if (SDL_VIDEO_RENDER_D3D || SDL_VIDEO_RENDER_D3D11 || SDL_VIDEO_RENDER_D3D12) #include "SDL_stdinc.h" #include "SDL_d3dmath.h" @@ -128,9 +128,8 @@ Float4X4 MatrixRotationZ(float r) m.v._33 = 1.0f; m.v._44 = 1.0f; return m; - } -#endif /* (SDL_VIDEO_RENDER_D3D || SDL_VIDEO_RENDER_D3D11) && !SDL_RENDER_DISABLED */ +#endif /* (SDL_VIDEO_RENDER_D3D || SDL_VIDEO_RENDER_D3D11 || SDL_VIDEO_RENDER_D3D12) */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/render/SDL_d3dmath.h b/SDL2-2.30.5/src/render/SDL_d3dmath.h similarity index 79% rename from SDL2-2.0.12/src/render/SDL_d3dmath.h rename to SDL2-2.30.5/src/render/SDL_d3dmath.h index 5bd3dc6..9ef2f53 100644 --- a/SDL2-2.0.12/src/render/SDL_d3dmath.h +++ b/SDL2-2.30.5/src/render/SDL_d3dmath.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,12 @@ */ #include "../SDL_internal.h" -#if (SDL_VIDEO_RENDER_D3D || SDL_VIDEO_RENDER_D3D11) && !SDL_RENDER_DISABLED +#if (SDL_VIDEO_RENDER_D3D || SDL_VIDEO_RENDER_D3D11 || SDL_VIDEO_RENDER_D3D12) + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif /* Direct3D matrix math functions */ @@ -47,8 +52,10 @@ typedef struct typedef struct { - union { - struct { + union + { + struct + { float _11, _12, _13, _14; float _21, _22, _23, _24; float _31, _32, _33, _34; @@ -58,7 +65,6 @@ typedef struct }; } Float4X4; - Float4X4 MatrixIdentity(); Float4X4 MatrixMultiply(Float4X4 M1, Float4X4 M2); Float4X4 MatrixScaling(float x, float y, float z); @@ -67,6 +73,11 @@ Float4X4 MatrixRotationX(float r); Float4X4 MatrixRotationY(float r); Float4X4 MatrixRotationZ(float r); -#endif /* (SDL_VIDEO_RENDER_D3D || SDL_VIDEO_RENDER_D3D11) && !SDL_RENDER_DISABLED */ +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif + +#endif /* (SDL_VIDEO_RENDER_D3D || SDL_VIDEO_RENDER_D3D11 || SDL_VIDEO_RENDER_D3D12) */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/render/SDL_render.c b/SDL2-2.30.5/src/render/SDL_render.c new file mode 100644 index 0000000..f7fcc52 --- /dev/null +++ b/SDL2-2.30.5/src/render/SDL_render.c @@ -0,0 +1,4535 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +/* The SDL 2D rendering system */ + +#include "SDL_hints.h" +#include "SDL_render.h" +#include "SDL_timer.h" +#include "SDL_sysrender.h" +#include "software/SDL_render_sw_c.h" +#include "../video/SDL_pixels_c.h" + +#if defined(__ANDROID__) +#include "../core/android/SDL_android.h" +#endif + +/* as a courtesy to iOS apps, we don't try to draw when in the background, as +that will crash the app. However, these apps _should_ have used +SDL_AddEventWatch to catch SDL_APP_WILLENTERBACKGROUND events and stopped +drawing themselves. Other platforms still draw, as the compositor can use it, +and more importantly: drawing to render targets isn't lost. But I still think +this should probably be removed at some point in the future. --ryan. */ +#if defined(__IPHONEOS__) || defined(__TVOS__) || defined(__ANDROID__) +#define DONT_DRAW_WHILE_HIDDEN 1 +#else +#define DONT_DRAW_WHILE_HIDDEN 0 +#endif + +#define SDL_WINDOWRENDERDATA "_SDL_WindowRenderData" + +#define CHECK_RENDERER_MAGIC(renderer, retval) \ + if (!renderer || renderer->magic != &renderer_magic) { \ + SDL_InvalidParamError("renderer"); \ + return retval; \ + } + +#define CHECK_TEXTURE_MAGIC(texture, retval) \ + if (!texture || texture->magic != &texture_magic) { \ + SDL_InvalidParamError("texture"); \ + return retval; \ + } + +/* Predefined blend modes */ +#define SDL_COMPOSE_BLENDMODE(srcColorFactor, dstColorFactor, colorOperation, \ + srcAlphaFactor, dstAlphaFactor, alphaOperation) \ + (SDL_BlendMode)(((Uint32)colorOperation << 0) | \ + ((Uint32)srcColorFactor << 4) | \ + ((Uint32)dstColorFactor << 8) | \ + ((Uint32)alphaOperation << 16) | \ + ((Uint32)srcAlphaFactor << 20) | \ + ((Uint32)dstAlphaFactor << 24)) + +#define SDL_BLENDMODE_NONE_FULL \ + SDL_COMPOSE_BLENDMODE(SDL_BLENDFACTOR_ONE, SDL_BLENDFACTOR_ZERO, SDL_BLENDOPERATION_ADD, \ + SDL_BLENDFACTOR_ONE, SDL_BLENDFACTOR_ZERO, SDL_BLENDOPERATION_ADD) + +#define SDL_BLENDMODE_BLEND_FULL \ + SDL_COMPOSE_BLENDMODE(SDL_BLENDFACTOR_SRC_ALPHA, SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA, SDL_BLENDOPERATION_ADD, \ + SDL_BLENDFACTOR_ONE, SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA, SDL_BLENDOPERATION_ADD) + +#define SDL_BLENDMODE_ADD_FULL \ + SDL_COMPOSE_BLENDMODE(SDL_BLENDFACTOR_SRC_ALPHA, SDL_BLENDFACTOR_ONE, SDL_BLENDOPERATION_ADD, \ + SDL_BLENDFACTOR_ZERO, SDL_BLENDFACTOR_ONE, SDL_BLENDOPERATION_ADD) + +#define SDL_BLENDMODE_MOD_FULL \ + SDL_COMPOSE_BLENDMODE(SDL_BLENDFACTOR_ZERO, SDL_BLENDFACTOR_SRC_COLOR, SDL_BLENDOPERATION_ADD, \ + SDL_BLENDFACTOR_ZERO, SDL_BLENDFACTOR_ONE, SDL_BLENDOPERATION_ADD) + +#define SDL_BLENDMODE_MUL_FULL \ + SDL_COMPOSE_BLENDMODE(SDL_BLENDFACTOR_DST_COLOR, SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA, SDL_BLENDOPERATION_ADD, \ + SDL_BLENDFACTOR_ZERO, SDL_BLENDFACTOR_ONE, SDL_BLENDOPERATION_ADD) + +#ifndef SDL_RENDER_DISABLED +static const SDL_RenderDriver *render_drivers[] = { +#if SDL_VIDEO_RENDER_D3D + &D3D_RenderDriver, +#endif +#if SDL_VIDEO_RENDER_D3D11 + &D3D11_RenderDriver, +#endif +#if SDL_VIDEO_RENDER_D3D12 + &D3D12_RenderDriver, +#endif +#if SDL_VIDEO_RENDER_METAL + &METAL_RenderDriver, +#endif +#if SDL_VIDEO_RENDER_OGL + &GL_RenderDriver, +#endif +#if SDL_VIDEO_RENDER_OGL_ES2 + &GLES2_RenderDriver, +#endif +#if SDL_VIDEO_RENDER_OGL_ES + &GLES_RenderDriver, +#endif +#if SDL_VIDEO_RENDER_DIRECTFB + &DirectFB_RenderDriver, +#endif +#if SDL_VIDEO_RENDER_PS2 + &PS2_RenderDriver, +#endif +#if SDL_VIDEO_RENDER_PSP + &PSP_RenderDriver, +#endif +#if SDL_VIDEO_RENDER_VITA_GXM + &VITA_GXM_RenderDriver, +#endif +#if SDL_VIDEO_RENDER_SW + &SW_RenderDriver +#endif +}; +#endif /* !SDL_RENDER_DISABLED */ + +static char renderer_magic; +static char texture_magic; + +static SDL_INLINE void DebugLogRenderCommands(const SDL_RenderCommand *cmd) +{ +#if 0 + unsigned int i = 1; + SDL_Log("Render commands to flush:"); + while (cmd) { + switch (cmd->command) { + case SDL_RENDERCMD_NO_OP: + SDL_Log(" %u. no-op", i++); + break; + + case SDL_RENDERCMD_SETVIEWPORT: + SDL_Log(" %u. set viewport (first=%u, rect={(%d, %d), %dx%d})", i++, + (unsigned int) cmd->data.viewport.first, + cmd->data.viewport.rect.x, cmd->data.viewport.rect.y, + cmd->data.viewport.rect.w, cmd->data.viewport.rect.h); + break; + + case SDL_RENDERCMD_SETCLIPRECT: + SDL_Log(" %u. set cliprect (enabled=%s, rect={(%d, %d), %dx%d})", i++, + cmd->data.cliprect.enabled ? "true" : "false", + cmd->data.cliprect.rect.x, cmd->data.cliprect.rect.y, + cmd->data.cliprect.rect.w, cmd->data.cliprect.rect.h); + break; + + case SDL_RENDERCMD_SETDRAWCOLOR: + SDL_Log(" %u. set draw color (first=%u, r=%d, g=%d, b=%d, a=%d)", i++, + (unsigned int) cmd->data.color.first, + (int) cmd->data.color.r, (int) cmd->data.color.g, + (int) cmd->data.color.b, (int) cmd->data.color.a); + break; + + case SDL_RENDERCMD_CLEAR: + SDL_Log(" %u. clear (first=%u, r=%d, g=%d, b=%d, a=%d)", i++, + (unsigned int) cmd->data.color.first, + (int) cmd->data.color.r, (int) cmd->data.color.g, + (int) cmd->data.color.b, (int) cmd->data.color.a); + break; + + case SDL_RENDERCMD_DRAW_POINTS: + SDL_Log(" %u. draw points (first=%u, count=%u, r=%d, g=%d, b=%d, a=%d, blend=%d)", i++, + (unsigned int) cmd->data.draw.first, + (unsigned int) cmd->data.draw.count, + (int) cmd->data.draw.r, (int) cmd->data.draw.g, + (int) cmd->data.draw.b, (int) cmd->data.draw.a, + (int) cmd->data.draw.blend); + break; + + case SDL_RENDERCMD_DRAW_LINES: + SDL_Log(" %u. draw lines (first=%u, count=%u, r=%d, g=%d, b=%d, a=%d, blend=%d)", i++, + (unsigned int) cmd->data.draw.first, + (unsigned int) cmd->data.draw.count, + (int) cmd->data.draw.r, (int) cmd->data.draw.g, + (int) cmd->data.draw.b, (int) cmd->data.draw.a, + (int) cmd->data.draw.blend); + break; + + case SDL_RENDERCMD_FILL_RECTS: + SDL_Log(" %u. fill rects (first=%u, count=%u, r=%d, g=%d, b=%d, a=%d, blend=%d)", i++, + (unsigned int) cmd->data.draw.first, + (unsigned int) cmd->data.draw.count, + (int) cmd->data.draw.r, (int) cmd->data.draw.g, + (int) cmd->data.draw.b, (int) cmd->data.draw.a, + (int) cmd->data.draw.blend); + break; + + case SDL_RENDERCMD_COPY: + SDL_Log(" %u. copy (first=%u, count=%u, r=%d, g=%d, b=%d, a=%d, blend=%d, tex=%p)", i++, + (unsigned int) cmd->data.draw.first, + (unsigned int) cmd->data.draw.count, + (int) cmd->data.draw.r, (int) cmd->data.draw.g, + (int) cmd->data.draw.b, (int) cmd->data.draw.a, + (int) cmd->data.draw.blend, cmd->data.draw.texture); + break; + + + case SDL_RENDERCMD_COPY_EX: + SDL_Log(" %u. copyex (first=%u, count=%u, r=%d, g=%d, b=%d, a=%d, blend=%d, tex=%p)", i++, + (unsigned int) cmd->data.draw.first, + (unsigned int) cmd->data.draw.count, + (int) cmd->data.draw.r, (int) cmd->data.draw.g, + (int) cmd->data.draw.b, (int) cmd->data.draw.a, + (int) cmd->data.draw.blend, cmd->data.draw.texture); + break; + + case SDL_RENDERCMD_GEOMETRY: + SDL_Log(" %u. geometry (first=%u, count=%u, r=%d, g=%d, b=%d, a=%d, blend=%d, tex=%p)", i++, + (unsigned int) cmd->data.draw.first, + (unsigned int) cmd->data.draw.count, + (int) cmd->data.draw.r, (int) cmd->data.draw.g, + (int) cmd->data.draw.b, (int) cmd->data.draw.a, + (int) cmd->data.draw.blend, cmd->data.draw.texture); + break; + + } + cmd = cmd->next; + } +#endif +} + +static int FlushRenderCommands(SDL_Renderer *renderer) +{ + int retval; + + SDL_assert((renderer->render_commands == NULL) == (renderer->render_commands_tail == NULL)); + + if (!renderer->render_commands) { /* nothing to do! */ + SDL_assert(renderer->vertex_data_used == 0); + return 0; + } + + DebugLogRenderCommands(renderer->render_commands); + + retval = renderer->RunCommandQueue(renderer, renderer->render_commands, renderer->vertex_data, renderer->vertex_data_used); + + /* Move the whole render command queue to the unused pool so we can reuse them next time. */ + if (renderer->render_commands_tail) { + renderer->render_commands_tail->next = renderer->render_commands_pool; + renderer->render_commands_pool = renderer->render_commands; + renderer->render_commands_tail = NULL; + renderer->render_commands = NULL; + } + renderer->vertex_data_used = 0; + renderer->render_command_generation++; + renderer->color_queued = SDL_FALSE; + renderer->viewport_queued = SDL_FALSE; + renderer->cliprect_queued = SDL_FALSE; + return retval; +} + +static int FlushRenderCommandsIfTextureNeeded(SDL_Texture *texture) +{ + SDL_Renderer *renderer = texture->renderer; + if (texture->last_command_generation == renderer->render_command_generation) { + /* the current command queue depends on this texture, flush the queue now before it changes */ + return FlushRenderCommands(renderer); + } + return 0; +} + +static SDL_INLINE int FlushRenderCommandsIfNotBatching(SDL_Renderer *renderer) +{ + return renderer->batching ? 0 : FlushRenderCommands(renderer); +} + +int SDL_RenderFlush(SDL_Renderer *renderer) +{ + return FlushRenderCommands(renderer); +} + +void *SDL_AllocateRenderVertices(SDL_Renderer *renderer, const size_t numbytes, const size_t alignment, size_t *offset) +{ + const size_t needed = renderer->vertex_data_used + numbytes + alignment; + const size_t current_offset = renderer->vertex_data_used; + + const size_t aligner = (alignment && ((current_offset & (alignment - 1)) != 0)) ? (alignment - (current_offset & (alignment - 1))) : 0; + const size_t aligned = current_offset + aligner; + + if (renderer->vertex_data_allocation < needed) { + const size_t current_allocation = renderer->vertex_data ? renderer->vertex_data_allocation : 1024; + size_t newsize = current_allocation * 2; + void *ptr; + while (newsize < needed) { + newsize *= 2; + } + + ptr = SDL_realloc(renderer->vertex_data, newsize); + + if (!ptr) { + SDL_OutOfMemory(); + return NULL; + } + renderer->vertex_data = ptr; + renderer->vertex_data_allocation = newsize; + } + + if (offset) { + *offset = aligned; + } + + renderer->vertex_data_used += aligner + numbytes; + + return ((Uint8 *)renderer->vertex_data) + aligned; +} + +static SDL_RenderCommand *AllocateRenderCommand(SDL_Renderer *renderer) +{ + SDL_RenderCommand *retval = NULL; + + /* !!! FIXME: are there threading limitations in SDL's render API? If not, we need to mutex this. */ + retval = renderer->render_commands_pool; + if (retval) { + renderer->render_commands_pool = retval->next; + retval->next = NULL; + } else { + retval = SDL_calloc(1, sizeof(*retval)); + if (!retval) { + SDL_OutOfMemory(); + return NULL; + } + } + + SDL_assert((renderer->render_commands == NULL) == (renderer->render_commands_tail == NULL)); + if (renderer->render_commands_tail) { + renderer->render_commands_tail->next = retval; + } else { + renderer->render_commands = retval; + } + renderer->render_commands_tail = retval; + + return retval; +} + +static int QueueCmdSetViewport(SDL_Renderer *renderer) +{ + int retval = 0; + if (!renderer->viewport_queued || (SDL_memcmp(&renderer->viewport, &renderer->last_queued_viewport, sizeof(SDL_DRect)) != 0)) { + SDL_RenderCommand *cmd = AllocateRenderCommand(renderer); + retval = -1; + if (cmd) { + cmd->command = SDL_RENDERCMD_SETVIEWPORT; + cmd->data.viewport.first = 0; /* render backend will fill this in. */ + /* Convert SDL_DRect to SDL_Rect */ + cmd->data.viewport.rect.x = (int)SDL_floor(renderer->viewport.x); + cmd->data.viewport.rect.y = (int)SDL_floor(renderer->viewport.y); + cmd->data.viewport.rect.w = (int)SDL_floor(renderer->viewport.w); + cmd->data.viewport.rect.h = (int)SDL_floor(renderer->viewport.h); + retval = renderer->QueueSetViewport(renderer, cmd); + if (retval < 0) { + cmd->command = SDL_RENDERCMD_NO_OP; + } else { + SDL_copyp(&renderer->last_queued_viewport, &renderer->viewport); + renderer->viewport_queued = SDL_TRUE; + } + } + } + return retval; +} + +static int QueueCmdSetClipRect(SDL_Renderer *renderer) +{ + int retval = 0; + if ((!renderer->cliprect_queued) || + (renderer->clipping_enabled != renderer->last_queued_cliprect_enabled) || + (SDL_memcmp(&renderer->clip_rect, &renderer->last_queued_cliprect, sizeof(SDL_DRect)) != 0)) { + SDL_RenderCommand *cmd = AllocateRenderCommand(renderer); + if (!cmd) { + retval = -1; + } else { + cmd->command = SDL_RENDERCMD_SETCLIPRECT; + cmd->data.cliprect.enabled = renderer->clipping_enabled; + /* Convert SDL_DRect to SDL_Rect */ + cmd->data.cliprect.rect.x = (int)SDL_floor(renderer->clip_rect.x); + cmd->data.cliprect.rect.y = (int)SDL_floor(renderer->clip_rect.y); + cmd->data.cliprect.rect.w = (int)SDL_floor(renderer->clip_rect.w); + cmd->data.cliprect.rect.h = (int)SDL_floor(renderer->clip_rect.h); + SDL_copyp(&renderer->last_queued_cliprect, &renderer->clip_rect); + renderer->last_queued_cliprect_enabled = renderer->clipping_enabled; + renderer->cliprect_queued = SDL_TRUE; + } + } + return retval; +} + +static int QueueCmdSetDrawColor(SDL_Renderer *renderer, SDL_Color *col) +{ + const Uint32 color = (((Uint32)col->a << 24) | (col->r << 16) | (col->g << 8) | col->b); + int retval = 0; + + if (!renderer->color_queued || (color != renderer->last_queued_color)) { + SDL_RenderCommand *cmd = AllocateRenderCommand(renderer); + retval = -1; + + if (cmd) { + cmd->command = SDL_RENDERCMD_SETDRAWCOLOR; + cmd->data.color.first = 0; /* render backend will fill this in. */ + cmd->data.color.r = col->r; + cmd->data.color.g = col->g; + cmd->data.color.b = col->b; + cmd->data.color.a = col->a; + retval = renderer->QueueSetDrawColor(renderer, cmd); + if (retval < 0) { + cmd->command = SDL_RENDERCMD_NO_OP; + } else { + renderer->last_queued_color = color; + renderer->color_queued = SDL_TRUE; + } + } + } + return retval; +} + +static int QueueCmdClear(SDL_Renderer *renderer) +{ + SDL_RenderCommand *cmd = AllocateRenderCommand(renderer); + if (!cmd) { + return -1; + } + + cmd->command = SDL_RENDERCMD_CLEAR; + cmd->data.color.first = 0; + cmd->data.color.r = renderer->color.r; + cmd->data.color.g = renderer->color.g; + cmd->data.color.b = renderer->color.b; + cmd->data.color.a = renderer->color.a; + return 0; +} + +static SDL_RenderCommand *PrepQueueCmdDraw(SDL_Renderer *renderer, const SDL_RenderCommandType cmdtype, SDL_Texture *texture) +{ + SDL_RenderCommand *cmd = NULL; + int retval = 0; + SDL_Color *color; + SDL_BlendMode blendMode; + + if (texture) { + color = &texture->color; + blendMode = texture->blendMode; + } else { + color = &renderer->color; + blendMode = renderer->blendMode; + } + + if (cmdtype != SDL_RENDERCMD_GEOMETRY) { + /* !!! FIXME: drop this draw if viewport w or h is zero. */ + retval = QueueCmdSetDrawColor(renderer, color); + } + + /* Set the viewport and clip rect directly before draws, so the backends + * don't have to worry about that state not being valid at draw time. */ + if (retval == 0 && !renderer->viewport_queued) { + retval = QueueCmdSetViewport(renderer); + } + if (retval == 0 && !renderer->cliprect_queued) { + retval = QueueCmdSetClipRect(renderer); + } + + if (retval == 0) { + cmd = AllocateRenderCommand(renderer); + if (cmd) { + cmd->command = cmdtype; + cmd->data.draw.first = 0; /* render backend will fill this in. */ + cmd->data.draw.count = 0; /* render backend will fill this in. */ + cmd->data.draw.r = color->r; + cmd->data.draw.g = color->g; + cmd->data.draw.b = color->b; + cmd->data.draw.a = color->a; + cmd->data.draw.blend = blendMode; + cmd->data.draw.texture = texture; + } + } + return cmd; +} + +static int QueueCmdDrawPoints(SDL_Renderer *renderer, const SDL_FPoint *points, const int count) +{ + SDL_RenderCommand *cmd = PrepQueueCmdDraw(renderer, SDL_RENDERCMD_DRAW_POINTS, NULL); + int retval = -1; + if (cmd) { + retval = renderer->QueueDrawPoints(renderer, cmd, points, count); + if (retval < 0) { + cmd->command = SDL_RENDERCMD_NO_OP; + } + } + return retval; +} + +static int QueueCmdDrawLines(SDL_Renderer *renderer, const SDL_FPoint *points, const int count) +{ + SDL_RenderCommand *cmd = PrepQueueCmdDraw(renderer, SDL_RENDERCMD_DRAW_LINES, NULL); + int retval = -1; + if (cmd) { + retval = renderer->QueueDrawLines(renderer, cmd, points, count); + if (retval < 0) { + cmd->command = SDL_RENDERCMD_NO_OP; + } + } + return retval; +} + +static int QueueCmdFillRects(SDL_Renderer *renderer, const SDL_FRect *rects, const int count) +{ + SDL_RenderCommand *cmd; + int retval = -1; + const int use_rendergeometry = (!renderer->QueueFillRects); + + cmd = PrepQueueCmdDraw(renderer, (use_rendergeometry ? SDL_RENDERCMD_GEOMETRY : SDL_RENDERCMD_FILL_RECTS), NULL); + + if (cmd) { + if (use_rendergeometry) { + SDL_bool isstack1; + SDL_bool isstack2; + float *xy = SDL_small_alloc(float, 4 * 2 * count, &isstack1); + int *indices = SDL_small_alloc(int, 6 * count, &isstack2); + + if (xy && indices) { + int i; + float *ptr_xy = xy; + int *ptr_indices = indices; + const int xy_stride = 2 * sizeof(float); + const int num_vertices = 4 * count; + const int num_indices = 6 * count; + const int size_indices = 4; + int cur_index = 0; + const int *rect_index_order = renderer->rect_index_order; + + for (i = 0; i < count; ++i) { + float minx, miny, maxx, maxy; + + minx = rects[i].x; + miny = rects[i].y; + maxx = rects[i].x + rects[i].w; + maxy = rects[i].y + rects[i].h; + + *ptr_xy++ = minx; + *ptr_xy++ = miny; + *ptr_xy++ = maxx; + *ptr_xy++ = miny; + *ptr_xy++ = maxx; + *ptr_xy++ = maxy; + *ptr_xy++ = minx; + *ptr_xy++ = maxy; + + *ptr_indices++ = cur_index + rect_index_order[0]; + *ptr_indices++ = cur_index + rect_index_order[1]; + *ptr_indices++ = cur_index + rect_index_order[2]; + *ptr_indices++ = cur_index + rect_index_order[3]; + *ptr_indices++ = cur_index + rect_index_order[4]; + *ptr_indices++ = cur_index + rect_index_order[5]; + cur_index += 4; + } + + retval = renderer->QueueGeometry(renderer, cmd, NULL, + xy, xy_stride, &renderer->color, 0 /* color_stride */, NULL, 0, + num_vertices, indices, num_indices, size_indices, + 1.0f, 1.0f); + + if (retval < 0) { + cmd->command = SDL_RENDERCMD_NO_OP; + } + } + SDL_small_free(xy, isstack1); + SDL_small_free(indices, isstack2); + + } else { + retval = renderer->QueueFillRects(renderer, cmd, rects, count); + if (retval < 0) { + cmd->command = SDL_RENDERCMD_NO_OP; + } + } + } + return retval; +} + +static int QueueCmdCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_FRect *dstrect) +{ + SDL_RenderCommand *cmd = PrepQueueCmdDraw(renderer, SDL_RENDERCMD_COPY, texture); + int retval = -1; + if (cmd) { + retval = renderer->QueueCopy(renderer, cmd, texture, srcrect, dstrect); + if (retval < 0) { + cmd->command = SDL_RENDERCMD_NO_OP; + } + } + return retval; +} + +static int QueueCmdCopyEx(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *srcquad, const SDL_FRect *dstrect, + const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip, float scale_x, float scale_y) +{ + SDL_RenderCommand *cmd = PrepQueueCmdDraw(renderer, SDL_RENDERCMD_COPY_EX, texture); + int retval = -1; + if (cmd) { + retval = renderer->QueueCopyEx(renderer, cmd, texture, srcquad, dstrect, angle, center, flip, scale_x, scale_y); + if (retval < 0) { + cmd->command = SDL_RENDERCMD_NO_OP; + } + } + return retval; +} + +static int QueueCmdGeometry(SDL_Renderer *renderer, SDL_Texture *texture, + const float *xy, int xy_stride, + const SDL_Color *color, int color_stride, + const float *uv, int uv_stride, + int num_vertices, + const void *indices, int num_indices, int size_indices, + float scale_x, float scale_y) +{ + SDL_RenderCommand *cmd; + int retval = -1; + cmd = PrepQueueCmdDraw(renderer, SDL_RENDERCMD_GEOMETRY, texture); + if (cmd) { + retval = renderer->QueueGeometry(renderer, cmd, texture, + xy, xy_stride, + color, color_stride, uv, uv_stride, + num_vertices, indices, num_indices, size_indices, + scale_x, scale_y); + if (retval < 0) { + cmd->command = SDL_RENDERCMD_NO_OP; + } + } + return retval; +} + +static int UpdateLogicalSize(SDL_Renderer *renderer, SDL_bool flush_viewport_cmd); + +int SDL_GetNumRenderDrivers(void) +{ +#ifndef SDL_RENDER_DISABLED + return SDL_arraysize(render_drivers); +#else + return 0; +#endif +} + +int SDL_GetRenderDriverInfo(int index, SDL_RendererInfo *info) +{ +#ifndef SDL_RENDER_DISABLED + if (index < 0 || index >= SDL_GetNumRenderDrivers()) { + return SDL_SetError("index must be in the range of 0 - %d", + SDL_GetNumRenderDrivers() - 1); + } + *info = render_drivers[index]->info; + return 0; +#else + return SDL_SetError("SDL not built with rendering support"); +#endif +} + +static void GetWindowViewportValues(SDL_Renderer *renderer, int *logical_w, int *logical_h, SDL_DRect *viewport, SDL_FPoint *scale) +{ + SDL_LockMutex(renderer->target_mutex); + *logical_w = renderer->target ? renderer->logical_w_backup : renderer->logical_w; + *logical_h = renderer->target ? renderer->logical_h_backup : renderer->logical_h; + *viewport = renderer->target ? renderer->viewport_backup : renderer->viewport; + *scale = renderer->target ? renderer->scale_backup : renderer->scale; + SDL_UnlockMutex(renderer->target_mutex); +} + +static int SDLCALL SDL_RendererEventWatch(void *userdata, SDL_Event *event) +{ + SDL_Renderer *renderer = (SDL_Renderer *)userdata; + + if (event->type == SDL_WINDOWEVENT) { + SDL_Window *window = SDL_GetWindowFromID(event->window.windowID); + if (window == renderer->window) { + if (renderer->WindowEvent) { + renderer->WindowEvent(renderer, &event->window); + } + + /* In addition to size changes, we also want to do this block for + * window display changes as well! If the new display has a new DPI, + * we need to update the viewport for the new window/drawable ratio. + */ + if (event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED || + event->window.event == SDL_WINDOWEVENT_DISPLAY_CHANGED) { + /* Make sure we're operating on the default render target */ + SDL_Texture *saved_target = SDL_GetRenderTarget(renderer); + if (saved_target) { + SDL_SetRenderTarget(renderer, NULL); + } + + /* Update the DPI scale if the window has been resized. */ + if (window && renderer->GetOutputSize) { + int window_w, window_h; + int output_w, output_h; + if (renderer->GetOutputSize(renderer, &output_w, &output_h) == 0) { + SDL_GetWindowSize(renderer->window, &window_w, &window_h); + renderer->dpi_scale.x = (float)window_w / output_w; + renderer->dpi_scale.y = (float)window_h / output_h; + } + } + + if (renderer->logical_w) { +#if defined(__ANDROID__) + /* Don't immediatly flush because the app may be in + * background, and the egl context shouldn't be used. */ + SDL_bool flush_viewport_cmd = SDL_FALSE; +#else + SDL_bool flush_viewport_cmd = SDL_TRUE; +#endif + UpdateLogicalSize(renderer, flush_viewport_cmd); + } else { + /* Window was resized, reset viewport */ + int w, h; + + if (renderer->GetOutputSize) { + renderer->GetOutputSize(renderer, &w, &h); + } else { + SDL_GetWindowSize(renderer->window, &w, &h); + } + + renderer->viewport.x = (double)0; + renderer->viewport.y = (double)0; + renderer->viewport.w = (double)w; + renderer->viewport.h = (double)h; + QueueCmdSetViewport(renderer); +#if defined(__ANDROID__) + /* Don't immediatly flush because the app may be in + * background, and the egl context shouldn't be used. */ +#else + FlushRenderCommandsIfNotBatching(renderer); +#endif + } + + if (saved_target) { + SDL_SetRenderTarget(renderer, saved_target); + } + } else if (event->window.event == SDL_WINDOWEVENT_HIDDEN) { + renderer->hidden = SDL_TRUE; + } else if (event->window.event == SDL_WINDOWEVENT_SHOWN) { + if (!(SDL_GetWindowFlags(window) & SDL_WINDOW_MINIMIZED)) { + renderer->hidden = SDL_FALSE; + } + } else if (event->window.event == SDL_WINDOWEVENT_MINIMIZED) { + renderer->hidden = SDL_TRUE; + } else if (event->window.event == SDL_WINDOWEVENT_RESTORED || + event->window.event == SDL_WINDOWEVENT_MAXIMIZED) { + if (!(SDL_GetWindowFlags(window) & SDL_WINDOW_HIDDEN)) { + renderer->hidden = SDL_FALSE; + } + } + } + } else if (event->type == SDL_MOUSEMOTION) { + SDL_Window *window = SDL_GetWindowFromID(event->motion.windowID); + if (window == renderer->window) { + int logical_w, logical_h; + SDL_DRect viewport; + SDL_FPoint scale; + GetWindowViewportValues(renderer, &logical_w, &logical_h, &viewport, &scale); + if (logical_w) { + event->motion.x -= (int)(viewport.x * renderer->dpi_scale.x); + event->motion.y -= (int)(viewport.y * renderer->dpi_scale.y); + event->motion.x = (int)(event->motion.x / (scale.x * renderer->dpi_scale.x)); + event->motion.y = (int)(event->motion.y / (scale.y * renderer->dpi_scale.y)); + if (event->motion.xrel != 0 && renderer->relative_scaling) { + float rel = renderer->xrel + event->motion.xrel / (scale.x * renderer->dpi_scale.x); + float truncated = SDL_truncf(rel); + renderer->xrel = rel - truncated; + event->motion.xrel = (Sint32)truncated; + } + if (event->motion.yrel != 0 && renderer->relative_scaling) { + float rel = renderer->yrel + event->motion.yrel / (scale.y * renderer->dpi_scale.y); + float truncated = SDL_truncf(rel); + renderer->yrel = rel - truncated; + event->motion.yrel = (Sint32)truncated; + } + } + } + } else if (event->type == SDL_MOUSEBUTTONDOWN || + event->type == SDL_MOUSEBUTTONUP) { + SDL_Window *window = SDL_GetWindowFromID(event->button.windowID); + if (window == renderer->window) { + int logical_w, logical_h; + SDL_DRect viewport; + SDL_FPoint scale; + GetWindowViewportValues(renderer, &logical_w, &logical_h, &viewport, &scale); + if (logical_w) { + event->button.x -= (int)(viewport.x * renderer->dpi_scale.x); + event->button.y -= (int)(viewport.y * renderer->dpi_scale.y); + event->button.x = (int)(event->button.x / (scale.x * renderer->dpi_scale.x)); + event->button.y = (int)(event->button.y / (scale.y * renderer->dpi_scale.y)); + } + } + } else if (event->type == SDL_MOUSEWHEEL) { + SDL_Window *window = SDL_GetWindowFromID(event->wheel.windowID); + if (window == renderer->window) { + int logical_w, logical_h; + SDL_DRect viewport; + SDL_FPoint scale; + GetWindowViewportValues(renderer, &logical_w, &logical_h, &viewport, &scale); + if (logical_w) { + event->wheel.mouseX -= (int)(viewport.x * renderer->dpi_scale.x); + event->wheel.mouseY -= (int)(viewport.y * renderer->dpi_scale.y); + event->wheel.mouseX = (int)(event->wheel.mouseX / (scale.x * renderer->dpi_scale.x)); + event->wheel.mouseY = (int)(event->wheel.mouseY / (scale.y * renderer->dpi_scale.y)); + } + } + } else if (event->type == SDL_FINGERDOWN || + event->type == SDL_FINGERUP || + event->type == SDL_FINGERMOTION) { + int logical_w, logical_h; + float physical_w, physical_h; + SDL_DRect viewport; + SDL_FPoint scale; + GetWindowViewportValues(renderer, &logical_w, &logical_h, &viewport, &scale); + + /* !!! FIXME: we probably should drop events that are outside of the + !!! FIXME: viewport, but we can't do that from an event watcher, + !!! FIXME: and we would have to track if a touch happened outside + !!! FIXME: the viewport and then slid into it to insert extra + !!! FIXME: events, which is a mess, so for now we just clamp these + !!! FIXME: events to the edge. */ + + if (renderer->GetOutputSize) { + int w, h; + renderer->GetOutputSize(renderer, &w, &h); + physical_w = (float)w; + physical_h = (float)h; + } else { + int w, h; + SDL_GetWindowSize(renderer->window, &w, &h); + physical_w = ((float)w) * renderer->dpi_scale.x; + physical_h = ((float)h) * renderer->dpi_scale.y; + } + + if (physical_w == 0.0f) { /* nowhere for the touch to go, avoid division by zero and put it dead center. */ + event->tfinger.x = 0.5f; + } else { + const float normalized_viewport_x = ((float)viewport.x) / physical_w; + const float normalized_viewport_w = ((float)viewport.w) / physical_w; + if (event->tfinger.x <= normalized_viewport_x) { + event->tfinger.x = 0.0f; /* to the left of the viewport, clamp to the edge. */ + } else if (event->tfinger.x >= (normalized_viewport_x + normalized_viewport_w)) { + event->tfinger.x = 1.0f; /* to the right of the viewport, clamp to the edge. */ + } else { + event->tfinger.x = (event->tfinger.x - normalized_viewport_x) / normalized_viewport_w; + } + } + + if (physical_h == 0.0f) { /* nowhere for the touch to go, avoid division by zero and put it dead center. */ + event->tfinger.y = 0.5f; + } else { + const float normalized_viewport_y = ((float)viewport.y) / physical_h; + const float normalized_viewport_h = ((float)viewport.h) / physical_h; + if (event->tfinger.y <= normalized_viewport_y) { + event->tfinger.y = 0.0f; /* to the left of the viewport, clamp to the edge. */ + } else if (event->tfinger.y >= (normalized_viewport_y + normalized_viewport_h)) { + event->tfinger.y = 1.0f; /* to the right of the viewport, clamp to the edge. */ + } else { + event->tfinger.y = (event->tfinger.y - normalized_viewport_y) / normalized_viewport_h; + } + } + } + + return 0; +} + +int SDL_CreateWindowAndRenderer(int width, int height, Uint32 window_flags, + SDL_Window **window, SDL_Renderer **renderer) +{ + *window = SDL_CreateWindow(NULL, SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, + width, height, window_flags); + if (!*window) { + *renderer = NULL; + return -1; + } + + *renderer = SDL_CreateRenderer(*window, -1, 0); + if (!*renderer) { + return -1; + } + + return 0; +} + +#ifndef SDL_RENDER_DISABLED +static SDL_INLINE void VerifyDrawQueueFunctions(const SDL_Renderer *renderer) +{ + /* all of these functions are required to be implemented, even as no-ops, so we don't + have to check that they aren't NULL over and over. */ + SDL_assert(renderer->QueueSetViewport != NULL); + SDL_assert(renderer->QueueSetDrawColor != NULL); + SDL_assert(renderer->QueueDrawPoints != NULL); + SDL_assert(renderer->QueueDrawLines != NULL || renderer->QueueGeometry != NULL); + SDL_assert(renderer->QueueFillRects != NULL || renderer->QueueGeometry != NULL); + SDL_assert(renderer->QueueCopy != NULL || renderer->QueueGeometry != NULL); + SDL_assert(renderer->RunCommandQueue != NULL); +} + +static SDL_RenderLineMethod SDL_GetRenderLineMethod(void) +{ + const char *hint = SDL_GetHint(SDL_HINT_RENDER_LINE_METHOD); + + int method = 0; + if (hint) { + method = SDL_atoi(hint); + } + switch (method) { + case 1: + return SDL_RENDERLINEMETHOD_POINTS; + case 2: + return SDL_RENDERLINEMETHOD_LINES; + case 3: + return SDL_RENDERLINEMETHOD_GEOMETRY; + default: + return SDL_RENDERLINEMETHOD_POINTS; + } +} + +static void SDL_CalculateSimulatedVSyncInterval(SDL_Renderer *renderer, SDL_Window *window) +{ + /* FIXME: SDL refresh rate API should return numerator/denominator */ + int refresh_rate = 0; + int display_index = SDL_GetWindowDisplayIndex(window); + SDL_DisplayMode mode; + + if (display_index < 0) { + display_index = 0; + } + if (SDL_GetDesktopDisplayMode(display_index, &mode) == 0) { + refresh_rate = mode.refresh_rate; + } + if (!refresh_rate) { + /* Pick a good default refresh rate */ + refresh_rate = 60; + } + renderer->simulate_vsync_interval = (1000 / refresh_rate); +} +#endif /* !SDL_RENDER_DISABLED */ + +SDL_Renderer *SDL_CreateRenderer(SDL_Window *window, int index, Uint32 flags) +{ +#ifndef SDL_RENDER_DISABLED + SDL_Renderer *renderer = NULL; + int n = SDL_GetNumRenderDrivers(); + SDL_bool batching = SDL_TRUE; + const char *hint; + +#if defined(__ANDROID__) + Android_ActivityMutex_Lock_Running(); +#endif + + if (!window) { + SDL_InvalidParamError("window"); + goto error; + } + + if (SDL_HasWindowSurface(window)) { + SDL_SetError("Surface already associated with window"); + goto error; + } + + if (SDL_GetRenderer(window)) { + SDL_SetError("Renderer already associated with window"); + goto error; + } + + hint = SDL_GetHint(SDL_HINT_RENDER_VSYNC); + if (hint && *hint) { + if (SDL_GetHintBoolean(SDL_HINT_RENDER_VSYNC, SDL_TRUE)) { + flags |= SDL_RENDERER_PRESENTVSYNC; + } else { + flags &= ~SDL_RENDERER_PRESENTVSYNC; + } + } + + if (index < 0) { + hint = SDL_GetHint(SDL_HINT_RENDER_DRIVER); + if (hint) { + for (index = 0; index < n; ++index) { + const SDL_RenderDriver *driver = render_drivers[index]; + + if (SDL_strcasecmp(hint, driver->info.name) == 0) { + /* Create a new renderer instance */ + renderer = driver->CreateRenderer(window, flags); + if (renderer) { + batching = SDL_FALSE; + } + break; + } + } + } + + if (!renderer) { + for (index = 0; index < n; ++index) { + const SDL_RenderDriver *driver = render_drivers[index]; + + if ((driver->info.flags & flags) == flags) { + /* Create a new renderer instance */ + renderer = driver->CreateRenderer(window, flags); + if (renderer) { + /* Yay, we got one! */ + break; + } + } + } + } + if (!renderer) { + SDL_SetError("Couldn't find matching render driver"); + goto error; + } + } else { + if (index >= n) { + SDL_SetError("index must be -1 or in the range of 0 - %d", + n - 1); + goto error; + } + /* Create a new renderer instance */ + renderer = render_drivers[index]->CreateRenderer(window, flags); + batching = SDL_FALSE; + if (!renderer) { + goto error; + } + } + + if (flags & SDL_RENDERER_PRESENTVSYNC) { + renderer->wanted_vsync = SDL_TRUE; + + if (!(renderer->info.flags & SDL_RENDERER_PRESENTVSYNC)) { + renderer->simulate_vsync = SDL_TRUE; + renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; + } + } + SDL_CalculateSimulatedVSyncInterval(renderer, window); + + VerifyDrawQueueFunctions(renderer); + + /* let app/user override batching decisions. */ + if (renderer->always_batch) { + batching = SDL_TRUE; + } else if (SDL_GetHint(SDL_HINT_RENDER_BATCHING)) { + batching = SDL_GetHintBoolean(SDL_HINT_RENDER_BATCHING, SDL_TRUE); + } + + renderer->batching = batching; + renderer->magic = &renderer_magic; + renderer->window = window; + renderer->target_mutex = SDL_CreateMutex(); + renderer->scale.x = 1.0f; + renderer->scale.y = 1.0f; + renderer->dpi_scale.x = 1.0f; + renderer->dpi_scale.y = 1.0f; + + /* Default value, if not specified by the renderer back-end */ + if (renderer->rect_index_order[0] == 0 && renderer->rect_index_order[1] == 0) { + renderer->rect_index_order[0] = 0; + renderer->rect_index_order[1] = 1; + renderer->rect_index_order[2] = 2; + renderer->rect_index_order[3] = 0; + renderer->rect_index_order[4] = 2; + renderer->rect_index_order[5] = 3; + } + + /* new textures start at zero, so we start at 1 so first render doesn't flush by accident. */ + renderer->render_command_generation = 1; + + if (renderer->GetOutputSize) { + int window_w, window_h; + int output_w, output_h; + if (renderer->GetOutputSize(renderer, &output_w, &output_h) == 0) { + SDL_GetWindowSize(renderer->window, &window_w, &window_h); + renderer->dpi_scale.x = (float)window_w / output_w; + renderer->dpi_scale.y = (float)window_h / output_h; + } + } + + renderer->relative_scaling = SDL_GetHintBoolean(SDL_HINT_MOUSE_RELATIVE_SCALING, SDL_TRUE); + + renderer->line_method = SDL_GetRenderLineMethod(); + + if (SDL_GetWindowFlags(window) & (SDL_WINDOW_HIDDEN | SDL_WINDOW_MINIMIZED)) { + renderer->hidden = SDL_TRUE; + } else { + renderer->hidden = SDL_FALSE; + } + + SDL_SetWindowData(window, SDL_WINDOWRENDERDATA, renderer); + + SDL_RenderSetViewport(renderer, NULL); + + SDL_AddEventWatch(SDL_RendererEventWatch, renderer); + + SDL_LogInfo(SDL_LOG_CATEGORY_RENDER, + "Created renderer: %s", renderer->info.name); + +#if defined(__ANDROID__) + Android_ActivityMutex_Unlock(); +#endif + return renderer; + +error: + +#if defined(__ANDROID__) + Android_ActivityMutex_Unlock(); +#endif + return NULL; + +#else + SDL_SetError("SDL not built with rendering support"); + return NULL; +#endif +} + +SDL_Renderer *SDL_CreateSoftwareRenderer(SDL_Surface *surface) +{ +#if SDL_VIDEO_RENDER_SW + SDL_Renderer *renderer; + + renderer = SW_CreateRendererForSurface(surface); + + if (renderer) { + VerifyDrawQueueFunctions(renderer); + renderer->magic = &renderer_magic; + renderer->target_mutex = SDL_CreateMutex(); + renderer->scale.x = 1.0f; + renderer->scale.y = 1.0f; + + /* new textures start at zero, so we start at 1 so first render doesn't flush by accident. */ + renderer->render_command_generation = 1; + + /* Software renderer always uses line method, for speed */ + renderer->line_method = SDL_RENDERLINEMETHOD_LINES; + + SDL_RenderSetViewport(renderer, NULL); + } + return renderer; +#else + SDL_SetError("SDL not built with rendering support"); + return NULL; +#endif /* !SDL_RENDER_DISABLED */ +} + +SDL_Renderer *SDL_GetRenderer(SDL_Window *window) +{ + return (SDL_Renderer *)SDL_GetWindowData(window, SDL_WINDOWRENDERDATA); +} + +SDL_Window *SDL_RenderGetWindow(SDL_Renderer *renderer) +{ + CHECK_RENDERER_MAGIC(renderer, NULL); + return renderer->window; +} + +int SDL_GetRendererInfo(SDL_Renderer *renderer, SDL_RendererInfo *info) +{ + CHECK_RENDERER_MAGIC(renderer, -1); + + *info = renderer->info; + return 0; +} + +int SDL_GetRendererOutputSize(SDL_Renderer *renderer, int *w, int *h) +{ + CHECK_RENDERER_MAGIC(renderer, -1); + + if (renderer->target) { + return SDL_QueryTexture(renderer->target, NULL, NULL, w, h); + } else if (renderer->GetOutputSize) { + return renderer->GetOutputSize(renderer, w, h); + } else if (renderer->window) { + SDL_GetWindowSize(renderer->window, w, h); + return 0; + } else { + SDL_assert(0 && "This should never happen"); + return SDL_SetError("Renderer doesn't support querying output size"); + } +} + +static SDL_bool IsSupportedBlendMode(SDL_Renderer *renderer, SDL_BlendMode blendMode) +{ + switch (blendMode) { + /* These are required to be supported by all renderers */ + case SDL_BLENDMODE_NONE: + case SDL_BLENDMODE_BLEND: + case SDL_BLENDMODE_ADD: + case SDL_BLENDMODE_MOD: + case SDL_BLENDMODE_MUL: + return SDL_TRUE; + + default: + return renderer->SupportsBlendMode && renderer->SupportsBlendMode(renderer, blendMode); + } +} + +static SDL_bool IsSupportedFormat(SDL_Renderer *renderer, Uint32 format) +{ + Uint32 i; + + for (i = 0; i < renderer->info.num_texture_formats; ++i) { + if (renderer->info.texture_formats[i] == format) { + return SDL_TRUE; + } + } + return SDL_FALSE; +} + +static Uint32 GetClosestSupportedFormat(SDL_Renderer *renderer, Uint32 format) +{ + Uint32 i; + + if (SDL_ISPIXELFORMAT_FOURCC(format)) { + /* Look for an exact match */ + for (i = 0; i < renderer->info.num_texture_formats; ++i) { + if (renderer->info.texture_formats[i] == format) { + return renderer->info.texture_formats[i]; + } + } + } else { + SDL_bool hasAlpha = SDL_ISPIXELFORMAT_ALPHA(format); + + /* We just want to match the first format that has the same channels */ + for (i = 0; i < renderer->info.num_texture_formats; ++i) { + if (!SDL_ISPIXELFORMAT_FOURCC(renderer->info.texture_formats[i]) && + SDL_ISPIXELFORMAT_ALPHA(renderer->info.texture_formats[i]) == hasAlpha) { + return renderer->info.texture_formats[i]; + } + } + } + return renderer->info.texture_formats[0]; +} + +static SDL_ScaleMode SDL_GetScaleMode(void) +{ + const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY); + + if (!hint || SDL_strcasecmp(hint, "nearest") == 0) { + return SDL_ScaleModeNearest; + } else if (SDL_strcasecmp(hint, "linear") == 0) { + return SDL_ScaleModeLinear; + } else if (SDL_strcasecmp(hint, "best") == 0) { + return SDL_ScaleModeBest; + } else { + return (SDL_ScaleMode)SDL_atoi(hint); + } +} + +SDL_Texture *SDL_CreateTexture(SDL_Renderer *renderer, Uint32 format, int access, int w, int h) +{ + SDL_Texture *texture; + SDL_bool texture_is_fourcc_and_target; + + CHECK_RENDERER_MAGIC(renderer, NULL); + + if (!format) { + format = renderer->info.texture_formats[0]; + } + if (SDL_BYTESPERPIXEL(format) == 0) { + SDL_SetError("Invalid texture format"); + return NULL; + } + if (SDL_ISPIXELFORMAT_INDEXED(format)) { + if (!IsSupportedFormat(renderer, format)) { + SDL_SetError("Palettized textures are not supported"); + return NULL; + } + } + if (w <= 0 || h <= 0) { + SDL_SetError("Texture dimensions can't be 0"); + return NULL; + } + if ((renderer->info.max_texture_width && w > renderer->info.max_texture_width) || + (renderer->info.max_texture_height && h > renderer->info.max_texture_height)) { + SDL_SetError("Texture dimensions are limited to %dx%d", renderer->info.max_texture_width, renderer->info.max_texture_height); + return NULL; + } + texture = (SDL_Texture *)SDL_calloc(1, sizeof(*texture)); + if (!texture) { + SDL_OutOfMemory(); + return NULL; + } + texture->magic = &texture_magic; + texture->format = format; + texture->access = access; + texture->w = w; + texture->h = h; + texture->color.r = 255; + texture->color.g = 255; + texture->color.b = 255; + texture->color.a = 255; + texture->scaleMode = SDL_GetScaleMode(); + texture->renderer = renderer; + texture->next = renderer->textures; + if (renderer->textures) { + renderer->textures->prev = texture; + } + renderer->textures = texture; + + /* FOURCC format cannot be used directly by renderer back-ends for target texture */ + texture_is_fourcc_and_target = (access == SDL_TEXTUREACCESS_TARGET && SDL_ISPIXELFORMAT_FOURCC(texture->format)); + + if (texture_is_fourcc_and_target == SDL_FALSE && IsSupportedFormat(renderer, format)) { + if (renderer->CreateTexture(renderer, texture) < 0) { + SDL_DestroyTexture(texture); + return NULL; + } + } else { + int closest_format; + + if (texture_is_fourcc_and_target == SDL_FALSE) { + closest_format = GetClosestSupportedFormat(renderer, format); + } else { + closest_format = renderer->info.texture_formats[0]; + } + + texture->native = SDL_CreateTexture(renderer, closest_format, access, w, h); + if (!texture->native) { + SDL_DestroyTexture(texture); + return NULL; + } + + /* Swap textures to have texture before texture->native in the list */ + texture->native->next = texture->next; + if (texture->native->next) { + texture->native->next->prev = texture->native; + } + texture->prev = texture->native->prev; + if (texture->prev) { + texture->prev->next = texture; + } + texture->native->prev = texture; + texture->next = texture->native; + renderer->textures = texture; + + if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { +#if SDL_HAVE_YUV + texture->yuv = SDL_SW_CreateYUVTexture(format, w, h); +#else + SDL_SetError("SDL not built with YUV support"); +#endif + if (!texture->yuv) { + SDL_DestroyTexture(texture); + return NULL; + } + } else if (access == SDL_TEXTUREACCESS_STREAMING) { + /* The pitch is 4 byte aligned */ + texture->pitch = (((w * SDL_BYTESPERPIXEL(format)) + 3) & ~3); + texture->pixels = SDL_calloc(1, (size_t)texture->pitch * h); + if (!texture->pixels) { + SDL_DestroyTexture(texture); + return NULL; + } + } + } + return texture; +} + +SDL_Texture *SDL_CreateTextureFromSurface(SDL_Renderer *renderer, SDL_Surface *surface) +{ + const SDL_PixelFormat *fmt; + SDL_bool needAlpha; + SDL_bool direct_update; + int i; + Uint32 format = SDL_PIXELFORMAT_UNKNOWN; + SDL_Texture *texture; + + CHECK_RENDERER_MAGIC(renderer, NULL); + + if (!surface) { + SDL_InvalidParamError("SDL_CreateTextureFromSurface(): surface"); + return NULL; + } + + /* See what the best texture format is */ + fmt = surface->format; + if (fmt->Amask || SDL_HasColorKey(surface)) { + needAlpha = SDL_TRUE; + } else { + needAlpha = SDL_FALSE; + } + + /* If Palette contains alpha values, promotes to alpha format */ + if (fmt->palette) { + SDL_bool is_opaque, has_alpha_channel; + SDL_DetectPalette(fmt->palette, &is_opaque, &has_alpha_channel); + if (!is_opaque) { + needAlpha = SDL_TRUE; + } + } + + /* Try to have the best pixel format for the texture */ + /* No alpha, but a colorkey => promote to alpha */ + if (!fmt->Amask && SDL_HasColorKey(surface)) { + if (fmt->format == SDL_PIXELFORMAT_RGB888) { + for (i = 0; i < (int)renderer->info.num_texture_formats; ++i) { + if (renderer->info.texture_formats[i] == SDL_PIXELFORMAT_ARGB8888) { + format = SDL_PIXELFORMAT_ARGB8888; + break; + } + } + } else if (fmt->format == SDL_PIXELFORMAT_BGR888) { + for (i = 0; i < (int)renderer->info.num_texture_formats; ++i) { + if (renderer->info.texture_formats[i] == SDL_PIXELFORMAT_ABGR8888) { + format = SDL_PIXELFORMAT_ABGR8888; + break; + } + } + } + } else { + /* Exact match would be fine */ + for (i = 0; i < (int)renderer->info.num_texture_formats; ++i) { + if (renderer->info.texture_formats[i] == fmt->format) { + format = fmt->format; + break; + } + } + } + + /* Fallback, choose a valid pixel format */ + if (format == SDL_PIXELFORMAT_UNKNOWN) { + format = renderer->info.texture_formats[0]; + for (i = 0; i < (int)renderer->info.num_texture_formats; ++i) { + if (!SDL_ISPIXELFORMAT_FOURCC(renderer->info.texture_formats[i]) && + SDL_ISPIXELFORMAT_ALPHA(renderer->info.texture_formats[i]) == needAlpha) { + format = renderer->info.texture_formats[i]; + break; + } + } + } + + texture = SDL_CreateTexture(renderer, format, SDL_TEXTUREACCESS_STATIC, + surface->w, surface->h); + if (!texture) { + return NULL; + } + + if (format == surface->format->format) { + if (surface->format->Amask && SDL_HasColorKey(surface)) { + /* Surface and Renderer formats are identicals. + * Intermediate conversion is needed to convert color key to alpha (SDL_ConvertColorkeyToAlpha()). */ + direct_update = SDL_FALSE; + } else { + /* Update Texture directly */ + direct_update = SDL_TRUE; + } + } else { + /* Surface and Renderer formats are differents, it needs an intermediate conversion. */ + direct_update = SDL_FALSE; + } + + if (direct_update) { + if (SDL_MUSTLOCK(surface)) { + SDL_LockSurface(surface); + SDL_UpdateTexture(texture, NULL, surface->pixels, surface->pitch); + SDL_UnlockSurface(surface); + } else { + SDL_UpdateTexture(texture, NULL, surface->pixels, surface->pitch); + } + +#if SDL_VIDEO_RENDER_DIRECTFB + /* DirectFB allows palette format for textures. + * Copy SDL_Surface palette to the texture */ + if (SDL_ISPIXELFORMAT_INDEXED(format)) { + if (SDL_strcasecmp(renderer->info.name, "directfb") == 0) { + extern void DirectFB_SetTexturePalette(SDL_Renderer *renderer, SDL_Texture *texture, SDL_Palette *pal); + DirectFB_SetTexturePalette(renderer, texture, surface->format->palette); + } + } +#endif + + } else { + SDL_PixelFormat *dst_fmt; + SDL_Surface *temp = NULL; + + /* Set up a destination surface for the texture update */ + dst_fmt = SDL_AllocFormat(format); + if (!dst_fmt) { + SDL_DestroyTexture(texture); + return NULL; + } + temp = SDL_ConvertSurface(surface, dst_fmt, 0); + SDL_FreeFormat(dst_fmt); + if (temp) { + SDL_UpdateTexture(texture, NULL, temp->pixels, temp->pitch); + SDL_FreeSurface(temp); + } else { + SDL_DestroyTexture(texture); + return NULL; + } + } + + { + Uint8 r, g, b, a; + SDL_BlendMode blendMode; + + SDL_GetSurfaceColorMod(surface, &r, &g, &b); + SDL_SetTextureColorMod(texture, r, g, b); + + SDL_GetSurfaceAlphaMod(surface, &a); + SDL_SetTextureAlphaMod(texture, a); + + if (SDL_HasColorKey(surface)) { + /* We converted to a texture with alpha format */ + SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); + } else { + SDL_GetSurfaceBlendMode(surface, &blendMode); + SDL_SetTextureBlendMode(texture, blendMode); + } + } + return texture; +} + +int SDL_QueryTexture(SDL_Texture *texture, Uint32 *format, int *access, + int *w, int *h) +{ + CHECK_TEXTURE_MAGIC(texture, -1); + + if (format) { + *format = texture->format; + } + if (access) { + *access = texture->access; + } + if (w) { + *w = texture->w; + } + if (h) { + *h = texture->h; + } + return 0; +} + +int SDL_SetTextureColorMod(SDL_Texture *texture, Uint8 r, Uint8 g, Uint8 b) +{ + CHECK_TEXTURE_MAGIC(texture, -1); + + if (r < 255 || g < 255 || b < 255) { + texture->modMode |= SDL_TEXTUREMODULATE_COLOR; + } else { + texture->modMode &= ~SDL_TEXTUREMODULATE_COLOR; + } + texture->color.r = r; + texture->color.g = g; + texture->color.b = b; + if (texture->native) { + return SDL_SetTextureColorMod(texture->native, r, g, b); + } + return 0; +} + +int SDL_GetTextureColorMod(SDL_Texture *texture, Uint8 *r, Uint8 *g, + Uint8 *b) +{ + CHECK_TEXTURE_MAGIC(texture, -1); + + if (r) { + *r = texture->color.r; + } + if (g) { + *g = texture->color.g; + } + if (b) { + *b = texture->color.b; + } + return 0; +} + +int SDL_SetTextureAlphaMod(SDL_Texture *texture, Uint8 alpha) +{ + CHECK_TEXTURE_MAGIC(texture, -1); + + if (alpha < 255) { + texture->modMode |= SDL_TEXTUREMODULATE_ALPHA; + } else { + texture->modMode &= ~SDL_TEXTUREMODULATE_ALPHA; + } + texture->color.a = alpha; + if (texture->native) { + return SDL_SetTextureAlphaMod(texture->native, alpha); + } + return 0; +} + +int SDL_GetTextureAlphaMod(SDL_Texture *texture, Uint8 *alpha) +{ + CHECK_TEXTURE_MAGIC(texture, -1); + + if (alpha) { + *alpha = texture->color.a; + } + return 0; +} + +int SDL_SetTextureBlendMode(SDL_Texture *texture, SDL_BlendMode blendMode) +{ + SDL_Renderer *renderer; + + CHECK_TEXTURE_MAGIC(texture, -1); + + renderer = texture->renderer; + if (!IsSupportedBlendMode(renderer, blendMode)) { + return SDL_Unsupported(); + } + texture->blendMode = blendMode; + if (texture->native) { + return SDL_SetTextureBlendMode(texture->native, blendMode); + } + return 0; +} + +int SDL_GetTextureBlendMode(SDL_Texture *texture, SDL_BlendMode *blendMode) +{ + CHECK_TEXTURE_MAGIC(texture, -1); + + if (blendMode) { + *blendMode = texture->blendMode; + } + return 0; +} + +int SDL_SetTextureScaleMode(SDL_Texture *texture, SDL_ScaleMode scaleMode) +{ + SDL_Renderer *renderer; + + CHECK_TEXTURE_MAGIC(texture, -1); + + renderer = texture->renderer; + texture->scaleMode = scaleMode; + if (texture->native) { + return SDL_SetTextureScaleMode(texture->native, scaleMode); + } else { + renderer->SetTextureScaleMode(renderer, texture, scaleMode); + } + return 0; +} + +int SDL_GetTextureScaleMode(SDL_Texture *texture, SDL_ScaleMode *scaleMode) +{ + CHECK_TEXTURE_MAGIC(texture, -1); + + if (scaleMode) { + *scaleMode = texture->scaleMode; + } + return 0; +} + +int SDL_SetTextureUserData(SDL_Texture *texture, void *userdata) +{ + CHECK_TEXTURE_MAGIC(texture, -1); + + texture->userdata = userdata; + return 0; +} + +void *SDL_GetTextureUserData(SDL_Texture *texture) +{ + CHECK_TEXTURE_MAGIC(texture, NULL); + + return texture->userdata; +} + +#if SDL_HAVE_YUV +static int SDL_UpdateTextureYUV(SDL_Texture *texture, const SDL_Rect *rect, + const void *pixels, int pitch) +{ + SDL_Texture *native = texture->native; + SDL_Rect full_rect; + + if (SDL_SW_UpdateYUVTexture(texture->yuv, rect, pixels, pitch) < 0) { + return -1; + } + + full_rect.x = 0; + full_rect.y = 0; + full_rect.w = texture->w; + full_rect.h = texture->h; + rect = &full_rect; + + if (texture->access == SDL_TEXTUREACCESS_STREAMING) { + /* We can lock the texture and copy to it */ + void *native_pixels = NULL; + int native_pitch = 0; + + if (SDL_LockTexture(native, rect, &native_pixels, &native_pitch) < 0) { + return -1; + } + SDL_SW_CopyYUVToRGB(texture->yuv, rect, native->format, + rect->w, rect->h, native_pixels, native_pitch); + SDL_UnlockTexture(native); + } else { + /* Use a temporary buffer for updating */ + const int temp_pitch = (((rect->w * SDL_BYTESPERPIXEL(native->format)) + 3) & ~3); + const size_t alloclen = (size_t)rect->h * temp_pitch; + if (alloclen > 0) { + void *temp_pixels = SDL_malloc(alloclen); + if (!temp_pixels) { + return SDL_OutOfMemory(); + } + SDL_SW_CopyYUVToRGB(texture->yuv, rect, native->format, + rect->w, rect->h, temp_pixels, temp_pitch); + SDL_UpdateTexture(native, rect, temp_pixels, temp_pitch); + SDL_free(temp_pixels); + } + } + return 0; +} +#endif /* SDL_HAVE_YUV */ + +static int SDL_UpdateTextureNative(SDL_Texture *texture, const SDL_Rect *rect, + const void *pixels, int pitch) +{ + SDL_Texture *native = texture->native; + + if (!rect->w || !rect->h) { + return 0; /* nothing to do. */ + } + + if (texture->access == SDL_TEXTUREACCESS_STREAMING) { + /* We can lock the texture and copy to it */ + void *native_pixels = NULL; + int native_pitch = 0; + + if (SDL_LockTexture(native, rect, &native_pixels, &native_pitch) < 0) { + return -1; + } + SDL_ConvertPixels(rect->w, rect->h, + texture->format, pixels, pitch, + native->format, native_pixels, native_pitch); + SDL_UnlockTexture(native); + } else { + /* Use a temporary buffer for updating */ + const int temp_pitch = (((rect->w * SDL_BYTESPERPIXEL(native->format)) + 3) & ~3); + const size_t alloclen = (size_t)rect->h * temp_pitch; + if (alloclen > 0) { + void *temp_pixels = SDL_malloc(alloclen); + if (!temp_pixels) { + return SDL_OutOfMemory(); + } + SDL_ConvertPixels(rect->w, rect->h, + texture->format, pixels, pitch, + native->format, temp_pixels, temp_pitch); + SDL_UpdateTexture(native, rect, temp_pixels, temp_pitch); + SDL_free(temp_pixels); + } + } + return 0; +} + +int SDL_UpdateTexture(SDL_Texture *texture, const SDL_Rect *rect, + const void *pixels, int pitch) +{ + SDL_Rect real_rect; + + CHECK_TEXTURE_MAGIC(texture, -1); + + if (!pixels) { + return SDL_InvalidParamError("pixels"); + } + if (!pitch) { + return SDL_InvalidParamError("pitch"); + } + + real_rect.x = 0; + real_rect.y = 0; + real_rect.w = texture->w; + real_rect.h = texture->h; + if (rect) { + if (!SDL_IntersectRect(rect, &real_rect, &real_rect)) { + return 0; + } + } + + if (real_rect.w == 0 || real_rect.h == 0) { + return 0; /* nothing to do. */ +#if SDL_HAVE_YUV + } else if (texture->yuv) { + return SDL_UpdateTextureYUV(texture, &real_rect, pixels, pitch); +#endif + } else if (texture->native) { + return SDL_UpdateTextureNative(texture, &real_rect, pixels, pitch); + } else { + SDL_Renderer *renderer = texture->renderer; + if (FlushRenderCommandsIfTextureNeeded(texture) < 0) { + return -1; + } + return renderer->UpdateTexture(renderer, texture, &real_rect, pixels, pitch); + } +} + +#if SDL_HAVE_YUV +static int SDL_UpdateTextureYUVPlanar(SDL_Texture *texture, const SDL_Rect *rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *Uplane, int Upitch, + const Uint8 *Vplane, int Vpitch) +{ + SDL_Texture *native = texture->native; + SDL_Rect full_rect; + + if (SDL_SW_UpdateYUVTexturePlanar(texture->yuv, rect, Yplane, Ypitch, Uplane, Upitch, Vplane, Vpitch) < 0) { + return -1; + } + + full_rect.x = 0; + full_rect.y = 0; + full_rect.w = texture->w; + full_rect.h = texture->h; + rect = &full_rect; + + if (!rect->w || !rect->h) { + return 0; /* nothing to do. */ + } + + if (texture->access == SDL_TEXTUREACCESS_STREAMING) { + /* We can lock the texture and copy to it */ + void *native_pixels = NULL; + int native_pitch = 0; + + if (SDL_LockTexture(native, rect, &native_pixels, &native_pitch) < 0) { + return -1; + } + SDL_SW_CopyYUVToRGB(texture->yuv, rect, native->format, + rect->w, rect->h, native_pixels, native_pitch); + SDL_UnlockTexture(native); + } else { + /* Use a temporary buffer for updating */ + const int temp_pitch = (((rect->w * SDL_BYTESPERPIXEL(native->format)) + 3) & ~3); + const size_t alloclen = (size_t)rect->h * temp_pitch; + if (alloclen > 0) { + void *temp_pixels = SDL_malloc(alloclen); + if (!temp_pixels) { + return SDL_OutOfMemory(); + } + SDL_SW_CopyYUVToRGB(texture->yuv, rect, native->format, + rect->w, rect->h, temp_pixels, temp_pitch); + SDL_UpdateTexture(native, rect, temp_pixels, temp_pitch); + SDL_free(temp_pixels); + } + } + return 0; +} + +static int SDL_UpdateTextureNVPlanar(SDL_Texture *texture, const SDL_Rect *rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *UVplane, int UVpitch) +{ + SDL_Texture *native = texture->native; + SDL_Rect full_rect; + + if (SDL_SW_UpdateNVTexturePlanar(texture->yuv, rect, Yplane, Ypitch, UVplane, UVpitch) < 0) { + return -1; + } + + full_rect.x = 0; + full_rect.y = 0; + full_rect.w = texture->w; + full_rect.h = texture->h; + rect = &full_rect; + + if (!rect->w || !rect->h) { + return 0; /* nothing to do. */ + } + + if (texture->access == SDL_TEXTUREACCESS_STREAMING) { + /* We can lock the texture and copy to it */ + void *native_pixels = NULL; + int native_pitch = 0; + + if (SDL_LockTexture(native, rect, &native_pixels, &native_pitch) < 0) { + return -1; + } + SDL_SW_CopyYUVToRGB(texture->yuv, rect, native->format, + rect->w, rect->h, native_pixels, native_pitch); + SDL_UnlockTexture(native); + } else { + /* Use a temporary buffer for updating */ + const int temp_pitch = (((rect->w * SDL_BYTESPERPIXEL(native->format)) + 3) & ~3); + const size_t alloclen = (size_t)rect->h * temp_pitch; + if (alloclen > 0) { + void *temp_pixels = SDL_malloc(alloclen); + if (!temp_pixels) { + return SDL_OutOfMemory(); + } + SDL_SW_CopyYUVToRGB(texture->yuv, rect, native->format, + rect->w, rect->h, temp_pixels, temp_pitch); + SDL_UpdateTexture(native, rect, temp_pixels, temp_pitch); + SDL_free(temp_pixels); + } + } + return 0; +} + +#endif /* SDL_HAVE_YUV */ + +int SDL_UpdateYUVTexture(SDL_Texture *texture, const SDL_Rect *rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *Uplane, int Upitch, + const Uint8 *Vplane, int Vpitch) +{ +#if SDL_HAVE_YUV + SDL_Renderer *renderer; + SDL_Rect real_rect; + + CHECK_TEXTURE_MAGIC(texture, -1); + + if (!Yplane) { + return SDL_InvalidParamError("Yplane"); + } + if (!Ypitch) { + return SDL_InvalidParamError("Ypitch"); + } + if (!Uplane) { + return SDL_InvalidParamError("Uplane"); + } + if (!Upitch) { + return SDL_InvalidParamError("Upitch"); + } + if (!Vplane) { + return SDL_InvalidParamError("Vplane"); + } + if (!Vpitch) { + return SDL_InvalidParamError("Vpitch"); + } + + if (texture->format != SDL_PIXELFORMAT_YV12 && + texture->format != SDL_PIXELFORMAT_IYUV) { + return SDL_SetError("Texture format must by YV12 or IYUV"); + } + + real_rect.x = 0; + real_rect.y = 0; + real_rect.w = texture->w; + real_rect.h = texture->h; + if (rect) { + SDL_IntersectRect(rect, &real_rect, &real_rect); + } + + if (real_rect.w == 0 || real_rect.h == 0) { + return 0; /* nothing to do. */ + } + + if (texture->yuv) { + return SDL_UpdateTextureYUVPlanar(texture, &real_rect, Yplane, Ypitch, Uplane, Upitch, Vplane, Vpitch); + } else { + SDL_assert(!texture->native); + renderer = texture->renderer; + SDL_assert(renderer->UpdateTextureYUV); + if (renderer->UpdateTextureYUV) { + if (FlushRenderCommandsIfTextureNeeded(texture) < 0) { + return -1; + } + return renderer->UpdateTextureYUV(renderer, texture, &real_rect, Yplane, Ypitch, Uplane, Upitch, Vplane, Vpitch); + } else { + return SDL_Unsupported(); + } + } +#else + return -1; +#endif +} + +int SDL_UpdateNVTexture(SDL_Texture *texture, const SDL_Rect *rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *UVplane, int UVpitch) +{ +#if SDL_HAVE_YUV + SDL_Renderer *renderer; + SDL_Rect real_rect; + + CHECK_TEXTURE_MAGIC(texture, -1); + + if (!Yplane) { + return SDL_InvalidParamError("Yplane"); + } + if (!Ypitch) { + return SDL_InvalidParamError("Ypitch"); + } + if (!UVplane) { + return SDL_InvalidParamError("UVplane"); + } + if (!UVpitch) { + return SDL_InvalidParamError("UVpitch"); + } + + if (texture->format != SDL_PIXELFORMAT_NV12 && + texture->format != SDL_PIXELFORMAT_NV21) { + return SDL_SetError("Texture format must by NV12 or NV21"); + } + + real_rect.x = 0; + real_rect.y = 0; + real_rect.w = texture->w; + real_rect.h = texture->h; + if (rect) { + SDL_IntersectRect(rect, &real_rect, &real_rect); + } + + if (real_rect.w == 0 || real_rect.h == 0) { + return 0; /* nothing to do. */ + } + + if (texture->yuv) { + return SDL_UpdateTextureNVPlanar(texture, &real_rect, Yplane, Ypitch, UVplane, UVpitch); + } else { + SDL_assert(!texture->native); + renderer = texture->renderer; + SDL_assert(renderer->UpdateTextureNV); + if (renderer->UpdateTextureNV) { + if (FlushRenderCommandsIfTextureNeeded(texture) < 0) { + return -1; + } + return renderer->UpdateTextureNV(renderer, texture, &real_rect, Yplane, Ypitch, UVplane, UVpitch); + } else { + return SDL_Unsupported(); + } + } +#else + return -1; +#endif +} + +#if SDL_HAVE_YUV +static int SDL_LockTextureYUV(SDL_Texture *texture, const SDL_Rect *rect, + void **pixels, int *pitch) +{ + return SDL_SW_LockYUVTexture(texture->yuv, rect, pixels, pitch); +} +#endif /* SDL_HAVE_YUV */ + +static int SDL_LockTextureNative(SDL_Texture *texture, const SDL_Rect *rect, + void **pixels, int *pitch) +{ + texture->locked_rect = *rect; + *pixels = (void *)((Uint8 *)texture->pixels + + rect->y * texture->pitch + + rect->x * SDL_BYTESPERPIXEL(texture->format)); + *pitch = texture->pitch; + return 0; +} + +int SDL_LockTexture(SDL_Texture *texture, const SDL_Rect *rect, + void **pixels, int *pitch) +{ + SDL_Rect full_rect; + + CHECK_TEXTURE_MAGIC(texture, -1); + + if (texture->access != SDL_TEXTUREACCESS_STREAMING) { + return SDL_SetError("SDL_LockTexture(): texture must be streaming"); + } + + if (!rect) { + full_rect.x = 0; + full_rect.y = 0; + full_rect.w = texture->w; + full_rect.h = texture->h; + rect = &full_rect; + } + +#if SDL_HAVE_YUV + if (texture->yuv) { + if (FlushRenderCommandsIfTextureNeeded(texture) < 0) { + return -1; + } + return SDL_LockTextureYUV(texture, rect, pixels, pitch); + } else +#endif + if (texture->native) { + /* Calls a real SDL_LockTexture/SDL_UnlockTexture on unlock, flushing then. */ + return SDL_LockTextureNative(texture, rect, pixels, pitch); + } else { + SDL_Renderer *renderer = texture->renderer; + if (FlushRenderCommandsIfTextureNeeded(texture) < 0) { + return -1; + } + return renderer->LockTexture(renderer, texture, rect, pixels, pitch); + } +} + +int SDL_LockTextureToSurface(SDL_Texture *texture, const SDL_Rect *rect, + SDL_Surface **surface) +{ + SDL_Rect real_rect; + void *pixels = NULL; + int pitch = 0; /* fix static analysis */ + int ret; + + if (!texture || !surface) { + return -1; + } + + real_rect.x = 0; + real_rect.y = 0; + real_rect.w = texture->w; + real_rect.h = texture->h; + if (rect) { + SDL_IntersectRect(rect, &real_rect, &real_rect); + } + + ret = SDL_LockTexture(texture, &real_rect, &pixels, &pitch); + if (ret < 0) { + return ret; + } + + texture->locked_surface = SDL_CreateRGBSurfaceWithFormatFrom(pixels, real_rect.w, real_rect.h, 0, pitch, texture->format); + if (!texture->locked_surface) { + SDL_UnlockTexture(texture); + return -1; + } + + *surface = texture->locked_surface; + return 0; +} + +#if SDL_HAVE_YUV +static void SDL_UnlockTextureYUV(SDL_Texture *texture) +{ + SDL_Texture *native = texture->native; + void *native_pixels = NULL; + int native_pitch = 0; + SDL_Rect rect; + + rect.x = 0; + rect.y = 0; + rect.w = texture->w; + rect.h = texture->h; + + if (SDL_LockTexture(native, &rect, &native_pixels, &native_pitch) < 0) { + return; + } + SDL_SW_CopyYUVToRGB(texture->yuv, &rect, native->format, + rect.w, rect.h, native_pixels, native_pitch); + SDL_UnlockTexture(native); +} +#endif /* SDL_HAVE_YUV */ + +static void SDL_UnlockTextureNative(SDL_Texture *texture) +{ + SDL_Texture *native = texture->native; + void *native_pixels = NULL; + int native_pitch = 0; + const SDL_Rect *rect = &texture->locked_rect; + const void *pixels = (void *)((Uint8 *)texture->pixels + + rect->y * texture->pitch + + rect->x * SDL_BYTESPERPIXEL(texture->format)); + int pitch = texture->pitch; + + if (SDL_LockTexture(native, rect, &native_pixels, &native_pitch) < 0) { + return; + } + SDL_ConvertPixels(rect->w, rect->h, + texture->format, pixels, pitch, + native->format, native_pixels, native_pitch); + SDL_UnlockTexture(native); +} + +void SDL_UnlockTexture(SDL_Texture *texture) +{ + CHECK_TEXTURE_MAGIC(texture, ); + + if (texture->access != SDL_TEXTUREACCESS_STREAMING) { + return; + } +#if SDL_HAVE_YUV + if (texture->yuv) { + SDL_UnlockTextureYUV(texture); + } else +#endif + if (texture->native) { + SDL_UnlockTextureNative(texture); + } else { + SDL_Renderer *renderer = texture->renderer; + renderer->UnlockTexture(renderer, texture); + } + + SDL_FreeSurface(texture->locked_surface); + texture->locked_surface = NULL; +} + +SDL_bool SDL_RenderTargetSupported(SDL_Renderer *renderer) +{ + if (!renderer || !renderer->SetRenderTarget) { + return SDL_FALSE; + } + return (renderer->info.flags & SDL_RENDERER_TARGETTEXTURE) != 0; +} + +int SDL_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture) +{ + if (!SDL_RenderTargetSupported(renderer)) { + return SDL_Unsupported(); + } + + /* texture == NULL is valid and means reset the target to the window */ + if (texture) { + CHECK_TEXTURE_MAGIC(texture, -1); + if (renderer != texture->renderer) { + return SDL_SetError("Texture was not created with this renderer"); + } + if (texture->access != SDL_TEXTUREACCESS_TARGET) { + return SDL_SetError("Texture not created with SDL_TEXTUREACCESS_TARGET"); + } + if (texture->native) { + /* Always render to the native texture */ + texture = texture->native; + } + } + + if (texture == renderer->target) { + /* Nothing to do! */ + return 0; + } + + FlushRenderCommands(renderer); /* time to send everything to the GPU! */ + + SDL_LockMutex(renderer->target_mutex); + + if (texture && !renderer->target) { + /* Make a backup of the viewport */ + renderer->viewport_backup = renderer->viewport; + renderer->clip_rect_backup = renderer->clip_rect; + renderer->clipping_enabled_backup = renderer->clipping_enabled; + renderer->scale_backup = renderer->scale; + renderer->logical_w_backup = renderer->logical_w; + renderer->logical_h_backup = renderer->logical_h; + } + renderer->target = texture; + + if (renderer->SetRenderTarget(renderer, texture) < 0) { + SDL_UnlockMutex(renderer->target_mutex); + return -1; + } + + if (texture) { + renderer->viewport.x = (double)0; + renderer->viewport.y = (double)0; + renderer->viewport.w = (double)texture->w; + renderer->viewport.h = (double)texture->h; + SDL_zero(renderer->clip_rect); + renderer->clipping_enabled = SDL_FALSE; + renderer->scale.x = 1.0f; + renderer->scale.y = 1.0f; + renderer->logical_w = texture->w; + renderer->logical_h = texture->h; + } else { + renderer->viewport = renderer->viewport_backup; + renderer->clip_rect = renderer->clip_rect_backup; + renderer->clipping_enabled = renderer->clipping_enabled_backup; + renderer->scale = renderer->scale_backup; + renderer->logical_w = renderer->logical_w_backup; + renderer->logical_h = renderer->logical_h_backup; + } + + SDL_UnlockMutex(renderer->target_mutex); + + if (QueueCmdSetViewport(renderer) < 0) { + return -1; + } + if (QueueCmdSetClipRect(renderer) < 0) { + return -1; + } + + /* All set! */ + return FlushRenderCommandsIfNotBatching(renderer); +} + +SDL_Texture *SDL_GetRenderTarget(SDL_Renderer *renderer) +{ + CHECK_RENDERER_MAGIC(renderer, NULL); + + return renderer->target; +} + +static int UpdateLogicalSize(SDL_Renderer *renderer, SDL_bool flush_viewport_cmd) +{ + int w = 1, h = 1; + float want_aspect; + float real_aspect; + float scale; + SDL_Rect viewport; + /* 0 is for letterbox, 1 is for overscan */ + int scale_policy = 0; + const char *hint; + + if (!renderer->logical_w || !renderer->logical_h) { + return 0; + } + if (SDL_GetRendererOutputSize(renderer, &w, &h) < 0) { + return -1; + } + + hint = SDL_GetHint(SDL_HINT_RENDER_LOGICAL_SIZE_MODE); + if (hint && (*hint == '1' || SDL_strcasecmp(hint, "overscan") == 0)) { +#if SDL_VIDEO_RENDER_D3D + SDL_bool overscan_supported = SDL_TRUE; + /* Unfortunately, Direct3D 9 doesn't support negative viewport numbers + which the overscan implementation relies on. + */ + if (SDL_strcasecmp(SDL_GetCurrentVideoDriver(), "direct3d") == 0) { + overscan_supported = SDL_FALSE; + } + if (overscan_supported) { + scale_policy = 1; + } +#else + scale_policy = 1; +#endif + } + + want_aspect = (float)renderer->logical_w / renderer->logical_h; + real_aspect = (float)w / h; + + /* Clear the scale because we're setting viewport in output coordinates */ + SDL_RenderSetScale(renderer, 1.0f, 1.0f); + + if (renderer->integer_scale) { + if (want_aspect > real_aspect) { + scale = (float)(w / renderer->logical_w); /* This an integer division! */ + } else { + scale = (float)(h / renderer->logical_h); /* This an integer division! */ + } + + if (scale < 1.0f) { + scale = 1.0f; + } + + viewport.w = (int)SDL_floor(renderer->logical_w * scale); + viewport.x = (w - viewport.w) / 2; + viewport.h = (int)SDL_floor(renderer->logical_h * scale); + viewport.y = (h - viewport.h) / 2; + } else if (SDL_fabs(want_aspect - real_aspect) < 0.0001) { + /* The aspect ratios are the same, just scale appropriately */ + scale = (float)w / renderer->logical_w; + + SDL_zero(viewport); + SDL_GetRendererOutputSize(renderer, &viewport.w, &viewport.h); + } else if (want_aspect > real_aspect) { + if (scale_policy == 1) { + /* We want a wider aspect ratio than is available - + zoom so logical height matches the real height + and the width will grow off the screen + */ + scale = (float)h / renderer->logical_h; + viewport.y = 0; + viewport.h = h; + viewport.w = (int)SDL_floor(renderer->logical_w * scale); + viewport.x = (w - viewport.w) / 2; + } else { + /* We want a wider aspect ratio than is available - letterbox it */ + scale = (float)w / renderer->logical_w; + viewport.x = 0; + viewport.w = w; + viewport.h = (int)SDL_floor(renderer->logical_h * scale); + viewport.y = (h - viewport.h) / 2; + } + } else { + if (scale_policy == 1) { + /* We want a narrower aspect ratio than is available - + zoom so logical width matches the real width + and the height will grow off the screen + */ + scale = (float)w / renderer->logical_w; + viewport.x = 0; + viewport.w = w; + viewport.h = (int)SDL_floor(renderer->logical_h * scale); + viewport.y = (h - viewport.h) / 2; + } else { + /* We want a narrower aspect ratio than is available - use side-bars */ + scale = (float)h / renderer->logical_h; + viewport.y = 0; + viewport.h = h; + viewport.w = (int)SDL_floor(renderer->logical_w * scale); + viewport.x = (w - viewport.w) / 2; + } + } + + /* Set the new viewport */ + renderer->viewport.x = (double)viewport.x * renderer->scale.x; + renderer->viewport.y = (double)viewport.y * renderer->scale.y; + renderer->viewport.w = (double)viewport.w * renderer->scale.x; + renderer->viewport.h = (double)viewport.h * renderer->scale.y; + QueueCmdSetViewport(renderer); + if (flush_viewport_cmd) { + FlushRenderCommandsIfNotBatching(renderer); + } + + /* Set the new scale */ + SDL_RenderSetScale(renderer, scale, scale); + + return 0; +} + +int SDL_RenderSetLogicalSize(SDL_Renderer *renderer, int w, int h) +{ + CHECK_RENDERER_MAGIC(renderer, -1); + + if (!w || !h) { + /* Clear any previous logical resolution */ + renderer->logical_w = 0; + renderer->logical_h = 0; + SDL_RenderSetViewport(renderer, NULL); + SDL_RenderSetScale(renderer, 1.0f, 1.0f); + return 0; + } + + renderer->logical_w = w; + renderer->logical_h = h; + + return UpdateLogicalSize(renderer, SDL_TRUE); +} + +void SDL_RenderGetLogicalSize(SDL_Renderer *renderer, int *w, int *h) +{ + CHECK_RENDERER_MAGIC(renderer, ); + + if (w) { + *w = renderer->logical_w; + } + if (h) { + *h = renderer->logical_h; + } +} + +int SDL_RenderSetIntegerScale(SDL_Renderer *renderer, SDL_bool enable) +{ + CHECK_RENDERER_MAGIC(renderer, -1); + + renderer->integer_scale = enable; + + return UpdateLogicalSize(renderer, SDL_TRUE); +} + +SDL_bool SDL_RenderGetIntegerScale(SDL_Renderer *renderer) +{ + CHECK_RENDERER_MAGIC(renderer, SDL_FALSE); + + return renderer->integer_scale; +} + +int SDL_RenderSetViewport(SDL_Renderer *renderer, const SDL_Rect *rect) +{ + int retval; + CHECK_RENDERER_MAGIC(renderer, -1); + + if (rect) { + renderer->viewport.x = (double)rect->x * renderer->scale.x; + renderer->viewport.y = (double)rect->y * renderer->scale.y; + renderer->viewport.w = (double)rect->w * renderer->scale.x; + renderer->viewport.h = (double)rect->h * renderer->scale.y; + } else { + int w, h; + if (SDL_GetRendererOutputSize(renderer, &w, &h) < 0) { + return -1; + } + renderer->viewport.x = 0.0; + renderer->viewport.y = 0.0; + /* NOLINTBEGIN(clang-analyzer-core.uninitialized.Assign): SDL_GetRendererOutputSize cannot fail */ + renderer->viewport.w = (double)w; + renderer->viewport.h = (double)h; + /* NOLINTEND(clang-analyzer-core.uninitialized.Assign) */ + } + retval = QueueCmdSetViewport(renderer); + return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer); +} + +void SDL_RenderGetViewport(SDL_Renderer *renderer, SDL_Rect *rect) +{ + CHECK_RENDERER_MAGIC(renderer, ); + + if (rect) { + rect->x = (int)SDL_floor(renderer->viewport.x / renderer->scale.x); + rect->y = (int)SDL_floor(renderer->viewport.y / renderer->scale.y); + rect->w = (int)SDL_floor(renderer->viewport.w / renderer->scale.x); + rect->h = (int)SDL_floor(renderer->viewport.h / renderer->scale.y); + } +} + +static void RenderGetViewportSize(SDL_Renderer *renderer, SDL_FRect *rect) +{ + rect->x = 0.0f; + rect->y = 0.0f; + rect->w = (float)(renderer->viewport.w / renderer->scale.x); + rect->h = (float)(renderer->viewport.h / renderer->scale.y); +} + +int SDL_RenderSetClipRect(SDL_Renderer *renderer, const SDL_Rect *rect) +{ + int retval; + CHECK_RENDERER_MAGIC(renderer, -1) + + if (rect && rect->w >= 0 && rect->h >= 0) { + renderer->clipping_enabled = SDL_TRUE; + renderer->clip_rect.x = (double)rect->x * renderer->scale.x; + renderer->clip_rect.y = (double)rect->y * renderer->scale.y; + renderer->clip_rect.w = (double)rect->w * renderer->scale.x; + renderer->clip_rect.h = (double)rect->h * renderer->scale.y; + } else { + renderer->clipping_enabled = SDL_FALSE; + SDL_zero(renderer->clip_rect); + } + + retval = QueueCmdSetClipRect(renderer); + return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer); +} + +void SDL_RenderGetClipRect(SDL_Renderer *renderer, SDL_Rect *rect) +{ + CHECK_RENDERER_MAGIC(renderer, ) + + if (rect) { + rect->x = (int)SDL_floor(renderer->clip_rect.x / renderer->scale.x); + rect->y = (int)SDL_floor(renderer->clip_rect.y / renderer->scale.y); + rect->w = (int)SDL_floor(renderer->clip_rect.w / renderer->scale.x); + rect->h = (int)SDL_floor(renderer->clip_rect.h / renderer->scale.y); + } +} + +SDL_bool SDL_RenderIsClipEnabled(SDL_Renderer *renderer) +{ + CHECK_RENDERER_MAGIC(renderer, SDL_FALSE) + return renderer->clipping_enabled; +} + +int SDL_RenderSetScale(SDL_Renderer *renderer, float scaleX, float scaleY) +{ + CHECK_RENDERER_MAGIC(renderer, -1); + + renderer->scale.x = scaleX; + renderer->scale.y = scaleY; + return 0; +} + +void SDL_RenderGetScale(SDL_Renderer *renderer, float *scaleX, float *scaleY) +{ + CHECK_RENDERER_MAGIC(renderer, ); + + if (scaleX) { + *scaleX = renderer->scale.x; + } + if (scaleY) { + *scaleY = renderer->scale.y; + } +} + +void SDL_RenderWindowToLogical(SDL_Renderer *renderer, int windowX, int windowY, float *logicalX, float *logicalY) +{ + float window_physical_x, window_physical_y; + + CHECK_RENDERER_MAGIC(renderer, ); + + window_physical_x = ((float)windowX) / renderer->dpi_scale.x; + window_physical_y = ((float)windowY) / renderer->dpi_scale.y; + + if (logicalX) { + *logicalX = (float)((window_physical_x - renderer->viewport.x) / renderer->scale.x); + } + if (logicalY) { + *logicalY = (float)((window_physical_y - renderer->viewport.y) / renderer->scale.y); + } +} + +void SDL_RenderLogicalToWindow(SDL_Renderer *renderer, float logicalX, float logicalY, int *windowX, int *windowY) +{ + float window_physical_x, window_physical_y; + + CHECK_RENDERER_MAGIC(renderer, ); + + window_physical_x = (float)((logicalX * renderer->scale.x) + renderer->viewport.x); + window_physical_y = (float)((logicalY * renderer->scale.y) + renderer->viewport.y); + + if (windowX) { + *windowX = (int)(window_physical_x * renderer->dpi_scale.x); + } + if (windowY) { + *windowY = (int)(window_physical_y * renderer->dpi_scale.y); + } +} + +int SDL_SetRenderDrawColor(SDL_Renderer *renderer, + Uint8 r, Uint8 g, Uint8 b, Uint8 a) +{ + CHECK_RENDERER_MAGIC(renderer, -1); + + renderer->color.r = r; + renderer->color.g = g; + renderer->color.b = b; + renderer->color.a = a; + return 0; +} + +int SDL_GetRenderDrawColor(SDL_Renderer *renderer, + Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a) +{ + CHECK_RENDERER_MAGIC(renderer, -1); + + if (r) { + *r = renderer->color.r; + } + if (g) { + *g = renderer->color.g; + } + if (b) { + *b = renderer->color.b; + } + if (a) { + *a = renderer->color.a; + } + return 0; +} + +int SDL_SetRenderDrawBlendMode(SDL_Renderer *renderer, SDL_BlendMode blendMode) +{ + CHECK_RENDERER_MAGIC(renderer, -1); + + if (!IsSupportedBlendMode(renderer, blendMode)) { + return SDL_Unsupported(); + } + renderer->blendMode = blendMode; + return 0; +} + +int SDL_GetRenderDrawBlendMode(SDL_Renderer *renderer, SDL_BlendMode *blendMode) +{ + CHECK_RENDERER_MAGIC(renderer, -1); + + *blendMode = renderer->blendMode; + return 0; +} + +int SDL_RenderClear(SDL_Renderer *renderer) +{ + int retval; + CHECK_RENDERER_MAGIC(renderer, -1); + retval = QueueCmdClear(renderer); + return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer); +} + +/* !!! FIXME: delete all the duplicate code for the integer versions in 2.1, + !!! FIXME: making the floating point versions the only available APIs. */ + +int SDL_RenderDrawPoint(SDL_Renderer *renderer, int x, int y) +{ + SDL_FPoint fpoint; + fpoint.x = (float)x; + fpoint.y = (float)y; + return SDL_RenderDrawPointsF(renderer, &fpoint, 1); +} + +int SDL_RenderDrawPointF(SDL_Renderer *renderer, float x, float y) +{ + SDL_FPoint fpoint; + fpoint.x = x; + fpoint.y = y; + return SDL_RenderDrawPointsF(renderer, &fpoint, 1); +} + +static int RenderDrawPointsWithRects(SDL_Renderer *renderer, + const SDL_Point *points, const int count) +{ + int retval; + SDL_bool isstack; + SDL_FRect *frects; + int i; + + if (count < 1) { + return 0; + } + + frects = SDL_small_alloc(SDL_FRect, count, &isstack); + if (!frects) { + return SDL_OutOfMemory(); + } + + for (i = 0; i < count; ++i) { + frects[i].x = points[i].x * renderer->scale.x; + frects[i].y = points[i].y * renderer->scale.y; + frects[i].w = renderer->scale.x; + frects[i].h = renderer->scale.y; + } + + retval = QueueCmdFillRects(renderer, frects, count); + + SDL_small_free(frects, isstack); + + return retval; +} + +int SDL_RenderDrawPoints(SDL_Renderer *renderer, + const SDL_Point *points, int count) +{ + SDL_FPoint *fpoints; + int i; + int retval; + SDL_bool isstack; + + CHECK_RENDERER_MAGIC(renderer, -1); + + if (!points) { + return SDL_InvalidParamError("SDL_RenderDrawPoints(): points"); + } + if (count < 1) { + return 0; + } + +#if DONT_DRAW_WHILE_HIDDEN + /* Don't draw while we're hidden */ + if (renderer->hidden) { + return 0; + } +#endif + + if (renderer->scale.x != 1.0f || renderer->scale.y != 1.0f) { + retval = RenderDrawPointsWithRects(renderer, points, count); + } else { + fpoints = SDL_small_alloc(SDL_FPoint, count, &isstack); + if (!fpoints) { + return SDL_OutOfMemory(); + } + for (i = 0; i < count; ++i) { + fpoints[i].x = (float)points[i].x; + fpoints[i].y = (float)points[i].y; + } + + retval = QueueCmdDrawPoints(renderer, fpoints, count); + + SDL_small_free(fpoints, isstack); + } + return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer); +} + +static int RenderDrawPointsWithRectsF(SDL_Renderer *renderer, + const SDL_FPoint *fpoints, const int count) +{ + int retval; + SDL_bool isstack; + SDL_FRect *frects; + int i; + + if (count < 1) { + return 0; + } + + frects = SDL_small_alloc(SDL_FRect, count, &isstack); + if (!frects) { + return SDL_OutOfMemory(); + } + + for (i = 0; i < count; ++i) { + frects[i].x = fpoints[i].x * renderer->scale.x; + frects[i].y = fpoints[i].y * renderer->scale.y; + frects[i].w = renderer->scale.x; + frects[i].h = renderer->scale.y; + } + + retval = QueueCmdFillRects(renderer, frects, count); + + SDL_small_free(frects, isstack); + + return retval; +} + +int SDL_RenderDrawPointsF(SDL_Renderer *renderer, + const SDL_FPoint *points, int count) +{ + int retval; + + CHECK_RENDERER_MAGIC(renderer, -1); + + if (!points) { + return SDL_InvalidParamError("SDL_RenderDrawPointsF(): points"); + } + if (count < 1) { + return 0; + } + +#if DONT_DRAW_WHILE_HIDDEN + /* Don't draw while we're hidden */ + if (renderer->hidden) { + return 0; + } +#endif + + if (renderer->scale.x != 1.0f || renderer->scale.y != 1.0f) { + retval = RenderDrawPointsWithRectsF(renderer, points, count); + } else { + retval = QueueCmdDrawPoints(renderer, points, count); + } + return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer); +} + +int SDL_RenderDrawLine(SDL_Renderer *renderer, int x1, int y1, int x2, int y2) +{ + SDL_FPoint points[2]; + points[0].x = (float)x1; + points[0].y = (float)y1; + points[1].x = (float)x2; + points[1].y = (float)y2; + return SDL_RenderDrawLinesF(renderer, points, 2); +} + +int SDL_RenderDrawLineF(SDL_Renderer *renderer, float x1, float y1, float x2, float y2) +{ + SDL_FPoint points[2]; + points[0].x = x1; + points[0].y = y1; + points[1].x = x2; + points[1].y = y2; + return SDL_RenderDrawLinesF(renderer, points, 2); +} + +static int RenderDrawLineBresenham(SDL_Renderer *renderer, int x1, int y1, int x2, int y2, SDL_bool draw_last) +{ + int i, deltax, deltay, numpixels; + int d, dinc1, dinc2; + int x, xinc1, xinc2; + int y, yinc1, yinc2; + int retval; + SDL_bool isstack; + SDL_FPoint *points; + SDL_Rect clip_rect; + + /* the backend might clip this further to the clipping rect, but we + just want a basic safety against generating millions of points for + massive lines. */ + clip_rect.x = 0; + clip_rect.y = 0; + clip_rect.w = (int) renderer->viewport.w; + clip_rect.h = (int) renderer->viewport.h; + if (!SDL_IntersectRectAndLine(&clip_rect, &x1, &y1, &x2, &y2)) { + return 0; + } + + deltax = SDL_abs(x2 - x1); + deltay = SDL_abs(y2 - y1); + + if (deltax >= deltay) { + numpixels = deltax + 1; + d = (2 * deltay) - deltax; + dinc1 = deltay * 2; + dinc2 = (deltay - deltax) * 2; + xinc1 = 1; + xinc2 = 1; + yinc1 = 0; + yinc2 = 1; + } else { + numpixels = deltay + 1; + d = (2 * deltax) - deltay; + dinc1 = deltax * 2; + dinc2 = (deltax - deltay) * 2; + xinc1 = 0; + xinc2 = 1; + yinc1 = 1; + yinc2 = 1; + } + + if (x1 > x2) { + xinc1 = -xinc1; + xinc2 = -xinc2; + } + if (y1 > y2) { + yinc1 = -yinc1; + yinc2 = -yinc2; + } + + x = x1; + y = y1; + + if (!draw_last) { + --numpixels; + } + + points = SDL_small_alloc(SDL_FPoint, numpixels, &isstack); + if (!points) { + return SDL_OutOfMemory(); + } + for (i = 0; i < numpixels; ++i) { + points[i].x = (float)x; + points[i].y = (float)y; + + if (d < 0) { + d += dinc1; + x += xinc1; + y += yinc1; + } else { + d += dinc2; + x += xinc2; + y += yinc2; + } + } + + if (renderer->scale.x != 1.0f || renderer->scale.y != 1.0f) { + retval = RenderDrawPointsWithRectsF(renderer, points, numpixels); + } else { + retval = QueueCmdDrawPoints(renderer, points, numpixels); + } + + SDL_small_free(points, isstack); + + return retval; +} + +static int RenderDrawLinesWithRectsF(SDL_Renderer *renderer, + const SDL_FPoint *points, const int count) +{ + const float scale_x = renderer->scale.x; + const float scale_y = renderer->scale.y; + SDL_FRect *frect; + SDL_FRect *frects; + int i, nrects = 0; + int retval = 0; + SDL_bool isstack; + SDL_bool drew_line = SDL_FALSE; + SDL_bool draw_last = SDL_FALSE; + + frects = SDL_small_alloc(SDL_FRect, count - 1, &isstack); + if (!frects) { + return SDL_OutOfMemory(); + } + + for (i = 0; i < count - 1; ++i) { + SDL_bool same_x = (points[i].x == points[i + 1].x); + SDL_bool same_y = (points[i].y == points[i + 1].y); + + if (i == (count - 2)) { + if (!drew_line || points[i + 1].x != points[0].x || points[i + 1].y != points[0].y) { + draw_last = SDL_TRUE; + } + } else { + if (same_x && same_y) { + continue; + } + } + if (same_x) { + const float minY = SDL_min(points[i].y, points[i + 1].y); + const float maxY = SDL_max(points[i].y, points[i + 1].y); + + frect = &frects[nrects++]; + frect->x = points[i].x * scale_x; + frect->y = minY * scale_y; + frect->w = scale_x; + frect->h = (maxY - minY + draw_last) * scale_y; + if (!draw_last && points[i + 1].y < points[i].y) { + frect->y += scale_y; + } + } else if (same_y) { + const float minX = SDL_min(points[i].x, points[i + 1].x); + const float maxX = SDL_max(points[i].x, points[i + 1].x); + + frect = &frects[nrects++]; + frect->x = minX * scale_x; + frect->y = points[i].y * scale_y; + frect->w = (maxX - minX + draw_last) * scale_x; + frect->h = scale_y; + if (!draw_last && points[i + 1].x < points[i].x) { + frect->x += scale_x; + } + } else { + retval += RenderDrawLineBresenham(renderer, (int)SDL_roundf(points[i].x), (int)SDL_roundf(points[i].y), + (int)SDL_roundf(points[i + 1].x), (int)SDL_roundf(points[i + 1].y), draw_last); + } + drew_line = SDL_TRUE; + } + + if (nrects) { + retval += QueueCmdFillRects(renderer, frects, nrects); + } + + SDL_small_free(frects, isstack); + + if (retval < 0) { + retval = -1; + } + return retval; +} + +int SDL_RenderDrawLines(SDL_Renderer *renderer, + const SDL_Point *points, int count) +{ + SDL_FPoint *fpoints; + int i; + int retval; + SDL_bool isstack; + + CHECK_RENDERER_MAGIC(renderer, -1); + + if (!points) { + return SDL_InvalidParamError("SDL_RenderDrawLines(): points"); + } + if (count < 2) { + return 0; + } + +#if DONT_DRAW_WHILE_HIDDEN + /* Don't draw while we're hidden */ + if (renderer->hidden) { + return 0; + } +#endif + + fpoints = SDL_small_alloc(SDL_FPoint, count, &isstack); + if (!fpoints) { + return SDL_OutOfMemory(); + } + + for (i = 0; i < count; ++i) { + fpoints[i].x = (float)points[i].x; + fpoints[i].y = (float)points[i].y; + } + + retval = SDL_RenderDrawLinesF(renderer, fpoints, count); + + SDL_small_free(fpoints, isstack); + + return retval; +} + +int SDL_RenderDrawLinesF(SDL_Renderer *renderer, + const SDL_FPoint *points, int count) +{ + int retval = 0; + + CHECK_RENDERER_MAGIC(renderer, -1); + + if (!points) { + return SDL_InvalidParamError("SDL_RenderDrawLinesF(): points"); + } + if (count < 2) { + return 0; + } + +#if DONT_DRAW_WHILE_HIDDEN + /* Don't draw while we're hidden */ + if (renderer->hidden) { + return 0; + } +#endif + + if (renderer->line_method == SDL_RENDERLINEMETHOD_POINTS) { + retval = RenderDrawLinesWithRectsF(renderer, points, count); + } else if (renderer->line_method == SDL_RENDERLINEMETHOD_GEOMETRY) { + SDL_bool isstack1; + SDL_bool isstack2; + const float scale_x = renderer->scale.x; + const float scale_y = renderer->scale.y; + float *xy = SDL_small_alloc(float, 4 * 2 * count, &isstack1); + int *indices = SDL_small_alloc(int, + (4) * 3 * (count - 1) + (2) * 3 * (count), &isstack2); + + if (xy && indices) { + int i; + float *ptr_xy = xy; + int *ptr_indices = indices; + const int xy_stride = 2 * sizeof(float); + int num_vertices = 4 * count; + int num_indices = 0; + const int size_indices = 4; + int cur_index = -4; + const int is_looping = (points[0].x == points[count - 1].x && points[0].y == points[count - 1].y); + SDL_FPoint p; /* previous point */ + p.x = p.y = 0.0f; + /* p q + + 0----1------ 4----5 + | \ |``\ | \ | + | \ | ` `\| \ | + 3----2-------7----6 + */ + for (i = 0; i < count; ++i) { + SDL_FPoint q = points[i]; /* current point */ + + q.x *= scale_x; + q.y *= scale_y; + + *ptr_xy++ = q.x; + *ptr_xy++ = q.y; + *ptr_xy++ = q.x + scale_x; + *ptr_xy++ = q.y; + *ptr_xy++ = q.x + scale_x; + *ptr_xy++ = q.y + scale_y; + *ptr_xy++ = q.x; + *ptr_xy++ = q.y + scale_y; + +#define ADD_TRIANGLE(i1, i2, i3) \ + *ptr_indices++ = cur_index + i1; \ + *ptr_indices++ = cur_index + i2; \ + *ptr_indices++ = cur_index + i3; \ + num_indices += 3; + + /* closed polyline, don´t draw twice the point */ + if (i || is_looping == 0) { + ADD_TRIANGLE(4, 5, 6) + ADD_TRIANGLE(4, 6, 7) + } + + /* first point only, no segment */ + if (i == 0) { + p = q; + cur_index += 4; + continue; + } + + /* draw segment */ + if (p.y == q.y) { + if (p.x < q.x) { + ADD_TRIANGLE(1, 4, 7) + ADD_TRIANGLE(1, 7, 2) + } else { + ADD_TRIANGLE(5, 0, 3) + ADD_TRIANGLE(5, 3, 6) + } + } else if (p.x == q.x) { + if (p.y < q.y) { + ADD_TRIANGLE(2, 5, 4) + ADD_TRIANGLE(2, 4, 3) + } else { + ADD_TRIANGLE(6, 1, 0) + ADD_TRIANGLE(6, 0, 7) + } + } else { + if (p.y < q.y) { + if (p.x < q.x) { + ADD_TRIANGLE(1, 5, 4) + ADD_TRIANGLE(1, 4, 2) + ADD_TRIANGLE(2, 4, 7) + ADD_TRIANGLE(2, 7, 3) + } else { + ADD_TRIANGLE(4, 0, 5) + ADD_TRIANGLE(5, 0, 3) + ADD_TRIANGLE(5, 3, 6) + ADD_TRIANGLE(6, 3, 2) + } + } else { + if (p.x < q.x) { + ADD_TRIANGLE(0, 4, 7) + ADD_TRIANGLE(0, 7, 1) + ADD_TRIANGLE(1, 7, 6) + ADD_TRIANGLE(1, 6, 2) + } else { + ADD_TRIANGLE(6, 5, 1) + ADD_TRIANGLE(6, 1, 0) + ADD_TRIANGLE(7, 6, 0) + ADD_TRIANGLE(7, 0, 3) + } + } + } + + p = q; + cur_index += 4; + } + + retval = QueueCmdGeometry(renderer, NULL, + xy, xy_stride, &renderer->color, 0 /* color_stride */, NULL, 0, + num_vertices, indices, num_indices, size_indices, + 1.0f, 1.0f); + } + + SDL_small_free(xy, isstack1); + SDL_small_free(indices, isstack2); + + } else if (renderer->scale.x != 1.0f || renderer->scale.y != 1.0f) { + retval = RenderDrawLinesWithRectsF(renderer, points, count); + } else { + retval = QueueCmdDrawLines(renderer, points, count); + } + + return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer); +} + +int SDL_RenderDrawRect(SDL_Renderer *renderer, const SDL_Rect *rect) +{ + SDL_FRect frect; + SDL_FRect *prect = NULL; + + if (rect) { + frect.x = (float)rect->x; + frect.y = (float)rect->y; + frect.w = (float)rect->w; + frect.h = (float)rect->h; + prect = &frect; + } + + return SDL_RenderDrawRectF(renderer, prect); +} + +int SDL_RenderDrawRectF(SDL_Renderer *renderer, const SDL_FRect *rect) +{ + SDL_FRect frect; + SDL_FPoint points[5]; + + CHECK_RENDERER_MAGIC(renderer, -1); + + /* If 'rect' == NULL, then outline the whole surface */ + if (!rect) { + RenderGetViewportSize(renderer, &frect); + rect = &frect; + } + + points[0].x = rect->x; + points[0].y = rect->y; + points[1].x = rect->x + rect->w - 1; + points[1].y = rect->y; + points[2].x = rect->x + rect->w - 1; + points[2].y = rect->y + rect->h - 1; + points[3].x = rect->x; + points[3].y = rect->y + rect->h - 1; + points[4].x = rect->x; + points[4].y = rect->y; + return SDL_RenderDrawLinesF(renderer, points, 5); +} + +int SDL_RenderDrawRects(SDL_Renderer *renderer, + const SDL_Rect *rects, int count) +{ + int i; + + CHECK_RENDERER_MAGIC(renderer, -1); + + if (!rects) { + return SDL_InvalidParamError("SDL_RenderDrawRects(): rects"); + } + if (count < 1) { + return 0; + } + +#if DONT_DRAW_WHILE_HIDDEN + /* Don't draw while we're hidden */ + if (renderer->hidden) { + return 0; + } +#endif + + for (i = 0; i < count; ++i) { + if (SDL_RenderDrawRect(renderer, &rects[i]) < 0) { + return -1; + } + } + return 0; +} + +int SDL_RenderDrawRectsF(SDL_Renderer *renderer, + const SDL_FRect *rects, int count) +{ + int i; + + CHECK_RENDERER_MAGIC(renderer, -1); + + if (!rects) { + return SDL_InvalidParamError("SDL_RenderDrawRectsF(): rects"); + } + if (count < 1) { + return 0; + } + +#if DONT_DRAW_WHILE_HIDDEN + /* Don't draw while we're hidden */ + if (renderer->hidden) { + return 0; + } +#endif + + for (i = 0; i < count; ++i) { + if (SDL_RenderDrawRectF(renderer, &rects[i]) < 0) { + return -1; + } + } + return 0; +} + +int SDL_RenderFillRect(SDL_Renderer *renderer, const SDL_Rect *rect) +{ + SDL_FRect frect; + + CHECK_RENDERER_MAGIC(renderer, -1); + + /* If 'rect' == NULL, then outline the whole surface */ + if (rect) { + frect.x = (float)rect->x; + frect.y = (float)rect->y; + frect.w = (float)rect->w; + frect.h = (float)rect->h; + } else { + RenderGetViewportSize(renderer, &frect); + } + return SDL_RenderFillRectsF(renderer, &frect, 1); +} + +int SDL_RenderFillRectF(SDL_Renderer *renderer, const SDL_FRect *rect) +{ + SDL_FRect frect; + + CHECK_RENDERER_MAGIC(renderer, -1); + + /* If 'rect' == NULL, then outline the whole surface */ + if (!rect) { + RenderGetViewportSize(renderer, &frect); + rect = &frect; + } + return SDL_RenderFillRectsF(renderer, rect, 1); +} + +int SDL_RenderFillRects(SDL_Renderer *renderer, + const SDL_Rect *rects, int count) +{ + SDL_FRect *frects; + int i; + int retval; + SDL_bool isstack; + + CHECK_RENDERER_MAGIC(renderer, -1); + + if (!rects) { + return SDL_InvalidParamError("SDL_RenderFillRects(): rects"); + } + if (count < 1) { + return 0; + } + +#if DONT_DRAW_WHILE_HIDDEN + /* Don't draw while we're hidden */ + if (renderer->hidden) { + return 0; + } +#endif + + frects = SDL_small_alloc(SDL_FRect, count, &isstack); + if (!frects) { + return SDL_OutOfMemory(); + } + for (i = 0; i < count; ++i) { + frects[i].x = rects[i].x * renderer->scale.x; + frects[i].y = rects[i].y * renderer->scale.y; + frects[i].w = rects[i].w * renderer->scale.x; + frects[i].h = rects[i].h * renderer->scale.y; + } + + retval = QueueCmdFillRects(renderer, frects, count); + + SDL_small_free(frects, isstack); + + return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer); +} + +int SDL_RenderFillRectsF(SDL_Renderer *renderer, + const SDL_FRect *rects, int count) +{ + SDL_FRect *frects; + int i; + int retval; + SDL_bool isstack; + + CHECK_RENDERER_MAGIC(renderer, -1); + + if (!rects) { + return SDL_InvalidParamError("SDL_RenderFillRectsF(): rects"); + } + if (count < 1) { + return 0; + } + +#if DONT_DRAW_WHILE_HIDDEN + /* Don't draw while we're hidden */ + if (renderer->hidden) { + return 0; + } +#endif + + frects = SDL_small_alloc(SDL_FRect, count, &isstack); + if (!frects) { + return SDL_OutOfMemory(); + } + for (i = 0; i < count; ++i) { + frects[i].x = rects[i].x * renderer->scale.x; + frects[i].y = rects[i].y * renderer->scale.y; + frects[i].w = rects[i].w * renderer->scale.x; + frects[i].h = rects[i].h * renderer->scale.y; + } + + retval = QueueCmdFillRects(renderer, frects, count); + + SDL_small_free(frects, isstack); + + return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer); +} + +int SDL_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *srcrect, const SDL_Rect *dstrect) +{ + SDL_FRect dstfrect; + SDL_FRect *pdstfrect = NULL; + if (dstrect) { + dstfrect.x = (float)dstrect->x; + dstfrect.y = (float)dstrect->y; + dstfrect.w = (float)dstrect->w; + dstfrect.h = (float)dstrect->h; + pdstfrect = &dstfrect; + } + return SDL_RenderCopyF(renderer, texture, srcrect, pdstfrect); +} + +int SDL_RenderCopyF(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *srcrect, const SDL_FRect *dstrect) +{ + SDL_Rect real_srcrect; + SDL_FRect real_dstrect; + int retval; + int use_rendergeometry; + + CHECK_RENDERER_MAGIC(renderer, -1); + CHECK_TEXTURE_MAGIC(texture, -1); + + if (renderer != texture->renderer) { + return SDL_SetError("Texture was not created with this renderer"); + } + +#if DONT_DRAW_WHILE_HIDDEN + /* Don't draw while we're hidden */ + if (renderer->hidden) { + return 0; + } +#endif + + use_rendergeometry = (!renderer->QueueCopy); + + real_srcrect.x = 0; + real_srcrect.y = 0; + real_srcrect.w = texture->w; + real_srcrect.h = texture->h; + if (srcrect) { + if (!SDL_IntersectRect(srcrect, &real_srcrect, &real_srcrect)) { + return 0; + } + } + + RenderGetViewportSize(renderer, &real_dstrect); + if (dstrect) { + if (!SDL_HasIntersectionF(dstrect, &real_dstrect)) { + return 0; + } + real_dstrect = *dstrect; + } + + if (texture->native) { + texture = texture->native; + } + + texture->last_command_generation = renderer->render_command_generation; + + if (use_rendergeometry) { + float xy[8]; + const int xy_stride = 2 * sizeof(float); + float uv[8]; + const int uv_stride = 2 * sizeof(float); + const int num_vertices = 4; + const int *indices = renderer->rect_index_order; + const int num_indices = 6; + const int size_indices = 4; + float minu, minv, maxu, maxv; + float minx, miny, maxx, maxy; + + minu = (float)(real_srcrect.x) / (float)texture->w; + minv = (float)(real_srcrect.y) / (float)texture->h; + maxu = (float)(real_srcrect.x + real_srcrect.w) / (float)texture->w; + maxv = (float)(real_srcrect.y + real_srcrect.h) / (float)texture->h; + + minx = real_dstrect.x; + miny = real_dstrect.y; + maxx = real_dstrect.x + real_dstrect.w; + maxy = real_dstrect.y + real_dstrect.h; + + uv[0] = minu; + uv[1] = minv; + uv[2] = maxu; + uv[3] = minv; + uv[4] = maxu; + uv[5] = maxv; + uv[6] = minu; + uv[7] = maxv; + + xy[0] = minx; + xy[1] = miny; + xy[2] = maxx; + xy[3] = miny; + xy[4] = maxx; + xy[5] = maxy; + xy[6] = minx; + xy[7] = maxy; + + retval = QueueCmdGeometry(renderer, texture, + xy, xy_stride, &texture->color, 0 /* color_stride */, uv, uv_stride, + num_vertices, + indices, num_indices, size_indices, + renderer->scale.x, renderer->scale.y); + } else { + + real_dstrect.x *= renderer->scale.x; + real_dstrect.y *= renderer->scale.y; + real_dstrect.w *= renderer->scale.x; + real_dstrect.h *= renderer->scale.y; + + retval = QueueCmdCopy(renderer, texture, &real_srcrect, &real_dstrect); + } + return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer); +} + +int SDL_RenderCopyEx(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *srcrect, const SDL_Rect *dstrect, + const double angle, const SDL_Point *center, const SDL_RendererFlip flip) +{ + SDL_FRect dstfrect; + SDL_FRect *pdstfrect = NULL; + SDL_FPoint fcenter; + SDL_FPoint *pfcenter = NULL; + + if (dstrect) { + dstfrect.x = (float)dstrect->x; + dstfrect.y = (float)dstrect->y; + dstfrect.w = (float)dstrect->w; + dstfrect.h = (float)dstrect->h; + pdstfrect = &dstfrect; + } + + if (center) { + fcenter.x = (float)center->x; + fcenter.y = (float)center->y; + pfcenter = &fcenter; + } + + return SDL_RenderCopyExF(renderer, texture, srcrect, pdstfrect, angle, pfcenter, flip); +} + +int SDL_RenderCopyExF(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *srcrect, const SDL_FRect *dstrect, + const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip) +{ + SDL_Rect real_srcrect; + SDL_FRect real_dstrect; + SDL_FPoint real_center; + int retval; + int use_rendergeometry; + + if (flip == SDL_FLIP_NONE && (int)(angle / 360) == angle / 360) { /* fast path when we don't need rotation or flipping */ + return SDL_RenderCopyF(renderer, texture, srcrect, dstrect); + } + + CHECK_RENDERER_MAGIC(renderer, -1); + CHECK_TEXTURE_MAGIC(texture, -1); + + if (renderer != texture->renderer) { + return SDL_SetError("Texture was not created with this renderer"); + } + if (!renderer->QueueCopyEx && !renderer->QueueGeometry) { + return SDL_SetError("Renderer does not support RenderCopyEx"); + } + +#if DONT_DRAW_WHILE_HIDDEN + /* Don't draw while we're hidden */ + if (renderer->hidden) { + return 0; + } +#endif + + use_rendergeometry = (!renderer->QueueCopyEx); + + real_srcrect.x = 0; + real_srcrect.y = 0; + real_srcrect.w = texture->w; + real_srcrect.h = texture->h; + if (srcrect) { + if (!SDL_IntersectRect(srcrect, &real_srcrect, &real_srcrect)) { + return 0; + } + } + + /* We don't intersect the dstrect with the viewport as RenderCopy does because of potential rotation clipping issues... TODO: should we? */ + if (dstrect) { + real_dstrect = *dstrect; + } else { + RenderGetViewportSize(renderer, &real_dstrect); + } + + if (texture->native) { + texture = texture->native; + } + + if (center) { + real_center = *center; + } else { + real_center.x = real_dstrect.w / 2.0f; + real_center.y = real_dstrect.h / 2.0f; + } + + texture->last_command_generation = renderer->render_command_generation; + + if (use_rendergeometry) { + float xy[8]; + const int xy_stride = 2 * sizeof(float); + float uv[8]; + const int uv_stride = 2 * sizeof(float); + const int num_vertices = 4; + const int *indices = renderer->rect_index_order; + const int num_indices = 6; + const int size_indices = 4; + float minu, minv, maxu, maxv; + float minx, miny, maxx, maxy; + float centerx, centery; + + float s_minx, s_miny, s_maxx, s_maxy; + float c_minx, c_miny, c_maxx, c_maxy; + + const float radian_angle = (float)((M_PI * angle) / 180.0); + const float s = SDL_sinf(radian_angle); + const float c = SDL_cosf(radian_angle); + + minu = (float)(real_srcrect.x) / (float)texture->w; + minv = (float)(real_srcrect.y) / (float)texture->h; + maxu = (float)(real_srcrect.x + real_srcrect.w) / (float)texture->w; + maxv = (float)(real_srcrect.y + real_srcrect.h) / (float)texture->h; + + centerx = real_center.x + real_dstrect.x; + centery = real_center.y + real_dstrect.y; + + if (flip & SDL_FLIP_HORIZONTAL) { + minx = real_dstrect.x + real_dstrect.w; + maxx = real_dstrect.x; + } else { + minx = real_dstrect.x; + maxx = real_dstrect.x + real_dstrect.w; + } + + if (flip & SDL_FLIP_VERTICAL) { + miny = real_dstrect.y + real_dstrect.h; + maxy = real_dstrect.y; + } else { + miny = real_dstrect.y; + maxy = real_dstrect.y + real_dstrect.h; + } + + uv[0] = minu; + uv[1] = minv; + uv[2] = maxu; + uv[3] = minv; + uv[4] = maxu; + uv[5] = maxv; + uv[6] = minu; + uv[7] = maxv; + + /* apply rotation with 2x2 matrix ( c -s ) + * ( s c ) */ + s_minx = s * (minx - centerx); + s_miny = s * (miny - centery); + s_maxx = s * (maxx - centerx); + s_maxy = s * (maxy - centery); + c_minx = c * (minx - centerx); + c_miny = c * (miny - centery); + c_maxx = c * (maxx - centerx); + c_maxy = c * (maxy - centery); + + /* (minx, miny) */ + xy[0] = (c_minx - s_miny) + centerx; + xy[1] = (s_minx + c_miny) + centery; + /* (maxx, miny) */ + xy[2] = (c_maxx - s_miny) + centerx; + xy[3] = (s_maxx + c_miny) + centery; + /* (maxx, maxy) */ + xy[4] = (c_maxx - s_maxy) + centerx; + xy[5] = (s_maxx + c_maxy) + centery; + /* (minx, maxy) */ + xy[6] = (c_minx - s_maxy) + centerx; + xy[7] = (s_minx + c_maxy) + centery; + + retval = QueueCmdGeometry(renderer, texture, + xy, xy_stride, &texture->color, 0 /* color_stride */, uv, uv_stride, + num_vertices, + indices, num_indices, size_indices, + renderer->scale.x, renderer->scale.y); + } else { + + retval = QueueCmdCopyEx(renderer, texture, &real_srcrect, &real_dstrect, angle, &real_center, flip, renderer->scale.x, renderer->scale.y); + } + return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer); +} + +int SDL_RenderGeometry(SDL_Renderer *renderer, + SDL_Texture *texture, + const SDL_Vertex *vertices, int num_vertices, + const int *indices, int num_indices) +{ + if (vertices) { + const float *xy = &vertices->position.x; + int xy_stride = sizeof(SDL_Vertex); + const SDL_Color *color = &vertices->color; + int color_stride = sizeof(SDL_Vertex); + const float *uv = &vertices->tex_coord.x; + int uv_stride = sizeof(SDL_Vertex); + int size_indices = 4; + return SDL_RenderGeometryRaw(renderer, texture, xy, xy_stride, color, color_stride, uv, uv_stride, num_vertices, indices, num_indices, size_indices); + } else { + return SDL_InvalidParamError("vertices"); + } +} + +static int remap_one_indice( + int prev, + int k, + SDL_Texture *texture, + const float *xy, int xy_stride, + const SDL_Color *color, int color_stride, + const float *uv, int uv_stride) +{ + const float *xy0_, *xy1_, *uv0_, *uv1_; + int col0_, col1_; + xy0_ = (const float *)((const char *)xy + prev * xy_stride); + xy1_ = (const float *)((const char *)xy + k * xy_stride); + if (xy0_[0] != xy1_[0]) { + return k; + } + if (xy0_[1] != xy1_[1]) { + return k; + } + if (texture) { + uv0_ = (const float *)((const char *)uv + prev * uv_stride); + uv1_ = (const float *)((const char *)uv + k * uv_stride); + if (uv0_[0] != uv1_[0]) { + return k; + } + if (uv0_[1] != uv1_[1]) { + return k; + } + } + col0_ = *(const int *)((const char *)color + prev * color_stride); + col1_ = *(const int *)((const char *)color + k * color_stride); + + if (col0_ != col1_) { + return k; + } + + return prev; +} + +static int remap_indices( + int prev[3], + int k, + SDL_Texture *texture, + const float *xy, int xy_stride, + const SDL_Color *color, int color_stride, + const float *uv, int uv_stride) +{ + int i; + if (prev[0] == -1) { + return k; + } + + for (i = 0; i < 3; i++) { + int new_k = remap_one_indice(prev[i], k, texture, xy, xy_stride, color, color_stride, uv, uv_stride); + if (new_k != k) { + return new_k; + } + } + return k; +} + +#define DEBUG_SW_RENDER_GEOMETRY 0 +/* For the software renderer, try to reinterpret triangles as SDL_Rect */ +static int SDLCALL SDL_SW_RenderGeometryRaw(SDL_Renderer *renderer, + SDL_Texture *texture, + const float *xy, int xy_stride, + const SDL_Color *color, int color_stride, + const float *uv, int uv_stride, + int num_vertices, + const void *indices, int num_indices, int size_indices) +{ + int i; + int retval = 0; + int count = indices ? num_indices : num_vertices; + int prev[3]; /* Previous triangle vertex indices */ + int texw = 0, texh = 0; + SDL_BlendMode blendMode = SDL_BLENDMODE_NONE; + Uint8 r = 0, g = 0, b = 0, a = 0; + + /* Save */ + SDL_GetRenderDrawBlendMode(renderer, &blendMode); + SDL_GetRenderDrawColor(renderer, &r, &g, &b, &a); + + if (texture) { + SDL_QueryTexture(texture, NULL, NULL, &texw, &texh); + } + + prev[0] = -1; + prev[1] = -1; + prev[2] = -1; + size_indices = indices ? size_indices : 0; + + for (i = 0; i < count; i += 3) { + int k0, k1, k2; /* Current triangle indices */ + int is_quad = 1; +#if DEBUG_SW_RENDER_GEOMETRY + int is_uniform = 1; + int is_rectangle = 1; +#endif + int A = -1; /* Top left vertex */ + int B = -1; /* Bottom right vertex */ + int C = -1; /* Third vertex of current triangle */ + int C2 = -1; /* Last, vertex of previous triangle */ + + if (size_indices == 4) { + k0 = ((const Uint32 *)indices)[i]; + k1 = ((const Uint32 *)indices)[i + 1]; + k2 = ((const Uint32 *)indices)[i + 2]; + } else if (size_indices == 2) { + k0 = ((const Uint16 *)indices)[i]; + k1 = ((const Uint16 *)indices)[i + 1]; + k2 = ((const Uint16 *)indices)[i + 2]; + } else if (size_indices == 1) { + k0 = ((const Uint8 *)indices)[i]; + k1 = ((const Uint8 *)indices)[i + 1]; + k2 = ((const Uint8 *)indices)[i + 2]; + } else { + /* Vertices were not provided by indices. Maybe some are duplicated. + * We try to indentificate the duplicates by comparing with the previous three vertices */ + k0 = remap_indices(prev, i, texture, xy, xy_stride, color, color_stride, uv, uv_stride); + k1 = remap_indices(prev, i + 1, texture, xy, xy_stride, color, color_stride, uv, uv_stride); + k2 = remap_indices(prev, i + 2, texture, xy, xy_stride, color, color_stride, uv, uv_stride); + } + + if (prev[0] == -1) { + prev[0] = k0; + prev[1] = k1; + prev[2] = k2; + continue; + } + + /* Two triangles forming a quadialateral, + * prev and current triangles must have exactly 2 common vertices */ + { + int cnt = 0, j = 3; + while (j--) { + int p = prev[j]; + if (p == k0 || p == k1 || p == k2) { + cnt++; + } + } + is_quad = (cnt == 2); + } + + /* Identify vertices */ + if (is_quad) { + const float *xy0_, *xy1_, *xy2_; + float x0, x1, x2; + float y0, y1, y2; + xy0_ = (const float *)((const char *)xy + k0 * xy_stride); + xy1_ = (const float *)((const char *)xy + k1 * xy_stride); + xy2_ = (const float *)((const char *)xy + k2 * xy_stride); + x0 = xy0_[0]; + y0 = xy0_[1]; + x1 = xy1_[0]; + y1 = xy1_[1]; + x2 = xy2_[0]; + y2 = xy2_[1]; + + /* Find top-left */ + if (x0 <= x1 && y0 <= y1) { + if (x0 <= x2 && y0 <= y2) { + A = k0; + } else { + A = k2; + } + } else { + if (x1 <= x2 && y1 <= y2) { + A = k1; + } else { + A = k2; + } + } + + /* Find bottom-right */ + if (x0 >= x1 && y0 >= y1) { + if (x0 >= x2 && y0 >= y2) { + B = k0; + } else { + B = k2; + } + } else { + if (x1 >= x2 && y1 >= y2) { + B = k1; + } else { + B = k2; + } + } + + /* Find C */ + if (k0 != A && k0 != B) { + C = k0; + } else if (k1 != A && k1 != B) { + C = k1; + } else { + C = k2; + } + + /* Find C2 */ + if (prev[0] != A && prev[0] != B) { + C2 = prev[0]; + } else if (prev[1] != A && prev[1] != B) { + C2 = prev[1]; + } else { + C2 = prev[2]; + } + + xy0_ = (const float *)((const char *)xy + A * xy_stride); + xy1_ = (const float *)((const char *)xy + B * xy_stride); + xy2_ = (const float *)((const char *)xy + C * xy_stride); + x0 = xy0_[0]; + y0 = xy0_[1]; + x1 = xy1_[0]; + y1 = xy1_[1]; + x2 = xy2_[0]; + y2 = xy2_[1]; + + /* Check if triangle A B C is rectangle */ + if ((x0 == x2 && y1 == y2) || (y0 == y2 && x1 == x2)) { + /* ok */ + } else { + is_quad = 0; +#if DEBUG_SW_RENDER_GEOMETRY + is_rectangle = 0; +#endif + } + + xy2_ = (const float *)((const char *)xy + C2 * xy_stride); + x2 = xy2_[0]; + y2 = xy2_[1]; + + /* Check if triangle A B C2 is rectangle */ + if ((x0 == x2 && y1 == y2) || (y0 == y2 && x1 == x2)) { + /* ok */ + } else { + is_quad = 0; +#if DEBUG_SW_RENDER_GEOMETRY + is_rectangle = 0; +#endif + } + } + + /* Check if uniformly colored */ + if (is_quad) { + const int col0_ = *(const int *)((const char *)color + A * color_stride); + const int col1_ = *(const int *)((const char *)color + B * color_stride); + const int col2_ = *(const int *)((const char *)color + C * color_stride); + const int col3_ = *(const int *)((const char *)color + C2 * color_stride); + if (col0_ == col1_ && col0_ == col2_ && col0_ == col3_) { + /* ok */ + } else { + is_quad = 0; +#if DEBUG_SW_RENDER_GEOMETRY + is_uniform = 0; +#endif + } + } + + /* Start rendering rect */ + if (is_quad) { + SDL_Rect s; + SDL_FRect d; + const float *xy0_, *xy1_, *uv0_, *uv1_; + SDL_Color col0_ = *(const SDL_Color *)((const char *)color + k0 * color_stride); + + xy0_ = (const float *)((const char *)xy + A * xy_stride); + xy1_ = (const float *)((const char *)xy + B * xy_stride); + + if (texture) { + uv0_ = (const float *)((const char *)uv + A * uv_stride); + uv1_ = (const float *)((const char *)uv + B * uv_stride); + s.x = (int)(uv0_[0] * texw); + s.y = (int)(uv0_[1] * texh); + s.w = (int)(uv1_[0] * texw - s.x); + s.h = (int)(uv1_[1] * texh - s.y); + } + + d.x = xy0_[0]; + d.y = xy0_[1]; + d.w = xy1_[0] - d.x; + d.h = xy1_[1] - d.y; + + /* Rect + texture */ + if (texture && s.w != 0 && s.h != 0) { + SDL_SetTextureAlphaMod(texture, col0_.a); + SDL_SetTextureColorMod(texture, col0_.r, col0_.g, col0_.b); + if (s.w > 0 && s.h > 0) { + SDL_RenderCopyF(renderer, texture, &s, &d); + } else { + int flags = 0; + if (s.w < 0) { + flags |= SDL_FLIP_HORIZONTAL; + s.w *= -1; + s.x -= s.w; + } + if (s.h < 0) { + flags |= SDL_FLIP_VERTICAL; + s.h *= -1; + s.y -= s.h; + } + SDL_RenderCopyExF(renderer, texture, &s, &d, 0, NULL, flags); + } + +#if DEBUG_SW_RENDER_GEOMETRY + SDL_Log("Rect-COPY: RGB %d %d %d - Alpha:%d - texture=%p: src=(%d,%d, %d x %d) dst (%f, %f, %f x %f)", col0_.r, col0_.g, col0_.b, col0_.a, + (void *)texture, s.x, s.y, s.w, s.h, d.x, d.y, d.w, d.h); +#endif + } else if (d.w != 0.0f && d.h != 0.0f) { /* Rect, no texture */ + SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); + SDL_SetRenderDrawColor(renderer, col0_.r, col0_.g, col0_.b, col0_.a); + SDL_RenderFillRectF(renderer, &d); +#if DEBUG_SW_RENDER_GEOMETRY + SDL_Log("Rect-FILL: RGB %d %d %d - Alpha:%d - texture=%p: dst (%f, %f, %f x %f)", col0_.r, col0_.g, col0_.b, col0_.a, + (void *)texture, d.x, d.y, d.w, d.h); + } else { + SDL_Log("Rect-DISMISS: RGB %d %d %d - Alpha:%d - texture=%p: src=(%d,%d, %d x %d) dst (%f, %f, %f x %f)", col0_.r, col0_.g, col0_.b, col0_.a, + (void *)texture, s.x, s.y, s.w, s.h, d.x, d.y, d.w, d.h); +#endif + } + + prev[0] = -1; + } else { + /* Render triangles */ + if (prev[0] != -1) { +#if DEBUG_SW_RENDER_GEOMETRY + SDL_Log("Triangle %d %d %d - is_uniform:%d is_rectangle:%d", prev[0], prev[1], prev[2], is_uniform, is_rectangle); +#endif + retval = QueueCmdGeometry(renderer, texture, + xy, xy_stride, color, color_stride, uv, uv_stride, + num_vertices, prev, 3, 4, renderer->scale.x, renderer->scale.y); + if (retval < 0) { + goto end; + } else { + FlushRenderCommandsIfNotBatching(renderer); + } + } + + prev[0] = k0; + prev[1] = k1; + prev[2] = k2; + } + } /* End for (), next triangle */ + + if (prev[0] != -1) { + /* flush the last triangle */ +#if DEBUG_SW_RENDER_GEOMETRY + SDL_Log("Last triangle %d %d %d", prev[0], prev[1], prev[2]); +#endif + retval = QueueCmdGeometry(renderer, texture, + xy, xy_stride, color, color_stride, uv, uv_stride, + num_vertices, prev, 3, 4, renderer->scale.x, renderer->scale.y); + if (retval < 0) { + goto end; + } else { + FlushRenderCommandsIfNotBatching(renderer); + } + } + +end: + /* Restore */ + SDL_SetRenderDrawBlendMode(renderer, blendMode); + SDL_SetRenderDrawColor(renderer, r, g, b, a); + + return retval; +} + +int SDL_RenderGeometryRaw(SDL_Renderer *renderer, + SDL_Texture *texture, + const float *xy, int xy_stride, + const SDL_Color *color, int color_stride, + const float *uv, int uv_stride, + int num_vertices, + const void *indices, int num_indices, int size_indices) +{ + int i; + int retval = 0; + int count = indices ? num_indices : num_vertices; + + CHECK_RENDERER_MAGIC(renderer, -1); + + if (!renderer->QueueGeometry) { + return SDL_Unsupported(); + } + + if (texture) { + CHECK_TEXTURE_MAGIC(texture, -1); + + if (renderer != texture->renderer) { + return SDL_SetError("Texture was not created with this renderer"); + } + } + + if (!xy) { + return SDL_InvalidParamError("xy"); + } + + if (!color) { + return SDL_InvalidParamError("color"); + } + + if (texture && !uv) { + return SDL_InvalidParamError("uv"); + } + + if (count % 3 != 0) { + return SDL_InvalidParamError(indices ? "num_indices" : "num_vertices"); + } + + if (indices) { + if (size_indices != 1 && size_indices != 2 && size_indices != 4) { + return SDL_InvalidParamError("size_indices"); + } + } else { + size_indices = 0; + } + +#if DONT_DRAW_WHILE_HIDDEN + /* Don't draw while we're hidden */ + if (renderer->hidden) { + return 0; + } +#endif + + if (num_vertices < 3) { + return 0; + } + + if (texture && texture->native) { + texture = texture->native; + } + + if (texture) { + for (i = 0; i < num_vertices; ++i) { + const float *uv_ = (const float *)((const char *)uv + i * uv_stride); + float u = uv_[0]; + float v = uv_[1]; + if (u < 0.0f || v < 0.0f || u > 1.0f || v > 1.0f) { + return SDL_SetError("Values of 'uv' out of bounds %f %f at %d/%d", u, v, i, num_vertices); + } + } + } + + if (indices) { + for (i = 0; i < num_indices; ++i) { + int j; + if (size_indices == 4) { + j = ((const Uint32 *)indices)[i]; + } else if (size_indices == 2) { + j = ((const Uint16 *)indices)[i]; + } else { + j = ((const Uint8 *)indices)[i]; + } + if (j < 0 || j >= num_vertices) { + return SDL_SetError("Values of 'indices' out of bounds"); + } + } + } + + if (texture) { + texture->last_command_generation = renderer->render_command_generation; + } + + /* For the software renderer, try to reinterpret triangles as SDL_Rect */ + if (renderer->info.flags & SDL_RENDERER_SOFTWARE) { + return SDL_SW_RenderGeometryRaw(renderer, texture, + xy, xy_stride, color, color_stride, uv, uv_stride, num_vertices, + indices, num_indices, size_indices); + } + + retval = QueueCmdGeometry(renderer, texture, + xy, xy_stride, color, color_stride, uv, uv_stride, + num_vertices, + indices, num_indices, size_indices, + renderer->scale.x, renderer->scale.y); + + return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer); +} + +int SDL_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect, + Uint32 format, void *pixels, int pitch) +{ + SDL_Rect real_rect; + + CHECK_RENDERER_MAGIC(renderer, -1); + + if (!renderer->RenderReadPixels) { + return SDL_Unsupported(); + } + + FlushRenderCommands(renderer); /* we need to render before we read the results. */ + + if (!format) { + if (!renderer->target) { + format = SDL_GetWindowPixelFormat(renderer->window); + } else { + format = renderer->target->format; + } + } + + real_rect.x = (int)SDL_floor(renderer->viewport.x); + real_rect.y = (int)SDL_floor(renderer->viewport.y); + real_rect.w = (int)SDL_floor(renderer->viewport.w); + real_rect.h = (int)SDL_floor(renderer->viewport.h); + if (rect) { + if (!SDL_IntersectRect(rect, &real_rect, &real_rect)) { + return 0; + } + if (real_rect.y > rect->y) { + pixels = (Uint8 *)pixels + pitch * (real_rect.y - rect->y); + } + if (real_rect.x > rect->x) { + int bpp = SDL_BYTESPERPIXEL(format); + pixels = (Uint8 *)pixels + bpp * (real_rect.x - rect->x); + } + } + + return renderer->RenderReadPixels(renderer, &real_rect, + format, pixels, pitch); +} + +static void SDL_RenderSimulateVSync(SDL_Renderer *renderer) +{ + Uint32 now, elapsed; + const Uint32 interval = renderer->simulate_vsync_interval; + + if (!interval) { + /* We can't do sub-ms delay, so just return here */ + return; + } + + now = SDL_GetTicks(); + elapsed = (now - renderer->last_present); + if (elapsed < interval) { + Uint32 duration = (interval - elapsed); + SDL_Delay(duration); + now = SDL_GetTicks(); + } + + elapsed = (now - renderer->last_present); + if (!renderer->last_present || elapsed > 1000) { + /* It's been too long, reset the presentation timeline */ + renderer->last_present = now; + } else { + renderer->last_present += (elapsed / interval) * interval; + } +} + +void SDL_RenderPresent(SDL_Renderer *renderer) +{ + SDL_bool presented = SDL_TRUE; + + CHECK_RENDERER_MAGIC(renderer, ); + + FlushRenderCommands(renderer); /* time to send everything to the GPU! */ + +#if DONT_DRAW_WHILE_HIDDEN + /* Don't present while we're hidden */ + if (renderer->hidden) { + presented = SDL_FALSE; + } else +#endif + if (renderer->RenderPresent(renderer) < 0) { + presented = SDL_FALSE; + } + + if (renderer->simulate_vsync || + (!presented && renderer->wanted_vsync)) { + SDL_RenderSimulateVSync(renderer); + } +} + +void SDL_DestroyTexture(SDL_Texture *texture) +{ + SDL_Renderer *renderer; + + CHECK_TEXTURE_MAGIC(texture, ); + + renderer = texture->renderer; + if (texture == renderer->target) { + SDL_SetRenderTarget(renderer, NULL); /* implies command queue flush */ + } else { + FlushRenderCommandsIfTextureNeeded(texture); + } + + texture->magic = NULL; + + if (texture->next) { + texture->next->prev = texture->prev; + } + if (texture->prev) { + texture->prev->next = texture->next; + } else { + renderer->textures = texture->next; + } + + if (texture->native) { + SDL_DestroyTexture(texture->native); + } +#if SDL_HAVE_YUV + if (texture->yuv) { + SDL_SW_DestroyYUVTexture(texture->yuv); + } +#endif + SDL_free(texture->pixels); + + renderer->DestroyTexture(renderer, texture); + + SDL_FreeSurface(texture->locked_surface); + texture->locked_surface = NULL; + + SDL_free(texture); +} + +void SDL_DestroyRenderer(SDL_Renderer *renderer) +{ + SDL_RenderCommand *cmd; + + CHECK_RENDERER_MAGIC(renderer, ); + + SDL_DelEventWatch(SDL_RendererEventWatch, renderer); + + if (renderer->render_commands_tail) { + renderer->render_commands_tail->next = renderer->render_commands_pool; + cmd = renderer->render_commands; + } else { + cmd = renderer->render_commands_pool; + } + + renderer->render_commands_pool = NULL; + renderer->render_commands_tail = NULL; + renderer->render_commands = NULL; + + while (cmd) { + SDL_RenderCommand *next = cmd->next; + SDL_free(cmd); + cmd = next; + } + + SDL_free(renderer->vertex_data); + + /* Free existing textures for this renderer */ + while (renderer->textures) { + SDL_Texture *tex = renderer->textures; + (void)tex; + SDL_DestroyTexture(renderer->textures); + SDL_assert(tex != renderer->textures); /* satisfy static analysis. */ + } + + if (renderer->window) { + SDL_SetWindowData(renderer->window, SDL_WINDOWRENDERDATA, NULL); + } + + /* It's no longer magical... */ + renderer->magic = NULL; + + /* Free the target mutex */ + SDL_DestroyMutex(renderer->target_mutex); + renderer->target_mutex = NULL; + + /* Free the renderer instance */ + renderer->DestroyRenderer(renderer); +} + +int SDL_GL_BindTexture(SDL_Texture *texture, float *texw, float *texh) +{ + SDL_Renderer *renderer; + + CHECK_TEXTURE_MAGIC(texture, -1); + renderer = texture->renderer; + if (texture->native) { + return SDL_GL_BindTexture(texture->native, texw, texh); + } else if (renderer && renderer->GL_BindTexture) { + FlushRenderCommandsIfTextureNeeded(texture); /* in case the app is going to mess with it. */ + return renderer->GL_BindTexture(renderer, texture, texw, texh); + } else { + return SDL_Unsupported(); + } +} + +int SDL_GL_UnbindTexture(SDL_Texture *texture) +{ + SDL_Renderer *renderer; + + CHECK_TEXTURE_MAGIC(texture, -1); + renderer = texture->renderer; + if (texture->native) { + return SDL_GL_UnbindTexture(texture->native); + } else if (renderer && renderer->GL_UnbindTexture) { + FlushRenderCommandsIfTextureNeeded(texture); /* in case the app messed with it. */ + return renderer->GL_UnbindTexture(renderer, texture); + } + + return SDL_Unsupported(); +} + +void *SDL_RenderGetMetalLayer(SDL_Renderer *renderer) +{ + CHECK_RENDERER_MAGIC(renderer, NULL); + + if (renderer->GetMetalLayer) { + FlushRenderCommands(renderer); /* in case the app is going to mess with it. */ + return renderer->GetMetalLayer(renderer); + } + return NULL; +} + +void *SDL_RenderGetMetalCommandEncoder(SDL_Renderer *renderer) +{ + CHECK_RENDERER_MAGIC(renderer, NULL); + + if (renderer->GetMetalCommandEncoder) { + FlushRenderCommands(renderer); /* in case the app is going to mess with it. */ + return renderer->GetMetalCommandEncoder(renderer); + } + return NULL; +} + +static SDL_BlendMode SDL_GetShortBlendMode(SDL_BlendMode blendMode) +{ + if (blendMode == SDL_BLENDMODE_NONE_FULL) { + return SDL_BLENDMODE_NONE; + } + if (blendMode == SDL_BLENDMODE_BLEND_FULL) { + return SDL_BLENDMODE_BLEND; + } + if (blendMode == SDL_BLENDMODE_ADD_FULL) { + return SDL_BLENDMODE_ADD; + } + if (blendMode == SDL_BLENDMODE_MOD_FULL) { + return SDL_BLENDMODE_MOD; + } + if (blendMode == SDL_BLENDMODE_MUL_FULL) { + return SDL_BLENDMODE_MUL; + } + return blendMode; +} + +static SDL_BlendMode SDL_GetLongBlendMode(SDL_BlendMode blendMode) +{ + if (blendMode == SDL_BLENDMODE_NONE) { + return SDL_BLENDMODE_NONE_FULL; + } + if (blendMode == SDL_BLENDMODE_BLEND) { + return SDL_BLENDMODE_BLEND_FULL; + } + if (blendMode == SDL_BLENDMODE_ADD) { + return SDL_BLENDMODE_ADD_FULL; + } + if (blendMode == SDL_BLENDMODE_MOD) { + return SDL_BLENDMODE_MOD_FULL; + } + if (blendMode == SDL_BLENDMODE_MUL) { + return SDL_BLENDMODE_MUL_FULL; + } + return blendMode; +} + +SDL_BlendMode SDL_ComposeCustomBlendMode(SDL_BlendFactor srcColorFactor, SDL_BlendFactor dstColorFactor, + SDL_BlendOperation colorOperation, + SDL_BlendFactor srcAlphaFactor, SDL_BlendFactor dstAlphaFactor, + SDL_BlendOperation alphaOperation) +{ + SDL_BlendMode blendMode = SDL_COMPOSE_BLENDMODE(srcColorFactor, dstColorFactor, colorOperation, + srcAlphaFactor, dstAlphaFactor, alphaOperation); + return SDL_GetShortBlendMode(blendMode); +} + +SDL_BlendFactor SDL_GetBlendModeSrcColorFactor(SDL_BlendMode blendMode) +{ + blendMode = SDL_GetLongBlendMode(blendMode); + return (SDL_BlendFactor)(((Uint32)blendMode >> 4) & 0xF); +} + +SDL_BlendFactor SDL_GetBlendModeDstColorFactor(SDL_BlendMode blendMode) +{ + blendMode = SDL_GetLongBlendMode(blendMode); + return (SDL_BlendFactor)(((Uint32)blendMode >> 8) & 0xF); +} + +SDL_BlendOperation SDL_GetBlendModeColorOperation(SDL_BlendMode blendMode) +{ + blendMode = SDL_GetLongBlendMode(blendMode); + return (SDL_BlendOperation)(((Uint32)blendMode >> 0) & 0xF); +} + +SDL_BlendFactor SDL_GetBlendModeSrcAlphaFactor(SDL_BlendMode blendMode) +{ + blendMode = SDL_GetLongBlendMode(blendMode); + return (SDL_BlendFactor)(((Uint32)blendMode >> 20) & 0xF); +} + +SDL_BlendFactor SDL_GetBlendModeDstAlphaFactor(SDL_BlendMode blendMode) +{ + blendMode = SDL_GetLongBlendMode(blendMode); + return (SDL_BlendFactor)(((Uint32)blendMode >> 24) & 0xF); +} + +SDL_BlendOperation SDL_GetBlendModeAlphaOperation(SDL_BlendMode blendMode) +{ + blendMode = SDL_GetLongBlendMode(blendMode); + return (SDL_BlendOperation)(((Uint32)blendMode >> 16) & 0xF); +} + +int SDL_RenderSetVSync(SDL_Renderer *renderer, int vsync) +{ + CHECK_RENDERER_MAGIC(renderer, -1); + + if (vsync != 0 && vsync != 1) { + return SDL_Unsupported(); + } + + renderer->wanted_vsync = vsync ? SDL_TRUE : SDL_FALSE; + + if (!renderer->SetVSync || + renderer->SetVSync(renderer, vsync) != 0) { + renderer->simulate_vsync = vsync ? SDL_TRUE : SDL_FALSE; + if (renderer->simulate_vsync) { + renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; + } else { + renderer->info.flags &= ~SDL_RENDERER_PRESENTVSYNC; + } + } else { + renderer->simulate_vsync = SDL_FALSE; + } + return 0; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/render/SDL_sysrender.h b/SDL2-2.30.5/src/render/SDL_sysrender.h new file mode 100644 index 0000000..a4eef4d --- /dev/null +++ b/SDL2-2.30.5/src/render/SDL_sysrender.h @@ -0,0 +1,334 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifndef SDL_sysrender_h_ +#define SDL_sysrender_h_ + +#include "SDL_render.h" +#include "SDL_events.h" +#include "SDL_mutex.h" +#include "SDL_yuv_sw_c.h" + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * A rectangle, with the origin at the upper left (double precision). + */ +typedef struct SDL_DRect +{ + double x; + double y; + double w; + double h; +} SDL_DRect; + +/* The SDL 2D rendering system */ + +typedef struct SDL_RenderDriver SDL_RenderDriver; + +/* Define the SDL texture structure */ +struct SDL_Texture +{ + const void *magic; + Uint32 format; /**< The pixel format of the texture */ + int access; /**< SDL_TextureAccess */ + int w; /**< The width of the texture */ + int h; /**< The height of the texture */ + int modMode; /**< The texture modulation mode */ + SDL_BlendMode blendMode; /**< The texture blend mode */ + SDL_ScaleMode scaleMode; /**< The texture scale mode */ + SDL_Color color; /**< Texture modulation values */ + + SDL_Renderer *renderer; + + /* Support for formats not supported directly by the renderer */ + SDL_Texture *native; + SDL_SW_YUVTexture *yuv; + void *pixels; + int pitch; + SDL_Rect locked_rect; + SDL_Surface *locked_surface; /**< Locked region exposed as a SDL surface */ + + Uint32 last_command_generation; /* last command queue generation this texture was in. */ + + void *driverdata; /**< Driver specific texture representation */ + void *userdata; + + SDL_Texture *prev; + SDL_Texture *next; +}; + +typedef enum +{ + SDL_RENDERCMD_NO_OP, + SDL_RENDERCMD_SETVIEWPORT, + SDL_RENDERCMD_SETCLIPRECT, + SDL_RENDERCMD_SETDRAWCOLOR, + SDL_RENDERCMD_CLEAR, + SDL_RENDERCMD_DRAW_POINTS, + SDL_RENDERCMD_DRAW_LINES, + SDL_RENDERCMD_FILL_RECTS, + SDL_RENDERCMD_COPY, + SDL_RENDERCMD_COPY_EX, + SDL_RENDERCMD_GEOMETRY +} SDL_RenderCommandType; + +typedef struct SDL_RenderCommand +{ + SDL_RenderCommandType command; + union + { + struct + { + size_t first; + SDL_Rect rect; + } viewport; + struct + { + SDL_bool enabled; + SDL_Rect rect; + } cliprect; + struct + { + size_t first; + size_t count; + Uint8 r, g, b, a; + SDL_BlendMode blend; + SDL_Texture *texture; + } draw; + struct + { + size_t first; + Uint8 r, g, b, a; + } color; + } data; + struct SDL_RenderCommand *next; +} SDL_RenderCommand; + +typedef struct SDL_VertexSolid +{ + SDL_FPoint position; + SDL_Color color; +} SDL_VertexSolid; + +typedef enum +{ + SDL_RENDERLINEMETHOD_POINTS, + SDL_RENDERLINEMETHOD_LINES, + SDL_RENDERLINEMETHOD_GEOMETRY, +} SDL_RenderLineMethod; + +/* Define the SDL renderer structure */ +struct SDL_Renderer +{ + const void *magic; + + void (*WindowEvent)(SDL_Renderer *renderer, const SDL_WindowEvent *event); + int (*GetOutputSize)(SDL_Renderer *renderer, int *w, int *h); + SDL_bool (*SupportsBlendMode)(SDL_Renderer *renderer, SDL_BlendMode blendMode); + int (*CreateTexture)(SDL_Renderer *renderer, SDL_Texture *texture); + int (*QueueSetViewport)(SDL_Renderer *renderer, SDL_RenderCommand *cmd); + int (*QueueSetDrawColor)(SDL_Renderer *renderer, SDL_RenderCommand *cmd); + int (*QueueDrawPoints)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, + int count); + int (*QueueDrawLines)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, + int count); + int (*QueueFillRects)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FRect *rects, + int count); + int (*QueueCopy)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, + const SDL_Rect *srcrect, const SDL_FRect *dstrect); + int (*QueueCopyEx)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, + const SDL_Rect *srcquad, const SDL_FRect *dstrect, + const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip, float scale_x, float scale_y); + int (*QueueGeometry)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, + const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride, + int num_vertices, const void *indices, int num_indices, int size_indices, + float scale_x, float scale_y); + + int (*RunCommandQueue)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize); + int (*UpdateTexture)(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *rect, const void *pixels, + int pitch); +#if SDL_HAVE_YUV + int (*UpdateTextureYUV)(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *Uplane, int Upitch, + const Uint8 *Vplane, int Vpitch); + int (*UpdateTextureNV)(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *UVplane, int UVpitch); +#endif + int (*LockTexture)(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *rect, void **pixels, int *pitch); + void (*UnlockTexture)(SDL_Renderer *renderer, SDL_Texture *texture); + void (*SetTextureScaleMode)(SDL_Renderer *renderer, SDL_Texture *texture, SDL_ScaleMode scaleMode); + int (*SetRenderTarget)(SDL_Renderer *renderer, SDL_Texture *texture); + int (*RenderReadPixels)(SDL_Renderer *renderer, const SDL_Rect *rect, + Uint32 format, void *pixels, int pitch); + int (*RenderPresent)(SDL_Renderer *renderer); + void (*DestroyTexture)(SDL_Renderer *renderer, SDL_Texture *texture); + + void (*DestroyRenderer)(SDL_Renderer *renderer); + + int (*SetVSync)(SDL_Renderer *renderer, int vsync); + + int (*GL_BindTexture)(SDL_Renderer *renderer, SDL_Texture *texture, float *texw, float *texh); + int (*GL_UnbindTexture)(SDL_Renderer *renderer, SDL_Texture *texture); + + void *(*GetMetalLayer)(SDL_Renderer *renderer); + void *(*GetMetalCommandEncoder)(SDL_Renderer *renderer); + + /* The current renderer info */ + SDL_RendererInfo info; + + /* The window associated with the renderer */ + SDL_Window *window; + SDL_bool hidden; + + /* Whether we should simulate vsync */ + SDL_bool wanted_vsync; + SDL_bool simulate_vsync; + Uint32 simulate_vsync_interval; + Uint32 last_present; + + /* The logical resolution for rendering */ + int logical_w; + int logical_h; + int logical_w_backup; + int logical_h_backup; + + /* Whether or not to force the viewport to even integer intervals */ + SDL_bool integer_scale; + + /* The drawable area within the window */ + SDL_DRect viewport; + SDL_DRect viewport_backup; + + /* The clip rectangle within the window */ + SDL_DRect clip_rect; + SDL_DRect clip_rect_backup; + + /* Whether or not the clipping rectangle is used. */ + SDL_bool clipping_enabled; + SDL_bool clipping_enabled_backup; + + /* The render output coordinate scale */ + SDL_FPoint scale; + SDL_FPoint scale_backup; + + /* The pixel to point coordinate scale */ + SDL_FPoint dpi_scale; + + /* Whether or not to scale relative mouse motion */ + SDL_bool relative_scaling; + + /* The method of drawing lines */ + SDL_RenderLineMethod line_method; + + /* List of triangle indices to draw rects */ + int rect_index_order[6]; + + /* Remainder from scaled relative motion */ + float xrel; + float yrel; + + /* The list of textures */ + SDL_Texture *textures; + SDL_Texture *target; + SDL_mutex *target_mutex; + + SDL_Color color; /**< Color for drawing operations values */ + SDL_BlendMode blendMode; /**< The drawing blend mode */ + + SDL_bool always_batch; + SDL_bool batching; + SDL_RenderCommand *render_commands; + SDL_RenderCommand *render_commands_tail; + SDL_RenderCommand *render_commands_pool; + Uint32 render_command_generation; + Uint32 last_queued_color; + SDL_DRect last_queued_viewport; + SDL_DRect last_queued_cliprect; + SDL_bool last_queued_cliprect_enabled; + SDL_bool color_queued; + SDL_bool viewport_queued; + SDL_bool cliprect_queued; + + void *vertex_data; + size_t vertex_data_used; + size_t vertex_data_allocation; + + void *driverdata; +}; + +/* Define the SDL render driver structure */ +struct SDL_RenderDriver +{ + SDL_Renderer *(*CreateRenderer)(SDL_Window *window, Uint32 flags); + + /* Info about the renderer capabilities */ + SDL_RendererInfo info; +}; + +/* Not all of these are available in a given build. Use #ifdefs, etc. */ +extern SDL_RenderDriver D3D_RenderDriver; +extern SDL_RenderDriver D3D11_RenderDriver; +extern SDL_RenderDriver D3D12_RenderDriver; +extern SDL_RenderDriver GL_RenderDriver; +extern SDL_RenderDriver GLES2_RenderDriver; +extern SDL_RenderDriver GLES_RenderDriver; +extern SDL_RenderDriver DirectFB_RenderDriver; +extern SDL_RenderDriver METAL_RenderDriver; +extern SDL_RenderDriver PS2_RenderDriver; +extern SDL_RenderDriver PSP_RenderDriver; +extern SDL_RenderDriver SW_RenderDriver; +extern SDL_RenderDriver VITA_GXM_RenderDriver; + +/* Blend mode functions */ +extern SDL_BlendFactor SDL_GetBlendModeSrcColorFactor(SDL_BlendMode blendMode); +extern SDL_BlendFactor SDL_GetBlendModeDstColorFactor(SDL_BlendMode blendMode); +extern SDL_BlendOperation SDL_GetBlendModeColorOperation(SDL_BlendMode blendMode); +extern SDL_BlendFactor SDL_GetBlendModeSrcAlphaFactor(SDL_BlendMode blendMode); +extern SDL_BlendFactor SDL_GetBlendModeDstAlphaFactor(SDL_BlendMode blendMode); +extern SDL_BlendOperation SDL_GetBlendModeAlphaOperation(SDL_BlendMode blendMode); + +/* drivers call this during their Queue*() methods to make space in a array that are used + for a vertex buffer during RunCommandQueue(). Pointers returned here are only valid until + the next call, because it might be in an array that gets realloc()'d. */ +extern void *SDL_AllocateRenderVertices(SDL_Renderer *renderer, const size_t numbytes, const size_t alignment, size_t *offset); + +extern int SDL_PrivateLowerBlitScaled(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect, SDL_ScaleMode scaleMode); +extern int SDL_PrivateUpperBlitScaled(SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect, SDL_ScaleMode scaleMode); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif + +#endif /* SDL_sysrender_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/render/SDL_yuv_sw.c b/SDL2-2.30.5/src/render/SDL_yuv_sw.c similarity index 60% rename from SDL2-2.0.12/src/render/SDL_yuv_sw.c rename to SDL2-2.30.5/src/render/SDL_yuv_sw.c index c0cae26..903279b 100644 --- a/SDL2-2.0.12/src/render/SDL_yuv_sw.c +++ b/SDL2-2.30.5/src/render/SDL_yuv_sw.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -24,13 +24,11 @@ #if SDL_HAVE_YUV -#include "SDL_assert.h" - #include "SDL_yuv_sw_c.h" +#include "../video/SDL_yuv_c.h" +#include "SDL_cpuinfo.h" - -SDL_SW_YUVTexture * -SDL_SW_CreateYUVTexture(Uint32 format, int w, int h) +SDL_SW_YUVTexture *SDL_SW_CreateYUVTexture(Uint32 format, int w, int h) { SDL_SW_YUVTexture *swdata; @@ -48,7 +46,7 @@ SDL_SW_CreateYUVTexture(Uint32 format, int w, int h) return NULL; } - swdata = (SDL_SW_YUVTexture *) SDL_calloc(1, sizeof(*swdata)); + swdata = (SDL_SW_YUVTexture *)SDL_calloc(1, sizeof(*swdata)); if (!swdata) { SDL_OutOfMemory(); return NULL; @@ -59,33 +57,13 @@ SDL_SW_CreateYUVTexture(Uint32 format, int w, int h) swdata->w = w; swdata->h = h; { - 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; + size_t dst_size; + if (SDL_CalculateYUVSize(format, w, h, &dst_size, NULL) < 0) { + SDL_SW_DestroyYUVTexture(swdata); + SDL_OutOfMemory(); + return NULL; } - swdata->pixels = (Uint8 *) SDL_malloc(dst_size); + swdata->pixels = (Uint8 *)SDL_SIMDAlloc(dst_size); if (!swdata->pixels) { SDL_SW_DestroyYUVTexture(swdata); SDL_OutOfMemory(); @@ -125,36 +103,34 @@ SDL_SW_CreateYUVTexture(Uint32 format, int w, int h) } /* We're all done.. */ - return (swdata); + return swdata; } -int -SDL_SW_QueryYUVTexturePixels(SDL_SW_YUVTexture * swdata, void **pixels, - int *pitch) +int SDL_SW_QueryYUVTexturePixels(SDL_SW_YUVTexture *swdata, void **pixels, + int *pitch) { *pixels = swdata->planes[0]; *pitch = swdata->pitches[0]; return 0; } -int -SDL_SW_UpdateYUVTexture(SDL_SW_YUVTexture * swdata, const SDL_Rect * rect, - const void *pixels, int pitch) +int SDL_SW_UpdateYUVTexture(SDL_SW_YUVTexture *swdata, const SDL_Rect *rect, + const void *pixels, int pitch) { switch (swdata->format) { case SDL_PIXELFORMAT_YV12: case SDL_PIXELFORMAT_IYUV: 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)); + SDL_memcpy(swdata->pixels, pixels, + (size_t)(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; + src = (Uint8 *)pixels; dst = swdata->pixels + rect->y * swdata->w + rect->x; length = rect->w; for (row = 0; row < rect->h; ++row) { @@ -162,94 +138,92 @@ 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; + src = (Uint8 *)pixels + rect->h * pitch; dst = swdata->pixels + swdata->h * swdata->w; - dst += rect->y/2 * ((swdata->w + 1) / 2) + rect->x/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) { + for (row = 0; row < (rect->h + 1) / 2; ++row) { SDL_memcpy(dst, src, length); - src += (pitch + 1)/2; - dst += (swdata->w + 1)/2; + src += (pitch + 1) / 2; + dst += (swdata->w + 1) / 2; } /* Copy the next plane */ - src = (Uint8 *) pixels + rect->h * pitch + ((rect->h + 1) / 2) * ((pitch + 1) / 2); + src = (Uint8 *)pixels + rect->h * pitch + ((rect->h + 1) / 2) * ((pitch + 1) / 2); dst = swdata->pixels + swdata->h * swdata->w + - ((swdata->h + 1)/2) * ((swdata->w+1) / 2); - dst += rect->y/2 * ((swdata->w + 1)/2) + rect->x/2; + ((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) { + for (row = 0; row < (rect->h + 1) / 2; ++row) { SDL_memcpy(dst, src, length); - src += (pitch + 1)/2; - dst += (swdata->w + 1)/2; + src += (pitch + 1) / 2; + dst += (swdata->w + 1) / 2; } } break; case SDL_PIXELFORMAT_YUY2: case SDL_PIXELFORMAT_UYVY: case SDL_PIXELFORMAT_YVYU: - { + { + Uint8 *src, *dst; + int row; + size_t length; + + src = (Uint8 *)pixels; + dst = + swdata->planes[0] + rect->y * swdata->pitches[0] + + rect->x * 2; + length = 4 * (((size_t)rect->w + 1) / 2); + for (row = 0; row < rect->h; ++row) { + SDL_memcpy(dst, src, length); + src += pitch; + dst += swdata->pitches[0]; + } + } 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, + (size_t)(swdata->h * swdata->w) + 2 * ((swdata->h + 1) / 2) * ((swdata->w + 1) / 2)); + } else { + Uint8 *src, *dst; int row; size_t length; - src = (Uint8 *) pixels; - dst = - swdata->planes[0] + rect->y * swdata->pitches[0] + - rect->x * 2; - length = 4 * ((rect->w + 1) / 2); + /* 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->pitches[0]; - } - } - 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); - } + 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 * (((size_t)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); } } } + } return 0; } -int -SDL_SW_UpdateYUVTexturePlanar(SDL_SW_YUVTexture * swdata, const SDL_Rect * rect, - const Uint8 *Yplane, int Ypitch, - const Uint8 *Uplane, int Upitch, - const Uint8 *Vplane, int Vpitch) +int SDL_SW_UpdateYUVTexturePlanar(SDL_SW_YUVTexture *swdata, const SDL_Rect *rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *Uplane, int Upitch, + const Uint8 *Vplane, int Vpitch) { const Uint8 *src; Uint8 *dst; @@ -274,12 +248,12 @@ SDL_SW_UpdateYUVTexturePlanar(SDL_SW_YUVTexture * swdata, const SDL_Rect * rect, dst = swdata->pixels + swdata->h * swdata->w + ((swdata->h + 1) / 2) * ((swdata->w + 1) / 2); } - dst += rect->y/2 * ((swdata->w + 1)/2) + rect->x/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) { + for (row = 0; row < (rect->h + 1) / 2; ++row) { SDL_memcpy(dst, src, length); src += Upitch; - dst += (swdata->w + 1)/2; + dst += (swdata->w + 1) / 2; } /* Copy the V plane */ @@ -290,30 +264,60 @@ SDL_SW_UpdateYUVTexturePlanar(SDL_SW_YUVTexture * swdata, const SDL_Rect * rect, dst = swdata->pixels + swdata->h * swdata->w + ((swdata->h + 1) / 2) * ((swdata->w + 1) / 2); } - dst += rect->y/2 * ((swdata->w + 1)/2) + rect->x/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) { + for (row = 0; row < (rect->h + 1) / 2; ++row) { SDL_memcpy(dst, src, length); src += Vpitch; - dst += (swdata->w + 1)/2; + dst += (swdata->w + 1) / 2; } return 0; } -int -SDL_SW_LockYUVTexture(SDL_SW_YUVTexture * swdata, const SDL_Rect * rect, - void **pixels, int *pitch) +int SDL_SW_UpdateNVTexturePlanar(SDL_SW_YUVTexture *swdata, const SDL_Rect *rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *UVplane, int UVpitch) +{ + const Uint8 *src; + Uint8 *dst; + int row; + size_t length; + + /* Copy the Y plane */ + src = Yplane; + 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 += Ypitch; + dst += swdata->w; + } + + /* Copy the UV or VU plane */ + src = UVplane; + dst = swdata->pixels + swdata->h * swdata->w; + dst += rect->y * ((swdata->w + 1) / 2) + rect->x; + length = (rect->w + 1) / 2; + length *= 2; + for (row = 0; row < (rect->h + 1) / 2; ++row) { + SDL_memcpy(dst, src, length); + src += UVpitch; + dst += 2 * ((swdata->w + 1) / 2); + } + + return 0; +} + +int SDL_SW_LockYUVTexture(SDL_SW_YUVTexture *swdata, const SDL_Rect *rect, + void **pixels, int *pitch) { 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, IYUV, NV12, NV21 textures only support full surface locks"); + if (rect && (rect->x != 0 || rect->y != 0 || rect->w != swdata->w || rect->h != swdata->h)) { + return SDL_SetError("YV12, IYUV, NV12, NV21 textures only support full surface locks"); } break; } @@ -327,15 +331,13 @@ SDL_SW_LockYUVTexture(SDL_SW_YUVTexture * swdata, const SDL_Rect * rect, return 0; } -void -SDL_SW_UnlockYUVTexture(SDL_SW_YUVTexture * swdata) +void SDL_SW_UnlockYUVTexture(SDL_SW_YUVTexture *swdata) { } -int -SDL_SW_CopyYUVToRGB(SDL_SW_YUVTexture * swdata, const SDL_Rect * srcrect, - Uint32 target_format, int w, int h, void *pixels, - int pitch) +int SDL_SW_CopyYUVToRGB(SDL_SW_YUVTexture *swdata, const SDL_Rect *srcrect, + Uint32 target_format, int w, int h, void *pixels, + int pitch) { int stretch; @@ -373,7 +375,7 @@ SDL_SW_CopyYUVToRGB(SDL_SW_YUVTexture * swdata, const SDL_Rect * srcrect, SDL_CreateRGBSurfaceFrom(pixels, w, h, bpp, pitch, Rmask, Gmask, Bmask, Amask); if (!swdata->display) { - return (-1); + return -1; } } if (!swdata->stretch) { @@ -384,14 +386,14 @@ SDL_SW_CopyYUVToRGB(SDL_SW_YUVTexture * swdata, const SDL_Rect * srcrect, SDL_CreateRGBSurface(0, swdata->w, swdata->h, bpp, Rmask, Gmask, Bmask, Amask); if (!swdata->stretch) { - return (-1); + return -1; } } pixels = swdata->stretch->pixels; pitch = swdata->stretch->pitch; } if (SDL_ConvertPixels(swdata->w, swdata->h, swdata->format, - swdata->planes[0], swdata->pitches[0], + swdata->planes[0], swdata->pitches[0], target_format, pixels, pitch) < 0) { return -1; } @@ -402,11 +404,10 @@ SDL_SW_CopyYUVToRGB(SDL_SW_YUVTexture * swdata, const SDL_Rect * srcrect, return 0; } -void -SDL_SW_DestroyYUVTexture(SDL_SW_YUVTexture * swdata) +void SDL_SW_DestroyYUVTexture(SDL_SW_YUVTexture *swdata) { if (swdata) { - SDL_free(swdata->pixels); + SDL_SIMDFree(swdata->pixels); SDL_FreeSurface(swdata->stretch); SDL_FreeSurface(swdata->display); SDL_free(swdata); diff --git a/SDL2-2.0.12/src/render/SDL_yuv_sw_c.h b/SDL2-2.30.5/src/render/SDL_yuv_sw_c.h similarity index 71% rename from SDL2-2.0.12/src/render/SDL_yuv_sw_c.h rename to SDL2-2.30.5/src/render/SDL_yuv_sw_c.h index 75c6f27..c123c51 100644 --- a/SDL2-2.0.12/src/render/SDL_yuv_sw_c.h +++ b/SDL2-2.30.5/src/render/SDL_yuv_sw_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -47,26 +47,24 @@ struct SDL_SW_YUVTexture typedef struct SDL_SW_YUVTexture SDL_SW_YUVTexture; SDL_SW_YUVTexture *SDL_SW_CreateYUVTexture(Uint32 format, int w, int h); -int SDL_SW_QueryYUVTexturePixels(SDL_SW_YUVTexture * swdata, void **pixels, +int SDL_SW_QueryYUVTexturePixels(SDL_SW_YUVTexture *swdata, void **pixels, int *pitch); -int SDL_SW_UpdateYUVTexture(SDL_SW_YUVTexture * swdata, const SDL_Rect * rect, +int SDL_SW_UpdateYUVTexture(SDL_SW_YUVTexture *swdata, const SDL_Rect *rect, const void *pixels, int pitch); -int SDL_SW_UpdateYUVTexturePlanar(SDL_SW_YUVTexture * swdata, const SDL_Rect * rect, +int SDL_SW_UpdateYUVTexturePlanar(SDL_SW_YUVTexture *swdata, const SDL_Rect *rect, const Uint8 *Yplane, int Ypitch, const Uint8 *Uplane, int Upitch, const Uint8 *Vplane, int Vpitch); -int SDL_SW_LockYUVTexture(SDL_SW_YUVTexture * swdata, const SDL_Rect * rect, +int SDL_SW_UpdateNVTexturePlanar(SDL_SW_YUVTexture *swdata, const SDL_Rect *rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *UVplane, int UVpitch); +int SDL_SW_LockYUVTexture(SDL_SW_YUVTexture *swdata, const SDL_Rect *rect, void **pixels, int *pitch); -void SDL_SW_UnlockYUVTexture(SDL_SW_YUVTexture * swdata); -int SDL_SW_CopyYUVToRGB(SDL_SW_YUVTexture * swdata, const SDL_Rect * srcrect, +void SDL_SW_UnlockYUVTexture(SDL_SW_YUVTexture *swdata); +int SDL_SW_CopyYUVToRGB(SDL_SW_YUVTexture *swdata, const SDL_Rect *srcrect, Uint32 target_format, int w, int h, void *pixels, int pitch); -void SDL_SW_DestroyYUVTexture(SDL_SW_YUVTexture * swdata); - -/* FIXME: This breaks on various versions of GCC and should be rewritten using intrinsics */ -#if 0 /* (__GNUC__ > 2) && defined(__i386__) && __OPTIMIZE__ && SDL_ASSEMBLY_ROUTINES && !defined(__clang__) */ -#define USE_MMX_ASSEMBLY 1 -#endif +void SDL_SW_DestroyYUVTexture(SDL_SW_YUVTexture *swdata); #endif /* SDL_yuv_sw_c_h_ */ diff --git a/SDL2-2.0.12/src/render/direct3d/SDL_render_d3d.c b/SDL2-2.30.5/src/render/direct3d/SDL_render_d3d.c similarity index 64% rename from SDL2-2.0.12/src/render/direct3d/SDL_render_d3d.c rename to SDL2-2.30.5/src/render/direct3d/SDL_render_d3d.c index f04a50a..f117bd6 100644 --- a/SDL2-2.0.12/src/render/direct3d/SDL_render_d3d.c +++ b/SDL2-2.30.5/src/render/direct3d/SDL_render_d3d.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,15 +23,13 @@ #include "SDL_render.h" #include "SDL_system.h" -#if SDL_VIDEO_RENDER_D3D && !SDL_RENDER_DISABLED +#if SDL_VIDEO_RENDER_D3D #include "../../core/windows/SDL_windows.h" #include "SDL_hints.h" #include "SDL_loadso.h" #include "SDL_syswm.h" -#include "SDL_log.h" -#include "SDL_assert.h" #include "../SDL_sysrender.h" #include "../SDL_d3dmath.h" #include "../../video/windows/SDL_windowsvideo.h" @@ -53,16 +51,14 @@ typedef struct SDL_bool cliprect_enabled_dirty; SDL_Rect cliprect; SDL_bool cliprect_dirty; - SDL_bool is_copy_ex; LPDIRECT3DPIXELSHADER9 shader; } D3D_DrawStateCache; - /* Direct3D renderer implementation */ typedef struct { - void* d3dDLL; + void *d3dDLL; IDirect3D9 *d3d; IDirect3DDevice9 *device; UINT adapter; @@ -73,8 +69,10 @@ typedef struct D3DTEXTUREFILTERTYPE scaleMode[8]; IDirect3DSurface9 *defaultRenderTarget; IDirect3DSurface9 *currentRenderTarget; - void* d3dxDLL; + void *d3dxDLL; +#if SDL_HAVE_YUV LPDIRECT3DPIXELSHADER9 shaders[NUM_SHADERS]; +#endif LPDIRECT3DVERTEXBUFFER9 vertexBuffers[8]; size_t vertexBufferSize[8]; int currentVertexBuffer; @@ -98,6 +96,7 @@ typedef struct D3D_TextureRep texture; D3DTEXTUREFILTERTYPE scaleMode; +#if SDL_HAVE_YUV /* YV12 texture support */ SDL_bool yuv; D3D_TextureRep utexture; @@ -105,6 +104,7 @@ typedef struct Uint8 *pixels; int pitch; SDL_Rect locked_rect; +#endif } D3D_TextureData; typedef struct @@ -114,8 +114,7 @@ typedef struct float u, v; } Vertex; -static int -D3D_SetError(const char *prefix, HRESULT result) +static int D3D_SetError(const char *prefix, HRESULT result) { const char *error; @@ -193,8 +192,7 @@ D3D_SetError(const char *prefix, HRESULT result) return SDL_SetError("%s: %s", prefix, error); } -static D3DFORMAT -PixelFormatToD3DFMT(Uint32 format) +static D3DFORMAT PixelFormatToD3DFMT(Uint32 format) { switch (format) { case SDL_PIXELFORMAT_RGB565: @@ -213,8 +211,7 @@ PixelFormatToD3DFMT(Uint32 format) } } -static Uint32 -D3DFMTToPixelFormat(D3DFORMAT format) +static Uint32 D3DFMTToPixelFormat(D3DFORMAT format) { switch (format) { case D3DFMT_R5G6B5: @@ -228,8 +225,7 @@ D3DFMTToPixelFormat(D3DFORMAT format) } } -static void -D3D_InitRenderState(D3D_RenderData *data) +static void D3D_InitRenderState(D3D_RenderData *data) { D3DMATRIX matrix; @@ -287,12 +283,11 @@ D3D_InitRenderState(D3D_RenderData *data) data->beginScene = SDL_TRUE; } -static int D3D_Reset(SDL_Renderer * renderer); +static int D3D_Reset(SDL_Renderer *renderer); -static int -D3D_ActivateRenderer(SDL_Renderer * renderer) +static int D3D_ActivateRenderer(SDL_Renderer *renderer) { - D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; + D3D_RenderData *data = (D3D_RenderData *)renderer->driverdata; HRESULT result; if (data->updateSize) { @@ -300,7 +295,7 @@ D3D_ActivateRenderer(SDL_Renderer * renderer) int w, h; Uint32 window_flags = SDL_GetWindowFlags(window); - SDL_GetWindowSize(window, &w, &h); + SDL_GetWindowSizeInPixels(window, &w, &h); data->pparams.BackBufferWidth = w; data->pparams.BackBufferHeight = h; if (window_flags & SDL_WINDOW_FULLSCREEN && (window_flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP) { @@ -336,16 +331,21 @@ D3D_ActivateRenderer(SDL_Renderer * renderer) return 0; } -static void -D3D_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event) +static void D3D_WindowEvent(SDL_Renderer *renderer, const SDL_WindowEvent *event) { - D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; + D3D_RenderData *data = (D3D_RenderData *)renderer->driverdata; if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED) { data->updateSize = SDL_TRUE; } } +static int D3D_GetOutputSize(SDL_Renderer *renderer, int *w, int *h) +{ + SDL_GetWindowSizeInPixels(renderer->window, w, h); + return 0; +} + static D3DBLEND GetBlendFunc(SDL_BlendFactor factor) { switch (factor) { @@ -370,14 +370,33 @@ static D3DBLEND GetBlendFunc(SDL_BlendFactor factor) case SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA: return D3DBLEND_INVDESTALPHA; default: - return (D3DBLEND)0; + break; } + return (D3DBLEND)0; } -static SDL_bool -D3D_SupportsBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode) +static D3DBLENDOP GetBlendEquation(SDL_BlendOperation operation) { - D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; + switch (operation) { + case SDL_BLENDOPERATION_ADD: + return D3DBLENDOP_ADD; + case SDL_BLENDOPERATION_SUBTRACT: + return D3DBLENDOP_SUBTRACT; + case SDL_BLENDOPERATION_REV_SUBTRACT: + return D3DBLENDOP_REVSUBTRACT; + case SDL_BLENDOPERATION_MINIMUM: + return D3DBLENDOP_MIN; + case SDL_BLENDOPERATION_MAXIMUM: + return D3DBLENDOP_MAX; + default: + break; + } + return (D3DBLENDOP)0; +} + +static SDL_bool D3D_SupportsBlendMode(SDL_Renderer *renderer, SDL_BlendMode blendMode) +{ + D3D_RenderData *data = (D3D_RenderData *)renderer->driverdata; SDL_BlendFactor srcColorFactor = SDL_GetBlendModeSrcColorFactor(blendMode); SDL_BlendFactor srcAlphaFactor = SDL_GetBlendModeSrcAlphaFactor(blendMode); SDL_BlendOperation colorOperation = SDL_GetBlendModeColorOperation(blendMode); @@ -386,20 +405,21 @@ D3D_SupportsBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode) SDL_BlendOperation alphaOperation = SDL_GetBlendModeAlphaOperation(blendMode); if (!GetBlendFunc(srcColorFactor) || !GetBlendFunc(srcAlphaFactor) || - !GetBlendFunc(dstColorFactor) || !GetBlendFunc(dstAlphaFactor)) { + !GetBlendEquation(colorOperation) || + !GetBlendFunc(dstColorFactor) || !GetBlendFunc(dstAlphaFactor) || + !GetBlendEquation(alphaOperation)) { return SDL_FALSE; } - if ((srcColorFactor != srcAlphaFactor || dstColorFactor != dstAlphaFactor) && !data->enableSeparateAlphaBlend) { - return SDL_FALSE; - } - if (colorOperation != SDL_BLENDOPERATION_ADD || alphaOperation != SDL_BLENDOPERATION_ADD) { - return SDL_FALSE; + + if (!data->enableSeparateAlphaBlend) { + if ((srcColorFactor != srcAlphaFactor) || (dstColorFactor != dstAlphaFactor) || (colorOperation != alphaOperation)) { + return SDL_FALSE; + } } return SDL_TRUE; } -static int -D3D_CreateTextureRep(IDirect3DDevice9 *device, D3D_TextureRep *texture, DWORD usage, Uint32 format, D3DFORMAT d3dfmt, int w, int h) +static int D3D_CreateTextureRep(IDirect3DDevice9 *device, D3D_TextureRep *texture, DWORD usage, Uint32 format, D3DFORMAT d3dfmt, int w, int h) { HRESULT result; @@ -411,23 +431,21 @@ D3D_CreateTextureRep(IDirect3DDevice9 *device, D3D_TextureRep *texture, DWORD us texture->d3dfmt = d3dfmt; result = IDirect3DDevice9_CreateTexture(device, w, h, 1, usage, - PixelFormatToD3DFMT(format), - D3DPOOL_DEFAULT, &texture->texture, NULL); + PixelFormatToD3DFMT(format), + D3DPOOL_DEFAULT, &texture->texture, NULL); if (FAILED(result)) { return D3D_SetError("CreateTexture(D3DPOOL_DEFAULT)", result); } return 0; } - -static int -D3D_CreateStagingTexture(IDirect3DDevice9 *device, D3D_TextureRep *texture) +static int D3D_CreateStagingTexture(IDirect3DDevice9 *device, D3D_TextureRep *texture) { HRESULT result; - if (texture->staging == NULL) { + if (!texture->staging) { result = IDirect3DDevice9_CreateTexture(device, texture->w, texture->h, 1, 0, - texture->d3dfmt, D3DPOOL_SYSTEMMEM, &texture->staging, NULL); + texture->d3dfmt, D3DPOOL_SYSTEMMEM, &texture->staging, NULL); if (FAILED(result)) { return D3D_SetError("CreateTexture(D3DPOOL_SYSTEMMEM)", result); } @@ -435,8 +453,7 @@ D3D_CreateStagingTexture(IDirect3DDevice9 *device, D3D_TextureRep *texture) return 0; } -static int -D3D_RecreateTextureRep(IDirect3DDevice9 *device, D3D_TextureRep *texture) +static int D3D_RecreateTextureRep(IDirect3DDevice9 *device, D3D_TextureRep *texture) { if (texture->texture) { IDirect3DTexture9_Release(texture->texture); @@ -449,8 +466,7 @@ D3D_RecreateTextureRep(IDirect3DDevice9 *device, D3D_TextureRep *texture) return 0; } -static int -D3D_UpdateTextureRep(IDirect3DDevice9 *device, D3D_TextureRep *texture, int x, int y, int w, int h, const void *pixels, int pitch) +static int D3D_UpdateTextureRep(IDirect3DDevice9 *device, D3D_TextureRep *texture, int x, int y, int w, int h, const void *pixels, int pitch) { RECT d3drect; D3DLOCKED_RECT locked; @@ -464,10 +480,10 @@ D3D_UpdateTextureRep(IDirect3DDevice9 *device, D3D_TextureRep *texture, int x, i } d3drect.left = x; - d3drect.right = x + w; + d3drect.right = (LONG)x + w; d3drect.top = y; - d3drect.bottom = y + h; - + d3drect.bottom = (LONG)y + h; + result = IDirect3DTexture9_LockRect(texture->staging, 0, &locked, &d3drect, 0); if (FAILED(result)) { return D3D_SetError("LockRect()", result); @@ -477,7 +493,7 @@ D3D_UpdateTextureRep(IDirect3DDevice9 *device, D3D_TextureRep *texture, int x, i dst = (Uint8 *)locked.pBits; length = w * SDL_BYTESPERPIXEL(texture->format); if (length == pitch && length == locked.Pitch) { - SDL_memcpy(dst, src, length*h); + SDL_memcpy(dst, src, (size_t)length * h); } else { if (length > pitch) { length = pitch; @@ -500,8 +516,7 @@ D3D_UpdateTextureRep(IDirect3DDevice9 *device, D3D_TextureRep *texture, int x, i return 0; } -static void -D3D_DestroyTextureRep(D3D_TextureRep *texture) +static void D3D_DestroyTextureRep(D3D_TextureRep *texture) { if (texture->texture) { IDirect3DTexture9_Release(texture->texture); @@ -513,14 +528,13 @@ D3D_DestroyTextureRep(D3D_TextureRep *texture) } } -static int -D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) +static int D3D_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) { - D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; + D3D_RenderData *data = (D3D_RenderData *)renderer->driverdata; D3D_TextureData *texturedata; DWORD usage; - texturedata = (D3D_TextureData *) SDL_calloc(1, sizeof(*texturedata)); + texturedata = (D3D_TextureData *)SDL_calloc(1, sizeof(*texturedata)); if (!texturedata) { return SDL_OutOfMemory(); } @@ -537,7 +551,7 @@ D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) if (D3D_CreateTextureRep(data->device, &texturedata->texture, usage, texture->format, PixelFormatToD3DFMT(texture->format), texture->w, texture->h) < 0) { return -1; } - +#if SDL_HAVE_YUV if (texture->format == SDL_PIXELFORMAT_YV12 || texture->format == SDL_PIXELFORMAT_IYUV) { texturedata->yuv = SDL_TRUE; @@ -550,11 +564,11 @@ D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) return -1; } } +#endif return 0; } -static int -D3D_RecreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) +static int D3D_RecreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) { D3D_RenderData *data = (D3D_RenderData *)renderer->driverdata; D3D_TextureData *texturedata = (D3D_TextureData *)texture->driverdata; @@ -566,7 +580,7 @@ D3D_RecreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) if (D3D_RecreateTextureRep(data->device, &texturedata->texture) < 0) { return -1; } - +#if SDL_HAVE_YUV if (texturedata->yuv) { if (D3D_RecreateTextureRep(data->device, &texturedata->utexture) < 0) { return -1; @@ -576,55 +590,54 @@ D3D_RecreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) return -1; } } +#endif return 0; } -static int -D3D_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * rect, const void *pixels, int pitch) +static int D3D_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *rect, const void *pixels, int pitch) { D3D_RenderData *data = (D3D_RenderData *)renderer->driverdata; - D3D_TextureData *texturedata = (D3D_TextureData *) texture->driverdata; + D3D_TextureData *texturedata = (D3D_TextureData *)texture->driverdata; if (!texturedata) { - SDL_SetError("Texture is not currently available"); - return -1; + return SDL_SetError("Texture is not currently available"); } if (D3D_UpdateTextureRep(data->device, &texturedata->texture, rect->x, rect->y, rect->w, rect->h, pixels, pitch) < 0) { return -1; } - +#if SDL_HAVE_YUV if (texturedata->yuv) { /* Skip to the correct offset into the next texture */ - pixels = (const void*)((const Uint8*)pixels + rect->h * pitch); + pixels = (const void *)((const Uint8 *)pixels + rect->h * pitch); if (D3D_UpdateTextureRep(data->device, texture->format == SDL_PIXELFORMAT_YV12 ? &texturedata->vtexture : &texturedata->utexture, rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2, pixels, (pitch + 1) / 2) < 0) { return -1; } /* Skip to the correct offset into the next texture */ - pixels = (const void*)((const Uint8*)pixels + ((rect->h + 1) / 2) * ((pitch + 1) / 2)); + pixels = (const void *)((const Uint8 *)pixels + ((rect->h + 1) / 2) * ((pitch + 1) / 2)); if (D3D_UpdateTextureRep(data->device, texture->format == SDL_PIXELFORMAT_YV12 ? &texturedata->utexture : &texturedata->vtexture, rect->x / 2, (rect->y + 1) / 2, (rect->w + 1) / 2, (rect->h + 1) / 2, pixels, (pitch + 1) / 2) < 0) { return -1; } } +#endif return 0; } -static int -D3D_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * rect, - const Uint8 *Yplane, int Ypitch, - const Uint8 *Uplane, int Upitch, - const Uint8 *Vplane, int Vpitch) +#if SDL_HAVE_YUV +static int D3D_UpdateTextureYUV(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *Uplane, int Upitch, + const Uint8 *Vplane, int Vpitch) { D3D_RenderData *data = (D3D_RenderData *)renderer->driverdata; - D3D_TextureData *texturedata = (D3D_TextureData *) texture->driverdata; + D3D_TextureData *texturedata = (D3D_TextureData *)texture->driverdata; if (!texturedata) { - SDL_SetError("Texture is not currently available"); - return -1; + return SDL_SetError("Texture is not currently available"); } if (D3D_UpdateTextureRep(data->device, &texturedata->texture, rect->x, rect->y, rect->w, rect->h, Yplane, Ypitch) < 0) { @@ -638,20 +651,19 @@ D3D_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture, } return 0; } +#endif -static int -D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * rect, void **pixels, int *pitch) +static int D3D_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *rect, void **pixels, int *pitch) { D3D_RenderData *data = (D3D_RenderData *)renderer->driverdata; D3D_TextureData *texturedata = (D3D_TextureData *)texture->driverdata; IDirect3DDevice9 *device = data->device; if (!texturedata) { - SDL_SetError("Texture is not currently available"); - return -1; + return SDL_SetError("Texture is not currently available"); } - +#if SDL_HAVE_YUV texturedata->locked_rect = *rect; if (texturedata->yuv) { @@ -664,10 +676,12 @@ D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, } } *pixels = - (void *) ((Uint8 *) texturedata->pixels + rect->y * texturedata->pitch + - rect->x * SDL_BYTESPERPIXEL(texture->format)); + (void *)(texturedata->pixels + rect->y * texturedata->pitch + + rect->x * SDL_BYTESPERPIXEL(texture->format)); *pitch = texturedata->pitch; - } else { + } else +#endif + { RECT d3drect; D3DLOCKED_RECT locked; HRESULT result; @@ -677,9 +691,9 @@ D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, } d3drect.left = rect->x; - d3drect.right = rect->x + rect->w; + d3drect.right = (LONG)rect->x + rect->w; d3drect.top = rect->y; - d3drect.bottom = rect->y + rect->h; + d3drect.bottom = (LONG)rect->y + rect->h; result = IDirect3DTexture9_LockRect(texturedata->texture.staging, 0, &locked, &d3drect, 0); if (FAILED(result)) { @@ -691,8 +705,7 @@ D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, return 0; } -static void -D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) +static void D3D_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture) { D3D_RenderData *data = (D3D_RenderData *)renderer->driverdata; D3D_TextureData *texturedata = (D3D_TextureData *)texture->driverdata; @@ -700,14 +713,16 @@ D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) if (!texturedata) { return; } - +#if SDL_HAVE_YUV if (texturedata->yuv) { const SDL_Rect *rect = &texturedata->locked_rect; void *pixels = - (void *) ((Uint8 *) texturedata->pixels + rect->y * texturedata->pitch + - rect->x * SDL_BYTESPERPIXEL(texture->format)); + (void *)(texturedata->pixels + rect->y * texturedata->pitch + + rect->x * SDL_BYTESPERPIXEL(texture->format)); D3D_UpdateTexture(renderer, texture, rect, pixels, texturedata->pitch); - } else { + } else +#endif + { IDirect3DTexture9_UnlockRect(texturedata->texture.staging, 0); texturedata->texture.dirty = SDL_TRUE; if (data->drawstate.texture == texture) { @@ -715,16 +730,11 @@ D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) data->drawstate.shader = NULL; IDirect3DDevice9_SetPixelShader(data->device, NULL); IDirect3DDevice9_SetTexture(data->device, 0, NULL); - if (texturedata->yuv) { - IDirect3DDevice9_SetTexture(data->device, 1, NULL); - IDirect3DDevice9_SetTexture(data->device, 2, NULL); - } } } } -static void -D3D_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture, SDL_ScaleMode scaleMode) +static void D3D_SetTextureScaleMode(SDL_Renderer *renderer, SDL_Texture *texture, SDL_ScaleMode scaleMode) { D3D_TextureData *texturedata = (D3D_TextureData *)texture->driverdata; @@ -735,30 +745,28 @@ D3D_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture, SDL_Scal texturedata->scaleMode = (scaleMode == SDL_ScaleModeNearest) ? D3DTEXF_POINT : D3DTEXF_LINEAR; } -static int -D3D_SetRenderTargetInternal(SDL_Renderer * renderer, SDL_Texture * texture) +static int D3D_SetRenderTargetInternal(SDL_Renderer *renderer, SDL_Texture *texture) { - D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; + D3D_RenderData *data = (D3D_RenderData *)renderer->driverdata; D3D_TextureData *texturedata; D3D_TextureRep *texturerep; HRESULT result; IDirect3DDevice9 *device = data->device; /* Release the previous render target if it wasn't the default one */ - if (data->currentRenderTarget != NULL) { + if (data->currentRenderTarget) { IDirect3DSurface9_Release(data->currentRenderTarget); data->currentRenderTarget = NULL; } - if (texture == NULL) { + if (!texture) { IDirect3DDevice9_SetRenderTarget(data->device, 0, data->defaultRenderTarget); return 0; } texturedata = (D3D_TextureData *)texture->driverdata; if (!texturedata) { - SDL_SetError("Texture is not currently available"); - return -1; + return SDL_SetError("Texture is not currently available"); } /* Make sure the render target is updated if it was locked and written to */ @@ -766,7 +774,7 @@ D3D_SetRenderTargetInternal(SDL_Renderer * renderer, SDL_Texture * texture) if (texturerep->dirty && texturerep->staging) { if (!texturerep->texture) { result = IDirect3DDevice9_CreateTexture(device, texturerep->w, texturerep->h, 1, texturerep->usage, - PixelFormatToD3DFMT(texturerep->format), D3DPOOL_DEFAULT, &texturerep->texture, NULL); + PixelFormatToD3DFMT(texturerep->format), D3DPOOL_DEFAULT, &texturerep->texture, NULL); if (FAILED(result)) { return D3D_SetError("CreateTexture(D3DPOOL_DEFAULT)", result); } @@ -780,19 +788,18 @@ D3D_SetRenderTargetInternal(SDL_Renderer * renderer, SDL_Texture * texture) } result = IDirect3DTexture9_GetSurfaceLevel(texturedata->texture.texture, 0, &data->currentRenderTarget); - if(FAILED(result)) { + if (FAILED(result)) { return D3D_SetError("GetSurfaceLevel()", result); } result = IDirect3DDevice9_SetRenderTarget(data->device, 0, data->currentRenderTarget); - if(FAILED(result)) { + if (FAILED(result)) { return D3D_SetError("SetRenderTarget()", result); } return 0; } -static int -D3D_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture) +static int D3D_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture) { if (D3D_ActivateRenderer(renderer) < 0) { return -1; @@ -801,19 +808,16 @@ D3D_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture) return D3D_SetRenderTargetInternal(renderer, texture); } - -static int -D3D_QueueSetViewport(SDL_Renderer * renderer, SDL_RenderCommand *cmd) +static int D3D_QueueSetViewport(SDL_Renderer *renderer, SDL_RenderCommand *cmd) { - return 0; /* nothing to do in this backend. */ + return 0; /* nothing to do in this backend. */ } -static int -D3D_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count) +static int D3D_QueueDrawPoints(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count) { const DWORD color = D3DCOLOR_ARGB(cmd->data.draw.a, cmd->data.draw.r, cmd->data.draw.g, cmd->data.draw.b); - const size_t vertslen = count * sizeof (Vertex); - Vertex *verts = (Vertex *) SDL_AllocateRenderVertices(renderer, vertslen, 0, &cmd->data.draw.first); + const size_t vertslen = count * sizeof(Vertex); + Vertex *verts = (Vertex *)SDL_AllocateRenderVertices(renderer, vertslen, 0, &cmd->data.draw.first); int i; if (!verts) { @@ -832,202 +836,65 @@ D3D_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_F return 0; } -static int -D3D_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRect * rects, int count) +static int D3D_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, + const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride, + int num_vertices, const void *indices, int num_indices, int size_indices, + float scale_x, float scale_y) { - const DWORD color = D3DCOLOR_ARGB(cmd->data.draw.a, cmd->data.draw.r, cmd->data.draw.g, cmd->data.draw.b); - const size_t vertslen = count * sizeof (Vertex) * 4; - Vertex *verts = (Vertex *) SDL_AllocateRenderVertices(renderer, vertslen, 0, &cmd->data.draw.first); int i; + int count = indices ? num_indices : num_vertices; + Vertex *verts = (Vertex *)SDL_AllocateRenderVertices(renderer, count * sizeof(Vertex), 0, &cmd->data.draw.first); if (!verts) { return -1; } - SDL_memset(verts, '\0', vertslen); cmd->data.draw.count = count; + size_indices = indices ? size_indices : 0; for (i = 0; i < count; i++) { - const SDL_FRect *rect = &rects[i]; - const float minx = rect->x; - const float maxx = rect->x + rect->w; - const float miny = rect->y; - const float maxy = rect->y + rect->h; + int j; + float *xy_; + SDL_Color col_; + if (size_indices == 4) { + j = ((const Uint32 *)indices)[i]; + } else if (size_indices == 2) { + j = ((const Uint16 *)indices)[i]; + } else if (size_indices == 1) { + j = ((const Uint8 *)indices)[i]; + } else { + j = i; + } - verts->x = minx; - verts->y = miny; - verts->color = color; - verts++; + xy_ = (float *)((char *)xy + j * xy_stride); + col_ = *(SDL_Color *)((char *)color + j * color_stride); - verts->x = maxx; - verts->y = miny; - verts->color = color; - verts++; + verts->x = xy_[0] * scale_x - 0.5f; + verts->y = xy_[1] * scale_y - 0.5f; + verts->z = 0.0f; + verts->color = D3DCOLOR_ARGB(col_.a, col_.r, col_.g, col_.b); - verts->x = maxx; - verts->y = maxy; - verts->color = color; - verts++; + if (texture) { + float *uv_ = (float *)((char *)uv + j * uv_stride); + verts->u = uv_[0]; + verts->v = uv_[1]; + } else { + verts->u = 0.0f; + verts->v = 0.0f; + } - verts->x = minx; - verts->y = maxy; - verts->color = color; - verts++; + verts += 1; } - return 0; } -static int -D3D_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_FRect * dstrect) -{ - const DWORD color = D3DCOLOR_ARGB(cmd->data.draw.a, cmd->data.draw.r, cmd->data.draw.g, cmd->data.draw.b); - float minx, miny, maxx, maxy; - float minu, maxu, minv, maxv; - const size_t vertslen = sizeof (Vertex) * 4; - Vertex *verts = (Vertex *) SDL_AllocateRenderVertices(renderer, vertslen, 0, &cmd->data.draw.first); - - if (!verts) { - return -1; - } - - cmd->data.draw.count = 1; - - minx = dstrect->x - 0.5f; - miny = dstrect->y - 0.5f; - maxx = dstrect->x + dstrect->w - 0.5f; - maxy = dstrect->y + dstrect->h - 0.5f; - - minu = (float) srcrect->x / texture->w; - maxu = (float) (srcrect->x + srcrect->w) / texture->w; - minv = (float) srcrect->y / texture->h; - maxv = (float) (srcrect->y + srcrect->h) / texture->h; - - verts->x = minx; - verts->y = miny; - verts->z = 0.0f; - verts->color = color; - verts->u = minu; - verts->v = minv; - verts++; - - verts->x = maxx; - verts->y = miny; - verts->z = 0.0f; - verts->color = color; - verts->u = maxu; - verts->v = minv; - verts++; - - verts->x = maxx; - verts->y = maxy; - verts->z = 0.0f; - verts->color = color; - verts->u = maxu; - verts->v = maxv; - verts++; - - verts->x = minx; - verts->y = maxy; - verts->z = 0.0f; - verts->color = color; - verts->u = minu; - verts->v = maxv; - verts++; - - return 0; -} - -static int -D3D_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture, - const SDL_Rect * srcquad, const SDL_FRect * dstrect, - const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip) -{ - const DWORD color = D3DCOLOR_ARGB(cmd->data.draw.a, cmd->data.draw.r, cmd->data.draw.g, cmd->data.draw.b); - float minx, miny, maxx, maxy; - float minu, maxu, minv, maxv; - const size_t vertslen = sizeof (Vertex) * 5; - Vertex *verts = (Vertex *) SDL_AllocateRenderVertices(renderer, vertslen, 0, &cmd->data.draw.first); - - if (!verts) { - return -1; - } - - cmd->data.draw.count = 1; - - minx = -center->x; - maxx = dstrect->w - center->x; - miny = -center->y; - maxy = dstrect->h - center->y; - - if (flip & SDL_FLIP_HORIZONTAL) { - minu = (float) (srcquad->x + srcquad->w) / texture->w; - maxu = (float) srcquad->x / texture->w; - } else { - minu = (float) srcquad->x / texture->w; - maxu = (float) (srcquad->x + srcquad->w) / texture->w; - } - - if (flip & SDL_FLIP_VERTICAL) { - minv = (float) (srcquad->y + srcquad->h) / texture->h; - maxv = (float) srcquad->y / texture->h; - } else { - minv = (float) srcquad->y / texture->h; - maxv = (float) (srcquad->y + srcquad->h) / texture->h; - } - - verts->x = minx; - verts->y = miny; - verts->z = 0.0f; - verts->color = color; - verts->u = minu; - verts->v = minv; - verts++; - - verts->x = maxx; - verts->y = miny; - verts->z = 0.0f; - verts->color = color; - verts->u = maxu; - verts->v = minv; - verts++; - - verts->x = maxx; - verts->y = maxy; - verts->z = 0.0f; - verts->color = color; - verts->u = maxu; - verts->v = maxv; - verts++; - - verts->x = minx; - verts->y = maxy; - verts->z = 0.0f; - verts->color = color; - verts->u = minu; - verts->v = maxv; - verts++; - - verts->x = dstrect->x + center->x - 0.5f; /* X translation */ - verts->y = dstrect->y + center->y - 0.5f; /* Y translation */ - verts->z = (float)(M_PI * (float) angle / 180.0f); /* rotation */ - verts->color = 0; - verts->u = 0.0f; - verts->v = 0.0f; - verts++; - - return 0; -} - -static int -UpdateDirtyTexture(IDirect3DDevice9 *device, D3D_TextureRep *texture) +static int UpdateDirtyTexture(IDirect3DDevice9 *device, D3D_TextureRep *texture) { if (texture->dirty && texture->staging) { HRESULT result; if (!texture->texture) { result = IDirect3DDevice9_CreateTexture(device, texture->w, texture->h, 1, texture->usage, - PixelFormatToD3DFMT(texture->format), D3DPOOL_DEFAULT, &texture->texture, NULL); + PixelFormatToD3DFMT(texture->format), D3DPOOL_DEFAULT, &texture->texture, NULL); if (FAILED(result)) { return D3D_SetError("CreateTexture(D3DPOOL_DEFAULT)", result); } @@ -1042,8 +909,7 @@ UpdateDirtyTexture(IDirect3DDevice9 *device, D3D_TextureRep *texture) return 0; } -static int -BindTextureRep(IDirect3DDevice9 *device, D3D_TextureRep *texture, DWORD sampler) +static int BindTextureRep(IDirect3DDevice9 *device, D3D_TextureRep *texture, DWORD sampler) { HRESULT result; UpdateDirtyTexture(device, texture); @@ -1054,8 +920,7 @@ BindTextureRep(IDirect3DDevice9 *device, D3D_TextureRep *texture, DWORD sampler) return 0; } -static void -UpdateTextureScaleMode(D3D_RenderData *data, D3D_TextureData *texturedata, unsigned index) +static void UpdateTextureScaleMode(D3D_RenderData *data, D3D_TextureData *texturedata, unsigned index) { if (texturedata->scaleMode != data->scaleMode[index]) { IDirect3DDevice9_SetSamplerState(data->device, index, D3DSAMP_MINFILTER, @@ -1070,16 +935,14 @@ UpdateTextureScaleMode(D3D_RenderData *data, D3D_TextureData *texturedata, unsig } } -static int -SetupTextureState(D3D_RenderData *data, SDL_Texture * texture, LPDIRECT3DPIXELSHADER9 *shader) +static int SetupTextureState(D3D_RenderData *data, SDL_Texture *texture, LPDIRECT3DPIXELSHADER9 *shader) { D3D_TextureData *texturedata = (D3D_TextureData *)texture->driverdata; SDL_assert(*shader == NULL); if (!texturedata) { - SDL_SetError("Texture is not currently available"); - return -1; + return SDL_SetError("Texture is not currently available"); } UpdateTextureScaleMode(data, texturedata, 0); @@ -1087,7 +950,7 @@ SetupTextureState(D3D_RenderData *data, SDL_Texture * texture, LPDIRECT3DPIXELSH if (BindTextureRep(data->device, &texturedata->texture, 0) < 0) { return -1; } - +#if SDL_HAVE_YUV if (texturedata->yuv) { switch (SDL_GetYUVConversionModeForResolution(texture->w, texture->h)) { case SDL_YUV_CONVERSION_JPEG: @@ -1113,30 +976,32 @@ SetupTextureState(D3D_RenderData *data, SDL_Texture * texture, LPDIRECT3DPIXELSH return -1; } } +#endif return 0; } -static int -SetDrawState(D3D_RenderData *data, const SDL_RenderCommand *cmd) +static int SetDrawState(D3D_RenderData *data, const SDL_RenderCommand *cmd) { - const SDL_bool was_copy_ex = data->drawstate.is_copy_ex; - const SDL_bool is_copy_ex = (cmd->command == SDL_RENDERCMD_COPY_EX); SDL_Texture *texture = cmd->data.draw.texture; const SDL_BlendMode blend = cmd->data.draw.blend; if (texture != data->drawstate.texture) { - D3D_TextureData *oldtexturedata = data->drawstate.texture ? (D3D_TextureData *) data->drawstate.texture->driverdata : NULL; - D3D_TextureData *newtexturedata = texture ? (D3D_TextureData *) texture->driverdata : NULL; +#if SDL_HAVE_YUV + D3D_TextureData *oldtexturedata = data->drawstate.texture ? (D3D_TextureData *)data->drawstate.texture->driverdata : NULL; + D3D_TextureData *newtexturedata = texture ? (D3D_TextureData *)texture->driverdata : NULL; +#endif LPDIRECT3DPIXELSHADER9 shader = NULL; /* disable any enabled textures we aren't going to use, let SetupTextureState() do the rest. */ - if (texture == NULL) { + if (!texture) { IDirect3DDevice9_SetTexture(data->device, 0, NULL); } +#if SDL_HAVE_YUV if ((!newtexturedata || !newtexturedata->yuv) && (oldtexturedata && oldtexturedata->yuv)) { IDirect3DDevice9_SetTexture(data->device, 1, NULL); IDirect3DDevice9_SetTexture(data->device, 2, NULL); } +#endif if (texture && SetupTextureState(data, texture, &shader) < 0) { return -1; } @@ -1151,12 +1016,14 @@ SetDrawState(D3D_RenderData *data, const SDL_RenderCommand *cmd) data->drawstate.texture = texture; } else if (texture) { - D3D_TextureData *texturedata = (D3D_TextureData *) texture->driverdata; + D3D_TextureData *texturedata = (D3D_TextureData *)texture->driverdata; UpdateDirtyTexture(data->device, &texturedata->texture); +#if SDL_HAVE_YUV if (texturedata->yuv) { UpdateDirtyTexture(data->device, &texturedata->utexture); UpdateDirtyTexture(data->device, &texturedata->vtexture); } +#endif } if (blend != data->drawstate.blend) { @@ -1168,28 +1035,30 @@ SetDrawState(D3D_RenderData *data, const SDL_RenderCommand *cmd) GetBlendFunc(SDL_GetBlendModeSrcColorFactor(blend))); IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLEND, GetBlendFunc(SDL_GetBlendModeDstColorFactor(blend))); + IDirect3DDevice9_SetRenderState(data->device, D3DRS_BLENDOP, + GetBlendEquation(SDL_GetBlendModeColorOperation(blend))); if (data->enableSeparateAlphaBlend) { IDirect3DDevice9_SetRenderState(data->device, D3DRS_SRCBLENDALPHA, GetBlendFunc(SDL_GetBlendModeSrcAlphaFactor(blend))); IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLENDALPHA, GetBlendFunc(SDL_GetBlendModeDstAlphaFactor(blend))); + IDirect3DDevice9_SetRenderState(data->device, D3DRS_BLENDOPALPHA, + GetBlendEquation(SDL_GetBlendModeAlphaOperation(blend))); } } data->drawstate.blend = blend; } - if (is_copy_ex != was_copy_ex) { - if (!is_copy_ex) { /* SDL_RENDERCMD_COPY_EX will set this, we only want to reset it here if necessary. */ - const Float4X4 d3dmatrix = MatrixIdentity(); - IDirect3DDevice9_SetTransform(data->device, D3DTS_VIEW, (D3DMATRIX*) &d3dmatrix); - } - data->drawstate.is_copy_ex = is_copy_ex; - } - if (data->drawstate.viewport_dirty) { const SDL_Rect *viewport = &data->drawstate.viewport; - const D3DVIEWPORT9 d3dviewport = { viewport->x, viewport->y, viewport->w, viewport->h, 0.0f, 1.0f }; + D3DVIEWPORT9 d3dviewport; + d3dviewport.X = viewport->x; + d3dviewport.Y = viewport->y; + d3dviewport.Width = viewport->w; + d3dviewport.Height = viewport->h; + d3dviewport.MinZ = 0.0f; + d3dviewport.MaxZ = 1.0f; IDirect3DDevice9_SetViewport(data->device, &d3dviewport); /* Set an orthographic projection matrix */ @@ -1216,7 +1085,11 @@ SetDrawState(D3D_RenderData *data, const SDL_RenderCommand *cmd) if (data->drawstate.cliprect_dirty) { const SDL_Rect *viewport = &data->drawstate.viewport; const SDL_Rect *rect = &data->drawstate.cliprect; - const RECT d3drect = { viewport->x + rect->x, viewport->y + rect->y, viewport->x + rect->x + rect->w, viewport->y + rect->y + rect->h }; + RECT d3drect; + d3drect.left = (LONG)viewport->x + rect->x; + d3drect.top = (LONG)viewport->y + rect->y; + d3drect.right = (LONG)viewport->x + rect->x + rect->w; + d3drect.bottom = (LONG)viewport->y + rect->y + rect->h; IDirect3DDevice9_SetScissorRect(data->device, &d3drect); data->drawstate.cliprect_dirty = SDL_FALSE; } @@ -1224,216 +1097,194 @@ SetDrawState(D3D_RenderData *data, const SDL_RenderCommand *cmd) return 0; } -static int -D3D_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize) +static int D3D_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize) { - D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; + D3D_RenderData *data = (D3D_RenderData *)renderer->driverdata; const int vboidx = data->currentVertexBuffer; IDirect3DVertexBuffer9 *vbo = NULL; const SDL_bool istarget = renderer->target != NULL; - size_t i; if (D3D_ActivateRenderer(renderer) < 0) { return -1; } - /* upload the new VBO data for this set of commands. */ - vbo = data->vertexBuffers[vboidx]; - if (data->vertexBufferSize[vboidx] < vertsize) { - const DWORD usage = D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY; - const DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1; + if (vertsize > 0) { + /* upload the new VBO data for this set of commands. */ + vbo = data->vertexBuffers[vboidx]; + if (data->vertexBufferSize[vboidx] < vertsize) { + const DWORD usage = D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY; + const DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1; + if (vbo) { + IDirect3DVertexBuffer9_Release(vbo); + } + + if (FAILED(IDirect3DDevice9_CreateVertexBuffer(data->device, (UINT)vertsize, usage, fvf, D3DPOOL_DEFAULT, &vbo, NULL))) { + vbo = NULL; + } + data->vertexBuffers[vboidx] = vbo; + data->vertexBufferSize[vboidx] = vbo ? vertsize : 0; + } + if (vbo) { - IDirect3DVertexBuffer9_Release(vbo); - } - - if (FAILED(IDirect3DDevice9_CreateVertexBuffer(data->device, (UINT) vertsize, usage, fvf, D3DPOOL_DEFAULT, &vbo, NULL))) { - vbo = NULL; - } - data->vertexBuffers[vboidx] = vbo; - data->vertexBufferSize[vboidx] = vbo ? vertsize : 0; - } - - if (vbo) { - void *ptr; - if (FAILED(IDirect3DVertexBuffer9_Lock(vbo, 0, (UINT) vertsize, &ptr, D3DLOCK_DISCARD))) { - vbo = NULL; /* oh well, we'll do immediate mode drawing. :( */ - } else { - SDL_memcpy(ptr, vertices, vertsize); - if (FAILED(IDirect3DVertexBuffer9_Unlock(vbo))) { - vbo = NULL; /* oh well, we'll do immediate mode drawing. :( */ + void *ptr; + if (FAILED(IDirect3DVertexBuffer9_Lock(vbo, 0, (UINT)vertsize, &ptr, D3DLOCK_DISCARD))) { + vbo = NULL; /* oh well, we'll do immediate mode drawing. :( */ + } else { + SDL_memcpy(ptr, vertices, vertsize); + if (FAILED(IDirect3DVertexBuffer9_Unlock(vbo))) { + vbo = NULL; /* oh well, we'll do immediate mode drawing. :( */ + } } } - } - /* cycle through a few VBOs so D3D has some time with the data before we replace it. */ - if (vbo) { - data->currentVertexBuffer++; - if (data->currentVertexBuffer >= SDL_arraysize(data->vertexBuffers)) { - data->currentVertexBuffer = 0; + /* cycle through a few VBOs so D3D has some time with the data before we replace it. */ + if (vbo) { + data->currentVertexBuffer++; + if (data->currentVertexBuffer >= SDL_arraysize(data->vertexBuffers)) { + data->currentVertexBuffer = 0; + } + } else if (!data->reportedVboProblem) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "SDL failed to get a vertex buffer for this Direct3D 9 rendering batch!"); + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Dropping back to a slower method."); + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "This might be a brief hiccup, but if performance is bad, this is probably why."); + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "This error will not be logged again for this renderer."); + data->reportedVboProblem = SDL_TRUE; } - } else if (!data->reportedVboProblem) { - SDL_LogError(SDL_LOG_CATEGORY_RENDER, "SDL failed to get a vertex buffer for this Direct3D 9 rendering batch!"); - SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Dropping back to a slower method."); - SDL_LogError(SDL_LOG_CATEGORY_RENDER, "This might be a brief hiccup, but if performance is bad, this is probably why."); - SDL_LogError(SDL_LOG_CATEGORY_RENDER, "This error will not be logged again for this renderer."); - data->reportedVboProblem = SDL_TRUE; } - IDirect3DDevice9_SetStreamSource(data->device, 0, vbo, 0, sizeof (Vertex)); + IDirect3DDevice9_SetStreamSource(data->device, 0, vbo, 0, sizeof(Vertex)); while (cmd) { switch (cmd->command) { - case SDL_RENDERCMD_SETDRAWCOLOR: { - /* currently this is sent with each vertex, but if we move to - shaders, we can put this in a uniform here and reduce vertex - buffer bandwidth */ - break; + case SDL_RENDERCMD_SETDRAWCOLOR: + { + /* currently this is sent with each vertex, but if we move to + shaders, we can put this in a uniform here and reduce vertex + buffer bandwidth */ + break; + } + + case SDL_RENDERCMD_SETVIEWPORT: + { + SDL_Rect *viewport = &data->drawstate.viewport; + if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof(cmd->data.viewport.rect)) != 0) { + SDL_copyp(viewport, &cmd->data.viewport.rect); + data->drawstate.viewport_dirty = SDL_TRUE; + data->drawstate.cliprect_dirty = SDL_TRUE; + } + break; + } + + case SDL_RENDERCMD_SETCLIPRECT: + { + const SDL_Rect *rect = &cmd->data.cliprect.rect; + if (data->drawstate.cliprect_enabled != cmd->data.cliprect.enabled) { + data->drawstate.cliprect_enabled = cmd->data.cliprect.enabled; + data->drawstate.cliprect_enabled_dirty = SDL_TRUE; } - case SDL_RENDERCMD_SETVIEWPORT: { - SDL_Rect *viewport = &data->drawstate.viewport; - if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect)) != 0) { - SDL_memcpy(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect)); - data->drawstate.viewport_dirty = SDL_TRUE; - } - break; + if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof(*rect)) != 0) { + SDL_copyp(&data->drawstate.cliprect, rect); + data->drawstate.cliprect_dirty = SDL_TRUE; + } + break; + } + + case SDL_RENDERCMD_CLEAR: + { + const DWORD color = D3DCOLOR_ARGB(cmd->data.color.a, cmd->data.color.r, cmd->data.color.g, cmd->data.color.b); + const SDL_Rect *viewport = &data->drawstate.viewport; + const int backw = istarget ? renderer->target->w : data->pparams.BackBufferWidth; + const int backh = istarget ? renderer->target->h : data->pparams.BackBufferHeight; + const SDL_bool viewport_equal = ((viewport->x == 0) && (viewport->y == 0) && (viewport->w == backw) && (viewport->h == backh)) ? SDL_TRUE : SDL_FALSE; + + if (data->drawstate.cliprect_enabled || data->drawstate.cliprect_enabled_dirty) { + IDirect3DDevice9_SetRenderState(data->device, D3DRS_SCISSORTESTENABLE, FALSE); + data->drawstate.cliprect_enabled_dirty = data->drawstate.cliprect_enabled; } - case SDL_RENDERCMD_SETCLIPRECT: { - const SDL_Rect *rect = &cmd->data.cliprect.rect; - if (data->drawstate.cliprect_enabled != cmd->data.cliprect.enabled) { - data->drawstate.cliprect_enabled = cmd->data.cliprect.enabled; - data->drawstate.cliprect_enabled_dirty = SDL_TRUE; - } - - if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof (SDL_Rect)) != 0) { - SDL_memcpy(&data->drawstate.cliprect, rect, sizeof (SDL_Rect)); - data->drawstate.cliprect_dirty = SDL_TRUE; - } - break; + /* Don't reset the viewport if we don't have to! */ + if (!data->drawstate.viewport_dirty && viewport_equal) { + IDirect3DDevice9_Clear(data->device, 0, NULL, D3DCLEAR_TARGET, color, 0.0f, 0); + } else { + /* Clear is defined to clear the entire render target */ + D3DVIEWPORT9 wholeviewport = { 0, 0, 0, 0, 0.0f, 1.0f }; + wholeviewport.Width = backw; + wholeviewport.Height = backh; + IDirect3DDevice9_SetViewport(data->device, &wholeviewport); + data->drawstate.viewport_dirty = SDL_TRUE; /* we still need to (re)set orthographic projection, so always mark it dirty. */ + IDirect3DDevice9_Clear(data->device, 0, NULL, D3DCLEAR_TARGET, color, 0.0f, 0); } - case SDL_RENDERCMD_CLEAR: { - const DWORD color = D3DCOLOR_ARGB(cmd->data.color.a, cmd->data.color.r, cmd->data.color.g, cmd->data.color.b); - const SDL_Rect *viewport = &data->drawstate.viewport; - const int backw = istarget ? renderer->target->w : data->pparams.BackBufferWidth; - const int backh = istarget ? renderer->target->h : data->pparams.BackBufferHeight; + break; + } - if (data->drawstate.cliprect_enabled) { - IDirect3DDevice9_SetRenderState(data->device, D3DRS_SCISSORTESTENABLE, FALSE); - data->drawstate.cliprect_enabled_dirty = SDL_TRUE; - } - - /* Don't reset the viewport if we don't have to! */ - if (!viewport->x && !viewport->y && (viewport->w == backw) && (viewport->h == backh)) { - IDirect3DDevice9_Clear(data->device, 0, NULL, D3DCLEAR_TARGET, color, 0.0f, 0); - } else { - /* Clear is defined to clear the entire render target */ - const D3DVIEWPORT9 wholeviewport = { 0, 0, backw, backh, 0.0f, 1.0f }; - IDirect3DDevice9_SetViewport(data->device, &wholeviewport); - data->drawstate.viewport_dirty = SDL_TRUE; - IDirect3DDevice9_Clear(data->device, 0, NULL, D3DCLEAR_TARGET, color, 0.0f, 0); - } - - break; + case SDL_RENDERCMD_DRAW_POINTS: + { + const size_t count = cmd->data.draw.count; + const size_t first = cmd->data.draw.first; + SetDrawState(data, cmd); + if (vbo) { + IDirect3DDevice9_DrawPrimitive(data->device, D3DPT_POINTLIST, (UINT)(first / sizeof(Vertex)), (UINT)count); + } else { + const Vertex *verts = (Vertex *)(((Uint8 *)vertices) + first); + IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_POINTLIST, (UINT)count, verts, sizeof(Vertex)); } + break; + } - case SDL_RENDERCMD_DRAW_POINTS: { - const size_t count = cmd->data.draw.count; - const size_t first = cmd->data.draw.first; - SetDrawState(data, cmd); - if (vbo) { - IDirect3DDevice9_DrawPrimitive(data->device, D3DPT_POINTLIST, (UINT) (first / sizeof (Vertex)), (UINT) count); - } else { - const Vertex *verts = (Vertex *) (((Uint8 *) vertices) + first); - IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_POINTLIST, (UINT) count, verts, sizeof (Vertex)); + case SDL_RENDERCMD_DRAW_LINES: + { + const size_t count = cmd->data.draw.count; + const size_t first = cmd->data.draw.first; + const Vertex *verts = (Vertex *)(((Uint8 *)vertices) + first); + + /* DirectX 9 has the same line rasterization semantics as GDI, + so we need to close the endpoint of the line with a second draw call. + NOLINTNEXTLINE(clang-analyzer-core.NullDereference): FIXME: Can verts truly not be NULL ? */ + const SDL_bool close_endpoint = ((count == 2) || (verts[0].x != verts[count - 1].x) || (verts[0].y != verts[count - 1].y)); + + SetDrawState(data, cmd); + + if (vbo) { + IDirect3DDevice9_DrawPrimitive(data->device, D3DPT_LINESTRIP, (UINT)(first / sizeof(Vertex)), (UINT)(count - 1)); + if (close_endpoint) { + IDirect3DDevice9_DrawPrimitive(data->device, D3DPT_POINTLIST, (UINT)((first / sizeof(Vertex)) + (count - 1)), 1); } - break; - } - - case SDL_RENDERCMD_DRAW_LINES: { - const size_t count = cmd->data.draw.count; - const size_t first = cmd->data.draw.first; - const Vertex *verts = (Vertex *) (((Uint8 *) vertices) + first); - - /* DirectX 9 has the same line rasterization semantics as GDI, - so we need to close the endpoint of the line with a second draw call. */ - const SDL_bool close_endpoint = ((count == 2) || (verts[0].x != verts[count-1].x) || (verts[0].y != verts[count-1].y)); - - SetDrawState(data, cmd); - - if (vbo) { - IDirect3DDevice9_DrawPrimitive(data->device, D3DPT_LINESTRIP, (UINT) (first / sizeof (Vertex)), (UINT) (count - 1)); - if (close_endpoint) { - IDirect3DDevice9_DrawPrimitive(data->device, D3DPT_POINTLIST, (UINT) ((first / sizeof (Vertex)) + (count - 1)), 1); - } - } else { - IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_LINESTRIP, (UINT) (count - 1), verts, sizeof (Vertex)); - if (close_endpoint) { - IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_POINTLIST, 1, &verts[count-1], sizeof (Vertex)); - } + } else { + IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_LINESTRIP, (UINT)(count - 1), verts, sizeof(Vertex)); + if (close_endpoint) { + IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_POINTLIST, 1, &verts[count - 1], sizeof(Vertex)); } - break; } + break; + } - case SDL_RENDERCMD_FILL_RECTS: { - const size_t count = cmd->data.draw.count; - const size_t first = cmd->data.draw.first; - SetDrawState(data, cmd); - if (vbo) { - size_t offset = 0; - for (i = 0; i < count; ++i, offset += 4) { - IDirect3DDevice9_DrawPrimitive(data->device, D3DPT_TRIANGLEFAN, (UINT) ((first / sizeof (Vertex)) + offset), 2); - } - } else { - const Vertex *verts = (Vertex *) (((Uint8 *) vertices) + first); - for (i = 0; i < count; ++i, verts += 4) { - IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_TRIANGLEFAN, 2, verts, sizeof (Vertex)); - } - } - break; + case SDL_RENDERCMD_FILL_RECTS: /* unused */ + break; + + case SDL_RENDERCMD_COPY: /* unused */ + break; + + case SDL_RENDERCMD_COPY_EX: /* unused */ + break; + + case SDL_RENDERCMD_GEOMETRY: + { + const size_t count = cmd->data.draw.count; + const size_t first = cmd->data.draw.first; + SetDrawState(data, cmd); + if (vbo) { + IDirect3DDevice9_DrawPrimitive(data->device, D3DPT_TRIANGLELIST, (UINT)(first / sizeof(Vertex)), (UINT)count / 3); + } else { + const Vertex *verts = (Vertex *)(((Uint8 *)vertices) + first); + IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_TRIANGLELIST, (UINT)count / 3, verts, sizeof(Vertex)); } + break; + } - case SDL_RENDERCMD_COPY: { - const size_t count = cmd->data.draw.count; - const size_t first = cmd->data.draw.first; - SetDrawState(data, cmd); - if (vbo) { - size_t offset = 0; - for (i = 0; i < count; ++i, offset += 4) { - IDirect3DDevice9_DrawPrimitive(data->device, D3DPT_TRIANGLEFAN, (UINT) ((first / sizeof (Vertex)) + offset), 2); - } - } else { - const Vertex *verts = (Vertex *) (((Uint8 *) vertices) + first); - for (i = 0; i < count; ++i, verts += 4) { - IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_TRIANGLEFAN, 2, verts, sizeof (Vertex)); - } - } - break; - } - - case SDL_RENDERCMD_COPY_EX: { - const size_t first = cmd->data.draw.first; - const Vertex *verts = (Vertex *) (((Uint8 *) vertices) + first); - const Vertex *transvert = verts + 4; - const float translatex = transvert->x; - const float translatey = transvert->y; - const float rotation = transvert->z; - const Float4X4 d3dmatrix = MatrixMultiply(MatrixRotationZ(rotation), MatrixTranslation(translatex, translatey, 0)); - SetDrawState(data, cmd); - - IDirect3DDevice9_SetTransform(data->device, D3DTS_VIEW, (D3DMATRIX*)&d3dmatrix); - - if (vbo) { - IDirect3DDevice9_DrawPrimitive(data->device, D3DPT_TRIANGLEFAN, (UINT) (first / sizeof (Vertex)), 2); - } else { - IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_TRIANGLEFAN, 2, verts, sizeof (Vertex)); - } - break; - } - - case SDL_RENDERCMD_NO_OP: - break; + case SDL_RENDERCMD_NO_OP: + break; } cmd = cmd->next; @@ -1442,18 +1293,17 @@ D3D_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *verti return 0; } - -static int -D3D_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, - Uint32 format, void * pixels, int pitch) +static int D3D_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect, + Uint32 format, void *pixels, int pitch) { - D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; + D3D_RenderData *data = (D3D_RenderData *)renderer->driverdata; D3DSURFACE_DESC desc; LPDIRECT3DSURFACE9 backBuffer; LPDIRECT3DSURFACE9 surface; RECT d3drect; D3DLOCKED_RECT locked; HRESULT result; + int status; if (data->currentRenderTarget) { backBuffer = data->currentRenderTarget; @@ -1478,9 +1328,9 @@ D3D_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, } d3drect.left = rect->x; - d3drect.right = rect->x + rect->w; + d3drect.right = (LONG)rect->x + rect->w; d3drect.top = rect->y; - d3drect.bottom = rect->y + rect->h; + d3drect.bottom = (LONG)rect->y + rect->h; result = IDirect3DSurface9_LockRect(surface, &locked, &d3drect, D3DLOCK_READONLY); if (FAILED(result)) { @@ -1488,21 +1338,20 @@ D3D_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, return D3D_SetError("LockRect()", result); } - SDL_ConvertPixels(rect->w, rect->h, - D3DFMTToPixelFormat(desc.Format), locked.pBits, locked.Pitch, - format, pixels, pitch); + status = SDL_ConvertPixels(rect->w, rect->h, + D3DFMTToPixelFormat(desc.Format), locked.pBits, locked.Pitch, + format, pixels, pitch); IDirect3DSurface9_UnlockRect(surface); IDirect3DSurface9_Release(surface); - return 0; + return status; } -static void -D3D_RenderPresent(SDL_Renderer * renderer) +static int D3D_RenderPresent(SDL_Renderer *renderer) { - D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; + D3D_RenderData *data = (D3D_RenderData *)renderer->driverdata; HRESULT result; if (!data->beginScene) { @@ -1513,32 +1362,34 @@ D3D_RenderPresent(SDL_Renderer * renderer) result = IDirect3DDevice9_TestCooperativeLevel(data->device); if (result == D3DERR_DEVICELOST) { /* We'll reset later */ - return; + return -1; } if (result == D3DERR_DEVICENOTRESET) { D3D_Reset(renderer); } result = IDirect3DDevice9_Present(data->device, NULL, NULL, NULL, NULL); if (FAILED(result)) { - D3D_SetError("Present()", result); + return D3D_SetError("Present()", result); } + return 0; } -static void -D3D_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) +static void D3D_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture) { - D3D_RenderData *renderdata = (D3D_RenderData *) renderer->driverdata; - D3D_TextureData *data = (D3D_TextureData *) texture->driverdata; + D3D_RenderData *renderdata = (D3D_RenderData *)renderer->driverdata; + D3D_TextureData *data = (D3D_TextureData *)texture->driverdata; if (renderdata->drawstate.texture == texture) { renderdata->drawstate.texture = NULL; renderdata->drawstate.shader = NULL; IDirect3DDevice9_SetPixelShader(renderdata->device, NULL); IDirect3DDevice9_SetTexture(renderdata->device, 0, NULL); +#if SDL_HAVE_YUV if (data->yuv) { IDirect3DDevice9_SetTexture(renderdata->device, 1, NULL); IDirect3DDevice9_SetTexture(renderdata->device, 2, NULL); } +#endif } if (!data) { @@ -1546,17 +1397,18 @@ D3D_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) } D3D_DestroyTextureRep(&data->texture); +#if SDL_HAVE_YUV D3D_DestroyTextureRep(&data->utexture); D3D_DestroyTextureRep(&data->vtexture); SDL_free(data->pixels); +#endif SDL_free(data); texture->driverdata = NULL; } -static void -D3D_DestroyRenderer(SDL_Renderer * renderer) +static void D3D_DestroyRenderer(SDL_Renderer *renderer) { - D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; + D3D_RenderData *data = (D3D_RenderData *)renderer->driverdata; if (data) { int i; @@ -1566,16 +1418,18 @@ D3D_DestroyRenderer(SDL_Renderer * renderer) IDirect3DSurface9_Release(data->defaultRenderTarget); data->defaultRenderTarget = NULL; } - if (data->currentRenderTarget != NULL) { + if (data->currentRenderTarget) { IDirect3DSurface9_Release(data->currentRenderTarget); data->currentRenderTarget = NULL; } +#if SDL_HAVE_YUV for (i = 0; i < SDL_arraysize(data->shaders); ++i) { if (data->shaders[i]) { IDirect3DPixelShader9_Release(data->shaders[i]); data->shaders[i] = NULL; } } +#endif /* Release all vertex buffers */ for (i = 0; i < SDL_arraysize(data->vertexBuffers); ++i) { if (data->vertexBuffers[i]) { @@ -1596,21 +1450,26 @@ D3D_DestroyRenderer(SDL_Renderer * renderer) SDL_free(renderer); } -static int -D3D_Reset(SDL_Renderer * renderer) +static int D3D_Reset(SDL_Renderer *renderer) { - D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; + D3D_RenderData *data = (D3D_RenderData *)renderer->driverdata; const Float4X4 d3dmatrix = MatrixIdentity(); HRESULT result; SDL_Texture *texture; int i; + /* Cancel any scene that we've started */ + if (!data->beginScene) { + IDirect3DDevice9_EndScene(data->device); + data->beginScene = SDL_TRUE; + } + /* Release the default render target before reset */ if (data->defaultRenderTarget) { IDirect3DSurface9_Release(data->defaultRenderTarget); data->defaultRenderTarget = NULL; } - if (data->currentRenderTarget != NULL) { + if (data->currentRenderTarget) { IDirect3DSurface9_Release(data->currentRenderTarget); data->currentRenderTarget = NULL; } @@ -1659,8 +1518,7 @@ D3D_Reset(SDL_Renderer * renderer) data->drawstate.texture = NULL; data->drawstate.shader = NULL; data->drawstate.blend = SDL_BLENDMODE_INVALID; - data->drawstate.is_copy_ex = SDL_FALSE; - IDirect3DDevice9_SetTransform(data->device, D3DTS_VIEW, (D3DMATRIX*)&d3dmatrix); + IDirect3DDevice9_SetTransform(data->device, D3DTS_VIEW, (D3DMATRIX *)&d3dmatrix); /* Let the application know that render targets were reset */ { @@ -1672,8 +1530,24 @@ D3D_Reset(SDL_Renderer * renderer) return 0; } -SDL_Renderer * -D3D_CreateRenderer(SDL_Window * window, Uint32 flags) +static int D3D_SetVSync(SDL_Renderer *renderer, const int vsync) +{ + D3D_RenderData *data = renderer->driverdata; + if (vsync) { + data->pparams.PresentationInterval = D3DPRESENT_INTERVAL_ONE; + renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; + } else { + data->pparams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; + renderer->info.flags &= ~SDL_RENDERER_PRESENTVSYNC; + } + if (D3D_Reset(renderer) < 0) { + /* D3D_Reset will call SDL_SetError() */ + return -1; + } + return 0; +} + +SDL_Renderer *D3D_CreateRenderer(SDL_Window *window, Uint32 flags) { SDL_Renderer *renderer; D3D_RenderData *data; @@ -1694,7 +1568,7 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags) return NULL; } - data = (D3D_RenderData *) SDL_calloc(1, sizeof(*data)); + data = (D3D_RenderData *)SDL_calloc(1, sizeof(*data)); if (!data) { SDL_free(renderer); SDL_OutOfMemory(); @@ -1709,26 +1583,28 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags) } renderer->WindowEvent = D3D_WindowEvent; + renderer->GetOutputSize = D3D_GetOutputSize; renderer->SupportsBlendMode = D3D_SupportsBlendMode; renderer->CreateTexture = D3D_CreateTexture; renderer->UpdateTexture = D3D_UpdateTexture; +#if SDL_HAVE_YUV renderer->UpdateTextureYUV = D3D_UpdateTextureYUV; +#endif renderer->LockTexture = D3D_LockTexture; renderer->UnlockTexture = D3D_UnlockTexture; renderer->SetTextureScaleMode = D3D_SetTextureScaleMode; renderer->SetRenderTarget = D3D_SetRenderTarget; renderer->QueueSetViewport = D3D_QueueSetViewport; - renderer->QueueSetDrawColor = D3D_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */ + renderer->QueueSetDrawColor = D3D_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */ renderer->QueueDrawPoints = D3D_QueueDrawPoints; - renderer->QueueDrawLines = D3D_QueueDrawPoints; /* lines and points queue vertices the same way. */ - renderer->QueueFillRects = D3D_QueueFillRects; - renderer->QueueCopy = D3D_QueueCopy; - renderer->QueueCopyEx = D3D_QueueCopyEx; + renderer->QueueDrawLines = D3D_QueueDrawPoints; /* lines and points queue vertices the same way. */ + renderer->QueueGeometry = D3D_QueueGeometry; renderer->RunCommandQueue = D3D_RunCommandQueue; renderer->RenderReadPixels = D3D_RenderReadPixels; renderer->RenderPresent = D3D_RenderPresent; renderer->DestroyTexture = D3D_DestroyTexture; renderer->DestroyRenderer = D3D_DestroyRenderer; + renderer->SetVSync = D3D_SetVSync; renderer->info = D3D_RenderDriver.info; renderer->info.flags = (SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE); renderer->driverdata = data; @@ -1737,7 +1613,7 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags) SDL_GetWindowWMInfo(window, &windowinfo); window_flags = SDL_GetWindowFlags(window); - SDL_GetWindowSize(window, &w, &h); + SDL_GetWindowSizeInPixels(window, &w, &h); SDL_GetWindowDisplayMode(window, &fullscreen_mode); SDL_zero(pparams); @@ -1813,9 +1689,6 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags) IDirect3DDevice9_GetDeviceCaps(data->device, &caps); renderer->info.max_texture_width = caps.MaxTextureWidth; renderer->info.max_texture_height = caps.MaxTextureHeight; - if (caps.NumSimultaneousRTs >= 2) { - renderer->info.flags |= SDL_RENDERER_TARGETTEXTURE; - } if (caps.PrimitiveMiscCaps & D3DPMISCCAPS_SEPARATEALPHABLEND) { data->enableSeparateAlphaBlend = SDL_TRUE; @@ -1827,7 +1700,7 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags) /* Set up parameters for rendering */ D3D_InitRenderState(data); - +#if SDL_HAVE_YUV if (caps.MaxSimultaneousTextures >= 3) { int i; for (i = 0; i < SDL_arraysize(data->shaders); ++i) { @@ -1841,7 +1714,10 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_IYUV; } } - +#endif + data->drawstate.viewport_dirty = SDL_TRUE; + data->drawstate.cliprect_dirty = SDL_TRUE; + data->drawstate.cliprect_enabled_dirty = SDL_TRUE; data->drawstate.blend = SDL_BLENDMODE_INVALID; return renderer; @@ -1849,25 +1725,23 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags) SDL_RenderDriver D3D_RenderDriver = { D3D_CreateRenderer, - { - "direct3d", - (SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE), - 1, - {SDL_PIXELFORMAT_ARGB8888}, - 0, - 0} + { "direct3d", + (SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE), + 1, + { SDL_PIXELFORMAT_ARGB8888 }, + 0, + 0 } }; -#endif /* SDL_VIDEO_RENDER_D3D && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_D3D */ -#ifdef __WIN32__ +#if defined(__WIN32__) || defined(__WINGDK__) /* This function needs to always exist on Windows, for the Dynamic API. */ -IDirect3DDevice9 * -SDL_RenderGetD3D9Device(SDL_Renderer * renderer) +IDirect3DDevice9 *SDL_RenderGetD3D9Device(SDL_Renderer *renderer) { IDirect3DDevice9 *device = NULL; -#if SDL_VIDEO_RENDER_D3D && !SDL_RENDER_DISABLED - D3D_RenderData *data = (D3D_RenderData *) renderer->driverdata; +#if SDL_VIDEO_RENDER_D3D + D3D_RenderData *data = (D3D_RenderData *)renderer->driverdata; /* Make sure that this is a D3D renderer */ if (renderer->DestroyRenderer != D3D_DestroyRenderer) { @@ -1879,10 +1753,10 @@ SDL_RenderGetD3D9Device(SDL_Renderer * renderer) if (device) { IDirect3DDevice9_AddRef(device); } -#endif /* SDL_VIDEO_RENDER_D3D && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_D3D */ return device; } -#endif /* __WIN32__ */ +#endif /* defined(__WIN32__) || defined(__WINGDK__) */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/render/direct3d/SDL_shaders_d3d.c b/SDL2-2.30.5/src/render/direct3d/SDL_shaders_d3d.c similarity index 98% rename from SDL2-2.0.12/src/render/direct3d/SDL_shaders_d3d.c rename to SDL2-2.30.5/src/render/direct3d/SDL_shaders_d3d.c index 7ab4cbc..2f55d80 100644 --- a/SDL2-2.0.12/src/render/direct3d/SDL_shaders_d3d.c +++ b/SDL2-2.30.5/src/render/direct3d/SDL_shaders_d3d.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,7 +23,7 @@ #include "SDL_render.h" #include "SDL_system.h" -#if SDL_VIDEO_RENDER_D3D && !SDL_RENDER_DISABLED +#if SDL_VIDEO_RENDER_D3D #include "../../core/windows/SDL_windows.h" @@ -257,7 +257,6 @@ static const DWORD D3D9_PixelShader_YUV_BT709[] = { 0x90e40000, 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff }; - static const DWORD *D3D9_shaders[] = { D3D9_PixelShader_YUV_JPEG, D3D9_PixelShader_YUV_BT601, @@ -269,6 +268,6 @@ HRESULT D3D9_CreatePixelShader(IDirect3DDevice9 *d3dDevice, D3D9_Shader shader, return IDirect3DDevice9_CreatePixelShader(d3dDevice, D3D9_shaders[shader], pixelShader); } -#endif /* SDL_VIDEO_RENDER_D3D && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_D3D */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/render/direct3d/SDL_shaders_d3d.h b/SDL2-2.30.5/src/render/direct3d/SDL_shaders_d3d.h similarity index 94% rename from SDL2-2.0.12/src/render/direct3d/SDL_shaders_d3d.h rename to SDL2-2.30.5/src/render/direct3d/SDL_shaders_d3d.h index 4c8e711..89cd1ea 100644 --- a/SDL2-2.0.12/src/render/direct3d/SDL_shaders_d3d.h +++ b/SDL2-2.30.5/src/render/direct3d/SDL_shaders_d3d.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -22,7 +22,8 @@ /* D3D9 shader implementation */ -typedef enum { +typedef enum +{ SHADER_YUV_JPEG, SHADER_YUV_BT601, SHADER_YUV_BT709, diff --git a/SDL2-2.0.12/src/render/direct3d11/SDL_render_d3d11.c b/SDL2-2.30.5/src/render/direct3d11/SDL_render_d3d11.c similarity index 63% rename from SDL2-2.0.12/src/render/direct3d11/SDL_render_d3d11.c rename to SDL2-2.30.5/src/render/direct3d11/SDL_render_d3d11.c index 735173e..8249256 100644 --- a/SDL2-2.0.12/src/render/direct3d11/SDL_render_d3d11.c +++ b/SDL2-2.30.5/src/render/direct3d11/SDL_render_d3d11.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,10 +20,16 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED +#include "SDL_render.h" +#include "SDL_system.h" + +#if SDL_VIDEO_RENDER_D3D11 #define COBJMACROS #include "../../core/windows/SDL_windows.h" +#if !defined(__WINRT__) +#include "../../video/windows/SDL_windowswindow.h" +#endif #include "SDL_hints.h" #include "SDL_loadso.h" #include "SDL_syswm.h" @@ -45,19 +51,25 @@ #if WINAPI_FAMILY == WINAPI_FAMILY_APP #include /* TODO, WinRT, XAML: get the ISwapChainBackgroundPanelNative from something other than a global var */ -extern ISwapChainBackgroundPanelNative * WINRT_GlobalSwapChainBackgroundPanelNative; -#endif /* WINAPI_FAMILY == WINAPI_FAMILY_APP */ - -#endif /* __WINRT__ */ +extern ISwapChainBackgroundPanelNative *WINRT_GlobalSwapChainBackgroundPanelNative; +#endif /* WINAPI_FAMILY == WINAPI_FAMILY_APP */ +#endif /* __WINRT__ */ +#if defined(_MSC_VER) && !defined(__clang__) +#define SDL_COMPOSE_ERROR(str) __FUNCTION__ ", " str +#else #define SDL_COMPOSE_ERROR(str) SDL_STRINGIFY_ARG(__FUNCTION__) ", " str +#endif -#define SAFE_RELEASE(X) if ((X)) { IUnknown_Release(SDL_static_cast(IUnknown*, X)); X = NULL; } +#define SAFE_RELEASE(X) \ + if ((X)) { \ + IUnknown_Release(SDL_static_cast(IUnknown *, X)); \ + X = NULL; \ + } - -/* !!! FIXME: vertex buffer bandwidth could be significantly lower; move color to a uniform, only use UV coords - !!! FIXME: when textures are needed, and don't ever pass Z, since it's always zero. */ +/* !!! FIXME: vertex buffer bandwidth could be lower; only use UV coords when + !!! FIXME: textures are needed. */ /* Vertex shader, common values */ typedef struct @@ -69,9 +81,9 @@ typedef struct /* Per-vertex data */ typedef struct { - Float3 pos; + Float2 pos; Float2 tex; - Float4 color; + SDL_Color color; } VertexPositionColor; /* Per-texture data */ @@ -84,7 +96,7 @@ typedef struct int lockedTexturePositionX; int lockedTexturePositionY; D3D11_FILTER scaleMode; - +#if SDL_HAVE_YUV /* YV12 texture support */ SDL_bool yuv; ID3D11Texture2D *mainTextureU; @@ -100,6 +112,7 @@ typedef struct Uint8 *pixels; int pitch; SDL_Rect locked_rect; +#endif } D3D11_TextureData; /* Blend mode data */ @@ -159,15 +172,14 @@ typedef struct int currentVertexBuffer; } D3D11_RenderData; - /* Define D3D GUIDs here so we don't have to include uuid.lib. -* -* Fix for SDL bug https://bugzilla.libsdl.org/show_bug.cgi?id=3437: -* The extra 'SDL_' was added to the start of each IID's name, in order -* to prevent build errors on both MinGW-w64 and WinRT/UWP. -* (SDL bug https://bugzilla.libsdl.org/show_bug.cgi?id=3336 led to -* linker errors in WinRT/UWP builds.) -*/ + * + * Fix for SDL bug https://bugzilla.libsdl.org/show_bug.cgi?id=3437: + * The extra 'SDL_' was added to the start of each IID's name, in order + * to prevent build errors on both MinGW-w64 and WinRT/UWP. + * (SDL bug https://bugzilla.libsdl.org/show_bug.cgi?id=3336 led to + * linker errors in WinRT/UWP builds.) + */ #ifdef __GNUC__ #pragma GCC diagnostic push @@ -176,55 +188,52 @@ typedef struct static const GUID SDL_IID_IDXGIFactory2 = { 0x50c83a1c, 0xe072, 0x4c48, { 0x87, 0xb0, 0x36, 0x30, 0xfa, 0x36, 0xa6, 0xd0 } }; static const GUID SDL_IID_IDXGIDevice1 = { 0x77db970f, 0x6276, 0x48ba, { 0xba, 0x28, 0x07, 0x01, 0x43, 0xb4, 0x39, 0x2c } }; +#if defined(__WINRT__) && NTDDI_VERSION > NTDDI_WIN8 static const GUID SDL_IID_IDXGIDevice3 = { 0x6007896c, 0x3244, 0x4afd, { 0xbf, 0x18, 0xa6, 0xd3, 0xbe, 0xda, 0x50, 0x23 } }; +#endif static const GUID SDL_IID_ID3D11Texture2D = { 0x6f15aaf2, 0xd208, 0x4e89, { 0x9a, 0xb4, 0x48, 0x95, 0x35, 0xd3, 0x4f, 0x9c } }; static const GUID SDL_IID_ID3D11Device1 = { 0xa04bfb29, 0x08ef, 0x43d6, { 0xa4, 0x9c, 0xa9, 0xbd, 0xbd, 0xcb, 0xe6, 0x86 } }; static const GUID SDL_IID_ID3D11DeviceContext1 = { 0xbb2c6faa, 0xb5fb, 0x4082, { 0x8e, 0x6b, 0x38, 0x8b, 0x8c, 0xfa, 0x90, 0xe1 } }; -static const GUID SDL_IID_ID3D11Debug = { 0x79cf2233, 0x7536, 0x4948, { 0x9d, 0x36, 0x1e, 0x46, 0x92, 0xdc, 0x57, 0x60 } }; +/*static const GUID SDL_IID_ID3D11Debug = { 0x79cf2233, 0x7536, 0x4948, { 0x9d, 0x36, 0x1e, 0x46, 0x92, 0xdc, 0x57, 0x60 } };*/ #ifdef __GNUC__ #pragma GCC diagnostic pop #endif - - -Uint32 -D3D11_DXGIFormatToSDLPixelFormat(DXGI_FORMAT dxgiFormat) +Uint32 D3D11_DXGIFormatToSDLPixelFormat(DXGI_FORMAT dxgiFormat) { switch (dxgiFormat) { - case DXGI_FORMAT_B8G8R8A8_UNORM: - return SDL_PIXELFORMAT_ARGB8888; - case DXGI_FORMAT_B8G8R8X8_UNORM: - return SDL_PIXELFORMAT_RGB888; - default: - return SDL_PIXELFORMAT_UNKNOWN; + case DXGI_FORMAT_B8G8R8A8_UNORM: + return SDL_PIXELFORMAT_ARGB8888; + case DXGI_FORMAT_B8G8R8X8_UNORM: + return SDL_PIXELFORMAT_RGB888; + default: + return SDL_PIXELFORMAT_UNKNOWN; } } -static DXGI_FORMAT -SDLPixelFormatToDXGIFormat(Uint32 sdlFormat) +static DXGI_FORMAT SDLPixelFormatToDXGIFormat(Uint32 sdlFormat) { switch (sdlFormat) { - case SDL_PIXELFORMAT_ARGB8888: - return DXGI_FORMAT_B8G8R8A8_UNORM; - case SDL_PIXELFORMAT_RGB888: - return DXGI_FORMAT_B8G8R8X8_UNORM; - case SDL_PIXELFORMAT_YV12: - case SDL_PIXELFORMAT_IYUV: - case SDL_PIXELFORMAT_NV12: /* For the Y texture */ - case SDL_PIXELFORMAT_NV21: /* For the Y texture */ - return DXGI_FORMAT_R8_UNORM; - default: - return DXGI_FORMAT_UNKNOWN; + case SDL_PIXELFORMAT_ARGB8888: + return DXGI_FORMAT_B8G8R8A8_UNORM; + case SDL_PIXELFORMAT_RGB888: + return DXGI_FORMAT_B8G8R8X8_UNORM; + case SDL_PIXELFORMAT_YV12: + case SDL_PIXELFORMAT_IYUV: + case SDL_PIXELFORMAT_NV12: /* For the Y texture */ + case SDL_PIXELFORMAT_NV21: /* For the Y texture */ + return DXGI_FORMAT_R8_UNORM; + default: + return DXGI_FORMAT_UNKNOWN; } } -static void D3D11_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture); +static void D3D11_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture); -static void -D3D11_ReleaseAll(SDL_Renderer * renderer) +static void D3D11_ReleaseAll(SDL_Renderer *renderer) { - D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata; + D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata; SDL_Texture *texture = NULL; /* Release all textures */ @@ -265,7 +274,7 @@ D3D11_ReleaseAll(SDL_Renderer * renderer) SAFE_RELEASE(data->clippedRasterizer); SAFE_RELEASE(data->vertexShaderConstants); - data->swapEffect = (DXGI_SWAP_EFFECT) 0; + data->swapEffect = (DXGI_SWAP_EFFECT)0; data->rotation = DXGI_MODE_ROTATION_UNSPECIFIED; data->currentRenderTargetView = NULL; data->currentRasterizerState = NULL; @@ -288,10 +297,9 @@ D3D11_ReleaseAll(SDL_Renderer * renderer) } } -static void -D3D11_DestroyRenderer(SDL_Renderer * renderer) +static void D3D11_DestroyRenderer(SDL_Renderer *renderer) { - D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata; + D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata; D3D11_ReleaseAll(renderer); if (data) { SDL_free(data); @@ -345,10 +353,9 @@ static D3D11_BLEND_OP GetBlendEquation(SDL_BlendOperation operation) } } -static ID3D11BlendState * -D3D11_CreateBlendState(SDL_Renderer * renderer, SDL_BlendMode blendMode) +static ID3D11BlendState *D3D11_CreateBlendState(SDL_Renderer *renderer, SDL_BlendMode blendMode) { - D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata; + D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata; SDL_BlendFactor srcColorFactor = SDL_GetBlendModeSrcColorFactor(blendMode); SDL_BlendFactor srcAlphaFactor = SDL_GetBlendModeSrcAlphaFactor(blendMode); SDL_BlendOperation colorOperation = SDL_GetBlendModeColorOperation(blendMode); @@ -392,12 +399,11 @@ D3D11_CreateBlendState(SDL_Renderer * renderer, SDL_BlendMode blendMode) } /* Create resources that depend on the device. */ -static HRESULT -D3D11_CreateDeviceResources(SDL_Renderer * renderer) +static HRESULT D3D11_CreateDeviceResources(SDL_Renderer *renderer) { - typedef HRESULT(WINAPI *PFN_CREATE_DXGI_FACTORY)(REFIID riid, void **ppFactory); + typedef HRESULT(WINAPI * PFN_CREATE_DXGI_FACTORY)(REFIID riid, void **ppFactory); PFN_CREATE_DXGI_FACTORY CreateDXGIFactoryFunc; - D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata; + D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata; PFN_D3D11_CREATE_DEVICE D3D11CreateDeviceFunc; ID3D11Device *d3dDevice = NULL; ID3D11DeviceContext *d3dContext = NULL; @@ -411,8 +417,7 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) * Don't forget to declare your application's minimum required feature level in its * description. All applications are assumed to support 9.1 unless otherwise stated. */ - D3D_FEATURE_LEVEL featureLevels[] = - { + D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, @@ -478,6 +483,11 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) creationFlags |= D3D11_CREATE_DEVICE_DEBUG; } + /* Create a single-threaded device unless the app requests otherwise. */ + if (!SDL_GetHintBoolean(SDL_HINT_RENDER_DIRECT3D_THREADSAFE, SDL_FALSE)) { + creationFlags |= D3D11_CREATE_DEVICE_SINGLETHREADED; + } + /* Create the Direct3D 11 API device object and a corresponding context. */ result = D3D11CreateDeviceFunc( data->dxgiAdapter, @@ -486,11 +496,11 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) creationFlags, /* Set set debug and Direct2D compatibility flags. */ featureLevels, /* List of feature levels this app can support. */ SDL_arraysize(featureLevels), - D3D11_SDK_VERSION, /* Always set this to D3D11_SDK_VERSION for Windows Store apps. */ - &d3dDevice, /* Returns the Direct3D device created. */ + D3D11_SDK_VERSION, /* Always set this to D3D11_SDK_VERSION for Windows Store apps. */ + &d3dDevice, /* Returns the Direct3D device created. */ &data->featureLevel, /* Returns feature level of device created. */ - &d3dContext /* Returns the device immediate context. */ - ); + &d3dContext /* Returns the device immediate context. */ + ); if (FAILED(result)) { WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("D3D11CreateDevice"), result); goto done; @@ -528,29 +538,29 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) * http://msdn.microsoft.com/en-us/library/windows/apps/ff476876.aspx */ switch (data->featureLevel) { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: - renderer->info.max_texture_width = renderer->info.max_texture_height = 16384; - break; + case D3D_FEATURE_LEVEL_11_1: + case D3D_FEATURE_LEVEL_11_0: + renderer->info.max_texture_width = renderer->info.max_texture_height = 16384; + break; - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: - renderer->info.max_texture_width = renderer->info.max_texture_height = 8192; - break; + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + renderer->info.max_texture_width = renderer->info.max_texture_height = 8192; + break; - case D3D_FEATURE_LEVEL_9_3: - renderer->info.max_texture_width = renderer->info.max_texture_height = 4096; - break; + case D3D_FEATURE_LEVEL_9_3: + renderer->info.max_texture_width = renderer->info.max_texture_height = 4096; + break; - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: - renderer->info.max_texture_width = renderer->info.max_texture_height = 2048; - break; + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + renderer->info.max_texture_width = renderer->info.max_texture_height = 2048; + break; - default: - SDL_SetError("%s, Unexpected feature level: %d", __FUNCTION__, data->featureLevel); - result = E_FAIL; - goto done; + default: + SDL_SetError("%s, Unexpected feature level: %d", __FUNCTION__, data->featureLevel); + result = E_FAIL; + goto done; } if (D3D11_CreateVertexShader(data->d3dDevice, &data->vertexShader, &data->inputLayout) < 0) { @@ -569,10 +579,9 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) constantBufferDesc.Usage = D3D11_USAGE_DEFAULT; constantBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; result = ID3D11Device_CreateBuffer(data->d3dDevice, - &constantBufferDesc, - NULL, - &data->vertexShaderConstants - ); + &constantBufferDesc, + NULL, + &data->vertexShaderConstants); if (FAILED(result)) { WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateBuffer [vertex shader constants]"), result); goto done; @@ -590,9 +599,8 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) samplerDesc.MinLOD = 0.0f; samplerDesc.MaxLOD = D3D11_FLOAT32_MAX; result = ID3D11Device_CreateSamplerState(data->d3dDevice, - &samplerDesc, - &data->nearestPixelSampler - ); + &samplerDesc, + &data->nearestPixelSampler); if (FAILED(result)) { WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateSamplerState [nearest-pixel filter]"), result); goto done; @@ -600,9 +608,8 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer) samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; result = ID3D11Device_CreateSamplerState(data->d3dDevice, - &samplerDesc, - &data->linearSampler - ); + &samplerDesc, + &data->linearSampler); if (FAILED(result)) { WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateSamplerState [linear filter]"), result); goto done; @@ -654,31 +661,28 @@ done: return result; } -#ifdef __WIN32__ +#if defined(__WIN32__) || defined(__WINGDK__) -static DXGI_MODE_ROTATION -D3D11_GetCurrentRotation() +static DXGI_MODE_ROTATION D3D11_GetCurrentRotation() { /* FIXME */ return DXGI_MODE_ROTATION_IDENTITY; } -#endif /* __WIN32__ */ +#endif /* defined(__WIN32__) || defined(__WINGDK__) */ -static BOOL -D3D11_IsDisplayRotated90Degrees(DXGI_MODE_ROTATION rotation) +static BOOL D3D11_IsDisplayRotated90Degrees(DXGI_MODE_ROTATION rotation) { switch (rotation) { - case DXGI_MODE_ROTATION_ROTATE90: - case DXGI_MODE_ROTATION_ROTATE270: - return TRUE; - default: - return FALSE; + case DXGI_MODE_ROTATION_ROTATE90: + case DXGI_MODE_ROTATION_ROTATE270: + return TRUE; + default: + return FALSE; } } -static int -D3D11_GetRotationForCurrentRenderTarget(SDL_Renderer * renderer) +static int D3D11_GetRotationForCurrentRenderTarget(SDL_Renderer *renderer) { D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata; if (data->currentOffscreenRenderTargetView) { @@ -688,54 +692,55 @@ D3D11_GetRotationForCurrentRenderTarget(SDL_Renderer * renderer) } } -static int -D3D11_GetViewportAlignedD3DRect(SDL_Renderer * renderer, const SDL_Rect * sdlRect, D3D11_RECT * outRect, BOOL includeViewportOffset) +static int D3D11_GetViewportAlignedD3DRect(SDL_Renderer *renderer, const SDL_Rect *sdlRect, D3D11_RECT *outRect, BOOL includeViewportOffset) { + D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata; const int rotation = D3D11_GetRotationForCurrentRenderTarget(renderer); + const SDL_Rect *viewport = &data->currentViewport; + switch (rotation) { - case DXGI_MODE_ROTATION_IDENTITY: - outRect->left = sdlRect->x; - outRect->right = sdlRect->x + sdlRect->w; - outRect->top = sdlRect->y; - outRect->bottom = sdlRect->y + sdlRect->h; - if (includeViewportOffset) { - outRect->left += renderer->viewport.x; - outRect->right += renderer->viewport.x; - outRect->top += renderer->viewport.y; - outRect->bottom += renderer->viewport.y; - } - break; - case DXGI_MODE_ROTATION_ROTATE270: - outRect->left = sdlRect->y; - outRect->right = sdlRect->y + sdlRect->h; - outRect->top = renderer->viewport.w - sdlRect->x - sdlRect->w; - outRect->bottom = renderer->viewport.w - sdlRect->x; - break; - case DXGI_MODE_ROTATION_ROTATE180: - outRect->left = renderer->viewport.w - sdlRect->x - sdlRect->w; - outRect->right = renderer->viewport.w - sdlRect->x; - outRect->top = renderer->viewport.h - sdlRect->y - sdlRect->h; - outRect->bottom = renderer->viewport.h - sdlRect->y; - break; - case DXGI_MODE_ROTATION_ROTATE90: - outRect->left = renderer->viewport.h - sdlRect->y - sdlRect->h; - outRect->right = renderer->viewport.h - sdlRect->y; - outRect->top = sdlRect->x; - outRect->bottom = sdlRect->x + sdlRect->h; - break; - default: - return SDL_SetError("The physical display is in an unknown or unsupported rotation"); + case DXGI_MODE_ROTATION_IDENTITY: + outRect->left = sdlRect->x; + outRect->right = (LONG)sdlRect->x + sdlRect->w; + outRect->top = sdlRect->y; + outRect->bottom = (LONG)sdlRect->y + sdlRect->h; + if (includeViewportOffset) { + outRect->left += viewport->x; + outRect->right += viewport->x; + outRect->top += viewport->y; + outRect->bottom += viewport->y; + } + break; + case DXGI_MODE_ROTATION_ROTATE270: + outRect->left = sdlRect->y; + outRect->right = (LONG)sdlRect->y + sdlRect->h; + outRect->top = viewport->w - sdlRect->x - sdlRect->w; + outRect->bottom = viewport->w - sdlRect->x; + break; + case DXGI_MODE_ROTATION_ROTATE180: + outRect->left = viewport->w - sdlRect->x - sdlRect->w; + outRect->right = viewport->w - sdlRect->x; + outRect->top = viewport->h - sdlRect->y - sdlRect->h; + outRect->bottom = viewport->h - sdlRect->y; + break; + case DXGI_MODE_ROTATION_ROTATE90: + outRect->left = viewport->h - sdlRect->y - sdlRect->h; + outRect->right = viewport->h - sdlRect->y; + outRect->top = sdlRect->x; + outRect->bottom = (LONG)sdlRect->x + sdlRect->h; + break; + default: + return SDL_SetError("The physical display is in an unknown or unsupported rotation"); } return 0; } -static HRESULT -D3D11_CreateSwapChain(SDL_Renderer * renderer, int w, int h) +static HRESULT D3D11_CreateSwapChain(SDL_Renderer *renderer, int w, int h) { D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata; #ifdef __WINRT__ IUnknown *coreWindow = D3D11_GetCoreWindowFromSDLRenderer(renderer); - const BOOL usingXAML = (coreWindow == NULL); + const BOOL usingXAML = (!coreWindow); #else IUnknown *coreWindow = NULL; const BOOL usingXAML = FALSE; @@ -753,15 +758,19 @@ D3D11_CreateSwapChain(SDL_Renderer * renderer, int w, int h) swapChainDesc.SampleDesc.Quality = 0; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.BufferCount = 2; /* Use double-buffering to minimize latency. */ -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP - swapChainDesc.Scaling = DXGI_SCALING_STRETCH; /* On phone, only stretch and aspect-ratio stretch scaling are allowed. */ +#if SDL_WINAPI_FAMILY_PHONE + swapChainDesc.Scaling = DXGI_SCALING_STRETCH; /* On phone, only stretch and aspect-ratio stretch scaling are allowed. */ swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; /* On phone, no swap effects are supported. */ /* TODO, WinRT: see if Win 8.x DXGI_SWAP_CHAIN_DESC1 settings are available on Windows Phone 8.1, and if there's any advantage to having them on */ #else if (usingXAML) { swapChainDesc.Scaling = DXGI_SCALING_STRETCH; } else { - swapChainDesc.Scaling = DXGI_SCALING_NONE; + if (WIN_IsWindows8OrGreater()) { + swapChainDesc.Scaling = DXGI_SCALING_NONE; + } else { + swapChainDesc.Scaling = DXGI_SCALING_STRETCH; + } } swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; /* All Windows Store apps must use this SwapEffect. */ #endif @@ -769,29 +778,28 @@ D3D11_CreateSwapChain(SDL_Renderer * renderer, int w, int h) if (coreWindow) { result = IDXGIFactory2_CreateSwapChainForCoreWindow(data->dxgiFactory, - (IUnknown *)data->d3dDevice, - coreWindow, - &swapChainDesc, - NULL, /* Allow on all displays. */ - &data->swapChain - ); + (IUnknown *)data->d3dDevice, + coreWindow, + &swapChainDesc, + NULL, /* Allow on all displays. */ + &data->swapChain); if (FAILED(result)) { WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGIFactory2::CreateSwapChainForCoreWindow"), result); goto done; } } else if (usingXAML) { result = IDXGIFactory2_CreateSwapChainForComposition(data->dxgiFactory, - (IUnknown *)data->d3dDevice, - &swapChainDesc, - NULL, - &data->swapChain); + (IUnknown *)data->d3dDevice, + &swapChainDesc, + NULL, + &data->swapChain); if (FAILED(result)) { WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGIFactory2::CreateSwapChainForComposition"), result); goto done; } #if WINAPI_FAMILY == WINAPI_FAMILY_APP - result = ISwapChainBackgroundPanelNative_SetSwapChain(WINRT_GlobalSwapChainBackgroundPanelNative, (IDXGISwapChain *) data->swapChain); + result = ISwapChainBackgroundPanelNative_SetSwapChain(WINRT_GlobalSwapChainBackgroundPanelNative, (IDXGISwapChain *)data->swapChain); if (FAILED(result)) { WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ISwapChainBackgroundPanelNative::SetSwapChain"), result); goto done; @@ -802,19 +810,18 @@ D3D11_CreateSwapChain(SDL_Renderer * renderer, int w, int h) goto done; #endif } else { -#ifdef __WIN32__ +#if defined(__WIN32__) || defined(__WINGDK__) SDL_SysWMinfo windowinfo; SDL_VERSION(&windowinfo.version); SDL_GetWindowWMInfo(renderer->window, &windowinfo); result = IDXGIFactory2_CreateSwapChainForHwnd(data->dxgiFactory, - (IUnknown *)data->d3dDevice, - windowinfo.info.win.window, - &swapChainDesc, - NULL, - NULL, /* Allow on all displays. */ - &data->swapChain - ); + (IUnknown *)data->d3dDevice, + windowinfo.info.win.window, + &swapChainDesc, + NULL, + NULL, /* Allow on all displays. */ + &data->swapChain); if (FAILED(result)) { WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGIFactory2::CreateSwapChainForHwnd"), result); goto done; @@ -822,9 +829,9 @@ D3D11_CreateSwapChain(SDL_Renderer * renderer, int w, int h) IDXGIFactory_MakeWindowAssociation(data->dxgiFactory, windowinfo.info.win.window, DXGI_MWA_NO_WINDOW_CHANGES); #else - SDL_SetError(__FUNCTION__", Unable to find something to attach a swap chain to"); + SDL_SetError(__FUNCTION__ ", Unable to find something to attach a swap chain to"); goto done; -#endif /* ifdef __WIN32__ / else */ +#endif /* defined(__WIN32__) || defined(__WINGDK__) / else */ } data->swapEffect = swapChainDesc.SwapEffect; @@ -833,19 +840,17 @@ done: return result; } -static void -D3D11_ReleaseMainRenderTargetView(SDL_Renderer * renderer) +static void D3D11_ReleaseMainRenderTargetView(SDL_Renderer *renderer) { D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata; ID3D11DeviceContext_OMSetRenderTargets(data->d3dContext, 0, NULL, NULL); SAFE_RELEASE(data->mainRenderTargetView); } -static HRESULT D3D11_UpdateForWindowSizeChange(SDL_Renderer * renderer); - +static HRESULT D3D11_UpdateForWindowSizeChange(SDL_Renderer *renderer); HRESULT -D3D11_HandleDeviceLost(SDL_Renderer * renderer) +D3D11_HandleDeviceLost(SDL_Renderer *renderer) { HRESULT result = S_OK; @@ -874,8 +879,7 @@ D3D11_HandleDeviceLost(SDL_Renderer * renderer) } /* Initialize all resources that change when the window's size changes. */ -static HRESULT -D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) +static HRESULT D3D11_CreateWindowSizeDependentResources(SDL_Renderer *renderer) { D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata; ID3D11Texture2D *backBuffer = NULL; @@ -888,7 +892,11 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) /* The width and height of the swap chain must be based on the display's * non-rotated size. */ +#if defined(__WINRT__) SDL_GetWindowSize(renderer->window, &w, &h); +#else + SDL_GetWindowSizeInPixels(renderer->window, &w, &h); +#endif data->rotation = D3D11_GetCurrentRotation(); /* SDL_Log("%s: windowSize={%d,%d}, orientation=%d\n", __FUNCTION__, w, h, (int)data->rotation); */ if (D3D11_IsDisplayRotated90Degrees(data->rotation)) { @@ -899,19 +907,18 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) if (data->swapChain) { /* IDXGISwapChain::ResizeBuffers is not available on Windows Phone 8. */ -#if !defined(__WINRT__) || (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) +#if !defined(__WINRT__) || !SDL_WINAPI_FAMILY_PHONE /* If the swap chain already exists, resize it. */ result = IDXGISwapChain_ResizeBuffers(data->swapChain, - 0, - w, h, - DXGI_FORMAT_UNKNOWN, - 0 - ); + 0, + w, h, + DXGI_FORMAT_UNKNOWN, + 0); if (result == DXGI_ERROR_DEVICE_REMOVED) { /* If the device was removed for any reason, a new device and swap chain will need to be created. */ D3D11_HandleDeviceLost(renderer); - /* Everything is set up now. Do not continue execution of this method. HandleDeviceLost will reenter this method + /* Everything is set up now. Do not continue execution of this method. HandleDeviceLost will reenter this method * and correctly set up the new device. */ goto done; @@ -922,12 +929,12 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) #endif } else { result = D3D11_CreateSwapChain(renderer, w, h); - if (FAILED(result)) { + if (FAILED(result) || !data->swapChain) { goto done; } } - -#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP + +#if !SDL_WINAPI_FAMILY_PHONE /* Set the proper rotation for the swap chain. * * To note, the call for this, IDXGISwapChain1::SetRotation, is not necessary @@ -944,20 +951,21 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) * * TODO, WinRT: reexamine the docs for IDXGISwapChain1::SetRotation, see if might be available, usable, and prudent-to-call on WinPhone 8.1 */ - if (data->swapEffect == DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL) { - result = IDXGISwapChain1_SetRotation(data->swapChain, data->rotation); - if (FAILED(result)) { - WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGISwapChain1::SetRotation"), result); - goto done; + if (WIN_IsWindows8OrGreater()) { + if (data->swapEffect == DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL) { + result = IDXGISwapChain1_SetRotation(data->swapChain, data->rotation); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGISwapChain1::SetRotation"), result); + goto done; + } } } #endif result = IDXGISwapChain_GetBuffer(data->swapChain, - 0, - &SDL_IID_ID3D11Texture2D, - (void **)&backBuffer - ); + 0, + &SDL_IID_ID3D11Texture2D, + (void **)&backBuffer); if (FAILED(result)) { WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGISwapChain::GetBuffer [back-buffer]"), result); goto done; @@ -965,15 +973,23 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer) /* Create a render target view of the swap chain back buffer. */ result = ID3D11Device_CreateRenderTargetView(data->d3dDevice, - (ID3D11Resource *)backBuffer, - NULL, - &data->mainRenderTargetView - ); + (ID3D11Resource *)backBuffer, + NULL, + &data->mainRenderTargetView); if (FAILED(result)) { WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device::CreateRenderTargetView"), result); goto done; } + /* Set the swap chain target immediately, so that a target is always set + * even before we get to SetDrawState. Without this it's possible to hit + * null references in places like ReadPixels! + */ + ID3D11DeviceContext_OMSetRenderTargets(data->d3dContext, + 1, + &data->mainRenderTargetView, + NULL); + data->viewportDirty = SDL_TRUE; done: @@ -982,14 +998,12 @@ done: } /* This method is called when the window's size changes. */ -static HRESULT -D3D11_UpdateForWindowSizeChange(SDL_Renderer * renderer) +static HRESULT D3D11_UpdateForWindowSizeChange(SDL_Renderer *renderer) { return D3D11_CreateWindowSizeDependentResources(renderer); } -void -D3D11_Trim(SDL_Renderer * renderer) +void D3D11_Trim(SDL_Renderer *renderer) { #ifdef __WINRT__ #if NTDDI_VERSION > NTDDI_WIN8 @@ -999,7 +1013,7 @@ D3D11_Trim(SDL_Renderer * renderer) result = ID3D11Device_QueryInterface(data->d3dDevice, &SDL_IID_IDXGIDevice3, &dxgiDevice); if (FAILED(result)) { - //WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device to IDXGIDevice3", result); + // WIN_SetErrorFromHRESULT(__FUNCTION__ ", ID3D11Device to IDXGIDevice3", result); return; } @@ -1009,16 +1023,22 @@ D3D11_Trim(SDL_Renderer * renderer) #endif } -static void -D3D11_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event) +static void D3D11_WindowEvent(SDL_Renderer *renderer, const SDL_WindowEvent *event) { if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED) { D3D11_UpdateForWindowSizeChange(renderer); } } -static SDL_bool -D3D11_SupportsBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode) +#if !defined(__WINRT__) +static int D3D11_GetOutputSize(SDL_Renderer *renderer, int *w, int *h) +{ + SDL_GetWindowSizeInPixels(renderer->window, w, h); + return 0; +} +#endif + +static SDL_bool D3D11_SupportsBlendMode(SDL_Renderer *renderer, SDL_BlendMode blendMode) { SDL_BlendFactor srcColorFactor = SDL_GetBlendModeSrcColorFactor(blendMode); SDL_BlendFactor srcAlphaFactor = SDL_GetBlendModeSrcAlphaFactor(blendMode); @@ -1036,10 +1056,9 @@ D3D11_SupportsBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode) return SDL_TRUE; } -static int -D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) +static int D3D11_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) { - D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata; + D3D11_RenderData *rendererData = (D3D11_RenderData *)renderer->driverdata; D3D11_TextureData *textureData; HRESULT result; DXGI_FORMAT textureFormat = SDLPixelFormatToDXGIFormat(texture->format); @@ -1048,15 +1067,15 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) if (textureFormat == DXGI_FORMAT_UNKNOWN) { return SDL_SetError("%s, An unsupported SDL pixel format (0x%x) was specified", - __FUNCTION__, texture->format); + __FUNCTION__, texture->format); } - textureData = (D3D11_TextureData*) SDL_calloc(1, sizeof(*textureData)); + textureData = (D3D11_TextureData *)SDL_calloc(1, sizeof(*textureData)); if (!textureData) { SDL_OutOfMemory(); return -1; } - textureData->scaleMode = (texture->scaleMode == SDL_ScaleModeNearest) ? D3D11_FILTER_MIN_MAG_MIP_POINT : D3D11_FILTER_MIN_MAG_MIP_LINEAR; + textureData->scaleMode = (texture->scaleMode == SDL_ScaleModeNearest) ? D3D11_FILTER_MIN_MAG_MIP_POINT : D3D11_FILTER_MIN_MAG_MIP_LINEAR; texture->driverdata = textureData; @@ -1085,16 +1104,14 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) } result = ID3D11Device_CreateTexture2D(rendererData->d3dDevice, - &textureDesc, - NULL, - &textureData->mainTexture - ); + &textureDesc, + NULL, + &textureData->mainTexture); if (FAILED(result)) { D3D11_DestroyTexture(renderer, texture); - WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result); - return -1; + return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result); } - +#if SDL_HAVE_YUV if (texture->format == SDL_PIXELFORMAT_YV12 || texture->format == SDL_PIXELFORMAT_IYUV) { textureData->yuv = SDL_TRUE; @@ -1103,25 +1120,21 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) textureDesc.Height = (textureDesc.Height + 1) / 2; result = ID3D11Device_CreateTexture2D(rendererData->d3dDevice, - &textureDesc, - NULL, - &textureData->mainTextureU - ); + &textureDesc, + NULL, + &textureData->mainTextureU); if (FAILED(result)) { D3D11_DestroyTexture(renderer, texture); - WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result); - return -1; + return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result); } result = ID3D11Device_CreateTexture2D(rendererData->d3dDevice, - &textureDesc, - NULL, - &textureData->mainTextureV - ); + &textureDesc, + NULL, + &textureData->mainTextureV); if (FAILED(result)) { D3D11_DestroyTexture(renderer, texture); - WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result); - return -1; + return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result); } } @@ -1136,52 +1149,45 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) nvTextureDesc.Height = (textureDesc.Height + 1) / 2; result = ID3D11Device_CreateTexture2D(rendererData->d3dDevice, - &nvTextureDesc, - NULL, - &textureData->mainTextureNV - ); + &nvTextureDesc, + NULL, + &textureData->mainTextureNV); if (FAILED(result)) { D3D11_DestroyTexture(renderer, texture); - WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result); - return -1; + return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result); } } - +#endif /* SDL_HAVE_YUV */ + SDL_zero(resourceViewDesc); resourceViewDesc.Format = textureDesc.Format; resourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; resourceViewDesc.Texture2D.MostDetailedMip = 0; resourceViewDesc.Texture2D.MipLevels = textureDesc.MipLevels; result = ID3D11Device_CreateShaderResourceView(rendererData->d3dDevice, - (ID3D11Resource *)textureData->mainTexture, - &resourceViewDesc, - &textureData->mainTextureResourceView - ); + (ID3D11Resource *)textureData->mainTexture, + &resourceViewDesc, + &textureData->mainTextureResourceView); if (FAILED(result)) { D3D11_DestroyTexture(renderer, texture); - WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateShaderResourceView"), result); - return -1; + return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateShaderResourceView"), result); } - +#if SDL_HAVE_YUV if (textureData->yuv) { result = ID3D11Device_CreateShaderResourceView(rendererData->d3dDevice, - (ID3D11Resource *)textureData->mainTextureU, - &resourceViewDesc, - &textureData->mainTextureResourceViewU - ); + (ID3D11Resource *)textureData->mainTextureU, + &resourceViewDesc, + &textureData->mainTextureResourceViewU); if (FAILED(result)) { D3D11_DestroyTexture(renderer, texture); - WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateShaderResourceView"), result); - return -1; + return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateShaderResourceView"), result); } result = ID3D11Device_CreateShaderResourceView(rendererData->d3dDevice, - (ID3D11Resource *)textureData->mainTextureV, - &resourceViewDesc, - &textureData->mainTextureResourceViewV - ); + (ID3D11Resource *)textureData->mainTextureV, + &resourceViewDesc, + &textureData->mainTextureResourceViewV); if (FAILED(result)) { D3D11_DestroyTexture(renderer, texture); - WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateShaderResourceView"), result); - return -1; + return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateShaderResourceView"), result); } } @@ -1191,40 +1197,38 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) nvResourceViewDesc.Format = DXGI_FORMAT_R8G8_UNORM; result = ID3D11Device_CreateShaderResourceView(rendererData->d3dDevice, - (ID3D11Resource *)textureData->mainTextureNV, - &nvResourceViewDesc, - &textureData->mainTextureResourceViewNV - ); + (ID3D11Resource *)textureData->mainTextureNV, + &nvResourceViewDesc, + &textureData->mainTextureResourceViewNV); if (FAILED(result)) { D3D11_DestroyTexture(renderer, texture); - WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateShaderResourceView"), result); - return -1; + return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateShaderResourceView"), result); } } +#endif /* SDL_HAVE_YUV */ if (texture->access & SDL_TEXTUREACCESS_TARGET) { D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc; + SDL_zero(renderTargetViewDesc); renderTargetViewDesc.Format = textureDesc.Format; renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; renderTargetViewDesc.Texture2D.MipSlice = 0; result = ID3D11Device_CreateRenderTargetView(rendererData->d3dDevice, - (ID3D11Resource *)textureData->mainTexture, - &renderTargetViewDesc, - &textureData->mainTextureRenderTargetView); + (ID3D11Resource *)textureData->mainTexture, + &renderTargetViewDesc, + &textureData->mainTextureRenderTargetView); if (FAILED(result)) { D3D11_DestroyTexture(renderer, texture); - WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateRenderTargetView"), result); - return -1; + return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateRenderTargetView"), result); } } return 0; } -static void -D3D11_DestroyTexture(SDL_Renderer * renderer, - SDL_Texture * texture) +static void D3D11_DestroyTexture(SDL_Renderer *renderer, + SDL_Texture *texture) { D3D11_TextureData *data = (D3D11_TextureData *)texture->driverdata; @@ -1236,17 +1240,20 @@ D3D11_DestroyTexture(SDL_Renderer * renderer, SAFE_RELEASE(data->mainTextureResourceView); SAFE_RELEASE(data->mainTextureRenderTargetView); SAFE_RELEASE(data->stagingTexture); +#if SDL_HAVE_YUV SAFE_RELEASE(data->mainTextureU); SAFE_RELEASE(data->mainTextureResourceViewU); SAFE_RELEASE(data->mainTextureV); SAFE_RELEASE(data->mainTextureResourceViewV); + SAFE_RELEASE(data->mainTextureNV); + SAFE_RELEASE(data->mainTextureResourceViewNV); SDL_free(data->pixels); +#endif SDL_free(data); texture->driverdata = NULL; } -static int -D3D11_UpdateTextureInternal(D3D11_RenderData *rendererData, ID3D11Texture2D *texture, int bpp, int x, int y, int w, int h, const void *pixels, int pitch) +static int D3D11_UpdateTextureInternal(D3D11_RenderData *rendererData, ID3D11Texture2D *texture, int bpp, int x, int y, int w, int h, const void *pixels, int pitch) { ID3D11Texture2D *stagingTexture; const Uint8 *src; @@ -1266,33 +1273,30 @@ D3D11_UpdateTextureInternal(D3D11_RenderData *rendererData, ID3D11Texture2D *tex stagingTextureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; stagingTextureDesc.Usage = D3D11_USAGE_STAGING; result = ID3D11Device_CreateTexture2D(rendererData->d3dDevice, - &stagingTextureDesc, - NULL, - &stagingTexture); + &stagingTextureDesc, + NULL, + &stagingTexture); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D [create staging texture]"), result); - return -1; + return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D [create staging texture]"), result); } /* Get a write-only pointer to data in the staging texture: */ result = ID3D11DeviceContext_Map(rendererData->d3dContext, - (ID3D11Resource *)stagingTexture, - 0, - D3D11_MAP_WRITE, - 0, - &textureMemory - ); + (ID3D11Resource *)stagingTexture, + 0, + D3D11_MAP_WRITE, + 0, + &textureMemory); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11DeviceContext1::Map [map staging texture]"), result); SAFE_RELEASE(stagingTexture); - return -1; + return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11DeviceContext1::Map [map staging texture]"), result); } src = (const Uint8 *)pixels; dst = textureMemory.pData; length = w * bpp; if (length == pitch && length == textureMemory.RowPitch) { - SDL_memcpy(dst, src, length*h); + SDL_memcpy(dst, src, (size_t)length * h); } else { if (length > (UINT)pitch) { length = pitch; @@ -1309,52 +1313,50 @@ D3D11_UpdateTextureInternal(D3D11_RenderData *rendererData, ID3D11Texture2D *tex /* Commit the pixel buffer's changes back to the staging texture: */ ID3D11DeviceContext_Unmap(rendererData->d3dContext, - (ID3D11Resource *)stagingTexture, - 0); + (ID3D11Resource *)stagingTexture, + 0); /* Copy the staging texture's contents back to the texture: */ ID3D11DeviceContext_CopySubresourceRegion(rendererData->d3dContext, - (ID3D11Resource *)texture, - 0, - x, - y, - 0, - (ID3D11Resource *)stagingTexture, - 0, - NULL); + (ID3D11Resource *)texture, + 0, + x, + y, + 0, + (ID3D11Resource *)stagingTexture, + 0, + NULL); SAFE_RELEASE(stagingTexture); return 0; } -static int -D3D11_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * rect, const void * srcPixels, - int srcPitch) +static int D3D11_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *rect, const void *srcPixels, + int srcPitch) { D3D11_RenderData *rendererData = (D3D11_RenderData *)renderer->driverdata; D3D11_TextureData *textureData = (D3D11_TextureData *)texture->driverdata; if (!textureData) { - SDL_SetError("Texture is not currently available"); - return -1; + return SDL_SetError("Texture is not currently available"); } if (D3D11_UpdateTextureInternal(rendererData, textureData->mainTexture, SDL_BYTESPERPIXEL(texture->format), rect->x, rect->y, rect->w, rect->h, srcPixels, srcPitch) < 0) { return -1; } - +#if SDL_HAVE_YUV if (textureData->yuv) { /* Skip to the correct offset into the next texture */ - srcPixels = (const void*)((const Uint8*)srcPixels + rect->h * srcPitch); + srcPixels = (const void *)((const Uint8 *)srcPixels + rect->h * srcPitch); if (D3D11_UpdateTextureInternal(rendererData, texture->format == SDL_PIXELFORMAT_YV12 ? textureData->mainTextureV : textureData->mainTextureU, SDL_BYTESPERPIXEL(texture->format), rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2, srcPixels, (srcPitch + 1) / 2) < 0) { return -1; } /* Skip to the correct offset into the next texture */ - srcPixels = (const void*)((const Uint8*)srcPixels + ((rect->h + 1) / 2) * ((srcPitch + 1) / 2)); + srcPixels = (const void *)((const Uint8 *)srcPixels + ((rect->h + 1) / 2) * ((srcPitch + 1) / 2)); if (D3D11_UpdateTextureInternal(rendererData, texture->format == SDL_PIXELFORMAT_YV12 ? textureData->mainTextureU : textureData->mainTextureV, SDL_BYTESPERPIXEL(texture->format), rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2, srcPixels, (srcPitch + 1) / 2) < 0) { return -1; } @@ -1362,28 +1364,28 @@ D3D11_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, if (textureData->nv12) { /* Skip to the correct offset into the next texture */ - srcPixels = (const void*)((const Uint8*)srcPixels + rect->h * srcPitch); + srcPixels = (const void *)((const Uint8 *)srcPixels + rect->h * srcPitch); - if (D3D11_UpdateTextureInternal(rendererData, textureData->mainTextureNV, 2, rect->x / 2, rect->y / 2, ((rect->w + 1) / 2), (rect->h + 1) / 2, srcPixels, 2*((srcPitch + 1) / 2)) < 0) { + if (D3D11_UpdateTextureInternal(rendererData, textureData->mainTextureNV, 2, rect->x / 2, rect->y / 2, ((rect->w + 1) / 2), (rect->h + 1) / 2, srcPixels, 2 * ((srcPitch + 1) / 2)) < 0) { return -1; } } +#endif /* SDL_HAVE_YUV */ return 0; } -static int -D3D11_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * rect, - const Uint8 *Yplane, int Ypitch, - const Uint8 *Uplane, int Upitch, - const Uint8 *Vplane, int Vpitch) +#if SDL_HAVE_YUV +static int D3D11_UpdateTextureYUV(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *Uplane, int Upitch, + const Uint8 *Vplane, int Vpitch) { D3D11_RenderData *rendererData = (D3D11_RenderData *)renderer->driverdata; D3D11_TextureData *textureData = (D3D11_TextureData *)texture->driverdata; if (!textureData) { - SDL_SetError("Texture is not currently available"); - return -1; + return SDL_SetError("Texture is not currently available"); } if (D3D11_UpdateTextureInternal(rendererData, textureData->mainTexture, SDL_BYTESPERPIXEL(texture->format), rect->x, rect->y, rect->w, rect->h, Yplane, Ypitch) < 0) { @@ -1398,21 +1400,42 @@ D3D11_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture, return 0; } -static int -D3D11_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * rect, void **pixels, int *pitch) +static int D3D11_UpdateTextureNV(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *UVplane, int UVpitch) { - D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata; - D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata; + D3D11_RenderData *rendererData = (D3D11_RenderData *)renderer->driverdata; + D3D11_TextureData *textureData = (D3D11_TextureData *)texture->driverdata; + + if (!textureData) { + return SDL_SetError("Texture is not currently available"); + } + + if (D3D11_UpdateTextureInternal(rendererData, textureData->mainTexture, SDL_BYTESPERPIXEL(texture->format), rect->x, rect->y, rect->w, rect->h, Yplane, Ypitch) < 0) { + return -1; + } + + if (D3D11_UpdateTextureInternal(rendererData, textureData->mainTextureNV, 2, rect->x / 2, rect->y / 2, ((rect->w + 1) / 2), (rect->h + 1) / 2, UVplane, UVpitch) < 0) { + return -1; + } + return 0; +} +#endif + +static int D3D11_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *rect, void **pixels, int *pitch) +{ + D3D11_RenderData *rendererData = (D3D11_RenderData *)renderer->driverdata; + D3D11_TextureData *textureData = (D3D11_TextureData *)texture->driverdata; HRESULT result = S_OK; D3D11_TEXTURE2D_DESC stagingTextureDesc; D3D11_MAPPED_SUBRESOURCE textureMemory; if (!textureData) { - SDL_SetError("Texture is not currently available"); - return -1; + return SDL_SetError("Texture is not currently available"); } - +#if SDL_HAVE_YUV if (textureData->yuv || textureData->nv12) { /* It's more efficient to upload directly... */ if (!textureData->pixels) { @@ -1424,16 +1447,16 @@ D3D11_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, } textureData->locked_rect = *rect; *pixels = - (void *)((Uint8 *)textureData->pixels + rect->y * textureData->pitch + - rect->x * SDL_BYTESPERPIXEL(texture->format)); + (void *)(textureData->pixels + rect->y * textureData->pitch + + rect->x * SDL_BYTESPERPIXEL(texture->format)); *pitch = textureData->pitch; return 0; } - +#endif if (textureData->stagingTexture) { return SDL_SetError("texture is already locked"); } - + /* Create a 'staging' texture, which will be used to write to a portion * of the main texture. This is necessary, as Direct3D 11.1 does not * have the ability to write a CPU-bound pixel buffer to a rectangular @@ -1450,29 +1473,26 @@ D3D11_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, stagingTextureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; stagingTextureDesc.Usage = D3D11_USAGE_STAGING; result = ID3D11Device_CreateTexture2D(rendererData->d3dDevice, - &stagingTextureDesc, - NULL, - &textureData->stagingTexture); + &stagingTextureDesc, + NULL, + &textureData->stagingTexture); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D [create staging texture]"), result); - return -1; + return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D [create staging texture]"), result); } /* Get a write-only pointer to data in the staging texture: */ result = ID3D11DeviceContext_Map(rendererData->d3dContext, - (ID3D11Resource *)textureData->stagingTexture, - 0, - D3D11_MAP_WRITE, - 0, - &textureMemory - ); + (ID3D11Resource *)textureData->stagingTexture, + 0, + D3D11_MAP_WRITE, + 0, + &textureMemory); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11DeviceContext1::Map [map staging texture]"), result); SAFE_RELEASE(textureData->stagingTexture); - return -1; + return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11DeviceContext1::Map [map staging texture]"), result); } - /* Make note of where the staging texture will be written to + /* Make note of where the staging texture will be written to * (on a call to SDL_UnlockTexture): */ textureData->lockedTexturePositionX = rect->x; @@ -1486,68 +1506,65 @@ D3D11_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, return 0; } -static void -D3D11_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) +static void D3D11_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture) { - D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata; - D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata; - + D3D11_RenderData *rendererData = (D3D11_RenderData *)renderer->driverdata; + D3D11_TextureData *textureData = (D3D11_TextureData *)texture->driverdata; + if (!textureData) { return; } - +#if SDL_HAVE_YUV if (textureData->yuv || textureData->nv12) { const SDL_Rect *rect = &textureData->locked_rect; void *pixels = - (void *) ((Uint8 *) textureData->pixels + rect->y * textureData->pitch + - rect->x * SDL_BYTESPERPIXEL(texture->format)); + (void *)(textureData->pixels + rect->y * textureData->pitch + + rect->x * SDL_BYTESPERPIXEL(texture->format)); D3D11_UpdateTexture(renderer, texture, rect, pixels, textureData->pitch); return; } - +#endif /* Commit the pixel buffer's changes back to the staging texture: */ ID3D11DeviceContext_Unmap(rendererData->d3dContext, - (ID3D11Resource *)textureData->stagingTexture, - 0); + (ID3D11Resource *)textureData->stagingTexture, + 0); /* Copy the staging texture's contents back to the main texture: */ ID3D11DeviceContext_CopySubresourceRegion(rendererData->d3dContext, - (ID3D11Resource *)textureData->mainTexture, - 0, - textureData->lockedTexturePositionX, - textureData->lockedTexturePositionY, - 0, - (ID3D11Resource *)textureData->stagingTexture, - 0, - NULL); + (ID3D11Resource *)textureData->mainTexture, + 0, + textureData->lockedTexturePositionX, + textureData->lockedTexturePositionY, + 0, + (ID3D11Resource *)textureData->stagingTexture, + 0, + NULL); SAFE_RELEASE(textureData->stagingTexture); } -static void -D3D11_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture, SDL_ScaleMode scaleMode) +static void D3D11_SetTextureScaleMode(SDL_Renderer *renderer, SDL_Texture *texture, SDL_ScaleMode scaleMode) { - D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata; - + D3D11_TextureData *textureData = (D3D11_TextureData *)texture->driverdata; + if (!textureData) { return; } - textureData->scaleMode = (scaleMode == SDL_ScaleModeNearest) ? D3D11_FILTER_MIN_MAG_MIP_POINT : D3D11_FILTER_MIN_MAG_MIP_LINEAR; + textureData->scaleMode = (scaleMode == SDL_ScaleModeNearest) ? D3D11_FILTER_MIN_MAG_MIP_POINT : D3D11_FILTER_MIN_MAG_MIP_LINEAR; } -static int -D3D11_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture) +static int D3D11_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture) { - D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata; + D3D11_RenderData *rendererData = (D3D11_RenderData *)renderer->driverdata; D3D11_TextureData *textureData = NULL; - if (texture == NULL) { + if (!texture) { rendererData->currentOffscreenRenderTargetView = NULL; return 0; } - textureData = (D3D11_TextureData *) texture->driverdata; + textureData = (D3D11_TextureData *)texture->driverdata; if (!textureData->mainTextureRenderTargetView) { return SDL_SetError("specified texture is not a render target"); @@ -1558,21 +1575,20 @@ D3D11_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture) return 0; } -static int -D3D11_QueueSetViewport(SDL_Renderer * renderer, SDL_RenderCommand *cmd) +static int D3D11_QueueSetViewport(SDL_Renderer *renderer, SDL_RenderCommand *cmd) { - return 0; /* nothing to do in this backend. */ + return 0; /* nothing to do in this backend. */ } -static int -D3D11_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count) +static int D3D11_QueueDrawPoints(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count) { - VertexPositionColor *verts = (VertexPositionColor *) SDL_AllocateRenderVertices(renderer, count * sizeof (VertexPositionColor), 0, &cmd->data.draw.first); - const float r = (float)(cmd->data.draw.r / 255.0f); - const float g = (float)(cmd->data.draw.g / 255.0f); - const float b = (float)(cmd->data.draw.b / 255.0f); - const float a = (float)(cmd->data.draw.a / 255.0f); + VertexPositionColor *verts = (VertexPositionColor *)SDL_AllocateRenderVertices(renderer, count * sizeof(VertexPositionColor), 0, &cmd->data.draw.first); int i; + SDL_Color color; + color.r = cmd->data.draw.r; + color.g = cmd->data.draw.g; + color.b = cmd->data.draw.b; + color.a = cmd->data.draw.a; if (!verts) { return -1; @@ -1583,278 +1599,87 @@ D3D11_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL for (i = 0; i < count; i++) { verts->pos.x = points[i].x + 0.5f; verts->pos.y = points[i].y + 0.5f; - verts->pos.z = 0.0f; verts->tex.x = 0.0f; verts->tex.y = 0.0f; - verts->color.x = r; - verts->color.y = g; - verts->color.z = b; - verts->color.w = a; + verts->color = color; verts++; } return 0; } -static int -D3D11_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRect * rects, int count) +static int D3D11_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, + const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride, + int num_vertices, const void *indices, int num_indices, int size_indices, + float scale_x, float scale_y) { - VertexPositionColor *verts = (VertexPositionColor *) SDL_AllocateRenderVertices(renderer, count * 4 * sizeof (VertexPositionColor), 0, &cmd->data.draw.first); - const float r = (float)(cmd->data.draw.r / 255.0f); - const float g = (float)(cmd->data.draw.g / 255.0f); - const float b = (float)(cmd->data.draw.b / 255.0f); - const float a = (float)(cmd->data.draw.a / 255.0f); int i; + int count = indices ? num_indices : num_vertices; + VertexPositionColor *verts = (VertexPositionColor *)SDL_AllocateRenderVertices(renderer, count * sizeof(VertexPositionColor), 0, &cmd->data.draw.first); if (!verts) { return -1; } cmd->data.draw.count = count; + size_indices = indices ? size_indices : 0; for (i = 0; i < count; i++) { - verts->pos.x = rects[i].x; - verts->pos.y = rects[i].y; - verts->pos.z = 0.0f; - verts->tex.x = 0.0f; - verts->tex.y = 0.0f; - verts->color.x = r; - verts->color.y = g; - verts->color.z = b; - verts->color.w = a; - verts++; + int j; + float *xy_; + if (size_indices == 4) { + j = ((const Uint32 *)indices)[i]; + } else if (size_indices == 2) { + j = ((const Uint16 *)indices)[i]; + } else if (size_indices == 1) { + j = ((const Uint8 *)indices)[i]; + } else { + j = i; + } - verts->pos.x = rects[i].x; - verts->pos.y = rects[i].y + rects[i].h; - verts->pos.z = 0.0f; - verts->tex.x = 0.0f; - verts->tex.y = 0.0f; - verts->color.x = r; - verts->color.y = g; - verts->color.z = b; - verts->color.w = a; - verts++; + xy_ = (float *)((char *)xy + j * xy_stride); - verts->pos.x = rects[i].x + rects[i].w; - verts->pos.y = rects[i].y; - verts->pos.z = 0.0f; - verts->tex.x = 0.0f; - verts->tex.y = 0.0f; - verts->color.x = r; - verts->color.y = g; - verts->color.z = b; - verts->color.w = a; - verts++; + verts->pos.x = xy_[0] * scale_x; + verts->pos.y = xy_[1] * scale_y; + verts->color = *(SDL_Color *)((char *)color + j * color_stride); - verts->pos.x = rects[i].x + rects[i].w; - verts->pos.y = rects[i].y + rects[i].h; - verts->pos.z = 0.0f; - verts->tex.x = 0.0f; - verts->tex.y = 0.0f; - verts->color.x = r; - verts->color.y = g; - verts->color.z = b; - verts->color.w = a; - verts++; + if (texture) { + float *uv_ = (float *)((char *)uv + j * uv_stride); + verts->tex.x = uv_[0]; + verts->tex.y = uv_[1]; + } else { + verts->tex.x = 0.0f; + verts->tex.y = 0.0f; + } + + verts += 1; } - return 0; } -static int -D3D11_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_FRect * dstrect) +static int D3D11_UpdateVertexBuffer(SDL_Renderer *renderer, + const void *vertexData, size_t dataSizeInBytes) { - VertexPositionColor *verts = (VertexPositionColor *) SDL_AllocateRenderVertices(renderer, 4 * sizeof (VertexPositionColor), 0, &cmd->data.draw.first); - const float r = (float)(cmd->data.draw.r / 255.0f); - const float g = (float)(cmd->data.draw.g / 255.0f); - const float b = (float)(cmd->data.draw.b / 255.0f); - const float a = (float)(cmd->data.draw.a / 255.0f); - const float minu = (float) srcrect->x / texture->w; - const float maxu = (float) (srcrect->x + srcrect->w) / texture->w; - const float minv = (float) srcrect->y / texture->h; - const float maxv = (float) (srcrect->y + srcrect->h) / texture->h; - - if (!verts) { - return -1; - } - - cmd->data.draw.count = 1; - - verts->pos.x = dstrect->x; - verts->pos.y = dstrect->y; - verts->pos.z = 0.0f; - verts->tex.x = minu; - verts->tex.y = minv; - verts->color.x = r; - verts->color.y = g; - verts->color.z = b; - verts->color.w = a; - verts++; - - verts->pos.x = dstrect->x; - verts->pos.y = dstrect->y + dstrect->h; - verts->pos.z = 0.0f; - verts->tex.x = minu; - verts->tex.y = maxv; - verts->color.x = r; - verts->color.y = g; - verts->color.z = b; - verts->color.w = a; - verts++; - - verts->pos.x = dstrect->x + dstrect->w; - verts->pos.y = dstrect->y; - verts->pos.z = 0.0f; - verts->tex.x = maxu; - verts->tex.y = minv; - verts->color.x = r; - verts->color.y = g; - verts->color.z = b; - verts->color.w = a; - verts++; - - verts->pos.x = dstrect->x + dstrect->w; - verts->pos.y = dstrect->y + dstrect->h; - verts->pos.z = 0.0f; - verts->tex.x = maxu; - verts->tex.y = maxv; - verts->color.x = r; - verts->color.y = g; - verts->color.z = b; - verts->color.w = a; - verts++; - - return 0; -} - -static int -D3D11_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_FRect * dstrect, - const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip) -{ - VertexPositionColor *verts = (VertexPositionColor *) SDL_AllocateRenderVertices(renderer, 5 * sizeof (VertexPositionColor), 0, &cmd->data.draw.first); - const float r = (float)(cmd->data.draw.r / 255.0f); - const float g = (float)(cmd->data.draw.g / 255.0f); - const float b = (float)(cmd->data.draw.b / 255.0f); - const float a = (float)(cmd->data.draw.a / 255.0f); - float minx, miny, maxx, maxy; - float minu, maxu, minv, maxv; - - if (!verts) { - return -1; - } - - cmd->data.draw.count = 1; - - minx = -center->x; - maxx = dstrect->w - center->x; - miny = -center->y; - maxy = dstrect->h - center->y; - - if (flip & SDL_FLIP_HORIZONTAL) { - minu = (float) (srcrect->x + srcrect->w) / texture->w; - maxu = (float) srcrect->x / texture->w; - } else { - minu = (float) srcrect->x / texture->w; - maxu = (float) (srcrect->x + srcrect->w) / texture->w; - } - - if (flip & SDL_FLIP_VERTICAL) { - minv = (float) (srcrect->y + srcrect->h) / texture->h; - maxv = (float) srcrect->y / texture->h; - } else { - minv = (float) srcrect->y / texture->h; - maxv = (float) (srcrect->y + srcrect->h) / texture->h; - } - - - - verts->pos.x = minx; - verts->pos.y = miny; - verts->pos.z = 0.0f; - verts->color.x = r; - verts->color.y = g; - verts->color.z = b; - verts->color.w = a; - verts->tex.x = minu; - verts->tex.y = minv; - verts++; - - verts->pos.x = minx; - verts->pos.y = maxy; - verts->pos.z = 0.0f; - verts->color.x = r; - verts->color.y = g; - verts->color.z = b; - verts->color.w = a; - verts->tex.x = minu; - verts->tex.y = maxv; - verts++; - - verts->pos.x = maxx; - verts->pos.y = miny; - verts->pos.z = 0.0f; - verts->color.x = r; - verts->color.y = g; - verts->color.z = b; - verts->color.w = a; - verts->tex.x = maxu; - verts->tex.y = minv; - verts++; - - verts->pos.x = maxx; - verts->pos.y = maxy; - verts->pos.z = 0.0f; - verts->color.x = r; - verts->color.y = g; - verts->color.z = b; - verts->color.w = a; - verts->tex.x = maxu; - verts->tex.y = maxv; - verts++; - - verts->pos.x = dstrect->x + center->x; /* X translation */ - verts->pos.y = dstrect->y + center->y; /* Y translation */ - verts->pos.z = (float)(M_PI * (float) angle / 180.0f); /* rotation */ - verts->color.x = 0; - verts->color.y = 0; - verts->color.z = 0; - verts->color.w = 0; - verts->tex.x = 0.0f; - verts->tex.y = 0.0f; - verts++; - - return 0; -} - - -static int -D3D11_UpdateVertexBuffer(SDL_Renderer *renderer, - const void * vertexData, size_t dataSizeInBytes) -{ - D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata; + D3D11_RenderData *rendererData = (D3D11_RenderData *)renderer->driverdata; HRESULT result = S_OK; const int vbidx = rendererData->currentVertexBuffer; const UINT stride = sizeof(VertexPositionColor); const UINT offset = 0; if (dataSizeInBytes == 0) { - return 0; /* nothing to do. */ + return 0; /* nothing to do. */ } if (rendererData->vertexBuffers[vbidx] && rendererData->vertexBufferSizes[vbidx] >= dataSizeInBytes) { D3D11_MAPPED_SUBRESOURCE mappedResource; result = ID3D11DeviceContext_Map(rendererData->d3dContext, - (ID3D11Resource *)rendererData->vertexBuffers[vbidx], - 0, - D3D11_MAP_WRITE_DISCARD, - 0, - &mappedResource - ); + (ID3D11Resource *)rendererData->vertexBuffers[vbidx], + 0, + D3D11_MAP_WRITE_DISCARD, + 0, + &mappedResource); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11DeviceContext1::Map [vertex buffer]"), result); - return -1; + return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11DeviceContext1::Map [vertex buffer]"), result); } SDL_memcpy(mappedResource.pData, vertexData, dataSizeInBytes); ID3D11DeviceContext_Unmap(rendererData->d3dContext, (ID3D11Resource *)rendererData->vertexBuffers[vbidx], 0); @@ -1865,7 +1690,7 @@ D3D11_UpdateVertexBuffer(SDL_Renderer *renderer, SAFE_RELEASE(rendererData->vertexBuffers[vbidx]); SDL_zero(vertexBufferDesc); - vertexBufferDesc.ByteWidth = (UINT) dataSizeInBytes; + vertexBufferDesc.ByteWidth = (UINT)dataSizeInBytes; vertexBufferDesc.Usage = D3D11_USAGE_DYNAMIC; vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; vertexBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; @@ -1876,25 +1701,22 @@ D3D11_UpdateVertexBuffer(SDL_Renderer *renderer, vertexBufferData.SysMemSlicePitch = 0; result = ID3D11Device_CreateBuffer(rendererData->d3dDevice, - &vertexBufferDesc, - &vertexBufferData, - &rendererData->vertexBuffers[vbidx] - ); + &vertexBufferDesc, + &vertexBufferData, + &rendererData->vertexBuffers[vbidx]); if (FAILED(result)) { - WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateBuffer [vertex buffer]"), result); - return -1; + return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateBuffer [vertex buffer]"), result); } rendererData->vertexBufferSizes[vbidx] = dataSizeInBytes; } ID3D11DeviceContext_IASetVertexBuffers(rendererData->d3dContext, - 0, - 1, - &rendererData->vertexBuffers[vbidx], - &stride, - &offset - ); + 0, + 1, + &rendererData->vertexBuffers[vbidx], + &stride, + &offset); rendererData->currentVertexBuffer++; if (rendererData->currentVertexBuffer >= SDL_arraysize(rendererData->vertexBuffers)) { @@ -1904,10 +1726,9 @@ D3D11_UpdateVertexBuffer(SDL_Renderer *renderer, return 0; } -static int -D3D11_UpdateViewport(SDL_Renderer * renderer) +static int D3D11_UpdateViewport(SDL_Renderer *renderer) { - D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata; + D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata; const SDL_Rect *viewport = &data->currentViewport; Float4X4 projection; Float4X4 view; @@ -1961,8 +1782,8 @@ D3D11_UpdateViewport(SDL_Renderer * renderer) * for eventual transfer to the GPU. */ data->vertexShaderConstantsData.projectionAndView = MatrixMultiply( - view, - projection); + view, + projection); /* Update the Direct3D viewport, which seems to be aligned to the * swap buffer's coordinate space, which is always in either @@ -1971,15 +1792,15 @@ D3D11_UpdateViewport(SDL_Renderer * renderer) */ swapDimensions = D3D11_IsDisplayRotated90Degrees(rotation); if (swapDimensions) { - orientationAlignedViewport.x = (float) viewport->y; - orientationAlignedViewport.y = (float) viewport->x; - orientationAlignedViewport.w = (float) viewport->h; - orientationAlignedViewport.h = (float) viewport->w; + orientationAlignedViewport.x = (float)viewport->y; + orientationAlignedViewport.y = (float)viewport->x; + orientationAlignedViewport.w = (float)viewport->h; + orientationAlignedViewport.h = (float)viewport->w; } else { - orientationAlignedViewport.x = (float) viewport->x; - orientationAlignedViewport.y = (float) viewport->y; - orientationAlignedViewport.w = (float) viewport->w; - orientationAlignedViewport.h = (float) viewport->h; + orientationAlignedViewport.x = (float)viewport->x; + orientationAlignedViewport.y = (float)viewport->y; + orientationAlignedViewport.w = (float)viewport->w; + orientationAlignedViewport.h = (float)viewport->h; } /* TODO, WinRT: get custom viewports working with non-Landscape modes (Portrait, PortraitFlipped, and LandscapeFlipped) */ @@ -1997,22 +1818,19 @@ D3D11_UpdateViewport(SDL_Renderer * renderer) return 0; } -static ID3D11RenderTargetView * -D3D11_GetCurrentRenderTargetView(SDL_Renderer * renderer) +static ID3D11RenderTargetView *D3D11_GetCurrentRenderTargetView(SDL_Renderer *renderer) { D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata; if (data->currentOffscreenRenderTargetView) { return data->currentOffscreenRenderTargetView; - } - else { + } else { return data->mainRenderTargetView; } } -static int -D3D11_SetDrawState(SDL_Renderer * renderer, const SDL_RenderCommand *cmd, ID3D11PixelShader * shader, - const int numShaderResources, ID3D11ShaderResourceView ** shaderResources, - ID3D11SamplerState * sampler, const Float4X4 *matrix) +static int D3D11_SetDrawState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, ID3D11PixelShader *shader, + const int numShaderResources, ID3D11ShaderResourceView **shaderResources, + ID3D11SamplerState *sampler, const Float4X4 *matrix) { D3D11_RenderData *rendererData = (D3D11_RenderData *)renderer->driverdata; @@ -2024,12 +1842,24 @@ D3D11_SetDrawState(SDL_Renderer * renderer, const SDL_RenderCommand *cmd, ID3D11 ID3D11BlendState *blendState = NULL; SDL_bool updateSubresource = SDL_FALSE; + if (numShaderResources > 0) { + shaderResource = shaderResources[0]; + } else { + shaderResource = NULL; + } + + /* Make sure the render target isn't bound to a shader */ + if (shaderResource != rendererData->currentShaderResource) { + ID3D11ShaderResourceView *pNullResource = NULL; + ID3D11DeviceContext_PSSetShaderResources(rendererData->d3dContext, 0, 1, &pNullResource); + rendererData->currentShaderResource = NULL; + } + if (renderTargetView != rendererData->currentRenderTargetView) { ID3D11DeviceContext_OMSetRenderTargets(rendererData->d3dContext, - 1, - &renderTargetView, - NULL - ); + 1, + &renderTargetView, + NULL); rendererData->currentRenderTargetView = renderTargetView; } @@ -2088,11 +1918,6 @@ D3D11_SetDrawState(SDL_Renderer * renderer, const SDL_RenderCommand *cmd, ID3D11 ID3D11DeviceContext_PSSetShader(rendererData->d3dContext, shader, NULL, 0); rendererData->currentShader = shader; } - if (numShaderResources > 0) { - shaderResource = shaderResources[0]; - } else { - shaderResource = NULL; - } if (shaderResource != rendererData->currentShaderResource) { ID3D11DeviceContext_PSSetShaderResources(rendererData->d3dContext, 0, numShaderResources, shaderResources); rendererData->currentShaderResource = shaderResource; @@ -2102,27 +1927,25 @@ D3D11_SetDrawState(SDL_Renderer * renderer, const SDL_RenderCommand *cmd, ID3D11 rendererData->currentSampler = sampler; } - if (updateSubresource == SDL_TRUE || SDL_memcmp(&rendererData->vertexShaderConstantsData.model, newmatrix, sizeof (*newmatrix)) != 0) { - SDL_memcpy(&rendererData->vertexShaderConstantsData.model, newmatrix, sizeof (*newmatrix)); + if (updateSubresource == SDL_TRUE || SDL_memcmp(&rendererData->vertexShaderConstantsData.model, newmatrix, sizeof(*newmatrix)) != 0) { + SDL_copyp(&rendererData->vertexShaderConstantsData.model, newmatrix); ID3D11DeviceContext_UpdateSubresource(rendererData->d3dContext, - (ID3D11Resource *)rendererData->vertexShaderConstants, - 0, - NULL, - &rendererData->vertexShaderConstantsData, - 0, - 0 - ); + (ID3D11Resource *)rendererData->vertexShaderConstants, + 0, + NULL, + &rendererData->vertexShaderConstantsData, + 0, + 0); } return 0; } -static int -D3D11_SetCopyState(SDL_Renderer * renderer, const SDL_RenderCommand *cmd, const Float4X4 *matrix) +static int D3D11_SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const Float4X4 *matrix) { SDL_Texture *texture = cmd->data.draw.texture; - D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata; - D3D11_TextureData *textureData = (D3D11_TextureData *) texture->driverdata; + D3D11_RenderData *rendererData = (D3D11_RenderData *)renderer->driverdata; + D3D11_TextureData *textureData = (D3D11_TextureData *)texture->driverdata; ID3D11SamplerState *textureSampler; switch (textureData->scaleMode) { @@ -2135,7 +1958,7 @@ D3D11_SetCopyState(SDL_Renderer * renderer, const SDL_RenderCommand *cmd, const default: return SDL_SetError("Unknown scale mode: %d\n", textureData->scaleMode); } - +#if SDL_HAVE_YUV if (textureData->yuv) { ID3D11ShaderResourceView *shaderResources[] = { textureData->mainTextureResourceView, @@ -2184,27 +2007,23 @@ D3D11_SetCopyState(SDL_Renderer * renderer, const SDL_RenderCommand *cmd, const return D3D11_SetDrawState(renderer, cmd, rendererData->pixelShaders[shader], SDL_arraysize(shaderResources), shaderResources, textureSampler, matrix); - } - +#endif /* SDL_HAVE_YUV */ return D3D11_SetDrawState(renderer, cmd, rendererData->pixelShaders[SHADER_RGB], 1, &textureData->mainTextureResourceView, textureSampler, matrix); } -static void -D3D11_DrawPrimitives(SDL_Renderer * renderer, D3D11_PRIMITIVE_TOPOLOGY primitiveTopology, const size_t vertexStart, const size_t vertexCount) +static void D3D11_DrawPrimitives(SDL_Renderer *renderer, D3D11_PRIMITIVE_TOPOLOGY primitiveTopology, const size_t vertexStart, const size_t vertexCount) { - D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata; + D3D11_RenderData *rendererData = (D3D11_RenderData *)renderer->driverdata; ID3D11DeviceContext_IASetPrimitiveTopology(rendererData->d3dContext, primitiveTopology); - ID3D11DeviceContext_Draw(rendererData->d3dContext, (UINT) vertexCount, (UINT) vertexStart); + ID3D11DeviceContext_Draw(rendererData->d3dContext, (UINT)vertexCount, (UINT)vertexStart); } -static int -D3D11_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize) +static int D3D11_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize) { - D3D11_RenderData *rendererData = (D3D11_RenderData *) renderer->driverdata; + D3D11_RenderData *rendererData = (D3D11_RenderData *)renderer->driverdata; const int viewportRotation = D3D11_GetRotationForCurrentRenderTarget(renderer); - size_t i; if (rendererData->currentViewportRotation != viewportRotation) { rendererData->currentViewportRotation = viewportRotation; @@ -2217,101 +2036,100 @@ D3D11_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver while (cmd) { switch (cmd->command) { - case SDL_RENDERCMD_SETDRAWCOLOR: { - break; /* this isn't currently used in this render backend. */ - } + case SDL_RENDERCMD_SETDRAWCOLOR: + { + break; /* this isn't currently used in this render backend. */ + } - case SDL_RENDERCMD_SETVIEWPORT: { - SDL_Rect *viewport = &rendererData->currentViewport; - if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect)) != 0) { - SDL_memcpy(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect)); - rendererData->viewportDirty = SDL_TRUE; - } - break; + case SDL_RENDERCMD_SETVIEWPORT: + { + SDL_Rect *viewport = &rendererData->currentViewport; + if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof(cmd->data.viewport.rect)) != 0) { + SDL_copyp(viewport, &cmd->data.viewport.rect); + rendererData->viewportDirty = SDL_TRUE; + rendererData->cliprectDirty = SDL_TRUE; } + break; + } - case SDL_RENDERCMD_SETCLIPRECT: { - const SDL_Rect *rect = &cmd->data.cliprect.rect; - if (rendererData->currentCliprectEnabled != cmd->data.cliprect.enabled) { - rendererData->currentCliprectEnabled = cmd->data.cliprect.enabled; - rendererData->cliprectDirty = SDL_TRUE; - } - if (SDL_memcmp(&rendererData->currentCliprect, rect, sizeof (SDL_Rect)) != 0) { - SDL_memcpy(&rendererData->currentCliprect, rect, sizeof (SDL_Rect)); - rendererData->cliprectDirty = SDL_TRUE; - } - break; + case SDL_RENDERCMD_SETCLIPRECT: + { + const SDL_Rect *rect = &cmd->data.cliprect.rect; + if (rendererData->currentCliprectEnabled != cmd->data.cliprect.enabled) { + rendererData->currentCliprectEnabled = cmd->data.cliprect.enabled; + rendererData->cliprectDirty = SDL_TRUE; } - - case SDL_RENDERCMD_CLEAR: { - const float colorRGBA[] = { - (cmd->data.color.r / 255.0f), - (cmd->data.color.g / 255.0f), - (cmd->data.color.b / 255.0f), - (cmd->data.color.a / 255.0f) - }; - ID3D11DeviceContext_ClearRenderTargetView(rendererData->d3dContext, D3D11_GetCurrentRenderTargetView(renderer), colorRGBA); - break; + if (SDL_memcmp(&rendererData->currentCliprect, rect, sizeof(*rect)) != 0) { + SDL_copyp(&rendererData->currentCliprect, rect); + rendererData->cliprectDirty = SDL_TRUE; } + break; + } - case SDL_RENDERCMD_DRAW_POINTS: { - const size_t count = cmd->data.draw.count; - const size_t first = cmd->data.draw.first; - const size_t start = first / sizeof (VertexPositionColor); - D3D11_SetDrawState(renderer, cmd, rendererData->pixelShaders[SHADER_SOLID], 0, NULL, NULL, NULL); - D3D11_DrawPrimitives(renderer, D3D11_PRIMITIVE_TOPOLOGY_POINTLIST, start, count); - break; + case SDL_RENDERCMD_CLEAR: + { + const float colorRGBA[] = { + (cmd->data.color.r / 255.0f), + (cmd->data.color.g / 255.0f), + (cmd->data.color.b / 255.0f), + (cmd->data.color.a / 255.0f) + }; + ID3D11DeviceContext_ClearRenderTargetView(rendererData->d3dContext, D3D11_GetCurrentRenderTargetView(renderer), colorRGBA); + break; + } + + case SDL_RENDERCMD_DRAW_POINTS: + { + const size_t count = cmd->data.draw.count; + const size_t first = cmd->data.draw.first; + const size_t start = first / sizeof(VertexPositionColor); + D3D11_SetDrawState(renderer, cmd, rendererData->pixelShaders[SHADER_SOLID], 0, NULL, NULL, NULL); + D3D11_DrawPrimitives(renderer, D3D11_PRIMITIVE_TOPOLOGY_POINTLIST, start, count); + break; + } + + case SDL_RENDERCMD_DRAW_LINES: + { + const size_t count = cmd->data.draw.count; + const size_t first = cmd->data.draw.first; + const size_t start = first / sizeof(VertexPositionColor); + const VertexPositionColor *verts = (VertexPositionColor *)(((Uint8 *)vertices) + first); + D3D11_SetDrawState(renderer, cmd, rendererData->pixelShaders[SHADER_SOLID], 0, NULL, NULL, NULL); + D3D11_DrawPrimitives(renderer, D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP, start, count); + if (verts[0].pos.x != verts[count - 1].pos.x || verts[0].pos.y != verts[count - 1].pos.y) { + D3D11_DrawPrimitives(renderer, D3D11_PRIMITIVE_TOPOLOGY_POINTLIST, start + (count - 1), 1); } + break; + } - case SDL_RENDERCMD_DRAW_LINES: { - const size_t count = cmd->data.draw.count; - const size_t first = cmd->data.draw.first; - const size_t start = first / sizeof (VertexPositionColor); - const VertexPositionColor *verts = (VertexPositionColor *) (((Uint8 *) vertices) + first); - D3D11_SetDrawState(renderer, cmd, rendererData->pixelShaders[SHADER_SOLID], 0, NULL, NULL, NULL); - D3D11_DrawPrimitives(renderer, D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP, start, count); - if (verts[0].pos.x != verts[count - 1].pos.x || verts[0].pos.y != verts[count - 1].pos.y) { - D3D11_DrawPrimitives(renderer, D3D11_PRIMITIVE_TOPOLOGY_POINTLIST, start + (count-1), 1); - } - break; - } + case SDL_RENDERCMD_FILL_RECTS: /* unused */ + break; - case SDL_RENDERCMD_FILL_RECTS: { - const size_t count = cmd->data.draw.count; - const size_t first = cmd->data.draw.first; - const size_t start = first / sizeof (VertexPositionColor); - size_t offset = 0; - D3D11_SetDrawState(renderer, cmd, rendererData->pixelShaders[SHADER_SOLID], 0, NULL, NULL, NULL); - for (i = 0; i < count; i++, offset += 4) { - D3D11_DrawPrimitives(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, start + offset, 4); - } - break; - } + case SDL_RENDERCMD_COPY: /* unused */ + break; - case SDL_RENDERCMD_COPY: { - const size_t first = cmd->data.draw.first; - const size_t start = first / sizeof (VertexPositionColor); + case SDL_RENDERCMD_COPY_EX: /* unused */ + break; + + case SDL_RENDERCMD_GEOMETRY: + { + SDL_Texture *texture = cmd->data.draw.texture; + const size_t count = cmd->data.draw.count; + const size_t first = cmd->data.draw.first; + const size_t start = first / sizeof(VertexPositionColor); + + if (texture) { D3D11_SetCopyState(renderer, cmd, NULL); - D3D11_DrawPrimitives(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, start, 4); - break; + } else { + D3D11_SetDrawState(renderer, cmd, rendererData->pixelShaders[SHADER_SOLID], 0, NULL, NULL, NULL); } - case SDL_RENDERCMD_COPY_EX: { - const size_t first = cmd->data.draw.first; - const size_t start = first / sizeof (VertexPositionColor); - const VertexPositionColor *verts = (VertexPositionColor *) (((Uint8 *) vertices) + first); - const VertexPositionColor *transvert = verts + 4; - const float translatex = transvert->pos.x; - const float translatey = transvert->pos.y; - const float rotation = transvert->pos.z; - const Float4X4 matrix = MatrixMultiply(MatrixRotationZ(rotation), MatrixTranslation(translatex, translatey, 0)); - D3D11_SetCopyState(renderer, cmd, &matrix); - D3D11_DrawPrimitives(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, start, 4); - break; - } + D3D11_DrawPrimitives(renderer, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, start, count); + break; + } - case SDL_RENDERCMD_NO_OP: - break; + case SDL_RENDERCMD_NO_OP: + break; } cmd = cmd->next; @@ -2320,28 +2138,29 @@ D3D11_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver return 0; } -static int -D3D11_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, - Uint32 format, void * pixels, int pitch) +static int D3D11_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect, + Uint32 format, void *pixels, int pitch) { - D3D11_RenderData * data = (D3D11_RenderData *) renderer->driverdata; + D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata; + ID3D11RenderTargetView *renderTargetView = NULL; ID3D11Texture2D *backBuffer = NULL; ID3D11Texture2D *stagingTexture = NULL; HRESULT result; int status = -1; D3D11_TEXTURE2D_DESC stagingTextureDesc; - D3D11_RECT srcRect = {0, 0, 0, 0}; + D3D11_RECT srcRect = { 0, 0, 0, 0 }; D3D11_BOX srcBox; D3D11_MAPPED_SUBRESOURCE textureMemory; - /* Retrieve a pointer to the back buffer: */ - result = IDXGISwapChain_GetBuffer(data->swapChain, - 0, - &SDL_IID_ID3D11Texture2D, - (void **)&backBuffer - ); - if (FAILED(result)) { - WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGISwapChain1::GetBuffer [get back buffer]"), result); + renderTargetView = D3D11_GetCurrentRenderTargetView(renderer); + if (!renderTargetView) { + SDL_SetError("%s, ID3D11DeviceContext::OMGetRenderTargets failed", __FUNCTION__); + goto done; + } + + ID3D11View_GetResource(renderTargetView, (ID3D11Resource **)&backBuffer); + if (!backBuffer) { + SDL_SetError("%s, ID3D11View::GetResource failed", __FUNCTION__); goto done; } @@ -2354,9 +2173,9 @@ D3D11_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, stagingTextureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; stagingTextureDesc.Usage = D3D11_USAGE_STAGING; result = ID3D11Device_CreateTexture2D(data->d3dDevice, - &stagingTextureDesc, - NULL, - &stagingTexture); + &stagingTextureDesc, + NULL, + &stagingTexture); if (FAILED(result)) { WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D [create staging texture]"), result); goto done; @@ -2375,20 +2194,20 @@ D3D11_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, srcBox.front = 0; srcBox.back = 1; ID3D11DeviceContext_CopySubresourceRegion(data->d3dContext, - (ID3D11Resource *)stagingTexture, - 0, - 0, 0, 0, - (ID3D11Resource *)backBuffer, - 0, - &srcBox); + (ID3D11Resource *)stagingTexture, + 0, + 0, 0, 0, + (ID3D11Resource *)backBuffer, + 0, + &srcBox); /* Map the staging texture's data to CPU-accessible memory: */ result = ID3D11DeviceContext_Map(data->d3dContext, - (ID3D11Resource *)stagingTexture, - 0, - D3D11_MAP_READ, - 0, - &textureMemory); + (ID3D11Resource *)stagingTexture, + 0, + D3D11_MAP_READ, + 0, + &textureMemory); if (FAILED(result)) { WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11DeviceContext1::Map [map staging texture]"), result); goto done; @@ -2397,29 +2216,19 @@ D3D11_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, /* Copy the data into the desired buffer, converting pixels to the * desired format at the same time: */ - if (SDL_ConvertPixels( + status = SDL_ConvertPixels( rect->w, rect->h, D3D11_DXGIFormatToSDLPixelFormat(stagingTextureDesc.Format), textureMemory.pData, textureMemory.RowPitch, format, pixels, - pitch) != 0) { - /* When SDL_ConvertPixels fails, it'll have already set the format. - * Get the error message, and attach some extra data to it. - */ - char errorMessage[1024]; - SDL_snprintf(errorMessage, sizeof(errorMessage), "%s, Convert Pixels failed: %s", __FUNCTION__, SDL_GetError()); - SDL_SetError("%s", errorMessage); - goto done; - } + pitch); /* Unmap the texture: */ ID3D11DeviceContext_Unmap(data->d3dContext, - (ID3D11Resource *)stagingTexture, - 0); - - status = 0; + (ID3D11Resource *)stagingTexture, + 0); done: SAFE_RELEASE(backBuffer); @@ -2427,10 +2236,9 @@ done: return status; } -static void -D3D11_RenderPresent(SDL_Renderer * renderer) +static int D3D11_RenderPresent(SDL_Renderer *renderer) { - D3D11_RenderData *data = (D3D11_RenderData *) renderer->driverdata; + D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata; UINT syncInterval; UINT presentFlags; HRESULT result; @@ -2438,7 +2246,7 @@ D3D11_RenderPresent(SDL_Renderer * renderer) SDL_zero(parameters); -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP +#if SDL_WINAPI_FAMILY_PHONE syncInterval = 1; presentFlags = 0; result = IDXGISwapChain_Present(data->swapChain, syncInterval, presentFlags); @@ -2462,18 +2270,18 @@ D3D11_RenderPresent(SDL_Renderer * renderer) * This is a valid operation only when the existing contents will be entirely * overwritten. If dirty or scroll rects are used, this call should be removed. */ - ID3D11DeviceContext1_DiscardView(data->d3dContext, (ID3D11View*)data->mainRenderTargetView); + ID3D11DeviceContext1_DiscardView(data->d3dContext, (ID3D11View *)data->mainRenderTargetView); /* When the present flips, it unbinds the current view, so bind it again on the next draw call */ data->currentRenderTargetView = NULL; if (FAILED(result) && result != DXGI_ERROR_WAS_STILL_DRAWING) { - /* If the device was removed either by a disconnect or a driver upgrade, we + /* If the device was removed either by a disconnect or a driver upgrade, we * must recreate all device resources. * * TODO, WinRT: consider throwing an exception if D3D11_RenderPresent fails, especially if there is a way to salvage debug info from users' machines */ - if ( result == DXGI_ERROR_DEVICE_REMOVED ) { + if (result == DXGI_ERROR_DEVICE_REMOVED) { D3D11_HandleDeviceLost(renderer); } else if (result == DXGI_ERROR_INVALID_CALL) { /* We probably went through a fullscreen <-> windowed transition */ @@ -2481,23 +2289,39 @@ D3D11_RenderPresent(SDL_Renderer * renderer) } else { WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGISwapChain::Present"), result); } + return -1; } + return 0; } -SDL_Renderer * -D3D11_CreateRenderer(SDL_Window * window, Uint32 flags) +#if SDL_WINAPI_FAMILY_PHONE +/* no-op. */ +#else +static int D3D11_SetVSync(SDL_Renderer *renderer, const int vsync) +{ + if (vsync) { + renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; + } else { + renderer->info.flags &= ~SDL_RENDERER_PRESENTVSYNC; + } + return 0; +} +#endif + +SDL_Renderer *D3D11_CreateRenderer(SDL_Window *window, Uint32 flags) { SDL_Renderer *renderer; D3D11_RenderData *data; - renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer)); + renderer = (SDL_Renderer *)SDL_calloc(1, sizeof(*renderer)); if (!renderer) { SDL_OutOfMemory(); return NULL; } - data = (D3D11_RenderData *) SDL_calloc(1, sizeof(*data)); + data = (D3D11_RenderData *)SDL_calloc(1, sizeof(*data)); if (!data) { + SDL_free(renderer); SDL_OutOfMemory(); return NULL; } @@ -2505,21 +2329,25 @@ D3D11_CreateRenderer(SDL_Window * window, Uint32 flags) data->identity = MatrixIdentity(); renderer->WindowEvent = D3D11_WindowEvent; +#if !defined(__WINRT__) + renderer->GetOutputSize = D3D11_GetOutputSize; +#endif renderer->SupportsBlendMode = D3D11_SupportsBlendMode; renderer->CreateTexture = D3D11_CreateTexture; renderer->UpdateTexture = D3D11_UpdateTexture; +#if SDL_HAVE_YUV renderer->UpdateTextureYUV = D3D11_UpdateTextureYUV; + renderer->UpdateTextureNV = D3D11_UpdateTextureNV; +#endif renderer->LockTexture = D3D11_LockTexture; renderer->UnlockTexture = D3D11_UnlockTexture; renderer->SetTextureScaleMode = D3D11_SetTextureScaleMode; renderer->SetRenderTarget = D3D11_SetRenderTarget; renderer->QueueSetViewport = D3D11_QueueSetViewport; - renderer->QueueSetDrawColor = D3D11_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */ + renderer->QueueSetDrawColor = D3D11_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */ renderer->QueueDrawPoints = D3D11_QueueDrawPoints; - renderer->QueueDrawLines = D3D11_QueueDrawPoints; /* lines and points queue vertices the same way. */ - renderer->QueueFillRects = D3D11_QueueFillRects; - renderer->QueueCopy = D3D11_QueueCopy; - renderer->QueueCopyEx = D3D11_QueueCopyEx; + renderer->QueueDrawLines = D3D11_QueueDrawPoints; /* lines and points queue vertices the same way. */ + renderer->QueueGeometry = D3D11_QueueGeometry; renderer->RunCommandQueue = D3D11_RunCommandQueue; renderer->RenderReadPixels = D3D11_RenderReadPixels; renderer->RenderPresent = D3D11_RenderPresent; @@ -2529,7 +2357,7 @@ D3D11_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->info.flags = (SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE); renderer->driverdata = data; -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP +#if SDL_WINAPI_FAMILY_PHONE /* VSync is required in Windows Phone, at least for Win Phone 8.0 and 8.1. * Failure to use it seems to either result in: * @@ -2538,14 +2366,15 @@ D3D11_CreateRenderer(SDL_Window * window, Uint32 flags) * * - with the D3D11 debug runtime turned ON, vsync gets automatically * turned back on, and the following gets output to the debug console: - * - * DXGI ERROR: IDXGISwapChain::Present: Interval 0 is not supported, changed to Interval 1. [ UNKNOWN ERROR #1024: ] + * + * DXGI ERROR: IDXGISwapChain::Present: Interval 0 is not supported, changed to Interval 1. [ UNKNOWN ERROR #1024: ] */ renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; #else - if ((flags & SDL_RENDERER_PRESENTVSYNC)) { + if (flags & SDL_RENDERER_PRESENTVSYNC) { renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; } + renderer->SetVSync = D3D11_SetVSync; #endif /* HACK: make sure the SDL_Renderer references the SDL_Window data now, in @@ -2573,22 +2402,45 @@ SDL_RenderDriver D3D11_RenderDriver = { ( SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | - SDL_RENDERER_TARGETTEXTURE - ), /* flags. see SDL_RendererFlags */ - 6, /* num_texture_formats */ - { /* texture_formats */ - SDL_PIXELFORMAT_ARGB8888, - SDL_PIXELFORMAT_RGB888, - SDL_PIXELFORMAT_YV12, - SDL_PIXELFORMAT_IYUV, - SDL_PIXELFORMAT_NV12, - SDL_PIXELFORMAT_NV21 - }, - 0, /* max_texture_width: will be filled in later */ - 0 /* max_texture_height: will be filled in later */ + SDL_RENDERER_TARGETTEXTURE), /* flags. see SDL_RendererFlags */ + 6, /* num_texture_formats */ + { /* texture_formats */ + SDL_PIXELFORMAT_ARGB8888, + SDL_PIXELFORMAT_RGB888, + SDL_PIXELFORMAT_YV12, + SDL_PIXELFORMAT_IYUV, + SDL_PIXELFORMAT_NV12, + SDL_PIXELFORMAT_NV21 }, + 0, /* max_texture_width: will be filled in later */ + 0 /* max_texture_height: will be filled in later */ } }; -#endif /* SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_D3D11 */ + +#if defined(__WIN32__) || defined(__WINGDK__) +/* This function needs to always exist on Windows, for the Dynamic API. */ +ID3D11Device *SDL_RenderGetD3D11Device(SDL_Renderer *renderer) +{ + ID3D11Device *device = NULL; + +#if SDL_VIDEO_RENDER_D3D11 + D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata; + + /* Make sure that this is a D3D renderer */ + if (renderer->DestroyRenderer != D3D11_DestroyRenderer) { + SDL_SetError("Renderer is not a D3D11 renderer"); + return NULL; + } + + device = (ID3D11Device *)data->d3dDevice; + if (device) { + ID3D11Device_AddRef(device); + } +#endif /* SDL_VIDEO_RENDER_D3D11 */ + + return device; +} +#endif /* defined(__WIN32__) || defined(__WINGDK__) */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/render/direct3d11/SDL_render_winrt.cpp b/SDL2-2.30.5/src/render/direct3d11/SDL_render_winrt.cpp similarity index 88% rename from SDL2-2.0.12/src/render/direct3d11/SDL_render_winrt.cpp rename to SDL2-2.30.5/src/render/direct3d11/SDL_render_winrt.cpp index 329b3ff..0ed7add 100644 --- a/SDL2-2.0.12/src/render/direct3d11/SDL_render_winrt.cpp +++ b/SDL2-2.30.5/src/render/direct3d11/SDL_render_winrt.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED +#if SDL_VIDEO_RENDER_D3D11 #include "SDL_syswm.h" #include "../../video/winrt/SDL_winrtvideo_cpp.h" @@ -42,12 +42,11 @@ using namespace Windows::Graphics::Display; #include "SDL_render_winrt.h" - extern "C" void * -D3D11_GetCoreWindowFromSDLRenderer(SDL_Renderer * renderer) +D3D11_GetCoreWindowFromSDLRenderer(SDL_Renderer *renderer) { - SDL_Window * sdlWindow = renderer->window; - if ( ! renderer->window ) { + SDL_Window *sdlWindow = renderer->window; + if (!renderer->window) { return NULL; } @@ -84,7 +83,7 @@ D3D11_GetCurrentRotation() switch (currentOrientation) { -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP +#if SDL_WINAPI_FAMILY_PHONE /* Windows Phone rotations */ case DisplayOrientations::Landscape: return DXGI_MODE_ROTATION_ROTATE90; @@ -104,13 +103,12 @@ D3D11_GetCurrentRotation() return DXGI_MODE_ROTATION_ROTATE180; case DisplayOrientations::PortraitFlipped: return DXGI_MODE_ROTATION_ROTATE90; -#endif /* WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP */ +#endif /* SDL_WINAPI_FAMILY_PHONE */ } return DXGI_MODE_ROTATION_IDENTITY; } - -#endif /* SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_D3D11 */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/render/direct3d11/SDL_render_winrt.h b/SDL2-2.30.5/src/render/direct3d11/SDL_render_winrt.h similarity index 82% rename from SDL2-2.0.12/src/render/direct3d11/SDL_render_winrt.h rename to SDL2-2.30.5/src/render/direct3d11/SDL_render_winrt.h index c2fd3a4..dd9a176 100644 --- a/SDL2-2.0.12/src/render/direct3d11/SDL_render_winrt.h +++ b/SDL2-2.30.5/src/render/direct3d11/SDL_render_winrt.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED +#if SDL_VIDEO_RENDER_D3D11 #include "SDL_render.h" @@ -28,13 +28,13 @@ extern "C" { #endif -void * D3D11_GetCoreWindowFromSDLRenderer(SDL_Renderer * renderer); +void *D3D11_GetCoreWindowFromSDLRenderer(SDL_Renderer *renderer); DXGI_MODE_ROTATION D3D11_GetCurrentRotation(); #ifdef __cplusplus } #endif -#endif /* SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_D3D11 */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/render/direct3d11/SDL_shaders_d3d11.c b/SDL2-2.30.5/src/render/direct3d11/SDL_shaders_d3d11.c similarity index 98% rename from SDL2-2.0.12/src/render/direct3d11/SDL_shaders_d3d11.c rename to SDL2-2.30.5/src/render/direct3d11/SDL_shaders_d3d11.c index 4c23f6d..5f3a9a4 100644 --- a/SDL2-2.0.12/src/render/direct3d11/SDL_shaders_d3d11.c +++ b/SDL2-2.30.5/src/render/direct3d11/SDL_shaders_d3d11.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED +#if SDL_VIDEO_RENDER_D3D11 #include "SDL_stdinc.h" @@ -32,7 +32,6 @@ #define SDL_COMPOSE_ERROR(str) SDL_STRINGIFY_ARG(__FUNCTION__) ", " str - /* Direct3D 11.x shaders SDL's shaders are compiled into SDL itself, to simplify distribution. @@ -52,14 +51,14 @@ - vs_4_0_level_9_1: Vertex shader for Windows 8+, including Windows RT - ps_4_0_level_9_3: Pixel shader for Windows Phone 8 - vs_4_0_level_9_3: Vertex shader for Windows Phone 8 - + Shader object code was converted to a list of DWORDs via the following *nix style command (available separately from Windows + MSVC): hexdump -v -e '6/4 "0x%08.8x, " "\n"' */ -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP +#if SDL_WINAPI_FAMILY_PHONE #define D3D11_USE_SHADER_MODEL_4_0_level_9_3 #else #define D3D11_USE_SHADER_MODEL_4_0_level_9_1 @@ -1886,9 +1885,10 @@ static struct { const void *shader_data; SIZE_T shader_size; -} D3D11_shaders[] = { +} D3D11_shaders[NUM_SHADERS] = { { D3D11_PixelShader_Colors, sizeof(D3D11_PixelShader_Colors) }, { D3D11_PixelShader_Textures, sizeof(D3D11_PixelShader_Textures) }, +#if SDL_HAVE_YUV { D3D11_PixelShader_YUV_JPEG, sizeof(D3D11_PixelShader_YUV_JPEG) }, { D3D11_PixelShader_YUV_BT601, sizeof(D3D11_PixelShader_YUV_BT601) }, { D3D11_PixelShader_YUV_BT709, sizeof(D3D11_PixelShader_YUV_BT709) }, @@ -1898,38 +1898,36 @@ static struct { D3D11_PixelShader_NV21_JPEG, sizeof(D3D11_PixelShader_NV21_JPEG) }, { D3D11_PixelShader_NV21_BT601, sizeof(D3D11_PixelShader_NV21_BT601) }, { D3D11_PixelShader_NV21_BT709, sizeof(D3D11_PixelShader_NV21_BT709) }, +#endif }; int D3D11_CreateVertexShader(ID3D11Device1 *d3dDevice, ID3D11VertexShader **vertexShader, ID3D11InputLayout **inputLayout) { /* Declare how the input layout for SDL's vertex shader will be setup: */ - const D3D11_INPUT_ELEMENT_DESC vertexDesc[] = - { - { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, - { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, - { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 20, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + const D3D11_INPUT_ELEMENT_DESC vertexDesc[] = { + { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 16, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; HRESULT result; /* Load in SDL's one and only vertex shader: */ result = ID3D11Device_CreateVertexShader(d3dDevice, - D3D11_VertexShader, - sizeof(D3D11_VertexShader), - NULL, - vertexShader - ); + D3D11_VertexShader, + sizeof(D3D11_VertexShader), + NULL, + vertexShader); if (FAILED(result)) { return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateVertexShader"), result); } /* Create an input layout for SDL's vertex shader: */ result = ID3D11Device_CreateInputLayout(d3dDevice, - vertexDesc, - ARRAYSIZE(vertexDesc), - D3D11_VertexShader, - sizeof(D3D11_VertexShader), - inputLayout - ); + vertexDesc, + ARRAYSIZE(vertexDesc), + D3D11_VertexShader, + sizeof(D3D11_VertexShader), + inputLayout); if (FAILED(result)) { return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateInputLayout"), result); } @@ -1941,17 +1939,16 @@ int D3D11_CreatePixelShader(ID3D11Device1 *d3dDevice, D3D11_Shader shader, ID3D1 HRESULT result; result = ID3D11Device_CreatePixelShader(d3dDevice, - D3D11_shaders[shader].shader_data, - D3D11_shaders[shader].shader_size, - NULL, - pixelShader - ); + D3D11_shaders[shader].shader_data, + D3D11_shaders[shader].shader_size, + NULL, + pixelShader); if (FAILED(result)) { return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreatePixelShader"), result); } return 0; } -#endif /* SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_D3D11 */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/render/direct3d11/SDL_shaders_d3d11.h b/SDL2-2.30.5/src/render/direct3d11/SDL_shaders_d3d11.h similarity index 93% rename from SDL2-2.0.12/src/render/direct3d11/SDL_shaders_d3d11.h rename to SDL2-2.30.5/src/render/direct3d11/SDL_shaders_d3d11.h index cffb998..010cd93 100644 --- a/SDL2-2.0.12/src/render/direct3d11/SDL_shaders_d3d11.h +++ b/SDL2-2.30.5/src/render/direct3d11/SDL_shaders_d3d11.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -22,9 +22,11 @@ /* D3D11 shader implementation */ -typedef enum { +typedef enum +{ SHADER_SOLID, SHADER_RGB, +#if SDL_HAVE_YUV SHADER_YUV_JPEG, SHADER_YUV_BT601, SHADER_YUV_BT709, @@ -34,6 +36,7 @@ typedef enum { SHADER_NV21_JPEG, SHADER_NV21_BT601, SHADER_NV21_BT709, +#endif NUM_SHADERS } D3D11_Shader; diff --git a/SDL2-2.30.5/src/render/direct3d12/SDL_render_d3d12.c b/SDL2-2.30.5/src/render/direct3d12/SDL_render_d3d12.c new file mode 100644 index 0000000..8a607bf --- /dev/null +++ b/SDL2-2.30.5/src/render/direct3d12/SDL_render_d3d12.c @@ -0,0 +1,3144 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_render.h" +#include "SDL_system.h" + +#if SDL_VIDEO_RENDER_D3D12 + +#define SDL_D3D12_NUM_BUFFERS 2 +#define SDL_D3D12_NUM_VERTEX_BUFFERS 256 +#define SDL_D3D12_MAX_NUM_TEXTURES 16384 +#define SDL_D3D12_NUM_UPLOAD_BUFFERS 32 + +#include "../../core/windows/SDL_windows.h" +#include "../../video/windows/SDL_windowswindow.h" +#include "SDL_hints.h" +#include "SDL_loadso.h" +#include "SDL_syswm.h" +#include "../SDL_sysrender.h" +#include "../SDL_d3dmath.h" + +#if defined(__XBOXONE__) || defined(__XBOXSERIES__) +#include "SDL_render_d3d12_xbox.h" +#ifndef D3D12_TEXTURE_DATA_PITCH_ALIGNMENT +#define D3D12_TEXTURE_DATA_PITCH_ALIGNMENT 256 +#endif +#else +#include +#include +#include +#include +#include +#endif + +#include "SDL_shaders_d3d12.h" + +#if defined(_MSC_VER) && !defined(__clang__) +#define SDL_COMPOSE_ERROR(str) __FUNCTION__ ", " str +#else +#define SDL_COMPOSE_ERROR(str) SDL_STRINGIFY_ARG(__FUNCTION__) ", " str +#endif + +/* DXGI_PRESENT flags are removed on Xbox */ +#if defined(__XBOXONE__) || defined(__XBOXSERIES__) +#define DXGI_PRESENT_ALLOW_TEARING 0 +#endif + +#ifdef __cplusplus +#define SAFE_RELEASE(X) \ + if (X) { \ + (X)->Release(); \ + X = NULL; \ + } +#define D3D_CALL(THIS, FUNC, ...) (THIS)->FUNC(__VA_ARGS__) +#define D3D_CALL_RET(THIS, FUNC, RETVAL, ...) *(RETVAL) = (THIS)->FUNC(__VA_ARGS__) +#define D3D_GUID(X) (X) +#else +#define SAFE_RELEASE(X) \ + if (X) { \ + (X)->lpVtbl->Release(X); \ + X = NULL; \ + } +#define D3D_CALL(THIS, FUNC, ...) (THIS)->lpVtbl->FUNC((THIS), ##__VA_ARGS__) +#define D3D_CALL_RET(THIS, FUNC, ...) (THIS)->lpVtbl->FUNC((THIS), ##__VA_ARGS__) +#define D3D_GUID(X) &(X) +#endif + +/* + * Older MS Windows SDK headers declare some d3d12 functions with the wrong function prototype. + * - ID3D12Heap::GetDesc + * - ID3D12Resource::GetDesc + * - ID3D12DescriptorHeap::GetDesc + * (and 9 more)+ + * This is fixed in SDKs since WDK_NTDDI_VERSION >= NTDDI_WIN10_FE (0x0A00000A) + */ + +#if !(defined(__MINGW32__) || defined(__XBOXONE__) || defined(__XBOXSERIES__)) \ + && (WDK_NTDDI_VERSION < 0x0A00000A) + +#define D3D_CALL_RET_ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(THIS, ...) do { \ + void (STDMETHODCALLTYPE * func)(ID3D12DescriptorHeap * This, D3D12_CPU_DESCRIPTOR_HANDLE * Handle) = \ + (void*)(THIS)->lpVtbl->GetCPUDescriptorHandleForHeapStart; \ + func((THIS), ##__VA_ARGS__); \ + } while (0) + +#define D3D_CALL_RET_ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(THIS, ...) do { \ + void (STDMETHODCALLTYPE * func)(ID3D12DescriptorHeap * This, D3D12_GPU_DESCRIPTOR_HANDLE * Handle) = \ + (void*)(THIS)->lpVtbl->GetGPUDescriptorHandleForHeapStart; \ + func((THIS), ##__VA_ARGS__); \ + } while (0) + +#define D3D_CALL_RET_ID3D12Resource_GetDesc(THIS, ...) do { \ + void (STDMETHODCALLTYPE * func)(ID3D12Resource * This, D3D12_RESOURCE_DESC * Desc) = \ + (void*)(THIS)->lpVtbl->GetDesc; \ + func((THIS), ##__VA_ARGS__); \ + } while (0) + +#else + +/* + * MinGW has correct function prototypes in the vtables, but defines wrong functions + * Xbox just needs these macros defined as used below (because CINTERFACE doesn't exist) + */ + +#define D3D_CALL_RET_ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(THIS, ...) \ + D3D_CALL_RET(THIS, GetCPUDescriptorHandleForHeapStart, ##__VA_ARGS__); + +#define D3D_CALL_RET_ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(THIS, ...) \ + D3D_CALL_RET(THIS, GetGPUDescriptorHandleForHeapStart, ##__VA_ARGS__); + +#define D3D_CALL_RET_ID3D12Resource_GetDesc(THIS, ...) \ + D3D_CALL_RET(THIS, GetDesc, ##__VA_ARGS__); + +#endif + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* !!! FIXME: vertex buffer bandwidth could be lower; only use UV coords when + !!! FIXME: textures are needed. */ + +/* Vertex shader, common values */ +typedef struct +{ + Float4X4 model; + Float4X4 projectionAndView; +} VertexShaderConstants; + +/* Per-vertex data */ +typedef struct +{ + Float2 pos; + Float2 tex; + SDL_Color color; +} VertexPositionColor; + +/* Per-texture data */ +typedef struct +{ + ID3D12Resource *mainTexture; + D3D12_CPU_DESCRIPTOR_HANDLE mainTextureResourceView; + D3D12_RESOURCE_STATES mainResourceState; + SIZE_T mainSRVIndex; + D3D12_CPU_DESCRIPTOR_HANDLE mainTextureRenderTargetView; + DXGI_FORMAT mainTextureFormat; + ID3D12Resource *stagingBuffer; + D3D12_RESOURCE_STATES stagingResourceState; + D3D12_FILTER scaleMode; +#if SDL_HAVE_YUV + /* YV12 texture support */ + SDL_bool yuv; + ID3D12Resource *mainTextureU; + D3D12_CPU_DESCRIPTOR_HANDLE mainTextureResourceViewU; + D3D12_RESOURCE_STATES mainResourceStateU; + SIZE_T mainSRVIndexU; + ID3D12Resource *mainTextureV; + D3D12_CPU_DESCRIPTOR_HANDLE mainTextureResourceViewV; + D3D12_RESOURCE_STATES mainResourceStateV; + SIZE_T mainSRVIndexV; + + /* NV12 texture support */ + SDL_bool nv12; + ID3D12Resource *mainTextureNV; + D3D12_CPU_DESCRIPTOR_HANDLE mainTextureResourceViewNV; + D3D12_RESOURCE_STATES mainResourceStateNV; + SIZE_T mainSRVIndexNV; + + Uint8 *pixels; + int pitch; +#endif + SDL_Rect lockedRect; +} D3D12_TextureData; + +/* Pipeline State Object data */ +typedef struct +{ + D3D12_Shader shader; + SDL_BlendMode blendMode; + D3D12_PRIMITIVE_TOPOLOGY_TYPE topology; + DXGI_FORMAT rtvFormat; + ID3D12PipelineState *pipelineState; +} D3D12_PipelineState; + +/* Vertex Buffer */ +typedef struct +{ + ID3D12Resource *resource; + D3D12_VERTEX_BUFFER_VIEW view; + size_t size; +} D3D12_VertexBuffer; + +/* For SRV pool allocator */ +typedef struct +{ + SIZE_T index; + void *next; +} D3D12_SRVPoolNode; + +/* Private renderer data */ +typedef struct +{ + void *hDXGIMod; + void *hD3D12Mod; +#if defined(__XBOXONE__) || defined(__XBOXSERIES__) + UINT64 frameToken; +#else + IDXGIFactory6 *dxgiFactory; + IDXGIAdapter4 *dxgiAdapter; + IDXGIDebug *dxgiDebug; + IDXGISwapChain4 *swapChain; +#endif + ID3D12Device1 *d3dDevice; + ID3D12Debug *debugInterface; + ID3D12CommandQueue *commandQueue; + ID3D12GraphicsCommandList2 *commandList; + DXGI_SWAP_EFFECT swapEffect; + UINT swapFlags; + + /* Descriptor heaps */ + ID3D12DescriptorHeap *rtvDescriptorHeap; + UINT rtvDescriptorSize; + ID3D12DescriptorHeap *textureRTVDescriptorHeap; + ID3D12DescriptorHeap *srvDescriptorHeap; + UINT srvDescriptorSize; + ID3D12DescriptorHeap *samplerDescriptorHeap; + UINT samplerDescriptorSize; + + /* Data needed per backbuffer */ + ID3D12CommandAllocator *commandAllocators[SDL_D3D12_NUM_BUFFERS]; + ID3D12Resource *renderTargets[SDL_D3D12_NUM_BUFFERS]; + UINT64 fenceValue; + int currentBackBufferIndex; + + /* Fences */ + ID3D12Fence *fence; + HANDLE fenceEvent; + + /* Root signature and pipeline state data */ + ID3D12RootSignature *rootSignatures[NUM_ROOTSIGS]; + int pipelineStateCount; + D3D12_PipelineState *pipelineStates; + D3D12_PipelineState *currentPipelineState; + + D3D12_VertexBuffer vertexBuffers[SDL_D3D12_NUM_VERTEX_BUFFERS]; + D3D12_CPU_DESCRIPTOR_HANDLE nearestPixelSampler; + D3D12_CPU_DESCRIPTOR_HANDLE linearSampler; + + /* Data for staging/allocating textures */ + ID3D12Resource *uploadBuffers[SDL_D3D12_NUM_UPLOAD_BUFFERS]; + int currentUploadBuffer; + + /* Pool allocator to handle reusing SRV heap indices */ + D3D12_SRVPoolNode *srvPoolHead; + D3D12_SRVPoolNode srvPoolNodes[SDL_D3D12_MAX_NUM_TEXTURES]; + + /* Vertex buffer constants */ + VertexShaderConstants vertexShaderConstantsData; + + /* Cached renderer properties */ + DXGI_MODE_ROTATION rotation; + D3D12_TextureData *textureRenderTarget; + D3D12_CPU_DESCRIPTOR_HANDLE currentRenderTargetView; + D3D12_CPU_DESCRIPTOR_HANDLE currentShaderResource; + D3D12_CPU_DESCRIPTOR_HANDLE currentSampler; + SDL_bool cliprectDirty; + SDL_bool currentCliprectEnabled; + SDL_Rect currentCliprect; + SDL_Rect currentViewport; + int currentViewportRotation; + SDL_bool viewportDirty; + Float4X4 identity; + int currentVertexBuffer; + SDL_bool issueBatch; +} D3D12_RenderData; + +/* Define D3D GUIDs here so we don't have to include uuid.lib. */ + +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-const-variable" +#endif + +static const GUID SDL_IID_IDXGIFactory6 = { 0xc1b6694f, 0xff09, 0x44a9, { 0xb0, 0x3c, 0x77, 0x90, 0x0a, 0x0a, 0x1d, 0x17 } }; +static const GUID SDL_IID_IDXGIAdapter4 = { 0x3c8d99d1, 0x4fbf, 0x4181, { 0xa8, 0x2c, 0xaf, 0x66, 0xbf, 0x7b, 0xd2, 0x4e } }; +static const GUID SDL_IID_IDXGIDevice1 = { 0x77db970f, 0x6276, 0x48ba, { 0xba, 0x28, 0x07, 0x01, 0x43, 0xb4, 0x39, 0x2c } }; +static const GUID SDL_IID_ID3D12Device1 = { 0x77acce80, 0x638e, 0x4e65, { 0x88, 0x95, 0xc1, 0xf2, 0x33, 0x86, 0x86, 0x3e } }; +static const GUID SDL_IID_IDXGISwapChain4 = { 0x3D585D5A, 0xBD4A, 0x489E, { 0xB1, 0xF4, 0x3D, 0xBC, 0xB6, 0x45, 0x2F, 0xFB } }; +static const GUID SDL_IID_IDXGIDebug1 = { 0xc5a05f0c, 0x16f2, 0x4adf, { 0x9f, 0x4d, 0xa8, 0xc4, 0xd5, 0x8a, 0xc5, 0x50 } }; +static const GUID SDL_IID_IDXGIInfoQueue = { 0xD67441C7, 0x672A, 0x476f, { 0x9E, 0x82, 0xCD, 0x55, 0xB4, 0x49, 0x49, 0xCE } }; +static const GUID SDL_IID_ID3D12Debug = { 0x344488b7, 0x6846, 0x474b, { 0xb9, 0x89, 0xf0, 0x27, 0x44, 0x82, 0x45, 0xe0 } }; +static const GUID SDL_DXGI_DEBUG_ALL = { 0xe48ae283, 0xda80, 0x490b, { 0x87, 0xe6, 0x43, 0xe9, 0xa9, 0xcf, 0xda, 0x8 } }; +static const GUID SDL_IID_ID3D12CommandQueue = { 0x0ec870a6, 0x5d7e, 0x4c22, { 0x8c, 0xfc, 0x5b, 0xaa, 0xe0, 0x76, 0x16, 0xed } }; +static const GUID SDL_IID_ID3D12DescriptorHeap = { 0x8efb471d, 0x616c, 0x4f49, { 0x90, 0xf7, 0x12, 0x7b, 0xb7, 0x63, 0xfa, 0x51 } }; +static const GUID SDL_IID_ID3D12CommandAllocator = { 0x6102dee4, 0xaf59, 0x4b09, { 0xb9, 0x99, 0xb4, 0x4d, 0x73, 0xf0, 0x9b, 0x24 } }; +static const GUID SDL_IID_ID3D12GraphicsCommandList2 = { 0x38C3E585, 0xFF17, 0x412C, { 0x91, 0x50, 0x4F, 0xC6, 0xF9, 0xD7, 0x2A, 0x28 } }; +static const GUID SDL_IID_ID3D12Fence = { 0x0a753dcf, 0xc4d8, 0x4b91, { 0xad, 0xf6, 0xbe, 0x5a, 0x60, 0xd9, 0x5a, 0x76 } }; +static const GUID SDL_IID_ID3D12Resource = { 0x696442be, 0xa72e, 0x4059, { 0xbc, 0x79, 0x5b, 0x5c, 0x98, 0x04, 0x0f, 0xad } }; +static const GUID SDL_IID_ID3D12RootSignature = { 0xc54a6b66, 0x72df, 0x4ee8, { 0x8b, 0xe5, 0xa9, 0x46, 0xa1, 0x42, 0x92, 0x14 } }; +static const GUID SDL_IID_ID3D12PipelineState = { 0x765a30f3, 0xf624, 0x4c6f, { 0xa8, 0x28, 0xac, 0xe9, 0x48, 0x62, 0x24, 0x45 } }; +static const GUID SDL_IID_ID3D12Heap = { 0x6b3b2502, 0x6e51, 0x45b3, { 0x90, 0xee, 0x98, 0x84, 0x26, 0x5e, 0x8d, 0xf3 } }; +static const GUID SDL_IID_ID3D12InfoQueue = { 0x0742a90b, 0xc387, 0x483f, { 0xb9, 0x46, 0x30, 0xa7, 0xe4, 0xe6, 0x14, 0x58 } }; + +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic pop +#endif + +UINT D3D12_Align(UINT location, UINT alignment) +{ + return (location + (alignment - 1)) & ~(alignment - 1); +} + +Uint32 D3D12_DXGIFormatToSDLPixelFormat(DXGI_FORMAT dxgiFormat) +{ + switch (dxgiFormat) { + case DXGI_FORMAT_B8G8R8A8_UNORM: + return SDL_PIXELFORMAT_ARGB8888; + case DXGI_FORMAT_B8G8R8X8_UNORM: + return SDL_PIXELFORMAT_RGB888; + default: + return SDL_PIXELFORMAT_UNKNOWN; + } +} + +static DXGI_FORMAT SDLPixelFormatToDXGIFormat(Uint32 sdlFormat) +{ + switch (sdlFormat) { + case SDL_PIXELFORMAT_ARGB8888: + return DXGI_FORMAT_B8G8R8A8_UNORM; + case SDL_PIXELFORMAT_RGB888: + return DXGI_FORMAT_B8G8R8X8_UNORM; + case SDL_PIXELFORMAT_YV12: + case SDL_PIXELFORMAT_IYUV: + case SDL_PIXELFORMAT_NV12: /* For the Y texture */ + case SDL_PIXELFORMAT_NV21: /* For the Y texture */ + return DXGI_FORMAT_R8_UNORM; + default: + return DXGI_FORMAT_UNKNOWN; + } +} + +static void D3D12_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture); + +static void D3D12_ReleaseAll(SDL_Renderer *renderer) +{ + D3D12_RenderData *data = (D3D12_RenderData *)renderer->driverdata; + SDL_Texture *texture = NULL; + + /* Release all textures */ + for (texture = renderer->textures; texture; texture = texture->next) { + D3D12_DestroyTexture(renderer, texture); + } + + /* Release/reset everything else */ + if (data) { + int i; + +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + SAFE_RELEASE(data->dxgiFactory); + SAFE_RELEASE(data->dxgiAdapter); + SAFE_RELEASE(data->swapChain); +#endif + SAFE_RELEASE(data->d3dDevice); + SAFE_RELEASE(data->debugInterface); + SAFE_RELEASE(data->commandQueue); + SAFE_RELEASE(data->commandList); + SAFE_RELEASE(data->rtvDescriptorHeap); + SAFE_RELEASE(data->textureRTVDescriptorHeap); + SAFE_RELEASE(data->srvDescriptorHeap); + SAFE_RELEASE(data->samplerDescriptorHeap); + SAFE_RELEASE(data->fence); + + for (i = 0; i < SDL_D3D12_NUM_BUFFERS; ++i) { + SAFE_RELEASE(data->commandAllocators[i]); + SAFE_RELEASE(data->renderTargets[i]); + } + + if (data->pipelineStateCount > 0) { + for (i = 0; i < data->pipelineStateCount; ++i) { + SAFE_RELEASE(data->pipelineStates[i].pipelineState); + } + SDL_free(data->pipelineStates); + data->pipelineStateCount = 0; + } + + for (i = 0; i < NUM_ROOTSIGS; ++i) { + SAFE_RELEASE(data->rootSignatures[i]); + } + + for (i = 0; i < SDL_D3D12_NUM_VERTEX_BUFFERS; ++i) { + SAFE_RELEASE(data->vertexBuffers[i].resource); + data->vertexBuffers[i].size = 0; + } + + data->swapEffect = (DXGI_SWAP_EFFECT)0; + data->swapFlags = 0; + data->currentRenderTargetView.ptr = 0; + data->currentSampler.ptr = 0; + +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + /* Check for any leaks if in debug mode */ + if (data->dxgiDebug) { + DXGI_DEBUG_RLO_FLAGS rloFlags = (DXGI_DEBUG_RLO_FLAGS)(DXGI_DEBUG_RLO_SUMMARY | DXGI_DEBUG_RLO_IGNORE_INTERNAL); + D3D_CALL(data->dxgiDebug, ReportLiveObjects, SDL_DXGI_DEBUG_ALL, rloFlags); + SAFE_RELEASE(data->dxgiDebug); + } +#endif + + /* Unload the D3D libraries. This should be done last, in order + * to prevent IUnknown::Release() calls from crashing. + */ + if (data->hD3D12Mod) { + SDL_UnloadObject(data->hD3D12Mod); + data->hD3D12Mod = NULL; + } + if (data->hDXGIMod) { + SDL_UnloadObject(data->hDXGIMod); + data->hDXGIMod = NULL; + } + } +} + +static D3D12_GPU_DESCRIPTOR_HANDLE D3D12_CPUtoGPUHandle(ID3D12DescriptorHeap *heap, D3D12_CPU_DESCRIPTOR_HANDLE CPUHandle) +{ + D3D12_CPU_DESCRIPTOR_HANDLE CPUHeapStart; + D3D12_GPU_DESCRIPTOR_HANDLE GPUHandle; + SIZE_T offset; + + /* Calculate the correct offset into the heap */ + D3D_CALL_RET_ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap, &CPUHeapStart); + offset = CPUHandle.ptr - CPUHeapStart.ptr; + + D3D_CALL_RET_ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap, &GPUHandle); + GPUHandle.ptr += offset; + + return GPUHandle; +} + +static void D3D12_WaitForGPU(D3D12_RenderData *data) +{ + if (data->commandQueue && data->fence && data->fenceEvent) { + D3D_CALL(data->commandQueue, Signal, data->fence, data->fenceValue); + if (D3D_CALL(data->fence, GetCompletedValue) < data->fenceValue) { + D3D_CALL(data->fence, SetEventOnCompletion, + data->fenceValue, + data->fenceEvent); + WaitForSingleObjectEx(data->fenceEvent, INFINITE, FALSE); + } + + data->fenceValue++; + } +} + +static D3D12_CPU_DESCRIPTOR_HANDLE D3D12_GetCurrentRenderTargetView(SDL_Renderer *renderer) +{ + D3D12_RenderData *data = (D3D12_RenderData *)renderer->driverdata; + D3D12_CPU_DESCRIPTOR_HANDLE rtvDescriptor; + + if (data->textureRenderTarget) { + return data->textureRenderTarget->mainTextureRenderTargetView; + } + + SDL_zero(rtvDescriptor); + D3D_CALL_RET_ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(data->rtvDescriptorHeap, &rtvDescriptor); + rtvDescriptor.ptr += data->currentBackBufferIndex * data->rtvDescriptorSize; + return rtvDescriptor; +} + +static void D3D12_TransitionResource(D3D12_RenderData *data, + ID3D12Resource *resource, + D3D12_RESOURCE_STATES beforeState, + D3D12_RESOURCE_STATES afterState) +{ + D3D12_RESOURCE_BARRIER barrier; + + if (beforeState != afterState) { + SDL_zero(barrier); + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Transition.pResource = resource; + barrier.Transition.StateBefore = beforeState; + barrier.Transition.StateAfter = afterState; + barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + + D3D_CALL(data->commandList, ResourceBarrier, 1, &barrier); + } +} + +static void D3D12_ResetCommandList(D3D12_RenderData *data) +{ + int i; + ID3D12DescriptorHeap *rootDescriptorHeaps[] = { data->srvDescriptorHeap, data->samplerDescriptorHeap }; + ID3D12CommandAllocator *commandAllocator = data->commandAllocators[data->currentBackBufferIndex]; + + D3D_CALL(commandAllocator, Reset); + D3D_CALL(data->commandList, Reset, commandAllocator, NULL); + data->currentPipelineState = NULL; + data->currentVertexBuffer = 0; + data->issueBatch = SDL_FALSE; + data->cliprectDirty = SDL_TRUE; + data->viewportDirty = SDL_TRUE; + data->currentRenderTargetView.ptr = 0; + + /* Release any upload buffers that were inflight */ + for (i = 0; i < data->currentUploadBuffer; ++i) { + SAFE_RELEASE(data->uploadBuffers[i]); + } + data->currentUploadBuffer = 0; + + D3D_CALL(data->commandList, SetDescriptorHeaps, 2, rootDescriptorHeaps); +} + +static int D3D12_IssueBatch(D3D12_RenderData *data) +{ + HRESULT result = S_OK; + + /* Issue the command list */ + result = D3D_CALL(data->commandList, Close); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("D3D12_IssueBatch"), result); + return result; + } + D3D_CALL(data->commandQueue, ExecuteCommandLists, 1, (ID3D12CommandList *const *)&data->commandList); + + D3D12_WaitForGPU(data); + + D3D12_ResetCommandList(data); + + return result; +} + +static void D3D12_DestroyRenderer(SDL_Renderer *renderer) +{ + D3D12_RenderData *data = (D3D12_RenderData *)renderer->driverdata; + D3D12_WaitForGPU(data); + D3D12_ReleaseAll(renderer); + if (data) { + SDL_free(data); + } + SDL_free(renderer); +} + +static int D3D12_GetOutputSize(SDL_Renderer *renderer, int *w, int *h) +{ + SDL_GetWindowSizeInPixels(renderer->window, w, h); + return 0; +} + +static D3D12_BLEND GetBlendFunc(SDL_BlendFactor factor) +{ + switch (factor) { + case SDL_BLENDFACTOR_ZERO: + return D3D12_BLEND_ZERO; + case SDL_BLENDFACTOR_ONE: + return D3D12_BLEND_ONE; + case SDL_BLENDFACTOR_SRC_COLOR: + return D3D12_BLEND_SRC_COLOR; + case SDL_BLENDFACTOR_ONE_MINUS_SRC_COLOR: + return D3D12_BLEND_INV_SRC_COLOR; + case SDL_BLENDFACTOR_SRC_ALPHA: + return D3D12_BLEND_SRC_ALPHA; + case SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA: + return D3D12_BLEND_INV_SRC_ALPHA; + case SDL_BLENDFACTOR_DST_COLOR: + return D3D12_BLEND_DEST_COLOR; + case SDL_BLENDFACTOR_ONE_MINUS_DST_COLOR: + return D3D12_BLEND_INV_DEST_COLOR; + case SDL_BLENDFACTOR_DST_ALPHA: + return D3D12_BLEND_DEST_ALPHA; + case SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA: + return D3D12_BLEND_INV_DEST_ALPHA; + default: + return (D3D12_BLEND)0; + } +} + +static D3D12_BLEND_OP GetBlendEquation(SDL_BlendOperation operation) +{ + switch (operation) { + case SDL_BLENDOPERATION_ADD: + return D3D12_BLEND_OP_ADD; + case SDL_BLENDOPERATION_SUBTRACT: + return D3D12_BLEND_OP_SUBTRACT; + case SDL_BLENDOPERATION_REV_SUBTRACT: + return D3D12_BLEND_OP_REV_SUBTRACT; + case SDL_BLENDOPERATION_MINIMUM: + return D3D12_BLEND_OP_MIN; + case SDL_BLENDOPERATION_MAXIMUM: + return D3D12_BLEND_OP_MAX; + default: + return (D3D12_BLEND_OP)0; + } +} + +static void D3D12_CreateBlendState(SDL_Renderer *renderer, SDL_BlendMode blendMode, D3D12_BLEND_DESC *outBlendDesc) +{ + SDL_BlendFactor srcColorFactor = SDL_GetBlendModeSrcColorFactor(blendMode); + SDL_BlendFactor srcAlphaFactor = SDL_GetBlendModeSrcAlphaFactor(blendMode); + SDL_BlendOperation colorOperation = SDL_GetBlendModeColorOperation(blendMode); + SDL_BlendFactor dstColorFactor = SDL_GetBlendModeDstColorFactor(blendMode); + SDL_BlendFactor dstAlphaFactor = SDL_GetBlendModeDstAlphaFactor(blendMode); + SDL_BlendOperation alphaOperation = SDL_GetBlendModeAlphaOperation(blendMode); + + SDL_zerop(outBlendDesc); + outBlendDesc->AlphaToCoverageEnable = FALSE; + outBlendDesc->IndependentBlendEnable = FALSE; + outBlendDesc->RenderTarget[0].BlendEnable = TRUE; + outBlendDesc->RenderTarget[0].SrcBlend = GetBlendFunc(srcColorFactor); + outBlendDesc->RenderTarget[0].DestBlend = GetBlendFunc(dstColorFactor); + outBlendDesc->RenderTarget[0].BlendOp = GetBlendEquation(colorOperation); + outBlendDesc->RenderTarget[0].SrcBlendAlpha = GetBlendFunc(srcAlphaFactor); + outBlendDesc->RenderTarget[0].DestBlendAlpha = GetBlendFunc(dstAlphaFactor); + outBlendDesc->RenderTarget[0].BlendOpAlpha = GetBlendEquation(alphaOperation); + outBlendDesc->RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL; +} + +static D3D12_PipelineState *D3D12_CreatePipelineState(SDL_Renderer *renderer, + D3D12_Shader shader, + SDL_BlendMode blendMode, + D3D12_PRIMITIVE_TOPOLOGY_TYPE topology, + DXGI_FORMAT rtvFormat) +{ + const D3D12_INPUT_ELEMENT_DESC vertexDesc[] = { + { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 16, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + }; + D3D12_RenderData *data = (D3D12_RenderData *)renderer->driverdata; + D3D12_GRAPHICS_PIPELINE_STATE_DESC pipelineDesc; + ID3D12PipelineState *pipelineState = NULL; + D3D12_PipelineState *pipelineStates; + HRESULT result = S_OK; + + SDL_zero(pipelineDesc); + pipelineDesc.pRootSignature = data->rootSignatures[D3D12_GetRootSignatureType(shader)]; + D3D12_GetVertexShader(shader, &pipelineDesc.VS); + D3D12_GetPixelShader(shader, &pipelineDesc.PS); + D3D12_CreateBlendState(renderer, blendMode, &pipelineDesc.BlendState); + pipelineDesc.SampleMask = 0xffffffff; + + pipelineDesc.RasterizerState.AntialiasedLineEnable = FALSE; + pipelineDesc.RasterizerState.CullMode = D3D12_CULL_MODE_NONE; + pipelineDesc.RasterizerState.DepthBias = 0; + pipelineDesc.RasterizerState.DepthBiasClamp = 0.0f; + pipelineDesc.RasterizerState.DepthClipEnable = TRUE; + pipelineDesc.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID; + pipelineDesc.RasterizerState.FrontCounterClockwise = FALSE; + pipelineDesc.RasterizerState.MultisampleEnable = FALSE; + pipelineDesc.RasterizerState.SlopeScaledDepthBias = 0.0f; + + pipelineDesc.InputLayout.pInputElementDescs = vertexDesc; + pipelineDesc.InputLayout.NumElements = 3; + + pipelineDesc.PrimitiveTopologyType = topology; + + pipelineDesc.NumRenderTargets = 1; + pipelineDesc.RTVFormats[0] = rtvFormat; + pipelineDesc.SampleDesc.Count = 1; + pipelineDesc.SampleDesc.Quality = 0; + + result = D3D_CALL(data->d3dDevice, CreateGraphicsPipelineState, + &pipelineDesc, + D3D_GUID(SDL_IID_ID3D12PipelineState), + (void **)&pipelineState); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D12Device::CreateGraphicsPipelineState"), result); + return NULL; + } + + pipelineStates = (D3D12_PipelineState *)SDL_realloc(data->pipelineStates, (data->pipelineStateCount + 1) * sizeof(*pipelineStates)); + if (!pipelineStates) { + SAFE_RELEASE(pipelineState); + SDL_OutOfMemory(); + return NULL; + } + + pipelineStates[data->pipelineStateCount].shader = shader; + pipelineStates[data->pipelineStateCount].blendMode = blendMode; + pipelineStates[data->pipelineStateCount].topology = topology; + pipelineStates[data->pipelineStateCount].rtvFormat = rtvFormat; + pipelineStates[data->pipelineStateCount].pipelineState = pipelineState; + data->pipelineStates = pipelineStates; + ++data->pipelineStateCount; + + return &pipelineStates[data->pipelineStateCount - 1]; +} + +static HRESULT D3D12_CreateVertexBuffer(D3D12_RenderData *data, size_t vbidx, size_t size) +{ + D3D12_HEAP_PROPERTIES vbufferHeapProps; + D3D12_RESOURCE_DESC vbufferDesc; + HRESULT result; + + SAFE_RELEASE(data->vertexBuffers[vbidx].resource); + + SDL_zero(vbufferHeapProps); + vbufferHeapProps.Type = D3D12_HEAP_TYPE_UPLOAD; + vbufferHeapProps.CreationNodeMask = 1; + vbufferHeapProps.VisibleNodeMask = 1; + + SDL_zero(vbufferDesc); + vbufferDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + vbufferDesc.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT; + vbufferDesc.Width = size; + vbufferDesc.Height = 1; + vbufferDesc.DepthOrArraySize = 1; + vbufferDesc.MipLevels = 1; + vbufferDesc.Format = DXGI_FORMAT_UNKNOWN; + vbufferDesc.SampleDesc.Count = 1; + vbufferDesc.SampleDesc.Quality = 0; + vbufferDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + vbufferDesc.Flags = D3D12_RESOURCE_FLAG_NONE; + + result = D3D_CALL(data->d3dDevice, CreateCommittedResource, + &vbufferHeapProps, + D3D12_HEAP_FLAG_NONE, + &vbufferDesc, + D3D12_RESOURCE_STATE_GENERIC_READ, + NULL, + D3D_GUID(SDL_IID_ID3D12Resource), + (void **)&data->vertexBuffers[vbidx].resource); + + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D12Device::CreatePlacedResource [vertex buffer]"), result); + return result; + } + + data->vertexBuffers[vbidx].view.BufferLocation = D3D_CALL(data->vertexBuffers[vbidx].resource, GetGPUVirtualAddress); + data->vertexBuffers[vbidx].view.StrideInBytes = sizeof(VertexPositionColor); + data->vertexBuffers[vbidx].size = size; + + return result; +} + +/* Create resources that depend on the device. */ +static HRESULT D3D12_CreateDeviceResources(SDL_Renderer *renderer) +{ +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + typedef HRESULT(WINAPI * PFN_CREATE_DXGI_FACTORY)(UINT flags, REFIID riid, void **ppFactory); + PFN_CREATE_DXGI_FACTORY CreateDXGIFactoryFunc; + PFN_D3D12_CREATE_DEVICE D3D12CreateDeviceFunc; +#endif + typedef HANDLE(WINAPI * PFN_CREATE_EVENT_EX)(LPSECURITY_ATTRIBUTES lpEventAttributes, LPCWSTR lpName, DWORD dwFlags, DWORD dwDesiredAccess); + PFN_CREATE_EVENT_EX CreateEventExFunc; + + D3D12_RenderData *data = (D3D12_RenderData *)renderer->driverdata; + ID3D12Device *d3dDevice = NULL; + HRESULT result = S_OK; + UINT creationFlags = 0; + int i, j, k, l; + SDL_bool createDebug = SDL_FALSE; + + D3D12_COMMAND_QUEUE_DESC queueDesc; + D3D12_DESCRIPTOR_HEAP_DESC descriptorHeapDesc; + D3D12_SAMPLER_DESC samplerDesc; + ID3D12DescriptorHeap *rootDescriptorHeaps[2]; + + const SDL_BlendMode defaultBlendModes[] = { + SDL_BLENDMODE_NONE, + SDL_BLENDMODE_BLEND, + SDL_BLENDMODE_ADD, + SDL_BLENDMODE_MOD, + SDL_BLENDMODE_MUL + }; + const DXGI_FORMAT defaultRTVFormats[] = { + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_B8G8R8X8_UNORM, + DXGI_FORMAT_R8_UNORM + }; + + /* See if we need debug interfaces */ + createDebug = SDL_GetHintBoolean(SDL_HINT_RENDER_DIRECT3D11_DEBUG, SDL_FALSE); + +#ifdef __GDK__ + CreateEventExFunc = CreateEventExW; +#else + /* CreateEventEx() arrived in Vista, so we need to load it with GetProcAddress for XP. */ + { + HMODULE kernel32 = GetModuleHandle(TEXT("kernel32.dll")); + CreateEventExFunc = NULL; + if (kernel32) { + CreateEventExFunc = (PFN_CREATE_EVENT_EX)GetProcAddress(kernel32, "CreateEventExW"); + } + } +#endif + if (!CreateEventExFunc) { + result = E_FAIL; + goto done; + } + +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + data->hDXGIMod = SDL_LoadObject("dxgi.dll"); + if (!data->hDXGIMod) { + result = E_FAIL; + goto done; + } + + CreateDXGIFactoryFunc = (PFN_CREATE_DXGI_FACTORY)SDL_LoadFunction(data->hDXGIMod, "CreateDXGIFactory2"); + if (!CreateDXGIFactoryFunc) { + result = E_FAIL; + goto done; + } + + data->hD3D12Mod = SDL_LoadObject("D3D12.dll"); + if (!data->hD3D12Mod) { + result = E_FAIL; + goto done; + } + + D3D12CreateDeviceFunc = (PFN_D3D12_CREATE_DEVICE)SDL_LoadFunction(data->hD3D12Mod, "D3D12CreateDevice"); + if (!D3D12CreateDeviceFunc) { + result = E_FAIL; + goto done; + } + + if (createDebug) { + PFN_D3D12_GET_DEBUG_INTERFACE D3D12GetDebugInterfaceFunc; + + D3D12GetDebugInterfaceFunc = (PFN_D3D12_GET_DEBUG_INTERFACE)SDL_LoadFunction(data->hD3D12Mod, "D3D12GetDebugInterface"); + if (!D3D12GetDebugInterfaceFunc) { + result = E_FAIL; + goto done; + } + D3D12GetDebugInterfaceFunc(D3D_GUID(SDL_IID_ID3D12Debug), (void **)&data->debugInterface); + D3D_CALL(data->debugInterface, EnableDebugLayer); + } +#endif /*!defined(__XBOXONE__) && !defined(__XBOXSERIES__)*/ + +#if defined(__XBOXONE__) || defined(__XBOXSERIES__) + result = D3D12_XBOX_CreateDevice(&d3dDevice, createDebug); + if (FAILED(result)) { + /* SDL Error is set by D3D12_XBOX_CreateDevice */ + goto done; + } +#else + if (createDebug) { +#ifdef __IDXGIInfoQueue_INTERFACE_DEFINED__ + IDXGIInfoQueue *dxgiInfoQueue = NULL; + PFN_CREATE_DXGI_FACTORY DXGIGetDebugInterfaceFunc; + + /* If the debug hint is set, also create the DXGI factory in debug mode */ + DXGIGetDebugInterfaceFunc = (PFN_CREATE_DXGI_FACTORY)SDL_LoadFunction(data->hDXGIMod, "DXGIGetDebugInterface1"); + if (!DXGIGetDebugInterfaceFunc) { + result = E_FAIL; + goto done; + } + + result = DXGIGetDebugInterfaceFunc(0, D3D_GUID(SDL_IID_IDXGIDebug1), (void **)&data->dxgiDebug); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("DXGIGetDebugInterface1"), result); + goto done; + } + + result = DXGIGetDebugInterfaceFunc(0, D3D_GUID(SDL_IID_IDXGIInfoQueue), (void **)&dxgiInfoQueue); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("DXGIGetDebugInterface1"), result); + goto done; + } + + D3D_CALL(dxgiInfoQueue, SetBreakOnSeverity, SDL_DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_ERROR, TRUE); + D3D_CALL(dxgiInfoQueue, SetBreakOnSeverity, SDL_DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_CORRUPTION, TRUE); + SAFE_RELEASE(dxgiInfoQueue); +#endif /* __IDXGIInfoQueue_INTERFACE_DEFINED__ */ + creationFlags = DXGI_CREATE_FACTORY_DEBUG; + } + + result = CreateDXGIFactoryFunc(creationFlags, D3D_GUID(SDL_IID_IDXGIFactory6), (void **)&data->dxgiFactory); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("CreateDXGIFactory"), result); + goto done; + } + + /* Prefer a high performance adapter if there are multiple choices */ + result = D3D_CALL(data->dxgiFactory, EnumAdapterByGpuPreference, + 0, + DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE, + D3D_GUID(SDL_IID_IDXGIAdapter4), + (void **)&data->dxgiAdapter); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("D3D12CreateDevice"), result); + goto done; + } + + result = D3D12CreateDeviceFunc((IUnknown *)data->dxgiAdapter, + D3D_FEATURE_LEVEL_11_0, /* Request minimum feature level 11.0 for maximum compatibility */ + D3D_GUID(SDL_IID_ID3D12Device1), + (void **)&d3dDevice); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("D3D12CreateDevice"), result); + goto done; + } + + /* Setup the info queue if in debug mode */ + if (createDebug) { + ID3D12InfoQueue *infoQueue = NULL; + D3D12_MESSAGE_SEVERITY severities[] = { D3D12_MESSAGE_SEVERITY_INFO }; + D3D12_INFO_QUEUE_FILTER filter; + + result = D3D_CALL(d3dDevice, QueryInterface, D3D_GUID(SDL_IID_ID3D12InfoQueue), (void **)&infoQueue); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D12Device to ID3D12InfoQueue"), result); + goto done; + } + + SDL_zero(filter); + filter.DenyList.NumSeverities = 1; + filter.DenyList.pSeverityList = severities; + D3D_CALL(infoQueue, PushStorageFilter, &filter); + + D3D_CALL(infoQueue, SetBreakOnSeverity, D3D12_MESSAGE_SEVERITY_ERROR, TRUE); + D3D_CALL(infoQueue, SetBreakOnSeverity, D3D12_MESSAGE_SEVERITY_CORRUPTION, TRUE); + + SAFE_RELEASE(infoQueue); + } +#endif /*!defined(__XBOXONE__) && !defined(__XBOXSERIES__)*/ + + result = D3D_CALL(d3dDevice, QueryInterface, D3D_GUID(SDL_IID_ID3D12Device1), (void **)&data->d3dDevice); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D12Device to ID3D12Device1"), result); + goto done; + } + + /* Create a command queue */ + SDL_zero(queueDesc); + queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; + queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; + + result = D3D_CALL(data->d3dDevice, CreateCommandQueue, + &queueDesc, + D3D_GUID(SDL_IID_ID3D12CommandQueue), + (void **)&data->commandQueue); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D12Device::CreateCommandQueue"), result); + goto done; + } + + /* Create the descriptor heaps for the render target view, texture SRVs, and samplers */ + SDL_zero(descriptorHeapDesc); + descriptorHeapDesc.NumDescriptors = SDL_D3D12_NUM_BUFFERS; + descriptorHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; + result = D3D_CALL(data->d3dDevice, CreateDescriptorHeap, + &descriptorHeapDesc, + D3D_GUID(SDL_IID_ID3D12DescriptorHeap), + (void **)&data->rtvDescriptorHeap); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D12Device::CreateDescriptorHeap [rtv]"), result); + goto done; + } + data->rtvDescriptorSize = D3D_CALL(d3dDevice, GetDescriptorHandleIncrementSize, D3D12_DESCRIPTOR_HEAP_TYPE_RTV); + + descriptorHeapDesc.NumDescriptors = SDL_D3D12_MAX_NUM_TEXTURES; + result = D3D_CALL(data->d3dDevice, CreateDescriptorHeap, + &descriptorHeapDesc, + D3D_GUID(SDL_IID_ID3D12DescriptorHeap), + (void **)&data->textureRTVDescriptorHeap); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D12Device::CreateDescriptorHeap [texture rtv]"), result); + goto done; + } + + SDL_zero(descriptorHeapDesc); + descriptorHeapDesc.NumDescriptors = SDL_D3D12_MAX_NUM_TEXTURES; + descriptorHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; + descriptorHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; + result = D3D_CALL(data->d3dDevice, CreateDescriptorHeap, + &descriptorHeapDesc, + D3D_GUID(SDL_IID_ID3D12DescriptorHeap), + (void **)&data->srvDescriptorHeap); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D12Device::CreateDescriptorHeap [srv]"), result); + goto done; + } + rootDescriptorHeaps[0] = data->srvDescriptorHeap; + data->srvDescriptorSize = D3D_CALL(d3dDevice, GetDescriptorHandleIncrementSize, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); + + SDL_zero(descriptorHeapDesc); + descriptorHeapDesc.NumDescriptors = 2; + descriptorHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER; + descriptorHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; + result = D3D_CALL(data->d3dDevice, CreateDescriptorHeap, + &descriptorHeapDesc, + D3D_GUID(SDL_IID_ID3D12DescriptorHeap), + (void **)&data->samplerDescriptorHeap); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D12Device::CreateDescriptorHeap [sampler]"), result); + goto done; + } + rootDescriptorHeaps[1] = data->samplerDescriptorHeap; + data->samplerDescriptorSize = D3D_CALL(d3dDevice, GetDescriptorHandleIncrementSize, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); + + /* Create a command allocator for each back buffer */ + for (i = 0; i < SDL_D3D12_NUM_BUFFERS; ++i) { + result = D3D_CALL(data->d3dDevice, CreateCommandAllocator, + D3D12_COMMAND_LIST_TYPE_DIRECT, + D3D_GUID(SDL_IID_ID3D12CommandAllocator), + (void **)&data->commandAllocators[i]); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D12Device::CreateCommandAllocator"), result); + goto done; + } + } + + /* Create the command list */ + result = D3D_CALL(data->d3dDevice, CreateCommandList, + 0, + D3D12_COMMAND_LIST_TYPE_DIRECT, + data->commandAllocators[0], + NULL, + D3D_GUID(SDL_IID_ID3D12GraphicsCommandList2), + (void **)&data->commandList); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D12Device::CreateCommandList"), result); + goto done; + } + + /* Set the descriptor heaps to the correct initial value */ + D3D_CALL(data->commandList, SetDescriptorHeaps, 2, rootDescriptorHeaps); + + /* Create the fence and fence event */ + result = D3D_CALL(data->d3dDevice, CreateFence, + data->fenceValue, + D3D12_FENCE_FLAG_NONE, + D3D_GUID(SDL_IID_ID3D12Fence), + (void **)&data->fence); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D12Device::CreateFence"), result); + goto done; + } + + data->fenceValue++; + + data->fenceEvent = CreateEventExFunc(NULL, NULL, 0, EVENT_MODIFY_STATE | SYNCHRONIZE); + if (!data->fenceEvent) { + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("CreateEventEx"), result); + goto done; + } + + /* Create all the root signatures */ + for (i = 0; i < NUM_ROOTSIGS; ++i) { + D3D12_SHADER_BYTECODE rootSigData; + D3D12_GetRootSignatureData((D3D12_RootSignature)i, &rootSigData); + result = D3D_CALL(data->d3dDevice, CreateRootSignature, + 0, + rootSigData.pShaderBytecode, + rootSigData.BytecodeLength, + D3D_GUID(SDL_IID_ID3D12RootSignature), + (void **)&data->rootSignatures[i]); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D12Device::CreateRootSignature"), result); + goto done; + } + } + + /* Create all the default pipeline state objects + (will add everything except custom blend states) */ + for (i = 0; i < NUM_SHADERS; ++i) { + for (j = 0; j < SDL_arraysize(defaultBlendModes); ++j) { + for (k = D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT; k < D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH; ++k) { + for (l = 0; l < SDL_arraysize(defaultRTVFormats); ++l) { + if (!D3D12_CreatePipelineState(renderer, (D3D12_Shader)i, defaultBlendModes[j], (D3D12_PRIMITIVE_TOPOLOGY_TYPE)k, defaultRTVFormats[l])) { + /* D3D12_CreatePipelineState will set the SDL error, if it fails */ + goto done; + } + } + } + } + } + + /* Create default vertex buffers */ + for (i = 0; i < SDL_D3D12_NUM_VERTEX_BUFFERS; ++i) { + D3D12_CreateVertexBuffer(data, i, D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT); + } + + /* Create samplers to use when drawing textures: */ + SDL_zero(samplerDesc); + samplerDesc.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT; + samplerDesc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; + samplerDesc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; + samplerDesc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP; + samplerDesc.MipLODBias = 0.0f; + samplerDesc.MaxAnisotropy = 1; + samplerDesc.ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS; + samplerDesc.MinLOD = 0.0f; + samplerDesc.MaxLOD = D3D12_FLOAT32_MAX; + D3D_CALL_RET_ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(data->samplerDescriptorHeap, &data->nearestPixelSampler); + D3D_CALL(data->d3dDevice, CreateSampler, &samplerDesc, data->nearestPixelSampler); + + samplerDesc.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR; + data->linearSampler.ptr = data->nearestPixelSampler.ptr + data->samplerDescriptorSize; + D3D_CALL(data->d3dDevice, CreateSampler, &samplerDesc, data->linearSampler); + + /* Initialize the pool allocator for SRVs */ + for (i = 0; i < SDL_D3D12_MAX_NUM_TEXTURES; ++i) { + data->srvPoolNodes[i].index = (SIZE_T)i; + if (i != SDL_D3D12_MAX_NUM_TEXTURES - 1) { + data->srvPoolNodes[i].next = &data->srvPoolNodes[i + 1]; + } + } + data->srvPoolHead = &data->srvPoolNodes[0]; +done: + SAFE_RELEASE(d3dDevice); + return result; +} + +static DXGI_MODE_ROTATION D3D12_GetCurrentRotation() +{ + /* FIXME */ + return DXGI_MODE_ROTATION_IDENTITY; +} + +static BOOL D3D12_IsDisplayRotated90Degrees(DXGI_MODE_ROTATION rotation) +{ + switch (rotation) { + case DXGI_MODE_ROTATION_ROTATE90: + case DXGI_MODE_ROTATION_ROTATE270: + return TRUE; + default: + return FALSE; + } +} + +static int D3D12_GetRotationForCurrentRenderTarget(SDL_Renderer *renderer) +{ + D3D12_RenderData *data = (D3D12_RenderData *)renderer->driverdata; + if (data->textureRenderTarget) { + return DXGI_MODE_ROTATION_IDENTITY; + } else { + return data->rotation; + } +} + +static int D3D12_GetViewportAlignedD3DRect(SDL_Renderer *renderer, const SDL_Rect *sdlRect, D3D12_RECT *outRect, BOOL includeViewportOffset) +{ + D3D12_RenderData *data = (D3D12_RenderData *)renderer->driverdata; + const int rotation = D3D12_GetRotationForCurrentRenderTarget(renderer); + const SDL_Rect *viewport = &data->currentViewport; + + switch (rotation) { + case DXGI_MODE_ROTATION_IDENTITY: + outRect->left = sdlRect->x; + outRect->right = (LONG)sdlRect->x + sdlRect->w; + outRect->top = sdlRect->y; + outRect->bottom = (LONG)sdlRect->y + sdlRect->h; + if (includeViewportOffset) { + outRect->left += viewport->x; + outRect->right += viewport->x; + outRect->top += viewport->y; + outRect->bottom += viewport->y; + } + break; + case DXGI_MODE_ROTATION_ROTATE270: + outRect->left = sdlRect->y; + outRect->right = (LONG)sdlRect->y + sdlRect->h; + outRect->top = viewport->w - sdlRect->x - sdlRect->w; + outRect->bottom = viewport->w - sdlRect->x; + break; + case DXGI_MODE_ROTATION_ROTATE180: + outRect->left = viewport->w - sdlRect->x - sdlRect->w; + outRect->right = viewport->w - sdlRect->x; + outRect->top = viewport->h - sdlRect->y - sdlRect->h; + outRect->bottom = viewport->h - sdlRect->y; + break; + case DXGI_MODE_ROTATION_ROTATE90: + outRect->left = viewport->h - sdlRect->y - sdlRect->h; + outRect->right = viewport->h - sdlRect->y; + outRect->top = sdlRect->x; + outRect->bottom = (LONG)sdlRect->x + sdlRect->h; + break; + default: + return SDL_SetError("The physical display is in an unknown or unsupported rotation"); + } + return 0; +} + +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) +static HRESULT D3D12_CreateSwapChain(SDL_Renderer *renderer, int w, int h) +{ + D3D12_RenderData *data = (D3D12_RenderData *)renderer->driverdata; + IDXGISwapChain1* swapChain = NULL; + HRESULT result = S_OK; + SDL_SysWMinfo windowinfo; + + /* Create a swap chain using the same adapter as the existing Direct3D device. */ + DXGI_SWAP_CHAIN_DESC1 swapChainDesc; + SDL_zero(swapChainDesc); + swapChainDesc.Width = w; + swapChainDesc.Height = h; + swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; /* This is the most common swap chain format. */ + swapChainDesc.Stereo = FALSE; + swapChainDesc.SampleDesc.Count = 1; /* Don't use multi-sampling. */ + swapChainDesc.SampleDesc.Quality = 0; + swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swapChainDesc.BufferCount = 2; /* Use double-buffering to minimize latency. */ + if (WIN_IsWindows8OrGreater()) { + swapChainDesc.Scaling = DXGI_SCALING_NONE; + } else { + swapChainDesc.Scaling = DXGI_SCALING_STRETCH; + } + swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; /* All Windows Store apps must use this SwapEffect. */ + swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT | /* To support SetMaximumFrameLatency */ + DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING; /* To support presenting with allow tearing on */ + + SDL_VERSION(&windowinfo.version); + if (!SDL_GetWindowWMInfo(renderer->window, &windowinfo) || + windowinfo.subsystem != SDL_SYSWM_WINDOWS) + { + SDL_SetError("Couldn't get window handle"); + result = E_FAIL; + goto done; + } + + result = D3D_CALL(data->dxgiFactory, CreateSwapChainForHwnd, + (IUnknown *)data->commandQueue, + windowinfo.info.win.window, + &swapChainDesc, + NULL, + NULL, /* Allow on all displays. */ + &swapChain); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGIFactory2::CreateSwapChainForHwnd"), result); + goto done; + } + + D3D_CALL(data->dxgiFactory, MakeWindowAssociation, windowinfo.info.win.window, DXGI_MWA_NO_WINDOW_CHANGES); + + result = D3D_CALL(swapChain, QueryInterface, D3D_GUID(SDL_IID_IDXGISwapChain4), (void **)&data->swapChain); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGISwapChain1::QueryInterface"), result); + goto done; + } + + /* Ensure that the swapchain does not queue more than one frame at a time. This both reduces latency + * and ensures that the application will only render after each VSync, minimizing power consumption. + */ + result = D3D_CALL(data->swapChain, SetMaximumFrameLatency, 1); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGISwapChain4::SetMaximumFrameLatency"), result); + goto done; + } + + data->swapEffect = swapChainDesc.SwapEffect; + data->swapFlags = swapChainDesc.Flags; + +done: + SAFE_RELEASE(swapChain); + return result; +} +#endif + +static HRESULT D3D12_UpdateForWindowSizeChange(SDL_Renderer *renderer); + +HRESULT +D3D12_HandleDeviceLost(SDL_Renderer *renderer) +{ + HRESULT result = S_OK; + + D3D12_ReleaseAll(renderer); + + result = D3D12_CreateDeviceResources(renderer); + if (FAILED(result)) { + /* D3D12_CreateDeviceResources will set the SDL error */ + return result; + } + + result = D3D12_UpdateForWindowSizeChange(renderer); + if (FAILED(result)) { + /* D3D12_UpdateForWindowSizeChange will set the SDL error */ + return result; + } + + /* Let the application know that the device has been reset */ + { + SDL_Event event; + event.type = SDL_RENDER_DEVICE_RESET; + SDL_PushEvent(&event); + } + + return S_OK; +} + +/* Initialize all resources that change when the window's size changes. */ +static HRESULT D3D12_CreateWindowSizeDependentResources(SDL_Renderer *renderer) +{ + D3D12_RenderData *data = (D3D12_RenderData *)renderer->driverdata; + HRESULT result = S_OK; + int i, w, h; + + D3D12_RENDER_TARGET_VIEW_DESC rtvDesc; + D3D12_CPU_DESCRIPTOR_HANDLE rtvDescriptor; + + /* Release resources in the current command list */ + D3D12_IssueBatch(data); + D3D_CALL(data->commandList, OMSetRenderTargets, 0, NULL, FALSE, NULL); + + /* Release render targets */ + for (i = 0; i < SDL_D3D12_NUM_BUFFERS; ++i) { + SAFE_RELEASE(data->renderTargets[i]); + } + + /* The width and height of the swap chain must be based on the display's + * non-rotated size. + */ + SDL_GetWindowSizeInPixels(renderer->window, &w, &h); + data->rotation = D3D12_GetCurrentRotation(); + if (D3D12_IsDisplayRotated90Degrees(data->rotation)) { + int tmp = w; + w = h; + h = tmp; + } + +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + if (data->swapChain) { + /* If the swap chain already exists, resize it. */ + result = D3D_CALL(data->swapChain, ResizeBuffers, + 0, + w, h, + DXGI_FORMAT_UNKNOWN, + data->swapFlags); + if (result == DXGI_ERROR_DEVICE_REMOVED) { + /* If the device was removed for any reason, a new device and swap chain will need to be created. */ + D3D12_HandleDeviceLost(renderer); + + /* Everything is set up now. Do not continue execution of this method. HandleDeviceLost will reenter this method + * and correctly set up the new device. + */ + goto done; + } else if (FAILED(result)) { + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGISwapChain::ResizeBuffers"), result); + goto done; + } + } else { + result = D3D12_CreateSwapChain(renderer, w, h); + if (FAILED(result)) { + goto done; + } + } + + /* Set the proper rotation for the swap chain. */ + if (WIN_IsWindows8OrGreater()) { + if (data->swapEffect == DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL) { + result = D3D_CALL(data->swapChain, SetRotation, data->rotation); /* NOLINT(clang-analyzer-core.NullDereference) */ + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGISwapChain4::SetRotation"), result); + goto done; + } + } + } +#endif /*!defined(__XBOXONE__) && !defined(__XBOXSERIES__)*/ + + /* Get each back buffer render target and create render target views */ + for (i = 0; i < SDL_D3D12_NUM_BUFFERS; ++i) { +#if defined(__XBOXONE__) || defined(__XBOXSERIES__) + result = D3D12_XBOX_CreateBackBufferTarget(data->d3dDevice, renderer->window->w, renderer->window->h, (void **)&data->renderTargets[i]); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("D3D12_XBOX_CreateBackBufferTarget"), result); + goto done; + } +#else + result = D3D_CALL(data->swapChain, GetBuffer, /* NOLINT(clang-analyzer-core.NullDereference) */ + i, + D3D_GUID(SDL_IID_ID3D12Resource), + (void **)&data->renderTargets[i]); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGISwapChain4::GetBuffer"), result); + goto done; + } +#endif + + SDL_zero(rtvDesc); + rtvDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; + rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; + + SDL_zero(rtvDescriptor); + D3D_CALL_RET_ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(data->rtvDescriptorHeap, &rtvDescriptor); + rtvDescriptor.ptr += i * data->rtvDescriptorSize; + D3D_CALL(data->d3dDevice, CreateRenderTargetView, data->renderTargets[i], &rtvDesc, rtvDescriptor); + } + + /* Set back buffer index to current buffer */ +#if defined(__XBOXONE__) || defined(__XBOXSERIES__) + data->currentBackBufferIndex = 0; +#else + data->currentBackBufferIndex = D3D_CALL(data->swapChain, GetCurrentBackBufferIndex); +#endif + + /* Set the swap chain target immediately, so that a target is always set + * even before we get to SetDrawState. Without this it's possible to hit + * null references in places like ReadPixels! + */ + data->currentRenderTargetView = D3D12_GetCurrentRenderTargetView(renderer); + D3D_CALL(data->commandList, OMSetRenderTargets, 1, &data->currentRenderTargetView, FALSE, NULL); + D3D12_TransitionResource(data, + data->renderTargets[data->currentBackBufferIndex], + D3D12_RESOURCE_STATE_PRESENT, + D3D12_RESOURCE_STATE_RENDER_TARGET); + + data->viewportDirty = SDL_TRUE; + +#if defined(__XBOXONE__) || defined(__XBOXSERIES__) + D3D12_XBOX_StartFrame(data->d3dDevice, &data->frameToken); +#endif + +done: + return result; +} + +/* This method is called when the window's size changes. */ +static HRESULT D3D12_UpdateForWindowSizeChange(SDL_Renderer *renderer) +{ + D3D12_RenderData *data = (D3D12_RenderData *)renderer->driverdata; + /* If the GPU has previous work, wait for it to be done first */ + D3D12_WaitForGPU(data); + return D3D12_CreateWindowSizeDependentResources(renderer); +} + +static void D3D12_WindowEvent(SDL_Renderer *renderer, const SDL_WindowEvent *event) +{ + if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED) { + D3D12_UpdateForWindowSizeChange(renderer); + } +} + +static SDL_bool D3D12_SupportsBlendMode(SDL_Renderer *renderer, SDL_BlendMode blendMode) +{ + SDL_BlendFactor srcColorFactor = SDL_GetBlendModeSrcColorFactor(blendMode); + SDL_BlendFactor srcAlphaFactor = SDL_GetBlendModeSrcAlphaFactor(blendMode); + SDL_BlendOperation colorOperation = SDL_GetBlendModeColorOperation(blendMode); + SDL_BlendFactor dstColorFactor = SDL_GetBlendModeDstColorFactor(blendMode); + SDL_BlendFactor dstAlphaFactor = SDL_GetBlendModeDstAlphaFactor(blendMode); + SDL_BlendOperation alphaOperation = SDL_GetBlendModeAlphaOperation(blendMode); + + if (!GetBlendFunc(srcColorFactor) || !GetBlendFunc(srcAlphaFactor) || + !GetBlendEquation(colorOperation) || + !GetBlendFunc(dstColorFactor) || !GetBlendFunc(dstAlphaFactor) || + !GetBlendEquation(alphaOperation)) { + return SDL_FALSE; + } + return SDL_TRUE; +} + +static SIZE_T D3D12_GetAvailableSRVIndex(SDL_Renderer *renderer) +{ + D3D12_RenderData *rendererData = (D3D12_RenderData *)renderer->driverdata; + if (rendererData->srvPoolHead) { + SIZE_T index = rendererData->srvPoolHead->index; + rendererData->srvPoolHead = (D3D12_SRVPoolNode *)(rendererData->srvPoolHead->next); + return index; + } else { + SDL_SetError("[d3d12] Cannot allocate more than %d textures!", SDL_D3D12_MAX_NUM_TEXTURES); + return SDL_D3D12_MAX_NUM_TEXTURES + 1; + } +} + +static void D3D12_FreeSRVIndex(SDL_Renderer *renderer, SIZE_T index) +{ + D3D12_RenderData *rendererData = (D3D12_RenderData *)renderer->driverdata; + rendererData->srvPoolNodes[index].next = rendererData->srvPoolHead; + rendererData->srvPoolHead = &rendererData->srvPoolNodes[index]; +} + +static int D3D12_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) +{ + D3D12_RenderData *rendererData = (D3D12_RenderData *)renderer->driverdata; + D3D12_TextureData *textureData; + HRESULT result; + DXGI_FORMAT textureFormat = SDLPixelFormatToDXGIFormat(texture->format); + D3D12_RESOURCE_DESC textureDesc; + D3D12_HEAP_PROPERTIES heapProps; + D3D12_SHADER_RESOURCE_VIEW_DESC resourceViewDesc; + + if (textureFormat == DXGI_FORMAT_UNKNOWN) { + return SDL_SetError("%s, An unsupported SDL pixel format (0x%x) was specified", __FUNCTION__, texture->format); + } + + textureData = (D3D12_TextureData *)SDL_calloc(1, sizeof(*textureData)); + if (!textureData) { + SDL_OutOfMemory(); + return -1; + } + textureData->scaleMode = (texture->scaleMode == SDL_ScaleModeNearest) ? D3D12_FILTER_MIN_MAG_MIP_POINT : D3D12_FILTER_MIN_MAG_MIP_LINEAR; + + texture->driverdata = textureData; + textureData->mainTextureFormat = textureFormat; + + SDL_zero(textureDesc); + textureDesc.Width = texture->w; + textureDesc.Height = texture->h; + textureDesc.MipLevels = 1; + textureDesc.DepthOrArraySize = 1; + textureDesc.Format = textureFormat; + textureDesc.SampleDesc.Count = 1; + textureDesc.SampleDesc.Quality = 0; + textureDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + textureDesc.Flags = D3D12_RESOURCE_FLAG_NONE; + + if (texture->access == SDL_TEXTUREACCESS_TARGET) { + textureDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; + } + + SDL_zero(heapProps); + heapProps.Type = D3D12_HEAP_TYPE_DEFAULT; + heapProps.CreationNodeMask = 1; + heapProps.VisibleNodeMask = 1; + + result = D3D_CALL(rendererData->d3dDevice, CreateCommittedResource, + &heapProps, + D3D12_HEAP_FLAG_NONE, + &textureDesc, + D3D12_RESOURCE_STATE_COPY_DEST, + NULL, + D3D_GUID(SDL_IID_ID3D12Resource), + (void **)&textureData->mainTexture); + textureData->mainResourceState = D3D12_RESOURCE_STATE_COPY_DEST; + if (FAILED(result)) { + D3D12_DestroyTexture(renderer, texture); + return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D12Device::CreateCommittedResource [texture]"), result); + } +#if SDL_HAVE_YUV + if (texture->format == SDL_PIXELFORMAT_YV12 || + texture->format == SDL_PIXELFORMAT_IYUV) { + textureData->yuv = SDL_TRUE; + + textureDesc.Width = (textureDesc.Width + 1) / 2; + textureDesc.Height = (textureDesc.Height + 1) / 2; + + result = D3D_CALL(rendererData->d3dDevice, CreateCommittedResource, + &heapProps, + D3D12_HEAP_FLAG_NONE, + &textureDesc, + D3D12_RESOURCE_STATE_COPY_DEST, + NULL, + D3D_GUID(SDL_IID_ID3D12Resource), + (void **)&textureData->mainTextureU); + textureData->mainResourceStateU = D3D12_RESOURCE_STATE_COPY_DEST; + if (FAILED(result)) { + D3D12_DestroyTexture(renderer, texture); + return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D12Device::CreateCommittedResource [texture]"), result); + } + + result = D3D_CALL(rendererData->d3dDevice, CreateCommittedResource, + &heapProps, + D3D12_HEAP_FLAG_NONE, + &textureDesc, + D3D12_RESOURCE_STATE_COPY_DEST, + NULL, + D3D_GUID(SDL_IID_ID3D12Resource), + (void **)&textureData->mainTextureV); + textureData->mainResourceStateV = D3D12_RESOURCE_STATE_COPY_DEST; + if (FAILED(result)) { + D3D12_DestroyTexture(renderer, texture); + return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D12Device::CreateCommittedResource [texture]"), result); + } + } + + if (texture->format == SDL_PIXELFORMAT_NV12 || + texture->format == SDL_PIXELFORMAT_NV21) { + D3D12_RESOURCE_DESC nvTextureDesc = textureDesc; + + textureData->nv12 = SDL_TRUE; + + nvTextureDesc.Format = DXGI_FORMAT_R8G8_UNORM; + nvTextureDesc.Width = (textureDesc.Width + 1) / 2; + nvTextureDesc.Height = (textureDesc.Height + 1) / 2; + + result = D3D_CALL(rendererData->d3dDevice, CreateCommittedResource, + &heapProps, + D3D12_HEAP_FLAG_NONE, + &nvTextureDesc, + D3D12_RESOURCE_STATE_COPY_DEST, + NULL, + D3D_GUID(SDL_IID_ID3D12Resource), + (void **)&textureData->mainTextureNV); + textureData->mainResourceStateNV = D3D12_RESOURCE_STATE_COPY_DEST; + if (FAILED(result)) { + D3D12_DestroyTexture(renderer, texture); + return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D12Device::CreateTexture2D"), result); + } + } +#endif /* SDL_HAVE_YUV */ + SDL_zero(resourceViewDesc); + resourceViewDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + resourceViewDesc.Format = textureDesc.Format; + resourceViewDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; + resourceViewDesc.Texture2D.MostDetailedMip = 0; + resourceViewDesc.Texture2D.MipLevels = textureDesc.MipLevels; + + textureData->mainSRVIndex = D3D12_GetAvailableSRVIndex(renderer); + D3D_CALL_RET_ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(rendererData->srvDescriptorHeap, &textureData->mainTextureResourceView); + textureData->mainTextureResourceView.ptr += textureData->mainSRVIndex * rendererData->srvDescriptorSize; + + D3D_CALL(rendererData->d3dDevice, CreateShaderResourceView, + textureData->mainTexture, + &resourceViewDesc, + textureData->mainTextureResourceView); +#if SDL_HAVE_YUV + if (textureData->yuv) { + D3D_CALL_RET_ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(rendererData->srvDescriptorHeap, &textureData->mainTextureResourceViewU); + textureData->mainSRVIndexU = D3D12_GetAvailableSRVIndex(renderer); + textureData->mainTextureResourceViewU.ptr += textureData->mainSRVIndexU * rendererData->srvDescriptorSize; + D3D_CALL(rendererData->d3dDevice, CreateShaderResourceView, + textureData->mainTextureU, + &resourceViewDesc, + textureData->mainTextureResourceViewU); + + D3D_CALL_RET_ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(rendererData->srvDescriptorHeap, &textureData->mainTextureResourceViewV); + textureData->mainSRVIndexV = D3D12_GetAvailableSRVIndex(renderer); + textureData->mainTextureResourceViewV.ptr += textureData->mainSRVIndexV * rendererData->srvDescriptorSize; + D3D_CALL(rendererData->d3dDevice, CreateShaderResourceView, + textureData->mainTextureV, + &resourceViewDesc, + textureData->mainTextureResourceViewV); + } + + if (textureData->nv12) { + D3D12_SHADER_RESOURCE_VIEW_DESC nvResourceViewDesc = resourceViewDesc; + + nvResourceViewDesc.Format = DXGI_FORMAT_R8G8_UNORM; + + D3D_CALL_RET_ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(rendererData->srvDescriptorHeap, &textureData->mainTextureResourceViewNV); + textureData->mainSRVIndexNV = D3D12_GetAvailableSRVIndex(renderer); + textureData->mainTextureResourceViewNV.ptr += textureData->mainSRVIndexNV * rendererData->srvDescriptorSize; + D3D_CALL(rendererData->d3dDevice, CreateShaderResourceView, + textureData->mainTextureNV, + &nvResourceViewDesc, + textureData->mainTextureResourceViewNV); + } +#endif /* SDL_HAVE_YUV */ + + if (texture->access & SDL_TEXTUREACCESS_TARGET) { + D3D12_RENDER_TARGET_VIEW_DESC renderTargetViewDesc; + SDL_zero(renderTargetViewDesc); + renderTargetViewDesc.Format = textureDesc.Format; + renderTargetViewDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; + renderTargetViewDesc.Texture2D.MipSlice = 0; + + D3D_CALL_RET_ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(rendererData->textureRTVDescriptorHeap, &textureData->mainTextureRenderTargetView); + textureData->mainTextureRenderTargetView.ptr += textureData->mainSRVIndex * rendererData->rtvDescriptorSize; + + D3D_CALL(rendererData->d3dDevice, CreateRenderTargetView, + (ID3D12Resource *)textureData->mainTexture, + &renderTargetViewDesc, + textureData->mainTextureRenderTargetView); + } + + return 0; +} + +static void D3D12_DestroyTexture(SDL_Renderer *renderer, + SDL_Texture *texture) +{ + D3D12_RenderData *rendererData = (D3D12_RenderData *)renderer->driverdata; + D3D12_TextureData *textureData = (D3D12_TextureData *)texture->driverdata; + + if (!textureData) { + return; + } + + /* Because SDL_DestroyTexture might be called while the data is in-flight, we need to issue the batch first + Unfortunately, this means that deleting a lot of textures mid-frame will have poor performance. */ + D3D12_IssueBatch(rendererData); + + SAFE_RELEASE(textureData->mainTexture); + SAFE_RELEASE(textureData->stagingBuffer); + D3D12_FreeSRVIndex(renderer, textureData->mainSRVIndex); +#if SDL_HAVE_YUV + SAFE_RELEASE(textureData->mainTextureU); + SAFE_RELEASE(textureData->mainTextureV); + if (textureData->yuv) { + D3D12_FreeSRVIndex(renderer, textureData->mainSRVIndexU); + D3D12_FreeSRVIndex(renderer, textureData->mainSRVIndexV); + } + SAFE_RELEASE(textureData->mainTextureNV); + if (textureData->yuv) { + D3D12_FreeSRVIndex(renderer, textureData->mainSRVIndexNV); + } + SDL_free(textureData->pixels); +#endif + SDL_free(textureData); + texture->driverdata = NULL; +} + +static int D3D12_UpdateTextureInternal(D3D12_RenderData *rendererData, ID3D12Resource *texture, int bpp, int x, int y, int w, int h, const void *pixels, int pitch, D3D12_RESOURCE_STATES *resourceState) +{ + const Uint8 *src; + Uint8 *dst; + int row; + UINT length; + HRESULT result; + D3D12_RESOURCE_DESC textureDesc; + D3D12_RESOURCE_DESC uploadDesc; + D3D12_HEAP_PROPERTIES heapProps; + D3D12_SUBRESOURCE_FOOTPRINT pitchedDesc; + D3D12_PLACED_SUBRESOURCE_FOOTPRINT placedTextureDesc; + D3D12_TEXTURE_COPY_LOCATION srcLocation; + D3D12_TEXTURE_COPY_LOCATION dstLocation; + BYTE *textureMemory; + ID3D12Resource *uploadBuffer; + + /* Create an upload buffer, which will be used to write to the main texture. */ + SDL_zero(textureDesc); + D3D_CALL_RET_ID3D12Resource_GetDesc(texture, &textureDesc); + textureDesc.Width = w; + textureDesc.Height = h; + + SDL_zero(uploadDesc); + uploadDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + uploadDesc.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT; + uploadDesc.Height = 1; + uploadDesc.DepthOrArraySize = 1; + uploadDesc.MipLevels = 1; + uploadDesc.Format = DXGI_FORMAT_UNKNOWN; + uploadDesc.SampleDesc.Count = 1; + uploadDesc.SampleDesc.Quality = 0; + uploadDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + uploadDesc.Flags = D3D12_RESOURCE_FLAG_NONE; + + /* Figure out how much we need to allocate for the upload buffer */ + D3D_CALL(rendererData->d3dDevice, GetCopyableFootprints, + &textureDesc, + 0, + 1, + 0, + NULL, + NULL, + NULL, + &uploadDesc.Width); + + SDL_zero(heapProps); + heapProps.Type = D3D12_HEAP_TYPE_UPLOAD; + heapProps.CreationNodeMask = 1; + heapProps.VisibleNodeMask = 1; + + /* Create the upload buffer */ + result = D3D_CALL(rendererData->d3dDevice, CreateCommittedResource, + &heapProps, + D3D12_HEAP_FLAG_NONE, + &uploadDesc, + D3D12_RESOURCE_STATE_GENERIC_READ, + NULL, + D3D_GUID(SDL_IID_ID3D12Resource), + (void **)&rendererData->uploadBuffers[rendererData->currentUploadBuffer]); + if (FAILED(result)) { + return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D12Device::CreateCommittedResource [create upload buffer]"), result); + } + + /* Get a write-only pointer to data in the upload buffer: */ + uploadBuffer = rendererData->uploadBuffers[rendererData->currentUploadBuffer]; + result = D3D_CALL(uploadBuffer, Map, + 0, + NULL, + (void **)&textureMemory); + if (FAILED(result)) { + SAFE_RELEASE(rendererData->uploadBuffers[rendererData->currentUploadBuffer]); + return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D12Resource::Map [map staging texture]"), result); + } + + SDL_zero(pitchedDesc); + pitchedDesc.Format = textureDesc.Format; + pitchedDesc.Width = w; + pitchedDesc.Height = h; + pitchedDesc.Depth = 1; + pitchedDesc.RowPitch = D3D12_Align(w * bpp, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT); + + SDL_zero(placedTextureDesc); + placedTextureDesc.Offset = 0; + placedTextureDesc.Footprint = pitchedDesc; + + src = (const Uint8 *)pixels; + dst = textureMemory; + length = w * bpp; + if (length == pitch && length == pitchedDesc.RowPitch) { + SDL_memcpy(dst, src, (size_t)length * h); + } else { + if (length > (UINT)pitch) { + length = pitch; + } + if (length > pitchedDesc.RowPitch) { + length = pitchedDesc.RowPitch; + } + for (row = 0; row < h; ++row) { + SDL_memcpy(dst, src, length); + src += pitch; + dst += pitchedDesc.RowPitch; + } + } + + /* Commit the changes back to the upload buffer: */ + D3D_CALL(uploadBuffer, Unmap, 0, NULL); + + /* Make sure the destination is in the correct resource state */ + D3D12_TransitionResource(rendererData, texture, *resourceState, D3D12_RESOURCE_STATE_COPY_DEST); + *resourceState = D3D12_RESOURCE_STATE_COPY_DEST; + + SDL_zero(dstLocation); + dstLocation.pResource = texture; + dstLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + dstLocation.SubresourceIndex = 0; + + SDL_zero(srcLocation); + srcLocation.pResource = rendererData->uploadBuffers[rendererData->currentUploadBuffer]; + srcLocation.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + srcLocation.PlacedFootprint = placedTextureDesc; + + D3D_CALL(rendererData->commandList, CopyTextureRegion, + &dstLocation, + x, + y, + 0, + &srcLocation, + NULL); + + /* Transition the texture to be shader accessible */ + D3D12_TransitionResource(rendererData, texture, *resourceState, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); + *resourceState = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; + + rendererData->currentUploadBuffer++; + /* If we've used up all the upload buffers, we need to issue the batch */ + if (rendererData->currentUploadBuffer == SDL_D3D12_NUM_UPLOAD_BUFFERS) { + D3D12_IssueBatch(rendererData); + } + + return 0; +} + +static int D3D12_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *rect, const void *srcPixels, + int srcPitch) +{ + D3D12_RenderData *rendererData = (D3D12_RenderData *)renderer->driverdata; + D3D12_TextureData *textureData = (D3D12_TextureData *)texture->driverdata; + + if (!textureData) { + return SDL_SetError("Texture is not currently available"); + } + + if (D3D12_UpdateTextureInternal(rendererData, textureData->mainTexture, SDL_BYTESPERPIXEL(texture->format), rect->x, rect->y, rect->w, rect->h, srcPixels, srcPitch, &textureData->mainResourceState) < 0) { + return -1; + } +#if SDL_HAVE_YUV + if (textureData->yuv) { + /* Skip to the correct offset into the next texture */ + srcPixels = (const void *)((const Uint8 *)srcPixels + rect->h * srcPitch); + + if (D3D12_UpdateTextureInternal(rendererData, texture->format == SDL_PIXELFORMAT_YV12 ? textureData->mainTextureV : textureData->mainTextureU, SDL_BYTESPERPIXEL(texture->format), rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2, srcPixels, (srcPitch + 1) / 2, texture->format == SDL_PIXELFORMAT_YV12 ? &textureData->mainResourceStateV : &textureData->mainResourceStateU) < 0) { + return -1; + } + + /* Skip to the correct offset into the next texture */ + srcPixels = (const void *)((const Uint8 *)srcPixels + ((rect->h + 1) / 2) * ((srcPitch + 1) / 2)); + if (D3D12_UpdateTextureInternal(rendererData, texture->format == SDL_PIXELFORMAT_YV12 ? textureData->mainTextureU : textureData->mainTextureV, SDL_BYTESPERPIXEL(texture->format), rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2, srcPixels, (srcPitch + 1) / 2, texture->format == SDL_PIXELFORMAT_YV12 ? &textureData->mainResourceStateU : &textureData->mainResourceStateV) < 0) { + return -1; + } + } + + if (textureData->nv12) { + /* Skip to the correct offset into the next texture */ + srcPixels = (const void *)((const Uint8 *)srcPixels + rect->h * srcPitch); + + if (D3D12_UpdateTextureInternal(rendererData, textureData->mainTextureNV, 2, rect->x / 2, rect->y / 2, ((rect->w + 1) / 2), (rect->h + 1) / 2, srcPixels, 2 * ((srcPitch + 1) / 2), &textureData->mainResourceStateNV) < 0) { + return -1; + } + } +#endif /* SDL_HAVE_YUV */ + return 0; +} + +#if SDL_HAVE_YUV +static int D3D12_UpdateTextureYUV(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *Uplane, int Upitch, + const Uint8 *Vplane, int Vpitch) +{ + D3D12_RenderData *rendererData = (D3D12_RenderData *)renderer->driverdata; + D3D12_TextureData *textureData = (D3D12_TextureData *)texture->driverdata; + + if (!textureData) { + return SDL_SetError("Texture is not currently available"); + } + + if (D3D12_UpdateTextureInternal(rendererData, textureData->mainTexture, SDL_BYTESPERPIXEL(texture->format), rect->x, rect->y, rect->w, rect->h, Yplane, Ypitch, &textureData->mainResourceState) < 0) { + return -1; + } + if (D3D12_UpdateTextureInternal(rendererData, textureData->mainTextureU, SDL_BYTESPERPIXEL(texture->format), rect->x / 2, rect->y / 2, rect->w / 2, rect->h / 2, Uplane, Upitch, &textureData->mainResourceStateU) < 0) { + return -1; + } + if (D3D12_UpdateTextureInternal(rendererData, textureData->mainTextureV, SDL_BYTESPERPIXEL(texture->format), rect->x / 2, rect->y / 2, rect->w / 2, rect->h / 2, Vplane, Vpitch, &textureData->mainResourceStateV) < 0) { + return -1; + } + return 0; +} + +static int D3D12_UpdateTextureNV(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *UVplane, int UVpitch) +{ + D3D12_RenderData *rendererData = (D3D12_RenderData *)renderer->driverdata; + D3D12_TextureData *textureData = (D3D12_TextureData *)texture->driverdata; + + if (!textureData) { + return SDL_SetError("Texture is not currently available"); + } + + if (D3D12_UpdateTextureInternal(rendererData, textureData->mainTexture, SDL_BYTESPERPIXEL(texture->format), rect->x, rect->y, rect->w, rect->h, Yplane, Ypitch, &textureData->mainResourceState) < 0) { + return -1; + } + + if (D3D12_UpdateTextureInternal(rendererData, textureData->mainTextureNV, 2, rect->x / 2, rect->y / 2, ((rect->w + 1) / 2), (rect->h + 1) / 2, UVplane, UVpitch, &textureData->mainResourceStateNV) < 0) { + return -1; + } + return 0; +} +#endif + +static int D3D12_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *rect, void **pixels, int *pitch) +{ + D3D12_RenderData *rendererData = (D3D12_RenderData *)renderer->driverdata; + D3D12_TextureData *textureData = (D3D12_TextureData *)texture->driverdata; + HRESULT result = S_OK; + + D3D12_RESOURCE_DESC textureDesc; + D3D12_RESOURCE_DESC uploadDesc; + D3D12_HEAP_PROPERTIES heapProps; + D3D12_SUBRESOURCE_FOOTPRINT pitchedDesc; + BYTE *textureMemory; + int bpp; + + if (!textureData) { + return SDL_SetError("Texture is not currently available"); + } +#if SDL_HAVE_YUV + if (textureData->yuv || textureData->nv12) { + /* It's more efficient to upload directly... */ + if (!textureData->pixels) { + textureData->pitch = texture->w; + textureData->pixels = (Uint8 *)SDL_malloc((texture->h * textureData->pitch * 3) / 2); + if (!textureData->pixels) { + return SDL_OutOfMemory(); + } + } + textureData->lockedRect = *rect; + *pixels = + (void *)(textureData->pixels + rect->y * textureData->pitch + + rect->x * SDL_BYTESPERPIXEL(texture->format)); + *pitch = textureData->pitch; + return 0; + } +#endif + if (textureData->stagingBuffer) { + return SDL_SetError("texture is already locked"); + } + + /* Create an upload buffer, which will be used to write to the main texture. */ + SDL_zero(textureDesc); + D3D_CALL_RET_ID3D12Resource_GetDesc(textureData->mainTexture, &textureDesc); + textureDesc.Width = rect->w; + textureDesc.Height = rect->h; + + SDL_zero(uploadDesc); + uploadDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + uploadDesc.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT; + uploadDesc.Height = 1; + uploadDesc.DepthOrArraySize = 1; + uploadDesc.MipLevels = 1; + uploadDesc.Format = DXGI_FORMAT_UNKNOWN; + uploadDesc.SampleDesc.Count = 1; + uploadDesc.SampleDesc.Quality = 0; + uploadDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + uploadDesc.Flags = D3D12_RESOURCE_FLAG_NONE; + + /* Figure out how much we need to allocate for the upload buffer */ + D3D_CALL(rendererData->d3dDevice, GetCopyableFootprints, + &textureDesc, + 0, + 1, + 0, + NULL, + NULL, + NULL, + &uploadDesc.Width); + + SDL_zero(heapProps); + heapProps.Type = D3D12_HEAP_TYPE_UPLOAD; + heapProps.CreationNodeMask = 1; + heapProps.VisibleNodeMask = 1; + + /* Create the upload buffer */ + result = D3D_CALL(rendererData->d3dDevice, CreateCommittedResource, + &heapProps, + D3D12_HEAP_FLAG_NONE, + &uploadDesc, + D3D12_RESOURCE_STATE_GENERIC_READ, + NULL, + D3D_GUID(SDL_IID_ID3D12Resource), + (void **)&textureData->stagingBuffer); + if (FAILED(result)) { + return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D12Device::CreateCommittedResource [create upload buffer]"), result); + } + + /* Get a write-only pointer to data in the upload buffer: */ + result = D3D_CALL(textureData->stagingBuffer, Map, + 0, + NULL, + (void **)&textureMemory); + if (FAILED(result)) { + SAFE_RELEASE(rendererData->uploadBuffers[rendererData->currentUploadBuffer]); + return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D12Resource::Map [map staging texture]"), result); + } + + SDL_zero(pitchedDesc); + pitchedDesc.Format = textureDesc.Format; + pitchedDesc.Width = rect->w; + pitchedDesc.Height = rect->h; + pitchedDesc.Depth = 1; + if (pitchedDesc.Format == DXGI_FORMAT_R8_UNORM) { + bpp = 1; + } else { + bpp = 4; + } + pitchedDesc.RowPitch = D3D12_Align(rect->w * bpp, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT); + + /* Make note of where the staging texture will be written to + * (on a call to SDL_UnlockTexture): + */ + textureData->lockedRect = *rect; + + /* Make sure the caller has information on the texture's pixel buffer, + * then return: + */ + *pixels = textureMemory; + *pitch = pitchedDesc.RowPitch; + return 0; +} + +static void D3D12_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture) +{ + D3D12_RenderData *rendererData = (D3D12_RenderData *)renderer->driverdata; + D3D12_TextureData *textureData = (D3D12_TextureData *)texture->driverdata; + + D3D12_RESOURCE_DESC textureDesc; + D3D12_SUBRESOURCE_FOOTPRINT pitchedDesc; + D3D12_PLACED_SUBRESOURCE_FOOTPRINT placedTextureDesc; + D3D12_TEXTURE_COPY_LOCATION srcLocation; + D3D12_TEXTURE_COPY_LOCATION dstLocation; + int bpp; + + if (!textureData) { + return; + } +#if SDL_HAVE_YUV + if (textureData->yuv || textureData->nv12) { + const SDL_Rect *rect = &textureData->lockedRect; + void *pixels = + (void *)(textureData->pixels + rect->y * textureData->pitch + + rect->x * SDL_BYTESPERPIXEL(texture->format)); + D3D12_UpdateTexture(renderer, texture, rect, pixels, textureData->pitch); + return; + } +#endif + /* Commit the pixel buffer's changes back to the staging texture: */ + D3D_CALL(textureData->stagingBuffer, Unmap, 0, NULL); + + SDL_zero(textureDesc); + D3D_CALL_RET_ID3D12Resource_GetDesc(textureData->mainTexture, &textureDesc); + textureDesc.Width = textureData->lockedRect.w; + textureDesc.Height = textureData->lockedRect.h; + + SDL_zero(pitchedDesc); + pitchedDesc.Format = textureDesc.Format; + pitchedDesc.Width = (UINT)textureDesc.Width; + pitchedDesc.Height = textureDesc.Height; + pitchedDesc.Depth = 1; + if (pitchedDesc.Format == DXGI_FORMAT_R8_UNORM) { + bpp = 1; + } else { + bpp = 4; + } + pitchedDesc.RowPitch = D3D12_Align(textureData->lockedRect.w * bpp, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT); + + SDL_zero(placedTextureDesc); + placedTextureDesc.Offset = 0; + placedTextureDesc.Footprint = pitchedDesc; + + D3D12_TransitionResource(rendererData, textureData->mainTexture, textureData->mainResourceState, D3D12_RESOURCE_STATE_COPY_DEST); + textureData->mainResourceState = D3D12_RESOURCE_STATE_COPY_DEST; + + SDL_zero(dstLocation); + dstLocation.pResource = textureData->mainTexture; + dstLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + dstLocation.SubresourceIndex = 0; + + SDL_zero(srcLocation); + srcLocation.pResource = textureData->stagingBuffer; + srcLocation.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + srcLocation.PlacedFootprint = placedTextureDesc; + + D3D_CALL(rendererData->commandList, CopyTextureRegion, + &dstLocation, + textureData->lockedRect.x, + textureData->lockedRect.y, + 0, + &srcLocation, + NULL); + + /* Transition the texture to be shader accessible */ + D3D12_TransitionResource(rendererData, textureData->mainTexture, textureData->mainResourceState, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); + textureData->mainResourceState = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; + + /* Execute the command list before releasing the staging buffer */ + D3D12_IssueBatch(rendererData); + SAFE_RELEASE(textureData->stagingBuffer); +} + +static void D3D12_SetTextureScaleMode(SDL_Renderer *renderer, SDL_Texture *texture, SDL_ScaleMode scaleMode) +{ + D3D12_TextureData *textureData = (D3D12_TextureData *)texture->driverdata; + + if (!textureData) { + return; + } + + textureData->scaleMode = (scaleMode == SDL_ScaleModeNearest) ? D3D12_FILTER_MIN_MAG_MIP_POINT : D3D12_FILTER_MIN_MAG_MIP_LINEAR; +} + +static int D3D12_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture) +{ + D3D12_RenderData *rendererData = (D3D12_RenderData *)renderer->driverdata; + D3D12_TextureData *textureData = NULL; + + if (!texture) { + if (rendererData->textureRenderTarget) { + D3D12_TransitionResource(rendererData, + rendererData->textureRenderTarget->mainTexture, + rendererData->textureRenderTarget->mainResourceState, + D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); + rendererData->textureRenderTarget->mainResourceState = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; + } + rendererData->textureRenderTarget = NULL; + return 0; + } + + textureData = (D3D12_TextureData *)texture->driverdata; + + if (!textureData->mainTextureRenderTargetView.ptr) { + return SDL_SetError("specified texture is not a render target"); + } + + rendererData->textureRenderTarget = textureData; + D3D12_TransitionResource(rendererData, + rendererData->textureRenderTarget->mainTexture, + rendererData->textureRenderTarget->mainResourceState, + D3D12_RESOURCE_STATE_RENDER_TARGET); + rendererData->textureRenderTarget->mainResourceState = D3D12_RESOURCE_STATE_RENDER_TARGET; + + return 0; +} + +static int D3D12_QueueSetViewport(SDL_Renderer *renderer, SDL_RenderCommand *cmd) +{ + return 0; /* nothing to do in this backend. */ +} + +static int D3D12_QueueDrawPoints(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count) +{ + VertexPositionColor *verts = (VertexPositionColor *)SDL_AllocateRenderVertices(renderer, count * sizeof(VertexPositionColor), 0, &cmd->data.draw.first); + int i; + SDL_Color color; + color.r = cmd->data.draw.r; + color.g = cmd->data.draw.g; + color.b = cmd->data.draw.b; + color.a = cmd->data.draw.a; + + if (!verts) { + return -1; + } + + cmd->data.draw.count = count; + + for (i = 0; i < count; i++) { + verts->pos.x = points[i].x + 0.5f; + verts->pos.y = points[i].y + 0.5f; + verts->tex.x = 0.0f; + verts->tex.y = 0.0f; + verts->color = color; + verts++; + } + + return 0; +} + +static int D3D12_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, + const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride, + int num_vertices, const void *indices, int num_indices, int size_indices, + float scale_x, float scale_y) +{ + int i; + int count = indices ? num_indices : num_vertices; + VertexPositionColor *verts = (VertexPositionColor *)SDL_AllocateRenderVertices(renderer, count * sizeof(VertexPositionColor), 0, &cmd->data.draw.first); + + if (!verts) { + return -1; + } + + cmd->data.draw.count = count; + size_indices = indices ? size_indices : 0; + + for (i = 0; i < count; i++) { + int j; + float *xy_; + if (size_indices == 4) { + j = ((const Uint32 *)indices)[i]; + } else if (size_indices == 2) { + j = ((const Uint16 *)indices)[i]; + } else if (size_indices == 1) { + j = ((const Uint8 *)indices)[i]; + } else { + j = i; + } + + xy_ = (float *)((char *)xy + j * xy_stride); + + verts->pos.x = xy_[0] * scale_x; + verts->pos.y = xy_[1] * scale_y; + verts->color = *(SDL_Color *)((char *)color + j * color_stride); + + if (texture) { + float *uv_ = (float *)((char *)uv + j * uv_stride); + verts->tex.x = uv_[0]; + verts->tex.y = uv_[1]; + } else { + verts->tex.x = 0.0f; + verts->tex.y = 0.0f; + } + + verts += 1; + } + return 0; +} + +static int D3D12_UpdateVertexBuffer(SDL_Renderer *renderer, + const void *vertexData, size_t dataSizeInBytes) +{ + D3D12_RenderData *rendererData = (D3D12_RenderData *)renderer->driverdata; + HRESULT result = S_OK; + const int vbidx = rendererData->currentVertexBuffer; + UINT8 *vertexBufferData = NULL; + D3D12_RANGE range; + ID3D12Resource *vertexBuffer; + + range.Begin = 0; + range.End = 0; + + if (dataSizeInBytes == 0) { + return 0; /* nothing to do. */ + } + + if (rendererData->issueBatch) { + if (FAILED(D3D12_IssueBatch(rendererData))) { + SDL_SetError("Failed to issue intermediate batch"); + return E_FAIL; + } + } + + /* If the existing vertex buffer isn't big enough, we need to recreate a big enough one */ + if (dataSizeInBytes > rendererData->vertexBuffers[vbidx].size) { + D3D12_CreateVertexBuffer(rendererData, vbidx, dataSizeInBytes); + } + + vertexBuffer = rendererData->vertexBuffers[vbidx].resource; + result = D3D_CALL(vertexBuffer, Map, 0, &range, (void **)&vertexBufferData); + if (FAILED(result)) { + return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D12Resource::Map [vertex buffer]"), result); + } + SDL_memcpy(vertexBufferData, vertexData, dataSizeInBytes); + D3D_CALL(vertexBuffer, Unmap, 0, NULL); + + rendererData->vertexBuffers[vbidx].view.SizeInBytes = (UINT)dataSizeInBytes; + + D3D_CALL(rendererData->commandList, IASetVertexBuffers, 0, 1, &rendererData->vertexBuffers[vbidx].view); + + rendererData->currentVertexBuffer++; + if (rendererData->currentVertexBuffer >= SDL_D3D12_NUM_VERTEX_BUFFERS) { + rendererData->currentVertexBuffer = 0; + rendererData->issueBatch = SDL_TRUE; + } + + return S_OK; +} + +static int D3D12_UpdateViewport(SDL_Renderer *renderer) +{ + D3D12_RenderData *data = (D3D12_RenderData *)renderer->driverdata; + const SDL_Rect *viewport = &data->currentViewport; + Float4X4 projection; + Float4X4 view; + SDL_FRect orientationAlignedViewport; + BOOL swapDimensions; + D3D12_VIEWPORT d3dviewport; + const int rotation = D3D12_GetRotationForCurrentRenderTarget(renderer); + + if (viewport->w == 0 || viewport->h == 0) { + /* If the viewport is empty, assume that it is because + * SDL_CreateRenderer is calling it, and will call it again later + * with a non-empty viewport. + */ + /* SDL_Log("%s, no viewport was set!\n", __FUNCTION__); */ + return -1; + } + + /* Make sure the SDL viewport gets rotated to that of the physical display's rotation. + * Keep in mind here that the Y-axis will be been inverted (from Direct3D's + * default coordinate system) so rotations will be done in the opposite + * direction of the DXGI_MODE_ROTATION enumeration. + */ + switch (rotation) { + case DXGI_MODE_ROTATION_IDENTITY: + projection = MatrixIdentity(); + break; + case DXGI_MODE_ROTATION_ROTATE270: + projection = MatrixRotationZ(SDL_static_cast(float, M_PI * 0.5f)); + break; + case DXGI_MODE_ROTATION_ROTATE180: + projection = MatrixRotationZ(SDL_static_cast(float, M_PI)); + break; + case DXGI_MODE_ROTATION_ROTATE90: + projection = MatrixRotationZ(SDL_static_cast(float, -M_PI * 0.5f)); + break; + default: + return SDL_SetError("An unknown DisplayOrientation is being used"); + } + + /* Update the view matrix */ + SDL_zero(view); + view.m[0][0] = 2.0f / viewport->w; + view.m[1][1] = -2.0f / viewport->h; + view.m[2][2] = 1.0f; + view.m[3][0] = -1.0f; + view.m[3][1] = 1.0f; + view.m[3][3] = 1.0f; + + /* Combine the projection + view matrix together now, as both only get + * set here (as of this writing, on Dec 26, 2013). When done, store it + * for eventual transfer to the GPU. + */ + data->vertexShaderConstantsData.projectionAndView = MatrixMultiply( + view, + projection); + + /* Update the Direct3D viewport, which seems to be aligned to the + * swap buffer's coordinate space, which is always in either + * a landscape mode, for all Windows 8/RT devices, or a portrait mode, + * for Windows Phone devices. + */ + swapDimensions = D3D12_IsDisplayRotated90Degrees((DXGI_MODE_ROTATION)rotation); + if (swapDimensions) { + orientationAlignedViewport.x = (float)viewport->y; + orientationAlignedViewport.y = (float)viewport->x; + orientationAlignedViewport.w = (float)viewport->h; + orientationAlignedViewport.h = (float)viewport->w; + } else { + orientationAlignedViewport.x = (float)viewport->x; + orientationAlignedViewport.y = (float)viewport->y; + orientationAlignedViewport.w = (float)viewport->w; + orientationAlignedViewport.h = (float)viewport->h; + } + + d3dviewport.TopLeftX = orientationAlignedViewport.x; + d3dviewport.TopLeftY = orientationAlignedViewport.y; + d3dviewport.Width = orientationAlignedViewport.w; + d3dviewport.Height = orientationAlignedViewport.h; + d3dviewport.MinDepth = 0.0f; + d3dviewport.MaxDepth = 1.0f; + /* SDL_Log("%s: D3D viewport = {%f,%f,%f,%f}\n", __FUNCTION__, d3dviewport.TopLeftX, d3dviewport.TopLeftY, d3dviewport.Width, d3dviewport.Height); */ + D3D_CALL(data->commandList, RSSetViewports, 1, &d3dviewport); + + data->viewportDirty = SDL_FALSE; + + return 0; +} + +static int D3D12_SetDrawState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, D3D12_Shader shader, + D3D12_PRIMITIVE_TOPOLOGY_TYPE topology, + const int numShaderResources, D3D12_CPU_DESCRIPTOR_HANDLE *shaderResources, + D3D12_CPU_DESCRIPTOR_HANDLE *sampler, const Float4X4 *matrix) + +{ + D3D12_RenderData *rendererData = (D3D12_RenderData *)renderer->driverdata; + const Float4X4 *newmatrix = matrix ? matrix : &rendererData->identity; + D3D12_CPU_DESCRIPTOR_HANDLE renderTargetView = D3D12_GetCurrentRenderTargetView(renderer); + const SDL_BlendMode blendMode = cmd->data.draw.blend; + SDL_bool updateSubresource = SDL_FALSE; + int i; + D3D12_CPU_DESCRIPTOR_HANDLE firstShaderResource; + DXGI_FORMAT rtvFormat = DXGI_FORMAT_B8G8R8A8_UNORM; + + if (rendererData->textureRenderTarget) { + rtvFormat = rendererData->textureRenderTarget->mainTextureFormat; + } + + /* See if we need to change the pipeline state */ + if (!rendererData->currentPipelineState || + rendererData->currentPipelineState->shader != shader || + rendererData->currentPipelineState->blendMode != blendMode || + rendererData->currentPipelineState->topology != topology || + rendererData->currentPipelineState->rtvFormat != rtvFormat) { + + /* Find the matching pipeline. + NOTE: Although it may seem inefficient to linearly search through ~450 pipelines + to find the correct one, in profiling this doesn't come up at all. + It's unlikely that using a hash table would affect performance a measurable amount unless + it's a degenerate case that's chaning the pipline state dozens of times per frame. + */ + rendererData->currentPipelineState = NULL; + for (i = 0; i < rendererData->pipelineStateCount; ++i) { + D3D12_PipelineState *candidatePiplineState = &rendererData->pipelineStates[i]; + if (candidatePiplineState->shader == shader && + candidatePiplineState->blendMode == blendMode && + candidatePiplineState->topology == topology && + candidatePiplineState->rtvFormat == rtvFormat) { + rendererData->currentPipelineState = candidatePiplineState; + break; + } + } + + /* If we didn't find a match, create a new one -- it must mean the blend mode is non-standard */ + if (!rendererData->currentPipelineState) { + rendererData->currentPipelineState = D3D12_CreatePipelineState(renderer, shader, blendMode, topology, rtvFormat); + } + + if (!rendererData->currentPipelineState) { + return SDL_SetError("[direct3d12] Unable to create required pipeline state"); + } + + D3D_CALL(rendererData->commandList, SetPipelineState, rendererData->currentPipelineState->pipelineState); + D3D_CALL(rendererData->commandList, SetGraphicsRootSignature, + rendererData->rootSignatures[D3D12_GetRootSignatureType(rendererData->currentPipelineState->shader)]); + /* When we change these we will need to re-upload the constant buffer and reset any descriptors */ + updateSubresource = SDL_TRUE; + rendererData->currentSampler.ptr = 0; + rendererData->currentShaderResource.ptr = 0; + } + + if (renderTargetView.ptr != rendererData->currentRenderTargetView.ptr) { + D3D_CALL(rendererData->commandList, OMSetRenderTargets, 1, &renderTargetView, FALSE, NULL); + rendererData->currentRenderTargetView = renderTargetView; + } + + if (rendererData->viewportDirty) { + if (D3D12_UpdateViewport(renderer) == 0) { + /* vertexShaderConstantsData.projectionAndView has changed */ + updateSubresource = SDL_TRUE; + } + } + + if (rendererData->cliprectDirty) { + D3D12_RECT scissorRect; + if (D3D12_GetViewportAlignedD3DRect(renderer, &rendererData->currentCliprect, &scissorRect, TRUE) != 0) { + /* D3D12_GetViewportAlignedD3DRect will have set the SDL error */ + return -1; + } + D3D_CALL(rendererData->commandList, RSSetScissorRects, 1, &scissorRect); + rendererData->cliprectDirty = SDL_FALSE; + } + + if (numShaderResources > 0) { + firstShaderResource = shaderResources[0]; + } else { + firstShaderResource.ptr = 0; + } + if (firstShaderResource.ptr != rendererData->currentShaderResource.ptr) { + for (i = 0; i < numShaderResources; ++i) { + D3D12_GPU_DESCRIPTOR_HANDLE GPUHandle = D3D12_CPUtoGPUHandle(rendererData->srvDescriptorHeap, shaderResources[i]); + D3D_CALL(rendererData->commandList, SetGraphicsRootDescriptorTable, i + 1, GPUHandle); + } + rendererData->currentShaderResource.ptr = firstShaderResource.ptr; + } + + if (sampler && sampler->ptr != rendererData->currentSampler.ptr) { + D3D12_GPU_DESCRIPTOR_HANDLE GPUHandle = D3D12_CPUtoGPUHandle(rendererData->samplerDescriptorHeap, *sampler); + UINT tableIndex = 0; + + /* Figure out the correct sampler descriptor table index based on the type of shader */ + switch (shader) { + case SHADER_RGB: + tableIndex = 2; + break; +#if SDL_HAVE_YUV + case SHADER_YUV_JPEG: + case SHADER_YUV_BT601: + case SHADER_YUV_BT709: + tableIndex = 4; + break; + case SHADER_NV12_JPEG: + case SHADER_NV12_BT601: + case SHADER_NV12_BT709: + case SHADER_NV21_JPEG: + case SHADER_NV21_BT601: + case SHADER_NV21_BT709: + tableIndex = 3; + break; +#endif + default: + return SDL_SetError("[direct3d12] Trying to set a sampler for a shader which doesn't have one"); + break; + } + + D3D_CALL(rendererData->commandList, SetGraphicsRootDescriptorTable, tableIndex, GPUHandle); + rendererData->currentSampler = *sampler; + } + + if (updateSubresource == SDL_TRUE || SDL_memcmp(&rendererData->vertexShaderConstantsData.model, newmatrix, sizeof(*newmatrix)) != 0) { + SDL_memcpy(&rendererData->vertexShaderConstantsData.model, newmatrix, sizeof(*newmatrix)); + D3D_CALL(rendererData->commandList, SetGraphicsRoot32BitConstants, + 0, + 32, + &rendererData->vertexShaderConstantsData, + 0); + } + + return 0; +} + +static int D3D12_SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const Float4X4 *matrix) +{ + SDL_Texture *texture = cmd->data.draw.texture; + D3D12_RenderData *rendererData = (D3D12_RenderData *)renderer->driverdata; + D3D12_TextureData *textureData = (D3D12_TextureData *)texture->driverdata; + D3D12_CPU_DESCRIPTOR_HANDLE *textureSampler; + + switch (textureData->scaleMode) { + case D3D12_FILTER_MIN_MAG_MIP_POINT: + textureSampler = &rendererData->nearestPixelSampler; + break; + case D3D12_FILTER_MIN_MAG_MIP_LINEAR: + textureSampler = &rendererData->linearSampler; + break; + default: + return SDL_SetError("Unknown scale mode: %d\n", textureData->scaleMode); + } +#if SDL_HAVE_YUV + if (textureData->yuv) { + D3D12_CPU_DESCRIPTOR_HANDLE shaderResources[] = { + textureData->mainTextureResourceView, + textureData->mainTextureResourceViewU, + textureData->mainTextureResourceViewV + }; + D3D12_Shader shader; + + switch (SDL_GetYUVConversionModeForResolution(texture->w, texture->h)) { + case SDL_YUV_CONVERSION_JPEG: + shader = SHADER_YUV_JPEG; + break; + case SDL_YUV_CONVERSION_BT601: + shader = SHADER_YUV_BT601; + break; + case SDL_YUV_CONVERSION_BT709: + shader = SHADER_YUV_BT709; + break; + default: + return SDL_SetError("Unsupported YUV conversion mode"); + } + + /* Make sure each texture is in the correct state to be accessed by the pixel shader. */ + D3D12_TransitionResource(rendererData, textureData->mainTexture, textureData->mainResourceState, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); + textureData->mainResourceState = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; + D3D12_TransitionResource(rendererData, textureData->mainTextureU, textureData->mainResourceStateU, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); + textureData->mainResourceStateU = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; + D3D12_TransitionResource(rendererData, textureData->mainTextureV, textureData->mainResourceStateV, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); + textureData->mainResourceStateV = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; + + return D3D12_SetDrawState(renderer, cmd, shader, D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE, SDL_arraysize(shaderResources), shaderResources, + textureSampler, matrix); + } else if (textureData->nv12) { + D3D12_CPU_DESCRIPTOR_HANDLE shaderResources[] = { + textureData->mainTextureResourceView, + textureData->mainTextureResourceViewNV, + }; + D3D12_Shader shader; + + switch (SDL_GetYUVConversionModeForResolution(texture->w, texture->h)) { + case SDL_YUV_CONVERSION_JPEG: + shader = texture->format == SDL_PIXELFORMAT_NV12 ? SHADER_NV12_JPEG : SHADER_NV21_JPEG; + break; + case SDL_YUV_CONVERSION_BT601: + shader = texture->format == SDL_PIXELFORMAT_NV12 ? SHADER_NV12_BT601 : SHADER_NV21_BT601; + break; + case SDL_YUV_CONVERSION_BT709: + shader = texture->format == SDL_PIXELFORMAT_NV12 ? SHADER_NV12_BT709 : SHADER_NV21_BT709; + break; + default: + return SDL_SetError("Unsupported YUV conversion mode"); + } + + /* Make sure each texture is in the correct state to be accessed by the pixel shader. */ + D3D12_TransitionResource(rendererData, textureData->mainTexture, textureData->mainResourceState, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); + textureData->mainResourceState = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; + D3D12_TransitionResource(rendererData, textureData->mainTextureNV, textureData->mainResourceStateNV, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); + textureData->mainResourceStateNV = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; + + return D3D12_SetDrawState(renderer, cmd, shader, D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE, SDL_arraysize(shaderResources), shaderResources, + textureSampler, matrix); + } +#endif /* SDL_HAVE_YUV */ + D3D12_TransitionResource(rendererData, textureData->mainTexture, textureData->mainResourceState, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); + textureData->mainResourceState = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; + return D3D12_SetDrawState(renderer, cmd, SHADER_RGB, D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE, 1, &textureData->mainTextureResourceView, + textureSampler, matrix); +} + +static void D3D12_DrawPrimitives(SDL_Renderer *renderer, D3D12_PRIMITIVE_TOPOLOGY primitiveTopology, const size_t vertexStart, const size_t vertexCount) +{ + D3D12_RenderData *rendererData = (D3D12_RenderData *)renderer->driverdata; + D3D_CALL(rendererData->commandList, IASetPrimitiveTopology, primitiveTopology); + D3D_CALL(rendererData->commandList, DrawInstanced, (UINT)vertexCount, 1, (UINT)vertexStart, 0); +} + +static int D3D12_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize) +{ + D3D12_RenderData *rendererData = (D3D12_RenderData *)renderer->driverdata; + const int viewportRotation = D3D12_GetRotationForCurrentRenderTarget(renderer); + + if (rendererData->currentViewportRotation != viewportRotation) { + rendererData->currentViewportRotation = viewportRotation; + rendererData->viewportDirty = SDL_TRUE; + } + + if (D3D12_UpdateVertexBuffer(renderer, vertices, vertsize) < 0) { + return -1; + } + + while (cmd) { + switch (cmd->command) { + case SDL_RENDERCMD_SETDRAWCOLOR: + { + break; /* this isn't currently used in this render backend. */ + } + + case SDL_RENDERCMD_SETVIEWPORT: + { + SDL_Rect *viewport = &rendererData->currentViewport; + if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof(cmd->data.viewport.rect)) != 0) { + SDL_copyp(viewport, &cmd->data.viewport.rect); + rendererData->viewportDirty = SDL_TRUE; + rendererData->cliprectDirty = SDL_TRUE; + } + break; + } + + case SDL_RENDERCMD_SETCLIPRECT: + { + const SDL_Rect *rect = &cmd->data.cliprect.rect; + SDL_Rect viewport_cliprect; + if (rendererData->currentCliprectEnabled != cmd->data.cliprect.enabled) { + rendererData->currentCliprectEnabled = cmd->data.cliprect.enabled; + rendererData->cliprectDirty = SDL_TRUE; + } + if (!rendererData->currentCliprectEnabled) { + /* If the clip rect is disabled, then the scissor rect should be the whole viewport, + since direct3d12 doesn't allow disabling the scissor rectangle */ + viewport_cliprect.x = 0; + viewport_cliprect.y = 0; + viewport_cliprect.w = rendererData->currentViewport.w; + viewport_cliprect.h = rendererData->currentViewport.h; + rect = &viewport_cliprect; + } + if (SDL_memcmp(&rendererData->currentCliprect, rect, sizeof(*rect)) != 0) { + SDL_copyp(&rendererData->currentCliprect, rect); + rendererData->cliprectDirty = SDL_TRUE; + } + break; + } + + case SDL_RENDERCMD_CLEAR: + { + const float colorRGBA[] = { + (cmd->data.color.r / 255.0f), + (cmd->data.color.g / 255.0f), + (cmd->data.color.b / 255.0f), + (cmd->data.color.a / 255.0f) + }; + + D3D12_CPU_DESCRIPTOR_HANDLE rtvDescriptor = D3D12_GetCurrentRenderTargetView(renderer); + D3D_CALL(rendererData->commandList, ClearRenderTargetView, rtvDescriptor, colorRGBA, 0, NULL); + break; + } + + case SDL_RENDERCMD_DRAW_POINTS: + { + const size_t count = cmd->data.draw.count; + const size_t first = cmd->data.draw.first; + const size_t start = first / sizeof(VertexPositionColor); + D3D12_SetDrawState(renderer, cmd, SHADER_SOLID, D3D12_PRIMITIVE_TOPOLOGY_TYPE_POINT, 0, NULL, NULL, NULL); + D3D12_DrawPrimitives(renderer, D3D_PRIMITIVE_TOPOLOGY_POINTLIST, start, count); + break; + } + + case SDL_RENDERCMD_DRAW_LINES: + { + const size_t count = cmd->data.draw.count; + const size_t first = cmd->data.draw.first; + const size_t start = first / sizeof(VertexPositionColor); + const VertexPositionColor *verts = (VertexPositionColor *)(((Uint8 *)vertices) + first); + D3D12_SetDrawState(renderer, cmd, SHADER_SOLID, D3D12_PRIMITIVE_TOPOLOGY_TYPE_LINE, 0, NULL, NULL, NULL); + D3D12_DrawPrimitives(renderer, D3D_PRIMITIVE_TOPOLOGY_LINESTRIP, start, count); + if (verts[0].pos.x != verts[count - 1].pos.x || verts[0].pos.y != verts[count - 1].pos.y) { + D3D12_DrawPrimitives(renderer, D3D_PRIMITIVE_TOPOLOGY_POINTLIST, start + (count - 1), 1); + } + break; + } + + case SDL_RENDERCMD_FILL_RECTS: /* unused */ + break; + + case SDL_RENDERCMD_COPY: /* unused */ + break; + + case SDL_RENDERCMD_COPY_EX: /* unused */ + break; + + case SDL_RENDERCMD_GEOMETRY: + { + SDL_Texture *texture = cmd->data.draw.texture; + const size_t count = cmd->data.draw.count; + const size_t first = cmd->data.draw.first; + const size_t start = first / sizeof(VertexPositionColor); + + if (texture) { + D3D12_SetCopyState(renderer, cmd, NULL); + } else { + D3D12_SetDrawState(renderer, cmd, SHADER_SOLID, D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE, 0, NULL, NULL, NULL); + } + + D3D12_DrawPrimitives(renderer, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST, start, count); + break; + } + + case SDL_RENDERCMD_NO_OP: + break; + } + + cmd = cmd->next; + } + + return 0; +} + +static int D3D12_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect, + Uint32 format, void *pixels, int pitch) +{ + D3D12_RenderData *data = (D3D12_RenderData *)renderer->driverdata; + ID3D12Resource *backBuffer = NULL; + ID3D12Resource *readbackBuffer = NULL; + HRESULT result; + int status = -1; + D3D12_RESOURCE_DESC textureDesc; + D3D12_RESOURCE_DESC readbackDesc; + D3D12_HEAP_PROPERTIES heapProps; + D3D12_RECT srcRect = { 0, 0, 0, 0 }; + D3D12_BOX srcBox; + D3D12_TEXTURE_COPY_LOCATION dstLocation; + D3D12_TEXTURE_COPY_LOCATION srcLocation; + D3D12_PLACED_SUBRESOURCE_FOOTPRINT placedTextureDesc; + D3D12_SUBRESOURCE_FOOTPRINT pitchedDesc; + BYTE *textureMemory; + int bpp; + + if (data->textureRenderTarget) { + backBuffer = data->textureRenderTarget->mainTexture; + } else { + backBuffer = data->renderTargets[data->currentBackBufferIndex]; + } + + /* Create a staging texture to copy the screen's data to: */ + SDL_zero(textureDesc); + D3D_CALL_RET_ID3D12Resource_GetDesc(backBuffer, &textureDesc); + textureDesc.Width = rect->w; + textureDesc.Height = rect->h; + + SDL_zero(readbackDesc); + readbackDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + readbackDesc.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT; + readbackDesc.Height = 1; + readbackDesc.DepthOrArraySize = 1; + readbackDesc.MipLevels = 1; + readbackDesc.Format = DXGI_FORMAT_UNKNOWN; + readbackDesc.SampleDesc.Count = 1; + readbackDesc.SampleDesc.Quality = 0; + readbackDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + readbackDesc.Flags = D3D12_RESOURCE_FLAG_NONE; + + /* Figure out how much we need to allocate for the upload buffer */ + D3D_CALL(data->d3dDevice, GetCopyableFootprints, + &textureDesc, + 0, + 1, + 0, + NULL, + NULL, + NULL, + &readbackDesc.Width); + + SDL_zero(heapProps); + heapProps.Type = D3D12_HEAP_TYPE_READBACK; + heapProps.CreationNodeMask = 1; + heapProps.VisibleNodeMask = 1; + + result = D3D_CALL(data->d3dDevice, CreateCommittedResource, + &heapProps, + D3D12_HEAP_FLAG_NONE, + &readbackDesc, + D3D12_RESOURCE_STATE_COPY_DEST, + NULL, + D3D_GUID(SDL_IID_ID3D12Resource), + (void **)&readbackBuffer); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D12Device::CreateTexture2D [create staging texture]"), result); + goto done; + } + + /* Transition the render target to be copyable from */ + D3D12_TransitionResource(data, backBuffer, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE); + + /* Copy the desired portion of the back buffer to the staging texture: */ + if (D3D12_GetViewportAlignedD3DRect(renderer, rect, &srcRect, FALSE) != 0) { + /* D3D12_GetViewportAlignedD3DRect will have set the SDL error */ + goto done; + } + srcBox.left = srcRect.left; + srcBox.right = srcRect.right; + srcBox.top = srcRect.top; + srcBox.bottom = srcRect.bottom; + srcBox.front = 0; + srcBox.back = 1; + + /* Issue the copy texture region */ + SDL_zero(pitchedDesc); + pitchedDesc.Format = textureDesc.Format; + pitchedDesc.Width = (UINT)textureDesc.Width; + pitchedDesc.Height = textureDesc.Height; + pitchedDesc.Depth = 1; + if (pitchedDesc.Format == DXGI_FORMAT_R8_UNORM) { + bpp = 1; + } else { + bpp = 4; + } + pitchedDesc.RowPitch = D3D12_Align(pitchedDesc.Width * bpp, D3D12_TEXTURE_DATA_PITCH_ALIGNMENT); + + SDL_zero(placedTextureDesc); + placedTextureDesc.Offset = 0; + placedTextureDesc.Footprint = pitchedDesc; + + SDL_zero(dstLocation); + dstLocation.pResource = readbackBuffer; + dstLocation.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + dstLocation.PlacedFootprint = placedTextureDesc; + + SDL_zero(srcLocation); + srcLocation.pResource = backBuffer; + srcLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + srcLocation.SubresourceIndex = 0; + + D3D_CALL(data->commandList, CopyTextureRegion, + &dstLocation, + 0, 0, 0, + &srcLocation, + &srcBox); + + /* We need to issue the command list for the copy to finish */ + D3D12_IssueBatch(data); + + /* Transition the render target back to a render target */ + D3D12_TransitionResource(data, backBuffer, D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET); + + /* Map the staging texture's data to CPU-accessible memory: */ + result = D3D_CALL(readbackBuffer, Map, + 0, + NULL, + (void **)&textureMemory); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D12Resource::Map [map staging texture]"), result); + goto done; + } + + /* Copy the data into the desired buffer, converting pixels to the + * desired format at the same time: + */ + status = SDL_ConvertPixels( + rect->w, rect->h, + D3D12_DXGIFormatToSDLPixelFormat(textureDesc.Format), + textureMemory, + pitchedDesc.RowPitch, + format, + pixels, + pitch); + + /* Unmap the texture: */ + D3D_CALL(readbackBuffer, Unmap, 0, NULL); + +done: + SAFE_RELEASE(readbackBuffer); + return status; +} + +static int D3D12_RenderPresent(SDL_Renderer *renderer) +{ + D3D12_RenderData *data = (D3D12_RenderData *)renderer->driverdata; +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + UINT syncInterval; + UINT presentFlags; +#endif + HRESULT result; + + /* Transition the render target to present state */ + D3D12_TransitionResource(data, + data->renderTargets[data->currentBackBufferIndex], + D3D12_RESOURCE_STATE_RENDER_TARGET, + D3D12_RESOURCE_STATE_PRESENT); + + /* Issue the command list */ + result = D3D_CALL(data->commandList, Close); + D3D_CALL(data->commandQueue, ExecuteCommandLists, 1, (ID3D12CommandList *const *)&data->commandList); + +#if defined(__XBOXONE__) || defined(__XBOXSERIES__) + result = D3D12_XBOX_PresentFrame(data->commandQueue, data->frameToken, data->renderTargets[data->currentBackBufferIndex]); +#else + if (renderer->info.flags & SDL_RENDERER_PRESENTVSYNC) { + syncInterval = 1; + presentFlags = 0; + } else { + syncInterval = 0; + presentFlags = DXGI_PRESENT_ALLOW_TEARING; + } + + /* The application may optionally specify "dirty" or "scroll" + * rects to improve efficiency in certain scenarios. + */ + result = D3D_CALL(data->swapChain, Present, syncInterval, presentFlags); +#endif + + if (FAILED(result) && result != DXGI_ERROR_WAS_STILL_DRAWING) { + /* If the device was removed either by a disconnect or a driver upgrade, we + * must recreate all device resources. + */ + if (result == DXGI_ERROR_DEVICE_REMOVED) { + D3D12_HandleDeviceLost(renderer); + } else if (result == DXGI_ERROR_INVALID_CALL) { + /* We probably went through a fullscreen <-> windowed transition */ + D3D12_CreateWindowSizeDependentResources(renderer); + } else { + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGISwapChain::Present"), result); + } + return -1; + } else { + /* Wait for the GPU and move to the next frame */ + result = D3D_CALL(data->commandQueue, Signal, data->fence, data->fenceValue); + + if (D3D_CALL(data->fence, GetCompletedValue) < data->fenceValue) { + result = D3D_CALL(data->fence, SetEventOnCompletion, + data->fenceValue, + data->fenceEvent); + WaitForSingleObjectEx(data->fenceEvent, INFINITE, FALSE); + } + + data->fenceValue++; +#if defined(__XBOXONE__) || defined(__XBOXSERIES__) + data->currentBackBufferIndex++; + data->currentBackBufferIndex %= SDL_D3D12_NUM_BUFFERS; +#else + data->currentBackBufferIndex = D3D_CALL(data->swapChain, GetCurrentBackBufferIndex); +#endif + + /* Reset the command allocator and command list, and transition back to render target */ + D3D12_ResetCommandList(data); + D3D12_TransitionResource(data, + data->renderTargets[data->currentBackBufferIndex], + D3D12_RESOURCE_STATE_PRESENT, + D3D12_RESOURCE_STATE_RENDER_TARGET); + +#if defined(__XBOXONE__) || defined(__XBOXSERIES__) + D3D12_XBOX_StartFrame(data->d3dDevice, &data->frameToken); +#endif + return 0; + } +} + +static int D3D12_SetVSync(SDL_Renderer *renderer, const int vsync) +{ + if (vsync) { + renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; + } else { + renderer->info.flags &= ~SDL_RENDERER_PRESENTVSYNC; + } + return 0; +} + +SDL_Renderer *D3D12_CreateRenderer(SDL_Window *window, Uint32 flags) +{ + SDL_Renderer *renderer; + D3D12_RenderData *data; + + renderer = (SDL_Renderer *)SDL_calloc(1, sizeof(*renderer)); + if (!renderer) { + SDL_OutOfMemory(); + return NULL; + } + + data = (D3D12_RenderData *)SDL_calloc(1, sizeof(*data)); + if (!data) { + SDL_free(renderer); + SDL_OutOfMemory(); + return NULL; + } + + data->identity = MatrixIdentity(); + + renderer->WindowEvent = D3D12_WindowEvent; + renderer->GetOutputSize = D3D12_GetOutputSize; + renderer->SupportsBlendMode = D3D12_SupportsBlendMode; + renderer->CreateTexture = D3D12_CreateTexture; + renderer->UpdateTexture = D3D12_UpdateTexture; +#if SDL_HAVE_YUV + renderer->UpdateTextureYUV = D3D12_UpdateTextureYUV; + renderer->UpdateTextureNV = D3D12_UpdateTextureNV; +#endif + renderer->LockTexture = D3D12_LockTexture; + renderer->UnlockTexture = D3D12_UnlockTexture; + renderer->SetTextureScaleMode = D3D12_SetTextureScaleMode; + renderer->SetRenderTarget = D3D12_SetRenderTarget; + renderer->QueueSetViewport = D3D12_QueueSetViewport; + renderer->QueueSetDrawColor = D3D12_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */ + renderer->QueueDrawPoints = D3D12_QueueDrawPoints; + renderer->QueueDrawLines = D3D12_QueueDrawPoints; /* lines and points queue vertices the same way. */ + renderer->QueueGeometry = D3D12_QueueGeometry; + renderer->RunCommandQueue = D3D12_RunCommandQueue; + renderer->RenderReadPixels = D3D12_RenderReadPixels; + renderer->RenderPresent = D3D12_RenderPresent; + renderer->DestroyTexture = D3D12_DestroyTexture; + renderer->DestroyRenderer = D3D12_DestroyRenderer; + renderer->info = D3D12_RenderDriver.info; + renderer->info.flags = (SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE); + renderer->driverdata = data; + + if (flags & SDL_RENDERER_PRESENTVSYNC) { + renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; + } + renderer->SetVSync = D3D12_SetVSync; + + /* HACK: make sure the SDL_Renderer references the SDL_Window data now, in + * order to give init functions access to the underlying window handle: + */ + renderer->window = window; + + /* Initialize Direct3D resources */ + if (FAILED(D3D12_CreateDeviceResources(renderer))) { + D3D12_DestroyRenderer(renderer); + return NULL; + } + if (FAILED(D3D12_CreateWindowSizeDependentResources(renderer))) { + D3D12_DestroyRenderer(renderer); + return NULL; + } + + return renderer; +} + +SDL_RenderDriver D3D12_RenderDriver = { + D3D12_CreateRenderer, + { + "direct3d12", + ( + SDL_RENDERER_ACCELERATED | + SDL_RENDERER_PRESENTVSYNC | + SDL_RENDERER_TARGETTEXTURE), /* flags. see SDL_RendererFlags */ + 6, /* num_texture_formats */ + { /* texture_formats */ + SDL_PIXELFORMAT_ARGB8888, + SDL_PIXELFORMAT_RGB888, + SDL_PIXELFORMAT_YV12, + SDL_PIXELFORMAT_IYUV, + SDL_PIXELFORMAT_NV12, + SDL_PIXELFORMAT_NV21 }, + 16384, /* max_texture_width */ + 16384 /* max_texture_height */ + } +}; + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif + +#endif /* SDL_VIDEO_RENDER_D3D12 */ + +#if defined(__WIN32__) || defined(__GDK__) +#ifdef __cplusplus +extern "C" +#endif + /* This function needs to always exist on Windows, for the Dynamic API. */ + ID3D12Device * + SDL_RenderGetD3D12Device(SDL_Renderer *renderer) +{ + ID3D12Device *device = NULL; + +#if SDL_VIDEO_RENDER_D3D12 + D3D12_RenderData *data = (D3D12_RenderData *)renderer->driverdata; + + /* Make sure that this is a D3D renderer */ + if (renderer->DestroyRenderer != D3D12_DestroyRenderer) { + SDL_SetError("Renderer is not a D3D12 renderer"); + return NULL; + } + + device = (ID3D12Device *)data->d3dDevice; + if (device) { + D3D_CALL(device, AddRef); + } +#endif /* SDL_VIDEO_RENDER_D3D12 */ + + return device; +} +#endif /* defined(__WIN32__) || defined(__GDK__) */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/render/direct3d12/SDL_render_d3d12_xbox.cpp b/SDL2-2.30.5/src/render/direct3d12/SDL_render_d3d12_xbox.cpp new file mode 100644 index 0000000..7b598c0 --- /dev/null +++ b/SDL2-2.30.5/src/render/direct3d12/SDL_render_d3d12_xbox.cpp @@ -0,0 +1,174 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" +#if SDL_VIDEO_RENDER_D3D12 && (defined(__XBOXONE__) || defined(__XBOXSERIES__)) +#include "SDL_render_d3d12_xbox.h" +#include "../../core/windows/SDL_windows.h" +#include + +#if defined(_MSC_VER) && !defined(__clang__) +#define SDL_COMPOSE_ERROR(str) __FUNCTION__ ", " str +#else +#define SDL_COMPOSE_ERROR(str) SDL_STRINGIFY_ARG(__FUNCTION__) ", " str +#endif + +static const GUID SDL_IID_ID3D12Device1 = { 0x77acce80, 0x638e, 0x4e65, { 0x88, 0x95, 0xc1, 0xf2, 0x33, 0x86, 0x86, 0x3e } }; +static const GUID SDL_IID_ID3D12Resource = { 0x696442be, 0xa72e, 0x4059, { 0xbc, 0x79, 0x5b, 0x5c, 0x98, 0x04, 0x0f, 0xad } }; +static const GUID SDL_IID_IDXGIDevice1 = { 0x77db970f, 0x6276, 0x48ba, { 0xba, 0x28, 0x07, 0x01, 0x43, 0xb4, 0x39, 0x2c } }; + +extern "C" HRESULT +D3D12_XBOX_CreateDevice(ID3D12Device **device, SDL_bool createDebug) +{ + HRESULT result; + D3D12XBOX_CREATE_DEVICE_PARAMETERS params; + IDXGIDevice1 *dxgiDevice; + IDXGIAdapter *dxgiAdapter; + IDXGIOutput *dxgiOutput; + SDL_zero(params); + + params.Version = D3D12_SDK_VERSION; + params.ProcessDebugFlags = createDebug ? D3D12_PROCESS_DEBUG_FLAG_DEBUG_LAYER_ENABLED : D3D12XBOX_PROCESS_DEBUG_FLAG_NONE; + params.GraphicsCommandQueueRingSizeBytes = D3D12XBOX_DEFAULT_SIZE_BYTES; + params.GraphicsScratchMemorySizeBytes = D3D12XBOX_DEFAULT_SIZE_BYTES; + params.ComputeScratchMemorySizeBytes = D3D12XBOX_DEFAULT_SIZE_BYTES; + + result = D3D12XboxCreateDevice(NULL, ¶ms, SDL_IID_ID3D12Device1, (void **) device); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("[xbox] D3D12XboxCreateDevice"), result); + goto done; + } + + result = (*device)->QueryInterface(SDL_IID_IDXGIDevice1, (void **) &dxgiDevice); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("[xbox] ID3D12Device to IDXGIDevice1"), result); + goto done; + } + + result = dxgiDevice->GetAdapter(&dxgiAdapter); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("[xbox] dxgiDevice->GetAdapter"), result); + goto done; + } + + result = dxgiAdapter->EnumOutputs(0, &dxgiOutput); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("[xbox] dxgiAdapter->EnumOutputs"), result); + goto done; + } + + /* Set frame interval */ + result = (*device)->SetFrameIntervalX(dxgiOutput, D3D12XBOX_FRAME_INTERVAL_60_HZ, 1, D3D12XBOX_FRAME_INTERVAL_FLAG_NONE); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("[xbox] SetFrameIntervalX"), result); + goto done; + } + + result = (*device)->ScheduleFrameEventX(D3D12XBOX_FRAME_EVENT_ORIGIN, 0, NULL, D3D12XBOX_SCHEDULE_FRAME_EVENT_FLAG_NONE); + if (FAILED(result)) { + WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("[xbox] ScheduleFrameEventX"), result); + goto done; + } + +done: + return result; +} + +extern "C" HRESULT +D3D12_XBOX_CreateBackBufferTarget(ID3D12Device1 *device, int width, int height, void **resource) +{ + + D3D12_HEAP_PROPERTIES heapProps; + D3D12_RESOURCE_DESC resourceDesc; + + SDL_zero(heapProps); + heapProps.Type = D3D12_HEAP_TYPE_DEFAULT; + heapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + heapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + heapProps.CreationNodeMask = 1; + heapProps.VisibleNodeMask = 1; + + SDL_zero(resourceDesc); + resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + resourceDesc.Alignment = 0; + resourceDesc.Width = width; + resourceDesc.Height = height; + resourceDesc.DepthOrArraySize = 1; + resourceDesc.MipLevels = 1; + resourceDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; + resourceDesc.SampleDesc.Count = 1; + resourceDesc.SampleDesc.Quality = 0; + resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; + resourceDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; + + return device->CreateCommittedResource(&heapProps, + D3D12_HEAP_FLAG_ALLOW_DISPLAY, + &resourceDesc, + D3D12_RESOURCE_STATE_PRESENT, + NULL, + SDL_IID_ID3D12Resource, + resource + ); +} + +extern "C" HRESULT +D3D12_XBOX_StartFrame(ID3D12Device1 *device, UINT64 *outToken) +{ + *outToken = D3D12XBOX_FRAME_PIPELINE_TOKEN_NULL; + return device->WaitFrameEventX(D3D12XBOX_FRAME_EVENT_ORIGIN, INFINITE, NULL, D3D12XBOX_WAIT_FRAME_EVENT_FLAG_NONE, outToken); +} + +extern "C" HRESULT +D3D12_XBOX_PresentFrame(ID3D12CommandQueue *commandQueue, UINT64 token, ID3D12Resource *renderTarget) +{ + D3D12XBOX_PRESENT_PLANE_PARAMETERS planeParameters; + SDL_zero(planeParameters); + planeParameters.Token = token; + planeParameters.ResourceCount = 1; + planeParameters.ppResources = &renderTarget; + return commandQueue->PresentX(1, &planeParameters, NULL); +} + +extern "C" void +D3D12_XBOX_GetResolution(Uint32 *width, Uint32 *height) +{ + switch (XSystemGetDeviceType()) { + case XSystemDeviceType::XboxScarlettLockhart: + *width = 2560; + *height = 1440; + break; + + case XSystemDeviceType::XboxOneX: + case XSystemDeviceType::XboxScarlettAnaconda: + case XSystemDeviceType::XboxOneXDevkit: + case XSystemDeviceType::XboxScarlettDevkit: + *width = 3840; + *height = 2160; + break; + + default: + *width = 1920; + *height = 1080; + break; + } +} + +#endif diff --git a/SDL2-2.0.12/include/SDL_clipboard.h b/SDL2-2.30.5/src/render/direct3d12/SDL_render_d3d12_xbox.h similarity index 54% rename from SDL2-2.0.12/include/SDL_clipboard.h rename to SDL2-2.30.5/src/render/direct3d12/SDL_render_d3d12_xbox.h index dbf69fc..6db955a 100644 --- a/SDL2-2.0.12/include/SDL_clipboard.h +++ b/SDL2-2.30.5/src/render/direct3d12/SDL_render_d3d12_xbox.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -19,53 +19,31 @@ 3. This notice may not be removed or altered from any source distribution. */ -/** - * \file SDL_clipboard.h - * - * Include file for SDL clipboard handling - */ +#ifndef SDL_render_d3d12_xbox_h_ +#define SDL_render_d3d12_xbox_h_ -#ifndef SDL_clipboard_h_ -#define SDL_clipboard_h_ +#include "../../SDL_internal.h" -#include "SDL_stdinc.h" +#if defined(__XBOXONE__) +#include +#else /* __XBOXSERIES__ */ +#include +#endif -#include "begin_code.h" /* Set up for C function definitions, even when using C++ */ #ifdef __cplusplus extern "C" { #endif -/* Function prototypes */ - -/** - * \brief Put UTF-8 text into the clipboard - * - * \sa SDL_GetClipboardText() - */ -extern DECLSPEC int SDLCALL SDL_SetClipboardText(const char *text); - -/** - * \brief Get UTF-8 text from the clipboard, which must be freed with SDL_free() - * - * \sa SDL_SetClipboardText() - */ -extern DECLSPEC char * SDLCALL SDL_GetClipboardText(void); - -/** - * \brief Returns a flag indicating whether the clipboard exists and contains a text string that is non-empty - * - * \sa SDL_GetClipboardText() - */ -extern DECLSPEC SDL_bool SDLCALL SDL_HasClipboardText(void); - +extern HRESULT D3D12_XBOX_CreateDevice(ID3D12Device **device, SDL_bool createDebug); +extern HRESULT D3D12_XBOX_CreateBackBufferTarget(ID3D12Device1 *device, int width, int height, void **resource); +extern HRESULT D3D12_XBOX_StartFrame(ID3D12Device1 *device, UINT64 *outToken); +extern HRESULT D3D12_XBOX_PresentFrame(ID3D12CommandQueue *commandQueue, UINT64 token, ID3D12Resource *renderTarget); +extern void D3D12_XBOX_GetResolution(Uint32 *width, Uint32 *height); /* Ends C function definitions when using C++ */ #ifdef __cplusplus } #endif -#include "close_code.h" -#endif /* SDL_clipboard_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ +#endif diff --git a/SDL2-2.30.5/src/render/direct3d12/SDL_shaders_d3d12.c b/SDL2-2.30.5/src/render/direct3d12/SDL_shaders_d3d12.c new file mode 100644 index 0000000..29862d4 --- /dev/null +++ b/SDL2-2.30.5/src/render/direct3d12/SDL_shaders_d3d12.c @@ -0,0 +1,6939 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#if SDL_VIDEO_RENDER_D3D12 && !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + +#include "SDL_stdinc.h" + +#include "../../core/windows/SDL_windows.h" +#include + +#include "SDL_shaders_d3d12.h" + +#define SDL_COMPOSE_ERROR(str) SDL_STRINGIFY_ARG(__FUNCTION__) ", " str + +/* Direct3D 12 shaders + + SDL's shaders are compiled into SDL itself, to simplify distribution. + + All Direct3D 12 shaders were compiled with the following: + + dxc -E -T -Fo + + Variables: + - : the function. This is main for the pixel shader, and one of + four options for the vertex shader + - : the type of shader. A table of utilized shader types is + listed below. + - : where to store compiled output + - : where to read shader source code from + + Shader types: + - ps_6_0: Pixel shader + - vs_6_0: Vertex shader + + + Shader object code was converted to unsigned chars via the following + *nix style command (available separately from Windows + MSVC): + + xxd --include + */ + +/* The color-only-rendering pixel shader: + + --- D3D12_PixelShader_Colors.hlsl --- + struct PixelShaderInput + { + float4 pos : SV_POSITION; + float2 tex : TEXCOORD0; + float4 color : COLOR0; + }; + + #define ColorRS \ + "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \ + "DENY_DOMAIN_SHADER_ROOT_ACCESS |" \ + "DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \ + "DENY_HULL_SHADER_ROOT_ACCESS )," \ + "RootConstants(num32BitConstants=32, b0)" + + [RootSignature(ColorRS)] + float4 main(PixelShaderInput input) : SV_TARGET0 + { + return input.color; + } +*/ + +static unsigned char D3D12_PixelShader_Colors[] = { + 0x44, 0x58, 0x42, 0x43, 0x38, 0xfe, 0xa0, 0xc7, 0x8e, 0xb3, 0x78, 0x02, + 0x7e, 0x71, 0xa9, 0x1c, 0x23, 0x3e, 0x23, 0xa2, 0x01, 0x00, 0x00, 0x00, + 0xe5, 0x0c, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0xdb, 0x00, 0x00, 0x00, 0x15, 0x01, 0x00, 0x00, + 0xd9, 0x01, 0x00, 0x00, 0x11, 0x02, 0x00, 0x00, 0xa9, 0x07, 0x00, 0x00, + 0xc5, 0x07, 0x00, 0x00, 0x53, 0x46, 0x49, 0x30, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31, + 0x83, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x53, 0x56, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, + 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x43, 0x4f, 0x4c, + 0x4f, 0x52, 0x00, 0x4f, 0x53, 0x47, 0x31, 0x32, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x00, 0x50, 0x53, 0x56, 0x30, 0xbc, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x03, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x54, 0x45, + 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x44, + 0x03, 0x03, 0x04, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x01, 0x42, 0x00, 0x03, 0x02, 0x00, 0x00, 0x0a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, 0x03, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x44, + 0x10, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x00, 0x52, 0x54, 0x53, 0x30, 0x30, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, + 0x00, 0x53, 0x54, 0x41, 0x54, 0x90, 0x05, 0x00, 0x00, 0x60, 0x00, 0x00, + 0x00, 0x64, 0x01, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c, 0x00, 0x01, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x78, 0x05, 0x00, 0x00, 0x42, 0x43, 0xc0, + 0xde, 0x21, 0x0c, 0x00, 0x00, 0x5b, 0x01, 0x00, 0x00, 0x0b, 0x82, 0x20, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, + 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, + 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x10, 0x45, + 0x02, 0x42, 0x92, 0x0b, 0x42, 0x84, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, + 0x4b, 0x0a, 0x32, 0x42, 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, + 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4, 0x48, 0x0e, 0x90, 0x11, 0x22, 0xc4, + 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x21, 0x46, + 0x06, 0x51, 0x18, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1b, 0x8c, 0xe0, + 0xff, 0xff, 0xff, 0xff, 0x07, 0x40, 0x02, 0xa8, 0x0d, 0x84, 0xf0, 0xff, + 0xff, 0xff, 0xff, 0x03, 0x20, 0x01, 0x00, 0x00, 0x00, 0x49, 0x18, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, 0x42, 0x20, 0x00, 0x00, + 0x00, 0x89, 0x20, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x32, 0x22, 0x08, + 0x09, 0x20, 0x64, 0x85, 0x04, 0x13, 0x22, 0xa4, 0x84, 0x04, 0x13, 0x22, + 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x88, 0x8c, 0x0b, 0x84, 0x84, + 0x4c, 0x10, 0x3c, 0x23, 0x00, 0x25, 0x00, 0x8a, 0x19, 0x80, 0x39, 0x02, + 0x30, 0x98, 0x23, 0x40, 0x8a, 0x31, 0x44, 0x54, 0x44, 0x56, 0x0c, 0x20, + 0xa2, 0x1a, 0xc2, 0x81, 0x80, 0x61, 0x04, 0x62, 0x18, 0x46, 0x10, 0x86, + 0xbb, 0xa4, 0x29, 0xa2, 0x84, 0xc9, 0x4f, 0x91, 0x8b, 0x58, 0xd8, 0x03, + 0x18, 0x88, 0x48, 0x6c, 0x1e, 0x6a, 0x42, 0xc3, 0xf2, 0xa6, 0x03, 0x01, + 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, + 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e, 0x6d, 0xd0, + 0x0e, 0x7a, 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, + 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, + 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, + 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x10, 0x07, 0x76, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x43, 0x9e, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x3c, 0x06, 0x10, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x79, 0x10, + 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x02, + 0x01, 0x10, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x14, 0x19, 0x11, 0x4c, + 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0xa2, 0x12, 0x18, 0x01, + 0x28, 0x86, 0x02, 0x2b, 0x83, 0x42, 0x28, 0x87, 0x92, 0x28, 0x90, 0x02, + 0x2a, 0x82, 0xf2, 0xa0, 0x2a, 0x89, 0x32, 0x28, 0x84, 0x11, 0x80, 0x22, + 0x28, 0x10, 0xea, 0x19, 0x00, 0xf2, 0xb1, 0x1c, 0x86, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x04, 0x02, 0x01, 0x00, 0x00, 0x79, 0x18, 0x00, + 0x00, 0x85, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, + 0x44, 0x35, 0x18, 0x63, 0x0b, 0x73, 0x3b, 0x03, 0xb1, 0x2b, 0x93, 0x9b, + 0x4b, 0x7b, 0x73, 0x03, 0x99, 0x71, 0xb9, 0x01, 0x41, 0xa1, 0x0b, 0x3b, + 0x9b, 0x7b, 0x91, 0x2a, 0x62, 0x2a, 0x0a, 0x9a, 0x2a, 0xfa, 0x9a, 0xb9, + 0x81, 0x79, 0x31, 0x4b, 0x73, 0x0b, 0x63, 0x4b, 0xd9, 0x10, 0x04, 0x13, + 0x04, 0x62, 0x98, 0x20, 0x10, 0xc4, 0x06, 0x61, 0x20, 0x36, 0x08, 0x04, + 0x41, 0x01, 0x6e, 0x6e, 0x82, 0x40, 0x14, 0x1b, 0x86, 0x03, 0x21, 0x26, + 0x08, 0x4d, 0x35, 0x41, 0x20, 0x0c, 0x0e, 0x70, 0x6f, 0x73, 0x13, 0x04, + 0xe2, 0x98, 0x20, 0x10, 0x08, 0x97, 0x29, 0xab, 0x2f, 0xa8, 0xa7, 0xa9, + 0x24, 0xaa, 0xa4, 0x27, 0xa7, 0x09, 0x02, 0x91, 0x4c, 0x10, 0x08, 0x65, + 0x03, 0x82, 0x30, 0x0d, 0xe1, 0x3c, 0x50, 0xc4, 0x81, 0xae, 0x0c, 0x6f, + 0x82, 0x40, 0x2c, 0x4c, 0xa8, 0x8a, 0xb0, 0x86, 0x9e, 0x9e, 0xa4, 0x88, + 0x60, 0x36, 0x20, 0xc8, 0xd4, 0x50, 0x4e, 0x05, 0x45, 0x2c, 0xc6, 0xde, + 0xd8, 0xde, 0xe4, 0x26, 0x08, 0x04, 0x43, 0x63, 0xe8, 0x89, 0xe9, 0x49, + 0x0a, 0x66, 0x03, 0x82, 0x5c, 0x0d, 0xe6, 0x64, 0x50, 0xb4, 0x81, 0x58, + 0x24, 0x4b, 0xdb, 0x30, 0x10, 0xca, 0x36, 0x41, 0x10, 0x80, 0x0d, 0xc0, + 0x86, 0x81, 0xf0, 0xbc, 0x0d, 0xc1, 0xb7, 0x61, 0x18, 0x3a, 0x30, 0x98, + 0x20, 0x38, 0xd6, 0x86, 0x40, 0x0c, 0x48, 0xb4, 0x85, 0xa5, 0xb9, 0x71, + 0x99, 0xb2, 0xfa, 0x82, 0x7a, 0x9b, 0x4b, 0xa3, 0x4b, 0x7b, 0x73, 0x9b, + 0x20, 0x14, 0xcf, 0x04, 0xa1, 0x80, 0x36, 0x04, 0xc4, 0x04, 0xa1, 0x88, + 0x26, 0x08, 0x85, 0xb4, 0x61, 0x21, 0xca, 0xc0, 0x0c, 0xce, 0x00, 0x0d, + 0xd2, 0x60, 0x48, 0x03, 0x42, 0x0d, 0x00, 0x22, 0x54, 0x45, 0x58, 0x43, + 0x4f, 0x4f, 0x52, 0x44, 0x13, 0x84, 0x62, 0xda, 0xb0, 0x0c, 0x6c, 0x60, + 0x06, 0x6a, 0x80, 0x06, 0x6d, 0x30, 0xb4, 0xc1, 0xa0, 0x06, 0xc0, 0x04, + 0x81, 0x68, 0x58, 0x0c, 0x3d, 0x31, 0x3d, 0x49, 0x4d, 0x10, 0x08, 0x67, + 0x83, 0xd0, 0xc4, 0xc1, 0x86, 0xe5, 0x0d, 0xe0, 0xc0, 0x0c, 0xd4, 0x00, + 0x0d, 0xda, 0x60, 0x48, 0x83, 0x37, 0x50, 0x03, 0x39, 0xd8, 0x30, 0xac, + 0x81, 0x1b, 0xcc, 0x01, 0x93, 0x29, 0xab, 0x2f, 0xaa, 0x30, 0xb9, 0xb3, + 0x32, 0xba, 0x09, 0x42, 0x41, 0x6d, 0x58, 0x88, 0x3a, 0x30, 0x03, 0x3b, + 0x40, 0x03, 0x35, 0x18, 0xd2, 0x80, 0x50, 0x03, 0x39, 0xd8, 0x10, 0xdc, + 0xc1, 0x86, 0x81, 0x0e, 0xf0, 0x00, 0xd8, 0x50, 0x74, 0x64, 0x90, 0x07, + 0x00, 0xc0, 0x22, 0xcd, 0x6d, 0x8e, 0x6e, 0x8e, 0xc6, 0x5c, 0xda, 0xd9, + 0x17, 0x1b, 0x19, 0x8d, 0xb9, 0xb4, 0xb3, 0xaf, 0x39, 0xba, 0x0d, 0xc6, + 0x1e, 0x44, 0x7c, 0xe0, 0xf4, 0x81, 0x53, 0x85, 0x8d, 0xcd, 0xae, 0xcd, + 0x25, 0x8d, 0xac, 0xcc, 0x8d, 0x6e, 0x4a, 0x10, 0x54, 0x21, 0xc3, 0x73, + 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x9b, 0x12, 0x10, 0x4d, 0xc8, + 0xf0, 0x5c, 0xec, 0xc2, 0xd8, 0xec, 0xca, 0xe4, 0xa6, 0x04, 0x45, 0x1d, + 0x32, 0x3c, 0x97, 0x39, 0xb4, 0x30, 0xb2, 0x32, 0xb9, 0xa6, 0x37, 0xb2, + 0x32, 0xb6, 0x29, 0x01, 0x52, 0x89, 0x0c, 0xcf, 0x85, 0x2e, 0x0f, 0xae, + 0x2c, 0xc8, 0xcd, 0xed, 0x8d, 0x2e, 0x8c, 0x2e, 0xed, 0xcd, 0x6d, 0x6e, + 0x8a, 0xb0, 0x81, 0x41, 0x1d, 0x32, 0x3c, 0x17, 0xbb, 0xb4, 0xb2, 0xbb, + 0x24, 0xb2, 0x29, 0xba, 0x30, 0xba, 0xb2, 0x29, 0x81, 0x18, 0xd4, 0x21, + 0xc3, 0x73, 0x29, 0x73, 0xa3, 0x93, 0xcb, 0x83, 0x7a, 0x4b, 0x73, 0xa3, + 0x9b, 0x9b, 0x12, 0xe4, 0x41, 0x17, 0x32, 0x3c, 0x97, 0xb1, 0xb7, 0x3a, + 0x37, 0xba, 0x32, 0xb9, 0xb9, 0x29, 0x41, 0x1f, 0x00, 0x79, 0x18, 0x00, + 0x00, 0x4c, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, + 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, + 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, + 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, + 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, + 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, + 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, + 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, + 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, + 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, + 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, + 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, + 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, + 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, + 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, + 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, + 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, + 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, + 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, + 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, + 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, + 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, + 0x3b, 0xb0, 0xc3, 0x0c, 0xc4, 0x21, 0x07, 0x7c, 0x70, 0x03, 0x7a, 0x28, + 0x87, 0x76, 0x80, 0x87, 0x19, 0xd1, 0x43, 0x0e, 0xf8, 0xe0, 0x06, 0xe4, + 0x20, 0x0e, 0xe7, 0xe0, 0x06, 0xf6, 0x10, 0x0e, 0xf2, 0xc0, 0x0e, 0xe1, + 0x90, 0x0f, 0xef, 0x50, 0x0f, 0xf4, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, + 0x00, 0x0b, 0x00, 0x00, 0x00, 0x16, 0x30, 0x0d, 0x97, 0xef, 0x3c, 0xfe, + 0xe2, 0x00, 0x83, 0xd8, 0x3c, 0xd4, 0xe4, 0x17, 0xb7, 0x6d, 0x02, 0xd5, + 0x70, 0xf9, 0xce, 0xe3, 0x4b, 0x93, 0x13, 0x11, 0x28, 0x35, 0x3d, 0xd4, + 0xe4, 0x17, 0xb7, 0x6d, 0x00, 0x04, 0x03, 0x20, 0x0d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x14, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1, 0x4a, 0xd5, 0x78, 0xe4, 0x4f, 0xd6, + 0x12, 0x0d, 0x86, 0x23, 0xf7, 0x0e, 0x82, 0x21, 0x40, 0x44, 0x58, 0x49, + 0x4c, 0x18, 0x05, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x46, 0x01, 0x00, + 0x00, 0x44, 0x58, 0x49, 0x4c, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x05, 0x00, 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, + 0x00, 0x3d, 0x01, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, + 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, + 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x10, 0x45, 0x02, 0x42, 0x92, 0x0b, + 0x42, 0x84, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x42, + 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, + 0x42, 0xe4, 0x48, 0x0e, 0x90, 0x11, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, + 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x21, 0x46, 0x06, 0x51, 0x18, 0x00, + 0x00, 0x06, 0x00, 0x00, 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, + 0x07, 0x40, 0x02, 0xa8, 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, + 0x20, 0x01, 0x00, 0x00, 0x00, 0x49, 0x18, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x13, 0x82, 0x60, 0x42, 0x20, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, + 0x00, 0x0f, 0x00, 0x00, 0x00, 0x32, 0x22, 0x08, 0x09, 0x20, 0x64, 0x85, + 0x04, 0x13, 0x22, 0xa4, 0x84, 0x04, 0x13, 0x22, 0xe3, 0x84, 0xa1, 0x90, + 0x14, 0x12, 0x4c, 0x88, 0x8c, 0x0b, 0x84, 0x84, 0x4c, 0x10, 0x30, 0x23, + 0x00, 0x25, 0x00, 0x8a, 0x19, 0x80, 0x39, 0x02, 0x30, 0x98, 0x23, 0x40, + 0x8a, 0x31, 0x44, 0x54, 0x44, 0x56, 0x0c, 0x20, 0xa2, 0x1a, 0xc2, 0x81, + 0x80, 0x74, 0x20, 0x00, 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, + 0x87, 0x36, 0x68, 0x87, 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, + 0x50, 0x0e, 0x6d, 0xd0, 0x0e, 0x7a, 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, + 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, + 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, + 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, + 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, + 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, + 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, + 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, + 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x43, + 0x9e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x86, 0x3c, 0x06, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x79, 0x10, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc8, 0x02, 0x01, 0x0d, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, + 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, + 0xa2, 0x12, 0x18, 0x01, 0x28, 0x86, 0x22, 0x28, 0x83, 0xf2, 0xa0, 0x2a, + 0x89, 0x32, 0x28, 0x84, 0x11, 0x80, 0x22, 0x28, 0x10, 0xda, 0xb1, 0x1c, + 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x02, 0x01, 0x00, + 0x00, 0x79, 0x18, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, + 0x90, 0x46, 0x02, 0x13, 0x44, 0x35, 0x18, 0x63, 0x0b, 0x73, 0x3b, 0x03, + 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x03, 0x99, 0x71, 0xb9, 0x01, + 0x41, 0xa1, 0x0b, 0x3b, 0x9b, 0x7b, 0x91, 0x2a, 0x62, 0x2a, 0x0a, 0x9a, + 0x2a, 0xfa, 0x9a, 0xb9, 0x81, 0x79, 0x31, 0x4b, 0x73, 0x0b, 0x63, 0x4b, + 0xd9, 0x10, 0x04, 0x13, 0x04, 0x62, 0x98, 0x20, 0x10, 0xc4, 0x06, 0x61, + 0x20, 0x26, 0x08, 0x44, 0xb1, 0x41, 0x18, 0x0c, 0x0a, 0x70, 0x73, 0x1b, + 0x06, 0xc4, 0x20, 0x26, 0x08, 0xcb, 0xb3, 0x21, 0x50, 0x26, 0x08, 0x02, + 0x40, 0xa2, 0x2d, 0x2c, 0xcd, 0x8d, 0xcb, 0x94, 0xd5, 0x17, 0xd4, 0xdb, + 0x5c, 0x1a, 0x5d, 0xda, 0x9b, 0xdb, 0x04, 0xa1, 0x48, 0x26, 0x08, 0x85, + 0xb2, 0x21, 0x20, 0x26, 0x08, 0xc5, 0x32, 0x41, 0x28, 0x98, 0x0d, 0x0b, + 0xe1, 0x3c, 0x50, 0x24, 0x0d, 0x12, 0x31, 0x01, 0x44, 0xa8, 0x8a, 0xb0, + 0x86, 0x9e, 0x9e, 0xa4, 0x88, 0x26, 0x08, 0x45, 0xb3, 0x61, 0x19, 0xaa, + 0x67, 0x8a, 0xac, 0xc1, 0x1a, 0x26, 0x60, 0x82, 0x40, 0x18, 0x2c, 0x86, + 0x9e, 0x98, 0x9e, 0xa4, 0x26, 0x08, 0xc4, 0x31, 0x41, 0x20, 0x90, 0x0d, + 0x82, 0xb6, 0x6d, 0x58, 0xb0, 0xec, 0x99, 0x22, 0x6b, 0x90, 0xb0, 0x89, + 0xdb, 0x30, 0x50, 0x57, 0xc7, 0x64, 0xca, 0xea, 0x8b, 0x2a, 0x4c, 0xee, + 0xac, 0x8c, 0x6e, 0x82, 0x50, 0x38, 0x1b, 0x16, 0xe2, 0x7b, 0xc0, 0x20, + 0x9a, 0x06, 0x89, 0x98, 0xb8, 0x0d, 0x41, 0x18, 0x6c, 0x18, 0x3c, 0x31, + 0x00, 0x36, 0x14, 0x4c, 0x33, 0x06, 0x00, 0x50, 0x85, 0x8d, 0xcd, 0xae, + 0xcd, 0x25, 0x8d, 0xac, 0xcc, 0x8d, 0x6e, 0x4a, 0x10, 0x54, 0x21, 0xc3, + 0x73, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x9b, 0x12, 0x10, 0x4d, + 0xc8, 0xf0, 0x5c, 0xec, 0xc2, 0xd8, 0xec, 0xca, 0xe4, 0xa6, 0x04, 0x46, + 0x1d, 0x32, 0x3c, 0x97, 0x39, 0xb4, 0x30, 0xb2, 0x32, 0xb9, 0xa6, 0x37, + 0xb2, 0x32, 0xb6, 0x29, 0x01, 0x52, 0x87, 0x0c, 0xcf, 0xc5, 0x2e, 0xad, + 0xec, 0x2e, 0x89, 0x6c, 0x8a, 0x2e, 0x8c, 0xae, 0x6c, 0x4a, 0xa0, 0xd4, + 0x21, 0xc3, 0x73, 0x29, 0x73, 0xa3, 0x93, 0xcb, 0x83, 0x7a, 0x4b, 0x73, + 0xa3, 0x9b, 0x9b, 0x12, 0x8c, 0x01, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, + 0x00, 0x4c, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, + 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, + 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, + 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, + 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, + 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, + 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, + 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, + 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, + 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, + 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, + 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, + 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, + 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, + 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, + 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, + 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, + 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, + 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, + 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, + 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, + 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, + 0x3b, 0xb0, 0xc3, 0x0c, 0xc4, 0x21, 0x07, 0x7c, 0x70, 0x03, 0x7a, 0x28, + 0x87, 0x76, 0x80, 0x87, 0x19, 0xd1, 0x43, 0x0e, 0xf8, 0xe0, 0x06, 0xe4, + 0x20, 0x0e, 0xe7, 0xe0, 0x06, 0xf6, 0x10, 0x0e, 0xf2, 0xc0, 0x0e, 0xe1, + 0x90, 0x0f, 0xef, 0x50, 0x0f, 0xf4, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, + 0x00, 0x0b, 0x00, 0x00, 0x00, 0x16, 0x30, 0x0d, 0x97, 0xef, 0x3c, 0xfe, + 0xe2, 0x00, 0x83, 0xd8, 0x3c, 0xd4, 0xe4, 0x17, 0xb7, 0x6d, 0x02, 0xd5, + 0x70, 0xf9, 0xce, 0xe3, 0x4b, 0x93, 0x13, 0x11, 0x28, 0x35, 0x3d, 0xd4, + 0xe4, 0x17, 0xb7, 0x6d, 0x00, 0x04, 0x03, 0x20, 0x0d, 0x00, 0x00, 0x00, + 0x00, 0x61, 0x20, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, + 0x2c, 0x10, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x44, 0x85, 0x30, + 0x03, 0x50, 0x0a, 0x54, 0x25, 0x00, 0x00, 0x00, 0x00, 0x23, 0x06, 0x09, + 0x00, 0x82, 0x60, 0x60, 0x4c, 0x84, 0x03, 0x21, 0xc3, 0x88, 0x41, 0x02, + 0x80, 0x20, 0x18, 0x18, 0x54, 0xf1, 0x44, 0x02, 0x31, 0x62, 0x90, 0x00, + 0x20, 0x08, 0x06, 0x46, 0x65, 0x40, 0x52, 0x52, 0x8c, 0x18, 0x24, 0x00, + 0x08, 0x82, 0x81, 0x61, 0x1d, 0xd1, 0xd4, 0x18, 0x23, 0x06, 0x09, 0x00, + 0x82, 0x60, 0x80, 0x58, 0x06, 0x45, 0x31, 0xc4, 0x88, 0x41, 0x02, 0x80, + 0x20, 0x18, 0x20, 0x96, 0x41, 0x51, 0xc5, 0x30, 0x62, 0x90, 0x00, 0x20, + 0x08, 0x06, 0x88, 0x65, 0x50, 0xd4, 0x22, 0x8c, 0x18, 0x24, 0x00, 0x08, + 0x82, 0x01, 0x62, 0x19, 0x14, 0xe5, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00 +}; + +/* The texture-rendering pixel shader: + + --- D3D12_PixelShader_Textures.hlsl --- + Texture2D theTexture : register(t0); + SamplerState theSampler : register(s0); + + struct PixelShaderInput + { + float4 pos : SV_POSITION; + float2 tex : TEXCOORD0; + float4 color : COLOR0; + }; + + #define TextureRS \ + "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \ + " DENY_DOMAIN_SHADER_ROOT_ACCESS |" \ + " DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \ + " DENY_HULL_SHADER_ROOT_ACCESS )," \ + "RootConstants(num32BitConstants=32, b0),"\ + "DescriptorTable ( SRV(t0), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( Sampler(s0), visibility = SHADER_VISIBILITY_PIXEL )" + + [RootSignature(TextureRS)] + float4 main(PixelShaderInput input) : SV_TARGET + { + return theTexture.Sample(theSampler, input.tex) * input.color; + } +*/ + +static unsigned char D3D12_PixelShader_Textures[] = { + 0x44, 0x58, 0x42, 0x43, 0x7e, 0x22, 0x8c, 0xc3, 0x6b, 0xf9, 0xa8, 0x10, + 0xf1, 0x5f, 0x55, 0xde, 0x62, 0x56, 0x81, 0x2d, 0x01, 0x00, 0x00, 0x00, + 0x7d, 0x11, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0xdb, 0x00, 0x00, 0x00, 0x15, 0x01, 0x00, 0x00, + 0xfd, 0x01, 0x00, 0x00, 0x8d, 0x02, 0x00, 0x00, 0x6d, 0x0a, 0x00, 0x00, + 0x89, 0x0a, 0x00, 0x00, 0x53, 0x46, 0x49, 0x30, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31, + 0x83, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x53, 0x56, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, + 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x43, 0x4f, 0x4c, + 0x4f, 0x52, 0x00, 0x4f, 0x53, 0x47, 0x31, 0x32, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x00, 0x50, 0x53, 0x56, 0x30, 0xe0, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x03, 0x01, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x54, 0x45, + 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x44, + 0x03, 0x03, 0x04, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x01, 0x42, 0x00, 0x03, 0x02, 0x00, 0x00, 0x0a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, 0x03, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x44, + 0x10, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, + 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x00, 0x52, 0x54, 0x53, 0x30, 0x88, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, + 0x00, 0x70, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xff, 0xff, 0x53, 0x54, 0x41, 0x54, 0xd8, 0x07, 0x00, + 0x00, 0x60, 0x00, 0x00, 0x00, 0xf6, 0x01, 0x00, 0x00, 0x44, 0x58, 0x49, + 0x4c, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xc0, 0x07, 0x00, + 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0xed, 0x01, 0x00, + 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, + 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, + 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, + 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, + 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88, 0x48, 0x90, 0x14, + 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4, 0x48, 0x0e, + 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, + 0x8a, 0x04, 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40, 0x02, 0xa8, + 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x20, 0x6d, 0x30, 0x86, + 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x09, 0xa8, 0x00, 0x49, 0x18, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, 0x42, 0x20, 0x4c, 0x08, + 0x06, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x4a, 0x00, 0x00, + 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, + 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, + 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x70, 0x33, 0x00, 0xc3, 0x08, 0x04, + 0x30, 0x47, 0x00, 0x06, 0x33, 0xb5, 0xc1, 0x38, 0xb0, 0x43, 0x38, 0xcc, + 0xc3, 0x3c, 0xb8, 0x01, 0x2d, 0x94, 0x03, 0x3e, 0xd0, 0x43, 0x3d, 0xc8, + 0x43, 0x39, 0xc8, 0x01, 0x29, 0xf0, 0x81, 0x3d, 0x94, 0xc3, 0x38, 0xd0, + 0xc3, 0x3b, 0xc8, 0x03, 0x1f, 0x98, 0x03, 0x3b, 0xbc, 0x43, 0x38, 0xd0, + 0x03, 0x1b, 0x80, 0x01, 0x1d, 0xf8, 0x01, 0x18, 0xf8, 0x81, 0x1e, 0xe8, + 0x41, 0x3b, 0xa4, 0x03, 0x3c, 0xcc, 0xc3, 0x2f, 0xd0, 0x43, 0x3e, 0xc0, + 0x43, 0x39, 0xa0, 0x40, 0xcc, 0x24, 0x06, 0xe3, 0xc0, 0x0e, 0xe1, 0x30, + 0x0f, 0xf3, 0xe0, 0x06, 0xb4, 0x50, 0x0e, 0xf8, 0x40, 0x0f, 0xf5, 0x20, + 0x0f, 0xe5, 0x20, 0x07, 0xa4, 0xc0, 0x07, 0xf6, 0x50, 0x0e, 0xe3, 0x40, + 0x0f, 0xef, 0x20, 0x0f, 0x7c, 0x60, 0x0e, 0xec, 0xf0, 0x0e, 0xe1, 0x40, + 0x0f, 0x6c, 0x00, 0x06, 0x74, 0xe0, 0x07, 0x60, 0xe0, 0x07, 0x48, 0x08, + 0x83, 0xc8, 0x4d, 0xd2, 0x14, 0x51, 0xc2, 0xe4, 0xb3, 0x00, 0xf3, 0x2c, + 0x44, 0xc4, 0x4e, 0xc0, 0x44, 0xa0, 0x40, 0x90, 0x19, 0x01, 0x28, 0x01, + 0xa2, 0x34, 0x47, 0x80, 0x14, 0x03, 0x08, 0x21, 0x96, 0x20, 0x56, 0x0c, + 0x24, 0x84, 0x58, 0x80, 0xdc, 0x4d, 0xc3, 0xe5, 0x4f, 0xd8, 0x43, 0x48, + 0xfe, 0x4a, 0x48, 0x2b, 0x31, 0xf9, 0xc5, 0x6d, 0xa3, 0x02, 0x00, 0x00, + 0x04, 0xad, 0x7b, 0x86, 0xcb, 0x9f, 0xb0, 0x87, 0x90, 0xfc, 0x10, 0x68, + 0x86, 0x85, 0x40, 0x41, 0x2c, 0x0c, 0x14, 0x52, 0x02, 0x00, 0x80, 0x10, + 0x02, 0xd0, 0x9c, 0x23, 0x08, 0x8a, 0x21, 0xc5, 0x12, 0xa2, 0x92, 0x1d, + 0x08, 0x18, 0x46, 0x10, 0x80, 0xbb, 0xa4, 0x29, 0xa2, 0x84, 0xc9, 0x4f, + 0x91, 0x8b, 0x58, 0xd8, 0x03, 0x18, 0x88, 0x48, 0x6c, 0x1e, 0x6a, 0x42, + 0x43, 0xc8, 0x21, 0x1d, 0x04, 0x00, 0x00, 0x00, 0x00, 0x13, 0x14, 0x72, + 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, 0x79, 0x68, 0x03, 0x72, + 0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e, 0x6d, 0xd0, 0x0e, 0x7a, 0x50, 0x0e, + 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, + 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, + 0x78, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, + 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, + 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, + 0x74, 0xd0, 0x06, 0xe6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, + 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, + 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0xe0, 0x0e, + 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, + 0x76, 0x40, 0x07, 0x3a, 0x0f, 0x64, 0x90, 0x21, 0x23, 0x45, 0x44, 0x00, + 0x72, 0x00, 0xc0, 0xf4, 0x00, 0x80, 0x87, 0x3c, 0x09, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x79, 0x18, 0x20, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf2, 0x38, 0x40, + 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xe4, 0x99, + 0x80, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xc8, + 0x63, 0x01, 0x01, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x16, 0x08, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, + 0x18, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, + 0x5a, 0x05, 0x42, 0xa2, 0x04, 0x46, 0x00, 0x8a, 0xa1, 0x08, 0x4a, 0xa2, + 0x50, 0xca, 0xa0, 0x1c, 0x0a, 0xa4, 0x10, 0x4a, 0xa1, 0xc0, 0x0a, 0xa8, + 0x3c, 0x8a, 0x85, 0x56, 0x11, 0x8c, 0x00, 0x14, 0x42, 0x19, 0x94, 0x04, + 0x9d, 0x19, 0x00, 0x2a, 0x33, 0x00, 0x44, 0x66, 0x00, 0x68, 0xcc, 0x00, + 0x50, 0x98, 0x01, 0x20, 0x3d, 0x03, 0x40, 0x7b, 0x2c, 0x87, 0x21, 0x00, + 0x00, 0x00, 0x9e, 0x07, 0x00, 0x02, 0x81, 0x40, 0x00, 0x79, 0x18, 0x00, + 0x00, 0xb7, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, + 0x44, 0x35, 0x18, 0x63, 0x0b, 0x73, 0x3b, 0x03, 0xb1, 0x2b, 0x93, 0x9b, + 0x4b, 0x7b, 0x73, 0x03, 0x99, 0x71, 0xb9, 0x01, 0x41, 0xa1, 0x0b, 0x3b, + 0x9b, 0x7b, 0x91, 0x2a, 0x62, 0x2a, 0x0a, 0x9a, 0x2a, 0xfa, 0x9a, 0xb9, + 0x81, 0x79, 0x31, 0x4b, 0x73, 0x0b, 0x63, 0x4b, 0xd9, 0x10, 0x04, 0x13, + 0x04, 0x01, 0x99, 0x20, 0x08, 0xc9, 0x06, 0x61, 0x20, 0x36, 0x08, 0x04, + 0x41, 0x01, 0x6e, 0x6e, 0x82, 0x20, 0x28, 0x1b, 0x86, 0x03, 0x21, 0x26, + 0x08, 0x45, 0x47, 0x85, 0x0e, 0xad, 0x8c, 0xaa, 0x0c, 0x8f, 0xae, 0x4e, + 0xae, 0x6c, 0x82, 0x20, 0x2c, 0x13, 0x04, 0x81, 0xd9, 0x20, 0x10, 0xcd, + 0x86, 0x84, 0x50, 0x16, 0x82, 0x18, 0x18, 0xc2, 0xd9, 0x10, 0x3c, 0x13, + 0x84, 0x83, 0xa3, 0x42, 0x87, 0x56, 0x36, 0x15, 0xd6, 0x06, 0xc7, 0x56, + 0x26, 0xb7, 0x01, 0x21, 0x22, 0x89, 0x20, 0x06, 0x02, 0xd8, 0x10, 0x4c, + 0x1b, 0x08, 0x08, 0x00, 0xa8, 0x09, 0x02, 0xe1, 0x4d, 0x10, 0x84, 0x86, + 0x01, 0xda, 0x04, 0x41, 0x70, 0x26, 0x08, 0xc2, 0xb3, 0xc1, 0x40, 0xb0, + 0x8c, 0xd0, 0x1a, 0x12, 0x6d, 0x69, 0x70, 0x73, 0x13, 0x04, 0x01, 0xda, + 0x40, 0x20, 0x5c, 0xd6, 0x4d, 0x10, 0x02, 0x30, 0xd8, 0x20, 0x10, 0xdf, + 0x86, 0x00, 0x0c, 0x36, 0x08, 0x44, 0x18, 0x6c, 0x20, 0xae, 0xcd, 0x13, + 0x83, 0x09, 0xc2, 0xf0, 0x4d, 0x10, 0x84, 0x88, 0x06, 0x5a, 0x98, 0x1b, + 0x19, 0x5b, 0xd9, 0x04, 0x41, 0x90, 0x36, 0x18, 0x88, 0x19, 0x64, 0x84, + 0x76, 0x06, 0x1b, 0x84, 0x32, 0x40, 0x83, 0x09, 0x82, 0x16, 0x06, 0x13, + 0x04, 0x61, 0xe2, 0x00, 0xf7, 0x36, 0xc7, 0x65, 0xca, 0xea, 0x0b, 0xea, + 0x69, 0x2a, 0x89, 0x2a, 0xe9, 0xc9, 0x69, 0x03, 0x82, 0xb0, 0x41, 0x46, + 0x94, 0x41, 0x1b, 0x68, 0x0d, 0x07, 0xba, 0x32, 0x3c, 0x26, 0x54, 0x45, + 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x30, 0x1b, 0x10, 0xe4, 0x0d, 0xb2, + 0xae, 0x0c, 0xe0, 0x40, 0x6b, 0x58, 0x8c, 0xbd, 0xb1, 0xbd, 0xc9, 0x4d, + 0x10, 0x04, 0x8a, 0xc6, 0xd0, 0x13, 0xd3, 0x93, 0x14, 0xcc, 0x06, 0x04, + 0x91, 0x83, 0x6c, 0x0e, 0xca, 0x80, 0x0e, 0xb4, 0x66, 0x03, 0xb1, 0x06, + 0x6e, 0x10, 0x07, 0x75, 0xb0, 0xe1, 0x20, 0xac, 0x31, 0x20, 0x83, 0x34, + 0x50, 0x03, 0x3b, 0x98, 0x20, 0x28, 0xc2, 0x06, 0x60, 0xc3, 0x40, 0xe4, + 0x41, 0x1e, 0x6c, 0x08, 0xf4, 0x60, 0xc3, 0x30, 0xe0, 0xc1, 0x1e, 0x4c, + 0x10, 0x36, 0x31, 0xd8, 0x10, 0xf4, 0x01, 0x89, 0xb6, 0xb0, 0x34, 0x37, + 0x2e, 0x53, 0x56, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x13, 0x84, 0x65, 0x9b, 0x20, 0x2c, 0xda, 0x86, 0x80, 0x98, 0x20, 0x2c, + 0xd9, 0x04, 0x61, 0xc1, 0x36, 0x2c, 0x04, 0x28, 0x84, 0x82, 0x28, 0x8c, + 0x02, 0x29, 0x0c, 0xa4, 0x40, 0x94, 0x02, 0x40, 0x84, 0xaa, 0x08, 0x6b, + 0xe8, 0xe9, 0x49, 0x8a, 0x68, 0x82, 0xb0, 0x5c, 0x1b, 0x84, 0x2c, 0xdb, + 0xb0, 0x0c, 0xa7, 0x10, 0x0a, 0xa5, 0x30, 0x0a, 0xa8, 0x30, 0xa0, 0xc2, + 0x50, 0x0a, 0xa9, 0xc0, 0x62, 0xe8, 0x89, 0xe9, 0x49, 0x6a, 0x82, 0x20, + 0x54, 0x1b, 0x84, 0x8c, 0x15, 0x36, 0x2c, 0xcc, 0x2a, 0x84, 0x42, 0x29, + 0x8c, 0x02, 0x2a, 0x0c, 0xa4, 0xc0, 0x94, 0x42, 0x2b, 0x6c, 0x18, 0x4c, + 0x41, 0x15, 0x5c, 0x81, 0xc9, 0x94, 0xd5, 0x17, 0x55, 0x98, 0xdc, 0x59, + 0x19, 0xdd, 0x04, 0x61, 0x39, 0x36, 0x2c, 0x04, 0x2c, 0x84, 0x42, 0x2c, + 0x8c, 0x42, 0x29, 0x0c, 0xa4, 0x40, 0x94, 0x42, 0x2b, 0x6c, 0x08, 0x64, + 0x61, 0xc3, 0xf0, 0x0a, 0xb3, 0x00, 0x6c, 0x28, 0xf0, 0xe0, 0x0f, 0x68, + 0xa1, 0x02, 0x68, 0x98, 0xb1, 0xbd, 0x85, 0xd1, 0xcd, 0xb1, 0x48, 0x73, + 0x9b, 0xa3, 0x9b, 0x9b, 0x20, 0x08, 0x16, 0x8d, 0xb9, 0xb4, 0xb3, 0x2f, + 0x36, 0x32, 0x1a, 0x73, 0x69, 0x67, 0x5f, 0x73, 0x74, 0x44, 0xe8, 0xca, + 0xf0, 0xbe, 0xdc, 0xde, 0xe4, 0xda, 0x36, 0x28, 0xb6, 0x50, 0x06, 0xb7, + 0x80, 0x0b, 0xb9, 0x80, 0xe8, 0x42, 0x19, 0xec, 0xc2, 0x50, 0x85, 0x8d, + 0xcd, 0xae, 0xcd, 0x25, 0x8d, 0xac, 0xcc, 0x8d, 0x6e, 0x4a, 0x10, 0x54, + 0x21, 0xc3, 0x73, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x9b, 0x12, + 0x10, 0x4d, 0xc8, 0xf0, 0x5c, 0xec, 0xc2, 0xd8, 0xec, 0xca, 0xe4, 0xa6, + 0x04, 0x45, 0x1d, 0x32, 0x3c, 0x97, 0x39, 0xb4, 0x30, 0xb2, 0x32, 0xb9, + 0xa6, 0x37, 0xb2, 0x32, 0xb6, 0x29, 0x01, 0x52, 0x86, 0x0c, 0xcf, 0x45, + 0xae, 0x6c, 0xee, 0xad, 0x4e, 0x6e, 0xac, 0x6c, 0x6e, 0x4a, 0x40, 0x55, + 0x22, 0xc3, 0x73, 0xa1, 0xcb, 0x83, 0x2b, 0x0b, 0x72, 0x73, 0x7b, 0xa3, + 0x0b, 0xa3, 0x4b, 0x7b, 0x73, 0x9b, 0x9b, 0x22, 0xd8, 0xc1, 0x1e, 0xd4, + 0x21, 0xc3, 0x73, 0xb1, 0x4b, 0x2b, 0xbb, 0x4b, 0x22, 0x9b, 0xa2, 0x0b, + 0xa3, 0x2b, 0x9b, 0x12, 0xf4, 0x41, 0x1d, 0x32, 0x3c, 0x97, 0x32, 0x37, + 0x3a, 0xb9, 0x3c, 0xa8, 0xb7, 0x34, 0x37, 0xba, 0xb9, 0x29, 0x01, 0x2d, + 0x74, 0x21, 0xc3, 0x73, 0x19, 0x7b, 0xab, 0x73, 0xa3, 0x2b, 0x93, 0x9b, + 0x9b, 0x12, 0xec, 0x02, 0x00, 0x79, 0x18, 0x00, 0x00, 0x4c, 0x00, 0x00, + 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, + 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, + 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, + 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, + 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, + 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, + 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, + 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, + 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, + 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, + 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, + 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, + 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, + 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, + 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, + 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, + 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, + 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, + 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, + 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, + 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, + 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, + 0xc4, 0x21, 0x07, 0x7c, 0x70, 0x03, 0x7a, 0x28, 0x87, 0x76, 0x80, 0x87, + 0x19, 0xd1, 0x43, 0x0e, 0xf8, 0xe0, 0x06, 0xe4, 0x20, 0x0e, 0xe7, 0xe0, + 0x06, 0xf6, 0x10, 0x0e, 0xf2, 0xc0, 0x0e, 0xe1, 0x90, 0x0f, 0xef, 0x50, + 0x0f, 0xf4, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x24, 0x00, 0x00, + 0x00, 0x15, 0xf0, 0x05, 0x7e, 0x74, 0x74, 0x79, 0x1a, 0x6e, 0xc3, 0xd9, + 0x65, 0x39, 0x10, 0x38, 0xab, 0x4e, 0xc3, 0x6d, 0x38, 0xbb, 0x2c, 0x9f, + 0xd2, 0xc3, 0xf4, 0x32, 0x10, 0x18, 0x2c, 0x80, 0x37, 0x08, 0xfc, 0xe8, + 0xe8, 0x32, 0xb5, 0x8c, 0xa7, 0xd7, 0xe5, 0x65, 0x20, 0x70, 0x66, 0xfd, + 0x91, 0xa8, 0x65, 0x3c, 0xbd, 0x2e, 0x2f, 0xcb, 0x88, 0x40, 0xeb, 0x8f, + 0x64, 0x2f, 0x8f, 0xe9, 0x6f, 0x39, 0xb0, 0x49, 0x82, 0xcd, 0x80, 0x40, + 0x20, 0x30, 0x68, 0x06, 0xd2, 0x70, 0xf9, 0xce, 0xe3, 0x0b, 0x11, 0x01, + 0x4c, 0x44, 0x08, 0x34, 0xc3, 0x42, 0xd8, 0xc0, 0x34, 0x5c, 0xbe, 0xf3, + 0xf8, 0x8b, 0x03, 0x0c, 0x62, 0xf3, 0x50, 0x93, 0x5f, 0xdc, 0xb6, 0x15, + 0x40, 0xc3, 0xe5, 0x3b, 0x8f, 0x2f, 0x01, 0xcc, 0xb3, 0x10, 0x7e, 0x71, + 0xdb, 0x46, 0x50, 0x0d, 0x97, 0xef, 0x3c, 0xbe, 0x34, 0x39, 0x11, 0x81, + 0x52, 0xd3, 0x43, 0x4d, 0x7e, 0x71, 0xdb, 0x26, 0x40, 0x30, 0x00, 0xd2, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x14, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xa4, 0x51, 0x7f, 0xb4, 0x3e, 0x6a, + 0xe5, 0x04, 0x66, 0x2e, 0x73, 0x80, 0x43, 0xf2, 0xb2, 0x44, 0x58, 0x49, + 0x4c, 0xec, 0x06, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xbb, 0x01, 0x00, + 0x00, 0x44, 0x58, 0x49, 0x4c, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0xd4, 0x06, 0x00, 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, + 0x00, 0xb2, 0x01, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, + 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, + 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, + 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, + 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, + 0x42, 0xe4, 0x48, 0x0e, 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, + 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, + 0x07, 0x40, 0x02, 0xa8, 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, + 0x20, 0x6d, 0x30, 0x86, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x09, 0xa8, + 0x00, 0x49, 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, + 0x42, 0x20, 0x4c, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, + 0x00, 0x43, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, + 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, + 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x68, 0x23, + 0x00, 0x25, 0x00, 0x14, 0x66, 0x00, 0xe6, 0x08, 0xc0, 0x60, 0x8e, 0x00, + 0x29, 0xc6, 0x20, 0x84, 0x14, 0x42, 0xa6, 0x18, 0x80, 0x10, 0x52, 0x06, + 0xa1, 0x9b, 0x86, 0xcb, 0x9f, 0xb0, 0x87, 0x90, 0xfc, 0x95, 0x90, 0x56, + 0x62, 0xf2, 0x8b, 0xdb, 0x46, 0xc5, 0x18, 0x63, 0x10, 0x2a, 0xf7, 0x0c, + 0x97, 0x3f, 0x61, 0x0f, 0x21, 0xf9, 0x21, 0xd0, 0x0c, 0x0b, 0x81, 0x82, + 0x55, 0x18, 0x45, 0x18, 0x1b, 0x63, 0x0c, 0x42, 0xc8, 0xa0, 0x36, 0x47, + 0x10, 0x14, 0x83, 0x91, 0x42, 0xc8, 0x23, 0x38, 0x10, 0x30, 0x8c, 0x40, + 0x0c, 0x33, 0xb5, 0xc1, 0x38, 0xb0, 0x43, 0x38, 0xcc, 0xc3, 0x3c, 0xb8, + 0x01, 0x2d, 0x94, 0x03, 0x3e, 0xd0, 0x43, 0x3d, 0xc8, 0x43, 0x39, 0xc8, + 0x01, 0x29, 0xf0, 0x81, 0x3d, 0x94, 0xc3, 0x38, 0xd0, 0xc3, 0x3b, 0xc8, + 0x03, 0x1f, 0x98, 0x03, 0x3b, 0xbc, 0x43, 0x38, 0xd0, 0x03, 0x1b, 0x80, + 0x01, 0x1d, 0xf8, 0x01, 0x18, 0xf8, 0x81, 0x1e, 0xe8, 0x41, 0x3b, 0xa4, + 0x03, 0x3c, 0xcc, 0xc3, 0x2f, 0xd0, 0x43, 0x3e, 0xc0, 0x43, 0x39, 0xa0, + 0x80, 0xcc, 0x24, 0x06, 0xe3, 0xc0, 0x0e, 0xe1, 0x30, 0x0f, 0xf3, 0xe0, + 0x06, 0xb4, 0x50, 0x0e, 0xf8, 0x40, 0x0f, 0xf5, 0x20, 0x0f, 0xe5, 0x20, + 0x07, 0xa4, 0xc0, 0x07, 0xf6, 0x50, 0x0e, 0xe3, 0x40, 0x0f, 0xef, 0x20, + 0x0f, 0x7c, 0x60, 0x0e, 0xec, 0xf0, 0x0e, 0xe1, 0x40, 0x0f, 0x6c, 0x00, + 0x06, 0x74, 0xe0, 0x07, 0x60, 0xe0, 0x07, 0x48, 0x98, 0x94, 0xea, 0x4d, + 0xd2, 0x14, 0x51, 0xc2, 0xe4, 0xb3, 0x00, 0xf3, 0x2c, 0x44, 0xc4, 0x4e, + 0xc0, 0x44, 0xa0, 0x80, 0xd0, 0x4d, 0x07, 0x02, 0x00, 0x13, 0x14, 0x72, + 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, 0x79, 0x68, 0x03, 0x72, + 0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e, 0x6d, 0xd0, 0x0e, 0x7a, 0x50, 0x0e, + 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, + 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, + 0x78, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, + 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, + 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, + 0x74, 0xd0, 0x06, 0xe6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, + 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, + 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0xe0, 0x0e, + 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, + 0x76, 0x40, 0x07, 0x43, 0x9e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x86, 0x3c, 0x06, 0x10, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x79, 0x10, 0x20, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf2, 0x34, 0x40, 0x00, 0x0c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xe4, 0x81, 0x80, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0b, 0x04, 0x00, + 0x00, 0x0f, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x14, 0x19, 0x11, 0x4c, + 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x22, 0x25, 0x30, 0x02, + 0x50, 0x0c, 0x45, 0x50, 0x12, 0x65, 0x50, 0x1e, 0x54, 0x4a, 0xa2, 0x0c, + 0x0a, 0x61, 0x04, 0xa0, 0x08, 0x0a, 0x84, 0xec, 0x0c, 0x00, 0xe1, 0x19, + 0x00, 0xca, 0x63, 0x39, 0x0c, 0x01, 0x00, 0x00, 0xf0, 0x3c, 0x00, 0x10, + 0x08, 0x04, 0x02, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x63, 0x00, 0x00, + 0x00, 0x1a, 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, 0x44, 0x35, 0x18, 0x63, + 0x0b, 0x73, 0x3b, 0x03, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x03, + 0x99, 0x71, 0xb9, 0x01, 0x41, 0xa1, 0x0b, 0x3b, 0x9b, 0x7b, 0x91, 0x2a, + 0x62, 0x2a, 0x0a, 0x9a, 0x2a, 0xfa, 0x9a, 0xb9, 0x81, 0x79, 0x31, 0x4b, + 0x73, 0x0b, 0x63, 0x4b, 0xd9, 0x10, 0x04, 0x13, 0x04, 0xa2, 0x98, 0x20, + 0x10, 0xc6, 0x06, 0x61, 0x20, 0x26, 0x08, 0xc4, 0xb1, 0x41, 0x18, 0x0c, + 0x0a, 0x70, 0x73, 0x1b, 0x06, 0xc4, 0x20, 0x26, 0x08, 0x96, 0x44, 0x60, + 0x82, 0x40, 0x20, 0x13, 0x04, 0x22, 0xd9, 0x20, 0x10, 0xcd, 0x86, 0x84, + 0x50, 0x16, 0x82, 0x18, 0x18, 0xc2, 0xd9, 0x10, 0x3c, 0x13, 0x04, 0x6c, + 0xda, 0x80, 0x10, 0xd1, 0x42, 0x10, 0x03, 0x01, 0x6c, 0x08, 0xa4, 0x0d, + 0x04, 0x04, 0x00, 0xd3, 0x04, 0x21, 0xa3, 0x36, 0x04, 0xd5, 0x04, 0x41, + 0x00, 0x48, 0xb4, 0x85, 0xa5, 0xb9, 0x71, 0x99, 0xb2, 0xfa, 0x82, 0x7a, + 0x9b, 0x4b, 0xa3, 0x4b, 0x7b, 0x73, 0x9b, 0x20, 0x14, 0xcc, 0x04, 0xa1, + 0x68, 0x36, 0x04, 0xc4, 0x04, 0xa1, 0x70, 0x26, 0x08, 0xc5, 0xb3, 0x61, + 0x21, 0x32, 0x6d, 0xe3, 0xba, 0xa1, 0x23, 0x3c, 0x80, 0x08, 0x55, 0x11, + 0xd6, 0xd0, 0xd3, 0x93, 0x14, 0xd1, 0x04, 0xa1, 0x80, 0x26, 0x08, 0x84, + 0xb2, 0x41, 0x10, 0x03, 0x31, 0xd8, 0xb0, 0x0c, 0x60, 0xa0, 0x79, 0x5c, + 0x18, 0x0c, 0x61, 0x30, 0x78, 0x63, 0xc0, 0x62, 0xe8, 0x89, 0xe9, 0x49, + 0x6a, 0x82, 0x40, 0x2c, 0x1b, 0x04, 0x31, 0x30, 0x83, 0x0d, 0x0b, 0x53, + 0x06, 0x9a, 0xc7, 0x85, 0xc1, 0xd0, 0x31, 0xde, 0x19, 0x6c, 0x18, 0x3e, + 0x32, 0x40, 0x03, 0x26, 0x53, 0x56, 0x5f, 0x54, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x13, 0x84, 0x22, 0xda, 0xb0, 0x10, 0x6a, 0xa0, 0xad, 0x01, 0xe7, + 0x0d, 0x1d, 0xe1, 0x9d, 0xc1, 0x86, 0x80, 0x0d, 0x36, 0x0c, 0x69, 0xd0, + 0x06, 0xc0, 0x86, 0xe2, 0xc2, 0xdc, 0x80, 0x02, 0xaa, 0xb0, 0xb1, 0xd9, + 0xb5, 0xb9, 0xa4, 0x91, 0x95, 0xb9, 0xd1, 0x4d, 0x09, 0x82, 0x2a, 0x64, + 0x78, 0x2e, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x02, 0xa2, + 0x09, 0x19, 0x9e, 0x8b, 0x5d, 0x18, 0x9b, 0x5d, 0x99, 0xdc, 0x94, 0xc0, + 0xa8, 0x43, 0x86, 0xe7, 0x32, 0x87, 0x16, 0x46, 0x56, 0x26, 0xd7, 0xf4, + 0x46, 0x56, 0xc6, 0x36, 0x25, 0x40, 0xca, 0x90, 0xe1, 0xb9, 0xc8, 0x95, + 0xcd, 0xbd, 0xd5, 0xc9, 0x8d, 0x95, 0xcd, 0x4d, 0x09, 0xa6, 0x3a, 0x64, + 0x78, 0x2e, 0x76, 0x69, 0x65, 0x77, 0x49, 0x64, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x53, 0x82, 0xaa, 0x0e, 0x19, 0x9e, 0x4b, 0x99, 0x1b, 0x9d, 0x5c, + 0x1e, 0xd4, 0x5b, 0x9a, 0x1b, 0xdd, 0xdc, 0x94, 0xc0, 0x0d, 0x00, 0x00, + 0x00, 0x79, 0x18, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, + 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, + 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, + 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, + 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, + 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, + 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, + 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, + 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, + 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, + 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, + 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, + 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, + 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, + 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, + 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, + 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, + 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, + 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, + 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, + 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, + 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, + 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc4, 0x21, 0x07, 0x7c, + 0x70, 0x03, 0x7a, 0x28, 0x87, 0x76, 0x80, 0x87, 0x19, 0xd1, 0x43, 0x0e, + 0xf8, 0xe0, 0x06, 0xe4, 0x20, 0x0e, 0xe7, 0xe0, 0x06, 0xf6, 0x10, 0x0e, + 0xf2, 0xc0, 0x0e, 0xe1, 0x90, 0x0f, 0xef, 0x50, 0x0f, 0xf4, 0x00, 0x00, + 0x00, 0x71, 0x20, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x46, 0x20, 0x0d, + 0x97, 0xef, 0x3c, 0xbe, 0x10, 0x11, 0xc0, 0x44, 0x84, 0x40, 0x33, 0x2c, + 0x84, 0x05, 0x4c, 0xc3, 0xe5, 0x3b, 0x8f, 0xbf, 0x38, 0xc0, 0x20, 0x36, + 0x0f, 0x35, 0xf9, 0xc5, 0x6d, 0xdb, 0x00, 0x34, 0x5c, 0xbe, 0xf3, 0xf8, + 0x12, 0xc0, 0x3c, 0x0b, 0xe1, 0x17, 0xb7, 0x6d, 0x02, 0xd5, 0x70, 0xf9, + 0xce, 0xe3, 0x4b, 0x93, 0x13, 0x11, 0x28, 0x35, 0x3d, 0xd4, 0xe4, 0x17, + 0xb7, 0x6d, 0x00, 0x04, 0x03, 0x20, 0x0d, 0x00, 0x00, 0x61, 0x20, 0x00, + 0x00, 0x3a, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, + 0x00, 0x05, 0x00, 0x00, 0x00, 0xf4, 0x46, 0x00, 0x88, 0xcc, 0x00, 0x14, + 0x42, 0x29, 0x94, 0x5c, 0xe1, 0x51, 0x29, 0x01, 0x1a, 0x33, 0x00, 0x00, + 0x00, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x00, 0x65, 0x84, 0x73, 0x5d, + 0xc8, 0x88, 0x41, 0x02, 0x80, 0x20, 0x18, 0x40, 0x5a, 0x11, 0x61, 0x58, + 0x32, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x86, 0x87, 0x5c, 0x19, 0x94, + 0x8c, 0x18, 0x24, 0x00, 0x08, 0x82, 0x81, 0xf1, 0x25, 0x98, 0x56, 0x28, + 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x60, 0x80, 0x81, 0x92, 0x6d, 0xd1, + 0x32, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x46, 0x18, 0x2c, 0x1a, 0x57, + 0x31, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x60, 0x88, 0x01, 0xe3, 0x75, + 0x54, 0x33, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0xc6, 0x18, 0x34, 0x9f, + 0x97, 0x38, 0x23, 0x06, 0x0f, 0x00, 0x82, 0x60, 0xd0, 0x88, 0xc1, 0x82, + 0x1c, 0x42, 0x90, 0x24, 0xdf, 0xf7, 0x24, 0xa3, 0x09, 0x01, 0x30, 0x9a, + 0x20, 0x04, 0xa3, 0x09, 0x83, 0x30, 0x9a, 0x40, 0x0c, 0x46, 0x2c, 0xf2, + 0x31, 0x62, 0x91, 0x8f, 0x11, 0x8b, 0x7c, 0x8c, 0x58, 0xe4, 0x33, 0x62, + 0x90, 0x00, 0x20, 0x08, 0x06, 0x08, 0x1b, 0x58, 0x68, 0x80, 0x06, 0x1f, + 0x31, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x08, 0x1b, 0x58, 0x68, 0x80, + 0x06, 0xd3, 0x30, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x08, 0x1b, 0x58, + 0x68, 0x80, 0x06, 0x9e, 0x30, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x08, + 0x1b, 0x58, 0x68, 0x80, 0x06, 0x61, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00 +}; + +/* The yuv-rendering pixel shader: + + --- D3D12_PixelShader_YUV_JPEG.hlsl --- + Texture2D theTextureY : register(t0); + Texture2D theTextureU : register(t1); + Texture2D theTextureV : register(t2); + SamplerState theSampler : register(s0); + + struct PixelShaderInput + { + float4 pos : SV_POSITION; + float2 tex : TEXCOORD0; + float4 color : COLOR0; + }; + + #define YUVRS \ + "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \ + " DENY_DOMAIN_SHADER_ROOT_ACCESS |" \ + " DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \ + " DENY_HULL_SHADER_ROOT_ACCESS )," \ + "RootConstants(num32BitConstants=32, b0),"\ + "DescriptorTable ( SRV(t0), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( SRV(t1), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( SRV(t2), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( Sampler(s0), visibility = SHADER_VISIBILITY_PIXEL )" + + [RootSignature(YUVRS)] + float4 main(PixelShaderInput input) : SV_TARGET + { + const float3 offset = {0.0, -0.501960814, -0.501960814}; + const float3 Rcoeff = {1.0000, 0.0000, 1.4020}; + const float3 Gcoeff = {1.0000, -0.3441, -0.7141}; + const float3 Bcoeff = {1.0000, 1.7720, 0.0000}; + + float4 Output; + + float3 yuv; + yuv.x = theTextureY.Sample(theSampler, input.tex).r; + yuv.y = theTextureU.Sample(theSampler, input.tex).r; + yuv.z = theTextureV.Sample(theSampler, input.tex).r; + + yuv += offset; + Output.r = dot(yuv, Rcoeff); + Output.g = dot(yuv, Gcoeff); + Output.b = dot(yuv, Bcoeff); + Output.a = 1.0f; + + return Output * input.color; + } + +*/ + +static unsigned char D3D12_PixelShader_YUV_JPEG[] = { + 0x44, 0x58, 0x42, 0x43, 0xb1, 0xef, 0x39, 0xc1, 0xc8, 0x72, 0xbb, 0xb0, + 0x20, 0x73, 0xd6, 0x2a, 0xc9, 0xba, 0xcb, 0x70, 0x01, 0x00, 0x00, 0x00, + 0x95, 0x13, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0xdb, 0x00, 0x00, 0x00, 0x15, 0x01, 0x00, 0x00, + 0x1d, 0x02, 0x00, 0x00, 0x05, 0x03, 0x00, 0x00, 0x9d, 0x0b, 0x00, 0x00, + 0xb9, 0x0b, 0x00, 0x00, 0x53, 0x46, 0x49, 0x30, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31, + 0x83, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x53, 0x56, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, + 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x43, 0x4f, 0x4c, + 0x4f, 0x52, 0x00, 0x4f, 0x53, 0x47, 0x31, 0x32, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x00, 0x50, 0x53, 0x56, 0x30, 0x00, 0x01, 0x00, 0x00, 0x24, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x03, 0x01, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, + 0x52, 0x44, 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x44, 0x03, 0x03, 0x04, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x42, + 0x00, 0x03, 0x02, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x02, 0x44, 0x00, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x44, 0x10, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x52, 0x54, 0x53, 0x30, 0xe0, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x05, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xe0, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x05, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x05, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x05, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x05, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0xff, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, + 0x00, 0xc8, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xff, 0xff, 0x53, 0x54, 0x41, 0x54, 0x90, 0x08, 0x00, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x24, 0x02, 0x00, 0x00, 0x44, 0x58, 0x49, + 0x4c, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x78, 0x08, 0x00, + 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x1b, 0x02, 0x00, + 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, + 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, + 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, + 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, + 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88, 0x48, 0x90, 0x14, + 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4, 0x48, 0x0e, + 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, + 0x8a, 0x04, 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40, 0x02, 0xa8, + 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x20, 0x6d, 0x30, 0x86, + 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x09, 0xa8, 0x00, 0x49, 0x18, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, 0x42, 0x20, 0x4c, 0x08, + 0x06, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x4b, 0x00, 0x00, + 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, + 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, + 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x78, 0x33, 0x00, 0xc3, 0x08, 0x04, + 0x30, 0x47, 0x00, 0x06, 0x33, 0xb5, 0xc1, 0x38, 0xb0, 0x43, 0x38, 0xcc, + 0xc3, 0x3c, 0xb8, 0x01, 0x2d, 0x94, 0x03, 0x3e, 0xd0, 0x43, 0x3d, 0xc8, + 0x43, 0x39, 0xc8, 0x01, 0x29, 0xf0, 0x81, 0x3d, 0x94, 0xc3, 0x38, 0xd0, + 0xc3, 0x3b, 0xc8, 0x03, 0x1f, 0x98, 0x03, 0x3b, 0xbc, 0x43, 0x38, 0xd0, + 0x03, 0x1b, 0x80, 0x01, 0x1d, 0xf8, 0x01, 0x18, 0xf8, 0x81, 0x1e, 0xe8, + 0x41, 0x3b, 0xa4, 0x03, 0x3c, 0xcc, 0xc3, 0x2f, 0xd0, 0x43, 0x3e, 0xc0, + 0x43, 0x39, 0xa0, 0x40, 0xcc, 0x24, 0x06, 0xe3, 0xc0, 0x0e, 0xe1, 0x30, + 0x0f, 0xf3, 0xe0, 0x06, 0xb4, 0x50, 0x0e, 0xf8, 0x40, 0x0f, 0xf5, 0x20, + 0x0f, 0xe5, 0x20, 0x07, 0xa4, 0xc0, 0x07, 0xf6, 0x50, 0x0e, 0xe3, 0x40, + 0x0f, 0xef, 0x20, 0x0f, 0x7c, 0x60, 0x0e, 0xec, 0xf0, 0x0e, 0xe1, 0x40, + 0x0f, 0x6c, 0x00, 0x06, 0x74, 0xe0, 0x07, 0x60, 0xe0, 0x07, 0x48, 0x08, + 0x83, 0xc8, 0x4d, 0xd2, 0x14, 0x51, 0xc2, 0xe4, 0xb3, 0x00, 0xf3, 0x2c, + 0x44, 0xc4, 0x4e, 0xc0, 0x44, 0xa0, 0x40, 0x90, 0x19, 0x01, 0x28, 0x01, + 0xa2, 0x34, 0x47, 0x80, 0x14, 0x03, 0x08, 0x21, 0x96, 0x20, 0x56, 0x0c, + 0x24, 0x84, 0x58, 0x80, 0xdc, 0x4d, 0xc3, 0xe5, 0x4f, 0xd8, 0x43, 0x48, + 0xfe, 0x4a, 0x48, 0x2b, 0x31, 0xf9, 0xc5, 0x6d, 0xa3, 0x02, 0x00, 0x00, + 0x04, 0xad, 0x7b, 0x86, 0xcb, 0x9f, 0xb0, 0x87, 0x90, 0xfc, 0x10, 0x68, + 0x86, 0x85, 0x40, 0x41, 0x2c, 0x0c, 0x14, 0x52, 0x02, 0x00, 0x80, 0x10, + 0x02, 0xd0, 0x2c, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0xd5, 0x39, 0x82, + 0xa0, 0x18, 0x52, 0x2c, 0x21, 0x2e, 0xe1, 0x81, 0x80, 0x61, 0x04, 0x01, + 0xb8, 0x4b, 0x9a, 0x22, 0x4a, 0x98, 0xfc, 0x14, 0xb9, 0x88, 0x85, 0x3d, + 0x80, 0x81, 0x88, 0xc4, 0xe6, 0xa1, 0x26, 0x34, 0x84, 0x1d, 0xd2, 0x41, + 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, + 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e, 0x6d, 0xd0, + 0x0e, 0x7a, 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, + 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, + 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, + 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x10, 0x07, 0x76, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x3a, 0x0f, 0x64, 0x90, 0x21, + 0x23, 0x45, 0x44, 0x00, 0x72, 0x00, 0xc0, 0xe4, 0x00, 0x80, 0xc9, 0x01, + 0x00, 0xd3, 0x03, 0x00, 0x1e, 0xf2, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xe4, 0x61, 0x80, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xc8, 0xe3, 0x00, 0x01, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x90, 0x67, 0x02, 0x02, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x21, 0x4f, 0x05, + 0x04, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x1e, + 0x0c, 0x08, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb2, + 0x40, 0x16, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x18, 0x19, 0x11, 0x4c, + 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x5a, 0x05, 0x42, 0xa2, + 0x04, 0x46, 0x00, 0x8a, 0xa1, 0x08, 0x4a, 0xa2, 0x50, 0xca, 0xa0, 0x1c, + 0x0a, 0xa4, 0x10, 0x4a, 0xa1, 0xc0, 0x0a, 0xa8, 0x3c, 0x0a, 0xa2, 0x74, + 0x68, 0x15, 0xc1, 0x08, 0x40, 0x21, 0x94, 0x41, 0x49, 0xd0, 0x99, 0x01, + 0xa0, 0x32, 0x03, 0x40, 0x64, 0x06, 0x80, 0xc6, 0x0c, 0x00, 0x85, 0x19, + 0x00, 0xe2, 0x33, 0x00, 0xd4, 0xc7, 0x72, 0x18, 0x02, 0x00, 0x00, 0xe0, + 0x38, 0x00, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, + 0x00, 0xc5, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, + 0x44, 0x35, 0x18, 0x63, 0x0b, 0x73, 0x3b, 0x03, 0xb1, 0x2b, 0x93, 0x9b, + 0x4b, 0x7b, 0x73, 0x03, 0x99, 0x71, 0xb9, 0x01, 0x41, 0xa1, 0x0b, 0x3b, + 0x9b, 0x7b, 0x91, 0x2a, 0x62, 0x2a, 0x0a, 0x9a, 0x2a, 0xfa, 0x9a, 0xb9, + 0x81, 0x79, 0x31, 0x4b, 0x73, 0x0b, 0x63, 0x4b, 0xd9, 0x10, 0x04, 0x13, + 0x04, 0x61, 0x99, 0x20, 0x08, 0xcc, 0x06, 0x61, 0x20, 0x36, 0x08, 0x04, + 0x41, 0x01, 0x6e, 0x6e, 0x82, 0x20, 0x34, 0x1b, 0x86, 0x03, 0x21, 0x26, + 0x08, 0x45, 0x18, 0x70, 0xa1, 0x43, 0x2b, 0xa3, 0x2a, 0xc3, 0xa3, 0xab, + 0x93, 0x2b, 0xcb, 0x9a, 0x20, 0x08, 0xce, 0x04, 0x41, 0x78, 0x36, 0x08, + 0x44, 0xb3, 0x21, 0x21, 0x94, 0x85, 0x20, 0x06, 0x86, 0x70, 0xb8, 0xd0, + 0xa1, 0x95, 0x51, 0x95, 0xe1, 0xd1, 0xd5, 0xc9, 0x95, 0x55, 0x6d, 0x48, + 0x06, 0x05, 0x22, 0x86, 0x81, 0x21, 0x1c, 0x2e, 0x74, 0x68, 0x65, 0x54, + 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x56, 0x1b, 0x12, 0x46, 0x91, 0x08, + 0x66, 0x60, 0x08, 0x67, 0xc3, 0xf0, 0x44, 0xd3, 0x04, 0xe1, 0x00, 0x03, + 0x2a, 0x74, 0x68, 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x1b, + 0x10, 0xa2, 0xb2, 0x08, 0x62, 0x20, 0x80, 0x0d, 0xc1, 0xb5, 0x81, 0xa0, + 0x00, 0x00, 0x9b, 0x20, 0x10, 0x62, 0x30, 0x41, 0x10, 0x20, 0x06, 0x68, + 0x13, 0x04, 0x21, 0x9a, 0x20, 0x08, 0xd2, 0x06, 0x03, 0xe1, 0x3a, 0xc2, + 0x6b, 0x48, 0xb4, 0xa5, 0xc1, 0xcd, 0x4d, 0x10, 0x84, 0x69, 0x03, 0x81, + 0x80, 0x41, 0x17, 0x06, 0x13, 0x84, 0x80, 0x0c, 0x36, 0x08, 0xc4, 0x18, + 0x6c, 0x08, 0xc8, 0x60, 0x83, 0x40, 0x94, 0xc1, 0x06, 0x62, 0xfb, 0xc4, + 0xc0, 0x0c, 0x26, 0x08, 0xc3, 0x18, 0x4c, 0x10, 0x04, 0x8a, 0x06, 0x5a, + 0x98, 0x1b, 0x19, 0x5b, 0xd9, 0x04, 0x41, 0xa8, 0x36, 0x18, 0x88, 0x1a, + 0x74, 0x84, 0xb7, 0x06, 0x1b, 0x84, 0x34, 0x60, 0x83, 0x09, 0x02, 0x57, + 0x06, 0x13, 0x04, 0xc1, 0xe2, 0x00, 0xf7, 0x36, 0xc7, 0x65, 0xca, 0xea, + 0x0b, 0xea, 0x69, 0x2a, 0x89, 0x2a, 0xe9, 0xc9, 0x69, 0x03, 0x82, 0xc0, + 0x41, 0x47, 0xa4, 0x41, 0x1c, 0x78, 0x0d, 0x07, 0xba, 0x32, 0x3c, 0x26, + 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x30, 0x1b, 0x10, 0x64, + 0x0e, 0xba, 0x30, 0x48, 0x03, 0x3a, 0xf0, 0x1a, 0x16, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x13, 0x04, 0xe1, 0xa2, 0x31, 0xf4, 0xc4, 0xf4, 0x24, 0x05, + 0xb3, 0x01, 0x41, 0xec, 0xa0, 0xbb, 0x83, 0x34, 0xc0, 0x03, 0xaf, 0xd9, + 0x40, 0xbc, 0x81, 0x1c, 0xd4, 0x41, 0x1e, 0x6c, 0x38, 0x08, 0xed, 0x0c, + 0xd0, 0xa0, 0x0d, 0xdc, 0x40, 0x0f, 0x26, 0x08, 0x0a, 0xb1, 0x01, 0xd8, + 0x30, 0x10, 0x7d, 0xd0, 0x07, 0x1b, 0x02, 0x3f, 0xd8, 0x30, 0x0c, 0x7c, + 0xf0, 0x07, 0x13, 0x84, 0xce, 0x0c, 0x36, 0x04, 0xa1, 0x40, 0xa2, 0x2d, + 0x2c, 0xcd, 0x8d, 0xcb, 0x94, 0xd5, 0x17, 0xd4, 0xdb, 0x5c, 0x1a, 0x5d, + 0xda, 0x9b, 0xdb, 0x04, 0x61, 0xf9, 0x26, 0x08, 0x8b, 0xb7, 0x21, 0x20, + 0x26, 0x08, 0x4b, 0x37, 0x41, 0x58, 0xb8, 0x0d, 0x0b, 0x41, 0x0a, 0xa5, + 0x60, 0x0a, 0xa7, 0x80, 0x0a, 0x03, 0x2a, 0x10, 0xa9, 0x00, 0x10, 0xa1, + 0x2a, 0xc2, 0x1a, 0x7a, 0x7a, 0x92, 0x22, 0x9a, 0x20, 0x2c, 0xdb, 0x06, + 0xa1, 0xeb, 0x36, 0x2c, 0xc3, 0x2a, 0x94, 0x42, 0x2a, 0x9c, 0x02, 0x2b, + 0x0c, 0xac, 0x30, 0xa4, 0x42, 0x2b, 0xb0, 0x18, 0x7a, 0x62, 0x7a, 0x92, + 0x9a, 0x20, 0x08, 0xd8, 0x06, 0xa1, 0x83, 0x85, 0x0d, 0x0b, 0xf3, 0x0a, + 0xa5, 0x90, 0x0a, 0xa7, 0xc0, 0x0a, 0x03, 0x2a, 0x30, 0xa9, 0x10, 0x0b, + 0x1b, 0x06, 0x55, 0x70, 0x05, 0x59, 0x60, 0x32, 0x65, 0xf5, 0x45, 0x15, + 0x26, 0x77, 0x56, 0x46, 0x37, 0x41, 0x58, 0x94, 0x0d, 0x0b, 0x41, 0x0b, + 0xa5, 0x50, 0x0b, 0xa7, 0x90, 0x0a, 0x03, 0x2a, 0x10, 0xa9, 0x10, 0x0b, + 0x1b, 0x02, 0x5b, 0xd8, 0x30, 0xcc, 0xc2, 0x2d, 0x00, 0x1b, 0x0a, 0x3e, + 0x18, 0x05, 0x5c, 0xc8, 0x00, 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x73, + 0x13, 0x04, 0x21, 0x63, 0x91, 0xe6, 0x36, 0x47, 0x37, 0x37, 0x41, 0x10, + 0x34, 0x1a, 0x73, 0x69, 0x67, 0x5f, 0x6c, 0x64, 0x34, 0xe6, 0xd2, 0xce, + 0xbe, 0xe6, 0xe8, 0x88, 0xd0, 0x95, 0xe1, 0x7d, 0xb9, 0xbd, 0xc9, 0xb5, + 0x6d, 0x50, 0x74, 0x61, 0x17, 0x78, 0xa1, 0x17, 0x7c, 0x01, 0xf9, 0x85, + 0x34, 0x00, 0x87, 0xae, 0x0a, 0x1b, 0x9b, 0x5d, 0x9b, 0x4b, 0x1a, 0x59, + 0x99, 0x1b, 0xdd, 0x94, 0x20, 0xa8, 0x42, 0x86, 0xe7, 0x62, 0x57, 0x26, + 0x37, 0x97, 0xf6, 0xe6, 0x36, 0x25, 0x20, 0x9a, 0x90, 0xe1, 0xb9, 0xd8, + 0x85, 0xb1, 0xd9, 0x95, 0xc9, 0x4d, 0x09, 0x8a, 0x3a, 0x64, 0x78, 0x2e, + 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x53, + 0x02, 0xa4, 0x0c, 0x19, 0x9e, 0x8b, 0x5c, 0xd9, 0xdc, 0x5b, 0x9d, 0xdc, + 0x58, 0xd9, 0xdc, 0x94, 0x00, 0xab, 0x44, 0x86, 0xe7, 0x42, 0x97, 0x07, + 0x57, 0x16, 0xe4, 0xe6, 0xf6, 0x46, 0x17, 0x46, 0x97, 0xf6, 0xe6, 0x36, + 0x37, 0x45, 0xd0, 0x83, 0x3f, 0xa8, 0x43, 0x86, 0xe7, 0x62, 0x97, 0x56, + 0x76, 0x97, 0x44, 0x36, 0x45, 0x17, 0x46, 0x57, 0x36, 0x25, 0x08, 0x85, + 0x3a, 0x64, 0x78, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x50, 0x6f, 0x69, + 0x6e, 0x74, 0x73, 0x53, 0x02, 0x5c, 0xe8, 0x42, 0x86, 0xe7, 0x32, 0xf6, + 0x56, 0xe7, 0x46, 0x57, 0x26, 0x37, 0x37, 0x25, 0x00, 0x07, 0x00, 0x00, + 0x00, 0x79, 0x18, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, + 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, + 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, + 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, + 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, + 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, + 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, + 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, + 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, + 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, + 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, + 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, + 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, + 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, + 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, + 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, + 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, + 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, + 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, + 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, + 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, + 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, + 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc4, 0x21, 0x07, 0x7c, + 0x70, 0x03, 0x7a, 0x28, 0x87, 0x76, 0x80, 0x87, 0x19, 0xd1, 0x43, 0x0e, + 0xf8, 0xe0, 0x06, 0xe4, 0x20, 0x0e, 0xe7, 0xe0, 0x06, 0xf6, 0x10, 0x0e, + 0xf2, 0xc0, 0x0e, 0xe1, 0x90, 0x0f, 0xef, 0x50, 0x0f, 0xf4, 0x00, 0x00, + 0x00, 0x71, 0x20, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x35, 0xf0, 0x05, + 0x7e, 0x74, 0x74, 0x79, 0x1a, 0x6e, 0xc3, 0xd9, 0x65, 0x39, 0x10, 0x38, + 0xab, 0x4e, 0xc3, 0x6d, 0x38, 0xbb, 0x2c, 0x9f, 0xd2, 0xc3, 0xf4, 0x32, + 0x10, 0x18, 0xac, 0x00, 0x38, 0x08, 0xfc, 0xe8, 0xe8, 0x32, 0xb5, 0x8c, + 0xa7, 0xd7, 0xe5, 0xe5, 0x2a, 0x10, 0x38, 0xb3, 0xfe, 0x48, 0xd4, 0x32, + 0x9e, 0x5e, 0x97, 0x97, 0x65, 0x44, 0xa0, 0xf5, 0x47, 0xb2, 0x97, 0xc7, + 0xf4, 0xb7, 0x1c, 0xd8, 0x24, 0xc1, 0x66, 0x40, 0x20, 0x10, 0x18, 0x2c, + 0x01, 0x38, 0x08, 0xfc, 0xe8, 0xe8, 0x32, 0xb5, 0x8c, 0xa7, 0xd7, 0xe5, + 0x65, 0x2b, 0x10, 0x38, 0xb3, 0xfe, 0x48, 0xd4, 0x32, 0x9e, 0x5e, 0x97, + 0x97, 0x65, 0x44, 0xa0, 0xf5, 0x47, 0xb2, 0x97, 0xc7, 0xf4, 0xb7, 0x1c, + 0xd8, 0x24, 0xc1, 0x66, 0x40, 0x20, 0x10, 0x18, 0x2c, 0x00, 0x38, 0x08, + 0xfc, 0xe8, 0xe8, 0x32, 0xb5, 0x8c, 0xa7, 0xd7, 0xe5, 0xe5, 0x2c, 0x10, + 0x38, 0xb3, 0xfe, 0x48, 0xd4, 0x32, 0x9e, 0x5e, 0x97, 0x97, 0x65, 0x44, + 0xa0, 0xf5, 0x47, 0xb2, 0x97, 0xc7, 0xf4, 0xb7, 0x1c, 0xd8, 0x24, 0xc1, + 0x66, 0x40, 0x20, 0x10, 0x18, 0xb4, 0x04, 0x69, 0xb8, 0x7c, 0xe7, 0xf1, + 0x85, 0x88, 0x00, 0x26, 0x22, 0x04, 0x9a, 0x61, 0x21, 0x0c, 0xc1, 0x19, + 0x2e, 0xdf, 0x79, 0xfc, 0xc1, 0x99, 0x6e, 0xbf, 0xb8, 0x6d, 0x2b, 0x98, + 0x86, 0xcb, 0x77, 0x1e, 0x7f, 0x71, 0x80, 0x41, 0x6c, 0x1e, 0x6a, 0xf2, + 0x8b, 0xdb, 0xb6, 0x03, 0x68, 0xb8, 0x7c, 0xe7, 0xf1, 0x25, 0x80, 0x79, + 0x16, 0xc2, 0x2f, 0x6e, 0xdb, 0x0c, 0xaa, 0xe1, 0xf2, 0x9d, 0xc7, 0x97, + 0x26, 0x27, 0x22, 0x50, 0x6a, 0x7a, 0xa8, 0xc9, 0x2f, 0x6e, 0xdb, 0x08, + 0x08, 0x06, 0x40, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x41, 0x53, + 0x48, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd2, 0x76, 0x77, + 0xba, 0xe6, 0x06, 0xb3, 0xd2, 0x85, 0x4b, 0xcf, 0xc4, 0x54, 0x26, 0x79, + 0xad, 0x44, 0x58, 0x49, 0x4c, 0xd4, 0x07, 0x00, 0x00, 0x60, 0x00, 0x00, + 0x00, 0xf5, 0x01, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c, 0x00, 0x01, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0xbc, 0x07, 0x00, 0x00, 0x42, 0x43, 0xc0, + 0xde, 0x21, 0x0c, 0x00, 0x00, 0xec, 0x01, 0x00, 0x00, 0x0b, 0x82, 0x20, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, + 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, + 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, + 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, + 0x4b, 0x0a, 0x32, 0x52, 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, + 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4, 0x48, 0x0e, 0x90, 0x91, 0x22, 0xc4, + 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x29, 0x46, + 0x06, 0x51, 0x18, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1b, 0x8c, 0xe0, + 0xff, 0xff, 0xff, 0xff, 0x07, 0x40, 0x02, 0xa8, 0x0d, 0x84, 0xf0, 0xff, + 0xff, 0xff, 0xff, 0x03, 0x20, 0x6d, 0x30, 0x86, 0xff, 0xff, 0xff, 0xff, + 0x1f, 0x00, 0x09, 0xa8, 0x00, 0x49, 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x13, 0x82, 0x60, 0x42, 0x20, 0x4c, 0x08, 0x06, 0x00, 0x00, 0x00, + 0x00, 0x89, 0x20, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, + 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, + 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, + 0x4c, 0x10, 0x70, 0x23, 0x00, 0x25, 0x00, 0x14, 0x66, 0x00, 0xe6, 0x08, + 0xc0, 0x60, 0x8e, 0x00, 0x29, 0xc6, 0x20, 0x84, 0x14, 0x42, 0xa6, 0x18, + 0x80, 0x10, 0x52, 0x06, 0xa1, 0x9b, 0x86, 0xcb, 0x9f, 0xb0, 0x87, 0x90, + 0xfc, 0x95, 0x90, 0x56, 0x62, 0xf2, 0x8b, 0xdb, 0x46, 0xc5, 0x18, 0x63, + 0x10, 0x2a, 0xf7, 0x0c, 0x97, 0x3f, 0x61, 0x0f, 0x21, 0xf9, 0x21, 0xd0, + 0x0c, 0x0b, 0x81, 0x82, 0x55, 0x18, 0x45, 0x18, 0x1b, 0x63, 0x0c, 0x42, + 0xc8, 0xa0, 0x56, 0x90, 0x41, 0xc6, 0x18, 0x63, 0x0c, 0x7a, 0x73, 0x04, + 0x41, 0x31, 0x18, 0x29, 0x84, 0x44, 0x92, 0x03, 0x01, 0xc3, 0x08, 0xc4, + 0x30, 0x53, 0x1b, 0x8c, 0x03, 0x3b, 0x84, 0xc3, 0x3c, 0xcc, 0x83, 0x1b, + 0xd0, 0x42, 0x39, 0xe0, 0x03, 0x3d, 0xd4, 0x83, 0x3c, 0x94, 0x83, 0x1c, + 0x90, 0x02, 0x1f, 0xd8, 0x43, 0x39, 0x8c, 0x03, 0x3d, 0xbc, 0x83, 0x3c, + 0xf0, 0x81, 0x39, 0xb0, 0xc3, 0x3b, 0x84, 0x03, 0x3d, 0xb0, 0x01, 0x18, + 0xd0, 0x81, 0x1f, 0x80, 0x81, 0x1f, 0xe8, 0x81, 0x1e, 0xb4, 0x43, 0x3a, + 0xc0, 0xc3, 0x3c, 0xfc, 0x02, 0x3d, 0xe4, 0x03, 0x3c, 0x94, 0x03, 0x0a, + 0xc8, 0x4c, 0x62, 0x30, 0x0e, 0xec, 0x10, 0x0e, 0xf3, 0x30, 0x0f, 0x6e, + 0x40, 0x0b, 0xe5, 0x80, 0x0f, 0xf4, 0x50, 0x0f, 0xf2, 0x50, 0x0e, 0x72, + 0x40, 0x0a, 0x7c, 0x60, 0x0f, 0xe5, 0x30, 0x0e, 0xf4, 0xf0, 0x0e, 0xf2, + 0xc0, 0x07, 0xe6, 0xc0, 0x0e, 0xef, 0x10, 0x0e, 0xf4, 0xc0, 0x06, 0x60, + 0x40, 0x07, 0x7e, 0x00, 0x06, 0x7e, 0x80, 0x84, 0x6a, 0xe9, 0xde, 0x24, + 0x4d, 0x11, 0x25, 0x4c, 0x3e, 0x0b, 0x30, 0xcf, 0x42, 0x44, 0xec, 0x04, + 0x4c, 0x04, 0x0a, 0x08, 0xe5, 0x74, 0x20, 0x00, 0x00, 0x13, 0x14, 0x72, + 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, 0x79, 0x68, 0x03, 0x72, + 0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e, 0x6d, 0xd0, 0x0e, 0x7a, 0x50, 0x0e, + 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, + 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, + 0x78, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, + 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, + 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, + 0x74, 0xd0, 0x06, 0xe6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, + 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, + 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0xe0, 0x0e, + 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, + 0x76, 0x40, 0x07, 0x43, 0x9e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x86, 0x3c, 0x06, 0x10, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x79, 0x10, 0x20, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf2, 0x34, 0x40, 0x00, 0x0c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xe4, 0x79, 0x80, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xc8, 0x23, 0x01, + 0x01, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x16, 0x08, + 0x00, 0x0f, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x14, 0x19, 0x11, 0x4c, + 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x22, 0x25, 0x30, 0x02, + 0x50, 0x0c, 0x45, 0x50, 0x12, 0x65, 0x50, 0x1e, 0x54, 0x4a, 0xa2, 0x0c, + 0x0a, 0x61, 0x04, 0xa0, 0x08, 0x0a, 0x84, 0xf0, 0x0c, 0x00, 0xe9, 0x19, + 0x00, 0xda, 0x63, 0x39, 0x0c, 0x01, 0x00, 0x00, 0x70, 0x1c, 0x00, 0x10, + 0x08, 0x04, 0x02, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x69, 0x00, 0x00, + 0x00, 0x1a, 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, 0x44, 0x35, 0x18, 0x63, + 0x0b, 0x73, 0x3b, 0x03, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x03, + 0x99, 0x71, 0xb9, 0x01, 0x41, 0xa1, 0x0b, 0x3b, 0x9b, 0x7b, 0x91, 0x2a, + 0x62, 0x2a, 0x0a, 0x9a, 0x2a, 0xfa, 0x9a, 0xb9, 0x81, 0x79, 0x31, 0x4b, + 0x73, 0x0b, 0x63, 0x4b, 0xd9, 0x10, 0x04, 0x13, 0x04, 0xc2, 0x98, 0x20, + 0x10, 0xc7, 0x06, 0x61, 0x20, 0x26, 0x08, 0x04, 0xb2, 0x41, 0x18, 0x0c, + 0x0a, 0x70, 0x73, 0x1b, 0x06, 0xc4, 0x20, 0x26, 0x08, 0xd8, 0x44, 0x60, + 0x82, 0x40, 0x24, 0x13, 0x04, 0x42, 0xd9, 0x20, 0x10, 0xcd, 0x86, 0x84, + 0x50, 0x16, 0x82, 0x18, 0x18, 0xc2, 0xd9, 0x90, 0x0c, 0xca, 0x42, 0x0c, + 0x03, 0x43, 0x38, 0x1b, 0x12, 0x46, 0x59, 0x08, 0x66, 0x60, 0x08, 0x67, + 0xc3, 0xf0, 0x40, 0xd1, 0x04, 0x41, 0xa3, 0x36, 0x20, 0xc4, 0xb4, 0x10, + 0xc4, 0x40, 0x00, 0x1b, 0x02, 0x6a, 0x03, 0x21, 0x01, 0x40, 0x35, 0x41, + 0xd8, 0xaa, 0x0d, 0xc1, 0x35, 0x41, 0x10, 0x00, 0x12, 0x6d, 0x61, 0x69, + 0x6e, 0x5c, 0xa6, 0xac, 0xbe, 0xa0, 0xde, 0xe6, 0xd2, 0xe8, 0xd2, 0xde, + 0xdc, 0x26, 0x08, 0x45, 0x33, 0x41, 0x28, 0x9c, 0x0d, 0x01, 0x31, 0x41, + 0x28, 0x9e, 0x09, 0x42, 0x01, 0x6d, 0x58, 0x88, 0x8d, 0xeb, 0xbc, 0x6f, + 0xf8, 0x08, 0x30, 0x00, 0x88, 0x50, 0x15, 0x61, 0x0d, 0x3d, 0x3d, 0x49, + 0x11, 0x4d, 0x10, 0x8a, 0x68, 0x82, 0x40, 0x2c, 0x1b, 0x04, 0x32, 0x20, + 0x83, 0x0d, 0xcb, 0x20, 0x06, 0x1c, 0x18, 0x78, 0x63, 0x30, 0x8c, 0xc1, + 0x00, 0x06, 0x65, 0xc0, 0x62, 0xe8, 0x89, 0xe9, 0x49, 0x6a, 0x82, 0x40, + 0x30, 0x1b, 0x04, 0x32, 0x40, 0x83, 0x0d, 0x0b, 0x73, 0x06, 0x1c, 0x18, + 0x78, 0x63, 0x30, 0x7c, 0x0c, 0x18, 0xa4, 0xc1, 0x86, 0x21, 0x0c, 0xcc, + 0x40, 0x0d, 0x98, 0x4c, 0x59, 0x7d, 0x51, 0x85, 0xc9, 0x9d, 0x95, 0xd1, + 0x4d, 0x10, 0x0a, 0x69, 0xc3, 0x42, 0xb0, 0x01, 0xd7, 0x06, 0x1e, 0x18, + 0x0c, 0x1f, 0x01, 0x06, 0x69, 0xb0, 0x21, 0x70, 0x83, 0x0d, 0xc3, 0x1a, + 0xbc, 0x01, 0xb0, 0xa1, 0xc8, 0x34, 0x38, 0xb0, 0x80, 0x2a, 0x6c, 0x6c, + 0x76, 0x6d, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x53, 0x82, 0xa0, 0x0a, + 0x19, 0x9e, 0x8b, 0x5d, 0x99, 0xdc, 0x5c, 0xda, 0x9b, 0xdb, 0x94, 0x80, + 0x68, 0x42, 0x86, 0xe7, 0x62, 0x17, 0xc6, 0x66, 0x57, 0x26, 0x37, 0x25, + 0x30, 0xea, 0x90, 0xe1, 0xb9, 0xcc, 0xa1, 0x85, 0x91, 0x95, 0xc9, 0x35, + 0xbd, 0x91, 0x95, 0xb1, 0x4d, 0x09, 0x90, 0x32, 0x64, 0x78, 0x2e, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x53, 0x82, 0xaa, 0x0e, + 0x19, 0x9e, 0x8b, 0x5d, 0x5a, 0xd9, 0x5d, 0x12, 0xd9, 0x14, 0x5d, 0x18, + 0x5d, 0xd9, 0x94, 0xe0, 0xaa, 0x43, 0x86, 0xe7, 0x52, 0xe6, 0x46, 0x27, + 0x97, 0x07, 0xf5, 0x96, 0xe6, 0x46, 0x37, 0x37, 0x25, 0x80, 0x03, 0x00, + 0x00, 0x79, 0x18, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, + 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, + 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, + 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, + 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, + 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, + 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, + 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, + 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, + 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, + 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, + 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, + 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, + 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, + 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, + 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, + 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, + 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, + 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, + 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, + 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, + 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, + 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc4, 0x21, 0x07, 0x7c, + 0x70, 0x03, 0x7a, 0x28, 0x87, 0x76, 0x80, 0x87, 0x19, 0xd1, 0x43, 0x0e, + 0xf8, 0xe0, 0x06, 0xe4, 0x20, 0x0e, 0xe7, 0xe0, 0x06, 0xf6, 0x10, 0x0e, + 0xf2, 0xc0, 0x0e, 0xe1, 0x90, 0x0f, 0xef, 0x50, 0x0f, 0xf4, 0x00, 0x00, + 0x00, 0x71, 0x20, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x56, 0x20, 0x0d, + 0x97, 0xef, 0x3c, 0xbe, 0x10, 0x11, 0xc0, 0x44, 0x84, 0x40, 0x33, 0x2c, + 0x84, 0x11, 0x38, 0xc3, 0xe5, 0x3b, 0x8f, 0x3f, 0x38, 0xd3, 0xed, 0x17, + 0xb7, 0x6d, 0x01, 0xd3, 0x70, 0xf9, 0xce, 0xe3, 0x2f, 0x0e, 0x30, 0x88, + 0xcd, 0x43, 0x4d, 0x7e, 0x71, 0xdb, 0x36, 0x00, 0x0d, 0x97, 0xef, 0x3c, + 0xbe, 0x04, 0x30, 0xcf, 0x42, 0xf8, 0xc5, 0x6d, 0x9b, 0x40, 0x35, 0x5c, + 0xbe, 0xf3, 0xf8, 0xd2, 0xe4, 0x44, 0x04, 0x4a, 0x4d, 0x0f, 0x35, 0xf9, + 0xc5, 0x6d, 0x1b, 0x00, 0xc1, 0x00, 0x48, 0x03, 0x00, 0x61, 0x20, 0x00, + 0x00, 0x66, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x14, 0x47, 0x00, 0xa8, 0x94, 0x00, 0x91, + 0x72, 0x2b, 0xbc, 0x52, 0x28, 0xb9, 0x42, 0x98, 0x01, 0xa0, 0x31, 0x46, + 0x50, 0x9e, 0x74, 0xe9, 0x7f, 0x63, 0x04, 0xa2, 0x3e, 0xb7, 0xf3, 0x2f, + 0x8c, 0x11, 0x80, 0xef, 0x0a, 0xae, 0xbf, 0x30, 0x46, 0xc0, 0x97, 0xbd, + 0xb9, 0x7f, 0x23, 0x00, 0x63, 0x04, 0x21, 0x09, 0x86, 0xf0, 0x2f, 0x8c, + 0x11, 0x80, 0x20, 0x08, 0xe2, 0xdf, 0x0c, 0x00, 0x00, 0x23, 0x06, 0x09, + 0x00, 0x82, 0x60, 0x20, 0x85, 0xc1, 0x62, 0x75, 0x1d, 0x34, 0x62, 0x90, + 0x00, 0x20, 0x08, 0x06, 0x92, 0x18, 0x30, 0x57, 0x18, 0x84, 0x41, 0x34, + 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0xd2, 0x18, 0x34, 0x58, 0x18, 0x84, + 0x81, 0x34, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x12, 0x19, 0x38, 0x9b, + 0x18, 0x88, 0xc1, 0x34, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x46, 0x1a, + 0x38, 0x61, 0x30, 0x06, 0x5a, 0x33, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, + 0x86, 0x1a, 0x3c, 0x62, 0x40, 0x06, 0x94, 0x33, 0x62, 0x90, 0x00, 0x20, + 0x08, 0x06, 0xc6, 0x1a, 0x40, 0x63, 0x50, 0x06, 0xdb, 0x33, 0x62, 0x90, + 0x00, 0x20, 0x08, 0x06, 0x06, 0x1b, 0x44, 0x64, 0x60, 0x06, 0x1f, 0x34, + 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x46, 0x1b, 0x48, 0x68, 0x70, 0x06, + 0x5e, 0x34, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x86, 0x1b, 0x4c, 0x69, + 0x80, 0x06, 0x98, 0x34, 0x62, 0xf0, 0x00, 0x20, 0x08, 0x06, 0x4d, 0x1b, + 0x5c, 0xc8, 0x21, 0x04, 0xcb, 0x92, 0x06, 0x69, 0x30, 0x2d, 0xa3, 0x09, + 0x01, 0x30, 0x62, 0xf0, 0x00, 0x20, 0x08, 0x06, 0xcd, 0x1b, 0x64, 0x4b, + 0x42, 0x0c, 0x4d, 0xb3, 0x06, 0x6b, 0x50, 0x35, 0xa3, 0x09, 0x01, 0x30, + 0x62, 0xf0, 0x00, 0x20, 0x08, 0x06, 0x4d, 0x1c, 0x6c, 0xce, 0x62, 0x14, + 0xcf, 0xd3, 0x06, 0x6d, 0x70, 0x3d, 0xa3, 0x09, 0x01, 0x60, 0xc3, 0x04, + 0x1f, 0x13, 0x28, 0xf8, 0x8c, 0x18, 0x2c, 0x00, 0x08, 0x82, 0xc1, 0x43, + 0x07, 0x60, 0x70, 0x08, 0x01, 0x65, 0x5d, 0x23, 0x06, 0x0b, 0x00, 0x82, + 0x60, 0xf0, 0xd4, 0x41, 0x18, 0x20, 0x83, 0x50, 0x65, 0xda, 0x88, 0xc1, + 0x02, 0x80, 0x20, 0x18, 0x3c, 0x76, 0x20, 0x06, 0x09, 0x31, 0x58, 0x1c, + 0x66, 0x43, 0x24, 0x1f, 0x1b, 0x22, 0xf9, 0xd8, 0x10, 0xc9, 0x67, 0xc4, + 0x20, 0x01, 0x40, 0x10, 0x0c, 0x10, 0x3e, 0x20, 0x83, 0x3b, 0xb8, 0x03, + 0x37, 0x18, 0x46, 0x0c, 0x12, 0x00, 0x04, 0xc1, 0x00, 0xe1, 0x03, 0x32, + 0xb8, 0x83, 0x3b, 0x38, 0x03, 0x61, 0xc4, 0x20, 0x01, 0x40, 0x10, 0x0c, + 0x10, 0x3e, 0x20, 0x83, 0x3b, 0xb8, 0x83, 0x36, 0x08, 0x46, 0x0c, 0x12, + 0x00, 0x04, 0xc1, 0x00, 0xe1, 0x03, 0x32, 0xb8, 0x83, 0x3b, 0x80, 0x83, + 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +/* The yuv-rendering pixel shader: + + --- D3D12_PixelShader_YUV_BT601.hlsl --- + Texture2D theTextureY : register(t0); + Texture2D theTextureU : register(t1); + Texture2D theTextureV : register(t2); + SamplerState theSampler : register(s0); + + struct PixelShaderInput + { + float4 pos : SV_POSITION; + float2 tex : TEXCOORD0; + float4 color : COLOR0; + }; + + #define YUVRS \ + "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \ + " DENY_DOMAIN_SHADER_ROOT_ACCESS |" \ + " DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \ + " DENY_HULL_SHADER_ROOT_ACCESS )," \ + "RootConstants(num32BitConstants=32, b0),"\ + "DescriptorTable ( SRV(t0), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( SRV(t1), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( SRV(t2), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( Sampler(s0), visibility = SHADER_VISIBILITY_PIXEL )" + + [RootSignature(YUVRS)] + float4 main(PixelShaderInput input) : SV_TARGET + { + const float3 offset = {-0.0627451017, -0.501960814, -0.501960814}; + const float3 Rcoeff = {1.1644, 0.0000, 1.5960}; + const float3 Gcoeff = {1.1644, -0.3918, -0.8130}; + const float3 Bcoeff = {1.1644, 2.0172, 0.0000}; + + float4 Output; + + float3 yuv; + yuv.x = theTextureY.Sample(theSampler, input.tex).r; + yuv.y = theTextureU.Sample(theSampler, input.tex).r; + yuv.z = theTextureV.Sample(theSampler, input.tex).r; + + yuv += offset; + Output.r = dot(yuv, Rcoeff); + Output.g = dot(yuv, Gcoeff); + Output.b = dot(yuv, Bcoeff); + Output.a = 1.0f; + + return Output * input.color; + } + +*/ + +static unsigned char D3D12_PixelShader_YUV_BT601[] = { + 0x44, 0x58, 0x42, 0x43, 0x15, 0xda, 0x8f, 0x26, 0x88, 0x1f, 0xc5, 0x79, + 0x25, 0xc3, 0x83, 0x74, 0xb6, 0xe8, 0x4f, 0x43, 0x01, 0x00, 0x00, 0x00, + 0x99, 0x13, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0xdb, 0x00, 0x00, 0x00, 0x15, 0x01, 0x00, 0x00, + 0x1d, 0x02, 0x00, 0x00, 0x05, 0x03, 0x00, 0x00, 0x95, 0x0b, 0x00, 0x00, + 0xb1, 0x0b, 0x00, 0x00, 0x53, 0x46, 0x49, 0x30, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31, + 0x83, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x53, 0x56, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, + 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x43, 0x4f, 0x4c, + 0x4f, 0x52, 0x00, 0x4f, 0x53, 0x47, 0x31, 0x32, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x00, 0x50, 0x53, 0x56, 0x30, 0x00, 0x01, 0x00, 0x00, 0x24, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x03, 0x01, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, + 0x52, 0x44, 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x44, 0x03, 0x03, 0x04, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x42, + 0x00, 0x03, 0x02, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x02, 0x44, 0x00, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x44, 0x10, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x52, 0x54, 0x53, 0x30, 0xe0, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x05, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xe0, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x05, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x05, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x05, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x05, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0xff, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, + 0x00, 0xc8, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xff, 0xff, 0x53, 0x54, 0x41, 0x54, 0x88, 0x08, 0x00, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x22, 0x02, 0x00, 0x00, 0x44, 0x58, 0x49, + 0x4c, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x08, 0x00, + 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x19, 0x02, 0x00, + 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, + 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, + 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, + 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, + 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88, 0x48, 0x90, 0x14, + 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4, 0x48, 0x0e, + 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, + 0x8a, 0x04, 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40, 0x02, 0xa8, + 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x20, 0x6d, 0x30, 0x86, + 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x09, 0xa8, 0x00, 0x49, 0x18, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, 0x42, 0x20, 0x4c, 0x08, + 0x06, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x4b, 0x00, 0x00, + 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, + 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, + 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x78, 0x33, 0x00, 0xc3, 0x08, 0x04, + 0x30, 0x47, 0x00, 0x06, 0x33, 0xb5, 0xc1, 0x38, 0xb0, 0x43, 0x38, 0xcc, + 0xc3, 0x3c, 0xb8, 0x01, 0x2d, 0x94, 0x03, 0x3e, 0xd0, 0x43, 0x3d, 0xc8, + 0x43, 0x39, 0xc8, 0x01, 0x29, 0xf0, 0x81, 0x3d, 0x94, 0xc3, 0x38, 0xd0, + 0xc3, 0x3b, 0xc8, 0x03, 0x1f, 0x98, 0x03, 0x3b, 0xbc, 0x43, 0x38, 0xd0, + 0x03, 0x1b, 0x80, 0x01, 0x1d, 0xf8, 0x01, 0x18, 0xf8, 0x81, 0x1e, 0xe8, + 0x41, 0x3b, 0xa4, 0x03, 0x3c, 0xcc, 0xc3, 0x2f, 0xd0, 0x43, 0x3e, 0xc0, + 0x43, 0x39, 0xa0, 0x40, 0xcc, 0x24, 0x06, 0xe3, 0xc0, 0x0e, 0xe1, 0x30, + 0x0f, 0xf3, 0xe0, 0x06, 0xb4, 0x50, 0x0e, 0xf8, 0x40, 0x0f, 0xf5, 0x20, + 0x0f, 0xe5, 0x20, 0x07, 0xa4, 0xc0, 0x07, 0xf6, 0x50, 0x0e, 0xe3, 0x40, + 0x0f, 0xef, 0x20, 0x0f, 0x7c, 0x60, 0x0e, 0xec, 0xf0, 0x0e, 0xe1, 0x40, + 0x0f, 0x6c, 0x00, 0x06, 0x74, 0xe0, 0x07, 0x60, 0xe0, 0x07, 0x48, 0x08, + 0x83, 0xc8, 0x4d, 0xd2, 0x14, 0x51, 0xc2, 0xe4, 0xb3, 0x00, 0xf3, 0x2c, + 0x44, 0xc4, 0x4e, 0xc0, 0x44, 0xa0, 0x40, 0x90, 0x19, 0x01, 0x28, 0x01, + 0xa2, 0x34, 0x47, 0x80, 0x14, 0x03, 0x08, 0x21, 0x96, 0x20, 0x56, 0x0c, + 0x24, 0x84, 0x58, 0x80, 0xdc, 0x4d, 0xc3, 0xe5, 0x4f, 0xd8, 0x43, 0x48, + 0xfe, 0x4a, 0x48, 0x2b, 0x31, 0xf9, 0xc5, 0x6d, 0xa3, 0x02, 0x00, 0x00, + 0x04, 0xad, 0x7b, 0x86, 0xcb, 0x9f, 0xb0, 0x87, 0x90, 0xfc, 0x10, 0x68, + 0x86, 0x85, 0x40, 0x41, 0x2c, 0x0c, 0x14, 0x52, 0x02, 0x00, 0x80, 0x10, + 0x02, 0xd0, 0x2c, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0xd5, 0x39, 0x82, + 0xa0, 0x18, 0x52, 0x2c, 0x21, 0x2e, 0xe1, 0x81, 0x80, 0x61, 0x04, 0x01, + 0xb8, 0x4b, 0x9a, 0x22, 0x4a, 0x98, 0xfc, 0x14, 0xb9, 0x88, 0x85, 0x3d, + 0x80, 0x81, 0x88, 0xc4, 0xe6, 0xa1, 0x26, 0x34, 0x84, 0x1d, 0xd2, 0x41, + 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, + 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e, 0x6d, 0xd0, + 0x0e, 0x7a, 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, + 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, + 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, + 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x10, 0x07, 0x76, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x3a, 0x0f, 0x64, 0x90, 0x21, + 0x23, 0x45, 0x44, 0x00, 0x72, 0x00, 0xc0, 0xe4, 0x00, 0x80, 0xc9, 0x01, + 0x00, 0xd3, 0x03, 0x00, 0x1e, 0xf2, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xe4, 0x61, 0x80, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xc8, 0xe3, 0x00, 0x01, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x90, 0x67, 0x02, 0x02, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x21, 0x4f, 0x05, + 0x04, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x1e, + 0x0c, 0x08, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb2, + 0x40, 0x15, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x18, 0x19, 0x11, 0x4c, + 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x5a, 0x05, 0x42, 0xa2, + 0x04, 0x46, 0x00, 0x8a, 0xa1, 0x08, 0x4a, 0xa2, 0x50, 0xca, 0xa0, 0x1c, + 0x0a, 0xa4, 0x10, 0x4a, 0xa1, 0xc0, 0x0a, 0xa8, 0x3c, 0x8a, 0x87, 0x56, + 0x11, 0x8c, 0x00, 0x14, 0x42, 0x19, 0x94, 0x04, 0x9d, 0x19, 0x00, 0x2a, + 0x33, 0x00, 0x44, 0x66, 0x00, 0x68, 0xcc, 0x00, 0x50, 0x98, 0x01, 0x20, + 0x3e, 0x03, 0x40, 0x7d, 0x2c, 0x87, 0x21, 0x00, 0x00, 0x00, 0x8e, 0x03, + 0x00, 0x02, 0x81, 0x40, 0x00, 0x79, 0x18, 0x00, 0x00, 0xc4, 0x00, 0x00, + 0x00, 0x1a, 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, 0x44, 0x35, 0x18, 0x63, + 0x0b, 0x73, 0x3b, 0x03, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x03, + 0x99, 0x71, 0xb9, 0x01, 0x41, 0xa1, 0x0b, 0x3b, 0x9b, 0x7b, 0x91, 0x2a, + 0x62, 0x2a, 0x0a, 0x9a, 0x2a, 0xfa, 0x9a, 0xb9, 0x81, 0x79, 0x31, 0x4b, + 0x73, 0x0b, 0x63, 0x4b, 0xd9, 0x10, 0x04, 0x13, 0x04, 0x61, 0x99, 0x20, + 0x08, 0xcc, 0x06, 0x61, 0x20, 0x36, 0x08, 0x04, 0x41, 0x01, 0x6e, 0x6e, + 0x82, 0x20, 0x34, 0x1b, 0x86, 0x03, 0x21, 0x26, 0x08, 0x05, 0x18, 0x70, + 0xa1, 0x43, 0x2b, 0xa3, 0x2a, 0xc3, 0xa3, 0xab, 0x93, 0x2b, 0xcb, 0x9a, + 0x20, 0x08, 0xce, 0x04, 0x41, 0x78, 0x36, 0x08, 0x44, 0xb3, 0x21, 0x21, + 0x94, 0x85, 0x20, 0x06, 0x86, 0x70, 0xb8, 0xd0, 0xa1, 0x95, 0x51, 0x95, + 0xe1, 0xd1, 0xd5, 0xc9, 0x95, 0x55, 0x6d, 0x48, 0x06, 0x05, 0x22, 0x86, + 0x81, 0x21, 0x1c, 0x2e, 0x74, 0x68, 0x65, 0x54, 0x65, 0x78, 0x74, 0x75, + 0x72, 0x65, 0x56, 0x1b, 0x12, 0x46, 0x91, 0x08, 0x66, 0x60, 0x08, 0x67, + 0xc3, 0xf0, 0x44, 0xd3, 0x04, 0xe1, 0xf8, 0xa8, 0xd0, 0xa1, 0x95, 0x4d, + 0x85, 0xb5, 0xc1, 0xb1, 0x95, 0xc9, 0x6d, 0x40, 0x88, 0xca, 0x22, 0x88, + 0x81, 0x00, 0x36, 0x04, 0xd7, 0x06, 0x82, 0x02, 0x00, 0x6c, 0x82, 0x40, + 0x84, 0xc1, 0x04, 0x41, 0x80, 0x18, 0xa0, 0x4d, 0x10, 0x84, 0x68, 0x82, + 0x20, 0x48, 0x1b, 0x0c, 0x84, 0xeb, 0x08, 0xaf, 0x21, 0xd1, 0x96, 0x06, + 0x37, 0x37, 0x41, 0x10, 0xa6, 0x0d, 0x04, 0x02, 0x06, 0x5d, 0x18, 0x4c, + 0x10, 0x82, 0x31, 0xd8, 0x20, 0x10, 0x63, 0xb0, 0x21, 0x20, 0x83, 0x0d, + 0x02, 0x51, 0x06, 0x1b, 0x88, 0xed, 0x13, 0x03, 0x33, 0x98, 0x20, 0x0c, + 0x62, 0x30, 0x41, 0x10, 0x28, 0x1a, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, + 0x13, 0x04, 0xa1, 0xda, 0x60, 0x20, 0x6a, 0xd0, 0x11, 0xde, 0x1a, 0x6c, + 0x10, 0xd2, 0x80, 0x0d, 0x26, 0x08, 0x1c, 0x19, 0x4c, 0x10, 0x04, 0x8b, + 0x03, 0xdc, 0xdb, 0x1c, 0x97, 0x29, 0xab, 0x2f, 0xa8, 0xa7, 0xa9, 0x24, + 0xaa, 0xa4, 0x27, 0xa7, 0x0d, 0x08, 0x02, 0x07, 0x1d, 0x91, 0x06, 0x71, + 0xe0, 0x35, 0x1c, 0xe8, 0xca, 0xf0, 0x98, 0x50, 0x15, 0x61, 0x0d, 0x3d, + 0x3d, 0x49, 0x11, 0xc1, 0x6c, 0x40, 0x90, 0x39, 0xe8, 0xc2, 0x20, 0x0d, + 0xe8, 0xc0, 0x6b, 0x58, 0x8c, 0xbd, 0xb1, 0xbd, 0xc9, 0x4d, 0x10, 0x84, + 0x8b, 0xc6, 0xd0, 0x13, 0xd3, 0x93, 0x14, 0xcc, 0x06, 0x04, 0xb1, 0x83, + 0xee, 0x0e, 0xd2, 0x00, 0x0f, 0xbc, 0x66, 0x03, 0xf1, 0x06, 0x72, 0x50, + 0x07, 0x79, 0xb0, 0xe1, 0x20, 0xb4, 0x33, 0x40, 0x83, 0x36, 0x70, 0x03, + 0x3d, 0x98, 0x20, 0x28, 0xc4, 0x06, 0x60, 0xc3, 0x40, 0xf4, 0x41, 0x1f, + 0x6c, 0x08, 0xfc, 0x60, 0xc3, 0x30, 0xf0, 0xc1, 0x1f, 0x4c, 0x10, 0xba, + 0x32, 0xd8, 0x10, 0x84, 0x02, 0x89, 0xb6, 0xb0, 0x34, 0x37, 0x2e, 0x53, + 0x56, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x13, 0x84, + 0xc5, 0x9b, 0x20, 0x2c, 0xdd, 0x86, 0x80, 0x98, 0x20, 0x2c, 0xdc, 0x04, + 0x61, 0xd9, 0x36, 0x2c, 0x04, 0x29, 0x94, 0x82, 0x29, 0x9c, 0x02, 0x2a, + 0x0c, 0xa8, 0x40, 0xa4, 0x02, 0x40, 0x84, 0xaa, 0x08, 0x6b, 0xe8, 0xe9, + 0x49, 0x8a, 0x68, 0x82, 0xb0, 0x68, 0x1b, 0x84, 0xae, 0xdb, 0xb0, 0x0c, + 0xab, 0x50, 0x0a, 0xa9, 0x70, 0x0a, 0xac, 0x30, 0xb0, 0xc2, 0x90, 0x0a, + 0xad, 0xc0, 0x62, 0xe8, 0x89, 0xe9, 0x49, 0x6a, 0x82, 0x20, 0x60, 0x1b, + 0x84, 0x0e, 0x16, 0x36, 0x2c, 0xcc, 0x2b, 0x94, 0x42, 0x2a, 0x9c, 0x02, + 0x2b, 0x0c, 0xa8, 0xc0, 0xa4, 0x42, 0x2c, 0x6c, 0x18, 0x54, 0xc1, 0x15, + 0x64, 0x81, 0xc9, 0x94, 0xd5, 0x17, 0x55, 0x98, 0xdc, 0x59, 0x19, 0xdd, + 0x04, 0x61, 0x51, 0x36, 0x2c, 0x04, 0x2d, 0x94, 0x42, 0x2d, 0x9c, 0x42, + 0x2a, 0x0c, 0xa8, 0x40, 0xa4, 0x42, 0x2c, 0x6c, 0x08, 0x6c, 0x61, 0xc3, + 0x30, 0x0b, 0xb7, 0x00, 0x6c, 0x28, 0xf8, 0x60, 0x14, 0x70, 0x21, 0x03, + 0x68, 0x98, 0xb1, 0xbd, 0x85, 0xd1, 0xcd, 0xb1, 0x48, 0x73, 0x9b, 0xa3, + 0x9b, 0x9b, 0x20, 0x08, 0x19, 0x8d, 0xb9, 0xb4, 0xb3, 0x2f, 0x36, 0x32, + 0x1a, 0x73, 0x69, 0x67, 0x5f, 0x73, 0x74, 0x44, 0xe8, 0xca, 0xf0, 0xbe, + 0xdc, 0xde, 0xe4, 0xda, 0x36, 0x28, 0xba, 0xd0, 0xec, 0x02, 0x2f, 0xf4, + 0x02, 0xe2, 0x0b, 0x69, 0xf0, 0x0b, 0x5d, 0x15, 0x36, 0x36, 0xbb, 0x36, + 0x97, 0x34, 0xb2, 0x32, 0x37, 0xba, 0x29, 0x41, 0x50, 0x85, 0x0c, 0xcf, + 0xc5, 0xae, 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x6d, 0x4a, 0x40, 0x34, 0x21, + 0xc3, 0x73, 0xb1, 0x0b, 0x63, 0xb3, 0x2b, 0x93, 0x9b, 0x12, 0x14, 0x75, + 0xc8, 0xf0, 0x5c, 0xe6, 0xd0, 0xc2, 0xc8, 0xca, 0xe4, 0x9a, 0xde, 0xc8, + 0xca, 0xd8, 0xa6, 0x04, 0x48, 0x19, 0x32, 0x3c, 0x17, 0xb9, 0xb2, 0xb9, + 0xb7, 0x3a, 0xb9, 0xb1, 0xb2, 0xb9, 0x29, 0x01, 0x56, 0x89, 0x0c, 0xcf, + 0x85, 0x2e, 0x0f, 0xae, 0x2c, 0xc8, 0xcd, 0xed, 0x8d, 0x2e, 0x8c, 0x2e, + 0xed, 0xcd, 0x6d, 0x6e, 0x8a, 0xa0, 0x07, 0x7f, 0x50, 0x87, 0x0c, 0xcf, + 0xc5, 0x2e, 0xad, 0xec, 0x2e, 0x89, 0x6c, 0x8a, 0x2e, 0x8c, 0xae, 0x6c, + 0x4a, 0x10, 0x0a, 0x75, 0xc8, 0xf0, 0x5c, 0xca, 0xdc, 0xe8, 0xe4, 0xf2, + 0xa0, 0xde, 0xd2, 0xdc, 0xe8, 0xe6, 0xa6, 0x04, 0xb8, 0xd0, 0x85, 0x0c, + 0xcf, 0x65, 0xec, 0xad, 0xce, 0x8d, 0xae, 0x4c, 0x6e, 0x6e, 0x4a, 0xf0, + 0x0b, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x4c, 0x00, 0x00, + 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, + 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, + 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, + 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, + 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, + 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, + 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, + 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, + 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, + 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, + 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, + 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, + 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, + 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, + 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, + 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, + 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, + 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, + 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, + 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, + 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, + 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, + 0xc4, 0x21, 0x07, 0x7c, 0x70, 0x03, 0x7a, 0x28, 0x87, 0x76, 0x80, 0x87, + 0x19, 0xd1, 0x43, 0x0e, 0xf8, 0xe0, 0x06, 0xe4, 0x20, 0x0e, 0xe7, 0xe0, + 0x06, 0xf6, 0x10, 0x0e, 0xf2, 0xc0, 0x0e, 0xe1, 0x90, 0x0f, 0xef, 0x50, + 0x0f, 0xf4, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x3e, 0x00, 0x00, + 0x00, 0x35, 0xf0, 0x05, 0x7e, 0x74, 0x74, 0x79, 0x1a, 0x6e, 0xc3, 0xd9, + 0x65, 0x39, 0x10, 0x38, 0xab, 0x4e, 0xc3, 0x6d, 0x38, 0xbb, 0x2c, 0x9f, + 0xd2, 0xc3, 0xf4, 0x32, 0x10, 0x18, 0xac, 0x00, 0x38, 0x08, 0xfc, 0xe8, + 0xe8, 0x32, 0xb5, 0x8c, 0xa7, 0xd7, 0xe5, 0xe5, 0x2a, 0x10, 0x38, 0xb3, + 0xfe, 0x48, 0xd4, 0x32, 0x9e, 0x5e, 0x97, 0x97, 0x65, 0x44, 0xa0, 0xf5, + 0x47, 0xb2, 0x97, 0xc7, 0xf4, 0xb7, 0x1c, 0xd8, 0x24, 0xc1, 0x66, 0x40, + 0x20, 0x10, 0x18, 0x2c, 0x01, 0x38, 0x08, 0xfc, 0xe8, 0xe8, 0x32, 0xb5, + 0x8c, 0xa7, 0xd7, 0xe5, 0x65, 0x2b, 0x10, 0x38, 0xb3, 0xfe, 0x48, 0xd4, + 0x32, 0x9e, 0x5e, 0x97, 0x97, 0x65, 0x44, 0xa0, 0xf5, 0x47, 0xb2, 0x97, + 0xc7, 0xf4, 0xb7, 0x1c, 0xd8, 0x24, 0xc1, 0x66, 0x40, 0x20, 0x10, 0x18, + 0x2c, 0x00, 0x38, 0x08, 0xfc, 0xe8, 0xe8, 0x32, 0xb5, 0x8c, 0xa7, 0xd7, + 0xe5, 0xe5, 0x2c, 0x10, 0x38, 0xb3, 0xfe, 0x48, 0xd4, 0x32, 0x9e, 0x5e, + 0x97, 0x97, 0x65, 0x44, 0xa0, 0xf5, 0x47, 0xb2, 0x97, 0xc7, 0xf4, 0xb7, + 0x1c, 0xd8, 0x24, 0xc1, 0x66, 0x40, 0x20, 0x10, 0x18, 0xb4, 0x04, 0x69, + 0xb8, 0x7c, 0xe7, 0xf1, 0x85, 0x88, 0x00, 0x26, 0x22, 0x04, 0x9a, 0x61, + 0x21, 0x0c, 0xc1, 0x19, 0x2e, 0xdf, 0x79, 0xfc, 0xc1, 0x99, 0x6e, 0xbf, + 0xb8, 0x6d, 0x2b, 0x98, 0x86, 0xcb, 0x77, 0x1e, 0x7f, 0x71, 0x80, 0x41, + 0x6c, 0x1e, 0x6a, 0xf2, 0x8b, 0xdb, 0xb6, 0x03, 0x68, 0xb8, 0x7c, 0xe7, + 0xf1, 0x25, 0x80, 0x79, 0x16, 0xc2, 0x2f, 0x6e, 0xdb, 0x0c, 0xaa, 0xe1, + 0xf2, 0x9d, 0xc7, 0x97, 0x26, 0x27, 0x22, 0x50, 0x6a, 0x7a, 0xa8, 0xc9, + 0x2f, 0x6e, 0xdb, 0x08, 0x08, 0x06, 0x40, 0x1a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x48, 0x41, 0x53, 0x48, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x57, 0xe4, 0xe0, 0xfd, 0x5b, 0x8a, 0xbf, 0x47, 0x55, 0x60, 0xe1, + 0xa5, 0xe1, 0x4c, 0x5a, 0xa7, 0x44, 0x58, 0x49, 0x4c, 0xe0, 0x07, 0x00, + 0x00, 0x60, 0x00, 0x00, 0x00, 0xf8, 0x01, 0x00, 0x00, 0x44, 0x58, 0x49, + 0x4c, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xc8, 0x07, 0x00, + 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0xef, 0x01, 0x00, + 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, + 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, + 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, + 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, + 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88, 0x48, 0x90, 0x14, + 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4, 0x48, 0x0e, + 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, + 0x8a, 0x04, 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40, 0x02, 0xa8, + 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x20, 0x6d, 0x30, 0x86, + 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x09, 0xa8, 0x00, 0x49, 0x18, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, 0x42, 0x20, 0x4c, 0x08, + 0x06, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x45, 0x00, 0x00, + 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, + 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, + 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x70, 0x23, 0x00, 0x25, 0x00, 0x14, + 0x66, 0x00, 0xe6, 0x08, 0xc0, 0x60, 0x8e, 0x00, 0x29, 0xc6, 0x20, 0x84, + 0x14, 0x42, 0xa6, 0x18, 0x80, 0x10, 0x52, 0x06, 0xa1, 0x9b, 0x86, 0xcb, + 0x9f, 0xb0, 0x87, 0x90, 0xfc, 0x95, 0x90, 0x56, 0x62, 0xf2, 0x8b, 0xdb, + 0x46, 0xc5, 0x18, 0x63, 0x10, 0x2a, 0xf7, 0x0c, 0x97, 0x3f, 0x61, 0x0f, + 0x21, 0xf9, 0x21, 0xd0, 0x0c, 0x0b, 0x81, 0x82, 0x55, 0x18, 0x45, 0x18, + 0x1b, 0x63, 0x0c, 0x42, 0xc8, 0xa0, 0x56, 0x90, 0x41, 0xc6, 0x18, 0x63, + 0x0c, 0x7a, 0x73, 0x04, 0x41, 0x31, 0x18, 0x29, 0x84, 0x44, 0x92, 0x03, + 0x01, 0xc3, 0x08, 0xc4, 0x30, 0x53, 0x1b, 0x8c, 0x03, 0x3b, 0x84, 0xc3, + 0x3c, 0xcc, 0x83, 0x1b, 0xd0, 0x42, 0x39, 0xe0, 0x03, 0x3d, 0xd4, 0x83, + 0x3c, 0x94, 0x83, 0x1c, 0x90, 0x02, 0x1f, 0xd8, 0x43, 0x39, 0x8c, 0x03, + 0x3d, 0xbc, 0x83, 0x3c, 0xf0, 0x81, 0x39, 0xb0, 0xc3, 0x3b, 0x84, 0x03, + 0x3d, 0xb0, 0x01, 0x18, 0xd0, 0x81, 0x1f, 0x80, 0x81, 0x1f, 0xe8, 0x81, + 0x1e, 0xb4, 0x43, 0x3a, 0xc0, 0xc3, 0x3c, 0xfc, 0x02, 0x3d, 0xe4, 0x03, + 0x3c, 0x94, 0x03, 0x0a, 0xc8, 0x4c, 0x62, 0x30, 0x0e, 0xec, 0x10, 0x0e, + 0xf3, 0x30, 0x0f, 0x6e, 0x40, 0x0b, 0xe5, 0x80, 0x0f, 0xf4, 0x50, 0x0f, + 0xf2, 0x50, 0x0e, 0x72, 0x40, 0x0a, 0x7c, 0x60, 0x0f, 0xe5, 0x30, 0x0e, + 0xf4, 0xf0, 0x0e, 0xf2, 0xc0, 0x07, 0xe6, 0xc0, 0x0e, 0xef, 0x10, 0x0e, + 0xf4, 0xc0, 0x06, 0x60, 0x40, 0x07, 0x7e, 0x00, 0x06, 0x7e, 0x80, 0x84, + 0x6a, 0xe9, 0xde, 0x24, 0x4d, 0x11, 0x25, 0x4c, 0x3e, 0x0b, 0x30, 0xcf, + 0x42, 0x44, 0xec, 0x04, 0x4c, 0x04, 0x0a, 0x08, 0xe5, 0x74, 0x20, 0x00, + 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, + 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e, 0x6d, 0xd0, + 0x0e, 0x7a, 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, + 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, + 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, + 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x10, 0x07, 0x76, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x43, 0x9e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x3c, 0x06, 0x10, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x79, 0x10, + 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf2, + 0x34, 0x40, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, + 0xe4, 0x79, 0x80, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0xc8, 0x23, 0x01, 0x01, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x16, 0x08, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, + 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, + 0x22, 0x25, 0x30, 0x02, 0x50, 0x0c, 0x45, 0x50, 0x12, 0x65, 0x50, 0x1e, + 0x54, 0x4a, 0xa2, 0x0c, 0x0a, 0x61, 0x04, 0xa0, 0x08, 0x0a, 0x84, 0xf0, + 0x0c, 0x00, 0xe9, 0x19, 0x00, 0xda, 0x63, 0x39, 0x0c, 0x01, 0x00, 0x00, + 0x70, 0x1c, 0x00, 0x10, 0x08, 0x04, 0x02, 0x00, 0x00, 0x79, 0x18, 0x00, + 0x00, 0x69, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, + 0x44, 0x35, 0x18, 0x63, 0x0b, 0x73, 0x3b, 0x03, 0xb1, 0x2b, 0x93, 0x9b, + 0x4b, 0x7b, 0x73, 0x03, 0x99, 0x71, 0xb9, 0x01, 0x41, 0xa1, 0x0b, 0x3b, + 0x9b, 0x7b, 0x91, 0x2a, 0x62, 0x2a, 0x0a, 0x9a, 0x2a, 0xfa, 0x9a, 0xb9, + 0x81, 0x79, 0x31, 0x4b, 0x73, 0x0b, 0x63, 0x4b, 0xd9, 0x10, 0x04, 0x13, + 0x04, 0xc2, 0x98, 0x20, 0x10, 0xc7, 0x06, 0x61, 0x20, 0x26, 0x08, 0x04, + 0xb2, 0x41, 0x18, 0x0c, 0x0a, 0x70, 0x73, 0x1b, 0x06, 0xc4, 0x20, 0x26, + 0x08, 0xd8, 0x44, 0x60, 0x82, 0x40, 0x24, 0x13, 0x04, 0x42, 0xd9, 0x20, + 0x10, 0xcd, 0x86, 0x84, 0x50, 0x16, 0x82, 0x18, 0x18, 0xc2, 0xd9, 0x90, + 0x0c, 0xca, 0x42, 0x0c, 0x03, 0x43, 0x38, 0x1b, 0x12, 0x46, 0x59, 0x08, + 0x66, 0x60, 0x08, 0x67, 0xc3, 0xf0, 0x40, 0xd1, 0x04, 0x41, 0xa3, 0x36, + 0x20, 0xc4, 0xb4, 0x10, 0xc4, 0x40, 0x00, 0x1b, 0x02, 0x6a, 0x03, 0x21, + 0x01, 0x40, 0x35, 0x41, 0xd8, 0xaa, 0x0d, 0xc1, 0x35, 0x41, 0x10, 0x00, + 0x12, 0x6d, 0x61, 0x69, 0x6e, 0x5c, 0xa6, 0xac, 0xbe, 0xa0, 0xde, 0xe6, + 0xd2, 0xe8, 0xd2, 0xde, 0xdc, 0x26, 0x08, 0x45, 0x33, 0x41, 0x28, 0x9c, + 0x0d, 0x01, 0x31, 0x41, 0x28, 0x9e, 0x09, 0x42, 0x01, 0x6d, 0x58, 0x88, + 0x8d, 0xeb, 0xbc, 0x6f, 0xf8, 0x08, 0x30, 0x00, 0x88, 0x50, 0x15, 0x61, + 0x0d, 0x3d, 0x3d, 0x49, 0x11, 0x4d, 0x10, 0x8a, 0x68, 0x82, 0x40, 0x2c, + 0x1b, 0x04, 0x32, 0x20, 0x83, 0x0d, 0xcb, 0x20, 0x06, 0x1c, 0x18, 0x78, + 0x63, 0x30, 0x8c, 0xc1, 0x00, 0x06, 0x65, 0xc0, 0x62, 0xe8, 0x89, 0xe9, + 0x49, 0x6a, 0x82, 0x40, 0x30, 0x1b, 0x04, 0x32, 0x40, 0x83, 0x0d, 0x0b, + 0x73, 0x06, 0x1c, 0x18, 0x78, 0x63, 0x30, 0x7c, 0x0c, 0x18, 0xa4, 0xc1, + 0x86, 0x21, 0x0c, 0xcc, 0x40, 0x0d, 0x98, 0x4c, 0x59, 0x7d, 0x51, 0x85, + 0xc9, 0x9d, 0x95, 0xd1, 0x4d, 0x10, 0x0a, 0x69, 0xc3, 0x42, 0xb0, 0x01, + 0xd7, 0x06, 0x1e, 0x18, 0x0c, 0x1f, 0x01, 0x06, 0x69, 0xb0, 0x21, 0x70, + 0x83, 0x0d, 0xc3, 0x1a, 0xbc, 0x01, 0xb0, 0xa1, 0xc8, 0x34, 0x38, 0xb0, + 0x80, 0x2a, 0x6c, 0x6c, 0x76, 0x6d, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, + 0x53, 0x82, 0xa0, 0x0a, 0x19, 0x9e, 0x8b, 0x5d, 0x99, 0xdc, 0x5c, 0xda, + 0x9b, 0xdb, 0x94, 0x80, 0x68, 0x42, 0x86, 0xe7, 0x62, 0x17, 0xc6, 0x66, + 0x57, 0x26, 0x37, 0x25, 0x30, 0xea, 0x90, 0xe1, 0xb9, 0xcc, 0xa1, 0x85, + 0x91, 0x95, 0xc9, 0x35, 0xbd, 0x91, 0x95, 0xb1, 0x4d, 0x09, 0x90, 0x32, + 0x64, 0x78, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, + 0x53, 0x82, 0xaa, 0x0e, 0x19, 0x9e, 0x8b, 0x5d, 0x5a, 0xd9, 0x5d, 0x12, + 0xd9, 0x14, 0x5d, 0x18, 0x5d, 0xd9, 0x94, 0xe0, 0xaa, 0x43, 0x86, 0xe7, + 0x52, 0xe6, 0x46, 0x27, 0x97, 0x07, 0xf5, 0x96, 0xe6, 0x46, 0x37, 0x37, + 0x25, 0x80, 0x03, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x4c, 0x00, 0x00, + 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, + 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, + 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, + 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, + 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, + 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, + 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, + 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, + 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, + 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, + 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, + 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, + 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, + 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, + 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, + 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, + 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, + 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, + 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, + 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, + 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, + 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, + 0xc4, 0x21, 0x07, 0x7c, 0x70, 0x03, 0x7a, 0x28, 0x87, 0x76, 0x80, 0x87, + 0x19, 0xd1, 0x43, 0x0e, 0xf8, 0xe0, 0x06, 0xe4, 0x20, 0x0e, 0xe7, 0xe0, + 0x06, 0xf6, 0x10, 0x0e, 0xf2, 0xc0, 0x0e, 0xe1, 0x90, 0x0f, 0xef, 0x50, + 0x0f, 0xf4, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x15, 0x00, 0x00, + 0x00, 0x56, 0x20, 0x0d, 0x97, 0xef, 0x3c, 0xbe, 0x10, 0x11, 0xc0, 0x44, + 0x84, 0x40, 0x33, 0x2c, 0x84, 0x11, 0x38, 0xc3, 0xe5, 0x3b, 0x8f, 0x3f, + 0x38, 0xd3, 0xed, 0x17, 0xb7, 0x6d, 0x01, 0xd3, 0x70, 0xf9, 0xce, 0xe3, + 0x2f, 0x0e, 0x30, 0x88, 0xcd, 0x43, 0x4d, 0x7e, 0x71, 0xdb, 0x36, 0x00, + 0x0d, 0x97, 0xef, 0x3c, 0xbe, 0x04, 0x30, 0xcf, 0x42, 0xf8, 0xc5, 0x6d, + 0x9b, 0x40, 0x35, 0x5c, 0xbe, 0xf3, 0xf8, 0xd2, 0xe4, 0x44, 0x04, 0x4a, + 0x4d, 0x0f, 0x35, 0xf9, 0xc5, 0x6d, 0x1b, 0x00, 0xc1, 0x00, 0x48, 0x03, + 0x00, 0x61, 0x20, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, + 0x2c, 0x10, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x47, 0x00, + 0xa8, 0x94, 0x00, 0x91, 0x72, 0x2b, 0xbc, 0x52, 0x28, 0xb9, 0x42, 0x98, + 0x01, 0xa0, 0x31, 0x46, 0xe0, 0xba, 0xa6, 0x08, 0x82, 0xc1, 0x18, 0x41, + 0x69, 0xa2, 0x60, 0xfd, 0x0b, 0x63, 0x04, 0x22, 0x6c, 0xc6, 0xec, 0x2f, + 0x8c, 0x11, 0xe8, 0xad, 0x8c, 0xf3, 0xdf, 0x18, 0x41, 0x48, 0x82, 0x21, + 0xee, 0x0b, 0x23, 0x00, 0x63, 0x04, 0x21, 0x09, 0x86, 0xf0, 0x2f, 0x8c, + 0x11, 0xbc, 0xb8, 0xa8, 0xe6, 0xdf, 0x0c, 0x00, 0x00, 0x23, 0x06, 0x09, + 0x00, 0x82, 0x60, 0x20, 0x89, 0x01, 0x73, 0x79, 0x5e, 0x34, 0x62, 0x90, + 0x00, 0x20, 0x08, 0x06, 0xd2, 0x18, 0x34, 0x98, 0x18, 0x88, 0x81, 0x34, + 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x12, 0x19, 0x38, 0x99, 0x18, 0x88, + 0xc1, 0x34, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x52, 0x19, 0x3c, 0xdc, + 0x18, 0x8c, 0x01, 0x35, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x86, 0x1a, + 0x3c, 0x62, 0x40, 0x06, 0x9b, 0x33, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, + 0xc6, 0x1a, 0x40, 0x63, 0x50, 0x06, 0xd5, 0x33, 0x62, 0x90, 0x00, 0x20, + 0x08, 0x06, 0x06, 0x1b, 0x44, 0x64, 0x60, 0x06, 0x1c, 0x34, 0x62, 0x90, + 0x00, 0x20, 0x08, 0x06, 0x46, 0x1b, 0x48, 0x65, 0x70, 0x06, 0x60, 0x10, + 0x8d, 0x18, 0x24, 0x00, 0x08, 0x82, 0x81, 0xe1, 0x06, 0x53, 0x1a, 0xa0, + 0xc1, 0x27, 0x8d, 0x18, 0x24, 0x00, 0x08, 0x82, 0x81, 0xf1, 0x06, 0x94, + 0x1a, 0xa4, 0x41, 0x36, 0x8d, 0x18, 0x3c, 0x00, 0x08, 0x82, 0x41, 0xe3, + 0x06, 0x18, 0x72, 0x08, 0xc1, 0xb2, 0xa8, 0x81, 0x1a, 0x50, 0xcb, 0x68, + 0x42, 0x00, 0x8c, 0x18, 0x3c, 0x00, 0x08, 0x82, 0x41, 0x03, 0x07, 0xda, + 0x92, 0x10, 0x43, 0xd3, 0xb0, 0x01, 0x1b, 0x58, 0xcd, 0x68, 0x42, 0x00, + 0x8c, 0x18, 0x3c, 0x00, 0x08, 0x82, 0x41, 0x23, 0x07, 0x9c, 0xb3, 0x18, + 0xc5, 0xf3, 0xb8, 0x81, 0x1b, 0x60, 0xcf, 0x68, 0x42, 0x00, 0x58, 0x51, + 0xc1, 0xc7, 0x08, 0x0a, 0x3e, 0x36, 0x54, 0xf0, 0x19, 0x31, 0x58, 0x00, + 0x10, 0x04, 0x83, 0xc7, 0x0e, 0xc4, 0x60, 0x10, 0x82, 0xea, 0xca, 0x46, + 0x0c, 0x16, 0x00, 0x04, 0xc1, 0xe0, 0xb9, 0x83, 0x31, 0x20, 0x06, 0xc1, + 0xda, 0xb8, 0x11, 0x83, 0x05, 0x00, 0x41, 0x30, 0x78, 0xf0, 0x80, 0x0c, + 0x0a, 0x62, 0xb8, 0xbc, 0xcc, 0x06, 0x49, 0x3e, 0x36, 0x48, 0xf2, 0xb1, + 0x41, 0x92, 0xcf, 0x88, 0x41, 0x02, 0x80, 0x20, 0x18, 0x20, 0x7e, 0x60, + 0x06, 0x79, 0x90, 0x07, 0x70, 0x30, 0x8c, 0x18, 0x24, 0x00, 0x08, 0x82, + 0x01, 0xe2, 0x07, 0x66, 0x90, 0x07, 0x79, 0x90, 0x06, 0xc2, 0x88, 0x41, + 0x02, 0x80, 0x20, 0x18, 0x20, 0x7e, 0x60, 0x06, 0x79, 0x90, 0x07, 0x6f, + 0x10, 0x8c, 0x18, 0x24, 0x00, 0x08, 0x82, 0x01, 0xe2, 0x07, 0x66, 0x90, + 0x07, 0x79, 0x20, 0x07, 0x12, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 +}; + +/* The yuv-rendering pixel shader: + + --- D3D12_PixelShader_YUV_BT709.hlsl --- + Texture2D theTextureY : register(t0); + Texture2D theTextureU : register(t1); + Texture2D theTextureV : register(t2); + SamplerState theSampler : register(s0); + + struct PixelShaderInput + { + float4 pos : SV_POSITION; + float2 tex : TEXCOORD0; + float4 color : COLOR0; + }; + + #define YUVRS \ + "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \ + " DENY_DOMAIN_SHADER_ROOT_ACCESS |" \ + " DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \ + " DENY_HULL_SHADER_ROOT_ACCESS )," \ + "RootConstants(num32BitConstants=32, b0),"\ + "DescriptorTable ( SRV(t0), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( SRV(t1), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( SRV(t2), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( Sampler(s0), visibility = SHADER_VISIBILITY_PIXEL )" + + [RootSignature(YUVRS)] + float4 main(PixelShaderInput input) : SV_TARGET + { + const float3 offset = {-0.0627451017, -0.501960814, -0.501960814}; + const float3 Rcoeff = {1.1644, 0.0000, 1.7927}; + const float3 Gcoeff = {1.1644, -0.2132, -0.5329}; + const float3 Bcoeff = {1.1644, 2.1124, 0.0000}; + + float4 Output; + + float3 yuv; + yuv.x = theTextureY.Sample(theSampler, input.tex).r; + yuv.y = theTextureU.Sample(theSampler, input.tex).r; + yuv.z = theTextureV.Sample(theSampler, input.tex).r; + + yuv += offset; + Output.r = dot(yuv, Rcoeff); + Output.g = dot(yuv, Gcoeff); + Output.b = dot(yuv, Bcoeff); + Output.a = 1.0f; + + return Output * input.color; + } + +*/ + +static unsigned char D3D12_PixelShader_YUV_BT709[] = { + 0x44, 0x58, 0x42, 0x43, 0xe6, 0x97, 0xfb, 0x70, 0x81, 0x58, 0x82, 0x84, + 0xfd, 0xe7, 0xb6, 0x4d, 0x56, 0x90, 0xf8, 0x87, 0x01, 0x00, 0x00, 0x00, + 0x99, 0x13, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0xdb, 0x00, 0x00, 0x00, 0x15, 0x01, 0x00, 0x00, + 0x1d, 0x02, 0x00, 0x00, 0x05, 0x03, 0x00, 0x00, 0x95, 0x0b, 0x00, 0x00, + 0xb1, 0x0b, 0x00, 0x00, 0x53, 0x46, 0x49, 0x30, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31, + 0x83, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x53, 0x56, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, + 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x43, 0x4f, 0x4c, + 0x4f, 0x52, 0x00, 0x4f, 0x53, 0x47, 0x31, 0x32, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x00, 0x50, 0x53, 0x56, 0x30, 0x00, 0x01, 0x00, 0x00, 0x24, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x03, 0x01, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, + 0x52, 0x44, 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x44, 0x03, 0x03, 0x04, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x42, + 0x00, 0x03, 0x02, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x02, 0x44, 0x00, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x44, 0x10, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x52, 0x54, 0x53, 0x30, 0xe0, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x05, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xe0, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x05, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x05, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x05, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x05, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0xff, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, + 0x00, 0xc8, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xff, 0xff, 0x53, 0x54, 0x41, 0x54, 0x88, 0x08, 0x00, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x22, 0x02, 0x00, 0x00, 0x44, 0x58, 0x49, + 0x4c, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x70, 0x08, 0x00, + 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x19, 0x02, 0x00, + 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, + 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, + 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, + 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, + 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88, 0x48, 0x90, 0x14, + 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4, 0x48, 0x0e, + 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, + 0x8a, 0x04, 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40, 0x02, 0xa8, + 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x20, 0x6d, 0x30, 0x86, + 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x09, 0xa8, 0x00, 0x49, 0x18, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, 0x42, 0x20, 0x4c, 0x08, + 0x06, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x4b, 0x00, 0x00, + 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, + 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, + 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x78, 0x33, 0x00, 0xc3, 0x08, 0x04, + 0x30, 0x47, 0x00, 0x06, 0x33, 0xb5, 0xc1, 0x38, 0xb0, 0x43, 0x38, 0xcc, + 0xc3, 0x3c, 0xb8, 0x01, 0x2d, 0x94, 0x03, 0x3e, 0xd0, 0x43, 0x3d, 0xc8, + 0x43, 0x39, 0xc8, 0x01, 0x29, 0xf0, 0x81, 0x3d, 0x94, 0xc3, 0x38, 0xd0, + 0xc3, 0x3b, 0xc8, 0x03, 0x1f, 0x98, 0x03, 0x3b, 0xbc, 0x43, 0x38, 0xd0, + 0x03, 0x1b, 0x80, 0x01, 0x1d, 0xf8, 0x01, 0x18, 0xf8, 0x81, 0x1e, 0xe8, + 0x41, 0x3b, 0xa4, 0x03, 0x3c, 0xcc, 0xc3, 0x2f, 0xd0, 0x43, 0x3e, 0xc0, + 0x43, 0x39, 0xa0, 0x40, 0xcc, 0x24, 0x06, 0xe3, 0xc0, 0x0e, 0xe1, 0x30, + 0x0f, 0xf3, 0xe0, 0x06, 0xb4, 0x50, 0x0e, 0xf8, 0x40, 0x0f, 0xf5, 0x20, + 0x0f, 0xe5, 0x20, 0x07, 0xa4, 0xc0, 0x07, 0xf6, 0x50, 0x0e, 0xe3, 0x40, + 0x0f, 0xef, 0x20, 0x0f, 0x7c, 0x60, 0x0e, 0xec, 0xf0, 0x0e, 0xe1, 0x40, + 0x0f, 0x6c, 0x00, 0x06, 0x74, 0xe0, 0x07, 0x60, 0xe0, 0x07, 0x48, 0x08, + 0x83, 0xc8, 0x4d, 0xd2, 0x14, 0x51, 0xc2, 0xe4, 0xb3, 0x00, 0xf3, 0x2c, + 0x44, 0xc4, 0x4e, 0xc0, 0x44, 0xa0, 0x40, 0x90, 0x19, 0x01, 0x28, 0x01, + 0xa2, 0x34, 0x47, 0x80, 0x14, 0x03, 0x08, 0x21, 0x96, 0x20, 0x56, 0x0c, + 0x24, 0x84, 0x58, 0x80, 0xdc, 0x4d, 0xc3, 0xe5, 0x4f, 0xd8, 0x43, 0x48, + 0xfe, 0x4a, 0x48, 0x2b, 0x31, 0xf9, 0xc5, 0x6d, 0xa3, 0x02, 0x00, 0x00, + 0x04, 0xad, 0x7b, 0x86, 0xcb, 0x9f, 0xb0, 0x87, 0x90, 0xfc, 0x10, 0x68, + 0x86, 0x85, 0x40, 0x41, 0x2c, 0x0c, 0x14, 0x52, 0x02, 0x00, 0x80, 0x10, + 0x02, 0xd0, 0x2c, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0xd5, 0x39, 0x82, + 0xa0, 0x18, 0x52, 0x2c, 0x21, 0x2e, 0xe1, 0x81, 0x80, 0x61, 0x04, 0x01, + 0xb8, 0x4b, 0x9a, 0x22, 0x4a, 0x98, 0xfc, 0x14, 0xb9, 0x88, 0x85, 0x3d, + 0x80, 0x81, 0x88, 0xc4, 0xe6, 0xa1, 0x26, 0x34, 0x84, 0x1d, 0xd2, 0x41, + 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, + 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e, 0x6d, 0xd0, + 0x0e, 0x7a, 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, + 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, + 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, + 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x10, 0x07, 0x76, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x3a, 0x0f, 0x64, 0x90, 0x21, + 0x23, 0x45, 0x44, 0x00, 0x72, 0x00, 0xc0, 0xe4, 0x00, 0x80, 0xc9, 0x01, + 0x00, 0xd3, 0x03, 0x00, 0x1e, 0xf2, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xe4, 0x61, 0x80, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xc8, 0xe3, 0x00, 0x01, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x90, 0x67, 0x02, 0x02, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x21, 0x4f, 0x05, + 0x04, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x1e, + 0x0c, 0x08, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb2, + 0x40, 0x15, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x18, 0x19, 0x11, 0x4c, + 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x5a, 0x05, 0x42, 0xa2, + 0x04, 0x46, 0x00, 0x8a, 0xa1, 0x08, 0x4a, 0xa2, 0x50, 0xca, 0xa0, 0x1c, + 0x0a, 0xa4, 0x10, 0x4a, 0xa1, 0xc0, 0x0a, 0xa8, 0x3c, 0x8a, 0x87, 0x56, + 0x11, 0x8c, 0x00, 0x14, 0x42, 0x19, 0x94, 0x04, 0x9d, 0x19, 0x00, 0x2a, + 0x33, 0x00, 0x44, 0x66, 0x00, 0x68, 0xcc, 0x00, 0x50, 0x98, 0x01, 0x20, + 0x3e, 0x03, 0x40, 0x7d, 0x2c, 0x87, 0x21, 0x00, 0x00, 0x00, 0x8e, 0x03, + 0x00, 0x02, 0x81, 0x40, 0x00, 0x79, 0x18, 0x00, 0x00, 0xc4, 0x00, 0x00, + 0x00, 0x1a, 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, 0x44, 0x35, 0x18, 0x63, + 0x0b, 0x73, 0x3b, 0x03, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x03, + 0x99, 0x71, 0xb9, 0x01, 0x41, 0xa1, 0x0b, 0x3b, 0x9b, 0x7b, 0x91, 0x2a, + 0x62, 0x2a, 0x0a, 0x9a, 0x2a, 0xfa, 0x9a, 0xb9, 0x81, 0x79, 0x31, 0x4b, + 0x73, 0x0b, 0x63, 0x4b, 0xd9, 0x10, 0x04, 0x13, 0x04, 0x61, 0x99, 0x20, + 0x08, 0xcc, 0x06, 0x61, 0x20, 0x36, 0x08, 0x04, 0x41, 0x01, 0x6e, 0x6e, + 0x82, 0x20, 0x34, 0x1b, 0x86, 0x03, 0x21, 0x26, 0x08, 0x05, 0x18, 0x70, + 0xa1, 0x43, 0x2b, 0xa3, 0x2a, 0xc3, 0xa3, 0xab, 0x93, 0x2b, 0xcb, 0x9a, + 0x20, 0x08, 0xce, 0x04, 0x41, 0x78, 0x36, 0x08, 0x44, 0xb3, 0x21, 0x21, + 0x94, 0x85, 0x20, 0x06, 0x86, 0x70, 0xb8, 0xd0, 0xa1, 0x95, 0x51, 0x95, + 0xe1, 0xd1, 0xd5, 0xc9, 0x95, 0x55, 0x6d, 0x48, 0x06, 0x05, 0x22, 0x86, + 0x81, 0x21, 0x1c, 0x2e, 0x74, 0x68, 0x65, 0x54, 0x65, 0x78, 0x74, 0x75, + 0x72, 0x65, 0x56, 0x1b, 0x12, 0x46, 0x91, 0x08, 0x66, 0x60, 0x08, 0x67, + 0xc3, 0xf0, 0x44, 0xd3, 0x04, 0xe1, 0xf8, 0xa8, 0xd0, 0xa1, 0x95, 0x4d, + 0x85, 0xb5, 0xc1, 0xb1, 0x95, 0xc9, 0x6d, 0x40, 0x88, 0xca, 0x22, 0x88, + 0x81, 0x00, 0x36, 0x04, 0xd7, 0x06, 0x82, 0x02, 0x00, 0x6c, 0x82, 0x40, + 0x84, 0xc1, 0x04, 0x41, 0x80, 0x18, 0xa0, 0x4d, 0x10, 0x84, 0x68, 0x82, + 0x20, 0x48, 0x1b, 0x0c, 0x84, 0xeb, 0x08, 0xaf, 0x21, 0xd1, 0x96, 0x06, + 0x37, 0x37, 0x41, 0x10, 0xa6, 0x0d, 0x04, 0x02, 0x06, 0x5d, 0x18, 0x4c, + 0x10, 0x82, 0x31, 0xd8, 0x20, 0x10, 0x63, 0xb0, 0x21, 0x20, 0x83, 0x0d, + 0x02, 0x51, 0x06, 0x1b, 0x88, 0xed, 0x13, 0x03, 0x33, 0x98, 0x20, 0x0c, + 0x62, 0x30, 0x41, 0x10, 0x28, 0x1a, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, + 0x13, 0x04, 0xa1, 0xda, 0x60, 0x20, 0x6a, 0xd0, 0x11, 0xde, 0x1a, 0x6c, + 0x10, 0xd2, 0x80, 0x0d, 0x26, 0x08, 0x1c, 0x19, 0x4c, 0x10, 0x04, 0x8b, + 0x03, 0xdc, 0xdb, 0x1c, 0x97, 0x29, 0xab, 0x2f, 0xa8, 0xa7, 0xa9, 0x24, + 0xaa, 0xa4, 0x27, 0xa7, 0x0d, 0x08, 0x02, 0x07, 0x1d, 0x91, 0x06, 0x71, + 0xe0, 0x35, 0x1c, 0xe8, 0xca, 0xf0, 0x98, 0x50, 0x15, 0x61, 0x0d, 0x3d, + 0x3d, 0x49, 0x11, 0xc1, 0x6c, 0x40, 0x90, 0x39, 0xe8, 0xc2, 0x20, 0x0d, + 0xe8, 0xc0, 0x6b, 0x58, 0x8c, 0xbd, 0xb1, 0xbd, 0xc9, 0x4d, 0x10, 0x84, + 0x8b, 0xc6, 0xd0, 0x13, 0xd3, 0x93, 0x14, 0xcc, 0x06, 0x04, 0xb1, 0x83, + 0xee, 0x0e, 0xd2, 0x00, 0x0f, 0xbc, 0x66, 0x03, 0xf1, 0x06, 0x72, 0x50, + 0x07, 0x79, 0xb0, 0xe1, 0x20, 0xb4, 0x33, 0x40, 0x83, 0x36, 0x70, 0x03, + 0x3d, 0x98, 0x20, 0x28, 0xc4, 0x06, 0x60, 0xc3, 0x40, 0xf4, 0x41, 0x1f, + 0x6c, 0x08, 0xfc, 0x60, 0xc3, 0x30, 0xf0, 0xc1, 0x1f, 0x4c, 0x10, 0xba, + 0x32, 0xd8, 0x10, 0x84, 0x02, 0x89, 0xb6, 0xb0, 0x34, 0x37, 0x2e, 0x53, + 0x56, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x13, 0x84, + 0xc5, 0x9b, 0x20, 0x2c, 0xdd, 0x86, 0x80, 0x98, 0x20, 0x2c, 0xdc, 0x04, + 0x61, 0xd9, 0x36, 0x2c, 0x04, 0x29, 0x94, 0x82, 0x29, 0x9c, 0x02, 0x2a, + 0x0c, 0xa8, 0x40, 0xa4, 0x02, 0x40, 0x84, 0xaa, 0x08, 0x6b, 0xe8, 0xe9, + 0x49, 0x8a, 0x68, 0x82, 0xb0, 0x68, 0x1b, 0x84, 0xae, 0xdb, 0xb0, 0x0c, + 0xab, 0x50, 0x0a, 0xa9, 0x70, 0x0a, 0xac, 0x30, 0xb0, 0xc2, 0x90, 0x0a, + 0xad, 0xc0, 0x62, 0xe8, 0x89, 0xe9, 0x49, 0x6a, 0x82, 0x20, 0x60, 0x1b, + 0x84, 0x0e, 0x16, 0x36, 0x2c, 0xcc, 0x2b, 0x94, 0x42, 0x2a, 0x9c, 0x02, + 0x2b, 0x0c, 0xa8, 0xc0, 0xa4, 0x42, 0x2c, 0x6c, 0x18, 0x54, 0xc1, 0x15, + 0x64, 0x81, 0xc9, 0x94, 0xd5, 0x17, 0x55, 0x98, 0xdc, 0x59, 0x19, 0xdd, + 0x04, 0x61, 0x51, 0x36, 0x2c, 0x04, 0x2d, 0x94, 0x42, 0x2d, 0x9c, 0x42, + 0x2a, 0x0c, 0xa8, 0x40, 0xa4, 0x42, 0x2c, 0x6c, 0x08, 0x6c, 0x61, 0xc3, + 0x30, 0x0b, 0xb7, 0x00, 0x6c, 0x28, 0xf8, 0x60, 0x14, 0x70, 0x21, 0x03, + 0x68, 0x98, 0xb1, 0xbd, 0x85, 0xd1, 0xcd, 0xb1, 0x48, 0x73, 0x9b, 0xa3, + 0x9b, 0x9b, 0x20, 0x08, 0x19, 0x8d, 0xb9, 0xb4, 0xb3, 0x2f, 0x36, 0x32, + 0x1a, 0x73, 0x69, 0x67, 0x5f, 0x73, 0x74, 0x44, 0xe8, 0xca, 0xf0, 0xbe, + 0xdc, 0xde, 0xe4, 0xda, 0x36, 0x28, 0xba, 0xd0, 0xec, 0x02, 0x2f, 0xf4, + 0x02, 0xe2, 0x0b, 0x69, 0xf0, 0x0b, 0x5d, 0x15, 0x36, 0x36, 0xbb, 0x36, + 0x97, 0x34, 0xb2, 0x32, 0x37, 0xba, 0x29, 0x41, 0x50, 0x85, 0x0c, 0xcf, + 0xc5, 0xae, 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x6d, 0x4a, 0x40, 0x34, 0x21, + 0xc3, 0x73, 0xb1, 0x0b, 0x63, 0xb3, 0x2b, 0x93, 0x9b, 0x12, 0x14, 0x75, + 0xc8, 0xf0, 0x5c, 0xe6, 0xd0, 0xc2, 0xc8, 0xca, 0xe4, 0x9a, 0xde, 0xc8, + 0xca, 0xd8, 0xa6, 0x04, 0x48, 0x19, 0x32, 0x3c, 0x17, 0xb9, 0xb2, 0xb9, + 0xb7, 0x3a, 0xb9, 0xb1, 0xb2, 0xb9, 0x29, 0x01, 0x56, 0x89, 0x0c, 0xcf, + 0x85, 0x2e, 0x0f, 0xae, 0x2c, 0xc8, 0xcd, 0xed, 0x8d, 0x2e, 0x8c, 0x2e, + 0xed, 0xcd, 0x6d, 0x6e, 0x8a, 0xa0, 0x07, 0x7f, 0x50, 0x87, 0x0c, 0xcf, + 0xc5, 0x2e, 0xad, 0xec, 0x2e, 0x89, 0x6c, 0x8a, 0x2e, 0x8c, 0xae, 0x6c, + 0x4a, 0x10, 0x0a, 0x75, 0xc8, 0xf0, 0x5c, 0xca, 0xdc, 0xe8, 0xe4, 0xf2, + 0xa0, 0xde, 0xd2, 0xdc, 0xe8, 0xe6, 0xa6, 0x04, 0xb8, 0xd0, 0x85, 0x0c, + 0xcf, 0x65, 0xec, 0xad, 0xce, 0x8d, 0xae, 0x4c, 0x6e, 0x6e, 0x4a, 0xf0, + 0x0b, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x4c, 0x00, 0x00, + 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, + 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, + 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, + 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, + 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, + 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, + 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, + 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, + 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, + 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, + 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, + 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, + 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, + 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, + 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, + 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, + 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, + 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, + 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, + 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, + 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, + 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, + 0xc4, 0x21, 0x07, 0x7c, 0x70, 0x03, 0x7a, 0x28, 0x87, 0x76, 0x80, 0x87, + 0x19, 0xd1, 0x43, 0x0e, 0xf8, 0xe0, 0x06, 0xe4, 0x20, 0x0e, 0xe7, 0xe0, + 0x06, 0xf6, 0x10, 0x0e, 0xf2, 0xc0, 0x0e, 0xe1, 0x90, 0x0f, 0xef, 0x50, + 0x0f, 0xf4, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x3e, 0x00, 0x00, + 0x00, 0x35, 0xf0, 0x05, 0x7e, 0x74, 0x74, 0x79, 0x1a, 0x6e, 0xc3, 0xd9, + 0x65, 0x39, 0x10, 0x38, 0xab, 0x4e, 0xc3, 0x6d, 0x38, 0xbb, 0x2c, 0x9f, + 0xd2, 0xc3, 0xf4, 0x32, 0x10, 0x18, 0xac, 0x00, 0x38, 0x08, 0xfc, 0xe8, + 0xe8, 0x32, 0xb5, 0x8c, 0xa7, 0xd7, 0xe5, 0xe5, 0x2a, 0x10, 0x38, 0xb3, + 0xfe, 0x48, 0xd4, 0x32, 0x9e, 0x5e, 0x97, 0x97, 0x65, 0x44, 0xa0, 0xf5, + 0x47, 0xb2, 0x97, 0xc7, 0xf4, 0xb7, 0x1c, 0xd8, 0x24, 0xc1, 0x66, 0x40, + 0x20, 0x10, 0x18, 0x2c, 0x01, 0x38, 0x08, 0xfc, 0xe8, 0xe8, 0x32, 0xb5, + 0x8c, 0xa7, 0xd7, 0xe5, 0x65, 0x2b, 0x10, 0x38, 0xb3, 0xfe, 0x48, 0xd4, + 0x32, 0x9e, 0x5e, 0x97, 0x97, 0x65, 0x44, 0xa0, 0xf5, 0x47, 0xb2, 0x97, + 0xc7, 0xf4, 0xb7, 0x1c, 0xd8, 0x24, 0xc1, 0x66, 0x40, 0x20, 0x10, 0x18, + 0x2c, 0x00, 0x38, 0x08, 0xfc, 0xe8, 0xe8, 0x32, 0xb5, 0x8c, 0xa7, 0xd7, + 0xe5, 0xe5, 0x2c, 0x10, 0x38, 0xb3, 0xfe, 0x48, 0xd4, 0x32, 0x9e, 0x5e, + 0x97, 0x97, 0x65, 0x44, 0xa0, 0xf5, 0x47, 0xb2, 0x97, 0xc7, 0xf4, 0xb7, + 0x1c, 0xd8, 0x24, 0xc1, 0x66, 0x40, 0x20, 0x10, 0x18, 0xb4, 0x04, 0x69, + 0xb8, 0x7c, 0xe7, 0xf1, 0x85, 0x88, 0x00, 0x26, 0x22, 0x04, 0x9a, 0x61, + 0x21, 0x0c, 0xc1, 0x19, 0x2e, 0xdf, 0x79, 0xfc, 0xc1, 0x99, 0x6e, 0xbf, + 0xb8, 0x6d, 0x2b, 0x98, 0x86, 0xcb, 0x77, 0x1e, 0x7f, 0x71, 0x80, 0x41, + 0x6c, 0x1e, 0x6a, 0xf2, 0x8b, 0xdb, 0xb6, 0x03, 0x68, 0xb8, 0x7c, 0xe7, + 0xf1, 0x25, 0x80, 0x79, 0x16, 0xc2, 0x2f, 0x6e, 0xdb, 0x0c, 0xaa, 0xe1, + 0xf2, 0x9d, 0xc7, 0x97, 0x26, 0x27, 0x22, 0x50, 0x6a, 0x7a, 0xa8, 0xc9, + 0x2f, 0x6e, 0xdb, 0x08, 0x08, 0x06, 0x40, 0x1a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x48, 0x41, 0x53, 0x48, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x28, 0xea, 0x91, 0x74, 0x07, 0xef, 0x37, 0x34, 0xc5, 0x63, 0xc4, + 0x30, 0x49, 0xbf, 0x93, 0x8b, 0x44, 0x58, 0x49, 0x4c, 0xe0, 0x07, 0x00, + 0x00, 0x60, 0x00, 0x00, 0x00, 0xf8, 0x01, 0x00, 0x00, 0x44, 0x58, 0x49, + 0x4c, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xc8, 0x07, 0x00, + 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0xef, 0x01, 0x00, + 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, + 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, + 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, + 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, + 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88, 0x48, 0x90, 0x14, + 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4, 0x48, 0x0e, + 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, + 0x8a, 0x04, 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40, 0x02, 0xa8, + 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x20, 0x6d, 0x30, 0x86, + 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x09, 0xa8, 0x00, 0x49, 0x18, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, 0x42, 0x20, 0x4c, 0x08, + 0x06, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x45, 0x00, 0x00, + 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, + 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, + 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x70, 0x23, 0x00, 0x25, 0x00, 0x14, + 0x66, 0x00, 0xe6, 0x08, 0xc0, 0x60, 0x8e, 0x00, 0x29, 0xc6, 0x20, 0x84, + 0x14, 0x42, 0xa6, 0x18, 0x80, 0x10, 0x52, 0x06, 0xa1, 0x9b, 0x86, 0xcb, + 0x9f, 0xb0, 0x87, 0x90, 0xfc, 0x95, 0x90, 0x56, 0x62, 0xf2, 0x8b, 0xdb, + 0x46, 0xc5, 0x18, 0x63, 0x10, 0x2a, 0xf7, 0x0c, 0x97, 0x3f, 0x61, 0x0f, + 0x21, 0xf9, 0x21, 0xd0, 0x0c, 0x0b, 0x81, 0x82, 0x55, 0x18, 0x45, 0x18, + 0x1b, 0x63, 0x0c, 0x42, 0xc8, 0xa0, 0x56, 0x90, 0x41, 0xc6, 0x18, 0x63, + 0x0c, 0x7a, 0x73, 0x04, 0x41, 0x31, 0x18, 0x29, 0x84, 0x44, 0x92, 0x03, + 0x01, 0xc3, 0x08, 0xc4, 0x30, 0x53, 0x1b, 0x8c, 0x03, 0x3b, 0x84, 0xc3, + 0x3c, 0xcc, 0x83, 0x1b, 0xd0, 0x42, 0x39, 0xe0, 0x03, 0x3d, 0xd4, 0x83, + 0x3c, 0x94, 0x83, 0x1c, 0x90, 0x02, 0x1f, 0xd8, 0x43, 0x39, 0x8c, 0x03, + 0x3d, 0xbc, 0x83, 0x3c, 0xf0, 0x81, 0x39, 0xb0, 0xc3, 0x3b, 0x84, 0x03, + 0x3d, 0xb0, 0x01, 0x18, 0xd0, 0x81, 0x1f, 0x80, 0x81, 0x1f, 0xe8, 0x81, + 0x1e, 0xb4, 0x43, 0x3a, 0xc0, 0xc3, 0x3c, 0xfc, 0x02, 0x3d, 0xe4, 0x03, + 0x3c, 0x94, 0x03, 0x0a, 0xc8, 0x4c, 0x62, 0x30, 0x0e, 0xec, 0x10, 0x0e, + 0xf3, 0x30, 0x0f, 0x6e, 0x40, 0x0b, 0xe5, 0x80, 0x0f, 0xf4, 0x50, 0x0f, + 0xf2, 0x50, 0x0e, 0x72, 0x40, 0x0a, 0x7c, 0x60, 0x0f, 0xe5, 0x30, 0x0e, + 0xf4, 0xf0, 0x0e, 0xf2, 0xc0, 0x07, 0xe6, 0xc0, 0x0e, 0xef, 0x10, 0x0e, + 0xf4, 0xc0, 0x06, 0x60, 0x40, 0x07, 0x7e, 0x00, 0x06, 0x7e, 0x80, 0x84, + 0x6a, 0xe9, 0xde, 0x24, 0x4d, 0x11, 0x25, 0x4c, 0x3e, 0x0b, 0x30, 0xcf, + 0x42, 0x44, 0xec, 0x04, 0x4c, 0x04, 0x0a, 0x08, 0xe5, 0x74, 0x20, 0x00, + 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, + 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e, 0x6d, 0xd0, + 0x0e, 0x7a, 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, + 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, + 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, + 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x10, 0x07, 0x76, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x43, 0x9e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x3c, 0x06, 0x10, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x79, 0x10, + 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf2, + 0x34, 0x40, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, + 0xe4, 0x79, 0x80, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0xc8, 0x23, 0x01, 0x01, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x16, 0x08, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, + 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, + 0x22, 0x25, 0x30, 0x02, 0x50, 0x0c, 0x45, 0x50, 0x12, 0x65, 0x50, 0x1e, + 0x54, 0x4a, 0xa2, 0x0c, 0x0a, 0x61, 0x04, 0xa0, 0x08, 0x0a, 0x84, 0xf0, + 0x0c, 0x00, 0xe9, 0x19, 0x00, 0xda, 0x63, 0x39, 0x0c, 0x01, 0x00, 0x00, + 0x70, 0x1c, 0x00, 0x10, 0x08, 0x04, 0x02, 0x00, 0x00, 0x79, 0x18, 0x00, + 0x00, 0x69, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, + 0x44, 0x35, 0x18, 0x63, 0x0b, 0x73, 0x3b, 0x03, 0xb1, 0x2b, 0x93, 0x9b, + 0x4b, 0x7b, 0x73, 0x03, 0x99, 0x71, 0xb9, 0x01, 0x41, 0xa1, 0x0b, 0x3b, + 0x9b, 0x7b, 0x91, 0x2a, 0x62, 0x2a, 0x0a, 0x9a, 0x2a, 0xfa, 0x9a, 0xb9, + 0x81, 0x79, 0x31, 0x4b, 0x73, 0x0b, 0x63, 0x4b, 0xd9, 0x10, 0x04, 0x13, + 0x04, 0xc2, 0x98, 0x20, 0x10, 0xc7, 0x06, 0x61, 0x20, 0x26, 0x08, 0x04, + 0xb2, 0x41, 0x18, 0x0c, 0x0a, 0x70, 0x73, 0x1b, 0x06, 0xc4, 0x20, 0x26, + 0x08, 0xd8, 0x44, 0x60, 0x82, 0x40, 0x24, 0x13, 0x04, 0x42, 0xd9, 0x20, + 0x10, 0xcd, 0x86, 0x84, 0x50, 0x16, 0x82, 0x18, 0x18, 0xc2, 0xd9, 0x90, + 0x0c, 0xca, 0x42, 0x0c, 0x03, 0x43, 0x38, 0x1b, 0x12, 0x46, 0x59, 0x08, + 0x66, 0x60, 0x08, 0x67, 0xc3, 0xf0, 0x40, 0xd1, 0x04, 0x41, 0xa3, 0x36, + 0x20, 0xc4, 0xb4, 0x10, 0xc4, 0x40, 0x00, 0x1b, 0x02, 0x6a, 0x03, 0x21, + 0x01, 0x40, 0x35, 0x41, 0xd8, 0xaa, 0x0d, 0xc1, 0x35, 0x41, 0x10, 0x00, + 0x12, 0x6d, 0x61, 0x69, 0x6e, 0x5c, 0xa6, 0xac, 0xbe, 0xa0, 0xde, 0xe6, + 0xd2, 0xe8, 0xd2, 0xde, 0xdc, 0x26, 0x08, 0x45, 0x33, 0x41, 0x28, 0x9c, + 0x0d, 0x01, 0x31, 0x41, 0x28, 0x9e, 0x09, 0x42, 0x01, 0x6d, 0x58, 0x88, + 0x8d, 0xeb, 0xbc, 0x6f, 0xf8, 0x08, 0x30, 0x00, 0x88, 0x50, 0x15, 0x61, + 0x0d, 0x3d, 0x3d, 0x49, 0x11, 0x4d, 0x10, 0x8a, 0x68, 0x82, 0x40, 0x2c, + 0x1b, 0x04, 0x32, 0x20, 0x83, 0x0d, 0xcb, 0x20, 0x06, 0x1c, 0x18, 0x78, + 0x63, 0x30, 0x8c, 0xc1, 0x00, 0x06, 0x65, 0xc0, 0x62, 0xe8, 0x89, 0xe9, + 0x49, 0x6a, 0x82, 0x40, 0x30, 0x1b, 0x04, 0x32, 0x40, 0x83, 0x0d, 0x0b, + 0x73, 0x06, 0x1c, 0x18, 0x78, 0x63, 0x30, 0x7c, 0x0c, 0x18, 0xa4, 0xc1, + 0x86, 0x21, 0x0c, 0xcc, 0x40, 0x0d, 0x98, 0x4c, 0x59, 0x7d, 0x51, 0x85, + 0xc9, 0x9d, 0x95, 0xd1, 0x4d, 0x10, 0x0a, 0x69, 0xc3, 0x42, 0xb0, 0x01, + 0xd7, 0x06, 0x1e, 0x18, 0x0c, 0x1f, 0x01, 0x06, 0x69, 0xb0, 0x21, 0x70, + 0x83, 0x0d, 0xc3, 0x1a, 0xbc, 0x01, 0xb0, 0xa1, 0xc8, 0x34, 0x38, 0xb0, + 0x80, 0x2a, 0x6c, 0x6c, 0x76, 0x6d, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, + 0x53, 0x82, 0xa0, 0x0a, 0x19, 0x9e, 0x8b, 0x5d, 0x99, 0xdc, 0x5c, 0xda, + 0x9b, 0xdb, 0x94, 0x80, 0x68, 0x42, 0x86, 0xe7, 0x62, 0x17, 0xc6, 0x66, + 0x57, 0x26, 0x37, 0x25, 0x30, 0xea, 0x90, 0xe1, 0xb9, 0xcc, 0xa1, 0x85, + 0x91, 0x95, 0xc9, 0x35, 0xbd, 0x91, 0x95, 0xb1, 0x4d, 0x09, 0x90, 0x32, + 0x64, 0x78, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, + 0x53, 0x82, 0xaa, 0x0e, 0x19, 0x9e, 0x8b, 0x5d, 0x5a, 0xd9, 0x5d, 0x12, + 0xd9, 0x14, 0x5d, 0x18, 0x5d, 0xd9, 0x94, 0xe0, 0xaa, 0x43, 0x86, 0xe7, + 0x52, 0xe6, 0x46, 0x27, 0x97, 0x07, 0xf5, 0x96, 0xe6, 0x46, 0x37, 0x37, + 0x25, 0x80, 0x03, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x4c, 0x00, 0x00, + 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, + 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, + 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, + 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, + 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, + 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, + 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, + 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, + 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, + 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, + 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, + 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, + 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, + 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, + 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, + 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, + 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, + 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, + 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, + 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, + 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, + 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, + 0xc4, 0x21, 0x07, 0x7c, 0x70, 0x03, 0x7a, 0x28, 0x87, 0x76, 0x80, 0x87, + 0x19, 0xd1, 0x43, 0x0e, 0xf8, 0xe0, 0x06, 0xe4, 0x20, 0x0e, 0xe7, 0xe0, + 0x06, 0xf6, 0x10, 0x0e, 0xf2, 0xc0, 0x0e, 0xe1, 0x90, 0x0f, 0xef, 0x50, + 0x0f, 0xf4, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x15, 0x00, 0x00, + 0x00, 0x56, 0x20, 0x0d, 0x97, 0xef, 0x3c, 0xbe, 0x10, 0x11, 0xc0, 0x44, + 0x84, 0x40, 0x33, 0x2c, 0x84, 0x11, 0x38, 0xc3, 0xe5, 0x3b, 0x8f, 0x3f, + 0x38, 0xd3, 0xed, 0x17, 0xb7, 0x6d, 0x01, 0xd3, 0x70, 0xf9, 0xce, 0xe3, + 0x2f, 0x0e, 0x30, 0x88, 0xcd, 0x43, 0x4d, 0x7e, 0x71, 0xdb, 0x36, 0x00, + 0x0d, 0x97, 0xef, 0x3c, 0xbe, 0x04, 0x30, 0xcf, 0x42, 0xf8, 0xc5, 0x6d, + 0x9b, 0x40, 0x35, 0x5c, 0xbe, 0xf3, 0xf8, 0xd2, 0xe4, 0x44, 0x04, 0x4a, + 0x4d, 0x0f, 0x35, 0xf9, 0xc5, 0x6d, 0x1b, 0x00, 0xc1, 0x00, 0x48, 0x03, + 0x00, 0x61, 0x20, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, + 0x2c, 0x10, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x47, 0x00, + 0xa8, 0x94, 0x00, 0x91, 0x72, 0x2b, 0xbc, 0x52, 0x28, 0xb9, 0x42, 0x98, + 0x01, 0xa0, 0x31, 0x46, 0x00, 0xb3, 0xac, 0x0b, 0x82, 0xc1, 0x18, 0x81, + 0x18, 0xee, 0x30, 0xfc, 0x0b, 0x63, 0x04, 0x3a, 0x4a, 0xd3, 0xe5, 0x2f, + 0x8c, 0x11, 0xc8, 0x79, 0xaf, 0xfa, 0xdf, 0x18, 0x41, 0x48, 0x82, 0x21, + 0xee, 0x0b, 0x23, 0x00, 0x63, 0x04, 0x21, 0x09, 0x86, 0xf0, 0x2f, 0x8c, + 0x11, 0xbc, 0xb8, 0xa8, 0xe6, 0xdf, 0x0c, 0x00, 0x00, 0x23, 0x06, 0x09, + 0x00, 0x82, 0x60, 0x20, 0x89, 0x01, 0x73, 0x79, 0x5e, 0x34, 0x62, 0x90, + 0x00, 0x20, 0x08, 0x06, 0xd2, 0x18, 0x34, 0x98, 0x18, 0x88, 0x81, 0x34, + 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x12, 0x19, 0x38, 0x99, 0x18, 0x88, + 0xc1, 0x34, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x52, 0x19, 0x3c, 0xdc, + 0x18, 0x8c, 0x01, 0x35, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x86, 0x1a, + 0x3c, 0x62, 0x40, 0x06, 0x9b, 0x33, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, + 0xc6, 0x1a, 0x40, 0x63, 0x50, 0x06, 0xd5, 0x33, 0x62, 0x90, 0x00, 0x20, + 0x08, 0x06, 0x06, 0x1b, 0x44, 0x64, 0x60, 0x06, 0x1c, 0x34, 0x62, 0x90, + 0x00, 0x20, 0x08, 0x06, 0x46, 0x1b, 0x48, 0x65, 0x70, 0x06, 0x60, 0x10, + 0x8d, 0x18, 0x24, 0x00, 0x08, 0x82, 0x81, 0xe1, 0x06, 0x53, 0x1a, 0xa0, + 0xc1, 0x27, 0x8d, 0x18, 0x24, 0x00, 0x08, 0x82, 0x81, 0xf1, 0x06, 0x94, + 0x1a, 0xa4, 0x41, 0x36, 0x8d, 0x18, 0x3c, 0x00, 0x08, 0x82, 0x41, 0xe3, + 0x06, 0x18, 0x72, 0x08, 0xc1, 0xb2, 0xa8, 0x81, 0x1a, 0x50, 0xcb, 0x68, + 0x42, 0x00, 0x8c, 0x18, 0x3c, 0x00, 0x08, 0x82, 0x41, 0x03, 0x07, 0xda, + 0x92, 0x10, 0x43, 0xd3, 0xb0, 0x01, 0x1b, 0x58, 0xcd, 0x68, 0x42, 0x00, + 0x8c, 0x18, 0x3c, 0x00, 0x08, 0x82, 0x41, 0x23, 0x07, 0x9c, 0xb3, 0x18, + 0xc5, 0xf3, 0xb8, 0x81, 0x1b, 0x60, 0xcf, 0x68, 0x42, 0x00, 0x58, 0x51, + 0xc1, 0xc7, 0x08, 0x0a, 0x3e, 0x36, 0x54, 0xf0, 0x19, 0x31, 0x58, 0x00, + 0x10, 0x04, 0x83, 0xc7, 0x0e, 0xc4, 0x60, 0x10, 0x82, 0xea, 0xca, 0x46, + 0x0c, 0x16, 0x00, 0x04, 0xc1, 0xe0, 0xb9, 0x83, 0x31, 0x20, 0x06, 0xc1, + 0xda, 0xb8, 0x11, 0x83, 0x05, 0x00, 0x41, 0x30, 0x78, 0xf0, 0x80, 0x0c, + 0x0a, 0x62, 0xb8, 0xbc, 0xcc, 0x06, 0x49, 0x3e, 0x36, 0x48, 0xf2, 0xb1, + 0x41, 0x92, 0xcf, 0x88, 0x41, 0x02, 0x80, 0x20, 0x18, 0x20, 0x7e, 0x60, + 0x06, 0x79, 0x90, 0x07, 0x70, 0x30, 0x8c, 0x18, 0x24, 0x00, 0x08, 0x82, + 0x01, 0xe2, 0x07, 0x66, 0x90, 0x07, 0x79, 0x90, 0x06, 0xc2, 0x88, 0x41, + 0x02, 0x80, 0x20, 0x18, 0x20, 0x7e, 0x60, 0x06, 0x79, 0x90, 0x07, 0x6f, + 0x10, 0x8c, 0x18, 0x24, 0x00, 0x08, 0x82, 0x01, 0xe2, 0x07, 0x66, 0x90, + 0x07, 0x79, 0x20, 0x07, 0x12, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 +}; + +/* The yuv-rendering pixel shader: + + --- D3D12_PixelShader_NV12_JPEG.hlsl --- + Texture2D theTextureY : register(t0); + Texture2D theTextureUV : register(t1); + SamplerState theSampler : register(s0); + + struct PixelShaderInput + { + float4 pos : SV_POSITION; + float2 tex : TEXCOORD0; + float4 color : COLOR0; + }; + + #define NVRS \ + "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \ + " DENY_DOMAIN_SHADER_ROOT_ACCESS |" \ + " DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \ + " DENY_HULL_SHADER_ROOT_ACCESS )," \ + "RootConstants(num32BitConstants=32, b0),"\ + "DescriptorTable ( SRV(t0), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( SRV(t1), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( Sampler(s0), visibility = SHADER_VISIBILITY_PIXEL )" + + [RootSignature(NVRS)] + float4 main(PixelShaderInput input) : SV_TARGET + { + const float3 offset = {0.0, -0.501960814, -0.501960814}; + const float3 Rcoeff = {1.0000, 0.0000, 1.4020}; + const float3 Gcoeff = {1.0000, -0.3441, -0.7141}; + const float3 Bcoeff = {1.0000, 1.7720, 0.0000}; + + float4 Output; + + float3 yuv; + yuv.x = theTextureY.Sample(theSampler, input.tex).r; + yuv.yz = theTextureUV.Sample(theSampler, input.tex).rg; + + yuv += offset; + Output.r = dot(yuv, Rcoeff); + Output.g = dot(yuv, Gcoeff); + Output.b = dot(yuv, Bcoeff); + Output.a = 1.0f; + + return Output * input.color; + } + +*/ + +static unsigned char D3D12_PixelShader_NV12_JPEG[] = { + 0x44, 0x58, 0x42, 0x43, 0x4d, 0x84, 0xab, 0xd3, 0xf9, 0x2a, 0x29, 0x46, + 0xc8, 0x39, 0x22, 0xd6, 0x7a, 0xdf, 0x22, 0x16, 0x01, 0x00, 0x00, 0x00, + 0xe1, 0x12, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0xdb, 0x00, 0x00, 0x00, 0x15, 0x01, 0x00, 0x00, + 0x0d, 0x02, 0x00, 0x00, 0xc9, 0x02, 0x00, 0x00, 0x1d, 0x0b, 0x00, 0x00, + 0x39, 0x0b, 0x00, 0x00, 0x53, 0x46, 0x49, 0x30, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31, + 0x83, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x53, 0x56, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, + 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x43, 0x4f, 0x4c, + 0x4f, 0x52, 0x00, 0x4f, 0x53, 0x47, 0x31, 0x32, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x00, 0x50, 0x53, 0x56, 0x30, 0xf0, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x03, 0x01, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x43, + 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x44, 0x03, 0x03, 0x04, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x42, 0x00, 0x03, 0x02, 0x00, + 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, + 0x00, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x44, 0x10, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x52, 0x54, 0x53, + 0x30, 0xb4, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, + 0x00, 0x1d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0xff, 0x01, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, + 0x00, 0x9c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xff, 0xff, 0x53, 0x54, 0x41, 0x54, 0x4c, 0x08, 0x00, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x13, 0x02, 0x00, 0x00, 0x44, 0x58, 0x49, + 0x4c, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x34, 0x08, 0x00, + 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x0a, 0x02, 0x00, + 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, + 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, + 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, + 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, + 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88, 0x48, 0x90, 0x14, + 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4, 0x48, 0x0e, + 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, + 0x8a, 0x04, 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40, 0x02, 0xa8, + 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x20, 0x6d, 0x30, 0x86, + 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x09, 0xa8, 0x00, 0x49, 0x18, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, 0x42, 0x20, 0x4c, 0x08, + 0x06, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x4b, 0x00, 0x00, + 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, + 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, + 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x78, 0x33, 0x00, 0xc3, 0x08, 0x04, + 0x30, 0x47, 0x00, 0x06, 0x33, 0xb5, 0xc1, 0x38, 0xb0, 0x43, 0x38, 0xcc, + 0xc3, 0x3c, 0xb8, 0x01, 0x2d, 0x94, 0x03, 0x3e, 0xd0, 0x43, 0x3d, 0xc8, + 0x43, 0x39, 0xc8, 0x01, 0x29, 0xf0, 0x81, 0x3d, 0x94, 0xc3, 0x38, 0xd0, + 0xc3, 0x3b, 0xc8, 0x03, 0x1f, 0x98, 0x03, 0x3b, 0xbc, 0x43, 0x38, 0xd0, + 0x03, 0x1b, 0x80, 0x01, 0x1d, 0xf8, 0x01, 0x18, 0xf8, 0x81, 0x1e, 0xe8, + 0x41, 0x3b, 0xa4, 0x03, 0x3c, 0xcc, 0xc3, 0x2f, 0xd0, 0x43, 0x3e, 0xc0, + 0x43, 0x39, 0xa0, 0x40, 0xcc, 0x24, 0x06, 0xe3, 0xc0, 0x0e, 0xe1, 0x30, + 0x0f, 0xf3, 0xe0, 0x06, 0xb4, 0x50, 0x0e, 0xf8, 0x40, 0x0f, 0xf5, 0x20, + 0x0f, 0xe5, 0x20, 0x07, 0xa4, 0xc0, 0x07, 0xf6, 0x50, 0x0e, 0xe3, 0x40, + 0x0f, 0xef, 0x20, 0x0f, 0x7c, 0x60, 0x0e, 0xec, 0xf0, 0x0e, 0xe1, 0x40, + 0x0f, 0x6c, 0x00, 0x06, 0x74, 0xe0, 0x07, 0x60, 0xe0, 0x07, 0x48, 0x08, + 0x83, 0xc8, 0x4d, 0xd2, 0x14, 0x51, 0xc2, 0xe4, 0xb3, 0x00, 0xf3, 0x2c, + 0x44, 0xc4, 0x4e, 0xc0, 0x44, 0xa0, 0x40, 0x90, 0x19, 0x01, 0x28, 0x01, + 0xa2, 0x34, 0x47, 0x80, 0x14, 0x03, 0x08, 0x21, 0x96, 0x20, 0x56, 0x0c, + 0x24, 0x84, 0x58, 0x80, 0xdc, 0x4d, 0xc3, 0xe5, 0x4f, 0xd8, 0x43, 0x48, + 0xfe, 0x4a, 0x48, 0x2b, 0x31, 0xf9, 0xc5, 0x6d, 0xa3, 0x02, 0x00, 0x00, + 0x04, 0xad, 0x7b, 0x86, 0xcb, 0x9f, 0xb0, 0x87, 0x90, 0xfc, 0x10, 0x68, + 0x86, 0x85, 0x40, 0x41, 0x2c, 0x0c, 0x14, 0x52, 0x02, 0x00, 0x80, 0x10, + 0x02, 0xd0, 0x2c, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0xd5, 0x39, 0x82, + 0xa0, 0x18, 0x52, 0x2c, 0x21, 0x2e, 0xe1, 0x81, 0x80, 0x61, 0x04, 0x01, + 0xb8, 0x4b, 0x9a, 0x22, 0x4a, 0x98, 0xfc, 0x14, 0xb9, 0x88, 0x85, 0x3d, + 0x80, 0x81, 0x88, 0xc4, 0xe6, 0xa1, 0x26, 0x34, 0x84, 0x1d, 0xd2, 0x41, + 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, + 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e, 0x6d, 0xd0, + 0x0e, 0x7a, 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, + 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, + 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, + 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x10, 0x07, 0x76, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x3a, 0x0f, 0x64, 0x90, 0x21, + 0x23, 0x45, 0x44, 0x00, 0x72, 0x00, 0xc0, 0xe4, 0x00, 0x80, 0xe9, 0x01, + 0x00, 0x0f, 0x79, 0x12, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0xf2, 0x30, 0x40, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x30, 0xe4, 0x71, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x60, 0xc8, 0x33, 0x01, 0x01, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x90, 0xa7, 0x02, 0x02, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x21, 0x0f, 0x06, 0x04, 0xc0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x20, 0x00, 0x00, + 0x00, 0x16, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x18, 0x19, 0x11, 0x4c, + 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x5a, 0x05, 0x42, 0xa2, + 0x04, 0x46, 0x00, 0x8a, 0xa1, 0x08, 0x4a, 0xa2, 0x50, 0xca, 0xa0, 0x1c, + 0x0a, 0xa4, 0x10, 0x4a, 0xa1, 0xc0, 0x0a, 0xa8, 0x3c, 0x0a, 0xa2, 0x6c, + 0x68, 0x15, 0xc1, 0x08, 0x40, 0x21, 0x94, 0x41, 0x49, 0xd0, 0x99, 0x01, + 0xa0, 0x32, 0x03, 0x40, 0x64, 0x06, 0x80, 0xc6, 0x0c, 0x00, 0x85, 0x19, + 0x00, 0xe2, 0x33, 0x00, 0xd4, 0xc7, 0x72, 0x18, 0x02, 0x00, 0x00, 0xe0, + 0x38, 0x00, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, + 0x00, 0xbf, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, + 0x44, 0x35, 0x18, 0x63, 0x0b, 0x73, 0x3b, 0x03, 0xb1, 0x2b, 0x93, 0x9b, + 0x4b, 0x7b, 0x73, 0x03, 0x99, 0x71, 0xb9, 0x01, 0x41, 0xa1, 0x0b, 0x3b, + 0x9b, 0x7b, 0x91, 0x2a, 0x62, 0x2a, 0x0a, 0x9a, 0x2a, 0xfa, 0x9a, 0xb9, + 0x81, 0x79, 0x31, 0x4b, 0x73, 0x0b, 0x63, 0x4b, 0xd9, 0x10, 0x04, 0x13, + 0x04, 0x41, 0x99, 0x20, 0x08, 0xcb, 0x06, 0x61, 0x20, 0x36, 0x08, 0x04, + 0x41, 0x01, 0x6e, 0x6e, 0x82, 0x20, 0x30, 0x1b, 0x86, 0x03, 0x21, 0x26, + 0x08, 0x05, 0x18, 0x70, 0xa1, 0x43, 0x2b, 0xa3, 0x2a, 0xc3, 0xa3, 0xab, + 0x93, 0x2b, 0xcb, 0x9a, 0x20, 0x08, 0xcd, 0x04, 0x41, 0x70, 0x36, 0x08, + 0x44, 0xb3, 0x21, 0x21, 0x94, 0x85, 0x20, 0x06, 0x86, 0x70, 0xc8, 0xd0, + 0xa1, 0x95, 0x51, 0x95, 0xe1, 0xd1, 0xd5, 0xc9, 0x95, 0x55, 0x59, 0x6d, + 0x48, 0x06, 0x05, 0x22, 0x86, 0x81, 0x21, 0x9c, 0x0d, 0xc2, 0x13, 0x4d, + 0x10, 0x8e, 0x8f, 0x0a, 0x1d, 0x5a, 0xd9, 0x54, 0x58, 0x1b, 0x1c, 0x5b, + 0x99, 0xdc, 0x06, 0x84, 0x98, 0x28, 0x82, 0x18, 0x08, 0x60, 0x43, 0x50, + 0x6d, 0x20, 0x24, 0x00, 0xb0, 0x26, 0x08, 0x44, 0x18, 0x4c, 0x10, 0x84, + 0x87, 0x01, 0xda, 0x04, 0x41, 0x80, 0x26, 0x08, 0x42, 0xb4, 0xc1, 0x40, + 0xb4, 0x8d, 0xe0, 0x1a, 0x12, 0x6d, 0x69, 0x70, 0x73, 0x13, 0x04, 0x41, + 0xda, 0x40, 0x20, 0xde, 0xf6, 0x4d, 0x10, 0x82, 0x31, 0xd8, 0x20, 0x10, + 0x61, 0xb0, 0x21, 0x10, 0x83, 0x0d, 0x02, 0x31, 0x06, 0x1b, 0x88, 0xac, + 0x03, 0x03, 0x32, 0x98, 0x20, 0x0c, 0x62, 0x30, 0x41, 0x10, 0x26, 0x1a, + 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x13, 0x04, 0x81, 0xda, 0x60, 0x20, + 0x68, 0xb0, 0x11, 0x5c, 0x1a, 0x6c, 0x10, 0xce, 0x40, 0x0d, 0x26, 0x08, + 0x1c, 0x19, 0x4c, 0x10, 0x84, 0x8a, 0x03, 0xdc, 0xdb, 0x1c, 0x97, 0x29, + 0xab, 0x2f, 0xa8, 0xa7, 0xa9, 0x24, 0xaa, 0xa4, 0x27, 0xa7, 0x0d, 0x08, + 0xe2, 0x06, 0x1b, 0x71, 0x06, 0x6f, 0xc0, 0x35, 0x1c, 0xe8, 0xca, 0xf0, + 0x98, 0x50, 0x15, 0x61, 0x0d, 0x3d, 0x3d, 0x49, 0x11, 0xc1, 0x6c, 0x40, + 0x90, 0x38, 0xd8, 0xbe, 0x33, 0x90, 0x03, 0xae, 0x61, 0x31, 0xf6, 0xc6, + 0xf6, 0x26, 0x37, 0x41, 0x10, 0x2c, 0x1a, 0x43, 0x4f, 0x4c, 0x4f, 0x52, + 0x30, 0x1b, 0x10, 0x84, 0x0e, 0xb6, 0x3a, 0x38, 0x03, 0x3b, 0xe0, 0x9a, + 0x0d, 0x44, 0x1b, 0xc0, 0xc1, 0x1c, 0xdc, 0xc1, 0x86, 0x83, 0xc0, 0xca, + 0xc0, 0x0c, 0xd6, 0x80, 0x0d, 0xf0, 0x60, 0x82, 0xa0, 0x0c, 0x1b, 0x80, + 0x0d, 0x03, 0xb1, 0x07, 0x7b, 0xb0, 0x21, 0xe0, 0x83, 0x0d, 0xc3, 0xa0, + 0x07, 0x7d, 0x30, 0x41, 0xe8, 0xca, 0x60, 0x43, 0xf0, 0x07, 0x24, 0xda, + 0xc2, 0xd2, 0xdc, 0xb8, 0x4c, 0x59, 0x7d, 0x41, 0xbd, 0xcd, 0xa5, 0xd1, + 0xa5, 0xbd, 0xb9, 0x4d, 0x10, 0x16, 0x6f, 0x82, 0xb0, 0x74, 0x1b, 0x02, + 0x62, 0x82, 0xb0, 0x70, 0x13, 0x84, 0x65, 0xdb, 0xb0, 0x10, 0xa2, 0x30, + 0x0a, 0xa4, 0x50, 0x0a, 0xa6, 0x30, 0x98, 0x02, 0x71, 0x0a, 0x00, 0x11, + 0xaa, 0x22, 0xac, 0xa1, 0xa7, 0x27, 0x29, 0xa2, 0x09, 0xc2, 0xa2, 0x6d, + 0x10, 0xb6, 0x6d, 0xc3, 0x32, 0xa4, 0xc2, 0x28, 0x9c, 0x42, 0x29, 0xa8, + 0xc2, 0xa0, 0x0a, 0xc3, 0x29, 0xac, 0x02, 0x8b, 0xa1, 0x27, 0xa6, 0x27, + 0xa9, 0x09, 0x82, 0x70, 0x6d, 0x10, 0x36, 0x57, 0xd8, 0xb0, 0x30, 0xad, + 0x30, 0x0a, 0xa7, 0x50, 0x0a, 0xaa, 0x30, 0x98, 0x02, 0x73, 0x0a, 0xaf, + 0xb0, 0x61, 0x40, 0x05, 0x56, 0x80, 0x05, 0x26, 0x53, 0x56, 0x5f, 0x54, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x13, 0x84, 0x25, 0xd9, 0xb0, 0x10, 0xb2, + 0x30, 0x0a, 0xb3, 0x50, 0x0a, 0xa7, 0x30, 0x98, 0x02, 0x71, 0x0a, 0xaf, + 0xb0, 0x21, 0xa0, 0x85, 0x0d, 0x43, 0x2c, 0xd4, 0x02, 0xb0, 0xa1, 0xd0, + 0x83, 0x50, 0xb0, 0x85, 0x0b, 0xa0, 0x61, 0xc6, 0xf6, 0x16, 0x46, 0x37, + 0x37, 0x41, 0x10, 0x30, 0x16, 0x69, 0x6e, 0x73, 0x74, 0x73, 0x13, 0x04, + 0x21, 0xa3, 0x31, 0x97, 0x76, 0xf6, 0xc5, 0x46, 0x46, 0x63, 0x2e, 0xed, + 0xec, 0x6b, 0x8e, 0x8e, 0x08, 0x5d, 0x19, 0xde, 0x97, 0xdb, 0x9b, 0x5c, + 0xdb, 0x06, 0x05, 0x17, 0x72, 0x41, 0x17, 0x76, 0x81, 0x17, 0x90, 0x5e, + 0x38, 0x03, 0x5f, 0x60, 0xaa, 0xb0, 0xb1, 0xd9, 0xb5, 0xb9, 0xa4, 0x91, + 0x95, 0xb9, 0xd1, 0x4d, 0x09, 0x82, 0x2a, 0x64, 0x78, 0x2e, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x02, 0xa2, 0x09, 0x19, 0x9e, 0x8b, + 0x5d, 0x18, 0x9b, 0x5d, 0x99, 0xdc, 0x94, 0xa0, 0xa8, 0x43, 0x86, 0xe7, + 0x32, 0x87, 0x16, 0x46, 0x56, 0x26, 0xd7, 0xf4, 0x46, 0x56, 0xc6, 0x36, + 0x25, 0x40, 0xca, 0x90, 0xe1, 0xb9, 0xc8, 0x95, 0xcd, 0xbd, 0xd5, 0xc9, + 0x8d, 0x95, 0xcd, 0x4d, 0x09, 0xac, 0x4a, 0x64, 0x78, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x53, 0x04, 0x3c, 0xe8, 0x83, 0x3a, 0x64, 0x78, 0x2e, 0x76, 0x69, + 0x65, 0x77, 0x49, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x82, 0x3f, + 0xa8, 0x43, 0x86, 0xe7, 0x52, 0xe6, 0x46, 0x27, 0x97, 0x07, 0xf5, 0x96, + 0xe6, 0x46, 0x37, 0x37, 0x25, 0xb0, 0x85, 0x2e, 0x64, 0x78, 0x2e, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x53, 0x02, 0x5f, 0x00, 0x00, + 0x00, 0x79, 0x18, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, + 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, + 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, + 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, + 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, + 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, + 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, + 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, + 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, + 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, + 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, + 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, + 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, + 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, + 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, + 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, + 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, + 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, + 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, + 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, + 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, + 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, + 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc4, 0x21, 0x07, 0x7c, + 0x70, 0x03, 0x7a, 0x28, 0x87, 0x76, 0x80, 0x87, 0x19, 0xd1, 0x43, 0x0e, + 0xf8, 0xe0, 0x06, 0xe4, 0x20, 0x0e, 0xe7, 0xe0, 0x06, 0xf6, 0x10, 0x0e, + 0xf2, 0xc0, 0x0e, 0xe1, 0x90, 0x0f, 0xef, 0x50, 0x0f, 0xf4, 0x00, 0x00, + 0x00, 0x71, 0x20, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x25, 0xf0, 0x05, + 0x7e, 0x74, 0x74, 0x79, 0x1a, 0x6e, 0xc3, 0xd9, 0x65, 0x39, 0x10, 0x38, + 0xab, 0x4e, 0xc3, 0x6d, 0x38, 0xbb, 0x2c, 0x9f, 0xd2, 0xc3, 0xf4, 0x32, + 0x10, 0x18, 0xac, 0x80, 0x38, 0x08, 0xfc, 0xe8, 0xe8, 0x32, 0xb5, 0x8c, + 0xa7, 0xd7, 0xe5, 0xe5, 0xaa, 0x15, 0x08, 0x9c, 0x59, 0x7f, 0x24, 0x6a, + 0x19, 0x4f, 0xaf, 0xcb, 0xcb, 0x32, 0x22, 0xd0, 0xfa, 0x23, 0xd9, 0xcb, + 0x63, 0xfa, 0x5b, 0x0e, 0x6c, 0x92, 0x60, 0x33, 0x20, 0x10, 0x08, 0x0c, + 0x16, 0x00, 0x1c, 0x04, 0x7e, 0x74, 0x74, 0x99, 0x5a, 0xc6, 0xd3, 0xeb, + 0xf2, 0x72, 0x16, 0x08, 0x9c, 0x59, 0x7f, 0x24, 0x6a, 0x19, 0x4f, 0xaf, + 0xcb, 0xcb, 0x32, 0x22, 0xd0, 0xfa, 0x23, 0xd9, 0xcb, 0x63, 0xfa, 0x5b, + 0x0e, 0x6c, 0x92, 0x60, 0x33, 0x20, 0x10, 0x08, 0x0c, 0x1a, 0x82, 0x34, + 0x5c, 0xbe, 0xf3, 0xf8, 0x42, 0x44, 0x00, 0x13, 0x11, 0x02, 0xcd, 0xb0, + 0x10, 0x76, 0xe0, 0x0c, 0x97, 0xef, 0x3c, 0xfe, 0xe0, 0x4c, 0xb7, 0x5f, + 0xdc, 0xb6, 0x11, 0x4c, 0xc3, 0xe5, 0x3b, 0x8f, 0xbf, 0x38, 0xc0, 0x20, + 0x36, 0x0f, 0x35, 0xf9, 0xc5, 0x6d, 0x9b, 0x01, 0x34, 0x5c, 0xbe, 0xf3, + 0xf8, 0x12, 0xc0, 0x3c, 0x0b, 0xe1, 0x17, 0xb7, 0x6d, 0x05, 0xd5, 0x70, + 0xf9, 0xce, 0xe3, 0x4b, 0x93, 0x13, 0x11, 0x28, 0x35, 0x3d, 0xd4, 0xe4, + 0x17, 0xb7, 0x6d, 0x03, 0x04, 0x03, 0x20, 0x0d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x48, 0x41, 0x53, 0x48, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xa0, 0x59, 0x53, 0xa0, 0x6c, 0x9f, 0xab, 0x00, 0x3c, 0x49, 0x69, + 0x91, 0x4f, 0x9f, 0xaf, 0x32, 0x44, 0x58, 0x49, 0x4c, 0xa0, 0x07, 0x00, + 0x00, 0x60, 0x00, 0x00, 0x00, 0xe8, 0x01, 0x00, 0x00, 0x44, 0x58, 0x49, + 0x4c, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x88, 0x07, 0x00, + 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0xdf, 0x01, 0x00, + 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, + 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, + 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, + 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, + 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88, 0x48, 0x90, 0x14, + 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4, 0x48, 0x0e, + 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, + 0x8a, 0x04, 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40, 0x02, 0xa8, + 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x20, 0x6d, 0x30, 0x86, + 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x09, 0xa8, 0x00, 0x49, 0x18, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, 0x42, 0x20, 0x4c, 0x08, + 0x06, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x45, 0x00, 0x00, + 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, + 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, + 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x70, 0x23, 0x00, 0x25, 0x00, 0x14, + 0x66, 0x00, 0xe6, 0x08, 0xc0, 0x60, 0x8e, 0x00, 0x29, 0xc6, 0x20, 0x84, + 0x14, 0x42, 0xa6, 0x18, 0x80, 0x10, 0x52, 0x06, 0xa1, 0x9b, 0x86, 0xcb, + 0x9f, 0xb0, 0x87, 0x90, 0xfc, 0x95, 0x90, 0x56, 0x62, 0xf2, 0x8b, 0xdb, + 0x46, 0xc5, 0x18, 0x63, 0x10, 0x2a, 0xf7, 0x0c, 0x97, 0x3f, 0x61, 0x0f, + 0x21, 0xf9, 0x21, 0xd0, 0x0c, 0x0b, 0x81, 0x82, 0x55, 0x18, 0x45, 0x18, + 0x1b, 0x63, 0x0c, 0x42, 0xc8, 0xa0, 0x56, 0x90, 0x41, 0xc6, 0x18, 0x63, + 0x0c, 0x7a, 0x73, 0x04, 0x41, 0x31, 0x18, 0x29, 0x84, 0x44, 0x92, 0x03, + 0x01, 0xc3, 0x08, 0xc4, 0x30, 0x53, 0x1b, 0x8c, 0x03, 0x3b, 0x84, 0xc3, + 0x3c, 0xcc, 0x83, 0x1b, 0xd0, 0x42, 0x39, 0xe0, 0x03, 0x3d, 0xd4, 0x83, + 0x3c, 0x94, 0x83, 0x1c, 0x90, 0x02, 0x1f, 0xd8, 0x43, 0x39, 0x8c, 0x03, + 0x3d, 0xbc, 0x83, 0x3c, 0xf0, 0x81, 0x39, 0xb0, 0xc3, 0x3b, 0x84, 0x03, + 0x3d, 0xb0, 0x01, 0x18, 0xd0, 0x81, 0x1f, 0x80, 0x81, 0x1f, 0xe8, 0x81, + 0x1e, 0xb4, 0x43, 0x3a, 0xc0, 0xc3, 0x3c, 0xfc, 0x02, 0x3d, 0xe4, 0x03, + 0x3c, 0x94, 0x03, 0x0a, 0xc8, 0x4c, 0x62, 0x30, 0x0e, 0xec, 0x10, 0x0e, + 0xf3, 0x30, 0x0f, 0x6e, 0x40, 0x0b, 0xe5, 0x80, 0x0f, 0xf4, 0x50, 0x0f, + 0xf2, 0x50, 0x0e, 0x72, 0x40, 0x0a, 0x7c, 0x60, 0x0f, 0xe5, 0x30, 0x0e, + 0xf4, 0xf0, 0x0e, 0xf2, 0xc0, 0x07, 0xe6, 0xc0, 0x0e, 0xef, 0x10, 0x0e, + 0xf4, 0xc0, 0x06, 0x60, 0x40, 0x07, 0x7e, 0x00, 0x06, 0x7e, 0x80, 0x84, + 0x6a, 0xe9, 0xde, 0x24, 0x4d, 0x11, 0x25, 0x4c, 0x3e, 0x0b, 0x30, 0xcf, + 0x42, 0x44, 0xec, 0x04, 0x4c, 0x04, 0x0a, 0x08, 0xe5, 0x74, 0x20, 0x00, + 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, + 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e, 0x6d, 0xd0, + 0x0e, 0x7a, 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, + 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, + 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, + 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x10, 0x07, 0x76, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x43, 0x9e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x3c, 0x06, 0x10, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x79, 0x10, + 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf2, + 0x34, 0x40, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, + 0xe4, 0x79, 0x80, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0xc8, 0x23, 0x01, 0x01, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x16, 0x08, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, + 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, + 0x22, 0x25, 0x30, 0x02, 0x50, 0x0c, 0x45, 0x50, 0x12, 0x65, 0x50, 0x1e, + 0x54, 0x4a, 0xa2, 0x0c, 0x0a, 0x61, 0x04, 0xa0, 0x08, 0x0a, 0x84, 0xf0, + 0x0c, 0x00, 0xe9, 0x19, 0x00, 0xda, 0x63, 0x39, 0x0c, 0x01, 0x00, 0x00, + 0x70, 0x1c, 0x00, 0x10, 0x08, 0x04, 0x02, 0x00, 0x00, 0x79, 0x18, 0x00, + 0x00, 0x65, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, + 0x44, 0x35, 0x18, 0x63, 0x0b, 0x73, 0x3b, 0x03, 0xb1, 0x2b, 0x93, 0x9b, + 0x4b, 0x7b, 0x73, 0x03, 0x99, 0x71, 0xb9, 0x01, 0x41, 0xa1, 0x0b, 0x3b, + 0x9b, 0x7b, 0x91, 0x2a, 0x62, 0x2a, 0x0a, 0x9a, 0x2a, 0xfa, 0x9a, 0xb9, + 0x81, 0x79, 0x31, 0x4b, 0x73, 0x0b, 0x63, 0x4b, 0xd9, 0x10, 0x04, 0x13, + 0x04, 0xc2, 0x98, 0x20, 0x10, 0xc7, 0x06, 0x61, 0x20, 0x26, 0x08, 0x04, + 0xb2, 0x41, 0x18, 0x0c, 0x0a, 0x70, 0x73, 0x1b, 0x06, 0xc4, 0x20, 0x26, + 0x08, 0xd8, 0x44, 0x60, 0x82, 0x40, 0x24, 0x13, 0x04, 0x42, 0xd9, 0x20, + 0x10, 0xcd, 0x86, 0x84, 0x50, 0x16, 0x82, 0x18, 0x18, 0xc2, 0xd9, 0x90, + 0x0c, 0xca, 0x42, 0x0c, 0x03, 0x43, 0x38, 0x1b, 0x84, 0x07, 0x9a, 0x20, + 0x68, 0xd4, 0x06, 0x84, 0x90, 0x16, 0x82, 0x18, 0x08, 0x60, 0x43, 0x30, + 0x6d, 0x20, 0x22, 0x00, 0xa0, 0x26, 0x08, 0x5b, 0xb5, 0x21, 0xb0, 0x26, + 0x08, 0x02, 0x40, 0xa2, 0x2d, 0x2c, 0xcd, 0x8d, 0xcb, 0x94, 0xd5, 0x17, + 0xd4, 0xdb, 0x5c, 0x1a, 0x5d, 0xda, 0x9b, 0xdb, 0x04, 0xa1, 0x68, 0x26, + 0x08, 0x85, 0xb3, 0x21, 0x20, 0x26, 0x08, 0xc5, 0x33, 0x41, 0x28, 0xa0, + 0x0d, 0x0b, 0xa1, 0x6d, 0x5c, 0xe7, 0x0d, 0x1e, 0xf1, 0x01, 0x44, 0xa8, + 0x8a, 0xb0, 0x86, 0x9e, 0x9e, 0xa4, 0x88, 0x26, 0x08, 0x45, 0x34, 0x41, + 0x20, 0x96, 0x0d, 0xc2, 0x18, 0x8c, 0xc1, 0x86, 0x65, 0x08, 0x83, 0xed, + 0xeb, 0xc4, 0x60, 0x10, 0x83, 0xe1, 0x23, 0x03, 0x16, 0x43, 0x4f, 0x4c, + 0x4f, 0x52, 0x13, 0x04, 0x82, 0xd9, 0x20, 0x8c, 0xc1, 0x19, 0x6c, 0x58, + 0x18, 0x33, 0xd8, 0xbe, 0x4e, 0x0c, 0x06, 0x8f, 0xf9, 0xd0, 0x60, 0xc3, + 0x00, 0x06, 0x65, 0x90, 0x06, 0x4c, 0xa6, 0xac, 0xbe, 0xa8, 0xc2, 0xe4, + 0xce, 0xca, 0xe8, 0x26, 0x08, 0x85, 0xb4, 0x61, 0x21, 0xd6, 0x60, 0x63, + 0x83, 0xee, 0x1b, 0x3c, 0xe2, 0x43, 0x83, 0x0d, 0x41, 0x1b, 0x6c, 0x18, + 0xd4, 0xc0, 0x0d, 0x80, 0x0d, 0x05, 0x96, 0xbd, 0x41, 0x05, 0x54, 0x61, + 0x63, 0xb3, 0x6b, 0x73, 0x49, 0x23, 0x2b, 0x73, 0xa3, 0x9b, 0x12, 0x04, + 0x55, 0xc8, 0xf0, 0x5c, 0xec, 0xca, 0xe4, 0xe6, 0xd2, 0xde, 0xdc, 0xa6, + 0x04, 0x44, 0x13, 0x32, 0x3c, 0x17, 0xbb, 0x30, 0x36, 0xbb, 0x32, 0xb9, + 0x29, 0x81, 0x51, 0x87, 0x0c, 0xcf, 0x65, 0x0e, 0x2d, 0x8c, 0xac, 0x4c, + 0xae, 0xe9, 0x8d, 0xac, 0x8c, 0x6d, 0x4a, 0x80, 0x94, 0x21, 0xc3, 0x73, + 0x91, 0x2b, 0x9b, 0x7b, 0xab, 0x93, 0x1b, 0x2b, 0x9b, 0x9b, 0x12, 0x50, + 0x75, 0xc8, 0xf0, 0x5c, 0xec, 0xd2, 0xca, 0xee, 0x92, 0xc8, 0xa6, 0xe8, + 0xc2, 0xe8, 0xca, 0xa6, 0x04, 0x56, 0x1d, 0x32, 0x3c, 0x97, 0x32, 0x37, + 0x3a, 0xb9, 0x3c, 0xa8, 0xb7, 0x34, 0x37, 0xba, 0xb9, 0x29, 0xc1, 0x1b, + 0x00, 0x79, 0x18, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, + 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, + 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, + 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, + 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, + 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, + 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, + 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, + 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, + 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, + 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, + 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, + 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, + 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, + 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, + 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, + 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, + 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, + 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, + 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, + 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, + 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, + 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc4, 0x21, 0x07, 0x7c, + 0x70, 0x03, 0x7a, 0x28, 0x87, 0x76, 0x80, 0x87, 0x19, 0xd1, 0x43, 0x0e, + 0xf8, 0xe0, 0x06, 0xe4, 0x20, 0x0e, 0xe7, 0xe0, 0x06, 0xf6, 0x10, 0x0e, + 0xf2, 0xc0, 0x0e, 0xe1, 0x90, 0x0f, 0xef, 0x50, 0x0f, 0xf4, 0x00, 0x00, + 0x00, 0x71, 0x20, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x56, 0x20, 0x0d, + 0x97, 0xef, 0x3c, 0xbe, 0x10, 0x11, 0xc0, 0x44, 0x84, 0x40, 0x33, 0x2c, + 0x84, 0x11, 0x38, 0xc3, 0xe5, 0x3b, 0x8f, 0x3f, 0x38, 0xd3, 0xed, 0x17, + 0xb7, 0x6d, 0x01, 0xd3, 0x70, 0xf9, 0xce, 0xe3, 0x2f, 0x0e, 0x30, 0x88, + 0xcd, 0x43, 0x4d, 0x7e, 0x71, 0xdb, 0x36, 0x00, 0x0d, 0x97, 0xef, 0x3c, + 0xbe, 0x04, 0x30, 0xcf, 0x42, 0xf8, 0xc5, 0x6d, 0x9b, 0x40, 0x35, 0x5c, + 0xbe, 0xf3, 0xf8, 0xd2, 0xe4, 0x44, 0x04, 0x4a, 0x4d, 0x0f, 0x35, 0xf9, + 0xc5, 0x6d, 0x1b, 0x00, 0xc1, 0x00, 0x48, 0x03, 0x00, 0x61, 0x20, 0x00, + 0x00, 0x5d, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x14, 0x47, 0x00, 0xa8, 0x94, 0x00, 0x91, + 0xc2, 0x2b, 0xb7, 0x92, 0x2b, 0x85, 0x42, 0x98, 0x01, 0xa0, 0x31, 0x46, + 0x50, 0x9e, 0x74, 0xe9, 0x7f, 0x63, 0x04, 0xa2, 0x3e, 0xb7, 0xf3, 0x2f, + 0x8c, 0x11, 0x80, 0xef, 0x0a, 0xae, 0xbf, 0x30, 0x46, 0xc0, 0x97, 0xbd, + 0xb9, 0x7f, 0x23, 0x00, 0x63, 0x04, 0x21, 0x09, 0x86, 0xf0, 0x2f, 0x8c, + 0x11, 0x80, 0x20, 0x08, 0xe2, 0xdf, 0x0c, 0x00, 0x00, 0x23, 0x06, 0x09, + 0x00, 0x82, 0x60, 0x20, 0x85, 0x01, 0x63, 0x81, 0x01, 0x18, 0x40, 0x23, + 0x06, 0x09, 0x00, 0x82, 0x60, 0x20, 0x89, 0x41, 0x73, 0x81, 0x01, 0x18, + 0x44, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x20, 0x8d, 0x81, 0xa3, 0x85, + 0x41, 0x18, 0x48, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x60, 0xa0, 0x41, + 0x03, 0x06, 0x62, 0x90, 0x31, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x60, + 0xa4, 0x81, 0x13, 0x06, 0x63, 0x30, 0x35, 0x23, 0x06, 0x09, 0x00, 0x82, + 0x60, 0x60, 0xa8, 0xc1, 0x23, 0x06, 0x64, 0xa0, 0x39, 0x23, 0x06, 0x09, + 0x00, 0x82, 0x60, 0x60, 0xac, 0x01, 0x34, 0x06, 0x65, 0xe0, 0x3d, 0x23, + 0x06, 0x09, 0x00, 0x82, 0x60, 0x60, 0xb0, 0x41, 0x74, 0x06, 0x66, 0xd0, + 0x41, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x60, 0xb4, 0x81, 0x84, 0x06, + 0x67, 0x70, 0x45, 0x23, 0x06, 0x0f, 0x00, 0x82, 0x60, 0xd0, 0xb0, 0xc1, + 0x85, 0x1c, 0x42, 0xa0, 0x28, 0x68, 0x80, 0x06, 0x92, 0x32, 0x9a, 0x10, + 0x00, 0x23, 0x06, 0x0f, 0x00, 0x82, 0x60, 0xd0, 0xb8, 0x41, 0xb6, 0x24, + 0xc4, 0xc0, 0x30, 0x6a, 0xa0, 0x06, 0x14, 0x33, 0x9a, 0x10, 0x00, 0xa3, + 0x09, 0x42, 0x60, 0x42, 0x04, 0x1f, 0x13, 0x24, 0xf8, 0x8c, 0x18, 0x2c, + 0x00, 0x08, 0x82, 0xc1, 0x23, 0x07, 0x9d, 0x21, 0x04, 0x12, 0x55, 0x8d, + 0x18, 0x2c, 0x00, 0x08, 0x82, 0xc1, 0x33, 0x07, 0xde, 0x31, 0x08, 0xd3, + 0x85, 0x8d, 0x18, 0x2c, 0x00, 0x08, 0x82, 0xc1, 0x43, 0x07, 0x1f, 0x42, + 0x0c, 0x94, 0x66, 0xd9, 0x00, 0xc9, 0xc7, 0x06, 0x48, 0x3e, 0x36, 0x40, + 0xf2, 0x19, 0x31, 0x48, 0x00, 0x10, 0x04, 0x03, 0x44, 0x0f, 0xc2, 0xa0, + 0x0e, 0xea, 0x80, 0x0d, 0x86, 0x11, 0x83, 0x04, 0x00, 0x41, 0x30, 0x40, + 0xf4, 0x20, 0x0c, 0xea, 0xa0, 0x0e, 0xca, 0x40, 0x18, 0x31, 0x48, 0x00, + 0x10, 0x04, 0x03, 0x44, 0x0f, 0xc2, 0xa0, 0x0e, 0xea, 0x60, 0x0d, 0x82, + 0x11, 0x83, 0x04, 0x00, 0x41, 0x30, 0x40, 0xf4, 0x20, 0x0c, 0xea, 0xa0, + 0x0e, 0xdc, 0x00, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +/* The yuv-rendering pixel shader: + + --- D3D12_PixelShader_NV12_BT601.hlsl --- + Texture2D theTextureY : register(t0); + Texture2D theTextureUV : register(t1); + SamplerState theSampler : register(s0); + + struct PixelShaderInput + { + float4 pos : SV_POSITION; + float2 tex : TEXCOORD0; + float4 color : COLOR0; + }; + + #define NVRS \ + "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \ + " DENY_DOMAIN_SHADER_ROOT_ACCESS |" \ + " DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \ + " DENY_HULL_SHADER_ROOT_ACCESS )," \ + "RootConstants(num32BitConstants=32, b0),"\ + "DescriptorTable ( SRV(t0), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( SRV(t1), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( Sampler(s0), visibility = SHADER_VISIBILITY_PIXEL )" + + [RootSignature(NVRS)] + float4 main(PixelShaderInput input) : SV_TARGET + { + const float3 offset = {-0.0627451017, -0.501960814, -0.501960814}; + const float3 Rcoeff = {1.1644, 0.0000, 1.5960}; + const float3 Gcoeff = {1.1644, -0.3918, -0.8130}; + const float3 Bcoeff = {1.1644, 2.0172, 0.0000}; + + float4 Output; + + float3 yuv; + yuv.x = theTextureY.Sample(theSampler, input.tex).r; + yuv.yz = theTextureUV.Sample(theSampler, input.tex).rg; + + yuv += offset; + Output.r = dot(yuv, Rcoeff); + Output.g = dot(yuv, Gcoeff); + Output.b = dot(yuv, Bcoeff); + Output.a = 1.0f; + + return Output * input.color; + } + +*/ + +static unsigned char D3D12_PixelShader_NV12_BT601[] = { + 0x44, 0x58, 0x42, 0x43, 0xd0, 0xda, 0x37, 0x96, 0x52, 0x6b, 0x77, 0x3b, + 0x82, 0x71, 0x03, 0xf9, 0x0a, 0x76, 0x4b, 0xd7, 0x01, 0x00, 0x00, 0x00, + 0xe9, 0x12, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0xdb, 0x00, 0x00, 0x00, 0x15, 0x01, 0x00, 0x00, + 0x0d, 0x02, 0x00, 0x00, 0xc9, 0x02, 0x00, 0x00, 0x15, 0x0b, 0x00, 0x00, + 0x31, 0x0b, 0x00, 0x00, 0x53, 0x46, 0x49, 0x30, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31, + 0x83, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x53, 0x56, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, + 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x43, 0x4f, 0x4c, + 0x4f, 0x52, 0x00, 0x4f, 0x53, 0x47, 0x31, 0x32, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x00, 0x50, 0x53, 0x56, 0x30, 0xf0, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x03, 0x01, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x43, + 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x44, 0x03, 0x03, 0x04, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x42, 0x00, 0x03, 0x02, 0x00, + 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, + 0x00, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x44, 0x10, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x52, 0x54, 0x53, + 0x30, 0xb4, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, + 0x00, 0x1d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0xff, 0x01, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, + 0x00, 0x9c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xff, 0xff, 0x53, 0x54, 0x41, 0x54, 0x44, 0x08, 0x00, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x11, 0x02, 0x00, 0x00, 0x44, 0x58, 0x49, + 0x4c, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x2c, 0x08, 0x00, + 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x08, 0x02, 0x00, + 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, + 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, + 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, + 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, + 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88, 0x48, 0x90, 0x14, + 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4, 0x48, 0x0e, + 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, + 0x8a, 0x04, 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40, 0x02, 0xa8, + 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x20, 0x6d, 0x30, 0x86, + 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x09, 0xa8, 0x00, 0x49, 0x18, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, 0x42, 0x20, 0x4c, 0x08, + 0x06, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x4b, 0x00, 0x00, + 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, + 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, + 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x78, 0x33, 0x00, 0xc3, 0x08, 0x04, + 0x30, 0x47, 0x00, 0x06, 0x33, 0xb5, 0xc1, 0x38, 0xb0, 0x43, 0x38, 0xcc, + 0xc3, 0x3c, 0xb8, 0x01, 0x2d, 0x94, 0x03, 0x3e, 0xd0, 0x43, 0x3d, 0xc8, + 0x43, 0x39, 0xc8, 0x01, 0x29, 0xf0, 0x81, 0x3d, 0x94, 0xc3, 0x38, 0xd0, + 0xc3, 0x3b, 0xc8, 0x03, 0x1f, 0x98, 0x03, 0x3b, 0xbc, 0x43, 0x38, 0xd0, + 0x03, 0x1b, 0x80, 0x01, 0x1d, 0xf8, 0x01, 0x18, 0xf8, 0x81, 0x1e, 0xe8, + 0x41, 0x3b, 0xa4, 0x03, 0x3c, 0xcc, 0xc3, 0x2f, 0xd0, 0x43, 0x3e, 0xc0, + 0x43, 0x39, 0xa0, 0x40, 0xcc, 0x24, 0x06, 0xe3, 0xc0, 0x0e, 0xe1, 0x30, + 0x0f, 0xf3, 0xe0, 0x06, 0xb4, 0x50, 0x0e, 0xf8, 0x40, 0x0f, 0xf5, 0x20, + 0x0f, 0xe5, 0x20, 0x07, 0xa4, 0xc0, 0x07, 0xf6, 0x50, 0x0e, 0xe3, 0x40, + 0x0f, 0xef, 0x20, 0x0f, 0x7c, 0x60, 0x0e, 0xec, 0xf0, 0x0e, 0xe1, 0x40, + 0x0f, 0x6c, 0x00, 0x06, 0x74, 0xe0, 0x07, 0x60, 0xe0, 0x07, 0x48, 0x08, + 0x83, 0xc8, 0x4d, 0xd2, 0x14, 0x51, 0xc2, 0xe4, 0xb3, 0x00, 0xf3, 0x2c, + 0x44, 0xc4, 0x4e, 0xc0, 0x44, 0xa0, 0x40, 0x90, 0x19, 0x01, 0x28, 0x01, + 0xa2, 0x34, 0x47, 0x80, 0x14, 0x03, 0x08, 0x21, 0x96, 0x20, 0x56, 0x0c, + 0x24, 0x84, 0x58, 0x80, 0xdc, 0x4d, 0xc3, 0xe5, 0x4f, 0xd8, 0x43, 0x48, + 0xfe, 0x4a, 0x48, 0x2b, 0x31, 0xf9, 0xc5, 0x6d, 0xa3, 0x02, 0x00, 0x00, + 0x04, 0xad, 0x7b, 0x86, 0xcb, 0x9f, 0xb0, 0x87, 0x90, 0xfc, 0x10, 0x68, + 0x86, 0x85, 0x40, 0x41, 0x2c, 0x0c, 0x14, 0x52, 0x02, 0x00, 0x80, 0x10, + 0x02, 0xd0, 0x2c, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0xd5, 0x39, 0x82, + 0xa0, 0x18, 0x52, 0x2c, 0x21, 0x2e, 0xe1, 0x81, 0x80, 0x61, 0x04, 0x01, + 0xb8, 0x4b, 0x9a, 0x22, 0x4a, 0x98, 0xfc, 0x14, 0xb9, 0x88, 0x85, 0x3d, + 0x80, 0x81, 0x88, 0xc4, 0xe6, 0xa1, 0x26, 0x34, 0x84, 0x1d, 0xd2, 0x41, + 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, + 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e, 0x6d, 0xd0, + 0x0e, 0x7a, 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, + 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, + 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, + 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x10, 0x07, 0x76, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x3a, 0x0f, 0x64, 0x90, 0x21, + 0x23, 0x45, 0x44, 0x00, 0x72, 0x00, 0xc0, 0xe4, 0x00, 0x80, 0xe9, 0x01, + 0x00, 0x0f, 0x79, 0x12, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0xf2, 0x30, 0x40, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x30, 0xe4, 0x71, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x60, 0xc8, 0x33, 0x01, 0x01, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x90, 0xa7, 0x02, 0x02, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x21, 0x0f, 0x06, 0x04, 0xc0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x20, 0x00, 0x00, + 0x00, 0x15, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x18, 0x19, 0x11, 0x4c, + 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x5a, 0x05, 0x42, 0xa2, + 0x04, 0x46, 0x00, 0x8a, 0xa1, 0x08, 0x4a, 0xa2, 0x50, 0xca, 0xa0, 0x1c, + 0x0a, 0xa4, 0x10, 0x4a, 0xa1, 0xc0, 0x0a, 0xa8, 0x3c, 0x0a, 0x87, 0x56, + 0x11, 0x8c, 0x00, 0x14, 0x42, 0x19, 0x94, 0x04, 0x9d, 0x19, 0x00, 0x2a, + 0x33, 0x00, 0x44, 0x66, 0x00, 0x68, 0xcc, 0x00, 0x50, 0x98, 0x01, 0x20, + 0x3e, 0x03, 0x40, 0x7d, 0x2c, 0x87, 0x21, 0x00, 0x00, 0x00, 0x8e, 0x03, + 0x00, 0x02, 0x81, 0x40, 0x00, 0x79, 0x18, 0x00, 0x00, 0xbe, 0x00, 0x00, + 0x00, 0x1a, 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, 0x44, 0x35, 0x18, 0x63, + 0x0b, 0x73, 0x3b, 0x03, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x03, + 0x99, 0x71, 0xb9, 0x01, 0x41, 0xa1, 0x0b, 0x3b, 0x9b, 0x7b, 0x91, 0x2a, + 0x62, 0x2a, 0x0a, 0x9a, 0x2a, 0xfa, 0x9a, 0xb9, 0x81, 0x79, 0x31, 0x4b, + 0x73, 0x0b, 0x63, 0x4b, 0xd9, 0x10, 0x04, 0x13, 0x04, 0x41, 0x99, 0x20, + 0x08, 0xcb, 0x06, 0x61, 0x20, 0x36, 0x08, 0x04, 0x41, 0x01, 0x6e, 0x6e, + 0x82, 0x20, 0x30, 0x1b, 0x86, 0x03, 0x21, 0x26, 0x08, 0xc5, 0xc7, 0x85, + 0x0e, 0xad, 0x8c, 0xaa, 0x0c, 0x8f, 0xae, 0x4e, 0xae, 0x2c, 0x6b, 0x82, + 0x20, 0x34, 0x13, 0x04, 0xc1, 0xd9, 0x20, 0x10, 0xcd, 0x86, 0x84, 0x50, + 0x16, 0x82, 0x18, 0x18, 0xc2, 0x21, 0x43, 0x87, 0x56, 0x46, 0x55, 0x86, + 0x47, 0x57, 0x27, 0x57, 0x56, 0x65, 0xb5, 0x21, 0x19, 0x14, 0x88, 0x18, + 0x06, 0x86, 0x70, 0x36, 0x08, 0x4f, 0x34, 0x41, 0x38, 0x3c, 0x2a, 0x74, + 0x68, 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x1b, 0x10, 0x62, + 0xa2, 0x08, 0x62, 0x20, 0x80, 0x0d, 0x41, 0xb5, 0x81, 0x90, 0x00, 0xc0, + 0x9a, 0x20, 0x10, 0x60, 0x30, 0x41, 0x10, 0x1e, 0x06, 0x68, 0x13, 0x04, + 0x01, 0x9a, 0x20, 0x08, 0xd1, 0x06, 0x03, 0xd1, 0x36, 0x82, 0x6b, 0x48, + 0xb4, 0xa5, 0xc1, 0xcd, 0x4d, 0x10, 0x04, 0x69, 0x03, 0x81, 0x78, 0xdb, + 0x37, 0x41, 0x08, 0xc4, 0x60, 0x83, 0x40, 0x84, 0xc1, 0x86, 0x40, 0x0c, + 0x36, 0x08, 0xc4, 0x18, 0x6c, 0x20, 0xb2, 0x0e, 0x0c, 0xc8, 0x60, 0x82, + 0x30, 0x84, 0xc1, 0x04, 0x41, 0x98, 0x68, 0xa0, 0x85, 0xb9, 0x91, 0xb1, + 0x95, 0x4d, 0x10, 0x04, 0x6a, 0x83, 0x81, 0xa0, 0xc1, 0x46, 0x70, 0x69, + 0xb0, 0x41, 0x38, 0x03, 0x35, 0x98, 0x20, 0x70, 0x63, 0x30, 0x41, 0x10, + 0x2a, 0x0e, 0x70, 0x6f, 0x73, 0x5c, 0xa6, 0xac, 0xbe, 0xa0, 0x9e, 0xa6, + 0x92, 0xa8, 0x92, 0x9e, 0x9c, 0x36, 0x20, 0x88, 0x1b, 0x6c, 0xc4, 0x19, + 0xbc, 0x01, 0xd7, 0x70, 0xa0, 0x2b, 0xc3, 0x63, 0x42, 0x55, 0x84, 0x35, + 0xf4, 0xf4, 0x24, 0x45, 0x04, 0xb3, 0x01, 0x41, 0xe2, 0x60, 0xfb, 0xce, + 0x40, 0x0e, 0xb8, 0x86, 0xc5, 0xd8, 0x1b, 0xdb, 0x9b, 0xdc, 0x04, 0x41, + 0xb0, 0x68, 0x0c, 0x3d, 0x31, 0x3d, 0x49, 0xc1, 0x6c, 0x40, 0x10, 0x3a, + 0xd8, 0xea, 0xe0, 0x0c, 0xec, 0x80, 0x6b, 0x36, 0x10, 0x6d, 0x00, 0x07, + 0x73, 0x70, 0x07, 0x1b, 0x0e, 0x02, 0x2b, 0x03, 0x33, 0x58, 0x03, 0x36, + 0xc0, 0x83, 0x09, 0x82, 0x32, 0x6c, 0x00, 0x36, 0x0c, 0xc4, 0x1e, 0xec, + 0xc1, 0x86, 0x80, 0x0f, 0x36, 0x0c, 0x83, 0x1e, 0xf4, 0xc1, 0x04, 0xa1, + 0x23, 0x83, 0x0d, 0xc1, 0x1f, 0x90, 0x68, 0x0b, 0x4b, 0x73, 0xe3, 0x32, + 0x65, 0xf5, 0x05, 0xf5, 0x36, 0x97, 0x46, 0x97, 0xf6, 0xe6, 0x36, 0x41, + 0x58, 0xba, 0x09, 0xc2, 0xc2, 0x6d, 0x08, 0x88, 0x09, 0xc2, 0xb2, 0x4d, + 0x10, 0x16, 0x6d, 0xc3, 0x42, 0x88, 0xc2, 0x28, 0x90, 0x42, 0x29, 0x98, + 0xc2, 0x60, 0x0a, 0xc4, 0x29, 0x00, 0x44, 0xa8, 0x8a, 0xb0, 0x86, 0x9e, + 0x9e, 0xa4, 0x88, 0x26, 0x08, 0x4b, 0xb6, 0x41, 0xd8, 0xb6, 0x0d, 0xcb, + 0x90, 0x0a, 0xa3, 0x70, 0x0a, 0xa5, 0xa0, 0x0a, 0x83, 0x2a, 0x0c, 0xa7, + 0xb0, 0x0a, 0x2c, 0x86, 0x9e, 0x98, 0x9e, 0xa4, 0x26, 0x08, 0xc2, 0xb5, + 0x41, 0xd8, 0x5c, 0x61, 0xc3, 0xc2, 0xb4, 0xc2, 0x28, 0x9c, 0x42, 0x29, + 0xa8, 0xc2, 0x60, 0x0a, 0xcc, 0x29, 0xbc, 0xc2, 0x86, 0x01, 0x15, 0x58, + 0x01, 0x16, 0x98, 0x4c, 0x59, 0x7d, 0x51, 0x85, 0xc9, 0x9d, 0x95, 0xd1, + 0x4d, 0x10, 0x96, 0x64, 0xc3, 0x42, 0xc8, 0xc2, 0x28, 0xcc, 0x42, 0x29, + 0x9c, 0xc2, 0x60, 0x0a, 0xc4, 0x29, 0xbc, 0xc2, 0x86, 0x80, 0x16, 0x36, + 0x0c, 0xb1, 0x50, 0x0b, 0xc0, 0x86, 0x42, 0x0f, 0x42, 0xc1, 0x16, 0x2e, + 0x80, 0x86, 0x19, 0xdb, 0x5b, 0x18, 0xdd, 0x1c, 0x8b, 0x34, 0xb7, 0x39, + 0xba, 0xb9, 0x09, 0x82, 0x80, 0xd1, 0x98, 0x4b, 0x3b, 0xfb, 0x62, 0x23, + 0xa3, 0x31, 0x97, 0x76, 0xf6, 0x35, 0x47, 0x47, 0x84, 0xae, 0x0c, 0xef, + 0xcb, 0xed, 0x4d, 0xae, 0x6d, 0x83, 0x82, 0x0b, 0x4d, 0x2e, 0xe8, 0xc2, + 0x2e, 0x20, 0xbc, 0x70, 0x06, 0xbd, 0xc0, 0x54, 0x61, 0x63, 0xb3, 0x6b, + 0x73, 0x49, 0x23, 0x2b, 0x73, 0xa3, 0x9b, 0x12, 0x04, 0x55, 0xc8, 0xf0, + 0x5c, 0xec, 0xca, 0xe4, 0xe6, 0xd2, 0xde, 0xdc, 0xa6, 0x04, 0x44, 0x13, + 0x32, 0x3c, 0x17, 0xbb, 0x30, 0x36, 0xbb, 0x32, 0xb9, 0x29, 0x41, 0x51, + 0x87, 0x0c, 0xcf, 0x65, 0x0e, 0x2d, 0x8c, 0xac, 0x4c, 0xae, 0xe9, 0x8d, + 0xac, 0x8c, 0x6d, 0x4a, 0x80, 0x94, 0x21, 0xc3, 0x73, 0x91, 0x2b, 0x9b, + 0x7b, 0xab, 0x93, 0x1b, 0x2b, 0x9b, 0x9b, 0x12, 0x58, 0x95, 0xc8, 0xf0, + 0x5c, 0xe8, 0xf2, 0xe0, 0xca, 0x82, 0xdc, 0xdc, 0xde, 0xe8, 0xc2, 0xe8, + 0xd2, 0xde, 0xdc, 0xe6, 0xa6, 0x08, 0x78, 0xd0, 0x07, 0x75, 0xc8, 0xf0, + 0x5c, 0xec, 0xd2, 0xca, 0xee, 0x92, 0xc8, 0xa6, 0xe8, 0xc2, 0xe8, 0xca, + 0xa6, 0x04, 0x7f, 0x50, 0x87, 0x0c, 0xcf, 0xa5, 0xcc, 0x8d, 0x4e, 0x2e, + 0x0f, 0xea, 0x2d, 0xcd, 0x8d, 0x6e, 0x6e, 0x4a, 0x60, 0x0b, 0x5d, 0xc8, + 0xf0, 0x5c, 0xc6, 0xde, 0xea, 0xdc, 0xe8, 0xca, 0xe4, 0xe6, 0xa6, 0x04, + 0xbd, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x4c, 0x00, 0x00, + 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, + 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, + 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, + 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, + 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, + 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, + 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, + 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, + 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, + 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, + 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, + 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, + 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, + 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, + 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, + 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, + 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, + 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, + 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, + 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, + 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, + 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, + 0xc4, 0x21, 0x07, 0x7c, 0x70, 0x03, 0x7a, 0x28, 0x87, 0x76, 0x80, 0x87, + 0x19, 0xd1, 0x43, 0x0e, 0xf8, 0xe0, 0x06, 0xe4, 0x20, 0x0e, 0xe7, 0xe0, + 0x06, 0xf6, 0x10, 0x0e, 0xf2, 0xc0, 0x0e, 0xe1, 0x90, 0x0f, 0xef, 0x50, + 0x0f, 0xf4, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x33, 0x00, 0x00, + 0x00, 0x25, 0xf0, 0x05, 0x7e, 0x74, 0x74, 0x79, 0x1a, 0x6e, 0xc3, 0xd9, + 0x65, 0x39, 0x10, 0x38, 0xab, 0x4e, 0xc3, 0x6d, 0x38, 0xbb, 0x2c, 0x9f, + 0xd2, 0xc3, 0xf4, 0x32, 0x10, 0x18, 0xac, 0x80, 0x38, 0x08, 0xfc, 0xe8, + 0xe8, 0x32, 0xb5, 0x8c, 0xa7, 0xd7, 0xe5, 0xe5, 0xaa, 0x15, 0x08, 0x9c, + 0x59, 0x7f, 0x24, 0x6a, 0x19, 0x4f, 0xaf, 0xcb, 0xcb, 0x32, 0x22, 0xd0, + 0xfa, 0x23, 0xd9, 0xcb, 0x63, 0xfa, 0x5b, 0x0e, 0x6c, 0x92, 0x60, 0x33, + 0x20, 0x10, 0x08, 0x0c, 0x16, 0x00, 0x1c, 0x04, 0x7e, 0x74, 0x74, 0x99, + 0x5a, 0xc6, 0xd3, 0xeb, 0xf2, 0x72, 0x16, 0x08, 0x9c, 0x59, 0x7f, 0x24, + 0x6a, 0x19, 0x4f, 0xaf, 0xcb, 0xcb, 0x32, 0x22, 0xd0, 0xfa, 0x23, 0xd9, + 0xcb, 0x63, 0xfa, 0x5b, 0x0e, 0x6c, 0x92, 0x60, 0x33, 0x20, 0x10, 0x08, + 0x0c, 0x1a, 0x82, 0x34, 0x5c, 0xbe, 0xf3, 0xf8, 0x42, 0x44, 0x00, 0x13, + 0x11, 0x02, 0xcd, 0xb0, 0x10, 0x76, 0xe0, 0x0c, 0x97, 0xef, 0x3c, 0xfe, + 0xe0, 0x4c, 0xb7, 0x5f, 0xdc, 0xb6, 0x11, 0x4c, 0xc3, 0xe5, 0x3b, 0x8f, + 0xbf, 0x38, 0xc0, 0x20, 0x36, 0x0f, 0x35, 0xf9, 0xc5, 0x6d, 0x9b, 0x01, + 0x34, 0x5c, 0xbe, 0xf3, 0xf8, 0x12, 0xc0, 0x3c, 0x0b, 0xe1, 0x17, 0xb7, + 0x6d, 0x05, 0xd5, 0x70, 0xf9, 0xce, 0xe3, 0x4b, 0x93, 0x13, 0x11, 0x28, + 0x35, 0x3d, 0xd4, 0xe4, 0x17, 0xb7, 0x6d, 0x03, 0x04, 0x03, 0x20, 0x0d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x14, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x59, 0x5f, 0x75, 0xd6, 0x73, 0xad, + 0xd4, 0x07, 0x66, 0xfb, 0xaa, 0x3b, 0xb4, 0x38, 0x99, 0x44, 0x58, 0x49, + 0x4c, 0xb0, 0x07, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xec, 0x01, 0x00, + 0x00, 0x44, 0x58, 0x49, 0x4c, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x98, 0x07, 0x00, 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, + 0x00, 0xe3, 0x01, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, + 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, + 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, + 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, + 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, + 0x42, 0xe4, 0x48, 0x0e, 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, + 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, + 0x07, 0x40, 0x02, 0xa8, 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, + 0x20, 0x6d, 0x30, 0x86, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x09, 0xa8, + 0x00, 0x49, 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, + 0x42, 0x20, 0x4c, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, + 0x00, 0x45, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, + 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, + 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x70, 0x23, + 0x00, 0x25, 0x00, 0x14, 0x66, 0x00, 0xe6, 0x08, 0xc0, 0x60, 0x8e, 0x00, + 0x29, 0xc6, 0x20, 0x84, 0x14, 0x42, 0xa6, 0x18, 0x80, 0x10, 0x52, 0x06, + 0xa1, 0x9b, 0x86, 0xcb, 0x9f, 0xb0, 0x87, 0x90, 0xfc, 0x95, 0x90, 0x56, + 0x62, 0xf2, 0x8b, 0xdb, 0x46, 0xc5, 0x18, 0x63, 0x10, 0x2a, 0xf7, 0x0c, + 0x97, 0x3f, 0x61, 0x0f, 0x21, 0xf9, 0x21, 0xd0, 0x0c, 0x0b, 0x81, 0x82, + 0x55, 0x18, 0x45, 0x18, 0x1b, 0x63, 0x0c, 0x42, 0xc8, 0xa0, 0x56, 0x90, + 0x41, 0xc6, 0x18, 0x63, 0x0c, 0x7a, 0x73, 0x04, 0x41, 0x31, 0x18, 0x29, + 0x84, 0x44, 0x92, 0x03, 0x01, 0xc3, 0x08, 0xc4, 0x30, 0x53, 0x1b, 0x8c, + 0x03, 0x3b, 0x84, 0xc3, 0x3c, 0xcc, 0x83, 0x1b, 0xd0, 0x42, 0x39, 0xe0, + 0x03, 0x3d, 0xd4, 0x83, 0x3c, 0x94, 0x83, 0x1c, 0x90, 0x02, 0x1f, 0xd8, + 0x43, 0x39, 0x8c, 0x03, 0x3d, 0xbc, 0x83, 0x3c, 0xf0, 0x81, 0x39, 0xb0, + 0xc3, 0x3b, 0x84, 0x03, 0x3d, 0xb0, 0x01, 0x18, 0xd0, 0x81, 0x1f, 0x80, + 0x81, 0x1f, 0xe8, 0x81, 0x1e, 0xb4, 0x43, 0x3a, 0xc0, 0xc3, 0x3c, 0xfc, + 0x02, 0x3d, 0xe4, 0x03, 0x3c, 0x94, 0x03, 0x0a, 0xc8, 0x4c, 0x62, 0x30, + 0x0e, 0xec, 0x10, 0x0e, 0xf3, 0x30, 0x0f, 0x6e, 0x40, 0x0b, 0xe5, 0x80, + 0x0f, 0xf4, 0x50, 0x0f, 0xf2, 0x50, 0x0e, 0x72, 0x40, 0x0a, 0x7c, 0x60, + 0x0f, 0xe5, 0x30, 0x0e, 0xf4, 0xf0, 0x0e, 0xf2, 0xc0, 0x07, 0xe6, 0xc0, + 0x0e, 0xef, 0x10, 0x0e, 0xf4, 0xc0, 0x06, 0x60, 0x40, 0x07, 0x7e, 0x00, + 0x06, 0x7e, 0x80, 0x84, 0x6a, 0xe9, 0xde, 0x24, 0x4d, 0x11, 0x25, 0x4c, + 0x3e, 0x0b, 0x30, 0xcf, 0x42, 0x44, 0xec, 0x04, 0x4c, 0x04, 0x0a, 0x08, + 0xe5, 0x74, 0x20, 0x00, 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, + 0x87, 0x36, 0x68, 0x87, 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, + 0x50, 0x0e, 0x6d, 0xd0, 0x0e, 0x7a, 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, + 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, + 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, + 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, + 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, + 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, + 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, + 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, + 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x43, + 0x9e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x86, 0x3c, 0x06, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x79, 0x10, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0xf2, 0x34, 0x40, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x30, 0xe4, 0x79, 0x80, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x60, 0xc8, 0x23, 0x01, 0x01, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x16, 0x08, 0x00, 0x0f, 0x00, 0x00, + 0x00, 0x32, 0x1e, 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, + 0x47, 0xc6, 0x04, 0x43, 0x22, 0x25, 0x30, 0x02, 0x50, 0x0c, 0x45, 0x50, + 0x12, 0x65, 0x50, 0x1e, 0x54, 0x4a, 0xa2, 0x0c, 0x0a, 0x61, 0x04, 0xa0, + 0x08, 0x0a, 0x84, 0xf0, 0x0c, 0x00, 0xe9, 0x19, 0x00, 0xda, 0x63, 0x39, + 0x0c, 0x01, 0x00, 0x00, 0x70, 0x1c, 0x00, 0x10, 0x08, 0x04, 0x02, 0x00, + 0x00, 0x79, 0x18, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, + 0x90, 0x46, 0x02, 0x13, 0x44, 0x35, 0x18, 0x63, 0x0b, 0x73, 0x3b, 0x03, + 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x03, 0x99, 0x71, 0xb9, 0x01, + 0x41, 0xa1, 0x0b, 0x3b, 0x9b, 0x7b, 0x91, 0x2a, 0x62, 0x2a, 0x0a, 0x9a, + 0x2a, 0xfa, 0x9a, 0xb9, 0x81, 0x79, 0x31, 0x4b, 0x73, 0x0b, 0x63, 0x4b, + 0xd9, 0x10, 0x04, 0x13, 0x04, 0xc2, 0x98, 0x20, 0x10, 0xc7, 0x06, 0x61, + 0x20, 0x26, 0x08, 0x04, 0xb2, 0x41, 0x18, 0x0c, 0x0a, 0x70, 0x73, 0x1b, + 0x06, 0xc4, 0x20, 0x26, 0x08, 0xd8, 0x44, 0x60, 0x82, 0x40, 0x24, 0x13, + 0x04, 0x42, 0xd9, 0x20, 0x10, 0xcd, 0x86, 0x84, 0x50, 0x16, 0x82, 0x18, + 0x18, 0xc2, 0xd9, 0x90, 0x0c, 0xca, 0x42, 0x0c, 0x03, 0x43, 0x38, 0x1b, + 0x84, 0x07, 0x9a, 0x20, 0x68, 0xd4, 0x06, 0x84, 0x90, 0x16, 0x82, 0x18, + 0x08, 0x60, 0x43, 0x30, 0x6d, 0x20, 0x22, 0x00, 0xa0, 0x26, 0x08, 0x5b, + 0xb5, 0x21, 0xb0, 0x26, 0x08, 0x02, 0x40, 0xa2, 0x2d, 0x2c, 0xcd, 0x8d, + 0xcb, 0x94, 0xd5, 0x17, 0xd4, 0xdb, 0x5c, 0x1a, 0x5d, 0xda, 0x9b, 0xdb, + 0x04, 0xa1, 0x68, 0x26, 0x08, 0x85, 0xb3, 0x21, 0x20, 0x26, 0x08, 0xc5, + 0x33, 0x41, 0x28, 0xa0, 0x0d, 0x0b, 0xa1, 0x6d, 0x5c, 0xe7, 0x0d, 0x1e, + 0xf1, 0x01, 0x44, 0xa8, 0x8a, 0xb0, 0x86, 0x9e, 0x9e, 0xa4, 0x88, 0x26, + 0x08, 0x45, 0x34, 0x41, 0x20, 0x96, 0x0d, 0xc2, 0x18, 0x8c, 0xc1, 0x86, + 0x65, 0x08, 0x83, 0xed, 0xeb, 0xc4, 0x60, 0x10, 0x83, 0xe1, 0x23, 0x03, + 0x16, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x13, 0x04, 0x82, 0xd9, 0x20, 0x8c, + 0xc1, 0x19, 0x6c, 0x58, 0x18, 0x33, 0xd8, 0xbe, 0x4e, 0x0c, 0x06, 0x8f, + 0xf9, 0xd0, 0x60, 0xc3, 0x00, 0x06, 0x65, 0x90, 0x06, 0x4c, 0xa6, 0xac, + 0xbe, 0xa8, 0xc2, 0xe4, 0xce, 0xca, 0xe8, 0x26, 0x08, 0x85, 0xb4, 0x61, + 0x21, 0xd6, 0x60, 0x63, 0x83, 0xee, 0x1b, 0x3c, 0xe2, 0x43, 0x83, 0x0d, + 0x41, 0x1b, 0x6c, 0x18, 0xd4, 0xc0, 0x0d, 0x80, 0x0d, 0x05, 0x96, 0xbd, + 0x41, 0x05, 0x54, 0x61, 0x63, 0xb3, 0x6b, 0x73, 0x49, 0x23, 0x2b, 0x73, + 0xa3, 0x9b, 0x12, 0x04, 0x55, 0xc8, 0xf0, 0x5c, 0xec, 0xca, 0xe4, 0xe6, + 0xd2, 0xde, 0xdc, 0xa6, 0x04, 0x44, 0x13, 0x32, 0x3c, 0x17, 0xbb, 0x30, + 0x36, 0xbb, 0x32, 0xb9, 0x29, 0x81, 0x51, 0x87, 0x0c, 0xcf, 0x65, 0x0e, + 0x2d, 0x8c, 0xac, 0x4c, 0xae, 0xe9, 0x8d, 0xac, 0x8c, 0x6d, 0x4a, 0x80, + 0x94, 0x21, 0xc3, 0x73, 0x91, 0x2b, 0x9b, 0x7b, 0xab, 0x93, 0x1b, 0x2b, + 0x9b, 0x9b, 0x12, 0x50, 0x75, 0xc8, 0xf0, 0x5c, 0xec, 0xd2, 0xca, 0xee, + 0x92, 0xc8, 0xa6, 0xe8, 0xc2, 0xe8, 0xca, 0xa6, 0x04, 0x56, 0x1d, 0x32, + 0x3c, 0x97, 0x32, 0x37, 0x3a, 0xb9, 0x3c, 0xa8, 0xb7, 0x34, 0x37, 0xba, + 0xb9, 0x29, 0xc1, 0x1b, 0x00, 0x79, 0x18, 0x00, 0x00, 0x4c, 0x00, 0x00, + 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, + 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, + 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, + 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, + 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, + 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, + 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, + 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, + 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, + 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, + 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, + 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, + 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, + 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, + 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, + 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, + 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, + 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, + 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, + 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, + 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, + 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, + 0xc4, 0x21, 0x07, 0x7c, 0x70, 0x03, 0x7a, 0x28, 0x87, 0x76, 0x80, 0x87, + 0x19, 0xd1, 0x43, 0x0e, 0xf8, 0xe0, 0x06, 0xe4, 0x20, 0x0e, 0xe7, 0xe0, + 0x06, 0xf6, 0x10, 0x0e, 0xf2, 0xc0, 0x0e, 0xe1, 0x90, 0x0f, 0xef, 0x50, + 0x0f, 0xf4, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x15, 0x00, 0x00, + 0x00, 0x56, 0x20, 0x0d, 0x97, 0xef, 0x3c, 0xbe, 0x10, 0x11, 0xc0, 0x44, + 0x84, 0x40, 0x33, 0x2c, 0x84, 0x11, 0x38, 0xc3, 0xe5, 0x3b, 0x8f, 0x3f, + 0x38, 0xd3, 0xed, 0x17, 0xb7, 0x6d, 0x01, 0xd3, 0x70, 0xf9, 0xce, 0xe3, + 0x2f, 0x0e, 0x30, 0x88, 0xcd, 0x43, 0x4d, 0x7e, 0x71, 0xdb, 0x36, 0x00, + 0x0d, 0x97, 0xef, 0x3c, 0xbe, 0x04, 0x30, 0xcf, 0x42, 0xf8, 0xc5, 0x6d, + 0x9b, 0x40, 0x35, 0x5c, 0xbe, 0xf3, 0xf8, 0xd2, 0xe4, 0x44, 0x04, 0x4a, + 0x4d, 0x0f, 0x35, 0xf9, 0xc5, 0x6d, 0x1b, 0x00, 0xc1, 0x00, 0x48, 0x03, + 0x00, 0x61, 0x20, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, + 0x2c, 0x10, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x47, 0x00, + 0xa8, 0x94, 0x00, 0x91, 0xc2, 0x2b, 0xb7, 0x92, 0x2b, 0x85, 0x42, 0x98, + 0x01, 0xa0, 0x31, 0x46, 0xe0, 0xba, 0xa6, 0x08, 0x82, 0xc1, 0x18, 0x41, + 0x69, 0xa2, 0x60, 0xfd, 0x0b, 0x63, 0x04, 0x22, 0x6c, 0xc6, 0xec, 0x2f, + 0x8c, 0x11, 0xe8, 0xad, 0x8c, 0xf3, 0xdf, 0x18, 0x41, 0x48, 0x82, 0x21, + 0xee, 0x0b, 0x23, 0x00, 0x63, 0x04, 0x21, 0x09, 0x86, 0xf0, 0x2f, 0x8c, + 0x11, 0xbc, 0xb8, 0xa8, 0xe6, 0xdf, 0x0c, 0x00, 0x00, 0x23, 0x06, 0x09, + 0x00, 0x82, 0x60, 0x20, 0x89, 0x41, 0x73, 0x85, 0x41, 0x18, 0x44, 0x23, + 0x06, 0x09, 0x00, 0x82, 0x60, 0x20, 0x8d, 0x81, 0x83, 0x85, 0x41, 0x18, + 0x48, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x20, 0x91, 0xc1, 0xb3, 0x89, + 0x81, 0x18, 0x4c, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x60, 0xa4, 0x81, + 0x13, 0x06, 0x63, 0xa0, 0x35, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x60, + 0xa8, 0xc1, 0x23, 0x06, 0x64, 0x40, 0x39, 0x23, 0x06, 0x09, 0x00, 0x82, + 0x60, 0x60, 0xac, 0x01, 0x34, 0x06, 0x65, 0xb0, 0x3d, 0x23, 0x06, 0x09, + 0x00, 0x82, 0x60, 0x60, 0xb0, 0x41, 0x44, 0x06, 0x66, 0xf0, 0x41, 0x23, + 0x06, 0x09, 0x00, 0x82, 0x60, 0x60, 0xb4, 0x81, 0x84, 0x06, 0x67, 0xe0, + 0x45, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x60, 0xb8, 0xc1, 0x94, 0x06, + 0x68, 0x80, 0x49, 0x23, 0x06, 0x0f, 0x00, 0x82, 0x60, 0xd0, 0xb4, 0x01, + 0x86, 0x1c, 0x42, 0xa0, 0x28, 0x69, 0x90, 0x06, 0x93, 0x32, 0x9a, 0x10, + 0x00, 0x23, 0x06, 0x0f, 0x00, 0x82, 0x60, 0xd0, 0xbc, 0x81, 0xb6, 0x24, + 0xc4, 0xc0, 0x30, 0x6b, 0xb0, 0x06, 0x15, 0x33, 0x9a, 0x10, 0x00, 0xa3, + 0x09, 0x42, 0x60, 0xc4, 0x04, 0x1f, 0x1b, 0x24, 0xf8, 0xd8, 0x30, 0xc1, + 0x67, 0xc4, 0x60, 0x01, 0x40, 0x10, 0x0c, 0x1e, 0x3a, 0xf8, 0x06, 0x21, + 0x98, 0xaa, 0x6b, 0xc4, 0x60, 0x01, 0x40, 0x10, 0x0c, 0x9e, 0x3a, 0x00, + 0x03, 0x62, 0x10, 0xa8, 0x4c, 0x1b, 0x31, 0x58, 0x00, 0x10, 0x04, 0x83, + 0xc7, 0x0e, 0xc2, 0xa0, 0x20, 0x86, 0x8a, 0xbb, 0x6c, 0x88, 0xe4, 0x63, + 0x43, 0x24, 0x1f, 0x1b, 0x22, 0xf9, 0x8c, 0x18, 0x24, 0x00, 0x08, 0x82, + 0x01, 0xc2, 0x07, 0x63, 0x70, 0x07, 0x77, 0xe0, 0x06, 0xc3, 0x88, 0x41, + 0x02, 0x80, 0x20, 0x18, 0x20, 0x7c, 0x30, 0x06, 0x77, 0x70, 0x07, 0x67, + 0x20, 0x8c, 0x18, 0x24, 0x00, 0x08, 0x82, 0x01, 0xc2, 0x07, 0x63, 0x70, + 0x07, 0x77, 0xd0, 0x06, 0xc1, 0x88, 0x41, 0x02, 0x80, 0x20, 0x18, 0x20, + 0x7c, 0x30, 0x06, 0x77, 0x70, 0x07, 0x70, 0x10, 0x21, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +/* The yuv-rendering pixel shader: + + --- D3D12_PixelShader_NV12_BT709.hlsl --- + Texture2D theTextureY : register(t0); + Texture2D theTextureUV : register(t1); + SamplerState theSampler : register(s0); + + struct PixelShaderInput + { + float4 pos : SV_POSITION; + float2 tex : TEXCOORD0; + float4 color : COLOR0; + }; + + #define NVRS \ + "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \ + " DENY_DOMAIN_SHADER_ROOT_ACCESS |" \ + " DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \ + " DENY_HULL_SHADER_ROOT_ACCESS )," \ + "RootConstants(num32BitConstants=32, b0),"\ + "DescriptorTable ( SRV(t0), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( SRV(t1), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( Sampler(s0), visibility = SHADER_VISIBILITY_PIXEL )" + + [RootSignature(NVRS)] + float4 main(PixelShaderInput input) : SV_TARGET + { + const float3 offset = {-0.0627451017, -0.501960814, -0.501960814}; + const float3 Rcoeff = {1.1644, 0.0000, 1.7927}; + const float3 Gcoeff = {1.1644, -0.2132, -0.5329}; + const float3 Bcoeff = {1.1644, 2.1124, 0.0000}; + + float4 Output; + + float3 yuv; + yuv.x = theTextureY.Sample(theSampler, input.tex).r; + yuv.yz = theTextureUV.Sample(theSampler, input.tex).rg; + + yuv += offset; + Output.r = dot(yuv, Rcoeff); + Output.g = dot(yuv, Gcoeff); + Output.b = dot(yuv, Bcoeff); + Output.a = 1.0f; + + return Output * input.color; + } + +*/ + +static unsigned char D3D12_PixelShader_NV12_BT709[] = { + 0x44, 0x58, 0x42, 0x43, 0x45, 0xb4, 0xa5, 0xa8, 0x01, 0xc5, 0xab, 0xf5, + 0xc0, 0x51, 0x32, 0xc2, 0xc3, 0x60, 0x64, 0xf1, 0x01, 0x00, 0x00, 0x00, + 0xe9, 0x12, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0xdb, 0x00, 0x00, 0x00, 0x15, 0x01, 0x00, 0x00, + 0x0d, 0x02, 0x00, 0x00, 0xc9, 0x02, 0x00, 0x00, 0x15, 0x0b, 0x00, 0x00, + 0x31, 0x0b, 0x00, 0x00, 0x53, 0x46, 0x49, 0x30, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31, + 0x83, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x53, 0x56, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, + 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x43, 0x4f, 0x4c, + 0x4f, 0x52, 0x00, 0x4f, 0x53, 0x47, 0x31, 0x32, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x00, 0x50, 0x53, 0x56, 0x30, 0xf0, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x03, 0x01, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x43, + 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x44, 0x03, 0x03, 0x04, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x42, 0x00, 0x03, 0x02, 0x00, + 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, + 0x00, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x44, 0x10, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x52, 0x54, 0x53, + 0x30, 0xb4, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, + 0x00, 0x1d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0xff, 0x01, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, + 0x00, 0x9c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xff, 0xff, 0x53, 0x54, 0x41, 0x54, 0x44, 0x08, 0x00, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x11, 0x02, 0x00, 0x00, 0x44, 0x58, 0x49, + 0x4c, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x2c, 0x08, 0x00, + 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x08, 0x02, 0x00, + 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, + 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, + 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, + 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, + 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88, 0x48, 0x90, 0x14, + 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4, 0x48, 0x0e, + 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, + 0x8a, 0x04, 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40, 0x02, 0xa8, + 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x20, 0x6d, 0x30, 0x86, + 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x09, 0xa8, 0x00, 0x49, 0x18, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, 0x42, 0x20, 0x4c, 0x08, + 0x06, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x4b, 0x00, 0x00, + 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, + 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, + 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x78, 0x33, 0x00, 0xc3, 0x08, 0x04, + 0x30, 0x47, 0x00, 0x06, 0x33, 0xb5, 0xc1, 0x38, 0xb0, 0x43, 0x38, 0xcc, + 0xc3, 0x3c, 0xb8, 0x01, 0x2d, 0x94, 0x03, 0x3e, 0xd0, 0x43, 0x3d, 0xc8, + 0x43, 0x39, 0xc8, 0x01, 0x29, 0xf0, 0x81, 0x3d, 0x94, 0xc3, 0x38, 0xd0, + 0xc3, 0x3b, 0xc8, 0x03, 0x1f, 0x98, 0x03, 0x3b, 0xbc, 0x43, 0x38, 0xd0, + 0x03, 0x1b, 0x80, 0x01, 0x1d, 0xf8, 0x01, 0x18, 0xf8, 0x81, 0x1e, 0xe8, + 0x41, 0x3b, 0xa4, 0x03, 0x3c, 0xcc, 0xc3, 0x2f, 0xd0, 0x43, 0x3e, 0xc0, + 0x43, 0x39, 0xa0, 0x40, 0xcc, 0x24, 0x06, 0xe3, 0xc0, 0x0e, 0xe1, 0x30, + 0x0f, 0xf3, 0xe0, 0x06, 0xb4, 0x50, 0x0e, 0xf8, 0x40, 0x0f, 0xf5, 0x20, + 0x0f, 0xe5, 0x20, 0x07, 0xa4, 0xc0, 0x07, 0xf6, 0x50, 0x0e, 0xe3, 0x40, + 0x0f, 0xef, 0x20, 0x0f, 0x7c, 0x60, 0x0e, 0xec, 0xf0, 0x0e, 0xe1, 0x40, + 0x0f, 0x6c, 0x00, 0x06, 0x74, 0xe0, 0x07, 0x60, 0xe0, 0x07, 0x48, 0x08, + 0x83, 0xc8, 0x4d, 0xd2, 0x14, 0x51, 0xc2, 0xe4, 0xb3, 0x00, 0xf3, 0x2c, + 0x44, 0xc4, 0x4e, 0xc0, 0x44, 0xa0, 0x40, 0x90, 0x19, 0x01, 0x28, 0x01, + 0xa2, 0x34, 0x47, 0x80, 0x14, 0x03, 0x08, 0x21, 0x96, 0x20, 0x56, 0x0c, + 0x24, 0x84, 0x58, 0x80, 0xdc, 0x4d, 0xc3, 0xe5, 0x4f, 0xd8, 0x43, 0x48, + 0xfe, 0x4a, 0x48, 0x2b, 0x31, 0xf9, 0xc5, 0x6d, 0xa3, 0x02, 0x00, 0x00, + 0x04, 0xad, 0x7b, 0x86, 0xcb, 0x9f, 0xb0, 0x87, 0x90, 0xfc, 0x10, 0x68, + 0x86, 0x85, 0x40, 0x41, 0x2c, 0x0c, 0x14, 0x52, 0x02, 0x00, 0x80, 0x10, + 0x02, 0xd0, 0x2c, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0xd5, 0x39, 0x82, + 0xa0, 0x18, 0x52, 0x2c, 0x21, 0x2e, 0xe1, 0x81, 0x80, 0x61, 0x04, 0x01, + 0xb8, 0x4b, 0x9a, 0x22, 0x4a, 0x98, 0xfc, 0x14, 0xb9, 0x88, 0x85, 0x3d, + 0x80, 0x81, 0x88, 0xc4, 0xe6, 0xa1, 0x26, 0x34, 0x84, 0x1d, 0xd2, 0x41, + 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, + 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e, 0x6d, 0xd0, + 0x0e, 0x7a, 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, + 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, + 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, + 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x10, 0x07, 0x76, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x3a, 0x0f, 0x64, 0x90, 0x21, + 0x23, 0x45, 0x44, 0x00, 0x72, 0x00, 0xc0, 0xe4, 0x00, 0x80, 0xe9, 0x01, + 0x00, 0x0f, 0x79, 0x12, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0xf2, 0x30, 0x40, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x30, 0xe4, 0x71, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x60, 0xc8, 0x33, 0x01, 0x01, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x90, 0xa7, 0x02, 0x02, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x21, 0x0f, 0x06, 0x04, 0xc0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x20, 0x00, 0x00, + 0x00, 0x15, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x18, 0x19, 0x11, 0x4c, + 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x5a, 0x05, 0x42, 0xa2, + 0x04, 0x46, 0x00, 0x8a, 0xa1, 0x08, 0x4a, 0xa2, 0x50, 0xca, 0xa0, 0x1c, + 0x0a, 0xa4, 0x10, 0x4a, 0xa1, 0xc0, 0x0a, 0xa8, 0x3c, 0x0a, 0x87, 0x56, + 0x11, 0x8c, 0x00, 0x14, 0x42, 0x19, 0x94, 0x04, 0x9d, 0x19, 0x00, 0x2a, + 0x33, 0x00, 0x44, 0x66, 0x00, 0x68, 0xcc, 0x00, 0x50, 0x98, 0x01, 0x20, + 0x3e, 0x03, 0x40, 0x7d, 0x2c, 0x87, 0x21, 0x00, 0x00, 0x00, 0x8e, 0x03, + 0x00, 0x02, 0x81, 0x40, 0x00, 0x79, 0x18, 0x00, 0x00, 0xbe, 0x00, 0x00, + 0x00, 0x1a, 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, 0x44, 0x35, 0x18, 0x63, + 0x0b, 0x73, 0x3b, 0x03, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x03, + 0x99, 0x71, 0xb9, 0x01, 0x41, 0xa1, 0x0b, 0x3b, 0x9b, 0x7b, 0x91, 0x2a, + 0x62, 0x2a, 0x0a, 0x9a, 0x2a, 0xfa, 0x9a, 0xb9, 0x81, 0x79, 0x31, 0x4b, + 0x73, 0x0b, 0x63, 0x4b, 0xd9, 0x10, 0x04, 0x13, 0x04, 0x41, 0x99, 0x20, + 0x08, 0xcb, 0x06, 0x61, 0x20, 0x36, 0x08, 0x04, 0x41, 0x01, 0x6e, 0x6e, + 0x82, 0x20, 0x30, 0x1b, 0x86, 0x03, 0x21, 0x26, 0x08, 0xc5, 0xc7, 0x85, + 0x0e, 0xad, 0x8c, 0xaa, 0x0c, 0x8f, 0xae, 0x4e, 0xae, 0x2c, 0x6b, 0x82, + 0x20, 0x34, 0x13, 0x04, 0xc1, 0xd9, 0x20, 0x10, 0xcd, 0x86, 0x84, 0x50, + 0x16, 0x82, 0x18, 0x18, 0xc2, 0x21, 0x43, 0x87, 0x56, 0x46, 0x55, 0x86, + 0x47, 0x57, 0x27, 0x57, 0x56, 0x65, 0xb5, 0x21, 0x19, 0x14, 0x88, 0x18, + 0x06, 0x86, 0x70, 0x36, 0x08, 0x4f, 0x34, 0x41, 0x38, 0x3c, 0x2a, 0x74, + 0x68, 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x1b, 0x10, 0x62, + 0xa2, 0x08, 0x62, 0x20, 0x80, 0x0d, 0x41, 0xb5, 0x81, 0x90, 0x00, 0xc0, + 0x9a, 0x20, 0x10, 0x60, 0x30, 0x41, 0x10, 0x1e, 0x06, 0x68, 0x13, 0x04, + 0x01, 0x9a, 0x20, 0x08, 0xd1, 0x06, 0x03, 0xd1, 0x36, 0x82, 0x6b, 0x48, + 0xb4, 0xa5, 0xc1, 0xcd, 0x4d, 0x10, 0x04, 0x69, 0x03, 0x81, 0x78, 0xdb, + 0x37, 0x41, 0x08, 0xc4, 0x60, 0x83, 0x40, 0x84, 0xc1, 0x86, 0x40, 0x0c, + 0x36, 0x08, 0xc4, 0x18, 0x6c, 0x20, 0xb2, 0x0e, 0x0c, 0xc8, 0x60, 0x82, + 0x30, 0x84, 0xc1, 0x04, 0x41, 0x98, 0x68, 0xa0, 0x85, 0xb9, 0x91, 0xb1, + 0x95, 0x4d, 0x10, 0x04, 0x6a, 0x83, 0x81, 0xa0, 0xc1, 0x46, 0x70, 0x69, + 0xb0, 0x41, 0x38, 0x03, 0x35, 0x98, 0x20, 0x70, 0x63, 0x30, 0x41, 0x10, + 0x2a, 0x0e, 0x70, 0x6f, 0x73, 0x5c, 0xa6, 0xac, 0xbe, 0xa0, 0x9e, 0xa6, + 0x92, 0xa8, 0x92, 0x9e, 0x9c, 0x36, 0x20, 0x88, 0x1b, 0x6c, 0xc4, 0x19, + 0xbc, 0x01, 0xd7, 0x70, 0xa0, 0x2b, 0xc3, 0x63, 0x42, 0x55, 0x84, 0x35, + 0xf4, 0xf4, 0x24, 0x45, 0x04, 0xb3, 0x01, 0x41, 0xe2, 0x60, 0xfb, 0xce, + 0x40, 0x0e, 0xb8, 0x86, 0xc5, 0xd8, 0x1b, 0xdb, 0x9b, 0xdc, 0x04, 0x41, + 0xb0, 0x68, 0x0c, 0x3d, 0x31, 0x3d, 0x49, 0xc1, 0x6c, 0x40, 0x10, 0x3a, + 0xd8, 0xea, 0xe0, 0x0c, 0xec, 0x80, 0x6b, 0x36, 0x10, 0x6d, 0x00, 0x07, + 0x73, 0x70, 0x07, 0x1b, 0x0e, 0x02, 0x2b, 0x03, 0x33, 0x58, 0x03, 0x36, + 0xc0, 0x83, 0x09, 0x82, 0x32, 0x6c, 0x00, 0x36, 0x0c, 0xc4, 0x1e, 0xec, + 0xc1, 0x86, 0x80, 0x0f, 0x36, 0x0c, 0x83, 0x1e, 0xf4, 0xc1, 0x04, 0xa1, + 0x23, 0x83, 0x0d, 0xc1, 0x1f, 0x90, 0x68, 0x0b, 0x4b, 0x73, 0xe3, 0x32, + 0x65, 0xf5, 0x05, 0xf5, 0x36, 0x97, 0x46, 0x97, 0xf6, 0xe6, 0x36, 0x41, + 0x58, 0xba, 0x09, 0xc2, 0xc2, 0x6d, 0x08, 0x88, 0x09, 0xc2, 0xb2, 0x4d, + 0x10, 0x16, 0x6d, 0xc3, 0x42, 0x88, 0xc2, 0x28, 0x90, 0x42, 0x29, 0x98, + 0xc2, 0x60, 0x0a, 0xc4, 0x29, 0x00, 0x44, 0xa8, 0x8a, 0xb0, 0x86, 0x9e, + 0x9e, 0xa4, 0x88, 0x26, 0x08, 0x4b, 0xb6, 0x41, 0xd8, 0xb6, 0x0d, 0xcb, + 0x90, 0x0a, 0xa3, 0x70, 0x0a, 0xa5, 0xa0, 0x0a, 0x83, 0x2a, 0x0c, 0xa7, + 0xb0, 0x0a, 0x2c, 0x86, 0x9e, 0x98, 0x9e, 0xa4, 0x26, 0x08, 0xc2, 0xb5, + 0x41, 0xd8, 0x5c, 0x61, 0xc3, 0xc2, 0xb4, 0xc2, 0x28, 0x9c, 0x42, 0x29, + 0xa8, 0xc2, 0x60, 0x0a, 0xcc, 0x29, 0xbc, 0xc2, 0x86, 0x01, 0x15, 0x58, + 0x01, 0x16, 0x98, 0x4c, 0x59, 0x7d, 0x51, 0x85, 0xc9, 0x9d, 0x95, 0xd1, + 0x4d, 0x10, 0x96, 0x64, 0xc3, 0x42, 0xc8, 0xc2, 0x28, 0xcc, 0x42, 0x29, + 0x9c, 0xc2, 0x60, 0x0a, 0xc4, 0x29, 0xbc, 0xc2, 0x86, 0x80, 0x16, 0x36, + 0x0c, 0xb1, 0x50, 0x0b, 0xc0, 0x86, 0x42, 0x0f, 0x42, 0xc1, 0x16, 0x2e, + 0x80, 0x86, 0x19, 0xdb, 0x5b, 0x18, 0xdd, 0x1c, 0x8b, 0x34, 0xb7, 0x39, + 0xba, 0xb9, 0x09, 0x82, 0x80, 0xd1, 0x98, 0x4b, 0x3b, 0xfb, 0x62, 0x23, + 0xa3, 0x31, 0x97, 0x76, 0xf6, 0x35, 0x47, 0x47, 0x84, 0xae, 0x0c, 0xef, + 0xcb, 0xed, 0x4d, 0xae, 0x6d, 0x83, 0x82, 0x0b, 0x4d, 0x2e, 0xe8, 0xc2, + 0x2e, 0x20, 0xbc, 0x70, 0x06, 0xbd, 0xc0, 0x54, 0x61, 0x63, 0xb3, 0x6b, + 0x73, 0x49, 0x23, 0x2b, 0x73, 0xa3, 0x9b, 0x12, 0x04, 0x55, 0xc8, 0xf0, + 0x5c, 0xec, 0xca, 0xe4, 0xe6, 0xd2, 0xde, 0xdc, 0xa6, 0x04, 0x44, 0x13, + 0x32, 0x3c, 0x17, 0xbb, 0x30, 0x36, 0xbb, 0x32, 0xb9, 0x29, 0x41, 0x51, + 0x87, 0x0c, 0xcf, 0x65, 0x0e, 0x2d, 0x8c, 0xac, 0x4c, 0xae, 0xe9, 0x8d, + 0xac, 0x8c, 0x6d, 0x4a, 0x80, 0x94, 0x21, 0xc3, 0x73, 0x91, 0x2b, 0x9b, + 0x7b, 0xab, 0x93, 0x1b, 0x2b, 0x9b, 0x9b, 0x12, 0x58, 0x95, 0xc8, 0xf0, + 0x5c, 0xe8, 0xf2, 0xe0, 0xca, 0x82, 0xdc, 0xdc, 0xde, 0xe8, 0xc2, 0xe8, + 0xd2, 0xde, 0xdc, 0xe6, 0xa6, 0x08, 0x78, 0xd0, 0x07, 0x75, 0xc8, 0xf0, + 0x5c, 0xec, 0xd2, 0xca, 0xee, 0x92, 0xc8, 0xa6, 0xe8, 0xc2, 0xe8, 0xca, + 0xa6, 0x04, 0x7f, 0x50, 0x87, 0x0c, 0xcf, 0xa5, 0xcc, 0x8d, 0x4e, 0x2e, + 0x0f, 0xea, 0x2d, 0xcd, 0x8d, 0x6e, 0x6e, 0x4a, 0x60, 0x0b, 0x5d, 0xc8, + 0xf0, 0x5c, 0xc6, 0xde, 0xea, 0xdc, 0xe8, 0xca, 0xe4, 0xe6, 0xa6, 0x04, + 0xbd, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x4c, 0x00, 0x00, + 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, + 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, + 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, + 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, + 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, + 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, + 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, + 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, + 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, + 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, + 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, + 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, + 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, + 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, + 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, + 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, + 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, + 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, + 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, + 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, + 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, + 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, + 0xc4, 0x21, 0x07, 0x7c, 0x70, 0x03, 0x7a, 0x28, 0x87, 0x76, 0x80, 0x87, + 0x19, 0xd1, 0x43, 0x0e, 0xf8, 0xe0, 0x06, 0xe4, 0x20, 0x0e, 0xe7, 0xe0, + 0x06, 0xf6, 0x10, 0x0e, 0xf2, 0xc0, 0x0e, 0xe1, 0x90, 0x0f, 0xef, 0x50, + 0x0f, 0xf4, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x33, 0x00, 0x00, + 0x00, 0x25, 0xf0, 0x05, 0x7e, 0x74, 0x74, 0x79, 0x1a, 0x6e, 0xc3, 0xd9, + 0x65, 0x39, 0x10, 0x38, 0xab, 0x4e, 0xc3, 0x6d, 0x38, 0xbb, 0x2c, 0x9f, + 0xd2, 0xc3, 0xf4, 0x32, 0x10, 0x18, 0xac, 0x80, 0x38, 0x08, 0xfc, 0xe8, + 0xe8, 0x32, 0xb5, 0x8c, 0xa7, 0xd7, 0xe5, 0xe5, 0xaa, 0x15, 0x08, 0x9c, + 0x59, 0x7f, 0x24, 0x6a, 0x19, 0x4f, 0xaf, 0xcb, 0xcb, 0x32, 0x22, 0xd0, + 0xfa, 0x23, 0xd9, 0xcb, 0x63, 0xfa, 0x5b, 0x0e, 0x6c, 0x92, 0x60, 0x33, + 0x20, 0x10, 0x08, 0x0c, 0x16, 0x00, 0x1c, 0x04, 0x7e, 0x74, 0x74, 0x99, + 0x5a, 0xc6, 0xd3, 0xeb, 0xf2, 0x72, 0x16, 0x08, 0x9c, 0x59, 0x7f, 0x24, + 0x6a, 0x19, 0x4f, 0xaf, 0xcb, 0xcb, 0x32, 0x22, 0xd0, 0xfa, 0x23, 0xd9, + 0xcb, 0x63, 0xfa, 0x5b, 0x0e, 0x6c, 0x92, 0x60, 0x33, 0x20, 0x10, 0x08, + 0x0c, 0x1a, 0x82, 0x34, 0x5c, 0xbe, 0xf3, 0xf8, 0x42, 0x44, 0x00, 0x13, + 0x11, 0x02, 0xcd, 0xb0, 0x10, 0x76, 0xe0, 0x0c, 0x97, 0xef, 0x3c, 0xfe, + 0xe0, 0x4c, 0xb7, 0x5f, 0xdc, 0xb6, 0x11, 0x4c, 0xc3, 0xe5, 0x3b, 0x8f, + 0xbf, 0x38, 0xc0, 0x20, 0x36, 0x0f, 0x35, 0xf9, 0xc5, 0x6d, 0x9b, 0x01, + 0x34, 0x5c, 0xbe, 0xf3, 0xf8, 0x12, 0xc0, 0x3c, 0x0b, 0xe1, 0x17, 0xb7, + 0x6d, 0x05, 0xd5, 0x70, 0xf9, 0xce, 0xe3, 0x4b, 0x93, 0x13, 0x11, 0x28, + 0x35, 0x3d, 0xd4, 0xe4, 0x17, 0xb7, 0x6d, 0x03, 0x04, 0x03, 0x20, 0x0d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x14, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd1, 0x3f, 0x63, 0xb2, 0x44, 0xb0, 0x28, + 0x54, 0xc4, 0x46, 0x87, 0x44, 0x49, 0x1b, 0x1b, 0xb5, 0x44, 0x58, 0x49, + 0x4c, 0xb0, 0x07, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xec, 0x01, 0x00, + 0x00, 0x44, 0x58, 0x49, 0x4c, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x98, 0x07, 0x00, 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, + 0x00, 0xe3, 0x01, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, + 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, + 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, + 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, + 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, + 0x42, 0xe4, 0x48, 0x0e, 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, + 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, + 0x07, 0x40, 0x02, 0xa8, 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, + 0x20, 0x6d, 0x30, 0x86, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x09, 0xa8, + 0x00, 0x49, 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, + 0x42, 0x20, 0x4c, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, + 0x00, 0x45, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, + 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, + 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x70, 0x23, + 0x00, 0x25, 0x00, 0x14, 0x66, 0x00, 0xe6, 0x08, 0xc0, 0x60, 0x8e, 0x00, + 0x29, 0xc6, 0x20, 0x84, 0x14, 0x42, 0xa6, 0x18, 0x80, 0x10, 0x52, 0x06, + 0xa1, 0x9b, 0x86, 0xcb, 0x9f, 0xb0, 0x87, 0x90, 0xfc, 0x95, 0x90, 0x56, + 0x62, 0xf2, 0x8b, 0xdb, 0x46, 0xc5, 0x18, 0x63, 0x10, 0x2a, 0xf7, 0x0c, + 0x97, 0x3f, 0x61, 0x0f, 0x21, 0xf9, 0x21, 0xd0, 0x0c, 0x0b, 0x81, 0x82, + 0x55, 0x18, 0x45, 0x18, 0x1b, 0x63, 0x0c, 0x42, 0xc8, 0xa0, 0x56, 0x90, + 0x41, 0xc6, 0x18, 0x63, 0x0c, 0x7a, 0x73, 0x04, 0x41, 0x31, 0x18, 0x29, + 0x84, 0x44, 0x92, 0x03, 0x01, 0xc3, 0x08, 0xc4, 0x30, 0x53, 0x1b, 0x8c, + 0x03, 0x3b, 0x84, 0xc3, 0x3c, 0xcc, 0x83, 0x1b, 0xd0, 0x42, 0x39, 0xe0, + 0x03, 0x3d, 0xd4, 0x83, 0x3c, 0x94, 0x83, 0x1c, 0x90, 0x02, 0x1f, 0xd8, + 0x43, 0x39, 0x8c, 0x03, 0x3d, 0xbc, 0x83, 0x3c, 0xf0, 0x81, 0x39, 0xb0, + 0xc3, 0x3b, 0x84, 0x03, 0x3d, 0xb0, 0x01, 0x18, 0xd0, 0x81, 0x1f, 0x80, + 0x81, 0x1f, 0xe8, 0x81, 0x1e, 0xb4, 0x43, 0x3a, 0xc0, 0xc3, 0x3c, 0xfc, + 0x02, 0x3d, 0xe4, 0x03, 0x3c, 0x94, 0x03, 0x0a, 0xc8, 0x4c, 0x62, 0x30, + 0x0e, 0xec, 0x10, 0x0e, 0xf3, 0x30, 0x0f, 0x6e, 0x40, 0x0b, 0xe5, 0x80, + 0x0f, 0xf4, 0x50, 0x0f, 0xf2, 0x50, 0x0e, 0x72, 0x40, 0x0a, 0x7c, 0x60, + 0x0f, 0xe5, 0x30, 0x0e, 0xf4, 0xf0, 0x0e, 0xf2, 0xc0, 0x07, 0xe6, 0xc0, + 0x0e, 0xef, 0x10, 0x0e, 0xf4, 0xc0, 0x06, 0x60, 0x40, 0x07, 0x7e, 0x00, + 0x06, 0x7e, 0x80, 0x84, 0x6a, 0xe9, 0xde, 0x24, 0x4d, 0x11, 0x25, 0x4c, + 0x3e, 0x0b, 0x30, 0xcf, 0x42, 0x44, 0xec, 0x04, 0x4c, 0x04, 0x0a, 0x08, + 0xe5, 0x74, 0x20, 0x00, 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, + 0x87, 0x36, 0x68, 0x87, 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, + 0x50, 0x0e, 0x6d, 0xd0, 0x0e, 0x7a, 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, + 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, + 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, + 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, + 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, + 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, + 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, + 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, + 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x43, + 0x9e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x86, 0x3c, 0x06, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x79, 0x10, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0xf2, 0x34, 0x40, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x30, 0xe4, 0x79, 0x80, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x60, 0xc8, 0x23, 0x01, 0x01, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x16, 0x08, 0x00, 0x0f, 0x00, 0x00, + 0x00, 0x32, 0x1e, 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, + 0x47, 0xc6, 0x04, 0x43, 0x22, 0x25, 0x30, 0x02, 0x50, 0x0c, 0x45, 0x50, + 0x12, 0x65, 0x50, 0x1e, 0x54, 0x4a, 0xa2, 0x0c, 0x0a, 0x61, 0x04, 0xa0, + 0x08, 0x0a, 0x84, 0xf0, 0x0c, 0x00, 0xe9, 0x19, 0x00, 0xda, 0x63, 0x39, + 0x0c, 0x01, 0x00, 0x00, 0x70, 0x1c, 0x00, 0x10, 0x08, 0x04, 0x02, 0x00, + 0x00, 0x79, 0x18, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, + 0x90, 0x46, 0x02, 0x13, 0x44, 0x35, 0x18, 0x63, 0x0b, 0x73, 0x3b, 0x03, + 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x03, 0x99, 0x71, 0xb9, 0x01, + 0x41, 0xa1, 0x0b, 0x3b, 0x9b, 0x7b, 0x91, 0x2a, 0x62, 0x2a, 0x0a, 0x9a, + 0x2a, 0xfa, 0x9a, 0xb9, 0x81, 0x79, 0x31, 0x4b, 0x73, 0x0b, 0x63, 0x4b, + 0xd9, 0x10, 0x04, 0x13, 0x04, 0xc2, 0x98, 0x20, 0x10, 0xc7, 0x06, 0x61, + 0x20, 0x26, 0x08, 0x04, 0xb2, 0x41, 0x18, 0x0c, 0x0a, 0x70, 0x73, 0x1b, + 0x06, 0xc4, 0x20, 0x26, 0x08, 0xd8, 0x44, 0x60, 0x82, 0x40, 0x24, 0x13, + 0x04, 0x42, 0xd9, 0x20, 0x10, 0xcd, 0x86, 0x84, 0x50, 0x16, 0x82, 0x18, + 0x18, 0xc2, 0xd9, 0x90, 0x0c, 0xca, 0x42, 0x0c, 0x03, 0x43, 0x38, 0x1b, + 0x84, 0x07, 0x9a, 0x20, 0x68, 0xd4, 0x06, 0x84, 0x90, 0x16, 0x82, 0x18, + 0x08, 0x60, 0x43, 0x30, 0x6d, 0x20, 0x22, 0x00, 0xa0, 0x26, 0x08, 0x5b, + 0xb5, 0x21, 0xb0, 0x26, 0x08, 0x02, 0x40, 0xa2, 0x2d, 0x2c, 0xcd, 0x8d, + 0xcb, 0x94, 0xd5, 0x17, 0xd4, 0xdb, 0x5c, 0x1a, 0x5d, 0xda, 0x9b, 0xdb, + 0x04, 0xa1, 0x68, 0x26, 0x08, 0x85, 0xb3, 0x21, 0x20, 0x26, 0x08, 0xc5, + 0x33, 0x41, 0x28, 0xa0, 0x0d, 0x0b, 0xa1, 0x6d, 0x5c, 0xe7, 0x0d, 0x1e, + 0xf1, 0x01, 0x44, 0xa8, 0x8a, 0xb0, 0x86, 0x9e, 0x9e, 0xa4, 0x88, 0x26, + 0x08, 0x45, 0x34, 0x41, 0x20, 0x96, 0x0d, 0xc2, 0x18, 0x8c, 0xc1, 0x86, + 0x65, 0x08, 0x83, 0xed, 0xeb, 0xc4, 0x60, 0x10, 0x83, 0xe1, 0x23, 0x03, + 0x16, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x13, 0x04, 0x82, 0xd9, 0x20, 0x8c, + 0xc1, 0x19, 0x6c, 0x58, 0x18, 0x33, 0xd8, 0xbe, 0x4e, 0x0c, 0x06, 0x8f, + 0xf9, 0xd0, 0x60, 0xc3, 0x00, 0x06, 0x65, 0x90, 0x06, 0x4c, 0xa6, 0xac, + 0xbe, 0xa8, 0xc2, 0xe4, 0xce, 0xca, 0xe8, 0x26, 0x08, 0x85, 0xb4, 0x61, + 0x21, 0xd6, 0x60, 0x63, 0x83, 0xee, 0x1b, 0x3c, 0xe2, 0x43, 0x83, 0x0d, + 0x41, 0x1b, 0x6c, 0x18, 0xd4, 0xc0, 0x0d, 0x80, 0x0d, 0x05, 0x96, 0xbd, + 0x41, 0x05, 0x54, 0x61, 0x63, 0xb3, 0x6b, 0x73, 0x49, 0x23, 0x2b, 0x73, + 0xa3, 0x9b, 0x12, 0x04, 0x55, 0xc8, 0xf0, 0x5c, 0xec, 0xca, 0xe4, 0xe6, + 0xd2, 0xde, 0xdc, 0xa6, 0x04, 0x44, 0x13, 0x32, 0x3c, 0x17, 0xbb, 0x30, + 0x36, 0xbb, 0x32, 0xb9, 0x29, 0x81, 0x51, 0x87, 0x0c, 0xcf, 0x65, 0x0e, + 0x2d, 0x8c, 0xac, 0x4c, 0xae, 0xe9, 0x8d, 0xac, 0x8c, 0x6d, 0x4a, 0x80, + 0x94, 0x21, 0xc3, 0x73, 0x91, 0x2b, 0x9b, 0x7b, 0xab, 0x93, 0x1b, 0x2b, + 0x9b, 0x9b, 0x12, 0x50, 0x75, 0xc8, 0xf0, 0x5c, 0xec, 0xd2, 0xca, 0xee, + 0x92, 0xc8, 0xa6, 0xe8, 0xc2, 0xe8, 0xca, 0xa6, 0x04, 0x56, 0x1d, 0x32, + 0x3c, 0x97, 0x32, 0x37, 0x3a, 0xb9, 0x3c, 0xa8, 0xb7, 0x34, 0x37, 0xba, + 0xb9, 0x29, 0xc1, 0x1b, 0x00, 0x79, 0x18, 0x00, 0x00, 0x4c, 0x00, 0x00, + 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, + 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, + 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, + 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, + 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, + 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, + 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, + 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, + 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, + 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, + 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, + 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, + 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, + 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, + 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, + 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, + 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, + 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, + 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, + 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, + 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, + 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, + 0xc4, 0x21, 0x07, 0x7c, 0x70, 0x03, 0x7a, 0x28, 0x87, 0x76, 0x80, 0x87, + 0x19, 0xd1, 0x43, 0x0e, 0xf8, 0xe0, 0x06, 0xe4, 0x20, 0x0e, 0xe7, 0xe0, + 0x06, 0xf6, 0x10, 0x0e, 0xf2, 0xc0, 0x0e, 0xe1, 0x90, 0x0f, 0xef, 0x50, + 0x0f, 0xf4, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x15, 0x00, 0x00, + 0x00, 0x56, 0x20, 0x0d, 0x97, 0xef, 0x3c, 0xbe, 0x10, 0x11, 0xc0, 0x44, + 0x84, 0x40, 0x33, 0x2c, 0x84, 0x11, 0x38, 0xc3, 0xe5, 0x3b, 0x8f, 0x3f, + 0x38, 0xd3, 0xed, 0x17, 0xb7, 0x6d, 0x01, 0xd3, 0x70, 0xf9, 0xce, 0xe3, + 0x2f, 0x0e, 0x30, 0x88, 0xcd, 0x43, 0x4d, 0x7e, 0x71, 0xdb, 0x36, 0x00, + 0x0d, 0x97, 0xef, 0x3c, 0xbe, 0x04, 0x30, 0xcf, 0x42, 0xf8, 0xc5, 0x6d, + 0x9b, 0x40, 0x35, 0x5c, 0xbe, 0xf3, 0xf8, 0xd2, 0xe4, 0x44, 0x04, 0x4a, + 0x4d, 0x0f, 0x35, 0xf9, 0xc5, 0x6d, 0x1b, 0x00, 0xc1, 0x00, 0x48, 0x03, + 0x00, 0x61, 0x20, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, + 0x2c, 0x10, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x47, 0x00, + 0xa8, 0x94, 0x00, 0x91, 0xc2, 0x2b, 0xb7, 0x92, 0x2b, 0x85, 0x42, 0x98, + 0x01, 0xa0, 0x31, 0x46, 0x00, 0xb3, 0xac, 0x0b, 0x82, 0xc1, 0x18, 0x81, + 0x18, 0xee, 0x30, 0xfc, 0x0b, 0x63, 0x04, 0x3a, 0x4a, 0xd3, 0xe5, 0x2f, + 0x8c, 0x11, 0xc8, 0x79, 0xaf, 0xfa, 0xdf, 0x18, 0x41, 0x48, 0x82, 0x21, + 0xee, 0x0b, 0x23, 0x00, 0x63, 0x04, 0x21, 0x09, 0x86, 0xf0, 0x2f, 0x8c, + 0x11, 0xbc, 0xb8, 0xa8, 0xe6, 0xdf, 0x0c, 0x00, 0x00, 0x23, 0x06, 0x09, + 0x00, 0x82, 0x60, 0x20, 0x89, 0x41, 0x73, 0x85, 0x41, 0x18, 0x44, 0x23, + 0x06, 0x09, 0x00, 0x82, 0x60, 0x20, 0x8d, 0x81, 0x83, 0x85, 0x41, 0x18, + 0x48, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x20, 0x91, 0xc1, 0xb3, 0x89, + 0x81, 0x18, 0x4c, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x60, 0xa4, 0x81, + 0x13, 0x06, 0x63, 0xa0, 0x35, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x60, + 0xa8, 0xc1, 0x23, 0x06, 0x64, 0x40, 0x39, 0x23, 0x06, 0x09, 0x00, 0x82, + 0x60, 0x60, 0xac, 0x01, 0x34, 0x06, 0x65, 0xb0, 0x3d, 0x23, 0x06, 0x09, + 0x00, 0x82, 0x60, 0x60, 0xb0, 0x41, 0x44, 0x06, 0x66, 0xf0, 0x41, 0x23, + 0x06, 0x09, 0x00, 0x82, 0x60, 0x60, 0xb4, 0x81, 0x84, 0x06, 0x67, 0xe0, + 0x45, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x60, 0xb8, 0xc1, 0x94, 0x06, + 0x68, 0x80, 0x49, 0x23, 0x06, 0x0f, 0x00, 0x82, 0x60, 0xd0, 0xb4, 0x01, + 0x86, 0x1c, 0x42, 0xa0, 0x28, 0x69, 0x90, 0x06, 0x93, 0x32, 0x9a, 0x10, + 0x00, 0x23, 0x06, 0x0f, 0x00, 0x82, 0x60, 0xd0, 0xbc, 0x81, 0xb6, 0x24, + 0xc4, 0xc0, 0x30, 0x6b, 0xb0, 0x06, 0x15, 0x33, 0x9a, 0x10, 0x00, 0xa3, + 0x09, 0x42, 0x60, 0xc4, 0x04, 0x1f, 0x1b, 0x24, 0xf8, 0xd8, 0x30, 0xc1, + 0x67, 0xc4, 0x60, 0x01, 0x40, 0x10, 0x0c, 0x1e, 0x3a, 0xf8, 0x06, 0x21, + 0x98, 0xaa, 0x6b, 0xc4, 0x60, 0x01, 0x40, 0x10, 0x0c, 0x9e, 0x3a, 0x00, + 0x03, 0x62, 0x10, 0xa8, 0x4c, 0x1b, 0x31, 0x58, 0x00, 0x10, 0x04, 0x83, + 0xc7, 0x0e, 0xc2, 0xa0, 0x20, 0x86, 0x8a, 0xbb, 0x6c, 0x88, 0xe4, 0x63, + 0x43, 0x24, 0x1f, 0x1b, 0x22, 0xf9, 0x8c, 0x18, 0x24, 0x00, 0x08, 0x82, + 0x01, 0xc2, 0x07, 0x63, 0x70, 0x07, 0x77, 0xe0, 0x06, 0xc3, 0x88, 0x41, + 0x02, 0x80, 0x20, 0x18, 0x20, 0x7c, 0x30, 0x06, 0x77, 0x70, 0x07, 0x67, + 0x20, 0x8c, 0x18, 0x24, 0x00, 0x08, 0x82, 0x01, 0xc2, 0x07, 0x63, 0x70, + 0x07, 0x77, 0xd0, 0x06, 0xc1, 0x88, 0x41, 0x02, 0x80, 0x20, 0x18, 0x20, + 0x7c, 0x30, 0x06, 0x77, 0x70, 0x07, 0x70, 0x10, 0x21, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +/* The yuv-rendering pixel shader: + + --- D3D12_PixelShader_NV21_JPEG.hlsl --- + Texture2D theTextureY : register(t0); + Texture2D theTextureUV : register(t1); + SamplerState theSampler : register(s0); + + struct PixelShaderInput + { + float4 pos : SV_POSITION; + float2 tex : TEXCOORD0; + float4 color : COLOR0; + }; + + #define NVRS \ + "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \ + " DENY_DOMAIN_SHADER_ROOT_ACCESS |" \ + " DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \ + " DENY_HULL_SHADER_ROOT_ACCESS )," \ + "RootConstants(num32BitConstants=32, b0),"\ + "DescriptorTable ( SRV(t0), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( SRV(t1), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( Sampler(s0), visibility = SHADER_VISIBILITY_PIXEL )" + + [RootSignature(NVRS)] + float4 main(PixelShaderInput input) : SV_TARGET + { + const float3 offset = {0.0, -0.501960814, -0.501960814}; + const float3 Rcoeff = {1.0000, 0.0000, 1.4020}; + const float3 Gcoeff = {1.0000, -0.3441, -0.7141}; + const float3 Bcoeff = {1.0000, 1.7720, 0.0000}; + + float4 Output; + + float3 yuv; + yuv.x = theTextureY.Sample(theSampler, input.tex).r; + yuv.yz = theTextureUV.Sample(theSampler, input.tex).gr; + + yuv += offset; + Output.r = dot(yuv, Rcoeff); + Output.g = dot(yuv, Gcoeff); + Output.b = dot(yuv, Bcoeff); + Output.a = 1.0f; + + return Output * input.color; + } + +*/ + +static unsigned char D3D12_PixelShader_NV21_JPEG[] = { + 0x44, 0x58, 0x42, 0x43, 0xcf, 0xc7, 0x5e, 0x20, 0x3e, 0x0d, 0xdf, 0x60, + 0x41, 0xdf, 0xe0, 0xb4, 0x61, 0xb5, 0x7b, 0x53, 0x01, 0x00, 0x00, 0x00, + 0xe1, 0x12, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0xdb, 0x00, 0x00, 0x00, 0x15, 0x01, 0x00, 0x00, + 0x0d, 0x02, 0x00, 0x00, 0xc9, 0x02, 0x00, 0x00, 0x1d, 0x0b, 0x00, 0x00, + 0x39, 0x0b, 0x00, 0x00, 0x53, 0x46, 0x49, 0x30, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31, + 0x83, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x53, 0x56, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, + 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x43, 0x4f, 0x4c, + 0x4f, 0x52, 0x00, 0x4f, 0x53, 0x47, 0x31, 0x32, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x00, 0x50, 0x53, 0x56, 0x30, 0xf0, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x03, 0x01, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x43, + 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x44, 0x03, 0x03, 0x04, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x42, 0x00, 0x03, 0x02, 0x00, + 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, + 0x00, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x44, 0x10, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x52, 0x54, 0x53, + 0x30, 0xb4, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, + 0x00, 0x1d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0xff, 0x01, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, + 0x00, 0x9c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xff, 0xff, 0x53, 0x54, 0x41, 0x54, 0x4c, 0x08, 0x00, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x13, 0x02, 0x00, 0x00, 0x44, 0x58, 0x49, + 0x4c, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x34, 0x08, 0x00, + 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x0a, 0x02, 0x00, + 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, + 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, + 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, + 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, + 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88, 0x48, 0x90, 0x14, + 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4, 0x48, 0x0e, + 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, + 0x8a, 0x04, 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40, 0x02, 0xa8, + 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x20, 0x6d, 0x30, 0x86, + 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x09, 0xa8, 0x00, 0x49, 0x18, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, 0x42, 0x20, 0x4c, 0x08, + 0x06, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x4b, 0x00, 0x00, + 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, + 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, + 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x78, 0x33, 0x00, 0xc3, 0x08, 0x04, + 0x30, 0x47, 0x00, 0x06, 0x33, 0xb5, 0xc1, 0x38, 0xb0, 0x43, 0x38, 0xcc, + 0xc3, 0x3c, 0xb8, 0x01, 0x2d, 0x94, 0x03, 0x3e, 0xd0, 0x43, 0x3d, 0xc8, + 0x43, 0x39, 0xc8, 0x01, 0x29, 0xf0, 0x81, 0x3d, 0x94, 0xc3, 0x38, 0xd0, + 0xc3, 0x3b, 0xc8, 0x03, 0x1f, 0x98, 0x03, 0x3b, 0xbc, 0x43, 0x38, 0xd0, + 0x03, 0x1b, 0x80, 0x01, 0x1d, 0xf8, 0x01, 0x18, 0xf8, 0x81, 0x1e, 0xe8, + 0x41, 0x3b, 0xa4, 0x03, 0x3c, 0xcc, 0xc3, 0x2f, 0xd0, 0x43, 0x3e, 0xc0, + 0x43, 0x39, 0xa0, 0x40, 0xcc, 0x24, 0x06, 0xe3, 0xc0, 0x0e, 0xe1, 0x30, + 0x0f, 0xf3, 0xe0, 0x06, 0xb4, 0x50, 0x0e, 0xf8, 0x40, 0x0f, 0xf5, 0x20, + 0x0f, 0xe5, 0x20, 0x07, 0xa4, 0xc0, 0x07, 0xf6, 0x50, 0x0e, 0xe3, 0x40, + 0x0f, 0xef, 0x20, 0x0f, 0x7c, 0x60, 0x0e, 0xec, 0xf0, 0x0e, 0xe1, 0x40, + 0x0f, 0x6c, 0x00, 0x06, 0x74, 0xe0, 0x07, 0x60, 0xe0, 0x07, 0x48, 0x08, + 0x83, 0xc8, 0x4d, 0xd2, 0x14, 0x51, 0xc2, 0xe4, 0xb3, 0x00, 0xf3, 0x2c, + 0x44, 0xc4, 0x4e, 0xc0, 0x44, 0xa0, 0x40, 0x90, 0x19, 0x01, 0x28, 0x01, + 0xa2, 0x34, 0x47, 0x80, 0x14, 0x03, 0x08, 0x21, 0x96, 0x20, 0x56, 0x0c, + 0x24, 0x84, 0x58, 0x80, 0xdc, 0x4d, 0xc3, 0xe5, 0x4f, 0xd8, 0x43, 0x48, + 0xfe, 0x4a, 0x48, 0x2b, 0x31, 0xf9, 0xc5, 0x6d, 0xa3, 0x02, 0x00, 0x00, + 0x04, 0xad, 0x7b, 0x86, 0xcb, 0x9f, 0xb0, 0x87, 0x90, 0xfc, 0x10, 0x68, + 0x86, 0x85, 0x40, 0x41, 0x2c, 0x0c, 0x14, 0x52, 0x02, 0x00, 0x80, 0x10, + 0x02, 0xd0, 0x2c, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0xd5, 0x39, 0x82, + 0xa0, 0x18, 0x52, 0x2c, 0x21, 0x2e, 0xe1, 0x81, 0x80, 0x61, 0x04, 0x01, + 0xb8, 0x4b, 0x9a, 0x22, 0x4a, 0x98, 0xfc, 0x14, 0xb9, 0x88, 0x85, 0x3d, + 0x80, 0x81, 0x88, 0xc4, 0xe6, 0xa1, 0x26, 0x34, 0x84, 0x1d, 0xd2, 0x41, + 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, + 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e, 0x6d, 0xd0, + 0x0e, 0x7a, 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, + 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, + 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, + 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x10, 0x07, 0x76, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x3a, 0x0f, 0x64, 0x90, 0x21, + 0x23, 0x45, 0x44, 0x00, 0x72, 0x00, 0xc0, 0xe4, 0x00, 0x80, 0xe9, 0x01, + 0x00, 0x0f, 0x79, 0x12, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0xf2, 0x30, 0x40, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x30, 0xe4, 0x71, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x60, 0xc8, 0x33, 0x01, 0x01, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x90, 0xa7, 0x02, 0x02, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x21, 0x0f, 0x06, 0x04, 0xc0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x20, 0x00, 0x00, + 0x00, 0x16, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x18, 0x19, 0x11, 0x4c, + 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x5a, 0x05, 0x42, 0xa2, + 0x04, 0x46, 0x00, 0x8a, 0xa1, 0x08, 0x4a, 0xa2, 0x50, 0xca, 0xa0, 0x1c, + 0x0a, 0xa4, 0x10, 0x4a, 0xa1, 0xc0, 0x0a, 0xa8, 0x3c, 0x0a, 0xa2, 0x6c, + 0x68, 0x15, 0xc1, 0x08, 0x40, 0x21, 0x94, 0x41, 0x49, 0xd0, 0x99, 0x01, + 0xa0, 0x32, 0x03, 0x40, 0x64, 0x06, 0x80, 0xc6, 0x0c, 0x00, 0x85, 0x19, + 0x00, 0xe2, 0x33, 0x00, 0xd4, 0xc7, 0x72, 0x18, 0x02, 0x00, 0x00, 0xe0, + 0x38, 0x00, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, + 0x00, 0xbf, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, + 0x44, 0x35, 0x18, 0x63, 0x0b, 0x73, 0x3b, 0x03, 0xb1, 0x2b, 0x93, 0x9b, + 0x4b, 0x7b, 0x73, 0x03, 0x99, 0x71, 0xb9, 0x01, 0x41, 0xa1, 0x0b, 0x3b, + 0x9b, 0x7b, 0x91, 0x2a, 0x62, 0x2a, 0x0a, 0x9a, 0x2a, 0xfa, 0x9a, 0xb9, + 0x81, 0x79, 0x31, 0x4b, 0x73, 0x0b, 0x63, 0x4b, 0xd9, 0x10, 0x04, 0x13, + 0x04, 0x41, 0x99, 0x20, 0x08, 0xcb, 0x06, 0x61, 0x20, 0x36, 0x08, 0x04, + 0x41, 0x01, 0x6e, 0x6e, 0x82, 0x20, 0x30, 0x1b, 0x86, 0x03, 0x21, 0x26, + 0x08, 0x05, 0x18, 0x70, 0xa1, 0x43, 0x2b, 0xa3, 0x2a, 0xc3, 0xa3, 0xab, + 0x93, 0x2b, 0xcb, 0x9a, 0x20, 0x08, 0xcd, 0x04, 0x41, 0x70, 0x36, 0x08, + 0x44, 0xb3, 0x21, 0x21, 0x94, 0x85, 0x20, 0x06, 0x86, 0x70, 0xc8, 0xd0, + 0xa1, 0x95, 0x51, 0x95, 0xe1, 0xd1, 0xd5, 0xc9, 0x95, 0x55, 0x59, 0x6d, + 0x48, 0x06, 0x05, 0x22, 0x86, 0x81, 0x21, 0x9c, 0x0d, 0xc2, 0x13, 0x4d, + 0x10, 0x8e, 0x8f, 0x0a, 0x1d, 0x5a, 0xd9, 0x54, 0x58, 0x1b, 0x1c, 0x5b, + 0x99, 0xdc, 0x06, 0x84, 0x98, 0x28, 0x82, 0x18, 0x08, 0x60, 0x43, 0x50, + 0x6d, 0x20, 0x24, 0x00, 0xb0, 0x26, 0x08, 0x44, 0x18, 0x4c, 0x10, 0x84, + 0x87, 0x01, 0xda, 0x04, 0x41, 0x80, 0x26, 0x08, 0x42, 0xb4, 0xc1, 0x40, + 0xb4, 0x8d, 0xe0, 0x1a, 0x12, 0x6d, 0x69, 0x70, 0x73, 0x13, 0x04, 0x41, + 0xda, 0x40, 0x20, 0xde, 0xf6, 0x4d, 0x10, 0x82, 0x31, 0xd8, 0x20, 0x10, + 0x61, 0xb0, 0x21, 0x10, 0x83, 0x0d, 0x02, 0x31, 0x06, 0x1b, 0x88, 0xac, + 0x03, 0x03, 0x32, 0x98, 0x20, 0x0c, 0x62, 0x30, 0x41, 0x10, 0x26, 0x1a, + 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x13, 0x04, 0x81, 0xda, 0x60, 0x20, + 0x68, 0xb0, 0x11, 0x5c, 0x1a, 0x6c, 0x10, 0xce, 0x40, 0x0d, 0x26, 0x08, + 0x1c, 0x19, 0x4c, 0x10, 0x84, 0x8a, 0x03, 0xdc, 0xdb, 0x1c, 0x97, 0x29, + 0xab, 0x2f, 0xa8, 0xa7, 0xa9, 0x24, 0xaa, 0xa4, 0x27, 0xa7, 0x0d, 0x08, + 0xe2, 0x06, 0x1b, 0x71, 0x06, 0x6f, 0xc0, 0x35, 0x1c, 0xe8, 0xca, 0xf0, + 0x98, 0x50, 0x15, 0x61, 0x0d, 0x3d, 0x3d, 0x49, 0x11, 0xc1, 0x6c, 0x40, + 0x90, 0x38, 0xd8, 0xbe, 0x33, 0x90, 0x03, 0xae, 0x61, 0x31, 0xf6, 0xc6, + 0xf6, 0x26, 0x37, 0x41, 0x10, 0x2c, 0x1a, 0x43, 0x4f, 0x4c, 0x4f, 0x52, + 0x30, 0x1b, 0x10, 0x84, 0x0e, 0xb6, 0x3a, 0x38, 0x03, 0x3b, 0xe0, 0x9a, + 0x0d, 0x44, 0x1b, 0xc0, 0xc1, 0x1c, 0xdc, 0xc1, 0x86, 0x83, 0xc0, 0xca, + 0xc0, 0x0c, 0xd6, 0x80, 0x0d, 0xf0, 0x60, 0x82, 0xa0, 0x0c, 0x1b, 0x80, + 0x0d, 0x03, 0xb1, 0x07, 0x7b, 0xb0, 0x21, 0xe0, 0x83, 0x0d, 0xc3, 0xa0, + 0x07, 0x7d, 0x30, 0x41, 0xe8, 0xca, 0x60, 0x43, 0xf0, 0x07, 0x24, 0xda, + 0xc2, 0xd2, 0xdc, 0xb8, 0x4c, 0x59, 0x7d, 0x41, 0xbd, 0xcd, 0xa5, 0xd1, + 0xa5, 0xbd, 0xb9, 0x4d, 0x10, 0x16, 0x6f, 0x82, 0xb0, 0x74, 0x1b, 0x02, + 0x62, 0x82, 0xb0, 0x70, 0x13, 0x84, 0x65, 0xdb, 0xb0, 0x10, 0xa2, 0x30, + 0x0a, 0xa4, 0x50, 0x0a, 0xa6, 0x30, 0x98, 0x02, 0x71, 0x0a, 0x00, 0x11, + 0xaa, 0x22, 0xac, 0xa1, 0xa7, 0x27, 0x29, 0xa2, 0x09, 0xc2, 0xa2, 0x6d, + 0x10, 0xb6, 0x6d, 0xc3, 0x32, 0xa4, 0xc2, 0x28, 0x9c, 0x42, 0x29, 0xa8, + 0xc2, 0xa0, 0x0a, 0xc3, 0x29, 0xac, 0x02, 0x8b, 0xa1, 0x27, 0xa6, 0x27, + 0xa9, 0x09, 0x82, 0x70, 0x6d, 0x10, 0x36, 0x57, 0xd8, 0xb0, 0x30, 0xad, + 0x30, 0x0a, 0xa7, 0x50, 0x0a, 0xaa, 0x30, 0x98, 0x02, 0x73, 0x0a, 0xaf, + 0xb0, 0x61, 0x40, 0x05, 0x56, 0x80, 0x05, 0x26, 0x53, 0x56, 0x5f, 0x54, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x13, 0x84, 0x25, 0xd9, 0xb0, 0x10, 0xb2, + 0x30, 0x0a, 0xb3, 0x50, 0x0a, 0xa7, 0x30, 0x98, 0x02, 0x71, 0x0a, 0xaf, + 0xb0, 0x21, 0xa0, 0x85, 0x0d, 0x43, 0x2c, 0xd4, 0x02, 0xb0, 0xa1, 0xd0, + 0x83, 0x50, 0xb0, 0x85, 0x0b, 0xa0, 0x61, 0xc6, 0xf6, 0x16, 0x46, 0x37, + 0x37, 0x41, 0x10, 0x30, 0x16, 0x69, 0x6e, 0x73, 0x74, 0x73, 0x13, 0x04, + 0x21, 0xa3, 0x31, 0x97, 0x76, 0xf6, 0xc5, 0x46, 0x46, 0x63, 0x2e, 0xed, + 0xec, 0x6b, 0x8e, 0x8e, 0x08, 0x5d, 0x19, 0xde, 0x97, 0xdb, 0x9b, 0x5c, + 0xdb, 0x06, 0x05, 0x17, 0x72, 0x41, 0x17, 0x76, 0x81, 0x17, 0x90, 0x5e, + 0x38, 0x03, 0x5f, 0x60, 0xaa, 0xb0, 0xb1, 0xd9, 0xb5, 0xb9, 0xa4, 0x91, + 0x95, 0xb9, 0xd1, 0x4d, 0x09, 0x82, 0x2a, 0x64, 0x78, 0x2e, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x02, 0xa2, 0x09, 0x19, 0x9e, 0x8b, + 0x5d, 0x18, 0x9b, 0x5d, 0x99, 0xdc, 0x94, 0xa0, 0xa8, 0x43, 0x86, 0xe7, + 0x32, 0x87, 0x16, 0x46, 0x56, 0x26, 0xd7, 0xf4, 0x46, 0x56, 0xc6, 0x36, + 0x25, 0x40, 0xca, 0x90, 0xe1, 0xb9, 0xc8, 0x95, 0xcd, 0xbd, 0xd5, 0xc9, + 0x8d, 0x95, 0xcd, 0x4d, 0x09, 0xac, 0x4a, 0x64, 0x78, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x53, 0x04, 0x3c, 0xe8, 0x83, 0x3a, 0x64, 0x78, 0x2e, 0x76, 0x69, + 0x65, 0x77, 0x49, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x82, 0x3f, + 0xa8, 0x43, 0x86, 0xe7, 0x52, 0xe6, 0x46, 0x27, 0x97, 0x07, 0xf5, 0x96, + 0xe6, 0x46, 0x37, 0x37, 0x25, 0xb0, 0x85, 0x2e, 0x64, 0x78, 0x2e, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x53, 0x02, 0x5f, 0x00, 0x00, + 0x00, 0x79, 0x18, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, + 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, + 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, + 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, + 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, + 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, + 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, + 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, + 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, + 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, + 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, + 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, + 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, + 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, + 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, + 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, + 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, + 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, + 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, + 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, + 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, + 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, + 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc4, 0x21, 0x07, 0x7c, + 0x70, 0x03, 0x7a, 0x28, 0x87, 0x76, 0x80, 0x87, 0x19, 0xd1, 0x43, 0x0e, + 0xf8, 0xe0, 0x06, 0xe4, 0x20, 0x0e, 0xe7, 0xe0, 0x06, 0xf6, 0x10, 0x0e, + 0xf2, 0xc0, 0x0e, 0xe1, 0x90, 0x0f, 0xef, 0x50, 0x0f, 0xf4, 0x00, 0x00, + 0x00, 0x71, 0x20, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x25, 0xf0, 0x05, + 0x7e, 0x74, 0x74, 0x79, 0x1a, 0x6e, 0xc3, 0xd9, 0x65, 0x39, 0x10, 0x38, + 0xab, 0x4e, 0xc3, 0x6d, 0x38, 0xbb, 0x2c, 0x9f, 0xd2, 0xc3, 0xf4, 0x32, + 0x10, 0x18, 0xac, 0x80, 0x38, 0x08, 0xfc, 0xe8, 0xe8, 0x32, 0xb5, 0x8c, + 0xa7, 0xd7, 0xe5, 0xe5, 0xaa, 0x15, 0x08, 0x9c, 0x59, 0x7f, 0x24, 0x6a, + 0x19, 0x4f, 0xaf, 0xcb, 0xcb, 0x32, 0x22, 0xd0, 0xfa, 0x23, 0xd9, 0xcb, + 0x63, 0xfa, 0x5b, 0x0e, 0x6c, 0x92, 0x60, 0x33, 0x20, 0x10, 0x08, 0x0c, + 0x16, 0x00, 0x1c, 0x04, 0x7e, 0x74, 0x74, 0x99, 0x5a, 0xc6, 0xd3, 0xeb, + 0xf2, 0x72, 0x16, 0x08, 0x9c, 0x59, 0x7f, 0x24, 0x6a, 0x19, 0x4f, 0xaf, + 0xcb, 0xcb, 0x32, 0x22, 0xd0, 0xfa, 0x23, 0xd9, 0xcb, 0x63, 0xfa, 0x5b, + 0x0e, 0x6c, 0x92, 0x60, 0x33, 0x20, 0x10, 0x08, 0x0c, 0x1a, 0x82, 0x34, + 0x5c, 0xbe, 0xf3, 0xf8, 0x42, 0x44, 0x00, 0x13, 0x11, 0x02, 0xcd, 0xb0, + 0x10, 0x76, 0xe0, 0x0c, 0x97, 0xef, 0x3c, 0xfe, 0xe0, 0x4c, 0xb7, 0x5f, + 0xdc, 0xb6, 0x11, 0x4c, 0xc3, 0xe5, 0x3b, 0x8f, 0xbf, 0x38, 0xc0, 0x20, + 0x36, 0x0f, 0x35, 0xf9, 0xc5, 0x6d, 0x9b, 0x01, 0x34, 0x5c, 0xbe, 0xf3, + 0xf8, 0x12, 0xc0, 0x3c, 0x0b, 0xe1, 0x17, 0xb7, 0x6d, 0x05, 0xd5, 0x70, + 0xf9, 0xce, 0xe3, 0x4b, 0x93, 0x13, 0x11, 0x28, 0x35, 0x3d, 0xd4, 0xe4, + 0x17, 0xb7, 0x6d, 0x03, 0x04, 0x03, 0x20, 0x0d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x48, 0x41, 0x53, 0x48, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3d, 0xf1, 0x38, 0x49, 0x7f, 0x91, 0x6b, 0xbb, 0x2e, 0x0c, 0x31, + 0x06, 0xa9, 0xa3, 0xcd, 0x81, 0x44, 0x58, 0x49, 0x4c, 0xa0, 0x07, 0x00, + 0x00, 0x60, 0x00, 0x00, 0x00, 0xe8, 0x01, 0x00, 0x00, 0x44, 0x58, 0x49, + 0x4c, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x88, 0x07, 0x00, + 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0xdf, 0x01, 0x00, + 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, + 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, + 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, + 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, + 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88, 0x48, 0x90, 0x14, + 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4, 0x48, 0x0e, + 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, + 0x8a, 0x04, 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40, 0x02, 0xa8, + 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x20, 0x6d, 0x30, 0x86, + 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x09, 0xa8, 0x00, 0x49, 0x18, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, 0x42, 0x20, 0x4c, 0x08, + 0x06, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x45, 0x00, 0x00, + 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, + 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, + 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x70, 0x23, 0x00, 0x25, 0x00, 0x14, + 0x66, 0x00, 0xe6, 0x08, 0xc0, 0x60, 0x8e, 0x00, 0x29, 0xc6, 0x20, 0x84, + 0x14, 0x42, 0xa6, 0x18, 0x80, 0x10, 0x52, 0x06, 0xa1, 0x9b, 0x86, 0xcb, + 0x9f, 0xb0, 0x87, 0x90, 0xfc, 0x95, 0x90, 0x56, 0x62, 0xf2, 0x8b, 0xdb, + 0x46, 0xc5, 0x18, 0x63, 0x10, 0x2a, 0xf7, 0x0c, 0x97, 0x3f, 0x61, 0x0f, + 0x21, 0xf9, 0x21, 0xd0, 0x0c, 0x0b, 0x81, 0x82, 0x55, 0x18, 0x45, 0x18, + 0x1b, 0x63, 0x0c, 0x42, 0xc8, 0xa0, 0x56, 0x90, 0x41, 0xc6, 0x18, 0x63, + 0x0c, 0x7a, 0x73, 0x04, 0x41, 0x31, 0x18, 0x29, 0x84, 0x44, 0x92, 0x03, + 0x01, 0xc3, 0x08, 0xc4, 0x30, 0x53, 0x1b, 0x8c, 0x03, 0x3b, 0x84, 0xc3, + 0x3c, 0xcc, 0x83, 0x1b, 0xd0, 0x42, 0x39, 0xe0, 0x03, 0x3d, 0xd4, 0x83, + 0x3c, 0x94, 0x83, 0x1c, 0x90, 0x02, 0x1f, 0xd8, 0x43, 0x39, 0x8c, 0x03, + 0x3d, 0xbc, 0x83, 0x3c, 0xf0, 0x81, 0x39, 0xb0, 0xc3, 0x3b, 0x84, 0x03, + 0x3d, 0xb0, 0x01, 0x18, 0xd0, 0x81, 0x1f, 0x80, 0x81, 0x1f, 0xe8, 0x81, + 0x1e, 0xb4, 0x43, 0x3a, 0xc0, 0xc3, 0x3c, 0xfc, 0x02, 0x3d, 0xe4, 0x03, + 0x3c, 0x94, 0x03, 0x0a, 0xc8, 0x4c, 0x62, 0x30, 0x0e, 0xec, 0x10, 0x0e, + 0xf3, 0x30, 0x0f, 0x6e, 0x40, 0x0b, 0xe5, 0x80, 0x0f, 0xf4, 0x50, 0x0f, + 0xf2, 0x50, 0x0e, 0x72, 0x40, 0x0a, 0x7c, 0x60, 0x0f, 0xe5, 0x30, 0x0e, + 0xf4, 0xf0, 0x0e, 0xf2, 0xc0, 0x07, 0xe6, 0xc0, 0x0e, 0xef, 0x10, 0x0e, + 0xf4, 0xc0, 0x06, 0x60, 0x40, 0x07, 0x7e, 0x00, 0x06, 0x7e, 0x80, 0x84, + 0x6a, 0xe9, 0xde, 0x24, 0x4d, 0x11, 0x25, 0x4c, 0x3e, 0x0b, 0x30, 0xcf, + 0x42, 0x44, 0xec, 0x04, 0x4c, 0x04, 0x0a, 0x08, 0xe5, 0x74, 0x20, 0x00, + 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, + 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e, 0x6d, 0xd0, + 0x0e, 0x7a, 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, + 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, + 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, + 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x10, 0x07, 0x76, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x43, 0x9e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x3c, 0x06, 0x10, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x79, 0x10, + 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf2, + 0x34, 0x40, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, + 0xe4, 0x79, 0x80, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0xc8, 0x23, 0x01, 0x01, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x16, 0x08, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, + 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, + 0x22, 0x25, 0x30, 0x02, 0x50, 0x0c, 0x45, 0x50, 0x12, 0x65, 0x50, 0x1e, + 0x54, 0x4a, 0xa2, 0x0c, 0x0a, 0x61, 0x04, 0xa0, 0x08, 0x0a, 0x84, 0xf0, + 0x0c, 0x00, 0xe9, 0x19, 0x00, 0xda, 0x63, 0x39, 0x0c, 0x01, 0x00, 0x00, + 0x70, 0x1c, 0x00, 0x10, 0x08, 0x04, 0x02, 0x00, 0x00, 0x79, 0x18, 0x00, + 0x00, 0x65, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, + 0x44, 0x35, 0x18, 0x63, 0x0b, 0x73, 0x3b, 0x03, 0xb1, 0x2b, 0x93, 0x9b, + 0x4b, 0x7b, 0x73, 0x03, 0x99, 0x71, 0xb9, 0x01, 0x41, 0xa1, 0x0b, 0x3b, + 0x9b, 0x7b, 0x91, 0x2a, 0x62, 0x2a, 0x0a, 0x9a, 0x2a, 0xfa, 0x9a, 0xb9, + 0x81, 0x79, 0x31, 0x4b, 0x73, 0x0b, 0x63, 0x4b, 0xd9, 0x10, 0x04, 0x13, + 0x04, 0xc2, 0x98, 0x20, 0x10, 0xc7, 0x06, 0x61, 0x20, 0x26, 0x08, 0x04, + 0xb2, 0x41, 0x18, 0x0c, 0x0a, 0x70, 0x73, 0x1b, 0x06, 0xc4, 0x20, 0x26, + 0x08, 0xd8, 0x44, 0x60, 0x82, 0x40, 0x24, 0x13, 0x04, 0x42, 0xd9, 0x20, + 0x10, 0xcd, 0x86, 0x84, 0x50, 0x16, 0x82, 0x18, 0x18, 0xc2, 0xd9, 0x90, + 0x0c, 0xca, 0x42, 0x0c, 0x03, 0x43, 0x38, 0x1b, 0x84, 0x07, 0x9a, 0x20, + 0x68, 0xd4, 0x06, 0x84, 0x90, 0x16, 0x82, 0x18, 0x08, 0x60, 0x43, 0x30, + 0x6d, 0x20, 0x22, 0x00, 0xa0, 0x26, 0x08, 0x5b, 0xb5, 0x21, 0xb0, 0x26, + 0x08, 0x02, 0x40, 0xa2, 0x2d, 0x2c, 0xcd, 0x8d, 0xcb, 0x94, 0xd5, 0x17, + 0xd4, 0xdb, 0x5c, 0x1a, 0x5d, 0xda, 0x9b, 0xdb, 0x04, 0xa1, 0x68, 0x26, + 0x08, 0x85, 0xb3, 0x21, 0x20, 0x26, 0x08, 0xc5, 0x33, 0x41, 0x28, 0xa0, + 0x0d, 0x0b, 0xa1, 0x6d, 0x5c, 0xe7, 0x0d, 0x1e, 0xf1, 0x01, 0x44, 0xa8, + 0x8a, 0xb0, 0x86, 0x9e, 0x9e, 0xa4, 0x88, 0x26, 0x08, 0x45, 0x34, 0x41, + 0x20, 0x96, 0x0d, 0xc2, 0x18, 0x8c, 0xc1, 0x86, 0x65, 0x08, 0x83, 0xed, + 0xeb, 0xc4, 0x60, 0x10, 0x83, 0xe1, 0x23, 0x03, 0x16, 0x43, 0x4f, 0x4c, + 0x4f, 0x52, 0x13, 0x04, 0x82, 0xd9, 0x20, 0x8c, 0xc1, 0x19, 0x6c, 0x58, + 0x18, 0x33, 0xd8, 0xbe, 0x4e, 0x0c, 0x06, 0x8f, 0xf9, 0xd0, 0x60, 0xc3, + 0x00, 0x06, 0x65, 0x90, 0x06, 0x4c, 0xa6, 0xac, 0xbe, 0xa8, 0xc2, 0xe4, + 0xce, 0xca, 0xe8, 0x26, 0x08, 0x85, 0xb4, 0x61, 0x21, 0xd6, 0x60, 0x63, + 0x83, 0xee, 0x1b, 0x3c, 0xe2, 0x43, 0x83, 0x0d, 0x41, 0x1b, 0x6c, 0x18, + 0xd4, 0xc0, 0x0d, 0x80, 0x0d, 0x05, 0x96, 0xbd, 0x41, 0x05, 0x54, 0x61, + 0x63, 0xb3, 0x6b, 0x73, 0x49, 0x23, 0x2b, 0x73, 0xa3, 0x9b, 0x12, 0x04, + 0x55, 0xc8, 0xf0, 0x5c, 0xec, 0xca, 0xe4, 0xe6, 0xd2, 0xde, 0xdc, 0xa6, + 0x04, 0x44, 0x13, 0x32, 0x3c, 0x17, 0xbb, 0x30, 0x36, 0xbb, 0x32, 0xb9, + 0x29, 0x81, 0x51, 0x87, 0x0c, 0xcf, 0x65, 0x0e, 0x2d, 0x8c, 0xac, 0x4c, + 0xae, 0xe9, 0x8d, 0xac, 0x8c, 0x6d, 0x4a, 0x80, 0x94, 0x21, 0xc3, 0x73, + 0x91, 0x2b, 0x9b, 0x7b, 0xab, 0x93, 0x1b, 0x2b, 0x9b, 0x9b, 0x12, 0x50, + 0x75, 0xc8, 0xf0, 0x5c, 0xec, 0xd2, 0xca, 0xee, 0x92, 0xc8, 0xa6, 0xe8, + 0xc2, 0xe8, 0xca, 0xa6, 0x04, 0x56, 0x1d, 0x32, 0x3c, 0x97, 0x32, 0x37, + 0x3a, 0xb9, 0x3c, 0xa8, 0xb7, 0x34, 0x37, 0xba, 0xb9, 0x29, 0xc1, 0x1b, + 0x00, 0x79, 0x18, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, + 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, + 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, + 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, + 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, + 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, + 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, + 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, + 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, + 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, + 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, + 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, + 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, + 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, + 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, + 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, + 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, + 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, + 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, + 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, + 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, + 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, + 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc4, 0x21, 0x07, 0x7c, + 0x70, 0x03, 0x7a, 0x28, 0x87, 0x76, 0x80, 0x87, 0x19, 0xd1, 0x43, 0x0e, + 0xf8, 0xe0, 0x06, 0xe4, 0x20, 0x0e, 0xe7, 0xe0, 0x06, 0xf6, 0x10, 0x0e, + 0xf2, 0xc0, 0x0e, 0xe1, 0x90, 0x0f, 0xef, 0x50, 0x0f, 0xf4, 0x00, 0x00, + 0x00, 0x71, 0x20, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x56, 0x20, 0x0d, + 0x97, 0xef, 0x3c, 0xbe, 0x10, 0x11, 0xc0, 0x44, 0x84, 0x40, 0x33, 0x2c, + 0x84, 0x11, 0x38, 0xc3, 0xe5, 0x3b, 0x8f, 0x3f, 0x38, 0xd3, 0xed, 0x17, + 0xb7, 0x6d, 0x01, 0xd3, 0x70, 0xf9, 0xce, 0xe3, 0x2f, 0x0e, 0x30, 0x88, + 0xcd, 0x43, 0x4d, 0x7e, 0x71, 0xdb, 0x36, 0x00, 0x0d, 0x97, 0xef, 0x3c, + 0xbe, 0x04, 0x30, 0xcf, 0x42, 0xf8, 0xc5, 0x6d, 0x9b, 0x40, 0x35, 0x5c, + 0xbe, 0xf3, 0xf8, 0xd2, 0xe4, 0x44, 0x04, 0x4a, 0x4d, 0x0f, 0x35, 0xf9, + 0xc5, 0x6d, 0x1b, 0x00, 0xc1, 0x00, 0x48, 0x03, 0x00, 0x61, 0x20, 0x00, + 0x00, 0x5d, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x14, 0x47, 0x00, 0xa8, 0x94, 0x00, 0x91, + 0xc2, 0x2b, 0xb7, 0x92, 0x2b, 0x85, 0x42, 0x98, 0x01, 0xa0, 0x31, 0x46, + 0x50, 0x9e, 0x74, 0xe9, 0x7f, 0x63, 0x04, 0xa2, 0x3e, 0xb7, 0xf3, 0x2f, + 0x8c, 0x11, 0x80, 0xef, 0x0a, 0xae, 0xbf, 0x30, 0x46, 0xc0, 0x97, 0xbd, + 0xb9, 0x7f, 0x23, 0x00, 0x63, 0x04, 0x21, 0x09, 0x86, 0xf0, 0x2f, 0x8c, + 0x11, 0x80, 0x20, 0x08, 0xe2, 0xdf, 0x0c, 0x00, 0x00, 0x23, 0x06, 0x09, + 0x00, 0x82, 0x60, 0x20, 0x85, 0x01, 0x63, 0x81, 0x01, 0x18, 0x40, 0x23, + 0x06, 0x09, 0x00, 0x82, 0x60, 0x20, 0x89, 0x41, 0x73, 0x81, 0x01, 0x18, + 0x44, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x20, 0x8d, 0x81, 0xa3, 0x85, + 0x41, 0x18, 0x48, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x60, 0xa0, 0x41, + 0x03, 0x06, 0x62, 0x90, 0x31, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x60, + 0xa4, 0x81, 0x13, 0x06, 0x63, 0x30, 0x35, 0x23, 0x06, 0x09, 0x00, 0x82, + 0x60, 0x60, 0xa8, 0xc1, 0x23, 0x06, 0x64, 0xa0, 0x39, 0x23, 0x06, 0x09, + 0x00, 0x82, 0x60, 0x60, 0xac, 0x01, 0x34, 0x06, 0x65, 0xe0, 0x3d, 0x23, + 0x06, 0x09, 0x00, 0x82, 0x60, 0x60, 0xb0, 0x41, 0x74, 0x06, 0x66, 0xd0, + 0x41, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x60, 0xb4, 0x81, 0x84, 0x06, + 0x67, 0x70, 0x45, 0x23, 0x06, 0x0f, 0x00, 0x82, 0x60, 0xd0, 0xb0, 0xc1, + 0x85, 0x1c, 0x42, 0xa0, 0x28, 0x68, 0x80, 0x06, 0x92, 0x32, 0x9a, 0x10, + 0x00, 0x23, 0x06, 0x0f, 0x00, 0x82, 0x60, 0xd0, 0xb8, 0x41, 0xb6, 0x24, + 0xc4, 0xc0, 0x30, 0x6a, 0xa0, 0x06, 0x14, 0x33, 0x9a, 0x10, 0x00, 0xa3, + 0x09, 0x42, 0x60, 0x41, 0x04, 0x1f, 0x1b, 0x24, 0xf8, 0x8c, 0x18, 0x2c, + 0x00, 0x08, 0x82, 0xc1, 0x23, 0x07, 0x9d, 0x21, 0x04, 0x12, 0x55, 0x8d, + 0x18, 0x2c, 0x00, 0x08, 0x82, 0xc1, 0x33, 0x07, 0xde, 0x31, 0x08, 0xd3, + 0x85, 0x8d, 0x18, 0x2c, 0x00, 0x08, 0x82, 0xc1, 0x43, 0x07, 0x1f, 0x42, + 0x0c, 0x94, 0x66, 0xd9, 0x00, 0xc9, 0xc7, 0x06, 0x48, 0x3e, 0x36, 0x40, + 0xf2, 0x19, 0x31, 0x48, 0x00, 0x10, 0x04, 0x03, 0x44, 0x0f, 0xc2, 0xa0, + 0x0e, 0xea, 0x80, 0x0d, 0x86, 0x11, 0x83, 0x04, 0x00, 0x41, 0x30, 0x40, + 0xf4, 0x20, 0x0c, 0xea, 0xa0, 0x0e, 0xca, 0x40, 0x18, 0x31, 0x48, 0x00, + 0x10, 0x04, 0x03, 0x44, 0x0f, 0xc2, 0xa0, 0x0e, 0xea, 0x60, 0x0d, 0x82, + 0x11, 0x83, 0x04, 0x00, 0x41, 0x30, 0x40, 0xf4, 0x20, 0x0c, 0xea, 0xa0, + 0x0e, 0xdc, 0x00, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +/* The yuv-rendering pixel shader: + + --- D3D12_PixelShader_NV21_BT601.hlsl --- + Texture2D theTextureY : register(t0); + Texture2D theTextureUV : register(t1); + SamplerState theSampler : register(s0); + + struct PixelShaderInput + { + float4 pos : SV_POSITION; + float2 tex : TEXCOORD0; + float4 color : COLOR0; + }; + + #define NVRS \ + "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \ + " DENY_DOMAIN_SHADER_ROOT_ACCESS |" \ + " DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \ + " DENY_HULL_SHADER_ROOT_ACCESS )," \ + "RootConstants(num32BitConstants=32, b0),"\ + "DescriptorTable ( SRV(t0), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( SRV(t1), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( Sampler(s0), visibility = SHADER_VISIBILITY_PIXEL )" + + [RootSignature(NVRS)] + float4 main(PixelShaderInput input) : SV_TARGET + { + const float3 offset = {-0.0627451017, -0.501960814, -0.501960814}; + const float3 Rcoeff = {1.1644, 0.0000, 1.5960}; + const float3 Gcoeff = {1.1644, -0.3918, -0.8130}; + const float3 Bcoeff = {1.1644, 2.0172, 0.0000}; + + float4 Output; + + float3 yuv; + yuv.x = theTextureY.Sample(theSampler, input.tex).r; + yuv.yz = theTextureUV.Sample(theSampler, input.tex).gr; + + yuv += offset; + Output.r = dot(yuv, Rcoeff); + Output.g = dot(yuv, Gcoeff); + Output.b = dot(yuv, Bcoeff); + Output.a = 1.0f; + + return Output * input.color; + } + +*/ + +static unsigned char D3D12_PixelShader_NV21_BT601[] = { + 0x44, 0x58, 0x42, 0x43, 0x06, 0x29, 0xca, 0x47, 0x9e, 0x47, 0xed, 0x99, + 0xcf, 0xa5, 0xa6, 0xdb, 0x0b, 0x0d, 0xa5, 0x31, 0x01, 0x00, 0x00, 0x00, + 0xe9, 0x12, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0xdb, 0x00, 0x00, 0x00, 0x15, 0x01, 0x00, 0x00, + 0x0d, 0x02, 0x00, 0x00, 0xc9, 0x02, 0x00, 0x00, 0x15, 0x0b, 0x00, 0x00, + 0x31, 0x0b, 0x00, 0x00, 0x53, 0x46, 0x49, 0x30, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31, + 0x83, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x53, 0x56, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, + 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x43, 0x4f, 0x4c, + 0x4f, 0x52, 0x00, 0x4f, 0x53, 0x47, 0x31, 0x32, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x00, 0x50, 0x53, 0x56, 0x30, 0xf0, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x03, 0x01, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x43, + 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x44, 0x03, 0x03, 0x04, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x42, 0x00, 0x03, 0x02, 0x00, + 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, + 0x00, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x44, 0x10, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x52, 0x54, 0x53, + 0x30, 0xb4, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, + 0x00, 0x1d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0xff, 0x01, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, + 0x00, 0x9c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xff, 0xff, 0x53, 0x54, 0x41, 0x54, 0x44, 0x08, 0x00, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x11, 0x02, 0x00, 0x00, 0x44, 0x58, 0x49, + 0x4c, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x2c, 0x08, 0x00, + 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x08, 0x02, 0x00, + 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, + 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, + 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, + 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, + 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88, 0x48, 0x90, 0x14, + 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4, 0x48, 0x0e, + 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, + 0x8a, 0x04, 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40, 0x02, 0xa8, + 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x20, 0x6d, 0x30, 0x86, + 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x09, 0xa8, 0x00, 0x49, 0x18, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, 0x42, 0x20, 0x4c, 0x08, + 0x06, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x4b, 0x00, 0x00, + 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, + 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, + 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x78, 0x33, 0x00, 0xc3, 0x08, 0x04, + 0x30, 0x47, 0x00, 0x06, 0x33, 0xb5, 0xc1, 0x38, 0xb0, 0x43, 0x38, 0xcc, + 0xc3, 0x3c, 0xb8, 0x01, 0x2d, 0x94, 0x03, 0x3e, 0xd0, 0x43, 0x3d, 0xc8, + 0x43, 0x39, 0xc8, 0x01, 0x29, 0xf0, 0x81, 0x3d, 0x94, 0xc3, 0x38, 0xd0, + 0xc3, 0x3b, 0xc8, 0x03, 0x1f, 0x98, 0x03, 0x3b, 0xbc, 0x43, 0x38, 0xd0, + 0x03, 0x1b, 0x80, 0x01, 0x1d, 0xf8, 0x01, 0x18, 0xf8, 0x81, 0x1e, 0xe8, + 0x41, 0x3b, 0xa4, 0x03, 0x3c, 0xcc, 0xc3, 0x2f, 0xd0, 0x43, 0x3e, 0xc0, + 0x43, 0x39, 0xa0, 0x40, 0xcc, 0x24, 0x06, 0xe3, 0xc0, 0x0e, 0xe1, 0x30, + 0x0f, 0xf3, 0xe0, 0x06, 0xb4, 0x50, 0x0e, 0xf8, 0x40, 0x0f, 0xf5, 0x20, + 0x0f, 0xe5, 0x20, 0x07, 0xa4, 0xc0, 0x07, 0xf6, 0x50, 0x0e, 0xe3, 0x40, + 0x0f, 0xef, 0x20, 0x0f, 0x7c, 0x60, 0x0e, 0xec, 0xf0, 0x0e, 0xe1, 0x40, + 0x0f, 0x6c, 0x00, 0x06, 0x74, 0xe0, 0x07, 0x60, 0xe0, 0x07, 0x48, 0x08, + 0x83, 0xc8, 0x4d, 0xd2, 0x14, 0x51, 0xc2, 0xe4, 0xb3, 0x00, 0xf3, 0x2c, + 0x44, 0xc4, 0x4e, 0xc0, 0x44, 0xa0, 0x40, 0x90, 0x19, 0x01, 0x28, 0x01, + 0xa2, 0x34, 0x47, 0x80, 0x14, 0x03, 0x08, 0x21, 0x96, 0x20, 0x56, 0x0c, + 0x24, 0x84, 0x58, 0x80, 0xdc, 0x4d, 0xc3, 0xe5, 0x4f, 0xd8, 0x43, 0x48, + 0xfe, 0x4a, 0x48, 0x2b, 0x31, 0xf9, 0xc5, 0x6d, 0xa3, 0x02, 0x00, 0x00, + 0x04, 0xad, 0x7b, 0x86, 0xcb, 0x9f, 0xb0, 0x87, 0x90, 0xfc, 0x10, 0x68, + 0x86, 0x85, 0x40, 0x41, 0x2c, 0x0c, 0x14, 0x52, 0x02, 0x00, 0x80, 0x10, + 0x02, 0xd0, 0x2c, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0xd5, 0x39, 0x82, + 0xa0, 0x18, 0x52, 0x2c, 0x21, 0x2e, 0xe1, 0x81, 0x80, 0x61, 0x04, 0x01, + 0xb8, 0x4b, 0x9a, 0x22, 0x4a, 0x98, 0xfc, 0x14, 0xb9, 0x88, 0x85, 0x3d, + 0x80, 0x81, 0x88, 0xc4, 0xe6, 0xa1, 0x26, 0x34, 0x84, 0x1d, 0xd2, 0x41, + 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, + 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e, 0x6d, 0xd0, + 0x0e, 0x7a, 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, + 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, + 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, + 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x10, 0x07, 0x76, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x3a, 0x0f, 0x64, 0x90, 0x21, + 0x23, 0x45, 0x44, 0x00, 0x72, 0x00, 0xc0, 0xe4, 0x00, 0x80, 0xe9, 0x01, + 0x00, 0x0f, 0x79, 0x12, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0xf2, 0x30, 0x40, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x30, 0xe4, 0x71, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x60, 0xc8, 0x33, 0x01, 0x01, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x90, 0xa7, 0x02, 0x02, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x21, 0x0f, 0x06, 0x04, 0xc0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x20, 0x00, 0x00, + 0x00, 0x15, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x18, 0x19, 0x11, 0x4c, + 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x5a, 0x05, 0x42, 0xa2, + 0x04, 0x46, 0x00, 0x8a, 0xa1, 0x08, 0x4a, 0xa2, 0x50, 0xca, 0xa0, 0x1c, + 0x0a, 0xa4, 0x10, 0x4a, 0xa1, 0xc0, 0x0a, 0xa8, 0x3c, 0x0a, 0x87, 0x56, + 0x11, 0x8c, 0x00, 0x14, 0x42, 0x19, 0x94, 0x04, 0x9d, 0x19, 0x00, 0x2a, + 0x33, 0x00, 0x44, 0x66, 0x00, 0x68, 0xcc, 0x00, 0x50, 0x98, 0x01, 0x20, + 0x3e, 0x03, 0x40, 0x7d, 0x2c, 0x87, 0x21, 0x00, 0x00, 0x00, 0x8e, 0x03, + 0x00, 0x02, 0x81, 0x40, 0x00, 0x79, 0x18, 0x00, 0x00, 0xbe, 0x00, 0x00, + 0x00, 0x1a, 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, 0x44, 0x35, 0x18, 0x63, + 0x0b, 0x73, 0x3b, 0x03, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x03, + 0x99, 0x71, 0xb9, 0x01, 0x41, 0xa1, 0x0b, 0x3b, 0x9b, 0x7b, 0x91, 0x2a, + 0x62, 0x2a, 0x0a, 0x9a, 0x2a, 0xfa, 0x9a, 0xb9, 0x81, 0x79, 0x31, 0x4b, + 0x73, 0x0b, 0x63, 0x4b, 0xd9, 0x10, 0x04, 0x13, 0x04, 0x41, 0x99, 0x20, + 0x08, 0xcb, 0x06, 0x61, 0x20, 0x36, 0x08, 0x04, 0x41, 0x01, 0x6e, 0x6e, + 0x82, 0x20, 0x30, 0x1b, 0x86, 0x03, 0x21, 0x26, 0x08, 0xc5, 0xc7, 0x85, + 0x0e, 0xad, 0x8c, 0xaa, 0x0c, 0x8f, 0xae, 0x4e, 0xae, 0x2c, 0x6b, 0x82, + 0x20, 0x34, 0x13, 0x04, 0xc1, 0xd9, 0x20, 0x10, 0xcd, 0x86, 0x84, 0x50, + 0x16, 0x82, 0x18, 0x18, 0xc2, 0x21, 0x43, 0x87, 0x56, 0x46, 0x55, 0x86, + 0x47, 0x57, 0x27, 0x57, 0x56, 0x65, 0xb5, 0x21, 0x19, 0x14, 0x88, 0x18, + 0x06, 0x86, 0x70, 0x36, 0x08, 0x4f, 0x34, 0x41, 0x38, 0x3c, 0x2a, 0x74, + 0x68, 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x1b, 0x10, 0x62, + 0xa2, 0x08, 0x62, 0x20, 0x80, 0x0d, 0x41, 0xb5, 0x81, 0x90, 0x00, 0xc0, + 0x9a, 0x20, 0x10, 0x60, 0x30, 0x41, 0x10, 0x1e, 0x06, 0x68, 0x13, 0x04, + 0x01, 0x9a, 0x20, 0x08, 0xd1, 0x06, 0x03, 0xd1, 0x36, 0x82, 0x6b, 0x48, + 0xb4, 0xa5, 0xc1, 0xcd, 0x4d, 0x10, 0x04, 0x69, 0x03, 0x81, 0x78, 0xdb, + 0x37, 0x41, 0x08, 0xc4, 0x60, 0x83, 0x40, 0x84, 0xc1, 0x86, 0x40, 0x0c, + 0x36, 0x08, 0xc4, 0x18, 0x6c, 0x20, 0xb2, 0x0e, 0x0c, 0xc8, 0x60, 0x82, + 0x30, 0x84, 0xc1, 0x04, 0x41, 0x98, 0x68, 0xa0, 0x85, 0xb9, 0x91, 0xb1, + 0x95, 0x4d, 0x10, 0x04, 0x6a, 0x83, 0x81, 0xa0, 0xc1, 0x46, 0x70, 0x69, + 0xb0, 0x41, 0x38, 0x03, 0x35, 0x98, 0x20, 0x70, 0x63, 0x30, 0x41, 0x10, + 0x2a, 0x0e, 0x70, 0x6f, 0x73, 0x5c, 0xa6, 0xac, 0xbe, 0xa0, 0x9e, 0xa6, + 0x92, 0xa8, 0x92, 0x9e, 0x9c, 0x36, 0x20, 0x88, 0x1b, 0x6c, 0xc4, 0x19, + 0xbc, 0x01, 0xd7, 0x70, 0xa0, 0x2b, 0xc3, 0x63, 0x42, 0x55, 0x84, 0x35, + 0xf4, 0xf4, 0x24, 0x45, 0x04, 0xb3, 0x01, 0x41, 0xe2, 0x60, 0xfb, 0xce, + 0x40, 0x0e, 0xb8, 0x86, 0xc5, 0xd8, 0x1b, 0xdb, 0x9b, 0xdc, 0x04, 0x41, + 0xb0, 0x68, 0x0c, 0x3d, 0x31, 0x3d, 0x49, 0xc1, 0x6c, 0x40, 0x10, 0x3a, + 0xd8, 0xea, 0xe0, 0x0c, 0xec, 0x80, 0x6b, 0x36, 0x10, 0x6d, 0x00, 0x07, + 0x73, 0x70, 0x07, 0x1b, 0x0e, 0x02, 0x2b, 0x03, 0x33, 0x58, 0x03, 0x36, + 0xc0, 0x83, 0x09, 0x82, 0x32, 0x6c, 0x00, 0x36, 0x0c, 0xc4, 0x1e, 0xec, + 0xc1, 0x86, 0x80, 0x0f, 0x36, 0x0c, 0x83, 0x1e, 0xf4, 0xc1, 0x04, 0xa1, + 0x23, 0x83, 0x0d, 0xc1, 0x1f, 0x90, 0x68, 0x0b, 0x4b, 0x73, 0xe3, 0x32, + 0x65, 0xf5, 0x05, 0xf5, 0x36, 0x97, 0x46, 0x97, 0xf6, 0xe6, 0x36, 0x41, + 0x58, 0xba, 0x09, 0xc2, 0xc2, 0x6d, 0x08, 0x88, 0x09, 0xc2, 0xb2, 0x4d, + 0x10, 0x16, 0x6d, 0xc3, 0x42, 0x88, 0xc2, 0x28, 0x90, 0x42, 0x29, 0x98, + 0xc2, 0x60, 0x0a, 0xc4, 0x29, 0x00, 0x44, 0xa8, 0x8a, 0xb0, 0x86, 0x9e, + 0x9e, 0xa4, 0x88, 0x26, 0x08, 0x4b, 0xb6, 0x41, 0xd8, 0xb6, 0x0d, 0xcb, + 0x90, 0x0a, 0xa3, 0x70, 0x0a, 0xa5, 0xa0, 0x0a, 0x83, 0x2a, 0x0c, 0xa7, + 0xb0, 0x0a, 0x2c, 0x86, 0x9e, 0x98, 0x9e, 0xa4, 0x26, 0x08, 0xc2, 0xb5, + 0x41, 0xd8, 0x5c, 0x61, 0xc3, 0xc2, 0xb4, 0xc2, 0x28, 0x9c, 0x42, 0x29, + 0xa8, 0xc2, 0x60, 0x0a, 0xcc, 0x29, 0xbc, 0xc2, 0x86, 0x01, 0x15, 0x58, + 0x01, 0x16, 0x98, 0x4c, 0x59, 0x7d, 0x51, 0x85, 0xc9, 0x9d, 0x95, 0xd1, + 0x4d, 0x10, 0x96, 0x64, 0xc3, 0x42, 0xc8, 0xc2, 0x28, 0xcc, 0x42, 0x29, + 0x9c, 0xc2, 0x60, 0x0a, 0xc4, 0x29, 0xbc, 0xc2, 0x86, 0x80, 0x16, 0x36, + 0x0c, 0xb1, 0x50, 0x0b, 0xc0, 0x86, 0x42, 0x0f, 0x42, 0xc1, 0x16, 0x2e, + 0x80, 0x86, 0x19, 0xdb, 0x5b, 0x18, 0xdd, 0x1c, 0x8b, 0x34, 0xb7, 0x39, + 0xba, 0xb9, 0x09, 0x82, 0x80, 0xd1, 0x98, 0x4b, 0x3b, 0xfb, 0x62, 0x23, + 0xa3, 0x31, 0x97, 0x76, 0xf6, 0x35, 0x47, 0x47, 0x84, 0xae, 0x0c, 0xef, + 0xcb, 0xed, 0x4d, 0xae, 0x6d, 0x83, 0x82, 0x0b, 0x4d, 0x2e, 0xe8, 0xc2, + 0x2e, 0x20, 0xbc, 0x70, 0x06, 0xbd, 0xc0, 0x54, 0x61, 0x63, 0xb3, 0x6b, + 0x73, 0x49, 0x23, 0x2b, 0x73, 0xa3, 0x9b, 0x12, 0x04, 0x55, 0xc8, 0xf0, + 0x5c, 0xec, 0xca, 0xe4, 0xe6, 0xd2, 0xde, 0xdc, 0xa6, 0x04, 0x44, 0x13, + 0x32, 0x3c, 0x17, 0xbb, 0x30, 0x36, 0xbb, 0x32, 0xb9, 0x29, 0x41, 0x51, + 0x87, 0x0c, 0xcf, 0x65, 0x0e, 0x2d, 0x8c, 0xac, 0x4c, 0xae, 0xe9, 0x8d, + 0xac, 0x8c, 0x6d, 0x4a, 0x80, 0x94, 0x21, 0xc3, 0x73, 0x91, 0x2b, 0x9b, + 0x7b, 0xab, 0x93, 0x1b, 0x2b, 0x9b, 0x9b, 0x12, 0x58, 0x95, 0xc8, 0xf0, + 0x5c, 0xe8, 0xf2, 0xe0, 0xca, 0x82, 0xdc, 0xdc, 0xde, 0xe8, 0xc2, 0xe8, + 0xd2, 0xde, 0xdc, 0xe6, 0xa6, 0x08, 0x78, 0xd0, 0x07, 0x75, 0xc8, 0xf0, + 0x5c, 0xec, 0xd2, 0xca, 0xee, 0x92, 0xc8, 0xa6, 0xe8, 0xc2, 0xe8, 0xca, + 0xa6, 0x04, 0x7f, 0x50, 0x87, 0x0c, 0xcf, 0xa5, 0xcc, 0x8d, 0x4e, 0x2e, + 0x0f, 0xea, 0x2d, 0xcd, 0x8d, 0x6e, 0x6e, 0x4a, 0x60, 0x0b, 0x5d, 0xc8, + 0xf0, 0x5c, 0xc6, 0xde, 0xea, 0xdc, 0xe8, 0xca, 0xe4, 0xe6, 0xa6, 0x04, + 0xbd, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x4c, 0x00, 0x00, + 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, + 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, + 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, + 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, + 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, + 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, + 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, + 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, + 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, + 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, + 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, + 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, + 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, + 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, + 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, + 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, + 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, + 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, + 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, + 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, + 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, + 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, + 0xc4, 0x21, 0x07, 0x7c, 0x70, 0x03, 0x7a, 0x28, 0x87, 0x76, 0x80, 0x87, + 0x19, 0xd1, 0x43, 0x0e, 0xf8, 0xe0, 0x06, 0xe4, 0x20, 0x0e, 0xe7, 0xe0, + 0x06, 0xf6, 0x10, 0x0e, 0xf2, 0xc0, 0x0e, 0xe1, 0x90, 0x0f, 0xef, 0x50, + 0x0f, 0xf4, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x33, 0x00, 0x00, + 0x00, 0x25, 0xf0, 0x05, 0x7e, 0x74, 0x74, 0x79, 0x1a, 0x6e, 0xc3, 0xd9, + 0x65, 0x39, 0x10, 0x38, 0xab, 0x4e, 0xc3, 0x6d, 0x38, 0xbb, 0x2c, 0x9f, + 0xd2, 0xc3, 0xf4, 0x32, 0x10, 0x18, 0xac, 0x80, 0x38, 0x08, 0xfc, 0xe8, + 0xe8, 0x32, 0xb5, 0x8c, 0xa7, 0xd7, 0xe5, 0xe5, 0xaa, 0x15, 0x08, 0x9c, + 0x59, 0x7f, 0x24, 0x6a, 0x19, 0x4f, 0xaf, 0xcb, 0xcb, 0x32, 0x22, 0xd0, + 0xfa, 0x23, 0xd9, 0xcb, 0x63, 0xfa, 0x5b, 0x0e, 0x6c, 0x92, 0x60, 0x33, + 0x20, 0x10, 0x08, 0x0c, 0x16, 0x00, 0x1c, 0x04, 0x7e, 0x74, 0x74, 0x99, + 0x5a, 0xc6, 0xd3, 0xeb, 0xf2, 0x72, 0x16, 0x08, 0x9c, 0x59, 0x7f, 0x24, + 0x6a, 0x19, 0x4f, 0xaf, 0xcb, 0xcb, 0x32, 0x22, 0xd0, 0xfa, 0x23, 0xd9, + 0xcb, 0x63, 0xfa, 0x5b, 0x0e, 0x6c, 0x92, 0x60, 0x33, 0x20, 0x10, 0x08, + 0x0c, 0x1a, 0x82, 0x34, 0x5c, 0xbe, 0xf3, 0xf8, 0x42, 0x44, 0x00, 0x13, + 0x11, 0x02, 0xcd, 0xb0, 0x10, 0x76, 0xe0, 0x0c, 0x97, 0xef, 0x3c, 0xfe, + 0xe0, 0x4c, 0xb7, 0x5f, 0xdc, 0xb6, 0x11, 0x4c, 0xc3, 0xe5, 0x3b, 0x8f, + 0xbf, 0x38, 0xc0, 0x20, 0x36, 0x0f, 0x35, 0xf9, 0xc5, 0x6d, 0x9b, 0x01, + 0x34, 0x5c, 0xbe, 0xf3, 0xf8, 0x12, 0xc0, 0x3c, 0x0b, 0xe1, 0x17, 0xb7, + 0x6d, 0x05, 0xd5, 0x70, 0xf9, 0xce, 0xe3, 0x4b, 0x93, 0x13, 0x11, 0x28, + 0x35, 0x3d, 0xd4, 0xe4, 0x17, 0xb7, 0x6d, 0x03, 0x04, 0x03, 0x20, 0x0d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x14, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x6a, 0x46, 0xfe, 0xd5, 0x21, 0x7d, + 0xa1, 0xb7, 0x81, 0xb9, 0x35, 0xf9, 0x0f, 0x28, 0x1d, 0x44, 0x58, 0x49, + 0x4c, 0xb0, 0x07, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xec, 0x01, 0x00, + 0x00, 0x44, 0x58, 0x49, 0x4c, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x98, 0x07, 0x00, 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, + 0x00, 0xe3, 0x01, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, + 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, + 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, + 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, + 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, + 0x42, 0xe4, 0x48, 0x0e, 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, + 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, + 0x07, 0x40, 0x02, 0xa8, 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, + 0x20, 0x6d, 0x30, 0x86, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x09, 0xa8, + 0x00, 0x49, 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, + 0x42, 0x20, 0x4c, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, + 0x00, 0x45, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, + 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, + 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x70, 0x23, + 0x00, 0x25, 0x00, 0x14, 0x66, 0x00, 0xe6, 0x08, 0xc0, 0x60, 0x8e, 0x00, + 0x29, 0xc6, 0x20, 0x84, 0x14, 0x42, 0xa6, 0x18, 0x80, 0x10, 0x52, 0x06, + 0xa1, 0x9b, 0x86, 0xcb, 0x9f, 0xb0, 0x87, 0x90, 0xfc, 0x95, 0x90, 0x56, + 0x62, 0xf2, 0x8b, 0xdb, 0x46, 0xc5, 0x18, 0x63, 0x10, 0x2a, 0xf7, 0x0c, + 0x97, 0x3f, 0x61, 0x0f, 0x21, 0xf9, 0x21, 0xd0, 0x0c, 0x0b, 0x81, 0x82, + 0x55, 0x18, 0x45, 0x18, 0x1b, 0x63, 0x0c, 0x42, 0xc8, 0xa0, 0x56, 0x90, + 0x41, 0xc6, 0x18, 0x63, 0x0c, 0x7a, 0x73, 0x04, 0x41, 0x31, 0x18, 0x29, + 0x84, 0x44, 0x92, 0x03, 0x01, 0xc3, 0x08, 0xc4, 0x30, 0x53, 0x1b, 0x8c, + 0x03, 0x3b, 0x84, 0xc3, 0x3c, 0xcc, 0x83, 0x1b, 0xd0, 0x42, 0x39, 0xe0, + 0x03, 0x3d, 0xd4, 0x83, 0x3c, 0x94, 0x83, 0x1c, 0x90, 0x02, 0x1f, 0xd8, + 0x43, 0x39, 0x8c, 0x03, 0x3d, 0xbc, 0x83, 0x3c, 0xf0, 0x81, 0x39, 0xb0, + 0xc3, 0x3b, 0x84, 0x03, 0x3d, 0xb0, 0x01, 0x18, 0xd0, 0x81, 0x1f, 0x80, + 0x81, 0x1f, 0xe8, 0x81, 0x1e, 0xb4, 0x43, 0x3a, 0xc0, 0xc3, 0x3c, 0xfc, + 0x02, 0x3d, 0xe4, 0x03, 0x3c, 0x94, 0x03, 0x0a, 0xc8, 0x4c, 0x62, 0x30, + 0x0e, 0xec, 0x10, 0x0e, 0xf3, 0x30, 0x0f, 0x6e, 0x40, 0x0b, 0xe5, 0x80, + 0x0f, 0xf4, 0x50, 0x0f, 0xf2, 0x50, 0x0e, 0x72, 0x40, 0x0a, 0x7c, 0x60, + 0x0f, 0xe5, 0x30, 0x0e, 0xf4, 0xf0, 0x0e, 0xf2, 0xc0, 0x07, 0xe6, 0xc0, + 0x0e, 0xef, 0x10, 0x0e, 0xf4, 0xc0, 0x06, 0x60, 0x40, 0x07, 0x7e, 0x00, + 0x06, 0x7e, 0x80, 0x84, 0x6a, 0xe9, 0xde, 0x24, 0x4d, 0x11, 0x25, 0x4c, + 0x3e, 0x0b, 0x30, 0xcf, 0x42, 0x44, 0xec, 0x04, 0x4c, 0x04, 0x0a, 0x08, + 0xe5, 0x74, 0x20, 0x00, 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, + 0x87, 0x36, 0x68, 0x87, 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, + 0x50, 0x0e, 0x6d, 0xd0, 0x0e, 0x7a, 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, + 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, + 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, + 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, + 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, + 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, + 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, + 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, + 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x43, + 0x9e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x86, 0x3c, 0x06, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x79, 0x10, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0xf2, 0x34, 0x40, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x30, 0xe4, 0x79, 0x80, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x60, 0xc8, 0x23, 0x01, 0x01, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x16, 0x08, 0x00, 0x0f, 0x00, 0x00, + 0x00, 0x32, 0x1e, 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, + 0x47, 0xc6, 0x04, 0x43, 0x22, 0x25, 0x30, 0x02, 0x50, 0x0c, 0x45, 0x50, + 0x12, 0x65, 0x50, 0x1e, 0x54, 0x4a, 0xa2, 0x0c, 0x0a, 0x61, 0x04, 0xa0, + 0x08, 0x0a, 0x84, 0xf0, 0x0c, 0x00, 0xe9, 0x19, 0x00, 0xda, 0x63, 0x39, + 0x0c, 0x01, 0x00, 0x00, 0x70, 0x1c, 0x00, 0x10, 0x08, 0x04, 0x02, 0x00, + 0x00, 0x79, 0x18, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, + 0x90, 0x46, 0x02, 0x13, 0x44, 0x35, 0x18, 0x63, 0x0b, 0x73, 0x3b, 0x03, + 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x03, 0x99, 0x71, 0xb9, 0x01, + 0x41, 0xa1, 0x0b, 0x3b, 0x9b, 0x7b, 0x91, 0x2a, 0x62, 0x2a, 0x0a, 0x9a, + 0x2a, 0xfa, 0x9a, 0xb9, 0x81, 0x79, 0x31, 0x4b, 0x73, 0x0b, 0x63, 0x4b, + 0xd9, 0x10, 0x04, 0x13, 0x04, 0xc2, 0x98, 0x20, 0x10, 0xc7, 0x06, 0x61, + 0x20, 0x26, 0x08, 0x04, 0xb2, 0x41, 0x18, 0x0c, 0x0a, 0x70, 0x73, 0x1b, + 0x06, 0xc4, 0x20, 0x26, 0x08, 0xd8, 0x44, 0x60, 0x82, 0x40, 0x24, 0x13, + 0x04, 0x42, 0xd9, 0x20, 0x10, 0xcd, 0x86, 0x84, 0x50, 0x16, 0x82, 0x18, + 0x18, 0xc2, 0xd9, 0x90, 0x0c, 0xca, 0x42, 0x0c, 0x03, 0x43, 0x38, 0x1b, + 0x84, 0x07, 0x9a, 0x20, 0x68, 0xd4, 0x06, 0x84, 0x90, 0x16, 0x82, 0x18, + 0x08, 0x60, 0x43, 0x30, 0x6d, 0x20, 0x22, 0x00, 0xa0, 0x26, 0x08, 0x5b, + 0xb5, 0x21, 0xb0, 0x26, 0x08, 0x02, 0x40, 0xa2, 0x2d, 0x2c, 0xcd, 0x8d, + 0xcb, 0x94, 0xd5, 0x17, 0xd4, 0xdb, 0x5c, 0x1a, 0x5d, 0xda, 0x9b, 0xdb, + 0x04, 0xa1, 0x68, 0x26, 0x08, 0x85, 0xb3, 0x21, 0x20, 0x26, 0x08, 0xc5, + 0x33, 0x41, 0x28, 0xa0, 0x0d, 0x0b, 0xa1, 0x6d, 0x5c, 0xe7, 0x0d, 0x1e, + 0xf1, 0x01, 0x44, 0xa8, 0x8a, 0xb0, 0x86, 0x9e, 0x9e, 0xa4, 0x88, 0x26, + 0x08, 0x45, 0x34, 0x41, 0x20, 0x96, 0x0d, 0xc2, 0x18, 0x8c, 0xc1, 0x86, + 0x65, 0x08, 0x83, 0xed, 0xeb, 0xc4, 0x60, 0x10, 0x83, 0xe1, 0x23, 0x03, + 0x16, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x13, 0x04, 0x82, 0xd9, 0x20, 0x8c, + 0xc1, 0x19, 0x6c, 0x58, 0x18, 0x33, 0xd8, 0xbe, 0x4e, 0x0c, 0x06, 0x8f, + 0xf9, 0xd0, 0x60, 0xc3, 0x00, 0x06, 0x65, 0x90, 0x06, 0x4c, 0xa6, 0xac, + 0xbe, 0xa8, 0xc2, 0xe4, 0xce, 0xca, 0xe8, 0x26, 0x08, 0x85, 0xb4, 0x61, + 0x21, 0xd6, 0x60, 0x63, 0x83, 0xee, 0x1b, 0x3c, 0xe2, 0x43, 0x83, 0x0d, + 0x41, 0x1b, 0x6c, 0x18, 0xd4, 0xc0, 0x0d, 0x80, 0x0d, 0x05, 0x96, 0xbd, + 0x41, 0x05, 0x54, 0x61, 0x63, 0xb3, 0x6b, 0x73, 0x49, 0x23, 0x2b, 0x73, + 0xa3, 0x9b, 0x12, 0x04, 0x55, 0xc8, 0xf0, 0x5c, 0xec, 0xca, 0xe4, 0xe6, + 0xd2, 0xde, 0xdc, 0xa6, 0x04, 0x44, 0x13, 0x32, 0x3c, 0x17, 0xbb, 0x30, + 0x36, 0xbb, 0x32, 0xb9, 0x29, 0x81, 0x51, 0x87, 0x0c, 0xcf, 0x65, 0x0e, + 0x2d, 0x8c, 0xac, 0x4c, 0xae, 0xe9, 0x8d, 0xac, 0x8c, 0x6d, 0x4a, 0x80, + 0x94, 0x21, 0xc3, 0x73, 0x91, 0x2b, 0x9b, 0x7b, 0xab, 0x93, 0x1b, 0x2b, + 0x9b, 0x9b, 0x12, 0x50, 0x75, 0xc8, 0xf0, 0x5c, 0xec, 0xd2, 0xca, 0xee, + 0x92, 0xc8, 0xa6, 0xe8, 0xc2, 0xe8, 0xca, 0xa6, 0x04, 0x56, 0x1d, 0x32, + 0x3c, 0x97, 0x32, 0x37, 0x3a, 0xb9, 0x3c, 0xa8, 0xb7, 0x34, 0x37, 0xba, + 0xb9, 0x29, 0xc1, 0x1b, 0x00, 0x79, 0x18, 0x00, 0x00, 0x4c, 0x00, 0x00, + 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, + 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, + 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, + 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, + 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, + 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, + 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, + 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, + 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, + 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, + 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, + 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, + 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, + 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, + 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, + 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, + 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, + 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, + 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, + 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, + 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, + 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, + 0xc4, 0x21, 0x07, 0x7c, 0x70, 0x03, 0x7a, 0x28, 0x87, 0x76, 0x80, 0x87, + 0x19, 0xd1, 0x43, 0x0e, 0xf8, 0xe0, 0x06, 0xe4, 0x20, 0x0e, 0xe7, 0xe0, + 0x06, 0xf6, 0x10, 0x0e, 0xf2, 0xc0, 0x0e, 0xe1, 0x90, 0x0f, 0xef, 0x50, + 0x0f, 0xf4, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x15, 0x00, 0x00, + 0x00, 0x56, 0x20, 0x0d, 0x97, 0xef, 0x3c, 0xbe, 0x10, 0x11, 0xc0, 0x44, + 0x84, 0x40, 0x33, 0x2c, 0x84, 0x11, 0x38, 0xc3, 0xe5, 0x3b, 0x8f, 0x3f, + 0x38, 0xd3, 0xed, 0x17, 0xb7, 0x6d, 0x01, 0xd3, 0x70, 0xf9, 0xce, 0xe3, + 0x2f, 0x0e, 0x30, 0x88, 0xcd, 0x43, 0x4d, 0x7e, 0x71, 0xdb, 0x36, 0x00, + 0x0d, 0x97, 0xef, 0x3c, 0xbe, 0x04, 0x30, 0xcf, 0x42, 0xf8, 0xc5, 0x6d, + 0x9b, 0x40, 0x35, 0x5c, 0xbe, 0xf3, 0xf8, 0xd2, 0xe4, 0x44, 0x04, 0x4a, + 0x4d, 0x0f, 0x35, 0xf9, 0xc5, 0x6d, 0x1b, 0x00, 0xc1, 0x00, 0x48, 0x03, + 0x00, 0x61, 0x20, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, + 0x2c, 0x10, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x47, 0x00, + 0xa8, 0x94, 0x00, 0x91, 0xc2, 0x2b, 0xb7, 0x92, 0x2b, 0x85, 0x42, 0x98, + 0x01, 0xa0, 0x31, 0x46, 0xe0, 0xba, 0xa6, 0x08, 0x82, 0xc1, 0x18, 0x41, + 0x69, 0xa2, 0x60, 0xfd, 0x0b, 0x63, 0x04, 0x22, 0x6c, 0xc6, 0xec, 0x2f, + 0x8c, 0x11, 0xe8, 0xad, 0x8c, 0xf3, 0xdf, 0x18, 0x41, 0x48, 0x82, 0x21, + 0xee, 0x0b, 0x23, 0x00, 0x63, 0x04, 0x21, 0x09, 0x86, 0xf0, 0x2f, 0x8c, + 0x11, 0xbc, 0xb8, 0xa8, 0xe6, 0xdf, 0x0c, 0x00, 0x00, 0x23, 0x06, 0x09, + 0x00, 0x82, 0x60, 0x20, 0x89, 0x41, 0x73, 0x85, 0x41, 0x18, 0x44, 0x23, + 0x06, 0x09, 0x00, 0x82, 0x60, 0x20, 0x8d, 0x81, 0x83, 0x85, 0x41, 0x18, + 0x48, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x20, 0x91, 0xc1, 0xb3, 0x89, + 0x81, 0x18, 0x4c, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x60, 0xa4, 0x81, + 0x13, 0x06, 0x63, 0xa0, 0x35, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x60, + 0xa8, 0xc1, 0x23, 0x06, 0x64, 0x40, 0x39, 0x23, 0x06, 0x09, 0x00, 0x82, + 0x60, 0x60, 0xac, 0x01, 0x34, 0x06, 0x65, 0xb0, 0x3d, 0x23, 0x06, 0x09, + 0x00, 0x82, 0x60, 0x60, 0xb0, 0x41, 0x44, 0x06, 0x66, 0xf0, 0x41, 0x23, + 0x06, 0x09, 0x00, 0x82, 0x60, 0x60, 0xb4, 0x81, 0x84, 0x06, 0x67, 0xe0, + 0x45, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x60, 0xb8, 0xc1, 0x94, 0x06, + 0x68, 0x80, 0x49, 0x23, 0x06, 0x0f, 0x00, 0x82, 0x60, 0xd0, 0xb4, 0x01, + 0x86, 0x1c, 0x42, 0xa0, 0x28, 0x69, 0x90, 0x06, 0x93, 0x32, 0x9a, 0x10, + 0x00, 0x23, 0x06, 0x0f, 0x00, 0x82, 0x60, 0xd0, 0xbc, 0x81, 0xb6, 0x24, + 0xc4, 0xc0, 0x30, 0x6b, 0xb0, 0x06, 0x15, 0x33, 0x9a, 0x10, 0x00, 0xa3, + 0x09, 0x42, 0x60, 0xc4, 0x04, 0x1f, 0x13, 0x24, 0xf8, 0x18, 0x31, 0xc1, + 0x67, 0xc4, 0x60, 0x01, 0x40, 0x10, 0x0c, 0x1e, 0x3a, 0xf8, 0x06, 0x21, + 0x98, 0xaa, 0x6b, 0xc4, 0x60, 0x01, 0x40, 0x10, 0x0c, 0x9e, 0x3a, 0x00, + 0x03, 0x62, 0x10, 0xa8, 0x4c, 0x1b, 0x31, 0x58, 0x00, 0x10, 0x04, 0x83, + 0xc7, 0x0e, 0xc2, 0xa0, 0x20, 0x86, 0x8a, 0xbb, 0x6c, 0x88, 0xe4, 0x63, + 0x43, 0x24, 0x1f, 0x1b, 0x22, 0xf9, 0x8c, 0x18, 0x24, 0x00, 0x08, 0x82, + 0x01, 0xc2, 0x07, 0x63, 0x70, 0x07, 0x77, 0xe0, 0x06, 0xc3, 0x88, 0x41, + 0x02, 0x80, 0x20, 0x18, 0x20, 0x7c, 0x30, 0x06, 0x77, 0x70, 0x07, 0x67, + 0x20, 0x8c, 0x18, 0x24, 0x00, 0x08, 0x82, 0x01, 0xc2, 0x07, 0x63, 0x70, + 0x07, 0x77, 0xd0, 0x06, 0xc1, 0x88, 0x41, 0x02, 0x80, 0x20, 0x18, 0x20, + 0x7c, 0x30, 0x06, 0x77, 0x70, 0x07, 0x70, 0x10, 0x21, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +/* The yuv-rendering pixel shader: + + --- D3D12_PixelShader_NV21_BT709.hlsl --- + Texture2D theTextureY : register(t0); + Texture2D theTextureUV : register(t1); + SamplerState theSampler : register(s0); + + struct PixelShaderInput + { + float4 pos : SV_POSITION; + float2 tex : TEXCOORD0; + float4 color : COLOR0; + }; + + #define NVRS \ + "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \ + " DENY_DOMAIN_SHADER_ROOT_ACCESS |" \ + " DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \ + " DENY_HULL_SHADER_ROOT_ACCESS )," \ + "RootConstants(num32BitConstants=32, b0),"\ + "DescriptorTable ( SRV(t0), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( SRV(t1), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( Sampler(s0), visibility = SHADER_VISIBILITY_PIXEL )" + + [RootSignature(NVRS)] + float4 main(PixelShaderInput input) : SV_TARGET + { + const float3 offset = {-0.0627451017, -0.501960814, -0.501960814}; + const float3 Rcoeff = {1.1644, 0.0000, 1.7927}; + const float3 Gcoeff = {1.1644, -0.2132, -0.5329}; + const float3 Bcoeff = {1.1644, 2.1124, 0.0000}; + + float4 Output; + + float3 yuv; + yuv.x = theTextureY.Sample(theSampler, input.tex).r; + yuv.yz = theTextureUV.Sample(theSampler, input.tex).gr; + + yuv += offset; + Output.r = dot(yuv, Rcoeff); + Output.g = dot(yuv, Gcoeff); + Output.b = dot(yuv, Bcoeff); + Output.a = 1.0f; + + return Output * input.color; + } + +*/ + +static unsigned char D3D12_PixelShader_NV21_BT709[] = { + 0x44, 0x58, 0x42, 0x43, 0x5c, 0x52, 0x50, 0xb3, 0x0c, 0x9c, 0x81, 0x8a, + 0x2d, 0x9e, 0x1b, 0x5d, 0x0b, 0xcb, 0x2a, 0xa0, 0x01, 0x00, 0x00, 0x00, + 0xe9, 0x12, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0xdb, 0x00, 0x00, 0x00, 0x15, 0x01, 0x00, 0x00, + 0x0d, 0x02, 0x00, 0x00, 0xc9, 0x02, 0x00, 0x00, 0x15, 0x0b, 0x00, 0x00, + 0x31, 0x0b, 0x00, 0x00, 0x53, 0x46, 0x49, 0x30, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31, + 0x83, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x53, 0x56, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, + 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x43, 0x4f, 0x4c, + 0x4f, 0x52, 0x00, 0x4f, 0x53, 0x47, 0x31, 0x32, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x00, 0x50, 0x53, 0x56, 0x30, 0xf0, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x03, 0x01, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x43, + 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x44, 0x03, 0x03, 0x04, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x42, 0x00, 0x03, 0x02, 0x00, + 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, + 0x00, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x44, 0x10, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x52, 0x54, 0x53, + 0x30, 0xb4, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, + 0x00, 0x1d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, + 0xff, 0x01, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, + 0x00, 0x9c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xff, 0xff, 0x53, 0x54, 0x41, 0x54, 0x44, 0x08, 0x00, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x11, 0x02, 0x00, 0x00, 0x44, 0x58, 0x49, + 0x4c, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x2c, 0x08, 0x00, + 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x08, 0x02, 0x00, + 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, + 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, + 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, + 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, + 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88, 0x48, 0x90, 0x14, + 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4, 0x48, 0x0e, + 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, + 0x8a, 0x04, 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40, 0x02, 0xa8, + 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x20, 0x6d, 0x30, 0x86, + 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x09, 0xa8, 0x00, 0x49, 0x18, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, 0x42, 0x20, 0x4c, 0x08, + 0x06, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x4b, 0x00, 0x00, + 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, + 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, + 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x78, 0x33, 0x00, 0xc3, 0x08, 0x04, + 0x30, 0x47, 0x00, 0x06, 0x33, 0xb5, 0xc1, 0x38, 0xb0, 0x43, 0x38, 0xcc, + 0xc3, 0x3c, 0xb8, 0x01, 0x2d, 0x94, 0x03, 0x3e, 0xd0, 0x43, 0x3d, 0xc8, + 0x43, 0x39, 0xc8, 0x01, 0x29, 0xf0, 0x81, 0x3d, 0x94, 0xc3, 0x38, 0xd0, + 0xc3, 0x3b, 0xc8, 0x03, 0x1f, 0x98, 0x03, 0x3b, 0xbc, 0x43, 0x38, 0xd0, + 0x03, 0x1b, 0x80, 0x01, 0x1d, 0xf8, 0x01, 0x18, 0xf8, 0x81, 0x1e, 0xe8, + 0x41, 0x3b, 0xa4, 0x03, 0x3c, 0xcc, 0xc3, 0x2f, 0xd0, 0x43, 0x3e, 0xc0, + 0x43, 0x39, 0xa0, 0x40, 0xcc, 0x24, 0x06, 0xe3, 0xc0, 0x0e, 0xe1, 0x30, + 0x0f, 0xf3, 0xe0, 0x06, 0xb4, 0x50, 0x0e, 0xf8, 0x40, 0x0f, 0xf5, 0x20, + 0x0f, 0xe5, 0x20, 0x07, 0xa4, 0xc0, 0x07, 0xf6, 0x50, 0x0e, 0xe3, 0x40, + 0x0f, 0xef, 0x20, 0x0f, 0x7c, 0x60, 0x0e, 0xec, 0xf0, 0x0e, 0xe1, 0x40, + 0x0f, 0x6c, 0x00, 0x06, 0x74, 0xe0, 0x07, 0x60, 0xe0, 0x07, 0x48, 0x08, + 0x83, 0xc8, 0x4d, 0xd2, 0x14, 0x51, 0xc2, 0xe4, 0xb3, 0x00, 0xf3, 0x2c, + 0x44, 0xc4, 0x4e, 0xc0, 0x44, 0xa0, 0x40, 0x90, 0x19, 0x01, 0x28, 0x01, + 0xa2, 0x34, 0x47, 0x80, 0x14, 0x03, 0x08, 0x21, 0x96, 0x20, 0x56, 0x0c, + 0x24, 0x84, 0x58, 0x80, 0xdc, 0x4d, 0xc3, 0xe5, 0x4f, 0xd8, 0x43, 0x48, + 0xfe, 0x4a, 0x48, 0x2b, 0x31, 0xf9, 0xc5, 0x6d, 0xa3, 0x02, 0x00, 0x00, + 0x04, 0xad, 0x7b, 0x86, 0xcb, 0x9f, 0xb0, 0x87, 0x90, 0xfc, 0x10, 0x68, + 0x86, 0x85, 0x40, 0x41, 0x2c, 0x0c, 0x14, 0x52, 0x02, 0x00, 0x80, 0x10, + 0x02, 0xd0, 0x2c, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0xd5, 0x39, 0x82, + 0xa0, 0x18, 0x52, 0x2c, 0x21, 0x2e, 0xe1, 0x81, 0x80, 0x61, 0x04, 0x01, + 0xb8, 0x4b, 0x9a, 0x22, 0x4a, 0x98, 0xfc, 0x14, 0xb9, 0x88, 0x85, 0x3d, + 0x80, 0x81, 0x88, 0xc4, 0xe6, 0xa1, 0x26, 0x34, 0x84, 0x1d, 0xd2, 0x41, + 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, + 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e, 0x6d, 0xd0, + 0x0e, 0x7a, 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, + 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, + 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, + 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x10, 0x07, 0x76, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x3a, 0x0f, 0x64, 0x90, 0x21, + 0x23, 0x45, 0x44, 0x00, 0x72, 0x00, 0xc0, 0xe4, 0x00, 0x80, 0xe9, 0x01, + 0x00, 0x0f, 0x79, 0x12, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0xf2, 0x30, 0x40, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x30, 0xe4, 0x71, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x60, 0xc8, 0x33, 0x01, 0x01, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x90, 0xa7, 0x02, 0x02, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x21, 0x0f, 0x06, 0x04, 0xc0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x20, 0x00, 0x00, + 0x00, 0x15, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x18, 0x19, 0x11, 0x4c, + 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x5a, 0x05, 0x42, 0xa2, + 0x04, 0x46, 0x00, 0x8a, 0xa1, 0x08, 0x4a, 0xa2, 0x50, 0xca, 0xa0, 0x1c, + 0x0a, 0xa4, 0x10, 0x4a, 0xa1, 0xc0, 0x0a, 0xa8, 0x3c, 0x0a, 0x87, 0x56, + 0x11, 0x8c, 0x00, 0x14, 0x42, 0x19, 0x94, 0x04, 0x9d, 0x19, 0x00, 0x2a, + 0x33, 0x00, 0x44, 0x66, 0x00, 0x68, 0xcc, 0x00, 0x50, 0x98, 0x01, 0x20, + 0x3e, 0x03, 0x40, 0x7d, 0x2c, 0x87, 0x21, 0x00, 0x00, 0x00, 0x8e, 0x03, + 0x00, 0x02, 0x81, 0x40, 0x00, 0x79, 0x18, 0x00, 0x00, 0xbe, 0x00, 0x00, + 0x00, 0x1a, 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, 0x44, 0x35, 0x18, 0x63, + 0x0b, 0x73, 0x3b, 0x03, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x03, + 0x99, 0x71, 0xb9, 0x01, 0x41, 0xa1, 0x0b, 0x3b, 0x9b, 0x7b, 0x91, 0x2a, + 0x62, 0x2a, 0x0a, 0x9a, 0x2a, 0xfa, 0x9a, 0xb9, 0x81, 0x79, 0x31, 0x4b, + 0x73, 0x0b, 0x63, 0x4b, 0xd9, 0x10, 0x04, 0x13, 0x04, 0x41, 0x99, 0x20, + 0x08, 0xcb, 0x06, 0x61, 0x20, 0x36, 0x08, 0x04, 0x41, 0x01, 0x6e, 0x6e, + 0x82, 0x20, 0x30, 0x1b, 0x86, 0x03, 0x21, 0x26, 0x08, 0xc5, 0xc7, 0x85, + 0x0e, 0xad, 0x8c, 0xaa, 0x0c, 0x8f, 0xae, 0x4e, 0xae, 0x2c, 0x6b, 0x82, + 0x20, 0x34, 0x13, 0x04, 0xc1, 0xd9, 0x20, 0x10, 0xcd, 0x86, 0x84, 0x50, + 0x16, 0x82, 0x18, 0x18, 0xc2, 0x21, 0x43, 0x87, 0x56, 0x46, 0x55, 0x86, + 0x47, 0x57, 0x27, 0x57, 0x56, 0x65, 0xb5, 0x21, 0x19, 0x14, 0x88, 0x18, + 0x06, 0x86, 0x70, 0x36, 0x08, 0x4f, 0x34, 0x41, 0x38, 0x3c, 0x2a, 0x74, + 0x68, 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x1b, 0x10, 0x62, + 0xa2, 0x08, 0x62, 0x20, 0x80, 0x0d, 0x41, 0xb5, 0x81, 0x90, 0x00, 0xc0, + 0x9a, 0x20, 0x10, 0x60, 0x30, 0x41, 0x10, 0x1e, 0x06, 0x68, 0x13, 0x04, + 0x01, 0x9a, 0x20, 0x08, 0xd1, 0x06, 0x03, 0xd1, 0x36, 0x82, 0x6b, 0x48, + 0xb4, 0xa5, 0xc1, 0xcd, 0x4d, 0x10, 0x04, 0x69, 0x03, 0x81, 0x78, 0xdb, + 0x37, 0x41, 0x08, 0xc4, 0x60, 0x83, 0x40, 0x84, 0xc1, 0x86, 0x40, 0x0c, + 0x36, 0x08, 0xc4, 0x18, 0x6c, 0x20, 0xb2, 0x0e, 0x0c, 0xc8, 0x60, 0x82, + 0x30, 0x84, 0xc1, 0x04, 0x41, 0x98, 0x68, 0xa0, 0x85, 0xb9, 0x91, 0xb1, + 0x95, 0x4d, 0x10, 0x04, 0x6a, 0x83, 0x81, 0xa0, 0xc1, 0x46, 0x70, 0x69, + 0xb0, 0x41, 0x38, 0x03, 0x35, 0x98, 0x20, 0x70, 0x63, 0x30, 0x41, 0x10, + 0x2a, 0x0e, 0x70, 0x6f, 0x73, 0x5c, 0xa6, 0xac, 0xbe, 0xa0, 0x9e, 0xa6, + 0x92, 0xa8, 0x92, 0x9e, 0x9c, 0x36, 0x20, 0x88, 0x1b, 0x6c, 0xc4, 0x19, + 0xbc, 0x01, 0xd7, 0x70, 0xa0, 0x2b, 0xc3, 0x63, 0x42, 0x55, 0x84, 0x35, + 0xf4, 0xf4, 0x24, 0x45, 0x04, 0xb3, 0x01, 0x41, 0xe2, 0x60, 0xfb, 0xce, + 0x40, 0x0e, 0xb8, 0x86, 0xc5, 0xd8, 0x1b, 0xdb, 0x9b, 0xdc, 0x04, 0x41, + 0xb0, 0x68, 0x0c, 0x3d, 0x31, 0x3d, 0x49, 0xc1, 0x6c, 0x40, 0x10, 0x3a, + 0xd8, 0xea, 0xe0, 0x0c, 0xec, 0x80, 0x6b, 0x36, 0x10, 0x6d, 0x00, 0x07, + 0x73, 0x70, 0x07, 0x1b, 0x0e, 0x02, 0x2b, 0x03, 0x33, 0x58, 0x03, 0x36, + 0xc0, 0x83, 0x09, 0x82, 0x32, 0x6c, 0x00, 0x36, 0x0c, 0xc4, 0x1e, 0xec, + 0xc1, 0x86, 0x80, 0x0f, 0x36, 0x0c, 0x83, 0x1e, 0xf4, 0xc1, 0x04, 0xa1, + 0x23, 0x83, 0x0d, 0xc1, 0x1f, 0x90, 0x68, 0x0b, 0x4b, 0x73, 0xe3, 0x32, + 0x65, 0xf5, 0x05, 0xf5, 0x36, 0x97, 0x46, 0x97, 0xf6, 0xe6, 0x36, 0x41, + 0x58, 0xba, 0x09, 0xc2, 0xc2, 0x6d, 0x08, 0x88, 0x09, 0xc2, 0xb2, 0x4d, + 0x10, 0x16, 0x6d, 0xc3, 0x42, 0x88, 0xc2, 0x28, 0x90, 0x42, 0x29, 0x98, + 0xc2, 0x60, 0x0a, 0xc4, 0x29, 0x00, 0x44, 0xa8, 0x8a, 0xb0, 0x86, 0x9e, + 0x9e, 0xa4, 0x88, 0x26, 0x08, 0x4b, 0xb6, 0x41, 0xd8, 0xb6, 0x0d, 0xcb, + 0x90, 0x0a, 0xa3, 0x70, 0x0a, 0xa5, 0xa0, 0x0a, 0x83, 0x2a, 0x0c, 0xa7, + 0xb0, 0x0a, 0x2c, 0x86, 0x9e, 0x98, 0x9e, 0xa4, 0x26, 0x08, 0xc2, 0xb5, + 0x41, 0xd8, 0x5c, 0x61, 0xc3, 0xc2, 0xb4, 0xc2, 0x28, 0x9c, 0x42, 0x29, + 0xa8, 0xc2, 0x60, 0x0a, 0xcc, 0x29, 0xbc, 0xc2, 0x86, 0x01, 0x15, 0x58, + 0x01, 0x16, 0x98, 0x4c, 0x59, 0x7d, 0x51, 0x85, 0xc9, 0x9d, 0x95, 0xd1, + 0x4d, 0x10, 0x96, 0x64, 0xc3, 0x42, 0xc8, 0xc2, 0x28, 0xcc, 0x42, 0x29, + 0x9c, 0xc2, 0x60, 0x0a, 0xc4, 0x29, 0xbc, 0xc2, 0x86, 0x80, 0x16, 0x36, + 0x0c, 0xb1, 0x50, 0x0b, 0xc0, 0x86, 0x42, 0x0f, 0x42, 0xc1, 0x16, 0x2e, + 0x80, 0x86, 0x19, 0xdb, 0x5b, 0x18, 0xdd, 0x1c, 0x8b, 0x34, 0xb7, 0x39, + 0xba, 0xb9, 0x09, 0x82, 0x80, 0xd1, 0x98, 0x4b, 0x3b, 0xfb, 0x62, 0x23, + 0xa3, 0x31, 0x97, 0x76, 0xf6, 0x35, 0x47, 0x47, 0x84, 0xae, 0x0c, 0xef, + 0xcb, 0xed, 0x4d, 0xae, 0x6d, 0x83, 0x82, 0x0b, 0x4d, 0x2e, 0xe8, 0xc2, + 0x2e, 0x20, 0xbc, 0x70, 0x06, 0xbd, 0xc0, 0x54, 0x61, 0x63, 0xb3, 0x6b, + 0x73, 0x49, 0x23, 0x2b, 0x73, 0xa3, 0x9b, 0x12, 0x04, 0x55, 0xc8, 0xf0, + 0x5c, 0xec, 0xca, 0xe4, 0xe6, 0xd2, 0xde, 0xdc, 0xa6, 0x04, 0x44, 0x13, + 0x32, 0x3c, 0x17, 0xbb, 0x30, 0x36, 0xbb, 0x32, 0xb9, 0x29, 0x41, 0x51, + 0x87, 0x0c, 0xcf, 0x65, 0x0e, 0x2d, 0x8c, 0xac, 0x4c, 0xae, 0xe9, 0x8d, + 0xac, 0x8c, 0x6d, 0x4a, 0x80, 0x94, 0x21, 0xc3, 0x73, 0x91, 0x2b, 0x9b, + 0x7b, 0xab, 0x93, 0x1b, 0x2b, 0x9b, 0x9b, 0x12, 0x58, 0x95, 0xc8, 0xf0, + 0x5c, 0xe8, 0xf2, 0xe0, 0xca, 0x82, 0xdc, 0xdc, 0xde, 0xe8, 0xc2, 0xe8, + 0xd2, 0xde, 0xdc, 0xe6, 0xa6, 0x08, 0x78, 0xd0, 0x07, 0x75, 0xc8, 0xf0, + 0x5c, 0xec, 0xd2, 0xca, 0xee, 0x92, 0xc8, 0xa6, 0xe8, 0xc2, 0xe8, 0xca, + 0xa6, 0x04, 0x7f, 0x50, 0x87, 0x0c, 0xcf, 0xa5, 0xcc, 0x8d, 0x4e, 0x2e, + 0x0f, 0xea, 0x2d, 0xcd, 0x8d, 0x6e, 0x6e, 0x4a, 0x60, 0x0b, 0x5d, 0xc8, + 0xf0, 0x5c, 0xc6, 0xde, 0xea, 0xdc, 0xe8, 0xca, 0xe4, 0xe6, 0xa6, 0x04, + 0xbd, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x4c, 0x00, 0x00, + 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, + 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, + 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, + 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, + 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, + 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, + 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, + 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, + 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, + 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, + 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, + 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, + 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, + 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, + 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, + 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, + 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, + 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, + 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, + 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, + 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, + 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, + 0xc4, 0x21, 0x07, 0x7c, 0x70, 0x03, 0x7a, 0x28, 0x87, 0x76, 0x80, 0x87, + 0x19, 0xd1, 0x43, 0x0e, 0xf8, 0xe0, 0x06, 0xe4, 0x20, 0x0e, 0xe7, 0xe0, + 0x06, 0xf6, 0x10, 0x0e, 0xf2, 0xc0, 0x0e, 0xe1, 0x90, 0x0f, 0xef, 0x50, + 0x0f, 0xf4, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x33, 0x00, 0x00, + 0x00, 0x25, 0xf0, 0x05, 0x7e, 0x74, 0x74, 0x79, 0x1a, 0x6e, 0xc3, 0xd9, + 0x65, 0x39, 0x10, 0x38, 0xab, 0x4e, 0xc3, 0x6d, 0x38, 0xbb, 0x2c, 0x9f, + 0xd2, 0xc3, 0xf4, 0x32, 0x10, 0x18, 0xac, 0x80, 0x38, 0x08, 0xfc, 0xe8, + 0xe8, 0x32, 0xb5, 0x8c, 0xa7, 0xd7, 0xe5, 0xe5, 0xaa, 0x15, 0x08, 0x9c, + 0x59, 0x7f, 0x24, 0x6a, 0x19, 0x4f, 0xaf, 0xcb, 0xcb, 0x32, 0x22, 0xd0, + 0xfa, 0x23, 0xd9, 0xcb, 0x63, 0xfa, 0x5b, 0x0e, 0x6c, 0x92, 0x60, 0x33, + 0x20, 0x10, 0x08, 0x0c, 0x16, 0x00, 0x1c, 0x04, 0x7e, 0x74, 0x74, 0x99, + 0x5a, 0xc6, 0xd3, 0xeb, 0xf2, 0x72, 0x16, 0x08, 0x9c, 0x59, 0x7f, 0x24, + 0x6a, 0x19, 0x4f, 0xaf, 0xcb, 0xcb, 0x32, 0x22, 0xd0, 0xfa, 0x23, 0xd9, + 0xcb, 0x63, 0xfa, 0x5b, 0x0e, 0x6c, 0x92, 0x60, 0x33, 0x20, 0x10, 0x08, + 0x0c, 0x1a, 0x82, 0x34, 0x5c, 0xbe, 0xf3, 0xf8, 0x42, 0x44, 0x00, 0x13, + 0x11, 0x02, 0xcd, 0xb0, 0x10, 0x76, 0xe0, 0x0c, 0x97, 0xef, 0x3c, 0xfe, + 0xe0, 0x4c, 0xb7, 0x5f, 0xdc, 0xb6, 0x11, 0x4c, 0xc3, 0xe5, 0x3b, 0x8f, + 0xbf, 0x38, 0xc0, 0x20, 0x36, 0x0f, 0x35, 0xf9, 0xc5, 0x6d, 0x9b, 0x01, + 0x34, 0x5c, 0xbe, 0xf3, 0xf8, 0x12, 0xc0, 0x3c, 0x0b, 0xe1, 0x17, 0xb7, + 0x6d, 0x05, 0xd5, 0x70, 0xf9, 0xce, 0xe3, 0x4b, 0x93, 0x13, 0x11, 0x28, + 0x35, 0x3d, 0xd4, 0xe4, 0x17, 0xb7, 0x6d, 0x03, 0x04, 0x03, 0x20, 0x0d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x14, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x33, 0x44, 0x4f, 0x49, 0x10, 0x21, + 0xcb, 0x08, 0xc8, 0x3e, 0x2d, 0x19, 0x9c, 0x34, 0xa7, 0x44, 0x58, 0x49, + 0x4c, 0xb0, 0x07, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0xec, 0x01, 0x00, + 0x00, 0x44, 0x58, 0x49, 0x4c, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x98, 0x07, 0x00, 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, + 0x00, 0xe3, 0x01, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, + 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, + 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, + 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, + 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, + 0x42, 0xe4, 0x48, 0x0e, 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, + 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, + 0x07, 0x40, 0x02, 0xa8, 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, + 0x20, 0x6d, 0x30, 0x86, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x09, 0xa8, + 0x00, 0x49, 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, + 0x42, 0x20, 0x4c, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, + 0x00, 0x45, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, + 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, + 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x70, 0x23, + 0x00, 0x25, 0x00, 0x14, 0x66, 0x00, 0xe6, 0x08, 0xc0, 0x60, 0x8e, 0x00, + 0x29, 0xc6, 0x20, 0x84, 0x14, 0x42, 0xa6, 0x18, 0x80, 0x10, 0x52, 0x06, + 0xa1, 0x9b, 0x86, 0xcb, 0x9f, 0xb0, 0x87, 0x90, 0xfc, 0x95, 0x90, 0x56, + 0x62, 0xf2, 0x8b, 0xdb, 0x46, 0xc5, 0x18, 0x63, 0x10, 0x2a, 0xf7, 0x0c, + 0x97, 0x3f, 0x61, 0x0f, 0x21, 0xf9, 0x21, 0xd0, 0x0c, 0x0b, 0x81, 0x82, + 0x55, 0x18, 0x45, 0x18, 0x1b, 0x63, 0x0c, 0x42, 0xc8, 0xa0, 0x56, 0x90, + 0x41, 0xc6, 0x18, 0x63, 0x0c, 0x7a, 0x73, 0x04, 0x41, 0x31, 0x18, 0x29, + 0x84, 0x44, 0x92, 0x03, 0x01, 0xc3, 0x08, 0xc4, 0x30, 0x53, 0x1b, 0x8c, + 0x03, 0x3b, 0x84, 0xc3, 0x3c, 0xcc, 0x83, 0x1b, 0xd0, 0x42, 0x39, 0xe0, + 0x03, 0x3d, 0xd4, 0x83, 0x3c, 0x94, 0x83, 0x1c, 0x90, 0x02, 0x1f, 0xd8, + 0x43, 0x39, 0x8c, 0x03, 0x3d, 0xbc, 0x83, 0x3c, 0xf0, 0x81, 0x39, 0xb0, + 0xc3, 0x3b, 0x84, 0x03, 0x3d, 0xb0, 0x01, 0x18, 0xd0, 0x81, 0x1f, 0x80, + 0x81, 0x1f, 0xe8, 0x81, 0x1e, 0xb4, 0x43, 0x3a, 0xc0, 0xc3, 0x3c, 0xfc, + 0x02, 0x3d, 0xe4, 0x03, 0x3c, 0x94, 0x03, 0x0a, 0xc8, 0x4c, 0x62, 0x30, + 0x0e, 0xec, 0x10, 0x0e, 0xf3, 0x30, 0x0f, 0x6e, 0x40, 0x0b, 0xe5, 0x80, + 0x0f, 0xf4, 0x50, 0x0f, 0xf2, 0x50, 0x0e, 0x72, 0x40, 0x0a, 0x7c, 0x60, + 0x0f, 0xe5, 0x30, 0x0e, 0xf4, 0xf0, 0x0e, 0xf2, 0xc0, 0x07, 0xe6, 0xc0, + 0x0e, 0xef, 0x10, 0x0e, 0xf4, 0xc0, 0x06, 0x60, 0x40, 0x07, 0x7e, 0x00, + 0x06, 0x7e, 0x80, 0x84, 0x6a, 0xe9, 0xde, 0x24, 0x4d, 0x11, 0x25, 0x4c, + 0x3e, 0x0b, 0x30, 0xcf, 0x42, 0x44, 0xec, 0x04, 0x4c, 0x04, 0x0a, 0x08, + 0xe5, 0x74, 0x20, 0x00, 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, + 0x87, 0x36, 0x68, 0x87, 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, + 0x50, 0x0e, 0x6d, 0xd0, 0x0e, 0x7a, 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, + 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, + 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, + 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, + 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, + 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, + 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, + 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, + 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x43, + 0x9e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x86, 0x3c, 0x06, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x79, 0x10, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0xf2, 0x34, 0x40, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x30, 0xe4, 0x79, 0x80, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x60, 0xc8, 0x23, 0x01, 0x01, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x16, 0x08, 0x00, 0x0f, 0x00, 0x00, + 0x00, 0x32, 0x1e, 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, + 0x47, 0xc6, 0x04, 0x43, 0x22, 0x25, 0x30, 0x02, 0x50, 0x0c, 0x45, 0x50, + 0x12, 0x65, 0x50, 0x1e, 0x54, 0x4a, 0xa2, 0x0c, 0x0a, 0x61, 0x04, 0xa0, + 0x08, 0x0a, 0x84, 0xf0, 0x0c, 0x00, 0xe9, 0x19, 0x00, 0xda, 0x63, 0x39, + 0x0c, 0x01, 0x00, 0x00, 0x70, 0x1c, 0x00, 0x10, 0x08, 0x04, 0x02, 0x00, + 0x00, 0x79, 0x18, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, + 0x90, 0x46, 0x02, 0x13, 0x44, 0x35, 0x18, 0x63, 0x0b, 0x73, 0x3b, 0x03, + 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x03, 0x99, 0x71, 0xb9, 0x01, + 0x41, 0xa1, 0x0b, 0x3b, 0x9b, 0x7b, 0x91, 0x2a, 0x62, 0x2a, 0x0a, 0x9a, + 0x2a, 0xfa, 0x9a, 0xb9, 0x81, 0x79, 0x31, 0x4b, 0x73, 0x0b, 0x63, 0x4b, + 0xd9, 0x10, 0x04, 0x13, 0x04, 0xc2, 0x98, 0x20, 0x10, 0xc7, 0x06, 0x61, + 0x20, 0x26, 0x08, 0x04, 0xb2, 0x41, 0x18, 0x0c, 0x0a, 0x70, 0x73, 0x1b, + 0x06, 0xc4, 0x20, 0x26, 0x08, 0xd8, 0x44, 0x60, 0x82, 0x40, 0x24, 0x13, + 0x04, 0x42, 0xd9, 0x20, 0x10, 0xcd, 0x86, 0x84, 0x50, 0x16, 0x82, 0x18, + 0x18, 0xc2, 0xd9, 0x90, 0x0c, 0xca, 0x42, 0x0c, 0x03, 0x43, 0x38, 0x1b, + 0x84, 0x07, 0x9a, 0x20, 0x68, 0xd4, 0x06, 0x84, 0x90, 0x16, 0x82, 0x18, + 0x08, 0x60, 0x43, 0x30, 0x6d, 0x20, 0x22, 0x00, 0xa0, 0x26, 0x08, 0x5b, + 0xb5, 0x21, 0xb0, 0x26, 0x08, 0x02, 0x40, 0xa2, 0x2d, 0x2c, 0xcd, 0x8d, + 0xcb, 0x94, 0xd5, 0x17, 0xd4, 0xdb, 0x5c, 0x1a, 0x5d, 0xda, 0x9b, 0xdb, + 0x04, 0xa1, 0x68, 0x26, 0x08, 0x85, 0xb3, 0x21, 0x20, 0x26, 0x08, 0xc5, + 0x33, 0x41, 0x28, 0xa0, 0x0d, 0x0b, 0xa1, 0x6d, 0x5c, 0xe7, 0x0d, 0x1e, + 0xf1, 0x01, 0x44, 0xa8, 0x8a, 0xb0, 0x86, 0x9e, 0x9e, 0xa4, 0x88, 0x26, + 0x08, 0x45, 0x34, 0x41, 0x20, 0x96, 0x0d, 0xc2, 0x18, 0x8c, 0xc1, 0x86, + 0x65, 0x08, 0x83, 0xed, 0xeb, 0xc4, 0x60, 0x10, 0x83, 0xe1, 0x23, 0x03, + 0x16, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x13, 0x04, 0x82, 0xd9, 0x20, 0x8c, + 0xc1, 0x19, 0x6c, 0x58, 0x18, 0x33, 0xd8, 0xbe, 0x4e, 0x0c, 0x06, 0x8f, + 0xf9, 0xd0, 0x60, 0xc3, 0x00, 0x06, 0x65, 0x90, 0x06, 0x4c, 0xa6, 0xac, + 0xbe, 0xa8, 0xc2, 0xe4, 0xce, 0xca, 0xe8, 0x26, 0x08, 0x85, 0xb4, 0x61, + 0x21, 0xd6, 0x60, 0x63, 0x83, 0xee, 0x1b, 0x3c, 0xe2, 0x43, 0x83, 0x0d, + 0x41, 0x1b, 0x6c, 0x18, 0xd4, 0xc0, 0x0d, 0x80, 0x0d, 0x05, 0x96, 0xbd, + 0x41, 0x05, 0x54, 0x61, 0x63, 0xb3, 0x6b, 0x73, 0x49, 0x23, 0x2b, 0x73, + 0xa3, 0x9b, 0x12, 0x04, 0x55, 0xc8, 0xf0, 0x5c, 0xec, 0xca, 0xe4, 0xe6, + 0xd2, 0xde, 0xdc, 0xa6, 0x04, 0x44, 0x13, 0x32, 0x3c, 0x17, 0xbb, 0x30, + 0x36, 0xbb, 0x32, 0xb9, 0x29, 0x81, 0x51, 0x87, 0x0c, 0xcf, 0x65, 0x0e, + 0x2d, 0x8c, 0xac, 0x4c, 0xae, 0xe9, 0x8d, 0xac, 0x8c, 0x6d, 0x4a, 0x80, + 0x94, 0x21, 0xc3, 0x73, 0x91, 0x2b, 0x9b, 0x7b, 0xab, 0x93, 0x1b, 0x2b, + 0x9b, 0x9b, 0x12, 0x50, 0x75, 0xc8, 0xf0, 0x5c, 0xec, 0xd2, 0xca, 0xee, + 0x92, 0xc8, 0xa6, 0xe8, 0xc2, 0xe8, 0xca, 0xa6, 0x04, 0x56, 0x1d, 0x32, + 0x3c, 0x97, 0x32, 0x37, 0x3a, 0xb9, 0x3c, 0xa8, 0xb7, 0x34, 0x37, 0xba, + 0xb9, 0x29, 0xc1, 0x1b, 0x00, 0x79, 0x18, 0x00, 0x00, 0x4c, 0x00, 0x00, + 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, + 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, + 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, + 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, + 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, + 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, + 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, + 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, + 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, + 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, + 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, + 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, + 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, + 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, + 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, + 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, + 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, + 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, + 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, + 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, + 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, + 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, + 0xc4, 0x21, 0x07, 0x7c, 0x70, 0x03, 0x7a, 0x28, 0x87, 0x76, 0x80, 0x87, + 0x19, 0xd1, 0x43, 0x0e, 0xf8, 0xe0, 0x06, 0xe4, 0x20, 0x0e, 0xe7, 0xe0, + 0x06, 0xf6, 0x10, 0x0e, 0xf2, 0xc0, 0x0e, 0xe1, 0x90, 0x0f, 0xef, 0x50, + 0x0f, 0xf4, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x15, 0x00, 0x00, + 0x00, 0x56, 0x20, 0x0d, 0x97, 0xef, 0x3c, 0xbe, 0x10, 0x11, 0xc0, 0x44, + 0x84, 0x40, 0x33, 0x2c, 0x84, 0x11, 0x38, 0xc3, 0xe5, 0x3b, 0x8f, 0x3f, + 0x38, 0xd3, 0xed, 0x17, 0xb7, 0x6d, 0x01, 0xd3, 0x70, 0xf9, 0xce, 0xe3, + 0x2f, 0x0e, 0x30, 0x88, 0xcd, 0x43, 0x4d, 0x7e, 0x71, 0xdb, 0x36, 0x00, + 0x0d, 0x97, 0xef, 0x3c, 0xbe, 0x04, 0x30, 0xcf, 0x42, 0xf8, 0xc5, 0x6d, + 0x9b, 0x40, 0x35, 0x5c, 0xbe, 0xf3, 0xf8, 0xd2, 0xe4, 0x44, 0x04, 0x4a, + 0x4d, 0x0f, 0x35, 0xf9, 0xc5, 0x6d, 0x1b, 0x00, 0xc1, 0x00, 0x48, 0x03, + 0x00, 0x61, 0x20, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, + 0x2c, 0x10, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x47, 0x00, + 0xa8, 0x94, 0x00, 0x91, 0xc2, 0x2b, 0xb7, 0x92, 0x2b, 0x85, 0x42, 0x98, + 0x01, 0xa0, 0x31, 0x46, 0x00, 0xb3, 0xac, 0x0b, 0x82, 0xc1, 0x18, 0x81, + 0x18, 0xee, 0x30, 0xfc, 0x0b, 0x63, 0x04, 0x3a, 0x4a, 0xd3, 0xe5, 0x2f, + 0x8c, 0x11, 0xc8, 0x79, 0xaf, 0xfa, 0xdf, 0x18, 0x41, 0x48, 0x82, 0x21, + 0xee, 0x0b, 0x23, 0x00, 0x63, 0x04, 0x21, 0x09, 0x86, 0xf0, 0x2f, 0x8c, + 0x11, 0xbc, 0xb8, 0xa8, 0xe6, 0xdf, 0x0c, 0x00, 0x00, 0x23, 0x06, 0x09, + 0x00, 0x82, 0x60, 0x20, 0x89, 0x41, 0x73, 0x85, 0x41, 0x18, 0x44, 0x23, + 0x06, 0x09, 0x00, 0x82, 0x60, 0x20, 0x8d, 0x81, 0x83, 0x85, 0x41, 0x18, + 0x48, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x20, 0x91, 0xc1, 0xb3, 0x89, + 0x81, 0x18, 0x4c, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x60, 0xa4, 0x81, + 0x13, 0x06, 0x63, 0xa0, 0x35, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x60, + 0xa8, 0xc1, 0x23, 0x06, 0x64, 0x40, 0x39, 0x23, 0x06, 0x09, 0x00, 0x82, + 0x60, 0x60, 0xac, 0x01, 0x34, 0x06, 0x65, 0xb0, 0x3d, 0x23, 0x06, 0x09, + 0x00, 0x82, 0x60, 0x60, 0xb0, 0x41, 0x44, 0x06, 0x66, 0xf0, 0x41, 0x23, + 0x06, 0x09, 0x00, 0x82, 0x60, 0x60, 0xb4, 0x81, 0x84, 0x06, 0x67, 0xe0, + 0x45, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x60, 0xb8, 0xc1, 0x94, 0x06, + 0x68, 0x80, 0x49, 0x23, 0x06, 0x0f, 0x00, 0x82, 0x60, 0xd0, 0xb4, 0x01, + 0x86, 0x1c, 0x42, 0xa0, 0x28, 0x69, 0x90, 0x06, 0x93, 0x32, 0x9a, 0x10, + 0x00, 0x23, 0x06, 0x0f, 0x00, 0x82, 0x60, 0xd0, 0xbc, 0x81, 0xb6, 0x24, + 0xc4, 0xc0, 0x30, 0x6b, 0xb0, 0x06, 0x15, 0x33, 0x9a, 0x10, 0x00, 0xa3, + 0x09, 0x42, 0x60, 0xc4, 0x04, 0x1f, 0x13, 0x24, 0xf8, 0x18, 0x31, 0xc1, + 0x67, 0xc4, 0x60, 0x01, 0x40, 0x10, 0x0c, 0x1e, 0x3a, 0xf8, 0x06, 0x21, + 0x98, 0xaa, 0x6b, 0xc4, 0x60, 0x01, 0x40, 0x10, 0x0c, 0x9e, 0x3a, 0x00, + 0x03, 0x62, 0x10, 0xa8, 0x4c, 0x1b, 0x31, 0x58, 0x00, 0x10, 0x04, 0x83, + 0xc7, 0x0e, 0xc2, 0xa0, 0x20, 0x86, 0x8a, 0xbb, 0x6c, 0x88, 0xe4, 0x63, + 0x43, 0x24, 0x1f, 0x1b, 0x22, 0xf9, 0x8c, 0x18, 0x24, 0x00, 0x08, 0x82, + 0x01, 0xc2, 0x07, 0x63, 0x70, 0x07, 0x77, 0xe0, 0x06, 0xc3, 0x88, 0x41, + 0x02, 0x80, 0x20, 0x18, 0x20, 0x7c, 0x30, 0x06, 0x77, 0x70, 0x07, 0x67, + 0x20, 0x8c, 0x18, 0x24, 0x00, 0x08, 0x82, 0x01, 0xc2, 0x07, 0x63, 0x70, + 0x07, 0x77, 0xd0, 0x06, 0xc1, 0x88, 0x41, 0x02, 0x80, 0x20, 0x18, 0x20, + 0x7c, 0x30, 0x06, 0x77, 0x70, 0x07, 0x70, 0x10, 0x21, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +/* The sole vertex shader (have to build 4x for different root signatures): + + --- D3D12_VertexShader.hlsl --- + #pragma pack_matrix( row_major ) + + cbuffer VertexShaderConstants : register(b0) + { + matrix model; + matrix projectionAndView; + }; + + struct VertexShaderInput + { + float3 pos : POSITION; + float2 tex : TEXCOORD0; + float4 color : COLOR0; + }; + + struct VertexShaderOutput + { + float4 pos : SV_POSITION; + float2 tex : TEXCOORD0; + float4 color : COLOR0; + }; + + #define ColorRS \ + "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \ + "DENY_DOMAIN_SHADER_ROOT_ACCESS |" \ + "DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \ + "DENY_HULL_SHADER_ROOT_ACCESS )," \ + "RootConstants(num32BitConstants=32, b0)" + + #define TextureRS \ + "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \ + " DENY_DOMAIN_SHADER_ROOT_ACCESS |" \ + " DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \ + " DENY_HULL_SHADER_ROOT_ACCESS )," \ + "RootConstants(num32BitConstants=32, b0),"\ + "DescriptorTable ( SRV(t0), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( Sampler(s0), visibility = SHADER_VISIBILITY_PIXEL )" + + #define YUVRS \ + "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \ + " DENY_DOMAIN_SHADER_ROOT_ACCESS |" \ + " DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \ + " DENY_HULL_SHADER_ROOT_ACCESS )," \ + "RootConstants(num32BitConstants=32, b0),"\ + "DescriptorTable ( SRV(t0), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( SRV(t1), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( SRV(t2), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( Sampler(s0), visibility = SHADER_VISIBILITY_PIXEL )" + + #define NVRS \ + "RootFlags ( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |" \ + " DENY_DOMAIN_SHADER_ROOT_ACCESS |" \ + " DENY_GEOMETRY_SHADER_ROOT_ACCESS |" \ + " DENY_HULL_SHADER_ROOT_ACCESS )," \ + "RootConstants(num32BitConstants=32, b0),"\ + "DescriptorTable ( SRV(t0), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( SRV(t1), visibility = SHADER_VISIBILITY_PIXEL ),"\ + "DescriptorTable ( Sampler(s0), visibility = SHADER_VISIBILITY_PIXEL )" + + [RootSignature(ColorRS)] + VertexShaderOutput mainColor(VertexShaderInput input) + { + VertexShaderOutput output; + float4 pos = float4(input.pos, 1.0f); + + // Transform the vertex position into projected space. + pos = mul(pos, model); + pos = mul(pos, projectionAndView); + output.pos = pos; + + // Pass through texture coordinates and color values without transformation + output.tex = input.tex; + output.color = input.color; + + return output; + } + + [RootSignature(TextureRS)] + VertexShaderOutput mainTexture(VertexShaderInput input) + { + return mainColor(input); + } + + [RootSignature(YUVRS)] + VertexShaderOutput mainYUV(VertexShaderInput input) + { + return mainColor(input); + } + + [RootSignature(NVRS)] + VertexShaderOutput mainNV(VertexShaderInput input) + { + return mainColor(input); + } +*/ + +static unsigned char D3D12_VertexShader_Colors[] = { + 0x44, 0x58, 0x42, 0x43, 0xbd, 0x28, 0xdc, 0xb4, 0x40, 0x82, 0x5f, 0xf6, + 0x92, 0x33, 0x60, 0xe7, 0x83, 0x5b, 0x8f, 0x2d, 0x01, 0x00, 0x00, 0x00, + 0xeb, 0x13, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0xd8, 0x00, 0x00, 0x00, 0x63, 0x01, 0x00, 0x00, + 0x73, 0x02, 0x00, 0x00, 0xab, 0x02, 0x00, 0x00, 0xa7, 0x0a, 0x00, 0x00, + 0xc3, 0x0a, 0x00, 0x00, 0x53, 0x46, 0x49, 0x30, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31, + 0x80, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x54, 0x45, 0x58, + 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, + 0x4f, 0x53, 0x47, 0x31, 0x83, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x03, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, + 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x50, 0x53, 0x56, 0x30, 0x08, + 0x01, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x03, + 0x03, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, + 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x54, 0x45, 0x58, + 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, + 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x43, 0x4f, 0x4c, + 0x4f, 0x52, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x43, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x01, 0x42, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x44, 0x03, 0x03, 0x04, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x01, 0x42, 0x00, 0x03, 0x02, 0x00, 0x00, 0x22, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, 0x03, + 0x02, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x52, 0x54, 0x53, 0x30, 0x30, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x53, + 0x54, 0x41, 0x54, 0xf4, 0x07, 0x00, 0x00, 0x60, 0x00, 0x01, 0x00, 0xfd, + 0x01, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c, 0x00, 0x01, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0xdc, 0x07, 0x00, 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, + 0x0c, 0x00, 0x00, 0xf4, 0x01, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, + 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, + 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x18, 0x45, 0x02, 0x42, + 0x92, 0x0b, 0x42, 0xc4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, + 0x32, 0x62, 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, + 0x19, 0x32, 0x42, 0xe4, 0x48, 0x0e, 0x90, 0x11, 0x23, 0xc4, 0x50, 0x41, + 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x31, 0x46, 0x06, 0x51, + 0x18, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, + 0xff, 0xff, 0x07, 0x40, 0x02, 0xa8, 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, + 0xff, 0x03, 0x20, 0x6d, 0x30, 0x86, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, + 0x09, 0xa8, 0x00, 0x49, 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, + 0x82, 0x60, 0x42, 0x20, 0x4c, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x89, + 0x20, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x32, 0x22, 0x88, 0x09, 0x20, + 0x64, 0x85, 0x04, 0x13, 0x23, 0xa4, 0x84, 0x04, 0x13, 0x23, 0xe3, 0x84, + 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8c, 0x8c, 0x0b, 0x84, 0xc4, 0x4c, 0x10, + 0x88, 0xc1, 0x0c, 0xc0, 0x30, 0x02, 0x01, 0x24, 0x41, 0x70, 0x70, 0x30, + 0x5c, 0x3e, 0xb0, 0x20, 0x46, 0xc3, 0x10, 0xcd, 0xe4, 0x2f, 0x84, 0x01, + 0x08, 0x98, 0x2f, 0x4d, 0x11, 0x25, 0x4c, 0xfe, 0x4b, 0x44, 0x13, 0x71, + 0xb1, 0x07, 0x30, 0x10, 0x11, 0xe7, 0x34, 0xd2, 0x04, 0x34, 0x93, 0x84, + 0x04, 0x41, 0xb8, 0x6e, 0xb8, 0x7c, 0x60, 0x41, 0x8c, 0x86, 0x21, 0x9a, + 0xc9, 0x5f, 0x08, 0x03, 0x10, 0x30, 0x9f, 0x73, 0x1a, 0x69, 0x02, 0x9a, + 0x49, 0x42, 0xc1, 0x40, 0xc4, 0x08, 0x40, 0x09, 0x0c, 0x3a, 0xe6, 0x08, + 0xc0, 0x60, 0x8e, 0x00, 0x29, 0x06, 0x90, 0x24, 0x89, 0x92, 0xd0, 0x52, + 0x0c, 0x23, 0x49, 0x12, 0x05, 0xa0, 0xe6, 0xa8, 0xe1, 0xf2, 0x27, 0xec, + 0x21, 0x24, 0x9f, 0xdb, 0xa8, 0x62, 0x25, 0x26, 0xbf, 0xb8, 0x6d, 0x44, + 0x00, 0x00, 0x00, 0x90, 0x72, 0xcf, 0x70, 0xf9, 0x13, 0xf6, 0x10, 0x92, + 0x1f, 0x02, 0xcd, 0xb0, 0x10, 0x28, 0x80, 0x0a, 0xf1, 0x24, 0x51, 0x42, + 0x52, 0x29, 0x80, 0x04, 0x00, 0x00, 0xa2, 0xe6, 0x08, 0x82, 0x62, 0x44, + 0x89, 0x92, 0x24, 0x16, 0x5d, 0x03, 0x01, 0x67, 0x09, 0x0b, 0x20, 0x49, + 0x3e, 0x03, 0x4c, 0x11, 0x72, 0xf9, 0xc5, 0xe2, 0x00, 0x93, 0x8f, 0xfb, + 0x38, 0x0a, 0x84, 0xe3, 0xa4, 0x29, 0xa2, 0x84, 0xc9, 0x7f, 0x89, 0x68, + 0x22, 0x2e, 0xf6, 0x00, 0x06, 0x22, 0xe2, 0x9c, 0x46, 0x9a, 0x80, 0x66, + 0x92, 0x90, 0xa0, 0x69, 0xc3, 0x08, 0x02, 0x70, 0x99, 0x34, 0x45, 0x94, + 0x30, 0xf9, 0x2f, 0x11, 0x4d, 0xc4, 0xc5, 0x1e, 0xc0, 0x40, 0x44, 0x28, + 0x35, 0x3d, 0xd4, 0x84, 0x86, 0x80, 0x0b, 0x86, 0x11, 0x06, 0xe0, 0x30, + 0x69, 0x8a, 0x28, 0x61, 0xf2, 0x5f, 0x22, 0x9a, 0x88, 0x8b, 0x3d, 0x80, + 0x81, 0x88, 0xc4, 0xe6, 0xa1, 0x26, 0x34, 0x78, 0x5c, 0x70, 0x09, 0xe7, + 0x34, 0xd2, 0x04, 0x34, 0x93, 0x84, 0x82, 0x2d, 0x1d, 0x12, 0x00, 0x13, + 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, 0x79, 0x68, + 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e, 0x6d, 0xd0, 0x0e, 0x7a, + 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, + 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, + 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, + 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, + 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, + 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, + 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, + 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, + 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x3a, 0x0f, 0x64, 0x90, 0x21, 0x23, 0x25, + 0x40, 0x00, 0x52, 0x00, 0xc0, 0x90, 0xe7, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x21, 0xcf, 0x02, 0x04, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x9e, 0x06, 0x08, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x3c, 0x12, 0x10, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x79, 0x28, + 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf2, + 0x5c, 0x40, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, + 0x05, 0x02, 0x00, 0x19, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x18, 0x19, + 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x52, 0x0a, + 0xa1, 0x08, 0xca, 0x80, 0x92, 0x12, 0x18, 0x01, 0x28, 0x86, 0x02, 0x14, + 0x28, 0x82, 0x42, 0x28, 0x83, 0x72, 0x28, 0x89, 0x02, 0x0c, 0x28, 0xb0, + 0x02, 0x29, 0xa0, 0xf2, 0x28, 0x8c, 0xd2, 0x0d, 0x28, 0x0a, 0x52, 0x4a, + 0x62, 0x04, 0x80, 0x8a, 0x19, 0x00, 0x22, 0x66, 0x00, 0x68, 0x98, 0x01, + 0xa0, 0x6d, 0x06, 0x80, 0xba, 0x19, 0x00, 0xfa, 0x66, 0x00, 0x08, 0x9c, + 0x01, 0xa0, 0x70, 0x2c, 0x87, 0x61, 0x9e, 0xe7, 0x01, 0x20, 0x30, 0x00, + 0x00, 0x10, 0x01, 0x21, 0x10, 0x0c, 0x40, 0x50, 0x00, 0x00, 0x00, 0x79, + 0x18, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x90, 0x46, + 0x02, 0x13, 0x44, 0x35, 0x18, 0x63, 0x0b, 0x73, 0x3b, 0x03, 0xb1, 0x2b, + 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x03, 0x99, 0x71, 0xb9, 0x01, 0x41, 0xa1, + 0x0b, 0x3b, 0x9b, 0x7b, 0x91, 0x2a, 0x62, 0x2a, 0x0a, 0x9a, 0x2a, 0xfa, + 0x9a, 0xb9, 0x81, 0x79, 0x31, 0x4b, 0x73, 0x0b, 0x63, 0x4b, 0xd9, 0x10, + 0x04, 0x13, 0x84, 0x44, 0x99, 0x20, 0x24, 0xcb, 0x06, 0x61, 0x20, 0x36, + 0x08, 0x04, 0x41, 0xc1, 0x6e, 0x6e, 0x82, 0x90, 0x30, 0x1b, 0x86, 0x03, + 0x21, 0x26, 0x08, 0x45, 0xc7, 0x64, 0xe8, 0xcd, 0x6d, 0x8e, 0x2e, 0xcc, + 0x8d, 0x6e, 0x6e, 0x82, 0x90, 0x34, 0x1b, 0x10, 0x42, 0x59, 0x08, 0x62, + 0x60, 0x80, 0x0d, 0x41, 0xb3, 0x81, 0x00, 0x00, 0x07, 0x98, 0x20, 0x6c, + 0x60, 0xc0, 0xa2, 0xed, 0x8d, 0xac, 0x8c, 0x6d, 0x82, 0x90, 0x38, 0x13, + 0x84, 0xe4, 0xd9, 0x30, 0x4c, 0xd3, 0x30, 0x41, 0x48, 0xa0, 0x09, 0x42, + 0x12, 0x4d, 0x10, 0x12, 0x69, 0x03, 0x82, 0x44, 0x12, 0x55, 0x11, 0xd6, + 0xc5, 0x08, 0x4e, 0xee, 0x4d, 0xad, 0x6c, 0x8c, 0x2e, 0xed, 0xcd, 0x2d, + 0xc8, 0x8d, 0xcc, 0x2a, 0xad, 0xec, 0x6e, 0x82, 0x90, 0x4c, 0x1b, 0x10, + 0x24, 0x93, 0xa8, 0x4a, 0xb3, 0xae, 0x0d, 0x03, 0x83, 0x6d, 0x13, 0x84, + 0x2e, 0x0c, 0x26, 0x08, 0x09, 0xc5, 0x01, 0xee, 0x6d, 0x8e, 0xcb, 0x94, + 0xd5, 0x17, 0xd4, 0xd3, 0x54, 0x12, 0x55, 0xd2, 0x93, 0xd3, 0x06, 0x04, + 0xf9, 0x2a, 0x62, 0x02, 0x03, 0xeb, 0xe2, 0x40, 0x57, 0x86, 0x37, 0x41, + 0x48, 0x2a, 0x26, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x30, + 0x1b, 0x10, 0x44, 0x0c, 0xaa, 0x31, 0x98, 0xc8, 0xc0, 0xba, 0x58, 0x8c, + 0xbd, 0xb1, 0xbd, 0xc9, 0x4d, 0x10, 0x12, 0x8b, 0xc6, 0xd0, 0x13, 0xd3, + 0x93, 0x14, 0xcc, 0x06, 0x04, 0x31, 0x83, 0xea, 0x0c, 0x26, 0x34, 0xb0, + 0xae, 0x0d, 0x84, 0x17, 0x06, 0x65, 0x90, 0x06, 0x13, 0x84, 0x4f, 0x0c, + 0x88, 0x40, 0x3d, 0x4d, 0x25, 0x51, 0x25, 0x3d, 0x39, 0x6d, 0x40, 0x90, + 0xaf, 0x22, 0x26, 0x36, 0xb0, 0xae, 0x0d, 0x84, 0xd7, 0x06, 0x65, 0x90, + 0x06, 0x13, 0x04, 0x30, 0x18, 0x83, 0x0d, 0x04, 0xb2, 0x54, 0xc4, 0x06, + 0x81, 0x81, 0x83, 0x09, 0xc2, 0xf0, 0x4d, 0x10, 0x08, 0x6f, 0x43, 0x43, + 0x40, 0x5c, 0xa7, 0x06, 0x6b, 0xe0, 0x06, 0x6f, 0x10, 0x07, 0x72, 0xc0, + 0xcd, 0x41, 0x1c, 0x4c, 0x10, 0x90, 0x60, 0x03, 0xb0, 0x61, 0x20, 0xec, + 0xc0, 0x0e, 0x36, 0x04, 0x77, 0xb0, 0x61, 0x18, 0xea, 0x00, 0x0f, 0x26, + 0x08, 0x61, 0x40, 0x06, 0x1b, 0x02, 0x3d, 0x60, 0xd2, 0x16, 0x96, 0xe6, + 0x36, 0xf4, 0xc6, 0xf6, 0x26, 0x37, 0x41, 0x50, 0xb6, 0x09, 0x82, 0xc2, + 0x6d, 0x08, 0x88, 0x09, 0x82, 0x92, 0x6c, 0x10, 0x2a, 0x6b, 0xc3, 0x42, + 0xb0, 0x41, 0x1f, 0xf8, 0xc1, 0x1f, 0xf8, 0xc1, 0x00, 0x0a, 0x84, 0x1f, + 0x84, 0x02, 0x11, 0xaa, 0x22, 0xac, 0xa1, 0xa7, 0x27, 0x29, 0xa2, 0x09, + 0x82, 0x82, 0x6c, 0x10, 0xaa, 0x6a, 0xc3, 0x32, 0x8c, 0x42, 0x1f, 0xf8, + 0xc1, 0x1f, 0xf8, 0xc1, 0x40, 0x0a, 0x83, 0x1f, 0x94, 0x02, 0x8b, 0xa1, + 0x27, 0xa6, 0x27, 0xa9, 0x09, 0x82, 0x72, 0x4c, 0x10, 0x92, 0x6b, 0x83, + 0x50, 0xa5, 0xc2, 0x86, 0x45, 0x3a, 0x85, 0x3e, 0xf0, 0x83, 0x3f, 0xf0, + 0x83, 0x01, 0x15, 0x24, 0x3f, 0x50, 0x85, 0x0d, 0x83, 0x28, 0x98, 0xc2, + 0x2a, 0x70, 0x99, 0xb2, 0xfa, 0x82, 0x7a, 0x9b, 0x4b, 0xa3, 0x4b, 0x7b, + 0x73, 0xdb, 0xb0, 0x10, 0xad, 0xd0, 0x07, 0xa0, 0xf0, 0x07, 0xa8, 0x30, + 0xa0, 0x02, 0xe1, 0x07, 0xaa, 0xb0, 0x61, 0x19, 0x46, 0xa1, 0x0f, 0xfc, + 0xe0, 0x0f, 0x48, 0x61, 0x20, 0x85, 0xc1, 0x0f, 0x4a, 0x61, 0xc3, 0x22, + 0x9d, 0x42, 0x1f, 0xf8, 0xc1, 0x1f, 0x90, 0xc2, 0x80, 0x0a, 0x92, 0x1f, + 0xa8, 0xc2, 0x86, 0xc1, 0x15, 0x5e, 0x01, 0x16, 0x36, 0x0c, 0xac, 0x10, + 0x0b, 0xc0, 0x86, 0xa2, 0x0e, 0xf8, 0x40, 0x16, 0x1e, 0x80, 0x86, 0x19, + 0xdb, 0x5b, 0x18, 0xdd, 0xdc, 0x04, 0x21, 0xc1, 0x58, 0xa4, 0xb9, 0xcd, + 0xd1, 0xcd, 0x4d, 0x10, 0x92, 0x8c, 0xc6, 0x5c, 0xda, 0xd9, 0x17, 0x1b, + 0x19, 0x8d, 0xb9, 0xb4, 0xb3, 0xaf, 0x39, 0xba, 0x09, 0x42, 0xa2, 0x6d, + 0x40, 0x68, 0xa1, 0x16, 0x6c, 0xe1, 0x16, 0x70, 0xe1, 0xca, 0x05, 0x5d, + 0xa8, 0xc2, 0xc6, 0x66, 0xd7, 0xe6, 0x92, 0x46, 0x56, 0xe6, 0x46, 0x37, + 0x25, 0x08, 0xaa, 0x90, 0xe1, 0xb9, 0xd8, 0x95, 0xc9, 0xcd, 0xa5, 0xbd, + 0xb9, 0x4d, 0x09, 0x88, 0x26, 0x64, 0x78, 0x2e, 0x76, 0x61, 0x6c, 0x76, + 0x65, 0x72, 0x53, 0x82, 0xa2, 0x0e, 0x19, 0x9e, 0xcb, 0x1c, 0x5a, 0x18, + 0x59, 0x99, 0x5c, 0xd3, 0x1b, 0x59, 0x19, 0xdb, 0x94, 0x00, 0x29, 0x43, + 0x86, 0xe7, 0x22, 0x57, 0x36, 0xf7, 0x56, 0x27, 0x37, 0x56, 0x36, 0x37, + 0x25, 0x70, 0x2a, 0x91, 0xe1, 0xb9, 0xd0, 0xe5, 0xc1, 0x95, 0x05, 0xb9, + 0xb9, 0xbd, 0xd1, 0x85, 0xd1, 0xa5, 0xbd, 0xb9, 0xcd, 0x4d, 0x11, 0xe6, + 0x00, 0x0f, 0xea, 0x90, 0xe1, 0xb9, 0xd8, 0xa5, 0x95, 0xdd, 0x25, 0x91, + 0x4d, 0xd1, 0x85, 0xd1, 0x95, 0x4d, 0x09, 0xf4, 0xa0, 0x0e, 0x19, 0x9e, + 0x4b, 0x99, 0x1b, 0x9d, 0x5c, 0x1e, 0xd4, 0x5b, 0x9a, 0x1b, 0xdd, 0xdc, + 0x94, 0x40, 0x16, 0xba, 0x90, 0xe1, 0xb9, 0x8c, 0xbd, 0xd5, 0xb9, 0xd1, + 0x95, 0xc9, 0xcd, 0x4d, 0x09, 0x74, 0x01, 0x79, 0x18, 0x00, 0x00, 0x49, + 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, + 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, + 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, + 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, + 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, + 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, + 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, + 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, + 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, + 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, + 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, + 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, + 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, + 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, + 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, + 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, + 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, + 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, + 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, + 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, + 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, + 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, + 0xc3, 0x8c, 0xc8, 0x21, 0x07, 0x7c, 0x70, 0x03, 0x72, 0x10, 0x87, 0x73, + 0x70, 0x03, 0x7b, 0x08, 0x07, 0x79, 0x60, 0x87, 0x70, 0xc8, 0x87, 0x77, + 0xa8, 0x07, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x1d, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x71, 0x4e, 0x23, 0x4d, 0x40, 0x33, 0x49, + 0xff, 0x42, 0x18, 0x80, 0x80, 0x19, 0xc1, 0x36, 0x5c, 0xbe, 0xf3, 0xf8, + 0x42, 0x40, 0x15, 0x05, 0x11, 0x95, 0x0e, 0x30, 0x94, 0x84, 0x01, 0x08, + 0x98, 0x5f, 0xdc, 0xb6, 0x19, 0x48, 0xc3, 0xe5, 0x3b, 0x8f, 0x2f, 0x44, + 0x04, 0x30, 0x11, 0x21, 0xd0, 0x0c, 0x0b, 0x61, 0x02, 0xd3, 0x70, 0xf9, + 0xce, 0xe3, 0x2f, 0x0e, 0x30, 0x88, 0xcd, 0x43, 0x4d, 0x7e, 0x71, 0xdb, + 0x36, 0x50, 0x0d, 0x97, 0xef, 0x3c, 0xbe, 0x34, 0x39, 0x11, 0x81, 0x52, + 0xd3, 0x43, 0x4d, 0x7e, 0x71, 0xdb, 0x56, 0x20, 0x0d, 0x97, 0xef, 0x3c, + 0xfe, 0x44, 0x44, 0x13, 0x02, 0x44, 0x98, 0x5f, 0xdc, 0xb6, 0x05, 0x24, + 0x0c, 0x80, 0x34, 0x9c, 0xb3, 0x38, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x14, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x46, 0x05, 0xa8, 0xdb, 0xf4, 0x51, 0x8f, 0x4d, 0x34, + 0xfb, 0x4e, 0x9d, 0x82, 0x8b, 0x6e, 0x9e, 0x44, 0x58, 0x49, 0x4c, 0x20, + 0x09, 0x00, 0x00, 0x60, 0x00, 0x01, 0x00, 0x48, 0x02, 0x00, 0x00, 0x44, + 0x58, 0x49, 0x4c, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, + 0x09, 0x00, 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x3f, + 0x02, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, + 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, + 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, + 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, + 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88, 0x48, + 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4, + 0x48, 0x0e, 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, + 0x83, 0xe5, 0x8a, 0x04, 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40, + 0x02, 0xa8, 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x20, 0x6d, + 0x30, 0x86, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x09, 0xa8, 0x00, 0x49, + 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, 0x42, 0x20, + 0x4c, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x30, + 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, + 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, + 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x6c, 0x23, 0x00, 0x25, + 0x00, 0x14, 0x66, 0x00, 0xe6, 0x08, 0xc0, 0x60, 0x8e, 0x00, 0x29, 0xc6, + 0x20, 0x84, 0x14, 0x42, 0xa6, 0x18, 0x80, 0x10, 0x52, 0x06, 0xa1, 0xa3, + 0x86, 0xcb, 0x9f, 0xb0, 0x87, 0x90, 0x7c, 0x6e, 0xa3, 0x8a, 0x95, 0x98, + 0xfc, 0xe2, 0xb6, 0x11, 0x31, 0xc6, 0x18, 0x54, 0xee, 0x19, 0x2e, 0x7f, + 0xc2, 0x1e, 0x42, 0xf2, 0x43, 0xa0, 0x19, 0x16, 0x02, 0x05, 0xab, 0x10, + 0x8a, 0x30, 0x42, 0xad, 0x14, 0x83, 0x8c, 0x31, 0xe8, 0xcd, 0x11, 0x04, + 0xc5, 0x60, 0xa4, 0x10, 0x12, 0x49, 0x0e, 0x04, 0x0c, 0x23, 0x10, 0x43, + 0x12, 0xd4, 0x83, 0x83, 0xe1, 0xf2, 0x81, 0x05, 0x31, 0x1a, 0x86, 0x68, + 0x26, 0x7f, 0x21, 0x0c, 0x40, 0xc0, 0x7c, 0x69, 0x8a, 0x28, 0x61, 0xf2, + 0x5f, 0x22, 0x9a, 0x88, 0x8b, 0x3d, 0x80, 0x81, 0x88, 0x38, 0xa7, 0x91, + 0x26, 0xa0, 0x99, 0x24, 0x24, 0x58, 0x7b, 0xdd, 0x70, 0xf9, 0xc0, 0x82, + 0x18, 0x0d, 0x43, 0x34, 0x93, 0xbf, 0x10, 0x06, 0x20, 0x60, 0x3e, 0xe7, + 0x34, 0xd2, 0x04, 0x34, 0x93, 0x84, 0x82, 0x4b, 0x38, 0x1d, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, + 0x68, 0x87, 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e, + 0x6d, 0xd0, 0x0e, 0x7a, 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07, + 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, + 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, 0x20, 0x07, + 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, + 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, + 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x10, 0x07, + 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, + 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, + 0x76, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, + 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x43, 0x9e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x3c, + 0x06, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, + 0x79, 0x10, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0xf2, 0x34, 0x40, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0xe4, 0x79, 0x80, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x60, 0xc8, 0x23, 0x01, 0x01, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x40, 0x16, 0x08, 0x00, 0x10, 0x00, 0x00, 0x00, 0x32, + 0x1e, 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, + 0x04, 0x43, 0x22, 0x25, 0x30, 0x02, 0x50, 0x0c, 0x05, 0x28, 0x50, 0x06, + 0xe5, 0x50, 0x04, 0xe5, 0x41, 0xa5, 0x24, 0x46, 0x00, 0xca, 0xa0, 0x08, + 0x0a, 0x81, 0xf2, 0x0c, 0x00, 0xe9, 0xb1, 0x1c, 0x86, 0x79, 0x9e, 0x07, + 0x80, 0xc0, 0x00, 0x00, 0x40, 0x04, 0x84, 0x40, 0x30, 0x00, 0x41, 0x01, + 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x1a, + 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, 0x44, 0x35, 0x18, 0x63, 0x0b, 0x73, + 0x3b, 0x03, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x03, 0x99, 0x71, + 0xb9, 0x01, 0x41, 0xa1, 0x0b, 0x3b, 0x9b, 0x7b, 0x91, 0x2a, 0x62, 0x2a, + 0x0a, 0x9a, 0x2a, 0xfa, 0x9a, 0xb9, 0x81, 0x79, 0x31, 0x4b, 0x73, 0x0b, + 0x63, 0x4b, 0xd9, 0x10, 0x04, 0x13, 0x04, 0xc2, 0x98, 0x20, 0x10, 0xc7, + 0x06, 0x61, 0x20, 0x26, 0x08, 0x04, 0xb2, 0x41, 0x18, 0x0c, 0x0a, 0x76, + 0x73, 0x1b, 0x06, 0xc4, 0x20, 0x26, 0x08, 0xd9, 0x44, 0x60, 0x82, 0x40, + 0x24, 0x1b, 0x10, 0x42, 0x59, 0x08, 0x62, 0x60, 0x80, 0x0d, 0x41, 0xb3, + 0x81, 0x00, 0x00, 0x07, 0x98, 0x20, 0x68, 0xd4, 0x86, 0x00, 0x9a, 0x20, + 0x08, 0x00, 0x93, 0xb6, 0xb0, 0x34, 0xb7, 0xa1, 0x37, 0xb6, 0x37, 0x39, + 0x22, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x13, 0x84, 0xc2, + 0x99, 0x20, 0x14, 0xcf, 0x86, 0x80, 0x98, 0x20, 0x14, 0xd0, 0x04, 0x81, + 0x50, 0x26, 0x08, 0xc4, 0xb2, 0x41, 0xc8, 0xb4, 0x0d, 0x0b, 0x41, 0x55, + 0xd6, 0x65, 0x0d, 0x18, 0x61, 0x6d, 0x44, 0xa8, 0x8a, 0xb0, 0x86, 0x9e, + 0x9e, 0xa4, 0x88, 0x26, 0x08, 0x45, 0xb4, 0x41, 0xc8, 0xb2, 0x0d, 0xcb, + 0xd0, 0x55, 0xd6, 0x65, 0x0d, 0xde, 0x60, 0x7d, 0x13, 0x04, 0x82, 0x61, + 0x31, 0xf4, 0xc4, 0xf4, 0x24, 0x35, 0x41, 0x28, 0xa4, 0x09, 0x02, 0xd1, + 0x6c, 0x10, 0x32, 0x32, 0xd8, 0xb0, 0x84, 0x81, 0x18, 0x54, 0xd6, 0x65, + 0x0d, 0x63, 0x10, 0x06, 0x56, 0x19, 0x6c, 0x18, 0x38, 0x30, 0x30, 0x03, + 0x2e, 0x53, 0x56, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x1b, 0x16, 0x02, 0x0d, 0x2a, 0xec, 0x1a, 0x83, 0x61, 0x0c, 0x08, 0xab, + 0x0c, 0x36, 0x2c, 0x43, 0x57, 0x59, 0x97, 0x37, 0x78, 0x83, 0xf5, 0x6d, + 0x58, 0xc2, 0x40, 0x0c, 0x2a, 0xeb, 0xf2, 0x86, 0x31, 0x08, 0x03, 0xab, + 0x0c, 0x36, 0x0c, 0x69, 0xa0, 0x06, 0x6b, 0xb0, 0x61, 0x38, 0x03, 0x36, + 0x00, 0x36, 0x14, 0xd2, 0xd4, 0x06, 0x0f, 0x50, 0x85, 0x8d, 0xcd, 0xae, + 0xcd, 0x25, 0x8d, 0xac, 0xcc, 0x8d, 0x6e, 0x4a, 0x10, 0x54, 0x21, 0xc3, + 0x73, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x9b, 0x12, 0x10, 0x4d, + 0xc8, 0xf0, 0x5c, 0xec, 0xc2, 0xd8, 0xec, 0xca, 0xe4, 0xa6, 0x04, 0x46, + 0x1d, 0x32, 0x3c, 0x97, 0x39, 0xb4, 0x30, 0xb2, 0x32, 0xb9, 0xa6, 0x37, + 0xb2, 0x32, 0xb6, 0x29, 0x01, 0x52, 0x86, 0x0c, 0xcf, 0x45, 0xae, 0x6c, + 0xee, 0xad, 0x4e, 0x6e, 0xac, 0x6c, 0x6e, 0x4a, 0xe0, 0xd4, 0x21, 0xc3, + 0x73, 0xb1, 0x4b, 0x2b, 0xbb, 0x4b, 0x22, 0x9b, 0xa2, 0x0b, 0xa3, 0x2b, + 0x9b, 0x12, 0x40, 0x75, 0xc8, 0xf0, 0x5c, 0xca, 0xdc, 0xe8, 0xe4, 0xf2, + 0xa0, 0xde, 0xd2, 0xdc, 0xe8, 0xe6, 0xa6, 0x04, 0x6d, 0x00, 0x00, 0x79, + 0x18, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, + 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, + 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, + 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, + 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, + 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, + 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, + 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, + 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, + 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, + 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, + 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, + 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, + 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, + 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, + 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, + 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, + 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, + 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, + 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, + 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, + 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, + 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x8c, 0xc8, 0x21, 0x07, 0x7c, 0x70, 0x03, + 0x72, 0x10, 0x87, 0x73, 0x70, 0x03, 0x7b, 0x08, 0x07, 0x79, 0x60, 0x87, + 0x70, 0xc8, 0x87, 0x77, 0xa8, 0x07, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x71, + 0x20, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x36, 0xb0, 0x0d, 0x97, 0xef, + 0x3c, 0xbe, 0x10, 0x50, 0x45, 0x41, 0x44, 0xa5, 0x03, 0x0c, 0x25, 0x61, + 0x00, 0x02, 0xe6, 0x17, 0xb7, 0x6d, 0x05, 0xd2, 0x70, 0xf9, 0xce, 0xe3, + 0x0b, 0x11, 0x01, 0x4c, 0x44, 0x08, 0x34, 0xc3, 0x42, 0x58, 0xc0, 0x34, + 0x5c, 0xbe, 0xf3, 0xf8, 0x8b, 0x03, 0x0c, 0x62, 0xf3, 0x50, 0x93, 0x5f, + 0xdc, 0xb6, 0x09, 0x54, 0xc3, 0xe5, 0x3b, 0x8f, 0x2f, 0x4d, 0x4e, 0x44, + 0xa0, 0xd4, 0xf4, 0x50, 0x93, 0x5f, 0xdc, 0xb6, 0x11, 0x48, 0xc3, 0xe5, + 0x3b, 0x8f, 0x3f, 0x11, 0xd1, 0x84, 0x00, 0x11, 0xe6, 0x17, 0xb7, 0x6d, + 0x00, 0x09, 0x03, 0x20, 0x0d, 0xe7, 0x2c, 0x4e, 0x04, 0x00, 0x00, 0x61, + 0x20, 0x00, 0x00, 0xcf, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x44, 0x8a, 0xab, 0x14, 0x0a, + 0x61, 0x06, 0xa0, 0xec, 0x4a, 0x8e, 0x4a, 0x09, 0x50, 0x1c, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x20, 0x61, 0x03, + 0x63, 0x59, 0xc1, 0x88, 0x41, 0x02, 0x80, 0x20, 0x18, 0x18, 0xdd, 0x21, + 0x5d, 0x8f, 0x31, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x86, 0x87, 0x4c, + 0x18, 0x71, 0x8c, 0x18, 0x24, 0x00, 0x08, 0x82, 0x81, 0xf1, 0x25, 0x54, + 0xf6, 0x20, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x60, 0x80, 0x81, 0x52, + 0x69, 0x51, 0x32, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x46, 0x18, 0x2c, + 0xdc, 0x36, 0x29, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x60, 0x88, 0x01, + 0xd3, 0x71, 0xc8, 0x32, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0xc6, 0x18, + 0x34, 0x5d, 0x57, 0x31, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x60, 0x90, + 0x81, 0xe3, 0x79, 0x4a, 0x33, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x46, + 0x19, 0x3c, 0xdf, 0x57, 0x39, 0x23, 0x06, 0x07, 0x00, 0x82, 0x60, 0xd0, + 0x90, 0x81, 0xa3, 0x80, 0xc1, 0x68, 0x42, 0x00, 0x8c, 0x26, 0x08, 0xc1, + 0x68, 0xc2, 0x20, 0x8c, 0x26, 0x10, 0xc3, 0x88, 0xc1, 0x01, 0x80, 0x20, + 0x18, 0x34, 0x69, 0x30, 0x3d, 0x66, 0x30, 0x9a, 0x10, 0x00, 0xa3, 0x09, + 0x42, 0x30, 0x9a, 0x30, 0x08, 0xa3, 0x09, 0xc4, 0x30, 0x62, 0x70, 0x00, + 0x20, 0x08, 0x06, 0x8d, 0x1b, 0x60, 0x54, 0x19, 0x8c, 0x26, 0x04, 0xc0, + 0x68, 0x82, 0x10, 0x8c, 0x26, 0x0c, 0xc2, 0x68, 0x02, 0x31, 0x8c, 0x18, + 0x1c, 0x00, 0x08, 0x82, 0x41, 0x33, 0x07, 0x5d, 0xc6, 0x06, 0xa3, 0x09, + 0x01, 0x30, 0x9a, 0x20, 0x04, 0xa3, 0x09, 0x83, 0x30, 0x9a, 0x40, 0x0c, + 0x36, 0x5d, 0xf2, 0x19, 0x31, 0x40, 0x00, 0x10, 0x04, 0x83, 0x07, 0x0f, + 0xce, 0xe0, 0x7a, 0x82, 0x11, 0x03, 0x04, 0x00, 0x41, 0x30, 0x78, 0xf2, + 0x00, 0x0d, 0xae, 0x25, 0xb0, 0xe0, 0x80, 0x8e, 0x59, 0x9b, 0x7c, 0x46, + 0x0c, 0x10, 0x00, 0x04, 0xc1, 0xe0, 0xe1, 0x83, 0x35, 0xd8, 0xa4, 0x60, + 0xc4, 0x00, 0x01, 0x40, 0x10, 0x0c, 0x9e, 0x3e, 0x60, 0x83, 0xcd, 0x09, + 0x2c, 0x50, 0xa0, 0x63, 0xd9, 0x27, 0x9f, 0x11, 0x03, 0x04, 0x00, 0x41, + 0x30, 0x78, 0x40, 0xe1, 0x0d, 0xbe, 0x2a, 0x18, 0x31, 0x40, 0x00, 0x10, + 0x04, 0x83, 0x27, 0x14, 0xe0, 0xe0, 0x8b, 0x02, 0x0b, 0x1a, 0xe8, 0x18, + 0x37, 0x06, 0xf2, 0x19, 0x31, 0x40, 0x00, 0x10, 0x04, 0x83, 0x87, 0x14, + 0xe6, 0x60, 0x0c, 0xb0, 0x60, 0xc4, 0x00, 0x01, 0x40, 0x10, 0x0c, 0x9e, + 0x52, 0xa0, 0x83, 0x31, 0xa0, 0x02, 0x0b, 0x20, 0xe8, 0x8c, 0x18, 0x1c, + 0x00, 0x08, 0x82, 0x41, 0x83, 0x0a, 0x72, 0xe0, 0x06, 0x74, 0x30, 0x9a, + 0x10, 0x00, 0xa3, 0x09, 0x42, 0x30, 0x9a, 0x30, 0x08, 0xa3, 0x09, 0xc4, + 0x30, 0x62, 0x70, 0x00, 0x20, 0x08, 0x06, 0x4d, 0x2b, 0xdc, 0xc1, 0x1c, + 0xe8, 0xc1, 0x68, 0x42, 0x00, 0x8c, 0x26, 0x08, 0xc1, 0x68, 0xc2, 0x20, + 0x8c, 0x26, 0x10, 0xc3, 0x88, 0xc1, 0x01, 0x80, 0x20, 0x18, 0x34, 0xb2, + 0xc0, 0x07, 0x78, 0xd0, 0x0a, 0xa3, 0x09, 0x01, 0x30, 0x9a, 0x20, 0x04, + 0xa3, 0x09, 0x83, 0x30, 0x9a, 0x40, 0x0c, 0x23, 0x06, 0x07, 0x00, 0x82, + 0x60, 0xd0, 0xdc, 0x42, 0x28, 0xf4, 0xc1, 0x2b, 0x8c, 0x26, 0x04, 0xc0, + 0x68, 0x82, 0x10, 0x8c, 0x26, 0x0c, 0xc2, 0x68, 0x02, 0x31, 0xd8, 0x14, + 0x06, 0xf2, 0x19, 0x31, 0x40, 0x00, 0x10, 0x04, 0x83, 0x87, 0x17, 0x56, + 0xc1, 0x7b, 0x82, 0x11, 0x03, 0x04, 0x00, 0x41, 0x30, 0x78, 0x7a, 0x81, + 0x15, 0xb6, 0x25, 0x18, 0x31, 0x40, 0x00, 0x10, 0x04, 0x83, 0xc7, 0x17, + 0x5a, 0x01, 0x3b, 0x02, 0xb3, 0xca, 0x40, 0x3e, 0x23, 0x06, 0x08, 0x00, + 0x82, 0x60, 0xf0, 0x80, 0xc3, 0x2b, 0x88, 0x81, 0x14, 0x8c, 0x18, 0x20, + 0x00, 0x08, 0x82, 0xc1, 0x13, 0x0e, 0xb0, 0xf0, 0x39, 0xc1, 0x88, 0x01, + 0x02, 0x80, 0x20, 0x18, 0x3c, 0xe2, 0x10, 0x0b, 0x9c, 0x12, 0x58, 0x96, + 0x06, 0xf2, 0x19, 0x31, 0x40, 0x00, 0x10, 0x04, 0x83, 0x87, 0x1c, 0x66, + 0xc1, 0x0c, 0xaa, 0x60, 0xc4, 0x00, 0x01, 0x40, 0x10, 0x0c, 0x9e, 0x72, + 0xa0, 0x85, 0x31, 0x88, 0x82, 0x11, 0x03, 0x04, 0x00, 0x41, 0x30, 0x78, + 0xcc, 0xa1, 0x16, 0xc0, 0xa0, 0x09, 0x8c, 0x6b, 0x03, 0xf9, 0x8c, 0x18, + 0x20, 0x00, 0x08, 0x82, 0xc1, 0x83, 0x0e, 0xb7, 0xa0, 0x06, 0x58, 0x30, + 0x62, 0x80, 0x00, 0x20, 0x08, 0x06, 0x4f, 0x3a, 0xe0, 0xc2, 0x19, 0x50, + 0xc1, 0x88, 0x01, 0x02, 0x80, 0x20, 0x18, 0x3c, 0xea, 0x90, 0x0b, 0x64, + 0x00, 0x05, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x80, 0xb4, 0x43, 0x2e, + 0xa0, 0x03, 0x3a, 0x80, 0x43, 0x33, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, + 0x48, 0x3b, 0xe4, 0x02, 0x3a, 0xa0, 0x03, 0x2d, 0x24, 0x23, 0x06, 0x09, + 0x00, 0x82, 0x60, 0x80, 0xb4, 0x43, 0x2e, 0xa0, 0x03, 0x3a, 0xf8, 0x42, + 0x31, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x48, 0x3b, 0xe4, 0x02, 0x3a, + 0xa0, 0xc3, 0x2f, 0x04, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x80, 0xb4, + 0x43, 0x2e, 0xa4, 0x03, 0x3a, 0x80, 0x43, 0x2b, 0x8c, 0x18, 0x24, 0x00, + 0x08, 0x82, 0x01, 0xd2, 0x0e, 0xb9, 0x90, 0x0e, 0xe8, 0x40, 0x0b, 0xac, + 0x30, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x48, 0x3b, 0xe4, 0xc2, 0x38, + 0xa0, 0x03, 0x38, 0xc4, 0xc2, 0x88, 0x41, 0x02, 0x80, 0x20, 0x18, 0x20, + 0xed, 0x90, 0x0b, 0xe3, 0x80, 0x0e, 0xb4, 0x00, 0x0b, 0x23, 0x06, 0x09, + 0x00, 0x82, 0x60, 0x80, 0xb4, 0x43, 0x2e, 0x8c, 0x03, 0x3a, 0xf8, 0xc2, + 0x2b, 0x8c, 0x18, 0x24, 0x00, 0x08, 0x82, 0x01, 0xd2, 0x0e, 0xb9, 0x30, + 0x0e, 0xe8, 0xf0, 0x0b, 0xae, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static unsigned char D3D12_VertexShader_Textures[] = { + 0x44, 0x58, 0x42, 0x43, 0x64, 0x78, 0x9b, 0xaf, 0x0d, 0x1f, 0x5b, 0x33, + 0xd2, 0x5e, 0x6d, 0x7f, 0x5d, 0x5c, 0xd1, 0x9d, 0x01, 0x00, 0x00, 0x00, + 0x4b, 0x14, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0xd8, 0x00, 0x00, 0x00, 0x63, 0x01, 0x00, 0x00, + 0x73, 0x02, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x03, 0x0b, 0x00, 0x00, + 0x1f, 0x0b, 0x00, 0x00, 0x53, 0x46, 0x49, 0x30, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31, + 0x80, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x54, 0x45, 0x58, + 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, + 0x4f, 0x53, 0x47, 0x31, 0x83, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x03, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, + 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x50, 0x53, 0x56, 0x30, 0x08, + 0x01, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x03, + 0x03, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, + 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x54, 0x45, 0x58, + 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, + 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x43, 0x4f, 0x4c, + 0x4f, 0x52, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x43, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x01, 0x42, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x44, 0x03, 0x03, 0x04, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x01, 0x42, 0x00, 0x03, 0x02, 0x00, 0x00, 0x22, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, 0x03, + 0x02, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x52, 0x54, 0x53, 0x30, 0x88, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x70, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xff, 0xff, 0x53, 0x54, 0x41, 0x54, 0xf8, 0x07, 0x00, 0x00, 0x60, + 0x00, 0x01, 0x00, 0xfe, 0x01, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c, 0x00, + 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x42, + 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0xf5, 0x01, 0x00, 0x00, 0x0b, + 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, + 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, + 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, + 0x18, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xc4, 0x10, 0x32, 0x14, 0x38, + 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x62, 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, + 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4, 0x48, 0x0e, 0x90, 0x11, + 0x23, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, + 0x31, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1b, + 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40, 0x02, 0xa8, 0x0d, 0x84, + 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x20, 0x6d, 0x30, 0x86, 0xff, 0xff, + 0xff, 0xff, 0x1f, 0x00, 0x09, 0xa8, 0x00, 0x49, 0x18, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, 0x42, 0x20, 0x4c, 0x08, 0x06, 0x00, + 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x32, + 0x22, 0x88, 0x09, 0x20, 0x64, 0x85, 0x04, 0x13, 0x23, 0xa4, 0x84, 0x04, + 0x13, 0x23, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8c, 0x8c, 0x0b, + 0x84, 0xc4, 0x4c, 0x10, 0x88, 0xc1, 0x0c, 0xc0, 0x30, 0x02, 0x01, 0x24, + 0x41, 0x70, 0x70, 0x30, 0x5c, 0x3e, 0xb0, 0x20, 0x46, 0xc3, 0x10, 0xcd, + 0xe4, 0x2f, 0x84, 0x01, 0x08, 0x98, 0x2f, 0x4d, 0x11, 0x25, 0x4c, 0xfe, + 0x4b, 0x44, 0x13, 0x71, 0xb1, 0x07, 0x30, 0x10, 0x11, 0xe7, 0x34, 0xd2, + 0x04, 0x34, 0x93, 0x84, 0x04, 0x41, 0xb8, 0x6e, 0xb8, 0x7c, 0x60, 0x41, + 0x8c, 0x86, 0x21, 0x9a, 0xc9, 0x5f, 0x08, 0x03, 0x10, 0x30, 0x9f, 0x73, + 0x1a, 0x69, 0x02, 0x9a, 0x49, 0x42, 0xc1, 0x40, 0xc4, 0x08, 0x40, 0x09, + 0x0c, 0x3a, 0xe6, 0x08, 0xc0, 0x60, 0x8e, 0x00, 0x29, 0x06, 0x90, 0x24, + 0x89, 0x92, 0xd0, 0x52, 0x0c, 0x23, 0x49, 0x12, 0x05, 0xa0, 0xe6, 0xa8, + 0xe1, 0xf2, 0x27, 0xec, 0x21, 0x24, 0x9f, 0xdb, 0xa8, 0x62, 0x25, 0x26, + 0xbf, 0xb8, 0x6d, 0x44, 0x00, 0x00, 0x00, 0x90, 0x72, 0xcf, 0x70, 0xf9, + 0x13, 0xf6, 0x10, 0x92, 0x1f, 0x02, 0xcd, 0xb0, 0x10, 0x28, 0x80, 0x0a, + 0xf1, 0x24, 0x51, 0x42, 0x52, 0x29, 0x80, 0x04, 0x00, 0x00, 0xa2, 0xe6, + 0x08, 0x82, 0x62, 0x44, 0x89, 0x92, 0x24, 0x16, 0x5d, 0x03, 0x01, 0x67, + 0x09, 0x0b, 0x20, 0x49, 0x3e, 0x03, 0x4c, 0x11, 0x72, 0xf9, 0xc5, 0xe2, + 0x00, 0x93, 0x8f, 0xfb, 0x38, 0x0a, 0x84, 0xe3, 0xa4, 0x29, 0xa2, 0x84, + 0xc9, 0x7f, 0x89, 0x68, 0x22, 0x2e, 0xf6, 0x00, 0x06, 0x22, 0xe2, 0x9c, + 0x46, 0x9a, 0x80, 0x66, 0x92, 0x90, 0xa0, 0x69, 0xc3, 0x08, 0x02, 0x70, + 0x99, 0x34, 0x45, 0x94, 0x30, 0xf9, 0x2f, 0x11, 0x4d, 0xc4, 0xc5, 0x1e, + 0xc0, 0x40, 0x44, 0x28, 0x35, 0x3d, 0xd4, 0x84, 0x86, 0x80, 0x0b, 0x86, + 0x11, 0x06, 0xe0, 0x30, 0x69, 0x8a, 0x28, 0x61, 0xf2, 0x5f, 0x22, 0x9a, + 0x88, 0x8b, 0x3d, 0x80, 0x81, 0x88, 0xc4, 0xe6, 0xa1, 0x26, 0x34, 0x78, + 0x5c, 0x70, 0x09, 0xe7, 0x34, 0xd2, 0x04, 0x34, 0x93, 0x84, 0x82, 0x2d, + 0x1d, 0x12, 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, + 0x68, 0x87, 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e, + 0x6d, 0xd0, 0x0e, 0x7a, 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07, + 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, + 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, 0x20, 0x07, + 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, + 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, + 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x10, 0x07, + 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, + 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, + 0x76, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, + 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x3a, 0x0f, 0x64, + 0x90, 0x21, 0x23, 0x25, 0x40, 0x00, 0x52, 0x00, 0xc0, 0x90, 0xe7, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x21, 0xcf, + 0x02, 0x04, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, + 0x9e, 0x06, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x86, 0x3c, 0x12, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x79, 0x28, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0xf2, 0x5c, 0x40, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x90, 0x05, 0x02, 0x00, 0x19, 0x00, 0x00, 0x00, 0x32, + 0x1e, 0x98, 0x18, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, + 0x04, 0x43, 0x52, 0x0a, 0xa1, 0x08, 0xca, 0x80, 0x92, 0x12, 0x18, 0x01, + 0x28, 0x86, 0x02, 0x14, 0x28, 0x82, 0x42, 0x28, 0x83, 0x72, 0x28, 0x89, + 0x02, 0x0c, 0x28, 0xb0, 0x02, 0x29, 0xa0, 0xf2, 0x28, 0x8c, 0xd2, 0x0d, + 0x28, 0x0a, 0x52, 0x4a, 0x62, 0x04, 0x80, 0x8a, 0x19, 0x00, 0x22, 0x66, + 0x00, 0x68, 0x98, 0x01, 0xa0, 0x6d, 0x06, 0x80, 0xba, 0x19, 0x00, 0xfa, + 0x66, 0x00, 0x08, 0x9c, 0x01, 0xa0, 0x70, 0x2c, 0x87, 0x61, 0x9e, 0xe7, + 0x01, 0x20, 0x30, 0x00, 0x00, 0x10, 0x01, 0x21, 0x10, 0x0c, 0x40, 0x50, + 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, 0x1a, + 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, 0x44, 0x35, 0x18, 0x63, 0x0b, 0x73, + 0x3b, 0x03, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x03, 0x99, 0x71, + 0xb9, 0x01, 0x41, 0xa1, 0x0b, 0x3b, 0x9b, 0x7b, 0x91, 0x2a, 0x62, 0x2a, + 0x0a, 0x9a, 0x2a, 0xfa, 0x9a, 0xb9, 0x81, 0x79, 0x31, 0x4b, 0x73, 0x0b, + 0x63, 0x4b, 0xd9, 0x10, 0x04, 0x13, 0x84, 0x44, 0x99, 0x20, 0x24, 0xcb, + 0x06, 0x61, 0x20, 0x36, 0x08, 0x04, 0x41, 0xc1, 0x6e, 0x6e, 0x82, 0x90, + 0x30, 0x1b, 0x86, 0x03, 0x21, 0x26, 0x08, 0x45, 0xc7, 0x64, 0xe8, 0xcd, + 0x6d, 0x8e, 0x2e, 0xcc, 0x8d, 0x6e, 0x6e, 0x82, 0x90, 0x34, 0x1b, 0x10, + 0x42, 0x59, 0x08, 0x62, 0x60, 0x80, 0x0d, 0x41, 0xb3, 0x81, 0x00, 0x00, + 0x07, 0x98, 0x20, 0x6c, 0x60, 0xc0, 0xa2, 0xed, 0x8d, 0xac, 0x8c, 0x6d, + 0x82, 0x90, 0x38, 0x13, 0x84, 0xe4, 0xd9, 0x30, 0x4c, 0xd3, 0x30, 0x41, + 0x48, 0xa0, 0x09, 0x42, 0x12, 0x4d, 0x10, 0x12, 0x69, 0x03, 0x82, 0x44, + 0x12, 0x55, 0x11, 0xd6, 0xc5, 0x08, 0x4e, 0xee, 0x4d, 0xad, 0x6c, 0x8c, + 0x2e, 0xed, 0xcd, 0x2d, 0xc8, 0x8d, 0xcc, 0x2a, 0xad, 0xec, 0x6e, 0x82, + 0x90, 0x4c, 0x1b, 0x10, 0x24, 0x93, 0xa8, 0x4a, 0xb3, 0xae, 0x0d, 0x03, + 0x83, 0x6d, 0x13, 0x84, 0x2e, 0x0c, 0x26, 0x08, 0x09, 0xc5, 0x01, 0xee, + 0x6d, 0x8e, 0xcb, 0x94, 0xd5, 0x17, 0xd4, 0xd3, 0x54, 0x12, 0x55, 0xd2, + 0x93, 0xd3, 0x06, 0x04, 0xf9, 0x2a, 0x62, 0x02, 0x03, 0xeb, 0xe2, 0x40, + 0x57, 0x86, 0x37, 0x41, 0x48, 0x2a, 0x26, 0x54, 0x45, 0x58, 0x43, 0x4f, + 0x4f, 0x52, 0x44, 0x30, 0x1b, 0x10, 0x44, 0x0c, 0xaa, 0x31, 0x98, 0xc8, + 0xc0, 0xba, 0x58, 0x8c, 0xbd, 0xb1, 0xbd, 0xc9, 0x4d, 0x10, 0x12, 0x8b, + 0xc6, 0xd0, 0x13, 0xd3, 0x93, 0x14, 0xcc, 0x06, 0x04, 0x31, 0x83, 0xea, + 0x0c, 0x26, 0x34, 0xb0, 0xae, 0x0d, 0x84, 0x17, 0x06, 0x65, 0x90, 0x06, + 0x13, 0x84, 0x4f, 0x0c, 0x88, 0x40, 0x3d, 0x4d, 0x25, 0x51, 0x25, 0x3d, + 0x39, 0x6d, 0x40, 0x90, 0xaf, 0x22, 0x26, 0x36, 0xb0, 0xae, 0x0d, 0x84, + 0xd7, 0x06, 0x65, 0x90, 0x06, 0x13, 0x04, 0x30, 0x18, 0x83, 0x0d, 0x04, + 0xb2, 0x54, 0xc4, 0x06, 0x81, 0x81, 0x83, 0x09, 0xc2, 0xf0, 0x4d, 0x10, + 0x08, 0x6f, 0x43, 0x43, 0x40, 0x5c, 0xa7, 0x06, 0x6b, 0xe0, 0x06, 0x6f, + 0x10, 0x07, 0x72, 0xc0, 0xcd, 0x41, 0x1c, 0x4c, 0x10, 0x90, 0x60, 0x03, + 0xb0, 0x61, 0x20, 0xec, 0xc0, 0x0e, 0x36, 0x04, 0x77, 0xb0, 0x61, 0x18, + 0xea, 0x00, 0x0f, 0x26, 0x08, 0x61, 0x40, 0x06, 0x1b, 0x02, 0x3d, 0xe0, + 0xd2, 0x16, 0x96, 0xe6, 0x46, 0x55, 0x86, 0x47, 0x57, 0x27, 0x57, 0x36, + 0x41, 0x50, 0xb6, 0x09, 0x82, 0xc2, 0x6d, 0x08, 0x88, 0x09, 0x82, 0x92, + 0x6c, 0x10, 0x2a, 0x6b, 0xc3, 0x42, 0xb0, 0x41, 0x1f, 0xf8, 0xc1, 0x1f, + 0xf8, 0xc1, 0x00, 0x0a, 0x84, 0x1f, 0x84, 0x02, 0x11, 0xaa, 0x22, 0xac, + 0xa1, 0xa7, 0x27, 0x29, 0xa2, 0x09, 0x82, 0x82, 0x6c, 0x10, 0xaa, 0x6a, + 0xc3, 0x32, 0x8c, 0x42, 0x1f, 0xf8, 0xc1, 0x1f, 0xf8, 0xc1, 0x40, 0x0a, + 0x83, 0x1f, 0x94, 0x02, 0x8b, 0xa1, 0x27, 0xa6, 0x27, 0xa9, 0x09, 0x82, + 0x72, 0x4c, 0x10, 0x92, 0x6b, 0x83, 0x50, 0xa5, 0xc2, 0x86, 0x45, 0x3a, + 0x85, 0x3e, 0xf0, 0x83, 0x3f, 0xf0, 0x83, 0x01, 0x15, 0x24, 0x3f, 0x50, + 0x85, 0x0d, 0x83, 0x28, 0x98, 0xc2, 0x2a, 0x70, 0x99, 0xb2, 0xfa, 0x82, + 0x7a, 0x9b, 0x4b, 0xa3, 0x4b, 0x7b, 0x73, 0xdb, 0xb0, 0x10, 0xad, 0xd0, + 0x07, 0xa0, 0xf0, 0x07, 0xa8, 0x30, 0xa0, 0x02, 0xe1, 0x07, 0xaa, 0xb0, + 0x61, 0x19, 0x46, 0xa1, 0x0f, 0xfc, 0xe0, 0x0f, 0x48, 0x61, 0x20, 0x85, + 0xc1, 0x0f, 0x4a, 0x61, 0xc3, 0x22, 0x9d, 0x42, 0x1f, 0xf8, 0xc1, 0x1f, + 0x90, 0xc2, 0x80, 0x0a, 0x92, 0x1f, 0xa8, 0xc2, 0x86, 0xc1, 0x15, 0x5e, + 0x01, 0x16, 0x36, 0x0c, 0xac, 0x10, 0x0b, 0xc0, 0x86, 0xa2, 0x0e, 0xf8, + 0x40, 0x16, 0x1e, 0x80, 0x86, 0x19, 0xdb, 0x5b, 0x18, 0xdd, 0xdc, 0x04, + 0x21, 0xc1, 0x58, 0xa4, 0xb9, 0xcd, 0xd1, 0xcd, 0x4d, 0x10, 0x92, 0x8c, + 0xc6, 0x5c, 0xda, 0xd9, 0x17, 0x1b, 0x19, 0x8d, 0xb9, 0xb4, 0xb3, 0xaf, + 0x39, 0xba, 0x09, 0x42, 0xa2, 0x6d, 0x40, 0x68, 0xa1, 0x16, 0x6c, 0xe1, + 0x16, 0x70, 0xe1, 0xca, 0x05, 0x5d, 0xa8, 0xc2, 0xc6, 0x66, 0xd7, 0xe6, + 0x92, 0x46, 0x56, 0xe6, 0x46, 0x37, 0x25, 0x08, 0xaa, 0x90, 0xe1, 0xb9, + 0xd8, 0x95, 0xc9, 0xcd, 0xa5, 0xbd, 0xb9, 0x4d, 0x09, 0x88, 0x26, 0x64, + 0x78, 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x65, 0x72, 0x53, 0x82, 0xa2, 0x0e, + 0x19, 0x9e, 0xcb, 0x1c, 0x5a, 0x18, 0x59, 0x99, 0x5c, 0xd3, 0x1b, 0x59, + 0x19, 0xdb, 0x94, 0x00, 0x29, 0x43, 0x86, 0xe7, 0x22, 0x57, 0x36, 0xf7, + 0x56, 0x27, 0x37, 0x56, 0x36, 0x37, 0x25, 0x70, 0x2a, 0x91, 0xe1, 0xb9, + 0xd0, 0xe5, 0xc1, 0x95, 0x05, 0xb9, 0xb9, 0xbd, 0xd1, 0x85, 0xd1, 0xa5, + 0xbd, 0xb9, 0xcd, 0x4d, 0x11, 0xe6, 0x00, 0x0f, 0xea, 0x90, 0xe1, 0xb9, + 0xd8, 0xa5, 0x95, 0xdd, 0x25, 0x91, 0x4d, 0xd1, 0x85, 0xd1, 0x95, 0x4d, + 0x09, 0xf4, 0xa0, 0x0e, 0x19, 0x9e, 0x4b, 0x99, 0x1b, 0x9d, 0x5c, 0x1e, + 0xd4, 0x5b, 0x9a, 0x1b, 0xdd, 0xdc, 0x94, 0x40, 0x16, 0xba, 0x90, 0xe1, + 0xb9, 0x8c, 0xbd, 0xd5, 0xb9, 0xd1, 0x95, 0xc9, 0xcd, 0x4d, 0x09, 0x74, + 0x01, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x33, + 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, + 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, + 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, + 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, + 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, + 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, + 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, + 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, + 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, + 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, + 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, + 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, + 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, + 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, + 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, + 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, + 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, + 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, + 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, + 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, + 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, + 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x8c, 0xc8, 0x21, + 0x07, 0x7c, 0x70, 0x03, 0x72, 0x10, 0x87, 0x73, 0x70, 0x03, 0x7b, 0x08, + 0x07, 0x79, 0x60, 0x87, 0x70, 0xc8, 0x87, 0x77, 0xa8, 0x07, 0x7a, 0x00, + 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x06, + 0x00, 0x71, 0x4e, 0x23, 0x4d, 0x40, 0x33, 0x49, 0xff, 0x42, 0x18, 0x80, + 0x80, 0x19, 0xc1, 0x36, 0x5c, 0xbe, 0xf3, 0xf8, 0x42, 0x40, 0x15, 0x05, + 0x11, 0x95, 0x0e, 0x30, 0x94, 0x84, 0x01, 0x08, 0x98, 0x5f, 0xdc, 0xb6, + 0x19, 0x48, 0xc3, 0xe5, 0x3b, 0x8f, 0x2f, 0x44, 0x04, 0x30, 0x11, 0x21, + 0xd0, 0x0c, 0x0b, 0x61, 0x02, 0xd3, 0x70, 0xf9, 0xce, 0xe3, 0x2f, 0x0e, + 0x30, 0x88, 0xcd, 0x43, 0x4d, 0x7e, 0x71, 0xdb, 0x36, 0x50, 0x0d, 0x97, + 0xef, 0x3c, 0xbe, 0x34, 0x39, 0x11, 0x81, 0x52, 0xd3, 0x43, 0x4d, 0x7e, + 0x71, 0xdb, 0x56, 0x20, 0x0d, 0x97, 0xef, 0x3c, 0xfe, 0x44, 0x44, 0x13, + 0x02, 0x44, 0x98, 0x5f, 0xdc, 0xb6, 0x05, 0x2c, 0x0c, 0x80, 0x34, 0x2d, + 0x71, 0x4d, 0x54, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, + 0x41, 0x53, 0x48, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, + 0xa0, 0xdd, 0xa0, 0xcf, 0x1a, 0x5f, 0x65, 0x5e, 0xda, 0x32, 0xf3, 0x80, + 0x17, 0x51, 0x70, 0x44, 0x58, 0x49, 0x4c, 0x24, 0x09, 0x00, 0x00, 0x60, + 0x00, 0x01, 0x00, 0x49, 0x02, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c, 0x00, + 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0c, 0x09, 0x00, 0x00, 0x42, + 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x0b, + 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, + 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, + 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, + 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, + 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, + 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4, 0x48, 0x0e, 0x90, 0x91, + 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, + 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1b, + 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40, 0x02, 0xa8, 0x0d, 0x84, + 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x20, 0x6d, 0x30, 0x86, 0xff, 0xff, + 0xff, 0xff, 0x1f, 0x00, 0x09, 0xa8, 0x00, 0x49, 0x18, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, 0x42, 0x20, 0x4c, 0x08, 0x06, 0x00, + 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x32, + 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, + 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, + 0x84, 0xa4, 0x4c, 0x10, 0x6c, 0x23, 0x00, 0x25, 0x00, 0x14, 0x66, 0x00, + 0xe6, 0x08, 0xc0, 0x60, 0x8e, 0x00, 0x29, 0xc6, 0x20, 0x84, 0x14, 0x42, + 0xa6, 0x18, 0x80, 0x10, 0x52, 0x06, 0xa1, 0xa3, 0x86, 0xcb, 0x9f, 0xb0, + 0x87, 0x90, 0x7c, 0x6e, 0xa3, 0x8a, 0x95, 0x98, 0xfc, 0xe2, 0xb6, 0x11, + 0x31, 0xc6, 0x18, 0x54, 0xee, 0x19, 0x2e, 0x7f, 0xc2, 0x1e, 0x42, 0xf2, + 0x43, 0xa0, 0x19, 0x16, 0x02, 0x05, 0xab, 0x10, 0x8a, 0x30, 0x42, 0xad, + 0x14, 0x83, 0x8c, 0x31, 0xe8, 0xcd, 0x11, 0x04, 0xc5, 0x60, 0xa4, 0x10, + 0x12, 0x49, 0x0e, 0x04, 0x0c, 0x23, 0x10, 0x43, 0x12, 0xd4, 0x83, 0x83, + 0xe1, 0xf2, 0x81, 0x05, 0x31, 0x1a, 0x86, 0x68, 0x26, 0x7f, 0x21, 0x0c, + 0x40, 0xc0, 0x7c, 0x69, 0x8a, 0x28, 0x61, 0xf2, 0x5f, 0x22, 0x9a, 0x88, + 0x8b, 0x3d, 0x80, 0x81, 0x88, 0x38, 0xa7, 0x91, 0x26, 0xa0, 0x99, 0x24, + 0x24, 0x58, 0x7b, 0xdd, 0x70, 0xf9, 0xc0, 0x82, 0x18, 0x0d, 0x43, 0x34, + 0x93, 0xbf, 0x10, 0x06, 0x20, 0x60, 0x3e, 0xe7, 0x34, 0xd2, 0x04, 0x34, + 0x93, 0x84, 0x82, 0x4b, 0x38, 0x1d, 0x08, 0x00, 0x00, 0x00, 0x00, 0x13, + 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, 0x79, 0x68, + 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e, 0x6d, 0xd0, 0x0e, 0x7a, + 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, + 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, + 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, + 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, + 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, + 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, + 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, + 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, + 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x43, 0x9e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x3c, 0x06, 0x10, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x79, 0x10, 0x20, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf2, 0x34, 0x40, + 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xe4, 0x79, + 0x80, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xc8, + 0x23, 0x01, 0x01, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x16, 0x08, 0x00, 0x10, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x14, 0x19, + 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x22, 0x25, + 0x30, 0x02, 0x50, 0x0c, 0x05, 0x28, 0x50, 0x06, 0xe5, 0x50, 0x04, 0xe5, + 0x41, 0xa5, 0x24, 0x46, 0x00, 0xca, 0xa0, 0x08, 0x0a, 0x81, 0xf2, 0x0c, + 0x00, 0xe9, 0xb1, 0x1c, 0x86, 0x79, 0x9e, 0x07, 0x80, 0xc0, 0x00, 0x00, + 0x40, 0x04, 0x84, 0x40, 0x30, 0x00, 0x41, 0x01, 0x00, 0x00, 0x00, 0x79, + 0x18, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x90, 0x46, + 0x02, 0x13, 0x44, 0x35, 0x18, 0x63, 0x0b, 0x73, 0x3b, 0x03, 0xb1, 0x2b, + 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x03, 0x99, 0x71, 0xb9, 0x01, 0x41, 0xa1, + 0x0b, 0x3b, 0x9b, 0x7b, 0x91, 0x2a, 0x62, 0x2a, 0x0a, 0x9a, 0x2a, 0xfa, + 0x9a, 0xb9, 0x81, 0x79, 0x31, 0x4b, 0x73, 0x0b, 0x63, 0x4b, 0xd9, 0x10, + 0x04, 0x13, 0x04, 0xc2, 0x98, 0x20, 0x10, 0xc7, 0x06, 0x61, 0x20, 0x26, + 0x08, 0x04, 0xb2, 0x41, 0x18, 0x0c, 0x0a, 0x76, 0x73, 0x1b, 0x06, 0xc4, + 0x20, 0x26, 0x08, 0xd9, 0x44, 0x60, 0x82, 0x40, 0x24, 0x1b, 0x10, 0x42, + 0x59, 0x08, 0x62, 0x60, 0x80, 0x0d, 0x41, 0xb3, 0x81, 0x00, 0x00, 0x07, + 0x98, 0x20, 0x68, 0xd4, 0x86, 0x00, 0x9a, 0x20, 0x08, 0x00, 0x97, 0xb6, + 0xb0, 0x34, 0x37, 0xaa, 0x32, 0x3c, 0xba, 0x3a, 0xb9, 0x32, 0x22, 0x50, + 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x13, 0x84, 0xc2, 0x99, 0x20, + 0x14, 0xcf, 0x86, 0x80, 0x98, 0x20, 0x14, 0xd0, 0x04, 0x81, 0x50, 0x26, + 0x08, 0xc4, 0xb2, 0x41, 0xc8, 0xb4, 0x0d, 0x0b, 0x41, 0x55, 0xd6, 0x65, + 0x0d, 0x18, 0x61, 0x6d, 0x44, 0xa8, 0x8a, 0xb0, 0x86, 0x9e, 0x9e, 0xa4, + 0x88, 0x26, 0x08, 0x45, 0xb4, 0x41, 0xc8, 0xb2, 0x0d, 0xcb, 0xd0, 0x55, + 0xd6, 0x65, 0x0d, 0xde, 0x60, 0x7d, 0x13, 0x04, 0x82, 0x61, 0x31, 0xf4, + 0xc4, 0xf4, 0x24, 0x35, 0x41, 0x28, 0xa4, 0x09, 0x02, 0xd1, 0x6c, 0x10, + 0x32, 0x32, 0xd8, 0xb0, 0x84, 0x81, 0x18, 0x54, 0xd6, 0x65, 0x0d, 0x63, + 0x10, 0x06, 0x56, 0x19, 0x6c, 0x18, 0x38, 0x30, 0x30, 0x03, 0x2e, 0x53, + 0x56, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x1b, 0x16, + 0x02, 0x0d, 0x2a, 0xec, 0x1a, 0x83, 0x61, 0x0c, 0x08, 0xab, 0x0c, 0x36, + 0x2c, 0x43, 0x57, 0x59, 0x97, 0x37, 0x78, 0x83, 0xf5, 0x6d, 0x58, 0xc2, + 0x40, 0x0c, 0x2a, 0xeb, 0xf2, 0x86, 0x31, 0x08, 0x03, 0xab, 0x0c, 0x36, + 0x0c, 0x69, 0xa0, 0x06, 0x6b, 0xb0, 0x61, 0x38, 0x03, 0x36, 0x00, 0x36, + 0x14, 0xd2, 0xd4, 0x06, 0x0f, 0x50, 0x85, 0x8d, 0xcd, 0xae, 0xcd, 0x25, + 0x8d, 0xac, 0xcc, 0x8d, 0x6e, 0x4a, 0x10, 0x54, 0x21, 0xc3, 0x73, 0xb1, + 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x9b, 0x12, 0x10, 0x4d, 0xc8, 0xf0, + 0x5c, 0xec, 0xc2, 0xd8, 0xec, 0xca, 0xe4, 0xa6, 0x04, 0x46, 0x1d, 0x32, + 0x3c, 0x97, 0x39, 0xb4, 0x30, 0xb2, 0x32, 0xb9, 0xa6, 0x37, 0xb2, 0x32, + 0xb6, 0x29, 0x01, 0x52, 0x86, 0x0c, 0xcf, 0x45, 0xae, 0x6c, 0xee, 0xad, + 0x4e, 0x6e, 0xac, 0x6c, 0x6e, 0x4a, 0xe0, 0xd4, 0x21, 0xc3, 0x73, 0xb1, + 0x4b, 0x2b, 0xbb, 0x4b, 0x22, 0x9b, 0xa2, 0x0b, 0xa3, 0x2b, 0x9b, 0x12, + 0x40, 0x75, 0xc8, 0xf0, 0x5c, 0xca, 0xdc, 0xe8, 0xe4, 0xf2, 0xa0, 0xde, + 0xd2, 0xdc, 0xe8, 0xe6, 0xa6, 0x04, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x79, + 0x18, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, + 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, + 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, + 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, + 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, + 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, + 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, + 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, + 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, + 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, + 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, + 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, + 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, + 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, + 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, + 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, + 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, + 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, + 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, + 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, + 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, + 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, + 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x8c, 0xc8, 0x21, 0x07, 0x7c, 0x70, 0x03, + 0x72, 0x10, 0x87, 0x73, 0x70, 0x03, 0x7b, 0x08, 0x07, 0x79, 0x60, 0x87, + 0x70, 0xc8, 0x87, 0x77, 0xa8, 0x07, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x71, + 0x20, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x36, 0xb0, 0x0d, 0x97, 0xef, + 0x3c, 0xbe, 0x10, 0x50, 0x45, 0x41, 0x44, 0xa5, 0x03, 0x0c, 0x25, 0x61, + 0x00, 0x02, 0xe6, 0x17, 0xb7, 0x6d, 0x05, 0xd2, 0x70, 0xf9, 0xce, 0xe3, + 0x0b, 0x11, 0x01, 0x4c, 0x44, 0x08, 0x34, 0xc3, 0x42, 0x58, 0xc0, 0x34, + 0x5c, 0xbe, 0xf3, 0xf8, 0x8b, 0x03, 0x0c, 0x62, 0xf3, 0x50, 0x93, 0x5f, + 0xdc, 0xb6, 0x09, 0x54, 0xc3, 0xe5, 0x3b, 0x8f, 0x2f, 0x4d, 0x4e, 0x44, + 0xa0, 0xd4, 0xf4, 0x50, 0x93, 0x5f, 0xdc, 0xb6, 0x11, 0x48, 0xc3, 0xe5, + 0x3b, 0x8f, 0x3f, 0x11, 0xd1, 0x84, 0x00, 0x11, 0xe6, 0x17, 0xb7, 0x6d, + 0x00, 0x0b, 0x03, 0x20, 0x4d, 0x4b, 0x5c, 0x13, 0x15, 0x11, 0x00, 0x61, + 0x20, 0x00, 0x00, 0xcf, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x44, 0x8a, 0xab, 0x14, 0x0a, + 0x61, 0x06, 0xa0, 0xec, 0x4a, 0x8e, 0x4a, 0x09, 0x50, 0x1c, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x20, 0x61, 0x03, + 0x63, 0x59, 0xc1, 0x88, 0x41, 0x02, 0x80, 0x20, 0x18, 0x18, 0xdd, 0x21, + 0x5d, 0x8f, 0x31, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x86, 0x87, 0x4c, + 0x18, 0x71, 0x8c, 0x18, 0x24, 0x00, 0x08, 0x82, 0x81, 0xf1, 0x25, 0x54, + 0xf6, 0x20, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x60, 0x80, 0x81, 0x52, + 0x69, 0x51, 0x32, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x46, 0x18, 0x2c, + 0xdc, 0x36, 0x29, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x60, 0x88, 0x01, + 0xd3, 0x71, 0xc8, 0x32, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0xc6, 0x18, + 0x34, 0x5d, 0x57, 0x31, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x60, 0x90, + 0x81, 0xe3, 0x79, 0x4a, 0x33, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x46, + 0x19, 0x3c, 0xdf, 0x57, 0x39, 0x23, 0x06, 0x07, 0x00, 0x82, 0x60, 0xd0, + 0x90, 0x81, 0xa3, 0x80, 0xc1, 0x68, 0x42, 0x00, 0x8c, 0x26, 0x08, 0xc1, + 0x68, 0xc2, 0x20, 0x8c, 0x26, 0x10, 0xc3, 0x88, 0xc1, 0x01, 0x80, 0x20, + 0x18, 0x34, 0x69, 0x30, 0x3d, 0x66, 0x30, 0x9a, 0x10, 0x00, 0xa3, 0x09, + 0x42, 0x30, 0x9a, 0x30, 0x08, 0xa3, 0x09, 0xc4, 0x30, 0x62, 0x70, 0x00, + 0x20, 0x08, 0x06, 0x8d, 0x1b, 0x60, 0x54, 0x19, 0x8c, 0x26, 0x04, 0xc0, + 0x68, 0x82, 0x10, 0x8c, 0x26, 0x0c, 0xc2, 0x68, 0x02, 0x31, 0x8c, 0x18, + 0x1c, 0x00, 0x08, 0x82, 0x41, 0x33, 0x07, 0x5d, 0xc6, 0x06, 0xa3, 0x09, + 0x01, 0x30, 0x9a, 0x20, 0x04, 0xa3, 0x09, 0x83, 0x30, 0x9a, 0x40, 0x0c, + 0x36, 0x5d, 0xf2, 0x19, 0x31, 0x40, 0x00, 0x10, 0x04, 0x83, 0x07, 0x0f, + 0xce, 0xe0, 0x7a, 0x82, 0x11, 0x03, 0x04, 0x00, 0x41, 0x30, 0x78, 0xf2, + 0x00, 0x0d, 0xae, 0x25, 0xb0, 0xe0, 0x80, 0x8e, 0x59, 0x9b, 0x7c, 0x46, + 0x0c, 0x10, 0x00, 0x04, 0xc1, 0xe0, 0xe1, 0x83, 0x35, 0xd8, 0xa4, 0x60, + 0xc4, 0x00, 0x01, 0x40, 0x10, 0x0c, 0x9e, 0x3e, 0x60, 0x83, 0xcd, 0x09, + 0x2c, 0x50, 0xa0, 0x63, 0xd9, 0x27, 0x9f, 0x11, 0x03, 0x04, 0x00, 0x41, + 0x30, 0x78, 0x40, 0xe1, 0x0d, 0xbe, 0x2a, 0x18, 0x31, 0x40, 0x00, 0x10, + 0x04, 0x83, 0x27, 0x14, 0xe0, 0xe0, 0x8b, 0x02, 0x0b, 0x1a, 0xe8, 0x18, + 0x37, 0x06, 0xf2, 0x19, 0x31, 0x40, 0x00, 0x10, 0x04, 0x83, 0x87, 0x14, + 0xe6, 0x60, 0x0c, 0xb0, 0x60, 0xc4, 0x00, 0x01, 0x40, 0x10, 0x0c, 0x9e, + 0x52, 0xa0, 0x83, 0x31, 0xa0, 0x02, 0x0b, 0x20, 0xe8, 0x8c, 0x18, 0x1c, + 0x00, 0x08, 0x82, 0x41, 0x83, 0x0a, 0x72, 0xe0, 0x06, 0x74, 0x30, 0x9a, + 0x10, 0x00, 0xa3, 0x09, 0x42, 0x30, 0x9a, 0x30, 0x08, 0xa3, 0x09, 0xc4, + 0x30, 0x62, 0x70, 0x00, 0x20, 0x08, 0x06, 0x4d, 0x2b, 0xdc, 0xc1, 0x1c, + 0xe8, 0xc1, 0x68, 0x42, 0x00, 0x8c, 0x26, 0x08, 0xc1, 0x68, 0xc2, 0x20, + 0x8c, 0x26, 0x10, 0xc3, 0x88, 0xc1, 0x01, 0x80, 0x20, 0x18, 0x34, 0xb2, + 0xc0, 0x07, 0x78, 0xd0, 0x0a, 0xa3, 0x09, 0x01, 0x30, 0x9a, 0x20, 0x04, + 0xa3, 0x09, 0x83, 0x30, 0x9a, 0x40, 0x0c, 0x23, 0x06, 0x07, 0x00, 0x82, + 0x60, 0xd0, 0xdc, 0x42, 0x28, 0xf4, 0xc1, 0x2b, 0x8c, 0x26, 0x04, 0xc0, + 0x68, 0x82, 0x10, 0x8c, 0x26, 0x0c, 0xc2, 0x68, 0x02, 0x31, 0xd8, 0x14, + 0x06, 0xf2, 0x19, 0x31, 0x40, 0x00, 0x10, 0x04, 0x83, 0x87, 0x17, 0x56, + 0xc1, 0x7b, 0x82, 0x11, 0x03, 0x04, 0x00, 0x41, 0x30, 0x78, 0x7a, 0x81, + 0x15, 0xb6, 0x25, 0x18, 0x31, 0x40, 0x00, 0x10, 0x04, 0x83, 0xc7, 0x17, + 0x5a, 0x01, 0x3b, 0x02, 0xb3, 0xca, 0x40, 0x3e, 0x23, 0x06, 0x08, 0x00, + 0x82, 0x60, 0xf0, 0x80, 0xc3, 0x2b, 0x88, 0x81, 0x14, 0x8c, 0x18, 0x20, + 0x00, 0x08, 0x82, 0xc1, 0x13, 0x0e, 0xb0, 0xf0, 0x39, 0xc1, 0x88, 0x01, + 0x02, 0x80, 0x20, 0x18, 0x3c, 0xe2, 0x10, 0x0b, 0x9c, 0x12, 0x58, 0x96, + 0x06, 0xf2, 0x19, 0x31, 0x40, 0x00, 0x10, 0x04, 0x83, 0x87, 0x1c, 0x66, + 0xc1, 0x0c, 0xaa, 0x60, 0xc4, 0x00, 0x01, 0x40, 0x10, 0x0c, 0x9e, 0x72, + 0xa0, 0x85, 0x31, 0x88, 0x82, 0x11, 0x03, 0x04, 0x00, 0x41, 0x30, 0x78, + 0xcc, 0xa1, 0x16, 0xc0, 0xa0, 0x09, 0x8c, 0x6b, 0x03, 0xf9, 0x8c, 0x18, + 0x20, 0x00, 0x08, 0x82, 0xc1, 0x83, 0x0e, 0xb7, 0xa0, 0x06, 0x58, 0x30, + 0x62, 0x80, 0x00, 0x20, 0x08, 0x06, 0x4f, 0x3a, 0xe0, 0xc2, 0x19, 0x50, + 0xc1, 0x88, 0x01, 0x02, 0x80, 0x20, 0x18, 0x3c, 0xea, 0x90, 0x0b, 0x64, + 0x00, 0x05, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x80, 0xb4, 0x43, 0x2e, + 0xa0, 0x03, 0x3a, 0x80, 0x43, 0x33, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, + 0x48, 0x3b, 0xe4, 0x02, 0x3a, 0xa0, 0x03, 0x2d, 0x24, 0x23, 0x06, 0x09, + 0x00, 0x82, 0x60, 0x80, 0xb4, 0x43, 0x2e, 0xa0, 0x03, 0x3a, 0xf8, 0x42, + 0x31, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x48, 0x3b, 0xe4, 0x02, 0x3a, + 0xa0, 0xc3, 0x2f, 0x04, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x80, 0xb4, + 0x43, 0x2e, 0xa4, 0x03, 0x3a, 0x80, 0x43, 0x2b, 0x8c, 0x18, 0x24, 0x00, + 0x08, 0x82, 0x01, 0xd2, 0x0e, 0xb9, 0x90, 0x0e, 0xe8, 0x40, 0x0b, 0xac, + 0x30, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x48, 0x3b, 0xe4, 0xc2, 0x38, + 0xa0, 0x03, 0x38, 0xc4, 0xc2, 0x88, 0x41, 0x02, 0x80, 0x20, 0x18, 0x20, + 0xed, 0x90, 0x0b, 0xe3, 0x80, 0x0e, 0xb4, 0x00, 0x0b, 0x23, 0x06, 0x09, + 0x00, 0x82, 0x60, 0x80, 0xb4, 0x43, 0x2e, 0x8c, 0x03, 0x3a, 0xf8, 0xc2, + 0x2b, 0x8c, 0x18, 0x24, 0x00, 0x08, 0x82, 0x01, 0xd2, 0x0e, 0xb9, 0x30, + 0x0e, 0xe8, 0xf0, 0x0b, 0xae, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static unsigned char D3D12_VertexShader_YUV[] = { + 0x44, 0x58, 0x42, 0x43, 0xec, 0x10, 0x35, 0x4f, 0x25, 0x8f, 0xde, 0xa0, + 0xad, 0x2c, 0x2c, 0xb7, 0x5e, 0xd4, 0x57, 0xdd, 0x01, 0x00, 0x00, 0x00, + 0x97, 0x14, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0xd8, 0x00, 0x00, 0x00, 0x63, 0x01, 0x00, 0x00, + 0x73, 0x02, 0x00, 0x00, 0x5b, 0x03, 0x00, 0x00, 0x53, 0x0b, 0x00, 0x00, + 0x6f, 0x0b, 0x00, 0x00, 0x53, 0x46, 0x49, 0x30, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31, + 0x80, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x54, 0x45, 0x58, + 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, + 0x4f, 0x53, 0x47, 0x31, 0x83, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x03, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, + 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x50, 0x53, 0x56, 0x30, 0x08, + 0x01, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x03, + 0x03, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, + 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x54, 0x45, 0x58, + 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, + 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x43, 0x4f, 0x4c, + 0x4f, 0x52, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x43, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x01, 0x42, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x44, 0x03, 0x03, 0x04, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x01, 0x42, 0x00, 0x03, 0x02, 0x00, 0x00, 0x22, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, 0x03, + 0x02, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x52, 0x54, 0x53, 0x30, 0xe0, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x88, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, + 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x53, 0x54, 0x41, 0x54, 0xf0, + 0x07, 0x00, 0x00, 0x60, 0x00, 0x01, 0x00, 0xfc, 0x01, 0x00, 0x00, 0x44, + 0x58, 0x49, 0x4c, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xd8, + 0x07, 0x00, 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0xf3, + 0x01, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, + 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, + 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, + 0x04, 0x8b, 0x62, 0x80, 0x18, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xc4, + 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x62, 0x88, 0x48, + 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4, + 0x48, 0x0e, 0x90, 0x11, 0x23, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, + 0x83, 0xe5, 0x8a, 0x04, 0x31, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40, + 0x02, 0xa8, 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x20, 0x6d, + 0x30, 0x86, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x09, 0xa8, 0x00, 0x49, + 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, 0x42, 0x20, + 0x4c, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x4c, + 0x00, 0x00, 0x00, 0x32, 0x22, 0x88, 0x09, 0x20, 0x64, 0x85, 0x04, 0x13, + 0x23, 0xa4, 0x84, 0x04, 0x13, 0x23, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, + 0x4c, 0x8c, 0x8c, 0x0b, 0x84, 0xc4, 0x4c, 0x10, 0x88, 0xc1, 0x0c, 0xc0, + 0x30, 0x02, 0x01, 0x24, 0x41, 0x70, 0x70, 0x30, 0x5c, 0x3e, 0xb0, 0x20, + 0x46, 0xc3, 0x10, 0xcd, 0xe4, 0x2f, 0x84, 0x01, 0x08, 0x98, 0x2f, 0x4d, + 0x11, 0x25, 0x4c, 0xfe, 0x4b, 0x44, 0x13, 0x71, 0xb1, 0x07, 0x30, 0x10, + 0x11, 0xe7, 0x34, 0xd2, 0x04, 0x34, 0x93, 0x84, 0x04, 0x41, 0xb8, 0x6e, + 0xb8, 0x7c, 0x60, 0x41, 0x8c, 0x86, 0x21, 0x9a, 0xc9, 0x5f, 0x08, 0x03, + 0x10, 0x30, 0x9f, 0x73, 0x1a, 0x69, 0x02, 0x9a, 0x49, 0x42, 0xc1, 0x40, + 0xc4, 0x08, 0x40, 0x09, 0x0c, 0x3a, 0xe6, 0x08, 0xc0, 0x60, 0x8e, 0x00, + 0x29, 0x06, 0x90, 0x24, 0x89, 0x92, 0xd0, 0x52, 0x0c, 0x23, 0x49, 0x12, + 0x05, 0xa0, 0xe6, 0xa8, 0xe1, 0xf2, 0x27, 0xec, 0x21, 0x24, 0x9f, 0xdb, + 0xa8, 0x62, 0x25, 0x26, 0xbf, 0xb8, 0x6d, 0x44, 0x00, 0x00, 0x00, 0x90, + 0x72, 0xcf, 0x70, 0xf9, 0x13, 0xf6, 0x10, 0x92, 0x1f, 0x02, 0xcd, 0xb0, + 0x10, 0x28, 0x80, 0x0a, 0xf1, 0x24, 0x51, 0x42, 0x52, 0x29, 0x80, 0x04, + 0x00, 0x00, 0xa2, 0xe6, 0x08, 0x82, 0x62, 0x44, 0x89, 0x92, 0x24, 0x16, + 0x5d, 0x03, 0x01, 0x67, 0x09, 0x0b, 0x20, 0x49, 0x3e, 0x03, 0x4c, 0x11, + 0x72, 0xf9, 0xc5, 0xe2, 0x00, 0x93, 0x8f, 0xfb, 0x38, 0x0a, 0x84, 0xe3, + 0xa4, 0x29, 0xa2, 0x84, 0xc9, 0x7f, 0x89, 0x68, 0x22, 0x2e, 0xf6, 0x00, + 0x06, 0x22, 0xe2, 0x9c, 0x46, 0x9a, 0x80, 0x66, 0x92, 0x90, 0xa0, 0x69, + 0xc3, 0x08, 0x02, 0x70, 0x99, 0x34, 0x45, 0x94, 0x30, 0xf9, 0x2f, 0x11, + 0x4d, 0xc4, 0xc5, 0x1e, 0xc0, 0x40, 0x44, 0x28, 0x35, 0x3d, 0xd4, 0x84, + 0x86, 0x80, 0x0b, 0x86, 0x11, 0x06, 0xe0, 0x30, 0x69, 0x8a, 0x28, 0x61, + 0xf2, 0x5f, 0x22, 0x9a, 0x88, 0x8b, 0x3d, 0x80, 0x81, 0x88, 0xc4, 0xe6, + 0xa1, 0x26, 0x34, 0x78, 0x5c, 0x70, 0x09, 0xe7, 0x34, 0xd2, 0x04, 0x34, + 0x93, 0x84, 0x82, 0x2d, 0x1d, 0x12, 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87, + 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87, + 0x0d, 0xaf, 0x50, 0x0e, 0x6d, 0xd0, 0x0e, 0x7a, 0x50, 0x0e, 0x6d, 0x00, + 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, + 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, + 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, + 0x06, 0xe6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, + 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, + 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, + 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x3a, 0x0f, 0x64, 0x90, 0x21, 0x23, 0x25, 0x40, 0x00, 0x52, 0x00, + 0xc0, 0x90, 0xe7, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x21, 0xcf, 0x02, 0x04, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x43, 0x9e, 0x06, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x86, 0x3c, 0x12, 0x10, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x79, 0x28, 0x20, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf2, 0x5c, 0x40, 0x00, 0x0c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x05, 0x02, 0x00, 0x19, + 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x18, 0x19, 0x11, 0x4c, 0x90, 0x8c, + 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x52, 0x0a, 0xa1, 0x08, 0xca, 0x80, + 0x92, 0x12, 0x18, 0x01, 0x28, 0x86, 0x02, 0x14, 0x28, 0x82, 0x42, 0x28, + 0x83, 0x72, 0x28, 0x89, 0x02, 0x0c, 0x28, 0xb0, 0x02, 0x29, 0xa0, 0xf2, + 0x28, 0x8c, 0xd2, 0x0d, 0x28, 0x0a, 0x52, 0x4a, 0x62, 0x04, 0x80, 0x8a, + 0x19, 0x00, 0x22, 0x66, 0x00, 0x68, 0x98, 0x01, 0xa0, 0x6d, 0x06, 0x80, + 0xba, 0x19, 0x00, 0xfa, 0x66, 0x00, 0x08, 0x9c, 0x01, 0xa0, 0x70, 0x2c, + 0x87, 0x61, 0x9e, 0xe7, 0x01, 0x20, 0x30, 0x00, 0x00, 0x10, 0x01, 0x21, + 0x10, 0x0c, 0x40, 0x50, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0xc0, + 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, 0x44, 0x35, + 0x18, 0x63, 0x0b, 0x73, 0x3b, 0x03, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, + 0x73, 0x03, 0x99, 0x71, 0xb9, 0x01, 0x41, 0xa1, 0x0b, 0x3b, 0x9b, 0x7b, + 0x91, 0x2a, 0x62, 0x2a, 0x0a, 0x9a, 0x2a, 0xfa, 0x9a, 0xb9, 0x81, 0x79, + 0x31, 0x4b, 0x73, 0x0b, 0x63, 0x4b, 0xd9, 0x10, 0x04, 0x13, 0x84, 0x44, + 0x99, 0x20, 0x24, 0xcb, 0x06, 0x61, 0x20, 0x36, 0x08, 0x04, 0x41, 0xc1, + 0x6e, 0x6e, 0x82, 0x90, 0x30, 0x1b, 0x86, 0x03, 0x21, 0x26, 0x08, 0x45, + 0xc7, 0x64, 0xe8, 0xcd, 0x6d, 0x8e, 0x2e, 0xcc, 0x8d, 0x6e, 0x6e, 0x82, + 0x90, 0x34, 0x1b, 0x10, 0x42, 0x59, 0x08, 0x62, 0x60, 0x80, 0x0d, 0x41, + 0xb3, 0x81, 0x00, 0x00, 0x07, 0x98, 0x20, 0x6c, 0x60, 0xc0, 0xa2, 0xed, + 0x8d, 0xac, 0x8c, 0x6d, 0x82, 0x90, 0x38, 0x13, 0x84, 0xe4, 0xd9, 0x30, + 0x4c, 0xd3, 0x30, 0x41, 0x48, 0xa0, 0x09, 0x42, 0x12, 0x4d, 0x10, 0x12, + 0x69, 0x03, 0x82, 0x44, 0x12, 0x55, 0x11, 0xd6, 0xc5, 0x08, 0x4e, 0xee, + 0x4d, 0xad, 0x6c, 0x8c, 0x2e, 0xed, 0xcd, 0x2d, 0xc8, 0x8d, 0xcc, 0x2a, + 0xad, 0xec, 0x6e, 0x82, 0x90, 0x4c, 0x1b, 0x10, 0x24, 0x93, 0xa8, 0x4a, + 0xb3, 0xae, 0x0d, 0x03, 0x83, 0x6d, 0x13, 0x84, 0x2e, 0x0c, 0x26, 0x08, + 0x09, 0xc5, 0x01, 0xee, 0x6d, 0x8e, 0xcb, 0x94, 0xd5, 0x17, 0xd4, 0xd3, + 0x54, 0x12, 0x55, 0xd2, 0x93, 0xd3, 0x06, 0x04, 0xf9, 0x2a, 0x62, 0x02, + 0x03, 0xeb, 0xe2, 0x40, 0x57, 0x86, 0x37, 0x41, 0x48, 0x2a, 0x26, 0x54, + 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x30, 0x1b, 0x10, 0x44, 0x0c, + 0xaa, 0x31, 0x98, 0xc8, 0xc0, 0xba, 0x58, 0x8c, 0xbd, 0xb1, 0xbd, 0xc9, + 0x4d, 0x10, 0x12, 0x8b, 0xc6, 0xd0, 0x13, 0xd3, 0x93, 0x14, 0xcc, 0x06, + 0x04, 0x31, 0x83, 0xea, 0x0c, 0x26, 0x34, 0xb0, 0xae, 0x0d, 0x84, 0x17, + 0x06, 0x65, 0x90, 0x06, 0x13, 0x84, 0x4f, 0x0c, 0x88, 0x40, 0x3d, 0x4d, + 0x25, 0x51, 0x25, 0x3d, 0x39, 0x6d, 0x40, 0x90, 0xaf, 0x22, 0x26, 0x36, + 0xb0, 0xae, 0x0d, 0x84, 0xd7, 0x06, 0x65, 0x90, 0x06, 0x13, 0x04, 0x30, + 0x18, 0x83, 0x0d, 0x04, 0xb2, 0x54, 0xc4, 0x06, 0x81, 0x81, 0x83, 0x09, + 0xc2, 0xf0, 0x4d, 0x10, 0x08, 0x6f, 0x43, 0x43, 0x40, 0x5c, 0xa7, 0x06, + 0x6b, 0xe0, 0x06, 0x6f, 0x10, 0x07, 0x72, 0xc0, 0xcd, 0x41, 0x1c, 0x4c, + 0x10, 0x90, 0x60, 0x03, 0xb0, 0x61, 0x20, 0xec, 0xc0, 0x0e, 0x36, 0x04, + 0x77, 0xb0, 0x61, 0x18, 0xea, 0x00, 0x0f, 0x26, 0x08, 0x61, 0x40, 0x06, + 0x1b, 0x02, 0x3d, 0xe0, 0xd1, 0x16, 0x96, 0xe6, 0x96, 0x55, 0x65, 0x35, + 0x41, 0x50, 0xb6, 0x09, 0x82, 0xc2, 0x6d, 0x08, 0x88, 0x09, 0x82, 0x92, + 0x6c, 0x10, 0x2a, 0x6b, 0xc3, 0x42, 0xb0, 0x41, 0x1f, 0xf8, 0xc1, 0x1f, + 0xf8, 0xc1, 0x00, 0x0a, 0x84, 0x1f, 0x84, 0x02, 0x11, 0xaa, 0x22, 0xac, + 0xa1, 0xa7, 0x27, 0x29, 0xa2, 0x09, 0x82, 0x82, 0x6c, 0x10, 0xaa, 0x6a, + 0xc3, 0x32, 0x8c, 0x42, 0x1f, 0xf8, 0xc1, 0x1f, 0xf8, 0xc1, 0x40, 0x0a, + 0x83, 0x1f, 0x94, 0x02, 0x8b, 0xa1, 0x27, 0xa6, 0x27, 0xa9, 0x09, 0x82, + 0x72, 0x4c, 0x10, 0x92, 0x6b, 0x83, 0x50, 0xa5, 0xc2, 0x86, 0x45, 0x3a, + 0x85, 0x3e, 0xf0, 0x83, 0x3f, 0xf0, 0x83, 0x01, 0x15, 0x24, 0x3f, 0x50, + 0x85, 0x0d, 0x83, 0x28, 0x98, 0xc2, 0x2a, 0x70, 0x99, 0xb2, 0xfa, 0x82, + 0x7a, 0x9b, 0x4b, 0xa3, 0x4b, 0x7b, 0x73, 0xdb, 0xb0, 0x10, 0xad, 0xd0, + 0x07, 0xa0, 0xf0, 0x07, 0xa8, 0x30, 0xa0, 0x02, 0xe1, 0x07, 0xaa, 0xb0, + 0x61, 0x19, 0x46, 0xa1, 0x0f, 0xfc, 0xe0, 0x0f, 0x48, 0x61, 0x20, 0x85, + 0xc1, 0x0f, 0x4a, 0x61, 0xc3, 0x22, 0x9d, 0x42, 0x1f, 0xf8, 0xc1, 0x1f, + 0x90, 0xc2, 0x80, 0x0a, 0x92, 0x1f, 0xa8, 0xc2, 0x86, 0xc1, 0x15, 0x5e, + 0x01, 0x16, 0x36, 0x0c, 0xac, 0x10, 0x0b, 0xc0, 0x86, 0xa2, 0x0e, 0xf8, + 0x40, 0x16, 0x1e, 0x80, 0x86, 0x19, 0xdb, 0x5b, 0x18, 0xdd, 0xdc, 0x04, + 0x21, 0xc1, 0x58, 0xa4, 0xb9, 0xcd, 0xd1, 0xcd, 0x4d, 0x10, 0x92, 0x8c, + 0xc6, 0x5c, 0xda, 0xd9, 0x17, 0x1b, 0x19, 0x8d, 0xb9, 0xb4, 0xb3, 0xaf, + 0x39, 0xba, 0x09, 0x42, 0xa2, 0x6d, 0x40, 0x68, 0xa1, 0x16, 0x6c, 0xe1, + 0x16, 0x70, 0xe1, 0xca, 0x05, 0x5d, 0xa8, 0xc2, 0xc6, 0x66, 0xd7, 0xe6, + 0x92, 0x46, 0x56, 0xe6, 0x46, 0x37, 0x25, 0x08, 0xaa, 0x90, 0xe1, 0xb9, + 0xd8, 0x95, 0xc9, 0xcd, 0xa5, 0xbd, 0xb9, 0x4d, 0x09, 0x88, 0x26, 0x64, + 0x78, 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x65, 0x72, 0x53, 0x82, 0xa2, 0x0e, + 0x19, 0x9e, 0xcb, 0x1c, 0x5a, 0x18, 0x59, 0x99, 0x5c, 0xd3, 0x1b, 0x59, + 0x19, 0xdb, 0x94, 0x00, 0x29, 0x43, 0x86, 0xe7, 0x22, 0x57, 0x36, 0xf7, + 0x56, 0x27, 0x37, 0x56, 0x36, 0x37, 0x25, 0x70, 0x2a, 0x91, 0xe1, 0xb9, + 0xd0, 0xe5, 0xc1, 0x95, 0x05, 0xb9, 0xb9, 0xbd, 0xd1, 0x85, 0xd1, 0xa5, + 0xbd, 0xb9, 0xcd, 0x4d, 0x11, 0xe6, 0x00, 0x0f, 0xea, 0x90, 0xe1, 0xb9, + 0xd8, 0xa5, 0x95, 0xdd, 0x25, 0x91, 0x4d, 0xd1, 0x85, 0xd1, 0x95, 0x4d, + 0x09, 0xf4, 0xa0, 0x0e, 0x19, 0x9e, 0x4b, 0x99, 0x1b, 0x9d, 0x5c, 0x1e, + 0xd4, 0x5b, 0x9a, 0x1b, 0xdd, 0xdc, 0x94, 0x40, 0x16, 0xba, 0x90, 0xe1, + 0xb9, 0x8c, 0xbd, 0xd5, 0xb9, 0xd1, 0x95, 0xc9, 0xcd, 0x4d, 0x09, 0x74, + 0x01, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x33, + 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, + 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, + 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, + 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, + 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, + 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, + 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, + 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, + 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, + 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, + 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, + 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, + 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, + 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, + 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, + 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, + 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, + 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, + 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, + 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, + 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, + 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x8c, 0xc8, 0x21, + 0x07, 0x7c, 0x70, 0x03, 0x72, 0x10, 0x87, 0x73, 0x70, 0x03, 0x7b, 0x08, + 0x07, 0x79, 0x60, 0x87, 0x70, 0xc8, 0x87, 0x77, 0xa8, 0x07, 0x7a, 0x00, + 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x06, + 0x00, 0x71, 0x4e, 0x23, 0x4d, 0x40, 0x33, 0x49, 0xff, 0x42, 0x18, 0x80, + 0x80, 0x19, 0xc1, 0x36, 0x5c, 0xbe, 0xf3, 0xf8, 0x42, 0x40, 0x15, 0x05, + 0x11, 0x95, 0x0e, 0x30, 0x94, 0x84, 0x01, 0x08, 0x98, 0x5f, 0xdc, 0xb6, + 0x19, 0x48, 0xc3, 0xe5, 0x3b, 0x8f, 0x2f, 0x44, 0x04, 0x30, 0x11, 0x21, + 0xd0, 0x0c, 0x0b, 0x61, 0x02, 0xd3, 0x70, 0xf9, 0xce, 0xe3, 0x2f, 0x0e, + 0x30, 0x88, 0xcd, 0x43, 0x4d, 0x7e, 0x71, 0xdb, 0x36, 0x50, 0x0d, 0x97, + 0xef, 0x3c, 0xbe, 0x34, 0x39, 0x11, 0x81, 0x52, 0xd3, 0x43, 0x4d, 0x7e, + 0x71, 0xdb, 0x56, 0x20, 0x0d, 0x97, 0xef, 0x3c, 0xfe, 0x44, 0x44, 0x13, + 0x02, 0x44, 0x98, 0x5f, 0xdc, 0xb6, 0x05, 0x1c, 0x0c, 0x80, 0x34, 0xb2, + 0xfb, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x37, 0x12, 0xc2, 0x76, + 0x04, 0xc6, 0xc0, 0xad, 0xe5, 0xc2, 0x1e, 0x4d, 0x70, 0xa6, 0x71, 0x44, + 0x58, 0x49, 0x4c, 0x20, 0x09, 0x00, 0x00, 0x60, 0x00, 0x01, 0x00, 0x48, + 0x02, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c, 0x00, 0x01, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x08, 0x09, 0x00, 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, + 0x0c, 0x00, 0x00, 0x3f, 0x02, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, + 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, + 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, + 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, + 0x32, 0x52, 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, + 0x19, 0x32, 0x42, 0xe4, 0x48, 0x0e, 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, + 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x29, 0x46, 0x06, 0x51, + 0x18, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, + 0xff, 0xff, 0x07, 0x40, 0x02, 0xa8, 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, + 0xff, 0x03, 0x20, 0x6d, 0x30, 0x86, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, + 0x09, 0xa8, 0x00, 0x49, 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, + 0x82, 0x60, 0x42, 0x20, 0x4c, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x89, + 0x20, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, + 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, + 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, + 0x6c, 0x23, 0x00, 0x25, 0x00, 0x14, 0x66, 0x00, 0xe6, 0x08, 0xc0, 0x60, + 0x8e, 0x00, 0x29, 0xc6, 0x20, 0x84, 0x14, 0x42, 0xa6, 0x18, 0x80, 0x10, + 0x52, 0x06, 0xa1, 0xa3, 0x86, 0xcb, 0x9f, 0xb0, 0x87, 0x90, 0x7c, 0x6e, + 0xa3, 0x8a, 0x95, 0x98, 0xfc, 0xe2, 0xb6, 0x11, 0x31, 0xc6, 0x18, 0x54, + 0xee, 0x19, 0x2e, 0x7f, 0xc2, 0x1e, 0x42, 0xf2, 0x43, 0xa0, 0x19, 0x16, + 0x02, 0x05, 0xab, 0x10, 0x8a, 0x30, 0x42, 0xad, 0x14, 0x83, 0x8c, 0x31, + 0xe8, 0xcd, 0x11, 0x04, 0xc5, 0x60, 0xa4, 0x10, 0x12, 0x49, 0x0e, 0x04, + 0x0c, 0x23, 0x10, 0x43, 0x12, 0xd4, 0x83, 0x83, 0xe1, 0xf2, 0x81, 0x05, + 0x31, 0x1a, 0x86, 0x68, 0x26, 0x7f, 0x21, 0x0c, 0x40, 0xc0, 0x7c, 0x69, + 0x8a, 0x28, 0x61, 0xf2, 0x5f, 0x22, 0x9a, 0x88, 0x8b, 0x3d, 0x80, 0x81, + 0x88, 0x38, 0xa7, 0x91, 0x26, 0xa0, 0x99, 0x24, 0x24, 0x58, 0x7b, 0xdd, + 0x70, 0xf9, 0xc0, 0x82, 0x18, 0x0d, 0x43, 0x34, 0x93, 0xbf, 0x10, 0x06, + 0x20, 0x60, 0x3e, 0xe7, 0x34, 0xd2, 0x04, 0x34, 0x93, 0x84, 0x82, 0x4b, + 0x38, 0x1d, 0x08, 0x00, 0x00, 0x00, 0x00, 0x13, 0x14, 0x72, 0xc0, 0x87, + 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, 0x79, 0x68, 0x03, 0x72, 0xc0, 0x87, + 0x0d, 0xaf, 0x50, 0x0e, 0x6d, 0xd0, 0x0e, 0x7a, 0x50, 0x0e, 0x6d, 0x00, + 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, + 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, + 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, + 0x06, 0xe6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, + 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, + 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, + 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x43, 0x9e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x86, 0x3c, 0x06, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0x79, 0x10, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0xf2, 0x34, 0x40, 0x00, 0x0c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xe4, 0x79, 0x80, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xc8, 0x23, 0x01, 0x01, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x16, 0x08, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, + 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x22, 0x25, 0x30, 0x02, 0x50, 0x0c, + 0x05, 0x28, 0x50, 0x06, 0xe5, 0x50, 0x04, 0xe5, 0x41, 0xa5, 0x24, 0x46, + 0x00, 0xca, 0xa0, 0x08, 0x0a, 0x81, 0xf2, 0x0c, 0x00, 0xe9, 0xb1, 0x1c, + 0x86, 0x79, 0x9e, 0x07, 0x80, 0xc0, 0x00, 0x00, 0x40, 0x04, 0x84, 0x40, + 0x30, 0x00, 0x41, 0x01, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x66, + 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x90, 0x46, 0x02, 0x13, 0x44, 0x35, + 0x18, 0x63, 0x0b, 0x73, 0x3b, 0x03, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, + 0x73, 0x03, 0x99, 0x71, 0xb9, 0x01, 0x41, 0xa1, 0x0b, 0x3b, 0x9b, 0x7b, + 0x91, 0x2a, 0x62, 0x2a, 0x0a, 0x9a, 0x2a, 0xfa, 0x9a, 0xb9, 0x81, 0x79, + 0x31, 0x4b, 0x73, 0x0b, 0x63, 0x4b, 0xd9, 0x10, 0x04, 0x13, 0x04, 0xc2, + 0x98, 0x20, 0x10, 0xc7, 0x06, 0x61, 0x20, 0x26, 0x08, 0x04, 0xb2, 0x41, + 0x18, 0x0c, 0x0a, 0x76, 0x73, 0x1b, 0x06, 0xc4, 0x20, 0x26, 0x08, 0xd9, + 0x44, 0x60, 0x82, 0x40, 0x24, 0x1b, 0x10, 0x42, 0x59, 0x08, 0x62, 0x60, + 0x80, 0x0d, 0x41, 0xb3, 0x81, 0x00, 0x00, 0x07, 0x98, 0x20, 0x68, 0xd4, + 0x86, 0x00, 0x9a, 0x20, 0x08, 0x00, 0x8f, 0xb6, 0xb0, 0x34, 0xb7, 0xac, + 0x2a, 0x2b, 0x22, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x13, + 0x84, 0xc2, 0x99, 0x20, 0x14, 0xcf, 0x86, 0x80, 0x98, 0x20, 0x14, 0xd0, + 0x04, 0x81, 0x50, 0x26, 0x08, 0xc4, 0xb2, 0x41, 0xc8, 0xb4, 0x0d, 0x0b, + 0x41, 0x55, 0xd6, 0x65, 0x0d, 0x18, 0x61, 0x6d, 0x44, 0xa8, 0x8a, 0xb0, + 0x86, 0x9e, 0x9e, 0xa4, 0x88, 0x26, 0x08, 0x45, 0xb4, 0x41, 0xc8, 0xb2, + 0x0d, 0xcb, 0xd0, 0x55, 0xd6, 0x65, 0x0d, 0xde, 0x60, 0x7d, 0x13, 0x04, + 0x82, 0x61, 0x31, 0xf4, 0xc4, 0xf4, 0x24, 0x35, 0x41, 0x28, 0xa4, 0x09, + 0x02, 0xd1, 0x6c, 0x10, 0x32, 0x32, 0xd8, 0xb0, 0x84, 0x81, 0x18, 0x54, + 0xd6, 0x65, 0x0d, 0x63, 0x10, 0x06, 0x56, 0x19, 0x6c, 0x18, 0x38, 0x30, + 0x30, 0x03, 0x2e, 0x53, 0x56, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x1b, 0x16, 0x02, 0x0d, 0x2a, 0xec, 0x1a, 0x83, 0x61, 0x0c, + 0x08, 0xab, 0x0c, 0x36, 0x2c, 0x43, 0x57, 0x59, 0x97, 0x37, 0x78, 0x83, + 0xf5, 0x6d, 0x58, 0xc2, 0x40, 0x0c, 0x2a, 0xeb, 0xf2, 0x86, 0x31, 0x08, + 0x03, 0xab, 0x0c, 0x36, 0x0c, 0x69, 0xa0, 0x06, 0x6b, 0xb0, 0x61, 0x38, + 0x03, 0x36, 0x00, 0x36, 0x14, 0xd2, 0xd4, 0x06, 0x0f, 0x50, 0x85, 0x8d, + 0xcd, 0xae, 0xcd, 0x25, 0x8d, 0xac, 0xcc, 0x8d, 0x6e, 0x4a, 0x10, 0x54, + 0x21, 0xc3, 0x73, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x9b, 0x12, + 0x10, 0x4d, 0xc8, 0xf0, 0x5c, 0xec, 0xc2, 0xd8, 0xec, 0xca, 0xe4, 0xa6, + 0x04, 0x46, 0x1d, 0x32, 0x3c, 0x97, 0x39, 0xb4, 0x30, 0xb2, 0x32, 0xb9, + 0xa6, 0x37, 0xb2, 0x32, 0xb6, 0x29, 0x01, 0x52, 0x86, 0x0c, 0xcf, 0x45, + 0xae, 0x6c, 0xee, 0xad, 0x4e, 0x6e, 0xac, 0x6c, 0x6e, 0x4a, 0xe0, 0xd4, + 0x21, 0xc3, 0x73, 0xb1, 0x4b, 0x2b, 0xbb, 0x4b, 0x22, 0x9b, 0xa2, 0x0b, + 0xa3, 0x2b, 0x9b, 0x12, 0x40, 0x75, 0xc8, 0xf0, 0x5c, 0xca, 0xdc, 0xe8, + 0xe4, 0xf2, 0xa0, 0xde, 0xd2, 0xdc, 0xe8, 0xe6, 0xa6, 0x04, 0x6d, 0x00, + 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x33, + 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, + 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, + 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, + 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, + 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, + 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, + 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, + 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, + 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, + 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, + 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, + 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, + 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, + 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, + 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, + 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, + 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, + 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, + 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, + 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, + 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, + 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x8c, 0xc8, 0x21, + 0x07, 0x7c, 0x70, 0x03, 0x72, 0x10, 0x87, 0x73, 0x70, 0x03, 0x7b, 0x08, + 0x07, 0x79, 0x60, 0x87, 0x70, 0xc8, 0x87, 0x77, 0xa8, 0x07, 0x7a, 0x00, + 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x36, + 0xb0, 0x0d, 0x97, 0xef, 0x3c, 0xbe, 0x10, 0x50, 0x45, 0x41, 0x44, 0xa5, + 0x03, 0x0c, 0x25, 0x61, 0x00, 0x02, 0xe6, 0x17, 0xb7, 0x6d, 0x05, 0xd2, + 0x70, 0xf9, 0xce, 0xe3, 0x0b, 0x11, 0x01, 0x4c, 0x44, 0x08, 0x34, 0xc3, + 0x42, 0x58, 0xc0, 0x34, 0x5c, 0xbe, 0xf3, 0xf8, 0x8b, 0x03, 0x0c, 0x62, + 0xf3, 0x50, 0x93, 0x5f, 0xdc, 0xb6, 0x09, 0x54, 0xc3, 0xe5, 0x3b, 0x8f, + 0x2f, 0x4d, 0x4e, 0x44, 0xa0, 0xd4, 0xf4, 0x50, 0x93, 0x5f, 0xdc, 0xb6, + 0x11, 0x48, 0xc3, 0xe5, 0x3b, 0x8f, 0x3f, 0x11, 0xd1, 0x84, 0x00, 0x11, + 0xe6, 0x17, 0xb7, 0x6d, 0x00, 0x07, 0x03, 0x20, 0x8d, 0xec, 0xbe, 0x00, + 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0xcf, 0x00, 0x00, 0x00, 0x13, + 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x44, + 0x8a, 0xab, 0x14, 0x0a, 0x61, 0x06, 0xa0, 0xec, 0x4a, 0x8e, 0x4a, 0x09, + 0x50, 0x1c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x23, 0x06, 0x09, 0x00, 0x82, + 0x60, 0x20, 0x61, 0x03, 0x63, 0x59, 0xc1, 0x88, 0x41, 0x02, 0x80, 0x20, + 0x18, 0x18, 0xdd, 0x21, 0x5d, 0x8f, 0x31, 0x62, 0x90, 0x00, 0x20, 0x08, + 0x06, 0x86, 0x87, 0x4c, 0x18, 0x71, 0x8c, 0x18, 0x24, 0x00, 0x08, 0x82, + 0x81, 0xf1, 0x25, 0x54, 0xf6, 0x20, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, + 0x60, 0x80, 0x81, 0x52, 0x69, 0x51, 0x32, 0x62, 0x90, 0x00, 0x20, 0x08, + 0x06, 0x46, 0x18, 0x2c, 0xdc, 0x36, 0x29, 0x23, 0x06, 0x09, 0x00, 0x82, + 0x60, 0x60, 0x88, 0x01, 0xd3, 0x71, 0xc8, 0x32, 0x62, 0x90, 0x00, 0x20, + 0x08, 0x06, 0xc6, 0x18, 0x34, 0x5d, 0x57, 0x31, 0x23, 0x06, 0x09, 0x00, + 0x82, 0x60, 0x60, 0x90, 0x81, 0xe3, 0x79, 0x4a, 0x33, 0x62, 0x90, 0x00, + 0x20, 0x08, 0x06, 0x46, 0x19, 0x3c, 0xdf, 0x57, 0x39, 0x23, 0x06, 0x07, + 0x00, 0x82, 0x60, 0xd0, 0x90, 0x81, 0xa3, 0x80, 0xc1, 0x68, 0x42, 0x00, + 0x8c, 0x26, 0x08, 0xc1, 0x68, 0xc2, 0x20, 0x8c, 0x26, 0x10, 0xc3, 0x88, + 0xc1, 0x01, 0x80, 0x20, 0x18, 0x34, 0x69, 0x30, 0x3d, 0x66, 0x30, 0x9a, + 0x10, 0x00, 0xa3, 0x09, 0x42, 0x30, 0x9a, 0x30, 0x08, 0xa3, 0x09, 0xc4, + 0x30, 0x62, 0x70, 0x00, 0x20, 0x08, 0x06, 0x8d, 0x1b, 0x60, 0x54, 0x19, + 0x8c, 0x26, 0x04, 0xc0, 0x68, 0x82, 0x10, 0x8c, 0x26, 0x0c, 0xc2, 0x68, + 0x02, 0x31, 0x8c, 0x18, 0x1c, 0x00, 0x08, 0x82, 0x41, 0x33, 0x07, 0x5d, + 0xc6, 0x06, 0xa3, 0x09, 0x01, 0x30, 0x9a, 0x20, 0x04, 0xa3, 0x09, 0x83, + 0x30, 0x9a, 0x40, 0x0c, 0x36, 0x5d, 0xf2, 0x19, 0x31, 0x40, 0x00, 0x10, + 0x04, 0x83, 0x07, 0x0f, 0xce, 0xe0, 0x7a, 0x82, 0x11, 0x03, 0x04, 0x00, + 0x41, 0x30, 0x78, 0xf2, 0x00, 0x0d, 0xae, 0x25, 0xb0, 0xe0, 0x80, 0x8e, + 0x59, 0x9b, 0x7c, 0x46, 0x0c, 0x10, 0x00, 0x04, 0xc1, 0xe0, 0xe1, 0x83, + 0x35, 0xd8, 0xa4, 0x60, 0xc4, 0x00, 0x01, 0x40, 0x10, 0x0c, 0x9e, 0x3e, + 0x60, 0x83, 0xcd, 0x09, 0x2c, 0x50, 0xa0, 0x63, 0xd9, 0x27, 0x9f, 0x11, + 0x03, 0x04, 0x00, 0x41, 0x30, 0x78, 0x40, 0xe1, 0x0d, 0xbe, 0x2a, 0x18, + 0x31, 0x40, 0x00, 0x10, 0x04, 0x83, 0x27, 0x14, 0xe0, 0xe0, 0x8b, 0x02, + 0x0b, 0x1a, 0xe8, 0x18, 0x37, 0x06, 0xf2, 0x19, 0x31, 0x40, 0x00, 0x10, + 0x04, 0x83, 0x87, 0x14, 0xe6, 0x60, 0x0c, 0xb0, 0x60, 0xc4, 0x00, 0x01, + 0x40, 0x10, 0x0c, 0x9e, 0x52, 0xa0, 0x83, 0x31, 0xa0, 0x02, 0x0b, 0x20, + 0xe8, 0x8c, 0x18, 0x1c, 0x00, 0x08, 0x82, 0x41, 0x83, 0x0a, 0x72, 0xe0, + 0x06, 0x74, 0x30, 0x9a, 0x10, 0x00, 0xa3, 0x09, 0x42, 0x30, 0x9a, 0x30, + 0x08, 0xa3, 0x09, 0xc4, 0x30, 0x62, 0x70, 0x00, 0x20, 0x08, 0x06, 0x4d, + 0x2b, 0xdc, 0xc1, 0x1c, 0xe8, 0xc1, 0x68, 0x42, 0x00, 0x8c, 0x26, 0x08, + 0xc1, 0x68, 0xc2, 0x20, 0x8c, 0x26, 0x10, 0xc3, 0x88, 0xc1, 0x01, 0x80, + 0x20, 0x18, 0x34, 0xb2, 0xc0, 0x07, 0x78, 0xd0, 0x0a, 0xa3, 0x09, 0x01, + 0x30, 0x9a, 0x20, 0x04, 0xa3, 0x09, 0x83, 0x30, 0x9a, 0x40, 0x0c, 0x23, + 0x06, 0x07, 0x00, 0x82, 0x60, 0xd0, 0xdc, 0x42, 0x28, 0xf4, 0xc1, 0x2b, + 0x8c, 0x26, 0x04, 0xc0, 0x68, 0x82, 0x10, 0x8c, 0x26, 0x0c, 0xc2, 0x68, + 0x02, 0x31, 0xd8, 0x14, 0x06, 0xf2, 0x19, 0x31, 0x40, 0x00, 0x10, 0x04, + 0x83, 0x87, 0x17, 0x56, 0xc1, 0x7b, 0x82, 0x11, 0x03, 0x04, 0x00, 0x41, + 0x30, 0x78, 0x7a, 0x81, 0x15, 0xb6, 0x25, 0x18, 0x31, 0x40, 0x00, 0x10, + 0x04, 0x83, 0xc7, 0x17, 0x5a, 0x01, 0x3b, 0x02, 0xb3, 0xca, 0x40, 0x3e, + 0x23, 0x06, 0x08, 0x00, 0x82, 0x60, 0xf0, 0x80, 0xc3, 0x2b, 0x88, 0x81, + 0x14, 0x8c, 0x18, 0x20, 0x00, 0x08, 0x82, 0xc1, 0x13, 0x0e, 0xb0, 0xf0, + 0x39, 0xc1, 0x88, 0x01, 0x02, 0x80, 0x20, 0x18, 0x3c, 0xe2, 0x10, 0x0b, + 0x9c, 0x12, 0x58, 0x96, 0x06, 0xf2, 0x19, 0x31, 0x40, 0x00, 0x10, 0x04, + 0x83, 0x87, 0x1c, 0x66, 0xc1, 0x0c, 0xaa, 0x60, 0xc4, 0x00, 0x01, 0x40, + 0x10, 0x0c, 0x9e, 0x72, 0xa0, 0x85, 0x31, 0x88, 0x82, 0x11, 0x03, 0x04, + 0x00, 0x41, 0x30, 0x78, 0xcc, 0xa1, 0x16, 0xc0, 0xa0, 0x09, 0x8c, 0x6b, + 0x03, 0xf9, 0x8c, 0x18, 0x20, 0x00, 0x08, 0x82, 0xc1, 0x83, 0x0e, 0xb7, + 0xa0, 0x06, 0x58, 0x30, 0x62, 0x80, 0x00, 0x20, 0x08, 0x06, 0x4f, 0x3a, + 0xe0, 0xc2, 0x19, 0x50, 0xc1, 0x88, 0x01, 0x02, 0x80, 0x20, 0x18, 0x3c, + 0xea, 0x90, 0x0b, 0x64, 0x00, 0x05, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, + 0x80, 0xb4, 0x43, 0x2e, 0xa0, 0x03, 0x3a, 0x80, 0x43, 0x33, 0x62, 0x90, + 0x00, 0x20, 0x08, 0x06, 0x48, 0x3b, 0xe4, 0x02, 0x3a, 0xa0, 0x03, 0x2d, + 0x24, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x80, 0xb4, 0x43, 0x2e, 0xa0, + 0x03, 0x3a, 0xf8, 0x42, 0x31, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x48, + 0x3b, 0xe4, 0x02, 0x3a, 0xa0, 0xc3, 0x2f, 0x04, 0x23, 0x06, 0x09, 0x00, + 0x82, 0x60, 0x80, 0xb4, 0x43, 0x2e, 0xa4, 0x03, 0x3a, 0x80, 0x43, 0x2b, + 0x8c, 0x18, 0x24, 0x00, 0x08, 0x82, 0x01, 0xd2, 0x0e, 0xb9, 0x90, 0x0e, + 0xe8, 0x40, 0x0b, 0xac, 0x30, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x48, + 0x3b, 0xe4, 0xc2, 0x38, 0xa0, 0x03, 0x38, 0xc4, 0xc2, 0x88, 0x41, 0x02, + 0x80, 0x20, 0x18, 0x20, 0xed, 0x90, 0x0b, 0xe3, 0x80, 0x0e, 0xb4, 0x00, + 0x0b, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x80, 0xb4, 0x43, 0x2e, 0x8c, + 0x03, 0x3a, 0xf8, 0xc2, 0x2b, 0x8c, 0x18, 0x24, 0x00, 0x08, 0x82, 0x01, + 0xd2, 0x0e, 0xb9, 0x30, 0x0e, 0xe8, 0xf0, 0x0b, 0xae, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00 +}; + +static unsigned char D3D12_VertexShader_NV[] = { + 0x44, 0x58, 0x42, 0x43, 0x52, 0x51, 0xf4, 0x61, 0xe0, 0x16, 0x3e, 0xc4, + 0xd9, 0x83, 0xc5, 0x7a, 0x0a, 0xa7, 0x7f, 0x7c, 0x01, 0x00, 0x00, 0x00, + 0x63, 0x14, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0xd8, 0x00, 0x00, 0x00, 0x63, 0x01, 0x00, 0x00, + 0x73, 0x02, 0x00, 0x00, 0x2f, 0x03, 0x00, 0x00, 0x27, 0x0b, 0x00, 0x00, + 0x43, 0x0b, 0x00, 0x00, 0x53, 0x46, 0x49, 0x30, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x53, 0x47, 0x31, + 0x80, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x54, 0x45, 0x58, + 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, + 0x4f, 0x53, 0x47, 0x31, 0x83, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x03, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, + 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x50, 0x53, 0x56, 0x30, 0x08, + 0x01, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x03, + 0x03, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, + 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x54, 0x45, 0x58, + 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, + 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x43, 0x4f, 0x4c, + 0x4f, 0x52, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x43, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x01, 0x42, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x44, 0x03, 0x03, 0x04, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x01, 0x42, 0x00, 0x03, 0x02, 0x00, 0x00, 0x22, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, 0x03, + 0x02, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x52, 0x54, 0x53, 0x30, 0xb4, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x7c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x53, + 0x54, 0x41, 0x54, 0xf0, 0x07, 0x00, 0x00, 0x60, 0x00, 0x01, 0x00, 0xfc, + 0x01, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c, 0x00, 0x01, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0xd8, 0x07, 0x00, 0x00, 0x42, 0x43, 0xc0, 0xde, 0x21, + 0x0c, 0x00, 0x00, 0xf3, 0x01, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, + 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, + 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x18, 0x45, 0x02, 0x42, + 0x92, 0x0b, 0x42, 0xc4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, + 0x32, 0x62, 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, + 0x19, 0x32, 0x42, 0xe4, 0x48, 0x0e, 0x90, 0x11, 0x23, 0xc4, 0x50, 0x41, + 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x31, 0x46, 0x06, 0x51, + 0x18, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1b, 0x8c, 0xe0, 0xff, 0xff, + 0xff, 0xff, 0x07, 0x40, 0x02, 0xa8, 0x0d, 0x84, 0xf0, 0xff, 0xff, 0xff, + 0xff, 0x03, 0x20, 0x6d, 0x30, 0x86, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, + 0x09, 0xa8, 0x00, 0x49, 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, + 0x82, 0x60, 0x42, 0x20, 0x4c, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x89, + 0x20, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x32, 0x22, 0x88, 0x09, 0x20, + 0x64, 0x85, 0x04, 0x13, 0x23, 0xa4, 0x84, 0x04, 0x13, 0x23, 0xe3, 0x84, + 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8c, 0x8c, 0x0b, 0x84, 0xc4, 0x4c, 0x10, + 0x88, 0xc1, 0x0c, 0xc0, 0x30, 0x02, 0x01, 0x24, 0x41, 0x70, 0x70, 0x30, + 0x5c, 0x3e, 0xb0, 0x20, 0x46, 0xc3, 0x10, 0xcd, 0xe4, 0x2f, 0x84, 0x01, + 0x08, 0x98, 0x2f, 0x4d, 0x11, 0x25, 0x4c, 0xfe, 0x4b, 0x44, 0x13, 0x71, + 0xb1, 0x07, 0x30, 0x10, 0x11, 0xe7, 0x34, 0xd2, 0x04, 0x34, 0x93, 0x84, + 0x04, 0x41, 0xb8, 0x6e, 0xb8, 0x7c, 0x60, 0x41, 0x8c, 0x86, 0x21, 0x9a, + 0xc9, 0x5f, 0x08, 0x03, 0x10, 0x30, 0x9f, 0x73, 0x1a, 0x69, 0x02, 0x9a, + 0x49, 0x42, 0xc1, 0x40, 0xc4, 0x08, 0x40, 0x09, 0x0c, 0x3a, 0xe6, 0x08, + 0xc0, 0x60, 0x8e, 0x00, 0x29, 0x06, 0x90, 0x24, 0x89, 0x92, 0xd0, 0x52, + 0x0c, 0x23, 0x49, 0x12, 0x05, 0xa0, 0xe6, 0xa8, 0xe1, 0xf2, 0x27, 0xec, + 0x21, 0x24, 0x9f, 0xdb, 0xa8, 0x62, 0x25, 0x26, 0xbf, 0xb8, 0x6d, 0x44, + 0x00, 0x00, 0x00, 0x90, 0x72, 0xcf, 0x70, 0xf9, 0x13, 0xf6, 0x10, 0x92, + 0x1f, 0x02, 0xcd, 0xb0, 0x10, 0x28, 0x80, 0x0a, 0xf1, 0x24, 0x51, 0x42, + 0x52, 0x29, 0x80, 0x04, 0x00, 0x00, 0xa2, 0xe6, 0x08, 0x82, 0x62, 0x44, + 0x89, 0x92, 0x24, 0x16, 0x5d, 0x03, 0x01, 0x67, 0x09, 0x0b, 0x20, 0x49, + 0x3e, 0x03, 0x4c, 0x11, 0x72, 0xf9, 0xc5, 0xe2, 0x00, 0x93, 0x8f, 0xfb, + 0x38, 0x0a, 0x84, 0xe3, 0xa4, 0x29, 0xa2, 0x84, 0xc9, 0x7f, 0x89, 0x68, + 0x22, 0x2e, 0xf6, 0x00, 0x06, 0x22, 0xe2, 0x9c, 0x46, 0x9a, 0x80, 0x66, + 0x92, 0x90, 0xa0, 0x69, 0xc3, 0x08, 0x02, 0x70, 0x99, 0x34, 0x45, 0x94, + 0x30, 0xf9, 0x2f, 0x11, 0x4d, 0xc4, 0xc5, 0x1e, 0xc0, 0x40, 0x44, 0x28, + 0x35, 0x3d, 0xd4, 0x84, 0x86, 0x80, 0x0b, 0x86, 0x11, 0x06, 0xe0, 0x30, + 0x69, 0x8a, 0x28, 0x61, 0xf2, 0x5f, 0x22, 0x9a, 0x88, 0x8b, 0x3d, 0x80, + 0x81, 0x88, 0xc4, 0xe6, 0xa1, 0x26, 0x34, 0x78, 0x5c, 0x70, 0x09, 0xe7, + 0x34, 0xd2, 0x04, 0x34, 0x93, 0x84, 0x82, 0x2d, 0x1d, 0x12, 0x00, 0x13, + 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, 0x79, 0x68, + 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e, 0x6d, 0xd0, 0x0e, 0x7a, + 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, + 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, + 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, + 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, + 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, + 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, + 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, + 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, + 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x3a, 0x0f, 0x64, 0x90, 0x21, 0x23, 0x25, + 0x40, 0x00, 0x52, 0x00, 0xc0, 0x90, 0xe7, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x21, 0xcf, 0x02, 0x04, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x9e, 0x06, 0x08, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x3c, 0x12, 0x10, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x79, 0x28, + 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf2, + 0x5c, 0x40, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, + 0x05, 0x02, 0x00, 0x19, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x18, 0x19, + 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x52, 0x0a, + 0xa1, 0x08, 0xca, 0x80, 0x92, 0x12, 0x18, 0x01, 0x28, 0x86, 0x02, 0x14, + 0x28, 0x82, 0x42, 0x28, 0x83, 0x72, 0x28, 0x89, 0x02, 0x0c, 0x28, 0xb0, + 0x02, 0x29, 0xa0, 0xf2, 0x28, 0x8c, 0xd2, 0x0d, 0x28, 0x0a, 0x52, 0x4a, + 0x62, 0x04, 0x80, 0x8a, 0x19, 0x00, 0x22, 0x66, 0x00, 0x68, 0x98, 0x01, + 0xa0, 0x6d, 0x06, 0x80, 0xba, 0x19, 0x00, 0xfa, 0x66, 0x00, 0x08, 0x9c, + 0x01, 0xa0, 0x70, 0x2c, 0x87, 0x61, 0x9e, 0xe7, 0x01, 0x20, 0x30, 0x00, + 0x00, 0x10, 0x01, 0x21, 0x10, 0x0c, 0x40, 0x50, 0x00, 0x00, 0x00, 0x79, + 0x18, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x90, 0x46, + 0x02, 0x13, 0x44, 0x35, 0x18, 0x63, 0x0b, 0x73, 0x3b, 0x03, 0xb1, 0x2b, + 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x03, 0x99, 0x71, 0xb9, 0x01, 0x41, 0xa1, + 0x0b, 0x3b, 0x9b, 0x7b, 0x91, 0x2a, 0x62, 0x2a, 0x0a, 0x9a, 0x2a, 0xfa, + 0x9a, 0xb9, 0x81, 0x79, 0x31, 0x4b, 0x73, 0x0b, 0x63, 0x4b, 0xd9, 0x10, + 0x04, 0x13, 0x84, 0x44, 0x99, 0x20, 0x24, 0xcb, 0x06, 0x61, 0x20, 0x36, + 0x08, 0x04, 0x41, 0xc1, 0x6e, 0x6e, 0x82, 0x90, 0x30, 0x1b, 0x86, 0x03, + 0x21, 0x26, 0x08, 0x45, 0xc7, 0x64, 0xe8, 0xcd, 0x6d, 0x8e, 0x2e, 0xcc, + 0x8d, 0x6e, 0x6e, 0x82, 0x90, 0x34, 0x1b, 0x10, 0x42, 0x59, 0x08, 0x62, + 0x60, 0x80, 0x0d, 0x41, 0xb3, 0x81, 0x00, 0x00, 0x07, 0x98, 0x20, 0x6c, + 0x60, 0xc0, 0xa2, 0xed, 0x8d, 0xac, 0x8c, 0x6d, 0x82, 0x90, 0x38, 0x13, + 0x84, 0xe4, 0xd9, 0x30, 0x4c, 0xd3, 0x30, 0x41, 0x48, 0xa0, 0x09, 0x42, + 0x12, 0x4d, 0x10, 0x12, 0x69, 0x03, 0x82, 0x44, 0x12, 0x55, 0x11, 0xd6, + 0xc5, 0x08, 0x4e, 0xee, 0x4d, 0xad, 0x6c, 0x8c, 0x2e, 0xed, 0xcd, 0x2d, + 0xc8, 0x8d, 0xcc, 0x2a, 0xad, 0xec, 0x6e, 0x82, 0x90, 0x4c, 0x1b, 0x10, + 0x24, 0x93, 0xa8, 0x4a, 0xb3, 0xae, 0x0d, 0x03, 0x83, 0x6d, 0x13, 0x84, + 0x2e, 0x0c, 0x26, 0x08, 0x09, 0xc5, 0x01, 0xee, 0x6d, 0x8e, 0xcb, 0x94, + 0xd5, 0x17, 0xd4, 0xd3, 0x54, 0x12, 0x55, 0xd2, 0x93, 0xd3, 0x06, 0x04, + 0xf9, 0x2a, 0x62, 0x02, 0x03, 0xeb, 0xe2, 0x40, 0x57, 0x86, 0x37, 0x41, + 0x48, 0x2a, 0x26, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x30, + 0x1b, 0x10, 0x44, 0x0c, 0xaa, 0x31, 0x98, 0xc8, 0xc0, 0xba, 0x58, 0x8c, + 0xbd, 0xb1, 0xbd, 0xc9, 0x4d, 0x10, 0x12, 0x8b, 0xc6, 0xd0, 0x13, 0xd3, + 0x93, 0x14, 0xcc, 0x06, 0x04, 0x31, 0x83, 0xea, 0x0c, 0x26, 0x34, 0xb0, + 0xae, 0x0d, 0x84, 0x17, 0x06, 0x65, 0x90, 0x06, 0x13, 0x84, 0x4f, 0x0c, + 0x88, 0x40, 0x3d, 0x4d, 0x25, 0x51, 0x25, 0x3d, 0x39, 0x6d, 0x40, 0x90, + 0xaf, 0x22, 0x26, 0x36, 0xb0, 0xae, 0x0d, 0x84, 0xd7, 0x06, 0x65, 0x90, + 0x06, 0x13, 0x04, 0x30, 0x18, 0x83, 0x0d, 0x04, 0xb2, 0x54, 0xc4, 0x06, + 0x81, 0x81, 0x83, 0x09, 0xc2, 0xf0, 0x4d, 0x10, 0x08, 0x6f, 0x43, 0x43, + 0x40, 0x5c, 0xa7, 0x06, 0x6b, 0xe0, 0x06, 0x6f, 0x10, 0x07, 0x72, 0xc0, + 0xcd, 0x41, 0x1c, 0x4c, 0x10, 0x90, 0x60, 0x03, 0xb0, 0x61, 0x20, 0xec, + 0xc0, 0x0e, 0x36, 0x04, 0x77, 0xb0, 0x61, 0x18, 0xea, 0x00, 0x0f, 0x26, + 0x08, 0x61, 0x40, 0x06, 0x1b, 0x02, 0x3d, 0xa0, 0xd1, 0x16, 0x96, 0xe6, + 0xe6, 0x64, 0x35, 0x41, 0x50, 0xb6, 0x09, 0x82, 0xc2, 0x6d, 0x08, 0x88, + 0x09, 0x82, 0x92, 0x6c, 0x10, 0x2a, 0x6b, 0xc3, 0x42, 0xb0, 0x41, 0x1f, + 0xf8, 0xc1, 0x1f, 0xf8, 0xc1, 0x00, 0x0a, 0x84, 0x1f, 0x84, 0x02, 0x11, + 0xaa, 0x22, 0xac, 0xa1, 0xa7, 0x27, 0x29, 0xa2, 0x09, 0x82, 0x82, 0x6c, + 0x10, 0xaa, 0x6a, 0xc3, 0x32, 0x8c, 0x42, 0x1f, 0xf8, 0xc1, 0x1f, 0xf8, + 0xc1, 0x40, 0x0a, 0x83, 0x1f, 0x94, 0x02, 0x8b, 0xa1, 0x27, 0xa6, 0x27, + 0xa9, 0x09, 0x82, 0x72, 0x4c, 0x10, 0x92, 0x6b, 0x83, 0x50, 0xa5, 0xc2, + 0x86, 0x45, 0x3a, 0x85, 0x3e, 0xf0, 0x83, 0x3f, 0xf0, 0x83, 0x01, 0x15, + 0x24, 0x3f, 0x50, 0x85, 0x0d, 0x83, 0x28, 0x98, 0xc2, 0x2a, 0x70, 0x99, + 0xb2, 0xfa, 0x82, 0x7a, 0x9b, 0x4b, 0xa3, 0x4b, 0x7b, 0x73, 0xdb, 0xb0, + 0x10, 0xad, 0xd0, 0x07, 0xa0, 0xf0, 0x07, 0xa8, 0x30, 0xa0, 0x02, 0xe1, + 0x07, 0xaa, 0xb0, 0x61, 0x19, 0x46, 0xa1, 0x0f, 0xfc, 0xe0, 0x0f, 0x48, + 0x61, 0x20, 0x85, 0xc1, 0x0f, 0x4a, 0x61, 0xc3, 0x22, 0x9d, 0x42, 0x1f, + 0xf8, 0xc1, 0x1f, 0x90, 0xc2, 0x80, 0x0a, 0x92, 0x1f, 0xa8, 0xc2, 0x86, + 0xc1, 0x15, 0x5e, 0x01, 0x16, 0x36, 0x0c, 0xac, 0x10, 0x0b, 0xc0, 0x86, + 0xa2, 0x0e, 0xf8, 0x40, 0x16, 0x1e, 0x80, 0x86, 0x19, 0xdb, 0x5b, 0x18, + 0xdd, 0xdc, 0x04, 0x21, 0xc1, 0x58, 0xa4, 0xb9, 0xcd, 0xd1, 0xcd, 0x4d, + 0x10, 0x92, 0x8c, 0xc6, 0x5c, 0xda, 0xd9, 0x17, 0x1b, 0x19, 0x8d, 0xb9, + 0xb4, 0xb3, 0xaf, 0x39, 0xba, 0x09, 0x42, 0xa2, 0x6d, 0x40, 0x68, 0xa1, + 0x16, 0x6c, 0xe1, 0x16, 0x70, 0xe1, 0xca, 0x05, 0x5d, 0xa8, 0xc2, 0xc6, + 0x66, 0xd7, 0xe6, 0x92, 0x46, 0x56, 0xe6, 0x46, 0x37, 0x25, 0x08, 0xaa, + 0x90, 0xe1, 0xb9, 0xd8, 0x95, 0xc9, 0xcd, 0xa5, 0xbd, 0xb9, 0x4d, 0x09, + 0x88, 0x26, 0x64, 0x78, 0x2e, 0x76, 0x61, 0x6c, 0x76, 0x65, 0x72, 0x53, + 0x82, 0xa2, 0x0e, 0x19, 0x9e, 0xcb, 0x1c, 0x5a, 0x18, 0x59, 0x99, 0x5c, + 0xd3, 0x1b, 0x59, 0x19, 0xdb, 0x94, 0x00, 0x29, 0x43, 0x86, 0xe7, 0x22, + 0x57, 0x36, 0xf7, 0x56, 0x27, 0x37, 0x56, 0x36, 0x37, 0x25, 0x70, 0x2a, + 0x91, 0xe1, 0xb9, 0xd0, 0xe5, 0xc1, 0x95, 0x05, 0xb9, 0xb9, 0xbd, 0xd1, + 0x85, 0xd1, 0xa5, 0xbd, 0xb9, 0xcd, 0x4d, 0x11, 0xe6, 0x00, 0x0f, 0xea, + 0x90, 0xe1, 0xb9, 0xd8, 0xa5, 0x95, 0xdd, 0x25, 0x91, 0x4d, 0xd1, 0x85, + 0xd1, 0x95, 0x4d, 0x09, 0xf4, 0xa0, 0x0e, 0x19, 0x9e, 0x4b, 0x99, 0x1b, + 0x9d, 0x5c, 0x1e, 0xd4, 0x5b, 0x9a, 0x1b, 0xdd, 0xdc, 0x94, 0x40, 0x16, + 0xba, 0x90, 0xe1, 0xb9, 0x8c, 0xbd, 0xd5, 0xb9, 0xd1, 0x95, 0xc9, 0xcd, + 0x4d, 0x09, 0x74, 0x01, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x49, + 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, + 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, + 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, + 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, + 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, + 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, + 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, + 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, + 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, + 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, + 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, + 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, + 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, + 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, + 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, + 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, + 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, + 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, + 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, + 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, + 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, + 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, + 0xc3, 0x8c, 0xc8, 0x21, 0x07, 0x7c, 0x70, 0x03, 0x72, 0x10, 0x87, 0x73, + 0x70, 0x03, 0x7b, 0x08, 0x07, 0x79, 0x60, 0x87, 0x70, 0xc8, 0x87, 0x77, + 0xa8, 0x07, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x1c, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x71, 0x4e, 0x23, 0x4d, 0x40, 0x33, 0x49, + 0xff, 0x42, 0x18, 0x80, 0x80, 0x19, 0xc1, 0x36, 0x5c, 0xbe, 0xf3, 0xf8, + 0x42, 0x40, 0x15, 0x05, 0x11, 0x95, 0x0e, 0x30, 0x94, 0x84, 0x01, 0x08, + 0x98, 0x5f, 0xdc, 0xb6, 0x19, 0x48, 0xc3, 0xe5, 0x3b, 0x8f, 0x2f, 0x44, + 0x04, 0x30, 0x11, 0x21, 0xd0, 0x0c, 0x0b, 0x61, 0x02, 0xd3, 0x70, 0xf9, + 0xce, 0xe3, 0x2f, 0x0e, 0x30, 0x88, 0xcd, 0x43, 0x4d, 0x7e, 0x71, 0xdb, + 0x36, 0x50, 0x0d, 0x97, 0xef, 0x3c, 0xbe, 0x34, 0x39, 0x11, 0x81, 0x52, + 0xd3, 0x43, 0x4d, 0x7e, 0x71, 0xdb, 0x56, 0x20, 0x0d, 0x97, 0xef, 0x3c, + 0xfe, 0x44, 0x44, 0x13, 0x02, 0x44, 0x98, 0x5f, 0xdc, 0xb6, 0x05, 0x18, + 0x0c, 0x80, 0x34, 0xe7, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, + 0x41, 0x53, 0x48, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, + 0x7e, 0xdd, 0xd9, 0x5c, 0x85, 0x79, 0x2c, 0xb5, 0xd6, 0x2b, 0x4f, 0x5a, + 0xb5, 0xd4, 0xd5, 0x44, 0x58, 0x49, 0x4c, 0x18, 0x09, 0x00, 0x00, 0x60, + 0x00, 0x01, 0x00, 0x46, 0x02, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c, 0x00, + 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x42, + 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x3d, 0x02, 0x00, 0x00, 0x0b, + 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, + 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, + 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, + 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, + 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, + 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0xe4, 0x48, 0x0e, 0x90, 0x91, + 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, + 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1b, + 0x8c, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x40, 0x02, 0xa8, 0x0d, 0x84, + 0xf0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x20, 0x6d, 0x30, 0x86, 0xff, 0xff, + 0xff, 0xff, 0x1f, 0x00, 0x09, 0xa8, 0x00, 0x49, 0x18, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x13, 0x82, 0x60, 0x42, 0x20, 0x4c, 0x08, 0x06, 0x00, + 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x32, + 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, + 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, + 0x84, 0xa4, 0x4c, 0x10, 0x6c, 0x23, 0x00, 0x25, 0x00, 0x14, 0x66, 0x00, + 0xe6, 0x08, 0xc0, 0x60, 0x8e, 0x00, 0x29, 0xc6, 0x20, 0x84, 0x14, 0x42, + 0xa6, 0x18, 0x80, 0x10, 0x52, 0x06, 0xa1, 0xa3, 0x86, 0xcb, 0x9f, 0xb0, + 0x87, 0x90, 0x7c, 0x6e, 0xa3, 0x8a, 0x95, 0x98, 0xfc, 0xe2, 0xb6, 0x11, + 0x31, 0xc6, 0x18, 0x54, 0xee, 0x19, 0x2e, 0x7f, 0xc2, 0x1e, 0x42, 0xf2, + 0x43, 0xa0, 0x19, 0x16, 0x02, 0x05, 0xab, 0x10, 0x8a, 0x30, 0x42, 0xad, + 0x14, 0x83, 0x8c, 0x31, 0xe8, 0xcd, 0x11, 0x04, 0xc5, 0x60, 0xa4, 0x10, + 0x12, 0x49, 0x0e, 0x04, 0x0c, 0x23, 0x10, 0x43, 0x12, 0xd4, 0x83, 0x83, + 0xe1, 0xf2, 0x81, 0x05, 0x31, 0x1a, 0x86, 0x68, 0x26, 0x7f, 0x21, 0x0c, + 0x40, 0xc0, 0x7c, 0x69, 0x8a, 0x28, 0x61, 0xf2, 0x5f, 0x22, 0x9a, 0x88, + 0x8b, 0x3d, 0x80, 0x81, 0x88, 0x38, 0xa7, 0x91, 0x26, 0xa0, 0x99, 0x24, + 0x24, 0x58, 0x7b, 0xdd, 0x70, 0xf9, 0xc0, 0x82, 0x18, 0x0d, 0x43, 0x34, + 0x93, 0xbf, 0x10, 0x06, 0x20, 0x60, 0x3e, 0xe7, 0x34, 0xd2, 0x04, 0x34, + 0x93, 0x84, 0x82, 0x4b, 0x38, 0x1d, 0x08, 0x00, 0x00, 0x00, 0x00, 0x13, + 0x14, 0x72, 0xc0, 0x87, 0x74, 0x60, 0x87, 0x36, 0x68, 0x87, 0x79, 0x68, + 0x03, 0x72, 0xc0, 0x87, 0x0d, 0xaf, 0x50, 0x0e, 0x6d, 0xd0, 0x0e, 0x7a, + 0x50, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, + 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, + 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x71, + 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, + 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, + 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, + 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, + 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, + 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x43, 0x9e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x3c, 0x06, 0x10, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x79, 0x10, 0x20, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf2, 0x34, 0x40, + 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xe4, 0x79, + 0x80, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xc8, + 0x23, 0x01, 0x01, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x16, 0x08, 0x00, 0x10, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x14, 0x19, + 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x22, 0x25, + 0x30, 0x02, 0x50, 0x0c, 0x05, 0x28, 0x50, 0x06, 0xe5, 0x50, 0x04, 0xe5, + 0x41, 0xa5, 0x24, 0x46, 0x00, 0xca, 0xa0, 0x08, 0x0a, 0x81, 0xf2, 0x0c, + 0x00, 0xe9, 0xb1, 0x1c, 0x86, 0x79, 0x9e, 0x07, 0x80, 0xc0, 0x00, 0x00, + 0x40, 0x04, 0x84, 0x40, 0x30, 0x00, 0x41, 0x01, 0x00, 0x00, 0x00, 0x79, + 0x18, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x90, 0x46, + 0x02, 0x13, 0x44, 0x35, 0x18, 0x63, 0x0b, 0x73, 0x3b, 0x03, 0xb1, 0x2b, + 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x03, 0x99, 0x71, 0xb9, 0x01, 0x41, 0xa1, + 0x0b, 0x3b, 0x9b, 0x7b, 0x91, 0x2a, 0x62, 0x2a, 0x0a, 0x9a, 0x2a, 0xfa, + 0x9a, 0xb9, 0x81, 0x79, 0x31, 0x4b, 0x73, 0x0b, 0x63, 0x4b, 0xd9, 0x10, + 0x04, 0x13, 0x04, 0xc2, 0x98, 0x20, 0x10, 0xc7, 0x06, 0x61, 0x20, 0x26, + 0x08, 0x04, 0xb2, 0x41, 0x18, 0x0c, 0x0a, 0x76, 0x73, 0x1b, 0x06, 0xc4, + 0x20, 0x26, 0x08, 0xd9, 0x44, 0x60, 0x82, 0x40, 0x24, 0x1b, 0x10, 0x42, + 0x59, 0x08, 0x62, 0x60, 0x80, 0x0d, 0x41, 0xb3, 0x81, 0x00, 0x00, 0x07, + 0x98, 0x20, 0x68, 0xd4, 0x86, 0x00, 0x9a, 0x20, 0x08, 0x00, 0x8d, 0xb6, + 0xb0, 0x34, 0x37, 0x27, 0x2b, 0x22, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, + 0x4f, 0x4e, 0x13, 0x84, 0xc2, 0x99, 0x20, 0x14, 0xcf, 0x86, 0x80, 0x98, + 0x20, 0x14, 0xd0, 0x04, 0x81, 0x50, 0x26, 0x08, 0xc4, 0xb2, 0x41, 0xc8, + 0xb4, 0x0d, 0x0b, 0x41, 0x55, 0xd6, 0x65, 0x0d, 0x18, 0x61, 0x6d, 0x44, + 0xa8, 0x8a, 0xb0, 0x86, 0x9e, 0x9e, 0xa4, 0x88, 0x26, 0x08, 0x45, 0xb4, + 0x41, 0xc8, 0xb2, 0x0d, 0xcb, 0xd0, 0x55, 0xd6, 0x65, 0x0d, 0xde, 0x60, + 0x7d, 0x13, 0x04, 0x82, 0x61, 0x31, 0xf4, 0xc4, 0xf4, 0x24, 0x35, 0x41, + 0x28, 0xa4, 0x09, 0x02, 0xd1, 0x6c, 0x10, 0x32, 0x32, 0xd8, 0xb0, 0x84, + 0x81, 0x18, 0x54, 0xd6, 0x65, 0x0d, 0x63, 0x10, 0x06, 0x56, 0x19, 0x6c, + 0x18, 0x38, 0x30, 0x30, 0x03, 0x2e, 0x53, 0x56, 0x5f, 0x50, 0x6f, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x1b, 0x16, 0x02, 0x0d, 0x2a, 0xec, 0x1a, + 0x83, 0x61, 0x0c, 0x08, 0xab, 0x0c, 0x36, 0x2c, 0x43, 0x57, 0x59, 0x97, + 0x37, 0x78, 0x83, 0xf5, 0x6d, 0x58, 0xc2, 0x40, 0x0c, 0x2a, 0xeb, 0xf2, + 0x86, 0x31, 0x08, 0x03, 0xab, 0x0c, 0x36, 0x0c, 0x69, 0xa0, 0x06, 0x6b, + 0xb0, 0x61, 0x38, 0x03, 0x36, 0x00, 0x36, 0x14, 0xd2, 0xd4, 0x06, 0x0f, + 0x50, 0x85, 0x8d, 0xcd, 0xae, 0xcd, 0x25, 0x8d, 0xac, 0xcc, 0x8d, 0x6e, + 0x4a, 0x10, 0x54, 0x21, 0xc3, 0x73, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, + 0x73, 0x9b, 0x12, 0x10, 0x4d, 0xc8, 0xf0, 0x5c, 0xec, 0xc2, 0xd8, 0xec, + 0xca, 0xe4, 0xa6, 0x04, 0x46, 0x1d, 0x32, 0x3c, 0x97, 0x39, 0xb4, 0x30, + 0xb2, 0x32, 0xb9, 0xa6, 0x37, 0xb2, 0x32, 0xb6, 0x29, 0x01, 0x52, 0x86, + 0x0c, 0xcf, 0x45, 0xae, 0x6c, 0xee, 0xad, 0x4e, 0x6e, 0xac, 0x6c, 0x6e, + 0x4a, 0xe0, 0xd4, 0x21, 0xc3, 0x73, 0xb1, 0x4b, 0x2b, 0xbb, 0x4b, 0x22, + 0x9b, 0xa2, 0x0b, 0xa3, 0x2b, 0x9b, 0x12, 0x40, 0x75, 0xc8, 0xf0, 0x5c, + 0xca, 0xdc, 0xe8, 0xe4, 0xf2, 0xa0, 0xde, 0xd2, 0xdc, 0xe8, 0xe6, 0xa6, + 0x04, 0x6d, 0x00, 0x79, 0x18, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x33, + 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, + 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, + 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, + 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, + 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, + 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, + 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, + 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, + 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, + 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, + 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, + 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, + 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, + 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, + 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, + 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, + 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, + 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, + 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, + 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, + 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, + 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x8c, 0xc8, 0x21, + 0x07, 0x7c, 0x70, 0x03, 0x72, 0x10, 0x87, 0x73, 0x70, 0x03, 0x7b, 0x08, + 0x07, 0x79, 0x60, 0x87, 0x70, 0xc8, 0x87, 0x77, 0xa8, 0x07, 0x7a, 0x00, + 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x36, + 0xb0, 0x0d, 0x97, 0xef, 0x3c, 0xbe, 0x10, 0x50, 0x45, 0x41, 0x44, 0xa5, + 0x03, 0x0c, 0x25, 0x61, 0x00, 0x02, 0xe6, 0x17, 0xb7, 0x6d, 0x05, 0xd2, + 0x70, 0xf9, 0xce, 0xe3, 0x0b, 0x11, 0x01, 0x4c, 0x44, 0x08, 0x34, 0xc3, + 0x42, 0x58, 0xc0, 0x34, 0x5c, 0xbe, 0xf3, 0xf8, 0x8b, 0x03, 0x0c, 0x62, + 0xf3, 0x50, 0x93, 0x5f, 0xdc, 0xb6, 0x09, 0x54, 0xc3, 0xe5, 0x3b, 0x8f, + 0x2f, 0x4d, 0x4e, 0x44, 0xa0, 0xd4, 0xf4, 0x50, 0x93, 0x5f, 0xdc, 0xb6, + 0x11, 0x48, 0xc3, 0xe5, 0x3b, 0x8f, 0x3f, 0x11, 0xd1, 0x84, 0x00, 0x11, + 0xe6, 0x17, 0xb7, 0x6d, 0x00, 0x06, 0x03, 0x20, 0xcd, 0xf9, 0x02, 0x61, + 0x20, 0x00, 0x00, 0xcf, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, + 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x44, 0x8a, 0xab, 0x14, 0x0a, + 0x61, 0x06, 0xa0, 0xec, 0x4a, 0x8e, 0x4a, 0x09, 0x50, 0x1c, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x20, 0x61, 0x03, + 0x63, 0x59, 0xc1, 0x88, 0x41, 0x02, 0x80, 0x20, 0x18, 0x18, 0xdd, 0x21, + 0x5d, 0x8f, 0x31, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x86, 0x87, 0x4c, + 0x18, 0x71, 0x8c, 0x18, 0x24, 0x00, 0x08, 0x82, 0x81, 0xf1, 0x25, 0x54, + 0xf6, 0x20, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x60, 0x80, 0x81, 0x52, + 0x69, 0x51, 0x32, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x46, 0x18, 0x2c, + 0xdc, 0x36, 0x29, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x60, 0x88, 0x01, + 0xd3, 0x71, 0xc8, 0x32, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0xc6, 0x18, + 0x34, 0x5d, 0x57, 0x31, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x60, 0x90, + 0x81, 0xe3, 0x79, 0x4a, 0x33, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x46, + 0x19, 0x3c, 0xdf, 0x57, 0x39, 0x23, 0x06, 0x07, 0x00, 0x82, 0x60, 0xd0, + 0x90, 0x81, 0xa3, 0x80, 0xc1, 0x68, 0x42, 0x00, 0x8c, 0x26, 0x08, 0xc1, + 0x68, 0xc2, 0x20, 0x8c, 0x26, 0x10, 0xc3, 0x88, 0xc1, 0x01, 0x80, 0x20, + 0x18, 0x34, 0x69, 0x30, 0x3d, 0x66, 0x30, 0x9a, 0x10, 0x00, 0xa3, 0x09, + 0x42, 0x30, 0x9a, 0x30, 0x08, 0xa3, 0x09, 0xc4, 0x30, 0x62, 0x70, 0x00, + 0x20, 0x08, 0x06, 0x8d, 0x1b, 0x60, 0x54, 0x19, 0x8c, 0x26, 0x04, 0xc0, + 0x68, 0x82, 0x10, 0x8c, 0x26, 0x0c, 0xc2, 0x68, 0x02, 0x31, 0x8c, 0x18, + 0x1c, 0x00, 0x08, 0x82, 0x41, 0x33, 0x07, 0x5d, 0xc6, 0x06, 0xa3, 0x09, + 0x01, 0x30, 0x9a, 0x20, 0x04, 0xa3, 0x09, 0x83, 0x30, 0x9a, 0x40, 0x0c, + 0x36, 0x5d, 0xf2, 0x19, 0x31, 0x40, 0x00, 0x10, 0x04, 0x83, 0x07, 0x0f, + 0xce, 0xe0, 0x7a, 0x82, 0x11, 0x03, 0x04, 0x00, 0x41, 0x30, 0x78, 0xf2, + 0x00, 0x0d, 0xae, 0x25, 0xb0, 0xe0, 0x80, 0x8e, 0x59, 0x9b, 0x7c, 0x46, + 0x0c, 0x10, 0x00, 0x04, 0xc1, 0xe0, 0xe1, 0x83, 0x35, 0xd8, 0xa4, 0x60, + 0xc4, 0x00, 0x01, 0x40, 0x10, 0x0c, 0x9e, 0x3e, 0x60, 0x83, 0xcd, 0x09, + 0x2c, 0x50, 0xa0, 0x63, 0xd9, 0x27, 0x9f, 0x11, 0x03, 0x04, 0x00, 0x41, + 0x30, 0x78, 0x40, 0xe1, 0x0d, 0xbe, 0x2a, 0x18, 0x31, 0x40, 0x00, 0x10, + 0x04, 0x83, 0x27, 0x14, 0xe0, 0xe0, 0x8b, 0x02, 0x0b, 0x1a, 0xe8, 0x18, + 0x37, 0x06, 0xf2, 0x19, 0x31, 0x40, 0x00, 0x10, 0x04, 0x83, 0x87, 0x14, + 0xe6, 0x60, 0x0c, 0xb0, 0x60, 0xc4, 0x00, 0x01, 0x40, 0x10, 0x0c, 0x9e, + 0x52, 0xa0, 0x83, 0x31, 0xa0, 0x02, 0x0b, 0x20, 0xe8, 0x8c, 0x18, 0x1c, + 0x00, 0x08, 0x82, 0x41, 0x83, 0x0a, 0x72, 0xe0, 0x06, 0x74, 0x30, 0x9a, + 0x10, 0x00, 0xa3, 0x09, 0x42, 0x30, 0x9a, 0x30, 0x08, 0xa3, 0x09, 0xc4, + 0x30, 0x62, 0x70, 0x00, 0x20, 0x08, 0x06, 0x4d, 0x2b, 0xdc, 0xc1, 0x1c, + 0xe8, 0xc1, 0x68, 0x42, 0x00, 0x8c, 0x26, 0x08, 0xc1, 0x68, 0xc2, 0x20, + 0x8c, 0x26, 0x10, 0xc3, 0x88, 0xc1, 0x01, 0x80, 0x20, 0x18, 0x34, 0xb2, + 0xc0, 0x07, 0x78, 0xd0, 0x0a, 0xa3, 0x09, 0x01, 0x30, 0x9a, 0x20, 0x04, + 0xa3, 0x09, 0x83, 0x30, 0x9a, 0x40, 0x0c, 0x23, 0x06, 0x07, 0x00, 0x82, + 0x60, 0xd0, 0xdc, 0x42, 0x28, 0xf4, 0xc1, 0x2b, 0x8c, 0x26, 0x04, 0xc0, + 0x68, 0x82, 0x10, 0x8c, 0x26, 0x0c, 0xc2, 0x68, 0x02, 0x31, 0xd8, 0x14, + 0x06, 0xf2, 0x19, 0x31, 0x40, 0x00, 0x10, 0x04, 0x83, 0x87, 0x17, 0x56, + 0xc1, 0x7b, 0x82, 0x11, 0x03, 0x04, 0x00, 0x41, 0x30, 0x78, 0x7a, 0x81, + 0x15, 0xb6, 0x25, 0x18, 0x31, 0x40, 0x00, 0x10, 0x04, 0x83, 0xc7, 0x17, + 0x5a, 0x01, 0x3b, 0x02, 0xb3, 0xca, 0x40, 0x3e, 0x23, 0x06, 0x08, 0x00, + 0x82, 0x60, 0xf0, 0x80, 0xc3, 0x2b, 0x88, 0x81, 0x14, 0x8c, 0x18, 0x20, + 0x00, 0x08, 0x82, 0xc1, 0x13, 0x0e, 0xb0, 0xf0, 0x39, 0xc1, 0x88, 0x01, + 0x02, 0x80, 0x20, 0x18, 0x3c, 0xe2, 0x10, 0x0b, 0x9c, 0x12, 0x58, 0x96, + 0x06, 0xf2, 0x19, 0x31, 0x40, 0x00, 0x10, 0x04, 0x83, 0x87, 0x1c, 0x66, + 0xc1, 0x0c, 0xaa, 0x60, 0xc4, 0x00, 0x01, 0x40, 0x10, 0x0c, 0x9e, 0x72, + 0xa0, 0x85, 0x31, 0x88, 0x82, 0x11, 0x03, 0x04, 0x00, 0x41, 0x30, 0x78, + 0xcc, 0xa1, 0x16, 0xc0, 0xa0, 0x09, 0x8c, 0x6b, 0x03, 0xf9, 0x8c, 0x18, + 0x20, 0x00, 0x08, 0x82, 0xc1, 0x83, 0x0e, 0xb7, 0xa0, 0x06, 0x58, 0x30, + 0x62, 0x80, 0x00, 0x20, 0x08, 0x06, 0x4f, 0x3a, 0xe0, 0xc2, 0x19, 0x50, + 0xc1, 0x88, 0x01, 0x02, 0x80, 0x20, 0x18, 0x3c, 0xea, 0x90, 0x0b, 0x64, + 0x00, 0x05, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x80, 0xb4, 0x43, 0x2e, + 0xa0, 0x03, 0x3a, 0x80, 0x43, 0x33, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, + 0x48, 0x3b, 0xe4, 0x02, 0x3a, 0xa0, 0x03, 0x2d, 0x24, 0x23, 0x06, 0x09, + 0x00, 0x82, 0x60, 0x80, 0xb4, 0x43, 0x2e, 0xa0, 0x03, 0x3a, 0xf8, 0x42, + 0x31, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x48, 0x3b, 0xe4, 0x02, 0x3a, + 0xa0, 0xc3, 0x2f, 0x04, 0x23, 0x06, 0x09, 0x00, 0x82, 0x60, 0x80, 0xb4, + 0x43, 0x2e, 0xa4, 0x03, 0x3a, 0x80, 0x43, 0x2b, 0x8c, 0x18, 0x24, 0x00, + 0x08, 0x82, 0x01, 0xd2, 0x0e, 0xb9, 0x90, 0x0e, 0xe8, 0x40, 0x0b, 0xac, + 0x30, 0x62, 0x90, 0x00, 0x20, 0x08, 0x06, 0x48, 0x3b, 0xe4, 0xc2, 0x38, + 0xa0, 0x03, 0x38, 0xc4, 0xc2, 0x88, 0x41, 0x02, 0x80, 0x20, 0x18, 0x20, + 0xed, 0x90, 0x0b, 0xe3, 0x80, 0x0e, 0xb4, 0x00, 0x0b, 0x23, 0x06, 0x09, + 0x00, 0x82, 0x60, 0x80, 0xb4, 0x43, 0x2e, 0x8c, 0x03, 0x3a, 0xf8, 0xc2, + 0x2b, 0x8c, 0x18, 0x24, 0x00, 0x08, 0x82, 0x01, 0xd2, 0x0e, 0xb9, 0x30, + 0x0e, 0xe8, 0xf0, 0x0b, 0xae, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +/* Root signature blobs extracted from Vertex Shader + dxc command line is: + dxc -E -T rootsig_1_1 -rootsig-define -Fo D3D12_VertexShader.hlsl + + Variables: + - : the root signature define + - : the output file name. + +*/ + +static unsigned char D3D12_RootSig_Color[] = { + 0x44, 0x58, 0x42, 0x43, 0x16, 0xb1, 0xe2, 0x29, 0x64, 0xb1, 0xb2, 0xe8, + 0x3c, 0xf7, 0xf6, 0x21, 0xad, 0x40, 0xa9, 0x50, 0x01, 0x00, 0x00, 0x00, + 0x5c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, + 0x52, 0x54, 0x53, 0x30, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00 +}; + +static unsigned char D3D12_RootSig_Texture[] = { + 0x44, 0x58, 0x42, 0x43, 0x7a, 0x3c, 0xe5, 0xd1, 0x3c, 0x38, 0x44, 0x34, + 0xda, 0xbc, 0x9b, 0xfc, 0xb3, 0xe7, 0x95, 0xaa, 0x01, 0x00, 0x00, 0x00, + 0xb4, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, + 0x52, 0x54, 0x53, 0x30, 0x88, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x88, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff +}; + +static unsigned char D3D12_RootSig_YUV[] = { + 0x44, 0x58, 0x42, 0x43, 0x65, 0xa2, 0x64, 0x32, 0x6e, 0x35, 0x8d, 0x76, + 0xf7, 0x54, 0x3c, 0x62, 0x2e, 0x8e, 0xa4, 0xbc, 0x01, 0x00, 0x00, 0x00, + 0x0c, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, + 0x52, 0x54, 0x53, 0x30, 0xe0, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x01, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, + 0xc8, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff +}; + +static unsigned char D3D12_RootSig_NV[] = { + 0x44, 0x58, 0x42, 0x43, 0x22, 0xd8, 0x7c, 0x4d, 0xb5, 0x44, 0x4a, 0xcd, + 0x25, 0xc2, 0x80, 0xac, 0x89, 0xb0, 0xa6, 0xfe, 0x01, 0x00, 0x00, 0x00, + 0xe0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, + 0x52, 0x54, 0x53, 0x30, 0xb4, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xb4, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x01, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff +}; + +static struct +{ + const void *ps_shader_data; + SIZE_T ps_shader_size; + const void *vs_shader_data; + SIZE_T vs_shader_size; + D3D12_RootSignature root_sig; +} D3D12_shaders[NUM_SHADERS] = { + { D3D12_PixelShader_Colors, sizeof(D3D12_PixelShader_Colors), + D3D12_VertexShader_Colors, sizeof(D3D12_VertexShader_Colors), + ROOTSIG_COLOR }, + { D3D12_PixelShader_Textures, sizeof(D3D12_PixelShader_Textures), + D3D12_VertexShader_Textures, sizeof(D3D12_VertexShader_Textures), + ROOTSIG_TEXTURE }, +#if SDL_HAVE_YUV + { D3D12_PixelShader_YUV_JPEG, sizeof(D3D12_PixelShader_YUV_JPEG), + D3D12_VertexShader_YUV, sizeof(D3D12_VertexShader_YUV), + ROOTSIG_YUV }, + { D3D12_PixelShader_YUV_BT601, sizeof(D3D12_PixelShader_YUV_BT601), + D3D12_VertexShader_YUV, sizeof(D3D12_VertexShader_YUV), + ROOTSIG_YUV }, + { D3D12_PixelShader_YUV_BT709, sizeof(D3D12_PixelShader_YUV_BT709), + D3D12_VertexShader_YUV, sizeof(D3D12_VertexShader_YUV), + ROOTSIG_YUV }, + { D3D12_PixelShader_NV12_JPEG, sizeof(D3D12_PixelShader_NV12_JPEG), + D3D12_VertexShader_NV, sizeof(D3D12_VertexShader_NV), + ROOTSIG_NV }, + { D3D12_PixelShader_NV12_BT601, sizeof(D3D12_PixelShader_NV12_BT601), + D3D12_VertexShader_NV, sizeof(D3D12_VertexShader_NV), + ROOTSIG_NV }, + { D3D12_PixelShader_NV12_BT709, sizeof(D3D12_PixelShader_NV12_BT709), + D3D12_VertexShader_NV, sizeof(D3D12_VertexShader_NV), + ROOTSIG_NV }, + { D3D12_PixelShader_NV21_JPEG, sizeof(D3D12_PixelShader_NV21_JPEG), + D3D12_VertexShader_NV, sizeof(D3D12_VertexShader_NV), + ROOTSIG_NV }, + { D3D12_PixelShader_NV21_BT601, sizeof(D3D12_PixelShader_NV21_BT601), + D3D12_VertexShader_NV, sizeof(D3D12_VertexShader_NV), + ROOTSIG_NV }, + { D3D12_PixelShader_NV21_BT709, sizeof(D3D12_PixelShader_NV21_BT709), + D3D12_VertexShader_NV, sizeof(D3D12_VertexShader_NV), + ROOTSIG_NV }, +#endif +}; + +static struct +{ + const void *rs_shader_data; + SIZE_T rs_shader_size; +} D3D12_rootsigs[NUM_ROOTSIGS] = { + { D3D12_RootSig_Color, sizeof(D3D12_RootSig_Color) }, + { D3D12_RootSig_Texture, sizeof(D3D12_RootSig_Texture) }, +#if SDL_HAVE_YUV + { D3D12_RootSig_YUV, sizeof(D3D12_RootSig_YUV) }, + { D3D12_RootSig_NV, sizeof(D3D12_RootSig_NV) }, +#endif +}; + +void D3D12_GetVertexShader(D3D12_Shader shader, D3D12_SHADER_BYTECODE *outBytecode) +{ + outBytecode->pShaderBytecode = D3D12_shaders[shader].vs_shader_data; + outBytecode->BytecodeLength = D3D12_shaders[shader].vs_shader_size; +} + +void D3D12_GetPixelShader(D3D12_Shader shader, D3D12_SHADER_BYTECODE *outBytecode) +{ + outBytecode->pShaderBytecode = D3D12_shaders[shader].ps_shader_data; + outBytecode->BytecodeLength = D3D12_shaders[shader].ps_shader_size; +} + +D3D12_RootSignature D3D12_GetRootSignatureType(D3D12_Shader shader) +{ + return D3D12_shaders[shader].root_sig; +} + +void D3D12_GetRootSignatureData(D3D12_RootSignature rootSig, D3D12_SHADER_BYTECODE *outBytecode) +{ + outBytecode->pShaderBytecode = D3D12_rootsigs[rootSig].rs_shader_data; + outBytecode->BytecodeLength = D3D12_rootsigs[rootSig].rs_shader_size; +} + +#endif /* SDL_VIDEO_RENDER_D3D12 && !defined(__XBOXONE__) && !defined(__XBOXSERIES__) */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/render/direct3d12/SDL_shaders_d3d12.h b/SDL2-2.30.5/src/render/direct3d12/SDL_shaders_d3d12.h new file mode 100644 index 0000000..f0c528d --- /dev/null +++ b/SDL2-2.30.5/src/render/direct3d12/SDL_shaders_d3d12.h @@ -0,0 +1,69 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +/* D3D12 shader implementation */ + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum +{ + SHADER_SOLID, + SHADER_RGB, +#if SDL_HAVE_YUV + SHADER_YUV_JPEG, + SHADER_YUV_BT601, + SHADER_YUV_BT709, + SHADER_NV12_JPEG, + SHADER_NV12_BT601, + SHADER_NV12_BT709, + SHADER_NV21_JPEG, + SHADER_NV21_BT601, + SHADER_NV21_BT709, +#endif + NUM_SHADERS +} D3D12_Shader; + +typedef enum +{ + ROOTSIG_COLOR, + ROOTSIG_TEXTURE, +#if SDL_HAVE_YUV + ROOTSIG_YUV, + ROOTSIG_NV, +#endif + NUM_ROOTSIGS +} D3D12_RootSignature; + +extern void D3D12_GetVertexShader(D3D12_Shader shader, D3D12_SHADER_BYTECODE *outBytecode); +extern void D3D12_GetPixelShader(D3D12_Shader shader, D3D12_SHADER_BYTECODE *outBytecode); +extern D3D12_RootSignature D3D12_GetRootSignatureType(D3D12_Shader shader); +extern void D3D12_GetRootSignatureData(D3D12_RootSignature rootSig, D3D12_SHADER_BYTECODE *outBytecode); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/render/direct3d12/SDL_shaders_d3d12_xboxone.cpp b/SDL2-2.30.5/src/render/direct3d12/SDL_shaders_d3d12_xboxone.cpp new file mode 100644 index 0000000..cc5c84f --- /dev/null +++ b/SDL2-2.30.5/src/render/direct3d12/SDL_shaders_d3d12_xboxone.cpp @@ -0,0 +1,144 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#if SDL_VIDEO_RENDER_D3D12 && defined(__XBOXONE__) + +#include + +#include "../../core/windows/SDL_windows.h" +#include + +#include "SDL_shaders_d3d12.h" + +#define SDL_COMPOSE_ERROR(str) SDL_STRINGIFY_ARG(__FUNCTION__) ", " str + +/* Shader blob headers are generated with a pre-build step using buildshaders.bat */ +#include "../VisualC-GDK/shaders/D3D12_PixelShader_Colors_One.h" +#include "../VisualC-GDK/shaders/D3D12_PixelShader_NV12_BT601_One.h" +#include "../VisualC-GDK/shaders/D3D12_PixelShader_NV12_BT709_One.h" +#include "../VisualC-GDK/shaders/D3D12_PixelShader_NV12_JPEG_One.h" +#include "../VisualC-GDK/shaders/D3D12_PixelShader_NV21_BT601_One.h" +#include "../VisualC-GDK/shaders/D3D12_PixelShader_NV21_BT709_One.h" +#include "../VisualC-GDK/shaders/D3D12_PixelShader_NV21_JPEG_One.h" +#include "../VisualC-GDK/shaders/D3D12_PixelShader_Textures_One.h" +#include "../VisualC-GDK/shaders/D3D12_PixelShader_YUV_BT601_One.h" +#include "../VisualC-GDK/shaders/D3D12_PixelShader_YUV_BT709_One.h" +#include "../VisualC-GDK/shaders/D3D12_PixelShader_YUV_JPEG_One.h" + +#include "../VisualC-GDK/shaders/D3D12_VertexShader_Color_One.h" +#include "../VisualC-GDK/shaders/D3D12_VertexShader_NV_One.h" +#include "../VisualC-GDK/shaders/D3D12_VertexShader_Texture_One.h" +#include "../VisualC-GDK/shaders/D3D12_VertexShader_YUV_One.h" + +#include "../VisualC-GDK/shaders/D3D12_RootSig_Color_One.h" +#include "../VisualC-GDK/shaders/D3D12_RootSig_NV_One.h" +#include "../VisualC-GDK/shaders/D3D12_RootSig_Texture_One.h" +#include "../VisualC-GDK/shaders/D3D12_RootSig_YUV_One.h" + +static struct +{ + const void *ps_shader_data; + SIZE_T ps_shader_size; + const void *vs_shader_data; + SIZE_T vs_shader_size; + D3D12_RootSignature root_sig; +} D3D12_shaders[NUM_SHADERS] = { + { D3D12_PixelShader_Colors, sizeof(D3D12_PixelShader_Colors), + D3D12_VertexShader_Color, sizeof(D3D12_VertexShader_Color), + ROOTSIG_COLOR }, + { D3D12_PixelShader_Textures, sizeof(D3D12_PixelShader_Textures), + D3D12_VertexShader_Texture, sizeof(D3D12_VertexShader_Texture), + ROOTSIG_TEXTURE }, +#if SDL_HAVE_YUV + { D3D12_PixelShader_YUV_JPEG, sizeof(D3D12_PixelShader_YUV_JPEG), + D3D12_VertexShader_YUV, sizeof(D3D12_VertexShader_YUV), + ROOTSIG_YUV }, + { D3D12_PixelShader_YUV_BT601, sizeof(D3D12_PixelShader_YUV_BT601), + D3D12_VertexShader_YUV, sizeof(D3D12_VertexShader_YUV), + ROOTSIG_YUV }, + { D3D12_PixelShader_YUV_BT709, sizeof(D3D12_PixelShader_YUV_BT709), + D3D12_VertexShader_YUV, sizeof(D3D12_VertexShader_YUV), + ROOTSIG_YUV }, + { D3D12_PixelShader_NV12_JPEG, sizeof(D3D12_PixelShader_NV12_JPEG), + D3D12_VertexShader_NV, sizeof(D3D12_VertexShader_NV), + ROOTSIG_NV }, + { D3D12_PixelShader_NV12_BT601, sizeof(D3D12_PixelShader_NV12_BT601), + D3D12_VertexShader_NV, sizeof(D3D12_VertexShader_NV), + ROOTSIG_NV }, + { D3D12_PixelShader_NV12_BT709, sizeof(D3D12_PixelShader_NV12_BT709), + D3D12_VertexShader_NV, sizeof(D3D12_VertexShader_NV), + ROOTSIG_NV }, + { D3D12_PixelShader_NV21_JPEG, sizeof(D3D12_PixelShader_NV21_JPEG), + D3D12_VertexShader_NV, sizeof(D3D12_VertexShader_NV), + ROOTSIG_NV }, + { D3D12_PixelShader_NV21_BT601, sizeof(D3D12_PixelShader_NV21_BT601), + D3D12_VertexShader_NV, sizeof(D3D12_VertexShader_NV), + ROOTSIG_NV }, + { D3D12_PixelShader_NV21_BT709, sizeof(D3D12_PixelShader_NV21_BT709), + D3D12_VertexShader_NV, sizeof(D3D12_VertexShader_NV), + ROOTSIG_NV }, +#endif +}; + +static struct +{ + const void *rs_shader_data; + SIZE_T rs_shader_size; +} D3D12_rootsigs[NUM_ROOTSIGS] = { + { D3D12_RootSig_Color, sizeof(D3D12_RootSig_Color) }, + { D3D12_RootSig_Texture, sizeof(D3D12_RootSig_Texture) }, +#if SDL_HAVE_YUV + { D3D12_RootSig_YUV, sizeof(D3D12_RootSig_YUV) }, + { D3D12_RootSig_NV, sizeof(D3D12_RootSig_NV) }, +#endif +}; + +extern "C" void +D3D12_GetVertexShader(D3D12_Shader shader, D3D12_SHADER_BYTECODE *outBytecode) +{ + outBytecode->pShaderBytecode = D3D12_shaders[shader].vs_shader_data; + outBytecode->BytecodeLength = D3D12_shaders[shader].vs_shader_size; +} + +extern "C" void +D3D12_GetPixelShader(D3D12_Shader shader, D3D12_SHADER_BYTECODE *outBytecode) +{ + outBytecode->pShaderBytecode = D3D12_shaders[shader].ps_shader_data; + outBytecode->BytecodeLength = D3D12_shaders[shader].ps_shader_size; +} + +extern "C" D3D12_RootSignature +D3D12_GetRootSignatureType(D3D12_Shader shader) +{ + return D3D12_shaders[shader].root_sig; +} + +extern "C" void +D3D12_GetRootSignatureData(D3D12_RootSignature rootSig, D3D12_SHADER_BYTECODE *outBytecode) +{ + outBytecode->pShaderBytecode = D3D12_rootsigs[rootSig].rs_shader_data; + outBytecode->BytecodeLength = D3D12_rootsigs[rootSig].rs_shader_size; +} + +#endif /* SDL_VIDEO_RENDER_D3D12 && defined(__XBOXONE__) */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/render/direct3d12/SDL_shaders_d3d12_xboxseries.cpp b/SDL2-2.30.5/src/render/direct3d12/SDL_shaders_d3d12_xboxseries.cpp new file mode 100644 index 0000000..f1e4063 --- /dev/null +++ b/SDL2-2.30.5/src/render/direct3d12/SDL_shaders_d3d12_xboxseries.cpp @@ -0,0 +1,144 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#if SDL_VIDEO_RENDER_D3D12 && defined(__XBOXSERIES__) + +#include + +#include "../../core/windows/SDL_windows.h" +#include + +#include "SDL_shaders_d3d12.h" + +#define SDL_COMPOSE_ERROR(str) SDL_STRINGIFY_ARG(__FUNCTION__) ", " str + +/* Shader blob headers are generated with a pre-build step using buildshaders.bat */ +#include "../VisualC-GDK/shaders/D3D12_PixelShader_Colors_Series.h" +#include "../VisualC-GDK/shaders/D3D12_PixelShader_Textures_Series.h" +#include "../VisualC-GDK/shaders/D3D12_PixelShader_NV12_BT601_Series.h" +#include "../VisualC-GDK/shaders/D3D12_PixelShader_NV12_BT709_Series.h" +#include "../VisualC-GDK/shaders/D3D12_PixelShader_NV12_JPEG_Series.h" +#include "../VisualC-GDK/shaders/D3D12_PixelShader_NV21_BT601_Series.h" +#include "../VisualC-GDK/shaders/D3D12_PixelShader_NV21_BT709_Series.h" +#include "../VisualC-GDK/shaders/D3D12_PixelShader_NV21_JPEG_Series.h" +#include "../VisualC-GDK/shaders/D3D12_PixelShader_YUV_BT601_Series.h" +#include "../VisualC-GDK/shaders/D3D12_PixelShader_YUV_BT709_Series.h" +#include "../VisualC-GDK/shaders/D3D12_PixelShader_YUV_JPEG_Series.h" + +#include "../VisualC-GDK/shaders/D3D12_VertexShader_Color_Series.h" +#include "../VisualC-GDK/shaders/D3D12_VertexShader_Texture_Series.h" +#include "../VisualC-GDK/shaders/D3D12_VertexShader_NV_Series.h" +#include "../VisualC-GDK/shaders/D3D12_VertexShader_YUV_Series.h" + +#include "../VisualC-GDK/shaders/D3D12_RootSig_Color_Series.h" +#include "../VisualC-GDK/shaders/D3D12_RootSig_Texture_Series.h" +#include "../VisualC-GDK/shaders/D3D12_RootSig_YUV_Series.h" +#include "../VisualC-GDK/shaders/D3D12_RootSig_NV_Series.h" + +static struct +{ + const void *ps_shader_data; + SIZE_T ps_shader_size; + const void *vs_shader_data; + SIZE_T vs_shader_size; + D3D12_RootSignature root_sig; +} D3D12_shaders[NUM_SHADERS] = { + { D3D12_PixelShader_Colors, sizeof(D3D12_PixelShader_Colors), + D3D12_VertexShader_Color, sizeof(D3D12_VertexShader_Color), + ROOTSIG_COLOR }, + { D3D12_PixelShader_Textures, sizeof(D3D12_PixelShader_Textures), + D3D12_VertexShader_Texture, sizeof(D3D12_VertexShader_Texture), + ROOTSIG_TEXTURE }, +#if SDL_HAVE_YUV + { D3D12_PixelShader_YUV_JPEG, sizeof(D3D12_PixelShader_YUV_JPEG), + D3D12_VertexShader_YUV, sizeof(D3D12_VertexShader_YUV), + ROOTSIG_YUV }, + { D3D12_PixelShader_YUV_BT601, sizeof(D3D12_PixelShader_YUV_BT601), + D3D12_VertexShader_YUV, sizeof(D3D12_VertexShader_YUV), + ROOTSIG_YUV }, + { D3D12_PixelShader_YUV_BT709, sizeof(D3D12_PixelShader_YUV_BT709), + D3D12_VertexShader_YUV, sizeof(D3D12_VertexShader_YUV), + ROOTSIG_YUV }, + { D3D12_PixelShader_NV12_JPEG, sizeof(D3D12_PixelShader_NV12_JPEG), + D3D12_VertexShader_NV, sizeof(D3D12_VertexShader_NV), + ROOTSIG_NV }, + { D3D12_PixelShader_NV12_BT601, sizeof(D3D12_PixelShader_NV12_BT601), + D3D12_VertexShader_NV, sizeof(D3D12_VertexShader_NV), + ROOTSIG_NV }, + { D3D12_PixelShader_NV12_BT709, sizeof(D3D12_PixelShader_NV12_BT709), + D3D12_VertexShader_NV, sizeof(D3D12_VertexShader_NV), + ROOTSIG_NV }, + { D3D12_PixelShader_NV21_JPEG, sizeof(D3D12_PixelShader_NV21_JPEG), + D3D12_VertexShader_NV, sizeof(D3D12_VertexShader_NV), + ROOTSIG_NV }, + { D3D12_PixelShader_NV21_BT601, sizeof(D3D12_PixelShader_NV21_BT601), + D3D12_VertexShader_NV, sizeof(D3D12_VertexShader_NV), + ROOTSIG_NV }, + { D3D12_PixelShader_NV21_BT709, sizeof(D3D12_PixelShader_NV21_BT709), + D3D12_VertexShader_NV, sizeof(D3D12_VertexShader_NV), + ROOTSIG_NV }, +#endif +}; + +static struct +{ + const void *rs_shader_data; + SIZE_T rs_shader_size; +} D3D12_rootsigs[NUM_ROOTSIGS] = { + { D3D12_RootSig_Color, sizeof(D3D12_RootSig_Color) }, + { D3D12_RootSig_Texture, sizeof(D3D12_RootSig_Texture) }, +#if SDL_HAVE_YUV + { D3D12_RootSig_YUV, sizeof(D3D12_RootSig_YUV) }, + { D3D12_RootSig_NV, sizeof(D3D12_RootSig_NV) }, +#endif +}; + +extern "C" void +D3D12_GetVertexShader(D3D12_Shader shader, D3D12_SHADER_BYTECODE *outBytecode) +{ + outBytecode->pShaderBytecode = D3D12_shaders[shader].vs_shader_data; + outBytecode->BytecodeLength = D3D12_shaders[shader].vs_shader_size; +} + +extern "C" void +D3D12_GetPixelShader(D3D12_Shader shader, D3D12_SHADER_BYTECODE *outBytecode) +{ + outBytecode->pShaderBytecode = D3D12_shaders[shader].ps_shader_data; + outBytecode->BytecodeLength = D3D12_shaders[shader].ps_shader_size; +} + +extern "C" D3D12_RootSignature +D3D12_GetRootSignatureType(D3D12_Shader shader) +{ + return D3D12_shaders[shader].root_sig; +} + +extern "C" void +D3D12_GetRootSignatureData(D3D12_RootSignature rootSig, D3D12_SHADER_BYTECODE *outBytecode) +{ + outBytecode->pShaderBytecode = D3D12_rootsigs[rootSig].rs_shader_data; + outBytecode->BytecodeLength = D3D12_rootsigs[rootSig].rs_shader_size; +} + +#endif /* SDL_VIDEO_RENDER_D3D12 && defined(__XBOXSERIES__) */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/render/metal/SDL_render_metal.m b/SDL2-2.30.5/src/render/metal/SDL_render_metal.m similarity index 72% rename from SDL2-2.0.12/src/render/metal/SDL_render_metal.m rename to SDL2-2.30.5/src/render/metal/SDL_render_metal.m index 74252ba..ee6b882 100644 --- a/SDL2-2.0.12/src/render/metal/SDL_render_metal.m +++ b/SDL2-2.30.5/src/render/metal/SDL_render_metal.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,11 +20,9 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_RENDER_METAL && !SDL_RENDER_DISABLED +#if SDL_VIDEO_RENDER_METAL #include "SDL_hints.h" -#include "SDL_log.h" -#include "SDL_assert.h" #include "SDL_syswm.h" #include "SDL_metal.h" #include "../SDL_sysrender.h" @@ -34,6 +32,7 @@ #import #ifdef __MACOSX__ +#import #import #endif @@ -41,16 +40,24 @@ #ifdef __MACOSX__ #include "SDL_shaders_metal_osx.h" #elif defined(__TVOS__) +#if TARGET_OS_SIMULATOR +#include "SDL_shaders_metal_tvsimulator.h" +#else #include "SDL_shaders_metal_tvos.h" +#endif +#else +#if TARGET_OS_SIMULATOR +#include "SDL_shaders_metal_iphonesimulator.h" #else #include "SDL_shaders_metal_ios.h" #endif +#endif /* Apple Metal renderer implementation */ /* macOS requires constants in a buffer to have a 256 byte alignment. */ /* Use native type alignments from https://developer.apple.com/metal/Metal-Shading-Language-Specification.pdf */ -#ifdef __MACOSX__ +#if defined(__MACOSX__) || TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST #define CONSTANT_ALIGN(x) (256) #else #define CONSTANT_ALIGN(x) (x < 4 ? 4 : x) @@ -132,24 +139,6 @@ typedef struct METAL_ShaderPipelines @end @implementation METAL_RenderData -#if !__has_feature(objc_arc) -- (void)dealloc -{ - [_mtldevice release]; - [_mtlcmdqueue release]; - [_mtlcmdbuffer release]; - [_mtlcmdencoder release]; - [_mtllibrary release]; - [_mtlbackbuffer release]; - [_mtlsamplernearest release]; - [_mtlsamplerlinear release]; - [_mtlbufconstants release]; - [_mtlbufquadindices release]; - [_mtllayer release]; - [_mtlpassdesc release]; - [super dealloc]; -} -#endif @end @interface METAL_TextureData : NSObject @@ -157,30 +146,20 @@ typedef struct METAL_ShaderPipelines @property (nonatomic, retain) id mtltexture_uv; @property (nonatomic, retain) id mtlsampler; @property (nonatomic, assign) SDL_MetalFragmentFunction fragmentFunction; +#if SDL_HAVE_YUV @property (nonatomic, assign) BOOL yuv; @property (nonatomic, assign) BOOL nv12; @property (nonatomic, assign) size_t conversionBufferOffset; +#endif @property (nonatomic, assign) BOOL hasdata; - @property (nonatomic, retain) id lockedbuffer; @property (nonatomic, assign) SDL_Rect lockedrect; @end @implementation METAL_TextureData -#if !__has_feature(objc_arc) -- (void)dealloc -{ - [_mtltexture release]; - [_mtltexture_uv release]; - [_mtlsampler release]; - [_lockedbuffer release]; - [super dealloc]; -} -#endif @end -static int -IsMetalAvailable(const SDL_SysWMinfo *syswm) +static int IsMetalAvailable(const SDL_SysWMinfo *syswm) { if (syswm->subsystem != SDL_SYSWM_COCOA && syswm->subsystem != SDL_SYSWM_UIKIT) { return SDL_SetError("Metal render target only supports Cocoa and UIKit video targets at the moment."); @@ -199,8 +178,7 @@ IsMetalAvailable(const SDL_SysWMinfo *syswm) static const MTLBlendOperation invalidBlendOperation = (MTLBlendOperation)0xFFFFFFFF; static const MTLBlendFactor invalidBlendFactor = (MTLBlendFactor)0xFFFFFFFF; -static MTLBlendOperation -GetBlendOperation(SDL_BlendOperation operation) +static MTLBlendOperation GetBlendOperation(SDL_BlendOperation operation) { switch (operation) { case SDL_BLENDOPERATION_ADD: return MTLBlendOperationAdd; @@ -212,8 +190,7 @@ GetBlendOperation(SDL_BlendOperation operation) } } -static MTLBlendFactor -GetBlendFactor(SDL_BlendFactor factor) +static MTLBlendFactor GetBlendFactor(SDL_BlendFactor factor) { switch (factor) { case SDL_BLENDFACTOR_ZERO: return MTLBlendFactorZero; @@ -230,8 +207,7 @@ GetBlendFactor(SDL_BlendFactor factor) } } -static NSString * -GetVertexFunctionName(SDL_MetalVertexFunction function) +static NSString *GetVertexFunctionName(SDL_MetalVertexFunction function) { switch (function) { case SDL_METAL_VERTEX_SOLID: return @"SDL_Solid_vertex"; @@ -240,8 +216,7 @@ GetVertexFunctionName(SDL_MetalVertexFunction function) } } -static NSString * -GetFragmentFunctionName(SDL_MetalFragmentFunction function) +static NSString *GetFragmentFunctionName(SDL_MetalFragmentFunction function) { switch (function) { case SDL_METAL_FRAGMENT_SOLID: return @"SDL_Solid_fragment"; @@ -253,49 +228,64 @@ GetFragmentFunctionName(SDL_MetalFragmentFunction function) } } -static id -MakePipelineState(METAL_RenderData *data, METAL_PipelineCache *cache, - NSString *blendlabel, SDL_BlendMode blendmode) +static id MakePipelineState(METAL_RenderData *data, METAL_PipelineCache *cache, NSString *blendlabel, SDL_BlendMode blendmode) { + MTLRenderPipelineDescriptor *mtlpipedesc; + MTLVertexDescriptor *vertdesc; + MTLRenderPipelineColorAttachmentDescriptor *rtdesc; + NSError *err = nil; + id state; + METAL_PipelineState pipeline; + METAL_PipelineState *states; + id mtlvertfn = [data.mtllibrary newFunctionWithName:GetVertexFunctionName(cache->vertexFunction)]; id mtlfragfn = [data.mtllibrary newFunctionWithName:GetFragmentFunctionName(cache->fragmentFunction)]; SDL_assert(mtlvertfn != nil); SDL_assert(mtlfragfn != nil); - MTLRenderPipelineDescriptor *mtlpipedesc = [[MTLRenderPipelineDescriptor alloc] init]; + mtlpipedesc = [[MTLRenderPipelineDescriptor alloc] init]; mtlpipedesc.vertexFunction = mtlvertfn; mtlpipedesc.fragmentFunction = mtlfragfn; - MTLVertexDescriptor *vertdesc = [MTLVertexDescriptor vertexDescriptor]; + vertdesc = [MTLVertexDescriptor vertexDescriptor]; switch (cache->vertexFunction) { case SDL_METAL_VERTEX_SOLID: - /* position (float2) */ - vertdesc.layouts[0].stride = sizeof(float) * 2; - vertdesc.layouts[0].stepFunction = MTLVertexStepFunctionPerVertex; - - vertdesc.attributes[0].format = MTLVertexFormatFloat2; - vertdesc.attributes[0].offset = 0; - vertdesc.attributes[0].bufferIndex = 0; - break; - case SDL_METAL_VERTEX_COPY: - /* position (float2), texcoord (float2) */ - vertdesc.layouts[0].stride = sizeof(float) * 4; + /* position (float2), color (uchar4normalized) */ + vertdesc.layouts[0].stride = sizeof(float) * 2 + sizeof(int); vertdesc.layouts[0].stepFunction = MTLVertexStepFunctionPerVertex; vertdesc.attributes[0].format = MTLVertexFormatFloat2; vertdesc.attributes[0].offset = 0; vertdesc.attributes[0].bufferIndex = 0; - vertdesc.attributes[1].format = MTLVertexFormatFloat2; + vertdesc.attributes[1].format = MTLVertexFormatUChar4Normalized; vertdesc.attributes[1].offset = sizeof(float) * 2; vertdesc.attributes[1].bufferIndex = 0; + + break; + case SDL_METAL_VERTEX_COPY: + /* position (float2), color (uchar4normalized), texcoord (float2) */ + vertdesc.layouts[0].stride = sizeof(float) * 2 + sizeof(int) + sizeof(float) * 2; + vertdesc.layouts[0].stepFunction = MTLVertexStepFunctionPerVertex; + + vertdesc.attributes[0].format = MTLVertexFormatFloat2; + vertdesc.attributes[0].offset = 0; + vertdesc.attributes[0].bufferIndex = 0; + + vertdesc.attributes[1].format = MTLVertexFormatUChar4Normalized; + vertdesc.attributes[1].offset = sizeof(float) * 2; + vertdesc.attributes[1].bufferIndex = 0; + + vertdesc.attributes[2].format = MTLVertexFormatFloat2; + vertdesc.attributes[2].offset = sizeof(float) * 2 + sizeof(int); + vertdesc.attributes[2].bufferIndex = 0; break; } mtlpipedesc.vertexDescriptor = vertdesc; - MTLRenderPipelineColorAttachmentDescriptor *rtdesc = mtlpipedesc.colorAttachments[0]; + rtdesc = mtlpipedesc.colorAttachments[0]; rtdesc.pixelFormat = cache->renderTargetFormat; if (blendmode != SDL_BLENDMODE_NONE) { @@ -312,22 +302,13 @@ MakePipelineState(METAL_RenderData *data, METAL_PipelineCache *cache, mtlpipedesc.label = [@(cache->label) stringByAppendingString:blendlabel]; - NSError *err = nil; - id state = [data.mtldevice newRenderPipelineStateWithDescriptor:mtlpipedesc error:&err]; + state = [data.mtldevice newRenderPipelineStateWithDescriptor:mtlpipedesc error:&err]; SDL_assert(err == nil); - METAL_PipelineState pipeline; pipeline.blendMode = blendmode; pipeline.pipe = (void *)CFBridgingRetain(state); - METAL_PipelineState *states = SDL_realloc(cache->states, (cache->count + 1) * sizeof(pipeline)); - -#if !__has_feature(objc_arc) - [mtlpipedesc release]; // !!! FIXME: can these be reused for each creation, or does the pipeline obtain it? - [mtlvertfn release]; - [mtlfragfn release]; - [state release]; -#endif + states = SDL_realloc(cache->states, (cache->count + 1) * sizeof(pipeline)); if (states) { states[cache->count++] = pipeline; @@ -340,8 +321,7 @@ MakePipelineState(METAL_RenderData *data, METAL_PipelineCache *cache, } } -static void -MakePipelineCache(METAL_RenderData *data, METAL_PipelineCache *cache, const char *label, +static void MakePipelineCache(METAL_RenderData *data, METAL_PipelineCache *cache, const char *label, MTLPixelFormat rtformat, SDL_MetalVertexFunction vertfn, SDL_MetalFragmentFunction fragfn) { SDL_zerop(cache); @@ -360,8 +340,7 @@ MakePipelineCache(METAL_RenderData *data, METAL_PipelineCache *cache, const char MakePipelineState(data, cache, @" (blend=mul)", SDL_BLENDMODE_MUL); } -static void -DestroyPipelineCache(METAL_PipelineCache *cache) +static void DestroyPipelineCache(METAL_PipelineCache *cache) { if (cache != NULL) { for (int i = 0; i < cache->count; i++) { @@ -372,8 +351,7 @@ DestroyPipelineCache(METAL_PipelineCache *cache) } } -void -MakeShaderPipelines(METAL_RenderData *data, METAL_ShaderPipelines *pipelines, MTLPixelFormat rtformat) +static void MakeShaderPipelines(METAL_RenderData *data, METAL_ShaderPipelines *pipelines, MTLPixelFormat rtformat) { SDL_zerop(pipelines); @@ -386,8 +364,7 @@ MakeShaderPipelines(METAL_RenderData *data, METAL_ShaderPipelines *pipelines, MT MakePipelineCache(data, &pipelines->caches[SDL_METAL_FRAGMENT_NV21], "SDL NV21 pipeline", rtformat, SDL_METAL_VERTEX_COPY, SDL_METAL_FRAGMENT_NV21); } -static METAL_ShaderPipelines * -ChooseShaderPipelines(METAL_RenderData *data, MTLPixelFormat rtformat) +static METAL_ShaderPipelines *ChooseShaderPipelines(METAL_RenderData *data, MTLPixelFormat rtformat) { METAL_ShaderPipelines *allpipelines = data.allpipelines; int count = data.pipelinescount; @@ -413,8 +390,7 @@ ChooseShaderPipelines(METAL_RenderData *data, MTLPixelFormat rtformat) return &data.allpipelines[count]; } -static void -DestroyAllPipelines(METAL_ShaderPipelines *allpipelines, int count) +static void DestroyAllPipelines(METAL_ShaderPipelines *allpipelines, int count) { if (allpipelines != NULL) { for (int i = 0; i < count; i++) { @@ -427,8 +403,7 @@ DestroyAllPipelines(METAL_ShaderPipelines *allpipelines, int count) } } -static inline id -ChoosePipelineState(METAL_RenderData *data, METAL_ShaderPipelines *pipelines, SDL_MetalFragmentFunction fragfn, SDL_BlendMode blendmode) +static inline id ChoosePipelineState(METAL_RenderData *data, METAL_ShaderPipelines *pipelines, SDL_MetalFragmentFunction fragfn, SDL_BlendMode blendmode) { METAL_PipelineCache *cache = &pipelines->caches[fragfn]; @@ -441,8 +416,7 @@ ChoosePipelineState(METAL_RenderData *data, METAL_ShaderPipelines *pipelines, SD return MakePipelineState(data, cache, [NSString stringWithFormat:@" (blend=custom 0x%x)", blendmode], blendmode); } -static void -METAL_ActivateRenderCommandEncoder(SDL_Renderer * renderer, MTLLoadAction load, MTLClearColor *clear_color, id vertex_buffer) +static SDL_bool METAL_ActivateRenderCommandEncoder(SDL_Renderer * renderer, MTLLoadAction load, MTLClearColor *clear_color, id vertex_buffer) { METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata; @@ -463,10 +437,16 @@ METAL_ActivateRenderCommandEncoder(SDL_Renderer * renderer, MTLLoadAction load, load = MTLLoadActionDontCare; } } - mtltexture = data.mtlbackbuffer.texture; + if (data.mtlbackbuffer != nil) { + mtltexture = data.mtlbackbuffer.texture; + } } - SDL_assert(mtltexture); + /* mtltexture can be nil here if macOS refused to give us a drawable, + which apparently can happen for minimized windows, etc. */ + if (mtltexture == nil) { + return SDL_FALSE; + } if (load == MTLLoadActionClear) { SDL_assert(clear_color != NULL); @@ -499,19 +479,15 @@ METAL_ActivateRenderCommandEncoder(SDL_Renderer * renderer, MTLLoadAction load, // or whatever. This means we can _always_ batch rendering commands! [data.mtlcmdbuffer enqueue]; } + + return SDL_TRUE; } -static void -METAL_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event) +static void METAL_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event) { - if (event->event == SDL_WINDOWEVENT_SHOWN || - event->event == SDL_WINDOWEVENT_HIDDEN) { - // !!! FIXME: write me - } } -static int -METAL_GetOutputSize(SDL_Renderer * renderer, int *w, int *h) +static int METAL_GetOutputSize(SDL_Renderer * renderer, int *w, int *h) { @autoreleasepool { METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata; if (w) { @@ -523,8 +499,7 @@ METAL_GetOutputSize(SDL_Renderer * renderer, int *w, int *h) return 0; }} -static SDL_bool -METAL_SupportsBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode) +static SDL_bool METAL_SupportsBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode) { SDL_BlendFactor srcColorFactor = SDL_GetBlendModeSrcColorFactor(blendMode); SDL_BlendFactor srcAlphaFactor = SDL_GetBlendModeSrcAlphaFactor(blendMode); @@ -544,11 +519,14 @@ METAL_SupportsBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode) return SDL_TRUE; } -static int -METAL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) +static int METAL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) { @autoreleasepool { METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata; MTLPixelFormat pixfmt; + MTLTextureDescriptor *mtltexdesc; + id mtltexture, mtltexture_uv; + BOOL yuv, nv12; + METAL_TextureData *texturedata; switch (texture->format) { case SDL_PIXELFORMAT_ABGR8888: @@ -567,7 +545,7 @@ METAL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) return SDL_SetError("Texture format %s not supported by Metal", SDL_GetPixelFormatName(texture->format)); } - MTLTextureDescriptor *mtltexdesc = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:pixfmt + mtltexdesc = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:pixfmt width:(NSUInteger)texture->w height:(NSUInteger)texture->h mipmapped:NO]; /* Not available in iOS 8. */ @@ -578,16 +556,16 @@ METAL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) mtltexdesc.usage = MTLTextureUsageShaderRead; } } - - id mtltexture = [data.mtldevice newTextureWithDescriptor:mtltexdesc]; + + mtltexture = [data.mtldevice newTextureWithDescriptor:mtltexdesc]; if (mtltexture == nil) { return SDL_SetError("Texture allocation failed"); } - id mtltexture_uv = nil; - - BOOL yuv = (texture->format == SDL_PIXELFORMAT_IYUV) || (texture->format == SDL_PIXELFORMAT_YV12); - BOOL nv12 = (texture->format == SDL_PIXELFORMAT_NV12) || (texture->format == SDL_PIXELFORMAT_NV21); + mtltexture_uv = nil; +#if SDL_HAVE_YUV + yuv = (texture->format == SDL_PIXELFORMAT_IYUV) || (texture->format == SDL_PIXELFORMAT_YV12); + nv12 = (texture->format == SDL_PIXELFORMAT_NV12) || (texture->format == SDL_PIXELFORMAT_NV21); if (yuv) { mtltexdesc.pixelFormat = MTLPixelFormatR8Unorm; @@ -604,14 +582,11 @@ METAL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) if (yuv || nv12) { mtltexture_uv = [data.mtldevice newTextureWithDescriptor:mtltexdesc]; if (mtltexture_uv == nil) { -#if !__has_feature(objc_arc) - [mtltexture release]; -#endif return SDL_SetError("Texture allocation failed"); } } - - METAL_TextureData *texturedata = [[METAL_TextureData alloc] init]; +#endif /* SDL_HAVE_YUV */ + texturedata = [[METAL_TextureData alloc] init]; if (texture->scaleMode == SDL_ScaleModeNearest) { texturedata.mtlsampler = data.mtlsamplernearest; } else { @@ -619,7 +594,7 @@ METAL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) } texturedata.mtltexture = mtltexture; texturedata.mtltexture_uv = mtltexture_uv; - +#if SDL_HAVE_YUV texturedata.yuv = yuv; texturedata.nv12 = nv12; @@ -629,10 +604,12 @@ METAL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) texturedata.fragmentFunction = SDL_METAL_FRAGMENT_NV12; } else if (texture->format == SDL_PIXELFORMAT_NV21) { texturedata.fragmentFunction = SDL_METAL_FRAGMENT_NV21; - } else { + } else +#endif + { texturedata.fragmentFunction = SDL_METAL_FRAGMENT_COPY; } - +#if SDL_HAVE_YUV if (yuv || nv12) { size_t offset = 0; SDL_YUV_CONVERSION_MODE mode = SDL_GetYUVConversionModeForResolution(texture->w, texture->h); @@ -644,20 +621,13 @@ METAL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) } texturedata.conversionBufferOffset = offset; } - - texture->driverdata = (void*)CFBridgingRetain(texturedata); - -#if !__has_feature(objc_arc) - [texturedata release]; - [mtltexture release]; - [mtltexture_uv release]; #endif + texture->driverdata = (void*)CFBridgingRetain(texturedata); return 0; }} -static void -METAL_UploadTextureData(id texture, SDL_Rect rect, int slice, +static void METAL_UploadTextureData(id texture, SDL_Rect rect, int slice, const void * pixels, int pitch) { [texture replaceRegion:MTLRegionMake2D(rect.x, rect.y, rect.w, rect.h) @@ -668,8 +638,7 @@ METAL_UploadTextureData(id texture, SDL_Rect rect, int slice, bytesPerImage:0]; } -static MTLStorageMode -METAL_GetStorageMode(id resource) +static MTLStorageMode METAL_GetStorageMode(id resource) { /* iOS 8 does not have this method. */ if ([resource respondsToSelector:@selector(storageMode)]) { @@ -678,14 +647,15 @@ METAL_GetStorageMode(id resource) return MTLStorageModeShared; } -static int -METAL_UpdateTextureInternal(SDL_Renderer * renderer, METAL_TextureData *texturedata, +static int METAL_UpdateTextureInternal(SDL_Renderer * renderer, METAL_TextureData *texturedata, id texture, SDL_Rect rect, int slice, const void * pixels, int pitch) { METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata; SDL_Rect stagingrect = {0, 0, rect.w, rect.h}; MTLTextureDescriptor *desc; + id stagingtex; + id blitcmd; /* If the texture is managed or shared and this is the first upload, we can * use replaceRegion to upload to it directly. Otherwise we upload the data @@ -707,15 +677,11 @@ METAL_UpdateTextureInternal(SDL_Renderer * renderer, METAL_TextureData *textured /* TODO: We could have a pool of textures or a MTLHeap we allocate from, * and release a staging texture back to the pool in the command buffer's * completion handler. */ - id stagingtex = [data.mtldevice newTextureWithDescriptor:desc]; + stagingtex = [data.mtldevice newTextureWithDescriptor:desc]; if (stagingtex == nil) { return SDL_OutOfMemory(); } -#if !__has_feature(objc_arc) - [stagingtex autorelease]; -#endif - METAL_UploadTextureData(stagingtex, stagingrect, 0, pixels, pitch); if (data.mtlcmdencoder != nil) { @@ -727,7 +693,7 @@ METAL_UpdateTextureInternal(SDL_Renderer * renderer, METAL_TextureData *textured data.mtlcmdbuffer = [data.mtlcmdqueue commandBuffer]; } - id blitcmd = [data.mtlcmdbuffer blitCommandEncoder]; + blitcmd = [data.mtlcmdbuffer blitCommandEncoder]; [blitcmd copyFromTexture:stagingtex sourceSlice:0 @@ -749,8 +715,7 @@ METAL_UpdateTextureInternal(SDL_Renderer * renderer, METAL_TextureData *textured return 0; } -static int -METAL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, +static int METAL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, const void *pixels, int pitch) { @autoreleasepool { METAL_TextureData *texturedata = (__bridge METAL_TextureData *)texture->driverdata; @@ -758,7 +723,7 @@ METAL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, if (METAL_UpdateTextureInternal(renderer, texturedata, texturedata.mtltexture, *rect, 0, pixels, pitch) < 0) { return -1; } - +#if SDL_HAVE_YUV if (texturedata.yuv) { int Uslice = texture->format == SDL_PIXELFORMAT_YV12 ? 1 : 0; int Vslice = texture->format == SDL_PIXELFORMAT_YV12 ? 0 : 1; @@ -788,14 +753,14 @@ METAL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, return -1; } } - +#endif texturedata.hasdata = YES; return 0; }} -static int -METAL_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture, +#if SDL_HAVE_YUV +static int METAL_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, const Uint8 *Yplane, int Ypitch, const Uint8 *Uplane, int Upitch, @@ -826,8 +791,34 @@ METAL_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture, return 0; }} -static int -METAL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, +static int METAL_UpdateTextureNV(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *UVplane, int UVpitch) +{ @autoreleasepool { + METAL_TextureData *texturedata = (__bridge METAL_TextureData *)texture->driverdata; + SDL_Rect UVrect = {rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2}; + + /* Bail out if we're supposed to update an empty rectangle */ + if (rect->w <= 0 || rect->h <= 0) { + return 0; + } + + if (METAL_UpdateTextureInternal(renderer, texturedata, texturedata.mtltexture, *rect, 0, Yplane, Ypitch) < 0) { + return -1; + } + + if (METAL_UpdateTextureInternal(renderer, texturedata, texturedata.mtltexture_uv, UVrect, 0, UVplane, UVpitch) < 0) { + return -1; + } + + texturedata.hasdata = YES; + + return 0; +}} +#endif + +static int METAL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, void **pixels, int *pitch) { @autoreleasepool { METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata; @@ -840,10 +831,12 @@ METAL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, } *pitch = SDL_BYTESPERPIXEL(texture->format) * rect->w; - +#if SDL_HAVE_YUV if (texturedata.yuv || texturedata.nv12) { buffersize = ((*pitch) * rect->h) + (2 * (*pitch + 1) / 2) * ((rect->h + 1) / 2); - } else { + } else +#endif + { buffersize = (*pitch) * rect->h; } @@ -856,19 +849,14 @@ METAL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, texturedata.lockedbuffer = lockedbuffer; *pixels = [lockedbuffer contents]; - /* METAL_TextureData.lockedbuffer retains. */ -#if !__has_feature(objc_arc) - [lockedbuffer release]; -#endif - return 0; }} -static void -METAL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) +static void METAL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) { @autoreleasepool { METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata; METAL_TextureData *texturedata = (__bridge METAL_TextureData *)texture->driverdata; + id blitcmd; SDL_Rect rect = texturedata.lockedrect; int pitch = SDL_BYTESPERPIXEL(texture->format) * rect.w; SDL_Rect UVrect = {rect.x / 2, rect.y / 2, (rect.w + 1) / 2, (rect.h + 1) / 2}; @@ -886,7 +874,7 @@ METAL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) data.mtlcmdbuffer = [data.mtlcmdqueue commandBuffer]; } - id blitcmd = [data.mtlcmdbuffer blitCommandEncoder]; + blitcmd = [data.mtlcmdbuffer blitCommandEncoder]; [blitcmd copyFromBuffer:texturedata.lockedbuffer sourceOffset:0 @@ -897,7 +885,7 @@ METAL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) destinationSlice:0 destinationLevel:0 destinationOrigin:MTLOriginMake(rect.x, rect.y, 0)]; - +#if SDL_HAVE_YUV if (texturedata.yuv) { int Uslice = texture->format == SDL_PIXELFORMAT_YV12 ? 1 : 0; int Vslice = texture->format == SDL_PIXELFORMAT_YV12 ? 0 : 1; @@ -937,7 +925,7 @@ METAL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) destinationLevel:0 destinationOrigin:MTLOriginMake(UVrect.x, UVrect.y, 0)]; } - +#endif [blitcmd endEncoding]; [data.mtlcmdbuffer commit]; @@ -947,8 +935,7 @@ METAL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) texturedata.hasdata = YES; }} -static void -METAL_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture, SDL_ScaleMode scaleMode) +static void METAL_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture, SDL_ScaleMode scaleMode) { @autoreleasepool { METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata; METAL_TextureData *texturedata = (__bridge METAL_TextureData *)texture->driverdata; @@ -960,8 +947,7 @@ METAL_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture, SDL_Sc } }} -static int -METAL_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture) +static int METAL_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture) { @autoreleasepool { METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata; @@ -982,20 +968,12 @@ METAL_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture) }} -// normalize a value from 0.0f to len into 0.0f to 1.0f. -static inline float -normtex(const float _val, const float len) -{ - return _val / len; -} - -static int -METAL_QueueSetViewport(SDL_Renderer * renderer, SDL_RenderCommand *cmd) +static int METAL_QueueSetViewport(SDL_Renderer * renderer, SDL_RenderCommand *cmd) { float projection[4][4]; /* Prepare an orthographic projection */ const int w = cmd->data.viewport.rect.w; const int h = cmd->data.viewport.rect.h; - const size_t matrixlen = sizeof (projection); + const size_t matrixlen = sizeof(projection); float *matrix = (float *) SDL_AllocateRenderVertices(renderer, matrixlen, CONSTANT_ALIGN(16), &cmd->data.viewport.first); if (!matrix) { return -1; @@ -1014,199 +992,150 @@ METAL_QueueSetViewport(SDL_Renderer * renderer, SDL_RenderCommand *cmd) return 0; } -static int -METAL_QueueSetDrawColor(SDL_Renderer *renderer, SDL_RenderCommand *cmd) +static int METAL_QueueSetDrawColor(SDL_Renderer *renderer, SDL_RenderCommand *cmd) { - const size_t vertlen = sizeof (float) * 4; + const size_t vertlen = sizeof(float) * 4; float *verts = (float *) SDL_AllocateRenderVertices(renderer, vertlen, DEVICE_ALIGN(16), &cmd->data.color.first); if (!verts) { return -1; } + /* + * FIXME: not needed anymore, some cleanup to do + * *(verts++) = ((float)cmd->data.color.r) / 255.0f; *(verts++) = ((float)cmd->data.color.g) / 255.0f; *(verts++) = ((float)cmd->data.color.b) / 255.0f; *(verts++) = ((float)cmd->data.color.a) / 255.0f; + */ return 0; } -static int -METAL_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count) +static int METAL_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count) { - const size_t vertlen = (sizeof (float) * 2) * count; + const SDL_Color color = { + cmd->data.draw.r, + cmd->data.draw.g, + cmd->data.draw.b, + cmd->data.draw.a + }; + + const size_t vertlen = (2 * sizeof(float) + sizeof(SDL_Color)) * count; float *verts = (float *) SDL_AllocateRenderVertices(renderer, vertlen, DEVICE_ALIGN(8), &cmd->data.draw.first); if (!verts) { return -1; } cmd->data.draw.count = count; - SDL_memcpy(verts, points, vertlen); + + for (int i = 0; i < count; i++, points++) { + *(verts++) = points->x; + *(verts++) = points->y; + *((SDL_Color *)verts++) = color; + } return 0; } -static int -METAL_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRect * rects, int count) +static int METAL_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count) { - const size_t vertlen = (sizeof (float) * 8) * count; - float *verts = (float *) SDL_AllocateRenderVertices(renderer, vertlen, DEVICE_ALIGN(8), &cmd->data.draw.first); - if (!verts) { - return -1; - } - - cmd->data.draw.count = count; - - /* Quads in the following vertex order (matches the quad index buffer): - * 1---3 - * | \ | - * 0---2 - */ - for (int i = 0; i < count; i++, rects++) { - if ((rects->w <= 0.0f) || (rects->h <= 0.0f)) { - cmd->data.draw.count--; - } else { - *(verts++) = rects->x; - *(verts++) = rects->y + rects->h; - *(verts++) = rects->x; - *(verts++) = rects->y; - *(verts++) = rects->x + rects->w; - *(verts++) = rects->y + rects->h; - *(verts++) = rects->x + rects->w; - *(verts++) = rects->y; - } - } - - if (cmd->data.draw.count == 0) { - cmd->command = SDL_RENDERCMD_NO_OP; // nothing to do, just skip this one later. - } - - return 0; -} - -static int -METAL_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_FRect * dstrect) -{ - const float texw = (float) texture->w; - const float texh = (float) texture->h; - // !!! FIXME: use an index buffer - const size_t vertlen = (sizeof (float) * 16); - float *verts = (float *) SDL_AllocateRenderVertices(renderer, vertlen, DEVICE_ALIGN(8), &cmd->data.draw.first); - if (!verts) { - return -1; - } - - cmd->data.draw.count = 1; - - /* Interleaved positions and texture coordinates */ - *(verts++) = dstrect->x; - *(verts++) = dstrect->y + dstrect->h; - *(verts++) = normtex(srcrect->x, texw); - *(verts++) = normtex(srcrect->y + srcrect->h, texh); - - *(verts++) = dstrect->x; - *(verts++) = dstrect->y; - *(verts++) = normtex(srcrect->x, texw); - *(verts++) = normtex(srcrect->y, texh); - - *(verts++) = dstrect->x + dstrect->w; - *(verts++) = dstrect->y + dstrect->h; - *(verts++) = normtex(srcrect->x + srcrect->w, texw); - *(verts++) = normtex(srcrect->y + srcrect->h, texh); - - *(verts++) = dstrect->x + dstrect->w; - *(verts++) = dstrect->y; - *(verts++) = normtex(srcrect->x + srcrect->w, texw); - *(verts++) = normtex(srcrect->y, texh); - - return 0; -} - -static int -METAL_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture, - const SDL_Rect * srcquad, const SDL_FRect * dstrect, - const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip) -{ - const float texw = (float) texture->w; - const float texh = (float) texture->h; - const float rads = (float)(M_PI * (float) angle / 180.0f); - const float c = cosf(rads), s = sinf(rads); - float minu, maxu, minv, maxv; - const size_t vertlen = (sizeof (float) * 32); + const SDL_Color color = { + cmd->data.draw.r, + cmd->data.draw.g, + cmd->data.draw.b, + cmd->data.draw.a + }; + size_t vertlen; float *verts; - // cheat and store this offset in (count) because it needs to be aligned in ways other fields don't and we aren't using count otherwise. - verts = (float *) SDL_AllocateRenderVertices(renderer, vertlen, CONSTANT_ALIGN(16), &cmd->data.draw.count); - if (!verts) { - return -1; - } + SDL_assert(count >= 2); /* should have been checked at the higher level. */ - // transform matrix - SDL_memset(verts, '\0', sizeof (*verts) * 16); - verts[10] = verts[15] = 1.0f; - // rotation - verts[0] = c; - verts[1] = s; - verts[4] = -s; - verts[5] = c; - - // translation - verts[12] = dstrect->x + center->x; - verts[13] = dstrect->y + center->y; - - // rest of the vertices don't need the aggressive alignment. Pack them in. + vertlen = (2 * sizeof(float) + sizeof(SDL_Color)) * count; verts = (float *) SDL_AllocateRenderVertices(renderer, vertlen, DEVICE_ALIGN(8), &cmd->data.draw.first); if (!verts) { return -1; } + cmd->data.draw.count = count; - minu = normtex(srcquad->x, texw); - maxu = normtex(srcquad->x + srcquad->w, texw); - minv = normtex(srcquad->y, texh); - maxv = normtex(srcquad->y + srcquad->h, texh); - - if (flip & SDL_FLIP_HORIZONTAL) { - float tmp = maxu; - maxu = minu; - minu = tmp; - } - if (flip & SDL_FLIP_VERTICAL) { - float tmp = maxv; - maxv = minv; - minv = tmp; + for (int i = 0; i < count; i++, points++) { + *(verts++) = points->x; + *(verts++) = points->y; + *((SDL_Color *)verts++) = color; } - /* Interleaved positions and texture coordinates */ - *(verts++) = -center->x; - *(verts++) = dstrect->h - center->y; - *(verts++) = minu; - *(verts++) = maxv; + /* If the line segment is completely horizontal or vertical, + make it one pixel longer, to satisfy the diamond-exit rule. + We should probably do this for diagonal lines too, but we'd have to + do some trigonometry to figure out the correct pixel and generally + when we have problems with pixel perfection, it's for straight lines + that are missing a pixel that frames something and not arbitrary + angles. Maybe !!! FIXME for later, though. */ - *(verts++) = -center->x; - *(verts++) = -center->y; - *(verts++) = minu; - *(verts++) = minv; + points -= 2; /* update the last line. */ + verts -= 2 + 1; - *(verts++) = dstrect->w - center->x; - *(verts++) = dstrect->h - center->y; - *(verts++) = maxu; - *(verts++) = maxv; + { + const float xstart = points[0].x; + const float ystart = points[0].y; + const float xend = points[1].x; + const float yend = points[1].y; - *(verts++) = dstrect->w - center->x; - *(verts++) = -center->y; - *(verts++) = maxu; - *(verts++) = minv; + if (ystart == yend) { /* horizontal line */ + verts[0] += (xend > xstart) ? 1.0f : -1.0f; + } else if (xstart == xend) { /* vertical line */ + verts[1] += (yend > ystart) ? 1.0f : -1.0f; + } + } return 0; } +static int METAL_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, + const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride, + int num_vertices, const void *indices, int num_indices, int size_indices, + float scale_x, float scale_y) +{ + int count = indices ? num_indices : num_vertices; + const size_t vertlen = (2 * sizeof(float) + sizeof(int) + (texture ? 2 : 0) * sizeof(float)) * count; + float *verts = (float *) SDL_AllocateRenderVertices(renderer, vertlen, DEVICE_ALIGN(8), &cmd->data.draw.first); + if (!verts) { + return -1; + } + + cmd->data.draw.count = count; + size_indices = indices ? size_indices : 0; + + for (int i = 0; i < count; i++) { + int j; + float *xy_; + if (size_indices == 4) { + j = ((const Uint32 *)indices)[i]; + } else if (size_indices == 2) { + j = ((const Uint16 *)indices)[i]; + } else if (size_indices == 1) { + j = ((const Uint8 *)indices)[i]; + } else { + j = i; + } + + xy_ = (float *)((char*)xy + j * xy_stride); + + *(verts++) = xy_[0] * scale_x; + *(verts++) = xy_[1] * scale_y; + + *((SDL_Color *)verts++) = *(SDL_Color *)((char*)color + j * color_stride); + + if (texture) { + float *uv_ = (float *)((char*)uv + j * uv_stride); + *(verts++) = uv_[0]; + *(verts++) = uv_[1]; + } + } + + return 0; +} typedef struct { - #if __has_feature(objc_arc) __unsafe_unretained id pipeline; __unsafe_unretained id vertex_buffer; - #else - id pipeline; - id vertex_buffer; - #endif size_t constants_offset; SDL_Texture *texture; SDL_bool cliprect_dirty; @@ -1219,8 +1148,7 @@ typedef struct size_t color_offset; } METAL_DrawStateCache; -static void -SetDrawState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const SDL_MetalFragmentFunction shader, +static SDL_bool SetDrawState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const SDL_MetalFragmentFunction shader, const size_t constants_offset, id mtlbufvertex, METAL_DrawStateCache *statecache) { METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata; @@ -1228,7 +1156,9 @@ SetDrawState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const SDL_Met size_t first = cmd->data.draw.first; id newpipeline; - METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionLoad, NULL, statecache->vertex_buffer); + if (!METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionLoad, NULL, statecache->vertex_buffer)) { + return SDL_FALSE; + } if (statecache->viewport_dirty) { MTLViewport viewport; @@ -1244,22 +1174,35 @@ SetDrawState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const SDL_Met } if (statecache->cliprect_dirty) { - MTLScissorRect mtlrect; + SDL_Rect output; + SDL_Rect clip; if (statecache->cliprect_enabled) { - const SDL_Rect *rect = &statecache->cliprect; - mtlrect.x = statecache->viewport.x + rect->x; - mtlrect.y = statecache->viewport.y + rect->y; - mtlrect.width = rect->w; - mtlrect.height = rect->h; + clip = statecache->cliprect; + clip.x += statecache->viewport.x; + clip.y += statecache->viewport.y; } else { - mtlrect.x = statecache->viewport.x; - mtlrect.y = statecache->viewport.y; - mtlrect.width = statecache->viewport.w; - mtlrect.height = statecache->viewport.h; + clip = statecache->viewport; } - if (mtlrect.width > 0 && mtlrect.height > 0) { + + /* Set Scissor Rect Validation: w/h must be <= render pass */ + SDL_zero(output); + + if (renderer->target) { + output.w = renderer->target->w; + output.h = renderer->target->h; + } else { + METAL_GetOutputSize(renderer, &output.w, &output.h); + } + + if (SDL_IntersectRect(&output, &clip, &clip)) { + MTLScissorRect mtlrect; + mtlrect.x = clip.x; + mtlrect.y = clip.y; + mtlrect.width = clip.w; + mtlrect.height = clip.h; [data.mtlcmdencoder setScissorRect:mtlrect]; } + statecache->cliprect_dirty = SDL_FALSE; } @@ -1282,17 +1225,19 @@ SetDrawState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const SDL_Met } [data.mtlcmdencoder setVertexBufferOffset:first atIndex:0]; /* position/texcoords */ + return SDL_TRUE; } -static void -SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const size_t constants_offset, +static SDL_bool SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const size_t constants_offset, id mtlbufvertex, METAL_DrawStateCache *statecache) { METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata; SDL_Texture *texture = cmd->data.draw.texture; METAL_TextureData *texturedata = (__bridge METAL_TextureData *)texture->driverdata; - SetDrawState(renderer, cmd, texturedata.fragmentFunction, constants_offset, mtlbufvertex, statecache); + if (!SetDrawState(renderer, cmd, texturedata.fragmentFunction, constants_offset, mtlbufvertex, statecache)) { + return SDL_FALSE; + } if (texture != statecache->texture) { METAL_TextureData *oldtexturedata = NULL; @@ -1304,23 +1249,24 @@ SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const size_t } [data.mtlcmdencoder setFragmentTexture:texturedata.mtltexture atIndex:0]; +#if SDL_HAVE_YUV if (texturedata.yuv || texturedata.nv12) { [data.mtlcmdencoder setFragmentTexture:texturedata.mtltexture_uv atIndex:1]; [data.mtlcmdencoder setFragmentBuffer:data.mtlbufconstants offset:texturedata.conversionBufferOffset atIndex:1]; } +#endif statecache->texture = texture; } + return SDL_TRUE; } -static int -METAL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize) +static int METAL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize) { @autoreleasepool { METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata; + id mtlbufvertex = nil; METAL_DrawStateCache statecache; SDL_zero(statecache); - id mtlbufvertex = nil; - statecache.pipeline = nil; statecache.vertex_buffer = nil; statecache.constants_offset = CONSTANTS_OFFSET_INVALID; @@ -1341,9 +1287,6 @@ METAL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver * TODO: this buffer is also used for constants. Is performance still * good for those, or should we have a managed buffer for them? */ mtlbufvertex = [data.mtldevice newBufferWithLength:vertsize options:MTLResourceStorageModeShared]; - #if !__has_feature(objc_arc) - [mtlbufvertex autorelease]; - #endif mtlbufvertex.label = @"SDL vertex data"; SDL_memcpy([mtlbufvertex contents], vertices, vertsize); @@ -1359,7 +1302,7 @@ METAL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver while (cmd) { switch (cmd->command) { case SDL_RENDERCMD_SETVIEWPORT: { - SDL_memcpy(&statecache.viewport, &cmd->data.viewport.rect, sizeof (statecache.viewport)); + SDL_memcpy(&statecache.viewport, &cmd->data.viewport.rect, sizeof(statecache.viewport)); statecache.projection_offset = cmd->data.viewport.first; statecache.viewport_dirty = SDL_TRUE; statecache.cliprect_dirty = SDL_TRUE; @@ -1367,7 +1310,7 @@ METAL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver } case SDL_RENDERCMD_SETCLIPRECT: { - SDL_memcpy(&statecache.cliprect, &cmd->data.cliprect.rect, sizeof (statecache.cliprect)); + SDL_memcpy(&statecache.cliprect, &cmd->data.cliprect.rect, sizeof(statecache.cliprect)); statecache.cliprect_enabled = cmd->data.cliprect.enabled; statecache.cliprect_dirty = SDL_TRUE; break; @@ -1400,14 +1343,17 @@ METAL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver statecache.cliprect_dirty = SDL_TRUE; statecache.viewport_dirty = SDL_TRUE; - const Uint8 r = cmd->data.color.r; - const Uint8 g = cmd->data.color.g; - const Uint8 b = cmd->data.color.b; - const Uint8 a = cmd->data.color.a; - MTLClearColor color = MTLClearColorMake(r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f); + { + const Uint8 r = cmd->data.color.r; + const Uint8 g = cmd->data.color.g; + const Uint8 b = cmd->data.color.b; + const Uint8 a = cmd->data.color.a; + MTLClearColor color = MTLClearColorMake(r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f); - // get new command encoder, set up with an initial clear operation. - METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionClear, &color, mtlbufvertex); + // get new command encoder, set up with an initial clear operation. + // (this might fail, and future draw operations will notice.) + METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionClear, &color, mtlbufvertex); + } break; } @@ -1415,44 +1361,34 @@ METAL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver case SDL_RENDERCMD_DRAW_LINES: { const size_t count = cmd->data.draw.count; const MTLPrimitiveType primtype = (cmd->command == SDL_RENDERCMD_DRAW_POINTS) ? MTLPrimitiveTypePoint : MTLPrimitiveTypeLineStrip; - SetDrawState(renderer, cmd, SDL_METAL_FRAGMENT_SOLID, CONSTANTS_OFFSET_HALF_PIXEL_TRANSFORM, mtlbufvertex, &statecache); - [data.mtlcmdencoder drawPrimitives:primtype vertexStart:0 vertexCount:count]; - break; - } - - case SDL_RENDERCMD_FILL_RECTS: { - const size_t count = cmd->data.draw.count; - const size_t maxcount = UINT16_MAX / 4; - SetDrawState(renderer, cmd, SDL_METAL_FRAGMENT_SOLID, CONSTANTS_OFFSET_IDENTITY, mtlbufvertex, &statecache); - if (count == 1) { - [data.mtlcmdencoder drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount:4]; - } else { - /* Our index buffer has 16 bit indices, so we can only draw - * 65k vertices (16k rects) at a time. */ - for (size_t i = 0; i < count; i += maxcount) { - /* Set the vertex buffer offset for our current positions. - * The vertex buffer itself was bound in SetDrawState. */ - [data.mtlcmdencoder setVertexBufferOffset:cmd->data.draw.first + i*sizeof(float)*8 atIndex:0]; - [data.mtlcmdencoder drawIndexedPrimitives:MTLPrimitiveTypeTriangle - indexCount:SDL_min(maxcount, count - i) * 6 - indexType:MTLIndexTypeUInt16 - indexBuffer:data.mtlbufquadindices - indexBufferOffset:0]; - } + if (SetDrawState(renderer, cmd, SDL_METAL_FRAGMENT_SOLID, CONSTANTS_OFFSET_HALF_PIXEL_TRANSFORM, mtlbufvertex, &statecache)) { + [data.mtlcmdencoder drawPrimitives:primtype vertexStart:0 vertexCount:count]; } break; } - case SDL_RENDERCMD_COPY: { - SetCopyState(renderer, cmd, CONSTANTS_OFFSET_IDENTITY, mtlbufvertex, &statecache); - [data.mtlcmdencoder drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount:4]; + case SDL_RENDERCMD_FILL_RECTS: /* unused */ break; - } - case SDL_RENDERCMD_COPY_EX: { - SetCopyState(renderer, cmd, CONSTANTS_OFFSET_INVALID, mtlbufvertex, &statecache); - [data.mtlcmdencoder setVertexBuffer:mtlbufvertex offset:cmd->data.draw.count atIndex:3]; // transform - [data.mtlcmdencoder drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount:4]; + case SDL_RENDERCMD_COPY: /* unused */ + break; + + case SDL_RENDERCMD_COPY_EX: /* unused */ + break; + + case SDL_RENDERCMD_GEOMETRY: { + const size_t count = cmd->data.draw.count; + SDL_Texture *texture = cmd->data.draw.texture; + + if (texture) { + if (SetCopyState(renderer, cmd, CONSTANTS_OFFSET_IDENTITY, mtlbufvertex, &statecache)) { + [data.mtlcmdencoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:count]; + } + } else { + if (SetDrawState(renderer, cmd, SDL_METAL_FRAGMENT_SOLID, CONSTANTS_OFFSET_IDENTITY, mtlbufvertex, &statecache)) { + [data.mtlcmdencoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:count]; + } + } break; } @@ -1465,15 +1401,21 @@ METAL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver return 0; }} -static int -METAL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, +static int METAL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 pixel_format, void * pixels, int pitch) { @autoreleasepool { METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata; - METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionLoad, NULL, nil); + id mtltexture; + MTLRegion mtlregion; + int temp_pitch, status; + Uint32 temp_format; + void *temp_pixels; + if (!METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionLoad, NULL, nil)) { + return SDL_SetError("Failed to activate render command encoder (is your window in the background?"); + } [data.mtlcmdencoder endEncoding]; - id mtltexture = data.mtlpassdesc.colorAttachments[0].texture; + mtltexture = data.mtlpassdesc.colorAttachments[0].texture; #ifdef __MACOSX__ /* on macOS with managed-storage textures, we need to tell the driver to @@ -1494,51 +1436,67 @@ METAL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, data.mtlcmdencoder = nil; data.mtlcmdbuffer = nil; - MTLRegion mtlregion = MTLRegionMake2D(rect->x, rect->y, rect->w, rect->h); + mtlregion = MTLRegionMake2D(rect->x, rect->y, rect->w, rect->h); // we only do BGRA8 or RGBA8 at the moment, so 4 will do. - const int temp_pitch = rect->w * 4; - void *temp_pixels = SDL_malloc(temp_pitch * rect->h); + temp_pitch = rect->w * 4; + temp_pixels = SDL_malloc(temp_pitch * rect->h); if (!temp_pixels) { return SDL_OutOfMemory(); } [mtltexture getBytes:temp_pixels bytesPerRow:temp_pitch fromRegion:mtlregion mipmapLevel:0]; - const Uint32 temp_format = (mtltexture.pixelFormat == MTLPixelFormatBGRA8Unorm) ? SDL_PIXELFORMAT_ARGB8888 : SDL_PIXELFORMAT_ABGR8888; - const int status = SDL_ConvertPixels(rect->w, rect->h, temp_format, temp_pixels, temp_pitch, pixel_format, pixels, pitch); + temp_format = (mtltexture.pixelFormat == MTLPixelFormatBGRA8Unorm) ? SDL_PIXELFORMAT_ARGB8888 : SDL_PIXELFORMAT_ABGR8888; + status = SDL_ConvertPixels(rect->w, rect->h, temp_format, temp_pixels, temp_pitch, pixel_format, pixels, pitch); SDL_free(temp_pixels); return status; }} -static void -METAL_RenderPresent(SDL_Renderer * renderer) +static int METAL_RenderPresent(SDL_Renderer * renderer) { @autoreleasepool { METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata; + SDL_bool ready = SDL_TRUE; - if (data.mtlcmdencoder != nil) { - [data.mtlcmdencoder endEncoding]; + // If we don't have a command buffer, we can't present, so activate to get one. + if (data.mtlcmdencoder == nil) { + // We haven't even gotten a backbuffer yet? Clear it to black. Otherwise, load the existing data. + if (data.mtlbackbuffer == nil) { + MTLClearColor color = MTLClearColorMake(0.0f, 0.0f, 0.0f, 1.0f); + ready = METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionClear, &color, nil); + } else { + ready = METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionLoad, NULL, nil); + } } - if (data.mtlbackbuffer != nil) { + + [data.mtlcmdencoder endEncoding]; + + // If we don't have a drawable to present, don't try to present it. + // But we'll still try to commit the command buffer in case it was already enqueued. + if (ready) { + SDL_assert(data.mtlbackbuffer != nil); [data.mtlcmdbuffer presentDrawable:data.mtlbackbuffer]; } - if (data.mtlcmdbuffer != nil) { - [data.mtlcmdbuffer commit]; - } + + [data.mtlcmdbuffer commit]; + data.mtlcmdencoder = nil; data.mtlcmdbuffer = nil; data.mtlbackbuffer = nil; + + if (renderer->hidden || !ready) { + return -1; + } + return 0; }} -static void -METAL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) +static void METAL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) { @autoreleasepool { CFBridgingRelease(texture->driverdata); texture->driverdata = NULL; }} -static void -METAL_DestroyRenderer(SDL_Renderer * renderer) +static void METAL_DestroyRenderer(SDL_Renderer * renderer) { @autoreleasepool { if (renderer->driverdata) { METAL_RenderData *data = CFBridgingRelease(renderer->driverdata); @@ -1549,29 +1507,80 @@ METAL_DestroyRenderer(SDL_Renderer * renderer) DestroyAllPipelines(data.allpipelines, data.pipelinescount); - SDL_Metal_DestroyView(data.mtlview); + /* Release the metal view instead of destroying it, + in case we want to use it later (recreating the renderer) + */ + /* SDL_Metal_DestroyView(data.mtlview); */ + CFBridgingRelease(data.mtlview); } SDL_free(renderer); }} -static void * -METAL_GetMetalLayer(SDL_Renderer * renderer) +static void *METAL_GetMetalLayer(SDL_Renderer * renderer) { @autoreleasepool { METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata; return (__bridge void*)data.mtllayer; }} -static void * -METAL_GetMetalCommandEncoder(SDL_Renderer * renderer) +static void *METAL_GetMetalCommandEncoder(SDL_Renderer * renderer) { @autoreleasepool { + // note that data.mtlcmdencoder can be nil if METAL_ActivateRenderCommandEncoder fails. + // Before SDL 2.0.18, it might have returned a non-nil encoding that might not have been + // usable for presentation. Check your return values! + METAL_RenderData *data; METAL_ActivateRenderCommandEncoder(renderer, MTLLoadActionLoad, NULL, nil); - METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata; + data = (__bridge METAL_RenderData *) renderer->driverdata; return (__bridge void*)data.mtlcmdencoder; }} -static SDL_Renderer * -METAL_CreateRenderer(SDL_Window * window, Uint32 flags) +static int METAL_SetVSync(SDL_Renderer * renderer, const int vsync) +{ +#if (defined(__MACOSX__) && defined(MAC_OS_X_VERSION_10_13)) || TARGET_OS_MACCATALYST + if (@available(macOS 10.13, *)) { + METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata; + if (vsync) { + data.mtllayer.displaySyncEnabled = YES; + renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; + } else { + data.mtllayer.displaySyncEnabled = NO; + renderer->info.flags &= ~SDL_RENDERER_PRESENTVSYNC; + } + return 0; + } +#endif + return SDL_SetError("This Apple OS does not support displaySyncEnabled!"); +} + +static SDL_MetalView GetWindowView(SDL_Window *window) +{ + SDL_SysWMinfo info; + + SDL_VERSION(&info.version); + if (SDL_GetWindowWMInfo(window, &info)) { +#ifdef __MACOSX__ + if (info.subsystem == SDL_SYSWM_COCOA) { + NSView *view = info.info.cocoa.window.contentView; + if (view.subviews.count > 0) { + view = view.subviews[0]; + if (view.tag == SDL_METALVIEW_TAG) { + return (SDL_MetalView)CFBridgingRetain(view); + } + } + } +#else + if (info.subsystem == SDL_SYSWM_UIKIT) { + UIView *view = info.info.uikit.window.rootViewController.view; + if (view.tag == SDL_METALVIEW_TAG) { + return (SDL_MetalView)CFBridgingRetain(view); + } + } +#endif + } + return nil; +} + +static SDL_Renderer *METAL_CreateRenderer(SDL_Window * window, Uint32 flags) { @autoreleasepool { SDL_Renderer *renderer = NULL; METAL_RenderData *data = NULL; @@ -1579,105 +1588,19 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags) SDL_MetalView view = NULL; CAMetalLayer *layer = nil; SDL_SysWMinfo syswm; - - SDL_VERSION(&syswm.version); - if (!SDL_GetWindowWMInfo(window, &syswm)) { - return NULL; - } - - if (IsMetalAvailable(&syswm) == -1) { - return NULL; - } - - renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer)); - if (!renderer) { - SDL_OutOfMemory(); - return NULL; - } - - // !!! FIXME: MTLCopyAllDevices() can find other GPUs on macOS... - mtldevice = MTLCreateSystemDefaultDevice(); - - if (mtldevice == nil) { - SDL_free(renderer); - SDL_SetError("Failed to obtain Metal device"); - return NULL; - } - - view = SDL_Metal_CreateView(window); - - if (view == NULL) { -#if !__has_feature(objc_arc) - [mtldevice release]; -#endif - SDL_free(renderer); - return NULL; - } - - // !!! FIXME: error checking on all of this. - data = [[METAL_RenderData alloc] init]; - - if (data == nil) { -#if !__has_feature(objc_arc) - [mtldevice release]; -#endif - SDL_Metal_DestroyView(view); - SDL_free(renderer); - return NULL; - } - - renderer->driverdata = (void*)CFBridgingRetain(data); - renderer->window = window; - - data.mtlview = view; - -#ifdef __MACOSX__ - layer = (CAMetalLayer *)[(NSView *)view layer]; -#else - layer = (CAMetalLayer *)[(__bridge UIView *)view layer]; -#endif - - layer.device = mtldevice; - - /* Necessary for RenderReadPixels. */ - layer.framebufferOnly = NO; - - data.mtldevice = layer.device; - data.mtllayer = layer; - id mtlcmdqueue = [data.mtldevice newCommandQueue]; - data.mtlcmdqueue = mtlcmdqueue; - data.mtlcmdqueue.label = @"SDL Metal Renderer"; - data.mtlpassdesc = [MTLRenderPassDescriptor renderPassDescriptor]; - NSError *err = nil; - - // The compiled .metallib is embedded in a static array in a header file - // but the original shader source code is in SDL_shaders_metal.metal. - dispatch_data_t mtllibdata = dispatch_data_create(sdl_metallib, sdl_metallib_len, dispatch_get_global_queue(0, 0), ^{}); - id mtllibrary = [data.mtldevice newLibraryWithData:mtllibdata error:&err]; - data.mtllibrary = mtllibrary; - SDL_assert(err == nil); -#if !__has_feature(objc_arc) - dispatch_release(mtllibdata); -#endif - data.mtllibrary.label = @"SDL Metal renderer shader library"; - - /* Do some shader pipeline state loading up-front rather than on demand. */ - data.pipelinescount = 0; - data.allpipelines = NULL; - ChooseShaderPipelines(data, MTLPixelFormatBGRA8Unorm); - - MTLSamplerDescriptor *samplerdesc = [[MTLSamplerDescriptor alloc] init]; - - samplerdesc.minFilter = MTLSamplerMinMagFilterNearest; - samplerdesc.magFilter = MTLSamplerMinMagFilterNearest; - id mtlsamplernearest = [data.mtldevice newSamplerStateWithDescriptor:samplerdesc]; - data.mtlsamplernearest = mtlsamplernearest; - - samplerdesc.minFilter = MTLSamplerMinMagFilterLinear; - samplerdesc.magFilter = MTLSamplerMinMagFilterLinear; - id mtlsamplerlinear = [data.mtldevice newSamplerStateWithDescriptor:samplerdesc]; - data.mtlsamplerlinear = mtlsamplerlinear; + dispatch_data_t mtllibdata; + char *constantdata; + int maxtexsize, quadcount = UINT16_MAX / 4; + UInt16 *indexdata; + size_t indicessize = sizeof(UInt16) * quadcount * 6; + MTLSamplerDescriptor *samplerdesc; + id mtlcmdqueue; + id mtllibrary; + id mtlsamplernearest, mtlsamplerlinear; + id mtlbufconstantstaging, mtlbufquadindicesstaging, mtlbufconstants, mtlbufquadindices; + id cmdbuffer; + id blitcmd; /* Note: matrices are column major. */ float identitytransform[16] = { @@ -1716,31 +1639,132 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags) 1.0000, 1.7720, 0.0000, 0.0, /* Bcoeff */ }; - id mtlbufconstantstaging = [data.mtldevice newBufferWithLength:CONSTANTS_LENGTH options:MTLResourceStorageModeShared]; - #if !__has_feature(objc_arc) - [mtlbufconstantstaging autorelease]; - #endif + SDL_VERSION(&syswm.version); + if (!SDL_GetWindowWMInfo(window, &syswm)) { + return NULL; + } - char *constantdata = [mtlbufconstantstaging contents]; + if (IsMetalAvailable(&syswm) == -1) { + return NULL; + } + + renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer)); + if (!renderer) { + SDL_OutOfMemory(); + return NULL; + } + +#ifdef __MACOSX__ + if (SDL_GetHintBoolean(SDL_HINT_RENDER_METAL_PREFER_LOW_POWER_DEVICE, SDL_TRUE)) { + NSArray> *devices = MTLCopyAllDevices(); + + for (id device in devices) { + if (device.isLowPower) { + mtldevice = device; + break; + } + } + } +#endif + + if (mtldevice == nil) { + mtldevice = MTLCreateSystemDefaultDevice(); + } + + if (mtldevice == nil) { + SDL_free(renderer); + SDL_SetError("Failed to obtain Metal device"); + return NULL; + } + + view = GetWindowView(window); + if (view == nil) { + view = SDL_Metal_CreateView(window); + } + + if (view == NULL) { + SDL_free(renderer); + return NULL; + } + + // !!! FIXME: error checking on all of this. + data = [[METAL_RenderData alloc] init]; + + if (data == nil) { + /* Release the metal view instead of destroying it, + in case we want to use it later (recreating the renderer) + */ + /* SDL_Metal_DestroyView(view); */ + CFBridgingRelease(view); + SDL_free(renderer); + return NULL; + } + + renderer->driverdata = (void*)CFBridgingRetain(data); + renderer->window = window; + + data.mtlview = view; + +#ifdef __MACOSX__ + layer = (CAMetalLayer *)[(__bridge NSView *)view layer]; +#else + layer = (CAMetalLayer *)[(__bridge UIView *)view layer]; +#endif + + layer.device = mtldevice; + + /* Necessary for RenderReadPixels. */ + layer.framebufferOnly = NO; + + data.mtldevice = layer.device; + data.mtllayer = layer; + mtlcmdqueue = [data.mtldevice newCommandQueue]; + data.mtlcmdqueue = mtlcmdqueue; + data.mtlcmdqueue.label = @"SDL Metal Renderer"; + data.mtlpassdesc = [MTLRenderPassDescriptor renderPassDescriptor]; + + // The compiled .metallib is embedded in a static array in a header file + // but the original shader source code is in SDL_shaders_metal.metal. + mtllibdata = dispatch_data_create(sdl_metallib, sdl_metallib_len, dispatch_get_global_queue(0, 0), ^{}); + mtllibrary = [data.mtldevice newLibraryWithData:mtllibdata error:&err]; + data.mtllibrary = mtllibrary; + SDL_assert(err == nil); + data.mtllibrary.label = @"SDL Metal renderer shader library"; + + /* Do some shader pipeline state loading up-front rather than on demand. */ + data.pipelinescount = 0; + data.allpipelines = NULL; + ChooseShaderPipelines(data, MTLPixelFormatBGRA8Unorm); + + samplerdesc = [[MTLSamplerDescriptor alloc] init]; + + samplerdesc.minFilter = MTLSamplerMinMagFilterNearest; + samplerdesc.magFilter = MTLSamplerMinMagFilterNearest; + mtlsamplernearest = [data.mtldevice newSamplerStateWithDescriptor:samplerdesc]; + data.mtlsamplernearest = mtlsamplernearest; + + samplerdesc.minFilter = MTLSamplerMinMagFilterLinear; + samplerdesc.magFilter = MTLSamplerMinMagFilterLinear; + mtlsamplerlinear = [data.mtldevice newSamplerStateWithDescriptor:samplerdesc]; + data.mtlsamplerlinear = mtlsamplerlinear; + + mtlbufconstantstaging = [data.mtldevice newBufferWithLength:CONSTANTS_LENGTH options:MTLResourceStorageModeShared]; + + constantdata = [mtlbufconstantstaging contents]; SDL_memcpy(constantdata + CONSTANTS_OFFSET_IDENTITY, identitytransform, sizeof(identitytransform)); SDL_memcpy(constantdata + CONSTANTS_OFFSET_HALF_PIXEL_TRANSFORM, halfpixeltransform, sizeof(halfpixeltransform)); SDL_memcpy(constantdata + CONSTANTS_OFFSET_DECODE_JPEG, decodetransformJPEG, sizeof(decodetransformJPEG)); SDL_memcpy(constantdata + CONSTANTS_OFFSET_DECODE_BT601, decodetransformBT601, sizeof(decodetransformBT601)); SDL_memcpy(constantdata + CONSTANTS_OFFSET_DECODE_BT709, decodetransformBT709, sizeof(decodetransformBT709)); - int quadcount = UINT16_MAX / 4; - size_t indicessize = sizeof(UInt16) * quadcount * 6; - id mtlbufquadindicesstaging = [data.mtldevice newBufferWithLength:indicessize options:MTLResourceStorageModeShared]; -#if !__has_feature(objc_arc) - [mtlbufquadindicesstaging autorelease]; -#endif + mtlbufquadindicesstaging = [data.mtldevice newBufferWithLength:indicessize options:MTLResourceStorageModeShared]; /* Quads in the following vertex order (matches the FillRects vertices): * 1---3 * | \ | * 0---2 */ - UInt16 *indexdata = [mtlbufquadindicesstaging contents]; + indexdata = [mtlbufquadindicesstaging contents]; for (int i = 0; i < quadcount; i++) { indexdata[i * 6 + 0] = i * 4 + 0; indexdata[i * 6 + 1] = i * 4 + 1; @@ -1751,16 +1775,16 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags) indexdata[i * 6 + 5] = i * 4 + 3; } - id mtlbufconstants = [data.mtldevice newBufferWithLength:CONSTANTS_LENGTH options:MTLResourceStorageModePrivate]; + mtlbufconstants = [data.mtldevice newBufferWithLength:CONSTANTS_LENGTH options:MTLResourceStorageModePrivate]; data.mtlbufconstants = mtlbufconstants; data.mtlbufconstants.label = @"SDL constant data"; - id mtlbufquadindices = [data.mtldevice newBufferWithLength:indicessize options:MTLResourceStorageModePrivate]; + mtlbufquadindices = [data.mtldevice newBufferWithLength:indicessize options:MTLResourceStorageModePrivate]; data.mtlbufquadindices = mtlbufquadindices; data.mtlbufquadindices.label = @"SDL quad index buffer"; - id cmdbuffer = [data.mtlcmdqueue commandBuffer]; - id blitcmd = [cmdbuffer blitCommandEncoder]; + cmdbuffer = [data.mtlcmdqueue commandBuffer]; + blitcmd = [cmdbuffer blitCommandEncoder]; [blitcmd copyFromBuffer:mtlbufconstantstaging sourceOffset:0 toBuffer:mtlbufconstants destinationOffset:0 size:CONSTANTS_LENGTH]; [blitcmd copyFromBuffer:mtlbufquadindicesstaging sourceOffset:0 toBuffer:mtlbufquadindices destinationOffset:0 size:indicessize]; @@ -1775,7 +1799,10 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->SupportsBlendMode = METAL_SupportsBlendMode; renderer->CreateTexture = METAL_CreateTexture; renderer->UpdateTexture = METAL_UpdateTexture; +#if SDL_HAVE_YUV renderer->UpdateTextureYUV = METAL_UpdateTextureYUV; + renderer->UpdateTextureNV = METAL_UpdateTextureNV; +#endif renderer->LockTexture = METAL_LockTexture; renderer->UnlockTexture = METAL_UnlockTexture; renderer->SetTextureScaleMode = METAL_SetTextureScaleMode; @@ -1783,15 +1810,14 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->QueueSetViewport = METAL_QueueSetViewport; renderer->QueueSetDrawColor = METAL_QueueSetDrawColor; renderer->QueueDrawPoints = METAL_QueueDrawPoints; - renderer->QueueDrawLines = METAL_QueueDrawPoints; // lines and points queue the same way. - renderer->QueueFillRects = METAL_QueueFillRects; - renderer->QueueCopy = METAL_QueueCopy; - renderer->QueueCopyEx = METAL_QueueCopyEx; + renderer->QueueDrawLines = METAL_QueueDrawLines; + renderer->QueueGeometry = METAL_QueueGeometry; renderer->RunCommandQueue = METAL_RunCommandQueue; renderer->RenderReadPixels = METAL_RenderReadPixels; renderer->RenderPresent = METAL_RenderPresent; renderer->DestroyTexture = METAL_DestroyTexture; renderer->DestroyRenderer = METAL_DestroyRenderer; + renderer->SetVSync = METAL_SetVSync; renderer->GetMetalLayer = METAL_GetMetalLayer; renderer->GetMetalCommandEncoder = METAL_GetMetalCommandEncoder; @@ -1800,7 +1826,7 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->always_batch = SDL_TRUE; -#if defined(__MACOSX__) && defined(MAC_OS_X_VERSION_10_13) +#if (defined(__MACOSX__) && defined(MAC_OS_X_VERSION_10_13)) || TARGET_OS_MACCATALYST if (@available(macOS 10.13, *)) { data.mtllayer.displaySyncEnabled = (flags & SDL_RENDERER_PRESENTVSYNC) != 0; if (data.mtllayer.displaySyncEnabled) { @@ -1813,8 +1839,8 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags) } /* https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf */ - int maxtexsize = 4096; -#if defined(__MACOSX__) + maxtexsize = 4096; +#if defined(__MACOSX__) || TARGET_OS_MACCATALYST maxtexsize = 16384; #elif defined(__TVOS__) maxtexsize = 8192; @@ -1849,18 +1875,6 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->info.max_texture_width = maxtexsize; renderer->info.max_texture_height = maxtexsize; -#if !__has_feature(objc_arc) - [mtlcmdqueue release]; - [mtllibrary release]; - [samplerdesc release]; - [mtlsamplernearest release]; - [mtlsamplerlinear release]; - [mtlbufconstants release]; - [mtlbufquadindices release]; - [data release]; - [mtldevice release]; -#endif - return renderer; }} @@ -1882,6 +1896,6 @@ SDL_RenderDriver METAL_RenderDriver = { } }; -#endif /* SDL_VIDEO_RENDER_METAL && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_METAL */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/render/metal/SDL_shaders_metal.metal b/SDL2-2.30.5/src/render/metal/SDL_shaders_metal.metal similarity index 79% rename from SDL2-2.0.12/src/render/metal/SDL_shaders_metal.metal rename to SDL2-2.30.5/src/render/metal/SDL_shaders_metal.metal index 7975a39..fd9e3a8 100644 --- a/SDL2-2.0.12/src/render/metal/SDL_shaders_metal.metal +++ b/SDL2-2.30.5/src/render/metal/SDL_shaders_metal.metal @@ -6,11 +6,13 @@ using namespace metal; struct SolidVertexInput { float2 position [[attribute(0)]]; + float4 color [[attribute(1)]]; }; struct SolidVertexOutput { float4 position [[position]]; + float4 color; float pointSize [[point_size]]; }; @@ -20,24 +22,27 @@ vertex SolidVertexOutput SDL_Solid_vertex(SolidVertexInput in [[stage_in]], { SolidVertexOutput v; v.position = (projection * transform) * float4(in.position, 0.0f, 1.0f); + v.color = in.color; v.pointSize = 1.0f; return v; } -fragment float4 SDL_Solid_fragment(const device float4 &col [[buffer(0)]]) +fragment float4 SDL_Solid_fragment(SolidVertexInput in [[stage_in]]) { - return col; + return in.color; } struct CopyVertexInput { float2 position [[attribute(0)]]; - float2 texcoord [[attribute(1)]]; + float4 color [[attribute(1)]]; + float2 texcoord [[attribute(2)]]; }; struct CopyVertexOutput { float4 position [[position]]; + float4 color; float2 texcoord; }; @@ -47,16 +52,16 @@ vertex CopyVertexOutput SDL_Copy_vertex(CopyVertexInput in [[stage_in]], { CopyVertexOutput v; v.position = (projection * transform) * float4(in.position, 0.0f, 1.0f); + v.color = in.color; v.texcoord = in.texcoord; return v; } fragment float4 SDL_Copy_fragment(CopyVertexOutput vert [[stage_in]], - const device float4 &col [[buffer(0)]], texture2d tex [[texture(0)]], sampler s [[sampler(0)]]) { - return tex.sample(s, vert.texcoord) * col; + return tex.sample(s, vert.texcoord) * vert.color; } struct YUVDecode @@ -68,7 +73,6 @@ struct YUVDecode }; fragment float4 SDL_YUV_fragment(CopyVertexOutput vert [[stage_in]], - const device float4 &col [[buffer(0)]], constant YUVDecode &decode [[buffer(1)]], texture2d texY [[texture(0)]], texture2d_array texUV [[texture(1)]], @@ -81,11 +85,10 @@ fragment float4 SDL_YUV_fragment(CopyVertexOutput vert [[stage_in]], yuv += decode.offset; - return col * float4(dot(yuv, decode.Rcoeff), dot(yuv, decode.Gcoeff), dot(yuv, decode.Bcoeff), 1.0); + return vert.color * float4(dot(yuv, decode.Rcoeff), dot(yuv, decode.Gcoeff), dot(yuv, decode.Bcoeff), 1.0); } fragment float4 SDL_NV12_fragment(CopyVertexOutput vert [[stage_in]], - const device float4 &col [[buffer(0)]], constant YUVDecode &decode [[buffer(1)]], texture2d texY [[texture(0)]], texture2d texUV [[texture(1)]], @@ -97,11 +100,10 @@ fragment float4 SDL_NV12_fragment(CopyVertexOutput vert [[stage_in]], yuv += decode.offset; - return col * float4(dot(yuv, decode.Rcoeff), dot(yuv, decode.Gcoeff), dot(yuv, decode.Bcoeff), 1.0); + return vert.color * float4(dot(yuv, decode.Rcoeff), dot(yuv, decode.Gcoeff), dot(yuv, decode.Bcoeff), 1.0); } fragment float4 SDL_NV21_fragment(CopyVertexOutput vert [[stage_in]], - const device float4 &col [[buffer(0)]], constant YUVDecode &decode [[buffer(1)]], texture2d texY [[texture(0)]], texture2d texUV [[texture(1)]], @@ -113,5 +115,6 @@ fragment float4 SDL_NV21_fragment(CopyVertexOutput vert [[stage_in]], yuv += decode.offset; - return col * float4(dot(yuv, decode.Rcoeff), dot(yuv, decode.Gcoeff), dot(yuv, decode.Bcoeff), 1.0); + return vert.color * float4(dot(yuv, decode.Rcoeff), dot(yuv, decode.Gcoeff), dot(yuv, decode.Bcoeff), 1.0); } + diff --git a/SDL2-2.30.5/src/render/metal/SDL_shaders_metal_ios.h b/SDL2-2.30.5/src/render/metal/SDL_shaders_metal_ios.h new file mode 100644 index 0000000..4488c67 --- /dev/null +++ b/SDL2-2.30.5/src/render/metal/SDL_shaders_metal_ios.h @@ -0,0 +1,1821 @@ +const unsigned char sdl_metallib[] = { + 0x4d, 0x54, 0x4c, 0x42, 0x01, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x32, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xac, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x72, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, + 0x4e, 0x41, 0x4d, 0x45, 0x11, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x53, 0x6f, + 0x6c, 0x69, 0x64, 0x5f, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x00, 0x54, + 0x59, 0x50, 0x45, 0x01, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x20, 0x00, + 0x13, 0x37, 0x18, 0x80, 0x89, 0x69, 0x90, 0x54, 0x43, 0x22, 0xe0, 0xd3, + 0xc9, 0x73, 0x9e, 0x97, 0x0d, 0x2b, 0x28, 0xbd, 0x50, 0x37, 0x8f, 0x58, + 0x37, 0x77, 0x01, 0xac, 0x6d, 0x88, 0x24, 0x29, 0x4f, 0x46, 0x46, 0x54, + 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x01, 0x00, 0x08, 0x00, + 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x77, 0x00, 0x00, 0x00, + 0x4e, 0x41, 0x4d, 0x45, 0x10, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x43, 0x6f, + 0x70, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x00, 0x54, 0x59, + 0x50, 0x45, 0x01, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x20, 0x00, 0x91, + 0x5a, 0xbb, 0x5b, 0x02, 0x11, 0xc3, 0x5b, 0xf6, 0x76, 0xc1, 0x89, 0xa1, + 0x01, 0x7b, 0x59, 0xb6, 0xd1, 0xe0, 0xb8, 0xdf, 0x74, 0x12, 0x2a, 0xd4, + 0x0f, 0x39, 0x55, 0x63, 0x7e, 0xe8, 0x4f, 0x4f, 0x46, 0x46, 0x54, 0x18, + 0x00, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, + 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x7a, 0x00, 0x00, 0x00, 0x4e, + 0x41, 0x4d, 0x45, 0x13, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x53, 0x6f, 0x6c, + 0x69, 0x64, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x00, + 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, 0x53, 0x48, 0x20, + 0x00, 0x44, 0xbf, 0x90, 0x59, 0x71, 0xf7, 0xaf, 0x19, 0x2d, 0x19, 0x6e, + 0x76, 0x40, 0x8a, 0xf6, 0xce, 0x7f, 0x14, 0x46, 0xc9, 0xe3, 0xae, 0x8b, + 0x7a, 0x85, 0x41, 0x59, 0x0f, 0xbd, 0xd7, 0x95, 0x16, 0x4f, 0x46, 0x46, + 0x54, 0x18, 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x17, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x01, 0x00, 0x08, + 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x79, 0x00, 0x00, + 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x12, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x43, + 0x6f, 0x70, 0x79, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, + 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, 0x53, 0x48, + 0x20, 0x00, 0x5f, 0x19, 0x9c, 0xe8, 0xec, 0xd5, 0xc9, 0xc3, 0x03, 0xc5, + 0x04, 0xc4, 0x43, 0x19, 0x4b, 0x03, 0xde, 0x02, 0xe4, 0x31, 0xab, 0x30, + 0xae, 0xca, 0x0a, 0xb2, 0x45, 0x33, 0x78, 0x01, 0x3f, 0xd3, 0x4f, 0x46, + 0x46, 0x54, 0x18, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x01, 0x00, + 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x78, 0x00, + 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x11, 0x00, 0x53, 0x44, 0x4c, 0x5f, + 0x59, 0x55, 0x56, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, + 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, 0x53, 0x48, + 0x20, 0x00, 0xff, 0xfc, 0x03, 0x55, 0x1e, 0xae, 0x75, 0xbf, 0xb8, 0x4e, + 0x84, 0xd6, 0xd4, 0x1c, 0x39, 0x5f, 0x4d, 0x60, 0xe8, 0x3a, 0x9c, 0xa7, + 0xed, 0xa5, 0xcf, 0xaa, 0xff, 0x32, 0xce, 0x0b, 0xd3, 0x57, 0x4f, 0x46, + 0x46, 0x54, 0x18, 0x00, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x2a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x01, 0x00, + 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x79, 0x00, + 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x12, 0x00, 0x53, 0x44, 0x4c, 0x5f, + 0x4e, 0x56, 0x31, 0x32, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, + 0x74, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, 0x53, + 0x48, 0x20, 0x00, 0xbe, 0x64, 0x2f, 0xcf, 0xf2, 0xe7, 0x72, 0x42, 0x38, + 0xf8, 0x0e, 0x52, 0x43, 0x15, 0x53, 0x7e, 0x24, 0x4c, 0xc4, 0x53, 0xfc, + 0xe6, 0xda, 0xd9, 0x4b, 0x9a, 0xfd, 0x84, 0x1e, 0x42, 0x31, 0x43, 0x4f, + 0x46, 0x46, 0x54, 0x18, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x37, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x01, + 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x79, + 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x12, 0x00, 0x53, 0x44, 0x4c, + 0x5f, 0x4e, 0x56, 0x32, 0x31, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, + 0x6e, 0x74, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, + 0x53, 0x48, 0x20, 0x00, 0xe6, 0xe4, 0xd7, 0x33, 0x1f, 0x59, 0xe9, 0x03, + 0xec, 0x6d, 0x07, 0xd1, 0xa3, 0xc3, 0x49, 0x6a, 0x9d, 0x22, 0x8b, 0xce, + 0x27, 0xd1, 0xae, 0x1e, 0xfc, 0x33, 0x6d, 0x56, 0x86, 0x25, 0xd5, 0x66, + 0x4f, 0x46, 0x46, 0x54, 0x18, 0x00, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x44, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, + 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, + 0x45, 0x4e, 0x44, 0x54, 0x29, 0x00, 0x00, 0x00, 0x56, 0x41, 0x54, 0x54, + 0x15, 0x00, 0x02, 0x00, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x00, 0x00, 0x80, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x01, 0x80, 0x56, + 0x41, 0x54, 0x59, 0x04, 0x00, 0x02, 0x00, 0x04, 0x06, 0x45, 0x4e, 0x44, + 0x54, 0x35, 0x00, 0x00, 0x00, 0x56, 0x41, 0x54, 0x54, 0x20, 0x00, 0x03, + 0x00, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x80, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x01, 0x80, 0x74, 0x65, 0x78, 0x63, + 0x6f, 0x6f, 0x72, 0x64, 0x00, 0x02, 0x80, 0x56, 0x41, 0x54, 0x59, 0x05, + 0x00, 0x03, 0x00, 0x04, 0x06, 0x04, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, + 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, + 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, + 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, + 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, + 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, + 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, + 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, + 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0xde, 0xc0, + 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xa0, 0x0b, + 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, + 0x00, 0x00, 0xe5, 0x02, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, + 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, + 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, + 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, + 0x44, 0x24, 0x48, 0x0a, 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, + 0x21, 0x72, 0x24, 0x07, 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, + 0xc6, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x84, 0x00, + 0x00, 0x00, 0x1b, 0xc8, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x90, + 0x80, 0x8a, 0x18, 0x87, 0x77, 0x90, 0x07, 0x79, 0x28, 0x87, 0x71, 0xa0, + 0x07, 0x76, 0xc8, 0x87, 0x36, 0x90, 0x87, 0x77, 0xa8, 0x07, 0x77, 0x20, + 0x87, 0x72, 0x20, 0x87, 0x36, 0x20, 0x87, 0x74, 0xb0, 0x87, 0x74, 0x20, + 0x87, 0x72, 0x68, 0x83, 0x79, 0x88, 0x07, 0x79, 0xa0, 0x87, 0x36, 0x30, + 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0xc0, 0x1c, + 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1c, 0xd2, 0x61, 0x1e, + 0xc2, 0x41, 0x1c, 0xd8, 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xc2, 0x21, 0x1d, + 0xd8, 0xa1, 0x0d, 0xc6, 0x21, 0x1c, 0xd8, 0x81, 0x1d, 0xe6, 0x01, 0x30, + 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x60, 0x87, 0x72, 0x98, + 0x87, 0x79, 0x68, 0x03, 0x78, 0x90, 0x87, 0x72, 0x18, 0x87, 0x74, 0x98, + 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x76, 0x08, 0x07, 0x72, 0x00, + 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, + 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, + 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, + 0xd8, 0x21, 0x1d, 0xda, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, + 0x06, 0x77, 0x78, 0x87, 0x36, 0x30, 0x07, 0x79, 0x08, 0x87, 0x76, 0x28, + 0x87, 0x36, 0x80, 0x87, 0x77, 0x48, 0x07, 0x77, 0xa0, 0x87, 0x72, 0x90, + 0x87, 0x36, 0x28, 0x07, 0x76, 0x48, 0x87, 0x76, 0x68, 0x03, 0x77, 0x78, + 0x07, 0x77, 0x68, 0x03, 0x76, 0x28, 0x87, 0x70, 0x30, 0x07, 0x80, 0x70, + 0x87, 0x77, 0x68, 0x83, 0x74, 0x70, 0x07, 0x73, 0x98, 0x87, 0x36, 0x30, + 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, + 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x40, 0x1d, + 0xea, 0xa1, 0x1d, 0xe0, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xc4, 0x81, 0x1d, + 0xca, 0x61, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, + 0x08, 0x77, 0x78, 0x87, 0x36, 0x70, 0x87, 0x70, 0x70, 0x87, 0x79, 0x68, + 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, + 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, + 0xe6, 0x21, 0x1d, 0xce, 0xc1, 0x1d, 0xca, 0x81, 0x1c, 0xda, 0x40, 0x1f, + 0xca, 0x41, 0x1e, 0xde, 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, + 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, + 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x7a, 0x90, 0x87, 0x70, 0x80, + 0x07, 0x78, 0x48, 0x07, 0x77, 0x38, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, + 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0x62, 0x1e, + 0xe8, 0x21, 0x1c, 0xc6, 0x61, 0x1d, 0xda, 0x00, 0x1e, 0xe4, 0xe1, 0x1d, + 0xe8, 0xa1, 0x1c, 0xc6, 0x81, 0x1e, 0xde, 0x41, 0x1e, 0xda, 0x40, 0x1c, + 0xea, 0xc1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, + 0xf4, 0xa1, 0x1c, 0x00, 0x3c, 0x00, 0x88, 0x7a, 0x70, 0x87, 0x79, 0x08, + 0x07, 0x73, 0x28, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, + 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, + 0xea, 0x61, 0x1e, 0xca, 0xa1, 0x0d, 0xe6, 0xe1, 0x1d, 0xcc, 0x81, 0x1e, + 0xda, 0xc0, 0x1c, 0xd8, 0xe1, 0x1d, 0xc2, 0x81, 0x1e, 0x00, 0x73, 0x08, + 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x36, 0x20, 0xc2, 0x00, 0x24, 0xc0, + 0x02, 0x54, 0x1b, 0x90, 0x81, 0x00, 0x12, 0x60, 0x01, 0x2a, 0x00, 0x00, + 0x00, 0x00, 0x49, 0x18, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x86, + 0x40, 0x18, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x1c, 0x00, + 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, + 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, + 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x40, 0x33, 0x00, 0xc3, 0x08, + 0x04, 0x60, 0x87, 0x10, 0xc0, 0x30, 0x82, 0x00, 0x24, 0x41, 0x98, 0x89, + 0x9a, 0x07, 0x7a, 0x90, 0x87, 0x7a, 0x18, 0x07, 0x7a, 0x70, 0x83, 0x76, + 0x28, 0x07, 0x7a, 0x08, 0x07, 0x76, 0xd0, 0x03, 0x3d, 0x68, 0x87, 0x70, + 0xa0, 0x07, 0x79, 0x48, 0x07, 0x7c, 0x40, 0x01, 0x19, 0x44, 0x28, 0x84, + 0x52, 0x88, 0x11, 0x8c, 0xa1, 0x33, 0x10, 0x30, 0x47, 0x00, 0x06, 0x29, + 0xa0, 0xe6, 0x08, 0x40, 0x61, 0x10, 0x21, 0x10, 0x86, 0x11, 0x08, 0x65, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xa8, 0x70, 0x48, 0x07, 0x79, + 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, + 0x68, 0x83, 0x74, 0x78, 0x87, 0x79, 0xc8, 0x03, 0x37, 0x80, 0x03, 0x37, + 0x80, 0x83, 0x0d, 0xb7, 0x51, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x60, 0x07, + 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, + 0xe9, 0x10, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, + 0x78, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x10, 0x07, + 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, + 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, + 0x72, 0xd0, 0x06, 0xe9, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, + 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x30, 0x07, 0x72, 0xa0, 0x07, + 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, + 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, + 0xf6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, + 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x73, 0x20, 0x07, + 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x30, 0x07, 0x72, 0xa0, 0x07, + 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x40, 0x07, + 0x78, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, + 0xf6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, + 0x74, 0xd0, 0x06, 0xf6, 0x90, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x20, 0x07, + 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, + 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, + 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x90, 0x07, 0x72, 0xa0, 0x07, + 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, + 0xf6, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, + 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x75, 0x10, 0x07, + 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, + 0x72, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, + 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, + 0x74, 0xd0, 0x06, 0xee, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, + 0x73, 0x20, 0x07, 0x43, 0x18, 0x04, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x2c, 0x10, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x32, 0x1e, + 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, + 0x43, 0x52, 0x25, 0x30, 0x02, 0x50, 0x80, 0x01, 0x45, 0x50, 0x20, 0x65, + 0x50, 0x08, 0x05, 0x41, 0x6c, 0x04, 0x80, 0xd6, 0x58, 0x82, 0x43, 0x00, + 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0xe4, 0x00, 0x00, 0x00, 0x1a, 0x03, + 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4, + 0x37, 0xb7, 0x21, 0x86, 0x42, 0x24, 0xc0, 0xa2, 0x50, 0xb9, 0x1b, 0x43, + 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x1b, 0x62, 0x28, 0x41, 0x22, + 0x28, 0x07, 0xe1, 0x20, 0x08, 0x0e, 0x8e, 0xad, 0x0c, 0x84, 0x89, 0xc9, + 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x0d, 0x64, 0x26, + 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, 0x06, 0x04, 0xa5, 0xad, 0x8c, 0x2e, + 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, + 0xc6, 0x25, 0x26, 0x65, 0x88, 0x90, 0x10, 0x43, 0x0c, 0x25, 0x50, 0x10, + 0x45, 0x60, 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, 0x04, 0x49, 0x0e, 0x25, + 0x50, 0x02, 0x45, 0xe0, 0x16, 0x96, 0x26, 0xe7, 0x32, 0xf6, 0xd6, 0x06, + 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, 0x26, 0xd7, 0x36, 0xf7, + 0x45, 0x96, 0x36, 0x17, 0x26, 0xc6, 0x56, 0x36, 0x44, 0x48, 0x12, 0x72, + 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, + 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, 0x65, 0x6e, + 0x61, 0x62, 0x6c, 0x65, 0x43, 0x84, 0x64, 0x21, 0x19, 0x84, 0xa5, 0xc9, + 0xb9, 0x8c, 0xbd, 0xb5, 0xc1, 0xa5, 0xb1, 0x95, 0xb9, 0x98, 0xc9, 0x85, + 0xb5, 0x95, 0x89, 0xd5, 0x99, 0x99, 0x95, 0xc9, 0x7d, 0x99, 0x95, 0xd1, + 0x8d, 0xa1, 0x7d, 0x95, 0xb9, 0x85, 0x89, 0xb1, 0x95, 0x0d, 0x11, 0x92, + 0x86, 0x4c, 0x58, 0x9a, 0x9c, 0x0b, 0xdc, 0xdb, 0x5c, 0x1a, 0x5d, 0xda, + 0x9b, 0x1b, 0xa3, 0xb0, 0x34, 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, + 0x3c, 0xb8, 0xb2, 0x2f, 0xb7, 0xb0, 0xb6, 0x32, 0x1a, 0x66, 0x6c, 0x6f, + 0x61, 0x74, 0x34, 0x64, 0xc2, 0xd2, 0xe4, 0x5c, 0xc2, 0xe4, 0xce, 0xbe, + 0xdc, 0xc2, 0xda, 0xca, 0x88, 0xc0, 0xbd, 0xcd, 0xa5, 0xd1, 0xa5, 0xbd, + 0xb9, 0x0d, 0x51, 0x92, 0x27, 0x81, 0x92, 0x28, 0x91, 0x92, 0x89, 0x51, + 0x58, 0x9a, 0x9c, 0x8b, 0x5d, 0x99, 0x1c, 0x5d, 0x19, 0xde, 0xd7, 0x5b, + 0x1d, 0x1d, 0x5c, 0x1d, 0x1d, 0xad, 0xb3, 0x32, 0xb7, 0x32, 0xb9, 0x30, + 0xba, 0x32, 0x32, 0x94, 0x9a, 0xb1, 0x37, 0xb6, 0x37, 0x39, 0x22, 0x3b, + 0x9a, 0x2f, 0xb3, 0x14, 0x16, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x43, 0x98, + 0xa4, 0x4a, 0xac, 0x04, 0x4a, 0xa2, 0x44, 0x4a, 0x2e, 0x3a, 0x61, 0x69, + 0x72, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x5f, 0x73, 0x69, 0x7a, 0x65, + 0x2c, 0xcc, 0xd8, 0xde, 0xc2, 0xe8, 0x98, 0xc0, 0xbd, 0xa5, 0xb9, 0xd1, + 0x4d, 0xa5, 0xe9, 0x95, 0x0d, 0x51, 0x92, 0x2c, 0x81, 0x12, 0x2d, 0x91, + 0x92, 0x6d, 0x88, 0x91, 0x50, 0x09, 0x96, 0x70, 0x84, 0xc2, 0xd2, 0xe4, + 0x5c, 0xec, 0xca, 0xe4, 0xe8, 0xca, 0xf0, 0xbe, 0xd2, 0xdc, 0xe0, 0xea, + 0xe8, 0x28, 0x85, 0xa5, 0xc9, 0xb9, 0xb0, 0xbd, 0x8d, 0x85, 0xd1, 0xa5, + 0xbd, 0xb9, 0x7d, 0xa5, 0xb9, 0x91, 0x95, 0xe1, 0xd1, 0x3b, 0x2b, 0x73, + 0x2b, 0x93, 0x0b, 0xa3, 0x2b, 0x23, 0x43, 0xf9, 0xfa, 0x0a, 0x4b, 0x93, + 0xfb, 0x82, 0x63, 0x0b, 0x1b, 0x2b, 0x43, 0x7b, 0x63, 0x23, 0x2b, 0x93, + 0xfb, 0xfa, 0x4a, 0xa1, 0x61, 0xc6, 0xf6, 0x16, 0x46, 0x27, 0x33, 0x84, + 0x52, 0x84, 0xc4, 0x4b, 0x3e, 0x45, 0x50, 0x82, 0x04, 0x0c, 0x12, 0x28, + 0x09, 0x83, 0x44, 0x4a, 0xa6, 0x21, 0x94, 0x12, 0x24, 0x5e, 0xf2, 0x29, + 0x81, 0x12, 0x24, 0x60, 0x90, 0x40, 0x49, 0x94, 0x48, 0xc9, 0x45, 0x25, + 0x2c, 0x4d, 0xce, 0x45, 0xac, 0xce, 0xcc, 0xac, 0x4c, 0x8e, 0x4f, 0x58, + 0x9a, 0x9c, 0x8b, 0x58, 0x9d, 0x99, 0x59, 0x99, 0xdc, 0xd7, 0x5c, 0x9a, + 0x5e, 0x19, 0x91, 0xb0, 0x34, 0x39, 0x17, 0xb9, 0xb2, 0x30, 0x32, 0x46, + 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x5f, 0x73, 0x69, 0x7a, 0x65, 0xbc, 0xc2, 0xd2, 0xe4, 0x5c, 0xc2, 0xe4, + 0xce, 0xbe, 0xe8, 0xf2, 0xe0, 0xca, 0xbe, 0xc2, 0xd8, 0xd2, 0xce, 0xdc, + 0xbe, 0xe6, 0xd2, 0xf4, 0xca, 0x88, 0x98, 0xb1, 0xbd, 0x85, 0xd1, 0xd1, + 0xe0, 0xd1, 0x50, 0x81, 0x93, 0x7b, 0x53, 0x2b, 0x1b, 0xa3, 0x4b, 0x7b, + 0x73, 0x1b, 0x02, 0x06, 0x0a, 0x91, 0x90, 0x41, 0x52, 0x06, 0xca, 0x90, + 0x7c, 0x0a, 0xa1, 0x04, 0x89, 0x19, 0x24, 0x67, 0xa0, 0x0c, 0x09, 0x1a, + 0x28, 0x45, 0x02, 0x25, 0x69, 0x90, 0x48, 0x89, 0x1a, 0x30, 0xa1, 0x93, + 0x0b, 0x73, 0x9b, 0x33, 0x7b, 0x93, 0x6b, 0x1b, 0x02, 0x06, 0x8a, 0x91, + 0x90, 0x41, 0x52, 0x06, 0xca, 0x90, 0x7c, 0x8a, 0xa1, 0x04, 0x89, 0x19, + 0x24, 0x67, 0xa0, 0x0c, 0x09, 0x1a, 0x28, 0x45, 0x02, 0x25, 0x69, 0x90, + 0x48, 0x09, 0x1b, 0x0c, 0x41, 0x12, 0x31, 0x48, 0xc6, 0x20, 0x59, 0x83, + 0xa4, 0x0d, 0x86, 0x18, 0x08, 0x90, 0x74, 0x89, 0x1b, 0xf0, 0x79, 0x6b, + 0x73, 0x4b, 0x83, 0x7b, 0xa3, 0x2b, 0x73, 0xa3, 0x03, 0x19, 0x43, 0x0b, + 0x93, 0xe3, 0x33, 0x95, 0xd6, 0x06, 0xc7, 0x56, 0x06, 0x32, 0xb4, 0xb2, + 0x02, 0x42, 0x25, 0x14, 0x14, 0x34, 0x44, 0x48, 0xe2, 0x60, 0x88, 0x91, + 0xc0, 0x41, 0x22, 0x07, 0x4c, 0x32, 0xc4, 0x48, 0xe6, 0x20, 0x99, 0x03, + 0x26, 0x19, 0x11, 0xb1, 0x03, 0x3b, 0xd8, 0x43, 0x3b, 0xb8, 0x41, 0x3b, + 0xbc, 0x03, 0x39, 0xd4, 0x03, 0x3b, 0x94, 0x83, 0x1b, 0x98, 0x03, 0x3b, + 0x84, 0xc3, 0x39, 0xcc, 0xc3, 0x14, 0x21, 0x18, 0x46, 0x28, 0xec, 0xc0, + 0x0e, 0xf6, 0xd0, 0x0e, 0x6e, 0x90, 0x0e, 0xe4, 0x50, 0x0e, 0xee, 0x40, + 0x0f, 0x53, 0x82, 0x62, 0xc4, 0x12, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0x60, + 0x0f, 0xe5, 0x20, 0x0f, 0xf3, 0x90, 0x0e, 0xef, 0xe0, 0x0e, 0x53, 0x02, + 0x63, 0x04, 0x15, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0xc0, 0x0e, 0xe1, 0xe0, + 0x0e, 0xe7, 0x50, 0x0f, 0xe1, 0x70, 0x0e, 0xe5, 0xf0, 0x0b, 0xf6, 0x50, + 0x0e, 0xf2, 0x30, 0x0f, 0xe9, 0xf0, 0x0e, 0xee, 0x30, 0x25, 0x40, 0x46, + 0x4c, 0xe1, 0x90, 0x0e, 0xf2, 0xe0, 0x06, 0xe3, 0xf0, 0x0e, 0xed, 0x00, + 0x0f, 0xe9, 0xc0, 0x0e, 0xe5, 0xf0, 0x0b, 0xef, 0x00, 0x0f, 0xf4, 0x90, + 0x0e, 0xef, 0xe0, 0x0e, 0xf3, 0x30, 0x65, 0x50, 0x18, 0x67, 0x84, 0x12, + 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0x60, 0x0f, 0xe5, 0x20, 0x0f, 0xf4, 0x50, + 0x0e, 0xf8, 0x30, 0x25, 0x78, 0x03, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, + 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, + 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, + 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, + 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, + 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, + 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, + 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, + 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, + 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, + 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, + 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, + 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, + 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, + 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, + 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, + 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, + 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, + 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, + 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, + 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, + 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, + 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, + 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, + 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, + 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, + 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, + 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, + 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, + 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, + 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, + 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, + 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, + 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, + 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, + 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, + 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, + 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, + 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, + 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, + 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, + 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, + 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x06, 0x00, 0xb1, 0x5d, 0xf9, 0xb3, 0xce, 0x82, 0x0c, 0x7f, + 0x45, 0x44, 0x13, 0x71, 0x01, 0x00, 0x61, 0x20, 0x00, 0x00, 0x54, 0x00, + 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x0b, 0x00, + 0x00, 0x00, 0xe4, 0xc6, 0x22, 0x86, 0x61, 0x18, 0xc6, 0x22, 0x04, 0x41, + 0x10, 0xc6, 0x22, 0x82, 0x20, 0x08, 0x46, 0x00, 0x88, 0x95, 0x40, 0x19, + 0x14, 0x01, 0x8d, 0x19, 0x00, 0x12, 0x33, 0x00, 0x14, 0x66, 0x00, 0x08, + 0x8c, 0x11, 0x80, 0x20, 0x08, 0xe2, 0x1f, 0x00, 0x00, 0x00, 0xe3, 0x11, + 0x4c, 0x84, 0x45, 0x14, 0x94, 0xf1, 0x88, 0x67, 0xd2, 0x26, 0x0a, 0xca, + 0x20, 0xc3, 0x60, 0x30, 0x26, 0x04, 0xf2, 0x19, 0x8f, 0x98, 0x2e, 0xaf, + 0xa1, 0xa0, 0x0c, 0x32, 0x1c, 0x4a, 0x64, 0x42, 0x20, 0x1f, 0x0b, 0x0a, + 0xf8, 0x8c, 0x47, 0x60, 0xdc, 0x18, 0x40, 0x14, 0x94, 0x41, 0x06, 0xe6, + 0xb9, 0x4c, 0x08, 0xe4, 0x63, 0x45, 0x00, 0x9f, 0xf1, 0x88, 0x2e, 0x0c, + 0xd0, 0xc0, 0xa2, 0xa0, 0x0c, 0x32, 0x44, 0x54, 0x67, 0x42, 0x20, 0x1f, + 0x2b, 0x02, 0xf8, 0x8c, 0x47, 0x84, 0x81, 0x19, 0xb4, 0x01, 0x47, 0x41, + 0x19, 0x64, 0x08, 0xb2, 0xcf, 0x82, 0x4a, 0x3e, 0x83, 0x0c, 0xc3, 0x26, + 0x06, 0x16, 0x4c, 0xf2, 0xb1, 0x21, 0x80, 0xcf, 0x20, 0x83, 0xe1, 0x99, + 0x81, 0x05, 0x91, 0x7c, 0x6c, 0x08, 0xe0, 0x33, 0xc8, 0x90, 0x84, 0x81, + 0x1a, 0x58, 0xf0, 0xc8, 0xc7, 0x86, 0x00, 0x3e, 0xe3, 0x11, 0x6e, 0x30, + 0x07, 0x7a, 0x80, 0x06, 0x14, 0x94, 0x41, 0x86, 0xc0, 0x0c, 0xd8, 0xc0, + 0x02, 0x31, 0x90, 0xcf, 0x20, 0xc3, 0x80, 0x06, 0x6f, 0x60, 0x01, 0x18, + 0xc8, 0x67, 0x90, 0xa1, 0x50, 0x03, 0x39, 0xb0, 0xa0, 0x93, 0xcf, 0x20, + 0xc3, 0xc1, 0x06, 0x75, 0x60, 0x81, 0x26, 0x9f, 0x41, 0x86, 0x3d, 0x80, + 0x03, 0x3a, 0xb0, 0x2c, 0x90, 0xcf, 0x20, 0x43, 0x1f, 0xc8, 0xc1, 0x1d, + 0x98, 0x13, 0xc8, 0xc7, 0x92, 0x01, 0x3e, 0x16, 0x30, 0xf0, 0xb1, 0x20, + 0x81, 0x8f, 0x05, 0x08, 0x7c, 0x2c, 0x28, 0xe0, 0x33, 0xdb, 0x80, 0x07, + 0x01, 0x30, 0xdb, 0x10, 0x90, 0x42, 0x30, 0xdb, 0x10, 0xe0, 0x81, 0x90, + 0x41, 0x40, 0x0c, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x5b, 0x86, + 0x20, 0xa0, 0x83, 0x2d, 0xc3, 0x10, 0xd0, 0xc1, 0x96, 0xe1, 0x08, 0xe8, + 0x60, 0xcb, 0xc0, 0x04, 0x74, 0xb0, 0x65, 0x88, 0x02, 0x3a, 0xd8, 0x32, + 0x58, 0x01, 0x1d, 0x6c, 0x19, 0xc6, 0x20, 0xa0, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, + 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xb0, 0x0b, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0xe9, 0x02, + 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, + 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, + 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, + 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, 0x44, 0x24, 0x48, 0x0a, + 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, 0x21, 0x72, 0x24, 0x07, + 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, + 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0x1b, 0xc8, + 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x90, 0x80, 0x8a, 0x18, 0x87, + 0x77, 0x90, 0x07, 0x79, 0x28, 0x87, 0x71, 0xa0, 0x07, 0x76, 0xc8, 0x87, + 0x36, 0x90, 0x87, 0x77, 0xa8, 0x07, 0x77, 0x20, 0x87, 0x72, 0x20, 0x87, + 0x36, 0x20, 0x87, 0x74, 0xb0, 0x87, 0x74, 0x20, 0x87, 0x72, 0x68, 0x83, + 0x79, 0x88, 0x07, 0x79, 0xa0, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, + 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, + 0xa1, 0x1c, 0x00, 0x82, 0x1c, 0xd2, 0x61, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, + 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xc2, 0x21, 0x1d, 0xd8, 0xa1, 0x0d, 0xc6, + 0x21, 0x1c, 0xd8, 0x81, 0x1d, 0xe6, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, + 0x79, 0x28, 0x07, 0x80, 0x60, 0x87, 0x72, 0x98, 0x87, 0x79, 0x68, 0x03, + 0x78, 0x90, 0x87, 0x72, 0x18, 0x87, 0x74, 0x98, 0x87, 0x72, 0x68, 0x03, + 0x73, 0x80, 0x87, 0x76, 0x08, 0x07, 0x72, 0x00, 0xcc, 0x21, 0x1c, 0xd8, + 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, + 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, + 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, + 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x06, 0x77, 0x78, 0x87, + 0x36, 0x30, 0x07, 0x79, 0x08, 0x87, 0x76, 0x28, 0x87, 0x36, 0x80, 0x87, + 0x77, 0x48, 0x07, 0x77, 0xa0, 0x87, 0x72, 0x90, 0x87, 0x36, 0x28, 0x07, + 0x76, 0x48, 0x87, 0x76, 0x68, 0x03, 0x77, 0x78, 0x07, 0x77, 0x68, 0x03, + 0x76, 0x28, 0x87, 0x70, 0x30, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x83, + 0x74, 0x70, 0x07, 0x73, 0x98, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, + 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, + 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x40, 0x1d, 0xea, 0xa1, 0x1d, 0xe0, + 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x1e, 0x00, + 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, + 0x36, 0x70, 0x87, 0x70, 0x70, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, + 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, + 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xce, + 0xc1, 0x1d, 0xca, 0x81, 0x1c, 0xda, 0x40, 0x1f, 0xca, 0x41, 0x1e, 0xde, + 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, + 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, + 0x77, 0x68, 0x03, 0x7a, 0x90, 0x87, 0x70, 0x80, 0x07, 0x78, 0x48, 0x07, + 0x77, 0x38, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, + 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0x62, 0x1e, 0xe8, 0x21, 0x1c, 0xc6, + 0x61, 0x1d, 0xda, 0x00, 0x1e, 0xe4, 0xe1, 0x1d, 0xe8, 0xa1, 0x1c, 0xc6, + 0x81, 0x1e, 0xde, 0x41, 0x1e, 0xda, 0x40, 0x1c, 0xea, 0xc1, 0x1c, 0xcc, + 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xf4, 0xa1, 0x1c, 0x00, + 0x3c, 0x00, 0x88, 0x7a, 0x70, 0x87, 0x79, 0x08, 0x07, 0x73, 0x28, 0x87, + 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, + 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xea, 0x61, 0x1e, 0xca, + 0xa1, 0x0d, 0xe6, 0xe1, 0x1d, 0xcc, 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xd8, + 0xe1, 0x1d, 0xc2, 0x81, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, + 0x72, 0x00, 0x36, 0x20, 0x02, 0x01, 0x24, 0xc0, 0x02, 0x54, 0x1b, 0x90, + 0xa1, 0x00, 0x12, 0x60, 0x01, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x49, 0x18, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x86, 0x40, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x32, 0x22, + 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, + 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, + 0xa4, 0x4c, 0x10, 0x40, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, + 0x00, 0x76, 0x08, 0x41, 0x24, 0x41, 0x98, 0x89, 0x9a, 0x07, 0x7a, 0x90, + 0x87, 0x7a, 0x18, 0x07, 0x7a, 0x70, 0x83, 0x76, 0x28, 0x07, 0x7a, 0x08, + 0x07, 0x76, 0xd0, 0x03, 0x3d, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x79, 0x48, + 0x07, 0x7c, 0x40, 0x01, 0x19, 0x44, 0x28, 0x84, 0x62, 0x0c, 0x11, 0x84, + 0x31, 0x74, 0x06, 0x02, 0xe6, 0x08, 0xc0, 0x20, 0x05, 0xd4, 0x1c, 0x01, + 0x28, 0x0c, 0x22, 0x04, 0xc2, 0x30, 0x02, 0xa1, 0x8c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x13, 0xa8, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, + 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, + 0x87, 0x79, 0xc8, 0x03, 0x37, 0x80, 0x03, 0x37, 0x80, 0x83, 0x0d, 0xb7, + 0x51, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x7a, + 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x78, + 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, + 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, + 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, + 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, + 0xd0, 0x06, 0xe6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, + 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x76, + 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xf6, + 0x20, 0x07, 0x74, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, + 0xd0, 0x06, 0xf6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, + 0x30, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x40, 0x07, 0x78, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x60, 0x07, 0x74, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, + 0x90, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, + 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, + 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, + 0x60, 0x0f, 0x71, 0x90, 0x07, 0x72, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, + 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x75, + 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, + 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x75, 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, + 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, 0x72, 0xd0, 0x06, 0xf6, + 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, + 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xd0, 0x06, 0xee, + 0x80, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x43, + 0x18, 0x04, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x2c, 0x10, + 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, + 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x52, 0x25, 0x50, + 0x04, 0x23, 0x00, 0x05, 0x18, 0x50, 0x08, 0x65, 0x50, 0x20, 0x05, 0x41, + 0x6c, 0x04, 0x80, 0xd6, 0x58, 0x82, 0x43, 0x00, 0x00, 0x00, 0x79, 0x18, + 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x10, 0x97, 0x29, + 0xa2, 0x25, 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4, 0x37, 0xb7, 0x21, 0x86, + 0x22, 0x24, 0xc0, 0xa2, 0x50, 0xb9, 0x1b, 0x43, 0x0b, 0x93, 0xfb, 0x9a, + 0x4b, 0xd3, 0x2b, 0x1b, 0x62, 0x28, 0x41, 0x22, 0x28, 0x05, 0xe1, 0x20, + 0x08, 0x0e, 0x8e, 0xad, 0x0c, 0x84, 0x89, 0xc9, 0xaa, 0x09, 0xc4, 0xae, + 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x0d, 0x64, 0x26, 0x06, 0x06, 0x26, 0xc6, + 0xa5, 0x06, 0x06, 0x04, 0xa5, 0xad, 0x8c, 0x2e, 0x8c, 0xcd, 0xac, 0xac, + 0x65, 0x26, 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, 0xc6, 0x25, 0x26, 0x65, + 0x88, 0x90, 0x10, 0x43, 0x0c, 0x25, 0x50, 0x10, 0x65, 0x60, 0xd1, 0x54, + 0x46, 0x17, 0xc6, 0x36, 0x04, 0x49, 0x0e, 0x25, 0x50, 0x02, 0x65, 0xe0, + 0x16, 0x96, 0x26, 0xe7, 0x32, 0xf6, 0xd6, 0x06, 0x97, 0xc6, 0x56, 0xe6, + 0x42, 0x56, 0xe6, 0xf6, 0x26, 0xd7, 0x36, 0xf7, 0x45, 0x96, 0x36, 0x17, + 0x26, 0xc6, 0x56, 0x36, 0x44, 0x48, 0x12, 0x72, 0x61, 0x69, 0x72, 0x2e, + 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, 0x74, + 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, + 0x43, 0x84, 0x64, 0x21, 0x19, 0x84, 0xa5, 0xc9, 0xb9, 0x8c, 0xbd, 0xb5, + 0xc1, 0xa5, 0xb1, 0x95, 0xb9, 0x98, 0xc9, 0x85, 0xb5, 0x95, 0x89, 0xd5, + 0x99, 0x99, 0x95, 0xc9, 0x7d, 0x99, 0x95, 0xd1, 0x8d, 0xa1, 0x7d, 0x95, + 0xb9, 0x85, 0x89, 0xb1, 0x95, 0x0d, 0x11, 0x92, 0x86, 0x4c, 0x58, 0x9a, + 0x9c, 0x0b, 0xdc, 0xdb, 0x5c, 0x1a, 0x5d, 0xda, 0x9b, 0x1b, 0xa3, 0xb0, + 0x34, 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0x2f, + 0xb7, 0xb0, 0xb6, 0x32, 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x64, + 0xc2, 0xd2, 0xe4, 0x5c, 0xc2, 0xe4, 0xce, 0xbe, 0xdc, 0xc2, 0xda, 0xca, + 0x88, 0xc0, 0xbd, 0xcd, 0xa5, 0xd1, 0xa5, 0xbd, 0xb9, 0x0d, 0x51, 0x92, + 0x27, 0x81, 0x92, 0x28, 0x91, 0x92, 0x89, 0x51, 0x58, 0x9a, 0x9c, 0x8b, + 0x5d, 0x99, 0x1c, 0x5d, 0x19, 0xde, 0xd7, 0x5b, 0x1d, 0x1d, 0x5c, 0x1d, + 0x1d, 0xad, 0xb3, 0x32, 0xb7, 0x32, 0xb9, 0x30, 0xba, 0x32, 0x32, 0x94, + 0x9a, 0xb1, 0x37, 0xb6, 0x37, 0x39, 0x22, 0x3b, 0x9a, 0x2f, 0xb3, 0x14, + 0x16, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x43, 0x98, 0xa4, 0x4a, 0xac, 0x04, + 0x4a, 0xa2, 0x44, 0x4a, 0x2e, 0x66, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, + 0x74, 0x65, 0x64, 0x28, 0x38, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, + 0x64, 0x44, 0x76, 0x32, 0x5f, 0x66, 0x29, 0x34, 0xcc, 0xd8, 0xde, 0xc2, + 0xe8, 0x64, 0x88, 0xd0, 0x95, 0xe1, 0x8d, 0xbd, 0xbd, 0xc9, 0x91, 0x0d, + 0x61, 0x92, 0x2a, 0xc9, 0x12, 0x28, 0xd1, 0x12, 0x29, 0xd9, 0x86, 0x18, + 0x09, 0x95, 0x60, 0x09, 0x47, 0x28, 0x2c, 0x4d, 0xce, 0xc5, 0xae, 0x4c, + 0x8e, 0xae, 0x0c, 0xef, 0x2b, 0xcd, 0x0d, 0xae, 0x8e, 0x8e, 0x52, 0x58, + 0x9a, 0x9c, 0x0b, 0xdb, 0xdb, 0x58, 0x18, 0x5d, 0xda, 0x9b, 0xdb, 0x57, + 0x9a, 0x1b, 0x59, 0x19, 0x1e, 0xbd, 0xb3, 0x32, 0xb7, 0x32, 0xb9, 0x30, + 0xba, 0x32, 0x32, 0x94, 0xaf, 0xaf, 0xb0, 0x34, 0xb9, 0x2f, 0x38, 0xb6, + 0xb0, 0xb1, 0x32, 0xb4, 0x37, 0x36, 0xb2, 0x32, 0xb9, 0xaf, 0xaf, 0x94, + 0x21, 0x94, 0x32, 0x24, 0x5e, 0xf2, 0x29, 0x83, 0x12, 0x24, 0x60, 0x90, + 0x40, 0x89, 0x96, 0x48, 0xc9, 0x34, 0x84, 0x52, 0x82, 0xc4, 0x4b, 0x3e, + 0x25, 0x50, 0x82, 0x04, 0x0c, 0x12, 0x28, 0x89, 0x12, 0x29, 0xb9, 0x86, + 0x50, 0x8a, 0x90, 0x78, 0xc9, 0xa7, 0x08, 0x4a, 0x90, 0x80, 0x41, 0x02, + 0x25, 0x5a, 0x22, 0x25, 0x1b, 0x95, 0xb0, 0x34, 0x39, 0x17, 0xb1, 0x3a, + 0x33, 0xb3, 0x32, 0x39, 0x3e, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, + 0x66, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x44, 0xc2, 0xd2, 0xe4, + 0x5c, 0xe4, 0xca, 0xc2, 0xc8, 0x18, 0x85, 0xa5, 0xc9, 0xb9, 0x84, 0xc9, + 0x9d, 0x7d, 0xd1, 0xe5, 0xc1, 0x95, 0x7d, 0xcd, 0xa5, 0xe9, 0x95, 0xf1, + 0x0a, 0x4b, 0x93, 0x73, 0x09, 0x93, 0x3b, 0xfb, 0xa2, 0xcb, 0x83, 0x2b, + 0xfb, 0x0a, 0x63, 0x4b, 0x3b, 0x73, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x23, + 0x62, 0xc6, 0xf6, 0x16, 0x46, 0x47, 0x83, 0x47, 0x43, 0x05, 0x4e, 0xee, + 0x4d, 0xad, 0x6c, 0x8c, 0x2e, 0xed, 0xcd, 0x6d, 0x08, 0x18, 0x28, 0x46, + 0x42, 0x06, 0x49, 0x19, 0x28, 0x44, 0xf2, 0x29, 0x82, 0x12, 0x24, 0x66, + 0x90, 0x9c, 0x81, 0x42, 0x24, 0x68, 0xa0, 0x1c, 0x09, 0x94, 0xa4, 0x41, + 0x22, 0x25, 0x6a, 0xc0, 0x84, 0x4e, 0x2e, 0xcc, 0x6d, 0xce, 0xec, 0x4d, + 0xae, 0x6d, 0x08, 0x18, 0x28, 0x45, 0x42, 0x06, 0x49, 0x19, 0x28, 0x44, + 0xf2, 0x29, 0x86, 0x12, 0x24, 0x66, 0x90, 0x9c, 0x81, 0x42, 0x24, 0x68, + 0xa0, 0x1c, 0x09, 0x94, 0xa4, 0x41, 0x22, 0x25, 0x6c, 0x30, 0x44, 0x49, + 0xc2, 0x20, 0x11, 0x83, 0x64, 0x0c, 0x92, 0x35, 0x48, 0xda, 0x60, 0x88, + 0x81, 0x00, 0x49, 0x97, 0xb8, 0x01, 0x9f, 0xb7, 0x36, 0xb7, 0x34, 0xb8, + 0x37, 0xba, 0x32, 0x37, 0x3a, 0x90, 0x31, 0xb4, 0x30, 0x39, 0x3e, 0x53, + 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x2b, 0x2b, 0x20, 0x54, 0x42, + 0x41, 0x41, 0x43, 0x84, 0x24, 0x0e, 0x86, 0x18, 0x09, 0x1c, 0x24, 0x72, + 0xc0, 0x24, 0x43, 0x8c, 0x64, 0x0e, 0x92, 0x39, 0x60, 0x92, 0x11, 0x11, + 0x3b, 0xb0, 0x83, 0x3d, 0xb4, 0x83, 0x1b, 0xb4, 0xc3, 0x3b, 0x90, 0x43, + 0x3d, 0xb0, 0x43, 0x39, 0xb8, 0x81, 0x39, 0xb0, 0x43, 0x38, 0x9c, 0xc3, + 0x3c, 0x4c, 0x11, 0x82, 0x61, 0x84, 0xc2, 0x0e, 0xec, 0x60, 0x0f, 0xed, + 0xe0, 0x06, 0xe9, 0x40, 0x0e, 0xe5, 0xe0, 0x0e, 0xf4, 0x30, 0x25, 0x28, + 0x46, 0x2c, 0xe1, 0x90, 0x0e, 0xf2, 0xe0, 0x06, 0xf6, 0x50, 0x0e, 0xf2, + 0x30, 0x0f, 0xe9, 0xf0, 0x0e, 0xee, 0x30, 0x25, 0x30, 0x46, 0x50, 0xe1, + 0x90, 0x0e, 0xf2, 0xe0, 0x06, 0xec, 0x10, 0x0e, 0xee, 0x70, 0x0e, 0xf5, + 0x10, 0x0e, 0xe7, 0x50, 0x0e, 0xbf, 0x60, 0x0f, 0xe5, 0x20, 0x0f, 0xf3, + 0x90, 0x0e, 0xef, 0xe0, 0x0e, 0x53, 0x02, 0x64, 0xc4, 0x14, 0x0e, 0xe9, + 0x20, 0x0f, 0x6e, 0x30, 0x0e, 0xef, 0xd0, 0x0e, 0xf0, 0x90, 0x0e, 0xec, + 0x50, 0x0e, 0xbf, 0xf0, 0x0e, 0xf0, 0x40, 0x0f, 0xe9, 0xf0, 0x0e, 0xee, + 0x30, 0x0f, 0x53, 0x06, 0x85, 0x71, 0x46, 0x28, 0xe1, 0x90, 0x0e, 0xf2, + 0xe0, 0x06, 0xf6, 0x50, 0x0e, 0xf2, 0x40, 0x0f, 0xe5, 0x80, 0x0f, 0x53, + 0x82, 0x37, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x7b, 0x00, + 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, + 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, + 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, + 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, + 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, + 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, + 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, + 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, + 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, + 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, + 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, + 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, + 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, + 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, + 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, + 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, + 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, + 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, + 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, + 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, + 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, + 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, + 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, + 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, + 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, + 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, + 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, + 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, + 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, + 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, + 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, + 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, + 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, + 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, + 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, + 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, + 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, + 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, + 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, + 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, + 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, + 0x3c, 0x00, 0x71, 0x20, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0xf0, + 0xb0, 0x5d, 0xf9, 0x73, 0xce, 0x83, 0xfd, 0x15, 0x11, 0x4d, 0xc4, 0x05, + 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x13, 0x04, + 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0xe4, 0xc6, + 0x22, 0x86, 0x61, 0x18, 0xc6, 0x22, 0x04, 0x41, 0x10, 0xc6, 0x22, 0x82, + 0x20, 0x08, 0x88, 0x95, 0x40, 0x19, 0x14, 0x01, 0xb9, 0x11, 0x00, 0x1a, + 0x33, 0x00, 0x24, 0x66, 0x00, 0x28, 0xcc, 0x00, 0x00, 0x00, 0xe3, 0x11, + 0x4b, 0x74, 0x45, 0x14, 0x94, 0xf1, 0x08, 0x67, 0xca, 0x26, 0x0a, 0xca, + 0x20, 0xc3, 0x50, 0x20, 0x26, 0x04, 0xf2, 0x19, 0x8f, 0x90, 0xae, 0xae, + 0xa1, 0xa0, 0x0c, 0x32, 0x1c, 0x09, 0x64, 0x42, 0x20, 0x1f, 0x0b, 0x0a, + 0xf8, 0x8c, 0x47, 0x5c, 0x9c, 0x18, 0x40, 0x14, 0x94, 0x41, 0x06, 0xc6, + 0xb1, 0x4c, 0x08, 0xe4, 0x63, 0x45, 0x00, 0x9f, 0xf1, 0x08, 0x2e, 0x0c, + 0xce, 0xc0, 0xa2, 0xa0, 0x0c, 0x32, 0x44, 0x13, 0x67, 0x42, 0x20, 0x1f, + 0x2b, 0x02, 0xf8, 0x8c, 0x47, 0x80, 0x81, 0x19, 0xb0, 0x01, 0x47, 0x41, + 0x19, 0x64, 0x08, 0xb0, 0xcd, 0x82, 0x4a, 0x3e, 0x83, 0x0c, 0x83, 0x16, + 0x06, 0x16, 0x4c, 0xf2, 0xb1, 0x21, 0x80, 0xcf, 0x20, 0x83, 0xd1, 0x95, + 0x81, 0x05, 0x91, 0x7c, 0x6c, 0x08, 0xe0, 0x33, 0xc8, 0x90, 0x80, 0x41, + 0x1a, 0x58, 0xf0, 0xc8, 0xc7, 0x86, 0x00, 0x3e, 0xe3, 0x11, 0x6d, 0x30, + 0x07, 0x79, 0x80, 0x06, 0x14, 0x94, 0x41, 0x86, 0xa0, 0x0c, 0xd0, 0xc0, + 0x02, 0x31, 0x90, 0xcf, 0x20, 0xc3, 0x70, 0x06, 0x6e, 0x60, 0x01, 0x18, + 0xc8, 0x67, 0x90, 0xa1, 0x48, 0x83, 0x38, 0xb0, 0xa0, 0x93, 0xcf, 0x20, + 0xc3, 0xb1, 0x06, 0x74, 0x60, 0x81, 0x26, 0x9f, 0x41, 0x86, 0x3d, 0x70, + 0x03, 0x38, 0xb0, 0x2c, 0x90, 0xcf, 0x20, 0x43, 0x1f, 0xc0, 0x81, 0x1d, + 0x98, 0x13, 0xc8, 0xc7, 0x92, 0x01, 0x3e, 0x16, 0x30, 0xf0, 0xb1, 0x20, + 0x81, 0x8f, 0x05, 0x08, 0x7c, 0x2c, 0x28, 0xe0, 0x33, 0xdb, 0x80, 0x07, + 0x01, 0x30, 0xdb, 0x10, 0x90, 0x42, 0x30, 0xdb, 0x10, 0x90, 0x82, 0x90, + 0x41, 0x40, 0x0c, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x5b, 0x86, + 0x20, 0xa0, 0x83, 0x2d, 0xc3, 0x10, 0xd0, 0xc1, 0x96, 0xe1, 0x08, 0xe8, + 0x60, 0xcb, 0xc0, 0x04, 0x74, 0xb0, 0x65, 0x88, 0x02, 0x3a, 0xd8, 0x32, + 0x58, 0x01, 0x1d, 0x6c, 0x19, 0xc6, 0x20, 0xa0, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, + 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xe0, 0x08, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x35, 0x02, + 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, + 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, + 0x8b, 0x62, 0x80, 0x10, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0x84, 0x10, + 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, 0x44, 0x24, 0x48, 0x0a, + 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, 0x21, 0x72, 0x24, 0x07, + 0xc8, 0x08, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, + 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x1b, 0xc8, + 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x90, 0x00, 0x8a, 0x18, 0x87, + 0x77, 0x90, 0x07, 0x79, 0x28, 0x87, 0x71, 0xa0, 0x07, 0x76, 0xc8, 0x87, + 0x36, 0x90, 0x87, 0x77, 0xa8, 0x07, 0x77, 0x20, 0x87, 0x72, 0x20, 0x87, + 0x36, 0x20, 0x87, 0x74, 0xb0, 0x87, 0x74, 0x20, 0x87, 0x72, 0x68, 0x83, + 0x79, 0x88, 0x07, 0x79, 0xa0, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, + 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, + 0xa1, 0x1c, 0x00, 0x82, 0x1c, 0xd2, 0x61, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, + 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xc2, 0x21, 0x1d, 0xd8, 0xa1, 0x0d, 0xc6, + 0x21, 0x1c, 0xd8, 0x81, 0x1d, 0xe6, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, + 0x79, 0x28, 0x07, 0x80, 0x60, 0x87, 0x72, 0x98, 0x87, 0x79, 0x68, 0x03, + 0x78, 0x90, 0x87, 0x72, 0x18, 0x87, 0x74, 0x98, 0x87, 0x72, 0x68, 0x03, + 0x73, 0x80, 0x87, 0x76, 0x08, 0x07, 0x72, 0x00, 0xcc, 0x21, 0x1c, 0xd8, + 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, + 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, + 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, + 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x06, 0x77, 0x78, 0x87, + 0x36, 0x30, 0x07, 0x79, 0x08, 0x87, 0x76, 0x28, 0x87, 0x36, 0x80, 0x87, + 0x77, 0x48, 0x07, 0x77, 0xa0, 0x87, 0x72, 0x90, 0x87, 0x36, 0x28, 0x07, + 0x76, 0x48, 0x87, 0x76, 0x68, 0x03, 0x77, 0x78, 0x07, 0x77, 0x68, 0x03, + 0x76, 0x28, 0x87, 0x70, 0x30, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x83, + 0x74, 0x70, 0x07, 0x73, 0x98, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, + 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, + 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x40, 0x1d, 0xea, 0xa1, 0x1d, 0xe0, + 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x1e, 0x00, + 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, + 0x36, 0x70, 0x87, 0x70, 0x70, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, + 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, + 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xce, + 0xc1, 0x1d, 0xca, 0x81, 0x1c, 0xda, 0x40, 0x1f, 0xca, 0x41, 0x1e, 0xde, + 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, + 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, + 0x77, 0x68, 0x03, 0x7a, 0x90, 0x87, 0x70, 0x80, 0x07, 0x78, 0x48, 0x07, + 0x77, 0x38, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, + 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0x62, 0x1e, 0xe8, 0x21, 0x1c, 0xc6, + 0x61, 0x1d, 0xda, 0x00, 0x1e, 0xe4, 0xe1, 0x1d, 0xe8, 0xa1, 0x1c, 0xc6, + 0x81, 0x1e, 0xde, 0x41, 0x1e, 0xda, 0x40, 0x1c, 0xea, 0xc1, 0x1c, 0xcc, + 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xf4, 0xa1, 0x1c, 0x00, + 0x3c, 0x00, 0x88, 0x7a, 0x70, 0x87, 0x79, 0x08, 0x07, 0x73, 0x28, 0x87, + 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, + 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xea, 0x61, 0x1e, 0xca, + 0xa1, 0x0d, 0xe6, 0xe1, 0x1d, 0xcc, 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xd8, + 0xe1, 0x1d, 0xc2, 0x81, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, + 0x72, 0x00, 0x36, 0x10, 0x82, 0x00, 0x58, 0x00, 0x00, 0x00, 0x49, 0x18, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x13, 0x84, 0x40, 0x00, 0x89, 0x20, + 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x32, 0x22, 0x08, 0x09, 0x20, 0x64, + 0x85, 0x04, 0x13, 0x22, 0xa4, 0x84, 0x04, 0x13, 0x22, 0xe3, 0x84, 0xa1, + 0x90, 0x14, 0x12, 0x4c, 0x88, 0x8c, 0x0b, 0x84, 0x84, 0x4c, 0x10, 0x24, + 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, 0x00, 0x65, 0x08, 0x09, + 0x9a, 0x81, 0x80, 0x39, 0x02, 0x30, 0x48, 0x01, 0x1b, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x13, 0xa8, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, + 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, + 0x87, 0x79, 0xc8, 0x03, 0x37, 0x80, 0x03, 0x37, 0x80, 0x83, 0x0d, 0xb7, + 0x51, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x7a, + 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x78, + 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, + 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, + 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, + 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, + 0xd0, 0x06, 0xe6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, + 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x76, + 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xf6, + 0x20, 0x07, 0x74, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, + 0xd0, 0x06, 0xf6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, + 0x30, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x40, 0x07, 0x78, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x60, 0x07, 0x74, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, + 0x90, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, + 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, + 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, + 0x60, 0x0f, 0x71, 0x90, 0x07, 0x72, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, + 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x75, + 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, + 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x75, 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, + 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, 0x72, 0xd0, 0x06, 0xf6, + 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, + 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xd0, 0x06, 0xee, + 0x80, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x43, + 0x18, 0x02, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x2c, 0x10, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x0c, 0x19, 0x11, + 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0xb2, 0x12, 0x18, + 0x01, 0x28, 0x82, 0x42, 0x28, 0x08, 0xba, 0xb1, 0x04, 0x87, 0x00, 0x00, + 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x1a, 0x03, + 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4, + 0x37, 0xb7, 0x21, 0x86, 0x31, 0x14, 0xc0, 0x61, 0x50, 0xb9, 0x1b, 0x43, + 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x1b, 0x62, 0x18, 0x41, 0x21, + 0x18, 0x04, 0xe1, 0x20, 0x08, 0x0e, 0x8e, 0xad, 0x0c, 0x84, 0x89, 0xc9, + 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x0d, 0x64, 0x26, + 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, 0x06, 0x04, 0xa5, 0xad, 0x8c, 0x2e, + 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, + 0xc6, 0x25, 0x26, 0x65, 0x88, 0x50, 0x10, 0x43, 0x0c, 0x23, 0x30, 0x0a, + 0x43, 0x60, 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, 0x04, 0x29, 0x0e, 0x23, + 0x30, 0x02, 0x43, 0xe0, 0x16, 0x96, 0x26, 0xe7, 0x32, 0xf6, 0xd6, 0x06, + 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, 0x26, 0xd7, 0x36, 0xf7, + 0x45, 0x96, 0x36, 0x17, 0x26, 0xc6, 0x56, 0x36, 0x44, 0x28, 0x12, 0x72, + 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, + 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, 0x65, 0x6e, + 0x61, 0x62, 0x6c, 0x65, 0x43, 0x84, 0x62, 0x21, 0x19, 0x84, 0xa5, 0xc9, + 0xb9, 0x8c, 0xbd, 0xb5, 0xc1, 0xa5, 0xb1, 0x95, 0xb9, 0x98, 0xc9, 0x85, + 0xb5, 0x95, 0x89, 0xd5, 0x99, 0x99, 0x95, 0xc9, 0x7d, 0x99, 0x95, 0xd1, + 0x8d, 0xa1, 0x7d, 0x95, 0xb9, 0x85, 0x89, 0xb1, 0x95, 0x0d, 0x11, 0x8a, + 0x86, 0x51, 0x58, 0x9a, 0x9c, 0x8b, 0x5c, 0x99, 0x1b, 0x59, 0x99, 0xdc, + 0x17, 0x5d, 0x98, 0xdc, 0x59, 0x19, 0x1d, 0xa3, 0xb0, 0x34, 0x39, 0x97, + 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0x2f, 0xb7, 0xb0, 0xb6, + 0x32, 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x43, 0x90, 0xe2, 0x31, + 0x84, 0x02, 0x2a, 0xa2, 0x21, 0x42, 0x21, 0x51, 0x0a, 0x4b, 0x93, 0x73, + 0x31, 0x93, 0x0b, 0x3b, 0x6b, 0x2b, 0x73, 0xa3, 0xfb, 0x4a, 0x73, 0x83, + 0xab, 0xa3, 0x63, 0x76, 0x56, 0xe6, 0x56, 0x26, 0x17, 0x46, 0x57, 0x46, + 0x86, 0x82, 0x03, 0xf7, 0x36, 0x97, 0x46, 0x97, 0xf6, 0xe6, 0x46, 0x64, + 0x27, 0xf3, 0x65, 0x96, 0x42, 0x25, 0x2c, 0x4d, 0xce, 0x65, 0xac, 0xcc, + 0x8d, 0xae, 0x4c, 0x8e, 0x4f, 0x58, 0x9a, 0x9c, 0x0b, 0x5c, 0x99, 0xdc, + 0x1c, 0x5c, 0xd9, 0x18, 0x5d, 0x9a, 0x5d, 0x19, 0x0d, 0x33, 0xb6, 0xb7, + 0x30, 0x3a, 0x19, 0x32, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x44, 0xe0, 0xde, 0xe6, 0xd2, 0xe8, 0xd2, 0xde, + 0xdc, 0x86, 0x48, 0x86, 0x50, 0x50, 0x45, 0x55, 0x58, 0xc5, 0x55, 0x40, + 0x05, 0x56, 0x64, 0x85, 0x46, 0xeb, 0xac, 0xcc, 0xad, 0x4c, 0x2e, 0x8c, + 0xae, 0x8c, 0x0c, 0xa5, 0x66, 0xec, 0x8d, 0xed, 0x4d, 0x8e, 0xc8, 0x8e, + 0xe6, 0xcb, 0x2c, 0x85, 0xc5, 0xd8, 0x1b, 0xdb, 0x9b, 0xdc, 0x10, 0xc9, + 0x08, 0x0a, 0xaa, 0xe0, 0x0a, 0xab, 0xb8, 0x0a, 0xa8, 0x88, 0x8a, 0xac, + 0xe8, 0x86, 0x10, 0xc5, 0x56, 0x78, 0x43, 0x0c, 0x02, 0x28, 0xa6, 0xe2, + 0x1b, 0x11, 0xb1, 0x03, 0x3b, 0xd8, 0x43, 0x3b, 0xb8, 0x41, 0x3b, 0xbc, + 0x03, 0x39, 0xd4, 0x03, 0x3b, 0x94, 0x83, 0x1b, 0x98, 0x03, 0x3b, 0x84, + 0xc3, 0x39, 0xcc, 0xc3, 0x14, 0x21, 0x18, 0x46, 0x28, 0xec, 0xc0, 0x0e, + 0xf6, 0xd0, 0x0e, 0x6e, 0x90, 0x0e, 0xe4, 0x50, 0x0e, 0xee, 0x40, 0x0f, + 0x53, 0x82, 0x62, 0xc4, 0x12, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0x60, 0x0f, + 0xe5, 0x20, 0x0f, 0xf3, 0x90, 0x0e, 0xef, 0xe0, 0x0e, 0x53, 0x02, 0x63, + 0x04, 0x15, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0xc0, 0x0e, 0xe1, 0xe0, 0x0e, + 0xe7, 0x50, 0x0f, 0xe1, 0x70, 0x0e, 0xe5, 0xf0, 0x0b, 0xf6, 0x50, 0x0e, + 0xf2, 0x30, 0x0f, 0xe9, 0xf0, 0x0e, 0xee, 0x30, 0x25, 0x40, 0x46, 0x4c, + 0xe1, 0x90, 0x0e, 0xf2, 0xe0, 0x06, 0xe3, 0xf0, 0x0e, 0xed, 0x00, 0x0f, + 0xe9, 0xc0, 0x0e, 0xe5, 0xf0, 0x0b, 0xef, 0x00, 0x0f, 0xf4, 0x90, 0x0e, + 0xef, 0xe0, 0x0e, 0xf3, 0x30, 0x65, 0x50, 0x18, 0x67, 0x04, 0x13, 0x0e, + 0xe9, 0x20, 0x0f, 0x6e, 0x60, 0x0e, 0xf2, 0x10, 0x0e, 0xe7, 0xd0, 0x0e, + 0xe5, 0xe0, 0x0e, 0xf4, 0x30, 0x25, 0x00, 0x03, 0x00, 0x00, 0x79, 0x18, + 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, + 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, + 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, + 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, + 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, + 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, + 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, + 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, + 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, + 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, + 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, + 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, + 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, + 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, + 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, + 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, + 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, + 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, + 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, + 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, + 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, + 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, + 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, + 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, + 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, + 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, + 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, + 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, + 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, + 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, + 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, + 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, + 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, + 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, + 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, + 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, + 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, + 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, + 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, + 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, + 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, + 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, 0x00, 0x00, 0x05, 0x00, + 0x00, 0x00, 0x06, 0x20, 0xb1, 0x5d, 0xf9, 0xb3, 0xce, 0x82, 0x0c, 0x7f, + 0x11, 0x01, 0x06, 0x43, 0x34, 0x13, 0x00, 0x00, 0x00, 0x00, 0x61, 0x20, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x06, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, + 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x44, 0x0a, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x8e, 0x02, + 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, + 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, + 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, + 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, 0x44, 0x24, 0x48, 0x0a, + 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, 0x21, 0x72, 0x24, 0x07, + 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, + 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0x1b, 0xcc, + 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x60, 0x00, 0x09, 0xa8, 0x88, + 0x71, 0x78, 0x07, 0x79, 0x90, 0x87, 0x72, 0x18, 0x07, 0x7a, 0x60, 0x87, + 0x7c, 0x68, 0x03, 0x79, 0x78, 0x87, 0x7a, 0x70, 0x07, 0x72, 0x28, 0x07, + 0x72, 0x68, 0x03, 0x72, 0x48, 0x07, 0x7b, 0x48, 0x07, 0x72, 0x28, 0x87, + 0x36, 0x98, 0x87, 0x78, 0x90, 0x07, 0x7a, 0x68, 0x03, 0x73, 0x80, 0x87, + 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xcc, 0x21, 0x1c, 0xd8, + 0x61, 0x1e, 0xca, 0x01, 0x20, 0xc8, 0x21, 0x1d, 0xe6, 0x21, 0x1c, 0xc4, + 0x81, 0x1d, 0xca, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xd2, 0x81, 0x1d, 0xda, + 0x60, 0x1c, 0xc2, 0x81, 0x1d, 0xd8, 0x61, 0x1e, 0x00, 0x73, 0x08, 0x07, + 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x76, 0x28, 0x87, 0x79, 0x98, 0x87, + 0x36, 0x80, 0x07, 0x79, 0x28, 0x87, 0x71, 0x48, 0x87, 0x79, 0x28, 0x87, + 0x36, 0x30, 0x07, 0x78, 0x68, 0x87, 0x70, 0x20, 0x07, 0xc0, 0x1c, 0xc2, + 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xcc, + 0x41, 0x1e, 0xc2, 0xa1, 0x1d, 0xca, 0xa1, 0x0d, 0xe0, 0xe1, 0x1d, 0xd2, + 0xc1, 0x1d, 0xe8, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xca, 0x81, 0x1d, 0xd2, + 0xa1, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x60, 0x70, 0x87, + 0x77, 0x68, 0x03, 0x73, 0x90, 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, + 0x78, 0x78, 0x87, 0x74, 0x70, 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, + 0x72, 0x60, 0x87, 0x74, 0x68, 0x87, 0x36, 0x70, 0x87, 0x77, 0x70, 0x87, + 0x36, 0x60, 0x87, 0x72, 0x08, 0x07, 0x73, 0x00, 0x08, 0x77, 0x78, 0x87, + 0x36, 0x48, 0x07, 0x77, 0x30, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, + 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, + 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xd4, 0xa1, 0x1e, 0xda, + 0x01, 0x1e, 0xda, 0x80, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, 0xa1, 0x1c, 0xe6, + 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, + 0x77, 0x68, 0x03, 0x77, 0x08, 0x07, 0x77, 0x98, 0x87, 0x36, 0x30, 0x07, + 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, + 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x60, 0x1e, 0xd2, + 0xe1, 0x1c, 0xdc, 0xa1, 0x1c, 0xc8, 0xa1, 0x0d, 0xf4, 0xa1, 0x1c, 0xe4, + 0xe1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, + 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, + 0x77, 0x78, 0x87, 0x36, 0xa0, 0x07, 0x79, 0x08, 0x07, 0x78, 0x80, 0x87, + 0x74, 0x70, 0x87, 0x73, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, + 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xe6, 0x81, 0x1e, 0xc2, + 0x61, 0x1c, 0xd6, 0xa1, 0x0d, 0xe0, 0x41, 0x1e, 0xde, 0x81, 0x1e, 0xca, + 0x61, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, 0xa1, 0x0d, 0xc4, 0xa1, 0x1e, 0xcc, + 0xc1, 0x1c, 0xca, 0x41, 0x1e, 0xda, 0x60, 0x1e, 0xd2, 0x41, 0x1f, 0xca, + 0x01, 0xc0, 0x03, 0x80, 0xa8, 0x07, 0x77, 0x98, 0x87, 0x70, 0x30, 0x87, + 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, + 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xa2, 0x1e, 0xe6, + 0xa1, 0x1c, 0xda, 0x60, 0x1e, 0xde, 0xc1, 0x1c, 0xe8, 0xa1, 0x0d, 0xcc, + 0x81, 0x1d, 0xde, 0x21, 0x1c, 0xe8, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, + 0x79, 0x28, 0x07, 0x60, 0x83, 0x21, 0x10, 0xc0, 0x02, 0x54, 0x1b, 0x8c, + 0xa1, 0x00, 0x16, 0xa0, 0xda, 0x80, 0x10, 0xff, 0xff, 0xff, 0xff, 0x3f, + 0x00, 0x0c, 0x20, 0x01, 0xd5, 0x06, 0xa3, 0x08, 0x80, 0x05, 0xa8, 0x36, + 0x18, 0x86, 0x00, 0x2c, 0x40, 0x05, 0x49, 0x18, 0x00, 0x00, 0x03, 0x00, + 0x00, 0x00, 0x13, 0x86, 0x40, 0x18, 0x26, 0x0c, 0x44, 0x61, 0x00, 0x00, + 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x32, 0x22, + 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, + 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, + 0xa4, 0x4c, 0x10, 0x44, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, + 0x00, 0x47, 0x49, 0x53, 0x44, 0x09, 0x93, 0xff, 0x4f, 0xc4, 0x35, 0x51, + 0x11, 0xf1, 0xdb, 0xc3, 0x3f, 0x8d, 0x11, 0x00, 0x83, 0x08, 0x43, 0x70, + 0x91, 0x34, 0x45, 0x94, 0x30, 0xf9, 0xbf, 0x04, 0x30, 0xcf, 0x42, 0x44, + 0xff, 0x34, 0x46, 0x00, 0x0c, 0x22, 0x14, 0x42, 0x31, 0x42, 0x08, 0x82, + 0x18, 0x3a, 0x73, 0x04, 0xc1, 0x1c, 0x01, 0x18, 0x0c, 0x23, 0x08, 0x4a, + 0x41, 0x02, 0x31, 0x22, 0xad, 0x04, 0x88, 0x0d, 0x04, 0xa4, 0x80, 0x1a, + 0x01, 0x00, 0x13, 0xa8, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, + 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, + 0x87, 0x79, 0xc8, 0x03, 0x37, 0x80, 0x03, 0x37, 0x80, 0x83, 0x0d, 0xb7, + 0x51, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x7a, + 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x78, + 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, + 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, + 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, + 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, + 0xd0, 0x06, 0xe6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, + 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x76, + 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xf6, + 0x20, 0x07, 0x74, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, + 0xd0, 0x06, 0xf6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, + 0x30, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x40, 0x07, 0x78, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x60, 0x07, 0x74, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, + 0x90, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, + 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, + 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, + 0x60, 0x0f, 0x71, 0x90, 0x07, 0x72, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, + 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x75, + 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, + 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x75, 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, + 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, 0x72, 0xd0, 0x06, 0xf6, + 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, + 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xd0, 0x06, 0xee, + 0x80, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x43, + 0x18, 0x04, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x21, 0x4c, + 0x03, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x16, 0x08, 0x00, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, + 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x52, 0x25, 0x30, + 0x02, 0x50, 0x04, 0x85, 0x50, 0x10, 0x65, 0x40, 0x6f, 0x2c, 0xc1, 0x21, + 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0xca, 0x00, 0x00, 0x00, 0x1a, 0x03, + 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4, + 0x37, 0xb7, 0x21, 0x86, 0x42, 0x38, 0xc0, 0x83, 0x50, 0xb9, 0x1b, 0x43, + 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x1b, 0x62, 0x28, 0x82, 0x23, + 0x28, 0x05, 0xe1, 0x20, 0x08, 0x0e, 0x8e, 0xad, 0x0c, 0x84, 0x89, 0xc9, + 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x0d, 0x64, 0x26, + 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, 0x06, 0x04, 0xa5, 0xad, 0x8c, 0x2e, + 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, + 0xc6, 0x25, 0x26, 0x65, 0x88, 0xe0, 0x10, 0x43, 0x0c, 0x45, 0x50, 0x0c, + 0x65, 0x60, 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, 0x04, 0x71, 0x0e, 0x45, + 0x50, 0x04, 0x65, 0xe0, 0x16, 0x96, 0x26, 0xe7, 0x32, 0xf6, 0xd6, 0x06, + 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, 0x26, 0xd7, 0x36, 0xf7, + 0x45, 0x96, 0x36, 0x17, 0x26, 0xc6, 0x56, 0x36, 0x44, 0x70, 0x12, 0x72, + 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, + 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, 0x65, 0x6e, + 0x61, 0x62, 0x6c, 0x65, 0x43, 0x04, 0x67, 0x21, 0x19, 0x84, 0xa5, 0xc9, + 0xb9, 0x8c, 0xbd, 0xb5, 0xc1, 0xa5, 0xb1, 0x95, 0xb9, 0x98, 0xc9, 0x85, + 0xb5, 0x95, 0x89, 0xd5, 0x99, 0x99, 0x95, 0xc9, 0x7d, 0x99, 0x95, 0xd1, + 0x8d, 0xa1, 0x7d, 0x95, 0xb9, 0x85, 0x89, 0xb1, 0x95, 0x0d, 0x11, 0x9c, + 0x86, 0x51, 0x58, 0x9a, 0x9c, 0x8b, 0x5c, 0x99, 0x1b, 0x59, 0x99, 0xdc, + 0x17, 0x5d, 0x98, 0xdc, 0x59, 0x19, 0x1d, 0xa3, 0xb0, 0x34, 0x39, 0x97, + 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0x2f, 0xb7, 0xb0, 0xb6, + 0x32, 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x43, 0x10, 0xe7, 0x51, + 0x06, 0x07, 0x72, 0xa2, 0x21, 0x82, 0x23, 0x91, 0x09, 0x4b, 0x93, 0x73, + 0x81, 0x7b, 0x9b, 0x4b, 0xa3, 0x4b, 0x7b, 0x73, 0xa3, 0x12, 0x96, 0x26, + 0xe7, 0x32, 0x56, 0xe6, 0x46, 0x57, 0x26, 0x47, 0x29, 0x2c, 0x4d, 0xce, + 0xc5, 0xed, 0xed, 0x0b, 0xae, 0x4c, 0x6e, 0x0e, 0xae, 0x6c, 0x8c, 0x2e, + 0xcd, 0xae, 0x8c, 0x4c, 0x58, 0x9a, 0x9c, 0x4b, 0x98, 0xdc, 0xd9, 0x97, + 0x5b, 0x58, 0x5b, 0x19, 0x11, 0xb8, 0xb7, 0xb9, 0x34, 0xba, 0xb4, 0x37, + 0xb7, 0x21, 0x90, 0x32, 0x38, 0x94, 0x53, 0x39, 0x96, 0x03, 0x39, 0x91, + 0x73, 0x39, 0x18, 0xa5, 0xb0, 0x34, 0x39, 0x17, 0x33, 0xb9, 0xb0, 0xb3, + 0xb6, 0x32, 0x37, 0xba, 0xaf, 0x34, 0x37, 0xb8, 0x3a, 0x3a, 0x5a, 0x67, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x35, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x44, 0x76, 0x34, 0x5f, 0x66, 0x29, 0x7c, 0xc2, 0xd2, + 0xe4, 0x5c, 0xe0, 0xca, 0xe4, 0xe6, 0xe0, 0xca, 0xc6, 0xe8, 0xd2, 0xec, + 0xca, 0x58, 0x8c, 0xbd, 0xb1, 0xbd, 0xc9, 0x0d, 0x91, 0x14, 0xc1, 0xd1, + 0x9c, 0xcd, 0xa9, 0x1c, 0xce, 0x81, 0x9c, 0xc8, 0xb9, 0x9c, 0x8e, 0xd9, + 0x59, 0x99, 0x5b, 0x99, 0x5c, 0x18, 0x5d, 0x19, 0x19, 0x0a, 0x0e, 0x5d, + 0x19, 0xde, 0xd8, 0xdb, 0x9b, 0x1c, 0x19, 0x91, 0x9d, 0xcc, 0x97, 0x59, + 0x0a, 0x0d, 0x33, 0xb6, 0xb7, 0x30, 0x3a, 0x19, 0x22, 0x74, 0x65, 0x78, + 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x43, 0x24, 0x85, 0x70, 0x34, 0xe7, 0x73, + 0x2a, 0x87, 0x73, 0x20, 0x07, 0x0c, 0x9c, 0xcb, 0x09, 0x03, 0x2e, 0x61, + 0x69, 0x72, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x94, 0xc2, + 0xd2, 0xe4, 0x5c, 0xd8, 0xde, 0xc6, 0xc2, 0xe8, 0xd2, 0xde, 0xdc, 0xbe, + 0xd2, 0xdc, 0xc8, 0xca, 0xf0, 0xa8, 0x84, 0xa5, 0xc9, 0xb9, 0xcc, 0x85, + 0xb5, 0xc1, 0xb1, 0x95, 0x11, 0xa3, 0x2b, 0xc3, 0xa3, 0xab, 0x93, 0x2b, + 0x93, 0x21, 0xe3, 0x31, 0x63, 0x7b, 0x0b, 0xa3, 0x63, 0x01, 0x99, 0x0b, + 0x6b, 0x83, 0x63, 0x2b, 0xf3, 0xe1, 0x40, 0x57, 0x86, 0x37, 0x84, 0x52, + 0x0e, 0x67, 0x0c, 0x1c, 0x32, 0x50, 0x06, 0x45, 0x70, 0xca, 0xc0, 0x81, + 0x1c, 0x33, 0x70, 0x2e, 0xe7, 0x0c, 0xb8, 0x84, 0xa5, 0xc9, 0xb9, 0xcc, + 0x85, 0xb5, 0xc1, 0xb1, 0x95, 0xc9, 0xf1, 0x98, 0x0b, 0x6b, 0x83, 0x63, + 0x2b, 0x93, 0x63, 0x30, 0x37, 0x44, 0x52, 0x0a, 0x27, 0x0d, 0x1c, 0x32, + 0x50, 0x06, 0x45, 0x70, 0x20, 0x47, 0x0d, 0x9c, 0xcb, 0x59, 0x83, 0x21, + 0x8a, 0x93, 0x39, 0x9e, 0x23, 0x06, 0x0e, 0x1a, 0x38, 0x6c, 0x30, 0xc4, + 0x40, 0x00, 0x67, 0x72, 0xda, 0x60, 0x44, 0xc4, 0x0e, 0xec, 0x60, 0x0f, + 0xed, 0xe0, 0x06, 0xed, 0xf0, 0x0e, 0xe4, 0x50, 0x0f, 0xec, 0x50, 0x0e, + 0x6e, 0x60, 0x0e, 0xec, 0x10, 0x0e, 0xe7, 0x30, 0x0f, 0x53, 0x84, 0x60, + 0x18, 0xa1, 0xb0, 0x03, 0x3b, 0xd8, 0x43, 0x3b, 0xb8, 0x41, 0x3a, 0x90, + 0x43, 0x39, 0xb8, 0x03, 0x3d, 0x4c, 0x09, 0x8a, 0x11, 0x4b, 0x38, 0xa4, + 0x83, 0x3c, 0xb8, 0x81, 0x3d, 0x94, 0x83, 0x3c, 0xcc, 0x43, 0x3a, 0xbc, + 0x83, 0x3b, 0x4c, 0x09, 0x8c, 0x11, 0x54, 0x38, 0xa4, 0x83, 0x3c, 0xb8, + 0x01, 0x3b, 0x84, 0x83, 0x3b, 0x9c, 0x43, 0x3d, 0x84, 0xc3, 0x39, 0x94, + 0xc3, 0x2f, 0xd8, 0x43, 0x39, 0xc8, 0xc3, 0x3c, 0xa4, 0xc3, 0x3b, 0xb8, + 0xc3, 0x94, 0x00, 0x19, 0x31, 0x85, 0x43, 0x3a, 0xc8, 0x83, 0x1b, 0x8c, + 0xc3, 0x3b, 0xb4, 0x03, 0x3c, 0xa4, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, + 0x03, 0x3c, 0xd0, 0x43, 0x3a, 0xbc, 0x83, 0x3b, 0xcc, 0xc3, 0x94, 0x41, + 0x61, 0x9c, 0x11, 0x4c, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xc8, + 0x43, 0x38, 0x9c, 0x43, 0x3b, 0x94, 0x83, 0x3b, 0xd0, 0xc3, 0x94, 0xc0, + 0x0d, 0x00, 0x79, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, + 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, + 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, + 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, + 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, + 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, + 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, + 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, + 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, + 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, + 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, + 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, + 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, + 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, + 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, + 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, + 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, + 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, + 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, + 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, + 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, + 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, + 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, + 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, + 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, + 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, + 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, + 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, + 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, + 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, + 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, + 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, + 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, + 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, + 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, + 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, + 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, + 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, + 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, + 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, + 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, + 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, + 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x06, 0x10, 0xb1, 0x5d, 0xf9, 0x73, + 0xce, 0x83, 0xfd, 0x45, 0x04, 0x18, 0x0c, 0xd1, 0x4c, 0x16, 0xb0, 0x01, + 0x48, 0xe4, 0x4b, 0x00, 0xf3, 0x2c, 0xc4, 0x3f, 0x11, 0xd7, 0x44, 0x45, + 0xc4, 0x6f, 0x0f, 0x7e, 0x85, 0x17, 0xb7, 0x0d, 0x00, 0x00, 0x61, 0x20, + 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, + 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xb4, 0x46, 0x00, 0x28, 0xd5, 0xc0, + 0x08, 0x00, 0x81, 0x11, 0x00, 0x00, 0x23, 0x06, 0x8a, 0x10, 0x44, 0x46, + 0x71, 0x0c, 0x84, 0x10, 0x58, 0x90, 0xc8, 0x27, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, + 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xc8, 0x0c, + 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, + 0x00, 0x00, 0x2f, 0x03, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, + 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, + 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, + 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, + 0x44, 0x24, 0x48, 0x0a, 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, + 0x21, 0x72, 0x24, 0x07, 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, + 0xc6, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x8e, 0x00, + 0x00, 0x00, 0x1b, 0xcc, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x60, + 0x00, 0x09, 0xa8, 0x88, 0x71, 0x78, 0x07, 0x79, 0x90, 0x87, 0x72, 0x18, + 0x07, 0x7a, 0x60, 0x87, 0x7c, 0x68, 0x03, 0x79, 0x78, 0x87, 0x7a, 0x70, + 0x07, 0x72, 0x28, 0x07, 0x72, 0x68, 0x03, 0x72, 0x48, 0x07, 0x7b, 0x48, + 0x07, 0x72, 0x28, 0x87, 0x36, 0x98, 0x87, 0x78, 0x90, 0x07, 0x7a, 0x68, + 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, + 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xc8, 0x21, 0x1d, + 0xe6, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, + 0xd2, 0x81, 0x1d, 0xda, 0x60, 0x1c, 0xc2, 0x81, 0x1d, 0xd8, 0x61, 0x1e, + 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x76, 0x28, + 0x87, 0x79, 0x98, 0x87, 0x36, 0x80, 0x07, 0x79, 0x28, 0x87, 0x71, 0x48, + 0x87, 0x79, 0x28, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x87, 0x70, 0x20, + 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, + 0xde, 0xa1, 0x0d, 0xcc, 0x41, 0x1e, 0xc2, 0xa1, 0x1d, 0xca, 0xa1, 0x0d, + 0xe0, 0xe1, 0x1d, 0xd2, 0xc1, 0x1d, 0xe8, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, + 0xca, 0x81, 0x1d, 0xd2, 0xa1, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, + 0x07, 0x60, 0x70, 0x87, 0x77, 0x68, 0x03, 0x73, 0x90, 0x87, 0x70, 0x68, + 0x87, 0x72, 0x68, 0x03, 0x78, 0x78, 0x87, 0x74, 0x70, 0x07, 0x7a, 0x28, + 0x07, 0x79, 0x68, 0x83, 0x72, 0x60, 0x87, 0x74, 0x68, 0x87, 0x36, 0x70, + 0x87, 0x77, 0x70, 0x87, 0x36, 0x60, 0x87, 0x72, 0x08, 0x07, 0x73, 0x00, + 0x08, 0x77, 0x78, 0x87, 0x36, 0x48, 0x07, 0x77, 0x30, 0x87, 0x79, 0x68, + 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, + 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, + 0xd4, 0xa1, 0x1e, 0xda, 0x01, 0x1e, 0xda, 0x80, 0x1e, 0xc2, 0x41, 0x1c, + 0xd8, 0xa1, 0x1c, 0xe6, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, + 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x77, 0x08, 0x07, 0x77, 0x98, + 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, + 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, + 0xda, 0x60, 0x1e, 0xd2, 0xe1, 0x1c, 0xdc, 0xa1, 0x1c, 0xc8, 0xa1, 0x0d, + 0xf4, 0xa1, 0x1c, 0xe4, 0xe1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, + 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, + 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0xa0, 0x07, 0x79, 0x08, + 0x07, 0x78, 0x80, 0x87, 0x74, 0x70, 0x87, 0x73, 0x68, 0x83, 0x76, 0x08, + 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, + 0xe6, 0x81, 0x1e, 0xc2, 0x61, 0x1c, 0xd6, 0xa1, 0x0d, 0xe0, 0x41, 0x1e, + 0xde, 0x81, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, 0xa1, 0x0d, + 0xc4, 0xa1, 0x1e, 0xcc, 0xc1, 0x1c, 0xca, 0x41, 0x1e, 0xda, 0x60, 0x1e, + 0xd2, 0x41, 0x1f, 0xca, 0x01, 0xc0, 0x03, 0x80, 0xa8, 0x07, 0x77, 0x98, + 0x87, 0x70, 0x30, 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, + 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, + 0x00, 0xa2, 0x1e, 0xe6, 0xa1, 0x1c, 0xda, 0x60, 0x1e, 0xde, 0xc1, 0x1c, + 0xe8, 0xa1, 0x0d, 0xcc, 0x81, 0x1d, 0xde, 0x21, 0x1c, 0xe8, 0x01, 0x30, + 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x60, 0x03, 0x22, 0x10, 0x40, + 0x02, 0x2c, 0x40, 0xb5, 0xc1, 0x18, 0x0a, 0x60, 0x01, 0xaa, 0x0d, 0x06, + 0x71, 0x00, 0x0b, 0x50, 0x6d, 0x30, 0x8a, 0xff, 0xff, 0xff, 0xff, 0x1f, + 0x00, 0x09, 0xa0, 0x36, 0x20, 0xc6, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, + 0x03, 0x48, 0x40, 0xb5, 0xc1, 0x38, 0x02, 0x60, 0x01, 0xaa, 0x0d, 0x06, + 0x22, 0x00, 0x0b, 0x50, 0x01, 0x00, 0x49, 0x18, 0x00, 0x00, 0x03, 0x00, + 0x00, 0x00, 0x13, 0x88, 0x40, 0x18, 0x88, 0x09, 0x41, 0x31, 0x61, 0x30, + 0x0e, 0x04, 0x89, 0x20, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x32, 0x22, + 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, + 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, + 0xa4, 0x4c, 0x10, 0x78, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, + 0x00, 0xc3, 0x08, 0x03, 0x70, 0x90, 0x34, 0x45, 0x94, 0x30, 0xf9, 0xb2, + 0xfb, 0x76, 0x84, 0xe0, 0x0c, 0x04, 0x22, 0xc6, 0x18, 0x63, 0x10, 0x81, + 0x10, 0x8e, 0x92, 0xa6, 0x88, 0x12, 0x26, 0xff, 0x9f, 0x88, 0x6b, 0xa2, + 0x22, 0xe2, 0xb7, 0x87, 0x7f, 0x1a, 0x23, 0x00, 0x06, 0x11, 0x8c, 0xe0, + 0x34, 0x69, 0x8a, 0x28, 0x61, 0xf2, 0xff, 0x89, 0xb8, 0x26, 0x2a, 0x22, + 0x7e, 0x7b, 0xf8, 0x81, 0x28, 0x02, 0xb0, 0x7f, 0x1a, 0x23, 0x00, 0x06, + 0x11, 0x90, 0xe0, 0x22, 0x69, 0x8a, 0x28, 0x61, 0xf2, 0x7f, 0x09, 0x60, + 0x9e, 0x85, 0x88, 0xfe, 0x69, 0x8c, 0x00, 0x18, 0x44, 0x50, 0x84, 0x82, + 0x84, 0x10, 0x44, 0x39, 0x69, 0x11, 0x2b, 0x03, 0x18, 0x83, 0xdc, 0x1c, + 0x01, 0x18, 0xcc, 0x11, 0x04, 0xc3, 0x08, 0x02, 0x54, 0x92, 0x90, 0x96, + 0x80, 0x51, 0x46, 0x40, 0xb3, 0x20, 0xe1, 0x2c, 0x11, 0x65, 0x04, 0x54, + 0x07, 0x02, 0x52, 0x00, 0x0e, 0x23, 0x0c, 0xd0, 0x20, 0x42, 0x20, 0xcc, + 0x11, 0x80, 0xc2, 0x20, 0xc2, 0x20, 0x8c, 0x00, 0x00, 0x00, 0x13, 0xa8, + 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, + 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, 0x87, 0x79, 0xc8, 0x03, + 0x37, 0x80, 0x03, 0x37, 0x80, 0x83, 0x0d, 0xb7, 0x51, 0x0e, 0x6d, 0x00, + 0x0f, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, + 0x07, 0x74, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, + 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, + 0x06, 0xe9, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x10, + 0x07, 0x76, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, + 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x60, 0x07, 0x74, 0xa0, + 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, + 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, + 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, + 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x74, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, + 0x06, 0xf6, 0x40, 0x07, 0x78, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, + 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x90, 0x07, 0x76, 0xa0, + 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, + 0x06, 0xf6, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, + 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x90, + 0x07, 0x72, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, + 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, + 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, + 0x0f, 0x75, 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, 0x72, 0xa0, + 0x07, 0x75, 0x10, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x70, 0x20, + 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, + 0x07, 0x70, 0x20, 0x07, 0x74, 0xd0, 0x06, 0xee, 0x80, 0x07, 0x7a, 0x10, + 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x43, 0x98, 0x06, 0x00, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x21, 0xcc, 0x03, 0x04, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0x10, 0x86, 0x02, 0x02, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x60, 0x08, 0x63, 0x01, 0x01, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x90, 0x05, 0x02, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x32, 0x1e, + 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, + 0x43, 0x82, 0x25, 0x30, 0x02, 0x50, 0x20, 0x45, 0x50, 0x08, 0x05, 0x18, + 0x50, 0x10, 0x65, 0x50, 0x40, 0x05, 0x56, 0x0a, 0xc5, 0x40, 0x78, 0x2c, + 0xc1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x13, 0x01, + 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, 0x10, 0xab, + 0x32, 0xb9, 0xb9, 0xb4, 0x37, 0xb7, 0x21, 0x06, 0x74, 0x5c, 0x00, 0x06, + 0x51, 0xb9, 0x1b, 0x43, 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x1b, + 0x62, 0x40, 0xc4, 0x25, 0x40, 0x08, 0xe1, 0x20, 0x08, 0x0e, 0x8e, 0xad, + 0x0c, 0x84, 0x89, 0xc9, 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, 0x2e, 0xed, + 0xcd, 0x0d, 0x64, 0x26, 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, 0x06, 0x04, + 0xa5, 0xad, 0x8c, 0x2e, 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, 0x06, 0x06, + 0x26, 0xc6, 0xa5, 0x06, 0xc6, 0x25, 0x26, 0x65, 0x88, 0x70, 0x11, 0x43, + 0x0c, 0x88, 0x80, 0x14, 0xa8, 0x60, 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, + 0x04, 0xb9, 0x0e, 0x88, 0x80, 0x08, 0xa8, 0xe0, 0x16, 0x96, 0x26, 0xe7, + 0x32, 0xf6, 0xd6, 0x06, 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, + 0x26, 0xd7, 0x36, 0xf7, 0x45, 0x96, 0x36, 0x17, 0x26, 0xc6, 0x56, 0x36, + 0x44, 0xb8, 0x12, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, + 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, + 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x84, 0x6b, 0x21, + 0x19, 0x84, 0xa5, 0xc9, 0xb9, 0x8c, 0xbd, 0xb5, 0xc1, 0xa5, 0xb1, 0x95, + 0xb9, 0x98, 0xc9, 0x85, 0xb5, 0x95, 0x89, 0xd5, 0x99, 0x99, 0x95, 0xc9, + 0x7d, 0x99, 0x95, 0xd1, 0x8d, 0xa1, 0x7d, 0x95, 0xb9, 0x85, 0x89, 0xb1, + 0x95, 0x0d, 0x11, 0xae, 0x86, 0x51, 0x58, 0x9a, 0x9c, 0x8b, 0x5c, 0x99, + 0x1b, 0x59, 0x99, 0xdc, 0x17, 0x5d, 0x98, 0xdc, 0x59, 0x19, 0x1d, 0xa3, + 0xb0, 0x34, 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, + 0x2f, 0xb7, 0xb0, 0xb6, 0x32, 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, + 0x43, 0x90, 0xeb, 0x81, 0x8a, 0x0b, 0xba, 0xa2, 0x21, 0xc2, 0x25, 0x91, + 0x09, 0x4b, 0x93, 0x73, 0x81, 0x7b, 0x9b, 0x4b, 0xa3, 0x4b, 0x7b, 0x73, + 0xa3, 0x12, 0x96, 0x26, 0xe7, 0x32, 0x56, 0xe6, 0x46, 0x57, 0x26, 0x47, + 0x29, 0x2c, 0x4d, 0xce, 0xc5, 0xed, 0xed, 0x0b, 0xae, 0x4c, 0x6e, 0x0e, + 0xae, 0x6c, 0x8c, 0x2e, 0xcd, 0xae, 0x8c, 0x4c, 0x58, 0x9a, 0x9c, 0x4b, + 0x98, 0xdc, 0xd9, 0x97, 0x5b, 0x58, 0x5b, 0x19, 0x11, 0xb8, 0xb7, 0xb9, + 0x34, 0xba, 0xb4, 0x37, 0xb7, 0x21, 0x10, 0x54, 0x5c, 0xd4, 0x55, 0x5d, + 0xd6, 0x05, 0x5d, 0xd1, 0x75, 0x5d, 0x18, 0xa5, 0xb0, 0x34, 0x39, 0x17, + 0x33, 0xb9, 0xb0, 0xb3, 0xb6, 0x32, 0x37, 0xba, 0xaf, 0x34, 0x37, 0xb8, + 0x3a, 0x3a, 0x5a, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, + 0x28, 0x35, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x44, 0x76, 0x34, 0x5f, 0x66, + 0x29, 0x7c, 0xc2, 0xd2, 0xe4, 0x5c, 0xe0, 0xca, 0xe4, 0xe6, 0xe0, 0xca, + 0xc6, 0xe8, 0xd2, 0xec, 0xca, 0x58, 0x8c, 0xbd, 0xb1, 0xbd, 0xc9, 0x0d, + 0x91, 0x20, 0xe2, 0xd2, 0xae, 0xed, 0xaa, 0x2e, 0xee, 0x82, 0xae, 0xe8, + 0xba, 0xae, 0x8e, 0xd9, 0x59, 0x99, 0x5b, 0x99, 0x5c, 0x18, 0x5d, 0x19, + 0x19, 0x0a, 0x0e, 0x5d, 0x19, 0xde, 0xd8, 0xdb, 0x9b, 0x1c, 0x19, 0x91, + 0x9d, 0xcc, 0x97, 0x59, 0x0a, 0x0d, 0x33, 0xb6, 0xb7, 0x30, 0x3a, 0x19, + 0x22, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x43, 0x24, 0xe8, + 0xb8, 0xb4, 0xeb, 0xbb, 0xaa, 0x8b, 0xbb, 0xa0, 0x0b, 0x0c, 0xae, 0xeb, + 0x0a, 0x03, 0x2a, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, + 0x72, 0x7c, 0xc2, 0xd2, 0xe4, 0x5c, 0xc4, 0xea, 0xcc, 0xcc, 0xca, 0xe4, + 0xbe, 0xe6, 0xd2, 0xf4, 0xca, 0x28, 0x85, 0xa5, 0xc9, 0xb9, 0xb0, 0xbd, + 0x8d, 0x85, 0xd1, 0xa5, 0xbd, 0xb9, 0x7d, 0xa5, 0xb9, 0x91, 0x95, 0xe1, + 0x11, 0x09, 0x4b, 0x93, 0x73, 0x91, 0x2b, 0x0b, 0x23, 0x23, 0x15, 0x96, + 0x26, 0xe7, 0x32, 0x47, 0x27, 0x57, 0x37, 0x46, 0xf7, 0x45, 0x97, 0x07, + 0x57, 0xf6, 0x95, 0xe6, 0x66, 0xf6, 0x46, 0xc3, 0x8c, 0xed, 0x2d, 0x8c, + 0x6e, 0x86, 0xc6, 0x9b, 0x99, 0xd9, 0x5c, 0x19, 0x1d, 0x0d, 0xa9, 0xb1, + 0xb7, 0x32, 0x33, 0x33, 0x1a, 0x47, 0x63, 0x6f, 0x65, 0x66, 0x66, 0x34, + 0x84, 0xc6, 0xde, 0xca, 0xcc, 0xcc, 0x86, 0xa0, 0x01, 0x54, 0x40, 0x06, + 0x54, 0x5c, 0x68, 0x70, 0xa5, 0x01, 0x64, 0x40, 0x06, 0x54, 0x5c, 0x68, + 0x70, 0xa9, 0x01, 0xc4, 0x40, 0x06, 0x54, 0x5c, 0x68, 0x70, 0xad, 0x01, + 0xd4, 0x40, 0x06, 0x54, 0x5c, 0x68, 0x70, 0xb1, 0x01, 0xa3, 0xb0, 0x34, + 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0xaf, 0xb9, + 0x34, 0xbd, 0x32, 0x5e, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x5f, 0x73, + 0x69, 0x7a, 0x65, 0x4c, 0xb2, 0xaa, 0xac, 0x88, 0xca, 0xc6, 0xde, 0xc8, + 0xca, 0x68, 0x90, 0x95, 0x8d, 0xbd, 0x91, 0x95, 0x0d, 0x21, 0x03, 0x68, + 0xb9, 0xc6, 0xe0, 0x22, 0x03, 0x28, 0xb9, 0xca, 0x00, 0x22, 0x20, 0xe2, + 0x32, 0x83, 0xeb, 0x0c, 0xae, 0x36, 0xb8, 0xdc, 0x00, 0x4a, 0xae, 0x37, + 0x80, 0x8c, 0x0b, 0xba, 0xe0, 0xe0, 0xba, 0xae, 0x38, 0xe0, 0x12, 0x96, + 0x26, 0xe7, 0x42, 0x57, 0x86, 0x47, 0x57, 0x27, 0x57, 0x46, 0x25, 0x2c, + 0x4d, 0xce, 0x65, 0x2e, 0xac, 0x0d, 0x8e, 0xad, 0x8c, 0x18, 0x5d, 0x19, + 0x1e, 0x5d, 0x9d, 0x5c, 0x99, 0x0c, 0x19, 0x8f, 0x19, 0xdb, 0x5b, 0x18, + 0x1d, 0x0b, 0xc8, 0x5c, 0x58, 0x1b, 0x1c, 0x5b, 0x99, 0x0f, 0x09, 0xba, + 0x32, 0xbc, 0xac, 0x21, 0x14, 0x84, 0x5c, 0x73, 0x70, 0x95, 0x01, 0x54, + 0x40, 0xc4, 0x45, 0x07, 0x17, 0x74, 0xd5, 0xc1, 0x75, 0x5d, 0x76, 0x40, + 0x8f, 0xae, 0x0c, 0x8f, 0xae, 0x4e, 0xae, 0x4c, 0x86, 0xec, 0x2b, 0x4c, + 0x4e, 0x2e, 0x2c, 0x8f, 0xc7, 0x8c, 0xed, 0x2d, 0x8c, 0x8e, 0x05, 0x64, + 0x2e, 0xac, 0x0d, 0x8e, 0xad, 0xcc, 0x87, 0x05, 0x5d, 0x19, 0x5e, 0x95, + 0xd5, 0x10, 0x0a, 0x72, 0xae, 0x39, 0xb8, 0xca, 0x00, 0x22, 0x20, 0xe2, + 0xa2, 0x83, 0x0b, 0xba, 0xf0, 0xe0, 0xba, 0xae, 0x3c, 0xe0, 0x12, 0x96, + 0x26, 0xe7, 0x32, 0x17, 0xd6, 0x06, 0xc7, 0x56, 0x26, 0xc7, 0x63, 0x2e, + 0xac, 0x0d, 0x8e, 0xad, 0x4c, 0x8e, 0xc1, 0xdc, 0x10, 0x09, 0x7a, 0xae, + 0x3d, 0xb8, 0xca, 0x00, 0x2a, 0x20, 0xe2, 0x82, 0x2e, 0x3e, 0xb8, 0xae, + 0xab, 0x0f, 0x86, 0x38, 0x57, 0x76, 0x79, 0x97, 0x18, 0x5c, 0x72, 0x70, + 0xdd, 0xc1, 0xa5, 0x07, 0x97, 0x1f, 0x0c, 0x31, 0x1a, 0xe0, 0x9a, 0xae, + 0x3f, 0x18, 0x11, 0xb1, 0x03, 0x3b, 0xd8, 0x43, 0x3b, 0xb8, 0x41, 0x3b, + 0xbc, 0x03, 0x39, 0xd4, 0x03, 0x3b, 0x94, 0x83, 0x1b, 0x98, 0x03, 0x3b, + 0x84, 0xc3, 0x39, 0xcc, 0xc3, 0x14, 0x21, 0x18, 0x46, 0x28, 0xec, 0xc0, + 0x0e, 0xf6, 0xd0, 0x0e, 0x6e, 0x90, 0x0e, 0xe4, 0x50, 0x0e, 0xee, 0x40, + 0x0f, 0x53, 0x82, 0x62, 0xc4, 0x12, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0x60, + 0x0f, 0xe5, 0x20, 0x0f, 0xf3, 0x90, 0x0e, 0xef, 0xe0, 0x0e, 0x53, 0x02, + 0x63, 0x04, 0x15, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0xc0, 0x0e, 0xe1, 0xe0, + 0x0e, 0xe7, 0x50, 0x0f, 0xe1, 0x70, 0x0e, 0xe5, 0xf0, 0x0b, 0xf6, 0x50, + 0x0e, 0xf2, 0x30, 0x0f, 0xe9, 0xf0, 0x0e, 0xee, 0x30, 0x25, 0x40, 0x46, + 0x4c, 0xe1, 0x90, 0x0e, 0xf2, 0xe0, 0x06, 0xe3, 0xf0, 0x0e, 0xed, 0x00, + 0x0f, 0xe9, 0xc0, 0x0e, 0xe5, 0xf0, 0x0b, 0xef, 0x00, 0x0f, 0xf4, 0x90, + 0x0e, 0xef, 0xe0, 0x0e, 0xf3, 0x30, 0x65, 0x50, 0x18, 0x67, 0x04, 0x13, + 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0x60, 0x0e, 0xf2, 0x10, 0x0e, 0xe7, 0xd0, + 0x0e, 0xe5, 0xe0, 0x0e, 0xf4, 0x30, 0x25, 0x00, 0x05, 0x00, 0x79, 0x18, + 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, + 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, + 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, + 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, + 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, + 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, + 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, + 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, + 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, + 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, + 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, + 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, + 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, + 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, + 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, + 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, + 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, + 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, + 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, + 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, + 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, + 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, + 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, + 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, + 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, + 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, + 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, + 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, + 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, + 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, + 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, + 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, + 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, + 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, + 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, + 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, + 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, + 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, + 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, + 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, + 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, + 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, 0x00, 0x00, 0x14, 0x00, + 0x00, 0x00, 0x26, 0x10, 0x06, 0x00, 0x12, 0xf9, 0x12, 0xc0, 0x3c, 0x0b, + 0xf1, 0x4f, 0xc4, 0x35, 0x51, 0x11, 0xf1, 0xdb, 0xc3, 0x0f, 0x44, 0x11, + 0x80, 0xf9, 0x15, 0x5e, 0xdc, 0xb6, 0x05, 0x34, 0x00, 0x12, 0xf9, 0x83, + 0x33, 0xf9, 0xd5, 0x5d, 0xdc, 0xb6, 0x0d, 0x6c, 0x00, 0x12, 0xf9, 0x12, + 0xc0, 0x3c, 0x0b, 0xf1, 0x4f, 0xc4, 0x35, 0x51, 0x11, 0xf1, 0xdb, 0x83, + 0x5f, 0xe1, 0xc5, 0x6d, 0x1b, 0x00, 0xc4, 0x76, 0xe5, 0x2f, 0xbb, 0xef, + 0x5f, 0x44, 0x80, 0xc1, 0x10, 0xcd, 0x04, 0x00, 0x00, 0x00, 0x61, 0x20, + 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, + 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xb4, 0x47, 0x00, 0x28, 0xcf, 0x31, + 0x14, 0x5d, 0x37, 0xd6, 0x00, 0x04, 0x02, 0xc9, 0x11, 0x00, 0x8a, 0x23, + 0x00, 0x04, 0x67, 0x00, 0x28, 0xd6, 0x00, 0x85, 0x39, 0x08, 0x31, 0x10, + 0x03, 0x31, 0x08, 0x83, 0x19, 0x00, 0x02, 0x63, 0x04, 0x20, 0x08, 0x82, + 0xf8, 0x37, 0x03, 0x30, 0x02, 0x00, 0x23, 0x06, 0xca, 0x10, 0x84, 0xc1, + 0xd3, 0x44, 0x46, 0x82, 0x04, 0x83, 0x0c, 0x41, 0xc1, 0x8c, 0x18, 0x2c, + 0x43, 0x40, 0x06, 0xd0, 0x33, 0x85, 0x01, 0xb2, 0x28, 0xc3, 0x18, 0x42, + 0x20, 0x06, 0x73, 0x0c, 0x43, 0x40, 0x06, 0x23, 0x06, 0xcb, 0x10, 0x9c, + 0xc1, 0x24, 0x59, 0x65, 0xb0, 0x38, 0x8d, 0x31, 0x86, 0x10, 0x94, 0xc1, + 0x1c, 0xc3, 0x10, 0x90, 0xc1, 0x61, 0x7a, 0x29, 0x28, 0x83, 0x0c, 0x81, + 0x43, 0x19, 0x11, 0xc0, 0x67, 0xbc, 0x81, 0xc3, 0xd8, 0xe0, 0x02, 0xbd, + 0x14, 0x94, 0x41, 0x86, 0x60, 0xca, 0x46, 0x0c, 0x0a, 0x21, 0x98, 0x83, + 0x22, 0x18, 0x6f, 0x08, 0x83, 0xce, 0x0d, 0x2e, 0xd0, 0x4b, 0x41, 0x19, + 0x64, 0x08, 0x30, 0x6f, 0xc4, 0xa0, 0x10, 0x02, 0x3c, 0x50, 0x82, 0xf1, + 0x06, 0x33, 0x10, 0x83, 0x37, 0xb8, 0x40, 0x2f, 0x05, 0x65, 0x90, 0x21, + 0xe8, 0xc6, 0x60, 0xc4, 0xa0, 0x10, 0x82, 0x3e, 0x78, 0x82, 0x39, 0x06, + 0x30, 0x58, 0xf4, 0x60, 0x8e, 0x21, 0x38, 0xf8, 0x60, 0x8e, 0x21, 0x18, + 0xf4, 0xc0, 0x02, 0x38, 0x90, 0x4f, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, + 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x5c, 0x0c, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x14, 0x03, + 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, + 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, + 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, + 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, 0x44, 0x24, 0x48, 0x0a, + 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, 0x21, 0x72, 0x24, 0x07, + 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, + 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x1b, 0xcc, + 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x60, 0x00, 0x09, 0xa8, 0x88, + 0x71, 0x78, 0x07, 0x79, 0x90, 0x87, 0x72, 0x18, 0x07, 0x7a, 0x60, 0x87, + 0x7c, 0x68, 0x03, 0x79, 0x78, 0x87, 0x7a, 0x70, 0x07, 0x72, 0x28, 0x07, + 0x72, 0x68, 0x03, 0x72, 0x48, 0x07, 0x7b, 0x48, 0x07, 0x72, 0x28, 0x87, + 0x36, 0x98, 0x87, 0x78, 0x90, 0x07, 0x7a, 0x68, 0x03, 0x73, 0x80, 0x87, + 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xcc, 0x21, 0x1c, 0xd8, + 0x61, 0x1e, 0xca, 0x01, 0x20, 0xc8, 0x21, 0x1d, 0xe6, 0x21, 0x1c, 0xc4, + 0x81, 0x1d, 0xca, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xd2, 0x81, 0x1d, 0xda, + 0x60, 0x1c, 0xc2, 0x81, 0x1d, 0xd8, 0x61, 0x1e, 0x00, 0x73, 0x08, 0x07, + 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x76, 0x28, 0x87, 0x79, 0x98, 0x87, + 0x36, 0x80, 0x07, 0x79, 0x28, 0x87, 0x71, 0x48, 0x87, 0x79, 0x28, 0x87, + 0x36, 0x30, 0x07, 0x78, 0x68, 0x87, 0x70, 0x20, 0x07, 0xc0, 0x1c, 0xc2, + 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xcc, + 0x41, 0x1e, 0xc2, 0xa1, 0x1d, 0xca, 0xa1, 0x0d, 0xe0, 0xe1, 0x1d, 0xd2, + 0xc1, 0x1d, 0xe8, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xca, 0x81, 0x1d, 0xd2, + 0xa1, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x60, 0x70, 0x87, + 0x77, 0x68, 0x03, 0x73, 0x90, 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, + 0x78, 0x78, 0x87, 0x74, 0x70, 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, + 0x72, 0x60, 0x87, 0x74, 0x68, 0x87, 0x36, 0x70, 0x87, 0x77, 0x70, 0x87, + 0x36, 0x60, 0x87, 0x72, 0x08, 0x07, 0x73, 0x00, 0x08, 0x77, 0x78, 0x87, + 0x36, 0x48, 0x07, 0x77, 0x30, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, + 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, + 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xd4, 0xa1, 0x1e, 0xda, + 0x01, 0x1e, 0xda, 0x80, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, 0xa1, 0x1c, 0xe6, + 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, + 0x77, 0x68, 0x03, 0x77, 0x08, 0x07, 0x77, 0x98, 0x87, 0x36, 0x30, 0x07, + 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, + 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x60, 0x1e, 0xd2, + 0xe1, 0x1c, 0xdc, 0xa1, 0x1c, 0xc8, 0xa1, 0x0d, 0xf4, 0xa1, 0x1c, 0xe4, + 0xe1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, + 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, + 0x77, 0x78, 0x87, 0x36, 0xa0, 0x07, 0x79, 0x08, 0x07, 0x78, 0x80, 0x87, + 0x74, 0x70, 0x87, 0x73, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, + 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xe6, 0x81, 0x1e, 0xc2, + 0x61, 0x1c, 0xd6, 0xa1, 0x0d, 0xe0, 0x41, 0x1e, 0xde, 0x81, 0x1e, 0xca, + 0x61, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, 0xa1, 0x0d, 0xc4, 0xa1, 0x1e, 0xcc, + 0xc1, 0x1c, 0xca, 0x41, 0x1e, 0xda, 0x60, 0x1e, 0xd2, 0x41, 0x1f, 0xca, + 0x01, 0xc0, 0x03, 0x80, 0xa8, 0x07, 0x77, 0x98, 0x87, 0x70, 0x30, 0x87, + 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, + 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xa2, 0x1e, 0xe6, + 0xa1, 0x1c, 0xda, 0x60, 0x1e, 0xde, 0xc1, 0x1c, 0xe8, 0xa1, 0x0d, 0xcc, + 0x81, 0x1d, 0xde, 0x21, 0x1c, 0xe8, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, + 0x79, 0x28, 0x07, 0x60, 0x03, 0x22, 0x10, 0x40, 0x02, 0x2c, 0x40, 0xb5, + 0xc1, 0x18, 0x0a, 0x60, 0x01, 0xaa, 0x0d, 0x06, 0x61, 0x00, 0x0b, 0x50, + 0x6d, 0x30, 0x8a, 0x03, 0x58, 0x80, 0x6a, 0x83, 0x61, 0xfc, 0xff, 0xff, + 0xff, 0xff, 0x00, 0x48, 0x00, 0xb5, 0x01, 0x39, 0xfe, 0xff, 0xff, 0xff, + 0x7f, 0x00, 0x18, 0x40, 0x02, 0xaa, 0x0d, 0x06, 0x12, 0x00, 0x0b, 0x50, + 0x6d, 0x30, 0x12, 0x01, 0x58, 0x80, 0x0a, 0x00, 0x00, 0x00, 0x49, 0x18, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x13, 0x8a, 0x40, 0x18, 0x88, 0x62, + 0x42, 0x60, 0x4c, 0x18, 0x0e, 0x24, 0x01, 0x00, 0x00, 0x00, 0x89, 0x20, + 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, + 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, + 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x68, + 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, 0x00, 0xc3, 0x08, 0x03, + 0x70, 0x90, 0x34, 0x45, 0x94, 0x30, 0xf9, 0xb2, 0xfb, 0x76, 0x84, 0xe0, + 0x0c, 0x04, 0x22, 0xc6, 0x18, 0x63, 0x10, 0x81, 0x10, 0x8e, 0x92, 0xa6, + 0x88, 0x12, 0x26, 0xff, 0x9f, 0x88, 0x6b, 0xa2, 0x22, 0xe2, 0xb7, 0x87, + 0x7f, 0x1a, 0x23, 0x00, 0x06, 0x11, 0x8c, 0xe0, 0x22, 0x69, 0x8a, 0x28, + 0x61, 0xf2, 0x7f, 0x09, 0x60, 0x9e, 0x85, 0x88, 0xfe, 0x69, 0x8c, 0x00, + 0x18, 0x44, 0x40, 0x84, 0x82, 0x84, 0x10, 0x44, 0x39, 0x27, 0x91, 0x2a, + 0x03, 0x18, 0x83, 0xd8, 0x1c, 0x41, 0x30, 0x47, 0x00, 0x06, 0xc3, 0x08, + 0xc2, 0x53, 0x90, 0x70, 0x92, 0x70, 0xd0, 0x01, 0x8a, 0x03, 0x01, 0x29, + 0xf0, 0x86, 0x11, 0x86, 0x67, 0x10, 0x21, 0x10, 0xe6, 0x08, 0x40, 0x61, + 0x10, 0x61, 0x10, 0x46, 0x00, 0x00, 0x13, 0xa8, 0x70, 0x48, 0x07, 0x79, + 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, + 0x68, 0x83, 0x74, 0x78, 0x87, 0x79, 0xc8, 0x03, 0x37, 0x80, 0x03, 0x37, + 0x80, 0x83, 0x0d, 0xb7, 0x51, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x60, 0x07, + 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, + 0xe9, 0x10, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, + 0x78, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x10, 0x07, + 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, + 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, + 0x72, 0xd0, 0x06, 0xe9, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, + 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x30, 0x07, 0x72, 0xa0, 0x07, + 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, + 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, + 0xf6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, + 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x73, 0x20, 0x07, + 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x30, 0x07, 0x72, 0xa0, 0x07, + 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x40, 0x07, + 0x78, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, + 0xf6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, + 0x74, 0xd0, 0x06, 0xf6, 0x90, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x20, 0x07, + 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, + 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, + 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x90, 0x07, 0x72, 0xa0, 0x07, + 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, + 0xf6, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, + 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x75, 0x10, 0x07, + 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, + 0x72, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, + 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, + 0x74, 0xd0, 0x06, 0xee, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, + 0x73, 0x20, 0x07, 0x43, 0x98, 0x05, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x21, 0x4c, 0x03, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0x10, 0x46, 0x02, 0x02, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x0b, 0x04, 0x0b, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x14, 0x19, 0x11, + 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x7a, 0x25, 0x30, + 0x02, 0x50, 0x20, 0x45, 0x50, 0x08, 0x05, 0x18, 0x50, 0x10, 0x65, 0x50, + 0x40, 0x05, 0x56, 0x0a, 0xc5, 0x40, 0x74, 0x2c, 0xc1, 0x21, 0x00, 0x00, + 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x1a, 0x03, + 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4, + 0x37, 0xb7, 0x21, 0xc6, 0x63, 0x4c, 0x00, 0xf5, 0x50, 0xb9, 0x1b, 0x43, + 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x1b, 0x62, 0x3c, 0xc3, 0x24, + 0x3c, 0x07, 0xe1, 0x20, 0x08, 0x0e, 0x8e, 0xad, 0x0c, 0x84, 0x89, 0xc9, + 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x0d, 0x64, 0x26, + 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, 0x06, 0x04, 0xa5, 0xad, 0x8c, 0x2e, + 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, + 0xc6, 0x25, 0x26, 0x65, 0x88, 0x30, 0x11, 0x43, 0x8c, 0x67, 0x78, 0x92, + 0x87, 0x60, 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, 0x04, 0x99, 0x8e, 0x67, + 0x78, 0x86, 0x87, 0xe0, 0x16, 0x96, 0x26, 0xe7, 0x32, 0xf6, 0xd6, 0x06, + 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, 0x26, 0xd7, 0x36, 0xf7, + 0x45, 0x96, 0x36, 0x17, 0x26, 0xc6, 0x56, 0x36, 0x44, 0x98, 0x12, 0x72, + 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, + 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, 0x65, 0x6e, + 0x61, 0x62, 0x6c, 0x65, 0x43, 0x84, 0x69, 0x21, 0x19, 0x84, 0xa5, 0xc9, + 0xb9, 0x8c, 0xbd, 0xb5, 0xc1, 0xa5, 0xb1, 0x95, 0xb9, 0x98, 0xc9, 0x85, + 0xb5, 0x95, 0x89, 0xd5, 0x99, 0x99, 0x95, 0xc9, 0x7d, 0x99, 0x95, 0xd1, + 0x8d, 0xa1, 0x7d, 0x95, 0xb9, 0x85, 0x89, 0xb1, 0x95, 0x0d, 0x11, 0xa6, + 0x86, 0x51, 0x58, 0x9a, 0x9c, 0x8b, 0x5c, 0x99, 0x1b, 0x59, 0x99, 0xdc, + 0x17, 0x5d, 0x98, 0xdc, 0x59, 0x19, 0x1d, 0xa3, 0xb0, 0x34, 0x39, 0x97, + 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0x2f, 0xb7, 0xb0, 0xb6, + 0x32, 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x43, 0x90, 0xe9, 0x79, + 0x88, 0x09, 0x9a, 0xa2, 0x21, 0xc2, 0x24, 0x91, 0x09, 0x4b, 0x93, 0x73, + 0x81, 0x7b, 0x9b, 0x4b, 0xa3, 0x4b, 0x7b, 0x73, 0xa3, 0x12, 0x96, 0x26, + 0xe7, 0x32, 0x56, 0xe6, 0x46, 0x57, 0x26, 0x47, 0x29, 0x2c, 0x4d, 0xce, + 0xc5, 0xed, 0xed, 0x0b, 0xae, 0x4c, 0x6e, 0x0e, 0xae, 0x6c, 0x8c, 0x2e, + 0xcd, 0xae, 0x8c, 0x4c, 0x58, 0x9a, 0x9c, 0x4b, 0x98, 0xdc, 0xd9, 0x97, + 0x5b, 0x58, 0x5b, 0x19, 0x11, 0xb8, 0xb7, 0xb9, 0x34, 0xba, 0xb4, 0x37, + 0xb7, 0x21, 0xd0, 0x43, 0x4c, 0xd4, 0x54, 0x4d, 0xd6, 0x04, 0x4d, 0xd1, + 0x74, 0x4d, 0x18, 0xa5, 0xb0, 0x34, 0x39, 0x17, 0x33, 0xb9, 0xb0, 0xb3, + 0xb6, 0x32, 0x37, 0xba, 0xaf, 0x34, 0x37, 0xb8, 0x3a, 0x3a, 0x5a, 0x67, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x35, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x44, 0x76, 0x34, 0x5f, 0x66, 0x29, 0x7c, 0xc2, 0xd2, + 0xe4, 0x5c, 0xe0, 0xca, 0xe4, 0xe6, 0xe0, 0xca, 0xc6, 0xe8, 0xd2, 0xec, + 0xca, 0x58, 0x8c, 0xbd, 0xb1, 0xbd, 0xc9, 0x0d, 0x91, 0x9e, 0x61, 0xd2, + 0xa6, 0x6d, 0xaa, 0x26, 0x6e, 0x82, 0xa6, 0x68, 0xba, 0xa6, 0x8e, 0xd9, + 0x59, 0x99, 0x5b, 0x99, 0x5c, 0x18, 0x5d, 0x19, 0x19, 0x0a, 0x0e, 0x5d, + 0x19, 0xde, 0xd8, 0xdb, 0x9b, 0x1c, 0x19, 0x91, 0x9d, 0xcc, 0x97, 0x59, + 0x0a, 0x0d, 0x33, 0xb6, 0xb7, 0x30, 0x3a, 0x19, 0x22, 0x74, 0x65, 0x78, + 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x43, 0xa4, 0xc7, 0x98, 0xb4, 0xe9, 0x9b, + 0xaa, 0x89, 0x9b, 0xa0, 0x09, 0x0c, 0xa6, 0x6b, 0x0a, 0x03, 0x2a, 0x61, + 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x7c, 0xc2, 0xd2, + 0xe4, 0x5c, 0xc4, 0xea, 0xcc, 0xcc, 0xca, 0xe4, 0xbe, 0xe6, 0xd2, 0xf4, + 0xca, 0x28, 0x85, 0xa5, 0xc9, 0xb9, 0xb0, 0xbd, 0x8d, 0x85, 0xd1, 0xa5, + 0xbd, 0xb9, 0x7d, 0xa5, 0xb9, 0x91, 0x95, 0xe1, 0x11, 0x09, 0x4b, 0x93, + 0x73, 0x91, 0x2b, 0x0b, 0x23, 0x23, 0x15, 0x96, 0x26, 0xe7, 0x32, 0x47, + 0x27, 0x57, 0x37, 0x46, 0xf7, 0x45, 0x97, 0x07, 0x57, 0xf6, 0x95, 0xe6, + 0x66, 0xf6, 0x46, 0xc3, 0x8c, 0xed, 0x2d, 0x8c, 0x6e, 0x86, 0xc6, 0x9b, + 0x99, 0xd9, 0x5c, 0x19, 0x1d, 0x0d, 0xa9, 0xb1, 0xb7, 0x32, 0x33, 0x33, + 0x1a, 0x47, 0x63, 0x6f, 0x65, 0x66, 0x66, 0x34, 0x84, 0xc6, 0xde, 0xca, + 0xcc, 0xcc, 0x86, 0xa0, 0xc1, 0x43, 0x3c, 0xc5, 0x43, 0x4c, 0x68, 0x30, + 0xa5, 0xc1, 0x53, 0x3c, 0xc5, 0x43, 0x4c, 0x68, 0x30, 0xa9, 0xc1, 0xb3, + 0x3c, 0xc5, 0x43, 0x4c, 0x68, 0x30, 0xad, 0xc1, 0xc3, 0x3c, 0xc5, 0x43, + 0x4c, 0x68, 0x30, 0xb1, 0x01, 0xa3, 0xb0, 0x34, 0x39, 0x97, 0x30, 0xb9, + 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0xaf, 0xb9, 0x34, 0xbd, 0x32, 0x5e, + 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x4c, + 0xb2, 0xaa, 0xac, 0x88, 0xca, 0xc6, 0xde, 0xc8, 0xca, 0x68, 0x90, 0x95, + 0x8d, 0xbd, 0x91, 0x95, 0x0d, 0x21, 0x83, 0x47, 0x99, 0xc6, 0x60, 0x22, + 0x83, 0x07, 0x99, 0xca, 0xe0, 0x19, 0x9e, 0x61, 0x32, 0x83, 0xe9, 0x0c, + 0xa6, 0x36, 0x98, 0xdc, 0xe0, 0x41, 0xa6, 0x37, 0x78, 0x8a, 0x09, 0x9a, + 0xe0, 0x60, 0xba, 0xa6, 0x38, 0xe0, 0x12, 0x96, 0x26, 0xe7, 0x42, 0x57, + 0x86, 0x47, 0x57, 0x27, 0x57, 0x46, 0x25, 0x2c, 0x4d, 0xce, 0x65, 0x2e, + 0xac, 0x0d, 0x8e, 0xad, 0x8c, 0x18, 0x5d, 0x19, 0x1e, 0x5d, 0x9d, 0x5c, + 0x99, 0x0c, 0x19, 0x8f, 0x19, 0xdb, 0x5b, 0x18, 0x1d, 0x0b, 0xc8, 0x5c, + 0x58, 0x1b, 0x1c, 0x5b, 0x99, 0x0f, 0x09, 0xba, 0x32, 0xbc, 0xac, 0x21, + 0xd4, 0x73, 0x4c, 0x73, 0x30, 0x95, 0xc1, 0x43, 0x3c, 0xc3, 0x44, 0x07, + 0x13, 0x34, 0xd5, 0xc1, 0x74, 0x4d, 0x76, 0xc0, 0x82, 0xae, 0x0c, 0xaf, + 0xca, 0x6a, 0x08, 0xf5, 0x34, 0xd3, 0x1c, 0x4c, 0x65, 0xf0, 0x0c, 0xcf, + 0x30, 0xd1, 0xc1, 0x04, 0x4d, 0x75, 0x30, 0x5d, 0x13, 0x1e, 0x70, 0x09, + 0x4b, 0x93, 0x73, 0x99, 0x0b, 0x6b, 0x83, 0x63, 0x2b, 0x93, 0xe3, 0x31, + 0x17, 0xd6, 0x06, 0xc7, 0x56, 0x26, 0xc7, 0x60, 0x6e, 0x88, 0xf4, 0x38, + 0x93, 0x1e, 0x4c, 0x65, 0xf0, 0x10, 0xcf, 0x30, 0x41, 0xd3, 0x1e, 0x4c, + 0xd7, 0xc4, 0x07, 0x43, 0x9c, 0x29, 0x9b, 0xbc, 0x49, 0x0c, 0x26, 0x39, + 0x98, 0xee, 0x60, 0xca, 0x83, 0xa9, 0x0f, 0x86, 0x18, 0x0b, 0x30, 0x4d, + 0x93, 0x1f, 0x8c, 0x88, 0xd8, 0x81, 0x1d, 0xec, 0xa1, 0x1d, 0xdc, 0xa0, + 0x1d, 0xde, 0x81, 0x1c, 0xea, 0x81, 0x1d, 0xca, 0xc1, 0x0d, 0xcc, 0x81, + 0x1d, 0xc2, 0xe1, 0x1c, 0xe6, 0x61, 0x8a, 0x10, 0x0c, 0x23, 0x14, 0x76, + 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x48, 0x07, 0x72, 0x28, 0x07, 0x77, + 0xa0, 0x87, 0x29, 0x41, 0x31, 0x62, 0x09, 0x87, 0x74, 0x90, 0x07, 0x37, + 0xb0, 0x87, 0x72, 0x90, 0x87, 0x79, 0x48, 0x87, 0x77, 0x70, 0x87, 0x29, + 0x81, 0x31, 0x82, 0x0a, 0x87, 0x74, 0x90, 0x07, 0x37, 0x60, 0x87, 0x70, + 0x70, 0x87, 0x73, 0xa8, 0x87, 0x70, 0x38, 0x87, 0x72, 0xf8, 0x05, 0x7b, + 0x28, 0x07, 0x79, 0x98, 0x87, 0x74, 0x78, 0x07, 0x77, 0x98, 0x12, 0x20, + 0x23, 0xa6, 0x70, 0x48, 0x07, 0x79, 0x70, 0x83, 0x71, 0x78, 0x87, 0x76, + 0x80, 0x87, 0x74, 0x60, 0x87, 0x72, 0xf8, 0x85, 0x77, 0x80, 0x07, 0x7a, + 0x48, 0x87, 0x77, 0x70, 0x87, 0x79, 0x98, 0x32, 0x28, 0x8c, 0x33, 0x82, + 0x09, 0x87, 0x74, 0x90, 0x07, 0x37, 0x30, 0x07, 0x79, 0x08, 0x87, 0x73, + 0x68, 0x87, 0x72, 0x70, 0x07, 0x7a, 0x98, 0x12, 0xfc, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, + 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, + 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, + 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, + 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, + 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, + 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, + 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, + 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, + 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, + 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, + 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, + 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, + 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, + 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, + 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, + 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, + 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, + 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, + 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, + 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, + 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, + 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, + 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, + 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, + 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, + 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, + 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, + 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, + 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, + 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, + 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, + 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, + 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, + 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, + 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, + 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, + 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, + 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, + 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, + 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, + 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, + 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x16, 0xd0, 0x00, 0x48, 0xe4, 0x0f, + 0xce, 0xe4, 0x57, 0x77, 0x71, 0xdb, 0x26, 0xb0, 0x01, 0x48, 0xe4, 0x4b, + 0x00, 0xf3, 0x2c, 0xc4, 0x3f, 0x11, 0xd7, 0x44, 0x45, 0xc4, 0x6f, 0x0f, + 0x7e, 0x85, 0x17, 0xb7, 0x6d, 0x00, 0x11, 0xdb, 0x95, 0xff, 0xf9, 0xd6, + 0xf6, 0x5f, 0x44, 0x80, 0xc1, 0x10, 0xcd, 0x04, 0x00, 0x00, 0x61, 0x20, + 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, + 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x74, 0x47, 0x00, 0xa8, 0x8e, 0x35, + 0x00, 0x03, 0x31, 0xc7, 0x40, 0x0c, 0xde, 0x1c, 0x03, 0xe1, 0x79, 0x63, + 0x0d, 0x40, 0x20, 0x90, 0xab, 0x81, 0x11, 0x00, 0x7a, 0x33, 0x00, 0x04, + 0x47, 0x00, 0x28, 0xcc, 0x41, 0x90, 0x01, 0x19, 0x90, 0x81, 0x18, 0xcc, + 0x00, 0x10, 0x18, 0x23, 0x00, 0x41, 0x10, 0xc4, 0xbf, 0x11, 0x80, 0x19, + 0x00, 0x00, 0x23, 0x06, 0xca, 0x10, 0x8c, 0x41, 0xf4, 0x4c, 0x89, 0x81, + 0x08, 0x83, 0x0c, 0x41, 0xc1, 0x8c, 0x18, 0x28, 0x43, 0x50, 0x06, 0x52, + 0x54, 0x2d, 0x88, 0x42, 0x0c, 0x32, 0x04, 0xc7, 0x33, 0xc8, 0x30, 0x04, + 0xd1, 0x5d, 0x76, 0x29, 0x28, 0x83, 0x0c, 0xc1, 0x12, 0x19, 0x11, 0xc0, + 0x67, 0xbc, 0x61, 0xbb, 0xd6, 0xe0, 0x02, 0xbb, 0x14, 0x94, 0x41, 0x86, + 0x00, 0xb2, 0x46, 0x0c, 0x0a, 0x21, 0x88, 0x83, 0x22, 0x18, 0x6f, 0x00, + 0x03, 0xae, 0x0d, 0x2e, 0xb0, 0x4b, 0x41, 0x19, 0x64, 0x08, 0xaa, 0x6d, + 0xc4, 0xa0, 0x10, 0x02, 0x3b, 0x50, 0x82, 0xf1, 0x86, 0x32, 0x08, 0x03, + 0x37, 0xb8, 0xc0, 0x2e, 0x05, 0x65, 0x90, 0x21, 0xd0, 0xc0, 0x60, 0xc4, + 0xa0, 0x10, 0x82, 0x3d, 0x78, 0x82, 0x39, 0x86, 0x6e, 0xc9, 0x83, 0x39, + 0x86, 0xe0, 0xd8, 0x83, 0x39, 0x86, 0x60, 0xc8, 0x03, 0x0b, 0xde, 0x40, + 0x3e, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, + 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x68, 0x0c, + 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, + 0x00, 0x00, 0x17, 0x03, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, + 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, + 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, + 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, + 0x44, 0x24, 0x48, 0x0a, 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, + 0x21, 0x72, 0x24, 0x07, 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, + 0xc6, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x90, 0x00, + 0x00, 0x00, 0x1b, 0xcc, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x60, + 0x00, 0x09, 0xa8, 0x88, 0x71, 0x78, 0x07, 0x79, 0x90, 0x87, 0x72, 0x18, + 0x07, 0x7a, 0x60, 0x87, 0x7c, 0x68, 0x03, 0x79, 0x78, 0x87, 0x7a, 0x70, + 0x07, 0x72, 0x28, 0x07, 0x72, 0x68, 0x03, 0x72, 0x48, 0x07, 0x7b, 0x48, + 0x07, 0x72, 0x28, 0x87, 0x36, 0x98, 0x87, 0x78, 0x90, 0x07, 0x7a, 0x68, + 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, + 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xc8, 0x21, 0x1d, + 0xe6, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, + 0xd2, 0x81, 0x1d, 0xda, 0x60, 0x1c, 0xc2, 0x81, 0x1d, 0xd8, 0x61, 0x1e, + 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x76, 0x28, + 0x87, 0x79, 0x98, 0x87, 0x36, 0x80, 0x07, 0x79, 0x28, 0x87, 0x71, 0x48, + 0x87, 0x79, 0x28, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x87, 0x70, 0x20, + 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, + 0xde, 0xa1, 0x0d, 0xcc, 0x41, 0x1e, 0xc2, 0xa1, 0x1d, 0xca, 0xa1, 0x0d, + 0xe0, 0xe1, 0x1d, 0xd2, 0xc1, 0x1d, 0xe8, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, + 0xca, 0x81, 0x1d, 0xd2, 0xa1, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, + 0x07, 0x60, 0x70, 0x87, 0x77, 0x68, 0x03, 0x73, 0x90, 0x87, 0x70, 0x68, + 0x87, 0x72, 0x68, 0x03, 0x78, 0x78, 0x87, 0x74, 0x70, 0x07, 0x7a, 0x28, + 0x07, 0x79, 0x68, 0x83, 0x72, 0x60, 0x87, 0x74, 0x68, 0x87, 0x36, 0x70, + 0x87, 0x77, 0x70, 0x87, 0x36, 0x60, 0x87, 0x72, 0x08, 0x07, 0x73, 0x00, + 0x08, 0x77, 0x78, 0x87, 0x36, 0x48, 0x07, 0x77, 0x30, 0x87, 0x79, 0x68, + 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, + 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, + 0xd4, 0xa1, 0x1e, 0xda, 0x01, 0x1e, 0xda, 0x80, 0x1e, 0xc2, 0x41, 0x1c, + 0xd8, 0xa1, 0x1c, 0xe6, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, + 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x77, 0x08, 0x07, 0x77, 0x98, + 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, + 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, + 0xda, 0x60, 0x1e, 0xd2, 0xe1, 0x1c, 0xdc, 0xa1, 0x1c, 0xc8, 0xa1, 0x0d, + 0xf4, 0xa1, 0x1c, 0xe4, 0xe1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, + 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, + 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0xa0, 0x07, 0x79, 0x08, + 0x07, 0x78, 0x80, 0x87, 0x74, 0x70, 0x87, 0x73, 0x68, 0x83, 0x76, 0x08, + 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, + 0xe6, 0x81, 0x1e, 0xc2, 0x61, 0x1c, 0xd6, 0xa1, 0x0d, 0xe0, 0x41, 0x1e, + 0xde, 0x81, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, 0xa1, 0x0d, + 0xc4, 0xa1, 0x1e, 0xcc, 0xc1, 0x1c, 0xca, 0x41, 0x1e, 0xda, 0x60, 0x1e, + 0xd2, 0x41, 0x1f, 0xca, 0x01, 0xc0, 0x03, 0x80, 0xa8, 0x07, 0x77, 0x98, + 0x87, 0x70, 0x30, 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, + 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, + 0x00, 0xa2, 0x1e, 0xe6, 0xa1, 0x1c, 0xda, 0x60, 0x1e, 0xde, 0xc1, 0x1c, + 0xe8, 0xa1, 0x0d, 0xcc, 0x81, 0x1d, 0xde, 0x21, 0x1c, 0xe8, 0x01, 0x30, + 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x60, 0x03, 0x22, 0x10, 0x40, + 0x02, 0x2c, 0x40, 0xb5, 0xc1, 0x18, 0x0a, 0x60, 0x01, 0xaa, 0x0d, 0x06, + 0x61, 0x00, 0x0b, 0x50, 0x6d, 0x30, 0x8a, 0x03, 0x58, 0x80, 0x6a, 0x83, + 0x61, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x00, 0x48, 0x00, 0xb5, 0x01, 0x39, + 0xfe, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x18, 0x40, 0x02, 0xaa, 0x0d, 0x06, + 0x12, 0x00, 0x0b, 0x50, 0x6d, 0x30, 0x12, 0x01, 0x58, 0x80, 0x0a, 0x00, + 0x00, 0x00, 0x49, 0x18, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x13, 0x8a, + 0x40, 0x18, 0x88, 0x62, 0x42, 0x60, 0x4c, 0x18, 0x0e, 0x24, 0x01, 0x00, + 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x32, 0x22, + 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, + 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, + 0xa4, 0x4c, 0x10, 0x68, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, + 0x00, 0xc3, 0x08, 0x03, 0x70, 0x90, 0x34, 0x45, 0x94, 0x30, 0xf9, 0xb2, + 0xfb, 0x76, 0x84, 0xe0, 0x0c, 0x04, 0x22, 0xc6, 0x18, 0x63, 0x10, 0x81, + 0x10, 0x8e, 0x92, 0xa6, 0x88, 0x12, 0x26, 0xff, 0x9f, 0x88, 0x6b, 0xa2, + 0x22, 0xe2, 0xb7, 0x87, 0x7f, 0x1a, 0x23, 0x00, 0x06, 0x11, 0x8c, 0xe0, + 0x22, 0x69, 0x8a, 0x28, 0x61, 0xf2, 0x7f, 0x09, 0x60, 0x9e, 0x85, 0x88, + 0xfe, 0x69, 0x8c, 0x00, 0x18, 0x44, 0x40, 0x84, 0x82, 0x84, 0x10, 0x44, + 0x39, 0x27, 0x91, 0x2a, 0x03, 0x18, 0x83, 0xd8, 0x1c, 0x41, 0x30, 0x47, + 0x00, 0x06, 0xc3, 0x08, 0xc2, 0x53, 0x90, 0x70, 0x92, 0x70, 0xd0, 0x01, + 0x8a, 0x03, 0x01, 0x29, 0xf0, 0x86, 0x11, 0x86, 0x67, 0x10, 0x21, 0x10, + 0xe6, 0x08, 0x40, 0x61, 0x10, 0x61, 0x10, 0x46, 0x00, 0x00, 0x13, 0xa8, + 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, + 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, 0x87, 0x79, 0xc8, 0x03, + 0x37, 0x80, 0x03, 0x37, 0x80, 0x83, 0x0d, 0xb7, 0x51, 0x0e, 0x6d, 0x00, + 0x0f, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, + 0x07, 0x74, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, + 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, + 0x06, 0xe9, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x10, + 0x07, 0x76, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, + 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x60, 0x07, 0x74, 0xa0, + 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, + 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, + 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, + 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x74, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, + 0x06, 0xf6, 0x40, 0x07, 0x78, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, + 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x90, 0x07, 0x76, 0xa0, + 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, + 0x06, 0xf6, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, + 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x90, + 0x07, 0x72, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, + 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, + 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, + 0x0f, 0x75, 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, 0x72, 0xa0, + 0x07, 0x75, 0x10, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x70, 0x20, + 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, + 0x07, 0x70, 0x20, 0x07, 0x74, 0xd0, 0x06, 0xee, 0x80, 0x07, 0x7a, 0x10, + 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x43, 0x98, 0x05, 0x00, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x21, 0x4c, 0x03, 0x04, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0x10, 0x46, 0x02, 0x02, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x20, 0x0b, 0x04, 0x0b, 0x00, 0x00, 0x00, 0x32, 0x1e, + 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, + 0x43, 0x7a, 0x25, 0x30, 0x02, 0x50, 0x20, 0x45, 0x50, 0x08, 0x05, 0x18, + 0x50, 0x10, 0x65, 0x50, 0x40, 0x05, 0x56, 0x0a, 0xc5, 0x40, 0x74, 0x2c, + 0xc1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x0c, 0x01, + 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, 0x10, 0xab, + 0x32, 0xb9, 0xb9, 0xb4, 0x37, 0xb7, 0x21, 0xc6, 0x63, 0x4c, 0x00, 0xf5, + 0x50, 0xb9, 0x1b, 0x43, 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x1b, + 0x62, 0x3c, 0xc3, 0x24, 0x3c, 0x07, 0xe1, 0x20, 0x08, 0x0e, 0x8e, 0xad, + 0x0c, 0x84, 0x89, 0xc9, 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, 0x2e, 0xed, + 0xcd, 0x0d, 0x64, 0x26, 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, 0x06, 0x04, + 0xa5, 0xad, 0x8c, 0x2e, 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, 0x06, 0x06, + 0x26, 0xc6, 0xa5, 0x06, 0xc6, 0x25, 0x26, 0x65, 0x88, 0x30, 0x11, 0x43, + 0x8c, 0x67, 0x78, 0x92, 0x87, 0x60, 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, + 0x04, 0x99, 0x8e, 0x67, 0x78, 0x86, 0x87, 0xe0, 0x16, 0x96, 0x26, 0xe7, + 0x32, 0xf6, 0xd6, 0x06, 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, + 0x26, 0xd7, 0x36, 0xf7, 0x45, 0x96, 0x36, 0x17, 0x26, 0xc6, 0x56, 0x36, + 0x44, 0x98, 0x12, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, + 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, + 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x84, 0x69, 0x21, + 0x19, 0x84, 0xa5, 0xc9, 0xb9, 0x8c, 0xbd, 0xb5, 0xc1, 0xa5, 0xb1, 0x95, + 0xb9, 0x98, 0xc9, 0x85, 0xb5, 0x95, 0x89, 0xd5, 0x99, 0x99, 0x95, 0xc9, + 0x7d, 0x99, 0x95, 0xd1, 0x8d, 0xa1, 0x7d, 0x95, 0xb9, 0x85, 0x89, 0xb1, + 0x95, 0x0d, 0x11, 0xa6, 0x86, 0x51, 0x58, 0x9a, 0x9c, 0x8b, 0x5c, 0x99, + 0x1b, 0x59, 0x99, 0xdc, 0x17, 0x5d, 0x98, 0xdc, 0x59, 0x19, 0x1d, 0xa3, + 0xb0, 0x34, 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, + 0x2f, 0xb7, 0xb0, 0xb6, 0x32, 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, + 0x43, 0x90, 0xe9, 0x79, 0x88, 0x09, 0x9a, 0xa2, 0x21, 0xc2, 0x24, 0x91, + 0x09, 0x4b, 0x93, 0x73, 0x81, 0x7b, 0x9b, 0x4b, 0xa3, 0x4b, 0x7b, 0x73, + 0xa3, 0x12, 0x96, 0x26, 0xe7, 0x32, 0x56, 0xe6, 0x46, 0x57, 0x26, 0x47, + 0x29, 0x2c, 0x4d, 0xce, 0xc5, 0xed, 0xed, 0x0b, 0xae, 0x4c, 0x6e, 0x0e, + 0xae, 0x6c, 0x8c, 0x2e, 0xcd, 0xae, 0x8c, 0x4c, 0x58, 0x9a, 0x9c, 0x4b, + 0x98, 0xdc, 0xd9, 0x97, 0x5b, 0x58, 0x5b, 0x19, 0x11, 0xb8, 0xb7, 0xb9, + 0x34, 0xba, 0xb4, 0x37, 0xb7, 0x21, 0xd0, 0x43, 0x4c, 0xd4, 0x54, 0x4d, + 0xd6, 0x04, 0x4d, 0xd1, 0x74, 0x4d, 0x18, 0xa5, 0xb0, 0x34, 0x39, 0x17, + 0x33, 0xb9, 0xb0, 0xb3, 0xb6, 0x32, 0x37, 0xba, 0xaf, 0x34, 0x37, 0xb8, + 0x3a, 0x3a, 0x5a, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, + 0x28, 0x35, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x44, 0x76, 0x34, 0x5f, 0x66, + 0x29, 0x7c, 0xc2, 0xd2, 0xe4, 0x5c, 0xe0, 0xca, 0xe4, 0xe6, 0xe0, 0xca, + 0xc6, 0xe8, 0xd2, 0xec, 0xca, 0x58, 0x8c, 0xbd, 0xb1, 0xbd, 0xc9, 0x0d, + 0x91, 0x9e, 0x61, 0xd2, 0xa6, 0x6d, 0xaa, 0x26, 0x6e, 0x82, 0xa6, 0x68, + 0xba, 0xa6, 0x8e, 0xd9, 0x59, 0x99, 0x5b, 0x99, 0x5c, 0x18, 0x5d, 0x19, + 0x19, 0x0a, 0x0e, 0x5d, 0x19, 0xde, 0xd8, 0xdb, 0x9b, 0x1c, 0x19, 0x91, + 0x9d, 0xcc, 0x97, 0x59, 0x0a, 0x0d, 0x33, 0xb6, 0xb7, 0x30, 0x3a, 0x19, + 0x22, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x43, 0xa4, 0xc7, + 0x98, 0xb4, 0xe9, 0x9b, 0xaa, 0x89, 0x9b, 0xa0, 0x09, 0x0c, 0xa6, 0x6b, + 0x0a, 0x03, 0x2a, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, + 0x72, 0x7c, 0xc2, 0xd2, 0xe4, 0x5c, 0xc4, 0xea, 0xcc, 0xcc, 0xca, 0xe4, + 0xbe, 0xe6, 0xd2, 0xf4, 0xca, 0x28, 0x85, 0xa5, 0xc9, 0xb9, 0xb0, 0xbd, + 0x8d, 0x85, 0xd1, 0xa5, 0xbd, 0xb9, 0x7d, 0xa5, 0xb9, 0x91, 0x95, 0xe1, + 0x11, 0x09, 0x4b, 0x93, 0x73, 0x91, 0x2b, 0x0b, 0x23, 0x23, 0x15, 0x96, + 0x26, 0xe7, 0x32, 0x47, 0x27, 0x57, 0x37, 0x46, 0xf7, 0x45, 0x97, 0x07, + 0x57, 0xf6, 0x95, 0xe6, 0x66, 0xf6, 0x46, 0xc3, 0x8c, 0xed, 0x2d, 0x8c, + 0x6e, 0x86, 0xc6, 0x9b, 0x99, 0xd9, 0x5c, 0x19, 0x1d, 0x0d, 0xa9, 0xb1, + 0xb7, 0x32, 0x33, 0x33, 0x1a, 0x47, 0x63, 0x6f, 0x65, 0x66, 0x66, 0x34, + 0x84, 0xc6, 0xde, 0xca, 0xcc, 0xcc, 0x86, 0xa0, 0xc1, 0x43, 0x3c, 0xc5, + 0x43, 0x4c, 0x68, 0x30, 0xa5, 0xc1, 0x53, 0x3c, 0xc5, 0x43, 0x4c, 0x68, + 0x30, 0xa9, 0xc1, 0xb3, 0x3c, 0xc5, 0x43, 0x4c, 0x68, 0x30, 0xad, 0xc1, + 0xc3, 0x3c, 0xc5, 0x43, 0x4c, 0x68, 0x30, 0xb1, 0x01, 0xa3, 0xb0, 0x34, + 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0xaf, 0xb9, + 0x34, 0xbd, 0x32, 0x5e, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x5f, 0x73, + 0x69, 0x7a, 0x65, 0x4c, 0xb2, 0xaa, 0xac, 0x88, 0xca, 0xc6, 0xde, 0xc8, + 0xca, 0x68, 0x90, 0x95, 0x8d, 0xbd, 0x91, 0x95, 0x0d, 0x21, 0x83, 0x47, + 0x99, 0xc6, 0x60, 0x22, 0x83, 0x07, 0x99, 0xca, 0xe0, 0x19, 0x9e, 0x61, + 0x32, 0x83, 0xe9, 0x0c, 0xa6, 0x36, 0x98, 0xdc, 0xe0, 0x41, 0xa6, 0x37, + 0x78, 0x8a, 0x09, 0x9a, 0xe0, 0x60, 0xba, 0xa6, 0x38, 0xe0, 0x12, 0x96, + 0x26, 0xe7, 0x42, 0x57, 0x86, 0x47, 0x57, 0x27, 0x57, 0x46, 0x25, 0x2c, + 0x4d, 0xce, 0x65, 0x2e, 0xac, 0x0d, 0x8e, 0xad, 0x8c, 0x18, 0x5d, 0x19, + 0x1e, 0x5d, 0x9d, 0x5c, 0x99, 0x0c, 0x19, 0x8f, 0x19, 0xdb, 0x5b, 0x18, + 0x1d, 0x0b, 0xc8, 0x5c, 0x58, 0x1b, 0x1c, 0x5b, 0x99, 0x0f, 0x09, 0xba, + 0x32, 0xbc, 0xac, 0x21, 0xd4, 0x73, 0x4c, 0x73, 0x30, 0x95, 0xc1, 0x43, + 0x3c, 0xc3, 0x44, 0x07, 0x13, 0x34, 0xd5, 0xc1, 0x74, 0x4d, 0x76, 0xc0, + 0x82, 0xae, 0x0c, 0xaf, 0xca, 0x6a, 0x08, 0xf5, 0x34, 0xd3, 0x1c, 0x4c, + 0x65, 0xf0, 0x0c, 0xcf, 0x30, 0xd1, 0xc1, 0x04, 0x4d, 0x75, 0x30, 0x5d, + 0x13, 0x1e, 0x70, 0x09, 0x4b, 0x93, 0x73, 0x99, 0x0b, 0x6b, 0x83, 0x63, + 0x2b, 0x93, 0xe3, 0x31, 0x17, 0xd6, 0x06, 0xc7, 0x56, 0x26, 0xc7, 0x60, + 0x6e, 0x88, 0xf4, 0x38, 0x93, 0x1e, 0x4c, 0x65, 0xf0, 0x10, 0xcf, 0x30, + 0x41, 0xd3, 0x1e, 0x4c, 0xd7, 0xc4, 0x07, 0x43, 0x9c, 0x29, 0x9b, 0xbc, + 0x49, 0x0c, 0x26, 0x39, 0x98, 0xee, 0x60, 0xca, 0x83, 0xa9, 0x0f, 0x86, + 0x18, 0x0b, 0x30, 0x4d, 0x93, 0x1f, 0x8c, 0x88, 0xd8, 0x81, 0x1d, 0xec, + 0xa1, 0x1d, 0xdc, 0xa0, 0x1d, 0xde, 0x81, 0x1c, 0xea, 0x81, 0x1d, 0xca, + 0xc1, 0x0d, 0xcc, 0x81, 0x1d, 0xc2, 0xe1, 0x1c, 0xe6, 0x61, 0x8a, 0x10, + 0x0c, 0x23, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x48, 0x07, + 0x72, 0x28, 0x07, 0x77, 0xa0, 0x87, 0x29, 0x41, 0x31, 0x62, 0x09, 0x87, + 0x74, 0x90, 0x07, 0x37, 0xb0, 0x87, 0x72, 0x90, 0x87, 0x79, 0x48, 0x87, + 0x77, 0x70, 0x87, 0x29, 0x81, 0x31, 0x82, 0x0a, 0x87, 0x74, 0x90, 0x07, + 0x37, 0x60, 0x87, 0x70, 0x70, 0x87, 0x73, 0xa8, 0x87, 0x70, 0x38, 0x87, + 0x72, 0xf8, 0x05, 0x7b, 0x28, 0x07, 0x79, 0x98, 0x87, 0x74, 0x78, 0x07, + 0x77, 0x98, 0x12, 0x20, 0x23, 0xa6, 0x70, 0x48, 0x07, 0x79, 0x70, 0x83, + 0x71, 0x78, 0x87, 0x76, 0x80, 0x87, 0x74, 0x60, 0x87, 0x72, 0xf8, 0x85, + 0x77, 0x80, 0x07, 0x7a, 0x48, 0x87, 0x77, 0x70, 0x87, 0x79, 0x98, 0x32, + 0x28, 0x8c, 0x33, 0x82, 0x09, 0x87, 0x74, 0x90, 0x07, 0x37, 0x30, 0x07, + 0x79, 0x08, 0x87, 0x73, 0x68, 0x87, 0x72, 0x70, 0x07, 0x7a, 0x98, 0x12, + 0xfc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x7b, 0x00, + 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, + 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, + 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, + 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, + 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, + 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, + 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, + 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, + 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, + 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, + 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, + 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, + 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, + 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, + 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, + 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, + 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, + 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, + 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, + 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, + 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, + 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, + 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, + 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, + 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, + 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, + 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, + 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, + 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, + 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, + 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, + 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, + 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, + 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, + 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, + 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, + 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, + 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, + 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, + 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, + 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, + 0x3c, 0x00, 0x71, 0x20, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x16, 0xd0, + 0x00, 0x48, 0xe4, 0x0f, 0xce, 0xe4, 0x57, 0x77, 0x71, 0xdb, 0x26, 0xb0, + 0x01, 0x48, 0xe4, 0x4b, 0x00, 0xf3, 0x2c, 0xc4, 0x3f, 0x11, 0xd7, 0x44, + 0x45, 0xc4, 0x6f, 0x0f, 0x7e, 0x85, 0x17, 0xb7, 0x6d, 0x00, 0x11, 0xdb, + 0x95, 0xff, 0xf9, 0xda, 0xf5, 0x5f, 0x44, 0x80, 0xc1, 0x10, 0xcd, 0x04, + 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x13, 0x04, + 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x74, 0x47, + 0x00, 0xa8, 0x8e, 0x35, 0x00, 0x03, 0x31, 0xc7, 0x40, 0x0c, 0xdf, 0x1c, + 0x03, 0xf1, 0x7d, 0x63, 0x0d, 0x40, 0x20, 0x10, 0x1c, 0x4b, 0x08, 0x00, + 0x72, 0x35, 0x30, 0x02, 0x40, 0x6f, 0x06, 0x80, 0xe0, 0x08, 0x00, 0x89, + 0x19, 0x00, 0x0a, 0x73, 0x10, 0x66, 0x60, 0x06, 0x66, 0x40, 0x06, 0x33, + 0x00, 0x04, 0xc6, 0x08, 0x40, 0x10, 0x04, 0xf1, 0x6f, 0x04, 0x60, 0x06, + 0x00, 0x00, 0x23, 0x06, 0xca, 0x10, 0x94, 0xc1, 0x14, 0x55, 0xca, 0x91, + 0x08, 0x83, 0x0c, 0x41, 0xe1, 0x8c, 0x18, 0x28, 0x43, 0x70, 0x06, 0xd4, + 0x74, 0x31, 0xc9, 0x42, 0x0c, 0x32, 0x04, 0x87, 0x33, 0xc8, 0x10, 0x28, + 0xd2, 0x20, 0x03, 0x11, 0x50, 0xa7, 0xd9, 0xa5, 0xa0, 0x0c, 0x32, 0x04, + 0x0c, 0x65, 0x44, 0x00, 0x9f, 0xf1, 0x06, 0x4f, 0x73, 0x83, 0x0b, 0xec, + 0x52, 0x50, 0x06, 0x19, 0x82, 0x28, 0x1b, 0x31, 0x28, 0x84, 0x80, 0x0e, + 0x8a, 0x60, 0xbc, 0x61, 0x0c, 0x3e, 0x38, 0xb8, 0xc0, 0x2e, 0x05, 0x65, + 0x90, 0x21, 0xb0, 0xbc, 0x11, 0x83, 0x42, 0x08, 0xf2, 0x40, 0x09, 0xc6, + 0x1b, 0xd0, 0x80, 0x0c, 0xe2, 0xe0, 0x02, 0xbb, 0x14, 0x94, 0x41, 0x86, + 0x60, 0x1b, 0x83, 0x11, 0x83, 0x42, 0x08, 0xfc, 0xe0, 0x09, 0xe6, 0x18, + 0xbc, 0x85, 0x0f, 0xe6, 0x18, 0x82, 0xc3, 0x0f, 0xe6, 0x18, 0x82, 0x81, + 0x0f, 0x2c, 0x90, 0x03, 0xf9, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; +const unsigned int sdl_metallib_len = 21810; diff --git a/SDL2-2.30.5/src/render/metal/SDL_shaders_metal_iphonesimulator.h b/SDL2-2.30.5/src/render/metal/SDL_shaders_metal_iphonesimulator.h new file mode 100644 index 0000000..afa2f9d --- /dev/null +++ b/SDL2-2.30.5/src/render/metal/SDL_shaders_metal_iphonesimulator.h @@ -0,0 +1,2058 @@ +const unsigned char sdl_metallib[] = { + 0x4d, 0x54, 0x4c, 0x42, 0x01, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xae, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0e, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xd4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x5b, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, + 0x4e, 0x41, 0x4d, 0x45, 0x11, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x53, 0x6f, + 0x6c, 0x69, 0x64, 0x5f, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x00, 0x54, + 0x59, 0x50, 0x45, 0x01, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x20, 0x00, + 0x58, 0x42, 0x4b, 0xfb, 0xa2, 0x63, 0xc5, 0xbe, 0xa5, 0x8f, 0x87, 0x96, + 0xe5, 0x35, 0xca, 0x35, 0xa0, 0xb5, 0xd2, 0xda, 0x62, 0x66, 0xc3, 0xd2, + 0x70, 0xc6, 0x5e, 0xbd, 0x02, 0xc6, 0xb7, 0xe7, 0x4d, 0x44, 0x53, 0x5a, + 0x08, 0x00, 0x20, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x46, + 0x46, 0x54, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x02, 0x00, + 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x85, 0x00, + 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x10, 0x00, 0x53, 0x44, 0x4c, 0x5f, + 0x43, 0x6f, 0x70, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x00, + 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x20, + 0x00, 0x66, 0xdb, 0x11, 0xb3, 0x31, 0x5a, 0xaa, 0xb0, 0x50, 0xa4, 0x35, + 0xc1, 0x73, 0x21, 0x6b, 0xe9, 0xc9, 0x0c, 0x95, 0x5f, 0xa8, 0xd9, 0x57, + 0xa3, 0x88, 0xec, 0x3f, 0xa9, 0x0a, 0x90, 0xbe, 0x0f, 0x4d, 0x44, 0x53, + 0x5a, 0x08, 0x00, 0x30, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, + 0x46, 0x46, 0x54, 0x18, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0d, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x88, + 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x13, 0x00, 0x53, 0x44, 0x4c, + 0x5f, 0x53, 0x6f, 0x6c, 0x69, 0x64, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, + 0x65, 0x6e, 0x74, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, + 0x41, 0x53, 0x48, 0x20, 0x00, 0xbf, 0xdd, 0x75, 0x01, 0xa6, 0xb2, 0xda, + 0x74, 0x88, 0xeb, 0x9a, 0x42, 0x99, 0x64, 0xad, 0x86, 0x24, 0x0f, 0x60, + 0xba, 0xca, 0x60, 0x8d, 0x5b, 0x03, 0xaa, 0xb6, 0x47, 0xf6, 0x63, 0x4e, + 0xf7, 0x4d, 0x44, 0x53, 0x5a, 0x08, 0x00, 0x30, 0x0a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x4f, 0x46, 0x46, 0x54, 0x18, 0x00, 0x66, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x50, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, + 0x53, 0x08, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, + 0x4e, 0x44, 0x54, 0x87, 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x12, + 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x43, 0x6f, 0x70, 0x79, 0x5f, 0x66, 0x72, + 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, + 0x00, 0x01, 0x48, 0x41, 0x53, 0x48, 0x20, 0x00, 0x5c, 0xba, 0x6c, 0xdf, + 0xc2, 0xf6, 0x3b, 0x3e, 0x3e, 0x08, 0x43, 0xbe, 0x7d, 0x22, 0xfe, 0x64, + 0xc7, 0x25, 0x19, 0x08, 0xc4, 0x0f, 0xc6, 0xb9, 0x40, 0x15, 0x4f, 0x9d, + 0xae, 0x55, 0xea, 0x33, 0x4d, 0x44, 0x53, 0x5a, 0x08, 0x00, 0xc0, 0x0b, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x46, 0x46, 0x54, 0x18, 0x00, + 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x86, 0x00, 0x00, 0x00, 0x4e, 0x41, + 0x4d, 0x45, 0x11, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x59, 0x55, 0x56, 0x5f, + 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x54, 0x59, 0x50, + 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, 0x53, 0x48, 0x20, 0x00, 0x39, 0xaf, + 0x60, 0x76, 0x98, 0x96, 0x34, 0xa7, 0xe6, 0x4c, 0xe7, 0x40, 0xaf, 0x1b, + 0x46, 0x4a, 0x1e, 0xc7, 0x26, 0x6a, 0x31, 0xc3, 0x0d, 0xe8, 0x89, 0x4e, + 0x88, 0xff, 0x38, 0x12, 0x36, 0xcc, 0x4d, 0x44, 0x53, 0x5a, 0x08, 0x00, + 0xd0, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x46, 0x46, 0x54, + 0x18, 0x00, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x02, 0x00, 0x02, 0x00, + 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x87, 0x00, 0x00, 0x00, + 0x4e, 0x41, 0x4d, 0x45, 0x12, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x4e, 0x56, + 0x31, 0x32, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x00, + 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, 0x53, 0x48, 0x20, + 0x00, 0xb2, 0xee, 0x20, 0x5e, 0x09, 0xbf, 0x7f, 0xac, 0xd0, 0x23, 0x12, + 0xf8, 0xa4, 0x8d, 0xdc, 0x2f, 0x44, 0x73, 0xe5, 0x8b, 0xe3, 0xba, 0xb1, + 0x72, 0xaa, 0x49, 0x43, 0x65, 0xbf, 0x81, 0x38, 0x26, 0x4d, 0x44, 0x53, + 0x5a, 0x08, 0x00, 0x30, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, + 0x46, 0x46, 0x54, 0x18, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x3f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x87, + 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x12, 0x00, 0x53, 0x44, 0x4c, + 0x5f, 0x4e, 0x56, 0x32, 0x31, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, + 0x6e, 0x74, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, + 0x53, 0x48, 0x20, 0x00, 0x07, 0x3f, 0x28, 0x46, 0x4d, 0xc8, 0x8f, 0xea, + 0x98, 0xaa, 0x7f, 0xba, 0xf9, 0xee, 0x72, 0x32, 0x9b, 0x5f, 0xbd, 0x82, + 0xbc, 0x63, 0x20, 0x7f, 0xfe, 0xfa, 0x50, 0x7c, 0xc8, 0xc5, 0xe1, 0x28, + 0x4d, 0x44, 0x53, 0x5a, 0x08, 0x00, 0x40, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x4f, 0x46, 0x46, 0x54, 0x18, 0x00, 0x86, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x4d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, + 0x08, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, + 0x44, 0x54, 0x45, 0x4e, 0x44, 0x54, 0x29, 0x00, 0x00, 0x00, 0x56, 0x41, + 0x54, 0x54, 0x15, 0x00, 0x02, 0x00, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x00, 0x00, 0x80, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x01, + 0x80, 0x56, 0x41, 0x54, 0x59, 0x04, 0x00, 0x02, 0x00, 0x04, 0x06, 0x45, + 0x4e, 0x44, 0x54, 0x35, 0x00, 0x00, 0x00, 0x56, 0x41, 0x54, 0x54, 0x20, + 0x00, 0x03, 0x00, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, + 0x00, 0x80, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x01, 0x80, 0x74, 0x65, + 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x00, 0x02, 0x80, 0x56, 0x41, 0x54, + 0x59, 0x05, 0x00, 0x03, 0x00, 0x04, 0x06, 0x04, 0x45, 0x4e, 0x44, 0x54, + 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, + 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, + 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, + 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, + 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, + 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, + 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, + 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, + 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x0c, 0x0d, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, + 0x35, 0x14, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x62, 0x0c, 0x30, 0x24, + 0x80, 0x10, 0x05, 0xc8, 0x14, 0x00, 0x00, 0x00, 0x21, 0x0c, 0x00, 0x00, + 0x08, 0x03, 0x00, 0x00, 0x0b, 0x02, 0x21, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, + 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, + 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, + 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88, + 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, + 0x04, 0x49, 0x0e, 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, + 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, + 0x85, 0x00, 0x00, 0x00, 0x1b, 0xc8, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, + 0x01, 0x90, 0x80, 0x8a, 0x18, 0x87, 0x77, 0x90, 0x07, 0x79, 0x28, 0x87, + 0x71, 0xa0, 0x07, 0x76, 0xc8, 0x87, 0x36, 0x90, 0x87, 0x77, 0xa8, 0x07, + 0x77, 0x20, 0x87, 0x72, 0x20, 0x87, 0x36, 0x20, 0x87, 0x74, 0xb0, 0x87, + 0x74, 0x20, 0x87, 0x72, 0x68, 0x83, 0x79, 0x88, 0x07, 0x79, 0xa0, 0x87, + 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, + 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1c, 0xd2, + 0x61, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xc2, + 0x21, 0x1d, 0xd8, 0xa1, 0x0d, 0xc6, 0x21, 0x1c, 0xd8, 0x81, 0x1d, 0xe6, + 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x60, 0x87, + 0x72, 0x98, 0x87, 0x79, 0x68, 0x03, 0x78, 0x90, 0x87, 0x72, 0x18, 0x87, + 0x74, 0x98, 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x76, 0x08, 0x07, + 0x72, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, + 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, + 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, + 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, + 0x72, 0x00, 0x06, 0x77, 0x78, 0x87, 0x36, 0x30, 0x07, 0x79, 0x08, 0x87, + 0x76, 0x28, 0x87, 0x36, 0x80, 0x87, 0x77, 0x48, 0x07, 0x77, 0xa0, 0x87, + 0x72, 0x90, 0x87, 0x36, 0x28, 0x07, 0x76, 0x48, 0x87, 0x76, 0x68, 0x03, + 0x77, 0x78, 0x07, 0x77, 0x68, 0x03, 0x76, 0x28, 0x87, 0x70, 0x30, 0x07, + 0x80, 0x70, 0x87, 0x77, 0x68, 0x83, 0x74, 0x70, 0x07, 0x73, 0x98, 0x87, + 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, + 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, + 0x40, 0x1d, 0xea, 0xa1, 0x1d, 0xe0, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xc4, + 0x81, 0x1d, 0xca, 0x61, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, + 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x70, 0x87, 0x70, 0x70, 0x87, + 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, + 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, + 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xce, 0xc1, 0x1d, 0xca, 0x81, 0x1c, 0xda, + 0x40, 0x1f, 0xca, 0x41, 0x1e, 0xde, 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, + 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, + 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x7a, 0x90, 0x87, + 0x70, 0x80, 0x07, 0x78, 0x48, 0x07, 0x77, 0x38, 0x87, 0x36, 0x68, 0x87, + 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, + 0x62, 0x1e, 0xe8, 0x21, 0x1c, 0xc6, 0x61, 0x1d, 0xda, 0x00, 0x1e, 0xe4, + 0xe1, 0x1d, 0xe8, 0xa1, 0x1c, 0xc6, 0x81, 0x1e, 0xde, 0x41, 0x1e, 0xda, + 0x40, 0x1c, 0xea, 0xc1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xe6, + 0x21, 0x1d, 0xf4, 0xa1, 0x1c, 0x00, 0x3c, 0x00, 0x88, 0x7a, 0x70, 0x87, + 0x79, 0x08, 0x07, 0x73, 0x28, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, + 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, + 0x01, 0x20, 0xea, 0x61, 0x1e, 0xca, 0xa1, 0x0d, 0xe6, 0xe1, 0x1d, 0xcc, + 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xd8, 0xe1, 0x1d, 0xc2, 0x81, 0x1e, 0x00, + 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x36, 0x2c, 0xc2, 0x00, + 0x24, 0xc0, 0x02, 0x54, 0x41, 0x1a, 0x80, 0xc2, 0x86, 0x65, 0x20, 0x80, + 0x04, 0x58, 0x80, 0x2a, 0x48, 0x03, 0x50, 0x00, 0x49, 0x18, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x13, 0x86, 0x40, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x89, 0x20, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, + 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, + 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, + 0x10, 0x40, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x60, 0x87, 0x10, 0xc0, 0x30, + 0x82, 0x00, 0x24, 0x41, 0x98, 0x89, 0x9a, 0x07, 0x7a, 0x90, 0x87, 0x7a, + 0x18, 0x07, 0x7a, 0x70, 0x83, 0x76, 0x28, 0x07, 0x7a, 0x08, 0x07, 0x76, + 0xd0, 0x03, 0x3d, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x79, 0x48, 0x07, 0x7c, + 0x40, 0x01, 0x19, 0x44, 0x28, 0x84, 0x52, 0x88, 0x11, 0x8c, 0xa1, 0x33, + 0x10, 0x30, 0x47, 0x00, 0x06, 0x29, 0xa0, 0xe6, 0x08, 0x40, 0x61, 0x10, + 0x21, 0x10, 0x86, 0x11, 0x08, 0x65, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x13, 0xbe, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, + 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, 0x87, 0x79, + 0x88, 0x83, 0x39, 0x70, 0x03, 0x38, 0x70, 0x03, 0x38, 0x68, 0x83, 0x79, + 0x48, 0x87, 0x76, 0xa8, 0x07, 0x76, 0x08, 0x07, 0x7a, 0x78, 0x07, 0x79, + 0xd8, 0x70, 0x1b, 0xe5, 0xd0, 0x06, 0xf0, 0xa0, 0x07, 0x76, 0x40, 0x07, + 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x90, 0x0e, + 0x71, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x80, 0x07, + 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, + 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x90, 0x0e, + 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, + 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, + 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, + 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x76, 0x40, 0x07, + 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, + 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, + 0x6d, 0x60, 0x0f, 0x72, 0x40, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, + 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, + 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x74, 0x80, 0x07, + 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, + 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, + 0x6d, 0x60, 0x0f, 0x79, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, + 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x20, 0x07, + 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, + 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x79, 0x20, 0x07, 0x7a, 0x20, 0x07, + 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, 0x0f, + 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, + 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x50, 0x07, 0x71, 0x20, 0x07, + 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, + 0x6d, 0x60, 0x0f, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, 0x07, + 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, + 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, + 0x72, 0xa0, 0x11, 0xc2, 0x90, 0x10, 0xdb, 0x95, 0x3f, 0xeb, 0x2c, 0xc8, + 0xf0, 0x57, 0x44, 0x34, 0x11, 0xd7, 0x90, 0x08, 0x80, 0x0e, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x90, 0xd8, 0x20, 0x50, + 0x54, 0x61, 0x00, 0x00, 0x20, 0x0b, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, + 0xc6, 0x04, 0x43, 0x52, 0x45, 0x50, 0x02, 0x85, 0x30, 0x02, 0x50, 0x80, + 0x01, 0x05, 0x52, 0x06, 0xc4, 0x46, 0x00, 0x68, 0x8d, 0x25, 0x38, 0x04, + 0x00, 0x00, 0x00, 0x00, 0xb1, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, + 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, + 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, + 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, + 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, + 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, + 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, + 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, + 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, + 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, + 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, + 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, + 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, + 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, + 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, + 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, + 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, + 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, + 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, + 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, + 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, + 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, + 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, + 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, + 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, + 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, + 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, + 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, + 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, + 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, + 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, + 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, + 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, + 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, + 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, + 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, + 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, + 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, + 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, + 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, + 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, + 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, + 0x79, 0x20, 0x00, 0x00, 0xd1, 0x00, 0x00, 0x00, 0x32, 0x9a, 0x08, 0x14, + 0x02, 0x85, 0x8c, 0x27, 0x46, 0x46, 0xc8, 0x11, 0x32, 0x64, 0xd4, 0x3c, + 0xcc, 0x7c, 0x00, 0x00, 0x8b, 0x02, 0x07, 0xc5, 0xc6, 0x91, 0x01, 0x13, + 0x19, 0x0c, 0x12, 0x59, 0x85, 0x53, 0x24, 0x90, 0xe4, 0x19, 0xca, 0x83, + 0x44, 0x17, 0xa2, 0x24, 0x53, 0x44, 0x4b, 0x20, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x77, 0x63, 0x68, 0x61, 0x72, 0x5f, 0x73, 0x69, 0x7a, + 0x65, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x4c, 0x4c, 0x56, 0x4d, 0x20, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x33, 0x31, 0x30, 0x30, + 0x31, 0x2e, 0x35, 0x30, 0x20, 0x28, 0x6d, 0x65, 0x74, 0x61, 0x6c, 0x66, + 0x65, 0x2d, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x2e, 0x31, + 0x29, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, + 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x64, 0x65, 0x6e, 0x6f, 0x72, 0x6d, + 0x73, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, + 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, + 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, + 0x2e, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, + 0x5f, 0x66, 0x65, 0x74, 0x63, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x61, 0x69, 0x72, 0x2e, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, + 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x69, 0x72, 0x2e, + 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x35, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x44, 0x76, 0x34, 0x5f, 0x66, 0x29, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x70, + 0x6f, 0x69, 0x6e, 0x74, 0x53, 0x69, 0x7a, 0x65, 0x61, 0x69, 0x72, 0x2e, + 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, + 0x61, 0x69, 0x72, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, + 0x74, 0x65, 0x64, 0x28, 0x5f, 0x5f, 0x61, 0x69, 0x72, 0x5f, 0x70, 0x6c, + 0x61, 0x63, 0x65, 0x68, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x5f, 0x5f, 0x29, + 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, + 0x66, 0x66, 0x65, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, + 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x72, + 0x65, 0x61, 0x64, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, + 0x79, 0x70, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x61, 0x69, 0x72, 0x2e, + 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x61, 0x6c, 0x69, + 0x67, 0x6e, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x66, 0x6c, 0x6f, 0x61, 0x74, + 0x34, 0x78, 0x34, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x00, 0x00, + 0xc4, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x82, 0xa0, 0x04, + 0x23, 0x08, 0x4b, 0x32, 0x82, 0xa0, 0x08, 0x23, 0x08, 0xca, 0x30, 0x82, + 0xa0, 0x10, 0x23, 0x08, 0x08, 0x30, 0x82, 0xa0, 0x14, 0x23, 0x08, 0x8a, + 0x31, 0x82, 0xa0, 0x1c, 0x33, 0x0c, 0x5f, 0x00, 0x06, 0x33, 0x0c, 0x61, + 0x20, 0x88, 0xc1, 0x0c, 0xc1, 0x30, 0xc3, 0xf0, 0x7d, 0x63, 0x30, 0x03, + 0x41, 0x84, 0x41, 0x18, 0x8c, 0xc1, 0x0c, 0x41, 0x31, 0x43, 0x60, 0xcc, + 0x10, 0x1c, 0x33, 0x14, 0x48, 0xa2, 0x2c, 0xcc, 0x0c, 0x46, 0xe3, 0x24, + 0xca, 0xf2, 0xcc, 0x50, 0x40, 0x49, 0xb4, 0x48, 0x33, 0x0c, 0x70, 0x10, + 0x07, 0x72, 0x30, 0x83, 0x32, 0x06, 0x13, 0x35, 0x06, 0x61, 0x50, 0x25, + 0xd6, 0xc2, 0xcc, 0xa0, 0x84, 0xc1, 0x44, 0x85, 0x41, 0x18, 0x54, 0x89, + 0xb2, 0x3c, 0x33, 0x40, 0xdf, 0x85, 0x95, 0x01, 0xf5, 0x85, 0x41, 0xa6, + 0x95, 0xc1, 0x66, 0x06, 0x09, 0xb7, 0x74, 0x33, 0x40, 0x67, 0x70, 0x61, + 0x65, 0x40, 0x9d, 0x41, 0x18, 0x64, 0x5a, 0x19, 0x6c, 0x66, 0x90, 0x70, + 0x8b, 0x37, 0x03, 0x41, 0x07, 0x75, 0x60, 0x07, 0x77, 0x30, 0xc3, 0x40, + 0x06, 0x73, 0x80, 0x07, 0xb5, 0x01, 0x1c, 0xc7, 0x71, 0x1c, 0xc7, 0x71, + 0x1c, 0x1a, 0xb8, 0x81, 0x85, 0x06, 0x7a, 0x60, 0x59, 0x96, 0x1b, 0xd0, + 0x81, 0x1b, 0xd0, 0x81, 0x2f, 0xf8, 0x02, 0x4a, 0xd0, 0x04, 0x28, 0xc8, + 0x48, 0x60, 0x82, 0x2e, 0x62, 0x63, 0xb3, 0x6b, 0x73, 0x69, 0x7b, 0x23, + 0xab, 0x63, 0x2b, 0x73, 0x31, 0x63, 0x0b, 0x3b, 0x9b, 0x1b, 0x45, 0x38, + 0x03, 0x34, 0x38, 0x85, 0x8d, 0xcd, 0xae, 0xcd, 0x25, 0x8d, 0xac, 0xcc, + 0x8d, 0x6e, 0x94, 0x20, 0x0d, 0x6e, 0x09, 0x4b, 0x93, 0x73, 0xb1, 0x2b, + 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x1b, 0x25, 0x50, 0x83, 0xa3, 0xc2, 0xd2, + 0xe4, 0x5c, 0xd8, 0xc2, 0xdc, 0xce, 0xea, 0xc2, 0xce, 0xca, 0xbe, 0xec, + 0xca, 0xe4, 0xe6, 0xd2, 0xde, 0xdc, 0x46, 0x09, 0xd6, 0xe0, 0xa6, 0xb0, + 0x34, 0x39, 0x97, 0xb1, 0xb7, 0x36, 0xb8, 0x34, 0xb6, 0xb2, 0xaf, 0x37, + 0x38, 0xba, 0xb4, 0x37, 0xb7, 0xb9, 0x51, 0x06, 0x36, 0x68, 0x03, 0x37, + 0x38, 0x25, 0x2c, 0x4d, 0xce, 0xc5, 0xae, 0x4c, 0x8e, 0xae, 0x0c, 0x6f, + 0x94, 0x00, 0x0f, 0x00, 0xa9, 0x18, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0x0b, 0x0a, 0x72, 0x28, 0x87, 0x77, 0x80, 0x07, 0x7a, 0x58, 0x70, 0x98, + 0x43, 0x3d, 0xb8, 0xc3, 0x38, 0xb0, 0x43, 0x39, 0xd0, 0xc3, 0x82, 0xe6, + 0x1c, 0xc6, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0xc1, 0x1d, 0xe6, 0x21, + 0x1d, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x00, 0xd1, 0x10, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x07, 0xcc, 0x3c, 0xa4, 0x83, 0x3b, 0x9c, 0x03, + 0x3b, 0x94, 0x03, 0x3d, 0xa0, 0x83, 0x3c, 0x94, 0x43, 0x38, 0x90, 0xc3, + 0x01, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, + 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0xc4, 0x4a, 0xa0, 0x0c, 0x8a, 0x80, 0xdc, 0x08, 0xc0, 0x58, 0x44, 0x10, + 0x04, 0xc1, 0x58, 0x84, 0x20, 0x08, 0xc2, 0x58, 0xc4, 0x30, 0x0c, 0x03, + 0x81, 0x31, 0x02, 0x10, 0x04, 0x41, 0xfc, 0xa3, 0x30, 0x03, 0x40, 0x62, + 0x06, 0x80, 0xc6, 0x0c, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x22, 0x47, 0xc8, 0x90, 0x51, 0x0a, 0x84, 0x18, + 0x00, 0x00, 0x00, 0x00, 0xcf, 0x03, 0x00, 0x00, 0x6f, 0x6d, 0x6e, 0x69, + 0x70, 0x6f, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x63, 0x68, 0x61, 0x72, 0x53, + 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x2b, 0x2b, 0x20, 0x54, 0x42, + 0x41, 0x41, 0x00, 0x00, 0x13, 0x04, 0x06, 0xd9, 0x10, 0xec, 0xc1, 0x86, + 0x41, 0x0f, 0xfa, 0x80, 0x0f, 0x36, 0x0c, 0x7e, 0xe0, 0x07, 0x7c, 0x00, + 0xbb, 0x10, 0x4c, 0x54, 0x45, 0x14, 0x84, 0xb2, 0x0b, 0xf1, 0x4c, 0xd7, + 0x44, 0x41, 0x28, 0x83, 0x0c, 0xc3, 0xc1, 0x98, 0x10, 0x88, 0xff, 0x2e, + 0xc4, 0x74, 0x6d, 0x11, 0x05, 0xa1, 0x0c, 0x32, 0x1c, 0xcb, 0x63, 0x42, + 0x20, 0xfe, 0x16, 0x14, 0xe0, 0xbf, 0x0b, 0x81, 0x71, 0x60, 0x40, 0x51, + 0x10, 0xca, 0x20, 0x03, 0x03, 0x4d, 0x26, 0x04, 0xe2, 0x6f, 0x45, 0x00, + 0xfe, 0xbb, 0x10, 0x5d, 0x18, 0x94, 0x81, 0x46, 0x41, 0x28, 0x83, 0x0c, + 0x51, 0x75, 0x99, 0x10, 0x88, 0xbf, 0x15, 0x01, 0xf8, 0xef, 0x42, 0x84, + 0x81, 0x19, 0xa8, 0x01, 0x18, 0x50, 0x10, 0xca, 0x20, 0x43, 0xa0, 0x7d, + 0x16, 0x54, 0xe2, 0x3f, 0xc8, 0x30, 0x70, 0x60, 0x60, 0xc1, 0x24, 0xfe, + 0x36, 0x04, 0xe0, 0x3f, 0xc8, 0x60, 0x7c, 0x62, 0x60, 0x41, 0x24, 0xfe, + 0x36, 0x04, 0xe0, 0x3f, 0xc8, 0x90, 0x88, 0x01, 0x19, 0x58, 0xf0, 0x88, + 0xbf, 0x0d, 0x01, 0xf8, 0xef, 0x42, 0xb8, 0xc1, 0x1c, 0xdc, 0x01, 0x1b, + 0x50, 0x10, 0xca, 0x20, 0x43, 0x70, 0x06, 0x6c, 0x60, 0x81, 0x18, 0x88, + 0xff, 0x20, 0xc3, 0x90, 0x06, 0x6d, 0x60, 0x01, 0x18, 0x88, 0xff, 0x20, + 0x43, 0xb1, 0x06, 0x6e, 0x60, 0x41, 0x27, 0xfe, 0x83, 0x0c, 0x47, 0x1b, + 0xbc, 0x81, 0x05, 0x9a, 0xf8, 0x0f, 0x32, 0xec, 0x41, 0x1b, 0xd0, 0x81, + 0x65, 0x81, 0xf8, 0x0f, 0x32, 0xf4, 0xc1, 0x1b, 0xd4, 0x81, 0x39, 0x81, + 0xf8, 0x5b, 0x32, 0x80, 0xbf, 0x05, 0x0c, 0xf8, 0x5b, 0x90, 0x80, 0xbf, + 0x05, 0x08, 0xf8, 0x5b, 0x50, 0x80, 0xff, 0x6c, 0xc3, 0x1d, 0x04, 0xc0, + 0x6c, 0x43, 0x40, 0x0a, 0xc1, 0x6c, 0x43, 0xb0, 0x07, 0x42, 0x06, 0x01, + 0x31, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x5b, 0x86, 0x20, 0xf0, + 0x83, 0x2d, 0xc3, 0x10, 0xf8, 0xc1, 0x96, 0xe1, 0x08, 0xfc, 0x60, 0xcb, + 0xc0, 0x04, 0x7e, 0xb0, 0x65, 0x88, 0x02, 0x3f, 0xd8, 0x32, 0x58, 0x81, + 0x1f, 0x6c, 0x19, 0xc6, 0x20, 0xf0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x71, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x32, 0x0e, 0x10, 0x22, + 0x84, 0x00, 0x9f, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x65, 0x0c, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0xe8, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x24, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x5d, 0x0c, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x12, 0x03, 0x94, 0x79, 0x00, 0x00, 0x00, 0x00, 0x53, 0x44, 0x4c, 0x5f, + 0x53, 0x6f, 0x6c, 0x69, 0x64, 0x5f, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, + 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x2e, 0x31, 0x61, 0x69, + 0x72, 0x36, 0x34, 0x2d, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2d, 0x69, 0x6f, + 0x73, 0x31, 0x33, 0x2e, 0x30, 0x2e, 0x30, 0x2d, 0x73, 0x69, 0x6d, 0x75, + 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x10, 0x0d, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, + 0x35, 0x14, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x62, 0x0c, 0x30, 0x24, + 0x80, 0x10, 0x05, 0xc8, 0x14, 0x00, 0x00, 0x00, 0x21, 0x0c, 0x00, 0x00, + 0x0a, 0x03, 0x00, 0x00, 0x0b, 0x02, 0x21, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, + 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, + 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, + 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88, + 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, + 0x04, 0x49, 0x0e, 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, + 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, + 0x85, 0x00, 0x00, 0x00, 0x1b, 0xc8, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, + 0x01, 0x90, 0x80, 0x8a, 0x18, 0x87, 0x77, 0x90, 0x07, 0x79, 0x28, 0x87, + 0x71, 0xa0, 0x07, 0x76, 0xc8, 0x87, 0x36, 0x90, 0x87, 0x77, 0xa8, 0x07, + 0x77, 0x20, 0x87, 0x72, 0x20, 0x87, 0x36, 0x20, 0x87, 0x74, 0xb0, 0x87, + 0x74, 0x20, 0x87, 0x72, 0x68, 0x83, 0x79, 0x88, 0x07, 0x79, 0xa0, 0x87, + 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, + 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1c, 0xd2, + 0x61, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xc2, + 0x21, 0x1d, 0xd8, 0xa1, 0x0d, 0xc6, 0x21, 0x1c, 0xd8, 0x81, 0x1d, 0xe6, + 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x60, 0x87, + 0x72, 0x98, 0x87, 0x79, 0x68, 0x03, 0x78, 0x90, 0x87, 0x72, 0x18, 0x87, + 0x74, 0x98, 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x76, 0x08, 0x07, + 0x72, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, + 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, + 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, + 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, + 0x72, 0x00, 0x06, 0x77, 0x78, 0x87, 0x36, 0x30, 0x07, 0x79, 0x08, 0x87, + 0x76, 0x28, 0x87, 0x36, 0x80, 0x87, 0x77, 0x48, 0x07, 0x77, 0xa0, 0x87, + 0x72, 0x90, 0x87, 0x36, 0x28, 0x07, 0x76, 0x48, 0x87, 0x76, 0x68, 0x03, + 0x77, 0x78, 0x07, 0x77, 0x68, 0x03, 0x76, 0x28, 0x87, 0x70, 0x30, 0x07, + 0x80, 0x70, 0x87, 0x77, 0x68, 0x83, 0x74, 0x70, 0x07, 0x73, 0x98, 0x87, + 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, + 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, + 0x40, 0x1d, 0xea, 0xa1, 0x1d, 0xe0, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xc4, + 0x81, 0x1d, 0xca, 0x61, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, + 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x70, 0x87, 0x70, 0x70, 0x87, + 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, + 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, + 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xce, 0xc1, 0x1d, 0xca, 0x81, 0x1c, 0xda, + 0x40, 0x1f, 0xca, 0x41, 0x1e, 0xde, 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, + 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, + 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x7a, 0x90, 0x87, + 0x70, 0x80, 0x07, 0x78, 0x48, 0x07, 0x77, 0x38, 0x87, 0x36, 0x68, 0x87, + 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, + 0x62, 0x1e, 0xe8, 0x21, 0x1c, 0xc6, 0x61, 0x1d, 0xda, 0x00, 0x1e, 0xe4, + 0xe1, 0x1d, 0xe8, 0xa1, 0x1c, 0xc6, 0x81, 0x1e, 0xde, 0x41, 0x1e, 0xda, + 0x40, 0x1c, 0xea, 0xc1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xe6, + 0x21, 0x1d, 0xf4, 0xa1, 0x1c, 0x00, 0x3c, 0x00, 0x88, 0x7a, 0x70, 0x87, + 0x79, 0x08, 0x07, 0x73, 0x28, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, + 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, + 0x01, 0x20, 0xea, 0x61, 0x1e, 0xca, 0xa1, 0x0d, 0xe6, 0xe1, 0x1d, 0xcc, + 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xd8, 0xe1, 0x1d, 0xc2, 0x81, 0x1e, 0x00, + 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x36, 0x2c, 0x02, 0x01, + 0x24, 0xc0, 0x02, 0x54, 0x41, 0x1a, 0x80, 0xc2, 0x86, 0x65, 0x28, 0x80, + 0x04, 0x58, 0x80, 0x2a, 0x48, 0x03, 0x50, 0x00, 0x49, 0x18, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x13, 0x86, 0x40, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x89, 0x20, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, + 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, + 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, + 0x10, 0x40, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, 0x00, 0x76, + 0x08, 0x41, 0x24, 0x41, 0x98, 0x89, 0x9a, 0x07, 0x7a, 0x90, 0x87, 0x7a, + 0x18, 0x07, 0x7a, 0x70, 0x83, 0x76, 0x28, 0x07, 0x7a, 0x08, 0x07, 0x76, + 0xd0, 0x03, 0x3d, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x79, 0x48, 0x07, 0x7c, + 0x40, 0x01, 0x19, 0x44, 0x28, 0x84, 0x62, 0x0c, 0x11, 0x84, 0x31, 0x74, + 0x06, 0x02, 0xe6, 0x08, 0xc0, 0x20, 0x05, 0xd4, 0x1c, 0x01, 0x28, 0x0c, + 0x22, 0x04, 0xc2, 0x30, 0x02, 0xa1, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x13, 0xbe, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, + 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, 0x87, 0x79, + 0x88, 0x83, 0x39, 0x70, 0x03, 0x38, 0x70, 0x03, 0x38, 0x68, 0x83, 0x79, + 0x48, 0x87, 0x76, 0xa8, 0x07, 0x76, 0x08, 0x07, 0x7a, 0x78, 0x07, 0x79, + 0xd8, 0x70, 0x1b, 0xe5, 0xd0, 0x06, 0xf0, 0xa0, 0x07, 0x76, 0x40, 0x07, + 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x90, 0x0e, + 0x71, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x80, 0x07, + 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, + 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x90, 0x0e, + 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, + 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, + 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, + 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x76, 0x40, 0x07, + 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, + 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, + 0x6d, 0x60, 0x0f, 0x72, 0x40, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, + 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, + 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x74, 0x80, 0x07, + 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, + 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, + 0x6d, 0x60, 0x0f, 0x79, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, + 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x20, 0x07, + 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, + 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x79, 0x20, 0x07, 0x7a, 0x20, 0x07, + 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, 0x0f, + 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, + 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x50, 0x07, 0x71, 0x20, 0x07, + 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, + 0x6d, 0x60, 0x0f, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, 0x07, + 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, + 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, + 0x72, 0xa0, 0x11, 0xc2, 0x90, 0x0f, 0xdb, 0x95, 0x3f, 0xe7, 0x3c, 0xd8, + 0x5f, 0x11, 0xd1, 0x44, 0x5c, 0x43, 0x22, 0xe0, 0x39, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x40, 0x62, 0x83, 0x40, 0x51, + 0x86, 0x01, 0x00, 0x80, 0x2c, 0x10, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, + 0xc6, 0x04, 0x43, 0x52, 0x45, 0x50, 0x02, 0x85, 0x30, 0x02, 0x50, 0x06, + 0x05, 0x18, 0x50, 0x20, 0xc4, 0x46, 0x00, 0x68, 0x8d, 0x25, 0x38, 0x04, + 0x00, 0x00, 0x00, 0x00, 0xb1, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, + 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, + 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, + 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, + 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, + 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, + 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, + 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, + 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, + 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, + 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, + 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, + 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, + 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, + 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, + 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, + 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, + 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, + 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, + 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, + 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, + 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, + 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, + 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, + 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, + 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, + 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, + 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, + 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, + 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, + 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, + 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, + 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, + 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, + 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, + 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, + 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, + 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, + 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, + 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, + 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, + 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, + 0x79, 0x20, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, 0x32, 0x9a, 0x08, 0x14, + 0x02, 0x85, 0x8c, 0x27, 0x46, 0x46, 0xc8, 0x11, 0x32, 0x64, 0xd4, 0x3a, + 0x6c, 0x7d, 0x00, 0x00, 0x8b, 0x02, 0x07, 0xc5, 0xc6, 0x91, 0x01, 0x13, + 0x19, 0x0c, 0x12, 0x59, 0x45, 0x66, 0x20, 0x90, 0xe4, 0x29, 0x0f, 0x12, + 0x5d, 0x88, 0x92, 0x00, 0x53, 0x44, 0x4b, 0x20, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x77, 0x63, 0x68, 0x61, 0x72, 0x5f, 0x73, 0x69, 0x7a, + 0x65, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x4c, 0x4c, 0x56, 0x4d, 0x20, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x33, 0x31, 0x30, 0x30, + 0x31, 0x2e, 0x35, 0x30, 0x20, 0x28, 0x6d, 0x65, 0x74, 0x61, 0x6c, 0x66, + 0x65, 0x2d, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x2e, 0x31, + 0x29, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, + 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x64, 0x65, 0x6e, 0x6f, 0x72, 0x6d, + 0x73, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, + 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, + 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, + 0x2e, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, + 0x5f, 0x66, 0x65, 0x74, 0x63, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x61, 0x69, 0x72, 0x2e, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, + 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x69, 0x72, 0x2e, + 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x35, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x44, 0x76, 0x34, 0x5f, 0x66, 0x29, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, + 0x64, 0x28, 0x38, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x44, + 0x76, 0x32, 0x5f, 0x66, 0x29, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x74, + 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x61, 0x69, 0x72, 0x2e, 0x76, + 0x65, 0x72, 0x74, 0x65, 0x78, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x61, + 0x69, 0x72, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x69, 0x6e, 0x64, 0x65, 0x78, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, + 0x65, 0x64, 0x28, 0x5f, 0x5f, 0x61, 0x69, 0x72, 0x5f, 0x70, 0x6c, 0x61, + 0x63, 0x65, 0x68, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x5f, 0x5f, 0x29, 0x61, + 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x61, 0x69, 0x72, + 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, + 0x61, 0x69, 0x72, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x61, 0x69, 0x72, 0x2e, + 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x73, 0x69, 0x7a, + 0x65, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x5f, 0x73, 0x69, 0x7a, 0x65, + 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x78, 0x34, 0x70, 0x72, 0x6f, 0x6a, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, + 0x6f, 0x72, 0x6d, 0x00, 0x04, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x82, 0xa0, 0x04, 0x23, 0x08, 0x4b, 0x32, 0x82, 0xa0, 0x08, 0x23, + 0x08, 0xca, 0x30, 0x82, 0xa0, 0x10, 0x23, 0x08, 0x08, 0x30, 0x82, 0xa0, + 0x14, 0x23, 0x08, 0x8a, 0x31, 0x82, 0xa0, 0x1c, 0x33, 0x0c, 0x5e, 0xf0, + 0xcd, 0x30, 0x80, 0x81, 0x10, 0x06, 0x33, 0x04, 0xc3, 0x0c, 0x83, 0xe7, + 0x89, 0xc1, 0x0c, 0x04, 0x01, 0x06, 0x60, 0x20, 0x06, 0x33, 0x04, 0xc5, + 0x0c, 0x81, 0x31, 0x43, 0x70, 0xcc, 0x50, 0x20, 0x89, 0xb2, 0x30, 0x33, + 0x18, 0x8d, 0x93, 0x28, 0xcb, 0x33, 0x83, 0xd1, 0x40, 0x49, 0xb4, 0x48, + 0x33, 0x0c, 0x6f, 0x00, 0x07, 0x71, 0x30, 0x83, 0x22, 0x06, 0x13, 0x25, + 0x06, 0x60, 0x50, 0x25, 0xd1, 0xc2, 0xcc, 0xa0, 0x80, 0xc1, 0x44, 0x81, + 0x01, 0x18, 0x54, 0x89, 0xb2, 0x3c, 0x33, 0x28, 0xde, 0x44, 0x79, 0x60, + 0x50, 0x25, 0xd1, 0x22, 0xcd, 0x00, 0x91, 0x81, 0x75, 0x95, 0x01, 0xe5, + 0x81, 0x01, 0x96, 0x95, 0x81, 0x66, 0x06, 0xc9, 0xb6, 0x70, 0x33, 0x40, + 0x61, 0x60, 0x5d, 0x65, 0x40, 0x91, 0x01, 0x18, 0x60, 0x59, 0x19, 0x68, + 0x66, 0x90, 0x6c, 0x4b, 0x37, 0x43, 0x31, 0x07, 0x74, 0x50, 0x07, 0x76, + 0x70, 0x07, 0x33, 0x0c, 0x63, 0x20, 0x07, 0x78, 0x50, 0x1c, 0xc0, 0x71, + 0x1c, 0xc7, 0x71, 0x1c, 0xc7, 0x89, 0x81, 0x1b, 0x58, 0x68, 0xa0, 0x07, + 0x96, 0x65, 0xb9, 0x01, 0x1d, 0xd0, 0x01, 0x1d, 0xf8, 0x82, 0x2f, 0xc8, + 0x82, 0x4b, 0xd0, 0x04, 0x2b, 0xc8, 0x48, 0x60, 0x82, 0x2e, 0x62, 0x63, + 0xb3, 0x6b, 0x73, 0x69, 0x7b, 0x23, 0xab, 0x63, 0x2b, 0x73, 0x31, 0x63, + 0x0b, 0x3b, 0x9b, 0x1b, 0x45, 0x30, 0x83, 0x33, 0x38, 0x85, 0x8d, 0xcd, + 0xae, 0xcd, 0x25, 0x8d, 0xac, 0xcc, 0x8d, 0x6e, 0x94, 0x00, 0x0d, 0x6e, + 0x09, 0x4b, 0x93, 0x73, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x1b, + 0x25, 0x48, 0x83, 0xa3, 0xc2, 0xd2, 0xe4, 0x5c, 0xd8, 0xc2, 0xdc, 0xce, + 0xea, 0xc2, 0xce, 0xca, 0xbe, 0xec, 0xca, 0xe4, 0xe6, 0xd2, 0xde, 0xdc, + 0x46, 0x09, 0xd4, 0xe0, 0xa6, 0xb0, 0x34, 0x39, 0x97, 0xb1, 0xb7, 0x36, + 0xb8, 0x34, 0xb6, 0xb2, 0xaf, 0x37, 0x38, 0xba, 0xb4, 0x37, 0xb7, 0xb9, + 0x51, 0x86, 0x35, 0x60, 0x83, 0x36, 0x38, 0x25, 0x2c, 0x4d, 0xce, 0xc5, + 0xae, 0x4c, 0x8e, 0xae, 0x0c, 0x6f, 0x94, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0xa9, 0x18, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x0a, 0x72, 0x28, + 0x87, 0x77, 0x80, 0x07, 0x7a, 0x58, 0x70, 0x98, 0x43, 0x3d, 0xb8, 0xc3, + 0x38, 0xb0, 0x43, 0x39, 0xd0, 0xc3, 0x82, 0xe6, 0x1c, 0xc6, 0xa1, 0x0d, + 0xe8, 0x41, 0x1e, 0xc2, 0xc1, 0x1d, 0xe6, 0x21, 0x1d, 0xe8, 0x21, 0x1d, + 0xde, 0xc1, 0x1d, 0x00, 0xd1, 0x10, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x07, 0xcc, 0x3c, 0xa4, 0x83, 0x3b, 0x9c, 0x03, 0x3b, 0x94, 0x03, 0x3d, + 0xa0, 0x83, 0x3c, 0x94, 0x43, 0x38, 0x90, 0xc3, 0x01, 0x00, 0x00, 0x00, + 0x61, 0x20, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, + 0x10, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0xc4, 0x4a, 0xa0, 0x0c, + 0x8a, 0x80, 0xdc, 0x08, 0xc0, 0x58, 0x44, 0x10, 0x04, 0xc1, 0x58, 0x84, + 0x20, 0x08, 0xc2, 0x58, 0xc4, 0x30, 0x0c, 0x03, 0x85, 0x19, 0x00, 0x12, + 0x33, 0x00, 0x34, 0x66, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x30, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x22, 0x47, 0xc8, 0x90, 0x51, 0x0a, 0x84, 0x18, + 0x00, 0x00, 0x00, 0x00, 0xcf, 0x03, 0x00, 0x00, 0x6f, 0x6d, 0x6e, 0x69, + 0x70, 0x6f, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x63, 0x68, 0x61, 0x72, 0x53, + 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x2b, 0x2b, 0x20, 0x54, 0x42, + 0x41, 0x41, 0x00, 0x00, 0x13, 0x04, 0x06, 0xd9, 0x10, 0xec, 0xc1, 0x86, + 0x41, 0x0f, 0xfa, 0x80, 0x0f, 0x36, 0x0c, 0x7e, 0xe0, 0x07, 0x7c, 0x00, + 0xbb, 0x10, 0x4b, 0x54, 0x45, 0x14, 0x84, 0xb2, 0x0b, 0xe1, 0x4c, 0xd7, + 0x44, 0x41, 0x28, 0x83, 0x0c, 0xc3, 0xb1, 0x98, 0x10, 0x88, 0xff, 0x2e, + 0x84, 0x74, 0x6d, 0x10, 0x05, 0xa1, 0x0c, 0x32, 0x1c, 0x8b, 0x63, 0x42, + 0x20, 0xfe, 0x16, 0x14, 0xe0, 0xbf, 0x0b, 0x71, 0x71, 0x60, 0x30, 0x51, + 0x10, 0xca, 0x20, 0x03, 0x03, 0x49, 0x26, 0x04, 0xe2, 0x6f, 0x45, 0x00, + 0xfe, 0xbb, 0x10, 0x5c, 0x18, 0x94, 0x41, 0x46, 0x41, 0x28, 0x83, 0x0c, + 0x51, 0x65, 0x99, 0x10, 0x88, 0xbf, 0x15, 0x01, 0xf8, 0xef, 0x42, 0x80, + 0x81, 0x19, 0xa8, 0xc1, 0x47, 0x41, 0x28, 0x83, 0x0c, 0x81, 0xe6, 0x59, + 0x50, 0x89, 0xff, 0x20, 0xc3, 0xc0, 0x7d, 0x16, 0x4c, 0xe2, 0x6f, 0x43, + 0x00, 0xfe, 0x83, 0x0c, 0xc6, 0x17, 0x06, 0x16, 0x44, 0xe2, 0x6f, 0x43, + 0x00, 0xfe, 0x83, 0x0c, 0x89, 0x18, 0x8c, 0x81, 0x05, 0x8f, 0xf8, 0xdb, + 0x10, 0x80, 0xff, 0x2e, 0x44, 0x1b, 0xcc, 0xc1, 0x1d, 0xac, 0x01, 0x05, + 0xa1, 0x0c, 0x32, 0x04, 0x67, 0xb0, 0x06, 0x16, 0x88, 0x81, 0xf8, 0x0f, + 0x32, 0x0c, 0x69, 0xc0, 0x06, 0x16, 0x80, 0x81, 0xf8, 0x0f, 0x32, 0x14, + 0x6b, 0xd0, 0x06, 0x16, 0x74, 0xe2, 0x3f, 0xc8, 0x70, 0xb4, 0x81, 0x1b, + 0x58, 0xa0, 0x89, 0xff, 0x20, 0xc3, 0x1e, 0xb8, 0xc1, 0x1c, 0x58, 0x16, + 0x88, 0xff, 0x20, 0x43, 0x1f, 0xc0, 0x01, 0x1d, 0x98, 0x13, 0x88, 0xbf, + 0x25, 0x03, 0xf8, 0x5b, 0xc0, 0x80, 0xbf, 0x05, 0x09, 0xf8, 0x5b, 0x80, + 0x80, 0xbf, 0x05, 0x05, 0xf8, 0xcf, 0x36, 0xd8, 0x41, 0x00, 0xcc, 0x36, + 0x04, 0xa4, 0x10, 0xcc, 0x36, 0x04, 0xa4, 0x20, 0x64, 0x10, 0x10, 0x03, + 0x09, 0x00, 0x00, 0x00, 0x5b, 0x86, 0x20, 0xf0, 0x83, 0x2d, 0xc3, 0x10, + 0xf8, 0xc1, 0x96, 0xe1, 0x08, 0xfc, 0x60, 0xcb, 0xc0, 0x04, 0x7e, 0xb0, + 0x65, 0x88, 0x02, 0x3f, 0xd8, 0x32, 0x58, 0x81, 0x1f, 0x6c, 0x19, 0xc6, + 0x20, 0xf0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x32, 0x0e, 0x10, 0x22, 0x84, 0x00, 0xa4, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x0c, 0x00, 0x00, + 0x1d, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0xe8, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, + 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x5d, 0x0c, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0x78, + 0x00, 0x00, 0x00, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x43, 0x6f, 0x70, 0x79, + 0x5f, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x33, 0x31, 0x30, 0x30, 0x31, + 0x2e, 0x35, 0x30, 0x2e, 0x31, 0x61, 0x69, 0x72, 0x36, 0x34, 0x2d, 0x61, + 0x70, 0x70, 0x6c, 0x65, 0x2d, 0x69, 0x6f, 0x73, 0x31, 0x33, 0x2e, 0x30, + 0x2e, 0x30, 0x2d, 0x73, 0x69, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x6f, 0x72, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x14, 0x0a, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x42, 0x43, 0xc0, 0xde, 0x35, 0x14, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x62, 0x0c, 0x30, 0x24, 0x80, 0x10, 0x05, 0xc8, 0x14, 0x00, 0x00, 0x00, + 0x21, 0x0c, 0x00, 0x00, 0x4a, 0x02, 0x00, 0x00, 0x0b, 0x02, 0x21, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, + 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, + 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x10, 0x45, 0x02, + 0x42, 0x92, 0x0b, 0x42, 0x84, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, + 0x0a, 0x32, 0x42, 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, + 0x00, 0x19, 0x32, 0x42, 0x04, 0x49, 0x0e, 0x90, 0x11, 0x22, 0xc4, 0x50, + 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x21, 0x46, 0x06, + 0x51, 0x18, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x1b, 0xcc, 0x25, 0xf8, + 0xff, 0xff, 0xff, 0xff, 0x01, 0x80, 0x03, 0x40, 0x02, 0x28, 0x62, 0x1c, + 0xde, 0x41, 0x1e, 0xe4, 0xa1, 0x1c, 0xc6, 0x81, 0x1e, 0xd8, 0x21, 0x1f, + 0xda, 0x40, 0x1e, 0xde, 0xa1, 0x1e, 0xdc, 0x81, 0x1c, 0xca, 0x81, 0x1c, + 0xda, 0x80, 0x1c, 0xd2, 0xc1, 0x1e, 0xd2, 0x81, 0x1c, 0xca, 0xa1, 0x0d, + 0xe6, 0x21, 0x1e, 0xe4, 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, + 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, + 0x87, 0x72, 0x00, 0x08, 0x72, 0x48, 0x87, 0x79, 0x08, 0x07, 0x71, 0x60, + 0x87, 0x72, 0x68, 0x03, 0x7a, 0x08, 0x87, 0x74, 0x60, 0x87, 0x36, 0x18, + 0x87, 0x70, 0x60, 0x07, 0x76, 0x98, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, + 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1d, 0xca, 0x61, 0x1e, 0xe6, 0xa1, 0x0d, + 0xe0, 0x41, 0x1e, 0xca, 0x61, 0x1c, 0xd2, 0x61, 0x1e, 0xca, 0xa1, 0x0d, + 0xcc, 0x01, 0x1e, 0xda, 0x21, 0x1c, 0xc8, 0x01, 0x30, 0x87, 0x70, 0x60, + 0x87, 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x73, 0x90, + 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, 0x78, 0x78, 0x87, 0x74, 0x70, + 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, 0x72, 0x60, 0x87, 0x74, 0x68, + 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x18, 0xdc, 0xe1, 0x1d, + 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, + 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, + 0xd8, 0x21, 0x1d, 0xda, 0xa1, 0x0d, 0xdc, 0xe1, 0x1d, 0xdc, 0xa1, 0x0d, + 0xd8, 0xa1, 0x1c, 0xc2, 0xc1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, + 0xd2, 0xc1, 0x1d, 0xcc, 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, + 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, + 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x75, 0xa8, 0x87, 0x76, 0x80, + 0x87, 0x36, 0xa0, 0x87, 0x70, 0x10, 0x07, 0x76, 0x28, 0x87, 0x79, 0x00, + 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, + 0xda, 0xc0, 0x1d, 0xc2, 0xc1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, + 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, + 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x98, 0x87, 0x74, 0x38, + 0x07, 0x77, 0x28, 0x07, 0x72, 0x68, 0x03, 0x7d, 0x28, 0x07, 0x79, 0x78, + 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, + 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, + 0xde, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0x01, 0x1e, 0xe0, 0x21, 0x1d, + 0xdc, 0xe1, 0x1c, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, + 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x88, 0x79, 0xa0, 0x87, 0x70, 0x18, + 0x87, 0x75, 0x68, 0x03, 0x78, 0x90, 0x87, 0x77, 0xa0, 0x87, 0x72, 0x18, + 0x07, 0x7a, 0x78, 0x07, 0x79, 0x68, 0x03, 0x71, 0xa8, 0x07, 0x73, 0x30, + 0x87, 0x72, 0x90, 0x87, 0x36, 0x98, 0x87, 0x74, 0xd0, 0x87, 0x72, 0x00, + 0xf0, 0x00, 0x20, 0xea, 0xc1, 0x1d, 0xe6, 0x21, 0x1c, 0xcc, 0xa1, 0x1c, + 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, + 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0xa8, 0x87, 0x79, 0x28, + 0x87, 0x36, 0x98, 0x87, 0x77, 0x30, 0x07, 0x7a, 0x68, 0x03, 0x73, 0x60, + 0x87, 0x77, 0x08, 0x07, 0x7a, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, + 0xca, 0x01, 0xd8, 0x40, 0x08, 0x02, 0x60, 0x01, 0x49, 0x18, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x13, 0x84, 0x40, 0x00, 0x89, 0x20, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x32, 0x22, 0x08, 0x09, 0x20, 0x64, 0x85, 0x04, + 0x13, 0x22, 0xa4, 0x84, 0x04, 0x13, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, + 0x12, 0x4c, 0x88, 0x8c, 0x0b, 0x84, 0x84, 0x4c, 0x10, 0x24, 0x33, 0x00, + 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, 0x00, 0x65, 0x08, 0x09, 0x9a, 0x81, + 0x80, 0x39, 0x02, 0x30, 0x48, 0x01, 0x1b, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x13, 0xbe, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, + 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, 0x87, 0x79, + 0x88, 0x83, 0x39, 0x70, 0x03, 0x38, 0x70, 0x03, 0x38, 0x68, 0x83, 0x79, + 0x48, 0x87, 0x76, 0xa8, 0x07, 0x76, 0x08, 0x07, 0x7a, 0x78, 0x07, 0x79, + 0xd8, 0x70, 0x1b, 0xe5, 0xd0, 0x06, 0xf0, 0xa0, 0x07, 0x76, 0x40, 0x07, + 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x90, 0x0e, + 0x71, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x80, 0x07, + 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, + 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x90, 0x0e, + 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, + 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, + 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, + 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x76, 0x40, 0x07, + 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, + 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, + 0x6d, 0x60, 0x0f, 0x72, 0x40, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, + 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, + 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x74, 0x80, 0x07, + 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, + 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, + 0x6d, 0x60, 0x0f, 0x79, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, + 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x20, 0x07, + 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, + 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x79, 0x20, 0x07, 0x7a, 0x20, 0x07, + 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, 0x0f, + 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, + 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x50, 0x07, 0x71, 0x20, 0x07, + 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, + 0x6d, 0x60, 0x0f, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, 0x07, + 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, + 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, + 0x72, 0xa0, 0x11, 0xc2, 0x90, 0x12, 0xdb, 0x95, 0x3f, 0xeb, 0x2c, 0xc8, + 0xf0, 0x17, 0x11, 0x60, 0x30, 0x44, 0x33, 0x0d, 0x89, 0x00, 0x69, 0x00, + 0x00, 0x20, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x89, 0x0d, + 0x02, 0x45, 0x99, 0x04, 0x00, 0x00, 0xb2, 0x40, 0x07, 0x00, 0x00, 0x00, + 0x32, 0x1e, 0x98, 0x0c, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, + 0xc6, 0x04, 0x43, 0xb2, 0x22, 0x28, 0x81, 0x42, 0x18, 0x01, 0xa0, 0x1b, + 0x4b, 0x70, 0x08, 0x00, 0xb1, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, + 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, + 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, + 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, + 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, + 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, + 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, + 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, + 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, + 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, + 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, + 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, + 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, + 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, + 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, + 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, + 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, + 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, + 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, + 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, + 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, + 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, + 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, + 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, + 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, + 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, + 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, + 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, + 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, + 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, + 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, + 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, + 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, + 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, + 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, + 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, + 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, + 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, + 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, + 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, + 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, + 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, + 0x79, 0x20, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x32, 0x9a, 0x08, 0x14, + 0x02, 0x85, 0x8c, 0x27, 0x46, 0x46, 0xc8, 0x11, 0x32, 0x64, 0xd4, 0x26, + 0xc8, 0x56, 0x00, 0x00, 0x8b, 0x02, 0x07, 0xc5, 0xc6, 0x91, 0x41, 0x14, + 0x19, 0x52, 0xa6, 0x3c, 0x06, 0x83, 0x58, 0x05, 0x53, 0x44, 0x4b, 0x20, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x77, 0x63, 0x68, 0x61, 0x72, + 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x4c, + 0x4c, 0x56, 0x4d, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, + 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x20, 0x28, 0x6d, 0x65, + 0x74, 0x61, 0x6c, 0x66, 0x65, 0x2d, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, + 0x35, 0x30, 0x2e, 0x31, 0x29, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x61, 0x69, + 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x64, 0x65, + 0x6e, 0x6f, 0x72, 0x6d, 0x73, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, + 0x65, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, + 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, 0x65, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, + 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x62, 0x75, + 0x66, 0x66, 0x65, 0x72, 0x5f, 0x66, 0x65, 0x74, 0x63, 0x68, 0x5f, 0x65, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x72, 0x65, 0x6e, + 0x64, 0x65, 0x72, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x61, 0x69, + 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x61, 0x69, 0x72, + 0x2e, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x6e, + 0x70, 0x75, 0x74, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, + 0x28, 0x38, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x76, + 0x32, 0x5f, 0x66, 0x29, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x65, 0x6e, 0x74, + 0x65, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x70, 0x65, 0x72, 0x73, 0x70, 0x65, + 0x63, 0x74, 0x69, 0x76, 0x65, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x61, + 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x70, + 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x67, 0x65, 0x6e, 0x65, 0x72, + 0x61, 0x74, 0x65, 0x64, 0x28, 0x35, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x44, + 0x76, 0x34, 0x5f, 0x66, 0x29, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, + 0x23, 0x08, 0x46, 0x30, 0x82, 0x70, 0x14, 0x23, 0x08, 0x86, 0x30, 0x82, + 0x60, 0x0c, 0x23, 0x08, 0x06, 0x31, 0x82, 0x40, 0x00, 0x33, 0x0c, 0x54, + 0x50, 0xcd, 0x30, 0x58, 0xc2, 0x35, 0x43, 0x30, 0xcc, 0x30, 0x50, 0x14, + 0x36, 0x03, 0x41, 0x58, 0x16, 0x36, 0x43, 0x50, 0xcc, 0x10, 0x18, 0x33, + 0x04, 0xc7, 0x0c, 0x05, 0x82, 0x61, 0x89, 0x32, 0x43, 0x20, 0x06, 0x33, + 0x24, 0xd8, 0xc2, 0x34, 0x4e, 0xf2, 0x40, 0xd1, 0x0c, 0x89, 0xb5, 0x48, + 0x8d, 0x93, 0x28, 0xd0, 0x34, 0x83, 0x40, 0x06, 0x65, 0x30, 0xc3, 0x90, + 0x8d, 0x81, 0x19, 0xc8, 0x48, 0x60, 0x82, 0x2e, 0x62, 0x63, 0xb3, 0x6b, + 0x73, 0x69, 0x7b, 0x23, 0xab, 0x63, 0x2b, 0x73, 0x31, 0x63, 0x0b, 0x3b, + 0x9b, 0x1b, 0x45, 0xc8, 0xb4, 0x53, 0xd8, 0xd8, 0xec, 0xda, 0x5c, 0xd2, + 0xc8, 0xca, 0xdc, 0xe8, 0x46, 0x09, 0xb6, 0x5b, 0xc2, 0xd2, 0xe4, 0x5c, + 0xec, 0xca, 0xe4, 0xe6, 0xd2, 0xde, 0xdc, 0x46, 0x09, 0xb8, 0xa3, 0xc2, + 0xd2, 0xe4, 0x5c, 0xd8, 0xc2, 0xdc, 0xce, 0xea, 0xc2, 0xce, 0xca, 0xbe, + 0xec, 0xca, 0xe4, 0xe6, 0xd2, 0xde, 0xdc, 0x46, 0x09, 0xba, 0x9b, 0xc2, + 0xd2, 0xe4, 0x5c, 0xc6, 0xde, 0xda, 0xe0, 0xd2, 0xd8, 0xca, 0xbe, 0xde, + 0xe0, 0xe8, 0xd2, 0xde, 0xdc, 0xe6, 0x46, 0x19, 0xbc, 0x0f, 0x0c, 0x8e, + 0x09, 0x4b, 0x93, 0x73, 0x31, 0x93, 0x0b, 0x3b, 0x6b, 0x2b, 0x73, 0xa3, + 0x1b, 0x25, 0x30, 0x03, 0x00, 0x00, 0x00, 0x00, 0xa9, 0x18, 0x00, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x0a, 0x72, 0x28, 0x87, 0x77, 0x80, 0x07, + 0x7a, 0x58, 0x70, 0x98, 0x43, 0x3d, 0xb8, 0xc3, 0x38, 0xb0, 0x43, 0x39, + 0xd0, 0xc3, 0x82, 0xe6, 0x1c, 0xc6, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, + 0xc1, 0x1d, 0xe6, 0x21, 0x1d, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x00, + 0xd1, 0x10, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0xcc, 0x3c, 0xa4, + 0x83, 0x3b, 0x9c, 0x03, 0x3b, 0x94, 0x03, 0x3d, 0xa0, 0x83, 0x3c, 0x94, + 0x43, 0x38, 0x90, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x71, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x32, 0x0e, 0x10, 0x22, + 0x84, 0x00, 0xc8, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x65, 0x0c, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0xe8, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x24, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x5d, 0x0c, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x12, 0x03, 0x94, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x53, 0x44, 0x4c, 0x5f, + 0x53, 0x6f, 0x6c, 0x69, 0x64, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, + 0x6e, 0x74, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x2e, 0x31, + 0x61, 0x69, 0x72, 0x36, 0x34, 0x2d, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2d, + 0x69, 0x6f, 0x73, 0x31, 0x33, 0x2e, 0x30, 0x2e, 0x30, 0x2d, 0x73, 0x69, + 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, + 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xa8, 0x0b, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x35, 0x14, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x62, 0x0c, 0x30, 0x24, 0x80, 0x10, 0x05, 0xc8, + 0x14, 0x00, 0x00, 0x00, 0x21, 0x0c, 0x00, 0x00, 0xa2, 0x02, 0x00, 0x00, + 0x0b, 0x02, 0x21, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, + 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, + 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, + 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88, 0x48, 0x90, 0x14, 0x20, + 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0x04, 0x49, 0x0e, 0x90, + 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, + 0x04, 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, + 0x1b, 0xcc, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x58, 0x03, 0x40, + 0x02, 0x2a, 0x62, 0x1c, 0xde, 0x41, 0x1e, 0xe4, 0xa1, 0x1c, 0xc6, 0x81, + 0x1e, 0xd8, 0x21, 0x1f, 0xda, 0x40, 0x1e, 0xde, 0xa1, 0x1e, 0xdc, 0x81, + 0x1c, 0xca, 0x81, 0x1c, 0xda, 0x80, 0x1c, 0xd2, 0xc1, 0x1e, 0xd2, 0x81, + 0x1c, 0xca, 0xa1, 0x0d, 0xe6, 0x21, 0x1e, 0xe4, 0x81, 0x1e, 0xda, 0xc0, + 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x73, + 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x72, 0x48, 0x87, 0x79, + 0x08, 0x07, 0x71, 0x60, 0x87, 0x72, 0x68, 0x03, 0x7a, 0x08, 0x87, 0x74, + 0x60, 0x87, 0x36, 0x18, 0x87, 0x70, 0x60, 0x07, 0x76, 0x98, 0x07, 0xc0, + 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1d, 0xca, 0x61, + 0x1e, 0xe6, 0xa1, 0x0d, 0xe0, 0x41, 0x1e, 0xca, 0x61, 0x1c, 0xd2, 0x61, + 0x1e, 0xca, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0x21, 0x1c, 0xc8, 0x01, + 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, + 0x68, 0x03, 0x73, 0x90, 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, 0x78, + 0x78, 0x87, 0x74, 0x70, 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, 0x72, + 0x60, 0x87, 0x74, 0x68, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, + 0x18, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1, + 0x1c, 0xda, 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, + 0x1e, 0xda, 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, 0xa1, 0x0d, 0xdc, 0xe1, + 0x1d, 0xdc, 0xa1, 0x0d, 0xd8, 0xa1, 0x1c, 0xc2, 0xc1, 0x1c, 0x00, 0xc2, + 0x1d, 0xde, 0xa1, 0x0d, 0xd2, 0xc1, 0x1d, 0xcc, 0x61, 0x1e, 0xda, 0xc0, + 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, + 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x75, + 0xa8, 0x87, 0x76, 0x80, 0x87, 0x36, 0xa0, 0x87, 0x70, 0x10, 0x07, 0x76, + 0x28, 0x87, 0x79, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, + 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1d, 0xc2, 0xc1, 0x1d, 0xe6, 0xa1, + 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, + 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, + 0x98, 0x87, 0x74, 0x38, 0x07, 0x77, 0x28, 0x07, 0x72, 0x68, 0x03, 0x7d, + 0x28, 0x07, 0x79, 0x78, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, + 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, + 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0x01, + 0x1e, 0xe0, 0x21, 0x1d, 0xdc, 0xe1, 0x1c, 0xda, 0xa0, 0x1d, 0xc2, 0x81, + 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x88, 0x79, + 0xa0, 0x87, 0x70, 0x18, 0x87, 0x75, 0x68, 0x03, 0x78, 0x90, 0x87, 0x77, + 0xa0, 0x87, 0x72, 0x18, 0x07, 0x7a, 0x78, 0x07, 0x79, 0x68, 0x03, 0x71, + 0xa8, 0x07, 0x73, 0x30, 0x87, 0x72, 0x90, 0x87, 0x36, 0x98, 0x87, 0x74, + 0xd0, 0x87, 0x72, 0x00, 0xf0, 0x00, 0x20, 0xea, 0xc1, 0x1d, 0xe6, 0x21, + 0x1c, 0xcc, 0xa1, 0x1c, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, + 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, + 0xa8, 0x87, 0x79, 0x28, 0x87, 0x36, 0x98, 0x87, 0x77, 0x30, 0x07, 0x7a, + 0x68, 0x03, 0x73, 0x60, 0x87, 0x77, 0x08, 0x07, 0x7a, 0x00, 0xcc, 0x21, + 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0xd8, 0x60, 0x08, 0x04, 0xb0, 0x00, + 0xd5, 0x06, 0x63, 0x28, 0x80, 0x05, 0xa8, 0x36, 0x28, 0xc4, 0xff, 0xff, + 0xff, 0xff, 0x0f, 0x40, 0x1b, 0x00, 0x6b, 0x00, 0x48, 0x40, 0xb5, 0xc1, + 0x28, 0x02, 0x60, 0x01, 0xaa, 0x0d, 0x86, 0x21, 0x00, 0x0b, 0x50, 0x01, + 0x49, 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x86, 0x40, 0x18, + 0x26, 0x0c, 0x44, 0x61, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, + 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, + 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x4c, 0x33, 0x00, + 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, 0x00, 0x47, 0x49, 0x53, 0x44, 0x09, + 0x93, 0xff, 0x4f, 0xc4, 0x35, 0x51, 0x11, 0xf1, 0xdb, 0xc3, 0x3f, 0x8d, + 0x11, 0x00, 0x83, 0x08, 0x43, 0x70, 0x91, 0x34, 0x45, 0x94, 0x30, 0xf9, + 0xbf, 0x04, 0x30, 0xcf, 0x42, 0x44, 0xff, 0x34, 0x46, 0x00, 0x0c, 0x22, + 0x14, 0x42, 0x31, 0x42, 0x08, 0x82, 0x18, 0x3a, 0x73, 0x04, 0x88, 0x11, + 0x42, 0x9a, 0x23, 0x08, 0xe6, 0x08, 0xc0, 0x60, 0x18, 0x41, 0x60, 0x8a, + 0xa2, 0x88, 0x11, 0xab, 0x2d, 0x00, 0x18, 0xb9, 0x81, 0x80, 0x14, 0x60, + 0x23, 0x00, 0x00, 0x00, 0x13, 0xbe, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, + 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, + 0x74, 0x78, 0x87, 0x79, 0x88, 0x83, 0x39, 0x70, 0x03, 0x38, 0x70, 0x03, + 0x38, 0x68, 0x83, 0x79, 0x48, 0x87, 0x76, 0xa8, 0x07, 0x76, 0x08, 0x07, + 0x7a, 0x78, 0x07, 0x79, 0xd8, 0x70, 0x1b, 0xe5, 0xd0, 0x06, 0xf0, 0xa0, + 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, + 0x06, 0xe9, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, + 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, + 0x07, 0x6d, 0x90, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, + 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, + 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, + 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, + 0x07, 0x71, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x40, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x73, 0x20, + 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, + 0x0f, 0x74, 0x80, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x6d, 0x60, 0x0f, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, + 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x79, 0x60, 0x07, 0x7a, 0x10, + 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, + 0x0f, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, + 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x79, 0x20, + 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, + 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, + 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x50, + 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, + 0x07, 0x71, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x00, 0x07, 0x72, 0x40, + 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, + 0x07, 0x72, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, + 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x11, 0xc2, 0x90, 0x11, 0xdb, 0x95, + 0x3f, 0xe7, 0x3c, 0xd8, 0x5f, 0x44, 0x80, 0xc1, 0x10, 0xcd, 0x34, 0x24, + 0x02, 0xa2, 0x03, 0x00, 0x80, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x86, 0x44, 0xd1, 0xe6, 0x00, 0x01, 0x20, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x80, 0xc4, 0x06, 0x81, 0xa2, 0xa4, 0x02, 0x00, 0x00, + 0x59, 0x20, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, + 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x62, + 0x45, 0x50, 0x02, 0x85, 0x30, 0x02, 0x50, 0x06, 0x14, 0xc7, 0x12, 0x1c, + 0x02, 0x00, 0x00, 0x00, 0xb1, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, + 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, + 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, + 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, + 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, + 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, + 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, + 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, + 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, + 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, + 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, + 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, + 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, + 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, + 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, + 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, + 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, + 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, + 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, + 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, + 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, + 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, + 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, + 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, + 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, + 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, + 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, + 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, + 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, + 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, + 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, + 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, + 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, + 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, + 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, + 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, + 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, + 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, + 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, + 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, + 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, + 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, + 0x79, 0x20, 0x00, 0x00, 0xbe, 0x00, 0x00, 0x00, 0x32, 0x9a, 0x08, 0x14, + 0x02, 0x85, 0x8c, 0x27, 0x46, 0x46, 0xc8, 0x11, 0x32, 0x64, 0xd4, 0x3c, + 0x2c, 0x77, 0x00, 0x00, 0x8b, 0x02, 0x07, 0xc5, 0xc6, 0x91, 0x41, 0x14, + 0x19, 0x8c, 0x22, 0x31, 0x88, 0x64, 0x3d, 0x45, 0x66, 0x20, 0x8b, 0xa4, + 0x60, 0xc3, 0x72, 0x04, 0x53, 0x44, 0x4b, 0x20, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x77, 0x63, 0x68, 0x61, 0x72, 0x5f, 0x73, 0x69, 0x7a, + 0x65, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x4c, 0x4c, 0x56, 0x4d, 0x20, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x33, 0x31, 0x30, 0x30, + 0x31, 0x2e, 0x35, 0x30, 0x20, 0x28, 0x6d, 0x65, 0x74, 0x61, 0x6c, 0x66, + 0x65, 0x2d, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x2e, 0x31, + 0x29, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, + 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x64, 0x65, 0x6e, 0x6f, 0x72, 0x6d, + 0x73, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, + 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, + 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, + 0x2e, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, + 0x5f, 0x66, 0x65, 0x74, 0x63, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x61, 0x69, 0x72, 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x5f, + 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, + 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x66, + 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x61, 0x69, 0x72, 0x2e, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x65, 0x6e, + 0x74, 0x65, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x6e, 0x6f, 0x5f, 0x70, 0x65, + 0x72, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x61, 0x69, 0x72, + 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x69, 0x72, 0x2e, 0x66, 0x72, 0x61, + 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x67, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x35, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x44, 0x76, 0x34, 0x5f, 0x66, 0x29, 0x61, 0x69, 0x72, + 0x2e, 0x70, 0x65, 0x72, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, + 0x65, 0x64, 0x28, 0x38, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, + 0x44, 0x76, 0x32, 0x5f, 0x66, 0x29, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, + 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x61, 0x69, 0x72, 0x2e, + 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x6c, + 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x61, 0x69, 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x74, + 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x32, 0x64, 0x3c, 0x66, 0x6c, 0x6f, + 0x61, 0x74, 0x2c, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x3e, 0x74, + 0x65, 0x78, 0x61, 0x69, 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, + 0x72, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x73, 0x00, 0x00, 0x00, + 0x23, 0x08, 0x8c, 0x30, 0x82, 0x10, 0x1d, 0x23, 0x08, 0xcc, 0x30, 0x82, + 0xc0, 0x10, 0x23, 0x08, 0x4c, 0x31, 0x82, 0x80, 0x00, 0x23, 0x08, 0x8c, + 0x31, 0xc3, 0xf0, 0x05, 0x60, 0x30, 0xc3, 0x10, 0x06, 0x82, 0x18, 0xcc, + 0x10, 0x0c, 0x33, 0x0c, 0xdf, 0x37, 0x06, 0x33, 0x10, 0x44, 0x18, 0x84, + 0xc1, 0x18, 0xcc, 0x10, 0x14, 0x33, 0x04, 0xc6, 0x0c, 0xc1, 0x31, 0x43, + 0x81, 0x8c, 0xc1, 0x18, 0x24, 0xca, 0x0c, 0x81, 0x1b, 0xcc, 0x80, 0x8c, + 0xc1, 0xc2, 0x34, 0x89, 0xe2, 0x3c, 0x33, 0x24, 0x61, 0x00, 0x45, 0x8c, + 0x94, 0x28, 0xce, 0x34, 0x43, 0xf2, 0x41, 0x14, 0x23, 0x25, 0x95, 0x63, + 0xcd, 0xa0, 0x94, 0xc1, 0x85, 0x8d, 0x41, 0x18, 0x64, 0x89, 0xe6, 0x6c, + 0x33, 0x24, 0x62, 0xc0, 0x61, 0x63, 0x10, 0x06, 0x49, 0xe7, 0x78, 0x33, + 0x14, 0x70, 0x10, 0x07, 0x72, 0x30, 0x07, 0x74, 0x30, 0xc3, 0x40, 0x06, + 0x6f, 0x50, 0x07, 0x32, 0x12, 0x98, 0xa0, 0x8b, 0xd8, 0xd8, 0xec, 0xda, + 0x5c, 0xda, 0xde, 0xc8, 0xea, 0xd8, 0xca, 0x5c, 0xcc, 0xd8, 0xc2, 0xce, + 0xe6, 0x46, 0x11, 0xca, 0xc0, 0x0c, 0x4e, 0x61, 0x63, 0xb3, 0x6b, 0x73, + 0x49, 0x23, 0x2b, 0x73, 0xa3, 0x1b, 0x25, 0x38, 0x83, 0x5b, 0xc2, 0xd2, + 0xe4, 0x5c, 0xec, 0xca, 0xe4, 0xe6, 0xd2, 0xde, 0xdc, 0x46, 0x09, 0xd0, + 0xe0, 0xa8, 0xb0, 0x34, 0x39, 0x17, 0xb6, 0x30, 0xb7, 0xb3, 0xba, 0xb0, + 0xb3, 0xb2, 0x2f, 0xbb, 0x32, 0xb9, 0xb9, 0xb4, 0x37, 0xb7, 0x51, 0x82, + 0x34, 0xb8, 0x29, 0x2c, 0x4d, 0xce, 0x65, 0xec, 0xad, 0x0d, 0x2e, 0x8d, + 0xad, 0xec, 0xeb, 0x0d, 0x8e, 0x2e, 0xed, 0xcd, 0x6d, 0x6e, 0x94, 0x41, + 0x0d, 0xd6, 0x80, 0x0d, 0x8e, 0x09, 0x4b, 0x93, 0x73, 0x31, 0x93, 0x0b, + 0x3b, 0x6b, 0x2b, 0x73, 0xa3, 0x1b, 0x25, 0xa8, 0x03, 0x00, 0x00, 0x00, + 0xa9, 0x18, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x0a, 0x72, 0x28, + 0x87, 0x77, 0x80, 0x07, 0x7a, 0x58, 0x70, 0x98, 0x43, 0x3d, 0xb8, 0xc3, + 0x38, 0xb0, 0x43, 0x39, 0xd0, 0xc3, 0x82, 0xe6, 0x1c, 0xc6, 0xa1, 0x0d, + 0xe8, 0x41, 0x1e, 0xc2, 0xc1, 0x1d, 0xe6, 0x21, 0x1d, 0xe8, 0x21, 0x1d, + 0xde, 0xc1, 0x1d, 0x00, 0xd1, 0x10, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x07, 0xcc, 0x3c, 0xa4, 0x83, 0x3b, 0x9c, 0x03, 0x3b, 0x94, 0x03, 0x3d, + 0xa0, 0x83, 0x3c, 0x94, 0x43, 0x38, 0x90, 0xc3, 0x01, 0x00, 0x00, 0x00, + 0x61, 0x20, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, + 0x10, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xb4, 0x6a, 0x60, 0x04, + 0x80, 0xda, 0x08, 0x00, 0x81, 0x11, 0x00, 0x00, 0x23, 0x06, 0x8d, 0x10, + 0x82, 0x60, 0xe0, 0x40, 0x46, 0x71, 0x10, 0xc2, 0x10, 0x04, 0xcc, 0x68, + 0x42, 0x00, 0x58, 0xa0, 0x88, 0x7f, 0x06, 0x00, 0x71, 0x20, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x32, 0x0e, 0x10, 0x22, 0x84, 0x00, 0x96, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x0c, 0x00, 0x00, + 0x23, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0x20, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, + 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x24, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x1b, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x08, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x5d, 0x0c, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0xb5, + 0x00, 0x00, 0x00, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x43, 0x6f, 0x70, 0x79, + 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x69, 0x72, + 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x74, 0x65, 0x78, 0x74, + 0x75, 0x72, 0x65, 0x5f, 0x32, 0x64, 0x2e, 0x76, 0x34, 0x66, 0x33, 0x32, + 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x2e, 0x31, 0x61, 0x69, + 0x72, 0x36, 0x34, 0x2d, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2d, 0x69, 0x6f, + 0x73, 0x31, 0x33, 0x2e, 0x30, 0x2e, 0x30, 0x2d, 0x73, 0x69, 0x6d, 0x75, + 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0xb8, 0x0e, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x42, 0x43, 0xc0, 0xde, 0x35, 0x14, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x62, 0x0c, 0x30, 0x24, 0x80, 0x10, 0x05, 0xc8, 0x14, 0x00, 0x00, 0x00, + 0x21, 0x0c, 0x00, 0x00, 0x4f, 0x03, 0x00, 0x00, 0x0b, 0x02, 0x21, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, + 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, + 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x18, 0x45, 0x02, + 0x42, 0x92, 0x0b, 0x42, 0xc4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, + 0x0a, 0x32, 0x62, 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, + 0x00, 0x19, 0x32, 0x42, 0x04, 0x49, 0x0e, 0x90, 0x11, 0x23, 0xc4, 0x50, + 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x31, 0x46, 0x06, + 0x51, 0x18, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x1b, 0xcc, 0x25, 0xf8, + 0xff, 0xff, 0xff, 0xff, 0x01, 0x58, 0x03, 0x40, 0x02, 0x2a, 0x62, 0x1c, + 0xde, 0x41, 0x1e, 0xe4, 0xa1, 0x1c, 0xc6, 0x81, 0x1e, 0xd8, 0x21, 0x1f, + 0xda, 0x40, 0x1e, 0xde, 0xa1, 0x1e, 0xdc, 0x81, 0x1c, 0xca, 0x81, 0x1c, + 0xda, 0x80, 0x1c, 0xd2, 0xc1, 0x1e, 0xd2, 0x81, 0x1c, 0xca, 0xa1, 0x0d, + 0xe6, 0x21, 0x1e, 0xe4, 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, + 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, + 0x87, 0x72, 0x00, 0x08, 0x72, 0x48, 0x87, 0x79, 0x08, 0x07, 0x71, 0x60, + 0x87, 0x72, 0x68, 0x03, 0x7a, 0x08, 0x87, 0x74, 0x60, 0x87, 0x36, 0x18, + 0x87, 0x70, 0x60, 0x07, 0x76, 0x98, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, + 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1d, 0xca, 0x61, 0x1e, 0xe6, 0xa1, 0x0d, + 0xe0, 0x41, 0x1e, 0xca, 0x61, 0x1c, 0xd2, 0x61, 0x1e, 0xca, 0xa1, 0x0d, + 0xcc, 0x01, 0x1e, 0xda, 0x21, 0x1c, 0xc8, 0x01, 0x30, 0x87, 0x70, 0x60, + 0x87, 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x73, 0x90, + 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, 0x78, 0x78, 0x87, 0x74, 0x70, + 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, 0x72, 0x60, 0x87, 0x74, 0x68, + 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x18, 0xdc, 0xe1, 0x1d, + 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, + 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, + 0xd8, 0x21, 0x1d, 0xda, 0xa1, 0x0d, 0xdc, 0xe1, 0x1d, 0xdc, 0xa1, 0x0d, + 0xd8, 0xa1, 0x1c, 0xc2, 0xc1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, + 0xd2, 0xc1, 0x1d, 0xcc, 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, + 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, + 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x75, 0xa8, 0x87, 0x76, 0x80, + 0x87, 0x36, 0xa0, 0x87, 0x70, 0x10, 0x07, 0x76, 0x28, 0x87, 0x79, 0x00, + 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, + 0xda, 0xc0, 0x1d, 0xc2, 0xc1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, + 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, + 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x98, 0x87, 0x74, 0x38, + 0x07, 0x77, 0x28, 0x07, 0x72, 0x68, 0x03, 0x7d, 0x28, 0x07, 0x79, 0x78, + 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, + 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, + 0xde, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0x01, 0x1e, 0xe0, 0x21, 0x1d, + 0xdc, 0xe1, 0x1c, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, + 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x88, 0x79, 0xa0, 0x87, 0x70, 0x18, + 0x87, 0x75, 0x68, 0x03, 0x78, 0x90, 0x87, 0x77, 0xa0, 0x87, 0x72, 0x18, + 0x07, 0x7a, 0x78, 0x07, 0x79, 0x68, 0x03, 0x71, 0xa8, 0x07, 0x73, 0x30, + 0x87, 0x72, 0x90, 0x87, 0x36, 0x98, 0x87, 0x74, 0xd0, 0x87, 0x72, 0x00, + 0xf0, 0x00, 0x20, 0xea, 0xc1, 0x1d, 0xe6, 0x21, 0x1c, 0xcc, 0xa1, 0x1c, + 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, + 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0xa8, 0x87, 0x79, 0x28, + 0x87, 0x36, 0x98, 0x87, 0x77, 0x30, 0x07, 0x7a, 0x68, 0x03, 0x73, 0x60, + 0x87, 0x77, 0x08, 0x07, 0x7a, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, + 0xca, 0x01, 0xd8, 0xb0, 0x08, 0x04, 0x90, 0x00, 0x0b, 0x50, 0x05, 0x69, + 0x00, 0x0a, 0x1b, 0x8c, 0xa1, 0x00, 0x16, 0xa0, 0xda, 0x60, 0x10, 0x07, + 0xb0, 0x00, 0xd5, 0x06, 0xa3, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x90, + 0x00, 0x6a, 0x83, 0x62, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x00, 0xb4, 0x01, + 0xb0, 0x06, 0x80, 0x04, 0x54, 0x1b, 0x8c, 0x23, 0x00, 0x16, 0xa0, 0xda, + 0x60, 0x20, 0x02, 0xb0, 0x00, 0x15, 0x00, 0x00, 0x49, 0x18, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x13, 0x88, 0x40, 0x18, 0x88, 0x09, 0x41, 0x31, + 0x61, 0x30, 0x0e, 0x04, 0x89, 0x20, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, + 0x32, 0x22, 0x88, 0x09, 0x20, 0x64, 0x85, 0x04, 0x13, 0x23, 0xa4, 0x84, + 0x04, 0x13, 0x23, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8c, 0x8c, + 0x0b, 0x84, 0xc4, 0x4c, 0x10, 0x80, 0xc1, 0x0c, 0xc0, 0x30, 0x02, 0x01, + 0x0c, 0x23, 0x08, 0xc0, 0x30, 0xc2, 0x00, 0x1c, 0x24, 0x4d, 0x11, 0x25, + 0x4c, 0xbe, 0xec, 0xbe, 0x1d, 0x21, 0x38, 0x03, 0x81, 0x88, 0x61, 0x18, + 0x86, 0x41, 0x04, 0x42, 0x38, 0x4a, 0x9a, 0x22, 0x4a, 0x98, 0xfc, 0x7f, + 0x22, 0xae, 0x89, 0x8a, 0x88, 0xdf, 0x1e, 0xfe, 0x69, 0x8c, 0x00, 0x18, + 0x44, 0x30, 0x82, 0xd3, 0xa4, 0x29, 0xa2, 0x84, 0xc9, 0xff, 0x27, 0xe2, + 0x9a, 0xa8, 0x88, 0xf8, 0xed, 0xe1, 0x07, 0xa2, 0x08, 0xc0, 0xfe, 0x69, + 0x8c, 0x00, 0x18, 0x44, 0x40, 0x82, 0x8b, 0xa4, 0x29, 0xa2, 0x84, 0xc9, + 0xff, 0x25, 0x80, 0x79, 0x16, 0x22, 0xfa, 0xa7, 0x31, 0x02, 0x60, 0x10, + 0x41, 0x11, 0x0a, 0x12, 0x04, 0x81, 0x50, 0x1c, 0xc9, 0x42, 0x4c, 0x19, + 0x80, 0x61, 0x20, 0x67, 0x8e, 0x00, 0x31, 0x42, 0x00, 0xcd, 0x11, 0x80, + 0xc1, 0x1c, 0x41, 0x30, 0x8c, 0x20, 0x48, 0x65, 0x89, 0x92, 0x45, 0x90, + 0x26, 0x6a, 0x02, 0x00, 0x89, 0xaa, 0xa2, 0x44, 0xc7, 0x22, 0x4c, 0xd4, + 0x04, 0x00, 0x12, 0x5d, 0x03, 0x01, 0x29, 0x20, 0x0d, 0x23, 0x0c, 0xd2, + 0x1c, 0x01, 0x28, 0x0c, 0x22, 0x04, 0xc2, 0x20, 0xc2, 0x20, 0x8c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x13, 0xbe, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, + 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, + 0x74, 0x78, 0x87, 0x79, 0x88, 0x83, 0x39, 0x70, 0x03, 0x38, 0x70, 0x03, + 0x38, 0x68, 0x83, 0x79, 0x48, 0x87, 0x76, 0xa8, 0x07, 0x76, 0x08, 0x07, + 0x7a, 0x78, 0x07, 0x79, 0xd8, 0x70, 0x1b, 0xe5, 0xd0, 0x06, 0xf0, 0xa0, + 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, + 0x06, 0xe9, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, + 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, + 0x07, 0x6d, 0x90, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, + 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, + 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, + 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, + 0x07, 0x71, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x40, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x73, 0x20, + 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, + 0x0f, 0x74, 0x80, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x6d, 0x60, 0x0f, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, + 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x79, 0x60, 0x07, 0x7a, 0x10, + 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, + 0x0f, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, + 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x79, 0x20, + 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, + 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, + 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x50, + 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, + 0x07, 0x71, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x00, 0x07, 0x72, 0x40, + 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, + 0x07, 0x72, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, + 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x11, 0xc2, 0x90, 0x10, 0xdb, 0x95, + 0xbf, 0xec, 0xbe, 0x7f, 0x11, 0x01, 0x06, 0x43, 0x34, 0xd3, 0x90, 0x08, + 0x80, 0x18, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x18, 0x12, 0x41, 0x8d, 0x03, 0x04, 0x80, 0x00, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x43, 0xa2, 0x2e, 0x0c, 0x2a, 0x20, 0x00, 0x06, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x18, 0x12, 0xf9, 0xc1, 0x76, 0x01, + 0x01, 0x30, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x80, 0xc4, 0x06, + 0x81, 0xa2, 0x51, 0x03, 0x00, 0x00, 0x59, 0x20, 0x0a, 0x00, 0x00, 0x00, + 0x32, 0x1e, 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, + 0xc6, 0x04, 0x43, 0x92, 0x8a, 0xa0, 0x04, 0x0a, 0x61, 0x04, 0xa0, 0x0c, + 0x0a, 0x30, 0xa0, 0x40, 0x0a, 0xa8, 0xc0, 0x4a, 0xa1, 0x18, 0x48, 0x1b, + 0x4b, 0x70, 0x08, 0x00, 0xb1, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, + 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, + 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, + 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, + 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, + 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, + 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, + 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, + 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, + 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, + 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, + 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, + 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, + 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, + 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, + 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, + 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, + 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, + 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, + 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, + 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, + 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, + 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, + 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, + 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, + 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, + 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, + 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, + 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, + 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, + 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, + 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, + 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, + 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, + 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, + 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, + 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, + 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, + 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, + 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, + 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, + 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, + 0x79, 0x20, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x32, 0x9a, 0x08, 0x14, + 0x02, 0x85, 0x8c, 0x27, 0x46, 0x46, 0xc8, 0x11, 0x32, 0x64, 0xd4, 0xda, + 0x80, 0x0c, 0x66, 0x0a, 0x8b, 0x02, 0x07, 0xc5, 0xc6, 0x91, 0x41, 0x14, + 0x19, 0x8c, 0x22, 0x31, 0x88, 0x64, 0x3d, 0x45, 0x66, 0x20, 0xca, 0x23, + 0x21, 0x94, 0x61, 0x18, 0x86, 0x11, 0x5d, 0x89, 0xb1, 0x28, 0x18, 0xe1, + 0x15, 0xcb, 0x11, 0x00, 0x53, 0x44, 0x4b, 0x20, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x77, 0x63, 0x68, 0x61, 0x72, 0x5f, 0x73, 0x69, 0x7a, + 0x65, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x4c, 0x4c, 0x56, 0x4d, 0x20, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x33, 0x31, 0x30, 0x30, + 0x31, 0x2e, 0x35, 0x30, 0x20, 0x28, 0x6d, 0x65, 0x74, 0x61, 0x6c, 0x66, + 0x65, 0x2d, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x2e, 0x31, + 0x29, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, + 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x64, 0x65, 0x6e, 0x6f, 0x72, 0x6d, + 0x73, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, + 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, + 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, + 0x2e, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, + 0x5f, 0x66, 0x65, 0x74, 0x63, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x61, 0x69, 0x72, 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x5f, + 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, + 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x66, + 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x61, 0x69, 0x72, 0x2e, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x65, 0x6e, + 0x74, 0x65, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x6e, 0x6f, 0x5f, 0x70, 0x65, + 0x72, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x61, 0x69, 0x72, + 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x69, 0x72, 0x2e, 0x66, 0x72, 0x61, + 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x67, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x35, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x44, 0x76, 0x34, 0x5f, 0x66, 0x29, 0x61, 0x69, 0x72, + 0x2e, 0x70, 0x65, 0x72, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, + 0x65, 0x64, 0x28, 0x38, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, + 0x44, 0x76, 0x32, 0x5f, 0x66, 0x29, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, + 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x61, 0x69, 0x72, 0x2e, + 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, + 0x66, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x61, 0x69, 0x72, + 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, + 0x64, 0x65, 0x78, 0x61, 0x69, 0x72, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x61, + 0x69, 0x72, 0x2e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x66, 0x6c, 0x6f, 0x61, 0x74, + 0x33, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x52, 0x63, 0x6f, 0x65, 0x66, + 0x66, 0x47, 0x63, 0x6f, 0x65, 0x66, 0x66, 0x42, 0x63, 0x6f, 0x65, 0x66, + 0x66, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, + 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, + 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x59, 0x55, 0x56, 0x44, 0x65, 0x63, 0x6f, + 0x64, 0x65, 0x64, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x61, 0x69, 0x72, 0x2e, + 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x73, + 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, + 0x32, 0x64, 0x3c, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x2c, 0x20, 0x73, 0x61, + 0x6d, 0x70, 0x6c, 0x65, 0x3e, 0x74, 0x65, 0x78, 0x59, 0x74, 0x65, 0x78, + 0x74, 0x75, 0x72, 0x65, 0x32, 0x64, 0x5f, 0x61, 0x72, 0x72, 0x61, 0x79, + 0x3c, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x2c, 0x20, 0x73, 0x61, 0x6d, 0x70, + 0x6c, 0x65, 0x3e, 0x74, 0x65, 0x78, 0x55, 0x56, 0x61, 0x69, 0x72, 0x2e, + 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x73, 0x61, 0x6d, 0x70, 0x6c, + 0x65, 0x72, 0x73, 0x00, 0x44, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x82, 0x20, 0x11, 0x23, 0x08, 0xda, 0x33, 0x82, 0x20, 0x15, 0x23, + 0x08, 0x92, 0x31, 0x82, 0x20, 0x1d, 0x23, 0x08, 0x0d, 0x30, 0x82, 0x20, + 0x21, 0x23, 0x08, 0x52, 0x32, 0x82, 0x20, 0x29, 0x23, 0x08, 0xd2, 0x32, + 0x82, 0x20, 0x31, 0x23, 0x08, 0x52, 0x33, 0x82, 0x20, 0x39, 0x33, 0x0c, + 0x6e, 0x10, 0xbc, 0xc1, 0x0c, 0x03, 0x1c, 0x08, 0x71, 0x30, 0x43, 0x30, + 0xcc, 0x30, 0xb8, 0x81, 0x1b, 0xc8, 0xc1, 0x0c, 0x04, 0x01, 0x07, 0x70, + 0x20, 0x07, 0x33, 0x04, 0xc5, 0x0c, 0x81, 0x31, 0x43, 0x70, 0xcc, 0x50, + 0x20, 0x72, 0x20, 0x07, 0x89, 0x32, 0x43, 0x30, 0x0a, 0x33, 0x20, 0x72, + 0xb0, 0x30, 0x4d, 0xa2, 0x38, 0xcf, 0x0c, 0x09, 0x1c, 0x40, 0x11, 0x23, + 0x25, 0x8a, 0x33, 0xcd, 0x90, 0xb8, 0x01, 0x44, 0x31, 0x52, 0x52, 0x39, + 0xd6, 0x0c, 0x94, 0x1c, 0xd8, 0x81, 0x1c, 0x70, 0x9d, 0x1d, 0xd8, 0x81, + 0x1c, 0x70, 0xde, 0x1d, 0xd8, 0x81, 0x1c, 0x70, 0x1f, 0x1e, 0xd8, 0x81, + 0x1c, 0x70, 0x60, 0x30, 0x83, 0x44, 0x07, 0x17, 0x56, 0x07, 0x19, 0x1c, + 0xc0, 0x81, 0xb6, 0xa1, 0x42, 0x18, 0xd4, 0x81, 0x18, 0xd8, 0x41, 0x32, + 0x06, 0x0e, 0x19, 0xcc, 0xa0, 0xc4, 0x41, 0x19, 0x64, 0x72, 0x00, 0x07, + 0x66, 0x90, 0x9c, 0x81, 0x83, 0x06, 0x33, 0x28, 0x79, 0x50, 0x06, 0x19, + 0x1c, 0xc0, 0x81, 0x19, 0x24, 0x69, 0xe0, 0xa8, 0xc1, 0x0c, 0x89, 0x1e, + 0xac, 0x41, 0x26, 0x07, 0x70, 0x90, 0xb0, 0x81, 0xd3, 0x06, 0x33, 0x1c, + 0xa5, 0x60, 0x0a, 0xa7, 0x90, 0x0a, 0xaa, 0xb0, 0x0a, 0xac, 0x30, 0xc3, + 0x30, 0x07, 0xa4, 0xd0, 0x0a, 0x15, 0x06, 0x00, 0xc7, 0x71, 0x1c, 0xc7, + 0x71, 0x1c, 0xc7, 0x71, 0x1c, 0xe7, 0x06, 0x6e, 0x60, 0xd1, 0x81, 0x1e, + 0x58, 0x96, 0xa5, 0x07, 0x9c, 0x29, 0xb0, 0x02, 0x2b, 0xd8, 0x86, 0x5f, + 0xd8, 0x83, 0x3d, 0xa8, 0x03, 0x39, 0xc8, 0x48, 0x60, 0x82, 0x2e, 0x62, + 0x63, 0xb3, 0x6b, 0x73, 0x69, 0x7b, 0x23, 0xab, 0x63, 0x2b, 0x73, 0x31, + 0x63, 0x0b, 0x3b, 0x9b, 0x1b, 0x45, 0xd0, 0x83, 0x3d, 0x38, 0x85, 0x8d, + 0xcd, 0xae, 0xcd, 0x25, 0x8d, 0xac, 0xcc, 0x8d, 0x6e, 0x94, 0x80, 0x0f, + 0x6e, 0x09, 0x4b, 0x93, 0x73, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, + 0x1b, 0x25, 0xe8, 0x83, 0xa3, 0xc2, 0xd2, 0xe4, 0x5c, 0xd8, 0xc2, 0xdc, + 0xce, 0xea, 0xc2, 0xce, 0xca, 0xbe, 0xec, 0xca, 0xe4, 0xe6, 0xd2, 0xde, + 0xdc, 0x46, 0x09, 0xfc, 0xe0, 0xa6, 0xb0, 0x34, 0x39, 0x97, 0xb1, 0xb7, + 0x36, 0xb8, 0x34, 0xb6, 0xb2, 0xaf, 0x37, 0x38, 0xba, 0xb4, 0x37, 0xb7, + 0xb9, 0x51, 0x86, 0x3f, 0x00, 0x85, 0x50, 0x38, 0x26, 0x2c, 0x4d, 0xce, + 0xc5, 0x4c, 0x2e, 0xec, 0xac, 0xad, 0xcc, 0x8d, 0x6e, 0x94, 0xa0, 0x15, + 0x00, 0x00, 0x00, 0x00, 0xa9, 0x18, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0x0b, 0x0a, 0x72, 0x28, 0x87, 0x77, 0x80, 0x07, 0x7a, 0x58, 0x70, 0x98, + 0x43, 0x3d, 0xb8, 0xc3, 0x38, 0xb0, 0x43, 0x39, 0xd0, 0xc3, 0x82, 0xe6, + 0x1c, 0xc6, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0xc1, 0x1d, 0xe6, 0x21, + 0x1d, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x00, 0xd1, 0x10, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x07, 0xcc, 0x3c, 0xa4, 0x83, 0x3b, 0x9c, 0x03, + 0x3b, 0x94, 0x03, 0x3d, 0xa0, 0x83, 0x3c, 0x94, 0x43, 0x38, 0x90, 0xc3, + 0x01, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, + 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x24, 0xcd, 0x00, 0xd0, 0x54, 0x03, 0x23, 0x00, 0x44, 0x8d, 0x00, 0xd0, + 0x36, 0xd6, 0x00, 0x04, 0xc2, 0x1c, 0xc3, 0x71, 0x5d, 0xc4, 0x8d, 0x00, + 0x94, 0x40, 0x11, 0x10, 0x30, 0x02, 0x30, 0x03, 0x30, 0x46, 0x00, 0x82, + 0x20, 0x88, 0x7f, 0x14, 0xcc, 0x00, 0xcc, 0x41, 0x84, 0x41, 0x18, 0x84, + 0x81, 0x18, 0x00, 0x00, 0x23, 0x06, 0xcd, 0x10, 0x82, 0x60, 0x70, 0x89, + 0x41, 0xf4, 0x4c, 0xcd, 0xc2, 0x14, 0x85, 0x37, 0x9a, 0x10, 0x00, 0x83, + 0x0c, 0x01, 0xb1, 0x8c, 0x18, 0x38, 0x43, 0x08, 0x82, 0x41, 0x65, 0x06, + 0x93, 0x64, 0x85, 0x01, 0xe4, 0x3c, 0x08, 0x12, 0x06, 0xa3, 0x09, 0x01, + 0x30, 0x86, 0x10, 0x34, 0x73, 0x0c, 0x44, 0xd0, 0x8c, 0x18, 0x38, 0x43, + 0x08, 0x82, 0x41, 0xa5, 0x06, 0x97, 0xa5, 0x9d, 0x01, 0x25, 0x4d, 0x0c, + 0x53, 0x06, 0xa3, 0x09, 0x01, 0x30, 0x86, 0x10, 0x44, 0x73, 0x0c, 0x44, + 0x00, 0x5d, 0xd7, 0x2d, 0x05, 0x41, 0x19, 0x64, 0x08, 0x9e, 0xcb, 0x88, + 0x00, 0xfc, 0x37, 0x31, 0x84, 0xc1, 0xf5, 0x06, 0x17, 0x74, 0x4b, 0x41, + 0x50, 0x06, 0x19, 0x02, 0x8a, 0x1b, 0x31, 0x38, 0x84, 0x10, 0x04, 0x0b, + 0xff, 0x70, 0xee, 0xa0, 0x08, 0x36, 0x31, 0x98, 0x01, 0x57, 0x07, 0x17, + 0x74, 0x4b, 0x41, 0x50, 0x06, 0x19, 0x82, 0x2c, 0x0c, 0x46, 0x0c, 0x0e, + 0x21, 0x04, 0xc1, 0xc2, 0x3f, 0x1c, 0x3e, 0x50, 0x82, 0x4d, 0x0c, 0x6b, + 0x10, 0x06, 0x76, 0x70, 0x41, 0xb7, 0x14, 0x04, 0x65, 0x90, 0x21, 0xf0, + 0xcc, 0x60, 0xc4, 0xe0, 0x10, 0x42, 0x10, 0x2c, 0xfc, 0xc3, 0x09, 0x85, + 0x27, 0x98, 0x63, 0xf8, 0x16, 0x3e, 0x98, 0x63, 0x08, 0x8e, 0x3f, 0x98, + 0x63, 0x08, 0x86, 0x50, 0xb0, 0xa0, 0x0e, 0xc4, 0x3f, 0x03, 0x00, 0x00, + 0x71, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x32, 0x0e, 0x10, 0x22, + 0x84, 0x00, 0x8d, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x65, 0x0c, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0x70, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x63, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x24, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x08, 0x24, 0x00, 0x00, + 0x1d, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x08, 0x24, 0x00, 0x00, + 0x3e, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, + 0x1b, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x08, 0x24, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x5d, 0x0c, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, + 0x12, 0x03, 0x94, 0x22, 0x01, 0x00, 0x00, 0x00, 0x53, 0x44, 0x4c, 0x5f, + 0x59, 0x55, 0x56, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, + 0x61, 0x69, 0x72, 0x2e, 0x64, 0x6f, 0x74, 0x2e, 0x76, 0x33, 0x66, 0x33, + 0x32, 0x61, 0x69, 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, + 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x32, 0x64, 0x5f, 0x61, + 0x72, 0x72, 0x61, 0x79, 0x2e, 0x76, 0x34, 0x66, 0x33, 0x32, 0x61, 0x69, + 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x74, 0x65, 0x78, + 0x74, 0x75, 0x72, 0x65, 0x5f, 0x32, 0x64, 0x2e, 0x76, 0x34, 0x66, 0x33, + 0x32, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x2e, 0x31, 0x61, + 0x69, 0x72, 0x36, 0x34, 0x2d, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2d, 0x69, + 0x6f, 0x73, 0x31, 0x33, 0x2e, 0x30, 0x2e, 0x30, 0x2d, 0x73, 0x69, 0x6d, + 0x75, 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x1c, 0x0e, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x42, 0x43, 0xc0, 0xde, 0x35, 0x14, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x62, 0x0c, 0x30, 0x24, 0x80, 0x10, 0x05, 0xc8, 0x14, 0x00, 0x00, 0x00, + 0x21, 0x0c, 0x00, 0x00, 0x36, 0x03, 0x00, 0x00, 0x0b, 0x02, 0x21, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, + 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, + 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, + 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, + 0x0a, 0x32, 0x52, 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, + 0x00, 0x19, 0x32, 0x42, 0x04, 0x49, 0x0e, 0x90, 0x91, 0x22, 0xc4, 0x50, + 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x29, 0x46, 0x06, + 0x51, 0x18, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x1b, 0xcc, 0x25, 0xf8, + 0xff, 0xff, 0xff, 0xff, 0x01, 0x58, 0x03, 0x40, 0x02, 0x2a, 0x62, 0x1c, + 0xde, 0x41, 0x1e, 0xe4, 0xa1, 0x1c, 0xc6, 0x81, 0x1e, 0xd8, 0x21, 0x1f, + 0xda, 0x40, 0x1e, 0xde, 0xa1, 0x1e, 0xdc, 0x81, 0x1c, 0xca, 0x81, 0x1c, + 0xda, 0x80, 0x1c, 0xd2, 0xc1, 0x1e, 0xd2, 0x81, 0x1c, 0xca, 0xa1, 0x0d, + 0xe6, 0x21, 0x1e, 0xe4, 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, + 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, + 0x87, 0x72, 0x00, 0x08, 0x72, 0x48, 0x87, 0x79, 0x08, 0x07, 0x71, 0x60, + 0x87, 0x72, 0x68, 0x03, 0x7a, 0x08, 0x87, 0x74, 0x60, 0x87, 0x36, 0x18, + 0x87, 0x70, 0x60, 0x07, 0x76, 0x98, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, + 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1d, 0xca, 0x61, 0x1e, 0xe6, 0xa1, 0x0d, + 0xe0, 0x41, 0x1e, 0xca, 0x61, 0x1c, 0xd2, 0x61, 0x1e, 0xca, 0xa1, 0x0d, + 0xcc, 0x01, 0x1e, 0xda, 0x21, 0x1c, 0xc8, 0x01, 0x30, 0x87, 0x70, 0x60, + 0x87, 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x73, 0x90, + 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, 0x78, 0x78, 0x87, 0x74, 0x70, + 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, 0x72, 0x60, 0x87, 0x74, 0x68, + 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x18, 0xdc, 0xe1, 0x1d, + 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, + 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, + 0xd8, 0x21, 0x1d, 0xda, 0xa1, 0x0d, 0xdc, 0xe1, 0x1d, 0xdc, 0xa1, 0x0d, + 0xd8, 0xa1, 0x1c, 0xc2, 0xc1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, + 0xd2, 0xc1, 0x1d, 0xcc, 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, + 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, + 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x75, 0xa8, 0x87, 0x76, 0x80, + 0x87, 0x36, 0xa0, 0x87, 0x70, 0x10, 0x07, 0x76, 0x28, 0x87, 0x79, 0x00, + 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, + 0xda, 0xc0, 0x1d, 0xc2, 0xc1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, + 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, + 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x98, 0x87, 0x74, 0x38, + 0x07, 0x77, 0x28, 0x07, 0x72, 0x68, 0x03, 0x7d, 0x28, 0x07, 0x79, 0x78, + 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, + 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, + 0xde, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0x01, 0x1e, 0xe0, 0x21, 0x1d, + 0xdc, 0xe1, 0x1c, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, + 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x88, 0x79, 0xa0, 0x87, 0x70, 0x18, + 0x87, 0x75, 0x68, 0x03, 0x78, 0x90, 0x87, 0x77, 0xa0, 0x87, 0x72, 0x18, + 0x07, 0x7a, 0x78, 0x07, 0x79, 0x68, 0x03, 0x71, 0xa8, 0x07, 0x73, 0x30, + 0x87, 0x72, 0x90, 0x87, 0x36, 0x98, 0x87, 0x74, 0xd0, 0x87, 0x72, 0x00, + 0xf0, 0x00, 0x20, 0xea, 0xc1, 0x1d, 0xe6, 0x21, 0x1c, 0xcc, 0xa1, 0x1c, + 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, + 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0xa8, 0x87, 0x79, 0x28, + 0x87, 0x36, 0x98, 0x87, 0x77, 0x30, 0x07, 0x7a, 0x68, 0x03, 0x73, 0x60, + 0x87, 0x77, 0x08, 0x07, 0x7a, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, + 0xca, 0x01, 0xd8, 0xb0, 0x08, 0x04, 0x90, 0x00, 0x0b, 0x50, 0x05, 0x69, + 0x00, 0x0a, 0x1b, 0x8c, 0xa1, 0x00, 0x16, 0xa0, 0xda, 0x60, 0x10, 0x06, + 0xb0, 0x00, 0xd5, 0x06, 0xa3, 0x38, 0x80, 0x05, 0xa8, 0x36, 0x18, 0xc6, + 0xff, 0xff, 0xff, 0xff, 0x0f, 0x80, 0x04, 0x50, 0x1b, 0x94, 0xe3, 0xff, + 0xff, 0xff, 0xff, 0x07, 0xa0, 0x0d, 0x80, 0x35, 0x00, 0x24, 0xa0, 0xda, + 0x60, 0x20, 0x01, 0xb0, 0x00, 0xd5, 0x06, 0x23, 0x11, 0x80, 0x05, 0xa8, + 0x00, 0x00, 0x00, 0x00, 0x49, 0x18, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x13, 0x8a, 0x40, 0x18, 0x88, 0x62, 0x42, 0x60, 0x4c, 0x18, 0x0e, 0x24, + 0x01, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, + 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, + 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, + 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x70, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, + 0x8c, 0x20, 0x00, 0xc3, 0x08, 0x03, 0x70, 0x90, 0x34, 0x45, 0x94, 0x30, + 0xf9, 0xb2, 0xfb, 0x76, 0x84, 0xe0, 0x0c, 0x04, 0x22, 0xc6, 0x18, 0x63, + 0x10, 0x81, 0x10, 0x8e, 0x92, 0xa6, 0x88, 0x12, 0x26, 0xff, 0x9f, 0x88, + 0x6b, 0xa2, 0x22, 0xe2, 0xb7, 0x87, 0x7f, 0x1a, 0x23, 0x00, 0x06, 0x11, + 0x8c, 0xe0, 0x22, 0x69, 0x8a, 0x28, 0x61, 0xf2, 0x7f, 0x09, 0x60, 0x9e, + 0x85, 0x88, 0xfe, 0x69, 0x8c, 0x00, 0x18, 0x44, 0x40, 0x84, 0x82, 0x84, + 0x10, 0x44, 0x39, 0x27, 0x91, 0x2a, 0x03, 0x18, 0x83, 0xd8, 0x1c, 0x01, + 0x62, 0x84, 0xe0, 0xe6, 0x08, 0x82, 0x39, 0x02, 0x30, 0x18, 0x46, 0x10, + 0xa2, 0xa2, 0xbc, 0x93, 0x04, 0x94, 0x10, 0x80, 0x48, 0x73, 0x20, 0x20, + 0x05, 0xe2, 0x30, 0xc2, 0x10, 0x0d, 0x22, 0x04, 0xc2, 0x1c, 0x01, 0x28, + 0x0c, 0x22, 0x0c, 0xc2, 0x08, 0x00, 0x00, 0x00, 0x13, 0xbe, 0x70, 0x48, + 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, + 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, 0x87, 0x79, 0x88, 0x83, 0x39, 0x70, + 0x03, 0x38, 0x70, 0x03, 0x38, 0x68, 0x83, 0x79, 0x48, 0x87, 0x76, 0xa8, + 0x07, 0x76, 0x08, 0x07, 0x7a, 0x78, 0x07, 0x79, 0xd8, 0x70, 0x1b, 0xe5, + 0xd0, 0x06, 0xf0, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x78, + 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x7a, + 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, + 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x90, 0x0e, 0x73, 0x20, 0x07, 0x7a, + 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, + 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, + 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, + 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x60, 0x07, 0x7a, + 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, + 0x40, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, + 0x60, 0x0f, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, + 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x74, 0x80, 0x07, 0x7a, 0x60, 0x07, 0x74, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x76, 0x40, 0x07, 0x7a, + 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x79, + 0x60, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, + 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, + 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, + 0x10, 0x07, 0x79, 0x20, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, + 0x20, 0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x50, 0x07, 0x76, + 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, + 0xd0, 0x06, 0xf6, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, + 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x71, + 0x00, 0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, + 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, + 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x11, 0xc2, + 0x90, 0x11, 0xdb, 0x95, 0xff, 0xf9, 0xd6, 0xf6, 0x5f, 0x44, 0x80, 0xc1, + 0x10, 0xcd, 0x34, 0x24, 0x02, 0x22, 0x05, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x86, 0x44, 0x51, 0xc3, 0x00, 0x01, 0x20, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0xc0, 0x90, 0xc8, 0xdb, 0x26, + 0x20, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x90, 0xd8, + 0x20, 0x50, 0x14, 0x67, 0x00, 0x00, 0x20, 0x0b, 0x04, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, + 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x8a, 0x45, 0x50, 0x02, 0x85, + 0x30, 0x02, 0x50, 0x06, 0x05, 0x18, 0x50, 0x20, 0x05, 0x54, 0x60, 0xa5, + 0x50, 0x0c, 0x64, 0xc7, 0x12, 0x1c, 0x02, 0x00, 0xb1, 0x18, 0x00, 0x00, + 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, + 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, + 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, + 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, + 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, + 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, + 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, + 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, + 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, + 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, + 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, + 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, + 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, + 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, + 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, + 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, + 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, + 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, + 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, + 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, + 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, + 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, + 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, + 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, + 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, + 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, + 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, + 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, + 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, + 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, + 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, + 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, + 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, + 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, + 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, + 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, + 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, + 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, + 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, + 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, + 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, + 0xc0, 0xc3, 0x3c, 0x00, 0x79, 0x20, 0x00, 0x00, 0x09, 0x01, 0x00, 0x00, + 0x32, 0x9a, 0x08, 0x14, 0x02, 0x85, 0x8c, 0x27, 0x46, 0x46, 0xc8, 0x11, + 0x32, 0x64, 0xd4, 0xd8, 0x80, 0x0c, 0xea, 0x09, 0x8b, 0x02, 0x07, 0xc5, + 0xc6, 0x91, 0x41, 0x14, 0x19, 0x8c, 0x22, 0x31, 0x88, 0x64, 0x3d, 0x45, + 0x66, 0x20, 0xca, 0x23, 0x21, 0x94, 0x61, 0x18, 0x86, 0x11, 0x5d, 0x89, + 0xb1, 0x28, 0x18, 0x51, 0x2c, 0x47, 0x00, 0x00, 0x53, 0x44, 0x4b, 0x20, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x77, 0x63, 0x68, 0x61, 0x72, + 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x4c, + 0x4c, 0x56, 0x4d, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, + 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x20, 0x28, 0x6d, 0x65, + 0x74, 0x61, 0x6c, 0x66, 0x65, 0x2d, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, + 0x35, 0x30, 0x2e, 0x31, 0x29, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x61, 0x69, + 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x64, 0x65, + 0x6e, 0x6f, 0x72, 0x6d, 0x73, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, + 0x65, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, + 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, 0x65, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, + 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x62, 0x75, + 0x66, 0x66, 0x65, 0x72, 0x5f, 0x66, 0x65, 0x74, 0x63, 0x68, 0x5f, 0x65, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x72, 0x65, 0x6e, + 0x64, 0x65, 0x72, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x61, 0x69, + 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x61, 0x69, 0x72, + 0x2e, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x69, 0x72, + 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x6e, + 0x6f, 0x5f, 0x70, 0x65, 0x72, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x69, 0x72, + 0x2e, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x6e, + 0x70, 0x75, 0x74, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, + 0x28, 0x35, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x44, 0x76, 0x34, 0x5f, 0x66, + 0x29, 0x61, 0x69, 0x72, 0x2e, 0x70, 0x65, 0x72, 0x73, 0x70, 0x65, 0x63, + 0x74, 0x69, 0x76, 0x65, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x67, 0x65, 0x6e, + 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x38, 0x74, 0x65, 0x78, 0x63, + 0x6f, 0x6f, 0x72, 0x64, 0x44, 0x76, 0x32, 0x5f, 0x66, 0x29, 0x66, 0x6c, + 0x6f, 0x61, 0x74, 0x32, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, + 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x61, 0x69, + 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, + 0x65, 0x61, 0x69, 0x72, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x61, 0x69, 0x72, 0x2e, 0x72, + 0x65, 0x61, 0x64, 0x61, 0x69, 0x72, 0x2e, 0x73, 0x74, 0x72, 0x75, 0x63, + 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x66, + 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x52, + 0x63, 0x6f, 0x65, 0x66, 0x66, 0x47, 0x63, 0x6f, 0x65, 0x66, 0x66, 0x42, + 0x63, 0x6f, 0x65, 0x66, 0x66, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x61, 0x69, + 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x61, + 0x6c, 0x69, 0x67, 0x6e, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x59, 0x55, 0x56, + 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x65, 0x63, 0x6f, 0x64, 0x65, + 0x61, 0x69, 0x72, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x61, + 0x69, 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x78, + 0x74, 0x75, 0x72, 0x65, 0x32, 0x64, 0x3c, 0x66, 0x6c, 0x6f, 0x61, 0x74, + 0x2c, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x3e, 0x74, 0x65, 0x78, + 0x59, 0x74, 0x65, 0x78, 0x55, 0x56, 0x61, 0x69, 0x72, 0x2e, 0x73, 0x61, + 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, + 0x73, 0x00, 0x00, 0x00, 0x44, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x82, 0x10, 0x0d, 0x23, 0x08, 0x96, 0x33, 0x82, 0x10, 0x11, 0x23, + 0x08, 0x51, 0x31, 0x82, 0x10, 0x19, 0x23, 0x08, 0x0b, 0x30, 0x82, 0x10, + 0x1d, 0x23, 0x08, 0x11, 0x32, 0x82, 0x10, 0x25, 0x23, 0x08, 0x91, 0x32, + 0x82, 0x10, 0x2d, 0x23, 0x08, 0x11, 0x33, 0x82, 0x10, 0x35, 0x33, 0x0c, + 0x6d, 0x10, 0xb8, 0xc1, 0x0c, 0xc3, 0x1b, 0x08, 0x70, 0x30, 0x43, 0x30, + 0xcc, 0x30, 0xb4, 0x41, 0x1b, 0xc4, 0xc1, 0x0c, 0x04, 0xf1, 0x06, 0x6f, + 0x10, 0x07, 0x33, 0x04, 0xc5, 0x0c, 0x81, 0x31, 0x43, 0x70, 0xcc, 0x50, + 0x20, 0x71, 0x10, 0x07, 0x89, 0x32, 0x43, 0x20, 0x0a, 0x33, 0x20, 0x71, + 0xb0, 0x30, 0x4d, 0xa2, 0x38, 0xcf, 0x0c, 0xc9, 0x1b, 0x40, 0x11, 0x23, + 0x25, 0x8a, 0x33, 0xcd, 0x90, 0xb4, 0x01, 0x44, 0x31, 0x52, 0x52, 0x39, + 0xd6, 0x0c, 0x54, 0x1c, 0xd4, 0x41, 0x1c, 0x70, 0x5d, 0x1d, 0xd4, 0x41, + 0x1c, 0x70, 0x9e, 0x1d, 0xd4, 0x41, 0x1c, 0x70, 0xdf, 0x1d, 0xd4, 0x41, + 0x1c, 0x70, 0x60, 0x30, 0x83, 0x34, 0x07, 0x17, 0x46, 0x07, 0xd9, 0x1b, + 0xbc, 0x81, 0xb6, 0x9d, 0x42, 0x18, 0xd0, 0x81, 0x18, 0xd4, 0x41, 0x32, + 0x06, 0x0e, 0x19, 0xcc, 0xa0, 0xc0, 0x41, 0x19, 0x64, 0x71, 0xf0, 0x06, + 0x66, 0x90, 0x9c, 0x81, 0x83, 0x06, 0x33, 0x28, 0x78, 0x50, 0x06, 0xd9, + 0x1b, 0xbc, 0x81, 0x19, 0x24, 0x67, 0xe0, 0xa4, 0xc1, 0x0c, 0x49, 0x1e, + 0xa8, 0x41, 0x16, 0x07, 0x6f, 0x90, 0xac, 0x81, 0xc3, 0x06, 0x33, 0x1c, + 0xa4, 0x50, 0x0a, 0xa6, 0x80, 0x0a, 0xa9, 0xa0, 0x0a, 0xab, 0x30, 0xc3, + 0x20, 0x07, 0xa3, 0xc0, 0x0a, 0x15, 0x06, 0x00, 0xc7, 0x71, 0x1c, 0xc7, + 0x71, 0x1c, 0xc7, 0x71, 0x1c, 0xe7, 0x06, 0x6e, 0x60, 0xd1, 0x81, 0x1e, + 0x58, 0x96, 0xa5, 0x07, 0x9c, 0x29, 0xb0, 0x02, 0x2b, 0xd8, 0x86, 0x5f, + 0xd8, 0x83, 0x3d, 0xa8, 0x03, 0x39, 0xc8, 0x48, 0x60, 0x82, 0x2e, 0x62, + 0x63, 0xb3, 0x6b, 0x73, 0x69, 0x7b, 0x23, 0xab, 0x63, 0x2b, 0x73, 0x31, + 0x63, 0x0b, 0x3b, 0x9b, 0x1b, 0x45, 0xc8, 0x03, 0x3d, 0x38, 0x85, 0x8d, + 0xcd, 0xae, 0xcd, 0x25, 0x8d, 0xac, 0xcc, 0x8d, 0x6e, 0x94, 0x60, 0x0f, + 0x6e, 0x09, 0x4b, 0x93, 0x73, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, + 0x1b, 0x25, 0xe0, 0x83, 0xa3, 0xc2, 0xd2, 0xe4, 0x5c, 0xd8, 0xc2, 0xdc, + 0xce, 0xea, 0xc2, 0xce, 0xca, 0xbe, 0xec, 0xca, 0xe4, 0xe6, 0xd2, 0xde, + 0xdc, 0x46, 0x09, 0xfa, 0xe0, 0xa6, 0xb0, 0x34, 0x39, 0x97, 0xb1, 0xb7, + 0x36, 0xb8, 0x34, 0xb6, 0xb2, 0xaf, 0x37, 0x38, 0xba, 0xb4, 0x37, 0xb7, + 0xb9, 0x51, 0x06, 0x3f, 0xf8, 0x03, 0x50, 0x38, 0x26, 0x2c, 0x4d, 0xce, + 0xc5, 0x4c, 0x2e, 0xec, 0xac, 0xad, 0xcc, 0x8d, 0x6e, 0x94, 0x80, 0x15, + 0x00, 0x00, 0x00, 0x00, 0xa9, 0x18, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0x0b, 0x0a, 0x72, 0x28, 0x87, 0x77, 0x80, 0x07, 0x7a, 0x58, 0x70, 0x98, + 0x43, 0x3d, 0xb8, 0xc3, 0x38, 0xb0, 0x43, 0x39, 0xd0, 0xc3, 0x82, 0xe6, + 0x1c, 0xc6, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0xc1, 0x1d, 0xe6, 0x21, + 0x1d, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x00, 0xd1, 0x10, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x07, 0xcc, 0x3c, 0xa4, 0x83, 0x3b, 0x9c, 0x03, + 0x3b, 0x94, 0x03, 0x3d, 0xa0, 0x83, 0x3c, 0x94, 0x43, 0x38, 0x90, 0xc3, + 0x01, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, + 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x04, 0x6b, 0x60, 0x04, 0x80, 0xe2, 0x0c, 0x00, 0xc9, 0x11, 0x00, 0xba, + 0x63, 0x0d, 0x40, 0x20, 0xcc, 0x31, 0x18, 0x18, 0x36, 0xc7, 0x60, 0x10, + 0xd8, 0x58, 0x03, 0x30, 0x10, 0x94, 0x47, 0x00, 0x08, 0x8c, 0x00, 0xcc, + 0x00, 0x8c, 0x11, 0x80, 0x20, 0x08, 0xe2, 0x1f, 0x85, 0x19, 0x80, 0x39, + 0x08, 0x30, 0x00, 0x03, 0x30, 0x08, 0x03, 0x00, 0x23, 0x06, 0xcd, 0x10, + 0x82, 0x60, 0x30, 0x89, 0x41, 0xf4, 0x4c, 0xce, 0xd2, 0x14, 0x85, 0x37, + 0x9a, 0x10, 0x00, 0x83, 0x0c, 0x01, 0xb1, 0x8c, 0x18, 0x34, 0x43, 0x08, + 0x82, 0xc1, 0x54, 0x06, 0x93, 0x64, 0x45, 0x0e, 0x84, 0x20, 0x61, 0x30, + 0x9a, 0x10, 0x00, 0x83, 0x0c, 0xc1, 0xd1, 0x0c, 0x32, 0x10, 0x41, 0x73, + 0x19, 0x5e, 0x0a, 0x42, 0x19, 0x64, 0x08, 0x96, 0xc9, 0x88, 0x00, 0xfc, + 0x37, 0x19, 0xba, 0x68, 0x0d, 0x2e, 0xc0, 0x4b, 0x41, 0x28, 0x83, 0x0c, + 0x01, 0x84, 0x8d, 0x18, 0x1c, 0x42, 0x08, 0x82, 0x85, 0x7f, 0x30, 0x72, + 0x50, 0x04, 0x9b, 0x0c, 0x62, 0x60, 0xc5, 0xc1, 0x05, 0x78, 0x29, 0x08, + 0x65, 0x90, 0x21, 0xa8, 0xba, 0x11, 0x83, 0x43, 0x08, 0x41, 0xb0, 0xf0, + 0x0f, 0xe6, 0x0e, 0x94, 0x60, 0x93, 0xe1, 0x0c, 0x36, 0x39, 0xb8, 0x00, + 0x2f, 0x05, 0xa1, 0x0c, 0x32, 0x04, 0x9a, 0x18, 0x8c, 0x18, 0x1c, 0x42, + 0x08, 0x82, 0x85, 0x7f, 0x30, 0x7c, 0xf0, 0x04, 0x73, 0x0c, 0xdb, 0x82, + 0x07, 0x73, 0x0c, 0xc1, 0xb1, 0x07, 0x73, 0x0c, 0xc1, 0xd0, 0x07, 0x16, + 0xc4, 0x81, 0xf8, 0x67, 0x00, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x32, 0x0e, 0x10, 0x22, 0x84, 0x00, 0xfb, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x0c, 0x00, 0x00, + 0x29, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0x38, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, + 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x24, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x08, 0x24, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, + 0x1b, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x08, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x5d, 0x0c, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0xe2, + 0x00, 0x00, 0x00, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x4e, 0x56, 0x31, 0x32, + 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x69, 0x72, + 0x2e, 0x64, 0x6f, 0x74, 0x2e, 0x76, 0x33, 0x66, 0x33, 0x32, 0x61, 0x69, + 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x74, 0x65, 0x78, + 0x74, 0x75, 0x72, 0x65, 0x5f, 0x32, 0x64, 0x2e, 0x76, 0x34, 0x66, 0x33, + 0x32, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x2e, 0x31, 0x61, + 0x69, 0x72, 0x36, 0x34, 0x2d, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2d, 0x69, + 0x6f, 0x73, 0x31, 0x33, 0x2e, 0x30, 0x2e, 0x30, 0x2d, 0x73, 0x69, 0x6d, + 0x75, 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x28, 0x0e, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, + 0x35, 0x14, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x62, 0x0c, 0x30, 0x24, + 0x80, 0x10, 0x05, 0xc8, 0x14, 0x00, 0x00, 0x00, 0x21, 0x0c, 0x00, 0x00, + 0x39, 0x03, 0x00, 0x00, 0x0b, 0x02, 0x21, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, + 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, + 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, + 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88, + 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, + 0x04, 0x49, 0x0e, 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, + 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, + 0x92, 0x00, 0x00, 0x00, 0x1b, 0xcc, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, + 0x01, 0x58, 0x03, 0x40, 0x02, 0x2a, 0x62, 0x1c, 0xde, 0x41, 0x1e, 0xe4, + 0xa1, 0x1c, 0xc6, 0x81, 0x1e, 0xd8, 0x21, 0x1f, 0xda, 0x40, 0x1e, 0xde, + 0xa1, 0x1e, 0xdc, 0x81, 0x1c, 0xca, 0x81, 0x1c, 0xda, 0x80, 0x1c, 0xd2, + 0xc1, 0x1e, 0xd2, 0x81, 0x1c, 0xca, 0xa1, 0x0d, 0xe6, 0x21, 0x1e, 0xe4, + 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, + 0x01, 0x1d, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, + 0x72, 0x48, 0x87, 0x79, 0x08, 0x07, 0x71, 0x60, 0x87, 0x72, 0x68, 0x03, + 0x7a, 0x08, 0x87, 0x74, 0x60, 0x87, 0x36, 0x18, 0x87, 0x70, 0x60, 0x07, + 0x76, 0x98, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, + 0x82, 0x1d, 0xca, 0x61, 0x1e, 0xe6, 0xa1, 0x0d, 0xe0, 0x41, 0x1e, 0xca, + 0x61, 0x1c, 0xd2, 0x61, 0x1e, 0xca, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, + 0x21, 0x1c, 0xc8, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, + 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x73, 0x90, 0x87, 0x70, 0x68, 0x87, + 0x72, 0x68, 0x03, 0x78, 0x78, 0x87, 0x74, 0x70, 0x07, 0x7a, 0x28, 0x07, + 0x79, 0x68, 0x83, 0x72, 0x60, 0x87, 0x74, 0x68, 0x07, 0x80, 0x1e, 0xe4, + 0xa1, 0x1e, 0xca, 0x01, 0x18, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, + 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, + 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, + 0xa1, 0x0d, 0xdc, 0xe1, 0x1d, 0xdc, 0xa1, 0x0d, 0xd8, 0xa1, 0x1c, 0xc2, + 0xc1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xd2, 0xc1, 0x1d, 0xcc, + 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, + 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, + 0x77, 0x68, 0x03, 0x75, 0xa8, 0x87, 0x76, 0x80, 0x87, 0x36, 0xa0, 0x87, + 0x70, 0x10, 0x07, 0x76, 0x28, 0x87, 0x79, 0x00, 0xcc, 0x21, 0x1c, 0xd8, + 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1d, 0xc2, + 0xc1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, + 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, + 0x77, 0x78, 0x87, 0x36, 0x98, 0x87, 0x74, 0x38, 0x07, 0x77, 0x28, 0x07, + 0x72, 0x68, 0x03, 0x7d, 0x28, 0x07, 0x79, 0x78, 0x87, 0x79, 0x68, 0x03, + 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, + 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe8, + 0x41, 0x1e, 0xc2, 0x01, 0x1e, 0xe0, 0x21, 0x1d, 0xdc, 0xe1, 0x1c, 0xda, + 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, + 0x72, 0x00, 0x88, 0x79, 0xa0, 0x87, 0x70, 0x18, 0x87, 0x75, 0x68, 0x03, + 0x78, 0x90, 0x87, 0x77, 0xa0, 0x87, 0x72, 0x18, 0x07, 0x7a, 0x78, 0x07, + 0x79, 0x68, 0x03, 0x71, 0xa8, 0x07, 0x73, 0x30, 0x87, 0x72, 0x90, 0x87, + 0x36, 0x98, 0x87, 0x74, 0xd0, 0x87, 0x72, 0x00, 0xf0, 0x00, 0x20, 0xea, + 0xc1, 0x1d, 0xe6, 0x21, 0x1c, 0xcc, 0xa1, 0x1c, 0xda, 0xc0, 0x1c, 0xe0, + 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, + 0x7a, 0x28, 0x07, 0x80, 0xa8, 0x87, 0x79, 0x28, 0x87, 0x36, 0x98, 0x87, + 0x77, 0x30, 0x07, 0x7a, 0x68, 0x03, 0x73, 0x60, 0x87, 0x77, 0x08, 0x07, + 0x7a, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0xd8, 0xb0, + 0x08, 0x04, 0x90, 0x00, 0x0b, 0x50, 0x05, 0x69, 0x00, 0x0a, 0x1b, 0x8c, + 0xa1, 0x00, 0x16, 0xa0, 0xda, 0x60, 0x10, 0x06, 0xb0, 0x00, 0xd5, 0x06, + 0xa3, 0x38, 0x80, 0x05, 0xa8, 0x36, 0x18, 0xc6, 0xff, 0xff, 0xff, 0xff, + 0x0f, 0x80, 0x04, 0x50, 0x1b, 0x94, 0xe3, 0xff, 0xff, 0xff, 0xff, 0x07, + 0xa0, 0x0d, 0x80, 0x35, 0x00, 0x24, 0xa0, 0xda, 0x60, 0x20, 0x01, 0xb0, + 0x00, 0xd5, 0x06, 0x23, 0x11, 0x80, 0x05, 0xa8, 0x00, 0x00, 0x00, 0x00, + 0x49, 0x18, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x13, 0x8a, 0x40, 0x18, + 0x88, 0x62, 0x42, 0x60, 0x4c, 0x18, 0x0e, 0x24, 0x01, 0x00, 0x00, 0x00, + 0x89, 0x20, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, + 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, + 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, + 0x10, 0x70, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, 0x00, 0xc3, + 0x08, 0x03, 0x70, 0x90, 0x34, 0x45, 0x94, 0x30, 0xf9, 0xb2, 0xfb, 0x76, + 0x84, 0xe0, 0x0c, 0x04, 0x22, 0xc6, 0x18, 0x63, 0x10, 0x81, 0x10, 0x8e, + 0x92, 0xa6, 0x88, 0x12, 0x26, 0xff, 0x9f, 0x88, 0x6b, 0xa2, 0x22, 0xe2, + 0xb7, 0x87, 0x7f, 0x1a, 0x23, 0x00, 0x06, 0x11, 0x8c, 0xe0, 0x22, 0x69, + 0x8a, 0x28, 0x61, 0xf2, 0x7f, 0x09, 0x60, 0x9e, 0x85, 0x88, 0xfe, 0x69, + 0x8c, 0x00, 0x18, 0x44, 0x40, 0x84, 0x82, 0x84, 0x10, 0x44, 0x39, 0x27, + 0x91, 0x2a, 0x03, 0x18, 0x83, 0xd8, 0x1c, 0x01, 0x62, 0x84, 0xe0, 0xe6, + 0x08, 0x82, 0x39, 0x02, 0x30, 0x18, 0x46, 0x10, 0xa2, 0xa2, 0xbc, 0x93, + 0x04, 0x94, 0x10, 0x80, 0x48, 0x73, 0x20, 0x20, 0x05, 0xe2, 0x30, 0xc2, + 0x10, 0x0d, 0x22, 0x04, 0xc2, 0x1c, 0x01, 0x28, 0x0c, 0x22, 0x0c, 0xc2, + 0x08, 0x00, 0x00, 0x00, 0x13, 0xbe, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, + 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, + 0x74, 0x78, 0x87, 0x79, 0x88, 0x83, 0x39, 0x70, 0x03, 0x38, 0x70, 0x03, + 0x38, 0x68, 0x83, 0x79, 0x48, 0x87, 0x76, 0xa8, 0x07, 0x76, 0x08, 0x07, + 0x7a, 0x78, 0x07, 0x79, 0xd8, 0x70, 0x1b, 0xe5, 0xd0, 0x06, 0xf0, 0xa0, + 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, + 0x06, 0xe9, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, + 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, + 0x07, 0x6d, 0x90, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, + 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, + 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, + 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, + 0x07, 0x71, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x40, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x73, 0x20, + 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, + 0x0f, 0x74, 0x80, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x6d, 0x60, 0x0f, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, + 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x79, 0x60, 0x07, 0x7a, 0x10, + 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, + 0x0f, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, + 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x79, 0x20, + 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, + 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, + 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x50, + 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, + 0x07, 0x71, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x00, 0x07, 0x72, 0x40, + 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, + 0x07, 0x72, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, + 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x11, 0xc2, 0x90, 0x11, 0xdb, 0x95, + 0xff, 0xf9, 0xda, 0xf5, 0x5f, 0x44, 0x80, 0xc1, 0x10, 0xcd, 0x34, 0x24, + 0x02, 0x22, 0x05, 0x00, 0x80, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x86, 0x44, 0x51, 0xc3, 0x00, 0x01, 0x20, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0xc0, 0x90, 0xc8, 0xdb, 0x26, 0x20, 0x00, 0x06, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x90, 0xd8, 0x20, 0x50, 0x74, 0x67, + 0x00, 0x00, 0x20, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, + 0xc6, 0x04, 0x43, 0x8a, 0x45, 0x50, 0x02, 0x85, 0x30, 0x02, 0x50, 0x06, + 0x05, 0x18, 0x50, 0x20, 0x05, 0x54, 0x60, 0xa5, 0x50, 0x0c, 0x64, 0xc7, + 0x12, 0x1c, 0x02, 0x00, 0xb1, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, + 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, + 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, + 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, + 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, + 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, + 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, + 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, + 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, + 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, + 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, + 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, + 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, + 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, + 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, + 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, + 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, + 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, + 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, + 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, + 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, + 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, + 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, + 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, + 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, + 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, + 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, + 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, + 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, + 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, + 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, + 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, + 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, + 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, + 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, + 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, + 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, + 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, + 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, + 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, + 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, + 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, + 0x79, 0x20, 0x00, 0x00, 0x09, 0x01, 0x00, 0x00, 0x32, 0x9a, 0x08, 0x14, + 0x02, 0x85, 0x8c, 0x27, 0x46, 0x46, 0xc8, 0x11, 0x32, 0x64, 0xd4, 0xd8, + 0x80, 0x0c, 0xea, 0x09, 0x8b, 0x02, 0x07, 0xc5, 0xc6, 0x91, 0x41, 0x14, + 0x19, 0x8c, 0x22, 0x31, 0x88, 0x64, 0x3d, 0x45, 0x66, 0x20, 0xca, 0x23, + 0x21, 0x94, 0x61, 0x18, 0x86, 0x11, 0x5d, 0x89, 0xb1, 0x28, 0x18, 0x51, + 0x2c, 0x47, 0x00, 0x00, 0x53, 0x44, 0x4b, 0x20, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x77, 0x63, 0x68, 0x61, 0x72, 0x5f, 0x73, 0x69, 0x7a, + 0x65, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x4c, 0x4c, 0x56, 0x4d, 0x20, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x33, 0x31, 0x30, 0x30, + 0x31, 0x2e, 0x35, 0x30, 0x20, 0x28, 0x6d, 0x65, 0x74, 0x61, 0x6c, 0x66, + 0x65, 0x2d, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x2e, 0x31, + 0x29, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, + 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x64, 0x65, 0x6e, 0x6f, 0x72, 0x6d, + 0x73, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, + 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, + 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, + 0x2e, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, + 0x5f, 0x66, 0x65, 0x74, 0x63, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x61, 0x69, 0x72, 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x5f, + 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, + 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x66, + 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x61, 0x69, 0x72, 0x2e, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x65, 0x6e, + 0x74, 0x65, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x6e, 0x6f, 0x5f, 0x70, 0x65, + 0x72, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x61, 0x69, 0x72, + 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x69, 0x72, 0x2e, 0x66, 0x72, 0x61, + 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x67, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x35, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x44, 0x76, 0x34, 0x5f, 0x66, 0x29, 0x61, 0x69, 0x72, + 0x2e, 0x70, 0x65, 0x72, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, + 0x65, 0x64, 0x28, 0x38, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, + 0x44, 0x76, 0x32, 0x5f, 0x66, 0x29, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, + 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x61, 0x69, 0x72, 0x2e, + 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, + 0x66, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x61, 0x69, 0x72, + 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, + 0x64, 0x65, 0x78, 0x61, 0x69, 0x72, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x61, + 0x69, 0x72, 0x2e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x66, 0x6c, 0x6f, 0x61, 0x74, + 0x33, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x52, 0x63, 0x6f, 0x65, 0x66, + 0x66, 0x47, 0x63, 0x6f, 0x65, 0x66, 0x66, 0x42, 0x63, 0x6f, 0x65, 0x66, + 0x66, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, + 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, + 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x59, 0x55, 0x56, 0x44, 0x65, 0x63, 0x6f, + 0x64, 0x65, 0x64, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x61, 0x69, 0x72, 0x2e, + 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x73, + 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, + 0x32, 0x64, 0x3c, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x2c, 0x20, 0x73, 0x61, + 0x6d, 0x70, 0x6c, 0x65, 0x3e, 0x74, 0x65, 0x78, 0x59, 0x74, 0x65, 0x78, + 0x55, 0x56, 0x61, 0x69, 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, + 0x72, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x73, 0x00, 0x00, 0x00, + 0x44, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x82, 0x10, 0x0d, + 0x23, 0x08, 0x96, 0x33, 0x82, 0x10, 0x11, 0x23, 0x08, 0x51, 0x31, 0x82, + 0x10, 0x19, 0x23, 0x08, 0x0b, 0x30, 0x82, 0x10, 0x1d, 0x23, 0x08, 0x11, + 0x32, 0x82, 0x10, 0x25, 0x23, 0x08, 0x91, 0x32, 0x82, 0x10, 0x2d, 0x23, + 0x08, 0x11, 0x33, 0x82, 0x10, 0x35, 0x33, 0x0c, 0x6d, 0x10, 0xb8, 0xc1, + 0x0c, 0xc3, 0x1b, 0x08, 0x70, 0x30, 0x43, 0x30, 0xcc, 0x30, 0xb4, 0x41, + 0x1b, 0xc4, 0xc1, 0x0c, 0x04, 0xf1, 0x06, 0x6f, 0x10, 0x07, 0x33, 0x04, + 0xc5, 0x0c, 0x81, 0x31, 0x43, 0x70, 0xcc, 0x50, 0x20, 0x71, 0x10, 0x07, + 0x89, 0x32, 0x43, 0x20, 0x0a, 0x33, 0x20, 0x71, 0xb0, 0x30, 0x4d, 0xa2, + 0x38, 0xcf, 0x0c, 0xc9, 0x1b, 0x40, 0x11, 0x23, 0x25, 0x8a, 0x33, 0xcd, + 0x90, 0xb4, 0x01, 0x44, 0x31, 0x52, 0x52, 0x39, 0xd6, 0x0c, 0x54, 0x1c, + 0xd4, 0x41, 0x1c, 0x70, 0x5d, 0x1d, 0xd4, 0x41, 0x1c, 0x70, 0x9e, 0x1d, + 0xd4, 0x41, 0x1c, 0x70, 0xdf, 0x1d, 0xd4, 0x41, 0x1c, 0x70, 0x60, 0x30, + 0x83, 0x34, 0x07, 0x17, 0x46, 0x07, 0xd9, 0x1b, 0xbc, 0x81, 0xb6, 0x9d, + 0x42, 0x18, 0xd0, 0x81, 0x18, 0xd4, 0x41, 0x32, 0x06, 0x0e, 0x19, 0xcc, + 0xa0, 0xc0, 0x41, 0x19, 0x64, 0x71, 0xf0, 0x06, 0x66, 0x90, 0x9c, 0x81, + 0x83, 0x06, 0x33, 0x28, 0x78, 0x50, 0x06, 0xd9, 0x1b, 0xbc, 0x81, 0x19, + 0x24, 0x67, 0xe0, 0xa4, 0xc1, 0x0c, 0x49, 0x1e, 0xa8, 0x41, 0x16, 0x07, + 0x6f, 0x90, 0xac, 0x81, 0xc3, 0x06, 0x33, 0x1c, 0xa4, 0x50, 0x0a, 0xa6, + 0x80, 0x0a, 0xa9, 0xa0, 0x0a, 0xab, 0x30, 0xc3, 0x20, 0x07, 0xa3, 0xc0, + 0x0a, 0x15, 0x06, 0x00, 0xc7, 0x71, 0x1c, 0xc7, 0x71, 0x1c, 0xc7, 0x71, + 0x1c, 0xe7, 0x06, 0x6e, 0x60, 0xd1, 0x81, 0x1e, 0x58, 0x96, 0xa5, 0x07, + 0x9c, 0x29, 0xb0, 0x02, 0x2b, 0xd8, 0x86, 0x5f, 0xd8, 0x83, 0x3d, 0xa8, + 0x03, 0x39, 0xc8, 0x48, 0x60, 0x82, 0x2e, 0x62, 0x63, 0xb3, 0x6b, 0x73, + 0x69, 0x7b, 0x23, 0xab, 0x63, 0x2b, 0x73, 0x31, 0x63, 0x0b, 0x3b, 0x9b, + 0x1b, 0x45, 0xc8, 0x03, 0x3d, 0x38, 0x85, 0x8d, 0xcd, 0xae, 0xcd, 0x25, + 0x8d, 0xac, 0xcc, 0x8d, 0x6e, 0x94, 0x60, 0x0f, 0x6e, 0x09, 0x4b, 0x93, + 0x73, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x1b, 0x25, 0xe0, 0x83, + 0xa3, 0xc2, 0xd2, 0xe4, 0x5c, 0xd8, 0xc2, 0xdc, 0xce, 0xea, 0xc2, 0xce, + 0xca, 0xbe, 0xec, 0xca, 0xe4, 0xe6, 0xd2, 0xde, 0xdc, 0x46, 0x09, 0xfa, + 0xe0, 0xa6, 0xb0, 0x34, 0x39, 0x97, 0xb1, 0xb7, 0x36, 0xb8, 0x34, 0xb6, + 0xb2, 0xaf, 0x37, 0x38, 0xba, 0xb4, 0x37, 0xb7, 0xb9, 0x51, 0x06, 0x3f, + 0xf8, 0x03, 0x50, 0x38, 0x26, 0x2c, 0x4d, 0xce, 0xc5, 0x4c, 0x2e, 0xec, + 0xac, 0xad, 0xcc, 0x8d, 0x6e, 0x94, 0x80, 0x15, 0x00, 0x00, 0x00, 0x00, + 0xa9, 0x18, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x0a, 0x72, 0x28, + 0x87, 0x77, 0x80, 0x07, 0x7a, 0x58, 0x70, 0x98, 0x43, 0x3d, 0xb8, 0xc3, + 0x38, 0xb0, 0x43, 0x39, 0xd0, 0xc3, 0x82, 0xe6, 0x1c, 0xc6, 0xa1, 0x0d, + 0xe8, 0x41, 0x1e, 0xc2, 0xc1, 0x1d, 0xe6, 0x21, 0x1d, 0xe8, 0x21, 0x1d, + 0xde, 0xc1, 0x1d, 0x00, 0xd1, 0x10, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x07, 0xcc, 0x3c, 0xa4, 0x83, 0x3b, 0x9c, 0x03, 0x3b, 0x94, 0x03, 0x3d, + 0xa0, 0x83, 0x3c, 0x94, 0x43, 0x38, 0x90, 0xc3, 0x01, 0x00, 0x00, 0x00, + 0x61, 0x20, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, + 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x6b, 0x60, 0x04, + 0x80, 0xe2, 0x0c, 0x00, 0xc9, 0x11, 0x80, 0xb1, 0x84, 0x00, 0xa0, 0x3b, + 0xd6, 0x00, 0x04, 0xc2, 0x1c, 0x83, 0x81, 0x61, 0x73, 0x0c, 0x06, 0x81, + 0x8d, 0x35, 0x00, 0x03, 0x41, 0x79, 0x04, 0x80, 0xc0, 0x08, 0xc0, 0x0c, + 0xc0, 0x18, 0x01, 0x08, 0x82, 0x20, 0xfe, 0x51, 0x98, 0x01, 0x98, 0x83, + 0x08, 0x83, 0x30, 0x08, 0x03, 0x31, 0x20, 0x31, 0x03, 0x00, 0x00, 0x00, + 0x23, 0x06, 0xcd, 0x10, 0x82, 0x60, 0x30, 0x91, 0xc1, 0x14, 0x55, 0x50, + 0xf3, 0x18, 0x06, 0x18, 0x8c, 0x26, 0x04, 0xc0, 0x20, 0x43, 0x50, 0x30, + 0x23, 0x06, 0xcd, 0x10, 0x82, 0x60, 0x30, 0x9d, 0x41, 0x45, 0x61, 0x13, + 0x24, 0x25, 0xc9, 0x18, 0x8c, 0x26, 0x04, 0xc0, 0x20, 0x43, 0x80, 0x44, + 0x83, 0x0c, 0xc1, 0xf1, 0x0c, 0x32, 0x14, 0xc1, 0x73, 0x1c, 0x5e, 0x0a, + 0x42, 0x19, 0x64, 0x08, 0x9a, 0xca, 0x88, 0x00, 0xfc, 0x37, 0x19, 0xc0, + 0x60, 0x72, 0x83, 0x0b, 0xf0, 0x52, 0x10, 0xca, 0x20, 0x43, 0x20, 0x69, + 0x23, 0x06, 0x87, 0x10, 0x82, 0x60, 0xe1, 0x1f, 0x4c, 0x1d, 0x14, 0xc1, + 0x26, 0x43, 0x19, 0x60, 0x74, 0x70, 0x01, 0x5e, 0x0a, 0x42, 0x19, 0x64, + 0x08, 0xae, 0x6f, 0xc4, 0xe0, 0x10, 0x42, 0x10, 0x2c, 0xfc, 0x83, 0xd1, + 0x03, 0x25, 0xd8, 0x64, 0x50, 0x83, 0xae, 0x0e, 0x2e, 0xc0, 0x4b, 0x41, + 0x28, 0x83, 0x0c, 0x01, 0x47, 0x06, 0x23, 0x06, 0x87, 0x10, 0x82, 0x60, + 0xe1, 0x1f, 0xcc, 0x1f, 0x3c, 0xc1, 0x1c, 0x43, 0xb7, 0xec, 0xc1, 0x1c, + 0x43, 0x70, 0xf8, 0xc1, 0x1c, 0x43, 0x30, 0x80, 0x82, 0x05, 0x74, 0x20, + 0xfe, 0x19, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x32, 0x0e, 0x10, 0x22, 0x84, 0x00, 0xfb, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x65, 0x0c, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, + 0x12, 0x03, 0x94, 0x38, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x39, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x24, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x08, 0x24, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x08, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, 0x0c, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0xe2, 0x00, 0x00, 0x00, 0x00, + 0x53, 0x44, 0x4c, 0x5f, 0x4e, 0x56, 0x32, 0x31, 0x5f, 0x66, 0x72, 0x61, + 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x69, 0x72, 0x2e, 0x64, 0x6f, 0x74, + 0x2e, 0x76, 0x33, 0x66, 0x33, 0x32, 0x61, 0x69, 0x72, 0x2e, 0x73, 0x61, + 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, + 0x5f, 0x32, 0x64, 0x2e, 0x76, 0x34, 0x66, 0x33, 0x32, 0x33, 0x31, 0x30, + 0x30, 0x31, 0x2e, 0x35, 0x30, 0x2e, 0x31, 0x61, 0x69, 0x72, 0x36, 0x34, + 0x2d, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2d, 0x69, 0x6f, 0x73, 0x31, 0x33, + 0x2e, 0x30, 0x2e, 0x30, 0x2d, 0x73, 0x69, 0x6d, 0x75, 0x6c, 0x61, 0x74, + 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; +const unsigned int sdl_metallib_len = 24660; diff --git a/SDL2-2.30.5/src/render/metal/SDL_shaders_metal_osx.h b/SDL2-2.30.5/src/render/metal/SDL_shaders_metal_osx.h new file mode 100644 index 0000000..2bec8a5 --- /dev/null +++ b/SDL2-2.30.5/src/render/metal/SDL_shaders_metal_osx.h @@ -0,0 +1,1825 @@ +const unsigned char sdl_metallib[] = { + 0x4d, 0x54, 0x4c, 0x42, 0x01, 0x80, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x62, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xac, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x72, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, + 0x4e, 0x41, 0x4d, 0x45, 0x11, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x53, 0x6f, + 0x6c, 0x69, 0x64, 0x5f, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x00, 0x54, + 0x59, 0x50, 0x45, 0x01, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x20, 0x00, + 0xb0, 0x1e, 0xd4, 0x63, 0x77, 0xeb, 0x95, 0x35, 0xec, 0xfd, 0x42, 0xfc, + 0x8f, 0x6c, 0xc0, 0x67, 0x91, 0x59, 0x50, 0x52, 0x7e, 0x6d, 0x23, 0xef, + 0x26, 0x6e, 0x78, 0xc7, 0x67, 0x3f, 0xa3, 0xda, 0x4f, 0x46, 0x46, 0x54, + 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x01, 0x00, 0x08, 0x00, + 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x77, 0x00, 0x00, 0x00, + 0x4e, 0x41, 0x4d, 0x45, 0x10, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x43, 0x6f, + 0x70, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x00, 0x54, 0x59, + 0x50, 0x45, 0x01, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x20, 0x00, 0xc6, + 0x60, 0xef, 0x78, 0xb0, 0x6b, 0x69, 0x3a, 0x1f, 0x4c, 0xad, 0xbb, 0xcb, + 0xbc, 0x96, 0x77, 0xac, 0xa6, 0xe1, 0x3b, 0x3b, 0x06, 0x4c, 0x64, 0x10, + 0xee, 0xfe, 0xc0, 0xb7, 0x24, 0x28, 0x70, 0x4f, 0x46, 0x46, 0x54, 0x18, + 0x00, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, + 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x7a, 0x00, 0x00, 0x00, 0x4e, + 0x41, 0x4d, 0x45, 0x13, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x53, 0x6f, 0x6c, + 0x69, 0x64, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x00, + 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, 0x53, 0x48, 0x20, + 0x00, 0xec, 0xda, 0x64, 0x8c, 0x89, 0xb3, 0x61, 0x32, 0x78, 0xa4, 0x67, + 0x9d, 0xd2, 0xad, 0x75, 0x55, 0x9d, 0xec, 0xf8, 0x6d, 0xc9, 0xb1, 0x4a, + 0x94, 0xac, 0x2d, 0x9a, 0x29, 0xed, 0xf5, 0x72, 0x3e, 0x4f, 0x46, 0x46, + 0x54, 0x18, 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x17, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x01, 0x00, 0x08, + 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x79, 0x00, 0x00, + 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x12, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x43, + 0x6f, 0x70, 0x79, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, + 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, 0x53, 0x48, + 0x20, 0x00, 0x8c, 0xa9, 0xc1, 0x5f, 0x0c, 0x8d, 0x69, 0xe0, 0xac, 0x20, + 0x39, 0x45, 0xb5, 0x81, 0x5a, 0xbd, 0x1a, 0xb2, 0x48, 0xa8, 0xe7, 0x81, + 0x31, 0x3b, 0x3a, 0x22, 0x20, 0xe2, 0xb9, 0xf7, 0x71, 0x8f, 0x4f, 0x46, + 0x46, 0x54, 0x18, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x01, 0x00, + 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x78, 0x00, + 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x11, 0x00, 0x53, 0x44, 0x4c, 0x5f, + 0x59, 0x55, 0x56, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, + 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, 0x53, 0x48, + 0x20, 0x00, 0x21, 0x22, 0xf2, 0x05, 0x0d, 0x3c, 0xbe, 0x5c, 0xe3, 0xc5, + 0xe5, 0xf2, 0x92, 0x32, 0x24, 0xf8, 0xeb, 0xfe, 0xd1, 0xe9, 0x4e, 0xc0, + 0x0f, 0x88, 0x2e, 0xf5, 0xfd, 0x77, 0x98, 0x5e, 0x6a, 0x30, 0x4f, 0x46, + 0x46, 0x54, 0x18, 0x00, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x01, 0x00, + 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x79, 0x00, + 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x12, 0x00, 0x53, 0x44, 0x4c, 0x5f, + 0x4e, 0x56, 0x31, 0x32, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, + 0x74, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, 0x53, + 0x48, 0x20, 0x00, 0xe5, 0xd5, 0x21, 0xe2, 0x33, 0x80, 0x3a, 0xf8, 0xa1, + 0x58, 0x1b, 0xcc, 0x61, 0xe3, 0xba, 0xd9, 0x3e, 0xc3, 0x5a, 0xaa, 0xbc, + 0x0c, 0x67, 0x0a, 0x41, 0xcc, 0x77, 0xb3, 0xb8, 0x43, 0x43, 0x43, 0x4f, + 0x46, 0x46, 0x54, 0x18, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x37, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x01, + 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x79, + 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x12, 0x00, 0x53, 0x44, 0x4c, + 0x5f, 0x4e, 0x56, 0x32, 0x31, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, + 0x6e, 0x74, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, + 0x53, 0x48, 0x20, 0x00, 0xd2, 0x98, 0x77, 0xab, 0xf4, 0x02, 0x99, 0x2b, + 0x5d, 0xda, 0xac, 0xe3, 0x25, 0xb7, 0xe0, 0xfd, 0x5f, 0x85, 0x65, 0x3b, + 0x16, 0xb8, 0x21, 0xa3, 0x6e, 0x13, 0x5b, 0x11, 0x32, 0x77, 0xca, 0xc2, + 0x4f, 0x46, 0x46, 0x54, 0x18, 0x00, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x44, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, + 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, + 0x45, 0x4e, 0x44, 0x54, 0x29, 0x00, 0x00, 0x00, 0x56, 0x41, 0x54, 0x54, + 0x15, 0x00, 0x02, 0x00, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x00, 0x00, 0x80, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x01, 0x80, 0x56, + 0x41, 0x54, 0x59, 0x04, 0x00, 0x02, 0x00, 0x04, 0x06, 0x45, 0x4e, 0x44, + 0x54, 0x35, 0x00, 0x00, 0x00, 0x56, 0x41, 0x54, 0x54, 0x20, 0x00, 0x03, + 0x00, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x80, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x01, 0x80, 0x74, 0x65, 0x78, 0x63, + 0x6f, 0x6f, 0x72, 0x64, 0x00, 0x02, 0x80, 0x56, 0x41, 0x54, 0x59, 0x05, + 0x00, 0x03, 0x00, 0x04, 0x06, 0x04, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, + 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, + 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, + 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, + 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, + 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, + 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, + 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, + 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0xde, 0xc0, + 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xa4, 0x0b, + 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, + 0x00, 0x00, 0xe6, 0x02, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, + 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, + 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, + 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, + 0x44, 0x24, 0x48, 0x0a, 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, + 0x21, 0x72, 0x24, 0x07, 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, + 0xc6, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x83, 0x00, + 0x00, 0x00, 0x1b, 0xc8, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x90, + 0x80, 0x8a, 0x18, 0x87, 0x77, 0x90, 0x07, 0x79, 0x28, 0x87, 0x71, 0xa0, + 0x07, 0x76, 0xc8, 0x87, 0x36, 0x90, 0x87, 0x77, 0xa8, 0x07, 0x77, 0x20, + 0x87, 0x72, 0x20, 0x87, 0x36, 0x20, 0x87, 0x74, 0xb0, 0x87, 0x74, 0x20, + 0x87, 0x72, 0x68, 0x83, 0x79, 0x88, 0x07, 0x79, 0xa0, 0x87, 0x36, 0x30, + 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0xc0, 0x1c, + 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1c, 0xd2, 0x61, 0x1e, + 0xc2, 0x41, 0x1c, 0xd8, 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xc2, 0x21, 0x1d, + 0xd8, 0xa1, 0x0d, 0xc6, 0x21, 0x1c, 0xd8, 0x81, 0x1d, 0xe6, 0x01, 0x30, + 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x60, 0x87, 0x72, 0x98, + 0x87, 0x79, 0x68, 0x03, 0x78, 0x90, 0x87, 0x72, 0x18, 0x87, 0x74, 0x98, + 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x76, 0x08, 0x07, 0x72, 0x00, + 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, + 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, + 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, + 0xd8, 0x21, 0x1d, 0xda, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, + 0x06, 0x77, 0x78, 0x87, 0x36, 0x30, 0x07, 0x79, 0x08, 0x87, 0x76, 0x28, + 0x87, 0x36, 0x80, 0x87, 0x77, 0x48, 0x07, 0x77, 0xa0, 0x87, 0x72, 0x90, + 0x87, 0x36, 0x28, 0x07, 0x76, 0x48, 0x87, 0x76, 0x68, 0x03, 0x77, 0x78, + 0x07, 0x77, 0x68, 0x03, 0x76, 0x28, 0x87, 0x70, 0x30, 0x07, 0x80, 0x70, + 0x87, 0x77, 0x68, 0x83, 0x74, 0x70, 0x07, 0x73, 0x98, 0x87, 0x36, 0x30, + 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, + 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x40, 0x1d, + 0xea, 0xa1, 0x1d, 0xe0, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xc4, 0x81, 0x1d, + 0xca, 0x61, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, + 0x08, 0x77, 0x78, 0x87, 0x36, 0x70, 0x87, 0x70, 0x70, 0x87, 0x79, 0x68, + 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, + 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, + 0xe6, 0x21, 0x1d, 0xce, 0xc1, 0x1d, 0xca, 0x81, 0x1c, 0xda, 0x40, 0x1f, + 0xca, 0x41, 0x1e, 0xde, 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, + 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, + 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x7a, 0x90, 0x87, 0x70, 0x80, + 0x07, 0x78, 0x48, 0x07, 0x77, 0x38, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, + 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0x62, 0x1e, + 0xe8, 0x21, 0x1c, 0xc6, 0x61, 0x1d, 0xda, 0x00, 0x1e, 0xe4, 0xe1, 0x1d, + 0xe8, 0xa1, 0x1c, 0xc6, 0x81, 0x1e, 0xde, 0x41, 0x1e, 0xda, 0x40, 0x1c, + 0xea, 0xc1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, + 0xf4, 0xa1, 0x1c, 0x00, 0x3c, 0x00, 0x88, 0x7a, 0x70, 0x87, 0x79, 0x08, + 0x07, 0x73, 0x28, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, + 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, + 0xea, 0x61, 0x1e, 0xca, 0xa1, 0x0d, 0xe6, 0xe1, 0x1d, 0xcc, 0x81, 0x1e, + 0xda, 0xc0, 0x1c, 0xd8, 0xe1, 0x1d, 0xc2, 0x81, 0x1e, 0x00, 0x73, 0x08, + 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x36, 0x18, 0xc2, 0x00, 0x2c, 0x40, + 0xb5, 0xc1, 0x18, 0x08, 0x60, 0x01, 0x2a, 0x00, 0x00, 0x00, 0x49, 0x18, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x86, 0x40, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x32, 0x22, + 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, + 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, + 0xa4, 0x4c, 0x10, 0x40, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x60, 0x87, 0x10, + 0xc0, 0x30, 0x82, 0x00, 0x24, 0x41, 0x98, 0x89, 0x9a, 0x07, 0x7a, 0x90, + 0x87, 0x7a, 0x18, 0x07, 0x7a, 0x70, 0x83, 0x76, 0x28, 0x07, 0x7a, 0x08, + 0x07, 0x76, 0xd0, 0x03, 0x3d, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x79, 0x48, + 0x07, 0x7c, 0x40, 0x01, 0x19, 0x44, 0x28, 0x84, 0x52, 0x88, 0x11, 0x8c, + 0xa1, 0x33, 0x10, 0x30, 0x47, 0x00, 0x06, 0x29, 0xa0, 0xe6, 0x08, 0x40, + 0x61, 0x10, 0x21, 0x10, 0x86, 0x11, 0x08, 0x65, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x13, 0xb2, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, + 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x76, 0x08, + 0x87, 0x71, 0x78, 0x87, 0x79, 0xc0, 0x87, 0x38, 0x80, 0x03, 0x37, 0x88, + 0x83, 0x38, 0x70, 0x03, 0x38, 0xd8, 0x70, 0x1b, 0xe5, 0xd0, 0x06, 0xf0, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, + 0xd0, 0x06, 0xe9, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, + 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, + 0x60, 0x07, 0x6d, 0x90, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, + 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, + 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0e, 0x73, + 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, + 0x60, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, + 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x40, 0x07, 0x7a, + 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x73, + 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, + 0x60, 0x0f, 0x74, 0x80, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x79, 0x60, 0x07, 0x7a, + 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, + 0x60, 0x0f, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, + 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x79, + 0x20, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, + 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, + 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, + 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, + 0x50, 0x07, 0x71, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x00, 0x07, 0x72, + 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, + 0x00, 0x07, 0x72, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, + 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0x30, 0x84, 0x41, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x02, 0x01, 0x00, 0x00, 0x0a, 0x00, + 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, + 0x26, 0x47, 0xc6, 0x04, 0x43, 0x52, 0x25, 0x30, 0x02, 0x50, 0x80, 0x01, + 0x45, 0x50, 0x20, 0x65, 0x50, 0x08, 0x05, 0x41, 0x6c, 0x04, 0x80, 0xd6, + 0x58, 0xc2, 0x12, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0xe4, 0x00, + 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, 0x10, 0xab, + 0x32, 0xb9, 0xb9, 0xb4, 0x37, 0xb7, 0x21, 0x86, 0x42, 0x24, 0xc0, 0xa2, + 0x50, 0xb9, 0x1b, 0x43, 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x1b, + 0x62, 0x28, 0x41, 0x22, 0x28, 0x07, 0xe5, 0x20, 0x08, 0x0e, 0x8e, 0xad, + 0x0c, 0x84, 0x89, 0xc9, 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, 0x2e, 0xed, + 0xcd, 0x0d, 0x64, 0x26, 0x06, 0x06, 0x26, 0xc6, 0x25, 0xc6, 0x06, 0x06, + 0x04, 0xa5, 0xad, 0x8c, 0x2e, 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, 0x06, + 0x06, 0x26, 0xc6, 0x25, 0xc6, 0x06, 0xc6, 0x25, 0x26, 0x65, 0x88, 0x90, + 0x10, 0x43, 0x0c, 0x25, 0x50, 0x10, 0x45, 0x60, 0xd1, 0x54, 0x46, 0x17, + 0xc6, 0x36, 0x04, 0x49, 0x0e, 0x25, 0x50, 0x02, 0x45, 0xe0, 0x16, 0x96, + 0x26, 0xe7, 0x32, 0xf6, 0xd6, 0x06, 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, + 0xe6, 0xf6, 0x26, 0xd7, 0x36, 0xf7, 0x45, 0x96, 0x36, 0x17, 0x26, 0xc6, + 0x56, 0x36, 0x44, 0x48, 0x12, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, + 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, + 0x61, 0x74, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x84, + 0x64, 0x61, 0x19, 0x84, 0xa5, 0xc9, 0xb9, 0x8c, 0xbd, 0xb5, 0xc1, 0xa5, + 0xb1, 0x95, 0xb9, 0x98, 0xc9, 0x85, 0xb5, 0x95, 0x89, 0xd5, 0x99, 0x99, + 0x95, 0xc9, 0x7d, 0x99, 0x95, 0xd1, 0x8d, 0xa1, 0x7d, 0x91, 0xa5, 0xcd, + 0x85, 0x89, 0xb1, 0x95, 0x0d, 0x11, 0x92, 0x86, 0x4c, 0x58, 0x9a, 0x9c, + 0x0b, 0xdc, 0xdb, 0x5c, 0x1a, 0x5d, 0xda, 0x9b, 0x1b, 0xa3, 0xb0, 0x34, + 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0x2f, 0xb7, + 0xb0, 0xb6, 0x32, 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x64, 0xc2, + 0xd2, 0xe4, 0x5c, 0xc2, 0xe4, 0xce, 0xbe, 0xdc, 0xc2, 0xda, 0xca, 0x88, + 0xc0, 0xbd, 0xcd, 0xa5, 0xd1, 0xa5, 0xbd, 0xb9, 0x0d, 0x51, 0x92, 0x27, + 0x81, 0x92, 0x28, 0x91, 0x92, 0x89, 0x51, 0x58, 0x9a, 0x9c, 0x8b, 0x5d, + 0x99, 0x1c, 0x5d, 0x19, 0xde, 0xd7, 0x5b, 0x1d, 0x1d, 0x5c, 0x1d, 0x1d, + 0xad, 0xb3, 0x32, 0xb7, 0x32, 0xb9, 0x30, 0xba, 0x32, 0x32, 0x94, 0x9a, + 0xb1, 0x37, 0xb6, 0x37, 0x39, 0x22, 0x3b, 0x9a, 0x2f, 0xb3, 0x14, 0x16, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x43, 0x98, 0xa4, 0x4a, 0xac, 0x04, 0x4a, + 0xa2, 0x44, 0x4a, 0x2e, 0x3a, 0x61, 0x69, 0x72, 0x2e, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x2c, 0xcc, 0xd8, 0xde, 0xc2, + 0xe8, 0x98, 0xc0, 0xbd, 0xa5, 0xb9, 0xd1, 0x4d, 0xa5, 0xe9, 0x95, 0x0d, + 0x51, 0x92, 0x2c, 0x81, 0x12, 0x2d, 0x91, 0x92, 0x6d, 0x88, 0x91, 0x50, + 0x09, 0x96, 0x70, 0x84, 0xc2, 0xd2, 0xe4, 0x5c, 0xec, 0xca, 0xe4, 0xe8, + 0xca, 0xf0, 0xbe, 0xd2, 0xdc, 0xe0, 0xea, 0xe8, 0x28, 0x85, 0xa5, 0xc9, + 0xb9, 0xb0, 0xbd, 0x8d, 0x85, 0xd1, 0xa5, 0xbd, 0xb9, 0x7d, 0xa5, 0xb9, + 0x91, 0x95, 0xe1, 0xd1, 0x3b, 0x2b, 0x73, 0x2b, 0x93, 0x0b, 0xa3, 0x2b, + 0x23, 0x43, 0xf9, 0xfa, 0x0a, 0x4b, 0x93, 0xfb, 0x82, 0x63, 0x0b, 0x1b, + 0x2b, 0x43, 0x7b, 0x63, 0x23, 0x2b, 0x93, 0xfb, 0xfa, 0x4a, 0xa1, 0x61, + 0xc6, 0xf6, 0x16, 0x46, 0x27, 0x33, 0x84, 0x52, 0x84, 0xc4, 0x4b, 0x3e, + 0x45, 0x50, 0x82, 0x04, 0x0c, 0x12, 0x28, 0x09, 0x83, 0x44, 0x4a, 0xa6, + 0x21, 0x94, 0x12, 0x24, 0x5e, 0xf2, 0x29, 0x81, 0x12, 0x24, 0x60, 0x90, + 0x40, 0x49, 0x94, 0x48, 0xc9, 0x45, 0x25, 0x2c, 0x4d, 0xce, 0x45, 0xac, + 0xce, 0xcc, 0xac, 0x4c, 0x8e, 0x4f, 0x58, 0x9a, 0x9c, 0x8b, 0x58, 0x9d, + 0x99, 0x59, 0x99, 0xdc, 0xd7, 0x5c, 0x9a, 0x5e, 0x19, 0x91, 0xb0, 0x34, + 0x39, 0x17, 0xb9, 0xb2, 0x30, 0x32, 0x46, 0x61, 0x69, 0x72, 0x2e, 0x61, + 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, + 0xbc, 0xc2, 0xd2, 0xe4, 0x5c, 0xc2, 0xe4, 0xce, 0xbe, 0xe8, 0xf2, 0xe0, + 0xca, 0xbe, 0xc2, 0xd8, 0xd2, 0xce, 0xdc, 0xbe, 0xe6, 0xd2, 0xf4, 0xca, + 0x88, 0x98, 0xb1, 0xbd, 0x85, 0xd1, 0xd1, 0xe0, 0xd1, 0x50, 0x81, 0x93, + 0x7b, 0x53, 0x2b, 0x1b, 0xa3, 0x4b, 0x7b, 0x73, 0x1b, 0x02, 0x06, 0x0a, + 0x91, 0x90, 0x41, 0x52, 0x06, 0xca, 0x90, 0x7c, 0x0a, 0xa1, 0x04, 0x89, + 0x19, 0x24, 0x67, 0xa0, 0x0c, 0x09, 0x1a, 0x28, 0x45, 0x02, 0x25, 0x69, + 0x90, 0x48, 0x89, 0x1a, 0x30, 0xa1, 0x93, 0x0b, 0x73, 0x9b, 0x33, 0x7b, + 0x93, 0x6b, 0x1b, 0x02, 0x06, 0x8a, 0x91, 0x90, 0x41, 0x52, 0x06, 0xca, + 0x90, 0x7c, 0x8a, 0xa1, 0x04, 0x89, 0x19, 0x24, 0x67, 0xa0, 0x0c, 0x09, + 0x1a, 0x28, 0x45, 0x02, 0x25, 0x69, 0x90, 0x48, 0x09, 0x1b, 0x0c, 0x41, + 0x12, 0x31, 0x48, 0xc6, 0x20, 0x59, 0x83, 0xa4, 0x0d, 0x86, 0x18, 0x08, + 0x90, 0x74, 0x89, 0x1b, 0xf0, 0x79, 0x6b, 0x73, 0x4b, 0x83, 0x7b, 0xa3, + 0x2b, 0x73, 0xa3, 0x03, 0x19, 0x43, 0x0b, 0x93, 0xe3, 0x33, 0x95, 0xd6, + 0x06, 0xc7, 0x56, 0x06, 0x32, 0xb4, 0xb2, 0x02, 0x42, 0x25, 0x14, 0x14, + 0x34, 0x44, 0x48, 0xe2, 0x60, 0x88, 0x91, 0xc0, 0x41, 0x22, 0x07, 0x4c, + 0x32, 0xc4, 0x48, 0xe6, 0x20, 0x99, 0x03, 0x26, 0x19, 0x11, 0xb1, 0x03, + 0x3b, 0xd8, 0x43, 0x3b, 0xb8, 0x41, 0x3b, 0xbc, 0x03, 0x39, 0xd4, 0x03, + 0x3b, 0x94, 0x83, 0x1b, 0x98, 0x03, 0x3b, 0x84, 0xc3, 0x39, 0xcc, 0xc3, + 0x14, 0x21, 0x18, 0x46, 0x28, 0xec, 0xc0, 0x0e, 0xf6, 0xd0, 0x0e, 0x6e, + 0x90, 0x0e, 0xe4, 0x50, 0x0e, 0xee, 0x40, 0x0f, 0x53, 0x82, 0x62, 0xc4, + 0x12, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0x60, 0x0f, 0xe5, 0x20, 0x0f, 0xf3, + 0x90, 0x0e, 0xef, 0xe0, 0x0e, 0x53, 0x02, 0x63, 0x04, 0x15, 0x0e, 0xe9, + 0x20, 0x0f, 0x6e, 0xc0, 0x0e, 0xe1, 0xe0, 0x0e, 0xe7, 0x50, 0x0f, 0xe1, + 0x70, 0x0e, 0xe5, 0xf0, 0x0b, 0xf6, 0x50, 0x0e, 0xf2, 0x30, 0x0f, 0xe9, + 0xf0, 0x0e, 0xee, 0x30, 0x25, 0x40, 0x46, 0x4c, 0xe1, 0x90, 0x0e, 0xf2, + 0xe0, 0x06, 0xe3, 0xf0, 0x0e, 0xed, 0x00, 0x0f, 0xe9, 0xc0, 0x0e, 0xe5, + 0xf0, 0x0b, 0xef, 0x00, 0x0f, 0xf4, 0x90, 0x0e, 0xef, 0xe0, 0x0e, 0xf3, + 0x30, 0x65, 0x50, 0x18, 0x67, 0x84, 0x12, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, + 0x60, 0x0f, 0xe5, 0x20, 0x0f, 0xf4, 0x50, 0x0e, 0xf8, 0x30, 0x25, 0x78, + 0x03, 0x00, 0x79, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, + 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, + 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, + 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, + 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, + 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, + 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, + 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, + 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, + 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, + 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, + 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, + 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, + 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, + 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, + 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, + 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, + 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, + 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, + 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, + 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, + 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, + 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, + 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, + 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, + 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, + 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, + 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, + 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, + 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, + 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, + 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, + 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, + 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, + 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, + 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, + 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, + 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, + 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, + 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, + 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, + 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0xb1, 0x5d, 0xf9, 0xb3, + 0xce, 0x82, 0x0c, 0x7f, 0x45, 0x44, 0x13, 0x71, 0x01, 0x00, 0x61, 0x20, + 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, + 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0xe4, 0xc6, 0x22, 0x86, 0x61, 0x18, + 0xc6, 0x22, 0x04, 0x41, 0x10, 0xc6, 0x22, 0x82, 0x20, 0x08, 0x46, 0x00, + 0x88, 0x95, 0x40, 0x19, 0x14, 0x01, 0x8d, 0x19, 0x00, 0x12, 0x33, 0x00, + 0x14, 0x66, 0x00, 0x08, 0x8c, 0x11, 0x80, 0x20, 0x08, 0xe2, 0x1f, 0x00, + 0x00, 0x00, 0xe3, 0x11, 0x4c, 0x84, 0x45, 0x14, 0x94, 0xf1, 0x88, 0x67, + 0xd2, 0x26, 0x0a, 0xca, 0x20, 0xc3, 0x60, 0x30, 0x26, 0x04, 0xf2, 0x19, + 0x8f, 0x98, 0x2e, 0xaf, 0xa1, 0xa0, 0x0c, 0x32, 0x1c, 0x4a, 0x64, 0x42, + 0x20, 0x1f, 0x0b, 0x0a, 0xf8, 0x8c, 0x47, 0x60, 0xdc, 0x18, 0x40, 0x14, + 0x94, 0x41, 0x06, 0xe6, 0xb9, 0x4c, 0x08, 0xe4, 0x63, 0x45, 0x00, 0x9f, + 0xf1, 0x88, 0x2e, 0x0c, 0xd0, 0xc0, 0xa2, 0xa0, 0x0c, 0x32, 0x44, 0x54, + 0x67, 0x42, 0x20, 0x1f, 0x2b, 0x02, 0xf8, 0x8c, 0x47, 0x84, 0x81, 0x19, + 0xb4, 0x01, 0x47, 0x41, 0x19, 0x64, 0x08, 0xb2, 0xcf, 0x82, 0x4a, 0x3e, + 0x83, 0x0c, 0xc3, 0x26, 0x06, 0x16, 0x4c, 0xf2, 0xb1, 0x21, 0x80, 0xcf, + 0x20, 0x83, 0xe1, 0x99, 0x81, 0x05, 0x91, 0x7c, 0x6c, 0x08, 0xe0, 0x33, + 0xc8, 0x90, 0x84, 0x81, 0x1a, 0x58, 0xf0, 0xc8, 0xc7, 0x86, 0x00, 0x3e, + 0xe3, 0x11, 0x6e, 0x30, 0x07, 0x7a, 0x80, 0x06, 0x14, 0x94, 0x41, 0x86, + 0xc0, 0x0c, 0xd8, 0xc0, 0x02, 0x31, 0x90, 0xcf, 0x20, 0xc3, 0x80, 0x06, + 0x6f, 0x60, 0x01, 0x18, 0xc8, 0x67, 0x90, 0xa1, 0x50, 0x03, 0x39, 0xb0, + 0xa0, 0x93, 0xcf, 0x20, 0xc3, 0xc1, 0x06, 0x75, 0x60, 0x81, 0x26, 0x9f, + 0x41, 0x86, 0x3d, 0x80, 0x03, 0x3a, 0xb0, 0x2c, 0x90, 0xcf, 0x20, 0x43, + 0x1f, 0xc8, 0xc1, 0x1d, 0x98, 0x13, 0xc8, 0xc7, 0x92, 0x01, 0x3e, 0x16, + 0x30, 0xf0, 0xb1, 0x20, 0x81, 0x8f, 0x05, 0x08, 0x7c, 0x2c, 0x28, 0xe0, + 0x33, 0xdb, 0x80, 0x07, 0x01, 0x30, 0xdb, 0x10, 0x90, 0x42, 0x30, 0xdb, + 0x10, 0xe0, 0x81, 0x90, 0x41, 0x40, 0x0c, 0x00, 0x00, 0x00, 0x09, 0x00, + 0x00, 0x00, 0x5b, 0x86, 0x20, 0xa0, 0x83, 0x2d, 0xc3, 0x10, 0xd0, 0xc1, + 0x96, 0xe1, 0x08, 0xe8, 0x60, 0xcb, 0xc0, 0x04, 0x74, 0xb0, 0x65, 0x88, + 0x02, 0x3a, 0xd8, 0x32, 0x58, 0x01, 0x1d, 0x6c, 0x19, 0xc6, 0x20, 0xa0, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, + 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xb4, 0x0b, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0xea, 0x02, + 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, + 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, + 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, + 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, 0x44, 0x24, 0x48, 0x0a, + 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, 0x21, 0x72, 0x24, 0x07, + 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, + 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x1b, 0xc8, + 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x90, 0x80, 0x8a, 0x18, 0x87, + 0x77, 0x90, 0x07, 0x79, 0x28, 0x87, 0x71, 0xa0, 0x07, 0x76, 0xc8, 0x87, + 0x36, 0x90, 0x87, 0x77, 0xa8, 0x07, 0x77, 0x20, 0x87, 0x72, 0x20, 0x87, + 0x36, 0x20, 0x87, 0x74, 0xb0, 0x87, 0x74, 0x20, 0x87, 0x72, 0x68, 0x83, + 0x79, 0x88, 0x07, 0x79, 0xa0, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, + 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, + 0xa1, 0x1c, 0x00, 0x82, 0x1c, 0xd2, 0x61, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, + 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xc2, 0x21, 0x1d, 0xd8, 0xa1, 0x0d, 0xc6, + 0x21, 0x1c, 0xd8, 0x81, 0x1d, 0xe6, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, + 0x79, 0x28, 0x07, 0x80, 0x60, 0x87, 0x72, 0x98, 0x87, 0x79, 0x68, 0x03, + 0x78, 0x90, 0x87, 0x72, 0x18, 0x87, 0x74, 0x98, 0x87, 0x72, 0x68, 0x03, + 0x73, 0x80, 0x87, 0x76, 0x08, 0x07, 0x72, 0x00, 0xcc, 0x21, 0x1c, 0xd8, + 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, + 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, + 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, + 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x06, 0x77, 0x78, 0x87, + 0x36, 0x30, 0x07, 0x79, 0x08, 0x87, 0x76, 0x28, 0x87, 0x36, 0x80, 0x87, + 0x77, 0x48, 0x07, 0x77, 0xa0, 0x87, 0x72, 0x90, 0x87, 0x36, 0x28, 0x07, + 0x76, 0x48, 0x87, 0x76, 0x68, 0x03, 0x77, 0x78, 0x07, 0x77, 0x68, 0x03, + 0x76, 0x28, 0x87, 0x70, 0x30, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x83, + 0x74, 0x70, 0x07, 0x73, 0x98, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, + 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, + 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x40, 0x1d, 0xea, 0xa1, 0x1d, 0xe0, + 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x1e, 0x00, + 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, + 0x36, 0x70, 0x87, 0x70, 0x70, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, + 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, + 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xce, + 0xc1, 0x1d, 0xca, 0x81, 0x1c, 0xda, 0x40, 0x1f, 0xca, 0x41, 0x1e, 0xde, + 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, + 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, + 0x77, 0x68, 0x03, 0x7a, 0x90, 0x87, 0x70, 0x80, 0x07, 0x78, 0x48, 0x07, + 0x77, 0x38, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, + 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0x62, 0x1e, 0xe8, 0x21, 0x1c, 0xc6, + 0x61, 0x1d, 0xda, 0x00, 0x1e, 0xe4, 0xe1, 0x1d, 0xe8, 0xa1, 0x1c, 0xc6, + 0x81, 0x1e, 0xde, 0x41, 0x1e, 0xda, 0x40, 0x1c, 0xea, 0xc1, 0x1c, 0xcc, + 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xf4, 0xa1, 0x1c, 0x00, + 0x3c, 0x00, 0x88, 0x7a, 0x70, 0x87, 0x79, 0x08, 0x07, 0x73, 0x28, 0x87, + 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, + 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xea, 0x61, 0x1e, 0xca, + 0xa1, 0x0d, 0xe6, 0xe1, 0x1d, 0xcc, 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xd8, + 0xe1, 0x1d, 0xc2, 0x81, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, + 0x72, 0x00, 0x36, 0x18, 0x02, 0x01, 0x2c, 0x40, 0xb5, 0xc1, 0x18, 0x0a, + 0x60, 0x01, 0x2a, 0x00, 0x00, 0x00, 0x49, 0x18, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x13, 0x86, 0x40, 0x18, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, + 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, + 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, + 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x40, + 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, 0x00, 0x76, 0x08, 0x41, + 0x24, 0x41, 0x98, 0x89, 0x9a, 0x07, 0x7a, 0x90, 0x87, 0x7a, 0x18, 0x07, + 0x7a, 0x70, 0x83, 0x76, 0x28, 0x07, 0x7a, 0x08, 0x07, 0x76, 0xd0, 0x03, + 0x3d, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x79, 0x48, 0x07, 0x7c, 0x40, 0x01, + 0x19, 0x44, 0x28, 0x84, 0x62, 0x0c, 0x11, 0x84, 0x31, 0x74, 0x06, 0x02, + 0xe6, 0x08, 0xc0, 0x20, 0x05, 0xd4, 0x1c, 0x01, 0x28, 0x0c, 0x22, 0x04, + 0xc2, 0x30, 0x02, 0xa1, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xb2, + 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, + 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x76, 0x08, 0x87, 0x71, 0x78, 0x87, + 0x79, 0xc0, 0x87, 0x38, 0x80, 0x03, 0x37, 0x88, 0x83, 0x38, 0x70, 0x03, + 0x38, 0xd8, 0x70, 0x1b, 0xe5, 0xd0, 0x06, 0xf0, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x90, + 0x0e, 0x71, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x80, + 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, + 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x90, + 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, + 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, + 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x76, 0x40, + 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, + 0x0f, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, + 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x40, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x73, 0x20, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x74, 0x80, + 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, + 0x0f, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x6d, 0x60, 0x0f, 0x79, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, + 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x20, + 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, + 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x79, 0x20, 0x07, 0x7a, 0x20, + 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, + 0x0f, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, + 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x50, 0x07, 0x71, 0x20, + 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, + 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, + 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, + 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0x30, 0x84, 0x41, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc8, 0x02, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x32, 0x1e, + 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, + 0x43, 0x52, 0x25, 0x50, 0x04, 0x23, 0x00, 0x05, 0x18, 0x50, 0x08, 0x65, + 0x50, 0x20, 0x05, 0x41, 0x6c, 0x04, 0x80, 0xd6, 0x58, 0xc2, 0x12, 0x00, + 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, 0x1a, 0x03, + 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4, + 0x37, 0xb7, 0x21, 0x86, 0x22, 0x24, 0xc0, 0xa2, 0x50, 0xb9, 0x1b, 0x43, + 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x1b, 0x62, 0x28, 0x41, 0x22, + 0x28, 0x05, 0xe5, 0x20, 0x08, 0x0e, 0x8e, 0xad, 0x0c, 0x84, 0x89, 0xc9, + 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x0d, 0x64, 0x26, + 0x06, 0x06, 0x26, 0xc6, 0x25, 0xc6, 0x06, 0x06, 0x04, 0xa5, 0xad, 0x8c, + 0x2e, 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, 0x06, 0x06, 0x26, 0xc6, 0x25, + 0xc6, 0x06, 0xc6, 0x25, 0x26, 0x65, 0x88, 0x90, 0x10, 0x43, 0x0c, 0x25, + 0x50, 0x10, 0x65, 0x60, 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, 0x04, 0x49, + 0x0e, 0x25, 0x50, 0x02, 0x65, 0xe0, 0x16, 0x96, 0x26, 0xe7, 0x32, 0xf6, + 0xd6, 0x06, 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, 0x26, 0xd7, + 0x36, 0xf7, 0x45, 0x96, 0x36, 0x17, 0x26, 0xc6, 0x56, 0x36, 0x44, 0x48, + 0x12, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, + 0x65, 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, + 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x84, 0x64, 0x61, 0x19, 0x84, + 0xa5, 0xc9, 0xb9, 0x8c, 0xbd, 0xb5, 0xc1, 0xa5, 0xb1, 0x95, 0xb9, 0x98, + 0xc9, 0x85, 0xb5, 0x95, 0x89, 0xd5, 0x99, 0x99, 0x95, 0xc9, 0x7d, 0x99, + 0x95, 0xd1, 0x8d, 0xa1, 0x7d, 0x91, 0xa5, 0xcd, 0x85, 0x89, 0xb1, 0x95, + 0x0d, 0x11, 0x92, 0x86, 0x4c, 0x58, 0x9a, 0x9c, 0x0b, 0xdc, 0xdb, 0x5c, + 0x1a, 0x5d, 0xda, 0x9b, 0x1b, 0xa3, 0xb0, 0x34, 0x39, 0x97, 0x30, 0xb9, + 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0x2f, 0xb7, 0xb0, 0xb6, 0x32, 0x1a, + 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x64, 0xc2, 0xd2, 0xe4, 0x5c, 0xc2, + 0xe4, 0xce, 0xbe, 0xdc, 0xc2, 0xda, 0xca, 0x88, 0xc0, 0xbd, 0xcd, 0xa5, + 0xd1, 0xa5, 0xbd, 0xb9, 0x0d, 0x51, 0x92, 0x27, 0x81, 0x92, 0x28, 0x91, + 0x92, 0x89, 0x51, 0x58, 0x9a, 0x9c, 0x8b, 0x5d, 0x99, 0x1c, 0x5d, 0x19, + 0xde, 0xd7, 0x5b, 0x1d, 0x1d, 0x5c, 0x1d, 0x1d, 0xad, 0xb3, 0x32, 0xb7, + 0x32, 0xb9, 0x30, 0xba, 0x32, 0x32, 0x94, 0x9a, 0xb1, 0x37, 0xb6, 0x37, + 0x39, 0x22, 0x3b, 0x9a, 0x2f, 0xb3, 0x14, 0x16, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x43, 0x98, 0xa4, 0x4a, 0xac, 0x04, 0x4a, 0xa2, 0x44, 0x4a, 0x2e, + 0x66, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x38, + 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x44, 0x76, 0x32, 0x5f, + 0x66, 0x29, 0x34, 0xcc, 0xd8, 0xde, 0xc2, 0xe8, 0x64, 0x88, 0xd0, 0x95, + 0xe1, 0x8d, 0xbd, 0xbd, 0xc9, 0x91, 0x0d, 0x61, 0x92, 0x2a, 0xc9, 0x12, + 0x28, 0xd1, 0x12, 0x29, 0xd9, 0x86, 0x18, 0x09, 0x95, 0x60, 0x09, 0x47, + 0x28, 0x2c, 0x4d, 0xce, 0xc5, 0xae, 0x4c, 0x8e, 0xae, 0x0c, 0xef, 0x2b, + 0xcd, 0x0d, 0xae, 0x8e, 0x8e, 0x52, 0x58, 0x9a, 0x9c, 0x0b, 0xdb, 0xdb, + 0x58, 0x18, 0x5d, 0xda, 0x9b, 0xdb, 0x57, 0x9a, 0x1b, 0x59, 0x19, 0x1e, + 0xbd, 0xb3, 0x32, 0xb7, 0x32, 0xb9, 0x30, 0xba, 0x32, 0x32, 0x94, 0xaf, + 0xaf, 0xb0, 0x34, 0xb9, 0x2f, 0x38, 0xb6, 0xb0, 0xb1, 0x32, 0xb4, 0x37, + 0x36, 0xb2, 0x32, 0xb9, 0xaf, 0xaf, 0x94, 0x21, 0x94, 0x32, 0x24, 0x5e, + 0xf2, 0x29, 0x83, 0x12, 0x24, 0x60, 0x90, 0x40, 0x89, 0x96, 0x48, 0xc9, + 0x34, 0x84, 0x52, 0x82, 0xc4, 0x4b, 0x3e, 0x25, 0x50, 0x82, 0x04, 0x0c, + 0x12, 0x28, 0x89, 0x12, 0x29, 0xb9, 0x86, 0x50, 0x8a, 0x90, 0x78, 0xc9, + 0xa7, 0x08, 0x4a, 0x90, 0x80, 0x41, 0x02, 0x25, 0x5a, 0x22, 0x25, 0x1b, + 0x95, 0xb0, 0x34, 0x39, 0x17, 0xb1, 0x3a, 0x33, 0xb3, 0x32, 0x39, 0x3e, + 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x73, + 0x69, 0x7a, 0x65, 0x44, 0xc2, 0xd2, 0xe4, 0x5c, 0xe4, 0xca, 0xc2, 0xc8, + 0x18, 0x85, 0xa5, 0xc9, 0xb9, 0x84, 0xc9, 0x9d, 0x7d, 0xd1, 0xe5, 0xc1, + 0x95, 0x7d, 0xcd, 0xa5, 0xe9, 0x95, 0xf1, 0x0a, 0x4b, 0x93, 0x73, 0x09, + 0x93, 0x3b, 0xfb, 0xa2, 0xcb, 0x83, 0x2b, 0xfb, 0x0a, 0x63, 0x4b, 0x3b, + 0x73, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x23, 0x62, 0xc6, 0xf6, 0x16, 0x46, + 0x47, 0x83, 0x47, 0x43, 0x05, 0x4e, 0xee, 0x4d, 0xad, 0x6c, 0x8c, 0x2e, + 0xed, 0xcd, 0x6d, 0x08, 0x18, 0x28, 0x46, 0x42, 0x06, 0x49, 0x19, 0x28, + 0x44, 0xf2, 0x29, 0x82, 0x12, 0x24, 0x66, 0x90, 0x9c, 0x81, 0x42, 0x24, + 0x68, 0xa0, 0x1c, 0x09, 0x94, 0xa4, 0x41, 0x22, 0x25, 0x6a, 0xc0, 0x84, + 0x4e, 0x2e, 0xcc, 0x6d, 0xce, 0xec, 0x4d, 0xae, 0x6d, 0x08, 0x18, 0x28, + 0x45, 0x42, 0x06, 0x49, 0x19, 0x28, 0x44, 0xf2, 0x29, 0x86, 0x12, 0x24, + 0x66, 0x90, 0x9c, 0x81, 0x42, 0x24, 0x68, 0xa0, 0x1c, 0x09, 0x94, 0xa4, + 0x41, 0x22, 0x25, 0x6c, 0x30, 0x44, 0x49, 0xc2, 0x20, 0x11, 0x83, 0x64, + 0x0c, 0x92, 0x35, 0x48, 0xda, 0x60, 0x88, 0x81, 0x00, 0x49, 0x97, 0xb8, + 0x01, 0x9f, 0xb7, 0x36, 0xb7, 0x34, 0xb8, 0x37, 0xba, 0x32, 0x37, 0x3a, + 0x90, 0x31, 0xb4, 0x30, 0x39, 0x3e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, + 0x20, 0x43, 0x2b, 0x2b, 0x20, 0x54, 0x42, 0x41, 0x41, 0x43, 0x84, 0x24, + 0x0e, 0x86, 0x18, 0x09, 0x1c, 0x24, 0x72, 0xc0, 0x24, 0x43, 0x8c, 0x64, + 0x0e, 0x92, 0x39, 0x60, 0x92, 0x11, 0x11, 0x3b, 0xb0, 0x83, 0x3d, 0xb4, + 0x83, 0x1b, 0xb4, 0xc3, 0x3b, 0x90, 0x43, 0x3d, 0xb0, 0x43, 0x39, 0xb8, + 0x81, 0x39, 0xb0, 0x43, 0x38, 0x9c, 0xc3, 0x3c, 0x4c, 0x11, 0x82, 0x61, + 0x84, 0xc2, 0x0e, 0xec, 0x60, 0x0f, 0xed, 0xe0, 0x06, 0xe9, 0x40, 0x0e, + 0xe5, 0xe0, 0x0e, 0xf4, 0x30, 0x25, 0x28, 0x46, 0x2c, 0xe1, 0x90, 0x0e, + 0xf2, 0xe0, 0x06, 0xf6, 0x50, 0x0e, 0xf2, 0x30, 0x0f, 0xe9, 0xf0, 0x0e, + 0xee, 0x30, 0x25, 0x30, 0x46, 0x50, 0xe1, 0x90, 0x0e, 0xf2, 0xe0, 0x06, + 0xec, 0x10, 0x0e, 0xee, 0x70, 0x0e, 0xf5, 0x10, 0x0e, 0xe7, 0x50, 0x0e, + 0xbf, 0x60, 0x0f, 0xe5, 0x20, 0x0f, 0xf3, 0x90, 0x0e, 0xef, 0xe0, 0x0e, + 0x53, 0x02, 0x64, 0xc4, 0x14, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0x30, 0x0e, + 0xef, 0xd0, 0x0e, 0xf0, 0x90, 0x0e, 0xec, 0x50, 0x0e, 0xbf, 0xf0, 0x0e, + 0xf0, 0x40, 0x0f, 0xe9, 0xf0, 0x0e, 0xee, 0x30, 0x0f, 0x53, 0x06, 0x85, + 0x71, 0x46, 0x28, 0xe1, 0x90, 0x0e, 0xf2, 0xe0, 0x06, 0xf6, 0x50, 0x0e, + 0xf2, 0x40, 0x0f, 0xe5, 0x80, 0x0f, 0x53, 0x82, 0x37, 0x00, 0x79, 0x18, + 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, + 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, + 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, + 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, + 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, + 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, + 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, + 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, + 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, + 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, + 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, + 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, + 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, + 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, + 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, + 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, + 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, + 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, + 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, + 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, + 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, + 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, + 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, + 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, + 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, + 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, + 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, + 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, + 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, + 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, + 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, + 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, + 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, + 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, + 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, + 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, + 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, + 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, + 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, + 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, + 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, + 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x06, 0xf0, 0xb0, 0x5d, 0xf9, 0x73, 0xce, 0x83, 0xfd, 0x15, + 0x11, 0x4d, 0xc4, 0x05, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x52, 0x00, + 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x09, 0x00, + 0x00, 0x00, 0xe4, 0xc6, 0x22, 0x86, 0x61, 0x18, 0xc6, 0x22, 0x04, 0x41, + 0x10, 0xc6, 0x22, 0x82, 0x20, 0x08, 0x88, 0x95, 0x40, 0x19, 0x14, 0x01, + 0xb9, 0x11, 0x00, 0x1a, 0x33, 0x00, 0x24, 0x66, 0x00, 0x28, 0xcc, 0x00, + 0x00, 0x00, 0xe3, 0x11, 0x4b, 0x74, 0x45, 0x14, 0x94, 0xf1, 0x08, 0x67, + 0xca, 0x26, 0x0a, 0xca, 0x20, 0xc3, 0x50, 0x20, 0x26, 0x04, 0xf2, 0x19, + 0x8f, 0x90, 0xae, 0xae, 0xa1, 0xa0, 0x0c, 0x32, 0x1c, 0x09, 0x64, 0x42, + 0x20, 0x1f, 0x0b, 0x0a, 0xf8, 0x8c, 0x47, 0x5c, 0x9c, 0x18, 0x40, 0x14, + 0x94, 0x41, 0x06, 0xc6, 0xb1, 0x4c, 0x08, 0xe4, 0x63, 0x45, 0x00, 0x9f, + 0xf1, 0x08, 0x2e, 0x0c, 0xce, 0xc0, 0xa2, 0xa0, 0x0c, 0x32, 0x44, 0x13, + 0x67, 0x42, 0x20, 0x1f, 0x2b, 0x02, 0xf8, 0x8c, 0x47, 0x80, 0x81, 0x19, + 0xb0, 0x01, 0x47, 0x41, 0x19, 0x64, 0x08, 0xb0, 0xcd, 0x82, 0x4a, 0x3e, + 0x83, 0x0c, 0x83, 0x16, 0x06, 0x16, 0x4c, 0xf2, 0xb1, 0x21, 0x80, 0xcf, + 0x20, 0x83, 0xd1, 0x95, 0x81, 0x05, 0x91, 0x7c, 0x6c, 0x08, 0xe0, 0x33, + 0xc8, 0x90, 0x80, 0x41, 0x1a, 0x58, 0xf0, 0xc8, 0xc7, 0x86, 0x00, 0x3e, + 0xe3, 0x11, 0x6d, 0x30, 0x07, 0x79, 0x80, 0x06, 0x14, 0x94, 0x41, 0x86, + 0xa0, 0x0c, 0xd0, 0xc0, 0x02, 0x31, 0x90, 0xcf, 0x20, 0xc3, 0x70, 0x06, + 0x6e, 0x60, 0x01, 0x18, 0xc8, 0x67, 0x90, 0xa1, 0x48, 0x83, 0x38, 0xb0, + 0xa0, 0x93, 0xcf, 0x20, 0xc3, 0xb1, 0x06, 0x74, 0x60, 0x81, 0x26, 0x9f, + 0x41, 0x86, 0x3d, 0x70, 0x03, 0x38, 0xb0, 0x2c, 0x90, 0xcf, 0x20, 0x43, + 0x1f, 0xc0, 0x81, 0x1d, 0x98, 0x13, 0xc8, 0xc7, 0x92, 0x01, 0x3e, 0x16, + 0x30, 0xf0, 0xb1, 0x20, 0x81, 0x8f, 0x05, 0x08, 0x7c, 0x2c, 0x28, 0xe0, + 0x33, 0xdb, 0x80, 0x07, 0x01, 0x30, 0xdb, 0x10, 0x90, 0x42, 0x30, 0xdb, + 0x10, 0x90, 0x82, 0x90, 0x41, 0x40, 0x0c, 0x00, 0x00, 0x00, 0x09, 0x00, + 0x00, 0x00, 0x5b, 0x86, 0x20, 0xa0, 0x83, 0x2d, 0xc3, 0x10, 0xd0, 0xc1, + 0x96, 0xe1, 0x08, 0xe8, 0x60, 0xcb, 0xc0, 0x04, 0x74, 0xb0, 0x65, 0x88, + 0x02, 0x3a, 0xd8, 0x32, 0x58, 0x01, 0x1d, 0x6c, 0x19, 0xc6, 0x20, 0xa0, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, + 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xec, 0x08, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x38, 0x02, + 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, + 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, + 0x8b, 0x62, 0x80, 0x10, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0x84, 0x10, + 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, 0x44, 0x24, 0x48, 0x0a, + 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, 0x21, 0x72, 0x24, 0x07, + 0xc8, 0x08, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, + 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x1b, 0xc8, + 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x90, 0x00, 0x8a, 0x18, 0x87, + 0x77, 0x90, 0x07, 0x79, 0x28, 0x87, 0x71, 0xa0, 0x07, 0x76, 0xc8, 0x87, + 0x36, 0x90, 0x87, 0x77, 0xa8, 0x07, 0x77, 0x20, 0x87, 0x72, 0x20, 0x87, + 0x36, 0x20, 0x87, 0x74, 0xb0, 0x87, 0x74, 0x20, 0x87, 0x72, 0x68, 0x83, + 0x79, 0x88, 0x07, 0x79, 0xa0, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, + 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, + 0xa1, 0x1c, 0x00, 0x82, 0x1c, 0xd2, 0x61, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, + 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xc2, 0x21, 0x1d, 0xd8, 0xa1, 0x0d, 0xc6, + 0x21, 0x1c, 0xd8, 0x81, 0x1d, 0xe6, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, + 0x79, 0x28, 0x07, 0x80, 0x60, 0x87, 0x72, 0x98, 0x87, 0x79, 0x68, 0x03, + 0x78, 0x90, 0x87, 0x72, 0x18, 0x87, 0x74, 0x98, 0x87, 0x72, 0x68, 0x03, + 0x73, 0x80, 0x87, 0x76, 0x08, 0x07, 0x72, 0x00, 0xcc, 0x21, 0x1c, 0xd8, + 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, + 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, + 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, + 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x06, 0x77, 0x78, 0x87, + 0x36, 0x30, 0x07, 0x79, 0x08, 0x87, 0x76, 0x28, 0x87, 0x36, 0x80, 0x87, + 0x77, 0x48, 0x07, 0x77, 0xa0, 0x87, 0x72, 0x90, 0x87, 0x36, 0x28, 0x07, + 0x76, 0x48, 0x87, 0x76, 0x68, 0x03, 0x77, 0x78, 0x07, 0x77, 0x68, 0x03, + 0x76, 0x28, 0x87, 0x70, 0x30, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x83, + 0x74, 0x70, 0x07, 0x73, 0x98, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, + 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, + 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x40, 0x1d, 0xea, 0xa1, 0x1d, 0xe0, + 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x1e, 0x00, + 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, + 0x36, 0x70, 0x87, 0x70, 0x70, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, + 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, + 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xce, + 0xc1, 0x1d, 0xca, 0x81, 0x1c, 0xda, 0x40, 0x1f, 0xca, 0x41, 0x1e, 0xde, + 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, + 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, + 0x77, 0x68, 0x03, 0x7a, 0x90, 0x87, 0x70, 0x80, 0x07, 0x78, 0x48, 0x07, + 0x77, 0x38, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, + 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0x62, 0x1e, 0xe8, 0x21, 0x1c, 0xc6, + 0x61, 0x1d, 0xda, 0x00, 0x1e, 0xe4, 0xe1, 0x1d, 0xe8, 0xa1, 0x1c, 0xc6, + 0x81, 0x1e, 0xde, 0x41, 0x1e, 0xda, 0x40, 0x1c, 0xea, 0xc1, 0x1c, 0xcc, + 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xf4, 0xa1, 0x1c, 0x00, + 0x3c, 0x00, 0x88, 0x7a, 0x70, 0x87, 0x79, 0x08, 0x07, 0x73, 0x28, 0x87, + 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, + 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xea, 0x61, 0x1e, 0xca, + 0xa1, 0x0d, 0xe6, 0xe1, 0x1d, 0xcc, 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xd8, + 0xe1, 0x1d, 0xc2, 0x81, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, + 0x72, 0x00, 0x36, 0x10, 0x82, 0x00, 0x58, 0x00, 0x00, 0x00, 0x49, 0x18, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x13, 0x84, 0x40, 0x00, 0x89, 0x20, + 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x32, 0x22, 0x08, 0x09, 0x20, 0x64, + 0x85, 0x04, 0x13, 0x22, 0xa4, 0x84, 0x04, 0x13, 0x22, 0xe3, 0x84, 0xa1, + 0x90, 0x14, 0x12, 0x4c, 0x88, 0x8c, 0x0b, 0x84, 0x84, 0x4c, 0x10, 0x24, + 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, 0x00, 0x65, 0x08, 0x09, + 0x9a, 0x81, 0x80, 0x39, 0x02, 0x30, 0x48, 0x01, 0x1b, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x13, 0xb2, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, + 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x76, 0x08, + 0x87, 0x71, 0x78, 0x87, 0x79, 0xc0, 0x87, 0x38, 0x80, 0x03, 0x37, 0x88, + 0x83, 0x38, 0x70, 0x03, 0x38, 0xd8, 0x70, 0x1b, 0xe5, 0xd0, 0x06, 0xf0, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, + 0xd0, 0x06, 0xe9, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, + 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, + 0x60, 0x07, 0x6d, 0x90, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, + 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, + 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0e, 0x73, + 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, + 0x60, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, + 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x40, 0x07, 0x7a, + 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x73, + 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, + 0x60, 0x0f, 0x74, 0x80, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x79, 0x60, 0x07, 0x7a, + 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, + 0x60, 0x0f, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, + 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x79, + 0x20, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, + 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, + 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, + 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, + 0x50, 0x07, 0x71, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x00, 0x07, 0x72, + 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, + 0x00, 0x07, 0x72, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, + 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0x30, 0x84, 0x21, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x02, 0x01, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x32, 0x1e, 0x98, 0x0c, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, + 0x26, 0x47, 0xc6, 0x04, 0x43, 0xb2, 0x12, 0x18, 0x01, 0x28, 0x82, 0x42, + 0x28, 0x08, 0xba, 0xb1, 0x84, 0x25, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, + 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x10, 0x97, 0x29, + 0xa2, 0x25, 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4, 0x37, 0xb7, 0x21, 0x86, + 0x31, 0x14, 0xc0, 0x61, 0x50, 0xb9, 0x1b, 0x43, 0x0b, 0x93, 0xfb, 0x9a, + 0x4b, 0xd3, 0x2b, 0x1b, 0x62, 0x18, 0x41, 0x21, 0x18, 0x04, 0xe5, 0x20, + 0x08, 0x0e, 0x8e, 0xad, 0x0c, 0x84, 0x89, 0xc9, 0xaa, 0x09, 0xc4, 0xae, + 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x0d, 0x64, 0x26, 0x06, 0x06, 0x26, 0xc6, + 0x25, 0xc6, 0x06, 0x06, 0x04, 0xa5, 0xad, 0x8c, 0x2e, 0x8c, 0xcd, 0xac, + 0xac, 0x65, 0x26, 0x06, 0x06, 0x26, 0xc6, 0x25, 0xc6, 0x06, 0xc6, 0x25, + 0x26, 0x65, 0x88, 0x50, 0x10, 0x43, 0x0c, 0x23, 0x30, 0x0a, 0x43, 0x60, + 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, 0x04, 0x29, 0x0e, 0x23, 0x30, 0x02, + 0x43, 0xe0, 0x16, 0x96, 0x26, 0xe7, 0x32, 0xf6, 0xd6, 0x06, 0x97, 0xc6, + 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, 0x26, 0xd7, 0x36, 0xf7, 0x45, 0x96, + 0x36, 0x17, 0x26, 0xc6, 0x56, 0x36, 0x44, 0x28, 0x12, 0x72, 0x61, 0x69, + 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, + 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, + 0x6c, 0x65, 0x43, 0x84, 0x62, 0x61, 0x19, 0x84, 0xa5, 0xc9, 0xb9, 0x8c, + 0xbd, 0xb5, 0xc1, 0xa5, 0xb1, 0x95, 0xb9, 0x98, 0xc9, 0x85, 0xb5, 0x95, + 0x89, 0xd5, 0x99, 0x99, 0x95, 0xc9, 0x7d, 0x99, 0x95, 0xd1, 0x8d, 0xa1, + 0x7d, 0x91, 0xa5, 0xcd, 0x85, 0x89, 0xb1, 0x95, 0x0d, 0x11, 0x8a, 0x86, + 0x51, 0x58, 0x9a, 0x9c, 0x8b, 0x5c, 0x99, 0x1b, 0x59, 0x99, 0xdc, 0x17, + 0x5d, 0x98, 0xdc, 0x59, 0x19, 0x1d, 0xa3, 0xb0, 0x34, 0x39, 0x97, 0x30, + 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0x2f, 0xb7, 0xb0, 0xb6, 0x32, + 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x43, 0x90, 0xe2, 0x31, 0x84, + 0x02, 0x2a, 0xa2, 0x21, 0x42, 0x21, 0x51, 0x0a, 0x4b, 0x93, 0x73, 0x31, + 0x93, 0x0b, 0x3b, 0x6b, 0x2b, 0x73, 0xa3, 0xfb, 0x4a, 0x73, 0x83, 0xab, + 0xa3, 0x63, 0x76, 0x56, 0xe6, 0x56, 0x26, 0x17, 0x46, 0x57, 0x46, 0x86, + 0x82, 0x03, 0xf7, 0x36, 0x97, 0x46, 0x97, 0xf6, 0xe6, 0x46, 0x64, 0x27, + 0xf3, 0x65, 0x96, 0x42, 0x25, 0x2c, 0x4d, 0xce, 0x65, 0xac, 0xcc, 0x8d, + 0xae, 0x4c, 0x8e, 0x4f, 0x58, 0x9a, 0x9c, 0x0b, 0x5c, 0x99, 0xdc, 0x1c, + 0x5c, 0xd9, 0x18, 0x5d, 0x9a, 0x5d, 0x19, 0x0d, 0x33, 0xb6, 0xb7, 0x30, + 0x3a, 0x19, 0x32, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x44, 0xe0, 0xde, 0xe6, 0xd2, 0xe8, 0xd2, 0xde, 0xdc, + 0x86, 0x48, 0x86, 0x50, 0x50, 0x45, 0x55, 0x58, 0xc5, 0x55, 0x40, 0x05, + 0x56, 0x64, 0x85, 0x46, 0xeb, 0xac, 0xcc, 0xad, 0x4c, 0x2e, 0x8c, 0xae, + 0x8c, 0x0c, 0xa5, 0x66, 0xec, 0x8d, 0xed, 0x4d, 0x8e, 0xc8, 0x8e, 0xe6, + 0xcb, 0x2c, 0x85, 0xc5, 0xd8, 0x1b, 0xdb, 0x9b, 0xdc, 0x10, 0xc9, 0x08, + 0x0a, 0xaa, 0xe0, 0x0a, 0xab, 0xb8, 0x0a, 0xa8, 0x88, 0x8a, 0xac, 0xe8, + 0x86, 0x10, 0xc5, 0x56, 0x78, 0x43, 0x0c, 0x02, 0x28, 0xa6, 0xe2, 0x1b, + 0x11, 0xb1, 0x03, 0x3b, 0xd8, 0x43, 0x3b, 0xb8, 0x41, 0x3b, 0xbc, 0x03, + 0x39, 0xd4, 0x03, 0x3b, 0x94, 0x83, 0x1b, 0x98, 0x03, 0x3b, 0x84, 0xc3, + 0x39, 0xcc, 0xc3, 0x14, 0x21, 0x18, 0x46, 0x28, 0xec, 0xc0, 0x0e, 0xf6, + 0xd0, 0x0e, 0x6e, 0x90, 0x0e, 0xe4, 0x50, 0x0e, 0xee, 0x40, 0x0f, 0x53, + 0x82, 0x62, 0xc4, 0x12, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0x60, 0x0f, 0xe5, + 0x20, 0x0f, 0xf3, 0x90, 0x0e, 0xef, 0xe0, 0x0e, 0x53, 0x02, 0x63, 0x04, + 0x15, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0xc0, 0x0e, 0xe1, 0xe0, 0x0e, 0xe7, + 0x50, 0x0f, 0xe1, 0x70, 0x0e, 0xe5, 0xf0, 0x0b, 0xf6, 0x50, 0x0e, 0xf2, + 0x30, 0x0f, 0xe9, 0xf0, 0x0e, 0xee, 0x30, 0x25, 0x40, 0x46, 0x4c, 0xe1, + 0x90, 0x0e, 0xf2, 0xe0, 0x06, 0xe3, 0xf0, 0x0e, 0xed, 0x00, 0x0f, 0xe9, + 0xc0, 0x0e, 0xe5, 0xf0, 0x0b, 0xef, 0x00, 0x0f, 0xf4, 0x90, 0x0e, 0xef, + 0xe0, 0x0e, 0xf3, 0x30, 0x65, 0x50, 0x18, 0x67, 0x04, 0x13, 0x0e, 0xe9, + 0x20, 0x0f, 0x6e, 0x60, 0x0e, 0xf2, 0x10, 0x0e, 0xe7, 0xd0, 0x0e, 0xe5, + 0xe0, 0x0e, 0xf4, 0x30, 0x25, 0x00, 0x03, 0x00, 0x00, 0x00, 0x79, 0x18, + 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, + 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, + 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, + 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, + 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, + 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, + 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, + 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, + 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, + 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, + 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, + 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, + 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, + 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, + 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, + 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, + 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, + 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, + 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, + 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, + 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, + 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, + 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, + 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, + 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, + 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, + 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, + 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, + 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, + 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, + 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, + 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, + 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, + 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, + 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, + 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, + 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, + 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, + 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, + 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, + 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, + 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, 0x00, 0x00, 0x05, 0x00, + 0x00, 0x00, 0x06, 0x20, 0xb1, 0x5d, 0xf9, 0xb3, 0xce, 0x82, 0x0c, 0x7f, + 0x11, 0x01, 0x06, 0x43, 0x34, 0x13, 0x00, 0x00, 0x00, 0x00, 0x61, 0x20, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x06, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, + 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x50, 0x0a, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x91, 0x02, + 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, + 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, + 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, + 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, 0x44, 0x24, 0x48, 0x0a, + 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, 0x21, 0x72, 0x24, 0x07, + 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, + 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0x1b, 0xcc, + 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x60, 0x00, 0x09, 0xa8, 0x88, + 0x71, 0x78, 0x07, 0x79, 0x90, 0x87, 0x72, 0x18, 0x07, 0x7a, 0x60, 0x87, + 0x7c, 0x68, 0x03, 0x79, 0x78, 0x87, 0x7a, 0x70, 0x07, 0x72, 0x28, 0x07, + 0x72, 0x68, 0x03, 0x72, 0x48, 0x07, 0x7b, 0x48, 0x07, 0x72, 0x28, 0x87, + 0x36, 0x98, 0x87, 0x78, 0x90, 0x07, 0x7a, 0x68, 0x03, 0x73, 0x80, 0x87, + 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xcc, 0x21, 0x1c, 0xd8, + 0x61, 0x1e, 0xca, 0x01, 0x20, 0xc8, 0x21, 0x1d, 0xe6, 0x21, 0x1c, 0xc4, + 0x81, 0x1d, 0xca, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xd2, 0x81, 0x1d, 0xda, + 0x60, 0x1c, 0xc2, 0x81, 0x1d, 0xd8, 0x61, 0x1e, 0x00, 0x73, 0x08, 0x07, + 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x76, 0x28, 0x87, 0x79, 0x98, 0x87, + 0x36, 0x80, 0x07, 0x79, 0x28, 0x87, 0x71, 0x48, 0x87, 0x79, 0x28, 0x87, + 0x36, 0x30, 0x07, 0x78, 0x68, 0x87, 0x70, 0x20, 0x07, 0xc0, 0x1c, 0xc2, + 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xcc, + 0x41, 0x1e, 0xc2, 0xa1, 0x1d, 0xca, 0xa1, 0x0d, 0xe0, 0xe1, 0x1d, 0xd2, + 0xc1, 0x1d, 0xe8, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xca, 0x81, 0x1d, 0xd2, + 0xa1, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x60, 0x70, 0x87, + 0x77, 0x68, 0x03, 0x73, 0x90, 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, + 0x78, 0x78, 0x87, 0x74, 0x70, 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, + 0x72, 0x60, 0x87, 0x74, 0x68, 0x87, 0x36, 0x70, 0x87, 0x77, 0x70, 0x87, + 0x36, 0x60, 0x87, 0x72, 0x08, 0x07, 0x73, 0x00, 0x08, 0x77, 0x78, 0x87, + 0x36, 0x48, 0x07, 0x77, 0x30, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, + 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, + 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xd4, 0xa1, 0x1e, 0xda, + 0x01, 0x1e, 0xda, 0x80, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, 0xa1, 0x1c, 0xe6, + 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, + 0x77, 0x68, 0x03, 0x77, 0x08, 0x07, 0x77, 0x98, 0x87, 0x36, 0x30, 0x07, + 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, + 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x60, 0x1e, 0xd2, + 0xe1, 0x1c, 0xdc, 0xa1, 0x1c, 0xc8, 0xa1, 0x0d, 0xf4, 0xa1, 0x1c, 0xe4, + 0xe1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, + 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, + 0x77, 0x78, 0x87, 0x36, 0xa0, 0x07, 0x79, 0x08, 0x07, 0x78, 0x80, 0x87, + 0x74, 0x70, 0x87, 0x73, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, + 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xe6, 0x81, 0x1e, 0xc2, + 0x61, 0x1c, 0xd6, 0xa1, 0x0d, 0xe0, 0x41, 0x1e, 0xde, 0x81, 0x1e, 0xca, + 0x61, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, 0xa1, 0x0d, 0xc4, 0xa1, 0x1e, 0xcc, + 0xc1, 0x1c, 0xca, 0x41, 0x1e, 0xda, 0x60, 0x1e, 0xd2, 0x41, 0x1f, 0xca, + 0x01, 0xc0, 0x03, 0x80, 0xa8, 0x07, 0x77, 0x98, 0x87, 0x70, 0x30, 0x87, + 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, + 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xa2, 0x1e, 0xe6, + 0xa1, 0x1c, 0xda, 0x60, 0x1e, 0xde, 0xc1, 0x1c, 0xe8, 0xa1, 0x0d, 0xcc, + 0x81, 0x1d, 0xde, 0x21, 0x1c, 0xe8, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, + 0x79, 0x28, 0x07, 0x60, 0x83, 0x21, 0x10, 0xc0, 0x02, 0x54, 0x1b, 0x8c, + 0xa1, 0x00, 0x16, 0xa0, 0xda, 0x80, 0x10, 0xff, 0xff, 0xff, 0xff, 0x3f, + 0x00, 0x0c, 0x20, 0x01, 0xd5, 0x06, 0xa3, 0x08, 0x80, 0x05, 0xa8, 0x36, + 0x18, 0x86, 0x00, 0x2c, 0x40, 0x05, 0x49, 0x18, 0x00, 0x00, 0x03, 0x00, + 0x00, 0x00, 0x13, 0x86, 0x40, 0x18, 0x26, 0x0c, 0x44, 0x61, 0x00, 0x00, + 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x32, 0x22, + 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, + 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, + 0xa4, 0x4c, 0x10, 0x44, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, + 0x00, 0x47, 0x49, 0x53, 0x44, 0x09, 0x93, 0xff, 0x4f, 0xc4, 0x35, 0x51, + 0x11, 0xf1, 0xdb, 0xc3, 0x3f, 0x8d, 0x11, 0x00, 0x83, 0x08, 0x43, 0x70, + 0x91, 0x34, 0x45, 0x94, 0x30, 0xf9, 0xbf, 0x04, 0x30, 0xcf, 0x42, 0x44, + 0xff, 0x34, 0x46, 0x00, 0x0c, 0x22, 0x14, 0x42, 0x31, 0x42, 0x08, 0x82, + 0x18, 0x3a, 0x73, 0x04, 0xc1, 0x1c, 0x01, 0x18, 0x0c, 0x23, 0x08, 0x4a, + 0x41, 0x02, 0x31, 0x22, 0xad, 0x04, 0x88, 0x0d, 0x04, 0xa4, 0x80, 0x1a, + 0x01, 0x00, 0x13, 0xb2, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, + 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x76, 0x08, + 0x87, 0x71, 0x78, 0x87, 0x79, 0xc0, 0x87, 0x38, 0x80, 0x03, 0x37, 0x88, + 0x83, 0x38, 0x70, 0x03, 0x38, 0xd8, 0x70, 0x1b, 0xe5, 0xd0, 0x06, 0xf0, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, + 0xd0, 0x06, 0xe9, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, + 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, + 0x60, 0x07, 0x6d, 0x90, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, + 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, + 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0e, 0x73, + 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, + 0x60, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, + 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x40, 0x07, 0x7a, + 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x73, + 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, + 0x60, 0x0f, 0x74, 0x80, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x79, 0x60, 0x07, 0x7a, + 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, + 0x60, 0x0f, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, + 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x79, + 0x20, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, + 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, + 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, + 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, + 0x50, 0x07, 0x71, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x00, 0x07, 0x72, + 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, + 0x00, 0x07, 0x72, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, + 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0x30, 0x84, 0x41, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xc2, 0x34, 0x40, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x64, 0x81, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, + 0x26, 0x47, 0xc6, 0x04, 0x43, 0x52, 0x25, 0x30, 0x02, 0x50, 0x04, 0x85, + 0x50, 0x10, 0x65, 0x40, 0x6f, 0x2c, 0x61, 0x09, 0x00, 0x00, 0x79, 0x18, + 0x00, 0x00, 0xcb, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x10, 0x97, 0x29, + 0xa2, 0x25, 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4, 0x37, 0xb7, 0x21, 0x86, + 0x42, 0x38, 0xc0, 0x83, 0x50, 0xb9, 0x1b, 0x43, 0x0b, 0x93, 0xfb, 0x9a, + 0x4b, 0xd3, 0x2b, 0x1b, 0x62, 0x28, 0x82, 0x23, 0x28, 0x05, 0xe5, 0x20, + 0x08, 0x0e, 0x8e, 0xad, 0x0c, 0x84, 0x89, 0xc9, 0xaa, 0x09, 0xc4, 0xae, + 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x0d, 0x64, 0x26, 0x06, 0x06, 0x26, 0xc6, + 0x25, 0xc6, 0x06, 0x06, 0x04, 0xa5, 0xad, 0x8c, 0x2e, 0x8c, 0xcd, 0xac, + 0xac, 0x65, 0x26, 0x06, 0x06, 0x26, 0xc6, 0x25, 0xc6, 0x06, 0xc6, 0x25, + 0x26, 0x65, 0x88, 0xe0, 0x10, 0x43, 0x0c, 0x45, 0x50, 0x0c, 0x65, 0x60, + 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, 0x04, 0x71, 0x0e, 0x45, 0x50, 0x04, + 0x65, 0xe0, 0x16, 0x96, 0x26, 0xe7, 0x32, 0xf6, 0xd6, 0x06, 0x97, 0xc6, + 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, 0x26, 0xd7, 0x36, 0xf7, 0x45, 0x96, + 0x36, 0x17, 0x26, 0xc6, 0x56, 0x36, 0x44, 0x70, 0x12, 0x72, 0x61, 0x69, + 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, + 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, + 0x6c, 0x65, 0x43, 0x04, 0x67, 0x61, 0x19, 0x84, 0xa5, 0xc9, 0xb9, 0x8c, + 0xbd, 0xb5, 0xc1, 0xa5, 0xb1, 0x95, 0xb9, 0x98, 0xc9, 0x85, 0xb5, 0x95, + 0x89, 0xd5, 0x99, 0x99, 0x95, 0xc9, 0x7d, 0x99, 0x95, 0xd1, 0x8d, 0xa1, + 0x7d, 0x91, 0xa5, 0xcd, 0x85, 0x89, 0xb1, 0x95, 0x0d, 0x11, 0x9c, 0x86, + 0x51, 0x58, 0x9a, 0x9c, 0x8b, 0x5c, 0x99, 0x1b, 0x59, 0x99, 0xdc, 0x17, + 0x5d, 0x98, 0xdc, 0x59, 0x19, 0x1d, 0xa3, 0xb0, 0x34, 0x39, 0x97, 0x30, + 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0x2f, 0xb7, 0xb0, 0xb6, 0x32, + 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x43, 0x10, 0xe7, 0x51, 0x06, + 0x07, 0x72, 0xa2, 0x21, 0x82, 0x23, 0x91, 0x09, 0x4b, 0x93, 0x73, 0x81, + 0x7b, 0x9b, 0x4b, 0xa3, 0x4b, 0x7b, 0x73, 0xa3, 0x12, 0x96, 0x26, 0xe7, + 0x32, 0x56, 0xe6, 0x46, 0x57, 0x26, 0x47, 0x29, 0x2c, 0x4d, 0xce, 0xc5, + 0xed, 0xed, 0x0b, 0xae, 0x4c, 0x6e, 0x0e, 0xae, 0x6c, 0x8c, 0x2e, 0xcd, + 0xae, 0x8c, 0x4c, 0x58, 0x9a, 0x9c, 0x4b, 0x98, 0xdc, 0xd9, 0x97, 0x5b, + 0x58, 0x5b, 0x19, 0x11, 0xb8, 0xb7, 0xb9, 0x34, 0xba, 0xb4, 0x37, 0xb7, + 0x21, 0x90, 0x32, 0x38, 0x94, 0x53, 0x39, 0x96, 0x03, 0x39, 0x91, 0x73, + 0x39, 0x18, 0xa5, 0xb0, 0x34, 0x39, 0x17, 0x33, 0xb9, 0xb0, 0xb3, 0xb6, + 0x32, 0x37, 0xba, 0xaf, 0x34, 0x37, 0xb8, 0x3a, 0x3a, 0x5a, 0x67, 0x65, + 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x35, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x44, 0x76, 0x34, 0x5f, 0x66, 0x29, 0x7c, 0xc2, 0xd2, 0xe4, + 0x5c, 0xe0, 0xca, 0xe4, 0xe6, 0xe0, 0xca, 0xc6, 0xe8, 0xd2, 0xec, 0xca, + 0x58, 0x8c, 0xbd, 0xb1, 0xbd, 0xc9, 0x0d, 0x91, 0x14, 0xc1, 0xd1, 0x9c, + 0xcd, 0xa9, 0x1c, 0xce, 0x81, 0x9c, 0xc8, 0xb9, 0x9c, 0x8e, 0xd9, 0x59, + 0x99, 0x5b, 0x99, 0x5c, 0x18, 0x5d, 0x19, 0x19, 0x0a, 0x0e, 0x5d, 0x19, + 0xde, 0xd8, 0xdb, 0x9b, 0x1c, 0x19, 0x91, 0x9d, 0xcc, 0x97, 0x59, 0x0a, + 0x0d, 0x33, 0xb6, 0xb7, 0x30, 0x3a, 0x19, 0x22, 0x74, 0x65, 0x78, 0x63, + 0x6f, 0x6f, 0x72, 0x64, 0x43, 0x24, 0x85, 0x70, 0x34, 0xe7, 0x73, 0x2a, + 0x87, 0x73, 0x20, 0x07, 0x0c, 0x9c, 0xcb, 0x09, 0x03, 0x2e, 0x61, 0x69, + 0x72, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x94, 0xc2, 0xd2, + 0xe4, 0x5c, 0xd8, 0xde, 0xc6, 0xc2, 0xe8, 0xd2, 0xde, 0xdc, 0xbe, 0xd2, + 0xdc, 0xc8, 0xca, 0xf0, 0xa8, 0x84, 0xa5, 0xc9, 0xb9, 0xcc, 0x85, 0xb5, + 0xc1, 0xb1, 0x95, 0x11, 0xa3, 0x2b, 0xc3, 0xa3, 0xab, 0x93, 0x2b, 0x93, + 0x21, 0xe3, 0x31, 0x63, 0x7b, 0x0b, 0xa3, 0x63, 0x01, 0x99, 0x0b, 0x6b, + 0x83, 0x63, 0x2b, 0xf3, 0xe1, 0x40, 0x57, 0x86, 0x37, 0x84, 0x52, 0x0e, + 0x67, 0x0c, 0x1c, 0x32, 0x50, 0x06, 0x45, 0x70, 0xca, 0xc0, 0x81, 0x1c, + 0x33, 0x70, 0x2e, 0xe7, 0x0c, 0xb8, 0x84, 0xa5, 0xc9, 0xb9, 0xcc, 0x85, + 0xb5, 0xc1, 0xb1, 0x95, 0xc9, 0xf1, 0x98, 0x0b, 0x6b, 0x83, 0x63, 0x2b, + 0x93, 0x63, 0x30, 0x37, 0x44, 0x52, 0x0a, 0x27, 0x0d, 0x1c, 0x32, 0x50, + 0x06, 0x45, 0x70, 0x20, 0x47, 0x0d, 0x9c, 0xcb, 0x59, 0x83, 0x21, 0x8a, + 0x93, 0x39, 0x9e, 0x23, 0x06, 0x0e, 0x1a, 0x38, 0x6c, 0x30, 0xc4, 0x40, + 0x00, 0x67, 0x72, 0xda, 0x60, 0x44, 0xc4, 0x0e, 0xec, 0x60, 0x0f, 0xed, + 0xe0, 0x06, 0xed, 0xf0, 0x0e, 0xe4, 0x50, 0x0f, 0xec, 0x50, 0x0e, 0x6e, + 0x60, 0x0e, 0xec, 0x10, 0x0e, 0xe7, 0x30, 0x0f, 0x53, 0x84, 0x60, 0x18, + 0xa1, 0xb0, 0x03, 0x3b, 0xd8, 0x43, 0x3b, 0xb8, 0x41, 0x3a, 0x90, 0x43, + 0x39, 0xb8, 0x03, 0x3d, 0x4c, 0x09, 0x8a, 0x11, 0x4b, 0x38, 0xa4, 0x83, + 0x3c, 0xb8, 0x81, 0x3d, 0x94, 0x83, 0x3c, 0xcc, 0x43, 0x3a, 0xbc, 0x83, + 0x3b, 0x4c, 0x09, 0x8c, 0x11, 0x54, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x01, + 0x3b, 0x84, 0x83, 0x3b, 0x9c, 0x43, 0x3d, 0x84, 0xc3, 0x39, 0x94, 0xc3, + 0x2f, 0xd8, 0x43, 0x39, 0xc8, 0xc3, 0x3c, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, + 0x94, 0x00, 0x19, 0x31, 0x85, 0x43, 0x3a, 0xc8, 0x83, 0x1b, 0x8c, 0xc3, + 0x3b, 0xb4, 0x03, 0x3c, 0xa4, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x03, + 0x3c, 0xd0, 0x43, 0x3a, 0xbc, 0x83, 0x3b, 0xcc, 0xc3, 0x94, 0x41, 0x61, + 0x9c, 0x11, 0x4c, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xc8, 0x43, + 0x38, 0x9c, 0x43, 0x3b, 0x94, 0x83, 0x3b, 0xd0, 0xc3, 0x94, 0xc0, 0x0d, + 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, + 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, + 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, + 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, + 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, + 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, + 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, + 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, + 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, + 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, + 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, + 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, + 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, + 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, + 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, + 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, + 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, + 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, + 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, + 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, + 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, + 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, + 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, + 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, + 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, + 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, + 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, + 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, + 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, + 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, + 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, + 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, + 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, + 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, + 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, + 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, + 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, + 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, + 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, + 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, + 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, + 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, + 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x06, 0x10, 0xb1, 0x5d, 0xf9, 0x73, + 0xce, 0x83, 0xfd, 0x45, 0x04, 0x18, 0x0c, 0xd1, 0x4c, 0x16, 0xb0, 0x01, + 0x48, 0xe4, 0x4b, 0x00, 0xf3, 0x2c, 0xc4, 0x3f, 0x11, 0xd7, 0x44, 0x45, + 0xc4, 0x6f, 0x0f, 0x7e, 0x85, 0x17, 0xb7, 0x0d, 0x00, 0x00, 0x61, 0x20, + 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, + 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xb4, 0x46, 0x00, 0x28, 0xd5, 0xc0, + 0x08, 0x00, 0x81, 0x11, 0x00, 0x00, 0x23, 0x06, 0x8a, 0x10, 0x44, 0x46, + 0x71, 0x0c, 0x84, 0x10, 0x58, 0x90, 0xc8, 0x27, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, + 0x00, 0x00, 0xd4, 0x0c, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, + 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x32, 0x03, 0x00, 0x00, 0x0b, 0x82, + 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x07, 0x81, + 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, + 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, + 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, + 0x18, 0x49, 0x0a, 0x32, 0x44, 0x24, 0x48, 0x0a, 0x90, 0x21, 0x23, 0xc4, + 0x52, 0x80, 0x0c, 0x19, 0x21, 0x72, 0x24, 0x07, 0xc8, 0x48, 0x11, 0x62, + 0xa8, 0xa0, 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x51, 0x18, + 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00, 0x1b, 0xcc, 0x25, 0xf8, 0xff, 0xff, + 0xff, 0xff, 0x01, 0x60, 0x00, 0x09, 0xa8, 0x88, 0x71, 0x78, 0x07, 0x79, + 0x90, 0x87, 0x72, 0x18, 0x07, 0x7a, 0x60, 0x87, 0x7c, 0x68, 0x03, 0x79, + 0x78, 0x87, 0x7a, 0x70, 0x07, 0x72, 0x28, 0x07, 0x72, 0x68, 0x03, 0x72, + 0x48, 0x07, 0x7b, 0x48, 0x07, 0x72, 0x28, 0x87, 0x36, 0x98, 0x87, 0x78, + 0x90, 0x07, 0x7a, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, + 0xa0, 0x07, 0x74, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, + 0x20, 0xc8, 0x21, 0x1d, 0xe6, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0xa1, + 0x0d, 0xe8, 0x21, 0x1c, 0xd2, 0x81, 0x1d, 0xda, 0x60, 0x1c, 0xc2, 0x81, + 0x1d, 0xd8, 0x61, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, + 0x00, 0x08, 0x76, 0x28, 0x87, 0x79, 0x98, 0x87, 0x36, 0x80, 0x07, 0x79, + 0x28, 0x87, 0x71, 0x48, 0x87, 0x79, 0x28, 0x87, 0x36, 0x30, 0x07, 0x78, + 0x68, 0x87, 0x70, 0x20, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, + 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xcc, 0x41, 0x1e, 0xc2, 0xa1, + 0x1d, 0xca, 0xa1, 0x0d, 0xe0, 0xe1, 0x1d, 0xd2, 0xc1, 0x1d, 0xe8, 0xa1, + 0x1c, 0xe4, 0xa1, 0x0d, 0xca, 0x81, 0x1d, 0xd2, 0xa1, 0x1d, 0x00, 0x7a, + 0x90, 0x87, 0x7a, 0x28, 0x07, 0x60, 0x70, 0x87, 0x77, 0x68, 0x03, 0x73, + 0x90, 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, 0x78, 0x78, 0x87, 0x74, + 0x70, 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, 0x72, 0x60, 0x87, 0x74, + 0x68, 0x87, 0x36, 0x70, 0x87, 0x77, 0x70, 0x87, 0x36, 0x60, 0x87, 0x72, + 0x08, 0x07, 0x73, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x48, 0x07, 0x77, + 0x30, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, + 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, + 0x1d, 0xde, 0xa1, 0x0d, 0xd4, 0xa1, 0x1e, 0xda, 0x01, 0x1e, 0xda, 0x80, + 0x1e, 0xc2, 0x41, 0x1c, 0xd8, 0xa1, 0x1c, 0xe6, 0x01, 0x30, 0x87, 0x70, + 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x77, + 0x08, 0x07, 0x77, 0x98, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, + 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, + 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x60, 0x1e, 0xd2, 0xe1, 0x1c, 0xdc, 0xa1, + 0x1c, 0xc8, 0xa1, 0x0d, 0xf4, 0xa1, 0x1c, 0xe4, 0xe1, 0x1d, 0xe6, 0xa1, + 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, + 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, + 0xa0, 0x07, 0x79, 0x08, 0x07, 0x78, 0x80, 0x87, 0x74, 0x70, 0x87, 0x73, + 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, + 0x1e, 0xca, 0x01, 0x20, 0xe6, 0x81, 0x1e, 0xc2, 0x61, 0x1c, 0xd6, 0xa1, + 0x0d, 0xe0, 0x41, 0x1e, 0xde, 0x81, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0xe1, + 0x1d, 0xe4, 0xa1, 0x0d, 0xc4, 0xa1, 0x1e, 0xcc, 0xc1, 0x1c, 0xca, 0x41, + 0x1e, 0xda, 0x60, 0x1e, 0xd2, 0x41, 0x1f, 0xca, 0x01, 0xc0, 0x03, 0x80, + 0xa8, 0x07, 0x77, 0x98, 0x87, 0x70, 0x30, 0x87, 0x72, 0x68, 0x03, 0x73, + 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, + 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xa2, 0x1e, 0xe6, 0xa1, 0x1c, 0xda, 0x60, + 0x1e, 0xde, 0xc1, 0x1c, 0xe8, 0xa1, 0x0d, 0xcc, 0x81, 0x1d, 0xde, 0x21, + 0x1c, 0xe8, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x60, + 0x83, 0x21, 0x10, 0xc0, 0x02, 0x54, 0x1b, 0x8c, 0xa1, 0x00, 0x16, 0xa0, + 0xda, 0x60, 0x10, 0x07, 0xb0, 0x00, 0xd5, 0x06, 0xa3, 0xf8, 0xff, 0xff, + 0xff, 0xff, 0x01, 0x90, 0x00, 0x6a, 0x03, 0x62, 0xfc, 0xff, 0xff, 0xff, + 0xff, 0x00, 0x30, 0x80, 0x04, 0x54, 0x1b, 0x8c, 0x23, 0x00, 0x16, 0xa0, + 0xda, 0x60, 0x20, 0x02, 0xb0, 0x00, 0x15, 0x00, 0x00, 0x00, 0x49, 0x18, + 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x88, 0x40, 0x18, 0x88, 0x09, + 0x41, 0x31, 0x61, 0x30, 0x0e, 0x04, 0x89, 0x20, 0x00, 0x00, 0x30, 0x00, + 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, + 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, + 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x78, 0x33, 0x00, 0xc3, 0x08, + 0x04, 0x30, 0x8c, 0x20, 0x00, 0xc3, 0x08, 0x03, 0x70, 0x90, 0x34, 0x45, + 0x94, 0x30, 0xf9, 0xb2, 0xfb, 0x76, 0x84, 0xe0, 0x0c, 0x04, 0x22, 0xc6, + 0x18, 0x63, 0x10, 0x81, 0x10, 0x8e, 0x92, 0xa6, 0x88, 0x12, 0x26, 0xff, + 0x9f, 0x88, 0x6b, 0xa2, 0x22, 0xe2, 0xb7, 0x87, 0x7f, 0x1a, 0x23, 0x00, + 0x06, 0x11, 0x8c, 0xe0, 0x34, 0x69, 0x8a, 0x28, 0x61, 0xf2, 0xff, 0x89, + 0xb8, 0x26, 0x2a, 0x22, 0x7e, 0x7b, 0xf8, 0x81, 0x28, 0x02, 0xb0, 0x7f, + 0x1a, 0x23, 0x00, 0x06, 0x11, 0x90, 0xe0, 0x22, 0x69, 0x8a, 0x28, 0x61, + 0xf2, 0x7f, 0x09, 0x60, 0x9e, 0x85, 0x88, 0xfe, 0x69, 0x8c, 0x00, 0x18, + 0x44, 0x50, 0x84, 0x82, 0x84, 0x10, 0x44, 0x39, 0x69, 0x11, 0x2b, 0x03, + 0x18, 0x83, 0xdc, 0x1c, 0x01, 0x18, 0xcc, 0x11, 0x04, 0xc3, 0x08, 0x02, + 0x54, 0x92, 0x90, 0x96, 0x80, 0x51, 0x46, 0x40, 0xb3, 0x20, 0xe1, 0x2c, + 0x11, 0x65, 0x04, 0x54, 0x07, 0x02, 0x52, 0x00, 0x0e, 0x23, 0x0c, 0xd0, + 0x20, 0x42, 0x20, 0xcc, 0x11, 0x80, 0xc2, 0x20, 0xc2, 0x20, 0x8c, 0x00, + 0x00, 0x00, 0x13, 0xb2, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, + 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x76, 0x08, + 0x87, 0x71, 0x78, 0x87, 0x79, 0xc0, 0x87, 0x38, 0x80, 0x03, 0x37, 0x88, + 0x83, 0x38, 0x70, 0x03, 0x38, 0xd8, 0x70, 0x1b, 0xe5, 0xd0, 0x06, 0xf0, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, + 0xd0, 0x06, 0xe9, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, + 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, + 0x60, 0x07, 0x6d, 0x90, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, + 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, + 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0e, 0x73, + 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, + 0x60, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, + 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x40, 0x07, 0x7a, + 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x73, + 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, + 0x60, 0x0f, 0x74, 0x80, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x79, 0x60, 0x07, 0x7a, + 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, + 0x60, 0x0f, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, + 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x79, + 0x20, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, + 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, + 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, + 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, + 0x50, 0x07, 0x71, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x00, 0x07, 0x72, + 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, + 0x00, 0x07, 0x72, 0x40, 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, + 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0x30, 0x84, 0x69, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xc2, 0x3c, 0x40, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0c, 0x61, 0x28, 0x20, 0x00, 0x06, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x86, 0x30, 0x16, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x59, 0x20, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x32, 0x1e, + 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, + 0x43, 0x82, 0x25, 0x30, 0x02, 0x50, 0x20, 0x45, 0x50, 0x08, 0x05, 0x18, + 0x50, 0x10, 0x65, 0x50, 0x40, 0x05, 0x56, 0x0a, 0xc5, 0x40, 0x78, 0x2c, + 0x61, 0x09, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x14, 0x01, + 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, 0x10, 0xab, + 0x32, 0xb9, 0xb9, 0xb4, 0x37, 0xb7, 0x21, 0x06, 0x74, 0x5c, 0x00, 0x06, + 0x51, 0xb9, 0x1b, 0x43, 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x1b, + 0x62, 0x40, 0xc4, 0x25, 0x40, 0x08, 0xe5, 0x20, 0x08, 0x0e, 0x8e, 0xad, + 0x0c, 0x84, 0x89, 0xc9, 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, 0x2e, 0xed, + 0xcd, 0x0d, 0x64, 0x26, 0x06, 0x06, 0x26, 0xc6, 0x25, 0xc6, 0x06, 0x06, + 0x04, 0xa5, 0xad, 0x8c, 0x2e, 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, 0x06, + 0x06, 0x26, 0xc6, 0x25, 0xc6, 0x06, 0xc6, 0x25, 0x26, 0x65, 0x88, 0x70, + 0x11, 0x43, 0x0c, 0x88, 0x80, 0x14, 0xa8, 0x60, 0xd1, 0x54, 0x46, 0x17, + 0xc6, 0x36, 0x04, 0xb9, 0x0e, 0x88, 0x80, 0x08, 0xa8, 0xe0, 0x16, 0x96, + 0x26, 0xe7, 0x32, 0xf6, 0xd6, 0x06, 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, + 0xe6, 0xf6, 0x26, 0xd7, 0x36, 0xf7, 0x45, 0x96, 0x36, 0x17, 0x26, 0xc6, + 0x56, 0x36, 0x44, 0xb8, 0x12, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, + 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, + 0x61, 0x74, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x84, + 0x6b, 0x61, 0x19, 0x84, 0xa5, 0xc9, 0xb9, 0x8c, 0xbd, 0xb5, 0xc1, 0xa5, + 0xb1, 0x95, 0xb9, 0x98, 0xc9, 0x85, 0xb5, 0x95, 0x89, 0xd5, 0x99, 0x99, + 0x95, 0xc9, 0x7d, 0x99, 0x95, 0xd1, 0x8d, 0xa1, 0x7d, 0x91, 0xa5, 0xcd, + 0x85, 0x89, 0xb1, 0x95, 0x0d, 0x11, 0xae, 0x86, 0x51, 0x58, 0x9a, 0x9c, + 0x8b, 0x5c, 0x99, 0x1b, 0x59, 0x99, 0xdc, 0x17, 0x5d, 0x98, 0xdc, 0x59, + 0x19, 0x1d, 0xa3, 0xb0, 0x34, 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, + 0x3c, 0xb8, 0xb2, 0x2f, 0xb7, 0xb0, 0xb6, 0x32, 0x1a, 0x66, 0x6c, 0x6f, + 0x61, 0x74, 0x34, 0x43, 0x90, 0xeb, 0x81, 0x8a, 0x0b, 0xba, 0xa2, 0x21, + 0xc2, 0x25, 0x91, 0x09, 0x4b, 0x93, 0x73, 0x81, 0x7b, 0x9b, 0x4b, 0xa3, + 0x4b, 0x7b, 0x73, 0xa3, 0x12, 0x96, 0x26, 0xe7, 0x32, 0x56, 0xe6, 0x46, + 0x57, 0x26, 0x47, 0x29, 0x2c, 0x4d, 0xce, 0xc5, 0xed, 0xed, 0x0b, 0xae, + 0x4c, 0x6e, 0x0e, 0xae, 0x6c, 0x8c, 0x2e, 0xcd, 0xae, 0x8c, 0x4c, 0x58, + 0x9a, 0x9c, 0x4b, 0x98, 0xdc, 0xd9, 0x97, 0x5b, 0x58, 0x5b, 0x19, 0x11, + 0xb8, 0xb7, 0xb9, 0x34, 0xba, 0xb4, 0x37, 0xb7, 0x21, 0x10, 0x54, 0x5c, + 0xd4, 0x55, 0x5d, 0xd6, 0x05, 0x5d, 0xd1, 0x75, 0x5d, 0x18, 0xa5, 0xb0, + 0x34, 0x39, 0x17, 0x33, 0xb9, 0xb0, 0xb3, 0xb6, 0x32, 0x37, 0xba, 0xaf, + 0x34, 0x37, 0xb8, 0x3a, 0x3a, 0x5a, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, + 0x74, 0x65, 0x64, 0x28, 0x35, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x44, 0x76, + 0x34, 0x5f, 0x66, 0x29, 0x7c, 0xc2, 0xd2, 0xe4, 0x5c, 0xe0, 0xca, 0xe4, + 0xe6, 0xe0, 0xca, 0xc6, 0xe8, 0xd2, 0xec, 0xca, 0x58, 0x8c, 0xbd, 0xb1, + 0xbd, 0xc9, 0x0d, 0x91, 0x20, 0xe2, 0xd2, 0xae, 0xed, 0xaa, 0x2e, 0xee, + 0x82, 0xae, 0xe8, 0xba, 0xae, 0x8e, 0xd9, 0x59, 0x99, 0x5b, 0x99, 0x5c, + 0x18, 0x5d, 0x19, 0x19, 0x0a, 0x0e, 0x5d, 0x19, 0xde, 0xd8, 0xdb, 0x9b, + 0x1c, 0x19, 0x91, 0x9d, 0xcc, 0x97, 0x59, 0x0a, 0x0d, 0x33, 0xb6, 0xb7, + 0x30, 0x3a, 0x19, 0x22, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, + 0x43, 0x24, 0xe8, 0xb8, 0xb4, 0xeb, 0xbb, 0xaa, 0x8b, 0xbb, 0xa0, 0x0b, + 0x0c, 0xae, 0xeb, 0x0a, 0x03, 0x2a, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, + 0x66, 0x66, 0x65, 0x72, 0x7c, 0xc2, 0xd2, 0xe4, 0x5c, 0xc4, 0xea, 0xcc, + 0xcc, 0xca, 0xe4, 0xbe, 0xe6, 0xd2, 0xf4, 0xca, 0x28, 0x85, 0xa5, 0xc9, + 0xb9, 0xb0, 0xbd, 0x8d, 0x85, 0xd1, 0xa5, 0xbd, 0xb9, 0x7d, 0xa5, 0xb9, + 0x91, 0x95, 0xe1, 0x11, 0x09, 0x4b, 0x93, 0x73, 0x91, 0x2b, 0x0b, 0x23, + 0x23, 0x15, 0x96, 0x26, 0xe7, 0x32, 0x47, 0x27, 0x57, 0x37, 0x46, 0xf7, + 0x45, 0x97, 0x07, 0x57, 0xf6, 0x95, 0xe6, 0x66, 0xf6, 0x46, 0xc3, 0x8c, + 0xed, 0x2d, 0x8c, 0x6e, 0x86, 0xc6, 0x9b, 0x99, 0xd9, 0x5c, 0x19, 0x1d, + 0x0d, 0xa9, 0xb1, 0xb7, 0x32, 0x33, 0x33, 0x1a, 0x47, 0x63, 0x6f, 0x65, + 0x66, 0x66, 0x34, 0x84, 0xc6, 0xde, 0xca, 0xcc, 0xcc, 0x86, 0xa0, 0x01, + 0x54, 0x40, 0x06, 0x54, 0x5c, 0x68, 0x70, 0xa5, 0x01, 0x64, 0x40, 0x06, + 0x54, 0x5c, 0x68, 0x70, 0xa9, 0x01, 0xc4, 0x40, 0x06, 0x54, 0x5c, 0x68, + 0x70, 0xad, 0x01, 0xd4, 0x40, 0x06, 0x54, 0x5c, 0x68, 0x70, 0xb1, 0x01, + 0xa3, 0xb0, 0x34, 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, + 0xb2, 0xaf, 0xb9, 0x34, 0xbd, 0x32, 0x5e, 0x61, 0x69, 0x72, 0x2e, 0x61, + 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x61, 0x6c, 0x69, 0x67, + 0x6e, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x4c, 0xb2, 0xaa, 0xac, 0x88, 0xca, + 0xc6, 0xde, 0xc8, 0xca, 0x68, 0x90, 0x95, 0x8d, 0xbd, 0x91, 0x95, 0x0d, + 0x21, 0x03, 0x68, 0xb9, 0xc6, 0xe0, 0x22, 0x03, 0x28, 0xb9, 0xca, 0x00, + 0x22, 0x20, 0xe2, 0x32, 0x83, 0xeb, 0x0c, 0xae, 0x36, 0xb8, 0xdc, 0x00, + 0x4a, 0xae, 0x37, 0x80, 0x8c, 0x0b, 0xba, 0xe0, 0xe0, 0xba, 0xae, 0x38, + 0xe0, 0x12, 0x96, 0x26, 0xe7, 0x42, 0x57, 0x86, 0x47, 0x57, 0x27, 0x57, + 0x46, 0x25, 0x2c, 0x4d, 0xce, 0x65, 0x2e, 0xac, 0x0d, 0x8e, 0xad, 0x8c, + 0x18, 0x5d, 0x19, 0x1e, 0x5d, 0x9d, 0x5c, 0x99, 0x0c, 0x19, 0x8f, 0x19, + 0xdb, 0x5b, 0x18, 0x1d, 0x0b, 0xc8, 0x5c, 0x58, 0x1b, 0x1c, 0x5b, 0x99, + 0x0f, 0x09, 0xba, 0x32, 0xbc, 0xac, 0x21, 0x14, 0x84, 0x5c, 0x73, 0x70, + 0x95, 0x01, 0x54, 0x40, 0xc4, 0x45, 0x07, 0x17, 0x74, 0xd5, 0xc1, 0x75, + 0x5d, 0x76, 0x40, 0x8f, 0xae, 0x0c, 0x8f, 0xae, 0x4e, 0xae, 0x4c, 0x86, + 0xec, 0x2b, 0x4c, 0x4e, 0x2e, 0x2c, 0x8f, 0xc7, 0x8c, 0xed, 0x2d, 0x8c, + 0x8e, 0x05, 0x64, 0x2e, 0xac, 0x0d, 0x8e, 0xad, 0xcc, 0x87, 0x05, 0x5d, + 0x19, 0x5e, 0x95, 0xd5, 0x10, 0x0a, 0x72, 0xae, 0x39, 0xb8, 0xca, 0x00, + 0x22, 0x20, 0xe2, 0xa2, 0x83, 0x0b, 0xba, 0xf0, 0xe0, 0xba, 0xae, 0x3c, + 0xe0, 0x12, 0x96, 0x26, 0xe7, 0x32, 0x17, 0xd6, 0x06, 0xc7, 0x56, 0x26, + 0xc7, 0x63, 0x2e, 0xac, 0x0d, 0x8e, 0xad, 0x4c, 0x8e, 0xc1, 0xdc, 0x10, + 0x09, 0x7a, 0xae, 0x3d, 0xb8, 0xca, 0x00, 0x2a, 0x20, 0xe2, 0x82, 0x2e, + 0x3e, 0xb8, 0xae, 0xab, 0x0f, 0x86, 0x38, 0x57, 0x76, 0x79, 0x97, 0x18, + 0x5c, 0x72, 0x70, 0xdd, 0xc1, 0xa5, 0x07, 0x97, 0x1f, 0x0c, 0x31, 0x1a, + 0xe0, 0x9a, 0xae, 0x3f, 0x18, 0x11, 0xb1, 0x03, 0x3b, 0xd8, 0x43, 0x3b, + 0xb8, 0x41, 0x3b, 0xbc, 0x03, 0x39, 0xd4, 0x03, 0x3b, 0x94, 0x83, 0x1b, + 0x98, 0x03, 0x3b, 0x84, 0xc3, 0x39, 0xcc, 0xc3, 0x14, 0x21, 0x18, 0x46, + 0x28, 0xec, 0xc0, 0x0e, 0xf6, 0xd0, 0x0e, 0x6e, 0x90, 0x0e, 0xe4, 0x50, + 0x0e, 0xee, 0x40, 0x0f, 0x53, 0x82, 0x62, 0xc4, 0x12, 0x0e, 0xe9, 0x20, + 0x0f, 0x6e, 0x60, 0x0f, 0xe5, 0x20, 0x0f, 0xf3, 0x90, 0x0e, 0xef, 0xe0, + 0x0e, 0x53, 0x02, 0x63, 0x04, 0x15, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0xc0, + 0x0e, 0xe1, 0xe0, 0x0e, 0xe7, 0x50, 0x0f, 0xe1, 0x70, 0x0e, 0xe5, 0xf0, + 0x0b, 0xf6, 0x50, 0x0e, 0xf2, 0x30, 0x0f, 0xe9, 0xf0, 0x0e, 0xee, 0x30, + 0x25, 0x40, 0x46, 0x4c, 0xe1, 0x90, 0x0e, 0xf2, 0xe0, 0x06, 0xe3, 0xf0, + 0x0e, 0xed, 0x00, 0x0f, 0xe9, 0xc0, 0x0e, 0xe5, 0xf0, 0x0b, 0xef, 0x00, + 0x0f, 0xf4, 0x90, 0x0e, 0xef, 0xe0, 0x0e, 0xf3, 0x30, 0x65, 0x50, 0x18, + 0x67, 0x04, 0x13, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0x60, 0x0e, 0xf2, 0x10, + 0x0e, 0xe7, 0xd0, 0x0e, 0xe5, 0xe0, 0x0e, 0xf4, 0x30, 0x25, 0x00, 0x05, + 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, + 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, + 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, + 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, + 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, + 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, + 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, + 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, + 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, + 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, + 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, + 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, + 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, + 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, + 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, + 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, + 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, + 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, + 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, + 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, + 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, + 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, + 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, + 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, + 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, + 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, + 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, + 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, + 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, + 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, + 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, + 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, + 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, + 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, + 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, + 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, + 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, + 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, + 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, + 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, + 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, + 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, + 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x26, 0x10, 0x06, 0x00, 0x12, 0xf9, + 0x12, 0xc0, 0x3c, 0x0b, 0xf1, 0x4f, 0xc4, 0x35, 0x51, 0x11, 0xf1, 0xdb, + 0xc3, 0x0f, 0x44, 0x11, 0x80, 0xf9, 0x15, 0x5e, 0xdc, 0xb6, 0x05, 0x34, + 0x00, 0x12, 0xf9, 0x83, 0x33, 0xf9, 0xd5, 0x5d, 0xdc, 0xb6, 0x0d, 0x6c, + 0x00, 0x12, 0xf9, 0x12, 0xc0, 0x3c, 0x0b, 0xf1, 0x4f, 0xc4, 0x35, 0x51, + 0x11, 0xf1, 0xdb, 0x83, 0x5f, 0xe1, 0xc5, 0x6d, 0x1b, 0x00, 0xc4, 0x76, + 0xe5, 0x2f, 0xbb, 0xef, 0x5f, 0x44, 0x80, 0xc1, 0x10, 0xcd, 0x04, 0x00, + 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x13, 0x04, + 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xb4, 0x47, + 0x00, 0x28, 0xcf, 0x31, 0x14, 0x5d, 0x37, 0xd6, 0x00, 0x04, 0x02, 0xc9, + 0x11, 0x00, 0x8a, 0x23, 0x00, 0x04, 0x67, 0x00, 0x28, 0xd6, 0x00, 0x85, + 0x39, 0x08, 0x31, 0x10, 0x03, 0x31, 0x08, 0x83, 0x19, 0x00, 0x02, 0x63, + 0x04, 0x20, 0x08, 0x82, 0xf8, 0x37, 0x03, 0x30, 0x02, 0x00, 0x23, 0x06, + 0xca, 0x10, 0x84, 0xc1, 0xd3, 0x44, 0x46, 0x82, 0x04, 0x83, 0x0c, 0x41, + 0xc1, 0x8c, 0x18, 0x2c, 0x43, 0x40, 0x06, 0xd0, 0x33, 0x85, 0x01, 0xb2, + 0x28, 0xc3, 0x18, 0x42, 0x20, 0x06, 0x73, 0x0c, 0x43, 0x40, 0x06, 0x23, + 0x06, 0xcb, 0x10, 0x9c, 0xc1, 0x24, 0x59, 0x65, 0xb0, 0x38, 0x8d, 0x31, + 0x86, 0x10, 0x94, 0xc1, 0x1c, 0xc3, 0x10, 0x90, 0xc1, 0x61, 0x7a, 0x29, + 0x28, 0x83, 0x0c, 0x81, 0x43, 0x19, 0x11, 0xc0, 0x67, 0xbc, 0x81, 0xc3, + 0xd8, 0xe0, 0x02, 0xbd, 0x14, 0x94, 0x41, 0x86, 0x60, 0xca, 0x46, 0x0c, + 0x0a, 0x21, 0x98, 0x83, 0x22, 0x18, 0x6f, 0x08, 0x83, 0xce, 0x0d, 0x2e, + 0xd0, 0x4b, 0x41, 0x19, 0x64, 0x08, 0x30, 0x6f, 0xc4, 0xa0, 0x10, 0x02, + 0x3c, 0x50, 0x82, 0xf1, 0x06, 0x33, 0x10, 0x83, 0x37, 0xb8, 0x40, 0x2f, + 0x05, 0x65, 0x90, 0x21, 0xe8, 0xc6, 0x60, 0xc4, 0xa0, 0x10, 0x82, 0x3e, + 0x78, 0x82, 0x39, 0x06, 0x30, 0x58, 0xf4, 0x60, 0x8e, 0x21, 0x38, 0xf8, + 0x60, 0x8e, 0x21, 0x18, 0xf4, 0xc0, 0x02, 0x38, 0x90, 0x4f, 0x06, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, + 0x00, 0x00, 0x60, 0x0c, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, + 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x15, 0x03, 0x00, 0x00, 0x0b, 0x82, + 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x07, 0x81, + 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, + 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, + 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, + 0x18, 0x49, 0x0a, 0x32, 0x44, 0x24, 0x48, 0x0a, 0x90, 0x21, 0x23, 0xc4, + 0x52, 0x80, 0x0c, 0x19, 0x21, 0x72, 0x24, 0x07, 0xc8, 0x48, 0x11, 0x62, + 0xa8, 0xa0, 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x51, 0x18, + 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x1b, 0xcc, 0x25, 0xf8, 0xff, 0xff, + 0xff, 0xff, 0x01, 0x60, 0x00, 0x09, 0xa8, 0x88, 0x71, 0x78, 0x07, 0x79, + 0x90, 0x87, 0x72, 0x18, 0x07, 0x7a, 0x60, 0x87, 0x7c, 0x68, 0x03, 0x79, + 0x78, 0x87, 0x7a, 0x70, 0x07, 0x72, 0x28, 0x07, 0x72, 0x68, 0x03, 0x72, + 0x48, 0x07, 0x7b, 0x48, 0x07, 0x72, 0x28, 0x87, 0x36, 0x98, 0x87, 0x78, + 0x90, 0x07, 0x7a, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, + 0xa0, 0x07, 0x74, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, + 0x20, 0xc8, 0x21, 0x1d, 0xe6, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0xa1, + 0x0d, 0xe8, 0x21, 0x1c, 0xd2, 0x81, 0x1d, 0xda, 0x60, 0x1c, 0xc2, 0x81, + 0x1d, 0xd8, 0x61, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, + 0x00, 0x08, 0x76, 0x28, 0x87, 0x79, 0x98, 0x87, 0x36, 0x80, 0x07, 0x79, + 0x28, 0x87, 0x71, 0x48, 0x87, 0x79, 0x28, 0x87, 0x36, 0x30, 0x07, 0x78, + 0x68, 0x87, 0x70, 0x20, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, + 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xcc, 0x41, 0x1e, 0xc2, 0xa1, + 0x1d, 0xca, 0xa1, 0x0d, 0xe0, 0xe1, 0x1d, 0xd2, 0xc1, 0x1d, 0xe8, 0xa1, + 0x1c, 0xe4, 0xa1, 0x0d, 0xca, 0x81, 0x1d, 0xd2, 0xa1, 0x1d, 0x00, 0x7a, + 0x90, 0x87, 0x7a, 0x28, 0x07, 0x60, 0x70, 0x87, 0x77, 0x68, 0x03, 0x73, + 0x90, 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, 0x78, 0x78, 0x87, 0x74, + 0x70, 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, 0x72, 0x60, 0x87, 0x74, + 0x68, 0x87, 0x36, 0x70, 0x87, 0x77, 0x70, 0x87, 0x36, 0x60, 0x87, 0x72, + 0x08, 0x07, 0x73, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x48, 0x07, 0x77, + 0x30, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, + 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, + 0x1d, 0xde, 0xa1, 0x0d, 0xd4, 0xa1, 0x1e, 0xda, 0x01, 0x1e, 0xda, 0x80, + 0x1e, 0xc2, 0x41, 0x1c, 0xd8, 0xa1, 0x1c, 0xe6, 0x01, 0x30, 0x87, 0x70, + 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x77, + 0x08, 0x07, 0x77, 0x98, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, + 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, + 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x60, 0x1e, 0xd2, 0xe1, 0x1c, 0xdc, 0xa1, + 0x1c, 0xc8, 0xa1, 0x0d, 0xf4, 0xa1, 0x1c, 0xe4, 0xe1, 0x1d, 0xe6, 0xa1, + 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, + 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, + 0xa0, 0x07, 0x79, 0x08, 0x07, 0x78, 0x80, 0x87, 0x74, 0x70, 0x87, 0x73, + 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, + 0x1e, 0xca, 0x01, 0x20, 0xe6, 0x81, 0x1e, 0xc2, 0x61, 0x1c, 0xd6, 0xa1, + 0x0d, 0xe0, 0x41, 0x1e, 0xde, 0x81, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0xe1, + 0x1d, 0xe4, 0xa1, 0x0d, 0xc4, 0xa1, 0x1e, 0xcc, 0xc1, 0x1c, 0xca, 0x41, + 0x1e, 0xda, 0x60, 0x1e, 0xd2, 0x41, 0x1f, 0xca, 0x01, 0xc0, 0x03, 0x80, + 0xa8, 0x07, 0x77, 0x98, 0x87, 0x70, 0x30, 0x87, 0x72, 0x68, 0x03, 0x73, + 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, + 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xa2, 0x1e, 0xe6, 0xa1, 0x1c, 0xda, 0x60, + 0x1e, 0xde, 0xc1, 0x1c, 0xe8, 0xa1, 0x0d, 0xcc, 0x81, 0x1d, 0xde, 0x21, + 0x1c, 0xe8, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x60, + 0x83, 0x21, 0x10, 0xc0, 0x02, 0x54, 0x1b, 0x8c, 0xa1, 0x00, 0x16, 0xa0, + 0xda, 0x60, 0x10, 0x06, 0xb0, 0x00, 0xd5, 0x06, 0xa3, 0x38, 0x80, 0x05, + 0xa8, 0x36, 0x18, 0xc6, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x80, 0x04, 0x50, + 0x1b, 0x90, 0xe3, 0xff, 0xff, 0xff, 0xff, 0x07, 0x80, 0x01, 0x24, 0xa0, + 0xda, 0x60, 0x20, 0x01, 0xb0, 0x00, 0xd5, 0x06, 0x23, 0x11, 0x80, 0x05, + 0xa8, 0x00, 0x49, 0x18, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x13, 0x8a, + 0x40, 0x18, 0x88, 0x62, 0x42, 0x60, 0x4c, 0x18, 0x0e, 0x24, 0x01, 0x00, + 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x32, 0x22, + 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, + 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, + 0xa4, 0x4c, 0x10, 0x68, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, + 0x00, 0xc3, 0x08, 0x03, 0x70, 0x90, 0x34, 0x45, 0x94, 0x30, 0xf9, 0xb2, + 0xfb, 0x76, 0x84, 0xe0, 0x0c, 0x04, 0x22, 0xc6, 0x18, 0x63, 0x10, 0x81, + 0x10, 0x8e, 0x92, 0xa6, 0x88, 0x12, 0x26, 0xff, 0x9f, 0x88, 0x6b, 0xa2, + 0x22, 0xe2, 0xb7, 0x87, 0x7f, 0x1a, 0x23, 0x00, 0x06, 0x11, 0x8c, 0xe0, + 0x22, 0x69, 0x8a, 0x28, 0x61, 0xf2, 0x7f, 0x09, 0x60, 0x9e, 0x85, 0x88, + 0xfe, 0x69, 0x8c, 0x00, 0x18, 0x44, 0x40, 0x84, 0x82, 0x84, 0x10, 0x44, + 0x39, 0x27, 0x91, 0x2a, 0x03, 0x18, 0x83, 0xd8, 0x1c, 0x41, 0x30, 0x47, + 0x00, 0x06, 0xc3, 0x08, 0xc2, 0x53, 0x90, 0x70, 0x92, 0x70, 0xd0, 0x01, + 0x8a, 0x03, 0x01, 0x29, 0xf0, 0x86, 0x11, 0x86, 0x67, 0x10, 0x21, 0x10, + 0xe6, 0x08, 0x40, 0x61, 0x10, 0x61, 0x10, 0x46, 0x00, 0x00, 0x13, 0xb2, + 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, + 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x76, 0x08, 0x87, 0x71, 0x78, 0x87, + 0x79, 0xc0, 0x87, 0x38, 0x80, 0x03, 0x37, 0x88, 0x83, 0x38, 0x70, 0x03, + 0x38, 0xd8, 0x70, 0x1b, 0xe5, 0xd0, 0x06, 0xf0, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x90, + 0x0e, 0x71, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x80, + 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, + 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x90, + 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, + 0x07, 0x6d, 0x90, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, + 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x76, 0x40, + 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, + 0x0f, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, + 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x40, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x73, 0x20, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x74, 0x80, + 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, + 0x0f, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x6d, 0x60, 0x0f, 0x79, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, + 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x20, + 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, + 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x79, 0x20, 0x07, 0x7a, 0x20, + 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, + 0x0f, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, + 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x50, 0x07, 0x71, 0x20, + 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, + 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, + 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, + 0x07, 0x6d, 0xe0, 0x0e, 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, + 0x07, 0x72, 0x30, 0x84, 0x59, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0xc2, 0x34, 0x40, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0c, 0x61, 0x24, 0x20, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb2, + 0x40, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x14, 0x19, 0x11, + 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x7a, 0x25, 0x30, + 0x02, 0x50, 0x20, 0x45, 0x50, 0x08, 0x05, 0x18, 0x50, 0x10, 0x65, 0x50, + 0x40, 0x05, 0x56, 0x0a, 0xc5, 0x40, 0x74, 0x2c, 0x61, 0x09, 0x00, 0x00, + 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x1a, 0x03, + 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4, + 0x37, 0xb7, 0x21, 0xc6, 0x63, 0x4c, 0x00, 0xf5, 0x50, 0xb9, 0x1b, 0x43, + 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x1b, 0x62, 0x3c, 0xc3, 0x24, + 0x3c, 0x07, 0xe5, 0x20, 0x08, 0x0e, 0x8e, 0xad, 0x0c, 0x84, 0x89, 0xc9, + 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x0d, 0x64, 0x26, + 0x06, 0x06, 0x26, 0xc6, 0x25, 0xc6, 0x06, 0x06, 0x04, 0xa5, 0xad, 0x8c, + 0x2e, 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, 0x06, 0x06, 0x26, 0xc6, 0x25, + 0xc6, 0x06, 0xc6, 0x25, 0x26, 0x65, 0x88, 0x30, 0x11, 0x43, 0x8c, 0x67, + 0x78, 0x92, 0x87, 0x60, 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, 0x04, 0x99, + 0x8e, 0x67, 0x78, 0x86, 0x87, 0xe0, 0x16, 0x96, 0x26, 0xe7, 0x32, 0xf6, + 0xd6, 0x06, 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, 0x26, 0xd7, + 0x36, 0xf7, 0x45, 0x96, 0x36, 0x17, 0x26, 0xc6, 0x56, 0x36, 0x44, 0x98, + 0x12, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, + 0x65, 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, + 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x84, 0x69, 0x61, 0x19, 0x84, + 0xa5, 0xc9, 0xb9, 0x8c, 0xbd, 0xb5, 0xc1, 0xa5, 0xb1, 0x95, 0xb9, 0x98, + 0xc9, 0x85, 0xb5, 0x95, 0x89, 0xd5, 0x99, 0x99, 0x95, 0xc9, 0x7d, 0x99, + 0x95, 0xd1, 0x8d, 0xa1, 0x7d, 0x91, 0xa5, 0xcd, 0x85, 0x89, 0xb1, 0x95, + 0x0d, 0x11, 0xa6, 0x86, 0x51, 0x58, 0x9a, 0x9c, 0x8b, 0x5c, 0x99, 0x1b, + 0x59, 0x99, 0xdc, 0x17, 0x5d, 0x98, 0xdc, 0x59, 0x19, 0x1d, 0xa3, 0xb0, + 0x34, 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0x2f, + 0xb7, 0xb0, 0xb6, 0x32, 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x43, + 0x90, 0xe9, 0x79, 0x88, 0x09, 0x9a, 0xa2, 0x21, 0xc2, 0x24, 0x91, 0x09, + 0x4b, 0x93, 0x73, 0x81, 0x7b, 0x9b, 0x4b, 0xa3, 0x4b, 0x7b, 0x73, 0xa3, + 0x12, 0x96, 0x26, 0xe7, 0x32, 0x56, 0xe6, 0x46, 0x57, 0x26, 0x47, 0x29, + 0x2c, 0x4d, 0xce, 0xc5, 0xed, 0xed, 0x0b, 0xae, 0x4c, 0x6e, 0x0e, 0xae, + 0x6c, 0x8c, 0x2e, 0xcd, 0xae, 0x8c, 0x4c, 0x58, 0x9a, 0x9c, 0x4b, 0x98, + 0xdc, 0xd9, 0x97, 0x5b, 0x58, 0x5b, 0x19, 0x11, 0xb8, 0xb7, 0xb9, 0x34, + 0xba, 0xb4, 0x37, 0xb7, 0x21, 0xd0, 0x43, 0x4c, 0xd4, 0x54, 0x4d, 0xd6, + 0x04, 0x4d, 0xd1, 0x74, 0x4d, 0x18, 0xa5, 0xb0, 0x34, 0x39, 0x17, 0x33, + 0xb9, 0xb0, 0xb3, 0xb6, 0x32, 0x37, 0xba, 0xaf, 0x34, 0x37, 0xb8, 0x3a, + 0x3a, 0x5a, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, + 0x35, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x44, 0x76, 0x34, 0x5f, 0x66, 0x29, + 0x7c, 0xc2, 0xd2, 0xe4, 0x5c, 0xe0, 0xca, 0xe4, 0xe6, 0xe0, 0xca, 0xc6, + 0xe8, 0xd2, 0xec, 0xca, 0x58, 0x8c, 0xbd, 0xb1, 0xbd, 0xc9, 0x0d, 0x91, + 0x9e, 0x61, 0xd2, 0xa6, 0x6d, 0xaa, 0x26, 0x6e, 0x82, 0xa6, 0x68, 0xba, + 0xa6, 0x8e, 0xd9, 0x59, 0x99, 0x5b, 0x99, 0x5c, 0x18, 0x5d, 0x19, 0x19, + 0x0a, 0x0e, 0x5d, 0x19, 0xde, 0xd8, 0xdb, 0x9b, 0x1c, 0x19, 0x91, 0x9d, + 0xcc, 0x97, 0x59, 0x0a, 0x0d, 0x33, 0xb6, 0xb7, 0x30, 0x3a, 0x19, 0x22, + 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x43, 0xa4, 0xc7, 0x98, + 0xb4, 0xe9, 0x9b, 0xaa, 0x89, 0x9b, 0xa0, 0x09, 0x0c, 0xa6, 0x6b, 0x0a, + 0x03, 0x2a, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, + 0x7c, 0xc2, 0xd2, 0xe4, 0x5c, 0xc4, 0xea, 0xcc, 0xcc, 0xca, 0xe4, 0xbe, + 0xe6, 0xd2, 0xf4, 0xca, 0x28, 0x85, 0xa5, 0xc9, 0xb9, 0xb0, 0xbd, 0x8d, + 0x85, 0xd1, 0xa5, 0xbd, 0xb9, 0x7d, 0xa5, 0xb9, 0x91, 0x95, 0xe1, 0x11, + 0x09, 0x4b, 0x93, 0x73, 0x91, 0x2b, 0x0b, 0x23, 0x23, 0x15, 0x96, 0x26, + 0xe7, 0x32, 0x47, 0x27, 0x57, 0x37, 0x46, 0xf7, 0x45, 0x97, 0x07, 0x57, + 0xf6, 0x95, 0xe6, 0x66, 0xf6, 0x46, 0xc3, 0x8c, 0xed, 0x2d, 0x8c, 0x6e, + 0x86, 0xc6, 0x9b, 0x99, 0xd9, 0x5c, 0x19, 0x1d, 0x0d, 0xa9, 0xb1, 0xb7, + 0x32, 0x33, 0x33, 0x1a, 0x47, 0x63, 0x6f, 0x65, 0x66, 0x66, 0x34, 0x84, + 0xc6, 0xde, 0xca, 0xcc, 0xcc, 0x86, 0xa0, 0xc1, 0x43, 0x3c, 0xc5, 0x43, + 0x4c, 0x68, 0x30, 0xa5, 0xc1, 0x53, 0x3c, 0xc5, 0x43, 0x4c, 0x68, 0x30, + 0xa9, 0xc1, 0xb3, 0x3c, 0xc5, 0x43, 0x4c, 0x68, 0x30, 0xad, 0xc1, 0xc3, + 0x3c, 0xc5, 0x43, 0x4c, 0x68, 0x30, 0xb1, 0x01, 0xa3, 0xb0, 0x34, 0x39, + 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0xaf, 0xb9, 0x34, + 0xbd, 0x32, 0x5e, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, + 0x79, 0x70, 0x65, 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x5f, 0x73, 0x69, + 0x7a, 0x65, 0x4c, 0xb2, 0xaa, 0xac, 0x88, 0xca, 0xc6, 0xde, 0xc8, 0xca, + 0x68, 0x90, 0x95, 0x8d, 0xbd, 0x91, 0x95, 0x0d, 0x21, 0x83, 0x47, 0x99, + 0xc6, 0x60, 0x22, 0x83, 0x07, 0x99, 0xca, 0xe0, 0x19, 0x9e, 0x61, 0x32, + 0x83, 0xe9, 0x0c, 0xa6, 0x36, 0x98, 0xdc, 0xe0, 0x41, 0xa6, 0x37, 0x78, + 0x8a, 0x09, 0x9a, 0xe0, 0x60, 0xba, 0xa6, 0x38, 0xe0, 0x12, 0x96, 0x26, + 0xe7, 0x42, 0x57, 0x86, 0x47, 0x57, 0x27, 0x57, 0x46, 0x25, 0x2c, 0x4d, + 0xce, 0x65, 0x2e, 0xac, 0x0d, 0x8e, 0xad, 0x8c, 0x18, 0x5d, 0x19, 0x1e, + 0x5d, 0x9d, 0x5c, 0x99, 0x0c, 0x19, 0x8f, 0x19, 0xdb, 0x5b, 0x18, 0x1d, + 0x0b, 0xc8, 0x5c, 0x58, 0x1b, 0x1c, 0x5b, 0x99, 0x0f, 0x09, 0xba, 0x32, + 0xbc, 0xac, 0x21, 0xd4, 0x73, 0x4c, 0x73, 0x30, 0x95, 0xc1, 0x43, 0x3c, + 0xc3, 0x44, 0x07, 0x13, 0x34, 0xd5, 0xc1, 0x74, 0x4d, 0x76, 0xc0, 0x82, + 0xae, 0x0c, 0xaf, 0xca, 0x6a, 0x08, 0xf5, 0x34, 0xd3, 0x1c, 0x4c, 0x65, + 0xf0, 0x0c, 0xcf, 0x30, 0xd1, 0xc1, 0x04, 0x4d, 0x75, 0x30, 0x5d, 0x13, + 0x1e, 0x70, 0x09, 0x4b, 0x93, 0x73, 0x99, 0x0b, 0x6b, 0x83, 0x63, 0x2b, + 0x93, 0xe3, 0x31, 0x17, 0xd6, 0x06, 0xc7, 0x56, 0x26, 0xc7, 0x60, 0x6e, + 0x88, 0xf4, 0x38, 0x93, 0x1e, 0x4c, 0x65, 0xf0, 0x10, 0xcf, 0x30, 0x41, + 0xd3, 0x1e, 0x4c, 0xd7, 0xc4, 0x07, 0x43, 0x9c, 0x29, 0x9b, 0xbc, 0x49, + 0x0c, 0x26, 0x39, 0x98, 0xee, 0x60, 0xca, 0x83, 0xa9, 0x0f, 0x86, 0x18, + 0x0b, 0x30, 0x4d, 0x93, 0x1f, 0x8c, 0x88, 0xd8, 0x81, 0x1d, 0xec, 0xa1, + 0x1d, 0xdc, 0xa0, 0x1d, 0xde, 0x81, 0x1c, 0xea, 0x81, 0x1d, 0xca, 0xc1, + 0x0d, 0xcc, 0x81, 0x1d, 0xc2, 0xe1, 0x1c, 0xe6, 0x61, 0x8a, 0x10, 0x0c, + 0x23, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x48, 0x07, 0x72, + 0x28, 0x07, 0x77, 0xa0, 0x87, 0x29, 0x41, 0x31, 0x62, 0x09, 0x87, 0x74, + 0x90, 0x07, 0x37, 0xb0, 0x87, 0x72, 0x90, 0x87, 0x79, 0x48, 0x87, 0x77, + 0x70, 0x87, 0x29, 0x81, 0x31, 0x82, 0x0a, 0x87, 0x74, 0x90, 0x07, 0x37, + 0x60, 0x87, 0x70, 0x70, 0x87, 0x73, 0xa8, 0x87, 0x70, 0x38, 0x87, 0x72, + 0xf8, 0x05, 0x7b, 0x28, 0x07, 0x79, 0x98, 0x87, 0x74, 0x78, 0x07, 0x77, + 0x98, 0x12, 0x20, 0x23, 0xa6, 0x70, 0x48, 0x07, 0x79, 0x70, 0x83, 0x71, + 0x78, 0x87, 0x76, 0x80, 0x87, 0x74, 0x60, 0x87, 0x72, 0xf8, 0x85, 0x77, + 0x80, 0x07, 0x7a, 0x48, 0x87, 0x77, 0x70, 0x87, 0x79, 0x98, 0x32, 0x28, + 0x8c, 0x33, 0x82, 0x09, 0x87, 0x74, 0x90, 0x07, 0x37, 0x30, 0x07, 0x79, + 0x08, 0x87, 0x73, 0x68, 0x87, 0x72, 0x70, 0x07, 0x7a, 0x98, 0x12, 0xfc, + 0x01, 0x00, 0x79, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, + 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, + 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, + 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, + 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, + 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, + 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, + 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, + 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, + 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, + 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, + 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, + 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, + 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, + 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, + 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, + 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, + 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, + 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, + 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, + 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, + 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, + 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, + 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, + 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, + 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, + 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, + 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, + 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, + 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, + 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, + 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, + 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, + 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, + 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, + 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, + 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, + 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, + 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, + 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, + 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, + 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, + 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x16, 0xd0, 0x00, 0x48, 0xe4, 0x0f, + 0xce, 0xe4, 0x57, 0x77, 0x71, 0xdb, 0x26, 0xb0, 0x01, 0x48, 0xe4, 0x4b, + 0x00, 0xf3, 0x2c, 0xc4, 0x3f, 0x11, 0xd7, 0x44, 0x45, 0xc4, 0x6f, 0x0f, + 0x7e, 0x85, 0x17, 0xb7, 0x6d, 0x00, 0x11, 0xdb, 0x95, 0xff, 0xf9, 0xd6, + 0xf6, 0x5f, 0x44, 0x80, 0xc1, 0x10, 0xcd, 0x04, 0x00, 0x00, 0x61, 0x20, + 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, + 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x74, 0x47, 0x00, 0xa8, 0x8e, 0x35, + 0x00, 0x03, 0x31, 0xc7, 0x40, 0x0c, 0xde, 0x1c, 0x03, 0xe1, 0x79, 0x63, + 0x0d, 0x40, 0x20, 0x90, 0xab, 0x81, 0x11, 0x00, 0x7a, 0x33, 0x00, 0x04, + 0x47, 0x00, 0x28, 0xcc, 0x41, 0x90, 0x01, 0x19, 0x90, 0x81, 0x18, 0xcc, + 0x00, 0x10, 0x18, 0x23, 0x00, 0x41, 0x10, 0xc4, 0xbf, 0x11, 0x80, 0x19, + 0x00, 0x00, 0x23, 0x06, 0xca, 0x10, 0x8c, 0x41, 0xf4, 0x4c, 0x89, 0x81, + 0x08, 0x83, 0x0c, 0x41, 0xc1, 0x8c, 0x18, 0x28, 0x43, 0x50, 0x06, 0x52, + 0x54, 0x2d, 0x88, 0x42, 0x0c, 0x32, 0x04, 0xc7, 0x33, 0xc8, 0x30, 0x04, + 0xd1, 0x5d, 0x76, 0x29, 0x28, 0x83, 0x0c, 0xc1, 0x12, 0x19, 0x11, 0xc0, + 0x67, 0xbc, 0x61, 0xbb, 0xd6, 0xe0, 0x02, 0xbb, 0x14, 0x94, 0x41, 0x86, + 0x00, 0xb2, 0x46, 0x0c, 0x0a, 0x21, 0x88, 0x83, 0x22, 0x18, 0x6f, 0x00, + 0x03, 0xae, 0x0d, 0x2e, 0xb0, 0x4b, 0x41, 0x19, 0x64, 0x08, 0xaa, 0x6d, + 0xc4, 0xa0, 0x10, 0x02, 0x3b, 0x50, 0x82, 0xf1, 0x86, 0x32, 0x08, 0x03, + 0x37, 0xb8, 0xc0, 0x2e, 0x05, 0x65, 0x90, 0x21, 0xd0, 0xc0, 0x60, 0xc4, + 0xa0, 0x10, 0x82, 0x3d, 0x78, 0x82, 0x39, 0x86, 0x6e, 0xc9, 0x83, 0x39, + 0x86, 0xe0, 0xd8, 0x83, 0x39, 0x86, 0x60, 0xc8, 0x03, 0x0b, 0xde, 0x40, + 0x3e, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, + 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x6c, 0x0c, + 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, + 0x00, 0x00, 0x18, 0x03, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, + 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, + 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, + 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, + 0x44, 0x24, 0x48, 0x0a, 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, + 0x21, 0x72, 0x24, 0x07, 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, + 0xc6, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x8f, 0x00, + 0x00, 0x00, 0x1b, 0xcc, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x60, + 0x00, 0x09, 0xa8, 0x88, 0x71, 0x78, 0x07, 0x79, 0x90, 0x87, 0x72, 0x18, + 0x07, 0x7a, 0x60, 0x87, 0x7c, 0x68, 0x03, 0x79, 0x78, 0x87, 0x7a, 0x70, + 0x07, 0x72, 0x28, 0x07, 0x72, 0x68, 0x03, 0x72, 0x48, 0x07, 0x7b, 0x48, + 0x07, 0x72, 0x28, 0x87, 0x36, 0x98, 0x87, 0x78, 0x90, 0x07, 0x7a, 0x68, + 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, + 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xc8, 0x21, 0x1d, + 0xe6, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, + 0xd2, 0x81, 0x1d, 0xda, 0x60, 0x1c, 0xc2, 0x81, 0x1d, 0xd8, 0x61, 0x1e, + 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x76, 0x28, + 0x87, 0x79, 0x98, 0x87, 0x36, 0x80, 0x07, 0x79, 0x28, 0x87, 0x71, 0x48, + 0x87, 0x79, 0x28, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x87, 0x70, 0x20, + 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, + 0xde, 0xa1, 0x0d, 0xcc, 0x41, 0x1e, 0xc2, 0xa1, 0x1d, 0xca, 0xa1, 0x0d, + 0xe0, 0xe1, 0x1d, 0xd2, 0xc1, 0x1d, 0xe8, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, + 0xca, 0x81, 0x1d, 0xd2, 0xa1, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, + 0x07, 0x60, 0x70, 0x87, 0x77, 0x68, 0x03, 0x73, 0x90, 0x87, 0x70, 0x68, + 0x87, 0x72, 0x68, 0x03, 0x78, 0x78, 0x87, 0x74, 0x70, 0x07, 0x7a, 0x28, + 0x07, 0x79, 0x68, 0x83, 0x72, 0x60, 0x87, 0x74, 0x68, 0x87, 0x36, 0x70, + 0x87, 0x77, 0x70, 0x87, 0x36, 0x60, 0x87, 0x72, 0x08, 0x07, 0x73, 0x00, + 0x08, 0x77, 0x78, 0x87, 0x36, 0x48, 0x07, 0x77, 0x30, 0x87, 0x79, 0x68, + 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, + 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, + 0xd4, 0xa1, 0x1e, 0xda, 0x01, 0x1e, 0xda, 0x80, 0x1e, 0xc2, 0x41, 0x1c, + 0xd8, 0xa1, 0x1c, 0xe6, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, + 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x77, 0x08, 0x07, 0x77, 0x98, + 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, + 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, + 0xda, 0x60, 0x1e, 0xd2, 0xe1, 0x1c, 0xdc, 0xa1, 0x1c, 0xc8, 0xa1, 0x0d, + 0xf4, 0xa1, 0x1c, 0xe4, 0xe1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, + 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, + 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0xa0, 0x07, 0x79, 0x08, + 0x07, 0x78, 0x80, 0x87, 0x74, 0x70, 0x87, 0x73, 0x68, 0x83, 0x76, 0x08, + 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, + 0xe6, 0x81, 0x1e, 0xc2, 0x61, 0x1c, 0xd6, 0xa1, 0x0d, 0xe0, 0x41, 0x1e, + 0xde, 0x81, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, 0xa1, 0x0d, + 0xc4, 0xa1, 0x1e, 0xcc, 0xc1, 0x1c, 0xca, 0x41, 0x1e, 0xda, 0x60, 0x1e, + 0xd2, 0x41, 0x1f, 0xca, 0x01, 0xc0, 0x03, 0x80, 0xa8, 0x07, 0x77, 0x98, + 0x87, 0x70, 0x30, 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, + 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, + 0x00, 0xa2, 0x1e, 0xe6, 0xa1, 0x1c, 0xda, 0x60, 0x1e, 0xde, 0xc1, 0x1c, + 0xe8, 0xa1, 0x0d, 0xcc, 0x81, 0x1d, 0xde, 0x21, 0x1c, 0xe8, 0x01, 0x30, + 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x60, 0x83, 0x21, 0x10, 0xc0, + 0x02, 0x54, 0x1b, 0x8c, 0xa1, 0x00, 0x16, 0xa0, 0xda, 0x60, 0x10, 0x06, + 0xb0, 0x00, 0xd5, 0x06, 0xa3, 0x38, 0x80, 0x05, 0xa8, 0x36, 0x18, 0xc6, + 0xff, 0xff, 0xff, 0xff, 0x0f, 0x80, 0x04, 0x50, 0x1b, 0x90, 0xe3, 0xff, + 0xff, 0xff, 0xff, 0x07, 0x80, 0x01, 0x24, 0xa0, 0xda, 0x60, 0x20, 0x01, + 0xb0, 0x00, 0xd5, 0x06, 0x23, 0x11, 0x80, 0x05, 0xa8, 0x00, 0x49, 0x18, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x13, 0x8a, 0x40, 0x18, 0x88, 0x62, + 0x42, 0x60, 0x4c, 0x18, 0x0e, 0x24, 0x01, 0x00, 0x00, 0x00, 0x89, 0x20, + 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, + 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, + 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x68, + 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, 0x00, 0xc3, 0x08, 0x03, + 0x70, 0x90, 0x34, 0x45, 0x94, 0x30, 0xf9, 0xb2, 0xfb, 0x76, 0x84, 0xe0, + 0x0c, 0x04, 0x22, 0xc6, 0x18, 0x63, 0x10, 0x81, 0x10, 0x8e, 0x92, 0xa6, + 0x88, 0x12, 0x26, 0xff, 0x9f, 0x88, 0x6b, 0xa2, 0x22, 0xe2, 0xb7, 0x87, + 0x7f, 0x1a, 0x23, 0x00, 0x06, 0x11, 0x8c, 0xe0, 0x22, 0x69, 0x8a, 0x28, + 0x61, 0xf2, 0x7f, 0x09, 0x60, 0x9e, 0x85, 0x88, 0xfe, 0x69, 0x8c, 0x00, + 0x18, 0x44, 0x40, 0x84, 0x82, 0x84, 0x10, 0x44, 0x39, 0x27, 0x91, 0x2a, + 0x03, 0x18, 0x83, 0xd8, 0x1c, 0x41, 0x30, 0x47, 0x00, 0x06, 0xc3, 0x08, + 0xc2, 0x53, 0x90, 0x70, 0x92, 0x70, 0xd0, 0x01, 0x8a, 0x03, 0x01, 0x29, + 0xf0, 0x86, 0x11, 0x86, 0x67, 0x10, 0x21, 0x10, 0xe6, 0x08, 0x40, 0x61, + 0x10, 0x61, 0x10, 0x46, 0x00, 0x00, 0x13, 0xb2, 0x70, 0x48, 0x07, 0x79, + 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, + 0x68, 0x83, 0x76, 0x08, 0x87, 0x71, 0x78, 0x87, 0x79, 0xc0, 0x87, 0x38, + 0x80, 0x03, 0x37, 0x88, 0x83, 0x38, 0x70, 0x03, 0x38, 0xd8, 0x70, 0x1b, + 0xe5, 0xd0, 0x06, 0xf0, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, + 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0xa0, 0x07, + 0x78, 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x80, 0x07, 0x7a, 0x80, 0x07, + 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, + 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x90, 0x0e, 0x73, 0x20, 0x07, + 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x6d, 0x90, 0x0e, + 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, + 0x6d, 0x60, 0x0e, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, + 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0e, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, + 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x60, 0x07, + 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x6d, 0x60, 0x0f, + 0x72, 0x40, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, + 0x6d, 0x60, 0x0f, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xa0, 0x07, + 0x73, 0x20, 0x07, 0x6d, 0x60, 0x0f, 0x74, 0x80, 0x07, 0x7a, 0x60, 0x07, + 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, 0x76, 0x40, 0x07, + 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x6d, 0x60, 0x0f, + 0x79, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, + 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, + 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, + 0xf6, 0x10, 0x07, 0x79, 0x20, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, + 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x72, 0x50, 0x07, + 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, + 0x76, 0xd0, 0x06, 0xf6, 0x50, 0x07, 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, + 0x71, 0x20, 0x07, 0x7a, 0x50, 0x07, 0x71, 0x20, 0x07, 0x6d, 0x60, 0x0f, + 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, + 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x6d, 0xe0, 0x0e, + 0x78, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x30, 0x07, 0x72, 0x30, 0x84, + 0x59, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xc2, 0x34, + 0x40, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x61, 0x24, 0x20, + 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb2, 0x40, 0x00, 0x0b, 0x00, + 0x00, 0x00, 0x32, 0x1e, 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, + 0x26, 0x47, 0xc6, 0x04, 0x43, 0x7a, 0x25, 0x30, 0x02, 0x50, 0x20, 0x45, + 0x50, 0x08, 0x05, 0x18, 0x50, 0x10, 0x65, 0x50, 0x40, 0x05, 0x56, 0x0a, + 0xc5, 0x40, 0x74, 0x2c, 0x61, 0x09, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, + 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x10, 0x97, 0x29, + 0xa2, 0x25, 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4, 0x37, 0xb7, 0x21, 0xc6, + 0x63, 0x4c, 0x00, 0xf5, 0x50, 0xb9, 0x1b, 0x43, 0x0b, 0x93, 0xfb, 0x9a, + 0x4b, 0xd3, 0x2b, 0x1b, 0x62, 0x3c, 0xc3, 0x24, 0x3c, 0x07, 0xe5, 0x20, + 0x08, 0x0e, 0x8e, 0xad, 0x0c, 0x84, 0x89, 0xc9, 0xaa, 0x09, 0xc4, 0xae, + 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x0d, 0x64, 0x26, 0x06, 0x06, 0x26, 0xc6, + 0x25, 0xc6, 0x06, 0x06, 0x04, 0xa5, 0xad, 0x8c, 0x2e, 0x8c, 0xcd, 0xac, + 0xac, 0x65, 0x26, 0x06, 0x06, 0x26, 0xc6, 0x25, 0xc6, 0x06, 0xc6, 0x25, + 0x26, 0x65, 0x88, 0x30, 0x11, 0x43, 0x8c, 0x67, 0x78, 0x92, 0x87, 0x60, + 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, 0x04, 0x99, 0x8e, 0x67, 0x78, 0x86, + 0x87, 0xe0, 0x16, 0x96, 0x26, 0xe7, 0x32, 0xf6, 0xd6, 0x06, 0x97, 0xc6, + 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, 0x26, 0xd7, 0x36, 0xf7, 0x45, 0x96, + 0x36, 0x17, 0x26, 0xc6, 0x56, 0x36, 0x44, 0x98, 0x12, 0x72, 0x61, 0x69, + 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, + 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, + 0x6c, 0x65, 0x43, 0x84, 0x69, 0x61, 0x19, 0x84, 0xa5, 0xc9, 0xb9, 0x8c, + 0xbd, 0xb5, 0xc1, 0xa5, 0xb1, 0x95, 0xb9, 0x98, 0xc9, 0x85, 0xb5, 0x95, + 0x89, 0xd5, 0x99, 0x99, 0x95, 0xc9, 0x7d, 0x99, 0x95, 0xd1, 0x8d, 0xa1, + 0x7d, 0x91, 0xa5, 0xcd, 0x85, 0x89, 0xb1, 0x95, 0x0d, 0x11, 0xa6, 0x86, + 0x51, 0x58, 0x9a, 0x9c, 0x8b, 0x5c, 0x99, 0x1b, 0x59, 0x99, 0xdc, 0x17, + 0x5d, 0x98, 0xdc, 0x59, 0x19, 0x1d, 0xa3, 0xb0, 0x34, 0x39, 0x97, 0x30, + 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0x2f, 0xb7, 0xb0, 0xb6, 0x32, + 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x43, 0x90, 0xe9, 0x79, 0x88, + 0x09, 0x9a, 0xa2, 0x21, 0xc2, 0x24, 0x91, 0x09, 0x4b, 0x93, 0x73, 0x81, + 0x7b, 0x9b, 0x4b, 0xa3, 0x4b, 0x7b, 0x73, 0xa3, 0x12, 0x96, 0x26, 0xe7, + 0x32, 0x56, 0xe6, 0x46, 0x57, 0x26, 0x47, 0x29, 0x2c, 0x4d, 0xce, 0xc5, + 0xed, 0xed, 0x0b, 0xae, 0x4c, 0x6e, 0x0e, 0xae, 0x6c, 0x8c, 0x2e, 0xcd, + 0xae, 0x8c, 0x4c, 0x58, 0x9a, 0x9c, 0x4b, 0x98, 0xdc, 0xd9, 0x97, 0x5b, + 0x58, 0x5b, 0x19, 0x11, 0xb8, 0xb7, 0xb9, 0x34, 0xba, 0xb4, 0x37, 0xb7, + 0x21, 0xd0, 0x43, 0x4c, 0xd4, 0x54, 0x4d, 0xd6, 0x04, 0x4d, 0xd1, 0x74, + 0x4d, 0x18, 0xa5, 0xb0, 0x34, 0x39, 0x17, 0x33, 0xb9, 0xb0, 0xb3, 0xb6, + 0x32, 0x37, 0xba, 0xaf, 0x34, 0x37, 0xb8, 0x3a, 0x3a, 0x5a, 0x67, 0x65, + 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x35, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x44, 0x76, 0x34, 0x5f, 0x66, 0x29, 0x7c, 0xc2, 0xd2, 0xe4, + 0x5c, 0xe0, 0xca, 0xe4, 0xe6, 0xe0, 0xca, 0xc6, 0xe8, 0xd2, 0xec, 0xca, + 0x58, 0x8c, 0xbd, 0xb1, 0xbd, 0xc9, 0x0d, 0x91, 0x9e, 0x61, 0xd2, 0xa6, + 0x6d, 0xaa, 0x26, 0x6e, 0x82, 0xa6, 0x68, 0xba, 0xa6, 0x8e, 0xd9, 0x59, + 0x99, 0x5b, 0x99, 0x5c, 0x18, 0x5d, 0x19, 0x19, 0x0a, 0x0e, 0x5d, 0x19, + 0xde, 0xd8, 0xdb, 0x9b, 0x1c, 0x19, 0x91, 0x9d, 0xcc, 0x97, 0x59, 0x0a, + 0x0d, 0x33, 0xb6, 0xb7, 0x30, 0x3a, 0x19, 0x22, 0x74, 0x65, 0x78, 0x63, + 0x6f, 0x6f, 0x72, 0x64, 0x43, 0xa4, 0xc7, 0x98, 0xb4, 0xe9, 0x9b, 0xaa, + 0x89, 0x9b, 0xa0, 0x09, 0x0c, 0xa6, 0x6b, 0x0a, 0x03, 0x2a, 0x61, 0x69, + 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x7c, 0xc2, 0xd2, 0xe4, + 0x5c, 0xc4, 0xea, 0xcc, 0xcc, 0xca, 0xe4, 0xbe, 0xe6, 0xd2, 0xf4, 0xca, + 0x28, 0x85, 0xa5, 0xc9, 0xb9, 0xb0, 0xbd, 0x8d, 0x85, 0xd1, 0xa5, 0xbd, + 0xb9, 0x7d, 0xa5, 0xb9, 0x91, 0x95, 0xe1, 0x11, 0x09, 0x4b, 0x93, 0x73, + 0x91, 0x2b, 0x0b, 0x23, 0x23, 0x15, 0x96, 0x26, 0xe7, 0x32, 0x47, 0x27, + 0x57, 0x37, 0x46, 0xf7, 0x45, 0x97, 0x07, 0x57, 0xf6, 0x95, 0xe6, 0x66, + 0xf6, 0x46, 0xc3, 0x8c, 0xed, 0x2d, 0x8c, 0x6e, 0x86, 0xc6, 0x9b, 0x99, + 0xd9, 0x5c, 0x19, 0x1d, 0x0d, 0xa9, 0xb1, 0xb7, 0x32, 0x33, 0x33, 0x1a, + 0x47, 0x63, 0x6f, 0x65, 0x66, 0x66, 0x34, 0x84, 0xc6, 0xde, 0xca, 0xcc, + 0xcc, 0x86, 0xa0, 0xc1, 0x43, 0x3c, 0xc5, 0x43, 0x4c, 0x68, 0x30, 0xa5, + 0xc1, 0x53, 0x3c, 0xc5, 0x43, 0x4c, 0x68, 0x30, 0xa9, 0xc1, 0xb3, 0x3c, + 0xc5, 0x43, 0x4c, 0x68, 0x30, 0xad, 0xc1, 0xc3, 0x3c, 0xc5, 0x43, 0x4c, + 0x68, 0x30, 0xb1, 0x01, 0xa3, 0xb0, 0x34, 0x39, 0x97, 0x30, 0xb9, 0xb3, + 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0xaf, 0xb9, 0x34, 0xbd, 0x32, 0x5e, 0x61, + 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, + 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x4c, 0xb2, + 0xaa, 0xac, 0x88, 0xca, 0xc6, 0xde, 0xc8, 0xca, 0x68, 0x90, 0x95, 0x8d, + 0xbd, 0x91, 0x95, 0x0d, 0x21, 0x83, 0x47, 0x99, 0xc6, 0x60, 0x22, 0x83, + 0x07, 0x99, 0xca, 0xe0, 0x19, 0x9e, 0x61, 0x32, 0x83, 0xe9, 0x0c, 0xa6, + 0x36, 0x98, 0xdc, 0xe0, 0x41, 0xa6, 0x37, 0x78, 0x8a, 0x09, 0x9a, 0xe0, + 0x60, 0xba, 0xa6, 0x38, 0xe0, 0x12, 0x96, 0x26, 0xe7, 0x42, 0x57, 0x86, + 0x47, 0x57, 0x27, 0x57, 0x46, 0x25, 0x2c, 0x4d, 0xce, 0x65, 0x2e, 0xac, + 0x0d, 0x8e, 0xad, 0x8c, 0x18, 0x5d, 0x19, 0x1e, 0x5d, 0x9d, 0x5c, 0x99, + 0x0c, 0x19, 0x8f, 0x19, 0xdb, 0x5b, 0x18, 0x1d, 0x0b, 0xc8, 0x5c, 0x58, + 0x1b, 0x1c, 0x5b, 0x99, 0x0f, 0x09, 0xba, 0x32, 0xbc, 0xac, 0x21, 0xd4, + 0x73, 0x4c, 0x73, 0x30, 0x95, 0xc1, 0x43, 0x3c, 0xc3, 0x44, 0x07, 0x13, + 0x34, 0xd5, 0xc1, 0x74, 0x4d, 0x76, 0xc0, 0x82, 0xae, 0x0c, 0xaf, 0xca, + 0x6a, 0x08, 0xf5, 0x34, 0xd3, 0x1c, 0x4c, 0x65, 0xf0, 0x0c, 0xcf, 0x30, + 0xd1, 0xc1, 0x04, 0x4d, 0x75, 0x30, 0x5d, 0x13, 0x1e, 0x70, 0x09, 0x4b, + 0x93, 0x73, 0x99, 0x0b, 0x6b, 0x83, 0x63, 0x2b, 0x93, 0xe3, 0x31, 0x17, + 0xd6, 0x06, 0xc7, 0x56, 0x26, 0xc7, 0x60, 0x6e, 0x88, 0xf4, 0x38, 0x93, + 0x1e, 0x4c, 0x65, 0xf0, 0x10, 0xcf, 0x30, 0x41, 0xd3, 0x1e, 0x4c, 0xd7, + 0xc4, 0x07, 0x43, 0x9c, 0x29, 0x9b, 0xbc, 0x49, 0x0c, 0x26, 0x39, 0x98, + 0xee, 0x60, 0xca, 0x83, 0xa9, 0x0f, 0x86, 0x18, 0x0b, 0x30, 0x4d, 0x93, + 0x1f, 0x8c, 0x88, 0xd8, 0x81, 0x1d, 0xec, 0xa1, 0x1d, 0xdc, 0xa0, 0x1d, + 0xde, 0x81, 0x1c, 0xea, 0x81, 0x1d, 0xca, 0xc1, 0x0d, 0xcc, 0x81, 0x1d, + 0xc2, 0xe1, 0x1c, 0xe6, 0x61, 0x8a, 0x10, 0x0c, 0x23, 0x14, 0x76, 0x60, + 0x07, 0x7b, 0x68, 0x07, 0x37, 0x48, 0x07, 0x72, 0x28, 0x07, 0x77, 0xa0, + 0x87, 0x29, 0x41, 0x31, 0x62, 0x09, 0x87, 0x74, 0x90, 0x07, 0x37, 0xb0, + 0x87, 0x72, 0x90, 0x87, 0x79, 0x48, 0x87, 0x77, 0x70, 0x87, 0x29, 0x81, + 0x31, 0x82, 0x0a, 0x87, 0x74, 0x90, 0x07, 0x37, 0x60, 0x87, 0x70, 0x70, + 0x87, 0x73, 0xa8, 0x87, 0x70, 0x38, 0x87, 0x72, 0xf8, 0x05, 0x7b, 0x28, + 0x07, 0x79, 0x98, 0x87, 0x74, 0x78, 0x07, 0x77, 0x98, 0x12, 0x20, 0x23, + 0xa6, 0x70, 0x48, 0x07, 0x79, 0x70, 0x83, 0x71, 0x78, 0x87, 0x76, 0x80, + 0x87, 0x74, 0x60, 0x87, 0x72, 0xf8, 0x85, 0x77, 0x80, 0x07, 0x7a, 0x48, + 0x87, 0x77, 0x70, 0x87, 0x79, 0x98, 0x32, 0x28, 0x8c, 0x33, 0x82, 0x09, + 0x87, 0x74, 0x90, 0x07, 0x37, 0x30, 0x07, 0x79, 0x08, 0x87, 0x73, 0x68, + 0x87, 0x72, 0x70, 0x07, 0x7a, 0x98, 0x12, 0xfc, 0x01, 0x00, 0x79, 0x18, + 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, + 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, + 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, + 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, + 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, + 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, + 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, + 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, + 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, + 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, + 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, + 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, + 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, + 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, + 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, + 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, + 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, + 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, + 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, + 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, + 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, + 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, + 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, + 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, + 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, + 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, + 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, + 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, + 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, + 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, + 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, + 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, + 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, + 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, + 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, + 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, + 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, + 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, + 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, + 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, + 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, + 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, 0x00, 0x00, 0x0d, 0x00, + 0x00, 0x00, 0x16, 0xd0, 0x00, 0x48, 0xe4, 0x0f, 0xce, 0xe4, 0x57, 0x77, + 0x71, 0xdb, 0x26, 0xb0, 0x01, 0x48, 0xe4, 0x4b, 0x00, 0xf3, 0x2c, 0xc4, + 0x3f, 0x11, 0xd7, 0x44, 0x45, 0xc4, 0x6f, 0x0f, 0x7e, 0x85, 0x17, 0xb7, + 0x6d, 0x00, 0x11, 0xdb, 0x95, 0xff, 0xf9, 0xda, 0xf5, 0x5f, 0x44, 0x80, + 0xc1, 0x10, 0xcd, 0x04, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x36, 0x00, + 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x74, 0x47, 0x00, 0xa8, 0x8e, 0x35, 0x00, 0x03, 0x31, 0xc7, + 0x40, 0x0c, 0xdf, 0x1c, 0x03, 0xf1, 0x7d, 0x63, 0x0d, 0x40, 0x20, 0x10, + 0x1c, 0x4b, 0x08, 0x00, 0x72, 0x35, 0x30, 0x02, 0x40, 0x6f, 0x06, 0x80, + 0xe0, 0x08, 0x00, 0x89, 0x19, 0x00, 0x0a, 0x73, 0x10, 0x66, 0x60, 0x06, + 0x66, 0x40, 0x06, 0x33, 0x00, 0x04, 0xc6, 0x08, 0x40, 0x10, 0x04, 0xf1, + 0x6f, 0x04, 0x60, 0x06, 0x00, 0x00, 0x23, 0x06, 0xca, 0x10, 0x94, 0xc1, + 0x14, 0x55, 0xca, 0x91, 0x08, 0x83, 0x0c, 0x41, 0xe1, 0x8c, 0x18, 0x28, + 0x43, 0x70, 0x06, 0xd4, 0x74, 0x31, 0xc9, 0x42, 0x0c, 0x32, 0x04, 0x87, + 0x33, 0xc8, 0x10, 0x28, 0xd2, 0x20, 0x03, 0x11, 0x50, 0xa7, 0xd9, 0xa5, + 0xa0, 0x0c, 0x32, 0x04, 0x0c, 0x65, 0x44, 0x00, 0x9f, 0xf1, 0x06, 0x4f, + 0x73, 0x83, 0x0b, 0xec, 0x52, 0x50, 0x06, 0x19, 0x82, 0x28, 0x1b, 0x31, + 0x28, 0x84, 0x80, 0x0e, 0x8a, 0x60, 0xbc, 0x61, 0x0c, 0x3e, 0x38, 0xb8, + 0xc0, 0x2e, 0x05, 0x65, 0x90, 0x21, 0xb0, 0xbc, 0x11, 0x83, 0x42, 0x08, + 0xf2, 0x40, 0x09, 0xc6, 0x1b, 0xd0, 0x80, 0x0c, 0xe2, 0xe0, 0x02, 0xbb, + 0x14, 0x94, 0x41, 0x86, 0x60, 0x1b, 0x83, 0x11, 0x83, 0x42, 0x08, 0xfc, + 0xe0, 0x09, 0xe6, 0x18, 0xbc, 0x85, 0x0f, 0xe6, 0x18, 0x82, 0xc3, 0x0f, + 0xe6, 0x18, 0x82, 0x81, 0x0f, 0x2c, 0x90, 0x03, 0xf9, 0x64, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; +const unsigned int sdl_metallib_len = 21858; diff --git a/SDL2-2.30.5/src/render/metal/SDL_shaders_metal_tvos.h b/SDL2-2.30.5/src/render/metal/SDL_shaders_metal_tvos.h new file mode 100644 index 0000000..bbf2cec --- /dev/null +++ b/SDL2-2.30.5/src/render/metal/SDL_shaders_metal_tvos.h @@ -0,0 +1,1821 @@ +const unsigned char sdl_metallib[] = { + 0x4d, 0x54, 0x4c, 0x42, 0x01, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x32, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xac, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x72, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x50, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, + 0x4e, 0x41, 0x4d, 0x45, 0x11, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x53, 0x6f, + 0x6c, 0x69, 0x64, 0x5f, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x00, 0x54, + 0x59, 0x50, 0x45, 0x01, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x20, 0x00, + 0xa4, 0x5e, 0x94, 0xe7, 0x16, 0x2a, 0x15, 0xdb, 0x41, 0x62, 0x0f, 0xc4, + 0x8a, 0xaa, 0x92, 0x52, 0xe1, 0x1e, 0xbe, 0x5f, 0xef, 0xec, 0x0e, 0x83, + 0x38, 0xb6, 0x06, 0x42, 0xfb, 0x46, 0x30, 0x45, 0x4f, 0x46, 0x46, 0x54, + 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x01, 0x00, 0x08, 0x00, + 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x77, 0x00, 0x00, 0x00, + 0x4e, 0x41, 0x4d, 0x45, 0x10, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x43, 0x6f, + 0x70, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x00, 0x54, 0x59, + 0x50, 0x45, 0x01, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x20, 0x00, 0x4a, + 0xdb, 0x37, 0xcf, 0x60, 0x13, 0xba, 0xf8, 0x04, 0xff, 0xec, 0xd1, 0x3d, + 0x3f, 0x77, 0xbb, 0xaa, 0xe4, 0x36, 0xd0, 0x6e, 0x89, 0xfb, 0x91, 0xfb, + 0xfd, 0xb2, 0xb4, 0x56, 0x8e, 0x5e, 0x05, 0x4f, 0x46, 0x46, 0x54, 0x18, + 0x00, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, + 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x7a, 0x00, 0x00, 0x00, 0x4e, + 0x41, 0x4d, 0x45, 0x13, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x53, 0x6f, 0x6c, + 0x69, 0x64, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x00, + 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, 0x53, 0x48, 0x20, + 0x00, 0x93, 0xcd, 0x48, 0xeb, 0xee, 0x18, 0x36, 0xf1, 0x25, 0x14, 0x9f, + 0x98, 0xc6, 0x7e, 0x3f, 0x06, 0xd1, 0x5d, 0x98, 0x2a, 0x2f, 0x70, 0xe1, + 0xa3, 0xa4, 0x4f, 0x06, 0x51, 0xd9, 0x24, 0xdb, 0x3d, 0x4f, 0x46, 0x46, + 0x54, 0x18, 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x17, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x01, 0x00, 0x08, + 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x79, 0x00, 0x00, + 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x12, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x43, + 0x6f, 0x70, 0x79, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, + 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, 0x53, 0x48, + 0x20, 0x00, 0x48, 0x19, 0xba, 0x48, 0x88, 0x08, 0x02, 0x7a, 0x7b, 0x87, + 0x60, 0x4f, 0x56, 0x77, 0x82, 0x12, 0xd0, 0x8d, 0x75, 0x00, 0x13, 0xd4, + 0x4f, 0x12, 0x69, 0x87, 0x49, 0x45, 0xb7, 0xda, 0x31, 0x6f, 0x4f, 0x46, + 0x46, 0x54, 0x18, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x01, 0x00, + 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x78, 0x00, + 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x11, 0x00, 0x53, 0x44, 0x4c, 0x5f, + 0x59, 0x55, 0x56, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, + 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, 0x53, 0x48, + 0x20, 0x00, 0x86, 0xd8, 0xc8, 0xb9, 0x4b, 0x3f, 0xf0, 0x71, 0x98, 0x15, + 0x75, 0xd7, 0xc4, 0x78, 0x49, 0x02, 0xc5, 0x2c, 0x0d, 0xa2, 0xf8, 0x40, + 0xd8, 0x18, 0xf5, 0xa8, 0xc2, 0x8b, 0x11, 0x42, 0x60, 0x9e, 0x4f, 0x46, + 0x46, 0x54, 0x18, 0x00, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x2a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x01, 0x00, + 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x79, 0x00, + 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x12, 0x00, 0x53, 0x44, 0x4c, 0x5f, + 0x4e, 0x56, 0x31, 0x32, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, + 0x74, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, 0x53, + 0x48, 0x20, 0x00, 0x0c, 0x19, 0x24, 0x25, 0x5b, 0x90, 0x7b, 0xbe, 0xd8, + 0x0c, 0x0d, 0x1b, 0x66, 0xe5, 0x2f, 0xc5, 0x6d, 0x8a, 0xf1, 0x08, 0xc3, + 0x68, 0x52, 0x1a, 0x5b, 0x1f, 0x8d, 0x05, 0xe0, 0x43, 0x9b, 0xce, 0x4f, + 0x46, 0x46, 0x54, 0x18, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x37, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x01, + 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x79, + 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x12, 0x00, 0x53, 0x44, 0x4c, + 0x5f, 0x4e, 0x56, 0x32, 0x31, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, + 0x6e, 0x74, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, + 0x53, 0x48, 0x20, 0x00, 0x4a, 0x04, 0xcb, 0xef, 0xd3, 0x81, 0xd0, 0x17, + 0x11, 0xf6, 0x23, 0x6b, 0x3b, 0x38, 0xfc, 0x61, 0xe0, 0x6d, 0x22, 0x94, + 0x28, 0x7c, 0x7f, 0xe6, 0x31, 0xde, 0x9b, 0xe1, 0x58, 0x2b, 0x1f, 0x84, + 0x4f, 0x46, 0x46, 0x54, 0x18, 0x00, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x44, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, + 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, + 0x45, 0x4e, 0x44, 0x54, 0x29, 0x00, 0x00, 0x00, 0x56, 0x41, 0x54, 0x54, + 0x15, 0x00, 0x02, 0x00, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x00, 0x00, 0x80, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x01, 0x80, 0x56, + 0x41, 0x54, 0x59, 0x04, 0x00, 0x02, 0x00, 0x04, 0x06, 0x45, 0x4e, 0x44, + 0x54, 0x35, 0x00, 0x00, 0x00, 0x56, 0x41, 0x54, 0x54, 0x20, 0x00, 0x03, + 0x00, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x80, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x01, 0x80, 0x74, 0x65, 0x78, 0x63, + 0x6f, 0x6f, 0x72, 0x64, 0x00, 0x02, 0x80, 0x56, 0x41, 0x54, 0x59, 0x05, + 0x00, 0x03, 0x00, 0x04, 0x06, 0x04, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, + 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, + 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, + 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, + 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, + 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, + 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, + 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, + 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0xde, 0xc0, + 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xa0, 0x0b, + 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, + 0x00, 0x00, 0xe5, 0x02, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, + 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, + 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, + 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, + 0x44, 0x24, 0x48, 0x0a, 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, + 0x21, 0x72, 0x24, 0x07, 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, + 0xc6, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x84, 0x00, + 0x00, 0x00, 0x1b, 0xc8, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x90, + 0x80, 0x8a, 0x18, 0x87, 0x77, 0x90, 0x07, 0x79, 0x28, 0x87, 0x71, 0xa0, + 0x07, 0x76, 0xc8, 0x87, 0x36, 0x90, 0x87, 0x77, 0xa8, 0x07, 0x77, 0x20, + 0x87, 0x72, 0x20, 0x87, 0x36, 0x20, 0x87, 0x74, 0xb0, 0x87, 0x74, 0x20, + 0x87, 0x72, 0x68, 0x83, 0x79, 0x88, 0x07, 0x79, 0xa0, 0x87, 0x36, 0x30, + 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0xc0, 0x1c, + 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1c, 0xd2, 0x61, 0x1e, + 0xc2, 0x41, 0x1c, 0xd8, 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xc2, 0x21, 0x1d, + 0xd8, 0xa1, 0x0d, 0xc6, 0x21, 0x1c, 0xd8, 0x81, 0x1d, 0xe6, 0x01, 0x30, + 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x60, 0x87, 0x72, 0x98, + 0x87, 0x79, 0x68, 0x03, 0x78, 0x90, 0x87, 0x72, 0x18, 0x87, 0x74, 0x98, + 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x76, 0x08, 0x07, 0x72, 0x00, + 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, + 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, + 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, + 0xd8, 0x21, 0x1d, 0xda, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, + 0x06, 0x77, 0x78, 0x87, 0x36, 0x30, 0x07, 0x79, 0x08, 0x87, 0x76, 0x28, + 0x87, 0x36, 0x80, 0x87, 0x77, 0x48, 0x07, 0x77, 0xa0, 0x87, 0x72, 0x90, + 0x87, 0x36, 0x28, 0x07, 0x76, 0x48, 0x87, 0x76, 0x68, 0x03, 0x77, 0x78, + 0x07, 0x77, 0x68, 0x03, 0x76, 0x28, 0x87, 0x70, 0x30, 0x07, 0x80, 0x70, + 0x87, 0x77, 0x68, 0x83, 0x74, 0x70, 0x07, 0x73, 0x98, 0x87, 0x36, 0x30, + 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, + 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x40, 0x1d, + 0xea, 0xa1, 0x1d, 0xe0, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xc4, 0x81, 0x1d, + 0xca, 0x61, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, + 0x08, 0x77, 0x78, 0x87, 0x36, 0x70, 0x87, 0x70, 0x70, 0x87, 0x79, 0x68, + 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, + 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, + 0xe6, 0x21, 0x1d, 0xce, 0xc1, 0x1d, 0xca, 0x81, 0x1c, 0xda, 0x40, 0x1f, + 0xca, 0x41, 0x1e, 0xde, 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, + 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, + 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x7a, 0x90, 0x87, 0x70, 0x80, + 0x07, 0x78, 0x48, 0x07, 0x77, 0x38, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, + 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0x62, 0x1e, + 0xe8, 0x21, 0x1c, 0xc6, 0x61, 0x1d, 0xda, 0x00, 0x1e, 0xe4, 0xe1, 0x1d, + 0xe8, 0xa1, 0x1c, 0xc6, 0x81, 0x1e, 0xde, 0x41, 0x1e, 0xda, 0x40, 0x1c, + 0xea, 0xc1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, + 0xf4, 0xa1, 0x1c, 0x00, 0x3c, 0x00, 0x88, 0x7a, 0x70, 0x87, 0x79, 0x08, + 0x07, 0x73, 0x28, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, + 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, + 0xea, 0x61, 0x1e, 0xca, 0xa1, 0x0d, 0xe6, 0xe1, 0x1d, 0xcc, 0x81, 0x1e, + 0xda, 0xc0, 0x1c, 0xd8, 0xe1, 0x1d, 0xc2, 0x81, 0x1e, 0x00, 0x73, 0x08, + 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x36, 0x20, 0xc2, 0x00, 0x24, 0xc0, + 0x02, 0x54, 0x1b, 0x90, 0x81, 0x00, 0x12, 0x60, 0x01, 0x2a, 0x00, 0x00, + 0x00, 0x00, 0x49, 0x18, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x86, + 0x40, 0x18, 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x1c, 0x00, + 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, + 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, + 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x40, 0x33, 0x00, 0xc3, 0x08, + 0x04, 0x60, 0x87, 0x10, 0xc0, 0x30, 0x82, 0x00, 0x24, 0x41, 0x98, 0x89, + 0x9a, 0x07, 0x7a, 0x90, 0x87, 0x7a, 0x18, 0x07, 0x7a, 0x70, 0x83, 0x76, + 0x28, 0x07, 0x7a, 0x08, 0x07, 0x76, 0xd0, 0x03, 0x3d, 0x68, 0x87, 0x70, + 0xa0, 0x07, 0x79, 0x48, 0x07, 0x7c, 0x40, 0x01, 0x19, 0x44, 0x28, 0x84, + 0x52, 0x88, 0x11, 0x8c, 0xa1, 0x33, 0x10, 0x30, 0x47, 0x00, 0x06, 0x29, + 0xa0, 0xe6, 0x08, 0x40, 0x61, 0x10, 0x21, 0x10, 0x86, 0x11, 0x08, 0x65, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xa8, 0x70, 0x48, 0x07, 0x79, + 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, + 0x68, 0x83, 0x74, 0x78, 0x87, 0x79, 0xc8, 0x03, 0x37, 0x80, 0x03, 0x37, + 0x80, 0x83, 0x0d, 0xb7, 0x51, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x60, 0x07, + 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, + 0xe9, 0x10, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, + 0x78, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x10, 0x07, + 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, + 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, + 0x72, 0xd0, 0x06, 0xe9, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, + 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x30, 0x07, 0x72, 0xa0, 0x07, + 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, + 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, + 0xf6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, + 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x73, 0x20, 0x07, + 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x30, 0x07, 0x72, 0xa0, 0x07, + 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x40, 0x07, + 0x78, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, + 0xf6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, + 0x74, 0xd0, 0x06, 0xf6, 0x90, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x20, 0x07, + 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, + 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, + 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x90, 0x07, 0x72, 0xa0, 0x07, + 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, + 0xf6, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, + 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x75, 0x10, 0x07, + 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, + 0x72, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, + 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, + 0x74, 0xd0, 0x06, 0xee, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, + 0x73, 0x20, 0x07, 0x43, 0x18, 0x04, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x2c, 0x10, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x32, 0x1e, + 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, + 0x43, 0x52, 0x25, 0x30, 0x02, 0x50, 0x80, 0x01, 0x45, 0x50, 0x20, 0x65, + 0x50, 0x08, 0x05, 0x41, 0x6c, 0x04, 0x80, 0xd6, 0x58, 0x82, 0x33, 0x00, + 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0xe4, 0x00, 0x00, 0x00, 0x1a, 0x03, + 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4, + 0x37, 0xb7, 0x21, 0x86, 0x42, 0x24, 0xc0, 0xa2, 0x50, 0xb9, 0x1b, 0x43, + 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x1b, 0x62, 0x28, 0x41, 0x22, + 0x28, 0x07, 0xe1, 0x20, 0x08, 0x0e, 0x8e, 0xad, 0x0c, 0x84, 0x89, 0xc9, + 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x0d, 0x64, 0x26, + 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, 0x06, 0x04, 0xa5, 0xad, 0x8c, 0x2e, + 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, + 0xc6, 0x25, 0x26, 0x65, 0x88, 0x90, 0x10, 0x43, 0x0c, 0x25, 0x50, 0x10, + 0x45, 0x60, 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, 0x04, 0x49, 0x0e, 0x25, + 0x50, 0x02, 0x45, 0xe0, 0x16, 0x96, 0x26, 0xe7, 0x32, 0xf6, 0xd6, 0x06, + 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, 0x26, 0xd7, 0x36, 0xf7, + 0x45, 0x96, 0x36, 0x17, 0x26, 0xc6, 0x56, 0x36, 0x44, 0x48, 0x12, 0x72, + 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, + 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, 0x65, 0x6e, + 0x61, 0x62, 0x6c, 0x65, 0x43, 0x84, 0x64, 0x21, 0x19, 0x84, 0xa5, 0xc9, + 0xb9, 0x8c, 0xbd, 0xb5, 0xc1, 0xa5, 0xb1, 0x95, 0xb9, 0x98, 0xc9, 0x85, + 0xb5, 0x95, 0x89, 0xd5, 0x99, 0x99, 0x95, 0xc9, 0x7d, 0x99, 0x95, 0xd1, + 0x8d, 0xa1, 0x7d, 0x95, 0xb9, 0x85, 0x89, 0xb1, 0x95, 0x0d, 0x11, 0x92, + 0x86, 0x4c, 0x58, 0x9a, 0x9c, 0x0b, 0xdc, 0xdb, 0x5c, 0x1a, 0x5d, 0xda, + 0x9b, 0x1b, 0xa3, 0xb0, 0x34, 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, + 0x3c, 0xb8, 0xb2, 0x2f, 0xb7, 0xb0, 0xb6, 0x32, 0x1a, 0x66, 0x6c, 0x6f, + 0x61, 0x74, 0x34, 0x64, 0xc2, 0xd2, 0xe4, 0x5c, 0xc2, 0xe4, 0xce, 0xbe, + 0xdc, 0xc2, 0xda, 0xca, 0x88, 0xc0, 0xbd, 0xcd, 0xa5, 0xd1, 0xa5, 0xbd, + 0xb9, 0x0d, 0x51, 0x92, 0x27, 0x81, 0x92, 0x28, 0x91, 0x92, 0x89, 0x51, + 0x58, 0x9a, 0x9c, 0x8b, 0x5d, 0x99, 0x1c, 0x5d, 0x19, 0xde, 0xd7, 0x5b, + 0x1d, 0x1d, 0x5c, 0x1d, 0x1d, 0xad, 0xb3, 0x32, 0xb7, 0x32, 0xb9, 0x30, + 0xba, 0x32, 0x32, 0x94, 0x9a, 0xb1, 0x37, 0xb6, 0x37, 0x39, 0x22, 0x3b, + 0x9a, 0x2f, 0xb3, 0x14, 0x16, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x43, 0x98, + 0xa4, 0x4a, 0xac, 0x04, 0x4a, 0xa2, 0x44, 0x4a, 0x2e, 0x3a, 0x61, 0x69, + 0x72, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x5f, 0x73, 0x69, 0x7a, 0x65, + 0x2c, 0xcc, 0xd8, 0xde, 0xc2, 0xe8, 0x98, 0xc0, 0xbd, 0xa5, 0xb9, 0xd1, + 0x4d, 0xa5, 0xe9, 0x95, 0x0d, 0x51, 0x92, 0x2c, 0x81, 0x12, 0x2d, 0x91, + 0x92, 0x6d, 0x88, 0x91, 0x50, 0x09, 0x96, 0x70, 0x84, 0xc2, 0xd2, 0xe4, + 0x5c, 0xec, 0xca, 0xe4, 0xe8, 0xca, 0xf0, 0xbe, 0xd2, 0xdc, 0xe0, 0xea, + 0xe8, 0x28, 0x85, 0xa5, 0xc9, 0xb9, 0xb0, 0xbd, 0x8d, 0x85, 0xd1, 0xa5, + 0xbd, 0xb9, 0x7d, 0xa5, 0xb9, 0x91, 0x95, 0xe1, 0xd1, 0x3b, 0x2b, 0x73, + 0x2b, 0x93, 0x0b, 0xa3, 0x2b, 0x23, 0x43, 0xf9, 0xfa, 0x0a, 0x4b, 0x93, + 0xfb, 0x82, 0x63, 0x0b, 0x1b, 0x2b, 0x43, 0x7b, 0x63, 0x23, 0x2b, 0x93, + 0xfb, 0xfa, 0x4a, 0xa1, 0x61, 0xc6, 0xf6, 0x16, 0x46, 0x27, 0x33, 0x84, + 0x52, 0x84, 0xc4, 0x4b, 0x3e, 0x45, 0x50, 0x82, 0x04, 0x0c, 0x12, 0x28, + 0x09, 0x83, 0x44, 0x4a, 0xa6, 0x21, 0x94, 0x12, 0x24, 0x5e, 0xf2, 0x29, + 0x81, 0x12, 0x24, 0x60, 0x90, 0x40, 0x49, 0x94, 0x48, 0xc9, 0x45, 0x25, + 0x2c, 0x4d, 0xce, 0x45, 0xac, 0xce, 0xcc, 0xac, 0x4c, 0x8e, 0x4f, 0x58, + 0x9a, 0x9c, 0x8b, 0x58, 0x9d, 0x99, 0x59, 0x99, 0xdc, 0xd7, 0x5c, 0x9a, + 0x5e, 0x19, 0x91, 0xb0, 0x34, 0x39, 0x17, 0xb9, 0xb2, 0x30, 0x32, 0x46, + 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x5f, 0x73, 0x69, 0x7a, 0x65, 0xbc, 0xc2, 0xd2, 0xe4, 0x5c, 0xc2, 0xe4, + 0xce, 0xbe, 0xe8, 0xf2, 0xe0, 0xca, 0xbe, 0xc2, 0xd8, 0xd2, 0xce, 0xdc, + 0xbe, 0xe6, 0xd2, 0xf4, 0xca, 0x88, 0x98, 0xb1, 0xbd, 0x85, 0xd1, 0xd1, + 0xe0, 0xd1, 0x50, 0x81, 0x93, 0x7b, 0x53, 0x2b, 0x1b, 0xa3, 0x4b, 0x7b, + 0x73, 0x1b, 0x02, 0x06, 0x0a, 0x91, 0x90, 0x41, 0x52, 0x06, 0xca, 0x90, + 0x7c, 0x0a, 0xa1, 0x04, 0x89, 0x19, 0x24, 0x67, 0xa0, 0x0c, 0x09, 0x1a, + 0x28, 0x45, 0x02, 0x25, 0x69, 0x90, 0x48, 0x89, 0x1a, 0x30, 0xa1, 0x93, + 0x0b, 0x73, 0x9b, 0x33, 0x7b, 0x93, 0x6b, 0x1b, 0x02, 0x06, 0x8a, 0x91, + 0x90, 0x41, 0x52, 0x06, 0xca, 0x90, 0x7c, 0x8a, 0xa1, 0x04, 0x89, 0x19, + 0x24, 0x67, 0xa0, 0x0c, 0x09, 0x1a, 0x28, 0x45, 0x02, 0x25, 0x69, 0x90, + 0x48, 0x09, 0x1b, 0x0c, 0x41, 0x12, 0x31, 0x48, 0xc6, 0x20, 0x59, 0x83, + 0xa4, 0x0d, 0x86, 0x18, 0x08, 0x90, 0x74, 0x89, 0x1b, 0xf0, 0x79, 0x6b, + 0x73, 0x4b, 0x83, 0x7b, 0xa3, 0x2b, 0x73, 0xa3, 0x03, 0x19, 0x43, 0x0b, + 0x93, 0xe3, 0x33, 0x95, 0xd6, 0x06, 0xc7, 0x56, 0x06, 0x32, 0xb4, 0xb2, + 0x02, 0x42, 0x25, 0x14, 0x14, 0x34, 0x44, 0x48, 0xe2, 0x60, 0x88, 0x91, + 0xc0, 0x41, 0x22, 0x07, 0x4c, 0x32, 0xc4, 0x48, 0xe6, 0x20, 0x99, 0x03, + 0x26, 0x19, 0x11, 0xb1, 0x03, 0x3b, 0xd8, 0x43, 0x3b, 0xb8, 0x41, 0x3b, + 0xbc, 0x03, 0x39, 0xd4, 0x03, 0x3b, 0x94, 0x83, 0x1b, 0x98, 0x03, 0x3b, + 0x84, 0xc3, 0x39, 0xcc, 0xc3, 0x14, 0x21, 0x18, 0x46, 0x28, 0xec, 0xc0, + 0x0e, 0xf6, 0xd0, 0x0e, 0x6e, 0x90, 0x0e, 0xe4, 0x50, 0x0e, 0xee, 0x40, + 0x0f, 0x53, 0x82, 0x62, 0xc4, 0x12, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0x60, + 0x0f, 0xe5, 0x20, 0x0f, 0xf3, 0x90, 0x0e, 0xef, 0xe0, 0x0e, 0x53, 0x02, + 0x63, 0x04, 0x15, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0xc0, 0x0e, 0xe1, 0xe0, + 0x0e, 0xe7, 0x50, 0x0f, 0xe1, 0x70, 0x0e, 0xe5, 0xf0, 0x0b, 0xf6, 0x50, + 0x0e, 0xf2, 0x30, 0x0f, 0xe9, 0xf0, 0x0e, 0xee, 0x30, 0x25, 0x40, 0x46, + 0x4c, 0xe1, 0x90, 0x0e, 0xf2, 0xe0, 0x06, 0xe3, 0xf0, 0x0e, 0xed, 0x00, + 0x0f, 0xe9, 0xc0, 0x0e, 0xe5, 0xf0, 0x0b, 0xef, 0x00, 0x0f, 0xf4, 0x90, + 0x0e, 0xef, 0xe0, 0x0e, 0xf3, 0x30, 0x65, 0x50, 0x18, 0x67, 0x84, 0x12, + 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0x60, 0x0f, 0xe5, 0x20, 0x0f, 0xf4, 0x50, + 0x0e, 0xf8, 0x30, 0x25, 0x78, 0x03, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, + 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, + 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, + 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, + 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, + 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, + 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, + 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, + 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, + 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, + 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, + 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, + 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, + 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, + 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, + 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, + 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, + 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, + 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, + 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, + 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, + 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, + 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, + 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, + 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, + 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, + 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, + 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, + 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, + 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, + 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, + 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, + 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, + 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, + 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, + 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, + 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, + 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, + 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, + 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, + 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, + 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, + 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x06, 0x00, 0xb1, 0x5d, 0xf9, 0xb3, 0xce, 0x82, 0x0c, 0x7f, + 0x45, 0x44, 0x13, 0x71, 0x01, 0x00, 0x61, 0x20, 0x00, 0x00, 0x54, 0x00, + 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x0b, 0x00, + 0x00, 0x00, 0xe4, 0xc6, 0x22, 0x86, 0x61, 0x18, 0xc6, 0x22, 0x04, 0x41, + 0x10, 0xc6, 0x22, 0x82, 0x20, 0x08, 0x46, 0x00, 0x88, 0x95, 0x40, 0x19, + 0x14, 0x01, 0x8d, 0x19, 0x00, 0x12, 0x33, 0x00, 0x14, 0x66, 0x00, 0x08, + 0x8c, 0x11, 0x80, 0x20, 0x08, 0xe2, 0x1f, 0x00, 0x00, 0x00, 0xe3, 0x11, + 0x4c, 0x84, 0x45, 0x14, 0x94, 0xf1, 0x88, 0x67, 0xd2, 0x26, 0x0a, 0xca, + 0x20, 0xc3, 0x60, 0x30, 0x26, 0x04, 0xf2, 0x19, 0x8f, 0x98, 0x2e, 0xaf, + 0xa1, 0xa0, 0x0c, 0x32, 0x1c, 0x4a, 0x64, 0x42, 0x20, 0x1f, 0x0b, 0x0a, + 0xf8, 0x8c, 0x47, 0x60, 0xdc, 0x18, 0x40, 0x14, 0x94, 0x41, 0x06, 0xe6, + 0xb9, 0x4c, 0x08, 0xe4, 0x63, 0x45, 0x00, 0x9f, 0xf1, 0x88, 0x2e, 0x0c, + 0xd0, 0xc0, 0xa2, 0xa0, 0x0c, 0x32, 0x44, 0x54, 0x67, 0x42, 0x20, 0x1f, + 0x2b, 0x02, 0xf8, 0x8c, 0x47, 0x84, 0x81, 0x19, 0xb4, 0x01, 0x47, 0x41, + 0x19, 0x64, 0x08, 0xb2, 0xcf, 0x82, 0x4a, 0x3e, 0x83, 0x0c, 0xc3, 0x26, + 0x06, 0x16, 0x4c, 0xf2, 0xb1, 0x21, 0x80, 0xcf, 0x20, 0x83, 0xe1, 0x99, + 0x81, 0x05, 0x91, 0x7c, 0x6c, 0x08, 0xe0, 0x33, 0xc8, 0x90, 0x84, 0x81, + 0x1a, 0x58, 0xf0, 0xc8, 0xc7, 0x86, 0x00, 0x3e, 0xe3, 0x11, 0x6e, 0x30, + 0x07, 0x7a, 0x80, 0x06, 0x14, 0x94, 0x41, 0x86, 0xc0, 0x0c, 0xd8, 0xc0, + 0x02, 0x31, 0x90, 0xcf, 0x20, 0xc3, 0x80, 0x06, 0x6f, 0x60, 0x01, 0x18, + 0xc8, 0x67, 0x90, 0xa1, 0x50, 0x03, 0x39, 0xb0, 0xa0, 0x93, 0xcf, 0x20, + 0xc3, 0xc1, 0x06, 0x75, 0x60, 0x81, 0x26, 0x9f, 0x41, 0x86, 0x3d, 0x80, + 0x03, 0x3a, 0xb0, 0x2c, 0x90, 0xcf, 0x20, 0x43, 0x1f, 0xc8, 0xc1, 0x1d, + 0x98, 0x13, 0xc8, 0xc7, 0x92, 0x01, 0x3e, 0x16, 0x30, 0xf0, 0xb1, 0x20, + 0x81, 0x8f, 0x05, 0x08, 0x7c, 0x2c, 0x28, 0xe0, 0x33, 0xdb, 0x80, 0x07, + 0x01, 0x30, 0xdb, 0x10, 0x90, 0x42, 0x30, 0xdb, 0x10, 0xe0, 0x81, 0x90, + 0x41, 0x40, 0x0c, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x5b, 0x86, + 0x20, 0xa0, 0x83, 0x2d, 0xc3, 0x10, 0xd0, 0xc1, 0x96, 0xe1, 0x08, 0xe8, + 0x60, 0xcb, 0xc0, 0x04, 0x74, 0xb0, 0x65, 0x88, 0x02, 0x3a, 0xd8, 0x32, + 0x58, 0x01, 0x1d, 0x6c, 0x19, 0xc6, 0x20, 0xa0, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, + 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xb0, 0x0b, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0xe9, 0x02, + 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, + 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, + 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, + 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, 0x44, 0x24, 0x48, 0x0a, + 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, 0x21, 0x72, 0x24, 0x07, + 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, + 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0x1b, 0xc8, + 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x90, 0x80, 0x8a, 0x18, 0x87, + 0x77, 0x90, 0x07, 0x79, 0x28, 0x87, 0x71, 0xa0, 0x07, 0x76, 0xc8, 0x87, + 0x36, 0x90, 0x87, 0x77, 0xa8, 0x07, 0x77, 0x20, 0x87, 0x72, 0x20, 0x87, + 0x36, 0x20, 0x87, 0x74, 0xb0, 0x87, 0x74, 0x20, 0x87, 0x72, 0x68, 0x83, + 0x79, 0x88, 0x07, 0x79, 0xa0, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, + 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, + 0xa1, 0x1c, 0x00, 0x82, 0x1c, 0xd2, 0x61, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, + 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xc2, 0x21, 0x1d, 0xd8, 0xa1, 0x0d, 0xc6, + 0x21, 0x1c, 0xd8, 0x81, 0x1d, 0xe6, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, + 0x79, 0x28, 0x07, 0x80, 0x60, 0x87, 0x72, 0x98, 0x87, 0x79, 0x68, 0x03, + 0x78, 0x90, 0x87, 0x72, 0x18, 0x87, 0x74, 0x98, 0x87, 0x72, 0x68, 0x03, + 0x73, 0x80, 0x87, 0x76, 0x08, 0x07, 0x72, 0x00, 0xcc, 0x21, 0x1c, 0xd8, + 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, + 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, + 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, + 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x06, 0x77, 0x78, 0x87, + 0x36, 0x30, 0x07, 0x79, 0x08, 0x87, 0x76, 0x28, 0x87, 0x36, 0x80, 0x87, + 0x77, 0x48, 0x07, 0x77, 0xa0, 0x87, 0x72, 0x90, 0x87, 0x36, 0x28, 0x07, + 0x76, 0x48, 0x87, 0x76, 0x68, 0x03, 0x77, 0x78, 0x07, 0x77, 0x68, 0x03, + 0x76, 0x28, 0x87, 0x70, 0x30, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x83, + 0x74, 0x70, 0x07, 0x73, 0x98, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, + 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, + 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x40, 0x1d, 0xea, 0xa1, 0x1d, 0xe0, + 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x1e, 0x00, + 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, + 0x36, 0x70, 0x87, 0x70, 0x70, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, + 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, + 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xce, + 0xc1, 0x1d, 0xca, 0x81, 0x1c, 0xda, 0x40, 0x1f, 0xca, 0x41, 0x1e, 0xde, + 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, + 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, + 0x77, 0x68, 0x03, 0x7a, 0x90, 0x87, 0x70, 0x80, 0x07, 0x78, 0x48, 0x07, + 0x77, 0x38, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, + 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0x62, 0x1e, 0xe8, 0x21, 0x1c, 0xc6, + 0x61, 0x1d, 0xda, 0x00, 0x1e, 0xe4, 0xe1, 0x1d, 0xe8, 0xa1, 0x1c, 0xc6, + 0x81, 0x1e, 0xde, 0x41, 0x1e, 0xda, 0x40, 0x1c, 0xea, 0xc1, 0x1c, 0xcc, + 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xf4, 0xa1, 0x1c, 0x00, + 0x3c, 0x00, 0x88, 0x7a, 0x70, 0x87, 0x79, 0x08, 0x07, 0x73, 0x28, 0x87, + 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, + 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xea, 0x61, 0x1e, 0xca, + 0xa1, 0x0d, 0xe6, 0xe1, 0x1d, 0xcc, 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xd8, + 0xe1, 0x1d, 0xc2, 0x81, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, + 0x72, 0x00, 0x36, 0x20, 0x02, 0x01, 0x24, 0xc0, 0x02, 0x54, 0x1b, 0x90, + 0xa1, 0x00, 0x12, 0x60, 0x01, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x49, 0x18, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x86, 0x40, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x32, 0x22, + 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, + 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, + 0xa4, 0x4c, 0x10, 0x40, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, + 0x00, 0x76, 0x08, 0x41, 0x24, 0x41, 0x98, 0x89, 0x9a, 0x07, 0x7a, 0x90, + 0x87, 0x7a, 0x18, 0x07, 0x7a, 0x70, 0x83, 0x76, 0x28, 0x07, 0x7a, 0x08, + 0x07, 0x76, 0xd0, 0x03, 0x3d, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x79, 0x48, + 0x07, 0x7c, 0x40, 0x01, 0x19, 0x44, 0x28, 0x84, 0x62, 0x0c, 0x11, 0x84, + 0x31, 0x74, 0x06, 0x02, 0xe6, 0x08, 0xc0, 0x20, 0x05, 0xd4, 0x1c, 0x01, + 0x28, 0x0c, 0x22, 0x04, 0xc2, 0x30, 0x02, 0xa1, 0x8c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x13, 0xa8, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, + 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, + 0x87, 0x79, 0xc8, 0x03, 0x37, 0x80, 0x03, 0x37, 0x80, 0x83, 0x0d, 0xb7, + 0x51, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x7a, + 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x78, + 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, + 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, + 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, + 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, + 0xd0, 0x06, 0xe6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, + 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x76, + 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xf6, + 0x20, 0x07, 0x74, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, + 0xd0, 0x06, 0xf6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, + 0x30, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x40, 0x07, 0x78, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x60, 0x07, 0x74, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, + 0x90, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, + 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, + 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, + 0x60, 0x0f, 0x71, 0x90, 0x07, 0x72, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, + 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x75, + 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, + 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x75, 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, + 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, 0x72, 0xd0, 0x06, 0xf6, + 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, + 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xd0, 0x06, 0xee, + 0x80, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x43, + 0x18, 0x04, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x2c, 0x10, + 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, + 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x52, 0x25, 0x50, + 0x04, 0x23, 0x00, 0x05, 0x18, 0x50, 0x08, 0x65, 0x50, 0x20, 0x05, 0x41, + 0x6c, 0x04, 0x80, 0xd6, 0x58, 0x82, 0x33, 0x00, 0x00, 0x00, 0x79, 0x18, + 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x10, 0x97, 0x29, + 0xa2, 0x25, 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4, 0x37, 0xb7, 0x21, 0x86, + 0x22, 0x24, 0xc0, 0xa2, 0x50, 0xb9, 0x1b, 0x43, 0x0b, 0x93, 0xfb, 0x9a, + 0x4b, 0xd3, 0x2b, 0x1b, 0x62, 0x28, 0x41, 0x22, 0x28, 0x05, 0xe1, 0x20, + 0x08, 0x0e, 0x8e, 0xad, 0x0c, 0x84, 0x89, 0xc9, 0xaa, 0x09, 0xc4, 0xae, + 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x0d, 0x64, 0x26, 0x06, 0x06, 0x26, 0xc6, + 0xa5, 0x06, 0x06, 0x04, 0xa5, 0xad, 0x8c, 0x2e, 0x8c, 0xcd, 0xac, 0xac, + 0x65, 0x26, 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, 0xc6, 0x25, 0x26, 0x65, + 0x88, 0x90, 0x10, 0x43, 0x0c, 0x25, 0x50, 0x10, 0x65, 0x60, 0xd1, 0x54, + 0x46, 0x17, 0xc6, 0x36, 0x04, 0x49, 0x0e, 0x25, 0x50, 0x02, 0x65, 0xe0, + 0x16, 0x96, 0x26, 0xe7, 0x32, 0xf6, 0xd6, 0x06, 0x97, 0xc6, 0x56, 0xe6, + 0x42, 0x56, 0xe6, 0xf6, 0x26, 0xd7, 0x36, 0xf7, 0x45, 0x96, 0x36, 0x17, + 0x26, 0xc6, 0x56, 0x36, 0x44, 0x48, 0x12, 0x72, 0x61, 0x69, 0x72, 0x2e, + 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, 0x74, + 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, + 0x43, 0x84, 0x64, 0x21, 0x19, 0x84, 0xa5, 0xc9, 0xb9, 0x8c, 0xbd, 0xb5, + 0xc1, 0xa5, 0xb1, 0x95, 0xb9, 0x98, 0xc9, 0x85, 0xb5, 0x95, 0x89, 0xd5, + 0x99, 0x99, 0x95, 0xc9, 0x7d, 0x99, 0x95, 0xd1, 0x8d, 0xa1, 0x7d, 0x95, + 0xb9, 0x85, 0x89, 0xb1, 0x95, 0x0d, 0x11, 0x92, 0x86, 0x4c, 0x58, 0x9a, + 0x9c, 0x0b, 0xdc, 0xdb, 0x5c, 0x1a, 0x5d, 0xda, 0x9b, 0x1b, 0xa3, 0xb0, + 0x34, 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0x2f, + 0xb7, 0xb0, 0xb6, 0x32, 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x64, + 0xc2, 0xd2, 0xe4, 0x5c, 0xc2, 0xe4, 0xce, 0xbe, 0xdc, 0xc2, 0xda, 0xca, + 0x88, 0xc0, 0xbd, 0xcd, 0xa5, 0xd1, 0xa5, 0xbd, 0xb9, 0x0d, 0x51, 0x92, + 0x27, 0x81, 0x92, 0x28, 0x91, 0x92, 0x89, 0x51, 0x58, 0x9a, 0x9c, 0x8b, + 0x5d, 0x99, 0x1c, 0x5d, 0x19, 0xde, 0xd7, 0x5b, 0x1d, 0x1d, 0x5c, 0x1d, + 0x1d, 0xad, 0xb3, 0x32, 0xb7, 0x32, 0xb9, 0x30, 0xba, 0x32, 0x32, 0x94, + 0x9a, 0xb1, 0x37, 0xb6, 0x37, 0x39, 0x22, 0x3b, 0x9a, 0x2f, 0xb3, 0x14, + 0x16, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x43, 0x98, 0xa4, 0x4a, 0xac, 0x04, + 0x4a, 0xa2, 0x44, 0x4a, 0x2e, 0x66, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, + 0x74, 0x65, 0x64, 0x28, 0x38, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, + 0x64, 0x44, 0x76, 0x32, 0x5f, 0x66, 0x29, 0x34, 0xcc, 0xd8, 0xde, 0xc2, + 0xe8, 0x64, 0x88, 0xd0, 0x95, 0xe1, 0x8d, 0xbd, 0xbd, 0xc9, 0x91, 0x0d, + 0x61, 0x92, 0x2a, 0xc9, 0x12, 0x28, 0xd1, 0x12, 0x29, 0xd9, 0x86, 0x18, + 0x09, 0x95, 0x60, 0x09, 0x47, 0x28, 0x2c, 0x4d, 0xce, 0xc5, 0xae, 0x4c, + 0x8e, 0xae, 0x0c, 0xef, 0x2b, 0xcd, 0x0d, 0xae, 0x8e, 0x8e, 0x52, 0x58, + 0x9a, 0x9c, 0x0b, 0xdb, 0xdb, 0x58, 0x18, 0x5d, 0xda, 0x9b, 0xdb, 0x57, + 0x9a, 0x1b, 0x59, 0x19, 0x1e, 0xbd, 0xb3, 0x32, 0xb7, 0x32, 0xb9, 0x30, + 0xba, 0x32, 0x32, 0x94, 0xaf, 0xaf, 0xb0, 0x34, 0xb9, 0x2f, 0x38, 0xb6, + 0xb0, 0xb1, 0x32, 0xb4, 0x37, 0x36, 0xb2, 0x32, 0xb9, 0xaf, 0xaf, 0x94, + 0x21, 0x94, 0x32, 0x24, 0x5e, 0xf2, 0x29, 0x83, 0x12, 0x24, 0x60, 0x90, + 0x40, 0x89, 0x96, 0x48, 0xc9, 0x34, 0x84, 0x52, 0x82, 0xc4, 0x4b, 0x3e, + 0x25, 0x50, 0x82, 0x04, 0x0c, 0x12, 0x28, 0x89, 0x12, 0x29, 0xb9, 0x86, + 0x50, 0x8a, 0x90, 0x78, 0xc9, 0xa7, 0x08, 0x4a, 0x90, 0x80, 0x41, 0x02, + 0x25, 0x5a, 0x22, 0x25, 0x1b, 0x95, 0xb0, 0x34, 0x39, 0x17, 0xb1, 0x3a, + 0x33, 0xb3, 0x32, 0x39, 0x3e, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, + 0x66, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x44, 0xc2, 0xd2, 0xe4, + 0x5c, 0xe4, 0xca, 0xc2, 0xc8, 0x18, 0x85, 0xa5, 0xc9, 0xb9, 0x84, 0xc9, + 0x9d, 0x7d, 0xd1, 0xe5, 0xc1, 0x95, 0x7d, 0xcd, 0xa5, 0xe9, 0x95, 0xf1, + 0x0a, 0x4b, 0x93, 0x73, 0x09, 0x93, 0x3b, 0xfb, 0xa2, 0xcb, 0x83, 0x2b, + 0xfb, 0x0a, 0x63, 0x4b, 0x3b, 0x73, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x23, + 0x62, 0xc6, 0xf6, 0x16, 0x46, 0x47, 0x83, 0x47, 0x43, 0x05, 0x4e, 0xee, + 0x4d, 0xad, 0x6c, 0x8c, 0x2e, 0xed, 0xcd, 0x6d, 0x08, 0x18, 0x28, 0x46, + 0x42, 0x06, 0x49, 0x19, 0x28, 0x44, 0xf2, 0x29, 0x82, 0x12, 0x24, 0x66, + 0x90, 0x9c, 0x81, 0x42, 0x24, 0x68, 0xa0, 0x1c, 0x09, 0x94, 0xa4, 0x41, + 0x22, 0x25, 0x6a, 0xc0, 0x84, 0x4e, 0x2e, 0xcc, 0x6d, 0xce, 0xec, 0x4d, + 0xae, 0x6d, 0x08, 0x18, 0x28, 0x45, 0x42, 0x06, 0x49, 0x19, 0x28, 0x44, + 0xf2, 0x29, 0x86, 0x12, 0x24, 0x66, 0x90, 0x9c, 0x81, 0x42, 0x24, 0x68, + 0xa0, 0x1c, 0x09, 0x94, 0xa4, 0x41, 0x22, 0x25, 0x6c, 0x30, 0x44, 0x49, + 0xc2, 0x20, 0x11, 0x83, 0x64, 0x0c, 0x92, 0x35, 0x48, 0xda, 0x60, 0x88, + 0x81, 0x00, 0x49, 0x97, 0xb8, 0x01, 0x9f, 0xb7, 0x36, 0xb7, 0x34, 0xb8, + 0x37, 0xba, 0x32, 0x37, 0x3a, 0x90, 0x31, 0xb4, 0x30, 0x39, 0x3e, 0x53, + 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x2b, 0x2b, 0x20, 0x54, 0x42, + 0x41, 0x41, 0x43, 0x84, 0x24, 0x0e, 0x86, 0x18, 0x09, 0x1c, 0x24, 0x72, + 0xc0, 0x24, 0x43, 0x8c, 0x64, 0x0e, 0x92, 0x39, 0x60, 0x92, 0x11, 0x11, + 0x3b, 0xb0, 0x83, 0x3d, 0xb4, 0x83, 0x1b, 0xb4, 0xc3, 0x3b, 0x90, 0x43, + 0x3d, 0xb0, 0x43, 0x39, 0xb8, 0x81, 0x39, 0xb0, 0x43, 0x38, 0x9c, 0xc3, + 0x3c, 0x4c, 0x11, 0x82, 0x61, 0x84, 0xc2, 0x0e, 0xec, 0x60, 0x0f, 0xed, + 0xe0, 0x06, 0xe9, 0x40, 0x0e, 0xe5, 0xe0, 0x0e, 0xf4, 0x30, 0x25, 0x28, + 0x46, 0x2c, 0xe1, 0x90, 0x0e, 0xf2, 0xe0, 0x06, 0xf6, 0x50, 0x0e, 0xf2, + 0x30, 0x0f, 0xe9, 0xf0, 0x0e, 0xee, 0x30, 0x25, 0x30, 0x46, 0x50, 0xe1, + 0x90, 0x0e, 0xf2, 0xe0, 0x06, 0xec, 0x10, 0x0e, 0xee, 0x70, 0x0e, 0xf5, + 0x10, 0x0e, 0xe7, 0x50, 0x0e, 0xbf, 0x60, 0x0f, 0xe5, 0x20, 0x0f, 0xf3, + 0x90, 0x0e, 0xef, 0xe0, 0x0e, 0x53, 0x02, 0x64, 0xc4, 0x14, 0x0e, 0xe9, + 0x20, 0x0f, 0x6e, 0x30, 0x0e, 0xef, 0xd0, 0x0e, 0xf0, 0x90, 0x0e, 0xec, + 0x50, 0x0e, 0xbf, 0xf0, 0x0e, 0xf0, 0x40, 0x0f, 0xe9, 0xf0, 0x0e, 0xee, + 0x30, 0x0f, 0x53, 0x06, 0x85, 0x71, 0x46, 0x28, 0xe1, 0x90, 0x0e, 0xf2, + 0xe0, 0x06, 0xf6, 0x50, 0x0e, 0xf2, 0x40, 0x0f, 0xe5, 0x80, 0x0f, 0x53, + 0x82, 0x37, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x7b, 0x00, + 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, + 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, + 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, + 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, + 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, + 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, + 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, + 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, + 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, + 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, + 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, + 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, + 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, + 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, + 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, + 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, + 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, + 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, + 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, + 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, + 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, + 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, + 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, + 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, + 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, + 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, + 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, + 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, + 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, + 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, + 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, + 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, + 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, + 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, + 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, + 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, + 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, + 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, + 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, + 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, + 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, + 0x3c, 0x00, 0x71, 0x20, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0xf0, + 0xb0, 0x5d, 0xf9, 0x73, 0xce, 0x83, 0xfd, 0x15, 0x11, 0x4d, 0xc4, 0x05, + 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x13, 0x04, + 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0xe4, 0xc6, + 0x22, 0x86, 0x61, 0x18, 0xc6, 0x22, 0x04, 0x41, 0x10, 0xc6, 0x22, 0x82, + 0x20, 0x08, 0x88, 0x95, 0x40, 0x19, 0x14, 0x01, 0xb9, 0x11, 0x00, 0x1a, + 0x33, 0x00, 0x24, 0x66, 0x00, 0x28, 0xcc, 0x00, 0x00, 0x00, 0xe3, 0x11, + 0x4b, 0x74, 0x45, 0x14, 0x94, 0xf1, 0x08, 0x67, 0xca, 0x26, 0x0a, 0xca, + 0x20, 0xc3, 0x50, 0x20, 0x26, 0x04, 0xf2, 0x19, 0x8f, 0x90, 0xae, 0xae, + 0xa1, 0xa0, 0x0c, 0x32, 0x1c, 0x09, 0x64, 0x42, 0x20, 0x1f, 0x0b, 0x0a, + 0xf8, 0x8c, 0x47, 0x5c, 0x9c, 0x18, 0x40, 0x14, 0x94, 0x41, 0x06, 0xc6, + 0xb1, 0x4c, 0x08, 0xe4, 0x63, 0x45, 0x00, 0x9f, 0xf1, 0x08, 0x2e, 0x0c, + 0xce, 0xc0, 0xa2, 0xa0, 0x0c, 0x32, 0x44, 0x13, 0x67, 0x42, 0x20, 0x1f, + 0x2b, 0x02, 0xf8, 0x8c, 0x47, 0x80, 0x81, 0x19, 0xb0, 0x01, 0x47, 0x41, + 0x19, 0x64, 0x08, 0xb0, 0xcd, 0x82, 0x4a, 0x3e, 0x83, 0x0c, 0x83, 0x16, + 0x06, 0x16, 0x4c, 0xf2, 0xb1, 0x21, 0x80, 0xcf, 0x20, 0x83, 0xd1, 0x95, + 0x81, 0x05, 0x91, 0x7c, 0x6c, 0x08, 0xe0, 0x33, 0xc8, 0x90, 0x80, 0x41, + 0x1a, 0x58, 0xf0, 0xc8, 0xc7, 0x86, 0x00, 0x3e, 0xe3, 0x11, 0x6d, 0x30, + 0x07, 0x79, 0x80, 0x06, 0x14, 0x94, 0x41, 0x86, 0xa0, 0x0c, 0xd0, 0xc0, + 0x02, 0x31, 0x90, 0xcf, 0x20, 0xc3, 0x70, 0x06, 0x6e, 0x60, 0x01, 0x18, + 0xc8, 0x67, 0x90, 0xa1, 0x48, 0x83, 0x38, 0xb0, 0xa0, 0x93, 0xcf, 0x20, + 0xc3, 0xb1, 0x06, 0x74, 0x60, 0x81, 0x26, 0x9f, 0x41, 0x86, 0x3d, 0x70, + 0x03, 0x38, 0xb0, 0x2c, 0x90, 0xcf, 0x20, 0x43, 0x1f, 0xc0, 0x81, 0x1d, + 0x98, 0x13, 0xc8, 0xc7, 0x92, 0x01, 0x3e, 0x16, 0x30, 0xf0, 0xb1, 0x20, + 0x81, 0x8f, 0x05, 0x08, 0x7c, 0x2c, 0x28, 0xe0, 0x33, 0xdb, 0x80, 0x07, + 0x01, 0x30, 0xdb, 0x10, 0x90, 0x42, 0x30, 0xdb, 0x10, 0x90, 0x82, 0x90, + 0x41, 0x40, 0x0c, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x5b, 0x86, + 0x20, 0xa0, 0x83, 0x2d, 0xc3, 0x10, 0xd0, 0xc1, 0x96, 0xe1, 0x08, 0xe8, + 0x60, 0xcb, 0xc0, 0x04, 0x74, 0xb0, 0x65, 0x88, 0x02, 0x3a, 0xd8, 0x32, + 0x58, 0x01, 0x1d, 0x6c, 0x19, 0xc6, 0x20, 0xa0, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, + 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xe0, 0x08, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x35, 0x02, + 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, + 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, + 0x8b, 0x62, 0x80, 0x10, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0x84, 0x10, + 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, 0x44, 0x24, 0x48, 0x0a, + 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, 0x21, 0x72, 0x24, 0x07, + 0xc8, 0x08, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, + 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x1b, 0xc8, + 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x90, 0x00, 0x8a, 0x18, 0x87, + 0x77, 0x90, 0x07, 0x79, 0x28, 0x87, 0x71, 0xa0, 0x07, 0x76, 0xc8, 0x87, + 0x36, 0x90, 0x87, 0x77, 0xa8, 0x07, 0x77, 0x20, 0x87, 0x72, 0x20, 0x87, + 0x36, 0x20, 0x87, 0x74, 0xb0, 0x87, 0x74, 0x20, 0x87, 0x72, 0x68, 0x83, + 0x79, 0x88, 0x07, 0x79, 0xa0, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, + 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, + 0xa1, 0x1c, 0x00, 0x82, 0x1c, 0xd2, 0x61, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, + 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xc2, 0x21, 0x1d, 0xd8, 0xa1, 0x0d, 0xc6, + 0x21, 0x1c, 0xd8, 0x81, 0x1d, 0xe6, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, + 0x79, 0x28, 0x07, 0x80, 0x60, 0x87, 0x72, 0x98, 0x87, 0x79, 0x68, 0x03, + 0x78, 0x90, 0x87, 0x72, 0x18, 0x87, 0x74, 0x98, 0x87, 0x72, 0x68, 0x03, + 0x73, 0x80, 0x87, 0x76, 0x08, 0x07, 0x72, 0x00, 0xcc, 0x21, 0x1c, 0xd8, + 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, + 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, + 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, + 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x06, 0x77, 0x78, 0x87, + 0x36, 0x30, 0x07, 0x79, 0x08, 0x87, 0x76, 0x28, 0x87, 0x36, 0x80, 0x87, + 0x77, 0x48, 0x07, 0x77, 0xa0, 0x87, 0x72, 0x90, 0x87, 0x36, 0x28, 0x07, + 0x76, 0x48, 0x87, 0x76, 0x68, 0x03, 0x77, 0x78, 0x07, 0x77, 0x68, 0x03, + 0x76, 0x28, 0x87, 0x70, 0x30, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x83, + 0x74, 0x70, 0x07, 0x73, 0x98, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, + 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, + 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x40, 0x1d, 0xea, 0xa1, 0x1d, 0xe0, + 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x1e, 0x00, + 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, + 0x36, 0x70, 0x87, 0x70, 0x70, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, + 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, + 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xce, + 0xc1, 0x1d, 0xca, 0x81, 0x1c, 0xda, 0x40, 0x1f, 0xca, 0x41, 0x1e, 0xde, + 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, + 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, + 0x77, 0x68, 0x03, 0x7a, 0x90, 0x87, 0x70, 0x80, 0x07, 0x78, 0x48, 0x07, + 0x77, 0x38, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, + 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0x62, 0x1e, 0xe8, 0x21, 0x1c, 0xc6, + 0x61, 0x1d, 0xda, 0x00, 0x1e, 0xe4, 0xe1, 0x1d, 0xe8, 0xa1, 0x1c, 0xc6, + 0x81, 0x1e, 0xde, 0x41, 0x1e, 0xda, 0x40, 0x1c, 0xea, 0xc1, 0x1c, 0xcc, + 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xf4, 0xa1, 0x1c, 0x00, + 0x3c, 0x00, 0x88, 0x7a, 0x70, 0x87, 0x79, 0x08, 0x07, 0x73, 0x28, 0x87, + 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, + 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xea, 0x61, 0x1e, 0xca, + 0xa1, 0x0d, 0xe6, 0xe1, 0x1d, 0xcc, 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xd8, + 0xe1, 0x1d, 0xc2, 0x81, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, + 0x72, 0x00, 0x36, 0x10, 0x82, 0x00, 0x58, 0x00, 0x00, 0x00, 0x49, 0x18, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x13, 0x84, 0x40, 0x00, 0x89, 0x20, + 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x32, 0x22, 0x08, 0x09, 0x20, 0x64, + 0x85, 0x04, 0x13, 0x22, 0xa4, 0x84, 0x04, 0x13, 0x22, 0xe3, 0x84, 0xa1, + 0x90, 0x14, 0x12, 0x4c, 0x88, 0x8c, 0x0b, 0x84, 0x84, 0x4c, 0x10, 0x24, + 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, 0x00, 0x65, 0x08, 0x09, + 0x9a, 0x81, 0x80, 0x39, 0x02, 0x30, 0x48, 0x01, 0x1b, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x13, 0xa8, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, + 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, + 0x87, 0x79, 0xc8, 0x03, 0x37, 0x80, 0x03, 0x37, 0x80, 0x83, 0x0d, 0xb7, + 0x51, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x7a, + 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x78, + 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, + 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, + 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, + 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, + 0xd0, 0x06, 0xe6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, + 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x76, + 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xf6, + 0x20, 0x07, 0x74, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, + 0xd0, 0x06, 0xf6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, + 0x30, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x40, 0x07, 0x78, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x60, 0x07, 0x74, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, + 0x90, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, + 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, + 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, + 0x60, 0x0f, 0x71, 0x90, 0x07, 0x72, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, + 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x75, + 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, + 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x75, 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, + 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, 0x72, 0xd0, 0x06, 0xf6, + 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, + 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xd0, 0x06, 0xee, + 0x80, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x43, + 0x18, 0x02, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x2c, 0x10, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x0c, 0x19, 0x11, + 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0xb2, 0x12, 0x18, + 0x01, 0x28, 0x82, 0x42, 0x28, 0x08, 0xba, 0xb1, 0x04, 0x67, 0x00, 0x00, + 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x1a, 0x03, + 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4, + 0x37, 0xb7, 0x21, 0x86, 0x31, 0x14, 0xc0, 0x61, 0x50, 0xb9, 0x1b, 0x43, + 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x1b, 0x62, 0x18, 0x41, 0x21, + 0x18, 0x04, 0xe1, 0x20, 0x08, 0x0e, 0x8e, 0xad, 0x0c, 0x84, 0x89, 0xc9, + 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x0d, 0x64, 0x26, + 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, 0x06, 0x04, 0xa5, 0xad, 0x8c, 0x2e, + 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, + 0xc6, 0x25, 0x26, 0x65, 0x88, 0x50, 0x10, 0x43, 0x0c, 0x23, 0x30, 0x0a, + 0x43, 0x60, 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, 0x04, 0x29, 0x0e, 0x23, + 0x30, 0x02, 0x43, 0xe0, 0x16, 0x96, 0x26, 0xe7, 0x32, 0xf6, 0xd6, 0x06, + 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, 0x26, 0xd7, 0x36, 0xf7, + 0x45, 0x96, 0x36, 0x17, 0x26, 0xc6, 0x56, 0x36, 0x44, 0x28, 0x12, 0x72, + 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, + 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, 0x65, 0x6e, + 0x61, 0x62, 0x6c, 0x65, 0x43, 0x84, 0x62, 0x21, 0x19, 0x84, 0xa5, 0xc9, + 0xb9, 0x8c, 0xbd, 0xb5, 0xc1, 0xa5, 0xb1, 0x95, 0xb9, 0x98, 0xc9, 0x85, + 0xb5, 0x95, 0x89, 0xd5, 0x99, 0x99, 0x95, 0xc9, 0x7d, 0x99, 0x95, 0xd1, + 0x8d, 0xa1, 0x7d, 0x95, 0xb9, 0x85, 0x89, 0xb1, 0x95, 0x0d, 0x11, 0x8a, + 0x86, 0x51, 0x58, 0x9a, 0x9c, 0x8b, 0x5c, 0x99, 0x1b, 0x59, 0x99, 0xdc, + 0x17, 0x5d, 0x98, 0xdc, 0x59, 0x19, 0x1d, 0xa3, 0xb0, 0x34, 0x39, 0x97, + 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0x2f, 0xb7, 0xb0, 0xb6, + 0x32, 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x43, 0x90, 0xe2, 0x31, + 0x84, 0x02, 0x2a, 0xa2, 0x21, 0x42, 0x21, 0x51, 0x0a, 0x4b, 0x93, 0x73, + 0x31, 0x93, 0x0b, 0x3b, 0x6b, 0x2b, 0x73, 0xa3, 0xfb, 0x4a, 0x73, 0x83, + 0xab, 0xa3, 0x63, 0x76, 0x56, 0xe6, 0x56, 0x26, 0x17, 0x46, 0x57, 0x46, + 0x86, 0x82, 0x03, 0xf7, 0x36, 0x97, 0x46, 0x97, 0xf6, 0xe6, 0x46, 0x64, + 0x27, 0xf3, 0x65, 0x96, 0x42, 0x25, 0x2c, 0x4d, 0xce, 0x65, 0xac, 0xcc, + 0x8d, 0xae, 0x4c, 0x8e, 0x4f, 0x58, 0x9a, 0x9c, 0x0b, 0x5c, 0x99, 0xdc, + 0x1c, 0x5c, 0xd9, 0x18, 0x5d, 0x9a, 0x5d, 0x19, 0x0d, 0x33, 0xb6, 0xb7, + 0x30, 0x3a, 0x19, 0x32, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x44, 0xe0, 0xde, 0xe6, 0xd2, 0xe8, 0xd2, 0xde, + 0xdc, 0x86, 0x48, 0x86, 0x50, 0x50, 0x45, 0x55, 0x58, 0xc5, 0x55, 0x40, + 0x05, 0x56, 0x64, 0x85, 0x46, 0xeb, 0xac, 0xcc, 0xad, 0x4c, 0x2e, 0x8c, + 0xae, 0x8c, 0x0c, 0xa5, 0x66, 0xec, 0x8d, 0xed, 0x4d, 0x8e, 0xc8, 0x8e, + 0xe6, 0xcb, 0x2c, 0x85, 0xc5, 0xd8, 0x1b, 0xdb, 0x9b, 0xdc, 0x10, 0xc9, + 0x08, 0x0a, 0xaa, 0xe0, 0x0a, 0xab, 0xb8, 0x0a, 0xa8, 0x88, 0x8a, 0xac, + 0xe8, 0x86, 0x10, 0xc5, 0x56, 0x78, 0x43, 0x0c, 0x02, 0x28, 0xa6, 0xe2, + 0x1b, 0x11, 0xb1, 0x03, 0x3b, 0xd8, 0x43, 0x3b, 0xb8, 0x41, 0x3b, 0xbc, + 0x03, 0x39, 0xd4, 0x03, 0x3b, 0x94, 0x83, 0x1b, 0x98, 0x03, 0x3b, 0x84, + 0xc3, 0x39, 0xcc, 0xc3, 0x14, 0x21, 0x18, 0x46, 0x28, 0xec, 0xc0, 0x0e, + 0xf6, 0xd0, 0x0e, 0x6e, 0x90, 0x0e, 0xe4, 0x50, 0x0e, 0xee, 0x40, 0x0f, + 0x53, 0x82, 0x62, 0xc4, 0x12, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0x60, 0x0f, + 0xe5, 0x20, 0x0f, 0xf3, 0x90, 0x0e, 0xef, 0xe0, 0x0e, 0x53, 0x02, 0x63, + 0x04, 0x15, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0xc0, 0x0e, 0xe1, 0xe0, 0x0e, + 0xe7, 0x50, 0x0f, 0xe1, 0x70, 0x0e, 0xe5, 0xf0, 0x0b, 0xf6, 0x50, 0x0e, + 0xf2, 0x30, 0x0f, 0xe9, 0xf0, 0x0e, 0xee, 0x30, 0x25, 0x40, 0x46, 0x4c, + 0xe1, 0x90, 0x0e, 0xf2, 0xe0, 0x06, 0xe3, 0xf0, 0x0e, 0xed, 0x00, 0x0f, + 0xe9, 0xc0, 0x0e, 0xe5, 0xf0, 0x0b, 0xef, 0x00, 0x0f, 0xf4, 0x90, 0x0e, + 0xef, 0xe0, 0x0e, 0xf3, 0x30, 0x65, 0x50, 0x18, 0x67, 0x04, 0x13, 0x0e, + 0xe9, 0x20, 0x0f, 0x6e, 0x60, 0x0e, 0xf2, 0x10, 0x0e, 0xe7, 0xd0, 0x0e, + 0xe5, 0xe0, 0x0e, 0xf4, 0x30, 0x25, 0x00, 0x03, 0x00, 0x00, 0x79, 0x18, + 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, + 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, + 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, + 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, + 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, + 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, + 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, + 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, + 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, + 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, + 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, + 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, + 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, + 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, + 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, + 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, + 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, + 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, + 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, + 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, + 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, + 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, + 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, + 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, + 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, + 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, + 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, + 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, + 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, + 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, + 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, + 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, + 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, + 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, + 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, + 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, + 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, + 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, + 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, + 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, + 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, + 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, 0x00, 0x00, 0x05, 0x00, + 0x00, 0x00, 0x06, 0x20, 0xb1, 0x5d, 0xf9, 0xb3, 0xce, 0x82, 0x0c, 0x7f, + 0x11, 0x01, 0x06, 0x43, 0x34, 0x13, 0x00, 0x00, 0x00, 0x00, 0x61, 0x20, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x06, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, + 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x44, 0x0a, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x8e, 0x02, + 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, + 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, + 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, + 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, 0x44, 0x24, 0x48, 0x0a, + 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, 0x21, 0x72, 0x24, 0x07, + 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, + 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0x1b, 0xcc, + 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x60, 0x00, 0x09, 0xa8, 0x88, + 0x71, 0x78, 0x07, 0x79, 0x90, 0x87, 0x72, 0x18, 0x07, 0x7a, 0x60, 0x87, + 0x7c, 0x68, 0x03, 0x79, 0x78, 0x87, 0x7a, 0x70, 0x07, 0x72, 0x28, 0x07, + 0x72, 0x68, 0x03, 0x72, 0x48, 0x07, 0x7b, 0x48, 0x07, 0x72, 0x28, 0x87, + 0x36, 0x98, 0x87, 0x78, 0x90, 0x07, 0x7a, 0x68, 0x03, 0x73, 0x80, 0x87, + 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xcc, 0x21, 0x1c, 0xd8, + 0x61, 0x1e, 0xca, 0x01, 0x20, 0xc8, 0x21, 0x1d, 0xe6, 0x21, 0x1c, 0xc4, + 0x81, 0x1d, 0xca, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xd2, 0x81, 0x1d, 0xda, + 0x60, 0x1c, 0xc2, 0x81, 0x1d, 0xd8, 0x61, 0x1e, 0x00, 0x73, 0x08, 0x07, + 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x76, 0x28, 0x87, 0x79, 0x98, 0x87, + 0x36, 0x80, 0x07, 0x79, 0x28, 0x87, 0x71, 0x48, 0x87, 0x79, 0x28, 0x87, + 0x36, 0x30, 0x07, 0x78, 0x68, 0x87, 0x70, 0x20, 0x07, 0xc0, 0x1c, 0xc2, + 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xcc, + 0x41, 0x1e, 0xc2, 0xa1, 0x1d, 0xca, 0xa1, 0x0d, 0xe0, 0xe1, 0x1d, 0xd2, + 0xc1, 0x1d, 0xe8, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xca, 0x81, 0x1d, 0xd2, + 0xa1, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x60, 0x70, 0x87, + 0x77, 0x68, 0x03, 0x73, 0x90, 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, + 0x78, 0x78, 0x87, 0x74, 0x70, 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, + 0x72, 0x60, 0x87, 0x74, 0x68, 0x87, 0x36, 0x70, 0x87, 0x77, 0x70, 0x87, + 0x36, 0x60, 0x87, 0x72, 0x08, 0x07, 0x73, 0x00, 0x08, 0x77, 0x78, 0x87, + 0x36, 0x48, 0x07, 0x77, 0x30, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, + 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, + 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xd4, 0xa1, 0x1e, 0xda, + 0x01, 0x1e, 0xda, 0x80, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, 0xa1, 0x1c, 0xe6, + 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, + 0x77, 0x68, 0x03, 0x77, 0x08, 0x07, 0x77, 0x98, 0x87, 0x36, 0x30, 0x07, + 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, + 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x60, 0x1e, 0xd2, + 0xe1, 0x1c, 0xdc, 0xa1, 0x1c, 0xc8, 0xa1, 0x0d, 0xf4, 0xa1, 0x1c, 0xe4, + 0xe1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, + 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, + 0x77, 0x78, 0x87, 0x36, 0xa0, 0x07, 0x79, 0x08, 0x07, 0x78, 0x80, 0x87, + 0x74, 0x70, 0x87, 0x73, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, + 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xe6, 0x81, 0x1e, 0xc2, + 0x61, 0x1c, 0xd6, 0xa1, 0x0d, 0xe0, 0x41, 0x1e, 0xde, 0x81, 0x1e, 0xca, + 0x61, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, 0xa1, 0x0d, 0xc4, 0xa1, 0x1e, 0xcc, + 0xc1, 0x1c, 0xca, 0x41, 0x1e, 0xda, 0x60, 0x1e, 0xd2, 0x41, 0x1f, 0xca, + 0x01, 0xc0, 0x03, 0x80, 0xa8, 0x07, 0x77, 0x98, 0x87, 0x70, 0x30, 0x87, + 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, + 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xa2, 0x1e, 0xe6, + 0xa1, 0x1c, 0xda, 0x60, 0x1e, 0xde, 0xc1, 0x1c, 0xe8, 0xa1, 0x0d, 0xcc, + 0x81, 0x1d, 0xde, 0x21, 0x1c, 0xe8, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, + 0x79, 0x28, 0x07, 0x60, 0x83, 0x21, 0x10, 0xc0, 0x02, 0x54, 0x1b, 0x8c, + 0xa1, 0x00, 0x16, 0xa0, 0xda, 0x80, 0x10, 0xff, 0xff, 0xff, 0xff, 0x3f, + 0x00, 0x0c, 0x20, 0x01, 0xd5, 0x06, 0xa3, 0x08, 0x80, 0x05, 0xa8, 0x36, + 0x18, 0x86, 0x00, 0x2c, 0x40, 0x05, 0x49, 0x18, 0x00, 0x00, 0x03, 0x00, + 0x00, 0x00, 0x13, 0x86, 0x40, 0x18, 0x26, 0x0c, 0x44, 0x61, 0x00, 0x00, + 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x32, 0x22, + 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, + 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, + 0xa4, 0x4c, 0x10, 0x44, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, + 0x00, 0x47, 0x49, 0x53, 0x44, 0x09, 0x93, 0xff, 0x4f, 0xc4, 0x35, 0x51, + 0x11, 0xf1, 0xdb, 0xc3, 0x3f, 0x8d, 0x11, 0x00, 0x83, 0x08, 0x43, 0x70, + 0x91, 0x34, 0x45, 0x94, 0x30, 0xf9, 0xbf, 0x04, 0x30, 0xcf, 0x42, 0x44, + 0xff, 0x34, 0x46, 0x00, 0x0c, 0x22, 0x14, 0x42, 0x31, 0x42, 0x08, 0x82, + 0x18, 0x3a, 0x73, 0x04, 0xc1, 0x1c, 0x01, 0x18, 0x0c, 0x23, 0x08, 0x4a, + 0x41, 0x02, 0x31, 0x22, 0xad, 0x04, 0x88, 0x0d, 0x04, 0xa4, 0x80, 0x1a, + 0x01, 0x00, 0x13, 0xa8, 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, + 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, + 0x87, 0x79, 0xc8, 0x03, 0x37, 0x80, 0x03, 0x37, 0x80, 0x83, 0x0d, 0xb7, + 0x51, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x7a, + 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x78, + 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, + 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, + 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, + 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, + 0xd0, 0x06, 0xe6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, + 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x76, + 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xf6, + 0x20, 0x07, 0x74, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, + 0xd0, 0x06, 0xf6, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, + 0x30, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x40, 0x07, 0x78, 0xa0, 0x07, 0x76, + 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x60, 0x07, 0x74, + 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, + 0x90, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, + 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, + 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, + 0x60, 0x0f, 0x71, 0x90, 0x07, 0x72, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, + 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x75, + 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, + 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x75, 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, + 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, 0x72, 0xd0, 0x06, 0xf6, + 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, + 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xd0, 0x06, 0xee, + 0x80, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x43, + 0x18, 0x04, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x21, 0x4c, + 0x03, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x16, 0x08, 0x00, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, + 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x52, 0x25, 0x30, + 0x02, 0x50, 0x04, 0x85, 0x50, 0x10, 0x65, 0x40, 0x6f, 0x2c, 0xc1, 0x19, + 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0xca, 0x00, 0x00, 0x00, 0x1a, 0x03, + 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4, + 0x37, 0xb7, 0x21, 0x86, 0x42, 0x38, 0xc0, 0x83, 0x50, 0xb9, 0x1b, 0x43, + 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x1b, 0x62, 0x28, 0x82, 0x23, + 0x28, 0x05, 0xe1, 0x20, 0x08, 0x0e, 0x8e, 0xad, 0x0c, 0x84, 0x89, 0xc9, + 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x0d, 0x64, 0x26, + 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, 0x06, 0x04, 0xa5, 0xad, 0x8c, 0x2e, + 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, + 0xc6, 0x25, 0x26, 0x65, 0x88, 0xe0, 0x10, 0x43, 0x0c, 0x45, 0x50, 0x0c, + 0x65, 0x60, 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, 0x04, 0x71, 0x0e, 0x45, + 0x50, 0x04, 0x65, 0xe0, 0x16, 0x96, 0x26, 0xe7, 0x32, 0xf6, 0xd6, 0x06, + 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, 0x26, 0xd7, 0x36, 0xf7, + 0x45, 0x96, 0x36, 0x17, 0x26, 0xc6, 0x56, 0x36, 0x44, 0x70, 0x12, 0x72, + 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, + 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, 0x65, 0x6e, + 0x61, 0x62, 0x6c, 0x65, 0x43, 0x04, 0x67, 0x21, 0x19, 0x84, 0xa5, 0xc9, + 0xb9, 0x8c, 0xbd, 0xb5, 0xc1, 0xa5, 0xb1, 0x95, 0xb9, 0x98, 0xc9, 0x85, + 0xb5, 0x95, 0x89, 0xd5, 0x99, 0x99, 0x95, 0xc9, 0x7d, 0x99, 0x95, 0xd1, + 0x8d, 0xa1, 0x7d, 0x95, 0xb9, 0x85, 0x89, 0xb1, 0x95, 0x0d, 0x11, 0x9c, + 0x86, 0x51, 0x58, 0x9a, 0x9c, 0x8b, 0x5c, 0x99, 0x1b, 0x59, 0x99, 0xdc, + 0x17, 0x5d, 0x98, 0xdc, 0x59, 0x19, 0x1d, 0xa3, 0xb0, 0x34, 0x39, 0x97, + 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0x2f, 0xb7, 0xb0, 0xb6, + 0x32, 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x43, 0x10, 0xe7, 0x51, + 0x06, 0x07, 0x72, 0xa2, 0x21, 0x82, 0x23, 0x91, 0x09, 0x4b, 0x93, 0x73, + 0x81, 0x7b, 0x9b, 0x4b, 0xa3, 0x4b, 0x7b, 0x73, 0xa3, 0x12, 0x96, 0x26, + 0xe7, 0x32, 0x56, 0xe6, 0x46, 0x57, 0x26, 0x47, 0x29, 0x2c, 0x4d, 0xce, + 0xc5, 0xed, 0xed, 0x0b, 0xae, 0x4c, 0x6e, 0x0e, 0xae, 0x6c, 0x8c, 0x2e, + 0xcd, 0xae, 0x8c, 0x4c, 0x58, 0x9a, 0x9c, 0x4b, 0x98, 0xdc, 0xd9, 0x97, + 0x5b, 0x58, 0x5b, 0x19, 0x11, 0xb8, 0xb7, 0xb9, 0x34, 0xba, 0xb4, 0x37, + 0xb7, 0x21, 0x90, 0x32, 0x38, 0x94, 0x53, 0x39, 0x96, 0x03, 0x39, 0x91, + 0x73, 0x39, 0x18, 0xa5, 0xb0, 0x34, 0x39, 0x17, 0x33, 0xb9, 0xb0, 0xb3, + 0xb6, 0x32, 0x37, 0xba, 0xaf, 0x34, 0x37, 0xb8, 0x3a, 0x3a, 0x5a, 0x67, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x35, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x44, 0x76, 0x34, 0x5f, 0x66, 0x29, 0x7c, 0xc2, 0xd2, + 0xe4, 0x5c, 0xe0, 0xca, 0xe4, 0xe6, 0xe0, 0xca, 0xc6, 0xe8, 0xd2, 0xec, + 0xca, 0x58, 0x8c, 0xbd, 0xb1, 0xbd, 0xc9, 0x0d, 0x91, 0x14, 0xc1, 0xd1, + 0x9c, 0xcd, 0xa9, 0x1c, 0xce, 0x81, 0x9c, 0xc8, 0xb9, 0x9c, 0x8e, 0xd9, + 0x59, 0x99, 0x5b, 0x99, 0x5c, 0x18, 0x5d, 0x19, 0x19, 0x0a, 0x0e, 0x5d, + 0x19, 0xde, 0xd8, 0xdb, 0x9b, 0x1c, 0x19, 0x91, 0x9d, 0xcc, 0x97, 0x59, + 0x0a, 0x0d, 0x33, 0xb6, 0xb7, 0x30, 0x3a, 0x19, 0x22, 0x74, 0x65, 0x78, + 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x43, 0x24, 0x85, 0x70, 0x34, 0xe7, 0x73, + 0x2a, 0x87, 0x73, 0x20, 0x07, 0x0c, 0x9c, 0xcb, 0x09, 0x03, 0x2e, 0x61, + 0x69, 0x72, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x94, 0xc2, + 0xd2, 0xe4, 0x5c, 0xd8, 0xde, 0xc6, 0xc2, 0xe8, 0xd2, 0xde, 0xdc, 0xbe, + 0xd2, 0xdc, 0xc8, 0xca, 0xf0, 0xa8, 0x84, 0xa5, 0xc9, 0xb9, 0xcc, 0x85, + 0xb5, 0xc1, 0xb1, 0x95, 0x11, 0xa3, 0x2b, 0xc3, 0xa3, 0xab, 0x93, 0x2b, + 0x93, 0x21, 0xe3, 0x31, 0x63, 0x7b, 0x0b, 0xa3, 0x63, 0x01, 0x99, 0x0b, + 0x6b, 0x83, 0x63, 0x2b, 0xf3, 0xe1, 0x40, 0x57, 0x86, 0x37, 0x84, 0x52, + 0x0e, 0x67, 0x0c, 0x1c, 0x32, 0x50, 0x06, 0x45, 0x70, 0xca, 0xc0, 0x81, + 0x1c, 0x33, 0x70, 0x2e, 0xe7, 0x0c, 0xb8, 0x84, 0xa5, 0xc9, 0xb9, 0xcc, + 0x85, 0xb5, 0xc1, 0xb1, 0x95, 0xc9, 0xf1, 0x98, 0x0b, 0x6b, 0x83, 0x63, + 0x2b, 0x93, 0x63, 0x30, 0x37, 0x44, 0x52, 0x0a, 0x27, 0x0d, 0x1c, 0x32, + 0x50, 0x06, 0x45, 0x70, 0x20, 0x47, 0x0d, 0x9c, 0xcb, 0x59, 0x83, 0x21, + 0x8a, 0x93, 0x39, 0x9e, 0x23, 0x06, 0x0e, 0x1a, 0x38, 0x6c, 0x30, 0xc4, + 0x40, 0x00, 0x67, 0x72, 0xda, 0x60, 0x44, 0xc4, 0x0e, 0xec, 0x60, 0x0f, + 0xed, 0xe0, 0x06, 0xed, 0xf0, 0x0e, 0xe4, 0x50, 0x0f, 0xec, 0x50, 0x0e, + 0x6e, 0x60, 0x0e, 0xec, 0x10, 0x0e, 0xe7, 0x30, 0x0f, 0x53, 0x84, 0x60, + 0x18, 0xa1, 0xb0, 0x03, 0x3b, 0xd8, 0x43, 0x3b, 0xb8, 0x41, 0x3a, 0x90, + 0x43, 0x39, 0xb8, 0x03, 0x3d, 0x4c, 0x09, 0x8a, 0x11, 0x4b, 0x38, 0xa4, + 0x83, 0x3c, 0xb8, 0x81, 0x3d, 0x94, 0x83, 0x3c, 0xcc, 0x43, 0x3a, 0xbc, + 0x83, 0x3b, 0x4c, 0x09, 0x8c, 0x11, 0x54, 0x38, 0xa4, 0x83, 0x3c, 0xb8, + 0x01, 0x3b, 0x84, 0x83, 0x3b, 0x9c, 0x43, 0x3d, 0x84, 0xc3, 0x39, 0x94, + 0xc3, 0x2f, 0xd8, 0x43, 0x39, 0xc8, 0xc3, 0x3c, 0xa4, 0xc3, 0x3b, 0xb8, + 0xc3, 0x94, 0x00, 0x19, 0x31, 0x85, 0x43, 0x3a, 0xc8, 0x83, 0x1b, 0x8c, + 0xc3, 0x3b, 0xb4, 0x03, 0x3c, 0xa4, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, + 0x03, 0x3c, 0xd0, 0x43, 0x3a, 0xbc, 0x83, 0x3b, 0xcc, 0xc3, 0x94, 0x41, + 0x61, 0x9c, 0x11, 0x4c, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xc8, + 0x43, 0x38, 0x9c, 0x43, 0x3b, 0x94, 0x83, 0x3b, 0xd0, 0xc3, 0x94, 0xc0, + 0x0d, 0x00, 0x79, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, + 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, + 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, + 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, + 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, + 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, + 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, + 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, + 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, + 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, + 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, + 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, + 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, + 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, + 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, + 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, + 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, + 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, + 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, + 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, + 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, + 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, + 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, + 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, + 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, + 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, + 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, + 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, + 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, + 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, + 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, + 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, + 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, + 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, + 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, + 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, + 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, + 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, + 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, + 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, + 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, + 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, + 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x06, 0x10, 0xb1, 0x5d, 0xf9, 0x73, + 0xce, 0x83, 0xfd, 0x45, 0x04, 0x18, 0x0c, 0xd1, 0x4c, 0x16, 0xb0, 0x01, + 0x48, 0xe4, 0x4b, 0x00, 0xf3, 0x2c, 0xc4, 0x3f, 0x11, 0xd7, 0x44, 0x45, + 0xc4, 0x6f, 0x0f, 0x7e, 0x85, 0x17, 0xb7, 0x0d, 0x00, 0x00, 0x61, 0x20, + 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, + 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xb4, 0x46, 0x00, 0x28, 0xd5, 0xc0, + 0x08, 0x00, 0x81, 0x11, 0x00, 0x00, 0x23, 0x06, 0x8a, 0x10, 0x44, 0x46, + 0x71, 0x0c, 0x84, 0x10, 0x58, 0x90, 0xc8, 0x27, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, + 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xc8, 0x0c, + 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, + 0x00, 0x00, 0x2f, 0x03, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, + 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, + 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, + 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, + 0x44, 0x24, 0x48, 0x0a, 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, + 0x21, 0x72, 0x24, 0x07, 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, + 0xc6, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x8e, 0x00, + 0x00, 0x00, 0x1b, 0xcc, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x60, + 0x00, 0x09, 0xa8, 0x88, 0x71, 0x78, 0x07, 0x79, 0x90, 0x87, 0x72, 0x18, + 0x07, 0x7a, 0x60, 0x87, 0x7c, 0x68, 0x03, 0x79, 0x78, 0x87, 0x7a, 0x70, + 0x07, 0x72, 0x28, 0x07, 0x72, 0x68, 0x03, 0x72, 0x48, 0x07, 0x7b, 0x48, + 0x07, 0x72, 0x28, 0x87, 0x36, 0x98, 0x87, 0x78, 0x90, 0x07, 0x7a, 0x68, + 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, + 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xc8, 0x21, 0x1d, + 0xe6, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, + 0xd2, 0x81, 0x1d, 0xda, 0x60, 0x1c, 0xc2, 0x81, 0x1d, 0xd8, 0x61, 0x1e, + 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x76, 0x28, + 0x87, 0x79, 0x98, 0x87, 0x36, 0x80, 0x07, 0x79, 0x28, 0x87, 0x71, 0x48, + 0x87, 0x79, 0x28, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x87, 0x70, 0x20, + 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, + 0xde, 0xa1, 0x0d, 0xcc, 0x41, 0x1e, 0xc2, 0xa1, 0x1d, 0xca, 0xa1, 0x0d, + 0xe0, 0xe1, 0x1d, 0xd2, 0xc1, 0x1d, 0xe8, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, + 0xca, 0x81, 0x1d, 0xd2, 0xa1, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, + 0x07, 0x60, 0x70, 0x87, 0x77, 0x68, 0x03, 0x73, 0x90, 0x87, 0x70, 0x68, + 0x87, 0x72, 0x68, 0x03, 0x78, 0x78, 0x87, 0x74, 0x70, 0x07, 0x7a, 0x28, + 0x07, 0x79, 0x68, 0x83, 0x72, 0x60, 0x87, 0x74, 0x68, 0x87, 0x36, 0x70, + 0x87, 0x77, 0x70, 0x87, 0x36, 0x60, 0x87, 0x72, 0x08, 0x07, 0x73, 0x00, + 0x08, 0x77, 0x78, 0x87, 0x36, 0x48, 0x07, 0x77, 0x30, 0x87, 0x79, 0x68, + 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, + 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, + 0xd4, 0xa1, 0x1e, 0xda, 0x01, 0x1e, 0xda, 0x80, 0x1e, 0xc2, 0x41, 0x1c, + 0xd8, 0xa1, 0x1c, 0xe6, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, + 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x77, 0x08, 0x07, 0x77, 0x98, + 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, + 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, + 0xda, 0x60, 0x1e, 0xd2, 0xe1, 0x1c, 0xdc, 0xa1, 0x1c, 0xc8, 0xa1, 0x0d, + 0xf4, 0xa1, 0x1c, 0xe4, 0xe1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, + 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, + 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0xa0, 0x07, 0x79, 0x08, + 0x07, 0x78, 0x80, 0x87, 0x74, 0x70, 0x87, 0x73, 0x68, 0x83, 0x76, 0x08, + 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, + 0xe6, 0x81, 0x1e, 0xc2, 0x61, 0x1c, 0xd6, 0xa1, 0x0d, 0xe0, 0x41, 0x1e, + 0xde, 0x81, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, 0xa1, 0x0d, + 0xc4, 0xa1, 0x1e, 0xcc, 0xc1, 0x1c, 0xca, 0x41, 0x1e, 0xda, 0x60, 0x1e, + 0xd2, 0x41, 0x1f, 0xca, 0x01, 0xc0, 0x03, 0x80, 0xa8, 0x07, 0x77, 0x98, + 0x87, 0x70, 0x30, 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, + 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, + 0x00, 0xa2, 0x1e, 0xe6, 0xa1, 0x1c, 0xda, 0x60, 0x1e, 0xde, 0xc1, 0x1c, + 0xe8, 0xa1, 0x0d, 0xcc, 0x81, 0x1d, 0xde, 0x21, 0x1c, 0xe8, 0x01, 0x30, + 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x60, 0x03, 0x22, 0x10, 0x40, + 0x02, 0x2c, 0x40, 0xb5, 0xc1, 0x18, 0x0a, 0x60, 0x01, 0xaa, 0x0d, 0x06, + 0x71, 0x00, 0x0b, 0x50, 0x6d, 0x30, 0x8a, 0xff, 0xff, 0xff, 0xff, 0x1f, + 0x00, 0x09, 0xa0, 0x36, 0x20, 0xc6, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, + 0x03, 0x48, 0x40, 0xb5, 0xc1, 0x38, 0x02, 0x60, 0x01, 0xaa, 0x0d, 0x06, + 0x22, 0x00, 0x0b, 0x50, 0x01, 0x00, 0x49, 0x18, 0x00, 0x00, 0x03, 0x00, + 0x00, 0x00, 0x13, 0x88, 0x40, 0x18, 0x88, 0x09, 0x41, 0x31, 0x61, 0x30, + 0x0e, 0x04, 0x89, 0x20, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x32, 0x22, + 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, + 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, + 0xa4, 0x4c, 0x10, 0x78, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, + 0x00, 0xc3, 0x08, 0x03, 0x70, 0x90, 0x34, 0x45, 0x94, 0x30, 0xf9, 0xb2, + 0xfb, 0x76, 0x84, 0xe0, 0x0c, 0x04, 0x22, 0xc6, 0x18, 0x63, 0x10, 0x81, + 0x10, 0x8e, 0x92, 0xa6, 0x88, 0x12, 0x26, 0xff, 0x9f, 0x88, 0x6b, 0xa2, + 0x22, 0xe2, 0xb7, 0x87, 0x7f, 0x1a, 0x23, 0x00, 0x06, 0x11, 0x8c, 0xe0, + 0x34, 0x69, 0x8a, 0x28, 0x61, 0xf2, 0xff, 0x89, 0xb8, 0x26, 0x2a, 0x22, + 0x7e, 0x7b, 0xf8, 0x81, 0x28, 0x02, 0xb0, 0x7f, 0x1a, 0x23, 0x00, 0x06, + 0x11, 0x90, 0xe0, 0x22, 0x69, 0x8a, 0x28, 0x61, 0xf2, 0x7f, 0x09, 0x60, + 0x9e, 0x85, 0x88, 0xfe, 0x69, 0x8c, 0x00, 0x18, 0x44, 0x50, 0x84, 0x82, + 0x84, 0x10, 0x44, 0x39, 0x69, 0x11, 0x2b, 0x03, 0x18, 0x83, 0xdc, 0x1c, + 0x01, 0x18, 0xcc, 0x11, 0x04, 0xc3, 0x08, 0x02, 0x54, 0x92, 0x90, 0x96, + 0x80, 0x51, 0x46, 0x40, 0xb3, 0x20, 0xe1, 0x2c, 0x11, 0x65, 0x04, 0x54, + 0x07, 0x02, 0x52, 0x00, 0x0e, 0x23, 0x0c, 0xd0, 0x20, 0x42, 0x20, 0xcc, + 0x11, 0x80, 0xc2, 0x20, 0xc2, 0x20, 0x8c, 0x00, 0x00, 0x00, 0x13, 0xa8, + 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, + 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, 0x87, 0x79, 0xc8, 0x03, + 0x37, 0x80, 0x03, 0x37, 0x80, 0x83, 0x0d, 0xb7, 0x51, 0x0e, 0x6d, 0x00, + 0x0f, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, + 0x07, 0x74, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, + 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, + 0x06, 0xe9, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x10, + 0x07, 0x76, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, + 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x60, 0x07, 0x74, 0xa0, + 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, + 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, + 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, + 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x74, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, + 0x06, 0xf6, 0x40, 0x07, 0x78, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, + 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x90, 0x07, 0x76, 0xa0, + 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, + 0x06, 0xf6, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, + 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x90, + 0x07, 0x72, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, + 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, + 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, + 0x0f, 0x75, 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, 0x72, 0xa0, + 0x07, 0x75, 0x10, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x70, 0x20, + 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, + 0x07, 0x70, 0x20, 0x07, 0x74, 0xd0, 0x06, 0xee, 0x80, 0x07, 0x7a, 0x10, + 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x43, 0x98, 0x06, 0x00, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x21, 0xcc, 0x03, 0x04, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0x10, 0x86, 0x02, 0x02, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x60, 0x08, 0x63, 0x01, 0x01, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x90, 0x05, 0x02, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x32, 0x1e, + 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, + 0x43, 0x82, 0x25, 0x30, 0x02, 0x50, 0x20, 0x45, 0x50, 0x08, 0x05, 0x18, + 0x50, 0x10, 0x65, 0x50, 0x40, 0x05, 0x56, 0x0a, 0xc5, 0x40, 0x78, 0x2c, + 0xc1, 0x19, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x13, 0x01, + 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, 0x10, 0xab, + 0x32, 0xb9, 0xb9, 0xb4, 0x37, 0xb7, 0x21, 0x06, 0x74, 0x5c, 0x00, 0x06, + 0x51, 0xb9, 0x1b, 0x43, 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x1b, + 0x62, 0x40, 0xc4, 0x25, 0x40, 0x08, 0xe1, 0x20, 0x08, 0x0e, 0x8e, 0xad, + 0x0c, 0x84, 0x89, 0xc9, 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, 0x2e, 0xed, + 0xcd, 0x0d, 0x64, 0x26, 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, 0x06, 0x04, + 0xa5, 0xad, 0x8c, 0x2e, 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, 0x06, 0x06, + 0x26, 0xc6, 0xa5, 0x06, 0xc6, 0x25, 0x26, 0x65, 0x88, 0x70, 0x11, 0x43, + 0x0c, 0x88, 0x80, 0x14, 0xa8, 0x60, 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, + 0x04, 0xb9, 0x0e, 0x88, 0x80, 0x08, 0xa8, 0xe0, 0x16, 0x96, 0x26, 0xe7, + 0x32, 0xf6, 0xd6, 0x06, 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, + 0x26, 0xd7, 0x36, 0xf7, 0x45, 0x96, 0x36, 0x17, 0x26, 0xc6, 0x56, 0x36, + 0x44, 0xb8, 0x12, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, + 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, + 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x84, 0x6b, 0x21, + 0x19, 0x84, 0xa5, 0xc9, 0xb9, 0x8c, 0xbd, 0xb5, 0xc1, 0xa5, 0xb1, 0x95, + 0xb9, 0x98, 0xc9, 0x85, 0xb5, 0x95, 0x89, 0xd5, 0x99, 0x99, 0x95, 0xc9, + 0x7d, 0x99, 0x95, 0xd1, 0x8d, 0xa1, 0x7d, 0x95, 0xb9, 0x85, 0x89, 0xb1, + 0x95, 0x0d, 0x11, 0xae, 0x86, 0x51, 0x58, 0x9a, 0x9c, 0x8b, 0x5c, 0x99, + 0x1b, 0x59, 0x99, 0xdc, 0x17, 0x5d, 0x98, 0xdc, 0x59, 0x19, 0x1d, 0xa3, + 0xb0, 0x34, 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, + 0x2f, 0xb7, 0xb0, 0xb6, 0x32, 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, + 0x43, 0x90, 0xeb, 0x81, 0x8a, 0x0b, 0xba, 0xa2, 0x21, 0xc2, 0x25, 0x91, + 0x09, 0x4b, 0x93, 0x73, 0x81, 0x7b, 0x9b, 0x4b, 0xa3, 0x4b, 0x7b, 0x73, + 0xa3, 0x12, 0x96, 0x26, 0xe7, 0x32, 0x56, 0xe6, 0x46, 0x57, 0x26, 0x47, + 0x29, 0x2c, 0x4d, 0xce, 0xc5, 0xed, 0xed, 0x0b, 0xae, 0x4c, 0x6e, 0x0e, + 0xae, 0x6c, 0x8c, 0x2e, 0xcd, 0xae, 0x8c, 0x4c, 0x58, 0x9a, 0x9c, 0x4b, + 0x98, 0xdc, 0xd9, 0x97, 0x5b, 0x58, 0x5b, 0x19, 0x11, 0xb8, 0xb7, 0xb9, + 0x34, 0xba, 0xb4, 0x37, 0xb7, 0x21, 0x10, 0x54, 0x5c, 0xd4, 0x55, 0x5d, + 0xd6, 0x05, 0x5d, 0xd1, 0x75, 0x5d, 0x18, 0xa5, 0xb0, 0x34, 0x39, 0x17, + 0x33, 0xb9, 0xb0, 0xb3, 0xb6, 0x32, 0x37, 0xba, 0xaf, 0x34, 0x37, 0xb8, + 0x3a, 0x3a, 0x5a, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, + 0x28, 0x35, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x44, 0x76, 0x34, 0x5f, 0x66, + 0x29, 0x7c, 0xc2, 0xd2, 0xe4, 0x5c, 0xe0, 0xca, 0xe4, 0xe6, 0xe0, 0xca, + 0xc6, 0xe8, 0xd2, 0xec, 0xca, 0x58, 0x8c, 0xbd, 0xb1, 0xbd, 0xc9, 0x0d, + 0x91, 0x20, 0xe2, 0xd2, 0xae, 0xed, 0xaa, 0x2e, 0xee, 0x82, 0xae, 0xe8, + 0xba, 0xae, 0x8e, 0xd9, 0x59, 0x99, 0x5b, 0x99, 0x5c, 0x18, 0x5d, 0x19, + 0x19, 0x0a, 0x0e, 0x5d, 0x19, 0xde, 0xd8, 0xdb, 0x9b, 0x1c, 0x19, 0x91, + 0x9d, 0xcc, 0x97, 0x59, 0x0a, 0x0d, 0x33, 0xb6, 0xb7, 0x30, 0x3a, 0x19, + 0x22, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x43, 0x24, 0xe8, + 0xb8, 0xb4, 0xeb, 0xbb, 0xaa, 0x8b, 0xbb, 0xa0, 0x0b, 0x0c, 0xae, 0xeb, + 0x0a, 0x03, 0x2a, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, + 0x72, 0x7c, 0xc2, 0xd2, 0xe4, 0x5c, 0xc4, 0xea, 0xcc, 0xcc, 0xca, 0xe4, + 0xbe, 0xe6, 0xd2, 0xf4, 0xca, 0x28, 0x85, 0xa5, 0xc9, 0xb9, 0xb0, 0xbd, + 0x8d, 0x85, 0xd1, 0xa5, 0xbd, 0xb9, 0x7d, 0xa5, 0xb9, 0x91, 0x95, 0xe1, + 0x11, 0x09, 0x4b, 0x93, 0x73, 0x91, 0x2b, 0x0b, 0x23, 0x23, 0x15, 0x96, + 0x26, 0xe7, 0x32, 0x47, 0x27, 0x57, 0x37, 0x46, 0xf7, 0x45, 0x97, 0x07, + 0x57, 0xf6, 0x95, 0xe6, 0x66, 0xf6, 0x46, 0xc3, 0x8c, 0xed, 0x2d, 0x8c, + 0x6e, 0x86, 0xc6, 0x9b, 0x99, 0xd9, 0x5c, 0x19, 0x1d, 0x0d, 0xa9, 0xb1, + 0xb7, 0x32, 0x33, 0x33, 0x1a, 0x47, 0x63, 0x6f, 0x65, 0x66, 0x66, 0x34, + 0x84, 0xc6, 0xde, 0xca, 0xcc, 0xcc, 0x86, 0xa0, 0x01, 0x54, 0x40, 0x06, + 0x54, 0x5c, 0x68, 0x70, 0xa5, 0x01, 0x64, 0x40, 0x06, 0x54, 0x5c, 0x68, + 0x70, 0xa9, 0x01, 0xc4, 0x40, 0x06, 0x54, 0x5c, 0x68, 0x70, 0xad, 0x01, + 0xd4, 0x40, 0x06, 0x54, 0x5c, 0x68, 0x70, 0xb1, 0x01, 0xa3, 0xb0, 0x34, + 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0xaf, 0xb9, + 0x34, 0xbd, 0x32, 0x5e, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x5f, 0x73, + 0x69, 0x7a, 0x65, 0x4c, 0xb2, 0xaa, 0xac, 0x88, 0xca, 0xc6, 0xde, 0xc8, + 0xca, 0x68, 0x90, 0x95, 0x8d, 0xbd, 0x91, 0x95, 0x0d, 0x21, 0x03, 0x68, + 0xb9, 0xc6, 0xe0, 0x22, 0x03, 0x28, 0xb9, 0xca, 0x00, 0x22, 0x20, 0xe2, + 0x32, 0x83, 0xeb, 0x0c, 0xae, 0x36, 0xb8, 0xdc, 0x00, 0x4a, 0xae, 0x37, + 0x80, 0x8c, 0x0b, 0xba, 0xe0, 0xe0, 0xba, 0xae, 0x38, 0xe0, 0x12, 0x96, + 0x26, 0xe7, 0x42, 0x57, 0x86, 0x47, 0x57, 0x27, 0x57, 0x46, 0x25, 0x2c, + 0x4d, 0xce, 0x65, 0x2e, 0xac, 0x0d, 0x8e, 0xad, 0x8c, 0x18, 0x5d, 0x19, + 0x1e, 0x5d, 0x9d, 0x5c, 0x99, 0x0c, 0x19, 0x8f, 0x19, 0xdb, 0x5b, 0x18, + 0x1d, 0x0b, 0xc8, 0x5c, 0x58, 0x1b, 0x1c, 0x5b, 0x99, 0x0f, 0x09, 0xba, + 0x32, 0xbc, 0xac, 0x21, 0x14, 0x84, 0x5c, 0x73, 0x70, 0x95, 0x01, 0x54, + 0x40, 0xc4, 0x45, 0x07, 0x17, 0x74, 0xd5, 0xc1, 0x75, 0x5d, 0x76, 0x40, + 0x8f, 0xae, 0x0c, 0x8f, 0xae, 0x4e, 0xae, 0x4c, 0x86, 0xec, 0x2b, 0x4c, + 0x4e, 0x2e, 0x2c, 0x8f, 0xc7, 0x8c, 0xed, 0x2d, 0x8c, 0x8e, 0x05, 0x64, + 0x2e, 0xac, 0x0d, 0x8e, 0xad, 0xcc, 0x87, 0x05, 0x5d, 0x19, 0x5e, 0x95, + 0xd5, 0x10, 0x0a, 0x72, 0xae, 0x39, 0xb8, 0xca, 0x00, 0x22, 0x20, 0xe2, + 0xa2, 0x83, 0x0b, 0xba, 0xf0, 0xe0, 0xba, 0xae, 0x3c, 0xe0, 0x12, 0x96, + 0x26, 0xe7, 0x32, 0x17, 0xd6, 0x06, 0xc7, 0x56, 0x26, 0xc7, 0x63, 0x2e, + 0xac, 0x0d, 0x8e, 0xad, 0x4c, 0x8e, 0xc1, 0xdc, 0x10, 0x09, 0x7a, 0xae, + 0x3d, 0xb8, 0xca, 0x00, 0x2a, 0x20, 0xe2, 0x82, 0x2e, 0x3e, 0xb8, 0xae, + 0xab, 0x0f, 0x86, 0x38, 0x57, 0x76, 0x79, 0x97, 0x18, 0x5c, 0x72, 0x70, + 0xdd, 0xc1, 0xa5, 0x07, 0x97, 0x1f, 0x0c, 0x31, 0x1a, 0xe0, 0x9a, 0xae, + 0x3f, 0x18, 0x11, 0xb1, 0x03, 0x3b, 0xd8, 0x43, 0x3b, 0xb8, 0x41, 0x3b, + 0xbc, 0x03, 0x39, 0xd4, 0x03, 0x3b, 0x94, 0x83, 0x1b, 0x98, 0x03, 0x3b, + 0x84, 0xc3, 0x39, 0xcc, 0xc3, 0x14, 0x21, 0x18, 0x46, 0x28, 0xec, 0xc0, + 0x0e, 0xf6, 0xd0, 0x0e, 0x6e, 0x90, 0x0e, 0xe4, 0x50, 0x0e, 0xee, 0x40, + 0x0f, 0x53, 0x82, 0x62, 0xc4, 0x12, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0x60, + 0x0f, 0xe5, 0x20, 0x0f, 0xf3, 0x90, 0x0e, 0xef, 0xe0, 0x0e, 0x53, 0x02, + 0x63, 0x04, 0x15, 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0xc0, 0x0e, 0xe1, 0xe0, + 0x0e, 0xe7, 0x50, 0x0f, 0xe1, 0x70, 0x0e, 0xe5, 0xf0, 0x0b, 0xf6, 0x50, + 0x0e, 0xf2, 0x30, 0x0f, 0xe9, 0xf0, 0x0e, 0xee, 0x30, 0x25, 0x40, 0x46, + 0x4c, 0xe1, 0x90, 0x0e, 0xf2, 0xe0, 0x06, 0xe3, 0xf0, 0x0e, 0xed, 0x00, + 0x0f, 0xe9, 0xc0, 0x0e, 0xe5, 0xf0, 0x0b, 0xef, 0x00, 0x0f, 0xf4, 0x90, + 0x0e, 0xef, 0xe0, 0x0e, 0xf3, 0x30, 0x65, 0x50, 0x18, 0x67, 0x04, 0x13, + 0x0e, 0xe9, 0x20, 0x0f, 0x6e, 0x60, 0x0e, 0xf2, 0x10, 0x0e, 0xe7, 0xd0, + 0x0e, 0xe5, 0xe0, 0x0e, 0xf4, 0x30, 0x25, 0x00, 0x05, 0x00, 0x79, 0x18, + 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, + 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, + 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, + 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, + 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, + 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, + 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, + 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, + 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, + 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, + 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, + 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, + 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, + 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, + 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, + 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, + 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, + 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, + 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, + 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, + 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, + 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, + 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, + 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, + 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, + 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, + 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, + 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, + 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, + 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, + 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, + 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, + 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, + 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, + 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, + 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, + 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, + 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, + 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, + 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, + 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, + 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, 0x00, 0x00, 0x14, 0x00, + 0x00, 0x00, 0x26, 0x10, 0x06, 0x00, 0x12, 0xf9, 0x12, 0xc0, 0x3c, 0x0b, + 0xf1, 0x4f, 0xc4, 0x35, 0x51, 0x11, 0xf1, 0xdb, 0xc3, 0x0f, 0x44, 0x11, + 0x80, 0xf9, 0x15, 0x5e, 0xdc, 0xb6, 0x05, 0x34, 0x00, 0x12, 0xf9, 0x83, + 0x33, 0xf9, 0xd5, 0x5d, 0xdc, 0xb6, 0x0d, 0x6c, 0x00, 0x12, 0xf9, 0x12, + 0xc0, 0x3c, 0x0b, 0xf1, 0x4f, 0xc4, 0x35, 0x51, 0x11, 0xf1, 0xdb, 0x83, + 0x5f, 0xe1, 0xc5, 0x6d, 0x1b, 0x00, 0xc4, 0x76, 0xe5, 0x2f, 0xbb, 0xef, + 0x5f, 0x44, 0x80, 0xc1, 0x10, 0xcd, 0x04, 0x00, 0x00, 0x00, 0x61, 0x20, + 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, + 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xb4, 0x47, 0x00, 0x28, 0xcf, 0x31, + 0x14, 0x5d, 0x37, 0xd6, 0x00, 0x04, 0x02, 0xc9, 0x11, 0x00, 0x8a, 0x23, + 0x00, 0x04, 0x67, 0x00, 0x28, 0xd6, 0x00, 0x85, 0x39, 0x08, 0x31, 0x10, + 0x03, 0x31, 0x08, 0x83, 0x19, 0x00, 0x02, 0x63, 0x04, 0x20, 0x08, 0x82, + 0xf8, 0x37, 0x03, 0x30, 0x02, 0x00, 0x23, 0x06, 0xca, 0x10, 0x84, 0xc1, + 0xd3, 0x44, 0x46, 0x82, 0x04, 0x83, 0x0c, 0x41, 0xc1, 0x8c, 0x18, 0x2c, + 0x43, 0x40, 0x06, 0xd0, 0x33, 0x85, 0x01, 0xb2, 0x28, 0xc3, 0x18, 0x42, + 0x20, 0x06, 0x73, 0x0c, 0x43, 0x40, 0x06, 0x23, 0x06, 0xcb, 0x10, 0x9c, + 0xc1, 0x24, 0x59, 0x65, 0xb0, 0x38, 0x8d, 0x31, 0x86, 0x10, 0x94, 0xc1, + 0x1c, 0xc3, 0x10, 0x90, 0xc1, 0x61, 0x7a, 0x29, 0x28, 0x83, 0x0c, 0x81, + 0x43, 0x19, 0x11, 0xc0, 0x67, 0xbc, 0x81, 0xc3, 0xd8, 0xe0, 0x02, 0xbd, + 0x14, 0x94, 0x41, 0x86, 0x60, 0xca, 0x46, 0x0c, 0x0a, 0x21, 0x98, 0x83, + 0x22, 0x18, 0x6f, 0x08, 0x83, 0xce, 0x0d, 0x2e, 0xd0, 0x4b, 0x41, 0x19, + 0x64, 0x08, 0x30, 0x6f, 0xc4, 0xa0, 0x10, 0x02, 0x3c, 0x50, 0x82, 0xf1, + 0x06, 0x33, 0x10, 0x83, 0x37, 0xb8, 0x40, 0x2f, 0x05, 0x65, 0x90, 0x21, + 0xe8, 0xc6, 0x60, 0xc4, 0xa0, 0x10, 0x82, 0x3e, 0x78, 0x82, 0x39, 0x06, + 0x30, 0x58, 0xf4, 0x60, 0x8e, 0x21, 0x38, 0xf8, 0x60, 0x8e, 0x21, 0x18, + 0xf4, 0xc0, 0x02, 0x38, 0x90, 0x4f, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, + 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x5c, 0x0c, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, 0x00, 0x00, 0x14, 0x03, + 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, + 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, + 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, + 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, + 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, 0x44, 0x24, 0x48, 0x0a, + 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, 0x21, 0x72, 0x24, 0x07, + 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, 0xc6, 0xf0, 0x01, 0x00, + 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x1b, 0xcc, + 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x60, 0x00, 0x09, 0xa8, 0x88, + 0x71, 0x78, 0x07, 0x79, 0x90, 0x87, 0x72, 0x18, 0x07, 0x7a, 0x60, 0x87, + 0x7c, 0x68, 0x03, 0x79, 0x78, 0x87, 0x7a, 0x70, 0x07, 0x72, 0x28, 0x07, + 0x72, 0x68, 0x03, 0x72, 0x48, 0x07, 0x7b, 0x48, 0x07, 0x72, 0x28, 0x87, + 0x36, 0x98, 0x87, 0x78, 0x90, 0x07, 0x7a, 0x68, 0x03, 0x73, 0x80, 0x87, + 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xcc, 0x21, 0x1c, 0xd8, + 0x61, 0x1e, 0xca, 0x01, 0x20, 0xc8, 0x21, 0x1d, 0xe6, 0x21, 0x1c, 0xc4, + 0x81, 0x1d, 0xca, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xd2, 0x81, 0x1d, 0xda, + 0x60, 0x1c, 0xc2, 0x81, 0x1d, 0xd8, 0x61, 0x1e, 0x00, 0x73, 0x08, 0x07, + 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x76, 0x28, 0x87, 0x79, 0x98, 0x87, + 0x36, 0x80, 0x07, 0x79, 0x28, 0x87, 0x71, 0x48, 0x87, 0x79, 0x28, 0x87, + 0x36, 0x30, 0x07, 0x78, 0x68, 0x87, 0x70, 0x20, 0x07, 0xc0, 0x1c, 0xc2, + 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xcc, + 0x41, 0x1e, 0xc2, 0xa1, 0x1d, 0xca, 0xa1, 0x0d, 0xe0, 0xe1, 0x1d, 0xd2, + 0xc1, 0x1d, 0xe8, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xca, 0x81, 0x1d, 0xd2, + 0xa1, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x60, 0x70, 0x87, + 0x77, 0x68, 0x03, 0x73, 0x90, 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, + 0x78, 0x78, 0x87, 0x74, 0x70, 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, + 0x72, 0x60, 0x87, 0x74, 0x68, 0x87, 0x36, 0x70, 0x87, 0x77, 0x70, 0x87, + 0x36, 0x60, 0x87, 0x72, 0x08, 0x07, 0x73, 0x00, 0x08, 0x77, 0x78, 0x87, + 0x36, 0x48, 0x07, 0x77, 0x30, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, + 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, + 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xd4, 0xa1, 0x1e, 0xda, + 0x01, 0x1e, 0xda, 0x80, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, 0xa1, 0x1c, 0xe6, + 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, + 0x77, 0x68, 0x03, 0x77, 0x08, 0x07, 0x77, 0x98, 0x87, 0x36, 0x30, 0x07, + 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, + 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0x60, 0x1e, 0xd2, + 0xe1, 0x1c, 0xdc, 0xa1, 0x1c, 0xc8, 0xa1, 0x0d, 0xf4, 0xa1, 0x1c, 0xe4, + 0xe1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, + 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, + 0x77, 0x78, 0x87, 0x36, 0xa0, 0x07, 0x79, 0x08, 0x07, 0x78, 0x80, 0x87, + 0x74, 0x70, 0x87, 0x73, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, + 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xe6, 0x81, 0x1e, 0xc2, + 0x61, 0x1c, 0xd6, 0xa1, 0x0d, 0xe0, 0x41, 0x1e, 0xde, 0x81, 0x1e, 0xca, + 0x61, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, 0xa1, 0x0d, 0xc4, 0xa1, 0x1e, 0xcc, + 0xc1, 0x1c, 0xca, 0x41, 0x1e, 0xda, 0x60, 0x1e, 0xd2, 0x41, 0x1f, 0xca, + 0x01, 0xc0, 0x03, 0x80, 0xa8, 0x07, 0x77, 0x98, 0x87, 0x70, 0x30, 0x87, + 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, + 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xa2, 0x1e, 0xe6, + 0xa1, 0x1c, 0xda, 0x60, 0x1e, 0xde, 0xc1, 0x1c, 0xe8, 0xa1, 0x0d, 0xcc, + 0x81, 0x1d, 0xde, 0x21, 0x1c, 0xe8, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, + 0x79, 0x28, 0x07, 0x60, 0x03, 0x22, 0x10, 0x40, 0x02, 0x2c, 0x40, 0xb5, + 0xc1, 0x18, 0x0a, 0x60, 0x01, 0xaa, 0x0d, 0x06, 0x61, 0x00, 0x0b, 0x50, + 0x6d, 0x30, 0x8a, 0x03, 0x58, 0x80, 0x6a, 0x83, 0x61, 0xfc, 0xff, 0xff, + 0xff, 0xff, 0x00, 0x48, 0x00, 0xb5, 0x01, 0x39, 0xfe, 0xff, 0xff, 0xff, + 0x7f, 0x00, 0x18, 0x40, 0x02, 0xaa, 0x0d, 0x06, 0x12, 0x00, 0x0b, 0x50, + 0x6d, 0x30, 0x12, 0x01, 0x58, 0x80, 0x0a, 0x00, 0x00, 0x00, 0x49, 0x18, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x13, 0x8a, 0x40, 0x18, 0x88, 0x62, + 0x42, 0x60, 0x4c, 0x18, 0x0e, 0x24, 0x01, 0x00, 0x00, 0x00, 0x89, 0x20, + 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, + 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, + 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x68, + 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, 0x00, 0xc3, 0x08, 0x03, + 0x70, 0x90, 0x34, 0x45, 0x94, 0x30, 0xf9, 0xb2, 0xfb, 0x76, 0x84, 0xe0, + 0x0c, 0x04, 0x22, 0xc6, 0x18, 0x63, 0x10, 0x81, 0x10, 0x8e, 0x92, 0xa6, + 0x88, 0x12, 0x26, 0xff, 0x9f, 0x88, 0x6b, 0xa2, 0x22, 0xe2, 0xb7, 0x87, + 0x7f, 0x1a, 0x23, 0x00, 0x06, 0x11, 0x8c, 0xe0, 0x22, 0x69, 0x8a, 0x28, + 0x61, 0xf2, 0x7f, 0x09, 0x60, 0x9e, 0x85, 0x88, 0xfe, 0x69, 0x8c, 0x00, + 0x18, 0x44, 0x40, 0x84, 0x82, 0x84, 0x10, 0x44, 0x39, 0x27, 0x91, 0x2a, + 0x03, 0x18, 0x83, 0xd8, 0x1c, 0x41, 0x30, 0x47, 0x00, 0x06, 0xc3, 0x08, + 0xc2, 0x53, 0x90, 0x70, 0x92, 0x70, 0xd0, 0x01, 0x8a, 0x03, 0x01, 0x29, + 0xf0, 0x86, 0x11, 0x86, 0x67, 0x10, 0x21, 0x10, 0xe6, 0x08, 0x40, 0x61, + 0x10, 0x61, 0x10, 0x46, 0x00, 0x00, 0x13, 0xa8, 0x70, 0x48, 0x07, 0x79, + 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, 0x78, 0x60, 0x87, 0x72, + 0x68, 0x83, 0x74, 0x78, 0x87, 0x79, 0xc8, 0x03, 0x37, 0x80, 0x03, 0x37, + 0x80, 0x83, 0x0d, 0xb7, 0x51, 0x0e, 0x6d, 0x00, 0x0f, 0x7a, 0x60, 0x07, + 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, + 0xe9, 0x10, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, 0x07, 0x6d, 0x90, 0x0e, + 0x78, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, 0x06, 0xe9, 0x10, 0x07, + 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, + 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, + 0x72, 0xd0, 0x06, 0xe9, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, + 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x30, 0x07, 0x72, 0xa0, 0x07, + 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe6, 0x60, 0x07, + 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, + 0xf6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x10, 0x07, + 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x74, 0xa0, 0x07, 0x73, 0x20, 0x07, + 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x30, 0x07, 0x72, 0xa0, 0x07, + 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x40, 0x07, + 0x78, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, + 0xf6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, + 0x74, 0xd0, 0x06, 0xf6, 0x90, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x20, 0x07, + 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, 0x06, 0xf6, 0x10, 0x07, + 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, + 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x90, 0x07, 0x72, 0xa0, 0x07, + 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xd0, 0x06, + 0xf6, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, + 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, 0x0f, 0x75, 0x10, 0x07, + 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, + 0x72, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x70, 0x20, 0x07, 0x74, 0xa0, 0x07, + 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, 0x07, 0x70, 0x20, 0x07, + 0x74, 0xd0, 0x06, 0xee, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x76, 0xa0, 0x07, + 0x73, 0x20, 0x07, 0x43, 0x98, 0x05, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x21, 0x4c, 0x03, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0x10, 0x46, 0x02, 0x02, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x0b, 0x04, 0x0b, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x14, 0x19, 0x11, + 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x7a, 0x25, 0x30, + 0x02, 0x50, 0x20, 0x45, 0x50, 0x08, 0x05, 0x18, 0x50, 0x10, 0x65, 0x50, + 0x40, 0x05, 0x56, 0x0a, 0xc5, 0x40, 0x74, 0x2c, 0xc1, 0x19, 0x00, 0x00, + 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x1a, 0x03, + 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, 0x10, 0xab, 0x32, 0xb9, 0xb9, 0xb4, + 0x37, 0xb7, 0x21, 0xc6, 0x63, 0x4c, 0x00, 0xf5, 0x50, 0xb9, 0x1b, 0x43, + 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x1b, 0x62, 0x3c, 0xc3, 0x24, + 0x3c, 0x07, 0xe1, 0x20, 0x08, 0x0e, 0x8e, 0xad, 0x0c, 0x84, 0x89, 0xc9, + 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, 0x2e, 0xed, 0xcd, 0x0d, 0x64, 0x26, + 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, 0x06, 0x04, 0xa5, 0xad, 0x8c, 0x2e, + 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, + 0xc6, 0x25, 0x26, 0x65, 0x88, 0x30, 0x11, 0x43, 0x8c, 0x67, 0x78, 0x92, + 0x87, 0x60, 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, 0x04, 0x99, 0x8e, 0x67, + 0x78, 0x86, 0x87, 0xe0, 0x16, 0x96, 0x26, 0xe7, 0x32, 0xf6, 0xd6, 0x06, + 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, 0x26, 0xd7, 0x36, 0xf7, + 0x45, 0x96, 0x36, 0x17, 0x26, 0xc6, 0x56, 0x36, 0x44, 0x98, 0x12, 0x72, + 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, + 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, 0x65, 0x6e, + 0x61, 0x62, 0x6c, 0x65, 0x43, 0x84, 0x69, 0x21, 0x19, 0x84, 0xa5, 0xc9, + 0xb9, 0x8c, 0xbd, 0xb5, 0xc1, 0xa5, 0xb1, 0x95, 0xb9, 0x98, 0xc9, 0x85, + 0xb5, 0x95, 0x89, 0xd5, 0x99, 0x99, 0x95, 0xc9, 0x7d, 0x99, 0x95, 0xd1, + 0x8d, 0xa1, 0x7d, 0x95, 0xb9, 0x85, 0x89, 0xb1, 0x95, 0x0d, 0x11, 0xa6, + 0x86, 0x51, 0x58, 0x9a, 0x9c, 0x8b, 0x5c, 0x99, 0x1b, 0x59, 0x99, 0xdc, + 0x17, 0x5d, 0x98, 0xdc, 0x59, 0x19, 0x1d, 0xa3, 0xb0, 0x34, 0x39, 0x97, + 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0x2f, 0xb7, 0xb0, 0xb6, + 0x32, 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x43, 0x90, 0xe9, 0x79, + 0x88, 0x09, 0x9a, 0xa2, 0x21, 0xc2, 0x24, 0x91, 0x09, 0x4b, 0x93, 0x73, + 0x81, 0x7b, 0x9b, 0x4b, 0xa3, 0x4b, 0x7b, 0x73, 0xa3, 0x12, 0x96, 0x26, + 0xe7, 0x32, 0x56, 0xe6, 0x46, 0x57, 0x26, 0x47, 0x29, 0x2c, 0x4d, 0xce, + 0xc5, 0xed, 0xed, 0x0b, 0xae, 0x4c, 0x6e, 0x0e, 0xae, 0x6c, 0x8c, 0x2e, + 0xcd, 0xae, 0x8c, 0x4c, 0x58, 0x9a, 0x9c, 0x4b, 0x98, 0xdc, 0xd9, 0x97, + 0x5b, 0x58, 0x5b, 0x19, 0x11, 0xb8, 0xb7, 0xb9, 0x34, 0xba, 0xb4, 0x37, + 0xb7, 0x21, 0xd0, 0x43, 0x4c, 0xd4, 0x54, 0x4d, 0xd6, 0x04, 0x4d, 0xd1, + 0x74, 0x4d, 0x18, 0xa5, 0xb0, 0x34, 0x39, 0x17, 0x33, 0xb9, 0xb0, 0xb3, + 0xb6, 0x32, 0x37, 0xba, 0xaf, 0x34, 0x37, 0xb8, 0x3a, 0x3a, 0x5a, 0x67, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x35, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x44, 0x76, 0x34, 0x5f, 0x66, 0x29, 0x7c, 0xc2, 0xd2, + 0xe4, 0x5c, 0xe0, 0xca, 0xe4, 0xe6, 0xe0, 0xca, 0xc6, 0xe8, 0xd2, 0xec, + 0xca, 0x58, 0x8c, 0xbd, 0xb1, 0xbd, 0xc9, 0x0d, 0x91, 0x9e, 0x61, 0xd2, + 0xa6, 0x6d, 0xaa, 0x26, 0x6e, 0x82, 0xa6, 0x68, 0xba, 0xa6, 0x8e, 0xd9, + 0x59, 0x99, 0x5b, 0x99, 0x5c, 0x18, 0x5d, 0x19, 0x19, 0x0a, 0x0e, 0x5d, + 0x19, 0xde, 0xd8, 0xdb, 0x9b, 0x1c, 0x19, 0x91, 0x9d, 0xcc, 0x97, 0x59, + 0x0a, 0x0d, 0x33, 0xb6, 0xb7, 0x30, 0x3a, 0x19, 0x22, 0x74, 0x65, 0x78, + 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x43, 0xa4, 0xc7, 0x98, 0xb4, 0xe9, 0x9b, + 0xaa, 0x89, 0x9b, 0xa0, 0x09, 0x0c, 0xa6, 0x6b, 0x0a, 0x03, 0x2a, 0x61, + 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x7c, 0xc2, 0xd2, + 0xe4, 0x5c, 0xc4, 0xea, 0xcc, 0xcc, 0xca, 0xe4, 0xbe, 0xe6, 0xd2, 0xf4, + 0xca, 0x28, 0x85, 0xa5, 0xc9, 0xb9, 0xb0, 0xbd, 0x8d, 0x85, 0xd1, 0xa5, + 0xbd, 0xb9, 0x7d, 0xa5, 0xb9, 0x91, 0x95, 0xe1, 0x11, 0x09, 0x4b, 0x93, + 0x73, 0x91, 0x2b, 0x0b, 0x23, 0x23, 0x15, 0x96, 0x26, 0xe7, 0x32, 0x47, + 0x27, 0x57, 0x37, 0x46, 0xf7, 0x45, 0x97, 0x07, 0x57, 0xf6, 0x95, 0xe6, + 0x66, 0xf6, 0x46, 0xc3, 0x8c, 0xed, 0x2d, 0x8c, 0x6e, 0x86, 0xc6, 0x9b, + 0x99, 0xd9, 0x5c, 0x19, 0x1d, 0x0d, 0xa9, 0xb1, 0xb7, 0x32, 0x33, 0x33, + 0x1a, 0x47, 0x63, 0x6f, 0x65, 0x66, 0x66, 0x34, 0x84, 0xc6, 0xde, 0xca, + 0xcc, 0xcc, 0x86, 0xa0, 0xc1, 0x43, 0x3c, 0xc5, 0x43, 0x4c, 0x68, 0x30, + 0xa5, 0xc1, 0x53, 0x3c, 0xc5, 0x43, 0x4c, 0x68, 0x30, 0xa9, 0xc1, 0xb3, + 0x3c, 0xc5, 0x43, 0x4c, 0x68, 0x30, 0xad, 0xc1, 0xc3, 0x3c, 0xc5, 0x43, + 0x4c, 0x68, 0x30, 0xb1, 0x01, 0xa3, 0xb0, 0x34, 0x39, 0x97, 0x30, 0xb9, + 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0xaf, 0xb9, 0x34, 0xbd, 0x32, 0x5e, + 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x4c, + 0xb2, 0xaa, 0xac, 0x88, 0xca, 0xc6, 0xde, 0xc8, 0xca, 0x68, 0x90, 0x95, + 0x8d, 0xbd, 0x91, 0x95, 0x0d, 0x21, 0x83, 0x47, 0x99, 0xc6, 0x60, 0x22, + 0x83, 0x07, 0x99, 0xca, 0xe0, 0x19, 0x9e, 0x61, 0x32, 0x83, 0xe9, 0x0c, + 0xa6, 0x36, 0x98, 0xdc, 0xe0, 0x41, 0xa6, 0x37, 0x78, 0x8a, 0x09, 0x9a, + 0xe0, 0x60, 0xba, 0xa6, 0x38, 0xe0, 0x12, 0x96, 0x26, 0xe7, 0x42, 0x57, + 0x86, 0x47, 0x57, 0x27, 0x57, 0x46, 0x25, 0x2c, 0x4d, 0xce, 0x65, 0x2e, + 0xac, 0x0d, 0x8e, 0xad, 0x8c, 0x18, 0x5d, 0x19, 0x1e, 0x5d, 0x9d, 0x5c, + 0x99, 0x0c, 0x19, 0x8f, 0x19, 0xdb, 0x5b, 0x18, 0x1d, 0x0b, 0xc8, 0x5c, + 0x58, 0x1b, 0x1c, 0x5b, 0x99, 0x0f, 0x09, 0xba, 0x32, 0xbc, 0xac, 0x21, + 0xd4, 0x73, 0x4c, 0x73, 0x30, 0x95, 0xc1, 0x43, 0x3c, 0xc3, 0x44, 0x07, + 0x13, 0x34, 0xd5, 0xc1, 0x74, 0x4d, 0x76, 0xc0, 0x82, 0xae, 0x0c, 0xaf, + 0xca, 0x6a, 0x08, 0xf5, 0x34, 0xd3, 0x1c, 0x4c, 0x65, 0xf0, 0x0c, 0xcf, + 0x30, 0xd1, 0xc1, 0x04, 0x4d, 0x75, 0x30, 0x5d, 0x13, 0x1e, 0x70, 0x09, + 0x4b, 0x93, 0x73, 0x99, 0x0b, 0x6b, 0x83, 0x63, 0x2b, 0x93, 0xe3, 0x31, + 0x17, 0xd6, 0x06, 0xc7, 0x56, 0x26, 0xc7, 0x60, 0x6e, 0x88, 0xf4, 0x38, + 0x93, 0x1e, 0x4c, 0x65, 0xf0, 0x10, 0xcf, 0x30, 0x41, 0xd3, 0x1e, 0x4c, + 0xd7, 0xc4, 0x07, 0x43, 0x9c, 0x29, 0x9b, 0xbc, 0x49, 0x0c, 0x26, 0x39, + 0x98, 0xee, 0x60, 0xca, 0x83, 0xa9, 0x0f, 0x86, 0x18, 0x0b, 0x30, 0x4d, + 0x93, 0x1f, 0x8c, 0x88, 0xd8, 0x81, 0x1d, 0xec, 0xa1, 0x1d, 0xdc, 0xa0, + 0x1d, 0xde, 0x81, 0x1c, 0xea, 0x81, 0x1d, 0xca, 0xc1, 0x0d, 0xcc, 0x81, + 0x1d, 0xc2, 0xe1, 0x1c, 0xe6, 0x61, 0x8a, 0x10, 0x0c, 0x23, 0x14, 0x76, + 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x48, 0x07, 0x72, 0x28, 0x07, 0x77, + 0xa0, 0x87, 0x29, 0x41, 0x31, 0x62, 0x09, 0x87, 0x74, 0x90, 0x07, 0x37, + 0xb0, 0x87, 0x72, 0x90, 0x87, 0x79, 0x48, 0x87, 0x77, 0x70, 0x87, 0x29, + 0x81, 0x31, 0x82, 0x0a, 0x87, 0x74, 0x90, 0x07, 0x37, 0x60, 0x87, 0x70, + 0x70, 0x87, 0x73, 0xa8, 0x87, 0x70, 0x38, 0x87, 0x72, 0xf8, 0x05, 0x7b, + 0x28, 0x07, 0x79, 0x98, 0x87, 0x74, 0x78, 0x07, 0x77, 0x98, 0x12, 0x20, + 0x23, 0xa6, 0x70, 0x48, 0x07, 0x79, 0x70, 0x83, 0x71, 0x78, 0x87, 0x76, + 0x80, 0x87, 0x74, 0x60, 0x87, 0x72, 0xf8, 0x85, 0x77, 0x80, 0x07, 0x7a, + 0x48, 0x87, 0x77, 0x70, 0x87, 0x79, 0x98, 0x32, 0x28, 0x8c, 0x33, 0x82, + 0x09, 0x87, 0x74, 0x90, 0x07, 0x37, 0x30, 0x07, 0x79, 0x08, 0x87, 0x73, + 0x68, 0x87, 0x72, 0x70, 0x07, 0x7a, 0x98, 0x12, 0xfc, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, + 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, + 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, + 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, + 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, + 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, + 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, + 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, + 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, + 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, + 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, + 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, + 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, + 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, + 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, + 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, + 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, + 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, + 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, + 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, + 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, + 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, + 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, + 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, + 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, + 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, + 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, + 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, + 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, + 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, + 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, + 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, + 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, + 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, + 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, + 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, + 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, + 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, + 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, + 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, + 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, + 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x71, 0x20, + 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x16, 0xd0, 0x00, 0x48, 0xe4, 0x0f, + 0xce, 0xe4, 0x57, 0x77, 0x71, 0xdb, 0x26, 0xb0, 0x01, 0x48, 0xe4, 0x4b, + 0x00, 0xf3, 0x2c, 0xc4, 0x3f, 0x11, 0xd7, 0x44, 0x45, 0xc4, 0x6f, 0x0f, + 0x7e, 0x85, 0x17, 0xb7, 0x6d, 0x00, 0x11, 0xdb, 0x95, 0xff, 0xf9, 0xd6, + 0xf6, 0x5f, 0x44, 0x80, 0xc1, 0x10, 0xcd, 0x04, 0x00, 0x00, 0x61, 0x20, + 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, + 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x74, 0x47, 0x00, 0xa8, 0x8e, 0x35, + 0x00, 0x03, 0x31, 0xc7, 0x40, 0x0c, 0xde, 0x1c, 0x03, 0xe1, 0x79, 0x63, + 0x0d, 0x40, 0x20, 0x90, 0xab, 0x81, 0x11, 0x00, 0x7a, 0x33, 0x00, 0x04, + 0x47, 0x00, 0x28, 0xcc, 0x41, 0x90, 0x01, 0x19, 0x90, 0x81, 0x18, 0xcc, + 0x00, 0x10, 0x18, 0x23, 0x00, 0x41, 0x10, 0xc4, 0xbf, 0x11, 0x80, 0x19, + 0x00, 0x00, 0x23, 0x06, 0xca, 0x10, 0x8c, 0x41, 0xf4, 0x4c, 0x89, 0x81, + 0x08, 0x83, 0x0c, 0x41, 0xc1, 0x8c, 0x18, 0x28, 0x43, 0x50, 0x06, 0x52, + 0x54, 0x2d, 0x88, 0x42, 0x0c, 0x32, 0x04, 0xc7, 0x33, 0xc8, 0x30, 0x04, + 0xd1, 0x5d, 0x76, 0x29, 0x28, 0x83, 0x0c, 0xc1, 0x12, 0x19, 0x11, 0xc0, + 0x67, 0xbc, 0x61, 0xbb, 0xd6, 0xe0, 0x02, 0xbb, 0x14, 0x94, 0x41, 0x86, + 0x00, 0xb2, 0x46, 0x0c, 0x0a, 0x21, 0x88, 0x83, 0x22, 0x18, 0x6f, 0x00, + 0x03, 0xae, 0x0d, 0x2e, 0xb0, 0x4b, 0x41, 0x19, 0x64, 0x08, 0xaa, 0x6d, + 0xc4, 0xa0, 0x10, 0x02, 0x3b, 0x50, 0x82, 0xf1, 0x86, 0x32, 0x08, 0x03, + 0x37, 0xb8, 0xc0, 0x2e, 0x05, 0x65, 0x90, 0x21, 0xd0, 0xc0, 0x60, 0xc4, + 0xa0, 0x10, 0x82, 0x3d, 0x78, 0x82, 0x39, 0x86, 0x6e, 0xc9, 0x83, 0x39, + 0x86, 0xe0, 0xd8, 0x83, 0x39, 0x86, 0x60, 0xc8, 0x03, 0x0b, 0xde, 0x40, + 0x3e, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, + 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x68, 0x0c, + 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x21, 0x0c, + 0x00, 0x00, 0x17, 0x03, 0x00, 0x00, 0x0b, 0x82, 0x20, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, + 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, + 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, + 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x49, 0x0a, 0x32, + 0x44, 0x24, 0x48, 0x0a, 0x90, 0x21, 0x23, 0xc4, 0x52, 0x80, 0x0c, 0x19, + 0x21, 0x72, 0x24, 0x07, 0xc8, 0x48, 0x11, 0x62, 0xa8, 0xa0, 0xa8, 0x40, + 0xc6, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x51, 0x18, 0x00, 0x00, 0x90, 0x00, + 0x00, 0x00, 0x1b, 0xcc, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x60, + 0x00, 0x09, 0xa8, 0x88, 0x71, 0x78, 0x07, 0x79, 0x90, 0x87, 0x72, 0x18, + 0x07, 0x7a, 0x60, 0x87, 0x7c, 0x68, 0x03, 0x79, 0x78, 0x87, 0x7a, 0x70, + 0x07, 0x72, 0x28, 0x07, 0x72, 0x68, 0x03, 0x72, 0x48, 0x07, 0x7b, 0x48, + 0x07, 0x72, 0x28, 0x87, 0x36, 0x98, 0x87, 0x78, 0x90, 0x07, 0x7a, 0x68, + 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, + 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xc8, 0x21, 0x1d, + 0xe6, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, + 0xd2, 0x81, 0x1d, 0xda, 0x60, 0x1c, 0xc2, 0x81, 0x1d, 0xd8, 0x61, 0x1e, + 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x76, 0x28, + 0x87, 0x79, 0x98, 0x87, 0x36, 0x80, 0x07, 0x79, 0x28, 0x87, 0x71, 0x48, + 0x87, 0x79, 0x28, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x87, 0x70, 0x20, + 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, + 0xde, 0xa1, 0x0d, 0xcc, 0x41, 0x1e, 0xc2, 0xa1, 0x1d, 0xca, 0xa1, 0x0d, + 0xe0, 0xe1, 0x1d, 0xd2, 0xc1, 0x1d, 0xe8, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, + 0xca, 0x81, 0x1d, 0xd2, 0xa1, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, + 0x07, 0x60, 0x70, 0x87, 0x77, 0x68, 0x03, 0x73, 0x90, 0x87, 0x70, 0x68, + 0x87, 0x72, 0x68, 0x03, 0x78, 0x78, 0x87, 0x74, 0x70, 0x07, 0x7a, 0x28, + 0x07, 0x79, 0x68, 0x83, 0x72, 0x60, 0x87, 0x74, 0x68, 0x87, 0x36, 0x70, + 0x87, 0x77, 0x70, 0x87, 0x36, 0x60, 0x87, 0x72, 0x08, 0x07, 0x73, 0x00, + 0x08, 0x77, 0x78, 0x87, 0x36, 0x48, 0x07, 0x77, 0x30, 0x87, 0x79, 0x68, + 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, + 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, + 0xd4, 0xa1, 0x1e, 0xda, 0x01, 0x1e, 0xda, 0x80, 0x1e, 0xc2, 0x41, 0x1c, + 0xd8, 0xa1, 0x1c, 0xe6, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, + 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x77, 0x08, 0x07, 0x77, 0x98, + 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, + 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, + 0xda, 0x60, 0x1e, 0xd2, 0xe1, 0x1c, 0xdc, 0xa1, 0x1c, 0xc8, 0xa1, 0x0d, + 0xf4, 0xa1, 0x1c, 0xe4, 0xe1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, + 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, + 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0xa0, 0x07, 0x79, 0x08, + 0x07, 0x78, 0x80, 0x87, 0x74, 0x70, 0x87, 0x73, 0x68, 0x83, 0x76, 0x08, + 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, + 0xe6, 0x81, 0x1e, 0xc2, 0x61, 0x1c, 0xd6, 0xa1, 0x0d, 0xe0, 0x41, 0x1e, + 0xde, 0x81, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, 0xa1, 0x0d, + 0xc4, 0xa1, 0x1e, 0xcc, 0xc1, 0x1c, 0xca, 0x41, 0x1e, 0xda, 0x60, 0x1e, + 0xd2, 0x41, 0x1f, 0xca, 0x01, 0xc0, 0x03, 0x80, 0xa8, 0x07, 0x77, 0x98, + 0x87, 0x70, 0x30, 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, + 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, + 0x00, 0xa2, 0x1e, 0xe6, 0xa1, 0x1c, 0xda, 0x60, 0x1e, 0xde, 0xc1, 0x1c, + 0xe8, 0xa1, 0x0d, 0xcc, 0x81, 0x1d, 0xde, 0x21, 0x1c, 0xe8, 0x01, 0x30, + 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x60, 0x03, 0x22, 0x10, 0x40, + 0x02, 0x2c, 0x40, 0xb5, 0xc1, 0x18, 0x0a, 0x60, 0x01, 0xaa, 0x0d, 0x06, + 0x61, 0x00, 0x0b, 0x50, 0x6d, 0x30, 0x8a, 0x03, 0x58, 0x80, 0x6a, 0x83, + 0x61, 0xfc, 0xff, 0xff, 0xff, 0xff, 0x00, 0x48, 0x00, 0xb5, 0x01, 0x39, + 0xfe, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x18, 0x40, 0x02, 0xaa, 0x0d, 0x06, + 0x12, 0x00, 0x0b, 0x50, 0x6d, 0x30, 0x12, 0x01, 0x58, 0x80, 0x0a, 0x00, + 0x00, 0x00, 0x49, 0x18, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x13, 0x8a, + 0x40, 0x18, 0x88, 0x62, 0x42, 0x60, 0x4c, 0x18, 0x0e, 0x24, 0x01, 0x00, + 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x32, 0x22, + 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, + 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, + 0xa4, 0x4c, 0x10, 0x68, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, + 0x00, 0xc3, 0x08, 0x03, 0x70, 0x90, 0x34, 0x45, 0x94, 0x30, 0xf9, 0xb2, + 0xfb, 0x76, 0x84, 0xe0, 0x0c, 0x04, 0x22, 0xc6, 0x18, 0x63, 0x10, 0x81, + 0x10, 0x8e, 0x92, 0xa6, 0x88, 0x12, 0x26, 0xff, 0x9f, 0x88, 0x6b, 0xa2, + 0x22, 0xe2, 0xb7, 0x87, 0x7f, 0x1a, 0x23, 0x00, 0x06, 0x11, 0x8c, 0xe0, + 0x22, 0x69, 0x8a, 0x28, 0x61, 0xf2, 0x7f, 0x09, 0x60, 0x9e, 0x85, 0x88, + 0xfe, 0x69, 0x8c, 0x00, 0x18, 0x44, 0x40, 0x84, 0x82, 0x84, 0x10, 0x44, + 0x39, 0x27, 0x91, 0x2a, 0x03, 0x18, 0x83, 0xd8, 0x1c, 0x41, 0x30, 0x47, + 0x00, 0x06, 0xc3, 0x08, 0xc2, 0x53, 0x90, 0x70, 0x92, 0x70, 0xd0, 0x01, + 0x8a, 0x03, 0x01, 0x29, 0xf0, 0x86, 0x11, 0x86, 0x67, 0x10, 0x21, 0x10, + 0xe6, 0x08, 0x40, 0x61, 0x10, 0x61, 0x10, 0x46, 0x00, 0x00, 0x13, 0xa8, + 0x70, 0x48, 0x07, 0x79, 0xb0, 0x03, 0x3a, 0x68, 0x83, 0x70, 0x80, 0x07, + 0x78, 0x60, 0x87, 0x72, 0x68, 0x83, 0x74, 0x78, 0x87, 0x79, 0xc8, 0x03, + 0x37, 0x80, 0x03, 0x37, 0x80, 0x83, 0x0d, 0xb7, 0x51, 0x0e, 0x6d, 0x00, + 0x0f, 0x7a, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, + 0x07, 0x74, 0xd0, 0x06, 0xe9, 0x10, 0x07, 0x7a, 0x80, 0x07, 0x7a, 0x80, + 0x07, 0x6d, 0x90, 0x0e, 0x78, 0xa0, 0x07, 0x78, 0xa0, 0x07, 0x78, 0xd0, + 0x06, 0xe9, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, 0x07, 0x7a, 0x10, + 0x07, 0x76, 0xd0, 0x06, 0xe9, 0x30, 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, + 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xe9, 0x60, 0x07, 0x74, 0xa0, + 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xe6, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, + 0x06, 0xe6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, + 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x76, 0xa0, 0x07, 0x71, 0x60, + 0x07, 0x7a, 0x10, 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x74, 0xa0, + 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x30, + 0x07, 0x72, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x7a, 0x30, 0x07, 0x72, 0xd0, + 0x06, 0xf6, 0x40, 0x07, 0x78, 0xa0, 0x07, 0x76, 0x40, 0x07, 0x7a, 0x60, + 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x60, 0x07, 0x74, 0xa0, 0x07, 0x76, 0x40, + 0x07, 0x7a, 0x60, 0x07, 0x74, 0xd0, 0x06, 0xf6, 0x90, 0x07, 0x76, 0xa0, + 0x07, 0x71, 0x20, 0x07, 0x78, 0xa0, 0x07, 0x71, 0x20, 0x07, 0x78, 0xd0, + 0x06, 0xf6, 0x10, 0x07, 0x72, 0x80, 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, + 0x07, 0x7a, 0x10, 0x07, 0x72, 0x80, 0x07, 0x6d, 0x60, 0x0f, 0x71, 0x90, + 0x07, 0x72, 0xa0, 0x07, 0x72, 0x50, 0x07, 0x76, 0xa0, 0x07, 0x72, 0x50, + 0x07, 0x76, 0xd0, 0x06, 0xf6, 0x20, 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, + 0x07, 0x75, 0x60, 0x07, 0x7a, 0x20, 0x07, 0x75, 0x60, 0x07, 0x6d, 0x60, + 0x0f, 0x75, 0x10, 0x07, 0x72, 0xa0, 0x07, 0x75, 0x10, 0x07, 0x72, 0xa0, + 0x07, 0x75, 0x10, 0x07, 0x72, 0xd0, 0x06, 0xf6, 0x10, 0x07, 0x70, 0x20, + 0x07, 0x74, 0xa0, 0x07, 0x71, 0x00, 0x07, 0x72, 0x40, 0x07, 0x7a, 0x10, + 0x07, 0x70, 0x20, 0x07, 0x74, 0xd0, 0x06, 0xee, 0x80, 0x07, 0x7a, 0x10, + 0x07, 0x76, 0xa0, 0x07, 0x73, 0x20, 0x07, 0x43, 0x98, 0x05, 0x00, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x21, 0x4c, 0x03, 0x04, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0x10, 0x46, 0x02, 0x02, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x20, 0x0b, 0x04, 0x0b, 0x00, 0x00, 0x00, 0x32, 0x1e, + 0x98, 0x14, 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, + 0x43, 0x7a, 0x25, 0x30, 0x02, 0x50, 0x20, 0x45, 0x50, 0x08, 0x05, 0x18, + 0x50, 0x10, 0x65, 0x50, 0x40, 0x05, 0x56, 0x0a, 0xc5, 0x40, 0x74, 0x2c, + 0xc1, 0x19, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x0c, 0x01, + 0x00, 0x00, 0x1a, 0x03, 0x4c, 0x10, 0x97, 0x29, 0xa2, 0x25, 0x10, 0xab, + 0x32, 0xb9, 0xb9, 0xb4, 0x37, 0xb7, 0x21, 0xc6, 0x63, 0x4c, 0x00, 0xf5, + 0x50, 0xb9, 0x1b, 0x43, 0x0b, 0x93, 0xfb, 0x9a, 0x4b, 0xd3, 0x2b, 0x1b, + 0x62, 0x3c, 0xc3, 0x24, 0x3c, 0x07, 0xe1, 0x20, 0x08, 0x0e, 0x8e, 0xad, + 0x0c, 0x84, 0x89, 0xc9, 0xaa, 0x09, 0xc4, 0xae, 0x4c, 0x6e, 0x2e, 0xed, + 0xcd, 0x0d, 0x64, 0x26, 0x06, 0x06, 0x26, 0xc6, 0xa5, 0x06, 0x06, 0x04, + 0xa5, 0xad, 0x8c, 0x2e, 0x8c, 0xcd, 0xac, 0xac, 0x65, 0x26, 0x06, 0x06, + 0x26, 0xc6, 0xa5, 0x06, 0xc6, 0x25, 0x26, 0x65, 0x88, 0x30, 0x11, 0x43, + 0x8c, 0x67, 0x78, 0x92, 0x87, 0x60, 0xd1, 0x54, 0x46, 0x17, 0xc6, 0x36, + 0x04, 0x99, 0x8e, 0x67, 0x78, 0x86, 0x87, 0xe0, 0x16, 0x96, 0x26, 0xe7, + 0x32, 0xf6, 0xd6, 0x06, 0x97, 0xc6, 0x56, 0xe6, 0x42, 0x56, 0xe6, 0xf6, + 0x26, 0xd7, 0x36, 0xf7, 0x45, 0x96, 0x36, 0x17, 0x26, 0xc6, 0x56, 0x36, + 0x44, 0x98, 0x12, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, + 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, + 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x84, 0x69, 0x21, + 0x19, 0x84, 0xa5, 0xc9, 0xb9, 0x8c, 0xbd, 0xb5, 0xc1, 0xa5, 0xb1, 0x95, + 0xb9, 0x98, 0xc9, 0x85, 0xb5, 0x95, 0x89, 0xd5, 0x99, 0x99, 0x95, 0xc9, + 0x7d, 0x99, 0x95, 0xd1, 0x8d, 0xa1, 0x7d, 0x95, 0xb9, 0x85, 0x89, 0xb1, + 0x95, 0x0d, 0x11, 0xa6, 0x86, 0x51, 0x58, 0x9a, 0x9c, 0x8b, 0x5c, 0x99, + 0x1b, 0x59, 0x99, 0xdc, 0x17, 0x5d, 0x98, 0xdc, 0x59, 0x19, 0x1d, 0xa3, + 0xb0, 0x34, 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, + 0x2f, 0xb7, 0xb0, 0xb6, 0x32, 0x1a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, + 0x43, 0x90, 0xe9, 0x79, 0x88, 0x09, 0x9a, 0xa2, 0x21, 0xc2, 0x24, 0x91, + 0x09, 0x4b, 0x93, 0x73, 0x81, 0x7b, 0x9b, 0x4b, 0xa3, 0x4b, 0x7b, 0x73, + 0xa3, 0x12, 0x96, 0x26, 0xe7, 0x32, 0x56, 0xe6, 0x46, 0x57, 0x26, 0x47, + 0x29, 0x2c, 0x4d, 0xce, 0xc5, 0xed, 0xed, 0x0b, 0xae, 0x4c, 0x6e, 0x0e, + 0xae, 0x6c, 0x8c, 0x2e, 0xcd, 0xae, 0x8c, 0x4c, 0x58, 0x9a, 0x9c, 0x4b, + 0x98, 0xdc, 0xd9, 0x97, 0x5b, 0x58, 0x5b, 0x19, 0x11, 0xb8, 0xb7, 0xb9, + 0x34, 0xba, 0xb4, 0x37, 0xb7, 0x21, 0xd0, 0x43, 0x4c, 0xd4, 0x54, 0x4d, + 0xd6, 0x04, 0x4d, 0xd1, 0x74, 0x4d, 0x18, 0xa5, 0xb0, 0x34, 0x39, 0x17, + 0x33, 0xb9, 0xb0, 0xb3, 0xb6, 0x32, 0x37, 0xba, 0xaf, 0x34, 0x37, 0xb8, + 0x3a, 0x3a, 0x5a, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, + 0x28, 0x35, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x44, 0x76, 0x34, 0x5f, 0x66, + 0x29, 0x7c, 0xc2, 0xd2, 0xe4, 0x5c, 0xe0, 0xca, 0xe4, 0xe6, 0xe0, 0xca, + 0xc6, 0xe8, 0xd2, 0xec, 0xca, 0x58, 0x8c, 0xbd, 0xb1, 0xbd, 0xc9, 0x0d, + 0x91, 0x9e, 0x61, 0xd2, 0xa6, 0x6d, 0xaa, 0x26, 0x6e, 0x82, 0xa6, 0x68, + 0xba, 0xa6, 0x8e, 0xd9, 0x59, 0x99, 0x5b, 0x99, 0x5c, 0x18, 0x5d, 0x19, + 0x19, 0x0a, 0x0e, 0x5d, 0x19, 0xde, 0xd8, 0xdb, 0x9b, 0x1c, 0x19, 0x91, + 0x9d, 0xcc, 0x97, 0x59, 0x0a, 0x0d, 0x33, 0xb6, 0xb7, 0x30, 0x3a, 0x19, + 0x22, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x43, 0xa4, 0xc7, + 0x98, 0xb4, 0xe9, 0x9b, 0xaa, 0x89, 0x9b, 0xa0, 0x09, 0x0c, 0xa6, 0x6b, + 0x0a, 0x03, 0x2a, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, + 0x72, 0x7c, 0xc2, 0xd2, 0xe4, 0x5c, 0xc4, 0xea, 0xcc, 0xcc, 0xca, 0xe4, + 0xbe, 0xe6, 0xd2, 0xf4, 0xca, 0x28, 0x85, 0xa5, 0xc9, 0xb9, 0xb0, 0xbd, + 0x8d, 0x85, 0xd1, 0xa5, 0xbd, 0xb9, 0x7d, 0xa5, 0xb9, 0x91, 0x95, 0xe1, + 0x11, 0x09, 0x4b, 0x93, 0x73, 0x91, 0x2b, 0x0b, 0x23, 0x23, 0x15, 0x96, + 0x26, 0xe7, 0x32, 0x47, 0x27, 0x57, 0x37, 0x46, 0xf7, 0x45, 0x97, 0x07, + 0x57, 0xf6, 0x95, 0xe6, 0x66, 0xf6, 0x46, 0xc3, 0x8c, 0xed, 0x2d, 0x8c, + 0x6e, 0x86, 0xc6, 0x9b, 0x99, 0xd9, 0x5c, 0x19, 0x1d, 0x0d, 0xa9, 0xb1, + 0xb7, 0x32, 0x33, 0x33, 0x1a, 0x47, 0x63, 0x6f, 0x65, 0x66, 0x66, 0x34, + 0x84, 0xc6, 0xde, 0xca, 0xcc, 0xcc, 0x86, 0xa0, 0xc1, 0x43, 0x3c, 0xc5, + 0x43, 0x4c, 0x68, 0x30, 0xa5, 0xc1, 0x53, 0x3c, 0xc5, 0x43, 0x4c, 0x68, + 0x30, 0xa9, 0xc1, 0xb3, 0x3c, 0xc5, 0x43, 0x4c, 0x68, 0x30, 0xad, 0xc1, + 0xc3, 0x3c, 0xc5, 0x43, 0x4c, 0x68, 0x30, 0xb1, 0x01, 0xa3, 0xb0, 0x34, + 0x39, 0x97, 0x30, 0xb9, 0xb3, 0x2f, 0xba, 0x3c, 0xb8, 0xb2, 0xaf, 0xb9, + 0x34, 0xbd, 0x32, 0x5e, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x5f, 0x73, + 0x69, 0x7a, 0x65, 0x4c, 0xb2, 0xaa, 0xac, 0x88, 0xca, 0xc6, 0xde, 0xc8, + 0xca, 0x68, 0x90, 0x95, 0x8d, 0xbd, 0x91, 0x95, 0x0d, 0x21, 0x83, 0x47, + 0x99, 0xc6, 0x60, 0x22, 0x83, 0x07, 0x99, 0xca, 0xe0, 0x19, 0x9e, 0x61, + 0x32, 0x83, 0xe9, 0x0c, 0xa6, 0x36, 0x98, 0xdc, 0xe0, 0x41, 0xa6, 0x37, + 0x78, 0x8a, 0x09, 0x9a, 0xe0, 0x60, 0xba, 0xa6, 0x38, 0xe0, 0x12, 0x96, + 0x26, 0xe7, 0x42, 0x57, 0x86, 0x47, 0x57, 0x27, 0x57, 0x46, 0x25, 0x2c, + 0x4d, 0xce, 0x65, 0x2e, 0xac, 0x0d, 0x8e, 0xad, 0x8c, 0x18, 0x5d, 0x19, + 0x1e, 0x5d, 0x9d, 0x5c, 0x99, 0x0c, 0x19, 0x8f, 0x19, 0xdb, 0x5b, 0x18, + 0x1d, 0x0b, 0xc8, 0x5c, 0x58, 0x1b, 0x1c, 0x5b, 0x99, 0x0f, 0x09, 0xba, + 0x32, 0xbc, 0xac, 0x21, 0xd4, 0x73, 0x4c, 0x73, 0x30, 0x95, 0xc1, 0x43, + 0x3c, 0xc3, 0x44, 0x07, 0x13, 0x34, 0xd5, 0xc1, 0x74, 0x4d, 0x76, 0xc0, + 0x82, 0xae, 0x0c, 0xaf, 0xca, 0x6a, 0x08, 0xf5, 0x34, 0xd3, 0x1c, 0x4c, + 0x65, 0xf0, 0x0c, 0xcf, 0x30, 0xd1, 0xc1, 0x04, 0x4d, 0x75, 0x30, 0x5d, + 0x13, 0x1e, 0x70, 0x09, 0x4b, 0x93, 0x73, 0x99, 0x0b, 0x6b, 0x83, 0x63, + 0x2b, 0x93, 0xe3, 0x31, 0x17, 0xd6, 0x06, 0xc7, 0x56, 0x26, 0xc7, 0x60, + 0x6e, 0x88, 0xf4, 0x38, 0x93, 0x1e, 0x4c, 0x65, 0xf0, 0x10, 0xcf, 0x30, + 0x41, 0xd3, 0x1e, 0x4c, 0xd7, 0xc4, 0x07, 0x43, 0x9c, 0x29, 0x9b, 0xbc, + 0x49, 0x0c, 0x26, 0x39, 0x98, 0xee, 0x60, 0xca, 0x83, 0xa9, 0x0f, 0x86, + 0x18, 0x0b, 0x30, 0x4d, 0x93, 0x1f, 0x8c, 0x88, 0xd8, 0x81, 0x1d, 0xec, + 0xa1, 0x1d, 0xdc, 0xa0, 0x1d, 0xde, 0x81, 0x1c, 0xea, 0x81, 0x1d, 0xca, + 0xc1, 0x0d, 0xcc, 0x81, 0x1d, 0xc2, 0xe1, 0x1c, 0xe6, 0x61, 0x8a, 0x10, + 0x0c, 0x23, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x48, 0x07, + 0x72, 0x28, 0x07, 0x77, 0xa0, 0x87, 0x29, 0x41, 0x31, 0x62, 0x09, 0x87, + 0x74, 0x90, 0x07, 0x37, 0xb0, 0x87, 0x72, 0x90, 0x87, 0x79, 0x48, 0x87, + 0x77, 0x70, 0x87, 0x29, 0x81, 0x31, 0x82, 0x0a, 0x87, 0x74, 0x90, 0x07, + 0x37, 0x60, 0x87, 0x70, 0x70, 0x87, 0x73, 0xa8, 0x87, 0x70, 0x38, 0x87, + 0x72, 0xf8, 0x05, 0x7b, 0x28, 0x07, 0x79, 0x98, 0x87, 0x74, 0x78, 0x07, + 0x77, 0x98, 0x12, 0x20, 0x23, 0xa6, 0x70, 0x48, 0x07, 0x79, 0x70, 0x83, + 0x71, 0x78, 0x87, 0x76, 0x80, 0x87, 0x74, 0x60, 0x87, 0x72, 0xf8, 0x85, + 0x77, 0x80, 0x07, 0x7a, 0x48, 0x87, 0x77, 0x70, 0x87, 0x79, 0x98, 0x32, + 0x28, 0x8c, 0x33, 0x82, 0x09, 0x87, 0x74, 0x90, 0x07, 0x37, 0x30, 0x07, + 0x79, 0x08, 0x87, 0x73, 0x68, 0x87, 0x72, 0x70, 0x07, 0x7a, 0x98, 0x12, + 0xfc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x79, 0x18, 0x00, 0x00, 0x7b, 0x00, + 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, + 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, + 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, + 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, + 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, + 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, + 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, + 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, + 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, + 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, + 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, + 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, + 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, + 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, + 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, + 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, + 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, + 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, + 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, + 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, + 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, + 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, + 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, + 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, + 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, + 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, + 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, + 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, + 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, + 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, + 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, + 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, + 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, + 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, + 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, + 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, + 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, + 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, + 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, + 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, + 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, + 0x3c, 0x00, 0x71, 0x20, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x16, 0xd0, + 0x00, 0x48, 0xe4, 0x0f, 0xce, 0xe4, 0x57, 0x77, 0x71, 0xdb, 0x26, 0xb0, + 0x01, 0x48, 0xe4, 0x4b, 0x00, 0xf3, 0x2c, 0xc4, 0x3f, 0x11, 0xd7, 0x44, + 0x45, 0xc4, 0x6f, 0x0f, 0x7e, 0x85, 0x17, 0xb7, 0x6d, 0x00, 0x11, 0xdb, + 0x95, 0xff, 0xf9, 0xda, 0xf5, 0x5f, 0x44, 0x80, 0xc1, 0x10, 0xcd, 0x04, + 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x13, 0x04, + 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x74, 0x47, + 0x00, 0xa8, 0x8e, 0x35, 0x00, 0x03, 0x31, 0xc7, 0x40, 0x0c, 0xdf, 0x1c, + 0x03, 0xf1, 0x7d, 0x63, 0x0d, 0x40, 0x20, 0x10, 0x1c, 0x4b, 0x08, 0x00, + 0x72, 0x35, 0x30, 0x02, 0x40, 0x6f, 0x06, 0x80, 0xe0, 0x08, 0x00, 0x89, + 0x19, 0x00, 0x0a, 0x73, 0x10, 0x66, 0x60, 0x06, 0x66, 0x40, 0x06, 0x33, + 0x00, 0x04, 0xc6, 0x08, 0x40, 0x10, 0x04, 0xf1, 0x6f, 0x04, 0x60, 0x06, + 0x00, 0x00, 0x23, 0x06, 0xca, 0x10, 0x94, 0xc1, 0x14, 0x55, 0xca, 0x91, + 0x08, 0x83, 0x0c, 0x41, 0xe1, 0x8c, 0x18, 0x28, 0x43, 0x70, 0x06, 0xd4, + 0x74, 0x31, 0xc9, 0x42, 0x0c, 0x32, 0x04, 0x87, 0x33, 0xc8, 0x10, 0x28, + 0xd2, 0x20, 0x03, 0x11, 0x50, 0xa7, 0xd9, 0xa5, 0xa0, 0x0c, 0x32, 0x04, + 0x0c, 0x65, 0x44, 0x00, 0x9f, 0xf1, 0x06, 0x4f, 0x73, 0x83, 0x0b, 0xec, + 0x52, 0x50, 0x06, 0x19, 0x82, 0x28, 0x1b, 0x31, 0x28, 0x84, 0x80, 0x0e, + 0x8a, 0x60, 0xbc, 0x61, 0x0c, 0x3e, 0x38, 0xb8, 0xc0, 0x2e, 0x05, 0x65, + 0x90, 0x21, 0xb0, 0xbc, 0x11, 0x83, 0x42, 0x08, 0xf2, 0x40, 0x09, 0xc6, + 0x1b, 0xd0, 0x80, 0x0c, 0xe2, 0xe0, 0x02, 0xbb, 0x14, 0x94, 0x41, 0x86, + 0x60, 0x1b, 0x83, 0x11, 0x83, 0x42, 0x08, 0xfc, 0xe0, 0x09, 0xe6, 0x18, + 0xbc, 0x85, 0x0f, 0xe6, 0x18, 0x82, 0xc3, 0x0f, 0xe6, 0x18, 0x82, 0x81, + 0x0f, 0x2c, 0x90, 0x03, 0xf9, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; +const unsigned int sdl_metallib_len = 21810; diff --git a/SDL2-2.30.5/src/render/metal/SDL_shaders_metal_tvsimulator.h b/SDL2-2.30.5/src/render/metal/SDL_shaders_metal_tvsimulator.h new file mode 100644 index 0000000..2ceddcf --- /dev/null +++ b/SDL2-2.30.5/src/render/metal/SDL_shaders_metal_tvsimulator.h @@ -0,0 +1,2060 @@ +const unsigned char sdl_metallib[] = { + 0x4d, 0x54, 0x4c, 0x42, 0x01, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x64, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xae, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0e, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xd4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x5b, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, + 0x4e, 0x41, 0x4d, 0x45, 0x11, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x53, 0x6f, + 0x6c, 0x69, 0x64, 0x5f, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x00, 0x54, + 0x59, 0x50, 0x45, 0x01, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x20, 0x00, + 0x0c, 0x89, 0xfb, 0xf3, 0x80, 0x90, 0x8e, 0x7b, 0x79, 0xce, 0x85, 0xbe, + 0x02, 0x5a, 0x26, 0xb3, 0x39, 0x94, 0x89, 0x06, 0x15, 0xa3, 0x7c, 0x33, + 0xd4, 0xcb, 0xcd, 0x46, 0xe6, 0x32, 0x49, 0x18, 0x4d, 0x44, 0x53, 0x5a, + 0x08, 0x00, 0x30, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x46, + 0x46, 0x54, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x02, 0x00, + 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x85, 0x00, + 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x10, 0x00, 0x53, 0x44, 0x4c, 0x5f, + 0x43, 0x6f, 0x70, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x00, + 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x00, 0x48, 0x41, 0x53, 0x48, 0x20, + 0x00, 0xc8, 0xfe, 0x88, 0x61, 0xa2, 0xe6, 0xe3, 0x42, 0xf3, 0x2b, 0x5b, + 0x2a, 0x0e, 0x54, 0x9a, 0xec, 0x71, 0xac, 0x02, 0xfb, 0x88, 0xa2, 0x85, + 0x0e, 0x9c, 0x45, 0x93, 0x65, 0x23, 0xd3, 0xd3, 0x45, 0x4d, 0x44, 0x53, + 0x5a, 0x08, 0x00, 0x30, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, + 0x46, 0x46, 0x54, 0x18, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0d, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x88, + 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x13, 0x00, 0x53, 0x44, 0x4c, + 0x5f, 0x53, 0x6f, 0x6c, 0x69, 0x64, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, + 0x65, 0x6e, 0x74, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, + 0x41, 0x53, 0x48, 0x20, 0x00, 0xb3, 0x8a, 0x68, 0x2a, 0xd9, 0x82, 0x7b, + 0x43, 0xfb, 0xac, 0xd7, 0x0b, 0x21, 0xbf, 0x15, 0x37, 0x2d, 0x69, 0xf4, + 0x5e, 0xa9, 0xbf, 0xea, 0x08, 0xb5, 0xae, 0xdd, 0x08, 0xa0, 0x57, 0x15, + 0x34, 0x4d, 0x44, 0x53, 0x5a, 0x08, 0x00, 0x30, 0x0a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x4f, 0x46, 0x46, 0x54, 0x18, 0x00, 0x66, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, + 0x53, 0x08, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, + 0x4e, 0x44, 0x54, 0x87, 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x12, + 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x43, 0x6f, 0x70, 0x79, 0x5f, 0x66, 0x72, + 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, + 0x00, 0x01, 0x48, 0x41, 0x53, 0x48, 0x20, 0x00, 0x3a, 0xdb, 0x4f, 0xd9, + 0x5c, 0xa8, 0x18, 0xff, 0x1d, 0x96, 0x7f, 0x0d, 0xce, 0x02, 0xc1, 0xaf, + 0x38, 0xef, 0x15, 0x30, 0x92, 0x06, 0x8f, 0xfe, 0xa9, 0x07, 0x34, 0xfb, + 0x22, 0x93, 0xdc, 0xf9, 0x4d, 0x44, 0x53, 0x5a, 0x08, 0x00, 0xc0, 0x0b, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x46, 0x46, 0x54, 0x18, 0x00, + 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x90, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, + 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x86, 0x00, 0x00, 0x00, 0x4e, 0x41, + 0x4d, 0x45, 0x11, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x59, 0x55, 0x56, 0x5f, + 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x54, 0x59, 0x50, + 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, 0x53, 0x48, 0x20, 0x00, 0x26, 0x67, + 0x01, 0x40, 0x41, 0x64, 0x85, 0x58, 0xad, 0x6c, 0x46, 0xe8, 0xbf, 0x1a, + 0x79, 0x22, 0x12, 0x67, 0x32, 0x81, 0x20, 0xca, 0x22, 0xde, 0xc9, 0xc5, + 0xa1, 0x0a, 0x41, 0xfe, 0xd9, 0xa3, 0x4d, 0x44, 0x53, 0x5a, 0x08, 0x00, + 0xd0, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x46, 0x46, 0x54, + 0x18, 0x00, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x02, 0x00, 0x02, 0x00, + 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x87, 0x00, 0x00, 0x00, + 0x4e, 0x41, 0x4d, 0x45, 0x12, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x4e, 0x56, + 0x31, 0x32, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x00, + 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, 0x53, 0x48, 0x20, + 0x00, 0xff, 0x5a, 0xf7, 0xe3, 0x70, 0x77, 0x5e, 0x01, 0xaf, 0xf6, 0x9f, + 0x0b, 0xa1, 0x25, 0x76, 0xbf, 0xa1, 0x1f, 0xfb, 0x62, 0xbf, 0x02, 0xfa, + 0xa4, 0x10, 0x0d, 0xe9, 0x0f, 0x97, 0x2d, 0x3e, 0xca, 0x4d, 0x44, 0x53, + 0x5a, 0x08, 0x00, 0x30, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, + 0x46, 0x46, 0x54, 0x18, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x3f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, 0x08, 0x00, 0x02, + 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x87, + 0x00, 0x00, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x12, 0x00, 0x53, 0x44, 0x4c, + 0x5f, 0x4e, 0x56, 0x32, 0x31, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, + 0x6e, 0x74, 0x00, 0x54, 0x59, 0x50, 0x45, 0x01, 0x00, 0x01, 0x48, 0x41, + 0x53, 0x48, 0x20, 0x00, 0xdb, 0xf5, 0x5b, 0x6b, 0x9e, 0xad, 0xda, 0x32, + 0x16, 0x65, 0xd3, 0x04, 0x29, 0x2b, 0xc3, 0x71, 0xb9, 0x29, 0x97, 0xe1, + 0x4c, 0xa7, 0x36, 0x12, 0x81, 0x50, 0x19, 0xa9, 0x4b, 0x3f, 0xe8, 0xdb, + 0x4d, 0x44, 0x53, 0x5a, 0x08, 0x00, 0x40, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x4f, 0x46, 0x46, 0x54, 0x18, 0x00, 0x86, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x50, 0x4d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x45, 0x52, 0x53, + 0x08, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x45, 0x4e, + 0x44, 0x54, 0x45, 0x4e, 0x44, 0x54, 0x29, 0x00, 0x00, 0x00, 0x56, 0x41, + 0x54, 0x54, 0x15, 0x00, 0x02, 0x00, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x00, 0x00, 0x80, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x01, + 0x80, 0x56, 0x41, 0x54, 0x59, 0x04, 0x00, 0x02, 0x00, 0x04, 0x06, 0x45, + 0x4e, 0x44, 0x54, 0x35, 0x00, 0x00, 0x00, 0x56, 0x41, 0x54, 0x54, 0x20, + 0x00, 0x03, 0x00, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, + 0x00, 0x80, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x01, 0x80, 0x74, 0x65, + 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x00, 0x02, 0x80, 0x56, 0x41, 0x54, + 0x59, 0x05, 0x00, 0x03, 0x00, 0x04, 0x06, 0x04, 0x45, 0x4e, 0x44, 0x54, + 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, + 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, + 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, + 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, + 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, + 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, + 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, + 0x45, 0x4e, 0x44, 0x54, 0x04, 0x00, 0x00, 0x00, 0x45, 0x4e, 0x44, 0x54, + 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x10, 0x0d, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, + 0x35, 0x14, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x62, 0x0c, 0x30, 0x24, + 0x80, 0x10, 0x05, 0xc8, 0x14, 0x00, 0x00, 0x00, 0x21, 0x0c, 0x00, 0x00, + 0x09, 0x03, 0x00, 0x00, 0x0b, 0x02, 0x21, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, + 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, + 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, + 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88, + 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, + 0x04, 0x49, 0x0e, 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, + 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, + 0x85, 0x00, 0x00, 0x00, 0x1b, 0xc8, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, + 0x01, 0x90, 0x80, 0x8a, 0x18, 0x87, 0x77, 0x90, 0x07, 0x79, 0x28, 0x87, + 0x71, 0xa0, 0x07, 0x76, 0xc8, 0x87, 0x36, 0x90, 0x87, 0x77, 0xa8, 0x07, + 0x77, 0x20, 0x87, 0x72, 0x20, 0x87, 0x36, 0x20, 0x87, 0x74, 0xb0, 0x87, + 0x74, 0x20, 0x87, 0x72, 0x68, 0x83, 0x79, 0x88, 0x07, 0x79, 0xa0, 0x87, + 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, + 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1c, 0xd2, + 0x61, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xc2, + 0x21, 0x1d, 0xd8, 0xa1, 0x0d, 0xc6, 0x21, 0x1c, 0xd8, 0x81, 0x1d, 0xe6, + 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x60, 0x87, + 0x72, 0x98, 0x87, 0x79, 0x68, 0x03, 0x78, 0x90, 0x87, 0x72, 0x18, 0x87, + 0x74, 0x98, 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, 0x87, 0x76, 0x08, 0x07, + 0x72, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, + 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, + 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, + 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, + 0x72, 0x00, 0x06, 0x77, 0x78, 0x87, 0x36, 0x30, 0x07, 0x79, 0x08, 0x87, + 0x76, 0x28, 0x87, 0x36, 0x80, 0x87, 0x77, 0x48, 0x07, 0x77, 0xa0, 0x87, + 0x72, 0x90, 0x87, 0x36, 0x28, 0x07, 0x76, 0x48, 0x87, 0x76, 0x68, 0x03, + 0x77, 0x78, 0x07, 0x77, 0x68, 0x03, 0x76, 0x28, 0x87, 0x70, 0x30, 0x07, + 0x80, 0x70, 0x87, 0x77, 0x68, 0x83, 0x74, 0x70, 0x07, 0x73, 0x98, 0x87, + 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, + 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, + 0x40, 0x1d, 0xea, 0xa1, 0x1d, 0xe0, 0xa1, 0x0d, 0xe8, 0x21, 0x1c, 0xc4, + 0x81, 0x1d, 0xca, 0x61, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, + 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x70, 0x87, 0x70, 0x70, 0x87, + 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, + 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, + 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xce, 0xc1, 0x1d, 0xca, 0x81, 0x1c, 0xda, + 0x40, 0x1f, 0xca, 0x41, 0x1e, 0xde, 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, + 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, + 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x7a, 0x90, 0x87, + 0x70, 0x80, 0x07, 0x78, 0x48, 0x07, 0x77, 0x38, 0x87, 0x36, 0x68, 0x87, + 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, + 0x62, 0x1e, 0xe8, 0x21, 0x1c, 0xc6, 0x61, 0x1d, 0xda, 0x00, 0x1e, 0xe4, + 0xe1, 0x1d, 0xe8, 0xa1, 0x1c, 0xc6, 0x81, 0x1e, 0xde, 0x41, 0x1e, 0xda, + 0x40, 0x1c, 0xea, 0xc1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x0d, 0xe6, + 0x21, 0x1d, 0xf4, 0xa1, 0x1c, 0x00, 0x3c, 0x00, 0x88, 0x7a, 0x70, 0x87, + 0x79, 0x08, 0x07, 0x73, 0x28, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, + 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, + 0x01, 0x20, 0xea, 0x61, 0x1e, 0xca, 0xa1, 0x0d, 0xe6, 0xe1, 0x1d, 0xcc, + 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xd8, 0xe1, 0x1d, 0xc2, 0x81, 0x1e, 0x00, + 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x36, 0x2c, 0xc2, 0x00, + 0x24, 0xc0, 0x02, 0x54, 0x41, 0x1a, 0x80, 0xc2, 0x86, 0x65, 0x20, 0x80, + 0x04, 0x58, 0x80, 0x2a, 0x48, 0x03, 0x50, 0x00, 0x49, 0x18, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x13, 0x86, 0x40, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x89, 0x20, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, + 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, + 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, + 0x10, 0x40, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x60, 0x87, 0x10, 0xc0, 0x30, + 0x82, 0x00, 0x24, 0x41, 0x98, 0x89, 0x9a, 0x07, 0x7a, 0x90, 0x87, 0x7a, + 0x18, 0x07, 0x7a, 0x70, 0x83, 0x76, 0x28, 0x07, 0x7a, 0x08, 0x07, 0x76, + 0xd0, 0x03, 0x3d, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x79, 0x48, 0x07, 0x7c, + 0x40, 0x01, 0x19, 0x44, 0x28, 0x84, 0x52, 0x88, 0x11, 0x8c, 0xa1, 0x33, + 0x10, 0x30, 0x47, 0x00, 0x06, 0x29, 0xa0, 0xe6, 0x08, 0x40, 0x61, 0x10, + 0x21, 0x10, 0x86, 0x11, 0x08, 0x65, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x13, 0xc0, 0x20, 0x1c, 0xd2, 0x41, 0x1e, 0xec, 0x80, 0x0e, 0xda, 0x20, + 0x1c, 0xe0, 0x01, 0x1e, 0xd8, 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xec, 0xe1, + 0x1d, 0xe6, 0x21, 0x0e, 0xe6, 0xc0, 0x0d, 0xe0, 0xc0, 0x0d, 0xe0, 0xa0, + 0x0d, 0xe6, 0x21, 0x1d, 0xda, 0xa1, 0x1e, 0xd8, 0x21, 0x1c, 0xe8, 0xe1, + 0x1d, 0xe4, 0x61, 0xc3, 0x6d, 0x94, 0x43, 0x1b, 0xc0, 0x83, 0x1e, 0xd8, + 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, + 0x41, 0x3a, 0xc4, 0x81, 0x1e, 0xe0, 0x81, 0x1e, 0xe0, 0x41, 0x1b, 0xa4, + 0x03, 0x1e, 0xe8, 0x01, 0x1e, 0xe8, 0x01, 0x1e, 0xb4, 0x41, 0x3a, 0xc4, + 0x81, 0x1d, 0xe8, 0x41, 0x1c, 0xd8, 0x81, 0x1e, 0xc4, 0x81, 0x1d, 0xb4, + 0x41, 0x3a, 0xcc, 0x81, 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, + 0x81, 0x1c, 0xb4, 0x41, 0x3a, 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, + 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x39, 0xcc, 0x81, 0x1c, 0xe8, + 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, 0x39, 0xd8, + 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, + 0x81, 0x3d, 0xc4, 0x81, 0x1d, 0xe8, 0x41, 0x1c, 0xd8, 0x81, 0x1e, 0xc4, + 0x81, 0x1d, 0xb4, 0x81, 0x3d, 0xc8, 0x01, 0x1d, 0xe8, 0xc1, 0x1c, 0xc8, + 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, 0x3d, 0xcc, 0x81, 0x1c, 0xe8, + 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, 0x3d, 0xd0, + 0x01, 0x1e, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, + 0x81, 0x3d, 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, + 0x01, 0x1d, 0xb4, 0x81, 0x3d, 0xe4, 0x81, 0x1d, 0xe8, 0x41, 0x1c, 0xc8, + 0x01, 0x1e, 0xe8, 0x41, 0x1c, 0xc8, 0x01, 0x1e, 0xb4, 0x81, 0x3d, 0xc4, + 0x81, 0x1c, 0xe0, 0x81, 0x1e, 0xc4, 0x81, 0x1c, 0xe0, 0x81, 0x1e, 0xc4, + 0x81, 0x1c, 0xe0, 0x41, 0x1b, 0xd8, 0x43, 0x1c, 0xe4, 0x81, 0x1c, 0xe8, + 0x81, 0x1c, 0xd4, 0x81, 0x1d, 0xe8, 0x81, 0x1c, 0xd4, 0x81, 0x1d, 0xb4, + 0x81, 0x3d, 0xc8, 0x41, 0x1d, 0xd8, 0x81, 0x1e, 0xc8, 0x41, 0x1d, 0xd8, + 0x81, 0x1e, 0xc8, 0x41, 0x1d, 0xd8, 0x41, 0x1b, 0xd8, 0x43, 0x1d, 0xc4, + 0x81, 0x1c, 0xe8, 0x41, 0x1d, 0xc4, 0x81, 0x1c, 0xe8, 0x41, 0x1d, 0xc4, + 0x81, 0x1c, 0xb4, 0x81, 0x3d, 0xc4, 0x01, 0x1c, 0xc8, 0x01, 0x1d, 0xe8, + 0x41, 0x1c, 0xc0, 0x81, 0x1c, 0xd0, 0x81, 0x1e, 0xc4, 0x01, 0x1c, 0xc8, + 0x01, 0x1d, 0xb4, 0x81, 0x3b, 0xe0, 0x81, 0x1e, 0xc4, 0x81, 0x1d, 0xe8, + 0xc1, 0x1c, 0xc8, 0x81, 0x46, 0x08, 0x43, 0x42, 0x6c, 0x57, 0xfe, 0xac, + 0xb3, 0x20, 0xc3, 0x5f, 0x11, 0xd1, 0x44, 0x5c, 0x43, 0x22, 0x00, 0x3a, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x40, 0x62, + 0x83, 0x40, 0xd1, 0x85, 0x01, 0x00, 0x80, 0x2c, 0x10, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, + 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x52, 0x45, 0x50, 0x02, 0x85, + 0x30, 0x02, 0x50, 0x80, 0x01, 0x05, 0x52, 0x06, 0xc4, 0x46, 0x00, 0x68, + 0x8d, 0x25, 0x38, 0x03, 0x00, 0x00, 0x00, 0x00, 0xb1, 0x18, 0x00, 0x00, + 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, + 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, + 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, + 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, + 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, + 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, + 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, + 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, + 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, + 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, + 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, + 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, + 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, + 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, + 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, + 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, + 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, + 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, + 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, + 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, + 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, + 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, + 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, + 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, + 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, + 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, + 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, + 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, + 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, + 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, + 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, + 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, + 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, + 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, + 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, + 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, + 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, + 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, + 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, + 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, + 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, + 0xc0, 0xc3, 0x3c, 0x00, 0x79, 0x20, 0x00, 0x00, 0xd1, 0x00, 0x00, 0x00, + 0x32, 0x9a, 0x08, 0x14, 0x02, 0x85, 0x8c, 0x27, 0x46, 0x46, 0xc8, 0x11, + 0x32, 0x64, 0xd4, 0x3c, 0xcc, 0x7c, 0x00, 0x00, 0x8b, 0x02, 0x07, 0xc5, + 0xc6, 0x91, 0x01, 0x13, 0x19, 0x0c, 0x12, 0x59, 0x85, 0x53, 0x24, 0x90, + 0xe4, 0x19, 0xca, 0x83, 0x44, 0x17, 0xa2, 0x24, 0x53, 0x44, 0x4b, 0x20, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x77, 0x63, 0x68, 0x61, 0x72, + 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x4c, + 0x4c, 0x56, 0x4d, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, + 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x20, 0x28, 0x6d, 0x65, + 0x74, 0x61, 0x6c, 0x66, 0x65, 0x2d, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, + 0x35, 0x30, 0x2e, 0x31, 0x29, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x61, 0x69, + 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x64, 0x65, + 0x6e, 0x6f, 0x72, 0x6d, 0x73, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, + 0x65, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, + 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, 0x65, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, + 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x62, 0x75, + 0x66, 0x66, 0x65, 0x72, 0x5f, 0x66, 0x65, 0x74, 0x63, 0x68, 0x5f, 0x65, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x66, 0x6c, + 0x6f, 0x61, 0x74, 0x34, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x61, 0x69, 0x72, 0x2e, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x5f, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, + 0x65, 0x64, 0x28, 0x35, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x44, 0x76, 0x34, + 0x5f, 0x66, 0x29, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x61, 0x69, 0x72, 0x2e, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x66, 0x6c, + 0x6f, 0x61, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x53, 0x69, 0x7a, 0x65, + 0x61, 0x69, 0x72, 0x2e, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x5f, 0x69, + 0x6e, 0x70, 0x75, 0x74, 0x61, 0x69, 0x72, 0x2e, 0x6c, 0x6f, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x67, 0x65, + 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x5f, 0x5f, 0x61, 0x69, + 0x72, 0x5f, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x68, 0x6f, 0x6c, 0x64, 0x65, + 0x72, 0x5f, 0x5f, 0x29, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x61, 0x69, + 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x61, 0x69, 0x72, 0x2e, + 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x61, + 0x69, 0x72, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x61, 0x69, 0x72, 0x2e, 0x61, + 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, + 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x66, + 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x78, 0x34, 0x70, 0x72, 0x6f, 0x6a, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, + 0x72, 0x6d, 0x00, 0x00, 0xc4, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x82, 0xa0, 0x04, 0x23, 0x08, 0x4b, 0x32, 0x82, 0xa0, 0x08, 0x23, + 0x08, 0xca, 0x30, 0x82, 0xa0, 0x10, 0x23, 0x08, 0x08, 0x30, 0x82, 0xa0, + 0x14, 0x23, 0x08, 0x8a, 0x31, 0x82, 0xa0, 0x1c, 0x33, 0x0c, 0x5f, 0x00, + 0x06, 0x33, 0x0c, 0x61, 0x20, 0x88, 0xc1, 0x0c, 0xc1, 0x30, 0xc3, 0xf0, + 0x7d, 0x63, 0x30, 0x03, 0x41, 0x84, 0x41, 0x18, 0x8c, 0xc1, 0x0c, 0x41, + 0x31, 0x43, 0x60, 0xcc, 0x10, 0x1c, 0x33, 0x14, 0x48, 0xa2, 0x2c, 0xcc, + 0x0c, 0x46, 0xe3, 0x24, 0xca, 0xf2, 0xcc, 0x50, 0x40, 0x49, 0xb4, 0x48, + 0x33, 0x0c, 0x70, 0x10, 0x07, 0x72, 0x30, 0x83, 0x32, 0x06, 0x13, 0x35, + 0x06, 0x61, 0x50, 0x25, 0xd6, 0xc2, 0xcc, 0xa0, 0x84, 0xc1, 0x44, 0x85, + 0x41, 0x18, 0x54, 0x89, 0xb2, 0x3c, 0x33, 0x40, 0xdf, 0x85, 0x95, 0x01, + 0xf5, 0x85, 0x41, 0xa6, 0x95, 0xc1, 0x66, 0x06, 0x09, 0xb7, 0x74, 0x33, + 0x40, 0x67, 0x70, 0x61, 0x65, 0x40, 0x9d, 0x41, 0x18, 0x64, 0x5a, 0x19, + 0x6c, 0x66, 0x90, 0x70, 0x8b, 0x37, 0x03, 0x41, 0x07, 0x75, 0x60, 0x07, + 0x77, 0x30, 0xc3, 0x40, 0x06, 0x73, 0x80, 0x07, 0xb5, 0x01, 0x1c, 0xc7, + 0x71, 0x1c, 0xc7, 0x71, 0x1c, 0x1a, 0xb8, 0x81, 0x85, 0x06, 0x7a, 0x60, + 0x59, 0x96, 0x1b, 0xd0, 0x81, 0x1b, 0xd0, 0x81, 0x2f, 0xf8, 0x02, 0x4a, + 0xd0, 0x04, 0x28, 0xc8, 0x48, 0x60, 0x82, 0x2e, 0x62, 0x63, 0xb3, 0x6b, + 0x73, 0x69, 0x7b, 0x23, 0xab, 0x63, 0x2b, 0x73, 0x31, 0x63, 0x0b, 0x3b, + 0x9b, 0x1b, 0x45, 0x38, 0x03, 0x34, 0x38, 0x85, 0x8d, 0xcd, 0xae, 0xcd, + 0x25, 0x8d, 0xac, 0xcc, 0x8d, 0x6e, 0x94, 0x20, 0x0d, 0x6e, 0x09, 0x4b, + 0x93, 0x73, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x1b, 0x25, 0x50, + 0x83, 0xa3, 0xc2, 0xd2, 0xe4, 0x5c, 0xd8, 0xc2, 0xdc, 0xce, 0xea, 0xc2, + 0xce, 0xca, 0xbe, 0xec, 0xca, 0xe4, 0xe6, 0xd2, 0xde, 0xdc, 0x46, 0x09, + 0xd6, 0xe0, 0xa6, 0xb0, 0x34, 0x39, 0x97, 0xb1, 0xb7, 0x36, 0xb8, 0x34, + 0xb6, 0xb2, 0xaf, 0x37, 0x38, 0xba, 0xb4, 0x37, 0xb7, 0xb9, 0x51, 0x06, + 0x36, 0x68, 0x03, 0x37, 0x38, 0x25, 0x2c, 0x4d, 0xce, 0xc5, 0xae, 0x4c, + 0x8e, 0xae, 0x0c, 0x6f, 0x94, 0x00, 0x0f, 0x00, 0xa9, 0x18, 0x00, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x0a, 0x72, 0x28, 0x87, 0x77, 0x80, 0x07, + 0x7a, 0x58, 0x70, 0x98, 0x43, 0x3d, 0xb8, 0xc3, 0x38, 0xb0, 0x43, 0x39, + 0xd0, 0xc3, 0x82, 0xe6, 0x1c, 0xc6, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, + 0xc1, 0x1d, 0xe6, 0x21, 0x1d, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x00, + 0xd1, 0x10, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0xcc, 0x3c, 0xa4, + 0x83, 0x3b, 0x9c, 0x03, 0x3b, 0x94, 0x03, 0x3d, 0xa0, 0x83, 0x3c, 0x94, + 0x43, 0x38, 0x90, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, + 0x69, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0xc4, 0x4a, 0xa0, 0x0c, 0x8a, 0x80, 0xdc, 0x08, + 0xc0, 0x58, 0x44, 0x10, 0x04, 0xc1, 0x58, 0x84, 0x20, 0x08, 0xc2, 0x58, + 0xc4, 0x30, 0x0c, 0x03, 0x81, 0x31, 0x02, 0x10, 0x04, 0x41, 0xfc, 0xa3, + 0x30, 0x03, 0x40, 0x62, 0x06, 0x80, 0xc6, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0xf1, 0x30, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x22, 0x47, 0xc8, 0x90, + 0x51, 0x0a, 0x84, 0x18, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x03, 0x00, 0x00, + 0x6f, 0x6d, 0x6e, 0x69, 0x70, 0x6f, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x63, + 0x68, 0x61, 0x72, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x2b, + 0x2b, 0x20, 0x54, 0x42, 0x41, 0x41, 0x00, 0x00, 0x13, 0x04, 0x06, 0xd9, + 0x10, 0xec, 0xc1, 0x86, 0x41, 0x0f, 0xfa, 0x80, 0x0f, 0x36, 0x0c, 0x7e, + 0xe0, 0x07, 0x7c, 0x00, 0xbb, 0x10, 0x4c, 0x54, 0x45, 0x14, 0x84, 0xb2, + 0x0b, 0xf1, 0x4c, 0xd7, 0x44, 0x41, 0x28, 0x83, 0x0c, 0xc3, 0xc1, 0x98, + 0x10, 0x88, 0xff, 0x2e, 0xc4, 0x74, 0x6d, 0x11, 0x05, 0xa1, 0x0c, 0x32, + 0x1c, 0xcb, 0x63, 0x42, 0x20, 0xfe, 0x16, 0x14, 0xe0, 0xbf, 0x0b, 0x81, + 0x71, 0x60, 0x40, 0x51, 0x10, 0xca, 0x20, 0x03, 0x03, 0x4d, 0x26, 0x04, + 0xe2, 0x6f, 0x45, 0x00, 0xfe, 0xbb, 0x10, 0x5d, 0x18, 0x94, 0x81, 0x46, + 0x41, 0x28, 0x83, 0x0c, 0x51, 0x75, 0x99, 0x10, 0x88, 0xbf, 0x15, 0x01, + 0xf8, 0xef, 0x42, 0x84, 0x81, 0x19, 0xa8, 0x01, 0x18, 0x50, 0x10, 0xca, + 0x20, 0x43, 0xa0, 0x7d, 0x16, 0x54, 0xe2, 0x3f, 0xc8, 0x30, 0x70, 0x60, + 0x60, 0xc1, 0x24, 0xfe, 0x36, 0x04, 0xe0, 0x3f, 0xc8, 0x60, 0x7c, 0x62, + 0x60, 0x41, 0x24, 0xfe, 0x36, 0x04, 0xe0, 0x3f, 0xc8, 0x90, 0x88, 0x01, + 0x19, 0x58, 0xf0, 0x88, 0xbf, 0x0d, 0x01, 0xf8, 0xef, 0x42, 0xb8, 0xc1, + 0x1c, 0xdc, 0x01, 0x1b, 0x50, 0x10, 0xca, 0x20, 0x43, 0x70, 0x06, 0x6c, + 0x60, 0x81, 0x18, 0x88, 0xff, 0x20, 0xc3, 0x90, 0x06, 0x6d, 0x60, 0x01, + 0x18, 0x88, 0xff, 0x20, 0x43, 0xb1, 0x06, 0x6e, 0x60, 0x41, 0x27, 0xfe, + 0x83, 0x0c, 0x47, 0x1b, 0xbc, 0x81, 0x05, 0x9a, 0xf8, 0x0f, 0x32, 0xec, + 0x41, 0x1b, 0xd0, 0x81, 0x65, 0x81, 0xf8, 0x0f, 0x32, 0xf4, 0xc1, 0x1b, + 0xd4, 0x81, 0x39, 0x81, 0xf8, 0x5b, 0x32, 0x80, 0xbf, 0x05, 0x0c, 0xf8, + 0x5b, 0x90, 0x80, 0xbf, 0x05, 0x08, 0xf8, 0x5b, 0x50, 0x80, 0xff, 0x6c, + 0xc3, 0x1d, 0x04, 0xc0, 0x6c, 0x43, 0x40, 0x0a, 0xc1, 0x6c, 0x43, 0xb0, + 0x07, 0x42, 0x06, 0x01, 0x31, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x5b, 0x86, 0x20, 0xf0, 0x83, 0x2d, 0xc3, 0x10, 0xf8, 0xc1, 0x96, 0xe1, + 0x08, 0xfc, 0x60, 0xcb, 0xc0, 0x04, 0x7e, 0xb0, 0x65, 0x88, 0x02, 0x3f, + 0xd8, 0x32, 0x58, 0x81, 0x1f, 0x6c, 0x19, 0xc6, 0x20, 0xf0, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x32, 0x0e, 0x10, 0x22, 0x84, 0x00, 0xa0, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x65, 0x0c, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, + 0x12, 0x03, 0x94, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, 0x0c, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0x7a, 0x00, 0x00, 0x00, 0x00, + 0x53, 0x44, 0x4c, 0x5f, 0x53, 0x6f, 0x6c, 0x69, 0x64, 0x5f, 0x76, 0x65, + 0x72, 0x74, 0x65, 0x78, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, + 0x2e, 0x31, 0x61, 0x69, 0x72, 0x36, 0x34, 0x2d, 0x61, 0x70, 0x70, 0x6c, + 0x65, 0x2d, 0x74, 0x76, 0x6f, 0x73, 0x31, 0x33, 0x2e, 0x30, 0x2e, 0x30, + 0x2d, 0x73, 0x69, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x14, 0x0d, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x42, 0x43, 0xc0, 0xde, 0x35, 0x14, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x62, 0x0c, 0x30, 0x24, 0x80, 0x10, 0x05, 0xc8, 0x14, 0x00, 0x00, 0x00, + 0x21, 0x0c, 0x00, 0x00, 0x0a, 0x03, 0x00, 0x00, 0x0b, 0x02, 0x21, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, + 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, + 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, + 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, + 0x0a, 0x32, 0x52, 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, + 0x00, 0x19, 0x32, 0x42, 0x04, 0x49, 0x0e, 0x90, 0x91, 0x22, 0xc4, 0x50, + 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x29, 0x46, 0x06, + 0x51, 0x18, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x1b, 0xc8, 0x25, 0xf8, + 0xff, 0xff, 0xff, 0xff, 0x01, 0x90, 0x80, 0x8a, 0x18, 0x87, 0x77, 0x90, + 0x07, 0x79, 0x28, 0x87, 0x71, 0xa0, 0x07, 0x76, 0xc8, 0x87, 0x36, 0x90, + 0x87, 0x77, 0xa8, 0x07, 0x77, 0x20, 0x87, 0x72, 0x20, 0x87, 0x36, 0x20, + 0x87, 0x74, 0xb0, 0x87, 0x74, 0x20, 0x87, 0x72, 0x68, 0x83, 0x79, 0x88, + 0x07, 0x79, 0xa0, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, + 0x07, 0x7a, 0x40, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, + 0x00, 0x82, 0x1c, 0xd2, 0x61, 0x1e, 0xc2, 0x41, 0x1c, 0xd8, 0xa1, 0x1c, + 0xda, 0x80, 0x1e, 0xc2, 0x21, 0x1d, 0xd8, 0xa1, 0x0d, 0xc6, 0x21, 0x1c, + 0xd8, 0x81, 0x1d, 0xe6, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, + 0x07, 0x80, 0x60, 0x87, 0x72, 0x98, 0x87, 0x79, 0x68, 0x03, 0x78, 0x90, + 0x87, 0x72, 0x18, 0x87, 0x74, 0x98, 0x87, 0x72, 0x68, 0x03, 0x73, 0x80, + 0x87, 0x76, 0x08, 0x07, 0x72, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, + 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, + 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, + 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, 0x01, 0xa0, + 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x06, 0x77, 0x78, 0x87, 0x36, 0x30, + 0x07, 0x79, 0x08, 0x87, 0x76, 0x28, 0x87, 0x36, 0x80, 0x87, 0x77, 0x48, + 0x07, 0x77, 0xa0, 0x87, 0x72, 0x90, 0x87, 0x36, 0x28, 0x07, 0x76, 0x48, + 0x87, 0x76, 0x68, 0x03, 0x77, 0x78, 0x07, 0x77, 0x68, 0x03, 0x76, 0x28, + 0x87, 0x70, 0x30, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x83, 0x74, 0x70, + 0x07, 0x73, 0x98, 0x87, 0x36, 0x30, 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, + 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, + 0xdc, 0xe1, 0x1d, 0xda, 0x40, 0x1d, 0xea, 0xa1, 0x1d, 0xe0, 0xa1, 0x0d, + 0xe8, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x1e, 0x00, 0x73, 0x08, + 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x70, + 0x87, 0x70, 0x70, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, + 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, + 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xce, 0xc1, 0x1d, + 0xca, 0x81, 0x1c, 0xda, 0x40, 0x1f, 0xca, 0x41, 0x1e, 0xde, 0x61, 0x1e, + 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, + 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, + 0x03, 0x7a, 0x90, 0x87, 0x70, 0x80, 0x07, 0x78, 0x48, 0x07, 0x77, 0x38, + 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, + 0xea, 0xa1, 0x1c, 0x00, 0x62, 0x1e, 0xe8, 0x21, 0x1c, 0xc6, 0x61, 0x1d, + 0xda, 0x00, 0x1e, 0xe4, 0xe1, 0x1d, 0xe8, 0xa1, 0x1c, 0xc6, 0x81, 0x1e, + 0xde, 0x41, 0x1e, 0xda, 0x40, 0x1c, 0xea, 0xc1, 0x1c, 0xcc, 0xa1, 0x1c, + 0xe4, 0xa1, 0x0d, 0xe6, 0x21, 0x1d, 0xf4, 0xa1, 0x1c, 0x00, 0x3c, 0x00, + 0x88, 0x7a, 0x70, 0x87, 0x79, 0x08, 0x07, 0x73, 0x28, 0x87, 0x36, 0x30, + 0x07, 0x78, 0x68, 0x83, 0x76, 0x08, 0x07, 0x7a, 0x40, 0x07, 0x80, 0x1e, + 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x20, 0xea, 0x61, 0x1e, 0xca, 0xa1, 0x0d, + 0xe6, 0xe1, 0x1d, 0xcc, 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xd8, 0xe1, 0x1d, + 0xc2, 0x81, 0x1e, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, + 0x36, 0x2c, 0x02, 0x01, 0x24, 0xc0, 0x02, 0x54, 0x41, 0x1a, 0x80, 0xc2, + 0x86, 0x65, 0x28, 0x80, 0x04, 0x58, 0x80, 0x2a, 0x48, 0x03, 0x50, 0x00, + 0x49, 0x18, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x86, 0x40, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, + 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, + 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x40, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, + 0x8c, 0x20, 0x00, 0x76, 0x08, 0x41, 0x24, 0x41, 0x98, 0x89, 0x9a, 0x07, + 0x7a, 0x90, 0x87, 0x7a, 0x18, 0x07, 0x7a, 0x70, 0x83, 0x76, 0x28, 0x07, + 0x7a, 0x08, 0x07, 0x76, 0xd0, 0x03, 0x3d, 0x68, 0x87, 0x70, 0xa0, 0x07, + 0x79, 0x48, 0x07, 0x7c, 0x40, 0x01, 0x19, 0x44, 0x28, 0x84, 0x62, 0x0c, + 0x11, 0x84, 0x31, 0x74, 0x06, 0x02, 0xe6, 0x08, 0xc0, 0x20, 0x05, 0xd4, + 0x1c, 0x01, 0x28, 0x0c, 0x22, 0x04, 0xc2, 0x30, 0x02, 0xa1, 0x8c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x13, 0xc0, 0x20, 0x1c, 0xd2, 0x41, 0x1e, 0xec, + 0x80, 0x0e, 0xda, 0x20, 0x1c, 0xe0, 0x01, 0x1e, 0xd8, 0xa1, 0x1c, 0xda, + 0x80, 0x1e, 0xec, 0xe1, 0x1d, 0xe6, 0x21, 0x0e, 0xe6, 0xc0, 0x0d, 0xe0, + 0xc0, 0x0d, 0xe0, 0xa0, 0x0d, 0xe6, 0x21, 0x1d, 0xda, 0xa1, 0x1e, 0xd8, + 0x21, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, 0x61, 0xc3, 0x6d, 0x94, 0x43, 0x1b, + 0xc0, 0x83, 0x1e, 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, + 0xd8, 0x01, 0x1d, 0xb4, 0x41, 0x3a, 0xc4, 0x81, 0x1e, 0xe0, 0x81, 0x1e, + 0xe0, 0x41, 0x1b, 0xa4, 0x03, 0x1e, 0xe8, 0x01, 0x1e, 0xe8, 0x01, 0x1e, + 0xb4, 0x41, 0x3a, 0xc4, 0x81, 0x1d, 0xe8, 0x41, 0x1c, 0xd8, 0x81, 0x1e, + 0xc4, 0x81, 0x1d, 0xb4, 0x41, 0x3a, 0xcc, 0x81, 0x1c, 0xe8, 0xc1, 0x1c, + 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x41, 0x3a, 0xd8, 0x01, 0x1d, + 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x39, + 0xcc, 0x81, 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, + 0xb4, 0x81, 0x39, 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, + 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x3d, 0xc4, 0x81, 0x1d, 0xe8, 0x41, 0x1c, + 0xd8, 0x81, 0x1e, 0xc4, 0x81, 0x1d, 0xb4, 0x81, 0x3d, 0xc8, 0x01, 0x1d, + 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, 0x3d, + 0xcc, 0x81, 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, + 0xb4, 0x81, 0x3d, 0xd0, 0x01, 0x1e, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, + 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x3d, 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, + 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x3d, 0xe4, 0x81, 0x1d, + 0xe8, 0x41, 0x1c, 0xc8, 0x01, 0x1e, 0xe8, 0x41, 0x1c, 0xc8, 0x01, 0x1e, + 0xb4, 0x81, 0x3d, 0xc4, 0x81, 0x1c, 0xe0, 0x81, 0x1e, 0xc4, 0x81, 0x1c, + 0xe0, 0x81, 0x1e, 0xc4, 0x81, 0x1c, 0xe0, 0x41, 0x1b, 0xd8, 0x43, 0x1c, + 0xe4, 0x81, 0x1c, 0xe8, 0x81, 0x1c, 0xd4, 0x81, 0x1d, 0xe8, 0x81, 0x1c, + 0xd4, 0x81, 0x1d, 0xb4, 0x81, 0x3d, 0xc8, 0x41, 0x1d, 0xd8, 0x81, 0x1e, + 0xc8, 0x41, 0x1d, 0xd8, 0x81, 0x1e, 0xc8, 0x41, 0x1d, 0xd8, 0x41, 0x1b, + 0xd8, 0x43, 0x1d, 0xc4, 0x81, 0x1c, 0xe8, 0x41, 0x1d, 0xc4, 0x81, 0x1c, + 0xe8, 0x41, 0x1d, 0xc4, 0x81, 0x1c, 0xb4, 0x81, 0x3d, 0xc4, 0x01, 0x1c, + 0xc8, 0x01, 0x1d, 0xe8, 0x41, 0x1c, 0xc0, 0x81, 0x1c, 0xd0, 0x81, 0x1e, + 0xc4, 0x01, 0x1c, 0xc8, 0x01, 0x1d, 0xb4, 0x81, 0x3b, 0xe0, 0x81, 0x1e, + 0xc4, 0x81, 0x1d, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x46, 0x08, 0x43, 0x3e, + 0x6c, 0x57, 0xfe, 0x9c, 0xf3, 0x60, 0x7f, 0x45, 0x44, 0x13, 0x71, 0x0d, + 0x89, 0x80, 0xe7, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x89, 0x0d, 0x02, 0x45, 0x19, 0x06, 0x00, 0x00, 0xb2, 0x40, + 0x0a, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, + 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x52, 0x45, 0x50, 0x02, 0x85, + 0x30, 0x02, 0x50, 0x06, 0x05, 0x18, 0x50, 0x20, 0xc4, 0x46, 0x00, 0x68, + 0x8d, 0x25, 0x38, 0x03, 0x00, 0x00, 0x00, 0x00, 0xb1, 0x18, 0x00, 0x00, + 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, + 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, + 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, + 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, + 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, + 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, + 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, + 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, + 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, + 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, + 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, + 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, + 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, + 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, + 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, + 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, + 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, + 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, + 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, + 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, + 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, + 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, + 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, + 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, + 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, + 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, + 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, + 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, + 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, + 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, + 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, + 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, + 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, + 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, + 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, + 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, + 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, + 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, + 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, + 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, + 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, + 0xc0, 0xc3, 0x3c, 0x00, 0x79, 0x20, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, + 0x32, 0x9a, 0x08, 0x14, 0x02, 0x85, 0x8c, 0x27, 0x46, 0x46, 0xc8, 0x11, + 0x32, 0x64, 0xd4, 0x3a, 0x6c, 0x7d, 0x00, 0x00, 0x8b, 0x02, 0x07, 0xc5, + 0xc6, 0x91, 0x01, 0x13, 0x19, 0x0c, 0x12, 0x59, 0x45, 0x66, 0x20, 0x90, + 0xe4, 0x29, 0x0f, 0x12, 0x5d, 0x88, 0x92, 0x00, 0x53, 0x44, 0x4b, 0x20, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x77, 0x63, 0x68, 0x61, 0x72, + 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x4c, + 0x4c, 0x56, 0x4d, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, + 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x20, 0x28, 0x6d, 0x65, + 0x74, 0x61, 0x6c, 0x66, 0x65, 0x2d, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, + 0x35, 0x30, 0x2e, 0x31, 0x29, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x61, 0x69, + 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x64, 0x65, + 0x6e, 0x6f, 0x72, 0x6d, 0x73, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, + 0x65, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, + 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, 0x65, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, + 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x62, 0x75, + 0x66, 0x66, 0x65, 0x72, 0x5f, 0x66, 0x65, 0x74, 0x63, 0x68, 0x5f, 0x65, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x66, 0x6c, + 0x6f, 0x61, 0x74, 0x34, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x61, 0x69, 0x72, 0x2e, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x5f, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, + 0x65, 0x64, 0x28, 0x35, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x44, 0x76, 0x34, + 0x5f, 0x66, 0x29, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x67, 0x65, 0x6e, 0x65, + 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x38, 0x74, 0x65, 0x78, 0x63, 0x6f, + 0x6f, 0x72, 0x64, 0x44, 0x76, 0x32, 0x5f, 0x66, 0x29, 0x66, 0x6c, 0x6f, + 0x61, 0x74, 0x32, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x61, + 0x69, 0x72, 0x2e, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x5f, 0x69, 0x6e, + 0x70, 0x75, 0x74, 0x61, 0x69, 0x72, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x67, 0x65, 0x6e, + 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x5f, 0x5f, 0x61, 0x69, 0x72, + 0x5f, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x68, 0x6f, 0x6c, 0x64, 0x65, 0x72, + 0x5f, 0x5f, 0x29, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, + 0x72, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, + 0x73, 0x69, 0x7a, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x72, 0x65, 0x61, 0x64, + 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x5f, + 0x73, 0x69, 0x7a, 0x65, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x78, 0x34, + 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x00, 0x04, 0x58, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x30, 0x82, 0xa0, 0x04, 0x23, 0x08, 0x4b, 0x32, + 0x82, 0xa0, 0x08, 0x23, 0x08, 0xca, 0x30, 0x82, 0xa0, 0x10, 0x23, 0x08, + 0x08, 0x30, 0x82, 0xa0, 0x14, 0x23, 0x08, 0x8a, 0x31, 0x82, 0xa0, 0x1c, + 0x33, 0x0c, 0x5e, 0xf0, 0xcd, 0x30, 0x80, 0x81, 0x10, 0x06, 0x33, 0x04, + 0xc3, 0x0c, 0x83, 0xe7, 0x89, 0xc1, 0x0c, 0x04, 0x01, 0x06, 0x60, 0x20, + 0x06, 0x33, 0x04, 0xc5, 0x0c, 0x81, 0x31, 0x43, 0x70, 0xcc, 0x50, 0x20, + 0x89, 0xb2, 0x30, 0x33, 0x18, 0x8d, 0x93, 0x28, 0xcb, 0x33, 0x83, 0xd1, + 0x40, 0x49, 0xb4, 0x48, 0x33, 0x0c, 0x6f, 0x00, 0x07, 0x71, 0x30, 0x83, + 0x22, 0x06, 0x13, 0x25, 0x06, 0x60, 0x50, 0x25, 0xd1, 0xc2, 0xcc, 0xa0, + 0x80, 0xc1, 0x44, 0x81, 0x01, 0x18, 0x54, 0x89, 0xb2, 0x3c, 0x33, 0x28, + 0xde, 0x44, 0x79, 0x60, 0x50, 0x25, 0xd1, 0x22, 0xcd, 0x00, 0x91, 0x81, + 0x75, 0x95, 0x01, 0xe5, 0x81, 0x01, 0x96, 0x95, 0x81, 0x66, 0x06, 0xc9, + 0xb6, 0x70, 0x33, 0x40, 0x61, 0x60, 0x5d, 0x65, 0x40, 0x91, 0x01, 0x18, + 0x60, 0x59, 0x19, 0x68, 0x66, 0x90, 0x6c, 0x4b, 0x37, 0x43, 0x31, 0x07, + 0x74, 0x50, 0x07, 0x76, 0x70, 0x07, 0x33, 0x0c, 0x63, 0x20, 0x07, 0x78, + 0x50, 0x1c, 0xc0, 0x71, 0x1c, 0xc7, 0x71, 0x1c, 0xc7, 0x89, 0x81, 0x1b, + 0x58, 0x68, 0xa0, 0x07, 0x96, 0x65, 0xb9, 0x01, 0x1d, 0xd0, 0x01, 0x1d, + 0xf8, 0x82, 0x2f, 0xc8, 0x82, 0x4b, 0xd0, 0x04, 0x2b, 0xc8, 0x48, 0x60, + 0x82, 0x2e, 0x62, 0x63, 0xb3, 0x6b, 0x73, 0x69, 0x7b, 0x23, 0xab, 0x63, + 0x2b, 0x73, 0x31, 0x63, 0x0b, 0x3b, 0x9b, 0x1b, 0x45, 0x30, 0x83, 0x33, + 0x38, 0x85, 0x8d, 0xcd, 0xae, 0xcd, 0x25, 0x8d, 0xac, 0xcc, 0x8d, 0x6e, + 0x94, 0x00, 0x0d, 0x6e, 0x09, 0x4b, 0x93, 0x73, 0xb1, 0x2b, 0x93, 0x9b, + 0x4b, 0x7b, 0x73, 0x1b, 0x25, 0x48, 0x83, 0xa3, 0xc2, 0xd2, 0xe4, 0x5c, + 0xd8, 0xc2, 0xdc, 0xce, 0xea, 0xc2, 0xce, 0xca, 0xbe, 0xec, 0xca, 0xe4, + 0xe6, 0xd2, 0xde, 0xdc, 0x46, 0x09, 0xd4, 0xe0, 0xa6, 0xb0, 0x34, 0x39, + 0x97, 0xb1, 0xb7, 0x36, 0xb8, 0x34, 0xb6, 0xb2, 0xaf, 0x37, 0x38, 0xba, + 0xb4, 0x37, 0xb7, 0xb9, 0x51, 0x86, 0x35, 0x60, 0x83, 0x36, 0x38, 0x25, + 0x2c, 0x4d, 0xce, 0xc5, 0xae, 0x4c, 0x8e, 0xae, 0x0c, 0x6f, 0x94, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0xa9, 0x18, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0x0b, 0x0a, 0x72, 0x28, 0x87, 0x77, 0x80, 0x07, 0x7a, 0x58, 0x70, 0x98, + 0x43, 0x3d, 0xb8, 0xc3, 0x38, 0xb0, 0x43, 0x39, 0xd0, 0xc3, 0x82, 0xe6, + 0x1c, 0xc6, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0xc1, 0x1d, 0xe6, 0x21, + 0x1d, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x00, 0xd1, 0x10, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x07, 0xcc, 0x3c, 0xa4, 0x83, 0x3b, 0x9c, 0x03, + 0x3b, 0x94, 0x03, 0x3d, 0xa0, 0x83, 0x3c, 0x94, 0x43, 0x38, 0x90, 0xc3, + 0x01, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, + 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0xc4, 0x4a, 0xa0, 0x0c, 0x8a, 0x80, 0xdc, 0x08, 0xc0, 0x58, 0x44, 0x10, + 0x04, 0xc1, 0x58, 0x84, 0x20, 0x08, 0xc2, 0x58, 0xc4, 0x30, 0x0c, 0x03, + 0x85, 0x19, 0x00, 0x12, 0x33, 0x00, 0x34, 0x66, 0x00, 0x00, 0x00, 0x00, + 0xf1, 0x30, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x22, 0x47, 0xc8, 0x90, + 0x51, 0x0a, 0x84, 0x18, 0x00, 0x00, 0x00, 0x00, 0xcf, 0x03, 0x00, 0x00, + 0x6f, 0x6d, 0x6e, 0x69, 0x70, 0x6f, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x63, + 0x68, 0x61, 0x72, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x2b, + 0x2b, 0x20, 0x54, 0x42, 0x41, 0x41, 0x00, 0x00, 0x13, 0x04, 0x06, 0xd9, + 0x10, 0xec, 0xc1, 0x86, 0x41, 0x0f, 0xfa, 0x80, 0x0f, 0x36, 0x0c, 0x7e, + 0xe0, 0x07, 0x7c, 0x00, 0xbb, 0x10, 0x4b, 0x54, 0x45, 0x14, 0x84, 0xb2, + 0x0b, 0xe1, 0x4c, 0xd7, 0x44, 0x41, 0x28, 0x83, 0x0c, 0xc3, 0xb1, 0x98, + 0x10, 0x88, 0xff, 0x2e, 0x84, 0x74, 0x6d, 0x10, 0x05, 0xa1, 0x0c, 0x32, + 0x1c, 0x8b, 0x63, 0x42, 0x20, 0xfe, 0x16, 0x14, 0xe0, 0xbf, 0x0b, 0x71, + 0x71, 0x60, 0x30, 0x51, 0x10, 0xca, 0x20, 0x03, 0x03, 0x49, 0x26, 0x04, + 0xe2, 0x6f, 0x45, 0x00, 0xfe, 0xbb, 0x10, 0x5c, 0x18, 0x94, 0x41, 0x46, + 0x41, 0x28, 0x83, 0x0c, 0x51, 0x65, 0x99, 0x10, 0x88, 0xbf, 0x15, 0x01, + 0xf8, 0xef, 0x42, 0x80, 0x81, 0x19, 0xa8, 0xc1, 0x47, 0x41, 0x28, 0x83, + 0x0c, 0x81, 0xe6, 0x59, 0x50, 0x89, 0xff, 0x20, 0xc3, 0xc0, 0x7d, 0x16, + 0x4c, 0xe2, 0x6f, 0x43, 0x00, 0xfe, 0x83, 0x0c, 0xc6, 0x17, 0x06, 0x16, + 0x44, 0xe2, 0x6f, 0x43, 0x00, 0xfe, 0x83, 0x0c, 0x89, 0x18, 0x8c, 0x81, + 0x05, 0x8f, 0xf8, 0xdb, 0x10, 0x80, 0xff, 0x2e, 0x44, 0x1b, 0xcc, 0xc1, + 0x1d, 0xac, 0x01, 0x05, 0xa1, 0x0c, 0x32, 0x04, 0x67, 0xb0, 0x06, 0x16, + 0x88, 0x81, 0xf8, 0x0f, 0x32, 0x0c, 0x69, 0xc0, 0x06, 0x16, 0x80, 0x81, + 0xf8, 0x0f, 0x32, 0x14, 0x6b, 0xd0, 0x06, 0x16, 0x74, 0xe2, 0x3f, 0xc8, + 0x70, 0xb4, 0x81, 0x1b, 0x58, 0xa0, 0x89, 0xff, 0x20, 0xc3, 0x1e, 0xb8, + 0xc1, 0x1c, 0x58, 0x16, 0x88, 0xff, 0x20, 0x43, 0x1f, 0xc0, 0x01, 0x1d, + 0x98, 0x13, 0x88, 0xbf, 0x25, 0x03, 0xf8, 0x5b, 0xc0, 0x80, 0xbf, 0x05, + 0x09, 0xf8, 0x5b, 0x80, 0x80, 0xbf, 0x05, 0x05, 0xf8, 0xcf, 0x36, 0xd8, + 0x41, 0x00, 0xcc, 0x36, 0x04, 0xa4, 0x10, 0xcc, 0x36, 0x04, 0xa4, 0x20, + 0x64, 0x10, 0x10, 0x03, 0x09, 0x00, 0x00, 0x00, 0x5b, 0x86, 0x20, 0xf0, + 0x83, 0x2d, 0xc3, 0x10, 0xf8, 0xc1, 0x96, 0xe1, 0x08, 0xfc, 0x60, 0xcb, + 0xc0, 0x04, 0x7e, 0xb0, 0x65, 0x88, 0x02, 0x3f, 0xd8, 0x32, 0x58, 0x81, + 0x1f, 0x6c, 0x19, 0xc6, 0x20, 0xf0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x71, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x32, 0x0e, 0x10, 0x22, + 0x84, 0x00, 0xa4, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x65, 0x0c, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0xe8, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x19, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x24, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x5d, 0x0c, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x12, 0x03, 0x94, 0x79, 0x00, 0x00, 0x00, 0x00, 0x53, 0x44, 0x4c, 0x5f, + 0x43, 0x6f, 0x70, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x33, + 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x2e, 0x31, 0x61, 0x69, 0x72, + 0x36, 0x34, 0x2d, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2d, 0x74, 0x76, 0x6f, + 0x73, 0x31, 0x33, 0x2e, 0x30, 0x2e, 0x30, 0x2d, 0x73, 0x69, 0x6d, 0x75, + 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, + 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x18, 0x0a, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x35, 0x14, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x62, 0x0c, 0x30, 0x24, 0x80, 0x10, 0x05, 0xc8, + 0x14, 0x00, 0x00, 0x00, 0x21, 0x0c, 0x00, 0x00, 0x4b, 0x02, 0x00, 0x00, + 0x0b, 0x02, 0x21, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, + 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, + 0x80, 0x10, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0x84, 0x10, 0x32, 0x14, + 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x42, 0x88, 0x48, 0x90, 0x14, 0x20, + 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0x04, 0x49, 0x0e, 0x90, + 0x11, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, + 0x04, 0x21, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, + 0x1b, 0xcc, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x80, 0x03, 0x40, + 0x02, 0x28, 0x62, 0x1c, 0xde, 0x41, 0x1e, 0xe4, 0xa1, 0x1c, 0xc6, 0x81, + 0x1e, 0xd8, 0x21, 0x1f, 0xda, 0x40, 0x1e, 0xde, 0xa1, 0x1e, 0xdc, 0x81, + 0x1c, 0xca, 0x81, 0x1c, 0xda, 0x80, 0x1c, 0xd2, 0xc1, 0x1e, 0xd2, 0x81, + 0x1c, 0xca, 0xa1, 0x0d, 0xe6, 0x21, 0x1e, 0xe4, 0x81, 0x1e, 0xda, 0xc0, + 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x73, + 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x72, 0x48, 0x87, 0x79, + 0x08, 0x07, 0x71, 0x60, 0x87, 0x72, 0x68, 0x03, 0x7a, 0x08, 0x87, 0x74, + 0x60, 0x87, 0x36, 0x18, 0x87, 0x70, 0x60, 0x07, 0x76, 0x98, 0x07, 0xc0, + 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1d, 0xca, 0x61, + 0x1e, 0xe6, 0xa1, 0x0d, 0xe0, 0x41, 0x1e, 0xca, 0x61, 0x1c, 0xd2, 0x61, + 0x1e, 0xca, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0x21, 0x1c, 0xc8, 0x01, + 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, + 0x68, 0x03, 0x73, 0x90, 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, 0x78, + 0x78, 0x87, 0x74, 0x70, 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, 0x72, + 0x60, 0x87, 0x74, 0x68, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, + 0x18, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1, + 0x1c, 0xda, 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, + 0x1e, 0xda, 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, 0xa1, 0x0d, 0xdc, 0xe1, + 0x1d, 0xdc, 0xa1, 0x0d, 0xd8, 0xa1, 0x1c, 0xc2, 0xc1, 0x1c, 0x00, 0xc2, + 0x1d, 0xde, 0xa1, 0x0d, 0xd2, 0xc1, 0x1d, 0xcc, 0x61, 0x1e, 0xda, 0xc0, + 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, + 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x75, + 0xa8, 0x87, 0x76, 0x80, 0x87, 0x36, 0xa0, 0x87, 0x70, 0x10, 0x07, 0x76, + 0x28, 0x87, 0x79, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, + 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1d, 0xc2, 0xc1, 0x1d, 0xe6, 0xa1, + 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, + 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, + 0x98, 0x87, 0x74, 0x38, 0x07, 0x77, 0x28, 0x07, 0x72, 0x68, 0x03, 0x7d, + 0x28, 0x07, 0x79, 0x78, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, + 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, + 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0x01, + 0x1e, 0xe0, 0x21, 0x1d, 0xdc, 0xe1, 0x1c, 0xda, 0xa0, 0x1d, 0xc2, 0x81, + 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x88, 0x79, + 0xa0, 0x87, 0x70, 0x18, 0x87, 0x75, 0x68, 0x03, 0x78, 0x90, 0x87, 0x77, + 0xa0, 0x87, 0x72, 0x18, 0x07, 0x7a, 0x78, 0x07, 0x79, 0x68, 0x03, 0x71, + 0xa8, 0x07, 0x73, 0x30, 0x87, 0x72, 0x90, 0x87, 0x36, 0x98, 0x87, 0x74, + 0xd0, 0x87, 0x72, 0x00, 0xf0, 0x00, 0x20, 0xea, 0xc1, 0x1d, 0xe6, 0x21, + 0x1c, 0xcc, 0xa1, 0x1c, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, + 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, + 0xa8, 0x87, 0x79, 0x28, 0x87, 0x36, 0x98, 0x87, 0x77, 0x30, 0x07, 0x7a, + 0x68, 0x03, 0x73, 0x60, 0x87, 0x77, 0x08, 0x07, 0x7a, 0x00, 0xcc, 0x21, + 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0xd8, 0x40, 0x08, 0x02, 0x60, 0x01, + 0x49, 0x18, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x13, 0x84, 0x40, 0x00, + 0x89, 0x20, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x32, 0x22, 0x08, 0x09, + 0x20, 0x64, 0x85, 0x04, 0x13, 0x22, 0xa4, 0x84, 0x04, 0x13, 0x22, 0xe3, + 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x88, 0x8c, 0x0b, 0x84, 0x84, 0x4c, + 0x10, 0x24, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, 0x00, 0x65, + 0x08, 0x09, 0x9a, 0x81, 0x80, 0x39, 0x02, 0x30, 0x48, 0x01, 0x1b, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x13, 0xc0, 0x20, 0x1c, 0xd2, 0x41, 0x1e, 0xec, + 0x80, 0x0e, 0xda, 0x20, 0x1c, 0xe0, 0x01, 0x1e, 0xd8, 0xa1, 0x1c, 0xda, + 0x80, 0x1e, 0xec, 0xe1, 0x1d, 0xe6, 0x21, 0x0e, 0xe6, 0xc0, 0x0d, 0xe0, + 0xc0, 0x0d, 0xe0, 0xa0, 0x0d, 0xe6, 0x21, 0x1d, 0xda, 0xa1, 0x1e, 0xd8, + 0x21, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, 0x61, 0xc3, 0x6d, 0x94, 0x43, 0x1b, + 0xc0, 0x83, 0x1e, 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, + 0xd8, 0x01, 0x1d, 0xb4, 0x41, 0x3a, 0xc4, 0x81, 0x1e, 0xe0, 0x81, 0x1e, + 0xe0, 0x41, 0x1b, 0xa4, 0x03, 0x1e, 0xe8, 0x01, 0x1e, 0xe8, 0x01, 0x1e, + 0xb4, 0x41, 0x3a, 0xc4, 0x81, 0x1d, 0xe8, 0x41, 0x1c, 0xd8, 0x81, 0x1e, + 0xc4, 0x81, 0x1d, 0xb4, 0x41, 0x3a, 0xcc, 0x81, 0x1c, 0xe8, 0xc1, 0x1c, + 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x41, 0x3a, 0xd8, 0x01, 0x1d, + 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x39, + 0xcc, 0x81, 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, + 0xb4, 0x81, 0x39, 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, + 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x3d, 0xc4, 0x81, 0x1d, 0xe8, 0x41, 0x1c, + 0xd8, 0x81, 0x1e, 0xc4, 0x81, 0x1d, 0xb4, 0x81, 0x3d, 0xc8, 0x01, 0x1d, + 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, 0x3d, + 0xcc, 0x81, 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, + 0xb4, 0x81, 0x3d, 0xd0, 0x01, 0x1e, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, + 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x3d, 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, + 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x3d, 0xe4, 0x81, 0x1d, + 0xe8, 0x41, 0x1c, 0xc8, 0x01, 0x1e, 0xe8, 0x41, 0x1c, 0xc8, 0x01, 0x1e, + 0xb4, 0x81, 0x3d, 0xc4, 0x81, 0x1c, 0xe0, 0x81, 0x1e, 0xc4, 0x81, 0x1c, + 0xe0, 0x81, 0x1e, 0xc4, 0x81, 0x1c, 0xe0, 0x41, 0x1b, 0xd8, 0x43, 0x1c, + 0xe4, 0x81, 0x1c, 0xe8, 0x81, 0x1c, 0xd4, 0x81, 0x1d, 0xe8, 0x81, 0x1c, + 0xd4, 0x81, 0x1d, 0xb4, 0x81, 0x3d, 0xc8, 0x41, 0x1d, 0xd8, 0x81, 0x1e, + 0xc8, 0x41, 0x1d, 0xd8, 0x81, 0x1e, 0xc8, 0x41, 0x1d, 0xd8, 0x41, 0x1b, + 0xd8, 0x43, 0x1d, 0xc4, 0x81, 0x1c, 0xe8, 0x41, 0x1d, 0xc4, 0x81, 0x1c, + 0xe8, 0x41, 0x1d, 0xc4, 0x81, 0x1c, 0xb4, 0x81, 0x3d, 0xc4, 0x01, 0x1c, + 0xc8, 0x01, 0x1d, 0xe8, 0x41, 0x1c, 0xc0, 0x81, 0x1c, 0xd0, 0x81, 0x1e, + 0xc4, 0x01, 0x1c, 0xc8, 0x01, 0x1d, 0xb4, 0x81, 0x3b, 0xe0, 0x81, 0x1e, + 0xc4, 0x81, 0x1d, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x46, 0x08, 0x43, 0x4a, + 0x6c, 0x57, 0xfe, 0xac, 0xb3, 0x20, 0xc3, 0x5f, 0x44, 0x80, 0xc1, 0x10, + 0xcd, 0x34, 0x24, 0x02, 0xa4, 0x01, 0x00, 0x80, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x24, 0x36, 0x08, 0x14, 0x6d, 0x12, 0x00, 0x00, + 0xc8, 0x02, 0x01, 0x00, 0x07, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x0c, + 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0xb2, + 0x22, 0x28, 0x81, 0x42, 0x18, 0x01, 0xa0, 0x1b, 0x4b, 0x70, 0x06, 0x00, + 0xb1, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, + 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, + 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, + 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, + 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, + 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, + 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, + 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, + 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, + 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, + 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, + 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, + 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, + 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, + 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, + 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, + 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, + 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, + 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, + 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, + 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, + 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, + 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, + 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, + 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, + 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, + 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, + 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, + 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, + 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, + 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, + 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, + 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, + 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, + 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, + 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, + 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, + 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, + 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, + 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, + 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, + 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x79, 0x20, 0x00, 0x00, + 0x90, 0x00, 0x00, 0x00, 0x32, 0x9a, 0x08, 0x14, 0x02, 0x85, 0x8c, 0x27, + 0x46, 0x46, 0xc8, 0x11, 0x32, 0x64, 0xd4, 0x26, 0xc8, 0x56, 0x00, 0x00, + 0x8b, 0x02, 0x07, 0xc5, 0xc6, 0x91, 0x41, 0x14, 0x19, 0x52, 0xa6, 0x3c, + 0x06, 0x83, 0x58, 0x05, 0x53, 0x44, 0x4b, 0x20, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x77, 0x63, 0x68, 0x61, 0x72, 0x5f, 0x73, 0x69, 0x7a, + 0x65, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x4c, 0x4c, 0x56, 0x4d, 0x20, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x33, 0x31, 0x30, 0x30, + 0x31, 0x2e, 0x35, 0x30, 0x20, 0x28, 0x6d, 0x65, 0x74, 0x61, 0x6c, 0x66, + 0x65, 0x2d, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x2e, 0x31, + 0x29, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, + 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x64, 0x65, 0x6e, 0x6f, 0x72, 0x6d, + 0x73, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, + 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, + 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, + 0x2e, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, + 0x5f, 0x66, 0x65, 0x74, 0x63, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x61, 0x69, 0x72, 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x5f, + 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, + 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x66, + 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x61, 0x69, 0x72, 0x2e, 0x66, 0x72, 0x61, + 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x67, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x38, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x76, 0x32, 0x5f, 0x66, 0x29, + 0x61, 0x69, 0x72, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x61, 0x69, + 0x72, 0x2e, 0x70, 0x65, 0x72, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x61, 0x69, 0x72, 0x2e, 0x61, + 0x72, 0x67, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, + 0x28, 0x35, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x44, 0x76, 0x34, 0x5f, 0x66, + 0x29, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x23, 0x08, 0x46, 0x30, + 0x82, 0x70, 0x14, 0x23, 0x08, 0x86, 0x30, 0x82, 0x60, 0x0c, 0x23, 0x08, + 0x06, 0x31, 0x82, 0x40, 0x00, 0x33, 0x0c, 0x54, 0x50, 0xcd, 0x30, 0x58, + 0xc2, 0x35, 0x43, 0x30, 0xcc, 0x30, 0x50, 0x14, 0x36, 0x03, 0x41, 0x58, + 0x16, 0x36, 0x43, 0x50, 0xcc, 0x10, 0x18, 0x33, 0x04, 0xc7, 0x0c, 0x05, + 0x82, 0x61, 0x89, 0x32, 0x43, 0x20, 0x06, 0x33, 0x24, 0xd8, 0xc2, 0x34, + 0x4e, 0xf2, 0x40, 0xd1, 0x0c, 0x89, 0xb5, 0x48, 0x8d, 0x93, 0x28, 0xd0, + 0x34, 0x83, 0x40, 0x06, 0x65, 0x30, 0xc3, 0x90, 0x8d, 0x81, 0x19, 0xc8, + 0x48, 0x60, 0x82, 0x2e, 0x62, 0x63, 0xb3, 0x6b, 0x73, 0x69, 0x7b, 0x23, + 0xab, 0x63, 0x2b, 0x73, 0x31, 0x63, 0x0b, 0x3b, 0x9b, 0x1b, 0x45, 0xc8, + 0xb4, 0x53, 0xd8, 0xd8, 0xec, 0xda, 0x5c, 0xd2, 0xc8, 0xca, 0xdc, 0xe8, + 0x46, 0x09, 0xb6, 0x5b, 0xc2, 0xd2, 0xe4, 0x5c, 0xec, 0xca, 0xe4, 0xe6, + 0xd2, 0xde, 0xdc, 0x46, 0x09, 0xb8, 0xa3, 0xc2, 0xd2, 0xe4, 0x5c, 0xd8, + 0xc2, 0xdc, 0xce, 0xea, 0xc2, 0xce, 0xca, 0xbe, 0xec, 0xca, 0xe4, 0xe6, + 0xd2, 0xde, 0xdc, 0x46, 0x09, 0xba, 0x9b, 0xc2, 0xd2, 0xe4, 0x5c, 0xc6, + 0xde, 0xda, 0xe0, 0xd2, 0xd8, 0xca, 0xbe, 0xde, 0xe0, 0xe8, 0xd2, 0xde, + 0xdc, 0xe6, 0x46, 0x19, 0xbc, 0x0f, 0x0c, 0x8e, 0x09, 0x4b, 0x93, 0x73, + 0x31, 0x93, 0x0b, 0x3b, 0x6b, 0x2b, 0x73, 0xa3, 0x1b, 0x25, 0x30, 0x03, + 0x00, 0x00, 0x00, 0x00, 0xa9, 0x18, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0x0b, 0x0a, 0x72, 0x28, 0x87, 0x77, 0x80, 0x07, 0x7a, 0x58, 0x70, 0x98, + 0x43, 0x3d, 0xb8, 0xc3, 0x38, 0xb0, 0x43, 0x39, 0xd0, 0xc3, 0x82, 0xe6, + 0x1c, 0xc6, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0xc1, 0x1d, 0xe6, 0x21, + 0x1d, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x00, 0xd1, 0x10, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x07, 0xcc, 0x3c, 0xa4, 0x83, 0x3b, 0x9c, 0x03, + 0x3b, 0x94, 0x03, 0x3d, 0xa0, 0x83, 0x3c, 0x94, 0x43, 0x38, 0x90, 0xc3, + 0x01, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x13, 0x04, 0x41, 0x06, 0x00, 0x00, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x32, 0x0e, 0x10, 0x22, 0x84, 0x00, 0xc9, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x0c, 0x00, 0x00, + 0x1d, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0xe8, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x5d, 0x0c, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0x7c, + 0x00, 0x00, 0x00, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x53, 0x6f, 0x6c, 0x69, + 0x64, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x33, 0x31, + 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x2e, 0x31, 0x61, 0x69, 0x72, 0x36, + 0x34, 0x2d, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2d, 0x74, 0x76, 0x6f, 0x73, + 0x31, 0x33, 0x2e, 0x30, 0x2e, 0x30, 0x2d, 0x73, 0x69, 0x6d, 0x75, 0x6c, + 0x61, 0x74, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0xac, 0x0b, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, + 0x35, 0x14, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x62, 0x0c, 0x30, 0x24, + 0x80, 0x10, 0x05, 0xc8, 0x14, 0x00, 0x00, 0x00, 0x21, 0x0c, 0x00, 0x00, + 0xa3, 0x02, 0x00, 0x00, 0x0b, 0x02, 0x21, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, + 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, + 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, + 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88, + 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, + 0x04, 0x49, 0x0e, 0x90, 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, + 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, + 0x8a, 0x00, 0x00, 0x00, 0x1b, 0xcc, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, + 0x01, 0x58, 0x03, 0x40, 0x02, 0x2a, 0x62, 0x1c, 0xde, 0x41, 0x1e, 0xe4, + 0xa1, 0x1c, 0xc6, 0x81, 0x1e, 0xd8, 0x21, 0x1f, 0xda, 0x40, 0x1e, 0xde, + 0xa1, 0x1e, 0xdc, 0x81, 0x1c, 0xca, 0x81, 0x1c, 0xda, 0x80, 0x1c, 0xd2, + 0xc1, 0x1e, 0xd2, 0x81, 0x1c, 0xca, 0xa1, 0x0d, 0xe6, 0x21, 0x1e, 0xe4, + 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, + 0x01, 0x1d, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, + 0x72, 0x48, 0x87, 0x79, 0x08, 0x07, 0x71, 0x60, 0x87, 0x72, 0x68, 0x03, + 0x7a, 0x08, 0x87, 0x74, 0x60, 0x87, 0x36, 0x18, 0x87, 0x70, 0x60, 0x07, + 0x76, 0x98, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, + 0x82, 0x1d, 0xca, 0x61, 0x1e, 0xe6, 0xa1, 0x0d, 0xe0, 0x41, 0x1e, 0xca, + 0x61, 0x1c, 0xd2, 0x61, 0x1e, 0xca, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, + 0x21, 0x1c, 0xc8, 0x01, 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, + 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x73, 0x90, 0x87, 0x70, 0x68, 0x87, + 0x72, 0x68, 0x03, 0x78, 0x78, 0x87, 0x74, 0x70, 0x07, 0x7a, 0x28, 0x07, + 0x79, 0x68, 0x83, 0x72, 0x60, 0x87, 0x74, 0x68, 0x07, 0x80, 0x1e, 0xe4, + 0xa1, 0x1e, 0xca, 0x01, 0x18, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, + 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, + 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, + 0xa1, 0x0d, 0xdc, 0xe1, 0x1d, 0xdc, 0xa1, 0x0d, 0xd8, 0xa1, 0x1c, 0xc2, + 0xc1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xd2, 0xc1, 0x1d, 0xcc, + 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, + 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, + 0x77, 0x68, 0x03, 0x75, 0xa8, 0x87, 0x76, 0x80, 0x87, 0x36, 0xa0, 0x87, + 0x70, 0x10, 0x07, 0x76, 0x28, 0x87, 0x79, 0x00, 0xcc, 0x21, 0x1c, 0xd8, + 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1d, 0xc2, + 0xc1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, + 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, + 0x77, 0x78, 0x87, 0x36, 0x98, 0x87, 0x74, 0x38, 0x07, 0x77, 0x28, 0x07, + 0x72, 0x68, 0x03, 0x7d, 0x28, 0x07, 0x79, 0x78, 0x87, 0x79, 0x68, 0x03, + 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, + 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe8, + 0x41, 0x1e, 0xc2, 0x01, 0x1e, 0xe0, 0x21, 0x1d, 0xdc, 0xe1, 0x1c, 0xda, + 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, + 0x72, 0x00, 0x88, 0x79, 0xa0, 0x87, 0x70, 0x18, 0x87, 0x75, 0x68, 0x03, + 0x78, 0x90, 0x87, 0x77, 0xa0, 0x87, 0x72, 0x18, 0x07, 0x7a, 0x78, 0x07, + 0x79, 0x68, 0x03, 0x71, 0xa8, 0x07, 0x73, 0x30, 0x87, 0x72, 0x90, 0x87, + 0x36, 0x98, 0x87, 0x74, 0xd0, 0x87, 0x72, 0x00, 0xf0, 0x00, 0x20, 0xea, + 0xc1, 0x1d, 0xe6, 0x21, 0x1c, 0xcc, 0xa1, 0x1c, 0xda, 0xc0, 0x1c, 0xe0, + 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, + 0x7a, 0x28, 0x07, 0x80, 0xa8, 0x87, 0x79, 0x28, 0x87, 0x36, 0x98, 0x87, + 0x77, 0x30, 0x07, 0x7a, 0x68, 0x03, 0x73, 0x60, 0x87, 0x77, 0x08, 0x07, + 0x7a, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0xd8, 0x60, + 0x08, 0x04, 0xb0, 0x00, 0xd5, 0x06, 0x63, 0x28, 0x80, 0x05, 0xa8, 0x36, + 0x28, 0xc4, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x40, 0x1b, 0x00, 0x6b, 0x00, + 0x48, 0x40, 0xb5, 0xc1, 0x28, 0x02, 0x60, 0x01, 0xaa, 0x0d, 0x86, 0x21, + 0x00, 0x0b, 0x50, 0x01, 0x49, 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x13, 0x86, 0x40, 0x18, 0x26, 0x0c, 0x44, 0x61, 0x00, 0x00, 0x00, 0x00, + 0x89, 0x20, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, + 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, + 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, + 0x10, 0x4c, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, 0x00, 0x47, + 0x49, 0x53, 0x44, 0x09, 0x93, 0xff, 0x4f, 0xc4, 0x35, 0x51, 0x11, 0xf1, + 0xdb, 0xc3, 0x3f, 0x8d, 0x11, 0x00, 0x83, 0x08, 0x43, 0x70, 0x91, 0x34, + 0x45, 0x94, 0x30, 0xf9, 0xbf, 0x04, 0x30, 0xcf, 0x42, 0x44, 0xff, 0x34, + 0x46, 0x00, 0x0c, 0x22, 0x14, 0x42, 0x31, 0x42, 0x08, 0x82, 0x18, 0x3a, + 0x73, 0x04, 0x88, 0x11, 0x42, 0x9a, 0x23, 0x08, 0xe6, 0x08, 0xc0, 0x60, + 0x18, 0x41, 0x60, 0x8a, 0xa2, 0x88, 0x11, 0xab, 0x2d, 0x00, 0x18, 0xb9, + 0x81, 0x80, 0x14, 0x60, 0x23, 0x00, 0x00, 0x00, 0x13, 0xc0, 0x20, 0x1c, + 0xd2, 0x41, 0x1e, 0xec, 0x80, 0x0e, 0xda, 0x20, 0x1c, 0xe0, 0x01, 0x1e, + 0xd8, 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xec, 0xe1, 0x1d, 0xe6, 0x21, 0x0e, + 0xe6, 0xc0, 0x0d, 0xe0, 0xc0, 0x0d, 0xe0, 0xa0, 0x0d, 0xe6, 0x21, 0x1d, + 0xda, 0xa1, 0x1e, 0xd8, 0x21, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, 0x61, 0xc3, + 0x6d, 0x94, 0x43, 0x1b, 0xc0, 0x83, 0x1e, 0xd8, 0x01, 0x1d, 0xe8, 0x81, + 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x41, 0x3a, 0xc4, 0x81, + 0x1e, 0xe0, 0x81, 0x1e, 0xe0, 0x41, 0x1b, 0xa4, 0x03, 0x1e, 0xe8, 0x01, + 0x1e, 0xe8, 0x01, 0x1e, 0xb4, 0x41, 0x3a, 0xc4, 0x81, 0x1d, 0xe8, 0x41, + 0x1c, 0xd8, 0x81, 0x1e, 0xc4, 0x81, 0x1d, 0xb4, 0x41, 0x3a, 0xcc, 0x81, + 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x41, + 0x3a, 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, + 0x1d, 0xb4, 0x81, 0x39, 0xcc, 0x81, 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, + 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, 0x39, 0xd8, 0x01, 0x1d, 0xe8, 0x81, + 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x3d, 0xc4, 0x81, + 0x1d, 0xe8, 0x41, 0x1c, 0xd8, 0x81, 0x1e, 0xc4, 0x81, 0x1d, 0xb4, 0x81, + 0x3d, 0xc8, 0x01, 0x1d, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, + 0x1c, 0xb4, 0x81, 0x3d, 0xcc, 0x81, 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, + 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, 0x3d, 0xd0, 0x01, 0x1e, 0xe8, 0x81, + 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x3d, 0xd8, 0x01, + 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, + 0x3d, 0xe4, 0x81, 0x1d, 0xe8, 0x41, 0x1c, 0xc8, 0x01, 0x1e, 0xe8, 0x41, + 0x1c, 0xc8, 0x01, 0x1e, 0xb4, 0x81, 0x3d, 0xc4, 0x81, 0x1c, 0xe0, 0x81, + 0x1e, 0xc4, 0x81, 0x1c, 0xe0, 0x81, 0x1e, 0xc4, 0x81, 0x1c, 0xe0, 0x41, + 0x1b, 0xd8, 0x43, 0x1c, 0xe4, 0x81, 0x1c, 0xe8, 0x81, 0x1c, 0xd4, 0x81, + 0x1d, 0xe8, 0x81, 0x1c, 0xd4, 0x81, 0x1d, 0xb4, 0x81, 0x3d, 0xc8, 0x41, + 0x1d, 0xd8, 0x81, 0x1e, 0xc8, 0x41, 0x1d, 0xd8, 0x81, 0x1e, 0xc8, 0x41, + 0x1d, 0xd8, 0x41, 0x1b, 0xd8, 0x43, 0x1d, 0xc4, 0x81, 0x1c, 0xe8, 0x41, + 0x1d, 0xc4, 0x81, 0x1c, 0xe8, 0x41, 0x1d, 0xc4, 0x81, 0x1c, 0xb4, 0x81, + 0x3d, 0xc4, 0x01, 0x1c, 0xc8, 0x01, 0x1d, 0xe8, 0x41, 0x1c, 0xc0, 0x81, + 0x1c, 0xd0, 0x81, 0x1e, 0xc4, 0x01, 0x1c, 0xc8, 0x01, 0x1d, 0xb4, 0x81, + 0x3b, 0xe0, 0x81, 0x1e, 0xc4, 0x81, 0x1d, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, + 0x46, 0x08, 0x43, 0x46, 0x6c, 0x57, 0xfe, 0x9c, 0xf3, 0x60, 0x7f, 0x11, + 0x01, 0x06, 0x43, 0x34, 0xd3, 0x90, 0x08, 0x88, 0x0e, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x18, 0x12, 0x45, 0x9b, 0x03, + 0x04, 0x80, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x12, 0x1b, + 0x04, 0x8a, 0x96, 0x0a, 0x00, 0x00, 0x64, 0x81, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, + 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x62, 0x45, 0x50, 0x02, 0x85, + 0x30, 0x02, 0x50, 0x06, 0x14, 0xc7, 0x12, 0x9c, 0x01, 0x00, 0x00, 0x00, + 0xb1, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, + 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, + 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, + 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, + 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, + 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, + 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, + 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, + 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, + 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, + 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, + 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, + 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, + 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, + 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, + 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, + 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, + 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, + 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, + 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, + 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, + 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, + 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, + 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, + 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, + 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, + 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, + 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, + 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, + 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, + 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, + 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, + 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, + 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, + 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, + 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, + 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, + 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, + 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, + 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, + 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, + 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x79, 0x20, 0x00, 0x00, + 0xbe, 0x00, 0x00, 0x00, 0x32, 0x9a, 0x08, 0x14, 0x02, 0x85, 0x8c, 0x27, + 0x46, 0x46, 0xc8, 0x11, 0x32, 0x64, 0xd4, 0x3c, 0x2c, 0x77, 0x00, 0x00, + 0x8b, 0x02, 0x07, 0xc5, 0xc6, 0x91, 0x41, 0x14, 0x19, 0x8c, 0x22, 0x31, + 0x88, 0x64, 0x3d, 0x45, 0x66, 0x20, 0x8b, 0xa4, 0x60, 0xc3, 0x72, 0x04, + 0x53, 0x44, 0x4b, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x77, + 0x63, 0x68, 0x61, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x41, 0x70, 0x70, + 0x6c, 0x65, 0x20, 0x4c, 0x4c, 0x56, 0x4d, 0x20, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x20, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, + 0x20, 0x28, 0x6d, 0x65, 0x74, 0x61, 0x6c, 0x66, 0x65, 0x2d, 0x33, 0x31, + 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x2e, 0x31, 0x29, 0x4d, 0x65, 0x74, + 0x61, 0x6c, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, + 0x65, 0x2e, 0x64, 0x65, 0x6e, 0x6f, 0x72, 0x6d, 0x73, 0x5f, 0x64, 0x69, + 0x73, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, + 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, + 0x74, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, + 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x72, 0x61, + 0x6d, 0x65, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x66, 0x65, 0x74, + 0x63, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, + 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x5f, 0x74, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x66, 0x6c, 0x6f, 0x61, 0x74, + 0x34, 0x61, 0x69, 0x72, 0x2e, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x61, + 0x69, 0x72, 0x2e, 0x6e, 0x6f, 0x5f, 0x70, 0x65, 0x72, 0x73, 0x70, 0x65, + 0x63, 0x74, 0x69, 0x76, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x69, 0x72, 0x2e, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, + 0x74, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x67, 0x65, 0x6e, 0x65, 0x72, + 0x61, 0x74, 0x65, 0x64, 0x28, 0x35, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x44, + 0x76, 0x34, 0x5f, 0x66, 0x29, 0x61, 0x69, 0x72, 0x2e, 0x70, 0x65, 0x72, + 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x38, + 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x44, 0x76, 0x32, 0x5f, + 0x66, 0x29, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x74, 0x65, 0x78, 0x63, + 0x6f, 0x6f, 0x72, 0x64, 0x61, 0x69, 0x72, 0x2e, 0x74, 0x65, 0x78, 0x74, + 0x75, 0x72, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x61, 0x69, 0x72, + 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x78, 0x74, 0x75, + 0x72, 0x65, 0x32, 0x64, 0x3c, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x2c, 0x20, + 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x3e, 0x74, 0x65, 0x78, 0x61, 0x69, + 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x73, 0x61, 0x6d, + 0x70, 0x6c, 0x65, 0x72, 0x73, 0x00, 0x00, 0x00, 0x23, 0x08, 0x8c, 0x30, + 0x82, 0x10, 0x1d, 0x23, 0x08, 0xcc, 0x30, 0x82, 0xc0, 0x10, 0x23, 0x08, + 0x4c, 0x31, 0x82, 0x80, 0x00, 0x23, 0x08, 0x8c, 0x31, 0xc3, 0xf0, 0x05, + 0x60, 0x30, 0xc3, 0x10, 0x06, 0x82, 0x18, 0xcc, 0x10, 0x0c, 0x33, 0x0c, + 0xdf, 0x37, 0x06, 0x33, 0x10, 0x44, 0x18, 0x84, 0xc1, 0x18, 0xcc, 0x10, + 0x14, 0x33, 0x04, 0xc6, 0x0c, 0xc1, 0x31, 0x43, 0x81, 0x8c, 0xc1, 0x18, + 0x24, 0xca, 0x0c, 0x81, 0x1b, 0xcc, 0x80, 0x8c, 0xc1, 0xc2, 0x34, 0x89, + 0xe2, 0x3c, 0x33, 0x24, 0x61, 0x00, 0x45, 0x8c, 0x94, 0x28, 0xce, 0x34, + 0x43, 0xf2, 0x41, 0x14, 0x23, 0x25, 0x95, 0x63, 0xcd, 0xa0, 0x94, 0xc1, + 0x85, 0x8d, 0x41, 0x18, 0x64, 0x89, 0xe6, 0x6c, 0x33, 0x24, 0x62, 0xc0, + 0x61, 0x63, 0x10, 0x06, 0x49, 0xe7, 0x78, 0x33, 0x14, 0x70, 0x10, 0x07, + 0x72, 0x30, 0x07, 0x74, 0x30, 0xc3, 0x40, 0x06, 0x6f, 0x50, 0x07, 0x32, + 0x12, 0x98, 0xa0, 0x8b, 0xd8, 0xd8, 0xec, 0xda, 0x5c, 0xda, 0xde, 0xc8, + 0xea, 0xd8, 0xca, 0x5c, 0xcc, 0xd8, 0xc2, 0xce, 0xe6, 0x46, 0x11, 0xca, + 0xc0, 0x0c, 0x4e, 0x61, 0x63, 0xb3, 0x6b, 0x73, 0x49, 0x23, 0x2b, 0x73, + 0xa3, 0x1b, 0x25, 0x38, 0x83, 0x5b, 0xc2, 0xd2, 0xe4, 0x5c, 0xec, 0xca, + 0xe4, 0xe6, 0xd2, 0xde, 0xdc, 0x46, 0x09, 0xd0, 0xe0, 0xa8, 0xb0, 0x34, + 0x39, 0x17, 0xb6, 0x30, 0xb7, 0xb3, 0xba, 0xb0, 0xb3, 0xb2, 0x2f, 0xbb, + 0x32, 0xb9, 0xb9, 0xb4, 0x37, 0xb7, 0x51, 0x82, 0x34, 0xb8, 0x29, 0x2c, + 0x4d, 0xce, 0x65, 0xec, 0xad, 0x0d, 0x2e, 0x8d, 0xad, 0xec, 0xeb, 0x0d, + 0x8e, 0x2e, 0xed, 0xcd, 0x6d, 0x6e, 0x94, 0x41, 0x0d, 0xd6, 0x80, 0x0d, + 0x8e, 0x09, 0x4b, 0x93, 0x73, 0x31, 0x93, 0x0b, 0x3b, 0x6b, 0x2b, 0x73, + 0xa3, 0x1b, 0x25, 0xa8, 0x03, 0x00, 0x00, 0x00, 0xa9, 0x18, 0x00, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x0a, 0x72, 0x28, 0x87, 0x77, 0x80, 0x07, + 0x7a, 0x58, 0x70, 0x98, 0x43, 0x3d, 0xb8, 0xc3, 0x38, 0xb0, 0x43, 0x39, + 0xd0, 0xc3, 0x82, 0xe6, 0x1c, 0xc6, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, + 0xc1, 0x1d, 0xe6, 0x21, 0x1d, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x00, + 0xd1, 0x10, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0xcc, 0x3c, 0xa4, + 0x83, 0x3b, 0x9c, 0x03, 0x3b, 0x94, 0x03, 0x3d, 0xa0, 0x83, 0x3c, 0x94, + 0x43, 0x38, 0x90, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0xb4, 0x6a, 0x60, 0x04, 0x80, 0xda, 0x08, 0x00, + 0x81, 0x11, 0x00, 0x00, 0x23, 0x06, 0x8d, 0x10, 0x82, 0x60, 0xe0, 0x40, + 0x46, 0x71, 0x10, 0xc2, 0x10, 0x04, 0xcc, 0x68, 0x42, 0x00, 0x58, 0xa0, + 0x88, 0x7f, 0x06, 0x00, 0x71, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x32, 0x0e, 0x10, 0x22, 0x84, 0x00, 0x97, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x65, 0x0c, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, + 0x12, 0x03, 0x94, 0x20, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x2c, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x24, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x08, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, 0x0c, 0x00, 0x00, + 0x19, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0xb6, 0x00, 0x00, 0x00, 0x00, + 0x53, 0x44, 0x4c, 0x5f, 0x43, 0x6f, 0x70, 0x79, 0x5f, 0x66, 0x72, 0x61, + 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x69, 0x72, 0x2e, 0x73, 0x61, 0x6d, + 0x70, 0x6c, 0x65, 0x5f, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x5f, + 0x32, 0x64, 0x2e, 0x76, 0x34, 0x66, 0x33, 0x32, 0x33, 0x31, 0x30, 0x30, + 0x31, 0x2e, 0x35, 0x30, 0x2e, 0x31, 0x61, 0x69, 0x72, 0x36, 0x34, 0x2d, + 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2d, 0x74, 0x76, 0x6f, 0x73, 0x31, 0x33, + 0x2e, 0x30, 0x2e, 0x30, 0x2d, 0x73, 0x69, 0x6d, 0x75, 0x6c, 0x61, 0x74, + 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, + 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xbc, 0x0e, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x35, 0x14, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x62, 0x0c, 0x30, 0x24, 0x80, 0x10, 0x05, 0xc8, + 0x14, 0x00, 0x00, 0x00, 0x21, 0x0c, 0x00, 0x00, 0x50, 0x03, 0x00, 0x00, + 0x0b, 0x02, 0x21, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, + 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, + 0x80, 0x18, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xc4, 0x10, 0x32, 0x14, + 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x62, 0x88, 0x48, 0x90, 0x14, 0x20, + 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0x04, 0x49, 0x0e, 0x90, + 0x11, 0x23, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, + 0x04, 0x31, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, + 0x1b, 0xcc, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x58, 0x03, 0x40, + 0x02, 0x2a, 0x62, 0x1c, 0xde, 0x41, 0x1e, 0xe4, 0xa1, 0x1c, 0xc6, 0x81, + 0x1e, 0xd8, 0x21, 0x1f, 0xda, 0x40, 0x1e, 0xde, 0xa1, 0x1e, 0xdc, 0x81, + 0x1c, 0xca, 0x81, 0x1c, 0xda, 0x80, 0x1c, 0xd2, 0xc1, 0x1e, 0xd2, 0x81, + 0x1c, 0xca, 0xa1, 0x0d, 0xe6, 0x21, 0x1e, 0xe4, 0x81, 0x1e, 0xda, 0xc0, + 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x73, + 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x72, 0x48, 0x87, 0x79, + 0x08, 0x07, 0x71, 0x60, 0x87, 0x72, 0x68, 0x03, 0x7a, 0x08, 0x87, 0x74, + 0x60, 0x87, 0x36, 0x18, 0x87, 0x70, 0x60, 0x07, 0x76, 0x98, 0x07, 0xc0, + 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1d, 0xca, 0x61, + 0x1e, 0xe6, 0xa1, 0x0d, 0xe0, 0x41, 0x1e, 0xca, 0x61, 0x1c, 0xd2, 0x61, + 0x1e, 0xca, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0x21, 0x1c, 0xc8, 0x01, + 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, + 0x68, 0x03, 0x73, 0x90, 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, 0x78, + 0x78, 0x87, 0x74, 0x70, 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, 0x72, + 0x60, 0x87, 0x74, 0x68, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, + 0x18, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1, + 0x1c, 0xda, 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, + 0x1e, 0xda, 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, 0xa1, 0x0d, 0xdc, 0xe1, + 0x1d, 0xdc, 0xa1, 0x0d, 0xd8, 0xa1, 0x1c, 0xc2, 0xc1, 0x1c, 0x00, 0xc2, + 0x1d, 0xde, 0xa1, 0x0d, 0xd2, 0xc1, 0x1d, 0xcc, 0x61, 0x1e, 0xda, 0xc0, + 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, + 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x75, + 0xa8, 0x87, 0x76, 0x80, 0x87, 0x36, 0xa0, 0x87, 0x70, 0x10, 0x07, 0x76, + 0x28, 0x87, 0x79, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, + 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1d, 0xc2, 0xc1, 0x1d, 0xe6, 0xa1, + 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, + 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, + 0x98, 0x87, 0x74, 0x38, 0x07, 0x77, 0x28, 0x07, 0x72, 0x68, 0x03, 0x7d, + 0x28, 0x07, 0x79, 0x78, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, + 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, + 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0x01, + 0x1e, 0xe0, 0x21, 0x1d, 0xdc, 0xe1, 0x1c, 0xda, 0xa0, 0x1d, 0xc2, 0x81, + 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x88, 0x79, + 0xa0, 0x87, 0x70, 0x18, 0x87, 0x75, 0x68, 0x03, 0x78, 0x90, 0x87, 0x77, + 0xa0, 0x87, 0x72, 0x18, 0x07, 0x7a, 0x78, 0x07, 0x79, 0x68, 0x03, 0x71, + 0xa8, 0x07, 0x73, 0x30, 0x87, 0x72, 0x90, 0x87, 0x36, 0x98, 0x87, 0x74, + 0xd0, 0x87, 0x72, 0x00, 0xf0, 0x00, 0x20, 0xea, 0xc1, 0x1d, 0xe6, 0x21, + 0x1c, 0xcc, 0xa1, 0x1c, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, + 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, + 0xa8, 0x87, 0x79, 0x28, 0x87, 0x36, 0x98, 0x87, 0x77, 0x30, 0x07, 0x7a, + 0x68, 0x03, 0x73, 0x60, 0x87, 0x77, 0x08, 0x07, 0x7a, 0x00, 0xcc, 0x21, + 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0xd8, 0xb0, 0x08, 0x04, 0x90, 0x00, + 0x0b, 0x50, 0x05, 0x69, 0x00, 0x0a, 0x1b, 0x8c, 0xa1, 0x00, 0x16, 0xa0, + 0xda, 0x60, 0x10, 0x07, 0xb0, 0x00, 0xd5, 0x06, 0xa3, 0xf8, 0xff, 0xff, + 0xff, 0xff, 0x01, 0x90, 0x00, 0x6a, 0x83, 0x62, 0xfc, 0xff, 0xff, 0xff, + 0xff, 0x00, 0xb4, 0x01, 0xb0, 0x06, 0x80, 0x04, 0x54, 0x1b, 0x8c, 0x23, + 0x00, 0x16, 0xa0, 0xda, 0x60, 0x20, 0x02, 0xb0, 0x00, 0x15, 0x00, 0x00, + 0x49, 0x18, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x88, 0x40, 0x18, + 0x88, 0x09, 0x41, 0x31, 0x61, 0x30, 0x0e, 0x04, 0x89, 0x20, 0x00, 0x00, + 0x34, 0x00, 0x00, 0x00, 0x32, 0x22, 0x88, 0x09, 0x20, 0x64, 0x85, 0x04, + 0x13, 0x23, 0xa4, 0x84, 0x04, 0x13, 0x23, 0xe3, 0x84, 0xa1, 0x90, 0x14, + 0x12, 0x4c, 0x8c, 0x8c, 0x0b, 0x84, 0xc4, 0x4c, 0x10, 0x80, 0xc1, 0x0c, + 0xc0, 0x30, 0x02, 0x01, 0x0c, 0x23, 0x08, 0xc0, 0x30, 0xc2, 0x00, 0x1c, + 0x24, 0x4d, 0x11, 0x25, 0x4c, 0xbe, 0xec, 0xbe, 0x1d, 0x21, 0x38, 0x03, + 0x81, 0x88, 0x61, 0x18, 0x86, 0x41, 0x04, 0x42, 0x38, 0x4a, 0x9a, 0x22, + 0x4a, 0x98, 0xfc, 0x7f, 0x22, 0xae, 0x89, 0x8a, 0x88, 0xdf, 0x1e, 0xfe, + 0x69, 0x8c, 0x00, 0x18, 0x44, 0x30, 0x82, 0xd3, 0xa4, 0x29, 0xa2, 0x84, + 0xc9, 0xff, 0x27, 0xe2, 0x9a, 0xa8, 0x88, 0xf8, 0xed, 0xe1, 0x07, 0xa2, + 0x08, 0xc0, 0xfe, 0x69, 0x8c, 0x00, 0x18, 0x44, 0x40, 0x82, 0x8b, 0xa4, + 0x29, 0xa2, 0x84, 0xc9, 0xff, 0x25, 0x80, 0x79, 0x16, 0x22, 0xfa, 0xa7, + 0x31, 0x02, 0x60, 0x10, 0x41, 0x11, 0x0a, 0x12, 0x04, 0x81, 0x50, 0x1c, + 0xc9, 0x42, 0x4c, 0x19, 0x80, 0x61, 0x20, 0x67, 0x8e, 0x00, 0x31, 0x42, + 0x00, 0xcd, 0x11, 0x80, 0xc1, 0x1c, 0x41, 0x30, 0x8c, 0x20, 0x48, 0x65, + 0x89, 0x92, 0x45, 0x90, 0x26, 0x6a, 0x02, 0x00, 0x89, 0xaa, 0xa2, 0x44, + 0xc7, 0x22, 0x4c, 0xd4, 0x04, 0x00, 0x12, 0x5d, 0x03, 0x01, 0x29, 0x20, + 0x0d, 0x23, 0x0c, 0xd2, 0x1c, 0x01, 0x28, 0x0c, 0x22, 0x04, 0xc2, 0x20, + 0xc2, 0x20, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xc0, 0x20, 0x1c, + 0xd2, 0x41, 0x1e, 0xec, 0x80, 0x0e, 0xda, 0x20, 0x1c, 0xe0, 0x01, 0x1e, + 0xd8, 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xec, 0xe1, 0x1d, 0xe6, 0x21, 0x0e, + 0xe6, 0xc0, 0x0d, 0xe0, 0xc0, 0x0d, 0xe0, 0xa0, 0x0d, 0xe6, 0x21, 0x1d, + 0xda, 0xa1, 0x1e, 0xd8, 0x21, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, 0x61, 0xc3, + 0x6d, 0x94, 0x43, 0x1b, 0xc0, 0x83, 0x1e, 0xd8, 0x01, 0x1d, 0xe8, 0x81, + 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x41, 0x3a, 0xc4, 0x81, + 0x1e, 0xe0, 0x81, 0x1e, 0xe0, 0x41, 0x1b, 0xa4, 0x03, 0x1e, 0xe8, 0x01, + 0x1e, 0xe8, 0x01, 0x1e, 0xb4, 0x41, 0x3a, 0xc4, 0x81, 0x1d, 0xe8, 0x41, + 0x1c, 0xd8, 0x81, 0x1e, 0xc4, 0x81, 0x1d, 0xb4, 0x41, 0x3a, 0xcc, 0x81, + 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x41, + 0x3a, 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, + 0x1d, 0xb4, 0x81, 0x39, 0xcc, 0x81, 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, + 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, 0x39, 0xd8, 0x01, 0x1d, 0xe8, 0x81, + 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x3d, 0xc4, 0x81, + 0x1d, 0xe8, 0x41, 0x1c, 0xd8, 0x81, 0x1e, 0xc4, 0x81, 0x1d, 0xb4, 0x81, + 0x3d, 0xc8, 0x01, 0x1d, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, + 0x1c, 0xb4, 0x81, 0x3d, 0xcc, 0x81, 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, + 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, 0x3d, 0xd0, 0x01, 0x1e, 0xe8, 0x81, + 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x3d, 0xd8, 0x01, + 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, + 0x3d, 0xe4, 0x81, 0x1d, 0xe8, 0x41, 0x1c, 0xc8, 0x01, 0x1e, 0xe8, 0x41, + 0x1c, 0xc8, 0x01, 0x1e, 0xb4, 0x81, 0x3d, 0xc4, 0x81, 0x1c, 0xe0, 0x81, + 0x1e, 0xc4, 0x81, 0x1c, 0xe0, 0x81, 0x1e, 0xc4, 0x81, 0x1c, 0xe0, 0x41, + 0x1b, 0xd8, 0x43, 0x1c, 0xe4, 0x81, 0x1c, 0xe8, 0x81, 0x1c, 0xd4, 0x81, + 0x1d, 0xe8, 0x81, 0x1c, 0xd4, 0x81, 0x1d, 0xb4, 0x81, 0x3d, 0xc8, 0x41, + 0x1d, 0xd8, 0x81, 0x1e, 0xc8, 0x41, 0x1d, 0xd8, 0x81, 0x1e, 0xc8, 0x41, + 0x1d, 0xd8, 0x41, 0x1b, 0xd8, 0x43, 0x1d, 0xc4, 0x81, 0x1c, 0xe8, 0x41, + 0x1d, 0xc4, 0x81, 0x1c, 0xe8, 0x41, 0x1d, 0xc4, 0x81, 0x1c, 0xb4, 0x81, + 0x3d, 0xc4, 0x01, 0x1c, 0xc8, 0x01, 0x1d, 0xe8, 0x41, 0x1c, 0xc0, 0x81, + 0x1c, 0xd0, 0x81, 0x1e, 0xc4, 0x01, 0x1c, 0xc8, 0x01, 0x1d, 0xb4, 0x81, + 0x3b, 0xe0, 0x81, 0x1e, 0xc4, 0x81, 0x1d, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, + 0x46, 0x08, 0x43, 0x42, 0x6c, 0x57, 0xfe, 0xb2, 0xfb, 0xfe, 0x45, 0x04, + 0x18, 0x0c, 0xd1, 0x4c, 0x43, 0x22, 0x00, 0x62, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x60, 0x48, 0x04, 0x35, 0x0e, 0x10, + 0x00, 0x02, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x89, 0xba, + 0x30, 0xa8, 0x80, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x60, 0x48, 0xe4, 0x07, 0xdb, 0x05, 0x04, 0xc0, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x12, 0x1b, 0x04, 0x8a, 0x4a, 0x0d, 0x00, 0x00, + 0x64, 0x81, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x14, + 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x92, + 0x8a, 0xa0, 0x04, 0x0a, 0x61, 0x04, 0xa0, 0x0c, 0x0a, 0x30, 0xa0, 0x40, + 0x0a, 0xa8, 0xc0, 0x4a, 0xa1, 0x18, 0x48, 0x1b, 0x4b, 0x70, 0x06, 0x00, + 0xb1, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, + 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, + 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, + 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, + 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, + 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, + 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, + 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, + 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, + 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, + 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, + 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, + 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, + 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, + 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, + 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, + 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, + 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, + 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, + 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, + 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, + 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, + 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, + 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, + 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, + 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, + 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, + 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, + 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, + 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, + 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, + 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, + 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, + 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, + 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, + 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, + 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, + 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, + 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, + 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, + 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, + 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x79, 0x20, 0x00, 0x00, + 0x10, 0x01, 0x00, 0x00, 0x32, 0x9a, 0x08, 0x14, 0x02, 0x85, 0x8c, 0x27, + 0x46, 0x46, 0xc8, 0x11, 0x32, 0x64, 0xd4, 0xda, 0x80, 0x0c, 0x66, 0x0a, + 0x8b, 0x02, 0x07, 0xc5, 0xc6, 0x91, 0x41, 0x14, 0x19, 0x8c, 0x22, 0x31, + 0x88, 0x64, 0x3d, 0x45, 0x66, 0x20, 0xca, 0x23, 0x21, 0x94, 0x61, 0x18, + 0x86, 0x11, 0x5d, 0x89, 0xb1, 0x28, 0x18, 0xe1, 0x15, 0xcb, 0x11, 0x00, + 0x53, 0x44, 0x4b, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x77, + 0x63, 0x68, 0x61, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x41, 0x70, 0x70, + 0x6c, 0x65, 0x20, 0x4c, 0x4c, 0x56, 0x4d, 0x20, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x20, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, + 0x20, 0x28, 0x6d, 0x65, 0x74, 0x61, 0x6c, 0x66, 0x65, 0x2d, 0x33, 0x31, + 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x2e, 0x31, 0x29, 0x4d, 0x65, 0x74, + 0x61, 0x6c, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, + 0x65, 0x2e, 0x64, 0x65, 0x6e, 0x6f, 0x72, 0x6d, 0x73, 0x5f, 0x64, 0x69, + 0x73, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, + 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, + 0x74, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, + 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x72, 0x61, + 0x6d, 0x65, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x66, 0x65, 0x74, + 0x63, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, + 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x5f, 0x74, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x66, 0x6c, 0x6f, 0x61, 0x74, + 0x34, 0x61, 0x69, 0x72, 0x2e, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x61, + 0x69, 0x72, 0x2e, 0x6e, 0x6f, 0x5f, 0x70, 0x65, 0x72, 0x73, 0x70, 0x65, + 0x63, 0x74, 0x69, 0x76, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x69, 0x72, 0x2e, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, + 0x74, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x67, 0x65, 0x6e, 0x65, 0x72, + 0x61, 0x74, 0x65, 0x64, 0x28, 0x35, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x44, + 0x76, 0x34, 0x5f, 0x66, 0x29, 0x61, 0x69, 0x72, 0x2e, 0x70, 0x65, 0x72, + 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x38, + 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x44, 0x76, 0x32, 0x5f, + 0x66, 0x29, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x74, 0x65, 0x78, 0x63, + 0x6f, 0x6f, 0x72, 0x64, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, + 0x65, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, + 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x6c, 0x6f, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x61, + 0x69, 0x72, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x61, 0x69, 0x72, 0x2e, 0x73, + 0x74, 0x72, 0x75, 0x63, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x69, + 0x6e, 0x66, 0x6f, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x6f, 0x66, 0x66, + 0x73, 0x65, 0x74, 0x52, 0x63, 0x6f, 0x65, 0x66, 0x66, 0x47, 0x63, 0x6f, + 0x65, 0x66, 0x66, 0x42, 0x63, 0x6f, 0x65, 0x66, 0x66, 0x61, 0x69, 0x72, + 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x73, 0x69, + 0x7a, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x5f, 0x73, 0x69, 0x7a, + 0x65, 0x59, 0x55, 0x56, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x65, + 0x63, 0x6f, 0x64, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x74, 0x65, 0x78, 0x74, + 0x75, 0x72, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, + 0x65, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x32, 0x64, 0x3c, 0x66, + 0x6c, 0x6f, 0x61, 0x74, 0x2c, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, + 0x3e, 0x74, 0x65, 0x78, 0x59, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, + 0x32, 0x64, 0x5f, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3c, 0x66, 0x6c, 0x6f, + 0x61, 0x74, 0x2c, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x3e, 0x74, + 0x65, 0x78, 0x55, 0x56, 0x61, 0x69, 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, + 0x6c, 0x65, 0x72, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x73, 0x00, + 0x44, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x82, 0x20, 0x11, + 0x23, 0x08, 0xda, 0x33, 0x82, 0x20, 0x15, 0x23, 0x08, 0x92, 0x31, 0x82, + 0x20, 0x1d, 0x23, 0x08, 0x0d, 0x30, 0x82, 0x20, 0x21, 0x23, 0x08, 0x52, + 0x32, 0x82, 0x20, 0x29, 0x23, 0x08, 0xd2, 0x32, 0x82, 0x20, 0x31, 0x23, + 0x08, 0x52, 0x33, 0x82, 0x20, 0x39, 0x33, 0x0c, 0x6e, 0x10, 0xbc, 0xc1, + 0x0c, 0x03, 0x1c, 0x08, 0x71, 0x30, 0x43, 0x30, 0xcc, 0x30, 0xb8, 0x81, + 0x1b, 0xc8, 0xc1, 0x0c, 0x04, 0x01, 0x07, 0x70, 0x20, 0x07, 0x33, 0x04, + 0xc5, 0x0c, 0x81, 0x31, 0x43, 0x70, 0xcc, 0x50, 0x20, 0x72, 0x20, 0x07, + 0x89, 0x32, 0x43, 0x30, 0x0a, 0x33, 0x20, 0x72, 0xb0, 0x30, 0x4d, 0xa2, + 0x38, 0xcf, 0x0c, 0x09, 0x1c, 0x40, 0x11, 0x23, 0x25, 0x8a, 0x33, 0xcd, + 0x90, 0xb8, 0x01, 0x44, 0x31, 0x52, 0x52, 0x39, 0xd6, 0x0c, 0x94, 0x1c, + 0xd8, 0x81, 0x1c, 0x70, 0x9d, 0x1d, 0xd8, 0x81, 0x1c, 0x70, 0xde, 0x1d, + 0xd8, 0x81, 0x1c, 0x70, 0x1f, 0x1e, 0xd8, 0x81, 0x1c, 0x70, 0x60, 0x30, + 0x83, 0x44, 0x07, 0x17, 0x56, 0x07, 0x19, 0x1c, 0xc0, 0x81, 0xb6, 0xa1, + 0x42, 0x18, 0xd4, 0x81, 0x18, 0xd8, 0x41, 0x32, 0x06, 0x0e, 0x19, 0xcc, + 0xa0, 0xc4, 0x41, 0x19, 0x64, 0x72, 0x00, 0x07, 0x66, 0x90, 0x9c, 0x81, + 0x83, 0x06, 0x33, 0x28, 0x79, 0x50, 0x06, 0x19, 0x1c, 0xc0, 0x81, 0x19, + 0x24, 0x69, 0xe0, 0xa8, 0xc1, 0x0c, 0x89, 0x1e, 0xac, 0x41, 0x26, 0x07, + 0x70, 0x90, 0xb0, 0x81, 0xd3, 0x06, 0x33, 0x1c, 0xa5, 0x60, 0x0a, 0xa7, + 0x90, 0x0a, 0xaa, 0xb0, 0x0a, 0xac, 0x30, 0xc3, 0x30, 0x07, 0xa4, 0xd0, + 0x0a, 0x15, 0x06, 0x00, 0xc7, 0x71, 0x1c, 0xc7, 0x71, 0x1c, 0xc7, 0x71, + 0x1c, 0xe7, 0x06, 0x6e, 0x60, 0xd1, 0x81, 0x1e, 0x58, 0x96, 0xa5, 0x07, + 0x9c, 0x29, 0xb0, 0x02, 0x2b, 0xd8, 0x86, 0x5f, 0xd8, 0x83, 0x3d, 0xa8, + 0x03, 0x39, 0xc8, 0x48, 0x60, 0x82, 0x2e, 0x62, 0x63, 0xb3, 0x6b, 0x73, + 0x69, 0x7b, 0x23, 0xab, 0x63, 0x2b, 0x73, 0x31, 0x63, 0x0b, 0x3b, 0x9b, + 0x1b, 0x45, 0xd0, 0x83, 0x3d, 0x38, 0x85, 0x8d, 0xcd, 0xae, 0xcd, 0x25, + 0x8d, 0xac, 0xcc, 0x8d, 0x6e, 0x94, 0x80, 0x0f, 0x6e, 0x09, 0x4b, 0x93, + 0x73, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, 0x1b, 0x25, 0xe8, 0x83, + 0xa3, 0xc2, 0xd2, 0xe4, 0x5c, 0xd8, 0xc2, 0xdc, 0xce, 0xea, 0xc2, 0xce, + 0xca, 0xbe, 0xec, 0xca, 0xe4, 0xe6, 0xd2, 0xde, 0xdc, 0x46, 0x09, 0xfc, + 0xe0, 0xa6, 0xb0, 0x34, 0x39, 0x97, 0xb1, 0xb7, 0x36, 0xb8, 0x34, 0xb6, + 0xb2, 0xaf, 0x37, 0x38, 0xba, 0xb4, 0x37, 0xb7, 0xb9, 0x51, 0x86, 0x3f, + 0x00, 0x85, 0x50, 0x38, 0x26, 0x2c, 0x4d, 0xce, 0xc5, 0x4c, 0x2e, 0xec, + 0xac, 0xad, 0xcc, 0x8d, 0x6e, 0x94, 0xa0, 0x15, 0x00, 0x00, 0x00, 0x00, + 0xa9, 0x18, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x0a, 0x72, 0x28, + 0x87, 0x77, 0x80, 0x07, 0x7a, 0x58, 0x70, 0x98, 0x43, 0x3d, 0xb8, 0xc3, + 0x38, 0xb0, 0x43, 0x39, 0xd0, 0xc3, 0x82, 0xe6, 0x1c, 0xc6, 0xa1, 0x0d, + 0xe8, 0x41, 0x1e, 0xc2, 0xc1, 0x1d, 0xe6, 0x21, 0x1d, 0xe8, 0x21, 0x1d, + 0xde, 0xc1, 0x1d, 0x00, 0xd1, 0x10, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x07, 0xcc, 0x3c, 0xa4, 0x83, 0x3b, 0x9c, 0x03, 0x3b, 0x94, 0x03, 0x3d, + 0xa0, 0x83, 0x3c, 0x94, 0x43, 0x38, 0x90, 0xc3, 0x01, 0x00, 0x00, 0x00, + 0x61, 0x20, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, + 0x10, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x24, 0xcd, 0x00, 0xd0, + 0x54, 0x03, 0x23, 0x00, 0x44, 0x8d, 0x00, 0xd0, 0x36, 0xd6, 0x00, 0x04, + 0xc2, 0x1c, 0xc3, 0x71, 0x5d, 0xc4, 0x8d, 0x00, 0x94, 0x40, 0x11, 0x10, + 0x30, 0x02, 0x30, 0x03, 0x30, 0x46, 0x00, 0x82, 0x20, 0x88, 0x7f, 0x14, + 0xcc, 0x00, 0xcc, 0x41, 0x84, 0x41, 0x18, 0x84, 0x81, 0x18, 0x00, 0x00, + 0x23, 0x06, 0xcd, 0x10, 0x82, 0x60, 0x70, 0x89, 0x41, 0xf4, 0x4c, 0xcd, + 0xc2, 0x14, 0x85, 0x37, 0x9a, 0x10, 0x00, 0x83, 0x0c, 0x01, 0xb1, 0x8c, + 0x18, 0x38, 0x43, 0x08, 0x82, 0x41, 0x65, 0x06, 0x93, 0x64, 0x85, 0x01, + 0xe4, 0x3c, 0x08, 0x12, 0x06, 0xa3, 0x09, 0x01, 0x30, 0x86, 0x10, 0x34, + 0x73, 0x0c, 0x44, 0xd0, 0x8c, 0x18, 0x38, 0x43, 0x08, 0x82, 0x41, 0xa5, + 0x06, 0x97, 0xa5, 0x9d, 0x01, 0x25, 0x4d, 0x0c, 0x53, 0x06, 0xa3, 0x09, + 0x01, 0x30, 0x86, 0x10, 0x44, 0x73, 0x0c, 0x44, 0x00, 0x5d, 0xd7, 0x2d, + 0x05, 0x41, 0x19, 0x64, 0x08, 0x9e, 0xcb, 0x88, 0x00, 0xfc, 0x37, 0x31, + 0x84, 0xc1, 0xf5, 0x06, 0x17, 0x74, 0x4b, 0x41, 0x50, 0x06, 0x19, 0x02, + 0x8a, 0x1b, 0x31, 0x38, 0x84, 0x10, 0x04, 0x0b, 0xff, 0x70, 0xee, 0xa0, + 0x08, 0x36, 0x31, 0x98, 0x01, 0x57, 0x07, 0x17, 0x74, 0x4b, 0x41, 0x50, + 0x06, 0x19, 0x82, 0x2c, 0x0c, 0x46, 0x0c, 0x0e, 0x21, 0x04, 0xc1, 0xc2, + 0x3f, 0x1c, 0x3e, 0x50, 0x82, 0x4d, 0x0c, 0x6b, 0x10, 0x06, 0x76, 0x70, + 0x41, 0xb7, 0x14, 0x04, 0x65, 0x90, 0x21, 0xf0, 0xcc, 0x60, 0xc4, 0xe0, + 0x10, 0x42, 0x10, 0x2c, 0xfc, 0xc3, 0x09, 0x85, 0x27, 0x98, 0x63, 0xf8, + 0x16, 0x3e, 0x98, 0x63, 0x08, 0x8e, 0x3f, 0x98, 0x63, 0x08, 0x86, 0x50, + 0xb0, 0xa0, 0x0e, 0xc4, 0x3f, 0x03, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x32, 0x0e, 0x10, 0x22, 0x84, 0x00, 0x8e, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x0c, 0x00, 0x00, + 0x2f, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0x70, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x24, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x08, 0x24, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x08, 0x24, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, + 0x1b, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x08, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x5d, 0x0c, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0x23, + 0x01, 0x00, 0x00, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x59, 0x55, 0x56, 0x5f, + 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x69, 0x72, 0x2e, + 0x64, 0x6f, 0x74, 0x2e, 0x76, 0x33, 0x66, 0x33, 0x32, 0x61, 0x69, 0x72, + 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x74, 0x65, 0x78, 0x74, + 0x75, 0x72, 0x65, 0x5f, 0x32, 0x64, 0x5f, 0x61, 0x72, 0x72, 0x61, 0x79, + 0x2e, 0x76, 0x34, 0x66, 0x33, 0x32, 0x61, 0x69, 0x72, 0x2e, 0x73, 0x61, + 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, + 0x5f, 0x32, 0x64, 0x2e, 0x76, 0x34, 0x66, 0x33, 0x32, 0x33, 0x31, 0x30, + 0x30, 0x31, 0x2e, 0x35, 0x30, 0x2e, 0x31, 0x61, 0x69, 0x72, 0x36, 0x34, + 0x2d, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2d, 0x74, 0x76, 0x6f, 0x73, 0x31, + 0x33, 0x2e, 0x30, 0x2e, 0x30, 0x2d, 0x73, 0x69, 0x6d, 0x75, 0x6c, 0x61, + 0x74, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, + 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x1c, 0x0e, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x42, 0x43, 0xc0, 0xde, 0x35, 0x14, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x62, 0x0c, 0x30, 0x24, 0x80, 0x10, 0x05, 0xc8, + 0x14, 0x00, 0x00, 0x00, 0x21, 0x0c, 0x00, 0x00, 0x36, 0x03, 0x00, 0x00, + 0x0b, 0x02, 0x21, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x07, 0x81, 0x23, 0x91, 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, + 0x92, 0x01, 0x84, 0x0c, 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, + 0x80, 0x14, 0x45, 0x02, 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, + 0x38, 0x08, 0x18, 0x4b, 0x0a, 0x32, 0x52, 0x88, 0x48, 0x90, 0x14, 0x20, + 0x43, 0x46, 0x88, 0xa5, 0x00, 0x19, 0x32, 0x42, 0x04, 0x49, 0x0e, 0x90, + 0x91, 0x22, 0xc4, 0x50, 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, + 0x04, 0x29, 0x46, 0x06, 0x51, 0x18, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, + 0x1b, 0xcc, 0x25, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01, 0x58, 0x03, 0x40, + 0x02, 0x2a, 0x62, 0x1c, 0xde, 0x41, 0x1e, 0xe4, 0xa1, 0x1c, 0xc6, 0x81, + 0x1e, 0xd8, 0x21, 0x1f, 0xda, 0x40, 0x1e, 0xde, 0xa1, 0x1e, 0xdc, 0x81, + 0x1c, 0xca, 0x81, 0x1c, 0xda, 0x80, 0x1c, 0xd2, 0xc1, 0x1e, 0xd2, 0x81, + 0x1c, 0xca, 0xa1, 0x0d, 0xe6, 0x21, 0x1e, 0xe4, 0x81, 0x1e, 0xda, 0xc0, + 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x73, + 0x08, 0x07, 0x76, 0x98, 0x87, 0x72, 0x00, 0x08, 0x72, 0x48, 0x87, 0x79, + 0x08, 0x07, 0x71, 0x60, 0x87, 0x72, 0x68, 0x03, 0x7a, 0x08, 0x87, 0x74, + 0x60, 0x87, 0x36, 0x18, 0x87, 0x70, 0x60, 0x07, 0x76, 0x98, 0x07, 0xc0, + 0x1c, 0xc2, 0x81, 0x1d, 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1d, 0xca, 0x61, + 0x1e, 0xe6, 0xa1, 0x0d, 0xe0, 0x41, 0x1e, 0xca, 0x61, 0x1c, 0xd2, 0x61, + 0x1e, 0xca, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0x21, 0x1c, 0xc8, 0x01, + 0x30, 0x87, 0x70, 0x60, 0x87, 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, + 0x68, 0x03, 0x73, 0x90, 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, 0x78, + 0x78, 0x87, 0x74, 0x70, 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, 0x72, + 0x60, 0x87, 0x74, 0x68, 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, + 0x18, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1, + 0x1c, 0xda, 0x00, 0x1e, 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, + 0x1e, 0xda, 0xa0, 0x1c, 0xd8, 0x21, 0x1d, 0xda, 0xa1, 0x0d, 0xdc, 0xe1, + 0x1d, 0xdc, 0xa1, 0x0d, 0xd8, 0xa1, 0x1c, 0xc2, 0xc1, 0x1c, 0x00, 0xc2, + 0x1d, 0xde, 0xa1, 0x0d, 0xd2, 0xc1, 0x1d, 0xcc, 0x61, 0x1e, 0xda, 0xc0, + 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, + 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x75, + 0xa8, 0x87, 0x76, 0x80, 0x87, 0x36, 0xa0, 0x87, 0x70, 0x10, 0x07, 0x76, + 0x28, 0x87, 0x79, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, + 0x20, 0xdc, 0xe1, 0x1d, 0xda, 0xc0, 0x1d, 0xc2, 0xc1, 0x1d, 0xe6, 0xa1, + 0x0d, 0xcc, 0x01, 0x1e, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, + 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, + 0x98, 0x87, 0x74, 0x38, 0x07, 0x77, 0x28, 0x07, 0x72, 0x68, 0x03, 0x7d, + 0x28, 0x07, 0x79, 0x78, 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, + 0x68, 0x87, 0x70, 0xa0, 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, + 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0x01, + 0x1e, 0xe0, 0x21, 0x1d, 0xdc, 0xe1, 0x1c, 0xda, 0xa0, 0x1d, 0xc2, 0x81, + 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x88, 0x79, + 0xa0, 0x87, 0x70, 0x18, 0x87, 0x75, 0x68, 0x03, 0x78, 0x90, 0x87, 0x77, + 0xa0, 0x87, 0x72, 0x18, 0x07, 0x7a, 0x78, 0x07, 0x79, 0x68, 0x03, 0x71, + 0xa8, 0x07, 0x73, 0x30, 0x87, 0x72, 0x90, 0x87, 0x36, 0x98, 0x87, 0x74, + 0xd0, 0x87, 0x72, 0x00, 0xf0, 0x00, 0x20, 0xea, 0xc1, 0x1d, 0xe6, 0x21, + 0x1c, 0xcc, 0xa1, 0x1c, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, + 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, + 0xa8, 0x87, 0x79, 0x28, 0x87, 0x36, 0x98, 0x87, 0x77, 0x30, 0x07, 0x7a, + 0x68, 0x03, 0x73, 0x60, 0x87, 0x77, 0x08, 0x07, 0x7a, 0x00, 0xcc, 0x21, + 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0xd8, 0xb0, 0x08, 0x04, 0x90, 0x00, + 0x0b, 0x50, 0x05, 0x69, 0x00, 0x0a, 0x1b, 0x8c, 0xa1, 0x00, 0x16, 0xa0, + 0xda, 0x60, 0x10, 0x06, 0xb0, 0x00, 0xd5, 0x06, 0xa3, 0x38, 0x80, 0x05, + 0xa8, 0x36, 0x18, 0xc6, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x80, 0x04, 0x50, + 0x1b, 0x94, 0xe3, 0xff, 0xff, 0xff, 0xff, 0x07, 0xa0, 0x0d, 0x80, 0x35, + 0x00, 0x24, 0xa0, 0xda, 0x60, 0x20, 0x01, 0xb0, 0x00, 0xd5, 0x06, 0x23, + 0x11, 0x80, 0x05, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x49, 0x18, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x13, 0x8a, 0x40, 0x18, 0x88, 0x62, 0x42, 0x60, + 0x4c, 0x18, 0x0e, 0x24, 0x01, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, + 0x29, 0x00, 0x00, 0x00, 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, + 0x93, 0x22, 0xa4, 0x84, 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, + 0x12, 0x4c, 0x8a, 0x8c, 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x70, 0x33, 0x00, + 0xc3, 0x08, 0x04, 0x30, 0x8c, 0x20, 0x00, 0xc3, 0x08, 0x03, 0x70, 0x90, + 0x34, 0x45, 0x94, 0x30, 0xf9, 0xb2, 0xfb, 0x76, 0x84, 0xe0, 0x0c, 0x04, + 0x22, 0xc6, 0x18, 0x63, 0x10, 0x81, 0x10, 0x8e, 0x92, 0xa6, 0x88, 0x12, + 0x26, 0xff, 0x9f, 0x88, 0x6b, 0xa2, 0x22, 0xe2, 0xb7, 0x87, 0x7f, 0x1a, + 0x23, 0x00, 0x06, 0x11, 0x8c, 0xe0, 0x22, 0x69, 0x8a, 0x28, 0x61, 0xf2, + 0x7f, 0x09, 0x60, 0x9e, 0x85, 0x88, 0xfe, 0x69, 0x8c, 0x00, 0x18, 0x44, + 0x40, 0x84, 0x82, 0x84, 0x10, 0x44, 0x39, 0x27, 0x91, 0x2a, 0x03, 0x18, + 0x83, 0xd8, 0x1c, 0x01, 0x62, 0x84, 0xe0, 0xe6, 0x08, 0x82, 0x39, 0x02, + 0x30, 0x18, 0x46, 0x10, 0xa2, 0xa2, 0xbc, 0x93, 0x04, 0x94, 0x10, 0x80, + 0x48, 0x73, 0x20, 0x20, 0x05, 0xe2, 0x30, 0xc2, 0x10, 0x0d, 0x22, 0x04, + 0xc2, 0x1c, 0x01, 0x28, 0x0c, 0x22, 0x0c, 0xc2, 0x08, 0x00, 0x00, 0x00, + 0x13, 0xc0, 0x20, 0x1c, 0xd2, 0x41, 0x1e, 0xec, 0x80, 0x0e, 0xda, 0x20, + 0x1c, 0xe0, 0x01, 0x1e, 0xd8, 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xec, 0xe1, + 0x1d, 0xe6, 0x21, 0x0e, 0xe6, 0xc0, 0x0d, 0xe0, 0xc0, 0x0d, 0xe0, 0xa0, + 0x0d, 0xe6, 0x21, 0x1d, 0xda, 0xa1, 0x1e, 0xd8, 0x21, 0x1c, 0xe8, 0xe1, + 0x1d, 0xe4, 0x61, 0xc3, 0x6d, 0x94, 0x43, 0x1b, 0xc0, 0x83, 0x1e, 0xd8, + 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, + 0x41, 0x3a, 0xc4, 0x81, 0x1e, 0xe0, 0x81, 0x1e, 0xe0, 0x41, 0x1b, 0xa4, + 0x03, 0x1e, 0xe8, 0x01, 0x1e, 0xe8, 0x01, 0x1e, 0xb4, 0x41, 0x3a, 0xc4, + 0x81, 0x1d, 0xe8, 0x41, 0x1c, 0xd8, 0x81, 0x1e, 0xc4, 0x81, 0x1d, 0xb4, + 0x41, 0x3a, 0xcc, 0x81, 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, + 0x81, 0x1c, 0xb4, 0x41, 0x3a, 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, + 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x39, 0xcc, 0x81, 0x1c, 0xe8, + 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, 0x39, 0xd8, + 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, + 0x81, 0x3d, 0xc4, 0x81, 0x1d, 0xe8, 0x41, 0x1c, 0xd8, 0x81, 0x1e, 0xc4, + 0x81, 0x1d, 0xb4, 0x81, 0x3d, 0xc8, 0x01, 0x1d, 0xe8, 0xc1, 0x1c, 0xc8, + 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, 0x3d, 0xcc, 0x81, 0x1c, 0xe8, + 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, 0x3d, 0xd0, + 0x01, 0x1e, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, + 0x81, 0x3d, 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, + 0x01, 0x1d, 0xb4, 0x81, 0x3d, 0xe4, 0x81, 0x1d, 0xe8, 0x41, 0x1c, 0xc8, + 0x01, 0x1e, 0xe8, 0x41, 0x1c, 0xc8, 0x01, 0x1e, 0xb4, 0x81, 0x3d, 0xc4, + 0x81, 0x1c, 0xe0, 0x81, 0x1e, 0xc4, 0x81, 0x1c, 0xe0, 0x81, 0x1e, 0xc4, + 0x81, 0x1c, 0xe0, 0x41, 0x1b, 0xd8, 0x43, 0x1c, 0xe4, 0x81, 0x1c, 0xe8, + 0x81, 0x1c, 0xd4, 0x81, 0x1d, 0xe8, 0x81, 0x1c, 0xd4, 0x81, 0x1d, 0xb4, + 0x81, 0x3d, 0xc8, 0x41, 0x1d, 0xd8, 0x81, 0x1e, 0xc8, 0x41, 0x1d, 0xd8, + 0x81, 0x1e, 0xc8, 0x41, 0x1d, 0xd8, 0x41, 0x1b, 0xd8, 0x43, 0x1d, 0xc4, + 0x81, 0x1c, 0xe8, 0x41, 0x1d, 0xc4, 0x81, 0x1c, 0xe8, 0x41, 0x1d, 0xc4, + 0x81, 0x1c, 0xb4, 0x81, 0x3d, 0xc4, 0x01, 0x1c, 0xc8, 0x01, 0x1d, 0xe8, + 0x41, 0x1c, 0xc0, 0x81, 0x1c, 0xd0, 0x81, 0x1e, 0xc4, 0x01, 0x1c, 0xc8, + 0x01, 0x1d, 0xb4, 0x81, 0x3b, 0xe0, 0x81, 0x1e, 0xc4, 0x81, 0x1d, 0xe8, + 0xc1, 0x1c, 0xc8, 0x81, 0x46, 0x08, 0x43, 0x46, 0x6c, 0x57, 0xfe, 0xe7, + 0x5b, 0xdb, 0x7f, 0x11, 0x01, 0x06, 0x43, 0x34, 0xd3, 0x90, 0x08, 0x88, + 0x14, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x18, + 0x12, 0x45, 0x0d, 0x03, 0x04, 0x80, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x43, 0x22, 0x6f, 0x9b, 0x80, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x40, 0x62, 0x83, 0x40, 0x51, 0x9c, 0x01, 0x00, + 0x80, 0x2c, 0x10, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, + 0x19, 0x11, 0x4c, 0x90, 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x8a, + 0x45, 0x50, 0x02, 0x85, 0x30, 0x02, 0x50, 0x06, 0x05, 0x18, 0x50, 0x20, + 0x05, 0x54, 0x60, 0xa5, 0x50, 0x0c, 0x64, 0xc7, 0x12, 0x9c, 0x01, 0x00, + 0xb1, 0x18, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, + 0xc4, 0xe1, 0x1c, 0x66, 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, + 0x8c, 0x42, 0x80, 0x07, 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, + 0x00, 0x0f, 0xed, 0x10, 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, + 0xc2, 0xc1, 0x1d, 0xce, 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, + 0x38, 0x84, 0x83, 0x1b, 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, + 0x3d, 0xcc, 0x78, 0x8c, 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, + 0x87, 0x70, 0x70, 0x07, 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, + 0x87, 0x19, 0xcc, 0x11, 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, + 0x30, 0x0f, 0xe3, 0xf0, 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, + 0xde, 0x21, 0x1c, 0xd8, 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, + 0x3b, 0xbc, 0x83, 0x3b, 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, + 0x3c, 0x84, 0x03, 0x3b, 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, + 0x07, 0x37, 0x68, 0x87, 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, + 0x87, 0x70, 0x60, 0x07, 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, + 0x87, 0x77, 0x80, 0x87, 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, + 0x87, 0x79, 0x98, 0x81, 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, + 0xc0, 0x0e, 0xec, 0x30, 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, + 0xcc, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, + 0xc4, 0x81, 0x1d, 0xca, 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, + 0x39, 0x98, 0x43, 0x39, 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, + 0x38, 0x88, 0x03, 0x3b, 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, + 0x3b, 0xd4, 0x03, 0x3b, 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, + 0x87, 0x72, 0x70, 0x83, 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, + 0x87, 0x74, 0xa0, 0x87, 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, + 0x50, 0x0e, 0xe4, 0x90, 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, + 0x50, 0x0e, 0x33, 0x20, 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, + 0xd2, 0x21, 0x1c, 0xdc, 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, + 0xea, 0x01, 0x1e, 0x66, 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, + 0x3b, 0xcc, 0x50, 0x24, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, + 0x87, 0x77, 0x78, 0x07, 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, + 0x50, 0x0e, 0x33, 0x1e, 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, + 0xde, 0xc1, 0x1d, 0x7e, 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, + 0xf0, 0x61, 0x06, 0x54, 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, + 0x3d, 0xd0, 0x43, 0x39, 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, + 0x3b, 0xb0, 0xc3, 0x8c, 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, + 0x87, 0x74, 0x08, 0x07, 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, + 0x10, 0x0e, 0xec, 0xc0, 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, + 0xd2, 0x41, 0x1e, 0xe4, 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, + 0x66, 0x50, 0x59, 0x38, 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, + 0x3b, 0x8c, 0x03, 0x3d, 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, + 0x3c, 0xbc, 0x43, 0x3d, 0xc0, 0xc3, 0x3c, 0x00, 0x79, 0x20, 0x00, 0x00, + 0x09, 0x01, 0x00, 0x00, 0x32, 0x9a, 0x08, 0x14, 0x02, 0x85, 0x8c, 0x27, + 0x46, 0x46, 0xc8, 0x11, 0x32, 0x64, 0xd4, 0xd8, 0x80, 0x0c, 0xea, 0x09, + 0x8b, 0x02, 0x07, 0xc5, 0xc6, 0x91, 0x41, 0x14, 0x19, 0x8c, 0x22, 0x31, + 0x88, 0x64, 0x3d, 0x45, 0x66, 0x20, 0xca, 0x23, 0x21, 0x94, 0x61, 0x18, + 0x86, 0x11, 0x5d, 0x89, 0xb1, 0x28, 0x18, 0x51, 0x2c, 0x47, 0x00, 0x00, + 0x53, 0x44, 0x4b, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x77, + 0x63, 0x68, 0x61, 0x72, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x41, 0x70, 0x70, + 0x6c, 0x65, 0x20, 0x4c, 0x4c, 0x56, 0x4d, 0x20, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x20, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, + 0x20, 0x28, 0x6d, 0x65, 0x74, 0x61, 0x6c, 0x66, 0x65, 0x2d, 0x33, 0x31, + 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x2e, 0x31, 0x29, 0x4d, 0x65, 0x74, + 0x61, 0x6c, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, + 0x65, 0x2e, 0x64, 0x65, 0x6e, 0x6f, 0x72, 0x6d, 0x73, 0x5f, 0x64, 0x69, + 0x73, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, + 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, + 0x74, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, + 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x72, 0x61, + 0x6d, 0x65, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x66, 0x65, 0x74, + 0x63, 0x68, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, + 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x5f, 0x74, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x66, 0x6c, 0x6f, 0x61, 0x74, + 0x34, 0x61, 0x69, 0x72, 0x2e, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x61, + 0x69, 0x72, 0x2e, 0x6e, 0x6f, 0x5f, 0x70, 0x65, 0x72, 0x73, 0x70, 0x65, + 0x63, 0x74, 0x69, 0x76, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x69, 0x72, 0x2e, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, + 0x74, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x67, 0x65, 0x6e, 0x65, 0x72, + 0x61, 0x74, 0x65, 0x64, 0x28, 0x35, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x44, + 0x76, 0x34, 0x5f, 0x66, 0x29, 0x61, 0x69, 0x72, 0x2e, 0x70, 0x65, 0x72, + 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x38, + 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x44, 0x76, 0x32, 0x5f, + 0x66, 0x29, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x74, 0x65, 0x78, 0x63, + 0x6f, 0x6f, 0x72, 0x64, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, + 0x65, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, + 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x6c, 0x6f, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x61, + 0x69, 0x72, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x61, 0x69, 0x72, 0x2e, 0x73, + 0x74, 0x72, 0x75, 0x63, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x69, + 0x6e, 0x66, 0x6f, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x6f, 0x66, 0x66, + 0x73, 0x65, 0x74, 0x52, 0x63, 0x6f, 0x65, 0x66, 0x66, 0x47, 0x63, 0x6f, + 0x65, 0x66, 0x66, 0x42, 0x63, 0x6f, 0x65, 0x66, 0x66, 0x61, 0x69, 0x72, + 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x73, 0x69, + 0x7a, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x5f, 0x73, 0x69, 0x7a, + 0x65, 0x59, 0x55, 0x56, 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x65, + 0x63, 0x6f, 0x64, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x74, 0x65, 0x78, 0x74, + 0x75, 0x72, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, + 0x65, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x32, 0x64, 0x3c, 0x66, + 0x6c, 0x6f, 0x61, 0x74, 0x2c, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, + 0x3e, 0x74, 0x65, 0x78, 0x59, 0x74, 0x65, 0x78, 0x55, 0x56, 0x61, 0x69, + 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x73, 0x61, 0x6d, + 0x70, 0x6c, 0x65, 0x72, 0x73, 0x00, 0x00, 0x00, 0x44, 0x74, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x30, 0x82, 0x10, 0x0d, 0x23, 0x08, 0x96, 0x33, + 0x82, 0x10, 0x11, 0x23, 0x08, 0x51, 0x31, 0x82, 0x10, 0x19, 0x23, 0x08, + 0x0b, 0x30, 0x82, 0x10, 0x1d, 0x23, 0x08, 0x11, 0x32, 0x82, 0x10, 0x25, + 0x23, 0x08, 0x91, 0x32, 0x82, 0x10, 0x2d, 0x23, 0x08, 0x11, 0x33, 0x82, + 0x10, 0x35, 0x33, 0x0c, 0x6d, 0x10, 0xb8, 0xc1, 0x0c, 0xc3, 0x1b, 0x08, + 0x70, 0x30, 0x43, 0x30, 0xcc, 0x30, 0xb4, 0x41, 0x1b, 0xc4, 0xc1, 0x0c, + 0x04, 0xf1, 0x06, 0x6f, 0x10, 0x07, 0x33, 0x04, 0xc5, 0x0c, 0x81, 0x31, + 0x43, 0x70, 0xcc, 0x50, 0x20, 0x71, 0x10, 0x07, 0x89, 0x32, 0x43, 0x20, + 0x0a, 0x33, 0x20, 0x71, 0xb0, 0x30, 0x4d, 0xa2, 0x38, 0xcf, 0x0c, 0xc9, + 0x1b, 0x40, 0x11, 0x23, 0x25, 0x8a, 0x33, 0xcd, 0x90, 0xb4, 0x01, 0x44, + 0x31, 0x52, 0x52, 0x39, 0xd6, 0x0c, 0x54, 0x1c, 0xd4, 0x41, 0x1c, 0x70, + 0x5d, 0x1d, 0xd4, 0x41, 0x1c, 0x70, 0x9e, 0x1d, 0xd4, 0x41, 0x1c, 0x70, + 0xdf, 0x1d, 0xd4, 0x41, 0x1c, 0x70, 0x60, 0x30, 0x83, 0x34, 0x07, 0x17, + 0x46, 0x07, 0xd9, 0x1b, 0xbc, 0x81, 0xb6, 0x9d, 0x42, 0x18, 0xd0, 0x81, + 0x18, 0xd4, 0x41, 0x32, 0x06, 0x0e, 0x19, 0xcc, 0xa0, 0xc0, 0x41, 0x19, + 0x64, 0x71, 0xf0, 0x06, 0x66, 0x90, 0x9c, 0x81, 0x83, 0x06, 0x33, 0x28, + 0x78, 0x50, 0x06, 0xd9, 0x1b, 0xbc, 0x81, 0x19, 0x24, 0x67, 0xe0, 0xa4, + 0xc1, 0x0c, 0x49, 0x1e, 0xa8, 0x41, 0x16, 0x07, 0x6f, 0x90, 0xac, 0x81, + 0xc3, 0x06, 0x33, 0x1c, 0xa4, 0x50, 0x0a, 0xa6, 0x80, 0x0a, 0xa9, 0xa0, + 0x0a, 0xab, 0x30, 0xc3, 0x20, 0x07, 0xa3, 0xc0, 0x0a, 0x15, 0x06, 0x00, + 0xc7, 0x71, 0x1c, 0xc7, 0x71, 0x1c, 0xc7, 0x71, 0x1c, 0xe7, 0x06, 0x6e, + 0x60, 0xd1, 0x81, 0x1e, 0x58, 0x96, 0xa5, 0x07, 0x9c, 0x29, 0xb0, 0x02, + 0x2b, 0xd8, 0x86, 0x5f, 0xd8, 0x83, 0x3d, 0xa8, 0x03, 0x39, 0xc8, 0x48, + 0x60, 0x82, 0x2e, 0x62, 0x63, 0xb3, 0x6b, 0x73, 0x69, 0x7b, 0x23, 0xab, + 0x63, 0x2b, 0x73, 0x31, 0x63, 0x0b, 0x3b, 0x9b, 0x1b, 0x45, 0xc8, 0x03, + 0x3d, 0x38, 0x85, 0x8d, 0xcd, 0xae, 0xcd, 0x25, 0x8d, 0xac, 0xcc, 0x8d, + 0x6e, 0x94, 0x60, 0x0f, 0x6e, 0x09, 0x4b, 0x93, 0x73, 0xb1, 0x2b, 0x93, + 0x9b, 0x4b, 0x7b, 0x73, 0x1b, 0x25, 0xe0, 0x83, 0xa3, 0xc2, 0xd2, 0xe4, + 0x5c, 0xd8, 0xc2, 0xdc, 0xce, 0xea, 0xc2, 0xce, 0xca, 0xbe, 0xec, 0xca, + 0xe4, 0xe6, 0xd2, 0xde, 0xdc, 0x46, 0x09, 0xfa, 0xe0, 0xa6, 0xb0, 0x34, + 0x39, 0x97, 0xb1, 0xb7, 0x36, 0xb8, 0x34, 0xb6, 0xb2, 0xaf, 0x37, 0x38, + 0xba, 0xb4, 0x37, 0xb7, 0xb9, 0x51, 0x06, 0x3f, 0xf8, 0x03, 0x50, 0x38, + 0x26, 0x2c, 0x4d, 0xce, 0xc5, 0x4c, 0x2e, 0xec, 0xac, 0xad, 0xcc, 0x8d, + 0x6e, 0x94, 0x80, 0x15, 0x00, 0x00, 0x00, 0x00, 0xa9, 0x18, 0x00, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x0a, 0x72, 0x28, 0x87, 0x77, 0x80, 0x07, + 0x7a, 0x58, 0x70, 0x98, 0x43, 0x3d, 0xb8, 0xc3, 0x38, 0xb0, 0x43, 0x39, + 0xd0, 0xc3, 0x82, 0xe6, 0x1c, 0xc6, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, + 0xc1, 0x1d, 0xe6, 0x21, 0x1d, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x00, + 0xd1, 0x10, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0xcc, 0x3c, 0xa4, + 0x83, 0x3b, 0x9c, 0x03, 0x3b, 0x94, 0x03, 0x3d, 0xa0, 0x83, 0x3c, 0x94, + 0x43, 0x38, 0x90, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, + 0x3b, 0x00, 0x00, 0x00, 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x04, 0x6b, 0x60, 0x04, 0x80, 0xe2, 0x0c, 0x00, + 0xc9, 0x11, 0x00, 0xba, 0x63, 0x0d, 0x40, 0x20, 0xcc, 0x31, 0x18, 0x18, + 0x36, 0xc7, 0x60, 0x10, 0xd8, 0x58, 0x03, 0x30, 0x10, 0x94, 0x47, 0x00, + 0x08, 0x8c, 0x00, 0xcc, 0x00, 0x8c, 0x11, 0x80, 0x20, 0x08, 0xe2, 0x1f, + 0x85, 0x19, 0x80, 0x39, 0x08, 0x30, 0x00, 0x03, 0x30, 0x08, 0x03, 0x00, + 0x23, 0x06, 0xcd, 0x10, 0x82, 0x60, 0x30, 0x89, 0x41, 0xf4, 0x4c, 0xce, + 0xd2, 0x14, 0x85, 0x37, 0x9a, 0x10, 0x00, 0x83, 0x0c, 0x01, 0xb1, 0x8c, + 0x18, 0x34, 0x43, 0x08, 0x82, 0xc1, 0x54, 0x06, 0x93, 0x64, 0x45, 0x0e, + 0x84, 0x20, 0x61, 0x30, 0x9a, 0x10, 0x00, 0x83, 0x0c, 0xc1, 0xd1, 0x0c, + 0x32, 0x10, 0x41, 0x73, 0x19, 0x5e, 0x0a, 0x42, 0x19, 0x64, 0x08, 0x96, + 0xc9, 0x88, 0x00, 0xfc, 0x37, 0x19, 0xba, 0x68, 0x0d, 0x2e, 0xc0, 0x4b, + 0x41, 0x28, 0x83, 0x0c, 0x01, 0x84, 0x8d, 0x18, 0x1c, 0x42, 0x08, 0x82, + 0x85, 0x7f, 0x30, 0x72, 0x50, 0x04, 0x9b, 0x0c, 0x62, 0x60, 0xc5, 0xc1, + 0x05, 0x78, 0x29, 0x08, 0x65, 0x90, 0x21, 0xa8, 0xba, 0x11, 0x83, 0x43, + 0x08, 0x41, 0xb0, 0xf0, 0x0f, 0xe6, 0x0e, 0x94, 0x60, 0x93, 0xe1, 0x0c, + 0x36, 0x39, 0xb8, 0x00, 0x2f, 0x05, 0xa1, 0x0c, 0x32, 0x04, 0x9a, 0x18, + 0x8c, 0x18, 0x1c, 0x42, 0x08, 0x82, 0x85, 0x7f, 0x30, 0x7c, 0xf0, 0x04, + 0x73, 0x0c, 0xdb, 0x82, 0x07, 0x73, 0x0c, 0xc1, 0xb1, 0x07, 0x73, 0x0c, + 0xc1, 0xd0, 0x07, 0x16, 0xc4, 0x81, 0xf8, 0x67, 0x00, 0x00, 0x00, 0x00, + 0x71, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x32, 0x0e, 0x10, 0x22, + 0x84, 0x00, 0xfb, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x65, 0x0c, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0x38, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x43, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x24, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x08, 0x24, 0x00, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, + 0x1b, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x08, 0x24, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x5d, 0x0c, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x12, 0x03, 0x94, 0xe3, 0x00, 0x00, 0x00, 0x00, 0x53, 0x44, 0x4c, 0x5f, + 0x4e, 0x56, 0x31, 0x32, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, + 0x74, 0x61, 0x69, 0x72, 0x2e, 0x64, 0x6f, 0x74, 0x2e, 0x76, 0x33, 0x66, + 0x33, 0x32, 0x61, 0x69, 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, + 0x5f, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x32, 0x64, 0x2e, + 0x76, 0x34, 0x66, 0x33, 0x32, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, + 0x30, 0x2e, 0x31, 0x61, 0x69, 0x72, 0x36, 0x34, 0x2d, 0x61, 0x70, 0x70, + 0x6c, 0x65, 0x2d, 0x74, 0x76, 0x6f, 0x73, 0x31, 0x33, 0x2e, 0x30, 0x2e, + 0x30, 0x2d, 0x73, 0x69, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xde, 0xc0, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x28, 0x0e, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x42, 0x43, 0xc0, 0xde, 0x35, 0x14, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x62, 0x0c, 0x30, 0x24, 0x80, 0x10, 0x05, 0xc8, 0x14, 0x00, 0x00, 0x00, + 0x21, 0x0c, 0x00, 0x00, 0x39, 0x03, 0x00, 0x00, 0x0b, 0x02, 0x21, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x07, 0x81, 0x23, 0x91, + 0x41, 0xc8, 0x04, 0x49, 0x06, 0x10, 0x32, 0x39, 0x92, 0x01, 0x84, 0x0c, + 0x25, 0x05, 0x08, 0x19, 0x1e, 0x04, 0x8b, 0x62, 0x80, 0x14, 0x45, 0x02, + 0x42, 0x92, 0x0b, 0x42, 0xa4, 0x10, 0x32, 0x14, 0x38, 0x08, 0x18, 0x4b, + 0x0a, 0x32, 0x52, 0x88, 0x48, 0x90, 0x14, 0x20, 0x43, 0x46, 0x88, 0xa5, + 0x00, 0x19, 0x32, 0x42, 0x04, 0x49, 0x0e, 0x90, 0x91, 0x22, 0xc4, 0x50, + 0x41, 0x51, 0x81, 0x8c, 0xe1, 0x83, 0xe5, 0x8a, 0x04, 0x29, 0x46, 0x06, + 0x51, 0x18, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x1b, 0xcc, 0x25, 0xf8, + 0xff, 0xff, 0xff, 0xff, 0x01, 0x58, 0x03, 0x40, 0x02, 0x2a, 0x62, 0x1c, + 0xde, 0x41, 0x1e, 0xe4, 0xa1, 0x1c, 0xc6, 0x81, 0x1e, 0xd8, 0x21, 0x1f, + 0xda, 0x40, 0x1e, 0xde, 0xa1, 0x1e, 0xdc, 0x81, 0x1c, 0xca, 0x81, 0x1c, + 0xda, 0x80, 0x1c, 0xd2, 0xc1, 0x1e, 0xd2, 0x81, 0x1c, 0xca, 0xa1, 0x0d, + 0xe6, 0x21, 0x1e, 0xe4, 0x81, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, + 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x73, 0x08, 0x07, 0x76, 0x98, + 0x87, 0x72, 0x00, 0x08, 0x72, 0x48, 0x87, 0x79, 0x08, 0x07, 0x71, 0x60, + 0x87, 0x72, 0x68, 0x03, 0x7a, 0x08, 0x87, 0x74, 0x60, 0x87, 0x36, 0x18, + 0x87, 0x70, 0x60, 0x07, 0x76, 0x98, 0x07, 0xc0, 0x1c, 0xc2, 0x81, 0x1d, + 0xe6, 0xa1, 0x1c, 0x00, 0x82, 0x1d, 0xca, 0x61, 0x1e, 0xe6, 0xa1, 0x0d, + 0xe0, 0x41, 0x1e, 0xca, 0x61, 0x1c, 0xd2, 0x61, 0x1e, 0xca, 0xa1, 0x0d, + 0xcc, 0x01, 0x1e, 0xda, 0x21, 0x1c, 0xc8, 0x01, 0x30, 0x87, 0x70, 0x60, + 0x87, 0x79, 0x28, 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x73, 0x90, + 0x87, 0x70, 0x68, 0x87, 0x72, 0x68, 0x03, 0x78, 0x78, 0x87, 0x74, 0x70, + 0x07, 0x7a, 0x28, 0x07, 0x79, 0x68, 0x83, 0x72, 0x60, 0x87, 0x74, 0x68, + 0x07, 0x80, 0x1e, 0xe4, 0xa1, 0x1e, 0xca, 0x01, 0x18, 0xdc, 0xe1, 0x1d, + 0xda, 0xc0, 0x1c, 0xe4, 0x21, 0x1c, 0xda, 0xa1, 0x1c, 0xda, 0x00, 0x1e, + 0xde, 0x21, 0x1d, 0xdc, 0x81, 0x1e, 0xca, 0x41, 0x1e, 0xda, 0xa0, 0x1c, + 0xd8, 0x21, 0x1d, 0xda, 0xa1, 0x0d, 0xdc, 0xe1, 0x1d, 0xdc, 0xa1, 0x0d, + 0xd8, 0xa1, 0x1c, 0xc2, 0xc1, 0x1c, 0x00, 0xc2, 0x1d, 0xde, 0xa1, 0x0d, + 0xd2, 0xc1, 0x1d, 0xcc, 0x61, 0x1e, 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, + 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, + 0x07, 0x80, 0x70, 0x87, 0x77, 0x68, 0x03, 0x75, 0xa8, 0x87, 0x76, 0x80, + 0x87, 0x36, 0xa0, 0x87, 0x70, 0x10, 0x07, 0x76, 0x28, 0x87, 0x79, 0x00, + 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, 0xca, 0x01, 0x20, 0xdc, 0xe1, 0x1d, + 0xda, 0xc0, 0x1d, 0xc2, 0xc1, 0x1d, 0xe6, 0xa1, 0x0d, 0xcc, 0x01, 0x1e, + 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, 0x07, 0x79, 0xa8, + 0x87, 0x72, 0x00, 0x08, 0x77, 0x78, 0x87, 0x36, 0x98, 0x87, 0x74, 0x38, + 0x07, 0x77, 0x28, 0x07, 0x72, 0x68, 0x03, 0x7d, 0x28, 0x07, 0x79, 0x78, + 0x87, 0x79, 0x68, 0x03, 0x73, 0x80, 0x87, 0x36, 0x68, 0x87, 0x70, 0xa0, + 0x07, 0x74, 0x00, 0xe8, 0x41, 0x1e, 0xea, 0xa1, 0x1c, 0x00, 0xc2, 0x1d, + 0xde, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0x01, 0x1e, 0xe0, 0x21, 0x1d, + 0xdc, 0xe1, 0x1c, 0xda, 0xa0, 0x1d, 0xc2, 0x81, 0x1e, 0xd0, 0x01, 0xa0, + 0x07, 0x79, 0xa8, 0x87, 0x72, 0x00, 0x88, 0x79, 0xa0, 0x87, 0x70, 0x18, + 0x87, 0x75, 0x68, 0x03, 0x78, 0x90, 0x87, 0x77, 0xa0, 0x87, 0x72, 0x18, + 0x07, 0x7a, 0x78, 0x07, 0x79, 0x68, 0x03, 0x71, 0xa8, 0x07, 0x73, 0x30, + 0x87, 0x72, 0x90, 0x87, 0x36, 0x98, 0x87, 0x74, 0xd0, 0x87, 0x72, 0x00, + 0xf0, 0x00, 0x20, 0xea, 0xc1, 0x1d, 0xe6, 0x21, 0x1c, 0xcc, 0xa1, 0x1c, + 0xda, 0xc0, 0x1c, 0xe0, 0xa1, 0x0d, 0xda, 0x21, 0x1c, 0xe8, 0x01, 0x1d, + 0x00, 0x7a, 0x90, 0x87, 0x7a, 0x28, 0x07, 0x80, 0xa8, 0x87, 0x79, 0x28, + 0x87, 0x36, 0x98, 0x87, 0x77, 0x30, 0x07, 0x7a, 0x68, 0x03, 0x73, 0x60, + 0x87, 0x77, 0x08, 0x07, 0x7a, 0x00, 0xcc, 0x21, 0x1c, 0xd8, 0x61, 0x1e, + 0xca, 0x01, 0xd8, 0xb0, 0x08, 0x04, 0x90, 0x00, 0x0b, 0x50, 0x05, 0x69, + 0x00, 0x0a, 0x1b, 0x8c, 0xa1, 0x00, 0x16, 0xa0, 0xda, 0x60, 0x10, 0x06, + 0xb0, 0x00, 0xd5, 0x06, 0xa3, 0x38, 0x80, 0x05, 0xa8, 0x36, 0x18, 0xc6, + 0xff, 0xff, 0xff, 0xff, 0x0f, 0x80, 0x04, 0x50, 0x1b, 0x94, 0xe3, 0xff, + 0xff, 0xff, 0xff, 0x07, 0xa0, 0x0d, 0x80, 0x35, 0x00, 0x24, 0xa0, 0xda, + 0x60, 0x20, 0x01, 0xb0, 0x00, 0xd5, 0x06, 0x23, 0x11, 0x80, 0x05, 0xa8, + 0x00, 0x00, 0x00, 0x00, 0x49, 0x18, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x13, 0x8a, 0x40, 0x18, 0x88, 0x62, 0x42, 0x60, 0x4c, 0x18, 0x0e, 0x24, + 0x01, 0x00, 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, + 0x32, 0x22, 0x48, 0x09, 0x20, 0x64, 0x85, 0x04, 0x93, 0x22, 0xa4, 0x84, + 0x04, 0x93, 0x22, 0xe3, 0x84, 0xa1, 0x90, 0x14, 0x12, 0x4c, 0x8a, 0x8c, + 0x0b, 0x84, 0xa4, 0x4c, 0x10, 0x70, 0x33, 0x00, 0xc3, 0x08, 0x04, 0x30, + 0x8c, 0x20, 0x00, 0xc3, 0x08, 0x03, 0x70, 0x90, 0x34, 0x45, 0x94, 0x30, + 0xf9, 0xb2, 0xfb, 0x76, 0x84, 0xe0, 0x0c, 0x04, 0x22, 0xc6, 0x18, 0x63, + 0x10, 0x81, 0x10, 0x8e, 0x92, 0xa6, 0x88, 0x12, 0x26, 0xff, 0x9f, 0x88, + 0x6b, 0xa2, 0x22, 0xe2, 0xb7, 0x87, 0x7f, 0x1a, 0x23, 0x00, 0x06, 0x11, + 0x8c, 0xe0, 0x22, 0x69, 0x8a, 0x28, 0x61, 0xf2, 0x7f, 0x09, 0x60, 0x9e, + 0x85, 0x88, 0xfe, 0x69, 0x8c, 0x00, 0x18, 0x44, 0x40, 0x84, 0x82, 0x84, + 0x10, 0x44, 0x39, 0x27, 0x91, 0x2a, 0x03, 0x18, 0x83, 0xd8, 0x1c, 0x01, + 0x62, 0x84, 0xe0, 0xe6, 0x08, 0x82, 0x39, 0x02, 0x30, 0x18, 0x46, 0x10, + 0xa2, 0xa2, 0xbc, 0x93, 0x04, 0x94, 0x10, 0x80, 0x48, 0x73, 0x20, 0x20, + 0x05, 0xe2, 0x30, 0xc2, 0x10, 0x0d, 0x22, 0x04, 0xc2, 0x1c, 0x01, 0x28, + 0x0c, 0x22, 0x0c, 0xc2, 0x08, 0x00, 0x00, 0x00, 0x13, 0xc0, 0x20, 0x1c, + 0xd2, 0x41, 0x1e, 0xec, 0x80, 0x0e, 0xda, 0x20, 0x1c, 0xe0, 0x01, 0x1e, + 0xd8, 0xa1, 0x1c, 0xda, 0x80, 0x1e, 0xec, 0xe1, 0x1d, 0xe6, 0x21, 0x0e, + 0xe6, 0xc0, 0x0d, 0xe0, 0xc0, 0x0d, 0xe0, 0xa0, 0x0d, 0xe6, 0x21, 0x1d, + 0xda, 0xa1, 0x1e, 0xd8, 0x21, 0x1c, 0xe8, 0xe1, 0x1d, 0xe4, 0x61, 0xc3, + 0x6d, 0x94, 0x43, 0x1b, 0xc0, 0x83, 0x1e, 0xd8, 0x01, 0x1d, 0xe8, 0x81, + 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x41, 0x3a, 0xc4, 0x81, + 0x1e, 0xe0, 0x81, 0x1e, 0xe0, 0x41, 0x1b, 0xa4, 0x03, 0x1e, 0xe8, 0x01, + 0x1e, 0xe8, 0x01, 0x1e, 0xb4, 0x41, 0x3a, 0xc4, 0x81, 0x1d, 0xe8, 0x41, + 0x1c, 0xd8, 0x81, 0x1e, 0xc4, 0x81, 0x1d, 0xb4, 0x41, 0x3a, 0xcc, 0x81, + 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x41, + 0x3a, 0xd8, 0x01, 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, + 0x1d, 0xb4, 0x81, 0x39, 0xcc, 0x81, 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, + 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, 0x39, 0xd8, 0x01, 0x1d, 0xe8, 0x81, + 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x3d, 0xc4, 0x81, + 0x1d, 0xe8, 0x41, 0x1c, 0xd8, 0x81, 0x1e, 0xc4, 0x81, 0x1d, 0xb4, 0x81, + 0x3d, 0xc8, 0x01, 0x1d, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, 0x1e, 0xcc, 0x81, + 0x1c, 0xb4, 0x81, 0x3d, 0xcc, 0x81, 0x1c, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, + 0x1e, 0xcc, 0x81, 0x1c, 0xb4, 0x81, 0x3d, 0xd0, 0x01, 0x1e, 0xe8, 0x81, + 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, 0x3d, 0xd8, 0x01, + 0x1d, 0xe8, 0x81, 0x1d, 0xd0, 0x81, 0x1e, 0xd8, 0x01, 0x1d, 0xb4, 0x81, + 0x3d, 0xe4, 0x81, 0x1d, 0xe8, 0x41, 0x1c, 0xc8, 0x01, 0x1e, 0xe8, 0x41, + 0x1c, 0xc8, 0x01, 0x1e, 0xb4, 0x81, 0x3d, 0xc4, 0x81, 0x1c, 0xe0, 0x81, + 0x1e, 0xc4, 0x81, 0x1c, 0xe0, 0x81, 0x1e, 0xc4, 0x81, 0x1c, 0xe0, 0x41, + 0x1b, 0xd8, 0x43, 0x1c, 0xe4, 0x81, 0x1c, 0xe8, 0x81, 0x1c, 0xd4, 0x81, + 0x1d, 0xe8, 0x81, 0x1c, 0xd4, 0x81, 0x1d, 0xb4, 0x81, 0x3d, 0xc8, 0x41, + 0x1d, 0xd8, 0x81, 0x1e, 0xc8, 0x41, 0x1d, 0xd8, 0x81, 0x1e, 0xc8, 0x41, + 0x1d, 0xd8, 0x41, 0x1b, 0xd8, 0x43, 0x1d, 0xc4, 0x81, 0x1c, 0xe8, 0x41, + 0x1d, 0xc4, 0x81, 0x1c, 0xe8, 0x41, 0x1d, 0xc4, 0x81, 0x1c, 0xb4, 0x81, + 0x3d, 0xc4, 0x01, 0x1c, 0xc8, 0x01, 0x1d, 0xe8, 0x41, 0x1c, 0xc0, 0x81, + 0x1c, 0xd0, 0x81, 0x1e, 0xc4, 0x01, 0x1c, 0xc8, 0x01, 0x1d, 0xb4, 0x81, + 0x3b, 0xe0, 0x81, 0x1e, 0xc4, 0x81, 0x1d, 0xe8, 0xc1, 0x1c, 0xc8, 0x81, + 0x46, 0x08, 0x43, 0x46, 0x6c, 0x57, 0xfe, 0xe7, 0x6b, 0xd7, 0x7f, 0x11, + 0x01, 0x06, 0x43, 0x34, 0xd3, 0x90, 0x08, 0x88, 0x14, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x18, 0x12, 0x45, 0x0d, 0x03, + 0x04, 0x80, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x43, 0x22, + 0x6f, 0x9b, 0x80, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x40, 0x62, 0x83, 0x40, 0xd1, 0x9d, 0x01, 0x00, 0x80, 0x2c, 0x10, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x32, 0x1e, 0x98, 0x10, 0x19, 0x11, 0x4c, 0x90, + 0x8c, 0x09, 0x26, 0x47, 0xc6, 0x04, 0x43, 0x8a, 0x45, 0x50, 0x02, 0x85, + 0x30, 0x02, 0x50, 0x06, 0x05, 0x18, 0x50, 0x20, 0x05, 0x54, 0x60, 0xa5, + 0x50, 0x0c, 0x64, 0xc7, 0x12, 0x9c, 0x01, 0x00, 0xb1, 0x18, 0x00, 0x00, + 0x7b, 0x00, 0x00, 0x00, 0x33, 0x08, 0x80, 0x1c, 0xc4, 0xe1, 0x1c, 0x66, + 0x14, 0x01, 0x3d, 0x88, 0x43, 0x38, 0x84, 0xc3, 0x8c, 0x42, 0x80, 0x07, + 0x79, 0x78, 0x07, 0x73, 0x98, 0x71, 0x0c, 0xe6, 0x00, 0x0f, 0xed, 0x10, + 0x0e, 0xf4, 0x80, 0x0e, 0x33, 0x0c, 0x42, 0x1e, 0xc2, 0xc1, 0x1d, 0xce, + 0xa1, 0x1c, 0x66, 0x30, 0x05, 0x3d, 0x88, 0x43, 0x38, 0x84, 0x83, 0x1b, + 0xcc, 0x03, 0x3d, 0xc8, 0x43, 0x3d, 0x8c, 0x03, 0x3d, 0xcc, 0x78, 0x8c, + 0x74, 0x70, 0x07, 0x7b, 0x08, 0x07, 0x79, 0x48, 0x87, 0x70, 0x70, 0x07, + 0x7a, 0x70, 0x03, 0x76, 0x78, 0x87, 0x70, 0x20, 0x87, 0x19, 0xcc, 0x11, + 0x0e, 0xec, 0x90, 0x0e, 0xe1, 0x30, 0x0f, 0x6e, 0x30, 0x0f, 0xe3, 0xf0, + 0x0e, 0xf0, 0x50, 0x0e, 0x33, 0x10, 0xc4, 0x1d, 0xde, 0x21, 0x1c, 0xd8, + 0x21, 0x1d, 0xc2, 0x61, 0x1e, 0x66, 0x30, 0x89, 0x3b, 0xbc, 0x83, 0x3b, + 0xd0, 0x43, 0x39, 0xb4, 0x03, 0x3c, 0xbc, 0x83, 0x3c, 0x84, 0x03, 0x3b, + 0xcc, 0xf0, 0x14, 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x68, 0x87, + 0x72, 0x68, 0x07, 0x37, 0x80, 0x87, 0x70, 0x90, 0x87, 0x70, 0x60, 0x07, + 0x76, 0x28, 0x07, 0x76, 0xf8, 0x05, 0x76, 0x78, 0x87, 0x77, 0x80, 0x87, + 0x5f, 0x08, 0x87, 0x71, 0x18, 0x87, 0x72, 0x98, 0x87, 0x79, 0x98, 0x81, + 0x2c, 0xee, 0xf0, 0x0e, 0xee, 0xe0, 0x0e, 0xf5, 0xc0, 0x0e, 0xec, 0x30, + 0x03, 0x62, 0xc8, 0xa1, 0x1c, 0xe4, 0xa1, 0x1c, 0xcc, 0xa1, 0x1c, 0xe4, + 0xa1, 0x1c, 0xdc, 0x61, 0x1c, 0xca, 0x21, 0x1c, 0xc4, 0x81, 0x1d, 0xca, + 0x61, 0x06, 0xd6, 0x90, 0x43, 0x39, 0xc8, 0x43, 0x39, 0x98, 0x43, 0x39, + 0xc8, 0x43, 0x39, 0xb8, 0xc3, 0x38, 0x94, 0x43, 0x38, 0x88, 0x03, 0x3b, + 0x94, 0xc3, 0x2f, 0xbc, 0x83, 0x3c, 0xfc, 0x82, 0x3b, 0xd4, 0x03, 0x3b, + 0xb0, 0xc3, 0x0c, 0xc7, 0x69, 0x87, 0x70, 0x58, 0x87, 0x72, 0x70, 0x83, + 0x74, 0x68, 0x07, 0x78, 0x60, 0x87, 0x74, 0x18, 0x87, 0x74, 0xa0, 0x87, + 0x19, 0xce, 0x53, 0x0f, 0xee, 0x00, 0x0f, 0xf2, 0x50, 0x0e, 0xe4, 0x90, + 0x0e, 0xe3, 0x40, 0x0f, 0xe1, 0x20, 0x0e, 0xec, 0x50, 0x0e, 0x33, 0x20, + 0x28, 0x1d, 0xdc, 0xc1, 0x1e, 0xc2, 0x41, 0x1e, 0xd2, 0x21, 0x1c, 0xdc, + 0x81, 0x1e, 0xdc, 0xe0, 0x1c, 0xe4, 0xe1, 0x1d, 0xea, 0x01, 0x1e, 0x66, + 0x18, 0x51, 0x38, 0xb0, 0x43, 0x3a, 0x9c, 0x83, 0x3b, 0xcc, 0x50, 0x24, + 0x76, 0x60, 0x07, 0x7b, 0x68, 0x07, 0x37, 0x60, 0x87, 0x77, 0x78, 0x07, + 0x78, 0x98, 0x51, 0x4c, 0xf4, 0x90, 0x0f, 0xf0, 0x50, 0x0e, 0x33, 0x1e, + 0x6a, 0x1e, 0xca, 0x61, 0x1c, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x7e, + 0x01, 0x1e, 0xe4, 0xa1, 0x1c, 0xcc, 0x21, 0x1d, 0xf0, 0x61, 0x06, 0x54, + 0x85, 0x83, 0x38, 0xcc, 0xc3, 0x3b, 0xb0, 0x43, 0x3d, 0xd0, 0x43, 0x39, + 0xfc, 0xc2, 0x3c, 0xe4, 0x43, 0x3b, 0x88, 0xc3, 0x3b, 0xb0, 0xc3, 0x8c, + 0xc5, 0x0a, 0x87, 0x79, 0x98, 0x87, 0x77, 0x18, 0x87, 0x74, 0x08, 0x07, + 0x7a, 0x28, 0x07, 0x72, 0x98, 0x81, 0x5c, 0xe3, 0x10, 0x0e, 0xec, 0xc0, + 0x0e, 0xe5, 0x50, 0x0e, 0xf3, 0x30, 0x23, 0xc1, 0xd2, 0x41, 0x1e, 0xe4, + 0xe1, 0x17, 0xd8, 0xe1, 0x1d, 0xde, 0x01, 0x1e, 0x66, 0x50, 0x59, 0x38, + 0xa4, 0x83, 0x3c, 0xb8, 0x81, 0x39, 0xd4, 0x83, 0x3b, 0x8c, 0x03, 0x3d, + 0xa4, 0xc3, 0x3b, 0xb8, 0xc3, 0x2f, 0x9c, 0x83, 0x3c, 0xbc, 0x43, 0x3d, + 0xc0, 0xc3, 0x3c, 0x00, 0x79, 0x20, 0x00, 0x00, 0x09, 0x01, 0x00, 0x00, + 0x32, 0x9a, 0x08, 0x14, 0x02, 0x85, 0x8c, 0x27, 0x46, 0x46, 0xc8, 0x11, + 0x32, 0x64, 0xd4, 0xd8, 0x80, 0x0c, 0xea, 0x09, 0x8b, 0x02, 0x07, 0xc5, + 0xc6, 0x91, 0x41, 0x14, 0x19, 0x8c, 0x22, 0x31, 0x88, 0x64, 0x3d, 0x45, + 0x66, 0x20, 0xca, 0x23, 0x21, 0x94, 0x61, 0x18, 0x86, 0x11, 0x5d, 0x89, + 0xb1, 0x28, 0x18, 0x51, 0x2c, 0x47, 0x00, 0x00, 0x53, 0x44, 0x4b, 0x20, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x77, 0x63, 0x68, 0x61, 0x72, + 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x4c, + 0x4c, 0x56, 0x4d, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, + 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x20, 0x28, 0x6d, 0x65, + 0x74, 0x61, 0x6c, 0x66, 0x65, 0x2d, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, + 0x35, 0x30, 0x2e, 0x31, 0x29, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x61, 0x69, + 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x64, 0x65, + 0x6e, 0x6f, 0x72, 0x6d, 0x73, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, + 0x65, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, + 0x2e, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x6d, 0x61, 0x74, 0x68, 0x5f, 0x65, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x63, 0x6f, 0x6d, + 0x70, 0x69, 0x6c, 0x65, 0x2e, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x62, 0x75, + 0x66, 0x66, 0x65, 0x72, 0x5f, 0x66, 0x65, 0x74, 0x63, 0x68, 0x5f, 0x65, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x61, 0x69, 0x72, 0x2e, 0x72, 0x65, 0x6e, + 0x64, 0x65, 0x72, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x61, 0x69, + 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x61, 0x69, 0x72, + 0x2e, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x69, 0x72, + 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x61, 0x69, 0x72, 0x2e, 0x6e, + 0x6f, 0x5f, 0x70, 0x65, 0x72, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x69, 0x72, + 0x2e, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x6e, + 0x70, 0x75, 0x74, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, + 0x28, 0x35, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x44, 0x76, 0x34, 0x5f, 0x66, + 0x29, 0x61, 0x69, 0x72, 0x2e, 0x70, 0x65, 0x72, 0x73, 0x70, 0x65, 0x63, + 0x74, 0x69, 0x76, 0x65, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x67, 0x65, 0x6e, + 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x28, 0x38, 0x74, 0x65, 0x78, 0x63, + 0x6f, 0x6f, 0x72, 0x64, 0x44, 0x76, 0x32, 0x5f, 0x66, 0x29, 0x66, 0x6c, + 0x6f, 0x61, 0x74, 0x32, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, + 0x61, 0x69, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x61, 0x69, + 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x7a, + 0x65, 0x61, 0x69, 0x72, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x61, 0x69, 0x72, 0x2e, 0x72, + 0x65, 0x61, 0x64, 0x61, 0x69, 0x72, 0x2e, 0x73, 0x74, 0x72, 0x75, 0x63, + 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x66, + 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x52, + 0x63, 0x6f, 0x65, 0x66, 0x66, 0x47, 0x63, 0x6f, 0x65, 0x66, 0x66, 0x42, + 0x63, 0x6f, 0x65, 0x66, 0x66, 0x61, 0x69, 0x72, 0x2e, 0x61, 0x72, 0x67, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x61, 0x69, + 0x72, 0x2e, 0x61, 0x72, 0x67, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x61, + 0x6c, 0x69, 0x67, 0x6e, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x59, 0x55, 0x56, + 0x44, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x65, 0x63, 0x6f, 0x64, 0x65, + 0x61, 0x69, 0x72, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x61, + 0x69, 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x78, + 0x74, 0x75, 0x72, 0x65, 0x32, 0x64, 0x3c, 0x66, 0x6c, 0x6f, 0x61, 0x74, + 0x2c, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x3e, 0x74, 0x65, 0x78, + 0x59, 0x74, 0x65, 0x78, 0x55, 0x56, 0x61, 0x69, 0x72, 0x2e, 0x73, 0x61, + 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, + 0x73, 0x00, 0x00, 0x00, 0x44, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x82, 0x10, 0x0d, 0x23, 0x08, 0x96, 0x33, 0x82, 0x10, 0x11, 0x23, + 0x08, 0x51, 0x31, 0x82, 0x10, 0x19, 0x23, 0x08, 0x0b, 0x30, 0x82, 0x10, + 0x1d, 0x23, 0x08, 0x11, 0x32, 0x82, 0x10, 0x25, 0x23, 0x08, 0x91, 0x32, + 0x82, 0x10, 0x2d, 0x23, 0x08, 0x11, 0x33, 0x82, 0x10, 0x35, 0x33, 0x0c, + 0x6d, 0x10, 0xb8, 0xc1, 0x0c, 0xc3, 0x1b, 0x08, 0x70, 0x30, 0x43, 0x30, + 0xcc, 0x30, 0xb4, 0x41, 0x1b, 0xc4, 0xc1, 0x0c, 0x04, 0xf1, 0x06, 0x6f, + 0x10, 0x07, 0x33, 0x04, 0xc5, 0x0c, 0x81, 0x31, 0x43, 0x70, 0xcc, 0x50, + 0x20, 0x71, 0x10, 0x07, 0x89, 0x32, 0x43, 0x20, 0x0a, 0x33, 0x20, 0x71, + 0xb0, 0x30, 0x4d, 0xa2, 0x38, 0xcf, 0x0c, 0xc9, 0x1b, 0x40, 0x11, 0x23, + 0x25, 0x8a, 0x33, 0xcd, 0x90, 0xb4, 0x01, 0x44, 0x31, 0x52, 0x52, 0x39, + 0xd6, 0x0c, 0x54, 0x1c, 0xd4, 0x41, 0x1c, 0x70, 0x5d, 0x1d, 0xd4, 0x41, + 0x1c, 0x70, 0x9e, 0x1d, 0xd4, 0x41, 0x1c, 0x70, 0xdf, 0x1d, 0xd4, 0x41, + 0x1c, 0x70, 0x60, 0x30, 0x83, 0x34, 0x07, 0x17, 0x46, 0x07, 0xd9, 0x1b, + 0xbc, 0x81, 0xb6, 0x9d, 0x42, 0x18, 0xd0, 0x81, 0x18, 0xd4, 0x41, 0x32, + 0x06, 0x0e, 0x19, 0xcc, 0xa0, 0xc0, 0x41, 0x19, 0x64, 0x71, 0xf0, 0x06, + 0x66, 0x90, 0x9c, 0x81, 0x83, 0x06, 0x33, 0x28, 0x78, 0x50, 0x06, 0xd9, + 0x1b, 0xbc, 0x81, 0x19, 0x24, 0x67, 0xe0, 0xa4, 0xc1, 0x0c, 0x49, 0x1e, + 0xa8, 0x41, 0x16, 0x07, 0x6f, 0x90, 0xac, 0x81, 0xc3, 0x06, 0x33, 0x1c, + 0xa4, 0x50, 0x0a, 0xa6, 0x80, 0x0a, 0xa9, 0xa0, 0x0a, 0xab, 0x30, 0xc3, + 0x20, 0x07, 0xa3, 0xc0, 0x0a, 0x15, 0x06, 0x00, 0xc7, 0x71, 0x1c, 0xc7, + 0x71, 0x1c, 0xc7, 0x71, 0x1c, 0xe7, 0x06, 0x6e, 0x60, 0xd1, 0x81, 0x1e, + 0x58, 0x96, 0xa5, 0x07, 0x9c, 0x29, 0xb0, 0x02, 0x2b, 0xd8, 0x86, 0x5f, + 0xd8, 0x83, 0x3d, 0xa8, 0x03, 0x39, 0xc8, 0x48, 0x60, 0x82, 0x2e, 0x62, + 0x63, 0xb3, 0x6b, 0x73, 0x69, 0x7b, 0x23, 0xab, 0x63, 0x2b, 0x73, 0x31, + 0x63, 0x0b, 0x3b, 0x9b, 0x1b, 0x45, 0xc8, 0x03, 0x3d, 0x38, 0x85, 0x8d, + 0xcd, 0xae, 0xcd, 0x25, 0x8d, 0xac, 0xcc, 0x8d, 0x6e, 0x94, 0x60, 0x0f, + 0x6e, 0x09, 0x4b, 0x93, 0x73, 0xb1, 0x2b, 0x93, 0x9b, 0x4b, 0x7b, 0x73, + 0x1b, 0x25, 0xe0, 0x83, 0xa3, 0xc2, 0xd2, 0xe4, 0x5c, 0xd8, 0xc2, 0xdc, + 0xce, 0xea, 0xc2, 0xce, 0xca, 0xbe, 0xec, 0xca, 0xe4, 0xe6, 0xd2, 0xde, + 0xdc, 0x46, 0x09, 0xfa, 0xe0, 0xa6, 0xb0, 0x34, 0x39, 0x97, 0xb1, 0xb7, + 0x36, 0xb8, 0x34, 0xb6, 0xb2, 0xaf, 0x37, 0x38, 0xba, 0xb4, 0x37, 0xb7, + 0xb9, 0x51, 0x06, 0x3f, 0xf8, 0x03, 0x50, 0x38, 0x26, 0x2c, 0x4d, 0xce, + 0xc5, 0x4c, 0x2e, 0xec, 0xac, 0xad, 0xcc, 0x8d, 0x6e, 0x94, 0x80, 0x15, + 0x00, 0x00, 0x00, 0x00, 0xa9, 0x18, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0x0b, 0x0a, 0x72, 0x28, 0x87, 0x77, 0x80, 0x07, 0x7a, 0x58, 0x70, 0x98, + 0x43, 0x3d, 0xb8, 0xc3, 0x38, 0xb0, 0x43, 0x39, 0xd0, 0xc3, 0x82, 0xe6, + 0x1c, 0xc6, 0xa1, 0x0d, 0xe8, 0x41, 0x1e, 0xc2, 0xc1, 0x1d, 0xe6, 0x21, + 0x1d, 0xe8, 0x21, 0x1d, 0xde, 0xc1, 0x1d, 0x00, 0xd1, 0x10, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x07, 0xcc, 0x3c, 0xa4, 0x83, 0x3b, 0x9c, 0x03, + 0x3b, 0x94, 0x03, 0x3d, 0xa0, 0x83, 0x3c, 0x94, 0x43, 0x38, 0x90, 0xc3, + 0x01, 0x00, 0x00, 0x00, 0x61, 0x20, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, + 0x13, 0x04, 0x41, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x04, 0x6b, 0x60, 0x04, 0x80, 0xe2, 0x0c, 0x00, 0xc9, 0x11, 0x80, 0xb1, + 0x84, 0x00, 0xa0, 0x3b, 0xd6, 0x00, 0x04, 0xc2, 0x1c, 0x83, 0x81, 0x61, + 0x73, 0x0c, 0x06, 0x81, 0x8d, 0x35, 0x00, 0x03, 0x41, 0x79, 0x04, 0x80, + 0xc0, 0x08, 0xc0, 0x0c, 0xc0, 0x18, 0x01, 0x08, 0x82, 0x20, 0xfe, 0x51, + 0x98, 0x01, 0x98, 0x83, 0x08, 0x83, 0x30, 0x08, 0x03, 0x31, 0x20, 0x31, + 0x03, 0x00, 0x00, 0x00, 0x23, 0x06, 0xcd, 0x10, 0x82, 0x60, 0x30, 0x91, + 0xc1, 0x14, 0x55, 0x50, 0xf3, 0x18, 0x06, 0x18, 0x8c, 0x26, 0x04, 0xc0, + 0x20, 0x43, 0x50, 0x30, 0x23, 0x06, 0xcd, 0x10, 0x82, 0x60, 0x30, 0x9d, + 0x41, 0x45, 0x61, 0x13, 0x24, 0x25, 0xc9, 0x18, 0x8c, 0x26, 0x04, 0xc0, + 0x20, 0x43, 0x80, 0x44, 0x83, 0x0c, 0xc1, 0xf1, 0x0c, 0x32, 0x14, 0xc1, + 0x73, 0x1c, 0x5e, 0x0a, 0x42, 0x19, 0x64, 0x08, 0x9a, 0xca, 0x88, 0x00, + 0xfc, 0x37, 0x19, 0xc0, 0x60, 0x72, 0x83, 0x0b, 0xf0, 0x52, 0x10, 0xca, + 0x20, 0x43, 0x20, 0x69, 0x23, 0x06, 0x87, 0x10, 0x82, 0x60, 0xe1, 0x1f, + 0x4c, 0x1d, 0x14, 0xc1, 0x26, 0x43, 0x19, 0x60, 0x74, 0x70, 0x01, 0x5e, + 0x0a, 0x42, 0x19, 0x64, 0x08, 0xae, 0x6f, 0xc4, 0xe0, 0x10, 0x42, 0x10, + 0x2c, 0xfc, 0x83, 0xd1, 0x03, 0x25, 0xd8, 0x64, 0x50, 0x83, 0xae, 0x0e, + 0x2e, 0xc0, 0x4b, 0x41, 0x28, 0x83, 0x0c, 0x01, 0x47, 0x06, 0x23, 0x06, + 0x87, 0x10, 0x82, 0x60, 0xe1, 0x1f, 0xcc, 0x1f, 0x3c, 0xc1, 0x1c, 0x43, + 0xb7, 0xec, 0xc1, 0x1c, 0x43, 0x70, 0xf8, 0xc1, 0x1c, 0x43, 0x30, 0x80, + 0x82, 0x05, 0x74, 0x20, 0xfe, 0x19, 0x00, 0x00, 0x71, 0x20, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x32, 0x0e, 0x10, 0x22, 0x84, 0x00, 0xfb, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x0c, 0x00, 0x00, + 0x29, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0x38, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x24, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x08, 0x24, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, + 0x1b, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x08, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x5d, 0x0c, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x12, 0x03, 0x94, 0xe3, + 0x00, 0x00, 0x00, 0x00, 0x53, 0x44, 0x4c, 0x5f, 0x4e, 0x56, 0x32, 0x31, + 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x69, 0x72, + 0x2e, 0x64, 0x6f, 0x74, 0x2e, 0x76, 0x33, 0x66, 0x33, 0x32, 0x61, 0x69, + 0x72, 0x2e, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x74, 0x65, 0x78, + 0x74, 0x75, 0x72, 0x65, 0x5f, 0x32, 0x64, 0x2e, 0x76, 0x34, 0x66, 0x33, + 0x32, 0x33, 0x31, 0x30, 0x30, 0x31, 0x2e, 0x35, 0x30, 0x2e, 0x31, 0x61, + 0x69, 0x72, 0x36, 0x34, 0x2d, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2d, 0x74, + 0x76, 0x6f, 0x73, 0x31, 0x33, 0x2e, 0x30, 0x2e, 0x30, 0x2d, 0x73, 0x69, + 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; +const unsigned int sdl_metallib_len = 24676; diff --git a/SDL2-2.0.12/src/render/metal/build-metal-shaders.sh b/SDL2-2.30.5/src/render/metal/build-metal-shaders.sh similarity index 84% rename from SDL2-2.0.12/src/render/metal/build-metal-shaders.sh rename to SDL2-2.30.5/src/render/metal/build-metal-shaders.sh index fb4ddb7..0f3e48e 100644 --- a/SDL2-2.0.12/src/render/metal/build-metal-shaders.sh +++ b/SDL2-2.30.5/src/render/metal/build-metal-shaders.sh @@ -6,7 +6,7 @@ cd `dirname "$0"` generate_shaders() { - fileplatform=$1 + fileplatform=$1 compileplatform=$2 sdkplatform=$3 minversion=$4 @@ -19,4 +19,6 @@ generate_shaders() generate_shaders osx osx macosx 10.11 generate_shaders ios ios iphoneos 8.0 +generate_shaders iphonesimulator ios iphonesimulator 8.0 generate_shaders tvos ios appletvos 9.0 +generate_shaders tvsimulator ios appletvsimulator 9.0 diff --git a/SDL2-2.0.12/src/render/opengl/SDL_glfuncs.h b/SDL2-2.30.5/src/render/opengl/SDL_glfuncs.h similarity index 67% rename from SDL2-2.0.12/src/render/opengl/SDL_glfuncs.h rename to SDL2-2.30.5/src/render/opengl/SDL_glfuncs.h index 36846db..860b9c0 100644 --- a/SDL2-2.0.12/src/render/opengl/SDL_glfuncs.h +++ b/SDL2-2.30.5/src/render/opengl/SDL_glfuncs.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,7 +23,7 @@ If you need to use a GL function from the SDL video subsystem, change its entry from SDL_PROC_UNUSED to SDL_PROC and rebuild. */ -#define SDL_PROC_UNUSED(ret,func,params) +#define SDL_PROC_UNUSED(ret, func, params) SDL_PROC_UNUSED(void, glAccum, (GLenum, GLfloat)) SDL_PROC_UNUSED(void, glAlphaFunc, (GLenum, GLclampf)) @@ -73,22 +73,22 @@ SDL_PROC_UNUSED(void, glColor4i, (GLint, GLint, GLint, GLint)) SDL_PROC_UNUSED(void, glColor4iv, (const GLint *)) SDL_PROC_UNUSED(void, glColor4s, (GLshort, GLshort, GLshort, GLshort)) SDL_PROC_UNUSED(void, glColor4sv, (const GLshort *)) -SDL_PROC_UNUSED(void, glColor4ub, - (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)) -SDL_PROC_UNUSED(void, glColor4ubv, (const GLubyte * v)) +SDL_PROC(void, glColor4ub, + (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)) +SDL_PROC_UNUSED(void, glColor4ubv, (const GLubyte *v)) SDL_PROC_UNUSED(void, glColor4ui, (GLuint red, GLuint green, GLuint blue, GLuint alpha)) -SDL_PROC_UNUSED(void, glColor4uiv, (const GLuint * v)) +SDL_PROC_UNUSED(void, glColor4uiv, (const GLuint *v)) SDL_PROC_UNUSED(void, glColor4us, (GLushort red, GLushort green, GLushort blue, GLushort alpha)) -SDL_PROC_UNUSED(void, glColor4usv, (const GLushort * v)) +SDL_PROC_UNUSED(void, glColor4usv, (const GLushort *v)) SDL_PROC_UNUSED(void, glColorMask, (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)) SDL_PROC_UNUSED(void, glColorMaterial, (GLenum face, GLenum mode)) -SDL_PROC_UNUSED(void, glColorPointer, - (GLint size, GLenum type, GLsizei stride, - const GLvoid * pointer)) +SDL_PROC(void, glColorPointer, + (GLint size, GLenum type, GLsizei stride, + const GLvoid *pointer)) SDL_PROC_UNUSED(void, glCopyPixels, (GLint x, GLint y, GLsizei width, GLsizei height, GLenum type)) @@ -106,151 +106,151 @@ SDL_PROC_UNUSED(void, glCopyTexSubImage2D, GLint x, GLint y, GLsizei width, GLsizei height)) SDL_PROC_UNUSED(void, glCullFace, (GLenum mode)) SDL_PROC_UNUSED(void, glDeleteLists, (GLuint list, GLsizei range)) -SDL_PROC(void, glDeleteTextures, (GLsizei n, const GLuint * textures)) +SDL_PROC(void, glDeleteTextures, (GLsizei n, const GLuint *textures)) SDL_PROC(void, glDepthFunc, (GLenum func)) SDL_PROC_UNUSED(void, glDepthMask, (GLboolean flag)) SDL_PROC_UNUSED(void, glDepthRange, (GLclampd zNear, GLclampd zFar)) SDL_PROC(void, glDisable, (GLenum cap)) -SDL_PROC_UNUSED(void, glDisableClientState, (GLenum array)) -SDL_PROC_UNUSED(void, glDrawArrays, (GLenum mode, GLint first, GLsizei count)) +SDL_PROC(void, glDisableClientState, (GLenum array)) +SDL_PROC(void, glDrawArrays, (GLenum mode, GLint first, GLsizei count)) SDL_PROC_UNUSED(void, glDrawBuffer, (GLenum mode)) SDL_PROC_UNUSED(void, glDrawElements, (GLenum mode, GLsizei count, GLenum type, - const GLvoid * indices)) + const GLvoid *indices)) SDL_PROC(void, glDrawPixels, (GLsizei width, GLsizei height, GLenum format, GLenum type, - const GLvoid * pixels)) + const GLvoid *pixels)) SDL_PROC_UNUSED(void, glEdgeFlag, (GLboolean flag)) SDL_PROC_UNUSED(void, glEdgeFlagPointer, - (GLsizei stride, const GLvoid * pointer)) -SDL_PROC_UNUSED(void, glEdgeFlagv, (const GLboolean * flag)) + (GLsizei stride, const GLvoid *pointer)) +SDL_PROC_UNUSED(void, glEdgeFlagv, (const GLboolean *flag)) SDL_PROC(void, glEnable, (GLenum cap)) -SDL_PROC_UNUSED(void, glEnableClientState, (GLenum array)) +SDL_PROC(void, glEnableClientState, (GLenum array)) SDL_PROC(void, glEnd, (void)) SDL_PROC_UNUSED(void, glEndList, (void)) SDL_PROC_UNUSED(void, glEvalCoord1d, (GLdouble u)) -SDL_PROC_UNUSED(void, glEvalCoord1dv, (const GLdouble * u)) +SDL_PROC_UNUSED(void, glEvalCoord1dv, (const GLdouble *u)) SDL_PROC_UNUSED(void, glEvalCoord1f, (GLfloat u)) -SDL_PROC_UNUSED(void, glEvalCoord1fv, (const GLfloat * u)) +SDL_PROC_UNUSED(void, glEvalCoord1fv, (const GLfloat *u)) SDL_PROC_UNUSED(void, glEvalCoord2d, (GLdouble u, GLdouble v)) -SDL_PROC_UNUSED(void, glEvalCoord2dv, (const GLdouble * u)) +SDL_PROC_UNUSED(void, glEvalCoord2dv, (const GLdouble *u)) SDL_PROC_UNUSED(void, glEvalCoord2f, (GLfloat u, GLfloat v)) -SDL_PROC_UNUSED(void, glEvalCoord2fv, (const GLfloat * u)) +SDL_PROC_UNUSED(void, glEvalCoord2fv, (const GLfloat *u)) SDL_PROC_UNUSED(void, glEvalMesh1, (GLenum mode, GLint i1, GLint i2)) SDL_PROC_UNUSED(void, glEvalMesh2, (GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2)) SDL_PROC_UNUSED(void, glEvalPoint1, (GLint i)) SDL_PROC_UNUSED(void, glEvalPoint2, (GLint i, GLint j)) SDL_PROC_UNUSED(void, glFeedbackBuffer, - (GLsizei size, GLenum type, GLfloat * buffer)) + (GLsizei size, GLenum type, GLfloat *buffer)) SDL_PROC_UNUSED(void, glFinish, (void)) SDL_PROC_UNUSED(void, glFlush, (void)) SDL_PROC_UNUSED(void, glFogf, (GLenum pname, GLfloat param)) -SDL_PROC_UNUSED(void, glFogfv, (GLenum pname, const GLfloat * params)) +SDL_PROC_UNUSED(void, glFogfv, (GLenum pname, const GLfloat *params)) SDL_PROC_UNUSED(void, glFogi, (GLenum pname, GLint param)) -SDL_PROC_UNUSED(void, glFogiv, (GLenum pname, const GLint * params)) +SDL_PROC_UNUSED(void, glFogiv, (GLenum pname, const GLint *params)) SDL_PROC_UNUSED(void, glFrontFace, (GLenum mode)) SDL_PROC_UNUSED(void, glFrustum, (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)) SDL_PROC_UNUSED(GLuint, glGenLists, (GLsizei range)) -SDL_PROC(void, glGenTextures, (GLsizei n, GLuint * textures)) -SDL_PROC_UNUSED(void, glGetBooleanv, (GLenum pname, GLboolean * params)) -SDL_PROC_UNUSED(void, glGetClipPlane, (GLenum plane, GLdouble * equation)) -SDL_PROC_UNUSED(void, glGetDoublev, (GLenum pname, GLdouble * params)) +SDL_PROC(void, glGenTextures, (GLsizei n, GLuint *textures)) +SDL_PROC_UNUSED(void, glGetBooleanv, (GLenum pname, GLboolean *params)) +SDL_PROC_UNUSED(void, glGetClipPlane, (GLenum plane, GLdouble *equation)) +SDL_PROC_UNUSED(void, glGetDoublev, (GLenum pname, GLdouble *params)) SDL_PROC(GLenum, glGetError, (void)) -SDL_PROC_UNUSED(void, glGetFloatv, (GLenum pname, GLfloat * params)) -SDL_PROC(void, glGetIntegerv, (GLenum pname, GLint * params)) +SDL_PROC(void, glGetFloatv, (GLenum pname, GLfloat *params)) +SDL_PROC(void, glGetIntegerv, (GLenum pname, GLint *params)) SDL_PROC_UNUSED(void, glGetLightfv, - (GLenum light, GLenum pname, GLfloat * params)) + (GLenum light, GLenum pname, GLfloat *params)) SDL_PROC_UNUSED(void, glGetLightiv, - (GLenum light, GLenum pname, GLint * params)) -SDL_PROC_UNUSED(void, glGetMapdv, (GLenum target, GLenum query, GLdouble * v)) -SDL_PROC_UNUSED(void, glGetMapfv, (GLenum target, GLenum query, GLfloat * v)) -SDL_PROC_UNUSED(void, glGetMapiv, (GLenum target, GLenum query, GLint * v)) + (GLenum light, GLenum pname, GLint *params)) +SDL_PROC_UNUSED(void, glGetMapdv, (GLenum target, GLenum query, GLdouble *v)) +SDL_PROC_UNUSED(void, glGetMapfv, (GLenum target, GLenum query, GLfloat *v)) +SDL_PROC_UNUSED(void, glGetMapiv, (GLenum target, GLenum query, GLint *v)) SDL_PROC_UNUSED(void, glGetMaterialfv, - (GLenum face, GLenum pname, GLfloat * params)) + (GLenum face, GLenum pname, GLfloat *params)) SDL_PROC_UNUSED(void, glGetMaterialiv, - (GLenum face, GLenum pname, GLint * params)) -SDL_PROC_UNUSED(void, glGetPixelMapfv, (GLenum map, GLfloat * values)) -SDL_PROC_UNUSED(void, glGetPixelMapuiv, (GLenum map, GLuint * values)) -SDL_PROC_UNUSED(void, glGetPixelMapusv, (GLenum map, GLushort * values)) -SDL_PROC(void, glGetPointerv, (GLenum pname, GLvoid * *params)) + (GLenum face, GLenum pname, GLint *params)) +SDL_PROC_UNUSED(void, glGetPixelMapfv, (GLenum map, GLfloat *values)) +SDL_PROC_UNUSED(void, glGetPixelMapuiv, (GLenum map, GLuint *values)) +SDL_PROC_UNUSED(void, glGetPixelMapusv, (GLenum map, GLushort *values)) +SDL_PROC(void, glGetPointerv, (GLenum pname, GLvoid **params)) SDL_PROC_UNUSED(void, glGetPolygonStipple, (GLubyte * mask)) SDL_PROC(const GLubyte *, glGetString, (GLenum name)) SDL_PROC_UNUSED(void, glGetTexEnvfv, - (GLenum target, GLenum pname, GLfloat * params)) + (GLenum target, GLenum pname, GLfloat *params)) SDL_PROC_UNUSED(void, glGetTexEnviv, - (GLenum target, GLenum pname, GLint * params)) + (GLenum target, GLenum pname, GLint *params)) SDL_PROC_UNUSED(void, glGetTexGendv, - (GLenum coord, GLenum pname, GLdouble * params)) + (GLenum coord, GLenum pname, GLdouble *params)) SDL_PROC_UNUSED(void, glGetTexGenfv, - (GLenum coord, GLenum pname, GLfloat * params)) + (GLenum coord, GLenum pname, GLfloat *params)) SDL_PROC_UNUSED(void, glGetTexGeniv, - (GLenum coord, GLenum pname, GLint * params)) + (GLenum coord, GLenum pname, GLint *params)) SDL_PROC_UNUSED(void, glGetTexImage, (GLenum target, GLint level, GLenum format, GLenum type, - GLvoid * pixels)) + GLvoid *pixels)) SDL_PROC_UNUSED(void, glGetTexLevelParameterfv, - (GLenum target, GLint level, GLenum pname, GLfloat * params)) + (GLenum target, GLint level, GLenum pname, GLfloat *params)) SDL_PROC_UNUSED(void, glGetTexLevelParameteriv, - (GLenum target, GLint level, GLenum pname, GLint * params)) + (GLenum target, GLint level, GLenum pname, GLint *params)) SDL_PROC_UNUSED(void, glGetTexParameterfv, - (GLenum target, GLenum pname, GLfloat * params)) + (GLenum target, GLenum pname, GLfloat *params)) SDL_PROC_UNUSED(void, glGetTexParameteriv, - (GLenum target, GLenum pname, GLint * params)) + (GLenum target, GLenum pname, GLint *params)) SDL_PROC_UNUSED(void, glHint, (GLenum target, GLenum mode)) SDL_PROC_UNUSED(void, glIndexMask, (GLuint mask)) SDL_PROC_UNUSED(void, glIndexPointer, - (GLenum type, GLsizei stride, const GLvoid * pointer)) + (GLenum type, GLsizei stride, const GLvoid *pointer)) SDL_PROC_UNUSED(void, glIndexd, (GLdouble c)) -SDL_PROC_UNUSED(void, glIndexdv, (const GLdouble * c)) +SDL_PROC_UNUSED(void, glIndexdv, (const GLdouble *c)) SDL_PROC_UNUSED(void, glIndexf, (GLfloat c)) -SDL_PROC_UNUSED(void, glIndexfv, (const GLfloat * c)) +SDL_PROC_UNUSED(void, glIndexfv, (const GLfloat *c)) SDL_PROC_UNUSED(void, glIndexi, (GLint c)) -SDL_PROC_UNUSED(void, glIndexiv, (const GLint * c)) +SDL_PROC_UNUSED(void, glIndexiv, (const GLint *c)) SDL_PROC_UNUSED(void, glIndexs, (GLshort c)) -SDL_PROC_UNUSED(void, glIndexsv, (const GLshort * c)) +SDL_PROC_UNUSED(void, glIndexsv, (const GLshort *c)) SDL_PROC_UNUSED(void, glIndexub, (GLubyte c)) -SDL_PROC_UNUSED(void, glIndexubv, (const GLubyte * c)) +SDL_PROC_UNUSED(void, glIndexubv, (const GLubyte *c)) SDL_PROC_UNUSED(void, glInitNames, (void)) SDL_PROC_UNUSED(void, glInterleavedArrays, - (GLenum format, GLsizei stride, const GLvoid * pointer)) + (GLenum format, GLsizei stride, const GLvoid *pointer)) SDL_PROC_UNUSED(GLboolean, glIsEnabled, (GLenum cap)) SDL_PROC_UNUSED(GLboolean, glIsList, (GLuint list)) SDL_PROC_UNUSED(GLboolean, glIsTexture, (GLuint texture)) SDL_PROC_UNUSED(void, glLightModelf, (GLenum pname, GLfloat param)) -SDL_PROC_UNUSED(void, glLightModelfv, (GLenum pname, const GLfloat * params)) +SDL_PROC_UNUSED(void, glLightModelfv, (GLenum pname, const GLfloat *params)) SDL_PROC_UNUSED(void, glLightModeli, (GLenum pname, GLint param)) -SDL_PROC_UNUSED(void, glLightModeliv, (GLenum pname, const GLint * params)) +SDL_PROC_UNUSED(void, glLightModeliv, (GLenum pname, const GLint *params)) SDL_PROC_UNUSED(void, glLightf, (GLenum light, GLenum pname, GLfloat param)) SDL_PROC_UNUSED(void, glLightfv, - (GLenum light, GLenum pname, const GLfloat * params)) + (GLenum light, GLenum pname, const GLfloat *params)) SDL_PROC_UNUSED(void, glLighti, (GLenum light, GLenum pname, GLint param)) SDL_PROC_UNUSED(void, glLightiv, - (GLenum light, GLenum pname, const GLint * params)) + (GLenum light, GLenum pname, const GLint *params)) SDL_PROC_UNUSED(void, glLineStipple, (GLint factor, GLushort pattern)) SDL_PROC(void, glLineWidth, (GLfloat width)) SDL_PROC_UNUSED(void, glListBase, (GLuint base)) SDL_PROC(void, glLoadIdentity, (void)) -SDL_PROC_UNUSED(void, glLoadMatrixd, (const GLdouble * m)) -SDL_PROC_UNUSED(void, glLoadMatrixf, (const GLfloat * m)) +SDL_PROC_UNUSED(void, glLoadMatrixd, (const GLdouble *m)) +SDL_PROC_UNUSED(void, glLoadMatrixf, (const GLfloat *m)) SDL_PROC_UNUSED(void, glLoadName, (GLuint name)) SDL_PROC_UNUSED(void, glLogicOp, (GLenum opcode)) SDL_PROC_UNUSED(void, glMap1d, (GLenum target, GLdouble u1, GLdouble u2, GLint stride, - GLint order, const GLdouble * points)) + GLint order, const GLdouble *points)) SDL_PROC_UNUSED(void, glMap1f, (GLenum target, GLfloat u1, GLfloat u2, GLint stride, - GLint order, const GLfloat * points)) + GLint order, const GLfloat *points)) SDL_PROC_UNUSED(void, glMap2d, (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, - GLint vorder, const GLdouble * points)) + GLint vorder, const GLdouble *points)) SDL_PROC_UNUSED(void, glMap2f, (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, - GLint vorder, const GLfloat * points)) + GLint vorder, const GLfloat *points)) SDL_PROC_UNUSED(void, glMapGrid1d, (GLint un, GLdouble u1, GLdouble u2)) SDL_PROC_UNUSED(void, glMapGrid1f, (GLint un, GLfloat u1, GLfloat u2)) SDL_PROC_UNUSED(void, glMapGrid2d, @@ -261,36 +261,36 @@ SDL_PROC_UNUSED(void, glMapGrid2f, GLfloat v2)) SDL_PROC_UNUSED(void, glMaterialf, (GLenum face, GLenum pname, GLfloat param)) SDL_PROC_UNUSED(void, glMaterialfv, - (GLenum face, GLenum pname, const GLfloat * params)) + (GLenum face, GLenum pname, const GLfloat *params)) SDL_PROC_UNUSED(void, glMateriali, (GLenum face, GLenum pname, GLint param)) SDL_PROC_UNUSED(void, glMaterialiv, - (GLenum face, GLenum pname, const GLint * params)) + (GLenum face, GLenum pname, const GLint *params)) SDL_PROC(void, glMatrixMode, (GLenum mode)) -SDL_PROC_UNUSED(void, glMultMatrixd, (const GLdouble * m)) -SDL_PROC_UNUSED(void, glMultMatrixf, (const GLfloat * m)) +SDL_PROC_UNUSED(void, glMultMatrixd, (const GLdouble *m)) +SDL_PROC_UNUSED(void, glMultMatrixf, (const GLfloat *m)) SDL_PROC_UNUSED(void, glNewList, (GLuint list, GLenum mode)) SDL_PROC_UNUSED(void, glNormal3b, (GLbyte nx, GLbyte ny, GLbyte nz)) -SDL_PROC_UNUSED(void, glNormal3bv, (const GLbyte * v)) +SDL_PROC_UNUSED(void, glNormal3bv, (const GLbyte *v)) SDL_PROC_UNUSED(void, glNormal3d, (GLdouble nx, GLdouble ny, GLdouble nz)) -SDL_PROC_UNUSED(void, glNormal3dv, (const GLdouble * v)) +SDL_PROC_UNUSED(void, glNormal3dv, (const GLdouble *v)) SDL_PROC_UNUSED(void, glNormal3f, (GLfloat nx, GLfloat ny, GLfloat nz)) -SDL_PROC_UNUSED(void, glNormal3fv, (const GLfloat * v)) +SDL_PROC_UNUSED(void, glNormal3fv, (const GLfloat *v)) SDL_PROC_UNUSED(void, glNormal3i, (GLint nx, GLint ny, GLint nz)) -SDL_PROC_UNUSED(void, glNormal3iv, (const GLint * v)) +SDL_PROC_UNUSED(void, glNormal3iv, (const GLint *v)) SDL_PROC_UNUSED(void, glNormal3s, (GLshort nx, GLshort ny, GLshort nz)) -SDL_PROC_UNUSED(void, glNormal3sv, (const GLshort * v)) +SDL_PROC_UNUSED(void, glNormal3sv, (const GLshort *v)) SDL_PROC_UNUSED(void, glNormalPointer, - (GLenum type, GLsizei stride, const GLvoid * pointer)) + (GLenum type, GLsizei stride, const GLvoid *pointer)) SDL_PROC(void, glOrtho, (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)) SDL_PROC_UNUSED(void, glPassThrough, (GLfloat token)) SDL_PROC_UNUSED(void, glPixelMapfv, - (GLenum map, GLsizei mapsize, const GLfloat * values)) + (GLenum map, GLsizei mapsize, const GLfloat *values)) SDL_PROC_UNUSED(void, glPixelMapuiv, - (GLenum map, GLsizei mapsize, const GLuint * values)) + (GLenum map, GLsizei mapsize, const GLuint *values)) SDL_PROC_UNUSED(void, glPixelMapusv, - (GLenum map, GLsizei mapsize, const GLushort * values)) + (GLenum map, GLsizei mapsize, const GLushort *values)) SDL_PROC_UNUSED(void, glPixelStoref, (GLenum pname, GLfloat param)) SDL_PROC(void, glPixelStorei, (GLenum pname, GLint param)) SDL_PROC_UNUSED(void, glPixelTransferf, (GLenum pname, GLfloat param)) @@ -299,180 +299,180 @@ SDL_PROC_UNUSED(void, glPixelZoom, (GLfloat xfactor, GLfloat yfactor)) SDL_PROC(void, glPointSize, (GLfloat size)) SDL_PROC_UNUSED(void, glPolygonMode, (GLenum face, GLenum mode)) SDL_PROC_UNUSED(void, glPolygonOffset, (GLfloat factor, GLfloat units)) -SDL_PROC_UNUSED(void, glPolygonStipple, (const GLubyte * mask)) +SDL_PROC_UNUSED(void, glPolygonStipple, (const GLubyte *mask)) SDL_PROC_UNUSED(void, glPopAttrib, (void)) SDL_PROC_UNUSED(void, glPopClientAttrib, (void)) -SDL_PROC(void, glPopMatrix, (void)) +SDL_PROC_UNUSED(void, glPopMatrix, (void)) SDL_PROC_UNUSED(void, glPopName, (void)) SDL_PROC_UNUSED(void, glPrioritizeTextures, - (GLsizei n, const GLuint * textures, - const GLclampf * priorities)) + (GLsizei n, const GLuint *textures, + const GLclampf *priorities)) SDL_PROC_UNUSED(void, glPushAttrib, (GLbitfield mask)) SDL_PROC_UNUSED(void, glPushClientAttrib, (GLbitfield mask)) -SDL_PROC(void, glPushMatrix, (void)) +SDL_PROC_UNUSED(void, glPushMatrix, (void)) SDL_PROC_UNUSED(void, glPushName, (GLuint name)) SDL_PROC_UNUSED(void, glRasterPos2d, (GLdouble x, GLdouble y)) -SDL_PROC_UNUSED(void, glRasterPos2dv, (const GLdouble * v)) +SDL_PROC_UNUSED(void, glRasterPos2dv, (const GLdouble *v)) SDL_PROC_UNUSED(void, glRasterPos2f, (GLfloat x, GLfloat y)) -SDL_PROC_UNUSED(void, glRasterPos2fv, (const GLfloat * v)) +SDL_PROC_UNUSED(void, glRasterPos2fv, (const GLfloat *v)) SDL_PROC(void, glRasterPos2i, (GLint x, GLint y)) -SDL_PROC_UNUSED(void, glRasterPos2iv, (const GLint * v)) +SDL_PROC_UNUSED(void, glRasterPos2iv, (const GLint *v)) SDL_PROC_UNUSED(void, glRasterPos2s, (GLshort x, GLshort y)) -SDL_PROC_UNUSED(void, glRasterPos2sv, (const GLshort * v)) +SDL_PROC_UNUSED(void, glRasterPos2sv, (const GLshort *v)) SDL_PROC_UNUSED(void, glRasterPos3d, (GLdouble x, GLdouble y, GLdouble z)) -SDL_PROC_UNUSED(void, glRasterPos3dv, (const GLdouble * v)) +SDL_PROC_UNUSED(void, glRasterPos3dv, (const GLdouble *v)) SDL_PROC_UNUSED(void, glRasterPos3f, (GLfloat x, GLfloat y, GLfloat z)) -SDL_PROC_UNUSED(void, glRasterPos3fv, (const GLfloat * v)) +SDL_PROC_UNUSED(void, glRasterPos3fv, (const GLfloat *v)) SDL_PROC_UNUSED(void, glRasterPos3i, (GLint x, GLint y, GLint z)) -SDL_PROC_UNUSED(void, glRasterPos3iv, (const GLint * v)) +SDL_PROC_UNUSED(void, glRasterPos3iv, (const GLint *v)) SDL_PROC_UNUSED(void, glRasterPos3s, (GLshort x, GLshort y, GLshort z)) -SDL_PROC_UNUSED(void, glRasterPos3sv, (const GLshort * v)) +SDL_PROC_UNUSED(void, glRasterPos3sv, (const GLshort *v)) SDL_PROC_UNUSED(void, glRasterPos4d, (GLdouble x, GLdouble y, GLdouble z, GLdouble w)) -SDL_PROC_UNUSED(void, glRasterPos4dv, (const GLdouble * v)) +SDL_PROC_UNUSED(void, glRasterPos4dv, (const GLdouble *v)) SDL_PROC_UNUSED(void, glRasterPos4f, (GLfloat x, GLfloat y, GLfloat z, GLfloat w)) -SDL_PROC_UNUSED(void, glRasterPos4fv, (const GLfloat * v)) +SDL_PROC_UNUSED(void, glRasterPos4fv, (const GLfloat *v)) SDL_PROC_UNUSED(void, glRasterPos4i, (GLint x, GLint y, GLint z, GLint w)) -SDL_PROC_UNUSED(void, glRasterPos4iv, (const GLint * v)) +SDL_PROC_UNUSED(void, glRasterPos4iv, (const GLint *v)) SDL_PROC_UNUSED(void, glRasterPos4s, (GLshort x, GLshort y, GLshort z, GLshort w)) -SDL_PROC_UNUSED(void, glRasterPos4sv, (const GLshort * v)) +SDL_PROC_UNUSED(void, glRasterPos4sv, (const GLshort *v)) SDL_PROC(void, glReadBuffer, (GLenum mode)) SDL_PROC(void, glReadPixels, (GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, GLvoid * pixels)) + GLenum format, GLenum type, GLvoid *pixels)) SDL_PROC_UNUSED(void, glRectd, (GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2)) -SDL_PROC_UNUSED(void, glRectdv, (const GLdouble * v1, const GLdouble * v2)) +SDL_PROC_UNUSED(void, glRectdv, (const GLdouble *v1, const GLdouble *v2)) SDL_PROC(void, glRectf, - (GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)) -SDL_PROC_UNUSED(void, glRectfv, (const GLfloat * v1, const GLfloat * v2)) + (GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)) +SDL_PROC_UNUSED(void, glRectfv, (const GLfloat *v1, const GLfloat *v2)) SDL_PROC_UNUSED(void, glRecti, (GLint x1, GLint y1, GLint x2, GLint y2)) -SDL_PROC_UNUSED(void, glRectiv, (const GLint * v1, const GLint * v2)) +SDL_PROC_UNUSED(void, glRectiv, (const GLint *v1, const GLint *v2)) SDL_PROC_UNUSED(void, glRects, (GLshort x1, GLshort y1, GLshort x2, GLshort y2)) -SDL_PROC_UNUSED(void, glRectsv, (const GLshort * v1, const GLshort * v2)) +SDL_PROC_UNUSED(void, glRectsv, (const GLshort *v1, const GLshort *v2)) SDL_PROC_UNUSED(GLint, glRenderMode, (GLenum mode)) -SDL_PROC(void, glRotated, +SDL_PROC_UNUSED(void, glRotated, (GLdouble angle, GLdouble x, GLdouble y, GLdouble z)) SDL_PROC(void, glRotatef, - (GLfloat angle, GLfloat x, GLfloat y, GLfloat z)) + (GLfloat angle, GLfloat x, GLfloat y, GLfloat z)) SDL_PROC_UNUSED(void, glScaled, (GLdouble x, GLdouble y, GLdouble z)) SDL_PROC_UNUSED(void, glScalef, (GLfloat x, GLfloat y, GLfloat z)) SDL_PROC(void, glScissor, (GLint x, GLint y, GLsizei width, GLsizei height)) -SDL_PROC_UNUSED(void, glSelectBuffer, (GLsizei size, GLuint * buffer)) +SDL_PROC_UNUSED(void, glSelectBuffer, (GLsizei size, GLuint *buffer)) SDL_PROC(void, glShadeModel, (GLenum mode)) SDL_PROC_UNUSED(void, glStencilFunc, (GLenum func, GLint ref, GLuint mask)) SDL_PROC_UNUSED(void, glStencilMask, (GLuint mask)) SDL_PROC_UNUSED(void, glStencilOp, (GLenum fail, GLenum zfail, GLenum zpass)) SDL_PROC_UNUSED(void, glTexCoord1d, (GLdouble s)) -SDL_PROC_UNUSED(void, glTexCoord1dv, (const GLdouble * v)) +SDL_PROC_UNUSED(void, glTexCoord1dv, (const GLdouble *v)) SDL_PROC_UNUSED(void, glTexCoord1f, (GLfloat s)) -SDL_PROC_UNUSED(void, glTexCoord1fv, (const GLfloat * v)) +SDL_PROC_UNUSED(void, glTexCoord1fv, (const GLfloat *v)) SDL_PROC_UNUSED(void, glTexCoord1i, (GLint s)) -SDL_PROC_UNUSED(void, glTexCoord1iv, (const GLint * v)) +SDL_PROC_UNUSED(void, glTexCoord1iv, (const GLint *v)) SDL_PROC_UNUSED(void, glTexCoord1s, (GLshort s)) -SDL_PROC_UNUSED(void, glTexCoord1sv, (const GLshort * v)) +SDL_PROC_UNUSED(void, glTexCoord1sv, (const GLshort *v)) SDL_PROC_UNUSED(void, glTexCoord2d, (GLdouble s, GLdouble t)) -SDL_PROC_UNUSED(void, glTexCoord2dv, (const GLdouble * v)) +SDL_PROC_UNUSED(void, glTexCoord2dv, (const GLdouble *v)) SDL_PROC(void, glTexCoord2f, (GLfloat s, GLfloat t)) -SDL_PROC_UNUSED(void, glTexCoord2fv, (const GLfloat * v)) +SDL_PROC_UNUSED(void, glTexCoord2fv, (const GLfloat *v)) SDL_PROC_UNUSED(void, glTexCoord2i, (GLint s, GLint t)) -SDL_PROC_UNUSED(void, glTexCoord2iv, (const GLint * v)) +SDL_PROC_UNUSED(void, glTexCoord2iv, (const GLint *v)) SDL_PROC_UNUSED(void, glTexCoord2s, (GLshort s, GLshort t)) -SDL_PROC_UNUSED(void, glTexCoord2sv, (const GLshort * v)) +SDL_PROC_UNUSED(void, glTexCoord2sv, (const GLshort *v)) SDL_PROC_UNUSED(void, glTexCoord3d, (GLdouble s, GLdouble t, GLdouble r)) -SDL_PROC_UNUSED(void, glTexCoord3dv, (const GLdouble * v)) +SDL_PROC_UNUSED(void, glTexCoord3dv, (const GLdouble *v)) SDL_PROC_UNUSED(void, glTexCoord3f, (GLfloat s, GLfloat t, GLfloat r)) -SDL_PROC_UNUSED(void, glTexCoord3fv, (const GLfloat * v)) +SDL_PROC_UNUSED(void, glTexCoord3fv, (const GLfloat *v)) SDL_PROC_UNUSED(void, glTexCoord3i, (GLint s, GLint t, GLint r)) -SDL_PROC_UNUSED(void, glTexCoord3iv, (const GLint * v)) +SDL_PROC_UNUSED(void, glTexCoord3iv, (const GLint *v)) SDL_PROC_UNUSED(void, glTexCoord3s, (GLshort s, GLshort t, GLshort r)) -SDL_PROC_UNUSED(void, glTexCoord3sv, (const GLshort * v)) +SDL_PROC_UNUSED(void, glTexCoord3sv, (const GLshort *v)) SDL_PROC_UNUSED(void, glTexCoord4d, (GLdouble s, GLdouble t, GLdouble r, GLdouble q)) -SDL_PROC_UNUSED(void, glTexCoord4dv, (const GLdouble * v)) +SDL_PROC_UNUSED(void, glTexCoord4dv, (const GLdouble *v)) SDL_PROC_UNUSED(void, glTexCoord4f, (GLfloat s, GLfloat t, GLfloat r, GLfloat q)) -SDL_PROC_UNUSED(void, glTexCoord4fv, (const GLfloat * v)) +SDL_PROC_UNUSED(void, glTexCoord4fv, (const GLfloat *v)) SDL_PROC_UNUSED(void, glTexCoord4i, (GLint s, GLint t, GLint r, GLint q)) -SDL_PROC_UNUSED(void, glTexCoord4iv, (const GLint * v)) +SDL_PROC_UNUSED(void, glTexCoord4iv, (const GLint *v)) SDL_PROC_UNUSED(void, glTexCoord4s, (GLshort s, GLshort t, GLshort r, GLshort q)) -SDL_PROC_UNUSED(void, glTexCoord4sv, (const GLshort * v)) -SDL_PROC_UNUSED(void, glTexCoordPointer, - (GLint size, GLenum type, GLsizei stride, - const GLvoid * pointer)) +SDL_PROC_UNUSED(void, glTexCoord4sv, (const GLshort *v)) +SDL_PROC(void, glTexCoordPointer, + (GLint size, GLenum type, GLsizei stride, + const GLvoid *pointer)) SDL_PROC(void, glTexEnvf, (GLenum target, GLenum pname, GLfloat param)) SDL_PROC_UNUSED(void, glTexEnvfv, - (GLenum target, GLenum pname, const GLfloat * params)) + (GLenum target, GLenum pname, const GLfloat *params)) SDL_PROC_UNUSED(void, glTexEnvi, (GLenum target, GLenum pname, GLint param)) SDL_PROC_UNUSED(void, glTexEnviv, - (GLenum target, GLenum pname, const GLint * params)) + (GLenum target, GLenum pname, const GLint *params)) SDL_PROC_UNUSED(void, glTexGend, (GLenum coord, GLenum pname, GLdouble param)) SDL_PROC_UNUSED(void, glTexGendv, - (GLenum coord, GLenum pname, const GLdouble * params)) + (GLenum coord, GLenum pname, const GLdouble *params)) SDL_PROC_UNUSED(void, glTexGenf, (GLenum coord, GLenum pname, GLfloat param)) SDL_PROC_UNUSED(void, glTexGenfv, - (GLenum coord, GLenum pname, const GLfloat * params)) + (GLenum coord, GLenum pname, const GLfloat *params)) SDL_PROC_UNUSED(void, glTexGeni, (GLenum coord, GLenum pname, GLint param)) SDL_PROC_UNUSED(void, glTexGeniv, - (GLenum coord, GLenum pname, const GLint * params)) + (GLenum coord, GLenum pname, const GLint *params)) SDL_PROC_UNUSED(void, glTexImage1D, (GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, - const GLvoid * pixels)) + const GLvoid *pixels)) SDL_PROC(void, glTexImage2D, (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, - const GLvoid * pixels)) + const GLvoid *pixels)) SDL_PROC_UNUSED(void, glTexParameterf, (GLenum target, GLenum pname, GLfloat param)) SDL_PROC_UNUSED(void, glTexParameterfv, - (GLenum target, GLenum pname, const GLfloat * params)) + (GLenum target, GLenum pname, const GLfloat *params)) SDL_PROC(void, glTexParameteri, (GLenum target, GLenum pname, GLint param)) SDL_PROC_UNUSED(void, glTexParameteriv, - (GLenum target, GLenum pname, const GLint * params)) + (GLenum target, GLenum pname, const GLint *params)) SDL_PROC_UNUSED(void, glTexSubImage1D, (GLenum target, GLint level, GLint xoffset, GLsizei width, - GLenum format, GLenum type, const GLvoid * pixels)) + GLenum format, GLenum type, const GLvoid *pixels)) SDL_PROC(void, glTexSubImage2D, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, - const GLvoid * pixels)) + const GLvoid *pixels)) SDL_PROC_UNUSED(void, glTranslated, (GLdouble x, GLdouble y, GLdouble z)) -SDL_PROC(void, glTranslatef, (GLfloat x, GLfloat y, GLfloat z)) +SDL_PROC_UNUSED(void, glTranslatef, (GLfloat x, GLfloat y, GLfloat z)) SDL_PROC_UNUSED(void, glVertex2d, (GLdouble x, GLdouble y)) -SDL_PROC_UNUSED(void, glVertex2dv, (const GLdouble * v)) +SDL_PROC_UNUSED(void, glVertex2dv, (const GLdouble *v)) SDL_PROC(void, glVertex2f, (GLfloat x, GLfloat y)) -SDL_PROC_UNUSED(void, glVertex2fv, (const GLfloat * v)) +SDL_PROC_UNUSED(void, glVertex2fv, (const GLfloat *v)) SDL_PROC_UNUSED(void, glVertex2i, (GLint x, GLint y)) -SDL_PROC_UNUSED(void, glVertex2iv, (const GLint * v)) +SDL_PROC_UNUSED(void, glVertex2iv, (const GLint *v)) SDL_PROC_UNUSED(void, glVertex2s, (GLshort x, GLshort y)) -SDL_PROC_UNUSED(void, glVertex2sv, (const GLshort * v)) +SDL_PROC_UNUSED(void, glVertex2sv, (const GLshort *v)) SDL_PROC_UNUSED(void, glVertex3d, (GLdouble x, GLdouble y, GLdouble z)) -SDL_PROC_UNUSED(void, glVertex3dv, (const GLdouble * v)) +SDL_PROC_UNUSED(void, glVertex3dv, (const GLdouble *v)) SDL_PROC_UNUSED(void, glVertex3f, (GLfloat x, GLfloat y, GLfloat z)) -SDL_PROC(void, glVertex3fv, (const GLfloat * v)) +SDL_PROC(void, glVertex3fv, (const GLfloat *v)) SDL_PROC_UNUSED(void, glVertex3i, (GLint x, GLint y, GLint z)) -SDL_PROC_UNUSED(void, glVertex3iv, (const GLint * v)) +SDL_PROC_UNUSED(void, glVertex3iv, (const GLint *v)) SDL_PROC_UNUSED(void, glVertex3s, (GLshort x, GLshort y, GLshort z)) -SDL_PROC_UNUSED(void, glVertex3sv, (const GLshort * v)) +SDL_PROC_UNUSED(void, glVertex3sv, (const GLshort *v)) SDL_PROC_UNUSED(void, glVertex4d, (GLdouble x, GLdouble y, GLdouble z, GLdouble w)) -SDL_PROC_UNUSED(void, glVertex4dv, (const GLdouble * v)) +SDL_PROC_UNUSED(void, glVertex4dv, (const GLdouble *v)) SDL_PROC_UNUSED(void, glVertex4f, (GLfloat x, GLfloat y, GLfloat z, GLfloat w)) -SDL_PROC_UNUSED(void, glVertex4fv, (const GLfloat * v)) +SDL_PROC_UNUSED(void, glVertex4fv, (const GLfloat *v)) SDL_PROC_UNUSED(void, glVertex4i, (GLint x, GLint y, GLint z, GLint w)) -SDL_PROC_UNUSED(void, glVertex4iv, (const GLint * v)) +SDL_PROC_UNUSED(void, glVertex4iv, (const GLint *v)) SDL_PROC_UNUSED(void, glVertex4s, (GLshort x, GLshort y, GLshort z, GLshort w)) -SDL_PROC_UNUSED(void, glVertex4sv, (const GLshort * v)) -SDL_PROC_UNUSED(void, glVertexPointer, - (GLint size, GLenum type, GLsizei stride, - const GLvoid * pointer)) +SDL_PROC_UNUSED(void, glVertex4sv, (const GLshort *v)) +SDL_PROC(void, glVertexPointer, + (GLint size, GLenum type, GLsizei stride, + const GLvoid *pointer)) SDL_PROC(void, glViewport, (GLint x, GLint y, GLsizei width, GLsizei height)) /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/render/opengl/SDL_render_gl.c b/SDL2-2.30.5/src/render/opengl/SDL_render_gl.c similarity index 53% rename from SDL2-2.0.12/src/render/opengl/SDL_render_gl.c rename to SDL2-2.30.5/src/render/opengl/SDL_render_gl.c index 133a20b..9c26619 100644 --- a/SDL2-2.0.12/src/render/opengl/SDL_render_gl.c +++ b/SDL2-2.30.5/src/render/opengl/SDL_render_gl.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,21 +20,25 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_RENDER_OGL && !SDL_RENDER_DISABLED - +#if SDL_VIDEO_RENDER_OGL #include "SDL_hints.h" -#include "SDL_log.h" -#include "SDL_assert.h" +#include "../../video/SDL_sysvideo.h" /* For SDL_GL_SwapWindowWithResult */ #include "SDL_opengl.h" #include "../SDL_sysrender.h" #include "SDL_shaders_gl.h" +#include "../../SDL_utils_c.h" #ifdef __MACOSX__ #include #endif -/* To prevent unnecessary window recreation, - * these should match the defaults selected in SDL_GL_ResetAttributes +#ifdef SDL_VIDEO_VITA_PVR_OGL +#include +#include +#endif + +/* To prevent unnecessary window recreation, + * these should match the defaults selected in SDL_GL_ResetAttributes */ #define RENDERER_CONTEXT_MAJOR 2 @@ -46,9 +50,6 @@ http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Conceptual/OpenGL-MacProgGuide/opengl_texturedata/opengl_texturedata.html */ -/* Used to re-create the window with OpenGL capability */ -extern int SDL_RecreateWindow(SDL_Window * window, Uint32 flags); - static const float inv255f = 1.0f / 255.0f; typedef struct GL_FBOList GL_FBOList; @@ -75,6 +76,9 @@ typedef struct SDL_bool cliprect_dirty; SDL_Rect cliprect; SDL_bool texturing; + SDL_bool vertex_array; + SDL_bool color_array; + SDL_bool texture_array; Uint32 color; Uint32 clear_color; } GL_DrawStateCache; @@ -98,7 +102,7 @@ typedef struct GL_FBOList *framebuffers; /* OpenGL functions */ -#define SDL_PROC(ret,func,params) ret (APIENTRY *func) params; +#define SDL_PROC(ret, func, params) ret (APIENTRY *func) params; #include "SDL_glfuncs.h" #undef SDL_PROC @@ -126,45 +130,49 @@ typedef struct GLfloat texh; GLenum format; GLenum formattype; + GL_Shader shader; void *pixels; int pitch; SDL_Rect locked_rect; +#if SDL_HAVE_YUV /* YUV texture support */ SDL_bool yuv; SDL_bool nv12; GLuint utexture; GLuint vtexture; +#endif GL_FBOList *fbo; } GL_TextureData; -SDL_FORCE_INLINE const char* -GL_TranslateError (GLenum error) +SDL_FORCE_INLINE const char * +GL_TranslateError(GLenum error) { -#define GL_ERROR_TRANSLATE(e) case e: return #e; +#define GL_ERROR_TRANSLATE(e) \ + case e: \ + return #e; switch (error) { - GL_ERROR_TRANSLATE(GL_INVALID_ENUM) - GL_ERROR_TRANSLATE(GL_INVALID_VALUE) - GL_ERROR_TRANSLATE(GL_INVALID_OPERATION) - GL_ERROR_TRANSLATE(GL_OUT_OF_MEMORY) - GL_ERROR_TRANSLATE(GL_NO_ERROR) - GL_ERROR_TRANSLATE(GL_STACK_OVERFLOW) - GL_ERROR_TRANSLATE(GL_STACK_UNDERFLOW) - GL_ERROR_TRANSLATE(GL_TABLE_TOO_LARGE) + GL_ERROR_TRANSLATE(GL_INVALID_ENUM) + GL_ERROR_TRANSLATE(GL_INVALID_VALUE) + GL_ERROR_TRANSLATE(GL_INVALID_OPERATION) + GL_ERROR_TRANSLATE(GL_OUT_OF_MEMORY) + GL_ERROR_TRANSLATE(GL_NO_ERROR) + GL_ERROR_TRANSLATE(GL_STACK_OVERFLOW) + GL_ERROR_TRANSLATE(GL_STACK_UNDERFLOW) + GL_ERROR_TRANSLATE(GL_TABLE_TOO_LARGE) default: return "UNKNOWN"; -} + } #undef GL_ERROR_TRANSLATE } SDL_FORCE_INLINE void GL_ClearErrors(SDL_Renderer *renderer) { - GL_RenderData *data = (GL_RenderData *) renderer->driverdata; + GL_RenderData *data = (GL_RenderData *)renderer->driverdata; - if (!data->debug_enabled) - { + if (!data->debug_enabled) { return; } if (data->GL_ARB_debug_output_supported) { @@ -178,7 +186,7 @@ GL_ClearErrors(SDL_Renderer *renderer) data->errors = 0; data->error_messages = NULL; } - } else if (data->glGetError != NULL) { + } else if (data->glGetError) { while (data->glGetError() != GL_NO_ERROR) { /* continue; */ } @@ -186,13 +194,12 @@ GL_ClearErrors(SDL_Renderer *renderer) } SDL_FORCE_INLINE int -GL_CheckAllErrors (const char *prefix, SDL_Renderer *renderer, const char *file, int line, const char *function) +GL_CheckAllErrors(const char *prefix, SDL_Renderer *renderer, const char *file, int line, const char *function) { - GL_RenderData *data = (GL_RenderData *) renderer->driverdata; + GL_RenderData *data = (GL_RenderData *)renderer->driverdata; int ret = 0; - if (!data->debug_enabled) - { + if (!data->debug_enabled) { return 0; } if (data->GL_ARB_debug_output_supported) { @@ -228,20 +235,19 @@ GL_CheckAllErrors (const char *prefix, SDL_Renderer *renderer, const char *file, #define GL_CheckError(prefix, renderer) GL_CheckAllErrors(prefix, renderer, SDL_FILE, SDL_LINE, SDL_FUNCTION) #endif -static int -GL_LoadFunctions(GL_RenderData * data) +static int GL_LoadFunctions(GL_RenderData *data) { #ifdef __SDL_NOGETPROCADDR__ -#define SDL_PROC(ret,func,params) data->func=func; +#define SDL_PROC(ret, func, params) data->func = func; #else int retval = 0; -#define SDL_PROC(ret,func,params) \ - do { \ - data->func = SDL_GL_GetProcAddress(#func); \ - if ( ! data->func ) { \ +#define SDL_PROC(ret, func, params) \ + do { \ + data->func = SDL_GL_GetProcAddress(#func); \ + if (!data->func) { \ retval = SDL_SetError("Couldn't load GL function %s: %s", #func, SDL_GetError()); \ - } \ - } while ( 0 ); + } \ + } while (0); #endif /* __SDL_NOGETPROCADDR__ */ #include "SDL_glfuncs.h" @@ -249,10 +255,9 @@ GL_LoadFunctions(GL_RenderData * data) return retval; } -static int -GL_ActivateRenderer(SDL_Renderer * renderer) +static int GL_ActivateRenderer(SDL_Renderer *renderer) { - GL_RenderData *data = (GL_RenderData *) renderer->driverdata; + GL_RenderData *data = (GL_RenderData *)renderer->driverdata; if (SDL_GL_GetCurrentContext() != data->context) { if (SDL_GL_MakeCurrent(renderer->window, data->context) < 0) { @@ -265,11 +270,10 @@ GL_ActivateRenderer(SDL_Renderer * renderer) return 0; } -static void APIENTRY -GL_HandleDebugMessage(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const char *message, const void *userParam) +static void APIENTRY GL_HandleDebugMessage(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const char *message, const void *userParam) { - SDL_Renderer *renderer = (SDL_Renderer *) userParam; - GL_RenderData *data = (GL_RenderData *) renderer->driverdata; + SDL_Renderer *renderer = (SDL_Renderer *)userParam; + GL_RenderData *data = (GL_RenderData *)renderer->driverdata; if (type == GL_DEBUG_TYPE_ERROR_ARB) { /* Record this error */ @@ -278,7 +282,7 @@ GL_HandleDebugMessage(GLenum source, GLenum type, GLuint id, GLenum severity, GL if (error_messages) { data->errors = errors; data->error_messages = error_messages; - data->error_messages[data->errors-1] = SDL_strdup(message); + data->error_messages[data->errors - 1] = SDL_strdup(message); } } @@ -294,8 +298,7 @@ GL_HandleDebugMessage(GLenum source, GLenum type, GLuint id, GLenum severity, GL } } -static GL_FBOList * -GL_GetFBO(GL_RenderData *data, Uint32 w, Uint32 h) +static GL_FBOList *GL_GetFBO(GL_RenderData *data, Uint32 w, Uint32 h) { GL_FBOList *result = data->framebuffers; @@ -316,8 +319,20 @@ GL_GetFBO(GL_RenderData *data, Uint32 w, Uint32 h) return result; } -static int -GL_GetOutputSize(SDL_Renderer * renderer, int *w, int *h) +static void GL_WindowEvent(SDL_Renderer *renderer, const SDL_WindowEvent *event) +{ + /* If the window x/y/w/h changed at all, assume the viewport has been + * changed behind our backs. x/y changes might seem weird but viewport + * resets have been observed on macOS at minimum! + */ + if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED || + event->event == SDL_WINDOWEVENT_MOVED) { + GL_RenderData *data = (GL_RenderData *)renderer->driverdata; + data->drawstate.viewport_dirty = SDL_TRUE; + } +} + +static int GL_GetOutputSize(SDL_Renderer *renderer, int *w, int *h) { SDL_GL_GetDrawableSize(renderer->window, w, h); return 0; @@ -360,13 +375,16 @@ static GLenum GetBlendEquation(SDL_BlendOperation operation) return GL_FUNC_SUBTRACT; case SDL_BLENDOPERATION_REV_SUBTRACT: return GL_FUNC_REVERSE_SUBTRACT; + case SDL_BLENDOPERATION_MINIMUM: + return GL_MIN; + case SDL_BLENDOPERATION_MAXIMUM: + return GL_MAX; default: return GL_INVALID_ENUM; } } -static SDL_bool -GL_SupportsBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode) +static SDL_bool GL_SupportsBlendMode(SDL_Renderer *renderer, SDL_BlendMode blendMode) { SDL_BlendFactor srcColorFactor = SDL_GetBlendModeSrcColorFactor(blendMode); SDL_BlendFactor srcAlphaFactor = SDL_GetBlendModeSrcAlphaFactor(blendMode); @@ -389,20 +407,9 @@ GL_SupportsBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode) return SDL_TRUE; } -SDL_FORCE_INLINE int -power_of_2(int input) -{ - int value = 1; - - while (value < input) { - value <<= 1; - } - return value; -} - SDL_FORCE_INLINE SDL_bool convert_format(GL_RenderData *renderdata, Uint32 pixel_format, - GLint* internalFormat, GLenum* format, GLenum* type) + GLint *internalFormat, GLenum *format, GLenum *type) { switch (pixel_format) { case SDL_PIXELFORMAT_ARGB8888: @@ -438,10 +445,9 @@ convert_format(GL_RenderData *renderdata, Uint32 pixel_format, return SDL_TRUE; } -static int -GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) +static int GL_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) { - GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata; + GL_RenderData *renderdata = (GL_RenderData *)renderer->driverdata; const GLenum textype = renderdata->textype; GL_TextureData *data; GLint internalFormat; @@ -451,7 +457,8 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) GL_ActivateRenderer(renderer); - renderdata->drawstate.texture = NULL; /* we trash this state. */ + renderdata->drawstate.texture = NULL; /* we trash this state. */ + renderdata->drawstate.texturing = SDL_FALSE; /* we trash this state. */ if (texture->access == SDL_TEXTUREACCESS_TARGET && !renderdata->GL_EXT_framebuffer_object_supported) { @@ -464,7 +471,7 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) SDL_GetPixelFormatName(texture->format)); } - data = (GL_TextureData *) SDL_calloc(1, sizeof(*data)); + data = (GL_TextureData *)SDL_calloc(1, sizeof(*data)); if (!data) { return SDL_OutOfMemory(); } @@ -472,7 +479,7 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) if (texture->access == SDL_TEXTUREACCESS_STREAMING) { size_t size; data->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format); - size = texture->h * data->pitch; + size = (size_t)texture->h * data->pitch; if (texture->format == SDL_PIXELFORMAT_YV12 || texture->format == SDL_PIXELFORMAT_IYUV) { /* Need to add size for the U and V planes */ @@ -515,13 +522,13 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) } else if (renderdata->GL_ARB_texture_rectangle_supported) { texture_w = texture->w; texture_h = texture->h; - data->texw = (GLfloat) texture_w; - data->texh = (GLfloat) texture_h; + data->texw = (GLfloat)texture_w; + data->texh = (GLfloat)texture_h; } else { - texture_w = power_of_2(texture->w); - texture_h = power_of_2(texture->h); - data->texw = (GLfloat) (texture->w) / texture_w; - data->texh = (GLfloat) texture->h / texture_h; + texture_w = SDL_powerof2(texture->w); + texture_h = SDL_powerof2(texture->h); + data->texw = (GLfloat)(texture->w) / texture_w; + data->texh = (GLfloat)texture->h / texture_h; } data->format = format; @@ -542,13 +549,13 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) } #ifdef __MACOSX__ #ifndef GL_TEXTURE_STORAGE_HINT_APPLE -#define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC +#define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC #endif #ifndef STORAGE_CACHED_APPLE -#define STORAGE_CACHED_APPLE 0x85BE +#define STORAGE_CACHED_APPLE 0x85BE #endif #ifndef STORAGE_SHARED_APPLE -#define STORAGE_SHARED_APPLE 0x85BF +#define STORAGE_SHARED_APPLE 0x85BF #endif if (texture->access == SDL_TEXTUREACCESS_STREAMING) { renderdata->glTexParameteri(textype, GL_TEXTURE_STORAGE_HINT_APPLE, @@ -557,18 +564,15 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) renderdata->glTexParameteri(textype, GL_TEXTURE_STORAGE_HINT_APPLE, GL_STORAGE_CACHED_APPLE); } - if (texture->access == SDL_TEXTUREACCESS_STREAMING - && texture->format == SDL_PIXELFORMAT_ARGB8888 - && (texture->w % 8) == 0) { + if (texture->access == SDL_TEXTUREACCESS_STREAMING && texture->format == SDL_PIXELFORMAT_ARGB8888 && (texture->w % 8) == 0) { renderdata->glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE); renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1); renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH, - (data->pitch / SDL_BYTESPERPIXEL(texture->format))); + (data->pitch / SDL_BYTESPERPIXEL(texture->format))); renderdata->glTexImage2D(textype, 0, internalFormat, texture_w, texture_h, 0, format, type, data->pixels); renderdata->glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE); - } - else + } else #endif { renderdata->glTexImage2D(textype, 0, internalFormat, texture_w, @@ -579,13 +583,13 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) return -1; } +#if SDL_HAVE_YUV if (texture->format == SDL_PIXELFORMAT_YV12 || texture->format == SDL_PIXELFORMAT_IYUV) { data->yuv = SDL_TRUE; renderdata->glGenTextures(1, &data->utexture); renderdata->glGenTextures(1, &data->vtexture); - renderdata->glEnable(textype); renderdata->glBindTexture(textype, data->utexture); renderdata->glTexParameteri(textype, GL_TEXTURE_MIN_FILTER, @@ -596,8 +600,8 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) GL_CLAMP_TO_EDGE); renderdata->glTexParameteri(textype, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - renderdata->glTexImage2D(textype, 0, internalFormat, (texture_w+1)/2, - (texture_h+1)/2, 0, format, type, NULL); + renderdata->glTexImage2D(textype, 0, internalFormat, (texture_w + 1) / 2, + (texture_h + 1) / 2, 0, format, type, NULL); renderdata->glBindTexture(textype, data->vtexture); renderdata->glTexParameteri(textype, GL_TEXTURE_MIN_FILTER, @@ -608,10 +612,8 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) GL_CLAMP_TO_EDGE); renderdata->glTexParameteri(textype, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - renderdata->glTexImage2D(textype, 0, internalFormat, (texture_w+1)/2, - (texture_h+1)/2, 0, format, type, NULL); - - renderdata->glDisable(textype); + renderdata->glTexImage2D(textype, 0, internalFormat, (texture_w + 1) / 2, + (texture_h + 1) / 2, 0, format, type, NULL); } if (texture->format == SDL_PIXELFORMAT_NV12 || @@ -619,8 +621,6 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) data->nv12 = SDL_TRUE; renderdata->glGenTextures(1, &data->utexture); - renderdata->glEnable(textype); - renderdata->glBindTexture(textype, data->utexture); renderdata->glTexParameteri(textype, GL_TEXTURE_MIN_FILTER, scaleMode); @@ -630,59 +630,109 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) GL_CLAMP_TO_EDGE); renderdata->glTexParameteri(textype, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - renderdata->glTexImage2D(textype, 0, GL_LUMINANCE_ALPHA, (texture_w+1)/2, - (texture_h+1)/2, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, NULL); - renderdata->glDisable(textype); + renderdata->glTexImage2D(textype, 0, GL_LUMINANCE_ALPHA, (texture_w + 1) / 2, + (texture_h + 1) / 2, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, NULL); } +#endif + + if (texture->format == SDL_PIXELFORMAT_ABGR8888 || texture->format == SDL_PIXELFORMAT_ARGB8888) { + data->shader = SHADER_RGBA; + } else { + data->shader = SHADER_RGB; + } + +#if SDL_HAVE_YUV + if (data->yuv || data->nv12) { + switch (SDL_GetYUVConversionModeForResolution(texture->w, texture->h)) { + case SDL_YUV_CONVERSION_JPEG: + if (data->yuv) { + data->shader = SHADER_YUV_JPEG; + } else if (texture->format == SDL_PIXELFORMAT_NV12) { + data->shader = SHADER_NV12_JPEG; + } else { + data->shader = SHADER_NV21_JPEG; + } + break; + case SDL_YUV_CONVERSION_BT601: + if (data->yuv) { + data->shader = SHADER_YUV_BT601; + } else if (texture->format == SDL_PIXELFORMAT_NV12) { + if (SDL_GetHintBoolean("SDL_RENDER_OPENGL_NV12_RG_SHADER", SDL_FALSE)) { + data->shader = SHADER_NV12_RG_BT601; + } else { + data->shader = SHADER_NV12_RA_BT601; + } + } else { + data->shader = SHADER_NV21_BT601; + } + break; + case SDL_YUV_CONVERSION_BT709: + if (data->yuv) { + data->shader = SHADER_YUV_BT709; + } else if (texture->format == SDL_PIXELFORMAT_NV12) { + if (SDL_GetHintBoolean("SDL_RENDER_OPENGL_NV12_RG_SHADER", SDL_FALSE)) { + data->shader = SHADER_NV12_RG_BT709; + } else { + data->shader = SHADER_NV12_RA_BT709; + } + } else { + data->shader = SHADER_NV21_BT709; + } + break; + default: + SDL_assert(!"unsupported YUV conversion mode"); + break; + } + } +#endif /* SDL_HAVE_YUV */ return GL_CheckError("", renderer); } -static int -GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * rect, const void *pixels, int pitch) +static int GL_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *rect, const void *pixels, int pitch) { - GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata; + GL_RenderData *renderdata = (GL_RenderData *)renderer->driverdata; const GLenum textype = renderdata->textype; - GL_TextureData *data = (GL_TextureData *) texture->driverdata; + GL_TextureData *data = (GL_TextureData *)texture->driverdata; const int texturebpp = SDL_BYTESPERPIXEL(texture->format); - SDL_assert(texturebpp != 0); /* otherwise, division by zero later. */ + SDL_assert_release(texturebpp != 0); /* otherwise, division by zero later. */ GL_ActivateRenderer(renderer); - renderdata->drawstate.texture = NULL; /* we trash this state. */ + renderdata->drawstate.texture = NULL; /* we trash this state. */ - renderdata->glEnable(textype); renderdata->glBindTexture(textype, data->texture); renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1); renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH, (pitch / texturebpp)); renderdata->glTexSubImage2D(textype, 0, rect->x, rect->y, rect->w, rect->h, data->format, data->formattype, pixels); +#if SDL_HAVE_YUV if (data->yuv) { 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); + pixels = (const void *)((const Uint8 *)pixels + rect->h * pitch); if (texture->format == SDL_PIXELFORMAT_YV12) { renderdata->glBindTexture(textype, data->vtexture); } else { renderdata->glBindTexture(textype, data->utexture); } - renderdata->glTexSubImage2D(textype, 0, rect->x/2, rect->y/2, - (rect->w+1)/2, (rect->h+1)/2, + renderdata->glTexSubImage2D(textype, 0, rect->x / 2, rect->y / 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 + 1) / 2) * ((pitch + 1) / 2)); + pixels = (const void *)((const Uint8 *)pixels + ((rect->h + 1) / 2) * ((pitch + 1) / 2)); if (texture->format == SDL_PIXELFORMAT_YV12) { renderdata->glBindTexture(textype, data->utexture); } else { renderdata->glBindTexture(textype, data->vtexture); } - renderdata->glTexSubImage2D(textype, 0, rect->x/2, rect->y/2, - (rect->w+1)/2, (rect->h+1)/2, + renderdata->glTexSubImage2D(textype, 0, rect->x / 2, rect->y / 2, + (rect->w + 1) / 2, (rect->h + 1) / 2, data->format, data->formattype, pixels); } @@ -690,33 +740,31 @@ GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, 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); + pixels = (const void *)((const Uint8 *)pixels + rect->h * pitch); renderdata->glBindTexture(textype, data->utexture); - renderdata->glTexSubImage2D(textype, 0, rect->x/2, rect->y/2, - (rect->w + 1)/2, (rect->h + 1)/2, + renderdata->glTexSubImage2D(textype, 0, rect->x / 2, rect->y / 2, + (rect->w + 1) / 2, (rect->h + 1) / 2, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, pixels); } - renderdata->glDisable(textype); - +#endif return GL_CheckError("glTexSubImage2D()", renderer); } -static int -GL_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * rect, - const Uint8 *Yplane, int Ypitch, - const Uint8 *Uplane, int Upitch, - const Uint8 *Vplane, int Vpitch) +#if SDL_HAVE_YUV +static int GL_UpdateTextureYUV(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *Uplane, int Upitch, + const Uint8 *Vplane, int Vpitch) { - GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata; + GL_RenderData *renderdata = (GL_RenderData *)renderer->driverdata; const GLenum textype = renderdata->textype; - GL_TextureData *data = (GL_TextureData *) texture->driverdata; + GL_TextureData *data = (GL_TextureData *)texture->driverdata; GL_ActivateRenderer(renderer); - renderdata->drawstate.texture = NULL; /* we trash this state. */ + renderdata->drawstate.texture = NULL; /* we trash this state. */ - renderdata->glEnable(textype); renderdata->glBindTexture(textype, data->texture); renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1); renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH, Ypitch); @@ -726,65 +774,89 @@ GL_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture, renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH, Upitch); renderdata->glBindTexture(textype, data->utexture); - renderdata->glTexSubImage2D(textype, 0, rect->x/2, rect->y/2, - (rect->w + 1)/2, (rect->h + 1)/2, + renderdata->glTexSubImage2D(textype, 0, rect->x / 2, rect->y / 2, + (rect->w + 1) / 2, (rect->h + 1) / 2, data->format, data->formattype, Uplane); renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH, Vpitch); renderdata->glBindTexture(textype, data->vtexture); - renderdata->glTexSubImage2D(textype, 0, rect->x/2, rect->y/2, - (rect->w + 1)/2, (rect->h + 1)/2, + renderdata->glTexSubImage2D(textype, 0, rect->x / 2, rect->y / 2, + (rect->w + 1) / 2, (rect->h + 1) / 2, data->format, data->formattype, Vplane); - renderdata->glDisable(textype); return GL_CheckError("glTexSubImage2D()", renderer); } -static int -GL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * rect, void **pixels, int *pitch) +static int GL_UpdateTextureNV(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *UVplane, int UVpitch) { - GL_TextureData *data = (GL_TextureData *) texture->driverdata; + GL_RenderData *renderdata = (GL_RenderData *)renderer->driverdata; + const GLenum textype = renderdata->textype; + GL_TextureData *data = (GL_TextureData *)texture->driverdata; + + GL_ActivateRenderer(renderer); + + renderdata->drawstate.texture = NULL; /* we trash this state. */ + + renderdata->glBindTexture(textype, data->texture); + renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH, Ypitch); + renderdata->glTexSubImage2D(textype, 0, rect->x, rect->y, rect->w, + rect->h, data->format, data->formattype, + Yplane); + + renderdata->glPixelStorei(GL_UNPACK_ROW_LENGTH, UVpitch / 2); + renderdata->glBindTexture(textype, data->utexture); + renderdata->glTexSubImage2D(textype, 0, rect->x / 2, rect->y / 2, + (rect->w + 1) / 2, (rect->h + 1) / 2, + GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, UVplane); + + return GL_CheckError("glTexSubImage2D()", renderer); +} +#endif + +static int GL_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *rect, void **pixels, int *pitch) +{ + GL_TextureData *data = (GL_TextureData *)texture->driverdata; data->locked_rect = *rect; *pixels = - (void *) ((Uint8 *) data->pixels + rect->y * data->pitch + - rect->x * SDL_BYTESPERPIXEL(texture->format)); + (void *)((Uint8 *)data->pixels + rect->y * data->pitch + + rect->x * SDL_BYTESPERPIXEL(texture->format)); *pitch = data->pitch; return 0; } -static void -GL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) +static void GL_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture) { - GL_TextureData *data = (GL_TextureData *) texture->driverdata; + GL_TextureData *data = (GL_TextureData *)texture->driverdata; const SDL_Rect *rect; void *pixels; rect = &data->locked_rect; pixels = - (void *) ((Uint8 *) data->pixels + rect->y * data->pitch + - rect->x * SDL_BYTESPERPIXEL(texture->format)); + (void *)((Uint8 *)data->pixels + rect->y * data->pitch + + rect->x * SDL_BYTESPERPIXEL(texture->format)); GL_UpdateTexture(renderer, texture, rect, pixels, data->pitch); } -static void -GL_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture, SDL_ScaleMode scaleMode) +static void GL_SetTextureScaleMode(SDL_Renderer *renderer, SDL_Texture *texture, SDL_ScaleMode scaleMode) { - GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata; + GL_RenderData *renderdata = (GL_RenderData *)renderer->driverdata; const GLenum textype = renderdata->textype; - GL_TextureData *data = (GL_TextureData *) texture->driverdata; + GL_TextureData *data = (GL_TextureData *)texture->driverdata; GLenum glScaleMode = (scaleMode == SDL_ScaleModeNearest) ? GL_NEAREST : GL_LINEAR; - renderdata->glEnable(textype); renderdata->glBindTexture(textype, data->texture); renderdata->glTexParameteri(textype, GL_TEXTURE_MIN_FILTER, glScaleMode); renderdata->glTexParameteri(textype, GL_TEXTURE_MAG_FILTER, glScaleMode); - renderdata->glDisable(textype); +#if SDL_HAVE_YUV if (texture->format == SDL_PIXELFORMAT_YV12 || texture->format == SDL_PIXELFORMAT_IYUV) { - renderdata->glEnable(textype); renderdata->glBindTexture(textype, data->utexture); renderdata->glTexParameteri(textype, GL_TEXTURE_MIN_FILTER, glScaleMode); renderdata->glTexParameteri(textype, GL_TEXTURE_MAG_FILTER, glScaleMode); @@ -792,23 +864,20 @@ GL_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture, SDL_Scale renderdata->glBindTexture(textype, data->vtexture); renderdata->glTexParameteri(textype, GL_TEXTURE_MIN_FILTER, glScaleMode); renderdata->glTexParameteri(textype, GL_TEXTURE_MAG_FILTER, glScaleMode); - renderdata->glDisable(textype); } if (texture->format == SDL_PIXELFORMAT_NV12 || texture->format == SDL_PIXELFORMAT_NV21) { - renderdata->glEnable(textype); renderdata->glBindTexture(textype, data->utexture); renderdata->glTexParameteri(textype, GL_TEXTURE_MIN_FILTER, glScaleMode); renderdata->glTexParameteri(textype, GL_TEXTURE_MAG_FILTER, glScaleMode); - renderdata->glDisable(textype); } +#endif } -static int -GL_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture) +static int GL_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture) { - GL_RenderData *data = (GL_RenderData *) renderer->driverdata; + GL_RenderData *data = (GL_RenderData *)renderer->driverdata; GL_TextureData *texturedata; GLenum status; @@ -820,12 +889,12 @@ GL_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture) data->drawstate.viewport_dirty = SDL_TRUE; - if (texture == NULL) { + if (!texture) { data->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); return 0; } - texturedata = (GL_TextureData *) texture->driverdata; + texturedata = (GL_TextureData *)texture->driverdata; data->glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, texturedata->fbo->FBO); /* TODO: check if texture pixel format allows this operation */ data->glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, data->textype, texturedata->texture, 0); @@ -840,16 +909,14 @@ GL_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture) /* !!! FIXME: all these Queue* calls set up the vertex buffer the way the immediate mode !!! FIXME: renderer wants it, but this might want to operate differently if we move to !!! FIXME: VBOs at some point. */ -static int -GL_QueueSetViewport(SDL_Renderer * renderer, SDL_RenderCommand *cmd) +static int GL_QueueSetViewport(SDL_Renderer *renderer, SDL_RenderCommand *cmd) { - return 0; /* nothing to do in this backend. */ + return 0; /* nothing to do in this backend. */ } -static int -GL_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count) +static int GL_QueueDrawPoints(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count) { - GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, count * 2 * sizeof (GLfloat), 0, &cmd->data.draw.first); + GLfloat *verts = (GLfloat *)SDL_AllocateRenderVertices(renderer, count * 2 * sizeof(GLfloat), 0, &cmd->data.draw.first); int i; if (!verts) { @@ -865,133 +932,107 @@ GL_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FP return 0; } -static int -GL_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRect * rects, int count) +static int GL_QueueDrawLines(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count) { - GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, count * 4 * sizeof (GLfloat), 0, &cmd->data.draw.first); int i; + GLfloat prevx, prevy; + const size_t vertlen = (sizeof(GLfloat) * 2) * count; + GLfloat *verts = (GLfloat *)SDL_AllocateRenderVertices(renderer, vertlen, 0, &cmd->data.draw.first); if (!verts) { return -1; } + cmd->data.draw.count = count; + + /* 0.5f offset to hit the center of the pixel. */ + prevx = 0.5f + points->x; + prevy = 0.5f + points->y; + *(verts++) = prevx; + *(verts++) = prevy; + + /* bump the end of each line segment out a quarter of a pixel, to provoke + the diamond-exit rule. Without this, you won't just drop the last + pixel of the last line segment, but you might also drop pixels at the + edge of any given line segment along the way too. */ + for (i = 1; i < count; i++) { + const GLfloat xstart = prevx; + const GLfloat ystart = prevy; + const GLfloat xend = points[i].x + 0.5f; /* 0.5f to hit pixel center. */ + const GLfloat yend = points[i].y + 0.5f; + /* bump a little in the direction we are moving in. */ + const GLfloat deltax = xend - xstart; + const GLfloat deltay = yend - ystart; + const GLfloat angle = SDL_atan2f(deltay, deltax); + prevx = xend + (SDL_cosf(angle) * 0.25f); + prevy = yend + (SDL_sinf(angle) * 0.25f); + *(verts++) = prevx; + *(verts++) = prevy; + } + + return 0; +} + +static int GL_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, + const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride, + int num_vertices, const void *indices, int num_indices, int size_indices, + float scale_x, float scale_y) +{ + GL_TextureData *texturedata = NULL; + int i; + int count = indices ? num_indices : num_vertices; + GLfloat *verts; + size_t sz = 2 * sizeof(GLfloat) + 4 * sizeof(Uint8) + (texture ? 2 : 0) * sizeof(GLfloat); + + verts = (GLfloat *)SDL_AllocateRenderVertices(renderer, count * sz, 0, &cmd->data.draw.first); + if (!verts) { + return -1; + } + + if (texture) { + texturedata = (GL_TextureData *)texture->driverdata; + } cmd->data.draw.count = count; + size_indices = indices ? size_indices : 0; + for (i = 0; i < count; i++) { - const SDL_FRect *rect = &rects[i]; - *(verts++) = rect->x; - *(verts++) = rect->y; - *(verts++) = rect->x + rect->w; - *(verts++) = rect->y + rect->h; - } + int j; + float *xy_; + if (size_indices == 4) { + j = ((const Uint32 *)indices)[i]; + } else if (size_indices == 2) { + j = ((const Uint16 *)indices)[i]; + } else if (size_indices == 1) { + j = ((const Uint8 *)indices)[i]; + } else { + j = i; + } + xy_ = (float *)((char *)xy + j * xy_stride); + + *(verts++) = xy_[0] * scale_x; + *(verts++) = xy_[1] * scale_y; + + /* Not really a float, but it is still 4 bytes and will be cast to the + right type in the graphics driver. */ + SDL_memcpy(verts, ((char *)color + j * color_stride), sizeof(*color)); + ++verts; + + if (texture) { + float *uv_ = (float *)((char *)uv + j * uv_stride); + *(verts++) = uv_[0] * texturedata->texw; + *(verts++) = uv_[1] * texturedata->texh; + } + } return 0; } -static int -GL_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_FRect * dstrect) -{ - GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata; - GLfloat minx, miny, maxx, maxy; - GLfloat minu, maxu, minv, maxv; - GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, 8 * sizeof (GLfloat), 0, &cmd->data.draw.first); - - if (!verts) { - return -1; - } - - cmd->data.draw.count = 1; - - minx = dstrect->x; - miny = dstrect->y; - maxx = dstrect->x + dstrect->w; - maxy = dstrect->y + dstrect->h; - - minu = (GLfloat) srcrect->x / texture->w; - minu *= texturedata->texw; - maxu = (GLfloat) (srcrect->x + srcrect->w) / texture->w; - maxu *= texturedata->texw; - minv = (GLfloat) srcrect->y / texture->h; - minv *= texturedata->texh; - maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h; - maxv *= texturedata->texh; - - cmd->data.draw.count = 1; - *(verts++) = minx; - *(verts++) = miny; - *(verts++) = maxx; - *(verts++) = maxy; - *(verts++) = minu; - *(verts++) = maxu; - *(verts++) = minv; - *(verts++) = maxv; - return 0; -} - -static int -GL_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_FRect * dstrect, - const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip) -{ - GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata; - GLfloat minx, miny, maxx, maxy; - GLfloat centerx, centery; - GLfloat minu, maxu, minv, maxv; - GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, 11 * sizeof (GLfloat), 0, &cmd->data.draw.first); - - if (!verts) { - return -1; - } - - centerx = center->x; - centery = center->y; - - if (flip & SDL_FLIP_HORIZONTAL) { - minx = dstrect->w - centerx; - maxx = -centerx; - } - else { - minx = -centerx; - maxx = dstrect->w - centerx; - } - - if (flip & SDL_FLIP_VERTICAL) { - miny = dstrect->h - centery; - maxy = -centery; - } - else { - miny = -centery; - maxy = dstrect->h - centery; - } - - minu = (GLfloat) srcrect->x / texture->w; - minu *= texturedata->texw; - maxu = (GLfloat) (srcrect->x + srcrect->w) / texture->w; - maxu *= texturedata->texw; - minv = (GLfloat) srcrect->y / texture->h; - minv *= texturedata->texh; - maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h; - maxv *= texturedata->texh; - - cmd->data.draw.count = 1; - *(verts++) = minx; - *(verts++) = miny; - *(verts++) = maxx; - *(verts++) = maxy; - *(verts++) = minu; - *(verts++) = maxu; - *(verts++) = minv; - *(verts++) = maxv; - *(verts++) = (GLfloat) dstrect->x + centerx; - *(verts++) = (GLfloat) dstrect->y + centery; - *(verts++) = (GLfloat) angle; - return 0; -} - -static void -SetDrawState(GL_RenderData *data, const SDL_RenderCommand *cmd, const GL_Shader shader) +static int SetDrawState(GL_RenderData *data, const SDL_RenderCommand *cmd, const GL_Shader shader) { const SDL_BlendMode blend = cmd->data.draw.blend; + SDL_bool vertex_array; + SDL_bool color_array; + SDL_bool texture_array; if (data->drawstate.viewport_dirty) { const SDL_bool istarget = data->drawstate.target != NULL; @@ -1002,9 +1043,9 @@ SetDrawState(GL_RenderData *data, const SDL_RenderCommand *cmd, const GL_Shader istarget ? viewport->y : (data->drawstate.drawableh - viewport->y - viewport->h), viewport->w, viewport->h); if (viewport->w && viewport->h) { - data->glOrtho((GLdouble) 0, (GLdouble) viewport->w, - (GLdouble) istarget ? 0 : viewport->h, - (GLdouble) istarget ? viewport->h : 0, + data->glOrtho((GLdouble)0, (GLdouble)viewport->w, + (GLdouble)istarget ? 0 : viewport->h, + (GLdouble)istarget ? viewport->h : 0, 0.0, 1.0); } data->glMatrixMode(GL_MODELVIEW); @@ -1049,7 +1090,7 @@ SetDrawState(GL_RenderData *data, const SDL_RenderCommand *cmd, const GL_Shader } if ((cmd->data.draw.texture != NULL) != data->drawstate.texturing) { - if (cmd->data.draw.texture == NULL) { + if (!cmd->data.draw.texture) { data->glDisable(data->textype); data->drawstate.texturing = SDL_FALSE; } else { @@ -1057,86 +1098,86 @@ SetDrawState(GL_RenderData *data, const SDL_RenderCommand *cmd, const GL_Shader data->drawstate.texturing = SDL_TRUE; } } + + vertex_array = cmd->command == SDL_RENDERCMD_DRAW_POINTS || cmd->command == SDL_RENDERCMD_DRAW_LINES || cmd->command == SDL_RENDERCMD_GEOMETRY; + color_array = cmd->command == SDL_RENDERCMD_GEOMETRY; + texture_array = cmd->data.draw.texture != NULL; + + if (vertex_array != data->drawstate.vertex_array) { + if (vertex_array) { + data->glEnableClientState(GL_VERTEX_ARRAY); + } else { + data->glDisableClientState(GL_VERTEX_ARRAY); + } + data->drawstate.vertex_array = vertex_array; + } + + if (color_array != data->drawstate.color_array) { + if (color_array) { + data->glEnableClientState(GL_COLOR_ARRAY); + } else { + data->glDisableClientState(GL_COLOR_ARRAY); + } + data->drawstate.color_array = color_array; + } + + /* This is a little awkward but should avoid texcoord arrays getting into + a bad state if SDL_GL_BindTexture/UnbindTexture are called. */ + if (texture_array != data->drawstate.texture_array) { + if (texture_array) { + data->glEnableClientState(GL_TEXTURE_COORD_ARRAY); + } else { + data->glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } + data->drawstate.texture_array = texture_array; + } + + return 0; } -static void -SetCopyState(GL_RenderData *data, const SDL_RenderCommand *cmd) +static int SetCopyState(GL_RenderData *data, const SDL_RenderCommand *cmd) { SDL_Texture *texture = cmd->data.draw.texture; - const GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata; - GL_Shader shader; + const GL_TextureData *texturedata = (GL_TextureData *)texture->driverdata; - if (texture->format == SDL_PIXELFORMAT_ABGR8888 || texture->format == SDL_PIXELFORMAT_ARGB8888) { - shader = SHADER_RGBA; - } else { - shader = SHADER_RGB; - } - - if (data->shaders) { - if (texturedata->yuv || texturedata->nv12) { - switch (SDL_GetYUVConversionModeForResolution(texture->w, texture->h)) { - case SDL_YUV_CONVERSION_JPEG: - if (texturedata->yuv) { - shader = SHADER_YUV_JPEG; - } else if (texture->format == SDL_PIXELFORMAT_NV12) { - shader = SHADER_NV12_JPEG; - } else { - shader = SHADER_NV21_JPEG; - } - break; - case SDL_YUV_CONVERSION_BT601: - if (texturedata->yuv) { - shader = SHADER_YUV_BT601; - } else if (texture->format == SDL_PIXELFORMAT_NV12) { - shader = SHADER_NV12_BT601; - } else { - shader = SHADER_NV21_BT601; - } - break; - case SDL_YUV_CONVERSION_BT709: - if (texturedata->yuv) { - shader = SHADER_YUV_BT709; - } else if (texture->format == SDL_PIXELFORMAT_NV12) { - shader = SHADER_NV12_BT709; - } else { - shader = SHADER_NV21_BT709; - } - break; - default: - SDL_assert(!"unsupported YUV conversion mode"); - break; - } - } - } - - SetDrawState(data, cmd, shader); + SetDrawState(data, cmd, texturedata->shader); if (texture != data->drawstate.texture) { const GLenum textype = data->textype; +#if SDL_HAVE_YUV if (texturedata->yuv) { - data->glActiveTextureARB(GL_TEXTURE2_ARB); + if (data->GL_ARB_multitexture_supported) { + data->glActiveTextureARB(GL_TEXTURE2_ARB); + } data->glBindTexture(textype, texturedata->vtexture); - data->glActiveTextureARB(GL_TEXTURE1_ARB); + if (data->GL_ARB_multitexture_supported) { + data->glActiveTextureARB(GL_TEXTURE1_ARB); + } data->glBindTexture(textype, texturedata->utexture); } if (texturedata->nv12) { - data->glActiveTextureARB(GL_TEXTURE1_ARB); + if (data->GL_ARB_multitexture_supported) { + data->glActiveTextureARB(GL_TEXTURE1_ARB); + } data->glBindTexture(textype, texturedata->utexture); } - data->glActiveTextureARB(GL_TEXTURE0_ARB); +#endif + if (data->GL_ARB_multitexture_supported) { + data->glActiveTextureARB(GL_TEXTURE0_ARB); + } data->glBindTexture(textype, texturedata->texture); data->drawstate.texture = texture; } + + return 0; } -static int -GL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize) +static int GL_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize) { /* !!! FIXME: it'd be nice to use a vertex buffer instead of immediate mode... */ - GL_RenderData *data = (GL_RenderData *) renderer->driverdata; - size_t i; + GL_RenderData *data = (GL_RenderData *)renderer->driverdata; if (GL_ActivateRenderer(renderer) < 0) { return -1; @@ -1144,228 +1185,238 @@ GL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic data->drawstate.target = renderer->target; if (!data->drawstate.target) { - SDL_GL_GetDrawableSize(renderer->window, &data->drawstate.drawablew, &data->drawstate.drawableh); + int w, h; + SDL_GL_GetDrawableSize(renderer->window, &w, &h); + if ((w != data->drawstate.drawablew) || (h != data->drawstate.drawableh)) { + data->drawstate.viewport_dirty = SDL_TRUE; // if the window dimensions changed, invalidate the current viewport, etc. + data->drawstate.cliprect_dirty = SDL_TRUE; + data->drawstate.drawablew = w; + data->drawstate.drawableh = h; + } } +#ifdef __MACOSX__ + // On macOS on older systems, the OpenGL view change and resize events aren't + // necessarily synchronized, so just always reset it. + // Workaround for: https://discourse.libsdl.org/t/sdl-2-0-22-prerelease/35306/6 + data->drawstate.viewport_dirty = SDL_TRUE; +#endif while (cmd) { switch (cmd->command) { - case SDL_RENDERCMD_SETDRAWCOLOR: { - const Uint8 r = cmd->data.color.r; - const Uint8 g = cmd->data.color.g; - const Uint8 b = cmd->data.color.b; - const Uint8 a = cmd->data.color.a; - const Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b); - if (color != data->drawstate.color) { - data->glColor4f((GLfloat) r * inv255f, - (GLfloat) g * inv255f, - (GLfloat) b * inv255f, - (GLfloat) a * inv255f); - data->drawstate.color = color; - } - break; + case SDL_RENDERCMD_SETDRAWCOLOR: + { + const Uint8 r = cmd->data.color.r; + const Uint8 g = cmd->data.color.g; + const Uint8 b = cmd->data.color.b; + const Uint8 a = cmd->data.color.a; + const Uint32 color = (((Uint32)a << 24) | (r << 16) | (g << 8) | b); + if (color != data->drawstate.color) { + data->glColor4ub((GLubyte)r, (GLubyte)g, (GLubyte)b, (GLubyte)a); + data->drawstate.color = color; + } + break; + } + + case SDL_RENDERCMD_SETVIEWPORT: + { + SDL_Rect *viewport = &data->drawstate.viewport; + if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof(cmd->data.viewport.rect)) != 0) { + SDL_copyp(viewport, &cmd->data.viewport.rect); + data->drawstate.viewport_dirty = SDL_TRUE; + data->drawstate.cliprect_dirty = SDL_TRUE; + } + break; + } + + case SDL_RENDERCMD_SETCLIPRECT: + { + const SDL_Rect *rect = &cmd->data.cliprect.rect; + if (data->drawstate.cliprect_enabled != cmd->data.cliprect.enabled) { + data->drawstate.cliprect_enabled = cmd->data.cliprect.enabled; + data->drawstate.cliprect_enabled_dirty = SDL_TRUE; } - case SDL_RENDERCMD_SETVIEWPORT: { - SDL_Rect *viewport = &data->drawstate.viewport; - if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect)) != 0) { - SDL_memcpy(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect)); - data->drawstate.viewport_dirty = SDL_TRUE; - } - break; + if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof(*rect)) != 0) { + SDL_copyp(&data->drawstate.cliprect, rect); + data->drawstate.cliprect_dirty = SDL_TRUE; + } + break; + } + + case SDL_RENDERCMD_CLEAR: + { + const Uint8 r = cmd->data.color.r; + const Uint8 g = cmd->data.color.g; + const Uint8 b = cmd->data.color.b; + const Uint8 a = cmd->data.color.a; + const Uint32 color = (((Uint32)a << 24) | (r << 16) | (g << 8) | b); + if (color != data->drawstate.clear_color) { + const GLfloat fr = ((GLfloat)r) * inv255f; + const GLfloat fg = ((GLfloat)g) * inv255f; + const GLfloat fb = ((GLfloat)b) * inv255f; + const GLfloat fa = ((GLfloat)a) * inv255f; + data->glClearColor(fr, fg, fb, fa); + data->drawstate.clear_color = color; } - case SDL_RENDERCMD_SETCLIPRECT: { - const SDL_Rect *rect = &cmd->data.cliprect.rect; - if (data->drawstate.cliprect_enabled != cmd->data.cliprect.enabled) { - data->drawstate.cliprect_enabled = cmd->data.cliprect.enabled; - data->drawstate.cliprect_enabled_dirty = SDL_TRUE; - } - if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof (SDL_Rect)) != 0) { - SDL_memcpy(&data->drawstate.cliprect, rect, sizeof (SDL_Rect)); - data->drawstate.cliprect_dirty = SDL_TRUE; - } - break; + if (data->drawstate.cliprect_enabled || data->drawstate.cliprect_enabled_dirty) { + data->glDisable(GL_SCISSOR_TEST); + data->drawstate.cliprect_enabled_dirty = data->drawstate.cliprect_enabled; } - case SDL_RENDERCMD_CLEAR: { - const Uint8 r = cmd->data.color.r; - const Uint8 g = cmd->data.color.g; - const Uint8 b = cmd->data.color.b; - const Uint8 a = cmd->data.color.a; - const Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b); - if (color != data->drawstate.clear_color) { - const GLfloat fr = ((GLfloat) r) * inv255f; - const GLfloat fg = ((GLfloat) g) * inv255f; - const GLfloat fb = ((GLfloat) b) * inv255f; - const GLfloat fa = ((GLfloat) a) * inv255f; - data->glClearColor(fr, fg, fb, fa); - data->drawstate.clear_color = color; - } + data->glClear(GL_COLOR_BUFFER_BIT); + break; + } - if (data->drawstate.cliprect_enabled || data->drawstate.cliprect_enabled_dirty) { - data->glDisable(GL_SCISSOR_TEST); - data->drawstate.cliprect_enabled_dirty = data->drawstate.cliprect_enabled; - } + case SDL_RENDERCMD_FILL_RECTS: /* unused */ + break; - data->glClear(GL_COLOR_BUFFER_BIT); + case SDL_RENDERCMD_COPY: /* unused */ + break; - break; - } + case SDL_RENDERCMD_COPY_EX: /* unused */ + break; - case SDL_RENDERCMD_DRAW_POINTS: { - const size_t count = cmd->data.draw.count; - const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first); - SetDrawState(data, cmd, SHADER_SOLID); - data->glBegin(GL_POINTS); - for (i = 0; i < count; i++, verts += 2) { - data->glVertex2f(verts[0], verts[1]); - } - data->glEnd(); - break; - } + case SDL_RENDERCMD_DRAW_LINES: + { + if (SetDrawState(data, cmd, SHADER_SOLID) == 0) { + size_t count = cmd->data.draw.count; + const GLfloat *verts = (GLfloat *)(((Uint8 *)vertices) + cmd->data.draw.first); - case SDL_RENDERCMD_DRAW_LINES: { - const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first); - const size_t count = cmd->data.draw.count; - SetDrawState(data, cmd, SHADER_SOLID); - if (count > 2 && (verts[0] == verts[(count-1)*2]) && (verts[1] == verts[(count*2)-1])) { - data->glBegin(GL_LINE_LOOP); - /* GL_LINE_LOOP takes care of the final segment */ - for (i = 1; i < count; ++i, verts += 2) { - data->glVertex2f(verts[0], verts[1]); - } - data->glEnd(); + /* SetDrawState handles glEnableClientState. */ + data->glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, verts); + + if (count > 2) { + /* joined lines cannot be grouped */ + data->glDrawArrays(GL_LINE_STRIP, 0, (GLsizei)count); } else { - #if defined(__MACOSX__) || defined(__WIN32__) - #else - int x1, y1, x2, y2; - #endif + /* let's group non joined lines */ + SDL_RenderCommand *finalcmd = cmd; + SDL_RenderCommand *nextcmd = cmd->next; + SDL_BlendMode thisblend = cmd->data.draw.blend; - data->glBegin(GL_LINE_STRIP); - for (i = 0; i < count; ++i, verts += 2) { - data->glVertex2f(verts[0], verts[1]); + while (nextcmd) { + const SDL_RenderCommandType nextcmdtype = nextcmd->command; + if (nextcmdtype != SDL_RENDERCMD_DRAW_LINES) { + break; /* can't go any further on this draw call, different render command up next. */ + } else if (nextcmd->data.draw.count != 2) { + break; /* can't go any further on this draw call, those are joined lines */ + } else if (nextcmd->data.draw.blend != thisblend) { + break; /* can't go any further on this draw call, different blendmode copy up next. */ + } else { + finalcmd = nextcmd; /* we can combine copy operations here. Mark this one as the furthest okay command. */ + count += nextcmd->data.draw.count; + } + nextcmd = nextcmd->next; } - data->glEnd(); - verts -= 2 * count; - /* The line is half open, so we need one more point to complete it. - * http://www.opengl.org/documentation/specs/version1.1/glspec1.1/node47.html - * If we have to, we can use vertical line and horizontal line textures - * for vertical and horizontal lines, and then create custom textures - * for diagonal lines and software render those. It's terrible, but at - * least it would be pixel perfect. - */ - - data->glBegin(GL_POINTS); - #if defined(__MACOSX__) || defined(__WIN32__) - /* Mac OS X and Windows seem to always leave the last point open */ - data->glVertex2f(verts[(count-1)*2], verts[(count*2)-1]); - #else - /* Linux seems to leave the right-most or bottom-most point open */ - x1 = verts[0]; - y1 = verts[1]; - x2 = verts[(count-1)*2]; - y2 = verts[(count*2)-1]; - - if (x1 > x2) { - data->glVertex2f(x1, y1); - } else if (x2 > x1) { - data->glVertex2f(x2, y2); - } - if (y1 > y2) { - data->glVertex2f(x1, y1); - } else if (y2 > y1) { - data->glVertex2f(x2, y2); - } - #endif - data->glEnd(); + data->glDrawArrays(GL_LINES, 0, (GLsizei)count); + cmd = finalcmd; /* skip any copy commands we just combined in here. */ } - break; } + break; + } - case SDL_RENDERCMD_FILL_RECTS: { - const size_t count = cmd->data.draw.count; - const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first); - SetDrawState(data, cmd, SHADER_SOLID); - for (i = 0; i < count; ++i, verts += 4) { - data->glRectf(verts[0], verts[1], verts[2], verts[3]); + case SDL_RENDERCMD_DRAW_POINTS: + case SDL_RENDERCMD_GEOMETRY: + { + /* as long as we have the same copy command in a row, with the + same texture, we can combine them all into a single draw call. */ + SDL_Texture *thistexture = cmd->data.draw.texture; + SDL_BlendMode thisblend = cmd->data.draw.blend; + const SDL_RenderCommandType thiscmdtype = cmd->command; + SDL_RenderCommand *finalcmd = cmd; + SDL_RenderCommand *nextcmd = cmd->next; + size_t count = cmd->data.draw.count; + int ret; + while (nextcmd) { + const SDL_RenderCommandType nextcmdtype = nextcmd->command; + if (nextcmdtype != thiscmdtype) { + break; /* can't go any further on this draw call, different render command up next. */ + } else if (nextcmd->data.draw.texture != thistexture || nextcmd->data.draw.blend != thisblend) { + break; /* can't go any further on this draw call, different texture/blendmode copy up next. */ + } else { + finalcmd = nextcmd; /* we can combine copy operations here. Mark this one as the furthest okay command. */ + count += nextcmd->data.draw.count; } - break; + nextcmd = nextcmd->next; } - case SDL_RENDERCMD_COPY: { - const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first); - const GLfloat minx = verts[0]; - const GLfloat miny = verts[1]; - const GLfloat maxx = verts[2]; - const GLfloat maxy = verts[3]; - const GLfloat minu = verts[4]; - const GLfloat maxu = verts[5]; - const GLfloat minv = verts[6]; - const GLfloat maxv = verts[7]; - SetCopyState(data, cmd); - data->glBegin(GL_TRIANGLE_STRIP); - data->glTexCoord2f(minu, minv); - data->glVertex2f(minx, miny); - data->glTexCoord2f(maxu, minv); - data->glVertex2f(maxx, miny); - data->glTexCoord2f(minu, maxv); - data->glVertex2f(minx, maxy); - data->glTexCoord2f(maxu, maxv); - data->glVertex2f(maxx, maxy); - data->glEnd(); - break; + if (thistexture) { + ret = SetCopyState(data, cmd); + } else { + ret = SetDrawState(data, cmd, SHADER_SOLID); } - case SDL_RENDERCMD_COPY_EX: { - const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first); - const GLfloat minx = verts[0]; - const GLfloat miny = verts[1]; - const GLfloat maxx = verts[2]; - const GLfloat maxy = verts[3]; - const GLfloat minu = verts[4]; - const GLfloat maxu = verts[5]; - const GLfloat minv = verts[6]; - const GLfloat maxv = verts[7]; - const GLfloat translatex = verts[8]; - const GLfloat translatey = verts[9]; - const GLdouble angle = verts[10]; - SetCopyState(data, cmd); + if (ret == 0) { + const GLfloat *verts = (GLfloat *)(((Uint8 *)vertices) + cmd->data.draw.first); + int op = GL_TRIANGLES; /* SDL_RENDERCMD_GEOMETRY */ + if (thiscmdtype == SDL_RENDERCMD_DRAW_POINTS) { + op = GL_POINTS; + } - /* Translate to flip, rotate, translate to position */ - data->glPushMatrix(); - data->glTranslatef(translatex, translatey, 0.0f); - data->glRotated(angle, 0.0, 0.0, 1.0); - data->glBegin(GL_TRIANGLE_STRIP); - data->glTexCoord2f(minu, minv); - data->glVertex2f(minx, miny); - data->glTexCoord2f(maxu, minv); - data->glVertex2f(maxx, miny); - data->glTexCoord2f(minu, maxv); - data->glVertex2f(minx, maxy); - data->glTexCoord2f(maxu, maxv); - data->glVertex2f(maxx, maxy); - data->glEnd(); - data->glPopMatrix(); - break; + if (thiscmdtype == SDL_RENDERCMD_DRAW_POINTS) { + /* SetDrawState handles glEnableClientState. */ + data->glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, verts); + } else { + /* SetDrawState handles glEnableClientState. */ + if (thistexture) { + data->glVertexPointer(2, GL_FLOAT, sizeof(float) * 5, verts + 0); + data->glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(float) * 5, verts + 2); + data->glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 5, verts + 3); + } else { + data->glVertexPointer(2, GL_FLOAT, sizeof(float) * 3, verts + 0); + data->glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(float) * 3, verts + 2); + } + } + + data->glDrawArrays(op, 0, (GLsizei)count); + + /* Restore previously set color when we're done. */ + if (thiscmdtype != SDL_RENDERCMD_DRAW_POINTS) { + Uint32 color = data->drawstate.color; + GLubyte a = (GLubyte)((color >> 24) & 0xFF); + GLubyte r = (GLubyte)((color >> 16) & 0xFF); + GLubyte g = (GLubyte)((color >> 8) & 0xFF); + GLubyte b = (GLubyte)((color >> 0) & 0xFF); + data->glColor4ub(r, g, b, a); + } } - case SDL_RENDERCMD_NO_OP: - break; + cmd = finalcmd; /* skip any copy commands we just combined in here. */ + break; + } + + case SDL_RENDERCMD_NO_OP: + break; } cmd = cmd->next; } + /* Turn off vertex array state when we're done, in case external code + relies on it being off. */ + if (data->drawstate.vertex_array) { + data->glDisableClientState(GL_VERTEX_ARRAY); + data->drawstate.vertex_array = SDL_FALSE; + } + if (data->drawstate.color_array) { + data->glDisableClientState(GL_COLOR_ARRAY); + data->drawstate.color_array = SDL_FALSE; + } + if (data->drawstate.texture_array) { + data->glDisableClientState(GL_TEXTURE_COORD_ARRAY); + data->drawstate.texture_array = SDL_FALSE; + } + return GL_CheckError("", renderer); } -static int -GL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, - Uint32 pixel_format, void * pixels, int pitch) +static int GL_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect, + Uint32 pixel_format, void *pixels, int pitch) { - GL_RenderData *data = (GL_RenderData *) renderer->driverdata; + GL_RenderData *data = (GL_RenderData *)renderer->driverdata; Uint32 temp_format = renderer->target ? renderer->target->format : SDL_PIXELFORMAT_ARGB8888; void *temp_pixels; int temp_pitch; @@ -1382,12 +1433,12 @@ GL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, SDL_GetPixelFormatName(temp_format)); } - if (!rect->w || !rect->h) { - return 0; /* nothing to do. */ + if (rect->w == 0 || rect->h == 0) { + return 0; /* nothing to do. */ } temp_pitch = rect->w * SDL_BYTESPERPIXEL(temp_format); - temp_pixels = SDL_malloc(rect->h * temp_pitch); + temp_pixels = SDL_malloc((size_t)rect->h * temp_pitch); if (!temp_pixels) { return SDL_OutOfMemory(); } @@ -1398,7 +1449,7 @@ GL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, data->glPixelStorei(GL_PACK_ROW_LENGTH, (temp_pitch / SDL_BYTESPERPIXEL(temp_format))); - data->glReadPixels(rect->x, renderer->target ? rect->y : (h-rect->y)-rect->h, + data->glReadPixels(rect->x, renderer->target ? rect->y : (h - rect->y) - rect->h, rect->w, rect->h, format, type, temp_pixels); if (GL_CheckError("glReadPixels()", renderer) < 0) { @@ -1410,8 +1461,8 @@ GL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, if (!renderer->target) { SDL_bool isstack; length = rect->w * SDL_BYTESPERPIXEL(temp_format); - src = (Uint8*)temp_pixels + (rect->h-1)*temp_pitch; - dst = (Uint8*)temp_pixels; + src = (Uint8 *)temp_pixels + (rect->h - 1) * temp_pitch; + dst = (Uint8 *)temp_pixels; tmp = SDL_small_alloc(Uint8, length, &isstack); rows = rect->h / 2; while (rows--) { @@ -1432,19 +1483,17 @@ GL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, return status; } -static void -GL_RenderPresent(SDL_Renderer * renderer) +static int GL_RenderPresent(SDL_Renderer *renderer) { GL_ActivateRenderer(renderer); - SDL_GL_SwapWindow(renderer->window); + return SDL_GL_SwapWindowWithResult(renderer->window); } -static void -GL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) +static void GL_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture) { - GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata; - GL_TextureData *data = (GL_TextureData *) texture->driverdata; + GL_RenderData *renderdata = (GL_RenderData *)renderer->driverdata; + GL_TextureData *data = (GL_TextureData *)texture->driverdata; GL_ActivateRenderer(renderer); @@ -1461,29 +1510,30 @@ GL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) if (data->texture) { renderdata->glDeleteTextures(1, &data->texture); } +#if SDL_HAVE_YUV if (data->yuv) { renderdata->glDeleteTextures(1, &data->utexture); renderdata->glDeleteTextures(1, &data->vtexture); } +#endif SDL_free(data->pixels); SDL_free(data); texture->driverdata = NULL; } -static void -GL_DestroyRenderer(SDL_Renderer * renderer) +static void GL_DestroyRenderer(SDL_Renderer *renderer) { - GL_RenderData *data = (GL_RenderData *) renderer->driverdata; + GL_RenderData *data = (GL_RenderData *)renderer->driverdata; if (data) { - if (data->context != NULL) { + if (data->context) { /* make sure we delete the right resources! */ GL_ActivateRenderer(renderer); } GL_ClearErrors(renderer); if (data->GL_ARB_debug_output_supported) { - PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARBFunc = (PFNGLDEBUGMESSAGECALLBACKARBPROC) SDL_GL_GetProcAddress("glDebugMessageCallbackARB"); + PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARBFunc = (PFNGLDEBUGMESSAGECALLBACKARBPROC)SDL_GL_GetProcAddress("glDebugMessageCallbackARB"); /* Uh oh, we don't have a safe way of removing ourselves from the callback chain, if it changed after we set our callback. */ /* For now, just always replace the callback with the original one */ @@ -1508,55 +1558,95 @@ GL_DestroyRenderer(SDL_Renderer * renderer) SDL_free(renderer); } -static int -GL_BindTexture (SDL_Renderer * renderer, SDL_Texture *texture, float *texw, float *texh) +static int GL_BindTexture(SDL_Renderer *renderer, SDL_Texture *texture, float *texw, float *texh) { - GL_RenderData *data = (GL_RenderData *) renderer->driverdata; - GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata; + GL_RenderData *data = (GL_RenderData *)renderer->driverdata; + GL_TextureData *texturedata = (GL_TextureData *)texture->driverdata; const GLenum textype = data->textype; GL_ActivateRenderer(renderer); data->glEnable(textype); +#if SDL_HAVE_YUV if (texturedata->yuv) { - data->glActiveTextureARB(GL_TEXTURE2_ARB); + if (data->GL_ARB_multitexture_supported) { + data->glActiveTextureARB(GL_TEXTURE2_ARB); + } data->glBindTexture(textype, texturedata->vtexture); - data->glActiveTextureARB(GL_TEXTURE1_ARB); + if (data->GL_ARB_multitexture_supported) { + data->glActiveTextureARB(GL_TEXTURE1_ARB); + } data->glBindTexture(textype, texturedata->utexture); - data->glActiveTextureARB(GL_TEXTURE0_ARB); + if (data->GL_ARB_multitexture_supported) { + data->glActiveTextureARB(GL_TEXTURE0_ARB); + } } + if (texturedata->nv12) { + if (data->GL_ARB_multitexture_supported) { + data->glActiveTextureARB(GL_TEXTURE1_ARB); + } + data->glBindTexture(textype, texturedata->utexture); + + if (data->GL_ARB_multitexture_supported) { + data->glActiveTextureARB(GL_TEXTURE0_ARB); + } + } +#endif data->glBindTexture(textype, texturedata->texture); data->drawstate.texturing = SDL_TRUE; data->drawstate.texture = texture; - if(texw) *texw = (float)texturedata->texw; - if(texh) *texh = (float)texturedata->texh; - + if (texw) { + *texw = (float)texturedata->texw; + } + if (texh) { + *texh = (float)texturedata->texh; + } return 0; } -static int -GL_UnbindTexture (SDL_Renderer * renderer, SDL_Texture *texture) +static int GL_UnbindTexture(SDL_Renderer *renderer, SDL_Texture *texture) { - GL_RenderData *data = (GL_RenderData *) renderer->driverdata; - GL_TextureData *texturedata = (GL_TextureData *) texture->driverdata; + GL_RenderData *data = (GL_RenderData *)renderer->driverdata; + GL_TextureData *texturedata = (GL_TextureData *)texture->driverdata; const GLenum textype = data->textype; GL_ActivateRenderer(renderer); +#if SDL_HAVE_YUV if (texturedata->yuv) { - data->glActiveTextureARB(GL_TEXTURE2_ARB); + if (data->GL_ARB_multitexture_supported) { + data->glActiveTextureARB(GL_TEXTURE2_ARB); + } + data->glBindTexture(textype, 0); data->glDisable(textype); - data->glActiveTextureARB(GL_TEXTURE1_ARB); + if (data->GL_ARB_multitexture_supported) { + data->glActiveTextureARB(GL_TEXTURE1_ARB); + } + data->glBindTexture(textype, 0); data->glDisable(textype); - data->glActiveTextureARB(GL_TEXTURE0_ARB); + if (data->GL_ARB_multitexture_supported) { + data->glActiveTextureARB(GL_TEXTURE0_ARB); + } } + if (texturedata->nv12) { + if (data->GL_ARB_multitexture_supported) { + data->glActiveTextureARB(GL_TEXTURE1_ARB); + } + data->glBindTexture(textype, 0); + data->glDisable(textype); + if (data->GL_ARB_multitexture_supported) { + data->glActiveTextureARB(GL_TEXTURE0_ARB); + } + } +#endif + data->glBindTexture(textype, 0); data->glDisable(textype); data->drawstate.texturing = SDL_FALSE; @@ -1565,9 +1655,52 @@ GL_UnbindTexture (SDL_Renderer * renderer, SDL_Texture *texture) return 0; } +static int GL_SetVSync(SDL_Renderer *renderer, const int vsync) +{ + int retval; + if (vsync) { + retval = SDL_GL_SetSwapInterval(1); + } else { + retval = SDL_GL_SetSwapInterval(0); + } + if (retval != 0) { + return retval; + } + if (SDL_GL_GetSwapInterval() != 0) { + renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; + } else { + renderer->info.flags &= ~SDL_RENDERER_PRESENTVSYNC; + } + return retval; +} -SDL_Renderer * -GL_CreateRenderer(SDL_Window * window, Uint32 flags) +static SDL_bool GL_IsProbablyAccelerated(const GL_RenderData *data) +{ + /*const char *vendor = (const char *) data->glGetString(GL_VENDOR);*/ + const char *renderer = (const char *)data->glGetString(GL_RENDERER); + +#if defined(__WINDOWS__) || defined(__WINGDK__) + if (SDL_strcmp(renderer, "GDI Generic") == 0) { + return SDL_FALSE; /* Microsoft's fallback software renderer. Fix your system! */ + } +#endif + +#ifdef __APPLE__ + if (SDL_strcmp(renderer, "Apple Software Renderer") == 0) { + return SDL_FALSE; /* (a probably very old) Apple software-based OpenGL. */ + } +#endif + + if (SDL_strcmp(renderer, "Software Rasterizer") == 0) { + return SDL_FALSE; /* (a probably very old) Software Mesa, or some other generic thing. */ + } + + /* !!! FIXME: swrast? llvmpipe? softpipe? */ + + return SDL_TRUE; +} + +static SDL_Renderer *GL_CreateRenderer(SDL_Window *window, Uint32 flags) { SDL_Renderer *renderer; GL_RenderData *data; @@ -1575,11 +1708,14 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags) Uint32 window_flags; int profile_mask = 0, major = 0, minor = 0; SDL_bool changed_window = SDL_FALSE; + const char *hint; + SDL_bool non_power_of_two_supported = SDL_FALSE; SDL_GL_GetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, &profile_mask); SDL_GL_GetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, &major); SDL_GL_GetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, &minor); +#ifndef SDL_VIDEO_VITA_PVR_OGL 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) { @@ -1589,49 +1725,53 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags) 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) { + if (SDL_RecreateWindow(window, (window_flags & ~(SDL_WINDOW_VULKAN | SDL_WINDOW_METAL)) | SDL_WINDOW_OPENGL) < 0) { goto error; } } +#endif - renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer)); + renderer = (SDL_Renderer *)SDL_calloc(1, sizeof(*renderer)); if (!renderer) { SDL_OutOfMemory(); goto error; } - data = (GL_RenderData *) SDL_calloc(1, sizeof(*data)); + data = (GL_RenderData *)SDL_calloc(1, sizeof(*data)); if (!data) { SDL_free(renderer); SDL_OutOfMemory(); goto error; } + renderer->WindowEvent = GL_WindowEvent; renderer->GetOutputSize = GL_GetOutputSize; renderer->SupportsBlendMode = GL_SupportsBlendMode; renderer->CreateTexture = GL_CreateTexture; renderer->UpdateTexture = GL_UpdateTexture; +#if SDL_HAVE_YUV renderer->UpdateTextureYUV = GL_UpdateTextureYUV; + renderer->UpdateTextureNV = GL_UpdateTextureNV; +#endif renderer->LockTexture = GL_LockTexture; renderer->UnlockTexture = GL_UnlockTexture; renderer->SetTextureScaleMode = GL_SetTextureScaleMode; renderer->SetRenderTarget = GL_SetRenderTarget; renderer->QueueSetViewport = GL_QueueSetViewport; - renderer->QueueSetDrawColor = GL_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */ + renderer->QueueSetDrawColor = GL_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */ renderer->QueueDrawPoints = GL_QueueDrawPoints; - renderer->QueueDrawLines = GL_QueueDrawPoints; /* lines and points queue vertices the same way. */ - renderer->QueueFillRects = GL_QueueFillRects; - renderer->QueueCopy = GL_QueueCopy; - renderer->QueueCopyEx = GL_QueueCopyEx; + renderer->QueueDrawLines = GL_QueueDrawLines; + renderer->QueueGeometry = GL_QueueGeometry; renderer->RunCommandQueue = GL_RunCommandQueue; renderer->RenderReadPixels = GL_RenderReadPixels; renderer->RenderPresent = GL_RenderPresent; renderer->DestroyTexture = GL_DestroyTexture; renderer->DestroyRenderer = GL_DestroyRenderer; + renderer->SetVSync = GL_SetVSync; renderer->GL_BindTexture = GL_BindTexture; renderer->GL_UnbindTexture = GL_UnbindTexture; renderer->info = GL_RenderDriver.info; - renderer->info.flags = SDL_RENDERER_ACCELERATED; + renderer->info.flags = 0; /* will set some flags below. */ renderer->driverdata = data; renderer->window = window; @@ -1655,6 +1795,10 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags) goto error; } + if (GL_IsProbablyAccelerated(data)) { + renderer->info.flags |= SDL_RENDERER_ACCELERATED; + } + #ifdef __MACOSX__ /* Enable multi-threaded rendering */ /* Disabled until Ryan finishes his VBO/PBO code... @@ -1667,7 +1811,7 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags) } else { SDL_GL_SetSwapInterval(0); } - if (SDL_GL_GetSwapInterval() > 0) { + if (SDL_GL_GetSwapInterval() != 0) { renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; } @@ -1677,7 +1821,7 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags) data->debug_enabled = SDL_TRUE; } if (data->debug_enabled && SDL_GL_ExtensionSupported("GL_ARB_debug_output")) { - PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARBFunc = (PFNGLDEBUGMESSAGECALLBACKARBPROC) SDL_GL_GetProcAddress("glDebugMessageCallbackARB"); + PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARBFunc = (PFNGLDEBUGMESSAGECALLBACKARBPROC)SDL_GL_GetProcAddress("glDebugMessageCallbackARB"); data->GL_ARB_debug_output_supported = SDL_TRUE; data->glGetPointerv(GL_DEBUG_CALLBACK_FUNCTION_ARB, (GLvoid **)(char *)&data->next_error_callback); @@ -1688,15 +1832,37 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags) data->glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); } + hint = SDL_getenv("GL_ARB_texture_non_power_of_two"); + if (!hint || *hint != '0') { + SDL_bool isGL2 = SDL_FALSE; + const char *verstr = (const char *)data->glGetString(GL_VERSION); + if (verstr) { + char verbuf[16]; + char *ptr; + SDL_strlcpy(verbuf, verstr, sizeof(verbuf)); + ptr = SDL_strchr(verbuf, '.'); + if (ptr) { + *ptr = '\0'; + if (SDL_atoi(verbuf) >= 2) { + isGL2 = SDL_TRUE; + } + } + } + if (isGL2 || SDL_GL_ExtensionSupported("GL_ARB_texture_non_power_of_two")) { + non_power_of_two_supported = SDL_TRUE; + } + } + data->textype = GL_TEXTURE_2D; - if (SDL_GL_ExtensionSupported("GL_ARB_texture_non_power_of_two")) { + if (non_power_of_two_supported) { data->GL_ARB_texture_non_power_of_two_supported = SDL_TRUE; + data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value); + renderer->info.max_texture_width = value; + renderer->info.max_texture_height = value; } else if (SDL_GL_ExtensionSupported("GL_ARB_texture_rectangle") || SDL_GL_ExtensionSupported("GL_EXT_texture_rectangle")) { data->GL_ARB_texture_rectangle_supported = SDL_TRUE; data->textype = GL_TEXTURE_RECTANGLE_ARB; - } - if (data->GL_ARB_texture_rectangle_supported) { data->glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB, &value); renderer->info.max_texture_width = value; renderer->info.max_texture_height = value; @@ -1708,7 +1874,7 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags) /* Check for multitexture support */ if (SDL_GL_ExtensionSupported("GL_ARB_multitexture")) { - data->glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC) SDL_GL_GetProcAddress("glActiveTextureARB"); + data->glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC)SDL_GL_GetProcAddress("glActiveTextureARB"); if (data->glActiveTextureARB) { data->GL_ARB_multitexture_supported = SDL_TRUE; data->glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &data->num_texture_units); @@ -1721,19 +1887,30 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags) } SDL_LogInfo(SDL_LOG_CATEGORY_RENDER, "OpenGL shaders: %s", data->shaders ? "ENABLED" : "DISABLED"); - +#if SDL_HAVE_YUV /* We support YV12 textures using 3 textures and a shader */ if (data->shaders && data->num_texture_units >= 3) { renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_YV12; renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_IYUV; + } + + /* We support NV12 textures using 2 textures and a shader */ + if (data->shaders && data->num_texture_units >= 2) { renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_NV12; renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_NV21; } - +#endif #ifdef __MACOSX__ renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_UYVY; #endif + renderer->rect_index_order[0] = 0; + renderer->rect_index_order[1] = 1; + renderer->rect_index_order[2] = 3; + renderer->rect_index_order[3] = 1; + renderer->rect_index_order[4] = 3; + renderer->rect_index_order[5] = 2; + if (SDL_GL_ExtensionSupported("GL_EXT_framebuffer_object")) { data->GL_EXT_framebuffer_object_supported = SDL_TRUE; data->glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC) @@ -1758,7 +1935,7 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags) data->glDisable(GL_SCISSOR_TEST); data->glDisable(data->textype); data->glClearColor(1.0f, 1.0f, 1.0f, 1.0f); - data->glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + data->glColor4ub(255, 255, 255, 255); /* This ended up causing video discrepancies between OpenGL and Direct3D */ /* data->glEnable(GL_LINE_SMOOTH); */ @@ -1780,24 +1957,19 @@ error: return NULL; } - SDL_RenderDriver GL_RenderDriver = { GL_CreateRenderer, - { - "opengl", - (SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE), - 4, - { - SDL_PIXELFORMAT_ARGB8888, - SDL_PIXELFORMAT_ABGR8888, - SDL_PIXELFORMAT_RGB888, - SDL_PIXELFORMAT_BGR888 - }, - 0, - 0} + { "opengl", + (SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE), + 4, + { SDL_PIXELFORMAT_ARGB8888, + SDL_PIXELFORMAT_ABGR8888, + SDL_PIXELFORMAT_RGB888, + SDL_PIXELFORMAT_BGR888 }, + 0, + 0 } }; - -#endif /* SDL_VIDEO_RENDER_OGL && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_OGL */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/render/opengl/SDL_shaders_gl.c b/SDL2-2.30.5/src/render/opengl/SDL_shaders_gl.c similarity index 79% rename from SDL2-2.0.12/src/render/opengl/SDL_shaders_gl.c rename to SDL2-2.30.5/src/render/opengl/SDL_shaders_gl.c index ef75824..e24a36a 100644 --- a/SDL2-2.0.12/src/render/opengl/SDL_shaders_gl.c +++ b/SDL2-2.30.5/src/render/opengl/SDL_shaders_gl.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,10 +20,9 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_RENDER_OGL && !SDL_RENDER_DISABLED +#if SDL_VIDEO_RENDER_OGL #include "SDL_stdinc.h" -#include "SDL_log.h" #include "SDL_opengl.h" #include "SDL_video.h" #include "SDL_shaders_gl.h" @@ -62,6 +61,8 @@ struct GL_ShaderContext GL_ShaderData shaders[NUM_SHADERS]; }; +/* *INDENT-OFF* */ /* clang-format off */ + #define COLOR_VERTEX_SHADER \ "varying vec4 v_color;\n" \ "\n" \ @@ -150,7 +151,7 @@ struct GL_ShaderContext "uniform sampler2D tex1; // U/V \n" \ "\n" \ -#define NV12_SHADER_BODY \ +#define NV12_RA_SHADER_BODY \ "\n" \ "void main()\n" \ "{\n" \ @@ -175,6 +176,31 @@ struct GL_ShaderContext " gl_FragColor = vec4(rgb, 1.0) * v_color;\n" \ "}" \ +#define NV12_RG_SHADER_BODY \ +"\n" \ +"void main()\n" \ +"{\n" \ +" vec2 tcoord;\n" \ +" vec3 yuv, rgb;\n" \ +"\n" \ +" // Get the Y value \n" \ +" tcoord = v_texCoord;\n" \ +" yuv.x = texture2D(tex0, tcoord).r;\n" \ +"\n" \ +" // Get the U and V values \n" \ +" tcoord *= UVCoordScale;\n" \ +" yuv.yz = texture2D(tex1, tcoord).rg;\n" \ +"\n" \ +" // Do the color transform \n" \ +" yuv += offset;\n" \ +" rgb.r = dot(yuv, Rcoeff);\n" \ +" rgb.g = dot(yuv, Gcoeff);\n" \ +" rgb.b = dot(yuv, Bcoeff);\n" \ +"\n" \ +" // That was easy. :) \n" \ +" gl_FragColor = vec4(rgb, 1.0) * v_color;\n" \ +"}" \ + #define NV21_SHADER_PROLOGUE \ "varying vec4 v_color;\n" \ "varying vec2 v_texCoord;\n" \ @@ -211,8 +237,7 @@ struct GL_ShaderContext * NOTE: Always use sampler2D, etc here. We'll #define them to the * texture_rectangle versions if we choose to use that extension. */ -static const char *shader_source[NUM_SHADERS][2] = -{ +static const char *shader_source[NUM_SHADERS][2] = { /* SHADER_NONE */ { NULL, NULL }, @@ -260,7 +285,7 @@ static const char *shader_source[NUM_SHADERS][2] = " gl_FragColor = texture2D(tex0, v_texCoord) * v_color;\n" "}" }, - +#if SDL_HAVE_YUV /* SHADER_YUV_JPEG */ { /* vertex shader */ @@ -295,25 +320,43 @@ static const char *shader_source[NUM_SHADERS][2] = /* fragment shader */ NV12_SHADER_PROLOGUE JPEG_SHADER_CONSTANTS - NV12_SHADER_BODY + NV12_RA_SHADER_BODY }, - /* SHADER_NV12_BT601 */ + /* SHADER_NV12_RA_BT601 */ { /* vertex shader */ TEXTURE_VERTEX_SHADER, /* fragment shader */ NV12_SHADER_PROLOGUE BT601_SHADER_CONSTANTS - NV12_SHADER_BODY + NV12_RA_SHADER_BODY }, - /* SHADER_NV12_BT709 */ + /* SHADER_NV12_RG_BT601 */ + { + /* vertex shader */ + TEXTURE_VERTEX_SHADER, + /* fragment shader */ + NV12_SHADER_PROLOGUE + BT601_SHADER_CONSTANTS + NV12_RG_SHADER_BODY + }, + /* SHADER_NV12_RA_BT709 */ { /* vertex shader */ TEXTURE_VERTEX_SHADER, /* fragment shader */ NV12_SHADER_PROLOGUE BT709_SHADER_CONSTANTS - NV12_SHADER_BODY + NV12_RA_SHADER_BODY + }, + /* SHADER_NV12_RG_BT709 */ + { + /* vertex shader */ + TEXTURE_VERTEX_SHADER, + /* fragment shader */ + NV12_SHADER_PROLOGUE + BT709_SHADER_CONSTANTS + NV12_RG_SHADER_BODY }, /* SHADER_NV21_JPEG */ { @@ -342,10 +385,12 @@ static const char *shader_source[NUM_SHADERS][2] = BT709_SHADER_CONSTANTS NV21_SHADER_BODY }, +#endif /* SDL_HAVE_YUV */ }; -static SDL_bool -CompileShader(GL_ShaderContext *ctx, GLhandleARB shader, const char *defines, const char *source) +/* *INDENT-ON* */ /* clang-format on */ + +static SDL_bool CompileShader(GL_ShaderContext *ctx, GLhandleARB shader, const char *defines, const char *source) { GLint status; const char *sources[2]; @@ -362,13 +407,13 @@ CompileShader(GL_ShaderContext *ctx, GLhandleARB shader, const char *defines, co char *info; ctx->glGetObjectParameterivARB(shader, GL_OBJECT_INFO_LOG_LENGTH_ARB, &length); - info = SDL_small_alloc(char, length+1, &isstack); + info = SDL_small_alloc(char, length + 1, &isstack); ctx->glGetInfoLogARB(shader, length, NULL, info); SDL_LogError(SDL_LOG_CATEGORY_RENDER, - "Failed to compile shader:\n%s%s\n%s", defines, source, info); + "Failed to compile shader:\n%s%s\n%s", defines, source, info); #ifdef DEBUG_SHADERS fprintf(stderr, - "Failed to compile shader:\n%s%s\n%s", defines, source, info); + "Failed to compile shader:\n%s%s\n%s", defines, source, info); #endif SDL_small_free(info, isstack); @@ -378,8 +423,7 @@ CompileShader(GL_ShaderContext *ctx, GLhandleARB shader, const char *defines, co } } -static SDL_bool -CompileShaderProgram(GL_ShaderContext *ctx, int index, GL_ShaderData *data) +static SDL_bool CompileShaderProgram(GL_ShaderContext *ctx, int index, GL_ShaderData *data) { const int num_tmus_bound = 4; const char *vert_defines = ""; @@ -396,12 +440,12 @@ CompileShaderProgram(GL_ShaderContext *ctx, int index, GL_ShaderData *data) /* Make sure we use the correct sampler type for our texture type */ if (ctx->GL_ARB_texture_rectangle_supported) { frag_defines = -"#define sampler2D sampler2DRect\n" -"#define texture2D texture2DRect\n" -"#define UVCoordScale 0.5\n"; + "#define sampler2D sampler2DRect\n" + "#define texture2D texture2DRect\n" + "#define UVCoordScale 0.5\n"; } else { - frag_defines = -"#define UVCoordScale 1.0\n"; + frag_defines = + "#define UVCoordScale 1.0\n"; } /* Create one program object to rule them all */ @@ -428,7 +472,7 @@ CompileShaderProgram(GL_ShaderContext *ctx, int index, GL_ShaderData *data) ctx->glUseProgramObjectARB(data->program); for (i = 0; i < num_tmus_bound; ++i) { char tex_name[10]; - SDL_snprintf(tex_name, SDL_arraysize(tex_name), "tex%d", i); + (void)SDL_snprintf(tex_name, SDL_arraysize(tex_name), "tex%d", i); location = ctx->glGetUniformLocationARB(data->program, tex_name); if (location >= 0) { ctx->glUniform1iARB(location, i); @@ -436,19 +480,17 @@ CompileShaderProgram(GL_ShaderContext *ctx, int index, GL_ShaderData *data) } ctx->glUseProgramObjectARB(0); - return (ctx->glGetError() == GL_NO_ERROR); + return ctx->glGetError() == GL_NO_ERROR; } -static void -DestroyShaderProgram(GL_ShaderContext *ctx, GL_ShaderData *data) +static void DestroyShaderProgram(GL_ShaderContext *ctx, GL_ShaderData *data) { ctx->glDeleteObjectARB(data->vert_shader); ctx->glDeleteObjectARB(data->frag_shader); ctx->glDeleteObjectARB(data->program); } -GL_ShaderContext * -GL_CreateShaderContext(void) +GL_ShaderContext *GL_CreateShaderContext(void) { GL_ShaderContext *ctx; SDL_bool shaders_supported; @@ -471,20 +513,20 @@ GL_CreateShaderContext(void) SDL_GL_ExtensionSupported("GL_ARB_shading_language_100") && SDL_GL_ExtensionSupported("GL_ARB_vertex_shader") && SDL_GL_ExtensionSupported("GL_ARB_fragment_shader")) { - ctx->glGetError = (GLenum (*)(void)) SDL_GL_GetProcAddress("glGetError"); - ctx->glAttachObjectARB = (PFNGLATTACHOBJECTARBPROC) SDL_GL_GetProcAddress("glAttachObjectARB"); - ctx->glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC) SDL_GL_GetProcAddress("glCompileShaderARB"); - ctx->glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC) SDL_GL_GetProcAddress("glCreateProgramObjectARB"); - ctx->glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC) SDL_GL_GetProcAddress("glCreateShaderObjectARB"); - ctx->glDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC) SDL_GL_GetProcAddress("glDeleteObjectARB"); - ctx->glGetInfoLogARB = (PFNGLGETINFOLOGARBPROC) SDL_GL_GetProcAddress("glGetInfoLogARB"); - ctx->glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC) SDL_GL_GetProcAddress("glGetObjectParameterivARB"); - ctx->glGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC) SDL_GL_GetProcAddress("glGetUniformLocationARB"); - ctx->glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC) SDL_GL_GetProcAddress("glLinkProgramARB"); - ctx->glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC) SDL_GL_GetProcAddress("glShaderSourceARB"); - ctx->glUniform1iARB = (PFNGLUNIFORM1IARBPROC) SDL_GL_GetProcAddress("glUniform1iARB"); - ctx->glUniform1fARB = (PFNGLUNIFORM1FARBPROC) SDL_GL_GetProcAddress("glUniform1fARB"); - ctx->glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC) SDL_GL_GetProcAddress("glUseProgramObjectARB"); + ctx->glGetError = (GLenum(*)(void))SDL_GL_GetProcAddress("glGetError"); + ctx->glAttachObjectARB = (PFNGLATTACHOBJECTARBPROC)SDL_GL_GetProcAddress("glAttachObjectARB"); + ctx->glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC)SDL_GL_GetProcAddress("glCompileShaderARB"); + ctx->glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC)SDL_GL_GetProcAddress("glCreateProgramObjectARB"); + ctx->glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC)SDL_GL_GetProcAddress("glCreateShaderObjectARB"); + ctx->glDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC)SDL_GL_GetProcAddress("glDeleteObjectARB"); + ctx->glGetInfoLogARB = (PFNGLGETINFOLOGARBPROC)SDL_GL_GetProcAddress("glGetInfoLogARB"); + ctx->glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC)SDL_GL_GetProcAddress("glGetObjectParameterivARB"); + ctx->glGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC)SDL_GL_GetProcAddress("glGetUniformLocationARB"); + ctx->glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC)SDL_GL_GetProcAddress("glLinkProgramARB"); + ctx->glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC)SDL_GL_GetProcAddress("glShaderSourceARB"); + ctx->glUniform1iARB = (PFNGLUNIFORM1IARBPROC)SDL_GL_GetProcAddress("glUniform1iARB"); + ctx->glUniform1fARB = (PFNGLUNIFORM1FARBPROC)SDL_GL_GetProcAddress("glUniform1fARB"); + ctx->glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC)SDL_GL_GetProcAddress("glUseProgramObjectARB"); if (ctx->glGetError && ctx->glAttachObjectARB && ctx->glCompileShaderARB && @@ -520,14 +562,12 @@ GL_CreateShaderContext(void) return ctx; } -void -GL_SelectShader(GL_ShaderContext *ctx, GL_Shader shader) +void GL_SelectShader(GL_ShaderContext *ctx, GL_Shader shader) { ctx->glUseProgramObjectARB(ctx->shaders[shader].program); } -void -GL_DestroyShaderContext(GL_ShaderContext *ctx) +void GL_DestroyShaderContext(GL_ShaderContext *ctx) { int i; @@ -537,6 +577,6 @@ GL_DestroyShaderContext(GL_ShaderContext *ctx) SDL_free(ctx); } -#endif /* SDL_VIDEO_RENDER_OGL && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_OGL */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/render/opengl/SDL_shaders_gl.h b/SDL2-2.30.5/src/render/opengl/SDL_shaders_gl.h similarity index 85% rename from SDL2-2.0.12/src/render/opengl/SDL_shaders_gl.h rename to SDL2-2.30.5/src/render/opengl/SDL_shaders_gl.h index 71d864c..d237b3e 100644 --- a/SDL2-2.0.12/src/render/opengl/SDL_shaders_gl.h +++ b/SDL2-2.30.5/src/render/opengl/SDL_shaders_gl.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,27 +26,32 @@ /* OpenGL shader implementation */ -typedef enum { +typedef enum +{ SHADER_INVALID = -1, SHADER_NONE, SHADER_SOLID, SHADER_RGB, SHADER_RGBA, +#if SDL_HAVE_YUV SHADER_YUV_JPEG, SHADER_YUV_BT601, SHADER_YUV_BT709, SHADER_NV12_JPEG, - SHADER_NV12_BT601, - SHADER_NV12_BT709, + SHADER_NV12_RA_BT601, + SHADER_NV12_RG_BT601, + SHADER_NV12_RA_BT709, + SHADER_NV12_RG_BT709, SHADER_NV21_JPEG, SHADER_NV21_BT601, SHADER_NV21_BT709, +#endif NUM_SHADERS } GL_Shader; typedef struct GL_ShaderContext GL_ShaderContext; -extern GL_ShaderContext * GL_CreateShaderContext(void); +extern GL_ShaderContext *GL_CreateShaderContext(void); extern void GL_SelectShader(GL_ShaderContext *ctx, GL_Shader shader); extern void GL_DestroyShaderContext(GL_ShaderContext *ctx); diff --git a/SDL2-2.0.12/src/render/opengles/SDL_glesfuncs.h b/SDL2-2.30.5/src/render/opengles/SDL_glesfuncs.h similarity index 91% rename from SDL2-2.0.12/src/render/opengles/SDL_glesfuncs.h rename to SDL2-2.30.5/src/render/opengles/SDL_glesfuncs.h index e1d54bd..971b445 100644 --- a/SDL2-2.0.12/src/render/opengles/SDL_glesfuncs.h +++ b/SDL2-2.30.5/src/render/opengles/SDL_glesfuncs.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -27,6 +27,7 @@ SDL_PROC_OES(void, glBlendFuncSeparateOES, (GLenum, GLenum, GLenum, GLenum)) SDL_PROC(void, glClear, (GLbitfield)) SDL_PROC(void, glClearColor, (GLclampf, GLclampf, GLclampf, GLclampf)) SDL_PROC(void, glColor4f, (GLfloat, GLfloat, GLfloat, GLfloat)) +SDL_PROC(void, glColorPointer, (GLint, GLenum, GLsizei, const GLvoid *)) SDL_PROC(void, glDeleteTextures, (GLsizei, const GLuint *)) SDL_PROC(void, glDisable, (GLenum)) SDL_PROC(void, glDisableClientState, (GLenum array)) @@ -43,7 +44,7 @@ SDL_PROC(void, glLoadIdentity, (void)) SDL_PROC(void, glMatrixMode, (GLenum)) SDL_PROC(void, glOrthof, (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)) SDL_PROC(void, glPixelStorei, (GLenum, GLint)) -SDL_PROC(void, glReadPixels, (GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, GLvoid*)) +SDL_PROC(void, glReadPixels, (GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, GLvoid *)) SDL_PROC(void, glScissor, (GLint, GLint, GLsizei, GLsizei)) SDL_PROC(void, glTexCoordPointer, (GLint, GLenum, GLsizei, const GLvoid *)) SDL_PROC(void, glTexEnvf, (GLenum, GLenum, GLfloat)) @@ -56,10 +57,6 @@ SDL_PROC(void, glViewport, (GLint, GLint, GLsizei, GLsizei)) SDL_PROC_OES(void, glBindFramebufferOES, (GLenum, GLuint)) SDL_PROC_OES(void, glFramebufferTexture2DOES, (GLenum, GLenum, GLenum, GLuint, GLint)) SDL_PROC_OES(GLenum, glCheckFramebufferStatusOES, (GLenum)) -SDL_PROC(void, glPushMatrix, (void)) -SDL_PROC(void, glTranslatef, (GLfloat, GLfloat, GLfloat)) -SDL_PROC(void, glRotatef, (GLfloat, GLfloat, GLfloat, GLfloat)) -SDL_PROC(void, glPopMatrix, (void)) -SDL_PROC_OES(void, glDeleteFramebuffersOES, (GLsizei, const GLuint*)) +SDL_PROC_OES(void, glDeleteFramebuffersOES, (GLsizei, const GLuint *)) /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/render/opengles/SDL_render_gles.c b/SDL2-2.30.5/src/render/opengles/SDL_render_gles.c similarity index 59% rename from SDL2-2.0.12/src/render/opengles/SDL_render_gles.c rename to SDL2-2.30.5/src/render/opengles/SDL_render_gles.c index 044a1be..9906b46 100644 --- a/SDL2-2.0.12/src/render/opengles/SDL_render_gles.c +++ b/SDL2-2.30.5/src/render/opengles/SDL_render_gles.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,12 +20,13 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_RENDER_OGL_ES && !SDL_RENDER_DISABLED +#if SDL_VIDEO_RENDER_OGL_ES -#include "SDL_assert.h" #include "SDL_hints.h" +#include "../../video/SDL_sysvideo.h" /* For SDL_GL_SwapWindowWithResult */ #include "SDL_opengles.h" #include "../SDL_sysrender.h" +#include "../../SDL_utils_c.h" /* To prevent unnecessary window recreation, * these should match the defaults selected in SDL_GL_ResetAttributes @@ -49,7 +50,7 @@ glDrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height) /* OpenGL ES 1.1 renderer implementation, based on the OpenGL renderer */ /* Used to re-create the window with OpenGL ES capability */ -extern int SDL_RecreateWindow(SDL_Window * window, Uint32 flags); +extern int SDL_RecreateWindow(SDL_Window *window, Uint32 flags); static const float inv255f = 1.0f / 255.0f; @@ -57,9 +58,9 @@ typedef struct GLES_FBOList GLES_FBOList; struct GLES_FBOList { - Uint32 w, h; - GLuint FBO; - GLES_FBOList *next; + Uint32 w, h; + GLuint FBO; + GLES_FBOList *next; }; typedef struct @@ -84,8 +85,8 @@ typedef struct { SDL_GLContext context; -#define SDL_PROC(ret,func,params) ret (APIENTRY *func) params; -#define SDL_PROC_OES SDL_PROC +#define SDL_PROC(ret, func, params) ret (APIENTRY *func) params; +#define SDL_PROC_OES SDL_PROC #include "SDL_glesfuncs.h" #undef SDL_PROC #undef SDL_PROC_OES @@ -96,6 +97,7 @@ typedef struct SDL_bool GL_OES_blend_func_separate_supported; SDL_bool GL_OES_blend_equation_separate_supported; SDL_bool GL_OES_blend_subtract_supported; + SDL_bool GL_EXT_blend_minmax_supported; GLES_DrawStateCache drawstate; } GLES_RenderData; @@ -113,8 +115,7 @@ typedef struct GLES_FBOList *fbo; } GLES_TextureData; -static int -GLES_SetError(const char *prefix, GLenum result) +static int GLES_SetError(const char *prefix, GLenum result) { const char *error; @@ -147,31 +148,31 @@ GLES_SetError(const char *prefix, GLenum result) return SDL_SetError("%s: %s", prefix, error); } -static int GLES_LoadFunctions(GLES_RenderData * data) +static int GLES_LoadFunctions(GLES_RenderData *data) { -#if SDL_VIDEO_DRIVER_UIKIT +#ifdef SDL_VIDEO_DRIVER_UIKIT #define __SDL_NOGETPROCADDR__ -#elif SDL_VIDEO_DRIVER_ANDROID +#elif defined(SDL_VIDEO_DRIVER_ANDROID) #define __SDL_NOGETPROCADDR__ -#elif SDL_VIDEO_DRIVER_PANDORA +#elif defined(SDL_VIDEO_DRIVER_PANDORA) #define __SDL_NOGETPROCADDR__ #endif #ifdef __SDL_NOGETPROCADDR__ -#define SDL_PROC(ret,func,params) data->func=func; -#define SDL_PROC_OES(ret,func,params) data->func=func; +#define SDL_PROC(ret, func, params) data->func = func; +#define SDL_PROC_OES(ret, func, params) data->func = func; #else -#define SDL_PROC(ret,func,params) \ - do { \ - data->func = SDL_GL_GetProcAddress(#func); \ - if ( ! data->func ) { \ +#define SDL_PROC(ret, func, params) \ + do { \ + data->func = SDL_GL_GetProcAddress(#func); \ + if (!data->func) { \ return SDL_SetError("Couldn't load GLES function %s: %s", #func, SDL_GetError()); \ - } \ - } while ( 0 ); -#define SDL_PROC_OES(ret,func,params) \ - do { \ + } \ + } while (0); +#define SDL_PROC_OES(ret, func, params) \ + do { \ data->func = SDL_GL_GetProcAddress(#func); \ - } while ( 0 ); + } while (0); #endif /* __SDL_NOGETPROCADDR__ */ #include "SDL_glesfuncs.h" @@ -180,29 +181,26 @@ static int GLES_LoadFunctions(GLES_RenderData * data) return 0; } -static GLES_FBOList * -GLES_GetFBO(GLES_RenderData *data, Uint32 w, Uint32 h) +static GLES_FBOList *GLES_GetFBO(GLES_RenderData *data, Uint32 w, Uint32 h) { - GLES_FBOList *result = data->framebuffers; - while ((result) && ((result->w != w) || (result->h != h)) ) { - result = result->next; - } - if (result == NULL) { - result = SDL_malloc(sizeof(GLES_FBOList)); - result->w = w; - result->h = h; - data->glGenFramebuffersOES(1, &result->FBO); - result->next = data->framebuffers; - data->framebuffers = result; - } - return result; + GLES_FBOList *result = data->framebuffers; + while ((result) && ((result->w != w) || (result->h != h))) { + result = result->next; + } + if (!result) { + result = SDL_malloc(sizeof(GLES_FBOList)); + result->w = w; + result->h = h; + data->glGenFramebuffersOES(1, &result->FBO); + result->next = data->framebuffers; + data->framebuffers = result; + } + return result; } - -static int -GLES_ActivateRenderer(SDL_Renderer * renderer) +static int GLES_ActivateRenderer(SDL_Renderer *renderer) { - GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata; + GLES_RenderData *data = (GLES_RenderData *)renderer->driverdata; if (SDL_GL_GetCurrentContext() != data->context) { if (SDL_GL_MakeCurrent(renderer->window, data->context) < 0) { @@ -213,10 +211,9 @@ GLES_ActivateRenderer(SDL_Renderer * renderer) return 0; } -static void -GLES_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event) +static void GLES_WindowEvent(SDL_Renderer *renderer, const SDL_WindowEvent *event) { - GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata; + GLES_RenderData *data = (GLES_RenderData *)renderer->driverdata; if (event->event == SDL_WINDOWEVENT_MINIMIZED) { /* According to Apple documentation, we need to finish drawing NOW! */ @@ -224,8 +221,7 @@ GLES_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event) } } -static int -GLES_GetOutputSize(SDL_Renderer * renderer, int *w, int *h) +static int GLES_GetOutputSize(SDL_Renderer *renderer, int *w, int *h) { SDL_GL_GetDrawableSize(renderer->window, w, h); return 0; @@ -268,15 +264,18 @@ static GLenum GetBlendEquation(SDL_BlendOperation operation) return GL_FUNC_SUBTRACT_OES; case SDL_BLENDOPERATION_REV_SUBTRACT: return GL_FUNC_REVERSE_SUBTRACT_OES; + case SDL_BLENDOPERATION_MINIMUM: + return GL_MIN_EXT; + case SDL_BLENDOPERATION_MAXIMUM: + return GL_MAX_EXT; default: return GL_INVALID_ENUM; } } -static SDL_bool -GLES_SupportsBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode) +static SDL_bool GLES_SupportsBlendMode(SDL_Renderer *renderer, SDL_BlendMode blendMode) { - GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata; + GLES_RenderData *data = (GLES_RenderData *)renderer->driverdata; SDL_BlendFactor srcColorFactor = SDL_GetBlendModeSrcColorFactor(blendMode); SDL_BlendFactor srcAlphaFactor = SDL_GetBlendModeSrcAlphaFactor(blendMode); SDL_BlendOperation colorOperation = SDL_GetBlendModeColorOperation(blendMode); @@ -301,24 +300,18 @@ GLES_SupportsBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode) if (colorOperation != SDL_BLENDOPERATION_ADD && !data->GL_OES_blend_subtract_supported) { return SDL_FALSE; } + if (colorOperation == SDL_BLENDOPERATION_MINIMUM && !data->GL_EXT_blend_minmax_supported) { + return SDL_FALSE; + } + if (colorOperation == SDL_BLENDOPERATION_MAXIMUM && !data->GL_EXT_blend_minmax_supported) { + return SDL_FALSE; + } return SDL_TRUE; } -static SDL_INLINE int -power_of_2(int input) +static int GLES_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) { - int value = 1; - - while (value < input) { - value <<= 1; - } - return value; -} - -static int -GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) -{ - GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata; + GLES_RenderData *renderdata = (GLES_RenderData *)renderer->driverdata; GLES_TextureData *data; GLint internalFormat; GLenum format, type; @@ -329,7 +322,7 @@ GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) GLES_ActivateRenderer(renderer); switch (texture->format) { - case SDL_PIXELFORMAT_ABGR8888: + case SDL_PIXELFORMAT_RGBA32: internalFormat = GL_RGBA; format = GL_RGBA; type = GL_UNSIGNED_BYTE; @@ -338,7 +331,7 @@ GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) return SDL_SetError("Texture format not supported"); } - data = (GLES_TextureData *) SDL_calloc(1, sizeof(*data)); + data = (GLES_TextureData *)SDL_calloc(1, sizeof(*data)); if (!data) { return SDL_OutOfMemory(); } @@ -352,7 +345,6 @@ GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) } } - if (texture->access == SDL_TEXTUREACCESS_TARGET) { if (!renderdata->GL_OES_framebuffer_object_supported) { SDL_free(data); @@ -363,22 +355,24 @@ GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) data->fbo = NULL; } - renderdata->glGetError(); renderdata->glEnable(GL_TEXTURE_2D); renderdata->glGenTextures(1, &data->texture); result = renderdata->glGetError(); if (result != GL_NO_ERROR) { + if (texture->access == SDL_TEXTUREACCESS_STREAMING) { + SDL_free(data->pixels); + } SDL_free(data); return GLES_SetError("glGenTextures()", result); } data->type = GL_TEXTURE_2D; /* no NPOV textures allowed in OpenGL ES (yet) */ - texture_w = power_of_2(texture->w); - texture_h = power_of_2(texture->h); - data->texw = (GLfloat) texture->w / texture_w; - data->texh = (GLfloat) texture->h / texture_h; + texture_w = SDL_powerof2(texture->w); + texture_h = SDL_powerof2(texture->h); + data->texw = (GLfloat)texture->w / texture_w; + data->texh = (GLfloat)texture->h / texture_h; data->format = format; data->formattype = type; @@ -397,6 +391,9 @@ GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) result = renderdata->glGetError(); if (result != GL_NO_ERROR) { + if (texture->access == SDL_TEXTUREACCESS_STREAMING) { + SDL_free(data->pixels); + } SDL_free(data); return GLES_SetError("glTexImage2D()", result); } @@ -405,12 +402,11 @@ GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) return 0; } -static int -GLES_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * rect, const void *pixels, int pitch) +static int GLES_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *rect, const void *pixels, int pitch) { - GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata; - GLES_TextureData *data = (GLES_TextureData *) texture->driverdata; + GLES_RenderData *renderdata = (GLES_RenderData *)renderer->driverdata; + GLES_TextureData *data = (GLES_TextureData *)texture->driverdata; Uint8 *blob = NULL; Uint8 *src; int srcPitch; @@ -446,14 +442,14 @@ GLES_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, renderdata->glBindTexture(data->type, data->texture); renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1); renderdata->glTexSubImage2D(data->type, - 0, - rect->x, - rect->y, - rect->w, - rect->h, - data->format, - data->formattype, - src); + 0, + rect->x, + rect->y, + rect->w, + rect->h, + data->format, + data->formattype, + src); renderdata->glDisable(data->type); SDL_free(blob); @@ -466,23 +462,21 @@ GLES_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, return 0; } -static int -GLES_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * rect, void **pixels, int *pitch) +static int GLES_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *rect, void **pixels, int *pitch) { - GLES_TextureData *data = (GLES_TextureData *) texture->driverdata; + GLES_TextureData *data = (GLES_TextureData *)texture->driverdata; *pixels = - (void *) ((Uint8 *) data->pixels + rect->y * data->pitch + - rect->x * SDL_BYTESPERPIXEL(texture->format)); + (void *)((Uint8 *)data->pixels + rect->y * data->pitch + + rect->x * SDL_BYTESPERPIXEL(texture->format)); *pitch = data->pitch; return 0; } -static void -GLES_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) +static void GLES_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture) { - GLES_TextureData *data = (GLES_TextureData *) texture->driverdata; + GLES_TextureData *data = (GLES_TextureData *)texture->driverdata; SDL_Rect rect; /* We do whole texture updates, at least for now */ @@ -493,11 +487,10 @@ GLES_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) GLES_UpdateTexture(renderer, texture, &rect, data->pixels, data->pitch); } -static void -GLES_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture, SDL_ScaleMode scaleMode) +static void GLES_SetTextureScaleMode(SDL_Renderer *renderer, SDL_Texture *texture, SDL_ScaleMode scaleMode) { - GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata; - GLES_TextureData *data = (GLES_TextureData *) texture->driverdata; + GLES_RenderData *renderdata = (GLES_RenderData *)renderer->driverdata; + GLES_TextureData *data = (GLES_TextureData *)texture->driverdata; GLenum glScaleMode = (scaleMode == SDL_ScaleModeNearest) ? GL_NEAREST : GL_LINEAR; renderdata->glBindTexture(data->type, data->texture); @@ -505,10 +498,9 @@ GLES_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture, SDL_Sca renderdata->glTexParameteri(data->type, GL_TEXTURE_MAG_FILTER, glScaleMode); } -static int -GLES_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture) +static int GLES_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture) { - GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata; + GLES_RenderData *data = (GLES_RenderData *)renderer->driverdata; GLES_TextureData *texturedata = NULL; GLenum status; @@ -518,12 +510,12 @@ GLES_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture) data->drawstate.viewport_dirty = SDL_TRUE; - if (texture == NULL) { + if (!texture) { data->glBindFramebufferOES(GL_FRAMEBUFFER_OES, data->window_framebuffer); return 0; } - texturedata = (GLES_TextureData *) texture->driverdata; + texturedata = (GLES_TextureData *)texture->driverdata; data->glBindFramebufferOES(GL_FRAMEBUFFER_OES, texturedata->fbo->FBO); /* TODO: check if texture pixel format allows this operation */ data->glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, texturedata->type, texturedata->texture, 0); @@ -535,17 +527,14 @@ GLES_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture) return 0; } - -static int -GLES_QueueSetViewport(SDL_Renderer * renderer, SDL_RenderCommand *cmd) +static int GLES_QueueSetViewport(SDL_Renderer *renderer, SDL_RenderCommand *cmd) { - return 0; /* nothing to do in this backend. */ + return 0; /* nothing to do in this backend. */ } -static int -GLES_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count) +static int GLES_QueueDrawPoints(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count) { - GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, count * 2 * sizeof (GLfloat), 0, &cmd->data.draw.first); + GLfloat *verts = (GLfloat *)SDL_AllocateRenderVertices(renderer, count * 2 * sizeof(GLfloat), 0, &cmd->data.draw.first); int i; if (!verts) { @@ -561,174 +550,117 @@ GLES_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_ return 0; } -static int -GLES_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRect * rects, int count) +static int GLES_QueueDrawLines(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count) { - GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, count * 8 * sizeof (GLfloat), 0, &cmd->data.draw.first); int i; + GLfloat prevx, prevy; + const size_t vertlen = (sizeof(GLfloat) * 2) * count; + GLfloat *verts = (GLfloat *)SDL_AllocateRenderVertices(renderer, vertlen, 0, &cmd->data.draw.first); if (!verts) { return -1; } + cmd->data.draw.count = count; + + /* 0.5f offset to hit the center of the pixel. */ + prevx = 0.5f + points->x; + prevy = 0.5f + points->y; + *(verts++) = prevx; + *(verts++) = prevy; + + /* bump the end of each line segment out a quarter of a pixel, to provoke + the diamond-exit rule. Without this, you won't just drop the last + pixel of the last line segment, but you might also drop pixels at the + edge of any given line segment along the way too. */ + for (i = 1; i < count; i++) { + const GLfloat xstart = prevx; + const GLfloat ystart = prevy; + const GLfloat xend = points[i].x + 0.5f; /* 0.5f to hit pixel center. */ + const GLfloat yend = points[i].y + 0.5f; + /* bump a little in the direction we are moving in. */ + const GLfloat deltax = xend - xstart; + const GLfloat deltay = yend - ystart; + const GLfloat angle = SDL_atan2f(deltay, deltax); + prevx = xend + (SDL_cosf(angle) * 0.25f); + prevy = yend + (SDL_sinf(angle) * 0.25f); + *(verts++) = prevx; + *(verts++) = prevy; + } + + return 0; +} + +static int GLES_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, + const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride, + int num_vertices, const void *indices, int num_indices, int size_indices, + float scale_x, float scale_y) +{ + GLES_TextureData *texturedata = NULL; + int i; + int count = indices ? num_indices : num_vertices; + GLfloat *verts; + int sz = 2 + 4 + (texture ? 2 : 0); + + verts = (GLfloat *)SDL_AllocateRenderVertices(renderer, count * sz * sizeof(GLfloat), 0, &cmd->data.draw.first); + if (!verts) { + return -1; + } + + if (texture) { + texturedata = (GLES_TextureData *)texture->driverdata; + } cmd->data.draw.count = count; + size_indices = indices ? size_indices : 0; for (i = 0; i < count; i++) { - const SDL_FRect *rect = &rects[i]; - const GLfloat minx = rect->x; - const GLfloat maxx = rect->x + rect->w; - const GLfloat miny = rect->y; - const GLfloat maxy = rect->y + rect->h; - *(verts++) = minx; - *(verts++) = miny; - *(verts++) = maxx; - *(verts++) = miny; - *(verts++) = minx; - *(verts++) = maxy; - *(verts++) = maxx; - *(verts++) = maxy; - } + int j; + float *xy_; + SDL_Color col_; + if (size_indices == 4) { + j = ((const Uint32 *)indices)[i]; + } else if (size_indices == 2) { + j = ((const Uint16 *)indices)[i]; + } else if (size_indices == 1) { + j = ((const Uint8 *)indices)[i]; + } else { + j = i; + } + xy_ = (float *)((char *)xy + j * xy_stride); + col_ = *(SDL_Color *)((char *)color + j * color_stride); + + *(verts++) = xy_[0] * scale_x; + *(verts++) = xy_[1] * scale_y; + + *(verts++) = col_.r * inv255f; + *(verts++) = col_.g * inv255f; + *(verts++) = col_.b * inv255f; + *(verts++) = col_.a * inv255f; + + if (texture) { + float *uv_ = (float *)((char *)uv + j * uv_stride); + *(verts++) = uv_[0] * texturedata->texw; + *(verts++) = uv_[1] * texturedata->texh; + } + } return 0; } -static int -GLES_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_FRect * dstrect) -{ - GLES_TextureData *texturedata = (GLES_TextureData *) texture->driverdata; - GLfloat minx, miny, maxx, maxy; - GLfloat minu, maxu, minv, maxv; - GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, 16 * sizeof (GLfloat), 0, &cmd->data.draw.first); - - if (!verts) { - return -1; - } - - cmd->data.draw.count = 1; - - minx = dstrect->x; - miny = dstrect->y; - maxx = dstrect->x + dstrect->w; - maxy = dstrect->y + dstrect->h; - - minu = (GLfloat) srcrect->x / texture->w; - minu *= texturedata->texw; - maxu = (GLfloat) (srcrect->x + srcrect->w) / texture->w; - maxu *= texturedata->texw; - minv = (GLfloat) srcrect->y / texture->h; - minv *= texturedata->texh; - maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h; - maxv *= texturedata->texh; - - *(verts++) = minx; - *(verts++) = miny; - *(verts++) = maxx; - *(verts++) = miny; - *(verts++) = minx; - *(verts++) = maxy; - *(verts++) = maxx; - *(verts++) = maxy; - - *(verts++) = minu; - *(verts++) = minv; - *(verts++) = maxu; - *(verts++) = minv; - *(verts++) = minu; - *(verts++) = maxv; - *(verts++) = maxu; - *(verts++) = maxv; - - return 0; -} - -static int -GLES_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture, - const SDL_Rect * srcquad, const SDL_FRect * dstrect, - const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip) -{ - GLES_TextureData *texturedata = (GLES_TextureData *) texture->driverdata; - GLfloat minx, miny, maxx, maxy; - GLfloat centerx, centery; - GLfloat minu, maxu, minv, maxv; - GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, 19 * sizeof (GLfloat), 0, &cmd->data.draw.first); - - if (!verts) { - return -1; - } - - centerx = center->x; - centery = center->y; - - if (flip & SDL_FLIP_HORIZONTAL) { - minx = dstrect->w - centerx; - maxx = -centerx; - } - else { - minx = -centerx; - maxx = dstrect->w - centerx; - } - - if (flip & SDL_FLIP_VERTICAL) { - miny = dstrect->h - centery; - maxy = -centery; - } - else { - miny = -centery; - maxy = dstrect->h - centery; - } - - minu = (GLfloat) srcquad->x / texture->w; - minu *= texturedata->texw; - maxu = (GLfloat) (srcquad->x + srcquad->w) / texture->w; - maxu *= texturedata->texw; - minv = (GLfloat) srcquad->y / texture->h; - minv *= texturedata->texh; - maxv = (GLfloat) (srcquad->y + srcquad->h) / texture->h; - maxv *= texturedata->texh; - - cmd->data.draw.count = 1; - - *(verts++) = minx; - *(verts++) = miny; - *(verts++) = maxx; - *(verts++) = miny; - *(verts++) = minx; - *(verts++) = maxy; - *(verts++) = maxx; - *(verts++) = maxy; - - *(verts++) = minu; - *(verts++) = minv; - *(verts++) = maxu; - *(verts++) = minv; - *(verts++) = minu; - *(verts++) = maxv; - *(verts++) = maxu; - *(verts++) = maxv; - - *(verts++) = (GLfloat) dstrect->x + centerx; - *(verts++) = (GLfloat) dstrect->y + centery; - *(verts++) = (GLfloat) angle; - - return 0; -} - -static void -SetDrawState(GLES_RenderData *data, const SDL_RenderCommand *cmd) +static void SetDrawState(GLES_RenderData *data, const SDL_RenderCommand *cmd) { const SDL_BlendMode blend = cmd->data.draw.blend; const Uint8 r = cmd->data.draw.r; const Uint8 g = cmd->data.draw.g; const Uint8 b = cmd->data.draw.b; const Uint8 a = cmd->data.draw.a; - const Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b); + const Uint32 color = (((Uint32)a << 24) | (r << 16) | (g << 8) | b); if (color != data->drawstate.color) { - const GLfloat fr = ((GLfloat) r) * inv255f; - const GLfloat fg = ((GLfloat) g) * inv255f; - const GLfloat fb = ((GLfloat) b) * inv255f; - const GLfloat fa = ((GLfloat) a) * inv255f; + const GLfloat fr = ((GLfloat)r) * inv255f; + const GLfloat fg = ((GLfloat)g) * inv255f; + const GLfloat fb = ((GLfloat)b) * inv255f; + const GLfloat fa = ((GLfloat)a) * inv255f; data->glColor4f(fr, fg, fb, fa); data->drawstate.color = color; } @@ -742,9 +674,9 @@ SetDrawState(GLES_RenderData *data, const SDL_RenderCommand *cmd) istarget ? viewport->y : (data->drawstate.drawableh - viewport->y - viewport->h), viewport->w, viewport->h); if (viewport->w && viewport->h) { - data->glOrthof((GLfloat) 0, (GLfloat) viewport->w, - (GLfloat) (istarget ? 0 : viewport->h), - (GLfloat) (istarget ? viewport->h : 0), + data->glOrthof((GLfloat)0, (GLfloat)viewport->w, + (GLfloat)(istarget ? 0 : viewport->h), + (GLfloat)(istarget ? viewport->h : 0), 0.0, 1.0); } data->glMatrixMode(GL_MODELVIEW); @@ -807,24 +739,21 @@ SetDrawState(GLES_RenderData *data, const SDL_RenderCommand *cmd) } } -static void -SetCopyState(GLES_RenderData *data, const SDL_RenderCommand *cmd) +static void SetCopyState(GLES_RenderData *data, const SDL_RenderCommand *cmd) { SDL_Texture *texture = cmd->data.draw.texture; SetDrawState(data, cmd); if (texture != data->drawstate.texture) { - GLES_TextureData *texturedata = (GLES_TextureData *) texture->driverdata; + GLES_TextureData *texturedata = (GLES_TextureData *)texture->driverdata; data->glBindTexture(GL_TEXTURE_2D, texturedata->texture); data->drawstate.texture = texture; } } -static int -GLES_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize) +static int GLES_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize) { - GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata; - size_t i; + GLES_RenderData *data = (GLES_RenderData *)renderer->driverdata; if (GLES_ActivateRenderer(renderer) < 0) { return -1; @@ -833,128 +762,132 @@ GLES_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vert data->drawstate.target = renderer->target; if (!renderer->target) { - SDL_GL_GetDrawableSize(renderer->window, &data->drawstate.drawablew, &data->drawstate.drawableh); + int w, h; + SDL_GL_GetDrawableSize(renderer->window, &w, &h); + if ((w != data->drawstate.drawablew) || (h != data->drawstate.drawableh)) { + data->drawstate.viewport_dirty = SDL_TRUE; // if the window dimensions changed, invalidate the current viewport, etc. + data->drawstate.cliprect_dirty = SDL_TRUE; + data->drawstate.drawablew = w; + data->drawstate.drawableh = h; + } } while (cmd) { switch (cmd->command) { - case SDL_RENDERCMD_SETDRAWCOLOR: { - break; /* not used in this render backend. */ + case SDL_RENDERCMD_SETDRAWCOLOR: + { + break; /* not used in this render backend. */ + } + + case SDL_RENDERCMD_SETVIEWPORT: + { + SDL_Rect *viewport = &data->drawstate.viewport; + if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof(cmd->data.viewport.rect)) != 0) { + SDL_copyp(viewport, &cmd->data.viewport.rect); + data->drawstate.viewport_dirty = SDL_TRUE; + } + break; + } + + case SDL_RENDERCMD_SETCLIPRECT: + { + const SDL_Rect *rect = &cmd->data.cliprect.rect; + if (data->drawstate.cliprect_enabled != cmd->data.cliprect.enabled) { + data->drawstate.cliprect_enabled = cmd->data.cliprect.enabled; + data->drawstate.cliprect_enabled_dirty = SDL_TRUE; + } + if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof(*rect)) != 0) { + SDL_copyp(&data->drawstate.cliprect, rect); + data->drawstate.cliprect_dirty = SDL_TRUE; + } + break; + } + + case SDL_RENDERCMD_CLEAR: + { + const Uint8 r = cmd->data.color.r; + const Uint8 g = cmd->data.color.g; + const Uint8 b = cmd->data.color.b; + const Uint8 a = cmd->data.color.a; + const Uint32 color = (((Uint32)a << 24) | (r << 16) | (g << 8) | b); + if (color != data->drawstate.clear_color) { + const GLfloat fr = ((GLfloat)r) * inv255f; + const GLfloat fg = ((GLfloat)g) * inv255f; + const GLfloat fb = ((GLfloat)b) * inv255f; + const GLfloat fa = ((GLfloat)a) * inv255f; + data->glClearColor(fr, fg, fb, fa); + data->drawstate.clear_color = color; } - case SDL_RENDERCMD_SETVIEWPORT: { - SDL_Rect *viewport = &data->drawstate.viewport; - if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect)) != 0) { - SDL_memcpy(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect)); - data->drawstate.viewport_dirty = SDL_TRUE; - } - break; + if (data->drawstate.cliprect_enabled || data->drawstate.cliprect_enabled_dirty) { + data->glDisable(GL_SCISSOR_TEST); + data->drawstate.cliprect_enabled_dirty = data->drawstate.cliprect_enabled; } - case SDL_RENDERCMD_SETCLIPRECT: { - const SDL_Rect *rect = &cmd->data.cliprect.rect; - if (data->drawstate.cliprect_enabled != cmd->data.cliprect.enabled) { - data->drawstate.cliprect_enabled = cmd->data.cliprect.enabled; - data->drawstate.cliprect_enabled_dirty = SDL_TRUE; - } - if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof (SDL_Rect)) != 0) { - SDL_memcpy(&data->drawstate.cliprect, rect, sizeof (SDL_Rect)); - data->drawstate.cliprect_dirty = SDL_TRUE; - } - break; - } + data->glClear(GL_COLOR_BUFFER_BIT); - case SDL_RENDERCMD_CLEAR: { - const Uint8 r = cmd->data.color.r; - const Uint8 g = cmd->data.color.g; - const Uint8 b = cmd->data.color.b; - const Uint8 a = cmd->data.color.a; - const Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b); - if (color != data->drawstate.clear_color) { - const GLfloat fr = ((GLfloat) r) * inv255f; - const GLfloat fg = ((GLfloat) g) * inv255f; - const GLfloat fb = ((GLfloat) b) * inv255f; - const GLfloat fa = ((GLfloat) a) * inv255f; - data->glClearColor(fr, fg, fb, fa); - data->drawstate.clear_color = color; - } + break; + } - if (data->drawstate.cliprect_enabled || data->drawstate.cliprect_enabled_dirty) { - data->glDisable(GL_SCISSOR_TEST); - data->drawstate.cliprect_enabled_dirty = data->drawstate.cliprect_enabled; - } + case SDL_RENDERCMD_DRAW_POINTS: + { + const size_t count = cmd->data.draw.count; + const GLfloat *verts = (GLfloat *)(((Uint8 *)vertices) + cmd->data.draw.first); + SetDrawState(data, cmd); + data->glVertexPointer(2, GL_FLOAT, 0, verts); + data->glDrawArrays(GL_POINTS, 0, (GLsizei)count); + break; + } - data->glClear(GL_COLOR_BUFFER_BIT); + case SDL_RENDERCMD_DRAW_LINES: + { + const GLfloat *verts = (GLfloat *)(((Uint8 *)vertices) + cmd->data.draw.first); + const size_t count = cmd->data.draw.count; + SDL_assert(count >= 2); + SetDrawState(data, cmd); + data->glVertexPointer(2, GL_FLOAT, 0, verts); + data->glDrawArrays(GL_LINE_STRIP, 0, (GLsizei)count); + break; + } - break; - } + case SDL_RENDERCMD_FILL_RECTS: /* unused */ + break; - case SDL_RENDERCMD_DRAW_POINTS: { - const size_t count = cmd->data.draw.count; - const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first); - SetDrawState(data, cmd); - data->glVertexPointer(2, GL_FLOAT, 0, verts); - data->glDrawArrays(GL_POINTS, 0, (GLsizei) count); - break; - } + case SDL_RENDERCMD_COPY: /* unused */ + break; - case SDL_RENDERCMD_DRAW_LINES: { - const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first); - const size_t count = cmd->data.draw.count; - SetDrawState(data, cmd); - data->glVertexPointer(2, GL_FLOAT, 0, verts); - if (count > 2 && (verts[0] == verts[(count-1)*2]) && (verts[1] == verts[(count*2)-1])) { - /* GL_LINE_LOOP takes care of the final segment */ - data->glDrawArrays(GL_LINE_LOOP, 0, (GLsizei) (count - 1)); - } else { - data->glDrawArrays(GL_LINE_STRIP, 0, (GLsizei) count); - /* We need to close the endpoint of the line */ - data->glDrawArrays(GL_POINTS, (GLsizei) (count - 1), 1); - } - break; - } + case SDL_RENDERCMD_COPY_EX: /* unused */ + break; - case SDL_RENDERCMD_FILL_RECTS: { - const size_t count = cmd->data.draw.count; - const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first); - GLsizei offset = 0; - SetDrawState(data, cmd); - data->glVertexPointer(2, GL_FLOAT, 0, verts); - for (i = 0; i < count; ++i, offset += 4) { - data->glDrawArrays(GL_TRIANGLE_STRIP, offset, 4); - } - break; - } + case SDL_RENDERCMD_GEOMETRY: + { + const GLfloat *verts = (GLfloat *)(((Uint8 *)vertices) + cmd->data.draw.first); + SDL_Texture *texture = cmd->data.draw.texture; + const size_t count = cmd->data.draw.count; + int stride = (2 + 4 + (texture ? 2 : 0)) * sizeof(float); - case SDL_RENDERCMD_COPY: { - const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first); + if (texture) { SetCopyState(data, cmd); - data->glVertexPointer(2, GL_FLOAT, 0, verts); - data->glTexCoordPointer(2, GL_FLOAT, 0, verts + 8); - data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - break; + } else { + SetDrawState(data, cmd); } - case SDL_RENDERCMD_COPY_EX: { - const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first); - const GLfloat translatex = verts[16]; - const GLfloat translatey = verts[17]; - const GLfloat angle = verts[18]; - SetCopyState(data, cmd); - data->glVertexPointer(2, GL_FLOAT, 0, verts); - data->glTexCoordPointer(2, GL_FLOAT, 0, verts + 8); + data->glEnableClientState(GL_COLOR_ARRAY); - /* Translate to flip, rotate, translate to position */ - data->glPushMatrix(); - data->glTranslatef(translatex, translatey, 0.0f); - data->glRotatef(angle, 0.0, 0.0, 1.0); - data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - data->glPopMatrix(); - break; + data->glVertexPointer(2, GL_FLOAT, stride, verts); + data->glColorPointer(4, GL_FLOAT, stride, verts + 2); + if (texture) { + data->glTexCoordPointer(2, GL_FLOAT, stride, verts + 2 + 4); } - case SDL_RENDERCMD_NO_OP: - break; + data->glDrawArrays(GL_TRIANGLES, 0, (GLsizei)count); + + data->glDisableClientState(GL_COLOR_ARRAY); + break; + } + + case SDL_RENDERCMD_NO_OP: + break; } cmd = cmd->next; @@ -963,12 +896,11 @@ GLES_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vert return 0; } -static int -GLES_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, - Uint32 pixel_format, void * pixels, int pitch) +static int GLES_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect, + Uint32 pixel_format, void *pixels, int pitch) { - GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata; - Uint32 temp_format = renderer->target ? renderer->target->format : SDL_PIXELFORMAT_ABGR8888; + GLES_RenderData *data = (GLES_RenderData *)renderer->driverdata; + Uint32 temp_format = renderer->target ? renderer->target->format : SDL_PIXELFORMAT_RGBA32; void *temp_pixels; int temp_pitch; Uint8 *src, *dst, *tmp; @@ -987,15 +919,15 @@ GLES_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, data->glPixelStorei(GL_PACK_ALIGNMENT, 1); - data->glReadPixels(rect->x, renderer->target ? rect->y : (h-rect->y)-rect->h, + data->glReadPixels(rect->x, renderer->target ? rect->y : (h - rect->y) - rect->h, rect->w, rect->h, GL_RGBA, GL_UNSIGNED_BYTE, temp_pixels); /* Flip the rows to be top-down if necessary */ if (!renderer->target) { SDL_bool isstack; length = rect->w * SDL_BYTESPERPIXEL(temp_format); - src = (Uint8*)temp_pixels + (rect->h-1)*temp_pitch; - dst = (Uint8*)temp_pixels; + src = (Uint8 *)temp_pixels + (rect->h - 1) * temp_pitch; + dst = (Uint8 *)temp_pixels; tmp = SDL_small_alloc(Uint8, length, &isstack); rows = rect->h / 2; while (rows--) { @@ -1016,20 +948,18 @@ GLES_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, return status; } -static void -GLES_RenderPresent(SDL_Renderer * renderer) +static int GLES_RenderPresent(SDL_Renderer *renderer) { GLES_ActivateRenderer(renderer); - SDL_GL_SwapWindow(renderer->window); + return SDL_GL_SwapWindowWithResult(renderer->window); } -static void -GLES_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) +static void GLES_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture) { - GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata; + GLES_RenderData *renderdata = (GLES_RenderData *)renderer->driverdata; - GLES_TextureData *data = (GLES_TextureData *) texture->driverdata; + GLES_TextureData *data = (GLES_TextureData *)texture->driverdata; GLES_ActivateRenderer(renderer); @@ -1051,18 +981,17 @@ GLES_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) texture->driverdata = NULL; } -static void -GLES_DestroyRenderer(SDL_Renderer * renderer) +static void GLES_DestroyRenderer(SDL_Renderer *renderer) { - GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata; + GLES_RenderData *data = (GLES_RenderData *)renderer->driverdata; if (data) { if (data->context) { while (data->framebuffers) { - GLES_FBOList *nextnode = data->framebuffers->next; - data->glDeleteFramebuffersOES(1, &data->framebuffers->FBO); - SDL_free(data->framebuffers); - data->framebuffers = nextnode; + GLES_FBOList *nextnode = data->framebuffers->next; + data->glDeleteFramebuffersOES(1, &data->framebuffers->FBO); + SDL_free(data->framebuffers); + data->framebuffers = nextnode; } SDL_GL_DeleteContext(data->context); } @@ -1071,10 +1000,10 @@ GLES_DestroyRenderer(SDL_Renderer * renderer) SDL_free(renderer); } -static int GLES_BindTexture (SDL_Renderer * renderer, SDL_Texture *texture, float *texw, float *texh) +static int GLES_BindTexture(SDL_Renderer *renderer, SDL_Texture *texture, float *texw, float *texh) { - GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata; - GLES_TextureData *texturedata = (GLES_TextureData *) texture->driverdata; + GLES_RenderData *data = (GLES_RenderData *)renderer->driverdata; + GLES_TextureData *texturedata = (GLES_TextureData *)texture->driverdata; GLES_ActivateRenderer(renderer); data->glEnable(GL_TEXTURE_2D); @@ -1093,10 +1022,10 @@ static int GLES_BindTexture (SDL_Renderer * renderer, SDL_Texture *texture, floa return 0; } -static int GLES_UnbindTexture (SDL_Renderer * renderer, SDL_Texture *texture) +static int GLES_UnbindTexture(SDL_Renderer *renderer, SDL_Texture *texture) { - GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata; - GLES_TextureData *texturedata = (GLES_TextureData *) texture->driverdata; + GLES_RenderData *data = (GLES_RenderData *)renderer->driverdata; + GLES_TextureData *texturedata = (GLES_TextureData *)texture->driverdata; GLES_ActivateRenderer(renderer); data->glDisable(texturedata->type); @@ -1106,8 +1035,26 @@ static int GLES_UnbindTexture (SDL_Renderer * renderer, SDL_Texture *texture) return 0; } -static SDL_Renderer * -GLES_CreateRenderer(SDL_Window * window, Uint32 flags) +static int GLES_SetVSync(SDL_Renderer *renderer, const int vsync) +{ + int retval; + if (vsync) { + retval = SDL_GL_SetSwapInterval(1); + } else { + retval = SDL_GL_SetSwapInterval(0); + } + if (retval != 0) { + return retval; + } + if (SDL_GL_GetSwapInterval() != 0) { + renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; + } else { + renderer->info.flags &= ~SDL_RENDERER_PRESENTVSYNC; + } + return retval; +} + +static SDL_Renderer *GLES_CreateRenderer(SDL_Window *window, Uint32 flags) { SDL_Renderer *renderer; GLES_RenderData *data; @@ -1129,18 +1076,18 @@ GLES_CreateRenderer(SDL_Window * window, Uint32 flags) 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) { + if (SDL_RecreateWindow(window, (window_flags & ~(SDL_WINDOW_VULKAN | SDL_WINDOW_METAL)) | SDL_WINDOW_OPENGL) < 0) { goto error; } } - renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer)); + renderer = (SDL_Renderer *)SDL_calloc(1, sizeof(*renderer)); if (!renderer) { SDL_OutOfMemory(); goto error; } - data = (GLES_RenderData *) SDL_calloc(1, sizeof(*data)); + data = (GLES_RenderData *)SDL_calloc(1, sizeof(*data)); if (!data) { GLES_DestroyRenderer(renderer); SDL_OutOfMemory(); @@ -1157,17 +1104,16 @@ GLES_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->SetTextureScaleMode = GLES_SetTextureScaleMode; renderer->SetRenderTarget = GLES_SetRenderTarget; renderer->QueueSetViewport = GLES_QueueSetViewport; - renderer->QueueSetDrawColor = GLES_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */ + renderer->QueueSetDrawColor = GLES_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */ renderer->QueueDrawPoints = GLES_QueueDrawPoints; - renderer->QueueDrawLines = GLES_QueueDrawPoints; /* lines and points queue vertices the same way. */ - renderer->QueueFillRects = GLES_QueueFillRects; - renderer->QueueCopy = GLES_QueueCopy; - renderer->QueueCopyEx = GLES_QueueCopyEx; + renderer->QueueDrawLines = GLES_QueueDrawLines; + renderer->QueueGeometry = GLES_QueueGeometry; renderer->RunCommandQueue = GLES_RunCommandQueue; renderer->RenderReadPixels = GLES_RenderReadPixels; renderer->RenderPresent = GLES_RenderPresent; renderer->DestroyTexture = GLES_DestroyTexture; renderer->DestroyRenderer = GLES_DestroyRenderer; + renderer->SetVSync = GLES_SetVSync; renderer->GL_BindTexture = GLES_BindTexture; renderer->GL_UnbindTexture = GLES_UnbindTexture; renderer->info = GLES_RenderDriver.info; @@ -1195,7 +1141,7 @@ GLES_CreateRenderer(SDL_Window * window, Uint32 flags) } else { SDL_GL_SetSwapInterval(0); } - if (SDL_GL_GetSwapInterval() > 0) { + if (SDL_GL_GetSwapInterval() != 0) { renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; } @@ -1226,6 +1172,9 @@ GLES_CreateRenderer(SDL_Window * window, Uint32 flags) if (SDL_GL_ExtensionSupported("GL_OES_blend_subtract")) { data->GL_OES_blend_subtract_supported = SDL_TRUE; } + if (SDL_GL_ExtensionSupported("GL_EXT_blend_minmax")) { + data->GL_EXT_blend_minmax_supported = SDL_TRUE; + } /* Set up parameters for rendering */ data->glDisable(GL_DEPTH_TEST); @@ -1258,16 +1207,14 @@ error: SDL_RenderDriver GLES_RenderDriver = { GLES_CreateRenderer, - { - "opengles", - (SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC), - 1, - {SDL_PIXELFORMAT_ABGR8888}, - 0, - 0 - } + { "opengles", + (SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC), + 1, + { SDL_PIXELFORMAT_RGBA32 }, + 0, + 0 } }; -#endif /* SDL_VIDEO_RENDER_OGL_ES && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_OGL_ES */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/render/opengles2/SDL_gles2funcs.h b/SDL2-2.30.5/src/render/opengles2/SDL_gles2funcs.h similarity index 94% rename from SDL2-2.0.12/src/render/opengles2/SDL_gles2funcs.h rename to SDL2-2.30.5/src/render/opengles2/SDL_gles2funcs.h index 2a914ae..b808b76 100644 --- a/SDL2-2.0.12/src/render/opengles2/SDL_gles2funcs.h +++ b/SDL2-2.30.5/src/render/opengles2/SDL_gles2funcs.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -41,7 +41,6 @@ SDL_PROC(void, glEnableVertexAttribArray, (GLuint)) SDL_PROC(void, glFinish, (void)) SDL_PROC(void, glGenFramebuffers, (GLsizei, GLuint *)) SDL_PROC(void, glGenTextures, (GLsizei, GLuint *)) -SDL_PROC(void, glGetBooleanv, (GLenum, GLboolean *)) SDL_PROC(const GLubyte *, glGetString, (GLenum)) SDL_PROC(GLenum, glGetError, (void)) SDL_PROC(void, glGetIntegerv, (GLenum, GLint *)) @@ -51,10 +50,10 @@ SDL_PROC(void, glGetShaderiv, (GLuint, GLenum, GLint *)) SDL_PROC(GLint, glGetUniformLocation, (GLuint, const char *)) SDL_PROC(void, glLinkProgram, (GLuint)) SDL_PROC(void, glPixelStorei, (GLenum, GLint)) -SDL_PROC(void, glReadPixels, (GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, GLvoid*)) +SDL_PROC(void, glReadPixels, (GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, GLvoid *)) SDL_PROC(void, glScissor, (GLint, GLint, GLsizei, GLsizei)) SDL_PROC(void, glShaderBinary, (GLsizei, const GLuint *, GLenum, const void *, GLsizei)) -#if __NACL__ +#ifdef __NACL__ SDL_PROC(void, glShaderSource, (GLuint, GLsizei, const GLchar **, const GLint *)) #else SDL_PROC(void, glShaderSource, (GLuint, GLsizei, const GLchar* const*, const GLint *)) @@ -73,7 +72,7 @@ SDL_PROC(void, glFramebufferTexture2D, (GLenum, GLenum, GLenum, GLuint, GLint)) SDL_PROC(GLenum, glCheckFramebufferStatus, (GLenum)) SDL_PROC(void, glDeleteFramebuffers, (GLsizei, const GLuint *)) SDL_PROC(GLint, glGetAttribLocation, (GLuint, const GLchar *)) -SDL_PROC(void, glGetProgramInfoLog, (GLuint, GLsizei, GLsizei*, GLchar*)) +SDL_PROC(void, glGetProgramInfoLog, (GLuint, GLsizei, GLsizei *, GLchar *)) SDL_PROC(void, glGenBuffers, (GLsizei, GLuint *)) SDL_PROC(void, glDeleteBuffers, (GLsizei, const GLuint *)) SDL_PROC(void, glBindBuffer, (GLenum, GLuint)) diff --git a/SDL2-2.0.12/src/render/opengles2/SDL_render_gles2.c b/SDL2-2.30.5/src/render/opengles2/SDL_render_gles2.c similarity index 55% rename from SDL2-2.0.12/src/render/opengles2/SDL_render_gles2.c rename to SDL2-2.30.5/src/render/opengles2/SDL_render_gles2.c index fb83c87..43aebda 100644 --- a/SDL2-2.0.12/src/render/opengles2/SDL_render_gles2.c +++ b/SDL2-2.30.5/src/render/opengles2/SDL_render_gles2.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,24 +20,32 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_RENDER_OGL_ES2 && !SDL_RENDER_DISABLED +#if SDL_VIDEO_RENDER_OGL_ES2 -#include "SDL_assert.h" #include "SDL_hints.h" +#include "../../video/SDL_sysvideo.h" /* For SDL_GL_SwapWindowWithResult */ #include "SDL_opengles2.h" #include "../SDL_sysrender.h" #include "../../video/SDL_blit.h" #include "SDL_shaders_gles2.h" +/* WebGL doesn't offer client-side arrays, so use Vertex Buffer Objects + on Emscripten, which converts GLES2 into WebGL calls. + In all other cases, attempt to use client-side arrays, as they tend to + be dramatically faster when not batching, and about the same when + we are. */ +#if defined(__EMSCRIPTEN__) +#define USE_VERTEX_BUFFER_OBJECTS 1 +#else +#define USE_VERTEX_BUFFER_OBJECTS 0 +#endif + /* To prevent unnecessary window recreation, * these should match the defaults selected in SDL_GL_ResetAttributes */ #define RENDERER_CONTEXT_MAJOR 2 #define RENDERER_CONTEXT_MINOR 0 -/* Used to re-create the window with OpenGL ES capability */ -extern int SDL_RecreateWindow(SDL_Window * window, Uint32 flags); - /************************************************************************************************* * Context structures * *************************************************************************************************/ @@ -46,50 +54,35 @@ typedef struct GLES2_FBOList GLES2_FBOList; struct GLES2_FBOList { - Uint32 w, h; - GLuint FBO; - GLES2_FBOList *next; + Uint32 w, h; + GLuint FBO; + GLES2_FBOList *next; }; typedef struct GLES2_TextureData { - GLenum texture; + GLuint texture; GLenum texture_type; GLenum pixel_format; GLenum pixel_type; void *pixel_data; int pitch; +#if SDL_HAVE_YUV /* YUV texture support */ SDL_bool yuv; SDL_bool nv12; - GLenum texture_v; - GLenum texture_u; + GLuint texture_v; + GLuint texture_u; +#endif GLES2_FBOList *fbo; } GLES2_TextureData; -typedef struct GLES2_ShaderCacheEntry -{ - GLuint id; - GLES2_ShaderType type; - const GLES2_ShaderInstance *instance; - int references; - struct GLES2_ShaderCacheEntry *prev; - struct GLES2_ShaderCacheEntry *next; -} GLES2_ShaderCacheEntry; - -typedef struct GLES2_ShaderCache -{ - int count; - GLES2_ShaderCacheEntry *head; -} GLES2_ShaderCache; - typedef struct GLES2_ProgramCacheEntry { GLuint id; - GLES2_ShaderCacheEntry *vertex_shader; - GLES2_ShaderCacheEntry *fragment_shader; + GLuint vertex_shader; + GLuint fragment_shader; GLuint uniform_locations[16]; - Uint32 color; GLfloat projection[4][4]; struct GLES2_ProgramCacheEntry *prev; struct GLES2_ProgramCacheEntry *next; @@ -105,16 +98,14 @@ typedef struct GLES2_ProgramCache typedef enum { GLES2_ATTRIBUTE_POSITION = 0, - GLES2_ATTRIBUTE_TEXCOORD = 1, - GLES2_ATTRIBUTE_ANGLE = 2, - GLES2_ATTRIBUTE_CENTER = 3, + GLES2_ATTRIBUTE_COLOR = 1, + GLES2_ATTRIBUTE_TEXCOORD = 2, } GLES2_Attribute; typedef enum { GLES2_UNIFORM_PROJECTION, GLES2_UNIFORM_TEXTURE, - GLES2_UNIFORM_COLOR, GLES2_UNIFORM_TEXTURE_U, GLES2_UNIFORM_TEXTURE_V } GLES2_Uniform; @@ -145,8 +136,6 @@ typedef struct SDL_bool cliprect_dirty; SDL_Rect cliprect; SDL_bool texturing; - SDL_bool is_copy_ex; - Uint32 color; Uint32 clear_color; int drawablew; int drawableh; @@ -160,49 +149,55 @@ typedef struct GLES2_RenderData SDL_bool debug_enabled; -#define SDL_PROC(ret,func,params) ret (APIENTRY *func) params; + SDL_bool GL_EXT_blend_minmax_supported; + +#define SDL_PROC(ret, func, params) ret (APIENTRY *func) params; #include "SDL_gles2funcs.h" #undef SDL_PROC GLES2_FBOList *framebuffers; GLuint window_framebuffer; - int shader_format_count; - GLenum *shader_formats; - GLES2_ShaderCache shader_cache; + GLuint shader_id_cache[GLES2_SHADER_COUNT]; + GLES2_ProgramCache program_cache; Uint8 clear_r, clear_g, clear_b, clear_a; +#if USE_VERTEX_BUFFER_OBJECTS GLuint vertex_buffers[8]; size_t vertex_buffer_size[8]; int current_vertex_buffer; +#endif + GLES2_DrawStateCache drawstate; + GLES2_ShaderIncludeType texcoord_precision_hint; } GLES2_RenderData; #define GLES2_MAX_CACHED_PROGRAMS 8 static const float inv255f = 1.0f / 255.0f; - -SDL_FORCE_INLINE const char* -GL_TranslateError (GLenum error) +SDL_FORCE_INLINE const char * +GL_TranslateError(GLenum error) { -#define GL_ERROR_TRANSLATE(e) case e: return #e; +#define GL_ERROR_TRANSLATE(e) \ + case e: \ + return #e; switch (error) { - GL_ERROR_TRANSLATE(GL_INVALID_ENUM) - GL_ERROR_TRANSLATE(GL_INVALID_VALUE) - GL_ERROR_TRANSLATE(GL_INVALID_OPERATION) - GL_ERROR_TRANSLATE(GL_OUT_OF_MEMORY) - GL_ERROR_TRANSLATE(GL_NO_ERROR) + GL_ERROR_TRANSLATE(GL_INVALID_ENUM) + GL_ERROR_TRANSLATE(GL_INVALID_VALUE) + GL_ERROR_TRANSLATE(GL_INVALID_OPERATION) + GL_ERROR_TRANSLATE(GL_OUT_OF_MEMORY) + GL_ERROR_TRANSLATE(GL_NO_ERROR) default: return "UNKNOWN"; -} + } #undef GL_ERROR_TRANSLATE } SDL_FORCE_INLINE void GL_ClearErrors(SDL_Renderer *renderer) { - GLES2_RenderData *data = (GLES2_RenderData *) renderer->driverdata; + GLES2_RenderData *data = (GLES2_RenderData *)renderer->driverdata; if (!data->debug_enabled) { return; @@ -213,9 +208,9 @@ GL_ClearErrors(SDL_Renderer *renderer) } SDL_FORCE_INLINE int -GL_CheckAllErrors (const char *prefix, SDL_Renderer *renderer, const char *file, int line, const char *function) +GL_CheckAllErrors(const char *prefix, SDL_Renderer *renderer, const char *file, int line, const char *function) { - GLES2_RenderData *data = (GLES2_RenderData *) renderer->driverdata; + GLES2_RenderData *data = (GLES2_RenderData *)renderer->driverdata; int ret = 0; if (!data->debug_enabled) { @@ -225,7 +220,7 @@ GL_CheckAllErrors (const char *prefix, SDL_Renderer *renderer, const char *file, for (;;) { GLenum error = data->glGetError(); if (error != GL_NO_ERROR) { - if (prefix == NULL || prefix[0] == '\0') { + if (!prefix || prefix[0] == '\0') { prefix = "generic"; } SDL_SetError("%s: %s (%d): %s %s (0x%X)", prefix, file, line, function, GL_TranslateError(error), error); @@ -243,31 +238,30 @@ GL_CheckAllErrors (const char *prefix, SDL_Renderer *renderer, const char *file, #define GL_CheckError(prefix, renderer) GL_CheckAllErrors(prefix, renderer, SDL_FILE, SDL_LINE, SDL_FUNCTION) #endif - /************************************************************************************************* * Renderer state APIs * *************************************************************************************************/ -static int GLES2_LoadFunctions(GLES2_RenderData * data) +static int GLES2_LoadFunctions(GLES2_RenderData *data) { -#if SDL_VIDEO_DRIVER_UIKIT +#ifdef SDL_VIDEO_DRIVER_UIKIT #define __SDL_NOGETPROCADDR__ -#elif SDL_VIDEO_DRIVER_ANDROID +#elif defined(SDL_VIDEO_DRIVER_ANDROID) #define __SDL_NOGETPROCADDR__ -#elif SDL_VIDEO_DRIVER_PANDORA +#elif defined(SDL_VIDEO_DRIVER_PANDORA) #define __SDL_NOGETPROCADDR__ #endif #if defined __SDL_NOGETPROCADDR__ -#define SDL_PROC(ret,func,params) data->func=func; +#define SDL_PROC(ret, func, params) data->func = func; #else -#define SDL_PROC(ret,func,params) \ - do { \ - data->func = SDL_GL_GetProcAddress(#func); \ - if ( ! data->func ) { \ +#define SDL_PROC(ret, func, params) \ + do { \ + data->func = SDL_GL_GetProcAddress(#func); \ + if (!data->func) { \ return SDL_SetError("Couldn't load GLES2 function %s: %s", #func, SDL_GetError()); \ - } \ - } while ( 0 ); + } \ + } while (0); #endif /* __SDL_NOGETPROCADDR__ */ #include "SDL_gles2funcs.h" @@ -275,26 +269,24 @@ static int GLES2_LoadFunctions(GLES2_RenderData * data) return 0; } -static GLES2_FBOList * -GLES2_GetFBO(GLES2_RenderData *data, Uint32 w, Uint32 h) +static GLES2_FBOList *GLES2_GetFBO(GLES2_RenderData *data, Uint32 w, Uint32 h) { - GLES2_FBOList *result = data->framebuffers; - while ((result) && ((result->w != w) || (result->h != h)) ) { - result = result->next; - } - if (result == NULL) { - result = SDL_malloc(sizeof(GLES2_FBOList)); - result->w = w; - result->h = h; - data->glGenFramebuffers(1, &result->FBO); - result->next = data->framebuffers; - data->framebuffers = result; - } - return result; + GLES2_FBOList *result = data->framebuffers; + while ((result) && ((result->w != w) || (result->h != h))) { + result = result->next; + } + if (!result) { + result = SDL_malloc(sizeof(GLES2_FBOList)); + result->w = w; + result->h = h; + data->glGenFramebuffers(1, &result->FBO); + result->next = data->framebuffers; + data->framebuffers = result; + } + return result; } -static int -GLES2_ActivateRenderer(SDL_Renderer * renderer) +static int GLES2_ActivateRenderer(SDL_Renderer *renderer) { GLES2_RenderData *data = (GLES2_RenderData *)renderer->driverdata; @@ -312,8 +304,7 @@ GLES2_ActivateRenderer(SDL_Renderer * renderer) return 0; } -static void -GLES2_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event) +static void GLES2_WindowEvent(SDL_Renderer *renderer, const SDL_WindowEvent *event) { GLES2_RenderData *data = (GLES2_RenderData *)renderer->driverdata; @@ -323,8 +314,7 @@ GLES2_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event) } } -static int -GLES2_GetOutputSize(SDL_Renderer * renderer, int *w, int *h) +static int GLES2_GetOutputSize(SDL_Renderer *renderer, int *w, int *h) { SDL_GL_GetDrawableSize(renderer->window, w, h); return 0; @@ -367,14 +357,19 @@ static GLenum GetBlendEquation(SDL_BlendOperation operation) return GL_FUNC_SUBTRACT; case SDL_BLENDOPERATION_REV_SUBTRACT: return GL_FUNC_REVERSE_SUBTRACT; + case SDL_BLENDOPERATION_MINIMUM: + return GL_MIN_EXT; + case SDL_BLENDOPERATION_MAXIMUM: + return GL_MAX_EXT; default: return GL_INVALID_ENUM; } } -static SDL_bool -GLES2_SupportsBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode) +static SDL_bool GLES2_SupportsBlendMode(SDL_Renderer *renderer, SDL_BlendMode blendMode) { + GLES2_RenderData *data = (GLES2_RenderData *)renderer->driverdata; + SDL_BlendFactor srcColorFactor = SDL_GetBlendModeSrcColorFactor(blendMode); SDL_BlendFactor srcAlphaFactor = SDL_GetBlendModeSrcAlphaFactor(blendMode); SDL_BlendOperation colorOperation = SDL_GetBlendModeColorOperation(blendMode); @@ -390,36 +385,20 @@ GLES2_SupportsBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode) GetBlendEquation(alphaOperation) == GL_INVALID_ENUM) { return SDL_FALSE; } + + if (colorOperation == SDL_BLENDOPERATION_MINIMUM && !data->GL_EXT_blend_minmax_supported) { + return SDL_FALSE; + } + if (colorOperation == SDL_BLENDOPERATION_MAXIMUM && !data->GL_EXT_blend_minmax_supported) { + return SDL_FALSE; + } + return SDL_TRUE; } - -static void -GLES2_EvictShader(GLES2_RenderData *data, GLES2_ShaderCacheEntry *entry) -{ - /* Unlink the shader from the cache */ - if (entry->next) { - entry->next->prev = entry->prev; - } - if (entry->prev) { - entry->prev->next = entry->next; - } - if (data->shader_cache.head == entry) { - data->shader_cache.head = entry->next; - } - --data->shader_cache.count; - - /* Deallocate the shader */ - data->glDeleteShader(entry->id); - SDL_free(entry); -} - -static GLES2_ProgramCacheEntry * -GLES2_CacheProgram(GLES2_RenderData *data, GLES2_ShaderCacheEntry *vertex, - GLES2_ShaderCacheEntry *fragment) +static GLES2_ProgramCacheEntry *GLES2_CacheProgram(GLES2_RenderData *data, GLuint vertex, GLuint fragment) { GLES2_ProgramCacheEntry *entry; - GLES2_ShaderCacheEntry *shaderEntry; GLint linkSuccessful; /* Check if we've already cached this program */ @@ -457,12 +436,11 @@ GLES2_CacheProgram(GLES2_RenderData *data, GLES2_ShaderCacheEntry *vertex, /* Create the program and link it */ entry->id = data->glCreateProgram(); - data->glAttachShader(entry->id, vertex->id); - data->glAttachShader(entry->id, fragment->id); + data->glAttachShader(entry->id, vertex); + data->glAttachShader(entry->id, fragment); data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_POSITION, "a_position"); + data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_COLOR, "a_color"); data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_TEXCOORD, "a_texCoord"); - data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_ANGLE, "a_angle"); - data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_CENTER, "a_center"); data->glLinkProgram(entry->id); data->glGetProgramiv(entry->id, GL_LINK_STATUS, &linkSuccessful); if (!linkSuccessful) { @@ -481,27 +459,20 @@ GLES2_CacheProgram(GLES2_RenderData *data, GLES2_ShaderCacheEntry *vertex, data->glGetUniformLocation(entry->id, "u_texture_u"); entry->uniform_locations[GLES2_UNIFORM_TEXTURE] = data->glGetUniformLocation(entry->id, "u_texture"); - entry->uniform_locations[GLES2_UNIFORM_COLOR] = - data->glGetUniformLocation(entry->id, "u_color"); - - entry->color = 0; data->glUseProgram(entry->id); if (entry->uniform_locations[GLES2_UNIFORM_TEXTURE_V] != -1) { - data->glUniform1i(entry->uniform_locations[GLES2_UNIFORM_TEXTURE_V], 2); /* always texture unit 2. */ + data->glUniform1i(entry->uniform_locations[GLES2_UNIFORM_TEXTURE_V], 2); /* always texture unit 2. */ } if (entry->uniform_locations[GLES2_UNIFORM_TEXTURE_U] != -1) { - data->glUniform1i(entry->uniform_locations[GLES2_UNIFORM_TEXTURE_U], 1); /* always texture unit 1. */ + data->glUniform1i(entry->uniform_locations[GLES2_UNIFORM_TEXTURE_U], 1); /* always texture unit 1. */ } if (entry->uniform_locations[GLES2_UNIFORM_TEXTURE] != -1) { - data->glUniform1i(entry->uniform_locations[GLES2_UNIFORM_TEXTURE], 0); /* always texture unit 0. */ + data->glUniform1i(entry->uniform_locations[GLES2_UNIFORM_TEXTURE], 0); /* always texture unit 0. */ } if (entry->uniform_locations[GLES2_UNIFORM_PROJECTION] != -1) { data->glUniformMatrix4fv(entry->uniform_locations[GLES2_UNIFORM_PROJECTION], 1, GL_FALSE, (GLfloat *)entry->projection); } - if (entry->uniform_locations[GLES2_UNIFORM_COLOR] != -1) { - data->glUniform4f(entry->uniform_locations[GLES2_UNIFORM_COLOR], 0.0f, 0.0f, 0.0f, 0.0f); - } /* Cache the linked program */ if (data->program_cache.head) { @@ -513,23 +484,11 @@ GLES2_CacheProgram(GLES2_RenderData *data, GLES2_ShaderCacheEntry *vertex, data->program_cache.head = entry; ++data->program_cache.count; - /* Increment the refcount of the shaders we're using */ - ++vertex->references; - ++fragment->references; - /* Evict the last entry from the cache if we exceed the limit */ if (data->program_cache.count > GLES2_MAX_CACHED_PROGRAMS) { - shaderEntry = data->program_cache.tail->vertex_shader; - if (--shaderEntry->references <= 0) { - GLES2_EvictShader(data, shaderEntry); - } - shaderEntry = data->program_cache.tail->fragment_shader; - if (--shaderEntry->references <= 0) { - GLES2_EvictShader(data, shaderEntry); - } data->glDeleteProgram(data->program_cache.tail->id); data->program_cache.tail = data->program_cache.tail->prev; - if (data->program_cache.tail != NULL) { + if (data->program_cache.tail) { SDL_free(data->program_cache.tail->next); data->program_cache.tail->next = NULL; } @@ -538,108 +497,112 @@ GLES2_CacheProgram(GLES2_RenderData *data, GLES2_ShaderCacheEntry *vertex, return entry; } -static GLES2_ShaderCacheEntry * -GLES2_CacheShader(GLES2_RenderData *data, GLES2_ShaderType type) +static GLuint GLES2_CacheShader(GLES2_RenderData *data, GLES2_ShaderType type, GLenum shader_type) { - const GLES2_Shader *shader; - const GLES2_ShaderInstance *instance = NULL; - GLES2_ShaderCacheEntry *entry = NULL; + GLuint id = 0; GLint compileSuccessful = GL_FALSE; - int i, j; + int attempt, num_src; + const GLchar *shader_src_list[3]; + const GLchar *shader_body = GLES2_GetShader(type); - /* Find the corresponding shader */ - shader = GLES2_GetShader(type); - if (!shader) { - SDL_SetError("No shader matching the requested characteristics was found"); - return NULL; + if (!shader_body) { + SDL_SetError("No shader body src"); + return 0; } - /* Find a matching shader instance that's supported on this hardware */ - for (i = 0; i < shader->instance_count && !instance; ++i) { - for (j = 0; j < data->shader_format_count && !instance; ++j) { - if (!shader->instances[i]) { - continue; + for (attempt = 0; attempt < 2 && !compileSuccessful; ++attempt) { + num_src = 0; + + shader_src_list[num_src++] = GLES2_GetShaderPrologue(type); + + if (shader_type == GL_FRAGMENT_SHADER) { + if (attempt == 0) { + shader_src_list[num_src++] = GLES2_GetShaderInclude(data->texcoord_precision_hint); + } else { + shader_src_list[num_src++] = GLES2_GetShaderInclude(GLES2_SHADER_FRAGMENT_INCLUDE_UNDEF_PRECISION); } - if (shader->instances[i]->format != data->shader_formats[j]) { - continue; + } + + shader_src_list[num_src++] = shader_body; + + SDL_assert(num_src <= SDL_arraysize(shader_src_list)); + +#ifdef DEBUG_PRINT_SHADERS + { + int i; + char *message = NULL; + + SDL_asprintf(&message, "Compiling shader:\n"); + for (i = 0; i < num_src; ++i) { + char *last_message = message; + SDL_asprintf(&message, "%s%s", last_message, shader_src_list[i]); + SDL_free(last_message); } - instance = shader->instances[i]; + SDL_Log("%s\n", message); + SDL_free(message); } - } - if (!instance) { - SDL_SetError("The specified shader cannot be loaded on the current platform"); - return NULL; +#endif + + /* Compile */ + id = data->glCreateShader(shader_type); + data->glShaderSource(id, num_src, shader_src_list, NULL); + data->glCompileShader(id); + data->glGetShaderiv(id, GL_COMPILE_STATUS, &compileSuccessful); } - /* Check if we've already cached this shader */ - entry = data->shader_cache.head; - while (entry) { - if (entry->instance == instance) { - break; - } - entry = entry->next; - } - if (entry) { - return entry; - } - - /* Create a shader cache entry */ - entry = (GLES2_ShaderCacheEntry *)SDL_calloc(1, sizeof(GLES2_ShaderCacheEntry)); - if (!entry) { - SDL_OutOfMemory(); - return NULL; - } - entry->type = type; - entry->instance = instance; - - /* Compile or load the selected shader instance */ - entry->id = data->glCreateShader(instance->type); - if (instance->format == (GLenum)-1) { - data->glShaderSource(entry->id, 1, (const char **)(char *)&instance->data, NULL); - data->glCompileShader(entry->id); - data->glGetShaderiv(entry->id, GL_COMPILE_STATUS, &compileSuccessful); - } else { - data->glShaderBinary(1, &entry->id, instance->format, instance->data, instance->length); - compileSuccessful = GL_TRUE; - } if (!compileSuccessful) { SDL_bool isstack = SDL_FALSE; char *info = NULL; int length = 0; - data->glGetShaderiv(entry->id, GL_INFO_LOG_LENGTH, &length); + data->glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length); if (length > 0) { info = SDL_small_alloc(char, length, &isstack); if (info) { - data->glGetShaderInfoLog(entry->id, length, &length, info); + data->glGetShaderInfoLog(id, length, &length, info); } } if (info) { - SDL_SetError("Failed to load the shader: %s", info); + SDL_SetError("Failed to load the shader %d: %s", type, info); SDL_small_free(info, isstack); } else { - SDL_SetError("Failed to load the shader"); + SDL_SetError("Failed to load the shader %d", type); } - data->glDeleteShader(entry->id); - SDL_free(entry); - return NULL; + data->glDeleteShader(id); + return 0; } - /* Link the shader entry in at the front of the cache */ - if (data->shader_cache.head) { - entry->next = data->shader_cache.head; - data->shader_cache.head->prev = entry; - } - data->shader_cache.head = entry; - ++data->shader_cache.count; - return entry; + /* Cache */ + data->shader_id_cache[(Uint32)type] = id; + + return id; } -static int -GLES2_SelectProgram(GLES2_RenderData *data, GLES2_ImageSource source, int w, int h) +static int GLES2_CacheShaders(GLES2_RenderData *data) { - GLES2_ShaderCacheEntry *vertex = NULL; - GLES2_ShaderCacheEntry *fragment = NULL; + int shader; + + data->texcoord_precision_hint = GLES2_GetTexCoordPrecisionEnumFromHint(); + + for (shader = 0; shader < GLES2_SHADER_FRAGMENT_TEXTURE_EXTERNAL_OES; ++shader) { + GLenum shader_type; + + if (shader == GLES2_SHADER_VERTEX_DEFAULT) { + shader_type = GL_VERTEX_SHADER; + } else { + shader_type = GL_FRAGMENT_SHADER; + } + if (!GLES2_CacheShader(data, (GLES2_ShaderType)shader, shader_type)) { + return -1; + } + } + return 0; +} + +static int GLES2_SelectProgram(GLES2_RenderData *data, GLES2_ImageSource source, int w, int h) +{ + GLuint vertex; + GLuint fragment; GLES2_ShaderType vtype, ftype; GLES2_ProgramCacheEntry *program; @@ -647,30 +610,31 @@ GLES2_SelectProgram(GLES2_RenderData *data, GLES2_ImageSource source, int w, int vtype = GLES2_SHADER_VERTEX_DEFAULT; switch (source) { case GLES2_IMAGESOURCE_SOLID: - ftype = GLES2_SHADER_FRAGMENT_SOLID_SRC; + ftype = GLES2_SHADER_FRAGMENT_SOLID; break; case GLES2_IMAGESOURCE_TEXTURE_ABGR: - ftype = GLES2_SHADER_FRAGMENT_TEXTURE_ABGR_SRC; + ftype = GLES2_SHADER_FRAGMENT_TEXTURE_ABGR; break; case GLES2_IMAGESOURCE_TEXTURE_ARGB: - ftype = GLES2_SHADER_FRAGMENT_TEXTURE_ARGB_SRC; + ftype = GLES2_SHADER_FRAGMENT_TEXTURE_ARGB; break; case GLES2_IMAGESOURCE_TEXTURE_RGB: - ftype = GLES2_SHADER_FRAGMENT_TEXTURE_RGB_SRC; + ftype = GLES2_SHADER_FRAGMENT_TEXTURE_RGB; break; case GLES2_IMAGESOURCE_TEXTURE_BGR: - ftype = GLES2_SHADER_FRAGMENT_TEXTURE_BGR_SRC; + ftype = GLES2_SHADER_FRAGMENT_TEXTURE_BGR; break; +#if SDL_HAVE_YUV case GLES2_IMAGESOURCE_TEXTURE_YUV: switch (SDL_GetYUVConversionModeForResolution(w, h)) { case SDL_YUV_CONVERSION_JPEG: - ftype = GLES2_SHADER_FRAGMENT_TEXTURE_YUV_JPEG_SRC; + ftype = GLES2_SHADER_FRAGMENT_TEXTURE_YUV_JPEG; break; case SDL_YUV_CONVERSION_BT601: - ftype = GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT601_SRC; + ftype = GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT601; break; case SDL_YUV_CONVERSION_BT709: - ftype = GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT709_SRC; + ftype = GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT709; break; default: SDL_SetError("Unsupported YUV conversion mode: %d\n", SDL_GetYUVConversionModeForResolution(w, h)); @@ -680,13 +644,21 @@ GLES2_SelectProgram(GLES2_RenderData *data, GLES2_ImageSource source, int w, int case GLES2_IMAGESOURCE_TEXTURE_NV12: switch (SDL_GetYUVConversionModeForResolution(w, h)) { case SDL_YUV_CONVERSION_JPEG: - ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_JPEG_SRC; + ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_JPEG; break; case SDL_YUV_CONVERSION_BT601: - ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_BT601_SRC; + if (SDL_GetHintBoolean("SDL_RENDER_OPENGL_NV12_RG_SHADER", SDL_FALSE)) { + ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RG_BT601; + } else { + ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RA_BT601; + } break; case SDL_YUV_CONVERSION_BT709: - ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_BT709_SRC; + if (SDL_GetHintBoolean("SDL_RENDER_OPENGL_NV12_RG_SHADER", SDL_FALSE)) { + ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RG_BT709; + } else { + ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RA_BT709; + } break; default: SDL_SetError("Unsupported YUV conversion mode: %d\n", SDL_GetYUVConversionModeForResolution(w, h)); @@ -696,34 +668,42 @@ GLES2_SelectProgram(GLES2_RenderData *data, GLES2_ImageSource source, int w, int case GLES2_IMAGESOURCE_TEXTURE_NV21: switch (SDL_GetYUVConversionModeForResolution(w, h)) { case SDL_YUV_CONVERSION_JPEG: - ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV21_JPEG_SRC; + ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV21_JPEG; break; case SDL_YUV_CONVERSION_BT601: - ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT601_SRC; + ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT601; break; case SDL_YUV_CONVERSION_BT709: - ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT709_SRC; + ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT709; break; default: SDL_SetError("Unsupported YUV conversion mode: %d\n", SDL_GetYUVConversionModeForResolution(w, h)); goto fault; } break; +#endif /* SDL_HAVE_YUV */ case GLES2_IMAGESOURCE_TEXTURE_EXTERNAL_OES: - ftype = GLES2_SHADER_FRAGMENT_TEXTURE_EXTERNAL_OES_SRC; + ftype = GLES2_SHADER_FRAGMENT_TEXTURE_EXTERNAL_OES; break; default: goto fault; } /* Load the requested shaders */ - vertex = GLES2_CacheShader(data, vtype); + vertex = data->shader_id_cache[(Uint32)vtype]; if (!vertex) { - goto fault; + vertex = GLES2_CacheShader(data, vtype, GL_VERTEX_SHADER); + if (!vertex) { + goto fault; + } } - fragment = GLES2_CacheShader(data, ftype); + + fragment = data->shader_id_cache[(Uint32)ftype]; if (!fragment) { - goto fault; + fragment = GLES2_CacheShader(data, ftype, GL_FRAGMENT_SHADER); + if (!fragment) { + goto fault; + } } /* Check if we need to change programs at all */ @@ -748,207 +728,202 @@ GLES2_SelectProgram(GLES2_RenderData *data, GLES2_ImageSource source, int w, int /* Clean up and return */ return 0; fault: - if (vertex && vertex->references <= 0) { - GLES2_EvictShader(data, vertex); - } - if (fragment && fragment->references <= 0) { - GLES2_EvictShader(data, fragment); - } data->drawstate.program = NULL; return -1; } -static int -GLES2_QueueSetViewport(SDL_Renderer * renderer, SDL_RenderCommand *cmd) +static int GLES2_QueueSetViewport(SDL_Renderer *renderer, SDL_RenderCommand *cmd) { - return 0; /* nothing to do in this backend. */ + return 0; /* nothing to do in this backend. */ } -static int -GLES2_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count) +static int GLES2_QueueDrawPoints(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count) { - GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, count * 2 * sizeof (GLfloat), 0, &cmd->data.draw.first); + const SDL_bool colorswap = (renderer->target && (renderer->target->format == SDL_PIXELFORMAT_BGRA32 || renderer->target->format == SDL_PIXELFORMAT_BGRX32)); + SDL_VertexSolid *verts = (SDL_VertexSolid *)SDL_AllocateRenderVertices(renderer, count * sizeof(*verts), 0, &cmd->data.draw.first); int i; + SDL_Color color; + color.r = cmd->data.draw.r; + color.g = cmd->data.draw.g; + color.b = cmd->data.draw.b; + color.a = cmd->data.draw.a; if (!verts) { return -1; } + if (colorswap) { + Uint8 r = color.r; + color.r = color.b; + color.b = r; + } + cmd->data.draw.count = count; for (i = 0; i < count; i++) { - *(verts++) = 0.5f + points[i].x; - *(verts++) = 0.5f + points[i].y; + verts->position.x = 0.5f + points[i].x; + verts->position.y = 0.5f + points[i].y; + verts->color = color; + verts++; } return 0; } -static int -GLES2_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRect * rects, int count) +static int GLES2_QueueDrawLines(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count) { - GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, count * 8 * sizeof (GLfloat), 0, &cmd->data.draw.first); + const SDL_bool colorswap = (renderer->target && (renderer->target->format == SDL_PIXELFORMAT_BGRA32 || renderer->target->format == SDL_PIXELFORMAT_BGRX32)); int i; + GLfloat prevx, prevy; + SDL_VertexSolid *verts = (SDL_VertexSolid *)SDL_AllocateRenderVertices(renderer, count * sizeof(*verts), 0, &cmd->data.draw.first); + SDL_Color color; + color.r = cmd->data.draw.r; + color.g = cmd->data.draw.g; + color.b = cmd->data.draw.b; + color.a = cmd->data.draw.a; if (!verts) { return -1; } + if (colorswap) { + Uint8 r = color.r; + color.r = color.b; + color.b = r; + } + cmd->data.draw.count = count; - for (i = 0; i < count; i++) { - const SDL_FRect *rect = &rects[i]; - const GLfloat minx = rect->x; - const GLfloat maxx = rect->x + rect->w; - const GLfloat miny = rect->y; - const GLfloat maxy = rect->y + rect->h; - *(verts++) = minx; - *(verts++) = miny; - *(verts++) = maxx; - *(verts++) = miny; - *(verts++) = minx; - *(verts++) = maxy; - *(verts++) = maxx; - *(verts++) = maxy; + /* 0.5f offset to hit the center of the pixel. */ + prevx = 0.5f + points->x; + prevy = 0.5f + points->y; + verts->position.x = prevx; + verts->position.y = prevy; + verts->color = color; + verts++; + + /* bump the end of each line segment out a quarter of a pixel, to provoke + the diamond-exit rule. Without this, you won't just drop the last + pixel of the last line segment, but you might also drop pixels at the + edge of any given line segment along the way too. */ + for (i = 1; i < count; i++) { + const GLfloat xstart = prevx; + const GLfloat ystart = prevy; + const GLfloat xend = points[i].x + 0.5f; /* 0.5f to hit pixel center. */ + const GLfloat yend = points[i].y + 0.5f; + /* bump a little in the direction we are moving in. */ + const GLfloat deltax = xend - xstart; + const GLfloat deltay = yend - ystart; + const GLfloat angle = SDL_atan2f(deltay, deltax); + prevx = xend + (SDL_cosf(angle) * 0.25f); + prevy = yend + (SDL_sinf(angle) * 0.25f); + verts->position.x = prevx; + verts->position.y = prevy; + verts->color = color; + verts++; } return 0; } -static int -GLES2_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_FRect * dstrect) +static int GLES2_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, + const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride, + int num_vertices, const void *indices, int num_indices, int size_indices, + float scale_x, float scale_y) { - GLfloat minx, miny, maxx, maxy; - GLfloat minu, maxu, minv, maxv; - GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, 16 * sizeof (GLfloat), 0, &cmd->data.draw.first); + int i; + const SDL_bool colorswap = (renderer->target && (renderer->target->format == SDL_PIXELFORMAT_BGRA32 || renderer->target->format == SDL_PIXELFORMAT_BGRX32)); + int count = indices ? num_indices : num_vertices; - if (!verts) { - return -1; - } + cmd->data.draw.count = count; + size_indices = indices ? size_indices : 0; - cmd->data.draw.count = 1; + if (texture) { + SDL_Vertex *verts = (SDL_Vertex *)SDL_AllocateRenderVertices(renderer, count * sizeof(*verts), 0, &cmd->data.draw.first); + if (!verts) { + return -1; + } - minx = dstrect->x; - miny = dstrect->y; - maxx = dstrect->x + dstrect->w; - maxy = dstrect->y + dstrect->h; + for (i = 0; i < count; i++) { + int j; + float *xy_; + SDL_Color col_; + float *uv_; + if (size_indices == 4) { + j = ((const Uint32 *)indices)[i]; + } else if (size_indices == 2) { + j = ((const Uint16 *)indices)[i]; + } else if (size_indices == 1) { + j = ((const Uint8 *)indices)[i]; + } else { + j = i; + } - minu = (GLfloat) srcrect->x / texture->w; - maxu = (GLfloat) (srcrect->x + srcrect->w) / texture->w; - minv = (GLfloat) srcrect->y / texture->h; - maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h; + xy_ = (float *)((char *)xy + j * xy_stride); + col_ = *(SDL_Color *)((char *)color + j * color_stride); + uv_ = (float *)((char *)uv + j * uv_stride); - *(verts++) = minx; - *(verts++) = miny; - *(verts++) = maxx; - *(verts++) = miny; - *(verts++) = minx; - *(verts++) = maxy; - *(verts++) = maxx; - *(verts++) = maxy; + verts->position.x = xy_[0] * scale_x; + verts->position.y = xy_[1] * scale_y; - *(verts++) = minu; - *(verts++) = minv; - *(verts++) = maxu; - *(verts++) = minv; - *(verts++) = minu; - *(verts++) = maxv; - *(verts++) = maxu; - *(verts++) = maxv; + if (colorswap) { + Uint8 r = col_.r; + col_.r = col_.b; + col_.b = r; + } - return 0; -} + verts->color = col_; + verts->tex_coord.x = uv_[0]; + verts->tex_coord.y = uv_[1]; + verts++; + } -static int -GLES2_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture, - const SDL_Rect * srcquad, const SDL_FRect * dstrect, - const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip) -{ - /* render expects cos value - 1 (see GLES2_VertexSrc_Default_) */ - const float radian_angle = (float)(M_PI * (360.0 - angle) / 180.0); - const GLfloat s = (GLfloat) SDL_sin(radian_angle); - const GLfloat c = (GLfloat) SDL_cos(radian_angle) - 1.0f; - const GLfloat centerx = center->x + dstrect->x; - const GLfloat centery = center->y + dstrect->y; - GLfloat minx, miny, maxx, maxy; - GLfloat minu, maxu, minv, maxv; - GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, 32 * sizeof (GLfloat), 0, &cmd->data.draw.first); - - if (!verts) { - return -1; - } - - if (flip & SDL_FLIP_HORIZONTAL) { - minx = dstrect->x + dstrect->w; - maxx = dstrect->x; } else { - minx = dstrect->x; - maxx = dstrect->x + dstrect->w; + SDL_VertexSolid *verts = (SDL_VertexSolid *)SDL_AllocateRenderVertices(renderer, count * sizeof(*verts), 0, &cmd->data.draw.first); + if (!verts) { + return -1; + } + + for (i = 0; i < count; i++) { + int j; + float *xy_; + SDL_Color col_; + + if (size_indices == 4) { + j = ((const Uint32 *)indices)[i]; + } else if (size_indices == 2) { + j = ((const Uint16 *)indices)[i]; + } else if (size_indices == 1) { + j = ((const Uint8 *)indices)[i]; + } else { + j = i; + } + + xy_ = (float *)((char *)xy + j * xy_stride); + col_ = *(SDL_Color *)((char *)color + j * color_stride); + + verts->position.x = xy_[0] * scale_x; + verts->position.y = xy_[1] * scale_y; + + if (colorswap) { + Uint8 r = col_.r; + col_.r = col_.b; + col_.b = r; + } + + verts->color = col_; + verts++; + } } - if (flip & SDL_FLIP_VERTICAL) { - miny = dstrect->y + dstrect->h; - maxy = dstrect->y; - } else { - miny = dstrect->y; - maxy = dstrect->y + dstrect->h; - } - - minu = ((GLfloat) srcquad->x) / ((GLfloat) texture->w); - maxu = ((GLfloat) (srcquad->x + srcquad->w)) / ((GLfloat) texture->w); - minv = ((GLfloat) srcquad->y) / ((GLfloat) texture->h); - maxv = ((GLfloat) (srcquad->y + srcquad->h)) / ((GLfloat) texture->h); - - - cmd->data.draw.count = 1; - - *(verts++) = minx; - *(verts++) = miny; - *(verts++) = maxx; - *(verts++) = miny; - *(verts++) = minx; - *(verts++) = maxy; - *(verts++) = maxx; - *(verts++) = maxy; - - *(verts++) = minu; - *(verts++) = minv; - *(verts++) = maxu; - *(verts++) = minv; - *(verts++) = minu; - *(verts++) = maxv; - *(verts++) = maxu; - *(verts++) = maxv; - - *(verts++) = s; - *(verts++) = c; - *(verts++) = s; - *(verts++) = c; - *(verts++) = s; - *(verts++) = c; - *(verts++) = s; - *(verts++) = c; - - *(verts++) = centerx; - *(verts++) = centery; - *(verts++) = centerx; - *(verts++) = centery; - *(verts++) = centerx; - *(verts++) = centery; - *(verts++) = centerx; - *(verts++) = centery; - return 0; } -static int -SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, const GLES2_ImageSource imgsrc) +static int SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, const GLES2_ImageSource imgsrc, void *vertices) { - const SDL_bool was_copy_ex = data->drawstate.is_copy_ex; - const SDL_bool is_copy_ex = (cmd->command == SDL_RENDERCMD_COPY_EX); SDL_Texture *texture = cmd->data.draw.texture; const SDL_BlendMode blend = cmd->data.draw.blend; GLES2_ProgramCacheEntry *program; + int stride; SDL_assert((texture != NULL) == (imgsrc != GLES2_IMAGESOURCE_SOLID)); @@ -983,41 +958,25 @@ SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, const GLES2_I data->drawstate.cliprect_dirty = SDL_FALSE; } - if (texture != data->drawstate.texture) { - if ((texture != NULL) != data->drawstate.texturing) { - if (texture == NULL) { - data->glDisableVertexAttribArray((GLenum) GLES2_ATTRIBUTE_TEXCOORD); - data->drawstate.texturing = SDL_FALSE; - } else { - data->glEnableVertexAttribArray((GLenum) GLES2_ATTRIBUTE_TEXCOORD); - data->drawstate.texturing = SDL_TRUE; - } + if ((texture != NULL) != data->drawstate.texturing) { + if (!texture) { + data->glDisableVertexAttribArray((GLenum)GLES2_ATTRIBUTE_TEXCOORD); + data->drawstate.texturing = SDL_FALSE; + } else { + data->glEnableVertexAttribArray((GLenum)GLES2_ATTRIBUTE_TEXCOORD); + data->drawstate.texturing = SDL_TRUE; } - - if (texture) { - GLES2_TextureData *tdata = (GLES2_TextureData *) texture->driverdata; - if (tdata->yuv) { - data->glActiveTexture(GL_TEXTURE2); - data->glBindTexture(tdata->texture_type, tdata->texture_v); - - data->glActiveTexture(GL_TEXTURE1); - data->glBindTexture(tdata->texture_type, tdata->texture_u); - - data->glActiveTexture(GL_TEXTURE0); - } else if (tdata->nv12) { - data->glActiveTexture(GL_TEXTURE1); - data->glBindTexture(tdata->texture_type, tdata->texture_u); - - data->glActiveTexture(GL_TEXTURE0); - } - data->glBindTexture(tdata->texture_type, tdata->texture); - } - - data->drawstate.texture = texture; } if (texture) { - data->glVertexAttribPointer(GLES2_ATTRIBUTE_TEXCOORD, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid *) (cmd->data.draw.first + (sizeof (GLfloat) * 8))); + stride = sizeof(SDL_Vertex); + } else { + stride = sizeof(SDL_VertexSolid); + } + + if (texture) { + SDL_Vertex *verts = (SDL_Vertex *)(((Uint8 *)vertices) + cmd->data.draw.first); + data->glVertexAttribPointer(GLES2_ATTRIBUTE_TEXCOORD, 2, GL_FLOAT, GL_FALSE, stride, (const GLvoid *)&verts->tex_coord); } if (GLES2_SelectProgram(data, imgsrc, texture ? texture->w : 0, texture ? texture->h : 0) < 0) { @@ -1027,20 +986,9 @@ SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, const GLES2_I program = data->drawstate.program; if (program->uniform_locations[GLES2_UNIFORM_PROJECTION] != -1) { - if (SDL_memcmp(program->projection, data->drawstate.projection, sizeof (data->drawstate.projection)) != 0) { + if (SDL_memcmp(program->projection, data->drawstate.projection, sizeof(data->drawstate.projection)) != 0) { data->glUniformMatrix4fv(program->uniform_locations[GLES2_UNIFORM_PROJECTION], 1, GL_FALSE, (GLfloat *)data->drawstate.projection); - SDL_memcpy(program->projection, data->drawstate.projection, sizeof (data->drawstate.projection)); - } - } - - if (program->uniform_locations[GLES2_UNIFORM_COLOR] != -1) { - if (data->drawstate.color != program->color) { - const Uint8 r = (data->drawstate.color >> 16) & 0xFF; - const Uint8 g = (data->drawstate.color >> 8) & 0xFF; - const Uint8 b = (data->drawstate.color >> 0) & 0xFF; - const Uint8 a = (data->drawstate.color >> 24) & 0xFF; - data->glUniform4f(program->uniform_locations[GLES2_UNIFORM_COLOR], r * inv255f, g * inv255f, b * inv255f, a * inv255f); - program->color = data->drawstate.color; + SDL_memcpy(program->projection, data->drawstate.projection, sizeof(data->drawstate.projection)); } } @@ -1060,87 +1008,76 @@ SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, const GLES2_I } /* all drawing commands use this */ - data->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid *) cmd->data.draw.first); - - if (is_copy_ex != was_copy_ex) { - if (is_copy_ex) { - data->glEnableVertexAttribArray((GLenum) GLES2_ATTRIBUTE_ANGLE); - data->glEnableVertexAttribArray((GLenum) GLES2_ATTRIBUTE_CENTER); - } else { - data->glDisableVertexAttribArray((GLenum) GLES2_ATTRIBUTE_ANGLE); - data->glDisableVertexAttribArray((GLenum) GLES2_ATTRIBUTE_CENTER); - } - data->drawstate.is_copy_ex = is_copy_ex; - } - - if (is_copy_ex) { - data->glVertexAttribPointer(GLES2_ATTRIBUTE_ANGLE, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid *) (cmd->data.draw.first + (sizeof (GLfloat) * 16))); - data->glVertexAttribPointer(GLES2_ATTRIBUTE_CENTER, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid *) (cmd->data.draw.first + (sizeof (GLfloat) * 24))); + { + SDL_VertexSolid *verts = (SDL_VertexSolid *)(((Uint8 *)vertices) + cmd->data.draw.first); + data->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, stride, (const GLvoid *)&verts->position); + data->glVertexAttribPointer(GLES2_ATTRIBUTE_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE /* Normalized */, stride, (const GLvoid *)&verts->color); } return 0; } -static int -SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd) +static int SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, void *vertices) { - GLES2_RenderData *data = (GLES2_RenderData *) renderer->driverdata; + GLES2_RenderData *data = (GLES2_RenderData *)renderer->driverdata; GLES2_ImageSource sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR; SDL_Texture *texture = cmd->data.draw.texture; + int ret; /* Pick an appropriate shader */ if (renderer->target) { /* Check if we need to do color mapping between the source and render target textures */ if (renderer->target->format != texture->format) { switch (texture->format) { - case SDL_PIXELFORMAT_ARGB8888: + case SDL_PIXELFORMAT_BGRA32: switch (renderer->target->format) { - case SDL_PIXELFORMAT_ABGR8888: - case SDL_PIXELFORMAT_BGR888: + case SDL_PIXELFORMAT_RGBA32: + case SDL_PIXELFORMAT_RGBX32: sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB; break; - case SDL_PIXELFORMAT_RGB888: + case SDL_PIXELFORMAT_BGRX32: sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR; break; } break; - case SDL_PIXELFORMAT_ABGR8888: + case SDL_PIXELFORMAT_RGBA32: switch (renderer->target->format) { - case SDL_PIXELFORMAT_ARGB8888: - case SDL_PIXELFORMAT_RGB888: + case SDL_PIXELFORMAT_BGRA32: + case SDL_PIXELFORMAT_BGRX32: sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB; break; - case SDL_PIXELFORMAT_BGR888: + case SDL_PIXELFORMAT_RGBX32: sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR; break; } break; - case SDL_PIXELFORMAT_RGB888: + case SDL_PIXELFORMAT_BGRX32: switch (renderer->target->format) { - case SDL_PIXELFORMAT_ABGR8888: + case SDL_PIXELFORMAT_RGBA32: sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB; break; - case SDL_PIXELFORMAT_ARGB8888: + case SDL_PIXELFORMAT_BGRA32: sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR; break; - case SDL_PIXELFORMAT_BGR888: + case SDL_PIXELFORMAT_RGBX32: sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB; break; } break; - case SDL_PIXELFORMAT_BGR888: + case SDL_PIXELFORMAT_RGBX32: switch (renderer->target->format) { - case SDL_PIXELFORMAT_ABGR8888: + case SDL_PIXELFORMAT_RGBA32: sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR; break; - case SDL_PIXELFORMAT_ARGB8888: + case SDL_PIXELFORMAT_BGRA32: sourceType = GLES2_IMAGESOURCE_TEXTURE_RGB; break; - case SDL_PIXELFORMAT_RGB888: + case SDL_PIXELFORMAT_BGRX32: sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB; break; } break; +#if SDL_HAVE_YUV case SDL_PIXELFORMAT_IYUV: case SDL_PIXELFORMAT_YV12: sourceType = GLES2_IMAGESOURCE_TEXTURE_YUV; @@ -1151,6 +1088,7 @@ SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd) case SDL_PIXELFORMAT_NV21: sourceType = GLES2_IMAGESOURCE_TEXTURE_NV21; break; +#endif case SDL_PIXELFORMAT_EXTERNAL_OES: sourceType = GLES2_IMAGESOURCE_TEXTURE_EXTERNAL_OES; break; @@ -1158,51 +1096,78 @@ SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd) return SDL_SetError("Unsupported texture format"); } } else { - sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR; /* Texture formats match, use the non color mapping shader (even if the formats are not ABGR) */ + sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR; /* Texture formats match, use the non color mapping shader (even if the formats are not ABGR) */ } } else { switch (texture->format) { - case SDL_PIXELFORMAT_ARGB8888: - sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB; - break; - case SDL_PIXELFORMAT_ABGR8888: - sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR; - break; - case SDL_PIXELFORMAT_RGB888: - sourceType = GLES2_IMAGESOURCE_TEXTURE_RGB; - break; - case SDL_PIXELFORMAT_BGR888: - sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR; - break; - case SDL_PIXELFORMAT_IYUV: - case SDL_PIXELFORMAT_YV12: - sourceType = GLES2_IMAGESOURCE_TEXTURE_YUV; - break; - case SDL_PIXELFORMAT_NV12: - sourceType = GLES2_IMAGESOURCE_TEXTURE_NV12; - break; - case SDL_PIXELFORMAT_NV21: - sourceType = GLES2_IMAGESOURCE_TEXTURE_NV21; - break; - case SDL_PIXELFORMAT_EXTERNAL_OES: - sourceType = GLES2_IMAGESOURCE_TEXTURE_EXTERNAL_OES; - break; - default: - return SDL_SetError("Unsupported texture format"); + case SDL_PIXELFORMAT_BGRA32: + sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB; + break; + case SDL_PIXELFORMAT_RGBA32: + sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR; + break; + case SDL_PIXELFORMAT_BGRX32: + sourceType = GLES2_IMAGESOURCE_TEXTURE_RGB; + break; + case SDL_PIXELFORMAT_RGBX32: + sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR; + break; +#if SDL_HAVE_YUV + case SDL_PIXELFORMAT_IYUV: + case SDL_PIXELFORMAT_YV12: + sourceType = GLES2_IMAGESOURCE_TEXTURE_YUV; + break; + case SDL_PIXELFORMAT_NV12: + sourceType = GLES2_IMAGESOURCE_TEXTURE_NV12; + break; + case SDL_PIXELFORMAT_NV21: + sourceType = GLES2_IMAGESOURCE_TEXTURE_NV21; + break; +#endif + case SDL_PIXELFORMAT_EXTERNAL_OES: + sourceType = GLES2_IMAGESOURCE_TEXTURE_EXTERNAL_OES; + break; + default: + return SDL_SetError("Unsupported texture format"); } } - return SetDrawState(data, cmd, sourceType); + ret = SetDrawState(data, cmd, sourceType, vertices); + + if (texture != data->drawstate.texture) { + GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata; +#if SDL_HAVE_YUV + if (tdata->yuv) { + data->glActiveTexture(GL_TEXTURE2); + data->glBindTexture(tdata->texture_type, tdata->texture_v); + + data->glActiveTexture(GL_TEXTURE1); + data->glBindTexture(tdata->texture_type, tdata->texture_u); + + data->glActiveTexture(GL_TEXTURE0); + } else if (tdata->nv12) { + data->glActiveTexture(GL_TEXTURE1); + data->glBindTexture(tdata->texture_type, tdata->texture_u); + + data->glActiveTexture(GL_TEXTURE0); + } +#endif + data->glBindTexture(tdata->texture_type, tdata->texture); + data->drawstate.texture = texture; + } + + return ret; } -static int -GLES2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize) +static int GLES2_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize) { - GLES2_RenderData *data = (GLES2_RenderData *) renderer->driverdata; - const SDL_bool colorswap = (renderer->target && (renderer->target->format == SDL_PIXELFORMAT_ARGB8888 || renderer->target->format == SDL_PIXELFORMAT_RGB888)); + GLES2_RenderData *data = (GLES2_RenderData *)renderer->driverdata; + const SDL_bool colorswap = (renderer->target && (renderer->target->format == SDL_PIXELFORMAT_BGRA32 || renderer->target->format == SDL_PIXELFORMAT_BGRX32)); + +#if USE_VERTEX_BUFFER_OBJECTS const int vboidx = data->current_vertex_buffer; const GLuint vbo = data->vertex_buffers[vboidx]; - size_t i; +#endif if (GLES2_ActivateRenderer(renderer) < 0) { return -1; @@ -1210,9 +1175,17 @@ GLES2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver data->drawstate.target = renderer->target; if (!data->drawstate.target) { - SDL_GL_GetDrawableSize(renderer->window, &data->drawstate.drawablew, &data->drawstate.drawableh); + int w, h; + SDL_GL_GetDrawableSize(renderer->window, &w, &h); + if ((w != data->drawstate.drawablew) || (h != data->drawstate.drawableh)) { + data->drawstate.viewport_dirty = SDL_TRUE; // if the window dimensions changed, invalidate the current viewport, etc. + data->drawstate.cliprect_dirty = SDL_TRUE; + data->drawstate.drawablew = w; + data->drawstate.drawableh = h; + } } +#if USE_VERTEX_BUFFER_OBJECTS /* upload the new VBO data for this set of commands. */ data->glBindBuffer(GL_ARRAY_BUFFER, vbo); if (data->vertex_buffer_size[vboidx] < vertsize) { @@ -1227,109 +1200,156 @@ GLES2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver if (data->current_vertex_buffer >= SDL_arraysize(data->vertex_buffers)) { data->current_vertex_buffer = 0; } + vertices = NULL; /* attrib pointers will be offsets into the VBO. */ +#endif while (cmd) { switch (cmd->command) { - case SDL_RENDERCMD_SETDRAWCOLOR: { - const Uint8 r = colorswap ? cmd->data.color.b : cmd->data.color.r; - const Uint8 g = cmd->data.color.g; - const Uint8 b = colorswap ? cmd->data.color.r : cmd->data.color.b; - const Uint8 a = cmd->data.color.a; - data->drawstate.color = ((a << 24) | (r << 16) | (g << 8) | b); - break; + case SDL_RENDERCMD_SETDRAWCOLOR: + { + break; + } + + case SDL_RENDERCMD_SETVIEWPORT: + { + SDL_Rect *viewport = &data->drawstate.viewport; + if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof(cmd->data.viewport.rect)) != 0) { + SDL_copyp(viewport, &cmd->data.viewport.rect); + data->drawstate.viewport_dirty = SDL_TRUE; + data->drawstate.cliprect_dirty = SDL_TRUE; + } + break; + } + + case SDL_RENDERCMD_SETCLIPRECT: + { + const SDL_Rect *rect = &cmd->data.cliprect.rect; + if (data->drawstate.cliprect_enabled != cmd->data.cliprect.enabled) { + data->drawstate.cliprect_enabled = cmd->data.cliprect.enabled; + data->drawstate.cliprect_enabled_dirty = SDL_TRUE; } - case SDL_RENDERCMD_SETVIEWPORT: { - SDL_Rect *viewport = &data->drawstate.viewport; - if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect)) != 0) { - SDL_memcpy(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect)); - data->drawstate.viewport_dirty = SDL_TRUE; - } - break; + if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof(*rect)) != 0) { + SDL_copyp(&data->drawstate.cliprect, rect); + data->drawstate.cliprect_dirty = SDL_TRUE; + } + break; + } + + case SDL_RENDERCMD_CLEAR: + { + const Uint8 r = colorswap ? cmd->data.color.b : cmd->data.color.r; + const Uint8 g = cmd->data.color.g; + const Uint8 b = colorswap ? cmd->data.color.r : cmd->data.color.b; + const Uint8 a = cmd->data.color.a; + const Uint32 color = (((Uint32)a << 24) | (r << 16) | (g << 8) | b); + if (color != data->drawstate.clear_color) { + const GLfloat fr = ((GLfloat)r) * inv255f; + const GLfloat fg = ((GLfloat)g) * inv255f; + const GLfloat fb = ((GLfloat)b) * inv255f; + const GLfloat fa = ((GLfloat)a) * inv255f; + data->glClearColor(fr, fg, fb, fa); + data->drawstate.clear_color = color; } - case SDL_RENDERCMD_SETCLIPRECT: { - const SDL_Rect *rect = &cmd->data.cliprect.rect; - if (data->drawstate.cliprect_enabled != cmd->data.cliprect.enabled) { - data->drawstate.cliprect_enabled = cmd->data.cliprect.enabled; - data->drawstate.cliprect_enabled_dirty = SDL_TRUE; - } - - if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof (SDL_Rect)) != 0) { - SDL_memcpy(&data->drawstate.cliprect, rect, sizeof (SDL_Rect)); - data->drawstate.cliprect_dirty = SDL_TRUE; - } - break; + if (data->drawstate.cliprect_enabled || data->drawstate.cliprect_enabled_dirty) { + data->glDisable(GL_SCISSOR_TEST); + data->drawstate.cliprect_enabled_dirty = data->drawstate.cliprect_enabled; } - case SDL_RENDERCMD_CLEAR: { - const Uint8 r = colorswap ? cmd->data.color.b : cmd->data.color.r; - const Uint8 g = cmd->data.color.g; - const Uint8 b = colorswap ? cmd->data.color.r : cmd->data.color.b; - const Uint8 a = cmd->data.color.a; - const Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b); - if (color != data->drawstate.clear_color) { - const GLfloat fr = ((GLfloat) r) * inv255f; - const GLfloat fg = ((GLfloat) g) * inv255f; - const GLfloat fb = ((GLfloat) b) * inv255f; - const GLfloat fa = ((GLfloat) a) * inv255f; - data->glClearColor(fr, fg, fb, fa); - data->drawstate.clear_color = color; - } + data->glClear(GL_COLOR_BUFFER_BIT); + break; + } - if (data->drawstate.cliprect_enabled || data->drawstate.cliprect_enabled_dirty) { - data->glDisable(GL_SCISSOR_TEST); - data->drawstate.cliprect_enabled_dirty = data->drawstate.cliprect_enabled; - } + case SDL_RENDERCMD_FILL_RECTS: /* unused */ + break; - data->glClear(GL_COLOR_BUFFER_BIT); - break; - } + case SDL_RENDERCMD_COPY: /* unused */ + break; - case SDL_RENDERCMD_DRAW_POINTS: { - if (SetDrawState(data, cmd, GLES2_IMAGESOURCE_SOLID) == 0) { - data->glDrawArrays(GL_POINTS, 0, (GLsizei) cmd->data.draw.count); - } - break; - } + case SDL_RENDERCMD_COPY_EX: /* unused */ + break; - case SDL_RENDERCMD_DRAW_LINES: { - const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first); - const size_t count = cmd->data.draw.count; - if (SetDrawState(data, cmd, GLES2_IMAGESOURCE_SOLID) == 0) { - if (count > 2 && (verts[0] == verts[(count-1)*2]) && (verts[1] == verts[(count*2)-1])) { - /* GL_LINE_LOOP takes care of the final segment */ - data->glDrawArrays(GL_LINE_LOOP, 0, (GLsizei) (count - 1)); - } else { - data->glDrawArrays(GL_LINE_STRIP, 0, (GLsizei) count); - /* We need to close the endpoint of the line */ - data->glDrawArrays(GL_POINTS, (GLsizei) (count - 1), 1); + case SDL_RENDERCMD_DRAW_LINES: + { + if (SetDrawState(data, cmd, GLES2_IMAGESOURCE_SOLID, vertices) == 0) { + size_t count = cmd->data.draw.count; + if (count > 2) { + /* joined lines cannot be grouped */ + data->glDrawArrays(GL_LINE_STRIP, 0, (GLsizei)count); + } else { + /* let's group non joined lines */ + SDL_RenderCommand *finalcmd = cmd; + SDL_RenderCommand *nextcmd = cmd->next; + SDL_BlendMode thisblend = cmd->data.draw.blend; + + while (nextcmd) { + const SDL_RenderCommandType nextcmdtype = nextcmd->command; + if (nextcmdtype != SDL_RENDERCMD_DRAW_LINES) { + break; /* can't go any further on this draw call, different render command up next. */ + } else if (nextcmd->data.draw.count != 2) { + break; /* can't go any further on this draw call, those are joined lines */ + } else if (nextcmd->data.draw.blend != thisblend) { + break; /* can't go any further on this draw call, different blendmode copy up next. */ + } else { + finalcmd = nextcmd; /* we can combine copy operations here. Mark this one as the furthest okay command. */ + count += nextcmd->data.draw.count; + } + nextcmd = nextcmd->next; } + + data->glDrawArrays(GL_LINES, 0, (GLsizei)count); + cmd = finalcmd; /* skip any copy commands we just combined in here. */ } - break; + } + break; + } + + case SDL_RENDERCMD_DRAW_POINTS: + case SDL_RENDERCMD_GEOMETRY: + { + /* as long as we have the same copy command in a row, with the + same texture, we can combine them all into a single draw call. */ + SDL_Texture *thistexture = cmd->data.draw.texture; + SDL_BlendMode thisblend = cmd->data.draw.blend; + const SDL_RenderCommandType thiscmdtype = cmd->command; + SDL_RenderCommand *finalcmd = cmd; + SDL_RenderCommand *nextcmd = cmd->next; + size_t count = cmd->data.draw.count; + int ret; + while (nextcmd) { + const SDL_RenderCommandType nextcmdtype = nextcmd->command; + if (nextcmdtype != thiscmdtype) { + break; /* can't go any further on this draw call, different render command up next. */ + } else if (nextcmd->data.draw.texture != thistexture || nextcmd->data.draw.blend != thisblend) { + break; /* can't go any further on this draw call, different texture/blendmode copy up next. */ + } else { + finalcmd = nextcmd; /* we can combine copy operations here. Mark this one as the furthest okay command. */ + count += nextcmd->data.draw.count; + } + nextcmd = nextcmd->next; } - case SDL_RENDERCMD_FILL_RECTS: { - const size_t count = cmd->data.draw.count; - size_t offset = 0; - if (SetDrawState(data, cmd, GLES2_IMAGESOURCE_SOLID) == 0) { - for (i = 0; i < count; ++i, offset += 4) { - data->glDrawArrays(GL_TRIANGLE_STRIP, (GLsizei) offset, 4); - } - } - break; + if (thistexture) { + ret = SetCopyState(renderer, cmd, vertices); + } else { + ret = SetDrawState(data, cmd, GLES2_IMAGESOURCE_SOLID, vertices); } - case SDL_RENDERCMD_COPY: - case SDL_RENDERCMD_COPY_EX: { - if (SetCopyState(renderer, cmd) == 0) { - data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + if (ret == 0) { + int op = GL_TRIANGLES; /* SDL_RENDERCMD_GEOMETRY */ + if (thiscmdtype == SDL_RENDERCMD_DRAW_POINTS) { + op = GL_POINTS; } - break; + data->glDrawArrays(op, 0, (GLsizei)count); } - case SDL_RENDERCMD_NO_OP: - break; + cmd = finalcmd; /* skip any copy commands we just combined in here. */ + break; + } + + case SDL_RENDERCMD_NO_OP: + break; } cmd = cmd->next; @@ -1338,8 +1358,7 @@ GLES2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver return GL_CheckError("", renderer); } -static void -GLES2_DestroyRenderer(SDL_Renderer *renderer) +static void GLES2_DestroyRenderer(SDL_Renderer *renderer) { GLES2_RenderData *data = (GLES2_RenderData *)renderer->driverdata; @@ -1348,14 +1367,12 @@ GLES2_DestroyRenderer(SDL_Renderer *renderer) GLES2_ActivateRenderer(renderer); { - GLES2_ShaderCacheEntry *entry; - GLES2_ShaderCacheEntry *next; - entry = data->shader_cache.head; - while (entry) { - data->glDeleteShader(entry->id); - next = entry->next; - SDL_free(entry); - entry = next; + int i; + for (i = 0; i < GLES2_SHADER_COUNT; i++) { + GLuint id = data->shader_id_cache[i]; + if (id) { + data->glDeleteShader(id); + } } } { @@ -1379,20 +1396,20 @@ GLES2_DestroyRenderer(SDL_Renderer *renderer) data->framebuffers = nextnode; } +#if USE_VERTEX_BUFFER_OBJECTS data->glDeleteBuffers(SDL_arraysize(data->vertex_buffers), data->vertex_buffers); GL_CheckError("", renderer); +#endif SDL_GL_DeleteContext(data->context); } - SDL_free(data->shader_formats); SDL_free(data); } SDL_free(renderer); } -static int -GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) +static int GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) { GLES2_RenderData *renderdata = (GLES2_RenderData *)renderer->driverdata; GLES2_TextureData *data; @@ -1402,18 +1419,18 @@ GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) GLES2_ActivateRenderer(renderer); - renderdata->drawstate.texture = NULL; /* we trash this state. */ + renderdata->drawstate.texture = NULL; /* we trash this state. */ /* Determine the corresponding GLES texture format params */ - switch (texture->format) - { - case SDL_PIXELFORMAT_ARGB8888: - case SDL_PIXELFORMAT_ABGR8888: - case SDL_PIXELFORMAT_RGB888: - case SDL_PIXELFORMAT_BGR888: + switch (texture->format) { + case SDL_PIXELFORMAT_BGRA32: + case SDL_PIXELFORMAT_RGBA32: + case SDL_PIXELFORMAT_BGRX32: + case SDL_PIXELFORMAT_RGBX32: format = GL_RGBA; type = GL_UNSIGNED_BYTE; break; +#if SDL_HAVE_YUV case SDL_PIXELFORMAT_IYUV: case SDL_PIXELFORMAT_YV12: case SDL_PIXELFORMAT_NV12: @@ -1421,6 +1438,7 @@ GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) format = GL_LUMINANCE; type = GL_UNSIGNED_BYTE; break; +#endif #ifdef GL_TEXTURE_EXTERNAL_OES case SDL_PIXELFORMAT_EXTERNAL_OES: format = GL_NONE; @@ -1449,17 +1467,20 @@ GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) #endif data->pixel_format = format; data->pixel_type = type; +#if SDL_HAVE_YUV data->yuv = ((texture->format == SDL_PIXELFORMAT_IYUV) || (texture->format == SDL_PIXELFORMAT_YV12)); data->nv12 = ((texture->format == SDL_PIXELFORMAT_NV12) || (texture->format == SDL_PIXELFORMAT_NV21)); data->texture_u = 0; data->texture_v = 0; +#endif scaleMode = (texture->scaleMode == SDL_ScaleModeNearest) ? GL_NEAREST : GL_LINEAR; /* Allocate a blob for image renderdata */ if (texture->access == SDL_TEXTUREACCESS_STREAMING) { size_t size; data->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format); - size = texture->h * data->pitch; + size = (size_t)texture->h * data->pitch; +#if SDL_HAVE_YUV if (data->yuv) { /* Need to add size for the U and V planes */ size += 2 * ((texture->h + 1) / 2) * ((data->pitch + 1) / 2); @@ -1467,6 +1488,7 @@ GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) /* Need to add size for the U/V plane */ size += 2 * ((texture->h + 1) / 2) * ((data->pitch + 1) / 2); } +#endif data->pixel_data = SDL_calloc(1, size); if (!data->pixel_data) { SDL_free(data); @@ -1477,6 +1499,7 @@ GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) /* Allocate the texture */ GL_CheckError("", renderer); +#if SDL_HAVE_YUV if (data->yuv) { renderdata->glGenTextures(1, &data->texture_v); if (GL_CheckError("glGenTexures()", renderer) < 0) { @@ -1520,6 +1543,7 @@ GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) return -1; } } +#endif renderdata->glGenTextures(1, &data->texture); if (GL_CheckError("glGenTexures()", renderer) < 0) { @@ -1540,28 +1564,27 @@ GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) } if (texture->access == SDL_TEXTUREACCESS_TARGET) { - data->fbo = GLES2_GetFBO(renderer->driverdata, texture->w, texture->h); + data->fbo = GLES2_GetFBO(renderer->driverdata, texture->w, texture->h); } else { - data->fbo = NULL; + data->fbo = NULL; } return GL_CheckError("", renderer); } -static int -GLES2_TexSubImage2D(GLES2_RenderData *data, GLenum target, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels, GLint pitch, GLint bpp) +static int GLES2_TexSubImage2D(GLES2_RenderData *data, GLenum target, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels, GLint pitch, GLint bpp) { Uint8 *blob = NULL; Uint8 *src; - int src_pitch; + size_t src_pitch; int y; if ((width == 0) || (height == 0) || (bpp == 0)) { - return 0; /* nothing to do */ + return 0; /* nothing to do */ } /* Reformat the texture data into a tightly packed array */ - src_pitch = width * bpp; + src_pitch = (size_t)width * bpp; src = (Uint8 *)pixels; if (pitch != src_pitch) { blob = (Uint8 *)SDL_malloc(src_pitch * height); @@ -1569,8 +1592,7 @@ GLES2_TexSubImage2D(GLES2_RenderData *data, GLenum target, GLint xoffset, GLint return SDL_OutOfMemory(); } src = blob; - for (y = 0; y < height; ++y) - { + for (y = 0; y < height; ++y) { SDL_memcpy(src, pixels, src_pitch); src += src_pitch; pixels = (Uint8 *)pixels + pitch; @@ -1585,9 +1607,8 @@ GLES2_TexSubImage2D(GLES2_RenderData *data, GLenum target, GLint xoffset, GLint return 0; } -static int -GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, - const void *pixels, int pitch) +static int GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, + const void *pixels, int pitch) { GLES2_RenderData *data = (GLES2_RenderData *)renderer->driverdata; GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata; @@ -1599,75 +1620,76 @@ GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect return 0; } - data->drawstate.texture = NULL; /* we trash this state. */ + data->drawstate.texture = NULL; /* we trash this state. */ /* Create a texture subimage with the supplied data */ data->glBindTexture(tdata->texture_type, tdata->texture); GLES2_TexSubImage2D(data, tdata->texture_type, - rect->x, - rect->y, - rect->w, - rect->h, - tdata->pixel_format, - tdata->pixel_type, - pixels, pitch, SDL_BYTESPERPIXEL(texture->format)); + rect->x, + rect->y, + rect->w, + rect->h, + tdata->pixel_format, + tdata->pixel_type, + pixels, pitch, SDL_BYTESPERPIXEL(texture->format)); +#if SDL_HAVE_YUV if (tdata->yuv) { /* Skip to the correct offset into the next texture */ - pixels = (const void*)((const Uint8*)pixels + rect->h * pitch); + pixels = (const void *)((const Uint8 *)pixels + rect->h * pitch); if (texture->format == SDL_PIXELFORMAT_YV12) { data->glBindTexture(tdata->texture_type, tdata->texture_v); } else { data->glBindTexture(tdata->texture_type, tdata->texture_u); } GLES2_TexSubImage2D(data, tdata->texture_type, - rect->x / 2, - rect->y / 2, - (rect->w + 1) / 2, - (rect->h + 1) / 2, - tdata->pixel_format, - tdata->pixel_type, - pixels, (pitch + 1) / 2, 1); - + rect->x / 2, + rect->y / 2, + (rect->w + 1) / 2, + (rect->h + 1) / 2, + tdata->pixel_format, + tdata->pixel_type, + pixels, (pitch + 1) / 2, 1); /* Skip to the correct offset into the next texture */ - pixels = (const void*)((const Uint8*)pixels + ((rect->h + 1) / 2) * ((pitch + 1)/2)); + 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 { data->glBindTexture(tdata->texture_type, tdata->texture_v); } GLES2_TexSubImage2D(data, tdata->texture_type, - rect->x / 2, - rect->y / 2, - (rect->w + 1) / 2, - (rect->h + 1) / 2, - tdata->pixel_format, - tdata->pixel_type, - pixels, (pitch + 1) / 2, 1); + rect->x / 2, + rect->y / 2, + (rect->w + 1) / 2, + (rect->h + 1) / 2, + tdata->pixel_format, + tdata->pixel_type, + pixels, (pitch + 1) / 2, 1); } else if (tdata->nv12) { /* Skip to the correct offset into the next texture */ - pixels = (const void*)((const Uint8*)pixels + rect->h * pitch); + pixels = (const void *)((const Uint8 *)pixels + rect->h * pitch); data->glBindTexture(tdata->texture_type, tdata->texture_u); GLES2_TexSubImage2D(data, tdata->texture_type, - rect->x / 2, - rect->y / 2, - (rect->w + 1) / 2, - (rect->h + 1) / 2, - GL_LUMINANCE_ALPHA, - GL_UNSIGNED_BYTE, - pixels, 2 * ((pitch + 1) / 2), 2); + rect->x / 2, + rect->y / 2, + (rect->w + 1) / 2, + (rect->h + 1) / 2, + GL_LUMINANCE_ALPHA, + GL_UNSIGNED_BYTE, + pixels, 2 * ((pitch + 1) / 2), 2); } +#endif return GL_CheckError("glTexSubImage2D()", renderer); } -static int -GLES2_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * rect, - const Uint8 *Yplane, int Ypitch, - const Uint8 *Uplane, int Upitch, - const Uint8 *Vplane, int Vpitch) +#if SDL_HAVE_YUV +static int GLES2_UpdateTextureYUV(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *Uplane, int Upitch, + const Uint8 *Vplane, int Vpitch) { GLES2_RenderData *data = (GLES2_RenderData *)renderer->driverdata; GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata; @@ -1679,44 +1701,84 @@ GLES2_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture, return 0; } - data->drawstate.texture = NULL; /* we trash this state. */ + data->drawstate.texture = NULL; /* we trash this state. */ data->glBindTexture(tdata->texture_type, tdata->texture_v); GLES2_TexSubImage2D(data, tdata->texture_type, - rect->x / 2, - rect->y / 2, - (rect->w + 1) / 2, - (rect->h + 1) / 2, - tdata->pixel_format, - tdata->pixel_type, - Vplane, Vpitch, 1); + rect->x / 2, + rect->y / 2, + (rect->w + 1) / 2, + (rect->h + 1) / 2, + tdata->pixel_format, + tdata->pixel_type, + Vplane, Vpitch, 1); data->glBindTexture(tdata->texture_type, tdata->texture_u); GLES2_TexSubImage2D(data, tdata->texture_type, - rect->x / 2, - rect->y / 2, - (rect->w + 1) / 2, - (rect->h + 1) / 2, - tdata->pixel_format, - tdata->pixel_type, - Uplane, Upitch, 1); + rect->x / 2, + rect->y / 2, + (rect->w + 1) / 2, + (rect->h + 1) / 2, + tdata->pixel_format, + tdata->pixel_type, + Uplane, Upitch, 1); data->glBindTexture(tdata->texture_type, tdata->texture); GLES2_TexSubImage2D(data, tdata->texture_type, - rect->x, - rect->y, - rect->w, - rect->h, - tdata->pixel_format, - tdata->pixel_type, - Yplane, Ypitch, 1); + rect->x, + rect->y, + rect->w, + rect->h, + tdata->pixel_format, + tdata->pixel_type, + Yplane, Ypitch, 1); return GL_CheckError("glTexSubImage2D()", renderer); } -static int -GLES2_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, - void **pixels, int *pitch) +static int GLES2_UpdateTextureNV(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *UVplane, int UVpitch) +{ + GLES2_RenderData *data = (GLES2_RenderData *)renderer->driverdata; + GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata; + + GLES2_ActivateRenderer(renderer); + + /* Bail out if we're supposed to update an empty rectangle */ + if (rect->w <= 0 || rect->h <= 0) { + return 0; + } + + data->drawstate.texture = NULL; /* we trash this state. */ + + data->glBindTexture(tdata->texture_type, tdata->texture_u); + GLES2_TexSubImage2D(data, tdata->texture_type, + rect->x / 2, + rect->y / 2, + (rect->w + 1) / 2, + (rect->h + 1) / 2, + GL_LUMINANCE_ALPHA, + GL_UNSIGNED_BYTE, + UVplane, UVpitch, 2); + + data->glBindTexture(tdata->texture_type, tdata->texture); + GLES2_TexSubImage2D(data, tdata->texture_type, + rect->x, + rect->y, + rect->w, + rect->h, + tdata->pixel_format, + tdata->pixel_type, + Yplane, Ypitch, 1); + + return GL_CheckError("glTexSubImage2D()", renderer); +} +#endif + +static int GLES2_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, + void **pixels, int *pitch) { GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata; @@ -1729,8 +1791,7 @@ GLES2_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect * return 0; } -static void -GLES2_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture) +static void GLES2_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture) { GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata; SDL_Rect rect; @@ -1743,13 +1804,13 @@ GLES2_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture) GLES2_UpdateTexture(renderer, texture, &rect, tdata->pixel_data, tdata->pitch); } -static void -GLES2_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture, SDL_ScaleMode scaleMode) +static void GLES2_SetTextureScaleMode(SDL_Renderer *renderer, SDL_Texture *texture, SDL_ScaleMode scaleMode) { - GLES2_RenderData *renderdata = (GLES2_RenderData *) renderer->driverdata; - GLES2_TextureData *data = (GLES2_TextureData *) texture->driverdata; + GLES2_RenderData *renderdata = (GLES2_RenderData *)renderer->driverdata; + GLES2_TextureData *data = (GLES2_TextureData *)texture->driverdata; GLenum glScaleMode = (scaleMode == SDL_ScaleModeNearest) ? GL_NEAREST : GL_LINEAR; +#if SDL_HAVE_YUV if (data->yuv) { renderdata->glActiveTexture(GL_TEXTURE2); renderdata->glBindTexture(data->texture_type, data->texture_v); @@ -1766,6 +1827,7 @@ GLES2_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture, SDL_Sc renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MIN_FILTER, glScaleMode); renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MAG_FILTER, glScaleMode); } +#endif renderdata->glActiveTexture(GL_TEXTURE0); renderdata->glBindTexture(data->texture_type, data->texture); @@ -1773,19 +1835,18 @@ GLES2_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture, SDL_Sc renderdata->glTexParameteri(data->texture_type, GL_TEXTURE_MAG_FILTER, glScaleMode); } -static int -GLES2_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture) +static int GLES2_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture) { - GLES2_RenderData *data = (GLES2_RenderData *) renderer->driverdata; + GLES2_RenderData *data = (GLES2_RenderData *)renderer->driverdata; GLES2_TextureData *texturedata = NULL; GLenum status; data->drawstate.viewport_dirty = SDL_TRUE; - if (texture == NULL) { + if (!texture) { data->glBindFramebuffer(GL_FRAMEBUFFER, data->window_framebuffer); } else { - texturedata = (GLES2_TextureData *) texture->driverdata; + texturedata = (GLES2_TextureData *)texture->driverdata; data->glBindFramebuffer(GL_FRAMEBUFFER, texturedata->fbo->FBO); /* TODO: check if texture pixel format allows this operation */ data->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texturedata->texture_type, texturedata->texture, 0); @@ -1798,8 +1859,7 @@ GLES2_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture) return 0; } -static void -GLES2_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture) +static void GLES2_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture) { GLES2_RenderData *data = (GLES2_RenderData *)renderer->driverdata; GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata; @@ -1816,24 +1876,25 @@ GLES2_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture) /* Destroy the texture */ if (tdata) { data->glDeleteTextures(1, &tdata->texture); +#if SDL_HAVE_YUV if (tdata->texture_v) { data->glDeleteTextures(1, &tdata->texture_v); } if (tdata->texture_u) { data->glDeleteTextures(1, &tdata->texture_u); } +#endif SDL_free(tdata->pixel_data); SDL_free(tdata); texture->driverdata = NULL; } } -static int -GLES2_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, - Uint32 pixel_format, void * pixels, int pitch) +static int GLES2_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect, + Uint32 pixel_format, void *pixels, int pitch) { GLES2_RenderData *data = (GLES2_RenderData *)renderer->driverdata; - Uint32 temp_format = renderer->target ? renderer->target->format : SDL_PIXELFORMAT_ABGR8888; + Uint32 temp_format = renderer->target ? renderer->target->format : SDL_PIXELFORMAT_RGBA32; size_t buflen; void *temp_pixels; int temp_pitch; @@ -1842,9 +1903,9 @@ GLES2_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, int status; temp_pitch = rect->w * SDL_BYTESPERPIXEL(temp_format); - buflen = rect->h * temp_pitch; + buflen = (size_t)rect->h * temp_pitch; if (buflen == 0) { - return 0; /* nothing to do. */ + return 0; /* nothing to do. */ } temp_pixels = SDL_malloc(buflen); @@ -1854,7 +1915,7 @@ GLES2_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, SDL_GetRendererOutputSize(renderer, &w, &h); - data->glReadPixels(rect->x, renderer->target ? rect->y : (h-rect->y)-rect->h, + data->glReadPixels(rect->x, renderer->target ? rect->y : (h - rect->y) - rect->h, rect->w, rect->h, GL_RGBA, GL_UNSIGNED_BYTE, temp_pixels); if (GL_CheckError("glReadPixels()", renderer) < 0) { return -1; @@ -1864,8 +1925,8 @@ GLES2_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, if (!renderer->target) { SDL_bool isstack; length = rect->w * SDL_BYTESPERPIXEL(temp_format); - src = (Uint8*)temp_pixels + (rect->h-1)*temp_pitch; - dst = (Uint8*)temp_pixels; + src = (Uint8 *)temp_pixels + (rect->h - 1) * temp_pitch; + dst = (Uint8 *)temp_pixels; tmp = SDL_small_alloc(Uint8, length, &isstack); rows = rect->h / 2; while (rows--) { @@ -1886,26 +1947,60 @@ GLES2_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, return status; } -static void -GLES2_RenderPresent(SDL_Renderer *renderer) +static int GLES2_RenderPresent(SDL_Renderer *renderer) { /* Tell the video driver to swap buffers */ - SDL_GL_SwapWindow(renderer->window); + return SDL_GL_SwapWindowWithResult(renderer->window); } +static int GLES2_SetVSync(SDL_Renderer *renderer, const int vsync) +{ + int retval; + if (vsync) { + retval = SDL_GL_SetSwapInterval(1); + } else { + retval = SDL_GL_SetSwapInterval(0); + } + if (retval != 0) { + return retval; + } + if (SDL_GL_GetSwapInterval() != 0) { + renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; + } else { + renderer->info.flags &= ~SDL_RENDERER_PRESENTVSYNC; + } + return retval; +} /************************************************************************************************* * Bind/unbinding of textures *************************************************************************************************/ -static int GLES2_BindTexture (SDL_Renderer * renderer, SDL_Texture *texture, float *texw, float *texh); -static int GLES2_UnbindTexture (SDL_Renderer * renderer, SDL_Texture *texture); +static int GLES2_BindTexture(SDL_Renderer *renderer, SDL_Texture *texture, float *texw, float *texh); +static int GLES2_UnbindTexture(SDL_Renderer *renderer, SDL_Texture *texture); -static int GLES2_BindTexture (SDL_Renderer * renderer, SDL_Texture *texture, float *texw, float *texh) +static int GLES2_BindTexture(SDL_Renderer *renderer, SDL_Texture *texture, float *texw, float *texh) { GLES2_RenderData *data = (GLES2_RenderData *)renderer->driverdata; GLES2_TextureData *texturedata = (GLES2_TextureData *)texture->driverdata; GLES2_ActivateRenderer(renderer); +#if SDL_HAVE_YUV + if (texturedata->yuv) { + data->glActiveTexture(GL_TEXTURE2); + data->glBindTexture(texturedata->texture_type, texturedata->texture_v); + + data->glActiveTexture(GL_TEXTURE1); + data->glBindTexture(texturedata->texture_type, texturedata->texture_u); + + data->glActiveTexture(GL_TEXTURE0); + } else if (texturedata->nv12) { + data->glActiveTexture(GL_TEXTURE1); + data->glBindTexture(texturedata->texture_type, texturedata->texture_u); + + data->glActiveTexture(GL_TEXTURE0); + } +#endif + data->glBindTexture(texturedata->texture_type, texturedata->texture); data->drawstate.texture = texture; @@ -1919,7 +2014,7 @@ static int GLES2_BindTexture (SDL_Renderer * renderer, SDL_Texture *texture, flo return 0; } -static int GLES2_UnbindTexture (SDL_Renderer * renderer, SDL_Texture *texture) +static int GLES2_UnbindTexture(SDL_Renderer *renderer, SDL_Texture *texture) { GLES2_RenderData *data = (GLES2_RenderData *)renderer->driverdata; GLES2_TextureData *texturedata = (GLES2_TextureData *)texture->driverdata; @@ -1931,25 +2026,14 @@ static int GLES2_UnbindTexture (SDL_Renderer * renderer, SDL_Texture *texture) return 0; } - /************************************************************************************************* * Renderer instantiation * *************************************************************************************************/ -#ifdef ZUNE_HD -#define GL_NVIDIA_PLATFORM_BINARY_NV 0x890B -#endif - - -static SDL_Renderer * -GLES2_CreateRenderer(SDL_Window *window, Uint32 flags) +static SDL_Renderer *GLES2_CreateRenderer(SDL_Window *window, Uint32 flags) { SDL_Renderer *renderer; GLES2_RenderData *data; - GLint nFormats; -#ifndef ZUNE_HD - GLboolean hasCompiler; -#endif Uint32 window_flags = 0; /* -Wconditional-uninitialized */ GLint window_framebuffer; GLint value; @@ -1977,7 +2061,7 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags) 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) { + if (SDL_RecreateWindow(window, (window_flags & ~(SDL_WINDOW_VULKAN | SDL_WINDOW_METAL)) | SDL_WINDOW_OPENGL) < 0) { goto error; } } @@ -2021,7 +2105,14 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags) goto error; } -#if __WINRT__ + if (GLES2_CacheShaders(data) < 0) { + SDL_GL_DeleteContext(data->context); + SDL_free(renderer); + SDL_free(data); + goto error; + } + +#ifdef __WINRT__ /* DLudwig, 2013-11-29: ANGLE for WinRT doesn't seem to work unless VSync * is turned on. Not doing so will freeze the screen's contents to that * of the first drawn frame. @@ -2034,7 +2125,7 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags) } else { SDL_GL_SetSwapInterval(0); } - if (SDL_GL_GetSwapInterval() > 0) { + if (SDL_GL_GetSwapInterval() != 0) { renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; } @@ -2051,73 +2142,64 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags) data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value); renderer->info.max_texture_height = value; - /* Determine supported shader formats */ - /* HACK: glGetInteger is broken on the Zune HD's compositor, so we just hardcode this */ -#ifdef ZUNE_HD - nFormats = 1; -#else /* !ZUNE_HD */ - data->glGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &nFormats); - data->glGetBooleanv(GL_SHADER_COMPILER, &hasCompiler); - if (hasCompiler) { - ++nFormats; - } -#endif /* ZUNE_HD */ - data->shader_formats = (GLenum *)SDL_calloc(nFormats, sizeof(GLenum)); - if (!data->shader_formats) { - GLES2_DestroyRenderer(renderer); - SDL_OutOfMemory(); - goto error; - } - data->shader_format_count = nFormats; -#ifdef ZUNE_HD - data->shader_formats[0] = GL_NVIDIA_PLATFORM_BINARY_NV; -#else /* !ZUNE_HD */ - data->glGetIntegerv(GL_SHADER_BINARY_FORMATS, (GLint *)data->shader_formats); - if (hasCompiler) { - data->shader_formats[nFormats - 1] = (GLenum)-1; - } -#endif /* ZUNE_HD */ - +#if USE_VERTEX_BUFFER_OBJECTS /* we keep a few of these and cycle through them, so data can live for a few frames. */ data->glGenBuffers(SDL_arraysize(data->vertex_buffers), data->vertex_buffers); +#endif data->framebuffers = NULL; data->glGetIntegerv(GL_FRAMEBUFFER_BINDING, &window_framebuffer); data->window_framebuffer = (GLuint)window_framebuffer; /* Populate the function pointers for the module */ - renderer->WindowEvent = GLES2_WindowEvent; - renderer->GetOutputSize = GLES2_GetOutputSize; - renderer->SupportsBlendMode = GLES2_SupportsBlendMode; - renderer->CreateTexture = GLES2_CreateTexture; - renderer->UpdateTexture = GLES2_UpdateTexture; - renderer->UpdateTextureYUV = GLES2_UpdateTextureYUV; - renderer->LockTexture = GLES2_LockTexture; - renderer->UnlockTexture = GLES2_UnlockTexture; + renderer->WindowEvent = GLES2_WindowEvent; + renderer->GetOutputSize = GLES2_GetOutputSize; + renderer->SupportsBlendMode = GLES2_SupportsBlendMode; + renderer->CreateTexture = GLES2_CreateTexture; + renderer->UpdateTexture = GLES2_UpdateTexture; +#if SDL_HAVE_YUV + renderer->UpdateTextureYUV = GLES2_UpdateTextureYUV; + renderer->UpdateTextureNV = GLES2_UpdateTextureNV; +#endif + renderer->LockTexture = GLES2_LockTexture; + renderer->UnlockTexture = GLES2_UnlockTexture; renderer->SetTextureScaleMode = GLES2_SetTextureScaleMode; - renderer->SetRenderTarget = GLES2_SetRenderTarget; - renderer->QueueSetViewport = GLES2_QueueSetViewport; - renderer->QueueSetDrawColor = GLES2_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */ - renderer->QueueDrawPoints = GLES2_QueueDrawPoints; - renderer->QueueDrawLines = GLES2_QueueDrawPoints; /* lines and points queue vertices the same way. */ - renderer->QueueFillRects = GLES2_QueueFillRects; - renderer->QueueCopy = GLES2_QueueCopy; - renderer->QueueCopyEx = GLES2_QueueCopyEx; - renderer->RunCommandQueue = GLES2_RunCommandQueue; - renderer->RenderReadPixels = GLES2_RenderReadPixels; - renderer->RenderPresent = GLES2_RenderPresent; - renderer->DestroyTexture = GLES2_DestroyTexture; - renderer->DestroyRenderer = GLES2_DestroyRenderer; - renderer->GL_BindTexture = GLES2_BindTexture; - renderer->GL_UnbindTexture = GLES2_UnbindTexture; - + renderer->SetRenderTarget = GLES2_SetRenderTarget; + renderer->QueueSetViewport = GLES2_QueueSetViewport; + renderer->QueueSetDrawColor = GLES2_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */ + renderer->QueueDrawPoints = GLES2_QueueDrawPoints; + renderer->QueueDrawLines = GLES2_QueueDrawLines; + renderer->QueueGeometry = GLES2_QueueGeometry; + renderer->RunCommandQueue = GLES2_RunCommandQueue; + renderer->RenderReadPixels = GLES2_RenderReadPixels; + renderer->RenderPresent = GLES2_RenderPresent; + renderer->DestroyTexture = GLES2_DestroyTexture; + renderer->DestroyRenderer = GLES2_DestroyRenderer; + renderer->SetVSync = GLES2_SetVSync; + renderer->GL_BindTexture = GLES2_BindTexture; + renderer->GL_UnbindTexture = GLES2_UnbindTexture; +#if SDL_HAVE_YUV renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_YV12; renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_IYUV; renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_NV12; renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_NV21; -#ifdef GL_TEXTURE_EXTERNAL_OES - renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_EXTERNAL_OES; #endif +#ifdef GL_TEXTURE_EXTERNAL_OES + if (GLES2_CacheShader(data, GLES2_SHADER_FRAGMENT_TEXTURE_EXTERNAL_OES, GL_FRAGMENT_SHADER)) { + renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_EXTERNAL_OES; + } +#endif + + renderer->rect_index_order[0] = 0; + renderer->rect_index_order[1] = 1; + renderer->rect_index_order[2] = 3; + renderer->rect_index_order[3] = 1; + renderer->rect_index_order[4] = 3; + renderer->rect_index_order[5] = 2; + + if (SDL_GL_ExtensionSupported("GL_EXT_blend_minmax")) { + data->GL_EXT_blend_minmax_supported = SDL_TRUE; + } /* Set up parameters for rendering */ data->glActiveTexture(GL_TEXTURE0); @@ -2125,12 +2207,12 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags) data->glPixelStorei(GL_UNPACK_ALIGNMENT, 1); data->glEnableVertexAttribArray(GLES2_ATTRIBUTE_POSITION); + data->glEnableVertexAttribArray(GLES2_ATTRIBUTE_COLOR); data->glDisableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD); data->glClearColor(1.0f, 1.0f, 1.0f, 1.0f); data->drawstate.blend = SDL_BLENDMODE_INVALID; - data->drawstate.color = 0xFFFFFFFF; data->drawstate.clear_color = 0xFFFFFFFF; data->drawstate.projection[3][0] = -1.0f; data->drawstate.projection[3][3] = 1.0f; @@ -2152,21 +2234,17 @@ error: SDL_RenderDriver GLES2_RenderDriver = { GLES2_CreateRenderer, - { - "opengles2", - (SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE), - 4, - { - SDL_PIXELFORMAT_ARGB8888, - SDL_PIXELFORMAT_ABGR8888, - SDL_PIXELFORMAT_RGB888, - SDL_PIXELFORMAT_BGR888 - }, - 0, - 0 - } + { "opengles2", + (SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE), + 4, + { SDL_PIXELFORMAT_RGBA32, + SDL_PIXELFORMAT_BGRA32, + SDL_PIXELFORMAT_BGRX32, + SDL_PIXELFORMAT_RGBX32 }, + 0, + 0 } }; -#endif /* SDL_VIDEO_RENDER_OGL_ES2 && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_OGL_ES2 */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/render/opengles2/SDL_shaders_gles2.c b/SDL2-2.30.5/src/render/opengles2/SDL_shaders_gles2.c new file mode 100644 index 0000000..9a434f4 --- /dev/null +++ b/SDL2-2.30.5/src/render/opengles2/SDL_shaders_gles2.c @@ -0,0 +1,449 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#if SDL_VIDEO_RENDER_OGL_ES2 + +#include "SDL_hints.h" +#include "SDL_video.h" +#include "SDL_opengles2.h" +#include "SDL_shaders_gles2.h" +#include "SDL_stdinc.h" + +/* *INDENT-OFF* */ /* clang-format off */ + +/************************************************************************************************* + * Vertex/fragment shader source * + *************************************************************************************************/ + +static const char GLES2_Fragment_Include_Best_Texture_Precision[] = \ +"#ifdef GL_FRAGMENT_PRECISION_HIGH\n" \ +"#define SDL_TEXCOORD_PRECISION highp\n" \ +"#else\n" \ +"#define SDL_TEXCOORD_PRECISION mediump\n" \ +"#endif\n" \ +"\n" \ +"precision mediump float;\n" \ +"\n" \ +; + +static const char GLES2_Fragment_Include_Medium_Texture_Precision[] = \ +"#define SDL_TEXCOORD_PRECISION mediump\n" \ +"precision mediump float;\n" \ +"\n" \ +; + +static const char GLES2_Fragment_Include_High_Texture_Precision[] = \ +"#define SDL_TEXCOORD_PRECISION highp\n" \ +"precision mediump float;\n" \ +"\n" \ +; + +static const char GLES2_Fragment_Include_Undef_Precision[] = \ +"#define mediump\n" \ +"#define highp\n" \ +"#define lowp\n" \ +"#define SDL_TEXCOORD_PRECISION\n" \ +"\n" \ +; + +static const char GLES2_Vertex_Default[] = \ +"uniform mat4 u_projection;\n" \ +"attribute vec2 a_position;\n" \ +"attribute vec4 a_color;\n" \ +"attribute vec2 a_texCoord;\n" \ +"varying vec2 v_texCoord;\n" \ +"varying vec4 v_color;\n" \ +"\n" \ +"void main()\n" \ +"{\n" \ +" v_texCoord = a_texCoord;\n" \ +" gl_Position = u_projection * vec4(a_position, 0.0, 1.0);\n" \ +" gl_PointSize = 1.0;\n" \ +" v_color = a_color;\n" \ +"}\n" \ +; + +static const char GLES2_Fragment_Solid[] = \ +"varying mediump vec4 v_color;\n" \ +"\n" \ +"void main()\n" \ +"{\n" \ +" gl_FragColor = v_color;\n" \ +"}\n" \ +; + +static const char GLES2_Fragment_TextureABGR[] = \ +"uniform sampler2D u_texture;\n" \ +"varying mediump vec4 v_color;\n" \ +"varying SDL_TEXCOORD_PRECISION vec2 v_texCoord;\n" \ +"\n" \ +"void main()\n" \ +"{\n" \ +" gl_FragColor = texture2D(u_texture, v_texCoord);\n" \ +" gl_FragColor *= v_color;\n" \ +"}\n" \ +; + +/* ARGB to ABGR conversion */ +static const char GLES2_Fragment_TextureARGB[] = \ +"uniform sampler2D u_texture;\n" \ +"varying mediump vec4 v_color;\n" \ +"varying SDL_TEXCOORD_PRECISION vec2 v_texCoord;\n" \ +"\n" \ +"void main()\n" \ +"{\n" \ +" mediump vec4 abgr = texture2D(u_texture, v_texCoord);\n" \ +" gl_FragColor = abgr;\n" \ +" gl_FragColor.r = abgr.b;\n" \ +" gl_FragColor.b = abgr.r;\n" \ +" gl_FragColor *= v_color;\n" \ +"}\n" \ +; + +/* RGB to ABGR conversion */ +static const char GLES2_Fragment_TextureRGB[] = \ +"uniform sampler2D u_texture;\n" \ +"varying mediump vec4 v_color;\n" \ +"varying SDL_TEXCOORD_PRECISION vec2 v_texCoord;\n" \ +"\n" \ +"void main()\n" \ +"{\n" \ +" mediump vec4 abgr = texture2D(u_texture, v_texCoord);\n" \ +" gl_FragColor = abgr;\n" \ +" gl_FragColor.r = abgr.b;\n" \ +" gl_FragColor.b = abgr.r;\n" \ +" gl_FragColor.a = 1.0;\n" \ +" gl_FragColor *= v_color;\n" \ +"}\n" \ +; + +/* BGR to ABGR conversion */ +static const char GLES2_Fragment_TextureBGR[] = \ +"uniform sampler2D u_texture;\n" \ +"varying mediump vec4 v_color;\n" \ +"varying SDL_TEXCOORD_PRECISION vec2 v_texCoord;\n" \ +"\n" \ +"void main()\n" \ +"{\n" \ +" mediump vec4 abgr = texture2D(u_texture, v_texCoord);\n" \ +" gl_FragColor = abgr;\n" \ +" gl_FragColor.a = 1.0;\n" \ +" gl_FragColor *= v_color;\n" \ +"}\n" \ +; + +#if SDL_HAVE_YUV + +#define JPEG_SHADER_CONSTANTS \ +"// YUV offset \n" \ +"const vec3 offset = vec3(0, -0.501960814, -0.501960814);\n" \ +"\n" \ +"// RGB coefficients \n" \ +"const mat3 matrix = mat3( 1, 1, 1,\n" \ +" 0, -0.3441, 1.772,\n" \ +" 1.402, -0.7141, 0);\n" \ +"\n" \ + +#define BT601_SHADER_CONSTANTS \ +"// YUV offset \n" \ +"const vec3 offset = vec3(-0.0627451017, -0.501960814, -0.501960814);\n" \ +"\n" \ +"// RGB coefficients \n" \ +"const mat3 matrix = mat3( 1.1644, 1.1644, 1.1644,\n" \ +" 0, -0.3918, 2.0172,\n" \ +" 1.596, -0.813, 0);\n" \ +"\n" \ + +#define BT709_SHADER_CONSTANTS \ +"// YUV offset \n" \ +"const vec3 offset = vec3(-0.0627451017, -0.501960814, -0.501960814);\n" \ +"\n" \ +"// RGB coefficients \n" \ +"const mat3 matrix = mat3( 1.1644, 1.1644, 1.1644,\n" \ +" 0, -0.2132, 2.1124,\n" \ +" 1.7927, -0.5329, 0);\n" \ +"\n" \ + + +#define YUV_SHADER_PROLOGUE \ +"uniform sampler2D u_texture;\n" \ +"uniform sampler2D u_texture_u;\n" \ +"uniform sampler2D u_texture_v;\n" \ +"varying mediump vec4 v_color;\n" \ +"varying SDL_TEXCOORD_PRECISION vec2 v_texCoord;\n" \ +"\n" \ + +#define YUV_SHADER_BODY \ +"void main()\n" \ +"{\n" \ +" mediump vec3 yuv;\n" \ +" lowp vec3 rgb;\n" \ +"\n" \ +" // Get the YUV values \n" \ +" yuv.x = texture2D(u_texture, v_texCoord).r;\n" \ +" yuv.y = texture2D(u_texture_u, v_texCoord).r;\n" \ +" yuv.z = texture2D(u_texture_v, v_texCoord).r;\n" \ +"\n" \ +" // Do the color transform \n" \ +" yuv += offset;\n" \ +" rgb = matrix * yuv;\n" \ +"\n" \ +" // That was easy. :) \n" \ +" gl_FragColor = vec4(rgb, 1);\n" \ +" gl_FragColor *= v_color;\n" \ +"}" \ + +#define NV12_RA_SHADER_BODY \ +"void main()\n" \ +"{\n" \ +" mediump vec3 yuv;\n" \ +" lowp vec3 rgb;\n" \ +"\n" \ +" // Get the YUV values \n" \ +" yuv.x = texture2D(u_texture, v_texCoord).r;\n" \ +" yuv.yz = texture2D(u_texture_u, v_texCoord).ra;\n" \ +"\n" \ +" // Do the color transform \n" \ +" yuv += offset;\n" \ +" rgb = matrix * yuv;\n" \ +"\n" \ +" // That was easy. :) \n" \ +" gl_FragColor = vec4(rgb, 1);\n" \ +" gl_FragColor *= v_color;\n" \ +"}" \ + +#define NV12_RG_SHADER_BODY \ +"void main()\n" \ +"{\n" \ +" mediump vec3 yuv;\n" \ +" lowp vec3 rgb;\n" \ +"\n" \ +" // Get the YUV values \n" \ +" yuv.x = texture2D(u_texture, v_texCoord).r;\n" \ +" yuv.yz = texture2D(u_texture_u, v_texCoord).rg;\n" \ +"\n" \ +" // Do the color transform \n" \ +" yuv += offset;\n" \ +" rgb = matrix * yuv;\n" \ +"\n" \ +" // That was easy. :) \n" \ +" gl_FragColor = vec4(rgb, 1);\n" \ +" gl_FragColor *= v_color;\n" \ +"}" \ + +#define NV21_SHADER_BODY \ +"void main()\n" \ +"{\n" \ +" mediump vec3 yuv;\n" \ +" lowp vec3 rgb;\n" \ +"\n" \ +" // Get the YUV values \n" \ +" yuv.x = texture2D(u_texture, v_texCoord).r;\n" \ +" yuv.yz = texture2D(u_texture_u, v_texCoord).ar;\n" \ +"\n" \ +" // Do the color transform \n" \ +" yuv += offset;\n" \ +" rgb = matrix * yuv;\n" \ +"\n" \ +" // That was easy. :) \n" \ +" gl_FragColor = vec4(rgb, 1);\n" \ +" gl_FragColor *= v_color;\n" \ +"}" \ + +/* YUV to ABGR conversion */ +static const char GLES2_Fragment_TextureYUVJPEG[] = \ + YUV_SHADER_PROLOGUE \ + JPEG_SHADER_CONSTANTS \ + YUV_SHADER_BODY \ +; +static const char GLES2_Fragment_TextureYUVBT601[] = \ + YUV_SHADER_PROLOGUE \ + BT601_SHADER_CONSTANTS \ + YUV_SHADER_BODY \ +; +static const char GLES2_Fragment_TextureYUVBT709[] = \ + YUV_SHADER_PROLOGUE \ + BT709_SHADER_CONSTANTS \ + YUV_SHADER_BODY \ +; + +/* NV12 to ABGR conversion */ +static const char GLES2_Fragment_TextureNV12JPEG[] = \ + YUV_SHADER_PROLOGUE \ + JPEG_SHADER_CONSTANTS \ + NV12_RA_SHADER_BODY \ +; +static const char GLES2_Fragment_TextureNV12BT601_RA[] = \ + YUV_SHADER_PROLOGUE \ + BT601_SHADER_CONSTANTS \ + NV12_RA_SHADER_BODY \ +; +static const char GLES2_Fragment_TextureNV12BT601_RG[] = \ + YUV_SHADER_PROLOGUE \ + BT601_SHADER_CONSTANTS \ + NV12_RG_SHADER_BODY \ +; +static const char GLES2_Fragment_TextureNV12BT709_RA[] = \ + YUV_SHADER_PROLOGUE \ + BT709_SHADER_CONSTANTS \ + NV12_RA_SHADER_BODY \ +; +static const char GLES2_Fragment_TextureNV12BT709_RG[] = \ + YUV_SHADER_PROLOGUE \ + BT709_SHADER_CONSTANTS \ + NV12_RG_SHADER_BODY \ +; + +/* NV21 to ABGR conversion */ +static const char GLES2_Fragment_TextureNV21JPEG[] = \ + YUV_SHADER_PROLOGUE \ + JPEG_SHADER_CONSTANTS \ + NV21_SHADER_BODY \ +; +static const char GLES2_Fragment_TextureNV21BT601[] = \ + YUV_SHADER_PROLOGUE \ + BT601_SHADER_CONSTANTS \ + NV21_SHADER_BODY \ +; +static const char GLES2_Fragment_TextureNV21BT709[] = \ + YUV_SHADER_PROLOGUE \ + BT709_SHADER_CONSTANTS \ + NV21_SHADER_BODY \ +; +#endif + +/* Custom Android video format texture */ +static const char GLES2_Fragment_TextureExternalOES_Prologue[] = \ +"#extension GL_OES_EGL_image_external : require\n" \ +"\n" \ +; +static const char GLES2_Fragment_TextureExternalOES[] = \ +"uniform samplerExternalOES u_texture;\n" \ +"varying mediump vec4 v_color;\n" \ +"varying SDL_TEXCOORD_PRECISION vec2 v_texCoord;\n" \ +"\n" \ +"void main()\n" \ +"{\n" \ +" gl_FragColor = texture2D(u_texture, v_texCoord);\n" \ +" gl_FragColor *= v_color;\n" \ +"}\n" \ +; + +/* *INDENT-ON* */ /* clang-format on */ + +/************************************************************************************************* + * Shader selector * + *************************************************************************************************/ + +const char *GLES2_GetShaderPrologue(GLES2_ShaderType type) +{ + switch (type) { + case GLES2_SHADER_FRAGMENT_TEXTURE_EXTERNAL_OES: + return GLES2_Fragment_TextureExternalOES_Prologue; + default: + return ""; + } +} + +const char *GLES2_GetShaderInclude(GLES2_ShaderIncludeType type) +{ + switch (type) { + case GLES2_SHADER_FRAGMENT_INCLUDE_UNDEF_PRECISION: + return GLES2_Fragment_Include_Undef_Precision; + case GLES2_SHADER_FRAGMENT_INCLUDE_BEST_TEXCOORD_PRECISION: + return GLES2_Fragment_Include_Best_Texture_Precision; + case GLES2_SHADER_FRAGMENT_INCLUDE_MEDIUM_TEXCOORD_PRECISION: + return GLES2_Fragment_Include_Medium_Texture_Precision; + case GLES2_SHADER_FRAGMENT_INCLUDE_HIGH_TEXCOORD_PRECISION: + return GLES2_Fragment_Include_High_Texture_Precision; + default: + return ""; + } +} + +GLES2_ShaderIncludeType GLES2_GetTexCoordPrecisionEnumFromHint(void) +{ + const char *texcoord_hint = SDL_GetHint("SDL_RENDER_OPENGLES2_TEXCOORD_PRECISION"); + GLES2_ShaderIncludeType value = GLES2_SHADER_FRAGMENT_INCLUDE_BEST_TEXCOORD_PRECISION; + if (texcoord_hint) { + if (SDL_strcmp(texcoord_hint, "undefined") == 0) { + return GLES2_SHADER_FRAGMENT_INCLUDE_UNDEF_PRECISION; + } + if (SDL_strcmp(texcoord_hint, "high") == 0) { + return GLES2_SHADER_FRAGMENT_INCLUDE_HIGH_TEXCOORD_PRECISION; + } + if (SDL_strcmp(texcoord_hint, "medium") == 0) { + return GLES2_SHADER_FRAGMENT_INCLUDE_MEDIUM_TEXCOORD_PRECISION; + } + } + return value; +} + +const char *GLES2_GetShader(GLES2_ShaderType type) +{ + switch (type) { + case GLES2_SHADER_VERTEX_DEFAULT: + return GLES2_Vertex_Default; + case GLES2_SHADER_FRAGMENT_SOLID: + return GLES2_Fragment_Solid; + case GLES2_SHADER_FRAGMENT_TEXTURE_ABGR: + return GLES2_Fragment_TextureABGR; + case GLES2_SHADER_FRAGMENT_TEXTURE_ARGB: + return GLES2_Fragment_TextureARGB; + case GLES2_SHADER_FRAGMENT_TEXTURE_RGB: + return GLES2_Fragment_TextureRGB; + case GLES2_SHADER_FRAGMENT_TEXTURE_BGR: + return GLES2_Fragment_TextureBGR; +#if SDL_HAVE_YUV + case GLES2_SHADER_FRAGMENT_TEXTURE_YUV_JPEG: + return GLES2_Fragment_TextureYUVJPEG; + case GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT601: + return GLES2_Fragment_TextureYUVBT601; + case GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT709: + return GLES2_Fragment_TextureYUVBT709; + case GLES2_SHADER_FRAGMENT_TEXTURE_NV12_JPEG: + return GLES2_Fragment_TextureNV12JPEG; + case GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RA_BT601: + return GLES2_Fragment_TextureNV12BT601_RA; + case GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RG_BT601: + return GLES2_Fragment_TextureNV12BT601_RG; + case GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RA_BT709: + return GLES2_Fragment_TextureNV12BT709_RA; + case GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RG_BT709: + return GLES2_Fragment_TextureNV12BT709_RG; + case GLES2_SHADER_FRAGMENT_TEXTURE_NV21_JPEG: + return GLES2_Fragment_TextureNV21JPEG; + case GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT601: + return GLES2_Fragment_TextureNV21BT601; + case GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT709: + return GLES2_Fragment_TextureNV21BT709; +#endif + case GLES2_SHADER_FRAGMENT_TEXTURE_EXTERNAL_OES: + return GLES2_Fragment_TextureExternalOES; + default: + return NULL; + } +} + +#endif /* SDL_VIDEO_RENDER_OGL_ES2 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/render/opengles2/SDL_shaders_gles2.h b/SDL2-2.30.5/src/render/opengles2/SDL_shaders_gles2.h new file mode 100644 index 0000000..0be234f --- /dev/null +++ b/SDL2-2.30.5/src/render/opengles2/SDL_shaders_gles2.h @@ -0,0 +1,73 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifndef SDL_shaders_gles2_h_ +#define SDL_shaders_gles2_h_ + +#if SDL_VIDEO_RENDER_OGL_ES2 + +typedef enum +{ + GLES2_SHADER_FRAGMENT_INCLUDE_NONE = 0, + GLES2_SHADER_FRAGMENT_INCLUDE_BEST_TEXCOORD_PRECISION, + GLES2_SHADER_FRAGMENT_INCLUDE_MEDIUM_TEXCOORD_PRECISION, + GLES2_SHADER_FRAGMENT_INCLUDE_HIGH_TEXCOORD_PRECISION, + GLES2_SHADER_FRAGMENT_INCLUDE_UNDEF_PRECISION, + GLES2_SHADER_FRAGMENT_INCLUDE_COUNT +} GLES2_ShaderIncludeType; + +typedef enum +{ + GLES2_SHADER_VERTEX_DEFAULT = 0, + GLES2_SHADER_FRAGMENT_SOLID, + GLES2_SHADER_FRAGMENT_TEXTURE_ABGR, + GLES2_SHADER_FRAGMENT_TEXTURE_ARGB, + GLES2_SHADER_FRAGMENT_TEXTURE_BGR, + GLES2_SHADER_FRAGMENT_TEXTURE_RGB, +#if SDL_HAVE_YUV + GLES2_SHADER_FRAGMENT_TEXTURE_YUV_JPEG, + GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT601, + GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT709, + GLES2_SHADER_FRAGMENT_TEXTURE_NV12_JPEG, + GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RA_BT601, + GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RG_BT601, + GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RA_BT709, + GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RG_BT709, + GLES2_SHADER_FRAGMENT_TEXTURE_NV21_JPEG, + GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT601, + GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT709, +#endif + /* Shaders beyond this point are optional and not cached at render creation */ + GLES2_SHADER_FRAGMENT_TEXTURE_EXTERNAL_OES, + GLES2_SHADER_COUNT +} GLES2_ShaderType; + +extern const char *GLES2_GetShaderPrologue(GLES2_ShaderType type); +extern const char *GLES2_GetShaderInclude(GLES2_ShaderIncludeType type); +extern const char *GLES2_GetShader(GLES2_ShaderType type); +extern GLES2_ShaderIncludeType GLES2_GetTexCoordPrecisionEnumFromHint(void); + +#endif /* SDL_VIDEO_RENDER_OGL_ES2 */ + +#endif /* SDL_shaders_gles2_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/render/ps2/SDL_render_ps2.c b/SDL2-2.30.5/src/render/ps2/SDL_render_ps2.c new file mode 100644 index 0000000..ec17323 --- /dev/null +++ b/SDL2-2.30.5/src/render/ps2/SDL_render_ps2.c @@ -0,0 +1,712 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#if SDL_VIDEO_RENDER_PS2 + +#include "../SDL_sysrender.h" +#include "SDL_hints.h" + +#include +#include +#include +#include +#include + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeclaration-after-statement" +#include +#pragma GCC diagnostic pop + +/* turn black GS Screen */ +#define GS_BLACK GS_SETREG_RGBA(0x00, 0x00, 0x00, 0x80) +/* Size of Persistent drawbuffer (Single Buffered) */ +#define RENDER_QUEUE_PER_POOLSIZE 1024 * 256 // 256K of persistent renderqueue +/* Size of Oneshot drawbuffer (Double Buffered, so it uses this size * 2) */ +#define RENDER_QUEUE_OS_POOLSIZE 1024 * 1024 * 2 // 2048K of oneshot renderqueue + +typedef struct +{ + GSGLOBAL *gsGlobal; + uint64_t drawColor; + SDL_Rect *viewport; + int32_t vsync_callback_id; + uint8_t vsync; /* 0 (Disabled), 1 (Enabled), 2 (Dynamic) */ +} PS2_RenderData; + +static int vsync_sema_id = 0; + +/* PRIVATE METHODS */ +static int vsync_handler() +{ + iSignalSema(vsync_sema_id); + + ExitHandler(); + return 0; +} + +/* Copy of gsKit_sync_flip, but without the 'flip' */ +static void gsKit_sync(GSGLOBAL *gsGlobal) +{ + if (!gsGlobal->FirstFrame) { + WaitSema(vsync_sema_id); + } + while (PollSema(vsync_sema_id) >= 0) + ; +} + +/* Copy of gsKit_sync_flip, but without the 'sync' */ +static void gsKit_flip(GSGLOBAL *gsGlobal) +{ + if (!gsGlobal->FirstFrame) { + if (gsGlobal->DoubleBuffering == GS_SETTING_ON) { + GS_SET_DISPFB2(gsGlobal->ScreenBuffer[gsGlobal->ActiveBuffer & 1] / 8192, + gsGlobal->Width / 64, gsGlobal->PSM, 0, 0); + + gsGlobal->ActiveBuffer ^= 1; + } + } + + gsKit_setactive(gsGlobal); +} + +static int PixelFormatToPS2PSM(Uint32 format) +{ + switch (format) { + case SDL_PIXELFORMAT_ABGR1555: + return GS_PSM_CT16; + default: + return GS_PSM_CT32; + } +} + +static void PS2_WindowEvent(SDL_Renderer *renderer, const SDL_WindowEvent *event) +{ +} + +static int PS2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) +{ + GSTEXTURE *ps2_tex = (GSTEXTURE *)SDL_calloc(1, sizeof(GSTEXTURE)); + + if (!ps2_tex) { + return SDL_OutOfMemory(); + } + + ps2_tex->Width = texture->w; + ps2_tex->Height = texture->h; + ps2_tex->PSM = PixelFormatToPS2PSM(texture->format); + ps2_tex->Mem = memalign(128, gsKit_texture_size_ee(ps2_tex->Width, ps2_tex->Height, ps2_tex->PSM)); + + if (!ps2_tex->Mem) { + SDL_free(ps2_tex); + return SDL_OutOfMemory(); + } + + texture->driverdata = ps2_tex; + + return 0; +} + +static int PS2_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *rect, void **pixels, int *pitch) +{ + GSTEXTURE *ps2_texture = (GSTEXTURE *)texture->driverdata; + + *pixels = + (void *)((Uint8 *)ps2_texture->Mem + rect->y * ps2_texture->Width * SDL_BYTESPERPIXEL(texture->format) + + rect->x * SDL_BYTESPERPIXEL(texture->format)); + *pitch = ps2_texture->Width * SDL_BYTESPERPIXEL(texture->format); + return 0; +} + +static void PS2_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture) +{ + GSTEXTURE *ps2_texture = (GSTEXTURE *)texture->driverdata; + PS2_RenderData *data = (PS2_RenderData *)renderer->driverdata; + + gsKit_TexManager_invalidate(data->gsGlobal, ps2_texture); +} + +static int PS2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *rect, const void *pixels, int pitch) +{ + const Uint8 *src; + Uint8 *dst; + int row, length, dpitch; + src = pixels; + + PS2_LockTexture(renderer, texture, rect, (void **)&dst, &dpitch); + length = rect->w * SDL_BYTESPERPIXEL(texture->format); + if (length == pitch && length == dpitch) { + SDL_memcpy(dst, src, length * rect->h); + } else { + for (row = 0; row < rect->h; ++row) { + SDL_memcpy(dst, src, length); + src += pitch; + dst += dpitch; + } + } + + PS2_UnlockTexture(renderer, texture); + + return 0; +} + +static void PS2_SetTextureScaleMode(SDL_Renderer *renderer, SDL_Texture *texture, SDL_ScaleMode scaleMode) +{ + GSTEXTURE *ps2_texture = (GSTEXTURE *)texture->driverdata; + /* + set texture filtering according to scaleMode + suported hint values are nearest (0, default) or linear (1) + gskit scale mode is either GS_FILTER_NEAREST (good for tile-map) + or GS_FILTER_LINEAR (good for scaling) + */ + uint32_t gsKitScaleMode = (scaleMode == SDL_ScaleModeNearest + ? GS_FILTER_NEAREST + : GS_FILTER_LINEAR); + ps2_texture->Filter = gsKitScaleMode; +} + +static int PS2_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture) +{ + return 0; +} + +static int PS2_QueueSetViewport(SDL_Renderer *renderer, SDL_RenderCommand *cmd) +{ + PS2_RenderData *data = (PS2_RenderData *)renderer->driverdata; + const SDL_Rect *viewport = &cmd->data.viewport.rect; + data->viewport = (SDL_Rect *)viewport; + + data->gsGlobal->OffsetX = (int)((2048.0f + (float)viewport->x) * 16.0f); + data->gsGlobal->OffsetY = (int)((2048.0f + (float)viewport->y) * 16.0f); + gsKit_set_scissor(data->gsGlobal, GS_SETREG_SCISSOR(viewport->x, viewport->x + viewport->w, viewport->y, viewport->y + viewport->h)); + + return 0; +} + +static int PS2_QueueSetDrawColor(SDL_Renderer *renderer, SDL_RenderCommand *cmd) +{ + return 0; /* nothing to do in this backend. */ +} + +static int PS2_QueueDrawPoints(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count) +{ + PS2_RenderData *data = (PS2_RenderData *)renderer->driverdata; + GSPRIMPOINT *vertices = (GSPRIMPOINT *)SDL_AllocateRenderVertices(renderer, count * sizeof(GSPRIMPOINT), 4, &cmd->data.draw.first); + uint8_t colorR, colorG, colorB, colorA; + gs_rgbaq rgbaq; + int i; + + if (!vertices) { + return -1; + } + + cmd->data.draw.count = count; + + colorR = cmd->data.draw.r; + colorG = cmd->data.draw.g; + colorB = cmd->data.draw.b; + colorA = cmd->data.draw.a; + rgbaq = color_to_RGBAQ(colorR, colorG, colorB, colorA, 0.0f); + + for (i = 0; i < count; i++, vertices++, points++) { + vertices->xyz2 = vertex_to_XYZ2(data->gsGlobal, points->x, points->y, 0); + vertices->rgbaq = rgbaq; + } + return 0; +} + +static int PS2_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, + const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride, + int num_vertices, const void *indices, int num_indices, int size_indices, + float scale_x, float scale_y) +{ + int i; + int count = indices ? num_indices : num_vertices; + PS2_RenderData *data = (PS2_RenderData *)renderer->driverdata; + + cmd->data.draw.count = count; + size_indices = indices ? size_indices : 0; + + if (texture) { + GSPRIMUVPOINT *vertices = (GSPRIMUVPOINT *) SDL_AllocateRenderVertices(renderer, count * sizeof(GSPRIMUVPOINT), 4, &cmd->data.draw.first); + GSTEXTURE *ps2_tex = (GSTEXTURE *) texture->driverdata; + + if (!vertices) { + return -1; + } + + for (i = 0; i < count; i++) { + int j; + float *xy_; + float *uv_; + SDL_Color col_; + if (size_indices == 4) { + j = ((const Uint32 *)indices)[i]; + } else if (size_indices == 2) { + j = ((const Uint16 *)indices)[i]; + } else if (size_indices == 1) { + j = ((const Uint8 *)indices)[i]; + } else { + j = i; + } + + xy_ = (float *)((char *)xy + j * xy_stride); + col_ = *(SDL_Color *)((char *)color + j * color_stride); + uv_ = (float *)((char *)uv + j * uv_stride); + + vertices->xyz2 = vertex_to_XYZ2(data->gsGlobal, xy_[0] * scale_x, xy_[1] * scale_y, 0); + vertices->rgbaq = color_to_RGBAQ(col_.r, col_.g, col_.b, col_.a, 0); + vertices->uv = vertex_to_UV(ps2_tex, uv_[0] * ps2_tex->Width, uv_[1] * ps2_tex->Height); + + vertices++; + } + + } else { + GSPRIMPOINT *vertices = (GSPRIMPOINT *)SDL_AllocateRenderVertices(renderer, count * sizeof(GSPRIMPOINT), 4, &cmd->data.draw.first); + + if (!vertices) { + return -1; + } + + for (i = 0; i < count; i++) { + int j; + float *xy_; + SDL_Color col_; + if (size_indices == 4) { + j = ((const Uint32 *)indices)[i]; + } else if (size_indices == 2) { + j = ((const Uint16 *)indices)[i]; + } else if (size_indices == 1) { + j = ((const Uint8 *)indices)[i]; + } else { + j = i; + } + + xy_ = (float *)((char *)xy + j * xy_stride); + col_ = *(SDL_Color *)((char *)color + j * color_stride); + + vertices->xyz2 = vertex_to_XYZ2(data->gsGlobal, xy_[0] * scale_x, xy_[1] * scale_y, 0); + vertices->rgbaq = color_to_RGBAQ(col_.r, col_.g, col_.b, col_.a, 0.0f); + + vertices++; + } + } + + return 0; +} + +static int PS2_RenderSetViewPort(SDL_Renderer *renderer, SDL_RenderCommand *cmd) +{ + return 0; /* nothing to do in this backend. */ +} + +static int PS2_RenderSetClipRect(SDL_Renderer *renderer, SDL_RenderCommand *cmd) +{ + PS2_RenderData *data = (PS2_RenderData *)renderer->driverdata; + SDL_Rect *viewport = data->viewport; + + const SDL_Rect *rect = &cmd->data.cliprect.rect; + + if (cmd->data.cliprect.enabled) { + /* We need to do it relative to saved viewport */ + viewport->x += rect->x; + viewport->y += rect->y; + viewport->w = SDL_min(viewport->w, rect->w); + viewport->h = SDL_min(viewport->h, rect->h); + } + gsKit_set_scissor(data->gsGlobal, GS_SETREG_SCISSOR(viewport->x, viewport->x + viewport->w, viewport->y, viewport->y + viewport->h)); + + return 0; +} + +static int PS2_RenderSetDrawColor(SDL_Renderer *renderer, SDL_RenderCommand *cmd) +{ + int colorR, colorG, colorB, colorA; + + PS2_RenderData *data = (PS2_RenderData *)renderer->driverdata; + + colorR = (cmd->data.color.r); + colorG = (cmd->data.color.g); + colorB = (cmd->data.color.b); + colorA = (cmd->data.color.a); + data->drawColor = GS_SETREG_RGBAQ(colorR, colorG, colorB, colorA, 0x00); + return 0; +} + +static int PS2_RenderClear(SDL_Renderer *renderer, SDL_RenderCommand *cmd) +{ + int colorR, colorG, colorB, colorA, offsetX, offsetY; + SDL_Rect *viewport; + + PS2_RenderData *data = (PS2_RenderData *)renderer->driverdata; + + colorR = (cmd->data.color.r); + colorG = (cmd->data.color.g); + colorB = (cmd->data.color.b); + colorA = (cmd->data.color.a); + + /* Clear the screen, so let's put default viewport */ + gsKit_set_scissor(data->gsGlobal, GS_SCISSOR_RESET); + /* Put back original offset */ + offsetX = data->gsGlobal->OffsetX; + offsetY = data->gsGlobal->OffsetY; + data->gsGlobal->OffsetX = (int)(2048.0f * 16.0f); + data->gsGlobal->OffsetY = (int)(2048.0f * 16.0f); + gsKit_clear(data->gsGlobal, GS_SETREG_RGBAQ(colorR, colorG, colorB, colorA, 0x00)); + + /* Put back original offset */ + data->gsGlobal->OffsetX = offsetX; + data->gsGlobal->OffsetY = offsetY; + + // /* Put back view port */ + viewport = data->viewport; + gsKit_set_scissor(data->gsGlobal, GS_SETREG_SCISSOR(viewport->x, viewport->x + viewport->w, viewport->y, viewport->y + viewport->h)); + + return 0; +} + +static void PS2_SetBlendMode(PS2_RenderData *data, int blendMode) +{ +#define A_COLOR_SOURCE 0 +#define A_COLOR_DEST 1 +#define A_COLOR_NULL 2 +#define A_ALPHA_SOURCE 0 +#define A_ALPHA_DEST 1 +#define A_ALPHA_FIX 2 + + switch (blendMode) { + case SDL_BLENDMODE_NONE: + { + data->gsGlobal->PrimAlphaEnable = GS_SETTING_OFF; + break; + } + case SDL_BLENDMODE_BLEND: + { + gsKit_set_primalpha(data->gsGlobal, GS_SETREG_ALPHA(A_COLOR_SOURCE, A_COLOR_DEST, A_ALPHA_SOURCE, A_COLOR_DEST, 0), 0); + data->gsGlobal->PrimAlphaEnable = GS_SETTING_ON; + break; + } + case SDL_BLENDMODE_ADD: + { + gsKit_set_primalpha(data->gsGlobal, GS_SETREG_ALPHA(A_COLOR_SOURCE, A_COLOR_NULL, A_ALPHA_FIX, A_COLOR_DEST, 0x80), 0); + data->gsGlobal->PrimAlphaEnable = GS_SETTING_ON; + break; + } + case SDL_BLENDMODE_MUL: + case SDL_BLENDMODE_MOD: + { + /* We don't fully support MOD and MUL, however this is the best we can do */ + gsKit_set_primalpha(data->gsGlobal, GS_SETREG_ALPHA(A_COLOR_DEST, A_COLOR_NULL, A_ALPHA_SOURCE, A_COLOR_SOURCE, 0x80), 0); + data->gsGlobal->PrimAlphaEnable = GS_SETTING_ON; + break; + } + } +} + +static int PS2_RenderGeometry(SDL_Renderer *renderer, void *vertices, SDL_RenderCommand *cmd) +{ + PS2_RenderData *data = (PS2_RenderData *)renderer->driverdata; + const size_t count = cmd->data.draw.count; + + PS2_SetBlendMode(data, cmd->data.draw.blend); + + if (cmd->data.draw.texture) { + const GSPRIMUVPOINT *verts = (GSPRIMUVPOINT *) (vertices + cmd->data.draw.first); + GSTEXTURE *ps2_tex = (GSTEXTURE *)cmd->data.draw.texture->driverdata; + + gsKit_TexManager_bind(data->gsGlobal, ps2_tex); + gsKit_prim_list_triangle_goraud_texture_uv_3d(data->gsGlobal, ps2_tex, count, verts); + } else { + const GSPRIMPOINT *verts = (GSPRIMPOINT *)(vertices + cmd->data.draw.first); + gsKit_prim_list_triangle_gouraud_3d(data->gsGlobal, count, verts); + } + + return 0; +} + +int PS2_RenderLines(SDL_Renderer *renderer, void *vertices, SDL_RenderCommand *cmd) +{ + PS2_RenderData *data = (PS2_RenderData *)renderer->driverdata; + const size_t count = cmd->data.draw.count; + const GSPRIMPOINT *verts = (GSPRIMPOINT *)(vertices + cmd->data.draw.first); + + PS2_SetBlendMode(data, cmd->data.draw.blend); + gsKit_prim_list_line_goraud_3d(data->gsGlobal, count, verts); + + /* We're done! */ + return 0; +} + +int PS2_RenderPoints(SDL_Renderer *renderer, void *vertices, SDL_RenderCommand *cmd) +{ + PS2_RenderData *data = (PS2_RenderData *)renderer->driverdata; + const size_t count = cmd->data.draw.count; + const GSPRIMPOINT *verts = (GSPRIMPOINT *)(vertices + cmd->data.draw.first); + + PS2_SetBlendMode(data, cmd->data.draw.blend); + gsKit_prim_list_points(data->gsGlobal, count, verts); + + /* We're done! */ + return 0; +} + +static int PS2_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize) +{ + while (cmd) { + switch (cmd->command) { + case SDL_RENDERCMD_SETVIEWPORT: + { + PS2_RenderSetViewPort(renderer, cmd); + /* FIXME: We need to update the clip rect too, see https://github.com/libsdl-org/SDL/issues/9094 */ + break; + } + case SDL_RENDERCMD_SETCLIPRECT: + { + PS2_RenderSetClipRect(renderer, cmd); + break; + } + case SDL_RENDERCMD_SETDRAWCOLOR: + { + PS2_RenderSetDrawColor(renderer, cmd); + break; + } + case SDL_RENDERCMD_CLEAR: + { + PS2_RenderClear(renderer, cmd); + break; + } + case SDL_RENDERCMD_DRAW_POINTS: + { + PS2_RenderPoints(renderer, vertices, cmd); + break; + } + case SDL_RENDERCMD_DRAW_LINES: + { + PS2_RenderLines(renderer, vertices, cmd); + break; + } + case SDL_RENDERCMD_FILL_RECTS: /* unused */ + break; + case SDL_RENDERCMD_COPY: /* unused */ + break; + case SDL_RENDERCMD_COPY_EX: /* unused */ + break; + case SDL_RENDERCMD_GEOMETRY: + { + PS2_RenderGeometry(renderer, vertices, cmd); + break; + } + case SDL_RENDERCMD_NO_OP: + break; + } + cmd = cmd->next; + } + return 0; +} + +static int PS2_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect, + Uint32 format, void *pixels, int pitch) +{ + return SDL_Unsupported(); +} + +static int PS2_RenderPresent(SDL_Renderer *renderer) +{ + PS2_RenderData *data = (PS2_RenderData *)renderer->driverdata; + + if (data->gsGlobal->DoubleBuffering == GS_SETTING_OFF) { + if (data->vsync == 2) { // Dynamic + gsKit_sync(data->gsGlobal); + } else if (data->vsync == 1) { + gsKit_vsync_wait(); + } + gsKit_queue_exec(data->gsGlobal); + } else { + gsKit_queue_exec(data->gsGlobal); + gsKit_finish(); + if (data->vsync == 2) { // Dynamic + gsKit_sync(data->gsGlobal); + } else if (data->vsync == 1) { + gsKit_vsync_wait(); + } + gsKit_flip(data->gsGlobal); + } + gsKit_TexManager_nextFrame(data->gsGlobal); + gsKit_clear(data->gsGlobal, GS_BLACK); + return 0; +} + +static void PS2_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture) +{ + GSTEXTURE *ps2_texture = (GSTEXTURE *)texture->driverdata; + PS2_RenderData *data = (PS2_RenderData *)renderer->driverdata; + + if (!data) { + return; + } + + if (!ps2_texture) { + return; + } + + // Free from vram + gsKit_TexManager_free(data->gsGlobal, ps2_texture); + + SDL_free(ps2_texture->Mem); + SDL_free(ps2_texture); + texture->driverdata = NULL; +} + +static void PS2_DestroyRenderer(SDL_Renderer *renderer) +{ + PS2_RenderData *data = (PS2_RenderData *)renderer->driverdata; + + if (data) { + gsKit_clear(data->gsGlobal, GS_BLACK); + gsKit_vram_clear(data->gsGlobal); + gsKit_deinit_global(data->gsGlobal); + gsKit_remove_vsync_handler(data->vsync_callback_id); + + SDL_free(data); + } + + if (vsync_sema_id >= 0) { + DeleteSema(vsync_sema_id); + } + + SDL_free(renderer); +} + +static int PS2_SetVSync(SDL_Renderer *renderer, const int vsync) +{ + PS2_RenderData *data = (PS2_RenderData *)renderer->driverdata; + SDL_bool dynamicVsync = SDL_GetHintBoolean(SDL_HINT_PS2_DYNAMIC_VSYNC, SDL_FALSE); + data->vsync = vsync ? (dynamicVsync ? 2 : 1) : 0; + return 0; +} + +static SDL_Renderer *PS2_CreateRenderer(SDL_Window *window, Uint32 flags) +{ + SDL_Renderer *renderer; + PS2_RenderData *data; + GSGLOBAL *gsGlobal; + ee_sema_t sema; + SDL_bool dynamicVsync; + + renderer = (SDL_Renderer *)SDL_calloc(1, sizeof(*renderer)); + if (!renderer) { + SDL_OutOfMemory(); + return NULL; + } + + data = (PS2_RenderData *)SDL_calloc(1, sizeof(*data)); + if (!data) { + PS2_DestroyRenderer(renderer); + SDL_OutOfMemory(); + return NULL; + } + + /* Specific gsKit init */ + sema.init_count = 0; + sema.max_count = 1; + sema.option = 0; + vsync_sema_id = CreateSema(&sema); + + gsGlobal = gsKit_init_global_custom(RENDER_QUEUE_OS_POOLSIZE, RENDER_QUEUE_PER_POOLSIZE); + + gsGlobal->Mode = GS_MODE_NTSC; + gsGlobal->Height = 448; + + gsGlobal->PSM = GS_PSM_CT24; + gsGlobal->PSMZ = GS_PSMZ_16S; + gsGlobal->ZBuffering = GS_SETTING_OFF; + gsGlobal->DoubleBuffering = GS_SETTING_ON; + gsGlobal->PrimAlphaEnable = GS_SETTING_ON; + gsGlobal->Dithering = GS_SETTING_OFF; + + gsKit_set_primalpha(gsGlobal, GS_SETREG_ALPHA(0, 1, 0, 1, 0), 0); + + dmaKit_init(D_CTRL_RELE_OFF, D_CTRL_MFD_OFF, D_CTRL_STS_UNSPEC, D_CTRL_STD_OFF, D_CTRL_RCYC_8, 1 << DMA_CHANNEL_GIF); + dmaKit_chan_init(DMA_CHANNEL_GIF); + + gsKit_set_clamp(gsGlobal, GS_CMODE_REPEAT); + + gsKit_vram_clear(gsGlobal); + + gsKit_init_screen(gsGlobal); + + gsKit_TexManager_init(gsGlobal); + + data->vsync_callback_id = gsKit_add_vsync_handler(vsync_handler); + + gsKit_mode_switch(gsGlobal, GS_ONESHOT); + + gsKit_clear(gsGlobal, GS_BLACK); + + data->gsGlobal = gsGlobal; + dynamicVsync = SDL_GetHintBoolean(SDL_HINT_PS2_DYNAMIC_VSYNC, SDL_FALSE); + data->vsync = flags & SDL_RENDERER_PRESENTVSYNC ? (dynamicVsync ? 2 : 1) : 0; + + renderer->WindowEvent = PS2_WindowEvent; + renderer->CreateTexture = PS2_CreateTexture; + renderer->UpdateTexture = PS2_UpdateTexture; + renderer->LockTexture = PS2_LockTexture; + renderer->UnlockTexture = PS2_UnlockTexture; + renderer->SetTextureScaleMode = PS2_SetTextureScaleMode; + renderer->SetRenderTarget = PS2_SetRenderTarget; + renderer->QueueSetViewport = PS2_QueueSetViewport; + renderer->QueueSetDrawColor = PS2_QueueSetDrawColor; + renderer->QueueDrawPoints = PS2_QueueDrawPoints; + renderer->QueueDrawLines = PS2_QueueDrawPoints; + renderer->QueueGeometry = PS2_QueueGeometry; + renderer->RunCommandQueue = PS2_RunCommandQueue; + renderer->RenderReadPixels = PS2_RenderReadPixels; + renderer->RenderPresent = PS2_RenderPresent; + renderer->DestroyTexture = PS2_DestroyTexture; + renderer->DestroyRenderer = PS2_DestroyRenderer; + renderer->SetVSync = PS2_SetVSync; + renderer->info = PS2_RenderDriver.info; + renderer->driverdata = data; + renderer->window = window; + + return renderer; +} + +SDL_RenderDriver PS2_RenderDriver = { + .CreateRenderer = PS2_CreateRenderer, + .info = { + .name = "PS2 gsKit", + .flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE, + .num_texture_formats = 2, + .texture_formats = { + [0] = SDL_PIXELFORMAT_ABGR1555, + [1] = SDL_PIXELFORMAT_ABGR8888, + }, + .max_texture_width = 1024, + .max_texture_height = 1024, + } +}; + +#endif /* SDL_VIDEO_RENDER_PS2 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/render/psp/SDL_render_psp.c b/SDL2-2.30.5/src/render/psp/SDL_render_psp.c new file mode 100644 index 0000000..47fab82 --- /dev/null +++ b/SDL2-2.30.5/src/render/psp/SDL_render_psp.c @@ -0,0 +1,1427 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#if SDL_VIDEO_RENDER_PSP + +#include "SDL_hints.h" +#include "../SDL_sysrender.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* PSP renderer implementation, based on the PGE */ + +#define PSP_SCREEN_WIDTH 480 +#define PSP_SCREEN_HEIGHT 272 + +#define PSP_FRAME_BUFFER_WIDTH 512 +#define PSP_FRAME_BUFFER_SIZE (PSP_FRAME_BUFFER_WIDTH * PSP_SCREEN_HEIGHT) + +static unsigned int __attribute__((aligned(16))) DisplayList[262144]; + +#define COL5650(r, g, b, a) ((r >> 3) | ((g >> 2) << 5) | ((b >> 3) << 11)) +#define COL5551(r, g, b, a) ((r >> 3) | ((g >> 3) << 5) | ((b >> 3) << 10) | (a > 0 ? 0x7000 : 0)) +#define COL4444(r, g, b, a) ((r >> 4) | ((g >> 4) << 4) | ((b >> 4) << 8) | ((a >> 4) << 12)) +#define COL8888(r, g, b, a) ((r) | ((g) << 8) | ((b) << 16) | ((a) << 24)) + +/** + * Holds psp specific texture data + * + * Part of a hot-list of textures that are used as render targets + * When short of vram we spill Least-Recently-Used render targets to system memory + */ +typedef struct PSP_TextureData +{ + void *data; /**< Image data. */ + unsigned int size; /**< Size of data in bytes. */ + unsigned int width; /**< Image width. */ + unsigned int height; /**< Image height. */ + unsigned int textureWidth; /**< Texture width (power of two). */ + unsigned int textureHeight; /**< Texture height (power of two). */ + unsigned int bits; /**< Image bits per pixel. */ + unsigned int format; /**< Image format - one of ::pgePixelFormat. */ + unsigned int pitch; + SDL_bool swizzled; /**< Is image swizzled. */ + struct PSP_TextureData *prevhotw; /**< More recently used render target */ + struct PSP_TextureData *nexthotw; /**< Less recently used render target */ +} PSP_TextureData; + +typedef struct +{ + SDL_BlendMode mode; + unsigned int color; + int shadeModel; + SDL_Texture *texture; +} PSP_BlendState; + +typedef struct +{ + void *frontbuffer; /**< main screen buffer */ + void *backbuffer; /**< buffer presented to display */ + SDL_Texture *boundTarget; /**< currently bound rendertarget */ + SDL_bool initialized; /**< is driver initialized */ + SDL_bool displayListAvail; /**< is the display list already initialized for this frame */ + unsigned int psm; /**< format of the display buffers */ + unsigned int bpp; /**< bits per pixel of the main display */ + + SDL_bool vsync; /**< whether we do vsync */ + PSP_BlendState blendState; /**< current blend mode */ + PSP_TextureData *most_recent_target; /**< start of render target LRU double linked list */ + PSP_TextureData *least_recent_target; /**< end of the LRU list */ + + SDL_bool vblank_not_reached; /**< whether vblank wasn't reached */ +} PSP_RenderData; + +typedef struct +{ + float x, y, z; +} VertV; + +typedef struct +{ + float u, v; + float x, y, z; +} VertTV; + +typedef struct +{ + SDL_Color col; + float x, y, z; +} VertCV; + +typedef struct +{ + float u, v; + SDL_Color col; + float x, y, z; +} VertTCV; + +#define PI 3.14159265358979f + +#define radToDeg(x) ((x)*180.f / PI) +#define degToRad(x) ((x)*PI / 180.f) + +static float MathAbs(float x) +{ + float result; + + __asm__ volatile( + "mtv %1, S000\n" + "vabs.s S000, S000\n" + "mfv %0, S000\n" + : "=r"(result) + : "r"(x)); + + return result; +} + +static void MathSincos(float r, float *s, float *c) +{ + __asm__ volatile( + "mtv %2, S002\n" + "vcst.s S003, VFPU_2_PI\n" + "vmul.s S002, S002, S003\n" + "vrot.p C000, S002, [s, c]\n" + "mfv %0, S000\n" + "mfv %1, S001\n" + : "=r"(*s), "=r"(*c) + : "r"(r)); +} + +static void Swap(float *a, float *b) +{ + float n = *a; + *a = *b; + *b = n; +} + +static inline int InVram(void *data) +{ + return data < (void *)0x04200000; +} + +/* Return next power of 2 */ +static int TextureNextPow2(unsigned int w) +{ + unsigned int n = 2; + if (w == 0) { + return 0; + } + + while (w > n) { + n <<= 1; + } + + return n; +} + +static void psp_on_vblank(u32 sub, PSP_RenderData *data) +{ + if (data) { + data->vblank_not_reached = SDL_FALSE; + } +} + +static int PixelFormatToPSPFMT(Uint32 format) +{ + switch (format) { + case SDL_PIXELFORMAT_BGR565: + return GU_PSM_5650; + case SDL_PIXELFORMAT_ABGR1555: + return GU_PSM_5551; + case SDL_PIXELFORMAT_ABGR4444: + return GU_PSM_4444; + case SDL_PIXELFORMAT_ABGR8888: + return GU_PSM_8888; + default: + return GU_PSM_8888; + } +} + +/// SECTION render target LRU management +static void LRUTargetRelink(PSP_TextureData *psp_texture) +{ + if (psp_texture->prevhotw) { + psp_texture->prevhotw->nexthotw = psp_texture->nexthotw; + } + if (psp_texture->nexthotw) { + psp_texture->nexthotw->prevhotw = psp_texture->prevhotw; + } +} + +static void LRUTargetPushFront(PSP_RenderData *data, PSP_TextureData *psp_texture) +{ + psp_texture->nexthotw = data->most_recent_target; + if (data->most_recent_target) { + data->most_recent_target->prevhotw = psp_texture; + } + data->most_recent_target = psp_texture; + if (!data->least_recent_target) { + data->least_recent_target = psp_texture; + } +} + +static void LRUTargetRemove(PSP_RenderData *data, PSP_TextureData *psp_texture) +{ + LRUTargetRelink(psp_texture); + if (data->most_recent_target == psp_texture) { + data->most_recent_target = psp_texture->nexthotw; + } + if (data->least_recent_target == psp_texture) { + data->least_recent_target = psp_texture->prevhotw; + } + psp_texture->prevhotw = NULL; + psp_texture->nexthotw = NULL; +} + +static void LRUTargetBringFront(PSP_RenderData *data, PSP_TextureData *psp_texture) +{ + if (data->most_recent_target == psp_texture) { + return; // nothing to do + } + LRUTargetRemove(data, psp_texture); + LRUTargetPushFront(data, psp_texture); +} + +static void TextureStorageFree(void *storage) +{ + if (InVram(storage)) { + vfree(storage); + } else { + SDL_free(storage); + } +} + +static int TextureSwizzle(PSP_TextureData *psp_texture, void *dst) +{ + int bytewidth, height; + int rowblocks, rowblocksadd; + int i, j; + unsigned int blockaddress = 0; + unsigned int *src = NULL; + unsigned char *data = NULL; + + if (psp_texture->swizzled) { + return 1; + } + + bytewidth = psp_texture->textureWidth * (psp_texture->bits >> 3); + height = psp_texture->size / bytewidth; + + rowblocks = (bytewidth >> 4); + rowblocksadd = (rowblocks - 1) << 7; + + src = (unsigned int *)psp_texture->data; + + data = dst; + if (!data) { + data = SDL_malloc(psp_texture->size); + } + + if (!data) { + return SDL_OutOfMemory(); + } + + for (j = 0; j < height; j++, blockaddress += 16) { + unsigned int *block; + + block = (unsigned int *)&data[blockaddress]; + + for (i = 0; i < rowblocks; i++) { + *block++ = *src++; + *block++ = *src++; + *block++ = *src++; + *block++ = *src++; + block += 28; + } + + if ((j & 0x7) == 0x7) { + blockaddress += rowblocksadd; + } + } + + TextureStorageFree(psp_texture->data); + psp_texture->data = data; + psp_texture->swizzled = SDL_TRUE; + + sceKernelDcacheWritebackRange(psp_texture->data, psp_texture->size); + return 1; +} + +static int TextureUnswizzle(PSP_TextureData *psp_texture, void *dst) +{ + int bytewidth, height; + int widthblocks, heightblocks; + int dstpitch, dstrow; + int blockx, blocky; + int j; + unsigned int *src = NULL; + unsigned char *data = NULL; + unsigned char *ydst = NULL; + + if (!psp_texture->swizzled) { + return 1; + } + + bytewidth = psp_texture->textureWidth * (psp_texture->bits >> 3); + height = psp_texture->size / bytewidth; + + widthblocks = bytewidth / 16; + heightblocks = height / 8; + + dstpitch = (bytewidth - 16) / 4; + dstrow = bytewidth * 8; + + src = (unsigned int *)psp_texture->data; + + data = dst; + + if (!data) { + data = SDL_malloc(psp_texture->size); + } + + if (!data) { + return SDL_OutOfMemory(); + } + + ydst = (unsigned char *)data; + + for (blocky = 0; blocky < heightblocks; ++blocky) { + unsigned char *xdst = ydst; + + for (blockx = 0; blockx < widthblocks; ++blockx) { + unsigned int *block; + + block = (unsigned int *)xdst; + + for (j = 0; j < 8; ++j) { + *(block++) = *(src++); + *(block++) = *(src++); + *(block++) = *(src++); + *(block++) = *(src++); + block += dstpitch; + } + + xdst += 16; + } + + ydst += dstrow; + } + + TextureStorageFree(psp_texture->data); + + psp_texture->data = data; + + psp_texture->swizzled = SDL_FALSE; + + sceKernelDcacheWritebackRange(psp_texture->data, psp_texture->size); + return 1; +} + +static int TextureSpillToSram(PSP_RenderData *data, PSP_TextureData *psp_texture) +{ + // Assumes the texture is in VRAM + if (psp_texture->swizzled) { + // Texture was swizzled in vram, just copy to system memory + void *sdata = SDL_malloc(psp_texture->size); + if (!sdata) { + return SDL_OutOfMemory(); + } + + SDL_memcpy(sdata, psp_texture->data, psp_texture->size); + vfree(psp_texture->data); + psp_texture->data = sdata; + return 0; + } else { + return TextureSwizzle(psp_texture, NULL); // Will realloc in sysram + } +} + +static int TexturePromoteToVram(PSP_RenderData *data, PSP_TextureData *psp_texture, SDL_bool target) +{ + // Assumes texture in sram and a large enough continuous block in vram + void *tdata = vramalloc(psp_texture->size); + if (psp_texture->swizzled && target) { + return TextureUnswizzle(psp_texture, tdata); + } else { + SDL_memcpy(tdata, psp_texture->data, psp_texture->size); + SDL_free(psp_texture->data); + psp_texture->data = tdata; + return 0; + } +} + +static int TextureSpillLRU(PSP_RenderData *data, size_t wanted) +{ + PSP_TextureData *lru = data->least_recent_target; + if (lru) { + if (TextureSpillToSram(data, lru) < 0) { + return -1; + } + LRUTargetRemove(data, lru); + } else { + // Asked to spill but there nothing to spill + return SDL_SetError("Could not spill more VRAM to system memory. VRAM : %dKB,(%dKB), wanted %dKB", vmemavail() / 1024, vlargestblock() / 1024, wanted / 1024); + } + return 0; +} + +static int TextureSpillTargetsForSpace(PSP_RenderData *data, size_t size) +{ + while (vlargestblock() < size) { + if (TextureSpillLRU(data, size) < 0) { + return -1; + } + } + return 0; +} + +static int TextureBindAsTarget(PSP_RenderData *data, PSP_TextureData *psp_texture) +{ + unsigned int dstFormat; + + if (!InVram(psp_texture->data)) { + // Bring back the texture in vram + if (TextureSpillTargetsForSpace(data, psp_texture->size) < 0) { + return -1; + } + if (TexturePromoteToVram(data, psp_texture, SDL_TRUE) < 0) { + return -1; + } + } + LRUTargetBringFront(data, psp_texture); + sceGuDrawBufferList(psp_texture->format, vrelptr(psp_texture->data), psp_texture->textureWidth); + + // Stencil alpha dst hack + dstFormat = psp_texture->format; + if (dstFormat == GU_PSM_5551) { + sceGuEnable(GU_STENCIL_TEST); + sceGuStencilOp(GU_REPLACE, GU_REPLACE, GU_REPLACE); + sceGuStencilFunc(GU_GEQUAL, 0xff, 0xff); + sceGuEnable(GU_ALPHA_TEST); + sceGuAlphaFunc(GU_GREATER, 0x00, 0xff); + } else { + sceGuDisable(GU_STENCIL_TEST); + sceGuDisable(GU_ALPHA_TEST); + } + return 0; +} + +static void PSP_WindowEvent(SDL_Renderer *renderer, const SDL_WindowEvent *event) +{ +} + +static int PSP_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) +{ + PSP_RenderData *data = renderer->driverdata; + PSP_TextureData *psp_texture = (PSP_TextureData *)SDL_calloc(1, sizeof(*psp_texture)); + + if (!psp_texture) { + return SDL_OutOfMemory(); + } + + psp_texture->swizzled = SDL_FALSE; + psp_texture->width = texture->w; + psp_texture->height = texture->h; + psp_texture->textureHeight = TextureNextPow2(texture->h); + psp_texture->textureWidth = TextureNextPow2(texture->w); + psp_texture->format = PixelFormatToPSPFMT(texture->format); + + switch (psp_texture->format) { + case GU_PSM_5650: + case GU_PSM_5551: + case GU_PSM_4444: + psp_texture->bits = 16; + break; + + case GU_PSM_8888: + psp_texture->bits = 32; + break; + + default: + SDL_free(psp_texture); + return -1; + } + + psp_texture->pitch = psp_texture->textureWidth * SDL_BYTESPERPIXEL(texture->format); + psp_texture->size = psp_texture->textureHeight * psp_texture->pitch; + if (texture->access & SDL_TEXTUREACCESS_TARGET) { + if (TextureSpillTargetsForSpace(renderer->driverdata, psp_texture->size) < 0) { + SDL_free(psp_texture); + return -1; + } + psp_texture->data = vramalloc(psp_texture->size); + if (psp_texture->data) { + LRUTargetPushFront(data, psp_texture); + } + } else { + psp_texture->data = SDL_calloc(1, psp_texture->size); + } + + if (!psp_texture->data) { + SDL_free(psp_texture); + return SDL_OutOfMemory(); + } + texture->driverdata = psp_texture; + + return 0; +} + +static int TextureShouldSwizzle(PSP_TextureData *psp_texture, SDL_Texture *texture) +{ + return !((texture->access == SDL_TEXTUREACCESS_TARGET) && InVram(psp_texture->data)) && texture->access != SDL_TEXTUREACCESS_STREAMING && (texture->w >= 16 || texture->h >= 16); +} + +static void TextureActivate(SDL_Texture *texture) +{ + PSP_TextureData *psp_texture = (PSP_TextureData *)texture->driverdata; + int scaleMode = (texture->scaleMode == SDL_ScaleModeNearest) ? GU_NEAREST : GU_LINEAR; + + /* Swizzling is useless with small textures. */ + if (TextureShouldSwizzle(psp_texture, texture)) { + TextureSwizzle(psp_texture, NULL); + } + + sceGuTexWrap(GU_REPEAT, GU_REPEAT); + sceGuTexMode(psp_texture->format, 0, 0, psp_texture->swizzled); + sceGuTexFilter(scaleMode, scaleMode); /* GU_NEAREST good for tile-map */ + /* GU_LINEAR good for scaling */ + sceGuTexImage(0, psp_texture->textureWidth, psp_texture->textureHeight, psp_texture->textureWidth, psp_texture->data); +} + +static int PSP_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *rect, void **pixels, int *pitch); + +static int PSP_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *rect, const void *pixels, int pitch) +{ + /* PSP_TextureData *psp_texture = (PSP_TextureData *) texture->driverdata; */ + const Uint8 *src; + Uint8 *dst; + int row, length, dpitch; + src = pixels; + + PSP_LockTexture(renderer, texture, rect, (void **)&dst, &dpitch); + length = rect->w * SDL_BYTESPERPIXEL(texture->format); + if (length == pitch && length == dpitch) { + SDL_memcpy(dst, src, length * rect->h); + } else { + for (row = 0; row < rect->h; ++row) { + SDL_memcpy(dst, src, length); + src += pitch; + dst += dpitch; + } + } + + sceKernelDcacheWritebackAll(); + return 0; +} + +static int PSP_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *rect, void **pixels, int *pitch) +{ + PSP_TextureData *psp_texture = (PSP_TextureData *)texture->driverdata; + + *pixels = + (void *)((Uint8 *)psp_texture->data + rect->y * psp_texture->pitch + + rect->x * SDL_BYTESPERPIXEL(texture->format)); + *pitch = psp_texture->pitch; + return 0; +} + +static void PSP_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture) +{ + PSP_TextureData *psp_texture = (PSP_TextureData *)texture->driverdata; + SDL_Rect rect; + + /* We do whole texture updates, at least for now */ + rect.x = 0; + rect.y = 0; + rect.w = texture->w; + rect.h = texture->h; + PSP_UpdateTexture(renderer, texture, &rect, psp_texture->data, psp_texture->pitch); +} + +static void PSP_SetTextureScaleMode(SDL_Renderer *renderer, SDL_Texture *texture, SDL_ScaleMode scaleMode) +{ + /* Nothing to do because TextureActivate takes care of it */ +} + +static int PSP_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture) +{ + return 0; +} + +static int PSP_QueueSetViewport(SDL_Renderer *renderer, SDL_RenderCommand *cmd) +{ + return 0; /* nothing to do in this backend. */ +} + +static int PSP_QueueDrawPoints(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count) +{ + VertV *verts = (VertV *)SDL_AllocateRenderVertices(renderer, count * sizeof(VertV), 4, &cmd->data.draw.first); + int i; + + if (!verts) { + return -1; + } + + cmd->data.draw.count = count; + + for (i = 0; i < count; i++, verts++, points++) { + verts->x = points->x; + verts->y = points->y; + verts->z = 0.0f; + } + + return 0; +} + +static int PSP_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, + const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride, + int num_vertices, const void *indices, int num_indices, int size_indices, + float scale_x, float scale_y) +{ + int i; + int count = indices ? num_indices : num_vertices; + + cmd->data.draw.count = count; + size_indices = indices ? size_indices : 0; + + if (!texture) { + VertCV *verts; + verts = (VertCV *)SDL_AllocateRenderVertices(renderer, count * sizeof(VertCV), 4, &cmd->data.draw.first); + if (!verts) { + return -1; + } + + for (i = 0; i < count; i++) { + int j; + float *xy_; + SDL_Color col_; + if (size_indices == 4) { + j = ((const Uint32 *)indices)[i]; + } else if (size_indices == 2) { + j = ((const Uint16 *)indices)[i]; + } else if (size_indices == 1) { + j = ((const Uint8 *)indices)[i]; + } else { + j = i; + } + + xy_ = (float *)((char *)xy + j * xy_stride); + col_ = *(SDL_Color *)((char *)color + j * color_stride); + + verts->x = xy_[0] * scale_x; + verts->y = xy_[1] * scale_y; + verts->z = 0; + + verts->col = col_; + + verts++; + } + } else { + PSP_TextureData *psp_texture = (PSP_TextureData *)texture->driverdata; + VertTCV *verts; + verts = (VertTCV *)SDL_AllocateRenderVertices(renderer, count * sizeof(VertTCV), 4, &cmd->data.draw.first); + if (!verts) { + return -1; + } + + for (i = 0; i < count; i++) { + int j; + float *xy_; + SDL_Color col_; + float *uv_; + + if (size_indices == 4) { + j = ((const Uint32 *)indices)[i]; + } else if (size_indices == 2) { + j = ((const Uint16 *)indices)[i]; + } else if (size_indices == 1) { + j = ((const Uint8 *)indices)[i]; + } else { + j = i; + } + + xy_ = (float *)((char *)xy + j * xy_stride); + col_ = *(SDL_Color *)((char *)color + j * color_stride); + uv_ = (float *)((char *)uv + j * uv_stride); + + verts->x = xy_[0] * scale_x; + verts->y = xy_[1] * scale_y; + verts->z = 0; + + verts->col = col_; + + verts->u = uv_[0] * psp_texture->textureWidth; + verts->v = uv_[1] * psp_texture->textureHeight; + + verts++; + } + } + + return 0; +} + +static int PSP_QueueFillRects(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FRect *rects, int count) +{ + VertV *verts = (VertV *)SDL_AllocateRenderVertices(renderer, count * 2 * sizeof(VertV), 4, &cmd->data.draw.first); + int i; + + if (!verts) { + return -1; + } + + cmd->data.draw.count = count; + for (i = 0; i < count; i++, rects++) { + verts->x = rects->x; + verts->y = rects->y; + verts->z = 0.0f; + verts++; + + verts->x = rects->x + rects->w + 0.5f; + verts->y = rects->y + rects->h + 0.5f; + verts->z = 0.0f; + verts++; + } + + return 0; +} + +static int PSP_QueueCopy(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, + const SDL_Rect *srcrect, const SDL_FRect *dstrect) +{ + VertTV *verts; + const float x = dstrect->x; + const float y = dstrect->y; + const float width = dstrect->w; + const float height = dstrect->h; + + const float u0 = srcrect->x; + const float v0 = srcrect->y; + const float u1 = srcrect->x + srcrect->w; + const float v1 = srcrect->y + srcrect->h; + + if ((MathAbs(u1) - MathAbs(u0)) < 64.0f) { + verts = (VertTV *)SDL_AllocateRenderVertices(renderer, 2 * sizeof(VertTV), 4, &cmd->data.draw.first); + if (!verts) { + return -1; + } + + cmd->data.draw.count = 1; + + verts->u = u0; + verts->v = v0; + verts->x = x; + verts->y = y; + verts->z = 0; + verts++; + + verts->u = u1; + verts->v = v1; + verts->x = x + width; + verts->y = y + height; + verts->z = 0; + verts++; + } else { + float start, end; + float curU = u0; + float curX = x; + const float endX = x + width; + const float slice = 64.0f; + const size_t count = SDL_ceilf(width / slice); + size_t i; + float ustep = (u1 - u0) / width * slice; + + if (ustep < 0.0f) { + ustep = -ustep; + } + + cmd->data.draw.count = count; + + verts = (VertTV *)SDL_AllocateRenderVertices(renderer, count * 2 * sizeof(VertTV), 4, &cmd->data.draw.first); + if (!verts) { + return -1; + } + + for (i = 0, start = 0, end = width; i < count; i++, start += slice) { + const float polyWidth = ((curX + slice) > endX) ? (endX - curX) : slice; + const float sourceWidth = ((curU + ustep) > u1) ? (u1 - curU) : ustep; + + SDL_assert(start < end); + + verts->u = curU; + verts->v = v0; + verts->x = curX; + verts->y = y; + verts->z = 0; + verts++; + + curU += sourceWidth; + curX += polyWidth; + + verts->u = curU; + verts->v = v1; + verts->x = curX; + verts->y = (y + height); + verts->z = 0; + verts++; + } + } + + return 0; +} + +static int PSP_QueueCopyEx(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, + const SDL_Rect *srcrect, const SDL_FRect *dstrect, + const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip, float scale_x, float scale_y) +{ + VertTV *verts = (VertTV *)SDL_AllocateRenderVertices(renderer, 4 * sizeof(VertTV), 4, &cmd->data.draw.first); + const float centerx = center->x; + const float centery = center->y; + const float x = dstrect->x + centerx; + const float y = dstrect->y + centery; + const float width = dstrect->w - centerx; + const float height = dstrect->h - centery; + float s, c; + float cw1, sw1, ch1, sh1, cw2, sw2, ch2, sh2; + + float u0 = srcrect->x; + float v0 = srcrect->y; + float u1 = srcrect->x + srcrect->w; + float v1 = srcrect->y + srcrect->h; + + if (!verts) { + return -1; + } + + cmd->data.draw.count = 1; + + MathSincos(degToRad(360 - angle), &s, &c); + + cw1 = c * -centerx; + sw1 = s * -centerx; + ch1 = c * -centery; + sh1 = s * -centery; + cw2 = c * width; + sw2 = s * width; + ch2 = c * height; + sh2 = s * height; + + if (flip & SDL_FLIP_VERTICAL) { + Swap(&v0, &v1); + } + + if (flip & SDL_FLIP_HORIZONTAL) { + Swap(&u0, &u1); + } + + verts->u = u0; + verts->v = v0; + verts->x = x + cw1 + sh1; + verts->y = y - sw1 + ch1; + verts->z = 0; + verts++; + + verts->u = u0; + verts->v = v1; + verts->x = x + cw1 + sh2; + verts->y = y - sw1 + ch2; + verts->z = 0; + verts++; + + verts->u = u1; + verts->v = v1; + verts->x = x + cw2 + sh2; + verts->y = y - sw2 + ch2; + verts->z = 0; + verts++; + + verts->u = u1; + verts->v = v0; + verts->x = x + cw2 + sh1; + verts->y = y - sw2 + ch1; + verts->z = 0; + + if (scale_x != 1.0f || scale_y != 1.0f) { + verts->x *= scale_x; + verts->y *= scale_y; + verts--; + verts->x *= scale_x; + verts->y *= scale_y; + verts--; + verts->x *= scale_x; + verts->y *= scale_y; + verts--; + verts->x *= scale_x; + verts->y *= scale_y; + } + + return 0; +} + +static void ResetBlendState(PSP_BlendState *state) +{ + sceGuColor(0xffffffff); + state->color = 0xffffffff; + state->mode = SDL_BLENDMODE_INVALID; + state->texture = NULL; + sceGuDisable(GU_TEXTURE_2D); + sceGuShadeModel(GU_SMOOTH); + state->shadeModel = GU_SMOOTH; +} + +static void StartDrawing(SDL_Renderer *renderer) +{ + PSP_RenderData *data = (PSP_RenderData *)renderer->driverdata; + + // Check if we need to start GU displaylist + if (!data->displayListAvail) { + sceGuStart(GU_DIRECT, DisplayList); + data->displayListAvail = SDL_TRUE; + // ResetBlendState(&data->blendState); + } + + // Check if we need a draw buffer change + if (renderer->target != data->boundTarget) { + SDL_Texture *texture = renderer->target; + if (texture) { + PSP_TextureData *psp_texture = (PSP_TextureData *)texture->driverdata; + // Set target, registering LRU + TextureBindAsTarget(data, psp_texture); + } else { + // Set target back to screen + sceGuDrawBufferList(data->psm, vrelptr(data->frontbuffer), PSP_FRAME_BUFFER_WIDTH); + } + data->boundTarget = texture; + } +} + +static void PSP_SetBlendState(PSP_RenderData *data, PSP_BlendState *state) +{ + PSP_BlendState *current = &data->blendState; + + if (state->mode != current->mode) { + switch (state->mode) { + case SDL_BLENDMODE_NONE: + sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA); + sceGuDisable(GU_BLEND); + break; + case SDL_BLENDMODE_BLEND: + sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA); + sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0); + sceGuEnable(GU_BLEND); + break; + case SDL_BLENDMODE_ADD: + sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA); + sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_FIX, 0, 0x00FFFFFF); + sceGuEnable(GU_BLEND); + break; + case SDL_BLENDMODE_MOD: + sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA); + sceGuBlendFunc(GU_ADD, GU_FIX, GU_SRC_COLOR, 0, 0); + sceGuEnable(GU_BLEND); + break; + case SDL_BLENDMODE_MUL: + sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA); + /* FIXME SDL_BLENDMODE_MUL is simplified, and dstA is in fact un-changed.*/ + sceGuBlendFunc(GU_ADD, GU_DST_COLOR, GU_ONE_MINUS_SRC_ALPHA, 0, 0); + sceGuEnable(GU_BLEND); + break; + case SDL_BLENDMODE_INVALID: + break; + } + } + + if (state->color != current->color) { + sceGuColor(state->color); + } + + if (state->shadeModel != current->shadeModel) { + sceGuShadeModel(state->shadeModel); + } + + if (state->texture != current->texture) { + if (state->texture) { + TextureActivate(state->texture); + sceGuEnable(GU_TEXTURE_2D); + } else { + sceGuDisable(GU_TEXTURE_2D); + } + } + + *current = *state; +} + +static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize) +{ + PSP_RenderData *data = (PSP_RenderData *)renderer->driverdata; + Uint8 *gpumem = NULL; + StartDrawing(renderer); + + /* note that before the renderer interface change, this would do extrememly small + batches with sceGuGetMemory()--a few vertices at a time--and it's not clear that + this won't fail if you try to push 100,000 draw calls in a single batch. + I don't know what the limits on PSP hardware are. It might be useful to have + rendering backends report a reasonable maximum, so the higher level can flush + if we appear to be exceeding that. */ + gpumem = (Uint8 *)sceGuGetMemory(vertsize); + if (!gpumem) { + return SDL_SetError("Couldn't obtain a %d-byte vertex buffer!", (int)vertsize); + } + SDL_memcpy(gpumem, vertices, vertsize); + + while (cmd) { + switch (cmd->command) { + case SDL_RENDERCMD_SETDRAWCOLOR: + { + break; /* !!! FIXME: we could cache drawstate like color */ + } + + case SDL_RENDERCMD_SETVIEWPORT: + { + SDL_Rect *viewport = &cmd->data.viewport.rect; + sceGuOffset(2048 - (viewport->w >> 1), 2048 - (viewport->h >> 1)); + sceGuViewport(2048, 2048, viewport->w, viewport->h); + sceGuScissor(viewport->x, viewport->y, viewport->w, viewport->h); + /* FIXME: We need to update the clip rect too, see https://github.com/libsdl-org/SDL/issues/9094 */ + break; + } + + case SDL_RENDERCMD_SETCLIPRECT: + { + const SDL_Rect *rect = &cmd->data.cliprect.rect; + if (cmd->data.cliprect.enabled) { + sceGuEnable(GU_SCISSOR_TEST); + sceGuScissor(rect->x, rect->y, rect->w, rect->h); + } else { + sceGuDisable(GU_SCISSOR_TEST); + } + break; + } + + case SDL_RENDERCMD_CLEAR: + { + const Uint8 r = cmd->data.color.r; + const Uint8 g = cmd->data.color.g; + const Uint8 b = cmd->data.color.b; + const Uint8 a = cmd->data.color.a; + sceGuClearColor(GU_RGBA(r, g, b, a)); + sceGuClearStencil(a); + sceGuClear(GU_COLOR_BUFFER_BIT | GU_STENCIL_BUFFER_BIT); + break; + } + + case SDL_RENDERCMD_DRAW_POINTS: + { + const size_t count = cmd->data.draw.count; + const VertV *verts = (VertV *)(gpumem + cmd->data.draw.first); + const Uint8 r = cmd->data.draw.r; + const Uint8 g = cmd->data.draw.g; + const Uint8 b = cmd->data.draw.b; + const Uint8 a = cmd->data.draw.a; + PSP_BlendState state = { + .color = GU_RGBA(r, g, b, a), + .texture = NULL, + .mode = cmd->data.draw.blend, + .shadeModel = GU_FLAT + }; + PSP_SetBlendState(data, &state); + sceGuDrawArray(GU_POINTS, GU_VERTEX_32BITF | GU_TRANSFORM_2D, count, 0, verts); + break; + } + + case SDL_RENDERCMD_DRAW_LINES: + { + const size_t count = cmd->data.draw.count; + const VertV *verts = (VertV *)(gpumem + cmd->data.draw.first); + const Uint8 r = cmd->data.draw.r; + const Uint8 g = cmd->data.draw.g; + const Uint8 b = cmd->data.draw.b; + const Uint8 a = cmd->data.draw.a; + PSP_BlendState state = { + .color = GU_RGBA(r, g, b, a), + .texture = NULL, + .mode = cmd->data.draw.blend, + .shadeModel = GU_FLAT + }; + PSP_SetBlendState(data, &state); + sceGuDrawArray(GU_LINE_STRIP, GU_VERTEX_32BITF | GU_TRANSFORM_2D, count, 0, verts); + break; + } + + case SDL_RENDERCMD_FILL_RECTS: + { + const size_t count = cmd->data.draw.count; + const VertV *verts = (VertV *)(gpumem + cmd->data.draw.first); + const Uint8 r = cmd->data.draw.r; + const Uint8 g = cmd->data.draw.g; + const Uint8 b = cmd->data.draw.b; + const Uint8 a = cmd->data.draw.a; + PSP_BlendState state = { + .color = GU_RGBA(r, g, b, a), + .texture = NULL, + .mode = cmd->data.draw.blend, + .shadeModel = GU_FLAT + }; + PSP_SetBlendState(data, &state); + sceGuDrawArray(GU_SPRITES, GU_VERTEX_32BITF | GU_TRANSFORM_2D, 2 * count, 0, verts); + break; + } + + case SDL_RENDERCMD_COPY: + { + const size_t count = cmd->data.draw.count; + const VertTV *verts = (VertTV *)(gpumem + cmd->data.draw.first); + const Uint8 a = cmd->data.draw.a; + const Uint8 r = cmd->data.draw.r; + const Uint8 g = cmd->data.draw.g; + const Uint8 b = cmd->data.draw.b; + PSP_BlendState state = { + .color = GU_RGBA(r, g, b, a), + .texture = cmd->data.draw.texture, + .mode = cmd->data.draw.blend, + .shadeModel = GU_SMOOTH + }; + PSP_SetBlendState(data, &state); + sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF | GU_VERTEX_32BITF | GU_TRANSFORM_2D, 2 * count, 0, verts); + break; + } + + case SDL_RENDERCMD_COPY_EX: + { + const VertTV *verts = (VertTV *)(gpumem + cmd->data.draw.first); + const Uint8 a = cmd->data.draw.a; + const Uint8 r = cmd->data.draw.r; + const Uint8 g = cmd->data.draw.g; + const Uint8 b = cmd->data.draw.b; + PSP_BlendState state = { + .color = GU_RGBA(r, g, b, a), + .texture = cmd->data.draw.texture, + .mode = cmd->data.draw.blend, + .shadeModel = GU_SMOOTH + }; + PSP_SetBlendState(data, &state); + sceGuDrawArray(GU_TRIANGLE_FAN, GU_TEXTURE_32BITF | GU_VERTEX_32BITF | GU_TRANSFORM_2D, 4, 0, verts); + break; + } + + case SDL_RENDERCMD_GEOMETRY: + { + const size_t count = cmd->data.draw.count; + if (!cmd->data.draw.texture) { + const VertCV *verts = (VertCV *)(gpumem + cmd->data.draw.first); + sceGuDisable(GU_TEXTURE_2D); + /* In GU_SMOOTH mode */ + sceGuDrawArray(GU_TRIANGLES, GU_COLOR_8888 | GU_VERTEX_32BITF | GU_TRANSFORM_2D, count, 0, verts); + sceGuEnable(GU_TEXTURE_2D); + } else { + const VertTCV *verts = (VertTCV *)(gpumem + cmd->data.draw.first); + const Uint8 a = cmd->data.draw.a; + const Uint8 r = cmd->data.draw.r; + const Uint8 g = cmd->data.draw.g; + const Uint8 b = cmd->data.draw.b; + PSP_BlendState state = { + .color = GU_RGBA(r, g, b, a), + .texture = NULL, + .mode = cmd->data.draw.blend, + .shadeModel = GU_FLAT + }; + TextureActivate(cmd->data.draw.texture); + PSP_SetBlendState(data, &state); + sceGuDrawArray(GU_TRIANGLES, GU_TEXTURE_32BITF | GU_COLOR_8888 | GU_VERTEX_32BITF | GU_TRANSFORM_2D, count, 0, verts); + } + break; + } + + case SDL_RENDERCMD_NO_OP: + break; + } + + cmd = cmd->next; + } + + return 0; +} + +static int PSP_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect, + Uint32 pixel_format, void *pixels, int pitch) +{ + return SDL_Unsupported(); +} + +static int PSP_RenderPresent(SDL_Renderer *renderer) +{ + PSP_RenderData *data = (PSP_RenderData *)renderer->driverdata; + if (!data->displayListAvail) { + return -1; + } + + data->displayListAvail = SDL_FALSE; + sceGuFinish(); + sceGuSync(0, 0); + + if ((data->vsync) && (data->vblank_not_reached)) { + sceDisplayWaitVblankStart(); + } + data->vblank_not_reached = SDL_TRUE; + + data->backbuffer = data->frontbuffer; + data->frontbuffer = vabsptr(sceGuSwapBuffers()); + + return 0; +} + +static void PSP_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture) +{ + PSP_RenderData *renderdata = (PSP_RenderData *)renderer->driverdata; + PSP_TextureData *psp_texture = (PSP_TextureData *)texture->driverdata; + + if (!renderdata) { + return; + } + + if (!psp_texture) { + return; + } + + LRUTargetRemove(renderdata, psp_texture); + TextureStorageFree(psp_texture->data); + SDL_free(psp_texture); + texture->driverdata = NULL; +} + +static void PSP_DestroyRenderer(SDL_Renderer *renderer) +{ + PSP_RenderData *data = (PSP_RenderData *)renderer->driverdata; + if (data) { + if (!data->initialized) { + return; + } + + StartDrawing(renderer); + + sceKernelDisableSubIntr(PSP_VBLANK_INT, 0); + sceKernelReleaseSubIntrHandler(PSP_VBLANK_INT, 0); + sceDisplayWaitVblankStart(); + sceGuDisplay(GU_FALSE); + sceGuTerm(); + vfree(data->backbuffer); + vfree(data->frontbuffer); + + data->initialized = SDL_FALSE; + data->displayListAvail = SDL_FALSE; + SDL_free(data); + } + SDL_free(renderer); +} + +static int PSP_SetVSync(SDL_Renderer *renderer, const int vsync) +{ + PSP_RenderData *data = renderer->driverdata; + data->vsync = vsync; + return 0; +} + +SDL_Renderer *PSP_CreateRenderer(SDL_Window *window, Uint32 flags) +{ + + SDL_Renderer *renderer; + PSP_RenderData *data; + int pixelformat; + void *doublebuffer = NULL; + + renderer = (SDL_Renderer *)SDL_calloc(1, sizeof(*renderer)); + if (!renderer) { + SDL_OutOfMemory(); + return NULL; + } + + data = (PSP_RenderData *)SDL_calloc(1, sizeof(*data)); + if (!data) { + PSP_DestroyRenderer(renderer); + SDL_OutOfMemory(); + return NULL; + } + + renderer->WindowEvent = PSP_WindowEvent; + renderer->CreateTexture = PSP_CreateTexture; + renderer->UpdateTexture = PSP_UpdateTexture; + renderer->LockTexture = PSP_LockTexture; + renderer->UnlockTexture = PSP_UnlockTexture; + renderer->SetTextureScaleMode = PSP_SetTextureScaleMode; + renderer->SetRenderTarget = PSP_SetRenderTarget; + renderer->QueueSetViewport = PSP_QueueSetViewport; + renderer->QueueSetDrawColor = PSP_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */ + renderer->QueueDrawPoints = PSP_QueueDrawPoints; + renderer->QueueDrawLines = PSP_QueueDrawPoints; /* lines and points queue vertices the same way. */ + renderer->QueueGeometry = PSP_QueueGeometry; + renderer->QueueFillRects = PSP_QueueFillRects; + renderer->QueueCopy = PSP_QueueCopy; + renderer->QueueCopyEx = PSP_QueueCopyEx; + renderer->RunCommandQueue = PSP_RunCommandQueue; + renderer->RenderReadPixels = PSP_RenderReadPixels; + renderer->RenderPresent = PSP_RenderPresent; + renderer->DestroyTexture = PSP_DestroyTexture; + renderer->DestroyRenderer = PSP_DestroyRenderer; + renderer->SetVSync = PSP_SetVSync; + renderer->info = PSP_RenderDriver.info; + renderer->info.flags = (SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE); + renderer->driverdata = data; + renderer->window = window; + + data->initialized = SDL_TRUE; + data->most_recent_target = NULL; + data->least_recent_target = NULL; + + if (flags & SDL_RENDERER_PRESENTVSYNC) { + data->vsync = SDL_TRUE; + } else { + data->vsync = SDL_FALSE; + } + + pixelformat = PixelFormatToPSPFMT(SDL_GetWindowPixelFormat(window)); + switch (pixelformat) { + case GU_PSM_4444: + case GU_PSM_5650: + case GU_PSM_5551: + data->bpp = 2; + data->psm = pixelformat; + break; + default: + data->bpp = 4; + data->psm = GU_PSM_8888; + break; + } + + doublebuffer = vramalloc(PSP_FRAME_BUFFER_SIZE * data->bpp * 2); + data->backbuffer = doublebuffer; + data->frontbuffer = ((uint8_t *)doublebuffer) + PSP_FRAME_BUFFER_SIZE * data->bpp; + + sceGuInit(); + /* setup GU */ + sceGuStart(GU_DIRECT, DisplayList); + sceGuDrawBuffer(data->psm, vrelptr(data->frontbuffer), PSP_FRAME_BUFFER_WIDTH); + sceGuDispBuffer(PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT, vrelptr(data->backbuffer), PSP_FRAME_BUFFER_WIDTH); + + sceGuOffset(2048 - (PSP_SCREEN_WIDTH >> 1), 2048 - (PSP_SCREEN_HEIGHT >> 1)); + sceGuViewport(2048, 2048, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT); + + sceGuDisable(GU_DEPTH_TEST); + + /* Scissoring */ + sceGuScissor(0, 0, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT); + sceGuEnable(GU_SCISSOR_TEST); + + /* Backface culling */ + /* + FIXME: Culling probably un-needed ? It can conflict with SDL_RENDERCMD_GEOMETRY + sceGuFrontFace(GU_CCW); + sceGuEnable(GU_CULL_FACE); + */ + + // Setup initial blend state + ResetBlendState(&data->blendState); + + sceGuFinish(); + sceGuSync(0, 0); + sceDisplayWaitVblankStartCB(); + sceGuDisplay(GU_TRUE); + + /* Improve performance when VSYC is enabled and it is not reaching the 60 FPS */ + data->vblank_not_reached = SDL_TRUE; + sceKernelRegisterSubIntrHandler(PSP_VBLANK_INT, 0, psp_on_vblank, data); + sceKernelEnableSubIntr(PSP_VBLANK_INT, 0); + + return renderer; +} + +SDL_RenderDriver PSP_RenderDriver = { + .CreateRenderer = PSP_CreateRenderer, + .info = { + .name = "PSP", + .flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE, + .num_texture_formats = 4, + .texture_formats = { + [0] = SDL_PIXELFORMAT_BGR565, + [1] = SDL_PIXELFORMAT_ABGR1555, + [2] = SDL_PIXELFORMAT_ABGR4444, + [3] = SDL_PIXELFORMAT_ABGR8888, + }, + .max_texture_width = 512, + .max_texture_height = 512, + } +}; + +#endif /* SDL_VIDEO_RENDER_PSP */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/render/software/SDL_blendfillrect.c b/SDL2-2.30.5/src/render/software/SDL_blendfillrect.c similarity index 85% rename from SDL2-2.0.12/src/render/software/SDL_blendfillrect.c rename to SDL2-2.30.5/src/render/software/SDL_blendfillrect.c index 9ab5476..2026cb8 100644 --- a/SDL2-2.0.12/src/render/software/SDL_blendfillrect.c +++ b/SDL2-2.30.5/src/render/software/SDL_blendfillrect.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,15 +20,13 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_RENDER_SW && !SDL_RENDER_DISABLED +#if SDL_VIDEO_RENDER_SW #include "SDL_draw.h" #include "SDL_blendfillrect.h" - -static int -SDL_BlendFillRect_RGB555(SDL_Surface * dst, const SDL_Rect * rect, - SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) +static int SDL_BlendFillRect_RGB555(SDL_Surface *dst, const SDL_Rect *rect, + SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) { unsigned inva = 0xff - a; @@ -52,9 +50,8 @@ SDL_BlendFillRect_RGB555(SDL_Surface * dst, const SDL_Rect * rect, return 0; } -static int -SDL_BlendFillRect_RGB565(SDL_Surface * dst, const SDL_Rect * rect, - SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) +static int SDL_BlendFillRect_RGB565(SDL_Surface *dst, const SDL_Rect *rect, + SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) { unsigned inva = 0xff - a; @@ -78,9 +75,8 @@ SDL_BlendFillRect_RGB565(SDL_Surface * dst, const SDL_Rect * rect, return 0; } -static int -SDL_BlendFillRect_RGB888(SDL_Surface * dst, const SDL_Rect * rect, - SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) +static int SDL_BlendFillRect_RGB888(SDL_Surface *dst, const SDL_Rect *rect, + SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) { unsigned inva = 0xff - a; @@ -104,9 +100,8 @@ SDL_BlendFillRect_RGB888(SDL_Surface * dst, const SDL_Rect * rect, return 0; } -static int -SDL_BlendFillRect_ARGB8888(SDL_Surface * dst, const SDL_Rect * rect, - SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) +static int SDL_BlendFillRect_ARGB8888(SDL_Surface *dst, const SDL_Rect *rect, + SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) { unsigned inva = 0xff - a; @@ -130,9 +125,8 @@ SDL_BlendFillRect_ARGB8888(SDL_Surface * dst, const SDL_Rect * rect, return 0; } -static int -SDL_BlendFillRect_RGB(SDL_Surface * dst, const SDL_Rect * rect, - SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) +static int SDL_BlendFillRect_RGB(SDL_Surface *dst, const SDL_Rect *rect, + SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) { SDL_PixelFormat *fmt = dst->format; unsigned inva = 0xff - a; @@ -181,9 +175,8 @@ SDL_BlendFillRect_RGB(SDL_Surface * dst, const SDL_Rect * rect, } } -static int -SDL_BlendFillRect_RGBA(SDL_Surface * dst, const SDL_Rect * rect, - SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) +static int SDL_BlendFillRect_RGBA(SDL_Surface *dst, const SDL_Rect *rect, + SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) { SDL_PixelFormat *fmt = dst->format; unsigned inva = 0xff - a; @@ -213,14 +206,13 @@ SDL_BlendFillRect_RGBA(SDL_Surface * dst, const SDL_Rect * rect, } } -int -SDL_BlendFillRect(SDL_Surface * dst, const SDL_Rect * rect, - SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) +int SDL_BlendFillRect(SDL_Surface *dst, const SDL_Rect *rect, + SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) { SDL_Rect clipped; if (!dst) { - return SDL_SetError("Passed NULL destination surface"); + return SDL_InvalidParamError("SDL_BlendFillRect(): dst"); } /* This function doesn't work on surfaces < 8 bpp */ @@ -280,18 +272,17 @@ SDL_BlendFillRect(SDL_Surface * dst, const SDL_Rect * rect, } } -int -SDL_BlendFillRects(SDL_Surface * dst, const SDL_Rect * rects, int count, - SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) +int SDL_BlendFillRects(SDL_Surface *dst, const SDL_Rect *rects, int count, + SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) { SDL_Rect rect; int i; - int (*func)(SDL_Surface * dst, const SDL_Rect * rect, + int (*func)(SDL_Surface * dst, const SDL_Rect *rect, SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) = NULL; int status = 0; if (!dst) { - return SDL_SetError("Passed NULL destination surface"); + return SDL_InvalidParamError("SDL_BlendFillRects(): dst"); } /* This function doesn't work on surfaces < 8 bpp */ @@ -352,6 +343,6 @@ SDL_BlendFillRects(SDL_Surface * dst, const SDL_Rect * rects, int count, return status; } -#endif /* SDL_VIDEO_RENDER_SW && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_SW */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/render/software/SDL_blendfillrect.h b/SDL2-2.30.5/src/render/software/SDL_blendfillrect.h similarity index 75% rename from SDL2-2.0.12/src/render/software/SDL_blendfillrect.h rename to SDL2-2.30.5/src/render/software/SDL_blendfillrect.h index f120e13..eb9ba7d 100644 --- a/SDL2-2.0.12/src/render/software/SDL_blendfillrect.h +++ b/SDL2-2.30.5/src/render/software/SDL_blendfillrect.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -24,9 +24,8 @@ #include "../../SDL_internal.h" - -extern int SDL_BlendFillRect(SDL_Surface * dst, const SDL_Rect * rect, SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a); -extern int SDL_BlendFillRects(SDL_Surface * dst, const SDL_Rect * rects, int count, SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a); +extern int SDL_BlendFillRect(SDL_Surface *dst, const SDL_Rect *rect, SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a); +extern int SDL_BlendFillRects(SDL_Surface *dst, const SDL_Rect *rects, int count, SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a); #endif /* SDL_blendfillrect_h_ */ diff --git a/SDL2-2.0.12/src/render/software/SDL_blendline.c b/SDL2-2.30.5/src/render/software/SDL_blendline.c similarity index 90% rename from SDL2-2.0.12/src/render/software/SDL_blendline.c rename to SDL2-2.30.5/src/render/software/SDL_blendline.c index 38b2d04..19e2cdb 100644 --- a/SDL2-2.0.12/src/render/software/SDL_blendline.c +++ b/SDL2-2.30.5/src/render/software/SDL_blendline.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,17 +20,15 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_RENDER_SW && !SDL_RENDER_DISABLED +#if SDL_VIDEO_RENDER_SW #include "SDL_draw.h" #include "SDL_blendline.h" #include "SDL_blendpoint.h" - -static void -SDL_BlendLine_RGB2(SDL_Surface * dst, int x1, int y1, int x2, int y2, - SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a, - SDL_bool draw_end) +static void SDL_BlendLine_RGB2(SDL_Surface *dst, int x1, int y1, int x2, int y2, + SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a, + SDL_bool draw_end) { const SDL_PixelFormat *fmt = dst->format; unsigned r, g, b, a, inva; @@ -133,10 +131,9 @@ SDL_BlendLine_RGB2(SDL_Surface * dst, int x1, int y1, int x2, int y2, } } -static void -SDL_BlendLine_RGB555(SDL_Surface * dst, int x1, int y1, int x2, int y2, - SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a, - SDL_bool draw_end) +static void SDL_BlendLine_RGB555(SDL_Surface *dst, int x1, int y1, int x2, int y2, + SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a, + SDL_bool draw_end) { unsigned r, g, b, a, inva; @@ -238,10 +235,9 @@ SDL_BlendLine_RGB555(SDL_Surface * dst, int x1, int y1, int x2, int y2, } } -static void -SDL_BlendLine_RGB565(SDL_Surface * dst, int x1, int y1, int x2, int y2, - SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a, - SDL_bool draw_end) +static void SDL_BlendLine_RGB565(SDL_Surface *dst, int x1, int y1, int x2, int y2, + SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a, + SDL_bool draw_end) { unsigned r, g, b, a, inva; @@ -343,10 +339,9 @@ SDL_BlendLine_RGB565(SDL_Surface * dst, int x1, int y1, int x2, int y2, } } -static void -SDL_BlendLine_RGB4(SDL_Surface * dst, int x1, int y1, int x2, int y2, - SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a, - SDL_bool draw_end) +static void SDL_BlendLine_RGB4(SDL_Surface *dst, int x1, int y1, int x2, int y2, + SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a, + SDL_bool draw_end) { const SDL_PixelFormat *fmt = dst->format; unsigned r, g, b, a, inva; @@ -449,10 +444,9 @@ SDL_BlendLine_RGB4(SDL_Surface * dst, int x1, int y1, int x2, int y2, } } -static void -SDL_BlendLine_RGBA4(SDL_Surface * dst, int x1, int y1, int x2, int y2, - SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a, - SDL_bool draw_end) +static void SDL_BlendLine_RGBA4(SDL_Surface *dst, int x1, int y1, int x2, int y2, + SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a, + SDL_bool draw_end) { const SDL_PixelFormat *fmt = dst->format; unsigned r, g, b, a, inva; @@ -555,10 +549,9 @@ SDL_BlendLine_RGBA4(SDL_Surface * dst, int x1, int y1, int x2, int y2, } } -static void -SDL_BlendLine_RGB888(SDL_Surface * dst, int x1, int y1, int x2, int y2, - SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a, - SDL_bool draw_end) +static void SDL_BlendLine_RGB888(SDL_Surface *dst, int x1, int y1, int x2, int y2, + SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a, + SDL_bool draw_end) { unsigned r, g, b, a, inva; @@ -660,10 +653,9 @@ SDL_BlendLine_RGB888(SDL_Surface * dst, int x1, int y1, int x2, int y2, } } -static void -SDL_BlendLine_ARGB8888(SDL_Surface * dst, int x1, int y1, int x2, int y2, - SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a, - SDL_bool draw_end) +static void SDL_BlendLine_ARGB8888(SDL_Surface *dst, int x1, int y1, int x2, int y2, + SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a, + SDL_bool draw_end) { unsigned r, g, b, a, inva; @@ -765,14 +757,13 @@ SDL_BlendLine_ARGB8888(SDL_Surface * dst, int x1, int y1, int x2, int y2, } } -typedef void (*BlendLineFunc) (SDL_Surface * dst, - int x1, int y1, int x2, int y2, - SDL_BlendMode blendMode, - Uint8 r, Uint8 g, Uint8 b, Uint8 a, - SDL_bool draw_end); +typedef void (*BlendLineFunc)(SDL_Surface *dst, + int x1, int y1, int x2, int y2, + SDL_BlendMode blendMode, + Uint8 r, Uint8 g, Uint8 b, Uint8 a, + SDL_bool draw_end); -static BlendLineFunc -SDL_CalculateBlendLineFunc(const SDL_PixelFormat * fmt) +static BlendLineFunc SDL_CalculateBlendLineFunc(const SDL_PixelFormat *fmt) { switch (fmt->BytesPerPixel) { case 2: @@ -802,14 +793,13 @@ SDL_CalculateBlendLineFunc(const SDL_PixelFormat * fmt) return NULL; } -int -SDL_BlendLine(SDL_Surface * dst, int x1, int y1, int x2, int y2, - SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) +int SDL_BlendLine(SDL_Surface *dst, int x1, int y1, int x2, int y2, + SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) { BlendLineFunc func; if (!dst) { - return SDL_SetError("SDL_BlendLine(): Passed NULL destination surface"); + return SDL_InvalidParamError("SDL_BlendLine(): dst"); } func = SDL_CalculateBlendLineFunc(dst->format); @@ -827,9 +817,8 @@ SDL_BlendLine(SDL_Surface * dst, int x1, int y1, int x2, int y2, return 0; } -int -SDL_BlendLines(SDL_Surface * dst, const SDL_Point * points, int count, - SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) +int SDL_BlendLines(SDL_Surface *dst, const SDL_Point *points, int count, + SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) { int i; int x1, y1; @@ -847,8 +836,8 @@ SDL_BlendLines(SDL_Surface * dst, const SDL_Point * points, int count, } for (i = 1; i < count; ++i) { - x1 = points[i-1].x; - y1 = points[i-1].y; + x1 = points[i - 1].x; + y1 = points[i - 1].y; x2 = points[i].x; y2 = points[i].y; @@ -863,13 +852,13 @@ SDL_BlendLines(SDL_Surface * dst, const SDL_Point * points, int count, func(dst, x1, y1, x2, y2, blendMode, r, g, b, a, draw_end); } - if (points[0].x != points[count-1].x || points[0].y != points[count-1].y) { - SDL_BlendPoint(dst, points[count-1].x, points[count-1].y, + if (points[0].x != points[count - 1].x || points[0].y != points[count - 1].y) { + SDL_BlendPoint(dst, points[count - 1].x, points[count - 1].y, blendMode, r, g, b, a); } return 0; } -#endif /* SDL_VIDEO_RENDER_SW && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_SW */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/render/software/SDL_blendline.h b/SDL2-2.30.5/src/render/software/SDL_blendline.h similarity index 75% rename from SDL2-2.0.12/src/render/software/SDL_blendline.h rename to SDL2-2.30.5/src/render/software/SDL_blendline.h index 4e31313..993dd47 100644 --- a/SDL2-2.0.12/src/render/software/SDL_blendline.h +++ b/SDL2-2.30.5/src/render/software/SDL_blendline.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -24,9 +24,8 @@ #include "../../SDL_internal.h" - -extern int SDL_BlendLine(SDL_Surface * dst, int x1, int y1, int x2, int y2, SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a); -extern int SDL_BlendLines(SDL_Surface * dst, const SDL_Point * points, int count, SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a); +extern int SDL_BlendLine(SDL_Surface *dst, int x1, int y1, int x2, int y2, SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a); +extern int SDL_BlendLines(SDL_Surface *dst, const SDL_Point *points, int count, SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a); #endif /* SDL_blendline_h_ */ diff --git a/SDL2-2.0.12/src/render/software/SDL_blendpoint.c b/SDL2-2.30.5/src/render/software/SDL_blendpoint.c similarity index 85% rename from SDL2-2.0.12/src/render/software/SDL_blendpoint.c rename to SDL2-2.30.5/src/render/software/SDL_blendpoint.c index b6a406e..c380371 100644 --- a/SDL2-2.0.12/src/render/software/SDL_blendpoint.c +++ b/SDL2-2.30.5/src/render/software/SDL_blendpoint.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,15 +20,13 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_RENDER_SW && !SDL_RENDER_DISABLED +#if SDL_VIDEO_RENDER_SW #include "SDL_draw.h" #include "SDL_blendpoint.h" - -static int -SDL_BlendPoint_RGB555(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, Uint8 r, - Uint8 g, Uint8 b, Uint8 a) +static int SDL_BlendPoint_RGB555(SDL_Surface *dst, int x, int y, SDL_BlendMode blendMode, Uint8 r, + Uint8 g, Uint8 b, Uint8 a) { unsigned inva = 0xff - a; @@ -52,9 +50,8 @@ SDL_BlendPoint_RGB555(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, return 0; } -static int -SDL_BlendPoint_RGB565(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, Uint8 r, - Uint8 g, Uint8 b, Uint8 a) +static int SDL_BlendPoint_RGB565(SDL_Surface *dst, int x, int y, SDL_BlendMode blendMode, Uint8 r, + Uint8 g, Uint8 b, Uint8 a) { unsigned inva = 0xff - a; @@ -78,9 +75,8 @@ SDL_BlendPoint_RGB565(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, return 0; } -static int -SDL_BlendPoint_RGB888(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, Uint8 r, - Uint8 g, Uint8 b, Uint8 a) +static int SDL_BlendPoint_RGB888(SDL_Surface *dst, int x, int y, SDL_BlendMode blendMode, Uint8 r, + Uint8 g, Uint8 b, Uint8 a) { unsigned inva = 0xff - a; @@ -104,9 +100,8 @@ SDL_BlendPoint_RGB888(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, return 0; } -static int -SDL_BlendPoint_ARGB8888(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, - Uint8 r, Uint8 g, Uint8 b, Uint8 a) +static int SDL_BlendPoint_ARGB8888(SDL_Surface *dst, int x, int y, SDL_BlendMode blendMode, + Uint8 r, Uint8 g, Uint8 b, Uint8 a) { unsigned inva = 0xff - a; @@ -130,9 +125,8 @@ SDL_BlendPoint_ARGB8888(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode return 0; } -static int -SDL_BlendPoint_RGB(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, Uint8 r, - Uint8 g, Uint8 b, Uint8 a) +static int SDL_BlendPoint_RGB(SDL_Surface *dst, int x, int y, SDL_BlendMode blendMode, Uint8 r, + Uint8 g, Uint8 b, Uint8 a) { SDL_PixelFormat *fmt = dst->format; unsigned inva = 0xff - a; @@ -181,9 +175,8 @@ SDL_BlendPoint_RGB(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, Uin } } -static int -SDL_BlendPoint_RGBA(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, Uint8 r, - Uint8 g, Uint8 b, Uint8 a) +static int SDL_BlendPoint_RGBA(SDL_Surface *dst, int x, int y, SDL_BlendMode blendMode, Uint8 r, + Uint8 g, Uint8 b, Uint8 a) { SDL_PixelFormat *fmt = dst->format; unsigned inva = 0xff - a; @@ -213,12 +206,11 @@ SDL_BlendPoint_RGBA(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, Ui } } -int -SDL_BlendPoint(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, Uint8 r, - Uint8 g, Uint8 b, Uint8 a) +int SDL_BlendPoint(SDL_Surface *dst, int x, int y, SDL_BlendMode blendMode, Uint8 r, + Uint8 g, Uint8 b, Uint8 a) { if (!dst) { - return SDL_SetError("Passed NULL destination surface"); + return SDL_InvalidParamError("SDL_BlendPoint(): dst"); } /* This function doesn't work on surfaces < 8 bpp */ @@ -274,9 +266,8 @@ SDL_BlendPoint(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, Uint8 r } } -int -SDL_BlendPoints(SDL_Surface * dst, const SDL_Point * points, int count, - SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) +int SDL_BlendPoints(SDL_Surface *dst, const SDL_Point *points, int count, + SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) { int minx, miny; int maxx, maxy; @@ -287,7 +278,7 @@ SDL_BlendPoints(SDL_Surface * dst, const SDL_Point * points, int count, int status = 0; if (!dst) { - return SDL_SetError("Passed NULL destination surface"); + return SDL_InvalidParamError("SDL_BlendPoints(): dst"); } /* This function doesn't work on surfaces < 8 bpp */ @@ -357,6 +348,6 @@ SDL_BlendPoints(SDL_Surface * dst, const SDL_Point * points, int count, return status; } -#endif /* SDL_VIDEO_RENDER_SW && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_SW */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/render/software/SDL_blendpoint.h b/SDL2-2.30.5/src/render/software/SDL_blendpoint.h similarity index 75% rename from SDL2-2.0.12/src/render/software/SDL_blendpoint.h rename to SDL2-2.30.5/src/render/software/SDL_blendpoint.h index 9ac8365..86ee766 100644 --- a/SDL2-2.0.12/src/render/software/SDL_blendpoint.h +++ b/SDL2-2.30.5/src/render/software/SDL_blendpoint.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -24,9 +24,8 @@ #include "../../SDL_internal.h" - -extern int SDL_BlendPoint(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a); -extern int SDL_BlendPoints(SDL_Surface * dst, const SDL_Point * points, int count, SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a); +extern int SDL_BlendPoint(SDL_Surface *dst, int x, int y, SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a); +extern int SDL_BlendPoints(SDL_Surface *dst, const SDL_Point *points, int count, SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a); #endif /* SDL_blendpoint_h_ */ diff --git a/SDL2-2.30.5/src/render/software/SDL_draw.h b/SDL2-2.30.5/src/render/software/SDL_draw.h new file mode 100644 index 0000000..ab80b87 --- /dev/null +++ b/SDL2-2.30.5/src/render/software/SDL_draw.h @@ -0,0 +1,661 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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 "../../video/SDL_blit.h" + +/* This code assumes that r, g, b, a are the source color, + * and in the blend and add case, the RGB values are premultiplied by a. + */ + +#define DRAW_MUL(_a, _b) (((unsigned)(_a) * (_b)) / 255) + +#define DRAW_FASTSETPIXEL(type) \ + *pixel = (type)color + +#define DRAW_FASTSETPIXEL1 DRAW_FASTSETPIXEL(Uint8) +#define DRAW_FASTSETPIXEL2 DRAW_FASTSETPIXEL(Uint16) +#define DRAW_FASTSETPIXEL4 DRAW_FASTSETPIXEL(Uint32) + +#define DRAW_FASTSETPIXELXY(x, y, type, bpp, color) \ + *(type *)((Uint8 *)dst->pixels + (y)*dst->pitch + (x)*bpp) = (type)color + +#define DRAW_FASTSETPIXELXY1(x, y) DRAW_FASTSETPIXELXY(x, y, Uint8, 1, color) +#define DRAW_FASTSETPIXELXY2(x, y) DRAW_FASTSETPIXELXY(x, y, Uint16, 2, color) +#define DRAW_FASTSETPIXELXY4(x, y) DRAW_FASTSETPIXELXY(x, y, Uint32, 4, color) + +#define DRAW_SETPIXEL(setpixel) \ + do { \ + unsigned sr = r, sg = g, sb = b, sa = a; \ + (void)sa; \ + setpixel; \ + } while (0) + +#define DRAW_SETPIXEL_BLEND(getpixel, setpixel) \ + do { \ + unsigned sr, sg, sb, sa = 0xFF; \ + getpixel; \ + sr = DRAW_MUL(inva, sr) + r; \ + sg = DRAW_MUL(inva, sg) + g; \ + sb = DRAW_MUL(inva, sb) + b; \ + sa = DRAW_MUL(inva, sa) + a; \ + setpixel; \ + } while (0) + +#define DRAW_SETPIXEL_ADD(getpixel, setpixel) \ + do { \ + unsigned sr, sg, sb, sa; \ + (void)sa; \ + getpixel; \ + sr += r; \ + if (sr > 0xff) \ + sr = 0xff; \ + sg += g; \ + if (sg > 0xff) \ + sg = 0xff; \ + sb += b; \ + if (sb > 0xff) \ + sb = 0xff; \ + setpixel; \ + } while (0) + +#define DRAW_SETPIXEL_MOD(getpixel, setpixel) \ + do { \ + unsigned sr, sg, sb, sa; \ + (void)sa; \ + getpixel; \ + sr = DRAW_MUL(sr, r); \ + sg = DRAW_MUL(sg, g); \ + sb = DRAW_MUL(sb, b); \ + setpixel; \ + } while (0) + +#define DRAW_SETPIXEL_MUL(getpixel, setpixel) \ + do { \ + unsigned sr, sg, sb, sa; \ + (void)sa; \ + getpixel; \ + sr = DRAW_MUL(sr, r) + DRAW_MUL(inva, sr); \ + if (sr > 0xff) \ + sr = 0xff; \ + sg = DRAW_MUL(sg, g) + DRAW_MUL(inva, sg); \ + if (sg > 0xff) \ + sg = 0xff; \ + sb = DRAW_MUL(sb, b) + DRAW_MUL(inva, sb); \ + if (sb > 0xff) \ + sb = 0xff; \ + setpixel; \ + } while (0) + +#define DRAW_SETPIXELXY(x, y, type, bpp, op) \ + do { \ + type *pixel = (type *)((Uint8 *)dst->pixels + (y)*dst->pitch + (x)*bpp); \ + op; \ + } while (0) + +/* + * Define draw operators for RGB555 + */ + +#define DRAW_SETPIXEL_RGB555 \ + DRAW_SETPIXEL(RGB555_FROM_RGB(*pixel, sr, sg, sb)) + +#define DRAW_SETPIXEL_BLEND_RGB555 \ + DRAW_SETPIXEL_BLEND(RGB_FROM_RGB555(*pixel, sr, sg, sb), \ + RGB555_FROM_RGB(*pixel, sr, sg, sb)) + +#define DRAW_SETPIXEL_ADD_RGB555 \ + DRAW_SETPIXEL_ADD(RGB_FROM_RGB555(*pixel, sr, sg, sb), \ + RGB555_FROM_RGB(*pixel, sr, sg, sb)) + +#define DRAW_SETPIXEL_MOD_RGB555 \ + DRAW_SETPIXEL_MOD(RGB_FROM_RGB555(*pixel, sr, sg, sb), \ + RGB555_FROM_RGB(*pixel, sr, sg, sb)) + +#define DRAW_SETPIXEL_MUL_RGB555 \ + DRAW_SETPIXEL_MUL(RGB_FROM_RGB555(*pixel, sr, sg, sb), \ + RGB555_FROM_RGB(*pixel, sr, sg, sb)) + +#define DRAW_SETPIXELXY_RGB555(x, y) \ + DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_RGB555) + +#define DRAW_SETPIXELXY_BLEND_RGB555(x, y) \ + DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_BLEND_RGB555) + +#define DRAW_SETPIXELXY_ADD_RGB555(x, y) \ + DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_ADD_RGB555) + +#define DRAW_SETPIXELXY_MOD_RGB555(x, y) \ + DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_MOD_RGB555) + +#define DRAW_SETPIXELXY_MUL_RGB555(x, y) \ + DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_MUL_RGB555) + +/* + * Define draw operators for RGB565 + */ + +#define DRAW_SETPIXEL_RGB565 \ + DRAW_SETPIXEL(RGB565_FROM_RGB(*pixel, sr, sg, sb)) + +#define DRAW_SETPIXEL_BLEND_RGB565 \ + DRAW_SETPIXEL_BLEND(RGB_FROM_RGB565(*pixel, sr, sg, sb), \ + RGB565_FROM_RGB(*pixel, sr, sg, sb)) + +#define DRAW_SETPIXEL_ADD_RGB565 \ + DRAW_SETPIXEL_ADD(RGB_FROM_RGB565(*pixel, sr, sg, sb), \ + RGB565_FROM_RGB(*pixel, sr, sg, sb)) + +#define DRAW_SETPIXEL_MOD_RGB565 \ + DRAW_SETPIXEL_MOD(RGB_FROM_RGB565(*pixel, sr, sg, sb), \ + RGB565_FROM_RGB(*pixel, sr, sg, sb)) + +#define DRAW_SETPIXEL_MUL_RGB565 \ + DRAW_SETPIXEL_MUL(RGB_FROM_RGB565(*pixel, sr, sg, sb), \ + RGB565_FROM_RGB(*pixel, sr, sg, sb)) + +#define DRAW_SETPIXELXY_RGB565(x, y) \ + DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_RGB565) + +#define DRAW_SETPIXELXY_BLEND_RGB565(x, y) \ + DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_BLEND_RGB565) + +#define DRAW_SETPIXELXY_ADD_RGB565(x, y) \ + DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_ADD_RGB565) + +#define DRAW_SETPIXELXY_MOD_RGB565(x, y) \ + DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_MOD_RGB565) + +#define DRAW_SETPIXELXY_MUL_RGB565(x, y) \ + DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_MUL_RGB565) + +/* + * Define draw operators for RGB888 + */ + +#define DRAW_SETPIXEL_RGB888 \ + DRAW_SETPIXEL(RGB888_FROM_RGB(*pixel, sr, sg, sb)) + +#define DRAW_SETPIXEL_BLEND_RGB888 \ + DRAW_SETPIXEL_BLEND(RGB_FROM_RGB888(*pixel, sr, sg, sb), \ + RGB888_FROM_RGB(*pixel, sr, sg, sb)) + +#define DRAW_SETPIXEL_ADD_RGB888 \ + DRAW_SETPIXEL_ADD(RGB_FROM_RGB888(*pixel, sr, sg, sb), \ + RGB888_FROM_RGB(*pixel, sr, sg, sb)) + +#define DRAW_SETPIXEL_MOD_RGB888 \ + DRAW_SETPIXEL_MOD(RGB_FROM_RGB888(*pixel, sr, sg, sb), \ + RGB888_FROM_RGB(*pixel, sr, sg, sb)) + +#define DRAW_SETPIXEL_MUL_RGB888 \ + DRAW_SETPIXEL_MUL(RGB_FROM_RGB888(*pixel, sr, sg, sb), \ + RGB888_FROM_RGB(*pixel, sr, sg, sb)) + +#define DRAW_SETPIXELXY_RGB888(x, y) \ + DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_RGB888) + +#define DRAW_SETPIXELXY_BLEND_RGB888(x, y) \ + DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_BLEND_RGB888) + +#define DRAW_SETPIXELXY_ADD_RGB888(x, y) \ + DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_ADD_RGB888) + +#define DRAW_SETPIXELXY_MOD_RGB888(x, y) \ + DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_MOD_RGB888) + +#define DRAW_SETPIXELXY_MUL_RGB888(x, y) \ + DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_MUL_RGB888) + +/* + * Define draw operators for ARGB8888 + */ + +#define DRAW_SETPIXEL_ARGB8888 \ + DRAW_SETPIXEL(ARGB8888_FROM_RGBA(*pixel, sr, sg, sb, sa)) + +#define DRAW_SETPIXEL_BLEND_ARGB8888 \ + DRAW_SETPIXEL_BLEND(RGBA_FROM_ARGB8888(*pixel, sr, sg, sb, sa), \ + ARGB8888_FROM_RGBA(*pixel, sr, sg, sb, sa)) + +#define DRAW_SETPIXEL_ADD_ARGB8888 \ + DRAW_SETPIXEL_ADD(RGBA_FROM_ARGB8888(*pixel, sr, sg, sb, sa), \ + ARGB8888_FROM_RGBA(*pixel, sr, sg, sb, sa)) + +#define DRAW_SETPIXEL_MOD_ARGB8888 \ + DRAW_SETPIXEL_MOD(RGBA_FROM_ARGB8888(*pixel, sr, sg, sb, sa), \ + ARGB8888_FROM_RGBA(*pixel, sr, sg, sb, sa)) + +#define DRAW_SETPIXEL_MUL_ARGB8888 \ + DRAW_SETPIXEL_MUL(RGBA_FROM_ARGB8888(*pixel, sr, sg, sb, sa), \ + ARGB8888_FROM_RGBA(*pixel, sr, sg, sb, sa)) + +#define DRAW_SETPIXELXY_ARGB8888(x, y) \ + DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_ARGB8888) + +#define DRAW_SETPIXELXY_BLEND_ARGB8888(x, y) \ + DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_BLEND_ARGB8888) + +#define DRAW_SETPIXELXY_ADD_ARGB8888(x, y) \ + DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_ADD_ARGB8888) + +#define DRAW_SETPIXELXY_MOD_ARGB8888(x, y) \ + DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_MOD_ARGB8888) + +#define DRAW_SETPIXELXY_MUL_ARGB8888(x, y) \ + DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_MUL_ARGB8888) + +/* + * Define draw operators for general RGB + */ + +#define DRAW_SETPIXEL_RGB \ + DRAW_SETPIXEL(PIXEL_FROM_RGB(*pixel, fmt, sr, sg, sb)) + +#define DRAW_SETPIXEL_BLEND_RGB \ + DRAW_SETPIXEL_BLEND(RGB_FROM_PIXEL(*pixel, fmt, sr, sg, sb), \ + PIXEL_FROM_RGB(*pixel, fmt, sr, sg, sb)) + +#define DRAW_SETPIXEL_ADD_RGB \ + DRAW_SETPIXEL_ADD(RGB_FROM_PIXEL(*pixel, fmt, sr, sg, sb), \ + PIXEL_FROM_RGB(*pixel, fmt, sr, sg, sb)) + +#define DRAW_SETPIXEL_MOD_RGB \ + DRAW_SETPIXEL_MOD(RGB_FROM_PIXEL(*pixel, fmt, sr, sg, sb), \ + PIXEL_FROM_RGB(*pixel, fmt, sr, sg, sb)) + +#define DRAW_SETPIXEL_MUL_RGB \ + DRAW_SETPIXEL_MUL(RGB_FROM_PIXEL(*pixel, fmt, sr, sg, sb), \ + PIXEL_FROM_RGB(*pixel, fmt, sr, sg, sb)) + +#define DRAW_SETPIXELXY2_RGB(x, y) \ + DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_RGB) + +#define DRAW_SETPIXELXY4_RGB(x, y) \ + DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_RGB) + +#define DRAW_SETPIXELXY2_BLEND_RGB(x, y) \ + DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_BLEND_RGB) + +#define DRAW_SETPIXELXY4_BLEND_RGB(x, y) \ + DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_BLEND_RGB) + +#define DRAW_SETPIXELXY2_ADD_RGB(x, y) \ + DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_ADD_RGB) + +#define DRAW_SETPIXELXY4_ADD_RGB(x, y) \ + DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_ADD_RGB) + +#define DRAW_SETPIXELXY2_MOD_RGB(x, y) \ + DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_MOD_RGB) + +#define DRAW_SETPIXELXY4_MOD_RGB(x, y) \ + DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_MOD_RGB) + +#define DRAW_SETPIXELXY2_MUL_RGB(x, y) \ + DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_MUL_RGB) + +#define DRAW_SETPIXELXY4_MUL_RGB(x, y) \ + DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_MUL_RGB) + +/* + * Define draw operators for general RGBA + */ + +#define DRAW_SETPIXEL_RGBA \ + DRAW_SETPIXEL(PIXEL_FROM_RGBA(*pixel, fmt, sr, sg, sb, sa)) + +#define DRAW_SETPIXEL_BLEND_RGBA \ + DRAW_SETPIXEL_BLEND(RGBA_FROM_PIXEL(*pixel, fmt, sr, sg, sb, sa), \ + PIXEL_FROM_RGBA(*pixel, fmt, sr, sg, sb, sa)) + +#define DRAW_SETPIXEL_ADD_RGBA \ + DRAW_SETPIXEL_ADD(RGBA_FROM_PIXEL(*pixel, fmt, sr, sg, sb, sa), \ + PIXEL_FROM_RGBA(*pixel, fmt, sr, sg, sb, sa)) + +#define DRAW_SETPIXEL_MOD_RGBA \ + DRAW_SETPIXEL_MOD(RGBA_FROM_PIXEL(*pixel, fmt, sr, sg, sb, sa), \ + PIXEL_FROM_RGBA(*pixel, fmt, sr, sg, sb, sa)) + +#define DRAW_SETPIXEL_MUL_RGBA \ + DRAW_SETPIXEL_MUL(RGBA_FROM_PIXEL(*pixel, fmt, sr, sg, sb, sa), \ + PIXEL_FROM_RGBA(*pixel, fmt, sr, sg, sb, sa)) + +#define DRAW_SETPIXELXY4_RGBA(x, y) \ + DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_RGBA) + +#define DRAW_SETPIXELXY4_BLEND_RGBA(x, y) \ + DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_BLEND_RGBA) + +#define DRAW_SETPIXELXY4_ADD_RGBA(x, y) \ + DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_ADD_RGBA) + +#define DRAW_SETPIXELXY4_MOD_RGBA(x, y) \ + DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_MOD_RGBA) + +#define DRAW_SETPIXELXY4_MUL_RGBA(x, y) \ + DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_MUL_RGBA) + +/* + * Define line drawing macro + */ + +#define ABS(_x) ((_x) < 0 ? -(_x) : (_x)) + +/* Horizontal line */ +#define HLINE(type, op, draw_end) \ + { \ + int length; \ + int pitch = (dst->pitch / dst->format->BytesPerPixel); \ + type *pixel; \ + if (x1 <= x2) { \ + pixel = (type *)dst->pixels + y1 * pitch + x1; \ + length = draw_end ? (x2 - x1 + 1) : (x2 - x1); \ + } else { \ + pixel = (type *)dst->pixels + y1 * pitch + x2; \ + if (!draw_end) { \ + ++pixel; \ + } \ + length = draw_end ? (x1 - x2 + 1) : (x1 - x2); \ + } \ + while (length--) { \ + op; \ + ++pixel; \ + } \ + } + +/* Vertical line */ +#define VLINE(type, op, draw_end) \ + { \ + int length; \ + int pitch = (dst->pitch / dst->format->BytesPerPixel); \ + type *pixel; \ + if (y1 <= y2) { \ + pixel = (type *)dst->pixels + y1 * pitch + x1; \ + length = draw_end ? (y2 - y1 + 1) : (y2 - y1); \ + } else { \ + pixel = (type *)dst->pixels + y2 * pitch + x1; \ + if (!draw_end) { \ + pixel += pitch; \ + } \ + length = draw_end ? (y1 - y2 + 1) : (y1 - y2); \ + } \ + while (length--) { \ + op; \ + pixel += pitch; \ + } \ + } + +/* Diagonal line */ +#define DLINE(type, op, draw_end) \ + { \ + int length; \ + int pitch = (dst->pitch / dst->format->BytesPerPixel); \ + type *pixel; \ + if (y1 <= y2) { \ + pixel = (type *)dst->pixels + y1 * pitch + x1; \ + if (x1 <= x2) { \ + ++pitch; \ + } else { \ + --pitch; \ + } \ + length = (y2 - y1); \ + } else { \ + pixel = (type *)dst->pixels + y2 * pitch + x2; \ + if (x2 <= x1) { \ + ++pitch; \ + } else { \ + --pitch; \ + } \ + if (!draw_end) { \ + pixel += pitch; \ + } \ + length = (y1 - y2); \ + } \ + if (draw_end) { \ + ++length; \ + } \ + while (length--) { \ + op; \ + pixel += pitch; \ + } \ + } + +/* Bresenham's line algorithm */ +#define BLINE(x1, y1, x2, y2, op, draw_end) \ + { \ + int i, deltax, deltay, numpixels; \ + int d, dinc1, dinc2; \ + int x, xinc1, xinc2; \ + int y, yinc1, yinc2; \ + \ + deltax = ABS(x2 - x1); \ + deltay = ABS(y2 - y1); \ + \ + if (deltax >= deltay) { \ + numpixels = deltax + 1; \ + d = (2 * deltay) - deltax; \ + dinc1 = deltay * 2; \ + dinc2 = (deltay - deltax) * 2; \ + xinc1 = 1; \ + xinc2 = 1; \ + yinc1 = 0; \ + yinc2 = 1; \ + } else { \ + numpixels = deltay + 1; \ + d = (2 * deltax) - deltay; \ + dinc1 = deltax * 2; \ + dinc2 = (deltax - deltay) * 2; \ + xinc1 = 0; \ + xinc2 = 1; \ + yinc1 = 1; \ + yinc2 = 1; \ + } \ + \ + if (x1 > x2) { \ + xinc1 = -xinc1; \ + xinc2 = -xinc2; \ + } \ + if (y1 > y2) { \ + yinc1 = -yinc1; \ + yinc2 = -yinc2; \ + } \ + \ + x = x1; \ + y = y1; \ + \ + if (!draw_end) { \ + --numpixels; \ + } \ + for (i = 0; i < numpixels; ++i) { \ + op(x, y); \ + if (d < 0) { \ + d += dinc1; \ + x += xinc1; \ + y += yinc1; \ + } else { \ + d += dinc2; \ + x += xinc2; \ + y += yinc2; \ + } \ + } \ + } + +/* Xiaolin Wu's line algorithm, based on Michael Abrash's implementation */ +#define WULINE(x1, y1, x2, y2, opaque_op, blend_op, draw_end) \ + { \ + Uint16 ErrorAdj, ErrorAcc; \ + Uint16 ErrorAccTemp, Weighting; \ + int DeltaX, DeltaY, Temp, XDir; \ + unsigned r, g, b, a, inva; \ + \ + /* Draw the initial pixel, which is always exactly intersected by \ + the line and so needs no weighting */ \ + opaque_op(x1, y1); \ + \ + /* Draw the final pixel, which is always exactly intersected by the line \ + and so needs no weighting */ \ + if (draw_end) { \ + opaque_op(x2, y2); \ + } \ + \ + /* Make sure the line runs top to bottom */ \ + if (y1 > y2) { \ + Temp = y1; \ + y1 = y2; \ + y2 = Temp; \ + Temp = x1; \ + x1 = x2; \ + x2 = Temp; \ + } \ + DeltaY = y2 - y1; \ + \ + if ((DeltaX = x2 - x1) >= 0) { \ + XDir = 1; \ + } else { \ + XDir = -1; \ + DeltaX = -DeltaX; /* make DeltaX positive */ \ + } \ + \ + /* line is not horizontal, diagonal, or vertical */ \ + ErrorAcc = 0; /* initialize the line error accumulator to 0 */ \ + \ + /* Is this an X-major or Y-major line? */ \ + if (DeltaY > DeltaX) { \ + /* Y-major line; calculate 16-bit fixed-point fractional part of a \ + pixel that X advances each time Y advances 1 pixel, truncating the \ + result so that we won't overrun the endpoint along the X axis */ \ + ErrorAdj = ((unsigned long)DeltaX << 16) / (unsigned long)DeltaY; \ + /* Draw all pixels other than the first and last */ \ + while (--DeltaY) { \ + ErrorAccTemp = ErrorAcc; /* remember currrent accumulated error */ \ + ErrorAcc += ErrorAdj; /* calculate error for next pixel */ \ + if (ErrorAcc <= ErrorAccTemp) { \ + /* The error accumulator turned over, so advance the X coord */ \ + x1 += XDir; \ + } \ + y1++; /* Y-major, so always advance Y */ \ + /* The IntensityBits most significant bits of ErrorAcc give us the \ + intensity weighting for this pixel, and the complement of the \ + weighting for the paired pixel */ \ + Weighting = ErrorAcc >> 8; \ + { \ + a = DRAW_MUL(_a, (Weighting ^ 255)); \ + r = DRAW_MUL(_r, a); \ + g = DRAW_MUL(_g, a); \ + b = DRAW_MUL(_b, a); \ + inva = (a ^ 0xFF); \ + blend_op(x1, y1); \ + } \ + { \ + a = DRAW_MUL(_a, Weighting); \ + r = DRAW_MUL(_r, a); \ + g = DRAW_MUL(_g, a); \ + b = DRAW_MUL(_b, a); \ + inva = (a ^ 0xFF); \ + blend_op(x1 + XDir, y1); \ + } \ + } \ + } else { \ + /* X-major line; calculate 16-bit fixed-point fractional part of a \ + pixel that Y advances each time X advances 1 pixel, truncating the \ + result to avoid overrunning the endpoint along the X axis */ \ + ErrorAdj = ((unsigned long)DeltaY << 16) / (unsigned long)DeltaX; \ + /* Draw all pixels other than the first and last */ \ + while (--DeltaX) { \ + ErrorAccTemp = ErrorAcc; /* remember currrent accumulated error */ \ + ErrorAcc += ErrorAdj; /* calculate error for next pixel */ \ + if (ErrorAcc <= ErrorAccTemp) { \ + /* The error accumulator turned over, so advance the Y coord */ \ + y1++; \ + } \ + x1 += XDir; /* X-major, so always advance X */ \ + /* The IntensityBits most significant bits of ErrorAcc give us the \ + intensity weighting for this pixel, and the complement of the \ + weighting for the paired pixel */ \ + Weighting = ErrorAcc >> 8; \ + { \ + a = DRAW_MUL(_a, (Weighting ^ 255)); \ + r = DRAW_MUL(_r, a); \ + g = DRAW_MUL(_g, a); \ + b = DRAW_MUL(_b, a); \ + inva = (a ^ 0xFF); \ + blend_op(x1, y1); \ + } \ + { \ + a = DRAW_MUL(_a, Weighting); \ + r = DRAW_MUL(_r, a); \ + g = DRAW_MUL(_g, a); \ + b = DRAW_MUL(_b, a); \ + inva = (a ^ 0xFF); \ + blend_op(x1, y1 + 1); \ + } \ + } \ + } \ + } + +#ifdef AA_LINES +#define AALINE(x1, y1, x2, y2, opaque_op, blend_op, draw_end) \ + WULINE(x1, y1, x2, y2, opaque_op, blend_op, draw_end) +#else +#define AALINE(x1, y1, x2, y2, opaque_op, blend_op, draw_end) \ + BLINE(x1, y1, x2, y2, opaque_op, draw_end) +#endif + +/* + * Define fill rect macro + */ + +#define FILLRECT(type, op) \ + do { \ + int width = rect->w; \ + int height = rect->h; \ + int pitch = (dst->pitch / dst->format->BytesPerPixel); \ + int skip = pitch - width; \ + type *pixel = (type *)dst->pixels + rect->y * pitch + rect->x; \ + while (height--) { \ + { \ + int n = (width + 3) / 4; \ + switch (width & 3) { \ + case 0: \ + do { \ + op; \ + pixel++; \ + SDL_FALLTHROUGH; \ + case 3: \ + op; \ + pixel++; \ + SDL_FALLTHROUGH; \ + case 2: \ + op; \ + pixel++; \ + SDL_FALLTHROUGH; \ + case 1: \ + op; \ + pixel++; \ + } while (--n > 0); \ + } \ + } \ + pixel += skip; \ + } \ + } while (0) + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/render/software/SDL_drawline.c b/SDL2-2.30.5/src/render/software/SDL_drawline.c similarity index 74% rename from SDL2-2.0.12/src/render/software/SDL_drawline.c rename to SDL2-2.30.5/src/render/software/SDL_drawline.c index 0faeb4f..e164a8f 100644 --- a/SDL2-2.0.12/src/render/software/SDL_drawline.c +++ b/SDL2-2.30.5/src/render/software/SDL_drawline.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,16 +20,14 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_RENDER_SW && !SDL_RENDER_DISABLED +#if SDL_VIDEO_RENDER_SW #include "SDL_draw.h" #include "SDL_drawline.h" #include "SDL_drawpoint.h" - -static void -SDL_DrawLine1(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color, - SDL_bool draw_end) +static void SDL_DrawLine1(SDL_Surface *dst, int x1, int y1, int x2, int y2, Uint32 color, + SDL_bool draw_end) { if (y1 == y2) { int length; @@ -37,13 +35,13 @@ SDL_DrawLine1(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color, Uint8 *pixel; if (x1 <= x2) { pixel = (Uint8 *)dst->pixels + y1 * pitch + x1; - length = draw_end ? (x2-x1+1) : (x2-x1); + length = draw_end ? (x2 - x1 + 1) : (x2 - x1); } else { pixel = (Uint8 *)dst->pixels + y1 * pitch + x2; if (!draw_end) { ++pixel; } - length = draw_end ? (x1-x2+1) : (x1-x2); + length = draw_end ? (x1 - x2 + 1) : (x1 - x2); } SDL_memset(pixel, color, length); } else if (x1 == x2) { @@ -55,9 +53,8 @@ SDL_DrawLine1(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color, } } -static void -SDL_DrawLine2(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color, - SDL_bool draw_end) +static void SDL_DrawLine2(SDL_Surface *dst, int x1, int y1, int x2, int y2, Uint32 color, + SDL_bool draw_end) { if (y1 == y2) { HLINE(Uint16, DRAW_FASTSETPIXEL2, draw_end); @@ -67,7 +64,7 @@ SDL_DrawLine2(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color, DLINE(Uint16, DRAW_FASTSETPIXEL2, draw_end); } else { Uint8 _r, _g, _b, _a; - const SDL_PixelFormat * fmt = dst->format; + const SDL_PixelFormat *fmt = dst->format; SDL_GetRGBA(color, fmt, &_r, &_g, &_b, &_a); if (fmt->Rmask == 0x7C00) { AALINE(x1, y1, x2, y2, @@ -85,9 +82,8 @@ SDL_DrawLine2(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color, } } -static void -SDL_DrawLine4(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color, - SDL_bool draw_end) +static void SDL_DrawLine4(SDL_Surface *dst, int x1, int y1, int x2, int y2, Uint32 color, + SDL_bool draw_end) { if (y1 == y2) { HLINE(Uint32, DRAW_FASTSETPIXEL4, draw_end); @@ -97,7 +93,7 @@ SDL_DrawLine4(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color, DLINE(Uint32, DRAW_FASTSETPIXEL4, draw_end); } else { Uint8 _r, _g, _b, _a; - const SDL_PixelFormat * fmt = dst->format; + const SDL_PixelFormat *fmt = dst->format; SDL_GetRGBA(color, fmt, &_r, &_g, &_b, &_a); if (fmt->Rmask == 0x00FF0000) { if (!fmt->Amask) { @@ -117,12 +113,11 @@ SDL_DrawLine4(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color, } } -typedef void (*DrawLineFunc) (SDL_Surface * dst, - int x1, int y1, int x2, int y2, - Uint32 color, SDL_bool draw_end); +typedef void (*DrawLineFunc)(SDL_Surface *dst, + int x1, int y1, int x2, int y2, + Uint32 color, SDL_bool draw_end); -static DrawLineFunc -SDL_CalculateDrawLineFunc(const SDL_PixelFormat * fmt) +static DrawLineFunc SDL_CalculateDrawLineFunc(const SDL_PixelFormat *fmt) { switch (fmt->BytesPerPixel) { case 1: @@ -138,13 +133,12 @@ SDL_CalculateDrawLineFunc(const SDL_PixelFormat * fmt) return NULL; } -int -SDL_DrawLine(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color) +int SDL_DrawLine(SDL_Surface *dst, int x1, int y1, int x2, int y2, Uint32 color) { DrawLineFunc func; if (!dst) { - return SDL_SetError("SDL_DrawLine(): Passed NULL destination surface"); + return SDL_InvalidParamError("SDL_DrawLine(): dst"); } func = SDL_CalculateDrawLineFunc(dst->format); @@ -162,9 +156,8 @@ SDL_DrawLine(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color) return 0; } -int -SDL_DrawLines(SDL_Surface * dst, const SDL_Point * points, int count, - Uint32 color) +int SDL_DrawLines(SDL_Surface *dst, const SDL_Point *points, int count, + Uint32 color) { int i; int x1, y1; @@ -173,7 +166,7 @@ SDL_DrawLines(SDL_Surface * dst, const SDL_Point * points, int count, DrawLineFunc func; if (!dst) { - return SDL_SetError("SDL_DrawLines(): Passed NULL destination surface"); + return SDL_InvalidParamError("SDL_DrawLines(): dst"); } func = SDL_CalculateDrawLineFunc(dst->format); @@ -182,8 +175,8 @@ SDL_DrawLines(SDL_Surface * dst, const SDL_Point * points, int count, } for (i = 1; i < count; ++i) { - x1 = points[i-1].x; - y1 = points[i-1].y; + x1 = points[i - 1].x; + y1 = points[i - 1].y; x2 = points[i].x; y2 = points[i].y; @@ -193,17 +186,17 @@ SDL_DrawLines(SDL_Surface * dst, const SDL_Point * points, int count, continue; } - /* Draw the end if it was clipped */ - draw_end = (x2 != points[i].x || y2 != points[i].y); + /* Draw the end if the whole line is a single point or it was clipped */ + draw_end = ((x1 == x2) && (y1 == y2)) || (x2 != points[i].x || y2 != points[i].y); func(dst, x1, y1, x2, y2, color, draw_end); } - if (points[0].x != points[count-1].x || points[0].y != points[count-1].y) { - SDL_DrawPoint(dst, points[count-1].x, points[count-1].y, color); + if (points[0].x != points[count - 1].x || points[0].y != points[count - 1].y) { + SDL_DrawPoint(dst, points[count - 1].x, points[count - 1].y, color); } return 0; } -#endif /* SDL_VIDEO_RENDER_SW && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_SW */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/render/software/SDL_drawline.h b/SDL2-2.30.5/src/render/software/SDL_drawline.h similarity index 80% rename from SDL2-2.0.12/src/render/software/SDL_drawline.h rename to SDL2-2.30.5/src/render/software/SDL_drawline.h index ca46434..0d406c8 100644 --- a/SDL2-2.0.12/src/render/software/SDL_drawline.h +++ b/SDL2-2.30.5/src/render/software/SDL_drawline.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -24,9 +24,8 @@ #include "../../SDL_internal.h" - -extern int SDL_DrawLine(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color); -extern int SDL_DrawLines(SDL_Surface * dst, const SDL_Point * points, int count, Uint32 color); +extern int SDL_DrawLine(SDL_Surface *dst, int x1, int y1, int x2, int y2, Uint32 color); +extern int SDL_DrawLines(SDL_Surface *dst, const SDL_Point *points, int count, Uint32 color); #endif /* SDL_drawline_h_ */ diff --git a/SDL2-2.0.12/src/render/software/SDL_drawpoint.c b/SDL2-2.30.5/src/render/software/SDL_drawpoint.c similarity index 85% rename from SDL2-2.0.12/src/render/software/SDL_drawpoint.c rename to SDL2-2.30.5/src/render/software/SDL_drawpoint.c index 0e78744..16bb9fa 100644 --- a/SDL2-2.0.12/src/render/software/SDL_drawpoint.c +++ b/SDL2-2.30.5/src/render/software/SDL_drawpoint.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,17 +20,15 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_RENDER_SW && !SDL_RENDER_DISABLED +#if SDL_VIDEO_RENDER_SW #include "SDL_draw.h" #include "SDL_drawpoint.h" - -int -SDL_DrawPoint(SDL_Surface * dst, int x, int y, Uint32 color) +int SDL_DrawPoint(SDL_Surface *dst, int x, int y, Uint32 color) { if (!dst) { - return SDL_SetError("Passed NULL destination surface"); + return SDL_InvalidParamError("SDL_DrawPoint(): dst"); } /* This function doesn't work on surfaces < 8 bpp */ @@ -61,9 +59,8 @@ SDL_DrawPoint(SDL_Surface * dst, int x, int y, Uint32 color) return 0; } -int -SDL_DrawPoints(SDL_Surface * dst, const SDL_Point * points, int count, - Uint32 color) +int SDL_DrawPoints(SDL_Surface *dst, const SDL_Point *points, int count, + Uint32 color) { int minx, miny; int maxx, maxy; @@ -71,7 +68,7 @@ SDL_DrawPoints(SDL_Surface * dst, const SDL_Point * points, int count, int x, y; if (!dst) { - return SDL_SetError("Passed NULL destination surface"); + return SDL_InvalidParamError("SDL_DrawPoints(): dst"); } /* This function doesn't work on surfaces < 8 bpp */ @@ -109,6 +106,6 @@ SDL_DrawPoints(SDL_Surface * dst, const SDL_Point * points, int count, return 0; } -#endif /* SDL_VIDEO_RENDER_SW && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_SW */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/render/software/SDL_drawpoint.h b/SDL2-2.30.5/src/render/software/SDL_drawpoint.h similarity index 81% rename from SDL2-2.0.12/src/render/software/SDL_drawpoint.h rename to SDL2-2.30.5/src/render/software/SDL_drawpoint.h index 33e014f..1e74d59 100644 --- a/SDL2-2.0.12/src/render/software/SDL_drawpoint.h +++ b/SDL2-2.30.5/src/render/software/SDL_drawpoint.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -24,9 +24,8 @@ #include "../../SDL_internal.h" - -extern int SDL_DrawPoint(SDL_Surface * dst, int x, int y, Uint32 color); -extern int SDL_DrawPoints(SDL_Surface * dst, const SDL_Point * points, int count, Uint32 color); +extern int SDL_DrawPoint(SDL_Surface *dst, int x, int y, Uint32 color); +extern int SDL_DrawPoints(SDL_Surface *dst, const SDL_Point *points, int count, Uint32 color); #endif /* SDL_drawpoint_h_ */ diff --git a/SDL2-2.0.12/src/render/software/SDL_render_sw.c b/SDL2-2.30.5/src/render/software/SDL_render_sw.c similarity index 51% rename from SDL2-2.0.12/src/render/software/SDL_render_sw.c rename to SDL2-2.30.5/src/render/software/SDL_render_sw.c index b21fa2e..b784334 100644 --- a/SDL2-2.0.12/src/render/software/SDL_render_sw.c +++ b/SDL2-2.30.5/src/render/software/SDL_render_sw.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,12 +20,11 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_RENDER_SW && !SDL_RENDER_DISABLED +#if SDL_VIDEO_RENDER_SW #include "../SDL_sysrender.h" #include "SDL_render_sw_c.h" #include "SDL_hints.h" -#include "SDL_assert.h" #include "SDL_draw.h" #include "SDL_blendfillrect.h" @@ -34,6 +33,7 @@ #include "SDL_drawline.h" #include "SDL_drawpoint.h" #include "SDL_rotate.h" +#include "SDL_triangle.h" /* SDL surface based renderer implementation */ @@ -50,11 +50,9 @@ typedef struct SDL_Surface *window; } SW_RenderData; - -static SDL_Surface * -SW_ActivateRenderer(SDL_Renderer * renderer) +static SDL_Surface *SW_ActivateRenderer(SDL_Renderer *renderer) { - SW_RenderData *data = (SW_RenderData *) renderer->driverdata; + SW_RenderData *data = (SW_RenderData *)renderer->driverdata; if (!data->surface) { data->surface = data->window; @@ -68,10 +66,9 @@ SW_ActivateRenderer(SDL_Renderer * renderer) return data->surface; } -static void -SW_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event) +static void SW_WindowEvent(SDL_Renderer *renderer, const SDL_WindowEvent *event) { - SW_RenderData *data = (SW_RenderData *) renderer->driverdata; + SW_RenderData *data = (SW_RenderData *)renderer->driverdata; if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED) { data->surface = NULL; @@ -79,10 +76,9 @@ SW_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event) } } -static int -SW_GetOutputSize(SDL_Renderer * renderer, int *w, int *h) +static int SW_GetOutputSize(SDL_Renderer *renderer, int *w, int *h) { - SW_RenderData *data = (SW_RenderData *) renderer->driverdata; + SW_RenderData *data = (SW_RenderData *)renderer->driverdata; if (data->surface) { if (w) { @@ -95,31 +91,27 @@ SW_GetOutputSize(SDL_Renderer * renderer, int *w, int *h) } if (renderer->window) { - SDL_GetWindowSize(renderer->window, w, h); + SDL_GetWindowSizeInPixels(renderer->window, w, h); return 0; } - SDL_SetError("Software renderer doesn't have an output surface"); - return -1; + return SDL_SetError("Software renderer doesn't have an output surface"); } -static int -SW_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) +static int SW_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) { int bpp; Uint32 Rmask, Gmask, Bmask, Amask; - if (!SDL_PixelFormatEnumToMasks - (texture->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) { + if (!SDL_PixelFormatEnumToMasks(texture->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) { return SDL_SetError("Unknown texture format"); } texture->driverdata = SDL_CreateRGBSurface(0, texture->w, texture->h, bpp, Rmask, Gmask, Bmask, Amask); - SDL_SetSurfaceColorMod(texture->driverdata, texture->r, texture->g, - texture->b); - SDL_SetSurfaceAlphaMod(texture->driverdata, texture->a); + SDL_SetSurfaceColorMod(texture->driverdata, texture->color.r, texture->color.g, texture->color.b); + SDL_SetSurfaceAlphaMod(texture->driverdata, texture->color.a); SDL_SetSurfaceBlendMode(texture->driverdata, texture->blendMode); /* Only RLE encode textures without an alpha channel since the RLE coder @@ -135,78 +127,73 @@ SW_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) return 0; } -static int -SW_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * rect, const void *pixels, int pitch) +static int SW_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *rect, const void *pixels, int pitch) { - SDL_Surface *surface = (SDL_Surface *) texture->driverdata; + SDL_Surface *surface = (SDL_Surface *)texture->driverdata; Uint8 *src, *dst; int row; size_t length; - if(SDL_MUSTLOCK(surface)) + if (SDL_MUSTLOCK(surface)) { SDL_LockSurface(surface); - src = (Uint8 *) pixels; - dst = (Uint8 *) surface->pixels + - rect->y * surface->pitch + - rect->x * surface->format->BytesPerPixel; - length = rect->w * surface->format->BytesPerPixel; + } + src = (Uint8 *)pixels; + dst = (Uint8 *)surface->pixels + + rect->y * surface->pitch + + rect->x * surface->format->BytesPerPixel; + length = (size_t)rect->w * surface->format->BytesPerPixel; for (row = 0; row < rect->h; ++row) { SDL_memcpy(dst, src, length); src += pitch; dst += surface->pitch; } - if(SDL_MUSTLOCK(surface)) + if (SDL_MUSTLOCK(surface)) { SDL_UnlockSurface(surface); + } return 0; } -static int -SW_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, - const SDL_Rect * rect, void **pixels, int *pitch) +static int SW_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *rect, void **pixels, int *pitch) { - SDL_Surface *surface = (SDL_Surface *) texture->driverdata; + SDL_Surface *surface = (SDL_Surface *)texture->driverdata; *pixels = - (void *) ((Uint8 *) surface->pixels + rect->y * surface->pitch + - rect->x * surface->format->BytesPerPixel); + (void *)((Uint8 *)surface->pixels + rect->y * surface->pitch + + rect->x * surface->format->BytesPerPixel); *pitch = surface->pitch; return 0; } -static void -SW_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) +static void SW_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture) { } -static void -SW_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture, SDL_ScaleMode scaleMode) +static void SW_SetTextureScaleMode(SDL_Renderer *renderer, SDL_Texture *texture, SDL_ScaleMode scaleMode) { } -static int -SW_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture) +static int SW_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture) { - SW_RenderData *data = (SW_RenderData *) renderer->driverdata; + SW_RenderData *data = (SW_RenderData *)renderer->driverdata; if (texture) { - data->surface = (SDL_Surface *) texture->driverdata; + data->surface = (SDL_Surface *)texture->driverdata; } else { data->surface = data->window; } return 0; } -static int -SW_QueueSetViewport(SDL_Renderer * renderer, SDL_RenderCommand *cmd) +static int SW_QueueSetViewport(SDL_Renderer *renderer, SDL_RenderCommand *cmd) { - return 0; /* nothing to do in this backend. */ + return 0; /* nothing to do in this backend. */ } -static int -SW_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count) +static int SW_QueueDrawPoints(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count) { - SDL_Point *verts = (SDL_Point *) SDL_AllocateRenderVertices(renderer, count * sizeof (SDL_Point), 0, &cmd->data.draw.first); + SDL_Point *verts = (SDL_Point *)SDL_AllocateRenderVertices(renderer, count * sizeof(SDL_Point), 0, &cmd->data.draw.first); int i; if (!verts) { @@ -215,27 +202,17 @@ SW_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FP cmd->data.draw.count = count; - if (renderer->viewport.x || renderer->viewport.y) { - const int x = renderer->viewport.x; - const int y = renderer->viewport.y; - for (i = 0; i < count; i++, verts++, points++) { - verts->x = (int)(x + points->x); - verts->y = (int)(y + points->y); - } - } else { - for (i = 0; i < count; i++, verts++, points++) { - verts->x = (int)points->x; - verts->y = (int)points->y; - } + for (i = 0; i < count; i++, verts++, points++) { + verts->x = (int)points->x; + verts->y = (int)points->y; } return 0; } -static int -SW_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRect * rects, int count) +static int SW_QueueFillRects(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FRect *rects, int count) { - SDL_Rect *verts = (SDL_Rect *) SDL_AllocateRenderVertices(renderer, count * sizeof (SDL_Rect), 0, &cmd->data.draw.first); + SDL_Rect *verts = (SDL_Rect *)SDL_AllocateRenderVertices(renderer, count * sizeof(SDL_Rect), 0, &cmd->data.draw.first); int i; if (!verts) { @@ -244,33 +221,20 @@ SW_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRe cmd->data.draw.count = count; - if (renderer->viewport.x || renderer->viewport.y) { - const int x = renderer->viewport.x; - const int y = renderer->viewport.y; - - for (i = 0; i < count; i++, verts++, rects++) { - verts->x = (int)(x + rects->x); - verts->y = (int)(y + rects->y); - verts->w = SDL_max((int)rects->w, 1); - verts->h = SDL_max((int)rects->h, 1); - } - } else { - for (i = 0; i < count; i++, verts++, rects++) { - verts->x = (int)rects->x; - verts->y = (int)rects->y; - verts->w = SDL_max((int)rects->w, 1); - verts->h = SDL_max((int)rects->h, 1); - } + for (i = 0; i < count; i++, verts++, rects++) { + verts->x = (int)rects->x; + verts->y = (int)rects->y; + verts->w = SDL_max((int)rects->w, 1); + verts->h = SDL_max((int)rects->h, 1); } return 0; } -static int -SW_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_FRect * dstrect) +static int SW_QueueCopy(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, + const SDL_Rect *srcrect, const SDL_FRect *dstrect) { - SDL_Rect *verts = (SDL_Rect *) SDL_AllocateRenderVertices(renderer, 2 * sizeof (SDL_Rect), 0, &cmd->data.draw.first); + SDL_Rect *verts = (SDL_Rect *)SDL_AllocateRenderVertices(renderer, 2 * sizeof(SDL_Rect), 0, &cmd->data.draw.first); if (!verts) { return -1; @@ -278,16 +242,11 @@ SW_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * text cmd->data.draw.count = 1; - SDL_memcpy(verts, srcrect, sizeof (SDL_Rect)); + SDL_copyp(verts, srcrect); verts++; - if (renderer->viewport.x || renderer->viewport.y) { - verts->x = (int)(renderer->viewport.x + dstrect->x); - verts->y = (int)(renderer->viewport.y + dstrect->y); - } else { - verts->x = (int)dstrect->x; - verts->y = (int)dstrect->y; - } + verts->x = (int)dstrect->x; + verts->y = (int)dstrect->y; verts->w = (int)dstrect->w; verts->h = (int)dstrect->h; @@ -301,14 +260,15 @@ typedef struct CopyExData double angle; SDL_FPoint center; SDL_RendererFlip flip; + float scale_x; + float scale_y; } CopyExData; -static int -SW_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_FRect * dstrect, - const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip) +static int SW_QueueCopyEx(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, + const SDL_Rect *srcrect, const SDL_FRect *dstrect, + const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip, float scale_x, float scale_y) { - CopyExData *verts = (CopyExData *) SDL_AllocateRenderVertices(renderer, sizeof (CopyExData), 0, &cmd->data.draw.first); + CopyExData *verts = (CopyExData *)SDL_AllocateRenderVertices(renderer, sizeof(CopyExData), 0, &cmd->data.draw.first); if (!verts) { return -1; @@ -316,35 +276,48 @@ SW_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * te cmd->data.draw.count = 1; - SDL_memcpy(&verts->srcrect, srcrect, sizeof (SDL_Rect)); + SDL_copyp(&verts->srcrect, srcrect); - if (renderer->viewport.x || renderer->viewport.y) { - verts->dstrect.x = (int)(renderer->viewport.x + dstrect->x); - verts->dstrect.y = (int)(renderer->viewport.y + dstrect->y); - } else { - verts->dstrect.x = (int)dstrect->x; - verts->dstrect.y = (int)dstrect->y; - } + verts->dstrect.x = (int)dstrect->x; + verts->dstrect.y = (int)dstrect->y; verts->dstrect.w = (int)dstrect->w; verts->dstrect.h = (int)dstrect->h; verts->angle = angle; - SDL_memcpy(&verts->center, center, sizeof (SDL_FPoint)); + SDL_copyp(&verts->center, center); verts->flip = flip; + verts->scale_x = scale_x; + verts->scale_y = scale_y; return 0; } -static int -SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Surface *surface, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_Rect * final_rect, - const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip) +static int Blit_to_Screen(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *surface, SDL_Rect *dstrect, + float scale_x, float scale_y, SDL_ScaleMode scaleMode) { - SDL_Surface *src = (SDL_Surface *) texture->driverdata; + int retval; + /* Renderer scaling, if needed */ + if (scale_x != 1.0f || scale_y != 1.0f) { + SDL_Rect r; + r.x = (int)((float)dstrect->x * scale_x); + r.y = (int)((float)dstrect->y * scale_y); + r.w = (int)((float)dstrect->w * scale_x); + r.h = (int)((float)dstrect->h * scale_y); + retval = SDL_PrivateUpperBlitScaled(src, srcrect, surface, &r, scaleMode); + } else { + retval = SDL_BlitSurface(src, srcrect, surface, dstrect); + } + return retval; +} + +static int SW_RenderCopyEx(SDL_Renderer *renderer, SDL_Surface *surface, SDL_Texture *texture, + const SDL_Rect *srcrect, const SDL_Rect *final_rect, + const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip, float scale_x, float scale_y) +{ + SDL_Surface *src = (SDL_Surface *)texture->driverdata; SDL_Rect tmp_rect; SDL_Surface *src_clone, *src_rotated, *src_scaled; SDL_Surface *mask = NULL, *mask_rotated = NULL; - int retval = 0, dstwidth, dstheight, abscenterx, abscentery; - double cangle, sangle, px, py, p1x, p1y, p2x, p2y, p3x, p3y, p4x, p4y; + int retval = 0; SDL_BlendMode blendmode; Uint8 alphaMod, rMod, gMod, bMod; int applyModulation = SDL_FALSE; @@ -373,7 +346,7 @@ SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Surface *surface, SDL_Texture * tex src_clone = SDL_CreateRGBSurfaceFrom(src->pixels, src->w, src->h, src->format->BitsPerPixel, src->pitch, src->format->Rmask, src->format->Gmask, src->format->Bmask, src->format->Amask); - if (src_clone == NULL) { + if (!src_clone) { if (SDL_MUSTLOCK(src)) { SDL_UnlockSurface(src); } @@ -417,7 +390,7 @@ SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Surface *surface, SDL_Texture * tex if (blendmode == SDL_BLENDMODE_NONE && !isOpaque) { mask = SDL_CreateRGBSurface(0, final_rect->w, final_rect->h, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000); - if (mask == NULL) { + if (!mask) { retval = -1; } else { SDL_SetSurfaceBlendMode(mask, SDL_BLENDMODE_MOD); @@ -431,11 +404,11 @@ SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Surface *surface, SDL_Texture * tex SDL_Rect scale_rect = tmp_rect; src_scaled = SDL_CreateRGBSurface(0, final_rect->w, final_rect->h, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000); - if (src_scaled == NULL) { + if (!src_scaled) { retval = -1; } else { SDL_SetSurfaceBlendMode(src_clone, SDL_BLENDMODE_NONE); - retval = SDL_BlitScaled(src_clone, srcrect, src_scaled, &scale_rect); + retval = SDL_PrivateUpperBlitScaled(src_clone, srcrect, src_scaled, &scale_rect, texture->scaleMode); SDL_FreeSurface(src_clone); src_clone = src_scaled; src_scaled = NULL; @@ -446,53 +419,32 @@ SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Surface *surface, SDL_Texture * tex SDL_SetSurfaceBlendMode(src_clone, blendmode); if (!retval) { - SDLgfx_rotozoomSurfaceSizeTrig(tmp_rect.w, tmp_rect.h, angle, &dstwidth, &dstheight, &cangle, &sangle); - src_rotated = SDLgfx_rotateSurface(src_clone, angle, dstwidth/2, dstheight/2, (texture->scaleMode == SDL_ScaleModeNearest) ? 0 : 1, flip & SDL_FLIP_HORIZONTAL, flip & SDL_FLIP_VERTICAL, dstwidth, dstheight, cangle, sangle); - if (src_rotated == NULL) { + SDL_Rect rect_dest; + double cangle, sangle; + + SDLgfx_rotozoomSurfaceSizeTrig(tmp_rect.w, tmp_rect.h, angle, center, + &rect_dest, &cangle, &sangle); + src_rotated = SDLgfx_rotateSurface(src_clone, angle, + (texture->scaleMode == SDL_ScaleModeNearest) ? 0 : 1, flip & SDL_FLIP_HORIZONTAL, flip & SDL_FLIP_VERTICAL, + &rect_dest, cangle, sangle, center); + if (!src_rotated) { retval = -1; } - if (!retval && mask != NULL) { + if (!retval && mask) { /* The mask needed for the NONE blend mode gets rotated with the same parameters. */ - mask_rotated = SDLgfx_rotateSurface(mask, angle, dstwidth/2, dstheight/2, SDL_FALSE, 0, 0, dstwidth, dstheight, cangle, sangle); - if (mask_rotated == NULL) { + mask_rotated = SDLgfx_rotateSurface(mask, angle, + SDL_FALSE, 0, 0, + &rect_dest, cangle, sangle, center); + if (!mask_rotated) { retval = -1; } } if (!retval) { - /* Find out where the new origin is by rotating the four final_rect points around the center and then taking the extremes */ - abscenterx = final_rect->x + (int)center->x; - abscentery = final_rect->y + (int)center->y; - /* Compensate the angle inversion to match the behaviour of the other backends */ - sangle = -sangle; - /* Top Left */ - px = final_rect->x - abscenterx; - py = final_rect->y - abscentery; - p1x = px * cangle - py * sangle + abscenterx; - p1y = px * sangle + py * cangle + abscentery; - - /* Top Right */ - px = final_rect->x + final_rect->w - abscenterx; - py = final_rect->y - abscentery; - p2x = px * cangle - py * sangle + abscenterx; - p2y = px * sangle + py * cangle + abscentery; - - /* Bottom Left */ - px = final_rect->x - abscenterx; - py = final_rect->y + final_rect->h - abscentery; - p3x = px * cangle - py * sangle + abscenterx; - p3y = px * sangle + py * cangle + abscentery; - - /* Bottom Right */ - px = final_rect->x + final_rect->w - abscenterx; - py = final_rect->y + final_rect->h - abscentery; - p4x = px * cangle - py * sangle + abscenterx; - p4y = px * sangle + py * cangle + abscentery; - - tmp_rect.x = (int)MIN(MIN(p1x, p2x), MIN(p3x, p4x)); - tmp_rect.y = (int)MIN(MIN(p1y, p2y), MIN(p3y, p4y)); - tmp_rect.w = dstwidth; - tmp_rect.h = dstheight; + tmp_rect.x = final_rect->x + rect_dest.x; + tmp_rect.y = final_rect->y + rect_dest.y; + tmp_rect.w = rect_dest.w; + tmp_rect.h = rect_dest.h; /* The NONE blend mode needs some special care with non-opaque surfaces. * Other blend modes or opaque surfaces can be blitted directly. @@ -503,7 +455,8 @@ SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Surface *surface, SDL_Texture * tex SDL_SetSurfaceAlphaMod(src_rotated, alphaMod); SDL_SetSurfaceColorMod(src_rotated, rMod, gMod, bMod); } - retval = SDL_BlitSurface(src_rotated, NULL, surface, &tmp_rect); + /* Renderer scaling, if needed */ + retval = Blit_to_Screen(src_rotated, NULL, surface, &tmp_rect, scale_x, scale_y, texture->scaleMode); } else { /* The NONE blend mode requires three steps to get the pixels onto the destination surface. * First, the area where the rotated pixels will be blitted to get set to zero. @@ -512,7 +465,8 @@ SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Surface *surface, SDL_Texture * tex */ SDL_Rect mask_rect = tmp_rect; SDL_SetSurfaceBlendMode(mask_rotated, SDL_BLENDMODE_NONE); - retval = SDL_BlitSurface(mask_rotated, NULL, surface, &mask_rect); + /* Renderer scaling, if needed */ + retval = Blit_to_Screen(mask_rotated, NULL, surface, &mask_rect, scale_x, scale_y, texture->scaleMode); if (!retval) { /* The next step copies the alpha value. This is done with the BLEND blend mode and * by modulating the source colors with 0. Since the destination is all zeros, this @@ -520,7 +474,8 @@ SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Surface *surface, SDL_Texture * tex */ SDL_SetSurfaceColorMod(src_rotated, 0, 0, 0); mask_rect = tmp_rect; - retval = SDL_BlitSurface(src_rotated, NULL, surface, &mask_rect); + /* Renderer scaling, if needed */ + retval = Blit_to_Screen(src_rotated, NULL, surface, &mask_rect, scale_x, scale_y, texture->scaleMode); if (!retval) { /* The last step gets the color values in place. The ADD blend mode simply adds them to * the destination (where the color values are all zero). However, because the ADD blend @@ -532,18 +487,19 @@ SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Surface *surface, SDL_Texture * tex src_rotated->format->BitsPerPixel, src_rotated->pitch, src_rotated->format->Rmask, src_rotated->format->Gmask, src_rotated->format->Bmask, 0); - if (src_rotated_rgb == NULL) { + if (!src_rotated_rgb) { retval = -1; } else { SDL_SetSurfaceBlendMode(src_rotated_rgb, SDL_BLENDMODE_ADD); - retval = SDL_BlitSurface(src_rotated_rgb, NULL, surface, &tmp_rect); + /* Renderer scaling, if needed */ + retval = Blit_to_Screen(src_rotated_rgb, NULL, surface, &tmp_rect, scale_x, scale_y, texture->scaleMode); SDL_FreeSurface(src_rotated_rgb); } } } SDL_FreeSurface(mask_rotated); } - if (src_rotated != NULL) { + if (src_rotated) { SDL_FreeSurface(src_rotated); } } @@ -552,17 +508,112 @@ SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Surface *surface, SDL_Texture * tex if (SDL_MUSTLOCK(src)) { SDL_UnlockSurface(src); } - if (mask != NULL) { + if (mask) { SDL_FreeSurface(mask); } - if (src_clone != NULL) { + if (src_clone) { SDL_FreeSurface(src_clone); } return retval; } -static void -PrepTextureForCopy(const SDL_RenderCommand *cmd) +typedef struct GeometryFillData +{ + SDL_Point dst; + SDL_Color color; +} GeometryFillData; + +typedef struct GeometryCopyData +{ + SDL_Point src; + SDL_Point dst; + SDL_Color color; +} GeometryCopyData; + +static int SW_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, + const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride, + int num_vertices, const void *indices, int num_indices, int size_indices, + float scale_x, float scale_y) +{ + int i; + int count = indices ? num_indices : num_vertices; + void *verts; + size_t sz = texture ? sizeof(GeometryCopyData) : sizeof(GeometryFillData); + + verts = SDL_AllocateRenderVertices(renderer, count * sz, 0, &cmd->data.draw.first); + if (!verts) { + return -1; + } + + cmd->data.draw.count = count; + size_indices = indices ? size_indices : 0; + + if (texture) { + GeometryCopyData *ptr = (GeometryCopyData *)verts; + for (i = 0; i < count; i++) { + int j; + float *xy_; + SDL_Color col_; + float *uv_; + if (size_indices == 4) { + j = ((const Uint32 *)indices)[i]; + } else if (size_indices == 2) { + j = ((const Uint16 *)indices)[i]; + } else if (size_indices == 1) { + j = ((const Uint8 *)indices)[i]; + } else { + j = i; + } + + xy_ = (float *)((char *)xy + j * xy_stride); + col_ = *(SDL_Color *)((char *)color + j * color_stride); + + uv_ = (float *)((char *)uv + j * uv_stride); + + ptr->src.x = (int)(uv_[0] * texture->w); + ptr->src.y = (int)(uv_[1] * texture->h); + + ptr->dst.x = (int)(xy_[0] * scale_x); + ptr->dst.y = (int)(xy_[1] * scale_y); + trianglepoint_2_fixedpoint(&ptr->dst); + + ptr->color = col_; + + ptr++; + } + } else { + GeometryFillData *ptr = (GeometryFillData *)verts; + + for (i = 0; i < count; i++) { + int j; + float *xy_; + SDL_Color col_; + if (size_indices == 4) { + j = ((const Uint32 *)indices)[i]; + } else if (size_indices == 2) { + j = ((const Uint16 *)indices)[i]; + } else if (size_indices == 1) { + j = ((const Uint8 *)indices)[i]; + } else { + j = i; + } + + xy_ = (float *)((char *)xy + j * xy_stride); + col_ = *(SDL_Color *)((char *)color + j * color_stride); + + ptr->dst.x = (int)(xy_[0] * scale_x); + ptr->dst.y = (int)(xy_[1] * scale_y); + trianglepoint_2_fixedpoint(&ptr->dst); + + ptr->color = col_; + + ptr++; + } + } + return 0; +} + +static void PrepTextureForCopy(const SDL_RenderCommand *cmd) { const Uint8 r = cmd->data.draw.r; const Uint8 g = cmd->data.draw.g; @@ -570,7 +621,7 @@ PrepTextureForCopy(const SDL_RenderCommand *cmd) const Uint8 a = cmd->data.draw.a; const SDL_BlendMode blend = cmd->data.draw.blend; SDL_Texture *texture = cmd->data.draw.texture; - SDL_Surface *surface = (SDL_Surface *) texture->driverdata; + SDL_Surface *surface = (SDL_Surface *)texture->driverdata; const SDL_bool colormod = ((r & g & b) != 0xFF); const SDL_bool alphamod = (a != 0xFF); const SDL_bool blending = ((blend == SDL_BLENDMODE_ADD) || (blend == SDL_BLENDMODE_MOD) || (blend == SDL_BLENDMODE_MUL)); @@ -585,15 +636,14 @@ PrepTextureForCopy(const SDL_RenderCommand *cmd) SDL_SetSurfaceBlendMode(surface, blend); } -static void -SetDrawState(SDL_Surface *surface, SW_DrawStateCache *drawstate) +static void SetDrawState(SDL_Surface *surface, SW_DrawStateCache *drawstate) { if (drawstate->surface_cliprect_dirty) { const SDL_Rect *viewport = drawstate->viewport; const SDL_Rect *cliprect = drawstate->cliprect; - SDL_assert(viewport != NULL); /* the higher level should have forced a SDL_RENDERCMD_SETVIEWPORT */ + SDL_assert_release(viewport != NULL); /* the higher level should have forced a SDL_RENDERCMD_SETVIEWPORT */ - if (cliprect != NULL) { + if (cliprect) { SDL_Rect clip_rect; clip_rect.x = cliprect->x + viewport->x; clip_rect.y = cliprect->y + viewport->y; @@ -608,8 +658,7 @@ SetDrawState(SDL_Surface *surface, SW_DrawStateCache *drawstate) } } -static int -SW_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize) +static int SW_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize) { SDL_Surface *surface = SW_ActivateRenderer(renderer); SW_DrawStateCache drawstate; @@ -635,7 +684,7 @@ SW_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic } case SDL_RENDERCMD_SETCLIPRECT: { - drawstate.cliprect = cmd->data.cliprect.enabled ? &cmd->data.cliprect.rect : NULL; + drawstate.cliprect = cmd->data.cliprect.enabled ? &cmd->data.cliprect.rect : NULL; drawstate.surface_cliprect_dirty = SDL_TRUE; break; } @@ -658,9 +707,19 @@ SW_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic const Uint8 b = cmd->data.draw.b; const Uint8 a = cmd->data.draw.a; const int count = (int) cmd->data.draw.count; - const SDL_Point *verts = (SDL_Point *) (((Uint8 *) vertices) + cmd->data.draw.first); + SDL_Point *verts = (SDL_Point *) (((Uint8 *) vertices) + cmd->data.draw.first); const SDL_BlendMode blend = cmd->data.draw.blend; SetDrawState(surface, &drawstate); + + /* Apply viewport */ + if (drawstate.viewport && (drawstate.viewport->x || drawstate.viewport->y)) { + int i; + for (i = 0; i < count; i++) { + verts[i].x += drawstate.viewport->x; + verts[i].y += drawstate.viewport->y; + } + } + if (blend == SDL_BLENDMODE_NONE) { SDL_DrawPoints(surface, verts, count, SDL_MapRGBA(surface->format, r, g, b, a)); } else { @@ -675,9 +734,19 @@ SW_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic const Uint8 b = cmd->data.draw.b; const Uint8 a = cmd->data.draw.a; const int count = (int) cmd->data.draw.count; - const SDL_Point *verts = (SDL_Point *) (((Uint8 *) vertices) + cmd->data.draw.first); + SDL_Point *verts = (SDL_Point *) (((Uint8 *) vertices) + cmd->data.draw.first); const SDL_BlendMode blend = cmd->data.draw.blend; SetDrawState(surface, &drawstate); + + /* Apply viewport */ + if (drawstate.viewport && (drawstate.viewport->x || drawstate.viewport->y)) { + int i; + for (i = 0; i < count; i++) { + verts[i].x += drawstate.viewport->x; + verts[i].y += drawstate.viewport->y; + } + } + if (blend == SDL_BLENDMODE_NONE) { SDL_DrawLines(surface, verts, count, SDL_MapRGBA(surface->format, r, g, b, a)); } else { @@ -692,9 +761,19 @@ SW_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic const Uint8 b = cmd->data.draw.b; const Uint8 a = cmd->data.draw.a; const int count = (int) cmd->data.draw.count; - const SDL_Rect *verts = (SDL_Rect *) (((Uint8 *) vertices) + cmd->data.draw.first); + SDL_Rect *verts = (SDL_Rect *) (((Uint8 *) vertices) + cmd->data.draw.first); const SDL_BlendMode blend = cmd->data.draw.blend; SetDrawState(surface, &drawstate); + + /* Apply viewport */ + if (drawstate.viewport && (drawstate.viewport->x || drawstate.viewport->y)) { + int i; + for (i = 0; i < count; i++) { + verts[i].x += drawstate.viewport->x; + verts[i].y += drawstate.viewport->y; + } + } + if (blend == SDL_BLENDMODE_NONE) { SDL_FillRects(surface, verts, count, SDL_MapRGBA(surface->format, r, g, b, a)); } else { @@ -714,6 +793,12 @@ SW_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic PrepTextureForCopy(cmd); + /* Apply viewport */ + if (drawstate.viewport && (drawstate.viewport->x || drawstate.viewport->y)) { + dstrect->x += drawstate.viewport->x; + dstrect->y += drawstate.viewport->y; + } + if ( srcrect->w == dstrect->w && srcrect->h == dstrect->h ) { SDL_BlitSurface(src, srcrect, surface, dstrect); } else { @@ -721,17 +806,118 @@ SW_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic * to avoid potentially frequent RLE encoding/decoding. */ SDL_SetSurfaceRLE(surface, 0); - SDL_BlitScaled(src, srcrect, surface, dstrect); + + /* Prevent to do scaling + clipping on viewport boundaries as it may lose proportion */ + if (dstrect->x < 0 || dstrect->y < 0 || dstrect->x + dstrect->w > surface->w || dstrect->y + dstrect->h > surface->h) { + SDL_Surface *tmp = SDL_CreateRGBSurfaceWithFormat(0, dstrect->w, dstrect->h, 0, src->format->format); + /* Scale to an intermediate surface, then blit */ + if (tmp) { + SDL_Rect r; + SDL_BlendMode blendmode; + Uint8 alphaMod, rMod, gMod, bMod; + + SDL_GetSurfaceBlendMode(src, &blendmode); + SDL_GetSurfaceAlphaMod(src, &alphaMod); + SDL_GetSurfaceColorMod(src, &rMod, &gMod, &bMod); + + r.x = 0; + r.y = 0; + r.w = dstrect->w; + r.h = dstrect->h; + + SDL_SetSurfaceBlendMode(src, SDL_BLENDMODE_NONE); + SDL_SetSurfaceColorMod(src, 255, 255, 255); + SDL_SetSurfaceAlphaMod(src, 255); + + SDL_PrivateUpperBlitScaled(src, srcrect, tmp, &r, texture->scaleMode); + + SDL_SetSurfaceColorMod(tmp, rMod, gMod, bMod); + SDL_SetSurfaceAlphaMod(tmp, alphaMod); + SDL_SetSurfaceBlendMode(tmp, blendmode); + + SDL_BlitSurface(tmp, NULL, surface, dstrect); + SDL_FreeSurface(tmp); + /* No need to set back r/g/b/a/blendmode to 'src' since it's done in PrepTextureForCopy() */ + } + } else{ + SDL_PrivateUpperBlitScaled(src, srcrect, surface, dstrect, texture->scaleMode); + } } break; } case SDL_RENDERCMD_COPY_EX: { - const CopyExData *copydata = (CopyExData *) (((Uint8 *) vertices) + cmd->data.draw.first); + CopyExData *copydata = (CopyExData *) (((Uint8 *) vertices) + cmd->data.draw.first); SetDrawState(surface, &drawstate); PrepTextureForCopy(cmd); + + /* Apply viewport */ + if (drawstate.viewport && (drawstate.viewport->x || drawstate.viewport->y)) { + copydata->dstrect.x += drawstate.viewport->x; + copydata->dstrect.y += drawstate.viewport->y; + } + SW_RenderCopyEx(renderer, surface, cmd->data.draw.texture, ©data->srcrect, - ©data->dstrect, copydata->angle, ©data->center, copydata->flip); + ©data->dstrect, copydata->angle, ©data->center, copydata->flip, + copydata->scale_x, copydata->scale_y); + break; + } + + case SDL_RENDERCMD_GEOMETRY: { + int i; + SDL_Rect *verts = (SDL_Rect *) (((Uint8 *) vertices) + cmd->data.draw.first); + const int count = (int) cmd->data.draw.count; + SDL_Texture *texture = cmd->data.draw.texture; + const SDL_BlendMode blend = cmd->data.draw.blend; + + SetDrawState(surface, &drawstate); + + if (texture) { + SDL_Surface *src = (SDL_Surface *) texture->driverdata; + + GeometryCopyData *ptr = (GeometryCopyData *) verts; + + PrepTextureForCopy(cmd); + + /* Apply viewport */ + if (drawstate.viewport && (drawstate.viewport->x || drawstate.viewport->y)) { + SDL_Point vp; + vp.x = drawstate.viewport->x; + vp.y = drawstate.viewport->y; + trianglepoint_2_fixedpoint(&vp); + for (i = 0; i < count; i++) { + ptr[i].dst.x += vp.x; + ptr[i].dst.y += vp.y; + } + } + + for (i = 0; i < count; i += 3, ptr += 3) { + SDL_SW_BlitTriangle( + src, + &(ptr[0].src), &(ptr[1].src), &(ptr[2].src), + surface, + &(ptr[0].dst), &(ptr[1].dst), &(ptr[2].dst), + ptr[0].color, ptr[1].color, ptr[2].color); + } + } else { + GeometryFillData *ptr = (GeometryFillData *) verts; + + /* Apply viewport */ + if (drawstate.viewport && (drawstate.viewport->x || drawstate.viewport->y)) { + SDL_Point vp; + vp.x = drawstate.viewport->x; + vp.y = drawstate.viewport->y; + trianglepoint_2_fixedpoint(&vp); + for (i = 0; i < count; i++) { + ptr[i].dst.x += vp.x; + ptr[i].dst.y += vp.y; + } + } + + for (i = 0; i < count; i += 3, ptr += 3) { + SDL_SW_FillTriangle(surface, &(ptr[0].dst), &(ptr[1].dst), &(ptr[2].dst), blend, ptr[0].color, ptr[1].color, ptr[2].color); + } + } break; } @@ -745,9 +931,8 @@ SW_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic return 0; } -static int -SW_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, - Uint32 format, void * pixels, int pitch) +static int SW_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect, + Uint32 format, void *pixels, int pitch) { SDL_Surface *surface = SW_ActivateRenderer(renderer); Uint32 src_format; @@ -761,66 +946,67 @@ SW_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, * SDL_RenderReadPixels. */ - if (rect->x < 0 || rect->x+rect->w > surface->w || - rect->y < 0 || rect->y+rect->h > surface->h) { + if (rect->x < 0 || rect->x + rect->w > surface->w || + rect->y < 0 || rect->y + rect->h > surface->h) { return SDL_SetError("Tried to read outside of surface bounds"); } src_format = surface->format->format; - src_pixels = (void*)((Uint8 *) surface->pixels + - rect->y * surface->pitch + - rect->x * surface->format->BytesPerPixel); + src_pixels = (void *)((Uint8 *)surface->pixels + + rect->y * surface->pitch + + rect->x * surface->format->BytesPerPixel); return SDL_ConvertPixels(rect->w, rect->h, src_format, src_pixels, surface->pitch, format, pixels, pitch); } -static void -SW_RenderPresent(SDL_Renderer * renderer) +static int SW_RenderPresent(SDL_Renderer *renderer) { SDL_Window *window = renderer->window; - if (window) { - SDL_UpdateWindowSurface(window); + if (!window) { + return -1; } + return SDL_UpdateWindowSurface(window); } -static void -SW_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) +static void SW_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture) { - SDL_Surface *surface = (SDL_Surface *) texture->driverdata; + SDL_Surface *surface = (SDL_Surface *)texture->driverdata; SDL_FreeSurface(surface); } -static void -SW_DestroyRenderer(SDL_Renderer * renderer) +static void SW_DestroyRenderer(SDL_Renderer *renderer) { - SW_RenderData *data = (SW_RenderData *) renderer->driverdata; + SDL_Window *window = renderer->window; + SW_RenderData *data = (SW_RenderData *)renderer->driverdata; + if (window) { + SDL_DestroyWindowSurface(window); + } SDL_free(data); SDL_free(renderer); } -SDL_Renderer * -SW_CreateRendererForSurface(SDL_Surface * surface) +SDL_Renderer *SW_CreateRendererForSurface(SDL_Surface *surface) { SDL_Renderer *renderer; SW_RenderData *data; if (!surface) { - SDL_SetError("Can't create renderer for NULL surface"); + SDL_InvalidParamError("surface"); return NULL; } - renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer)); + renderer = (SDL_Renderer *)SDL_calloc(1, sizeof(*renderer)); if (!renderer) { SDL_OutOfMemory(); return NULL; } - data = (SW_RenderData *) SDL_calloc(1, sizeof(*data)); + data = (SW_RenderData *)SDL_calloc(1, sizeof(*data)); if (!data) { SW_DestroyRenderer(renderer); SDL_OutOfMemory(); @@ -838,12 +1024,13 @@ SW_CreateRendererForSurface(SDL_Surface * surface) renderer->SetTextureScaleMode = SW_SetTextureScaleMode; renderer->SetRenderTarget = SW_SetRenderTarget; renderer->QueueSetViewport = SW_QueueSetViewport; - renderer->QueueSetDrawColor = SW_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */ + renderer->QueueSetDrawColor = SW_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */ renderer->QueueDrawPoints = SW_QueueDrawPoints; - renderer->QueueDrawLines = SW_QueueDrawPoints; /* lines and points queue vertices the same way. */ + renderer->QueueDrawLines = SW_QueueDrawPoints; /* lines and points queue vertices the same way. */ renderer->QueueFillRects = SW_QueueFillRects; renderer->QueueCopy = SW_QueueCopy; renderer->QueueCopyEx = SW_QueueCopyEx; + renderer->QueueGeometry = SW_QueueGeometry; renderer->RunCommandQueue = SW_RunCommandQueue; renderer->RenderReadPixels = SW_RenderReadPixels; renderer->RenderPresent = SW_RenderPresent; @@ -852,17 +1039,34 @@ SW_CreateRendererForSurface(SDL_Surface * surface) renderer->info = SW_RenderDriver.info; renderer->driverdata = data; - SW_ActivateRenderer(renderer); - return renderer; } -static SDL_Renderer * -SW_CreateRenderer(SDL_Window * window, Uint32 flags) +static SDL_Renderer *SW_CreateRenderer(SDL_Window *window, Uint32 flags) { + const char *hint; SDL_Surface *surface; + SDL_bool no_hint_set; + + /* Set the vsync hint based on our flags, if it's not already set */ + hint = SDL_GetHint(SDL_HINT_RENDER_VSYNC); + if (!hint || !*hint) { + no_hint_set = SDL_TRUE; + } else { + no_hint_set = SDL_FALSE; + } + + if (no_hint_set) { + SDL_SetHint(SDL_HINT_RENDER_VSYNC, (flags & SDL_RENDERER_PRESENTVSYNC) ? "1" : "0"); + } surface = SDL_GetWindowSurface(window); + + /* Reset the vsync hint if we set it above */ + if (no_hint_set) { + SDL_SetHint(SDL_HINT_RENDER_VSYNC, ""); + } + if (!surface) { return NULL; } @@ -873,7 +1077,7 @@ SDL_RenderDriver SW_RenderDriver = { SW_CreateRenderer, { "software", - SDL_RENDERER_SOFTWARE | SDL_RENDERER_TARGETTEXTURE, + SDL_RENDERER_SOFTWARE | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE, 8, { SDL_PIXELFORMAT_ARGB8888, @@ -889,6 +1093,6 @@ SDL_RenderDriver SW_RenderDriver = { 0} }; -#endif /* SDL_VIDEO_RENDER_SW && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_SW */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/render/software/SDL_render_sw_c.h b/SDL2-2.30.5/src/render/software/SDL_render_sw_c.h similarity index 88% rename from SDL2-2.0.12/src/render/software/SDL_render_sw_c.h rename to SDL2-2.30.5/src/render/software/SDL_render_sw_c.h index fa6289b..1d7901f 100644 --- a/SDL2-2.0.12/src/render/software/SDL_render_sw_c.h +++ b/SDL2-2.30.5/src/render/software/SDL_render_sw_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -22,7 +22,7 @@ #ifndef SDL_render_sw_c_h_ #define SDL_render_sw_c_h_ -extern SDL_Renderer * SW_CreateRendererForSurface(SDL_Surface * surface); +extern SDL_Renderer *SW_CreateRendererForSurface(SDL_Surface *surface); #endif /* SDL_render_sw_c_h_ */ diff --git a/SDL2-2.0.12/src/render/software/SDL_rotate.c b/SDL2-2.30.5/src/render/software/SDL_rotate.c similarity index 54% rename from SDL2-2.0.12/src/render/software/SDL_rotate.c rename to SDL2-2.30.5/src/render/software/SDL_rotate.c index a903d1d..d29b92d 100644 --- a/SDL2-2.0.12/src/render/software/SDL_rotate.c +++ b/SDL2-2.30.5/src/render/software/SDL_rotate.c @@ -30,9 +30,9 @@ Andreas Schiffler -- aschiffler at ferzkopp dot net */ #include "../../SDL_internal.h" -#if SDL_VIDEO_RENDER_SW && !SDL_RENDER_DISABLED +#if SDL_VIDEO_RENDER_SW -#if defined(__WIN32__) +#if defined(__WIN32__) || defined(__GDK__) #include "../../core/windows/SDL_windows.h" #endif @@ -47,7 +47,8 @@ Andreas Schiffler -- aschiffler at ferzkopp dot net /* ! \brief A 32 bit RGBA pixel. */ -typedef struct tColorRGBA { +typedef struct tColorRGBA +{ Uint8 r; Uint8 g; Uint8 b; @@ -57,15 +58,11 @@ typedef struct tColorRGBA { /* ! \brief A 8bit Y/palette pixel. */ -typedef struct tColorY { +typedef struct tColorY +{ Uint8 y; } tColorY; -/* ! -\brief Returns maximum of two numbers a and b. -*/ -#define MAX(a,b) (((a) > (b)) ? (a) : (b)) - /* ! \brief Number of guard rows added to destination surfaces. @@ -81,8 +78,7 @@ to a situation where the program can segfault. /* ! \brief Returns colorkey info for a surface */ -static Uint32 -_colorkey(SDL_Surface *src) +static Uint32 get_colorkey(SDL_Surface *src) { Uint32 key = 0; if (SDL_HasColorKey(src)) { @@ -91,6 +87,18 @@ _colorkey(SDL_Surface *src) return key; } +/* rotate (sx, sy) by (angle, center) into (dx, dy) */ +static void rotate(double sx, double sy, double sinangle, double cosangle, const SDL_FPoint *center, double *dx, double *dy) +{ + sx -= center->x; + sy -= center->y; + + *dx = cosangle * sx - sinangle * sy; + *dy = sinangle * sx + cosangle * sy; + + *dx += center->x; + *dy += center->y; +} /* ! \brief Internal target surface sizing function for rotations with trig result return. @@ -104,67 +112,99 @@ _colorkey(SDL_Surface *src) \param sangle The cosine of the angle */ -void -SDLgfx_rotozoomSurfaceSizeTrig(int width, int height, double angle, - int *dstwidth, int *dstheight, - double *cangle, double *sangle) +void SDLgfx_rotozoomSurfaceSizeTrig(int width, int height, double angle, const SDL_FPoint *center, + SDL_Rect *rect_dest, double *cangle, double *sangle) { - /* The trig code below gets the wrong size (due to FP inaccuracy?) when angle is a multiple of 90 degrees */ - int angle90 = (int)(angle/90); - if(angle90 == angle/90) { /* if the angle is a multiple of 90 degrees */ - angle90 %= 4; - if(angle90 < 0) angle90 += 4; /* 0:0 deg, 1:90 deg, 2:180 deg, 3:270 deg */ - if(angle90 & 1) { - *dstwidth = height; - *dstheight = width; - *cangle = 0; - *sangle = angle90 == 1 ? -1 : 1; /* reversed because our rotations are clockwise */ - } else { - *dstwidth = width; - *dstheight = height; - *cangle = angle90 == 0 ? 1 : -1; - *sangle = 0; - } - } else { - double x, y, cx, cy, sx, sy; - double radangle; - int dstwidthhalf, dstheighthalf; - /* - * Determine destination width and height by rotating a centered source box - */ - radangle = angle * (M_PI / -180.0); /* reverse the angle because our rotations are clockwise */ - *sangle = SDL_sin(radangle); - *cangle = SDL_cos(radangle); - x = (double)(width / 2); - y = (double)(height / 2); - cx = *cangle * x; - cy = *cangle * y; - sx = *sangle * x; - sy = *sangle * y; + int minx, maxx, miny, maxy; + double radangle; + double x0, x1, x2, x3; + double y0, y1, y2, y3; + double sinangle; + double cosangle; - dstwidthhalf = MAX((int) - SDL_ceil(MAX(MAX(MAX(SDL_fabs(cx + sy), SDL_fabs(cx - sy)), SDL_fabs(-cx + sy)), SDL_fabs(-cx - sy))), 1); - dstheighthalf = MAX((int) - SDL_ceil(MAX(MAX(MAX(SDL_fabs(sx + cy), SDL_fabs(sx - cy)), SDL_fabs(-sx + cy)), SDL_fabs(-sx - cy))), 1); - *dstwidth = 2 * dstwidthhalf; - *dstheight = 2 * dstheighthalf; + radangle = angle * (M_PI / 180.0); + sinangle = SDL_sin(radangle); + cosangle = SDL_cos(radangle); + + /* + * Determine destination width and height by rotating a source box, at pixel center + */ + rotate(0.5, 0.5, sinangle, cosangle, center, &x0, &y0); + rotate(width - 0.5, 0.5, sinangle, cosangle, center, &x1, &y1); + rotate(0.5, height - 0.5, sinangle, cosangle, center, &x2, &y2); + rotate(width - 0.5, height - 0.5, sinangle, cosangle, center, &x3, &y3); + + minx = (int)SDL_floor(SDL_min(SDL_min(x0, x1), SDL_min(x2, x3))); + maxx = (int)SDL_ceil(SDL_max(SDL_max(x0, x1), SDL_max(x2, x3))); + + miny = (int)SDL_floor(SDL_min(SDL_min(y0, y1), SDL_min(y2, y3))); + maxy = (int)SDL_ceil(SDL_max(SDL_max(y0, y1), SDL_max(y2, y3))); + + rect_dest->w = maxx - minx; + rect_dest->h = maxy - miny; + rect_dest->x = minx; + rect_dest->y = miny; + + /* reverse the angle because our rotations are clockwise */ + *sangle = -sinangle; + *cangle = cosangle; + + { + /* The trig code below gets the wrong size (due to FP inaccuracy?) when angle is a multiple of 90 degrees */ + int angle90 = (int)(angle / 90); + if (angle90 == angle / 90) { /* if the angle is a multiple of 90 degrees */ + angle90 %= 4; + if (angle90 < 0) { + angle90 += 4; /* 0:0 deg, 1:90 deg, 2:180 deg, 3:270 deg */ + } + + if (angle90 & 1) { + rect_dest->w = height; + rect_dest->h = width; + *cangle = 0; + *sangle = angle90 == 1 ? -1 : 1; /* reversed because our rotations are clockwise */ + } else { + rect_dest->w = width; + rect_dest->h = height; + *cangle = angle90 == 0 ? 1 : -1; + *sangle = 0; + } + } } } /* Computes source pointer X/Y increments for a rotation that's a multiple of 90 degrees. */ -static void -computeSourceIncrements90(SDL_Surface * src, int bpp, int angle, int flipx, int flipy, - int *sincx, int *sincy, int *signx, int *signy) +static void computeSourceIncrements90(SDL_Surface *src, int bpp, int angle, int flipx, int flipy, + int *sincx, int *sincy, int *signx, int *signy) { int pitch = flipy ? -src->pitch : src->pitch; if (flipx) { bpp = -bpp; } switch (angle) { /* 0:0 deg, 1:90 deg, 2:180 deg, 3:270 deg */ - case 0: *sincx = bpp; *sincy = pitch - src->w * *sincx; *signx = *signy = 1; break; - case 1: *sincx = -pitch; *sincy = bpp - *sincx * src->h; *signx = 1; *signy = -1; break; - case 2: *sincx = -bpp; *sincy = -src->w * *sincx - pitch; *signx = *signy = -1; break; - case 3: default: *sincx = pitch; *sincy = -*sincx * src->h - bpp; *signx = -1; *signy = 1; break; + case 0: + *sincx = bpp; + *sincy = pitch - src->w * *sincx; + *signx = *signy = 1; + break; + case 1: + *sincx = -pitch; + *sincy = bpp - *sincx * src->h; + *signx = 1; + *signy = -1; + break; + case 2: + *sincx = -bpp; + *sincy = -src->w * *sincx - pitch; + *signx = *signy = -1; + break; + case 3: + default: + *sincx = pitch; + *sincy = -*sincx * src->h - bpp; + *signx = -1; + *signy = 1; + break; } if (flipx) { *signx = -*signx; @@ -175,34 +215,34 @@ computeSourceIncrements90(SDL_Surface * src, int bpp, int angle, int flipx, int } /* Performs a relatively fast rotation/flip when the angle is a multiple of 90 degrees. */ -#define TRANSFORM_SURFACE_90(pixelType) \ - int dy, dincy = dst->pitch - dst->w*sizeof(pixelType), sincx, sincy, signx, signy; \ - Uint8 *sp = (Uint8*)src->pixels, *dp = (Uint8*)dst->pixels, *de; \ +#define TRANSFORM_SURFACE_90(pixelType) \ + int dy, dincy = dst->pitch - dst->w * sizeof(pixelType), sincx, sincy, signx, signy; \ + Uint8 *sp = (Uint8 *)src->pixels, *dp = (Uint8 *)dst->pixels, *de; \ \ computeSourceIncrements90(src, sizeof(pixelType), angle, flipx, flipy, &sincx, &sincy, &signx, &signy); \ - if (signx < 0) sp += (src->w-1)*sizeof(pixelType); \ - if (signy < 0) sp += (src->h-1)*src->pitch; \ + if (signx < 0) \ + sp += (src->w - 1) * sizeof(pixelType); \ + if (signy < 0) \ + sp += (src->h - 1) * src->pitch; \ \ for (dy = 0; dy < dst->h; sp += sincy, dp += dincy, dy++) { \ - if (sincx == sizeof(pixelType)) { /* if advancing src and dest equally, use memcpy */ \ - SDL_memcpy(dp, sp, dst->w*sizeof(pixelType)); \ - sp += dst->w*sizeof(pixelType); \ - dp += dst->w*sizeof(pixelType); \ + if (sincx == sizeof(pixelType)) { /* if advancing src and dest equally, use SDL_memcpy */ \ + SDL_memcpy(dp, sp, dst->w * sizeof(pixelType)); \ + sp += dst->w * sizeof(pixelType); \ + dp += dst->w * sizeof(pixelType); \ } else { \ - for (de = dp + dst->w*sizeof(pixelType); dp != de; sp += sincx, dp += sizeof(pixelType)) { \ - *(pixelType*)dp = *(pixelType*)sp; \ + for (de = dp + dst->w * sizeof(pixelType); dp != de; sp += sincx, dp += sizeof(pixelType)) { \ + *(pixelType *)dp = *(pixelType *)sp; \ } \ } \ } -static void -transformSurfaceRGBA90(SDL_Surface * src, SDL_Surface * dst, int angle, int flipx, int flipy) +static void transformSurfaceRGBA90(SDL_Surface *src, SDL_Surface *dst, int angle, int flipx, int flipy) { TRANSFORM_SURFACE_90(tColorRGBA); } -static void -transformSurfaceY90(SDL_Surface * src, SDL_Surface * dst, int angle, int flipx, int flipy) +static void transformSurfaceY90(SDL_Surface *src, SDL_Surface *dst, int angle, int flipx, int flipy) { TRANSFORM_SURFACE_90(tColorY); } @@ -220,67 +260,86 @@ Assumes dst surface was allocated with the correct dimensions. \param src Source surface. \param dst Destination surface. -\param cx Horizontal center coordinate. -\param cy Vertical center coordinate. \param isin Integer version of sine of angle. \param icos Integer version of cosine of angle. \param flipx Flag indicating horizontal mirroring should be applied. \param flipy Flag indicating vertical mirroring should be applied. \param smooth Flag indicating anti-aliasing should be used. +\param dst_rect destination coordinates +\param center true center. */ -static void -_transformSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos, int flipx, int flipy, int smooth) +static void transformSurfaceRGBA(SDL_Surface *src, SDL_Surface *dst, int isin, int icos, + int flipx, int flipy, int smooth, + const SDL_Rect *rect_dest, + const SDL_FPoint *center) { - int x, y, t1, t2, dx, dy, xd, yd, sdx, sdy, ax, ay, ex, ey, sw, sh; + int sw, sh; + int cx, cy; tColorRGBA c00, c01, c10, c11, cswap; tColorRGBA *pc, *sp; int gap; + const int fp_half = (1 << 15); /* - * Variable setup - */ - xd = ((src->w - dst->w) << 15); - yd = ((src->h - dst->h) << 15); - ax = (cx << 16) - (icos * cx); - ay = (cy << 16) - (isin * cx); + * Variable setup + */ sw = src->w - 1; sh = src->h - 1; - pc = (tColorRGBA*) dst->pixels; + pc = (tColorRGBA *)dst->pixels; gap = dst->pitch - dst->w * 4; + cx = (int)(center->x * 65536.0); + cy = (int)(center->y * 65536.0); /* - * Switch between interpolating and non-interpolating code - */ + * Switch between interpolating and non-interpolating code + */ if (smooth) { + int y; for (y = 0; y < dst->h; y++) { - dy = cy - y; - sdx = (ax + (isin * dy)) + xd; - sdy = (ay - (icos * dy)) + yd; + int x; + double src_x = (rect_dest->x + 0 + 0.5 - center->x); + double src_y = (rect_dest->y + y + 0.5 - center->y); + int sdx = (int)((icos * src_x - isin * src_y) + cx - fp_half); + int sdy = (int)((isin * src_x + icos * src_y) + cy - fp_half); for (x = 0; x < dst->w; x++) { - dx = (sdx >> 16); - dy = (sdy >> 16); - if (flipx) dx = sw - dx; - if (flipy) dy = sh - dy; - if ((dx > -1) && (dy > -1) && (dx < (src->w-1)) && (dy < (src->h-1))) { - sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy) + dx; + int dx = (sdx >> 16); + int dy = (sdy >> 16); + if (flipx) { + dx = sw - dx; + } + if (flipy) { + dy = sh - dy; + } + if ((dx > -1) && (dy > -1) && (dx < (src->w - 1)) && (dy < (src->h - 1))) { + int ex, ey; + int t1, t2; + sp = (tColorRGBA *)((Uint8 *)src->pixels + src->pitch * dy) + dx; c00 = *sp; sp += 1; c01 = *sp; - sp += (src->pitch/4); + sp += (src->pitch / 4); c11 = *sp; sp -= 1; c10 = *sp; if (flipx) { - cswap = c00; c00=c01; c01=cswap; - cswap = c10; c10=c11; c11=cswap; + cswap = c00; + c00 = c01; + c01 = cswap; + cswap = c10; + c10 = c11; + c11 = cswap; } if (flipy) { - cswap = c00; c00=c10; c10=cswap; - cswap = c01; c01=c11; c11=cswap; + cswap = c00; + c00 = c10; + c10 = cswap; + cswap = c01; + c01 = c11; + c11 = cswap; } /* - * Interpolate colors - */ + * Interpolate colors + */ ex = (sdx & 0xffff); ey = (sdy & 0xffff); t1 = ((((c01.r - c00.r) * ex) >> 16) + c00.r) & 0xff; @@ -300,26 +359,33 @@ _transformSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int sdy += isin; pc++; } - pc = (tColorRGBA *) ((Uint8 *) pc + gap); + pc = (tColorRGBA *)((Uint8 *)pc + gap); } } else { + int y; for (y = 0; y < dst->h; y++) { - dy = cy - y; - sdx = (ax + (isin * dy)) + xd; - sdy = (ay - (icos * dy)) + yd; + int x; + double src_x = (rect_dest->x + 0 + 0.5 - center->x); + double src_y = (rect_dest->y + y + 0.5 - center->y); + int sdx = (int)((icos * src_x - isin * src_y) + cx - fp_half); + int sdy = (int)((isin * src_x + icos * src_y) + cy - fp_half); for (x = 0; x < dst->w; x++) { - dx = (sdx >> 16); - dy = (sdy >> 16); + int dx = (sdx >> 16); + int dy = (sdy >> 16); if ((unsigned)dx < (unsigned)src->w && (unsigned)dy < (unsigned)src->h) { - if(flipx) dx = sw - dx; - if(flipy) dy = sh - dy; + if (flipx) { + dx = sw - dx; + } + if (flipy) { + dy = sh - dy; + } *pc = *((tColorRGBA *)((Uint8 *)src->pixels + src->pitch * dy) + dx); } sdx += icos; sdy += isin; pc++; } - pc = (tColorRGBA *) ((Uint8 *) pc + gap); + pc = (tColorRGBA *)((Uint8 *)pc + gap); } } } @@ -335,46 +401,57 @@ Assumes dst surface was allocated with the correct dimensions. \param src Source surface. \param dst Destination surface. -\param cx Horizontal center coordinate. -\param cy Vertical center coordinate. \param isin Integer version of sine of angle. \param icos Integer version of cosine of angle. \param flipx Flag indicating horizontal mirroring should be applied. \param flipy Flag indicating vertical mirroring should be applied. +\param dst_rect destination coordinates +\param center true center. */ -static void -transformSurfaceY(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos, int flipx, int flipy) +static void transformSurfaceY(SDL_Surface *src, SDL_Surface *dst, int isin, int icos, int flipx, int flipy, + const SDL_Rect *rect_dest, + const SDL_FPoint *center) { - int x, y, dx, dy, xd, yd, sdx, sdy, ax, ay; + int sw, sh; + int cx, cy; tColorY *pc; int gap; + const int fp_half = (1 << 15); + int y; /* - * Variable setup - */ - xd = ((src->w - dst->w) << 15); - yd = ((src->h - dst->h) << 15); - ax = (cx << 16) - (icos * cx); - ay = (cy << 16) - (isin * cx); - pc = (tColorY*) dst->pixels; + * Variable setup + */ + sw = src->w - 1; + sh = src->h - 1; + pc = (tColorY *)dst->pixels; gap = dst->pitch - dst->w; + cx = (int)(center->x * 65536.0); + cy = (int)(center->y * 65536.0); + /* - * Clear surface to colorkey - */ - SDL_memset(pc, (int)(_colorkey(src) & 0xff), dst->pitch * dst->h); + * Clear surface to colorkey + */ + SDL_memset(pc, (int)(get_colorkey(src) & 0xff), (size_t)dst->pitch * dst->h); /* - * Iterate through destination surface - */ + * Iterate through destination surface + */ for (y = 0; y < dst->h; y++) { - dy = cy - y; - sdx = (ax + (isin * dy)) + xd; - sdy = (ay - (icos * dy)) + yd; + int x; + double src_x = (rect_dest->x + 0 + 0.5 - center->x); + double src_y = (rect_dest->y + y + 0.5 - center->y); + int sdx = (int)((icos * src_x - isin * src_y) + cx - fp_half); + int sdy = (int)((isin * src_x + icos * src_y) + cy - fp_half); for (x = 0; x < dst->w; x++) { - dx = (sdx >> 16); - dy = (sdy >> 16); + int dx = (sdx >> 16); + int dy = (sdy >> 16); if ((unsigned)dx < (unsigned)src->w && (unsigned)dy < (unsigned)src->h) { - if (flipx) dx = (src->w-1)-dx; - if (flipy) dy = (src->h-1)-dy; + if (flipx) { + dx = sw - dx; + } + if (flipy) { + dy = sh - dy; + } *pc = *((tColorY *)src->pixels + src->pitch * dy + dx); } sdx += icos; @@ -385,12 +462,11 @@ transformSurfaceY(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin } } - /* ! \brief Rotates and zooms a surface with different horizontal and vertival scaling factors and optional anti-aliasing. Rotates a 32-bit or 8-bit 'src' surface to newly created 'dst' surface. -'angle' is the rotation in degrees, 'centerx' and 'centery' the rotation center. If 'smooth' is set +'angle' is the rotation in degrees, 'center' the rotation center. If 'smooth' is set then the destination 32-bit surface is anti-aliased. 8-bit surfaces must have a colorkey. 32-bit surfaces must have a 8888 layout with red, green, blue and alpha masks (any ordering goes). The blend mode of the 'src' surface has some effects on generation of the 'dst' surface: The NONE @@ -400,21 +476,20 @@ When using the NONE and MOD modes, color and alpha modulation must be applied be \param src The surface to rotozoom. \param angle The angle to rotate in degrees. -\param centerx The horizontal coordinate of the center of rotation \param zoomy The vertical coordinate of the center of rotation \param smooth Antialiasing flag; set to SMOOTHING_ON to enable. \param flipx Set to 1 to flip the image horizontally \param flipy Set to 1 to flip the image vertically -\param dstwidth The destination surface width -\param dstheight The destination surface height +\param rect_dest The destination rect bounding box \param cangle The angle cosine \param sangle The angle sine +\param center The true coordinate of the center of rotation \return The new rotated surface. */ -SDL_Surface * -SDLgfx_rotateSurface(SDL_Surface * src, double angle, int centerx, int centery, int smooth, int flipx, int flipy, int dstwidth, int dstheight, double cangle, double sangle) +SDL_Surface *SDLgfx_rotateSurface(SDL_Surface *src, double angle, int smooth, int flipx, int flipy, + const SDL_Rect *rect_dest, double cangle, double sangle, const SDL_FPoint *center) { SDL_Surface *rz_dst; int is8bit, angle90; @@ -425,48 +500,52 @@ SDLgfx_rotateSurface(SDL_Surface * src, double angle, int centerx, int centery, double sangleinv, cangleinv; /* Sanity check */ - if (src == NULL) + if (!src) { return NULL; + } if (SDL_HasColorKey(src)) { if (SDL_GetColorKey(src, &colorkey) == 0) { colorKeyAvailable = SDL_TRUE; } } - /* This function requires a 32-bit surface or 8-bit surface with a colorkey */ is8bit = src->format->BitsPerPixel == 8 && colorKeyAvailable; - if (!(is8bit || (src->format->BitsPerPixel == 32 && src->format->Amask))) + if (!(is8bit || (src->format->BitsPerPixel == 32 && src->format->Amask))) { return NULL; + } - /* Calculate target factors from sin/cos and zoom */ - sangleinv = sangle*65536.0; - cangleinv = cangle*65536.0; + /* Calculate target factors from sine/cosine and zoom */ + sangleinv = sangle * 65536.0; + cangleinv = cangle * 65536.0; /* Alloc space to completely contain the rotated surface */ rz_dst = NULL; if (is8bit) { /* Target surface is 8 bit */ - rz_dst = SDL_CreateRGBSurface(0, dstwidth, dstheight + GUARD_ROWS, 8, 0, 0, 0, 0); - if (rz_dst != NULL) { - for (i = 0; i < src->format->palette->ncolors; i++) { - rz_dst->format->palette->colors[i] = src->format->palette->colors[i]; + rz_dst = SDL_CreateRGBSurfaceWithFormat(0, rect_dest->w, rect_dest->h + GUARD_ROWS, 8, src->format->format); + if (rz_dst) { + if (src->format->palette) { + for (i = 0; i < src->format->palette->ncolors; i++) { + rz_dst->format->palette->colors[i] = src->format->palette->colors[i]; + } + rz_dst->format->palette->ncolors = src->format->palette->ncolors; } - rz_dst->format->palette->ncolors = src->format->palette->ncolors; } } else { /* Target surface is 32 bit with source RGBA ordering */ - rz_dst = SDL_CreateRGBSurface(0, dstwidth, dstheight + GUARD_ROWS, 32, + rz_dst = SDL_CreateRGBSurface(0, rect_dest->w, rect_dest->h + GUARD_ROWS, 32, src->format->Rmask, src->format->Gmask, src->format->Bmask, src->format->Amask); } /* Check target */ - if (rz_dst == NULL) + if (!rz_dst) { return NULL; + } /* Adjust for guard rows */ - rz_dst->h = dstheight; + rz_dst->h = rect_dest->h; SDL_GetSurfaceBlendMode(src, &blendmode); @@ -497,32 +576,35 @@ SDLgfx_rotateSurface(SDL_Surface * src, double angle, int centerx, int centery, } /* check if the rotation is a multiple of 90 degrees so we can take a fast path and also somewhat reduce - * the off-by-one problem in _transformSurfaceRGBA that expresses itself when the rotation is near + * the off-by-one problem in transformSurfaceRGBA that expresses itself when the rotation is near * multiples of 90 degrees. */ - angle90 = (int)(angle/90); - if (angle90 == angle/90) { + angle90 = (int)(angle / 90); + if (angle90 == angle / 90) { angle90 %= 4; - if (angle90 < 0) angle90 += 4; /* 0:0 deg, 1:90 deg, 2:180 deg, 3:270 deg */ + if (angle90 < 0) { + angle90 += 4; /* 0:0 deg, 1:90 deg, 2:180 deg, 3:270 deg */ + } + } else { angle90 = -1; } if (is8bit) { /* Call the 8-bit transformation routine to do the rotation */ - if(angle90 >= 0) { + if (angle90 >= 0) { transformSurfaceY90(src, rz_dst, angle90, flipx, flipy); } else { - transformSurfaceY(src, rz_dst, centerx, centery, (int)sangleinv, (int)cangleinv, - flipx, flipy); + transformSurfaceY(src, rz_dst, (int)sangleinv, (int)cangleinv, + flipx, flipy, rect_dest, center); } } else { /* Call the 32-bit transformation routine to do the rotation */ if (angle90 >= 0) { transformSurfaceRGBA90(src, rz_dst, angle90, flipx, flipy); } else { - _transformSurfaceRGBA(src, rz_dst, centerx, centery, (int)sangleinv, (int)cangleinv, - flipx, flipy, smooth); + transformSurfaceRGBA(src, rz_dst, (int)sangleinv, (int)cangleinv, + flipx, flipy, smooth, rect_dest, center); } } @@ -535,4 +617,4 @@ SDLgfx_rotateSurface(SDL_Surface * src, double angle, int centerx, int centery, return rz_dst; } -#endif /* SDL_VIDEO_RENDER_SW && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_SW */ diff --git a/SDL2-2.0.12/src/render/software/SDL_rotate.h b/SDL2-2.30.5/src/render/software/SDL_rotate.h similarity index 70% rename from SDL2-2.0.12/src/render/software/SDL_rotate.h rename to SDL2-2.30.5/src/render/software/SDL_rotate.h index c1864d2..9e08e53 100644 --- a/SDL2-2.0.12/src/render/software/SDL_rotate.h +++ b/SDL2-2.30.5/src/render/software/SDL_rotate.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -22,11 +22,9 @@ #ifndef SDL_rotate_h_ #define SDL_rotate_h_ -#ifndef MIN -#define MIN(a,b) (((a) < (b)) ? (a) : (b)) -#endif - -extern SDL_Surface *SDLgfx_rotateSurface(SDL_Surface * src, double angle, int centerx, int centery, int smooth, int flipx, int flipy, int dstwidth, int dstheight, double cangle, double sangle); -extern void SDLgfx_rotozoomSurfaceSizeTrig(int width, int height, double angle, int *dstwidth, int *dstheight, double *cangle, double *sangle); +extern SDL_Surface *SDLgfx_rotateSurface(SDL_Surface *src, double angle, int smooth, int flipx, int flipy, + const SDL_Rect *rect_dest, double cangle, double sangle, const SDL_FPoint *center); +extern void SDLgfx_rotozoomSurfaceSizeTrig(int width, int height, double angle, const SDL_FPoint *center, + SDL_Rect *rect_dest, double *cangle, double *sangle); #endif /* SDL_rotate_h_ */ diff --git a/SDL2-2.30.5/src/render/software/SDL_triangle.c b/SDL2-2.30.5/src/render/software/SDL_triangle.c new file mode 100644 index 0000000..f6af3dc --- /dev/null +++ b/SDL2-2.30.5/src/render/software/SDL_triangle.c @@ -0,0 +1,940 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#if SDL_VIDEO_RENDER_SW + +#include + +#include "SDL_surface.h" +#include "SDL_triangle.h" + +#include "../../video/SDL_blit.h" + +/* fixed points bits precision + * Set to 1, so that it can start rendering wth middle of a pixel precision. + * It doesn't need to be increased. + * But, if increased too much, it overflows (srcx, srcy) coordinates used for filling with texture. + * (which could be turned to int64). + */ +#define FP_BITS 1 + +#define COLOR_EQ(c1, c2) ((c1).r == (c2).r && (c1).g == (c2).g && (c1).b == (c2).b && (c1).a == (c2).a) + +static void SDL_BlitTriangle_Slow(SDL_BlitInfo *info, + SDL_Point s2_x_area, SDL_Rect dstrect, int area, int bias_w0, int bias_w1, int bias_w2, + int d2d1_y, int d1d2_x, int d0d2_y, int d2d0_x, int d1d0_y, int d0d1_x, + int s2s0_x, int s2s1_x, int s2s0_y, int s2s1_y, int w0_row, int w1_row, int w2_row, + SDL_Color c0, SDL_Color c1, SDL_Color c2, int is_uniform); + +#if 0 +int SDL_BlitTriangle(SDL_Surface *src, const SDL_Point srcpoints[3], SDL_Surface *dst, const SDL_Point dstpoints[3]) +{ + int i; + SDL_Point points[6]; + + if (src == NULL || dst == NULL) { + return -1; + } + + for (i = 0; i < 3; i++) { + if (srcpoints[i].x < 0 || srcpoints[i].y < 0 || srcpoints[i].x >= src->w || srcpoints[i].y >= src->h) { + return SDL_SetError("Values of 'srcpoints' out of bounds"); + } + } + + points[0] = srcpoints[0]; + points[1] = dstpoints[0]; + points[2] = srcpoints[1]; + points[3] = dstpoints[1]; + points[4] = srcpoints[2]; + points[5] = dstpoints[2]; + for (i = 0; i < 3; i++) { + trianglepoint_2_fixedpoint(&points[2 * i + 1]); + } + return SDL_SW_BlitTriangle(src, dst, points); +} + +int SDL_FillTriangle(SDL_Surface *dst, const SDL_Point points[3], Uint32 color) +{ + int i; + SDL_Point points_tmp[3]; + if (dst == NULL) { + return -1; + } + for (i = 0; i < 3; i++) { + points_tmp[i] = points[i]; + trianglepoint_2_fixedpoint(&points_tmp[i]); + } + return SDL_SW_FillTriangle(dst, points_tmp, SDL_BLENDMODE_NONE, color); +} +#endif + +/* cross product AB x AC */ +static Sint64 cross_product(const SDL_Point *a, const SDL_Point *b, int c_x, int c_y) +{ + return ((Sint64)(b->x - a->x)) * ((Sint64)(c_y - a->y)) - ((Sint64)(b->y - a->y)) * ((Sint64)(c_x - a->x)); +} + +/* check for top left rules */ +static int is_top_left(const SDL_Point *a, const SDL_Point *b, int is_clockwise) +{ + if (is_clockwise) { + if (a->y == b->y && a->x < b->x) { + return 1; + } + if (b->y < a->y) { + return 1; + } + } else { + if (a->y == b->y && b->x < a->x) { + return 1; + } + if (a->y < b->y) { + return 1; + } + } + return 0; +} + +/* x = (y << FP_BITS) */ +/* prevent runtime error: left shift of negative value */ +#define PRECOMP(x, y) \ + val = y; \ + if (val >= 0) { \ + x = val << FP_BITS; \ + } else { \ + val *= -1; \ + x = val << FP_BITS; \ + x *= -1; \ + } + +void trianglepoint_2_fixedpoint(SDL_Point *a) +{ + int val; + PRECOMP(a->x, a->x); + PRECOMP(a->y, a->y); +} + +/* bounding rect of three points (in fixed point) */ +static void bounding_rect_fixedpoint(const SDL_Point *a, const SDL_Point *b, const SDL_Point *c, SDL_Rect *r) +{ + int min_x = SDL_min(a->x, SDL_min(b->x, c->x)); + int max_x = SDL_max(a->x, SDL_max(b->x, c->x)); + int min_y = SDL_min(a->y, SDL_min(b->y, c->y)); + int max_y = SDL_max(a->y, SDL_max(b->y, c->y)); + /* points are in fixed point, shift back */ + r->x = min_x >> FP_BITS; + r->y = min_y >> FP_BITS; + r->w = (max_x - min_x) >> FP_BITS; + r->h = (max_y - min_y) >> FP_BITS; +} + +/* bounding rect of three points */ +static void bounding_rect(const SDL_Point *a, const SDL_Point *b, const SDL_Point *c, SDL_Rect *r) +{ + int min_x = SDL_min(a->x, SDL_min(b->x, c->x)); + int max_x = SDL_max(a->x, SDL_max(b->x, c->x)); + int min_y = SDL_min(a->y, SDL_min(b->y, c->y)); + int max_y = SDL_max(a->y, SDL_max(b->y, c->y)); + r->x = min_x; + r->y = min_y; + r->w = (max_x - min_x); + r->h = (max_y - min_y); +} + +/* Triangle rendering, using Barycentric coordinates (w0, w1, w2) + * + * The cross product isn't computed from scratch at each iteration, + * but optimized using constant step increments + * + */ + +#define TRIANGLE_BEGIN_LOOP \ + { \ + int x, y; \ + for (y = 0; y < dstrect.h; y++) { \ + /* y start */ \ + Sint64 w0 = w0_row; \ + Sint64 w1 = w1_row; \ + Sint64 w2 = w2_row; \ + for (x = 0; x < dstrect.w; x++) { \ + /* In triangle */ \ + if (w0 + bias_w0 >= 0 && w1 + bias_w1 >= 0 && w2 + bias_w2 >= 0) { \ + Uint8 *dptr = (Uint8 *)dst_ptr + x * dstbpp; + +/* Use 64 bits precision to prevent overflow when interpolating color / texture with wide triangles */ +#define TRIANGLE_GET_TEXTCOORD \ + int srcx = (int)(((Sint64)w0 * s2s0_x + (Sint64)w1 * s2s1_x + s2_x_area.x) / area); \ + int srcy = (int)(((Sint64)w0 * s2s0_y + (Sint64)w1 * s2s1_y + s2_x_area.y) / area); + +#define TRIANGLE_GET_MAPPED_COLOR \ + int r = (int)(((Sint64)w0 * c0.r + (Sint64)w1 * c1.r + (Sint64)w2 * c2.r) / area); \ + int g = (int)(((Sint64)w0 * c0.g + (Sint64)w1 * c1.g + (Sint64)w2 * c2.g) / area); \ + int b = (int)(((Sint64)w0 * c0.b + (Sint64)w1 * c1.b + (Sint64)w2 * c2.b) / area); \ + int a = (int)(((Sint64)w0 * c0.a + (Sint64)w1 * c1.a + (Sint64)w2 * c2.a) / area); \ + int color = SDL_MapRGBA(format, r, g, b, a); + +#define TRIANGLE_GET_COLOR \ + int r = (int)(((Sint64)w0 * c0.r + (Sint64)w1 * c1.r + (Sint64)w2 * c2.r) / area); \ + int g = (int)(((Sint64)w0 * c0.g + (Sint64)w1 * c1.g + (Sint64)w2 * c2.g) / area); \ + int b = (int)(((Sint64)w0 * c0.b + (Sint64)w1 * c1.b + (Sint64)w2 * c2.b) / area); \ + int a = (int)(((Sint64)w0 * c0.a + (Sint64)w1 * c1.a + (Sint64)w2 * c2.a) / area); + +#define TRIANGLE_END_LOOP \ + } \ + /* x += 1 */ \ + w0 += d2d1_y; \ + w1 += d0d2_y; \ + w2 += d1d0_y; \ + } \ + /* y += 1 */ \ + w0_row += d1d2_x; \ + w1_row += d2d0_x; \ + w2_row += d0d1_x; \ + dst_ptr += dst_pitch; \ + } \ + } + +int SDL_SW_FillTriangle(SDL_Surface *dst, SDL_Point *d0, SDL_Point *d1, SDL_Point *d2, SDL_BlendMode blend, SDL_Color c0, SDL_Color c1, SDL_Color c2) +{ + int ret = 0; + int dst_locked = 0; + + SDL_Rect dstrect; + + int dstbpp; + Uint8 *dst_ptr; + int dst_pitch; + + Sint64 area; + int is_clockwise; + + int d2d1_y, d1d2_x, d0d2_y, d2d0_x, d1d0_y, d0d1_x; + Sint64 w0_row, w1_row, w2_row; + int bias_w0, bias_w1, bias_w2; + + int is_uniform; + + SDL_Surface *tmp = NULL; + + if (!dst) { + return -1; + } + + area = cross_product(d0, d1, d2->x, d2->y); + + is_uniform = COLOR_EQ(c0, c1) && COLOR_EQ(c1, c2); + + /* Flat triangle */ + if (area == 0) { + return 0; + } + + /* Lock the destination, if needed */ + if (SDL_MUSTLOCK(dst)) { + if (SDL_LockSurface(dst) < 0) { + ret = -1; + goto end; + } else { + dst_locked = 1; + } + } + + bounding_rect_fixedpoint(d0, d1, d2, &dstrect); + + { + /* Clip triangle rect with surface rect */ + SDL_Rect rect; + rect.x = 0; + rect.y = 0; + rect.w = dst->w; + rect.h = dst->h; + SDL_IntersectRect(&dstrect, &rect, &dstrect); + } + + { + /* Clip triangle with surface clip rect */ + SDL_Rect rect; + SDL_GetClipRect(dst, &rect); + SDL_IntersectRect(&dstrect, &rect, &dstrect); + } + + if (blend != SDL_BLENDMODE_NONE) { + int format = dst->format->format; + + /* need an alpha format */ + if (!dst->format->Amask) { + format = SDL_PIXELFORMAT_ARGB8888; + } + + /* Use an intermediate surface */ + tmp = SDL_CreateRGBSurfaceWithFormat(0, dstrect.w, dstrect.h, 0, format); + if (!tmp) { + ret = -1; + goto end; + } + + if (blend == SDL_BLENDMODE_MOD) { + Uint32 c = SDL_MapRGBA(tmp->format, 255, 255, 255, 255); + SDL_FillRect(tmp, NULL, c); + } + + SDL_SetSurfaceBlendMode(tmp, blend); + + dstbpp = tmp->format->BytesPerPixel; + dst_ptr = tmp->pixels; + dst_pitch = tmp->pitch; + + } else { + /* Write directly to destination surface */ + dstbpp = dst->format->BytesPerPixel; + dst_ptr = (Uint8 *)dst->pixels + dstrect.x * dstbpp + dstrect.y * dst->pitch; + dst_pitch = dst->pitch; + } + + is_clockwise = area > 0; + if (area < 0) { + area = -area; + } + + { + int val; + PRECOMP(d2d1_y, d1->y - d2->y) + PRECOMP(d0d2_y, d2->y - d0->y) + PRECOMP(d1d0_y, d0->y - d1->y) + PRECOMP(d1d2_x, d2->x - d1->x) + PRECOMP(d2d0_x, d0->x - d2->x) + PRECOMP(d0d1_x, d1->x - d0->x) + } + + /* Starting point for rendering, at the middle of a pixel */ + { + SDL_Point p; + p.x = dstrect.x; + p.y = dstrect.y; + trianglepoint_2_fixedpoint(&p); + p.x += (1 << FP_BITS) / 2; + p.y += (1 << FP_BITS) / 2; + w0_row = cross_product(d1, d2, p.x, p.y); + w1_row = cross_product(d2, d0, p.x, p.y); + w2_row = cross_product(d0, d1, p.x, p.y); + } + + /* Handle anti-clockwise triangles */ + if (!is_clockwise) { + d2d1_y *= -1; + d0d2_y *= -1; + d1d0_y *= -1; + d1d2_x *= -1; + d2d0_x *= -1; + d0d1_x *= -1; + w0_row *= -1; + w1_row *= -1; + w2_row *= -1; + } + + /* Add a bias to respect top-left rasterization rule */ + bias_w0 = (is_top_left(d1, d2, is_clockwise) ? 0 : -1); + bias_w1 = (is_top_left(d2, d0, is_clockwise) ? 0 : -1); + bias_w2 = (is_top_left(d0, d1, is_clockwise) ? 0 : -1); + + if (is_uniform) { + Uint32 color; + if (tmp) { + color = SDL_MapRGBA(tmp->format, c0.r, c0.g, c0.b, c0.a); + } else { + color = SDL_MapRGBA(dst->format, c0.r, c0.g, c0.b, c0.a); + } + + if (dstbpp == 4) { + TRIANGLE_BEGIN_LOOP + { + *(Uint32 *)dptr = color; + } + TRIANGLE_END_LOOP + } else if (dstbpp == 3) { + TRIANGLE_BEGIN_LOOP + { + Uint8 *s = (Uint8 *)&color; + dptr[0] = s[0]; + dptr[1] = s[1]; + dptr[2] = s[2]; + } + TRIANGLE_END_LOOP + } else if (dstbpp == 2) { + TRIANGLE_BEGIN_LOOP + { + *(Uint16 *)dptr = color; + } + TRIANGLE_END_LOOP + } else if (dstbpp == 1) { + TRIANGLE_BEGIN_LOOP + { + *dptr = color; + } + TRIANGLE_END_LOOP + } + } else { + SDL_PixelFormat *format = dst->format; + if (tmp) { + format = tmp->format; + } + if (dstbpp == 4) { + TRIANGLE_BEGIN_LOOP + { + TRIANGLE_GET_MAPPED_COLOR + *(Uint32 *)dptr = color; + } + TRIANGLE_END_LOOP + } else if (dstbpp == 3) { + TRIANGLE_BEGIN_LOOP + { + TRIANGLE_GET_MAPPED_COLOR + Uint8 *s = (Uint8 *)&color; + dptr[0] = s[0]; + dptr[1] = s[1]; + dptr[2] = s[2]; + } + TRIANGLE_END_LOOP + } else if (dstbpp == 2) { + TRIANGLE_BEGIN_LOOP + { + TRIANGLE_GET_MAPPED_COLOR + *(Uint16 *)dptr = color; + } + TRIANGLE_END_LOOP + } else if (dstbpp == 1) { + TRIANGLE_BEGIN_LOOP + { + TRIANGLE_GET_MAPPED_COLOR + *dptr = color; + } + TRIANGLE_END_LOOP + } + } + + if (tmp) { + SDL_BlitSurface(tmp, NULL, dst, &dstrect); + SDL_FreeSurface(tmp); + } + +end: + if (dst_locked) { + SDL_UnlockSurface(dst); + } + + return ret; +} + +int SDL_SW_BlitTriangle( + SDL_Surface *src, + SDL_Point *s0, SDL_Point *s1, SDL_Point *s2, + SDL_Surface *dst, + SDL_Point *d0, SDL_Point *d1, SDL_Point *d2, + SDL_Color c0, SDL_Color c1, SDL_Color c2) +{ + int ret = 0; + int src_locked = 0; + int dst_locked = 0; + + SDL_BlendMode blend; + + SDL_Rect dstrect; + + SDL_Point s2_x_area; + + int dstbpp; + Uint8 *dst_ptr; + int dst_pitch; + + int *src_ptr; + int src_pitch; + + Sint64 area, tmp64; + int is_clockwise; + + int d2d1_y, d1d2_x, d0d2_y, d2d0_x, d1d0_y, d0d1_x; + int s2s0_x, s2s1_x, s2s0_y, s2s1_y; + + Sint64 w0_row, w1_row, w2_row; + int bias_w0, bias_w1, bias_w2; + + int is_uniform; + + int has_modulation; + + if (!src) { + return SDL_InvalidParamError("src"); + } + if (!src) { + return SDL_InvalidParamError("dst"); + } + + area = cross_product(d0, d1, d2->x, d2->y); + + /* Flat triangle */ + if (area == 0) { + return 0; + } + + /* Lock the destination, if needed */ + if (SDL_MUSTLOCK(dst)) { + if (SDL_LockSurface(dst) < 0) { + ret = -1; + goto end; + } else { + dst_locked = 1; + } + } + + /* Lock the source, if needed */ + if (SDL_MUSTLOCK(src)) { + if (SDL_LockSurface(src) < 0) { + ret = -1; + goto end; + } else { + src_locked = 1; + } + } + + is_uniform = COLOR_EQ(c0, c1) && COLOR_EQ(c1, c2); + + bounding_rect_fixedpoint(d0, d1, d2, &dstrect); + + SDL_GetSurfaceBlendMode(src, &blend); + + /* TRIANGLE_GET_TEXTCOORD interpolates up to the max values included, so reduce by 1 */ + { + SDL_Rect srcrect; + int maxx, maxy; + bounding_rect(s0, s1, s2, &srcrect); + maxx = srcrect.x + srcrect.w; + maxy = srcrect.y + srcrect.h; + if (srcrect.w > 0) { + if (s0->x == maxx) { + s0->x--; + } + if (s1->x == maxx) { + s1->x--; + } + if (s2->x == maxx) { + s2->x--; + } + } + if (srcrect.h > 0) { + if (s0->y == maxy) { + s0->y--; + } + if (s1->y == maxy) { + s1->y--; + } + if (s2->y == maxy) { + s2->y--; + } + } + } + + if (is_uniform) { + // SDL_GetSurfaceColorMod(src, &r, &g, &b); + has_modulation = c0.r != 255 || c0.g != 255 || c0.b != 255 || c0.a != 255; + } else { + has_modulation = SDL_TRUE; + } + + { + /* Clip triangle rect with surface rect */ + SDL_Rect rect; + rect.x = 0; + rect.y = 0; + rect.w = dst->w; + rect.h = dst->h; + + SDL_IntersectRect(&dstrect, &rect, &dstrect); + } + + { + /* Clip triangle with surface clip rect */ + SDL_Rect rect; + SDL_GetClipRect(dst, &rect); + SDL_IntersectRect(&dstrect, &rect, &dstrect); + } + + /* Set destination pointer */ + dstbpp = dst->format->BytesPerPixel; + dst_ptr = (Uint8 *)dst->pixels + dstrect.x * dstbpp + dstrect.y * dst->pitch; + dst_pitch = dst->pitch; + + /* Set source pointer */ + src_ptr = src->pixels; + src_pitch = src->pitch; + + is_clockwise = area > 0; + if (area < 0) { + area = -area; + } + + { + int val; + PRECOMP(d2d1_y, d1->y - d2->y) + PRECOMP(d0d2_y, d2->y - d0->y) + PRECOMP(d1d0_y, d0->y - d1->y) + PRECOMP(d1d2_x, d2->x - d1->x) + PRECOMP(d2d0_x, d0->x - d2->x) + PRECOMP(d0d1_x, d1->x - d0->x) + } + + s2s0_x = s0->x - s2->x; + s2s1_x = s1->x - s2->x; + s2s0_y = s0->y - s2->y; + s2s1_y = s1->y - s2->y; + + /* Starting point for rendering, at the middle of a pixel */ + { + SDL_Point p; + p.x = dstrect.x; + p.y = dstrect.y; + trianglepoint_2_fixedpoint(&p); + p.x += (1 << FP_BITS) / 2; + p.y += (1 << FP_BITS) / 2; + w0_row = cross_product(d1, d2, p.x, p.y); + w1_row = cross_product(d2, d0, p.x, p.y); + w2_row = cross_product(d0, d1, p.x, p.y); + } + + /* Handle anti-clockwise triangles */ + if (!is_clockwise) { + d2d1_y *= -1; + d0d2_y *= -1; + d1d0_y *= -1; + d1d2_x *= -1; + d2d0_x *= -1; + d0d1_x *= -1; + w0_row *= -1; + w1_row *= -1; + w2_row *= -1; + } + + /* Add a bias to respect top-left rasterization rule */ + bias_w0 = (is_top_left(d1, d2, is_clockwise) ? 0 : -1); + bias_w1 = (is_top_left(d2, d0, is_clockwise) ? 0 : -1); + bias_w2 = (is_top_left(d0, d1, is_clockwise) ? 0 : -1); + + /* precompute constant 's2->x * area' used in TRIANGLE_GET_TEXTCOORD */ + tmp64 = s2->x * area; + if (tmp64 >= INT_MIN && tmp64 <= INT_MAX) { + s2_x_area.x = (int)tmp64; + } else { + ret = SDL_SetError("triangle area overflow"); + goto end; + } + tmp64 = s2->y * area; + if (tmp64 >= INT_MIN && tmp64 <= INT_MAX) { + s2_x_area.y = (int)tmp64; + } else { + ret = SDL_SetError("triangle area overflow"); + goto end; + } + + if (blend != SDL_BLENDMODE_NONE || src->format->format != dst->format->format || has_modulation || !is_uniform) { + /* Use SDL_BlitTriangle_Slow */ + + SDL_BlitInfo *info = &src->map->info; + SDL_BlitInfo tmp_info; + + SDL_zero(tmp_info); + + tmp_info.src_fmt = src->format; + tmp_info.dst_fmt = dst->format; + tmp_info.flags = info->flags; + /* + tmp_info.r = info->r; + tmp_info.g = info->g; + tmp_info.b = info->b; + tmp_info.a = info->a; + */ + tmp_info.r = c0.r; + tmp_info.g = c0.g; + tmp_info.b = c0.b; + tmp_info.a = c0.a; + + tmp_info.flags &= ~(SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA); + + if (c0.r != 255 || c1.r != 255 || c2.r != 255 || + c0.g != 255 || c1.g != 255 || c2.g != 255 || + c0.b != 255 || c1.b != 255 || c2.b != 255) { + tmp_info.flags |= SDL_COPY_MODULATE_COLOR; + } + + if (c0.a != 255 || c1.a != 255 || c2.a != 255) { + tmp_info.flags |= SDL_COPY_MODULATE_ALPHA; + } + + tmp_info.colorkey = info->colorkey; + + /* src */ + tmp_info.src = (Uint8 *)src_ptr; + tmp_info.src_pitch = src_pitch; + + /* dst */ + tmp_info.dst = dst_ptr; + tmp_info.dst_pitch = dst_pitch; + +#define CHECK_INT_RANGE(X) \ + if ((X) < INT_MIN || (X) > INT_MAX) { \ + ret = SDL_SetError("integer overflow (%s = %" SDL_PRIs64 ")", #X, X); \ + goto end; \ + } + CHECK_INT_RANGE(area); + CHECK_INT_RANGE(w0_row); + CHECK_INT_RANGE(w1_row); + CHECK_INT_RANGE(w2_row); + SDL_BlitTriangle_Slow(&tmp_info, s2_x_area, dstrect, (int)area, bias_w0, bias_w1, bias_w2, + d2d1_y, d1d2_x, d0d2_y, d2d0_x, d1d0_y, d0d1_x, + s2s0_x, s2s1_x, s2s0_y, s2s1_y, (int)w0_row, (int)w1_row, (int)w2_row, + c0, c1, c2, is_uniform); + + goto end; + } + + if (dstbpp == 4) { + TRIANGLE_BEGIN_LOOP + { + TRIANGLE_GET_TEXTCOORD + Uint32 *sptr = (Uint32 *)((Uint8 *)src_ptr + srcy * src_pitch); + *(Uint32 *)dptr = sptr[srcx]; + } + TRIANGLE_END_LOOP + } else if (dstbpp == 3) { + TRIANGLE_BEGIN_LOOP + { + TRIANGLE_GET_TEXTCOORD + Uint8 *sptr = (Uint8 *)src_ptr + srcy * src_pitch; + dptr[0] = sptr[3 * srcx]; + dptr[1] = sptr[3 * srcx + 1]; + dptr[2] = sptr[3 * srcx + 2]; + } + TRIANGLE_END_LOOP + } else if (dstbpp == 2) { + TRIANGLE_BEGIN_LOOP + { + TRIANGLE_GET_TEXTCOORD + Uint16 *sptr = (Uint16 *)((Uint8 *)src_ptr + srcy * src_pitch); + *(Uint16 *)dptr = sptr[srcx]; + } + TRIANGLE_END_LOOP + } else if (dstbpp == 1) { + TRIANGLE_BEGIN_LOOP + { + TRIANGLE_GET_TEXTCOORD + Uint8 *sptr = (Uint8 *)src_ptr + srcy * src_pitch; + *dptr = sptr[srcx]; + } + TRIANGLE_END_LOOP + } + +end: + if (dst_locked) { + SDL_UnlockSurface(dst); + } + if (src_locked) { + SDL_UnlockSurface(src); + } + + return ret; +} + +#define FORMAT_ALPHA 0 +#define FORMAT_NO_ALPHA -1 +#define FORMAT_2101010 1 +#define FORMAT_HAS_ALPHA(format) format == 0 +#define FORMAT_HAS_NO_ALPHA(format) format < 0 +static int SDL_INLINE detect_format(SDL_PixelFormat *pf) +{ + if (pf->format == SDL_PIXELFORMAT_ARGB2101010) { + return FORMAT_2101010; + } else if (pf->Amask) { + return FORMAT_ALPHA; + } else { + return FORMAT_NO_ALPHA; + } +} + +static void SDL_BlitTriangle_Slow(SDL_BlitInfo *info, + SDL_Point s2_x_area, SDL_Rect dstrect, int area, int bias_w0, int bias_w1, int bias_w2, + int d2d1_y, int d1d2_x, int d0d2_y, int d2d0_x, int d1d0_y, int d0d1_x, + int s2s0_x, int s2s1_x, int s2s0_y, int s2s1_y, int w0_row, int w1_row, int w2_row, + SDL_Color c0, SDL_Color c1, SDL_Color c2, int is_uniform) +{ + const int flags = info->flags; + Uint32 modulateR = info->r; + Uint32 modulateG = info->g; + Uint32 modulateB = info->b; + Uint32 modulateA = info->a; + Uint32 srcpixel; + Uint32 srcR, srcG, srcB, srcA; + Uint32 dstpixel; + Uint32 dstR, dstG, dstB, dstA; + SDL_PixelFormat *src_fmt = info->src_fmt; + SDL_PixelFormat *dst_fmt = info->dst_fmt; + int srcbpp = src_fmt->BytesPerPixel; + int dstbpp = dst_fmt->BytesPerPixel; + int srcfmt_val; + int dstfmt_val; + Uint32 rgbmask = ~src_fmt->Amask; + Uint32 ckey = info->colorkey & rgbmask; + + Uint8 *dst_ptr = info->dst; + int dst_pitch = info->dst_pitch; + + srcfmt_val = detect_format(src_fmt); + dstfmt_val = detect_format(dst_fmt); + + TRIANGLE_BEGIN_LOOP + { + Uint8 *src; + Uint8 *dst = dptr; + TRIANGLE_GET_TEXTCOORD + src = (info->src + (srcy * info->src_pitch) + (srcx * srcbpp)); + if (FORMAT_HAS_ALPHA(srcfmt_val)) { + DISEMBLE_RGBA(src, srcbpp, src_fmt, srcpixel, srcR, srcG, srcB, srcA); + } else if (FORMAT_HAS_NO_ALPHA(srcfmt_val)) { + DISEMBLE_RGB(src, srcbpp, src_fmt, srcpixel, srcR, srcG, srcB); + srcA = 0xFF; + } else { + /* SDL_PIXELFORMAT_ARGB2101010 */ + srcpixel = *((Uint32 *)(src)); + RGBA_FROM_ARGB2101010(srcpixel, srcR, srcG, srcB, srcA); + } + if (flags & SDL_COPY_COLORKEY) { + /* srcpixel isn't set for 24 bpp */ + if (srcbpp == 3) { + srcpixel = (srcR << src_fmt->Rshift) | + (srcG << src_fmt->Gshift) | (srcB << src_fmt->Bshift); + } + if ((srcpixel & rgbmask) == ckey) { + continue; + } + } + if ((flags & (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_MUL))) { + if (FORMAT_HAS_ALPHA(dstfmt_val)) { + DISEMBLE_RGBA(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG, dstB, dstA); + } else if (FORMAT_HAS_NO_ALPHA(dstfmt_val)) { + DISEMBLE_RGB(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG, dstB); + dstA = 0xFF; + } else { + /* SDL_PIXELFORMAT_ARGB2101010 */ + dstpixel = *((Uint32 *) (dst)); + RGBA_FROM_ARGB2101010(dstpixel, dstR, dstG, dstB, dstA); + } + } else { + /* don't care */ + dstR = dstG = dstB = dstA = 0; + } + + if (!is_uniform) { + TRIANGLE_GET_COLOR + modulateR = r; + modulateG = g; + modulateB = b; + modulateA = a; + } + + if (flags & SDL_COPY_MODULATE_COLOR) { + srcR = (srcR * modulateR) / 255; + srcG = (srcG * modulateG) / 255; + srcB = (srcB * modulateB) / 255; + } + if (flags & SDL_COPY_MODULATE_ALPHA) { + srcA = (srcA * modulateA) / 255; + } + if (flags & (SDL_COPY_BLEND | SDL_COPY_ADD)) { + /* This goes away if we ever use premultiplied alpha */ + if (srcA < 255) { + srcR = (srcR * srcA) / 255; + srcG = (srcG * srcA) / 255; + srcB = (srcB * srcA) / 255; + } + } + switch (flags & (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_MUL)) { + case 0: + dstR = srcR; + dstG = srcG; + dstB = srcB; + dstA = srcA; + break; + case SDL_COPY_BLEND: + dstR = srcR + ((255 - srcA) * dstR) / 255; + dstG = srcG + ((255 - srcA) * dstG) / 255; + dstB = srcB + ((255 - srcA) * dstB) / 255; + dstA = srcA + ((255 - srcA) * dstA) / 255; + break; + case SDL_COPY_ADD: + dstR = srcR + dstR; + if (dstR > 255) { + dstR = 255; + } + dstG = srcG + dstG; + if (dstG > 255) { + dstG = 255; + } + dstB = srcB + dstB; + if (dstB > 255) { + dstB = 255; + } + break; + case SDL_COPY_MOD: + dstR = (srcR * dstR) / 255; + dstG = (srcG * dstG) / 255; + dstB = (srcB * dstB) / 255; + break; + case SDL_COPY_MUL: + dstR = ((srcR * dstR) + (dstR * (255 - srcA))) / 255; + if (dstR > 255) { + dstR = 255; + } + dstG = ((srcG * dstG) + (dstG * (255 - srcA))) / 255; + if (dstG > 255) { + dstG = 255; + } + dstB = ((srcB * dstB) + (dstB * (255 - srcA))) / 255; + if (dstB > 255) { + dstB = 255; + } + break; + } + if (FORMAT_HAS_ALPHA(dstfmt_val)) { + ASSEMBLE_RGBA(dst, dstbpp, dst_fmt, dstR, dstG, dstB, dstA); + } else if (FORMAT_HAS_NO_ALPHA(dstfmt_val)) { + ASSEMBLE_RGB(dst, dstbpp, dst_fmt, dstR, dstG, dstB); + } else { + /* SDL_PIXELFORMAT_ARGB2101010 */ + Uint32 pixel; + ARGB2101010_FROM_RGBA(pixel, dstR, dstG, dstB, dstA); + *(Uint32 *)dst = pixel; + } + } + TRIANGLE_END_LOOP +} + +#endif /* SDL_VIDEO_RENDER_SW */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/render/software/SDL_triangle.h b/SDL2-2.30.5/src/render/software/SDL_triangle.h new file mode 100644 index 0000000..463cab6 --- /dev/null +++ b/SDL2-2.30.5/src/render/software/SDL_triangle.h @@ -0,0 +1,42 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#ifndef SDL_triangle_h_ +#define SDL_triangle_h_ + +#include "../../SDL_internal.h" + +extern int SDL_SW_FillTriangle(SDL_Surface *dst, + SDL_Point *d0, SDL_Point *d1, SDL_Point *d2, + SDL_BlendMode blend, SDL_Color c0, SDL_Color c1, SDL_Color c2); + +extern int SDL_SW_BlitTriangle( + SDL_Surface *src, + SDL_Point *s0, SDL_Point *s1, SDL_Point *s2, + SDL_Surface *dst, + SDL_Point *d0, SDL_Point *d1, SDL_Point *d2, + SDL_Color c0, SDL_Color c1, SDL_Color c2); + +extern void trianglepoint_2_fixedpoint(SDL_Point *a); + +#endif /* SDL_triangle_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/render/vitagxm/SDL_render_vita_gxm.c b/SDL2-2.30.5/src/render/vitagxm/SDL_render_vita_gxm.c new file mode 100644 index 0000000..7d80859 --- /dev/null +++ b/SDL2-2.30.5/src/render/vitagxm/SDL_render_vita_gxm.c @@ -0,0 +1,1230 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#if SDL_VIDEO_RENDER_VITA_GXM + +#include "SDL_hints.h" +#include "../SDL_sysrender.h" +#include "SDL_log.h" + +#include +#include +#include +#include +#include + +#include "SDL_render_vita_gxm_types.h" +#include "SDL_render_vita_gxm_tools.h" +#include "SDL_render_vita_gxm_memory.h" + +#include + +/* #define DEBUG_RAZOR */ + +#ifdef DEBUG_RAZOR +#include +#endif + +static SDL_Renderer *VITA_GXM_CreateRenderer(SDL_Window *window, Uint32 flags); + +static void VITA_GXM_WindowEvent(SDL_Renderer *renderer, const SDL_WindowEvent *event); + +static SDL_bool VITA_GXM_SupportsBlendMode(SDL_Renderer *renderer, SDL_BlendMode blendMode); + +static int VITA_GXM_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture); + +static int VITA_GXM_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *rect, const void *pixels, int pitch); + +static int VITA_GXM_UpdateTextureYUV(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *Uplane, int Upitch, + const Uint8 *Vplane, int Vpitch); + +static int VITA_GXM_UpdateTextureNV(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *UVplane, int UVpitch); + +static int VITA_GXM_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *rect, void **pixels, int *pitch); + +static void VITA_GXM_UnlockTexture(SDL_Renderer *renderer, + SDL_Texture *texture); + +static void VITA_GXM_SetTextureScaleMode(SDL_Renderer *renderer, SDL_Texture *texture, SDL_ScaleMode scaleMode); + +static int VITA_GXM_SetRenderTarget(SDL_Renderer *renderer, + SDL_Texture *texture); + +static int VITA_GXM_QueueSetViewport(SDL_Renderer *renderer, SDL_RenderCommand *cmd); + +static int VITA_GXM_QueueSetDrawColor(SDL_Renderer *renderer, SDL_RenderCommand *cmd); + +static int VITA_GXM_QueueDrawPoints(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count); +static int VITA_GXM_QueueDrawLines(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count); + +static int VITA_GXM_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, + const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride, + int num_vertices, const void *indices, int num_indices, int size_indices, + float scale_x, float scale_y); + +static int VITA_GXM_RenderClear(SDL_Renderer *renderer, SDL_RenderCommand *cmd); + +static int VITA_GXM_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize); + +static int VITA_GXM_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect, + Uint32 pixel_format, void *pixels, int pitch); + +static int VITA_GXM_RenderPresent(SDL_Renderer *renderer); +static void VITA_GXM_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture); +static void VITA_GXM_DestroyRenderer(SDL_Renderer *renderer); + +SDL_RenderDriver VITA_GXM_RenderDriver = { + .CreateRenderer = VITA_GXM_CreateRenderer, + .info = { + .name = "VITA gxm", + .flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE, + .num_texture_formats = 8, + .texture_formats = { + [0] = SDL_PIXELFORMAT_ABGR8888, + [1] = SDL_PIXELFORMAT_ARGB8888, + [2] = SDL_PIXELFORMAT_RGB565, + [3] = SDL_PIXELFORMAT_BGR565, + [4] = SDL_PIXELFORMAT_YV12, + [5] = SDL_PIXELFORMAT_IYUV, + [6] = SDL_PIXELFORMAT_NV12, + [7] = SDL_PIXELFORMAT_NV21, + }, + .max_texture_width = 4096, + .max_texture_height = 4096, + } +}; + +static int PixelFormatToVITAFMT(Uint32 format) +{ + switch (format) { + case SDL_PIXELFORMAT_ARGB8888: + return SCE_GXM_TEXTURE_FORMAT_U8U8U8U8_ARGB; + case SDL_PIXELFORMAT_RGB888: + return SCE_GXM_TEXTURE_FORMAT_U8U8U8U8_ARGB; + case SDL_PIXELFORMAT_BGR888: + return SCE_GXM_TEXTURE_FORMAT_U8U8U8U8_ABGR; + case SDL_PIXELFORMAT_ABGR8888: + return SCE_GXM_TEXTURE_FORMAT_U8U8U8U8_ABGR; + case SDL_PIXELFORMAT_RGB565: + return SCE_GXM_TEXTURE_FORMAT_U5U6U5_RGB; + case SDL_PIXELFORMAT_BGR565: + return SCE_GXM_TEXTURE_FORMAT_U5U6U5_BGR; + case SDL_PIXELFORMAT_YV12: + return SCE_GXM_TEXTURE_FORMAT_YVU420P3_CSC0; + case SDL_PIXELFORMAT_IYUV: + return SCE_GXM_TEXTURE_FORMAT_YUV420P3_CSC0; + // should be the other way around. looks like SCE bug. + case SDL_PIXELFORMAT_NV12: + return SCE_GXM_TEXTURE_FORMAT_YVU420P2_CSC0; + case SDL_PIXELFORMAT_NV21: + return SCE_GXM_TEXTURE_FORMAT_YUV420P2_CSC0; + default: + return SCE_GXM_TEXTURE_FORMAT_U8U8U8U8_ABGR; + } +} + +void StartDrawing(SDL_Renderer *renderer) +{ + VITA_GXM_RenderData *data = (VITA_GXM_RenderData *)renderer->driverdata; + if (data->drawing) { + return; + } + + data->drawstate.texture = NULL; + data->drawstate.vertex_program = NULL; + data->drawstate.fragment_program = NULL; + data->drawstate.last_command = -1; + data->drawstate.viewport_dirty = SDL_TRUE; + + // reset blend mode + // data->currentBlendMode = SDL_BLENDMODE_BLEND; + // fragment_programs *in = &data->blendFragmentPrograms.blend_mode_blend; + // data->colorFragmentProgram = in->color; + // data->textureFragmentProgram = in->texture; + + if (!renderer->target) { + sceGxmBeginScene( + data->gxm_context, + 0, + data->renderTarget, + NULL, + NULL, + data->displayBufferSync[data->backBufferIndex], + &data->displaySurface[data->backBufferIndex], + &data->depthSurface); + } else { + VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *)renderer->target->driverdata; + + sceGxmBeginScene( + data->gxm_context, + 0, + vita_texture->tex->gxm_rendertarget, + NULL, + NULL, + NULL, + &vita_texture->tex->gxm_colorsurface, + &vita_texture->tex->gxm_depthstencil); + } + + // unset_clip_rectangle(data); + + data->drawing = SDL_TRUE; +} + +static int VITA_GXM_SetVSync(SDL_Renderer *renderer, const int vsync) +{ + VITA_GXM_RenderData *data = renderer->driverdata; + if (vsync) { + data->displayData.wait_vblank = SDL_TRUE; + renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; + } else { + data->displayData.wait_vblank = SDL_FALSE; + renderer->info.flags &= ~SDL_RENDERER_PRESENTVSYNC; + } + return 0; +} + +SDL_Renderer *VITA_GXM_CreateRenderer(SDL_Window *window, Uint32 flags) +{ + SDL_Renderer *renderer; + VITA_GXM_RenderData *data; + + renderer = (SDL_Renderer *)SDL_calloc(1, sizeof(*renderer)); + if (!renderer) { + SDL_OutOfMemory(); + return NULL; + } + + data = (VITA_GXM_RenderData *)SDL_calloc(1, sizeof(VITA_GXM_RenderData)); + if (!data) { + SDL_free(renderer); + SDL_OutOfMemory(); + return NULL; + } + + renderer->WindowEvent = VITA_GXM_WindowEvent; + renderer->SupportsBlendMode = VITA_GXM_SupportsBlendMode; + renderer->CreateTexture = VITA_GXM_CreateTexture; + renderer->UpdateTexture = VITA_GXM_UpdateTexture; +#if SDL_HAVE_YUV + renderer->UpdateTextureYUV = VITA_GXM_UpdateTextureYUV; + renderer->UpdateTextureNV = VITA_GXM_UpdateTextureNV; +#endif + renderer->LockTexture = VITA_GXM_LockTexture; + renderer->UnlockTexture = VITA_GXM_UnlockTexture; + renderer->SetTextureScaleMode = VITA_GXM_SetTextureScaleMode; + renderer->SetRenderTarget = VITA_GXM_SetRenderTarget; + renderer->QueueSetViewport = VITA_GXM_QueueSetViewport; + renderer->QueueSetDrawColor = VITA_GXM_QueueSetDrawColor; + renderer->QueueDrawPoints = VITA_GXM_QueueDrawPoints; + renderer->QueueDrawLines = VITA_GXM_QueueDrawLines; + renderer->QueueGeometry = VITA_GXM_QueueGeometry; + renderer->RunCommandQueue = VITA_GXM_RunCommandQueue; + renderer->RenderReadPixels = VITA_GXM_RenderReadPixels; + renderer->RenderPresent = VITA_GXM_RenderPresent; + renderer->DestroyTexture = VITA_GXM_DestroyTexture; + renderer->DestroyRenderer = VITA_GXM_DestroyRenderer; + renderer->SetVSync = VITA_GXM_SetVSync; + + renderer->info = VITA_GXM_RenderDriver.info; + renderer->info.flags = (SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE); + renderer->driverdata = data; + renderer->window = window; + + data->initialized = SDL_TRUE; + + if (flags & SDL_RENDERER_PRESENTVSYNC) { + data->displayData.wait_vblank = SDL_TRUE; + } else { + data->displayData.wait_vblank = SDL_FALSE; + } + +#ifdef DEBUG_RAZOR + sceSysmoduleLoadModule(SCE_SYSMODULE_RAZOR_HUD); + sceSysmoduleLoadModule(SCE_SYSMODULE_RAZOR_CAPTURE); +#endif + + if (gxm_init(renderer) != 0) { + SDL_free(data); + SDL_free(renderer); + return NULL; + } + + return renderer; +} + +static void VITA_GXM_WindowEvent(SDL_Renderer *renderer, const SDL_WindowEvent *event) +{ +} + +static SDL_bool VITA_GXM_SupportsBlendMode(SDL_Renderer *renderer, SDL_BlendMode blendMode) +{ + // only for custom modes. we build all modes on init, so no custom modes, sorry + return SDL_FALSE; +} + +static int VITA_GXM_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) +{ + VITA_GXM_RenderData *data = (VITA_GXM_RenderData *)renderer->driverdata; + VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *)SDL_calloc(1, sizeof(VITA_GXM_TextureData)); + + if (!vita_texture) { + return SDL_OutOfMemory(); + } + + vita_texture->tex = create_gxm_texture( + data, + texture->w, + texture->h, + PixelFormatToVITAFMT(texture->format), + (texture->access == SDL_TEXTUREACCESS_TARGET), + &(vita_texture->w), + &(vita_texture->h), + &(vita_texture->pitch), + &(vita_texture->wscale)); + + if (!vita_texture->tex) { + SDL_free(vita_texture); + return SDL_OutOfMemory(); + } + + texture->driverdata = vita_texture; + + VITA_GXM_SetTextureScaleMode(renderer, texture, texture->scaleMode); + +#if SDL_HAVE_YUV + vita_texture->yuv = ((texture->format == SDL_PIXELFORMAT_IYUV) || (texture->format == SDL_PIXELFORMAT_YV12)); + vita_texture->nv12 = ((texture->format == SDL_PIXELFORMAT_NV12) || (texture->format == SDL_PIXELFORMAT_NV21)); +#endif + + return 0; +} + +static void VITA_GXM_SetYUVProfile(SDL_Renderer *renderer, SDL_Texture *texture) +{ + VITA_GXM_RenderData *data = (VITA_GXM_RenderData *)renderer->driverdata; + int ret = 0; + switch (SDL_GetYUVConversionModeForResolution(texture->w, texture->h)) { + case SDL_YUV_CONVERSION_BT601: + ret = sceGxmSetYuvProfile(data->gxm_context, 0, SCE_GXM_YUV_PROFILE_BT601_STANDARD); + break; + case SDL_YUV_CONVERSION_BT709: + ret = sceGxmSetYuvProfile(data->gxm_context, 0, SCE_GXM_YUV_PROFILE_BT709_STANDARD); + break; + case SDL_YUV_CONVERSION_JPEG: + default: + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Unsupported YUV profile: %d\n", SDL_GetYUVConversionModeForResolution(texture->w, texture->h)); + break; + } + + if (ret < 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Setting YUV profile failed: %x\n", ret); + } +} + +static int VITA_GXM_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *rect, const void *pixels, int pitch) +{ + VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *)texture->driverdata; + Uint8 *dst; + int row, length, dpitch; + +#if SDL_HAVE_YUV + if (vita_texture->yuv || vita_texture->nv12) { + VITA_GXM_SetYUVProfile(renderer, texture); + } +#endif + + VITA_GXM_LockTexture(renderer, texture, rect, (void **)&dst, &dpitch); + length = rect->w * SDL_BYTESPERPIXEL(texture->format); + if (length == pitch && length == dpitch) { + SDL_memcpy(dst, pixels, length * rect->h); + } else { + for (row = 0; row < rect->h; ++row) { + SDL_memcpy(dst, pixels, length); + pixels += pitch; + dst += dpitch; + } + } + +#if SDL_HAVE_YUV + if (vita_texture->yuv) { + void *Udst; + void *Vdst; + int uv_pitch = (dpitch + 1) / 2; + int uv_src_pitch = (pitch + 1) / 2; + SDL_Rect UVrect = { rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2 }; + + // skip Y plane + Uint8 *Dpixels = gxm_texture_get_datap(vita_texture->tex) + (vita_texture->pitch * vita_texture->h); + + Udst = Dpixels + (UVrect.y * uv_pitch) + UVrect.x; + Vdst = Dpixels + (uv_pitch * ((vita_texture->h + 1) / 2)) + (UVrect.y * uv_pitch) + UVrect.x; + + length = UVrect.w; + + // U plane + if (length == uv_src_pitch && length == uv_pitch) { + SDL_memcpy(Udst, pixels, length * UVrect.h); + } else { + for (row = 0; row < UVrect.h; ++row) { + SDL_memcpy(Udst, pixels, length); + pixels += uv_src_pitch; + Udst += uv_pitch; + } + } + + // V plane + if (length == uv_src_pitch && length == uv_pitch) { + SDL_memcpy(Vdst, pixels, length * UVrect.h); + } else { + for (row = 0; row < UVrect.h; ++row) { + SDL_memcpy(Vdst, pixels, length); + pixels += uv_src_pitch; + Vdst += uv_pitch; + } + } + + } else if (vita_texture->nv12) { + void *UVdst; + int uv_pitch = 2 * ((dpitch + 1) / 2); + int uv_src_pitch = 2 * ((pitch + 1) / 2); + SDL_Rect UVrect = { rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2 }; + + // skip Y plane + void *Dpixels = (void *)((Uint8 *)gxm_texture_get_datap(vita_texture->tex) + (vita_texture->pitch * vita_texture->h)); + UVdst = Dpixels + (UVrect.y * uv_pitch) + UVrect.x; + + length = UVrect.w * 2; + + // UV plane + if (length == uv_src_pitch && length == uv_pitch) { + SDL_memcpy(UVdst, pixels, length * UVrect.h); + } else { + for (row = 0; row < UVrect.h; ++row) { + SDL_memcpy(UVdst, pixels, length); + pixels += uv_src_pitch; + UVdst += uv_pitch; + } + } + } +#endif + + return 0; +} + +#if SDL_HAVE_YUV +static int VITA_GXM_UpdateTextureYUV(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *Uplane, int Upitch, + const Uint8 *Vplane, int Vpitch) +{ + Uint8 *dst; + int row, length, dpitch; + SDL_Rect UVrect = { rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2 }; + + VITA_GXM_SetYUVProfile(renderer, texture); + + // copy Y plane + // obtain pixels via locking so that texture is flushed + VITA_GXM_LockTexture(renderer, texture, rect, (void **)&dst, &dpitch); + + length = rect->w; + + if (length == Ypitch && length == dpitch) { + SDL_memcpy(dst, Yplane, length * rect->h); + } else { + for (row = 0; row < rect->h; ++row) { + SDL_memcpy(dst, Yplane, length); + Yplane += Ypitch; + dst += dpitch; + } + } + + // U/V planes + { + void *Udst; + void *Vdst; + VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *)texture->driverdata; + int uv_pitch = (dpitch + 1) / 2; + + // skip Y plane + void *pixels = (void *)((Uint8 *)gxm_texture_get_datap(vita_texture->tex) + (vita_texture->pitch * vita_texture->h)); + + if (texture->format == SDL_PIXELFORMAT_YV12) { // YVU + Vdst = pixels + (UVrect.y * uv_pitch) + UVrect.x; + Udst = pixels + (uv_pitch * ((vita_texture->h + 1) / 2)) + (UVrect.y * uv_pitch) + UVrect.x; + } else { // YUV + Udst = pixels + (UVrect.y * uv_pitch) + UVrect.x; + Vdst = pixels + (uv_pitch * ((vita_texture->h + 1) / 2)) + (UVrect.y * uv_pitch) + UVrect.x; + } + + length = UVrect.w; + + // U plane + if (length == Upitch && length == uv_pitch) { + SDL_memcpy(Udst, Uplane, length * UVrect.h); + } else { + for (row = 0; row < UVrect.h; ++row) { + SDL_memcpy(Udst, Uplane, length); + Uplane += Upitch; + Udst += uv_pitch; + } + } + + // V plane + if (length == Vpitch && length == uv_pitch) { + SDL_memcpy(Vdst, Vplane, length * UVrect.h); + } else { + for (row = 0; row < UVrect.h; ++row) { + SDL_memcpy(Vdst, Vplane, length); + Vplane += Vpitch; + Vdst += uv_pitch; + } + } + } + + return 0; +} + +static int VITA_GXM_UpdateTextureNV(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *rect, + const Uint8 *Yplane, int Ypitch, + const Uint8 *UVplane, int UVpitch) +{ + + Uint8 *dst; + int row, length, dpitch; + SDL_Rect UVrect = { rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2 }; + + VITA_GXM_SetYUVProfile(renderer, texture); + + // copy Y plane + VITA_GXM_LockTexture(renderer, texture, rect, (void **)&dst, &dpitch); + + length = rect->w * SDL_BYTESPERPIXEL(texture->format); + + if (length == Ypitch && length == dpitch) { + SDL_memcpy(dst, Yplane, length * rect->h); + } else { + for (row = 0; row < rect->h; ++row) { + SDL_memcpy(dst, Yplane, length); + Yplane += Ypitch; + dst += dpitch; + } + } + + // UV plane + { + void *UVdst; + VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *)texture->driverdata; + int uv_pitch = 2 * ((dpitch + 1) / 2); + + // skip Y plane + void *pixels = (void *)((Uint8 *)gxm_texture_get_datap(vita_texture->tex) + (vita_texture->pitch * vita_texture->h)); + + UVdst = pixels + (UVrect.y * uv_pitch) + UVrect.x; + + length = UVrect.w * 2; + + // UV plane + if (length == UVpitch && length == uv_pitch) { + SDL_memcpy(UVdst, UVplane, length * UVrect.h); + } else { + for (row = 0; row < UVrect.h; ++row) { + SDL_memcpy(UVdst, UVplane, length); + UVplane += UVpitch; + UVdst += uv_pitch; + } + } + } + + return 0; +} + +#endif + +static int VITA_GXM_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture, + const SDL_Rect *rect, void **pixels, int *pitch) +{ + VITA_GXM_RenderData *data = (VITA_GXM_RenderData *)renderer->driverdata; + VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *)texture->driverdata; + + *pixels = + (void *)((Uint8 *)gxm_texture_get_datap(vita_texture->tex) + (rect->y * vita_texture->pitch) + rect->x * SDL_BYTESPERPIXEL(texture->format)); + *pitch = vita_texture->pitch; + + // make sure that rendering is finished on render target textures + if (vita_texture->tex->gxm_rendertarget) { + sceGxmFinish(data->gxm_context); + } + + return 0; +} + +static void VITA_GXM_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture) +{ + // No need to update texture data on ps vita. + // VITA_GXM_LockTexture already returns a pointer to the texture pixels buffer. + // This really improves framerate when using lock/unlock. +} + +static void VITA_GXM_SetTextureScaleMode(SDL_Renderer *renderer, SDL_Texture *texture, SDL_ScaleMode scaleMode) +{ + VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *)texture->driverdata; + + /* + set texture filtering according to scaleMode + suported hint values are nearest (0, default) or linear (1) + vitaScaleMode is either SCE_GXM_TEXTURE_FILTER_POINT (good for tile-map) + or SCE_GXM_TEXTURE_FILTER_LINEAR (good for scaling) + */ + + int vitaScaleMode = (scaleMode == SDL_ScaleModeNearest + ? SCE_GXM_TEXTURE_FILTER_POINT + : SCE_GXM_TEXTURE_FILTER_LINEAR); + gxm_texture_set_filters(vita_texture->tex, vitaScaleMode, vitaScaleMode); + + return; +} + +static int VITA_GXM_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture) +{ + return 0; +} + +static void VITA_GXM_SetBlendMode(VITA_GXM_RenderData *data, int blendMode) +{ + if (blendMode != data->currentBlendMode) { + fragment_programs *in = &data->blendFragmentPrograms.blend_mode_blend; + + switch (blendMode) { + case SDL_BLENDMODE_NONE: + in = &data->blendFragmentPrograms.blend_mode_none; + break; + case SDL_BLENDMODE_BLEND: + in = &data->blendFragmentPrograms.blend_mode_blend; + break; + case SDL_BLENDMODE_ADD: + in = &data->blendFragmentPrograms.blend_mode_add; + break; + case SDL_BLENDMODE_MOD: + in = &data->blendFragmentPrograms.blend_mode_mod; + break; + case SDL_BLENDMODE_MUL: + in = &data->blendFragmentPrograms.blend_mode_mul; + break; + } + data->colorFragmentProgram = in->color; + data->textureFragmentProgram = in->texture; + data->currentBlendMode = blendMode; + } +} + +static int VITA_GXM_QueueSetViewport(SDL_Renderer *renderer, SDL_RenderCommand *cmd) +{ + return 0; +} + +static int VITA_GXM_QueueSetDrawColor(SDL_Renderer *renderer, SDL_RenderCommand *cmd) +{ + VITA_GXM_RenderData *data = (VITA_GXM_RenderData *)renderer->driverdata; + + data->drawstate.color.r = cmd->data.color.r; + data->drawstate.color.g = cmd->data.color.g; + data->drawstate.color.b = cmd->data.color.b; + data->drawstate.color.a = cmd->data.color.a; + + return 0; +} + +static int VITA_GXM_QueueDrawPoints(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count) +{ + VITA_GXM_RenderData *data = (VITA_GXM_RenderData *)renderer->driverdata; + + SDL_Color color = data->drawstate.color; + + color_vertex *vertex = (color_vertex *)pool_malloc( + data, + count * sizeof(color_vertex)); + + cmd->data.draw.first = (size_t)vertex; + cmd->data.draw.count = count; + + for (int i = 0; i < count; i++) { + vertex[i].x = points[i].x; + vertex[i].y = points[i].y; + vertex[i].color = color; + } + + return 0; +} + +static int VITA_GXM_QueueDrawLines(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count) +{ + VITA_GXM_RenderData *data = (VITA_GXM_RenderData *)renderer->driverdata; + SDL_Color color = data->drawstate.color; + + color_vertex *vertex = (color_vertex *)pool_malloc( + data, + (count - 1) * 2 * sizeof(color_vertex)); + + cmd->data.draw.first = (size_t)vertex; + cmd->data.draw.count = (count - 1) * 2; + + for (int i = 0; i < count - 1; i++) { + vertex[i * 2].x = points[i].x; + vertex[i * 2].y = points[i].y; + vertex[i * 2].color = color; + + vertex[i * 2 + 1].x = points[i + 1].x; + vertex[i * 2 + 1].y = points[i + 1].y; + vertex[i * 2 + 1].color = color; + } + + return 0; +} + +static int VITA_GXM_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, + const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride, + int num_vertices, const void *indices, int num_indices, int size_indices, + float scale_x, float scale_y) +{ + VITA_GXM_RenderData *data = (VITA_GXM_RenderData *)renderer->driverdata; + int i; + int count = indices ? num_indices : num_vertices; + + cmd->data.draw.count = count; + size_indices = indices ? size_indices : 0; + + if (texture) { + VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *)texture->driverdata; + texture_vertex *vertices; + + vertices = (texture_vertex *)pool_malloc( + data, + count * sizeof(texture_vertex)); + + if (!vertices) { + return -1; + } + + for (i = 0; i < count; i++) { + int j; + float *xy_; + float *uv_; + SDL_Color col_; + if (size_indices == 4) { + j = ((const Uint32 *)indices)[i]; + } else if (size_indices == 2) { + j = ((const Uint16 *)indices)[i]; + } else if (size_indices == 1) { + j = ((const Uint8 *)indices)[i]; + } else { + j = i; + } + + xy_ = (float *)((char *)xy + j * xy_stride); + col_ = *(SDL_Color *)((char *)color + j * color_stride); + uv_ = (float *)((char *)uv + j * uv_stride); + + vertices[i].x = xy_[0] * scale_x; + vertices[i].y = xy_[1] * scale_y; + vertices[i].u = uv_[0] * vita_texture->wscale; + vertices[i].v = uv_[1]; + vertices[i].color = col_; + } + + cmd->data.draw.first = (size_t)vertices; + + } else { + color_vertex *vertices; + + vertices = (color_vertex *)pool_malloc( + data, + count * sizeof(color_vertex)); + + if (!vertices) { + return -1; + } + + for (i = 0; i < count; i++) { + int j; + float *xy_; + SDL_Color col_; + if (size_indices == 4) { + j = ((const Uint32 *)indices)[i]; + } else if (size_indices == 2) { + j = ((const Uint16 *)indices)[i]; + } else if (size_indices == 1) { + j = ((const Uint8 *)indices)[i]; + } else { + j = i; + } + + xy_ = (float *)((char *)xy + j * xy_stride); + col_ = *(SDL_Color *)((char *)color + j * color_stride); + + vertices[i].x = xy_[0] * scale_x; + vertices[i].y = xy_[1] * scale_y; + vertices[i].color = col_; + } + cmd->data.draw.first = (size_t)vertices; + } + + return 0; +} + +static int VITA_GXM_RenderClear(SDL_Renderer *renderer, SDL_RenderCommand *cmd) +{ + void *color_buffer; + float clear_color[4]; + + VITA_GXM_RenderData *data = (VITA_GXM_RenderData *)renderer->driverdata; + unset_clip_rectangle(data); + + clear_color[0] = (cmd->data.color.r) / 255.0f; + clear_color[1] = (cmd->data.color.g) / 255.0f; + clear_color[2] = (cmd->data.color.b) / 255.0f; + clear_color[3] = (cmd->data.color.a) / 255.0f; + + // set clear shaders + data->drawstate.fragment_program = data->clearFragmentProgram; + data->drawstate.vertex_program = data->clearVertexProgram; + sceGxmSetVertexProgram(data->gxm_context, data->clearVertexProgram); + sceGxmSetFragmentProgram(data->gxm_context, data->clearFragmentProgram); + + // set the clear color + sceGxmReserveFragmentDefaultUniformBuffer(data->gxm_context, &color_buffer); + sceGxmSetUniformDataF(color_buffer, data->clearClearColorParam, 0, 4, clear_color); + + // draw the clear triangle + sceGxmSetVertexStream(data->gxm_context, 0, data->clearVertices); + sceGxmDraw(data->gxm_context, SCE_GXM_PRIMITIVE_TRIANGLES, SCE_GXM_INDEX_FORMAT_U16, data->linearIndices, 3); + + data->drawstate.cliprect_dirty = SDL_TRUE; + return 0; +} + +static int SetDrawState(VITA_GXM_RenderData *data, const SDL_RenderCommand *cmd) +{ + SDL_Texture *texture = cmd->data.draw.texture; + const SDL_BlendMode blend = cmd->data.draw.blend; + SceGxmFragmentProgram *fragment_program; + SceGxmVertexProgram *vertex_program; + SDL_bool matrix_updated = SDL_FALSE; + SDL_bool program_updated = SDL_FALSE; + + if (data->drawstate.viewport_dirty) { + const SDL_Rect *viewport = &data->drawstate.viewport; + + float sw = viewport->w / 2.; + float sh = viewport->h / 2.; + + float x_scale = sw; + float x_off = viewport->x + sw; + float y_scale = -(sh); + float y_off = viewport->y + sh; + + sceGxmSetViewport(data->gxm_context, x_off, x_scale, y_off, y_scale, 0.5f, 0.5f); + + if (viewport->w && viewport->h) { + init_orthographic_matrix(data->ortho_matrix, + (float)0, + (float)viewport->w, + (float)viewport->h, + (float)0, + 0.0f, 1.0f); + matrix_updated = SDL_TRUE; + } + + data->drawstate.viewport_dirty = SDL_FALSE; + } + + if (data->drawstate.cliprect_enabled_dirty) { + if (!data->drawstate.cliprect_enabled) { + unset_clip_rectangle(data); + } + data->drawstate.cliprect_enabled_dirty = SDL_FALSE; + } + + if (data->drawstate.cliprect_enabled && data->drawstate.cliprect_dirty) { + const SDL_Rect *rect = &data->drawstate.cliprect; + set_clip_rectangle(data, rect->x, rect->y, rect->x + rect->w, rect->y + rect->h); + data->drawstate.cliprect_dirty = SDL_FALSE; + } + + VITA_GXM_SetBlendMode(data, blend); // do that first, to select appropriate shaders + + if (texture) { + vertex_program = data->textureVertexProgram; + fragment_program = data->textureFragmentProgram; + } else { + vertex_program = data->colorVertexProgram; + fragment_program = data->colorFragmentProgram; + } + + if (data->drawstate.vertex_program != vertex_program) { + data->drawstate.vertex_program = vertex_program; + sceGxmSetVertexProgram(data->gxm_context, vertex_program); + program_updated = SDL_TRUE; + } + + if (data->drawstate.fragment_program != fragment_program) { + data->drawstate.fragment_program = fragment_program; + sceGxmSetFragmentProgram(data->gxm_context, fragment_program); + program_updated = SDL_TRUE; + } + + if (program_updated || matrix_updated) { + if (data->drawstate.fragment_program == data->textureFragmentProgram) { + void *vertex_wvp_buffer; + sceGxmReserveVertexDefaultUniformBuffer(data->gxm_context, &vertex_wvp_buffer); + sceGxmSetUniformDataF(vertex_wvp_buffer, data->textureWvpParam, 0, 16, data->ortho_matrix); + } else { // color + void *vertexDefaultBuffer; + sceGxmReserveVertexDefaultUniformBuffer(data->gxm_context, &vertexDefaultBuffer); + sceGxmSetUniformDataF(vertexDefaultBuffer, data->colorWvpParam, 0, 16, data->ortho_matrix); + } + } + + if (texture != data->drawstate.texture) { + if (texture) { + VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *)cmd->data.draw.texture->driverdata; + sceGxmSetFragmentTexture(data->gxm_context, 0, &vita_texture->tex->gxm_tex); + } + data->drawstate.texture = texture; + } + + /* all drawing commands use this */ + sceGxmSetVertexStream(data->gxm_context, 0, (const void *)cmd->data.draw.first); + + return 0; +} + +static int VITA_GXM_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize) +{ + VITA_GXM_RenderData *data = (VITA_GXM_RenderData *)renderer->driverdata; + StartDrawing(renderer); + + data->drawstate.target = renderer->target; + if (!data->drawstate.target) { + int w, h; + SDL_GL_GetDrawableSize(renderer->window, &w, &h); + if ((w != data->drawstate.drawablew) || (h != data->drawstate.drawableh)) { + data->drawstate.viewport_dirty = SDL_TRUE; // if the window dimensions changed, invalidate the current viewport, etc. + data->drawstate.cliprect_dirty = SDL_TRUE; + data->drawstate.drawablew = w; + data->drawstate.drawableh = h; + } + } + + while (cmd) { + switch (cmd->command) { + + case SDL_RENDERCMD_SETVIEWPORT: + { + SDL_Rect *viewport = &data->drawstate.viewport; + if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof(cmd->data.viewport.rect)) != 0) { + SDL_copyp(viewport, &cmd->data.viewport.rect); + data->drawstate.viewport_dirty = SDL_TRUE; + data->drawstate.cliprect_dirty = SDL_TRUE; + } + break; + } + + case SDL_RENDERCMD_SETCLIPRECT: + { + const SDL_Rect *rect = &cmd->data.cliprect.rect; + if (data->drawstate.cliprect_enabled != cmd->data.cliprect.enabled) { + data->drawstate.cliprect_enabled = cmd->data.cliprect.enabled; + data->drawstate.cliprect_enabled_dirty = SDL_TRUE; + } + + if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof(*rect)) != 0) { + SDL_copyp(&data->drawstate.cliprect, rect); + data->drawstate.cliprect_dirty = SDL_TRUE; + } + break; + } + + case SDL_RENDERCMD_SETDRAWCOLOR: + { + break; + } + + case SDL_RENDERCMD_CLEAR: + { + VITA_GXM_RenderClear(renderer, cmd); + break; + } + + case SDL_RENDERCMD_FILL_RECTS: /* unused */ + break; + + case SDL_RENDERCMD_COPY: /* unused */ + break; + + case SDL_RENDERCMD_COPY_EX: /* unused */ + break; + + case SDL_RENDERCMD_DRAW_POINTS: + case SDL_RENDERCMD_DRAW_LINES: + case SDL_RENDERCMD_GEOMETRY: + { + SDL_Texture *thistexture = cmd->data.draw.texture; + SDL_BlendMode thisblend = cmd->data.draw.blend; + const SDL_RenderCommandType thiscmdtype = cmd->command; + SDL_RenderCommand *finalcmd = cmd; + SDL_RenderCommand *nextcmd = cmd->next; + size_t count = cmd->data.draw.count; + int ret; + while (nextcmd) { + const SDL_RenderCommandType nextcmdtype = nextcmd->command; + if (nextcmdtype != thiscmdtype) { + break; /* can't go any further on this draw call, different render command up next. */ + } else if (nextcmd->data.draw.texture != thistexture || nextcmd->data.draw.blend != thisblend) { + break; /* can't go any further on this draw call, different texture/blendmode copy up next. */ + } else { + finalcmd = nextcmd; /* we can combine copy operations here. Mark this one as the furthest okay command. */ + count += nextcmd->data.draw.count; + } + nextcmd = nextcmd->next; + } + + ret = SetDrawState(data, cmd); + + if (ret == 0) { + int op = SCE_GXM_PRIMITIVE_TRIANGLES; + + if (thiscmdtype == SDL_RENDERCMD_DRAW_POINTS) { + sceGxmSetFrontPolygonMode(data->gxm_context, SCE_GXM_POLYGON_MODE_POINT); + op = SCE_GXM_PRIMITIVE_POINTS; + } else if (thiscmdtype == SDL_RENDERCMD_DRAW_LINES) { + sceGxmSetFrontPolygonMode(data->gxm_context, SCE_GXM_POLYGON_MODE_LINE); + op = SCE_GXM_PRIMITIVE_LINES; + } + + sceGxmDraw(data->gxm_context, op, SCE_GXM_INDEX_FORMAT_U16, data->linearIndices, count); + + if (thiscmdtype == SDL_RENDERCMD_DRAW_POINTS || thiscmdtype == SDL_RENDERCMD_DRAW_LINES) { + sceGxmSetFrontPolygonMode(data->gxm_context, SCE_GXM_POLYGON_MODE_TRIANGLE_FILL); + } + } + + cmd = finalcmd; /* skip any copy commands we just combined in here. */ + break; + } + + case SDL_RENDERCMD_NO_OP: + break; + } + data->drawstate.last_command = cmd->command; + cmd = cmd->next; + } + + sceGxmEndScene(data->gxm_context, NULL, NULL); + data->drawing = SDL_FALSE; + + return 0; +} + +void read_pixels(int x, int y, size_t width, size_t height, void *data) +{ + SceDisplayFrameBuf pParam; + int i, j; + Uint32 *out32; + Uint32 *in32; + + pParam.size = sizeof(SceDisplayFrameBuf); + + sceDisplayGetFrameBuf(&pParam, SCE_DISPLAY_SETBUF_NEXTFRAME); + + out32 = (Uint32 *)data; + in32 = (Uint32 *)pParam.base; + + in32 += (x + y * pParam.pitch); + + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) { + out32[(height - (i + 1)) * width + j] = in32[j]; + } + in32 += pParam.pitch; + } +} + +static int VITA_GXM_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect, + Uint32 pixel_format, void *pixels, int pitch) +{ + Uint32 temp_format = renderer->target ? renderer->target->format : SDL_PIXELFORMAT_ABGR8888; + size_t buflen; + void *temp_pixels; + int temp_pitch; + Uint8 *src, *dst, *tmp; + int w, h, length, rows; + int status; + + // TODO: read from texture rendertarget. Although no-one sane should do it. + if (renderer->target) { + return SDL_Unsupported(); + } + + temp_pitch = rect->w * SDL_BYTESPERPIXEL(temp_format); + buflen = rect->h * temp_pitch; + if (buflen == 0) { + return 0; /* nothing to do. */ + } + + temp_pixels = SDL_malloc(buflen); + if (!temp_pixels) { + return SDL_OutOfMemory(); + } + + SDL_GetRendererOutputSize(renderer, &w, &h); + + read_pixels(rect->x, renderer->target ? rect->y : (h - rect->y) - rect->h, + rect->w, rect->h, temp_pixels); + + /* Flip the rows to be top-down if necessary */ + + if (!renderer->target) { + SDL_bool isstack; + length = rect->w * SDL_BYTESPERPIXEL(temp_format); + src = (Uint8 *)temp_pixels + (rect->h - 1) * temp_pitch; + dst = (Uint8 *)temp_pixels; + tmp = SDL_small_alloc(Uint8, length, &isstack); + rows = rect->h / 2; + while (rows--) { + SDL_memcpy(tmp, dst, length); + SDL_memcpy(dst, src, length); + SDL_memcpy(src, tmp, length); + dst += temp_pitch; + src -= temp_pitch; + } + SDL_small_free(tmp, isstack); + } + + status = SDL_ConvertPixels(rect->w, rect->h, + temp_format, temp_pixels, temp_pitch, + pixel_format, pixels, pitch); + SDL_free(temp_pixels); + + return status; +} + +static int VITA_GXM_RenderPresent(SDL_Renderer *renderer) +{ + VITA_GXM_RenderData *data = (VITA_GXM_RenderData *)renderer->driverdata; + SceCommonDialogUpdateParam updateParam; + + data->displayData.address = data->displayBufferData[data->backBufferIndex]; + + SDL_memset(&updateParam, 0, sizeof(updateParam)); + + updateParam.renderTarget.colorFormat = VITA_GXM_COLOR_FORMAT; + updateParam.renderTarget.surfaceType = SCE_GXM_COLOR_SURFACE_LINEAR; + updateParam.renderTarget.width = VITA_GXM_SCREEN_WIDTH; + updateParam.renderTarget.height = VITA_GXM_SCREEN_HEIGHT; + updateParam.renderTarget.strideInPixels = VITA_GXM_SCREEN_STRIDE; + + updateParam.renderTarget.colorSurfaceData = data->displayBufferData[data->backBufferIndex]; + updateParam.renderTarget.depthSurfaceData = data->depthBufferData; + + updateParam.displaySyncObject = (SceGxmSyncObject *)data->displayBufferSync[data->backBufferIndex]; + + sceCommonDialogUpdate(&updateParam); + +#ifdef DEBUG_RAZOR + sceGxmPadHeartbeat( + (const SceGxmColorSurface *)&data->displaySurface[data->backBufferIndex], + (SceGxmSyncObject *)data->displayBufferSync[data->backBufferIndex]); +#endif + + sceGxmDisplayQueueAddEntry( + data->displayBufferSync[data->frontBufferIndex], // OLD fb + data->displayBufferSync[data->backBufferIndex], // NEW fb + &data->displayData); + + // update buffer indices + data->frontBufferIndex = data->backBufferIndex; + data->backBufferIndex = (data->backBufferIndex + 1) % VITA_GXM_BUFFERS; + data->pool_index = 0; + + data->current_pool = (data->current_pool + 1) % 2; + return 0; +} + +static void VITA_GXM_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture) +{ + VITA_GXM_RenderData *data = (VITA_GXM_RenderData *)renderer->driverdata; + VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *)texture->driverdata; + + if (!data) { + return; + } + + if (!vita_texture) { + return; + } + + if (!vita_texture->tex) { + return; + } + + sceGxmFinish(data->gxm_context); + + free_gxm_texture(data, vita_texture->tex); + + SDL_free(vita_texture); + + texture->driverdata = NULL; +} + +static void VITA_GXM_DestroyRenderer(SDL_Renderer *renderer) +{ + VITA_GXM_RenderData *data = (VITA_GXM_RenderData *)renderer->driverdata; + if (data) { + if (!data->initialized) { + return; + } + + gxm_finish(renderer); + + data->initialized = SDL_FALSE; + data->drawing = SDL_FALSE; + SDL_free(data); + } + SDL_free(renderer); +} + +#endif /* SDL_VIDEO_RENDER_VITA_GXM */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/render/vitagxm/SDL_render_vita_gxm_memory.c b/SDL2-2.30.5/src/render/vitagxm/SDL_render_vita_gxm_memory.c new file mode 100644 index 0000000..86e3311 --- /dev/null +++ b/SDL2-2.30.5/src/render/vitagxm/SDL_render_vita_gxm_memory.c @@ -0,0 +1,179 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#if SDL_VIDEO_RENDER_VITA_GXM + +#include "SDL_render_vita_gxm_memory.h" + +void *vita_mem_alloc(unsigned int type, unsigned int size, unsigned int alignment, unsigned int attribs, SceUID *uid) +{ + void *mem; + + if (type == SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW) { + size = ALIGN(size, 256 * 1024); + } else { + size = ALIGN(size, 4 * 1024); + } + + *uid = sceKernelAllocMemBlock("gpu_mem", type, size, NULL); + + if (*uid < 0) { + return NULL; + } + + if (sceKernelGetMemBlockBase(*uid, &mem) < 0) { + return NULL; + } + + if (sceGxmMapMemory(mem, size, attribs) < 0) { + return NULL; + } + + return mem; +} + +void vita_mem_free(SceUID uid) +{ + void *mem = NULL; + if (sceKernelGetMemBlockBase(uid, &mem) < 0) { + return; + } + sceGxmUnmapMemory(mem); + sceKernelFreeMemBlock(uid); +} + +void *vita_gpu_mem_alloc(VITA_GXM_RenderData *data, unsigned int size) +{ + void *mem; + + if (!data->texturePool) { + int poolsize; + int ret; + SceKernelFreeMemorySizeInfo info; + info.size = sizeof(SceKernelFreeMemorySizeInfo); + sceKernelGetFreeMemorySize(&info); + + poolsize = ALIGN(info.size_cdram, 256 * 1024); + if (poolsize > info.size_cdram) { + poolsize = ALIGN(info.size_cdram - 256 * 1024, 256 * 1024); + } + data->texturePoolUID = sceKernelAllocMemBlock("gpu_texture_pool", SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, poolsize, NULL); + if (data->texturePoolUID < 0) { + return NULL; + } + + ret = sceKernelGetMemBlockBase(data->texturePoolUID, &mem); + if (ret < 0) { + return NULL; + } + data->texturePool = sceClibMspaceCreate(mem, poolsize); + + if (!data->texturePool) { + return NULL; + } + ret = sceGxmMapMemory(mem, poolsize, SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE); + if (ret < 0) { + return NULL; + } + } + return sceClibMspaceMemalign(data->texturePool, SCE_GXM_TEXTURE_ALIGNMENT, size); +} + +void vita_gpu_mem_free(VITA_GXM_RenderData *data, void *ptr) +{ + if (data->texturePool) { + sceClibMspaceFree(data->texturePool, ptr); + } +} + +void vita_gpu_mem_destroy(VITA_GXM_RenderData *data) +{ + void *mem = NULL; + if (data->texturePool) { + sceClibMspaceDestroy(data->texturePool); + data->texturePool = NULL; + if (sceKernelGetMemBlockBase(data->texturePoolUID, &mem) < 0) { + return; + } + sceGxmUnmapMemory(mem); + sceKernelFreeMemBlock(data->texturePoolUID); + } +} + +void *vita_mem_vertex_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset) +{ + void *mem = NULL; + + size = ALIGN(size, 4096); + *uid = sceKernelAllocMemBlock("vertex_usse", SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, size, NULL); + + if (sceKernelGetMemBlockBase(*uid, &mem) < 0) { + return NULL; + } + if (sceGxmMapVertexUsseMemory(mem, size, usse_offset) < 0) { + return NULL; + } + + return mem; +} + +void vita_mem_vertex_usse_free(SceUID uid) +{ + void *mem = NULL; + if (sceKernelGetMemBlockBase(uid, &mem) < 0) { + return; + } + sceGxmUnmapVertexUsseMemory(mem); + sceKernelFreeMemBlock(uid); +} + +void *vita_mem_fragment_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset) +{ + void *mem = NULL; + + size = ALIGN(size, 4096); + *uid = sceKernelAllocMemBlock("fragment_usse", SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, size, NULL); + + if (sceKernelGetMemBlockBase(*uid, &mem) < 0) { + return NULL; + } + if (sceGxmMapFragmentUsseMemory(mem, size, usse_offset) < 0) { + return NULL; + } + + return mem; +} + +void vita_mem_fragment_usse_free(SceUID uid) +{ + void *mem = NULL; + if (sceKernelGetMemBlockBase(uid, &mem) < 0) { + return; + } + sceGxmUnmapFragmentUsseMemory(mem); + sceKernelFreeMemBlock(uid); +} + +#endif /* SDL_VIDEO_RENDER_VITA_GXM */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/render/vitagxm/SDL_render_vita_gxm_memory.h b/SDL2-2.30.5/src/render/vitagxm/SDL_render_vita_gxm_memory.h new file mode 100644 index 0000000..1f3832e --- /dev/null +++ b/SDL2-2.30.5/src/render/vitagxm/SDL_render_vita_gxm_memory.h @@ -0,0 +1,44 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#ifndef SDL_RENDER_VITA_GXM_MEMORY_H +#define SDL_RENDER_VITA_GXM_MEMORY_H + +#include +#include +#include +#include "SDL_render_vita_gxm_types.h" + +#define ALIGN(x, a) (((x) + ((a)-1)) & ~((a)-1)) + +void *vita_mem_alloc(unsigned int type, unsigned int size, unsigned int alignment, unsigned int attribs, SceUID *uid); +void vita_mem_free(SceUID uid); +void *vita_gpu_mem_alloc(VITA_GXM_RenderData *data, unsigned int size); +void vita_gpu_mem_free(VITA_GXM_RenderData *data, void *ptr); +void vita_gpu_mem_destroy(VITA_GXM_RenderData *data); +void *vita_mem_vertex_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset); +void vita_mem_vertex_usse_free(SceUID uid); +void *vita_mem_fragment_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset); +void vita_mem_fragment_usse_free(SceUID uid); + +#endif /* SDL_RENDER_VITA_GXM_MEMORY_H */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/render/vitagxm/SDL_render_vita_gxm_shaders.h b/SDL2-2.30.5/src/render/vitagxm/SDL_render_vita_gxm_shaders.h new file mode 100644 index 0000000..d383fd8 --- /dev/null +++ b/SDL2-2.30.5/src/render/vitagxm/SDL_render_vita_gxm_shaders.h @@ -0,0 +1,284 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#ifndef SDL_RENDER_VITA_GXM_SHADERS_H +#define SDL_RENDER_VITA_GXM_SHADERS_H + +#include + +/* *INDENT-OFF* */ /* clang-format off */ + +#define gxm_shader_clear_f_size 232 +static const unsigned char gxm_shader_clear_f[gxm_shader_clear_f_size] = { + 0x47, 0x58, 0x50, 0x00, 0x01, 0x05, 0x50, 0x03, + 0xe8, 0x00, 0x00, 0x00, 0xa2, 0x55, 0x22, 0x3e, + 0xc6, 0x7e, 0x77, 0xf1, 0x01, 0x00, 0x18, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xa4, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x68, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x5c, 0x00, 0x00, 0x00, 0xc0, 0x3d, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x44, 0xfa, 0x02, 0x80, 0x19, 0xf0, + 0x7e, 0x0d, 0x80, 0x40, 0x0e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x01, 0xe4, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x75, 0x43, 0x6c, 0x65, + 0x61, 0x72, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, +}; + +#define gxm_shader_clear_v_size 252 +static const unsigned char gxm_shader_clear_v[gxm_shader_clear_v_size] = { + 0x47, 0x58, 0x50, 0x00, 0x01, 0x05, 0x50, 0x03, + 0xfa, 0x00, 0x00, 0x00, 0xdc, 0x25, 0x34, 0x74, + 0x53, 0x4a, 0x7a, 0x5b, 0x04, 0x00, 0x19, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xb8, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x74, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x78, 0x00, 0x00, 0x00, 0xc0, 0x3d, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x44, 0xfa, + 0x01, 0x00, 0x04, 0x90, 0x85, 0x11, 0xa5, 0x08, + 0x01, 0x80, 0x56, 0x90, 0x81, 0x11, 0x83, 0x08, + 0x00, 0x00, 0x20, 0xa0, 0x00, 0x50, 0x27, 0xfb, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x61, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x00, 0x00, 0x00, +}; + +#define gxm_shader_color_f_size 212 +static const unsigned char gxm_shader_color_f[gxm_shader_color_f_size] = { + 0x47, 0x58, 0x50, 0x00, 0x01, 0x05, 0x50, 0x03, + 0xd4, 0x00, 0x00, 0x00, 0x9c, 0xd6, 0x9b, 0xf7, + 0x78, 0x00, 0x5d, 0x31, 0x01, 0x10, 0x18, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xac, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x78, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x6c, 0x00, 0x00, 0x00, 0xc0, 0x3d, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, + 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x0f, 0xa0, 0xd0, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x44, 0xfa, 0x02, 0x80, 0x19, 0xa0, + 0x7e, 0x0d, 0x80, 0x40, +}; + +#define gxm_shader_color_v_size 368 +static const unsigned char gxm_shader_color_v[gxm_shader_color_v_size] = { + 0x47, 0x58, 0x50, 0x00, 0x01, 0x05, 0x50, 0x03, + 0x6d, 0x01, 0x00, 0x00, 0x09, 0xce, 0x4e, 0xc2, + 0xe1, 0xcd, 0x24, 0xbc, 0x00, 0x00, 0x19, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x98, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x74, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0xb8, 0x00, 0x00, 0x00, 0xc0, 0x3d, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x09, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x06, 0x43, 0x00, 0x61, + 0x86, 0x81, 0xa2, 0x00, 0x07, 0x53, 0x40, 0x61, + 0x86, 0x81, 0xa2, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x01, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x44, 0xfa, + 0x80, 0x00, 0x08, 0x83, 0x21, 0x1d, 0x80, 0x38, + 0x00, 0x00, 0xf0, 0x83, 0x20, 0x0d, 0x80, 0x38, + 0x0a, 0x84, 0xb9, 0xff, 0xbc, 0x0d, 0xc0, 0x40, + 0x02, 0x11, 0x45, 0xcf, 0x80, 0x8f, 0xb1, 0x18, + 0x00, 0x11, 0x01, 0xc0, 0x81, 0x81, 0xb1, 0x18, + 0x01, 0xd1, 0x42, 0xc0, 0x81, 0x81, 0xb1, 0x18, + 0x40, 0x00, 0x10, 0x41, 0x09, 0x05, 0x82, 0x38, + 0x00, 0x00, 0x20, 0xa0, 0x00, 0x50, 0x27, 0xfb, + 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2a, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x00, 0x00, 0x01, 0xe4, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x61, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x00, 0x61, 0x43, 0x6f, 0x6c, 0x6f, 0x72, + 0x00, 0x77, 0x76, 0x70, 0x00, 0x00, 0x00, 0x00, +}; + +#define gxm_shader_texture_f_size 288 +static const unsigned char gxm_shader_texture_f[gxm_shader_texture_f_size] = { + 0x47, 0x58, 0x50, 0x00, 0x01, 0x05, 0x50, 0x03, + 0x20, 0x01, 0x00, 0x00, 0xeb, 0x4f, 0xb5, 0xba, + 0x60, 0xb2, 0xd0, 0x8d, 0x05, 0x18, 0x18, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xc4, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x78, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x84, 0x00, 0x00, 0x00, 0xc0, 0x3d, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, + 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, + 0x01, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0xa9, 0xd0, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0xf0, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x44, 0xfa, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x09, 0x00, 0xf8, 0x02, 0x80, 0x99, 0xaf, + 0xbc, 0x0d, 0xc0, 0x40, 0x06, 0x82, 0xb9, 0xaf, + 0xbc, 0x0d, 0x80, 0x40, 0x7c, 0x0f, 0x04, 0x00, + 0x86, 0x47, 0xa4, 0x10, 0x30, 0x00, 0x00, 0x00, + 0x02, 0x04, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x74, 0x65, 0x78, 0x00, +}; + +#define gxm_shader_texture_v_size 400 +static const unsigned char gxm_shader_texture_v[gxm_shader_texture_v_size] = { + 0x47, 0x58, 0x50, 0x00, 0x01, 0x05, 0x50, 0x03, + 0x8f, 0x01, 0x00, 0x00, 0x60, 0x1e, 0x69, 0x97, + 0x82, 0x7e, 0x0c, 0xac, 0x00, 0x00, 0x19, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x08, 0x01, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x98, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x74, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x3d, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x33, 0x0f, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x0a, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x06, 0x43, 0x00, 0x61, + 0x86, 0x81, 0xa2, 0x00, 0x07, 0x53, 0x40, 0x61, + 0x86, 0x81, 0xa2, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x01, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x44, 0xfa, + 0x01, 0x0e, 0x01, 0x01, 0x02, 0x00, 0x10, 0xfa, + 0x80, 0x00, 0x08, 0x83, 0x21, 0x25, 0x80, 0x38, + 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x14, 0xfa, + 0x00, 0x00, 0xf0, 0x83, 0x20, 0x0d, 0x80, 0x38, + 0x0a, 0x84, 0xb9, 0xff, 0xbc, 0x0d, 0xc0, 0x40, + 0x02, 0x11, 0x45, 0xcf, 0x80, 0x8f, 0xb1, 0x18, + 0x00, 0x11, 0x01, 0xc0, 0x81, 0x81, 0xb1, 0x18, + 0x01, 0xd1, 0x42, 0xc0, 0x81, 0x81, 0xb1, 0x18, + 0x00, 0x00, 0x20, 0xa0, 0x00, 0x50, 0x27, 0xfb, + 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3a, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x34, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x2b, 0x00, 0x00, 0x00, 0x01, 0xe4, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x61, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x00, 0x61, 0x54, 0x65, 0x78, 0x63, 0x6f, + 0x6f, 0x72, 0x64, 0x00, 0x61, 0x43, 0x6f, 0x6c, + 0x6f, 0x72, 0x00, 0x77, 0x76, 0x70, 0x00, 0x00, +}; + +/* *INDENT-ON* */ /* clang-format on */ + +static const SceGxmProgram *const clearVertexProgramGxp = (const SceGxmProgram *)gxm_shader_clear_v; +static const SceGxmProgram *const clearFragmentProgramGxp = (const SceGxmProgram *)gxm_shader_clear_f; +static const SceGxmProgram *const colorVertexProgramGxp = (const SceGxmProgram *)gxm_shader_color_v; +static const SceGxmProgram *const colorFragmentProgramGxp = (const SceGxmProgram *)gxm_shader_color_f; +static const SceGxmProgram *const textureVertexProgramGxp = (const SceGxmProgram *)gxm_shader_texture_v; +static const SceGxmProgram *const textureFragmentProgramGxp = (const SceGxmProgram *)gxm_shader_texture_f; + +#endif // SDL_RENDER_VITA_GXM_SHADERS_H + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/render/vitagxm/SDL_render_vita_gxm_tools.c b/SDL2-2.30.5/src/render/vitagxm/SDL_render_vita_gxm_tools.c new file mode 100644 index 0000000..2c38441 --- /dev/null +++ b/SDL2-2.30.5/src/render/vitagxm/SDL_render_vita_gxm_tools.c @@ -0,0 +1,1217 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#if SDL_VIDEO_RENDER_VITA_GXM + +#include "SDL_hints.h" +#include "../SDL_sysrender.h" +#include "SDL_log.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "SDL_render_vita_gxm_tools.h" +#include "SDL_render_vita_gxm_types.h" +#include "SDL_render_vita_gxm_memory.h" +#include "SDL_render_vita_gxm_shaders.h" + +void init_orthographic_matrix(float *m, float left, float right, float bottom, float top, float near, float far) +{ + m[0x0] = 2.0f / (right - left); + m[0x4] = 0.0f; + m[0x8] = 0.0f; + m[0xC] = -(right + left) / (right - left); + + m[0x1] = 0.0f; + m[0x5] = 2.0f / (top - bottom); + m[0x9] = 0.0f; + m[0xD] = -(top + bottom) / (top - bottom); + + m[0x2] = 0.0f; + m[0x6] = 0.0f; + m[0xA] = -2.0f / (far - near); + m[0xE] = (far + near) / (far - near); + + m[0x3] = 0.0f; + m[0x7] = 0.0f; + m[0xB] = 0.0f; + m[0xF] = 1.0f; +} + +static void *patcher_host_alloc(void *user_data, unsigned int size) +{ + void *mem = SDL_malloc(size); + (void)user_data; + return mem; +} + +static void patcher_host_free(void *user_data, void *mem) +{ + (void)user_data; + SDL_free(mem); +} + +void *pool_malloc(VITA_GXM_RenderData *data, unsigned int size) +{ + + if ((data->pool_index + size) < VITA_GXM_POOL_SIZE) { + void *addr = (void *)((unsigned int)data->pool_addr[data->current_pool] + data->pool_index); + data->pool_index += size; + return addr; + } + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "POOL OVERFLOW\n"); + return NULL; +} + +void *pool_memalign(VITA_GXM_RenderData *data, unsigned int size, unsigned int alignment) +{ + unsigned int new_index = (data->pool_index + alignment - 1) & ~(alignment - 1); + if ((new_index + size) < VITA_GXM_POOL_SIZE) { + void *addr = (void *)((unsigned int)data->pool_addr[data->current_pool] + new_index); + data->pool_index = new_index + size; + return addr; + } + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "POOL OVERFLOW\n"); + return NULL; +} + +static int tex_format_to_bytespp(SceGxmTextureFormat format) +{ + switch (format & 0x9f000000U) { + case SCE_GXM_TEXTURE_BASE_FORMAT_U8: + case SCE_GXM_TEXTURE_BASE_FORMAT_S8: + case SCE_GXM_TEXTURE_BASE_FORMAT_P8: + case SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P2: // YUV actually uses 12 bits per pixel. UV planes bits/mem are handled elsewhere + case SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P3: + return 1; + case SCE_GXM_TEXTURE_BASE_FORMAT_U4U4U4U4: + case SCE_GXM_TEXTURE_BASE_FORMAT_U8U3U3U2: + case SCE_GXM_TEXTURE_BASE_FORMAT_U1U5U5U5: + case SCE_GXM_TEXTURE_BASE_FORMAT_U5U6U5: + case SCE_GXM_TEXTURE_BASE_FORMAT_S5S5U6: + case SCE_GXM_TEXTURE_BASE_FORMAT_U8U8: + case SCE_GXM_TEXTURE_BASE_FORMAT_S8S8: + return 2; + case SCE_GXM_TEXTURE_BASE_FORMAT_U8U8U8: + case SCE_GXM_TEXTURE_BASE_FORMAT_S8S8S8: + return 3; + case SCE_GXM_TEXTURE_BASE_FORMAT_U8U8U8U8: + case SCE_GXM_TEXTURE_BASE_FORMAT_S8S8S8S8: + case SCE_GXM_TEXTURE_BASE_FORMAT_F32: + case SCE_GXM_TEXTURE_BASE_FORMAT_U32: + case SCE_GXM_TEXTURE_BASE_FORMAT_S32: + default: + return 4; + } +} + +static void display_callback(const void *callback_data) +{ + SceDisplayFrameBuf framebuf; + const VITA_GXM_DisplayData *display_data = (const VITA_GXM_DisplayData *)callback_data; + + SDL_memset(&framebuf, 0x00, sizeof(SceDisplayFrameBuf)); + framebuf.size = sizeof(SceDisplayFrameBuf); + framebuf.base = display_data->address; + framebuf.pitch = VITA_GXM_SCREEN_STRIDE; + framebuf.pixelformat = VITA_GXM_PIXEL_FORMAT; + framebuf.width = VITA_GXM_SCREEN_WIDTH; + framebuf.height = VITA_GXM_SCREEN_HEIGHT; + sceDisplaySetFrameBuf(&framebuf, SCE_DISPLAY_SETBUF_NEXTFRAME); + + if (display_data->wait_vblank) { + sceDisplayWaitVblankStart(); + } +} + +static void free_fragment_programs(VITA_GXM_RenderData *data, fragment_programs *out) +{ + sceGxmShaderPatcherReleaseFragmentProgram(data->shaderPatcher, out->color); + sceGxmShaderPatcherReleaseFragmentProgram(data->shaderPatcher, out->texture); +} + +static void make_fragment_programs(VITA_GXM_RenderData *data, fragment_programs *out, + const SceGxmBlendInfo *blend_info) +{ + int err; + + err = sceGxmShaderPatcherCreateFragmentProgram( + data->shaderPatcher, + data->colorFragmentProgramId, + SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4, + 0, + blend_info, + colorVertexProgramGxp, + &out->color); + + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Patcher create fragment failed: %d\n", err); + return; + } + + err = sceGxmShaderPatcherCreateFragmentProgram( + data->shaderPatcher, + data->textureFragmentProgramId, + SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4, + 0, + blend_info, + textureVertexProgramGxp, + &out->texture); + + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Patcher create fragment failed: %d\n", err); + return; + } +} + +static void set_stencil_mask(VITA_GXM_RenderData *data, float x, float y, float w, float h) +{ + void *vertexDefaultBuffer; + color_vertex *vertices = (color_vertex *)pool_memalign( + data, + 4 * sizeof(color_vertex), // 4 vertices + sizeof(color_vertex)); + + vertices[0].x = x; + vertices[0].y = y; + vertices[0].color.r = 0; + vertices[0].color.g = 0; + vertices[0].color.b = 0; + vertices[0].color.a = 0; + + vertices[1].x = x + w; + vertices[1].y = y; + vertices[1].color.r = 0; + vertices[1].color.g = 0; + vertices[1].color.b = 0; + vertices[1].color.a = 0; + + vertices[2].x = x; + vertices[2].y = y + h; + vertices[2].color.r = 0; + vertices[2].color.g = 0; + vertices[2].color.b = 0; + vertices[2].color.a = 0; + + vertices[3].x = x + w; + vertices[3].y = y + h; + vertices[3].color.r = 0; + vertices[3].color.g = 0; + vertices[3].color.b = 0; + vertices[3].color.a = 0; + + data->drawstate.fragment_program = data->colorFragmentProgram; + data->drawstate.vertex_program = data->colorVertexProgram; + sceGxmSetVertexProgram(data->gxm_context, data->colorVertexProgram); + sceGxmSetFragmentProgram(data->gxm_context, data->colorFragmentProgram); + + sceGxmReserveVertexDefaultUniformBuffer(data->gxm_context, &vertexDefaultBuffer); + sceGxmSetUniformDataF(vertexDefaultBuffer, data->colorWvpParam, 0, 16, data->ortho_matrix); + + sceGxmSetVertexStream(data->gxm_context, 0, vertices); + sceGxmDraw(data->gxm_context, SCE_GXM_PRIMITIVE_TRIANGLE_STRIP, SCE_GXM_INDEX_FORMAT_U16, data->linearIndices, 4); +} + +void set_clip_rectangle(VITA_GXM_RenderData *data, int x_min, int y_min, int x_max, int y_max) +{ + if (data->drawing) { + // clear the stencil buffer to 0 + sceGxmSetFrontStencilFunc( + data->gxm_context, + SCE_GXM_STENCIL_FUNC_NEVER, + SCE_GXM_STENCIL_OP_ZERO, + SCE_GXM_STENCIL_OP_ZERO, + SCE_GXM_STENCIL_OP_ZERO, + 0xFF, + 0xFF); + + set_stencil_mask(data, 0, 0, VITA_GXM_SCREEN_WIDTH, VITA_GXM_SCREEN_HEIGHT); + + // set the stencil to 1 in the desired region + sceGxmSetFrontStencilFunc( + data->gxm_context, + SCE_GXM_STENCIL_FUNC_NEVER, + SCE_GXM_STENCIL_OP_REPLACE, + SCE_GXM_STENCIL_OP_REPLACE, + SCE_GXM_STENCIL_OP_REPLACE, + 0xFF, + 0xFF); + + set_stencil_mask(data, x_min, y_min, x_max - x_min, y_max - y_min); + + // set the stencil function to only accept pixels where the stencil is 1 + sceGxmSetFrontStencilFunc( + data->gxm_context, + SCE_GXM_STENCIL_FUNC_EQUAL, + SCE_GXM_STENCIL_OP_KEEP, + SCE_GXM_STENCIL_OP_KEEP, + SCE_GXM_STENCIL_OP_KEEP, + 0xFF, + 0xFF); + } +} + +void unset_clip_rectangle(VITA_GXM_RenderData *data) +{ + sceGxmSetFrontStencilFunc( + data->gxm_context, + SCE_GXM_STENCIL_FUNC_ALWAYS, + SCE_GXM_STENCIL_OP_KEEP, + SCE_GXM_STENCIL_OP_KEEP, + SCE_GXM_STENCIL_OP_KEEP, + 0xFF, + 0xFF); +} + +int gxm_init(SDL_Renderer *renderer) +{ + unsigned int i, x, y; + int err; + void *vdmRingBuffer; + void *vertexRingBuffer; + void *fragmentRingBuffer; + unsigned int fragmentUsseRingBufferOffset; + void *fragmentUsseRingBuffer; + unsigned int patcherVertexUsseOffset; + unsigned int patcherFragmentUsseOffset; + void *patcherBuffer; + void *patcherVertexUsse; + void *patcherFragmentUsse; + + SceGxmRenderTargetParams renderTargetParams; + SceGxmShaderPatcherParams patcherParams; + + // compute the memory footprint of the depth buffer + const unsigned int alignedWidth = ALIGN(VITA_GXM_SCREEN_WIDTH, SCE_GXM_TILE_SIZEX); + const unsigned int alignedHeight = ALIGN(VITA_GXM_SCREEN_HEIGHT, SCE_GXM_TILE_SIZEY); + + unsigned int sampleCount = alignedWidth * alignedHeight; + unsigned int depthStrideInSamples = alignedWidth; + + // set buffer sizes for this sample + const unsigned int patcherBufferSize = 64 * 1024; + const unsigned int patcherVertexUsseSize = 64 * 1024; + const unsigned int patcherFragmentUsseSize = 64 * 1024; + + // Fill SceGxmBlendInfo + static const SceGxmBlendInfo blend_info_none = { + .colorFunc = SCE_GXM_BLEND_FUNC_NONE, + .alphaFunc = SCE_GXM_BLEND_FUNC_NONE, + .colorSrc = SCE_GXM_BLEND_FACTOR_ZERO, + .colorDst = SCE_GXM_BLEND_FACTOR_ZERO, + .alphaSrc = SCE_GXM_BLEND_FACTOR_ZERO, + .alphaDst = SCE_GXM_BLEND_FACTOR_ZERO, + .colorMask = SCE_GXM_COLOR_MASK_ALL + }; + + static const SceGxmBlendInfo blend_info_blend = { + .colorFunc = SCE_GXM_BLEND_FUNC_ADD, + .alphaFunc = SCE_GXM_BLEND_FUNC_ADD, + .colorSrc = SCE_GXM_BLEND_FACTOR_SRC_ALPHA, + .colorDst = SCE_GXM_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, + .alphaSrc = SCE_GXM_BLEND_FACTOR_ONE, + .alphaDst = SCE_GXM_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, + .colorMask = SCE_GXM_COLOR_MASK_ALL + }; + + static const SceGxmBlendInfo blend_info_add = { + .colorFunc = SCE_GXM_BLEND_FUNC_ADD, + .alphaFunc = SCE_GXM_BLEND_FUNC_ADD, + .colorSrc = SCE_GXM_BLEND_FACTOR_SRC_ALPHA, + .colorDst = SCE_GXM_BLEND_FACTOR_ONE, + .alphaSrc = SCE_GXM_BLEND_FACTOR_ZERO, + .alphaDst = SCE_GXM_BLEND_FACTOR_ONE, + .colorMask = SCE_GXM_COLOR_MASK_ALL + }; + + static const SceGxmBlendInfo blend_info_mod = { + .colorFunc = SCE_GXM_BLEND_FUNC_ADD, + .alphaFunc = SCE_GXM_BLEND_FUNC_ADD, + + .colorSrc = SCE_GXM_BLEND_FACTOR_ZERO, + .colorDst = SCE_GXM_BLEND_FACTOR_SRC_COLOR, + + .alphaSrc = SCE_GXM_BLEND_FACTOR_ZERO, + .alphaDst = SCE_GXM_BLEND_FACTOR_ONE, + .colorMask = SCE_GXM_COLOR_MASK_ALL + }; + + static const SceGxmBlendInfo blend_info_mul = { + .colorFunc = SCE_GXM_BLEND_FUNC_ADD, + .alphaFunc = SCE_GXM_BLEND_FUNC_ADD, + .colorSrc = SCE_GXM_BLEND_FACTOR_DST_COLOR, + .colorDst = SCE_GXM_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, + .alphaSrc = SCE_GXM_BLEND_FACTOR_DST_ALPHA, + .alphaDst = SCE_GXM_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, + .colorMask = SCE_GXM_COLOR_MASK_ALL + }; + + VITA_GXM_RenderData *data = (VITA_GXM_RenderData *)renderer->driverdata; + + SceGxmInitializeParams initializeParams; + SDL_memset(&initializeParams, 0, sizeof(SceGxmInitializeParams)); + initializeParams.flags = 0; + initializeParams.displayQueueMaxPendingCount = VITA_GXM_PENDING_SWAPS; + initializeParams.displayQueueCallback = display_callback; + initializeParams.displayQueueCallbackDataSize = sizeof(VITA_GXM_DisplayData); + initializeParams.parameterBufferSize = SCE_GXM_DEFAULT_PARAMETER_BUFFER_SIZE; + + err = sceGxmInitialize(&initializeParams); + + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "gxm init failed: %d\n", err); + return err; + } + + // allocate ring buffer memory using default sizes + vdmRingBuffer = vita_mem_alloc( + SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, + SCE_GXM_DEFAULT_VDM_RING_BUFFER_SIZE, + 4, + SCE_GXM_MEMORY_ATTRIB_READ, + &data->vdmRingBufferUid); + + vertexRingBuffer = vita_mem_alloc( + SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, + SCE_GXM_DEFAULT_VERTEX_RING_BUFFER_SIZE, + 4, + SCE_GXM_MEMORY_ATTRIB_READ, + &data->vertexRingBufferUid); + + fragmentRingBuffer = vita_mem_alloc( + SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, + SCE_GXM_DEFAULT_FRAGMENT_RING_BUFFER_SIZE, + 4, + SCE_GXM_MEMORY_ATTRIB_READ, + &data->fragmentRingBufferUid); + + fragmentUsseRingBuffer = vita_mem_fragment_usse_alloc( + SCE_GXM_DEFAULT_FRAGMENT_USSE_RING_BUFFER_SIZE, + &data->fragmentUsseRingBufferUid, + &fragmentUsseRingBufferOffset); + + SDL_memset(&data->contextParams, 0, sizeof(SceGxmContextParams)); + data->contextParams.hostMem = SDL_malloc(SCE_GXM_MINIMUM_CONTEXT_HOST_MEM_SIZE); + data->contextParams.hostMemSize = SCE_GXM_MINIMUM_CONTEXT_HOST_MEM_SIZE; + data->contextParams.vdmRingBufferMem = vdmRingBuffer; + data->contextParams.vdmRingBufferMemSize = SCE_GXM_DEFAULT_VDM_RING_BUFFER_SIZE; + data->contextParams.vertexRingBufferMem = vertexRingBuffer; + data->contextParams.vertexRingBufferMemSize = SCE_GXM_DEFAULT_VERTEX_RING_BUFFER_SIZE; + data->contextParams.fragmentRingBufferMem = fragmentRingBuffer; + data->contextParams.fragmentRingBufferMemSize = SCE_GXM_DEFAULT_FRAGMENT_RING_BUFFER_SIZE; + data->contextParams.fragmentUsseRingBufferMem = fragmentUsseRingBuffer; + data->contextParams.fragmentUsseRingBufferMemSize = SCE_GXM_DEFAULT_FRAGMENT_USSE_RING_BUFFER_SIZE; + data->contextParams.fragmentUsseRingBufferOffset = fragmentUsseRingBufferOffset; + + err = sceGxmCreateContext(&data->contextParams, &data->gxm_context); + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "create context failed: %d\n", err); + return err; + } + + // set up parameters + SDL_memset(&renderTargetParams, 0, sizeof(SceGxmRenderTargetParams)); + renderTargetParams.flags = 0; + renderTargetParams.width = VITA_GXM_SCREEN_WIDTH; + renderTargetParams.height = VITA_GXM_SCREEN_HEIGHT; + renderTargetParams.scenesPerFrame = 1; + renderTargetParams.multisampleMode = 0; + renderTargetParams.multisampleLocations = 0; + renderTargetParams.driverMemBlock = -1; // Invalid UID + + // create the render target + err = sceGxmCreateRenderTarget(&renderTargetParams, &data->renderTarget); + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "render target creation failed: %d\n", err); + return err; + } + + // allocate memory and sync objects for display buffers + for (i = 0; i < VITA_GXM_BUFFERS; i++) { + + // allocate memory for display + data->displayBufferData[i] = vita_mem_alloc( + SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, + 4 * VITA_GXM_SCREEN_STRIDE * VITA_GXM_SCREEN_HEIGHT, + SCE_GXM_COLOR_SURFACE_ALIGNMENT, + SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE, + &data->displayBufferUid[i]); + + // SDL_memset the buffer to black + for (y = 0; y < VITA_GXM_SCREEN_HEIGHT; y++) { + unsigned int *row = (unsigned int *)data->displayBufferData[i] + y * VITA_GXM_SCREEN_STRIDE; + for (x = 0; x < VITA_GXM_SCREEN_WIDTH; x++) { + row[x] = 0xff000000; + } + } + + // initialize a color surface for this display buffer + err = sceGxmColorSurfaceInit( + &data->displaySurface[i], + VITA_GXM_COLOR_FORMAT, + SCE_GXM_COLOR_SURFACE_LINEAR, + SCE_GXM_COLOR_SURFACE_SCALE_NONE, + SCE_GXM_OUTPUT_REGISTER_SIZE_32BIT, + VITA_GXM_SCREEN_WIDTH, + VITA_GXM_SCREEN_HEIGHT, + VITA_GXM_SCREEN_STRIDE, + data->displayBufferData[i]); + + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "color surface init failed: %d\n", err); + return err; + } + + // create a sync object that we will associate with this buffer + err = sceGxmSyncObjectCreate(&data->displayBufferSync[i]); + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "sync object creation failed: %d\n", err); + return err; + } + } + + // allocate the depth buffer + data->depthBufferData = vita_mem_alloc( + SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, + 4 * sampleCount, + SCE_GXM_DEPTHSTENCIL_SURFACE_ALIGNMENT, + SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE, + &data->depthBufferUid); + + // allocate the stencil buffer + data->stencilBufferData = vita_mem_alloc( + SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, + 4 * sampleCount, + SCE_GXM_DEPTHSTENCIL_SURFACE_ALIGNMENT, + SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE, + &data->stencilBufferUid); + + // create the SceGxmDepthStencilSurface structure + err = sceGxmDepthStencilSurfaceInit( + &data->depthSurface, + SCE_GXM_DEPTH_STENCIL_FORMAT_S8D24, + SCE_GXM_DEPTH_STENCIL_SURFACE_TILED, + depthStrideInSamples, + data->depthBufferData, + data->stencilBufferData); + + // set the stencil test reference (this is currently assumed to always remain 1 after here for region clipping) + sceGxmSetFrontStencilRef(data->gxm_context, 1); + + // set the stencil function (this wouldn't actually be needed, as the set clip rectangle function has to call this at the begginning of every scene) + sceGxmSetFrontStencilFunc( + data->gxm_context, + SCE_GXM_STENCIL_FUNC_ALWAYS, + SCE_GXM_STENCIL_OP_KEEP, + SCE_GXM_STENCIL_OP_KEEP, + SCE_GXM_STENCIL_OP_KEEP, + 0xFF, + 0xFF); + + // allocate memory for buffers and USSE code + patcherBuffer = vita_mem_alloc( + SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, + patcherBufferSize, + 4, + SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE, + &data->patcherBufferUid); + + patcherVertexUsse = vita_mem_vertex_usse_alloc( + patcherVertexUsseSize, + &data->patcherVertexUsseUid, + &patcherVertexUsseOffset); + + patcherFragmentUsse = vita_mem_fragment_usse_alloc( + patcherFragmentUsseSize, + &data->patcherFragmentUsseUid, + &patcherFragmentUsseOffset); + + // create a shader patcher + SDL_memset(&patcherParams, 0, sizeof(SceGxmShaderPatcherParams)); + patcherParams.userData = NULL; + patcherParams.hostAllocCallback = &patcher_host_alloc; + patcherParams.hostFreeCallback = &patcher_host_free; + patcherParams.bufferAllocCallback = NULL; + patcherParams.bufferFreeCallback = NULL; + patcherParams.bufferMem = patcherBuffer; + patcherParams.bufferMemSize = patcherBufferSize; + patcherParams.vertexUsseAllocCallback = NULL; + patcherParams.vertexUsseFreeCallback = NULL; + patcherParams.vertexUsseMem = patcherVertexUsse; + patcherParams.vertexUsseMemSize = patcherVertexUsseSize; + patcherParams.vertexUsseOffset = patcherVertexUsseOffset; + patcherParams.fragmentUsseAllocCallback = NULL; + patcherParams.fragmentUsseFreeCallback = NULL; + patcherParams.fragmentUsseMem = patcherFragmentUsse; + patcherParams.fragmentUsseMemSize = patcherFragmentUsseSize; + patcherParams.fragmentUsseOffset = patcherFragmentUsseOffset; + + err = sceGxmShaderPatcherCreate(&patcherParams, &data->shaderPatcher); + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "shader patcher creation failed: %d\n", err); + return err; + } + + // check the shaders + err = sceGxmProgramCheck(clearVertexProgramGxp); + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "check program (clear vertex) failed: %d\n", err); + return err; + } + + err = sceGxmProgramCheck(clearFragmentProgramGxp); + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "check program (clear fragment) failed: %d\n", err); + return err; + } + + err = sceGxmProgramCheck(colorVertexProgramGxp); + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "check program (color vertex) failed: %d\n", err); + return err; + } + + err = sceGxmProgramCheck(colorFragmentProgramGxp); + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "check program (color fragment) failed: %d\n", err); + return err; + } + + err = sceGxmProgramCheck(textureVertexProgramGxp); + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "check program (texture vertex) failed: %d\n", err); + return err; + } + + err = sceGxmProgramCheck(textureFragmentProgramGxp); + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "check program (texture fragment) failed: %d\n", err); + return err; + } + + // register programs with the patcher + err = sceGxmShaderPatcherRegisterProgram(data->shaderPatcher, clearVertexProgramGxp, &data->clearVertexProgramId); + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "register program (clear vertex) failed: %d\n", err); + return err; + } + + err = sceGxmShaderPatcherRegisterProgram(data->shaderPatcher, clearFragmentProgramGxp, &data->clearFragmentProgramId); + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "register program (clear fragment) failed: %d\n", err); + return err; + } + + err = sceGxmShaderPatcherRegisterProgram(data->shaderPatcher, colorVertexProgramGxp, &data->colorVertexProgramId); + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "register program (color vertex) failed: %d\n", err); + return err; + } + + err = sceGxmShaderPatcherRegisterProgram(data->shaderPatcher, colorFragmentProgramGxp, &data->colorFragmentProgramId); + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "register program (color fragment) failed: %d\n", err); + return err; + } + + err = sceGxmShaderPatcherRegisterProgram(data->shaderPatcher, textureVertexProgramGxp, &data->textureVertexProgramId); + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "register program (texture vertex) failed: %d\n", err); + return err; + } + + err = sceGxmShaderPatcherRegisterProgram(data->shaderPatcher, textureFragmentProgramGxp, &data->textureFragmentProgramId); + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "register program (texture fragment) failed: %d\n", err); + return err; + } + + { + // get attributes by name to create vertex format bindings + const SceGxmProgramParameter *paramClearPositionAttribute = sceGxmProgramFindParameterByName(clearVertexProgramGxp, "aPosition"); + + // create clear vertex format + SceGxmVertexAttribute clearVertexAttributes[1]; + SceGxmVertexStream clearVertexStreams[1]; + clearVertexAttributes[0].streamIndex = 0; + clearVertexAttributes[0].offset = 0; + clearVertexAttributes[0].format = SCE_GXM_ATTRIBUTE_FORMAT_F32; + clearVertexAttributes[0].componentCount = 2; + clearVertexAttributes[0].regIndex = sceGxmProgramParameterGetResourceIndex(paramClearPositionAttribute); + clearVertexStreams[0].stride = sizeof(clear_vertex); + clearVertexStreams[0].indexSource = SCE_GXM_INDEX_SOURCE_INDEX_16BIT; + + // create clear programs + err = sceGxmShaderPatcherCreateVertexProgram( + data->shaderPatcher, + data->clearVertexProgramId, + clearVertexAttributes, + 1, + clearVertexStreams, + 1, + &data->clearVertexProgram); + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "create program (clear vertex) failed: %d\n", err); + return err; + } + + err = sceGxmShaderPatcherCreateFragmentProgram( + data->shaderPatcher, + data->clearFragmentProgramId, + SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4, + 0, + NULL, + clearVertexProgramGxp, + &data->clearFragmentProgram); + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "create program (clear fragment) failed: %d\n", err); + return err; + } + + // create the clear triangle vertex/index data + data->clearVertices = (clear_vertex *)vita_mem_alloc( + SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, + 3 * sizeof(clear_vertex), + 4, + SCE_GXM_MEMORY_ATTRIB_READ, + &data->clearVerticesUid); + } + + // Allocate a 64k * 2 bytes = 128 KiB buffer and store all possible + // 16-bit indices in linear ascending order, so we can use this for + // all drawing operations where we don't want to use indexing. + data->linearIndices = (uint16_t *)vita_mem_alloc( + SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, + UINT16_MAX * sizeof(uint16_t), + sizeof(uint16_t), + SCE_GXM_MEMORY_ATTRIB_READ, + &data->linearIndicesUid); + + for (i = 0; i <= UINT16_MAX; ++i) { + data->linearIndices[i] = i; + } + + data->clearVertices[0].x = -1.0f; + data->clearVertices[0].y = -1.0f; + data->clearVertices[1].x = 3.0f; + data->clearVertices[1].y = -1.0f; + data->clearVertices[2].x = -1.0f; + data->clearVertices[2].y = 3.0f; + + { + const SceGxmProgramParameter *paramColorPositionAttribute = sceGxmProgramFindParameterByName(colorVertexProgramGxp, "aPosition"); + + const SceGxmProgramParameter *paramColorColorAttribute = sceGxmProgramFindParameterByName(colorVertexProgramGxp, "aColor"); + + // create color vertex format + SceGxmVertexAttribute colorVertexAttributes[2]; + SceGxmVertexStream colorVertexStreams[1]; + /* x,y: 2 float 32 bits */ + colorVertexAttributes[0].streamIndex = 0; + colorVertexAttributes[0].offset = 0; + colorVertexAttributes[0].format = SCE_GXM_ATTRIBUTE_FORMAT_F32; + colorVertexAttributes[0].componentCount = 2; // (x, y) + colorVertexAttributes[0].regIndex = sceGxmProgramParameterGetResourceIndex(paramColorPositionAttribute); + /* color: 4 unsigned char = 32 bits */ + colorVertexAttributes[1].streamIndex = 0; + colorVertexAttributes[1].offset = 8; // (x, y) * 4 = 8 bytes + colorVertexAttributes[1].format = SCE_GXM_ATTRIBUTE_FORMAT_U8N; + colorVertexAttributes[1].componentCount = 4; // (color) + colorVertexAttributes[1].regIndex = sceGxmProgramParameterGetResourceIndex(paramColorColorAttribute); + // 16 bit (short) indices + colorVertexStreams[0].stride = sizeof(color_vertex); + colorVertexStreams[0].indexSource = SCE_GXM_INDEX_SOURCE_INDEX_16BIT; + + // create color shaders + err = sceGxmShaderPatcherCreateVertexProgram( + data->shaderPatcher, + data->colorVertexProgramId, + colorVertexAttributes, + 2, + colorVertexStreams, + 1, + &data->colorVertexProgram); + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "create program (color vertex) failed: %d\n", err); + return err; + } + } + + { + const SceGxmProgramParameter *paramTexturePositionAttribute = sceGxmProgramFindParameterByName(textureVertexProgramGxp, "aPosition"); + const SceGxmProgramParameter *paramTextureTexcoordAttribute = sceGxmProgramFindParameterByName(textureVertexProgramGxp, "aTexcoord"); + const SceGxmProgramParameter *paramTextureColorAttribute = sceGxmProgramFindParameterByName(textureVertexProgramGxp, "aColor"); + + // create texture vertex format + SceGxmVertexAttribute textureVertexAttributes[3]; + SceGxmVertexStream textureVertexStreams[1]; + /* x,y: 2 float 32 bits */ + textureVertexAttributes[0].streamIndex = 0; + textureVertexAttributes[0].offset = 0; + textureVertexAttributes[0].format = SCE_GXM_ATTRIBUTE_FORMAT_F32; + textureVertexAttributes[0].componentCount = 2; // (x, y) + textureVertexAttributes[0].regIndex = sceGxmProgramParameterGetResourceIndex(paramTexturePositionAttribute); + /* u,v: 2 floats 32 bits */ + textureVertexAttributes[1].streamIndex = 0; + textureVertexAttributes[1].offset = 8; // (x, y) * 4 = 8 bytes + textureVertexAttributes[1].format = SCE_GXM_ATTRIBUTE_FORMAT_F32; + textureVertexAttributes[1].componentCount = 2; // (u, v) + textureVertexAttributes[1].regIndex = sceGxmProgramParameterGetResourceIndex(paramTextureTexcoordAttribute); + /* r,g,b,a: 4 unsigned chars 32 bits */ + textureVertexAttributes[2].streamIndex = 0; + textureVertexAttributes[2].offset = 16; // (x, y, u, v) * 4 = 16 bytes + textureVertexAttributes[2].format = SCE_GXM_ATTRIBUTE_FORMAT_U8N; + textureVertexAttributes[2].componentCount = 4; // (r, g, b, a) + textureVertexAttributes[2].regIndex = sceGxmProgramParameterGetResourceIndex(paramTextureColorAttribute); + // 16 bit (short) indices + textureVertexStreams[0].stride = sizeof(texture_vertex); + textureVertexStreams[0].indexSource = SCE_GXM_INDEX_SOURCE_INDEX_16BIT; + + // create texture shaders + err = sceGxmShaderPatcherCreateVertexProgram( + data->shaderPatcher, + data->textureVertexProgramId, + textureVertexAttributes, + 3, + textureVertexStreams, + 1, + &data->textureVertexProgram); + if (err != 0) { + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "create program (texture vertex) failed: %x\n", err); + return err; + } + } + + // Create variations of the fragment program based on blending mode + make_fragment_programs(data, &data->blendFragmentPrograms.blend_mode_none, &blend_info_none); + make_fragment_programs(data, &data->blendFragmentPrograms.blend_mode_blend, &blend_info_blend); + make_fragment_programs(data, &data->blendFragmentPrograms.blend_mode_add, &blend_info_add); + make_fragment_programs(data, &data->blendFragmentPrograms.blend_mode_mod, &blend_info_mod); + make_fragment_programs(data, &data->blendFragmentPrograms.blend_mode_mul, &blend_info_mul); + + { + // Default to blend blending mode + fragment_programs *in = &data->blendFragmentPrograms.blend_mode_blend; + + data->colorFragmentProgram = in->color; + data->textureFragmentProgram = in->texture; + } + + // find vertex uniforms by name and cache parameter information + data->clearClearColorParam = (SceGxmProgramParameter *)sceGxmProgramFindParameterByName(clearFragmentProgramGxp, "uClearColor"); + data->colorWvpParam = (SceGxmProgramParameter *)sceGxmProgramFindParameterByName(colorVertexProgramGxp, "wvp"); + data->textureWvpParam = (SceGxmProgramParameter *)sceGxmProgramFindParameterByName(textureVertexProgramGxp, "wvp"); + + // Allocate memory for the memory pool + data->pool_addr[0] = vita_mem_alloc( + SCE_KERNEL_MEMBLOCK_TYPE_USER_RW, + VITA_GXM_POOL_SIZE, + sizeof(void *), + SCE_GXM_MEMORY_ATTRIB_READ, + &data->poolUid[0]); + + data->pool_addr[1] = vita_mem_alloc( + SCE_KERNEL_MEMBLOCK_TYPE_USER_RW, + VITA_GXM_POOL_SIZE, + sizeof(void *), + SCE_GXM_MEMORY_ATTRIB_READ, + &data->poolUid[1]); + + init_orthographic_matrix(data->ortho_matrix, 0.0f, VITA_GXM_SCREEN_WIDTH, VITA_GXM_SCREEN_HEIGHT, 0.0f, 0.0f, 1.0f); + + data->backBufferIndex = 0; + data->frontBufferIndex = 0; + data->pool_index = 0; + data->current_pool = 0; + data->currentBlendMode = SDL_BLENDMODE_BLEND; + + return 0; +} + +void gxm_finish(SDL_Renderer *renderer) +{ + VITA_GXM_RenderData *data = (VITA_GXM_RenderData *)renderer->driverdata; + + // wait until rendering is done + sceGxmFinish(data->gxm_context); + + // clean up allocations + sceGxmShaderPatcherReleaseFragmentProgram(data->shaderPatcher, data->clearFragmentProgram); + sceGxmShaderPatcherReleaseVertexProgram(data->shaderPatcher, data->clearVertexProgram); + sceGxmShaderPatcherReleaseVertexProgram(data->shaderPatcher, data->colorVertexProgram); + sceGxmShaderPatcherReleaseVertexProgram(data->shaderPatcher, data->textureVertexProgram); + + free_fragment_programs(data, &data->blendFragmentPrograms.blend_mode_none); + free_fragment_programs(data, &data->blendFragmentPrograms.blend_mode_blend); + free_fragment_programs(data, &data->blendFragmentPrograms.blend_mode_add); + free_fragment_programs(data, &data->blendFragmentPrograms.blend_mode_mod); + free_fragment_programs(data, &data->blendFragmentPrograms.blend_mode_mul); + + vita_mem_free(data->linearIndicesUid); + vita_mem_free(data->clearVerticesUid); + + // wait until display queue is finished before deallocating display buffers + sceGxmDisplayQueueFinish(); + + // clean up display queue + vita_mem_free(data->depthBufferUid); + + for (size_t i = 0; i < VITA_GXM_BUFFERS; i++) { + // clear the buffer then deallocate + SDL_memset(data->displayBufferData[i], 0, VITA_GXM_SCREEN_HEIGHT * VITA_GXM_SCREEN_STRIDE * 4); + vita_mem_free(data->displayBufferUid[i]); + + // destroy the sync object + sceGxmSyncObjectDestroy(data->displayBufferSync[i]); + } + + // Free the depth and stencil buffer + vita_mem_free(data->depthBufferUid); + vita_mem_free(data->stencilBufferUid); + + // unregister programs and destroy shader patcher + sceGxmShaderPatcherUnregisterProgram(data->shaderPatcher, data->clearFragmentProgramId); + sceGxmShaderPatcherUnregisterProgram(data->shaderPatcher, data->clearVertexProgramId); + sceGxmShaderPatcherUnregisterProgram(data->shaderPatcher, data->colorFragmentProgramId); + sceGxmShaderPatcherUnregisterProgram(data->shaderPatcher, data->colorVertexProgramId); + sceGxmShaderPatcherUnregisterProgram(data->shaderPatcher, data->textureFragmentProgramId); + sceGxmShaderPatcherUnregisterProgram(data->shaderPatcher, data->textureVertexProgramId); + + sceGxmShaderPatcherDestroy(data->shaderPatcher); + vita_mem_fragment_usse_free(data->patcherFragmentUsseUid); + vita_mem_vertex_usse_free(data->patcherVertexUsseUid); + vita_mem_free(data->patcherBufferUid); + + // destroy the render target + sceGxmDestroyRenderTarget(data->renderTarget); + + // destroy the gxm context + sceGxmDestroyContext(data->gxm_context); + vita_mem_fragment_usse_free(data->fragmentUsseRingBufferUid); + vita_mem_free(data->fragmentRingBufferUid); + vita_mem_free(data->vertexRingBufferUid); + vita_mem_free(data->vdmRingBufferUid); + SDL_free(data->contextParams.hostMem); + + vita_mem_free(data->poolUid[0]); + vita_mem_free(data->poolUid[1]); + vita_gpu_mem_destroy(data); + + // terminate libgxm + sceGxmTerminate(); +} + +// textures + +void free_gxm_texture(VITA_GXM_RenderData *data, gxm_texture *texture) +{ + if (texture) { + if (texture->gxm_rendertarget) { + sceGxmDestroyRenderTarget(texture->gxm_rendertarget); + } + if (texture->depth_UID) { + vita_mem_free(texture->depth_UID); + } + if (texture->cdram) { + vita_gpu_mem_free(data, sceGxmTextureGetData(&texture->gxm_tex)); + } else { + vita_mem_free(texture->data_UID); + } + SDL_free(texture); + } +} + +SceGxmTextureFormat +gxm_texture_get_format(const gxm_texture *texture) +{ + return sceGxmTextureGetFormat(&texture->gxm_tex); +} + +void *gxm_texture_get_datap(const gxm_texture *texture) +{ + return sceGxmTextureGetData(&texture->gxm_tex); +} + +static SceGxmColorFormat tex_format_to_color_format(SceGxmTextureFormat format) +{ + switch (format) { + case SCE_GXM_TEXTURE_FORMAT_U8U8U8U8_ARGB: + return SCE_GXM_COLOR_FORMAT_U8U8U8U8_ARGB; + case SCE_GXM_TEXTURE_FORMAT_U8U8U8_RGB: + return SCE_GXM_COLOR_FORMAT_U8U8U8_RGB; + case SCE_GXM_TEXTURE_FORMAT_U8U8U8_BGR: + return SCE_GXM_COLOR_FORMAT_U8U8U8_BGR; + case SCE_GXM_TEXTURE_FORMAT_U8U8U8U8_ABGR: + return SCE_GXM_COLOR_FORMAT_U8U8U8U8_ABGR; + case SCE_GXM_TEXTURE_FORMAT_U5U6U5_RGB: + return SCE_GXM_COLOR_FORMAT_U5U6U5_RGB; + case SCE_GXM_TEXTURE_FORMAT_U5U6U5_BGR: + return SCE_GXM_COLOR_FORMAT_U5U6U5_BGR; + default: + return SCE_GXM_COLOR_FORMAT_U8U8U8U8_ABGR; + } +} + +gxm_texture *create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, SceGxmTextureFormat format, unsigned int isRenderTarget, unsigned int *return_w, unsigned int *return_h, unsigned int *return_pitch, float *return_wscale) +{ + gxm_texture *texture = SDL_calloc(1, sizeof(gxm_texture)); + int aligned_w = ALIGN(w, 8); + int texture_w = w; + int tex_size = aligned_w * h * tex_format_to_bytespp(format); + void *texture_data; + int ret; + + *return_wscale = 1.0f; + + // SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P3/P2 based formats require width aligned to 16 + if ((format & 0x9f000000U) == SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P3 || (format & 0x9f000000U) == SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P2) { + aligned_w = ALIGN(w, 16); + texture_w = aligned_w; + tex_size = aligned_w * h * tex_format_to_bytespp(format); + *return_wscale = (float)(w) / texture_w; + // add storage for UV planes + tex_size += (((aligned_w + 1) / 2) * ((h + 1) / 2)) * 2; + } + + if (!texture) { + return NULL; + } + + *return_w = w; + *return_h = h; + *return_pitch = aligned_w * tex_format_to_bytespp(format); + + /* Allocate a GPU buffer for the texture */ + texture_data = vita_gpu_mem_alloc( + data, + tex_size); + + /* Try SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE in case we're out of VRAM */ + if (!texture_data) { + SDL_LogWarn(SDL_LOG_CATEGORY_RENDER, "CDRAM texture allocation failed\n"); + texture_data = vita_mem_alloc( + SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, + tex_size, + SCE_GXM_TEXTURE_ALIGNMENT, + SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE, + &texture->data_UID); + texture->cdram = 0; + } else { + texture->cdram = 1; + } + + if (!texture_data) { + SDL_free(texture); + return NULL; + } + + /* Clear the texture */ + SDL_memset(texture_data, 0, tex_size); + + /* Create the gxm texture */ + ret = sceGxmTextureInitLinear(&texture->gxm_tex, texture_data, format, texture_w, h, 0); + if (ret < 0) { + free_gxm_texture(data, texture); + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "texture init failed: %x\n", ret); + return NULL; + } + + if (isRenderTarget) { + void *depthBufferData; + const uint32_t alignedWidth = ALIGN(w, SCE_GXM_TILE_SIZEX); + const uint32_t alignedHeight = ALIGN(h, SCE_GXM_TILE_SIZEY); + uint32_t sampleCount = alignedWidth * alignedHeight; + uint32_t depthStrideInSamples = alignedWidth; + const uint32_t alignedColorSurfaceStride = ALIGN(w, 8); + + int err = sceGxmColorSurfaceInit( + &texture->gxm_colorsurface, + tex_format_to_color_format(format), + SCE_GXM_COLOR_SURFACE_LINEAR, + SCE_GXM_COLOR_SURFACE_SCALE_NONE, + SCE_GXM_OUTPUT_REGISTER_SIZE_32BIT, + w, + h, + alignedColorSurfaceStride, + texture_data); + + if (err < 0) { + free_gxm_texture(data, texture); + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "color surface init failed: %x\n", err); + return NULL; + } + + // allocate it + depthBufferData = vita_mem_alloc( + SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, + 4 * sampleCount, + SCE_GXM_DEPTHSTENCIL_SURFACE_ALIGNMENT, + SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE, + &texture->depth_UID); + + // create the SceGxmDepthStencilSurface structure + err = sceGxmDepthStencilSurfaceInit( + &texture->gxm_depthstencil, + SCE_GXM_DEPTH_STENCIL_FORMAT_S8D24, + SCE_GXM_DEPTH_STENCIL_SURFACE_TILED, + depthStrideInSamples, + depthBufferData, + NULL); + + if (err < 0) { + free_gxm_texture(data, texture); + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "depth stencil init failed: %x\n", err); + return NULL; + } + + { + SceGxmRenderTarget *tgt = NULL; + + // set up parameters + SceGxmRenderTargetParams renderTargetParams; + SDL_memset(&renderTargetParams, 0, sizeof(SceGxmRenderTargetParams)); + renderTargetParams.flags = 0; + renderTargetParams.width = w; + renderTargetParams.height = h; + renderTargetParams.scenesPerFrame = 1; + renderTargetParams.multisampleMode = SCE_GXM_MULTISAMPLE_NONE; + renderTargetParams.multisampleLocations = 0; + renderTargetParams.driverMemBlock = -1; + + // create the render target + err = sceGxmCreateRenderTarget(&renderTargetParams, &tgt); + + texture->gxm_rendertarget = tgt; + + if (err < 0) { + free_gxm_texture(data, texture); + SDL_LogError(SDL_LOG_CATEGORY_RENDER, "create render target failed: %x\n", err); + return NULL; + } + } + } + + return texture; +} + +void gxm_texture_set_filters(gxm_texture *texture, SceGxmTextureFilter min_filter, SceGxmTextureFilter mag_filter) +{ + sceGxmTextureSetMinFilter(&texture->gxm_tex, min_filter); + sceGxmTextureSetMagFilter(&texture->gxm_tex, mag_filter); +} + +static unsigned int back_buffer_index_for_common_dialog = 0; +static unsigned int front_buffer_index_for_common_dialog = 0; +struct +{ + VITA_GXM_DisplayData displayData; + SceGxmSyncObject *sync; + SceGxmColorSurface surf; + SceUID uid; +} buffer_for_common_dialog[VITA_GXM_BUFFERS]; + +void gxm_minimal_init_for_common_dialog(void) +{ + SceGxmInitializeParams initializeParams; + SDL_zero(initializeParams); + initializeParams.flags = 0; + initializeParams.displayQueueMaxPendingCount = VITA_GXM_PENDING_SWAPS; + initializeParams.displayQueueCallback = display_callback; + initializeParams.displayQueueCallbackDataSize = sizeof(VITA_GXM_DisplayData); + initializeParams.parameterBufferSize = SCE_GXM_DEFAULT_PARAMETER_BUFFER_SIZE; + sceGxmInitialize(&initializeParams); +} + +void gxm_minimal_term_for_common_dialog(void) +{ + sceGxmTerminate(); +} + +void gxm_init_for_common_dialog(void) +{ + for (int i = 0; i < VITA_GXM_BUFFERS; i += 1) { + buffer_for_common_dialog[i].displayData.wait_vblank = SDL_TRUE; + buffer_for_common_dialog[i].displayData.address = vita_mem_alloc( + SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, + 4 * VITA_GXM_SCREEN_STRIDE * VITA_GXM_SCREEN_HEIGHT, + SCE_GXM_COLOR_SURFACE_ALIGNMENT, + SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE, + &buffer_for_common_dialog[i].uid); + sceGxmColorSurfaceInit( + &buffer_for_common_dialog[i].surf, + VITA_GXM_PIXEL_FORMAT, + SCE_GXM_COLOR_SURFACE_LINEAR, + SCE_GXM_COLOR_SURFACE_SCALE_NONE, + SCE_GXM_OUTPUT_REGISTER_SIZE_32BIT, + VITA_GXM_SCREEN_WIDTH, + VITA_GXM_SCREEN_HEIGHT, + VITA_GXM_SCREEN_STRIDE, + buffer_for_common_dialog[i].displayData.address); + sceGxmSyncObjectCreate(&buffer_for_common_dialog[i].sync); + } + sceGxmDisplayQueueFinish(); +} + +void gxm_swap_for_common_dialog(void) +{ + SceCommonDialogUpdateParam updateParam; + SDL_zero(updateParam); + updateParam.renderTarget.colorFormat = VITA_GXM_PIXEL_FORMAT; + updateParam.renderTarget.surfaceType = SCE_GXM_COLOR_SURFACE_LINEAR; + updateParam.renderTarget.width = VITA_GXM_SCREEN_WIDTH; + updateParam.renderTarget.height = VITA_GXM_SCREEN_HEIGHT; + updateParam.renderTarget.strideInPixels = VITA_GXM_SCREEN_STRIDE; + + updateParam.renderTarget.colorSurfaceData = buffer_for_common_dialog[back_buffer_index_for_common_dialog].displayData.address; + + updateParam.displaySyncObject = buffer_for_common_dialog[back_buffer_index_for_common_dialog].sync; + SDL_memset(buffer_for_common_dialog[back_buffer_index_for_common_dialog].displayData.address, 0, 4 * VITA_GXM_SCREEN_STRIDE * VITA_GXM_SCREEN_HEIGHT); + sceCommonDialogUpdate(&updateParam); + + sceGxmDisplayQueueAddEntry(buffer_for_common_dialog[front_buffer_index_for_common_dialog].sync, buffer_for_common_dialog[back_buffer_index_for_common_dialog].sync, &buffer_for_common_dialog[back_buffer_index_for_common_dialog].displayData); + front_buffer_index_for_common_dialog = back_buffer_index_for_common_dialog; + back_buffer_index_for_common_dialog = (back_buffer_index_for_common_dialog + 1) % VITA_GXM_BUFFERS; +} + +void gxm_term_for_common_dialog(void) +{ + sceGxmDisplayQueueFinish(); + for (int i = 0; i < VITA_GXM_BUFFERS; i += 1) { + vita_mem_free(buffer_for_common_dialog[i].uid); + sceGxmSyncObjectDestroy(buffer_for_common_dialog[i].sync); + } +} + +#endif /* SDL_VIDEO_RENDER_VITA_GXM */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/render/vitagxm/SDL_render_vita_gxm_tools.h b/SDL2-2.30.5/src/render/vitagxm/SDL_render_vita_gxm_tools.h new file mode 100644 index 0000000..ca50e3f --- /dev/null +++ b/SDL2-2.30.5/src/render/vitagxm/SDL_render_vita_gxm_tools.h @@ -0,0 +1,66 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#ifndef SDL_RENDER_VITA_GXM_TOOLS_H +#define SDL_RENDER_VITA_GXM_TOOLS_H + +#include "../../SDL_internal.h" + +#include "SDL_hints.h" +#include "../SDL_sysrender.h" + +#include +#include +#include +#include +#include +#include + +#include "SDL_render_vita_gxm_types.h" + +void init_orthographic_matrix(float *m, float left, float right, float bottom, float top, float near, float far); + +void *pool_malloc(VITA_GXM_RenderData *data, unsigned int size); +void *pool_memalign(VITA_GXM_RenderData *data, unsigned int size, unsigned int alignment); + +void set_clip_rectangle(VITA_GXM_RenderData *data, int x_min, int y_min, int x_max, int y_max); +void unset_clip_rectangle(VITA_GXM_RenderData *data); + +int gxm_init(SDL_Renderer *renderer); +void gxm_finish(SDL_Renderer *renderer); + +gxm_texture *create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, SceGxmTextureFormat format, unsigned int isRenderTarget, unsigned int *return_w, unsigned int *return_h, unsigned int *return_pitch, float *return_wscale); +void free_gxm_texture(VITA_GXM_RenderData *data, gxm_texture *texture); + +void gxm_texture_set_filters(gxm_texture *texture, SceGxmTextureFilter min_filter, SceGxmTextureFilter mag_filter); +SceGxmTextureFormat gxm_texture_get_format(const gxm_texture *texture); + +void *gxm_texture_get_datap(const gxm_texture *texture); + +void gxm_minimal_init_for_common_dialog(void); +void gxm_minimal_term_for_common_dialog(void); +void gxm_init_for_common_dialog(void); +void gxm_swap_for_common_dialog(void); +void gxm_term_for_common_dialog(void); + +#endif /* SDL_RENDER_VITA_GXM_TOOLS_H */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/render/vitagxm/SDL_render_vita_gxm_types.h b/SDL2-2.30.5/src/render/vitagxm/SDL_render_vita_gxm_types.h new file mode 100644 index 0000000..4255247 --- /dev/null +++ b/SDL2-2.30.5/src/render/vitagxm/SDL_render_vita_gxm_types.h @@ -0,0 +1,214 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#ifndef SDL_RENDER_VITA_GXM_TYPES_H +#define SDL_RENDER_VITA_GXM_TYPES_H + +#include "../../SDL_internal.h" + +#include "SDL_hints.h" +#include "../SDL_sysrender.h" + +#include +#include +#include +#include +#include +#include +#include + +#include + +#define VITA_GXM_SCREEN_WIDTH 960 +#define VITA_GXM_SCREEN_HEIGHT 544 +#define VITA_GXM_SCREEN_STRIDE 960 + +#define VITA_GXM_COLOR_FORMAT SCE_GXM_COLOR_FORMAT_A8B8G8R8 +#define VITA_GXM_PIXEL_FORMAT SCE_DISPLAY_PIXELFORMAT_A8B8G8R8 + +#define VITA_GXM_BUFFERS 3 +#define VITA_GXM_PENDING_SWAPS 2 +#define VITA_GXM_POOL_SIZE 2 * 1024 * 1024 + +typedef struct +{ + void *address; + Uint8 wait_vblank; +} VITA_GXM_DisplayData; + +typedef struct clear_vertex +{ + float x; + float y; +} clear_vertex; + +typedef struct color_vertex +{ + float x; + float y; + SDL_Color color; +} color_vertex; + +typedef struct texture_vertex +{ + float x; + float y; + float u; + float v; + SDL_Color color; +} texture_vertex; + +typedef struct gxm_texture +{ + SceGxmTexture gxm_tex; + SceUID data_UID; + SceGxmRenderTarget *gxm_rendertarget; + SceGxmColorSurface gxm_colorsurface; + SceGxmDepthStencilSurface gxm_depthstencil; + SceUID depth_UID; + SDL_bool cdram; +} gxm_texture; + +typedef struct fragment_programs +{ + SceGxmFragmentProgram *color; + SceGxmFragmentProgram *texture; +} fragment_programs; + +typedef struct blend_fragment_programs +{ + fragment_programs blend_mode_none; + fragment_programs blend_mode_blend; + fragment_programs blend_mode_add; + fragment_programs blend_mode_mod; + fragment_programs blend_mode_mul; +} blend_fragment_programs; + +typedef struct +{ + SDL_Rect viewport; + SDL_bool viewport_dirty; + SDL_Texture *texture; + SDL_Texture *target; + SDL_Color color; + SceGxmFragmentProgram *fragment_program; + SceGxmVertexProgram *vertex_program; + int last_command; + + SDL_bool cliprect_enabled_dirty; + SDL_bool cliprect_enabled; + SDL_bool cliprect_dirty; + SDL_Rect cliprect; + SDL_bool texturing; + SDL_Color clear_color; + int drawablew; + int drawableh; +} gxm_drawstate_cache; + +typedef struct +{ + SDL_bool initialized; + SDL_bool drawing; + + unsigned int psm; + unsigned int bpp; + + int currentBlendMode; + + VITA_GXM_DisplayData displayData; + + SceUID vdmRingBufferUid; + SceUID vertexRingBufferUid; + SceUID fragmentRingBufferUid; + SceUID fragmentUsseRingBufferUid; + SceGxmContextParams contextParams; + SceGxmContext *gxm_context; + SceGxmRenderTarget *renderTarget; + SceUID displayBufferUid[VITA_GXM_BUFFERS]; + void *displayBufferData[VITA_GXM_BUFFERS]; + SceGxmColorSurface displaySurface[VITA_GXM_BUFFERS]; + SceGxmSyncObject *displayBufferSync[VITA_GXM_BUFFERS]; + + SceUID depthBufferUid; + SceUID stencilBufferUid; + SceGxmDepthStencilSurface depthSurface; + void *depthBufferData; + void *stencilBufferData; + + unsigned int backBufferIndex; + unsigned int frontBufferIndex; + + void *pool_addr[2]; + SceUID poolUid[2]; + unsigned int pool_index; + unsigned int current_pool; + + float ortho_matrix[4 * 4]; + + SceGxmVertexProgram *colorVertexProgram; + SceGxmFragmentProgram *colorFragmentProgram; + SceGxmVertexProgram *textureVertexProgram; + SceGxmFragmentProgram *textureFragmentProgram; + SceGxmProgramParameter *clearClearColorParam; + SceGxmProgramParameter *colorWvpParam; + SceGxmProgramParameter *textureWvpParam; + + SceGxmShaderPatcher *shaderPatcher; + SceGxmVertexProgram *clearVertexProgram; + SceGxmFragmentProgram *clearFragmentProgram; + + SceGxmShaderPatcherId clearVertexProgramId; + SceGxmShaderPatcherId clearFragmentProgramId; + SceGxmShaderPatcherId colorVertexProgramId; + SceGxmShaderPatcherId colorFragmentProgramId; + SceGxmShaderPatcherId textureVertexProgramId; + SceGxmShaderPatcherId textureFragmentProgramId; + + SceUID patcherBufferUid; + SceUID patcherVertexUsseUid; + SceUID patcherFragmentUsseUid; + + SceUID clearVerticesUid; + SceUID linearIndicesUid; + clear_vertex *clearVertices; + uint16_t *linearIndices; + + blend_fragment_programs blendFragmentPrograms; + + gxm_drawstate_cache drawstate; + SceClibMspace texturePool; + SceUID texturePoolUID; +} VITA_GXM_RenderData; + +typedef struct +{ + gxm_texture *tex; + unsigned int pitch; + unsigned int w; + unsigned int h; + float wscale; + SDL_bool yuv; + SDL_bool nv12; +} VITA_GXM_TextureData; + +#endif /* SDL_RENDER_VITA_GXM_TYPES_H */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/render/vitagxm/shader_src/clear_f.cg b/SDL2-2.30.5/src/render/vitagxm/shader_src/clear_f.cg new file mode 100644 index 0000000..6d8fb3b --- /dev/null +++ b/SDL2-2.30.5/src/render/vitagxm/shader_src/clear_f.cg @@ -0,0 +1,4 @@ +float4 main( uniform float4 uClearColor) : COLOR +{ + return uClearColor; +} diff --git a/SDL2-2.30.5/src/render/vitagxm/shader_src/clear_v.cg b/SDL2-2.30.5/src/render/vitagxm/shader_src/clear_v.cg new file mode 100644 index 0000000..ee5aa9f --- /dev/null +++ b/SDL2-2.30.5/src/render/vitagxm/shader_src/clear_v.cg @@ -0,0 +1,4 @@ +float4 main(float2 aPosition) : POSITION +{ + return float4(aPosition, 1.f, 1.f); +} diff --git a/SDL2-2.30.5/src/render/vitagxm/shader_src/color_f.cg b/SDL2-2.30.5/src/render/vitagxm/shader_src/color_f.cg new file mode 100644 index 0000000..dc87c2a --- /dev/null +++ b/SDL2-2.30.5/src/render/vitagxm/shader_src/color_f.cg @@ -0,0 +1,4 @@ +float4 main(float4 vColor : COLOR) +{ + return vColor; +} diff --git a/SDL2-2.30.5/src/render/vitagxm/shader_src/color_v.cg b/SDL2-2.30.5/src/render/vitagxm/shader_src/color_v.cg new file mode 100644 index 0000000..4966099 --- /dev/null +++ b/SDL2-2.30.5/src/render/vitagxm/shader_src/color_v.cg @@ -0,0 +1,13 @@ +void main( + float2 aPosition, + float4 aColor, + uniform float4x4 wvp, + out float4 vPosition : POSITION, + out float4 vColor : COLOR, + out float pSize : PSIZE +) +{ + vPosition = mul(float4(aPosition, 1.f, 0.5f), wvp); + vColor = aColor; + pSize = 1.f; +} diff --git a/SDL2-2.30.5/src/render/vitagxm/shader_src/texture_f.cg b/SDL2-2.30.5/src/render/vitagxm/shader_src/texture_f.cg new file mode 100644 index 0000000..a1f63b8 --- /dev/null +++ b/SDL2-2.30.5/src/render/vitagxm/shader_src/texture_f.cg @@ -0,0 +1,4 @@ +float4 main(float2 vTexcoord : TEXCOORD0, float4 vColor : COLOR, uniform sampler2D tex) +{ + return tex2D(tex, vTexcoord) * vColor; +} diff --git a/SDL2-2.30.5/src/render/vitagxm/shader_src/texture_v.cg b/SDL2-2.30.5/src/render/vitagxm/shader_src/texture_v.cg new file mode 100644 index 0000000..9e05e9a --- /dev/null +++ b/SDL2-2.30.5/src/render/vitagxm/shader_src/texture_v.cg @@ -0,0 +1,14 @@ +void main( + float2 aPosition, + float2 aTexcoord, + float4 aColor, + uniform float4x4 wvp, + out float4 vPosition : POSITION, + out float4 vColor : COLOR, + out float2 vTexcoord : TEXCOORD0 +) +{ + vPosition = mul(float4(aPosition, 1.f, 0.5f), wvp); + vTexcoord = aTexcoord; + vColor = aColor; +} diff --git a/SDL2-2.0.12/src/sensor/SDL_sensor.c b/SDL2-2.30.5/src/sensor/SDL_sensor.c similarity index 80% rename from SDL2-2.0.12/src/sensor/SDL_sensor.c rename to SDL2-2.30.5/src/sensor/SDL_sensor.c index 68c3b1f..3179f73 100644 --- a/SDL2-2.0.12/src/sensor/SDL_sensor.c +++ b/SDL2-2.30.5/src/sensor/SDL_sensor.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,9 +26,8 @@ #include "SDL_atomic.h" #include "SDL_events.h" #include "SDL_syssensor.h" -#include "SDL_assert.h" -#if !SDL_EVENTS_DISABLED +#ifndef SDL_EVENTS_DISABLED #include "../events/SDL_events_c.h" #endif @@ -39,43 +38,44 @@ static SDL_SensorDriver *SDL_sensor_drivers[] = { #ifdef SDL_SENSOR_COREMOTION &SDL_COREMOTION_SensorDriver, #endif +#ifdef SDL_SENSOR_WINDOWS + &SDL_WINDOWS_SensorDriver, +#endif +#ifdef SDL_SENSOR_VITA + &SDL_VITA_SensorDriver, +#endif +#ifdef SDL_SENSOR_N3DS + &SDL_N3DS_SensorDriver, +#endif #if defined(SDL_SENSOR_DUMMY) || defined(SDL_SENSOR_DISABLED) &SDL_DUMMY_SensorDriver #endif }; -static SDL_Sensor *SDL_sensors = NULL; -static SDL_bool SDL_updating_sensor = SDL_FALSE; static SDL_mutex *SDL_sensor_lock = NULL; /* This needs to support recursive locks */ -static SDL_atomic_t SDL_next_sensor_instance_id; +static SDL_Sensor *SDL_sensors SDL_GUARDED_BY(SDL_sensor_lock) = NULL; +static SDL_atomic_t SDL_next_sensor_instance_id SDL_GUARDED_BY(SDL_sensor_lock); +static SDL_bool SDL_updating_sensor SDL_GUARDED_BY(SDL_sensor_lock) = SDL_FALSE; -static void -SDL_LockSensors(void) +void SDL_LockSensors(void) SDL_ACQUIRE(SDL_sensor_lock) { - if (SDL_sensor_lock) { - SDL_LockMutex(SDL_sensor_lock); - } + SDL_LockMutex(SDL_sensor_lock); } -static void -SDL_UnlockSensors(void) +void SDL_UnlockSensors(void) SDL_RELEASE(SDL_sensor_lock) { - if (SDL_sensor_lock) { - SDL_UnlockMutex(SDL_sensor_lock); - } + SDL_UnlockMutex(SDL_sensor_lock); } - -int -SDL_SensorInit(void) +int SDL_SensorInit(void) { int i, status; /* Create the sensor list lock */ - if (!SDL_sensor_lock) { + if (SDL_sensor_lock == NULL) { SDL_sensor_lock = SDL_CreateMutex(); } -#if !SDL_EVENTS_DISABLED +#ifndef SDL_EVENTS_DISABLED if (SDL_InitSubSystem(SDL_INIT_EVENTS) < 0) { return -1; } @@ -93,8 +93,7 @@ SDL_SensorInit(void) /* * Count the number of sensors attached to the system */ -int -SDL_NumSensors(void) +int SDL_NumSensors(void) { int i, total_sensors = 0; SDL_LockSensors(); @@ -109,7 +108,7 @@ SDL_NumSensors(void) * Return the next available sensor instance ID * This may be called by drivers from multiple threads, unprotected by any locks */ -SDL_SensorID SDL_GetNextSensorInstanceID() +SDL_SensorID SDL_GetNextSensorInstanceID(void) { return SDL_AtomicIncRef(&SDL_next_sensor_instance_id); } @@ -118,8 +117,7 @@ SDL_SensorID SDL_GetNextSensorInstanceID() * Get the driver and device index for an API device index * This should be called while the sensor lock is held, to prevent another thread from updating the list */ -static SDL_bool -SDL_GetDriverAndSensorIndex(int device_index, SDL_SensorDriver **driver, int *driver_index) +static SDL_bool SDL_GetDriverAndSensorIndex(int device_index, SDL_SensorDriver **driver, int *driver_index) { int i, num_sensors, total_sensors = 0; @@ -143,8 +141,7 @@ SDL_GetDriverAndSensorIndex(int device_index, SDL_SensorDriver **driver, int *dr /* * Get the implementation dependent name of a sensor */ -const char * -SDL_SensorGetDeviceName(int device_index) +const char *SDL_SensorGetDeviceName(int device_index) { SDL_SensorDriver *driver; const char *name = NULL; @@ -159,8 +156,7 @@ SDL_SensorGetDeviceName(int device_index) return name; } -SDL_SensorType -SDL_SensorGetDeviceType(int device_index) +SDL_SensorType SDL_SensorGetDeviceType(int device_index) { SDL_SensorDriver *driver; SDL_SensorType type = SDL_SENSOR_INVALID; @@ -174,8 +170,7 @@ SDL_SensorGetDeviceType(int device_index) return type; } -SDL_SensorType -SDL_SensorGetDeviceNonPortableType(int device_index) +int SDL_SensorGetDeviceNonPortableType(int device_index) { SDL_SensorDriver *driver; int type = -1; @@ -189,8 +184,7 @@ SDL_SensorGetDeviceNonPortableType(int device_index) return type; } -SDL_SensorID -SDL_SensorGetDeviceInstanceID(int device_index) +SDL_SensorID SDL_SensorGetDeviceInstanceID(int device_index) { SDL_SensorDriver *driver; SDL_SensorID instance_id = -1; @@ -211,8 +205,7 @@ SDL_SensorGetDeviceInstanceID(int device_index) * * This function returns a sensor identifier, or NULL if an error occurred. */ -SDL_Sensor * -SDL_SensorOpen(int device_index) +SDL_Sensor *SDL_SensorOpen(int device_index) { SDL_SensorDriver *driver; SDL_SensorID instance_id; @@ -234,17 +227,17 @@ SDL_SensorOpen(int device_index) instance_id = driver->GetDeviceInstanceID(device_index); while (sensorlist) { if (instance_id == sensorlist->instance_id) { - sensor = sensorlist; - ++sensor->ref_count; - SDL_UnlockSensors(); - return sensor; + sensor = sensorlist; + ++sensor->ref_count; + SDL_UnlockSensors(); + return sensor; } sensorlist = sensorlist->next; } /* Create and initialize the sensor */ - sensor = (SDL_Sensor *) SDL_calloc(sizeof(*sensor), 1); - if (sensor == NULL) { + sensor = (SDL_Sensor *)SDL_calloc(sizeof(*sensor), 1); + if (!sensor) { SDL_OutOfMemory(); SDL_UnlockSensors(); return NULL; @@ -283,8 +276,7 @@ SDL_SensorOpen(int device_index) /* * Find the SDL_Sensor that owns this instance id */ -SDL_Sensor * -SDL_SensorFromInstanceID(SDL_SensorID instance_id) +SDL_Sensor *SDL_SensorFromInstanceID(SDL_SensorID instance_id) { SDL_Sensor *sensor; @@ -301,12 +293,11 @@ SDL_SensorFromInstanceID(SDL_SensorID instance_id) /* * Checks to make sure the sensor is valid. */ -static int -SDL_PrivateSensorValid(SDL_Sensor * sensor) +static int SDL_PrivateSensorValid(SDL_Sensor *sensor) { int valid; - if (sensor == NULL) { + if (!sensor) { SDL_SetError("Sensor hasn't been opened yet"); valid = 0; } else { @@ -319,8 +310,7 @@ SDL_PrivateSensorValid(SDL_Sensor * sensor) /* * Get the friendly name of this sensor */ -const char * -SDL_SensorGetName(SDL_Sensor * sensor) +const char *SDL_SensorGetName(SDL_Sensor *sensor) { if (!SDL_PrivateSensorValid(sensor)) { return NULL; @@ -332,8 +322,7 @@ SDL_SensorGetName(SDL_Sensor * sensor) /* * Get the type of this sensor */ -SDL_SensorType -SDL_SensorGetType(SDL_Sensor * sensor) +SDL_SensorType SDL_SensorGetType(SDL_Sensor *sensor) { if (!SDL_PrivateSensorValid(sensor)) { return SDL_SENSOR_INVALID; @@ -345,8 +334,7 @@ SDL_SensorGetType(SDL_Sensor * sensor) /* * Get the platform dependent type of this sensor */ -int -SDL_SensorGetNonPortableType(SDL_Sensor * sensor) +int SDL_SensorGetNonPortableType(SDL_Sensor *sensor) { if (!SDL_PrivateSensorValid(sensor)) { return -1; @@ -358,8 +346,7 @@ SDL_SensorGetNonPortableType(SDL_Sensor * sensor) /* * Get the instance id for this opened sensor */ -SDL_SensorID -SDL_SensorGetInstanceID(SDL_Sensor * sensor) +SDL_SensorID SDL_SensorGetInstanceID(SDL_Sensor *sensor) { if (!SDL_PrivateSensorValid(sensor)) { return -1; @@ -371,23 +358,32 @@ SDL_SensorGetInstanceID(SDL_Sensor * sensor) /* * Get the current state of this sensor */ -int -SDL_SensorGetData(SDL_Sensor * sensor, float *data, int num_values) +int SDL_SensorGetData(SDL_Sensor *sensor, float *data, int num_values) +{ + return SDL_SensorGetDataWithTimestamp(sensor, NULL, data, num_values); +} + +/* + * Get the current state of this sensor + */ +int SDL_SensorGetDataWithTimestamp(SDL_Sensor *sensor, Uint64 *timestamp, float *data, int num_values) { if (!SDL_PrivateSensorValid(sensor)) { return -1; } num_values = SDL_min(num_values, SDL_arraysize(sensor->data)); - SDL_memcpy(data, sensor->data, num_values*sizeof(*data)); + SDL_memcpy(data, sensor->data, num_values * sizeof(*data)); + if (timestamp) { + *timestamp = sensor->timestamp_us; + } return 0; } /* * Close a sensor previously opened with SDL_SensorOpen() */ -void -SDL_SensorClose(SDL_Sensor * sensor) +void SDL_SensorClose(SDL_Sensor *sensor) { SDL_Sensor *sensorlist; SDL_Sensor *sensorlistprev; @@ -436,16 +432,15 @@ SDL_SensorClose(SDL_Sensor * sensor) SDL_UnlockSensors(); } -void -SDL_SensorQuit(void) +void SDL_SensorQuit(void) { int i; + SDL_LockSensors(); + /* Make sure we're not getting called in the middle of updating sensors */ SDL_assert(!SDL_updating_sensor); - SDL_LockSensors(); - /* Stop the event polling */ while (SDL_sensors) { SDL_sensors->ref_count = 1; @@ -454,12 +449,12 @@ SDL_SensorQuit(void) /* Quit the sensor setup */ for (i = 0; i < SDL_arraysize(SDL_sensor_drivers); ++i) { - SDL_sensor_drivers[i]->Quit(); + SDL_sensor_drivers[i]->Quit(); } SDL_UnlockSensors(); -#if !SDL_EVENTS_DISABLED +#ifndef SDL_EVENTS_DISABLED SDL_QuitSubSystem(SDL_INIT_EVENTS); #endif @@ -469,11 +464,9 @@ SDL_SensorQuit(void) } } - /* These are global for SDL_syssensor.c and SDL_events.c */ -int -SDL_PrivateSensorUpdate(SDL_Sensor *sensor, float *data, int num_values) +int SDL_PrivateSensorUpdate(SDL_Sensor *sensor, Uint64 timestamp_us, float *data, int num_values) { int posted; @@ -481,26 +474,27 @@ SDL_PrivateSensorUpdate(SDL_Sensor *sensor, float *data, int num_values) /* Update internal sensor state */ num_values = SDL_min(num_values, SDL_arraysize(sensor->data)); - SDL_memcpy(sensor->data, data, num_values*sizeof(*data)); + SDL_memcpy(sensor->data, data, num_values * sizeof(*data)); + sensor->timestamp_us = timestamp_us; /* Post the event, if desired */ posted = 0; -#if !SDL_EVENTS_DISABLED +#ifndef SDL_EVENTS_DISABLED if (SDL_GetEventState(SDL_SENSORUPDATE) == SDL_ENABLE) { SDL_Event event; event.type = SDL_SENSORUPDATE; event.sensor.which = sensor->instance_id; num_values = SDL_min(num_values, SDL_arraysize(event.sensor.data)); SDL_memset(event.sensor.data, 0, sizeof(event.sensor.data)); - SDL_memcpy(event.sensor.data, data, num_values*sizeof(*data)); + SDL_memcpy(event.sensor.data, data, num_values * sizeof(*data)); + event.sensor.timestamp_us = timestamp_us; posted = SDL_PushEvent(&event) == 1; } #endif /* !SDL_EVENTS_DISABLED */ return posted; } -void -SDL_SensorUpdate(void) +void SDL_SensorUpdate(void) { int i; SDL_Sensor *sensor, *next; @@ -519,15 +513,10 @@ SDL_SensorUpdate(void) SDL_updating_sensor = SDL_TRUE; - /* Make sure the list is unlocked while dispatching events to prevent application deadlocks */ - SDL_UnlockSensors(); - for (sensor = SDL_sensors; sensor; sensor = sensor->next) { sensor->driver->Update(sensor); } - SDL_LockSensors(); - SDL_updating_sensor = SDL_FALSE; /* If any sensors were closed while updating, free them here */ diff --git a/SDL2-2.0.12/src/sensor/SDL_sensor_c.h b/SDL2-2.30.5/src/sensor/SDL_sensor_c.h similarity index 89% rename from SDL2-2.0.12/src/sensor/SDL_sensor_c.h rename to SDL2-2.30.5/src/sensor/SDL_sensor_c.h index a66e858..0d2a483 100644 --- a/SDL2-2.0.12/src/sensor/SDL_sensor_c.h +++ b/SDL2-2.30.5/src/sensor/SDL_sensor_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -37,7 +37,7 @@ extern int SDL_SensorInit(void); extern void SDL_SensorQuit(void); /* Internal event queueing functions */ -extern int SDL_PrivateSensorUpdate(SDL_Sensor *sensor, float *data, int num_values); +extern int SDL_PrivateSensorUpdate(SDL_Sensor *sensor, Uint64 timestamp_us, float *data, int num_values); #endif /* SDL_sensor_c_h_ */ diff --git a/SDL2-2.0.12/src/sensor/SDL_syssensor.h b/SDL2-2.30.5/src/sensor/SDL_syssensor.h similarity index 74% rename from SDL2-2.0.12/src/sensor/SDL_syssensor.h rename to SDL2-2.30.5/src/sensor/SDL_syssensor.h index 394c68b..8f8196f 100644 --- a/SDL2-2.0.12/src/sensor/SDL_syssensor.h +++ b/SDL2-2.30.5/src/sensor/SDL_syssensor.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -32,20 +32,21 @@ /* The SDL sensor structure */ struct _SDL_Sensor { - SDL_SensorID instance_id; /* Device instance, monotonically increasing from 0 */ - char *name; /* Sensor name - system dependent */ - SDL_SensorType type; /* Type of the sensor */ - int non_portable_type; /* Platform dependent type of the sensor */ + SDL_SensorID instance_id; /* Device instance, monotonically increasing from 0 */ + char *name; /* Sensor name - system dependent */ + SDL_SensorType type; /* Type of the sensor */ + int non_portable_type; /* Platform dependent type of the sensor */ - float data[16]; /* The current state of the sensor */ + Uint64 timestamp_us; /* The timestamp of the last sensor update */ + float data[16]; /* The current state of the sensor */ struct _SDL_SensorDriver *driver; - struct sensor_hwdata *hwdata; /* Driver dependent information */ + struct sensor_hwdata *hwdata; /* Driver dependent information */ - int ref_count; /* Reference count for multiple opens */ + int ref_count; /* Reference count for multiple opens */ - struct _SDL_Sensor *next; /* pointer to next sensor we have allocated */ + struct _SDL_Sensor *next; /* pointer to next sensor we have allocated */ }; typedef struct _SDL_SensorDriver @@ -78,17 +79,17 @@ typedef struct _SDL_SensorDriver The sensor to open is specified by the device index. It returns 0, or -1 if there is an error. */ - int (*Open)(SDL_Sensor * sensor, int device_index); + int (*Open)(SDL_Sensor *sensor, int device_index); /* Function to update the state of a sensor - called as a device poll. * This function shouldn't update the sensor structure directly, * but instead should call SDL_PrivateSensorUpdate() to deliver events * and update sensor device state. */ - void (*Update)(SDL_Sensor * sensor); + void (*Update)(SDL_Sensor *sensor); /* Function to close a sensor after use */ - void (*Close)(SDL_Sensor * sensor); + void (*Close)(SDL_Sensor *sensor); /* Function to perform any system-specific sensor related cleanup */ void (*Quit)(void); @@ -98,8 +99,11 @@ typedef struct _SDL_SensorDriver /* The available sensor drivers */ extern SDL_SensorDriver SDL_ANDROID_SensorDriver; extern SDL_SensorDriver SDL_COREMOTION_SensorDriver; +extern SDL_SensorDriver SDL_WINDOWS_SensorDriver; extern SDL_SensorDriver SDL_DUMMY_SensorDriver; +extern SDL_SensorDriver SDL_VITA_SensorDriver; +extern SDL_SensorDriver SDL_N3DS_SensorDriver; -#endif /* SDL_syssensor_c_h_ */ +#endif /* SDL_syssensor_h_ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/sensor/android/SDL_androidsensor.c b/SDL2-2.30.5/src/sensor/android/SDL_androidsensor.c similarity index 75% rename from SDL2-2.0.12/src/sensor/android/SDL_androidsensor.c rename to SDL2-2.30.5/src/sensor/android/SDL_androidsensor.c index d7c0a7e..3f57253 100644 --- a/SDL2-2.0.12/src/sensor/android/SDL_androidsensor.c +++ b/SDL2-2.30.5/src/sensor/android/SDL_androidsensor.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -18,6 +18,7 @@ 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_config.h" @@ -31,10 +32,9 @@ #include "SDL_androidsensor.h" #include "../SDL_syssensor.h" #include "../SDL_sensor_c.h" -//#include "../../core/android/SDL_android.h" #ifndef LOOPER_ID_USER -#define LOOPER_ID_USER 3 +#define LOOPER_ID_USER 3 #endif typedef struct @@ -43,13 +43,12 @@ typedef struct SDL_SensorID instance_id; } SDL_AndroidSensor; -static ASensorManager* SDL_sensor_manager; -static ALooper* SDL_sensor_looper; +static ASensorManager *SDL_sensor_manager; +static ALooper *SDL_sensor_looper; static SDL_AndroidSensor *SDL_sensors; static int SDL_sensors_count; -static int -SDL_ANDROID_SensorInit(void) +static int SDL_ANDROID_SensorInit(void) { int i, sensors_count; ASensorList sensors; @@ -84,25 +83,21 @@ SDL_ANDROID_SensorInit(void) return 0; } -static int -SDL_ANDROID_SensorGetCount(void) +static int SDL_ANDROID_SensorGetCount(void) { return SDL_sensors_count; } -static void -SDL_ANDROID_SensorDetect(void) +static void SDL_ANDROID_SensorDetect(void) { } -static const char * -SDL_ANDROID_SensorGetDeviceName(int device_index) +static const char *SDL_ANDROID_SensorGetDeviceName(int device_index) { return ASensor_getName(SDL_sensors[device_index].asensor); } -static SDL_SensorType -SDL_ANDROID_SensorGetDeviceType(int device_index) +static SDL_SensorType SDL_ANDROID_SensorGetDeviceType(int device_index) { switch (ASensor_getType(SDL_sensors[device_index].asensor)) { case 0x00000001: @@ -114,25 +109,23 @@ SDL_ANDROID_SensorGetDeviceType(int device_index) } } -static int -SDL_ANDROID_SensorGetDeviceNonPortableType(int device_index) +static int SDL_ANDROID_SensorGetDeviceNonPortableType(int device_index) { return ASensor_getType(SDL_sensors[device_index].asensor); } -static SDL_SensorID -SDL_ANDROID_SensorGetDeviceInstanceID(int device_index) +static SDL_SensorID SDL_ANDROID_SensorGetDeviceInstanceID(int device_index) { return SDL_sensors[device_index].instance_id; } -static int -SDL_ANDROID_SensorOpen(SDL_Sensor *sensor, int device_index) +static int SDL_ANDROID_SensorOpen(SDL_Sensor *sensor, int device_index) { struct sensor_hwdata *hwdata; + int delay_us, min_delay_us; hwdata = (struct sensor_hwdata *)SDL_calloc(1, sizeof(*hwdata)); - if (hwdata == NULL) { + if (!hwdata) { return SDL_OutOfMemory(); } @@ -149,29 +142,34 @@ SDL_ANDROID_SensorOpen(SDL_Sensor *sensor, int device_index) return SDL_SetError("Couldn't enable sensor"); } - /* FIXME: What rate should we set for this sensor? 60 FPS? Let's try the default rate for now... */ + /* Use 60 Hz update rate if possible */ + /* FIXME: Maybe add a hint for this? */ + delay_us = 1000000 / 60; + min_delay_us = ASensor_getMinDelay(hwdata->asensor); + if (delay_us < min_delay_us) { + delay_us = min_delay_us; + } + ASensorEventQueue_setEventRate(hwdata->eventqueue, hwdata->asensor, delay_us); sensor->hwdata = hwdata; return 0; } - -static void -SDL_ANDROID_SensorUpdate(SDL_Sensor *sensor) + +static void SDL_ANDROID_SensorUpdate(SDL_Sensor *sensor) { int events; ASensorEvent event; - struct android_poll_source* source; + struct android_poll_source *source; - if (ALooper_pollAll(0, NULL, &events, (void**)&source) == LOOPER_ID_USER) { + if (ALooper_pollAll(0, NULL, &events, (void **)&source) == LOOPER_ID_USER) { SDL_zero(event); while (ASensorEventQueue_getEvents(sensor->hwdata->eventqueue, &event, 1) > 0) { - SDL_PrivateSensorUpdate(sensor, event.data, SDL_arraysize(event.data)); + SDL_PrivateSensorUpdate(sensor, 0, event.data, SDL_arraysize(event.data)); } } } -static void -SDL_ANDROID_SensorClose(SDL_Sensor *sensor) +static void SDL_ANDROID_SensorClose(SDL_Sensor *sensor) { if (sensor->hwdata) { ASensorEventQueue_disableSensor(sensor->hwdata->eventqueue, sensor->hwdata->asensor); @@ -181,8 +179,7 @@ SDL_ANDROID_SensorClose(SDL_Sensor *sensor) } } -static void -SDL_ANDROID_SensorQuit(void) +static void SDL_ANDROID_SensorQuit(void) { if (SDL_sensors) { SDL_free(SDL_sensors); @@ -191,8 +188,7 @@ SDL_ANDROID_SensorQuit(void) } } -SDL_SensorDriver SDL_ANDROID_SensorDriver = -{ +SDL_SensorDriver SDL_ANDROID_SensorDriver = { SDL_ANDROID_SensorInit, SDL_ANDROID_SensorGetCount, SDL_ANDROID_SensorDetect, diff --git a/SDL2-2.0.12/src/sensor/android/SDL_androidsensor.h b/SDL2-2.30.5/src/sensor/android/SDL_androidsensor.h similarity index 94% rename from SDL2-2.0.12/src/sensor/android/SDL_androidsensor.h rename to SDL2-2.30.5/src/sensor/android/SDL_androidsensor.h index 23c7cfb..5a119db 100644 --- a/SDL2-2.0.12/src/sensor/android/SDL_androidsensor.h +++ b/SDL2-2.30.5/src/sensor/android/SDL_androidsensor.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -27,5 +27,4 @@ struct sensor_hwdata ASensorEventQueue *eventqueue; }; - /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/sensor/coremotion/SDL_coremotionsensor.h b/SDL2-2.30.5/src/sensor/coremotion/SDL_coremotionsensor.h similarity index 94% rename from SDL2-2.0.12/src/sensor/coremotion/SDL_coremotionsensor.h rename to SDL2-2.30.5/src/sensor/coremotion/SDL_coremotionsensor.h index c97d15f..ae48163 100644 --- a/SDL2-2.0.12/src/sensor/coremotion/SDL_coremotionsensor.h +++ b/SDL2-2.30.5/src/sensor/coremotion/SDL_coremotionsensor.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,5 +26,4 @@ struct sensor_hwdata float data[3]; }; - /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/sensor/coremotion/SDL_coremotionsensor.m b/SDL2-2.30.5/src/sensor/coremotion/SDL_coremotionsensor.m similarity index 65% rename from SDL2-2.0.12/src/sensor/coremotion/SDL_coremotionsensor.m rename to SDL2-2.30.5/src/sensor/coremotion/SDL_coremotionsensor.m index 276109f..c653c9b 100644 --- a/SDL2-2.0.12/src/sensor/coremotion/SDL_coremotionsensor.m +++ b/SDL2-2.30.5/src/sensor/coremotion/SDL_coremotionsensor.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -42,8 +42,7 @@ static CMMotionManager *SDL_motion_manager; static SDL_CoreMotionSensor *SDL_sensors; static int SDL_sensors_count; -static int -SDL_COREMOTION_SensorInit(void) +static int SDL_COREMOTION_SensorInit(void) { int i, sensors_count = 0; @@ -80,19 +79,16 @@ SDL_COREMOTION_SensorInit(void) return 0; } -static int -SDL_COREMOTION_SensorGetCount(void) +static int SDL_COREMOTION_SensorGetCount(void) { return SDL_sensors_count; } -static void -SDL_COREMOTION_SensorDetect(void) +static void SDL_COREMOTION_SensorDetect(void) { } -static const char * -SDL_COREMOTION_SensorGetDeviceName(int device_index) +static const char *SDL_COREMOTION_SensorGetDeviceName(int device_index) { switch (SDL_sensors[device_index].type) { case SDL_SENSOR_ACCEL: @@ -104,26 +100,22 @@ SDL_COREMOTION_SensorGetDeviceName(int device_index) } } -static SDL_SensorType -SDL_COREMOTION_SensorGetDeviceType(int device_index) +static SDL_SensorType SDL_COREMOTION_SensorGetDeviceType(int device_index) { return SDL_sensors[device_index].type; } -static int -SDL_COREMOTION_SensorGetDeviceNonPortableType(int device_index) +static int SDL_COREMOTION_SensorGetDeviceNonPortableType(int device_index) { return SDL_sensors[device_index].type; } -static SDL_SensorID -SDL_COREMOTION_SensorGetDeviceInstanceID(int device_index) +static SDL_SensorID SDL_COREMOTION_SensorGetDeviceInstanceID(int device_index) { return SDL_sensors[device_index].instance_id; } -static int -SDL_COREMOTION_SensorOpen(SDL_Sensor *sensor, int device_index) +static int SDL_COREMOTION_SensorOpen(SDL_Sensor *sensor, int device_index) { struct sensor_hwdata *hwdata; @@ -133,8 +125,7 @@ SDL_COREMOTION_SensorOpen(SDL_Sensor *sensor, int device_index) } sensor->hwdata = hwdata; - switch (sensor->type) - { + switch (sensor->type) { case SDL_SENSOR_ACCEL: [SDL_motion_manager startAccelerometerUpdates]; break; @@ -146,55 +137,49 @@ SDL_COREMOTION_SensorOpen(SDL_Sensor *sensor, int device_index) } return 0; } - -static void -SDL_COREMOTION_SensorUpdate(SDL_Sensor *sensor) + +static void SDL_COREMOTION_SensorUpdate(SDL_Sensor *sensor) { - switch (sensor->type) - { + switch (sensor->type) { case SDL_SENSOR_ACCEL: - { - CMAccelerometerData *accelerometerData = SDL_motion_manager.accelerometerData; - if (accelerometerData) { - CMAcceleration acceleration = accelerometerData.acceleration; - float data[3]; - data[0] = acceleration.x * SDL_STANDARD_GRAVITY; - data[1] = acceleration.y * SDL_STANDARD_GRAVITY; - data[2] = acceleration.z * SDL_STANDARD_GRAVITY; - if (SDL_memcmp(data, sensor->hwdata->data, sizeof(data)) != 0) { - SDL_PrivateSensorUpdate(sensor, data, SDL_arraysize(data)); - SDL_memcpy(sensor->hwdata->data, data, sizeof(data)); - } + { + CMAccelerometerData *accelerometerData = SDL_motion_manager.accelerometerData; + if (accelerometerData) { + CMAcceleration acceleration = accelerometerData.acceleration; + float data[3]; + data[0] = -acceleration.x * SDL_STANDARD_GRAVITY; + data[1] = -acceleration.y * SDL_STANDARD_GRAVITY; + data[2] = -acceleration.z * SDL_STANDARD_GRAVITY; + if (SDL_memcmp(data, sensor->hwdata->data, sizeof(data)) != 0) { + SDL_PrivateSensorUpdate(sensor, 0, data, SDL_arraysize(data)); + SDL_memcpy(sensor->hwdata->data, data, sizeof(data)); } } - break; + } break; case SDL_SENSOR_GYRO: - { - CMGyroData *gyroData = SDL_motion_manager.gyroData; - if (gyroData) { - CMRotationRate rotationRate = gyroData.rotationRate; - float data[3]; - data[0] = rotationRate.x; - data[1] = rotationRate.y; - data[2] = rotationRate.z; - if (SDL_memcmp(data, sensor->hwdata->data, sizeof(data)) != 0) { - SDL_PrivateSensorUpdate(sensor, data, SDL_arraysize(data)); - SDL_memcpy(sensor->hwdata->data, data, sizeof(data)); - } + { + CMGyroData *gyroData = SDL_motion_manager.gyroData; + if (gyroData) { + CMRotationRate rotationRate = gyroData.rotationRate; + float data[3]; + data[0] = rotationRate.x; + data[1] = rotationRate.y; + data[2] = rotationRate.z; + if (SDL_memcmp(data, sensor->hwdata->data, sizeof(data)) != 0) { + SDL_PrivateSensorUpdate(sensor, 0, data, SDL_arraysize(data)); + SDL_memcpy(sensor->hwdata->data, data, sizeof(data)); } } - break; + } break; default: break; } } -static void -SDL_COREMOTION_SensorClose(SDL_Sensor *sensor) +static void SDL_COREMOTION_SensorClose(SDL_Sensor *sensor) { if (sensor->hwdata) { - switch (sensor->type) - { + switch (sensor->type) { case SDL_SENSOR_ACCEL: [SDL_motion_manager stopAccelerometerUpdates]; break; @@ -209,13 +194,11 @@ SDL_COREMOTION_SensorClose(SDL_Sensor *sensor) } } -static void -SDL_COREMOTION_SensorQuit(void) +static void SDL_COREMOTION_SensorQuit(void) { } -SDL_SensorDriver SDL_COREMOTION_SensorDriver = -{ +SDL_SensorDriver SDL_COREMOTION_SensorDriver = { SDL_COREMOTION_SensorInit, SDL_COREMOTION_SensorGetCount, SDL_COREMOTION_SensorDetect, diff --git a/SDL2-2.0.12/src/sensor/dummy/SDL_dummysensor.c b/SDL2-2.30.5/src/sensor/dummy/SDL_dummysensor.c similarity index 69% rename from SDL2-2.0.12/src/sensor/dummy/SDL_dummysensor.c rename to SDL2-2.30.5/src/sensor/dummy/SDL_dummysensor.c index aa55e1b..b8840d8 100644 --- a/SDL2-2.0.12/src/sensor/dummy/SDL_dummysensor.c +++ b/SDL2-2.30.5/src/sensor/dummy/SDL_dummysensor.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -18,6 +18,7 @@ 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_config.h" @@ -28,70 +29,58 @@ #include "SDL_dummysensor.h" #include "../SDL_syssensor.h" -static int -SDL_DUMMY_SensorInit(void) +static int SDL_DUMMY_SensorInit(void) { return 0; } -static int -SDL_DUMMY_SensorGetCount(void) +static int SDL_DUMMY_SensorGetCount(void) { return 0; } -static void -SDL_DUMMY_SensorDetect(void) +static void SDL_DUMMY_SensorDetect(void) { } -static const char * -SDL_DUMMY_SensorGetDeviceName(int device_index) +static const char *SDL_DUMMY_SensorGetDeviceName(int device_index) { return NULL; } -static SDL_SensorType -SDL_DUMMY_SensorGetDeviceType(int device_index) +static SDL_SensorType SDL_DUMMY_SensorGetDeviceType(int device_index) { return SDL_SENSOR_INVALID; } -static int -SDL_DUMMY_SensorGetDeviceNonPortableType(int device_index) +static int SDL_DUMMY_SensorGetDeviceNonPortableType(int device_index) { return -1; } -static SDL_SensorID -SDL_DUMMY_SensorGetDeviceInstanceID(int device_index) +static SDL_SensorID SDL_DUMMY_SensorGetDeviceInstanceID(int device_index) { return -1; } -static int -SDL_DUMMY_SensorOpen(SDL_Sensor *sensor, int device_index) +static int SDL_DUMMY_SensorOpen(SDL_Sensor *sensor, int device_index) { return SDL_Unsupported(); } - -static void -SDL_DUMMY_SensorUpdate(SDL_Sensor *sensor) + +static void SDL_DUMMY_SensorUpdate(SDL_Sensor *sensor) { } -static void -SDL_DUMMY_SensorClose(SDL_Sensor *sensor) +static void SDL_DUMMY_SensorClose(SDL_Sensor *sensor) { } -static void -SDL_DUMMY_SensorQuit(void) +static void SDL_DUMMY_SensorQuit(void) { } -SDL_SensorDriver SDL_DUMMY_SensorDriver = -{ +SDL_SensorDriver SDL_DUMMY_SensorDriver = { SDL_DUMMY_SensorInit, SDL_DUMMY_SensorGetCount, SDL_DUMMY_SensorDetect, diff --git a/SDL2-2.0.12/src/sensor/dummy/SDL_dummysensor.h b/SDL2-2.30.5/src/sensor/dummy/SDL_dummysensor.h similarity index 93% rename from SDL2-2.0.12/src/sensor/dummy/SDL_dummysensor.h rename to SDL2-2.30.5/src/sensor/dummy/SDL_dummysensor.h index ee66f2f..e8bf8ef 100644 --- a/SDL2-2.0.12/src/sensor/dummy/SDL_dummysensor.h +++ b/SDL2-2.30.5/src/sensor/dummy/SDL_dummysensor.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.30.5/src/sensor/n3ds/SDL_n3dssensor.c b/SDL2-2.30.5/src/sensor/n3ds/SDL_n3dssensor.c new file mode 100644 index 0000000..236b648 --- /dev/null +++ b/SDL2-2.30.5/src/sensor/n3ds/SDL_n3dssensor.c @@ -0,0 +1,207 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_SENSOR_N3DS + +#include <3ds.h> + +#include "../SDL_syssensor.h" + +/* 1 accelerometer and 1 gyroscope */ +#define N3DS_SENSOR_COUNT 2 + +typedef struct +{ + SDL_SensorType type; + SDL_SensorID instance_id; +} SDL_N3DSSensor; + +static SDL_N3DSSensor N3DS_sensors[N3DS_SENSOR_COUNT]; + +SDL_FORCE_INLINE int InitN3DSServices(void); +SDL_FORCE_INLINE void UpdateN3DSAccelerometer(SDL_Sensor *sensor); +SDL_FORCE_INLINE void UpdateN3DSGyroscope(SDL_Sensor *sensor); + +SDL_FORCE_INLINE SDL_bool +IsDeviceIndexValid(int device_index) +{ + return device_index >= 0 && device_index < N3DS_SENSOR_COUNT; +} + +static int N3DS_SensorInit(void) +{ + if (InitN3DSServices() < 0) { + return SDL_SetError("Failed to initialise N3DS services"); + } + + N3DS_sensors[0].type = SDL_SENSOR_ACCEL; + N3DS_sensors[0].instance_id = SDL_GetNextSensorInstanceID(); + N3DS_sensors[1].type = SDL_SENSOR_GYRO; + N3DS_sensors[1].instance_id = SDL_GetNextSensorInstanceID(); + return 0; +} + +SDL_FORCE_INLINE int +InitN3DSServices(void) +{ + if (R_FAILED(hidInit())) { + return -1; + } + + if (R_FAILED(HIDUSER_EnableAccelerometer())) { + return -1; + } + + if (R_FAILED(HIDUSER_EnableGyroscope())) { + return -1; + } + return 0; +} + +static int N3DS_SensorGetCount(void) +{ + return N3DS_SENSOR_COUNT; +} + +static void N3DS_SensorDetect(void) +{ +} + +static const char *N3DS_SensorGetDeviceName(int device_index) +{ + if (IsDeviceIndexValid(device_index)) { + switch (N3DS_sensors[device_index].type) { + case SDL_SENSOR_ACCEL: + return "Accelerometer"; + case SDL_SENSOR_GYRO: + return "Gyroscope"; + default: + return "Unknown"; + } + } + + return NULL; +} + +static SDL_SensorType N3DS_SensorGetDeviceType(int device_index) +{ + if (IsDeviceIndexValid(device_index)) { + return N3DS_sensors[device_index].type; + } + return SDL_SENSOR_INVALID; +} + +static int N3DS_SensorGetDeviceNonPortableType(int device_index) +{ + return (int)N3DS_SensorGetDeviceType(device_index); +} + +static SDL_SensorID N3DS_SensorGetDeviceInstanceID(int device_index) +{ + if (IsDeviceIndexValid(device_index)) { + return N3DS_sensors[device_index].instance_id; + } + return -1; +} + +static int N3DS_SensorOpen(SDL_Sensor *sensor, int device_index) +{ + return 0; +} + +static void N3DS_SensorUpdate(SDL_Sensor *sensor) +{ + switch (sensor->type) { + case SDL_SENSOR_ACCEL: + UpdateN3DSAccelerometer(sensor); + break; + case SDL_SENSOR_GYRO: + UpdateN3DSGyroscope(sensor); + break; + default: + break; + } +} + +SDL_FORCE_INLINE void +UpdateN3DSAccelerometer(SDL_Sensor *sensor) +{ + static accelVector previous_state = { 0, 0, 0 }; + accelVector current_state; + float data[3]; + + hidAccelRead(¤t_state); + if (SDL_memcmp(&previous_state, ¤t_state, sizeof(accelVector)) != 0) { + SDL_memcpy(&previous_state, ¤t_state, sizeof(accelVector)); + data[0] = (float)current_state.x * SDL_STANDARD_GRAVITY; + data[1] = (float)current_state.y * SDL_STANDARD_GRAVITY; + data[2] = (float)current_state.z * SDL_STANDARD_GRAVITY; + SDL_PrivateSensorUpdate(sensor, 0, data, sizeof(data)); + } +} + +SDL_FORCE_INLINE void +UpdateN3DSGyroscope(SDL_Sensor *sensor) +{ + static angularRate previous_state = { 0, 0, 0 }; + angularRate current_state; + float data[3]; + + hidGyroRead(¤t_state); + if (SDL_memcmp(&previous_state, ¤t_state, sizeof(angularRate)) != 0) { + SDL_memcpy(&previous_state, ¤t_state, sizeof(angularRate)); + data[0] = (float)current_state.x; + data[1] = (float)current_state.y; + data[2] = (float)current_state.z; + SDL_PrivateSensorUpdate(sensor, 0, data, sizeof(data)); + } +} + +static void N3DS_SensorClose(SDL_Sensor *sensor) +{ +} + +static void N3DS_SensorQuit(void) +{ + HIDUSER_DisableGyroscope(); + HIDUSER_DisableAccelerometer(); + hidExit(); +} + +SDL_SensorDriver SDL_N3DS_SensorDriver = { + .Init = N3DS_SensorInit, + .GetCount = N3DS_SensorGetCount, + .Detect = N3DS_SensorDetect, + .GetDeviceName = N3DS_SensorGetDeviceName, + .GetDeviceType = N3DS_SensorGetDeviceType, + .GetDeviceNonPortableType = N3DS_SensorGetDeviceNonPortableType, + .GetDeviceInstanceID = N3DS_SensorGetDeviceInstanceID, + .Open = N3DS_SensorOpen, + .Update = N3DS_SensorUpdate, + .Close = N3DS_SensorClose, + .Quit = N3DS_SensorQuit, +}; + +#endif /* SDL_SENSOR_N3DS */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/sensor/vita/SDL_vitasensor.c b/SDL2-2.30.5/src/sensor/vita/SDL_vitasensor.c new file mode 100644 index 0000000..8ff68dd --- /dev/null +++ b/SDL2-2.30.5/src/sensor/vita/SDL_vitasensor.c @@ -0,0 +1,212 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#if defined(SDL_SENSOR_VITA) + +#include "SDL_error.h" +#include "SDL_sensor.h" +#include "SDL_vitasensor.h" +#include "../SDL_syssensor.h" +#include + +#if !defined(SCE_MOTION_MAX_NUM_STATES) +#define SCE_MOTION_MAX_NUM_STATES 64 +#endif + +typedef struct +{ + SDL_SensorType type; + SDL_SensorID instance_id; +} SDL_VitaSensor; + +static SDL_VitaSensor *SDL_sensors; +static int SDL_sensors_count; + +static int SDL_VITA_SensorInit(void) +{ + sceMotionReset(); + sceMotionStartSampling(); + // not sure if these are needed, we are reading unfiltered state + sceMotionSetAngleThreshold(0); + sceMotionSetDeadband(SCE_FALSE); + sceMotionSetTiltCorrection(SCE_FALSE); + + SDL_sensors_count = 2; + + SDL_sensors = (SDL_VitaSensor *)SDL_calloc(SDL_sensors_count, sizeof(*SDL_sensors)); + if (!SDL_sensors) { + return SDL_OutOfMemory(); + } + + SDL_sensors[0].type = SDL_SENSOR_ACCEL; + SDL_sensors[0].instance_id = SDL_GetNextSensorInstanceID(); + SDL_sensors[1].type = SDL_SENSOR_GYRO; + SDL_sensors[1].instance_id = SDL_GetNextSensorInstanceID(); + + return 0; +} + +static int SDL_VITA_SensorGetCount(void) +{ + return SDL_sensors_count; +} + +static void SDL_VITA_SensorDetect(void) +{ +} + +static const char *SDL_VITA_SensorGetDeviceName(int device_index) +{ + if (device_index < SDL_sensors_count) { + switch (SDL_sensors[device_index].type) { + case SDL_SENSOR_ACCEL: + return "Accelerometer"; + case SDL_SENSOR_GYRO: + return "Gyro"; + default: + return "Unknown"; + } + } + + return NULL; +} + +static SDL_SensorType SDL_VITA_SensorGetDeviceType(int device_index) +{ + if (device_index < SDL_sensors_count) { + return SDL_sensors[device_index].type; + } + + return SDL_SENSOR_INVALID; +} + +static int SDL_VITA_SensorGetDeviceNonPortableType(int device_index) +{ + if (device_index < SDL_sensors_count) { + return SDL_sensors[device_index].type; + } + return -1; +} + +static SDL_SensorID SDL_VITA_SensorGetDeviceInstanceID(int device_index) +{ + if (device_index < SDL_sensors_count) { + return SDL_sensors[device_index].instance_id; + } + return -1; +} + +static int SDL_VITA_SensorOpen(SDL_Sensor *sensor, int device_index) +{ + struct sensor_hwdata *hwdata; + + hwdata = (struct sensor_hwdata *)SDL_calloc(1, sizeof(*hwdata)); + if (!hwdata) { + return SDL_OutOfMemory(); + } + sensor->hwdata = hwdata; + + return 0; +} + +static void SDL_VITA_SensorUpdate(SDL_Sensor *sensor) +{ + int err = 0; + SceMotionSensorState motionState[SCE_MOTION_MAX_NUM_STATES]; + SDL_memset(motionState, 0, sizeof(motionState)); + + err = sceMotionGetSensorState(motionState, SCE_MOTION_MAX_NUM_STATES); + if (err != 0) { + return; + } + + for (int i = 0; i < SCE_MOTION_MAX_NUM_STATES; i++) { + if (sensor->hwdata->counter < motionState[i].counter) { + unsigned int timestamp = motionState[i].timestamp; + + sensor->hwdata->counter = motionState[i].counter; + + if (sensor->hwdata->timestamp_us) { + unsigned int delta; + if (sensor->hwdata->last_timestamp > timestamp) { + SDL_COMPILE_TIME_ASSERT(timestamp, sizeof(timestamp) == sizeof(Uint32)); + delta = (SDL_MAX_UINT32 - sensor->hwdata->last_timestamp + timestamp + 1); + } else { + delta = (timestamp - sensor->hwdata->last_timestamp); + } + sensor->hwdata->timestamp_us += delta; + } else { + sensor->hwdata->timestamp_us = timestamp; + } + sensor->hwdata->last_timestamp = timestamp; + + switch (sensor->type) { + case SDL_SENSOR_ACCEL: + { + float data[3]; + data[0] = motionState[i].accelerometer.x * SDL_STANDARD_GRAVITY; + data[1] = motionState[i].accelerometer.y * SDL_STANDARD_GRAVITY; + data[2] = motionState[i].accelerometer.z * SDL_STANDARD_GRAVITY; + SDL_PrivateSensorUpdate(sensor, sensor->hwdata->timestamp_us, data, SDL_arraysize(data)); + } break; + case SDL_SENSOR_GYRO: + { + float data[3]; + data[0] = motionState[i].gyro.x; + data[1] = motionState[i].gyro.y; + data[2] = motionState[i].gyro.z; + SDL_PrivateSensorUpdate(sensor, sensor->hwdata->timestamp_us, data, SDL_arraysize(data)); + } break; + default: + break; + } + } + } +} + +static void SDL_VITA_SensorClose(SDL_Sensor *sensor) +{ +} + +static void SDL_VITA_SensorQuit(void) +{ + sceMotionStopSampling(); +} + +SDL_SensorDriver SDL_VITA_SensorDriver = { + SDL_VITA_SensorInit, + SDL_VITA_SensorGetCount, + SDL_VITA_SensorDetect, + SDL_VITA_SensorGetDeviceName, + SDL_VITA_SensorGetDeviceType, + SDL_VITA_SensorGetDeviceNonPortableType, + SDL_VITA_SensorGetDeviceInstanceID, + SDL_VITA_SensorOpen, + SDL_VITA_SensorUpdate, + SDL_VITA_SensorClose, + SDL_VITA_SensorQuit, +}; + +#endif /* SDL_SENSOR_VITA */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/sensor/vita/SDL_vitasensor.h b/SDL2-2.30.5/src/sensor/vita/SDL_vitasensor.h new file mode 100644 index 0000000..183c35a --- /dev/null +++ b/SDL2-2.30.5/src/sensor/vita/SDL_vitasensor.h @@ -0,0 +1,31 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +/* The private structure used to keep track of a sensor */ +struct sensor_hwdata +{ + Uint32 counter; + unsigned int last_timestamp; + Uint64 timestamp_us; +}; + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/sensor/windows/SDL_windowssensor.c b/SDL2-2.30.5/src/sensor/windows/SDL_windowssensor.c new file mode 100644 index 0000000..cba5b17 --- /dev/null +++ b/SDL2-2.30.5/src/sensor/windows/SDL_windowssensor.c @@ -0,0 +1,478 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_config.h" + +#if defined(SDL_SENSOR_WINDOWS) + +#include "SDL_error.h" +#include "SDL_mutex.h" +#include "SDL_sensor.h" +#include "SDL_windowssensor.h" +#include "../SDL_syssensor.h" +#include "../../core/windows/SDL_windows.h" + +#define COBJMACROS +#include +#include +#include + +DEFINE_GUID(SDL_CLSID_SensorManager, 0x77A1C827, 0xFCD2, 0x4689, 0x89, 0x15, 0x9D, 0x61, 0x3C, 0xC5, 0xFA, 0x3E); +DEFINE_GUID(SDL_IID_SensorManager, 0xBD77DB67, 0x45A8, 0x42DC, 0x8D, 0x00, 0x6D, 0xCF, 0x15, 0xF8, 0x37, 0x7A); +DEFINE_GUID(SDL_IID_SensorManagerEvents, 0x9B3B0B86, 0x266A, 0x4AAD, 0xB2, 0x1F, 0xFD, 0xE5, 0x50, 0x10, 0x01, 0xB7); +DEFINE_GUID(SDL_IID_SensorEvents, 0x5D8DCC91, 0x4641, 0x47E7, 0xB7, 0xC3, 0xB7, 0x4F, 0x48, 0xA6, 0xC3, 0x91); + +/* These constants aren't available in Visual Studio 2015 or earlier Windows SDK */ +DEFINE_PROPERTYKEY(SDL_SENSOR_DATA_TYPE_ANGULAR_VELOCITY_X_DEGREES_PER_SECOND, 0X3F8A69A2, 0X7C5, 0X4E48, 0XA9, 0X65, 0XCD, 0X79, 0X7A, 0XAB, 0X56, 0XD5, 10); //[VT_R8] +DEFINE_PROPERTYKEY(SDL_SENSOR_DATA_TYPE_ANGULAR_VELOCITY_Y_DEGREES_PER_SECOND, 0X3F8A69A2, 0X7C5, 0X4E48, 0XA9, 0X65, 0XCD, 0X79, 0X7A, 0XAB, 0X56, 0XD5, 11); //[VT_R8] +DEFINE_PROPERTYKEY(SDL_SENSOR_DATA_TYPE_ANGULAR_VELOCITY_Z_DEGREES_PER_SECOND, 0X3F8A69A2, 0X7C5, 0X4E48, 0XA9, 0X65, 0XCD, 0X79, 0X7A, 0XAB, 0X56, 0XD5, 12); //[VT_R8] + +typedef struct +{ + SDL_SensorID id; + ISensor *sensor; + SENSOR_ID sensor_id; + char *name; + SDL_SensorType type; + SDL_Sensor *sensor_opened; + +} SDL_Windows_Sensor; + +static SDL_bool SDL_windowscoinit; +static ISensorManager *SDL_sensor_manager; +static int SDL_num_sensors; +static SDL_Windows_Sensor *SDL_sensors; + +static int ConnectSensor(ISensor *sensor); +static int DisconnectSensor(ISensor *sensor); + +static HRESULT STDMETHODCALLTYPE ISensorManagerEventsVtbl_QueryInterface(ISensorManagerEvents *This, REFIID riid, void **ppvObject) +{ + if (!ppvObject) { + return E_INVALIDARG; + } + + *ppvObject = NULL; + if (WIN_IsEqualIID(riid, &IID_IUnknown) || WIN_IsEqualIID(riid, &SDL_IID_SensorManagerEvents)) { + *ppvObject = This; + return S_OK; + } + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE ISensorManagerEventsVtbl_AddRef(ISensorManagerEvents *This) +{ + return 1; +} + +static ULONG STDMETHODCALLTYPE ISensorManagerEventsVtbl_Release(ISensorManagerEvents *This) +{ + return 1; +} + +static HRESULT STDMETHODCALLTYPE ISensorManagerEventsVtbl_OnSensorEnter(ISensorManagerEvents *This, ISensor *pSensor, SensorState state) +{ + ConnectSensor(pSensor); + return S_OK; +} + +static ISensorManagerEventsVtbl sensor_manager_events_vtbl = { + ISensorManagerEventsVtbl_QueryInterface, + ISensorManagerEventsVtbl_AddRef, + ISensorManagerEventsVtbl_Release, + ISensorManagerEventsVtbl_OnSensorEnter +}; +static ISensorManagerEvents sensor_manager_events = { + &sensor_manager_events_vtbl +}; + +static HRESULT STDMETHODCALLTYPE ISensorEventsVtbl_QueryInterface(ISensorEvents *This, REFIID riid, void **ppvObject) +{ + if (!ppvObject) { + return E_INVALIDARG; + } + + *ppvObject = NULL; + if (WIN_IsEqualIID(riid, &IID_IUnknown) || WIN_IsEqualIID(riid, &SDL_IID_SensorEvents)) { + *ppvObject = This; + return S_OK; + } + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE ISensorEventsVtbl_AddRef(ISensorEvents *This) +{ + return 1; +} + +static ULONG STDMETHODCALLTYPE ISensorEventsVtbl_Release(ISensorEvents *This) +{ + return 1; +} + +static HRESULT STDMETHODCALLTYPE ISensorEventsVtbl_OnStateChanged(ISensorEvents *This, ISensor *pSensor, SensorState state) +{ +#ifdef DEBUG_SENSORS + int i; + + SDL_LockSensors(); + for (i = 0; i < SDL_num_sensors; ++i) { + if (pSensor == SDL_sensors[i].sensor) { + SDL_Log("Sensor %s state changed to %d\n", SDL_sensors[i].name, state); + } + } + SDL_UnlockSensors(); +#endif + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE ISensorEventsVtbl_OnDataUpdated(ISensorEvents *This, ISensor *pSensor, ISensorDataReport *pNewData) +{ + int i; + + SDL_LockSensors(); + for (i = 0; i < SDL_num_sensors; ++i) { + if (pSensor == SDL_sensors[i].sensor) { + if (SDL_sensors[i].sensor_opened) { + HRESULT hrX, hrY, hrZ; + PROPVARIANT valueX, valueY, valueZ; + +#ifdef DEBUG_SENSORS + SDL_Log("Sensor %s data updated\n", SDL_sensors[i].name); +#endif + switch (SDL_sensors[i].type) { + case SDL_SENSOR_ACCEL: + hrX = ISensorDataReport_GetSensorValue(pNewData, &SENSOR_DATA_TYPE_ACCELERATION_X_G, &valueX); + hrY = ISensorDataReport_GetSensorValue(pNewData, &SENSOR_DATA_TYPE_ACCELERATION_Y_G, &valueY); + hrZ = ISensorDataReport_GetSensorValue(pNewData, &SENSOR_DATA_TYPE_ACCELERATION_Z_G, &valueZ); + if (SUCCEEDED(hrX) && SUCCEEDED(hrY) && SUCCEEDED(hrZ) && + valueX.vt == VT_R8 && valueY.vt == VT_R8 && valueZ.vt == VT_R8) { + float values[3]; + + values[0] = (float)valueX.dblVal * SDL_STANDARD_GRAVITY; + values[1] = (float)valueY.dblVal * SDL_STANDARD_GRAVITY; + values[2] = (float)valueZ.dblVal * SDL_STANDARD_GRAVITY; + SDL_PrivateSensorUpdate(SDL_sensors[i].sensor_opened, 0, values, 3); + } + break; + case SDL_SENSOR_GYRO: + hrX = ISensorDataReport_GetSensorValue(pNewData, &SDL_SENSOR_DATA_TYPE_ANGULAR_VELOCITY_X_DEGREES_PER_SECOND, &valueX); + hrY = ISensorDataReport_GetSensorValue(pNewData, &SDL_SENSOR_DATA_TYPE_ANGULAR_VELOCITY_Y_DEGREES_PER_SECOND, &valueY); + hrZ = ISensorDataReport_GetSensorValue(pNewData, &SDL_SENSOR_DATA_TYPE_ANGULAR_VELOCITY_Z_DEGREES_PER_SECOND, &valueZ); + if (SUCCEEDED(hrX) && SUCCEEDED(hrY) && SUCCEEDED(hrZ) && + valueX.vt == VT_R8 && valueY.vt == VT_R8 && valueZ.vt == VT_R8) { + const float DEGREES_TO_RADIANS = (float)(M_PI / 180.0f); + float values[3]; + + values[0] = (float)valueX.dblVal * DEGREES_TO_RADIANS; + values[1] = (float)valueY.dblVal * DEGREES_TO_RADIANS; + values[2] = (float)valueZ.dblVal * DEGREES_TO_RADIANS; + SDL_PrivateSensorUpdate(SDL_sensors[i].sensor_opened, 0, values, 3); + } + break; + default: + /* FIXME: Need to know how to interpret the data for this sensor */ + break; + } + } + break; + } + } + SDL_UnlockSensors(); + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE ISensorEventsVtbl_OnEvent(ISensorEvents *This, ISensor *pSensor, REFGUID eventID, IPortableDeviceValues *pEventData) +{ +#ifdef DEBUG_SENSORS + int i; + + SDL_LockSensors(); + for (i = 0; i < SDL_num_sensors; ++i) { + if (pSensor == SDL_sensors[i].sensor) { + SDL_Log("Sensor %s event occurred\n", SDL_sensors[i].name); + } + } + SDL_UnlockSensors(); +#endif + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE ISensorEventsVtbl_OnLeave(ISensorEvents *This, REFSENSOR_ID ID) +{ + int i; + + SDL_LockSensors(); + for (i = 0; i < SDL_num_sensors; ++i) { + if (WIN_IsEqualIID(ID, &SDL_sensors[i].sensor_id)) { +#ifdef DEBUG_SENSORS + SDL_Log("Sensor %s disconnected\n", SDL_sensors[i].name); +#endif + DisconnectSensor(SDL_sensors[i].sensor); + } + } + SDL_UnlockSensors(); + + return S_OK; +} + +static ISensorEventsVtbl sensor_events_vtbl = { + ISensorEventsVtbl_QueryInterface, + ISensorEventsVtbl_AddRef, + ISensorEventsVtbl_Release, + ISensorEventsVtbl_OnStateChanged, + ISensorEventsVtbl_OnDataUpdated, + ISensorEventsVtbl_OnEvent, + ISensorEventsVtbl_OnLeave +}; +static ISensorEvents sensor_events = { + &sensor_events_vtbl +}; + +static int ConnectSensor(ISensor *sensor) +{ + SDL_Windows_Sensor *new_sensor, *new_sensors; + HRESULT hr; + SENSOR_ID sensor_id; + SENSOR_TYPE_ID type_id; + SDL_SensorType type; + BSTR bstr_name = NULL; + char *name; + + hr = ISensor_GetID(sensor, &sensor_id); + if (FAILED(hr)) { + return WIN_SetErrorFromHRESULT("Couldn't get sensor ID", hr); + } + + hr = ISensor_GetType(sensor, &type_id); + if (FAILED(hr)) { + return WIN_SetErrorFromHRESULT("Couldn't get sensor type", hr); + } + + if (WIN_IsEqualIID(&type_id, &SENSOR_TYPE_ACCELEROMETER_3D)) { + type = SDL_SENSOR_ACCEL; + } else if (WIN_IsEqualIID(&type_id, &SENSOR_TYPE_GYROMETER_3D)) { + type = SDL_SENSOR_GYRO; + } else { + return SDL_SetError("Unknown sensor type"); + } + + hr = ISensor_GetFriendlyName(sensor, &bstr_name); + if (SUCCEEDED(hr) && bstr_name) { + name = WIN_StringToUTF8W(bstr_name); + } else { + name = SDL_strdup("Unknown Sensor"); + } + if (bstr_name != NULL) { + SysFreeString(bstr_name); + } + if (!name) { + return SDL_OutOfMemory(); + } + + SDL_LockSensors(); + new_sensors = (SDL_Windows_Sensor *)SDL_realloc(SDL_sensors, (SDL_num_sensors + 1) * sizeof(SDL_Windows_Sensor)); + if (!new_sensors) { + SDL_UnlockSensors(); + SDL_free(name); + return SDL_OutOfMemory(); + } + + ISensor_AddRef(sensor); + ISensor_SetEventSink(sensor, &sensor_events); + + SDL_sensors = new_sensors; + new_sensor = &SDL_sensors[SDL_num_sensors]; + ++SDL_num_sensors; + + SDL_zerop(new_sensor); + new_sensor->id = SDL_GetNextSensorInstanceID(); + new_sensor->sensor = sensor; + new_sensor->type = type; + new_sensor->name = name; + + SDL_UnlockSensors(); + + return 0; +} + +static int DisconnectSensor(ISensor *sensor) +{ + SDL_Windows_Sensor *old_sensor; + int i; + + SDL_LockSensors(); + for (i = 0; i < SDL_num_sensors; ++i) { + old_sensor = &SDL_sensors[i]; + if (sensor == old_sensor->sensor) { + /* This call hangs for some reason: + * https://github.com/libsdl-org/SDL/issues/5288 + */ + /*ISensor_SetEventSink(sensor, NULL);*/ + ISensor_Release(sensor); + SDL_free(old_sensor->name); + --SDL_num_sensors; + if (i < SDL_num_sensors) { + SDL_memmove(&SDL_sensors[i], &SDL_sensors[i + 1], (SDL_num_sensors - i) * sizeof(SDL_sensors[i])); + } + break; + } + } + SDL_UnlockSensors(); + + return 0; +} + +static int SDL_WINDOWS_SensorInit(void) +{ + HRESULT hr; + ISensorCollection *sensor_collection = NULL; + + if (WIN_CoInitialize() == S_OK) { + SDL_windowscoinit = SDL_TRUE; + } + + hr = CoCreateInstance(&SDL_CLSID_SensorManager, NULL, CLSCTX_INPROC_SERVER, &SDL_IID_SensorManager, (LPVOID *)&SDL_sensor_manager); + if (FAILED(hr)) { + /* If we can't create a sensor manager (i.e. on Wine), we won't have any sensors, but don't fail the init */ + return 0; /* WIN_SetErrorFromHRESULT("Couldn't create the sensor manager", hr); */ + } + + hr = ISensorManager_SetEventSink(SDL_sensor_manager, &sensor_manager_events); + if (FAILED(hr)) { + ISensorManager_Release(SDL_sensor_manager); + SDL_sensor_manager = NULL; + return WIN_SetErrorFromHRESULT("Couldn't set the sensor manager event sink", hr); + } + + hr = ISensorManager_GetSensorsByCategory(SDL_sensor_manager, &SENSOR_CATEGORY_ALL, &sensor_collection); + if (SUCCEEDED(hr)) { + ULONG i, count; + + hr = ISensorCollection_GetCount(sensor_collection, &count); + if (SUCCEEDED(hr)) { + for (i = 0; i < count; ++i) { + ISensor *sensor; + + hr = ISensorCollection_GetAt(sensor_collection, i, &sensor); + if (SUCCEEDED(hr)) { + SensorState state; + + hr = ISensor_GetState(sensor, &state); + if (SUCCEEDED(hr)) { + ISensorManagerEventsVtbl_OnSensorEnter(&sensor_manager_events, sensor, state); + } + ISensorManager_Release(sensor); + } + } + } + ISensorCollection_Release(sensor_collection); + } + return 0; +} + +static int SDL_WINDOWS_SensorGetCount(void) +{ + return SDL_num_sensors; +} + +static void SDL_WINDOWS_SensorDetect(void) +{ +} + +static const char *SDL_WINDOWS_SensorGetDeviceName(int device_index) +{ + return SDL_sensors[device_index].name; +} + +static SDL_SensorType SDL_WINDOWS_SensorGetDeviceType(int device_index) +{ + return SDL_sensors[device_index].type; +} + +static int SDL_WINDOWS_SensorGetDeviceNonPortableType(int device_index) +{ + return -1; +} + +static SDL_SensorID SDL_WINDOWS_SensorGetDeviceInstanceID(int device_index) +{ + return SDL_sensors[device_index].id; +} + +static int SDL_WINDOWS_SensorOpen(SDL_Sensor *sensor, int device_index) +{ + SDL_sensors[device_index].sensor_opened = sensor; + return 0; +} + +static void SDL_WINDOWS_SensorUpdate(SDL_Sensor *sensor) +{ +} + +static void SDL_WINDOWS_SensorClose(SDL_Sensor *sensor) +{ + int i; + + for (i = 0; i < SDL_num_sensors; ++i) { + if (sensor == SDL_sensors[i].sensor_opened) { + SDL_sensors[i].sensor_opened = NULL; + break; + } + } +} + +static void SDL_WINDOWS_SensorQuit(void) +{ + while (SDL_num_sensors > 0) { + DisconnectSensor(SDL_sensors[0].sensor); + } + + if (SDL_sensor_manager) { + ISensorManager_SetEventSink(SDL_sensor_manager, NULL); + ISensorManager_Release(SDL_sensor_manager); + SDL_sensor_manager = NULL; + } + + if (SDL_windowscoinit) { + WIN_CoUninitialize(); + } +} + +SDL_SensorDriver SDL_WINDOWS_SensorDriver = { + SDL_WINDOWS_SensorInit, + SDL_WINDOWS_SensorGetCount, + SDL_WINDOWS_SensorDetect, + SDL_WINDOWS_SensorGetDeviceName, + SDL_WINDOWS_SensorGetDeviceType, + SDL_WINDOWS_SensorGetDeviceNonPortableType, + SDL_WINDOWS_SensorGetDeviceInstanceID, + SDL_WINDOWS_SensorOpen, + SDL_WINDOWS_SensorUpdate, + SDL_WINDOWS_SensorClose, + SDL_WINDOWS_SensorQuit, +}; + +#endif /* SDL_SENSOR_WINDOWS */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/sensor/windows/SDL_windowssensor.h b/SDL2-2.30.5/src/sensor/windows/SDL_windowssensor.h new file mode 100644 index 0000000..e8bf8ef --- /dev/null +++ b/SDL2-2.30.5/src/sensor/windows/SDL_windowssensor.h @@ -0,0 +1,23 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/stdlib/SDL_crc16.c b/SDL2-2.30.5/src/stdlib/SDL_crc16.c new file mode 100644 index 0000000..d1270f1 --- /dev/null +++ b/SDL2-2.30.5/src/stdlib/SDL_crc16.c @@ -0,0 +1,57 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_stdinc.h" + + +/* Public domain CRC implementation adapted from: + http://home.thep.lu.se/~bjorn/crc/crc32_simple.c + + This algorithm is compatible with the 16-bit CRC described here: + https://www.lammertbies.nl/comm/info/crc-calculation +*/ +/* NOTE: DO NOT CHANGE THIS ALGORITHM + There is code that relies on this in the joystick code +*/ + +static Uint16 crc16_for_byte(Uint8 r) +{ + Uint16 crc = 0; + int i; + for (i = 0; i < 8; ++i) { + crc = ((crc ^ r) & 1 ? 0xA001 : 0) ^ crc >> 1; + r >>= 1; + } + return crc; +} + +Uint16 SDL_crc16(Uint16 crc, const void *data, size_t len) +{ + /* As an optimization we can precalculate a 256 entry table for each byte */ + size_t i; + for (i = 0; i < len; ++i) { + crc = crc16_for_byte((Uint8)crc ^ ((const Uint8 *)data)[i]) ^ crc >> 8; + } + return crc; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/stdlib/SDL_crc32.c b/SDL2-2.30.5/src/stdlib/SDL_crc32.c new file mode 100644 index 0000000..ad6eed3 --- /dev/null +++ b/SDL2-2.30.5/src/stdlib/SDL_crc32.c @@ -0,0 +1,55 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_stdinc.h" + + +/* Public domain CRC implementation adapted from: + http://home.thep.lu.se/~bjorn/crc/crc32_simple.c + + This algorithm is compatible with the 32-bit CRC described here: + https://www.lammertbies.nl/comm/info/crc-calculation +*/ +/* NOTE: DO NOT CHANGE THIS ALGORITHM + There is code that relies on this in the joystick code +*/ + +static Uint32 crc32_for_byte(Uint32 r) +{ + int i; + for (i = 0; i < 8; ++i) { + r = (r & 1 ? 0 : (Uint32)0xEDB88320L) ^ r >> 1; + } + return r ^ (Uint32)0xFF000000L; +} + +Uint32 SDL_crc32(Uint32 crc, const void *data, size_t len) +{ + /* As an optimization we can precalculate a 256 entry table for each byte */ + size_t i; + for (i = 0; i < len; ++i) { + crc = crc32_for_byte((Uint8)crc ^ ((const Uint8 *)data)[i]) ^ crc >> 8; + } + return crc; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/stdlib/SDL_getenv.c b/SDL2-2.30.5/src/stdlib/SDL_getenv.c similarity index 77% rename from SDL2-2.0.12/src/stdlib/SDL_getenv.c rename to SDL2-2.30.5/src/stdlib/SDL_getenv.c index fd636e7..13cf5a3 100644 --- a/SDL2-2.0.12/src/stdlib/SDL_getenv.c +++ b/SDL2-2.30.5/src/stdlib/SDL_getenv.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -25,7 +25,7 @@ #include "../SDL_internal.h" -#if defined(__WIN32__) +#if defined(__WIN32__) || defined(__WINGDK__) #include "../core/windows/SDL_windows.h" #endif @@ -35,7 +35,7 @@ #include "SDL_stdinc.h" -#if defined(__WIN32__) && (!defined(HAVE_SETENV) || !defined(HAVE_GETENV)) +#if (defined(__WIN32__) || defined(__WINGDK__)) && (!defined(HAVE_SETENV) || !defined(HAVE_GETENV)) /* Note this isn't thread-safe! */ static char *SDL_envmem = NULL; /* Ugh, memory leak */ static size_t SDL_envmemlen = 0; @@ -44,28 +44,26 @@ static size_t SDL_envmemlen = 0; /* Put a variable into the environment */ /* Note: Name may not contain a '=' character. (Reference: http://www.unix.com/man-page/Linux/3/setenv/) */ #if defined(HAVE_SETENV) -int -SDL_setenv(const char *name, const char *value, int overwrite) +int SDL_setenv(const char *name, const char *value, int overwrite) { /* Input validation */ - if (!name || SDL_strlen(name) == 0 || SDL_strchr(name, '=') != NULL || !value) { - return (-1); + if (!name || *name == '\0' || SDL_strchr(name, '=') != NULL || !value) { + return -1; } - + return setenv(name, value, overwrite); } -#elif defined(__WIN32__) -int -SDL_setenv(const char *name, const char *value, int overwrite) +#elif defined(__WIN32__) || defined(__WINGDK__) +int SDL_setenv(const char *name, const char *value, int overwrite) { /* Input validation */ - if (!name || SDL_strlen(name) == 0 || SDL_strchr(name, '=') != NULL || !value) { - return (-1); + if (!name || *name == '\0' || SDL_strchr(name, '=') != NULL || !value) { + return -1; } - + if (!overwrite) { if (GetEnvironmentVariableA(name, NULL, 0) > 0) { - return 0; /* asked not to overwrite existing value. */ + return 0; /* asked not to overwrite existing value. */ } } if (!SetEnvironmentVariableA(name, *value ? value : NULL)) { @@ -75,48 +73,46 @@ SDL_setenv(const char *name, const char *value, int overwrite) } /* We have a real environment table, but no real setenv? Fake it w/ putenv. */ #elif (defined(HAVE_GETENV) && defined(HAVE_PUTENV) && !defined(HAVE_SETENV)) -int -SDL_setenv(const char *name, const char *value, int overwrite) +int SDL_setenv(const char *name, const char *value, int overwrite) { size_t len; char *new_variable; /* Input validation */ - if (!name || SDL_strlen(name) == 0 || SDL_strchr(name, '=') != NULL || !value) { - return (-1); + if (!name || *name == '\0' || SDL_strchr(name, '=') != NULL || !value) { + return -1; } - + if (getenv(name) != NULL) { if (overwrite) { unsetenv(name); } else { - return 0; /* leave the existing one there. */ + return 0; /* leave the existing one there. */ } } /* This leaks. Sorry. Get a better OS so we don't have to do this. */ len = SDL_strlen(name) + SDL_strlen(value) + 2; - new_variable = (char *) SDL_malloc(len); + new_variable = (char *)SDL_malloc(len); if (!new_variable) { - return (-1); + return -1; } SDL_snprintf(new_variable, len, "%s=%s", name, value); return putenv(new_variable); } #else /* roll our own */ -static char **SDL_env = (char **) 0; -int -SDL_setenv(const char *name, const char *value, int overwrite) +static char **SDL_env = (char **)0; +int SDL_setenv(const char *name, const char *value, int overwrite) { int added; - int len, i; + size_t len, i; char **new_env; char *new_variable; /* Input validation */ - if (!name || SDL_strlen(name) == 0 || SDL_strchr(name, '=') != NULL || !value) { - return (-1); + if (!name || *name == '\0' || SDL_strchr(name, '=') != NULL || !value) { + return -1; } /* See if it already exists */ @@ -126,9 +122,9 @@ SDL_setenv(const char *name, const char *value, int overwrite) /* Allocate memory for the variable */ len = SDL_strlen(name) + SDL_strlen(value) + 2; - new_variable = (char *) SDL_malloc(len); + new_variable = (char *)SDL_malloc(len); if (!new_variable) { - return (-1); + return -1; } SDL_snprintf(new_variable, len, "%s=%s", name, value); @@ -160,20 +156,19 @@ SDL_setenv(const char *name, const char *value, int overwrite) if (new_env) { SDL_env = new_env; SDL_env[i++] = new_variable; - SDL_env[i++] = (char *) 0; + SDL_env[i++] = (char *)0; added = 1; } else { SDL_free(new_variable); } } - return (added ? 0 : -1); + return added ? 0 : -1; } #endif /* Retrieve a variable named "name" from the environment */ #if defined(HAVE_GETENV) -char * -SDL_getenv(const char *name) +char *SDL_getenv(const char *name) { #if defined(__ANDROID__) /* Make sure variables from the application manifest are available */ @@ -181,52 +176,50 @@ SDL_getenv(const char *name) #endif /* Input validation */ - if (!name || !*name) { + if (!name || *name == '\0') { return NULL; } return getenv(name); } -#elif defined(__WIN32__) -char * -SDL_getenv(const char *name) +#elif defined(__WIN32__) || defined(__WINGDK__) +char *SDL_getenv(const char *name) { size_t bufferlen; /* Input validation */ - if (!name || SDL_strlen(name)==0) { + if (!name || *name == '\0') { return NULL; } - + bufferlen = - GetEnvironmentVariableA(name, SDL_envmem, (DWORD) SDL_envmemlen); + GetEnvironmentVariableA(name, SDL_envmem, (DWORD)SDL_envmemlen); if (bufferlen == 0) { return NULL; } if (bufferlen > SDL_envmemlen) { - char *newmem = (char *) SDL_realloc(SDL_envmem, bufferlen); - if (newmem == NULL) { + char *newmem = (char *)SDL_realloc(SDL_envmem, bufferlen); + if (!newmem) { return NULL; } SDL_envmem = newmem; SDL_envmemlen = bufferlen; - GetEnvironmentVariableA(name, SDL_envmem, (DWORD) SDL_envmemlen); + GetEnvironmentVariableA(name, SDL_envmem, (DWORD)SDL_envmemlen); } return SDL_envmem; } #else -char * -SDL_getenv(const char *name) +char *SDL_getenv(const char *name) { - int len, i; + size_t len, i; char *value; /* Input validation */ - if (!name || SDL_strlen(name)==0) { + if (!name || *name == '\0') { return NULL; } - - value = (char *) 0; + + value = (char *)0; if (SDL_env) { len = SDL_strlen(name); for (i = 0; SDL_env[i] && !value; ++i) { @@ -240,12 +233,10 @@ SDL_getenv(const char *name) } #endif - #ifdef TEST_MAIN #include -int -main(int argc, char *argv[]) +int main(int argc, char *argv[]) { char *value; @@ -308,7 +299,7 @@ main(int argc, char *argv[]) } else { printf("failed\n"); } - return (0); + return 0; } #endif /* TEST_MAIN */ diff --git a/SDL2-2.30.5/src/stdlib/SDL_iconv.c b/SDL2-2.30.5/src/stdlib/SDL_iconv.c new file mode 100644 index 0000000..416e199 --- /dev/null +++ b/SDL2-2.30.5/src/stdlib/SDL_iconv.c @@ -0,0 +1,861 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#if defined(__clang_analyzer__) && !defined(SDL_DISABLE_ANALYZE_MACROS) +#define SDL_DISABLE_ANALYZE_MACROS 1 +#endif + +#include "../SDL_internal.h" + +/* This file contains portable iconv functions for SDL */ + +#include "SDL_stdinc.h" +#include "SDL_endian.h" + +#if defined(HAVE_ICONV) && defined(HAVE_ICONV_H) +#ifndef SDL_USE_LIBICONV +/* Define LIBICONV_PLUG to use iconv from the base instead of ports and avoid linker errors. */ +#define LIBICONV_PLUG 1 +#endif +#include +#include + +SDL_COMPILE_TIME_ASSERT(iconv_t, sizeof(iconv_t) <= sizeof(SDL_iconv_t)); + +SDL_iconv_t SDL_iconv_open(const char *tocode, const char *fromcode) +{ + return (SDL_iconv_t)((uintptr_t)iconv_open(tocode, fromcode)); +} + +int SDL_iconv_close(SDL_iconv_t cd) +{ + return iconv_close((iconv_t)((uintptr_t)cd)); +} + +size_t SDL_iconv(SDL_iconv_t cd, + const char **inbuf, size_t *inbytesleft, + char **outbuf, size_t *outbytesleft) +{ + /* iconv's second parameter may or may not be `const char const *` depending on the + C runtime's whims. Casting to void * seems to make everyone happy, though. */ + const size_t retCode = iconv((iconv_t)((uintptr_t)cd), (void *)inbuf, inbytesleft, outbuf, outbytesleft); + if (retCode == (size_t)-1) { + switch (errno) { + case E2BIG: + return SDL_ICONV_E2BIG; + case EILSEQ: + return SDL_ICONV_EILSEQ; + case EINVAL: + return SDL_ICONV_EINVAL; + default: + return SDL_ICONV_ERROR; + } + } + return retCode; +} + +#else + +/* Lots of useful information on Unicode at: + http://www.cl.cam.ac.uk/~mgk25/unicode.html +*/ + +#define UNICODE_BOM 0xFEFF + +#define UNKNOWN_ASCII '?' +#define UNKNOWN_UNICODE 0xFFFD + +enum +{ + ENCODING_UNKNOWN, + ENCODING_ASCII, + ENCODING_LATIN1, + ENCODING_UTF8, + ENCODING_UTF16, /* Needs byte order marker */ + ENCODING_UTF16BE, + ENCODING_UTF16LE, + ENCODING_UTF32, /* Needs byte order marker */ + ENCODING_UTF32BE, + ENCODING_UTF32LE, + ENCODING_UCS2BE, + ENCODING_UCS2LE, + ENCODING_UCS4BE, + ENCODING_UCS4LE, +}; +#if SDL_BYTEORDER == SDL_BIG_ENDIAN +#define ENCODING_UTF16NATIVE ENCODING_UTF16BE +#define ENCODING_UTF32NATIVE ENCODING_UTF32BE +#define ENCODING_UCS2NATIVE ENCODING_UCS2BE +#define ENCODING_UCS4NATIVE ENCODING_UCS4BE +#else +#define ENCODING_UTF16NATIVE ENCODING_UTF16LE +#define ENCODING_UTF32NATIVE ENCODING_UTF32LE +#define ENCODING_UCS2NATIVE ENCODING_UCS2LE +#define ENCODING_UCS4NATIVE ENCODING_UCS4LE +#endif + +struct _SDL_iconv_t +{ + int src_fmt; + int dst_fmt; +}; + +static struct +{ + const char *name; + int format; +} encodings[] = { + /* *INDENT-OFF* */ /* clang-format off */ + { "ASCII", ENCODING_ASCII }, + { "US-ASCII", ENCODING_ASCII }, + { "8859-1", ENCODING_LATIN1 }, + { "ISO-8859-1", ENCODING_LATIN1 }, +#if defined(__WIN32__) || defined(__OS2__) || defined(__GDK__) + { "WCHAR_T", ENCODING_UTF16LE }, +#else + { "WCHAR_T", ENCODING_UCS4NATIVE }, +#endif + { "UTF8", ENCODING_UTF8 }, + { "UTF-8", ENCODING_UTF8 }, + { "UTF16", ENCODING_UTF16 }, + { "UTF-16", ENCODING_UTF16 }, + { "UTF16BE", ENCODING_UTF16BE }, + { "UTF-16BE", ENCODING_UTF16BE }, + { "UTF16LE", ENCODING_UTF16LE }, + { "UTF-16LE", ENCODING_UTF16LE }, + { "UTF32", ENCODING_UTF32 }, + { "UTF-32", ENCODING_UTF32 }, + { "UTF32BE", ENCODING_UTF32BE }, + { "UTF-32BE", ENCODING_UTF32BE }, + { "UTF32LE", ENCODING_UTF32LE }, + { "UTF-32LE", ENCODING_UTF32LE }, + { "UCS2", ENCODING_UCS2BE }, + { "UCS-2", ENCODING_UCS2BE }, + { "UCS-2LE", ENCODING_UCS2LE }, + { "UCS-2BE", ENCODING_UCS2BE }, + { "UCS-2-INTERNAL", ENCODING_UCS2NATIVE }, + { "UCS4", ENCODING_UCS4BE }, + { "UCS-4", ENCODING_UCS4BE }, + { "UCS-4LE", ENCODING_UCS4LE }, + { "UCS-4BE", ENCODING_UCS4BE }, + { "UCS-4-INTERNAL", ENCODING_UCS4NATIVE }, +/* *INDENT-ON* */ /* clang-format on */ +}; + +static const char *getlocale(char *buffer, size_t bufsize) +{ + const char *lang; + char *ptr; + + lang = SDL_getenv("LC_ALL"); + if (!lang) { + lang = SDL_getenv("LC_CTYPE"); + } + if (!lang) { + lang = SDL_getenv("LC_MESSAGES"); + } + if (!lang) { + lang = SDL_getenv("LANG"); + } + if (!lang || !*lang || SDL_strcmp(lang, "C") == 0) { + lang = "ASCII"; + } + + /* We need to trim down strings like "en_US.UTF-8@blah" to "UTF-8" */ + ptr = SDL_strchr(lang, '.'); + if (ptr) { + lang = ptr + 1; + } + + SDL_strlcpy(buffer, lang, bufsize); + ptr = SDL_strchr(buffer, '@'); + if (ptr) { + *ptr = '\0'; /* chop end of string. */ + } + + return buffer; +} + +SDL_iconv_t SDL_iconv_open(const char *tocode, const char *fromcode) +{ + int src_fmt = ENCODING_UNKNOWN; + int dst_fmt = ENCODING_UNKNOWN; + int i; + char fromcode_buffer[64]; + char tocode_buffer[64]; + + if (!fromcode || !*fromcode) { + fromcode = getlocale(fromcode_buffer, sizeof(fromcode_buffer)); + } + if (!tocode || !*tocode) { + tocode = getlocale(tocode_buffer, sizeof(tocode_buffer)); + } + for (i = 0; i < SDL_arraysize(encodings); ++i) { + if (SDL_strcasecmp(fromcode, encodings[i].name) == 0) { + src_fmt = encodings[i].format; + if (dst_fmt != ENCODING_UNKNOWN) { + break; + } + } + if (SDL_strcasecmp(tocode, encodings[i].name) == 0) { + dst_fmt = encodings[i].format; + if (src_fmt != ENCODING_UNKNOWN) { + break; + } + } + } + if (src_fmt != ENCODING_UNKNOWN && dst_fmt != ENCODING_UNKNOWN) { + SDL_iconv_t cd = (SDL_iconv_t)SDL_malloc(sizeof(*cd)); + if (cd) { + cd->src_fmt = src_fmt; + cd->dst_fmt = dst_fmt; + return cd; + } + } + return (SDL_iconv_t)-1; +} + +size_t +SDL_iconv(SDL_iconv_t cd, + const char **inbuf, size_t *inbytesleft, + char **outbuf, size_t *outbytesleft) +{ + /* For simplicity, we'll convert everything to and from UCS-4 */ + const char *src; + char *dst; + size_t srclen, dstlen; + Uint32 ch = 0; + size_t total; + + if (!inbuf || !*inbuf) { + /* Reset the context */ + return 0; + } + if (!outbuf || !*outbuf || !outbytesleft || !*outbytesleft) { + return SDL_ICONV_E2BIG; + } + src = *inbuf; + srclen = (inbytesleft ? *inbytesleft : 0); + dst = *outbuf; + dstlen = *outbytesleft; + + switch (cd->src_fmt) { + case ENCODING_UTF16: + /* Scan for a byte order marker */ + { + Uint8 *p = (Uint8 *)src; + size_t n = srclen / 2; + while (n) { + if (p[0] == 0xFF && p[1] == 0xFE) { + cd->src_fmt = ENCODING_UTF16BE; + break; + } else if (p[0] == 0xFE && p[1] == 0xFF) { + cd->src_fmt = ENCODING_UTF16LE; + break; + } + p += 2; + --n; + } + if (n == 0) { + /* We can't tell, default to host order */ + cd->src_fmt = ENCODING_UTF16NATIVE; + } + } + break; + case ENCODING_UTF32: + /* Scan for a byte order marker */ + { + Uint8 *p = (Uint8 *)src; + size_t n = srclen / 4; + while (n) { + if (p[0] == 0xFF && p[1] == 0xFE && + p[2] == 0x00 && p[3] == 0x00) { + cd->src_fmt = ENCODING_UTF32BE; + break; + } else if (p[0] == 0x00 && p[1] == 0x00 && + p[2] == 0xFE && p[3] == 0xFF) { + cd->src_fmt = ENCODING_UTF32LE; + break; + } + p += 4; + --n; + } + if (n == 0) { + /* We can't tell, default to host order */ + cd->src_fmt = ENCODING_UTF32NATIVE; + } + } + break; + } + + switch (cd->dst_fmt) { + case ENCODING_UTF16: + /* Default to host order, need to add byte order marker */ + if (dstlen < 2) { + return SDL_ICONV_E2BIG; + } + *(Uint16 *)dst = UNICODE_BOM; + dst += 2; + dstlen -= 2; + cd->dst_fmt = ENCODING_UTF16NATIVE; + break; + case ENCODING_UTF32: + /* Default to host order, need to add byte order marker */ + if (dstlen < 4) { + return SDL_ICONV_E2BIG; + } + *(Uint32 *)dst = UNICODE_BOM; + dst += 4; + dstlen -= 4; + cd->dst_fmt = ENCODING_UTF32NATIVE; + break; + } + + total = 0; + while (srclen > 0) { + /* Decode a character */ + switch (cd->src_fmt) { + case ENCODING_ASCII: + { + Uint8 *p = (Uint8 *)src; + ch = (Uint32)(p[0] & 0x7F); + ++src; + --srclen; + } break; + case ENCODING_LATIN1: + { + Uint8 *p = (Uint8 *)src; + ch = (Uint32)p[0]; + ++src; + --srclen; + } break; + case ENCODING_UTF8: /* RFC 3629 */ + { + Uint8 *p = (Uint8 *)src; + size_t left = 0; + SDL_bool overlong = SDL_FALSE; + if (p[0] >= 0xF0) { + if ((p[0] & 0xF8) != 0xF0) { + /* Skip illegal sequences + return SDL_ICONV_EILSEQ; + */ + ch = UNKNOWN_UNICODE; + } else { + if (p[0] == 0xF0 && srclen > 1 && (p[1] & 0xF0) == 0x80) { + overlong = SDL_TRUE; + } + ch = (Uint32)(p[0] & 0x07); + left = 3; + } + } else if (p[0] >= 0xE0) { + if ((p[0] & 0xF0) != 0xE0) { + /* Skip illegal sequences + return SDL_ICONV_EILSEQ; + */ + ch = UNKNOWN_UNICODE; + } else { + if (p[0] == 0xE0 && srclen > 1 && (p[1] & 0xE0) == 0x80) { + overlong = SDL_TRUE; + } + ch = (Uint32)(p[0] & 0x0F); + left = 2; + } + } else if (p[0] >= 0xC0) { + if ((p[0] & 0xE0) != 0xC0) { + /* Skip illegal sequences + return SDL_ICONV_EILSEQ; + */ + ch = UNKNOWN_UNICODE; + } else { + if ((p[0] & 0xDE) == 0xC0) { + overlong = SDL_TRUE; + } + ch = (Uint32)(p[0] & 0x1F); + left = 1; + } + } else { + if (p[0] & 0x80) { + /* Skip illegal sequences + return SDL_ICONV_EILSEQ; + */ + ch = UNKNOWN_UNICODE; + } else { + ch = (Uint32)p[0]; + } + } + ++src; + --srclen; + if (srclen < left) { + return SDL_ICONV_EINVAL; + } + while (left--) { + ++p; + if ((p[0] & 0xC0) != 0x80) { + /* Skip illegal sequences + return SDL_ICONV_EILSEQ; + */ + ch = UNKNOWN_UNICODE; + break; + } + ch <<= 6; + ch |= (p[0] & 0x3F); + ++src; + --srclen; + } + if (overlong) { + /* Potential security risk + return SDL_ICONV_EILSEQ; + */ + ch = UNKNOWN_UNICODE; + } + if ((ch >= 0xD800 && ch <= 0xDFFF) || + (ch == 0xFFFE || ch == 0xFFFF) || ch > 0x10FFFF) { + /* Skip illegal sequences + return SDL_ICONV_EILSEQ; + */ + ch = UNKNOWN_UNICODE; + } + } break; + case ENCODING_UTF16BE: /* RFC 2781 */ + { + Uint8 *p = (Uint8 *)src; + Uint16 W1, W2; + if (srclen < 2) { + return SDL_ICONV_EINVAL; + } + W1 = ((Uint16)p[0] << 8) | (Uint16)p[1]; + src += 2; + srclen -= 2; + if (W1 < 0xD800 || W1 > 0xDFFF) { + ch = (Uint32)W1; + break; + } + if (W1 > 0xDBFF) { + /* Skip illegal sequences + return SDL_ICONV_EILSEQ; + */ + ch = UNKNOWN_UNICODE; + break; + } + if (srclen < 2) { + return SDL_ICONV_EINVAL; + } + p = (Uint8 *)src; + W2 = ((Uint16)p[0] << 8) | (Uint16)p[1]; + src += 2; + srclen -= 2; + if (W2 < 0xDC00 || W2 > 0xDFFF) { + /* Skip illegal sequences + return SDL_ICONV_EILSEQ; + */ + ch = UNKNOWN_UNICODE; + break; + } + ch = (((Uint32)(W1 & 0x3FF) << 10) | + (Uint32)(W2 & 0x3FF)) + + 0x10000; + } break; + case ENCODING_UTF16LE: /* RFC 2781 */ + { + Uint8 *p = (Uint8 *)src; + Uint16 W1, W2; + if (srclen < 2) { + return SDL_ICONV_EINVAL; + } + W1 = ((Uint16)p[1] << 8) | (Uint16)p[0]; + src += 2; + srclen -= 2; + if (W1 < 0xD800 || W1 > 0xDFFF) { + ch = (Uint32)W1; + break; + } + if (W1 > 0xDBFF) { + /* Skip illegal sequences + return SDL_ICONV_EILSEQ; + */ + ch = UNKNOWN_UNICODE; + break; + } + if (srclen < 2) { + return SDL_ICONV_EINVAL; + } + p = (Uint8 *)src; + W2 = ((Uint16)p[1] << 8) | (Uint16)p[0]; + src += 2; + srclen -= 2; + if (W2 < 0xDC00 || W2 > 0xDFFF) { + /* Skip illegal sequences + return SDL_ICONV_EILSEQ; + */ + ch = UNKNOWN_UNICODE; + break; + } + ch = (((Uint32)(W1 & 0x3FF) << 10) | + (Uint32)(W2 & 0x3FF)) + + 0x10000; + } break; + case ENCODING_UCS2LE: + { + Uint8 *p = (Uint8 *)src; + if (srclen < 2) { + return SDL_ICONV_EINVAL; + } + ch = ((Uint32)p[1] << 8) | (Uint32)p[0]; + src += 2; + srclen -= 2; + } break; + case ENCODING_UCS2BE: + { + Uint8 *p = (Uint8 *)src; + if (srclen < 2) { + return SDL_ICONV_EINVAL; + } + ch = ((Uint32)p[0] << 8) | (Uint32)p[1]; + src += 2; + srclen -= 2; + } break; + case ENCODING_UCS4BE: + case ENCODING_UTF32BE: + { + Uint8 *p = (Uint8 *)src; + if (srclen < 4) { + return SDL_ICONV_EINVAL; + } + ch = ((Uint32)p[0] << 24) | + ((Uint32)p[1] << 16) | + ((Uint32)p[2] << 8) | (Uint32)p[3]; + src += 4; + srclen -= 4; + } break; + case ENCODING_UCS4LE: + case ENCODING_UTF32LE: + { + Uint8 *p = (Uint8 *)src; + if (srclen < 4) { + return SDL_ICONV_EINVAL; + } + ch = ((Uint32)p[3] << 24) | + ((Uint32)p[2] << 16) | + ((Uint32)p[1] << 8) | (Uint32)p[0]; + src += 4; + srclen -= 4; + } break; + } + + /* Encode a character */ + switch (cd->dst_fmt) { + case ENCODING_ASCII: + { + Uint8 *p = (Uint8 *)dst; + if (dstlen < 1) { + return SDL_ICONV_E2BIG; + } + if (ch > 0x7F) { + *p = UNKNOWN_ASCII; + } else { + *p = (Uint8)ch; + } + ++dst; + --dstlen; + } break; + case ENCODING_LATIN1: + { + Uint8 *p = (Uint8 *)dst; + if (dstlen < 1) { + return SDL_ICONV_E2BIG; + } + if (ch > 0xFF) { + *p = UNKNOWN_ASCII; + } else { + *p = (Uint8)ch; + } + ++dst; + --dstlen; + } break; + case ENCODING_UTF8: /* RFC 3629 */ + { + Uint8 *p = (Uint8 *)dst; + if (ch > 0x10FFFF) { + ch = UNKNOWN_UNICODE; + } + if (ch <= 0x7F) { + if (dstlen < 1) { + return SDL_ICONV_E2BIG; + } + *p = (Uint8)ch; + ++dst; + --dstlen; + } else if (ch <= 0x7FF) { + if (dstlen < 2) { + return SDL_ICONV_E2BIG; + } + p[0] = 0xC0 | (Uint8)((ch >> 6) & 0x1F); + p[1] = 0x80 | (Uint8)(ch & 0x3F); + dst += 2; + dstlen -= 2; + } else if (ch <= 0xFFFF) { + if (dstlen < 3) { + return SDL_ICONV_E2BIG; + } + p[0] = 0xE0 | (Uint8)((ch >> 12) & 0x0F); + p[1] = 0x80 | (Uint8)((ch >> 6) & 0x3F); + p[2] = 0x80 | (Uint8)(ch & 0x3F); + dst += 3; + dstlen -= 3; + } else { + if (dstlen < 4) { + return SDL_ICONV_E2BIG; + } + p[0] = 0xF0 | (Uint8)((ch >> 18) & 0x07); + p[1] = 0x80 | (Uint8)((ch >> 12) & 0x3F); + p[2] = 0x80 | (Uint8)((ch >> 6) & 0x3F); + p[3] = 0x80 | (Uint8)(ch & 0x3F); + dst += 4; + dstlen -= 4; + } + } break; + case ENCODING_UTF16BE: /* RFC 2781 */ + { + Uint8 *p = (Uint8 *)dst; + if (ch > 0x10FFFF) { + ch = UNKNOWN_UNICODE; + } + if (ch < 0x10000) { + if (dstlen < 2) { + return SDL_ICONV_E2BIG; + } + p[0] = (Uint8)(ch >> 8); + p[1] = (Uint8)ch; + dst += 2; + dstlen -= 2; + } else { + Uint16 W1, W2; + if (dstlen < 4) { + return SDL_ICONV_E2BIG; + } + ch = ch - 0x10000; + W1 = 0xD800 | (Uint16)((ch >> 10) & 0x3FF); + W2 = 0xDC00 | (Uint16)(ch & 0x3FF); + p[0] = (Uint8)(W1 >> 8); + p[1] = (Uint8)W1; + p[2] = (Uint8)(W2 >> 8); + p[3] = (Uint8)W2; + dst += 4; + dstlen -= 4; + } + } break; + case ENCODING_UTF16LE: /* RFC 2781 */ + { + Uint8 *p = (Uint8 *)dst; + if (ch > 0x10FFFF) { + ch = UNKNOWN_UNICODE; + } + if (ch < 0x10000) { + if (dstlen < 2) { + return SDL_ICONV_E2BIG; + } + p[1] = (Uint8)(ch >> 8); + p[0] = (Uint8)ch; + dst += 2; + dstlen -= 2; + } else { + Uint16 W1, W2; + if (dstlen < 4) { + return SDL_ICONV_E2BIG; + } + ch = ch - 0x10000; + W1 = 0xD800 | (Uint16)((ch >> 10) & 0x3FF); + W2 = 0xDC00 | (Uint16)(ch & 0x3FF); + p[1] = (Uint8)(W1 >> 8); + p[0] = (Uint8)W1; + p[3] = (Uint8)(W2 >> 8); + p[2] = (Uint8)W2; + dst += 4; + dstlen -= 4; + } + } break; + case ENCODING_UCS2BE: + { + Uint8 *p = (Uint8 *)dst; + if (ch > 0xFFFF) { + ch = UNKNOWN_UNICODE; + } + if (dstlen < 2) { + return SDL_ICONV_E2BIG; + } + p[0] = (Uint8)(ch >> 8); + p[1] = (Uint8)ch; + dst += 2; + dstlen -= 2; + } break; + case ENCODING_UCS2LE: + { + Uint8 *p = (Uint8 *)dst; + if (ch > 0xFFFF) { + ch = UNKNOWN_UNICODE; + } + if (dstlen < 2) { + return SDL_ICONV_E2BIG; + } + p[1] = (Uint8)(ch >> 8); + p[0] = (Uint8)ch; + dst += 2; + dstlen -= 2; + } break; + case ENCODING_UTF32BE: + if (ch > 0x10FFFF) { + ch = UNKNOWN_UNICODE; + } + SDL_FALLTHROUGH; + case ENCODING_UCS4BE: + if (ch > 0x7FFFFFFF) { + ch = UNKNOWN_UNICODE; + } + { + Uint8 *p = (Uint8 *)dst; + if (dstlen < 4) { + return SDL_ICONV_E2BIG; + } + p[0] = (Uint8)(ch >> 24); + p[1] = (Uint8)(ch >> 16); + p[2] = (Uint8)(ch >> 8); + p[3] = (Uint8)ch; + dst += 4; + dstlen -= 4; + } + break; + case ENCODING_UTF32LE: + if (ch > 0x10FFFF) { + ch = UNKNOWN_UNICODE; + } + SDL_FALLTHROUGH; + case ENCODING_UCS4LE: + if (ch > 0x7FFFFFFF) { + ch = UNKNOWN_UNICODE; + } + { + Uint8 *p = (Uint8 *)dst; + if (dstlen < 4) { + return SDL_ICONV_E2BIG; + } + p[3] = (Uint8)(ch >> 24); + p[2] = (Uint8)(ch >> 16); + p[1] = (Uint8)(ch >> 8); + p[0] = (Uint8)ch; + dst += 4; + dstlen -= 4; + } + break; + } + + /* Update state */ + *inbuf = src; + *inbytesleft = srclen; + *outbuf = dst; + *outbytesleft = dstlen; + ++total; + } + return total; +} + +int SDL_iconv_close(SDL_iconv_t cd) +{ + if (cd != (SDL_iconv_t)-1) { + SDL_free(cd); + } + return 0; +} + +#endif /* !HAVE_ICONV */ + +char *SDL_iconv_string(const char *tocode, const char *fromcode, const char *inbuf, size_t inbytesleft) +{ + SDL_iconv_t cd; + char *string; + size_t stringsize; + char *outbuf; + size_t outbytesleft; + size_t retCode = 0; + + if (!tocode || !*tocode) { + tocode = "UTF-8"; + } + if (!fromcode || !*fromcode) { + fromcode = "UTF-8"; + } + cd = SDL_iconv_open(tocode, fromcode); + if (cd == (SDL_iconv_t)-1) { + return NULL; + } + + stringsize = inbytesleft; + string = (char *)SDL_malloc(stringsize + sizeof(Uint32)); + if (!string) { + SDL_iconv_close(cd); + return NULL; + } + outbuf = string; + outbytesleft = stringsize; + SDL_memset(outbuf, 0, sizeof(Uint32)); + + while (inbytesleft > 0) { + const size_t oldinbytesleft = inbytesleft; + retCode = SDL_iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft); + switch (retCode) { + case SDL_ICONV_E2BIG: + { + const ptrdiff_t diff = (ptrdiff_t) (outbuf - string); + char *oldstring = string; + stringsize *= 2; + string = (char *)SDL_realloc(string, stringsize + sizeof(Uint32)); + if (!string) { + SDL_free(oldstring); + SDL_iconv_close(cd); + return NULL; + } + outbuf = string + diff; + outbytesleft = stringsize - diff; + SDL_memset(outbuf, 0, sizeof(Uint32)); + continue; + } + case SDL_ICONV_EILSEQ: + /* Try skipping some input data - not perfect, but... */ + ++inbuf; + --inbytesleft; + break; + case SDL_ICONV_EINVAL: + case SDL_ICONV_ERROR: + /* We can't continue... */ + inbytesleft = 0; + break; + } + /* Avoid infinite loops when nothing gets converted */ + if (oldinbytesleft == inbytesleft) { + break; + } + } + SDL_memset(outbuf, 0, sizeof(Uint32)); + SDL_iconv_close(cd); + + return string; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/stdlib/SDL_malloc.c b/SDL2-2.30.5/src/stdlib/SDL_malloc.c similarity index 61% rename from SDL2-2.0.12/src/stdlib/SDL_malloc.c rename to SDL2-2.30.5/src/stdlib/SDL_malloc.c index 7c9f0d6..4c26661 100644 --- a/SDL2-2.0.12/src/stdlib/SDL_malloc.c +++ b/SDL2-2.30.5/src/stdlib/SDL_malloc.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -483,10 +483,12 @@ DEFAULT_MMAP_THRESHOLD default: 256K #ifndef WIN32 #ifdef _WIN32 #define WIN32 1 -#endif /* _WIN32 */ -#endif /* WIN32 */ +#endif /* _WIN32 */ +#endif /* WIN32 */ #ifdef WIN32 +#ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN +#endif #include #define HAVE_MMAP 1 #define HAVE_MORECORE 0 @@ -499,8 +501,8 @@ DEFAULT_MMAP_THRESHOLD default: 256K #define LACKS_ERRNO_H #define LACKS_FCNTL_H #define MALLOC_FAILURE_ACTION -#define MMAP_CLEARS 0 /* WINCE and some others apparently don't clear */ -#endif /* WIN32 */ +#define MMAP_CLEARS 0 /* WINCE and some others apparently don't clear */ +#endif /* WIN32 */ #ifdef __OS2__ #define INCL_DOS @@ -515,113 +517,113 @@ DEFAULT_MMAP_THRESHOLD default: 256K #ifndef HAVE_MORECORE #define HAVE_MORECORE 0 #define HAVE_MMAP 1 -#endif /* HAVE_MORECORE */ -#endif /* DARWIN */ +#endif /* HAVE_MORECORE */ +#endif /* DARWIN */ #ifndef LACKS_SYS_TYPES_H -#include /* For size_t */ -#endif /* LACKS_SYS_TYPES_H */ +#include /* For size_t */ +#endif /* LACKS_SYS_TYPES_H */ /* The maximum possible size_t value has all bits set */ #define MAX_SIZE_T (~(size_t)0) #ifndef ONLY_MSPACES #define ONLY_MSPACES 0 -#endif /* ONLY_MSPACES */ +#endif /* ONLY_MSPACES */ #ifndef MSPACES #if ONLY_MSPACES #define MSPACES 1 -#else /* ONLY_MSPACES */ +#else /* ONLY_MSPACES */ #define MSPACES 0 -#endif /* ONLY_MSPACES */ -#endif /* MSPACES */ +#endif /* ONLY_MSPACES */ +#endif /* MSPACES */ #ifndef MALLOC_ALIGNMENT #define MALLOC_ALIGNMENT ((size_t)8U) -#endif /* MALLOC_ALIGNMENT */ +#endif /* MALLOC_ALIGNMENT */ #ifndef FOOTERS #define FOOTERS 0 -#endif /* FOOTERS */ +#endif /* FOOTERS */ #ifndef ABORT #define ABORT abort() -#endif /* ABORT */ +#endif /* ABORT */ #ifndef ABORT_ON_ASSERT_FAILURE #define ABORT_ON_ASSERT_FAILURE 1 -#endif /* ABORT_ON_ASSERT_FAILURE */ +#endif /* ABORT_ON_ASSERT_FAILURE */ #ifndef PROCEED_ON_ERROR #define PROCEED_ON_ERROR 0 -#endif /* PROCEED_ON_ERROR */ +#endif /* PROCEED_ON_ERROR */ #ifndef USE_LOCKS #define USE_LOCKS 0 -#endif /* USE_LOCKS */ +#endif /* USE_LOCKS */ #ifndef INSECURE #define INSECURE 0 -#endif /* INSECURE */ +#endif /* INSECURE */ #ifndef HAVE_MMAP #define HAVE_MMAP 1 -#endif /* HAVE_MMAP */ +#endif /* HAVE_MMAP */ #ifndef MMAP_CLEARS #define MMAP_CLEARS 1 -#endif /* MMAP_CLEARS */ +#endif /* MMAP_CLEARS */ #ifndef HAVE_MREMAP #ifdef linux #define HAVE_MREMAP 1 -#else /* linux */ +#else /* linux */ #define HAVE_MREMAP 0 -#endif /* linux */ -#endif /* HAVE_MREMAP */ +#endif /* linux */ +#endif /* HAVE_MREMAP */ #ifndef MALLOC_FAILURE_ACTION #define MALLOC_FAILURE_ACTION errno = ENOMEM; -#endif /* MALLOC_FAILURE_ACTION */ +#endif /* MALLOC_FAILURE_ACTION */ #ifndef HAVE_MORECORE #if ONLY_MSPACES #define HAVE_MORECORE 0 -#else /* ONLY_MSPACES */ +#else /* ONLY_MSPACES */ #define HAVE_MORECORE 1 -#endif /* ONLY_MSPACES */ -#endif /* HAVE_MORECORE */ +#endif /* ONLY_MSPACES */ +#endif /* HAVE_MORECORE */ #if !HAVE_MORECORE #define MORECORE_CONTIGUOUS 0 -#else /* !HAVE_MORECORE */ +#else /* !HAVE_MORECORE */ #ifndef MORECORE #define MORECORE sbrk -#endif /* MORECORE */ +#endif /* MORECORE */ #ifndef MORECORE_CONTIGUOUS #define MORECORE_CONTIGUOUS 1 -#endif /* MORECORE_CONTIGUOUS */ -#endif /* HAVE_MORECORE */ +#endif /* MORECORE_CONTIGUOUS */ +#endif /* HAVE_MORECORE */ #ifndef DEFAULT_GRANULARITY #if MORECORE_CONTIGUOUS -#define DEFAULT_GRANULARITY (0) /* 0 means to compute in init_mparams */ -#else /* MORECORE_CONTIGUOUS */ +#define DEFAULT_GRANULARITY (0) /* 0 means to compute in init_mparams */ +#else /* MORECORE_CONTIGUOUS */ #define DEFAULT_GRANULARITY ((size_t)64U * (size_t)1024U) -#endif /* MORECORE_CONTIGUOUS */ -#endif /* DEFAULT_GRANULARITY */ +#endif /* MORECORE_CONTIGUOUS */ +#endif /* DEFAULT_GRANULARITY */ #ifndef DEFAULT_TRIM_THRESHOLD #ifndef MORECORE_CANNOT_TRIM #define DEFAULT_TRIM_THRESHOLD ((size_t)2U * (size_t)1024U * (size_t)1024U) -#else /* MORECORE_CANNOT_TRIM */ +#else /* MORECORE_CANNOT_TRIM */ #define DEFAULT_TRIM_THRESHOLD MAX_SIZE_T -#endif /* MORECORE_CANNOT_TRIM */ -#endif /* DEFAULT_TRIM_THRESHOLD */ +#endif /* MORECORE_CANNOT_TRIM */ +#endif /* DEFAULT_TRIM_THRESHOLD */ #ifndef DEFAULT_MMAP_THRESHOLD #if HAVE_MMAP #define DEFAULT_MMAP_THRESHOLD ((size_t)256U * (size_t)1024U) -#else /* HAVE_MMAP */ +#else /* HAVE_MMAP */ #define DEFAULT_MMAP_THRESHOLD MAX_SIZE_T -#endif /* HAVE_MMAP */ -#endif /* DEFAULT_MMAP_THRESHOLD */ +#endif /* HAVE_MMAP */ +#endif /* DEFAULT_MMAP_THRESHOLD */ #ifndef USE_BUILTIN_FFS #define USE_BUILTIN_FFS 0 -#endif /* USE_BUILTIN_FFS */ +#endif /* USE_BUILTIN_FFS */ #ifndef USE_DEV_RANDOM #define USE_DEV_RANDOM 0 -#endif /* USE_DEV_RANDOM */ +#endif /* USE_DEV_RANDOM */ #ifndef NO_MALLINFO #define NO_MALLINFO 0 -#endif /* NO_MALLINFO */ +#endif /* NO_MALLINFO */ #ifndef MALLINFO_FIELD_TYPE #define MALLINFO_FIELD_TYPE size_t -#endif /* MALLINFO_FIELD_TYPE */ +#endif /* MALLINFO_FIELD_TYPE */ #ifndef memset #define memset SDL_memset @@ -672,27 +674,25 @@ DEFAULT_MMAP_THRESHOLD default: 256K #include "/usr/include/malloc.h" #else /* HAVE_USR_INCLUDE_MALLOC_H */ -struct mallinfo -{ - MALLINFO_FIELD_TYPE arena; /* non-mmapped space allocated from system */ - MALLINFO_FIELD_TYPE ordblks; /* number of free chunks */ - MALLINFO_FIELD_TYPE smblks; /* always 0 */ - MALLINFO_FIELD_TYPE hblks; /* always 0 */ - MALLINFO_FIELD_TYPE hblkhd; /* space in mmapped regions */ - MALLINFO_FIELD_TYPE usmblks; /* maximum total allocated space */ - MALLINFO_FIELD_TYPE fsmblks; /* always 0 */ - MALLINFO_FIELD_TYPE uordblks; /* total allocated space */ - MALLINFO_FIELD_TYPE fordblks; /* total free space */ - MALLINFO_FIELD_TYPE keepcost; /* releasable (via malloc_trim) space */ +struct mallinfo { + MALLINFO_FIELD_TYPE arena; /* non-mmapped space allocated from system */ + MALLINFO_FIELD_TYPE ordblks; /* number of free chunks */ + MALLINFO_FIELD_TYPE smblks; /* always 0 */ + MALLINFO_FIELD_TYPE hblks; /* always 0 */ + MALLINFO_FIELD_TYPE hblkhd; /* space in mmapped regions */ + MALLINFO_FIELD_TYPE usmblks; /* maximum total allocated space */ + MALLINFO_FIELD_TYPE fsmblks; /* always 0 */ + MALLINFO_FIELD_TYPE uordblks; /* total allocated space */ + MALLINFO_FIELD_TYPE fordblks; /* total free space */ + MALLINFO_FIELD_TYPE keepcost; /* releasable (via malloc_trim) space */ }; #endif /* HAVE_USR_INCLUDE_MALLOC_H */ #endif /* NO_MALLINFO */ #ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ +extern "C" { +#endif /* __cplusplus */ #if !ONLY_MSPACES @@ -715,7 +715,7 @@ extern "C" #define dlmalloc_max_footprint malloc_max_footprint #define dlindependent_calloc independent_calloc #define dlindependent_comalloc independent_comalloc -#endif /* USE_DL_PREFIX */ +#endif /* USE_DL_PREFIX */ /* @@ -732,7 +732,7 @@ extern "C" maximum supported value of n differs across systems, but is in all cases less than the maximum representable value of a size_t. */ - void *dlmalloc(size_t); +void* SDLCALL dlmalloc(size_t); /* free(void* p) @@ -741,14 +741,14 @@ extern "C" It has no effect if p is null. If p was not malloced or already freed, free(p) will by default cause the current program to abort. */ - void dlfree(void *); +void SDLCALL dlfree(void*); /* calloc(size_t n_elements, size_t element_size); Returns a pointer to n_elements * element_size bytes, with all locations set to zero. */ - void *dlcalloc(size_t, size_t); +void* SDLCALL dlcalloc(size_t, size_t); /* realloc(void* p, size_t n) @@ -773,7 +773,7 @@ extern "C" to be used as an argument to realloc is not supported. */ - void *dlrealloc(void *, size_t); +void* SDLCALL dlrealloc(void*, size_t); /* memalign(size_t alignment, size_t n); @@ -787,14 +787,14 @@ extern "C" Overreliance on memalign is a sure way to fragment space. */ - void *dlmemalign(size_t, size_t); +void* dlmemalign(size_t, size_t); /* valloc(size_t n); Equivalent to memalign(pagesize, n), where pagesize is the page size of the system. If the pagesize is unknown, 4096 is used. */ - void *dlvalloc(size_t); +void* dlvalloc(size_t); /* mallopt(int parameter_number, int parameter_value) @@ -814,7 +814,7 @@ extern "C" M_GRANULARITY -2 page size any power of 2 >= page size M_MMAP_THRESHOLD -3 256*1024 any (or 0 if no MMAP support) */ - int dlmallopt(int, int); +int dlmallopt(int, int); /* malloc_footprint(); @@ -825,7 +825,7 @@ extern "C" Even if locks are otherwise defined, this function does not use them, so results might not be up to date. */ - size_t dlmalloc_footprint(void); +size_t dlmalloc_footprint(void); /* malloc_max_footprint(); @@ -838,7 +838,7 @@ extern "C" otherwise defined, this function does not use them, so results might not be up to date. */ - size_t dlmalloc_max_footprint(void); +size_t dlmalloc_max_footprint(void); #if !NO_MALLINFO /* @@ -863,8 +863,8 @@ extern "C" be kept as longs, the reported values may wrap around zero and thus be inaccurate. */ - struct mallinfo dlmallinfo(void); -#endif /* NO_MALLINFO */ +struct mallinfo dlmallinfo(void); +#endif /* NO_MALLINFO */ /* independent_calloc(size_t n_elements, size_t element_size, void* chunks[]); @@ -918,7 +918,7 @@ extern "C" return first; } */ - void **dlindependent_calloc(size_t, size_t, void **); +void** dlindependent_calloc(size_t, size_t, void**); /* independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]); @@ -979,7 +979,7 @@ extern "C" since it cannot reuse existing noncontiguous small chunks that might be available for some of the elements. */ - void **dlindependent_comalloc(size_t, size_t *, void **); +void** dlindependent_comalloc(size_t, size_t*, void**); /* @@ -987,7 +987,7 @@ extern "C" Equivalent to valloc(minimum-page-that-holds(n)), that is, round up n to nearest pagesize. */ - void *dlpvalloc(size_t); +void* dlpvalloc(size_t); /* malloc_trim(size_t pad); @@ -1010,7 +1010,7 @@ extern "C" Malloc_trim returns 1 if it actually released any memory, else 0. */ - int dlmalloc_trim(size_t); +int dlmalloc_trim(size_t); /* malloc_usable_size(void* p); @@ -1026,7 +1026,7 @@ extern "C" p = malloc(n); assert(malloc_usable_size(p) >= 256); */ - size_t dlmalloc_usable_size(void *); +size_t dlmalloc_usable_size(void*); /* malloc_stats(); @@ -1047,9 +1047,9 @@ extern "C" malloc_stats prints only the most commonly interesting statistics. More information can be obtained by calling mallinfo. */ - void dlmalloc_stats(void); +void dlmalloc_stats(void); -#endif /* ONLY_MSPACES */ +#endif /* ONLY_MSPACES */ #if MSPACES @@ -1057,7 +1057,7 @@ extern "C" mspace is an opaque type representing an independent region of space that supports mspace_malloc, etc. */ - typedef void *mspace; +typedef void* mspace; /* create_mspace creates and returns a new independent space with the @@ -1070,7 +1070,7 @@ extern "C" compiling with a different DEFAULT_GRANULARITY or dynamically setting with mallopt(M_GRANULARITY, value). */ - mspace create_mspace(size_t capacity, int locked); +mspace create_mspace(size_t capacity, int locked); /* destroy_mspace destroys the given space, and attempts to return all @@ -1078,7 +1078,7 @@ extern "C" bytes freed. After destruction, the results of access to all memory used by the space become undefined. */ - size_t destroy_mspace(mspace msp); +size_t destroy_mspace(mspace msp); /* create_mspace_with_base uses the memory supplied as the initial base @@ -1089,13 +1089,13 @@ extern "C" Destroying this space will deallocate all additionally allocated space (if possible) but not the initial base. */ - mspace create_mspace_with_base(void *base, size_t capacity, int locked); +mspace create_mspace_with_base(void* base, size_t capacity, int locked); /* mspace_malloc behaves as malloc, but operates within the given space. */ - void *mspace_malloc(mspace msp, size_t bytes); +void* mspace_malloc(mspace msp, size_t bytes); /* mspace_free behaves as free, but operates within @@ -1105,7 +1105,7 @@ extern "C" free may be called instead of mspace_free because freed chunks from any space are handled by their originating spaces. */ - void mspace_free(mspace msp, void *mem); +void mspace_free(mspace msp, void* mem); /* mspace_realloc behaves as realloc, but operates within @@ -1116,45 +1116,45 @@ extern "C" realloced chunks from any space are handled by their originating spaces. */ - void *mspace_realloc(mspace msp, void *mem, size_t newsize); +void* mspace_realloc(mspace msp, void* mem, size_t newsize); /* mspace_calloc behaves as calloc, but operates within the given space. */ - void *mspace_calloc(mspace msp, size_t n_elements, size_t elem_size); +void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size); /* mspace_memalign behaves as memalign, but operates within the given space. */ - void *mspace_memalign(mspace msp, size_t alignment, size_t bytes); +void* mspace_memalign(mspace msp, size_t alignment, size_t bytes); /* mspace_independent_calloc behaves as independent_calloc, but operates within the given space. */ - void **mspace_independent_calloc(mspace msp, size_t n_elements, - size_t elem_size, void *chunks[]); +void** mspace_independent_calloc(mspace msp, size_t n_elements, + size_t elem_size, void* chunks[]); /* mspace_independent_comalloc behaves as independent_comalloc, but operates within the given space. */ - void **mspace_independent_comalloc(mspace msp, size_t n_elements, - size_t sizes[], void *chunks[]); +void** mspace_independent_comalloc(mspace msp, size_t n_elements, + size_t sizes[], void* chunks[]); /* mspace_footprint() returns the number of bytes obtained from the system for this space. */ - size_t mspace_footprint(mspace msp); +size_t mspace_footprint(mspace msp); /* mspace_max_footprint() returns the peak number of bytes obtained from the system for this space. */ - size_t mspace_max_footprint(mspace msp); +size_t mspace_max_footprint(mspace msp); #if !NO_MALLINFO @@ -1162,30 +1162,30 @@ extern "C" mspace_mallinfo behaves as mallinfo, but reports properties of the given space. */ - struct mallinfo mspace_mallinfo(mspace msp); -#endif /* NO_MALLINFO */ +struct mallinfo mspace_mallinfo(mspace msp); +#endif /* NO_MALLINFO */ /* mspace_malloc_stats behaves as malloc_stats, but reports properties of the given space. */ - void mspace_malloc_stats(mspace msp); +void mspace_malloc_stats(mspace msp); /* mspace_trim behaves as malloc_trim, but operates within the given space. */ - int mspace_trim(mspace msp, size_t pad); +int mspace_trim(mspace msp, size_t pad); /* An alias for mallopt. */ - int mspace_mallopt(int, int); +int mspace_mallopt(int, int); -#endif /* MSPACES */ +#endif /* MSPACES */ #ifdef __cplusplus -}; /* end of extern "C" */ +}; /* end of extern "C" */ #endif /* __cplusplus */ /* @@ -1201,21 +1201,21 @@ extern "C" /*------------------------------ internal #includes ---------------------- */ #ifdef _MSC_VER -#pragma warning( disable : 4146 ) /* no "unsigned" warnings */ +#pragma warning( disable : 4146 ) /* no "unsigned" warnings */ #endif /* _MSC_VER */ #ifndef LACKS_STDIO_H -#include /* for printing in malloc_stats */ +#include /* for printing in malloc_stats */ #endif #ifndef LACKS_ERRNO_H -#include /* for MALLOC_FAILURE_ACTION */ +#include /* for MALLOC_FAILURE_ACTION */ #endif /* LACKS_ERRNO_H */ #if FOOTERS -#include /* for magic initialization */ +#include /* for magic initialization */ #endif /* FOOTERS */ #ifndef LACKS_STDLIB_H -#include /* for abort() */ +#include /* for abort() */ #endif /* LACKS_STDLIB_H */ #ifdef DEBUG #if ABORT_ON_ASSERT_FAILURE @@ -1223,20 +1223,20 @@ extern "C" #else /* ABORT_ON_ASSERT_FAILURE */ #include #endif /* ABORT_ON_ASSERT_FAILURE */ -#else /* DEBUG */ +#else /* DEBUG */ #define assert(x) #endif /* DEBUG */ #ifndef LACKS_STRING_H -#include /* for memset etc */ -#endif /* LACKS_STRING_H */ +#include /* for memset etc */ +#endif /* LACKS_STRING_H */ #if USE_BUILTIN_FFS #ifndef LACKS_STRINGS_H -#include /* for ffs */ +#include /* for ffs */ #endif /* LACKS_STRINGS_H */ #endif /* USE_BUILTIN_FFS */ #if HAVE_MMAP #ifndef LACKS_SYS_MMAN_H -#include /* for mmap */ +#include /* for mmap */ #endif /* LACKS_SYS_MMAN_H */ #ifndef LACKS_FCNTL_H #include @@ -1244,17 +1244,17 @@ extern "C" #endif /* HAVE_MMAP */ #if HAVE_MORECORE #ifndef LACKS_UNISTD_H -#include /* for sbrk */ +#include /* for sbrk */ #else /* LACKS_UNISTD_H */ -#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) -extern void *sbrk(ptrdiff_t); +#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__DragonFly__) +extern void* sbrk(ptrdiff_t); #endif /* FreeBSD etc */ #endif /* LACKS_UNISTD_H */ #endif /* HAVE_MMAP */ #ifndef WIN32 #ifndef malloc_getpagesize -# ifdef _SC_PAGESIZE /* some SVR4 systems omit an underscore */ +# ifdef _SC_PAGESIZE /* some SVR4 systems omit an underscore */ # ifndef _SC_PAGE_SIZE # define _SC_PAGE_SIZE _SC_PAGESIZE # endif @@ -1263,10 +1263,10 @@ extern void *sbrk(ptrdiff_t); # define malloc_getpagesize sysconf(_SC_PAGE_SIZE) # else # if defined(BSD) || defined(DGUX) || defined(HAVE_GETPAGESIZE) -extern size_t getpagesize(); + extern size_t getpagesize(); # define malloc_getpagesize getpagesize() # else -# ifdef WIN32 /* use supplied emulation of getpagesize */ +# ifdef WIN32 /* use supplied emulation of getpagesize */ # define malloc_getpagesize getpagesize() # else # ifndef LACKS_SYS_PARAM_H @@ -1337,7 +1337,7 @@ extern size_t getpagesize(); /* MORECORE and MMAP must return MFAIL on failure */ #define MFAIL ((void*)(MAX_SIZE_T)) -#define CMFAIL ((char*)(MFAIL)) /* defined for convenience */ +#define CMFAIL ((char*)(MFAIL)) /* defined for convenience */ #if !HAVE_MMAP #define IS_MMAPPED_BIT (SIZE_T_ZERO) @@ -1350,7 +1350,7 @@ extern size_t getpagesize(); #define IS_MMAPPED_BIT (SIZE_T_ONE) #define USE_MMAP_BIT (SIZE_T_ONE) -#if !defined(WIN32) && !defined (__OS2__) +#if !defined(WIN32) && !defined(__OS2__) #define CALL_MUNMAP(a, s) munmap((a), (s)) #define MMAP_PROT (PROT_READ|PROT_WRITE) #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) @@ -1365,7 +1365,7 @@ extern size_t getpagesize(); is unlikely to be needed, but is supplied just in case. */ #define MMAP_FLAGS (MAP_PRIVATE) -static int dev_zero_fd = -1; /* Cached file descriptor for /dev/zero. */ +static int dev_zero_fd = -1; /* Cached file descriptor for /dev/zero. */ #define CALL_MMAP(s) ((dev_zero_fd < 0) ? \ (dev_zero_fd = open("/dev/zero", O_RDWR), \ mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0)) : \ @@ -1412,41 +1412,34 @@ static int os2munmap(void* ptr, size_t size) { #else /* WIN32 */ /* Win32 MMAP via VirtualAlloc */ -static void * -win32mmap(size_t size) -{ - void *ptr = - VirtualAlloc(0, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); - return (ptr != 0) ? ptr : MFAIL; +static void* win32mmap(size_t size) { + void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); + return (ptr != 0)? ptr: MFAIL; } /* For direct MMAP, use MEM_TOP_DOWN to minimize interference */ -static void * -win32direct_mmap(size_t size) -{ - void *ptr = VirtualAlloc(0, size, MEM_RESERVE | MEM_COMMIT | MEM_TOP_DOWN, - PAGE_READWRITE); - return (ptr != 0) ? ptr : MFAIL; +static void* win32direct_mmap(size_t size) { + void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN, + PAGE_READWRITE); + return (ptr != 0)? ptr: MFAIL; } /* This function supports releasing coalesed segments */ -static int -win32munmap(void *ptr, size_t size) -{ - MEMORY_BASIC_INFORMATION minfo; - char *cptr = ptr; - while (size) { - if (VirtualQuery(cptr, &minfo, sizeof(minfo)) == 0) - return -1; - if (minfo.BaseAddress != cptr || minfo.AllocationBase != cptr || - minfo.State != MEM_COMMIT || minfo.RegionSize > size) - return -1; - if (VirtualFree(cptr, 0, MEM_RELEASE) == 0) - return -1; - cptr += minfo.RegionSize; - size -= minfo.RegionSize; - } - return 0; +static int win32munmap(void* ptr, size_t size) { + MEMORY_BASIC_INFORMATION minfo; + char* cptr = ptr; + while (size) { + if (VirtualQuery(cptr, &minfo, sizeof(minfo)) == 0) + return -1; + if (minfo.BaseAddress != cptr || minfo.AllocationBase != cptr || + minfo.State != MEM_COMMIT || minfo.RegionSize > size) + return -1; + if (VirtualFree(cptr, 0, MEM_RELEASE) == 0) + return -1; + cptr += minfo.RegionSize; + size -= minfo.RegionSize; + } + return 0; } #define CALL_MMAP(s) win32mmap(s) @@ -1457,13 +1450,13 @@ win32munmap(void *ptr, size_t size) #if HAVE_MMAP && HAVE_MREMAP #define CALL_MREMAP(addr, osz, nsz, mv) mremap((addr), (osz), (nsz), (mv)) -#else /* HAVE_MMAP && HAVE_MREMAP */ +#else /* HAVE_MMAP && HAVE_MREMAP */ #define CALL_MREMAP(addr, osz, nsz, mv) MFAIL #endif /* HAVE_MMAP && HAVE_MREMAP */ #if HAVE_MORECORE #define CALL_MORECORE(S) MORECORE(S) -#else /* HAVE_MORECORE */ +#else /* HAVE_MORECORE */ #define CALL_MORECORE(S) MFAIL #endif /* HAVE_MORECORE */ @@ -1523,25 +1516,21 @@ static MLOCK_T magic_init_mutex; */ #define MLOCK_T long -static int -win32_acquire_lock(MLOCK_T * sl) -{ - for (;;) { +static int win32_acquire_lock (MLOCK_T *sl) { + for (;;) { #ifdef InterlockedCompareExchangePointer - if (!InterlockedCompareExchange(sl, 1, 0)) - return 0; -#else /* Use older void* version */ - if (!InterlockedCompareExchange((void **) sl, (void *) 1, (void *) 0)) - return 0; + if (!InterlockedCompareExchange(sl, 1, 0)) + return 0; +#else /* Use older void* version */ + if (!InterlockedCompareExchange((void**)sl, (void*)1, (void*)0)) + return 0; #endif /* InterlockedCompareExchangePointer */ - Sleep(0); - } + Sleep (0); + } } -static void -win32_release_lock(MLOCK_T * sl) -{ - InterlockedExchange(sl, 0); +static void win32_release_lock (MLOCK_T *sl) { + InterlockedExchange (sl, 0); } #define INITIAL_LOCK(l) *(l)=0 @@ -1554,7 +1543,7 @@ static MLOCK_T magic_init_mutex; #endif /* WIN32 */ #define USE_LOCK_BIT (2U) -#else /* USE_LOCKS */ +#else /* USE_LOCKS */ #define USE_LOCK_BIT (0U) #define INITIAL_LOCK(l) #endif /* USE_LOCKS */ @@ -1570,7 +1559,7 @@ static MLOCK_T magic_init_mutex; #if USE_LOCKS #define ACQUIRE_MAGIC_INIT_LOCK() ACQUIRE_LOCK(&magic_init_mutex); #define RELEASE_MAGIC_INIT_LOCK() RELEASE_LOCK(&magic_init_mutex); -#else /* USE_LOCKS */ +#else /* USE_LOCKS */ #define ACQUIRE_MAGIC_INIT_LOCK() #define RELEASE_MAGIC_INIT_LOCK() #endif /* USE_LOCKS */ @@ -1713,20 +1702,19 @@ static MLOCK_T magic_init_mutex; */ -struct malloc_chunk -{ - size_t prev_foot; /* Size of previous chunk (if free). */ - size_t head; /* Size and inuse bits. */ - struct malloc_chunk *fd; /* double links -- used only if free. */ - struct malloc_chunk *bk; +struct malloc_chunk { + size_t prev_foot; /* Size of previous chunk (if free). */ + size_t head; /* Size and inuse bits. */ + struct malloc_chunk* fd; /* double links -- used only if free. */ + struct malloc_chunk* bk; }; -typedef struct malloc_chunk mchunk; -typedef struct malloc_chunk *mchunkptr; -typedef struct malloc_chunk *sbinptr; /* The type of bins of chunks */ -typedef size_t bindex_t; /* Described below */ -typedef unsigned int binmap_t; /* Described below */ -typedef unsigned int flag_t; /* The type of various bit flag sets */ +typedef struct malloc_chunk mchunk; +typedef struct malloc_chunk* mchunkptr; +typedef struct malloc_chunk* sbinptr; /* The type of bins of chunks */ +typedef size_t bindex_t; /* Described below */ +typedef unsigned int binmap_t; /* Described below */ +typedef unsigned int flag_t; /* The type of various bit flag sets */ /* ------------------- Chunks sizes and alignments ----------------------- */ @@ -1919,22 +1907,21 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ is of course much better. */ -struct malloc_tree_chunk -{ - /* The first four fields must be compatible with malloc_chunk */ - size_t prev_foot; - size_t head; - struct malloc_tree_chunk *fd; - struct malloc_tree_chunk *bk; +struct malloc_tree_chunk { + /* The first four fields must be compatible with malloc_chunk */ + size_t prev_foot; + size_t head; + struct malloc_tree_chunk* fd; + struct malloc_tree_chunk* bk; - struct malloc_tree_chunk *child[2]; - struct malloc_tree_chunk *parent; - bindex_t index; + struct malloc_tree_chunk* child[2]; + struct malloc_tree_chunk* parent; + bindex_t index; }; -typedef struct malloc_tree_chunk tchunk; -typedef struct malloc_tree_chunk *tchunkptr; -typedef struct malloc_tree_chunk *tbinptr; /* The type of bins of trees */ +typedef struct malloc_tree_chunk tchunk; +typedef struct malloc_tree_chunk* tchunkptr; +typedef struct malloc_tree_chunk* tbinptr; /* The type of bins of trees */ /* A little helper macro for trees */ #define leftmost_child(t) ((t)->child[0] != 0? (t)->child[0] : (t)->child[1]) @@ -1996,19 +1983,18 @@ typedef struct malloc_tree_chunk *tbinptr; /* The type of bins of trees */ and deallocated/trimmed using MORECORE with negative arguments. */ -struct malloc_segment -{ - char *base; /* base address */ - size_t size; /* allocated size */ - struct malloc_segment *next; /* ptr to next segment */ - flag_t sflags; /* mmap and extern flag */ +struct malloc_segment { + char* base; /* base address */ + size_t size; /* allocated size */ + struct malloc_segment* next; /* ptr to next segment */ + flag_t sflags; /* mmap and extern flag */ }; #define is_mmapped_segment(S) ((S)->sflags & IS_MMAPPED_BIT) #define is_extern_segment(S) ((S)->sflags & EXTERN_BIT) -typedef struct malloc_segment msegment; -typedef struct malloc_segment *msegmentptr; +typedef struct malloc_segment msegment; +typedef struct malloc_segment* msegmentptr; /* ---------------------------- malloc_state ----------------------------- */ @@ -2095,29 +2081,28 @@ typedef struct malloc_segment *msegmentptr; #define MAX_SMALL_SIZE (MIN_LARGE_SIZE - SIZE_T_ONE) #define MAX_SMALL_REQUEST (MAX_SMALL_SIZE - CHUNK_ALIGN_MASK - CHUNK_OVERHEAD) -struct malloc_state -{ - binmap_t smallmap; - binmap_t treemap; - size_t dvsize; - size_t topsize; - char *least_addr; - mchunkptr dv; - mchunkptr top; - size_t trim_check; - size_t magic; - mchunkptr smallbins[(NSMALLBINS + 1) * 2]; - tbinptr treebins[NTREEBINS]; - size_t footprint; - size_t max_footprint; - flag_t mflags; +struct malloc_state { + binmap_t smallmap; + binmap_t treemap; + size_t dvsize; + size_t topsize; + char* least_addr; + mchunkptr dv; + mchunkptr top; + size_t trim_check; + size_t magic; + mchunkptr smallbins[(NSMALLBINS+1)*2]; + tbinptr treebins[NTREEBINS]; + size_t footprint; + size_t max_footprint; + flag_t mflags; #if USE_LOCKS - MLOCK_T mutex; /* locate lock among fields that rarely change */ -#endif /* USE_LOCKS */ - msegment seg; + MLOCK_T mutex; /* locate lock among fields that rarely change */ +#endif /* USE_LOCKS */ + msegment seg; }; -typedef struct malloc_state *mstate; +typedef struct malloc_state* mstate; /* ------------- Global malloc_state and malloc_params ------------------- */ @@ -2127,14 +2112,13 @@ typedef struct malloc_state *mstate; initialized in init_mparams. */ -struct malloc_params -{ - size_t magic; - size_t page_size; - size_t granularity; - size_t mmap_threshold; - size_t trim_threshold; - flag_t default_mflags; +struct malloc_params { + size_t magic; + size_t page_size; + size_t granularity; + size_t mmap_threshold; + size_t trim_threshold; + flag_t default_mflags; }; static struct malloc_params mparams; @@ -2183,34 +2167,30 @@ static struct malloc_state _gm_; ((char*)(A) >= S->base && (char*)(A) < S->base + S->size) /* Return segment holding given address */ -static msegmentptr -segment_holding(mstate m, char *addr) -{ - msegmentptr sp = &m->seg; - for (;;) { - if (addr >= sp->base && addr < sp->base + sp->size) - return sp; - if ((sp = sp->next) == 0) - return 0; - } +static msegmentptr segment_holding(mstate m, char* addr) { + msegmentptr sp = &m->seg; + for (;;) { + if (addr >= sp->base && addr < sp->base + sp->size) + return sp; + if ((sp = sp->next) == 0) + return 0; + } } /* Return true if segment contains a segment link */ -static int -has_segment_link(mstate m, msegmentptr ss) -{ - msegmentptr sp = &m->seg; - for (;;) { - if ((char *) sp >= ss->base && (char *) sp < ss->base + ss->size) - return 1; - if ((sp = sp->next) == 0) - return 0; - } +static int has_segment_link(mstate m, msegmentptr ss) { + msegmentptr sp = &m->seg; + for (;;) { + if ((char*)sp >= ss->base && (char*)sp < ss->base + ss->size) + return 1; + if ((sp = sp->next) == 0) + return 0; + } } #ifndef MORECORE_CANNOT_TRIM #define should_trim(M,s) ((s) > (M)->trim_check) -#else /* MORECORE_CANNOT_TRIM */ +#else /* MORECORE_CANNOT_TRIM */ #define should_trim(M,s) (0) #endif /* MORECORE_CANNOT_TRIM */ @@ -2242,11 +2222,11 @@ has_segment_link(mstate m, msegmentptr ss) #ifndef PREACTION #define PREACTION(M) (0) -#endif /* PREACTION */ +#endif /* PREACTION */ #ifndef POSTACTION #define POSTACTION(M) -#endif /* POSTACTION */ +#endif /* POSTACTION */ #endif /* USE_LOCKS */ @@ -2283,7 +2263,7 @@ static void reset_on_error(mstate m); /* -------------------------- Debugging setup ---------------------------- */ -#if ! DEBUG +#ifndef DEBUG #define check_free_chunk(M,P) #define check_inuse_chunk(M,P) @@ -2300,17 +2280,17 @@ static void reset_on_error(mstate m); #define check_mmapped_chunk(M,P) do_check_mmapped_chunk(M,P) #define check_malloc_state(M) do_check_malloc_state(M) -static void do_check_any_chunk(mstate m, mchunkptr p); -static void do_check_top_chunk(mstate m, mchunkptr p); -static void do_check_mmapped_chunk(mstate m, mchunkptr p); -static void do_check_inuse_chunk(mstate m, mchunkptr p); -static void do_check_free_chunk(mstate m, mchunkptr p); -static void do_check_malloced_chunk(mstate m, void *mem, size_t s); -static void do_check_tree(mstate m, tchunkptr t); -static void do_check_treebin(mstate m, bindex_t i); -static void do_check_smallbin(mstate m, bindex_t i); -static void do_check_malloc_state(mstate m); -static int bin_find(mstate m, mchunkptr x); +static void do_check_any_chunk(mstate m, mchunkptr p); +static void do_check_top_chunk(mstate m, mchunkptr p); +static void do_check_mmapped_chunk(mstate m, mchunkptr p); +static void do_check_inuse_chunk(mstate m, mchunkptr p); +static void do_check_free_chunk(mstate m, mchunkptr p); +static void do_check_malloced_chunk(mstate m, void* mem, size_t s); +static void do_check_tree(mstate m, tchunkptr t); +static void do_check_treebin(mstate m, bindex_t i); +static void do_check_smallbin(mstate m, bindex_t i); +static void do_check_malloc_state(mstate m); +static int bin_find(mstate m, mchunkptr x); static size_t traverse_and_check(mstate m); #endif /* DEBUG */ @@ -2326,7 +2306,7 @@ static size_t traverse_and_check(mstate m); #define treebin_at(M,i) (&((M)->treebins[i])) /* assign tree index for size S to variable I */ -#if defined(__GNUC__) && defined(i386) +#if defined(__GNUC__) && defined(__i386__) #define compute_tree_index(S, I)\ {\ size_t X = S >> TREEBIN_SHIFT;\ @@ -2391,7 +2371,7 @@ static size_t traverse_and_check(mstate m); /* index corresponding to given bit */ -#if defined(__GNUC__) && defined(i386) +#if defined(__GNUC__) && defined(__i386__) #define compute_bit2idx(X, I)\ {\ unsigned int J;\ @@ -2476,7 +2456,7 @@ static size_t traverse_and_check(mstate m); #if (FOOTERS && !INSECURE) /* Check if (alleged) mstate m has expected magic field */ #define ok_magic(M) ((M)->magic == mparams.magic) -#else /* (FOOTERS && !INSECURE) */ +#else /* (FOOTERS && !INSECURE) */ #define ok_magic(M) (1) #endif /* (FOOTERS && !INSECURE) */ @@ -2541,483 +2521,460 @@ static size_t traverse_and_check(mstate m); /* ---------------------------- setting mparams -------------------------- */ /* Initialize mparams */ -static int -init_mparams(void) -{ - if (mparams.page_size == 0) { - size_t s; +static int init_mparams(void) { + if (mparams.page_size == 0) { + size_t s; - mparams.mmap_threshold = DEFAULT_MMAP_THRESHOLD; - mparams.trim_threshold = DEFAULT_TRIM_THRESHOLD; + mparams.mmap_threshold = DEFAULT_MMAP_THRESHOLD; + mparams.trim_threshold = DEFAULT_TRIM_THRESHOLD; #if MORECORE_CONTIGUOUS - mparams.default_mflags = USE_LOCK_BIT | USE_MMAP_BIT; -#else /* MORECORE_CONTIGUOUS */ - mparams.default_mflags = - USE_LOCK_BIT | USE_MMAP_BIT | USE_NONCONTIGUOUS_BIT; + mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT; +#else /* MORECORE_CONTIGUOUS */ + mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT|USE_NONCONTIGUOUS_BIT; #endif /* MORECORE_CONTIGUOUS */ #if (FOOTERS && !INSECURE) - { + { #if USE_DEV_RANDOM - int fd; - unsigned char buf[sizeof(size_t)]; - /* Try to use /dev/urandom, else fall back on using time */ - if ((fd = open("/dev/urandom", O_RDONLY)) >= 0 && - read(fd, buf, sizeof(buf)) == sizeof(buf)) { - s = *((size_t *) buf); - close(fd); - } else + int fd; + unsigned char buf[sizeof(size_t)]; + /* Try to use /dev/urandom, else fall back on using time */ + if ((fd = open("/dev/urandom", O_RDONLY)) < 0) { + s = 0; + } else { + s = read(fd, buf, sizeof(buf)); + close(fd); + } + if (s == sizeof(buf)) + s = *((size_t *)buf); + else #endif /* USE_DEV_RANDOM */ - s = (size_t) (time(0) ^ (size_t) 0x55555555U); + s = (size_t)(time(0) ^ (size_t)0x55555555U); - s |= (size_t) 8U; /* ensure nonzero */ - s &= ~(size_t) 7U; /* improve chances of fault for bad values */ + s |= (size_t)8U; /* ensure nonzero */ + s &= ~(size_t)7U; /* improve chances of fault for bad values */ - } + } #else /* (FOOTERS && !INSECURE) */ - s = (size_t) 0x58585858U; + s = (size_t)0x58585858U; #endif /* (FOOTERS && !INSECURE) */ - ACQUIRE_MAGIC_INIT_LOCK(); - if (mparams.magic == 0) { - mparams.magic = s; - /* Set up lock for main malloc area */ - INITIAL_LOCK(&gm->mutex); - gm->mflags = mparams.default_mflags; - } - RELEASE_MAGIC_INIT_LOCK(); + (void)ACQUIRE_MAGIC_INIT_LOCK(); + if (mparams.magic == 0) { + mparams.magic = s; + /* Set up lock for main malloc area */ + INITIAL_LOCK(&gm->mutex); + gm->mflags = mparams.default_mflags; + } + RELEASE_MAGIC_INIT_LOCK(); #if !defined(WIN32) && !defined(__OS2__) - mparams.page_size = malloc_getpagesize; - mparams.granularity = ((DEFAULT_GRANULARITY != 0) ? - DEFAULT_GRANULARITY : mparams.page_size); + mparams.page_size = malloc_getpagesize; + mparams.granularity = ((DEFAULT_GRANULARITY != 0)? + DEFAULT_GRANULARITY : mparams.page_size); #elif defined (__OS2__) - /* if low-memory is used, os2munmap() would break - if it were anything other than 64k */ - mparams.page_size = 4096u; - mparams.granularity = 65536u; + /* if low-memory is used, os2munmap() would break + if it were anything other than 64k */ + mparams.page_size = 4096u; + mparams.granularity = 65536u; #else /* WIN32 */ - { - SYSTEM_INFO system_info; - GetSystemInfo(&system_info); - mparams.page_size = system_info.dwPageSize; - mparams.granularity = system_info.dwAllocationGranularity; - } + { + SYSTEM_INFO system_info; + GetSystemInfo(&system_info); + mparams.page_size = system_info.dwPageSize; + mparams.granularity = system_info.dwAllocationGranularity; + } #endif /* WIN32 */ - /* Sanity-check configuration: - size_t must be unsigned and as wide as pointer type. - ints must be at least 4 bytes. - alignment must be at least 8. - Alignment, min chunk size, and page size must all be powers of 2. - */ - if ((sizeof(size_t) != sizeof(char *)) || - (MAX_SIZE_T < MIN_CHUNK_SIZE) || - (sizeof(int) < 4) || - (MALLOC_ALIGNMENT < (size_t) 8U) || - ((MALLOC_ALIGNMENT & (MALLOC_ALIGNMENT - SIZE_T_ONE)) != 0) || - ((MCHUNK_SIZE & (MCHUNK_SIZE - SIZE_T_ONE)) != 0) || - ((mparams.granularity & (mparams.granularity - SIZE_T_ONE)) != 0) - || ((mparams.page_size & (mparams.page_size - SIZE_T_ONE)) != 0)) - ABORT; - } - return 0; + /* Sanity-check configuration: + size_t must be unsigned and as wide as pointer type. + ints must be at least 4 bytes. + alignment must be at least 8. + Alignment, min chunk size, and page size must all be powers of 2. + */ + if ((sizeof(size_t) != sizeof(char*)) || + (MAX_SIZE_T < MIN_CHUNK_SIZE) || + (sizeof(int) < 4) || + (MALLOC_ALIGNMENT < (size_t)8U) || + ((MALLOC_ALIGNMENT & (MALLOC_ALIGNMENT-SIZE_T_ONE)) != 0) || + ((MCHUNK_SIZE & (MCHUNK_SIZE-SIZE_T_ONE)) != 0) || + ((mparams.granularity & (mparams.granularity-SIZE_T_ONE)) != 0) || + ((mparams.page_size & (mparams.page_size-SIZE_T_ONE)) != 0)) + ABORT; + } + return 0; } /* support for mallopt */ -static int -change_mparam(int param_number, int value) -{ - size_t val = (size_t) value; - init_mparams(); - switch (param_number) { - case M_TRIM_THRESHOLD: - mparams.trim_threshold = val; - return 1; - case M_GRANULARITY: - if (val >= mparams.page_size && ((val & (val - 1)) == 0)) { - mparams.granularity = val; - return 1; - } else - return 0; - case M_MMAP_THRESHOLD: - mparams.mmap_threshold = val; - return 1; - default: - return 0; +static int change_mparam(int param_number, int value) { + size_t val = (size_t)value; + init_mparams(); + switch(param_number) { + case M_TRIM_THRESHOLD: + mparams.trim_threshold = val; + return 1; + case M_GRANULARITY: + if (val >= mparams.page_size && ((val & (val-1)) == 0)) { + mparams.granularity = val; + return 1; } + else + return 0; + case M_MMAP_THRESHOLD: + mparams.mmap_threshold = val; + return 1; + default: + return 0; + } } -#if DEBUG +#ifdef DEBUG /* ------------------------- Debugging Support --------------------------- */ /* Check properties of any chunk, whether free, inuse, mmapped etc */ -static void -do_check_any_chunk(mstate m, mchunkptr p) -{ - assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); - assert(ok_address(m, p)); +static void do_check_any_chunk(mstate m, mchunkptr p) { + assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); + assert(ok_address(m, p)); } /* Check properties of top chunk */ -static void -do_check_top_chunk(mstate m, mchunkptr p) -{ - msegmentptr sp = segment_holding(m, (char *) p); - size_t sz = chunksize(p); - assert(sp != 0); - assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); - assert(ok_address(m, p)); - assert(sz == m->topsize); - assert(sz > 0); - assert(sz == ((sp->base + sp->size) - (char *) p) - TOP_FOOT_SIZE); - assert(pinuse(p)); - assert(!next_pinuse(p)); +static void do_check_top_chunk(mstate m, mchunkptr p) { + msegmentptr sp = segment_holding(m, (char*)p); + size_t sz = chunksize(p); + assert(sp != 0); + assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); + assert(ok_address(m, p)); + assert(sz == m->topsize); + assert(sz > 0); + assert(sz == ((sp->base + sp->size) - (char*)p) - TOP_FOOT_SIZE); + assert(pinuse(p)); + assert(!next_pinuse(p)); } /* Check properties of (inuse) mmapped chunks */ -static void -do_check_mmapped_chunk(mstate m, mchunkptr p) -{ - size_t sz = chunksize(p); - size_t len = (sz + (p->prev_foot & ~IS_MMAPPED_BIT) + MMAP_FOOT_PAD); - assert(is_mmapped(p)); - assert(use_mmap(m)); - assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); - assert(ok_address(m, p)); - assert(!is_small(sz)); - assert((len & (mparams.page_size - SIZE_T_ONE)) == 0); - assert(chunk_plus_offset(p, sz)->head == FENCEPOST_HEAD); - assert(chunk_plus_offset(p, sz + SIZE_T_SIZE)->head == 0); +static void do_check_mmapped_chunk(mstate m, mchunkptr p) { + size_t sz = chunksize(p); + size_t len = (sz + (p->prev_foot & ~IS_MMAPPED_BIT) + MMAP_FOOT_PAD); + assert(is_mmapped(p)); + assert(use_mmap(m)); + assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); + assert(ok_address(m, p)); + assert(!is_small(sz)); + assert((len & (mparams.page_size-SIZE_T_ONE)) == 0); + assert(chunk_plus_offset(p, sz)->head == FENCEPOST_HEAD); + assert(chunk_plus_offset(p, sz+SIZE_T_SIZE)->head == 0); } /* Check properties of inuse chunks */ -static void -do_check_inuse_chunk(mstate m, mchunkptr p) -{ - do_check_any_chunk(m, p); - assert(cinuse(p)); - assert(next_pinuse(p)); - /* If not pinuse and not mmapped, previous chunk has OK offset */ - assert(is_mmapped(p) || pinuse(p) || next_chunk(prev_chunk(p)) == p); - if (is_mmapped(p)) - do_check_mmapped_chunk(m, p); +static void do_check_inuse_chunk(mstate m, mchunkptr p) { + do_check_any_chunk(m, p); + assert(cinuse(p)); + assert(next_pinuse(p)); + /* If not pinuse and not mmapped, previous chunk has OK offset */ + assert(is_mmapped(p) || pinuse(p) || next_chunk(prev_chunk(p)) == p); + if (is_mmapped(p)) + do_check_mmapped_chunk(m, p); } /* Check properties of free chunks */ -static void -do_check_free_chunk(mstate m, mchunkptr p) -{ - size_t sz = p->head & ~(PINUSE_BIT | CINUSE_BIT); - mchunkptr next = chunk_plus_offset(p, sz); - do_check_any_chunk(m, p); - assert(!cinuse(p)); - assert(!next_pinuse(p)); - assert(!is_mmapped(p)); - if (p != m->dv && p != m->top) { - if (sz >= MIN_CHUNK_SIZE) { - assert((sz & CHUNK_ALIGN_MASK) == 0); - assert(is_aligned(chunk2mem(p))); - assert(next->prev_foot == sz); - assert(pinuse(p)); - assert(next == m->top || cinuse(next)); - assert(p->fd->bk == p); - assert(p->bk->fd == p); - } else /* markers are always of size SIZE_T_SIZE */ - assert(sz == SIZE_T_SIZE); +static void do_check_free_chunk(mstate m, mchunkptr p) { + size_t sz = p->head & ~(PINUSE_BIT|CINUSE_BIT); + mchunkptr next = chunk_plus_offset(p, sz); + do_check_any_chunk(m, p); + assert(!cinuse(p)); + assert(!next_pinuse(p)); + assert (!is_mmapped(p)); + if (p != m->dv && p != m->top) { + if (sz >= MIN_CHUNK_SIZE) { + assert((sz & CHUNK_ALIGN_MASK) == 0); + assert(is_aligned(chunk2mem(p))); + assert(next->prev_foot == sz); + assert(pinuse(p)); + assert (next == m->top || cinuse(next)); + assert(p->fd->bk == p); + assert(p->bk->fd == p); } + else /* markers are always of size SIZE_T_SIZE */ + assert(sz == SIZE_T_SIZE); + } } /* Check properties of malloced chunks at the point they are malloced */ -static void -do_check_malloced_chunk(mstate m, void *mem, size_t s) -{ - if (mem != 0) { - mchunkptr p = mem2chunk(mem); - size_t sz = p->head & ~(PINUSE_BIT | CINUSE_BIT); - do_check_inuse_chunk(m, p); - assert((sz & CHUNK_ALIGN_MASK) == 0); - assert(sz >= MIN_CHUNK_SIZE); - assert(sz >= s); - /* unless mmapped, size is less than MIN_CHUNK_SIZE more than request */ - assert(is_mmapped(p) || sz < (s + MIN_CHUNK_SIZE)); - } +static void do_check_malloced_chunk(mstate m, void* mem, size_t s) { + if (mem != 0) { + mchunkptr p = mem2chunk(mem); + size_t sz = p->head & ~(PINUSE_BIT|CINUSE_BIT); + do_check_inuse_chunk(m, p); + assert((sz & CHUNK_ALIGN_MASK) == 0); + assert(sz >= MIN_CHUNK_SIZE); + assert(sz >= s); + /* unless mmapped, size is less than MIN_CHUNK_SIZE more than request */ + assert(is_mmapped(p) || sz < (s + MIN_CHUNK_SIZE)); + } } /* Check a tree and its subtrees. */ -static void -do_check_tree(mstate m, tchunkptr t) -{ - tchunkptr head = 0; - tchunkptr u = t; - bindex_t tindex = t->index; - size_t tsize = chunksize(t); - bindex_t idx; - compute_tree_index(tsize, idx); - assert(tindex == idx); - assert(tsize >= MIN_LARGE_SIZE); - assert(tsize >= minsize_for_tree_index(idx)); - assert((idx == NTREEBINS - 1) - || (tsize < minsize_for_tree_index((idx + 1)))); +static void do_check_tree(mstate m, tchunkptr t) { + tchunkptr head = 0; + tchunkptr u = t; + bindex_t tindex = t->index; + size_t tsize = chunksize(t); + bindex_t idx; + compute_tree_index(tsize, idx); + assert(tindex == idx); + assert(tsize >= MIN_LARGE_SIZE); + assert(tsize >= minsize_for_tree_index(idx)); + assert((idx == NTREEBINS-1) || (tsize < minsize_for_tree_index((idx+1)))); - do { /* traverse through chain of same-sized nodes */ - do_check_any_chunk(m, ((mchunkptr) u)); - assert(u->index == tindex); - assert(chunksize(u) == tsize); - assert(!cinuse(u)); - assert(!next_pinuse(u)); - assert(u->fd->bk == u); - assert(u->bk->fd == u); - if (u->parent == 0) { - assert(u->child[0] == 0); - assert(u->child[1] == 0); - } else { - assert(head == 0); /* only one node on chain has parent */ - head = u; - assert(u->parent != u); - assert(u->parent->child[0] == u || - u->parent->child[1] == u || - *((tbinptr *) (u->parent)) == u); - if (u->child[0] != 0) { - assert(u->child[0]->parent == u); - assert(u->child[0] != u); - do_check_tree(m, u->child[0]); - } - if (u->child[1] != 0) { - assert(u->child[1]->parent == u); - assert(u->child[1] != u); - do_check_tree(m, u->child[1]); - } - if (u->child[0] != 0 && u->child[1] != 0) { - assert(chunksize(u->child[0]) < chunksize(u->child[1])); - } - } - u = u->fd; - } while (u != t); - assert(head != 0); + do { /* traverse through chain of same-sized nodes */ + do_check_any_chunk(m, ((mchunkptr)u)); + assert(u->index == tindex); + assert(chunksize(u) == tsize); + assert(!cinuse(u)); + assert(!next_pinuse(u)); + assert(u->fd->bk == u); + assert(u->bk->fd == u); + if (u->parent == 0) { + assert(u->child[0] == 0); + assert(u->child[1] == 0); + } + else { + assert(head == 0); /* only one node on chain has parent */ + head = u; + assert(u->parent != u); + assert (u->parent->child[0] == u || + u->parent->child[1] == u || + *((tbinptr*)(u->parent)) == u); + if (u->child[0] != 0) { + assert(u->child[0]->parent == u); + assert(u->child[0] != u); + do_check_tree(m, u->child[0]); + } + if (u->child[1] != 0) { + assert(u->child[1]->parent == u); + assert(u->child[1] != u); + do_check_tree(m, u->child[1]); + } + if (u->child[0] != 0 && u->child[1] != 0) { + assert(chunksize(u->child[0]) < chunksize(u->child[1])); + } + } + u = u->fd; + } while (u != t); + assert(head != 0); } /* Check all the chunks in a treebin. */ -static void -do_check_treebin(mstate m, bindex_t i) -{ - tbinptr *tb = treebin_at(m, i); - tchunkptr t = *tb; - int empty = (m->treemap & (1U << i)) == 0; - if (t == 0) - assert(empty); - if (!empty) - do_check_tree(m, t); +static void do_check_treebin(mstate m, bindex_t i) { + tbinptr* tb = treebin_at(m, i); + tchunkptr t = *tb; + int empty = (m->treemap & (1U << i)) == 0; + if (t == 0) + assert(empty); + if (!empty) + do_check_tree(m, t); } /* Check all the chunks in a smallbin. */ -static void -do_check_smallbin(mstate m, bindex_t i) -{ - sbinptr b = smallbin_at(m, i); - mchunkptr p = b->bk; - unsigned int empty = (m->smallmap & (1U << i)) == 0; - if (p == b) - assert(empty); - if (!empty) { - for (; p != b; p = p->bk) { - size_t size = chunksize(p); - mchunkptr q; - /* each chunk claims to be free */ - do_check_free_chunk(m, p); - /* chunk belongs in bin */ - assert(small_index(size) == i); - assert(p->bk == b || chunksize(p->bk) == chunksize(p)); - /* chunk is followed by an inuse chunk */ - q = next_chunk(p); - if (q->head != FENCEPOST_HEAD) - do_check_inuse_chunk(m, q); - } +static void do_check_smallbin(mstate m, bindex_t i) { + sbinptr b = smallbin_at(m, i); + mchunkptr p = b->bk; + unsigned int empty = (m->smallmap & (1U << i)) == 0; + if (p == b) + assert(empty); + if (!empty) { + for (; p != b; p = p->bk) { + size_t size = chunksize(p); + mchunkptr q; + /* each chunk claims to be free */ + do_check_free_chunk(m, p); + /* chunk belongs in bin */ + assert(small_index(size) == i); + assert(p->bk == b || chunksize(p->bk) == chunksize(p)); + /* chunk is followed by an inuse chunk */ + q = next_chunk(p); + if (q->head != FENCEPOST_HEAD) + do_check_inuse_chunk(m, q); } + } } /* Find x in a bin. Used in other check functions. */ -static int -bin_find(mstate m, mchunkptr x) -{ - size_t size = chunksize(x); - if (is_small(size)) { - bindex_t sidx = small_index(size); - sbinptr b = smallbin_at(m, sidx); - if (smallmap_is_marked(m, sidx)) { - mchunkptr p = b; - do { - if (p == x) - return 1; - } while ((p = p->fd) != b); - } - } else { - bindex_t tidx; - compute_tree_index(size, tidx); - if (treemap_is_marked(m, tidx)) { - tchunkptr t = *treebin_at(m, tidx); - size_t sizebits = size << leftshift_for_tree_index(tidx); - while (t != 0 && chunksize(t) != size) { - t = t->child[(sizebits >> (SIZE_T_BITSIZE - SIZE_T_ONE)) & 1]; - sizebits <<= 1; - } - if (t != 0) { - tchunkptr u = t; - do { - if (u == (tchunkptr) x) - return 1; - } while ((u = u->fd) != t); - } - } +static int bin_find(mstate m, mchunkptr x) { + size_t size = chunksize(x); + if (is_small(size)) { + bindex_t sidx = small_index(size); + sbinptr b = smallbin_at(m, sidx); + if (smallmap_is_marked(m, sidx)) { + mchunkptr p = b; + do { + if (p == x) + return 1; + } while ((p = p->fd) != b); } - return 0; + } + else { + bindex_t tidx; + compute_tree_index(size, tidx); + if (treemap_is_marked(m, tidx)) { + tchunkptr t = *treebin_at(m, tidx); + size_t sizebits = size << leftshift_for_tree_index(tidx); + while (t != 0 && chunksize(t) != size) { + t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]; + sizebits <<= 1; + } + if (t != 0) { + tchunkptr u = t; + do { + if (u == (tchunkptr)x) + return 1; + } while ((u = u->fd) != t); + } + } + } + return 0; } /* Traverse each chunk and check it; return total */ -static size_t -traverse_and_check(mstate m) -{ - size_t sum = 0; - if (is_initialized(m)) { - msegmentptr s = &m->seg; - sum += m->topsize + TOP_FOOT_SIZE; - while (s != 0) { - mchunkptr q = align_as_chunk(s->base); - mchunkptr lastq = 0; - assert(pinuse(q)); - while (segment_holds(s, q) && - q != m->top && q->head != FENCEPOST_HEAD) { - sum += chunksize(q); - if (cinuse(q)) { - assert(!bin_find(m, q)); - do_check_inuse_chunk(m, q); - } else { - assert(q == m->dv || bin_find(m, q)); - assert(lastq == 0 || cinuse(lastq)); /* Not 2 consecutive free */ - do_check_free_chunk(m, q); - } - lastq = q; - q = next_chunk(q); - } - s = s->next; +static size_t traverse_and_check(mstate m) { + size_t sum = 0; + if (is_initialized(m)) { + msegmentptr s = &m->seg; + sum += m->topsize + TOP_FOOT_SIZE; + while (s != 0) { + mchunkptr q = align_as_chunk(s->base); + mchunkptr lastq = 0; + assert(pinuse(q)); + while (segment_holds(s, q) && + q != m->top && q->head != FENCEPOST_HEAD) { + sum += chunksize(q); + if (cinuse(q)) { + assert(!bin_find(m, q)); + do_check_inuse_chunk(m, q); } + else { + assert(q == m->dv || bin_find(m, q)); + assert(lastq == 0 || cinuse(lastq)); /* Not 2 consecutive free */ + do_check_free_chunk(m, q); + } + lastq = q; + q = next_chunk(q); + } + s = s->next; } - return sum; + } + return sum; } /* Check all properties of malloc_state. */ -static void -do_check_malloc_state(mstate m) -{ - bindex_t i; - size_t total; - /* check bins */ - for (i = 0; i < NSMALLBINS; ++i) - do_check_smallbin(m, i); - for (i = 0; i < NTREEBINS; ++i) - do_check_treebin(m, i); +static void do_check_malloc_state(mstate m) { + bindex_t i; + size_t total; + /* check bins */ + for (i = 0; i < NSMALLBINS; ++i) + do_check_smallbin(m, i); + for (i = 0; i < NTREEBINS; ++i) + do_check_treebin(m, i); - if (m->dvsize != 0) { /* check dv chunk */ - do_check_any_chunk(m, m->dv); - assert(m->dvsize == chunksize(m->dv)); - assert(m->dvsize >= MIN_CHUNK_SIZE); - assert(bin_find(m, m->dv) == 0); - } + if (m->dvsize != 0) { /* check dv chunk */ + do_check_any_chunk(m, m->dv); + assert(m->dvsize == chunksize(m->dv)); + assert(m->dvsize >= MIN_CHUNK_SIZE); + assert(bin_find(m, m->dv) == 0); + } - if (m->top != 0) { /* check top chunk */ - do_check_top_chunk(m, m->top); - assert(m->topsize == chunksize(m->top)); - assert(m->topsize > 0); - assert(bin_find(m, m->top) == 0); - } + if (m->top != 0) { /* check top chunk */ + do_check_top_chunk(m, m->top); + assert(m->topsize == chunksize(m->top)); + assert(m->topsize > 0); + assert(bin_find(m, m->top) == 0); + } - total = traverse_and_check(m); - assert(total <= m->footprint); - assert(m->footprint <= m->max_footprint); + total = traverse_and_check(m); + assert(total <= m->footprint); + assert(m->footprint <= m->max_footprint); } #endif /* DEBUG */ /* ----------------------------- statistics ------------------------------ */ #if !NO_MALLINFO -static struct mallinfo -internal_mallinfo(mstate m) -{ - struct mallinfo nm = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - if (!PREACTION(m)) { - check_malloc_state(m); - if (is_initialized(m)) { - size_t nfree = SIZE_T_ONE; /* top always free */ - size_t mfree = m->topsize + TOP_FOOT_SIZE; - size_t sum = mfree; - msegmentptr s = &m->seg; - while (s != 0) { - mchunkptr q = align_as_chunk(s->base); - while (segment_holds(s, q) && - q != m->top && q->head != FENCEPOST_HEAD) { - size_t sz = chunksize(q); - sum += sz; - if (!cinuse(q)) { - mfree += sz; - ++nfree; - } - q = next_chunk(q); - } - s = s->next; - } - - nm.arena = sum; - nm.ordblks = nfree; - nm.hblkhd = m->footprint - sum; - nm.usmblks = m->max_footprint; - nm.uordblks = m->footprint - mfree; - nm.fordblks = mfree; - nm.keepcost = m->topsize; +static struct mallinfo internal_mallinfo(mstate m) { + struct mallinfo nm = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + if (!PREACTION(m)) { + check_malloc_state(m); + if (is_initialized(m)) { + size_t nfree = SIZE_T_ONE; /* top always free */ + size_t mfree = m->topsize + TOP_FOOT_SIZE; + size_t sum = mfree; + msegmentptr s = &m->seg; + while (s != 0) { + mchunkptr q = align_as_chunk(s->base); + while (segment_holds(s, q) && + q != m->top && q->head != FENCEPOST_HEAD) { + size_t sz = chunksize(q); + sum += sz; + if (!cinuse(q)) { + mfree += sz; + ++nfree; + } + q = next_chunk(q); } + s = s->next; + } - POSTACTION(m); + nm.arena = sum; + nm.ordblks = nfree; + nm.hblkhd = m->footprint - sum; + nm.usmblks = m->max_footprint; + nm.uordblks = m->footprint - mfree; + nm.fordblks = mfree; + nm.keepcost = m->topsize; } - return nm; + + POSTACTION(m); + } + return nm; } #endif /* !NO_MALLINFO */ -static void -internal_malloc_stats(mstate m) -{ - if (!PREACTION(m)) { +static void internal_malloc_stats(mstate m) { + if (!PREACTION(m)) { #ifndef LACKS_STDIO_H - size_t maxfp = 0; + size_t maxfp = 0; #endif - size_t fp = 0; - size_t used = 0; - check_malloc_state(m); - if (is_initialized(m)) { - msegmentptr s = &m->seg; + size_t fp = 0; + size_t used = 0; + check_malloc_state(m); + if (is_initialized(m)) { + msegmentptr s = &m->seg; #ifndef LACKS_STDIO_H - maxfp = m->max_footprint; + maxfp = m->max_footprint; #endif - fp = m->footprint; - used = fp - (m->topsize + TOP_FOOT_SIZE); + fp = m->footprint; + used = fp - (m->topsize + TOP_FOOT_SIZE); - while (s != 0) { - mchunkptr q = align_as_chunk(s->base); - while (segment_holds(s, q) && - q != m->top && q->head != FENCEPOST_HEAD) { - if (!cinuse(q)) - used -= chunksize(q); - q = next_chunk(q); - } - s = s->next; - } + while (s != 0) { + mchunkptr q = align_as_chunk(s->base); + while (segment_holds(s, q) && + q != m->top && q->head != FENCEPOST_HEAD) { + if (!cinuse(q)) + used -= chunksize(q); + q = next_chunk(q); } + s = s->next; + } + } + #ifndef LACKS_STDIO_H - fprintf(stderr, "max system bytes = %10lu\n", - (unsigned long) (maxfp)); - fprintf(stderr, "system bytes = %10lu\n", (unsigned long) (fp)); - fprintf(stderr, "in use bytes = %10lu\n", (unsigned long) (used)); + fprintf(stderr, "max system bytes = %10lu\n", (unsigned long)(maxfp)); + fprintf(stderr, "system bytes = %10lu\n", (unsigned long)(fp)); + fprintf(stderr, "in use bytes = %10lu\n", (unsigned long)(used)); +#else + (void)used; #endif - POSTACTION(m); - } + POSTACTION(m); + } } /* ----------------------- Operations on smallbins ----------------------- */ @@ -3281,927 +3238,911 @@ internal_malloc_stats(mstate m) */ /* Malloc using mmap */ -static void * -mmap_alloc(mstate m, size_t nb) -{ - size_t mmsize = - granularity_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK); - if (mmsize > nb) { /* Check for wrap around 0 */ - char *mm = (char *) (DIRECT_MMAP(mmsize)); - if (mm != CMFAIL) { - size_t offset = align_offset(chunk2mem(mm)); - size_t psize = mmsize - offset - MMAP_FOOT_PAD; - mchunkptr p = (mchunkptr) (mm + offset); - p->prev_foot = offset | IS_MMAPPED_BIT; - (p)->head = (psize | CINUSE_BIT); - mark_inuse_foot(m, p, psize); - chunk_plus_offset(p, psize)->head = FENCEPOST_HEAD; - chunk_plus_offset(p, psize + SIZE_T_SIZE)->head = 0; +static void* mmap_alloc(mstate m, size_t nb) { + size_t mmsize = granularity_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK); + if (mmsize > nb) { /* Check for wrap around 0 */ + char* mm = (char*)(DIRECT_MMAP(mmsize)); + if (mm != CMFAIL) { + size_t offset = align_offset(chunk2mem(mm)); + size_t psize = mmsize - offset - MMAP_FOOT_PAD; + mchunkptr p = (mchunkptr)(mm + offset); + p->prev_foot = offset | IS_MMAPPED_BIT; + (p)->head = (psize|CINUSE_BIT); + mark_inuse_foot(m, p, psize); + chunk_plus_offset(p, psize)->head = FENCEPOST_HEAD; + chunk_plus_offset(p, psize+SIZE_T_SIZE)->head = 0; - if (mm < m->least_addr) - m->least_addr = mm; - if ((m->footprint += mmsize) > m->max_footprint) - m->max_footprint = m->footprint; - assert(is_aligned(chunk2mem(p))); - check_mmapped_chunk(m, p); - return chunk2mem(p); - } + if (mm < m->least_addr) + m->least_addr = mm; + if ((m->footprint += mmsize) > m->max_footprint) + m->max_footprint = m->footprint; + assert(is_aligned(chunk2mem(p))); + check_mmapped_chunk(m, p); + return chunk2mem(p); } - return 0; + } + return 0; } /* Realloc using mmap */ -static mchunkptr -mmap_resize(mstate m, mchunkptr oldp, size_t nb) -{ - size_t oldsize = chunksize(oldp); - if (is_small(nb)) /* Can't shrink mmap regions below small size */ - return 0; - /* Keep old chunk if big enough but not too big */ - if (oldsize >= nb + SIZE_T_SIZE && - (oldsize - nb) <= (mparams.granularity << 1)) - return oldp; - else { - size_t offset = oldp->prev_foot & ~IS_MMAPPED_BIT; - size_t oldmmsize = oldsize + offset + MMAP_FOOT_PAD; - size_t newmmsize = granularity_align(nb + SIX_SIZE_T_SIZES + - CHUNK_ALIGN_MASK); - char *cp = (char *) CALL_MREMAP((char *) oldp - offset, - oldmmsize, newmmsize, 1); - if (cp != CMFAIL) { - mchunkptr newp = (mchunkptr) (cp + offset); - size_t psize = newmmsize - offset - MMAP_FOOT_PAD; - newp->head = (psize | CINUSE_BIT); - mark_inuse_foot(m, newp, psize); - chunk_plus_offset(newp, psize)->head = FENCEPOST_HEAD; - chunk_plus_offset(newp, psize + SIZE_T_SIZE)->head = 0; - - if (cp < m->least_addr) - m->least_addr = cp; - if ((m->footprint += newmmsize - oldmmsize) > m->max_footprint) - m->max_footprint = m->footprint; - check_mmapped_chunk(m, newp); - return newp; - } - } +static mchunkptr mmap_resize(mstate m, mchunkptr oldp, size_t nb) { + size_t oldsize = chunksize(oldp); + if (is_small(nb)) /* Can't shrink mmap regions below small size */ return 0; + /* Keep old chunk if big enough but not too big */ + if (oldsize >= nb + SIZE_T_SIZE && + (oldsize - nb) <= (mparams.granularity << 1)) + return oldp; + else { + size_t offset = oldp->prev_foot & ~IS_MMAPPED_BIT; + size_t oldmmsize = oldsize + offset + MMAP_FOOT_PAD; + size_t newmmsize = granularity_align(nb + SIX_SIZE_T_SIZES + + CHUNK_ALIGN_MASK); + char* cp = (char*)CALL_MREMAP((char*)oldp - offset, + oldmmsize, newmmsize, 1); + if (cp != CMFAIL) { + mchunkptr newp = (mchunkptr)(cp + offset); + size_t psize = newmmsize - offset - MMAP_FOOT_PAD; + newp->head = (psize|CINUSE_BIT); + mark_inuse_foot(m, newp, psize); + chunk_plus_offset(newp, psize)->head = FENCEPOST_HEAD; + chunk_plus_offset(newp, psize+SIZE_T_SIZE)->head = 0; + + if (cp < m->least_addr) + m->least_addr = cp; + if ((m->footprint += newmmsize - oldmmsize) > m->max_footprint) + m->max_footprint = m->footprint; + check_mmapped_chunk(m, newp); + return newp; + } + } + return 0; } /* -------------------------- mspace management -------------------------- */ /* Initialize top chunk and its size */ -static void -init_top(mstate m, mchunkptr p, size_t psize) -{ - /* Ensure alignment */ - size_t offset = align_offset(chunk2mem(p)); - p = (mchunkptr) ((char *) p + offset); - psize -= offset; +static void init_top(mstate m, mchunkptr p, size_t psize) { + /* Ensure alignment */ + size_t offset = align_offset(chunk2mem(p)); + p = (mchunkptr)((char*)p + offset); + psize -= offset; - m->top = p; - m->topsize = psize; - p->head = psize | PINUSE_BIT; - /* set size of fake trailing chunk holding overhead space only once */ - chunk_plus_offset(p, psize)->head = TOP_FOOT_SIZE; - m->trim_check = mparams.trim_threshold; /* reset on each update */ + m->top = p; + m->topsize = psize; + p->head = psize | PINUSE_BIT; + /* set size of fake trailing chunk holding overhead space only once */ + chunk_plus_offset(p, psize)->head = TOP_FOOT_SIZE; + m->trim_check = mparams.trim_threshold; /* reset on each update */ } /* Initialize bins for a new mstate that is otherwise zeroed out */ -static void -init_bins(mstate m) -{ - /* Establish circular links for smallbins */ - bindex_t i; - for (i = 0; i < NSMALLBINS; ++i) { - sbinptr bin = smallbin_at(m, i); - bin->fd = bin->bk = bin; - } +static void init_bins(mstate m) { + /* Establish circular links for smallbins */ + bindex_t i; + for (i = 0; i < NSMALLBINS; ++i) { + sbinptr bin = smallbin_at(m,i); + bin->fd = bin->bk = bin; + } } #if PROCEED_ON_ERROR /* default corruption action */ -static void -reset_on_error(mstate m) -{ - int i; - ++malloc_corruption_error_count; - /* Reinitialize fields to forget about all memory */ - m->smallbins = m->treebins = 0; - m->dvsize = m->topsize = 0; - m->seg.base = 0; - m->seg.size = 0; - m->seg.next = 0; - m->top = m->dv = 0; - for (i = 0; i < NTREEBINS; ++i) - *treebin_at(m, i) = 0; - init_bins(m); +static void reset_on_error(mstate m) { + int i; + ++malloc_corruption_error_count; + /* Reinitialize fields to forget about all memory */ + m->smallbins = m->treebins = 0; + m->dvsize = m->topsize = 0; + m->seg.base = 0; + m->seg.size = 0; + m->seg.next = 0; + m->top = m->dv = 0; + for (i = 0; i < NTREEBINS; ++i) + *treebin_at(m, i) = 0; + init_bins(m); } #endif /* PROCEED_ON_ERROR */ /* Allocate chunk and prepend remainder with chunk in successor base. */ -static void * -prepend_alloc(mstate m, char *newbase, char *oldbase, size_t nb) -{ - mchunkptr p = align_as_chunk(newbase); - mchunkptr oldfirst = align_as_chunk(oldbase); - size_t psize = (char *) oldfirst - (char *) p; - mchunkptr q = chunk_plus_offset(p, nb); - size_t qsize = psize - nb; - set_size_and_pinuse_of_inuse_chunk(m, p, nb); +static void* prepend_alloc(mstate m, char* newbase, char* oldbase, + size_t nb) { + mchunkptr p = align_as_chunk(newbase); + mchunkptr oldfirst = align_as_chunk(oldbase); + size_t psize = (char*)oldfirst - (char*)p; + mchunkptr q = chunk_plus_offset(p, nb); + size_t qsize = psize - nb; + set_size_and_pinuse_of_inuse_chunk(m, p, nb); - assert((char *) oldfirst > (char *) q); - assert(pinuse(oldfirst)); - assert(qsize >= MIN_CHUNK_SIZE); + assert((char*)oldfirst > (char*)q); + assert(pinuse(oldfirst)); + assert(qsize >= MIN_CHUNK_SIZE); - /* consolidate remainder with first chunk of old base */ - if (oldfirst == m->top) { - size_t tsize = m->topsize += qsize; - m->top = q; - q->head = tsize | PINUSE_BIT; - check_top_chunk(m, q); - } else if (oldfirst == m->dv) { - size_t dsize = m->dvsize += qsize; - m->dv = q; - set_size_and_pinuse_of_free_chunk(q, dsize); - } else { - if (!cinuse(oldfirst)) { - size_t nsize = chunksize(oldfirst); - unlink_chunk(m, oldfirst, nsize); - oldfirst = chunk_plus_offset(oldfirst, nsize); - qsize += nsize; - } - set_free_with_pinuse(q, qsize, oldfirst); - insert_chunk(m, q, qsize); - check_free_chunk(m, q); + /* consolidate remainder with first chunk of old base */ + if (oldfirst == m->top) { + size_t tsize = m->topsize += qsize; + m->top = q; + q->head = tsize | PINUSE_BIT; + check_top_chunk(m, q); + } + else if (oldfirst == m->dv) { + size_t dsize = m->dvsize += qsize; + m->dv = q; + set_size_and_pinuse_of_free_chunk(q, dsize); + } + else { + if (!cinuse(oldfirst)) { + size_t nsize = chunksize(oldfirst); + unlink_chunk(m, oldfirst, nsize); + oldfirst = chunk_plus_offset(oldfirst, nsize); + qsize += nsize; } + set_free_with_pinuse(q, qsize, oldfirst); + insert_chunk(m, q, qsize); + check_free_chunk(m, q); + } - check_malloced_chunk(m, chunk2mem(p), nb); - return chunk2mem(p); + check_malloced_chunk(m, chunk2mem(p), nb); + return chunk2mem(p); } /* Add a segment to hold a new noncontiguous region */ -static void -add_segment(mstate m, char *tbase, size_t tsize, flag_t mmapped) -{ - /* Determine locations and sizes of segment, fenceposts, old top */ - char *old_top = (char *) m->top; - msegmentptr oldsp = segment_holding(m, old_top); - char *old_end = oldsp->base + oldsp->size; - size_t ssize = pad_request(sizeof(struct malloc_segment)); - char *rawsp = old_end - (ssize + FOUR_SIZE_T_SIZES + CHUNK_ALIGN_MASK); - size_t offset = align_offset(chunk2mem(rawsp)); - char *asp = rawsp + offset; - char *csp = (asp < (old_top + MIN_CHUNK_SIZE)) ? old_top : asp; - mchunkptr sp = (mchunkptr) csp; - msegmentptr ss = (msegmentptr) (chunk2mem(sp)); - mchunkptr tnext = chunk_plus_offset(sp, ssize); - mchunkptr p = tnext; - int nfences = 0; +static void add_segment(mstate m, char* tbase, size_t tsize, flag_t mmapped) { + /* Determine locations and sizes of segment, fenceposts, old top */ + char* old_top = (char*)m->top; + msegmentptr oldsp = segment_holding(m, old_top); + char* old_end = oldsp->base + oldsp->size; + size_t ssize = pad_request(sizeof(struct malloc_segment)); + char* rawsp = old_end - (ssize + FOUR_SIZE_T_SIZES + CHUNK_ALIGN_MASK); + size_t offset = align_offset(chunk2mem(rawsp)); + char* asp = rawsp + offset; + char* csp = (asp < (old_top + MIN_CHUNK_SIZE))? old_top : asp; + mchunkptr sp = (mchunkptr)csp; + msegmentptr ss = (msegmentptr)(chunk2mem(sp)); + mchunkptr tnext = chunk_plus_offset(sp, ssize); + mchunkptr p = tnext; +#ifdef DEBUG + int nfences = 0; +#endif - /* reset top to new space */ - init_top(m, (mchunkptr) tbase, tsize - TOP_FOOT_SIZE); + /* reset top to new space */ + init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE); - /* Set up segment record */ - assert(is_aligned(ss)); - set_size_and_pinuse_of_inuse_chunk(m, sp, ssize); - *ss = m->seg; /* Push current record */ - m->seg.base = tbase; - m->seg.size = tsize; - m->seg.sflags = mmapped; - m->seg.next = ss; + /* Set up segment record */ + assert(is_aligned(ss)); + set_size_and_pinuse_of_inuse_chunk(m, sp, ssize); + *ss = m->seg; /* Push current record */ + m->seg.base = tbase; + m->seg.size = tsize; + m->seg.sflags = mmapped; + m->seg.next = ss; - /* Insert trailing fenceposts */ - for (;;) { - mchunkptr nextp = chunk_plus_offset(p, SIZE_T_SIZE); - p->head = FENCEPOST_HEAD; - ++nfences; - if ((char *) (&(nextp->head)) < old_end) - p = nextp; - else - break; - } - assert(nfences >= 2); + /* Insert trailing fenceposts */ + for (;;) { + mchunkptr nextp = chunk_plus_offset(p, SIZE_T_SIZE); + p->head = FENCEPOST_HEAD; +#ifdef DEBUG + ++nfences; +#endif + if ((char*)(&(nextp->head)) < old_end) + p = nextp; + else + break; + } +#ifdef DEBUG + assert(nfences >= 2); +#endif - /* Insert the rest of old top into a bin as an ordinary free chunk */ - if (csp != old_top) { - mchunkptr q = (mchunkptr) old_top; - size_t psize = csp - old_top; - mchunkptr tn = chunk_plus_offset(q, psize); - set_free_with_pinuse(q, psize, tn); - insert_chunk(m, q, psize); - } + /* Insert the rest of old top into a bin as an ordinary free chunk */ + if (csp != old_top) { + mchunkptr q = (mchunkptr)old_top; + size_t psize = csp - old_top; + mchunkptr tn = chunk_plus_offset(q, psize); + set_free_with_pinuse(q, psize, tn); + insert_chunk(m, q, psize); + } - check_top_chunk(m, m->top); + check_top_chunk(m, m->top); } /* -------------------------- System allocation -------------------------- */ /* Get memory from system using MORECORE or MMAP */ -static void * -sys_alloc(mstate m, size_t nb) -{ - char *tbase = CMFAIL; - size_t tsize = 0; - flag_t mmap_flag = 0; +static void* sys_alloc(mstate m, size_t nb) { + char* tbase = CMFAIL; + size_t tsize = 0; + flag_t mmap_flag = 0; - init_mparams(); + init_mparams(); - /* Directly map large chunks */ - if (use_mmap(m) && nb >= mparams.mmap_threshold) { - void *mem = mmap_alloc(m, nb); - if (mem != 0) - return mem; - } + /* Directly map large chunks */ + if (use_mmap(m) && nb >= mparams.mmap_threshold) { + void* mem = mmap_alloc(m, nb); + if (mem != 0) + return mem; + } - /* - Try getting memory in any of three ways (in most-preferred to - least-preferred order): - 1. A call to MORECORE that can normally contiguously extend memory. + /* + Try getting memory in any of three ways (in most-preferred to + least-preferred order): + 1. A call to MORECORE that can normally contiguously extend memory. (disabled if not MORECORE_CONTIGUOUS or not HAVE_MORECORE or or main space is mmapped or a previous contiguous call failed) - 2. A call to MMAP new space (disabled if not HAVE_MMAP). + 2. A call to MMAP new space (disabled if not HAVE_MMAP). Note that under the default settings, if MORECORE is unable to fulfill a request, and HAVE_MMAP is true, then mmap is used as a noncontiguous system allocator. This is a useful backup strategy for systems with holes in address spaces -- in this case sbrk cannot contiguously expand the heap, but mmap may be able to find space. - 3. A call to MORECORE that cannot usually contiguously extend memory. + 3. A call to MORECORE that cannot usually contiguously extend memory. (disabled if not HAVE_MORECORE) - */ + */ - if (MORECORE_CONTIGUOUS && !use_noncontiguous(m)) { - char *br = CMFAIL; - msegmentptr ss = - (m->top == 0) ? 0 : segment_holding(m, (char *) m->top); - size_t asize = 0; - ACQUIRE_MORECORE_LOCK(); + if (MORECORE_CONTIGUOUS && !use_noncontiguous(m)) { + char* br = CMFAIL; + msegmentptr ss = (m->top == 0)? 0 : segment_holding(m, (char*)m->top); + size_t asize = 0; + ACQUIRE_MORECORE_LOCK(); - if (ss == 0) { /* First time through or recovery */ - char *base = (char *) CALL_MORECORE(0); - if (base != CMFAIL) { - asize = - granularity_align(nb + TOP_FOOT_SIZE + MALLOC_ALIGNMENT + - SIZE_T_ONE); - /* Adjust to end on a page boundary */ - if (!is_page_aligned(base)) - asize += (page_align((size_t) base) - (size_t) base); - /* Can't call MORECORE if size is negative when treated as signed */ - if (asize < HALF_MAX_SIZE_T && - (br = (char *) (CALL_MORECORE(asize))) == base) { - tbase = base; - tsize = asize; - } - } - } else { - /* Subtract out existing available top space from MORECORE request. */ - asize = - granularity_align(nb - m->topsize + TOP_FOOT_SIZE + - MALLOC_ALIGNMENT + SIZE_T_ONE); - /* Use mem here only if it did continuously extend old space */ - if (asize < HALF_MAX_SIZE_T && - (br = - (char *) (CALL_MORECORE(asize))) == ss->base + ss->size) { - tbase = br; - tsize = asize; - } + if (ss == 0) { /* First time through or recovery */ + char* base = (char*)CALL_MORECORE(0); + if (base != CMFAIL) { + asize = granularity_align(nb + TOP_FOOT_SIZE + MALLOC_ALIGNMENT + SIZE_T_ONE); + /* Adjust to end on a page boundary */ + if (!is_page_aligned(base)) + asize += (page_align((size_t)base) - (size_t)base); + /* Can't call MORECORE if size is negative when treated as signed */ + if (asize < HALF_MAX_SIZE_T && + (br = (char*)(CALL_MORECORE(asize))) == base) { + tbase = base; + tsize = asize; } - - if (tbase == CMFAIL) { /* Cope with partial failure */ - if (br != CMFAIL) { /* Try to use/extend the space we did get */ - if (asize < HALF_MAX_SIZE_T && - asize < nb + TOP_FOOT_SIZE + SIZE_T_ONE) { - size_t esize = - granularity_align(nb + TOP_FOOT_SIZE + - MALLOC_ALIGNMENT + SIZE_T_ONE - - asize); - if (esize < HALF_MAX_SIZE_T) { - char *end = (char *) CALL_MORECORE(esize); - if (end != CMFAIL) - asize += esize; - else { /* Can't use; try to release */ - end = (char *) CALL_MORECORE(-asize); - br = CMFAIL; - } - } - } - } - if (br != CMFAIL) { /* Use the space we did get */ - tbase = br; - tsize = asize; - } else - disable_contiguous(m); /* Don't try contiguous path in the future */ - } - - RELEASE_MORECORE_LOCK(); + } + } + else { + /* Subtract out existing available top space from MORECORE request. */ + asize = granularity_align(nb - m->topsize + TOP_FOOT_SIZE + MALLOC_ALIGNMENT + SIZE_T_ONE); + /* Use mem here only if it did continuously extend old space */ + if (asize < HALF_MAX_SIZE_T && + (br = (char*)(CALL_MORECORE(asize))) == ss->base+ss->size) { + tbase = br; + tsize = asize; + } } - if (HAVE_MMAP && tbase == CMFAIL) { /* Try MMAP */ - size_t req = nb + TOP_FOOT_SIZE + MALLOC_ALIGNMENT + SIZE_T_ONE; - size_t rsize = granularity_align(req); - if (rsize > nb) { /* Fail if wraps around zero */ - char *mp = (char *) (CALL_MMAP(rsize)); - if (mp != CMFAIL) { - tbase = mp; - tsize = rsize; - mmap_flag = IS_MMAPPED_BIT; + if (tbase == CMFAIL) { /* Cope with partial failure */ + if (br != CMFAIL) { /* Try to use/extend the space we did get */ + if (asize < HALF_MAX_SIZE_T && + asize < nb + TOP_FOOT_SIZE + SIZE_T_ONE) { + size_t esize = granularity_align(nb + TOP_FOOT_SIZE + MALLOC_ALIGNMENT + SIZE_T_ONE - asize); + if (esize < HALF_MAX_SIZE_T) { + char* end = (char*)CALL_MORECORE(esize); + if (end != CMFAIL) + asize += esize; + else { /* Can't use; try to release */ + end = (char*)CALL_MORECORE(-asize); + br = CMFAIL; } + } } + } + if (br != CMFAIL) { /* Use the space we did get */ + tbase = br; + tsize = asize; + } + else + disable_contiguous(m); /* Don't try contiguous path in the future */ } - if (HAVE_MORECORE && tbase == CMFAIL) { /* Try noncontiguous MORECORE */ - size_t asize = - granularity_align(nb + TOP_FOOT_SIZE + MALLOC_ALIGNMENT + - SIZE_T_ONE); - if (asize < HALF_MAX_SIZE_T) { - char *br = CMFAIL; - char *end = CMFAIL; - ACQUIRE_MORECORE_LOCK(); - br = (char *) (CALL_MORECORE(asize)); - end = (char *) (CALL_MORECORE(0)); - RELEASE_MORECORE_LOCK(); - if (br != CMFAIL && end != CMFAIL && br < end) { - size_t ssize = end - br; - if (ssize > nb + TOP_FOOT_SIZE) { - tbase = br; - tsize = ssize; - } - } + RELEASE_MORECORE_LOCK(); + } + + if (HAVE_MMAP && tbase == CMFAIL) { /* Try MMAP */ + size_t req = nb + TOP_FOOT_SIZE + MALLOC_ALIGNMENT + SIZE_T_ONE; + size_t rsize = granularity_align(req); + if (rsize > nb) { /* Fail if wraps around zero */ + char* mp = (char*)(CALL_MMAP(rsize)); + if (mp != CMFAIL) { + tbase = mp; + tsize = rsize; + mmap_flag = IS_MMAPPED_BIT; + } + } + } + + if (HAVE_MORECORE && tbase == CMFAIL) { /* Try noncontiguous MORECORE */ + size_t asize = granularity_align(nb + TOP_FOOT_SIZE + MALLOC_ALIGNMENT + SIZE_T_ONE); + if (asize < HALF_MAX_SIZE_T) { + char* br = CMFAIL; + char* end = CMFAIL; + ACQUIRE_MORECORE_LOCK(); + br = (char*)(CALL_MORECORE(asize)); + end = (char*)(CALL_MORECORE(0)); + RELEASE_MORECORE_LOCK(); + if (br != CMFAIL && end != CMFAIL && br < end) { + size_t ssize = end - br; + if (ssize > nb + TOP_FOOT_SIZE) { + tbase = br; + tsize = ssize; } + } + } + } + + if (tbase != CMFAIL) { + + if ((m->footprint += tsize) > m->max_footprint) + m->max_footprint = m->footprint; + + if (!is_initialized(m)) { /* first-time initialization */ + m->seg.base = m->least_addr = tbase; + m->seg.size = tsize; + m->seg.sflags = mmap_flag; + m->magic = mparams.magic; + init_bins(m); + if (is_global(m)) + init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE); + else { + /* Offset top by embedded malloc_state */ + mchunkptr mn = next_chunk(mem2chunk(m)); + init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) -TOP_FOOT_SIZE); + } } - if (tbase != CMFAIL) { - - if ((m->footprint += tsize) > m->max_footprint) - m->max_footprint = m->footprint; - - if (!is_initialized(m)) { /* first-time initialization */ - m->seg.base = m->least_addr = tbase; - m->seg.size = tsize; - m->seg.sflags = mmap_flag; - m->magic = mparams.magic; - init_bins(m); - if (is_global(m)) - init_top(m, (mchunkptr) tbase, tsize - TOP_FOOT_SIZE); - else { - /* Offset top by embedded malloc_state */ - mchunkptr mn = next_chunk(mem2chunk(m)); - init_top(m, mn, - (size_t) ((tbase + tsize) - (char *) mn) - - TOP_FOOT_SIZE); - } - } - - else { - /* Try to merge with an existing segment */ - msegmentptr sp = &m->seg; - while (sp != 0 && tbase != sp->base + sp->size) - sp = sp->next; - if (sp != 0 && !is_extern_segment(sp) && (sp->sflags & IS_MMAPPED_BIT) == mmap_flag && segment_holds(sp, m->top)) { /* append */ - sp->size += tsize; - init_top(m, m->top, m->topsize + tsize); - } else { - if (tbase < m->least_addr) - m->least_addr = tbase; - sp = &m->seg; - while (sp != 0 && sp->base != tbase + tsize) - sp = sp->next; - if (sp != 0 && - !is_extern_segment(sp) && - (sp->sflags & IS_MMAPPED_BIT) == mmap_flag) { - char *oldbase = sp->base; - sp->base = tbase; - sp->size += tsize; - return prepend_alloc(m, tbase, oldbase, nb); - } else - add_segment(m, tbase, tsize, mmap_flag); - } - } - - if (nb < m->topsize) { /* Allocate from new or extended top space */ - size_t rsize = m->topsize -= nb; - mchunkptr p = m->top; - mchunkptr r = m->top = chunk_plus_offset(p, nb); - r->head = rsize | PINUSE_BIT; - set_size_and_pinuse_of_inuse_chunk(m, p, nb); - check_top_chunk(m, m->top); - check_malloced_chunk(m, chunk2mem(p), nb); - return chunk2mem(p); + else { + /* Try to merge with an existing segment */ + msegmentptr sp = &m->seg; + while (sp != 0 && tbase != sp->base + sp->size) + sp = sp->next; + if (sp != 0 && + !is_extern_segment(sp) && + (sp->sflags & IS_MMAPPED_BIT) == mmap_flag && + segment_holds(sp, m->top)) { /* append */ + sp->size += tsize; + init_top(m, m->top, m->topsize + tsize); + } + else { + if (tbase < m->least_addr) + m->least_addr = tbase; + sp = &m->seg; + while (sp != 0 && sp->base != tbase + tsize) + sp = sp->next; + if (sp != 0 && + !is_extern_segment(sp) && + (sp->sflags & IS_MMAPPED_BIT) == mmap_flag) { + char* oldbase = sp->base; + sp->base = tbase; + sp->size += tsize; + return prepend_alloc(m, tbase, oldbase, nb); } + else + add_segment(m, tbase, tsize, mmap_flag); + } } - MALLOC_FAILURE_ACTION; - return 0; + if (nb < m->topsize) { /* Allocate from new or extended top space */ + size_t rsize = m->topsize -= nb; + mchunkptr p = m->top; + mchunkptr r = m->top = chunk_plus_offset(p, nb); + r->head = rsize | PINUSE_BIT; + set_size_and_pinuse_of_inuse_chunk(m, p, nb); + check_top_chunk(m, m->top); + check_malloced_chunk(m, chunk2mem(p), nb); + return chunk2mem(p); + } + } + + MALLOC_FAILURE_ACTION; + return 0; } /* ----------------------- system deallocation -------------------------- */ /* Unmap and unlink any mmapped segments that don't contain used chunks */ -static size_t -release_unused_segments(mstate m) -{ - size_t released = 0; - msegmentptr pred = &m->seg; - msegmentptr sp = pred->next; - while (sp != 0) { - char *base = sp->base; - size_t size = sp->size; - msegmentptr next = sp->next; - if (is_mmapped_segment(sp) && !is_extern_segment(sp)) { - mchunkptr p = align_as_chunk(base); - size_t psize = chunksize(p); - /* Can unmap if first chunk holds entire segment and not pinned */ - if (!cinuse(p) - && (char *) p + psize >= base + size - TOP_FOOT_SIZE) { - tchunkptr tp = (tchunkptr) p; - assert(segment_holds(sp, (char *) sp)); - if (p == m->dv) { - m->dv = 0; - m->dvsize = 0; - } else { - unlink_large_chunk(m, tp); - } - if (CALL_MUNMAP(base, size) == 0) { - released += size; - m->footprint -= size; - /* unlink obsoleted record */ - sp = pred; - sp->next = next; - } else { /* back out if cannot unmap */ - insert_large_chunk(m, tp, psize); - } - } +static size_t release_unused_segments(mstate m) { + size_t released = 0; + msegmentptr pred = &m->seg; + msegmentptr sp = pred->next; + while (sp != 0) { + char* base = sp->base; + size_t size = sp->size; + msegmentptr next = sp->next; + if (is_mmapped_segment(sp) && !is_extern_segment(sp)) { + mchunkptr p = align_as_chunk(base); + size_t psize = chunksize(p); + /* Can unmap if first chunk holds entire segment and not pinned */ + if (!cinuse(p) && (char*)p + psize >= base + size - TOP_FOOT_SIZE) { + tchunkptr tp = (tchunkptr)p; + assert(segment_holds(sp, (char*)sp)); + if (p == m->dv) { + m->dv = 0; + m->dvsize = 0; } - pred = sp; - sp = next; + else { + unlink_large_chunk(m, tp); + } + if (CALL_MUNMAP(base, size) == 0) { + released += size; + m->footprint -= size; + /* unlink obsoleted record */ + sp = pred; + sp->next = next; + } + else { /* back out if cannot unmap */ + insert_large_chunk(m, tp, psize); + } + } } - return released; + pred = sp; + sp = next; + } + return released; } -static int -sys_trim(mstate m, size_t pad) -{ - size_t released = 0; - if (pad < MAX_REQUEST && is_initialized(m)) { - pad += TOP_FOOT_SIZE; /* ensure enough room for segment overhead */ +static int sys_trim(mstate m, size_t pad) { + size_t released = 0; + if (pad < MAX_REQUEST && is_initialized(m)) { + pad += TOP_FOOT_SIZE; /* ensure enough room for segment overhead */ - if (m->topsize > pad) { - /* Shrink top space in granularity-size units, keeping at least one */ - size_t unit = mparams.granularity; - size_t extra = ((m->topsize - pad + (unit - SIZE_T_ONE)) / unit - - SIZE_T_ONE) * unit; - msegmentptr sp = segment_holding(m, (char *) m->top); + if (m->topsize > pad) { + /* Shrink top space in granularity-size units, keeping at least one */ + size_t unit = mparams.granularity; + size_t extra = ((m->topsize - pad + (unit - SIZE_T_ONE)) / unit - + SIZE_T_ONE) * unit; + msegmentptr sp = segment_holding(m, (char*)m->top); - if (!is_extern_segment(sp)) { - if (is_mmapped_segment(sp)) { - if (HAVE_MMAP && sp->size >= extra && !has_segment_link(m, sp)) { /* can't shrink if pinned */ - size_t newsize = sp->size - extra; - /* Prefer mremap, fall back to munmap */ - if ((CALL_MREMAP(sp->base, sp->size, newsize, 0) != - MFAIL) - || (CALL_MUNMAP(sp->base + newsize, extra) == 0)) { - released = extra; - } - } - } else if (HAVE_MORECORE) { - if (extra >= HALF_MAX_SIZE_T) /* Avoid wrapping negative */ - extra = (HALF_MAX_SIZE_T) + SIZE_T_ONE - unit; - ACQUIRE_MORECORE_LOCK(); - { - /* Make sure end of memory is where we last set it. */ - char *old_br = (char *) (CALL_MORECORE(0)); - if (old_br == sp->base + sp->size) { - char *rel_br = (char *) (CALL_MORECORE(-extra)); - char *new_br = (char *) (CALL_MORECORE(0)); - if (rel_br != CMFAIL && new_br < old_br) - released = old_br - new_br; - } - } - RELEASE_MORECORE_LOCK(); - } - } - - if (released != 0) { - sp->size -= released; - m->footprint -= released; - init_top(m, m->top, m->topsize - released); - check_top_chunk(m, m->top); + if (!is_extern_segment(sp)) { + if (is_mmapped_segment(sp)) { + if (HAVE_MMAP && + sp->size >= extra && + !has_segment_link(m, sp)) { /* can't shrink if pinned */ + size_t newsize = sp->size - extra; + /* Prefer mremap, fall back to munmap */ + if ((CALL_MREMAP(sp->base, sp->size, newsize, 0) != MFAIL) || + (CALL_MUNMAP(sp->base + newsize, extra) == 0)) { + released = extra; } + } } + else if (HAVE_MORECORE) { + if (extra >= HALF_MAX_SIZE_T) /* Avoid wrapping negative */ + extra = (HALF_MAX_SIZE_T) + SIZE_T_ONE - unit; + ACQUIRE_MORECORE_LOCK(); + { + /* Make sure end of memory is where we last set it. */ + char* old_br = (char*)(CALL_MORECORE(0)); + if (old_br == sp->base + sp->size) { + char* rel_br = (char*)(CALL_MORECORE(-extra)); + char* new_br = (char*)(CALL_MORECORE(0)); + if (rel_br != CMFAIL && new_br < old_br) + released = old_br - new_br; + } + } + RELEASE_MORECORE_LOCK(); + } + } - /* Unmap any unused mmapped segments */ - if (HAVE_MMAP) - released += release_unused_segments(m); - - /* On failure, disable autotrim to avoid repeated failed future calls */ - if (released == 0) - m->trim_check = MAX_SIZE_T; + if (released != 0) { + sp->size -= released; + m->footprint -= released; + init_top(m, m->top, m->topsize - released); + check_top_chunk(m, m->top); + } } - return (released != 0) ? 1 : 0; + /* Unmap any unused mmapped segments */ + if (HAVE_MMAP) + released += release_unused_segments(m); + + /* On failure, disable autotrim to avoid repeated failed future calls */ + if (released == 0) + m->trim_check = MAX_SIZE_T; + } + + return (released != 0)? 1 : 0; } /* ---------------------------- malloc support --------------------------- */ /* allocate a large request from the best fitting chunk in a treebin */ -static void * -tmalloc_large(mstate m, size_t nb) -{ - tchunkptr v = 0; - size_t rsize = -nb; /* Unsigned negation */ - tchunkptr t; - bindex_t idx; - compute_tree_index(nb, idx); +static void* tmalloc_large(mstate m, size_t nb) { + tchunkptr v = 0; + size_t rsize = -nb; /* Unsigned negation */ + tchunkptr t; + bindex_t idx; + compute_tree_index(nb, idx); - if ((t = *treebin_at(m, idx)) != 0) { - /* Traverse tree for this bin looking for node with size == nb */ - size_t sizebits = nb << leftshift_for_tree_index(idx); - tchunkptr rst = 0; /* The deepest untaken right subtree */ - for (;;) { - tchunkptr rt; - size_t trem = chunksize(t) - nb; - if (trem < rsize) { - v = t; - if ((rsize = trem) == 0) - break; - } - rt = t->child[1]; - t = t->child[(sizebits >> (SIZE_T_BITSIZE - SIZE_T_ONE)) & 1]; - if (rt != 0 && rt != t) - rst = rt; - if (t == 0) { - t = rst; /* set t to least subtree holding sizes > nb */ - break; - } - sizebits <<= 1; - } + if ((t = *treebin_at(m, idx)) != 0) { + /* Traverse tree for this bin looking for node with size == nb */ + size_t sizebits = nb << leftshift_for_tree_index(idx); + tchunkptr rst = 0; /* The deepest untaken right subtree */ + for (;;) { + tchunkptr rt; + size_t trem = chunksize(t) - nb; + if (trem < rsize) { + v = t; + if ((rsize = trem) == 0) + break; + } + rt = t->child[1]; + t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]; + if (rt != 0 && rt != t) + rst = rt; + if (t == 0) { + t = rst; /* set t to least subtree holding sizes > nb */ + break; + } + sizebits <<= 1; } + } - if (t == 0 && v == 0) { /* set t to root of next non-empty treebin */ - binmap_t leftbits = left_bits(idx2bit(idx)) & m->treemap; - if (leftbits != 0) { - bindex_t i; - binmap_t leastbit = least_bit(leftbits); - compute_bit2idx(leastbit, i); - t = *treebin_at(m, i); - } + if (t == 0 && v == 0) { /* set t to root of next non-empty treebin */ + binmap_t leftbits = left_bits(idx2bit(idx)) & m->treemap; + if (leftbits != 0) { + bindex_t i; + binmap_t leastbit = least_bit(leftbits); + compute_bit2idx(leastbit, i); + t = *treebin_at(m, i); } + } - while (t != 0) { /* find smallest of tree or subtree */ - size_t trem = chunksize(t) - nb; - if (trem < rsize) { - rsize = trem; - v = t; - } - t = leftmost_child(t); + while (t != 0) { /* find smallest of tree or subtree */ + size_t trem = chunksize(t) - nb; + if (trem < rsize) { + rsize = trem; + v = t; } + t = leftmost_child(t); + } - /* If dv is a better fit, return 0 so malloc will use it */ - if (v != 0 && rsize < (size_t) (m->dvsize - nb)) { - if (RTCHECK(ok_address(m, v))) { /* split */ - mchunkptr r = chunk_plus_offset(v, nb); - assert(chunksize(v) == rsize + nb); - if (RTCHECK(ok_next(v, r))) { - unlink_large_chunk(m, v); - if (rsize < MIN_CHUNK_SIZE) - set_inuse_and_pinuse(m, v, (rsize + nb)); - else { - set_size_and_pinuse_of_inuse_chunk(m, v, nb); - set_size_and_pinuse_of_free_chunk(r, rsize); - insert_chunk(m, r, rsize); - } - return chunk2mem(v); - } + /* If dv is a better fit, return 0 so malloc will use it */ + if (v != 0 && rsize < (size_t)(m->dvsize - nb)) { + if (RTCHECK(ok_address(m, v))) { /* split */ + mchunkptr r = chunk_plus_offset(v, nb); + assert(chunksize(v) == rsize + nb); + if (RTCHECK(ok_next(v, r))) { + unlink_large_chunk(m, v); + if (rsize < MIN_CHUNK_SIZE) + set_inuse_and_pinuse(m, v, (rsize + nb)); + else { + set_size_and_pinuse_of_inuse_chunk(m, v, nb); + set_size_and_pinuse_of_free_chunk(r, rsize); + insert_chunk(m, r, rsize); } - CORRUPTION_ERROR_ACTION(m); + return chunk2mem(v); + } } - return 0; + CORRUPTION_ERROR_ACTION(m); + } + return 0; } /* allocate a small request from the best fitting chunk in a treebin */ -static void * -tmalloc_small(mstate m, size_t nb) -{ - tchunkptr t, v; - size_t rsize; - bindex_t i; - binmap_t leastbit = least_bit(m->treemap); - compute_bit2idx(leastbit, i); +static void* tmalloc_small(mstate m, size_t nb) { + tchunkptr t, v; + size_t rsize; + bindex_t i; + binmap_t leastbit = least_bit(m->treemap); + compute_bit2idx(leastbit, i); - v = t = *treebin_at(m, i); - rsize = chunksize(t) - nb; + v = t = *treebin_at(m, i); + rsize = chunksize(t) - nb; - while ((t = leftmost_child(t)) != 0) { - size_t trem = chunksize(t) - nb; - if (trem < rsize) { - rsize = trem; - v = t; - } + while ((t = leftmost_child(t)) != 0) { + size_t trem = chunksize(t) - nb; + if (trem < rsize) { + rsize = trem; + v = t; } + } - if (RTCHECK(ok_address(m, v))) { - mchunkptr r = chunk_plus_offset(v, nb); - assert(chunksize(v) == rsize + nb); - if (RTCHECK(ok_next(v, r))) { - unlink_large_chunk(m, v); - if (rsize < MIN_CHUNK_SIZE) - set_inuse_and_pinuse(m, v, (rsize + nb)); - else { - set_size_and_pinuse_of_inuse_chunk(m, v, nb); - set_size_and_pinuse_of_free_chunk(r, rsize); - replace_dv(m, r, rsize); - } - return chunk2mem(v); - } + if (RTCHECK(ok_address(m, v))) { + mchunkptr r = chunk_plus_offset(v, nb); + assert(chunksize(v) == rsize + nb); + if (RTCHECK(ok_next(v, r))) { + unlink_large_chunk(m, v); + if (rsize < MIN_CHUNK_SIZE) + set_inuse_and_pinuse(m, v, (rsize + nb)); + else { + set_size_and_pinuse_of_inuse_chunk(m, v, nb); + set_size_and_pinuse_of_free_chunk(r, rsize); + replace_dv(m, r, rsize); + } + return chunk2mem(v); } + } - CORRUPTION_ERROR_ACTION(m); - return 0; + CORRUPTION_ERROR_ACTION(m); + return 0; } /* --------------------------- realloc support --------------------------- */ -static void * -internal_realloc(mstate m, void *oldmem, size_t bytes) -{ - if (bytes >= MAX_REQUEST) { - MALLOC_FAILURE_ACTION; - return 0; - } - if (!PREACTION(m)) { - mchunkptr oldp = mem2chunk(oldmem); - size_t oldsize = chunksize(oldp); - mchunkptr next = chunk_plus_offset(oldp, oldsize); - mchunkptr newp = 0; - void *extra = 0; - - /* Try to either shrink or extend into top. Else malloc-copy-free */ - - if (RTCHECK(ok_address(m, oldp) && ok_cinuse(oldp) && - ok_next(oldp, next) && ok_pinuse(next))) { - size_t nb = request2size(bytes); - if (is_mmapped(oldp)) - newp = mmap_resize(m, oldp, nb); - else if (oldsize >= nb) { /* already big enough */ - size_t rsize = oldsize - nb; - newp = oldp; - if (rsize >= MIN_CHUNK_SIZE) { - mchunkptr remainder = chunk_plus_offset(newp, nb); - set_inuse(m, newp, nb); - set_inuse(m, remainder, rsize); - extra = chunk2mem(remainder); - } - } else if (next == m->top && oldsize + m->topsize > nb) { - /* Expand into top */ - size_t newsize = oldsize + m->topsize; - size_t newtopsize = newsize - nb; - mchunkptr newtop = chunk_plus_offset(oldp, nb); - set_inuse(m, oldp, nb); - newtop->head = newtopsize | PINUSE_BIT; - m->top = newtop; - m->topsize = newtopsize; - newp = oldp; - } - } else { - USAGE_ERROR_ACTION(m, oldmem); - POSTACTION(m); - return 0; - } - - POSTACTION(m); - - if (newp != 0) { - if (extra != 0) { - internal_free(m, extra); - } - check_inuse_chunk(m, newp); - return chunk2mem(newp); - } else { - void *newmem = internal_malloc(m, bytes); - if (newmem != 0) { - size_t oc = oldsize - overhead_for(oldp); - memcpy(newmem, oldmem, (oc < bytes) ? oc : bytes); - internal_free(m, oldmem); - } - return newmem; - } - } +static void* internal_realloc(mstate m, void* oldmem, size_t bytes) { + if (bytes >= MAX_REQUEST) { + MALLOC_FAILURE_ACTION; return 0; + } + if (!PREACTION(m)) { + mchunkptr oldp = mem2chunk(oldmem); + size_t oldsize = chunksize(oldp); + mchunkptr next = chunk_plus_offset(oldp, oldsize); + mchunkptr newp = 0; + void* extra = 0; + + /* Try to either shrink or extend into top. Else malloc-copy-free */ + + if (RTCHECK(ok_address(m, oldp) && ok_cinuse(oldp) && + ok_next(oldp, next) && ok_pinuse(next))) { + size_t nb = request2size(bytes); + if (is_mmapped(oldp)) + newp = mmap_resize(m, oldp, nb); + else if (oldsize >= nb) { /* already big enough */ + size_t rsize = oldsize - nb; + newp = oldp; + if (rsize >= MIN_CHUNK_SIZE) { + mchunkptr remainder = chunk_plus_offset(newp, nb); + set_inuse(m, newp, nb); + set_inuse(m, remainder, rsize); + extra = chunk2mem(remainder); + } + } + else if (next == m->top && oldsize + m->topsize > nb) { + /* Expand into top */ + size_t newsize = oldsize + m->topsize; + size_t newtopsize = newsize - nb; + mchunkptr newtop = chunk_plus_offset(oldp, nb); + set_inuse(m, oldp, nb); + newtop->head = newtopsize |PINUSE_BIT; + m->top = newtop; + m->topsize = newtopsize; + newp = oldp; + } + } + else { + USAGE_ERROR_ACTION(m, oldmem); + POSTACTION(m); + return 0; + } + + POSTACTION(m); + + if (newp != 0) { + if (extra != 0) { + internal_free(m, extra); + } + check_inuse_chunk(m, newp); + return chunk2mem(newp); + } + else { + void* newmem = internal_malloc(m, bytes); + if (newmem != 0) { + size_t oc = oldsize - overhead_for(oldp); + memcpy(newmem, oldmem, (oc < bytes)? oc : bytes); + internal_free(m, oldmem); + } + return newmem; + } + } + return 0; } /* --------------------------- memalign support -------------------------- */ -static void * -internal_memalign(mstate m, size_t alignment, size_t bytes) -{ - if (alignment <= MALLOC_ALIGNMENT) /* Can just use malloc */ - return internal_malloc(m, bytes); - if (alignment < MIN_CHUNK_SIZE) /* must be at least a minimum chunk size */ - alignment = MIN_CHUNK_SIZE; - if ((alignment & (alignment - SIZE_T_ONE)) != 0) { /* Ensure a power of 2 */ - size_t a = MALLOC_ALIGNMENT << 1; - while (a < alignment) - a <<= 1; - alignment = a; +static void* internal_memalign(mstate m, size_t alignment, size_t bytes) { + if (alignment <= MALLOC_ALIGNMENT) /* Can just use malloc */ + return internal_malloc(m, bytes); + if (alignment < MIN_CHUNK_SIZE) /* must be at least a minimum chunk size */ + alignment = MIN_CHUNK_SIZE; + if ((alignment & (alignment-SIZE_T_ONE)) != 0) {/* Ensure a power of 2 */ + size_t a = MALLOC_ALIGNMENT << 1; + while (a < alignment) a <<= 1; + alignment = a; + } + + if (bytes >= MAX_REQUEST - alignment) { + if (m != 0) { /* Test isn't needed but avoids compiler warning */ + MALLOC_FAILURE_ACTION; } + } + else { + size_t nb = request2size(bytes); + size_t req = nb + alignment + MIN_CHUNK_SIZE - CHUNK_OVERHEAD; + char* mem = (char*)internal_malloc(m, req); + if (mem != 0) { + void* leader = 0; + void* trailer = 0; + mchunkptr p = mem2chunk(mem); - if (bytes >= MAX_REQUEST - alignment) { - if (m != 0) { /* Test isn't needed but avoids compiler warning */ - MALLOC_FAILURE_ACTION; + if (PREACTION(m)) return 0; + if ((((size_t)(mem)) % alignment) != 0) { /* misaligned */ + /* + Find an aligned spot inside chunk. Since we need to give + back leading space in a chunk of at least MIN_CHUNK_SIZE, if + the first calculation places us at a spot with less than + MIN_CHUNK_SIZE leader, we can move to the next aligned spot. + We've allocated enough total room so that this is always + possible. + */ + char* br = (char*)mem2chunk((size_t)(((size_t)(mem + + alignment - + SIZE_T_ONE)) & + -alignment)); + char* pos = ((size_t)(br - (char*)(p)) >= MIN_CHUNK_SIZE)? + br : br+alignment; + mchunkptr newp = (mchunkptr)pos; + size_t leadsize = pos - (char*)(p); + size_t newsize = chunksize(p) - leadsize; + + if (is_mmapped(p)) { /* For mmapped chunks, just adjust offset */ + newp->prev_foot = p->prev_foot + leadsize; + newp->head = (newsize|CINUSE_BIT); } - } else { - size_t nb = request2size(bytes); - size_t req = nb + alignment + MIN_CHUNK_SIZE - CHUNK_OVERHEAD; - char *mem = (char *) internal_malloc(m, req); - if (mem != 0) { - void *leader = 0; - void *trailer = 0; - mchunkptr p = mem2chunk(mem); - - if (PREACTION(m)) - return 0; - if ((((size_t) (mem)) % alignment) != 0) { /* misaligned */ - /* - Find an aligned spot inside chunk. Since we need to give - back leading space in a chunk of at least MIN_CHUNK_SIZE, if - the first calculation places us at a spot with less than - MIN_CHUNK_SIZE leader, we can move to the next aligned spot. - We've allocated enough total room so that this is always - possible. - */ - char *br = (char *) mem2chunk((size_t) (((size_t) (mem + - alignment - - SIZE_T_ONE)) - & -alignment)); - char *pos = - ((size_t) (br - (char *) (p)) >= - MIN_CHUNK_SIZE) ? br : br + alignment; - mchunkptr newp = (mchunkptr) pos; - size_t leadsize = pos - (char *) (p); - size_t newsize = chunksize(p) - leadsize; - - if (is_mmapped(p)) { /* For mmapped chunks, just adjust offset */ - newp->prev_foot = p->prev_foot + leadsize; - newp->head = (newsize | CINUSE_BIT); - } else { /* Otherwise, give back leader, use the rest */ - set_inuse(m, newp, newsize); - set_inuse(m, p, leadsize); - leader = chunk2mem(p); - } - p = newp; - } - - /* Give back spare room at the end */ - if (!is_mmapped(p)) { - size_t size = chunksize(p); - if (size > nb + MIN_CHUNK_SIZE) { - size_t remainder_size = size - nb; - mchunkptr remainder = chunk_plus_offset(p, nb); - set_inuse(m, p, nb); - set_inuse(m, remainder, remainder_size); - trailer = chunk2mem(remainder); - } - } - - assert(chunksize(p) >= nb); - assert((((size_t) (chunk2mem(p))) % alignment) == 0); - check_inuse_chunk(m, p); - POSTACTION(m); - if (leader != 0) { - internal_free(m, leader); - } - if (trailer != 0) { - internal_free(m, trailer); - } - return chunk2mem(p); + else { /* Otherwise, give back leader, use the rest */ + set_inuse(m, newp, newsize); + set_inuse(m, p, leadsize); + leader = chunk2mem(p); } + p = newp; + } + + /* Give back spare room at the end */ + if (!is_mmapped(p)) { + size_t size = chunksize(p); + if (size > nb + MIN_CHUNK_SIZE) { + size_t remainder_size = size - nb; + mchunkptr remainder = chunk_plus_offset(p, nb); + set_inuse(m, p, nb); + set_inuse(m, remainder, remainder_size); + trailer = chunk2mem(remainder); + } + } + + assert (chunksize(p) >= nb); + assert((((size_t)(chunk2mem(p))) % alignment) == 0); + check_inuse_chunk(m, p); + POSTACTION(m); + if (leader != 0) { + internal_free(m, leader); + } + if (trailer != 0) { + internal_free(m, trailer); + } + return chunk2mem(p); } - return 0; + } + return 0; } /* ------------------------ comalloc/coalloc support --------------------- */ -static void ** -ialloc(mstate m, size_t n_elements, size_t * sizes, int opts, void *chunks[]) -{ - /* - This provides common support for independent_X routines, handling - all of the combinations that can result. +static void** ialloc(mstate m, + size_t n_elements, + size_t* sizes, + int opts, + void* chunks[]) { + /* + This provides common support for independent_X routines, handling + all of the combinations that can result. - The opts arg has: - bit 0 set if all elements are same size (using sizes[0]) - bit 1 set if elements should be zeroed - */ + The opts arg has: + bit 0 set if all elements are same size (using sizes[0]) + bit 1 set if elements should be zeroed + */ - size_t element_size; /* chunksize of each element, if all same */ - size_t contents_size; /* total size of elements */ - size_t array_size; /* request size of pointer array */ - void *mem; /* malloced aggregate space */ - mchunkptr p; /* corresponding chunk */ - size_t remainder_size; /* remaining bytes while splitting */ - void **marray; /* either "chunks" or malloced ptr array */ - mchunkptr array_chunk; /* chunk for malloced ptr array */ - flag_t was_enabled; /* to disable mmap */ - size_t size; - size_t i; + size_t element_size; /* chunksize of each element, if all same */ + size_t contents_size; /* total size of elements */ + size_t array_size; /* request size of pointer array */ + void* mem; /* malloced aggregate space */ + mchunkptr p; /* corresponding chunk */ + size_t remainder_size; /* remaining bytes while splitting */ + void** marray; /* either "chunks" or malloced ptr array */ + mchunkptr array_chunk; /* chunk for malloced ptr array */ + flag_t was_enabled; /* to disable mmap */ + size_t size; + size_t i; - /* compute array length, if needed */ - if (chunks != 0) { - if (n_elements == 0) - return chunks; /* nothing to do */ - marray = chunks; - array_size = 0; - } else { - /* if empty req, must still return chunk representing empty array */ - if (n_elements == 0) - return (void **) internal_malloc(m, 0); - marray = 0; - array_size = request2size(n_elements * (sizeof(void *))); - } + /* compute array length, if needed */ + if (chunks != 0) { + if (n_elements == 0) + return chunks; /* nothing to do */ + marray = chunks; + array_size = 0; + } + else { + /* if empty req, must still return chunk representing empty array */ + if (n_elements == 0) + return (void**)internal_malloc(m, 0); + marray = 0; + array_size = request2size(n_elements * (sizeof(void*))); + } - /* compute total element size */ - if (opts & 0x1) { /* all-same-size */ - element_size = request2size(*sizes); - contents_size = n_elements * element_size; - } else { /* add up all the sizes */ - element_size = 0; - contents_size = 0; - for (i = 0; i != n_elements; ++i) - contents_size += request2size(sizes[i]); - } - - size = contents_size + array_size; - - /* - Allocate the aggregate chunk. First disable direct-mmapping so - malloc won't use it, since we would not be able to later - free/realloc space internal to a segregated mmap region. - */ - was_enabled = use_mmap(m); - disable_mmap(m); - mem = internal_malloc(m, size - CHUNK_OVERHEAD); - if (was_enabled) - enable_mmap(m); - if (mem == 0) - return 0; - - if (PREACTION(m)) - return 0; - p = mem2chunk(mem); - remainder_size = chunksize(p); - - assert(!is_mmapped(p)); - - if (opts & 0x2) { /* optionally clear the elements */ - memset((size_t *) mem, 0, remainder_size - SIZE_T_SIZE - array_size); - } - - /* If not provided, allocate the pointer array as final part of chunk */ - if (marray == 0) { - size_t array_chunk_size; - array_chunk = chunk_plus_offset(p, contents_size); - array_chunk_size = remainder_size - contents_size; - marray = (void **) (chunk2mem(array_chunk)); - set_size_and_pinuse_of_inuse_chunk(m, array_chunk, array_chunk_size); - remainder_size = contents_size; - } - - /* split out elements */ - for (i = 0;; ++i) { - marray[i] = chunk2mem(p); - if (i != n_elements - 1) { - if (element_size != 0) - size = element_size; - else - size = request2size(sizes[i]); - remainder_size -= size; - set_size_and_pinuse_of_inuse_chunk(m, p, size); - p = chunk_plus_offset(p, size); - } else { /* the final element absorbs any overallocation slop */ - set_size_and_pinuse_of_inuse_chunk(m, p, remainder_size); - break; - } - } - -#if DEBUG - if (marray != chunks) { - /* final element must have exactly exhausted chunk */ - if (element_size != 0) { - assert(remainder_size == element_size); - } else { - assert(remainder_size == request2size(sizes[i])); - } - check_inuse_chunk(m, mem2chunk(marray)); - } + /* compute total element size */ + if (opts & 0x1) { /* all-same-size */ + element_size = request2size(*sizes); + contents_size = n_elements * element_size; + } + else { /* add up all the sizes */ + element_size = 0; + contents_size = 0; for (i = 0; i != n_elements; ++i) - check_inuse_chunk(m, mem2chunk(marray[i])); + contents_size += request2size(sizes[i]); + } + + size = contents_size + array_size; + + /* + Allocate the aggregate chunk. First disable direct-mmapping so + malloc won't use it, since we would not be able to later + free/realloc space internal to a segregated mmap region. + */ + was_enabled = use_mmap(m); + disable_mmap(m); + mem = internal_malloc(m, size - CHUNK_OVERHEAD); + if (was_enabled) + enable_mmap(m); + if (mem == 0) + return 0; + + if (PREACTION(m)) return 0; + p = mem2chunk(mem); + remainder_size = chunksize(p); + + assert(!is_mmapped(p)); + + if (opts & 0x2) { /* optionally clear the elements */ + memset((size_t*)mem, 0, remainder_size - SIZE_T_SIZE - array_size); + } + + /* If not provided, allocate the pointer array as final part of chunk */ + if (marray == 0) { + size_t array_chunk_size; + array_chunk = chunk_plus_offset(p, contents_size); + array_chunk_size = remainder_size - contents_size; + marray = (void**) (chunk2mem(array_chunk)); + set_size_and_pinuse_of_inuse_chunk(m, array_chunk, array_chunk_size); + remainder_size = contents_size; + } + + /* split out elements */ + for (i = 0; ; ++i) { + marray[i] = chunk2mem(p); + if (i != n_elements-1) { + if (element_size != 0) + size = element_size; + else + size = request2size(sizes[i]); + remainder_size -= size; + set_size_and_pinuse_of_inuse_chunk(m, p, size); + p = chunk_plus_offset(p, size); + } + else { /* the final element absorbs any overallocation slop */ + set_size_and_pinuse_of_inuse_chunk(m, p, remainder_size); + break; + } + } + +#ifdef DEBUG + if (marray != chunks) { + /* final element must have exactly exhausted chunk */ + if (element_size != 0) { + assert(remainder_size == element_size); + } + else { + assert(remainder_size == request2size(sizes[i])); + } + check_inuse_chunk(m, mem2chunk(marray)); + } + for (i = 0; i != n_elements; ++i) + check_inuse_chunk(m, mem2chunk(marray[i])); #endif /* DEBUG */ - POSTACTION(m); - return marray; + POSTACTION(m); + return marray; } @@ -4209,369 +4150,343 @@ ialloc(mstate m, size_t n_elements, size_t * sizes, int opts, void *chunks[]) #if !ONLY_MSPACES -void * -dlmalloc(size_t bytes) -{ - /* - Basic algorithm: - If a small request (< 256 bytes minus per-chunk overhead): +void* dlmalloc(size_t bytes) { + /* + Basic algorithm: + If a small request (< 256 bytes minus per-chunk overhead): 1. If one exists, use a remainderless chunk in associated smallbin. - (Remainderless means that there are too few excess bytes to - represent as a chunk.) + (Remainderless means that there are too few excess bytes to + represent as a chunk.) 2. If it is big enough, use the dv chunk, which is normally the - chunk adjacent to the one used for the most recent small request. + chunk adjacent to the one used for the most recent small request. 3. If one exists, split the smallest available chunk in a bin, - saving remainder in dv. + saving remainder in dv. 4. If it is big enough, use the top chunk. 5. If available, get memory from system and use it - Otherwise, for a large request: + Otherwise, for a large request: 1. Find the smallest available binned chunk that fits, and use it - if it is better fitting than dv chunk, splitting if necessary. + if it is better fitting than dv chunk, splitting if necessary. 2. If better fitting than any binned chunk, use the dv chunk. 3. If it is big enough, use the top chunk. 4. If request size >= mmap threshold, try to directly mmap this chunk. 5. If available, get memory from system and use it - The ugly goto's here ensure that postaction occurs along all paths. - */ + The ugly goto's here ensure that postaction occurs along all paths. + */ - if (!PREACTION(gm)) { - void *mem; - size_t nb; - if (bytes <= MAX_SMALL_REQUEST) { - bindex_t idx; - binmap_t smallbits; - nb = (bytes < MIN_REQUEST) ? MIN_CHUNK_SIZE : pad_request(bytes); - idx = small_index(nb); - smallbits = gm->smallmap >> idx; + if (!PREACTION(gm)) { + void* mem; + size_t nb; + if (bytes <= MAX_SMALL_REQUEST) { + bindex_t idx; + binmap_t smallbits; + nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes); + idx = small_index(nb); + smallbits = gm->smallmap >> idx; - if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */ - mchunkptr b, p; - idx += ~smallbits & 1; /* Uses next bin if idx empty */ - b = smallbin_at(gm, idx); - p = b->fd; - assert(chunksize(p) == small_index2size(idx)); - unlink_first_small_chunk(gm, b, p, idx); - set_inuse_and_pinuse(gm, p, small_index2size(idx)); - mem = chunk2mem(p); - check_malloced_chunk(gm, mem, nb); - goto postaction; - } + if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */ + mchunkptr b, p; + idx += ~smallbits & 1; /* Uses next bin if idx empty */ + b = smallbin_at(gm, idx); + p = b->fd; + assert(chunksize(p) == small_index2size(idx)); + unlink_first_small_chunk(gm, b, p, idx); + set_inuse_and_pinuse(gm, p, small_index2size(idx)); + mem = chunk2mem(p); + check_malloced_chunk(gm, mem, nb); + goto postaction; + } - else if (nb > gm->dvsize) { - if (smallbits != 0) { /* Use chunk in next nonempty smallbin */ - mchunkptr b, p, r; - size_t rsize; - bindex_t i; - binmap_t leftbits = - (smallbits << idx) & left_bits(idx2bit(idx)); - binmap_t leastbit = least_bit(leftbits); - compute_bit2idx(leastbit, i); - b = smallbin_at(gm, i); - p = b->fd; - assert(chunksize(p) == small_index2size(i)); - unlink_first_small_chunk(gm, b, p, i); - rsize = small_index2size(i) - nb; - /* Fit here cannot be remainderless if 4byte sizes */ - if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE) - set_inuse_and_pinuse(gm, p, small_index2size(i)); - else { - set_size_and_pinuse_of_inuse_chunk(gm, p, nb); - r = chunk_plus_offset(p, nb); - set_size_and_pinuse_of_free_chunk(r, rsize); - replace_dv(gm, r, rsize); - } - mem = chunk2mem(p); - check_malloced_chunk(gm, mem, nb); - goto postaction; - } - - else if (gm->treemap != 0 - && (mem = tmalloc_small(gm, nb)) != 0) { - check_malloced_chunk(gm, mem, nb); - goto postaction; - } - } - } else if (bytes >= MAX_REQUEST) - nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */ - else { - nb = pad_request(bytes); - if (gm->treemap != 0 && (mem = tmalloc_large(gm, nb)) != 0) { - check_malloced_chunk(gm, mem, nb); - goto postaction; - } - } - - if (nb <= gm->dvsize) { - size_t rsize = gm->dvsize - nb; - mchunkptr p = gm->dv; - if (rsize >= MIN_CHUNK_SIZE) { /* split dv */ - mchunkptr r = gm->dv = chunk_plus_offset(p, nb); - gm->dvsize = rsize; - set_size_and_pinuse_of_free_chunk(r, rsize); - set_size_and_pinuse_of_inuse_chunk(gm, p, nb); - } else { /* exhaust dv */ - size_t dvs = gm->dvsize; - gm->dvsize = 0; - gm->dv = 0; - set_inuse_and_pinuse(gm, p, dvs); - } - mem = chunk2mem(p); - check_malloced_chunk(gm, mem, nb); - goto postaction; - } - - else if (nb < gm->topsize) { /* Split top */ - size_t rsize = gm->topsize -= nb; - mchunkptr p = gm->top; - mchunkptr r = gm->top = chunk_plus_offset(p, nb); - r->head = rsize | PINUSE_BIT; + else if (nb > gm->dvsize) { + if (smallbits != 0) { /* Use chunk in next nonempty smallbin */ + mchunkptr b, p, r; + size_t rsize; + bindex_t i; + binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx)); + binmap_t leastbit = least_bit(leftbits); + compute_bit2idx(leastbit, i); + b = smallbin_at(gm, i); + p = b->fd; + assert(chunksize(p) == small_index2size(i)); + unlink_first_small_chunk(gm, b, p, i); + rsize = small_index2size(i) - nb; + /* Fit here cannot be remainderless if 4byte sizes */ + if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE) + set_inuse_and_pinuse(gm, p, small_index2size(i)); + else { set_size_and_pinuse_of_inuse_chunk(gm, p, nb); - mem = chunk2mem(p); - check_top_chunk(gm, gm->top); - check_malloced_chunk(gm, mem, nb); - goto postaction; + r = chunk_plus_offset(p, nb); + set_size_and_pinuse_of_free_chunk(r, rsize); + replace_dv(gm, r, rsize); + } + mem = chunk2mem(p); + check_malloced_chunk(gm, mem, nb); + goto postaction; } - mem = sys_alloc(gm, nb); - - postaction: - POSTACTION(gm); - return mem; + else if (gm->treemap != 0 && (mem = tmalloc_small(gm, nb)) != 0) { + check_malloced_chunk(gm, mem, nb); + goto postaction; + } + } + } + else if (bytes >= MAX_REQUEST) + nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */ + else { + nb = pad_request(bytes); + if (gm->treemap != 0 && (mem = tmalloc_large(gm, nb)) != 0) { + check_malloced_chunk(gm, mem, nb); + goto postaction; + } } - return 0; + if (nb <= gm->dvsize) { + size_t rsize = gm->dvsize - nb; + mchunkptr p = gm->dv; + if (rsize >= MIN_CHUNK_SIZE) { /* split dv */ + mchunkptr r = gm->dv = chunk_plus_offset(p, nb); + gm->dvsize = rsize; + set_size_and_pinuse_of_free_chunk(r, rsize); + set_size_and_pinuse_of_inuse_chunk(gm, p, nb); + } + else { /* exhaust dv */ + size_t dvs = gm->dvsize; + gm->dvsize = 0; + gm->dv = 0; + set_inuse_and_pinuse(gm, p, dvs); + } + mem = chunk2mem(p); + check_malloced_chunk(gm, mem, nb); + goto postaction; + } + + else if (nb < gm->topsize) { /* Split top */ + size_t rsize = gm->topsize -= nb; + mchunkptr p = gm->top; + mchunkptr r = gm->top = chunk_plus_offset(p, nb); + r->head = rsize | PINUSE_BIT; + set_size_and_pinuse_of_inuse_chunk(gm, p, nb); + mem = chunk2mem(p); + check_top_chunk(gm, gm->top); + check_malloced_chunk(gm, mem, nb); + goto postaction; + } + + mem = sys_alloc(gm, nb); + + postaction: + POSTACTION(gm); + return mem; + } + + return 0; } -void -dlfree(void *mem) -{ - /* - Consolidate freed chunks with preceeding or succeeding bordering - free chunks, if they exist, and then place in a bin. Intermixed - with special cases for top, dv, mmapped chunks, and usage errors. - */ +void dlfree(void* mem) { + /* + Consolidate freed chunks with preceeding or succeeding bordering + free chunks, if they exist, and then place in a bin. Intermixed + with special cases for top, dv, mmapped chunks, and usage errors. + */ - if (mem != 0) { - mchunkptr p = mem2chunk(mem); + if (mem != 0) { + mchunkptr p = mem2chunk(mem); #if FOOTERS - mstate fm = get_mstate_for(p); - if (!ok_magic(fm)) { - USAGE_ERROR_ACTION(fm, p); - return; - } + mstate fm = get_mstate_for(p); + if (!ok_magic(fm)) { + USAGE_ERROR_ACTION(fm, p); + return; + } #else /* FOOTERS */ #define fm gm #endif /* FOOTERS */ - if (!PREACTION(fm)) { - check_inuse_chunk(fm, p); - if (RTCHECK(ok_address(fm, p) && ok_cinuse(p))) { - size_t psize = chunksize(p); - mchunkptr next = chunk_plus_offset(p, psize); - if (!pinuse(p)) { - size_t prevsize = p->prev_foot; - if ((prevsize & IS_MMAPPED_BIT) != 0) { - prevsize &= ~IS_MMAPPED_BIT; - psize += prevsize + MMAP_FOOT_PAD; - if (CALL_MUNMAP((char *) p - prevsize, psize) == 0) - fm->footprint -= psize; - goto postaction; - } else { - mchunkptr prev = chunk_minus_offset(p, prevsize); - psize += prevsize; - p = prev; - if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */ - if (p != fm->dv) { - unlink_chunk(fm, p, prevsize); - } else if ((next->head & INUSE_BITS) == - INUSE_BITS) { - fm->dvsize = psize; - set_free_with_pinuse(p, psize, next); - goto postaction; - } - } else - goto erroraction; - } - } - - if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) { - if (!cinuse(next)) { /* consolidate forward */ - if (next == fm->top) { - size_t tsize = fm->topsize += psize; - fm->top = p; - p->head = tsize | PINUSE_BIT; - if (p == fm->dv) { - fm->dv = 0; - fm->dvsize = 0; - } - if (should_trim(fm, tsize)) - sys_trim(fm, 0); - goto postaction; - } else if (next == fm->dv) { - size_t dsize = fm->dvsize += psize; - fm->dv = p; - set_size_and_pinuse_of_free_chunk(p, dsize); - goto postaction; - } else { - size_t nsize = chunksize(next); - psize += nsize; - unlink_chunk(fm, next, nsize); - set_size_and_pinuse_of_free_chunk(p, psize); - if (p == fm->dv) { - fm->dvsize = psize; - goto postaction; - } - } - } else - set_free_with_pinuse(p, psize, next); - insert_chunk(fm, p, psize); - check_free_chunk(fm, p); - goto postaction; - } + if (!PREACTION(fm)) { + check_inuse_chunk(fm, p); + if (RTCHECK(ok_address(fm, p) && ok_cinuse(p))) { + size_t psize = chunksize(p); + mchunkptr next = chunk_plus_offset(p, psize); + if (!pinuse(p)) { + size_t prevsize = p->prev_foot; + if ((prevsize & IS_MMAPPED_BIT) != 0) { + prevsize &= ~IS_MMAPPED_BIT; + psize += prevsize + MMAP_FOOT_PAD; + if (CALL_MUNMAP((char*)p - prevsize, psize) == 0) + fm->footprint -= psize; + goto postaction; + } + else { + mchunkptr prev = chunk_minus_offset(p, prevsize); + psize += prevsize; + p = prev; + if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */ + if (p != fm->dv) { + unlink_chunk(fm, p, prevsize); + } + else if ((next->head & INUSE_BITS) == INUSE_BITS) { + fm->dvsize = psize; + set_free_with_pinuse(p, psize, next); + goto postaction; + } } - erroraction: - USAGE_ERROR_ACTION(fm, p); - postaction: - POSTACTION(fm); + else + goto erroraction; + } } + + if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) { + if (!cinuse(next)) { /* consolidate forward */ + if (next == fm->top) { + size_t tsize = fm->topsize += psize; + fm->top = p; + p->head = tsize | PINUSE_BIT; + if (p == fm->dv) { + fm->dv = 0; + fm->dvsize = 0; + } + if (should_trim(fm, tsize)) + sys_trim(fm, 0); + goto postaction; + } + else if (next == fm->dv) { + size_t dsize = fm->dvsize += psize; + fm->dv = p; + set_size_and_pinuse_of_free_chunk(p, dsize); + goto postaction; + } + else { + size_t nsize = chunksize(next); + psize += nsize; + unlink_chunk(fm, next, nsize); + set_size_and_pinuse_of_free_chunk(p, psize); + if (p == fm->dv) { + fm->dvsize = psize; + goto postaction; + } + } + } + else + set_free_with_pinuse(p, psize, next); + insert_chunk(fm, p, psize); + check_free_chunk(fm, p); + goto postaction; + } + } + erroraction: + USAGE_ERROR_ACTION(fm, p); + postaction: + POSTACTION(fm); } + } #if !FOOTERS #undef fm #endif /* FOOTERS */ } -void * -dlcalloc(size_t n_elements, size_t elem_size) -{ - void *mem; - size_t req = 0; - if (n_elements != 0) { - req = n_elements * elem_size; - if (((n_elements | elem_size) & ~(size_t) 0xffff) && - (req / n_elements != elem_size)) - req = MAX_SIZE_T; /* force downstream failure on overflow */ - } - mem = dlmalloc(req); - if (mem != 0 && calloc_must_clear(mem2chunk(mem))) - memset(mem, 0, req); - return mem; +void* dlcalloc(size_t n_elements, size_t elem_size) { + void* mem; + size_t req = 0; + if (n_elements != 0) { + req = n_elements * elem_size; + if (((n_elements | elem_size) & ~(size_t)0xffff) && + (req / n_elements != elem_size)) + req = MAX_SIZE_T; /* force downstream failure on overflow */ + } + mem = dlmalloc(req); + if (mem != 0 && calloc_must_clear(mem2chunk(mem))) + memset(mem, 0, req); + return mem; } -void * -dlrealloc(void *oldmem, size_t bytes) -{ - if (oldmem == 0) - return dlmalloc(bytes); +void* dlrealloc(void* oldmem, size_t bytes) { + if (oldmem == 0) + return dlmalloc(bytes); #ifdef REALLOC_ZERO_BYTES_FREES - if (bytes == 0) { - dlfree(oldmem); - return 0; - } + if (bytes == 0) { + dlfree(oldmem); + return 0; + } #endif /* REALLOC_ZERO_BYTES_FREES */ - else { + else { #if ! FOOTERS - mstate m = gm; + mstate m = gm; #else /* FOOTERS */ - mstate m = get_mstate_for(mem2chunk(oldmem)); - if (!ok_magic(m)) { - USAGE_ERROR_ACTION(m, oldmem); - return 0; - } + mstate m = get_mstate_for(mem2chunk(oldmem)); + if (!ok_magic(m)) { + USAGE_ERROR_ACTION(m, oldmem); + return 0; + } #endif /* FOOTERS */ - return internal_realloc(m, oldmem, bytes); - } + return internal_realloc(m, oldmem, bytes); + } } -void * -dlmemalign(size_t alignment, size_t bytes) -{ - return internal_memalign(gm, alignment, bytes); +void* dlmemalign(size_t alignment, size_t bytes) { + return internal_memalign(gm, alignment, bytes); } -void ** -dlindependent_calloc(size_t n_elements, size_t elem_size, void *chunks[]) -{ - size_t sz = elem_size; /* serves as 1-element array */ - return ialloc(gm, n_elements, &sz, 3, chunks); +void** dlindependent_calloc(size_t n_elements, size_t elem_size, + void* chunks[]) { + size_t sz = elem_size; /* serves as 1-element array */ + return ialloc(gm, n_elements, &sz, 3, chunks); } -void ** -dlindependent_comalloc(size_t n_elements, size_t sizes[], void *chunks[]) -{ - return ialloc(gm, n_elements, sizes, 0, chunks); +void** dlindependent_comalloc(size_t n_elements, size_t sizes[], + void* chunks[]) { + return ialloc(gm, n_elements, sizes, 0, chunks); } -void * -dlvalloc(size_t bytes) -{ - size_t pagesz; - init_mparams(); - pagesz = mparams.page_size; - return dlmemalign(pagesz, bytes); +void* dlvalloc(size_t bytes) { + size_t pagesz; + init_mparams(); + pagesz = mparams.page_size; + return dlmemalign(pagesz, bytes); } -void * -dlpvalloc(size_t bytes) -{ - size_t pagesz; - init_mparams(); - pagesz = mparams.page_size; - return dlmemalign(pagesz, - (bytes + pagesz - SIZE_T_ONE) & ~(pagesz - SIZE_T_ONE)); +void* dlpvalloc(size_t bytes) { + size_t pagesz; + init_mparams(); + pagesz = mparams.page_size; + return dlmemalign(pagesz, (bytes + pagesz - SIZE_T_ONE) & ~(pagesz - SIZE_T_ONE)); } -int -dlmalloc_trim(size_t pad) -{ - int result = 0; - if (!PREACTION(gm)) { - result = sys_trim(gm, pad); - POSTACTION(gm); - } - return result; +int dlmalloc_trim(size_t pad) { + int result = 0; + if (!PREACTION(gm)) { + result = sys_trim(gm, pad); + POSTACTION(gm); + } + return result; } -size_t -dlmalloc_footprint(void) -{ - return gm->footprint; +size_t dlmalloc_footprint(void) { + return gm->footprint; } -size_t -dlmalloc_max_footprint(void) -{ - return gm->max_footprint; +size_t dlmalloc_max_footprint(void) { + return gm->max_footprint; } #if !NO_MALLINFO -struct mallinfo -dlmallinfo(void) -{ - return internal_mallinfo(gm); +struct mallinfo dlmallinfo(void) { + return internal_mallinfo(gm); } #endif /* NO_MALLINFO */ -void -dlmalloc_stats() -{ - internal_malloc_stats(gm); +void dlmalloc_stats() { + internal_malloc_stats(gm); } -size_t -dlmalloc_usable_size(void *mem) -{ - if (mem != 0) { - mchunkptr p = mem2chunk(mem); - if (cinuse(p)) - return chunksize(p) - overhead_for(p); - } - return 0; +size_t dlmalloc_usable_size(void* mem) { + if (mem != 0) { + mchunkptr p = mem2chunk(mem); + if (cinuse(p)) + return chunksize(p) - overhead_for(p); + } + return 0; } -int -dlmallopt(int param_number, int value) -{ - return change_mparam(param_number, value); +int dlmallopt(int param_number, int value) { + return change_mparam(param_number, value); } #endif /* !ONLY_MSPACES */ @@ -4580,85 +4495,78 @@ dlmallopt(int param_number, int value) #if MSPACES -static mstate -init_user_mstate(char *tbase, size_t tsize) -{ - size_t msize = pad_request(sizeof(struct malloc_state)); - mchunkptr mn; - mchunkptr msp = align_as_chunk(tbase); - mstate m = (mstate) (chunk2mem(msp)); - memset(m, 0, msize); - INITIAL_LOCK(&m->mutex); - msp->head = (msize | PINUSE_BIT | CINUSE_BIT); - m->seg.base = m->least_addr = tbase; - m->seg.size = m->footprint = m->max_footprint = tsize; - m->magic = mparams.magic; - m->mflags = mparams.default_mflags; - disable_contiguous(m); - init_bins(m); - mn = next_chunk(mem2chunk(m)); - init_top(m, mn, (size_t) ((tbase + tsize) - (char *) mn) - TOP_FOOT_SIZE); - check_top_chunk(m, m->top); - return m; +static mstate init_user_mstate(char* tbase, size_t tsize) { + size_t msize = pad_request(sizeof(struct malloc_state)); + mchunkptr mn; + mchunkptr msp = align_as_chunk(tbase); + mstate m = (mstate)(chunk2mem(msp)); + memset(m, 0, msize); + INITIAL_LOCK(&m->mutex); + msp->head = (msize|PINUSE_BIT|CINUSE_BIT); + m->seg.base = m->least_addr = tbase; + m->seg.size = m->footprint = m->max_footprint = tsize; + m->magic = mparams.magic; + m->mflags = mparams.default_mflags; + disable_contiguous(m); + init_bins(m); + mn = next_chunk(mem2chunk(m)); + init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) - TOP_FOOT_SIZE); + check_top_chunk(m, m->top); + return m; } -mspace -create_mspace(size_t capacity, int locked) -{ - mstate m = 0; - size_t msize = pad_request(sizeof(struct malloc_state)); - init_mparams(); /* Ensure pagesize etc initialized */ +mspace create_mspace(size_t capacity, int locked) { + mstate m = 0; + size_t msize = pad_request(sizeof(struct malloc_state)); + init_mparams(); /* Ensure pagesize etc initialized */ - if (capacity < (size_t) - (msize + TOP_FOOT_SIZE + mparams.page_size)) { - size_t rs = ((capacity == 0) ? mparams.granularity : - (capacity + TOP_FOOT_SIZE + msize)); - size_t tsize = granularity_align(rs); - char *tbase = (char *) (CALL_MMAP(tsize)); - if (tbase != CMFAIL) { - m = init_user_mstate(tbase, tsize); - m->seg.sflags = IS_MMAPPED_BIT; - set_lock(m, locked); - } + if (capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) { + size_t rs = ((capacity == 0)? mparams.granularity : + (capacity + TOP_FOOT_SIZE + msize)); + size_t tsize = granularity_align(rs); + char* tbase = (char*)(CALL_MMAP(tsize)); + if (tbase != CMFAIL) { + m = init_user_mstate(tbase, tsize); + m->seg.sflags = IS_MMAPPED_BIT; + set_lock(m, locked); } - return (mspace) m; + } + return (mspace)m; } -mspace -create_mspace_with_base(void *base, size_t capacity, int locked) -{ - mstate m = 0; - size_t msize = pad_request(sizeof(struct malloc_state)); - init_mparams(); /* Ensure pagesize etc initialized */ +mspace create_mspace_with_base(void* base, size_t capacity, int locked) { + mstate m = 0; + size_t msize = pad_request(sizeof(struct malloc_state)); + init_mparams(); /* Ensure pagesize etc initialized */ - if (capacity > msize + TOP_FOOT_SIZE && - capacity < (size_t) - (msize + TOP_FOOT_SIZE + mparams.page_size)) { - m = init_user_mstate((char *) base, capacity); - m->seg.sflags = EXTERN_BIT; - set_lock(m, locked); - } - return (mspace) m; + if (capacity > msize + TOP_FOOT_SIZE && + capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) { + m = init_user_mstate((char*)base, capacity); + m->seg.sflags = EXTERN_BIT; + set_lock(m, locked); + } + return (mspace)m; } -size_t -destroy_mspace(mspace msp) -{ - size_t freed = 0; - mstate ms = (mstate) msp; - if (ok_magic(ms)) { - msegmentptr sp = &ms->seg; - while (sp != 0) { - char *base = sp->base; - size_t size = sp->size; - flag_t flag = sp->sflags; - sp = sp->next; - if ((flag & IS_MMAPPED_BIT) && !(flag & EXTERN_BIT) && - CALL_MUNMAP(base, size) == 0) - freed += size; - } - } else { - USAGE_ERROR_ACTION(ms, ms); +size_t destroy_mspace(mspace msp) { + size_t freed = 0; + mstate ms = (mstate)msp; + if (ok_magic(ms)) { + msegmentptr sp = &ms->seg; + while (sp != 0) { + char* base = sp->base; + size_t size = sp->size; + flag_t flag = sp->sflags; + sp = sp->next; + if ((flag & IS_MMAPPED_BIT) && !(flag & EXTERN_BIT) && + CALL_MUNMAP(base, size) == 0) + freed += size; } - return freed; + } + else { + USAGE_ERROR_ACTION(ms,ms); + } + return freed; } /* @@ -4667,363 +4575,344 @@ destroy_mspace(mspace msp) */ -void * -mspace_malloc(mspace msp, size_t bytes) -{ - mstate ms = (mstate) msp; - if (!ok_magic(ms)) { - USAGE_ERROR_ACTION(ms, ms); - return 0; - } - if (!PREACTION(ms)) { - void *mem; - size_t nb; - if (bytes <= MAX_SMALL_REQUEST) { - bindex_t idx; - binmap_t smallbits; - nb = (bytes < MIN_REQUEST) ? MIN_CHUNK_SIZE : pad_request(bytes); - idx = small_index(nb); - smallbits = ms->smallmap >> idx; - - if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */ - mchunkptr b, p; - idx += ~smallbits & 1; /* Uses next bin if idx empty */ - b = smallbin_at(ms, idx); - p = b->fd; - assert(chunksize(p) == small_index2size(idx)); - unlink_first_small_chunk(ms, b, p, idx); - set_inuse_and_pinuse(ms, p, small_index2size(idx)); - mem = chunk2mem(p); - check_malloced_chunk(ms, mem, nb); - goto postaction; - } - - else if (nb > ms->dvsize) { - if (smallbits != 0) { /* Use chunk in next nonempty smallbin */ - mchunkptr b, p, r; - size_t rsize; - bindex_t i; - binmap_t leftbits = - (smallbits << idx) & left_bits(idx2bit(idx)); - binmap_t leastbit = least_bit(leftbits); - compute_bit2idx(leastbit, i); - b = smallbin_at(ms, i); - p = b->fd; - assert(chunksize(p) == small_index2size(i)); - unlink_first_small_chunk(ms, b, p, i); - rsize = small_index2size(i) - nb; - /* Fit here cannot be remainderless if 4byte sizes */ - if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE) - set_inuse_and_pinuse(ms, p, small_index2size(i)); - else { - set_size_and_pinuse_of_inuse_chunk(ms, p, nb); - r = chunk_plus_offset(p, nb); - set_size_and_pinuse_of_free_chunk(r, rsize); - replace_dv(ms, r, rsize); - } - mem = chunk2mem(p); - check_malloced_chunk(ms, mem, nb); - goto postaction; - } - - else if (ms->treemap != 0 - && (mem = tmalloc_small(ms, nb)) != 0) { - check_malloced_chunk(ms, mem, nb); - goto postaction; - } - } - } else if (bytes >= MAX_REQUEST) - nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */ - else { - nb = pad_request(bytes); - if (ms->treemap != 0 && (mem = tmalloc_large(ms, nb)) != 0) { - check_malloced_chunk(ms, mem, nb); - goto postaction; - } - } - - if (nb <= ms->dvsize) { - size_t rsize = ms->dvsize - nb; - mchunkptr p = ms->dv; - if (rsize >= MIN_CHUNK_SIZE) { /* split dv */ - mchunkptr r = ms->dv = chunk_plus_offset(p, nb); - ms->dvsize = rsize; - set_size_and_pinuse_of_free_chunk(r, rsize); - set_size_and_pinuse_of_inuse_chunk(ms, p, nb); - } else { /* exhaust dv */ - size_t dvs = ms->dvsize; - ms->dvsize = 0; - ms->dv = 0; - set_inuse_and_pinuse(ms, p, dvs); - } - mem = chunk2mem(p); - check_malloced_chunk(ms, mem, nb); - goto postaction; - } - - else if (nb < ms->topsize) { /* Split top */ - size_t rsize = ms->topsize -= nb; - mchunkptr p = ms->top; - mchunkptr r = ms->top = chunk_plus_offset(p, nb); - r->head = rsize | PINUSE_BIT; - set_size_and_pinuse_of_inuse_chunk(ms, p, nb); - mem = chunk2mem(p); - check_top_chunk(ms, ms->top); - check_malloced_chunk(ms, mem, nb); - goto postaction; - } - - mem = sys_alloc(ms, nb); - - postaction: - POSTACTION(ms); - return mem; - } - +void* mspace_malloc(mspace msp, size_t bytes) { + mstate ms = (mstate)msp; + if (!ok_magic(ms)) { + USAGE_ERROR_ACTION(ms,ms); return 0; -} + } + if (!PREACTION(ms)) { + void* mem; + size_t nb; + if (bytes <= MAX_SMALL_REQUEST) { + bindex_t idx; + binmap_t smallbits; + nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes); + idx = small_index(nb); + smallbits = ms->smallmap >> idx; -void -mspace_free(mspace msp, void *mem) -{ - if (mem != 0) { - mchunkptr p = mem2chunk(mem); -#if FOOTERS - mstate fm = get_mstate_for(p); -#else /* FOOTERS */ - mstate fm = (mstate) msp; -#endif /* FOOTERS */ - if (!ok_magic(fm)) { - USAGE_ERROR_ACTION(fm, p); - return; + if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */ + mchunkptr b, p; + idx += ~smallbits & 1; /* Uses next bin if idx empty */ + b = smallbin_at(ms, idx); + p = b->fd; + assert(chunksize(p) == small_index2size(idx)); + unlink_first_small_chunk(ms, b, p, idx); + set_inuse_and_pinuse(ms, p, small_index2size(idx)); + mem = chunk2mem(p); + check_malloced_chunk(ms, mem, nb); + goto postaction; + } + + else if (nb > ms->dvsize) { + if (smallbits != 0) { /* Use chunk in next nonempty smallbin */ + mchunkptr b, p, r; + size_t rsize; + bindex_t i; + binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx)); + binmap_t leastbit = least_bit(leftbits); + compute_bit2idx(leastbit, i); + b = smallbin_at(ms, i); + p = b->fd; + assert(chunksize(p) == small_index2size(i)); + unlink_first_small_chunk(ms, b, p, i); + rsize = small_index2size(i) - nb; + /* Fit here cannot be remainderless if 4byte sizes */ + if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE) + set_inuse_and_pinuse(ms, p, small_index2size(i)); + else { + set_size_and_pinuse_of_inuse_chunk(ms, p, nb); + r = chunk_plus_offset(p, nb); + set_size_and_pinuse_of_free_chunk(r, rsize); + replace_dv(ms, r, rsize); + } + mem = chunk2mem(p); + check_malloced_chunk(ms, mem, nb); + goto postaction; } - if (!PREACTION(fm)) { - check_inuse_chunk(fm, p); - if (RTCHECK(ok_address(fm, p) && ok_cinuse(p))) { - size_t psize = chunksize(p); - mchunkptr next = chunk_plus_offset(p, psize); - if (!pinuse(p)) { - size_t prevsize = p->prev_foot; - if ((prevsize & IS_MMAPPED_BIT) != 0) { - prevsize &= ~IS_MMAPPED_BIT; - psize += prevsize + MMAP_FOOT_PAD; - if (CALL_MUNMAP((char *) p - prevsize, psize) == 0) - fm->footprint -= psize; - goto postaction; - } else { - mchunkptr prev = chunk_minus_offset(p, prevsize); - psize += prevsize; - p = prev; - if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */ - if (p != fm->dv) { - unlink_chunk(fm, p, prevsize); - } else if ((next->head & INUSE_BITS) == - INUSE_BITS) { - fm->dvsize = psize; - set_free_with_pinuse(p, psize, next); - goto postaction; - } - } else - goto erroraction; - } - } - if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) { - if (!cinuse(next)) { /* consolidate forward */ - if (next == fm->top) { - size_t tsize = fm->topsize += psize; - fm->top = p; - p->head = tsize | PINUSE_BIT; - if (p == fm->dv) { - fm->dv = 0; - fm->dvsize = 0; - } - if (should_trim(fm, tsize)) - sys_trim(fm, 0); - goto postaction; - } else if (next == fm->dv) { - size_t dsize = fm->dvsize += psize; - fm->dv = p; - set_size_and_pinuse_of_free_chunk(p, dsize); - goto postaction; - } else { - size_t nsize = chunksize(next); - psize += nsize; - unlink_chunk(fm, next, nsize); - set_size_and_pinuse_of_free_chunk(p, psize); - if (p == fm->dv) { - fm->dvsize = psize; - goto postaction; - } - } - } else - set_free_with_pinuse(p, psize, next); - insert_chunk(fm, p, psize); - check_free_chunk(fm, p); - goto postaction; - } - } - erroraction: - USAGE_ERROR_ACTION(fm, p); - postaction: - POSTACTION(fm); + else if (ms->treemap != 0 && (mem = tmalloc_small(ms, nb)) != 0) { + check_malloced_chunk(ms, mem, nb); + goto postaction; } + } } -} - -void * -mspace_calloc(mspace msp, size_t n_elements, size_t elem_size) -{ - void *mem; - size_t req = 0; - mstate ms = (mstate) msp; - if (!ok_magic(ms)) { - USAGE_ERROR_ACTION(ms, ms); - return 0; - } - if (n_elements != 0) { - req = n_elements * elem_size; - if (((n_elements | elem_size) & ~(size_t) 0xffff) && - (req / n_elements != elem_size)) - req = MAX_SIZE_T; /* force downstream failure on overflow */ - } - mem = internal_malloc(ms, req); - if (mem != 0 && calloc_must_clear(mem2chunk(mem))) - memset(mem, 0, req); - return mem; -} - -void * -mspace_realloc(mspace msp, void *oldmem, size_t bytes) -{ - if (oldmem == 0) - return mspace_malloc(msp, bytes); -#ifdef REALLOC_ZERO_BYTES_FREES - if (bytes == 0) { - mspace_free(msp, oldmem); - return 0; - } -#endif /* REALLOC_ZERO_BYTES_FREES */ + else if (bytes >= MAX_REQUEST) + nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */ else { + nb = pad_request(bytes); + if (ms->treemap != 0 && (mem = tmalloc_large(ms, nb)) != 0) { + check_malloced_chunk(ms, mem, nb); + goto postaction; + } + } + + if (nb <= ms->dvsize) { + size_t rsize = ms->dvsize - nb; + mchunkptr p = ms->dv; + if (rsize >= MIN_CHUNK_SIZE) { /* split dv */ + mchunkptr r = ms->dv = chunk_plus_offset(p, nb); + ms->dvsize = rsize; + set_size_and_pinuse_of_free_chunk(r, rsize); + set_size_and_pinuse_of_inuse_chunk(ms, p, nb); + } + else { /* exhaust dv */ + size_t dvs = ms->dvsize; + ms->dvsize = 0; + ms->dv = 0; + set_inuse_and_pinuse(ms, p, dvs); + } + mem = chunk2mem(p); + check_malloced_chunk(ms, mem, nb); + goto postaction; + } + + else if (nb < ms->topsize) { /* Split top */ + size_t rsize = ms->topsize -= nb; + mchunkptr p = ms->top; + mchunkptr r = ms->top = chunk_plus_offset(p, nb); + r->head = rsize | PINUSE_BIT; + set_size_and_pinuse_of_inuse_chunk(ms, p, nb); + mem = chunk2mem(p); + check_top_chunk(ms, ms->top); + check_malloced_chunk(ms, mem, nb); + goto postaction; + } + + mem = sys_alloc(ms, nb); + + postaction: + POSTACTION(ms); + return mem; + } + + return 0; +} + +void mspace_free(mspace msp, void* mem) { + if (mem != 0) { + mchunkptr p = mem2chunk(mem); #if FOOTERS - mchunkptr p = mem2chunk(oldmem); - mstate ms = get_mstate_for(p); + mstate fm = get_mstate_for(p); #else /* FOOTERS */ - mstate ms = (mstate) msp; + mstate fm = (mstate)msp; #endif /* FOOTERS */ - if (!ok_magic(ms)) { - USAGE_ERROR_ACTION(ms, ms); - return 0; + if (!ok_magic(fm)) { + USAGE_ERROR_ACTION(fm, p); + return; + } + if (!PREACTION(fm)) { + check_inuse_chunk(fm, p); + if (RTCHECK(ok_address(fm, p) && ok_cinuse(p))) { + size_t psize = chunksize(p); + mchunkptr next = chunk_plus_offset(p, psize); + if (!pinuse(p)) { + size_t prevsize = p->prev_foot; + if ((prevsize & IS_MMAPPED_BIT) != 0) { + prevsize &= ~IS_MMAPPED_BIT; + psize += prevsize + MMAP_FOOT_PAD; + if (CALL_MUNMAP((char*)p - prevsize, psize) == 0) + fm->footprint -= psize; + goto postaction; + } + else { + mchunkptr prev = chunk_minus_offset(p, prevsize); + psize += prevsize; + p = prev; + if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */ + if (p != fm->dv) { + unlink_chunk(fm, p, prevsize); + } + else if ((next->head & INUSE_BITS) == INUSE_BITS) { + fm->dvsize = psize; + set_free_with_pinuse(p, psize, next); + goto postaction; + } + } + else + goto erroraction; + } } - return internal_realloc(ms, oldmem, bytes); - } -} -void * -mspace_memalign(mspace msp, size_t alignment, size_t bytes) -{ - mstate ms = (mstate) msp; - if (!ok_magic(ms)) { - USAGE_ERROR_ACTION(ms, ms); - return 0; - } - return internal_memalign(ms, alignment, bytes); -} - -void ** -mspace_independent_calloc(mspace msp, size_t n_elements, - size_t elem_size, void *chunks[]) -{ - size_t sz = elem_size; /* serves as 1-element array */ - mstate ms = (mstate) msp; - if (!ok_magic(ms)) { - USAGE_ERROR_ACTION(ms, ms); - return 0; - } - return ialloc(ms, n_elements, &sz, 3, chunks); -} - -void ** -mspace_independent_comalloc(mspace msp, size_t n_elements, - size_t sizes[], void *chunks[]) -{ - mstate ms = (mstate) msp; - if (!ok_magic(ms)) { - USAGE_ERROR_ACTION(ms, ms); - return 0; - } - return ialloc(ms, n_elements, sizes, 0, chunks); -} - -int -mspace_trim(mspace msp, size_t pad) -{ - int result = 0; - mstate ms = (mstate) msp; - if (ok_magic(ms)) { - if (!PREACTION(ms)) { - result = sys_trim(ms, pad); - POSTACTION(ms); + if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) { + if (!cinuse(next)) { /* consolidate forward */ + if (next == fm->top) { + size_t tsize = fm->topsize += psize; + fm->top = p; + p->head = tsize | PINUSE_BIT; + if (p == fm->dv) { + fm->dv = 0; + fm->dvsize = 0; + } + if (should_trim(fm, tsize)) + sys_trim(fm, 0); + goto postaction; + } + else if (next == fm->dv) { + size_t dsize = fm->dvsize += psize; + fm->dv = p; + set_size_and_pinuse_of_free_chunk(p, dsize); + goto postaction; + } + else { + size_t nsize = chunksize(next); + psize += nsize; + unlink_chunk(fm, next, nsize); + set_size_and_pinuse_of_free_chunk(p, psize); + if (p == fm->dv) { + fm->dvsize = psize; + goto postaction; + } + } + } + else + set_free_with_pinuse(p, psize, next); + insert_chunk(fm, p, psize); + check_free_chunk(fm, p); + goto postaction; } - } else { - USAGE_ERROR_ACTION(ms, ms); + } + erroraction: + USAGE_ERROR_ACTION(fm, p); + postaction: + POSTACTION(fm); } - return result; + } } -void -mspace_malloc_stats(mspace msp) -{ - mstate ms = (mstate) msp; - if (ok_magic(ms)) { - internal_malloc_stats(ms); - } else { - USAGE_ERROR_ACTION(ms, ms); - } +void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size) { + void* mem; + size_t req = 0; + mstate ms = (mstate)msp; + if (!ok_magic(ms)) { + USAGE_ERROR_ACTION(ms,ms); + return 0; + } + if (n_elements != 0) { + req = n_elements * elem_size; + if (((n_elements | elem_size) & ~(size_t)0xffff) && + (req / n_elements != elem_size)) + req = MAX_SIZE_T; /* force downstream failure on overflow */ + } + mem = internal_malloc(ms, req); + if (mem != 0 && calloc_must_clear(mem2chunk(mem))) + memset(mem, 0, req); + return mem; } -size_t -mspace_footprint(mspace msp) -{ - size_t result; - mstate ms = (mstate) msp; - if (ok_magic(ms)) { - result = ms->footprint; +void* mspace_realloc(mspace msp, void* oldmem, size_t bytes) { + if (oldmem == 0) + return mspace_malloc(msp, bytes); +#ifdef REALLOC_ZERO_BYTES_FREES + if (bytes == 0) { + mspace_free(msp, oldmem); + return 0; + } +#endif /* REALLOC_ZERO_BYTES_FREES */ + else { +#if FOOTERS + mchunkptr p = mem2chunk(oldmem); + mstate ms = get_mstate_for(p); +#else /* FOOTERS */ + mstate ms = (mstate)msp; +#endif /* FOOTERS */ + if (!ok_magic(ms)) { + USAGE_ERROR_ACTION(ms,ms); + return 0; } - USAGE_ERROR_ACTION(ms, ms); - return result; + return internal_realloc(ms, oldmem, bytes); + } +} + +void* mspace_memalign(mspace msp, size_t alignment, size_t bytes) { + mstate ms = (mstate)msp; + if (!ok_magic(ms)) { + USAGE_ERROR_ACTION(ms,ms); + return 0; + } + return internal_memalign(ms, alignment, bytes); +} + +void** mspace_independent_calloc(mspace msp, size_t n_elements, + size_t elem_size, void* chunks[]) { + size_t sz = elem_size; /* serves as 1-element array */ + mstate ms = (mstate)msp; + if (!ok_magic(ms)) { + USAGE_ERROR_ACTION(ms,ms); + return 0; + } + return ialloc(ms, n_elements, &sz, 3, chunks); +} + +void** mspace_independent_comalloc(mspace msp, size_t n_elements, + size_t sizes[], void* chunks[]) { + mstate ms = (mstate)msp; + if (!ok_magic(ms)) { + USAGE_ERROR_ACTION(ms,ms); + return 0; + } + return ialloc(ms, n_elements, sizes, 0, chunks); +} + +int mspace_trim(mspace msp, size_t pad) { + int result = 0; + mstate ms = (mstate)msp; + if (ok_magic(ms)) { + if (!PREACTION(ms)) { + result = sys_trim(ms, pad); + POSTACTION(ms); + } + } + else { + USAGE_ERROR_ACTION(ms,ms); + } + return result; +} + +void mspace_malloc_stats(mspace msp) { + mstate ms = (mstate)msp; + if (ok_magic(ms)) { + internal_malloc_stats(ms); + } + else { + USAGE_ERROR_ACTION(ms,ms); + } +} + +size_t mspace_footprint(mspace msp) { + size_t result; + mstate ms = (mstate)msp; + if (ok_magic(ms)) { + result = ms->footprint; + } + USAGE_ERROR_ACTION(ms,ms); + return result; } -size_t -mspace_max_footprint(mspace msp) -{ - size_t result; - mstate ms = (mstate) msp; - if (ok_magic(ms)) { - result = ms->max_footprint; - } - USAGE_ERROR_ACTION(ms, ms); - return result; +size_t mspace_max_footprint(mspace msp) { + size_t result; + mstate ms = (mstate)msp; + if (ok_magic(ms)) { + result = ms->max_footprint; + } + USAGE_ERROR_ACTION(ms,ms); + return result; } #if !NO_MALLINFO -struct mallinfo -mspace_mallinfo(mspace msp) -{ - mstate ms = (mstate) msp; - if (!ok_magic(ms)) { - USAGE_ERROR_ACTION(ms, ms); - } - return internal_mallinfo(ms); +struct mallinfo mspace_mallinfo(mspace msp) { + mstate ms = (mstate)msp; + if (!ok_magic(ms)) { + USAGE_ERROR_ACTION(ms,ms); + } + return internal_mallinfo(ms); } #endif /* NO_MALLINFO */ -int -mspace_mallopt(int param_number, int value) -{ - return change_mparam(param_number, value); +int mspace_mallopt(int param_number, int value) { + return change_mparam(param_number, value); } #endif /* MSPACES */ @@ -5304,10 +5193,10 @@ History: #endif /* !HAVE_MALLOC */ #ifdef HAVE_MALLOC -#define real_malloc malloc -#define real_calloc calloc -#define real_realloc realloc -#define real_free free +static void* SDLCALL real_malloc(size_t s) { return malloc(s); } +static void* SDLCALL real_calloc(size_t n, size_t s) { return calloc(n, s); } +static void* SDLCALL real_realloc(void *p, size_t s) { return realloc(p,s); } +static void SDLCALL real_free(void *p) { free(p); } #else #define real_malloc dlmalloc #define real_calloc dlcalloc @@ -5327,6 +5216,25 @@ static struct real_malloc, real_calloc, real_realloc, real_free, { 0 } }; +void SDL_GetOriginalMemoryFunctions(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 = real_malloc; + } + if (calloc_func) { + *calloc_func = real_calloc; + } + if (realloc_func) { + *realloc_func = real_realloc; + } + if (free_func) { + *free_func = real_free; + } +} + void SDL_GetMemoryFunctions(SDL_malloc_func *malloc_func, SDL_calloc_func *calloc_func, SDL_realloc_func *realloc_func, diff --git a/SDL2-2.0.12/src/stdlib/SDL_stdlib.c b/SDL2-2.30.5/src/stdlib/SDL_mslibc.c similarity index 67% rename from SDL2-2.0.12/src/stdlib/SDL_stdlib.c rename to SDL2-2.30.5/src/stdlib/SDL_mslibc.c index c2774cb..3b3e7e2 100644 --- a/SDL2-2.0.12/src/stdlib/SDL_stdlib.c +++ b/SDL2-2.30.5/src/stdlib/SDL_mslibc.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -25,434 +25,10 @@ #include "../SDL_internal.h" -/* This file contains portable stdlib functions for SDL */ +/* This file contains SDL replacements for functions in the C library */ -#include "SDL_stdinc.h" -#include "../libm/math_libm.h" +#if !defined(HAVE_LIBC) && !defined(SDL_STATIC_LIB) - -double -SDL_atan(double x) -{ -#if defined(HAVE_ATAN) - return atan(x); -#else - return SDL_uclibc_atan(x); -#endif -} - -float -SDL_atanf(float x) -{ -#if defined(HAVE_ATANF) - return atanf(x); -#else - return (float)SDL_atan((double)x); -#endif -} - -double -SDL_atan2(double x, double y) -{ -#if defined(HAVE_ATAN2) - return atan2(x, y); -#else - return SDL_uclibc_atan2(x, y); -#endif -} - -float -SDL_atan2f(float x, float y) -{ -#if defined(HAVE_ATAN2F) - return atan2f(x, y); -#else - return (float)SDL_atan2((double)x, (double)y); -#endif -} - -double -SDL_acos(double val) -{ -#if defined(HAVE_ACOS) - return acos(val); -#else - double result; - if (val == -1.0) { - result = M_PI; - } else { - result = SDL_atan(SDL_sqrt(1.0 - val * val) / val); - if (result < 0.0) - { - result += M_PI; - } - } - return result; -#endif -} - -float -SDL_acosf(float val) -{ -#if defined(HAVE_ACOSF) - return acosf(val); -#else - return (float)SDL_acos((double)val); -#endif -} - -double -SDL_asin(double val) -{ -#if defined(HAVE_ASIN) - return asin(val); -#else - double result; - if (val == -1.0) { - result = -(M_PI / 2.0); - } else { - result = (M_PI / 2.0) - SDL_acos(val); - } - return result; -#endif -} - -float -SDL_asinf(float val) -{ -#if defined(HAVE_ASINF) - return asinf(val); -#else - return (float)SDL_asin((double)val); -#endif -} - -double -SDL_ceil(double x) -{ -#if defined(HAVE_CEIL) - return ceil(x); -#else - double integer = SDL_floor(x); - double fraction = x - integer; - if (fraction > 0.0) { - integer += 1.0; - } - return integer; -#endif /* HAVE_CEIL */ -} - -float -SDL_ceilf(float x) -{ -#if defined(HAVE_CEILF) - return ceilf(x); -#else - return (float)SDL_ceil((float)x); -#endif -} - -double -SDL_copysign(double x, double y) -{ -#if defined(HAVE_COPYSIGN) - return copysign(x, y); -#elif defined(HAVE__COPYSIGN) - return _copysign(x, y); -#elif defined(__WATCOMC__) && defined(__386__) - /* this is nasty as hell, but it works.. */ - unsigned int *xi = (unsigned int *) &x, - *yi = (unsigned int *) &y; - xi[1] = (yi[1] & 0x80000000) | (xi[1] & 0x7fffffff); - return x; -#else - return SDL_uclibc_copysign(x, y); -#endif /* HAVE_COPYSIGN */ -} - -float -SDL_copysignf(float x, float y) -{ -#if defined(HAVE_COPYSIGNF) - return copysignf(x, y); -#else - return (float)SDL_copysign((double)x, (double)y); -#endif -} - -double -SDL_cos(double x) -{ -#if defined(HAVE_COS) - return cos(x); -#else - return SDL_uclibc_cos(x); -#endif -} - -float -SDL_cosf(float x) -{ -#if defined(HAVE_COSF) - return cosf(x); -#else - return (float)SDL_cos((double)x); -#endif -} - -double -SDL_exp(double x) -{ -#if defined(HAVE_EXP) - return exp(x); -#else - return SDL_uclibc_exp(x); -#endif -} - -float -SDL_expf(float x) -{ -#if defined(HAVE_EXPF) - return expf(x); -#else - return (float)SDL_exp((double)x); -#endif -} - -double -SDL_fabs(double x) -{ -#if defined(HAVE_FABS) - return fabs(x); -#else - return SDL_uclibc_fabs(x); -#endif -} - -float -SDL_fabsf(float x) -{ -#if defined(HAVE_FABSF) - return fabsf(x); -#else - return (float)SDL_fabs((double)x); -#endif -} - -double -SDL_floor(double x) -{ -#if defined(HAVE_FLOOR) - return floor(x); -#else - return SDL_uclibc_floor(x); -#endif -} - -float -SDL_floorf(float x) -{ -#if defined(HAVE_FLOORF) - return floorf(x); -#else - return (float)SDL_floor((double)x); -#endif -} - -double -SDL_fmod(double x, double y) -{ -#if defined(HAVE_FMOD) - return fmod(x, y); -#else - return SDL_uclibc_fmod(x, y); -#endif -} - -float -SDL_fmodf(float x, float y) -{ -#if defined(HAVE_FMODF) - return fmodf(x, y); -#else - return (float)SDL_fmod((double)x, (double)y); -#endif -} - -double -SDL_log(double x) -{ -#if defined(HAVE_LOG) - return log(x); -#else - return SDL_uclibc_log(x); -#endif -} - -float -SDL_logf(float x) -{ -#if defined(HAVE_LOGF) - return logf(x); -#else - return (float)SDL_log((double)x); -#endif -} - -double -SDL_log10(double x) -{ -#if defined(HAVE_LOG10) - return log10(x); -#else - return SDL_uclibc_log10(x); -#endif -} - -float -SDL_log10f(float x) -{ -#if defined(HAVE_LOG10F) - return log10f(x); -#else - return (float)SDL_log10((double)x); -#endif -} - -double -SDL_pow(double x, double y) -{ -#if defined(HAVE_POW) - return pow(x, y); -#else - return SDL_uclibc_pow(x, y); -#endif -} - -float -SDL_powf(float x, float y) -{ -#if defined(HAVE_POWF) - return powf(x, y); -#else - return (float)SDL_pow((double)x, (double)y); -#endif -} - -double -SDL_scalbn(double x, int n) -{ -#if defined(HAVE_SCALBN) - return scalbn(x, n); -#elif defined(HAVE__SCALB) - return _scalb(x, n); -#elif defined(HAVE_LIBC) && defined(HAVE_FLOAT_H) && (FLT_RADIX == 2) -/* from scalbn(3): If FLT_RADIX equals 2 (which is - * usual), then scalbn() is equivalent to ldexp(3). */ - return ldexp(x, n); -#else - return SDL_uclibc_scalbn(x, n); -#endif -} - -float -SDL_scalbnf(float x, int n) -{ -#if defined(HAVE_SCALBNF) - return scalbnf(x, n); -#else - return (float)SDL_scalbn((double)x, n); -#endif -} - -double -SDL_sin(double x) -{ -#if defined(HAVE_SIN) - return sin(x); -#else - return SDL_uclibc_sin(x); -#endif -} - -float -SDL_sinf(float x) -{ -#if defined(HAVE_SINF) - return sinf(x); -#else - return (float)SDL_sin((double)x); -#endif -} - -double -SDL_sqrt(double x) -{ -#if defined(HAVE_SQRT) - return sqrt(x); -#else - return SDL_uclibc_sqrt(x); -#endif -} - -float -SDL_sqrtf(float x) -{ -#if defined(HAVE_SQRTF) - return sqrtf(x); -#else - return (float)SDL_sqrt((double)x); -#endif -} - -double -SDL_tan(double x) -{ -#if defined(HAVE_TAN) - return tan(x); -#else - return SDL_uclibc_tan(x); -#endif -} - -float -SDL_tanf(float x) -{ -#if defined(HAVE_TANF) - return tanf(x); -#else - return (float)SDL_tan((double)x); -#endif -} - -int SDL_abs(int x) -{ -#if defined(HAVE_ABS) - return abs(x); -#else - return ((x) < 0 ? -(x) : (x)); -#endif -} - -#if defined(HAVE_CTYPE_H) -int SDL_isdigit(int x) { return isdigit(x); } -int SDL_isspace(int x) { return isspace(x); } -int SDL_isupper(int x) { return isupper(x); } -int SDL_islower(int x) { return islower(x); } -int SDL_toupper(int x) { return toupper(x); } -int SDL_tolower(int x) { return tolower(x); } -#else -int SDL_isdigit(int x) { return ((x) >= '0') && ((x) <= '9'); } -int SDL_isspace(int x) { return ((x) == ' ') || ((x) == '\t') || ((x) == '\r') || ((x) == '\n') || ((x) == '\f') || ((x) == '\v'); } -int SDL_isupper(int x) { return ((x) >= 'A') && ((x) <= 'Z'); } -int SDL_islower(int x) { return ((x) >= 'a') && ((x) <= 'z'); } -int SDL_toupper(int x) { return ((x) >= 'a') && ((x) <= 'z') ? ('A'+((x)-'a')) : (x); } -int SDL_tolower(int x) { return ((x) >= 'A') && ((x) <= 'Z') ? ('a'+((x)-'A')) : (x); } -#endif - - -#ifndef HAVE_LIBC /* These are some C runtime intrinsics that need to be defined */ #if defined(_MSC_VER) @@ -462,49 +38,40 @@ int SDL_tolower(int x) { return ((x) >= 'A') && ((x) <= 'Z') ? ('a'+((x)-'A')) : __declspec(selectany) int _fltused = 1; #endif -/* The optimizer on Visual Studio 2005 and later generates memcpy() calls */ -#if (_MSC_VER >= 1400) && defined(_WIN64) && !defined(_DEBUG) && !(_MSC_VER >= 1900 && defined(_MT)) -#include +/* The optimizer on Visual Studio 2005 and later generates memcpy() and memset() calls. + Always provide it for the SDL2 DLL, but skip it when building static lib w/ static runtime. */ +#if (_MSC_VER >= 1400) && (!defined(_MT) || defined(DLL_EXPORT)) +/* NOLINTNEXTLINE(readability-redundant-declaration) */ +extern void *memcpy(void *dst, const void *src, size_t len); +#pragma intrinsic(memcpy) +#if !defined(__clang__) #pragma function(memcpy) -void * memcpy ( void * destination, const void * source, size_t num ) +#endif +/* NOLINTNEXTLINE(readability-inconsistent-declaration-parameter-name) */ +void *memcpy(void *dst, const void *src, size_t len) { - const Uint8 *src = (const Uint8 *)source; - Uint8 *dst = (Uint8 *)destination; - size_t i; - - /* All WIN64 architectures have SSE, right? */ - if (!((uintptr_t) src & 15) && !((uintptr_t) dst & 15)) { - __m128 values[4]; - for (i = num / 64; i--;) { - _mm_prefetch(src, _MM_HINT_NTA); - values[0] = *(__m128 *) (src + 0); - values[1] = *(__m128 *) (src + 16); - values[2] = *(__m128 *) (src + 32); - values[3] = *(__m128 *) (src + 48); - _mm_stream_ps((float *) (dst + 0), values[0]); - _mm_stream_ps((float *) (dst + 16), values[1]); - _mm_stream_ps((float *) (dst + 32), values[2]); - _mm_stream_ps((float *) (dst + 48), values[3]); - src += 64; - dst += 64; - } - num &= 63; - } - - while (num--) { - *dst++ = *src++; - } - return destination; + return SDL_memcpy(dst, src, len); } -#endif /* _MSC_VER == 1600 && defined(_WIN64) && !defined(_DEBUG) */ + +/* NOLINTNEXTLINE(readability-redundant-declaration) */ +extern void *memset(void *dst, int c, size_t len); +#pragma intrinsic(memset) + +#if !defined(__clang__) +#pragma function(memset) +#endif +/* NOLINTNEXTLINE(readability-inconsistent-declaration-parameter-name) */ +void *memset(void *dst, int c, size_t len) +{ + return SDL_memset(dst, c, len); +} +#endif /* (_MSC_VER >= 1400) && (!defined(_MT) || defined(DLL_EXPORT)) */ #ifdef _M_IX86 /* Float to long */ -void -__declspec(naked) -_ftol() +void __declspec(naked) _ftol() { /* *INDENT-OFF* */ __asm { @@ -553,16 +120,18 @@ localexit: /* *INDENT-ON* */ } -void -_ftol2_sse() +void _ftol2_sse() +{ + _ftol(); +} + +void _ftol2() { _ftol(); } /* 64-bit math operators for 32-bit systems */ -void -__declspec(naked) -_allmul() +void __declspec(naked) _allmul() { /* *INDENT-OFF* */ __asm { @@ -590,9 +159,7 @@ hard: /* *INDENT-ON* */ } -void -__declspec(naked) -_alldiv() +void __declspec(naked) _alldiv() { /* *INDENT-OFF* */ __asm { @@ -678,9 +245,7 @@ L8: /* *INDENT-ON* */ } -void -__declspec(naked) -_aulldiv() +void __declspec(naked) _aulldiv() { /* *INDENT-OFF* */ __asm { @@ -736,9 +301,7 @@ L2: /* *INDENT-ON* */ } -void -__declspec(naked) -_allrem() +void __declspec(naked) _allrem() { /* *INDENT-OFF* */ __asm { @@ -823,9 +386,7 @@ L8: /* *INDENT-ON* */ } -void -__declspec(naked) -_aullrem() +void __declspec(naked) _aullrem() { /* *INDENT-OFF* */ __asm { @@ -882,9 +443,7 @@ L2: /* *INDENT-ON* */ } -void -__declspec(naked) -_alldvrm() +void __declspec(naked) _alldvrm() { /* *INDENT-OFF* */ __asm { @@ -992,9 +551,7 @@ L8: /* *INDENT-ON* */ } -void -__declspec(naked) -_aulldvrm() +void __declspec(naked) _aulldvrm() { /* *INDENT-OFF* */ __asm { @@ -1065,9 +622,7 @@ L2: /* *INDENT-ON* */ } -void -__declspec(naked) -_allshl() +void __declspec(naked) _allshl() { /* *INDENT-OFF* */ __asm { @@ -1092,9 +647,7 @@ RETZERO: /* *INDENT-ON* */ } -void -__declspec(naked) -_allshr() +void __declspec(naked) _allshr() { /* *INDENT-OFF* */ __asm { @@ -1119,9 +672,7 @@ RETSIGN: /* *INDENT-ON* */ } -void -__declspec(naked) -_aullshr() +void __declspec(naked) _aullshr() { /* *INDENT-OFF* */ __asm { @@ -1150,6 +701,19 @@ RETZERO: #endif /* MSC_VER */ -#endif /* !HAVE_LIBC */ +#if defined(__ICL) +/* The classic Intel compiler generates calls to _intel_fast_memcpy + * and _intel_fast_memset when building an optimized SDL library */ +void *_intel_fast_memcpy(void *dst, const void *src, size_t len) +{ + return SDL_memcpy(dst, src, len); +} +void *_intel_fast_memset(void *dst, int c, size_t len) +{ + return SDL_memset(dst, c, len); +} +#endif + +#endif /* !HAVE_LIBC && !SDL_STATIC_LIB */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/stdlib/SDL_qsort.c b/SDL2-2.30.5/src/stdlib/SDL_qsort.c similarity index 87% rename from SDL2-2.0.12/src/stdlib/SDL_qsort.c rename to SDL2-2.30.5/src/stdlib/SDL_qsort.c index 060db21..91fb1d2 100644 --- a/SDL2-2.0.12/src/stdlib/SDL_qsort.c +++ b/SDL2-2.30.5/src/stdlib/SDL_qsort.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,12 +26,13 @@ #include "../SDL_internal.h" #include "SDL_stdinc.h" -#include "SDL_assert.h" #if defined(HAVE_QSORT) -void -SDL_qsort(void *base, size_t nmemb, size_t size, int (*compare) (const void *, const void *)) +void SDL_qsort(void *base, size_t nmemb, size_t size, int (SDLCALL *compare) (const void *, const void *)) { + if (!base) { + return; + } qsort(base, nmemb, size, compare); } @@ -64,7 +65,7 @@ SDL_qsort(void *base, size_t nmemb, size_t size, int (*compare) (const void *, c /* This code came from Gareth McCaughan, under the zlib license. -Specifically this: https://www.mccaughan.org.uk/software/qsort.c-1.15 +Specifically this: https://www.mccaughan.org.uk/software/qsort.c-1.16 Everything below this comment until the HAVE_QSORT #endif was from Gareth (any minor changes will be noted inline). @@ -111,7 +112,7 @@ benefit! * Gareth McCaughan */ -/* Copyright (c) 1998-2016 Gareth McCaughan +/* Copyright (c) 1998-2021 Gareth McCaughan * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any @@ -147,17 +148,23 @@ benefit! * (pre-insertion-sort messed up). * Disable DEBUG_QSORT by default. * Tweak comments very slightly. + * 2021-02-20 v1.16 Fix bug kindly reported by Ray Gardner + * (error in recursion leading to possible + * stack overflow). + * When checking alignment, avoid casting + * pointer to possibly-smaller integer. */ /* BEGIN SDL CHANGE ... commented this out with an #if 0 block. --ryan. */ #if 0 #include +#include #include #include #undef DEBUG_QSORT -static char _ID[]=""; +static char _ID[]=""; #endif /* END SDL CHANGE ... commented this out with an #if 0 block. --ryan. */ @@ -167,7 +174,8 @@ static char _ID[]=""; #define WORD_BYTES sizeof(int) /* How big does our stack need to be? Answer: one entry per - * bit in a |size_t|. + * bit in a |size_t|. (Actually, a bit less because we don't + * recurse all the way down to size-1 subarrays.) */ #define STACK_SIZE (8*sizeof(size_t)) @@ -206,11 +214,12 @@ typedef struct { char * first; char * last; } stack_entry; * on large datasets for locality-of-reference reasons, * but it makes the code much nastier and increases * bookkeeping overhead. - * 2. We always save the shorter and get to work on the - * longer. This guarantees that every time we push - * an item onto the stack its size is <= 1/2 of that - * of its parent; so the stack can't need more than - * log_2(max-array-size) entries. + * 2. We always save the longer and get to work on the + * shorter. This guarantees that whenever we push + * a k'th entry onto the stack we are about to get + * working on something of size <= N/2^k where N is + * the original array size; so the stack can't need + * more than log_2(max-array-size) entries. * 3. We choose a pivot by looking at the first, last * and middle elements. We arrange them into order * because it's easy to do that in conjunction with @@ -272,8 +281,8 @@ typedef struct { char * first; char * last; } stack_entry; if (r>=Trunc) doRight \ else pop \ } \ - else if (l<=r) { pushLeft; doRight } \ - else if (r>=Trunc) { pushRight; doLeft }\ + else if (l<=r) { pushRight; doLeft } \ + else if (r>=Trunc) { pushLeft; doRight }\ else doLeft \ } @@ -367,7 +376,7 @@ typedef struct { char * first; char * last; } stack_entry; /* ---------------------------------------------------------------------- */ static char * pivot_big(char *first, char *mid, char *last, size_t size, - int compare(const void *, const void *)) { + int (SDLCALL * compare)(const void *, const void *)) { size_t d=(((last-first)/size)>>3)*size; #ifdef DEBUG_QSORT fprintf(stderr, "pivot_big: first=%p last=%p size=%lu n=%lu\n", first, (unsigned long)last, size, (unsigned long)((last-first+1)/size)); @@ -408,14 +417,14 @@ fprintf(stderr,"-> %d %d %d @ %p %p %p\n",*(int*)m1,*(int*)m2,*(int*)m3, m1,m2,m /* ---------------------------------------------------------------------- */ static void qsort_nonaligned(void *base, size_t nmemb, size_t size, - int (*compare)(const void *, const void *)) { + int (SDLCALL * compare)(const void *, const void *)) { stack_entry stack[STACK_SIZE]; int stacktop=0; char *first,*last; char *pivot=malloc(size); size_t trunc=TRUNC_nonaligned*size; - assert(pivot!=0); + assert(pivot != NULL); first=(char*)base; last=first+(nmemb-1)*size; @@ -439,14 +448,14 @@ static void qsort_nonaligned(void *base, size_t nmemb, size_t size, } static void qsort_aligned(void *base, size_t nmemb, size_t size, - int (*compare)(const void *, const void *)) { + int (SDLCALL * compare)(const void *, const void *)) { stack_entry stack[STACK_SIZE]; int stacktop=0; char *first,*last; char *pivot=malloc(size); size_t trunc=TRUNC_aligned*size; - assert(pivot!=0); + assert(pivot != NULL); first=(char*)base; last=first+(nmemb-1)*size; @@ -470,13 +479,13 @@ static void qsort_aligned(void *base, size_t nmemb, size_t size, } static void qsort_words(void *base, size_t nmemb, - int (*compare)(const void *, const void *)) { + int (SDLCALL * compare)(const void *, const void *)) { stack_entry stack[STACK_SIZE]; int stacktop=0; char *first,*last; char *pivot=malloc(WORD_BYTES); - assert(pivot!=0); + assert(pivot != NULL); first=(char*)base; last=first+(nmemb-1)*WORD_BYTES; @@ -522,10 +531,10 @@ fprintf(stderr, "after partitioning first=#%lu last=#%lu\n", (first-(char*)base) /* ---------------------------------------------------------------------- */ extern void qsortG(void *base, size_t nmemb, size_t size, - int (*compare)(const void *, const void *)) { + int (SDLCALL * compare)(const void *, const void *)) { if (nmemb<=1) return; - if (((size_t)base|size)&(WORD_BYTES-1)) + if (((uintptr_t)base|size)&(WORD_BYTES-1)) qsort_nonaligned(base,nmemb,size,compare); else if (size!=WORD_BYTES) qsort_aligned(base,nmemb,size,compare); @@ -535,5 +544,36 @@ extern void qsortG(void *base, size_t nmemb, size_t size, #endif /* HAVE_QSORT */ -/* vi: set ts=4 sw=4 expandtab: */ +void *SDL_bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (SDLCALL * compare)(const void *, const void *)) +{ +#if defined(HAVE_BSEARCH) + return bsearch(key, base, nmemb, size, compare); +#else +/* SDL's replacement: Taken from the Public Domain C Library (PDCLib): + Permission is granted to use, modify, and / or redistribute at will. +*/ + const void *pivot; + size_t corr; + int rc; + while (nmemb) { + /* algorithm needs -1 correction if remaining elements are an even number. */ + corr = nmemb % 2; + nmemb /= 2; + pivot = (const char *)base + (nmemb * size); + rc = compare(key, pivot); + + if (rc > 0) { + base = (const char *)pivot + size; + /* applying correction */ + nmemb -= (1 - corr); + } else if (rc == 0) { + return (void *)pivot; + } + } + + return NULL; +#endif /* HAVE_BSEARCH */ +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/stdlib/SDL_stdlib.c b/SDL2-2.30.5/src/stdlib/SDL_stdlib.c new file mode 100644 index 0000000..a90f09f --- /dev/null +++ b/SDL2-2.30.5/src/stdlib/SDL_stdlib.c @@ -0,0 +1,633 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#if defined(__clang_analyzer__) && !defined(SDL_DISABLE_ANALYZE_MACROS) +#define SDL_DISABLE_ANALYZE_MACROS 1 +#endif + +#include "../SDL_internal.h" + +/* This file contains portable stdlib functions for SDL */ + +#include "SDL_stdinc.h" +#include "../libm/math_libm.h" + +double +SDL_atan(double x) +{ +#if defined(HAVE_ATAN) + return atan(x); +#else + return SDL_uclibc_atan(x); +#endif +} + +float SDL_atanf(float x) +{ +#if defined(HAVE_ATANF) + return atanf(x); +#else + return (float)SDL_atan((double)x); +#endif +} + +double +SDL_atan2(double y, double x) +{ +#if defined(HAVE_ATAN2) + return atan2(y, x); +#else + return SDL_uclibc_atan2(y, x); +#endif +} + +float SDL_atan2f(float y, float x) +{ +#if defined(HAVE_ATAN2F) + return atan2f(y, x); +#else + return (float)SDL_atan2((double)y, (double)x); +#endif +} + +double +SDL_acos(double val) +{ +#if defined(HAVE_ACOS) + return acos(val); +#else + double result; + if (val == -1.0) { + result = M_PI; + } else { + result = SDL_atan(SDL_sqrt(1.0 - val * val) / val); + if (result < 0.0) + { + result += M_PI; + } + } + return result; +#endif +} + +float SDL_acosf(float val) +{ +#if defined(HAVE_ACOSF) + return acosf(val); +#else + return (float)SDL_acos((double)val); +#endif +} + +double +SDL_asin(double val) +{ +#if defined(HAVE_ASIN) + return asin(val); +#else + double result; + if (val == -1.0) { + result = -(M_PI / 2.0); + } else { + result = (M_PI / 2.0) - SDL_acos(val); + } + return result; +#endif +} + +float SDL_asinf(float val) +{ +#if defined(HAVE_ASINF) + return asinf(val); +#else + return (float)SDL_asin((double)val); +#endif +} + +double +SDL_ceil(double x) +{ +#if defined(HAVE_CEIL) + return ceil(x); +#else + double integer = SDL_floor(x); + double fraction = x - integer; + if (fraction > 0.0) { + integer += 1.0; + } + return integer; +#endif /* HAVE_CEIL */ +} + +float SDL_ceilf(float x) +{ +#if defined(HAVE_CEILF) + return ceilf(x); +#else + return (float)SDL_ceil((double)x); +#endif +} + +double +SDL_copysign(double x, double y) +{ +#if defined(HAVE_COPYSIGN) + return copysign(x, y); +#elif defined(HAVE__COPYSIGN) + return _copysign(x, y); +#elif defined(__WATCOMC__) && defined(__386__) + /* this is nasty as hell, but it works.. */ + unsigned int *xi = (unsigned int *)&x, + *yi = (unsigned int *)&y; + xi[1] = (yi[1] & 0x80000000) | (xi[1] & 0x7fffffff); + return x; +#else + return SDL_uclibc_copysign(x, y); +#endif /* HAVE_COPYSIGN */ +} + +float SDL_copysignf(float x, float y) +{ +#if defined(HAVE_COPYSIGNF) + return copysignf(x, y); +#else + return (float)SDL_copysign((double)x, (double)y); +#endif +} + +double +SDL_cos(double x) +{ +#if defined(HAVE_COS) + return cos(x); +#else + return SDL_uclibc_cos(x); +#endif +} + +float SDL_cosf(float x) +{ +#if defined(HAVE_COSF) + return cosf(x); +#else + return (float)SDL_cos((double)x); +#endif +} + +double +SDL_exp(double x) +{ +#if defined(HAVE_EXP) + return exp(x); +#else + return SDL_uclibc_exp(x); +#endif +} + +float SDL_expf(float x) +{ +#if defined(HAVE_EXPF) + return expf(x); +#else + return (float)SDL_exp((double)x); +#endif +} + +double +SDL_fabs(double x) +{ +#if defined(HAVE_FABS) + return fabs(x); +#else + return SDL_uclibc_fabs(x); +#endif +} + +float SDL_fabsf(float x) +{ +#if defined(HAVE_FABSF) + return fabsf(x); +#else + return (float)SDL_fabs((double)x); +#endif +} + +double +SDL_floor(double x) +{ +#if defined(HAVE_FLOOR) + return floor(x); +#else + return SDL_uclibc_floor(x); +#endif +} + +float SDL_floorf(float x) +{ +#if defined(HAVE_FLOORF) + return floorf(x); +#else + return (float)SDL_floor((double)x); +#endif +} + +double +SDL_trunc(double x) +{ +#if defined(HAVE_TRUNC) + return trunc(x); +#else + if (x >= 0.0f) { + return SDL_floor(x); + } else { + return SDL_ceil(x); + } +#endif +} + +float SDL_truncf(float x) +{ +#if defined(HAVE_TRUNCF) + return truncf(x); +#else + return (float)SDL_trunc((double)x); +#endif +} + +double +SDL_fmod(double x, double y) +{ +#if defined(HAVE_FMOD) + return fmod(x, y); +#else + return SDL_uclibc_fmod(x, y); +#endif +} + +float SDL_fmodf(float x, float y) +{ +#if defined(HAVE_FMODF) + return fmodf(x, y); +#else + return (float)SDL_fmod((double)x, (double)y); +#endif +} + +double +SDL_log(double x) +{ +#if defined(HAVE_LOG) + return log(x); +#else + return SDL_uclibc_log(x); +#endif +} + +float SDL_logf(float x) +{ +#if defined(HAVE_LOGF) + return logf(x); +#else + return (float)SDL_log((double)x); +#endif +} + +double +SDL_log10(double x) +{ +#if defined(HAVE_LOG10) + return log10(x); +#else + return SDL_uclibc_log10(x); +#endif +} + +float SDL_log10f(float x) +{ +#if defined(HAVE_LOG10F) + return log10f(x); +#else + return (float)SDL_log10((double)x); +#endif +} + +double +SDL_pow(double x, double y) +{ +#if defined(HAVE_POW) + return pow(x, y); +#else + return SDL_uclibc_pow(x, y); +#endif +} + +float SDL_powf(float x, float y) +{ +#if defined(HAVE_POWF) + return powf(x, y); +#else + return (float)SDL_pow((double)x, (double)y); +#endif +} + +double +SDL_round(double arg) +{ +#if defined HAVE_ROUND + return round(arg); +#else + if (arg >= 0.0) { + return SDL_floor(arg + 0.5); + } else { + return SDL_ceil(arg - 0.5); + } +#endif +} + +float SDL_roundf(float arg) +{ +#if defined HAVE_ROUNDF + return roundf(arg); +#else + return (float)SDL_round((double)arg); +#endif +} + +long SDL_lround(double arg) +{ +#if defined HAVE_LROUND + return lround(arg); +#else + return (long)SDL_round(arg); +#endif +} + +long SDL_lroundf(float arg) +{ +#if defined HAVE_LROUNDF + return lroundf(arg); +#else + return (long)SDL_round((double)arg); +#endif +} + +double +SDL_scalbn(double x, int n) +{ +#if defined(HAVE_SCALBN) + return scalbn(x, n); +#elif defined(HAVE__SCALB) + return _scalb(x, n); +#elif defined(HAVE_LIBC) && defined(HAVE_FLOAT_H) && (FLT_RADIX == 2) + /* from scalbn(3): If FLT_RADIX equals 2 (which is + * usual), then scalbn() is equivalent to ldexp(3). */ + return ldexp(x, n); +#else + return SDL_uclibc_scalbn(x, n); +#endif +} + +float SDL_scalbnf(float x, int n) +{ +#if defined(HAVE_SCALBNF) + return scalbnf(x, n); +#else + return (float)SDL_scalbn((double)x, n); +#endif +} + +double +SDL_sin(double x) +{ +#if defined(HAVE_SIN) + return sin(x); +#else + return SDL_uclibc_sin(x); +#endif +} + +float SDL_sinf(float x) +{ +#if defined(HAVE_SINF) + return sinf(x); +#else + return (float)SDL_sin((double)x); +#endif +} + +double +SDL_sqrt(double x) +{ +#if defined(HAVE_SQRT) + return sqrt(x); +#else + return SDL_uclibc_sqrt(x); +#endif +} + +float SDL_sqrtf(float x) +{ +#if defined(HAVE_SQRTF) + return sqrtf(x); +#else + return (float)SDL_sqrt((double)x); +#endif +} + +double +SDL_tan(double x) +{ +#if defined(HAVE_TAN) + return tan(x); +#else + return SDL_uclibc_tan(x); +#endif +} + +float SDL_tanf(float x) +{ +#if defined(HAVE_TANF) + return tanf(x); +#else + return (float)SDL_tan((double)x); +#endif +} + +int SDL_abs(int x) +{ +#if defined(HAVE_ABS) + return abs(x); +#else + return (x < 0) ? -x : x; +#endif +} + +#if defined(HAVE_CTYPE_H) +int SDL_isalpha(int x) +{ + return isalpha(x); +} +int SDL_isalnum(int x) { return isalnum(x); } +int SDL_isdigit(int x) { return isdigit(x); } +int SDL_isxdigit(int x) { return isxdigit(x); } +int SDL_ispunct(int x) { return ispunct(x); } +int SDL_isspace(int x) { return isspace(x); } +int SDL_isupper(int x) { return isupper(x); } +int SDL_islower(int x) { return islower(x); } +int SDL_isprint(int x) { return isprint(x); } +int SDL_isgraph(int x) { return isgraph(x); } +int SDL_iscntrl(int x) { return iscntrl(x); } +int SDL_toupper(int x) { return toupper(x); } +int SDL_tolower(int x) { return tolower(x); } +#else +int SDL_isalpha(int x) +{ + return (SDL_isupper(x)) || (SDL_islower(x)); +} +int SDL_isalnum(int x) { return (SDL_isalpha(x)) || (SDL_isdigit(x)); } +int SDL_isdigit(int x) { return ((x) >= '0') && ((x) <= '9'); } +int SDL_isxdigit(int x) { return (((x) >= 'A') && ((x) <= 'F')) || (((x) >= 'a') && ((x) <= 'f')) || (SDL_isdigit(x)); } +int SDL_ispunct(int x) { return (SDL_isgraph(x)) && (!SDL_isalnum(x)); } +int SDL_isspace(int x) { return ((x) == ' ') || ((x) == '\t') || ((x) == '\r') || ((x) == '\n') || ((x) == '\f') || ((x) == '\v'); } +int SDL_isupper(int x) { return ((x) >= 'A') && ((x) <= 'Z'); } +int SDL_islower(int x) { return ((x) >= 'a') && ((x) <= 'z'); } +int SDL_isprint(int x) { return ((x) >= ' ') && ((x) < '\x7f'); } +int SDL_isgraph(int x) { return (SDL_isprint(x)) && ((x) != ' '); } +int SDL_iscntrl(int x) { return (((x) >= '\0') && ((x) <= '\x1f')) || ((x) == '\x7f'); } +int SDL_toupper(int x) { return ((x) >= 'a') && ((x) <= 'z') ? ('A' + ((x) - 'a')) : (x); } +int SDL_tolower(int x) { return ((x) >= 'A') && ((x) <= 'Z') ? ('a' + ((x) - 'A')) : (x); } +#endif + +/* This file contains a portable memcpy manipulation function for SDL */ + +void *SDL_memcpy(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, size_t len) +{ +#ifdef __GNUC__ + /* Presumably this is well tuned for speed. + On my machine this is twice as fast as the C code below. + */ + return __builtin_memcpy(dst, src, len); +#elif defined(HAVE_MEMCPY) + return memcpy(dst, src, len); +#elif defined(HAVE_BCOPY) + bcopy(src, dst, len); + return dst; +#else + /* GCC 4.9.0 with -O3 will generate movaps instructions with the loop + using Uint32* pointers, so we need to make sure the pointers are + aligned before we loop using them. + */ + if (((uintptr_t)src & 0x3) || ((uintptr_t)dst & 0x3)) { + /* Do an unaligned byte copy */ + Uint8 *srcp1 = (Uint8 *)src; + Uint8 *dstp1 = (Uint8 *)dst; + + while (len--) { + *dstp1++ = *srcp1++; + } + } else { + size_t left = (len % 4); + Uint32 *srcp4, *dstp4; + Uint8 *srcp1, *dstp1; + + srcp4 = (Uint32 *)src; + dstp4 = (Uint32 *)dst; + len /= 4; + while (len--) { + *dstp4++ = *srcp4++; + } + + srcp1 = (Uint8 *)srcp4; + dstp1 = (Uint8 *)dstp4; + switch (left) { + case 3: + *dstp1++ = *srcp1++; + case 2: + *dstp1++ = *srcp1++; + case 1: + *dstp1++ = *srcp1++; + } + } + return dst; +#endif /* __GNUC__ */ +} + +void *SDL_memset(SDL_OUT_BYTECAP(len) void *dst, int c, size_t len) +{ +#if defined(HAVE_MEMSET) + return memset(dst, c, len); +#else + size_t left; + Uint32 *dstp4; + Uint8 *dstp1 = (Uint8 *)dst; + Uint8 value1; + Uint32 value4; + + /* The value used in memset() is a byte, passed as an int */ + c &= 0xff; + + /* The destination pointer needs to be aligned on a 4-byte boundary to + * execute a 32-bit set. Set first bytes manually if needed until it is + * aligned. */ + value1 = (Uint8)c; + while ((uintptr_t)dstp1 & 0x3) { + if (len--) { + *dstp1++ = value1; + } else { + return dst; + } + } + + value4 = ((Uint32)c | ((Uint32)c << 8) | ((Uint32)c << 16) | ((Uint32)c << 24)); + dstp4 = (Uint32 *)dstp1; + left = (len % 4); + len /= 4; + while (len--) { + *dstp4++ = value4; + } + + dstp1 = (Uint8 *)dstp4; + switch (left) { + case 3: + *dstp1++ = value1; + case 2: + *dstp1++ = value1; + case 1: + *dstp1++ = value1; + } + + return dst; +#endif /* HAVE_MEMSET */ +} + +#if defined(HAVE_CTYPE_H) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +int SDL_isblank(int x) +{ + return isblank(x); +} +#else +int SDL_isblank(int x) +{ + return ((x) == ' ') || ((x) == '\t'); +} +#endif + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/stdlib/SDL_string.c b/SDL2-2.30.5/src/stdlib/SDL_string.c similarity index 55% rename from SDL2-2.0.12/src/stdlib/SDL_string.c rename to SDL2-2.30.5/src/stdlib/SDL_string.c index 857c40b..b66163c 100644 --- a/SDL2-2.0.12/src/stdlib/SDL_string.c +++ b/SDL2-2.30.5/src/stdlib/SDL_string.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -27,30 +27,35 @@ /* This file contains portable string manipulation functions for SDL */ #include "SDL_stdinc.h" +#include "SDL_vacopy.h" -#if !defined(HAVE_VSSCANF) || !defined(HAVE_STRTOL) || !defined(HAVE_STRTOUL) || !defined(HAVE_STRTOLL) || !defined(HAVE_STRTOULL) || !defined(HAVE_STRTOD) -#define SDL_isupperhex(X) (((X) >= 'A') && ((X) <= 'F')) -#define SDL_islowerhex(X) (((X) >= 'a') && ((X) <= 'f')) +#if defined(__vita__) +#include #endif -#define UTF8_IsLeadByte(c) ((c) >= 0xC0 && (c) <= 0xF4) +#if !defined(HAVE_VSSCANF) || !defined(HAVE_STRTOL) || !defined(HAVE_STRTOUL) || !defined(HAVE_STRTOD) || !defined(HAVE_STRTOLL) || !defined(HAVE_STRTOULL) +#define SDL_isupperhex(X) (((X) >= 'A') && ((X) <= 'F')) +#define SDL_islowerhex(X) (((X) >= 'a') && ((X) <= 'f')) +#endif + +#define UTF8_IsLeadByte(c) ((c) >= 0xC0 && (c) <= 0xF4) #define UTF8_IsTrailingByte(c) ((c) >= 0x80 && (c) <= 0xBF) -static int UTF8_TrailingBytes(unsigned char c) +static size_t UTF8_TrailingBytes(unsigned char c) { - if (c >= 0xC0 && c <= 0xDF) + if (c >= 0xC0 && c <= 0xDF) { return 1; - else if (c >= 0xE0 && c <= 0xEF) + } else if (c >= 0xE0 && c <= 0xEF) { return 2; - else if (c >= 0xF0 && c <= 0xF4) + } else if (c >= 0xF0 && c <= 0xF4) { return 3; - else - return 0; + } + + return 0; } -#if !defined(HAVE_VSSCANF) || !defined(HAVE_STRTOL) -static size_t -SDL_ScanLong(const char *text, int radix, long *valuep) +#if !defined(HAVE_VSSCANF) || !defined(HAVE_STRTOL) || !defined(HAVE_STRTOUL) || !defined(HAVE_STRTOD) +static size_t SDL_ScanLong(const char *text, int count, int radix, long *valuep) { const char *textstart = text; long value = 0; @@ -65,7 +70,7 @@ SDL_ScanLong(const char *text, int radix, long *valuep) } for (;;) { int v; - if (SDL_isdigit((unsigned char) *text)) { + if (SDL_isdigit((unsigned char)*text)) { v = *text - '0'; } else if (radix == 16 && SDL_isupperhex(*text)) { v = 10 + (*text - 'A'); @@ -77,6 +82,10 @@ SDL_ScanLong(const char *text, int radix, long *valuep) value *= radix; value += v; ++text; + + if (count > 0 && (text - textstart) == count) { + break; + } } if (valuep && text > textstart) { if (negative && value) { @@ -85,23 +94,26 @@ SDL_ScanLong(const char *text, int radix, long *valuep) *valuep = value; } } - return (text - textstart); + return text - textstart; } #endif #if !defined(HAVE_VSSCANF) || !defined(HAVE_STRTOUL) || !defined(HAVE_STRTOD) -static size_t -SDL_ScanUnsignedLong(const char *text, int radix, unsigned long *valuep) +static size_t SDL_ScanUnsignedLong(const char *text, int count, int radix, unsigned long *valuep) { const char *textstart = text; unsigned long value = 0; + if (*text == '-') { + return SDL_ScanLong(text, count, radix, (long *)valuep); + } + if (radix == 16 && SDL_strncmp(text, "0x", 2) == 0) { text += 2; } for (;;) { int v; - if (SDL_isdigit((unsigned char) *text)) { + if (SDL_isdigit((unsigned char)*text)) { v = *text - '0'; } else if (radix == 16 && SDL_isupperhex(*text)) { v = 10 + (*text - 'A'); @@ -113,17 +125,20 @@ SDL_ScanUnsignedLong(const char *text, int radix, unsigned long *valuep) value *= radix; value += v; ++text; + + if (count > 0 && (text - textstart) == count) { + break; + } } if (valuep && text > textstart) { *valuep = value; } - return (text - textstart); + return text - textstart; } #endif #ifndef HAVE_VSSCANF -static size_t -SDL_ScanUintPtrT(const char *text, int radix, uintptr_t * valuep) +static size_t SDL_ScanUintPtrT(const char *text, int radix, uintptr_t *valuep) { const char *textstart = text; uintptr_t value = 0; @@ -133,7 +148,7 @@ SDL_ScanUintPtrT(const char *text, int radix, uintptr_t * valuep) } for (;;) { int v; - if (SDL_isdigit((unsigned char) *text)) { + if (SDL_isdigit((unsigned char)*text)) { v = *text - '0'; } else if (radix == 16 && SDL_isupperhex(*text)) { v = 10 + (*text - 'A'); @@ -149,13 +164,12 @@ SDL_ScanUintPtrT(const char *text, int radix, uintptr_t * valuep) if (valuep && text > textstart) { *valuep = value; } - return (text - textstart); + return text - textstart; } #endif -#if !defined(HAVE_VSSCANF) || !defined(HAVE_STRTOLL) -static size_t -SDL_ScanLongLong(const char *text, int radix, Sint64 * valuep) +#if !defined(HAVE_VSSCANF) || !defined(HAVE_STRTOLL) || !defined(HAVE_STRTOULL) +static size_t SDL_ScanLongLong(const char *text, int count, int radix, Sint64 *valuep) { const char *textstart = text; Sint64 value = 0; @@ -170,7 +184,7 @@ SDL_ScanLongLong(const char *text, int radix, Sint64 * valuep) } for (;;) { int v; - if (SDL_isdigit((unsigned char) *text)) { + if (SDL_isdigit((unsigned char)*text)) { v = *text - '0'; } else if (radix == 16 && SDL_isupperhex(*text)) { v = 10 + (*text - 'A'); @@ -182,6 +196,10 @@ SDL_ScanLongLong(const char *text, int radix, Sint64 * valuep) value *= radix; value += v; ++text; + + if (count > 0 && (text - textstart) == count) { + break; + } } if (valuep && text > textstart) { if (negative && value) { @@ -190,23 +208,26 @@ SDL_ScanLongLong(const char *text, int radix, Sint64 * valuep) *valuep = value; } } - return (text - textstart); + return text - textstart; } #endif #if !defined(HAVE_VSSCANF) || !defined(HAVE_STRTOULL) -static size_t -SDL_ScanUnsignedLongLong(const char *text, int radix, Uint64 * valuep) +static size_t SDL_ScanUnsignedLongLong(const char *text, int count, int radix, Uint64 *valuep) { const char *textstart = text; Uint64 value = 0; + if (*text == '-') { + return SDL_ScanLongLong(text, count, radix, (Sint64 *)valuep); + } + if (radix == 16 && SDL_strncmp(text, "0x", 2) == 0) { text += 2; } for (;;) { int v; - if (SDL_isdigit((unsigned char) *text)) { + if (SDL_isdigit((unsigned char)*text)) { v = *text - '0'; } else if (radix == 16 && SDL_isupperhex(*text)) { v = 10 + (*text - 'A'); @@ -218,17 +239,20 @@ SDL_ScanUnsignedLongLong(const char *text, int radix, Uint64 * valuep) value *= radix; value += v; ++text; + + if (count > 0 && (text - textstart) == count) { + break; + } } if (valuep && text > textstart) { *valuep = value; } - return (text - textstart); + return text - textstart; } #endif #if !defined(HAVE_VSSCANF) || !defined(HAVE_STRTOD) -static size_t -SDL_ScanFloat(const char *text, double *valuep) +static size_t SDL_ScanFloat(const char *text, double *valuep) { const char *textstart = text; unsigned long lvalue = 0; @@ -239,14 +263,14 @@ SDL_ScanFloat(const char *text, double *valuep) negative = SDL_TRUE; ++text; } - text += SDL_ScanUnsignedLong(text, 10, &lvalue); + text += SDL_ScanUnsignedLong(text, 0, 10, &lvalue); value += lvalue; if (*text == '.') { int mult = 10; ++text; - while (SDL_isdigit((unsigned char) *text)) { + while (SDL_isdigit((unsigned char)*text)) { lvalue = *text - '0'; - value += (double) lvalue / mult; + value += (double)lvalue / mult; mult *= 10; ++text; } @@ -258,120 +282,17 @@ SDL_ScanFloat(const char *text, double *valuep) *valuep = value; } } - return (text - textstart); + return text - textstart; } #endif -void * -SDL_memset(SDL_OUT_BYTECAP(len) void *dst, int c, size_t len) -{ -#if defined(HAVE_MEMSET) - return memset(dst, c, len); -#else - size_t left; - Uint32 *dstp4; - Uint8 *dstp1 = (Uint8 *) dst; - Uint8 value1; - Uint32 value4; - - /* The value used in memset() is a byte, passed as an int */ - c &= 0xff; - - /* The destination pointer needs to be aligned on a 4-byte boundary to - * execute a 32-bit set. Set first bytes manually if needed until it is - * aligned. */ - value1 = (Uint8)c; - while ((intptr_t)dstp1 & 0x3) { - if (len--) { - *dstp1++ = value1; - } else { - return dst; - } - } - - value4 = (c | (c << 8) | (c << 16) | (c << 24)); - dstp4 = (Uint32 *) dstp1; - left = (len % 4); - len /= 4; - while (len--) { - *dstp4++ = value4; - } - - dstp1 = (Uint8 *) dstp4; - switch (left) { - case 3: - *dstp1++ = value1; - case 2: - *dstp1++ = value1; - case 1: - *dstp1++ = value1; - } - - return dst; -#endif /* HAVE_MEMSET */ -} - -void * -SDL_memcpy(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, size_t len) -{ -#ifdef __GNUC__ - /* Presumably this is well tuned for speed. - On my machine this is twice as fast as the C code below. - */ - return __builtin_memcpy(dst, src, len); -#elif defined(HAVE_MEMCPY) - return memcpy(dst, src, len); -#elif defined(HAVE_BCOPY) - bcopy(src, dst, len); - return dst; -#else - /* GCC 4.9.0 with -O3 will generate movaps instructions with the loop - using Uint32* pointers, so we need to make sure the pointers are - aligned before we loop using them. - */ - if (((intptr_t)src & 0x3) || ((intptr_t)dst & 0x3)) { - /* Do an unaligned byte copy */ - Uint8 *srcp1 = (Uint8 *)src; - Uint8 *dstp1 = (Uint8 *)dst; - - while (len--) { - *dstp1++ = *srcp1++; - } - } else { - size_t left = (len % 4); - Uint32 *srcp4, *dstp4; - Uint8 *srcp1, *dstp1; - - srcp4 = (Uint32 *) src; - dstp4 = (Uint32 *) dst; - len /= 4; - while (len--) { - *dstp4++ = *srcp4++; - } - - srcp1 = (Uint8 *) srcp4; - dstp1 = (Uint8 *) dstp4; - switch (left) { - case 3: - *dstp1++ = *srcp1++; - case 2: - *dstp1++ = *srcp1++; - case 1: - *dstp1++ = *srcp1++; - } - } - return dst; -#endif /* __GNUC__ */ -} - -void * -SDL_memmove(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, size_t len) +void *SDL_memmove(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, size_t len) { #if defined(HAVE_MEMMOVE) return memmove(dst, src, len); #else - char *srcp = (char *) src; - char *dstp = (char *) dst; + char *srcp = (char *)src; + char *dstp = (char *)dst; if (src < dst) { srcp += len - 1; @@ -388,17 +309,27 @@ SDL_memmove(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, #endif /* HAVE_MEMMOVE */ } -int -SDL_memcmp(const void *s1, const void *s2, size_t len) +int SDL_memcmp(const void *s1, const void *s2, size_t len) { -#if defined(HAVE_MEMCMP) +#if defined(__vita__) + /* + Using memcmp on NULL is UB per POSIX / C99 7.21.1/2. + But, both linux and bsd allow that, with an exception: + zero length strings are always identical, so NULLs are never dereferenced. + sceClibMemcmp on PSVita doesn't allow that, so we check ourselves. + */ + if (len == 0) { + return 0; + } + return sceClibMemcmp(s1, s2, len); +#elif defined(HAVE_MEMCMP) return memcmp(s1, s2, len); #else - char *s1p = (char *) s1; - char *s2p = (char *) s2; + char *s1p = (char *)s1; + char *s2p = (char *)s2; while (len--) { if (*s1p != *s2p) { - return (*s1p - *s2p); + return *s1p - *s2p; } ++s1p; ++s2p; @@ -422,7 +353,7 @@ SDL_strlen(const char *string) } size_t -SDL_wcslen(const wchar_t * string) +SDL_wcslen(const wchar_t *string) { #if defined(HAVE_WCSLEN) return wcslen(string); @@ -466,8 +397,7 @@ SDL_wcslcat(SDL_INOUT_Z_CAP(maxlen) wchar_t *dst, const wchar_t *src, size_t max #endif /* HAVE_WCSLCAT */ } -wchar_t * -SDL_wcsdup(const wchar_t *string) +wchar_t *SDL_wcsdup(const wchar_t *string) { size_t len = ((SDL_wcslen(string) + 1) * sizeof(wchar_t)); wchar_t *newstr = (wchar_t *)SDL_malloc(len); @@ -477,11 +407,10 @@ SDL_wcsdup(const wchar_t *string) return newstr; } -wchar_t * -SDL_wcsstr(const wchar_t *haystack, const wchar_t *needle) +wchar_t *SDL_wcsstr(const wchar_t *haystack, const wchar_t *needle) { #if defined(HAVE_WCSSTR) - return SDL_const_cast(wchar_t*,wcsstr(haystack, needle)); + return SDL_const_cast(wchar_t *, wcsstr(haystack, needle)); #else size_t length = SDL_wcslen(needle); while (*haystack) { @@ -494,36 +423,120 @@ SDL_wcsstr(const wchar_t *haystack, const wchar_t *needle) #endif /* HAVE_WCSSTR */ } -int -SDL_wcscmp(const wchar_t *str1, const wchar_t *str2) +int SDL_wcscmp(const wchar_t *str1, const wchar_t *str2) { #if defined(HAVE_WCSCMP) return wcscmp(str1, str2); #else while (*str1 && *str2) { - if (*str1 != *str2) + if (*str1 != *str2) { break; + } ++str1; ++str2; } - return (int)(*str1 - *str2); + return *str1 - *str2; #endif /* HAVE_WCSCMP */ } -int -SDL_wcsncmp(const wchar_t *str1, const wchar_t *str2, size_t maxlen) +int SDL_wcsncmp(const wchar_t *str1, const wchar_t *str2, size_t maxlen) { #if defined(HAVE_WCSNCMP) return wcsncmp(str1, str2, maxlen); #else - while (*str1 && *str2) { - if (*str1 != *str2) + while (*str1 && *str2 && maxlen) { + if (*str1 != *str2) { break; + } + ++str1; + ++str2; + --maxlen; + } + if (!maxlen) { + return 0; + } + return *str1 - *str2; + +#endif /* HAVE_WCSNCMP */ +} + +int SDL_wcscasecmp(const wchar_t *str1, const wchar_t *str2) +{ +#if defined(HAVE_WCSCASECMP) + return wcscasecmp(str1, str2); +#elif defined(HAVE__WCSICMP) + return _wcsicmp(str1, str2); +#else + wchar_t a = 0; + wchar_t b = 0; + while (*str1 && *str2) { + /* FIXME: This doesn't actually support wide characters */ + if (*str1 >= 0x80 || *str2 >= 0x80) { + a = *str1; + b = *str2; + } else { + a = SDL_toupper((unsigned char)*str1); + b = SDL_toupper((unsigned char)*str2); + } + if (a != b) { + break; + } ++str1; ++str2; } - return (int)(*str1 - *str2); -#endif /* HAVE_WCSNCMP */ + + /* FIXME: This doesn't actually support wide characters */ + if (*str1 >= 0x80 || *str2 >= 0x80) { + a = *str1; + b = *str2; + } else { + a = SDL_toupper((unsigned char)*str1); + b = SDL_toupper((unsigned char)*str2); + } + return (int)((unsigned int)a - (unsigned int)b); +#endif /* HAVE__WCSICMP */ +} + +int SDL_wcsncasecmp(const wchar_t *str1, const wchar_t *str2, size_t maxlen) +{ +#if defined(HAVE_WCSNCASECMP) + return wcsncasecmp(str1, str2, maxlen); +#elif defined(HAVE__WCSNICMP) + return _wcsnicmp(str1, str2, maxlen); +#else + wchar_t a = 0; + wchar_t b = 0; + while (*str1 && *str2 && maxlen) { + /* FIXME: This doesn't actually support wide characters */ + if (*str1 >= 0x80 || *str2 >= 0x80) { + a = *str1; + b = *str2; + } else { + a = SDL_toupper((unsigned char)*str1); + b = SDL_toupper((unsigned char)*str2); + } + if (a != b) { + break; + } + ++str1; + ++str2; + --maxlen; + } + + if (maxlen == 0) { + return 0; + } else { + /* FIXME: This doesn't actually support wide characters */ + if (*str1 >= 0x80 || *str2 >= 0x80) { + a = *str1; + b = *str2; + } else { + a = SDL_toupper((unsigned char)*str1); + b = SDL_toupper((unsigned char)*str2); + } + return (int)((unsigned int)a - (unsigned int)b); + } +#endif /* HAVE__WCSNICMP */ } size_t @@ -548,22 +561,20 @@ SDL_utf8strlcpy(SDL_OUT_Z_CAP(dst_bytes) char *dst, const char *src, size_t dst_ size_t src_bytes = SDL_strlen(src); size_t bytes = SDL_min(src_bytes, dst_bytes - 1); size_t i = 0; - char trailing_bytes = 0; - if (bytes) - { + size_t trailing_bytes = 0; + + if (bytes) { unsigned char c = (unsigned char)src[bytes - 1]; - if (UTF8_IsLeadByte(c)) + if (UTF8_IsLeadByte(c)) { --bytes; - else if (UTF8_IsTrailingByte(c)) - { - for (i = bytes - 1; i != 0; --i) - { + } else if (UTF8_IsTrailingByte(c)) { + for (i = bytes - 1; i != 0; --i) { c = (unsigned char)src[i]; trailing_bytes = UTF8_TrailingBytes(c); - if (trailing_bytes) - { - if (bytes - i != trailing_bytes + 1) + if (trailing_bytes) { + if (bytes - i != trailing_bytes + 1) { bytes = i; + } break; } @@ -572,6 +583,7 @@ SDL_utf8strlcpy(SDL_OUT_Z_CAP(dst_bytes) char *dst, const char *src, size_t dst_ SDL_memcpy(dst, src, bytes); } dst[bytes] = '\0'; + return bytes; } @@ -580,7 +592,7 @@ SDL_utf8strlen(const char *str) { size_t retval = 0; const char *p = str; - char ch; + unsigned char ch; while ((ch = *(p++)) != 0) { /* if top two bits are 1 and 0, it's a continuation byte. */ @@ -588,7 +600,24 @@ SDL_utf8strlen(const char *str) retval++; } } - + + return retval; +} + +size_t +SDL_utf8strnlen(const char *str, size_t bytes) +{ + size_t retval = 0; + const char *p = str; + unsigned char ch; + + while ((ch = *(p++)) != 0 && bytes-- > 0) { + /* if top two bits are 1 and 0, it's a continuation byte. */ + if ((ch & 0xc0) != 0x80) { + retval++; + } + } + return retval; } @@ -607,8 +636,7 @@ SDL_strlcat(SDL_INOUT_Z_CAP(maxlen) char *dst, const char *src, size_t maxlen) #endif /* HAVE_STRLCAT */ } -char * -SDL_strdup(const char *string) +char *SDL_strdup(const char *string) { size_t len = SDL_strlen(string) + 1; char *newstr = (char *)SDL_malloc(len); @@ -618,8 +646,7 @@ SDL_strdup(const char *string) return newstr; } -char * -SDL_strrev(char *string) +char *SDL_strrev(char *string) { #if defined(HAVE__STRREV) return _strrev(string); @@ -629,7 +656,7 @@ SDL_strrev(char *string) char *b = &string[len - 1]; len /= 2; while (len--) { - char c = *a; + char c = *a; /* NOLINT(clang-analyzer-core.uninitialized.Assign) */ *a++ = *b; *b-- = c; } @@ -637,66 +664,65 @@ SDL_strrev(char *string) #endif /* HAVE__STRREV */ } -char * -SDL_strupr(char *string) +char *SDL_strupr(char *string) { #if defined(HAVE__STRUPR) return _strupr(string); #else char *bufp = string; while (*bufp) { - *bufp = SDL_toupper((unsigned char) *bufp); + *bufp = SDL_toupper((unsigned char)*bufp); ++bufp; } return string; #endif /* HAVE__STRUPR */ } -char * -SDL_strlwr(char *string) +char *SDL_strlwr(char *string) { #if defined(HAVE__STRLWR) return _strlwr(string); #else char *bufp = string; while (*bufp) { - *bufp = SDL_tolower((unsigned char) *bufp); + *bufp = SDL_tolower((unsigned char)*bufp); ++bufp; } return string; #endif /* HAVE__STRLWR */ } -char * -SDL_strchr(const char *string, int c) +char *SDL_strchr(const char *string, int c) { #ifdef HAVE_STRCHR - return SDL_const_cast(char*,strchr(string, c)); + return SDL_const_cast(char *, strchr(string, c)); #elif defined(HAVE_INDEX) - return SDL_const_cast(char*,index(string, c)); + return SDL_const_cast(char *, index(string, c)); #else while (*string) { if (*string == c) { - return (char *) string; + return (char *)string; } ++string; } + if (c == '\0') { + return (char *)string; + } return NULL; #endif /* HAVE_STRCHR */ } -char * -SDL_strrchr(const char *string, int c) +char *SDL_strrchr(const char *string, int c) { #ifdef HAVE_STRRCHR - return SDL_const_cast(char*,strrchr(string, c)); + return SDL_const_cast(char *, strrchr(string, c)); #elif defined(HAVE_RINDEX) - return SDL_const_cast(char*,rindex(string, c)); + return SDL_const_cast(char *, rindex(string, c)); #else - const char *bufp = string + SDL_strlen(string) - 1; + const char *bufp = string + SDL_strlen(string); while (bufp >= string) { if (*bufp == c) { - return (char *) bufp; + return (char *)bufp; } --bufp; } @@ -704,16 +730,15 @@ SDL_strrchr(const char *string, int c) #endif /* HAVE_STRRCHR */ } -char * -SDL_strstr(const char *haystack, const char *needle) +char *SDL_strstr(const char *haystack, const char *needle) { #if defined(HAVE_STRSTR) - return SDL_const_cast(char*,strstr(haystack, needle)); + return SDL_const_cast(char *, strstr(haystack, needle)); #else size_t length = SDL_strlen(needle); while (*haystack) { if (SDL_strncmp(haystack, needle, length) == 0) { - return (char *) haystack; + return (char *)haystack; } ++haystack; } @@ -721,6 +746,22 @@ SDL_strstr(const char *haystack, const char *needle) #endif /* HAVE_STRSTR */ } +char *SDL_strcasestr(const char *haystack, const char *needle) +{ +#if defined(HAVE_STRCASESTR) + return SDL_const_cast(char *, strcasestr(haystack, needle)); +#else + size_t length = SDL_strlen(needle); + while (*haystack) { + if (SDL_strncasecmp(haystack, needle, length) == 0) { + return (char *)haystack; + } + ++haystack; + } + return NULL; +#endif /* HAVE_STRCASESTR */ +} + #if !defined(HAVE__LTOA) || !defined(HAVE__I64TOA) || \ !defined(HAVE__ULTOA) || !defined(HAVE__UI64TOA) static const char ntoa_table[] = { @@ -731,8 +772,7 @@ static const char ntoa_table[] = { }; #endif /* ntoa() conversion table */ -char * -SDL_itoa(int value, char *string, int radix) +char *SDL_itoa(int value, char *string, int radix) { #ifdef HAVE_ITOA return itoa(value, string, radix); @@ -741,8 +781,7 @@ SDL_itoa(int value, char *string, int radix) #endif /* HAVE_ITOA */ } -char * -SDL_uitoa(unsigned int value, char *string, int radix) +char *SDL_uitoa(unsigned int value, char *string, int radix) { #ifdef HAVE__UITOA return _uitoa(value, string, radix); @@ -751,8 +790,7 @@ SDL_uitoa(unsigned int value, char *string, int radix) #endif /* HAVE__UITOA */ } -char * -SDL_ltoa(long value, char *string, int radix) +char *SDL_ltoa(long value, char *string, int radix) { #if defined(HAVE__LTOA) return _ltoa(value, string, radix); @@ -770,8 +808,7 @@ SDL_ltoa(long value, char *string, int radix) #endif /* HAVE__LTOA */ } -char * -SDL_ultoa(unsigned long value, char *string, int radix) +char *SDL_ultoa(unsigned long value, char *string, int radix) { #if defined(HAVE__ULTOA) return _ultoa(value, string, radix); @@ -795,8 +832,7 @@ SDL_ultoa(unsigned long value, char *string, int radix) #endif /* HAVE__ULTOA */ } -char * -SDL_lltoa(Sint64 value, char *string, int radix) +char *SDL_lltoa(Sint64 value, char *string, int radix) { #if defined(HAVE__I64TOA) return _i64toa(value, string, radix); @@ -814,8 +850,7 @@ SDL_lltoa(Sint64 value, char *string, int radix) #endif /* HAVE__I64TOA */ } -char * -SDL_ulltoa(Uint64 value, char *string, int radix) +char *SDL_ulltoa(Uint64 value, char *string, int radix) { #if defined(HAVE__UI64TOA) return _ui64toa(value, string, radix); @@ -844,7 +879,7 @@ int SDL_atoi(const char *string) #ifdef HAVE_ATOI return atoi(string); #else - return SDL_strtol(string, NULL, 0); + return SDL_strtol(string, NULL, 10); #endif /* HAVE_ATOI */ } @@ -857,8 +892,7 @@ double SDL_atof(const char *string) #endif /* HAVE_ATOF */ } -long -SDL_strtol(const char *string, char **endp, int base) +long SDL_strtol(const char *string, char **endp, int base) { #if defined(HAVE_STRTOL) return strtol(string, endp, base); @@ -874,9 +908,9 @@ SDL_strtol(const char *string, char **endp, int base) } } - len = SDL_ScanLong(string, base, &value); + len = SDL_ScanLong(string, 0, base, &value); if (endp) { - *endp = (char *) string + len; + *endp = (char *)string + len; } return value; #endif /* HAVE_STRTOL */ @@ -899,16 +933,15 @@ SDL_strtoul(const char *string, char **endp, int base) } } - len = SDL_ScanUnsignedLong(string, base, &value); + len = SDL_ScanUnsignedLong(string, 0, base, &value); if (endp) { - *endp = (char *) string + len; + *endp = (char *)string + len; } return value; #endif /* HAVE_STRTOUL */ } -Sint64 -SDL_strtoll(const char *string, char **endp, int base) +Sint64 SDL_strtoll(const char *string, char **endp, int base) { #if defined(HAVE_STRTOLL) return strtoll(string, endp, base); @@ -924,16 +957,15 @@ SDL_strtoll(const char *string, char **endp, int base) } } - len = SDL_ScanLongLong(string, base, &value); + len = SDL_ScanLongLong(string, 0, base, &value); if (endp) { - *endp = (char *) string + len; + *endp = (char *)string + len; } return value; #endif /* HAVE_STRTOLL */ } -Uint64 -SDL_strtoull(const char *string, char **endp, int base) +Uint64 SDL_strtoull(const char *string, char **endp, int base) { #if defined(HAVE_STRTOULL) return strtoull(string, endp, base); @@ -949,9 +981,9 @@ SDL_strtoull(const char *string, char **endp, int base) } } - len = SDL_ScanUnsignedLongLong(string, base, &value); + len = SDL_ScanUnsignedLongLong(string, 0, base, &value); if (endp) { - *endp = (char *) string + len; + *endp = (char *)string + len; } return value; #endif /* HAVE_STRTOULL */ @@ -968,103 +1000,105 @@ SDL_strtod(const char *string, char **endp) len = SDL_ScanFloat(string, &value); if (endp) { - *endp = (char *) string + len; + *endp = (char *)string + len; } return value; #endif /* HAVE_STRTOD */ } -int -SDL_strcmp(const char *str1, const char *str2) +int SDL_strcmp(const char *str1, const char *str2) { #if defined(HAVE_STRCMP) return strcmp(str1, str2); #else - while (*str1 && *str2) { - if (*str1 != *str2) + int result; + + while (1) { + result = ((unsigned char)*str1 - (unsigned char)*str2); + if (result != 0 || (*str1 == '\0' /* && *str2 == '\0'*/)) { break; + } ++str1; ++str2; } - return (int)((unsigned char) *str1 - (unsigned char) *str2); + return result; #endif /* HAVE_STRCMP */ } -int -SDL_strncmp(const char *str1, const char *str2, size_t maxlen) +int SDL_strncmp(const char *str1, const char *str2, size_t maxlen) { #if defined(HAVE_STRNCMP) return strncmp(str1, str2, maxlen); #else - while (*str1 && *str2 && maxlen) { - if (*str1 != *str2) + int result; + + while (maxlen) { + result = (int)(unsigned char)*str1 - (unsigned char)*str2; + if (result != 0 || *str1 == '\0' /* && *str2 == '\0'*/) { break; + } ++str1; ++str2; --maxlen; } if (!maxlen) { - return 0; + result = 0; } - return (int) ((unsigned char) *str1 - (unsigned char) *str2); + return result; #endif /* HAVE_STRNCMP */ } -int -SDL_strcasecmp(const char *str1, const char *str2) +int SDL_strcasecmp(const char *str1, const char *str2) { #ifdef HAVE_STRCASECMP return strcasecmp(str1, str2); #elif defined(HAVE__STRICMP) return _stricmp(str1, str2); #else - char a = 0; - char b = 0; - while (*str1 && *str2) { - a = SDL_toupper((unsigned char) *str1); - b = SDL_toupper((unsigned char) *str2); - if (a != b) + int a, b, result; + + while (1) { + a = SDL_toupper((unsigned char)*str1); + b = SDL_toupper((unsigned char)*str2); + result = a - b; + if (result != 0 || a == 0 /*&& b == 0*/) { break; + } ++str1; ++str2; } - a = SDL_toupper(*str1); - b = SDL_toupper(*str2); - return (int) ((unsigned char) a - (unsigned char) b); + return result; #endif /* HAVE_STRCASECMP */ } -int -SDL_strncasecmp(const char *str1, const char *str2, size_t maxlen) +int SDL_strncasecmp(const char *str1, const char *str2, size_t maxlen) { #ifdef HAVE_STRNCASECMP return strncasecmp(str1, str2, maxlen); #elif defined(HAVE__STRNICMP) return _strnicmp(str1, str2, maxlen); #else - char a = 0; - char b = 0; - while (*str1 && *str2 && maxlen) { - a = SDL_tolower((unsigned char) *str1); - b = SDL_tolower((unsigned char) *str2); - if (a != b) + int a, b, result; + + while (maxlen) { + a = SDL_tolower((unsigned char)*str1); + b = SDL_tolower((unsigned char)*str2); + result = a - b; + if (result != 0 || a == 0 /*&& b == 0*/) { break; + } ++str1; ++str2; --maxlen; } if (maxlen == 0) { - return 0; - } else { - a = SDL_tolower((unsigned char) *str1); - b = SDL_tolower((unsigned char) *str2); - return (int) ((unsigned char) a - (unsigned char) b); + result = 0; } + return result; #endif /* HAVE_STRNCASECMP */ } -int -SDL_sscanf(const char *text, SDL_SCANF_FORMAT_STRING const char *fmt, ...) +int SDL_sscanf(const char *text, SDL_SCANF_FORMAT_STRING const char *fmt, ...) { int rc; va_list ap; @@ -1075,14 +1109,46 @@ SDL_sscanf(const char *text, SDL_SCANF_FORMAT_STRING const char *fmt, ...) } #ifdef HAVE_VSSCANF -int -SDL_vsscanf(const char *text, const char *fmt, va_list ap) +int SDL_vsscanf(const char *text, const char *fmt, va_list ap) { return vsscanf(text, fmt, ap); } #else -int -SDL_vsscanf(const char *text, const char *fmt, va_list ap) +static SDL_bool CharacterMatchesSet(char c, const char *set, size_t set_len) +{ + SDL_bool invert = SDL_FALSE; + SDL_bool result = SDL_FALSE; + + if (*set == '^') { + invert = SDL_TRUE; + ++set; + --set_len; + } + while (set_len > 0 && !result) { + if (set_len >= 3 && set[1] == '-') { + char low_char = SDL_min(set[0], set[2]); + char high_char = SDL_max(set[0], set[2]); + if (c >= low_char && c <= high_char) { + result = SDL_TRUE; + } + set += 3; + set_len -= 3; + } else { + if (c == *set) { + result = SDL_TRUE; + } + ++set; + --set_len; + } + } + if (invert) { + result = result ? SDL_FALSE : SDL_TRUE; + } + return result; +} + +/* NOLINTNEXTLINE(readability-non-const-parameter) */ +int SDL_vsscanf(const char *text, const char *fmt, va_list ap) { int retval = 0; @@ -1092,7 +1158,7 @@ SDL_vsscanf(const char *text, const char *fmt, va_list ap) while (*fmt) { if (*fmt == ' ') { - while (SDL_isspace((unsigned char) *text)) { + while (SDL_isspace((unsigned char)*text)) { ++text; } ++fmt; @@ -1107,7 +1173,8 @@ SDL_vsscanf(const char *text, const char *fmt, va_list ap) DO_SHORT, DO_INT, DO_LONG, - DO_LONGLONG + DO_LONGLONG, + DO_SIZE_T } inttype = DO_INT; size_t advance; SDL_bool suppress = SDL_FALSE; @@ -1125,7 +1192,7 @@ SDL_vsscanf(const char *text, const char *fmt, va_list ap) suppress = SDL_TRUE; ++fmt; } - fmt += SDL_ScanLong(fmt, 10, &count); + fmt += SDL_ScanLong(fmt, 0, 10, &count); if (*fmt == 'c') { if (!count) { @@ -1145,7 +1212,7 @@ SDL_vsscanf(const char *text, const char *fmt, va_list ap) continue; } - while (SDL_isspace((unsigned char) *text)) { + while (SDL_isspace((unsigned char)*text)) { ++text; } @@ -1156,7 +1223,9 @@ SDL_vsscanf(const char *text, const char *fmt, va_list ap) suppress = SDL_TRUE; break; case 'h': - if (inttype > DO_SHORT) { + if (inttype == DO_INT) { + inttype = DO_SHORT; + } else if (inttype > DO_SHORT) { ++inttype; } break; @@ -1171,56 +1240,66 @@ SDL_vsscanf(const char *text, const char *fmt, va_list ap) inttype = DO_LONGLONG; } break; + case 'z': + inttype = DO_SIZE_T; + break; case 'i': - { - int index = 0; - if (text[index] == '-') { - ++index; - } - if (text[index] == '0') { - if (SDL_tolower((unsigned char) text[index + 1]) == 'x') { - radix = 16; - } else { - radix = 8; - } + { + int index = 0; + if (text[index] == '-') { + ++index; + } + if (text[index] == '0') { + if (SDL_tolower((unsigned char)text[index + 1]) == 'x') { + radix = 16; + } else { + radix = 8; } } - /* Fall through to %d handling */ + } + SDL_FALLTHROUGH; case 'd': if (inttype == DO_LONGLONG) { - Sint64 value; - advance = SDL_ScanLongLong(text, radix, &value); + Sint64 value = 0; + advance = SDL_ScanLongLong(text, count, radix, &value); text += advance; if (advance && !suppress) { Sint64 *valuep = va_arg(ap, Sint64 *); *valuep = value; ++retval; } + } else if (inttype == DO_SIZE_T) { + Sint64 value = 0; + advance = SDL_ScanLongLong(text, count, radix, &value); + text += advance; + if (advance && !suppress) { + size_t *valuep = va_arg(ap, size_t *); + *valuep = (size_t)value; + ++retval; + } } else { - long value; - advance = SDL_ScanLong(text, radix, &value); + long value = 0; + advance = SDL_ScanLong(text, count, radix, &value); text += advance; if (advance && !suppress) { switch (inttype) { case DO_SHORT: - { - short *valuep = va_arg(ap, short *); - *valuep = (short) value; - } - break; + { + short *valuep = va_arg(ap, short *); + *valuep = (short)value; + } break; case DO_INT: - { - int *valuep = va_arg(ap, int *); - *valuep = (int) value; - } - break; + { + int *valuep = va_arg(ap, int *); + *valuep = (int)value; + } break; case DO_LONG: - { - long *valuep = va_arg(ap, long *); - *valuep = value; - } - break; + { + long *valuep = va_arg(ap, long *); + *valuep = value; + } break; case DO_LONGLONG: + case DO_SIZE_T: /* Handled above */ break; } @@ -1233,48 +1312,55 @@ SDL_vsscanf(const char *text, const char *fmt, va_list ap) if (radix == 10) { radix = 8; } - /* Fall through to unsigned handling */ + SDL_FALLTHROUGH; case 'x': case 'X': if (radix == 10) { radix = 16; } - /* Fall through to unsigned handling */ + SDL_FALLTHROUGH; case 'u': if (inttype == DO_LONGLONG) { Uint64 value = 0; - advance = SDL_ScanUnsignedLongLong(text, radix, &value); + advance = SDL_ScanUnsignedLongLong(text, count, radix, &value); text += advance; if (advance && !suppress) { Uint64 *valuep = va_arg(ap, Uint64 *); *valuep = value; ++retval; } + } else if (inttype == DO_SIZE_T) { + Uint64 value = 0; + advance = SDL_ScanUnsignedLongLong(text, count, radix, &value); + text += advance; + if (advance && !suppress) { + size_t *valuep = va_arg(ap, size_t *); + *valuep = (size_t)value; + ++retval; + } } else { unsigned long value = 0; - advance = SDL_ScanUnsignedLong(text, radix, &value); + advance = SDL_ScanUnsignedLong(text, count, radix, &value); text += advance; if (advance && !suppress) { switch (inttype) { case DO_SHORT: - { - short *valuep = va_arg(ap, short *); - *valuep = (short) value; - } - break; + { + short *valuep = va_arg(ap, short *); + *valuep = (short)value; + } break; case DO_INT: - { - int *valuep = va_arg(ap, int *); - *valuep = (int) value; - } - break; + { + int *valuep = va_arg(ap, int *); + *valuep = (int)value; + } break; case DO_LONG: - { - long *valuep = va_arg(ap, long *); - *valuep = value; - } - break; + { + long *valuep = va_arg(ap, long *); + *valuep = value; + } break; case DO_LONGLONG: + case DO_SIZE_T: /* Handled above */ break; } @@ -1284,34 +1370,34 @@ SDL_vsscanf(const char *text, const char *fmt, va_list ap) done = SDL_TRUE; break; case 'p': - { - uintptr_t value = 0; - advance = SDL_ScanUintPtrT(text, 16, &value); - text += advance; - if (advance && !suppress) { - void **valuep = va_arg(ap, void **); - *valuep = (void *) value; - ++retval; - } + { + uintptr_t value = 0; + advance = SDL_ScanUintPtrT(text, 16, &value); + text += advance; + if (advance && !suppress) { + void **valuep = va_arg(ap, void **); + *valuep = (void *)value; + ++retval; } + } done = SDL_TRUE; break; case 'f': - { - double value; - advance = SDL_ScanFloat(text, &value); - text += advance; - if (advance && !suppress) { - float *valuep = va_arg(ap, float *); - *valuep = (float) value; - ++retval; - } + { + double value = 0.0; + advance = SDL_ScanFloat(text, &value); + text += advance; + if (advance && !suppress) { + float *valuep = va_arg(ap, float *); + *valuep = (float)value; + ++retval; } + } done = SDL_TRUE; break; case 's': if (suppress) { - while (!SDL_isspace((unsigned char) *text)) { + while (!SDL_isspace((unsigned char)*text)) { ++text; if (count) { if (--count == 0) { @@ -1321,7 +1407,7 @@ SDL_vsscanf(const char *text, const char *fmt, va_list ap) } } else { char *valuep = va_arg(ap, char *); - while (!SDL_isspace((unsigned char) *text)) { + while (!SDL_isspace((unsigned char)*text)) { *valuep++ = *text++; if (count) { if (--count == 0) { @@ -1334,6 +1420,44 @@ SDL_vsscanf(const char *text, const char *fmt, va_list ap) } done = SDL_TRUE; break; + case '[': + { + const char *set = fmt + 1; + while (*fmt && *fmt != ']') { + ++fmt; + } + if (*fmt) { + size_t set_len = (fmt - set); + if (suppress) { + while (CharacterMatchesSet(*text, set, set_len)) { + ++text; + if (count) { + if (--count == 0) { + break; + } + } + } + } else { + SDL_bool had_match = SDL_FALSE; + char *valuep = va_arg(ap, char *); + while (CharacterMatchesSet(*text, set, set_len)) { + had_match = SDL_TRUE; + *valuep++ = *text++; + if (count) { + if (--count == 0) { + break; + } + } + } + *valuep = '\0'; + if (had_match) { + ++retval; + } + } + } + } + done = SDL_TRUE; + break; default: done = SDL_TRUE; break; @@ -1355,8 +1479,7 @@ SDL_vsscanf(const char *text, const char *fmt, va_list ap) } #endif /* HAVE_VSSCANF */ -int -SDL_snprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) +int SDL_snprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) { va_list ap; int retval; @@ -1373,10 +1496,16 @@ SDL_snprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, SDL_PRINTF_FORMAT_ int SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt, va_list ap) { int retval; - if (!fmt) fmt = ""; + if (!fmt) { + fmt = ""; + } retval = _vsnprintf(text, maxlen, fmt, ap); - if (maxlen > 0) text[maxlen-1] = '\0'; - if (retval < 0) retval = (int) maxlen; + if (maxlen > 0) { + text[maxlen - 1] = '\0'; + } + if (retval < 0) { + retval = (int)maxlen; + } return retval; } #elif defined(HAVE_VSNPRINTF) @@ -1388,7 +1517,9 @@ int SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *f return vsnprintf(text, maxlen, fmt, ap); } #else - /* FIXME: implement more of the format specifiers */ +#define TEXT_AND_LEN_ARGS (length < maxlen) ? &text[length] : NULL, (length < maxlen) ? (maxlen - length) : 0 + +/* FIXME: implement more of the format specifiers */ typedef enum { SDL_CASE_NOCHANGE, @@ -1400,7 +1531,7 @@ typedef struct { SDL_bool left_justify; /* for now: ignored. */ SDL_bool force_sign; - SDL_bool force_type; /* for now: used only by float printer, ignored otherwise. */ + SDL_bool force_type; /* for now: used only by float printer, ignored otherwise. */ SDL_bool pad_zeroes; SDL_letter_case force_case; int width; @@ -1408,13 +1539,12 @@ typedef struct int precision; } SDL_FormatInfo; -static size_t -SDL_PrintString(char *text, size_t maxlen, SDL_FormatInfo *info, const char *string) +static size_t SDL_PrintString(char *text, size_t maxlen, SDL_FormatInfo *info, const char *string) { size_t length = 0; size_t slen, sz; - if (string == NULL) { + if (!string) { string = "(null)"; } @@ -1424,43 +1554,59 @@ SDL_PrintString(char *text, size_t maxlen, SDL_FormatInfo *info, const char *str size_t width = info->width - sz; size_t filllen; - if (info->precision >= 0 && (size_t)info->precision < sz) + if (info->precision >= 0 && (size_t)info->precision < sz) { width += sz - (size_t)info->precision; + } filllen = SDL_min(width, maxlen); SDL_memset(text, fill, filllen); text += filllen; - length += filllen; maxlen -= filllen; + length += width; } - slen = SDL_strlcpy(text, string, maxlen); - length += SDL_min(slen, maxlen); + SDL_strlcpy(text, string, maxlen); + length += sz; if (info) { if (info->precision >= 0 && (size_t)info->precision < sz) { slen = (size_t)info->precision; if (slen < maxlen) { - text[slen] = 0; - length -= (sz - slen); + text[slen] = '\0'; } + length -= (sz - slen); } - if (info->force_case == SDL_CASE_LOWER) { - SDL_strlwr(text); - } else if (info->force_case == SDL_CASE_UPPER) { - SDL_strupr(text); + if (maxlen > 1) { + if (info->force_case == SDL_CASE_LOWER) { + SDL_strlwr(text); + } else if (info->force_case == SDL_CASE_UPPER) { + SDL_strupr(text); + } } } return length; } -static void -SDL_IntPrecisionAdjust(char *num, size_t maxlen, SDL_FormatInfo *info) -{/* left-pad num with zeroes. */ +static size_t SDL_PrintStringW(char *text, size_t maxlen, SDL_FormatInfo *info, const wchar_t *wide_string) +{ + size_t length = 0; + if (wide_string) { + char *string = SDL_iconv_string("UTF-8", "WCHAR_T", (char *)(wide_string), (SDL_wcslen(wide_string) + 1) * sizeof(*wide_string)); + length = SDL_PrintString(TEXT_AND_LEN_ARGS, info, string); + SDL_free(string); + } else { + length = SDL_PrintString(TEXT_AND_LEN_ARGS, info, NULL); + } + return length; +} + +static void SDL_IntPrecisionAdjust(char *num, size_t maxlen, SDL_FormatInfo *info) +{ /* left-pad num with zeroes. */ size_t sz, pad, have_sign; - if (!info) + if (!info) { return; + } have_sign = 0; if (*num == '-' || *num == '+') { @@ -1476,12 +1622,12 @@ SDL_IntPrecisionAdjust(char *num, size_t maxlen, SDL_FormatInfo *info) SDL_memset(num, '0', pad); } } - info->precision = -1;/* so that SDL_PrintString() doesn't make a mess. */ + info->precision = -1; /* so that SDL_PrintString() doesn't make a mess. */ if (info->pad_zeroes && info->width > 0 && (size_t)info->width > sz + have_sign) { - /* handle here: spaces are added before the sign - but zeroes must be placed _after_ the sign. */ - /* sz hasn't changed: we ignore pad_zeroes if a precision is given. */ + /* handle here: spaces are added before the sign + but zeroes must be placed _after_ the sign. */ + /* sz hasn't changed: we ignore pad_zeroes if a precision is given. */ pad = (size_t)info->width - sz - have_sign; if (pad + sz + 1 <= maxlen) { SDL_memmove(num + pad, num, sz + 1); @@ -1491,8 +1637,7 @@ SDL_IntPrecisionAdjust(char *num, size_t maxlen, SDL_FormatInfo *info) } } -static size_t -SDL_PrintLong(char *text, size_t maxlen, SDL_FormatInfo *info, long value) +static size_t SDL_PrintLong(char *text, size_t maxlen, SDL_FormatInfo *info, long value) { char num[130], *p = num; @@ -1501,22 +1646,20 @@ SDL_PrintLong(char *text, size_t maxlen, SDL_FormatInfo *info, long value) } SDL_ltoa(value, p, info ? info->radix : 10); - SDL_IntPrecisionAdjust(num, maxlen, info); + SDL_IntPrecisionAdjust(num, sizeof(num), info); return SDL_PrintString(text, maxlen, info, num); } -static size_t -SDL_PrintUnsignedLong(char *text, size_t maxlen, SDL_FormatInfo *info, unsigned long value) +static size_t SDL_PrintUnsignedLong(char *text, size_t maxlen, SDL_FormatInfo *info, unsigned long value) { char num[130]; SDL_ultoa(value, num, info ? info->radix : 10); - SDL_IntPrecisionAdjust(num, maxlen, info); + SDL_IntPrecisionAdjust(num, sizeof(num), info); return SDL_PrintString(text, maxlen, info, num); } -static size_t -SDL_PrintLongLong(char *text, size_t maxlen, SDL_FormatInfo *info, Sint64 value) +static size_t SDL_PrintLongLong(char *text, size_t maxlen, SDL_FormatInfo *info, Sint64 value) { char num[130], *p = num; @@ -1525,143 +1668,109 @@ SDL_PrintLongLong(char *text, size_t maxlen, SDL_FormatInfo *info, Sint64 value) } SDL_lltoa(value, p, info ? info->radix : 10); - SDL_IntPrecisionAdjust(num, maxlen, info); + SDL_IntPrecisionAdjust(num, sizeof(num), info); return SDL_PrintString(text, maxlen, info, num); } -static size_t -SDL_PrintUnsignedLongLong(char *text, size_t maxlen, SDL_FormatInfo *info, Uint64 value) +static size_t SDL_PrintUnsignedLongLong(char *text, size_t maxlen, SDL_FormatInfo *info, Uint64 value) { char num[130]; SDL_ulltoa(value, num, info ? info->radix : 10); - SDL_IntPrecisionAdjust(num, maxlen, info); + SDL_IntPrecisionAdjust(num, sizeof(num), info); return SDL_PrintString(text, maxlen, info, num); } -static size_t -SDL_PrintFloat(char *text, size_t maxlen, SDL_FormatInfo *info, double arg) +static size_t SDL_PrintFloat(char *text, size_t maxlen, SDL_FormatInfo *info, double arg) { - int width; - size_t len; - size_t left = maxlen; - char *textstart = text; + size_t length = 0; - if (arg) { - /* This isn't especially accurate, but hey, it's easy. :) */ - unsigned long value; + /* This isn't especially accurate, but hey, it's easy. :) */ + unsigned long value; - if (arg < 0) { - if (left > 1) { - *text = '-'; - --left; - } - ++text; - arg = -arg; - } else if (info->force_sign) { - if (left > 1) { - *text = '+'; - --left; - } - ++text; + if (arg < 0) { + if (length < maxlen) { + text[length] = '-'; } - value = (unsigned long) arg; - len = SDL_PrintUnsignedLong(text, left, NULL, value); - if (len >= left) { - text += (left > 1) ? left - 1 : 0; - left = SDL_min(left, 1); - } else { - text += len; - left -= len; + ++length; + arg = -arg; + } else if (info->force_sign) { + if (length < maxlen) { + text[length] = '+'; } - arg -= value; - if (info->precision < 0) { - info->precision = 6; + ++length; + } + value = (unsigned long)arg; + length += SDL_PrintUnsignedLong(TEXT_AND_LEN_ARGS, NULL, value); + arg -= value; + if (info->precision < 0) { + info->precision = 6; + } + if (info->force_type || info->precision > 0) { + int mult = 10; + if (length < maxlen) { + text[length] = '.'; } - if (info->force_type || info->precision > 0) { - int mult = 10; - if (left > 1) { - *text = '.'; - --left; - } - ++text; - while (info->precision-- > 0) { - value = (unsigned long) (arg * mult); - len = SDL_PrintUnsignedLong(text, left, NULL, value); - if (len >= left) { - text += (left > 1) ? left - 1 : 0; - left = SDL_min(left, 1); - } else { - text += len; - left -= len; - } - arg -= (double) value / mult; - mult *= 10; - } - } - } else { - if (left > 1) { - *text = '0'; - --left; - } - ++text; - if (info->force_type) { - if (left > 1) { - *text = '.'; - --left; - } - ++text; + ++length; + while (info->precision-- > 0) { + value = (unsigned long)(arg * mult); + length += SDL_PrintUnsignedLong(TEXT_AND_LEN_ARGS, NULL, value); + arg -= (double)value / mult; + mult *= 10; } } - width = info->width - (int)(text - textstart); - if (width > 0) { + if (info->width > 0 && (size_t)info->width > length) { const char fill = info->pad_zeroes ? '0' : ' '; - char *end = text+left-1; - len = (text - textstart); - for (len = (text - textstart); len--; ) { - if ((textstart+len+width) < end) { - *(textstart+len+width) = *(textstart+len); - } - } - len = (size_t)width; - if (len >= left) { - text += (left > 1) ? left - 1 : 0; - left = SDL_min(left, 1); - } else { - text += len; - left -= len; - } + size_t width = info->width - length; + size_t filllen, movelen; - if (end != textstart) { - const size_t filllen = SDL_min(len, ((size_t) (end - textstart)) - 1); - SDL_memset(textstart, fill, filllen); - } + filllen = SDL_min(width, maxlen); + movelen = SDL_min(length, (maxlen - filllen)); + SDL_memmove(&text[filllen], text, movelen); + SDL_memset(text, fill, filllen); + length += width; } - return (text - textstart); + return length; } -int -SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt, va_list ap) +static size_t SDL_PrintPointer(char *text, size_t maxlen, SDL_FormatInfo *info, const void *value) { - size_t left = maxlen; - char *textstart = text; + char num[130]; + size_t length; + if (!value) { + return SDL_PrintString(text, maxlen, info, NULL); + } + + SDL_ulltoa((unsigned long long)(uintptr_t)value, num, 16); + length = SDL_PrintString(text, maxlen, info, "0x"); + return length + SDL_PrintString(TEXT_AND_LEN_ARGS, info, num); +} + +/* NOLINTNEXTLINE(readability-non-const-parameter) */ +int SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt, va_list ap) +{ + size_t length = 0; + + if (!text) { + maxlen = 0; + } if (!fmt) { fmt = ""; } - while (*fmt && left > 1) { + while (*fmt) { if (*fmt == '%') { SDL_bool done = SDL_FALSE; - size_t len = 0; SDL_bool check_flag; SDL_FormatInfo info; enum { DO_INT, DO_LONG, - DO_LONGLONG + DO_LONGLONG, + DO_SIZE_T } inttype = DO_INT; SDL_zero(info); @@ -1692,8 +1801,7 @@ SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt, if (*fmt >= '0' && *fmt <= '9') { info.width = SDL_strtol(fmt, (char **)&fmt, 0); - } - else if (*fmt == '*') { + } else if (*fmt == '*') { ++fmt; info.width = va_arg(ap, int); } @@ -1716,18 +1824,18 @@ SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt, while (!done) { switch (*fmt) { case '%': - if (left > 1) { - *text = '%'; + if (length < maxlen) { + text[length] = '%'; } - len = 1; + ++length; done = SDL_TRUE; break; case 'c': /* char is promoted to int when passed through (...) */ - if (left > 1) { - *text = (char) va_arg(ap, int); + if (length < maxlen) { + text[length] = (char)va_arg(ap, int); } - len = 1; + ++length; done = SDL_TRUE; break; case 'h': @@ -1744,6 +1852,9 @@ SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt, inttype = DO_LONGLONG; } break; + case 'z': + inttype = DO_SIZE_T; + break; case 'i': case 'd': if (info.precision >= 0) { @@ -1751,24 +1862,32 @@ SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt, } switch (inttype) { case DO_INT: - len = SDL_PrintLong(text, left, &info, - (long) va_arg(ap, int)); + length += SDL_PrintLong(TEXT_AND_LEN_ARGS, &info, + (long)va_arg(ap, int)); break; case DO_LONG: - len = SDL_PrintLong(text, left, &info, - va_arg(ap, long)); + length += SDL_PrintLong(TEXT_AND_LEN_ARGS, &info, + va_arg(ap, long)); break; case DO_LONGLONG: - len = SDL_PrintLongLong(text, left, &info, - va_arg(ap, Sint64)); + length += SDL_PrintLongLong(TEXT_AND_LEN_ARGS, &info, + va_arg(ap, Sint64)); + break; + case DO_SIZE_T: + length += SDL_PrintLongLong(TEXT_AND_LEN_ARGS, &info, + va_arg(ap, size_t)); break; } done = SDL_TRUE; break; case 'p': + info.force_case = SDL_CASE_LOWER; + length += SDL_PrintPointer(TEXT_AND_LEN_ARGS, &info, va_arg(ap, void *)); + done = SDL_TRUE; + break; case 'x': info.force_case = SDL_CASE_LOWER; - /* Fall through to 'X' handling */ + SDL_FALLTHROUGH; case 'X': if (info.force_case == SDL_CASE_NOCHANGE) { info.force_case = SDL_CASE_UPPER; @@ -1776,15 +1895,12 @@ SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt, if (info.radix == 10) { info.radix = 16; } - if (*fmt == 'p') { - inttype = DO_LONG; - } - /* Fall through to unsigned handling */ + SDL_FALLTHROUGH; case 'o': if (info.radix == 10) { info.radix = 8; } - /* Fall through to unsigned handling */ + SDL_FALLTHROUGH; case 'u': info.force_sign = SDL_FALSE; if (info.precision >= 0) { @@ -1792,39 +1908,41 @@ SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt, } switch (inttype) { case DO_INT: - len = SDL_PrintUnsignedLong(text, left, &info, - (unsigned long) - va_arg(ap, unsigned int)); + length += SDL_PrintUnsignedLong(TEXT_AND_LEN_ARGS, &info, + (unsigned long) + va_arg(ap, unsigned int)); break; case DO_LONG: - len = SDL_PrintUnsignedLong(text, left, &info, - va_arg(ap, unsigned long)); + length += SDL_PrintUnsignedLong(TEXT_AND_LEN_ARGS, &info, + va_arg(ap, unsigned long)); break; case DO_LONGLONG: - len = SDL_PrintUnsignedLongLong(text, left, &info, - va_arg(ap, Uint64)); + length += SDL_PrintUnsignedLongLong(TEXT_AND_LEN_ARGS, &info, + va_arg(ap, Uint64)); + break; + case DO_SIZE_T: + length += SDL_PrintUnsignedLongLong(TEXT_AND_LEN_ARGS, &info, + va_arg(ap, size_t)); break; } done = SDL_TRUE; break; case 'f': - len = SDL_PrintFloat(text, left, &info, va_arg(ap, double)); + length += SDL_PrintFloat(TEXT_AND_LEN_ARGS, &info, va_arg(ap, double)); done = SDL_TRUE; break; case 'S': - { - /* In practice this is used on Windows for WCHAR strings */ - wchar_t *wide_arg = va_arg(ap, wchar_t *); - char *arg = SDL_iconv_string("UTF-8", "UTF-16LE", (char *)(wide_arg), (SDL_wcslen(wide_arg)+1)*sizeof(*wide_arg)); - info.pad_zeroes = SDL_FALSE; - len = SDL_PrintString(text, left, &info, arg); - SDL_free(arg); - done = SDL_TRUE; - } + info.pad_zeroes = SDL_FALSE; + length += SDL_PrintStringW(TEXT_AND_LEN_ARGS, &info, va_arg(ap, wchar_t *)); + done = SDL_TRUE; break; case 's': info.pad_zeroes = SDL_FALSE; - len = SDL_PrintString(text, left, &info, va_arg(ap, char *)); + if (inttype > DO_INT) { + length += SDL_PrintStringW(TEXT_AND_LEN_ARGS, &info, va_arg(ap, wchar_t *)); + } else { + length += SDL_PrintString(TEXT_AND_LEN_ARGS, &info, va_arg(ap, char *)); + } done = SDL_TRUE; break; default: @@ -1833,23 +1951,78 @@ SDL_vsnprintf(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, const char *fmt, } ++fmt; } - if (len >= left) { - text += (left > 1) ? left - 1 : 0; - left = SDL_min(left, 1); - } else { - text += len; - left -= len; - } } else { - *text++ = *fmt++; - --left; + if (length < maxlen) { + text[length] = *fmt; + } + ++fmt; + ++length; } } - if (left > 0) { - *text = '\0'; + if (length < maxlen) { + text[length] = '\0'; + } else if (maxlen > 0) { + text[maxlen - 1] = '\0'; } - return (int)(text - textstart); + return (int)length; } + +#undef TEXT_AND_LEN_ARGS #endif /* HAVE_VSNPRINTF */ -/* vi: set ts=4 sw=4 expandtab: */ +int SDL_asprintf(char **strp, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) +{ + va_list ap; + int retval; + + va_start(ap, fmt); + retval = SDL_vasprintf(strp, fmt, ap); + va_end(ap); + + return retval; +} + +int SDL_vasprintf(char **strp, const char *fmt, va_list ap) +{ + int retval; + int size = 100; /* Guess we need no more than 100 bytes */ + char *p, *np; + va_list aq; + + *strp = NULL; + + p = (char *)SDL_malloc(size); + if (!p) { + return -1; + } + + while (1) { + /* Try to print in the allocated space */ + va_copy(aq, ap); + retval = SDL_vsnprintf(p, size, fmt, aq); + va_end(aq); + + /* Check error code */ + if (retval < 0) { + SDL_free(p); + return retval; + } + + /* If that worked, return the string */ + if (retval < size) { + *strp = p; + return retval; + } + + /* Else try again with more space */ + size = retval + 1; /* Precisely what is needed */ + + np = (char *)SDL_realloc(p, size); + if (!np) { + SDL_free(p); + return -1; + } else { + p = np; + } + } +} diff --git a/SDL2-2.0.12/src/stdlib/SDL_strtokr.c b/SDL2-2.30.5/src/stdlib/SDL_strtokr.c similarity index 94% rename from SDL2-2.0.12/src/stdlib/SDL_strtokr.c rename to SDL2-2.30.5/src/stdlib/SDL_strtokr.c index 3d69363..38dc830 100644 --- a/SDL2-2.0.12/src/stdlib/SDL_strtokr.c +++ b/SDL2-2.30.5/src/stdlib/SDL_strtokr.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -28,12 +28,9 @@ char *SDL_strtokr(char *s1, const char *s2, char **ptr) { -#if defined(HAVE_STRTOK_R) +#ifdef HAVE_STRTOK_R return strtok_r(s1, s2, ptr); -#elif defined(_MSC_VER) && defined(HAVE_STRTOK_S) - return strtok_s(s1, s2, ptr); - #else /* SDL implementation */ /* * Adapted from _PDCLIB_strtok() of PDClib library at diff --git a/SDL2-2.30.5/src/stdlib/SDL_vacopy.h b/SDL2-2.30.5/src/stdlib/SDL_vacopy.h new file mode 100644 index 0000000..ee45bf6 --- /dev/null +++ b/SDL2-2.30.5/src/stdlib/SDL_vacopy.h @@ -0,0 +1,36 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +/* Do our best to make sure va_copy is working */ +#if defined(__NGAGE__) +#undef va_copy +#define va_copy(dst, src) dst = src + +#elif defined(_MSC_VER) && _MSC_VER <= 1800 +/* Visual Studio 2013 tries to link with _vacopy in the C runtime. Newer versions do an inline assignment */ +#undef va_copy +#define va_copy(dst, src) dst = src + +#elif defined(__GNUC__) && (__GNUC__ < 3) +#define va_copy(dst, src) __va_copy(dst, src) +#endif + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/test/SDL_test_assert.c b/SDL2-2.30.5/src/test/SDL_test_assert.c similarity index 84% rename from SDL2-2.0.12/src/test/SDL_test_assert.c rename to SDL2-2.30.5/src/test/SDL_test_assert.c index 7414349..e8d0ff0 100644 --- a/SDL2-2.0.12/src/test/SDL_test_assert.c +++ b/SDL2-2.30.5/src/test/SDL_test_assert.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -36,10 +36,10 @@ #define SDLTEST_ASSERT_SUMMARY_FORMAT "Assert Summary: Total=%d Passed=%d Failed=%d" /* ! \brief counts the failed asserts */ -static Uint32 SDLTest_AssertsFailed = 0; +static int SDLTest_AssertsFailed = 0; /* ! \brief counts the passed asserts */ -static Uint32 SDLTest_AssertsPassed = 0; +static int SDLTest_AssertsPassed = 0; /* * Assert that logs and break execution flow on failures (i.e. for harness errors). @@ -52,7 +52,7 @@ void SDLTest_Assert(int assertCondition, SDL_PRINTF_FORMAT_STRING const char *as /* Print assert description into a buffer */ SDL_memset(logMessage, 0, SDLTEST_MAX_LOGMESSAGE_LENGTH); va_start(list, assertDescription); - SDL_vsnprintf(logMessage, SDLTEST_MAX_LOGMESSAGE_LENGTH - 1, assertDescription, list); + (void)SDL_vsnprintf(logMessage, SDLTEST_MAX_LOGMESSAGE_LENGTH - 1, assertDescription, list); va_end(list); /* Log, then assert and break on failure */ @@ -70,17 +70,14 @@ int SDLTest_AssertCheck(int assertCondition, SDL_PRINTF_FORMAT_STRING const char /* Print assert description into a buffer */ SDL_memset(logMessage, 0, SDLTEST_MAX_LOGMESSAGE_LENGTH); va_start(list, assertDescription); - SDL_vsnprintf(logMessage, SDLTEST_MAX_LOGMESSAGE_LENGTH - 1, assertDescription, list); + (void)SDL_vsnprintf(logMessage, SDLTEST_MAX_LOGMESSAGE_LENGTH - 1, assertDescription, list); va_end(list); /* Log pass or fail message */ - if (assertCondition == ASSERT_FAIL) - { + if (assertCondition == ASSERT_FAIL) { SDLTest_AssertsFailed++; SDLTest_LogError(SDLTEST_ASSERT_CHECK_FORMAT, logMessage, "Failed"); - } - else - { + } else { SDLTest_AssertsPassed++; SDLTest_Log(SDLTEST_ASSERT_CHECK_FORMAT, logMessage, "Passed"); } @@ -99,12 +96,12 @@ void SDLTest_AssertPass(SDL_PRINTF_FORMAT_STRING const char *assertDescription, /* Print assert description into a buffer */ SDL_memset(logMessage, 0, SDLTEST_MAX_LOGMESSAGE_LENGTH); va_start(list, assertDescription); - SDL_vsnprintf(logMessage, SDLTEST_MAX_LOGMESSAGE_LENGTH - 1, assertDescription, list); + (void)SDL_vsnprintf(logMessage, SDLTEST_MAX_LOGMESSAGE_LENGTH - 1, assertDescription, list); va_end(list); - /* Log pass message */ + /* Log pass message */ SDLTest_AssertsPassed++; - SDLTest_Log(SDLTEST_ASSERT_CHECK_FORMAT, logMessage, "Pass"); + SDLTest_Log(SDLTEST_ASSERT_CHECK_FORMAT, logMessage, "Passed"); } /* @@ -122,13 +119,10 @@ void SDLTest_ResetAssertSummary() */ void SDLTest_LogAssertSummary() { - Uint32 totalAsserts = SDLTest_AssertsPassed + SDLTest_AssertsFailed; - if (SDLTest_AssertsFailed == 0) - { + int totalAsserts = SDLTest_AssertsPassed + SDLTest_AssertsFailed; + if (SDLTest_AssertsFailed == 0) { SDLTest_Log(SDLTEST_ASSERT_SUMMARY_FORMAT, totalAsserts, SDLTest_AssertsPassed, SDLTest_AssertsFailed); - } - else - { + } else { SDLTest_LogError(SDLTEST_ASSERT_SUMMARY_FORMAT, totalAsserts, SDLTest_AssertsPassed, SDLTest_AssertsFailed); } } diff --git a/SDL2-2.0.12/src/test/SDL_test_common.c b/SDL2-2.30.5/src/test/SDL_test_common.c similarity index 61% rename from SDL2-2.0.12/src/test/SDL_test_common.c rename to SDL2-2.30.5/src/test/SDL_test_common.c index b48c6a5..04ad51f 100644 --- a/SDL2-2.0.12/src/test/SDL_test_common.c +++ b/SDL2-2.30.5/src/test/SDL_test_common.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -28,14 +28,17 @@ static const char *video_usage[] = { "[--video driver]", "[--renderer driver]", "[--gldebug]", - "[--info all|video|modes|render|event]", + "[--info all|video|modes|render|event|event_motion]", "[--log all|error|system|audio|video|render|input]", "[--display N]", + "[--metal-window | --opengl-window | --vulkan-window]", "[--fullscreen | --fullscreen-desktop | --windows N]", "[--title title]", "[--icon icon.bmp]", "[--center | --position X,Y]", "[--geometry WxH]", "[--min-geometry WxH]", "[--max-geometry WxH]", "[--logical WxH]", "[--scale N]", "[--depth N]", "[--refresh R]", "[--vsync]", "[--noframe]", - "[--resize]", "[--minimize]", "[--maximize]", "[--grab]", - "[--allow-highdpi]", "[--usable-bounds]" + "[--resizable]", "[--minimize]", "[--maximize]", "[--grab]", "[--keyboard-grab]", + "[--shown]", "[--hidden]", "[--input-focus]", "[--mouse-focus]", + "[--flash-on-focus-loss]", "[--allow-highdpi]", "[--confine-cursor X,Y,W,H]", + "[--usable-bounds]" }; static const char *audio_usage[] = { @@ -43,7 +46,7 @@ static const char *audio_usage[] = { "[--channels N]", "[--samples N]" }; -static void SDL_snprintfcat(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, SDL_PRINTF_FORMAT_STRING const char *fmt, ... ) +static void SDL_snprintfcat(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) { size_t length = SDL_strlen(text); va_list ap; @@ -51,12 +54,11 @@ static void SDL_snprintfcat(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, SDL va_start(ap, fmt); text += length; maxlen -= length; - SDL_vsnprintf(text, maxlen, fmt, ap); + (void)SDL_vsnprintf(text, maxlen, fmt, ap); va_end(ap); } -SDLTest_CommonState * -SDLTest_CommonCreateState(char **argv, Uint32 flags) +SDLTest_CommonState *SDLTest_CommonCreateState(char **argv, Uint32 flags) { int i; SDLTest_CommonState *state; @@ -113,8 +115,16 @@ SDLTest_CommonCreateState(char **argv, Uint32 flags) return state; } -int -SDLTest_CommonArg(SDLTest_CommonState * state, int index) +#define SEARCHARG(dim) \ + while (*dim && *dim != ',') { \ + ++dim; \ + } \ + if (!*dim) { \ + return -1; \ + } \ + *dim++ = '\0'; + +int SDLTest_CommonArg(SDLTest_CommonState *state, int index) { char **argv = state->argv; @@ -124,6 +134,7 @@ SDLTest_CommonArg(SDLTest_CommonState * state, int index) return -1; } state->videodriver = argv[index]; + SDL_SetHint(SDL_HINT_VIDEODRIVER, state->videodriver); return 2; } if (SDL_strcasecmp(argv[index], "--renderer") == 0) { @@ -165,6 +176,10 @@ SDLTest_CommonArg(SDLTest_CommonState * state, int index) state->verbose |= VERBOSE_EVENT; return 2; } + if (SDL_strcasecmp(argv[index], "event_motion") == 0) { + state->verbose |= (VERBOSE_EVENT | VERBOSE_MOTION); + return 2; + } return -1; } if (SDL_strcasecmp(argv[index], "--log") == 0) { @@ -218,6 +233,18 @@ SDLTest_CommonArg(SDLTest_CommonState * state, int index) } return 2; } + if (SDL_strcasecmp(argv[index], "--metal-window") == 0) { + state->window_flags |= SDL_WINDOW_METAL; + return 1; + } + if (SDL_strcasecmp(argv[index], "--opengl-window") == 0) { + state->window_flags |= SDL_WINDOW_OPENGL; + return 1; + } + if (SDL_strcasecmp(argv[index], "--vulkan-window") == 0) { + state->window_flags |= SDL_WINDOW_VULKAN; + return 1; + } if (SDL_strcasecmp(argv[index], "--fullscreen") == 0) { state->window_flags |= SDL_WINDOW_FULLSCREEN; state->num_windows = 1; @@ -234,7 +261,7 @@ SDLTest_CommonArg(SDLTest_CommonState * state, int index) } if (SDL_strcasecmp(argv[index], "--windows") == 0) { ++index; - if (!argv[index] || !SDL_isdigit(*argv[index])) { + if (!argv[index] || !SDL_isdigit((unsigned char)*argv[index])) { return -1; } if (!(state->window_flags & SDL_WINDOW_FULLSCREEN)) { @@ -282,6 +309,25 @@ SDLTest_CommonArg(SDLTest_CommonState * state, int index) state->window_y = SDL_atoi(y); return 2; } + if (SDL_strcasecmp(argv[index], "--confine-cursor") == 0) { + char *x, *y, *w, *h; + ++index; + if (!argv[index]) { + return -1; + } + x = argv[index]; + y = argv[index]; + SEARCHARG(y) + w = y; + SEARCHARG(w) + h = w; + SEARCHARG(h) + state->confine.x = SDL_atoi(x); + state->confine.y = SDL_atoi(y); + state->confine.w = SDL_atoi(w); + state->confine.h = SDL_atoi(h); + return 2; + } if (SDL_strcasecmp(argv[index], "--usable-bounds") == 0) { /* !!! FIXME: this is a bit of a hack, but I don't want to add a !!! FIXME: flag to the public structure in 2.0.x */ @@ -399,7 +445,7 @@ SDLTest_CommonArg(SDLTest_CommonState * state, int index) state->window_flags |= SDL_WINDOW_BORDERLESS; return 1; } - if (SDL_strcasecmp(argv[index], "--resize") == 0) { + if (SDL_strcasecmp(argv[index], "--resizable") == 0) { state->window_flags |= SDL_WINDOW_RESIZABLE; return 1; } @@ -411,8 +457,32 @@ SDLTest_CommonArg(SDLTest_CommonState * state, int index) state->window_flags |= SDL_WINDOW_MAXIMIZED; return 1; } + if (SDL_strcasecmp(argv[index], "--shown") == 0) { + state->window_flags |= SDL_WINDOW_SHOWN; + return 1; + } + if (SDL_strcasecmp(argv[index], "--hidden") == 0) { + state->window_flags |= SDL_WINDOW_HIDDEN; + return 1; + } + if (SDL_strcasecmp(argv[index], "--input-focus") == 0) { + state->window_flags |= SDL_WINDOW_INPUT_FOCUS; + return 1; + } + if (SDL_strcasecmp(argv[index], "--mouse-focus") == 0) { + state->window_flags |= SDL_WINDOW_MOUSE_FOCUS; + return 1; + } + if (SDL_strcasecmp(argv[index], "--flash-on-focus-loss") == 0) { + state->flash_on_focus_loss = SDL_TRUE; + return 1; + } if (SDL_strcasecmp(argv[index], "--grab") == 0) { - state->window_flags |= SDL_WINDOW_INPUT_GRABBED; + state->window_flags |= SDL_WINDOW_MOUSE_GRABBED; + return 1; + } + if (SDL_strcasecmp(argv[index], "--keyboard-grab") == 0) { + state->window_flags |= SDL_WINDOW_KEYBOARD_GRABBED; return 1; } if (SDL_strcasecmp(argv[index], "--rate") == 0) { @@ -467,7 +537,7 @@ SDLTest_CommonArg(SDLTest_CommonState * state, int index) if (!argv[index]) { return -1; } - state->audiospec.channels = (Uint8) SDL_atoi(argv[index]); + state->audiospec.channels = (Uint8)SDL_atoi(argv[index]); return 2; } if (SDL_strcasecmp(argv[index], "--samples") == 0) { @@ -475,27 +545,25 @@ SDLTest_CommonArg(SDLTest_CommonState * state, int index) if (!argv[index]) { return -1; } - state->audiospec.samples = (Uint16) SDL_atoi(argv[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)) { + if ((SDL_strcasecmp(argv[index], "-h") == 0) || (SDL_strcasecmp(argv[index], "--help") == 0)) { /* Print the usage message */ return -1; } if (SDL_strcmp(argv[index], "-NSDocumentRevisionsDebugMode") == 0) { - /* Debug flag sent by Xcode */ + /* Debug flag sent by Xcode */ return 2; } return 0; } -void -SDLTest_CommonLogUsage(SDLTest_CommonState * state, const char *argv0, const char **options) +void SDLTest_CommonLogUsage(SDLTest_CommonState *state, const char *argv0, const char **options) { int i; @@ -521,8 +589,7 @@ SDLTest_CommonLogUsage(SDLTest_CommonState * state, const char *argv0, const cha } } -static const char * -BuildCommonUsageString(char **pstr, const char **strlist, const int numitems, const char **strlist2, const int numitems2) +static const char *BuildCommonUsageString(char **pstr, const char **strlist, const int numitems, const char **strlist2, const int numitems2) { char *str = *pstr; if (!str) { @@ -536,19 +603,19 @@ BuildCommonUsageString(char **pstr, const char **strlist, const int numitems, co len += SDL_strlen(strlist2[i]) + 1; } } - str = (char *) SDL_calloc(1, len); + str = (char *)SDL_calloc(1, len); if (!str) { - return ""; /* oh well. */ + return ""; /* oh well. */ } SDL_strlcat(str, "[--trackmem] ", len); - for (i = 0; i < numitems-1; i++) { + for (i = 0; i < numitems - 1; i++) { SDL_strlcat(str, strlist[i], len); SDL_strlcat(str, " ", len); } SDL_strlcat(str, strlist[i], len); if (strlist2) { SDL_strlcat(str, " ", len); - for (i = 0; i < numitems2-1; i++) { + for (i = 0; i < numitems2 - 1; i++) { SDL_strlcat(str, strlist2[i], len); SDL_strlcat(str, " ", len); } @@ -563,25 +630,22 @@ static char *common_usage_video = NULL; static char *common_usage_audio = NULL; static char *common_usage_videoaudio = NULL; -const char * -SDLTest_CommonUsage(SDLTest_CommonState * state) +const char *SDLTest_CommonUsage(SDLTest_CommonState *state) { switch (state->flags & (SDL_INIT_VIDEO | SDL_INIT_AUDIO)) { - case SDL_INIT_VIDEO: - return BuildCommonUsageString(&common_usage_video, video_usage, SDL_arraysize(video_usage), NULL, 0); - case SDL_INIT_AUDIO: - return BuildCommonUsageString(&common_usage_audio, audio_usage, SDL_arraysize(audio_usage), NULL, 0); - case (SDL_INIT_VIDEO | SDL_INIT_AUDIO): - return BuildCommonUsageString(&common_usage_videoaudio, video_usage, SDL_arraysize(video_usage), audio_usage, SDL_arraysize(audio_usage)); - default: - return "[--trackmem]"; + case SDL_INIT_VIDEO: + return BuildCommonUsageString(&common_usage_video, video_usage, SDL_arraysize(video_usage), NULL, 0); + case SDL_INIT_AUDIO: + return BuildCommonUsageString(&common_usage_audio, audio_usage, SDL_arraysize(audio_usage), NULL, 0); + case (SDL_INIT_VIDEO | SDL_INIT_AUDIO): + return BuildCommonUsageString(&common_usage_videoaudio, video_usage, SDL_arraysize(video_usage), audio_usage, SDL_arraysize(audio_usage)); + default: + return "[--trackmem]"; } } - -SDL_bool -SDLTest_CommonDefaultArgs(SDLTest_CommonState *state, const int argc, char **argv) +SDL_bool SDLTest_CommonDefaultArgs(SDLTest_CommonState *state, const int argc, char **argv) { int i = 1; while (i < argc) { @@ -595,8 +659,243 @@ SDLTest_CommonDefaultArgs(SDLTest_CommonState *state, const int argc, char **arg return SDL_TRUE; } -static void -SDLTest_PrintRendererFlag(char *text, size_t maxlen, Uint32 flag) +static void SDLTest_PrintDisplayOrientation(char *text, size_t maxlen, SDL_DisplayOrientation orientation) +{ + switch (orientation) { + case SDL_ORIENTATION_UNKNOWN: + SDL_snprintfcat(text, maxlen, "UNKNOWN"); + break; + case SDL_ORIENTATION_LANDSCAPE: + SDL_snprintfcat(text, maxlen, "LANDSCAPE"); + break; + case SDL_ORIENTATION_LANDSCAPE_FLIPPED: + SDL_snprintfcat(text, maxlen, "LANDSCAPE_FLIPPED"); + break; + case SDL_ORIENTATION_PORTRAIT: + SDL_snprintfcat(text, maxlen, "PORTRAIT"); + break; + case SDL_ORIENTATION_PORTRAIT_FLIPPED: + SDL_snprintfcat(text, maxlen, "PORTRAIT_FLIPPED"); + break; + default: + SDL_snprintfcat(text, maxlen, "0x%8.8x", orientation); + break; + } +} + +static void SDLTest_PrintWindowFlag(char *text, size_t maxlen, Uint32 flag) +{ + switch (flag) { + case SDL_WINDOW_FULLSCREEN: + SDL_snprintfcat(text, maxlen, "FULLSCREEN"); + break; + case SDL_WINDOW_OPENGL: + SDL_snprintfcat(text, maxlen, "OPENGL"); + break; + case SDL_WINDOW_SHOWN: + SDL_snprintfcat(text, maxlen, "SHOWN"); + break; + case SDL_WINDOW_HIDDEN: + SDL_snprintfcat(text, maxlen, "HIDDEN"); + break; + case SDL_WINDOW_BORDERLESS: + SDL_snprintfcat(text, maxlen, "BORDERLESS"); + break; + case SDL_WINDOW_RESIZABLE: + SDL_snprintfcat(text, maxlen, "RESIZABLE"); + break; + case SDL_WINDOW_MINIMIZED: + SDL_snprintfcat(text, maxlen, "MINIMIZED"); + break; + case SDL_WINDOW_MAXIMIZED: + SDL_snprintfcat(text, maxlen, "MAXIMIZED"); + break; + case SDL_WINDOW_MOUSE_GRABBED: + SDL_snprintfcat(text, maxlen, "MOUSE_GRABBED"); + break; + case SDL_WINDOW_INPUT_FOCUS: + SDL_snprintfcat(text, maxlen, "INPUT_FOCUS"); + break; + case SDL_WINDOW_MOUSE_FOCUS: + SDL_snprintfcat(text, maxlen, "MOUSE_FOCUS"); + break; + case SDL_WINDOW_FULLSCREEN_DESKTOP: + SDL_snprintfcat(text, maxlen, "FULLSCREEN_DESKTOP"); + break; + case SDL_WINDOW_FOREIGN: + SDL_snprintfcat(text, maxlen, "FOREIGN"); + break; + case SDL_WINDOW_ALLOW_HIGHDPI: + SDL_snprintfcat(text, maxlen, "ALLOW_HIGHDPI"); + break; + case SDL_WINDOW_MOUSE_CAPTURE: + SDL_snprintfcat(text, maxlen, "MOUSE_CAPTURE"); + break; + case SDL_WINDOW_ALWAYS_ON_TOP: + SDL_snprintfcat(text, maxlen, "ALWAYS_ON_TOP"); + break; + case SDL_WINDOW_SKIP_TASKBAR: + SDL_snprintfcat(text, maxlen, "SKIP_TASKBAR"); + break; + case SDL_WINDOW_UTILITY: + SDL_snprintfcat(text, maxlen, "UTILITY"); + break; + case SDL_WINDOW_TOOLTIP: + SDL_snprintfcat(text, maxlen, "TOOLTIP"); + break; + case SDL_WINDOW_POPUP_MENU: + SDL_snprintfcat(text, maxlen, "POPUP_MENU"); + break; + case SDL_WINDOW_KEYBOARD_GRABBED: + SDL_snprintfcat(text, maxlen, "KEYBOARD_GRABBED"); + break; + case SDL_WINDOW_VULKAN: + SDL_snprintfcat(text, maxlen, "VULKAN"); + break; + case SDL_WINDOW_METAL: + SDL_snprintfcat(text, maxlen, "METAL"); + break; + default: + SDL_snprintfcat(text, maxlen, "0x%8.8x", flag); + break; + } +} + +static void SDLTest_PrintWindowFlags(char *text, size_t maxlen, Uint32 flags) +{ + const Uint32 window_flags[] = { + SDL_WINDOW_FULLSCREEN, + SDL_WINDOW_OPENGL, + SDL_WINDOW_SHOWN, + SDL_WINDOW_HIDDEN, + SDL_WINDOW_BORDERLESS, + SDL_WINDOW_RESIZABLE, + SDL_WINDOW_MINIMIZED, + SDL_WINDOW_MAXIMIZED, + SDL_WINDOW_MOUSE_GRABBED, + SDL_WINDOW_INPUT_FOCUS, + SDL_WINDOW_MOUSE_FOCUS, + SDL_WINDOW_FULLSCREEN_DESKTOP, + SDL_WINDOW_FOREIGN, + SDL_WINDOW_ALLOW_HIGHDPI, + SDL_WINDOW_MOUSE_CAPTURE, + SDL_WINDOW_ALWAYS_ON_TOP, + SDL_WINDOW_SKIP_TASKBAR, + SDL_WINDOW_UTILITY, + SDL_WINDOW_TOOLTIP, + SDL_WINDOW_POPUP_MENU, + SDL_WINDOW_KEYBOARD_GRABBED, + SDL_WINDOW_VULKAN, + SDL_WINDOW_METAL + }; + + int i; + int count = 0; + for (i = 0; i < (sizeof(window_flags) / sizeof(window_flags[0])); ++i) { + const Uint32 flag = window_flags[i]; + if ((flags & flag) == flag) { + if (count > 0) { + SDL_snprintfcat(text, maxlen, " | "); + } + SDLTest_PrintWindowFlag(text, maxlen, flag); + ++count; + } + } +} + +static void SDLTest_PrintModStateFlag(char *text, size_t maxlen, SDL_Keymod flag) +{ + switch (flag) { + case KMOD_LSHIFT: + SDL_snprintfcat(text, maxlen, "LSHIFT"); + break; + case KMOD_RSHIFT: + SDL_snprintfcat(text, maxlen, "RSHIFT"); + break; + case KMOD_LCTRL: + SDL_snprintfcat(text, maxlen, "LCTRL"); + break; + case KMOD_RCTRL: + SDL_snprintfcat(text, maxlen, "RCTRL"); + break; + case KMOD_LALT: + SDL_snprintfcat(text, maxlen, "LALT"); + break; + case KMOD_RALT: + SDL_snprintfcat(text, maxlen, "RALT"); + break; + case KMOD_LGUI: + SDL_snprintfcat(text, maxlen, "LGUI"); + break; + case KMOD_RGUI: + SDL_snprintfcat(text, maxlen, "RGUI"); + break; + case KMOD_NUM: + SDL_snprintfcat(text, maxlen, "NUM"); + break; + case KMOD_CAPS: + SDL_snprintfcat(text, maxlen, "CAPS"); + break; + case KMOD_MODE: + SDL_snprintfcat(text, maxlen, "MODE"); + break; + case KMOD_SCROLL: + SDL_snprintfcat(text, maxlen, "SCROLL"); + break; + default: + SDL_snprintfcat(text, maxlen, "0x%8.8x", (unsigned int) flag); + break; + } +} + +static void SDLTest_PrintModState(char *text, size_t maxlen, SDL_Keymod keymod) +{ + const SDL_Keymod kmod_flags[] = { + KMOD_LSHIFT, + KMOD_RSHIFT, + KMOD_LCTRL, + KMOD_RCTRL, + KMOD_LALT, + KMOD_RALT, + KMOD_LGUI, + KMOD_RGUI, + KMOD_NUM, + KMOD_CAPS, + KMOD_MODE, + KMOD_SCROLL + }; + + int i; + int count = 0; + for (i = 0; i < SDL_arraysize(kmod_flags); ++i) { + const SDL_Keymod flag = kmod_flags[i]; + if ((keymod & flag) == flag) { + if (count > 0) { + SDL_snprintfcat(text, maxlen, " | "); + } + SDLTest_PrintModStateFlag(text, maxlen, flag); + ++count; + } + } +} + +static void SDLTest_PrintButtonMask(char *text, size_t maxlen, Uint32 flags) +{ + int i; + int count = 0; + for (i = 1; i <= 32; ++i) { + const Uint32 flag = SDL_BUTTON(i); + if ((flags & flag) == flag) { + if (count > 0) { + SDL_snprintfcat(text, maxlen, " | "); + } + SDL_snprintfcat(text, maxlen, "SDL_BUTTON(%d)", i); + ++count; + } + } +} + +static void SDLTest_PrintRendererFlag(char *text, size_t maxlen, Uint32 flag) { switch (flag) { case SDL_RENDERER_SOFTWARE: @@ -617,8 +916,7 @@ SDLTest_PrintRendererFlag(char *text, size_t maxlen, Uint32 flag) } } -static void -SDLTest_PrintPixelFormat(char *text, size_t maxlen, Uint32 format) +static void SDLTest_PrintPixelFormat(char *text, size_t maxlen, Uint32 format) { switch (format) { case SDL_PIXELFORMAT_UNKNOWN: @@ -630,6 +928,12 @@ SDLTest_PrintPixelFormat(char *text, size_t maxlen, Uint32 format) case SDL_PIXELFORMAT_INDEX1MSB: SDL_snprintfcat(text, maxlen, "Index1MSB"); break; + case SDL_PIXELFORMAT_INDEX2LSB: + SDL_snprintfcat(text, maxlen, "Index2LSB"); + break; + case SDL_PIXELFORMAT_INDEX2MSB: + SDL_snprintfcat(text, maxlen, "Index2MSB"); + break; case SDL_PIXELFORMAT_INDEX4LSB: SDL_snprintfcat(text, maxlen, "Index4LSB"); break; @@ -726,18 +1030,17 @@ SDLTest_PrintPixelFormat(char *text, size_t maxlen, Uint32 format) } } -static void -SDLTest_PrintRenderer(SDL_RendererInfo * info) +static void SDLTest_PrintRenderer(SDL_RendererInfo *info) { int i, count; char text[1024]; SDL_Log(" Renderer %s:\n", info->name); - SDL_snprintf(text, sizeof(text), " Flags: 0x%8.8X", info->flags); + (void)SDL_snprintf(text, sizeof(text), " Flags: 0x%8.8" SDL_PRIX32, info->flags); SDL_snprintfcat(text, sizeof(text), " ("); count = 0; - for (i = 0; i < sizeof(info->flags) * 8; ++i) { + for (i = 0; i < 8 * sizeof(info->flags); ++i) { Uint32 flag = (1 << i); if (info->flags & flag) { if (count > 0) { @@ -750,8 +1053,8 @@ SDLTest_PrintRenderer(SDL_RendererInfo * info) SDL_snprintfcat(text, sizeof(text), ")"); SDL_Log("%s\n", text); - SDL_snprintf(text, sizeof(text), " Texture formats (%d): ", info->num_texture_formats); - for (i = 0; i < (int) info->num_texture_formats; ++i) { + (void)SDL_snprintf(text, sizeof(text), " Texture formats (%" SDL_PRIu32 "): ", info->num_texture_formats); + for (i = 0; i < (int)info->num_texture_formats; ++i) { if (i > 0) { SDL_snprintfcat(text, sizeof(text), ", "); } @@ -765,28 +1068,26 @@ SDLTest_PrintRenderer(SDL_RendererInfo * info) } } -static SDL_Surface * -SDLTest_LoadIcon(const char *file) +static SDL_Surface *SDLTest_LoadIcon(const char *file) { SDL_Surface *icon; /* Load the icon surface */ icon = SDL_LoadBMP(file); - if (icon == NULL) { + if (!icon) { SDL_Log("Couldn't load %s: %s\n", file, SDL_GetError()); - return (NULL); + return NULL; } if (icon->format->palette) { /* Set the colorkey */ - SDL_SetColorKey(icon, 1, *((Uint8 *) icon->pixels)); + SDL_SetColorKey(icon, 1, *((Uint8 *)icon->pixels)); } - return (icon); + return icon; } -static SDL_HitTestResult SDLCALL -SDLTest_ExampleHitTestCallback(SDL_Window *win, const SDL_Point *area, void *data) +static SDL_HitTestResult SDLCALL SDLTest_ExampleHitTestCallback(SDL_Window *win, const SDL_Point *area, void *data) { int w, h; const int RESIZE_BORDER = 8; @@ -800,25 +1101,25 @@ SDLTest_ExampleHitTestCallback(SDL_Window *win, const SDL_Point *area, void *dat if (area->y < RESIZE_BORDER) { SDL_Log("SDL_HITTEST_RESIZE_TOPLEFT\n"); return SDL_HITTEST_RESIZE_TOPLEFT; - } else if (area->y >= (h-RESIZE_BORDER)) { + } 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)) { + } 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)) { + } 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)) { + } 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) { @@ -831,8 +1132,7 @@ SDLTest_ExampleHitTestCallback(SDL_Window *win, const SDL_Point *area, void *dat return SDL_HITTEST_NORMAL; } -SDL_bool -SDLTest_CommonInit(SDLTest_CommonState * state) +SDL_bool SDLTest_CommonInit(SDLTest_CommonState *state) { int i, j, m, n, w, h; SDL_DisplayMode fullscreen_mode; @@ -844,7 +1144,7 @@ SDLTest_CommonInit(SDLTest_CommonState * state) if (n == 0) { SDL_Log("No built-in video drivers\n"); } else { - SDL_snprintf(text, sizeof(text), "Built-in video drivers:"); + (void)SDL_snprintf(text, sizeof(text), "Built-in video drivers:"); for (i = 0; i < n; ++i) { if (i > 0) { SDL_snprintfcat(text, sizeof(text), ","); @@ -903,7 +1203,7 @@ SDLTest_CommonInit(SDLTest_CommonState * state) SDL_DisplayMode mode; int bpp; Uint32 Rmask, Gmask, Bmask, Amask; -#if SDL_VIDEO_DRIVER_WINDOWS +#ifdef SDL_VIDEO_DRIVER_WINDOWS int adapterIndex = 0; int outputIndex = 0; #endif @@ -931,11 +1231,12 @@ SDLTest_CommonInit(SDLTest_CommonState * state) mode.w, mode.h, mode.refresh_rate, bpp, SDL_GetPixelFormatName(mode.format)); if (Rmask || Gmask || Bmask) { - SDL_Log(" Red Mask = 0x%.8x\n", Rmask); - SDL_Log(" Green Mask = 0x%.8x\n", Gmask); - SDL_Log(" Blue Mask = 0x%.8x\n", Bmask); - if (Amask) - SDL_Log(" Alpha Mask = 0x%.8x\n", Amask); + SDL_Log(" Red Mask = 0x%.8" SDL_PRIx32 "\n", Rmask); + SDL_Log(" Green Mask = 0x%.8" SDL_PRIx32 "\n", Gmask); + SDL_Log(" Blue Mask = 0x%.8" SDL_PRIx32 "\n", Bmask); + if (Amask) { + SDL_Log(" Alpha Mask = 0x%.8" SDL_PRIx32 "\n", Amask); + } } /* Print available fullscreen video modes */ @@ -952,22 +1253,22 @@ SDLTest_CommonInit(SDLTest_CommonState * state) j, mode.w, mode.h, mode.refresh_rate, bpp, SDL_GetPixelFormatName(mode.format)); if (Rmask || Gmask || Bmask) { - SDL_Log(" Red Mask = 0x%.8x\n", + SDL_Log(" Red Mask = 0x%.8" SDL_PRIx32 "\n", Rmask); - SDL_Log(" Green Mask = 0x%.8x\n", + SDL_Log(" Green Mask = 0x%.8" SDL_PRIx32 "\n", Gmask); - SDL_Log(" Blue Mask = 0x%.8x\n", + SDL_Log(" Blue Mask = 0x%.8" SDL_PRIx32 "\n", Bmask); - if (Amask) - SDL_Log(" Alpha Mask = 0x%.8x\n", - Amask); + if (Amask) { + SDL_Log(" Alpha Mask = 0x%.8" SDL_PRIx32 "\n", Amask); + } } } } -#if SDL_VIDEO_DRIVER_WINDOWS +#if defined(SDL_VIDEO_DRIVER_WINDOWS) && !defined(__XBOXONE__) && !defined(__XBOXSERIES__) /* Print the D3D9 adapter index */ - adapterIndex = SDL_Direct3D9GetAdapterIndex( i ); + adapterIndex = SDL_Direct3D9GetAdapterIndex(i); SDL_Log("D3D9 Adapter Index: %d", adapterIndex); /* Print the DXGI adapter and output indices */ @@ -1013,24 +1314,26 @@ SDLTest_CommonInit(SDLTest_CommonState * state) fullscreen_mode.refresh_rate = state->refresh_rate; state->windows = - (SDL_Window **) SDL_calloc(state->num_windows, - sizeof(*state->windows)); + (SDL_Window **)SDL_calloc(state->num_windows, + sizeof(*state->windows)); state->renderers = - (SDL_Renderer **) SDL_calloc(state->num_windows, + (SDL_Renderer **)SDL_calloc(state->num_windows, sizeof(*state->renderers)); state->targets = - (SDL_Texture **) SDL_calloc(state->num_windows, - sizeof(*state->targets)); + (SDL_Texture **)SDL_calloc(state->num_windows, + sizeof(*state->targets)); if (!state->windows || !state->renderers) { SDL_Log("Out of memory!\n"); return SDL_FALSE; } for (i = 0; i < state->num_windows; ++i) { char title[1024]; - SDL_Rect r = { - state->window_x, state->window_y, - state->window_w, state->window_h - }; + SDL_Rect r; + + r.x = state->window_x; + r.y = state->window_y; + r.w = state->window_w; + r.h = state->window_h; /* !!! FIXME: hack to make --usable-bounds work for now. */ if ((r.x == -1) && (r.y == -1) && (r.w == -1) && (r.h == -1)) { @@ -1038,8 +1341,8 @@ SDLTest_CommonInit(SDLTest_CommonState * state) } if (state->num_windows > 1) { - SDL_snprintf(title, SDL_arraysize(title), "%s %d", - state->window_title, i + 1); + (void)SDL_snprintf(title, SDL_arraysize(title), "%s %d", + state->window_title, i + 1); } else { SDL_strlcpy(title, state->window_title, SDL_arraysize(title)); } @@ -1059,10 +1362,12 @@ SDLTest_CommonInit(SDLTest_CommonState * state) SDL_GetWindowSize(state->windows[i], &w, &h); if (!(state->window_flags & SDL_WINDOW_RESIZABLE) && (w != state->window_w || h != state->window_h)) { - printf("Window requested size %dx%d, got %dx%d\n", state->window_w, state->window_h, w, h); + SDL_Log("Window requested size %dx%d, got %dx%d\n", state->window_w, state->window_h, w, h); state->window_w = w; state->window_h = h; } + fullscreen_mode.w = state->window_w; + fullscreen_mode.h = state->window_h; if (SDL_SetWindowDisplayMode(state->windows[i], &fullscreen_mode) < 0) { SDL_Log("Can't set up fullscreen display mode: %s\n", SDL_GetError()); @@ -1070,8 +1375,8 @@ 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)) == - (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); } @@ -1085,17 +1390,18 @@ SDLTest_CommonInit(SDLTest_CommonState * state) SDL_ShowWindow(state->windows[i]); - if (!state->skip_renderer - && (state->renderdriver - || !(state->window_flags & (SDL_WINDOW_OPENGL | SDL_WINDOW_VULKAN)))) { + if (!SDL_RectEmpty(&state->confine)) { + SDL_SetWindowMouseRect(state->windows[i], &state->confine); + } + + if (!state->skip_renderer && (state->renderdriver || !(state->window_flags & (SDL_WINDOW_OPENGL | SDL_WINDOW_VULKAN | SDL_WINDOW_METAL)))) { m = -1; if (state->renderdriver) { SDL_RendererInfo info; n = SDL_GetNumRenderDrivers(); for (j = 0; j < n; ++j) { SDL_GetRenderDriverInfo(j, &info); - if (SDL_strcasecmp(info.name, state->renderdriver) == - 0) { + if (SDL_strcasecmp(info.name, state->renderdriver) == 0) { m = j; break; } @@ -1107,7 +1413,7 @@ SDLTest_CommonInit(SDLTest_CommonState * state) } } state->renderers[i] = SDL_CreateRenderer(state->windows[i], - m, state->render_flags); + m, state->render_flags); if (!state->renderers[i]) { SDL_Log("Couldn't create renderer: %s\n", SDL_GetError()); @@ -1135,7 +1441,7 @@ SDLTest_CommonInit(SDLTest_CommonState * state) if (n == 0) { SDL_Log("No built-in audio drivers\n"); } else { - SDL_snprintf(text, sizeof(text), "Built-in audio drivers:"); + (void)SDL_snprintf(text, sizeof(text), "Built-in audio drivers:"); for (i = 0; i < n; ++i) { if (i > 0) { SDL_snprintfcat(text, sizeof(text), ","); @@ -1164,28 +1470,29 @@ SDLTest_CommonInit(SDLTest_CommonState * state) return SDL_TRUE; } -static const char * -DisplayOrientationName(int orientation) +static const char *DisplayOrientationName(int orientation) { - switch (orientation) - { -#define CASE(X) case SDL_ORIENTATION_##X: return #X + switch (orientation) { +#define CASE(X) \ + case SDL_ORIENTATION_##X: \ + return #X CASE(UNKNOWN); CASE(LANDSCAPE); CASE(LANDSCAPE_FLIPPED); CASE(PORTRAIT); CASE(PORTRAIT_FLIPPED); #undef CASE -default: return "???"; + default: + return "???"; } } -static const char * -ControllerAxisName(const SDL_GameControllerAxis axis) +static const char *ControllerAxisName(const SDL_GameControllerAxis axis) { - switch (axis) - { -#define AXIS_CASE(ax) case SDL_CONTROLLER_AXIS_##ax: return #ax + switch (axis) { +#define AXIS_CASE(ax) \ + case SDL_CONTROLLER_AXIS_##ax: \ + return #ax AXIS_CASE(INVALID); AXIS_CASE(LEFTX); AXIS_CASE(LEFTY); @@ -1194,16 +1501,17 @@ ControllerAxisName(const SDL_GameControllerAxis axis) AXIS_CASE(TRIGGERLEFT); AXIS_CASE(TRIGGERRIGHT); #undef AXIS_CASE -default: return "???"; + default: + return "???"; } } -static const char * -ControllerButtonName(const SDL_GameControllerButton button) +static const char *ControllerButtonName(const SDL_GameControllerButton button) { - switch (button) - { -#define BUTTON_CASE(btn) case SDL_CONTROLLER_BUTTON_##btn: return #btn + switch (button) { +#define BUTTON_CASE(btn) \ + case SDL_CONTROLLER_BUTTON_##btn: \ + return #btn BUTTON_CASE(INVALID); BUTTON_CASE(A); BUTTON_CASE(B); @@ -1221,26 +1529,34 @@ ControllerButtonName(const SDL_GameControllerButton button) BUTTON_CASE(DPAD_LEFT); BUTTON_CASE(DPAD_RIGHT); #undef BUTTON_CASE -default: return "???"; + default: + return "???"; } } -static void -SDLTest_PrintEvent(SDL_Event * event) +static void SDLTest_PrintEvent(SDL_Event *event) { - if ((event->type == SDL_MOUSEMOTION) || (event->type == SDL_FINGERMOTION)) { - /* Mouse and finger motion are really spammy */ - return; - } - switch (event->type) { case SDL_DISPLAYEVENT: switch (event->display.event) { + case SDL_DISPLAYEVENT_CONNECTED: + SDL_Log("SDL EVENT: Display %" SDL_PRIu32 " connected", + event->display.display); + break; + case SDL_DISPLAYEVENT_MOVED: + SDL_Log("SDL EVENT: Display %" SDL_PRIu32 " changed position", + event->display.display); + break; case SDL_DISPLAYEVENT_ORIENTATION: - SDL_Log("SDL EVENT: Display %d changed orientation to %s", event->display.display, DisplayOrientationName(event->display.data1)); + SDL_Log("SDL EVENT: Display %" SDL_PRIu32 " changed orientation to %s", + event->display.display, DisplayOrientationName(event->display.data1)); + break; + case SDL_DISPLAYEVENT_DISCONNECTED: + SDL_Log("SDL EVENT: Display %" SDL_PRIu32 " disconnected", + event->display.display); break; default: - SDL_Log("SDL EVENT: Display %d got unknown event 0x%4.4x", + SDL_Log("SDL EVENT: Display %" SDL_PRIu32 " got unknown event 0x%4.4x", event->display.display, event->display.event); break; } @@ -1248,194 +1564,199 @@ SDLTest_PrintEvent(SDL_Event * event) case SDL_WINDOWEVENT: switch (event->window.event) { case SDL_WINDOWEVENT_SHOWN: - SDL_Log("SDL EVENT: Window %d shown", event->window.windowID); + SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " shown", event->window.windowID); break; case SDL_WINDOWEVENT_HIDDEN: - SDL_Log("SDL EVENT: Window %d hidden", event->window.windowID); + SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " hidden", event->window.windowID); break; case SDL_WINDOWEVENT_EXPOSED: - SDL_Log("SDL EVENT: Window %d exposed", event->window.windowID); + SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " exposed", event->window.windowID); break; case SDL_WINDOWEVENT_MOVED: - SDL_Log("SDL EVENT: Window %d moved to %d,%d", - event->window.windowID, event->window.data1, - event->window.data2); + SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " moved to %" SDL_PRIs32 ",%" SDL_PRIs32, + event->window.windowID, event->window.data1, event->window.data2); break; case SDL_WINDOWEVENT_RESIZED: - SDL_Log("SDL EVENT: Window %d resized to %dx%d", - event->window.windowID, event->window.data1, - event->window.data2); + SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " resized to %" SDL_PRIs32 "x%" SDL_PRIs32, + event->window.windowID, event->window.data1, event->window.data2); break; case SDL_WINDOWEVENT_SIZE_CHANGED: - SDL_Log("SDL EVENT: Window %d changed size to %dx%d", - event->window.windowID, event->window.data1, - event->window.data2); + SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " changed size to %" SDL_PRIs32 "x%" SDL_PRIs32, + event->window.windowID, event->window.data1, event->window.data2); break; case SDL_WINDOWEVENT_MINIMIZED: - SDL_Log("SDL EVENT: Window %d minimized", event->window.windowID); + SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " minimized", event->window.windowID); break; case SDL_WINDOWEVENT_MAXIMIZED: - SDL_Log("SDL EVENT: Window %d maximized", event->window.windowID); + SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " maximized", event->window.windowID); break; case SDL_WINDOWEVENT_RESTORED: - SDL_Log("SDL EVENT: Window %d restored", event->window.windowID); + SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " restored", event->window.windowID); break; case SDL_WINDOWEVENT_ENTER: - SDL_Log("SDL EVENT: Mouse entered window %d", - event->window.windowID); + SDL_Log("SDL EVENT: Mouse entered window %" SDL_PRIu32, event->window.windowID); break; case SDL_WINDOWEVENT_LEAVE: - SDL_Log("SDL EVENT: Mouse left window %d", event->window.windowID); + SDL_Log("SDL EVENT: Mouse left window %" SDL_PRIu32, event->window.windowID); break; case SDL_WINDOWEVENT_FOCUS_GAINED: - SDL_Log("SDL EVENT: Window %d gained keyboard focus", + SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " gained keyboard focus", event->window.windowID); break; case SDL_WINDOWEVENT_FOCUS_LOST: - SDL_Log("SDL EVENT: Window %d lost keyboard focus", + SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " lost keyboard focus", event->window.windowID); break; case SDL_WINDOWEVENT_CLOSE: - SDL_Log("SDL EVENT: Window %d closed", event->window.windowID); + SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " closed", event->window.windowID); break; case SDL_WINDOWEVENT_TAKE_FOCUS: - SDL_Log("SDL EVENT: Window %d take focus", event->window.windowID); + SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " take focus", event->window.windowID); break; case SDL_WINDOWEVENT_HIT_TEST: - SDL_Log("SDL EVENT: Window %d hit test", event->window.windowID); + SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " hit test", event->window.windowID); + break; + case SDL_WINDOWEVENT_ICCPROF_CHANGED: + SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " ICC profile changed", event->window.windowID); + break; + case SDL_WINDOWEVENT_DISPLAY_CHANGED: + SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " display changed to %" SDL_PRIs32, event->window.windowID, event->window.data1); break; default: - SDL_Log("SDL EVENT: Window %d got unknown event 0x%4.4x", + SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " got unknown event 0x%4.4x", event->window.windowID, event->window.event); break; } break; case SDL_KEYDOWN: - SDL_Log("SDL EVENT: Keyboard: key pressed in window %d: scancode 0x%08X = %s, keycode 0x%08X = %s", + case SDL_KEYUP: { + char modstr[64]; + if (event->key.keysym.mod) { + modstr[0] = '\0'; + SDLTest_PrintModState(modstr, sizeof (modstr), event->key.keysym.mod); + } else { + SDL_strlcpy(modstr, "NONE", sizeof (modstr)); + } + SDL_Log("SDL EVENT: Keyboard: key %s in window %" SDL_PRIu32 ": scancode 0x%08X = %s, keycode 0x%08" SDL_PRIX32 " = %s, mods = %s", + (event->type == SDL_KEYDOWN) ? "pressed" : "released", event->key.windowID, event->key.keysym.scancode, SDL_GetScancodeName(event->key.keysym.scancode), - event->key.keysym.sym, SDL_GetKeyName(event->key.keysym.sym)); - break; - case SDL_KEYUP: - SDL_Log("SDL EVENT: Keyboard: key released in window %d: scancode 0x%08X = %s, keycode 0x%08X = %s", - event->key.windowID, - event->key.keysym.scancode, - SDL_GetScancodeName(event->key.keysym.scancode), - event->key.keysym.sym, SDL_GetKeyName(event->key.keysym.sym)); + event->key.keysym.sym, SDL_GetKeyName(event->key.keysym.sym), + modstr); break; + } case SDL_TEXTEDITING: - SDL_Log("SDL EVENT: Keyboard: text editing \"%s\" in window %d", + SDL_Log("SDL EVENT: Keyboard: text editing \"%s\" in window %" SDL_PRIu32, event->edit.text, event->edit.windowID); break; case SDL_TEXTINPUT: - SDL_Log("SDL EVENT: Keyboard: text input \"%s\" in window %d", + SDL_Log("SDL EVENT: Keyboard: text input \"%s\" in window %" SDL_PRIu32, event->text.text, event->text.windowID); break; case SDL_KEYMAPCHANGED: SDL_Log("SDL EVENT: Keymap changed"); break; case SDL_MOUSEMOTION: - SDL_Log("SDL EVENT: Mouse: moved to %d,%d (%d,%d) in window %d", + SDL_Log("SDL EVENT: Mouse: moved to %" SDL_PRIs32 ",%" SDL_PRIs32 " (%" SDL_PRIs32 ",%" SDL_PRIs32 ") in window %" SDL_PRIu32, event->motion.x, event->motion.y, event->motion.xrel, event->motion.yrel, event->motion.windowID); break; case SDL_MOUSEBUTTONDOWN: - SDL_Log("SDL EVENT: Mouse: button %d pressed at %d,%d with click count %d in window %d", + SDL_Log("SDL EVENT: Mouse: button %d pressed at %" SDL_PRIs32 ",%" SDL_PRIs32 " with click count %d in window %" SDL_PRIu32, event->button.button, event->button.x, event->button.y, event->button.clicks, event->button.windowID); break; case SDL_MOUSEBUTTONUP: - SDL_Log("SDL EVENT: Mouse: button %d released at %d,%d with click count %d in window %d", + SDL_Log("SDL EVENT: Mouse: button %d released at %" SDL_PRIs32 ",%" SDL_PRIs32 " with click count %d in window %" SDL_PRIu32, event->button.button, event->button.x, event->button.y, event->button.clicks, event->button.windowID); break; case SDL_MOUSEWHEEL: - SDL_Log("SDL EVENT: Mouse: wheel scrolled %d in x and %d in y (reversed: %d) in window %d", + SDL_Log("SDL EVENT: Mouse: wheel scrolled %" SDL_PRIs32 " in x and %" SDL_PRIs32 " in y (reversed: %" SDL_PRIu32 ") in window %" SDL_PRIu32, event->wheel.x, event->wheel.y, event->wheel.direction, event->wheel.windowID); break; case SDL_JOYDEVICEADDED: - SDL_Log("SDL EVENT: Joystick index %d attached", - event->jdevice.which); + SDL_Log("SDL EVENT: Joystick index %" SDL_PRIs32 " attached", + event->jdevice.which); break; case SDL_JOYDEVICEREMOVED: - SDL_Log("SDL EVENT: Joystick %d removed", - event->jdevice.which); + SDL_Log("SDL EVENT: Joystick %" SDL_PRIs32 " removed", + event->jdevice.which); break; case SDL_JOYBALLMOTION: - SDL_Log("SDL EVENT: Joystick %d: ball %d moved by %d,%d", + SDL_Log("SDL EVENT: Joystick %" SDL_PRIs32 ": ball %d moved by %d,%d", event->jball.which, event->jball.ball, event->jball.xrel, event->jball.yrel); break; case SDL_JOYHATMOTION: - { - const char *position = "UNKNOWN"; - switch (event->jhat.value) { - case SDL_HAT_CENTERED: - position = "CENTER"; - break; - case SDL_HAT_UP: - position = "UP"; - break; - case SDL_HAT_RIGHTUP: - position = "RIGHTUP"; - break; - case SDL_HAT_RIGHT: - position = "RIGHT"; - break; - case SDL_HAT_RIGHTDOWN: - position = "RIGHTDOWN"; - break; - case SDL_HAT_DOWN: - position = "DOWN"; - break; - case SDL_HAT_LEFTDOWN: - position = "LEFTDOWN"; - break; - case SDL_HAT_LEFT: - position = "LEFT"; - break; - case SDL_HAT_LEFTUP: - position = "LEFTUP"; - break; - } - SDL_Log("SDL EVENT: Joystick %d: hat %d moved to %s", event->jhat.which, - event->jhat.hat, position); + { + const char *position = "UNKNOWN"; + switch (event->jhat.value) { + case SDL_HAT_CENTERED: + position = "CENTER"; + break; + case SDL_HAT_UP: + position = "UP"; + break; + case SDL_HAT_RIGHTUP: + position = "RIGHTUP"; + break; + case SDL_HAT_RIGHT: + position = "RIGHT"; + break; + case SDL_HAT_RIGHTDOWN: + position = "RIGHTDOWN"; + break; + case SDL_HAT_DOWN: + position = "DOWN"; + break; + case SDL_HAT_LEFTDOWN: + position = "LEFTDOWN"; + break; + case SDL_HAT_LEFT: + position = "LEFT"; + break; + case SDL_HAT_LEFTUP: + position = "LEFTUP"; + break; } - break; + SDL_Log("SDL EVENT: Joystick %" SDL_PRIs32 ": hat %d moved to %s", + event->jhat.which, event->jhat.hat, position); + } break; case SDL_JOYBUTTONDOWN: - SDL_Log("SDL EVENT: Joystick %d: button %d pressed", + SDL_Log("SDL EVENT: Joystick %" SDL_PRIs32 ": button %d pressed", event->jbutton.which, event->jbutton.button); break; case SDL_JOYBUTTONUP: - SDL_Log("SDL EVENT: Joystick %d: button %d released", + SDL_Log("SDL EVENT: Joystick %" SDL_PRIs32 ": button %d released", event->jbutton.which, event->jbutton.button); break; case SDL_CONTROLLERDEVICEADDED: - SDL_Log("SDL EVENT: Controller index %d attached", - event->cdevice.which); + SDL_Log("SDL EVENT: Controller index %" SDL_PRIs32 " attached", + event->cdevice.which); break; case SDL_CONTROLLERDEVICEREMOVED: - SDL_Log("SDL EVENT: Controller %d removed", - event->cdevice.which); + SDL_Log("SDL EVENT: Controller %" SDL_PRIs32 " removed", + event->cdevice.which); break; case SDL_CONTROLLERAXISMOTION: - SDL_Log("SDL EVENT: Controller %d axis %d ('%s') value: %d", - event->caxis.which, - event->caxis.axis, - ControllerAxisName((SDL_GameControllerAxis)event->caxis.axis), - event->caxis.value); + SDL_Log("SDL EVENT: Controller %" SDL_PRIs32 " axis %d ('%s') value: %d", + event->caxis.which, + event->caxis.axis, + ControllerAxisName((SDL_GameControllerAxis)event->caxis.axis), + event->caxis.value); break; case SDL_CONTROLLERBUTTONDOWN: - SDL_Log("SDL EVENT: Controller %d button %d ('%s') down", - event->cbutton.which, event->cbutton.button, - ControllerButtonName((SDL_GameControllerButton)event->cbutton.button)); + SDL_Log("SDL EVENT: Controller %" SDL_PRIs32 "button %d ('%s') down", + event->cbutton.which, event->cbutton.button, + ControllerButtonName((SDL_GameControllerButton)event->cbutton.button)); break; case SDL_CONTROLLERBUTTONUP: - SDL_Log("SDL EVENT: Controller %d button %d ('%s') up", - event->cbutton.which, event->cbutton.button, - ControllerButtonName((SDL_GameControllerButton)event->cbutton.button)); + SDL_Log("SDL EVENT: Controller %" SDL_PRIs32 " button %d ('%s') up", + event->cbutton.which, event->cbutton.button, + ControllerButtonName((SDL_GameControllerButton)event->cbutton.button)); break; case SDL_CLIPBOARDUPDATE: SDL_Log("SDL EVENT: Clipboard updated"); @@ -1443,8 +1764,8 @@ SDLTest_PrintEvent(SDL_Event * event) case SDL_FINGERMOTION: SDL_Log("SDL EVENT: Finger: motion touch=%ld, finger=%ld, x=%f, y=%f, dx=%f, dy=%f, pressure=%f", - (long) event->tfinger.touchId, - (long) event->tfinger.fingerId, + (long)event->tfinger.touchId, + (long)event->tfinger.fingerId, event->tfinger.x, event->tfinger.y, event->tfinger.dx, event->tfinger.dy, event->tfinger.pressure); break; @@ -1452,16 +1773,16 @@ SDLTest_PrintEvent(SDL_Event * event) case SDL_FINGERUP: SDL_Log("SDL EVENT: Finger: %s touch=%ld, finger=%ld, x=%f, y=%f, dx=%f, dy=%f, pressure=%f", (event->type == SDL_FINGERDOWN) ? "down" : "up", - (long) event->tfinger.touchId, - (long) event->tfinger.fingerId, + (long)event->tfinger.touchId, + (long)event->tfinger.fingerId, event->tfinger.x, event->tfinger.y, event->tfinger.dx, event->tfinger.dy, event->tfinger.pressure); break; case SDL_DOLLARGESTURE: - SDL_Log("SDL_EVENT: Dollar gesture detect: %ld", (long) event->dgesture.gestureId); + SDL_Log("SDL_EVENT: Dollar gesture detect: %ld", (long)event->dgesture.gestureId); break; case SDL_DOLLARRECORD: - SDL_Log("SDL_EVENT: Dollar gesture record: %ld", (long) event->dgesture.gestureId); + SDL_Log("SDL_EVENT: Dollar gesture record: %ld", (long)event->dgesture.gestureId); break; case SDL_MULTIGESTURE: SDL_Log("SDL_EVENT: Multi gesture fingers: %d", event->mgesture.numFingers); @@ -1508,16 +1829,15 @@ SDLTest_PrintEvent(SDL_Event * event) SDL_Log("SDL EVENT: Quit requested"); break; case SDL_USEREVENT: - SDL_Log("SDL EVENT: User event %d", event->user.code); + SDL_Log("SDL EVENT: User event %" SDL_PRIs32, event->user.code); break; default: - SDL_Log("Unknown event 0x%4.4x", event->type); + SDL_Log("Unknown event 0x%4.4" SDL_PRIu32, event->type); break; } } -static void -SDLTest_ScreenShot(SDL_Renderer *renderer) +static void SDLTest_ScreenShot(SDL_Renderer *renderer) { SDL_Rect viewport; SDL_Surface *surface; @@ -1529,11 +1849,11 @@ SDLTest_ScreenShot(SDL_Renderer *renderer) SDL_RenderGetViewport(renderer, &viewport); surface = SDL_CreateRGBSurface(0, viewport.w, viewport.h, 24, #if SDL_BYTEORDER == SDL_LIL_ENDIAN - 0x00FF0000, 0x0000FF00, 0x000000FF, + 0x00FF0000, 0x0000FF00, 0x000000FF, #else - 0x000000FF, 0x0000FF00, 0x00FF0000, + 0x000000FF, 0x0000FF00, 0x00FF0000, #endif - 0x00000000); + 0x00000000); if (!surface) { SDL_Log("Couldn't create surface: %s\n", SDL_GetError()); return; @@ -1553,8 +1873,7 @@ SDLTest_ScreenShot(SDL_Renderer *renderer) } } -static void -FullscreenTo(int index, int windowId) +static void FullscreenTo(int index, int windowId) { Uint32 flags; struct SDL_Rect rect = { 0, 0, 0, 0 }; @@ -1563,73 +1882,86 @@ FullscreenTo(int index, int windowId) return; } - SDL_GetDisplayBounds( index, &rect ); + SDL_GetDisplayBounds(index, &rect); flags = SDL_GetWindowFlags(window); if (flags & SDL_WINDOW_FULLSCREEN) { - SDL_SetWindowFullscreen( window, SDL_FALSE ); - SDL_Delay( 15 ); + SDL_SetWindowFullscreen(window, 0); + SDL_Delay(15); } - SDL_SetWindowPosition( window, rect.x, rect.y ); - SDL_SetWindowFullscreen( window, SDL_TRUE ); + SDL_SetWindowPosition(window, rect.x, rect.y); + SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN); } -void -SDLTest_CommonEvent(SDLTest_CommonState * state, SDL_Event * event, int *done) +void SDLTest_CommonEvent(SDLTest_CommonState *state, SDL_Event *event, int *done) { int i; static SDL_MouseMotionEvent lastEvent; if (state->verbose & VERBOSE_EVENT) { - SDLTest_PrintEvent(event); + if (((event->type != SDL_MOUSEMOTION) && + (event->type != SDL_FINGERMOTION)) || + ((state->verbose & VERBOSE_MOTION) != 0)) { + SDLTest_PrintEvent(event); + } } switch (event->type) { case SDL_WINDOWEVENT: switch (event->window.event) { case SDL_WINDOWEVENT_CLOSE: - { - SDL_Window *window = SDL_GetWindowFromID(event->window.windowID); - if (window) { - for (i = 0; i < state->num_windows; ++i) { - if (window == state->windows[i]) { - if (state->targets[i]) { - SDL_DestroyTexture(state->targets[i]); - state->targets[i] = NULL; - } - if (state->renderers[i]) { - SDL_DestroyRenderer(state->renderers[i]); - state->renderers[i] = NULL; - } - SDL_DestroyWindow(state->windows[i]); - state->windows[i] = NULL; - break; + { + SDL_Window *window = SDL_GetWindowFromID(event->window.windowID); + if (window) { + for (i = 0; i < state->num_windows; ++i) { + if (window == state->windows[i]) { + if (state->targets[i]) { + SDL_DestroyTexture(state->targets[i]); + state->targets[i] = NULL; } + if (state->renderers[i]) { + SDL_DestroyRenderer(state->renderers[i]); + state->renderers[i] = NULL; + } + SDL_DestroyWindow(state->windows[i]); + state->windows[i] = NULL; + break; } } } + } break; + case SDL_WINDOWEVENT_FOCUS_LOST: + if (state->flash_on_focus_loss) { + SDL_Window *window = SDL_GetWindowFromID(event->window.windowID); + if (window) { + SDL_FlashWindow(window, SDL_FLASH_UNTIL_FOCUSED); + } + } + break; + default: break; } break; - case SDL_KEYDOWN: { + case SDL_KEYDOWN: + { SDL_bool withControl = !!(event->key.keysym.mod & KMOD_CTRL); SDL_bool withShift = !!(event->key.keysym.mod & KMOD_SHIFT); SDL_bool withAlt = !!(event->key.keysym.mod & KMOD_ALT); switch (event->key.keysym.sym) { /* Add hotkeys here */ - case SDLK_PRINTSCREEN: { - SDL_Window *window = SDL_GetWindowFromID(event->key.windowID); - if (window) { - for (i = 0; i < state->num_windows; ++i) { - if (window == state->windows[i]) { - SDLTest_ScreenShot(state->renderers[i]); - } + case SDLK_PRINTSCREEN: + { + SDL_Window *window = SDL_GetWindowFromID(event->key.windowID); + if (window) { + for (i = 0; i < state->num_windows; ++i) { + if (window == state->windows[i]) { + SDLTest_ScreenShot(state->renderers[i]); } } } - break; + } break; case SDLK_EQUALS: if (withControl) { /* Ctrl-+ double the size of the window */ @@ -1637,7 +1969,7 @@ SDLTest_CommonEvent(SDLTest_CommonState * state, SDL_Event * event, int *done) if (window) { int w, h; SDL_GetWindowSize(window, &w, &h); - SDL_SetWindowSize(window, w*2, h*2); + SDL_SetWindowSize(window, w * 2, h * 2); } } break; @@ -1648,7 +1980,7 @@ SDLTest_CommonEvent(SDLTest_CommonState * state, SDL_Event * event, int *done) if (window) { int w, h; SDL_GetWindowSize(window, &w, &h); - SDL_SetWindowSize(window, w/2, h/2); + SDL_SetWindowSize(window, w / 2, h / 2); } } break; @@ -1672,8 +2004,8 @@ SDLTest_CommonEvent(SDLTest_CommonState * state, SDL_Event * event, int *done) } SDL_Log("Centering on display %d\n", dest); SDL_SetWindowPosition(window, - SDL_WINDOWPOS_CENTERED_DISPLAY(dest), - SDL_WINDOWPOS_CENTERED_DISPLAY(dest)); + SDL_WINDOWPOS_CENTERED_DISPLAY(dest), + SDL_WINDOWPOS_CENTERED_DISPLAY(dest)); } } } @@ -1684,11 +2016,19 @@ SDLTest_CommonEvent(SDLTest_CommonState * state, SDL_Event * event, int *done) const int delta = 100; int x, y; SDL_GetWindowPosition(window, &x, &y); - - if (event->key.keysym.sym == SDLK_UP) y -= delta; - if (event->key.keysym.sym == SDLK_DOWN) y += delta; - if (event->key.keysym.sym == SDLK_LEFT) x -= delta; - if (event->key.keysym.sym == SDLK_RIGHT) x += delta; + + if (event->key.keysym.sym == SDLK_UP) { + y -= delta; + } + if (event->key.keysym.sym == SDLK_DOWN) { + y += delta; + } + if (event->key.keysym.sym == SDLK_LEFT) { + x -= delta; + } + if (event->key.keysym.sym == SDLK_RIGHT) { + x += delta; + } SDL_Log("Setting position to (%d, %d)\n", x, y); SDL_SetWindowPosition(window, x, y); @@ -1717,7 +2057,7 @@ SDLTest_CommonEvent(SDLTest_CommonState * state, SDL_Event * event, int *done) if (withControl) { /* Ctrl-C copy awesome text! */ SDL_SetClipboardText("SDL rocks!\nYou know it!"); - printf("Copied text to clipboard\n"); + SDL_Log("Copied text to clipboard\n"); } if (withAlt) { /* Alt-C toggle a render clip rectangle */ @@ -1728,10 +2068,10 @@ SDLTest_CommonEvent(SDLTest_CommonState * state, SDL_Event * event, int *done) SDL_GetWindowSize(state->windows[i], &w, &h); SDL_RenderGetClipRect(state->renderers[i], &clip); if (SDL_RectEmpty(&clip)) { - clip.x = w/4; - clip.y = h/4; - clip.w = w/2; - clip.h = h/2; + clip.x = w / 4; + clip.y = h / 4; + clip.w = w / 2; + clip.h = h / 2; SDL_RenderSetClipRect(state->renderers[i], &clip); } else { SDL_RenderSetClipRect(state->renderers[i], NULL); @@ -1753,22 +2093,40 @@ SDLTest_CommonEvent(SDLTest_CommonState * state, SDL_Event * event, int *done) /* Ctrl-V paste awesome text! */ char *text = SDL_GetClipboardText(); if (*text) { - printf("Clipboard: %s\n", text); + SDL_Log("Clipboard: %s\n", text); } else { - printf("Clipboard is empty\n"); + SDL_Log("Clipboard is empty\n"); } SDL_free(text); } break; + case SDLK_f: + if (withControl) { + /* Ctrl-F flash the window */ + SDL_Window *window = SDL_GetWindowFromID(event->key.windowID); + if (window) { + SDL_FlashWindow(window, SDL_FLASH_BRIEFLY); + } + } + break; case SDLK_g: if (withControl) { - /* Ctrl-G toggle grab */ + /* Ctrl-G toggle mouse grab */ SDL_Window *window = SDL_GetWindowFromID(event->key.windowID); if (window) { SDL_SetWindowGrab(window, !SDL_GetWindowGrab(window) ? SDL_TRUE : SDL_FALSE); } } break; + case SDLK_k: + if (withControl) { + /* Ctrl-K toggle keyboard grab */ + SDL_Window *window = SDL_GetWindowFromID(event->key.windowID); + if (window) { + SDL_SetWindowKeyboardGrab(window, !SDL_GetWindowKeyboardGrab(window) ? SDL_TRUE : SDL_FALSE); + } + } + break; case SDLK_m: if (withControl) { /* Ctrl-M maximize */ @@ -1789,6 +2147,20 @@ SDLTest_CommonEvent(SDLTest_CommonState * state, SDL_Event * event, int *done) SDL_SetRelativeMouseMode(!SDL_GetRelativeMouseMode() ? SDL_TRUE : SDL_FALSE); } break; + case SDLK_t: + if (withControl) { + /* Ctrl-T toggle topmost mode */ + SDL_Window *window = SDL_GetWindowFromID(event->key.windowID); + if (window) { + Uint32 flags = SDL_GetWindowFlags(window); + if (flags & SDL_WINDOW_ALWAYS_ON_TOP) { + SDL_SetWindowAlwaysOnTop(window, SDL_FALSE); + } else { + SDL_SetWindowAlwaysOnTop(window, SDL_TRUE); + } + } + } + break; case SDLK_z: if (withControl) { /* Ctrl-Z minimize */ @@ -1841,7 +2213,7 @@ SDLTest_CommonEvent(SDLTest_CommonState * state, SDL_Event * event, int *done) SDL_Window *window = SDL_GetWindowFromID(event->key.windowID); if (window) { const Uint32 flags = SDL_GetWindowFlags(window); - const SDL_bool b = ((flags & SDL_WINDOW_BORDERLESS) != 0) ? SDL_TRUE : SDL_FALSE; + const SDL_bool b = (flags & SDL_WINDOW_BORDERLESS) ? SDL_TRUE : SDL_FALSE; SDL_SetWindowBordered(window, b); } } @@ -1883,7 +2255,8 @@ SDLTest_CommonEvent(SDLTest_CommonState * state, SDL_Event * event, int *done) char message[256]; SDL_Window *window = SDL_GetWindowFromID(event->key.windowID); - SDL_snprintf(message, sizeof(message), "(%i, %i), rel (%i, %i)\n", lastEvent.x, lastEvent.y, lastEvent.xrel, lastEvent.yrel); + (void)SDL_snprintf(message, sizeof(message), "(%" SDL_PRIs32 ", %" SDL_PRIs32 "), rel (%" SDL_PRIs32 ", %" SDL_PRIs32 ")\n", + lastEvent.x, lastEvent.y, lastEvent.xrel, lastEvent.yrel); SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Last mouse position", message, window); break; } @@ -1906,8 +2279,7 @@ SDLTest_CommonEvent(SDLTest_CommonState * state, SDL_Event * event, int *done) } } -void -SDLTest_CommonQuit(SDLTest_CommonState * state) +void SDLTest_CommonQuit(SDLTest_CommonState *state) { int i; @@ -1946,4 +2318,184 @@ SDLTest_CommonQuit(SDLTest_CommonState * state) SDLTest_LogAllocations(); } +void SDLTest_CommonDrawWindowInfo(SDL_Renderer *renderer, SDL_Window *window, int *usedHeight) +{ + char text[1024]; + int textY = 0; + const int lineHeight = 10; + int x, y, w, h; + SDL_Rect rect; + SDL_DisplayMode mode; + float ddpi, hdpi, vdpi; + float scaleX, scaleY; + Uint32 flags; + const int windowDisplayIndex = SDL_GetWindowDisplayIndex(window); + SDL_RendererInfo info; + + /* Video */ + + SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); + SDLTest_DrawString(renderer, 0, textY, "-- Video --"); + textY += lineHeight; + + SDL_SetRenderDrawColor(renderer, 170, 170, 170, 255); + + (void)SDL_snprintf(text, sizeof(text), "SDL_GetCurrentVideoDriver: %s", SDL_GetCurrentVideoDriver()); + SDLTest_DrawString(renderer, 0, textY, text); + textY += lineHeight; + + /* Renderer */ + + SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); + SDLTest_DrawString(renderer, 0, textY, "-- Renderer --"); + textY += lineHeight; + + SDL_SetRenderDrawColor(renderer, 170, 170, 170, 255); + + if (0 == SDL_GetRendererInfo(renderer, &info)) { + (void)SDL_snprintf(text, sizeof(text), "SDL_GetRendererInfo: name: %s", info.name); + SDLTest_DrawString(renderer, 0, textY, text); + textY += lineHeight; + } + + if (0 == SDL_GetRendererOutputSize(renderer, &w, &h)) { + (void)SDL_snprintf(text, sizeof(text), "SDL_GetRendererOutputSize: %dx%d", w, h); + SDLTest_DrawString(renderer, 0, textY, text); + textY += lineHeight; + } + + SDL_RenderGetViewport(renderer, &rect); + (void)SDL_snprintf(text, sizeof(text), "SDL_RenderGetViewport: %d,%d, %dx%d", + rect.x, rect.y, rect.w, rect.h); + SDLTest_DrawString(renderer, 0, textY, text); + textY += lineHeight; + + SDL_RenderGetScale(renderer, &scaleX, &scaleY); + (void)SDL_snprintf(text, sizeof(text), "SDL_RenderGetScale: %f,%f", + scaleX, scaleY); + SDLTest_DrawString(renderer, 0, textY, text); + textY += lineHeight; + + SDL_RenderGetLogicalSize(renderer, &w, &h); + (void)SDL_snprintf(text, sizeof(text), "SDL_RenderGetLogicalSize: %dx%d", w, h); + SDLTest_DrawString(renderer, 0, textY, text); + textY += lineHeight; + + /* Window */ + + SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); + SDLTest_DrawString(renderer, 0, textY, "-- Window --"); + textY += lineHeight; + + SDL_SetRenderDrawColor(renderer, 170, 170, 170, 255); + + SDL_GetWindowPosition(window, &x, &y); + (void)SDL_snprintf(text, sizeof(text), "SDL_GetWindowPosition: %d,%d", x, y); + SDLTest_DrawString(renderer, 0, textY, text); + textY += lineHeight; + + SDL_GetWindowSize(window, &w, &h); + (void)SDL_snprintf(text, sizeof(text), "SDL_GetWindowSize: %dx%d", w, h); + SDLTest_DrawString(renderer, 0, textY, text); + textY += lineHeight; + + (void)SDL_snprintf(text, sizeof(text), "SDL_GetWindowFlags: "); + SDLTest_PrintWindowFlags(text, sizeof(text), SDL_GetWindowFlags(window)); + SDLTest_DrawString(renderer, 0, textY, text); + textY += lineHeight; + + if (0 == SDL_GetWindowDisplayMode(window, &mode)) { + (void)SDL_snprintf(text, sizeof(text), "SDL_GetWindowDisplayMode: %dx%d@%dHz (%s)", + mode.w, mode.h, mode.refresh_rate, SDL_GetPixelFormatName(mode.format)); + SDLTest_DrawString(renderer, 0, textY, text); + textY += lineHeight; + } + + /* Display */ + + SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); + SDLTest_DrawString(renderer, 0, textY, "-- Display --"); + textY += lineHeight; + + SDL_SetRenderDrawColor(renderer, 170, 170, 170, 255); + + (void)SDL_snprintf(text, sizeof(text), "SDL_GetWindowDisplayIndex: %d", windowDisplayIndex); + SDLTest_DrawString(renderer, 0, textY, text); + textY += lineHeight; + + (void)SDL_snprintf(text, sizeof(text), "SDL_GetDisplayName: %s", SDL_GetDisplayName(windowDisplayIndex)); + SDLTest_DrawString(renderer, 0, textY, text); + textY += lineHeight; + + if (0 == SDL_GetDisplayBounds(windowDisplayIndex, &rect)) { + (void)SDL_snprintf(text, sizeof(text), "SDL_GetDisplayBounds: %d,%d, %dx%d", + rect.x, rect.y, rect.w, rect.h); + SDLTest_DrawString(renderer, 0, textY, text); + textY += lineHeight; + } + + if (0 == SDL_GetCurrentDisplayMode(windowDisplayIndex, &mode)) { + (void)SDL_snprintf(text, sizeof(text), "SDL_GetCurrentDisplayMode: %dx%d@%d", + mode.w, mode.h, mode.refresh_rate); + SDLTest_DrawString(renderer, 0, textY, text); + textY += lineHeight; + } + + if (0 == SDL_GetDesktopDisplayMode(windowDisplayIndex, &mode)) { + (void)SDL_snprintf(text, sizeof(text), "SDL_GetDesktopDisplayMode: %dx%d@%d", + mode.w, mode.h, mode.refresh_rate); + SDLTest_DrawString(renderer, 0, textY, text); + textY += lineHeight; + } + + if (0 == SDL_GetDisplayDPI(windowDisplayIndex, &ddpi, &hdpi, &vdpi)) { + (void)SDL_snprintf(text, sizeof(text), "SDL_GetDisplayDPI: ddpi: %f, hdpi: %f, vdpi: %f", + ddpi, hdpi, vdpi); + SDLTest_DrawString(renderer, 0, textY, text); + textY += lineHeight; + } + + (void)SDL_snprintf(text, sizeof(text), "SDL_GetDisplayOrientation: "); + SDLTest_PrintDisplayOrientation(text, sizeof(text), SDL_GetDisplayOrientation(windowDisplayIndex)); + SDLTest_DrawString(renderer, 0, textY, text); + textY += lineHeight; + + /* Mouse */ + + SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); + SDLTest_DrawString(renderer, 0, textY, "-- Mouse --"); + textY += lineHeight; + + SDL_SetRenderDrawColor(renderer, 170, 170, 170, 255); + + flags = SDL_GetMouseState(&x, &y); + (void)SDL_snprintf(text, sizeof(text), "SDL_GetMouseState: %d,%d ", x, y); + SDLTest_PrintButtonMask(text, sizeof(text), flags); + SDLTest_DrawString(renderer, 0, textY, text); + textY += lineHeight; + + flags = SDL_GetGlobalMouseState(&x, &y); + (void)SDL_snprintf(text, sizeof(text), "SDL_GetGlobalMouseState: %d,%d ", x, y); + SDLTest_PrintButtonMask(text, sizeof(text), flags); + SDLTest_DrawString(renderer, 0, textY, text); + textY += lineHeight; + + /* Keyboard */ + + SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); + SDLTest_DrawString(renderer, 0, textY, "-- Keyboard --"); + textY += lineHeight; + + SDL_SetRenderDrawColor(renderer, 170, 170, 170, 255); + + (void)SDL_snprintf(text, sizeof(text), "SDL_GetModState: "); + SDLTest_PrintModState(text, sizeof(text), SDL_GetModState()); + SDLTest_DrawString(renderer, 0, textY, text); + textY += lineHeight; + + if (usedHeight) { + *usedHeight = textY; + } +} + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/test/SDL_test_compare.c b/SDL2-2.30.5/src/test/SDL_test_compare.c new file mode 100644 index 0000000..ba532c7 --- /dev/null +++ b/SDL2-2.30.5/src/test/SDL_test_compare.c @@ -0,0 +1,140 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +/* + + Based on automated SDL_Surface tests originally written by Edgar Simo 'bobbens'. + + Rewritten for test lib by Andreas Schiffler. + +*/ + +#include "SDL_config.h" + +#include "SDL_test.h" + +#define FILENAME_SIZE 128 + +/* Counter for _CompareSurface calls; used for filename creation when comparisons fail */ +static int _CompareSurfaceCount = 0; + +static Uint32 +GetPixel(Uint8 *p, size_t bytes_per_pixel) +{ + Uint32 ret = 0; + + SDL_assert(bytes_per_pixel <= sizeof(ret)); + + /* Fill the appropriate number of least-significant bytes of ret, + * leaving the most-significant bytes set to zero, so that ret can + * be decoded with SDL_GetRGBA afterwards. */ +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + SDL_memcpy(((Uint8 *) &ret) + (sizeof(ret) - bytes_per_pixel), p, bytes_per_pixel); +#else + SDL_memcpy(&ret, p, bytes_per_pixel); +#endif + + return ret; +} + +/* Compare surfaces */ +int SDLTest_CompareSurfaces(SDL_Surface *surface, SDL_Surface *referenceSurface, int allowable_error) +{ + int ret; + int i, j; + int bpp, bpp_reference; + Uint8 *p, *p_reference; + int dist; + int sampleErrorX = 0, sampleErrorY = 0, sampleDist = 0; + Uint8 R, G, B, A; + Uint8 Rd, Gd, Bd, Ad; + char imageFilename[FILENAME_SIZE]; + char referenceFilename[FILENAME_SIZE]; + + /* Validate input surfaces */ + if (!surface || !referenceSurface) { + return -1; + } + + /* Make sure surface size is the same. */ + if ((surface->w != referenceSurface->w) || (surface->h != referenceSurface->h)) { + return -2; + } + + /* Sanitize input value */ + if (allowable_error < 0) { + allowable_error = 0; + } + + SDL_LockSurface(surface); + SDL_LockSurface(referenceSurface); + + ret = 0; + bpp = surface->format->BytesPerPixel; + bpp_reference = referenceSurface->format->BytesPerPixel; + /* Compare image - should be same format. */ + for (j = 0; j < surface->h; j++) { + for (i = 0; i < surface->w; i++) { + Uint32 pixel; + p = (Uint8 *)surface->pixels + j * surface->pitch + i * bpp; + p_reference = (Uint8 *)referenceSurface->pixels + j * referenceSurface->pitch + i * bpp_reference; + + pixel = GetPixel(p, bpp); + SDL_GetRGBA(pixel, surface->format, &R, &G, &B, &A); + pixel = GetPixel(p_reference, bpp_reference); + SDL_GetRGBA(pixel, referenceSurface->format, &Rd, &Gd, &Bd, &Ad); + + dist = 0; + dist += (R - Rd) * (R - Rd); + dist += (G - Gd) * (G - Gd); + dist += (B - Bd) * (B - Bd); + + /* Allow some difference in blending accuracy */ + if (dist > allowable_error) { + ret++; + if (ret == 1) { + sampleErrorX = i; + sampleErrorY = j; + sampleDist = dist; + } + } + } + } + + SDL_UnlockSurface(surface); + SDL_UnlockSurface(referenceSurface); + + /* Save test image and reference for analysis on failures */ + _CompareSurfaceCount++; + if (ret != 0) { + SDLTest_LogError("Comparison of pixels with allowable error of %i failed %i times.", allowable_error, ret); + SDLTest_LogError("First detected occurrence at position %i,%i with a squared RGB-difference of %i.", sampleErrorX, sampleErrorY, sampleDist); + (void)SDL_snprintf(imageFilename, FILENAME_SIZE - 1, "CompareSurfaces%04d_TestOutput.bmp", _CompareSurfaceCount); + SDL_SaveBMP(surface, imageFilename); + (void)SDL_snprintf(referenceFilename, FILENAME_SIZE - 1, "CompareSurfaces%04d_Reference.bmp", _CompareSurfaceCount); + SDL_SaveBMP(referenceSurface, referenceFilename); + SDLTest_LogError("Surfaces from failed comparison saved as '%s' and '%s'", imageFilename, referenceFilename); + } + + return ret; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/test/SDL_test_crc32.c b/SDL2-2.30.5/src/test/SDL_test_crc32.c new file mode 100644 index 0000000..b13839b --- /dev/null +++ b/SDL2-2.30.5/src/test/SDL_test_crc32.c @@ -0,0 +1,165 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +/* + + Used by the test execution component. + Original source code contributed by A. Schiffler for GSOC project. + +*/ + +#include "SDL_config.h" + +#include "SDL_test.h" + +int SDLTest_Crc32Init(SDLTest_Crc32Context *crcContext) +{ + int i, j; + CrcUint32 c; + + /* Sanity check context pointer */ + if (!crcContext) { + return -1; + } + + /* + * Build auxiliary table for parallel byte-at-a-time CRC-32 + */ +#ifdef ORIGINAL_METHOD + for (i = 0; i < 256; ++i) { + for (c = i << 24, j = 8; j > 0; --j) { + c = c & 0x80000000 ? (c << 1) ^ CRC32_POLY : (c << 1); + } + crcContext->crc32_table[i] = c; + } +#else + for (i = 0; i < 256; i++) { + c = i; + for (j = 8; j > 0; j--) { + if (c & 1) { + c = (c >> 1) ^ CRC32_POLY; + } else { + c >>= 1; + } + } + crcContext->crc32_table[i] = c; + } +#endif + + return 0; +} + +/* Complete CRC32 calculation on a memory block */ +int SDLTest_Crc32Calc(SDLTest_Crc32Context *crcContext, CrcUint8 *inBuf, CrcUint32 inLen, CrcUint32 *crc32) +{ + if (SDLTest_Crc32CalcStart(crcContext, crc32)) { + return -1; + } + + if (SDLTest_Crc32CalcBuffer(crcContext, inBuf, inLen, crc32)) { + return -1; + } + + if (SDLTest_Crc32CalcEnd(crcContext, crc32)) { + return -1; + } + + return 0; +} + +/* Start crc calculation */ + +int SDLTest_Crc32CalcStart(SDLTest_Crc32Context *crcContext, CrcUint32 *crc32) +{ + /* Sanity check pointers */ + if (!crcContext) { + *crc32 = 0; + return -1; + } + + /* + * Preload shift register, per CRC-32 spec + */ + *crc32 = 0xffffffff; + + return 0; +} + +/* Finish crc calculation */ + +int SDLTest_Crc32CalcEnd(SDLTest_Crc32Context *crcContext, CrcUint32 *crc32) +{ + /* Sanity check pointers */ + if (!crcContext) { + *crc32 = 0; + return -1; + } + + /* + * Return complement, per CRC-32 spec + */ + *crc32 = (~(*crc32)); + + return 0; +} + +/* Include memory block in crc */ + +int SDLTest_Crc32CalcBuffer(SDLTest_Crc32Context *crcContext, CrcUint8 *inBuf, CrcUint32 inLen, CrcUint32 *crc32) +{ + CrcUint8 *p; + register CrcUint32 crc; + + if (!crcContext) { + *crc32 = 0; + return -1; + } + + if (!inBuf) { + return -1; + } + + /* + * Calculate CRC from data + */ + crc = *crc32; + for (p = inBuf; inLen > 0; ++p, --inLen) { +#ifdef ORIGINAL_METHOD + crc = (crc << 8) ^ crcContext->crc32_table[(crc >> 24) ^ *p]; +#else + crc = ((crc >> 8) & 0x00FFFFFF) ^ crcContext->crc32_table[(crc ^ *p) & 0xFF]; +#endif + } + *crc32 = crc; + + return 0; +} + +int SDLTest_Crc32Done(SDLTest_Crc32Context *crcContext) +{ + if (!crcContext) { + return -1; + } + + return 0; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/test/SDL_test_font.c b/SDL2-2.30.5/src/test/SDL_test_font.c new file mode 100644 index 0000000..ffa3dde --- /dev/null +++ b/SDL2-2.30.5/src/test/SDL_test_font.c @@ -0,0 +1,3495 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_test.h" + +/* ---- 8x8 font definition ---- */ + +/* +; Summary: font8_8.asm +; 8x8 monochrome bitmap fonts for rendering +; +; Author: +; Marcel Sondaar +; International Business Machines (public domain VGA fonts) +; +; License: +; Public Domain +; +*/ + +static unsigned char SDLTest_FontData[] = { + + /* + * 0 0x00 '^@' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 1 0x01 '^A' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 2 0x02 '^B' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 3 0x03 '^C' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 4 0x04 '^D' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 5 0x05 '^E' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 6 0x06 '^F' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 7 0x07 '^G' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 8 0x08 '^H' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 9 0x09 '^I' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 10 0x0a '^J' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 11 0x0b '^K' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 12 0x0c '^L' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 13 0x0d '^M' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 14 0x0e '^N' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 15 0x0f '^O' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 16 0x10 '^P' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 17 0x11 '^Q' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 18 0x12 '^R' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 19 0x13 '^S' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 20 0x14 '^T' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 21 0x15 '^U' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 22 0x16 '^V' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 23 0x17 '^W' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 24 0x18 '^X' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 25 0x19 '^Y' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 26 0x1a '^Z' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 27 0x1b '^[' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 28 0x1c '^\' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 29 0x1d '^]' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 30 0x1e '^^' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 31 0x1f '^_' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 32 0x20 ' ' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 33 0x21 '!' + */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* + * 34 0x22 '"' + */ + 0x36, /* 01101100 */ + 0x36, /* 01101100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 35 0x23 '#' + */ + 0x36, /* 01101100 */ + 0x36, /* 01101100 */ + 0x7f, /* 11111110 */ + 0x36, /* 01101100 */ + 0x7f, /* 11111110 */ + 0x36, /* 01101100 */ + 0x36, /* 01101100 */ + 0x00, /* 00000000 */ + + /* + * 36 0x24 '$' + */ + 0x0c, /* 00110000 */ + 0x3e, /* 01111100 */ + 0x03, /* 11000000 */ + 0x1e, /* 01111000 */ + 0x30, /* 00001100 */ + 0x1f, /* 11111000 */ + 0x0c, /* 00110000 */ + 0x00, /* 00000000 */ + + /* + * 37 0x25 '%' + */ + 0x00, /* 00000000 */ + 0x63, /* 11000110 */ + 0x33, /* 11001100 */ + 0x18, /* 00011000 */ + 0x0c, /* 00110000 */ + 0x66, /* 01100110 */ + 0x63, /* 11000110 */ + 0x00, /* 00000000 */ + + /* + * 38 0x26 '&' + */ + 0x1c, /* 00111000 */ + 0x36, /* 01101100 */ + 0x1c, /* 00111000 */ + 0x6e, /* 01110110 */ + 0x3b, /* 11011100 */ + 0x33, /* 11001100 */ + 0x6e, /* 01110110 */ + 0x00, /* 00000000 */ + + /* + * 39 0x27 ''' + */ + 0x06, /* 01100000 */ + 0x06, /* 01100000 */ + 0x03, /* 11000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 40 0x28 '(' + */ + 0x18, /* 00011000 */ + 0x0c, /* 00110000 */ + 0x06, /* 01100000 */ + 0x06, /* 01100000 */ + 0x06, /* 01100000 */ + 0x0c, /* 00110000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* + * 41 0x29 ')' + */ + 0x06, /* 01100000 */ + 0x0c, /* 00110000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x0c, /* 00110000 */ + 0x06, /* 01100000 */ + 0x00, /* 00000000 */ + + /* + * 42 0x2a '*' + */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0xff, /* 11111111 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 43 0x2b '+' + */ + 0x00, /* 00000000 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x3f, /* 11111100 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 44 0x2c ',' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x06, /* 01100000 */ + + /* + * 45 0x2d '-' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3f, /* 11111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 46 0x2e '.' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x00, /* 00000000 */ + + /* + * 47 0x2f '/' + */ + 0x60, /* 00000110 */ + 0x30, /* 00001100 */ + 0x18, /* 00011000 */ + 0x0c, /* 00110000 */ + 0x06, /* 01100000 */ + 0x03, /* 11000000 */ + 0x01, /* 10000000 */ + 0x00, /* 00000000 */ + + /* + * 48 0x30 '0' + */ + 0x3e, /* 01111100 */ + 0x63, /* 11000110 */ + 0x73, /* 11001110 */ + 0x7b, /* 11011110 */ + 0x6f, /* 11110110 */ + 0x67, /* 11100110 */ + 0x3e, /* 01111100 */ + 0x00, /* 00000000 */ + + /* + * 49 0x31 '1' + */ + 0x0c, /* 00110000 */ + 0x0e, /* 01110000 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x3f, /* 11111100 */ + 0x00, /* 00000000 */ + + /* + * 50 0x32 '2' + */ + 0x1e, /* 01111000 */ + 0x33, /* 11001100 */ + 0x30, /* 00001100 */ + 0x1c, /* 00111000 */ + 0x06, /* 01100000 */ + 0x33, /* 11001100 */ + 0x3f, /* 11111100 */ + 0x00, /* 00000000 */ + + /* + * 51 0x33 '3' + */ + 0x1e, /* 01111000 */ + 0x33, /* 11001100 */ + 0x30, /* 00001100 */ + 0x1c, /* 00111000 */ + 0x30, /* 00001100 */ + 0x33, /* 11001100 */ + 0x1e, /* 01111000 */ + 0x00, /* 00000000 */ + + /* + * 52 0x34 '4' + */ + 0x38, /* 00011100 */ + 0x3c, /* 00111100 */ + 0x36, /* 01101100 */ + 0x33, /* 11001100 */ + 0x7f, /* 11111110 */ + 0x30, /* 00001100 */ + 0x78, /* 00011110 */ + 0x00, /* 00000000 */ + + /* + * 53 0x35 '5' + */ + 0x3f, /* 11111100 */ + 0x03, /* 11000000 */ + 0x1f, /* 11111000 */ + 0x30, /* 00001100 */ + 0x30, /* 00001100 */ + 0x33, /* 11001100 */ + 0x1e, /* 01111000 */ + 0x00, /* 00000000 */ + + /* + * 54 0x36 '6' + */ + 0x1c, /* 00111000 */ + 0x06, /* 01100000 */ + 0x03, /* 11000000 */ + 0x1f, /* 11111000 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x1e, /* 01111000 */ + 0x00, /* 00000000 */ + + /* + * 55 0x37 '7' + */ + 0x3f, /* 11111100 */ + 0x33, /* 11001100 */ + 0x30, /* 00001100 */ + 0x18, /* 00011000 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x00, /* 00000000 */ + + /* + * 56 0x38 '8' + */ + 0x1e, /* 01111000 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x1e, /* 01111000 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x1e, /* 01111000 */ + 0x00, /* 00000000 */ + + /* + * 57 0x39 '9' + */ + 0x1e, /* 01111000 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x3e, /* 01111100 */ + 0x30, /* 00001100 */ + 0x18, /* 00011000 */ + 0x0e, /* 01110000 */ + 0x00, /* 00000000 */ + + /* + * 58 0x3a ':' + */ + 0x00, /* 00000000 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x00, /* 00000000 */ + + /* + * 59 0x3b ';' + */ + 0x00, /* 00000000 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x06, /* 01100000 */ + + /* + * 60 0x3c '<' + */ + 0x18, /* 00011000 */ + 0x0c, /* 00110000 */ + 0x06, /* 01100000 */ + 0x03, /* 11000000 */ + 0x06, /* 01100000 */ + 0x0c, /* 00110000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* + * 61 0x3d '=' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3f, /* 11111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3f, /* 11111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 62 0x3e '>' + */ + 0x06, /* 01100000 */ + 0x0c, /* 00110000 */ + 0x18, /* 00011000 */ + 0x30, /* 00001100 */ + 0x18, /* 00011000 */ + 0x0c, /* 00110000 */ + 0x06, /* 01100000 */ + 0x00, /* 00000000 */ + + /* + * 63 0x3f '?' + */ + 0x1e, /* 01111000 */ + 0x33, /* 11001100 */ + 0x30, /* 00001100 */ + 0x18, /* 00011000 */ + 0x0c, /* 00110000 */ + 0x00, /* 00000000 */ + 0x0c, /* 00110000 */ + 0x00, /* 00000000 */ + + /* + * 64 0x40 '@' + */ + 0x3e, /* 01111100 */ + 0x63, /* 11000110 */ + 0x7b, /* 11011110 */ + 0x7b, /* 11011110 */ + 0x7b, /* 11011110 */ + 0x03, /* 11000000 */ + 0x1e, /* 01111000 */ + 0x00, /* 00000000 */ + + /* + * 65 0x41 'A' + */ + 0x0c, /* 00110000 */ + 0x1e, /* 01111000 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x3f, /* 11111100 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x00, /* 00000000 */ + + /* + * 66 0x42 'B' + */ + 0x3f, /* 11111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3e, /* 01111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3f, /* 11111100 */ + 0x00, /* 00000000 */ + + /* + * 67 0x43 'C' + */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x03, /* 11000000 */ + 0x03, /* 11000000 */ + 0x03, /* 11000000 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* + * 68 0x44 'D' + */ + 0x1f, /* 11111000 */ + 0x36, /* 01101100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x36, /* 01101100 */ + 0x1f, /* 11111000 */ + 0x00, /* 00000000 */ + + /* + * 69 0x45 'E' + */ + 0x7f, /* 11111110 */ + 0x46, /* 01100010 */ + 0x16, /* 01101000 */ + 0x1e, /* 01111000 */ + 0x16, /* 01101000 */ + 0x46, /* 01100010 */ + 0x7f, /* 11111110 */ + 0x00, /* 00000000 */ + + /* + * 70 0x46 'F' + */ + 0x7f, /* 11111110 */ + 0x46, /* 01100010 */ + 0x16, /* 01101000 */ + 0x1e, /* 01111000 */ + 0x16, /* 01101000 */ + 0x06, /* 01100000 */ + 0x0f, /* 11110000 */ + 0x00, /* 00000000 */ + + /* + * 71 0x47 'G' + */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x03, /* 11000000 */ + 0x03, /* 11000000 */ + 0x73, /* 11001110 */ + 0x66, /* 01100110 */ + 0x7c, /* 00111110 */ + 0x00, /* 00000000 */ + + /* + * 72 0x48 'H' + */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x3f, /* 11111100 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x00, /* 00000000 */ + + /* + * 73 0x49 'I' + */ + 0x1e, /* 01111000 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x1e, /* 01111000 */ + 0x00, /* 00000000 */ + + /* + * 74 0x4a 'J' + */ + 0x78, /* 00011110 */ + 0x30, /* 00001100 */ + 0x30, /* 00001100 */ + 0x30, /* 00001100 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x1e, /* 01111000 */ + 0x00, /* 00000000 */ + + /* + * 75 0x4b 'K' + */ + 0x67, /* 11100110 */ + 0x66, /* 01100110 */ + 0x36, /* 01101100 */ + 0x1e, /* 01111000 */ + 0x36, /* 01101100 */ + 0x66, /* 01100110 */ + 0x67, /* 11100110 */ + 0x00, /* 00000000 */ + + /* + * 76 0x4c 'L' + */ + 0x0f, /* 11110000 */ + 0x06, /* 01100000 */ + 0x06, /* 01100000 */ + 0x06, /* 01100000 */ + 0x46, /* 01100010 */ + 0x66, /* 01100110 */ + 0x7f, /* 11111110 */ + 0x00, /* 00000000 */ + + /* + * 77 0x4d 'M' + */ + 0x63, /* 11000110 */ + 0x77, /* 11101110 */ + 0x7f, /* 11111110 */ + 0x7f, /* 11111110 */ + 0x6b, /* 11010110 */ + 0x63, /* 11000110 */ + 0x63, /* 11000110 */ + 0x00, /* 00000000 */ + + /* + * 78 0x4e 'N' + */ + 0x63, /* 11000110 */ + 0x67, /* 11100110 */ + 0x6f, /* 11110110 */ + 0x7b, /* 11011110 */ + 0x73, /* 11001110 */ + 0x63, /* 11000110 */ + 0x63, /* 11000110 */ + 0x00, /* 00000000 */ + + /* + * 79 0x4f 'O' + */ + 0x1c, /* 00111000 */ + 0x36, /* 01101100 */ + 0x63, /* 11000110 */ + 0x63, /* 11000110 */ + 0x63, /* 11000110 */ + 0x36, /* 01101100 */ + 0x1c, /* 00111000 */ + 0x00, /* 00000000 */ + + /* + * 80 0x50 'P' + */ + 0x3f, /* 11111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3e, /* 01111100 */ + 0x06, /* 01100000 */ + 0x06, /* 01100000 */ + 0x0f, /* 11110000 */ + 0x00, /* 00000000 */ + + /* + * 81 0x51 'Q' + */ + 0x1e, /* 01111000 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x3b, /* 11011100 */ + 0x1e, /* 01111000 */ + 0x38, /* 00011100 */ + 0x00, /* 00000000 */ + + /* + * 82 0x52 'R' + */ + 0x3f, /* 11111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3e, /* 01111100 */ + 0x36, /* 01101100 */ + 0x66, /* 01100110 */ + 0x67, /* 11100110 */ + 0x00, /* 00000000 */ + + /* + * 83 0x53 'S' + */ + 0x1e, /* 01111000 */ + 0x33, /* 11001100 */ + 0x07, /* 11100000 */ + 0x0e, /* 01110000 */ + 0x38, /* 00011100 */ + 0x33, /* 11001100 */ + 0x1e, /* 01111000 */ + 0x00, /* 00000000 */ + + /* + * 84 0x54 'T' + */ + 0x3f, /* 11111100 */ + 0x2d, /* 10110100 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x1e, /* 01111000 */ + 0x00, /* 00000000 */ + + /* + * 85 0x55 'U' + */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x3f, /* 11111100 */ + 0x00, /* 00000000 */ + + /* + * 86 0x56 'V' + */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x1e, /* 01111000 */ + 0x0c, /* 00110000 */ + 0x00, /* 00000000 */ + + /* + * 87 0x57 'W' + */ + 0x63, /* 11000110 */ + 0x63, /* 11000110 */ + 0x63, /* 11000110 */ + 0x6b, /* 11010110 */ + 0x7f, /* 11111110 */ + 0x77, /* 11101110 */ + 0x63, /* 11000110 */ + 0x00, /* 00000000 */ + + /* + * 88 0x58 'X' + */ + 0x63, /* 11000110 */ + 0x63, /* 11000110 */ + 0x36, /* 01101100 */ + 0x1c, /* 00111000 */ + 0x1c, /* 00111000 */ + 0x36, /* 01101100 */ + 0x63, /* 11000110 */ + 0x00, /* 00000000 */ + + /* + * 89 0x59 'Y' + */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x1e, /* 01111000 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x1e, /* 01111000 */ + 0x00, /* 00000000 */ + + /* + * 90 0x5a 'Z' + */ + 0x7f, /* 11111110 */ + 0x63, /* 11000110 */ + 0x31, /* 10001100 */ + 0x18, /* 00011000 */ + 0x4c, /* 00110010 */ + 0x66, /* 01100110 */ + 0x7f, /* 11111110 */ + 0x00, /* 00000000 */ + + /* + * 91 0x5b '[' + */ + 0x1e, /* 01111000 */ + 0x06, /* 01100000 */ + 0x06, /* 01100000 */ + 0x06, /* 01100000 */ + 0x06, /* 01100000 */ + 0x06, /* 01100000 */ + 0x1e, /* 01111000 */ + 0x00, /* 00000000 */ + + /* + * 92 0x5c '\' + */ + 0x03, /* 11000000 */ + 0x06, /* 01100000 */ + 0x0c, /* 00110000 */ + 0x18, /* 00011000 */ + 0x30, /* 00001100 */ + 0x60, /* 00000110 */ + 0x40, /* 00000010 */ + 0x00, /* 00000000 */ + + /* + * 93 0x5d ']' + */ + 0x1e, /* 01111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x1e, /* 01111000 */ + 0x00, /* 00000000 */ + + /* + * 94 0x5e '^' + */ + 0x08, /* 00010000 */ + 0x1c, /* 00111000 */ + 0x36, /* 01101100 */ + 0x63, /* 11000110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 95 0x5f '_' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xff, /* 11111111 */ + + /* + * 96 0x60 '`' + */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 97 0x61 'a' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1e, /* 01111000 */ + 0x30, /* 00001100 */ + 0x3e, /* 01111100 */ + 0x33, /* 11001100 */ + 0x6e, /* 01110110 */ + 0x00, /* 00000000 */ + + /* + * 98 0x62 'b' + */ + 0x07, /* 11100000 */ + 0x06, /* 01100000 */ + 0x06, /* 01100000 */ + 0x3e, /* 01111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3b, /* 11011100 */ + 0x00, /* 00000000 */ + + /* + * 99 0x63 'c' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1e, /* 01111000 */ + 0x33, /* 11001100 */ + 0x03, /* 11000000 */ + 0x33, /* 11001100 */ + 0x1e, /* 01111000 */ + 0x00, /* 00000000 */ + + /* + * 100 0x64 'd' + */ + 0x38, /* 00011100 */ + 0x30, /* 00001100 */ + 0x30, /* 00001100 */ + 0x3e, /* 01111100 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x6e, /* 01110110 */ + 0x00, /* 00000000 */ + + /* + * 101 0x65 'e' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1e, /* 01111000 */ + 0x33, /* 11001100 */ + 0x3f, /* 11111100 */ + 0x03, /* 11000000 */ + 0x1e, /* 01111000 */ + 0x00, /* 00000000 */ + + /* + * 102 0x66 'f' + */ + 0x1c, /* 00111000 */ + 0x36, /* 01101100 */ + 0x06, /* 01100000 */ + 0x0f, /* 11110000 */ + 0x06, /* 01100000 */ + 0x06, /* 01100000 */ + 0x0f, /* 11110000 */ + 0x00, /* 00000000 */ + + /* + * 103 0x67 'g' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x6e, /* 01110110 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x3e, /* 01111100 */ + 0x30, /* 00001100 */ + 0x1f, /* 11111000 */ + + /* + * 104 0x68 'h' + */ + 0x07, /* 11100000 */ + 0x06, /* 01100000 */ + 0x36, /* 01101100 */ + 0x6e, /* 01110110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x67, /* 11100110 */ + 0x00, /* 00000000 */ + + /* + * 105 0x69 'i' + */ + 0x0c, /* 00110000 */ + 0x00, /* 00000000 */ + 0x0e, /* 01110000 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x1e, /* 01111000 */ + 0x00, /* 00000000 */ + + /* + * 106 0x6a 'j' + */ + 0x30, /* 00001100 */ + 0x00, /* 00000000 */ + 0x30, /* 00001100 */ + 0x30, /* 00001100 */ + 0x30, /* 00001100 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x1e, /* 01111000 */ + + /* + * 107 0x6b 'k' + */ + 0x07, /* 11100000 */ + 0x06, /* 01100000 */ + 0x66, /* 01100110 */ + 0x36, /* 01101100 */ + 0x1e, /* 01111000 */ + 0x36, /* 01101100 */ + 0x67, /* 11100110 */ + 0x00, /* 00000000 */ + + /* + * 108 0x6c 'l' + */ + 0x0e, /* 01110000 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x1e, /* 01111000 */ + 0x00, /* 00000000 */ + + /* + * 109 0x6d 'm' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x33, /* 11001100 */ + 0x7f, /* 11111110 */ + 0x7f, /* 11111110 */ + 0x6b, /* 11010110 */ + 0x63, /* 11000110 */ + 0x00, /* 00000000 */ + + /* + * 110 0x6e 'n' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1f, /* 11111000 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x00, /* 00000000 */ + + /* + * 111 0x6f 'o' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1e, /* 01111000 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x1e, /* 01111000 */ + 0x00, /* 00000000 */ + + /* + * 112 0x70 'p' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3b, /* 11011100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3e, /* 01111100 */ + 0x06, /* 01100000 */ + 0x0f, /* 11110000 */ + + /* + * 113 0x71 'q' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x6e, /* 01110110 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x3e, /* 01111100 */ + 0x30, /* 00001100 */ + 0x78, /* 00011110 */ + + /* + * 114 0x72 'r' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3b, /* 11011100 */ + 0x6e, /* 01110110 */ + 0x66, /* 01100110 */ + 0x06, /* 01100000 */ + 0x0f, /* 11110000 */ + 0x00, /* 00000000 */ + + /* + * 115 0x73 's' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3e, /* 01111100 */ + 0x03, /* 11000000 */ + 0x1e, /* 01111000 */ + 0x30, /* 00001100 */ + 0x1f, /* 11111000 */ + 0x00, /* 00000000 */ + + /* + * 116 0x74 't' + */ + 0x08, /* 00010000 */ + 0x0c, /* 00110000 */ + 0x3e, /* 01111100 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x2c, /* 00110100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* + * 117 0x75 'u' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x6e, /* 01110110 */ + 0x00, /* 00000000 */ + + /* + * 118 0x76 'v' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x1e, /* 01111000 */ + 0x0c, /* 00110000 */ + 0x00, /* 00000000 */ + + /* + * 119 0x77 'w' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x63, /* 11000110 */ + 0x6b, /* 11010110 */ + 0x7f, /* 11111110 */ + 0x7f, /* 11111110 */ + 0x36, /* 01101100 */ + 0x00, /* 00000000 */ + + /* + * 120 0x78 'x' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x63, /* 11000110 */ + 0x36, /* 01101100 */ + 0x1c, /* 00111000 */ + 0x36, /* 01101100 */ + 0x63, /* 11000110 */ + 0x00, /* 00000000 */ + + /* + * 121 0x79 'y' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x3e, /* 01111100 */ + 0x30, /* 00001100 */ + 0x1f, /* 11111000 */ + + /* + * 122 0x7a 'z' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3f, /* 11111100 */ + 0x19, /* 10011000 */ + 0x0c, /* 00110000 */ + 0x26, /* 01100100 */ + 0x3f, /* 11111100 */ + 0x00, /* 00000000 */ + + /* + * 123 0x7b '{' + */ + 0x38, /* 00011100 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x07, /* 11100000 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x38, /* 00011100 */ + 0x00, /* 00000000 */ + + /* + * 124 0x7c '|' + */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* + * 125 0x7d '}' + */ + 0x07, /* 11100000 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x38, /* 00011100 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x07, /* 11100000 */ + 0x00, /* 00000000 */ + + /* + * 126 0x7e '~' + */ + 0x6e, /* 01110110 */ + 0x3b, /* 11011100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 127 0x7f '^?' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 128 0x80 '€' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 129 0x81 '' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 130 0x82 '‚' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 131 0x83 'ƒ' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 132 0x84 '„' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 133 0x85 ' +' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 134 0x86 '†' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 135 0x87 '‡' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 136 0x88 'ˆ' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 137 0x89 '‰' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 138 0x8a 'Š' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 139 0x8b '‹' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 140 0x8c 'Œ' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 141 0x8d '' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 142 0x8e 'Ž' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 143 0x8f '' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 144 0x90 '' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 145 0x91 '‘' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 146 0x92 '’' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 147 0x93 '“' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 148 0x94 '”' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 149 0x95 '•' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 150 0x96 '–' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 151 0x97 '—' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 152 0x98 '˜' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 153 0x99 '™' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 154 0x9a 'š' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 155 0x9b '›' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 156 0x9c 'œ' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 157 0x9d '' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 158 0x9e 'ž' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 159 0x9f 'Ÿ' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 160 0xa0 ' ' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 161 0xa1 '¡' + */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* + * 162 0xa2 '¢' + */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x03, /* 11000000 */ + 0x03, /* 11000000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + + /* + * 163 0xa3 '£' + */ + 0x1c, /* 00111000 */ + 0x36, /* 01101100 */ + 0x26, /* 01100100 */ + 0x0f, /* 11110000 */ + 0x06, /* 01100000 */ + 0x67, /* 11100110 */ + 0x3f, /* 11111100 */ + 0x00, /* 00000000 */ + + /* + * 164 0xa4 '¤' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x63, /* 11000110 */ + 0x3e, /* 01111100 */ + 0x36, /* 01101100 */ + 0x3e, /* 01111100 */ + 0x63, /* 11000110 */ + 0x00, /* 00000000 */ + + /* + * 165 0xa5 '¥' + */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x1e, /* 01111000 */ + 0x3f, /* 11111100 */ + 0x0c, /* 00110000 */ + 0x3f, /* 11111100 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + + /* + * 166 0xa6 '¦' + */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* + * 167 0xa7 '§' + */ + 0x7c, /* 00111110 */ + 0xc6, /* 01100011 */ + 0x1c, /* 00111000 */ + 0x36, /* 01101100 */ + 0x36, /* 01101100 */ + 0x1c, /* 00111000 */ + 0x33, /* 11001100 */ + 0x1e, /* 01111000 */ + + /* + * 168 0xa8 '¨' + */ + 0x33, /* 11001100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 169 0xa9 '©' + */ + 0x3c, /* 00111100 */ + 0x42, /* 01000010 */ + 0x99, /* 10011001 */ + 0x85, /* 10100001 */ + 0x85, /* 10100001 */ + 0x99, /* 10011001 */ + 0x42, /* 01000010 */ + 0x3c, /* 00111100 */ + + /* + * 170 0xaa 'ª' + */ + 0x3c, /* 00111100 */ + 0x36, /* 01101100 */ + 0x36, /* 01101100 */ + 0x7c, /* 00111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 171 0xab '«' + */ + 0x00, /* 00000000 */ + 0xcc, /* 00110011 */ + 0x66, /* 01100110 */ + 0x33, /* 11001100 */ + 0x66, /* 01100110 */ + 0xcc, /* 00110011 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 172 0xac '¬' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3f, /* 11111100 */ + 0x30, /* 00001100 */ + 0x30, /* 00001100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 173 0xad '­' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 174 0xae '®' + */ + 0x3c, /* 00111100 */ + 0x42, /* 01000010 */ + 0x9d, /* 10111001 */ + 0xa5, /* 10100101 */ + 0x9d, /* 10111001 */ + 0xa5, /* 10100101 */ + 0x42, /* 01000010 */ + 0x3c, /* 00111100 */ + + /* + * 175 0xaf '¯' + */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 176 0xb0 '°' + */ + 0x1c, /* 00111000 */ + 0x36, /* 01101100 */ + 0x36, /* 01101100 */ + 0x1c, /* 00111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 177 0xb1 '±' + */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x7e, /* 01111110 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* + * 178 0xb2 '²' + */ + 0x1c, /* 00111000 */ + 0x30, /* 00001100 */ + 0x18, /* 00011000 */ + 0x0c, /* 00110000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 179 0xb3 '³' + */ + 0x1c, /* 00111000 */ + 0x30, /* 00001100 */ + 0x18, /* 00011000 */ + 0x30, /* 00001100 */ + 0x1c, /* 00111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 180 0xb4 '´' + */ + 0x18, /* 00011000 */ + 0x0c, /* 00110000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 181 0xb5 'µ' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3e, /* 01111100 */ + 0x06, /* 01100000 */ + 0x03, /* 11000000 */ + + /* + * 182 0xb6 '¶' + */ + 0xfe, /* 01111111 */ + 0xdb, /* 11011011 */ + 0xdb, /* 11011011 */ + 0xde, /* 01111011 */ + 0xd8, /* 00011011 */ + 0xd8, /* 00011011 */ + 0xd8, /* 00011011 */ + 0x00, /* 00000000 */ + + /* + * 183 0xb7 '·' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 184 0xb8 '¸' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x30, /* 00001100 */ + 0x1e, /* 01111000 */ + + /* + * 185 0xb9 '¹' + */ + 0x08, /* 00010000 */ + 0x0c, /* 00110000 */ + 0x08, /* 00010000 */ + 0x1c, /* 00111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 186 0xba 'º' + */ + 0x1c, /* 00111000 */ + 0x36, /* 01101100 */ + 0x36, /* 01101100 */ + 0x1c, /* 00111000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 187 0xbb '»' + */ + 0x00, /* 00000000 */ + 0x33, /* 11001100 */ + 0x66, /* 01100110 */ + 0xcc, /* 00110011 */ + 0x66, /* 01100110 */ + 0x33, /* 11001100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 188 0xbc '¼' + */ + 0xc3, /* 11000011 */ + 0x63, /* 11000110 */ + 0x33, /* 11001100 */ + 0xbd, /* 10111101 */ + 0xec, /* 00110111 */ + 0xf6, /* 01101111 */ + 0xf3, /* 11001111 */ + 0x03, /* 11000000 */ + + /* + * 189 0xbd '½' + */ + 0xc3, /* 11000011 */ + 0x63, /* 11000110 */ + 0x33, /* 11001100 */ + 0x7b, /* 11011110 */ + 0xcc, /* 00110011 */ + 0x66, /* 01100110 */ + 0x33, /* 11001100 */ + 0xf0, /* 00001111 */ + + /* + * 190 0xbe '¾' + */ + 0x03, /* 11000000 */ + 0xc4, /* 00100011 */ + 0x63, /* 11000110 */ + 0xb4, /* 00101101 */ + 0xdb, /* 11011011 */ + 0xac, /* 00110101 */ + 0xe6, /* 01100111 */ + 0x80, /* 00000001 */ + + /* + * 191 0xbf '¿' + */ + 0x0c, /* 00110000 */ + 0x00, /* 00000000 */ + 0x0c, /* 00110000 */ + 0x06, /* 01100000 */ + 0x03, /* 11000000 */ + 0x33, /* 11001100 */ + 0x1e, /* 01111000 */ + 0x00, /* 00000000 */ + + /* + * 192 0xc0 'À' + */ + 0x07, /* 11100000 */ + 0x00, /* 00000000 */ + 0x1c, /* 00111000 */ + 0x36, /* 01101100 */ + 0x63, /* 11000110 */ + 0x7f, /* 11111110 */ + 0x63, /* 11000110 */ + 0x00, /* 00000000 */ + + /* + * 193 0xc1 'Á' + */ + 0x70, /* 00001110 */ + 0x00, /* 00000000 */ + 0x1c, /* 00111000 */ + 0x36, /* 01101100 */ + 0x63, /* 11000110 */ + 0x7f, /* 11111110 */ + 0x63, /* 11000110 */ + 0x00, /* 00000000 */ + + /* + * 194 0xc2 'Â' + */ + 0x1c, /* 00111000 */ + 0x36, /* 01101100 */ + 0x00, /* 00000000 */ + 0x3e, /* 01111100 */ + 0x63, /* 11000110 */ + 0x7f, /* 11111110 */ + 0x63, /* 11000110 */ + 0x00, /* 00000000 */ + + /* + * 195 0xc3 'Ã' + */ + 0x6e, /* 01110110 */ + 0x3b, /* 11011100 */ + 0x00, /* 00000000 */ + 0x3e, /* 01111100 */ + 0x63, /* 11000110 */ + 0x7f, /* 11111110 */ + 0x63, /* 11000110 */ + 0x00, /* 00000000 */ + + /* + * 196 0xc4 'Ä' + */ + 0x63, /* 11000110 */ + 0x1c, /* 00111000 */ + 0x36, /* 01101100 */ + 0x63, /* 11000110 */ + 0x7f, /* 11111110 */ + 0x63, /* 11000110 */ + 0x63, /* 11000110 */ + 0x00, /* 00000000 */ + + /* + * 197 0xc5 'Å' + */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x00, /* 00000000 */ + 0x1e, /* 01111000 */ + 0x33, /* 11001100 */ + 0x3f, /* 11111100 */ + 0x33, /* 11001100 */ + 0x00, /* 00000000 */ + + /* + * 198 0xc6 'Æ' + */ + 0x7c, /* 00111110 */ + 0x36, /* 01101100 */ + 0x33, /* 11001100 */ + 0x7f, /* 11111110 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x73, /* 11001110 */ + 0x00, /* 00000000 */ + + /* + * 199 0xc7 'Ç' + */ + 0x1e, /* 01111000 */ + 0x33, /* 11001100 */ + 0x03, /* 11000000 */ + 0x33, /* 11001100 */ + 0x1e, /* 01111000 */ + 0x18, /* 00011000 */ + 0x30, /* 00001100 */ + 0x1e, /* 01111000 */ + + /* + * 200 0xc8 'È' + */ + 0x07, /* 11100000 */ + 0x00, /* 00000000 */ + 0x3f, /* 11111100 */ + 0x06, /* 01100000 */ + 0x1e, /* 01111000 */ + 0x06, /* 01100000 */ + 0x3f, /* 11111100 */ + 0x00, /* 00000000 */ + + /* + * 201 0xc9 'É' + */ + 0x38, /* 00011100 */ + 0x00, /* 00000000 */ + 0x3f, /* 11111100 */ + 0x06, /* 01100000 */ + 0x1e, /* 01111000 */ + 0x06, /* 01100000 */ + 0x3f, /* 11111100 */ + 0x00, /* 00000000 */ + + /* + * 202 0xca 'Ê' + */ + 0x0c, /* 00110000 */ + 0x12, /* 01001000 */ + 0x3f, /* 11111100 */ + 0x06, /* 01100000 */ + 0x1e, /* 01111000 */ + 0x06, /* 01100000 */ + 0x3f, /* 11111100 */ + 0x00, /* 00000000 */ + + /* + * 203 0xcb 'Ë' + */ + 0x36, /* 01101100 */ + 0x00, /* 00000000 */ + 0x3f, /* 11111100 */ + 0x06, /* 01100000 */ + 0x1e, /* 01111000 */ + 0x06, /* 01100000 */ + 0x3f, /* 11111100 */ + 0x00, /* 00000000 */ + + /* + * 204 0xcc 'Ì' + */ + 0x07, /* 11100000 */ + 0x00, /* 00000000 */ + 0x1e, /* 01111000 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x1e, /* 01111000 */ + 0x00, /* 00000000 */ + + /* + * 205 0xcd 'Í' + */ + 0x38, /* 00011100 */ + 0x00, /* 00000000 */ + 0x1e, /* 01111000 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x1e, /* 01111000 */ + 0x00, /* 00000000 */ + + /* + * 206 0xce 'Î' + */ + 0x0c, /* 00110000 */ + 0x12, /* 01001000 */ + 0x00, /* 00000000 */ + 0x1e, /* 01111000 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x1e, /* 01111000 */ + 0x00, /* 00000000 */ + + /* + * 207 0xcf 'Ï' + */ + 0x33, /* 11001100 */ + 0x00, /* 00000000 */ + 0x1e, /* 01111000 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x1e, /* 01111000 */ + 0x00, /* 00000000 */ + + /* + * 208 0xd0 'Ð' + */ + 0x3f, /* 11111100 */ + 0x66, /* 01100110 */ + 0x6f, /* 11110110 */ + 0x6f, /* 11110110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3f, /* 11111100 */ + 0x00, /* 00000000 */ + + /* + * 209 0xd1 'Ñ' + */ + 0x3f, /* 11111100 */ + 0x00, /* 00000000 */ + 0x33, /* 11001100 */ + 0x37, /* 11101100 */ + 0x3f, /* 11111100 */ + 0x3b, /* 11011100 */ + 0x33, /* 11001100 */ + 0x00, /* 00000000 */ + + /* + * 210 0xd2 'Ò' + */ + 0x0e, /* 01110000 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* + * 211 0xd3 'Ó' + */ + 0x70, /* 00001110 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* + * 212 0xd4 'Ô' + */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* + * 213 0xd5 'Õ' + */ + 0x6e, /* 01110110 */ + 0x3b, /* 11011100 */ + 0x00, /* 00000000 */ + 0x3e, /* 01111100 */ + 0x63, /* 11000110 */ + 0x63, /* 11000110 */ + 0x3e, /* 01111100 */ + 0x00, /* 00000000 */ + + /* + * 214 0xd6 'Ö' + */ + 0xc3, /* 11000011 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* + * 215 0xd7 '×' + */ + 0x00, /* 00000000 */ + 0x36, /* 01101100 */ + 0x1c, /* 00111000 */ + 0x08, /* 00010000 */ + 0x1c, /* 00111000 */ + 0x36, /* 01101100 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* + * 216 0xd8 'Ø' + */ + 0x5c, /* 00111010 */ + 0x36, /* 01101100 */ + 0x73, /* 11001110 */ + 0x7b, /* 11011110 */ + 0x6f, /* 11110110 */ + 0x36, /* 01101100 */ + 0x1d, /* 10111000 */ + 0x00, /* 00000000 */ + + /* + * 217 0xd9 'Ù' + */ + 0x0e, /* 01110000 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* + * 218 0xda 'Ú' + */ + 0x70, /* 00001110 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* + * 219 0xdb 'Û' + */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* + * 220 0xdc 'Ü' + */ + 0x33, /* 11001100 */ + 0x00, /* 00000000 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x1e, /* 01111000 */ + 0x00, /* 00000000 */ + + /* + * 221 0xdd 'Ý' + */ + 0x70, /* 00001110 */ + 0x00, /* 00000000 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3c, /* 00111100 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* + * 222 0xde 'Þ' + */ + 0x0f, /* 11110000 */ + 0x06, /* 01100000 */ + 0x3e, /* 01111100 */ + 0x66, /* 01100110 */ + 0x66, /* 01100110 */ + 0x3e, /* 01111100 */ + 0x06, /* 01100000 */ + 0x0f, /* 11110000 */ + + /* + * 223 0xdf 'ß' + */ + 0x00, /* 00000000 */ + 0x1e, /* 01111000 */ + 0x33, /* 11001100 */ + 0x1f, /* 11111000 */ + 0x33, /* 11001100 */ + 0x1f, /* 11111000 */ + 0x03, /* 11000000 */ + 0x03, /* 11000000 */ + + /* + * 224 0xe0 'à' + */ + 0x07, /* 11100000 */ + 0x00, /* 00000000 */ + 0x1e, /* 01111000 */ + 0x30, /* 00001100 */ + 0x3e, /* 01111100 */ + 0x33, /* 11001100 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* + * 225 0xe1 'á' + */ + 0x38, /* 00011100 */ + 0x00, /* 00000000 */ + 0x1e, /* 01111000 */ + 0x30, /* 00001100 */ + 0x3e, /* 01111100 */ + 0x33, /* 11001100 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* + * 226 0xe2 'â' + */ + 0x7e, /* 01111110 */ + 0xc3, /* 11000011 */ + 0x3c, /* 00111100 */ + 0x60, /* 00000110 */ + 0x7c, /* 00111110 */ + 0x66, /* 01100110 */ + 0xfc, /* 00111111 */ + 0x00, /* 00000000 */ + + /* + * 227 0xe3 'ã' + */ + 0x6e, /* 01110110 */ + 0x3b, /* 11011100 */ + 0x1e, /* 01111000 */ + 0x30, /* 00001100 */ + 0x3e, /* 01111100 */ + 0x33, /* 11001100 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* + * 228 0xe4 'ä' + */ + 0x33, /* 11001100 */ + 0x00, /* 00000000 */ + 0x1e, /* 01111000 */ + 0x30, /* 00001100 */ + 0x3e, /* 01111100 */ + 0x33, /* 11001100 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* + * 229 0xe5 'å' + */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x1e, /* 01111000 */ + 0x30, /* 00001100 */ + 0x3e, /* 01111100 */ + 0x33, /* 11001100 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* + * 230 0xe6 'æ' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfe, /* 01111111 */ + 0x30, /* 00001100 */ + 0xfe, /* 01111111 */ + 0x33, /* 11001100 */ + 0xfe, /* 01111111 */ + 0x00, /* 00000000 */ + + /* + * 231 0xe7 'ç' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x1e, /* 01111000 */ + 0x03, /* 11000000 */ + 0x03, /* 11000000 */ + 0x1e, /* 01111000 */ + 0x30, /* 00001100 */ + 0x1c, /* 00111000 */ + + /* + * 232 0xe8 'è' + */ + 0x07, /* 11100000 */ + 0x00, /* 00000000 */ + 0x1e, /* 01111000 */ + 0x33, /* 11001100 */ + 0x3f, /* 11111100 */ + 0x03, /* 11000000 */ + 0x1e, /* 01111000 */ + 0x00, /* 00000000 */ + + /* + * 233 0xe9 'é' + */ + 0x38, /* 00011100 */ + 0x00, /* 00000000 */ + 0x1e, /* 01111000 */ + 0x33, /* 11001100 */ + 0x3f, /* 11111100 */ + 0x03, /* 11000000 */ + 0x1e, /* 01111000 */ + 0x00, /* 00000000 */ + + /* + * 234 0xea 'ê' + */ + 0x7e, /* 01111110 */ + 0xc3, /* 11000011 */ + 0x3c, /* 00111100 */ + 0x66, /* 01100110 */ + 0x7e, /* 01111110 */ + 0x06, /* 01100000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* + * 235 0xeb 'ë' + */ + 0x33, /* 11001100 */ + 0x00, /* 00000000 */ + 0x1e, /* 01111000 */ + 0x33, /* 11001100 */ + 0x3f, /* 11111100 */ + 0x03, /* 11000000 */ + 0x1e, /* 01111000 */ + 0x00, /* 00000000 */ + + /* + * 236 0xec 'ì' + */ + 0x07, /* 11100000 */ + 0x00, /* 00000000 */ + 0x0e, /* 01110000 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x1e, /* 01111000 */ + 0x00, /* 00000000 */ + + /* + * 237 0xed 'í' + */ + 0x1c, /* 00111000 */ + 0x00, /* 00000000 */ + 0x0e, /* 01110000 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x1e, /* 01111000 */ + 0x00, /* 00000000 */ + + /* + * 238 0xee 'î' + */ + 0x3e, /* 01111100 */ + 0x63, /* 11000110 */ + 0x1c, /* 00111000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x3c, /* 00111100 */ + 0x00, /* 00000000 */ + + /* + * 239 0xef 'ï' + */ + 0x33, /* 11001100 */ + 0x00, /* 00000000 */ + 0x0e, /* 01110000 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x0c, /* 00110000 */ + 0x1e, /* 01111000 */ + 0x00, /* 00000000 */ + + /* + * 240 0xf0 'ð' + */ + 0x1b, /* 11011000 */ + 0x0e, /* 01110000 */ + 0x1b, /* 11011000 */ + 0x30, /* 00001100 */ + 0x3e, /* 01111100 */ + 0x33, /* 11001100 */ + 0x1e, /* 01111000 */ + 0x00, /* 00000000 */ + + /* + * 241 0xf1 'ñ' + */ + 0x00, /* 00000000 */ + 0x1f, /* 11111000 */ + 0x00, /* 00000000 */ + 0x1f, /* 11111000 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x00, /* 00000000 */ + + /* + * 242 0xf2 'ò' + */ + 0x00, /* 00000000 */ + 0x07, /* 11100000 */ + 0x00, /* 00000000 */ + 0x1e, /* 01111000 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x1e, /* 01111000 */ + 0x00, /* 00000000 */ + + /* + * 243 0xf3 'ó' + */ + 0x00, /* 00000000 */ + 0x38, /* 00011100 */ + 0x00, /* 00000000 */ + 0x1e, /* 01111000 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x1e, /* 01111000 */ + 0x00, /* 00000000 */ + + /* + * 244 0xf4 'ô' + */ + 0x1e, /* 01111000 */ + 0x33, /* 11001100 */ + 0x00, /* 00000000 */ + 0x1e, /* 01111000 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x1e, /* 01111000 */ + 0x00, /* 00000000 */ + + /* + * 245 0xf5 'õ' + */ + 0x6e, /* 01110110 */ + 0x3b, /* 11011100 */ + 0x00, /* 00000000 */ + 0x1e, /* 01111000 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x1e, /* 01111000 */ + 0x00, /* 00000000 */ + + /* + * 246 0xf6 'ö' + */ + 0x00, /* 00000000 */ + 0x33, /* 11001100 */ + 0x00, /* 00000000 */ + 0x1e, /* 01111000 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x1e, /* 01111000 */ + 0x00, /* 00000000 */ + + /* + * 247 0xf7 '÷' + */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + 0x18, /* 00011000 */ + 0x18, /* 00011000 */ + 0x00, /* 00000000 */ + + /* + * 248 0xf8 'ø' + */ + 0x00, /* 00000000 */ + 0x60, /* 00000110 */ + 0x3c, /* 00111100 */ + 0x76, /* 01101110 */ + 0x7e, /* 01111110 */ + 0x6e, /* 01110110 */ + 0x3c, /* 00111100 */ + 0x06, /* 01100000 */ + + /* + * 249 0xf9 'ù' + */ + 0x00, /* 00000000 */ + 0x07, /* 11100000 */ + 0x00, /* 00000000 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* + * 250 0xfa 'ú' + */ + 0x00, /* 00000000 */ + 0x38, /* 00011100 */ + 0x00, /* 00000000 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* + * 251 0xfb 'û' + */ + 0x1e, /* 01111000 */ + 0x33, /* 11001100 */ + 0x00, /* 00000000 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* + * 252 0xfc 'ü' + */ + 0x00, /* 00000000 */ + 0x33, /* 11001100 */ + 0x00, /* 00000000 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x7e, /* 01111110 */ + 0x00, /* 00000000 */ + + /* + * 253 0xfd 'ý' + */ + 0x00, /* 00000000 */ + 0x38, /* 00011100 */ + 0x00, /* 00000000 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x3e, /* 01111100 */ + 0x30, /* 00001100 */ + 0x1f, /* 11111000 */ + + /* + * 254 0xfe 'þ' + */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x06, /* 01100000 */ + 0x3e, /* 01111100 */ + 0x66, /* 01100110 */ + 0x3e, /* 01111100 */ + 0x06, /* 01100000 */ + 0x00, /* 00000000 */ + + /* + * 255 0xff 'ÿ' + */ + 0x00, /* 00000000 */ + 0x33, /* 11001100 */ + 0x00, /* 00000000 */ + 0x33, /* 11001100 */ + 0x33, /* 11001100 */ + 0x3e, /* 01111100 */ + 0x30, /* 00001100 */ + 0x1f, /* 11111000 */ + +}; + +/* ---- Character */ + +struct SDLTest_CharTextureCache +{ + SDL_Renderer *renderer; + SDL_Texture *charTextureCache[256]; + struct SDLTest_CharTextureCache *next; +}; + +/*! +\brief List of per-renderer caches for 8x8 pixel font textures created at runtime. +*/ +static struct SDLTest_CharTextureCache *SDLTest_CharTextureCacheList; + +int SDLTest_DrawCharacter(SDL_Renderer *renderer, int x, int y, Uint32 c) +{ + const Uint32 charWidth = FONT_CHARACTER_SIZE; + const Uint32 charHeight = FONT_CHARACTER_SIZE; + const Uint32 charSize = FONT_CHARACTER_SIZE; + SDL_Rect srect; + SDL_Rect drect; + int result; + Uint32 ix, iy; + const unsigned char *charpos; + Uint32 *curpos; + Uint8 *linepos; + Uint32 pitch; + SDL_Surface *character; + Uint32 ci; + Uint8 r, g, b, a; + struct SDLTest_CharTextureCache *cache; + + /* + * Setup source rectangle + */ + srect.x = 0; + srect.y = 0; + srect.w = charWidth; + srect.h = charHeight; + + /* + * Setup destination rectangle + */ + drect.x = x; + drect.y = y; + drect.w = charWidth; + drect.h = charHeight; + + /* Character index in cache */ + ci = c; + + /* Search for this renderer's cache */ + for (cache = SDLTest_CharTextureCacheList; cache; cache = cache->next) { + if (cache->renderer == renderer) { + break; + } + } + + /* Allocate a new cache for this renderer if needed */ + if (!cache) { + cache = (struct SDLTest_CharTextureCache *)SDL_calloc(1, sizeof(struct SDLTest_CharTextureCache)); + cache->renderer = renderer; + cache->next = SDLTest_CharTextureCacheList; + SDLTest_CharTextureCacheList = cache; + } + + /* + * Create new charWidth x charHeight bitmap surface if not already present. + */ + if (cache->charTextureCache[ci] == NULL) { + /* + * Redraw character into surface + */ + character = SDL_CreateRGBSurface(SDL_SWSURFACE, + charWidth, charHeight, 32, + 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF); + if (!character) { + return -1; + } + + charpos = SDLTest_FontData + ci * charSize; + linepos = (Uint8 *)character->pixels; + pitch = character->pitch; + + /* + * Drawing loop + */ + for (iy = 0; iy < charWidth; iy++) { + curpos = (Uint32 *)linepos; + for (ix = 0; ix < charWidth; ix++) { + if ((*charpos) & (1 << ix)) { + *curpos = 0xffffffff; + } else { + *curpos = 0; + } + ++curpos; + } + linepos += pitch; + ++charpos; + } + + /* Convert temp surface into texture */ + cache->charTextureCache[ci] = SDL_CreateTextureFromSurface(renderer, character); + SDL_FreeSurface(character); + + /* + * Check pointer + */ + if (cache->charTextureCache[ci] == NULL) { + return -1; + } + } + + /* + * Set color + */ + result = 0; + result |= SDL_GetRenderDrawColor(renderer, &r, &g, &b, &a); + result |= SDL_SetTextureColorMod(cache->charTextureCache[ci], r, g, b); + result |= SDL_SetTextureAlphaMod(cache->charTextureCache[ci], a); + + /* + * Draw texture onto destination + */ + result |= SDL_RenderCopy(renderer, cache->charTextureCache[ci], &srect, &drect); + + return result; +} + +/* Gets a unicode value from a UTF-8 encoded string + * Outputs increment to advance the string */ +#define UNKNOWN_UNICODE 0xFFFD +static Uint32 UTF8_getch(const char *src, size_t srclen, int *inc) +{ + const Uint8 *p = (const Uint8 *)src; + size_t left = 0; + size_t save_srclen = srclen; + SDL_bool overlong = SDL_FALSE; + SDL_bool underflow = SDL_FALSE; + Uint32 ch = UNKNOWN_UNICODE; + + if (srclen == 0) { + return UNKNOWN_UNICODE; + } + if (p[0] >= 0xFC) { + if ((p[0] & 0xFE) == 0xFC) { + if (p[0] == 0xFC && (p[1] & 0xFC) == 0x80) { + overlong = SDL_TRUE; + } + ch = (Uint32)(p[0] & 0x01); + left = 5; + } + } else if (p[0] >= 0xF8) { + if ((p[0] & 0xFC) == 0xF8) { + if (p[0] == 0xF8 && (p[1] & 0xF8) == 0x80) { + overlong = SDL_TRUE; + } + ch = (Uint32)(p[0] & 0x03); + left = 4; + } + } else if (p[0] >= 0xF0) { + if ((p[0] & 0xF8) == 0xF0) { + if (p[0] == 0xF0 && (p[1] & 0xF0) == 0x80) { + overlong = SDL_TRUE; + } + ch = (Uint32)(p[0] & 0x07); + left = 3; + } + } else if (p[0] >= 0xE0) { + if ((p[0] & 0xF0) == 0xE0) { + if (p[0] == 0xE0 && (p[1] & 0xE0) == 0x80) { + overlong = SDL_TRUE; + } + ch = (Uint32)(p[0] & 0x0F); + left = 2; + } + } else if (p[0] >= 0xC0) { + if ((p[0] & 0xE0) == 0xC0) { + if ((p[0] & 0xDE) == 0xC0) { + overlong = SDL_TRUE; + } + ch = (Uint32)(p[0] & 0x1F); + left = 1; + } + } else { + if (!(p[0] & 0x80)) { + ch = (Uint32)p[0]; + } + } + --srclen; + while (left > 0 && srclen > 0) { + ++p; + if ((p[0] & 0xC0) != 0x80) { + ch = UNKNOWN_UNICODE; + break; + } + ch <<= 6; + ch |= (p[0] & 0x3F); + --srclen; + --left; + } + if (left > 0) { + underflow = SDL_TRUE; + } + + if (overlong || underflow || + (ch >= 0xD800 && ch <= 0xDFFF) || + (ch == 0xFFFE || ch == 0xFFFF) || ch > 0x10FFFF) { + ch = UNKNOWN_UNICODE; + } + + *inc = (int)(save_srclen - srclen); + + return ch; +} + +#define UTF8_IsTrailingByte(c) ((c) >= 0x80 && (c) <= 0xBF) + +int SDLTest_DrawString(SDL_Renderer *renderer, int x, int y, const char *s) +{ + const Uint32 charWidth = FONT_CHARACTER_SIZE; + int result = 0; + int curx = x; + int cury = y; + size_t len = SDL_strlen(s); + + while (len > 0 && !result) { + int advance = 0; + Uint32 ch = UTF8_getch(s, len, &advance); + if (ch < 256) { + result |= SDLTest_DrawCharacter(renderer, curx, cury, ch); + } + curx += charWidth; + s += advance; + len -= advance; + } + + return result; +} + +SDLTest_TextWindow *SDLTest_TextWindowCreate(int x, int y, int w, int h) +{ + SDLTest_TextWindow *textwin = (SDLTest_TextWindow *)SDL_malloc(sizeof(*textwin)); + + if (!textwin) { + return NULL; + } + + textwin->rect.x = x; + textwin->rect.y = y; + textwin->rect.w = w; + textwin->rect.h = h; + textwin->current = 0; + textwin->numlines = (h / FONT_LINE_HEIGHT); + textwin->lines = (char **)SDL_calloc(textwin->numlines, sizeof(*textwin->lines)); + if (!textwin->lines) { + SDL_free(textwin); + return NULL; + } + return textwin; +} + +void SDLTest_TextWindowDisplay(SDLTest_TextWindow *textwin, SDL_Renderer *renderer) +{ + int i, y; + + for (y = textwin->rect.y, i = 0; i < textwin->numlines; ++i, y += FONT_LINE_HEIGHT) { + if (textwin->lines[i]) { + SDLTest_DrawString(renderer, textwin->rect.x, y, textwin->lines[i]); + } + } +} + +void SDLTest_TextWindowAddText(SDLTest_TextWindow *textwin, const char *fmt, ...) +{ + char text[1024]; + va_list ap; + + va_start(ap, fmt); + (void)SDL_vsnprintf(text, sizeof(text), fmt, ap); + va_end(ap); + + SDLTest_TextWindowAddTextWithLength(textwin, text, SDL_strlen(text)); +} + +void SDLTest_TextWindowAddTextWithLength(SDLTest_TextWindow *textwin, const char *text, size_t len) +{ + size_t existing; + SDL_bool newline = SDL_FALSE; + char *line; + + if (len > 0 && text[len - 1] == '\n') { + --len; + newline = SDL_TRUE; + } + + if (textwin->lines[textwin->current]) { + existing = SDL_strlen(textwin->lines[textwin->current]); + } else { + existing = 0; + } + + if (*text == '\b') { + if (existing) { + while (existing > 1 && UTF8_IsTrailingByte((Uint8)textwin->lines[textwin->current][existing - 1])) { + --existing; + } + --existing; + textwin->lines[textwin->current][existing] = '\0'; + } else if (textwin->current > 0) { + SDL_free(textwin->lines[textwin->current]); + textwin->lines[textwin->current] = NULL; + --textwin->current; + } + return; + } + + line = (char *)SDL_realloc(textwin->lines[textwin->current], existing + len + 1); + if (line) { + SDL_memcpy(&line[existing], text, len); + line[existing + len] = '\0'; + textwin->lines[textwin->current] = line; + if (newline) { + if (textwin->current == textwin->numlines - 1) { + SDL_free(textwin->lines[0]); + SDL_memcpy(&textwin->lines[0], &textwin->lines[1], (textwin->numlines - 1) * sizeof(textwin->lines[1])); + textwin->lines[textwin->current] = NULL; + } else { + ++textwin->current; + } + } + } +} + +void SDLTest_TextWindowClear(SDLTest_TextWindow *textwin) +{ + int i; + + for (i = 0; i < textwin->numlines; ++i) { + if (textwin->lines[i]) { + SDL_free(textwin->lines[i]); + textwin->lines[i] = NULL; + } + } + textwin->current = 0; +} + +void SDLTest_TextWindowDestroy(SDLTest_TextWindow *textwin) +{ + if (textwin) { + SDLTest_TextWindowClear(textwin); + SDL_free(textwin->lines); + SDL_free(textwin); + } +} + +void SDLTest_CleanupTextDrawing(void) +{ + unsigned int i; + struct SDLTest_CharTextureCache *cache, *next; + + cache = SDLTest_CharTextureCacheList; + while (cache) { + for (i = 0; i < SDL_arraysize(cache->charTextureCache); ++i) { + if (cache->charTextureCache[i]) { + SDL_DestroyTexture(cache->charTextureCache[i]); + cache->charTextureCache[i] = NULL; + } + } + + next = cache->next; + SDL_free(cache); + cache = next; + } + + SDLTest_CharTextureCacheList = NULL; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/test/SDL_test_fuzzer.c b/SDL2-2.30.5/src/test/SDL_test_fuzzer.c similarity index 61% rename from SDL2-2.0.12/src/test/SDL_test_fuzzer.c rename to SDL2-2.30.5/src/test/SDL_test_fuzzer.c index 458d934..a04eee0 100644 --- a/SDL2-2.0.12/src/test/SDL_test_fuzzer.c +++ b/SDL2-2.30.5/src/test/SDL_test_fuzzer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -59,8 +59,7 @@ static SDLTest_RandomContext rndContext; * Note: doxygen documentation markup for functions is in the header file. */ -void -SDLTest_FuzzerInit(Uint64 execKey) +void SDLTest_FuzzerInit(Uint64 execKey) { Uint32 a = (execKey >> 32) & 0x00000000FFFFFFFF; Uint32 b = execKey & 0x00000000FFFFFFFF; @@ -69,64 +68,57 @@ SDLTest_FuzzerInit(Uint64 execKey) fuzzerInvocationCounter = 0; } -int -SDLTest_GetFuzzerInvocationCount() +int SDLTest_GetFuzzerInvocationCount() { return fuzzerInvocationCounter; } -Uint8 -SDLTest_RandomUint8() +Uint8 SDLTest_RandomUint8() { fuzzerInvocationCounter++; - return (Uint8) SDLTest_RandomInt(&rndContext) & 0x000000FF; + return (Uint8)SDLTest_RandomInt(&rndContext) & 0x000000FF; } -Sint8 -SDLTest_RandomSint8() +Sint8 SDLTest_RandomSint8() { fuzzerInvocationCounter++; - return (Sint8) SDLTest_RandomInt(&rndContext) & 0x000000FF; + return (Sint8)SDLTest_RandomInt(&rndContext) & 0x000000FF; } -Uint16 -SDLTest_RandomUint16() +Uint16 SDLTest_RandomUint16() { fuzzerInvocationCounter++; - return (Uint16) SDLTest_RandomInt(&rndContext) & 0x0000FFFF; + return (Uint16)SDLTest_RandomInt(&rndContext) & 0x0000FFFF; } -Sint16 -SDLTest_RandomSint16() +Sint16 SDLTest_RandomSint16() { fuzzerInvocationCounter++; - return (Sint16) SDLTest_RandomInt(&rndContext) & 0x0000FFFF; + return (Sint16)SDLTest_RandomInt(&rndContext) & 0x0000FFFF; } -Sint32 -SDLTest_RandomSint32() +Sint32 SDLTest_RandomSint32() { fuzzerInvocationCounter++; - return (Sint32) SDLTest_RandomInt(&rndContext); + return (Sint32)SDLTest_RandomInt(&rndContext); } -Uint32 -SDLTest_RandomUint32() +Uint32 SDLTest_RandomUint32() { fuzzerInvocationCounter++; - return (Uint32) SDLTest_RandomInt(&rndContext); + return (Uint32)SDLTest_RandomInt(&rndContext); } -Uint64 -SDLTest_RandomUint64() +Uint64 SDLTest_RandomUint64() { - union { + union + { Uint64 v64; Uint32 v32[2]; } value; @@ -140,10 +132,10 @@ SDLTest_RandomUint64() return value.v64; } -Sint64 -SDLTest_RandomSint64() +Sint64 SDLTest_RandomSint64() { - union { + union + { Uint64 v64; Uint32 v32[2]; } value; @@ -157,21 +149,18 @@ SDLTest_RandomSint64() return (Sint64)value.v64; } - - -Sint32 -SDLTest_RandomIntegerInRange(Sint32 pMin, Sint32 pMax) +Sint32 SDLTest_RandomIntegerInRange(Sint32 pMin, Sint32 pMax) { Sint64 min = pMin; Sint64 max = pMax; Sint64 temp; Sint64 number; - if(pMin > pMax) { + if (pMin > pMax) { temp = min; min = max; max = temp; - } else if(pMin == pMax) { + } else if (pMin == pMax) { return (Sint32)min; } @@ -204,48 +193,47 @@ SDLTest_RandomIntegerInRange(Sint32 pMin, Sint32 pMax) * * \returns Returns a random boundary value for the domain or 0 in case of error */ -static Uint64 -SDLTest_GenerateUnsignedBoundaryValues(const Uint64 maxValue, Uint64 boundary1, Uint64 boundary2, SDL_bool validDomain) +static Uint64 SDLTest_GenerateUnsignedBoundaryValues(const Uint64 maxValue, Uint64 boundary1, Uint64 boundary2, SDL_bool validDomain) { - Uint64 b1, b2; + Uint64 b1, b2; Uint64 delta; Uint64 tempBuf[4]; Uint8 index; - /* Maybe swap */ + /* Maybe swap */ if (boundary1 > boundary2) { b1 = boundary2; b2 = boundary1; } else { b1 = boundary1; b2 = boundary2; - } + } index = 0; if (validDomain == SDL_TRUE) { - if (b1 == b2) { - return b1; - } + if (b1 == b2) { + return b1; + } - /* Generate up to 4 values within bounds */ - delta = b2 - b1; - if (delta < 4) { - do { + /* Generate up to 4 values within bounds */ + delta = b2 - b1; + if (delta < 4) { + do { tempBuf[index] = b1 + index; index++; - } while (index < delta); - } else { - tempBuf[index] = b1; - index++; - tempBuf[index] = b1 + 1; - index++; - tempBuf[index] = b2 - 1; - index++; - tempBuf[index] = b2; - index++; - } + } while (index < delta); } else { - /* Generate up to 2 values outside of bounds */ + tempBuf[index] = b1; + index++; + tempBuf[index] = b1 + 1; + index++; + tempBuf[index] = b2 - 1; + index++; + tempBuf[index] = b2; + index++; + } + } else { + /* Generate up to 2 values outside of bounds */ if (b1 > 0) { tempBuf[index] = b1 - 1; index++; @@ -266,49 +254,44 @@ SDLTest_GenerateUnsignedBoundaryValues(const Uint64 maxValue, Uint64 boundary1, return tempBuf[SDLTest_RandomUint8() % index]; } - -Uint8 -SDLTest_RandomUint8BoundaryValue(Uint8 boundary1, Uint8 boundary2, SDL_bool validDomain) +Uint8 SDLTest_RandomUint8BoundaryValue(Uint8 boundary1, Uint8 boundary2, SDL_bool validDomain) { /* max value for Uint8 */ const Uint64 maxValue = UCHAR_MAX; return (Uint8)SDLTest_GenerateUnsignedBoundaryValues(maxValue, - (Uint64) boundary1, (Uint64) boundary2, - validDomain); + (Uint64)boundary1, (Uint64)boundary2, + validDomain); } -Uint16 -SDLTest_RandomUint16BoundaryValue(Uint16 boundary1, Uint16 boundary2, SDL_bool validDomain) +Uint16 SDLTest_RandomUint16BoundaryValue(Uint16 boundary1, Uint16 boundary2, SDL_bool validDomain) { /* max value for Uint16 */ const Uint64 maxValue = USHRT_MAX; return (Uint16)SDLTest_GenerateUnsignedBoundaryValues(maxValue, - (Uint64) boundary1, (Uint64) boundary2, - validDomain); + (Uint64)boundary1, (Uint64)boundary2, + validDomain); } -Uint32 -SDLTest_RandomUint32BoundaryValue(Uint32 boundary1, Uint32 boundary2, SDL_bool validDomain) +Uint32 SDLTest_RandomUint32BoundaryValue(Uint32 boundary1, Uint32 boundary2, SDL_bool validDomain) { - /* max value for Uint32 */ - #if ((ULONG_MAX) == (UINT_MAX)) - const Uint64 maxValue = ULONG_MAX; - #else - const Uint64 maxValue = UINT_MAX; - #endif +/* max value for Uint32 */ +#if ((ULONG_MAX) == (UINT_MAX)) + const Uint64 maxValue = ULONG_MAX; +#else + const Uint64 maxValue = UINT_MAX; +#endif return (Uint32)SDLTest_GenerateUnsignedBoundaryValues(maxValue, - (Uint64) boundary1, (Uint64) boundary2, - validDomain); + (Uint64)boundary1, (Uint64)boundary2, + validDomain); } -Uint64 -SDLTest_RandomUint64BoundaryValue(Uint64 boundary1, Uint64 boundary2, SDL_bool validDomain) +Uint64 SDLTest_RandomUint64BoundaryValue(Uint64 boundary1, Uint64 boundary2, SDL_bool validDomain) { /* max value for Uint64 */ const Uint64 maxValue = UINT64_MAX; return SDLTest_GenerateUnsignedBoundaryValues(maxValue, - boundary1, boundary2, - validDomain); + boundary1, boundary2, + validDomain); } /* ! @@ -336,48 +319,47 @@ SDLTest_RandomUint64BoundaryValue(Uint64 boundary1, Uint64 boundary2, SDL_bool v * * \returns Returns a random boundary value for the domain or 0 in case of error */ -static Sint64 -SDLTest_GenerateSignedBoundaryValues(const Sint64 minValue, const Sint64 maxValue, Sint64 boundary1, Sint64 boundary2, SDL_bool validDomain) +static Sint64 SDLTest_GenerateSignedBoundaryValues(const Sint64 minValue, const Sint64 maxValue, Sint64 boundary1, Sint64 boundary2, SDL_bool validDomain) { - Sint64 b1, b2; + Sint64 b1, b2; Sint64 delta; Sint64 tempBuf[4]; Uint8 index; - /* Maybe swap */ + /* Maybe swap */ if (boundary1 > boundary2) { b1 = boundary2; b2 = boundary1; } else { b1 = boundary1; b2 = boundary2; - } + } index = 0; if (validDomain == SDL_TRUE) { - if (b1 == b2) { - return b1; - } + if (b1 == b2) { + return b1; + } - /* Generate up to 4 values within bounds */ - delta = b2 - b1; - if (delta < 4) { - do { + /* Generate up to 4 values within bounds */ + delta = b2 - b1; + if (delta < 4) { + do { tempBuf[index] = b1 + index; index++; - } while (index < delta); - } else { - tempBuf[index] = b1; - index++; - tempBuf[index] = b1 + 1; - index++; - tempBuf[index] = b2 - 1; - index++; - tempBuf[index] = b2; - index++; - } + } while (index < delta); } else { - /* Generate up to 2 values outside of bounds */ + tempBuf[index] = b1; + index++; + tempBuf[index] = b1 + 1; + index++; + tempBuf[index] = b2 - 1; + index++; + tempBuf[index] = b2; + index++; + } + } else { + /* Generate up to 2 values outside of bounds */ if (b1 > minValue) { tempBuf[index] = b1 - 1; index++; @@ -398,72 +380,65 @@ SDLTest_GenerateSignedBoundaryValues(const Sint64 minValue, const Sint64 maxValu return tempBuf[SDLTest_RandomUint8() % index]; } - -Sint8 -SDLTest_RandomSint8BoundaryValue(Sint8 boundary1, Sint8 boundary2, SDL_bool validDomain) +Sint8 SDLTest_RandomSint8BoundaryValue(Sint8 boundary1, Sint8 boundary2, SDL_bool validDomain) { /* min & max values for Sint8 */ const Sint64 maxValue = SCHAR_MAX; const Sint64 minValue = SCHAR_MIN; return (Sint8)SDLTest_GenerateSignedBoundaryValues(minValue, maxValue, - (Sint64) boundary1, (Sint64) boundary2, - validDomain); + (Sint64)boundary1, (Sint64)boundary2, + validDomain); } -Sint16 -SDLTest_RandomSint16BoundaryValue(Sint16 boundary1, Sint16 boundary2, SDL_bool validDomain) +Sint16 SDLTest_RandomSint16BoundaryValue(Sint16 boundary1, Sint16 boundary2, SDL_bool validDomain) { /* min & max values for Sint16 */ const Sint64 maxValue = SHRT_MAX; const Sint64 minValue = SHRT_MIN; return (Sint16)SDLTest_GenerateSignedBoundaryValues(minValue, maxValue, - (Sint64) boundary1, (Sint64) boundary2, - validDomain); + (Sint64)boundary1, (Sint64)boundary2, + validDomain); } -Sint32 -SDLTest_RandomSint32BoundaryValue(Sint32 boundary1, Sint32 boundary2, SDL_bool validDomain) +Sint32 SDLTest_RandomSint32BoundaryValue(Sint32 boundary1, Sint32 boundary2, SDL_bool validDomain) { - /* min & max values for Sint32 */ - #if ((ULONG_MAX) == (UINT_MAX)) - const Sint64 maxValue = LONG_MAX; - const Sint64 minValue = LONG_MIN; - #else - const Sint64 maxValue = INT_MAX; - const Sint64 minValue = INT_MIN; - #endif +/* min & max values for Sint32 */ +#if ((ULONG_MAX) == (UINT_MAX)) + const Sint64 maxValue = LONG_MAX; + const Sint64 minValue = LONG_MIN; +#else + const Sint64 maxValue = INT_MAX; + const Sint64 minValue = INT_MIN; +#endif return (Sint32)SDLTest_GenerateSignedBoundaryValues(minValue, maxValue, - (Sint64) boundary1, (Sint64) boundary2, - validDomain); + (Sint64)boundary1, (Sint64)boundary2, + validDomain); } -Sint64 -SDLTest_RandomSint64BoundaryValue(Sint64 boundary1, Sint64 boundary2, SDL_bool validDomain) +Sint64 SDLTest_RandomSint64BoundaryValue(Sint64 boundary1, Sint64 boundary2, SDL_bool validDomain) { /* min & max values for Sint64 */ const Sint64 maxValue = INT64_MAX; const Sint64 minValue = INT64_MIN; return SDLTest_GenerateSignedBoundaryValues(minValue, maxValue, - boundary1, boundary2, - validDomain); + boundary1, boundary2, + validDomain); } -float -SDLTest_RandomUnitFloat() +float SDLTest_RandomUnitFloat() { - return SDLTest_RandomUint32() / (float) UINT_MAX; + return SDLTest_RandomUint32() / (float)UINT_MAX; } -float -SDLTest_RandomFloat() +float SDLTest_RandomFloat() { - return (float) (SDLTest_RandomUnitDouble() * 2.0 * (double)FLT_MAX - (double)(FLT_MAX)); + return (float)(SDLTest_RandomUnitDouble() * 2.0 * (double)FLT_MAX - (double)(FLT_MAX)); } double SDLTest_RandomUnitDouble() { - return (double) (SDLTest_RandomUint64() >> 11) * (1.0/9007199254740992.0); + return (double)(SDLTest_RandomUint64() >> 11) * (1.0 / 9007199254740992.0); } double @@ -472,8 +447,8 @@ SDLTest_RandomDouble() double r = 0.0; double s = 1.0; do { - s /= UINT_MAX + 1.0; - r += (double)SDLTest_RandomInt(&rndContext) * s; + s /= UINT_MAX + 1.0; + r += (double)SDLTest_RandomInt(&rndContext) * s; } while (s > DBL_EPSILON); fuzzerInvocationCounter++; @@ -481,46 +456,43 @@ SDLTest_RandomDouble() return r; } - -char * -SDLTest_RandomAsciiString() +char *SDLTest_RandomAsciiString() { return SDLTest_RandomAsciiStringWithMaximumLength(255); } -char * -SDLTest_RandomAsciiStringWithMaximumLength(int maxLength) +char *SDLTest_RandomAsciiStringWithMaximumLength(int maxLength) { int size; - if(maxLength < 1) { - SDL_InvalidParamError("maxLength"); + if (maxLength < 1) { + SDL_InvalidParamError("maxLength"); return NULL; } size = (SDLTest_RandomUint32() % (maxLength + 1)); - + if (size == 0) { + size = 1; + } return SDLTest_RandomAsciiStringOfSize(size); } -char * -SDLTest_RandomAsciiStringOfSize(int size) +char *SDLTest_RandomAsciiStringOfSize(int size) { char *string; int counter; - - if(size < 1) { - SDL_InvalidParamError("size"); + if (size < 1) { + SDL_InvalidParamError("size"); return NULL; } string = (char *)SDL_malloc((size + 1) * sizeof(char)); - if (string==NULL) { - return NULL; - } + if (!string) { + return NULL; + } - for(counter = 0; counter < size; ++counter) { + for (counter = 0; counter < size; ++counter) { string[counter] = (char)SDLTest_RandomIntegerInRange(32, 126); } diff --git a/SDL2-2.0.12/src/test/SDL_test_harness.c b/SDL2-2.30.5/src/test/SDL_test_harness.c similarity index 70% rename from SDL2-2.0.12/src/test/SDL_test_harness.c rename to SDL2-2.30.5/src/test/SDL_test_harness.c index 942ed38..460e694 100644 --- a/SDL2-2.0.12/src/test/SDL_test_harness.c +++ b/SDL2-2.30.5/src/test/SDL_test_harness.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -41,17 +41,16 @@ static Uint32 SDLTest_TestCaseTimeout = 3600; /** -* Generates a random run seed string for the harness. The generated seed -* will contain alphanumeric characters (0-9A-Z). -* -* Note: The returned string needs to be deallocated by the caller. -* -* \param length The length of the seed string to generate -* -* \returns The generated seed string -*/ -char * -SDLTest_GenerateRunSeed(const int length) + * Generates a random run seed string for the harness. The generated seed + * will contain alphanumeric characters (0-9A-Z). + * + * Note: The returned string needs to be deallocated by the caller. + * + * \param length The length of the seed string to generate + * + * \returns The generated seed string + */ +char *SDLTest_GenerateRunSeed(const int length) { char *seed = NULL; SDLTest_RandomContext randomContext; @@ -65,7 +64,7 @@ SDLTest_GenerateRunSeed(const int length) /* Allocate output buffer */ seed = (char *)SDL_malloc((length + 1) * sizeof(char)); - if (seed == NULL) { + if (!seed) { SDLTest_LogError("SDL_malloc for run seed output buffer failed."); SDL_Error(SDL_ENOMEM); return NULL; @@ -75,7 +74,7 @@ SDLTest_GenerateRunSeed(const int length) SDLTest_RandomInitTime(&randomContext); for (counter = 0; counter < length; counter++) { unsigned int number = SDLTest_Random(&randomContext); - char ch = (char) (number % (91 - 48)) + 48; + char ch = (char)(number % (91 - 48)) + 48; if (ch >= 58 && ch <= 64) { ch = 65; } @@ -87,18 +86,17 @@ SDLTest_GenerateRunSeed(const int length) } /** -* Generates an execution key for the fuzzer. -* -* \param runSeed The run seed to use -* \param suiteName The name of the test suite -* \param testName The name of the test -* \param iteration The iteration count -* -* \returns The generated execution key to initialize the fuzzer with. -* -*/ -static Uint64 -SDLTest_GenerateExecKey(const char *runSeed, char *suiteName, char *testName, int iteration) + * Generates an execution key for the fuzzer. + * + * \param runSeed The run seed to use + * \param suiteName The name of the test suite + * \param testName The name of the test + * \param iteration The iteration count + * + * \returns The generated execution key to initialize the fuzzer with. + * + */ +static Uint64 SDLTest_GenerateExecKey(const char *runSeed, const char *suiteName, const char *testName, int iteration) { SDLTest_Md5Context md5Context; Uint64 *keys; @@ -110,17 +108,17 @@ SDLTest_GenerateExecKey(const char *runSeed, char *suiteName, char *testName, in size_t entireStringLength; char *buffer; - if (runSeed == NULL || runSeed[0] == '\0') { + if (!runSeed || runSeed[0] == '\0') { SDLTest_LogError("Invalid runSeed string."); return -1; } - if (suiteName == NULL || suiteName[0] == '\0') { + if (!suiteName || suiteName[0] == '\0') { SDLTest_LogError("Invalid suiteName string."); return -1; } - if (testName == NULL || testName[0] == '\0') { + if (!testName || testName[0] == '\0') { SDLTest_LogError("Invalid testName string."); return -1; } @@ -132,25 +130,25 @@ SDLTest_GenerateExecKey(const char *runSeed, char *suiteName, char *testName, in /* Convert iteration number into a string */ SDL_memset(iterationString, 0, sizeof(iterationString)); - SDL_snprintf(iterationString, sizeof(iterationString) - 1, "%d", iteration); + (void)SDL_snprintf(iterationString, sizeof(iterationString) - 1, "%d", iteration); /* Combine the parameters into single string */ runSeedLength = SDL_strlen(runSeed); suiteNameLength = SDL_strlen(suiteName); testNameLength = SDL_strlen(testName); iterationStringLength = SDL_strlen(iterationString); - entireStringLength = runSeedLength + suiteNameLength + testNameLength + iterationStringLength + 1; + entireStringLength = runSeedLength + suiteNameLength + testNameLength + iterationStringLength + 1; buffer = (char *)SDL_malloc(entireStringLength); - if (buffer == NULL) { + if (!buffer) { SDLTest_LogError("Failed to allocate buffer for execKey generation."); SDL_Error(SDL_ENOMEM); return 0; } - SDL_snprintf(buffer, entireStringLength, "%s%s%s%d", runSeed, suiteName, testName, iteration); + (void)SDL_snprintf(buffer, entireStringLength, "%s%s%s%d", runSeed, suiteName, testName, iteration); /* Hash string and use half of the digest as 64bit exec key */ SDLTest_Md5Init(&md5Context); - SDLTest_Md5Update(&md5Context, (unsigned char *)buffer, (unsigned int) entireStringLength); + SDLTest_Md5Update(&md5Context, (unsigned char *)buffer, (unsigned int)entireStringLength); SDLTest_Md5Final(&md5Context); SDL_free(buffer); keys = (Uint64 *)md5Context.digest; @@ -159,22 +157,21 @@ SDLTest_GenerateExecKey(const char *runSeed, char *suiteName, char *testName, in } /** -* \brief Set timeout handler for test. -* -* Note: SDL_Init(SDL_INIT_TIMER) will be called if it wasn't done so before. -* -* \param timeout Timeout interval in seconds. -* \param callback Function that will be called after timeout has elapsed. -* -* \return Timer id or -1 on failure. -*/ -static SDL_TimerID -SDLTest_SetTestTimeout(int timeout, void (*callback)(void)) + * \brief Set timeout handler for test. + * + * Note: SDL_Init(SDL_INIT_TIMER) will be called if it wasn't done so before. + * + * \param timeout Timeout interval in seconds. + * \param callback Function that will be called after timeout has elapsed. + * + * \return Timer id or -1 on failure. + */ +static SDL_TimerID SDLTest_SetTestTimeout(int timeout, void(SDLCALL *callback)(void)) { Uint32 timeoutInMilliseconds; SDL_TimerID timerID; - if (callback == NULL) { + if (!callback) { SDLTest_LogError("Timeout callback can't be NULL"); return -1; } @@ -204,44 +201,40 @@ SDLTest_SetTestTimeout(int timeout, void (*callback)(void)) } /** -* \brief Timeout handler. Aborts test run and exits harness process. -*/ + * \brief Timeout handler. Aborts test run and exits harness process. + */ #if defined(__WATCOMC__) #pragma aux SDLTest_BailOut aborts; #endif -static SDL_NORETURN void -SDLTest_BailOut(void) +static SDL_NORETURN void SDLCALL SDLTest_BailOut(void) { SDLTest_LogError("TestCaseTimeout timer expired. Aborting test run."); exit(TEST_ABORTED); /* bail out from the test */ } /** -* \brief Execute a test using the given execution key. -* -* \param testSuite Suite containing the test case. -* \param testCase Case to execute. -* \param execKey Execution key for the fuzzer. -* \param forceTestRun Force test to run even if test was disabled in suite. -* -* \returns Test case result. -*/ -static int -SDLTest_RunTest(SDLTest_TestSuiteReference *testSuite, const SDLTest_TestCaseReference *testCase, Uint64 execKey, SDL_bool forceTestRun) + * \brief Execute a test using the given execution key. + * + * \param testSuite Suite containing the test case. + * \param testCase Case to execute. + * \param execKey Execution key for the fuzzer. + * \param forceTestRun Force test to run even if test was disabled in suite. + * + * \returns Test case result. + */ +static int SDLTest_RunTest(SDLTest_TestSuiteReference *testSuite, const SDLTest_TestCaseReference *testCase, Uint64 execKey, SDL_bool forceTestRun) { SDL_TimerID timer = 0; int testCaseResult = 0; int testResult = 0; int fuzzerCount; - if (testSuite==NULL || testCase==NULL || testSuite->name==NULL || testCase->name==NULL) - { + if (!testSuite || !testCase || !testSuite->name || !testCase->name) { SDLTest_LogError("Setup failure: testSuite or testCase references NULL"); return TEST_RESULT_SETUP_FAILURE; } - if (!testCase->enabled && forceTestRun == SDL_FALSE) - { + if (!testCase->enabled && forceTestRun == SDL_FALSE) { SDLTest_Log(SDLTEST_FINAL_RESULT_FORMAT, "Test", testCase->name, "Skipped (Disabled)"); return TEST_RESULT_SKIPPED; } @@ -316,7 +309,7 @@ SDLTest_RunTest(SDLTest_TestSuiteReference *testSuite, const SDLTest_TestCaseRef } /* Prints summary of all suites/tests contained in the given reference */ -#if 0 +#if 0 static void SDLTest_LogTestSuiteSummary(SDLTest_TestSuiteReference *testSuites) { int suiteCounter; @@ -326,7 +319,7 @@ static void SDLTest_LogTestSuiteSummary(SDLTest_TestSuiteReference *testSuites) /* Loop over all suites */ suiteCounter = 0; - while(&testSuites[suiteCounter]) { + while (&testSuites[suiteCounter]) { testSuite=&testSuites[suiteCounter]; suiteCounter++; SDLTest_Log("Test Suite %i - %s\n", suiteCounter, @@ -334,8 +327,7 @@ static void SDLTest_LogTestSuiteSummary(SDLTest_TestSuiteReference *testSuites) /* Loop over all test cases */ testCounter = 0; - while(testSuite->testCases[testCounter]) - { + while (testSuite->testCases[testCounter]) { testCase=(SDLTest_TestCaseReference *)testSuite->testCases[testCounter]; testCounter++; SDLTest_Log(" Test Case %i - %s: %s", testCounter, @@ -349,24 +341,24 @@ static void SDLTest_LogTestSuiteSummary(SDLTest_TestSuiteReference *testSuites) /* Gets a timer value in seconds */ static float GetClock() { - float currentClock = clock() / (float) CLOCKS_PER_SEC; + float currentClock = SDL_GetPerformanceCounter() / (float)SDL_GetPerformanceFrequency(); return currentClock; } /** -* \brief Execute a test suite using the given run seed and execution key. -* -* The filter string is matched to the suite name (full comparison) to select a single suite, -* or if no suite matches, it is matched to the test names (full comparison) to select a single test. -* -* \param testSuites Suites containing the test case. -* \param userRunSeed Custom run seed provided by user, or NULL to autogenerate one. -* \param userExecKey Custom execution key provided by user, or 0 to autogenerate one. -* \param filter Filter specification. NULL disables. Case sensitive. -* \param testIterations Number of iterations to run each test case. -* -* \returns Test run result; 0 when all tests passed, 1 if any tests failed. -*/ + * \brief Execute a test suite using the given run seed and execution key. + * + * The filter string is matched to the suite name (full comparison) to select a single suite, + * or if no suite matches, it is matched to the test names (full comparison) to select a single test. + * + * \param testSuites Suites containing the test case. + * \param userRunSeed Custom run seed provided by user, or NULL to autogenerate one. + * \param userExecKey Custom execution key provided by user, or 0 to autogenerate one. + * \param filter Filter specification. NULL disables. Case sensitive. + * \param testIterations Number of iterations to run each test case. + * + * \returns Test run result; 0 when all tests passed, 1 if any tests failed. + */ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *userRunSeed, Uint64 userExecKey, const char *filter, int testIterations) { int totalNumberOfTests = 0; @@ -377,8 +369,8 @@ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *user SDLTest_TestSuiteReference *testSuite; const SDLTest_TestCaseReference *testCase; const char *runSeed = NULL; - char *currentSuiteName; - char *currentTestName; + const char *currentSuiteName; + const char *currentTestName; Uint64 execKey; float runStartSeconds; float suiteStartSeconds; @@ -388,20 +380,21 @@ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *user float testEndSeconds; float runtime; int suiteFilter = 0; - char *suiteFilterName = NULL; + const char *suiteFilterName = NULL; int testFilter = 0; - char *testFilterName = NULL; - SDL_bool forceTestRun = SDL_FALSE; + const char *testFilterName = NULL; + SDL_bool forceTestRun = SDL_FALSE; int testResult = 0; int runResult = 0; - Uint32 totalTestFailedCount = 0; - Uint32 totalTestPassedCount = 0; - Uint32 totalTestSkippedCount = 0; - Uint32 testFailedCount = 0; - Uint32 testPassedCount = 0; - Uint32 testSkippedCount = 0; - Uint32 countSum = 0; + int totalTestFailedCount = 0; + int totalTestPassedCount = 0; + int totalTestSkippedCount = 0; + int testFailedCount = 0; + int testPassedCount = 0; + int testSkippedCount = 0; + int countSum = 0; const SDLTest_TestCaseReference **failedTests; + char generatedSeed[16 + 1]; /* Sanitize test iterations */ if (testIterations < 1) { @@ -409,17 +402,19 @@ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *user } /* Generate run see if we don't have one already */ - if (userRunSeed == NULL || userRunSeed[0] == '\0') { - runSeed = SDLTest_GenerateRunSeed(16); - if (runSeed == NULL) { + if (!userRunSeed || userRunSeed[0] == '\0') { + char *tmp = SDLTest_GenerateRunSeed(16); + if (!tmp) { SDLTest_LogError("Generating a random seed failed"); return 2; } + SDL_memcpy(generatedSeed, tmp, 16 + 1); + SDL_free(tmp); + runSeed = generatedSeed; } else { runSeed = userRunSeed; } - /* Reset per-run counters */ totalTestFailedCount = 0; totalTestPassedCount = 0; @@ -431,35 +426,39 @@ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *user /* Log run with fuzzer parameters */ SDLTest_Log("::::: Test Run /w seed '%s' started\n", runSeed); - /* Count the total number of tests */ + /* Count the total number of tests */ suiteCounter = 0; while (testSuites[suiteCounter]) { testSuite = testSuites[suiteCounter]; suiteCounter++; testCounter = 0; - while (testSuite->testCases[testCounter]) - { + while (testSuite->testCases[testCounter]) { testCounter++; - totalNumberOfTests++; - } - } + totalNumberOfTests++; + } + } - /* Pre-allocate an array for tracking failed tests (potentially all test cases) */ - failedTests = (const SDLTest_TestCaseReference **)SDL_malloc(totalNumberOfTests * sizeof(SDLTest_TestCaseReference *)); - if (failedTests == NULL) { - SDLTest_LogError("Unable to allocate cache for failed tests"); - SDL_Error(SDL_ENOMEM); - return -1; - } + if (totalNumberOfTests == 0) { + SDLTest_LogError("No tests to run?"); + return -1; + } + + /* Pre-allocate an array for tracking failed tests (potentially all test cases) */ + failedTests = (const SDLTest_TestCaseReference **)SDL_malloc(totalNumberOfTests * sizeof(SDLTest_TestCaseReference *)); + if (!failedTests) { + SDLTest_LogError("Unable to allocate cache for failed tests"); + SDL_Error(SDL_ENOMEM); + return -1; + } /* Initialize filtering */ - if (filter != NULL && filter[0] != '\0') { + if (filter && filter[0] != '\0') { /* Loop over all suites to check if we have a filter match */ suiteCounter = 0; while (testSuites[suiteCounter] && suiteFilter == 0) { testSuite = testSuites[suiteCounter]; suiteCounter++; - if (testSuite->name != NULL && SDL_strcmp(filter, testSuite->name) == 0) { + if (testSuite->name && SDL_strcasecmp(filter, testSuite->name) == 0) { /* Matched a suite name */ suiteFilter = 1; suiteFilterName = testSuite->name; @@ -469,11 +468,10 @@ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *user /* Within each suite, loop over all test cases to check if we have a filter match */ testCounter = 0; - while (testSuite->testCases[testCounter] && testFilter == 0) - { + while (testSuite->testCases[testCounter] && testFilter == 0) { testCase = testSuite->testCases[testCounter]; testCounter++; - if (testCase->name != NULL && SDL_strcmp(filter, testCase->name) == 0) { + if (testCase->name && SDL_strcasecmp(filter, testCase->name) == 0) { /* Matched a test name */ suiteFilter = 1; suiteFilterName = testSuite->name; @@ -487,26 +485,38 @@ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *user if (suiteFilter == 0 && testFilter == 0) { SDLTest_LogError("Filter '%s' did not match any test suite/case.", filter); + for (suiteCounter = 0; testSuites[suiteCounter]; ++suiteCounter) { + testSuite = testSuites[suiteCounter]; + if (testSuite->name) { + SDLTest_Log("Test suite: %s", testSuite->name); + } + + /* Within each suite, loop over all test cases to check if we have a filter match */ + for (testCounter = 0; testSuite->testCases[testCounter]; ++testCounter) { + testCase = testSuite->testCases[testCounter]; + SDLTest_Log(" test: %s%s", testCase->name, testCase->enabled ? "" : " (disabled)"); + } + } SDLTest_Log("Exit code: 2"); - SDL_free((void *) failedTests); + SDL_free((void *)failedTests); return 2; } } /* Loop over all suites */ suiteCounter = 0; - while(testSuites[suiteCounter]) { + while (testSuites[suiteCounter]) { testSuite = testSuites[suiteCounter]; currentSuiteName = (testSuite->name ? testSuite->name : SDLTEST_INVALID_NAME_FORMAT); suiteCounter++; /* Filter suite if flag set and we have a name */ - if (suiteFilter == 1 && suiteFilterName != NULL && testSuite->name != NULL && - SDL_strcmp(suiteFilterName, testSuite->name) != 0) { - /* Skip suite */ - SDLTest_Log("===== Test Suite %i: '%s' skipped\n", - suiteCounter, - currentSuiteName); + if (suiteFilter == 1 && suiteFilterName && testSuite->name && + SDL_strcasecmp(suiteFilterName, testSuite->name) != 0) { + /* Skip suite */ + SDLTest_Log("===== Test Suite %i: '%s' skipped\n", + suiteCounter, + currentSuiteName); } else { /* Reset per-suite counters */ @@ -519,30 +529,29 @@ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *user /* Log suite started */ SDLTest_Log("===== Test Suite %i: '%s' started\n", - suiteCounter, - currentSuiteName); + suiteCounter, + currentSuiteName); /* Loop over all test cases */ testCounter = 0; - while(testSuite->testCases[testCounter]) - { + while (testSuite->testCases[testCounter]) { testCase = testSuite->testCases[testCounter]; currentTestName = (testCase->name ? testCase->name : SDLTEST_INVALID_NAME_FORMAT); testCounter++; /* Filter tests if flag set and we have a name */ - if (testFilter == 1 && testFilterName != NULL && testCase->name != NULL && - SDL_strcmp(testFilterName, testCase->name) != 0) { - /* Skip test */ - SDLTest_Log("===== Test Case %i.%i: '%s' skipped\n", - suiteCounter, - testCounter, - currentTestName); + if (testFilter == 1 && testFilterName && testCase->name && + SDL_strcasecmp(testFilterName, testCase->name) != 0) { + /* Skip test */ + SDLTest_Log("===== Test Case %i.%i: '%s' skipped\n", + suiteCounter, + testCounter, + currentTestName); } else { /* Override 'disabled' flag if we specified a test filter (i.e. force run for debugging) */ if (testFilter == 1 && !testCase->enabled) { SDLTest_Log("Force run of disabled test since test filter was set"); - forceTestRun = SDL_TRUE; + forceTestRun = SDL_TRUE; } /* Take time - test start */ @@ -550,18 +559,17 @@ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *user /* Log test started */ SDLTest_Log("----- Test Case %i.%i: '%s' started", - suiteCounter, - testCounter, - currentTestName); - if (testCase->description != NULL && testCase->description[0] != '\0') { + suiteCounter, + testCounter, + currentTestName); + if (testCase->description && testCase->description[0] != '\0') { SDLTest_Log("Test Description: '%s'", - (testCase->description) ? testCase->description : SDLTEST_INVALID_NAME_FORMAT); + (testCase->description) ? testCase->description : SDLTEST_INVALID_NAME_FORMAT); } /* Loop over all iterations */ iterationCounter = 0; - while(iterationCounter < testIterations) - { + while (iterationCounter < testIterations) { iterationCounter++; if (userExecKey != 0) { @@ -571,7 +579,7 @@ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *user } SDLTest_Log("Test Iteration %i: execKey %" SDL_PRIu64, iterationCounter, execKey); - testResult = SDLTest_RunTest(testSuite, testCase, execKey, forceTestRun); + testResult = SDLTest_RunTest(testSuite, testCase, execKey, forceTestRun); if (testResult == TEST_RESULT_PASSED) { testPassedCount++; @@ -588,7 +596,9 @@ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *user /* Take time - test end */ testEndSeconds = GetClock(); runtime = testEndSeconds - testStartSeconds; - if (runtime < 0.0f) runtime = 0.0f; + if (runtime < 0.0f) { + runtime = 0.0f; + } if (testIterations > 1) { /* Log test runtime */ @@ -608,7 +618,7 @@ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *user SDLTest_LogError(SDLTEST_FINAL_RESULT_FORMAT, "Test", currentTestName, "Failed"); break; case TEST_RESULT_NO_ASSERT: - SDLTest_LogError(SDLTEST_FINAL_RESULT_FORMAT,"Test", currentTestName, "No Asserts"); + SDLTest_LogError(SDLTEST_FINAL_RESULT_FORMAT, "Test", currentTestName, "No Asserts"); break; } @@ -623,45 +633,42 @@ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *user /* Take time - suite end */ suiteEndSeconds = GetClock(); runtime = suiteEndSeconds - suiteStartSeconds; - if (runtime < 0.0f) runtime = 0.0f; + if (runtime < 0.0f) { + runtime = 0.0f; + } /* Log suite runtime */ SDLTest_Log("Total Suite runtime: %.1f sec", runtime); /* Log summary and final Suite result */ countSum = testPassedCount + testFailedCount + testSkippedCount; - if (testFailedCount == 0) - { + if (testFailedCount == 0) { SDLTest_Log(SDLTEST_LOG_SUMMARY_FORMAT, "Suite", countSum, testPassedCount, testFailedCount, testSkippedCount); SDLTest_Log(SDLTEST_FINAL_RESULT_FORMAT, "Suite", currentSuiteName, "Passed"); - } - else - { + } else { SDLTest_LogError(SDLTEST_LOG_SUMMARY_FORMAT, "Suite", countSum, testPassedCount, testFailedCount, testSkippedCount); SDLTest_LogError(SDLTEST_FINAL_RESULT_FORMAT, "Suite", currentSuiteName, "Failed"); } - } } /* Take time - run end */ runEndSeconds = GetClock(); runtime = runEndSeconds - runStartSeconds; - if (runtime < 0.0f) runtime = 0.0f; + if (runtime < 0.0f) { + runtime = 0.0f; + } /* Log total runtime */ SDLTest_Log("Total Run runtime: %.1f sec", runtime); /* Log summary and final run result */ countSum = totalTestPassedCount + totalTestFailedCount + totalTestSkippedCount; - if (totalTestFailedCount == 0) - { + if (totalTestFailedCount == 0) { runResult = 0; SDLTest_Log(SDLTEST_LOG_SUMMARY_FORMAT, "Run", countSum, totalTestPassedCount, totalTestFailedCount, totalTestSkippedCount); SDLTest_Log(SDLTEST_FINAL_RESULT_FORMAT, "Run /w seed", runSeed, "Passed"); - } - else - { + } else { runResult = 1; SDLTest_LogError(SDLTEST_LOG_SUMMARY_FORMAT, "Run", countSum, totalTestPassedCount, totalTestFailedCount, totalTestSkippedCount); SDLTest_LogError(SDLTEST_FINAL_RESULT_FORMAT, "Run /w seed", runSeed, "Failed"); @@ -671,10 +678,10 @@ int SDLTest_RunSuites(SDLTest_TestSuiteReference *testSuites[], const char *user if (failedNumberOfTests > 0) { SDLTest_Log("Harness input to repro failures:"); for (testCounter = 0; testCounter < failedNumberOfTests; testCounter++) { - SDLTest_Log(" --seed %s --filter %s", runSeed, failedTests[testCounter]->name); + SDLTest_Log(" --seed %s --filter %s", runSeed, failedTests[testCounter]->name); } } - SDL_free((void *) failedTests); + SDL_free((void *)failedTests); SDLTest_Log("Exit code: %d", runResult); return runResult; diff --git a/SDL2-2.30.5/src/test/SDL_test_imageBlit.c b/SDL2-2.30.5/src/test/SDL_test_imageBlit.c new file mode 100644 index 0000000..bf1cf2f --- /dev/null +++ b/SDL2-2.30.5/src/test/SDL_test_imageBlit.c @@ -0,0 +1,1666 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_test.h" + +/* GIMP RGB C-Source image dump (blit.c) */ + +static const SDLTest_SurfaceImage_t SDLTest_imageBlit = { + 80, + 60, + 3, + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377" + "\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0" + "\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377" + "\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377" + "\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0" + "\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0" + "\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0" + "\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0" + "\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0" + "\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0" + "\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0" + "\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377" + "\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377" + "\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377" + "\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377" + "\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377" + "\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377" + "\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0" + "\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0" + "\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377" + "\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377" + "\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0" + "\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0" + "\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0" + "\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0" + "\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377" + "\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377" + "\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0" + "\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0" + "\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0" + "\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0" + "\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377" + "\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377" + "\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0" + "\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0" + "\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0" + "\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0" + "\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377" + "\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377" + "\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0" + "\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0" + "\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0" + "\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0" + "\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377" + "\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377" + "\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0" + "\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0" + "\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0" + "\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0" + "\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377" + "\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377" + "\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0" + "\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0" + "\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0" + "\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0" + "\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377" + "\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377" + "\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0" + "\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0" + "\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\0\0\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377" + "\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377" + "\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377" + "\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377" + "\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377" + "\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377" + "\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377" + "\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377" + "\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377" + "\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377" + "\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377" + "\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377" + "\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377" + "\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\377" + "\377\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377" + "\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377" + "\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377" + "\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377" + "\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377" + "\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377" + "\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377" + "\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377" + "\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377" + "\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377" + "\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377" + "\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377" + "\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377" + "\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377" + "\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377" + "\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377" + "\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377" + "\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377" + "\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377" + "\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377" + "\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377" + "\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377" + "\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377" + "\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377" + "\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377" + "\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0" + "\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0" + "\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0" + "\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0" + "\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0" + "\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377" + "\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377" + "\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377" + "\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377" + "\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377" + "\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377" + "\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0" + "\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0" + "\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0" + "\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0" + "\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0" + "\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0" + "\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0" + "\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377" + "\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377" + "\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0" + "\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377" + "\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377" + "\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0" + "\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377" + "\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377" + "\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0" + "\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0" + "\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377" + "\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377" + "\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0" + "\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377" + "\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377" + "\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0" + "\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0" + "\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0" + "\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0" + "\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0" + "\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\0\377\377\0" + "\377\377\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377" + "\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0" + "\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0" + "\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377" + "\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377" + "\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0", +}; + +/** + * \brief Returns the Blit test image as SDL_Surface. + */ +SDL_Surface *SDLTest_ImageBlit() +{ + SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormatFrom( + (void *)SDLTest_imageBlit.pixel_data, + SDLTest_imageBlit.width, + SDLTest_imageBlit.height, + SDLTest_imageBlit.bytes_per_pixel * 8, + SDLTest_imageBlit.width * SDLTest_imageBlit.bytes_per_pixel, + SDL_PIXELFORMAT_RGB24); + return surface; +} + +static const SDLTest_SurfaceImage_t SDLTest_imageBlitColor = { + 80, + 60, + 3, + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\24\0\0\24\0\0\0\0\0\0" + "\0\0(\0\0(\0\0\0\0\0\0\0\0<\0\0<\0\0\0\0\0\0\0\0P\0\0P\0\0\0\0\0\0\0\0d\0" + "\0d\0\0\0\0\0\0\0\0x\0\0x\0\0\0\0\0\0\0\0\214\0\0\214\0\0\0\0\0\0\0\0\240" + "\0\0\240\0\0\0\0\0\0\0\0\264\0\0\264\0\0\0\0\0\0\0\0\310\0\0\310\0\0\0\0" + "\0\0\0\0\334\0\0\334\0\0\0\0\0\0\0\0\360\0\0\360\0\0\360\0\0\360\0\0\360" + "\0\0\360\0\0\360\0\0\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\24\0\0\24\0\0\24\0\0\0\0\0(\0\0" + "(\0\0(\0\0\0\0\0<\0\0<\0\0<\0\0\0\0\0P\0\0P\0\0P\0\0\0\0\0d\0\0d\0\0d\0\0" + "\0\0\0x\0\0x\0\0x\0\0\0\0\0\214\0\0\214\0\0\214\0\0\0\0\0\240\0\0\240\0\0" + "\240\0\0\0\0\0\264\0\0\264\0\0\264\0\0\0\0\0\310\0\0\310\0\0\310\0\0\0\0" + "\0\334\0\0\334\0\0\334\0\0\0\0\0\360\0\0\360\0\0\360\0\0\360\0\0\360\0\0" + "\360\0\0\360\0\0\360\0\0\360\0\0\360\0\0\360\0\0\360\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\24\0\0\24\0\0\24\0\0\0" + "\0\0(\0\0(\0\0(\0\0\0\0\0<\0\0<\0\0<\0\0\0\0\0P\0\0P\0\0P\0\0\0\0\0d\0\0" + "d\0\0d\0\0\0\0\0x\0\0x\0\0x\0\0\0\0\0\214\0\0\214\0\0\214\0\0\0\0\0\240\0" + "\0\240\0\0\240\0\0\0\0\0\264\0\0\264\0\0\264\0\0\0\0\0\310\0\0\310\0\0\310" + "\0\0\0\0\0\334\0\0\334\0\0\334\0\0\0\0\0\360\0\0\360\0\0\360\0\0\360\0\0" + "\360\0\0\360\0\0\360\0\0\360\0\0\360\0\0\360\0\0\360\0\0\360\0\0\360\0\0" + "\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\360\0\0\360\0\0\360\0\0\360\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0$\0\0$\0\0\0\0\0\0\0\0$\24\0" + "$\24\0\0\0\0\0\0\0$(\0$(\0\0\0\0\0\0\0$<\0$<\0\0\0\0\0\0\0$P\0$P\0\0\0\0" + "\0\0\0$d\0$d\0\0\0\0\0\0\0$x\0$x\0\0\0\0\0\0\0$\214\0$\214\0\0\0\0\0\0\0" + "$\240\0$\240\0\0\0\0\0\0\0$\264\0$\264\0\0\0\0\0\0\0$\310\0$\310\0\0\0\0" + "\0\0\0$\334\0$\334\0\0\0\0\0\0\0$\360\0$\360\0$\360\0$\360\0$\360\0$\360" + "\0$\360\0$\360\0\0\0\0\0\0\0\0\360\0\0\360\0\0\360\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0$\0\0$\0\0$\0\0\0\0\0$\24\0$\24\0$\24\0\0\0\0$(\0$(\0$(\0\0\0\0" + "$<\0$<\0$<\0\0\0\0$P\0$P\0$P\0\0\0\0$d\0$d\0$d\0\0\0\0$x\0$x\0$x\0\0\0\0" + "$\214\0$\214\0$\214\0\0\0\0$\240\0$\240\0$\240\0\0\0\0$\264\0$\264\0$\264" + "\0\0\0\0$\310\0$\310\0$\310\0\0\0\0$\334\0$\334\0$\334\0\0\0\0$\360\0$\360" + "\0$\360\0$\360\0$\360\0$\360\0$\360\0$\360\0$\360\0$\360\0$\360\0$\360\0" + "\0\0\0\0\360\0\0\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0$\0\0$\0\0$\0\0\0\0\0$\24\0" + "$\24\0$\24\0\0\0\0$(\0$(\0$(\0\0\0\0$<\0$<\0$<\0\0\0\0$P\0$P\0$P\0\0\0\0" + "$d\0$d\0$d\0\0\0\0$x\0$x\0$x\0\0\0\0$\214\0$\214\0$\214\0\0\0\0$\240\0$\240" + "\0$\240\0\0\0\0$\264\0$\264\0$\264\0\0\0\0$\310\0$\310\0$\310\0\0\0\0$\334" + "\0$\334\0$\334\0\0\0\0$\360\0$\360\0$\360\0$\360\0$\360\0$\360\0$\360\0$" + "\360\0$\360\0$\360\0$\360\0$\360\0$\360\0$\360\0\0\0\0\0\360\0\0\360\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0$\0\0$\0\0$\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0$\360\0$\360\0$\360\0$\360\0\0\0\0\0\360\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0$\0\0$\0\0$\0\0\0\0" + "\0\0\0\0H\0\0H\0\0\0\0\0\0\0\0H\24\0H\24\0\0\0\0\0\0\0H(\0H(\0\0\0\0\0\0" + "\0H<\0H<\0\0\0\0\0\0\0HP\0HP\0\0\0\0\0\0\0Hd\0Hd\0\0\0\0\0\0\0Hx\0Hx\0\0" + "\0\0\0\0\0H\214\0H\214\0\0\0\0\0\0\0H\240\0H\240\0\0\0\0\0\0\0H\264\0H\264" + "\0\0\0\0\0\0\0H\310\0H\310\0\0\0\0\0\0\0H\334\0H\334\0\0\0\0\0\0\0H\360\0" + "H\360\0H\360\0H\360\0H\360\0H\360\0H\360\0H\360\0\0\0\0\0\0\0$\360\0$\360" + "\0$\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0$\0\0$\0\0\0\0\0H\0\0H\0\0H\0\0\0\0\0H\24\0H\24\0H\24" + "\0\0\0\0H(\0H(\0H(\0\0\0\0H<\0H<\0H<\0\0\0\0HP\0HP\0HP\0\0\0\0Hd\0Hd\0Hd" + "\0\0\0\0Hx\0Hx\0Hx\0\0\0\0H\214\0H\214\0H\214\0\0\0\0H\240\0H\240\0H\240" + "\0\0\0\0H\264\0H\264\0H\264\0\0\0\0H\310\0H\310\0H\310\0\0\0\0H\334\0H\334" + "\0H\334\0\0\0\0H\360\0H\360\0H\360\0H\360\0H\360\0H\360\0H\360\0H\360\0H" + "\360\0H\360\0H\360\0H\360\0\0\0\0$\360\0$\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0$\0\0$\0\0\0\0\0H\0\0" + "H\0\0H\0\0\0\0\0H\24\0H\24\0H\24\0\0\0\0H(\0H(\0H(\0\0\0\0H<\0H<\0H<\0\0" + "\0\0HP\0HP\0HP\0\0\0\0Hd\0Hd\0Hd\0\0\0\0Hx\0Hx\0Hx\0\0\0\0H\214\0H\214\0" + "H\214\0\0\0\0H\240\0H\240\0H\240\0\0\0\0H\264\0H\264\0H\264\0\0\0\0H\310" + "\0H\310\0H\310\0\0\0\0H\334\0H\334\0H\334\0\0\0\0H\360\0H\360\0H\360\0H\360" + "\0H\360\0H\360\0H\360\0H\360\0H\360\0H\360\0H\360\0H\360\0H\360\0H\360\0" + "\0\0\0$\360\0$\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0$\0\0\0\0\0H\0\0H\0\0H\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0H\360\0H\360\0H\360\0H\360\0\0\0\0$\360\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0H\0\0H\0\0H\0\0\0\0\0\0\0\0l\0\0l\0\0\0\0\0\0\0\0l\24\0l\24\0\0\0\0\0\0" + "\0l(\0l(\0\0\0\0\0\0\0l<\0l<\0\0\0\0\0\0\0lP\0lP\0\0\0\0\0\0\0ld\0ld\0\0" + "\0\0\0\0\0lx\0lx\0\0\0\0\0\0\0l\214\0l\214\0\0\0\0\0\0\0l\240\0l\240\0\0" + "\0\0\0\0\0l\264\0l\264\0\0\0\0\0\0\0l\310\0l\310\0\0\0\0\0\0\0l\334\0l\334" + "\0\0\0\0\0\0\0l\360\0l\360\0l\360\0l\360\0l\360\0l\360\0l\360\0l\360\0\0" + "\0\0\0\0\0H\360\0H\360\0H\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0H\0\0H\0\0\0\0\0l\0\0l\0\0l\0\0" + "\0\0\0l\24\0l\24\0l\24\0\0\0\0l(\0l(\0l(\0\0\0\0l<\0l<\0l<\0\0\0\0lP\0lP" + "\0lP\0\0\0\0ld\0ld\0ld\0\0\0\0lx\0lx\0lx\0\0\0\0l\214\0l\214\0l\214\0\0\0" + "\0l\240\0l\240\0l\240\0\0\0\0l\264\0l\264\0l\264\0\0\0\0l\310\0l\310\0l\310" + "\0\0\0\0l\334\0l\334\0l\334\0\0\0\0l\360\0l\360\0l\360\0l\360\0l\360\0l\360" + "\0l\360\0l\360\0l\360\0l\360\0l\360\0l\360\0\0\0\0H\360\0H\360\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0H\0" + "\0H\0\0\0\0\0l\0\0l\0\0l\0\0\0\0\0l\24\0l\24\0l\24\0\0\0\0l(\0l(\0l(\0\0" + "\0\0l<\0l<\0l<\0\0\0\0lP\0lP\0lP\0\0\0\0ld\0ld\0ld\0\0\0\0lx\0lx\0lx\0\0" + "\0\0l\214\0l\214\0l\214\0\0\0\0l\240\0l\240\0l\240\0\0\0\0l\264\0l\264\0" + "l\264\0\0\0\0l\310\0l\310\0l\310\0\0\0\0l\334\0l\334\0l\334\0\0\0\0l\360" + "\0l\360\0l\360\0l\360\0l\360\0l\360\0l\360\0l\360\0l\360\0l\360\0l\360\0" + "l\360\0l\360\0l\360\0\0\0\0H\360\0H\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0H\0\0\0\0\0l\0\0l\0\0l\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0l\360\0l\360\0l\360\0l\360" + "\0\0\0\0H\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0l\0\0l\0\0l\0\0\0\0\0\0\0\0\220\0\0\220\0\0\0\0\0\0\0" + "\0\220\24\0\220\24\0\0\0\0\0\0\0\220(\0\220(\0\0\0\0\0\0\0\220<\0\220<\0" + "\0\0\0\0\0\0\220P\0\220P\0\0\0\0\0\0\0\220d\0\220d\0\0\0\0\0\0\0\220x\0\220" + "x\0\0\0\0\0\0\0\220\214\0\220\214\0\0\0\0\0\0\0\220\240\0\220\240\0\0\0\0" + "\0\0\0\220\264\0\220\264\0\0\0\0\0\0\0\220\310\0\220\310\0\0\0\0\0\0\0\220" + "\334\0\220\334\0\0\0\0\0\0\0\220\360\0\220\360\0\220\360\0\220\360\0\220" + "\360\0\220\360\0\220\360\0\220\360\0\0\0\0\0\0\0l\360\0l\360\0l\360\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0l\0\0l\0\0\0\0\0\220\0\0\220\0\0\220\0\0\0\0\0\220\24\0\220\24\0" + "\220\24\0\0\0\0\220(\0\220(\0\220(\0\0\0\0\220<\0\220<\0\220<\0\0\0\0\220" + "P\0\220P\0\220P\0\0\0\0\220d\0\220d\0\220d\0\0\0\0\220x\0\220x\0\220x\0\0" + "\0\0\220\214\0\220\214\0\220\214\0\0\0\0\220\240\0\220\240\0\220\240\0\0" + "\0\0\220\264\0\220\264\0\220\264\0\0\0\0\220\310\0\220\310\0\220\310\0\0" + "\0\0\220\334\0\220\334\0\220\334\0\0\0\0\220\360\0\220\360\0\220\360\0\220" + "\360\0\220\360\0\220\360\0\220\360\0\220\360\0\220\360\0\220\360\0\220\360" + "\0\220\360\0\0\0\0l\360\0l\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0l\0\0l\0\0\0\0\0\220\0\0\220\0\0\220" + "\0\0\0\0\0\220\24\0\220\24\0\220\24\0\0\0\0\220(\0\220(\0\220(\0\0\0\0\220" + "<\0\220<\0\220<\0\0\0\0\220P\0\220P\0\220P\0\0\0\0\220d\0\220d\0\220d\0\0" + "\0\0\220x\0\220x\0\220x\0\0\0\0\220\214\0\220\214\0\220\214\0\0\0\0\220\240" + "\0\220\240\0\220\240\0\0\0\0\220\264\0\220\264\0\220\264\0\0\0\0\220\310" + "\0\220\310\0\220\310\0\0\0\0\220\334\0\220\334\0\220\334\0\0\0\0\220\360" + "\0\220\360\0\220\360\0\220\360\0\220\360\0\220\360\0\220\360\0\220\360\0" + "\220\360\0\220\360\0\220\360\0\220\360\0\220\360\0\220\360\0\0\0\0l\360\0" + "l\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0l\0\0\0\0\0\220\0\0\220\0\0\220\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\220\360\0\220\360\0\220\360\0\220\360\0\0\0\0l\360" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\220\0\0\220\0\0\220\0\0\0\0\0\0\0\0\264\0\0\264\0\0\0\0\0\0\0\0" + "\264\24\0\264\24\0\0\0\0\0\0\0\264(\0\264(\0\0\0\0\0\0\0\264<\0\264<\0\0" + "\0\0\0\0\0\264P\0\264P\0\0\0\0\0\0\0\264d\0\264d\0\0\0\0\0\0\0\264x\0\264" + "x\0\0\0\0\0\0\0\264\214\0\264\214\0\0\0\0\0\0\0\264\240\0\264\240\0\0\0\0" + "\0\0\0\264\264\0\264\264\0\0\0\0\0\0\0\264\310\0\264\310\0\0\0\0\0\0\0\264" + "\334\0\264\334\0\0\0\0\0\0\0\264\360\0\264\360\0\264\360\0\264\360\0\264" + "\360\0\264\360\0\264\360\0\264\360\0\0\0\0\0\0\0\220\360\0\220\360\0\220" + "\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\220\0\0\220\0\0\0\0\0\264\0\0\264\0\0\264\0\0\0\0\0\264" + "\24\0\264\24\0\264\24\0\0\0\0\264(\0\264(\0\264(\0\0\0\0\264<\0\264<\0\264" + "<\0\0\0\0\264P\0\264P\0\264P\0\0\0\0\264d\0\264d\0\264d\0\0\0\0\264x\0\264" + "x\0\264x\0\0\0\0\264\214\0\264\214\0\264\214\0\0\0\0\264\240\0\264\240\0" + "\264\240\0\0\0\0\264\264\0\264\264\0\264\264\0\0\0\0\264\310\0\264\310\0" + "\264\310\0\0\0\0\264\334\0\264\334\0\264\334\0\0\0\0\264\360\0\264\360\0" + "\264\360\0\264\360\0\264\360\0\264\360\0\264\360\0\264\360\0\264\360\0\264" + "\360\0\264\360\0\264\360\0\0\0\0\220\360\0\220\360\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\220\0\0\220\0" + "\0\0\0\0\264\0\0\264\0\0\264\0\0\0\0\0\264\24\0\264\24\0\264\24\0\0\0\0\264" + "(\0\264(\0\264(\0\0\0\0\264<\0\264<\0\264<\0\0\0\0\264P\0\264P\0\264P\0\0" + "\0\0\264d\0\264d\0\264d\0\0\0\0\264x\0\264x\0\264x\0\0\0\0\264\214\0\264" + "\214\0\264\214\0\0\0\0\264\240\0\264\240\0\264\240\0\0\0\0\264\264\0\264" + "\264\0\264\264\0\0\0\0\264\310\0\264\310\0\264\310\0\0\0\0\264\334\0\264" + "\334\0\264\334\0\0\0\0\264\360\0\264\360\0\264\360\0\264\360\0\264\360\0" + "\264\360\0\264\360\0\264\360\0\264\360\0\264\360\0\264\360\0\264\360\0\264" + "\360\0\264\360\0\0\0\0\220\360\0\220\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\220\0\0\0\0\0\264\0\0\264\0\0" + "\264\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\264\360\0" + "\264\360\0\264\360\0\264\360\0\0\0\0\220\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\264\0\0\264\0\0\264" + "\0\0\0\0\0\0\0\0\330\0\0\330\0\0\0\0\0\0\0\0\330\24\0\330\24\0\0\0\0\0\0" + "\0\330(\0\330(\0\0\0\0\0\0\0\330<\0\330<\0\0\0\0\0\0\0\330P\0\330P\0\0\0" + "\0\0\0\0\330d\0\330d\0\0\0\0\0\0\0\330x\0\330x\0\0\0\0\0\0\0\330\214\0\330" + "\214\0\0\0\0\0\0\0\330\240\0\330\240\0\0\0\0\0\0\0\330\264\0\330\264\0\0" + "\0\0\0\0\0\330\310\0\330\310\0\0\0\0\0\0\0\330\334\0\330\334\0\0\0\0\0\0" + "\0\330\360\0\330\360\0\330\360\0\330\360\0\330\360\0\330\360\0\330\360\0" + "\330\360\0\0\0\0\0\0\0\264\360\0\264\360\0\264\360\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\264\0\0" + "\264\0\0\0\0\0\330\0\0\330\0\0\330\0\0\0\0\0\330\24\0\330\24\0\330\24\0\0" + "\0\0\330(\0\330(\0\330(\0\0\0\0\330<\0\330<\0\330<\0\0\0\0\330P\0\330P\0" + "\330P\0\0\0\0\330d\0\330d\0\330d\0\0\0\0\330x\0\330x\0\330x\0\0\0\0\330\214" + "\0\330\214\0\330\214\0\0\0\0\330\240\0\330\240\0\330\240\0\0\0\0\330\264" + "\0\330\264\0\330\264\0\0\0\0\330\310\0\330\310\0\330\310\0\0\0\0\330\334" + "\0\330\334\0\330\334\0\0\0\0\330\360\0\330\360\0\330\360\0\330\360\0\330" + "\360\0\330\360\0\330\360\0\330\360\0\330\360\0\330\360\0\330\360\0\330\360" + "\0\0\0\0\264\360\0\264\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\264\0\0\264\0\0\0\0\0\330\0\0\330\0\0" + "\330\0\0\0\0\0\330\24\0\330\24\0\330\24\0\0\0\0\330(\0\330(\0\330(\0\0\0" + "\0\330<\0\330<\0\330<\0\0\0\0\330P\0\330P\0\330P\0\0\0\0\330d\0\330d\0\330" + "d\0\0\0\0\330x\0\330x\0\330x\0\0\0\0\330\214\0\330\214\0\330\214\0\0\0\0" + "\330\240\0\330\240\0\330\240\0\0\0\0\330\264\0\330\264\0\330\264\0\0\0\0" + "\330\310\0\330\310\0\330\310\0\0\0\0\330\334\0\330\334\0\330\334\0\0\0\0" + "\330\360\0\330\360\0\330\360\0\330\360\0\330\360\0\330\360\0\330\360\0\330" + "\360\0\330\360\0\330\360\0\330\360\0\330\360\0\330\360\0\330\360\0\0\0\0" + "\264\360\0\264\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\264\0\0\0\0\0\330\0\0\330\0\0\330\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\330\360\0\330\360\0\330\360\0\330" + "\360\0\0\0\0\264\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\330\0\0\330\0\0\330\0\0\0\0\0\0\0\0\374\0\0" + "\374\0\0\0\0\0\0\0\0\374\24\0\374\24\0\0\0\0\0\0\0\374(\0\374(\0\0\0\0\0" + "\0\0\374<\0\374<\0\0\0\0\0\0\0\374P\0\374P\0\0\0\0\0\0\0\374d\0\374d\0\0" + "\0\0\0\0\0\374x\0\374x\0\0\0\0\0\0\0\374\214\0\374\214\0\0\0\0\0\0\0\374" + "\240\0\374\240\0\0\0\0\0\0\0\374\264\0\374\264\0\0\0\0\0\0\0\374\310\0\374" + "\310\0\0\0\0\0\0\0\374\334\0\374\334\0\0\0\0\0\0\0\374\360\0\374\360\0\374" + "\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\0\0\0\0\0\0\330" + "\360\0\330\360\0\330\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\330\0\0\330\0\0\0\0\0\374\0\0\374" + "\0\0\374\0\0\0\0\0\374\24\0\374\24\0\374\24\0\0\0\0\374(\0\374(\0\374(\0" + "\0\0\0\374<\0\374<\0\374<\0\0\0\0\374P\0\374P\0\374P\0\0\0\0\374d\0\374d" + "\0\374d\0\0\0\0\374x\0\374x\0\374x\0\0\0\0\374\214\0\374\214\0\374\214\0" + "\0\0\0\374\240\0\374\240\0\374\240\0\0\0\0\374\264\0\374\264\0\374\264\0" + "\0\0\0\374\310\0\374\310\0\374\310\0\0\0\0\374\334\0\374\334\0\374\334\0" + "\0\0\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360" + "\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\0\0\0\330\360\0\330" + "\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\330\0\0\330\0\0\0\0\0\374\0\0\374\0\0\374\0\0\0\0\0\374\24\0" + "\374\24\0\374\24\0\0\0\0\374(\0\374(\0\374(\0\0\0\0\374<\0\374<\0\374<\0" + "\0\0\0\374P\0\374P\0\374P\0\0\0\0\374d\0\374d\0\374d\0\0\0\0\374x\0\374x" + "\0\374x\0\0\0\0\374\214\0\374\214\0\374\214\0\0\0\0\374\240\0\374\240\0\374" + "\240\0\0\0\0\374\264\0\374\264\0\374\264\0\0\0\0\374\310\0\374\310\0\374" + "\310\0\0\0\0\374\334\0\374\334\0\374\334\0\0\0\0\374\360\0\374\360\0\374" + "\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360" + "\0\374\360\0\374\360\0\374\360\0\374\360\0\0\0\0\330\360\0\330\360\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\330" + "\0\0\0\0\0\374\0\0\374\0\0\374\0\0\0\0\0\374\24\0\374\24\0\374\24\0\0\0\0" + "\374(\0\374(\0\374(\0\0\0\0\374<\0\374<\0\374<\0\0\0\0\374P\0\374P\0\374" + "P\0\0\0\0\374d\0\374d\0\374d\0\0\0\0\374x\0\374x\0\374x\0\0\0\0\374\214\0" + "\374\214\0\374\214\0\0\0\0\374\240\0\374\240\0\374\240\0\0\0\0\374\264\0" + "\374\264\0\374\264\0\0\0\0\374\310\0\374\310\0\374\310\0\0\0\0\374\334\0" + "\374\334\0\374\334\0\0\0\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360" + "\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0" + "\374\360\0\374\360\0\374\360\0\374\360\0\0\0\0\330\360\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\374\0\0\374" + "\0\0\374\0\0\0\0\0\374\24\0\374\24\0\374\24\0\0\0\0\374(\0\374(\0\374(\0" + "\0\0\0\374<\0\374<\0\374<\0\0\0\0\374P\0\374P\0\374P\0\0\0\0\374d\0\374d" + "\0\374d\0\0\0\0\374x\0\374x\0\374x\0\0\0\0\374\214\0\374\214\0\374\214\0" + "\0\0\0\374\240\0\374\240\0\374\240\0\0\0\0\374\264\0\374\264\0\374\264\0" + "\0\0\0\374\310\0\374\310\0\374\310\0\0\0\0\374\334\0\374\334\0\374\334\0" + "\0\0\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360" + "\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0" + "\374\360\0\374\360\0\374\360\0\374\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\374\0\0\374\0\0\374" + "\0\0\0\0\0\374\24\0\374\24\0\374\24\0\0\0\0\374(\0\374(\0\374(\0\0\0\0\374" + "<\0\374<\0\374<\0\0\0\0\374P\0\374P\0\374P\0\0\0\0\374d\0\374d\0\374d\0\0" + "\0\0\374x\0\374x\0\374x\0\0\0\0\374\214\0\374\214\0\374\214\0\0\0\0\374\240" + "\0\374\240\0\374\240\0\0\0\0\374\264\0\374\264\0\374\264\0\0\0\0\374\310" + "\0\374\310\0\374\310\0\0\0\0\374\334\0\374\334\0\374\334\0\0\0\0\374\360" + "\0\374\360\0\374\360\0\0\0\0\0\0\0\0\0\0\0\0\0\374\360\0\374\360\0\374\360" + "\0\374\360\0\0\0\0\0\0\0\0\0\0\0\0\0\374\360\0\374\360\0\374\360\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\374\0\0\374\0\0\374\0\0\0\0\0\374\24\0\374\24\0\374\24\0\0\0\0\374(\0\374" + "(\0\374(\0\0\0\0\374<\0\374<\0\374<\0\0\0\0\374P\0\374P\0\374P\0\0\0\0\374" + "d\0\374d\0\374d\0\0\0\0\374x\0\374x\0\374x\0\0\0\0\374\214\0\374\214\0\374" + "\214\0\0\0\0\374\240\0\374\240\0\374\240\0\0\0\0\374\264\0\374\264\0\374" + "\264\0\0\0\0\374\310\0\374\310\0\374\310\0\0\0\0\374\334\0\374\334\0\374" + "\334\0\0\0\0\374\360\0\374\360\0\374\360\0\374\360\0\0\0\0\0\0\0\374\334" + "\0\0\0\0\374\360\0\374\360\0\374\360\0\374\360\0\0\0\0\0\0\0\374\334\0\0" + "\0\0\374\360\0\374\360\0\374\360\0\374\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\374\0\0\374\0\0\374\0\0\0\0" + "\0\374\24\0\374\24\0\374\24\0\0\0\0\374(\0\374(\0\374(\0\0\0\0\374<\0\374" + "<\0\374<\0\0\0\0\374P\0\374P\0\374P\0\0\0\0\374d\0\374d\0\374d\0\0\0\0\374" + "x\0\374x\0\374x\0\0\0\0\374\214\0\374\214\0\374\214\0\0\0\0\374\240\0\374" + "\240\0\374\240\0\0\0\0\374\264\0\374\264\0\374\264\0\0\0\0\374\310\0\374" + "\310\0\374\310\0\0\0\0\374\334\0\374\334\0\374\334\0\0\0\0\374\360\0\374" + "\360\0\374\360\0\374\360\0\0\0\0\0\0\0\0\0\0\0\0\0\374\360\0\374\360\0\374" + "\360\0\374\360\0\0\0\0\0\0\0\0\0\0\0\0\0\374\360\0\374\360\0\374\360\0\374" + "\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\374\0\0\374\0\0\374\0\0\0\0\0\374\24\0\374\24\0\374\24\0\0\0\0\374" + "(\0\374(\0\374(\0\0\0\0\374<\0\374<\0\374<\0\0\0\0\374P\0\374P\0\374P\0\0" + "\0\0\374d\0\374d\0\374d\0\0\0\0\374x\0\374x\0\374x\0\0\0\0\374\214\0\374" + "\214\0\374\214\0\0\0\0\374\240\0\374\240\0\374\240\0\0\0\0\374\264\0\374" + "\264\0\374\264\0\0\0\0\374\310\0\374\310\0\374\310\0\0\0\0\374\334\0\374" + "\334\0\374\334\0\0\0\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0" + "\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374" + "\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\374\0\0\374\0\0\374\0\0\0\0\0\374\24\0\374\24\0\374\24\0\0\0\0\374(\0" + "\374(\0\374(\0\0\0\0\374<\0\374<\0\374<\0\0\0\0\374P\0\374P\0\374P\0\0\0" + "\0\374d\0\374d\0\374d\0\0\0\0\374x\0\374x\0\374x\0\0\0\0\374\214\0\374\214" + "\0\374\214\0\0\0\0\374\240\0\374\240\0\374\240\0\0\0\0\374\264\0\374\264" + "\0\374\264\0\0\0\0\374\310\0\374\310\0\374\310\0\0\0\0\374\334\0\374\334" + "\0\374\334\0\0\0\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374" + "\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360" + "\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\374\0\0\374\0\0\374\0\0\0\0\0\374\24\0\374\24\0\374\24\0\0\0\0\374(\0\374" + "(\0\374(\0\0\0\0\374<\0\374<\0\374<\0\0\0\0\374P\0\374P\0\374P\0\0\0\0\374" + "d\0\374d\0\374d\0\0\0\0\374x\0\374x\0\374x\0\0\0\0\374\214\0\374\214\0\374" + "\214\0\0\0\0\374\240\0\374\240\0\374\240\0\0\0\0\374\264\0\374\264\0\374" + "\264\0\0\0\0\374\310\0\374\310\0\374\310\0\0\0\0\374\334\0\374\334\0\374" + "\334\0\0\0\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0" + "\374\360\0\374\360\0\374\360\0\0\0\0\0\0\0\374\360\0\374\360\0\374\360\0" + "\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\374\0\0\374" + "\0\0\374\0\0\0\0\0\374\24\0\374\24\0\374\24\0\0\0\0\374(\0\374(\0\374(\0" + "\0\0\0\374<\0\374<\0\374<\0\0\0\0\374P\0\374P\0\374P\0\0\0\0\374d\0\374d" + "\0\374d\0\0\0\0\374x\0\374x\0\374x\0\0\0\0\374\214\0\374\214\0\374\214\0" + "\0\0\0\374\240\0\374\240\0\374\240\0\0\0\0\374\264\0\374\264\0\374\264\0" + "\0\0\0\374\310\0\374\310\0\374\310\0\0\0\0\374\334\0\374\334\0\374\334\0" + "\0\0\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360" + "\0\374\360\0\374\360\0\0\0\0\0\0\0\374\360\0\374\360\0\374\360\0\374\360" + "\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\374\0\0\374\0\0\374" + "\0\0\0\0\0\374\24\0\374\24\0\374\24\0\0\0\0\374(\0\374(\0\374(\0\0\0\0\374" + "<\0\374<\0\374<\0\0\0\0\374P\0\374P\0\374P\0\0\0\0\374d\0\374d\0\374d\0\0" + "\0\0\374x\0\374x\0\374x\0\0\0\0\374\214\0\374\214\0\374\214\0\0\0\0\374\240" + "\0\374\240\0\374\240\0\0\0\0\374\264\0\374\264\0\374\264\0\0\0\0\374\310" + "\0\374\310\0\374\310\0\0\0\0\374\334\0\374\334\0\374\334\0\0\0\0\374\360" + "\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0" + "\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374" + "\360\0\374\360\0\374\360\0\374\360\0\374\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\374\0\0\374\0\0\374" + "\0\0\0\0\0\374\24\0\374\24\0\374\24\0\0\0\0\374(\0\374(\0\374(\0\0\0\0\374" + "<\0\374<\0\374<\0\0\0\0\374P\0\374P\0\374P\0\0\0\0\374d\0\374d\0\374d\0\0" + "\0\0\374x\0\374x\0\374x\0\0\0\0\374\214\0\374\214\0\374\214\0\0\0\0\374\240" + "\0\374\240\0\374\240\0\0\0\0\374\264\0\374\264\0\374\264\0\0\0\0\374\310" + "\0\374\310\0\374\310\0\0\0\0\374\334\0\374\334\0\374\334\0\0\0\0\374\360" + "\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0" + "\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374" + "\360\0\374\360\0\374\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\374\0\0\374\0\0\0\0\0\0\0\0\374\24" + "\0\374\24\0\0\0\0\0\0\0\374(\0\374(\0\0\0\0\0\0\0\374<\0\374<\0\0\0\0\0\0" + "\0\374P\0\374P\0\0\0\0\0\0\0\374d\0\374d\0\0\0\0\0\0\0\374x\0\374x\0\0\0" + "\0\0\0\0\374\214\0\374\214\0\0\0\0\0\0\0\374\240\0\374\240\0\0\0\0\0\0\0" + "\374\264\0\374\264\0\0\0\0\0\0\0\374\310\0\374\310\0\0\0\0\0\0\0\374\334" + "\0\374\334\0\0\0\0\0\0\0\374\360\0\374\360\0\0\0\0\0\0\0\0\0\0\374\360\0" + "\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\0" + "\0\0\0\0\0\0\0\0\374\360\0\374\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\374\0\0\374\0\0\0" + "\0\0\0\0\0\374\24\0\374\24\0\0\0\0\0\0\0\374(\0\374(\0\0\0\0\0\0\0\374<\0" + "\374<\0\0\0\0\0\0\0\374P\0\374P\0\0\0\0\0\0\0\374d\0\374d\0\0\0\0\0\0\0\374" + "x\0\374x\0\0\0\0\0\0\0\374\214\0\374\214\0\0\0\0\0\0\0\374\240\0\374\240" + "\0\0\0\0\0\0\0\374\264\0\374\264\0\0\0\0\0\0\0\374\310\0\374\310\0\0\0\0" + "\0\0\0\374\334\0\374\334\0\0\0\0\0\0\0\374\360\0\374\360\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\374\360\0\374" + "\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\374\0\0\374\0\0\0\0\0\0\0\0\374\24\0" + "\374\24\0\0\0\0\0\0\0\374(\0\374(\0\0\0\0\0\0\0\374<\0\374<\0\0\0\0\0\0\0" + "\374P\0\374P\0\0\0\0\0\0\0\374d\0\374d\0\0\0\0\0\0\0\374x\0\374x\0\0\0\0" + "\0\0\0\374\214\0\374\214\0\0\0\0\0\0\0\374\240\0\374\240\0\0\0\0\0\0\0\374" + "\264\0\374\264\0\0\0\0\0\0\0\374\310\0\374\310\0\0\0\0\0\0\0\374\334\0\374" + "\334\0\0\0\0\0\0\0\374\360\0\374\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\374\360\0\374\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\374\0\0\374\0\0\374\0\0\0\0\0\374\24\0\374\24\0\374\24\0" + "\0\0\0\374(\0\374(\0\374(\0\0\0\0\374<\0\374<\0\374<\0\0\0\0\374P\0\374P" + "\0\374P\0\0\0\0\374d\0\374d\0\374d\0\0\0\0\374x\0\374x\0\374x\0\0\0\0\374" + "\214\0\374\214\0\374\214\0\0\0\0\374\240\0\374\240\0\374\240\0\0\0\0\374" + "\264\0\374\264\0\374\264\0\0\0\0\374\310\0\374\310\0\374\310\0\0\0\0\374" + "\334\0\374\334\0\374\334\0\0\0\0\374\360\0\374\360\0\374\360\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\374\360\0\374\360\0\374\360\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\374\0\0\374\0\0\0\0\0\0\0\0" + "\374\24\0\374\24\0\0\0\0\0\0\0\374(\0\374(\0\0\0\0\0\0\0\374<\0\374<\0\0" + "\0\0\0\0\0\374P\0\374P\0\0\0\0\0\0\0\374d\0\374d\0\0\0\0\0\0\0\374x\0\374" + "x\0\0\0\0\0\0\0\374\214\0\374\214\0\0\0\0\0\0\0\374\240\0\374\240\0\0\0\0" + "\0\0\0\374\264\0\374\264\0\0\0\0\0\0\0\374\310\0\374\310\0\0\0\0\0\0\0\374" + "\334\0\374\334\0\0\0\0\0\0\0\374\360\0\374\360\0\374\360\0\374\360\0\374" + "\360\0\374\360\0\374\360\0\374\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", +}; + +/** + * \brief Returns the BlitColor test image as SDL_Surface. + */ +SDL_Surface *SDLTest_ImageBlitColor() +{ + SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormatFrom( + (void *)SDLTest_imageBlitColor.pixel_data, + SDLTest_imageBlitColor.width, + SDLTest_imageBlitColor.height, + SDLTest_imageBlitColor.bytes_per_pixel * 8, + SDLTest_imageBlitColor.width * SDLTest_imageBlitColor.bytes_per_pixel, + SDL_PIXELFORMAT_RGB24); + return surface; +} + +static const SDLTest_SurfaceImage_t SDLTest_imageBlitAlpha = { + 80, + 60, + 3, + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\24\24\0\24\24\0\20\20\0" + "\20\20\0" + "88\0" + "88\0**\0**\0ZZ\0ZZ\0==\0==\0yy\0yy\0II\0II\0\224\224\0\224" + "\224\0NN\0NN\0\254\254\0\254\254\0MM\0MM\0\302\302\0\302\302\0HH\0HH\0\324" + "\324\0\324\324\0>>\0>>\0\343\343\0\343\343\0" + "00\0" + "00\0\356\356\0\356\356" + "\0\40\40\0\40\40\0\367\367\0\367\367\0\16\16\0\16\16\0\374\374\0\374\374" + "\0\374\374\0\374\374\0\360\360\0\360\360\0\360\360\0\360\360\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\24\24\0\24\24\0\24\24\0\20\20\0" + "88\0" + "88\0" + "88\0**\0ff\0ff\0ff\0FF\0" + "\215\215\0\215\215\0\215\215\0UU\0\255\255\0\255\255\0\255\255\0[[\0\306" + "\306\0\306\306\0\306\306\0YY\0\331\331\0\331\331\0\331\331\0PP\0\350\350" + "\0\350\350\0\350\350\0DD\0\362\362\0\362\362\0\362\362\0" + "44\0\370\370\0" + "\370\370\0\370\370\0\"\"\0\374\374\0\374\374\0\374\374\0\16\16\0\376\376" + "\0\376\376\0\376\376\0\376\376\0\374\374\0\374\374\0\374\374\0\374\374\0" + "\360\360\0\360\360\0\360\360\0\360\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\24\24\0\24\24\0\24\24\0\20\20\0" + "88\0" + "" + "88\0" + "88\0**\0ff\0ff\0ff\0FF\0\226\226\0\226\226\0\215\215\0UU\0\271\271" + "\0\271\271\0\255\255\0[[\0\323\323\0\323\323\0\306\306\0YY\0\345\345\0\345" + "\345\0\331\331\0PP\0\360\360\0\360\360\0\350\350\0DD\0\370\370\0\370\370" + "\0\362\362\0" + "44\0\374\374\0\374\374\0\370\370\0\"\"\0\376\376\0\376\376" + "\0\374\374\0\16\16\0\376\376\0\376\376\0\376\376\0\376\376\0\376\376\0\376" + "\376\0\374\374\0\374\374\0\374\374\0\374\374\0\360\360\0\360\360\0\360\360" + "\0\360\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\24\24" + "\0\24\24\0\24\24\0\20\20\0" + "33\0" + "33\0" + "33\0&&\0OO\0OO\0OO\0" + "55\0``\0``" + "\0``\0::\0``\0``\0``\0" + "22\0WW\0WW\0WW\0''\0II\0II\0II\0\33\33\0" + "99\0" + "9" + "9\0" + "99\0\20\20\0))\0))\0))\0\10\10\0\33\33\0\33\33\0\33\33\0\3\3\0\17\17" + "\0\17\17\0\17\17\0\0\0\0\7\7\0\7\7\0\7\7\0\7\7\0\2\2\0\2\2\0\2\2\0\2\2\0" + "\16\16\0\16\16\0\16\16\0\16\16\0\360\360\0\360\360\0\360\360\0\360\360\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\24\24\0\24\24\0\24\24\0\16\16" + "\0" + "33\0GG\0GG\0" + "00\0``\0\210\210\0\210\210\0TT\0\204\204\0\263\263\0\263" + "\263\0ee\0\222\222\0\315\315\0\312\312\0gg\0\216\216\0\331\331\0\327\327" + "\0cc\0\202\202\0\340\340\0\337\337\0YY\0qq\0\345\345\0\344\344\0NN\0^^\0" + "\352\352\0\352\352\0@@\0JJ\0\357\357\0\357\357\0" + "11\0" + "66\0\364\364\0\364" + "\364\0\40\40\0\"\"\0\371\371\0\371\371\0\16\16\0\16\16\0\375\375\0\375\375" + "\0\376\376\0\376\376\0\362\362\0\362\362\0\376\376\0\376\376\0\16\16\0\16" + "\16\0\360\360\0\360\360\0\360\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\24" + "\24\0\24\24\0\22\22\0\24\24\0" + "88\0" + "88\0//\0BB\0pp\0pp\0UU\0ss\0\242\242" + "\0\242\242\0oo\0\230\230\0\306\306\0\306\306\0ww\0\265\265\0\335\335\0\335" + "\335\0ss\0\313\313\0\353\353\0\353\353\0ii\0\333\333\0\364\364\0\364\364" + "\0ZZ\0\351\351\0\371\371\0\371\371\0II\0\362\362\0\374\374\0\374\374\0" + "6" + "6\0\370\370\0\376\376\0\376\376\0\"\"\0\374\374\0\376\376\0\376\376\0\16" + "\16\0\376\376\0\376\376\0\376\376\0\376\376\0\375\375\0\376\376\0\376\376" + "\0\376\376\0\360\360\0\360\360\0\360\360\0\360\360\0\16\16\0\360\360\0\360" + "\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\24\24\0\24\24\0\22\22\0\"\"\0" + "88\0" + "" + "88\0//\0OO\0pp\0pp\0WW\0\203\203\0\242\242\0\242\242\0qq\0\256\256\0\312" + "\312\0\301\301\0||\0\313\313\0\342\342\0\325\325\0yy\0\336\336\0\360\360" + "\0\342\342\0mm\0\353\353\0\367\367\0\354\354\0\\\\\0\363\363\0\373\373\0" + "\362\362\0JJ\0\371\371\0\375\375\0\367\367\0" + "66\0\374\374\0\376\376\0\373" + "\373\0\"\"\0\376\376\0\376\376\0\375\375\0\16\16\0\376\376\0\376\376\0\376" + "\376\0\376\376\0\376\376\0\376\376\0\375\375\0\376\376\0\376\376\0\375\375" + "\0\360\360\0\374\374\0\360\360\0\376\376\0\16\16\0\360\360\0\360\360\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\24\24\0\22\22\0&&\0\"\"\0" + "88\0//\0PP\0HH\0gg\0NN" + "\0pp\0ee\0}}\0VV\0{{\0oo\0\202\202\0NN\0qq\0jj\0vv\0>>\0``\0\\\\\0cc\0,," + "\0MM\0KK\0OO\0\35\35\0::\0" + "99\0;;\0\21\21\0**\0))\0**\0\10\10\0\33\33\0" + "\33\33\0\33\33\0\3\3\0\17\17\0\17\17\0\17\17\0\0\0\0\7\7\0\7\7\0\7\7\0\7" + "\7\0\2\2\0\2\2\0\2\2\0\2\2\0\16\16\0\16\16\0\16\16\0\16\16\0\360\360\0\360" + "\360\0\376\376\0\376\376\0\16\16\0\360\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\22\22" + "\0&&\0&&\0\"\"\0" + "66\0[[\0oo\0ee\0``\0\220\220\0\270\270\0\250\250\0xx\0" + "\250\250\0\327\327\0\311\311\0zz\0\246\246\0\341\341\0\325\325\0rr\0\230" + "\230\0\343\343\0\334\334\0gg\0\205\205\0\344\344\0\340\340\0[[\0rr\0\346" + "\346\0\344\344\0NN\0^^\0\352\352\0\352\352\0AA\0JJ\0\357\357\0\357\357\0" + "" + "11\0" + "66\0\364\364\0\364\364\0\40\40\0\"\"\0\371\371\0\371\371\0\16\16" + "\0\16\16\0\375\375\0\375\375\0\376\376\0\376\376\0\362\362\0\362\362\0\376" + "\376\0\376\376\0\16\16\0\16\16\0\376\376\0\376\376\0\376\376\0\16\16\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\22\22\0&&\0&&\0\37\37\0;;\0``\0``\0HH\0qq\0\237\237" + "\0\237\237\0nn\0\227\227\0\306\306\0\306\306\0}}\0\254\254\0\334\334\0\334" + "\334\0}}\0\275\275\0\347\347\0\347\347\0vv\0\316\316\0\357\357\0\357\357" + "\0ii\0\334\334\0\365\365\0\365\365\0ZZ\0\351\351\0\371\371\0\371\371\0II" + "\0\362\362\0\374\374\0\374\374\0" + "66\0\370\370\0\376\376\0\376\376\0\"\"" + "\0\374\374\0\376\376\0\376\376\0\16\16\0\376\376\0\376\376\0\376\376\0\376" + "\376\0\375\375\0\376\376\0\376\376\0\376\376\0\360\360\0\360\360\0\360\360" + "\0\360\360\0\16\16\0\376\376\0\376\376\0\16\16\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "&&\0&&\0##\0--\0``\0``\0TT\0cc\0\237\237\0\231\231\0||\0\223\223\0\306\306" + "\0\301\301\0\217\217\0\267\267\0\336\336\0\322\322\0\220\220\0\317\317\0" + "\352\352\0\334\334\0\202\202\0\337\337\0\362\362\0\345\345\0qq\0\353\353" + "\0\370\370\0\354\354\0^^\0\363\363\0\373\373\0\362\362\0JJ\0\371\371\0\375" + "\375\0\367\367\0" + "66\0\374\374\0\376\376\0\373\373\0\"\"\0\376\376\0\376" + "\376\0\375\375\0\16\16\0\376\376\0\376\376\0\376\376\0\376\376\0\376\376" + "\0\376\376\0\375\375\0\376\376\0\376\376\0\375\375\0\360\360\0\376\376\0" + "\360\360\0\376\376\0\16\16\0\376\376\0\376\376\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "&&\0##\0" + "77\0--\0``\0PP\0nn\0[[\0\222\222\0kk\0\211\211\0qq\0\231\231\0" + "ff\0\210\210\0uu\0\217\217\0UU\0vv\0ll\0zz\0@@\0aa\0]]\0dd\0,,\0MM\0KK\0" + "OO\0\35\35\0::\0" + "99\0;;\0\21\21\0**\0))\0**\0\10\10\0\33\33\0\33\33\0\33" + "\33\0\3\3\0\17\17\0\17\17\0\17\17\0\0\0\0\7\7\0\7\7\0\7\7\0\7\7\0\2\2\0\2" + "\2\0\2\2\0\2\2\0\16\16\0\16\16\0\16\16\0\16\16\0\360\360\0\360\360\0\376" + "\376\0\376\376\0\16\16\0\376\376\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0##\0" + "77\0" + "77" + "\0--\0UU\0zz\0\216\216\0ww\0}}\0\254\254\0\324\324\0\264\264\0\207\207\0" + "\266\266\0\345\345\0\316\316\0\177\177\0\254\254\0\346\346\0\326\326\0rr" + "\0\231\231\0\344\344\0\334\334\0gg\0\206\206\0\344\344\0\340\340\0[[\0rr" + "\0\346\346\0\344\344\0NN\0^^\0\352\352\0\352\352\0AA\0JJ\0\357\357\0\357" + "\357\0" + "11\0" + "66\0\364\364\0\364\364\0\40\40\0\"\"\0\371\371\0\371\371\0" + "\16\16\0\16\16\0\375\375\0\375\375\0\376\376\0\376\376\0\362\362\0\362\362" + "\0\376\376\0\376\376\0\16\16\0\16\16\0\376\376\0\376\376\0\376\376\0\16\16" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\22\22\0" + "77\0" + "77\0--\0CC\0~~\0~~\0\\\\\0||\0" + "\274\274\0\274\274\0||\0\235\235\0\325\325\0\325\325\0\204\204\0\256\256" + "\0\340\340\0\340\340\0\177\177\0\275\275\0\351\351\0\351\351\0vv\0\316\316" + "\0\360\360\0\360\360\0ii\0\334\334\0\365\365\0\365\365\0ZZ\0\351\351\0\371" + "\371\0\371\371\0II\0\362\362\0\374\374\0\374\374\0" + "66\0\370\370\0\376\376" + "\0\376\376\0\"\"\0\374\374\0\376\376\0\376\376\0\16\16\0\376\376\0\376\376" + "\0\376\376\0\376\376\0\375\375\0\376\376\0\376\376\0\376\376\0\360\360\0" + "\360\360\0\360\360\0\360\360\0\16\16\0\376\376\0\376\376\0\16\16\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0&&\0" + "77\0" + "22\0--\0``\0vv\0pp\0gg\0\243\243\0\255\255" + "\0\225\225\0\231\231\0\311\311\0\314\314\0\235\235\0\271\271\0\337\337\0" + "\326\326\0\224\224\0\320\320\0\352\352\0\336\336\0\204\204\0\337\337\0\362" + "\362\0\345\345\0qq\0\353\353\0\370\370\0\354\354\0^^\0\363\363\0\373\373" + "\0\362\362\0JJ\0\371\371\0\375\375\0\367\367\0" + "66\0\374\374\0\376\376\0" + "\373\373\0\"\"\0\376\376\0\376\376\0\375\375\0\16\16\0\376\376\0\376\376" + "\0\376\376\0\376\376\0\376\376\0\376\376\0\375\375\0\376\376\0\376\376\0" + "\375\375\0\360\360\0\376\376\0\360\360\0\376\376\0\16\16\0\376\376\0\376" + "\376\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0&&\0##\0FF\0" + "99\0``\0PP\0\200\200\0dd\0\222" + "\222\0kk\0\222\222\0vv\0\231\231\0ff\0\213\213\0ww\0\217\217\0UU\0xx\0mm" + "\0zz\0@@\0bb\0]]\0dd\0,,\0MM\0KK\0OO\0\35\35\0::\0" + "99\0;;\0\21\21\0**\0" + "))\0**\0\10\10\0\33\33\0\33\33\0\33\33\0\3\3\0\17\17\0\17\17\0\17\17\0\0" + "\0\0\7\7\0\7\7\0\7\7\0\7\7\0\2\2\0\2\2\0\2\2\0\2\2\0\16\16\0\16\16\0\16\16" + "\0\16\16\0\360\360\0\360\360\0\376\376\0\376\376\0\16\16\0\376\376\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0##\0" + "77\0" + "77\0" + "99\0^^\0zz\0\216\216\0\201\201\0\203" + "\203\0\254\254\0\324\324\0\271\271\0\211\211\0\266\266\0\345\345\0\317\317" + "\0\200\200\0\254\254\0\346\346\0\326\326\0ss\0\231\231\0\344\344\0\334\334" + "\0gg\0\206\206\0\344\344\0\340\340\0[[\0rr\0\346\346\0\344\344\0NN\0^^\0" + "\352\352\0\352\352\0AA\0JJ\0\357\357\0\357\357\0" + "11\0" + "66\0\364\364\0\364" + "\364\0\40\40\0\"\"\0\371\371\0\371\371\0\16\16\0\16\16\0\375\375\0\375\375" + "\0\376\376\0\376\376\0\362\362\0\362\362\0\376\376\0\376\376\0\16\16\0\16" + "\16\0\376\376\0\376\376\0\376\376\0\16\16\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\22\22" + "\0" + "77\0" + "77\0--\0MM\0\210\210\0\210\210\0\\\\\0\202\202\0\302\302\0\302" + "\302\0||\0\240\240\0\330\330\0\330\330\0\204\204\0\257\257\0\341\341\0\341" + "\341\0\177\177\0\275\275\0\351\351\0\351\351\0vv\0\316\316\0\360\360\0\360" + "\360\0ii\0\334\334\0\365\365\0\365\365\0ZZ\0\351\351\0\371\371\0\371\371" + "\0II\0\362\362\0\374\374\0\374\374\0" + "66\0\370\370\0\376\376\0\376\376\0" + "\"\"\0\374\374\0\376\376\0\376\376\0\16\16\0\376\376\0\376\376\0\376\376" + "\0\376\376\0\375\375\0\376\376\0\376\376\0\376\376\0\360\360\0\360\360\0" + "\360\360\0\360\360\0\16\16\0\376\376\0\376\376\0\16\16\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0&&\0" + "77\0" + "22\0--\0``\0vv\0xx\0kk\0\245\245\0\257\257\0\235\235" + "\0\234\234\0\312\312\0\315\315\0\241\241\0\272\272\0\337\337\0\326\326\0" + "\225\225\0\320\320\0\352\352\0\336\336\0\204\204\0\337\337\0\362\362\0\345" + "\345\0qq\0\353\353\0\370\370\0\354\354\0^^\0\363\363\0\373\373\0\362\362" + "\0JJ\0\371\371\0\375\375\0\367\367\0" + "66\0\374\374\0\376\376\0\373\373\0" + "\"\"\0\376\376\0\376\376\0\375\375\0\16\16\0\376\376\0\376\376\0\376\376" + "\0\376\376\0\376\376\0\376\376\0\375\375\0\376\376\0\376\376\0\375\375\0" + "\360\360\0\376\376\0\360\360\0\376\376\0\16\16\0\376\376\0\376\376\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0&&\0##\0FF\0" + "99\0``\0PP\0\200\200\0dd\0\222\222\0kk" + "\0\222\222\0vv\0\231\231\0ff\0\213\213\0ww\0\217\217\0UU\0xx\0mm\0zz\0@@" + "\0bb\0]]\0dd\0,,\0MM\0KK\0OO\0\35\35\0::\0" + "99\0;;\0\21\21\0**\0))\0**\0" + "\10\10\0\33\33\0\33\33\0\33\33\0\3\3\0\17\17\0\17\17\0\17\17\0\0\0\0\7\7" + "\0\7\7\0\7\7\0\7\7\0\2\2\0\2\2\0\2\2\0\2\2\0\16\16\0\16\16\0\16\16\0\16\16" + "\0\360\360\0\360\360\0\376\376\0\376\376\0\16\16\0\376\376\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0##\0" + "77\0" + "77\0" + "99\0^^\0zz\0\216\216\0\201\201\0\203\203\0" + "\254\254\0\324\324\0\271\271\0\211\211\0\266\266\0\345\345\0\317\317\0\200" + "\200\0\254\254\0\346\346\0\326\326\0ss\0\231\231\0\344\344\0\334\334\0gg" + "\0\206\206\0\344\344\0\340\340\0[[\0rr\0\346\346\0\344\344\0NN\0^^\0\352" + "\352\0\352\352\0AA\0JJ\0\357\357\0\357\357\0" + "11\0" + "66\0\364\364\0\364\364" + "\0\40\40\0\"\"\0\371\371\0\371\371\0\16\16\0\16\16\0\375\375\0\375\375\0" + "\376\376\0\376\376\0\362\362\0\362\362\0\376\376\0\376\376\0\16\16\0\16\16" + "\0\376\376\0\376\376\0\376\376\0\16\16\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\22\22\0" + "" + "77\0" + "77\0--\0MM\0\210\210\0\210\210\0\\\\\0\202\202\0\302\302\0\302\302" + "\0||\0\240\240\0\330\330\0\330\330\0\204\204\0\257\257\0\341\341\0\341\341" + "\0\177\177\0\275\275\0\351\351\0\351\351\0vv\0\316\316\0\360\360\0\360\360" + "\0ii\0\334\334\0\365\365\0\365\365\0ZZ\0\351\351\0\371\371\0\371\371\0II" + "\0\362\362\0\374\374\0\374\374\0" + "66\0\370\370\0\376\376\0\376\376\0\"\"" + "\0\374\374\0\376\376\0\376\376\0\16\16\0\376\376\0\376\376\0\376\376\0\376" + "\376\0\375\375\0\376\376\0\376\376\0\376\376\0\360\360\0\360\360\0\360\360" + "\0\360\360\0\16\16\0\376\376\0\376\376\0\16\16\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "&&\0" + "77\0" + "22\0--\0``\0vv\0xx\0kk\0\245\245\0\257\257\0\235\235\0\234\234" + "\0\312\312\0\315\315\0\241\241\0\272\272\0\337\337\0\326\326\0\225\225\0" + "\320\320\0\352\352\0\336\336\0\204\204\0\337\337\0\362\362\0\345\345\0qq" + "\0\353\353\0\370\370\0\354\354\0^^\0\363\363\0\373\373\0\362\362\0JJ\0\371" + "\371\0\375\375\0\367\367\0" + "66\0\374\374\0\376\376\0\373\373\0\"\"\0\376" + "\376\0\376\376\0\375\375\0\16\16\0\376\376\0\376\376\0\376\376\0\376\376" + "\0\376\376\0\376\376\0\375\375\0\376\376\0\376\376\0\375\375\0\360\360\0" + "\376\376\0\360\360\0\376\376\0\16\16\0\376\376\0\376\376\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0&&\0##\0FF\0" + "99\0``\0PP\0\200\200\0dd\0\222\222\0kk\0\222\222" + "\0vv\0\231\231\0ff\0\213\213\0ww\0\217\217\0UU\0xx\0mm\0zz\0@@\0bb\0]]\0" + "dd\0,,\0MM\0KK\0OO\0\35\35\0::\0" + "99\0;;\0\21\21\0**\0))\0**\0\10\10\0\33" + "\33\0\33\33\0\33\33\0\3\3\0\17\17\0\17\17\0\17\17\0\0\0\0\7\7\0\7\7\0\7\7" + "\0\7\7\0\2\2\0\2\2\0\2\2\0\2\2\0\16\16\0\16\16\0\16\16\0\16\16\0\360\360" + "\0\360\360\0\376\376\0\376\376\0\16\16\0\376\376\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0##\0" + "77\0" + "77\0" + "99\0^^\0zz\0\216\216\0\201\201\0\203\203\0\254\254\0" + "\324\324\0\271\271\0\211\211\0\266\266\0\345\345\0\317\317\0\200\200\0\254" + "\254\0\346\346\0\326\326\0ss\0\231\231\0\344\344\0\334\334\0gg\0\206\206" + "\0\344\344\0\340\340\0[[\0rr\0\346\346\0\344\344\0NN\0^^\0\352\352\0\352" + "\352\0AA\0JJ\0\357\357\0\357\357\0" + "11\0" + "66\0\364\364\0\364\364\0\40\40" + "\0\"\"\0\371\371\0\371\371\0\16\16\0\16\16\0\375\375\0\375\375\0\376\376" + "\0\376\376\0\362\362\0\362\362\0\376\376\0\376\376\0\16\16\0\16\16\0\376" + "\376\0\376\376\0\376\376\0\16\16\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\22\22\0" + "77\0" + "" + "77\0--\0MM\0\210\210\0\210\210\0\\\\\0\202\202\0\302\302\0\302\302\0||" + "\0\240\240\0\330\330\0\330\330\0\204\204\0\257\257\0\341\341\0\341\341\0" + "\177\177\0\275\275\0\351\351\0\351\351\0vv\0\316\316\0\360\360\0\360\360" + "\0ii\0\334\334\0\365\365\0\365\365\0ZZ\0\351\351\0\371\371\0\371\371\0II" + "\0\362\362\0\374\374\0\374\374\0" + "66\0\370\370\0\376\376\0\376\376\0\"\"" + "\0\374\374\0\376\376\0\376\376\0\16\16\0\376\376\0\376\376\0\376\376\0\376" + "\376\0\375\375\0\376\376\0\376\376\0\376\376\0\360\360\0\360\360\0\360\360" + "\0\360\360\0\16\16\0\376\376\0\376\376\0\16\16\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "&&\0" + "77\0" + "22\0--\0``\0vv\0xx\0kk\0\245\245\0\257\257\0\235\235\0\234\234" + "\0\312\312\0\315\315\0\241\241\0\272\272\0\337\337\0\326\326\0\225\225\0" + "\320\320\0\352\352\0\336\336\0\204\204\0\337\337\0\362\362\0\345\345\0qq" + "\0\353\353\0\370\370\0\354\354\0^^\0\363\363\0\373\373\0\362\362\0JJ\0\371" + "\371\0\375\375\0\367\367\0" + "66\0\374\374\0\376\376\0\373\373\0\"\"\0\376" + "\376\0\376\376\0\375\375\0\16\16\0\376\376\0\376\376\0\376\376\0\376\376" + "\0\376\376\0\376\376\0\375\375\0\376\376\0\376\376\0\375\375\0\360\360\0" + "\376\376\0\360\360\0\376\376\0\16\16\0\376\376\0\376\376\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0&&\0##\0FF\0" + "99\0``\0PP\0\200\200\0dd\0\222\222\0kk\0\222\222" + "\0vv\0\231\231\0ff\0\213\213\0ww\0\217\217\0UU\0xx\0mm\0zz\0@@\0bb\0]]\0" + "dd\0,,\0MM\0KK\0OO\0\35\35\0::\0" + "99\0;;\0\21\21\0**\0))\0**\0\10\10\0\33" + "\33\0\33\33\0\33\33\0\3\3\0\17\17\0\17\17\0\17\17\0\0\0\0\7\7\0\7\7\0\7\7" + "\0\7\7\0\2\2\0\2\2\0\2\2\0\2\2\0\16\16\0\16\16\0\16\16\0\16\16\0\360\360" + "\0\360\360\0\376\376\0\376\376\0\16\16\0\376\376\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0##\0" + "77\0" + "77\0" + "99\0^^\0zz\0\216\216\0\201\201\0\203\203\0\254\254\0" + "\324\324\0\271\271\0\211\211\0\266\266\0\345\345\0\317\317\0\200\200\0\254" + "\254\0\346\346\0\326\326\0ss\0\231\231\0\344\344\0\334\334\0gg\0\206\206" + "\0\344\344\0\340\340\0[[\0rr\0\346\346\0\344\344\0NN\0^^\0\352\352\0\352" + "\352\0AA\0JJ\0\357\357\0\357\357\0" + "11\0" + "66\0\364\364\0\364\364\0\40\40" + "\0\"\"\0\371\371\0\371\371\0\16\16\0\16\16\0\375\375\0\375\375\0\376\376" + "\0\376\376\0\362\362\0\362\362\0\376\376\0\376\376\0\16\16\0\16\16\0\376" + "\376\0\376\376\0\376\376\0\16\16\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\22\22\0" + "77\0" + "" + "77\0--\0MM\0\210\210\0\210\210\0\\\\\0\202\202\0\302\302\0\302\302\0||" + "\0\240\240\0\330\330\0\330\330\0\204\204\0\257\257\0\341\341\0\341\341\0" + "\177\177\0\275\275\0\351\351\0\351\351\0vv\0\316\316\0\360\360\0\360\360" + "\0ii\0\334\334\0\365\365\0\365\365\0ZZ\0\351\351\0\371\371\0\371\371\0II" + "\0\362\362\0\374\374\0\374\374\0" + "66\0\370\370\0\376\376\0\376\376\0\"\"" + "\0\374\374\0\376\376\0\376\376\0\16\16\0\376\376\0\376\376\0\376\376\0\376" + "\376\0\375\375\0\376\376\0\376\376\0\376\376\0\360\360\0\360\360\0\360\360" + "\0\360\360\0\16\16\0\376\376\0\376\376\0\16\16\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "&&\0" + "77\0" + "22\0--\0``\0vv\0xx\0kk\0\245\245\0\257\257\0\235\235\0\234\234" + "\0\312\312\0\315\315\0\241\241\0\272\272\0\337\337\0\326\326\0\225\225\0" + "\320\320\0\352\352\0\336\336\0\204\204\0\337\337\0\362\362\0\345\345\0qq" + "\0\353\353\0\370\370\0\354\354\0^^\0\363\363\0\373\373\0\362\362\0JJ\0\371" + "\371\0\375\375\0\367\367\0" + "66\0\374\374\0\376\376\0\373\373\0\"\"\0\376" + "\376\0\376\376\0\375\375\0\16\16\0\376\376\0\376\376\0\376\376\0\376\376" + "\0\376\376\0\376\376\0\375\375\0\376\376\0\376\376\0\375\375\0\360\360\0" + "\376\376\0\360\360\0\376\376\0\16\16\0\376\376\0\376\376\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0&&\0##\0FF\0" + "99\0``\0PP\0\213\213\0mm\0\237\237\0uu\0\275\275" + "\0\232\232\0\306\306\0\204\204\0\331\331\0\272\272\0\336\336\0\205\205\0" + "\345\345\0\320\320\0\352\352\0{{\0\355\355\0\337\337\0\362\362\0mm\0\363" + "\363\0\353\353\0\370\370\0\\\\\0\367\367\0\363\363\0\373\373\0II\0\373\373" + "\0\371\371\0\375\375\0" + "66\0\375\375\0\374\374\0\376\376\0\"\"\0\376\376" + "\0\376\376\0\376\376\0\16\16\0\376\376\0\376\376\0\376\376\0\376\376\0\376" + "\376\0\376\376\0\376\376\0\376\376\0\375\375\0\376\376\0\375\375\0\375\375" + "\0\360\360\0\360\360\0\376\376\0\376\376\0\16\16\0\376\376\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0##\0" + "77\0" + "77\0" + "99\0gg\0\205\205\0\205\205\0ww\0\224\224\0" + "\310\310\0\310\310\0\247\247\0\240\240\0\354\354\0\354\354\0\306\306\0\227" + "\227\0\372\372\0\372\372\0\325\325\0\205\205\0\375\375\0\375\375\0\342\342" + "\0rr\0\376\376\0\376\376\0\354\354\0^^\0\376\376\0\376\376\0\363\363\0JJ" + "\0\376\376\0\376\376\0\370\370\0" + "66\0\376\376\0\376\376\0\374\374\0\"\"" + "\0\376\376\0\376\376\0\376\376\0\16\16\0\376\376\0\376\376\0\376\376\0\376" + "\376\0\376\376\0\376\376\0\376\376\0\376\376\0\376\376\0\376\376\0\375\375" + "\0\376\376\0\376\376\0\376\376\0\362\362\0\376\376\0\376\376\0\376\376\0" + "\16\16\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\22\22\0" + "77\0" + "77\0" + "11\0>>\0~~\0~~\0bb" + "\0__\0\261\261\0\261\261\0\212\212\0``\0\277\277\0\277\277\0\230\230\0SS" + "\0\275\275\0\275\275\0\233\233\0@@\0\273\273\0\273\273\0\240\240\0//\0\274" + "\274\0\274\274\0\252\252\0!!\0\301\301\0\301\301\0\266\266\0\25\25\0\311" + "\311\0\311\311\0\303\303\0\14\14\0\324\324\0\324\324\0\322\322\0\6\6\0\342" + "\342\0\342\342\0\341\341\0\1\1\0\361\361\0\361\361\0\361\361\0\15\15\0\15" + "\15\0\15\15\0\15\15\0\362\362\0\362\362\0\362\362\0\360\360\0\16\16\0\16" + "\16\0\16\16\0\2\2\0\376\376\0\376\376\0\376\376\0\16\16\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0&&\0" + "77\0" + "77\0\34\34\0SS\0kk\0\206\206\0BB\0\214\214\0\232\232" + "\0\302\302\0YY\0\250\250\0\255\255\0\340\340\0XX\0\264\264\0\264\264\0\355" + "\355\0SS\0\265\265\0\266\266\0\364\364\0JJ\0\270\270\0\272\272\0\371\371" + "\0AA\0\277\277\0\300\300\0\374\374\0" + "66\0\310\310\0\311\311\0\375\375\0" + "**\0\324\324\0\324\324\0\376\376\0\34\34\0\341\341\0\342\342\0\376\376\0" + "\15\15\0\361\361\0\361\361\0\376\376\0\361\361\0\15\15\0\15\15\0\376\376" + "\0\15\15\0\361\361\0\361\361\0\373\373\0\362\362\0\15\15\0\16\16\0\376\376" + "\0\16\16\0\361\361\0\376\376\0\376\376\0\376\376\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0&&\0&&\0" + "77\0))\0SS\0SS\0kk\0DD\0\205\205\0}}\0\222\222\0WW\0\241\241" + "\0\230\230\0\245\245\0XX\0\261\261\0\252\252\0\261\261\0SS\0\264\264\0\263" + "\263\0\265\265\0JJ\0\270\270\0\271\271\0\272\272\0AA\0\276\276\0\300\300" + "\0\300\300\0" + "66\0\310\310\0\311\311\0\311\311\0**\0\324\324\0\324\324\0" + "\324\324\0\34\34\0\341\341\0\342\342\0\342\342\0\15\15\0\361\361\0\361\361" + "\0\361\361\0\361\361\0\15\15\0\15\15\0\15\15\0\15\15\0\361\361\0\361\361" + "\0\361\361\0\362\362\0\15\15\0\16\16\0\16\16\0\16\16\0\361\361\0\376\376" + "\0\376\376\0\376\376\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0&&\0&&\0&&\0))\0pp\0cc\0cc" + "\0QQ\0\261\261\0\244\244\0\244\244\0ll\0\335\335\0\323\323\0\323\323\0ww" + "\0\364\364\0\356\356\0\356\356\0ss\0\370\370\0\371\371\0\371\371\0ii\0\372" + "\372\0\375\375\0\375\375\0YY\0\374\374\0\376\376\0\376\376\0HH\0\375\375" + "\0\376\376\0\376\376\0" + "66\0\376\376\0\376\376\0\376\376\0\"\"\0\376\376" + "\0\376\376\0\376\376\0\16\16\0\376\376\0\376\376\0\376\376\0\376\376\0\376" + "\376\0\376\376\0\376\376\0\376\376\0\376\376\0\376\376\0\376\376\0\376\376" + "\0\375\375\0\376\376\0\376\376\0\376\376\0\361\361\0\376\376\0\376\376\0" + "\376\376\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\24\24\0&&\0&&\0\40\40\0QQ\0pp\0pp\0KK" + "\0\215\215\0\261\261\0\261\261\0pp\0\274\274\0\337\337\0\337\337\0\200\200" + "\0\332\332\0\364\364\0\364\364\0}}\0\350\350\0\373\373\0\373\373\0oo\0\361" + "\361\0\375\375\0\375\375\0]]\0\367\367\0\376\376\0\376\376\0JJ\0\373\373" + "\0\376\376\0\376\376\0" + "66\0\375\375\0\376\376\0\376\376\0\"\"\0\376\376" + "\0\376\376\0\376\376\0\16\16\0\376\376\0\376\376\0\376\376\0\376\376\0\376" + "\376\0\376\376\0\376\376\0\376\376\0\376\376\0\376\376\0\376\376\0\376\376" + "\0\375\375\0\376\376\0\376\376\0\376\376\0\361\361\0\376\376\0\376\376\0" + "\360\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\24\24\0&&\0&&\0\20\20\0" + "88\0WW\0pp\0" + "==\0ss\0\212\212\0\252\252\0dd\0\250\250\0\264\264\0\312\312\0rr\0\313\313" + "\0\315\315\0\331\331\0rr\0\340\340\0\331\331\0\340\340\0hh\0\355\355\0\341" + "\341\0\345\345\0YY\0\366\366\0\350\350\0\352\352\0HH\0\372\372\0\356\356" + "\0\357\357\0" + "66\0\375\375\0\364\364\0\364\364\0\"\"\0\376\376\0\371\371" + "\0\371\371\0\16\16\0\376\376\0\375\375\0\375\375\0\376\376\0\376\376\0\361" + "\361\0\362\362\0\376\376\0\376\376\0\16\16\0\16\16\0\376\376\0\375\375\0" + "\376\376\0\375\375\0\374\374\0\360\360\0\376\376\0\376\376\0\360\360\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\24\24\0\24\24\0&&\0\40\40\0" + "88\0" + "88\0WW\0BB\0ff" + "\0ZZ\0}}\0^^\0\226\226\0\201\201\0\241\241\0nn\0\301\301\0\246\246\0\277" + "\277\0rr\0\333\333\0\301\301\0\321\321\0ii\0\353\353\0\323\323\0\335\335" + "\0[[\0\365\365\0\341\341\0\346\346\0II\0\372\372\0\353\353\0\356\356\0" + "6" + "6\0\375\375\0\363\363\0\364\364\0\"\"\0\376\376\0\371\371\0\371\371\0\16" + "\16\0\376\376\0\375\375\0\375\375\0\376\376\0\376\376\0\361\361\0\361\361" + "\0\376\376\0\376\376\0\16\16\0\16\16\0\376\376\0\374\374\0\375\375\0\374" + "\374\0\374\374\0\361\361\0\376\376\0\360\360\0\360\360\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\24\24\0\24\24\0\24\24\0\40\40\0HH\0" + "88\0" + "88\0BB\0~~\0ff\0ff\0" + "^^\0\256\256\0\226\226\0\226\226\0qq\0\325\325\0\277\277\0\277\277\0ss\0" + "\350\350\0\331\331\0\331\331\0jj\0\363\363\0\353\353\0\353\353\0[[\0\371" + "\371\0\365\365\0\365\365\0II\0\374\374\0\372\372\0\372\372\0" + "66\0\375\375" + "\0\375\375\0\375\375\0\"\"\0\376\376\0\376\376\0\376\376\0\16\16\0\376\376" + "\0\376\376\0\376\376\0\376\376\0\376\376\0\376\376\0\376\376\0\376\376\0" + "\376\376\0\376\376\0\376\376\0\376\376\0\374\374\0\374\374\0\374\374\0\376" + "\376\0\361\361\0\360\360\0\360\360\0\360\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\24\24\0\24\24\0\24\24\0\40\40\0HH\0HH\0" + "88\0BB\0~~\0~~\0ff\0^^\0\263" + "\263\0\263\263\0\231\231\0nn\0\330\330\0\330\330\0\274\274\0pp\0\353\353" + "\0\353\353\0\324\324\0hh\0\365\365\0\365\365\0\345\345\0ZZ\0\373\373\0\373" + "\373\0\361\361\0II\0\375\375\0\375\375\0\370\370\0" + "66\0\376\376\0\376\376" + "\0\374\374\0\"\"\0\376\376\0\376\376\0\376\376\0\16\16\0\376\376\0\376\376" + "\0\376\376\0\376\376\0\376\376\0\376\376\0\376\376\0\376\376\0\376\376\0" + "\376\376\0\374\374\0\374\374\0\376\376\0\376\376\0\361\361\0\360\360\0\360" + "\360\0\360\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\24\24\0\24\24\0\0\0" + "\0\0\0\0((\0HH\0\40\40\0\25\25\0QQ\0\207\207\0KK\0--\0}}\0\262\262\0bb\0" + "" + "44\0\235\235\0\320\320\0ff\0" + "00\0\257\257\0\341\341\0cc\0))\0\272\272" + "\0\354\354\0ZZ\0\37\37\0\303\303\0\363\363\0OO\0\26\26\0\314\314\0\370\370" + "\0AA\0\15\15\0\326\326\0\373\373\0" + "22\0\6\6\0\343\343\0\375\375\0!!\0\1" + "\1\0\362\362\0\376\376\0\16\16\0\16\16\0\16\16\0\375\375\0\375\375\0\375" + "\375\0\376\376\0\362\362\0\360\360\0\361\361\0\376\376\0\14\14\0\0\0\0\0" + "\0\0\360\360\0\360\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\24\24" + "\0\24\24\0\0\0\0\0\0\0((\0((\0\0\0\0\0\0\0<<\0<<\0\0\0\0\0\0\0PP\0PP\0\10" + "\10\0\4\4\0dd\0dd\0\14\14\0\6\6\0xx\0xx\0\14\14\0\5\5\0\214\214\0\214\214" + "\0\13\13\0\4\4\0\240\240\0\240\240\0\10\10\0\2\2\0\264\264\0\264\264\0\5" + "\5\0\1\1\0\310\310\0\310\310\0\3\3\0\0\0\0\334\334\0\334\334\0\1\1\0\0\0" + "\0\360\360\0\360\360\0\0\0\0\0\0\0\0\0\0\0\0\0\1\1\0\1\1\0\0\0\0\0\0\0\14" + "\14\0\14\14\0\0\0\0\0\0\0\360\360\0\360\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\24\24\0\24\24\0\0\0\0\0\0\0((\0((\0\0\0\0\0\0" + "\0<<\0<<\0\0\0\0\0\0\0XX\0XX\0\0\0\0\0\0\0pp\0pp\0\0\0\0\0\0\0\204\204\0" + "\204\204\0\0\0\0\0\0\0\227\227\0\227\227\0\0\0\0\0\0\0\250\250\0\250\250" + "\0\0\0\0\0\0\0\271\271\0\271\271\0\0\0\0\0\0\0\313\313\0\313\313\0\0\0\0" + "\0\0\0\335\335\0\335\335\0\0\0\0\0\0\0\360\360\0\360\360\0\0\0\0\0\0\0\1" + "\1\0\1\1\0\0\0\0\0\0\0\14\14\0\14\14\0\0\0\0\0\0\0\360\360\0\360\360\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\24\24\0" + "\24\24\0\24\24\0\0\0\0((\0((\0((\0\0\0\0<<\0HH\0HH\0\10\10\0PP\0dd\0dd\0" + "\14\14\0dd\0||\0||\0\14\14\0xx\0\221\221\0\221\221\0\13\13\0\214\214\0\243" + "\243\0\243\243\0\10\10\0\240\240\0\264\264\0\264\264\0\5\5\0\264\264\0\303" + "\303\0\303\303\0\3\3\0\310\310\0\322\322\0\322\322\0\1\1\0\334\334\0\341" + "\341\0\341\341\0\0\0\0\360\360\0\361\361\0\361\361\0\1\1\0\0\0\0\14\14\0" + "\14\14\0\14\14\0\0\0\0\360\360\0\360\360\0\360\360\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\24\24\0" + "\24\24\0\20\20\0\20\20\0" + "88\0" + "88\0**\0**\0ZZ\0ZZ\0==\0==\0yy\0yy\0II\0" + "II\0\224\224\0\224\224\0NN\0NN\0\254\254\0\254\254\0MM\0MM\0\302\302\0\302" + "\302\0HH\0HH\0\324\324\0\324\324\0>>\0>>\0\343\343\0\343\343\0" + "00\0" + "00" + "\0\356\356\0\356\356\0\40\40\0\40\40\0\367\367\0\367\367\0\16\16\0\16\16" + "\0\374\374\0\374\374\0\374\374\0\374\374\0\360\360\0\360\360\0\360\360\0" + "\360\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", +}; + +/** + * \brief Returns the BlitAlpha test image as SDL_Surface. + */ +SDL_Surface *SDLTest_ImageBlitAlpha() +{ + SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormatFrom( + (void *)SDLTest_imageBlitAlpha.pixel_data, + SDLTest_imageBlitAlpha.width, + SDLTest_imageBlitAlpha.height, + SDLTest_imageBlitAlpha.bytes_per_pixel * 8, + SDLTest_imageBlitAlpha.width * SDLTest_imageBlitAlpha.bytes_per_pixel, + SDL_PIXELFORMAT_RGB24); + return surface; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/test/SDL_test_imageBlitBlend.c b/SDL2-2.30.5/src/test/SDL_test_imageBlitBlend.c new file mode 100644 index 0000000..520cfff --- /dev/null +++ b/SDL2-2.30.5/src/test/SDL_test_imageBlitBlend.c @@ -0,0 +1,2947 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_test.h" + +/* GIMP RGB C-Source image dump (alpha.c) */ + +static const SDLTest_SurfaceImage_t SDLTest_imageBlitBlendAdd = { + 80, + 60, + 3, + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0dd\0dd\0dd\0dd\0\310\310\0\310\310\0\310\310\0\310" + "\310\0\310\310\0\310\310\0\310\310\0\310\310\0\310\310\0\310\310\0\310\310" + "\0\310\310\0\310\310\0\310\310\0\310\310\0\310\310\0\310\310\0\310\310\0" + "\310\310\0\310\310\0\310\310\0\310\310\0\310\310\0\310\310\0\310\310\0\310" + "\310\0\310\310\0\310\310\0\310\310\0\310\310\0\310\310\0\310\310\0\310\310" + "\0\310\310\0\310\310\0\310\310\0\310\310\0\310\310\0\310\310\0\310\310\0" + "\310\310\0\310\310\0\310\310\0\310\310\0\310\310\0\310\310\0\310\310\0\310" + "\310\0dd\0dd\0dd\0dd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0dd\0dd\0dd\0dd\0\310\310\0\310\310\0\310\310\0\310\310\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\310\310" + "\0\310\310\0\310\310\0\310\310\0dd\0dd\0dd\0dd\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0dd\0dd\0dd\0dd\0\310\310\0\310\310\0\310\310\0\310\310" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\310\310\0\310\310\0\310\310\0\310\310\0dd\0dd\0dd" + "\0dd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0dd\0dd\0dd\0dd\0\310\310\0\310\310\0" + "\310\310\0\310\310\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\310\310\0\310" + "\310\0\310\310\0\310\310\0dd\0dd\0dd\0dd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0dd\0dd\0dd\0" + "dd\0\310\310\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\310\310\0" + "dd\0dd\0dd\0dd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0dd\0dd\0dd\0dd\0\310\310\0\310\310\0\310\310" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\310\310\0\310\310\0\310\310\0dd\0dd\0dd\0dd\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0dd\0dd\0dd" + "\0\310\310\0\310\310\0\310\310\0\310\310\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\310" + "\310\0\310\310\0\310\310\0\310\310\0dd\0dd\0dd\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0dd\0dd\0\310\310\0\310\310" + "\0\310\310\0\310\310\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\310" + "\310\0\310\310\0\310\310\0\310\310\0dd\0dd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0dd\0\310\310\0\310\310\0\310" + "\310\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\310\310\0\310\310\0\310\310\0dd\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0dd\0\310\310\0\310" + "\310\0\310\310\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\310\310\0\310\310\0\310\310\0dd\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\310\310" + "\0\310\310\0\310\310\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\310\310\0\310\310" + "\0\310\310\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\310\310\0\310\310\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\310\310\0\310\310\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\310\310\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\310\310\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0dd\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0dd\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\310\310\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\310" + "\310\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\310\310\0\310\310\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\310\310\0\310\310\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\310\310\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\310\310\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0dd\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0dd\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\310\310\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\310\310" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\310\310\0\310\310\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\310\310\0\310\310\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\310\310\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\310\310\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0dd\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0dd\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\310\310\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\310\310\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\310" + "\310\0\310\310\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\310" + "\310\0\310\310\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\310\310\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\310\310\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0dd\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0dd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\310\310\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\310\310\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\310\310" + "\0\310\310\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\310\310" + "\0\310\310\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\310\310\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\310\310\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0dd\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0dd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\310\310\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\310\310\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\310\310\0\310" + "\310\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\310\310\0\310" + "\310\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\310\310\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\310\310\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0dd\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0dd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\310\310\0\377\377\0\377\377\0\310\310" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\310\310\0\377\377\0\377\377\0\310\310\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\310\310\0\310\310" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\310\310\0\310\310" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\310\310\0\310\310\0\310\310\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\310\310" + "\0\310\310\0\310\310\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0dd\0\310\310\0\310\310\0\310\310\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\310" + "\310\0\310\310\0\310\310\0dd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0dd\0\310\310\0\310\310\0dd\0\310\310\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\310\310\0" + "dd\0\310\310\0\310\310\0dd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0dd\0dd\0\310\310\0\310\310\0\310\310\0\310\310" + "\0\377\377\0\377\377\0\377\377\0\310\310\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\310\310\0\377\377\0\377\377\0\377\377\0\310\310\0\310\310\0\310" + "\310\0\310\310\0dd\0dd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0dd\0dd\0dd\0\310\310\0\377\377\0\310\310\0\310\310" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\310\310\0\310\310\0\377\377\0\310\310\0dd" + "\0dd\0dd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0dd\0dd\0dd\0\310\310\0\377\377\0\377\377\0\310\310\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\310\310\0\377\377\0\377\377\0\310\310\0dd\0dd\0dd\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0dd\0dd" + "\0\0\0\0\0\0\0dd\0\377\377\0\310\310\0\310\310\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\310\310\0\310\310\0\377\377\0dd\0\0" + "\0\0\0\0\0dd\0dd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0dd\0dd\0\0\0\0\0\0\0dd\0dd\0\0\0\0\0" + "\0\0dd\0dd\0\0\0\0\0\0\0dd\0dd\0dd\0dd\0dd\0dd\0dd\0dd\0dd\0dd\0dd\0dd\0" + "dd\0dd\0dd\0dd\0dd\0dd\0dd\0dd\0dd\0dd\0dd\0dd\0dd\0dd\0dd\0dd\0dd\0dd\0" + "dd\0dd\0dd\0dd\0dd\0dd\0dd\0dd\0dd\0dd\0\0\0\0\0\0\0dd\0dd\0\0\0\0\0\0\0" + "dd\0dd\0\0\0\0\0\0\0dd\0dd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0dd\0dd\0\0\0\0" + "\0\0\0dd\0dd\0\0\0\0\0\0\0dd\0dd\0\0\0\0\0\0\0\310\310\0\310\310\0\0\0\0" + "\0\0\0\310\310\0\310\310\0\0\0\0\0\0\0\310\310\0\310\310\0\0\0\0\0\0\0\310" + "\310\0\310\310\0\0\0\0\0\0\0\310\310\0\310\310\0\0\0\0\0\0\0\310\310\0\310" + "\310\0\0\0\0\0\0\0\310\310\0\310\310\0\0\0\0\0\0\0\310\310\0\310\310\0\0" + "\0\0\0\0\0\310\310\0\310\310\0\0\0\0\0\0\0\310\310\0\310\310\0\0\0\0\0\0" + "\0dd\0dd\0\0\0\0\0\0\0dd\0dd\0\0\0\0\0\0\0dd\0dd\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0dd\0dd\0dd\0\0\0\0dd\0dd\0dd\0\0\0\0dd\0\310\310\0\310" + "\310\0dd\0dd\0\310\310\0\310\310\0dd\0dd\0\310\310\0\310\310\0dd\0dd\0\310" + "\310\0\310\310\0dd\0dd\0\310\310\0\310\310\0dd\0dd\0\310\310\0\310\310\0" + "dd\0dd\0\310\310\0\310\310\0dd\0dd\0\310\310\0\310\310\0dd\0dd\0\310\310" + "\0\310\310\0dd\0dd\0\310\310\0\310\310\0dd\0dd\0\310\310\0\310\310\0dd\0" + "\0\0\0dd\0dd\0dd\0\0\0\0dd\0dd\0dd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0dd\0dd\0dd\0dd\0\310\310\0\310\310\0\310\310\0\310" + "\310\0\310\310\0\310\310\0\310\310\0\310\310\0\310\310\0\310\310\0\310\310" + "\0\310\310\0\310\310\0\310\310\0\310\310\0\310\310\0\310\310\0\310\310\0" + "\310\310\0\310\310\0\310\310\0\310\310\0\310\310\0\310\310\0\310\310\0\310" + "\310\0\310\310\0\310\310\0\310\310\0\310\310\0\310\310\0\310\310\0\310\310" + "\0\310\310\0\310\310\0\310\310\0\310\310\0\310\310\0\310\310\0\310\310\0" + "\310\310\0\310\310\0\310\310\0\310\310\0\310\310\0\310\310\0\310\310\0\310" + "\310\0dd\0dd\0dd\0dd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", +}; + +/** + * \brief Returns the BlitBlendAdd test image as SDL_Surface. + */ +SDL_Surface *SDLTest_ImageBlitBlendAdd() +{ + SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormatFrom( + (void *)SDLTest_imageBlitBlendAdd.pixel_data, + SDLTest_imageBlitBlendAdd.width, + SDLTest_imageBlitBlendAdd.height, + SDLTest_imageBlitBlendAdd.bytes_per_pixel * 8, + SDLTest_imageBlitBlendAdd.width * SDLTest_imageBlitBlendAdd.bytes_per_pixel, + SDL_PIXELFORMAT_RGB24); + return surface; +} + +static const SDLTest_SurfaceImage_t SDLTest_imageBlitBlend = { + 80, + 60, + 3, + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0dd\0dd\0<<\0<<\0\240\240\0\240\240\0aa\0aa\0\240" + "\240\0\240\240\0aa\0aa\0\240\240\0\240\240\0aa\0aa\0\240\240\0\240\240\0" + "aa\0aa\0\240\240\0\240\240\0aa\0aa\0\240\240\0\240\240\0aa\0aa\0\240\240" + "\0\240\240\0aa\0aa\0\240\240\0\240\240\0aa\0aa\0\240\240\0\240\240\0aa\0" + "aa\0\240\240\0\240\240\0aa\0aa\0\240\240\0\240\240\0aa\0aa\0\240\240\0\240" + "\240\0\240\240\0\240\240\0dd\0dd\0dd\0dd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0dd\0dd\0dd\0<<\0\240\240\0\240\240\0\240\240" + "\0aa\0\305\305\0\305\305\0\305\305\0ww\0\305\305\0\305\305\0\305\305\0ww" + "\0\305\305\0\305\305\0\305\305\0ww\0\305\305\0\305\305\0\305\305\0ww\0\305" + "\305\0\305\305\0\305\305\0ww\0\305\305\0\305\305\0\305\305\0ww\0\305\305" + "\0\305\305\0\305\305\0ww\0\305\305\0\305\305\0\305\305\0ww\0\305\305\0\305" + "\305\0\305\305\0ww\0\305\305\0\305\305\0\305\305\0ww\0\305\305\0\305\305" + "\0\305\305\0\305\305\0\240\240\0\240\240\0\240\240\0\240\240\0dd\0dd\0dd" + "\0dd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0dd\0dd\0dd\0<<\0\240\240" + "\0\240\240\0\240\240\0aa\0\305\305\0\305\305\0\305\305\0ww\0\333\333\0\333" + "\333\0\305\305\0ww\0\333\333\0\333\333\0\305\305\0ww\0\333\333\0\333\333" + "\0\305\305\0ww\0\333\333\0\333\333\0\305\305\0ww\0\333\333\0\333\333\0\305" + "\305\0ww\0\333\333\0\333\333\0\305\305\0ww\0\333\333\0\333\333\0\305\305" + "\0ww\0\333\333\0\333\333\0\305\305\0ww\0\333\333\0\333\333\0\305\305\0ww" + "\0\333\333\0\333\333\0\305\305\0\305\305\0\305\305\0\305\305\0\240\240\0" + "\240\240\0\240\240\0\240\240\0dd\0dd\0dd\0dd\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0dd\0dd\0dd\0<<\0aa\0aa\0aa\0::\0HH\0HH\0HH\0++\0PP\0PP\0PP\0" + "00\0PP" + "\0PP\0PP\0" + "00\0PP\0PP\0PP\0" + "00\0PP\0PP\0PP\0" + "00\0PP\0PP\0PP\0" + "00\0PP" + "\0PP\0PP\0" + "00\0PP\0PP\0PP\0" + "00\0PP\0PP\0PP\0" + "00\0PP\0PP\0PP\0" + "00\0PP" + "\0PP\0PP\0PP\0HH\0HH\0HH\0HH\0aa\0aa\0aa\0aa\0dd\0dd\0dd\0dd\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0dd\0dd\0dd\0$$\0aa\0\305\305\0\305\305\0``\0\205\205\0\351\351\0" + "\351\351\0||\0\222\222\0\321\321\0\321\321\0\177\177\0\225\225\0\324\324" + "\0\321\321\0\177\177\0\225\225\0\324\324\0\321\321\0\177\177\0\225\225\0" + "\324\324\0\321\321\0\177\177\0\225\225\0\324\324\0\321\321\0\177\177\0\225" + "\225\0\324\324\0\321\321\0\177\177\0\225\225\0\324\324\0\321\321\0\177\177" + "\0\225\225\0\324\324\0\321\321\0\177\177\0\225\225\0\324\324\0\321\321\0" + "\177\177\0\225\225\0\324\324\0\321\321\0\222\222\0\222\222\0\321\321\0\314" + "\314\0\351\351\0\351\351\0\254\254\0\236\236\0\305\305\0\305\305\0aa\0<<" + "\0dd\0dd\0dd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0dd\0dd\0<<\0dd\0\240\240\0\240\240\0aa\0\255\255" + "\0\322\322\0\322\322\0\177\177\0\315\315\0\343\343\0\343\343\0\211\211\0" + "\313\313\0\346\346\0\346\346\0\211\211\0\313\313\0\346\346\0\346\346\0\211" + "\211\0\313\313\0\346\346\0\346\346\0\211\211\0\313\313\0\346\346\0\346\346" + "\0\211\211\0\313\313\0\346\346\0\346\346\0\211\211\0\313\313\0\346\346\0" + "\346\346\0\211\211\0\313\313\0\346\346\0\346\346\0\211\211\0\313\313\0\346" + "\346\0\346\346\0\211\211\0\313\313\0\346\346\0\346\346\0\211\211\0\320\320" + "\0\327\327\0\327\327\0\322\322\0\276\276\0\322\322\0\322\322\0\305\305\0" + "yy\0\210\210\0\210\210\0dd\0<<\0dd\0dd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0dd\0dd\0<<\0\210\210\0\240" + "\240\0\240\240\0aa\0\266\266\0\322\322\0\322\322\0\205\205\0\327\327\0\343" + "\343\0\343\343\0\215\215\0\346\346\0\357\357\0\331\331\0\222\222\0\347\347" + "\0\357\357\0\331\331\0\222\222\0\347\347\0\357\357\0\331\331\0\222\222\0" + "\347\347\0\357\357\0\331\331\0\222\222\0\347\347\0\357\357\0\331\331\0\222" + "\222\0\347\347\0\357\357\0\331\331\0\222\222\0\347\347\0\357\357\0\331\331" + "\0\222\222\0\347\347\0\357\357\0\331\331\0\222\222\0\347\347\0\357\357\0" + "\331\331\0\222\222\0\357\357\0\346\346\0\320\320\0\351\351\0\327\327\0\343" + "\343\0\276\276\0\333\333\0\322\322\0\266\266\0yy\0\240\240\0\210\210\0\240" + "\240\0<<\0dd\0dd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0dd\0<<\0\240\240\0\210\210\0\240\240\0aa\0ww\0nn\0\177" + "\177\0MM\0SS\0OO\0SS\0" + "22\0WW\0TT\0XX\0" + "55\0UU\0UU\0XX\0" + "55\0UU\0UU\0" + "XX\0" + "55\0UU\0UU\0XX\0" + "55\0UU\0UU\0XX\0" + "55\0UU\0UU\0XX\0" + "55\0UU\0UU\0" + "XX\0" + "55\0UU\0UU\0XX\0" + "55\0UU\0UU\0XX\0" + "55\0UU\0XX\0TT\0TT\0LL\0OO\0SS" + "\0SS\0ss\0\177\177\0nn\0nn\0yy\0\210\210\0\240\240\0\240\240\0<<\0dd\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0<<" + "\0\240\240\0\240\240\0\210\210\0HH\0\205\205\0\351\351\0\333\333\0pp\0\225" + "\225\0\371\371\0\363\363\0\202\202\0\231\231\0\330\330\0\325\325\0\203\203" + "\0\231\231\0\331\331\0\324\324\0\203\203\0\231\231\0\331\331\0\324\324\0" + "\203\203\0\231\231\0\331\331\0\324\324\0\203\203\0\231\231\0\331\331\0\324" + "\324\0\203\203\0\231\231\0\331\331\0\324\324\0\203\203\0\231\231\0\331\331" + "\0\324\324\0\203\203\0\231\231\0\331\331\0\324\324\0\203\203\0\231\231\0" + "\331\331\0\324\324\0\203\203\0\231\231\0\331\331\0\325\325\0\231\231\0\231" + "\231\0\330\330\0\323\323\0\371\371\0\371\371\0\274\274\0\257\257\0\351\351" + "\0\351\351\0\205\205\0``\0\240\240\0\240\240\0\240\240\0<<\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0<<\0\240\240" + "\0\240\240\0RR\0\207\207\0\304\304\0\304\304\0nn\0\275\275\0\343\343\0\343" + "\343\0\205\205\0\324\324\0\352\352\0\352\352\0\214\214\0\316\316\0\352\352" + "\0\352\352\0\213\213\0\316\316\0\352\352\0\352\352\0\213\213\0\316\316\0" + "\352\352\0\352\352\0\213\213\0\316\316\0\352\352\0\352\352\0\213\213\0\316" + "\316\0\352\352\0\352\352\0\213\213\0\316\316\0\352\352\0\352\352\0\213\213" + "\0\316\316\0\352\352\0\352\352\0\213\213\0\316\316\0\352\352\0\352\352\0" + "\213\213\0\316\316\0\352\352\0\352\352\0\214\214\0\324\324\0\336\336\0\336" + "\336\0\331\331\0\310\310\0\343\343\0\343\343\0\325\325\0\217\217\0\254\254" + "\0\254\254\0\207\207\0aa\0\240\240\0\240\240\0<<\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\240\240\0\240\240\0aa" + "\0\225\225\0\304\304\0\304\304\0\205\205\0\276\276\0\343\343\0\340\340\0" + "\222\222\0\333\333\0\352\352\0\351\351\0\226\226\0\347\347\0\362\362\0\333" + "\333\0\230\230\0\351\351\0\361\361\0\333\333\0\230\230\0\351\351\0\361\361" + "\0\333\333\0\230\230\0\351\351\0\361\361\0\333\333\0\230\230\0\351\351\0" + "\361\361\0\333\333\0\230\230\0\351\351\0\361\361\0\333\333\0\230\230\0\351" + "\351\0\361\361\0\333\333\0\230\230\0\351\351\0\361\361\0\333\333\0\230\230" + "\0\351\351\0\361\361\0\333\333\0\230\230\0\362\362\0\351\351\0\323\323\0" + "\366\366\0\336\336\0\351\351\0\304\304\0\351\351\0\343\343\0\304\304\0\217" + "\217\0\333\333\0\254\254\0\266\266\0aa\0\240\240\0\240\240\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\240\240\0aa" + "\0\305\305\0\225\225\0\304\304\0ww\0\205\205\0ss\0\211\211\0RR\0VV\0PP\0" + "VV\0" + "33\0XX\0UU\0YY\0" + "66\0UU\0UU\0XX\0" + "66\0UU\0UU\0XX\0" + "66\0UU\0UU\0" + "XX\0" + "66\0UU\0UU\0XX\0" + "66\0UU\0UU\0XX\0" + "66\0UU\0UU\0XX\0" + "66\0UU\0UU\0" + "XX\0" + "66\0UU\0UU\0XX\0" + "66\0UU\0YY\0UU\0UU\0MM\0QQ\0UU\0UU\0ww\0\211\211" + "\0ww\0||\0\217\217\0\254\254\0\266\266\0\305\305\0aa\0\240\240\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0aa\0\305" + "\305\0\305\305\0\225\225\0UU\0\222\222\0\366\366\0\340\340\0tt\0\231\231" + "\0\375\375\0\364\364\0\203\203\0\231\231\0\331\331\0\326\326\0\203\203\0" + "\231\231\0\331\331\0\324\324\0\203\203\0\231\231\0\331\331\0\324\324\0\203" + "\203\0\231\231\0\331\331\0\324\324\0\203\203\0\231\231\0\331\331\0\324\324" + "\0\203\203\0\231\231\0\331\331\0\324\324\0\203\203\0\231\231\0\331\331\0" + "\324\324\0\203\203\0\231\231\0\331\331\0\324\324\0\203\203\0\231\231\0\331" + "\331\0\324\324\0\203\203\0\231\231\0\331\331\0\326\326\0\231\231\0\231\231" + "\0\331\331\0\324\324\0\373\373\0\375\375\0\300\300\0\263\263\0\361\361\0" + "\366\366\0\222\222\0mm\0\266\266\0\305\305\0\305\305\0aa\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0<<\0\305\305\0" + "\305\305\0``\0\214\214\0\321\321\0\321\321\0rr\0\277\277\0\346\346\0\346" + "\346\0\206\206\0\324\324\0\353\353\0\353\353\0\215\215\0\316\316\0\353\353" + "\0\353\353\0\213\213\0\316\316\0\353\353\0\353\353\0\213\213\0\316\316\0" + "\353\353\0\353\353\0\213\213\0\316\316\0\353\353\0\353\353\0\213\213\0\316" + "\316\0\353\353\0\353\353\0\213\213\0\316\316\0\353\353\0\353\353\0\213\213" + "\0\316\316\0\353\353\0\353\353\0\213\213\0\316\316\0\353\353\0\353\353\0" + "\213\213\0\316\316\0\353\353\0\353\353\0\215\215\0\324\324\0\337\337\0\337" + "\337\0\331\331\0\312\312\0\346\346\0\346\346\0\330\330\0\224\224\0\271\271" + "\0\271\271\0\217\217\0nn\0\305\305\0\305\305\0<<\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\240\240\0\305\305\0ww" + "\0\225\225\0\304\304\0\314\314\0\222\222\0\277\277\0\343\343\0\342\342\0" + "\226\226\0\333\333\0\352\352\0\351\351\0\227\227\0\350\350\0\362\362\0\333" + "\333\0\230\230\0\351\351\0\361\361\0\333\333\0\230\230\0\351\351\0\361\361" + "\0\333\333\0\230\230\0\351\351\0\361\361\0\333\333\0\230\230\0\351\351\0" + "\361\361\0\333\333\0\230\230\0\351\351\0\361\361\0\333\333\0\230\230\0\351" + "\351\0\361\361\0\333\333\0\230\230\0\351\351\0\361\361\0\333\333\0\230\230" + "\0\351\351\0\361\361\0\333\333\0\230\230\0\362\362\0\351\351\0\323\323\0" + "\370\370\0\336\336\0\352\352\0\306\306\0\354\354\0\344\344\0\305\305\0\227" + "\227\0\343\343\0\254\254\0\266\266\0ww\0\305\305\0\240\240\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\240\240\0aa" + "\0\333\333\0\236\236\0\304\304\0ww\0\210\210\0tt\0\211\211\0RR\0VV\0PP\0" + "VV\0" + "33\0XX\0UU\0YY\0" + "66\0UU\0UU\0XX\0" + "66\0UU\0UU\0XX\0" + "66\0UU\0UU\0" + "XX\0" + "66\0UU\0UU\0XX\0" + "66\0UU\0UU\0XX\0" + "66\0UU\0UU\0XX\0" + "66\0UU\0UU\0" + "XX\0" + "66\0UU\0UU\0XX\0" + "66\0UU\0YY\0UU\0UU\0MM\0QQ\0UU\0UU\0ww\0\211\211" + "\0ww\0}}\0\217\217\0\254\254\0\276\276\0\333\333\0aa\0\240\240\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0aa\0\305" + "\305\0\305\305\0\236\236\0XX\0\222\222\0\366\366\0\341\341\0tt\0\231\231" + "\0\375\375\0\364\364\0\203\203\0\231\231\0\331\331\0\326\326\0\203\203\0" + "\231\231\0\331\331\0\324\324\0\203\203\0\231\231\0\331\331\0\324\324\0\203" + "\203\0\231\231\0\331\331\0\324\324\0\203\203\0\231\231\0\331\331\0\324\324" + "\0\203\203\0\231\231\0\331\331\0\324\324\0\203\203\0\231\231\0\331\331\0" + "\324\324\0\203\203\0\231\231\0\331\331\0\324\324\0\203\203\0\231\231\0\331" + "\331\0\324\324\0\203\203\0\231\231\0\331\331\0\326\326\0\231\231\0\231\231" + "\0\331\331\0\324\324\0\373\373\0\375\375\0\300\300\0\263\263\0\361\361\0" + "\366\366\0\222\222\0pp\0\276\276\0\305\305\0\305\305\0aa\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0<<\0\305\305\0" + "\305\305\0``\0\217\217\0\324\324\0\324\324\0rr\0\300\300\0\347\347\0\347" + "\347\0\206\206\0\324\324\0\353\353\0\353\353\0\215\215\0\316\316\0\353\353" + "\0\353\353\0\213\213\0\316\316\0\353\353\0\353\353\0\213\213\0\316\316\0" + "\353\353\0\353\353\0\213\213\0\316\316\0\353\353\0\353\353\0\213\213\0\316" + "\316\0\353\353\0\353\353\0\213\213\0\316\316\0\353\353\0\353\353\0\213\213" + "\0\316\316\0\353\353\0\353\353\0\213\213\0\316\316\0\353\353\0\353\353\0" + "\213\213\0\316\316\0\353\353\0\353\353\0\215\215\0\324\324\0\337\337\0\337" + "\337\0\332\332\0\312\312\0\347\347\0\347\347\0\330\330\0\224\224\0\274\274" + "\0\274\274\0\222\222\0nn\0\305\305\0\305\305\0<<\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\240\240\0\305\305\0ww" + "\0\225\225\0\304\304\0\314\314\0\225\225\0\300\300\0\344\344\0\342\342\0" + "\226\226\0\333\333\0\352\352\0\351\351\0\227\227\0\350\350\0\362\362\0\333" + "\333\0\230\230\0\351\351\0\361\361\0\333\333\0\230\230\0\351\351\0\361\361" + "\0\333\333\0\230\230\0\351\351\0\361\361\0\333\333\0\230\230\0\351\351\0" + "\361\361\0\333\333\0\230\230\0\351\351\0\361\361\0\333\333\0\230\230\0\351" + "\351\0\361\361\0\333\333\0\230\230\0\351\351\0\361\361\0\333\333\0\230\230" + "\0\351\351\0\361\361\0\333\333\0\230\230\0\362\362\0\351\351\0\323\323\0" + "\370\370\0\337\337\0\352\352\0\306\306\0\355\355\0\345\345\0\306\306\0\231" + "\231\0\343\343\0\254\254\0\266\266\0ww\0\305\305\0\240\240\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\240\240\0aa" + "\0\333\333\0\236\236\0\304\304\0ww\0\210\210\0tt\0\211\211\0RR\0VV\0PP\0" + "VV\0" + "33\0XX\0UU\0YY\0" + "66\0UU\0UU\0XX\0" + "66\0UU\0UU\0XX\0" + "66\0UU\0UU\0" + "XX\0" + "66\0UU\0UU\0XX\0" + "66\0UU\0UU\0XX\0" + "66\0UU\0UU\0XX\0" + "66\0UU\0UU\0" + "XX\0" + "66\0UU\0UU\0XX\0" + "66\0UU\0YY\0UU\0UU\0MM\0QQ\0UU\0UU\0ww\0\211\211" + "\0ww\0}}\0\217\217\0\254\254\0\276\276\0\333\333\0aa\0\240\240\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0aa\0\305" + "\305\0\305\305\0\236\236\0XX\0\222\222\0\366\366\0\341\341\0tt\0\231\231" + "\0\375\375\0\364\364\0\203\203\0\231\231\0\331\331\0\326\326\0\203\203\0" + "\231\231\0\331\331\0\324\324\0\203\203\0\231\231\0\331\331\0\324\324\0\203" + "\203\0\231\231\0\331\331\0\324\324\0\203\203\0\231\231\0\331\331\0\324\324" + "\0\203\203\0\231\231\0\331\331\0\324\324\0\203\203\0\231\231\0\331\331\0" + "\324\324\0\203\203\0\231\231\0\331\331\0\324\324\0\203\203\0\231\231\0\331" + "\331\0\324\324\0\203\203\0\231\231\0\331\331\0\326\326\0\231\231\0\231\231" + "\0\331\331\0\324\324\0\373\373\0\375\375\0\300\300\0\263\263\0\361\361\0" + "\366\366\0\222\222\0pp\0\276\276\0\305\305\0\305\305\0aa\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0<<\0\305\305\0" + "\305\305\0``\0\217\217\0\324\324\0\324\324\0rr\0\300\300\0\347\347\0\347" + "\347\0\206\206\0\324\324\0\353\353\0\353\353\0\215\215\0\316\316\0\353\353" + "\0\353\353\0\213\213\0\316\316\0\353\353\0\353\353\0\213\213\0\316\316\0" + "\353\353\0\353\353\0\213\213\0\316\316\0\353\353\0\353\353\0\213\213\0\316" + "\316\0\353\353\0\353\353\0\213\213\0\316\316\0\353\353\0\353\353\0\213\213" + "\0\316\316\0\353\353\0\353\353\0\213\213\0\316\316\0\353\353\0\353\353\0" + "\213\213\0\316\316\0\353\353\0\353\353\0\215\215\0\324\324\0\337\337\0\337" + "\337\0\332\332\0\312\312\0\347\347\0\347\347\0\330\330\0\224\224\0\274\274" + "\0\274\274\0\222\222\0nn\0\305\305\0\305\305\0<<\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\240\240\0\305\305\0ww" + "\0\225\225\0\304\304\0\314\314\0\225\225\0\300\300\0\344\344\0\342\342\0" + "\226\226\0\333\333\0\352\352\0\351\351\0\227\227\0\350\350\0\362\362\0\333" + "\333\0\230\230\0\351\351\0\361\361\0\333\333\0\230\230\0\351\351\0\361\361" + "\0\333\333\0\230\230\0\351\351\0\361\361\0\333\333\0\230\230\0\351\351\0" + "\361\361\0\333\333\0\230\230\0\351\351\0\361\361\0\333\333\0\230\230\0\351" + "\351\0\361\361\0\333\333\0\230\230\0\351\351\0\361\361\0\333\333\0\230\230" + "\0\351\351\0\361\361\0\333\333\0\230\230\0\362\362\0\351\351\0\323\323\0" + "\370\370\0\337\337\0\352\352\0\306\306\0\355\355\0\345\345\0\306\306\0\231" + "\231\0\343\343\0\254\254\0\266\266\0ww\0\305\305\0\240\240\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\240\240\0aa" + "\0\333\333\0\236\236\0\304\304\0ww\0\210\210\0tt\0\211\211\0RR\0VV\0PP\0" + "VV\0" + "33\0XX\0UU\0YY\0" + "66\0UU\0UU\0XX\0" + "66\0UU\0UU\0XX\0" + "66\0UU\0UU\0" + "XX\0" + "66\0UU\0UU\0XX\0" + "66\0UU\0UU\0XX\0" + "66\0UU\0UU\0XX\0" + "66\0UU\0UU\0" + "XX\0" + "66\0UU\0UU\0XX\0" + "66\0UU\0YY\0UU\0UU\0MM\0QQ\0UU\0UU\0ww\0\211\211" + "\0ww\0}}\0\217\217\0\254\254\0\276\276\0\333\333\0aa\0\240\240\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0aa\0\305" + "\305\0\305\305\0\236\236\0XX\0\222\222\0\366\366\0\341\341\0tt\0\231\231" + "\0\375\375\0\364\364\0\203\203\0\231\231\0\331\331\0\326\326\0\203\203\0" + "\231\231\0\331\331\0\324\324\0\203\203\0\231\231\0\331\331\0\324\324\0\203" + "\203\0\231\231\0\331\331\0\324\324\0\203\203\0\231\231\0\331\331\0\324\324" + "\0\203\203\0\231\231\0\331\331\0\324\324\0\203\203\0\231\231\0\331\331\0" + "\324\324\0\203\203\0\231\231\0\331\331\0\324\324\0\203\203\0\231\231\0\331" + "\331\0\324\324\0\203\203\0\231\231\0\331\331\0\326\326\0\231\231\0\231\231" + "\0\331\331\0\324\324\0\373\373\0\375\375\0\300\300\0\263\263\0\361\361\0" + "\366\366\0\222\222\0pp\0\276\276\0\305\305\0\305\305\0aa\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0<<\0\305\305\0" + "\305\305\0``\0\217\217\0\324\324\0\324\324\0rr\0\300\300\0\347\347\0\347" + "\347\0\206\206\0\324\324\0\353\353\0\353\353\0\215\215\0\316\316\0\353\353" + "\0\353\353\0\213\213\0\316\316\0\353\353\0\353\353\0\213\213\0\316\316\0" + "\353\353\0\353\353\0\213\213\0\316\316\0\353\353\0\353\353\0\213\213\0\316" + "\316\0\353\353\0\353\353\0\213\213\0\316\316\0\353\353\0\353\353\0\213\213" + "\0\316\316\0\353\353\0\353\353\0\213\213\0\316\316\0\353\353\0\353\353\0" + "\213\213\0\316\316\0\353\353\0\353\353\0\215\215\0\324\324\0\337\337\0\337" + "\337\0\332\332\0\312\312\0\347\347\0\347\347\0\330\330\0\224\224\0\274\274" + "\0\274\274\0\222\222\0nn\0\305\305\0\305\305\0<<\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\240\240\0\305\305\0ww" + "\0\225\225\0\304\304\0\314\314\0\225\225\0\300\300\0\344\344\0\342\342\0" + "\226\226\0\333\333\0\352\352\0\351\351\0\227\227\0\350\350\0\362\362\0\333" + "\333\0\230\230\0\351\351\0\361\361\0\333\333\0\230\230\0\351\351\0\361\361" + "\0\333\333\0\230\230\0\351\351\0\361\361\0\333\333\0\230\230\0\351\351\0" + "\361\361\0\333\333\0\230\230\0\351\351\0\361\361\0\333\333\0\230\230\0\351" + "\351\0\361\361\0\333\333\0\230\230\0\351\351\0\361\361\0\333\333\0\230\230" + "\0\351\351\0\361\361\0\333\333\0\230\230\0\362\362\0\351\351\0\323\323\0" + "\370\370\0\337\337\0\352\352\0\306\306\0\355\355\0\345\345\0\306\306\0\231" + "\231\0\343\343\0\254\254\0\266\266\0ww\0\305\305\0\240\240\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\240\240\0aa" + "\0\333\333\0\236\236\0\304\304\0ww\0\210\210\0tt\0\211\211\0RR\0VV\0PP\0" + "VV\0" + "33\0XX\0UU\0YY\0" + "66\0UU\0UU\0XX\0" + "66\0UU\0UU\0XX\0" + "66\0UU\0UU\0" + "XX\0" + "66\0UU\0UU\0XX\0" + "66\0UU\0UU\0XX\0" + "66\0UU\0UU\0XX\0" + "66\0UU\0UU\0" + "XX\0" + "66\0UU\0UU\0XX\0" + "66\0UU\0YY\0UU\0UU\0MM\0QQ\0UU\0UU\0ww\0\211\211" + "\0ww\0}}\0\217\217\0\254\254\0\276\276\0\333\333\0aa\0\240\240\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0aa\0\305" + "\305\0\305\305\0\236\236\0XX\0\222\222\0\366\366\0\341\341\0tt\0\231\231" + "\0\375\375\0\364\364\0\203\203\0\231\231\0\331\331\0\326\326\0\203\203\0" + "\231\231\0\331\331\0\324\324\0\203\203\0\231\231\0\331\331\0\324\324\0\203" + "\203\0\231\231\0\331\331\0\324\324\0\203\203\0\231\231\0\331\331\0\324\324" + "\0\203\203\0\231\231\0\331\331\0\324\324\0\203\203\0\231\231\0\331\331\0" + "\324\324\0\203\203\0\231\231\0\331\331\0\324\324\0\203\203\0\231\231\0\331" + "\331\0\324\324\0\203\203\0\231\231\0\331\331\0\326\326\0\231\231\0\231\231" + "\0\331\331\0\324\324\0\373\373\0\375\375\0\300\300\0\263\263\0\361\361\0" + "\366\366\0\222\222\0pp\0\276\276\0\305\305\0\305\305\0aa\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0<<\0\305\305\0" + "\305\305\0``\0\217\217\0\324\324\0\324\324\0rr\0\300\300\0\347\347\0\347" + "\347\0\206\206\0\324\324\0\353\353\0\353\353\0\215\215\0\316\316\0\353\353" + "\0\353\353\0\213\213\0\316\316\0\353\353\0\353\353\0\213\213\0\316\316\0" + "\353\353\0\353\353\0\213\213\0\316\316\0\353\353\0\353\353\0\213\213\0\316" + "\316\0\353\353\0\353\353\0\213\213\0\316\316\0\353\353\0\353\353\0\213\213" + "\0\316\316\0\353\353\0\353\353\0\213\213\0\316\316\0\353\353\0\353\353\0" + "\213\213\0\316\316\0\353\353\0\353\353\0\215\215\0\324\324\0\337\337\0\337" + "\337\0\332\332\0\312\312\0\347\347\0\347\347\0\330\330\0\224\224\0\274\274" + "\0\274\274\0\222\222\0nn\0\305\305\0\305\305\0<<\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\240\240\0\305\305\0ww" + "\0\225\225\0\304\304\0\314\314\0\225\225\0\300\300\0\344\344\0\342\342\0" + "\226\226\0\333\333\0\352\352\0\351\351\0\227\227\0\350\350\0\362\362\0\333" + "\333\0\230\230\0\351\351\0\361\361\0\333\333\0\230\230\0\351\351\0\361\361" + "\0\333\333\0\230\230\0\351\351\0\361\361\0\333\333\0\230\230\0\351\351\0" + "\361\361\0\333\333\0\230\230\0\351\351\0\361\361\0\333\333\0\230\230\0\351" + "\351\0\361\361\0\333\333\0\230\230\0\351\351\0\361\361\0\333\333\0\230\230" + "\0\351\351\0\361\361\0\333\333\0\230\230\0\362\362\0\351\351\0\323\323\0" + "\370\370\0\337\337\0\352\352\0\306\306\0\355\355\0\345\345\0\306\306\0\231" + "\231\0\343\343\0\254\254\0\266\266\0ww\0\305\305\0\240\240\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\240\240\0aa" + "\0\333\333\0\236\236\0\304\304\0ww\0\340\340\0\300\300\0\343\343\0\210\210" + "\0\354\354\0\333\333\0\352\352\0\215\215\0\361\361\0\350\350\0\362\362\0" + "\223\223\0\351\351\0\351\351\0\361\361\0\223\223\0\351\351\0\351\351\0\361" + "\361\0\223\223\0\351\351\0\351\351\0\361\361\0\223\223\0\351\351\0\351\351" + "\0\361\361\0\223\223\0\351\351\0\351\351\0\361\361\0\223\223\0\351\351\0" + "\351\351\0\361\361\0\223\223\0\351\351\0\351\351\0\361\361\0\223\223\0\351" + "\351\0\351\351\0\361\361\0\223\223\0\351\351\0\362\362\0\351\351\0\351\351" + "\0\323\323\0\336\336\0\351\351\0\351\351\0\304\304\0\343\343\0\305\305\0" + "\317\317\0\217\217\0\254\254\0\276\276\0\333\333\0aa\0\240\240\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0aa\0\305" + "\305\0\305\305\0\236\236\0\222\222\0\361\361\0\361\361\0\316\316\0\230\230" + "\0\373\373\0\373\373\0\344\344\0\231\231\0\375\375\0\375\375\0\357\357\0" + "\231\231\0\375\375\0\375\375\0\347\347\0\231\231\0\375\375\0\375\375\0\347" + "\347\0\231\231\0\375\375\0\375\375\0\347\347\0\231\231\0\375\375\0\375\375" + "\0\347\347\0\231\231\0\375\375\0\375\375\0\347\347\0\231\231\0\375\375\0" + "\375\375\0\347\347\0\231\231\0\375\375\0\375\375\0\347\347\0\231\231\0\375" + "\375\0\375\375\0\347\347\0\231\231\0\375\375\0\375\375\0\360\360\0\373\373" + "\0\375\375\0\375\375\0\347\347\0\367\367\0\373\373\0\373\373\0\326\326\0" + "\351\351\0\361\361\0\361\361\0\271\271\0\276\276\0\305\305\0\305\305\0aa" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0<<\0\305\305\0\305\305\0\236\236\0HH\0\271\271\0\271\271\0\224\224\0VV" + "\0\277\277\0\277\277\0\251\251\0DD\0\252\252\0\252\252\0\235\235\0FF\0\253" + "\253\0\253\253\0\224\224\0EE\0\253\253\0\253\253\0\224\224\0EE\0\253\253" + "\0\253\253\0\224\224\0EE\0\253\253\0\253\253\0\224\224\0EE\0\253\253\0\253" + "\253\0\224\224\0EE\0\253\253\0\253\253\0\224\224\0EE\0\253\253\0\253\253" + "\0\224\224\0EE\0\253\253\0\253\253\0\224\224\0EE\0\253\253\0\253\253\0\235" + "\235\0rr\0uu\0uu\0^^\0\272\272\0\277\277\0\277\277\0\230\230\0\205\205\0" + "\222\222\0\222\222\0MM\0\266\266\0\305\305\0\305\305\0<<\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\240\240\0\305" + "\305\0\305\305\0RR\0\236\236\0\254\254\0\361\361\0VV\0\267\267\0\263\263" + "\0\356\356\0ee\0\247\247\0\244\244\0\356\356\0^^\0\251\251\0\247\247\0\365" + "\365\0bb\0\242\242\0\247\247\0\365\365\0bb\0\242\242\0\247\247\0\365\365" + "\0bb\0\242\242\0\247\247\0\365\365\0bb\0\242\242\0\247\247\0\365\365\0bb" + "\0\242\242\0\247\247\0\365\365\0bb\0\242\242\0\247\247\0\365\365\0bb\0\242" + "\242\0\247\247\0\365\365\0bb\0\242\242\0\247\247\0\365\365\0\252\252\0ee" + "\0jj\0\345\345\0tt\0\246\246\0\251\251\0\321\321\0\272\272\0ff\0\222\222" + "\0\322\322\0ww\0\210\210\0\305\305\0\305\305\0\240\240\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\240\240\0\240\240" + "\0\305\305\0``\0\236\236\0\236\236\0\254\254\0VV\0\264\264\0\254\254\0\261" + "\261\0dd\0\246\246\0\240\240\0\243\243\0^^\0\251\251\0\246\246\0\246\246" + "\0bb\0\242\242\0\246\246\0\246\246\0bb\0\242\242\0\246\246\0\246\246\0bb" + "\0\242\242\0\246\246\0\246\246\0bb\0\242\242\0\246\246\0\246\246\0bb\0\242" + "\242\0\246\246\0\246\246\0bb\0\242\242\0\246\246\0\246\246\0bb\0\242\242" + "\0\246\246\0\246\246\0bb\0\242\242\0\246\246\0\246\246\0\251\251\0dd\0hh" + "\0hh\0pp\0\243\243\0\240\240\0\236\236\0\264\264\0cc\0\177\177\0ww\0ww\0" + "\225\225\0\305\305\0\240\240\0\240\240\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\240\240\0\240\240\0\240\240\0``" + "\0\351\351\0\333\333\0\333\333\0||\0\366\366\0\361\361\0\361\361\0\211\211" + "\0\373\373\0\371\371\0\371\371\0\221\221\0\375\375\0\374\374\0\374\374\0" + "\224\224\0\365\365\0\374\374\0\374\374\0\224\224\0\365\365\0\374\374\0\374" + "\374\0\224\224\0\365\365\0\374\374\0\374\374\0\224\224\0\365\365\0\374\374" + "\0\374\374\0\224\224\0\365\365\0\374\374\0\374\374\0\224\224\0\365\365\0" + "\374\374\0\374\374\0\224\224\0\365\365\0\374\374\0\374\374\0\224\224\0\365" + "\365\0\374\374\0\374\374\0\375\375\0\356\356\0\371\371\0\371\371\0\372\372" + "\0\340\340\0\361\361\0\361\361\0\364\364\0\307\307\0\333\333\0\333\333\0" + "\351\351\0\225\225\0\240\240\0\240\240\0\240\240\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0dd\0\240\240\0\240\240" + "\0aa\0\304\304\0\351\351\0\351\351\0\205\205\0\340\340\0\366\366\0\366\366" + "\0\222\222\0\355\355\0\373\373\0\373\373\0\227\227\0\364\364\0\375\375\0" + "\375\375\0\230\230\0\360\360\0\375\375\0\375\375\0\230\230\0\360\360\0\375" + "\375\0\375\375\0\230\230\0\360\360\0\375\375\0\375\375\0\230\230\0\360\360" + "\0\375\375\0\375\375\0\230\230\0\360\360\0\375\375\0\375\375\0\230\230\0" + "\360\360\0\375\375\0\375\375\0\230\230\0\360\360\0\375\375\0\375\375\0\230" + "\230\0\360\360\0\375\375\0\375\375\0\373\373\0\356\356\0\373\373\0\373\373" + "\0\367\367\0\340\340\0\364\364\0\364\364\0\354\354\0\304\304\0\351\351\0" + "\351\351\0\322\322\0\210\210\0\240\240\0\240\240\0dd\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0dd\0\240\240\0\240" + "\240\0<<\0\240\240\0\305\305\0\351\351\0ww\0\320\320\0\301\301\0\324\324" + "\0\211\211\0\345\345\0\316\316\0\324\324\0\217\217\0\356\356\0\323\323\0" + "\326\326\0\223\223\0\354\354\0\323\323\0\326\326\0\223\223\0\354\354\0\323" + "\323\0\326\326\0\223\223\0\354\354\0\323\323\0\326\326\0\223\223\0\354\354" + "\0\323\323\0\326\326\0\223\223\0\354\354\0\323\323\0\326\326\0\223\223\0" + "\354\354\0\323\323\0\326\326\0\223\223\0\354\354\0\323\323\0\326\326\0\223" + "\223\0\354\354\0\323\323\0\326\326\0\362\362\0\344\344\0\261\261\0\272\272" + "\0\364\364\0\340\340\0\225\225\0\205\205\0\340\340\0\276\276\0\351\351\0" + "\266\266\0\240\240\0dd\0\240\240\0\240\240\0dd\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0dd\0dd\0\240\240\0aa\0\240" + "\240\0\240\240\0\305\305\0ww\0\305\305\0\240\240\0\266\266\0\205\205\0\333" + "\333\0\266\266\0\304\304\0\215\215\0\352\352\0\305\305\0\314\314\0\222\222" + "\0\352\352\0\305\305\0\314\314\0\222\222\0\352\352\0\305\305\0\314\314\0" + "\222\222\0\352\352\0\305\305\0\314\314\0\222\222\0\352\352\0\305\305\0\314" + "\314\0\222\222\0\352\352\0\305\305\0\314\314\0\222\222\0\352\352\0\305\305" + "\0\314\314\0\222\222\0\352\352\0\305\305\0\314\314\0\222\222\0\352\352\0" + "\305\305\0\314\314\0\361\361\0\335\335\0\242\242\0\236\236\0\333\333\0\312" + "\312\0ii\0aa\0\305\305\0\255\255\0\266\266\0\240\240\0\240\240\0\210\210" + "\0\240\240\0dd\0dd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0dd\0dd\0dd\0aa\0\305\305\0\240\240\0\240\240\0ww\0\333" + "\333\0\305\305\0\305\305\0\205\205\0\351\351\0\333\333\0\333\333\0\217\217" + "\0\363\363\0\351\351\0\351\351\0\223\223\0\357\357\0\351\351\0\351\351\0" + "\223\223\0\357\357\0\351\351\0\351\351\0\223\223\0\357\357\0\351\351\0\351" + "\351\0\223\223\0\357\357\0\351\351\0\351\351\0\223\223\0\357\357\0\351\351" + "\0\351\351\0\223\223\0\357\357\0\351\351\0\351\351\0\223\223\0\357\357\0" + "\351\351\0\351\351\0\223\223\0\357\357\0\351\351\0\351\351\0\363\363\0\345" + "\345\0\333\333\0\333\333\0\340\340\0\312\312\0\305\305\0\305\305\0\322\322" + "\0\255\255\0\240\240\0\240\240\0\305\305\0\210\210\0dd\0dd\0dd\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0dd" + "\0dd\0dd\0aa\0\305\305\0\305\305\0\240\240\0ww\0\333\333\0\333\333\0\305" + "\305\0\205\205\0\355\355\0\355\355\0\336\336\0\215\215\0\364\364\0\364\364" + "\0\335\335\0\215\215\0\364\364\0\364\364\0\335\335\0\215\215\0\364\364\0" + "\364\364\0\335\335\0\215\215\0\364\364\0\364\364\0\335\335\0\215\215\0\364" + "\364\0\364\364\0\335\335\0\215\215\0\364\364\0\364\364\0\335\335\0\215\215" + "\0\364\364\0\364\364\0\335\335\0\215\215\0\364\364\0\364\364\0\335\335\0" + "\215\215\0\364\364\0\364\364\0\335\335\0\351\351\0\355\355\0\355\355\0\312" + "\312\0\305\305\0\322\322\0\322\322\0\255\255\0\240\240\0\305\305\0\305\305" + "\0\210\210\0dd\0dd\0dd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0dd\0dd\0\0\0\0\0\0\0dd\0\305\305\0aa" + "\0" + "11\0\225\225\0\351\351\0\205\205\0HH\0\254\254\0\333\333\0ww\0BB\0\264" + "\264\0\340\340\0nn\0BB\0\264\264\0\340\340\0nn\0BB\0\264\264\0\340\340\0" + "nn\0BB\0\264\264\0\340\340\0nn\0BB\0\264\264\0\340\340\0nn\0BB\0\264\264" + "\0\340\340\0nn\0BB\0\264\264\0\340\340\0nn\0BB\0\264\264\0\340\340\0nn\0" + "BB\0\264\264\0\340\340\0nn\0nn\0\205\205\0\314\314\0\266\266\0\304\304\0" + "\351\351\0\236\236\0yy\0\210\210\0\305\305\0<<\0\0\0\0\0\0\0dd\0dd\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0dd\0dd\0\0\0\0\0\0\0dd\0dd\0\0\0\0\0\0\0dd\0dd\0\0\0\0\0\0" + "\0dd\0dd\0\25\25\0\14\14\0dd\0dd\0\25\25\0\14\14\0dd\0dd\0\25\25\0\14\14" + "\0dd\0dd\0\25\25\0\14\14\0dd\0dd\0\25\25\0\14\14\0dd\0dd\0\25\25\0\14\14" + "\0dd\0dd\0\25\25\0\14\14\0dd\0dd\0\25\25\0\14\14\0dd\0dd\0\25\25\0\14\14" + "\0dd\0dd\0\25\25\0\25\25\0\0\0\0\0\0\0$$\0$$\0\0\0\0\0\0\0<<\0<<\0\0\0\0" + "\0\0\0dd\0dd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0dd\0dd\0\0\0\0\0\0\0dd\0dd\0" + "\0\0\0\0\0\0dd\0dd\0\0\0\0\0\0\0yy\0yy\0\0\0\0\0\0\0yy\0yy\0\0\0\0\0\0\0" + "yy\0yy\0\0\0\0\0\0\0yy\0yy\0\0\0\0\0\0\0yy\0yy\0\0\0\0\0\0\0yy\0yy\0\0\0" + "\0\0\0\0yy\0yy\0\0\0\0\0\0\0yy\0yy\0\0\0\0\0\0\0yy\0yy\0\0\0\0\0\0\0yy\0" + "yy\0\0\0\0\0\0\0$$\0$$\0\0\0\0\0\0\0<<\0<<\0\0\0\0\0\0\0dd\0dd\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0dd\0dd\0dd\0\0\0\0dd\0dd\0dd\0\0\0\0dd" + "\0\210\210\0\210\210\0\25\25\0dd\0\210\210\0\210\210\0\25\25\0dd\0\210\210" + "\0\210\210\0\25\25\0dd\0\210\210\0\210\210\0\25\25\0dd\0\210\210\0\210\210" + "\0\25\25\0dd\0\210\210\0\210\210\0\25\25\0dd\0\210\210\0\210\210\0\25\25" + "\0dd\0\210\210\0\210\210\0\25\25\0dd\0\210\210\0\210\210\0\25\25\0dd\0\210" + "\210\0\210\210\0\25\25\0dd\0\210\210\0\210\210\0$$\0\0\0\0<<\0<<\0<<\0\0" + "\0\0dd\0dd\0dd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0dd\0dd\0<<\0<<\0\240\240\0\240\240\0aa\0aa\0\240\240\0\240\240\0aa\0" + "aa\0\240\240\0\240\240\0aa\0aa\0\240\240\0\240\240\0aa\0aa\0\240\240\0\240" + "\240\0aa\0aa\0\240\240\0\240\240\0aa\0aa\0\240\240\0\240\240\0aa\0aa\0\240" + "\240\0\240\240\0aa\0aa\0\240\240\0\240\240\0aa\0aa\0\240\240\0\240\240\0" + "aa\0aa\0\240\240\0\240\240\0aa\0aa\0\240\240\0\240\240\0\240\240\0\240\240" + "\0dd\0dd\0dd\0dd\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", +}; + +/** + * \brief Returns the BlitBlend test image as SDL_Surface. + */ +SDL_Surface *SDLTest_ImageBlitBlend() +{ + SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormatFrom( + (void *)SDLTest_imageBlitBlend.pixel_data, + SDLTest_imageBlitBlend.width, + SDLTest_imageBlitBlend.height, + SDLTest_imageBlitBlend.bytes_per_pixel * 8, + SDLTest_imageBlitBlend.width * SDLTest_imageBlitBlend.bytes_per_pixel, + SDL_PIXELFORMAT_RGB24); + return surface; +} + +static const SDLTest_SurfaceImage_t SDLTest_imageBlitBlendMod = { + 80, + 60, + 3, + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", +}; + +/** + * \brief Returns the BlitBlendMod test image as SDL_Surface. + */ +SDL_Surface *SDLTest_ImageBlitBlendMod() +{ + SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormatFrom( + (void *)SDLTest_imageBlitBlendMod.pixel_data, + SDLTest_imageBlitBlendMod.width, + SDLTest_imageBlitBlendMod.height, + SDLTest_imageBlitBlendMod.bytes_per_pixel * 8, + SDLTest_imageBlitBlendMod.width * SDLTest_imageBlitBlendMod.bytes_per_pixel, + SDL_PIXELFORMAT_RGB24); + return surface; +} + +static const SDLTest_SurfaceImage_t SDLTest_imageBlitBlendNone = { + 80, + 60, + 3, + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\0\0\0\0\0\0\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\0\0\0\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377" + "\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\0" + "\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\377\0\0\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\377\0\0\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\0\0\0\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\0\0\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0" + "\377\377\0\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377" + "\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\377\0\377\377" + "\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\0\0\0\377\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0\0\0\0\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\0\0\0\377\377\0\377" + "\377\0\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\0\377\377\0" + "\377\377\0\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\0\0\0\0\0\0\377\377\0\377\377\0\377\377\0\377" + "\377\0\377\377\0\377\377\0\377\377\0\377\377\0\0\0\0\0\0\0\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377", +}; + +/** + * \brief Returns the BlitBlendNone test image as SDL_Surface. + */ +SDL_Surface *SDLTest_ImageBlitBlendNone() +{ + SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormatFrom( + (void *)SDLTest_imageBlitBlendNone.pixel_data, + SDLTest_imageBlitBlendNone.width, + SDLTest_imageBlitBlendNone.height, + SDLTest_imageBlitBlendNone.bytes_per_pixel * 8, + SDLTest_imageBlitBlendNone.width * SDLTest_imageBlitBlendNone.bytes_per_pixel, + SDL_PIXELFORMAT_RGB24); + return surface; +} + +static const SDLTest_SurfaceImage_t SDLTest_imageBlitBlendAll = { + 80, + 60, + 3, + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\0\0\4\0\0\0\0\0\0\0" + "\0\11\0\0\11\0\0\0\0\0\0\0\0\16\0\0\16\0\0\0\0\0\0\0\0\11\0\0\11\0\0\0\0" + "\0\0\0\0\14\0\0\14\0\0\0\0\0\0\0\0\17\0\0\17\0\0\0\0\0\0\0\0\21\0\0\21\0" + "\0\0\0\0\0\0\0K\0\0K\0\0\0\0\0\0\0\0T\0\0T\0\0\0\0\0\0\0\0^\0\0^\0\0\0\0" + "\0\0\0\0g\0\0g\0\0\0\0\0\0\0\0\317\0\0\317\0\0\317\0\0\317\0\0\317\0\0\317" + "\0\0\317\0\0\317\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\0\0\4\0\0\4\0\0\0\0\0\11\0\0\11\0\0\11" + "\0\0\0\0\0\16\0\0\16\0\0\16\0\0\0\0\0\22\0\0\22\0\0\11\0\0\0\0\0\14\0\0\14" + "\0\0\14\0\0\0\0\0\17\0\0\17\0\0\17\0\0\0\0\0\21\0\0\21\0\0\21\0\0\0\0\0\24" + "\0\0\24\0\0K\0\0\0\0\0T\0\0T\0\0T\0\0\0\0\0^\0\0^\0\0^\0\0\0\0\0g\0\0g\0" + "\0g\0\0\0\0\0q\0\0q\0\0\317\0\0\317\0\0\317\0\0\317\0\0\317\0\0\317\0\0\317" + "\0\0\317\0\0\317\0\0\317\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\4\0\0\4\0\0\4\0\0\0\0\0\11\0\0\11\0\0\11\0\0\0\0\0" + "\16\0\0\16\0\0\16\0\0\0\0\0\22\0\0\22\0\0\22\0\0\0\0\0\14\0\0\14\0\0\14\0" + "\0\0\0\0\17\0\0\17\0\0\17\0\0\0\0\0\21\0\0\21\0\0\21\0\0\0\0\0\24\0\0\24" + "\0\0\24\0\0\0\0\0T\0\0T\0\0T\0\0\0\0\0^\0\0^\0\0^\0\0\0\0\0g\0\0g\0\0g\0" + "\0\0\0\0q\0\0q\0\0q\0\0\317\0\0\317\0\0\317\0\0\317\0\0\317\0\0\317\0\0\317" + "\0\0\317\0\0\317\0\0\317\0\0\317\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\4\0\0\4\0\0\4\0\0\0\0\0\10\0\0\10\0\0\10\0\0\0\0\0\15" + "\0\0\15\0\0\15\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\16\0\0\16\0\0\16\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0J\0\0J\0\0J\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\317" + "\0\0\317\0\0\317\0\0\317\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\0\0\1\0\0\0\0\0\0\0\0\1\0\0\1\0\0\1\0\0\1" + "\0\0\4\0\0\4\0\0\0\0\0\0\0\0\7\0\0\7\0\0\0\0\0\0\0\0&\0\0&\0\0\32\0\0\32" + "\0\0&\0\0&\0\0&\0\0&\0\0C\0\0C\0\0\0\0\0\0\0\0^\0\0^\0\0\0\0\0\0\0\17\251" + "\0\17\251\0\17\251\0\17\251\0\17\251\0\17\251\0\17\251\0\17\251\0\0\0\0\0" + "\0\0\0\317\0\0\317\0\0\317\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\6\2\0\6\2\0\0\1\0\0\0\0\0\1\0\0\1\0\0\1\0\0\1\0\0\1\0\0\1\0\0" + "\17\0\0\0\0\0\4\0\0\11\0\0\11\0\0\0\0\6+\0\6+\0\0&\0\0\32\0\0&\0\0&\0\0&" + "\0\0&\0\0" + "5\0\0" + "5\0\2\210\0\0\0\0\0C\0\0|\0\0|\0\0\0\0\17\251\0\17\251" + "\0\17\251\0\17\251\0\17\251\0\17\251\0\17\251\0\17\251\0\17\251\0\17\251" + "\0$\360\0$\360\0\0\0\0\0\317\0\0\317\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1" + "\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\0\0\1\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\6\2\0\6\2\0\6\2\0\0\0\0\0\1\0\0\1\0\0\1\0\0\1\0\0\1\0\0\1" + "\0\0\1\0\0\0\0\0\17\0\0\17\0\0\4\0\0\0\0\6+\0\6+\0\6+\0\0\32\0\0&\0\0&\0" + "\0&\0\0&\0\0" + "5\0\0" + "5\0\0" + "5\0\0\0\0\2\210\0\2\210\0\0C\0\0\0\0\17\251\0" + "\17\251\0\17\251\0\17\251\0\17\251\0\17\251\0\17\251\0\17\251\0\17\251\0" + "\17\251\0\17\251\0$\360\0$\360\0$\360\0\0\0\0\0\317\0\0\317\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\1\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "$\360\0$\360\0$\360\0$\360\0\0\0\0\0\317\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\0" + "\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\14\1\0\14\1\0\14\1" + "\0\14\1\0\15\1\0\15\1\0\0\0\0\0\0\0\14\2\0\14\2\0\14\2\0\14\2\0\16\2\0\16" + "\2\0\0\0\0\0\0\0\14!\0\14!\0\14!\0\14!\0\17(\0\17(\0\0\0\0\0\0\0\14+\0\14" + "+\0\14+\0\14+\0\20" + "9\0\20" + "9\0\0\0\0\0\0\0\36\215\0\36\215\0\36\215\0\36" + "\215\0(\264\0(\264\0\0\0\0\0\0\0\36\251\0\36\251\0\36\251\0\36\251\0\36\251" + "\0\36\251\0\36\251\0\36\251\0\0\0\0\0\0\0$\360\0$\360\0$\360\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\1\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\36\3" + "\0\36\3\0\14\1\0\14\1\0\15\1\0\15\1\0\15\1\0\0\0\0\14\2\0\14\2\0\14\2\0\14" + "\2\0\16\2\0\16\2\0\16\2\0\0\0\0\14\3\0\14\3\0\14!\0\14!\0\17(\0\17(\0\17" + "(\0\0\0\0\14+\0\14+\0\14+\0\14+\0\20" + "9\0\20" + "9\0\20" + "9\0\0\0\0\14" + "7\0\14" + "" + "7\0\36\215\0\36\215\0(\264\0(\264\0(\264\0\0\0\0\36\251\0\36\251\0\36\251" + "\0\36\251\0\36\251\0\36\251\0\36\251\0\36\251\0\36\251\0\36\251\0H\360\0" + "H\360\0\0\0\0$\360\0$\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\0\0\1\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\36\3\0\36\3\0\36\3\0\14\1\0\15\1\0\15\1\0\15\1" + "\0\0\0\0\14\2\0\14\2\0\14\2\0\14\2\0\16\2\0\16\2\0\16\2\0\0\0\0\14\3\0\14" + "\3\0\14\3\0\14!\0\17(\0\17(\0\17(\0\0\0\0\14+\0\14+\0\14+\0\14+\0\20" + "9\0" + "\20" + "9\0\20" + "9\0\0\0\0\14" + "7\0\14" + "7\0\14" + "7\0\36\215\0(\264\0(\264\0(\264" + "\0\0\0\0\36\251\0\36\251\0\36\251\0\36\251\0\36\251\0\36\251\0\36\251\0\36" + "\251\0\36\251\0\36\251\0\36\251\0H\360\0H\360\0H\360\0\0\0\0$\360\0$\360" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\13\1\0\13\1\0\13\1\0\13\1\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\11!\0" + "\11!\0\11!\0\11!\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\23n\0\23n\0\23n\0\23n\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0H\360\0H\360\0H\360\0H\360\0\0\0\0$\360\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\1\0\1\1\0\0\0\0\0\0\0\0\0\0\0\0\0\25\0\0\25\0\0\25\0\0\27\0" + "\0\13\0\0\13\0\0\1\0\0\11\0\0\4\0\0\4\0\0\0\0\0\0\0\0\25\3\0\25\3\0\0\0\0" + "\0\0\0\25\3\0\25\3\0\25\3\0\25\3\0\3\1\0\3\1\0\2\1\0\7\5\0\7\3\0\7\3\0\0" + "\0\0\0\0\0\25" + "4\0\25" + "4\0\0\0\0\0\0\0\25" + "4\0\25" + "4\0\25" + "4\0\25" + "4\0\20" + "\35\0\20\35\0\11\22\0\23F\0\34" + "6\0\34" + "6\0\0\0\0\0\0\0L\317\0L\317\0L\317" + "\0L\317\0L\317\0L\317\0L\317\0L\317\0\0\0\0\0\0\0" + "2\317\0" + "2\317\0" + "2\317" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\1\0\0\0\0\0\0\0\0\0\0\25\0\0\25" + "\0\0\25\0\0\4\0\0\5\0\0\2\0\0\1\0\0\4\0\0\14\0\0\14\0\0\0\0\0\37\7\0\37\7" + "\0\25\3\0\0\0\0\25\3\0\25\3\0\25\3\0\25\3\0\37\6\0\37\6\0\15\4\0\11\3\0\7" + "\3\0\14\10\0\14\10\0\0\0\0\25\16\0\25\16\0\25" + "4\0\0\0\0\25" + "4\0\25" + "4\0" + "\25" + "4\0\25" + "4\0&Q\0&Q\0&Q\0\31" + "5\0\34" + "6\0&j\0&j\0\0\0\0" + "5q\0" + "5q\0L\317" + "\0L\317\0L\317\0L\317\0L\317\0L\317\0L\317\0L\317\0L\317\0L\317\0\0\0\0" + "2" + "\317\0" + "2\317\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\0\0\1\1\0\0\0\0\0\0\0\25\0" + "\0\25\0\0\25\0\0\31\1\0\5\0\0\5\0\0\2\0\0\4\0\0\14\0\0\14\0\0\0\0\0\37\7" + "\0\37\7\0\37\7\0\0\0\0\25\3\0\25\3\0\25\3\0\25\3\0\37\6\0\37\6\0\37\6\0\11" + "\3\0\16\6\0\16\6\0\7\3\0\0\0\0\25\16\0\25\16\0\25\16\0\0\0\0\25" + "4\0\25" + "4" + "\0\25" + "4\0\25" + "4\0&Q\0&Q\0&Q\0\31" + "5\0+X\0+X\0\34" + "6\0\0\0\0" + "5q\0" + "5q\0" + "" + "5q\0L\317\0L\317\0L\317\0L\317\0L\317\0L\317\0L\317\0L\317\0L\317\0L\317" + "\0L\317\0\0\0\0" + "2\317\0" + "2\317\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\0\0\0\0\0\0\0" + "\0\0\0\0\25\0\0\25\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0L\317\0L\317\0L\317\0L\317" + "\0\0\0\0" + "2\317\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0e\4\0e\4\0\0\0\0\0\0\0e\11\0e\11\0\0\0\0\0\0\0e\16\0e\16\0\0\0\0\0\0" + "\0G\11\0G\11\0\0\0\0\0\0\0G\14\0G\14\0\0\0\0\0\0\0G\17\0G\17\0\0\0\0\0\0" + "\0G\21\0G\21\0\0\0\0\0\0\0GK\0GK\0\0\0\0\0\0\0GT\0GT\0\0\0\0\0\0\0G^\0G^" + "\0\0\0\0\0\0\0Gg\0Gg\0\0\0\0\0\0\0e\317\0e\317\0e\317\0e\317\0e\317\0e\317" + "\0e\317\0e\317\0\0\0\0\0\0\0L\317\0L\317\0L\317\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\1\0\0\0\0\0\0\0\0e\4\0e\4\0e\4\0\0\0\0e\11\0e\11\0e\11\0\0\0" + "\0e\16\0e\16\0e\16\0\0\0\0e\22\0e\22\0G\11\0\0\0\0G\14\0G\14\0G\14\0\0\0" + "\0G\17\0G\17\0G\17\0\0\0\0G\21\0G\21\0G\21\0\0\0\0G\24\0G\24\0GK\0\0\0\0" + "GT\0GT\0GT\0\0\0\0G^\0G^\0G^\0\0\0\0Gg\0Gg\0Gg\0\0\0\0Gq\0Gq\0e\317\0e\317" + "\0e\317\0e\317\0e\317\0e\317\0e\317\0e\317\0e\317\0e\317\0\0\0\0L\317\0L" + "\317\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\0\0\0\0\0e\4\0e\4\0e\4\0\0\0" + "\0e\11\0e\11\0e\11\0\0\0\0e\16\0e\16\0e\16\0\0\0\0e\22\0e\22\0e\22\0\0\0" + "\0G\14\0G\14\0G\14\0\0\0\0G\17\0G\17\0G\17\0\0\0\0G\21\0G\21\0G\21\0\0\0" + "\0G\24\0G\24\0G\24\0\0\0\0GT\0GT\0GT\0\0\0\0G^\0G^\0G^\0\0\0\0Gg\0Gg\0Gg" + "\0\0\0\0Gq\0Gq\0Gq\0e\317\0e\317\0e\317\0e\317\0e\317\0e\317\0e\317\0e\317" + "\0e\317\0e\317\0e\317\0\0\0\0L\317\0L\317\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0e\4\0e\4\0e\4\0\0\0\0b\10\0b\10\0b\10\0\0\0\0b\15\0b\15\0b\15\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0<\16\0<\16\0<\16\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0" + "2J\0" + "2J\0" + "2J\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0e\317\0e\317\0e\317\0e" + "\317\0\0\0\0L\317\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\216\1\0c\0\0c\0\0\0\0\0" + "`\0\0c\0\0c\0\0\2\0\0c\1\0i\0\0i\0\0\0\0\0\0\0\0e\0\0e\0\0\0\0\0\0\0\0{\1" + "\0{\1\0f\0\0f\0\0z\1\0z\1\0z\1\0z\1\0)\4\0)\4\0\0\0\0\0\0\0Q\7\0Q\7\0\0\0" + "\0\0\0\0{&\0{&\0W\32\0W\32\0z&\0z&\0z&\0z&\0IC\0IC\0\0\0\0\0\0\0X^\0X^\0" + "\0\0\0\0\0\0\261\251\0\261\251\0\261\251\0\261\251\0\261\251\0\261\251\0" + "\261\251\0\261\251\0\0\0\0\0\0\0e\317\0e\317\0e\317\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\216\1\0c\0\0`\0\0\2\0\0c\0\0c\0\0c\0\0\12\0\0k\1\0i\0\0" + "\0\0\0\11\0\0i\0\0i\0\0\0\0\0\256\2\0\256\2\0{\1\0f\0\0z\1\0z\1\0z\1\0z\1" + "\0\221\1\0\221\1\0\221\17\0\0\0\0)\4\0c\11\0c\11\0\0\0\0\256+\0\256+\0{&" + "\0W\32\0z&\0z&\0z&\0z&\0\2415\0\2415\0\243\210\0\0\0\0IC\0{|\0{|\0\0\0\0" + "\261\251\0\261\251\0\261\251\0\261\251\0\261\251\0\261\251\0\261\251\0\261" + "\251\0\261\251\0\261\251\0\264\360\0\264\360\0\0\0\0e\317\0e\317\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\216\1\0\216\1\0`\0\0\2\0\0c\0\0c\0\0c\0\0\12\0\0" + "k\1\0k\1\0\0\0\0\11\0\0i\0\0i\0\0\0\0\0\256\2\0\256\2\0\256\2\0f\0\0z\1\0" + "z\1\0z\1\0z\1\0\221\1\0\221\1\0\221\1\0\0\0\0\221\17\0\221\17\0)\4\0\0\0" + "\0\256+\0\256+\0\256+\0W\32\0z&\0z&\0z&\0z&\0\2415\0\2415\0\2415\0\0\0\0" + "\243\210\0\243\210\0IC\0\0\0\0\261\251\0\261\251\0\261\251\0\261\251\0\261" + "\251\0\261\251\0\261\251\0\261\251\0\261\251\0\261\251\0\261\251\0\264\360" + "\0\264\360\0\264\360\0\0\0\0e\317\0e\317\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\216\1" + "\0\211\1\0c\0\0\2\0\0c\0\0c\0\0k\0\0\12\0\0k\1\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\264\360\0\264\360" + "\0\264\360\0\264\360\0\0\0\0e\317\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\211\1\0\216\1" + "\0c\0\0\2\0\0c\0\0k\0\0q\0\0\20\0\0\0\0\0\0\0\0\322\1\0\322\1\0\322\1\0\322" + "\1\0\346\1\0\346\1\0\0\0\0\0\0\0\322\2\0\322\2\0\322\2\0\322\2\0\363\2\0" + "\363\2\0\0\0\0\0\0\0\322!\0\322!\0\322!\0\322!\0\371(\0\371(\0\0\0\0\0\0" + "\0\322+\0\322+\0\322+\0\322+\0\3719\0\3719\0\0\0\0\0\0\0\325\215\0\325\215" + "\0\325\215\0\325\215\0\374\264\0\374\264\0\0\0\0\0\0\0\325\251\0\325\251" + "\0\325\251\0\325\251\0\325\251\0\325\251\0\325\251\0\325\251\0\0\0\0\0\0" + "\0\264\360\0\264\360\0\264\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\211\1\0\216" + "\1\0c\0\0\2\0\0f\0\0m\0\0m\0\0\0\0\0\325\3\0\325\3\0\322\1\0\322\1\0\346" + "\1\0\346\1\0\346\1\0\0\0\0\322\2\0\322\2\0\322\2\0\322\2\0\363\2\0\363\2" + "\0\363\2\0\0\0\0\322\3\0\322\3\0\322!\0\322!\0\371(\0\371(\0\371(\0\0\0\0" + "\322+\0\322+\0\322+\0\322+\0\3719\0\3719\0\3719\0\0\0\0\3227\0\3227\0\325" + "\215\0\325\215\0\374\264\0\374\264\0\374\264\0\0\0\0\325\251\0\325\251\0" + "\325\251\0\325\251\0\325\251\0\325\251\0\325\251\0\325\251\0\325\251\0\325" + "\251\0\330\360\0\330\360\0\0\0\0\264\360\0\264\360\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\216\1\0\216\1\0c\0\0\10\0\0m\0\0m\0\0\0\0\0\325\3\0\325\3\0\325" + "\3\0\322\1\0\346\1\0\346\1\0\346\1\0\0\0\0\322\2\0\322\2\0\322\2\0\322\2" + "\0\363\2\0\363\2\0\363\2\0\0\0\0\322\3\0\322\3\0\322\3\0\322!\0\371(\0\371" + "(\0\371(\0\0\0\0\322+\0\322+\0\322+\0\322+\0\3719\0\3719\0\3719\0\0\0\0\322" + "7\0\3227\0\3227\0\325\215\0\374\264\0\374\264\0\374\264\0\0\0\0\325\251\0" + "\325\251\0\325\251\0\325\251\0\325\251\0\325\251\0\325\251\0\325\251\0\325" + "\251\0\325\251\0\325\251\0\330\360\0\330\360\0\330\360\0\0\0\0\264\360\0" + "\264\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\216\1\0\216\1\0i\0\0\10\0\0m\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\275\1\0\275\1\0\275\1\0" + "\275\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\244!\0\244!\0\244!\0\244!\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\213n\0\213n\0\213n\0\213n\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\330\360\0\330\360\0\330\360\0\330" + "\360\0\0\0\0\264\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\216\1\0\224\1\0i\0\0\10\0" + "\0\0\0\0\0\0\0\325\3\0\325\3\0\325\3\0\351\3\0\365\1\0\365\1\0\14\0\0\313" + "\2\0#\2\0#\2\0\0\0\0\0\0\0\371\37\0\371\37\0\0\0\0\0\0\0\371\37\0\371\37" + "\0\371\37\0\371\37\0.\17\0.\17\0#\14\0\304-\0Y!\0Y!\0\0\0\0\0\0\0\371p\0" + "\371p\0\0\0\0\0\0\0\371p\0\371p\0\371p\0\371p\0O>\0O>\0" + "3(\0\247\227\0\211" + "s\0\211s\0\0\0\0\0\0\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0" + "\374\360\0\374\360\0\374\360\0\0\0\0\0\0\0\330\360\0\330\360\0\330\360\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\4\0\0\224\1\0i\0\0\0\0\0\0\0\0\325\3\0\325" + "\3\0\325\3\0\17\2\0\"\2\0!\0\0\35\0\0#\2\0\342\4\0\342\4\0\0\0\0\371\37\0" + "\371\37\0\371\37\0\0\0\0\371\37\0\371\37\0\371\37\0\371\37\0\3775\0\3775" + "\0\374%\0\304\34\0Y!\0\373C\0\373C\0\0\0\0\371p\0\371p\0\371p\0\0\0\0\371" + "p\0\371p\0\371p\0\371p\0\377\256\0\377\256\0\377\256\0\247q\0\211s\0\375" + "\342\0\375\342\0\0\0\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0" + "\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\0" + "\0\0\330\360\0\330\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\12\0\0\224\1\0\0\0" + "\0\0\0\0\325\3\0\325\3\0\325\3\0\344\5\0\"\2\0\"\2\0\200\0\0#\2\0\342\4\0" + "\342\4\0\0\0\0\371\37\0\371\37\0\371\37\0\0\0\0\371\37\0\371\37\0\371\37" + "\0\371\37\0\3775\0\3775\0\3775\0\304\34\0\3732\0\3732\0Y!\0\0\0\0\371p\0" + "\371p\0\371p\0\0\0\0\371p\0\371p\0\371p\0\371p\0\377\256\0\377\256\0\377" + "\256\0\247q\0\375\274\0\375\274\0\211s\0\0\0\0\374\360\0\374\360\0\374\360" + "\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0" + "\374\360\0\374\360\0\374\360\0\374\360\0\0\0\0\330\360\0\330\360\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\12\0\0\0\0\0i\0\0\0\0\0\325\3\0\325\3\0\344\5\0\344\5" + "\0\"\2\0\36\1\0" + "4\2\0#\2\0\342\4\0\0\0\0\371\37\0\371\37\0\371\37\0\0\0" + "\0\371\37\0\371\37\0\371\37\0\371\37\0\3775\0\3775\0\3775\0\307)\0\3732\0" + "\3732\0\3732\0\0\0\0\371p\0\371p\0\371p\0\0\0\0\371p\0\371p\0\371p\0\371" + "p\0\377\256\0\377\256\0\377\256\0\247q\0\375\274\0\375\274\0\375\274\0\0" + "\0\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360" + "\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0" + "\374\360\0\374\360\0\0\0\0\330\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\12\0\0" + "\10\0\0\0\0\0\325\3\0\344\5\0\344\5\0\344\5\0\340\4\0\367\11\0\364\3\0#\2" + "\0\0\0\0\371\37\0\371\37\0\371\37\0\0\0\0\371\37\0\371\37\0\371\37\0\371" + "\37\0\3775\0\3775\0\3775\0\307)\0\376G\0\3732\0\3732\0\0\0\0\371p\0\371p" + "\0\371p\0\0\0\0\371p\0\371p\0\371p\0\371p\0\377\256\0\377\256\0\377\256\0" + "\247q\0\375\274\0\375\274\0\375\274\0\0\0\0\374\360\0\374\360\0\374\360\0" + "\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374" + "\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\12\0\0\10\0\0\0\0\0\0\0\0\17\2\0\17" + "\2\0\17\2\0\323\2\0\352\7\0\347\2\0\26\1\0\0\0\0\371\37\0\371\37\0\371\37" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0/\26\0/\26\0/\26\0\0\0\0" + "7\36\0" + "6\25\0" + "" + "6\25\0\0\0\0\371p\0\371p\0\371p\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0O>\0O>\0" + "O>\0\0\0\0VK\0VK\0VK\0\0\0\0\374\360\0\374\360\0\374\360\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\374\360\0\374\360\0\374\360\0\374\360\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\374\360\0\374\360\0\374\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\5\0\0\12\0" + "\0\10\0\0\0\0\0\17\2\0\17\2\0\344\5\0\15\1\0\352\7\0\352\7\0\347\2\0\0\0" + "\0\371\37\0\371\37\0\371\37\0\0\0\0\0\0\0\0\0\0\362\4\0\0\0\0/\26\0/\26\0" + "\3775\0$\21\0" + "7\36\0" + "7\36\0\3672\0\0\0\0\371p\0\371p\0\371p\0\0\0\0\0\0" + "\0\0\0\0\370A\0\0\0\0O>\0O>\0\377\256\0" + "3(\0VK\0VK\0\372\264\0\0\0\0\374" + "\360\0\374\360\0\374\360\0\374\360\0\0\0\0\0\0\0\341\271\0\0\0\0\374\360" + "\0\374\360\0\374\360\0\374\360\0\0\0\0\0\0\0\343\350\0\0\0\0\374\360\0\374" + "\360\0\374\360\0\374\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\5\0\0\5\0\0\10\0\0\0\0" + "\0\17\2\0\17\2\0\17\2\0\15\1\0\352\7\0\352\7\0\347\2\0\0\0\0\371\37\0\371" + "\37\0\371\37\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0/\26\0/\26\0/\26\0$\21\0" + "7\36" + "\0" + "7\36\0" + "6\25\0\0\0\0\371p\0\371p\0\371p\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0O>\0O>\0O>\0" + "3(\0VK\0VK\0VK\0\0\0\0\374\360\0\374\360\0\374\360\0\374" + "\360\0\0\0\0\0\0\0\0\0\0\0\0\0\374\360\0\374\360\0\374\360\0\374\360\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\374\360\0\374\360\0\374\360\0\374\360\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\5\0\0\5\0\0\5\0\0\0\0\0\344\5\0\344\5\0\344\5\0\316\4\0\367" + "\11\0\367\11\0\364\3\0\0\0\0\371\37\0\371\37\0\371\37\0\0\0\0\371\37\0\371" + "\37\0\371\37\0\371\37\0\3775\0\3775\0\3775\0\307)\0\376G\0\376G\0\3732\0" + "\0\0\0\371p\0\371p\0\371p\0\0\0\0\371p\0\371p\0\371p\0\371p\0\377\256\0\377" + "\256\0\377\256\0\247q\0\375\274\0\375\274\0\375\274\0\0\0\0\374\360\0\374" + "\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360" + "\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0" + "\374\360\0\374\360\0\374\360\0\374\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\5" + "\0\0\5\0\0\5\0\0\17\2\0\344\5\0\344\5\0\316\4\0\345\11\0\367\11\0\364\3\0" + "\0\0\0\371\37\0\371\37\0\371\37\0\0\0\0\371\37\0\371\37\0\371\37\0\371\37" + "\0\3775\0\3775\0\3775\0\307)\0\376G\0\376G\0\3732\0\0\0\0\371p\0\371p\0\371" + "p\0\0\0\0\371p\0\371p\0\371p\0\371p\0\377\256\0\377\256\0\377\256\0\247q" + "\0\375\274\0\375\274\0\375\274\0\0\0\0\374\360\0\374\360\0\374\360\0\374" + "\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360" + "\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0" + "\374\360\0\374\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\5\0\0\5\0\0\0\0\0\17\2" + "\0\344\5\0\344\5\0\15\1\0$\6\0$\6\0#\2\0\0\0\0\371\37\0\371\37\0\371\37\0" + "\0\0\0\371\37\0\371\37\0\371\37\0\371\37\0\3775\0/\26\0/\26\0\307)\0\376" + "G\0[/\0Y!\0\0\0\0\371p\0\371p\0\371p\0\0\0\0\371p\0\371p\0\371p\0\371p\0" + "\377\256\0O>\0O>\0\247q\0\375\274\0\211s\0\211s\0\0\0\0\374\360\0\374\360" + "\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0" + "\0\0\0\0\0\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0" + "\374\360\0\374\360\0\374\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\5\0\0" + "\5\0\0\17\2\0\17\2\0\344\5\0\316\4\0$\6\0$\6\0#\2\0\0\0\0\371\37\0\371\37" + "\0\371\37\0\0\0\0\371\37\0\371\37\0\371\37\0\371\37\0\3775\0/\26\0/\26\0" + "\307)\0\376G\0[/\0Y!\0\0\0\0\371p\0\371p\0\371p\0\0\0\0\371p\0\371p\0\371" + "p\0\371p\0\377\256\0O>\0O>\0\247q\0\375\274\0\211s\0\211s\0\0\0\0\374\360" + "\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0" + "\374\360\0\0\0\0\0\0\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0" + "\374\360\0\374\360\0\374\360\0\374\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\5\0\0\24\2\0\17\2\0\17\2\0\316\4\0\345\11\0$\6\0#\2\0\0\0\0\371" + "\37\0\371\37\0\371\37\0\0\0\0\371\37\0\371\37\0\371\37\0\371\37\0\3775\0" + "\3775\0\3775\0\307)\0\376G\0\376G\0\3732\0\0\0\0\371p\0\371p\0\371p\0\0\0" + "\0\371p\0\371p\0\371p\0\371p\0\377\256\0\377\256\0\377\256\0\247q\0\375\274" + "\0\375\274\0\375\274\0\0\0\0\374\360\0\374\360\0\374\360\0\374\360\0\374" + "\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360" + "\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0" + "\374\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\5\0\0\24\2\0\24" + "\2\0\17\2\0\316\4\0\345\11\0\342\3\0#\2\0\0\0\0\371\37\0\371\37\0\371\37" + "\0\0\0\0\371\37\0\371\37\0\371\37\0\371\37\0\3775\0\3775\0\3775\0\307)\0" + "\376G\0\3732\0\3732\0\0\0\0\371p\0\371p\0\371p\0\0\0\0\371p\0\371p\0\371" + "p\0\371p\0\377\256\0\377\256\0\377\256\0\247q\0\375\274\0\375\274\0\375\274" + "\0\0\0\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374" + "\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360" + "\0\374\360\0\374\360\0\374\360\0\374\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\17\2\0\24\2\0\5\0\0\0\0\0\27\5\0\342\3\0\313" + "\1\0\0\0\0\371\37\0\371\37\0\0\0\0\0\0\0\0\0\0\371\37\0\0\0\0\0\0\0/\26\0" + "\3775\0\371\37\0\302\30\0\3716\0Y!\0#\14\0\0\0\0\371p\0\371p\0\0\0\0\0\0" + "\0\0\0\0\371p\0\0\0\0\0\0\0O>\0\377\256\0\371p\0\243I\0\371\224\0\211s\0" + "" + "3(\0\0\0\0\374\360\0\374\360\0\0\0\0\0\0\0\0\0\0\374\360\0\374\360\0\374" + "\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\0\0\0\0\0\0\0\0" + "\0\374\360\0\374\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\17\2\0\17\2\0\0\0\0\0\0\0\26\1\0\26\1\0\0\0\0\0\0\0\371" + "\37\0\371\37\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0/\26\0/\26\0\0\0\0\0\0" + "\0" + "6\25\0" + "6\25\0\0\0\0\0\0\0\371p\0\371p\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0O>\0O>\0\0\0\0\0\0\0VK\0VK\0\0\0\0\0\0\0\374\360\0\374\360\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\374" + "\360\0\374\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\17\2\0\17\2\0\0\0\0\0\0\0\26\1\0\26\1\0\0\0\0\0\0" + "\0\371\37\0\371\37\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0/\26\0/\26\0\0\0" + "\0\0\0\0" + "6\25\0" + "6\25\0\0\0\0\0\0\0\371p\0\371p\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0O>\0O>\0\0\0\0\0\0\0VK\0VK\0\0\0\0\0\0\0\374\360\0\374\360" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\374\360\0" + "\374\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\17\2\0\17\2\0\16\0\0\0\0\0\26\1\0\26\1\0\26" + "\1\0\0\0\0\371\37\0\371\37\0\371\37\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0/\26\0" + "/\26\0.\17\0\0\0\0" + "6\25\0" + "6\25\0" + "6\25\0\0\0\0\371p\0\371p\0\371p\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0O>\0O>\0O>\0\0\0\0VK\0VK\0VK\0\0\0\0\374\360\0" + "\374\360\0\374\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\374\360\0\374\360" + "\0\374\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\16\0\0\16\0\0\14\0\0\14" + "\0\0#\2\0#\2\0\0\0\0\0\0\0\371\37\0\371\37\0\0\0\0\0\0\0\371\37\0\371\37" + "\0\371\37\0\371\37\0.\17\0.\17\0#\14\0#\14\0Y!\0Y!\0\0\0\0\0\0\0\371p\0\371" + "p\0\0\0\0\0\0\0\371p\0\371p\0\371p\0\371p\0O>\0O>\0" + "3(\0" + "3(\0\211s\0\211" + "s\0\0\0\0\0\0\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360\0\374\360" + "\0\374\360\0\374\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", +}; + +/** + * \brief Returns the BlitBlendAll test image as SDL_Surface. + */ +SDL_Surface *SDLTest_ImageBlitBlendAll() +{ + SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormatFrom( + (void *)SDLTest_imageBlitBlendAll.pixel_data, + SDLTest_imageBlitBlendAll.width, + SDLTest_imageBlitBlendAll.height, + SDLTest_imageBlitBlendAll.bytes_per_pixel * 8, + SDLTest_imageBlitBlendAll.width * SDLTest_imageBlitBlendAll.bytes_per_pixel, + SDL_PIXELFORMAT_RGB24); + return surface; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/test/SDL_test_imageFace.c b/SDL2-2.30.5/src/test/SDL_test_imageFace.c new file mode 100644 index 0000000..255acad --- /dev/null +++ b/SDL2-2.30.5/src/test/SDL_test_imageFace.c @@ -0,0 +1,238 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_test.h" + +/* GIMP RGBA C-Source image dump (face.c) */ + +static const SDLTest_SurfaceImage_t SDLTest_imageFace = { + 32, + 32, + 4, + "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" + "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" + "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0" + "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" + "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" + "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0" + "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" + "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" + "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0" + "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" + "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" + "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0" + "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" + "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" + "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0" + "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" + "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" + "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0" + "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" + "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" + "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0" + "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" + "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" + "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0" + "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" + "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" + "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0" + "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" + "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" + "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0" + "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" + "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" + "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0" + "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\0" + "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" + "\0\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0" + "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" + "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" + "\377\0\377\377\377\0\0\0\0\377\0\0\0\377\377\377\0\377\377\377\0\377\377" + "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\0\0\0\377\0\0\0\377\377\377\377\0\377\377\377\0\377\377\377\0\377" + "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" + "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0" + "\0\0\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0" + "\377\377\377\0\377\377\377\0\377\0\0\0\377\377\377\377\0\377\377\377\0\377" + "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" + "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\0\0\0\377\377" + "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0" + "\377\377\377\0\377\377\377\0\377\377\377\0\377\0\0\0\377\377\377\377\0\377" + "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" + "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\377\377\0\377\377\377\0\377\377\377\0\0\0\0\377\377\377\0\377\377" + "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0" + "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\0\0\0\377\377" + "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" + "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\377\377\0\377\377\377\0\0\0\0\377\377\377\0\377\377\377\0\377\377" + "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0" + "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" + "\0\0\0\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" + "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\377\377\0\377\377\377\0\0\0\0\377\377\377\0\377\377\377\0\377\377" + "\377\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\0\377\377\377" + "\0\377\377\377\0\377\377\377\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" + "\377\377\0\377\377\377\0\377\377\377\0\377\0\0\0\377\377\377\377\0\377\377" + "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\0\0\0\377\377" + "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\0\0\0\377\0\0\0\377" + "\377\377\377\0\0\0\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\0\0\0\377\0\0\0\377\377\377\377\0\0\0\0\377\377\377\0\377\377\377" + "\0\377\377\377\0\377\377\377\0\377\0\0\0\377\377\377\377\0\377\377\377\0" + "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" + "\377\377\0\377\377\377\0\377\377\377\0\0\0\0\377\377\377\0\377\377\377\0" + "\377\377\377\0\377\377\377\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" + "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\0\0\0\377\0\0\0" + "\377\0\0\0\377\0\0\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\0\0\0\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0" + "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" + "\377\377\0\0\0\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0" + "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" + "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" + "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\0\0\0\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0" + "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" + "\377\377\0\0\0\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0" + "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" + "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" + "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\0\0\0\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0" + "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" + "\377\377\0\0\0\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0" + "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" + "\0\0\0\377\0\0\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0" + "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" + "\0\0\0\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" + "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\0\0\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" + "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\0\0\0" + "\377\0\0\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" + "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\0\0\0" + "\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0" + "\0\0\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0" + "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" + "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\0" + "\0\0\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" + "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\377\377\0\0\0\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" + "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0" + "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\0\0\0\377\377" + "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" + "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\377\377\0\0\0\0\377\377\377\0\377\377\377\0\377\0\0\0\377\0\0\0\377" + "\0\0\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\0\0\0\377\0\0\0\377\0\0" + "\0\377\377\377\0\377\377\377\0\377\0\0\0\377\377\377\377\0\377\377\377\0" + "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" + "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" + "\377\0\0\0\0\377\377\377\0\377\377\377\0\377\0\0\0\377\0\0\0\377\0\0\0\377" + "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" + "\0\0\377\0\0\0\377\377\377\0\377\377\377\0\377\0\0\0\377\377\377\377\0\377" + "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" + "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\377\377\0\377\377\377\0\377\377\377\0\0\0\0\377\377\377\0\377\377" + "\377\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" + "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\0\377\377\377\0\377\0\0\0" + "\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0" + "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" + "\377\377\0\377\377\377\0\0\0\0\377\377\377\0\377\377\377\0\377\377\377\0" + "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377" + "\0\377\377\377\0\377\377\377\0\377\0\0\0\377\377\377\377\0\377\377\377\0" + "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" + "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" + "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\377\377\0\0\0\0\377\0\0\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0" + "\377\0\0\0\377\0\0\0\377\377\377\377\0\377\377\377\0\377\377\377\0\377\377" + "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0" + "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" + "\377\377\0\377\377\377\0\377\377\377\0\0\0\0\377\0\0\0\377\0\0\0\377\0\0" + "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\377\377\377\0\377\377\377" + "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0" + "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" + "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" + "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0" + "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" + "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" + "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0" + "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" + "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" + "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0" + "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" + "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" + "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0" + "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" + "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" + "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0" + "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" + "\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377" + "\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377" + "\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0" + "\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377\377\377\0\377" + "\377\377\0\377\377\377\0", +}; + +/** + * \brief Returns the Face test image as SDL_Surface. + */ +SDL_Surface *SDLTest_ImageFace() +{ + SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormatFrom( + (void *)SDLTest_imageFace.pixel_data, + SDLTest_imageFace.width, + SDLTest_imageFace.height, + SDLTest_imageFace.bytes_per_pixel * 8, + SDLTest_imageFace.width * SDLTest_imageFace.bytes_per_pixel, + SDL_PIXELFORMAT_RGBA32); + return surface; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/test/SDL_test_imagePrimitives.c b/SDL2-2.30.5/src/test/SDL_test_imagePrimitives.c new file mode 100644 index 0000000..6ef05c5 --- /dev/null +++ b/SDL2-2.30.5/src/test/SDL_test_imagePrimitives.c @@ -0,0 +1,519 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_test.h" + +/* GIMP RGB C-Source image dump (primitives.c) */ + +static const SDLTest_SurfaceImage_t SDLTest_imagePrimitives = { + 80, + 60, + 3, + "\5ii\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\15I\310\0\0\0\15I\310\0\0\0\15I\310\0\0\0\15" + "I\310\0\0\0\15I\310\0\0\0\15I\310\0\0\0\15I\310\0\0\0\15I\310\0\0\0\15I\310" + "\0\0\0\15I\310\0\0\0\15I\310\0\0\0\15I\310\0\0\0\15I\310\0\0\0\15I\310\0" + "\0\0\15I\310\0\0\0\15I\310\0\0\0\15I\310\0\0\0\15I\310\0\0\0\15I\310\0\0" + "\0\5ii\0\0\0\5ii\0\0\0\3\1\1\0\0\0\5\2\1\0\0\0\7\3\2\0\0\0\11\4\3\0\0\0\13" + "\5\3\0\0\0\15\6\4\0\0\0\17\7\5\0\0\0\21\10\5\0\0\0\23\11\6\0\0\0\25\12\7" + "\0\0\0\27\13\7\0\0\0\31\14\10\0\0\0\33\15\11\0\0\0\35\16\11\0\0\0\37\17\12" + "\0\0\0!\20\13\0\0\0#\21\13\0\0\0%\22\14\0\0\0'\23\15\15I\310)\24\15\15I\310" + "+\25\16\15I\310-\26\17\15I\310/\27\17\15I\3101\30\20\15I\3103\31\21\15I\310" + "5\32\21\15I\3107\33\22\15I\3109\34\23\15I\310;\35\23\15I\310=\36\24\15I\310" + "?\37\25\15I\310A\40\25\15I\310C!\26\15I\310E\"\27\15I\310G#\27\15I\310I$" + "\30\15I\310K%\31\15I\310M&\31\5iiO'\32\0\0\0\0\0\0\5ii\0\0\0\10\4\2\0\0\0" + "\14\6\4\0\0\0\20\10\5\0\0\0\24\12\6\0\0\0\30\14\10\0\0\0\34\16\11\0\0\0\40" + "\20\12\0\0\0$\22\14\0\0\0(\24\15\0\0\0,\26\16\0\0\0" + "0\30\20\0\0\0" + "4\32" + "\21\0\0\0" + "8\34\22\0\0\0<\36\24\0\0\0@\40\25\0\0\0D\"\26\0\0\0H$\30\0\0\0" + "L&\31\0\0\0P(\32\15I\310T*\34\15I\310X,\35\15I\310\\.\36\15I\310`0\40\15" + "I\310d2!\15I\310h4\"\15I\310l6$\15I\310p8%\15I\310t:&\15I\310x<(\15I\310" + "|>)\15I\310\200@*\15I\310\204B,\15I\310\210D-\15I\310\214F.\15I\310\220H" + "0\15I\310\224J1\15I\310\230L2\5ii\234N4\15I\310\0\0\0\0\0\0\0\0\0\5ii\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\15I" + "\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I" + "\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I" + "\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I" + "\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\5ii" + "\15I\310\15I\310\15I\310\0\0\0\0\0\0\0\0\0\0\0\0\5ii\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\15I\310\15I\310\15I\310\15" + "I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15" + "I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15" + "I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15" + "I\310\15I\310\15I\310\15I\310\15I\310\5ii\15I\310\15I\310\15I\310\15I\310" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\5ii\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15" + "I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15" + "I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15" + "I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15" + "I\310\5ii\15I\310\15I\310\15I\310\15I\310\15I\310\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\5ii\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\15" + "I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15" + "I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15" + "I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15" + "I\310\15I\310\15I\310\15I\310\15I\310\15I\310\5ii\15I\310\15I\310\15I\310" + "\15I\310\15I\310\15I\310\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\5ii\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\15I\310\15I\310\15I\310\15" + "I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15" + "I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15" + "I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15" + "I\310\15I\310\5ii\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\5ii\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15" + "I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15" + "I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15" + "I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\5ii\15I\310\15I\310" + "\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\5ii\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\15" + "I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15" + "I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15" + "I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15" + "I\310\15I\310\15I\310\5ii\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310" + "\15I\310\15I\310\15I\310\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\5ii\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d" + "\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\5ii\15I\310\15" + "I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\310\0d\5ii\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\5ii\310\0d\15I\310\15I\310\15I\310\15I\310\15I\310\15I" + "\310\15I\310\15I\310\15I\310\15I\310\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\310\0d\310\0d\5ii\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\5ii\310\0d\310\0d\15" + "I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15" + "I\310\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\310\0d" + "\310\0d\310\0d\5ii\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\5ii\310\0d\310\0d\310\0d\15I\310\15I\310\15I\310\15I\310" + "\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\310\0d\310\0d\310\0d\310\0d\5ii\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\5ii\310\0d\310\0d\310" + "\0d\310\0d\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310" + "\15I\310\15I\310\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\310\0d\310\0d\310\0d\310\0d\310\0d\5ii\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\5ii\310\0d\310\0d\310\0d\310\0d\310\0d\15I\310\15I\310\15I\310" + "\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\310\0d\310\0d\310\0d\310\0d" + "\310\0d\310\0d\5ii\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\5ii\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310" + "\15I\310\15I\310\15I\310\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\5ii\310\0d" + "\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\5ii\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\15I\310\15" + "I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\5ii\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\5ii\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\15I\310\15I\310\15I\310\15I\310\15I\310\15" + "I\310\15I\310\15I\310\15I\310\15I\310\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\5ii\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\5ii\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310" + "\15I\310\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\5ii\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\5ii\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\15I\310\15I\310\15I\310\15" + "I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\5ii\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\5ii\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310" + "\15I\310\15I\310\15I\310\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\5ii\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\5ii\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\15I\310\15I\310" + "\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\5" + "ii\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d" + "\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\5ii\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\15I\310\15I\310\15I\310\15I\310\15I\310\15" + "I\310\15I\310\15I\310\15I\310\15I\310\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\5ii\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\5ii\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310" + "\15I\310\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\5ii\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\5ii\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\15I\310\15I\310\15I\310\15" + "I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\5ii\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\5ii\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15" + "I\310\15I\310\15I\310\15I\310\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d" + "\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\5ii\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\5ii\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\15I\310" + "\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\5ii\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\5ii\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\15I\310\15I\310\15I\310\15I\310\15I" + "\310\15I\310\15I\310\15I\310\15I\310\15I\310\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\5ii\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\5ii\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310" + "\15I\310\15I\310\0\377\0\0\377\0\0\377\0\0\377\0\0\377\0\0\377\0\0\377\0" + "\0\377\0\0\377\0\0\377\0\0\377\0\0\377\0\0\377\0\0\377\0\0\377\0\0\377\0" + "\0\377\0\0\377\0\0\377\0\0\377\0\0\377\0\0\377\0\0\377\0\0\377\0\0\377\0" + "\0\377\0\0\377\0\0\377\0\0\377\0\5ii\0\377\0\0\377\0\0\377\0\0\377\0\0\377" + "\0\0\377\0\0\377\0\0\377\0\0\377\0\0\377\0" + "77\5\0\377\0\0\377\0\0\377\0" + "\0\377\0\0\377\0\0\377\0\0\377\0\0\377\0\0\377\0\5ii\0\377\0\0\377\0\0\377" + "\0\0\377\0\0\377\0\0\377\0\0\377\0\0\377\0\0\377\0\0\377\0\0\377\0\0\377" + "\0\0\377\0\0\377\0\0\377\0\0\377\0\0\377\0\0\377\0\0\377\0\0\377\0\0\377" + "\0\0\377\0\0\377\0\0\377\0\0\377\0\0\377\0\0\377\0\0\377\0\0\377\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\5ii\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d77\5\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\5ii\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\15I\310\15I\310\15I\310\15I\310\15I\310\15" + "I\310\15I\310\15I\310\15I\310\15I\310\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\5" + "ii\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d" + "\310\0d\310\0d77\5\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\5ii\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310" + "\15I\310\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\5ii\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d77\5\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\5ii\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\15I\310\15I\310\15I\310\15" + "I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\5ii\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d77\5\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\5ii\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15" + "I\310\15I\310\15I\310\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\5ii\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d77\5\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\5ii\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\15I\310\15I\310\15I" + "\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\5ii\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d77\5\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\5ii\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310" + "\15I\310\15I\310\15I\310\15I\310\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\5ii\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d77\5\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\5ii\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\15I\310" + "\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\5ii\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d77\5\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\5ii\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\15I\310\15I\310\15I\310\15I\310\15" + "I\310\15I\310\15I\310\15I\310\15I\310\15I\310\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\5ii\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d77\5\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\5ii\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310" + "\15I\310\15I\310\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\5ii\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d77\5\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\5ii\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\15I\310\15I\310\15I" + "\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\5ii\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d77\5\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\5ii\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310" + "\15I\310\15I\310\15I\310\15I\310\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\5i" + "i\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d77\5\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\5ii\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\15I" + "\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I" + "\310\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\5ii\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d77\5\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\5ii\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\15I\310\15I\310\15I\310\15I\310\15" + "I\310\15I\310\15I\310\15I\310\15I\310\15I\310\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\310\0d\310\0d\310\0d\310\0d\310\0d\5ii\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d77\5\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\5ii\310\0d\310\0d\310\0d\310\0d\310" + "\0d\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310" + "\15I\310\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\310" + "\0d\310\0d\310\0d\310\0d\5ii\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d77\5\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\5ii\310\0d\310\0d\310\0d\310\0d\15I\310\15I\310\15I\310\15I\310" + "\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\310\0d\310\0d\310\0d\5ii\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d77\5\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\5ii\310\0d\310" + "\0d\310\0d\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310" + "\15I\310\15I\310\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\310\0d\310\0d\5ii\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d77\5\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\5ii\310\0d\310\0d\15I\310\15I\310\15I\310" + "\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\310\0d\5ii\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d77\5\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\5ii\310\0d\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15" + "I\310\15I\310\15I\310\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\5ii\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d7" + "7\5\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0" + "d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310" + "\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\310\0d\5ii\15I\310\15I\310" + "\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\5ii\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0" + "77\5\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I" + "\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I" + "\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I" + "\310\15I\310\15I\310\15I\310\15I\310\5ii\15I\310\15I\310\15I\310\15I\310" + "\15I\310\15I\310\15I\310\15I\310\15I\310\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\5ii\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "77\5\15I" + "\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I" + "\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I" + "\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I" + "\310\15I\310\15I\310\5ii\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310" + "\15I\310\15I\310\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\5ii\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "77\5\15I\310\15I\310\15I\310\15I" + "\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I" + "\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I" + "\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I" + "\310\5ii\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\5ii\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0" + "77\5\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I" + "\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I" + "\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I" + "\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\5ii\15I\310" + "\15I\310\15I\310\15I\310\15I\310\15I\310\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\5" + "ii\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "77\5\15I" + "\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I" + "\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I" + "\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I" + "\310\15I\310\15I\310\15I\310\15I\310\15I\310\5ii\15I\310\15I\310\15I\310" + "\15I\310\15I\310\0\0\0\0\0\0\0\0\0\0\0\0\5ii\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "77\5\15I\310\15I\310\15I\310\15I" + "\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I" + "\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I" + "\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I" + "\310\15I\310\15I\310\15I\310\5ii\15I\310\15I\310\15I\310\15I\310\0\0\0\0" + "\0\0\0\0\0\5ii\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0" + "77\5\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I" + "\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I" + "\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I" + "\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I" + "\310\15I\310\5ii\15I\310\15I\310\15I\310\0\0\0\0\0\0\5ii\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "77\5\15I" + "\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I" + "\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I" + "\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I" + "\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\5ii" + "\15I\310\15I\310\0\0\0\5ii\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "77\5\15I\310\15I\310\15I\310\15I" + "\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I" + "\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I" + "\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I" + "\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\5ii\15I\310\5ii\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0" + "77\5\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I" + "\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I" + "\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I" + "\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I\310\15I" + "\310\15I\310\15I\310\15I\310\15I\310\5ii", +}; + +/** + * \brief Returns the Primitives test image as SDL_Surface. + */ +SDL_Surface *SDLTest_ImagePrimitives() +{ + SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormatFrom( + (void *)SDLTest_imagePrimitives.pixel_data, + SDLTest_imagePrimitives.width, + SDLTest_imagePrimitives.height, + SDLTest_imagePrimitives.bytes_per_pixel * 8, + SDLTest_imagePrimitives.width * SDLTest_imagePrimitives.bytes_per_pixel, + SDL_PIXELFORMAT_RGB24); + return surface; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/test/SDL_test_imagePrimitivesBlend.c b/SDL2-2.30.5/src/test/SDL_test_imagePrimitivesBlend.c new file mode 100644 index 0000000..8ee9f41 --- /dev/null +++ b/SDL2-2.30.5/src/test/SDL_test_imagePrimitivesBlend.c @@ -0,0 +1,692 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_test.h" + +/* GIMP RGB C-Source image dump (alpha.c) */ + +static const SDLTest_SurfaceImage_t SDLTest_imagePrimitivesBlend = { + 80, + 60, + 3, + "\260e\15\222\356/\37\313\15\36\330\17K\3745D\3471\0\20\0D\3502D\3502<\321" + ",\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0-\0\377\377" + "\377\377\377\377\311\324\311\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\0H\0\377\377\377\377\377\377\256\307\256\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\0c\0\377\377\377\377\377\377" + "\223\300\223\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\0~\0\377\377\377\377\377\377x\277x\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\0\231\0\377\377\377\377\377\377]\303]\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\0\264\0\377\377\377\377\377" + "\377B\316B\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\0" + "\317\0\377\377\377\377\377\377'\335'\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\0\352\0\377\377\377#\262\6\260d\15\260e\15\224\357" + "/&\262\6\34\300\5.\314\22\40\315\12[\3747M\332/\27\331\12\27\331\12K\374" + "5K\3745K\3745D\3471D\3471D\3471D\3471D\3471D\3502D\3502D\3502D\3502D\350" + "2D\3502D\3502D\3502D\3502D\3502\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377,\372\27\273\3465\327" + "Q.\260d\15\213\213\40\241\3601\200\366*=\265\13?\301\25s\375\265\14\177\252+\201\210\16\245\204" + "*\377\314U\312\\,\224'\11\260i\17\244\210\40\232\2211\331\353J\215\2351\377" + "\377\276\200\2521\200\2542\375\377\310u\2661t\2702t\2702\367\377\324\325" + "\355\305h\3021h\3042h\3042\377\377\377\377\377\377\364\377\336\335\364\323" + "\335\364\323\335\364\323\\\3202\\\3202\\\3202\\\3202\\\3202\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\346\371\342\346\371\342\346" + "\371\342\346\371\342\346\371\342\346\371\342\346\371\342\377\377\377\377" + "\377\377P\3342P\3342P\3342P\3342P\3342P\3342P\3342P\3342\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\27\331\12Y\316-h\3021\243\370Cg\230\15\230\224\"\245" + "\204*\377\314U\310J\21\327Q.\260b\21\245\2041\370\343N\230\2242\331\353J" + "\214\2402\377\377\276\200\2521\200\2542\375\377\310\317\344\266u\2661t\270" + "2\377\377\377\367\377\324\325\355\305h\3021h\3042h\3042h\3042\377\377\377" + "\377\377\377\364\377\336\335\364\323\335\364\323\335\364\323\335\364\323" + "\\\3202\\\3202\\\3202\\\3202\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\346\371\342\346\371" + "\342\346\371\342\346\371\342\346\371\342\346\371\342\377\377\377\377\377" + "\377\377\377\377\377\377\377P\3342P\3342P\3342P\3342P\3342P\3342P\3342P\334" + "2\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377K\3745!\315\13d\304,p\270)\177\252+\23\13\6\232\2211\245\204" + "1\347\270O\377\277Y\324<\22\265V\24\377\330Q\244\210\40#(\13\230\224\"\331" + "\353Ju\211.\377\377\276\200\2521\210\273:\200\2542\375\377\310\20" + "3\6u\266" + "1t\2702\271\307\271\367\377\324\325\355\305\341\377\321h\3021h\3042\16L\7" + "h\3042\377\377\377\242\300\242\377\377\377\335\364\323\355\377\343\335\364" + "\323\335\364\323\14f\7\\\3202\\\3202>\250*\\\3202\377\377\377\377\377\377" + "\377\377\377\377\377\377$\231$\377\377\377\377\377\377s\303s\377\377\377" + "\346\371\342\376\377\372\346\371\342\346\371\342\40\257\37\346\371\342\346" + "\371\342\\\316\\\377\377\377\377\377\377\377\377\377\377\377\377P\3342\13" + "\262\7P\3342P\3342*\327%P\3342P\3342o\377Q\377\377\377\377\377\377$\352$" + "\377\377\377\377\377\377K\3745]\3749s\375<\212\373@\243\370C\274\363G\331" + "\353J\370\343N\377\330Q\377\314U\377\277Y\377\260\\\224(\11\260|\36\245\204" + "1\377\377\250\232\2211\230\224\"\215\2351\214\2402\377\377\276\312\332\250" + "\200\2521\200\2542\377\377\377\317\344\266u\2661t\2702t\2702\377\377\377" + "\377\377\377\325\355\305\325\355\305\325\355\305h\3042h\3042h\3042\377\377" + "\377\377\377\377\377\377\377\377\377\377\335\364\323\335\364\323\335\364" + "\323\335\364\323\335\364\323\\\3202\\\3202\\\3202\\\3202\\\3202\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\346\371\342\346\371\342" + "\346\371\342\346\371\342\346\371\342\346\371\342\346\371\342\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377P\3342P\3342" + "P\3342P\3342\377\377\377K\3745O\3321\\\3161h\3021t\2702~\254'\214\240%\377" + "\377\262\370\343N\377\330Q\262x1\277l1\312`1\327R.\260X\23\377\330Q\244\210" + "2\377\377\250\230\2242\377\377\262\215\2351\214\2402\377\377\377\312\332" + "\250\200\2521\200\2542\377\377\377\375\377\310\317\344\266u\2661t\2702t\270" + "2\377\377\377\377\377\377\325\355\305\325\355\305\325\355\305h\3042h\304" + "2h\3042h\3042\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\335\364\323\335\364\323\335\364\323\335\364\323\377\377\377\\\3202\\\320" + "2\\\3202\\\3202\\\3202\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\346\371\342\346\371\342\346\371\342\346" + "\371\342\346\371\342\346\371\342\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377D\3471O\3321\21\7\11c\304+\367\377\324o\2520\200\252" + "1\214\2402\235\226'\377\377\250\377\330Q!\20\11\277l1\310d2\266?\33\224(" + "\11\260|\36\257\217;\377\377\250\232\2211\34$\11\377\377\262\215\2351q\206" + "0\377\377\377\312\332\250\217\303@\200\2542\200\25420Z0\317\344\266\317\344" + "\266X\2260t\2702t\2702\377\377\377\377\377\377\325\355\305(l%\325\355\305" + "\325\355\305K\2410h\3042h\3042\377\377\377\377\377\377\377\377\3770\2200" + "\377\377\377\377\377\377t\274p\335\364\323\335\364\323\373\377\361\377\377" + "\377\377\377\377\21\213\11\\\3202\\\3202<\274/\\\3202\377\377\377\377\377" + "\377\377\377\377\377\377\3770\3060\377\377\377\377\377\377V\330V\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\3770\3410\346\371\342\346" + "\371\342>\352>\346\371\342\377\377\377D\3471P\3342\364\377\352s\375\3369\\\3202\377\377\377\377\377\377\377\377\377\377\377\377D\3502\371\377" + "\364O\3321\\\3202\364\377\336h\3042\367\377\324u\2661\200\2542\377\377\276" + "\215\2351\230\2242\307\300\213\244\2102\377\377\234\262x1\274p2\377\337\207" + "\312`1\324E\30\327T1\260|2\377\377\234\245\2041\244\2102\377\377\250\232" + "\2211\230\2242\377\377\377\310\316\231\215\2351\214\2402\377\377\377\377" + "\377\377\312\332\250\312\332\250\200\2542\200\2542\377\377\377\377\377\377" + "\317\344\266\317\344\266\317\344\266t\2702t\2702t\2702\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\325\355\305\325\355\305\325\355" + "\305\377\377\377h\3042h\3042h\3042h\3042\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\335\364\323\335\364\323\335\364\323\335\364\323\377\377\377\377\377" + "\377\377\377\377\377\377\377\\\3202\\\3202\\\3202\377\377\377D\3502\371\377" + "\364O\3321\377\377\377\\\3161h\3042\367\377\324t\2702\375\377\310\200\252" + "1\377\377\377\215\2351\230\2242\377\377\250\244\2102\377\377\234\262x1\274" + "p2\316\214_\310d2\377\310|\327T1\227/\14\377\377\377\307\260|\244\2102\377" + "\377\377\307\300\213\230\2242\230\2242\377\377\377\310\316\231\214\2402\214" + "\2402\377\377\377\377\377\377\312\332\250\312\332\250\200\2542\200\2542\377" + "\377\377\377\377\377\377\377\377\317\344\266\317\344\266\317\344\266t\270" + "2t\2702t\2702\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\325\355\305\325\355\305\325\355\305\377\377\377\377\377\377h\3042h\3042" + "h\3042\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\335\364\323\335\364" + "\323\335\364\323\335\364\323\377\377\377\377\377\377\377\377\377\377\377" + "\377D\3502\371\377\364R\3344\364\377\352\\\3161H\22Hh\3021\377\377\377o\244" + "2\200\2542\312\332\250\226\245<\377\377\262\230\2242H-/\245\2041\377\377" + "\377\233i5\274p2\277l1\331sC\377\310|\324X2*\15\3\260|2\377\377\234\206s" + "7\244\2102\377\377\250\340\337\244\230\2242\377\377\377Hc2\310\316\231\214" + "\2402n\211:\377\377\377\377\377\377\353\377\311\312\332\250\200\2542$T\16" + "\377\377\377\377\377\377\236\277\236\377\377\377\317\344\266\367\377\336" + "\377\377\377t\2702\40n\16t\2702\377\377\377\212\303\212\377\377\377\377\377" + "\377\377\377\377\325\355\305\325\355\305<\2477\377\377\377\377\377\377O\276" + "Ah\3042h\3042\237\377i\377\377\377\377\377\377H\317H\377\377\377\377\377" + "\377c\335c\377\377\377\377\377\377\377\377\377\377\377\377\335\364\323>\337" + ";\335\364\323\377\377\377D\3502\362\375\360P\3342\346\371\342\\\3202\364" + "\377\336h\3042\367\377\324t\2702\375\377\310\200\2542\377\377\276\214\240" + "2\377\377\262\232\2211\377\377\377\245\2041\377\377\377\262x1\377\377\377" + "\277l1\310d2\312`1\324X2\327T1\260|2\377\377\377\307\260|\244\2102\377\377" + "\377\307\300\213\232\2211\230\2242\377\377\377\377\377\262\310\316\231\214" + "\2402\214\2402\377\377\377\377\377\377\312\332\250\312\332\250\200\2542\200" + "\2542\200\2542\377\377\377\377\377\377\377\377\377\317\344\266\317\344\266" + "\317\344\266\377\377\377t\2702t\2702t\2702\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\325\355\305\325\355\305\325\355\305\325\355" + "\305\377\377\377\377\377\377h\3042h\3042h\3042h\3042\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377D\3502\362\375\360P\3342\346\371\342\\\3202\335" + "\364\323h\3042\325\355\305t\2702\317\344\266\377\377\377\200\2521\377\377" + "\377\215\2351\377\377\377\232\2211\377\377\377\245\2041\377\377\377\262x" + "1\377\377\377\277l1\377\377\377\312`1\377\310|\327T1\227/\14\377\377\377" + "\307\260|\244\2102\244\2102\377\377\377\307\300\213\230\2242\230\2242\377" + "\377\377\310\316\231\310\316\231\214\2402\214\2402\377\377\377\377\377\377" + "\312\332\250\312\332\250\377\377\377\200\2542\200\2542\377\377\377\377\377" + "\377\377\377\377\377\377\377\317\344\266\317\344\266\377\377\377\377\377" + "\377t\2702t\2702\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\325\355\305\325\355\305\325\355\305\377\377" + "\377\377\377\377\377\377\377h\3042h\3042h\3042\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377D\3502\362\375\360" + "T\11TO\3321\377\377\377Z\3002\377\377\377h\3042\377\377\334t\2702\375\377" + "\310*\30\20\312\332\250\214\2402\262\260\214\230\2242\307\300\213\377\377" + "\377\245\2041\377\377\377:\35\20\377\377\377\277l1\316\264w\310d2\377\310" + "|\356qL\227/\14\260|2TZ3\307\260|\244\2102\274\302\274\307\300\213\307\300" + "\213\273\301U\377\377\377\377\377\377A^2\310\316\231\214\2402o\216B\377\377" + "\377\377\377\377\366\377\324\312\332\250\312\332\250*a\20\200\2542\377\377" + "\377\230\301\230\377\377\377\377\377\377\377\377\353\317\344\266\317\344" + "\266T\253Tt\2702t\2702]\265I\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377T\306T\377\377\377\325\355\305l\324i\325\355\305\377\377" + "\377\377\377\377\377\377\377h\3042\"\254\20h\3042h\3042b\353b\377\377\377" + "\377\377\377D\3502\362\375\360\377\377\377O\3321\377\377\377\\\3202\364\377" + "\336h\3042\325\355\305t\2702\317\344\266\377\377\377\200\2521\377\377\377" + "\214\2402\377\377\262\230\2242\307\300\213\244\2102\307\260|\377\377\377" + "\262x1\377\377\377\274p2\377\337\207\310d2\377\310|\324X2\333bB\260|2\377" + "\377\377\307\260|\244\2102\244\2102\377\377\377\307\300\213\232\2211\230" + "\2242\377\377\377\377\377\377\310\316\231\310\316\231\214\2402\214\2402\377" + "\377\377\377\377\377\377\377\377\312\332\250\312\332\250\200\2542\200\254" + "2\200\2542\377\377\377\377\377\377\377\377\377\377\377\377\317\344\266\317" + "\344\266\317\344\266\377\377\377t\2702t\2702t\2702\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\325\355\305" + "\325\355\305\325\355\305\325\355\305\377\377\377\377\377\377\377\377\377" + "h\3042h\3042\377\377\377\377\377\377D\3471\377\377\377P\3342\364\377\352" + "\\\3202\335\364\323\377\377\377h\3021\377\377\377t\2702\375\377\310\200\254" + "2\312\332\250\377\377\377\215\2351\377\377\377\230\2242\377\377\250\244\210" + "2\307\260|\377\377\377\262x1\377\377\377\274p2\377\337\207\310d2\323xQ\324" + "X2\327T1\227/\14\260|2\377\377\234\307\260|\244\2102\377\377\377\377\377" + "\377\307\300\213\230\2242\230\2242\377\377\377\377\377\377\310\316\231\310" + "\316\231\214\2402\214\2402\377\377\377\377\377\377\377\377\377\312\332\250" + "\312\332\250\377\377\377\200\2542\200\2542\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\317\344\266\317\344\266\377\377\377\377\377" + "\377t\2702t\2702t\2702\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\325\355\305\325\355\305\325" + "\355\305\377\377\377\377\377\377`\0`\377\377\377D\3471\371\366\371P\3342" + "\346\371\342\377\377\377\\\3161\377\377\377'\24\22\325\355\305t\2702\276" + "\310\251\377\377\377\200\2542\377\377\316\214\2402\310\316\231`6`\230\224" + "2\377\377\250\222u<\307\260|\377\377\377\315\214L\377\377\377\274p2M,#\310" + "d2\312`1\306\304\306\324X2\333bB\325\242W\377\377\377\307\260|=9\22\244\210" + "2\377\377\377\227\234w\307\300\213\230\2242\307\322a\377\377\377\377\377" + "\377Km9\310\316\231\214\2402r\226K\377\377\377\377\377\377\377\377\377\312" + "\332\250\312\332\250`\242`\200\2542\200\2542\224\306\224\377\377\377\377" + "\377\377\377\377\377\377\377\377\317\344\266M\250D\317\344\266\377\377\377" + "\203\322\203t\2702t\2702\301\377\177\377\377\377\377\377\377`\330`\377\377" + "\377\377\377\377r\344r\377\377\377\377\377\377\377\377\377\325\355\305\377" + "\377\377\377\377\377D\3502\371\377\364P\3342\346\371\342\377\377\377\\\320" + "2\364\377\336h\3042\325\355\305\377\377\377t\2702\317\344\266\200\2542\312" + "\332\250\377\377\377\214\2402\310\316\231\230\2242\307\300\213\377\377\377" + "\244\2102\307\260|\377\377\377\200U0\220^\377\7\4/\227U[\246]\377\255Q1\377" + "\242y\10\3/\306M@\6\4/{^\377mVvmVv\6\5/h\\\377h\\\377\\U\204\12\12\360\5" + "\5/VX\377VX\377\12\12\360LR\221\12\12\360\5\6/\214\2402\377\377\377\377\377" + "\377\377\377\377\312\332\250\312\332\250\377\377\377\200\2542\200\2542\200" + "\2542\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\317\344" + "\266\317\344\266\317\344\266\377\377\377\377\377\377t\2702t\2702\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377D\3502\362\375\360P\3342\346\371" + "\342\377\377\377\\\3202\335\364\323\377\377\377h\3042\367\377\324t\2702\317" + "\344\266\377\377\377\200\2542\312\332\250\377\377\377\214\2402\377\377\262" + "\230\2242\307\300\213\377\377\377\244\2102\307\260|{^\377\200U0\220^\377" + "\7\4/\227U[\246]\377\7\3/\377\242y\236\37" + "2\306M0\210%\14T-2{^\377mVv\6" + "\5/\6\5/h\\\377\\U\204\\U\204\5\5/\5\5/VX\377VX\377LR\221LR\221\377\377\377" + "\214\2402\214\2402\377\377\377\377\377\377\377\377\377\312\332\250\312\332" + "\250\312\332\250\377\377\377\200\2542\200\2542\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\317\344\266\317\344\266\377" + "\377\377\377\377\377t\2702t\2702t\2702\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377D\3502\365\375\363\377\377" + "\377O\3321l\22l\\\3202\335\364\323\357\346\357h\3042\325\355\305\377\377" + "\377t\2702\317\344\266l-l\200\2521\377\377\377\204\211=\310\316\231\377\377" + "\377\262\243L\307\300\213\377\377\377E&\25mVv{^\377ySB\220^\377\7\4/\275" + "t\201\246]\377\7\3/I\37!\277Z\377\10\3/\237YQ\6\4/{^\377\236\213\247mVv\6" + "\5/,-lh\\\377\\U\204dow\5\5/\5\5/\222\251\377VX\377\310\316\231T{@\377\377" + "\377\214\2402w\240V\377\377\377\377\377\377\377\377\377\377\377\377\312\332" + "\250U\231G\377\377\377\200\2542q\270\\\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377l\317l\317\344\266\317\344\266z\330v\377\377\377" + "\377\377\377\323\377\221t\2702t\2702l\352l\377\377\377\377\377\377\377\377" + "\377D\3502\362\375\360\377\377\377P\3342\346\371\342\377\377\377\\\3202\364" + "\377\336h\3042\325\355\305\377\377\377t\2702\317\344\266\377\377\377\200" + "\2542\312\332\250\377\377\377\214\2402\310\316\231\377\377\377\230\2242\307" + "\300\213\377\377\377\6\5/mVv{^\377\200U0\220^\377\7\4/\227U[\246]\377\7\3" + "/\255RN\277Z\377\10\3/\306M@\6\4/{^\377{^\377mVv\6\5/\6\5/h\\\377h\\\377" + "\\U\204\12\12\360\5\5/\12\12\360\377\377\377\377\377\377\310\316\231\310" + "\316\231\377\377\377\214\2402\214\2402\377\377\377\377\377\377\377\377\377" + "\377\377\377\312\332\250\312\332\250\377\377\377\200\2542\200\2542\200\254" + "2\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\317\344\266\317\344\266\317\344\266\377\377\377\377\377\377t\2702t\2702" + "\377\377\377\377\377\377D\3502\362\375\360\377\377\377P\3342\346\371\342" + "\377\377\377\\\3202\335\364\323\377\377\377h\3042\325\355\305\377\377\377" + "t\2702\317\344\266\377\377\377\200\2542\312\332\250\377\377\377\214\2402" + "\310\316\231\377\377\377\230\2242\307\300\213h\\\377\6\5/mVv{^\377\200U0" + "\220^\377\7\4/\227U[\246]\377\7\3/\255RN\277Z\377\10\3/\306M@\6\4/\6\4/{" + "^\377mVvmVv\6\5/\12\12\360h\\\377\\U\204\\U\204\5\5/\230\2242\377\377\377" + "\377\377\377\377\377\377\310\316\231\310\316\231\377\377\377\214\2402\214" + "\2402\377\377\377\377\377\377\377\377\377\377\377\377\312\332\250\312\332" + "\250\377\377\377\377\377\377\200\2542\200\2542\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\317\344\266\317" + "\344\266\377\377\377\377\377\377\377\377\377\377\377\377D\3502q\10p\377\377" + "\377P\3342\335\350\332\377\377\377\\\3202\351\366\337\377\377\377h\3042d" + "!\\\377\377\377t\2702\277\302\252\377\377\377\200\2542\343\345\301\377\377" + "\377\214\2402^2H\377\377\377\230\2242\257\235\204h\\\377\6\5/\223o\234{^" + "\377\6\4/<\36" + "1\377\252\215j)2\211XK\377\250\203\202$2\337~c\377\242y\236" + "\37" + "2]#\26\306M@\6\4/ym\274{^\377mVvELn\6\5/h\\\37703x\\U\204\307\300\213" + "\204\226\\\230\2242\377\377\377\377\377\377\377\377\377\310\316\231^\212" + "H\377\377\377\214\2402}\256b\377\377\377\377\377\377\377\377\377\377\377" + "\377\312\332\250_\251O\377\377\377\377\377\377y\310j\200\2542\377\377\377" + "\377\377\377\377\377\377\377\377\377x\341x\377\377\377\377\377\377\177\350" + "|\317\344\266\377\377\377\377\377\377D\3502\362\375\360\377\377\377P\334" + "2\346\371\342\377\377\377\\\3202\335\364\323\377\377\377\377\377\377h\304" + "2\325\355\305\377\377\377t\2702\317\344\266\377\377\377\200\2542\312\332" + "\250\377\377\377\214\2402\310\316\231\377\377\377\230\2242\\U\204h\\\377" + "\6\5/mVv{^\377\6\4/\12\12\360\201Vi\220^\377\7\4/\227U[\246]\377\7\3/\255" + "RN\277Z\377\10\3/\306M@\6\4/\12\12\360{^\377mVvmVv\6\5/\12\12\360h\\\377" + "\377\377\377\307\300\213\377\377\377\230\2242\230\2242\377\377\377\377\377" + "\377\377\377\377\310\316\231\310\316\231\377\377\377\214\2402\214\2402\377" + "\377\377\377\377\377\377\377\377\377\377\377\312\332\250\312\332\250\312" + "\332\250\377\377\377\200\2542\200\2542\200\2542\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377D\350" + "2\362\375\360\377\377\377P\3342\377\377\377\346\371\342\377\377\377\\\320" + "2\335\364\323\377\377\377h\3042\325\355\305\377\377\377t\2702\317\344\266" + "\377\377\377\200\2542\377\377\377\312\332\250\377\377\377\214\2402\310\316" + "\231\377\377\377\5\5/\\U\204h\\\377\6\5/mVv{^\377\6\4/\12\12\360\201Vi\220" + "^\377\7\4/\227U[\246]\377\7\3/\255RN\277Z\377\10\3/\306M@\6\4/\6\4/{^\377" + "\12\12\360mVv\6\5/\6\5/\377\377\377\377\377\377\307\300\213\307\300\213\377" + "\377\377\230\2242\377\377\377\377\377\377\377\377\377\377\377\377\310\316" + "\231\310\316\231\377\377\377\214\2402\214\2402\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\312\332\250\312\332\250\377\377\377\377" + "\377\377\200\2542\200\2542\377\377\377\377\377\377\377\377\377\377\377\377" + "\204\0\204\377\377\377D\3502\355\364\353\377\377\377\377\377\377Y\335;\346" + "\371\342\377\377\377/\26\31\335\364\323\377\377\377k\255<\325\355\305\377" + "\377\377\377\377\377t\2702\317\344\266\2046\204\200\2542\312\332\250\340" + "\317\340\214\2402\310\316\231\377\377\377VX\377\5\5//\33Dh\\\377\6\5/tVz" + "{^\377\6\4/=0\377\201Vi\220^\377\3\1\30\227U[\246]\377?6U\255RN\277Z\377" + "\337]s\306M0\306M@\3\2\30{^\377{^\377yv}mVv\244\2102\377\377\377\377\377" + "\377\377\377\377gyG\307\300\213\230\2242\212\242h\377\377\377\377\377\377" + "\377\377\377\377\377\377\310\316\231g\230O\377\377\377\214\2402\205\274q" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377h\270V\312\332" + "\250\377\377\377\222\344\222\200\2542\200\2542\377\377\377\377\377\377\377" + "\377\377\377\377\377D\3502\362\375\360\377\377\377\377\377\377P\3342\346" + "\371\342\377\377\377\\\3202\335\364\323\377\377\377\377\377\377h\3042\325" + "\355\305\377\377\377t\2702\317\344\266\377\377\377\377\377\377\200\2542\312" + "\332\250\377\377\377\214\2402\310\316\231VX\377\12\12\360\5\5/\\U\204h\\" + "\377\6\5/mVv{^\377\6\4/\12\12\360\201Vi\220^\377\7\4/\227U[\246]\377\7\3" + "/\255RN\255RN\277Z\377\10\3/\306M@\6\4/\12\12\360{^\377\12\12\360\307\260" + "|\244\2102\244\2102\377\377\377\377\377\377\377\377\377\307\300\213\377\377" + "\377\230\2242\230\2242\377\377\377\377\377\377\377\377\377\377\377\377\310" + "\316\231\377\377\377\377\377\377\214\2402\214\2402\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\312\332\250\312\332\250\377\377\377" + "\377\377\377\200\2542\200\2542\377\377\377\377\377\377D\3502\377\377\377" + "\362\375\360\377\377\377P\3342\346\371\342\377\377\377\\\3202\377\377\377" + "\335\364\323\377\377\377h\3042\325\355\305\377\377\377\377\377\377t\2702" + "\317\344\266\377\377\377\200\2542\312\332\250\377\377\377\377\377\377\214" + "\2402LR\221VX\377\5\5/\\U\204\12\12\360h\\\377\6\5/mVv{^\377\6\4/\12\12\360" + "\201Vi\220^\377\7\4/\227U[\246]\377\7\3/\7\3/\255RN\277Z\377\10\3/\306M@" + "\6\4/\6\4/{^\377\377\377\377\307\260|\377\377\377\244\2102\377\377\377\377" + "\377\377\377\377\377\307\300\213\307\300\213\377\377\377\230\2242\377\377" + "\377\377\377\377\377\377\377\377\377\377\310\316\231\310\316\231\377\377" + "\377\377\377\377\214\2402\214\2402\377\377\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\312\332\250\312\332\250\377\377\377\377\377\377\377" + "\377\377\377\377\377D\3502\377\377\377\362\375\360\377\377\377-\17\34\346" + "\371\342\377\377\377\363\346\363\\\3202\335\364\323\377\377\377h\3042\377" + "\377\377x)o\377\377\377t\2702\301\276\255\377\377\377\377\377\377\243\273" + "U\312\332\250\377\377\377O-\34\12\12\360LR\221gU\333\5\5/\\U\204<)\377h\\" + "\377\6\5/=!B{^\377\6\4/A2\306\201Vi\220^\377I9q\227U[\246]\377]-\220\7\3" + "/\255RN\245q\304\10\3/\306M0\377\236\221\6\4/\377\377\377\220\231\220\307" + "\260|\307\260|\226\227m\244\2102\377\377\377\377\377\377\377\377\377\307" + "\300\213p\207N\230\2242\230\2242\254\316\254\377\377\377\377\377\377\377" + "\377\377\310\316\231\310\316\231\220\317\220\377\377\377\214\2402\216\316" + "\200\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377r\310^\312" + "\332\250\377\377\377\377\377\377\377\377\377D\3502\362\375\360\377\377\377" + "P\3342\377\377\377\346\371\342\377\377\377\\\3202\335\364\323\377\377\377" + "\377\377\377h\3042\325\355\305\377\377\377\377\377\377t\2702\317\344\266" + "\377\377\377\200\2542\377\377\377\312\332\250\377\377\377\5\6/LR\221\12\12" + "\360VX\377\5\5/\\U\204h\\\377\12\12\360\6\5/mVv{^\377\6\4/\12\12\360\201" + "Vi\220^\377\7\4/\227U[\12\12\360\246]\377\7\3/\255RN\277Z\377\277Z\377\10" + "\3/\306M@\260|2\260|2\377\377\377\377\377\377\307\260|\377\377\377\244\210" + "2\377\377\377\377\377\377\377\377\377\377\377\377\307\300\213\377\377\377" + "\230\2242\230\2242\377\377\377\377\377\377\377\377\377\377\377\377\310\316" + "\231\310\316\231\377\377\377\377\377\377\214\2402\214\2402\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" + "\377\377D\3502\362\375\360\377\377\377P\3342\377\377\377\346\371\342\377" + "\377\377\\\3202\377\377\377\335\364\323\377\377\377h\3042\325\355\305\377" + "\377\377\377\377\377t\2702\317\344\266\377\377\377\377\377\377\200\2542\312" + "\332\250\377\377\377\12\12\360\5\6/LR\221VX\377\12\12\360\5\5/\\U\204h\\" + "\377\6\5/\12\12\360mVv{^\377\6\4/\12\12\360\201Vi\220^\377\7\4/\227U[\227" + "U[\246]\377\7\3/\255RN\12\12\360\277Z\377\10\3/\333bB\377\377\377\260|2\377" + "\377\377\377\377\377\307\260|\307\260|\244\2102\244\2102\377\377\377\377" + "\377\377\377\377\377\307\300\213\307\300\213\377\377\377\230\2242\230\224" + "2\377\377\377\377\377\377\377\377\377\377\377\377\310\316\231\310\316\231" + "\377\377\377\377\377\377\214\2402\214\2402\377\377\377\377\377\377\377\377" + "\377\377\377\377\377\377\377\377\377\377)\10\36\362\375\360\377\377\377\370" + "\356\370P\3342\346\371\342\377\377\377\377\377\377\\\3202\207\"\201\377\377" + "\377\377\377\377p\250D\325\355\305\377\377\377\377\377\377t\2702\317\344" + "\266\234?\234\200\2542\377\377\377\274\260\244FS\377\5\6/;#\377LR\221VX\377" + "\3\1\34\12\12\360\\U\204{^\330\6\5/\12\12\360\257\203\270{^\377\6\4/\6\4" + "\222\201Vi\220^\377P@d\12\12\360\227U[\370\244\377\7\3/\255RNi./\277Z\377" + "\324X2\264\202w\333bB\260|2\377\377\377\377\377\377\377\377\377yvK\377\377" + "\377\244\2102\236\247|\377\377\377\377\377\377\377\377\377\307\300\213\307" + "\300\213\234\306\234\230\2242\377\377\377\256\330\256\377\377\377\377\377" + "\377\377\377\377\310\316\231\310\316\231\234\341\234\377\377\377\214\240" + "2\232\343\223\377\377\377\377\377\377\377\377\377\377\377\377D\3502\362\375" + "\360\377\377\377\377\377\377P\3342\346\371\342\377\377\377\377\377\377\\" + "\3202\335\364\323\377\377\377\377\377\377h\3042\325\355\305\377\377\377\377" + "\377\377t\2702\317\344\266\377\377\377\377\377\377\200\2542\312\332\250\12" + "\12\360FS\377\5\6/LR\221\12\12\360RW\255\3\5\35\6\11\224ZT\\d[\261\3\4\35" + "\6\11\224lVTw]\264\4\4\35\6\11\224\200VN\214]\270\4\3\35\6\11\224\226UG\242" + "\\\274\4\3\35\4\3\35\254R@\377\377\311\203U\36\203U\36\323a:my\36my\36\377" + "\377\276\377\377\276\243\255X\243\255X\236\371\236e\204\36\236\371\236\374" + "\377\273\236\371\236\236\371\236\234\275`\236\371\236^\220\36^\220\36\236" + "\371\236\352\377\267\352\377\267\236\371\236\236\371\236\310\316\231\310" + "\316\231\377\377\377\377\377\377\214\2402\377\377\377\377\377\377\377\377" + "\377D\3502\362\375\360\377\377\377\377\377\377P\3342\346\371\342\377\377" + "\377\377\377\377\\\3202\377\377\377\335\364\323\377\377\377h\3042\377\377" + "\377\325\355\305\377\377\377t\2702\377\377\377\317\344\266\377\377\377\377" + "\377\377\200\2542\346\3\4\35lVT\4\4hw]\264\4\4\35aK\244\200VN\214]\270kZ\371\4\3\35" + "\270\212Io\225o\377\377\306{a\36\253\300\253\304wB\377\377\311\377\377\377" + "\203U\36\323a:\224D(my\36\236\371\236\307\316\266\377\377\276\236\371\236" + "\377\377\343\236\371\236e\204\36Gk\25\236\371\236\374\377\273\260\334\260" + "\236\371\236\234\275`\377\377\377\377\377\377\230\2242k\207#\377\377\377" + "\377\377\377\377\377\377\377\377\377D\3502\377\377\377\362\375\360\377\377" + "\377\377\377\377P\3342\346\371\342\377\377\377\377\377\377\\\3202\377\377" + "\377\335\364\323\377\377\377\377\377\377h\3042\377\377\377\325\355\305\377" + "\377\377\377\377\377t\2702\317\344\266\377\377\3778L\377\12\12\360\5\6/<" + "L\237\12\12\360BR\252\3\5\35\6\11\224JQbRW\255\6\11\224\3\5\35ZT\\\6\11\224" + "d[\261\6\11\224\3\4\35lVT\6\11\224w]\264\4\4\35\6\11\224\200VN\214]\270\6" + "\11\224tm\36\270\212I\270\212I\377\377\306{a\36{a\36\304wB\236\371\236\377" + "\377\311\203U\36\236\371\236\323a:my\36my\36\236\371\236\377\377\276\236" + "\371\236\243\255X\243\255X\236\371\236e\204\36\236\371\236\374\377\273\374" + "\377\273\236\371\236\307\300\213\307\300\213\377\377\377\377\377\377\230" + "\2242\377\377\377\377\377\377\377\377\377D\3502\377\377\377\362\375\360\377" + "\377\377\377\377\377P\3342\377\377\377\346\371\342\377\377\377\377\377\377" + "\\\3202\335\364\323\377\377\377\377\377\377\377\377\377h\3042\325\355\305" + "\377\377\377\377\377\377t\2702\377\377\377\317\344\2668L\377\12\12\360\5" + "\6/\12\12\360 + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -27,7 +27,7 @@ /* quiet windows compiler warnings */ #if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) -# define _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS #endif #include "SDL_config.h" @@ -43,8 +43,7 @@ /* work around compiler warning on older GCCs. */ #if (defined(__GNUC__) && (__GNUC__ <= 2)) -static size_t -strftime_gcc2_workaround(char *s, size_t max, const char *fmt, const struct tm *tm) +static size_t strftime_gcc2_workaround(char *s, size_t max, const char *fmt, const struct tm *tm) { return strftime(s, max, fmt, tm); } @@ -65,16 +64,21 @@ strftime_gcc2_workaround(char *s, size_t max, const char *fmt, const struct tm * * * \return Ascii representation of the timestamp in localtime in the format '08/23/01 14:55:02' */ -static char *SDLTest_TimestampToString(const time_t timestamp) +static const char * +SDLTest_TimestampToString(const time_t timestamp) { time_t copy; static char buffer[64]; struct tm *local; + size_t result = 0; SDL_memset(buffer, 0, sizeof(buffer)); copy = timestamp; local = localtime(©); - strftime(buffer, sizeof(buffer), "%x %X", local); + result = strftime(buffer, sizeof(buffer), "%x %X", local); + if (result == 0) { + return ""; + } return buffer; } @@ -90,7 +94,7 @@ void SDLTest_Log(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) /* Print log message into a buffer */ SDL_memset(logMessage, 0, SDLTEST_MAX_LOGMESSAGE_LENGTH); va_start(list, fmt); - SDL_vsnprintf(logMessage, SDLTEST_MAX_LOGMESSAGE_LENGTH - 1, fmt, list); + (void)SDL_vsnprintf(logMessage, SDLTEST_MAX_LOGMESSAGE_LENGTH - 1, fmt, list); va_end(list); /* Log with timestamp and newline */ @@ -108,7 +112,7 @@ void SDLTest_LogError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) /* Print log message into a buffer */ SDL_memset(logMessage, 0, SDLTEST_MAX_LOGMESSAGE_LENGTH); va_start(list, fmt); - SDL_vsnprintf(logMessage, SDLTEST_MAX_LOGMESSAGE_LENGTH - 1, fmt, list); + (void)SDL_vsnprintf(logMessage, SDLTEST_MAX_LOGMESSAGE_LENGTH - 1, fmt, list); va_end(list); /* Log with timestamp and newline */ diff --git a/SDL2-2.30.5/src/test/SDL_test_md5.c b/SDL2-2.30.5/src/test/SDL_test_md5.c new file mode 100644 index 0000000..83f6f9c --- /dev/null +++ b/SDL2-2.30.5/src/test/SDL_test_md5.c @@ -0,0 +1,347 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +/* + *********************************************************************** + ** RSA Data Security, Inc. MD5 Message-Digest Algorithm ** + ** Created: 2/17/90 RLR ** + ** Revised: 1/91 SRD,AJ,BSK,JT Reference C ver., 7/10 constant corr. ** + *********************************************************************** + */ + +/* + *********************************************************************** + ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** + ** ** + ** License to copy and use this software is granted provided that ** + ** it is identified as the "RSA Data Security, Inc. MD5 Message- ** + ** Digest Algorithm" in all material mentioning or referencing this ** + ** software or this function. ** + ** ** + ** License is also granted to make and use derivative works ** + ** provided that such works are identified as "derived from the RSA ** + ** Data Security, Inc. MD5 Message-Digest Algorithm" in all ** + ** material mentioning or referencing the derived work. ** + ** ** + ** RSA Data Security, Inc. makes no representations concerning ** + ** either the merchantability of this software or the suitability ** + ** of this software for any particular purpose. It is provided "as ** + ** is" without express or implied warranty of any kind. ** + ** ** + ** These notices must be retained in any copies of any part of this ** + ** documentation and/or software. ** + *********************************************************************** + */ + +#include "SDL_config.h" + +#include "SDL_test.h" + +/* Forward declaration of static helper function */ +static void SDLTest_Md5Transform(MD5UINT4 *buf, const MD5UINT4 *in); + +static unsigned char MD5PADDING[64] = { + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +/* F, G, H and I are basic MD5 functions */ +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | (~z))) + +/* ROTATE_LEFT rotates x left n bits */ +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) + +/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */ + +/* Rotation is separate from addition to prevent recomputation */ +#define FF(a, b, c, d, x, s, ac) \ + { \ + (a) += F((b), (c), (d)) + (x) + (MD5UINT4)(ac); \ + (a) = ROTATE_LEFT((a), (s)); \ + (a) += (b); \ + } +#define GG(a, b, c, d, x, s, ac) \ + { \ + (a) += G((b), (c), (d)) + (x) + (MD5UINT4)(ac); \ + (a) = ROTATE_LEFT((a), (s)); \ + (a) += (b); \ + } +#define HH(a, b, c, d, x, s, ac) \ + { \ + (a) += H((b), (c), (d)) + (x) + (MD5UINT4)(ac); \ + (a) = ROTATE_LEFT((a), (s)); \ + (a) += (b); \ + } +#define II(a, b, c, d, x, s, ac) \ + { \ + (a) += I((b), (c), (d)) + (x) + (MD5UINT4)(ac); \ + (a) = ROTATE_LEFT((a), (s)); \ + (a) += (b); \ + } + +/* + The routine MD5Init initializes the message-digest context + mdContext. All fields are set to zero. +*/ + +void SDLTest_Md5Init(SDLTest_Md5Context *mdContext) +{ + if (!mdContext) { + return; + } + + mdContext->i[0] = mdContext->i[1] = (MD5UINT4)0; + + /* + * Load magic initialization constants. + */ + mdContext->buf[0] = (MD5UINT4)0x67452301; + mdContext->buf[1] = (MD5UINT4)0xefcdab89; + mdContext->buf[2] = (MD5UINT4)0x98badcfe; + mdContext->buf[3] = (MD5UINT4)0x10325476; +} + +/* + The routine MD5Update updates the message-digest context to + account for the presence of each of the characters inBuf[0..inLen-1] + in the message whose digest is being computed. +*/ + +void SDLTest_Md5Update(SDLTest_Md5Context *mdContext, unsigned char *inBuf, + unsigned int inLen) +{ + MD5UINT4 in[16]; + int mdi; + unsigned int i, ii; + + if (!mdContext) { + return; + } + if (!inBuf || inLen < 1) { + return; + } + + /* + * compute number of bytes mod 64 + */ + mdi = (int)((mdContext->i[0] >> 3) & 0x3F); + + /* + * update number of bits + */ + if ((mdContext->i[0] + ((MD5UINT4)inLen << 3)) < mdContext->i[0]) { + mdContext->i[1]++; + } + mdContext->i[0] += ((MD5UINT4)inLen << 3); + mdContext->i[1] += ((MD5UINT4)inLen >> 29); + + while (inLen--) { + /* + * add new character to buffer, increment mdi + */ + mdContext->in[mdi++] = *inBuf++; + + /* + * transform if necessary + */ + if (mdi == 0x40) { + for (i = 0, ii = 0; i < 16; i++, ii += 4) { + in[i] = (((MD5UINT4)mdContext->in[ii + 3]) << 24) | (((MD5UINT4)mdContext->in[ii + 2]) << 16) | (((MD5UINT4)mdContext->in[ii + 1]) << 8) | ((MD5UINT4)mdContext->in[ii]); + } + SDLTest_Md5Transform(mdContext->buf, in); + mdi = 0; + } + } +} + +/* + The routine MD5Final terminates the message-digest computation and + ends with the desired message digest in mdContext->digest[0...15]. +*/ + +void SDLTest_Md5Final(SDLTest_Md5Context *mdContext) +{ + MD5UINT4 in[16]; + int mdi; + unsigned int i, ii; + unsigned int padLen; + + if (!mdContext) { + return; + } + + /* + * save number of bits + */ + in[14] = mdContext->i[0]; + in[15] = mdContext->i[1]; + + /* + * compute number of bytes mod 64 + */ + mdi = (int)((mdContext->i[0] >> 3) & 0x3F); + + /* + * pad out to 56 mod 64 + */ + padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi); + SDLTest_Md5Update(mdContext, MD5PADDING, padLen); + + /* + * append length in bits and transform + */ + for (i = 0, ii = 0; i < 14; i++, ii += 4) { + in[i] = (((MD5UINT4)mdContext->in[ii + 3]) << 24) | (((MD5UINT4)mdContext->in[ii + 2]) << 16) | (((MD5UINT4)mdContext->in[ii + 1]) << 8) | ((MD5UINT4)mdContext->in[ii]); + } + SDLTest_Md5Transform(mdContext->buf, in); + + /* + * store buffer in digest + */ + for (i = 0, ii = 0; i < 4; i++, ii += 4) { + mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF); + mdContext->digest[ii + 1] = + (unsigned char)((mdContext->buf[i] >> 8) & 0xFF); + mdContext->digest[ii + 2] = + (unsigned char)((mdContext->buf[i] >> 16) & 0xFF); + mdContext->digest[ii + 3] = + (unsigned char)((mdContext->buf[i] >> 24) & 0xFF); + } +} + +/* Basic MD5 step. Transforms buf based on in. + */ +static void SDLTest_Md5Transform(MD5UINT4 *buf, const MD5UINT4 *in) +{ + MD5UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3]; + + /* + * Round 1 + */ +#define S11 7 +#define S12 12 +#define S13 17 +#define S14 22 + FF(a, b, c, d, in[0], S11, 3614090360u); /* 1 */ + FF(d, a, b, c, in[1], S12, 3905402710u); /* 2 */ + FF(c, d, a, b, in[2], S13, 606105819u); /* 3 */ + FF(b, c, d, a, in[3], S14, 3250441966u); /* 4 */ + FF(a, b, c, d, in[4], S11, 4118548399u); /* 5 */ + FF(d, a, b, c, in[5], S12, 1200080426u); /* 6 */ + FF(c, d, a, b, in[6], S13, 2821735955u); /* 7 */ + FF(b, c, d, a, in[7], S14, 4249261313u); /* 8 */ + FF(a, b, c, d, in[8], S11, 1770035416u); /* 9 */ + FF(d, a, b, c, in[9], S12, 2336552879u); /* 10 */ + FF(c, d, a, b, in[10], S13, 4294925233u); /* 11 */ + FF(b, c, d, a, in[11], S14, 2304563134u); /* 12 */ + FF(a, b, c, d, in[12], S11, 1804603682u); /* 13 */ + FF(d, a, b, c, in[13], S12, 4254626195u); /* 14 */ + FF(c, d, a, b, in[14], S13, 2792965006u); /* 15 */ + FF(b, c, d, a, in[15], S14, 1236535329u); /* 16 */ + + /* + * Round 2 + */ +#define S21 5 +#define S22 9 +#define S23 14 +#define S24 20 + GG(a, b, c, d, in[1], S21, 4129170786u); /* 17 */ + GG(d, a, b, c, in[6], S22, 3225465664u); /* 18 */ + GG(c, d, a, b, in[11], S23, 643717713u); /* 19 */ + GG(b, c, d, a, in[0], S24, 3921069994u); /* 20 */ + GG(a, b, c, d, in[5], S21, 3593408605u); /* 21 */ + GG(d, a, b, c, in[10], S22, 38016083u); /* 22 */ + GG(c, d, a, b, in[15], S23, 3634488961u); /* 23 */ + GG(b, c, d, a, in[4], S24, 3889429448u); /* 24 */ + GG(a, b, c, d, in[9], S21, 568446438u); /* 25 */ + GG(d, a, b, c, in[14], S22, 3275163606u); /* 26 */ + GG(c, d, a, b, in[3], S23, 4107603335u); /* 27 */ + GG(b, c, d, a, in[8], S24, 1163531501u); /* 28 */ + GG(a, b, c, d, in[13], S21, 2850285829u); /* 29 */ + GG(d, a, b, c, in[2], S22, 4243563512u); /* 30 */ + GG(c, d, a, b, in[7], S23, 1735328473u); /* 31 */ + GG(b, c, d, a, in[12], S24, 2368359562u); /* 32 */ + + /* + * Round 3 + */ +#define S31 4 +#define S32 11 +#define S33 16 +#define S34 23 + HH(a, b, c, d, in[5], S31, 4294588738u); /* 33 */ + HH(d, a, b, c, in[8], S32, 2272392833u); /* 34 */ + HH(c, d, a, b, in[11], S33, 1839030562u); /* 35 */ + HH(b, c, d, a, in[14], S34, 4259657740u); /* 36 */ + HH(a, b, c, d, in[1], S31, 2763975236u); /* 37 */ + HH(d, a, b, c, in[4], S32, 1272893353u); /* 38 */ + HH(c, d, a, b, in[7], S33, 4139469664u); /* 39 */ + HH(b, c, d, a, in[10], S34, 3200236656u); /* 40 */ + HH(a, b, c, d, in[13], S31, 681279174u); /* 41 */ + HH(d, a, b, c, in[0], S32, 3936430074u); /* 42 */ + HH(c, d, a, b, in[3], S33, 3572445317u); /* 43 */ + HH(b, c, d, a, in[6], S34, 76029189u); /* 44 */ + HH(a, b, c, d, in[9], S31, 3654602809u); /* 45 */ + HH(d, a, b, c, in[12], S32, 3873151461u); /* 46 */ + HH(c, d, a, b, in[15], S33, 530742520u); /* 47 */ + HH(b, c, d, a, in[2], S34, 3299628645u); /* 48 */ + + /* + * Round 4 + */ +#define S41 6 +#define S42 10 +#define S43 15 +#define S44 21 + II(a, b, c, d, in[0], S41, 4096336452u); /* 49 */ + II(d, a, b, c, in[7], S42, 1126891415u); /* 50 */ + II(c, d, a, b, in[14], S43, 2878612391u); /* 51 */ + II(b, c, d, a, in[5], S44, 4237533241u); /* 52 */ + II(a, b, c, d, in[12], S41, 1700485571u); /* 53 */ + II(d, a, b, c, in[3], S42, 2399980690u); /* 54 */ + II(c, d, a, b, in[10], S43, 4293915773u); /* 55 */ + II(b, c, d, a, in[1], S44, 2240044497u); /* 56 */ + II(a, b, c, d, in[8], S41, 1873313359u); /* 57 */ + II(d, a, b, c, in[15], S42, 4264355552u); /* 58 */ + II(c, d, a, b, in[6], S43, 2734768916u); /* 59 */ + II(b, c, d, a, in[13], S44, 1309151649u); /* 60 */ + II(a, b, c, d, in[4], S41, 4149444226u); /* 61 */ + II(d, a, b, c, in[11], S42, 3174756917u); /* 62 */ + II(c, d, a, b, in[2], S43, 718787259u); /* 63 */ + II(b, c, d, a, in[9], S44, 3951481745u); /* 64 */ + + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/test/SDL_test_memory.c b/SDL2-2.30.5/src/test/SDL_test_memory.c similarity index 83% rename from SDL2-2.0.12/src/test/SDL_test_memory.c rename to SDL2-2.30.5/src/test/SDL_test_memory.c index c9f5520..ffd3eaa 100644 --- a/SDL2-2.0.12/src/test/SDL_test_memory.c +++ b/SDL2-2.30.5/src/test/SDL_test_memory.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,6 +26,7 @@ #include "SDL_test_memory.h" #ifdef HAVE_LIBUNWIND_H +#define UNW_LOCAL_ONLY #include #endif @@ -61,7 +62,7 @@ static unsigned int get_allocation_bucket(void *mem) index = (crc_value & (SDL_arraysize(s_tracked_allocations) - 1)); return index; } - + static SDL_bool SDL_IsAllocationTracked(void *mem) { SDL_tracked_allocation *entry; @@ -103,13 +104,13 @@ static void SDL_TrackAllocation(void *mem, size_t size) stack_index = 0; while (unw_step(&cursor) > 0) { unw_word_t offset, pc; - char sym[256]; + char sym[236]; 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, (unsigned long long)offset); + SDL_snprintf(entry->stack_names[stack_index], sizeof(entry->stack_names[stack_index]), "%s+0x%llx", sym, (unsigned long long)offset); } ++stack_index; @@ -144,7 +145,7 @@ static void SDL_UntrackAllocation(void *mem) } } -static void * SDLCALL SDLTest_TrackedMalloc(size_t size) +static void *SDLCALL SDLTest_TrackedMalloc(size_t size) { void *mem; @@ -155,7 +156,7 @@ static void * SDLCALL SDLTest_TrackedMalloc(size_t size) return mem; } -static void * SDLCALL SDLTest_TrackedCalloc(size_t nmemb, size_t size) +static void *SDLCALL SDLTest_TrackedCalloc(size_t nmemb, size_t size) { void *mem; @@ -166,11 +167,11 @@ static void * SDLCALL SDLTest_TrackedCalloc(size_t nmemb, size_t size) return mem; } -static void * SDLCALL SDLTest_TrackedRealloc(void *ptr, size_t size) +static void *SDLCALL SDLTest_TrackedRealloc(void *ptr, size_t size) { void *mem; - SDL_assert(!ptr || SDL_IsAllocationTracked(ptr)); + SDL_assert(ptr == NULL || SDL_IsAllocationTracked(ptr)); mem = SDL_realloc_orig(ptr, size); if (mem && mem != ptr) { if (ptr) { @@ -232,13 +233,19 @@ void SDLTest_LogAllocations() return; } -#define ADD_LINE() \ - message_size += (SDL_strlen(line) + 1); \ + message = SDL_realloc_orig(NULL, 1); + if (!message) { + return; + } + *message = 0; + +#define ADD_LINE() \ + message_size += (SDL_strlen(line) + 1); \ tmp = (char *)SDL_realloc_orig(message, message_size); \ - if (!tmp) { \ - return; \ - } \ - message = tmp; \ + if (!tmp) { \ + return; \ + } \ + message = tmp; \ SDL_strlcat(message, line, message_size) SDL_strlcpy(line, "Memory allocations:\n", sizeof(line)); @@ -250,21 +257,21 @@ 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: %d bytes\n", count, (int)entry->size); + (void)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%"SDL_PRIx64": %s\n", entry->stack[stack_index], entry->stack_names[stack_index]); + (void)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; ++count; } } - SDL_snprintf(line, sizeof(line), "Total: %.2f Kb in %d allocations\n", (float)total_allocated / 1024, count); + (void)SDL_snprintf(line, sizeof(line), "Total: %.2f Kb in %d allocations\n", total_allocated / 1024.0, count); ADD_LINE(); #undef ADD_LINE diff --git a/SDL2-2.30.5/src/test/SDL_test_random.c b/SDL2-2.30.5/src/test/SDL_test_random.c new file mode 100644 index 0000000..0d7ef4e --- /dev/null +++ b/SDL2-2.30.5/src/test/SDL_test_random.c @@ -0,0 +1,104 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +/* + + A portable "32-bit Multiply with carry" random number generator. + + Used by the fuzzer component. + Original source code contributed by A. Schiffler for GSOC project. + +*/ + +#include "SDL_config.h" + +#include +#include +#include + +#include "SDL_test.h" + +/* Initialize random number generator with two integer variables */ + +void SDLTest_RandomInit(SDLTest_RandomContext *rndContext, unsigned int xi, unsigned int ci) +{ + if (!rndContext) { + return; + } + + /* + * Choose a value for 'a' from this list + * 1791398085 1929682203 1683268614 1965537969 1675393560 + * 1967773755 1517746329 1447497129 1655692410 1606218150 + * 2051013963 1075433238 1557985959 1781943330 1893513180 + * 1631296680 2131995753 2083801278 1873196400 1554115554 + */ + rndContext->a = 1655692410; + rndContext->x = 30903; + rndContext->c = 0; + if (xi != 0) { + rndContext->x = xi; + } + rndContext->c = ci; + rndContext->ah = rndContext->a >> 16; + rndContext->al = rndContext->a & 65535; +} + +/* Initialize random number generator from system time */ + +void SDLTest_RandomInitTime(SDLTest_RandomContext *rndContext) +{ + int a, b; + + if (!rndContext) { + return; + } + + srand((unsigned int)time(NULL)); + a = rand(); + srand((unsigned int)SDL_GetPerformanceCounter()); + b = rand(); + SDLTest_RandomInit(rndContext, a, b); +} + +/* Returns random numbers */ + +unsigned int SDLTest_Random(SDLTest_RandomContext *rndContext) +{ + unsigned int xh, xl; + + if (!rndContext) { + return -1; + } + + xh = rndContext->x >> 16; + xl = rndContext->x & 65535; + rndContext->x = rndContext->x * rndContext->a + rndContext->c; + rndContext->c = + xh * rndContext->ah + ((xh * rndContext->al) >> 16) + + ((xl * rndContext->ah) >> 16); + if (xl * rndContext->al >= (~rndContext->c + 1)) { + rndContext->c++; + } + return rndContext->x; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/thread/SDL_systhread.h b/SDL2-2.30.5/src/thread/SDL_systhread.h similarity index 81% rename from SDL2-2.0.12/src/thread/SDL_systhread.h rename to SDL2-2.30.5/src/thread/SDL_systhread.h index 250a89b..b56eaf4 100644 --- a/SDL2-2.0.12/src/thread/SDL_systhread.h +++ b/SDL2-2.30.5/src/thread/SDL_systhread.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -28,16 +28,21 @@ #include "SDL_thread.h" #include "SDL_thread_c.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + /* This function creates a thread, passing args to SDL_RunThread(), saves a system-dependent thread id in thread->id, and returns 0 on success. */ #ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD -extern int SDL_SYS_CreateThread(SDL_Thread * thread, void *args, +extern int SDL_SYS_CreateThread(SDL_Thread *thread, pfnSDL_CurrentBeginThread pfnBeginThread, pfnSDL_CurrentEndThread pfnEndThread); #else -extern int SDL_SYS_CreateThread(SDL_Thread * thread, void *args); +extern int SDL_SYS_CreateThread(SDL_Thread *thread); #endif /* This function does any necessary setup in the child thread */ @@ -49,10 +54,10 @@ extern int SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority); /* This function waits for the thread to finish and frees any data allocated by SDL_SYS_CreateThread() */ -extern void SDL_SYS_WaitThread(SDL_Thread * thread); +extern void SDL_SYS_WaitThread(SDL_Thread *thread); /* Mark thread as cleaned up as soon as it exits, without joining. */ -extern void SDL_SYS_DetachThread(SDL_Thread * thread); +extern void SDL_SYS_DetachThread(SDL_Thread *thread); /* Get the thread local storage for this thread */ extern SDL_TLSData *SDL_SYS_GetTLSData(void); @@ -62,9 +67,14 @@ extern int SDL_SYS_SetTLSData(SDL_TLSData *data); /* This is for internal SDL use, so we don't need #ifdefs everywhere. */ extern SDL_Thread * -SDL_CreateThreadInternal(int (SDLCALL * fn) (void *), const char *name, +SDL_CreateThreadInternal(int(SDLCALL *fn)(void *), const char *name, const size_t stacksize, void *data); +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif + #endif /* SDL_systhread_h_ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/thread/SDL_thread.c b/SDL2-2.30.5/src/thread/SDL_thread.c similarity index 70% rename from SDL2-2.0.12/src/thread/SDL_thread.c rename to SDL2-2.30.5/src/thread/SDL_thread.c index c53ddcd..55c2902 100644 --- a/SDL2-2.0.12/src/thread/SDL_thread.c +++ b/SDL2-2.30.5/src/thread/SDL_thread.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -22,23 +22,19 @@ /* System independent thread management routines for SDL */ -#include "SDL_assert.h" #include "SDL_thread.h" #include "SDL_thread_c.h" #include "SDL_systhread.h" #include "SDL_hints.h" #include "../SDL_error_c.h" - -SDL_TLSID -SDL_TLSCreate() +SDL_TLSID SDL_TLSCreate(void) { static SDL_atomic_t SDL_tls_id; - return SDL_AtomicIncRef(&SDL_tls_id)+1; + return SDL_AtomicIncRef(&SDL_tls_id) + 1; } -void * -SDL_TLSGet(SDL_TLSID id) +void *SDL_TLSGet(SDL_TLSID id) { SDL_TLSData *storage; @@ -46,11 +42,10 @@ SDL_TLSGet(SDL_TLSID id) if (!storage || id == 0 || id > storage->limit) { return NULL; } - return storage->array[id-1].data; + return storage->array[id - 1].data; } -int -SDL_TLSSet(SDL_TLSID id, const void *value, void (SDLCALL *destructor)(void *)) +int SDL_TLSSet(SDL_TLSID id, const void *value, void(SDLCALL *destructor)(void *)) { SDL_TLSData *storage; @@ -64,7 +59,7 @@ SDL_TLSSet(SDL_TLSID id, const void *value, void (SDLCALL *destructor)(void *)) oldlimit = storage ? storage->limit : 0; newlimit = (id + TLS_ALLOC_CHUNKSIZE); - storage = (SDL_TLSData *)SDL_realloc(storage, sizeof(*storage)+(newlimit-1)*sizeof(storage->array[0])); + storage = (SDL_TLSData *)SDL_realloc(storage, sizeof(*storage) + (newlimit - 1) * sizeof(storage->array[0])); if (!storage) { return SDL_OutOfMemory(); } @@ -78,13 +73,12 @@ SDL_TLSSet(SDL_TLSID id, const void *value, void (SDLCALL *destructor)(void *)) } } - storage->array[id-1].data = SDL_const_cast(void*, value); - storage->array[id-1].destructor = destructor; + storage->array[id - 1].data = SDL_const_cast(void *, value); + storage->array[id - 1].destructor = destructor; return 0; } -static void -SDL_TLSCleanup() +void SDL_TLSCleanup(void) { SDL_TLSData *storage; @@ -101,7 +95,6 @@ SDL_TLSCleanup() } } - /* This is a generic implementation of thread-local storage which doesn't require additional OS support. @@ -110,7 +103,8 @@ SDL_TLSCleanup() storage this implementation should be improved to be production quality. */ -typedef struct SDL_TLSEntry { +typedef struct SDL_TLSEntry +{ SDL_threadID thread; SDL_TLSData *storage; struct SDL_TLSEntry *next; @@ -119,15 +113,13 @@ typedef struct SDL_TLSEntry { static SDL_mutex *SDL_generic_TLS_mutex; static SDL_TLSEntry *SDL_generic_TLS; - -SDL_TLSData * -SDL_Generic_GetTLSData(void) +SDL_TLSData *SDL_Generic_GetTLSData(void) { SDL_threadID thread = SDL_ThreadID(); SDL_TLSEntry *entry; SDL_TLSData *storage = NULL; -#if !SDL_THREADS_DISABLED +#ifndef SDL_THREADS_DISABLED if (!SDL_generic_TLS_mutex) { static SDL_SpinLock tls_lock; SDL_AtomicLock(&tls_lock); @@ -142,25 +134,24 @@ SDL_Generic_GetTLSData(void) } SDL_AtomicUnlock(&tls_lock); } -#endif /* SDL_THREADS_DISABLED */ - SDL_MemoryBarrierAcquire(); SDL_LockMutex(SDL_generic_TLS_mutex); +#endif /* SDL_THREADS_DISABLED */ + for (entry = SDL_generic_TLS; entry; entry = entry->next) { if (entry->thread == thread) { storage = entry->storage; break; } } -#if !SDL_THREADS_DISABLED +#ifndef SDL_THREADS_DISABLED SDL_UnlockMutex(SDL_generic_TLS_mutex); #endif return storage; } -int -SDL_Generic_SetTLSData(SDL_TLSData *storage) +int SDL_Generic_SetTLSData(SDL_TLSData *data) { SDL_threadID thread = SDL_ThreadID(); SDL_TLSEntry *prev, *entry; @@ -170,8 +161,8 @@ SDL_Generic_SetTLSData(SDL_TLSData *storage) prev = NULL; for (entry = SDL_generic_TLS; entry; entry = entry->next) { if (entry->thread == thread) { - if (storage) { - entry->storage = storage; + if (data) { + entry->storage = data; } else { if (prev) { prev->next = entry->next; @@ -188,7 +179,7 @@ SDL_Generic_SetTLSData(SDL_TLSData *storage) entry = (SDL_TLSEntry *)SDL_malloc(sizeof(*entry)); if (entry) { entry->thread = thread; - entry->storage = storage; + entry->storage = data; entry->next = SDL_generic_TLS; SDL_generic_TLS = entry; } @@ -201,19 +192,37 @@ SDL_Generic_SetTLSData(SDL_TLSData *storage) return 0; } -/* Routine to get the thread-specific error variable */ -SDL_error * -SDL_GetErrBuf(void) +/* Non-thread-safe global error variable */ +static SDL_error *SDL_GetStaticErrBuf(void) { -#if SDL_THREADS_DISABLED - /* Non-thread-safe global error variable */ static SDL_error SDL_global_error; + static char SDL_global_error_str[128]; + SDL_global_error.str = SDL_global_error_str; + SDL_global_error.len = sizeof(SDL_global_error_str); return &SDL_global_error; +} + +#ifndef SDL_THREADS_DISABLED +static void SDLCALL SDL_FreeErrBuf(void *data) +{ + SDL_error *errbuf = (SDL_error *)data; + + if (errbuf->str) { + errbuf->free_func(errbuf->str); + } + errbuf->free_func(errbuf); +} +#endif + +/* Routine to get the thread-specific error variable */ +SDL_error *SDL_GetErrBuf(void) +{ +#ifdef SDL_THREADS_DISABLED + return SDL_GetStaticErrBuf(); #else static SDL_SpinLock tls_lock; static SDL_bool tls_being_created; static SDL_TLSID tls_errbuf; - static SDL_error SDL_global_errbuf; const SDL_error *ALLOCATION_IN_PROGRESS = (SDL_error *)-1; SDL_error *errbuf; @@ -234,46 +243,43 @@ SDL_GetErrBuf(void) SDL_AtomicUnlock(&tls_lock); } if (!tls_errbuf) { - return &SDL_global_errbuf; + return SDL_GetStaticErrBuf(); } SDL_MemoryBarrierAcquire(); errbuf = (SDL_error *)SDL_TLSGet(tls_errbuf); if (errbuf == ALLOCATION_IN_PROGRESS) { - return &SDL_global_errbuf; + return SDL_GetStaticErrBuf(); } if (!errbuf) { + /* Get the original memory functions for this allocation because the lifetime + * of the error buffer may span calls to SDL_SetMemoryFunctions() by the app + */ + SDL_realloc_func realloc_func; + SDL_free_func free_func; + SDL_GetOriginalMemoryFunctions(NULL, NULL, &realloc_func, &free_func); + /* Mark that we're in the middle of allocating our buffer */ SDL_TLSSet(tls_errbuf, ALLOCATION_IN_PROGRESS, NULL); - errbuf = (SDL_error *)SDL_malloc(sizeof(*errbuf)); + errbuf = (SDL_error *)realloc_func(NULL, sizeof(*errbuf)); if (!errbuf) { SDL_TLSSet(tls_errbuf, NULL, NULL); - return &SDL_global_errbuf; + return SDL_GetStaticErrBuf(); } SDL_zerop(errbuf); - SDL_TLSSet(tls_errbuf, errbuf, SDL_free); + errbuf->realloc_func = realloc_func; + errbuf->free_func = free_func; + SDL_TLSSet(tls_errbuf, errbuf, SDL_FreeErrBuf); } return errbuf; #endif /* SDL_THREADS_DISABLED */ } - -/* Arguments and callback to setup and run the user thread function */ -typedef struct +void SDL_RunThread(SDL_Thread *thread) { - int (SDLCALL * func) (void *); - void *data; - SDL_Thread *info; - SDL_sem *wait; -} thread_args; + void *userdata = thread->userdata; + int(SDLCALL * userfunc)(void *) = thread->userfunc; -void -SDL_RunThread(void *data) -{ - thread_args *args = (thread_args *) data; - int (SDLCALL * userfunc) (void *) = args->func; - void *userdata = args->data; - SDL_Thread *thread = args->info; int *statusloc = &thread->status; /* Perform any system-dependent setup - this function may not fail */ @@ -282,9 +288,6 @@ SDL_RunThread(void *data) /* Get the thread id */ thread->threadid = SDL_ThreadID(); - /* Wake up the parent thread */ - SDL_SemPost(args->wait); - /* Run the function */ *statusloc = userfunc(userdata); @@ -308,104 +311,70 @@ SDL_RunThread(void *data) #undef SDL_CreateThreadWithStackSize #endif #if SDL_DYNAMIC_API -#define SDL_CreateThread SDL_CreateThread_REAL +#define SDL_CreateThread SDL_CreateThread_REAL #define SDL_CreateThreadWithStackSize SDL_CreateThreadWithStackSize_REAL #endif #ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD -SDL_Thread * -SDL_CreateThreadWithStackSize(int (SDLCALL * fn) (void *), - const char *name, const size_t stacksize, void *data, - pfnSDL_CurrentBeginThread pfnBeginThread, - pfnSDL_CurrentEndThread pfnEndThread) +SDL_Thread *SDL_CreateThreadWithStackSize(int(SDLCALL *fn)(void *), + const char *name, const size_t stacksize, void *data, + pfnSDL_CurrentBeginThread pfnBeginThread, + pfnSDL_CurrentEndThread pfnEndThread) #else -SDL_Thread * -SDL_CreateThreadWithStackSize(int (SDLCALL * fn) (void *), - const char *name, const size_t stacksize, void *data) +SDL_Thread *SDL_CreateThreadWithStackSize(int(SDLCALL *fn)(void *), + const char *name, const size_t stacksize, void *data) #endif { SDL_Thread *thread; - thread_args *args; int ret; /* Allocate memory for the thread info structure */ - thread = (SDL_Thread *) SDL_malloc(sizeof(*thread)); - if (thread == NULL) { + thread = (SDL_Thread *)SDL_calloc(1, sizeof(*thread)); + if (!thread) { SDL_OutOfMemory(); - return (NULL); + return NULL; } - SDL_zerop(thread); thread->status = -1; SDL_AtomicSet(&thread->state, SDL_THREAD_STATE_ALIVE); /* Set up the arguments for the thread */ - if (name != NULL) { + if (name) { thread->name = SDL_strdup(name); - if (thread->name == NULL) { + if (!thread->name) { SDL_OutOfMemory(); SDL_free(thread); - return (NULL); + return NULL; } } - /* Set up the arguments for the thread */ - args = (thread_args *) SDL_malloc(sizeof(*args)); - if (args == NULL) { - SDL_OutOfMemory(); - if (thread->name) { - SDL_free(thread->name); - } - SDL_free(thread); - return (NULL); - } - args->func = fn; - args->data = data; - args->info = thread; - args->wait = SDL_CreateSemaphore(0); - if (args->wait == NULL) { - if (thread->name) { - SDL_free(thread->name); - } - SDL_free(thread); - SDL_free(args); - return (NULL); - } - + thread->userfunc = fn; + thread->userdata = data; thread->stacksize = stacksize; /* Create the thread and go! */ #ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD - ret = SDL_SYS_CreateThread(thread, args, pfnBeginThread, pfnEndThread); + ret = SDL_SYS_CreateThread(thread, pfnBeginThread, pfnEndThread); #else - ret = SDL_SYS_CreateThread(thread, args); + ret = SDL_SYS_CreateThread(thread); #endif - if (ret >= 0) { - /* Wait for the thread function to use arguments */ - SDL_SemWait(args->wait); - } else { + if (ret < 0) { /* Oops, failed. Gotta free everything */ - if (thread->name) { - SDL_free(thread->name); - } + SDL_free(thread->name); SDL_free(thread); thread = NULL; } - SDL_DestroySemaphore(args->wait); - SDL_free(args); /* Everything is running now */ - return (thread); + return thread; } #ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD -DECLSPEC SDL_Thread *SDLCALL -SDL_CreateThread(int (SDLCALL * fn) (void *), +DECLSPEC SDL_Thread *SDLCALL SDL_CreateThread(int(SDLCALL *fn)(void *), const char *name, void *data, pfnSDL_CurrentBeginThread pfnBeginThread, pfnSDL_CurrentEndThread pfnEndThread) #else -DECLSPEC SDL_Thread *SDLCALL -SDL_CreateThread(int (SDLCALL * fn) (void *), +DECLSPEC SDL_Thread *SDLCALL SDL_CreateThread(int(SDLCALL *fn)(void *), const char *name, void *data) #endif { @@ -414,12 +383,12 @@ SDL_CreateThread(int (SDLCALL * fn) (void *), size_t stacksize = 0; /* If the SDL_HINT_THREAD_STACK_SIZE exists, use it */ - if (stackhint != NULL) { + if (stackhint) { char *endp = NULL; const Sint64 hintval = SDL_strtoll(stackhint, &endp, 10); - if ((*stackhint != '\0') && (*endp == '\0')) { /* a valid number? */ - if (hintval > 0) { /* reject bogus values. */ - stacksize = (size_t) hintval; + if ((*stackhint != '\0') && (*endp == '\0')) { /* a valid number? */ + if (hintval > 0) { /* reject bogus values. */ + stacksize = (size_t)hintval; } } } @@ -431,9 +400,9 @@ SDL_CreateThread(int (SDLCALL * fn) (void *), #endif } -SDL_Thread * -SDL_CreateThreadInternal(int (SDLCALL * fn) (void *), const char *name, - const size_t stacksize, void *data) { +SDL_Thread *SDL_CreateThreadInternal(int(SDLCALL *fn)(void *), const char *name, + const size_t stacksize, void *data) +{ #ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD return SDL_CreateThreadWithStackSize(fn, name, stacksize, data, NULL, NULL); #else @@ -441,8 +410,7 @@ SDL_CreateThreadInternal(int (SDLCALL * fn) (void *), const char *name, #endif } -SDL_threadID -SDL_GetThreadID(SDL_Thread * thread) +SDL_threadID SDL_GetThreadID(SDL_Thread *thread) { SDL_threadID id; @@ -454,8 +422,7 @@ SDL_GetThreadID(SDL_Thread * thread) return id; } -const char * -SDL_GetThreadName(SDL_Thread * thread) +const char *SDL_GetThreadName(SDL_Thread *thread) { if (thread) { return thread->name; @@ -464,14 +431,12 @@ SDL_GetThreadName(SDL_Thread * thread) } } -int -SDL_SetThreadPriority(SDL_ThreadPriority priority) +int SDL_SetThreadPriority(SDL_ThreadPriority priority) { return SDL_SYS_SetThreadPriority(priority); } -void -SDL_WaitThread(SDL_Thread * thread, int *status) +void SDL_WaitThread(SDL_Thread *thread, int *status) { if (thread) { SDL_SYS_WaitThread(thread); @@ -485,8 +450,7 @@ SDL_WaitThread(SDL_Thread * thread, int *status) } } -void -SDL_DetachThread(SDL_Thread * thread) +void SDL_DetachThread(SDL_Thread *thread) { if (!thread) { return; @@ -499,9 +463,9 @@ SDL_DetachThread(SDL_Thread * thread) /* all other states are pretty final, see where we landed. */ const int thread_state = SDL_AtomicGet(&thread->state); if ((thread_state == SDL_THREAD_STATE_DETACHED) || (thread_state == SDL_THREAD_STATE_CLEANED)) { - return; /* already detached (you shouldn't call this twice!) */ + return; /* already detached (you shouldn't call this twice!) */ } else if (thread_state == SDL_THREAD_STATE_ZOMBIE) { - SDL_WaitThread(thread, NULL); /* already done, clean it up. */ + SDL_WaitThread(thread, NULL); /* already done, clean it up. */ } else { SDL_assert(0 && "Unexpected thread state"); } diff --git a/SDL2-2.0.12/src/thread/SDL_thread_c.h b/SDL2-2.30.5/src/thread/SDL_thread_c.h similarity index 73% rename from SDL2-2.0.12/src/thread/SDL_thread_c.h rename to SDL2-2.30.5/src/thread/SDL_thread_c.h index 9cc52af..985a519 100644 --- a/SDL2-2.0.12/src/thread/SDL_thread_c.h +++ b/SDL2-2.30.5/src/thread/SDL_thread_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,16 +26,26 @@ #include "SDL_thread.h" /* Need the definitions of SYS_ThreadHandle */ -#if SDL_THREADS_DISABLED +#ifdef SDL_THREADS_DISABLED #include "generic/SDL_systhread_c.h" -#elif SDL_THREAD_PTHREAD +#elif defined(SDL_THREAD_PTHREAD) #include "pthread/SDL_systhread_c.h" -#elif SDL_THREAD_WINDOWS +#elif defined(SDL_THREAD_WINDOWS) #include "windows/SDL_systhread_c.h" -#elif SDL_THREAD_PSP +#elif defined(SDL_THREAD_PS2) +#include "ps2/SDL_systhread_c.h" +#elif defined(SDL_THREAD_PSP) #include "psp/SDL_systhread_c.h" -#elif SDL_THREAD_STDCPP +#elif defined(SDL_THREAD_VITA) +#include "vita/SDL_systhread_c.h" +#elif defined(SDL_THREAD_N3DS) +#include "n3ds/SDL_systhread_c.h" +#elif defined(SDL_THREAD_STDCPP) #include "stdcpp/SDL_systhread_c.h" +#elif defined(SDL_THREAD_OS2) +#include "os2/SDL_systhread_c.h" +#elif defined(SDL_THREAD_NGAGE) +#include "ngage/SDL_systhread_c.h" #else #error Need thread implementation for this platform #include "generic/SDL_systhread_c.h" @@ -56,22 +66,27 @@ struct SDL_Thread SDL_threadID threadid; SYS_ThreadHandle handle; int status; - SDL_atomic_t state; /* SDL_THREAD_STATE_* */ + SDL_atomic_t state; /* SDL_THREAD_STATE_* */ SDL_error errbuf; char *name; - size_t stacksize; /* 0 for default, >0 for user-specified stack size. */ + size_t stacksize; /* 0 for default, >0 for user-specified stack size. */ + int(SDLCALL *userfunc)(void *); + void *userdata; void *data; + void *endfunc; /* only used on some platforms. */ }; /* This is the function called to run a thread */ -extern void SDL_RunThread(void *data); +extern void SDL_RunThread(SDL_Thread *thread); /* This is the system-independent thread local storage structure */ -typedef struct { +typedef struct +{ unsigned int limit; - struct { + struct + { void *data; - void (SDLCALL *destructor)(void*); + void(SDLCALL *destructor)(void *); } array[1]; } SDL_TLSData; diff --git a/SDL2-2.0.12/src/thread/generic/SDL_syscond.c b/SDL2-2.30.5/src/thread/generic/SDL_syscond.c similarity index 77% rename from SDL2-2.0.12/src/thread/generic/SDL_syscond.c rename to SDL2-2.30.5/src/thread/generic/SDL_syscond.c index 5cd9745..ebd0412 100644 --- a/SDL2-2.0.12/src/thread/generic/SDL_syscond.c +++ b/SDL2-2.30.5/src/thread/generic/SDL_syscond.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -28,41 +28,55 @@ #include "SDL_thread.h" -struct SDL_cond +#include "../generic/SDL_syscond_c.h" + +/* If two implementations are to be compiled into SDL (the active one + * will be chosen at runtime), the function names need to be + * suffixed + */ +#ifndef SDL_THREAD_GENERIC_COND_SUFFIX +#define SDL_CreateCond_generic SDL_CreateCond +#define SDL_DestroyCond_generic SDL_DestroyCond +#define SDL_CondSignal_generic SDL_CondSignal +#define SDL_CondBroadcast_generic SDL_CondBroadcast +#define SDL_CondWait_generic SDL_CondWait +#define SDL_CondWaitTimeout_generic SDL_CondWaitTimeout +#endif + +typedef struct SDL_cond_generic { SDL_mutex *lock; int waiting; int signals; SDL_sem *wait_sem; SDL_sem *wait_done; -}; +} SDL_cond_generic; /* Create a condition variable */ -SDL_cond * -SDL_CreateCond(void) +SDL_cond *SDL_CreateCond_generic(void) { - SDL_cond *cond; + SDL_cond_generic *cond; - cond = (SDL_cond *) SDL_malloc(sizeof(SDL_cond)); + cond = (SDL_cond_generic *)SDL_malloc(sizeof(SDL_cond_generic)); if (cond) { cond->lock = SDL_CreateMutex(); cond->wait_sem = SDL_CreateSemaphore(0); cond->wait_done = SDL_CreateSemaphore(0); cond->waiting = cond->signals = 0; if (!cond->lock || !cond->wait_sem || !cond->wait_done) { - SDL_DestroyCond(cond); + SDL_DestroyCond_generic((SDL_cond *)cond); cond = NULL; } } else { SDL_OutOfMemory(); } - return (cond); + return (SDL_cond *)cond; } /* Destroy a condition variable */ -void -SDL_DestroyCond(SDL_cond * cond) +void SDL_DestroyCond_generic(SDL_cond *_cond) { + SDL_cond_generic *cond = (SDL_cond_generic *)_cond; if (cond) { if (cond->wait_sem) { SDL_DestroySemaphore(cond->wait_sem); @@ -78,11 +92,11 @@ SDL_DestroyCond(SDL_cond * cond) } /* Restart one of the threads that are waiting on the condition variable */ -int -SDL_CondSignal(SDL_cond * cond) +int SDL_CondSignal_generic(SDL_cond *_cond) { + SDL_cond_generic *cond = (SDL_cond_generic *)_cond; if (!cond) { - return SDL_SetError("Passed a NULL condition variable"); + return SDL_InvalidParamError("cond"); } /* If there are waiting threads not already signalled, then @@ -102,11 +116,11 @@ SDL_CondSignal(SDL_cond * cond) } /* Restart all threads that are waiting on the condition variable */ -int -SDL_CondBroadcast(SDL_cond * cond) +int SDL_CondBroadcast_generic(SDL_cond *_cond) { + SDL_cond_generic *cond = (SDL_cond_generic *)_cond; if (!cond) { - return SDL_SetError("Passed a NULL condition variable"); + return SDL_InvalidParamError("cond"); } /* If there are waiting threads not already signalled, then @@ -156,13 +170,13 @@ Thread B: SDL_CondSignal(cond); SDL_UnlockMutex(lock); */ -int -SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms) +int SDL_CondWaitTimeout_generic(SDL_cond *_cond, SDL_mutex *mutex, Uint32 ms) { + SDL_cond_generic *cond = (SDL_cond_generic *)_cond; int retval; if (!cond) { - return SDL_SetError("Passed a NULL condition variable"); + return SDL_InvalidParamError("cond"); } /* Obtain the protection mutex, and increment the number of waiters. @@ -211,10 +225,9 @@ SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms) } /* Wait on the condition variable forever */ -int -SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex) +int SDL_CondWait_generic(SDL_cond *cond, SDL_mutex *mutex) { - return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT); + return SDL_CondWaitTimeout_generic(cond, mutex, SDL_MUTEX_MAXWAIT); } /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/thread/generic/SDL_syscond_c.h b/SDL2-2.30.5/src/thread/generic/SDL_syscond_c.h new file mode 100644 index 0000000..64aaf41 --- /dev/null +++ b/SDL2-2.30.5/src/thread/generic/SDL_syscond_c.h @@ -0,0 +1,42 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_thread.h" + +#ifndef SDL_syscond_generic_h_ +#define SDL_syscond_generic_h_ + +#ifdef SDL_THREAD_GENERIC_COND_SUFFIX + +SDL_cond *SDL_CreateCond_generic(void); +void SDL_DestroyCond_generic(SDL_cond *cond); +int SDL_CondSignal_generic(SDL_cond *cond); +int SDL_CondBroadcast_generic(SDL_cond *cond); +int SDL_CondWait_generic(SDL_cond *cond, SDL_mutex *mutex); +int SDL_CondWaitTimeout_generic(SDL_cond *cond, + SDL_mutex *mutex, Uint32 ms); + +#endif /* SDL_THREAD_GENERIC_COND_SUFFIX */ + +#endif /* SDL_syscond_generic_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/thread/generic/SDL_sysmutex.c b/SDL2-2.30.5/src/thread/generic/SDL_sysmutex.c similarity index 84% rename from SDL2-2.0.12/src/thread/generic/SDL_sysmutex.c rename to SDL2-2.30.5/src/thread/generic/SDL_sysmutex.c index d3af9c5..f9fc4e4 100644 --- a/SDL2-2.0.12/src/thread/generic/SDL_sysmutex.c +++ b/SDL2-2.30.5/src/thread/generic/SDL_sysmutex.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -25,7 +25,6 @@ #include "SDL_thread.h" #include "SDL_systhread_c.h" - struct SDL_mutex { int recursive; @@ -34,13 +33,14 @@ struct SDL_mutex }; /* Create a mutex */ -SDL_mutex * -SDL_CreateMutex(void) +SDL_mutex *SDL_CreateMutex(void) { SDL_mutex *mutex; /* Allocate mutex memory */ - mutex = (SDL_mutex *) SDL_malloc(sizeof(*mutex)); + mutex = (SDL_mutex *)SDL_calloc(1, sizeof(*mutex)); + +#ifndef SDL_THREADS_DISABLED if (mutex) { /* Create the mutex semaphore, with initial value 1 */ mutex->sem = SDL_CreateSemaphore(1); @@ -53,12 +53,13 @@ SDL_CreateMutex(void) } else { SDL_OutOfMemory(); } +#endif /* !SDL_THREADS_DISABLED */ + return mutex; } /* Free the mutex */ -void -SDL_DestroyMutex(SDL_mutex * mutex) +void SDL_DestroyMutex(SDL_mutex *mutex) { if (mutex) { if (mutex->sem) { @@ -69,16 +70,15 @@ SDL_DestroyMutex(SDL_mutex * mutex) } /* Lock the mutex */ -int -SDL_LockMutex(SDL_mutex * mutex) +int SDL_LockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */ { -#if SDL_THREADS_DISABLED +#ifdef SDL_THREADS_DISABLED return 0; #else SDL_threadID this_thread; if (mutex == NULL) { - return SDL_SetError("Passed a NULL mutex"); + return 0; } this_thread = SDL_ThreadID(); @@ -99,17 +99,16 @@ SDL_LockMutex(SDL_mutex * mutex) } /* try Lock the mutex */ -int -SDL_TryLockMutex(SDL_mutex * mutex) +int SDL_TryLockMutex(SDL_mutex *mutex) { -#if SDL_THREADS_DISABLED +#ifdef SDL_THREADS_DISABLED return 0; #else int retval = 0; SDL_threadID this_thread; - if (mutex == NULL) { - return SDL_SetError("Passed a NULL mutex"); + if (!mutex) { + return 0; } this_thread = SDL_ThreadID(); @@ -132,14 +131,13 @@ SDL_TryLockMutex(SDL_mutex * mutex) } /* Unlock the mutex */ -int -SDL_mutexV(SDL_mutex * mutex) +int SDL_UnlockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */ { -#if SDL_THREADS_DISABLED +#ifdef SDL_THREADS_DISABLED return 0; #else if (mutex == NULL) { - return SDL_SetError("Passed a NULL mutex"); + return 0; } /* If we don't own the mutex, we can't unlock it */ diff --git a/SDL2-2.0.12/src/thread/psp/SDL_sysmutex_c.h b/SDL2-2.30.5/src/thread/generic/SDL_sysmutex_c.h similarity index 94% rename from SDL2-2.0.12/src/thread/psp/SDL_sysmutex_c.h rename to SDL2-2.30.5/src/thread/generic/SDL_sysmutex_c.h index 2f88359..886ce23 100644 --- a/SDL2-2.0.12/src/thread/psp/SDL_sysmutex_c.h +++ b/SDL2-2.30.5/src/thread/generic/SDL_sysmutex_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/thread/generic/SDL_syssem.c b/SDL2-2.30.5/src/thread/generic/SDL_syssem.c similarity index 81% rename from SDL2-2.0.12/src/thread/generic/SDL_syssem.c rename to SDL2-2.30.5/src/thread/generic/SDL_syssem.c index 027d54e..8b835b0 100644 --- a/SDL2-2.0.12/src/thread/generic/SDL_syssem.c +++ b/SDL2-2.30.5/src/thread/generic/SDL_syssem.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,47 +26,39 @@ #include "SDL_thread.h" #include "SDL_systhread_c.h" +#ifdef SDL_THREADS_DISABLED -#if SDL_THREADS_DISABLED - -SDL_sem * -SDL_CreateSemaphore(Uint32 initial_value) +SDL_sem *SDL_CreateSemaphore(Uint32 initial_value) { SDL_SetError("SDL not built with thread support"); - return (SDL_sem *) 0; + return (SDL_sem *)0; } -void -SDL_DestroySemaphore(SDL_sem * sem) +void SDL_DestroySemaphore(SDL_sem *sem) { } -int -SDL_SemTryWait(SDL_sem * sem) +int SDL_SemTryWait(SDL_sem *sem) { return SDL_SetError("SDL not built with thread support"); } -int -SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout) +int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) { return SDL_SetError("SDL not built with thread support"); } -int -SDL_SemWait(SDL_sem * sem) +int SDL_SemWait(SDL_sem *sem) { return SDL_SetError("SDL not built with thread support"); } -Uint32 -SDL_SemValue(SDL_sem * sem) +Uint32 SDL_SemValue(SDL_sem *sem) { return 0; } -int -SDL_SemPost(SDL_sem * sem) +int SDL_SemPost(SDL_sem *sem) { return SDL_SetError("SDL not built with thread support"); } @@ -81,12 +73,11 @@ struct SDL_semaphore SDL_cond *count_nonzero; }; -SDL_sem * -SDL_CreateSemaphore(Uint32 initial_value) +SDL_sem *SDL_CreateSemaphore(Uint32 initial_value) { SDL_sem *sem; - sem = (SDL_sem *) SDL_malloc(sizeof(*sem)); + sem = (SDL_sem *)SDL_malloc(sizeof(*sem)); if (!sem) { SDL_OutOfMemory(); return NULL; @@ -107,8 +98,7 @@ SDL_CreateSemaphore(Uint32 initial_value) /* WARNING: You cannot call this function when another thread is using the semaphore. */ -void -SDL_DestroySemaphore(SDL_sem * sem) +void SDL_DestroySemaphore(SDL_sem *sem) { if (sem) { sem->count = 0xFFFFFFFF; @@ -126,13 +116,12 @@ SDL_DestroySemaphore(SDL_sem * sem) } } -int -SDL_SemTryWait(SDL_sem * sem) +int SDL_SemTryWait(SDL_sem *sem) { int retval; if (!sem) { - return SDL_SetError("Passed a NULL semaphore"); + return SDL_InvalidParamError("sem"); } retval = SDL_MUTEX_TIMEDOUT; @@ -146,13 +135,12 @@ SDL_SemTryWait(SDL_sem * sem) return retval; } -int -SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout) +int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) { int retval; if (!sem) { - return SDL_SetError("Passed a NULL semaphore"); + return SDL_InvalidParamError("sem"); } /* A timeout of 0 is an easy case */ @@ -176,14 +164,12 @@ SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout) return retval; } -int -SDL_SemWait(SDL_sem * sem) +int SDL_SemWait(SDL_sem *sem) { return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT); } -Uint32 -SDL_SemValue(SDL_sem * sem) +Uint32 SDL_SemValue(SDL_sem *sem) { Uint32 value; @@ -196,11 +182,10 @@ SDL_SemValue(SDL_sem * sem) return value; } -int -SDL_SemPost(SDL_sem * sem) +int SDL_SemPost(SDL_sem *sem) { if (!sem) { - return SDL_SetError("Passed a NULL semaphore"); + return SDL_InvalidParamError("sem"); } SDL_LockMutex(sem->count_lock); diff --git a/SDL2-2.0.12/src/thread/generic/SDL_systhread.c b/SDL2-2.30.5/src/thread/generic/SDL_systhread.c similarity index 69% rename from SDL2-2.0.12/src/thread/generic/SDL_systhread.c rename to SDL2-2.30.5/src/thread/generic/SDL_systhread.c index fcba8d6..b3a33f7 100644 --- a/SDL2-2.0.12/src/thread/generic/SDL_systhread.c +++ b/SDL2-2.30.5/src/thread/generic/SDL_systhread.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,44 +26,37 @@ #include "../SDL_systhread.h" #ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD -int -SDL_SYS_CreateThread(SDL_Thread * thread, void *args, - pfnSDL_CurrentBeginThread pfnBeginThread, - pfnSDL_CurrentEndThread pfnEndThread) +int SDL_SYS_CreateThread(SDL_Thread *thread, + pfnSDL_CurrentBeginThread pfnBeginThread, + pfnSDL_CurrentEndThread pfnEndThread) #else -int -SDL_SYS_CreateThread(SDL_Thread * thread, void *args) +int SDL_SYS_CreateThread(SDL_Thread *thread) #endif /* SDL_PASSED_BEGINTHREAD_ENDTHREAD */ { return SDL_SetError("Threads are not supported on this platform"); } -void -SDL_SYS_SetupThread(const char *name) +void SDL_SYS_SetupThread(const char *name) { return; } -SDL_threadID -SDL_ThreadID(void) +SDL_threadID SDL_ThreadID(void) { - return (0); + return 0; } -int -SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority) +int SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority) { - return (0); + return 0; } -void -SDL_SYS_WaitThread(SDL_Thread * thread) +void SDL_SYS_WaitThread(SDL_Thread *thread) { return; } -void -SDL_SYS_DetachThread(SDL_Thread * thread) +void SDL_SYS_DetachThread(SDL_Thread *thread) { return; } diff --git a/SDL2-2.0.12/src/thread/generic/SDL_systhread_c.h b/SDL2-2.30.5/src/thread/generic/SDL_systhread_c.h similarity index 94% rename from SDL2-2.0.12/src/thread/generic/SDL_systhread_c.h rename to SDL2-2.30.5/src/thread/generic/SDL_systhread_c.h index 53cb82e..800b333 100644 --- a/SDL2-2.0.12/src/thread/generic/SDL_systhread_c.h +++ b/SDL2-2.30.5/src/thread/generic/SDL_systhread_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/thread/generic/SDL_systls.c b/SDL2-2.30.5/src/thread/generic/SDL_systls.c similarity index 88% rename from SDL2-2.0.12/src/thread/generic/SDL_systls.c rename to SDL2-2.30.5/src/thread/generic/SDL_systls.c index b814b9b..1d100e0 100644 --- a/SDL2-2.0.12/src/thread/generic/SDL_systls.c +++ b/SDL2-2.30.5/src/thread/generic/SDL_systls.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -22,15 +22,12 @@ #include "../../SDL_internal.h" #include "../SDL_thread_c.h" - -SDL_TLSData * -SDL_SYS_GetTLSData(void) +SDL_TLSData *SDL_SYS_GetTLSData(void) { return SDL_Generic_GetTLSData(); } -int -SDL_SYS_SetTLSData(SDL_TLSData *data) +int SDL_SYS_SetTLSData(SDL_TLSData *data) { return SDL_Generic_SetTLSData(data); } diff --git a/SDL2-2.30.5/src/thread/n3ds/SDL_syscond.c b/SDL2-2.30.5/src/thread/n3ds/SDL_syscond.c new file mode 100644 index 0000000..c5eae40 --- /dev/null +++ b/SDL2-2.30.5/src/thread/n3ds/SDL_syscond.c @@ -0,0 +1,127 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_THREAD_N3DS + +/* An implementation of condition variables using libctru's CondVar */ + +#include "SDL_sysmutex_c.h" + +struct SDL_cond +{ + CondVar cond_variable; +}; + +/* Create a condition variable */ +SDL_cond *SDL_CreateCond(void) +{ + SDL_cond *cond = (SDL_cond *)SDL_malloc(sizeof(SDL_cond)); + if (cond) { + CondVar_Init(&cond->cond_variable); + } else { + SDL_OutOfMemory(); + } + return cond; +} + +/* Destroy a condition variable */ +void SDL_DestroyCond(SDL_cond *cond) +{ + if (cond) { + SDL_free(cond); + } +} + +/* Restart one of the threads that are waiting on the condition variable */ +int SDL_CondSignal(SDL_cond *cond) +{ + if (!cond) { + return SDL_InvalidParamError("cond"); + } + + CondVar_Signal(&cond->cond_variable); + return 0; +} + +/* Restart all threads that are waiting on the condition variable */ +int SDL_CondBroadcast(SDL_cond *cond) +{ + if (!cond) { + return SDL_InvalidParamError("cond"); + } + + CondVar_Broadcast(&cond->cond_variable); + return 0; +} + +/* Wait on the condition variable for at most 'ms' milliseconds. + The mutex must be locked before entering this function! + The mutex is unlocked during the wait, and locked again after the wait. + +Typical use: + +Thread A: + SDL_LockMutex(lock); + while ( ! condition ) { + SDL_CondWait(cond, lock); + } + SDL_UnlockMutex(lock); + +Thread B: + SDL_LockMutex(lock); + ... + condition = true; + ... + SDL_CondSignal(cond); + SDL_UnlockMutex(lock); + */ +int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms) +{ + Result res; + + if (!cond) { + return SDL_InvalidParamError("cond"); + } + if (!mutex) { + return SDL_InvalidParamError("mutex"); + } + + res = 0; + if (ms == SDL_MUTEX_MAXWAIT) { + CondVar_Wait(&cond->cond_variable, &mutex->lock.lock); + } else { + res = CondVar_WaitTimeout(&cond->cond_variable, &mutex->lock.lock, + (s64)ms * 1000000LL); + } + + return R_SUCCEEDED(res) ? 0 : SDL_MUTEX_TIMEDOUT; +} + +/* Wait on the condition variable forever */ +int SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex) +{ + return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT); +} + +#endif /* SDL_THREAD_N3DS */ + +/* vi: set sts=4 ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/thread/n3ds/SDL_sysmutex.c b/SDL2-2.30.5/src/thread/n3ds/SDL_sysmutex.c new file mode 100644 index 0000000..71056c2 --- /dev/null +++ b/SDL2-2.30.5/src/thread/n3ds/SDL_sysmutex.c @@ -0,0 +1,88 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_THREAD_N3DS + +/* An implementation of mutexes using libctru's RecursiveLock */ + +#include "SDL_sysmutex_c.h" + +/* Create a mutex */ +SDL_mutex *SDL_CreateMutex(void) +{ + SDL_mutex *mutex; + + /* Allocate mutex memory */ + mutex = (SDL_mutex *)SDL_malloc(sizeof(*mutex)); + if (mutex) { + RecursiveLock_Init(&mutex->lock); + } else { + SDL_OutOfMemory(); + } + return mutex; +} + +/* Free the mutex */ +void SDL_DestroyMutex(SDL_mutex *mutex) +{ + if (mutex) { + SDL_free(mutex); + } +} + +/* Lock the mutex */ +int SDL_LockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */ +{ + if (mutex == NULL) { + return 0; + } + + RecursiveLock_Lock(&mutex->lock); + + return 0; +} + +/* try Lock the mutex */ +int SDL_TryLockMutex(SDL_mutex *mutex) +{ + if (!mutex) { + return 0; + } + + return RecursiveLock_TryLock(&mutex->lock); +} + +/* Unlock the mutex */ +int SDL_UnlockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */ +{ + if (mutex == NULL) { + return 0; + } + + RecursiveLock_Unlock(&mutex->lock); + + return 0; +} + +#endif /* SDL_THREAD_N3DS */ + +/* vi: set sts=4 ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/thread/n3ds/SDL_sysmutex_c.h b/SDL2-2.30.5/src/thread/n3ds/SDL_sysmutex_c.h new file mode 100644 index 0000000..4a3e7e9 --- /dev/null +++ b/SDL2-2.30.5/src/thread/n3ds/SDL_sysmutex_c.h @@ -0,0 +1,37 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifndef SDL_sysmutex_c_h_ +#define SDL_sysmutex_c_h_ + +#include <3ds.h> + +#include "SDL_mutex.h" + +struct SDL_mutex +{ + RecursiveLock lock; +}; + +#endif /* SDL_sysmutex_c_h */ + +/* vi: set sts=4 ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/thread/n3ds/SDL_syssem.c b/SDL2-2.30.5/src/thread/n3ds/SDL_syssem.c new file mode 100644 index 0000000..45e5305 --- /dev/null +++ b/SDL2-2.30.5/src/thread/n3ds/SDL_syssem.c @@ -0,0 +1,143 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_THREAD_N3DS + +/* An implementation of semaphores using libctru's LightSemaphore */ + +#include <3ds.h> + +#include "SDL_thread.h" +#include "SDL_timer.h" + +int WaitOnSemaphoreFor(SDL_sem *sem, Uint32 timeout); + +struct SDL_semaphore +{ + LightSemaphore semaphore; +}; + +SDL_sem *SDL_CreateSemaphore(Uint32 initial_value) +{ + SDL_sem *sem; + + if (initial_value > SDL_MAX_SINT16) { + SDL_SetError("Initial semaphore value too high for this platform"); + return NULL; + } + + sem = (SDL_sem *)SDL_malloc(sizeof(*sem)); + if (!sem) { + SDL_OutOfMemory(); + return NULL; + } + + LightSemaphore_Init(&sem->semaphore, initial_value, SDL_MAX_SINT16); + + return sem; +} + +/* WARNING: + You cannot call this function when another thread is using the semaphore. +*/ +void SDL_DestroySemaphore(SDL_sem *sem) +{ + SDL_free(sem); +} + +int SDL_SemTryWait(SDL_sem *sem) +{ + if (!sem) { + return SDL_InvalidParamError("sem"); + } + + if (LightSemaphore_TryAcquire(&sem->semaphore, 1) != 0) { + /* If we failed, yield to avoid starvation on busy waits */ + svcSleepThread(1); + return SDL_MUTEX_TIMEDOUT; + } + + return 0; +} + +int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) +{ + if (!sem) { + return SDL_InvalidParamError("sem"); + } + + if (timeout == SDL_MUTEX_MAXWAIT) { + LightSemaphore_Acquire(&sem->semaphore, 1); + return 0; + } + + if (LightSemaphore_TryAcquire(&sem->semaphore, 1) != 0) { + return WaitOnSemaphoreFor(sem, timeout); + } + + return 0; +} + +int WaitOnSemaphoreFor(SDL_sem *sem, Uint32 timeout) +{ + Uint64 stop_time = SDL_GetTicks64() + timeout; + Uint64 current_time = SDL_GetTicks64(); + while (current_time < stop_time) { + if (LightSemaphore_TryAcquire(&sem->semaphore, 1) == 0) { + return 0; + } + /* 100 microseconds seems to be the sweet spot */ + svcSleepThread(100000LL); + current_time = SDL_GetTicks64(); + } + + /* If we failed, yield to avoid starvation on busy waits */ + svcSleepThread(1); + return SDL_MUTEX_TIMEDOUT; +} + +int SDL_SemWait(SDL_sem *sem) +{ + return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT); +} + +Uint32 SDL_SemValue(SDL_sem *sem) +{ + if (!sem) { + SDL_InvalidParamError("sem"); + return 0; + } + return sem->semaphore.current_count; +} + +int SDL_SemPost(SDL_sem *sem) +{ + if (!sem) { + return SDL_InvalidParamError("sem"); + } + LightSemaphore_Release(&sem->semaphore, 1); + return 0; +} + +#endif /* SDL_THREAD_N3DS */ + +/* vi: set sts=4 ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/thread/n3ds/SDL_systhread.c b/SDL2-2.30.5/src/thread/n3ds/SDL_systhread.c new file mode 100644 index 0000000..c15c281 --- /dev/null +++ b/SDL2-2.30.5/src/thread/n3ds/SDL_systhread.c @@ -0,0 +1,139 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_THREAD_N3DS + +/* Thread management routines for SDL */ + +#include "../SDL_systhread.h" + +/* N3DS has very limited RAM (128MB), so we set a low default thread stack size. */ +#define N3DS_THREAD_STACK_SIZE_DEFAULT (80 * 1024) + +#define N3DS_THREAD_PRIORITY_LOW 0x3F /**< Minimum priority */ +#define N3DS_THREAD_PRIORITY_MEDIUM 0x2F /**< Slightly higher than main thread (0x30) */ +#define N3DS_THREAD_PRIORITY_HIGH 0x19 /**< High priority for non-video work */ +#define N3DS_THREAD_PRIORITY_TIME_CRITICAL 0x18 /**< Highest priority */ + +static size_t GetStackSize(size_t requested_size); + +static void ThreadEntry(void *arg) +{ + SDL_RunThread((SDL_Thread *)arg); + threadExit(0); +} + +#ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD +#error "SDL_PASSED_BEGINTHREAD_ENDTHREAD is not supported on N3DS" +#endif + +int SDL_SYS_CreateThread(SDL_Thread *thread) +{ + s32 priority = 0x30; + int cpu = -1; + size_t stack_size = GetStackSize(thread->stacksize); + + svcGetThreadPriority(&priority, CUR_THREAD_HANDLE); + + /* prefer putting audio thread on system core */ + if (thread->name && (SDL_strncmp(thread->name, "SDLAudioP", 9) == 0) && R_SUCCEEDED(APT_SetAppCpuTimeLimit(30))) { + cpu = 1; + } + + thread->handle = threadCreate(ThreadEntry, + thread, + stack_size, + priority, + cpu, + false); + + if (!thread->handle) { + return SDL_SetError("Couldn't create thread"); + } + + return 0; +} + +static size_t GetStackSize(size_t requested_size) +{ + if (requested_size == 0) { + return N3DS_THREAD_STACK_SIZE_DEFAULT; + } + + return requested_size; +} + +void SDL_SYS_SetupThread(const char *name) +{ + return; +} + +SDL_threadID SDL_ThreadID(void) +{ + u32 thread_ID = 0; + svcGetThreadId(&thread_ID, CUR_THREAD_HANDLE); + return (SDL_threadID)thread_ID; +} + +int SDL_SYS_SetThreadPriority(SDL_ThreadPriority sdl_priority) +{ + s32 svc_priority; + switch (sdl_priority) { + case SDL_THREAD_PRIORITY_LOW: + svc_priority = N3DS_THREAD_PRIORITY_LOW; + break; + case SDL_THREAD_PRIORITY_NORMAL: + svc_priority = N3DS_THREAD_PRIORITY_MEDIUM; + break; + case SDL_THREAD_PRIORITY_HIGH: + svc_priority = N3DS_THREAD_PRIORITY_HIGH; + break; + case SDL_THREAD_PRIORITY_TIME_CRITICAL: + svc_priority = N3DS_THREAD_PRIORITY_TIME_CRITICAL; + break; + default: + svc_priority = N3DS_THREAD_PRIORITY_MEDIUM; + } + return (int)svcSetThreadPriority(CUR_THREAD_HANDLE, svc_priority); +} + +void SDL_SYS_WaitThread(SDL_Thread *thread) +{ + Result res = threadJoin(thread->handle, U64_MAX); + + /* + Detached threads can be waited on, but should NOT be cleaned manually + as it would result in a fatal error. + */ + if (R_SUCCEEDED(res) && SDL_AtomicGet(&thread->state) != SDL_THREAD_STATE_DETACHED) { + threadFree(thread->handle); + } +} + +void SDL_SYS_DetachThread(SDL_Thread *thread) +{ + threadDetach(thread->handle); +} + +#endif /* SDL_THREAD_N3DS */ + +/* vi: set sts=4 ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/thread/n3ds/SDL_systhread_c.h b/SDL2-2.30.5/src/thread/n3ds/SDL_systhread_c.h new file mode 100644 index 0000000..ee8bf94 --- /dev/null +++ b/SDL2-2.30.5/src/thread/n3ds/SDL_systhread_c.h @@ -0,0 +1,32 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifndef SDL_systhread_c_h_ +#define SDL_systhread_c_h_ + +#include <3ds.h> + +typedef Thread SYS_ThreadHandle; + +#endif /* SDL_systhread_c_h_ */ + +/* vi: set sts=4 ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/thread/ngage/SDL_sysmutex.cpp b/SDL2-2.30.5/src/thread/ngage/SDL_sysmutex.cpp new file mode 100644 index 0000000..4aa2625 --- /dev/null +++ b/SDL2-2.30.5/src/thread/ngage/SDL_sysmutex.cpp @@ -0,0 +1,112 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +/* An implementation of mutexes using the Symbian API. */ + +#include + +#include "SDL_thread.h" +#include "SDL_systhread_c.h" + +struct SDL_mutex +{ + TInt handle; +}; + +extern TInt CreateUnique(TInt (*aFunc)(const TDesC &aName, TAny *, TAny *), TAny *, TAny *); + +static TInt NewMutex(const TDesC &aName, TAny *aPtr1, TAny *) +{ + return ((RMutex *)aPtr1)->CreateGlobal(aName); +} + +/* Create a mutex */ +SDL_mutex *SDL_CreateMutex(void) +{ + RMutex rmutex; + + TInt status = CreateUnique(NewMutex, &rmutex, NULL); + if (status != KErrNone) { + SDL_SetError("Couldn't create mutex."); + return NULL; + } + SDL_mutex *mutex = new /*(ELeave)*/ SDL_mutex; + mutex->handle = rmutex.Handle(); + return mutex; +} + +/* Free the mutex */ +void SDL_DestroyMutex(SDL_mutex *mutex) +{ + if (mutex) { + RMutex rmutex; + rmutex.SetHandle(mutex->handle); + rmutex.Signal(); + rmutex.Close(); + delete (mutex); + mutex = NULL; + } +} + +/* Lock the mutex */ +int SDL_LockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */ +{ + if (mutex == NULL) { + return 0; + } + + RMutex rmutex; + rmutex.SetHandle(mutex->handle); + rmutex.Wait(); + + return 0; +} + +/* Try to lock the mutex */ +#if 0 +int SDL_TryLockMutex(SDL_mutex *mutex) +{ + if (mutex == NULL) + { + return 0; + } + + // Not yet implemented. + return 0; +} +#endif + +/* Unlock the mutex */ +int SDL_UnlockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */ +{ + if (mutex == NULL) { + return 0; + } + + RMutex rmutex; + rmutex.SetHandle(mutex->handle); + rmutex.Signal(); + + return 0; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/thread/ngage/SDL_syssem.cpp b/SDL2-2.30.5/src/thread/ngage/SDL_syssem.cpp new file mode 100644 index 0000000..f8e1198 --- /dev/null +++ b/SDL2-2.30.5/src/thread/ngage/SDL_syssem.cpp @@ -0,0 +1,173 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +/* An implementation of semaphores using the Symbian API. */ + +#include + +#include "SDL_error.h" +#include "SDL_thread.h" + +#define SDL_MUTEX_TIMEOUT -2 + +struct SDL_semaphore +{ + TInt handle; + TInt count; +}; + +struct TInfo +{ + TInfo(TInt aTime, TInt aHandle) : iTime(aTime), iHandle(aHandle), iVal(0) {} + TInt iTime; + TInt iHandle; + TInt iVal; +}; + +extern TInt CreateUnique(TInt (*aFunc)(const TDesC &aName, TAny *, TAny *), TAny *, TAny *); + +static TBool RunThread(TAny *aInfo) +{ + TInfo *info = STATIC_CAST(TInfo *, aInfo); + User::After(info->iTime); + RSemaphore sema; + sema.SetHandle(info->iHandle); + sema.Signal(); + info->iVal = SDL_MUTEX_TIMEOUT; + return 0; +} + +static TInt NewThread(const TDesC &aName, TAny *aPtr1, TAny *aPtr2) +{ + return ((RThread *)(aPtr1))->Create(aName, RunThread, KDefaultStackSize, NULL, aPtr2); +} + +static TInt NewSema(const TDesC &aName, TAny *aPtr1, TAny *aPtr2) +{ + TInt value = *((TInt *)aPtr2); + return ((RSemaphore *)aPtr1)->CreateGlobal(aName, value); +} + +static void WaitAll(SDL_sem *sem) +{ + RSemaphore sema; + sema.SetHandle(sem->handle); + sema.Wait(); + while (sem->count < 0) { + sema.Wait(); + } +} + +SDL_sem *SDL_CreateSemaphore(Uint32 initial_value) +{ + RSemaphore s; + TInt status = CreateUnique(NewSema, &s, &initial_value); + if (status != KErrNone) { + SDL_SetError("Couldn't create semaphore"); + } + SDL_semaphore *sem = new /*(ELeave)*/ SDL_semaphore; + sem->handle = s.Handle(); + sem->count = initial_value; + return sem; +} + +void SDL_DestroySemaphore(SDL_sem *sem) +{ + if (sem) { + RSemaphore sema; + sema.SetHandle(sem->handle); + sema.Signal(sema.Count()); + sema.Close(); + delete sem; + sem = NULL; + } +} + +int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) +{ + if (!sem) { + return SDL_InvalidParamError("sem"); + } + + if (timeout == SDL_MUTEX_MAXWAIT) { + WaitAll(sem); + return SDL_MUTEX_MAXWAIT; + } + + RThread thread; + TInfo *info = new (ELeave) TInfo(timeout, sem->handle); + TInt status = CreateUnique(NewThread, &thread, info); + + if (status != KErrNone) { + return status; + } + + thread.Resume(); + WaitAll(sem); + + if (thread.ExitType() == EExitPending) { + thread.Kill(SDL_MUTEX_TIMEOUT); + } + + thread.Close(); + return info->iVal; +} + +int SDL_SemTryWait(SDL_sem *sem) +{ + if (!sem) { + return SDL_InvalidParamError("sem"); + } + + if (sem->count > 0) { + sem->count--; + } + return SDL_MUTEX_TIMEOUT; +} + +int SDL_SemWait(SDL_sem *sem) +{ + return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT); +} + +Uint32 SDL_SemValue(SDL_sem *sem) +{ + if (!sem) { + SDL_InvalidParamError("sem"); + return 0; + } + return sem->count; +} + +int SDL_SemPost(SDL_sem *sem) +{ + if (!sem) { + return SDL_InvalidParamError("sem"); + } + sem->count++; + RSemaphore sema; + sema.SetHandle(sem->handle); + sema.Signal(); + return 0; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/thread/ngage/SDL_systhread.cpp b/SDL2-2.30.5/src/thread/ngage/SDL_systhread.cpp new file mode 100644 index 0000000..8eb50b2 --- /dev/null +++ b/SDL2-2.30.5/src/thread/ngage/SDL_systhread.cpp @@ -0,0 +1,115 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_THREAD_NGAGE + +/* N-Gage thread management routines for SDL */ + +#include + +extern "C" { +#undef NULL +#include "SDL_error.h" +#include "SDL_thread.h" +#include "../SDL_systhread.h" +#include "../SDL_thread_c.h" +}; + +static int object_count; + +static int RunThread(TAny *data) +{ + SDL_RunThread((SDL_Thread *)data); + return 0; +} + +static TInt NewThread(const TDesC &aName, TAny *aPtr1, TAny *aPtr2) +{ + return ((RThread *)(aPtr1))->Create(aName, RunThread, KDefaultStackSize, NULL, aPtr2); +} + +int CreateUnique(TInt (*aFunc)(const TDesC &aName, TAny *, TAny *), TAny *aPtr1, TAny *aPtr2) +{ + TBuf<16> name; + TInt status = KErrNone; + do { + object_count++; + name.Format(_L("SDL_%x"), object_count); + status = aFunc(name, aPtr1, aPtr2); + } while (status == KErrAlreadyExists); + return status; +} + +int SDL_SYS_CreateThread(SDL_Thread *thread) +{ + RThread rthread; + + TInt status = CreateUnique(NewThread, &rthread, thread); + if (status != KErrNone) { + delete (RThread *)thread->handle; + thread->handle = NULL; + return SDL_SetError("Not enough resources to create thread"); + } + + rthread.Resume(); + thread->handle = rthread.Handle(); + return 0; +} + +void SDL_SYS_SetupThread(const char *name) +{ + return; +} + +SDL_threadID SDL_ThreadID(void) +{ + RThread current; + TThreadId id = current.Id(); + return id; +} + +int SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority) +{ + return 0; +} + +void SDL_SYS_WaitThread(SDL_Thread *thread) +{ + RThread t; + t.Open(thread->threadid); + if (t.ExitReason() == EExitPending) { + TRequestStatus status; + t.Logon(status); + User::WaitForRequest(status); + } + t.Close(); +} + +void SDL_SYS_DetachThread(SDL_Thread *thread) +{ + return; +} + +#endif /* SDL_THREAD_NGAGE */ + +/* vim: ts=4 sw=4 + */ diff --git a/SDL2-2.30.5/src/thread/ngage/SDL_systhread_c.h b/SDL2-2.30.5/src/thread/ngage/SDL_systhread_c.h new file mode 100644 index 0000000..ed6ce36 --- /dev/null +++ b/SDL2-2.30.5/src/thread/ngage/SDL_systhread_c.h @@ -0,0 +1,25 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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 int SYS_ThreadHandle; + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/thread/os2/SDL_sysmutex.c b/SDL2-2.30.5/src/thread/os2/SDL_sysmutex.c new file mode 100644 index 0000000..e3a32e2 --- /dev/null +++ b/SDL2-2.30.5/src/thread/os2/SDL_sysmutex.c @@ -0,0 +1,124 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_THREAD_OS2 + +/* An implementation of mutexes for OS/2 */ + +#include "SDL_thread.h" +#include "SDL_systhread_c.h" +#include "../../core/os2/SDL_os2.h" + +#define INCL_DOSSEMAPHORES +#define INCL_DOSERRORS +#include + +struct SDL_mutex { + HMTX _handle; +}; + +/* Create a mutex */ +SDL_mutex *SDL_CreateMutex(void) +{ + ULONG ulRC; + HMTX hMtx; + + ulRC = DosCreateMutexSem(NULL, &hMtx, 0, FALSE); + if (ulRC != NO_ERROR) { + debug_os2("DosCreateMutexSem(), rc = %u", ulRC); + return NULL; + } + + return (SDL_mutex *)hMtx; +} + +/* Free the mutex */ +void SDL_DestroyMutex(SDL_mutex * mutex) +{ + HMTX hMtx = (HMTX)mutex; + if (hMtx != NULLHANDLE) { + const ULONG ulRC = DosCloseMutexSem(hMtx); + if (ulRC != NO_ERROR) { + debug_os2("DosCloseMutexSem(), rc = %u", ulRC); + } + } +} + +/* Lock the mutex */ +int SDL_LockMutex(SDL_mutex * mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */ +{ + ULONG ulRC; + HMTX hMtx = (HMTX)mutex; + + if (hMtx == NULLHANDLE) + return 0; + + ulRC = DosRequestMutexSem(hMtx, SEM_INDEFINITE_WAIT); + if (ulRC != NO_ERROR) { + debug_os2("DosRequestMutexSem(), rc = %u", ulRC); + return -1; + } + + return 0; +} + +/* try Lock the mutex */ +int SDL_TryLockMutex(SDL_mutex * mutex) +{ + ULONG ulRC; + HMTX hMtx = (HMTX)mutex; + + if (hMtx == NULLHANDLE) + return 0; + + ulRC = DosRequestMutexSem(hMtx, SEM_IMMEDIATE_RETURN); + + if (ulRC == ERROR_TIMEOUT) + return SDL_MUTEX_TIMEDOUT; + + if (ulRC != NO_ERROR) { + debug_os2("DosRequestMutexSem(), rc = %u", ulRC); + return -1; + } + + return 0; +} + +/* Unlock the mutex */ +int SDL_UnlockMutex(SDL_mutex * mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */ +{ + ULONG ulRC; + HMTX hMtx = (HMTX)mutex; + + if (hMtx == NULLHANDLE) + return 0; + + ulRC = DosReleaseMutexSem(hMtx); + if (ulRC != NO_ERROR) + return SDL_SetError("DosReleaseMutexSem(), rc = %u", ulRC); + + return 0; +} + +#endif /* SDL_THREAD_OS2 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/thread/os2/SDL_syssem.c b/SDL2-2.30.5/src/thread/os2/SDL_syssem.c new file mode 100644 index 0000000..44d6e91 --- /dev/null +++ b/SDL2-2.30.5/src/thread/os2/SDL_syssem.c @@ -0,0 +1,183 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_THREAD_OS2 + +/* An implementation of semaphores for OS/2 */ + +#include "SDL_thread.h" +#include "../../core/os2/SDL_os2.h" + +#define INCL_DOSSEMAPHORES +#define INCL_DOSERRORS +#define INCL_DOSMISC +#include + +struct SDL_semaphore { + HEV hEv; + HMTX hMtx; + ULONG cPost; +}; + + +SDL_sem *SDL_CreateSemaphore(Uint32 initial_value) +{ + ULONG ulRC; + SDL_sem *pSDLSem = SDL_malloc(sizeof(SDL_sem)); + + if (!pSDLSem) { + SDL_OutOfMemory(); + return NULL; + } + + ulRC = DosCreateEventSem(NULL, &pSDLSem->hEv, DCE_AUTORESET, FALSE); + if (ulRC != NO_ERROR) { + debug_os2("DosCreateEventSem(), rc = %u", ulRC); + SDL_free(pSDLSem); + return NULL; + } + + ulRC = DosCreateMutexSem(NULL, &pSDLSem->hMtx, 0, FALSE); + if (ulRC != NO_ERROR) { + debug_os2("DosCreateMutexSem(), rc = %u", ulRC); + DosCloseEventSem(pSDLSem->hEv); + SDL_free(pSDLSem); + return NULL; + } + + pSDLSem->cPost = initial_value; + + return pSDLSem; +} + +void SDL_DestroySemaphore(SDL_sem * sem) +{ + if (!sem) return; + + DosCloseMutexSem(sem->hMtx); + DosCloseEventSem(sem->hEv); + SDL_free(sem); +} + +int SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout) +{ + ULONG ulRC; + ULONG ulStartTime, ulCurTime; + ULONG ulTimeout; + ULONG cPost; + + if (!sem) + return SDL_InvalidParamError("sem"); + + if (timeout != SEM_INDEFINITE_WAIT) + DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &ulStartTime, sizeof(ULONG)); + + while (TRUE) { + ulRC = DosRequestMutexSem(sem->hMtx, SEM_INDEFINITE_WAIT); + if (ulRC != NO_ERROR) + return SDL_SetError("DosRequestMutexSem() failed, rc = %u", ulRC); + + cPost = sem->cPost; + if (sem->cPost != 0) + sem->cPost--; + + DosReleaseMutexSem(sem->hMtx); + + if (cPost != 0) + break; + + if (timeout == SEM_INDEFINITE_WAIT) + ulTimeout = SEM_INDEFINITE_WAIT; + else { + DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &ulCurTime, sizeof(ULONG)); + ulTimeout = ulCurTime - ulStartTime; + if (timeout < ulTimeout) + return SDL_MUTEX_TIMEDOUT; + ulTimeout = timeout - ulTimeout; + } + + ulRC = DosWaitEventSem(sem->hEv, ulTimeout); + if (ulRC == ERROR_TIMEOUT) + return SDL_MUTEX_TIMEDOUT; + + if (ulRC != NO_ERROR) + return SDL_SetError("DosWaitEventSem() failed, rc = %u", ulRC); + } + + return 0; +} + +int SDL_SemTryWait(SDL_sem * sem) +{ + return SDL_SemWaitTimeout(sem, 0); +} + +int SDL_SemWait(SDL_sem * sem) +{ + return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT); +} + +Uint32 SDL_SemValue(SDL_sem * sem) +{ + ULONG ulRC; + + if (!sem) { + SDL_InvalidParamError("sem"); + return 0; + } + + ulRC = DosRequestMutexSem(sem->hMtx, SEM_INDEFINITE_WAIT); + if (ulRC != NO_ERROR) + return SDL_SetError("DosRequestMutexSem() failed, rc = %u", ulRC); + + ulRC = sem->cPost; + DosReleaseMutexSem(sem->hMtx); + + return ulRC; +} + +int SDL_SemPost(SDL_sem * sem) +{ + ULONG ulRC; + + if (!sem) + return SDL_InvalidParamError("sem"); + + ulRC = DosRequestMutexSem(sem->hMtx, SEM_INDEFINITE_WAIT); + if (ulRC != NO_ERROR) + return SDL_SetError("DosRequestMutexSem() failed, rc = %u", ulRC); + + sem->cPost++; + + ulRC = DosPostEventSem(sem->hEv); + if (ulRC != NO_ERROR && ulRC != ERROR_ALREADY_POSTED) { + debug_os2("DosPostEventSem() failed, rc = %u", ulRC); + } + + DosReleaseMutexSem(sem->hMtx); + + return 0; +} + +#endif /* SDL_THREAD_OS2 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/thread/os2/SDL_systhread.c b/SDL2-2.30.5/src/thread/os2/SDL_systhread.c new file mode 100644 index 0000000..f150de7 --- /dev/null +++ b/SDL2-2.30.5/src/thread/os2/SDL_systhread.c @@ -0,0 +1,127 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_THREAD_OS2 + +/* Thread management routines for SDL */ + +#include "SDL_thread.h" +#include "../SDL_systhread.h" +#include "../SDL_thread_c.h" +#include "../SDL_systhread.h" +#include "SDL_systls_c.h" +#include "../../core/os2/SDL_os2.h" +#ifndef SDL_PASSED_BEGINTHREAD_ENDTHREAD +#error This source only adjusted for SDL_PASSED_BEGINTHREAD_ENDTHREAD +#endif + +#define INCL_DOSPROCESS +#define INCL_DOSERRORS +#include +#include + + +static void RunThread(void *data) +{ + SDL_Thread *thread = (SDL_Thread *) data; + pfnSDL_CurrentEndThread pfnEndThread = (pfnSDL_CurrentEndThread) thread->endfunc; + + if (ppSDLTLSData) + *ppSDLTLSData = NULL; + + SDL_RunThread(thread); + + if (pfnEndThread != NULL) + pfnEndThread(); +} + +int SDL_SYS_CreateThread(SDL_Thread * thread, + pfnSDL_CurrentBeginThread pfnBeginThread, + pfnSDL_CurrentEndThread pfnEndThread) +{ + if (thread->stacksize == 0) + thread->stacksize = 65536; + + if (pfnBeginThread) { + /* Save the function which we will have to call to clear the RTL of calling app! */ + thread->endfunc = pfnEndThread; + /* Start the thread using the runtime library of calling app! */ + thread->handle = (SYS_ThreadHandle) + pfnBeginThread(RunThread, NULL, thread->stacksize, thread); + } else { + thread->endfunc = _endthread; + thread->handle = (SYS_ThreadHandle) + _beginthread(RunThread, NULL, thread->stacksize, thread); + } + + if (thread->handle == -1) + return SDL_SetError("Not enough resources to create thread"); + + return 0; +} + +void SDL_SYS_SetupThread(const char *name) +{ + /* nothing. */ +} + +SDL_threadID SDL_ThreadID(void) +{ + PTIB tib; + PPIB pib; + + DosGetInfoBlocks(&tib, &pib); + return tib->tib_ptib2->tib2_ultid; +} + +int SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority) +{ + ULONG ulRC; + + ulRC = DosSetPriority(PRTYS_THREAD, + (priority < SDL_THREAD_PRIORITY_NORMAL)? PRTYC_IDLETIME : + (priority > SDL_THREAD_PRIORITY_NORMAL)? PRTYC_TIMECRITICAL : + PRTYC_REGULAR, + 0, 0); + if (ulRC != NO_ERROR) + return SDL_SetError("DosSetPriority() failed, rc = %u", ulRC); + + return 0; +} + +void SDL_SYS_WaitThread(SDL_Thread * thread) +{ + ULONG ulRC = DosWaitThread((PTID)&thread->handle, DCWW_WAIT); + + if (ulRC != NO_ERROR) { + debug_os2("DosWaitThread() failed, rc = %u", ulRC); + } +} + +void SDL_SYS_DetachThread(SDL_Thread * thread) +{ + /* nothing. */ +} + +#endif /* SDL_THREAD_OS2 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/thread/os2/SDL_systhread_c.h b/SDL2-2.30.5/src/thread/os2/SDL_systhread_c.h new file mode 100644 index 0000000..ed6ce36 --- /dev/null +++ b/SDL2-2.30.5/src/thread/os2/SDL_systhread_c.h @@ -0,0 +1,25 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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 int SYS_ThreadHandle; + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/thread/os2/SDL_systls.c b/SDL2-2.30.5/src/thread/os2/SDL_systls.c new file mode 100644 index 0000000..5c380dd --- /dev/null +++ b/SDL2-2.30.5/src/thread/os2/SDL_systls.c @@ -0,0 +1,89 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_THREAD_OS2 + +#include "../../core/os2/SDL_os2.h" + +#include "SDL_thread.h" +#include "../SDL_thread_c.h" + +#define INCL_DOSPROCESS +#define INCL_DOSERRORS +#include + +SDL_TLSData **ppSDLTLSData = NULL; + +static ULONG cTLSAlloc = 0; + +/* SDL_OS2TLSAlloc() called from SDL_InitSubSystem() */ +void SDL_OS2TLSAlloc(void) +{ + ULONG ulRC; + + if (cTLSAlloc == 0 || !ppSDLTLSData) { + /* First call - allocate the thread local memory (1 DWORD) */ + ulRC = DosAllocThreadLocalMemory(1, (PULONG *)&ppSDLTLSData); + if (ulRC != NO_ERROR) { + debug_os2("DosAllocThreadLocalMemory() failed, rc = %u", ulRC); + } + } + cTLSAlloc++; +} + +/* SDL_OS2TLSFree() called from SDL_QuitSubSystem() */ +void SDL_OS2TLSFree(void) +{ + ULONG ulRC; + + if (cTLSAlloc != 0) + cTLSAlloc--; + + if (cTLSAlloc == 0 && ppSDLTLSData) { + /* Last call - free the thread local memory */ + ulRC = DosFreeThreadLocalMemory((PULONG)ppSDLTLSData); + if (ulRC != NO_ERROR) { + debug_os2("DosFreeThreadLocalMemory() failed, rc = %u", ulRC); + } else { + ppSDLTLSData = NULL; + } + } +} + +SDL_TLSData *SDL_SYS_GetTLSData(void) +{ + return (!ppSDLTLSData)? NULL : *ppSDLTLSData; +} + +int SDL_SYS_SetTLSData(SDL_TLSData *data) +{ + if (!ppSDLTLSData) + return -1; + + *ppSDLTLSData = data; + return 0; +} + +#endif /* SDL_THREAD_OS2 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/thread/os2/SDL_systls_c.h b/SDL2-2.30.5/src/thread/os2/SDL_systls_c.h new file mode 100644 index 0000000..bb39443 --- /dev/null +++ b/SDL2-2.30.5/src/thread/os2/SDL_systls_c.h @@ -0,0 +1,38 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_THREAD_OS2 + +#include "../SDL_thread_c.h" + +extern SDL_TLSData **ppSDLTLSData; + +/* SDL_OS2TLSAlloc() called from SDL_InitSubSystem() */ +void SDL_OS2TLSAlloc(void); + +/* SDL_OS2TLSFree() called from SDL_QuitSubSystem() */ +void SDL_OS2TLSFree(void); + +#endif /* SDL_THREAD_OS2 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/thread/ps2/SDL_syssem.c b/SDL2-2.30.5/src/thread/ps2/SDL_syssem.c new file mode 100644 index 0000000..c5f2cae --- /dev/null +++ b/SDL2-2.30.5/src/thread/ps2/SDL_syssem.c @@ -0,0 +1,158 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_THREAD_PS2 + +/* Semaphore functions for the PS2. */ + +#include +#include +#include + +#include "SDL_error.h" +#include "SDL_thread.h" + +#include + +struct SDL_semaphore +{ + s32 semid; +}; + +/* Create a semaphore */ +SDL_sem *SDL_CreateSemaphore(Uint32 initial_value) +{ + SDL_sem *sem; + ee_sema_t sema; + + sem = (SDL_sem *)SDL_malloc(sizeof(*sem)); + if (sem) { + /* TODO: Figure out the limit on the maximum value. */ + sema.init_count = initial_value; + sema.max_count = 255; + sema.option = 0; + sem->semid = CreateSema(&sema); + + if (sem->semid < 0) { + SDL_SetError("Couldn't create semaphore"); + SDL_free(sem); + sem = NULL; + } + } else { + SDL_OutOfMemory(); + } + + return sem; +} + +/* Free the semaphore */ +void SDL_DestroySemaphore(SDL_sem *sem) +{ + if (sem) { + if (sem->semid > 0) { + DeleteSema(sem->semid); + sem->semid = 0; + } + + SDL_free(sem); + } +} + +int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) +{ + int ret; + u64 timeout_usec; + u64 *timeout_ptr; + + if (!sem) { + return SDL_InvalidParamError("sem"); + } + + if (timeout == 0) { + if (PollSema(sem->semid) < 0) { + return SDL_MUTEX_TIMEDOUT; + } + return 0; + } + + timeout_ptr = NULL; + + if (timeout != SDL_MUTEX_MAXWAIT) { + timeout_usec = timeout * 1000; + timeout_ptr = &timeout_usec; + } + + ret = WaitSemaEx(sem->semid, 1, timeout_ptr); + + if (ret < 0) { + return SDL_MUTEX_TIMEDOUT; + } + return 0; // Wait condition satisfied. +} + +int SDL_SemTryWait(SDL_sem *sem) +{ + return SDL_SemWaitTimeout(sem, 0); +} + +int SDL_SemWait(SDL_sem *sem) +{ + return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT); +} + +/* Returns the current count of the semaphore */ +Uint32 SDL_SemValue(SDL_sem *sem) +{ + ee_sema_t info; + + if (!sem) { + SDL_InvalidParamError("sem"); + return 0; + } + + if (ReferSemaStatus(sem->semid, &info) >= 0) { + return info.count; + } + + return 0; +} + +int SDL_SemPost(SDL_sem *sem) +{ + int res; + + if (!sem) { + return SDL_InvalidParamError("sem"); + } + + res = SignalSema(sem->semid); + if (res < 0) { + return SDL_SetError("sceKernelSignalSema() failed"); + } + + return 0; +} + +#endif /* SDL_THREAD_PS2 */ + +/* vim: ts=4 sw=4 + */ diff --git a/SDL2-2.30.5/src/thread/ps2/SDL_systhread.c b/SDL2-2.30.5/src/thread/ps2/SDL_systhread.c new file mode 100644 index 0000000..15dcf0d --- /dev/null +++ b/SDL2-2.30.5/src/thread/ps2/SDL_systhread.c @@ -0,0 +1,140 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_THREAD_PS2 + +/* PS2 thread management routines for SDL */ + +#include +#include + +#include "SDL_error.h" +#include "SDL_thread.h" +#include "../SDL_systhread.h" +#include "../SDL_thread_c.h" +#include + +static void FinishThread(SDL_Thread *thread) +{ + ee_thread_status_t info; + int res; + + res = ReferThreadStatus(thread->handle, &info); + TerminateThread(thread->handle); + DeleteThread(thread->handle); + DeleteSema((int)thread->endfunc); + + if (res > 0) { + SDL_free(info.stack); + } +} + +static int childThread(void *arg) +{ + SDL_Thread *thread = (SDL_Thread *)arg; + int res = thread->userfunc(thread->userdata); + SignalSema((int)thread->endfunc); + return res; +} + +int SDL_SYS_CreateThread(SDL_Thread *thread) +{ + ee_thread_status_t status; + ee_thread_t eethread; + ee_sema_t sema; + size_t stack_size; + int priority = 32; + + /* Set priority of new thread to the same as the current thread */ + // status.size = sizeof(ee_thread_t); + if (ReferThreadStatus(GetThreadId(), &status) == 0) { + priority = status.current_priority; + } + + stack_size = thread->stacksize ? ((int)thread->stacksize) : 0x1800; + + /* Create EE Thread */ + eethread.attr = 0; + eethread.option = 0; + eethread.func = &childThread; + eethread.stack = SDL_malloc(stack_size); + eethread.stack_size = stack_size; + eethread.gp_reg = &_gp; + eethread.initial_priority = priority; + thread->handle = CreateThread(&eethread); + + if (thread->handle < 0) { + return SDL_SetError("CreateThread() failed"); + } + + // Prepare el semaphore for the ending function + sema.init_count = 0; + sema.max_count = 1; + sema.option = 0; + thread->endfunc = (void *)CreateSema(&sema); + + return StartThread(thread->handle, thread); +} + +void SDL_SYS_SetupThread(const char *name) +{ + /* Do nothing. */ +} + +SDL_threadID SDL_ThreadID(void) +{ + return (SDL_threadID)GetThreadId(); +} + +void SDL_SYS_WaitThread(SDL_Thread *thread) +{ + WaitSema((int)thread->endfunc); + ReleaseWaitThread(thread->handle); + FinishThread(thread); +} + +void SDL_SYS_DetachThread(SDL_Thread *thread) +{ + /* Do nothing. */ +} + +int SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority) +{ + int value; + + if (priority == SDL_THREAD_PRIORITY_LOW) { + value = 111; + } else if (priority == SDL_THREAD_PRIORITY_HIGH) { + value = 32; + } else if (priority == SDL_THREAD_PRIORITY_TIME_CRITICAL) { + value = 16; + } else { + value = 50; + } + + return ChangeThreadPriority(GetThreadId(), value); +} + +#endif /* SDL_THREAD_PS2 */ + +/* vim: ts=4 sw=4 + */ diff --git a/SDL2-2.30.5/src/thread/ps2/SDL_systhread_c.h b/SDL2-2.30.5/src/thread/ps2/SDL_systhread_c.h new file mode 100644 index 0000000..afab383 --- /dev/null +++ b/SDL2-2.30.5/src/thread/ps2/SDL_systhread_c.h @@ -0,0 +1,24 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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 + +typedef int32_t SYS_ThreadHandle; diff --git a/SDL2-2.30.5/src/thread/psp/SDL_sysmutex.c b/SDL2-2.30.5/src/thread/psp/SDL_sysmutex.c new file mode 100644 index 0000000..eafca9f --- /dev/null +++ b/SDL2-2.30.5/src/thread/psp/SDL_sysmutex.c @@ -0,0 +1,148 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_THREAD_PSP + +/* An implementation of mutexes using semaphores */ + +#include "SDL_thread.h" +#include "SDL_systhread_c.h" + +#include +#include + +#define SCE_KERNEL_MUTEX_ATTR_RECURSIVE 0x0200U + +struct SDL_mutex +{ + SceLwMutexWorkarea lock; +}; + +/* Create a mutex */ +SDL_mutex *SDL_CreateMutex(void) +{ + SDL_mutex *mutex = NULL; + SceInt32 res = 0; + + /* Allocate mutex memory */ + mutex = (SDL_mutex *)SDL_malloc(sizeof(*mutex)); + if (mutex) { + + res = sceKernelCreateLwMutex( + &mutex->lock, + "SDL mutex", + SCE_KERNEL_MUTEX_ATTR_RECURSIVE, + 0, + NULL); + + if (res < 0) { + SDL_SetError("Error trying to create mutex: %lx", res); + } + } else { + SDL_OutOfMemory(); + } + return mutex; +} + +/* Free the mutex */ +void SDL_DestroyMutex(SDL_mutex *mutex) +{ + if (mutex) { + sceKernelDeleteLwMutex(&mutex->lock); + SDL_free(mutex); + } +} + +/* Lock the mutex */ +int SDL_LockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */ +{ +#ifdef SDL_THREADS_DISABLED + return 0; +#else + SceInt32 res = 0; + + if (mutex == NULL) { + return 0; + } + + res = sceKernelLockLwMutex(&mutex->lock, 1, NULL); + if (res != SCE_KERNEL_ERROR_OK) { + return SDL_SetError("Error trying to lock mutex: %lx", res); + } + + return 0; +#endif /* SDL_THREADS_DISABLED */ +} + +/* Try to lock the mutex */ +int SDL_TryLockMutex(SDL_mutex *mutex) +{ +#ifdef SDL_THREADS_DISABLED + return 0; +#else + SceInt32 res = 0; + + if (!mutex) { + return 0; + } + + res = sceKernelTryLockLwMutex(&mutex->lock, 1); + switch (res) { + case SCE_KERNEL_ERROR_OK: + return 0; + break; + case SCE_KERNEL_ERROR_WAIT_TIMEOUT: + return SDL_MUTEX_TIMEDOUT; + break; + default: + return SDL_SetError("Error trying to lock mutex: %lx", res); + break; + } + + return -1; +#endif /* SDL_THREADS_DISABLED */ +} + +/* Unlock the mutex */ +int SDL_UnlockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */ +{ +#ifdef SDL_THREADS_DISABLED + return 0; +#else + SceInt32 res = 0; + + if (mutex == NULL) { + return 0; + } + + res = sceKernelUnlockLwMutex(&mutex->lock, 1); + if (res != 0) { + return SDL_SetError("Error trying to unlock mutex: %lx", res); + } + + return 0; +#endif /* SDL_THREADS_DISABLED */ +} + +#endif /* SDL_THREAD_PSP */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/thread/generic/SDL_sysmutex_c.h b/SDL2-2.30.5/src/thread/psp/SDL_sysmutex_c.h similarity index 94% rename from SDL2-2.0.12/src/thread/generic/SDL_sysmutex_c.h rename to SDL2-2.30.5/src/thread/psp/SDL_sysmutex_c.h index 2f88359..886ce23 100644 --- a/SDL2-2.0.12/src/thread/generic/SDL_sysmutex_c.h +++ b/SDL2-2.30.5/src/thread/psp/SDL_sysmutex_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/thread/psp/SDL_syssem.c b/SDL2-2.30.5/src/thread/psp/SDL_syssem.c similarity index 77% rename from SDL2-2.0.12/src/thread/psp/SDL_syssem.c rename to SDL2-2.30.5/src/thread/psp/SDL_syssem.c index edad3e4..9b8e7d1 100644 --- a/SDL2-2.0.12/src/thread/psp/SDL_syssem.c +++ b/SDL2-2.30.5/src/thread/psp/SDL_syssem.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_THREAD_PSP +#ifdef SDL_THREAD_PSP /* Semaphore functions for the PSP. */ @@ -33,23 +33,23 @@ #include #include -struct SDL_semaphore { - SceUID semid; +struct SDL_semaphore +{ + SceUID semid; }; - /* Create a semaphore */ SDL_sem *SDL_CreateSemaphore(Uint32 initial_value) { SDL_sem *sem; - sem = (SDL_sem *) malloc(sizeof(*sem)); - if (sem != NULL) { + sem = (SDL_sem *)SDL_malloc(sizeof(*sem)); + if (sem) { /* TODO: Figure out the limit on the maximum value. */ sem->semid = sceKernelCreateSema("SDL sema", 0, initial_value, 255, NULL); if (sem->semid < 0) { SDL_SetError("Couldn't create semaphore"); - free(sem); + SDL_free(sem); sem = NULL; } } else { @@ -62,13 +62,13 @@ SDL_sem *SDL_CreateSemaphore(Uint32 initial_value) /* Free the semaphore */ void SDL_DestroySemaphore(SDL_sem *sem) { - if (sem != NULL) { + if (sem) { if (sem->semid > 0) { sceKernelDeleteSema(sem->semid); sem->semid = 0; } - free(sem); + SDL_free(sem); } } @@ -81,9 +81,8 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) Uint32 *pTimeout; int res; - if (sem == NULL) { - SDL_SetError("Passed a NULL sem"); - return 0; + if (!sem) { + return SDL_InvalidParamError("sem"); } if (timeout == 0) { @@ -97,18 +96,18 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) if (timeout == SDL_MUTEX_MAXWAIT) { pTimeout = NULL; } else { - timeout *= 1000; /* Convert to microseconds. */ + timeout *= 1000; /* Convert to microseconds. */ pTimeout = &timeout; } - res = sceKernelWaitSema(sem->semid, 1, pTimeout); - switch (res) { - case SCE_KERNEL_ERROR_OK: - return 0; - case SCE_KERNEL_ERROR_WAIT_TIMEOUT: - return SDL_MUTEX_TIMEDOUT; - default: - return SDL_SetError("sceKernelWaitSema() failed"); + res = sceKernelWaitSema(sem->semid, 1, (SceUInt *)pTimeout); + switch (res) { + case SCE_KERNEL_ERROR_OK: + return 0; + case SCE_KERNEL_ERROR_WAIT_TIMEOUT: + return SDL_MUTEX_TIMEDOUT; + default: + return SDL_SetError("sceKernelWaitSema() failed"); } } @@ -127,8 +126,8 @@ Uint32 SDL_SemValue(SDL_sem *sem) { SceKernelSemaInfo info; - if (sem == NULL) { - SDL_SetError("Passed a NULL sem"); + if (!sem) { + SDL_InvalidParamError("sem"); return 0; } @@ -143,8 +142,8 @@ int SDL_SemPost(SDL_sem *sem) { int res; - if (sem == NULL) { - return SDL_SetError("Passed a NULL sem"); + if (!sem) { + return SDL_InvalidParamError("sem"); } res = sceKernelSignalSema(sem->semid, 1); diff --git a/SDL2-2.0.12/src/thread/psp/SDL_systhread.c b/SDL2-2.30.5/src/thread/psp/SDL_systhread.c similarity index 82% rename from SDL2-2.0.12/src/thread/psp/SDL_systhread.c rename to SDL2-2.30.5/src/thread/psp/SDL_systhread.c index c292afa..c137799 100644 --- a/SDL2-2.0.12/src/thread/psp/SDL_systhread.c +++ b/SDL2-2.30.5/src/thread/psp/SDL_systhread.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_THREAD_PSP +#ifdef SDL_THREAD_PSP /* PSP thread management routines for SDL */ @@ -34,14 +34,13 @@ #include #include - static int ThreadEntry(SceSize args, void *argp) { - SDL_RunThread(*(void **) argp); + SDL_RunThread(*(SDL_Thread **)argp); return 0; } -int SDL_SYS_CreateThread(SDL_Thread *thread, void *args) +int SDL_SYS_CreateThread(SDL_Thread *thread) { SceKernelThreadInfo status; int priority = 32; @@ -53,13 +52,13 @@ int SDL_SYS_CreateThread(SDL_Thread *thread, void *args) } thread->handle = sceKernelCreateThread(thread->name, ThreadEntry, - priority, thread->stacksize ? ((int) thread->stacksize) : 0x8000, - PSP_THREAD_ATTR_VFPU, NULL); + priority, thread->stacksize ? ((int)thread->stacksize) : 0x8000, + PSP_THREAD_ATTR_VFPU, NULL); if (thread->handle < 0) { return SDL_SetError("sceKernelCreateThread() failed"); } - sceKernelStartThread(thread->handle, 4, &args); + sceKernelStartThread(thread->handle, 4, &thread); return 0; } @@ -70,7 +69,7 @@ void SDL_SYS_SetupThread(const char *name) SDL_threadID SDL_ThreadID(void) { - return (SDL_threadID) sceKernelGetThreadId(); + return (SDL_threadID)sceKernelGetThreadId(); } void SDL_SYS_WaitThread(SDL_Thread *thread) @@ -95,17 +94,16 @@ int SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority) int value; if (priority == SDL_THREAD_PRIORITY_LOW) { - value = 19; + value = 111; } else if (priority == SDL_THREAD_PRIORITY_HIGH) { - value = -10; + value = 32; } else if (priority == SDL_THREAD_PRIORITY_TIME_CRITICAL) { - value = -20; + value = 16; } else { - value = 0; + value = 50; } - return sceKernelChangeThreadPriority(sceKernelGetThreadId(),value); - + return sceKernelChangeThreadPriority(sceKernelGetThreadId(), value); } #endif /* SDL_THREAD_PSP */ diff --git a/SDL2-2.0.12/src/thread/psp/SDL_systhread_c.h b/SDL2-2.30.5/src/thread/psp/SDL_systhread_c.h similarity index 94% rename from SDL2-2.0.12/src/thread/psp/SDL_systhread_c.h rename to SDL2-2.30.5/src/thread/psp/SDL_systhread_c.h index 4622fd3..ffa8449 100644 --- a/SDL2-2.0.12/src/thread/psp/SDL_systhread_c.h +++ b/SDL2-2.30.5/src/thread/psp/SDL_systhread_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/thread/pthread/SDL_syscond.c b/SDL2-2.30.5/src/thread/pthread/SDL_syscond.c similarity index 81% rename from SDL2-2.0.12/src/thread/pthread/SDL_syscond.c rename to SDL2-2.30.5/src/thread/pthread/SDL_syscond.c index 28cf819..a1a2e63 100644 --- a/SDL2-2.0.12/src/thread/pthread/SDL_syscond.c +++ b/SDL2-2.30.5/src/thread/pthread/SDL_syscond.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -35,12 +35,11 @@ struct SDL_cond }; /* Create a condition variable */ -SDL_cond * -SDL_CreateCond(void) +SDL_cond *SDL_CreateCond(void) { SDL_cond *cond; - cond = (SDL_cond *) SDL_malloc(sizeof(SDL_cond)); + cond = (SDL_cond *)SDL_malloc(sizeof(SDL_cond)); if (cond) { if (pthread_cond_init(&cond->cond, NULL) != 0) { SDL_SetError("pthread_cond_init() failed"); @@ -48,12 +47,11 @@ SDL_CreateCond(void) cond = NULL; } } - return (cond); + return cond; } /* Destroy a condition variable */ -void -SDL_DestroyCond(SDL_cond * cond) +void SDL_DestroyCond(SDL_cond *cond) { if (cond) { pthread_cond_destroy(&cond->cond); @@ -62,13 +60,12 @@ SDL_DestroyCond(SDL_cond * cond) } /* Restart one of the threads that are waiting on the condition variable */ -int -SDL_CondSignal(SDL_cond * cond) +int SDL_CondSignal(SDL_cond *cond) { int retval; if (!cond) { - return SDL_SetError("Passed a NULL condition variable"); + return SDL_InvalidParamError("cond"); } retval = 0; @@ -79,13 +76,12 @@ SDL_CondSignal(SDL_cond * cond) } /* Restart all threads that are waiting on the condition variable */ -int -SDL_CondBroadcast(SDL_cond * cond) +int SDL_CondBroadcast(SDL_cond *cond) { int retval; if (!cond) { - return SDL_SetError("Passed a NULL condition variable"); + return SDL_InvalidParamError("cond"); } retval = 0; @@ -95,8 +91,7 @@ SDL_CondBroadcast(SDL_cond * cond) return retval; } -int -SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms) +int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms) { int retval; #ifndef HAVE_CLOCK_GETTIME @@ -105,7 +100,7 @@ SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms) struct timespec abstime; if (!cond) { - return SDL_SetError("Passed a NULL condition variable"); + return SDL_InvalidParamError("cond"); } #ifdef HAVE_CLOCK_GETTIME @@ -117,14 +112,14 @@ SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms) gettimeofday(&delta, NULL); abstime.tv_sec = delta.tv_sec + (ms / 1000); - abstime.tv_nsec = (delta.tv_usec + (ms % 1000) * 1000) * 1000; + abstime.tv_nsec = (long)(delta.tv_usec + (ms % 1000) * 1000) * 1000; #endif if (abstime.tv_nsec > 1000000000) { abstime.tv_sec += 1; abstime.tv_nsec -= 1000000000; } - tryagain: +tryagain: retval = pthread_cond_timedwait(&cond->cond, &mutex->id, &abstime); switch (retval) { case EINTR: @@ -144,11 +139,10 @@ SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms) /* Wait on the condition variable, unlocking the provided mutex. The mutex must be locked before entering this function! */ -int -SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex) +int SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex) { if (!cond) { - return SDL_SetError("Passed a NULL condition variable"); + return SDL_InvalidParamError("cond"); } else if (pthread_cond_wait(&cond->cond, &mutex->id) != 0) { return SDL_SetError("pthread_cond_wait() failed"); } diff --git a/SDL2-2.0.12/src/thread/pthread/SDL_sysmutex.c b/SDL2-2.30.5/src/thread/pthread/SDL_sysmutex.c similarity index 82% rename from SDL2-2.0.12/src/thread/pthread/SDL_sysmutex.c rename to SDL2-2.30.5/src/thread/pthread/SDL_sysmutex.c index b4ebcc6..c66b5cc 100644 --- a/SDL2-2.0.12/src/thread/pthread/SDL_sysmutex.c +++ b/SDL2-2.30.5/src/thread/pthread/SDL_sysmutex.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -25,33 +25,32 @@ #include "SDL_thread.h" -#if !SDL_THREAD_PTHREAD_RECURSIVE_MUTEX && \ - !SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP -#define FAKE_RECURSIVE_MUTEX 1 +#if !(defined(SDL_THREAD_PTHREAD_RECURSIVE_MUTEX) || \ + defined(SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP)) +#define FAKE_RECURSIVE_MUTEX #endif struct SDL_mutex { pthread_mutex_t id; -#if FAKE_RECURSIVE_MUTEX +#ifdef FAKE_RECURSIVE_MUTEX int recursive; pthread_t owner; #endif }; -SDL_mutex * -SDL_CreateMutex(void) +SDL_mutex *SDL_CreateMutex(void) { SDL_mutex *mutex; pthread_mutexattr_t attr; /* Allocate the structure */ - mutex = (SDL_mutex *) SDL_calloc(1, sizeof(*mutex)); + mutex = (SDL_mutex *)SDL_calloc(1, sizeof(*mutex)); if (mutex) { pthread_mutexattr_init(&attr); -#if SDL_THREAD_PTHREAD_RECURSIVE_MUTEX +#ifdef SDL_THREAD_PTHREAD_RECURSIVE_MUTEX pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); -#elif SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP +#elif defined(SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP) pthread_mutexattr_setkind_np(&attr, PTHREAD_MUTEX_RECURSIVE_NP); #else /* No extra attributes necessary */ @@ -64,11 +63,10 @@ SDL_CreateMutex(void) } else { SDL_OutOfMemory(); } - return (mutex); + return mutex; } -void -SDL_DestroyMutex(SDL_mutex * mutex) +void SDL_DestroyMutex(SDL_mutex *mutex) { if (mutex) { pthread_mutex_destroy(&mutex->id); @@ -77,18 +75,17 @@ SDL_DestroyMutex(SDL_mutex * mutex) } /* Lock the mutex */ -int -SDL_LockMutex(SDL_mutex * mutex) +int SDL_LockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */ { -#if FAKE_RECURSIVE_MUTEX +#ifdef FAKE_RECURSIVE_MUTEX pthread_t this_thread; #endif if (mutex == NULL) { - return SDL_SetError("Passed a NULL mutex"); + return 0; } -#if FAKE_RECURSIVE_MUTEX +#ifdef FAKE_RECURSIVE_MUTEX this_thread = pthread_self(); if (mutex->owner == this_thread) { ++mutex->recursive; @@ -112,21 +109,20 @@ SDL_LockMutex(SDL_mutex * mutex) return 0; } -int -SDL_TryLockMutex(SDL_mutex * mutex) +int SDL_TryLockMutex(SDL_mutex *mutex) { int retval; int result; -#if FAKE_RECURSIVE_MUTEX +#ifdef FAKE_RECURSIVE_MUTEX pthread_t this_thread; #endif - if (mutex == NULL) { - return SDL_SetError("Passed a NULL mutex"); + if (!mutex) { + return 0; } retval = 0; -#if FAKE_RECURSIVE_MUTEX +#ifdef FAKE_RECURSIVE_MUTEX this_thread = pthread_self(); if (mutex->owner == this_thread) { ++mutex->recursive; @@ -158,14 +154,13 @@ SDL_TryLockMutex(SDL_mutex * mutex) return retval; } -int -SDL_UnlockMutex(SDL_mutex * mutex) +int SDL_UnlockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */ { if (mutex == NULL) { - return SDL_SetError("Passed a NULL mutex"); + return 0; } -#if FAKE_RECURSIVE_MUTEX +#ifdef FAKE_RECURSIVE_MUTEX /* We can only unlock the mutex if we own it */ if (pthread_self() == mutex->owner) { if (mutex->recursive) { diff --git a/SDL2-2.0.12/src/thread/pthread/SDL_sysmutex_c.h b/SDL2-2.30.5/src/thread/pthread/SDL_sysmutex_c.h similarity index 94% rename from SDL2-2.0.12/src/thread/pthread/SDL_sysmutex_c.h rename to SDL2-2.30.5/src/thread/pthread/SDL_sysmutex_c.h index 8c38367..0435a38 100644 --- a/SDL2-2.0.12/src/thread/pthread/SDL_sysmutex_c.h +++ b/SDL2-2.30.5/src/thread/pthread/SDL_sysmutex_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/thread/pthread/SDL_syssem.c b/SDL2-2.30.5/src/thread/pthread/SDL_syssem.c similarity index 81% rename from SDL2-2.0.12/src/thread/pthread/SDL_syssem.c rename to SDL2-2.30.5/src/thread/pthread/SDL_syssem.c index 9f3bc30..6d0cdd5 100644 --- a/SDL2-2.0.12/src/thread/pthread/SDL_syssem.c +++ b/SDL2-2.30.5/src/thread/pthread/SDL_syssem.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -42,10 +42,9 @@ struct SDL_semaphore }; /* Create a semaphore, initialized with value */ -SDL_sem * -SDL_CreateSemaphore(Uint32 initial_value) +SDL_sem *SDL_CreateSemaphore(Uint32 initial_value) { - SDL_sem *sem = (SDL_sem *) SDL_malloc(sizeof(SDL_sem)); + SDL_sem *sem = (SDL_sem *)SDL_malloc(sizeof(SDL_sem)); if (sem) { if (sem_init(&sem->sem, 0, initial_value) < 0) { SDL_SetError("sem_init() failed"); @@ -58,8 +57,7 @@ SDL_CreateSemaphore(Uint32 initial_value) return sem; } -void -SDL_DestroySemaphore(SDL_sem * sem) +void SDL_DestroySemaphore(SDL_sem *sem) { if (sem) { sem_destroy(&sem->sem); @@ -67,13 +65,12 @@ SDL_DestroySemaphore(SDL_sem * sem) } } -int -SDL_SemTryWait(SDL_sem * sem) +int SDL_SemTryWait(SDL_sem *sem) { int retval; if (!sem) { - return SDL_SetError("Passed a NULL semaphore"); + return SDL_InvalidParamError("sem"); } retval = SDL_MUTEX_TIMEDOUT; if (sem_trywait(&sem->sem) == 0) { @@ -82,13 +79,12 @@ SDL_SemTryWait(SDL_sem * sem) return retval; } -int -SDL_SemWait(SDL_sem * sem) +int SDL_SemWait(SDL_sem *sem) { int retval; if (!sem) { - return SDL_SetError("Passed a NULL semaphore"); + return SDL_InvalidParamError("sem"); } do { @@ -101,10 +97,9 @@ SDL_SemWait(SDL_sem * sem) return retval; } -int -SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout) +int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) { - int retval; + int retval = 0; #ifdef HAVE_SEM_TIMEDWAIT #ifndef HAVE_CLOCK_GETTIME struct timeval now; @@ -115,7 +110,7 @@ SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout) #endif if (!sem) { - return SDL_SetError("Passed a NULL semaphore"); + return SDL_InvalidParamError("sem"); } /* Try the easy cases first */ @@ -128,9 +123,9 @@ SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout) #ifdef HAVE_SEM_TIMEDWAIT /* Setup the timeout. sem_timedwait doesn't wait for - * a lapse of time, but until we reach a certain time. - * This time is now plus the timeout. - */ + * a lapse of time, but until we reach a certain time. + * This time is now plus the timeout. + */ #ifdef HAVE_CLOCK_GETTIME clock_gettime(CLOCK_REALTIME, &ts_timeout); @@ -176,26 +171,28 @@ SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout) return retval; } -Uint32 -SDL_SemValue(SDL_sem * sem) +Uint32 SDL_SemValue(SDL_sem *sem) { int ret = 0; - if (sem) { - sem_getvalue(&sem->sem, &ret); - if (ret < 0) { - ret = 0; - } + + if (!sem) { + SDL_InvalidParamError("sem"); + return 0; } - return (Uint32) ret; + + sem_getvalue(&sem->sem, &ret); + if (ret < 0) { + ret = 0; + } + return (Uint32)ret; } -int -SDL_SemPost(SDL_sem * sem) +int SDL_SemPost(SDL_sem *sem) { int retval; if (!sem) { - return SDL_SetError("Passed a NULL semaphore"); + return SDL_InvalidParamError("sem"); } retval = sem_post(&sem->sem); diff --git a/SDL2-2.30.5/src/thread/pthread/SDL_systhread.c b/SDL2-2.30.5/src/thread/pthread/SDL_systhread.c new file mode 100644 index 0000000..ccc0987 --- /dev/null +++ b/SDL2-2.30.5/src/thread/pthread/SDL_systhread.c @@ -0,0 +1,298 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_system.h" +#include "SDL_hints.h" + +#include + +#ifdef HAVE_PTHREAD_NP_H +#include +#endif + +#include +#include + +#ifdef __LINUX__ +#include +#include +#include +#include + +#include "../../core/linux/SDL_dbus.h" +#endif /* __LINUX__ */ + +#if (defined(__LINUX__) || defined(__MACOSX__) || defined(__IPHONEOS__)) && defined(HAVE_DLOPEN) +#include +#ifndef RTLD_DEFAULT +#define RTLD_DEFAULT NULL +#endif +#endif + +#include "SDL_thread.h" +#include "../SDL_thread_c.h" +#include "../SDL_systhread.h" +#ifdef __ANDROID__ +#include "../../core/android/SDL_android.h" +#endif + +#ifdef __HAIKU__ +#include +#endif + + +#ifndef __NACL__ +/* List of signals to mask in the subthreads */ +static const int sig_list[] = { + SIGHUP, SIGINT, SIGQUIT, SIGPIPE, SIGALRM, SIGTERM, SIGCHLD, SIGWINCH, + SIGVTALRM, SIGPROF, 0 +}; +#endif + +static void *RunThread(void *data) +{ +#ifdef __ANDROID__ + Android_JNI_SetupThread(); +#endif + SDL_RunThread((SDL_Thread *)data); + return NULL; +} + +#if (defined(__MACOSX__) || defined(__IPHONEOS__)) && defined(HAVE_DLOPEN) +static SDL_bool checked_setname = SDL_FALSE; +static int (*ppthread_setname_np)(const char *) = NULL; +#elif defined(__LINUX__) && defined(HAVE_DLOPEN) +static SDL_bool checked_setname = SDL_FALSE; +static int (*ppthread_setname_np)(pthread_t, const char *) = NULL; +#endif +int SDL_SYS_CreateThread(SDL_Thread *thread) +{ + pthread_attr_t type; + + /* do this here before any threads exist, so there's no race condition. */ + #if (defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__LINUX__)) && defined(HAVE_DLOPEN) + if (!checked_setname) { + void *fn = dlsym(RTLD_DEFAULT, "pthread_setname_np"); + #if defined(__MACOSX__) || defined(__IPHONEOS__) + ppthread_setname_np = (int(*)(const char*)) fn; + #elif defined(__LINUX__) + ppthread_setname_np = (int(*)(pthread_t, const char*)) fn; + #endif + checked_setname = SDL_TRUE; + } +#endif + + /* Set the thread attributes */ + if (pthread_attr_init(&type) != 0) { + return SDL_SetError("Couldn't initialize pthread attributes"); + } + pthread_attr_setdetachstate(&type, PTHREAD_CREATE_JOINABLE); + + /* Set caller-requested stack size. Otherwise: use the system default. */ + if (thread->stacksize) { + pthread_attr_setstacksize(&type, thread->stacksize); + } + + /* Create the thread and go! */ + if (pthread_create(&thread->handle, &type, RunThread, thread) != 0) { + return SDL_SetError("Not enough resources to create thread"); + } + + return 0; +} + +void SDL_SYS_SetupThread(const char *name) +{ +#if !defined(__NACL__) + int i; + sigset_t mask; +#endif /* !__NACL__ */ + + if (name) { + #if (defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__LINUX__)) && defined(HAVE_DLOPEN) + SDL_assert(checked_setname); + if (ppthread_setname_np) { + #if defined(__MACOSX__) || defined(__IPHONEOS__) + ppthread_setname_np(name); +#elif defined(__LINUX__) + if (ppthread_setname_np(pthread_self(), name) == ERANGE) { + char namebuf[16]; /* Limited to 16 char */ + SDL_strlcpy(namebuf, name, sizeof(namebuf)); + ppthread_setname_np(pthread_self(), namebuf); + } +#endif + } +#elif defined(HAVE_PTHREAD_SETNAME_NP) +#if defined(__NETBSD__) + pthread_setname_np(pthread_self(), "%s", name); +#else + if (pthread_setname_np(pthread_self(), name) == ERANGE) { + char namebuf[16]; /* Limited to 16 char */ + SDL_strlcpy(namebuf, name, sizeof(namebuf)); + pthread_setname_np(pthread_self(), namebuf); + } +#endif +#elif defined(HAVE_PTHREAD_SET_NAME_NP) + pthread_set_name_np(pthread_self(), name); +#elif defined(__HAIKU__) + /* The docs say the thread name can't be longer than B_OS_NAME_LENGTH. */ + char namebuf[B_OS_NAME_LENGTH]; + SDL_strlcpy(namebuf, name, sizeof(namebuf)); + rename_thread(find_thread(NULL), namebuf); +#endif + } + + /* NativeClient does not yet support signals.*/ +#if !defined(__NACL__) + /* Mask asynchronous signals for this thread */ + sigemptyset(&mask); + for (i = 0; sig_list[i]; ++i) { + sigaddset(&mask, sig_list[i]); + } + pthread_sigmask(SIG_BLOCK, &mask, 0); +#endif /* !__NACL__ */ + + +#ifdef PTHREAD_CANCEL_ASYNCHRONOUS + /* Allow ourselves to be asynchronously cancelled */ + { + int oldstate; + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate); + } +#endif +} + +SDL_threadID SDL_ThreadID(void) +{ + return (SDL_threadID)pthread_self(); +} + +int SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority) +{ +#if defined(__NACL__) || defined(__RISCOS__) || defined(__OS2__) + /* FIXME: Setting thread priority does not seem to be supported in NACL */ + return 0; +#else + struct sched_param sched; + int policy; + int pri_policy; + pthread_t thread = pthread_self(); + const char *policyhint = SDL_GetHint(SDL_HINT_THREAD_PRIORITY_POLICY); + const SDL_bool timecritical_realtime_hint = SDL_GetHintBoolean(SDL_HINT_THREAD_FORCE_REALTIME_TIME_CRITICAL, SDL_FALSE); + + if (pthread_getschedparam(thread, &policy, &sched) != 0) { + return SDL_SetError("pthread_getschedparam() failed"); + } + + /* Higher priority levels may require changing the pthread scheduler policy + * for the thread. SDL will make such changes by default but there is + * also a hint allowing that behavior to be overridden. */ + switch (priority) { + case SDL_THREAD_PRIORITY_LOW: + case SDL_THREAD_PRIORITY_NORMAL: + pri_policy = SCHED_OTHER; + break; + case SDL_THREAD_PRIORITY_HIGH: + case SDL_THREAD_PRIORITY_TIME_CRITICAL: +#if defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__TVOS__) + /* Apple requires SCHED_RR for high priority threads */ + pri_policy = SCHED_RR; + break; +#else + pri_policy = SCHED_OTHER; + break; +#endif + default: + pri_policy = policy; + break; + } + + if (timecritical_realtime_hint && priority == SDL_THREAD_PRIORITY_TIME_CRITICAL) { + pri_policy = SCHED_RR; + } + + if (policyhint) { + if (SDL_strcmp(policyhint, "current") == 0) { + /* Leave current thread scheduler policy unchanged */ + } else if (SDL_strcmp(policyhint, "other") == 0) { + policy = SCHED_OTHER; + } else if (SDL_strcmp(policyhint, "rr") == 0) { + policy = SCHED_RR; + } else if (SDL_strcmp(policyhint, "fifo") == 0) { + policy = SCHED_FIFO; + } else { + policy = pri_policy; + } + } else { + policy = pri_policy; + } + +#ifdef __LINUX__ + { + pid_t linuxTid = syscall(SYS_gettid); + return SDL_LinuxSetThreadPriorityAndPolicy(linuxTid, priority, policy); + } +#else + if (priority == SDL_THREAD_PRIORITY_LOW) { + sched.sched_priority = sched_get_priority_min(policy); + } else if (priority == SDL_THREAD_PRIORITY_TIME_CRITICAL) { + sched.sched_priority = sched_get_priority_max(policy); + } else { + int min_priority = sched_get_priority_min(policy); + int max_priority = sched_get_priority_max(policy); + +#if defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__TVOS__) + if (min_priority == 15 && max_priority == 47) { + /* Apple has a specific set of thread priorities */ + if (priority == SDL_THREAD_PRIORITY_HIGH) { + sched.sched_priority = 45; + } else { + sched.sched_priority = 37; + } + } else +#endif /* __MACOSX__ || __IPHONEOS__ || __TVOS__ */ + { + sched.sched_priority = (min_priority + (max_priority - min_priority) / 2); + if (priority == SDL_THREAD_PRIORITY_HIGH) { + sched.sched_priority += ((max_priority - min_priority) / 4); + } + } + } + if (pthread_setschedparam(thread, policy, &sched) != 0) { + return SDL_SetError("pthread_setschedparam() failed"); + } + return 0; +#endif /* linux */ +#endif /* #if __NACL__ || __RISCOS__ */ +} + +void SDL_SYS_WaitThread(SDL_Thread *thread) +{ + pthread_join(thread->handle, 0); +} + +void SDL_SYS_DetachThread(SDL_Thread *thread) +{ + pthread_detach(thread->handle); +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/thread/pthread/SDL_systhread_c.h b/SDL2-2.30.5/src/thread/pthread/SDL_systhread_c.h similarity index 94% rename from SDL2-2.0.12/src/thread/pthread/SDL_systhread_c.h rename to SDL2-2.30.5/src/thread/pthread/SDL_systhread_c.h index 3a9c992..04dbb22 100644 --- a/SDL2-2.0.12/src/thread/pthread/SDL_systhread_c.h +++ b/SDL2-2.30.5/src/thread/pthread/SDL_systhread_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/thread/pthread/SDL_systls.c b/SDL2-2.30.5/src/thread/pthread/SDL_systls.c similarity index 93% rename from SDL2-2.0.12/src/thread/pthread/SDL_systls.c rename to SDL2-2.30.5/src/thread/pthread/SDL_systls.c index e14571c..0618cb3 100644 --- a/SDL2-2.0.12/src/thread/pthread/SDL_systls.c +++ b/SDL2-2.30.5/src/thread/pthread/SDL_systls.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -25,14 +25,12 @@ #include - #define INVALID_PTHREAD_KEY ((pthread_key_t)-1) static pthread_key_t thread_local_storage = INVALID_PTHREAD_KEY; static SDL_bool generic_local_storage = SDL_FALSE; -SDL_TLSData * -SDL_SYS_GetTLSData(void) +SDL_TLSData *SDL_SYS_GetTLSData(void) { if (thread_local_storage == INVALID_PTHREAD_KEY && !generic_local_storage) { static SDL_SpinLock lock; @@ -55,8 +53,7 @@ SDL_SYS_GetTLSData(void) return (SDL_TLSData *)pthread_getspecific(thread_local_storage); } -int -SDL_SYS_SetTLSData(SDL_TLSData *data) +int SDL_SYS_SetTLSData(SDL_TLSData *data) { if (generic_local_storage) { return SDL_Generic_SetTLSData(data); diff --git a/SDL2-2.0.12/src/thread/stdcpp/SDL_syscond.cpp b/SDL2-2.30.5/src/thread/stdcpp/SDL_syscond.cpp similarity index 73% rename from SDL2-2.0.12/src/thread/stdcpp/SDL_syscond.cpp rename to SDL2-2.30.5/src/thread/stdcpp/SDL_syscond.cpp index a500007..561d774 100644 --- a/SDL2-2.0.12/src/thread/stdcpp/SDL_syscond.cpp +++ b/SDL2-2.30.5/src/thread/stdcpp/SDL_syscond.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -37,15 +37,14 @@ struct SDL_cond }; /* Create a condition variable */ -extern "C" -SDL_cond * +extern "C" SDL_cond * SDL_CreateCond(void) { /* Allocate and initialize the condition variable */ try { - SDL_cond * cond = new SDL_cond; + SDL_cond *cond = new SDL_cond; return cond; - } catch (std::system_error & ex) { + } catch (std::system_error &ex) { SDL_SetError("unable to create a C++ condition variable: code=%d; %s", ex.code(), ex.what()); return NULL; } catch (std::bad_alloc &) { @@ -55,9 +54,8 @@ SDL_CreateCond(void) } /* Destroy a condition variable */ -extern "C" -void -SDL_DestroyCond(SDL_cond * cond) +extern "C" void +SDL_DestroyCond(SDL_cond *cond) { if (cond) { delete cond; @@ -65,13 +63,11 @@ SDL_DestroyCond(SDL_cond * cond) } /* Restart one of the threads that are waiting on the condition variable */ -extern "C" -int -SDL_CondSignal(SDL_cond * cond) +extern "C" int +SDL_CondSignal(SDL_cond *cond) { if (!cond) { - SDL_SetError("Passed a NULL condition variable"); - return -1; + return SDL_InvalidParamError("cond"); } cond->cpp_cond.notify_one(); @@ -79,13 +75,11 @@ SDL_CondSignal(SDL_cond * cond) } /* Restart all threads that are waiting on the condition variable */ -extern "C" -int -SDL_CondBroadcast(SDL_cond * cond) +extern "C" int +SDL_CondBroadcast(SDL_cond *cond) { if (!cond) { - SDL_SetError("Passed a NULL condition variable"); - return -1; + return SDL_InvalidParamError("cond"); } cond->cpp_cond.notify_all(); @@ -113,33 +107,28 @@ Thread B: SDL_CondSignal(cond); SDL_UnlockMutex(lock); */ -extern "C" -int -SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms) +extern "C" int +SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms) { - if (!cond) { - SDL_SetError("Passed a NULL condition variable"); - return -1; + if (cond == NULL) { + return SDL_InvalidParamError("cond"); } - if (!mutex) { - SDL_SetError("Passed a NULL mutex variable"); - return -1; + if (mutex == NULL) { + return SDL_InvalidParamError("mutex"); } try { std::unique_lock cpp_lock(mutex->cpp_mutex, std::adopt_lock_t()); if (ms == SDL_MUTEX_MAXWAIT) { cond->cpp_cond.wait( - cpp_lock - ); + cpp_lock); cpp_lock.release(); return 0; } else { auto wait_result = cond->cpp_cond.wait_for( cpp_lock, - std::chrono::duration(ms) - ); + std::chrono::duration(ms)); cpp_lock.release(); if (wait_result == std::cv_status::timeout) { return SDL_MUTEX_TIMEDOUT; @@ -147,16 +136,14 @@ SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms) return 0; } } - } catch (std::system_error & ex) { - SDL_SetError("unable to wait on a C++ condition variable: code=%d; %s", ex.code(), ex.what()); - return -1; + } catch (std::system_error &ex) { + return SDL_SetError("unable to wait on a C++ condition variable: code=%d; %s", ex.code(), ex.what()); } } /* Wait on the condition variable forever */ -extern "C" -int -SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex) +extern "C" int +SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex) { return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT); } diff --git a/SDL2-2.0.12/src/thread/stdcpp/SDL_sysmutex.cpp b/SDL2-2.30.5/src/thread/stdcpp/SDL_sysmutex.cpp similarity index 71% rename from SDL2-2.0.12/src/thread/stdcpp/SDL_sysmutex.cpp rename to SDL2-2.30.5/src/thread/stdcpp/SDL_sysmutex.cpp index 2b134a7..bc04bed 100644 --- a/SDL2-2.0.12/src/thread/stdcpp/SDL_sysmutex.cpp +++ b/SDL2-2.30.5/src/thread/stdcpp/SDL_sysmutex.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,7 +23,6 @@ extern "C" { #include "SDL_thread.h" #include "SDL_systhread_c.h" -#include "SDL_log.h" } #include @@ -31,17 +30,15 @@ extern "C" { #include "SDL_sysmutex_c.h" #include - /* Create a mutex */ -extern "C" -SDL_mutex * +extern "C" SDL_mutex * SDL_CreateMutex(void) { /* Allocate and initialize the mutex */ try { - SDL_mutex * mutex = new SDL_mutex; + SDL_mutex *mutex = new SDL_mutex; return mutex; - } catch (std::system_error & ex) { + } catch (std::system_error &ex) { SDL_SetError("unable to create a C++ mutex: code=%d; %s", ex.code(), ex.what()); return NULL; } catch (std::bad_alloc &) { @@ -51,41 +48,37 @@ SDL_CreateMutex(void) } /* Free the mutex */ -extern "C" -void -SDL_DestroyMutex(SDL_mutex * mutex) +extern "C" void +SDL_DestroyMutex(SDL_mutex *mutex) { if (mutex) { delete mutex; } } -/* Lock the semaphore */ -extern "C" -int -SDL_mutexP(SDL_mutex * mutex) +/* Lock the mutex */ +extern "C" int +SDL_LockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */ { if (mutex == NULL) { - SDL_SetError("Passed a NULL mutex"); - return -1; + return 0; } try { mutex->cpp_mutex.lock(); return 0; - } catch (std::system_error & ex) { - SDL_SetError("unable to lock a C++ mutex: code=%d; %s", ex.code(), ex.what()); - return -1; + } catch (std::system_error &ex) { + return SDL_SetError("unable to lock a C++ mutex: code=%d; %s", ex.code(), ex.what()); } } /* TryLock the mutex */ -int -SDL_TryLockMutex(SDL_mutex * mutex) +int SDL_TryLockMutex(SDL_mutex *mutex) { int retval = 0; - if (mutex == NULL) { - return SDL_SetError("Passed a NULL mutex"); + + if (!mutex) { + return 0; } if (mutex->cpp_mutex.try_lock() == false) { @@ -95,13 +88,11 @@ SDL_TryLockMutex(SDL_mutex * mutex) } /* Unlock the mutex */ -extern "C" -int -SDL_mutexV(SDL_mutex * mutex) +extern "C" int +SDL_UnlockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */ { if (mutex == NULL) { - SDL_SetError("Passed a NULL mutex"); - return -1; + return 0; } mutex->cpp_mutex.unlock(); diff --git a/SDL2-2.0.12/src/thread/stdcpp/SDL_sysmutex_c.h b/SDL2-2.30.5/src/thread/stdcpp/SDL_sysmutex_c.h similarity index 94% rename from SDL2-2.0.12/src/thread/stdcpp/SDL_sysmutex_c.h rename to SDL2-2.30.5/src/thread/stdcpp/SDL_sysmutex_c.h index f86995f..dd53ee8 100644 --- a/SDL2-2.0.12/src/thread/stdcpp/SDL_sysmutex_c.h +++ b/SDL2-2.30.5/src/thread/stdcpp/SDL_sysmutex_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/thread/stdcpp/SDL_systhread.cpp b/SDL2-2.30.5/src/thread/stdcpp/SDL_systhread.cpp similarity index 70% rename from SDL2-2.0.12/src/thread/stdcpp/SDL_systhread.cpp rename to SDL2-2.30.5/src/thread/stdcpp/SDL_systhread.cpp index fc839d3..5b052bf 100644 --- a/SDL2-2.0.12/src/thread/stdcpp/SDL_systhread.cpp +++ b/SDL2-2.30.5/src/thread/stdcpp/SDL_systhread.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,7 +26,6 @@ extern "C" { #include "SDL_thread.h" #include "../SDL_thread_c.h" #include "../SDL_systhread.h" -#include "SDL_log.h" } #include @@ -37,32 +36,27 @@ extern "C" { #include #endif -static void -RunThread(void *args) +static void RunThread(void *args) { - SDL_RunThread(args); + SDL_RunThread((SDL_Thread *)args); } -extern "C" -int -SDL_SYS_CreateThread(SDL_Thread * thread, void *args) +extern "C" int +SDL_SYS_CreateThread(SDL_Thread *thread) { try { // !!! FIXME: no way to set a thread stack size here. - std::thread cpp_thread(RunThread, args); - thread->handle = (void *) new std::thread(std::move(cpp_thread)); + std::thread cpp_thread(RunThread, thread); + thread->handle = (void *)new std::thread(std::move(cpp_thread)); return 0; - } catch (std::system_error & ex) { - SDL_SetError("unable to start a C++ thread: code=%d; %s", ex.code(), ex.what()); - return -1; + } catch (std::system_error &ex) { + return SDL_SetError("unable to start a C++ thread: code=%d; %s", ex.code(), ex.what()); } catch (std::bad_alloc &) { - SDL_OutOfMemory(); - return -1; + return SDL_OutOfMemory(); } } -extern "C" -void +extern "C" void SDL_SYS_SetupThread(const char *name) { // Make sure a thread ID gets assigned ASAP, for debugging purposes: @@ -70,8 +64,7 @@ SDL_SYS_SetupThread(const char *name) return; } -extern "C" -SDL_threadID +extern "C" SDL_threadID SDL_ThreadID(void) { #ifdef __WINRT__ @@ -92,8 +85,7 @@ SDL_ThreadID(void) #endif } -extern "C" -int +extern "C" int SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority) { #ifdef __WINRT__ @@ -101,16 +93,13 @@ SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority) if (priority == SDL_THREAD_PRIORITY_LOW) { value = THREAD_PRIORITY_LOWEST; - } - else if (priority == SDL_THREAD_PRIORITY_HIGH) { + } else if (priority == SDL_THREAD_PRIORITY_HIGH) { value = THREAD_PRIORITY_HIGHEST; - } - else if (priority == SDL_THREAD_PRIORITY_TIME_CRITICAL) { + } else if (priority == SDL_THREAD_PRIORITY_TIME_CRITICAL) { // FIXME: WinRT does not support TIME_CRITICAL! -flibit SDL_LogWarn(SDL_LOG_CATEGORY_SYSTEM, "TIME_CRITICAL unsupported, falling back to HIGHEST"); value = THREAD_PRIORITY_HIGHEST; - } - else { + } else { value = THREAD_PRIORITY_NORMAL; } if (!SetThreadPriority(GetCurrentThread(), value)) { @@ -122,18 +111,21 @@ SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority) #endif } -extern "C" -void -SDL_SYS_WaitThread(SDL_Thread * thread) +extern "C" void +SDL_SYS_WaitThread(SDL_Thread *thread) { - if ( ! thread) { + if (!thread) { return; } try { - std::thread * cpp_thread = (std::thread *) thread->handle; - if (cpp_thread->joinable()) { - cpp_thread->join(); + std::thread *cpp_thread = (std::thread *)thread->handle; + if (cpp_thread) { + if (cpp_thread->joinable()) { + cpp_thread->join(); + } + delete cpp_thread; + thread->handle = nullptr; } } catch (std::system_error &) { // An error occurred when joining the thread. SDL_WaitThread does not, @@ -142,18 +134,21 @@ SDL_SYS_WaitThread(SDL_Thread * thread) } } -extern "C" -void -SDL_SYS_DetachThread(SDL_Thread * thread) +extern "C" void +SDL_SYS_DetachThread(SDL_Thread *thread) { - if ( ! thread) { + if (!thread) { return; } try { - std::thread * cpp_thread = (std::thread *) thread->handle; - if (cpp_thread->joinable()) { - cpp_thread->detach(); + std::thread *cpp_thread = (std::thread *)thread->handle; + if (cpp_thread) { + if (cpp_thread->joinable()) { + cpp_thread->detach(); + } + delete cpp_thread; + thread->handle = nullptr; } } catch (std::system_error &) { // An error occurred when detaching the thread. SDL_DetachThread does not, @@ -162,15 +157,13 @@ SDL_SYS_DetachThread(SDL_Thread * thread) } } -extern "C" -SDL_TLSData * +extern "C" SDL_TLSData * SDL_SYS_GetTLSData(void) { return SDL_Generic_GetTLSData(); } -extern "C" -int +extern "C" int SDL_SYS_SetTLSData(SDL_TLSData *data) { return SDL_Generic_SetTLSData(data); diff --git a/SDL2-2.0.12/src/thread/stdcpp/SDL_systhread_c.h b/SDL2-2.30.5/src/thread/stdcpp/SDL_systhread_c.h similarity index 91% rename from SDL2-2.0.12/src/thread/stdcpp/SDL_systhread_c.h rename to SDL2-2.30.5/src/thread/stdcpp/SDL_systhread_c.h index 919d71c..5cf9d11 100644 --- a/SDL2-2.0.12/src/thread/stdcpp/SDL_systhread_c.h +++ b/SDL2-2.30.5/src/thread/stdcpp/SDL_systhread_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -21,6 +21,6 @@ #include "SDL_config.h" /* For a thread handle, use a void pointer to a std::thread */ -typedef void * SYS_ThreadHandle; +typedef void *SYS_ThreadHandle; /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/thread/vita/SDL_sysmutex.c b/SDL2-2.30.5/src/thread/vita/SDL_sysmutex.c new file mode 100644 index 0000000..b030145 --- /dev/null +++ b/SDL2-2.30.5/src/thread/vita/SDL_sysmutex.c @@ -0,0 +1,144 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_THREAD_VITA + +#include "SDL_thread.h" +#include "SDL_systhread_c.h" + +#include +#include + +struct SDL_mutex +{ + SceKernelLwMutexWork lock; +}; + +/* Create a mutex */ +SDL_mutex *SDL_CreateMutex(void) +{ + SDL_mutex *mutex = NULL; + SceInt32 res = 0; + + /* Allocate mutex memory */ + mutex = (SDL_mutex *)SDL_malloc(sizeof(*mutex)); + if (mutex) { + + res = sceKernelCreateLwMutex( + &mutex->lock, + "SDL mutex", + SCE_KERNEL_MUTEX_ATTR_RECURSIVE, + 0, + NULL); + + if (res < 0) { + SDL_SetError("Error trying to create mutex: %x", res); + } + } else { + SDL_OutOfMemory(); + } + return mutex; +} + +/* Free the mutex */ +void SDL_DestroyMutex(SDL_mutex *mutex) +{ + if (mutex) { + sceKernelDeleteLwMutex(&mutex->lock); + SDL_free(mutex); + } +} + +/* Lock the mutex */ +int SDL_LockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */ +{ +#ifdef SDL_THREADS_DISABLED + return 0; +#else + SceInt32 res = 0; + + if (!mutex) { + return 0; + } + + res = sceKernelLockLwMutex(&mutex->lock, 1, NULL); + if (res != SCE_KERNEL_OK) { + return SDL_SetError("Error trying to lock mutex: %x", res); + } + + return 0; +#endif /* SDL_THREADS_DISABLED */ +} + +/* Try to lock the mutex */ +int SDL_TryLockMutex(SDL_mutex *mutex) +{ +#ifdef SDL_THREADS_DISABLED + return 0; +#else + SceInt32 res = 0; + + if (!mutex) { + return 0; + } + + res = sceKernelTryLockLwMutex(&mutex->lock, 1); + switch (res) { + case SCE_KERNEL_OK: + return 0; + break; + case SCE_KERNEL_ERROR_MUTEX_FAILED_TO_OWN: + return SDL_MUTEX_TIMEDOUT; + break; + default: + return SDL_SetError("Error trying to lock mutex: %x", res); + break; + } + + return -1; +#endif /* SDL_THREADS_DISABLED */ +} + +/* Unlock the mutex */ +int SDL_UnlockMutex(SDL_mutex *mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */ +{ +#ifdef SDL_THREADS_DISABLED + return 0; +#else + SceInt32 res = 0; + + if (mutex == NULL) { + return 0; + } + + res = sceKernelUnlockLwMutex(&mutex->lock, 1); + if (res != 0) { + return SDL_SetError("Error trying to unlock mutex: %x", res); + } + + return 0; +#endif /* SDL_THREADS_DISABLED */ +} + +#endif /* SDL_THREAD_VITA */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/thread/vita/SDL_sysmutex_c.h b/SDL2-2.30.5/src/thread/vita/SDL_sysmutex_c.h new file mode 100644 index 0000000..46b7996 --- /dev/null +++ b/SDL2-2.30.5/src/thread/vita/SDL_sysmutex_c.h @@ -0,0 +1,23 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/thread/vita/SDL_syssem.c b/SDL2-2.30.5/src/thread/vita/SDL_syssem.c new file mode 100644 index 0000000..0149ec3 --- /dev/null +++ b/SDL2-2.30.5/src/thread/vita/SDL_syssem.c @@ -0,0 +1,161 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_THREAD_VITA + +/* Semaphore functions for the VITA. */ + +#include +#include + +#include "SDL_error.h" +#include "SDL_thread.h" + +#include +#include +#include + +struct SDL_semaphore +{ + SceUID semid; +}; + +/* Create a semaphore */ +SDL_sem *SDL_CreateSemaphore(Uint32 initial_value) +{ + SDL_sem *sem; + + sem = (SDL_sem *)SDL_malloc(sizeof(*sem)); + if (sem) { + /* TODO: Figure out the limit on the maximum value. */ + sem->semid = sceKernelCreateSema("SDL sema", 0, initial_value, 255, NULL); + if (sem->semid < 0) { + SDL_SetError("Couldn't create semaphore"); + SDL_free(sem); + sem = NULL; + } + } else { + SDL_OutOfMemory(); + } + + return sem; +} + +/* Free the semaphore */ +void SDL_DestroySemaphore(SDL_sem *sem) +{ + if (sem) { + if (sem->semid > 0) { + sceKernelDeleteSema(sem->semid); + sem->semid = 0; + } + + SDL_free(sem); + } +} + +/* TODO: This routine is a bit overloaded. + * If the timeout is 0 then just poll the semaphore; if it's SDL_MUTEX_MAXWAIT, pass + * NULL to sceKernelWaitSema() so that it waits indefinitely; and if the timeout + * is specified, convert it to microseconds. */ +int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) +{ + Uint32 *pTimeout; + int res; + + if (!sem) { + return SDL_InvalidParamError("sem"); + } + + if (timeout == 0) { + res = sceKernelPollSema(sem->semid, 1); + if (res < 0) { + return SDL_MUTEX_TIMEDOUT; + } + return 0; + } + + if (timeout == SDL_MUTEX_MAXWAIT) { + pTimeout = NULL; + } else { + timeout *= 1000; /* Convert to microseconds. */ + pTimeout = &timeout; + } + + res = sceKernelWaitSema(sem->semid, 1, pTimeout); + switch (res) { + case SCE_KERNEL_OK: + return 0; + case SCE_KERNEL_ERROR_WAIT_TIMEOUT: + return SDL_MUTEX_TIMEDOUT; + default: + return SDL_SetError("WaitForSingleObject() failed"); + } +} + +int SDL_SemTryWait(SDL_sem *sem) +{ + return SDL_SemWaitTimeout(sem, 0); +} + +int SDL_SemWait(SDL_sem *sem) +{ + return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT); +} + +/* Returns the current count of the semaphore */ +Uint32 SDL_SemValue(SDL_sem *sem) +{ + SceKernelSemaInfo info; + info.size = sizeof(info); + + if (!sem) { + SDL_InvalidParamError("sem"); + return 0; + } + + if (sceKernelGetSemaInfo(sem->semid, &info) >= 0) { + return info.currentCount; + } + + return 0; +} + +int SDL_SemPost(SDL_sem *sem) +{ + int res; + + if (!sem) { + return SDL_InvalidParamError("sem"); + } + + res = sceKernelSignalSema(sem->semid, 1); + if (res < 0) { + return SDL_SetError("sceKernelSignalSema() failed"); + } + + return 0; +} + +#endif /* SDL_THREAD_VITA */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/thread/vita/SDL_systhread.c b/SDL2-2.30.5/src/thread/vita/SDL_systhread.c new file mode 100644 index 0000000..5e531b6 --- /dev/null +++ b/SDL2-2.30.5/src/thread/vita/SDL_systhread.c @@ -0,0 +1,137 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_THREAD_VITA + +/* VITA thread management routines for SDL */ + +#include +#include + +#include "SDL_error.h" +#include "SDL_thread.h" +#include "../SDL_systhread.h" +#include "../SDL_thread_c.h" +#include +#include + +#define VITA_THREAD_STACK_SIZE_MIN 0x1000 // 4KiB +#define VITA_THREAD_STACK_SIZE_MAX 0x2000000 // 32MiB +#define VITA_THREAD_STACK_SIZE_DEFAULT 0x10000 // 64KiB +#define VITA_THREAD_NAME_MAX 32 + +#define VITA_THREAD_PRIORITY_LOW 191 +#define VITA_THREAD_PRIORITY_NORMAL 160 +#define VITA_THREAD_PRIORITY_HIGH 112 +#define VITA_THREAD_PRIORITY_TIME_CRITICAL 64 + +static int ThreadEntry(SceSize args, void *argp) +{ + SDL_RunThread(*(SDL_Thread **)argp); + return 0; +} + +int SDL_SYS_CreateThread(SDL_Thread *thread) +{ + char thread_name[VITA_THREAD_NAME_MAX]; + size_t stack_size = VITA_THREAD_STACK_SIZE_DEFAULT; + + SDL_strlcpy(thread_name, "SDL thread", VITA_THREAD_NAME_MAX); + if (thread->name) { + SDL_strlcpy(thread_name, thread->name, VITA_THREAD_NAME_MAX); + } + + if (thread->stacksize) { + if (thread->stacksize < VITA_THREAD_STACK_SIZE_MIN) { + thread->stacksize = VITA_THREAD_STACK_SIZE_MIN; + } + if (thread->stacksize > VITA_THREAD_STACK_SIZE_MAX) { + thread->stacksize = VITA_THREAD_STACK_SIZE_MAX; + } + stack_size = thread->stacksize; + } + + /* Create new thread with the same priority as the current thread */ + thread->handle = sceKernelCreateThread( + thread_name, // name + ThreadEntry, // function to run + 0, // priority. 0 means priority of calling thread + stack_size, // stack size + 0, // attibutes. always 0 + 0, // cpu affinity mask. 0 = all CPUs + NULL // opt. always NULL + ); + + if (thread->handle < 0) { + return SDL_SetError("sceKernelCreateThread() failed"); + } + + sceKernelStartThread(thread->handle, 4, &thread); + return 0; +} + +void SDL_SYS_SetupThread(const char *name) +{ + /* Do nothing. */ +} + +SDL_threadID SDL_ThreadID(void) +{ + return (SDL_threadID)sceKernelGetThreadId(); +} + +void SDL_SYS_WaitThread(SDL_Thread *thread) +{ + sceKernelWaitThreadEnd(thread->handle, NULL, NULL); + sceKernelDeleteThread(thread->handle); +} + +void SDL_SYS_DetachThread(SDL_Thread *thread) +{ + /* Do nothing. */ +} + +int SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority) +{ + int value = VITA_THREAD_PRIORITY_NORMAL; + + switch (priority) { + case SDL_THREAD_PRIORITY_LOW: + value = VITA_THREAD_PRIORITY_LOW; + break; + case SDL_THREAD_PRIORITY_NORMAL: + value = VITA_THREAD_PRIORITY_NORMAL; + break; + case SDL_THREAD_PRIORITY_HIGH: + value = VITA_THREAD_PRIORITY_HIGH; + break; + case SDL_THREAD_PRIORITY_TIME_CRITICAL: + value = VITA_THREAD_PRIORITY_TIME_CRITICAL; + break; + } + + return sceKernelChangeThreadPriority(0, value); +} + +#endif /* SDL_THREAD_VITA */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/thread/vita/SDL_systhread_c.h b/SDL2-2.30.5/src/thread/vita/SDL_systhread_c.h new file mode 100644 index 0000000..7419b1e --- /dev/null +++ b/SDL2-2.30.5/src/thread/vita/SDL_systhread_c.h @@ -0,0 +1,26 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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 + +typedef SceUID SYS_ThreadHandle; + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/thread/windows/SDL_syscond_cv.c b/SDL2-2.30.5/src/thread/windows/SDL_syscond_cv.c new file mode 100644 index 0000000..b532231 --- /dev/null +++ b/SDL2-2.30.5/src/thread/windows/SDL_syscond_cv.c @@ -0,0 +1,287 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_hints.h" +#include "SDL_thread.h" + +#include "../generic/SDL_syscond_c.h" +#include "SDL_sysmutex_c.h" + +typedef SDL_cond *(*pfnSDL_CreateCond)(void); +typedef void (*pfnSDL_DestroyCond)(SDL_cond *); +typedef int (*pfnSDL_CondSignal)(SDL_cond *); +typedef int (*pfnSDL_CondBroadcast)(SDL_cond *); +typedef int (*pfnSDL_CondWait)(SDL_cond *, SDL_mutex *); +typedef int (*pfnSDL_CondWaitTimeout)(SDL_cond *, SDL_mutex *, Uint32); + +typedef struct SDL_cond_impl_t +{ + pfnSDL_CreateCond Create; + pfnSDL_DestroyCond Destroy; + pfnSDL_CondSignal Signal; + pfnSDL_CondBroadcast Broadcast; + pfnSDL_CondWait Wait; + pfnSDL_CondWaitTimeout WaitTimeout; +} SDL_cond_impl_t; + +/* Implementation will be chosen at runtime based on available Kernel features */ +static SDL_cond_impl_t SDL_cond_impl_active = { 0 }; + +/** + * Native Windows Condition Variable (SRW Locks) + */ + +#ifndef CONDITION_VARIABLE_INIT +#define CONDITION_VARIABLE_INIT \ + { \ + 0 \ + } +typedef struct CONDITION_VARIABLE +{ + PVOID Ptr; +} CONDITION_VARIABLE, *PCONDITION_VARIABLE; +#endif + +#ifdef __WINRT__ +#define pWakeConditionVariable WakeConditionVariable +#define pWakeAllConditionVariable WakeAllConditionVariable +#define pSleepConditionVariableSRW SleepConditionVariableSRW +#define pSleepConditionVariableCS SleepConditionVariableCS +#else +typedef VOID(WINAPI *pfnWakeConditionVariable)(PCONDITION_VARIABLE); +typedef VOID(WINAPI *pfnWakeAllConditionVariable)(PCONDITION_VARIABLE); +typedef BOOL(WINAPI *pfnSleepConditionVariableSRW)(PCONDITION_VARIABLE, PSRWLOCK, DWORD, ULONG); +typedef BOOL(WINAPI *pfnSleepConditionVariableCS)(PCONDITION_VARIABLE, PCRITICAL_SECTION, DWORD); + +static pfnWakeConditionVariable pWakeConditionVariable = NULL; +static pfnWakeAllConditionVariable pWakeAllConditionVariable = NULL; +static pfnSleepConditionVariableSRW pSleepConditionVariableSRW = NULL; +static pfnSleepConditionVariableCS pSleepConditionVariableCS = NULL; +#endif + +typedef struct SDL_cond_cv +{ + CONDITION_VARIABLE cond; +} SDL_cond_cv; + +static SDL_cond *SDL_CreateCond_cv(void) +{ + SDL_cond_cv *cond; + + /* Relies on CONDITION_VARIABLE_INIT == 0. */ + cond = (SDL_cond_cv *)SDL_calloc(1, sizeof(*cond)); + if (!cond) { + SDL_OutOfMemory(); + } + + return (SDL_cond *)cond; +} + +static void SDL_DestroyCond_cv(SDL_cond *cond) +{ + if (cond) { + /* There are no kernel allocated resources */ + SDL_free(cond); + } +} + +static int SDL_CondSignal_cv(SDL_cond *_cond) +{ + SDL_cond_cv *cond = (SDL_cond_cv *)_cond; + if (!cond) { + return SDL_InvalidParamError("cond"); + } + + pWakeConditionVariable(&cond->cond); + + return 0; +} + +static int SDL_CondBroadcast_cv(SDL_cond *_cond) +{ + SDL_cond_cv *cond = (SDL_cond_cv *)_cond; + if (!cond) { + return SDL_InvalidParamError("cond"); + } + + pWakeAllConditionVariable(&cond->cond); + + return 0; +} + +static int SDL_CondWaitTimeout_cv(SDL_cond *_cond, SDL_mutex *_mutex, Uint32 ms) +{ + SDL_cond_cv *cond = (SDL_cond_cv *)_cond; + DWORD timeout; + int ret; + + if (!cond) { + return SDL_InvalidParamError("cond"); + } + if (!_mutex) { + return SDL_InvalidParamError("mutex"); + } + + if (ms == SDL_MUTEX_MAXWAIT) { + timeout = INFINITE; + } else { + timeout = (DWORD)ms; + } + + if (SDL_mutex_impl_active.Type == SDL_MUTEX_SRW) { + SDL_mutex_srw *mutex = (SDL_mutex_srw *)_mutex; + + if (mutex->count != 1 || mutex->owner != GetCurrentThreadId()) { + return SDL_SetError("Passed mutex is not locked or locked recursively"); + } + + /* The mutex must be updated to the released state */ + mutex->count = 0; + mutex->owner = 0; + + if (pSleepConditionVariableSRW(&cond->cond, &mutex->srw, timeout, 0) == FALSE) { + if (GetLastError() == ERROR_TIMEOUT) { + ret = SDL_MUTEX_TIMEDOUT; + } else { + ret = SDL_SetError("SleepConditionVariableSRW() failed"); + } + } else { + ret = 0; + } + + /* The mutex is owned by us again, regardless of status of the wait */ + SDL_assert(mutex->count == 0 && mutex->owner == 0); + mutex->count = 1; + mutex->owner = GetCurrentThreadId(); + } else { + SDL_mutex_cs *mutex = (SDL_mutex_cs *)_mutex; + + SDL_assert(SDL_mutex_impl_active.Type == SDL_MUTEX_CS); + + if (pSleepConditionVariableCS(&cond->cond, &mutex->cs, timeout) == FALSE) { + if (GetLastError() == ERROR_TIMEOUT) { + ret = SDL_MUTEX_TIMEDOUT; + } else { + ret = SDL_SetError("SleepConditionVariableCS() failed"); + } + } else { + ret = 0; + } + } + + return ret; +} + +static int SDL_CondWait_cv(SDL_cond *cond, SDL_mutex *mutex) +{ + return SDL_CondWaitTimeout_cv(cond, mutex, SDL_MUTEX_MAXWAIT); +} + +static const SDL_cond_impl_t SDL_cond_impl_cv = { + &SDL_CreateCond_cv, + &SDL_DestroyCond_cv, + &SDL_CondSignal_cv, + &SDL_CondBroadcast_cv, + &SDL_CondWait_cv, + &SDL_CondWaitTimeout_cv, +}; + +/** + * Generic Condition Variable implementation using SDL_mutex and SDL_sem + */ + +static const SDL_cond_impl_t SDL_cond_impl_generic = { + &SDL_CreateCond_generic, + &SDL_DestroyCond_generic, + &SDL_CondSignal_generic, + &SDL_CondBroadcast_generic, + &SDL_CondWait_generic, + &SDL_CondWaitTimeout_generic, +}; + +SDL_cond *SDL_CreateCond(void) +{ + if (!SDL_cond_impl_active.Create) { + /* Default to generic implementation, works with all mutex implementations */ + const SDL_cond_impl_t *impl = &SDL_cond_impl_generic; + + if (SDL_mutex_impl_active.Type == SDL_MUTEX_INVALID) { + /* The mutex implementation isn't decided yet, trigger it */ + SDL_mutex *mutex = SDL_CreateMutex(); + if (!mutex) { + return NULL; + } + SDL_DestroyMutex(mutex); + + SDL_assert(SDL_mutex_impl_active.Type != SDL_MUTEX_INVALID); + } + +#ifdef __WINRT__ + /* Link statically on this platform */ + impl = &SDL_cond_impl_cv; +#else + { + HMODULE kernel32 = GetModuleHandle(TEXT("kernel32.dll")); + if (kernel32) { + pWakeConditionVariable = (pfnWakeConditionVariable)GetProcAddress(kernel32, "WakeConditionVariable"); + pWakeAllConditionVariable = (pfnWakeAllConditionVariable)GetProcAddress(kernel32, "WakeAllConditionVariable"); + pSleepConditionVariableSRW = (pfnSleepConditionVariableSRW)GetProcAddress(kernel32, "SleepConditionVariableSRW"); + pSleepConditionVariableCS = (pfnSleepConditionVariableCS)GetProcAddress(kernel32, "SleepConditionVariableCS"); + if (pWakeConditionVariable && pWakeAllConditionVariable && pSleepConditionVariableSRW && pSleepConditionVariableCS) { + /* Use the Windows provided API */ + impl = &SDL_cond_impl_cv; + } + } + } +#endif + + SDL_copyp(&SDL_cond_impl_active, impl); + } + return SDL_cond_impl_active.Create(); +} + +void SDL_DestroyCond(SDL_cond *cond) +{ + SDL_cond_impl_active.Destroy(cond); +} + +int SDL_CondSignal(SDL_cond *cond) +{ + return SDL_cond_impl_active.Signal(cond); +} + +int SDL_CondBroadcast(SDL_cond *cond) +{ + return SDL_cond_impl_active.Broadcast(cond); +} + +int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms) +{ + return SDL_cond_impl_active.WaitTimeout(cond, mutex, ms); +} + +int SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex) +{ + return SDL_cond_impl_active.Wait(cond, mutex); +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/thread/windows/SDL_sysmutex.c b/SDL2-2.30.5/src/thread/windows/SDL_sysmutex.c new file mode 100644 index 0000000..71cdac9 --- /dev/null +++ b/SDL2-2.30.5/src/thread/windows/SDL_sysmutex.c @@ -0,0 +1,290 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_THREAD_WINDOWS + +/** + * Mutex functions using the Win32 API + * There are two implementations available based on: + * - Critical Sections. Available on all OS versions since Windows XP. + * - Slim Reader/Writer Locks. Requires Windows 7 or newer. + * which are chosen at runtime. + */ + + +#include "SDL_hints.h" + +#include "SDL_sysmutex_c.h" + +/* Implementation will be chosen at runtime based on available Kernel features */ +SDL_mutex_impl_t SDL_mutex_impl_active = { 0 }; + +/** + * Implementation based on Slim Reader/Writer (SRW) Locks for Win 7 and newer. + */ + +#ifdef __WINRT__ +/* Functions are guaranteed to be available */ +#define pReleaseSRWLockExclusive ReleaseSRWLockExclusive +#define pAcquireSRWLockExclusive AcquireSRWLockExclusive +#define pTryAcquireSRWLockExclusive TryAcquireSRWLockExclusive +#else +typedef VOID(WINAPI *pfnReleaseSRWLockExclusive)(PSRWLOCK); +typedef VOID(WINAPI *pfnAcquireSRWLockExclusive)(PSRWLOCK); +typedef BOOLEAN(WINAPI *pfnTryAcquireSRWLockExclusive)(PSRWLOCK); +static pfnReleaseSRWLockExclusive pReleaseSRWLockExclusive = NULL; +static pfnAcquireSRWLockExclusive pAcquireSRWLockExclusive = NULL; +static pfnTryAcquireSRWLockExclusive pTryAcquireSRWLockExclusive = NULL; +#endif + +static SDL_mutex *SDL_CreateMutex_srw(void) +{ + SDL_mutex_srw *mutex; + + /* Relies on SRWLOCK_INIT == 0. */ + mutex = (SDL_mutex_srw *)SDL_calloc(1, sizeof(*mutex)); + if (!mutex) { + SDL_OutOfMemory(); + } + + return (SDL_mutex *)mutex; +} + +static void SDL_DestroyMutex_srw(SDL_mutex *mutex) +{ + /* There are no kernel allocated resources */ + SDL_free(mutex); +} + +static int SDL_LockMutex_srw(SDL_mutex *_mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */ +{ + SDL_mutex_srw *mutex = (SDL_mutex_srw *)_mutex; + DWORD this_thread; + + this_thread = GetCurrentThreadId(); + if (mutex->owner == this_thread) { + ++mutex->count; + } else { + /* The order of operations is important. + We set the locking thread id after we obtain the lock + so unlocks from other threads will fail. + */ + pAcquireSRWLockExclusive(&mutex->srw); + SDL_assert(mutex->count == 0 && mutex->owner == 0); + mutex->owner = this_thread; + mutex->count = 1; + } + return 0; +} + +static int SDL_TryLockMutex_srw(SDL_mutex *_mutex) +{ + SDL_mutex_srw *mutex = (SDL_mutex_srw *)_mutex; + DWORD this_thread; + int retval = 0; + + this_thread = GetCurrentThreadId(); + if (mutex->owner == this_thread) { + ++mutex->count; + } else { + if (pTryAcquireSRWLockExclusive(&mutex->srw) != 0) { + SDL_assert(mutex->count == 0 && mutex->owner == 0); + mutex->owner = this_thread; + mutex->count = 1; + } else { + retval = SDL_MUTEX_TIMEDOUT; + } + } + return retval; +} + +static int SDL_UnlockMutex_srw(SDL_mutex *_mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */ +{ + SDL_mutex_srw *mutex = (SDL_mutex_srw *)_mutex; + + if (mutex->owner == GetCurrentThreadId()) { + if (--mutex->count == 0) { + mutex->owner = 0; + pReleaseSRWLockExclusive(&mutex->srw); + } + } else { + return SDL_SetError("mutex not owned by this thread"); + } + + return 0; +} + +static const SDL_mutex_impl_t SDL_mutex_impl_srw = { + &SDL_CreateMutex_srw, + &SDL_DestroyMutex_srw, + &SDL_LockMutex_srw, + &SDL_TryLockMutex_srw, + &SDL_UnlockMutex_srw, + SDL_MUTEX_SRW, +}; + +/** + * Fallback Mutex implementation using Critical Sections (before Win 7) + */ + +/* Create a mutex */ +static SDL_mutex *SDL_CreateMutex_cs(void) +{ + SDL_mutex_cs *mutex; + + /* Allocate mutex memory */ + mutex = (SDL_mutex_cs *)SDL_malloc(sizeof(*mutex)); + if (mutex) { + /* Initialize */ + /* On SMP systems, a non-zero spin count generally helps performance */ +#ifdef __WINRT__ + InitializeCriticalSectionEx(&mutex->cs, 2000, 0); +#else + InitializeCriticalSectionAndSpinCount(&mutex->cs, 2000); +#endif + } else { + SDL_OutOfMemory(); + } + return (SDL_mutex *)mutex; +} + +/* Free the mutex */ +static void SDL_DestroyMutex_cs(SDL_mutex *mutex_) +{ + SDL_mutex_cs *mutex = (SDL_mutex_cs *)mutex_; + + DeleteCriticalSection(&mutex->cs); + SDL_free(mutex); +} + +/* Lock the mutex */ +static int SDL_LockMutex_cs(SDL_mutex *mutex_) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */ +{ + SDL_mutex_cs *mutex = (SDL_mutex_cs *)mutex_; + + EnterCriticalSection(&mutex->cs); + return 0; +} + +/* TryLock the mutex */ +static int SDL_TryLockMutex_cs(SDL_mutex *mutex_) +{ + SDL_mutex_cs *mutex = (SDL_mutex_cs *)mutex_; + int retval = 0; + + if (TryEnterCriticalSection(&mutex->cs) == 0) { + retval = SDL_MUTEX_TIMEDOUT; + } + return retval; +} + +/* Unlock the mutex */ +static int SDL_UnlockMutex_cs(SDL_mutex *mutex_) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */ +{ + SDL_mutex_cs *mutex = (SDL_mutex_cs *)mutex_; + + LeaveCriticalSection(&mutex->cs); + return 0; +} + +static const SDL_mutex_impl_t SDL_mutex_impl_cs = { + &SDL_CreateMutex_cs, + &SDL_DestroyMutex_cs, + &SDL_LockMutex_cs, + &SDL_TryLockMutex_cs, + &SDL_UnlockMutex_cs, + SDL_MUTEX_CS, +}; + +/** + * Runtime selection and redirection + */ + +SDL_mutex *SDL_CreateMutex(void) +{ + if (!SDL_mutex_impl_active.Create) { + /* Default to fallback implementation */ + const SDL_mutex_impl_t *impl = &SDL_mutex_impl_cs; + + if (!SDL_GetHintBoolean(SDL_HINT_WINDOWS_FORCE_MUTEX_CRITICAL_SECTIONS, SDL_FALSE)) { +#ifdef __WINRT__ + /* Link statically on this platform */ + impl = &SDL_mutex_impl_srw; +#else + /* Try faster implementation for Windows 7 and newer */ + HMODULE kernel32 = GetModuleHandle(TEXT("kernel32.dll")); + if (kernel32) { + /* Requires Vista: */ + pReleaseSRWLockExclusive = (pfnReleaseSRWLockExclusive)GetProcAddress(kernel32, "ReleaseSRWLockExclusive"); + pAcquireSRWLockExclusive = (pfnAcquireSRWLockExclusive)GetProcAddress(kernel32, "AcquireSRWLockExclusive"); + /* Requires 7: */ + pTryAcquireSRWLockExclusive = (pfnTryAcquireSRWLockExclusive)GetProcAddress(kernel32, "TryAcquireSRWLockExclusive"); + if (pReleaseSRWLockExclusive && pAcquireSRWLockExclusive && pTryAcquireSRWLockExclusive) { + impl = &SDL_mutex_impl_srw; + } + } +#endif + } + + /* Copy instead of using pointer to save one level of indirection */ + SDL_copyp(&SDL_mutex_impl_active, impl); + } + return SDL_mutex_impl_active.Create(); +} + +void SDL_DestroyMutex(SDL_mutex *mutex) +{ + if (mutex) { + SDL_mutex_impl_active.Destroy(mutex); + } +} + +int SDL_LockMutex(SDL_mutex *mutex) +{ + if (!mutex) { + return 0; + } + + return SDL_mutex_impl_active.Lock(mutex); +} + +int SDL_TryLockMutex(SDL_mutex *mutex) +{ + if (!mutex) { + return 0; + } + + return SDL_mutex_impl_active.TryLock(mutex); +} + +int SDL_UnlockMutex(SDL_mutex *mutex) +{ + if (!mutex) { + return 0; + } + + return SDL_mutex_impl_active.Unlock(mutex); +} + +#endif /* SDL_THREAD_WINDOWS */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/thread/windows/SDL_sysmutex_c.h b/SDL2-2.30.5/src/thread/windows/SDL_sysmutex_c.h new file mode 100644 index 0000000..6a0f45f --- /dev/null +++ b/SDL2-2.30.5/src/thread/windows/SDL_sysmutex_c.h @@ -0,0 +1,77 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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 "../../core/windows/SDL_windows.h" + +#include "SDL_mutex.h" + +typedef SDL_mutex * (*pfnSDL_CreateMutex)(void); +typedef int (*pfnSDL_LockMutex)(SDL_mutex *); +typedef int (*pfnSDL_TryLockMutex)(SDL_mutex *); +typedef int (*pfnSDL_UnlockMutex)(SDL_mutex *); +typedef void (*pfnSDL_DestroyMutex)(SDL_mutex *); + +typedef enum +{ + SDL_MUTEX_INVALID = 0, + SDL_MUTEX_SRW, + SDL_MUTEX_CS, +} SDL_MutexType; + +typedef struct SDL_mutex_impl_t +{ + pfnSDL_CreateMutex Create; + pfnSDL_DestroyMutex Destroy; + pfnSDL_LockMutex Lock; + pfnSDL_TryLockMutex TryLock; + pfnSDL_UnlockMutex Unlock; + /* Needed by SDL_cond: */ + SDL_MutexType Type; +} SDL_mutex_impl_t; + +extern SDL_mutex_impl_t SDL_mutex_impl_active; + +#ifndef SRWLOCK_INIT +#define SRWLOCK_INIT \ + { \ + 0 \ + } +typedef struct _SRWLOCK +{ + PVOID Ptr; +} SRWLOCK, *PSRWLOCK; +#endif + +typedef struct SDL_mutex_srw +{ + SRWLOCK srw; + /* SRW Locks are not recursive, that has to be handled by SDL: */ + DWORD count; + DWORD owner; +} SDL_mutex_srw; + +typedef struct SDL_mutex_cs +{ + CRITICAL_SECTION cs; +} SDL_mutex_cs; + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/thread/windows/SDL_syssem.c b/SDL2-2.30.5/src/thread/windows/SDL_syssem.c new file mode 100644 index 0000000..4c59fc1 --- /dev/null +++ b/SDL2-2.30.5/src/thread/windows/SDL_syssem.c @@ -0,0 +1,444 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_THREAD_WINDOWS + +/** + * Semaphore functions using the Win32 API + * There are two implementations available based on: + * - Kernel Semaphores. Available on all OS versions. (kern) + * Heavy-weight inter-process kernel objects. + * - Atomics and WaitOnAddress API. (atom) + * Faster due to significantly less context switches. + * Requires Windows 8 or newer. + * which are chosen at runtime. + */ + +#include "../../core/windows/SDL_windows.h" + +#include "SDL_hints.h" +#include "SDL_thread.h" +#include "SDL_timer.h" + +typedef SDL_sem * (*pfnSDL_CreateSemaphore)(Uint32); +typedef void (*pfnSDL_DestroySemaphore)(SDL_sem *); +typedef int (*pfnSDL_SemWaitTimeout)(SDL_sem *, Uint32); +typedef int (*pfnSDL_SemTryWait)(SDL_sem *); +typedef int (*pfnSDL_SemWait)(SDL_sem *); +typedef Uint32 (*pfnSDL_SemValue)(SDL_sem *); +typedef int (*pfnSDL_SemPost)(SDL_sem *); + +typedef struct SDL_semaphore_impl_t +{ + pfnSDL_CreateSemaphore Create; + pfnSDL_DestroySemaphore Destroy; + pfnSDL_SemWaitTimeout WaitTimeout; + pfnSDL_SemTryWait TryWait; + pfnSDL_SemWait Wait; + pfnSDL_SemValue Value; + pfnSDL_SemPost Post; +} SDL_sem_impl_t; + +/* Implementation will be chosen at runtime based on available Kernel features */ +static SDL_sem_impl_t SDL_sem_impl_active = { 0 }; + +/** + * Atomic + WaitOnAddress implementation + */ + +/* APIs not available on WinPhone 8.1 */ +/* https://www.microsoft.com/en-us/download/details.aspx?id=47328 */ + +#if !SDL_WINAPI_FAMILY_PHONE +#ifdef __WINRT__ +/* Functions are guaranteed to be available */ +#define pWaitOnAddress WaitOnAddress +#define pWakeByAddressSingle WakeByAddressSingle +#else +typedef BOOL(WINAPI *pfnWaitOnAddress)(volatile VOID *, PVOID, SIZE_T, DWORD); +typedef VOID(WINAPI *pfnWakeByAddressSingle)(PVOID); + +static pfnWaitOnAddress pWaitOnAddress = NULL; +static pfnWakeByAddressSingle pWakeByAddressSingle = NULL; +#endif + +typedef struct SDL_semaphore_atom +{ + LONG count; +} SDL_sem_atom; + +static SDL_sem *SDL_CreateSemaphore_atom(Uint32 initial_value) +{ + SDL_sem_atom *sem; + + sem = (SDL_sem_atom *)SDL_malloc(sizeof(*sem)); + if (sem) { + sem->count = initial_value; + } else { + SDL_OutOfMemory(); + } + return (SDL_sem *)sem; +} + +static void SDL_DestroySemaphore_atom(SDL_sem *sem) +{ + if (sem) { + SDL_free(sem); + } +} + +static int SDL_SemTryWait_atom(SDL_sem *_sem) +{ + SDL_sem_atom *sem = (SDL_sem_atom *)_sem; + LONG count; + + if (!sem) { + return SDL_InvalidParamError("sem"); + } + + count = sem->count; + if (count == 0) { + return SDL_MUTEX_TIMEDOUT; + } + + if (InterlockedCompareExchange(&sem->count, count - 1, count) == count) { + return 0; + } + + return SDL_MUTEX_TIMEDOUT; +} + +static int SDL_SemWait_atom(SDL_sem *_sem) +{ + SDL_sem_atom *sem = (SDL_sem_atom *)_sem; + LONG count; + + if (!sem) { + return SDL_InvalidParamError("sem"); + } + + for (;;) { + count = sem->count; + while (count == 0) { + if (pWaitOnAddress(&sem->count, &count, sizeof(sem->count), INFINITE) == FALSE) { + return SDL_SetError("WaitOnAddress() failed"); + } + count = sem->count; + } + + if (InterlockedCompareExchange(&sem->count, count - 1, count) == count) { + return 0; + } + } +} + +static int SDL_SemWaitTimeout_atom(SDL_sem *_sem, Uint32 timeout) +{ + SDL_sem_atom *sem = (SDL_sem_atom *)_sem; + LONG count; + Uint32 now; + Uint32 deadline; + DWORD timeout_eff; + + if (timeout == SDL_MUTEX_MAXWAIT) { + return SDL_SemWait_atom(_sem); + } + + if (!sem) { + return SDL_InvalidParamError("sem"); + } + + /** + * WaitOnAddress is subject to spurious and stolen wakeups so we + * need to recalculate the effective timeout before every wait + */ + now = SDL_GetTicks(); + deadline = now + (DWORD)timeout; + + for (;;) { + count = sem->count; + /* If no semaphore is available we need to wait */ + while (count == 0) { + now = SDL_GetTicks(); + if (deadline > now) { + timeout_eff = deadline - now; + } else { + return SDL_MUTEX_TIMEDOUT; + } + if (pWaitOnAddress(&sem->count, &count, sizeof(count), timeout_eff) == FALSE) { + if (GetLastError() == ERROR_TIMEOUT) { + return SDL_MUTEX_TIMEDOUT; + } + return SDL_SetError("WaitOnAddress() failed"); + } + count = sem->count; + } + + /* Actually the semaphore is only consumed if this succeeds */ + /* If it doesn't we need to do everything again */ + if (InterlockedCompareExchange(&sem->count, count - 1, count) == count) { + return 0; + } + } +} + +static Uint32 SDL_SemValue_atom(SDL_sem *_sem) +{ + SDL_sem_atom *sem = (SDL_sem_atom *)_sem; + + if (!sem) { + SDL_InvalidParamError("sem"); + return 0; + } + + return (Uint32)sem->count; +} + +static int SDL_SemPost_atom(SDL_sem *_sem) +{ + SDL_sem_atom *sem = (SDL_sem_atom *)_sem; + + if (!sem) { + return SDL_InvalidParamError("sem"); + } + + InterlockedIncrement(&sem->count); + pWakeByAddressSingle(&sem->count); + + return 0; +} + +static const SDL_sem_impl_t SDL_sem_impl_atom = { + &SDL_CreateSemaphore_atom, + &SDL_DestroySemaphore_atom, + &SDL_SemWaitTimeout_atom, + &SDL_SemTryWait_atom, + &SDL_SemWait_atom, + &SDL_SemValue_atom, + &SDL_SemPost_atom, +}; +#endif /* !SDL_WINAPI_FAMILY_PHONE */ + +/** + * Fallback Semaphore implementation using Kernel Semaphores + */ + +typedef struct SDL_semaphore_kern +{ + HANDLE id; + LONG count; +} SDL_sem_kern; + +/* Create a semaphore */ +static SDL_sem *SDL_CreateSemaphore_kern(Uint32 initial_value) +{ + SDL_sem_kern *sem; + + /* Allocate sem memory */ + sem = (SDL_sem_kern *)SDL_malloc(sizeof(*sem)); + if (sem) { + /* Create the semaphore, with max value 32K */ +#ifdef __WINRT__ + sem->id = CreateSemaphoreEx(NULL, initial_value, 32 * 1024, NULL, 0, SEMAPHORE_ALL_ACCESS); +#else + sem->id = CreateSemaphore(NULL, initial_value, 32 * 1024, NULL); +#endif + sem->count = initial_value; + if (!sem->id) { + SDL_SetError("Couldn't create semaphore"); + SDL_free(sem); + sem = NULL; + } + } else { + SDL_OutOfMemory(); + } + return (SDL_sem *)sem; +} + +/* Free the semaphore */ +static void SDL_DestroySemaphore_kern(SDL_sem *_sem) +{ + SDL_sem_kern *sem = (SDL_sem_kern *)_sem; + if (sem) { + if (sem->id) { + CloseHandle(sem->id); + sem->id = 0; + } + SDL_free(sem); + } +} + +static int SDL_SemWaitTimeout_kern(SDL_sem *_sem, Uint32 timeout) +{ + SDL_sem_kern *sem = (SDL_sem_kern *)_sem; + int retval; + DWORD dwMilliseconds; + + if (!sem) { + return SDL_InvalidParamError("sem"); + } + + if (timeout == SDL_MUTEX_MAXWAIT) { + dwMilliseconds = INFINITE; + } else { + dwMilliseconds = (DWORD)timeout; + } + switch (WaitForSingleObjectEx(sem->id, dwMilliseconds, FALSE)) { + case WAIT_OBJECT_0: + InterlockedDecrement(&sem->count); + retval = 0; + break; + case WAIT_TIMEOUT: + retval = SDL_MUTEX_TIMEDOUT; + break; + default: + retval = SDL_SetError("WaitForSingleObject() failed"); + break; + } + return retval; +} + +static int SDL_SemTryWait_kern(SDL_sem *sem) +{ + return SDL_SemWaitTimeout_kern(sem, 0); +} + +static int SDL_SemWait_kern(SDL_sem *sem) +{ + return SDL_SemWaitTimeout_kern(sem, SDL_MUTEX_MAXWAIT); +} + +/* Returns the current count of the semaphore */ +static Uint32 SDL_SemValue_kern(SDL_sem *_sem) +{ + SDL_sem_kern *sem = (SDL_sem_kern *)_sem; + if (!sem) { + SDL_InvalidParamError("sem"); + return 0; + } + return (Uint32)sem->count; +} + +static int SDL_SemPost_kern(SDL_sem *_sem) +{ + SDL_sem_kern *sem = (SDL_sem_kern *)_sem; + if (!sem) { + return SDL_InvalidParamError("sem"); + } + /* Increase the counter in the first place, because + * after a successful release the semaphore may + * immediately get destroyed by another thread which + * is waiting for this semaphore. + */ + InterlockedIncrement(&sem->count); + if (ReleaseSemaphore(sem->id, 1, NULL) == FALSE) { + InterlockedDecrement(&sem->count); /* restore */ + return SDL_SetError("ReleaseSemaphore() failed"); + } + return 0; +} + +static const SDL_sem_impl_t SDL_sem_impl_kern = { + &SDL_CreateSemaphore_kern, + &SDL_DestroySemaphore_kern, + &SDL_SemWaitTimeout_kern, + &SDL_SemTryWait_kern, + &SDL_SemWait_kern, + &SDL_SemValue_kern, + &SDL_SemPost_kern, +}; + +/** + * Runtime selection and redirection + */ + +SDL_sem *SDL_CreateSemaphore(Uint32 initial_value) +{ + if (!SDL_sem_impl_active.Create) { + /* Default to fallback implementation */ + const SDL_sem_impl_t *impl = &SDL_sem_impl_kern; + +#if !SDL_WINAPI_FAMILY_PHONE + if (!SDL_GetHintBoolean(SDL_HINT_WINDOWS_FORCE_SEMAPHORE_KERNEL, SDL_FALSE)) { +#ifdef __WINRT__ + /* Link statically on this platform */ + impl = &SDL_sem_impl_atom; +#else + /* We already statically link to features from this Api + * Set (e.g. WaitForSingleObject). Dynamically loading + * API Sets is not explicitly documented but according to + * Microsoft our specific use case is legal and correct: + * https://github.com/microsoft/STL/pull/593#issuecomment-655799859 + */ + HMODULE synch120 = GetModuleHandle(TEXT("api-ms-win-core-synch-l1-2-0.dll")); + if (synch120) { + /* Try to load required functions provided by Win 8 or newer */ + pWaitOnAddress = (pfnWaitOnAddress)GetProcAddress(synch120, "WaitOnAddress"); + pWakeByAddressSingle = (pfnWakeByAddressSingle)GetProcAddress(synch120, "WakeByAddressSingle"); + + if (pWaitOnAddress && pWakeByAddressSingle) { + impl = &SDL_sem_impl_atom; + } + } +#endif + } +#endif + + /* Copy instead of using pointer to save one level of indirection */ + SDL_copyp(&SDL_sem_impl_active, impl); + } + return SDL_sem_impl_active.Create(initial_value); +} + +void SDL_DestroySemaphore(SDL_sem *sem) +{ + SDL_sem_impl_active.Destroy(sem); +} + +int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) +{ + return SDL_sem_impl_active.WaitTimeout(sem, timeout); +} + +int SDL_SemTryWait(SDL_sem *sem) +{ + return SDL_sem_impl_active.TryWait(sem); +} + +int SDL_SemWait(SDL_sem *sem) +{ + return SDL_sem_impl_active.Wait(sem); +} + +Uint32 SDL_SemValue(SDL_sem *sem) +{ + return SDL_sem_impl_active.Value(sem); +} + +int SDL_SemPost(SDL_sem *sem) +{ + return SDL_sem_impl_active.Post(sem); +} + +#endif /* SDL_THREAD_WINDOWS */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/thread/windows/SDL_systhread.c b/SDL2-2.30.5/src/thread/windows/SDL_systhread.c similarity index 51% rename from SDL2-2.0.12/src/thread/windows/SDL_systhread.c rename to SDL2-2.30.5/src/thread/windows/SDL_systhread.c index a5e4e35..974759b 100644 --- a/SDL2-2.0.12/src/thread/windows/SDL_systhread.c +++ b/SDL2-2.30.5/src/thread/windows/SDL_systhread.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_THREAD_WINDOWS +#ifdef SDL_THREAD_WINDOWS /* Win32 thread management routines for SDL */ @@ -30,166 +30,114 @@ #include "../SDL_systhread.h" #include "SDL_systhread_c.h" -#ifndef SDL_PASSED_BEGINTHREAD_ENDTHREAD -/* We'll use the C library from this DLL */ -#include - #ifndef STACK_SIZE_PARAM_IS_A_RESERVATION #define STACK_SIZE_PARAM_IS_A_RESERVATION 0x00010000 #endif -/* Cygwin gcc-3 ... MingW64 (even with a i386 host) does this like MSVC. */ -#if (defined(__MINGW32__) && (__GNUC__ < 4)) -typedef unsigned long (__cdecl *pfnSDL_CurrentBeginThread) (void *, unsigned, - unsigned (__stdcall *func)(void *), void *arg, - unsigned, unsigned *threadID); -typedef void (__cdecl *pfnSDL_CurrentEndThread)(unsigned code); - -#elif defined(__WATCOMC__) -/* This is for Watcom targets except OS2 */ -#if __WATCOMC__ < 1240 -#define __watcall -#endif -typedef unsigned long (__watcall * pfnSDL_CurrentBeginThread) (void *, - unsigned, - unsigned - (__stdcall * - func) (void - *), - void *arg, - unsigned, - unsigned - *threadID); -typedef void (__watcall * pfnSDL_CurrentEndThread) (unsigned code); - -#else -typedef uintptr_t(__cdecl * pfnSDL_CurrentBeginThread) (void *, unsigned, - unsigned (__stdcall * - func) (void - *), - void *arg, unsigned, - unsigned *threadID); -typedef void (__cdecl * pfnSDL_CurrentEndThread) (unsigned code); -#endif +#ifndef SDL_PASSED_BEGINTHREAD_ENDTHREAD +/* We'll use the C library from this DLL */ +#include +typedef uintptr_t(__cdecl *pfnSDL_CurrentBeginThread)(void *, unsigned, + unsigned(__stdcall *func)(void*), + void *arg, unsigned, + unsigned *threadID); +typedef void(__cdecl *pfnSDL_CurrentEndThread)(unsigned code); #endif /* !SDL_PASSED_BEGINTHREAD_ENDTHREAD */ - -typedef struct ThreadStartParms +static DWORD RunThread(void *data) { - void *args; - pfnSDL_CurrentEndThread pfnCurrentEndThread; -} tThreadStartParms, *pThreadStartParms; - -static DWORD -RunThread(void *data) -{ - pThreadStartParms pThreadParms = (pThreadStartParms) data; - pfnSDL_CurrentEndThread pfnEndThread = pThreadParms->pfnCurrentEndThread; - void *args = pThreadParms->args; - SDL_free(pThreadParms); - SDL_RunThread(args); - if (pfnEndThread != NULL) + SDL_Thread *thread = (SDL_Thread *)data; + pfnSDL_CurrentEndThread pfnEndThread = (pfnSDL_CurrentEndThread)thread->endfunc; + SDL_RunThread(thread); + if (pfnEndThread) { pfnEndThread(0); - return (0); + } + return 0; } -static DWORD WINAPI -RunThreadViaCreateThread(LPVOID data) +static DWORD WINAPI MINGW32_FORCEALIGN RunThreadViaCreateThread(LPVOID data) { - return RunThread(data); + return RunThread(data); } -static unsigned __stdcall -RunThreadViaBeginThreadEx(void *data) +static unsigned __stdcall MINGW32_FORCEALIGN RunThreadViaBeginThreadEx(void *data) { - return (unsigned) RunThread(data); + return (unsigned)RunThread(data); } #ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD -int -SDL_SYS_CreateThread(SDL_Thread * thread, void *args, - pfnSDL_CurrentBeginThread pfnBeginThread, - pfnSDL_CurrentEndThread pfnEndThread) +int SDL_SYS_CreateThread(SDL_Thread *thread, + pfnSDL_CurrentBeginThread pfnBeginThread, + pfnSDL_CurrentEndThread pfnEndThread) { #elif defined(__CYGWIN__) || defined(__WINRT__) -int -SDL_SYS_CreateThread(SDL_Thread * thread, void *args) +int SDL_SYS_CreateThread(SDL_Thread *thread) { pfnSDL_CurrentBeginThread pfnBeginThread = NULL; pfnSDL_CurrentEndThread pfnEndThread = NULL; #else -int -SDL_SYS_CreateThread(SDL_Thread * thread, void *args) +int SDL_SYS_CreateThread(SDL_Thread *thread) { pfnSDL_CurrentBeginThread pfnBeginThread = (pfnSDL_CurrentBeginThread)_beginthreadex; pfnSDL_CurrentEndThread pfnEndThread = (pfnSDL_CurrentEndThread)_endthreadex; #endif /* SDL_PASSED_BEGINTHREAD_ENDTHREAD */ - pThreadStartParms pThreadParms = - (pThreadStartParms) SDL_malloc(sizeof(tThreadStartParms)); const DWORD flags = thread->stacksize ? STACK_SIZE_PARAM_IS_A_RESERVATION : 0; - if (!pThreadParms) { - return SDL_OutOfMemory(); - } + /* Save the function which we will have to call to clear the RTL of calling app! */ - pThreadParms->pfnCurrentEndThread = pfnEndThread; - /* Also save the real parameters we have to pass to thread function */ - pThreadParms->args = args; + thread->endfunc = pfnEndThread; /* thread->stacksize == 0 means "system default", same as win32 expects */ if (pfnBeginThread) { unsigned threadid = 0; - thread->handle = (SYS_ThreadHandle) - ((size_t) pfnBeginThread(NULL, (unsigned int) thread->stacksize, - RunThreadViaBeginThreadEx, - pThreadParms, flags, &threadid)); + thread->handle = (SYS_ThreadHandle)((size_t)pfnBeginThread(NULL, (unsigned int)thread->stacksize, + RunThreadViaBeginThreadEx, + thread, flags, &threadid)); } else { DWORD threadid = 0; thread->handle = CreateThread(NULL, thread->stacksize, RunThreadViaCreateThread, - pThreadParms, flags, &threadid); + thread, flags, &threadid); } - if (thread->handle == NULL) { + if (!thread->handle) { return SDL_SetError("Not enough resources to create thread"); } return 0; } -#pragma pack(push,8) +#pragma pack(push, 8) typedef struct tagTHREADNAME_INFO { - DWORD dwType; /* must be 0x1000 */ - LPCSTR szName; /* pointer to name (in user addr space) */ + DWORD dwType; /* must be 0x1000 */ + LPCSTR szName; /* pointer to name (in user addr space) */ DWORD dwThreadID; /* thread ID (-1=caller thread) */ - DWORD dwFlags; /* reserved for future use, must be zero */ + DWORD dwFlags; /* reserved for future use, must be zero */ } THREADNAME_INFO; #pragma pack(pop) +typedef HRESULT(WINAPI *pfnSetThreadDescription)(HANDLE, PCWSTR); -typedef HRESULT (WINAPI *pfnSetThreadDescription)(HANDLE, PCWSTR); - -void -SDL_SYS_SetupThread(const char *name) +void SDL_SYS_SetupThread(const char *name) { - if (name != NULL) { - #ifndef __WINRT__ /* !!! FIXME: There's no LoadLibrary() in WinRT; don't know if SetThreadDescription is available there at all at the moment. */ + if (name) { +#ifndef __WINRT__ /* !!! FIXME: There's no LoadLibrary() in WinRT; don't know if SetThreadDescription is available there at all at the moment. */ static pfnSetThreadDescription pSetThreadDescription = NULL; - static HMODULE kernel32 = 0; + static HMODULE kernel32 = NULL; if (!kernel32) { - kernel32 = LoadLibraryW(L"kernel32.dll"); + kernel32 = GetModuleHandle(TEXT("kernel32.dll")); if (kernel32) { - pSetThreadDescription = (pfnSetThreadDescription) GetProcAddress(kernel32, "SetThreadDescription"); + pSetThreadDescription = (pfnSetThreadDescription)GetProcAddress(kernel32, "SetThreadDescription"); } } - if (pSetThreadDescription != NULL) { - WCHAR *strw = WIN_UTF8ToString(name); + if (pSetThreadDescription) { + WCHAR *strw = WIN_UTF8ToStringW(name); if (strw) { pSetThreadDescription(GetCurrentThread(), strw); SDL_free(strw); } } - #endif +#endif /* Presumably some version of Visual Studio will understand SetThreadDescription(), but we still need to deal with older OSes and debuggers. Set it with the arcane @@ -207,23 +155,21 @@ SDL_SYS_SetupThread(const char *name) SDL_zero(inf); inf.dwType = 0x1000; inf.szName = name; - inf.dwThreadID = (DWORD) -1; + inf.dwThreadID = (DWORD)-1; inf.dwFlags = 0; /* The debugger catches this, renames the thread, continues on. */ - RaiseException(0x406D1388, 0, sizeof(inf) / sizeof(ULONG), (const ULONG_PTR*) &inf); + RaiseException(0x406D1388, 0, sizeof(inf) / sizeof(ULONG), (const ULONG_PTR *)&inf); } } } -SDL_threadID -SDL_ThreadID(void) +SDL_threadID SDL_ThreadID(void) { - return ((SDL_threadID) GetCurrentThreadId()); + return (SDL_threadID)GetCurrentThreadId(); } -int -SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority) +int SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority) { int value; @@ -242,15 +188,13 @@ SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority) return 0; } -void -SDL_SYS_WaitThread(SDL_Thread * thread) +void SDL_SYS_WaitThread(SDL_Thread *thread) { WaitForSingleObjectEx(thread->handle, INFINITE, FALSE); CloseHandle(thread->handle); } -void -SDL_SYS_DetachThread(SDL_Thread * thread) +void SDL_SYS_DetachThread(SDL_Thread *thread) { CloseHandle(thread->handle); } diff --git a/SDL2-2.0.12/src/thread/windows/SDL_systhread_c.h b/SDL2-2.30.5/src/thread/windows/SDL_systhread_c.h similarity index 94% rename from SDL2-2.0.12/src/thread/windows/SDL_systhread_c.h rename to SDL2-2.30.5/src/thread/windows/SDL_systhread_c.h index f843830..ae6978b 100644 --- a/SDL2-2.0.12/src/thread/windows/SDL_systhread_c.h +++ b/SDL2-2.30.5/src/thread/windows/SDL_systhread_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/thread/windows/SDL_systls.c b/SDL2-2.30.5/src/thread/windows/SDL_systls.c similarity index 91% rename from SDL2-2.0.12/src/thread/windows/SDL_systls.c rename to SDL2-2.30.5/src/thread/windows/SDL_systls.c index e37a332..9ae61b3 100644 --- a/SDL2-2.0.12/src/thread/windows/SDL_systls.c +++ b/SDL2-2.30.5/src/thread/windows/SDL_systls.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -21,7 +21,7 @@ #include "../../SDL_internal.h" -#if SDL_THREAD_WINDOWS +#ifdef SDL_THREAD_WINDOWS #include "../../core/windows/SDL_windows.h" @@ -32,7 +32,7 @@ #include #ifndef TLS_OUT_OF_INDEXES -#define TLS_OUT_OF_INDEXES FLS_OUT_OF_INDEXES +#define TLS_OUT_OF_INDEXES FLS_OUT_OF_INDEXES #endif #define TlsAlloc() FlsAlloc(NULL) @@ -43,8 +43,7 @@ static DWORD thread_local_storage = TLS_OUT_OF_INDEXES; static SDL_bool generic_local_storage = SDL_FALSE; -SDL_TLSData * -SDL_SYS_GetTLSData(void) +SDL_TLSData *SDL_SYS_GetTLSData(void) { if (thread_local_storage == TLS_OUT_OF_INDEXES && !generic_local_storage) { static SDL_SpinLock lock; @@ -67,8 +66,7 @@ SDL_SYS_GetTLSData(void) return (SDL_TLSData *)TlsGetValue(thread_local_storage); } -int -SDL_SYS_SetTLSData(SDL_TLSData *data) +int SDL_SYS_SetTLSData(SDL_TLSData *data) { if (generic_local_storage) { return SDL_Generic_SetTLSData(data); diff --git a/SDL2-2.0.12/src/timer/SDL_timer.c b/SDL2-2.30.5/src/timer/SDL_timer.c similarity index 74% rename from SDL2-2.0.12/src/timer/SDL_timer.c rename to SDL2-2.30.5/src/timer/SDL_timer.c index 4e8ea01..8cba808 100644 --- a/SDL2-2.0.12/src/timer/SDL_timer.c +++ b/SDL2-2.30.5/src/timer/SDL_timer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -28,6 +28,8 @@ /* #define DEBUG_TIMERS */ +#if !defined(__EMSCRIPTEN__) || !defined(SDL_THREADS_DISABLED) + typedef struct _SDL_Timer { int timerID; @@ -47,7 +49,8 @@ typedef struct _SDL_TimerMap } SDL_TimerMap; /* The timers are kept in a sorted list */ -typedef struct { +typedef struct +{ /* Data used by the main thread */ SDL_Thread *thread; SDL_atomic_t nextID; @@ -76,14 +79,13 @@ static SDL_TimerData SDL_timer_data; * Timers are removed by simply setting a canceled flag */ -static void -SDL_AddTimerInternal(SDL_TimerData *data, SDL_Timer *timer) +static void SDL_AddTimerInternal(SDL_TimerData *data, SDL_Timer *timer) { SDL_Timer *prev, *curr; prev = NULL; for (curr = data->timers; curr; prev = curr, curr = curr->next) { - if ((Sint32)(timer->scheduled-curr->scheduled) < 0) { + if ((Sint32)(timer->scheduled - curr->scheduled) < 0) { break; } } @@ -97,8 +99,7 @@ SDL_AddTimerInternal(SDL_TimerData *data, SDL_Timer *timer) timer->next = curr; } -static int SDLCALL -SDL_TimerThread(void *_data) +static int SDLCALL SDL_TimerThread(void *_data) { SDL_TimerData *data = (SDL_TimerData *)_data; SDL_Timer *pending; @@ -112,7 +113,7 @@ SDL_TimerThread(void *_data) * 2. Handle any timers that should dispatch this cycle * 3. Wait until next dispatch time or new timer arrives */ - for ( ; ; ) { + for (;;) { /* Pending and freelist maintenance */ SDL_AtomicLock(&data->lock); { @@ -151,7 +152,7 @@ SDL_TimerThread(void *_data) while (data->timers) { current = data->timers; - if ((Sint32)(tick-current->scheduled) < 0) { + if ((Sint32)(tick - current->scheduled) < 0) { /* Scheduled for the future, wait a bit */ delay = (current->scheduled - tick); break; @@ -203,8 +204,7 @@ SDL_TimerThread(void *_data) return 0; } -int -SDL_TimerInit(void) +int SDL_TimerInit(void) { SDL_TimerData *data = &SDL_timer_data; @@ -235,14 +235,13 @@ SDL_TimerInit(void) return 0; } -void -SDL_TimerQuit(void) +void SDL_TimerQuit(void) { SDL_TimerData *data = &SDL_timer_data; SDL_Timer *timer; SDL_TimerMap *entry; - if (SDL_AtomicCAS(&data->active, 1, 0)) { /* active? Move to inactive. */ + if (SDL_AtomicCAS(&data->active, 1, 0)) { /* active? Move to inactive. */ /* Shutdown the timer thread */ if (data->thread) { SDL_SemPost(data->sem); @@ -275,8 +274,7 @@ SDL_TimerQuit(void) } } -SDL_TimerID -SDL_AddTimer(Uint32 interval, SDL_TimerCallback callback, void *param) +SDL_TimerID SDL_AddTimer(Uint32 interval, SDL_TimerCallback callback, void *param) { SDL_TimerData *data = &SDL_timer_data; SDL_Timer *timer; @@ -338,8 +336,7 @@ SDL_AddTimer(Uint32 interval, SDL_TimerCallback callback, void *param) return entry->timerID; } -SDL_bool -SDL_RemoveTimer(SDL_TimerID id) +SDL_bool SDL_RemoveTimer(SDL_TimerID id) { SDL_TimerData *data = &SDL_timer_data; SDL_TimerMap *prev, *entry; @@ -370,4 +367,118 @@ SDL_RemoveTimer(SDL_TimerID id) return canceled; } +#else + +#include +#include + +typedef struct _SDL_TimerMap +{ + int timerID; + int timeoutID; + Uint32 interval; + SDL_TimerCallback callback; + void *param; + struct _SDL_TimerMap *next; +} SDL_TimerMap; + +typedef struct +{ + int nextID; + SDL_TimerMap *timermap; +} SDL_TimerData; + +static SDL_TimerData SDL_timer_data; + +static void SDL_Emscripten_TimerHelper(void *userdata) +{ + SDL_TimerMap *entry = (SDL_TimerMap *)userdata; + entry->interval = entry->callback(entry->interval, entry->param); + if (entry->interval > 0) { + entry->timeoutID = emscripten_set_timeout(&SDL_Emscripten_TimerHelper, + entry->interval, + entry); + } +} + +int SDL_TimerInit(void) +{ + return 0; +} + +void SDL_TimerQuit(void) +{ + SDL_TimerData *data = &SDL_timer_data; + SDL_TimerMap *entry; + + while (data->timermap) { + entry = data->timermap; + data->timermap = entry->next; + SDL_free(entry); + } +} + +SDL_TimerID SDL_AddTimer(Uint32 interval, SDL_TimerCallback callback, void *param) +{ + SDL_TimerData *data = &SDL_timer_data; + SDL_TimerMap *entry; + + entry = (SDL_TimerMap *)SDL_malloc(sizeof(*entry)); + if (!entry) { + SDL_OutOfMemory(); + return 0; + } + entry->timerID = ++data->nextID; + entry->callback = callback; + entry->param = param; + entry->interval = interval; + + entry->timeoutID = emscripten_set_timeout(&SDL_Emscripten_TimerHelper, + entry->interval, + entry); + + entry->next = data->timermap; + data->timermap = entry; + + return entry->timerID; +} + +SDL_bool SDL_RemoveTimer(SDL_TimerID id) +{ + SDL_TimerData *data = &SDL_timer_data; + SDL_TimerMap *prev, *entry; + + /* Find the timer */ + prev = NULL; + for (entry = data->timermap; entry; prev = entry, entry = entry->next) { + if (entry->timerID == id) { + if (prev) { + prev->next = entry->next; + } else { + data->timermap = entry->next; + } + break; + } + } + + if (entry) { + emscripten_clear_timeout(entry->timeoutID); + SDL_free(entry); + + return SDL_TRUE; + } + return SDL_FALSE; +} + +#endif + +/* This is a legacy support function; SDL_GetTicks() returns a Uint32, + which wraps back to zero every ~49 days. The newer SDL_GetTicks64() + doesn't have this problem, so we just wrap that function and clamp to + the low 32-bits for binary compatibility. */ +Uint32 SDL_GetTicks(void) +{ + return (Uint32)(SDL_GetTicks64() & 0xFFFFFFFF); +} + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/timer/SDL_timer_c.h b/SDL2-2.30.5/src/timer/SDL_timer_c.h similarity index 90% rename from SDL2-2.0.12/src/timer/SDL_timer_c.h rename to SDL2-2.30.5/src/timer/SDL_timer_c.h index 4e62845..f5c1e43 100644 --- a/SDL2-2.0.12/src/timer/SDL_timer_c.h +++ b/SDL2-2.30.5/src/timer/SDL_timer_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -28,7 +28,7 @@ #include "SDL_timer.h" #define ROUND_RESOLUTION(X) \ - (((X+TIMER_RESOLUTION-1)/TIMER_RESOLUTION)*TIMER_RESOLUTION) + (((X + TIMER_RESOLUTION - 1) / TIMER_RESOLUTION) * TIMER_RESOLUTION) extern void SDL_TicksInit(void); extern void SDL_TicksQuit(void); diff --git a/SDL2-2.0.12/src/timer/dummy/SDL_systimer.c b/SDL2-2.30.5/src/timer/dummy/SDL_systimer.c similarity index 85% rename from SDL2-2.0.12/src/timer/dummy/SDL_systimer.c rename to SDL2-2.30.5/src/timer/dummy/SDL_systimer.c index ffbdf30..ecc31ad 100644 --- a/SDL2-2.0.12/src/timer/dummy/SDL_systimer.c +++ b/SDL2-2.30.5/src/timer/dummy/SDL_systimer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,8 +26,7 @@ static SDL_bool ticks_started = SDL_FALSE; -void -SDL_TicksInit(void) +void SDL_TicksInit(void) { if (ticks_started) { return; @@ -35,14 +34,12 @@ SDL_TicksInit(void) ticks_started = SDL_TRUE; } -void -SDL_TicksQuit(void) +void SDL_TicksQuit(void) { ticks_started = SDL_FALSE; } -Uint32 -SDL_GetTicks(void) +Uint64 SDL_GetTicks64(void) { if (!ticks_started) { SDL_TicksInit(); @@ -52,20 +49,17 @@ SDL_GetTicks(void) return 0; } -Uint64 -SDL_GetPerformanceCounter(void) +Uint64 SDL_GetPerformanceCounter(void) { return SDL_GetTicks(); } -Uint64 -SDL_GetPerformanceFrequency(void) +Uint64 SDL_GetPerformanceFrequency(void) { return 1000; } -void -SDL_Delay(Uint32 ms) +void SDL_Delay(Uint32 ms) { SDL_Unsupported(); } diff --git a/SDL2-2.0.12/src/timer/haiku/SDL_systimer.c b/SDL2-2.30.5/src/timer/haiku/SDL_systimer.c similarity index 82% rename from SDL2-2.0.12/src/timer/haiku/SDL_systimer.c rename to SDL2-2.30.5/src/timer/haiku/SDL_systimer.c index b512fb1..8b038b5 100644 --- a/SDL2-2.0.12/src/timer/haiku/SDL_systimer.c +++ b/SDL2-2.30.5/src/timer/haiku/SDL_systimer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -29,8 +29,7 @@ static bigtime_t start; static SDL_bool ticks_started = SDL_FALSE; -void -SDL_TicksInit(void) +void SDL_TicksInit(void) { if (ticks_started) { return; @@ -41,36 +40,31 @@ SDL_TicksInit(void) start = system_time(); } -void -SDL_TicksQuit(void) +void SDL_TicksQuit(void) { ticks_started = SDL_FALSE; } -Uint32 -SDL_GetTicks(void) +Uint64 SDL_GetTicks64(void) { if (!ticks_started) { SDL_TicksInit(); } - return ((system_time() - start) / 1000); + return (Uint64)((system_time() - start) / 1000); } -Uint64 -SDL_GetPerformanceCounter(void) +Uint64 SDL_GetPerformanceCounter(void) { return system_time(); } -Uint64 -SDL_GetPerformanceFrequency(void) +Uint64 SDL_GetPerformanceFrequency(void) { return 1000000; } -void -SDL_Delay(Uint32 ms) +void SDL_Delay(Uint32 ms) { snooze(ms * 1000); } diff --git a/SDL2-2.30.5/src/timer/n3ds/SDL_systimer.c b/SDL2-2.30.5/src/timer/n3ds/SDL_systimer.c new file mode 100644 index 0000000..047b004 --- /dev/null +++ b/SDL2-2.30.5/src/timer/n3ds/SDL_systimer.c @@ -0,0 +1,75 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_TIMER_N3DS + +#include <3ds.h> + +static SDL_bool ticks_started = SDL_FALSE; +static u64 start_tick; + +#define NSEC_PER_MSEC 1000000ULL + +void SDL_TicksInit(void) +{ + if (ticks_started) { + return; + } + ticks_started = SDL_TRUE; + + start_tick = svcGetSystemTick(); +} + +void SDL_TicksQuit(void) +{ + ticks_started = SDL_FALSE; +} + +Uint64 SDL_GetTicks64(void) +{ + u64 elapsed; + if (!ticks_started) { + SDL_TicksInit(); + } + + elapsed = svcGetSystemTick() - start_tick; + return elapsed / CPU_TICKS_PER_MSEC; +} + +Uint64 SDL_GetPerformanceCounter(void) +{ + return svcGetSystemTick(); +} + +Uint64 SDL_GetPerformanceFrequency(void) +{ + return SYSCLOCK_ARM11; +} + +void SDL_Delay(Uint32 ms) +{ + svcSleepThread(ms * NSEC_PER_MSEC); +} + +#endif /* SDL_TIMER_N3DS */ + +/* vi: set sts=4 ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/timer/ngage/SDL_systimer.cpp b/SDL2-2.30.5/src/timer/ngage/SDL_systimer.cpp new file mode 100644 index 0000000..4ddf76f --- /dev/null +++ b/SDL2-2.30.5/src/timer/ngage/SDL_systimer.cpp @@ -0,0 +1,92 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#if defined(SDL_TIMER_NGAGE) + +#include +#include + +#include "SDL_timer.h" + +static SDL_bool ticks_started = SDL_FALSE; +static TUint start = 0; +static TInt tickPeriodMilliSeconds; + +#ifdef __cplusplus +extern "C" { +#endif + +void SDL_TicksInit(void) +{ + if (ticks_started) { + return; + } + ticks_started = SDL_TRUE; + start = User::TickCount(); + + TTimeIntervalMicroSeconds32 period; + TInt tmp = UserHal::TickPeriod(period); + + (void)tmp; /* Suppress redundant warning. */ + + tickPeriodMilliSeconds = period.Int() / 1000; +} + +void SDL_TicksQuit(void) +{ + ticks_started = SDL_FALSE; +} + +Uint64 SDL_GetTicks64(void) +{ + if (!ticks_started) { + SDL_TicksInit(); + } + + TUint deltaTics = User::TickCount() - start; + + // Overlaps early, but should do the trick for now. + return (Uint64)(deltaTics * tickPeriodMilliSeconds); +} + +Uint64 SDL_GetPerformanceCounter(void) +{ + return (Uint64)User::TickCount(); +} + +Uint64 SDL_GetPerformanceFrequency(void) +{ + return 1000000; +} + +void SDL_Delay(Uint32 ms) +{ + User::After(TTimeIntervalMicroSeconds32(ms * 1000)); +} + +#ifdef __cplusplus +} +#endif + +#endif /* SDL_TIMER_NGAGE */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/timer/os2/SDL_systimer.c b/SDL2-2.30.5/src/timer/os2/SDL_systimer.c new file mode 100644 index 0000000..f558855 --- /dev/null +++ b/SDL2-2.30.5/src/timer/os2/SDL_systimer.c @@ -0,0 +1,180 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_TIMER_OS2 + +#include "SDL_timer.h" +#include "../../core/os2/SDL_os2.h" + +#define INCL_DOSERRORS +#define INCL_DOSMISC +#define INCL_DOSPROFILE +#define INCL_DOSSEMAPHORES +#define INCL_DOSDATETIME +#define INCL_DOSPROCESS +#define INCL_DOSEXCEPTIONS +#include + +/* No need to switch priorities in SDL_Delay() for OS/2 versions > Warp3 fp 42, */ +/*#define _SWITCH_PRIORITY*/ + +typedef unsigned long long ULLONG; + +static SDL_bool ticks_started = SDL_FALSE; +static ULONG ulTmrFreq = 0; +static ULLONG ullTmrStart = 0; + +void SDL_TicksInit(void) +{ + ULONG ulTmrStart; /* for 32-bit fallback. */ + ULONG ulRC; + + if (ticks_started) { + return; + } + ticks_started = SDL_TRUE; + + ulRC = DosTmrQueryFreq(&ulTmrFreq); + if (ulRC != NO_ERROR) { + debug_os2("DosTmrQueryFreq() failed, rc = %u", ulRC); + } else { + ulRC = DosTmrQueryTime((PQWORD)&ullTmrStart); + if (ulRC == NO_ERROR) { + return; + } + debug_os2("DosTmrQueryTime() failed, rc = %u", ulRC); + } + + ulTmrFreq = 0; /* Error - use DosQuerySysInfo() for timer. */ + DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &ulTmrStart, sizeof(ULONG)); + ullTmrStart = (ULLONG) ulTmrStart; +} + +void SDL_TicksQuit(void) +{ + ticks_started = SDL_FALSE; +} + +Uint64 SDL_GetTicks64(void) +{ + Uint64 ui64Result; + ULLONG ullTmrNow; + + if (!ticks_started) { + SDL_TicksInit(); + } + + if (ulTmrFreq != 0) { + DosTmrQueryTime((PQWORD)&ullTmrNow); + ui64Result = (ullTmrNow - ullTmrStart) * 1000 / ulTmrFreq; + } else { + /* note that this counter rolls over to 0 every ~49 days. Fix your system so DosTmrQueryTime works if you need to avoid this. */ + ULONG ulTmrNow; + DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &ulTmrNow, sizeof(ULONG)); + ui64Result = (((Uint64) ulTmrNow) - ullTmrStart); + } + + return ui64Result; +} + +Uint64 SDL_GetPerformanceCounter(void) +{ + QWORD qwTmrNow; + + if (ulTmrFreq == 0 || (DosTmrQueryTime(&qwTmrNow) != NO_ERROR)) { + return SDL_GetTicks64(); + } + return *((Uint64 *)&qwTmrNow); +} + +Uint64 SDL_GetPerformanceFrequency(void) +{ + return (ulTmrFreq == 0)? 1000 : (Uint64)ulTmrFreq; +} + +void SDL_Delay(Uint32 ms) +{ + HTIMER hTimer = NULLHANDLE; + ULONG ulRC; +#ifdef _SWITCH_PRIORITY + PPIB pib; + PTIB tib; + BOOL fSetPriority = ms < 50; + ULONG ulSavePriority; + ULONG ulNesting; +#endif + HEV hevTimer; + + if (ms == 0) { + DosSleep(0); + return; + } + + ulRC = DosCreateEventSem(NULL, &hevTimer, DC_SEM_SHARED, FALSE); + if (ulRC != NO_ERROR) { + debug_os2("DosAsyncTimer() failed, rc = %u", ulRC); + DosSleep(ms); + return; + } + +#ifdef _SWITCH_PRIORITY + if (fSetPriority) { + if (DosGetInfoBlocks(&tib, &pib) != NO_ERROR) + fSetPriority = FALSE; + else { + ulSavePriority = tib->tib_ptib2->tib2_ulpri; + if (((ulSavePriority & 0xFF00) == 0x0300) || /* already have high pr. */ + (DosEnterMustComplete( &ulNesting) != NO_ERROR)) + fSetPriority = FALSE; + else { + DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, 0); + } + } + } +#endif + + DosResetEventSem(hevTimer, &ulRC); + ulRC = DosAsyncTimer(ms, (HSEM)hevTimer, &hTimer); + +#ifdef _SWITCH_PRIORITY + if (fSetPriority) { + if (DosSetPriority(PRTYS_THREAD, (ulSavePriority >> 8) & 0xFF, 0, 0) == NO_ERROR) + DosSetPriority(PRTYS_THREAD, 0, ulSavePriority & 0xFF, 0); + DosExitMustComplete(&ulNesting); + } +#endif + + if (ulRC != NO_ERROR) { + debug_os2("DosAsyncTimer() failed, rc = %u", ulRC); + } else { + DosWaitEventSem(hevTimer, SEM_INDEFINITE_WAIT); + } + + if (ulRC != NO_ERROR) + DosSleep(ms); + + DosCloseEventSem(hevTimer); +} + +#endif /* SDL_TIMER_OS2 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/timer/ps2/SDL_systimer.c b/SDL2-2.30.5/src/timer/ps2/SDL_systimer.c new file mode 100644 index 0000000..720f696 --- /dev/null +++ b/SDL2-2.30.5/src/timer/ps2/SDL_systimer.c @@ -0,0 +1,85 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_TIMER_PS2 + +#include "SDL_thread.h" +#include "SDL_timer.h" +#include "SDL_error.h" +#include "../SDL_timer_c.h" +#include +#include +#include +#include + +static uint64_t start; +static SDL_bool ticks_started = SDL_FALSE; + +void SDL_TicksInit(void) +{ + if (ticks_started) { + return; + } + ticks_started = SDL_TRUE; + + start = GetTimerSystemTime(); +} + +void SDL_TicksQuit(void) +{ + ticks_started = SDL_FALSE; +} + +Uint64 SDL_GetTicks64(void) +{ + uint64_t now; + + if (!ticks_started) { + SDL_TicksInit(); + } + + now = GetTimerSystemTime(); + return (Uint64)((now - start) / (kBUSCLK / CLOCKS_PER_SEC)); +} + +Uint64 SDL_GetPerformanceCounter(void) +{ + return SDL_GetTicks64(); +} + +Uint64 SDL_GetPerformanceFrequency(void) +{ + return 1000; +} + +void SDL_Delay(Uint32 ms) +{ + struct timespec tv = { 0 }; + tv.tv_sec = ms / 1000; + tv.tv_nsec = (ms % 1000) * 1000000; + nanosleep(&tv, NULL); +} + +#endif /* SDL_TIMER_PS2 */ + +/* vim: ts=4 sw=4 + */ diff --git a/SDL2-2.0.12/src/timer/psp/SDL_systimer.c b/SDL2-2.30.5/src/timer/psp/SDL_systimer.c similarity index 78% rename from SDL2-2.0.12/src/timer/psp/SDL_systimer.c rename to SDL2-2.30.5/src/timer/psp/SDL_systimer.c index ad4ab29..c69598e 100644 --- a/SDL2-2.0.12/src/timer/psp/SDL_systimer.c +++ b/SDL2-2.30.5/src/timer/psp/SDL_systimer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#ifdef SDL_TIMERS_PSP +#ifdef SDL_TIMER_PSP #include "SDL_thread.h" #include "SDL_timer.h" @@ -34,8 +34,7 @@ static struct timeval start; static SDL_bool ticks_started = SDL_FALSE; -void -SDL_TicksInit(void) +void SDL_TicksInit(void) { if (ticks_started) { return; @@ -45,34 +44,29 @@ SDL_TicksInit(void) gettimeofday(&start, NULL); } -void -SDL_TicksQuit(void) +void SDL_TicksQuit(void) { ticks_started = SDL_FALSE; } -Uint32 SDL_GetTicks(void) +Uint64 SDL_GetTicks64(void) { + struct timeval now; + if (!ticks_started) { SDL_TicksInit(); } - struct timeval now; - Uint32 ticks; - gettimeofday(&now, NULL); - ticks=(now.tv_sec-start.tv_sec)*1000+(now.tv_usec-start.tv_usec)/1000; - return(ticks); + return (Uint64)(((Sint64)(now.tv_sec - start.tv_sec) * 1000) + ((now.tv_usec - start.tv_usec) / 1000)); } -Uint64 -SDL_GetPerformanceCounter(void) +Uint64 SDL_GetPerformanceCounter(void) { - return SDL_GetTicks(); + return SDL_GetTicks64(); } -Uint64 -SDL_GetPerformanceFrequency(void) +Uint64 SDL_GetPerformanceFrequency(void) { return 1000; } @@ -80,12 +74,13 @@ SDL_GetPerformanceFrequency(void) void SDL_Delay(Uint32 ms) { const Uint32 max_delay = 0xffffffffUL / 1000; - if(ms > max_delay) + if (ms > max_delay) { ms = max_delay; + } sceKernelDelayThreadCB(ms * 1000); } -#endif /* SDL_TIMERS_PSP */ +#endif /* SDL_TIMER_PSP */ /* vim: ts=4 sw=4 */ diff --git a/SDL2-2.0.12/src/timer/unix/SDL_systimer.c b/SDL2-2.30.5/src/timer/unix/SDL_systimer.c similarity index 75% rename from SDL2-2.0.12/src/timer/unix/SDL_systimer.c rename to SDL2-2.30.5/src/timer/unix/SDL_systimer.c index 411705a..a697b71 100644 --- a/SDL2-2.0.12/src/timer/unix/SDL_systimer.c +++ b/SDL2-2.30.5/src/timer/unix/SDL_systimer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -28,9 +28,13 @@ #include #include "SDL_timer.h" -#include "SDL_assert.h" +#include "SDL_hints.h" #include "../SDL_timer_c.h" +#ifdef __EMSCRIPTEN__ +#include +#endif + /* The clock_gettime provides monotonous time, so we should use it if it's available. The clock_gettime function is behind ifdef for __USE_POSIX199309 @@ -42,7 +46,7 @@ Also added OS X Monotonic clock support Based on work in https://github.com/ThomasHabets/monotonic_clock */ -#if HAVE_NANOSLEEP || HAVE_CLOCK_GETTIME +#if defined(HAVE_NANOSLEEP) || defined(HAVE_CLOCK_GETTIME) #include #endif #ifdef __APPLE__ @@ -50,7 +54,7 @@ #endif /* Use CLOCK_MONOTONIC_RAW, if available, which is not subject to adjustment by NTP */ -#if HAVE_CLOCK_GETTIME +#ifdef HAVE_CLOCK_GETTIME #ifdef CLOCK_MONOTONIC_RAW #define SDL_MONOTONIC_CLOCK CLOCK_MONOTONIC_RAW #else @@ -59,7 +63,7 @@ #endif /* The first ticks value of the application */ -#if HAVE_CLOCK_GETTIME +#ifdef HAVE_CLOCK_GETTIME static struct timespec start_ts; #elif defined(__APPLE__) static uint64_t start_mach; @@ -69,8 +73,7 @@ static SDL_bool has_monotonic_time = SDL_FALSE; static struct timeval start_tv; static SDL_bool ticks_started = SDL_FALSE; -void -SDL_TicksInit(void) +void SDL_TicksInit(void) { if (ticks_started) { return; @@ -78,13 +81,12 @@ SDL_TicksInit(void) ticks_started = SDL_TRUE; /* Set first ticks value */ -#if HAVE_CLOCK_GETTIME +#ifdef HAVE_CLOCK_GETTIME if (clock_gettime(SDL_MONOTONIC_CLOCK, &start_ts) == 0) { has_monotonic_time = SDL_TRUE; } else #elif defined(__APPLE__) - kern_return_t ret = mach_timebase_info(&mach_base_info); - if (ret == 0) { + if (mach_timebase_info(&mach_base_info) == 0) { has_monotonic_time = SDL_TRUE; start_mach = mach_absolute_time(); } else @@ -94,43 +96,37 @@ SDL_TicksInit(void) } } -void -SDL_TicksQuit(void) +void SDL_TicksQuit(void) { ticks_started = SDL_FALSE; } -Uint32 -SDL_GetTicks(void) +Uint64 SDL_GetTicks64(void) { - Uint32 ticks; if (!ticks_started) { SDL_TicksInit(); } if (has_monotonic_time) { -#if HAVE_CLOCK_GETTIME +#ifdef HAVE_CLOCK_GETTIME struct timespec now; clock_gettime(SDL_MONOTONIC_CLOCK, &now); - ticks = (Uint32)((now.tv_sec - start_ts.tv_sec) * 1000 + (now.tv_nsec - start_ts.tv_nsec) / 1000000); + return (Uint64)(((Sint64)(now.tv_sec - start_ts.tv_sec) * 1000) + ((now.tv_nsec - start_ts.tv_nsec) / 1000000)); #elif defined(__APPLE__) - uint64_t now = mach_absolute_time(); - ticks = (Uint32)((((now - start_mach) * mach_base_info.numer) / mach_base_info.denom) / 1000000); + const uint64_t now = mach_absolute_time(); + return (((now - start_mach) * mach_base_info.numer) / mach_base_info.denom) / 1000000; #else SDL_assert(SDL_FALSE); - ticks = 0; + return 0; #endif } else { struct timeval now; - gettimeofday(&now, NULL); - ticks = (Uint32)((now.tv_sec - start_tv.tv_sec) * 1000 + (now.tv_usec - start_tv.tv_usec) / 1000); + return (Uint64)(((Sint64)(now.tv_sec - start_tv.tv_sec) * 1000) + ((now.tv_usec - start_tv.tv_usec) / 1000)); } - return (ticks); } -Uint64 -SDL_GetPerformanceCounter(void) +Uint64 SDL_GetPerformanceCounter(void) { Uint64 ticks; if (!ticks_started) { @@ -138,7 +134,7 @@ SDL_GetPerformanceCounter(void) } if (has_monotonic_time) { -#if HAVE_CLOCK_GETTIME +#ifdef HAVE_CLOCK_GETTIME struct timespec now; clock_gettime(SDL_MONOTONIC_CLOCK, &now); @@ -159,18 +155,17 @@ SDL_GetPerformanceCounter(void) ticks *= 1000000; ticks += now.tv_usec; } - return (ticks); + return ticks; } -Uint64 -SDL_GetPerformanceFrequency(void) +Uint64 SDL_GetPerformanceFrequency(void) { if (!ticks_started) { SDL_TicksInit(); } if (has_monotonic_time) { -#if HAVE_CLOCK_GETTIME +#ifdef HAVE_CLOCK_GETTIME return 1000000000; #elif defined(__APPLE__) Uint64 freq = mach_base_info.denom; @@ -178,46 +173,53 @@ SDL_GetPerformanceFrequency(void) freq /= mach_base_info.numer; return freq; #endif - } - + } + return 1000000; } -void -SDL_Delay(Uint32 ms) +void SDL_Delay(Uint32 ms) { int was_error; -#if HAVE_NANOSLEEP +#ifdef HAVE_NANOSLEEP struct timespec elapsed, tv; #else struct timeval tv; - Uint32 then, now, elapsed; + Uint64 then, now, elapsed; +#endif + +#ifdef __EMSCRIPTEN__ + if (emscripten_has_asyncify() && SDL_GetHintBoolean(SDL_HINT_EMSCRIPTEN_ASYNCIFY, SDL_TRUE)) { + /* pseudo-synchronous pause, used directly or through e.g. SDL_WaitEvent */ + emscripten_sleep(ms); + return; + } #endif /* Set the timeout interval */ -#if HAVE_NANOSLEEP +#ifdef HAVE_NANOSLEEP elapsed.tv_sec = ms / 1000; elapsed.tv_nsec = (ms % 1000) * 1000000; #else - then = SDL_GetTicks(); + then = SDL_GetTicks64(); #endif do { errno = 0; -#if HAVE_NANOSLEEP +#ifdef HAVE_NANOSLEEP tv.tv_sec = elapsed.tv_sec; tv.tv_nsec = elapsed.tv_nsec; was_error = nanosleep(&tv, &elapsed); #else /* Calculate the time interval left (in case of interrupt) */ - now = SDL_GetTicks(); + now = SDL_GetTicks64(); elapsed = (now - then); then = now; - if (elapsed >= ms) { + if (elapsed >= ((Uint64)ms)) { break; } - ms -= elapsed; + ms -= (Uint32)elapsed; tv.tv_sec = ms / 1000; tv.tv_usec = (ms % 1000) * 1000; diff --git a/SDL2-2.30.5/src/timer/vita/SDL_systimer.c b/SDL2-2.30.5/src/timer/vita/SDL_systimer.c new file mode 100644 index 0000000..d5ccabc --- /dev/null +++ b/SDL2-2.30.5/src/timer/vita/SDL_systimer.c @@ -0,0 +1,85 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_TIMER_VITA + +#include "SDL_thread.h" +#include "SDL_timer.h" +#include "SDL_error.h" +#include "../SDL_timer_c.h" +#include +#include +#include +#include + +static uint64_t start; +static SDL_bool ticks_started = SDL_FALSE; + +void SDL_TicksInit(void) +{ + if (ticks_started) { + return; + } + ticks_started = SDL_TRUE; + + start = sceKernelGetProcessTimeWide(); +} + +void SDL_TicksQuit(void) +{ + ticks_started = SDL_FALSE; +} + +Uint64 SDL_GetTicks64(void) +{ + uint64_t now; + + if (!ticks_started) { + SDL_TicksInit(); + } + + now = sceKernelGetProcessTimeWide(); + return (Uint64)((now - start) / 1000); +} + +Uint64 SDL_GetPerformanceCounter(void) +{ + return sceKernelGetProcessTimeWide(); +} + +Uint64 SDL_GetPerformanceFrequency(void) +{ + return 1000000; +} + +void SDL_Delay(Uint32 ms) +{ + const Uint32 max_delay = 0xffffffffUL / 1000; + if (ms > max_delay) { + ms = max_delay; + } + sceKernelDelayThreadCB(ms * 1000); +} + +#endif /* SDL_TIMER_VITA */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/timer/windows/SDL_systimer.c b/SDL2-2.30.5/src/timer/windows/SDL_systimer.c similarity index 65% rename from SDL2-2.0.12/src/timer/windows/SDL_systimer.c rename to SDL2-2.30.5/src/timer/windows/SDL_systimer.c index 6c8d23f..e7c2c78 100644 --- a/SDL2-2.0.12/src/timer/windows/SDL_systimer.c +++ b/SDL2-2.30.5/src/timer/windows/SDL_systimer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -31,19 +31,16 @@ /* The first (low-resolution) ticks value of the application */ static DWORD start = 0; -static BOOL ticks_started = FALSE; +static BOOL ticks_started = FALSE; -/* Store if a high-resolution performance counter exists on the system */ -static BOOL hires_timer_available; /* The first high-resolution ticks value of the application */ -static LARGE_INTEGER hires_start_ticks; +static LARGE_INTEGER start_ticks; /* The number of ticks per second of the high-resolution performance counter */ -static LARGE_INTEGER hires_ticks_per_second; +static LARGE_INTEGER ticks_per_second; -static void -SDL_SetSystemTimerResolution(const UINT uPeriod) +static void SDL_SetSystemTimerResolution(const UINT uPeriod) { -#ifndef __WINRT__ +#if !defined(__WINRT__) && !defined(__XBOXONE__) && !defined(__XBOXSERIES__) static UINT timer_period = 0; if (uPeriod != timer_period) { @@ -60,8 +57,7 @@ SDL_SetSystemTimerResolution(const UINT uPeriod) #endif } -static void SDLCALL -SDL_TimerResolutionChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +static void SDLCALL SDL_TimerResolutionChanged(void *userdata, const char *name, const char *oldValue, const char *hint) { UINT uPeriod; @@ -76,9 +72,10 @@ SDL_TimerResolutionChanged(void *userdata, const char *name, const char *oldValu } } -void -SDL_TicksInit(void) +void SDL_TicksInit(void) { + BOOL rc; + if (ticks_started) { return; } @@ -90,83 +87,56 @@ SDL_TicksInit(void) SDL_TimerResolutionChanged, NULL); /* Set first ticks value */ - /* QueryPerformanceCounter has had problems in the past, but lots of games - use it, so we'll rely on it here. + /* QueryPerformanceCounter allegedly is always available and reliable as of WinXP, + so we'll rely on it here. */ - if (QueryPerformanceFrequency(&hires_ticks_per_second) == TRUE) { - hires_timer_available = TRUE; - QueryPerformanceCounter(&hires_start_ticks); - } else { - hires_timer_available = FALSE; -#ifndef __WINRT__ - start = timeGetTime(); -#endif /* __WINRT__ */ - } + rc = QueryPerformanceFrequency(&ticks_per_second); + SDL_assert(rc != 0); /* this should _never_ fail if you're on XP or later. */ + QueryPerformanceCounter(&start_ticks); } -void -SDL_TicksQuit(void) +void SDL_TicksQuit(void) { SDL_DelHintCallback(SDL_HINT_TIMER_RESOLUTION, SDL_TimerResolutionChanged, NULL); - SDL_SetSystemTimerResolution(0); /* always release our timer resolution request. */ + SDL_SetSystemTimerResolution(0); /* always release our timer resolution request. */ start = 0; ticks_started = SDL_FALSE; } -Uint32 -SDL_GetTicks(void) +Uint64 SDL_GetTicks64(void) { - DWORD now = 0; - LARGE_INTEGER hires_now; + LARGE_INTEGER now; + BOOL rc; if (!ticks_started) { SDL_TicksInit(); } - if (hires_timer_available) { - QueryPerformanceCounter(&hires_now); - - hires_now.QuadPart -= hires_start_ticks.QuadPart; - hires_now.QuadPart *= 1000; - hires_now.QuadPart /= hires_ticks_per_second.QuadPart; - - return (DWORD) hires_now.QuadPart; - } else { -#ifndef __WINRT__ - now = timeGetTime(); -#endif /* __WINRT__ */ - } - - return (now - start); + rc = QueryPerformanceCounter(&now); + SDL_assert(rc != 0); /* this should _never_ fail if you're on XP or later. */ + return (Uint64)(((now.QuadPart - start_ticks.QuadPart) * 1000) / ticks_per_second.QuadPart); } -Uint64 -SDL_GetPerformanceCounter(void) +Uint64 SDL_GetPerformanceCounter(void) { LARGE_INTEGER counter; - - if (!QueryPerformanceCounter(&counter)) { - return SDL_GetTicks(); - } - return counter.QuadPart; + const BOOL rc = QueryPerformanceCounter(&counter); + SDL_assert(rc != 0); /* this should _never_ fail if you're on XP or later. */ + return (Uint64)counter.QuadPart; } -Uint64 -SDL_GetPerformanceFrequency(void) +Uint64 SDL_GetPerformanceFrequency(void) { LARGE_INTEGER frequency; - - if (!QueryPerformanceFrequency(&frequency)) { - return 1000; - } - return frequency.QuadPart; + const BOOL rc = QueryPerformanceFrequency(&frequency); + SDL_assert(rc != 0); /* this should _never_ fail if you're on XP or later. */ + return (Uint64)frequency.QuadPart; } -void -SDL_Delay(Uint32 ms) +void SDL_Delay(Uint32 ms) { /* Sleep() is not publicly available to apps in early versions of WinRT. * diff --git a/SDL2-2.0.12/src/video/SDL_RLEaccel.c b/SDL2-2.30.5/src/video/SDL_RLEaccel.c similarity index 52% rename from SDL2-2.0.12/src/video/SDL_RLEaccel.c rename to SDL2-2.30.5/src/video/SDL_RLEaccel.c index c9b84e3..a007984 100644 --- a/SDL2-2.0.12/src/video/SDL_RLEaccel.c +++ b/SDL2-2.30.5/src/video/SDL_RLEaccel.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -27,7 +27,7 @@ * * Original version by Sam Lantinga * - * Mattias Engdegrd (Yorick): Rewrite. New encoding format, encoder and + * Mattias Engdegård (Yorick): Rewrite. New encoding format, encoder and * decoder. Added per-surface alpha blitter. Added per-pixel alpha * format, encoder and blitter. * @@ -92,18 +92,14 @@ #include "SDL_blit.h" #include "SDL_RLEaccel_c.h" -#ifndef MIN -#define MIN(a, b) ((a) < (b) ? (a) : (b)) -#endif - -#define PIXEL_COPY(to, from, len, bpp) \ +#define PIXEL_COPY(to, from, len, bpp) \ SDL_memcpy(to, from, (size_t)(len) * (bpp)) /* * Various colorkey blit methods, for opaque and per-surface alpha */ -#define OPAQUE_BLIT(to, from, length, bpp, alpha) \ +#define OPAQUE_BLIT(to, from, length, bpp, alpha) \ PIXEL_COPY(to, from, length, bpp) /* @@ -113,22 +109,22 @@ * of each component, so the bits from the multiplication don't collide. * This can be used for any RGB permutation of course. */ -#define ALPHA_BLIT32_888(to, from, length, bpp, alpha) \ - do { \ - int i; \ - Uint32 *src = (Uint32 *)(from); \ - Uint32 *dst = (Uint32 *)(to); \ - for (i = 0; i < (int)(length); i++) { \ - Uint32 s = *src++; \ - Uint32 d = *dst; \ - Uint32 s1 = s & 0xff00ff; \ - Uint32 d1 = d & 0xff00ff; \ +#define ALPHA_BLIT32_888(to, from, length, bpp, alpha) \ + do { \ + int i; \ + Uint32 *src = (Uint32 *)(from); \ + Uint32 *dst = (Uint32 *)(to); \ + for (i = 0; i < (int)(length); i++) { \ + Uint32 s = *src++; \ + Uint32 d = *dst; \ + Uint32 s1 = s & 0xff00ff; \ + Uint32 d1 = d & 0xff00ff; \ d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff; \ - s &= 0xff00; \ - d &= 0xff00; \ - d = (d + ((s - d) * alpha >> 8)) & 0xff00; \ - *dst++ = d1 | d; \ - } \ + s &= 0xff00; \ + d &= 0xff00; \ + d = (d + ((s - d) * alpha >> 8)) & 0xff00; \ + *dst++ = d1 | d; \ + } \ } while (0) /* @@ -137,99 +133,99 @@ * components at the same time. Since the smallest gap is here just * 5 bits, we have to scale alpha down to 5 bits as well. */ -#define ALPHA_BLIT16_565(to, from, length, bpp, alpha) \ - do { \ - int i; \ - Uint16 *src = (Uint16 *)(from); \ - Uint16 *dst = (Uint16 *)(to); \ - Uint32 ALPHA = alpha >> 3; \ - for(i = 0; i < (int)(length); i++) { \ - Uint32 s = *src++; \ - Uint32 d = *dst; \ - s = (s | s << 16) & 0x07e0f81f; \ - d = (d | d << 16) & 0x07e0f81f; \ - d += (s - d) * ALPHA >> 5; \ - d &= 0x07e0f81f; \ - *dst++ = (Uint16)(d | d >> 16); \ - } \ - } while(0) +#define ALPHA_BLIT16_565(to, from, length, bpp, alpha) \ + do { \ + int i; \ + Uint16 *src = (Uint16 *)(from); \ + Uint16 *dst = (Uint16 *)(to); \ + Uint32 ALPHA = alpha >> 3; \ + for (i = 0; i < (int)(length); i++) { \ + Uint32 s = *src++; \ + Uint32 d = *dst; \ + s = (s | s << 16) & 0x07e0f81f; \ + d = (d | d << 16) & 0x07e0f81f; \ + d += (s - d) * ALPHA >> 5; \ + d &= 0x07e0f81f; \ + *dst++ = (Uint16)(d | d >> 16); \ + } \ + } while (0) -#define ALPHA_BLIT16_555(to, from, length, bpp, alpha) \ - do { \ - int i; \ - Uint16 *src = (Uint16 *)(from); \ - Uint16 *dst = (Uint16 *)(to); \ - Uint32 ALPHA = alpha >> 3; \ - for(i = 0; i < (int)(length); i++) { \ - Uint32 s = *src++; \ - Uint32 d = *dst; \ - s = (s | s << 16) & 0x03e07c1f; \ - d = (d | d << 16) & 0x03e07c1f; \ - d += (s - d) * ALPHA >> 5; \ - d &= 0x03e07c1f; \ - *dst++ = (Uint16)(d | d >> 16); \ - } \ - } while(0) +#define ALPHA_BLIT16_555(to, from, length, bpp, alpha) \ + do { \ + int i; \ + Uint16 *src = (Uint16 *)(from); \ + Uint16 *dst = (Uint16 *)(to); \ + Uint32 ALPHA = alpha >> 3; \ + for (i = 0; i < (int)(length); i++) { \ + Uint32 s = *src++; \ + Uint32 d = *dst; \ + s = (s | s << 16) & 0x03e07c1f; \ + d = (d | d << 16) & 0x03e07c1f; \ + d += (s - d) * ALPHA >> 5; \ + d &= 0x03e07c1f; \ + *dst++ = (Uint16)(d | d >> 16); \ + } \ + } while (0) /* * The general slow catch-all function, for remaining depths and formats */ -#define ALPHA_BLIT_ANY(to, from, length, bpp, alpha) \ - do { \ - int i; \ - Uint8 *src = from; \ - Uint8 *dst = to; \ - for (i = 0; i < (int)(length); i++) { \ - Uint32 s, d; \ - unsigned rs, gs, bs, rd, gd, bd; \ - switch (bpp) { \ - case 2: \ - s = *(Uint16 *)src; \ - d = *(Uint16 *)dst; \ - break; \ - case 3: \ - if (SDL_BYTEORDER == SDL_BIG_ENDIAN) { \ +#define ALPHA_BLIT_ANY(to, from, length, bpp, alpha) \ + do { \ + int i; \ + Uint8 *src = from; \ + Uint8 *dst = to; \ + for (i = 0; i < (int)(length); i++) { \ + Uint32 s, d; \ + unsigned rs, gs, bs, rd, gd, bd; \ + switch (bpp) { \ + case 2: \ + s = *(Uint16 *)src; \ + d = *(Uint16 *)dst; \ + break; \ + case 3: \ + if (SDL_BYTEORDER == SDL_BIG_ENDIAN) { \ s = (src[0] << 16) | (src[1] << 8) | src[2]; \ d = (dst[0] << 16) | (dst[1] << 8) | dst[2]; \ - } else { \ + } else { \ s = (src[2] << 16) | (src[1] << 8) | src[0]; \ d = (dst[2] << 16) | (dst[1] << 8) | dst[0]; \ - } \ - break; \ - case 4: \ - s = *(Uint32 *)src; \ - d = *(Uint32 *)dst; \ - break; \ - } \ - RGB_FROM_PIXEL(s, fmt, rs, gs, bs); \ - RGB_FROM_PIXEL(d, fmt, rd, gd, bd); \ - rd += (rs - rd) * alpha >> 8; \ - gd += (gs - gd) * alpha >> 8; \ - bd += (bs - bd) * alpha >> 8; \ - PIXEL_FROM_RGB(d, fmt, rd, gd, bd); \ - switch (bpp) { \ - case 2: \ - *(Uint16 *)dst = (Uint16)d; \ - break; \ - case 3: \ - if (SDL_BYTEORDER == SDL_BIG_ENDIAN) { \ - dst[0] = (Uint8)(d >> 16); \ - dst[1] = (Uint8)(d >> 8); \ - dst[2] = (Uint8)(d); \ - } else { \ - dst[0] = (Uint8)d; \ - dst[1] = (Uint8)(d >> 8); \ - dst[2] = (Uint8)(d >> 16); \ - } \ - break; \ - case 4: \ - *(Uint32 *)dst = d; \ - break; \ - } \ - src += bpp; \ - dst += bpp; \ - } \ - } while(0) + } \ + break; \ + case 4: \ + s = *(Uint32 *)src; \ + d = *(Uint32 *)dst; \ + break; \ + } \ + RGB_FROM_PIXEL(s, fmt, rs, gs, bs); \ + RGB_FROM_PIXEL(d, fmt, rd, gd, bd); \ + rd += (rs - rd) * alpha >> 8; \ + gd += (gs - gd) * alpha >> 8; \ + bd += (bs - bd) * alpha >> 8; \ + PIXEL_FROM_RGB(d, fmt, rd, gd, bd); \ + switch (bpp) { \ + case 2: \ + *(Uint16 *)dst = (Uint16)d; \ + break; \ + case 3: \ + if (SDL_BYTEORDER == SDL_BIG_ENDIAN) { \ + dst[0] = (Uint8)(d >> 16); \ + dst[1] = (Uint8)(d >> 8); \ + dst[2] = (Uint8)(d); \ + } else { \ + dst[0] = (Uint8)d; \ + dst[1] = (Uint8)(d >> 8); \ + dst[2] = (Uint8)(d >> 16); \ + } \ + break; \ + case 4: \ + *(Uint32 *)dst = d; \ + break; \ + } \ + src += bpp; \ + dst += bpp; \ + } \ + } while (0) /* * Special case: 50% alpha (alpha=128) @@ -239,18 +235,17 @@ * First zero the lowest bit of each component, which gives us room to * add them. Then shift right and add the sum of the lowest bits. */ -#define ALPHA_BLIT32_888_50(to, from, length, bpp, alpha) \ - do { \ - int i; \ - Uint32 *src = (Uint32 *)(from); \ - Uint32 *dst = (Uint32 *)(to); \ - for(i = 0; i < (int)(length); i++) { \ - Uint32 s = *src++; \ - Uint32 d = *dst; \ - *dst++ = (((s & 0x00fefefe) + (d & 0x00fefefe)) >> 1) \ - + (s & d & 0x00010101); \ - } \ - } while(0) +#define ALPHA_BLIT32_888_50(to, from, length, bpp, alpha) \ + do { \ + int i; \ + Uint32 *src = (Uint32 *)(from); \ + Uint32 *dst = (Uint32 *)(to); \ + for (i = 0; i < (int)(length); i++) { \ + Uint32 s = *src++; \ + Uint32 d = *dst; \ + *dst++ = (((s & 0x00fefefe) + (d & 0x00fefefe)) >> 1) + (s & d & 0x00010101); \ + } \ + } while (0) /* * For 16bpp, we can actually blend two pixels in parallel, if we take @@ -258,198 +253,198 @@ */ /* helper: blend a single 16 bit pixel at 50% */ -#define BLEND16_50(dst, src, mask) \ - do { \ - Uint32 s = *src++; \ - Uint32 d = *dst; \ - *dst++ = (Uint16)((((s & mask) + (d & mask)) >> 1) + \ - (s & d & (~mask & 0xffff))); \ - } while(0) +#define BLEND16_50(dst, src, mask) \ + do { \ + Uint32 s = *src++; \ + Uint32 d = *dst; \ + *dst++ = (Uint16)((((s & mask) + (d & mask)) >> 1) + \ + (s & d & (~mask & 0xffff))); \ + } while (0) /* basic 16bpp blender. mask is the pixels to keep when adding. */ -#define ALPHA_BLIT16_50(to, from, length, bpp, alpha, mask) \ - do { \ - unsigned n = (length); \ - Uint16 *src = (Uint16 *)(from); \ - Uint16 *dst = (Uint16 *)(to); \ - if (((uintptr_t)src ^ (uintptr_t)dst) & 3) { \ - /* source and destination not in phase, blit one by one */ \ - while (n--) \ - BLEND16_50(dst, src, mask); \ - } else { \ - if ((uintptr_t)src & 3) { \ - /* first odd pixel */ \ - BLEND16_50(dst, src, mask); \ - n--; \ - } \ - for (; n > 1; n -= 2) { \ - Uint32 s = *(Uint32 *)src; \ - Uint32 d = *(Uint32 *)dst; \ - *(Uint32 *)dst = ((s & (mask | mask << 16)) >> 1) \ - + ((d & (mask | mask << 16)) >> 1) \ - + (s & d & (~(mask | mask << 16))); \ - src += 2; \ - dst += 2; \ - } \ - if (n) \ - BLEND16_50(dst, src, mask); /* last odd pixel */ \ - } \ - } while(0) +#define ALPHA_BLIT16_50(to, from, length, bpp, alpha, mask) \ + do { \ + unsigned n = (length); \ + Uint16 *src = (Uint16 *)(from); \ + Uint16 *dst = (Uint16 *)(to); \ + if (((uintptr_t)src ^ (uintptr_t)dst) & 3) { \ + /* source and destination not in phase, blit one by one */ \ + while (n--) \ + BLEND16_50(dst, src, mask); \ + } else { \ + if ((uintptr_t)src & 3) { \ + /* first odd pixel */ \ + BLEND16_50(dst, src, mask); \ + n--; \ + } \ + for (; n > 1; n -= 2) { \ + Uint32 s = *(Uint32 *)src; \ + Uint32 d = *(Uint32 *)dst; \ + *(Uint32 *)dst = ((s & (mask | mask << 16)) >> 1) + ((d & (mask | mask << 16)) >> 1) + (s & d & (~(mask | mask << 16))); \ + src += 2; \ + dst += 2; \ + } \ + if (n) \ + BLEND16_50(dst, src, mask); /* last odd pixel */ \ + } \ + } while (0) -#define ALPHA_BLIT16_565_50(to, from, length, bpp, alpha) \ +#define ALPHA_BLIT16_565_50(to, from, length, bpp, alpha) \ ALPHA_BLIT16_50(to, from, length, bpp, alpha, 0xf7deU) -#define ALPHA_BLIT16_555_50(to, from, length, bpp, alpha) \ +#define ALPHA_BLIT16_555_50(to, from, length, bpp, alpha) \ ALPHA_BLIT16_50(to, from, length, bpp, alpha, 0xfbdeU) -#define CHOOSE_BLIT(blitter, alpha, fmt) \ - do { \ - if (alpha == 255) { \ - switch (fmt->BytesPerPixel) { \ - case 1: blitter(1, Uint8, OPAQUE_BLIT); break; \ - case 2: blitter(2, Uint8, OPAQUE_BLIT); break; \ - case 3: blitter(3, Uint8, OPAQUE_BLIT); break; \ - case 4: blitter(4, Uint16, OPAQUE_BLIT); break; \ - } \ - } else { \ - switch (fmt->BytesPerPixel) { \ - case 1: \ - /* No 8bpp alpha blitting */ \ - break; \ - \ - case 2: \ - switch (fmt->Rmask | fmt->Gmask | fmt->Bmask) { \ - case 0xffff: \ - if (fmt->Gmask == 0x07e0 \ - || fmt->Rmask == 0x07e0 \ - || fmt->Bmask == 0x07e0) { \ - if (alpha == 128) { \ - blitter(2, Uint8, ALPHA_BLIT16_565_50); \ - } else { \ - blitter(2, Uint8, ALPHA_BLIT16_565); \ - } \ - } else \ - goto general16; \ - break; \ - \ - case 0x7fff: \ - if (fmt->Gmask == 0x03e0 \ - || fmt->Rmask == 0x03e0 \ - || fmt->Bmask == 0x03e0) { \ - if (alpha == 128) { \ - blitter(2, Uint8, ALPHA_BLIT16_555_50); \ - } else { \ - blitter(2, Uint8, ALPHA_BLIT16_555); \ - } \ - break; \ - } else \ - goto general16; \ - break; \ - \ - default: \ - general16: \ - blitter(2, Uint8, ALPHA_BLIT_ANY); \ - } \ - break; \ - \ - case 3: \ - blitter(3, Uint8, ALPHA_BLIT_ANY); \ - break; \ - \ - case 4: \ - if ((fmt->Rmask | fmt->Gmask | fmt->Bmask) == 0x00ffffff \ - && (fmt->Gmask == 0xff00 || fmt->Rmask == 0xff00 \ - || fmt->Bmask == 0xff00)) { \ - if (alpha == 128) { \ - blitter(4, Uint16, ALPHA_BLIT32_888_50); \ - } else { \ - blitter(4, Uint16, ALPHA_BLIT32_888); \ - } \ - } else \ - blitter(4, Uint16, ALPHA_BLIT_ANY); \ - break; \ - } \ - } \ - } while(0) +#define CHOOSE_BLIT(blitter, alpha, fmt) \ + do { \ + if (alpha == 255) { \ + switch (fmt->BytesPerPixel) { \ + case 1: \ + blitter(1, Uint8, OPAQUE_BLIT); \ + break; \ + case 2: \ + blitter(2, Uint8, OPAQUE_BLIT); \ + break; \ + case 3: \ + blitter(3, Uint8, OPAQUE_BLIT); \ + break; \ + case 4: \ + blitter(4, Uint16, OPAQUE_BLIT); \ + break; \ + } \ + } else { \ + switch (fmt->BytesPerPixel) { \ + case 1: \ + /* No 8bpp alpha blitting */ \ + break; \ + \ + case 2: \ + switch (fmt->Rmask | fmt->Gmask | fmt->Bmask) { \ + case 0xffff: \ + if (fmt->Gmask == 0x07e0 || fmt->Rmask == 0x07e0 || fmt->Bmask == 0x07e0) { \ + if (alpha == 128) { \ + blitter(2, Uint8, ALPHA_BLIT16_565_50); \ + } else { \ + blitter(2, Uint8, ALPHA_BLIT16_565); \ + } \ + } else { \ + goto general16; \ + } \ + break; \ + \ + case 0x7fff: \ + if (fmt->Gmask == 0x03e0 || fmt->Rmask == 0x03e0 || fmt->Bmask == 0x03e0) { \ + if (alpha == 128) { \ + blitter(2, Uint8, ALPHA_BLIT16_555_50); \ + } else { \ + blitter(2, Uint8, ALPHA_BLIT16_555); \ + } \ + break; \ + } else { \ + goto general16; \ + } \ + break; \ + \ + default: \ + general16: \ + blitter(2, Uint8, ALPHA_BLIT_ANY); \ + } \ + break; \ + \ + case 3: \ + blitter(3, Uint8, ALPHA_BLIT_ANY); \ + break; \ + \ + case 4: \ + if ((fmt->Rmask | fmt->Gmask | fmt->Bmask) == 0x00ffffff && (fmt->Gmask == 0xff00 || fmt->Rmask == 0xff00 || fmt->Bmask == 0xff00)) { \ + if (alpha == 128) { \ + blitter(4, Uint16, ALPHA_BLIT32_888_50); \ + } else { \ + blitter(4, Uint16, ALPHA_BLIT32_888); \ + } \ + } else { \ + blitter(4, Uint16, ALPHA_BLIT_ANY); \ + } \ + break; \ + } \ + } \ + } while (0) /* * Set a pixel value using the given format, except that the alpha value is * placed in the top byte. This is the format used for RLE with alpha. */ -#define RLEPIXEL_FROM_RGBA(Pixel, fmt, r, g, b, a) \ -{ \ - Pixel = ((r>>fmt->Rloss)<Rshift)| \ - ((g>>fmt->Gloss)<Gshift)| \ - ((b>>fmt->Bloss)<Bshift)| \ - (a<<24); \ -} +#define RLEPIXEL_FROM_RGBA(Pixel, fmt, r, g, b, a) \ + { \ + Pixel = ((r >> fmt->Rloss) << fmt->Rshift) | \ + ((g >> fmt->Gloss) << fmt->Gshift) | \ + ((b >> fmt->Bloss) << fmt->Bshift) | \ + (a << 24); \ + } /* * This takes care of the case when the surface is clipped on the left and/or * right. Top clipping has already been taken care of. */ -static void -RLEClipBlit(int w, Uint8 * srcbuf, SDL_Surface * surf_dst, - Uint8 * dstbuf, SDL_Rect * srcrect, unsigned alpha) +#define RLECLIPBLIT(bpp, Type, do_blit) \ + do { \ + int linecount = srcrect->h; \ + int ofs = 0; \ + int left = srcrect->x; \ + int right = left + srcrect->w; \ + dstbuf -= left * bpp; \ + for (;;) { \ + int run; \ + ofs += *(Type *)srcbuf; \ + run = ((Type *)srcbuf)[1]; \ + srcbuf += 2 * sizeof(Type); \ + if (run) { \ + /* clip to left and right borders */ \ + if (ofs < right) { \ + int start = 0; \ + int len = run; \ + int startcol; \ + if (left - ofs > 0) { \ + start = left - ofs; \ + len -= start; \ + if (len <= 0) \ + goto nocopy##bpp##do_blit; \ + } \ + startcol = ofs + start; \ + if (len > right - startcol) \ + len = right - startcol; \ + do_blit(dstbuf + startcol * bpp, srcbuf + start * bpp, \ + len, bpp, alpha); \ + } \ + nocopy##bpp##do_blit : srcbuf += run * bpp; \ + ofs += run; \ + } else if (!ofs) { \ + break; \ + } \ + \ + if (ofs == w) { \ + ofs = 0; \ + dstbuf += surf_dst->pitch; \ + if (!--linecount) { \ + break; \ + } \ + } \ + } \ + } while (0) + +static void RLEClipBlit(int w, Uint8 *srcbuf, SDL_Surface *surf_dst, + Uint8 *dstbuf, SDL_Rect *srcrect, unsigned alpha) { SDL_PixelFormat *fmt = surf_dst->format; -#define RLECLIPBLIT(bpp, Type, do_blit) \ - do { \ - int linecount = srcrect->h; \ - int ofs = 0; \ - int left = srcrect->x; \ - int right = left + srcrect->w; \ - dstbuf -= left * bpp; \ - for (;;) { \ - int run; \ - ofs += *(Type *)srcbuf; \ - run = ((Type *)srcbuf)[1]; \ - srcbuf += 2 * sizeof(Type); \ - if (run) { \ - /* clip to left and right borders */ \ - if (ofs < right) { \ - int start = 0; \ - int len = run; \ - int startcol; \ - if (left - ofs > 0) { \ - start = left - ofs; \ - len -= start; \ - if (len <= 0) \ - goto nocopy ## bpp ## do_blit; \ - } \ - startcol = ofs + start; \ - if (len > right - startcol) \ - len = right - startcol; \ - do_blit(dstbuf + startcol * bpp, srcbuf + start * bpp, \ - len, bpp, alpha); \ - } \ - nocopy ## bpp ## do_blit: \ - srcbuf += run * bpp; \ - ofs += run; \ - } else if (!ofs) \ - break; \ - \ - if (ofs == w) { \ - ofs = 0; \ - dstbuf += surf_dst->pitch; \ - if (!--linecount) \ - break; \ - } \ - } \ - } while(0) - CHOOSE_BLIT(RLECLIPBLIT, alpha, fmt); +} #undef RLECLIPBLIT -} - - /* blit a colorkeyed RLE surface */ -static int SDLCALL -SDL_RLEBlit(SDL_Surface * surf_src, SDL_Rect * srcrect, - SDL_Surface * surf_dst, SDL_Rect * dstrect) +static int SDLCALL SDL_RLEBlit(SDL_Surface *surf_src, SDL_Rect *srcrect, + SDL_Surface *surf_dst, SDL_Rect *dstrect) { Uint8 *dstbuf; Uint8 *srcbuf; @@ -460,16 +455,15 @@ SDL_RLEBlit(SDL_Surface * surf_src, SDL_Rect * srcrect, /* Lock the destination if necessary */ if (SDL_MUSTLOCK(surf_dst)) { if (SDL_LockSurface(surf_dst) < 0) { - return (-1); + return -1; } } /* Set up the source and destination pointers */ x = dstrect->x; y = dstrect->y; - dstbuf = (Uint8 *) surf_dst->pixels - + y * surf_dst->pitch + x * surf_src->format->BytesPerPixel; - srcbuf = (Uint8 *) surf_src->map->data; + dstbuf = (Uint8 *)surf_dst->pixels + y * surf_dst->pitch + x * surf_src->format->BytesPerPixel; + srcbuf = (Uint8 *)surf_src->map->data; { /* skip lines at the top if necessary */ @@ -478,22 +472,22 @@ SDL_RLEBlit(SDL_Surface * surf_src, SDL_Rect * srcrect, if (vskip) { #define RLESKIP(bpp, Type) \ - for(;;) { \ - int run; \ - ofs += *(Type *)srcbuf; \ - run = ((Type *)srcbuf)[1]; \ - srcbuf += sizeof(Type) * 2; \ - if(run) { \ + for (;;) { \ + int run; \ + ofs += *(Type *)srcbuf; \ + run = ((Type *)srcbuf)[1]; \ + srcbuf += sizeof(Type) * 2; \ + if (run) { \ srcbuf += run * bpp; \ - ofs += run; \ - } else if(!ofs) \ - goto done; \ - if(ofs == w) { \ - ofs = 0; \ - if(!--vskip) \ - break; \ - } \ - } + ofs += run; \ + } else if (!ofs) \ + goto done; \ + if (ofs == w) { \ + ofs = 0; \ + if (!--vskip) \ + break; \ + } \ + } switch (surf_src->format->BytesPerPixel) { case 1: @@ -511,7 +505,6 @@ SDL_RLEBlit(SDL_Surface * surf_src, SDL_Rect * srcrect, } #undef RLESKIP - } } @@ -522,41 +515,41 @@ SDL_RLEBlit(SDL_Surface * surf_src, SDL_Rect * srcrect, } else { SDL_PixelFormat *fmt = surf_src->format; -#define RLEBLIT(bpp, Type, do_blit) \ - do { \ - int linecount = srcrect->h; \ - int ofs = 0; \ - for(;;) { \ - unsigned run; \ - ofs += *(Type *)srcbuf; \ - run = ((Type *)srcbuf)[1]; \ - srcbuf += 2 * sizeof(Type); \ - if(run) { \ - do_blit(dstbuf + ofs * bpp, srcbuf, run, bpp, alpha); \ - srcbuf += run * bpp; \ - ofs += run; \ - } else if(!ofs) \ - break; \ - if(ofs == w) { \ - ofs = 0; \ - dstbuf += surf_dst->pitch; \ - if(!--linecount) \ - break; \ - } \ - } \ - } while(0) +#define RLEBLIT(bpp, Type, do_blit) \ + do { \ + int linecount = srcrect->h; \ + int ofs = 0; \ + for (;;) { \ + unsigned run; \ + ofs += *(Type *)srcbuf; \ + run = ((Type *)srcbuf)[1]; \ + srcbuf += 2 * sizeof(Type); \ + if (run) { \ + do_blit(dstbuf + ofs * bpp, srcbuf, run, bpp, alpha); \ + srcbuf += run * bpp; \ + ofs += run; \ + } else if (!ofs) \ + break; \ + if (ofs == w) { \ + ofs = 0; \ + dstbuf += surf_dst->pitch; \ + if (!--linecount) \ + break; \ + } \ + } \ + } while (0) CHOOSE_BLIT(RLEBLIT, alpha, fmt); #undef RLEBLIT } - done: +done: /* Unlock the destination if necessary */ if (SDL_MUSTLOCK(surf_dst)) { SDL_UnlockSurface(surf_dst); } - return (0); + return 0; } #undef OPAQUE_BLIT @@ -570,47 +563,47 @@ SDL_RLEBlit(SDL_Surface * surf_src, SDL_Rect * srcrect, * For 32bpp pixels, we have made sure the alpha is stored in the top * 8 bits, so proceed as usual */ -#define BLIT_TRANSL_888(src, dst) \ - do { \ - Uint32 s = src; \ - Uint32 d = dst; \ - unsigned alpha = s >> 24; \ - Uint32 s1 = s & 0xff00ff; \ - Uint32 d1 = d & 0xff00ff; \ - d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff; \ - s &= 0xff00; \ - d &= 0xff00; \ - d = (d + ((s - d) * alpha >> 8)) & 0xff00; \ - dst = d1 | d | 0xff000000; \ - } while(0) +#define BLIT_TRANSL_888(src, dst) \ + do { \ + Uint32 s = src; \ + Uint32 d = dst; \ + unsigned alpha = s >> 24; \ + Uint32 s1 = s & 0xff00ff; \ + Uint32 d1 = d & 0xff00ff; \ + d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff; \ + s &= 0xff00; \ + d &= 0xff00; \ + d = (d + ((s - d) * alpha >> 8)) & 0xff00; \ + dst = d1 | d | 0xff000000; \ + } while (0) /* * For 16bpp pixels, we have stored the 5 most significant alpha bits in * bits 5-10. As before, we can process all 3 RGB components at the same time. */ -#define BLIT_TRANSL_565(src, dst) \ - do { \ - Uint32 s = src; \ - Uint32 d = dst; \ - unsigned alpha = (s & 0x3e0) >> 5; \ - s &= 0x07e0f81f; \ - d = (d | d << 16) & 0x07e0f81f; \ - d += (s - d) * alpha >> 5; \ - d &= 0x07e0f81f; \ - dst = (Uint16)(d | d >> 16); \ - } while(0) +#define BLIT_TRANSL_565(src, dst) \ + do { \ + Uint32 s = src; \ + Uint32 d = dst; \ + unsigned alpha = (s & 0x3e0) >> 5; \ + s &= 0x07e0f81f; \ + d = (d | d << 16) & 0x07e0f81f; \ + d += (s - d) * alpha >> 5; \ + d &= 0x07e0f81f; \ + dst = (Uint16)(d | d >> 16); \ + } while (0) -#define BLIT_TRANSL_555(src, dst) \ - do { \ - Uint32 s = src; \ - Uint32 d = dst; \ - unsigned alpha = (s & 0x3e0) >> 5; \ - s &= 0x03e07c1f; \ - d = (d | d << 16) & 0x03e07c1f; \ - d += (s - d) * alpha >> 5; \ - d &= 0x03e07c1f; \ - dst = (Uint16)(d | d >> 16); \ - } while(0) +#define BLIT_TRANSL_555(src, dst) \ + do { \ + Uint32 s = src; \ + Uint32 d = dst; \ + unsigned alpha = (s & 0x3e0) >> 5; \ + s &= 0x03e07c1f; \ + d = (d | d << 16) & 0x03e07c1f; \ + d += (s - d) * alpha >> 5; \ + d &= 0x03e07c1f; \ + dst = (Uint16)(d | d >> 16); \ + } while (0) /* used to save the destination format in the encoding. Designed to be macro-compatible with SDL_PixelFormat but without the unneeded fields */ @@ -633,9 +626,8 @@ typedef struct } RLEDestFormat; /* blit a pixel-alpha RLE surface clipped at the right and/or left edges */ -static void -RLEAlphaClipBlit(int w, Uint8 * srcbuf, SDL_Surface * surf_dst, - Uint8 * dstbuf, SDL_Rect * srcrect) +static void RLEAlphaClipBlit(int w, Uint8 *srcbuf, SDL_Surface *surf_dst, + Uint8 *dstbuf, SDL_Rect *srcrect) { SDL_PixelFormat *df = surf_dst->format; /* @@ -643,80 +635,81 @@ RLEAlphaClipBlit(int w, Uint8 * srcbuf, SDL_Surface * surf_dst, * Ctype the translucent count type, and do_blend the macro * to blend one pixel. */ -#define RLEALPHACLIPBLIT(Ptype, Ctype, do_blend) \ - do { \ - int linecount = srcrect->h; \ - int left = srcrect->x; \ - int right = left + srcrect->w; \ - dstbuf -= left * sizeof(Ptype); \ - do { \ - int ofs = 0; \ - /* blit opaque pixels on one line */ \ - do { \ - unsigned run; \ - ofs += ((Ctype *)srcbuf)[0]; \ - run = ((Ctype *)srcbuf)[1]; \ - srcbuf += 2 * sizeof(Ctype); \ - if(run) { \ - /* clip to left and right borders */ \ - int cofs = ofs; \ - int crun = run; \ - if(left - cofs > 0) { \ - crun -= left - cofs; \ - cofs = left; \ - } \ - if(crun > right - cofs) \ - crun = right - cofs; \ - if(crun > 0) \ - PIXEL_COPY(dstbuf + cofs * sizeof(Ptype), \ - srcbuf + (cofs - ofs) * sizeof(Ptype), \ - (unsigned)crun, sizeof(Ptype)); \ - srcbuf += run * sizeof(Ptype); \ - ofs += run; \ - } else if(!ofs) \ - return; \ - } while(ofs < w); \ - /* skip padding if necessary */ \ - if(sizeof(Ptype) == 2) \ - srcbuf += (uintptr_t)srcbuf & 2; \ - /* blit translucent pixels on the same line */ \ - ofs = 0; \ - do { \ - unsigned run; \ - ofs += ((Uint16 *)srcbuf)[0]; \ - run = ((Uint16 *)srcbuf)[1]; \ - srcbuf += 4; \ - if(run) { \ - /* clip to left and right borders */ \ - int cofs = ofs; \ - int crun = run; \ - if(left - cofs > 0) { \ - crun -= left - cofs; \ - cofs = left; \ - } \ - if(crun > right - cofs) \ - crun = right - cofs; \ - if(crun > 0) { \ - Ptype *dst = (Ptype *)dstbuf + cofs; \ - Uint32 *src = (Uint32 *)srcbuf + (cofs - ofs); \ - int i; \ - for(i = 0; i < crun; i++) \ - do_blend(src[i], dst[i]); \ - } \ - srcbuf += run * 4; \ - ofs += run; \ - } \ - } while(ofs < w); \ - dstbuf += surf_dst->pitch; \ - } while(--linecount); \ - } while(0) +#define RLEALPHACLIPBLIT(Ptype, Ctype, do_blend) \ + do { \ + int linecount = srcrect->h; \ + int left = srcrect->x; \ + int right = left + srcrect->w; \ + dstbuf -= left * sizeof(Ptype); \ + do { \ + int ofs = 0; \ + /* blit opaque pixels on one line */ \ + do { \ + unsigned run; \ + ofs += ((Ctype *)srcbuf)[0]; \ + run = ((Ctype *)srcbuf)[1]; \ + srcbuf += 2 * sizeof(Ctype); \ + if (run) { \ + /* clip to left and right borders */ \ + int cofs = ofs; \ + int crun = run; \ + if (left - cofs > 0) { \ + crun -= left - cofs; \ + cofs = left; \ + } \ + if (crun > right - cofs) \ + crun = right - cofs; \ + if (crun > 0) \ + PIXEL_COPY(dstbuf + cofs * sizeof(Ptype), \ + srcbuf + (cofs - ofs) * sizeof(Ptype), \ + (unsigned)crun, sizeof(Ptype)); \ + srcbuf += run * sizeof(Ptype); \ + ofs += run; \ + } else if (!ofs) \ + return; \ + } while (ofs < w); \ + /* skip padding if necessary */ \ + if (sizeof(Ptype) == 2) \ + srcbuf += (uintptr_t)srcbuf & 2; \ + /* blit translucent pixels on the same line */ \ + ofs = 0; \ + do { \ + unsigned run; \ + ofs += ((Uint16 *)srcbuf)[0]; \ + run = ((Uint16 *)srcbuf)[1]; \ + srcbuf += 4; \ + if (run) { \ + /* clip to left and right borders */ \ + int cofs = ofs; \ + int crun = run; \ + if (left - cofs > 0) { \ + crun -= left - cofs; \ + cofs = left; \ + } \ + if (crun > right - cofs) \ + crun = right - cofs; \ + if (crun > 0) { \ + Ptype *dst = (Ptype *)dstbuf + cofs; \ + Uint32 *src = (Uint32 *)srcbuf + (cofs - ofs); \ + int i; \ + for (i = 0; i < crun; i++) \ + do_blend(src[i], dst[i]); \ + } \ + srcbuf += run * 4; \ + ofs += run; \ + } \ + } while (ofs < w); \ + dstbuf += surf_dst->pitch; \ + } while (--linecount); \ + } while (0) switch (df->BytesPerPixel) { case 2: - if (df->Gmask == 0x07e0 || df->Rmask == 0x07e0 || df->Bmask == 0x07e0) + if (df->Gmask == 0x07e0 || df->Rmask == 0x07e0 || df->Bmask == 0x07e0) { RLEALPHACLIPBLIT(Uint16, Uint8, BLIT_TRANSL_565); - else + } else { RLEALPHACLIPBLIT(Uint16, Uint8, BLIT_TRANSL_555); + } break; case 4: RLEALPHACLIPBLIT(Uint32, Uint16, BLIT_TRANSL_888); @@ -725,9 +718,8 @@ RLEAlphaClipBlit(int w, Uint8 * srcbuf, SDL_Surface * surf_dst, } /* blit a pixel-alpha RLE surface */ -static int SDLCALL -SDL_RLEAlphaBlit(SDL_Surface * surf_src, SDL_Rect * srcrect, - SDL_Surface * surf_dst, SDL_Rect * dstrect) +static int SDLCALL SDL_RLEAlphaBlit(SDL_Surface *surf_src, SDL_Rect *srcrect, + SDL_Surface *surf_dst, SDL_Rect *dstrect) { int x, y; int w = surf_src->w; @@ -743,8 +735,8 @@ SDL_RLEAlphaBlit(SDL_Surface * surf_src, SDL_Rect * srcrect, x = dstrect->x; y = dstrect->y; - dstbuf = (Uint8 *) surf_dst->pixels + y * surf_dst->pitch + x * df->BytesPerPixel; - srcbuf = (Uint8 *) surf_src->map->data + sizeof(RLEDestFormat); + dstbuf = (Uint8 *)surf_dst->pixels + y * surf_dst->pitch + x * df->BytesPerPixel; + srcbuf = (Uint8 *)surf_src->map->data + sizeof(RLEDestFormat); { /* skip lines at the top if necessary */ @@ -764,38 +756,40 @@ SDL_RLEAlphaBlit(SDL_Surface * surf_src, SDL_Rect * srcrect, if (run) { srcbuf += 2 * run; ofs += run; - } else if (!ofs) + } else if (ofs == 0) { goto done; + } } while (ofs < w); /* skip padding */ - srcbuf += (uintptr_t) srcbuf & 2; + srcbuf += (uintptr_t)srcbuf & 2; /* skip translucent line */ ofs = 0; do { int run; - ofs += ((Uint16 *) srcbuf)[0]; - run = ((Uint16 *) srcbuf)[1]; + ofs += ((Uint16 *)srcbuf)[0]; + run = ((Uint16 *)srcbuf)[1]; srcbuf += 4 * (run + 1); ofs += run; } while (ofs < w); } while (--vskip); } else { /* the 32/32 interleaved format */ - vskip <<= 1; /* opaque and translucent have same format */ + vskip <<= 1; /* opaque and translucent have same format */ do { ofs = 0; do { int run; - ofs += ((Uint16 *) srcbuf)[0]; - run = ((Uint16 *) srcbuf)[1]; + ofs += ((Uint16 *)srcbuf)[0]; + run = ((Uint16 *)srcbuf)[1]; srcbuf += 4; if (run) { srcbuf += 4 * run; ofs += run; - } else if (!ofs) + } else if (ofs == 0) { goto done; + } } while (ofs < w); } while (--vskip); } @@ -812,58 +806,58 @@ SDL_RLEAlphaBlit(SDL_Surface * surf_src, SDL_Rect * srcrect, * Ctype the translucent count type, and do_blend the * macro to blend one pixel. */ -#define RLEALPHABLIT(Ptype, Ctype, do_blend) \ - do { \ - int linecount = srcrect->h; \ - do { \ - int ofs = 0; \ - /* blit opaque pixels on one line */ \ - do { \ - unsigned run; \ - ofs += ((Ctype *)srcbuf)[0]; \ - run = ((Ctype *)srcbuf)[1]; \ - srcbuf += 2 * sizeof(Ctype); \ - if(run) { \ - PIXEL_COPY(dstbuf + ofs * sizeof(Ptype), srcbuf, \ - run, sizeof(Ptype)); \ - srcbuf += run * sizeof(Ptype); \ - ofs += run; \ - } else if(!ofs) \ - goto done; \ - } while(ofs < w); \ - /* skip padding if necessary */ \ - if(sizeof(Ptype) == 2) \ - srcbuf += (uintptr_t)srcbuf & 2; \ - /* blit translucent pixels on the same line */ \ - ofs = 0; \ - do { \ - unsigned run; \ - ofs += ((Uint16 *)srcbuf)[0]; \ - run = ((Uint16 *)srcbuf)[1]; \ - srcbuf += 4; \ - if(run) { \ - Ptype *dst = (Ptype *)dstbuf + ofs; \ - unsigned i; \ - for(i = 0; i < run; i++) { \ - Uint32 src = *(Uint32 *)srcbuf; \ - do_blend(src, *dst); \ - srcbuf += 4; \ - dst++; \ - } \ - ofs += run; \ - } \ - } while(ofs < w); \ - dstbuf += surf_dst->pitch; \ - } while(--linecount); \ - } while(0) +#define RLEALPHABLIT(Ptype, Ctype, do_blend) \ + do { \ + int linecount = srcrect->h; \ + do { \ + int ofs = 0; \ + /* blit opaque pixels on one line */ \ + do { \ + unsigned run; \ + ofs += ((Ctype *)srcbuf)[0]; \ + run = ((Ctype *)srcbuf)[1]; \ + srcbuf += 2 * sizeof(Ctype); \ + if (run) { \ + PIXEL_COPY(dstbuf + ofs * sizeof(Ptype), srcbuf, \ + run, sizeof(Ptype)); \ + srcbuf += run * sizeof(Ptype); \ + ofs += run; \ + } else if (!ofs) \ + goto done; \ + } while (ofs < w); \ + /* skip padding if necessary */ \ + if (sizeof(Ptype) == 2) \ + srcbuf += (uintptr_t)srcbuf & 2; \ + /* blit translucent pixels on the same line */ \ + ofs = 0; \ + do { \ + unsigned run; \ + ofs += ((Uint16 *)srcbuf)[0]; \ + run = ((Uint16 *)srcbuf)[1]; \ + srcbuf += 4; \ + if (run) { \ + Ptype *dst = (Ptype *)dstbuf + ofs; \ + unsigned i; \ + for (i = 0; i < run; i++) { \ + Uint32 src = *(Uint32 *)srcbuf; \ + do_blend(src, *dst); \ + srcbuf += 4; \ + dst++; \ + } \ + ofs += run; \ + } \ + } while (ofs < w); \ + dstbuf += surf_dst->pitch; \ + } while (--linecount); \ + } while (0) switch (df->BytesPerPixel) { case 2: - if (df->Gmask == 0x07e0 || df->Rmask == 0x07e0 - || df->Bmask == 0x07e0) + if (df->Gmask == 0x07e0 || df->Rmask == 0x07e0 || df->Bmask == 0x07e0) { RLEALPHABLIT(Uint16, Uint8, BLIT_TRANSL_565); - else + } else { RLEALPHABLIT(Uint16, Uint8, BLIT_TRANSL_555); + } break; case 4: RLEALPHABLIT(Uint32, Uint16, BLIT_TRANSL_888); @@ -871,7 +865,7 @@ SDL_RLEAlphaBlit(SDL_Surface * surf_src, SDL_Rect * srcrect, } } - done: +done: /* Unlock the destination if necessary */ if (SDL_MUSTLOCK(surf_dst)) { SDL_UnlockSurface(surf_dst); @@ -890,9 +884,8 @@ SDL_RLEAlphaBlit(SDL_Surface * surf_src, SDL_Rect * srcrect, */ /* encode 32bpp rgb + a into 16bpp rgb, losing alpha */ -static int -copy_opaque_16(void *dst, Uint32 * src, int n, - SDL_PixelFormat * sfmt, SDL_PixelFormat * dfmt) +static int copy_opaque_16(void *dst, Uint32 *src, int n, + SDL_PixelFormat *sfmt, SDL_PixelFormat *dfmt) { int i; Uint16 *d = dst; @@ -907,9 +900,8 @@ copy_opaque_16(void *dst, Uint32 * src, int n, } /* decode opaque pixels from 16bpp to 32bpp rgb + a */ -static int -uncopy_opaque_16(Uint32 * dst, void *src, int n, - RLEDestFormat * sfmt, SDL_PixelFormat * dfmt) +static int uncopy_opaque_16(Uint32 *dst, void *src, int n, + RLEDestFormat *sfmt, SDL_PixelFormat *dfmt) { int i; Uint16 *s = src; @@ -924,12 +916,9 @@ uncopy_opaque_16(Uint32 * dst, void *src, int n, return n * 2; } - - /* encode 32bpp rgb + a into 32bpp G0RAB format for blitting into 565 */ -static int -copy_transl_565(void *dst, Uint32 * src, int n, - SDL_PixelFormat * sfmt, SDL_PixelFormat * dfmt) +static int copy_transl_565(void *dst, Uint32 *src, int n, + SDL_PixelFormat *sfmt, SDL_PixelFormat *dfmt) { int i; Uint32 *d = dst; @@ -946,9 +935,8 @@ copy_transl_565(void *dst, Uint32 * src, int n, } /* encode 32bpp rgb + a into 32bpp G0RAB format for blitting into 555 */ -static int -copy_transl_555(void *dst, Uint32 * src, int n, - SDL_PixelFormat * sfmt, SDL_PixelFormat * dfmt) +static int copy_transl_555(void *dst, Uint32 *src, int n, + SDL_PixelFormat *sfmt, SDL_PixelFormat *dfmt) { int i; Uint32 *d = dst; @@ -965,9 +953,8 @@ copy_transl_555(void *dst, Uint32 * src, int n, } /* decode translucent pixels from 32bpp GORAB to 32bpp rgb + a */ -static int -uncopy_transl_16(Uint32 * dst, void *src, int n, - RLEDestFormat * sfmt, SDL_PixelFormat * dfmt) +static int uncopy_transl_16(Uint32 *dst, void *src, int n, + RLEDestFormat *sfmt, SDL_PixelFormat *dfmt) { int i; Uint32 *s = src; @@ -984,9 +971,8 @@ uncopy_transl_16(Uint32 * dst, void *src, int n, } /* encode 32bpp rgba into 32bpp rgba, keeping alpha (dual purpose) */ -static int -copy_32(void *dst, Uint32 * src, int n, - SDL_PixelFormat * sfmt, SDL_PixelFormat * dfmt) +static int copy_32(void *dst, Uint32 *src, int n, + SDL_PixelFormat *sfmt, SDL_PixelFormat *dfmt) { int i; Uint32 *d = dst; @@ -1001,9 +987,8 @@ copy_32(void *dst, Uint32 * src, int n, } /* decode 32bpp rgba into 32bpp rgba, keeping alpha (dual purpose) */ -static int -uncopy_32(Uint32 * dst, void *src, int n, - RLEDestFormat * sfmt, SDL_PixelFormat * dfmt) +static int uncopy_32(Uint32 *dst, void *src, int n, + RLEDestFormat *sfmt, SDL_PixelFormat *dfmt) { int i; Uint32 *s = src; @@ -1018,14 +1003,13 @@ uncopy_32(Uint32 * dst, void *src, int n, return n * 4; } -#define ISOPAQUE(pixel, fmt) ((((pixel) & fmt->Amask) >> fmt->Ashift) == 255) +#define ISOPAQUE(pixel, fmt) ((((pixel)&fmt->Amask) >> fmt->Ashift) == 255) -#define ISTRANSL(pixel, fmt) \ - ((unsigned)((((pixel) & fmt->Amask) >> fmt->Ashift) - 1U) < 254U) +#define ISTRANSL(pixel, fmt) \ + ((unsigned)((((pixel)&fmt->Amask) >> fmt->Ashift) - 1U) < 254U) /* convert surface to be quickly alpha-blittable onto dest, if possible */ -static int -RLEAlphaSurface(SDL_Surface * surface) +static int RLEAlphaSurface(SDL_Surface *surface) { SDL_Surface *dest; SDL_PixelFormat *df; @@ -1034,17 +1018,19 @@ RLEAlphaSurface(SDL_Surface * surface) int max_transl_run = 65535; unsigned masksum; Uint8 *rlebuf, *dst; - int (*copy_opaque) (void *, Uint32 *, int, - SDL_PixelFormat *, SDL_PixelFormat *); - int (*copy_transl) (void *, Uint32 *, int, - SDL_PixelFormat *, SDL_PixelFormat *); + int (*copy_opaque)(void *, Uint32 *, int, + SDL_PixelFormat *, SDL_PixelFormat *); + int (*copy_transl)(void *, Uint32 *, int, + SDL_PixelFormat *, SDL_PixelFormat *); dest = surface->map->dst; - if (!dest) + if (!dest) { return -1; + } df = dest->format; - if (surface->format->BitsPerPixel != 32) - return -1; /* only 32bpp source supported */ + if (surface->format->BitsPerPixel != 32) { + return -1; /* only 32bpp source supported */ + } /* find out whether the destination is one we support, and determine the max size of the encoded result */ @@ -1054,52 +1040,53 @@ RLEAlphaSurface(SDL_Surface * surface) /* 16bpp: only support 565 and 555 formats */ switch (masksum) { case 0xffff: - if (df->Gmask == 0x07e0 - || df->Rmask == 0x07e0 || df->Bmask == 0x07e0) { + if (df->Gmask == 0x07e0 || df->Rmask == 0x07e0 || df->Bmask == 0x07e0) { copy_opaque = copy_opaque_16; copy_transl = copy_transl_565; - } else + } else { return -1; + } break; case 0x7fff: - if (df->Gmask == 0x03e0 - || df->Rmask == 0x03e0 || df->Bmask == 0x03e0) { + if (df->Gmask == 0x03e0 || df->Rmask == 0x03e0 || df->Bmask == 0x03e0) { copy_opaque = copy_opaque_16; copy_transl = copy_transl_555; - } else + } else { return -1; + } break; default: return -1; } - max_opaque_run = 255; /* runs stored as bytes */ + max_opaque_run = 255; /* runs stored as bytes */ /* worst case is alternating opaque and translucent pixels, with room for alignment padding between lines */ maxsize = surface->h * (2 + (4 + 2) * (surface->w + 1)) + 2; break; case 4: - if (masksum != 0x00ffffff) - return -1; /* requires unused high byte */ + if (masksum != 0x00ffffff) { + return -1; /* requires unused high byte */ + } copy_opaque = copy_32; copy_transl = copy_32; - max_opaque_run = 255; /* runs stored as short ints */ + max_opaque_run = 255; /* runs stored as short ints */ /* worst case is alternating opaque and translucent pixels */ maxsize = surface->h * 2 * 4 * (surface->w + 1) + 4; break; default: - return -1; /* anything else unsupported right now */ + return -1; /* anything else unsupported right now */ } maxsize += sizeof(RLEDestFormat); - rlebuf = (Uint8 *) SDL_malloc(maxsize); + rlebuf = (Uint8 *)SDL_malloc(maxsize); if (!rlebuf) { return SDL_OutOfMemory(); } { /* save the destination format so we can undo the encoding later */ - RLEDestFormat *r = (RLEDestFormat *) rlebuf; + RLEDestFormat *r = (RLEDestFormat *)rlebuf; r->BytesPerPixel = df->BytesPerPixel; r->Rmask = df->Rmask; r->Gmask = df->Gmask; @@ -1121,23 +1108,23 @@ RLEAlphaSurface(SDL_Surface * surface) int x, y; int h = surface->h, w = surface->w; SDL_PixelFormat *sf = surface->format; - Uint32 *src = (Uint32 *) surface->pixels; - Uint8 *lastline = dst; /* end of last non-blank line */ + Uint32 *src = (Uint32 *)surface->pixels; + Uint8 *lastline = dst; /* end of last non-blank line */ /* opaque counts are 8 or 16 bits, depending on target depth */ -#define ADD_OPAQUE_COUNTS(n, m) \ - if(df->BytesPerPixel == 4) { \ - ((Uint16 *)dst)[0] = n; \ - ((Uint16 *)dst)[1] = m; \ - dst += 4; \ - } else { \ - dst[0] = n; \ - dst[1] = m; \ - dst += 2; \ +#define ADD_OPAQUE_COUNTS(n, m) \ + if (df->BytesPerPixel == 4) { \ + ((Uint16 *)dst)[0] = n; \ + ((Uint16 *)dst)[1] = m; \ + dst += 4; \ + } else { \ + dst[0] = n; \ + dst[1] = m; \ + dst += 2; \ } /* translucent counts are always 16 bit */ -#define ADD_TRANSL_COUNTS(n, m) \ +#define ADD_TRANSL_COUNTS(n, m) \ (((Uint16 *)dst)[0] = n, ((Uint16 *)dst)[1] = m, dst += 4) for (y = 0; y < h; y++) { @@ -1148,26 +1135,29 @@ RLEAlphaSurface(SDL_Surface * surface) do { int run, skip, len; skipstart = x; - while (x < w && !ISOPAQUE(src[x], sf)) + while (x < w && !ISOPAQUE(src[x], sf)) { x++; + } runstart = x; - while (x < w && ISOPAQUE(src[x], sf)) + while (x < w && ISOPAQUE(src[x], sf)) { x++; + } skip = runstart - skipstart; - if (skip == w) + if (skip == w) { blankline = 1; + } run = x - runstart; while (skip > max_opaque_run) { ADD_OPAQUE_COUNTS(max_opaque_run, 0); skip -= max_opaque_run; } - len = MIN(run, max_opaque_run); + len = SDL_min(run, max_opaque_run); ADD_OPAQUE_COUNTS(skip, len); dst += copy_opaque(dst, src + runstart, len, sf, df); runstart += len; run -= len; while (run) { - len = MIN(run, max_opaque_run); + len = SDL_min(run, max_opaque_run); ADD_OPAQUE_COUNTS(0, len); dst += copy_opaque(dst, src + runstart, len, sf, df); runstart += len; @@ -1176,18 +1166,20 @@ RLEAlphaSurface(SDL_Surface * surface) } while (x < w); /* Make sure the next output address is 32-bit aligned */ - dst += (uintptr_t) dst & 2; + dst += (uintptr_t)dst & 2; /* Next, encode all translucent pixels of the same scan line */ x = 0; do { int run, skip, len; skipstart = x; - while (x < w && !ISTRANSL(src[x], sf)) + while (x < w && !ISTRANSL(src[x], sf)) { x++; + } runstart = x; - while (x < w && ISTRANSL(src[x], sf)) + while (x < w && ISTRANSL(src[x], sf)) { x++; + } skip = runstart - skipstart; blankline &= (skip == w); run = x - runstart; @@ -1195,25 +1187,26 @@ RLEAlphaSurface(SDL_Surface * surface) ADD_TRANSL_COUNTS(max_transl_run, 0); skip -= max_transl_run; } - len = MIN(run, max_transl_run); + len = SDL_min(run, max_transl_run); ADD_TRANSL_COUNTS(skip, len); dst += copy_transl(dst, src + runstart, len, sf, df); runstart += len; run -= len; while (run) { - len = MIN(run, max_transl_run); + len = SDL_min(run, max_transl_run); ADD_TRANSL_COUNTS(0, len); dst += copy_transl(dst, src + runstart, len, sf, df); runstart += len; run -= len; } - if (!blankline) + if (!blankline) { lastline = dst; + } } while (x < w); src += surface->pitch >> 2; } - dst = lastline; /* back up past trailing blank lines */ + dst = lastline; /* back up past trailing blank lines */ ADD_OPAQUE_COUNTS(0, 0); } @@ -1222,36 +1215,38 @@ RLEAlphaSurface(SDL_Surface * surface) /* Now that we have it encoded, release the original pixels */ if (!(surface->flags & SDL_PREALLOC)) { - SDL_SIMDFree(surface->pixels); + if (surface->flags & SDL_SIMD_ALIGNED) { + SDL_SIMDFree(surface->pixels); + surface->flags &= ~SDL_SIMD_ALIGNED; + } else { + SDL_free(surface->pixels); + } surface->pixels = NULL; - surface->flags &= ~SDL_SIMD_ALIGNED; } - /* realloc the buffer to release unused memory */ + /* reallocate the buffer to release unused memory */ { Uint8 *p = SDL_realloc(rlebuf, dst - rlebuf); - if (!p) + if (!p) { p = rlebuf; + } surface->map->data = p; } return 0; } -static Uint32 -getpix_8(const Uint8 * srcbuf) +static Uint32 getpix_8(const Uint8 *srcbuf) { return *srcbuf; } -static Uint32 -getpix_16(const Uint8 * srcbuf) +static Uint32 getpix_16(const Uint8 *srcbuf) { - return *(const Uint16 *) srcbuf; + return *(const Uint16 *)srcbuf; } -static Uint32 -getpix_24(const Uint8 * srcbuf) +static Uint32 getpix_24(const Uint8 *srcbuf) { #if SDL_BYTEORDER == SDL_LIL_ENDIAN return srcbuf[0] + (srcbuf[1] << 8) + (srcbuf[2] << 16); @@ -1260,20 +1255,18 @@ getpix_24(const Uint8 * srcbuf) #endif } -static Uint32 -getpix_32(const Uint8 * srcbuf) +static Uint32 getpix_32(const Uint8 *srcbuf) { - return *(const Uint32 *) srcbuf; + return *(const Uint32 *)srcbuf; } -typedef Uint32(*getpix_func) (const Uint8 *); +typedef Uint32 (*getpix_func)(const Uint8 *); static const getpix_func getpixes[4] = { getpix_8, getpix_16, getpix_24, getpix_32 }; -static int -RLEColorkeySurface(SDL_Surface * surface) +static int RLEColorkeySurface(SDL_Surface *surface) { Uint8 *rlebuf, *dst; int maxn; @@ -1295,26 +1288,24 @@ RLEColorkeySurface(SDL_Surface * surface) case 2: case 3: /* worst case is solid runs, at most 255 pixels wide */ - maxsize = surface->h * (2 * (surface->w / 255 + 1) - + surface->w * bpp) + 2; + maxsize = surface->h * (2 * (surface->w / 255 + 1) + surface->w * bpp) + 2; break; case 4: /* worst case is solid runs, at most 65535 pixels wide */ - maxsize = surface->h * (4 * (surface->w / 65535 + 1) - + surface->w * 4) + 4; + maxsize = surface->h * (4 * (surface->w / 65535 + 1) + surface->w * 4) + 4; break; default: return -1; } - rlebuf = (Uint8 *) SDL_malloc(maxsize); - if (rlebuf == NULL) { + rlebuf = (Uint8 *)SDL_malloc(maxsize); + if (!rlebuf) { return SDL_OutOfMemory(); } /* Set up the conversion */ - srcbuf = (Uint8 *) surface->pixels; + srcbuf = (Uint8 *)surface->pixels; maxn = bpp == 4 ? 65535 : 255; dst = rlebuf; rgbmask = ~surface->format->Amask; @@ -1324,12 +1315,12 @@ RLEColorkeySurface(SDL_Surface * surface) w = surface->w; h = surface->h; -#define ADD_COUNTS(n, m) \ - if(bpp == 4) { \ - ((Uint16 *)dst)[0] = n; \ - ((Uint16 *)dst)[1] = m; \ +#define ADD_COUNTS(n, m) \ + if (bpp == 4) { \ + ((Uint16 *)dst)[0] = n; \ + ((Uint16 *)dst)[1] = m; \ dst += 4; \ - } else { \ + } else { \ dst[0] = n; \ dst[1] = m; \ dst += 2; \ @@ -1339,19 +1330,23 @@ RLEColorkeySurface(SDL_Surface * surface) int x = 0; int blankline = 0; do { - int run, skip, len; + int run, skip; + int len; int runstart; int skipstart = x; /* find run of transparent, then opaque pixels */ - while (x < w && (getpix(srcbuf + x * bpp) & rgbmask) == ckey) + while (x < w && (getpix(srcbuf + x * bpp) & rgbmask) == ckey) { x++; + } runstart = x; - while (x < w && (getpix(srcbuf + x * bpp) & rgbmask) != ckey) + while (x < w && (getpix(srcbuf + x * bpp) & rgbmask) != ckey) { x++; + } skip = runstart - skipstart; - if (skip == w) + if (skip == w) { blankline = 1; + } run = x - runstart; /* encode segment */ @@ -1359,52 +1354,57 @@ RLEColorkeySurface(SDL_Surface * surface) ADD_COUNTS(maxn, 0); skip -= maxn; } - len = MIN(run, maxn); + len = SDL_min(run, maxn); ADD_COUNTS(skip, len); - SDL_memcpy(dst, srcbuf + runstart * bpp, len * bpp); + SDL_memcpy(dst, srcbuf + runstart * bpp, (size_t)len * bpp); dst += len * bpp; run -= len; runstart += len; while (run) { - len = MIN(run, maxn); + len = SDL_min(run, maxn); ADD_COUNTS(0, len); - SDL_memcpy(dst, srcbuf + runstart * bpp, len * bpp); + SDL_memcpy(dst, srcbuf + runstart * bpp, (size_t)len * bpp); dst += len * bpp; runstart += len; run -= len; } - if (!blankline) + if (!blankline) { lastline = dst; + } } while (x < w); srcbuf += surface->pitch; } - dst = lastline; /* back up bast trailing blank lines */ + dst = lastline; /* back up bast trailing blank lines */ ADD_COUNTS(0, 0); #undef ADD_COUNTS /* Now that we have it encoded, release the original pixels */ if (!(surface->flags & SDL_PREALLOC)) { - SDL_SIMDFree(surface->pixels); + if (surface->flags & SDL_SIMD_ALIGNED) { + SDL_SIMDFree(surface->pixels); + surface->flags &= ~SDL_SIMD_ALIGNED; + } else { + SDL_free(surface->pixels); + } surface->pixels = NULL; - surface->flags &= ~SDL_SIMD_ALIGNED; } - /* realloc the buffer to release unused memory */ + /* reallocate the buffer to release unused memory */ { - /* If realloc returns NULL, the original block is left intact */ + /* If SDL_realloc returns NULL, the original block is left intact */ Uint8 *p = SDL_realloc(rlebuf, dst - rlebuf); - if (!p) + if (!p) { p = rlebuf; + } surface->map->data = p; } return 0; } -int -SDL_RLESurface(SDL_Surface * surface) +int SDL_RLESurface(SDL_Surface *surface) { int flags; @@ -1423,9 +1423,13 @@ SDL_RLESurface(SDL_Surface * surface) return -1; } - /* If we don't have colorkey or blending, nothing to do... */ flags = surface->map->info.flags; - if (!(flags & (SDL_COPY_COLORKEY | SDL_COPY_BLEND))) { + if (flags & SDL_COPY_COLORKEY) { + /* ok */ + } else if ((flags & SDL_COPY_BLEND) && surface->format->Amask) { + /* ok */ + } else { + /* If we don't have colorkey or blending, nothing to do... */ return -1; } @@ -1458,7 +1462,7 @@ SDL_RLESurface(SDL_Surface * surface) /* The surface is now accelerated */ surface->flags |= SDL_RLEACCEL; - return (0); + return 0; } /* @@ -1467,17 +1471,16 @@ SDL_RLESurface(SDL_Surface * surface) * completely transparent pixels will be lost, and color and alpha depth * may have been reduced (when encoding for 16bpp targets). */ -static SDL_bool -UnRLEAlpha(SDL_Surface * surface) +static SDL_bool UnRLEAlpha(SDL_Surface *surface) { Uint8 *srcbuf; Uint32 *dst; SDL_PixelFormat *sf = surface->format; RLEDestFormat *df = surface->map->data; - int (*uncopy_opaque) (Uint32 *, void *, int, - RLEDestFormat *, SDL_PixelFormat *); - int (*uncopy_transl) (Uint32 *, void *, int, - RLEDestFormat *, SDL_PixelFormat *); + int (*uncopy_opaque)(Uint32 *, void *, int, + RLEDestFormat *, SDL_PixelFormat *); + int (*uncopy_transl)(Uint32 *, void *, int, + RLEDestFormat *, SDL_PixelFormat *); int w = surface->w; int bpp = df->BytesPerPixel; @@ -1488,16 +1491,16 @@ UnRLEAlpha(SDL_Surface * surface) uncopy_opaque = uncopy_transl = uncopy_32; } - surface->pixels = SDL_SIMDAlloc(surface->h * surface->pitch); + surface->pixels = SDL_SIMDAlloc((size_t)surface->h * surface->pitch); if (!surface->pixels) { - return (SDL_FALSE); + return SDL_FALSE; } surface->flags |= SDL_SIMD_ALIGNED; /* fill background with transparent pixels */ - SDL_memset(surface->pixels, 0, surface->h * surface->pitch); + SDL_memset(surface->pixels, 0, (size_t)surface->h * surface->pitch); dst = surface->pixels; - srcbuf = (Uint8 *) (df + 1); + srcbuf = (Uint8 *)(df + 1); for (;;) { /* copy opaque pixels */ int ofs = 0; @@ -1508,8 +1511,8 @@ UnRLEAlpha(SDL_Surface * surface) run = srcbuf[1]; srcbuf += 2; } else { - ofs += ((Uint16 *) srcbuf)[0]; - run = ((Uint16 *) srcbuf)[1]; + ofs += ((Uint16 *)srcbuf)[0]; + run = ((Uint16 *)srcbuf)[1]; srcbuf += 4; } if (run) { @@ -1521,15 +1524,16 @@ UnRLEAlpha(SDL_Surface * surface) } while (ofs < w); /* skip padding if needed */ - if (bpp == 2) - srcbuf += (uintptr_t) srcbuf & 2; + if (bpp == 2) { + srcbuf += (uintptr_t)srcbuf & 2; + } /* copy translucent pixels */ ofs = 0; do { unsigned run; - ofs += ((Uint16 *) srcbuf)[0]; - run = ((Uint16 *) srcbuf)[1]; + ofs += ((Uint16 *)srcbuf)[0]; + run = ((Uint16 *)srcbuf)[1]; srcbuf += 4; if (run) { srcbuf += uncopy_transl(dst + ofs, srcbuf, run, df, sf); @@ -1540,11 +1544,10 @@ UnRLEAlpha(SDL_Surface * surface) } end_function: - return (SDL_TRUE); + return SDL_TRUE; } -void -SDL_UnRLESurface(SDL_Surface * surface, int recode) +void SDL_UnRLESurface(SDL_Surface *surface, int recode) { if (surface->flags & SDL_RLEACCEL) { surface->flags &= ~SDL_RLEACCEL; @@ -1554,7 +1557,7 @@ SDL_UnRLESurface(SDL_Surface * surface, int recode) SDL_Rect full; /* re-create the original surface */ - surface->pixels = SDL_SIMDAlloc(surface->h * surface->pitch); + surface->pixels = SDL_SIMDAlloc((size_t)surface->h * surface->pitch); if (!surface->pixels) { /* Oh crap... */ surface->flags |= SDL_RLEACCEL; diff --git a/SDL2-2.0.12/src/video/SDL_RLEaccel_c.h b/SDL2-2.30.5/src/video/SDL_RLEaccel_c.h similarity index 86% rename from SDL2-2.0.12/src/video/SDL_RLEaccel_c.h rename to SDL2-2.30.5/src/video/SDL_RLEaccel_c.h index 3dcc6c0..5968081 100644 --- a/SDL2-2.0.12/src/video/SDL_RLEaccel_c.h +++ b/SDL2-2.30.5/src/video/SDL_RLEaccel_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,8 +26,8 @@ /* Useful functions and variables from SDL_RLEaccel.c */ -extern int SDL_RLESurface(SDL_Surface * surface); -extern void SDL_UnRLESurface(SDL_Surface * surface, int recode); +extern int SDL_RLESurface(SDL_Surface *surface); +extern void SDL_UnRLESurface(SDL_Surface *surface, int recode); #endif /* SDL_RLEaccel_c_h_ */ diff --git a/SDL2-2.0.12/src/video/SDL_blit.c b/SDL2-2.30.5/src/video/SDL_blit.c similarity index 85% rename from SDL2-2.0.12/src/video/SDL_blit.c rename to SDL2-2.30.5/src/video/SDL_blit.c index a5df0b9..19d47a1 100644 --- a/SDL2-2.0.12/src/video/SDL_blit.c +++ b/SDL2-2.30.5/src/video/SDL_blit.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -30,9 +30,8 @@ #include "SDL_pixels_c.h" /* The general purpose software blit routine */ -static int SDLCALL -SDL_SoftBlit(SDL_Surface * src, SDL_Rect * srcrect, - SDL_Surface * dst, SDL_Rect * dstrect) +static int SDLCALL SDL_SoftBlit(SDL_Surface *src, SDL_Rect *srcrect, + SDL_Surface *dst, SDL_Rect *dstrect) { int okay; int src_locked; @@ -66,23 +65,23 @@ SDL_SoftBlit(SDL_Surface * src, SDL_Rect * srcrect, SDL_BlitInfo *info = &src->map->info; /* Set up the blit information */ - info->src = (Uint8 *) src->pixels + - (Uint16) srcrect->y * src->pitch + - (Uint16) srcrect->x * info->src_fmt->BytesPerPixel; + info->src = (Uint8 *)src->pixels + + (Uint16)srcrect->y * src->pitch + + (Uint16)srcrect->x * info->src_fmt->BytesPerPixel; info->src_w = srcrect->w; info->src_h = srcrect->h; info->src_pitch = src->pitch; info->src_skip = info->src_pitch - info->src_w * info->src_fmt->BytesPerPixel; info->dst = - (Uint8 *) dst->pixels + (Uint16) dstrect->y * dst->pitch + - (Uint16) dstrect->x * info->dst_fmt->BytesPerPixel; + (Uint8 *)dst->pixels + (Uint16)dstrect->y * dst->pitch + + (Uint16)dstrect->x * info->dst_fmt->BytesPerPixel; info->dst_w = dstrect->w; info->dst_h = dstrect->h; info->dst_pitch = dst->pitch; info->dst_skip = info->dst_pitch - info->dst_w * info->dst_fmt->BytesPerPixel; - RunBlit = (SDL_BlitFunc) src->map->data; + RunBlit = (SDL_BlitFunc)src->map->data; /* Run the actual software blit */ RunBlit(info); @@ -96,7 +95,7 @@ SDL_SoftBlit(SDL_Surface * src, SDL_Rect * srcrect, SDL_UnlockSurface(src); } /* Blit is done! */ - return (okay ? 0 : -1); + return okay ? 0 : -1; } #if SDL_HAVE_BLIT_AUTO @@ -104,8 +103,7 @@ SDL_SoftBlit(SDL_Surface * src, SDL_Rect * srcrect, #ifdef __MACOSX__ #include -static SDL_bool -SDL_UseAltivecPrefetch() +static SDL_bool SDL_UseAltivecPrefetch() { const char key[] = "hw.l3cachesize"; u_int64_t result = 0; @@ -118,17 +116,15 @@ SDL_UseAltivecPrefetch() } } #else -static SDL_bool -SDL_UseAltivecPrefetch() +static SDL_bool SDL_UseAltivecPrefetch(void) { /* Just guess G4 */ return SDL_TRUE; } #endif /* __MACOSX__ */ -static SDL_BlitFunc -SDL_ChooseBlitFunc(Uint32 src_format, Uint32 dst_format, int flags, - SDL_BlitFuncEntry * entries) +static SDL_BlitFunc SDL_ChooseBlitFunc(Uint32 src_format, Uint32 dst_format, int flags, + SDL_BlitFuncEntry *entries) { int i, flagcheck = (flags & (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_MUL | SDL_COPY_COLORKEY | SDL_COPY_NEAREST)); static int features = 0x7fffffff; @@ -141,7 +137,7 @@ SDL_ChooseBlitFunc(Uint32 src_format, Uint32 dst_format, int flags, /* Allow an override for testing .. */ if (override) { - SDL_sscanf(override, "%u", &features); + (void)SDL_sscanf(override, "%u", &features); } else { if (SDL_HasMMX()) { features |= SDL_CPU_MMX; @@ -192,8 +188,7 @@ SDL_ChooseBlitFunc(Uint32 src_format, Uint32 dst_format, int flags, #endif /* SDL_HAVE_BLIT_AUTO */ /* Figure out which of many blit routines to set up on a surface */ -int -SDL_CalculateBlit(SDL_Surface * surface) +int SDL_CalculateBlit(SDL_Surface *surface) { SDL_BlitFunc blit = NULL; SDL_BlitMap *map = surface->map; @@ -231,19 +226,17 @@ SDL_CalculateBlit(SDL_Surface * surface) if (map->identity && !(map->info.flags & ~SDL_COPY_RLE_DESIRED)) { blit = SDL_BlitCopy; } else if (surface->format->Rloss > 8 || dst->format->Rloss > 8) { - /* Greater than 8 bits per channel not supported yet */ - SDL_InvalidateMap(map); - return SDL_SetError("Blit combination not supported"); + blit = SDL_Blit_Slow; } #if SDL_HAVE_BLIT_0 else if (surface->format->BitsPerPixel < 8 && - SDL_ISPIXELFORMAT_INDEXED(surface->format->format)) { + SDL_ISPIXELFORMAT_INDEXED(surface->format->format)) { blit = SDL_CalculateBlit0(surface); } #endif #if SDL_HAVE_BLIT_1 else if (surface->format->BytesPerPixel == 1 && - SDL_ISPIXELFORMAT_INDEXED(surface->format->format)) { + SDL_ISPIXELFORMAT_INDEXED(surface->format->format)) { blit = SDL_CalculateBlit1(surface); } #endif @@ -258,7 +251,7 @@ SDL_CalculateBlit(SDL_Surface * surface) } #endif #if SDL_HAVE_BLIT_AUTO - if (blit == NULL) { + if (!blit) { Uint32 src_format = surface->format->format; Uint32 dst_format = dst->format->format; @@ -269,7 +262,7 @@ SDL_CalculateBlit(SDL_Surface * surface) #endif #ifndef TEST_SLOW_BLIT - if (blit == NULL) + if (!blit) #endif { Uint32 src_format = surface->format->format; @@ -285,7 +278,7 @@ SDL_CalculateBlit(SDL_Surface * surface) map->data = blit; /* Make sure we have a blit function */ - if (blit == NULL) { + if (!blit) { SDL_InvalidateMap(map); return SDL_SetError("Blit combination not supported"); } diff --git a/SDL2-2.30.5/src/video/SDL_blit.h b/SDL2-2.30.5/src/video/SDL_blit.h new file mode 100644 index 0000000..731ea63 --- /dev/null +++ b/SDL2-2.30.5/src/video/SDL_blit.h @@ -0,0 +1,589 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifndef SDL_blit_h_ +#define SDL_blit_h_ + +#include "SDL_cpuinfo.h" +#include "SDL_endian.h" +#include "SDL_surface.h" + +/* pixman ARM blitters are 32 bit only : */ +#if defined(__aarch64__) || defined(_M_ARM64) +#undef SDL_ARM_SIMD_BLITTERS +#undef SDL_ARM_NEON_BLITTERS +#endif + +/* Table to do pixel byte expansion */ +extern Uint8 *SDL_expand_byte[9]; + +/* SDL blit copy flags */ +#define SDL_COPY_MODULATE_COLOR 0x00000001 +#define SDL_COPY_MODULATE_ALPHA 0x00000002 +#define SDL_COPY_BLEND 0x00000010 +#define SDL_COPY_ADD 0x00000020 +#define SDL_COPY_MOD 0x00000040 +#define SDL_COPY_MUL 0x00000080 +#define SDL_COPY_COLORKEY 0x00000100 +#define SDL_COPY_NEAREST 0x00000200 +#define SDL_COPY_RLE_DESIRED 0x00001000 +#define SDL_COPY_RLE_COLORKEY 0x00002000 +#define SDL_COPY_RLE_ALPHAKEY 0x00004000 +#define SDL_COPY_RLE_MASK (SDL_COPY_RLE_DESIRED | SDL_COPY_RLE_COLORKEY | SDL_COPY_RLE_ALPHAKEY) + +/* SDL blit CPU flags */ +#define SDL_CPU_ANY 0x00000000 +#define SDL_CPU_MMX 0x00000001 +#define SDL_CPU_3DNOW 0x00000002 +#define SDL_CPU_SSE 0x00000004 +#define SDL_CPU_SSE2 0x00000008 +#define SDL_CPU_ALTIVEC_PREFETCH 0x00000010 +#define SDL_CPU_ALTIVEC_NOPREFETCH 0x00000020 + +typedef struct +{ + Uint8 *src; + int src_w, src_h; + int src_pitch; + int src_skip; + Uint8 *dst; + int dst_w, dst_h; + int dst_pitch; + int dst_skip; + SDL_PixelFormat *src_fmt; + SDL_PixelFormat *dst_fmt; + Uint8 *table; + int flags; + Uint32 colorkey; + Uint8 r, g, b, a; +} SDL_BlitInfo; + +typedef void (*SDL_BlitFunc)(SDL_BlitInfo *info); + +typedef struct +{ + Uint32 src_format; + Uint32 dst_format; + int flags; + int cpu; + SDL_BlitFunc func; +} SDL_BlitFuncEntry; + +/* Blit mapping definition */ +/* typedef'ed in SDL_surface.h */ +struct SDL_BlitMap +{ + SDL_Surface *dst; + int identity; + SDL_blit blit; + void *data; + SDL_BlitInfo info; + + /* the version count matches the destination; mismatch indicates + an invalid mapping */ + Uint32 dst_palette_version; + Uint32 src_palette_version; +}; + +/* Functions found in SDL_blit.c */ +extern int SDL_CalculateBlit(SDL_Surface *surface); + +/* Functions found in SDL_blit_*.c */ +extern SDL_BlitFunc SDL_CalculateBlit0(SDL_Surface *surface); +extern SDL_BlitFunc SDL_CalculateBlit1(SDL_Surface *surface); +extern SDL_BlitFunc SDL_CalculateBlitN(SDL_Surface *surface); +extern SDL_BlitFunc SDL_CalculateBlitA(SDL_Surface *surface); + +/* + * Useful macros for blitting routines + */ + +#if defined(__GNUC__) +#define DECLARE_ALIGNED(t, v, a) t __attribute__((aligned(a))) v +#elif defined(_MSC_VER) +#define DECLARE_ALIGNED(t, v, a) __declspec(align(a)) t v +#else +#define DECLARE_ALIGNED(t, v, a) t v +#endif + +/* Load pixel of the specified format from a buffer and get its R-G-B values */ +#define RGB_FROM_PIXEL(Pixel, fmt, r, g, b) \ + { \ + r = SDL_expand_byte[fmt->Rloss][((Pixel & fmt->Rmask) >> fmt->Rshift)]; \ + g = SDL_expand_byte[fmt->Gloss][((Pixel & fmt->Gmask) >> fmt->Gshift)]; \ + b = SDL_expand_byte[fmt->Bloss][((Pixel & fmt->Bmask) >> fmt->Bshift)]; \ + } +#define RGB_FROM_RGB565(Pixel, r, g, b) \ + { \ + r = SDL_expand_byte[3][((Pixel & 0xF800) >> 11)]; \ + g = SDL_expand_byte[2][((Pixel & 0x07E0) >> 5)]; \ + b = SDL_expand_byte[3][(Pixel & 0x001F)]; \ + } +#define RGB_FROM_RGB555(Pixel, r, g, b) \ + { \ + r = SDL_expand_byte[3][((Pixel & 0x7C00) >> 10)]; \ + g = SDL_expand_byte[3][((Pixel & 0x03E0) >> 5)]; \ + b = SDL_expand_byte[3][(Pixel & 0x001F)]; \ + } +#define RGB_FROM_RGB888(Pixel, r, g, b) \ + { \ + r = ((Pixel & 0xFF0000) >> 16); \ + g = ((Pixel & 0xFF00) >> 8); \ + b = (Pixel & 0xFF); \ + } +#define RETRIEVE_RGB_PIXEL(buf, bpp, Pixel) \ + do { \ + switch (bpp) { \ + case 1: \ + Pixel = *((Uint8 *)(buf)); \ + break; \ + \ + case 2: \ + Pixel = *((Uint16 *)(buf)); \ + break; \ + \ + case 3: \ + { \ + Uint8 *B = (Uint8 *)(buf); \ + if (SDL_BYTEORDER == SDL_LIL_ENDIAN) { \ + Pixel = B[0] + (B[1] << 8) + (B[2] << 16); \ + } else { \ + Pixel = (B[0] << 16) + (B[1] << 8) + B[2]; \ + } \ + } break; \ + \ + case 4: \ + Pixel = *((Uint32 *)(buf)); \ + break; \ + \ + default: \ + Pixel = 0; /* stop gcc complaints */ \ + break; \ + } \ + } while (0) + +#define DISEMBLE_RGB(buf, bpp, fmt, Pixel, r, g, b) \ + do { \ + switch (bpp) { \ + case 1: \ + Pixel = *((Uint8 *)(buf)); \ + RGB_FROM_PIXEL(Pixel, fmt, r, g, b); \ + break; \ + \ + case 2: \ + Pixel = *((Uint16 *)(buf)); \ + RGB_FROM_PIXEL(Pixel, fmt, r, g, b); \ + break; \ + \ + case 3: \ + { \ + Pixel = 0; \ + if (SDL_BYTEORDER == SDL_LIL_ENDIAN) { \ + r = *((buf) + fmt->Rshift / 8); \ + g = *((buf) + fmt->Gshift / 8); \ + b = *((buf) + fmt->Bshift / 8); \ + } else { \ + r = *((buf) + 2 - fmt->Rshift / 8); \ + g = *((buf) + 2 - fmt->Gshift / 8); \ + b = *((buf) + 2 - fmt->Bshift / 8); \ + } \ + } break; \ + \ + case 4: \ + Pixel = *((Uint32 *)(buf)); \ + RGB_FROM_PIXEL(Pixel, fmt, r, g, b); \ + break; \ + \ + default: \ + /* stop gcc complaints */ \ + Pixel = 0; \ + r = g = b = 0; \ + break; \ + } \ + } while (0) + +/* Assemble R-G-B values into a specified pixel format and store them */ +#define PIXEL_FROM_RGB(Pixel, fmt, r, g, b) \ + { \ + Pixel = ((r >> fmt->Rloss) << fmt->Rshift) | \ + ((g >> fmt->Gloss) << fmt->Gshift) | \ + ((b >> fmt->Bloss) << fmt->Bshift) | \ + fmt->Amask; \ + } +#define RGB565_FROM_RGB(Pixel, r, g, b) \ + { \ + Pixel = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3); \ + } +#define RGB555_FROM_RGB(Pixel, r, g, b) \ + { \ + Pixel = ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3); \ + } +#define RGB888_FROM_RGB(Pixel, r, g, b) \ + { \ + Pixel = (r << 16) | (g << 8) | b; \ + } +#define ARGB8888_FROM_RGBA(Pixel, r, g, b, a) \ + { \ + Pixel = (a << 24) | (r << 16) | (g << 8) | b; \ + } +#define RGBA8888_FROM_RGBA(Pixel, r, g, b, a) \ + { \ + Pixel = (r << 24) | (g << 16) | (b << 8) | a; \ + } +#define ABGR8888_FROM_RGBA(Pixel, r, g, b, a) \ + { \ + Pixel = (a << 24) | (b << 16) | (g << 8) | r; \ + } +#define BGRA8888_FROM_RGBA(Pixel, r, g, b, a) \ + { \ + Pixel = (b << 24) | (g << 16) | (r << 8) | a; \ + } +#define ARGB2101010_FROM_RGBA(Pixel, r, g, b, a) \ + { \ + r = r ? ((r << 2) | 0x3) : 0; \ + g = g ? ((g << 2) | 0x3) : 0; \ + b = b ? ((b << 2) | 0x3) : 0; \ + a = (a * 3) / 255; \ + Pixel = (a << 30) | (r << 20) | (g << 10) | b; \ + } +#define ASSEMBLE_RGB(buf, bpp, fmt, r, g, b) \ + { \ + switch (bpp) { \ + case 1: \ + { \ + Uint8 _pixel; \ + \ + PIXEL_FROM_RGB(_pixel, fmt, r, g, b); \ + *((Uint8 *)(buf)) = _pixel; \ + } break; \ + \ + case 2: \ + { \ + Uint16 _pixel; \ + \ + PIXEL_FROM_RGB(_pixel, fmt, r, g, b); \ + *((Uint16 *)(buf)) = _pixel; \ + } break; \ + \ + case 3: \ + { \ + if (SDL_BYTEORDER == SDL_LIL_ENDIAN) { \ + *((buf) + fmt->Rshift / 8) = r; \ + *((buf) + fmt->Gshift / 8) = g; \ + *((buf) + fmt->Bshift / 8) = b; \ + } else { \ + *((buf) + 2 - fmt->Rshift / 8) = r; \ + *((buf) + 2 - fmt->Gshift / 8) = g; \ + *((buf) + 2 - fmt->Bshift / 8) = b; \ + } \ + } break; \ + \ + case 4: \ + { \ + Uint32 _pixel; \ + \ + PIXEL_FROM_RGB(_pixel, fmt, r, g, b); \ + *((Uint32 *)(buf)) = _pixel; \ + } break; \ + } \ + } + +/* FIXME: Should we rescale alpha into 0..255 here? */ +#define RGBA_FROM_PIXEL(Pixel, fmt, r, g, b, a) \ + { \ + r = SDL_expand_byte[fmt->Rloss][((Pixel & fmt->Rmask) >> fmt->Rshift)]; \ + g = SDL_expand_byte[fmt->Gloss][((Pixel & fmt->Gmask) >> fmt->Gshift)]; \ + b = SDL_expand_byte[fmt->Bloss][((Pixel & fmt->Bmask) >> fmt->Bshift)]; \ + a = SDL_expand_byte[fmt->Aloss][((Pixel & fmt->Amask) >> fmt->Ashift)]; \ + } +#define RGBA_FROM_8888(Pixel, fmt, r, g, b, a) \ + { \ + r = (Pixel & fmt->Rmask) >> fmt->Rshift; \ + g = (Pixel & fmt->Gmask) >> fmt->Gshift; \ + b = (Pixel & fmt->Bmask) >> fmt->Bshift; \ + a = (Pixel & fmt->Amask) >> fmt->Ashift; \ + } +#define RGBA_FROM_RGBA8888(Pixel, r, g, b, a) \ + { \ + r = (Pixel >> 24); \ + g = ((Pixel >> 16) & 0xFF); \ + b = ((Pixel >> 8) & 0xFF); \ + a = (Pixel & 0xFF); \ + } +#define RGBA_FROM_ARGB8888(Pixel, r, g, b, a) \ + { \ + r = ((Pixel >> 16) & 0xFF); \ + g = ((Pixel >> 8) & 0xFF); \ + b = (Pixel & 0xFF); \ + a = (Pixel >> 24); \ + } +#define RGBA_FROM_ABGR8888(Pixel, r, g, b, a) \ + { \ + r = (Pixel & 0xFF); \ + g = ((Pixel >> 8) & 0xFF); \ + b = ((Pixel >> 16) & 0xFF); \ + a = (Pixel >> 24); \ + } +#define RGBA_FROM_BGRA8888(Pixel, r, g, b, a) \ + { \ + r = ((Pixel >> 8) & 0xFF); \ + g = ((Pixel >> 16) & 0xFF); \ + b = (Pixel >> 24); \ + a = (Pixel & 0xFF); \ + } +#define RGBA_FROM_ARGB2101010(Pixel, r, g, b, a) \ + { \ + r = ((Pixel >> 22) & 0xFF); \ + g = ((Pixel >> 12) & 0xFF); \ + b = ((Pixel >> 2) & 0xFF); \ + a = SDL_expand_byte[6][(Pixel >> 30)]; \ + } +#define DISEMBLE_RGBA(buf, bpp, fmt, Pixel, r, g, b, a) \ + do { \ + switch (bpp) { \ + case 1: \ + Pixel = *((Uint8 *)(buf)); \ + RGBA_FROM_PIXEL(Pixel, fmt, r, g, b, a); \ + break; \ + \ + case 2: \ + Pixel = *((Uint16 *)(buf)); \ + RGBA_FROM_PIXEL(Pixel, fmt, r, g, b, a); \ + break; \ + \ + case 3: \ + { \ + Pixel = 0; \ + if (SDL_BYTEORDER == SDL_LIL_ENDIAN) { \ + r = *((buf) + fmt->Rshift / 8); \ + g = *((buf) + fmt->Gshift / 8); \ + b = *((buf) + fmt->Bshift / 8); \ + } else { \ + r = *((buf) + 2 - fmt->Rshift / 8); \ + g = *((buf) + 2 - fmt->Gshift / 8); \ + b = *((buf) + 2 - fmt->Bshift / 8); \ + } \ + a = 0xFF; \ + } break; \ + \ + case 4: \ + Pixel = *((Uint32 *)(buf)); \ + RGBA_FROM_PIXEL(Pixel, fmt, r, g, b, a); \ + break; \ + \ + default: \ + /* stop gcc complaints */ \ + Pixel = 0; \ + r = g = b = a = 0; \ + break; \ + } \ + } while (0) + +/* FIXME: this isn't correct, especially for Alpha (maximum != 255) */ +#define PIXEL_FROM_RGBA(Pixel, fmt, r, g, b, a) \ + { \ + Pixel = ((r >> fmt->Rloss) << fmt->Rshift) | \ + ((g >> fmt->Gloss) << fmt->Gshift) | \ + ((b >> fmt->Bloss) << fmt->Bshift) | \ + ((a >> fmt->Aloss) << fmt->Ashift); \ + } +#define ASSEMBLE_RGBA(buf, bpp, fmt, r, g, b, a) \ + { \ + switch (bpp) { \ + case 1: \ + { \ + Uint8 _pixel; \ + \ + PIXEL_FROM_RGBA(_pixel, fmt, r, g, b, a); \ + *((Uint8 *)(buf)) = _pixel; \ + } break; \ + \ + case 2: \ + { \ + Uint16 _pixel; \ + \ + PIXEL_FROM_RGBA(_pixel, fmt, r, g, b, a); \ + *((Uint16 *)(buf)) = _pixel; \ + } break; \ + \ + case 3: \ + { \ + if (SDL_BYTEORDER == SDL_LIL_ENDIAN) { \ + *((buf) + fmt->Rshift / 8) = r; \ + *((buf) + fmt->Gshift / 8) = g; \ + *((buf) + fmt->Bshift / 8) = b; \ + } else { \ + *((buf) + 2 - fmt->Rshift / 8) = r; \ + *((buf) + 2 - fmt->Gshift / 8) = g; \ + *((buf) + 2 - fmt->Bshift / 8) = b; \ + } \ + } break; \ + \ + case 4: \ + { \ + Uint32 _pixel; \ + \ + PIXEL_FROM_RGBA(_pixel, fmt, r, g, b, a); \ + *((Uint32 *)(buf)) = _pixel; \ + } break; \ + } \ + } + +/* Blend the RGB values of two pixels with an alpha value */ +#define ALPHA_BLEND_RGB(sR, sG, sB, A, dR, dG, dB) \ + do { \ + dR = (Uint8)((((int)(sR - dR) * (int)A) / 255) + dR); \ + dG = (Uint8)((((int)(sG - dG) * (int)A) / 255) + dG); \ + dB = (Uint8)((((int)(sB - dB) * (int)A) / 255) + dB); \ + } while (0) + +/* Blend the RGBA values of two pixels */ +#define ALPHA_BLEND_RGBA(sR, sG, sB, sA, dR, dG, dB, dA) \ + do { \ + dR = (Uint8)((((int)(sR - dR) * (int)sA) / 255) + dR); \ + dG = (Uint8)((((int)(sG - dG) * (int)sA) / 255) + dG); \ + dB = (Uint8)((((int)(sB - dB) * (int)sA) / 255) + dB); \ + dA = (Uint8)((int)sA + dA - ((int)sA * dA) / 255); \ + } while (0) + +/* This is a very useful loop for optimizing blitters */ +#if defined(_MSC_VER) && (_MSC_VER == 1300) +/* There's a bug in the Visual C++ 7 optimizer when compiling this code */ +#else +#define USE_DUFFS_LOOP +#endif +#ifdef USE_DUFFS_LOOP + +/* 8-times unrolled loop */ +#define DUFFS_LOOP8(pixel_copy_increment, width) \ + { \ + int n = (width + 7) / 8; \ + switch (width & 7) { \ + case 0: \ + do { \ + pixel_copy_increment; \ + SDL_FALLTHROUGH; \ + case 7: \ + pixel_copy_increment; \ + SDL_FALLTHROUGH; \ + case 6: \ + pixel_copy_increment; \ + SDL_FALLTHROUGH; \ + case 5: \ + pixel_copy_increment; \ + SDL_FALLTHROUGH; \ + case 4: \ + pixel_copy_increment; \ + SDL_FALLTHROUGH; \ + case 3: \ + pixel_copy_increment; \ + SDL_FALLTHROUGH; \ + case 2: \ + pixel_copy_increment; \ + SDL_FALLTHROUGH; \ + case 1: \ + pixel_copy_increment; \ + } while (--n > 0); \ + } \ + } + +/* 4-times unrolled loop */ +#define DUFFS_LOOP4(pixel_copy_increment, width) \ + { \ + int n = (width + 3) / 4; \ + switch (width & 3) { \ + case 0: \ + do { \ + pixel_copy_increment; \ + SDL_FALLTHROUGH; \ + case 3: \ + pixel_copy_increment; \ + SDL_FALLTHROUGH; \ + case 2: \ + pixel_copy_increment; \ + SDL_FALLTHROUGH; \ + case 1: \ + pixel_copy_increment; \ + } while (--n > 0); \ + } \ + } + +/* Use the 8-times version of the loop by default */ +#define DUFFS_LOOP(pixel_copy_increment, width) \ + DUFFS_LOOP8(pixel_copy_increment, width) + +/* Special version of Duff's device for even more optimization */ +#define DUFFS_LOOP_124(pixel_copy_increment1, \ + pixel_copy_increment2, \ + pixel_copy_increment4, width) \ + { \ + int n = width; \ + if (n & 1) { \ + pixel_copy_increment1; \ + n -= 1; \ + } \ + if (n & 2) { \ + pixel_copy_increment2; \ + n -= 2; \ + } \ + if (n & 4) { \ + pixel_copy_increment4; \ + n -= 4; \ + } \ + if (n) { \ + n /= 8; \ + do { \ + pixel_copy_increment4; \ + pixel_copy_increment4; \ + } while (--n > 0); \ + } \ + } + +#else + +/* Don't use Duff's device to unroll loops */ +#define DUFFS_LOOP(pixel_copy_increment, width) \ + { \ + int n; \ + for (n = width; n > 0; --n) { \ + pixel_copy_increment; \ + } \ + } +#define DUFFS_LOOP8(pixel_copy_increment, width) \ + DUFFS_LOOP(pixel_copy_increment, width) +#define DUFFS_LOOP4(pixel_copy_increment, width) \ + DUFFS_LOOP(pixel_copy_increment, width) +#define DUFFS_LOOP_124(pixel_copy_increment1, \ + pixel_copy_increment2, \ + pixel_copy_increment4, width) \ + DUFFS_LOOP(pixel_copy_increment1, width) + +#endif /* USE_DUFFS_LOOP */ + +/* Prevent Visual C++ 6.0 from printing out stupid warnings */ +#if defined(_MSC_VER) && (_MSC_VER >= 600) +#pragma warning(disable : 4550) +#endif + +#endif /* SDL_blit_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/SDL_blit_0.c b/SDL2-2.30.5/src/video/SDL_blit_0.c new file mode 100644 index 0000000..e7750dd --- /dev/null +++ b/SDL2-2.30.5/src/video/SDL_blit_0.c @@ -0,0 +1,986 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#if SDL_HAVE_BLIT_0 + +#include "SDL_video.h" +#include "SDL_blit.h" + +/* Functions to blit from bitmaps to other surfaces */ + +SDL_FORCE_INLINE void BlitBto1(SDL_BlitInfo *info, const Uint32 srcbpp) +{ + const Uint32 mask = (1 << srcbpp) - 1; + const Uint32 align = (8 / srcbpp) - 1; + + int c; + int width, height; + Uint8 *src, *map, *dst; + int srcskip, dstskip; + + /* Set up some basic variables */ + width = info->dst_w; + height = info->dst_h; + src = info->src; + srcskip = info->src_skip; + dst = info->dst; + dstskip = info->dst_skip; + map = info->table; + + if (srcbpp == 4) + srcskip += width - (width + 1) / 2; + else if (srcbpp == 2) + srcskip += width - (width + 3) / 4; + else if (srcbpp == 1) + srcskip += width - (width + 7) / 8; + + if (map) { + if (SDL_PIXELORDER(info->src_fmt->format) == SDL_BITMAPORDER_4321) { + while (height--) { + Uint8 byte = 0, bit; + for (c = 0; c < width; ++c) { + if (!(c & align)) { + byte = *src++; + } + bit = (byte & mask); + if (1) { + *dst = map[bit]; + } + dst++; + byte >>= srcbpp; + } + src += srcskip; + dst += dstskip; + } + } else { + while (height--) { + Uint8 byte = 0, bit; + for (c = 0; c < width; ++c) { + if (!(c & align)) { + byte = *src++; + } + bit = (byte >> (8 - srcbpp)) & mask; + if (1) { + *dst = map[bit]; + } + dst++; + byte <<= srcbpp; + } + src += srcskip; + dst += dstskip; + } + } + } else { + if (SDL_PIXELORDER(info->src_fmt->format) == SDL_BITMAPORDER_4321) { + while (height--) { + Uint8 byte = 0, bit; + for (c = 0; c < width; ++c) { + if (!(c & align)) { + byte = *src++; + } + bit = (byte & mask); + if (1) { + *dst = bit; + } + dst++; + byte >>= srcbpp; + } + src += srcskip; + dst += dstskip; + } + } else { + while (height--) { + Uint8 byte = 0, bit; + for (c = 0; c < width; ++c) { + if (!(c & align)) { + byte = *src++; + } + bit = (byte >> (8 - srcbpp)) & mask; + if (1) { + *dst = bit; + } + dst++; + byte <<= srcbpp; + } + src += srcskip; + dst += dstskip; + } + } + } +} + +SDL_FORCE_INLINE void BlitBto2(SDL_BlitInfo *info, const Uint32 srcbpp) +{ + const Uint32 mask = (1 << srcbpp) - 1; + const Uint32 align = (8 / srcbpp) - 1; + + int c; + int width, height; + Uint8 *src; + Uint16 *map, *dst; + int srcskip, dstskip; + + /* Set up some basic variables */ + width = info->dst_w; + height = info->dst_h; + src = info->src; + srcskip = info->src_skip; + dst = (Uint16 *)info->dst; + dstskip = info->dst_skip / 2; + map = (Uint16 *)info->table; + + if (srcbpp == 4) + srcskip += width - (width + 1) / 2; + else if (srcbpp == 2) + srcskip += width - (width + 3) / 4; + else if (srcbpp == 1) + srcskip += width - (width + 7) / 8; + + if (SDL_PIXELORDER(info->src_fmt->format) == SDL_BITMAPORDER_4321) { + while (height--) { + Uint8 byte = 0, bit; + for (c = 0; c < width; ++c) { + if (!(c & align)) { + byte = *src++; + } + bit = (byte & mask); + if (1) { + *dst = map[bit]; + } + byte >>= srcbpp; + dst++; + } + src += srcskip; + dst += dstskip; + } + } else { + while (height--) { + Uint8 byte = 0, bit; + for (c = 0; c < width; ++c) { + if (!(c & align)) { + byte = *src++; + } + bit = (byte >> (8 - srcbpp)) & mask; + if (1) { + *dst = map[bit]; + } + byte <<= srcbpp; + dst++; + } + src += srcskip; + dst += dstskip; + } + } +} + +SDL_FORCE_INLINE void BlitBto3(SDL_BlitInfo *info, const Uint32 srcbpp) +{ + const Uint32 mask = (1 << srcbpp) - 1; + const Uint32 align = (8 / srcbpp) - 1; + + int c, o; + int width, height; + Uint8 *src, *map, *dst; + int srcskip, dstskip; + + /* Set up some basic variables */ + width = info->dst_w; + height = info->dst_h; + src = info->src; + srcskip = info->src_skip; + dst = info->dst; + dstskip = info->dst_skip; + map = info->table; + + if (srcbpp == 4) + srcskip += width - (width + 1) / 2; + else if (srcbpp == 2) + srcskip += width - (width + 3) / 4; + else if (srcbpp == 1) + srcskip += width - (width + 7) / 8; + + if (SDL_PIXELORDER(info->src_fmt->format) == SDL_BITMAPORDER_4321) { + while (height--) { + Uint8 byte = 0, bit; + for (c = 0; c < width; ++c) { + if (!(c & align)) { + byte = *src++; + } + bit = (byte & mask); + if (1) { + o = bit * 4; + dst[0] = map[o++]; + dst[1] = map[o++]; + dst[2] = map[o++]; + } + byte >>= srcbpp; + dst += 3; + } + src += srcskip; + dst += dstskip; + } + } else { + while (height--) { + Uint8 byte = 0, bit; + for (c = 0; c < width; ++c) { + if (!(c & align)) { + byte = *src++; + } + bit = (byte >> (8 - srcbpp)) & mask; + if (1) { + o = bit * 4; + dst[0] = map[o++]; + dst[1] = map[o++]; + dst[2] = map[o++]; + } + byte <<= srcbpp; + dst += 3; + } + src += srcskip; + dst += dstskip; + } + } +} + +SDL_FORCE_INLINE void BlitBto4(SDL_BlitInfo *info, const Uint32 srcbpp) +{ + const Uint32 mask = (1 << srcbpp) - 1; + const Uint32 align = (8 / srcbpp) - 1; + + int width, height; + Uint8 *src; + Uint32 *map, *dst; + int srcskip, dstskip; + int c; + + /* Set up some basic variables */ + width = info->dst_w; + height = info->dst_h; + src = info->src; + srcskip = info->src_skip; + dst = (Uint32 *)info->dst; + dstskip = info->dst_skip / 4; + map = (Uint32 *)info->table; + + if (srcbpp == 4) + srcskip += width - (width + 1) / 2; + else if (srcbpp == 2) + srcskip += width - (width + 3) / 4; + else if (srcbpp == 1) + srcskip += width - (width + 7) / 8; + + if (SDL_PIXELORDER(info->src_fmt->format) == SDL_BITMAPORDER_4321) { + while (height--) { + Uint8 byte = 0, bit; + for (c = 0; c < width; ++c) { + if (!(c & align)) { + byte = *src++; + } + bit = (byte & mask); + if (1) { + *dst = map[bit]; + } + byte >>= srcbpp; + dst++; + } + src += srcskip; + dst += dstskip; + } + } else { + while (height--) { + Uint8 byte = 0, bit; + for (c = 0; c < width; ++c) { + if (!(c & align)) { + byte = *src++; + } + bit = (byte >> (8 - srcbpp)) & mask; + if (1) { + *dst = map[bit]; + } + byte <<= srcbpp; + dst++; + } + src += srcskip; + dst += dstskip; + } + } +} + +SDL_FORCE_INLINE void BlitBto1Key(SDL_BlitInfo *info, const Uint32 srcbpp) +{ + const Uint32 mask = (1 << srcbpp) - 1; + const Uint32 align = (8 / srcbpp) - 1; + + int width = info->dst_w; + int height = info->dst_h; + Uint8 *src = info->src; + Uint8 *dst = info->dst; + int srcskip = info->src_skip; + int dstskip = info->dst_skip; + Uint32 ckey = info->colorkey; + Uint8 *palmap = info->table; + int c; + + /* Set up some basic variables */ + if (srcbpp == 4) + srcskip += width - (width + 1) / 2; + else if (srcbpp == 2) + srcskip += width - (width + 3) / 4; + else if (srcbpp == 1) + srcskip += width - (width + 7) / 8; + + if (palmap) { + if (SDL_PIXELORDER(info->src_fmt->format) == SDL_BITMAPORDER_4321) { + while (height--) { + Uint8 byte = 0, bit; + for (c = 0; c < width; ++c) { + if (!(c & align)) { + byte = *src++; + } + bit = (byte & mask); + if (bit != ckey) { + *dst = palmap[bit]; + } + dst++; + byte >>= srcbpp; + } + src += srcskip; + dst += dstskip; + } + } else { + while (height--) { + Uint8 byte = 0, bit; + for (c = 0; c < width; ++c) { + if (!(c & align)) { + byte = *src++; + } + bit = (byte >> (8 - srcbpp)) & mask; + if (bit != ckey) { + *dst = palmap[bit]; + } + dst++; + byte <<= srcbpp; + } + src += srcskip; + dst += dstskip; + } + } + } else { + if (SDL_PIXELORDER(info->src_fmt->format) == SDL_BITMAPORDER_4321) { + while (height--) { + Uint8 byte = 0, bit; + for (c = 0; c < width; ++c) { + if (!(c & align)) { + byte = *src++; + } + bit = (byte & mask); + if (bit != ckey) { + *dst = bit; + } + dst++; + byte >>= srcbpp; + } + src += srcskip; + dst += dstskip; + } + } else { + while (height--) { + Uint8 byte = 0, bit; + for (c = 0; c < width; ++c) { + if (!(c & align)) { + byte = *src++; + } + bit = (byte >> (8 - srcbpp)) & mask; + if (bit != ckey) { + *dst = bit; + } + dst++; + byte <<= srcbpp; + } + src += srcskip; + dst += dstskip; + } + } + } +} + +SDL_FORCE_INLINE void BlitBto2Key(SDL_BlitInfo *info, const Uint32 srcbpp) +{ + const Uint32 mask = (1 << srcbpp) - 1; + const Uint32 align = (8 / srcbpp) - 1; + + int width = info->dst_w; + int height = info->dst_h; + Uint8 *src = info->src; + Uint16 *dstp = (Uint16 *)info->dst; + int srcskip = info->src_skip; + int dstskip = info->dst_skip; + Uint32 ckey = info->colorkey; + Uint8 *palmap = info->table; + int c; + + /* Set up some basic variables */ + if (srcbpp == 4) + srcskip += width - (width + 1) / 2; + else if (srcbpp == 2) + srcskip += width - (width + 3) / 4; + else if (srcbpp == 1) + srcskip += width - (width + 7) / 8; + dstskip /= 2; + + if (SDL_PIXELORDER(info->src_fmt->format) == SDL_BITMAPORDER_4321) { + while (height--) { + Uint8 byte = 0, bit; + for (c = 0; c < width; ++c) { + if (!(c & align)) { + byte = *src++; + } + bit = (byte & mask); + if (bit != ckey) { + *dstp = ((Uint16 *)palmap)[bit]; + } + byte >>= srcbpp; + dstp++; + } + src += srcskip; + dstp += dstskip; + } + } else { + while (height--) { + Uint8 byte = 0, bit; + for (c = 0; c < width; ++c) { + if (!(c & align)) { + byte = *src++; + } + bit = (byte >> (8 - srcbpp)) & mask; + if (bit != ckey) { + *dstp = ((Uint16 *)palmap)[bit]; + } + byte <<= srcbpp; + dstp++; + } + src += srcskip; + dstp += dstskip; + } + } +} + +SDL_FORCE_INLINE void BlitBto3Key(SDL_BlitInfo *info, const Uint32 srcbpp) +{ + const Uint32 mask = (1 << srcbpp) - 1; + const Uint32 align = (8 / srcbpp) - 1; + + int width = info->dst_w; + int height = info->dst_h; + Uint8 *src = info->src; + Uint8 *dst = info->dst; + int srcskip = info->src_skip; + int dstskip = info->dst_skip; + Uint32 ckey = info->colorkey; + Uint8 *palmap = info->table; + int c; + + /* Set up some basic variables */ + if (srcbpp == 4) + srcskip += width - (width + 1) / 2; + else if (srcbpp == 2) + srcskip += width - (width + 3) / 4; + else if (srcbpp == 1) + srcskip += width - (width + 7) / 8; + + if (SDL_PIXELORDER(info->src_fmt->format) == SDL_BITMAPORDER_4321) { + while (height--) { + Uint8 byte = 0, bit; + for (c = 0; c < width; ++c) { + if (!(c & align)) { + byte = *src++; + } + bit = (byte & mask); + if (bit != ckey) { + SDL_memcpy(dst, &palmap[bit * 4], 3); + } + byte >>= srcbpp; + dst += 3; + } + src += srcskip; + dst += dstskip; + } + } else { + while (height--) { + Uint8 byte = 0, bit; + for (c = 0; c < width; ++c) { + if (!(c & align)) { + byte = *src++; + } + bit = (byte >> (8 - srcbpp)) & mask; + if (bit != ckey) { + SDL_memcpy(dst, &palmap[bit * 4], 3); + } + byte <<= srcbpp; + dst += 3; + } + src += srcskip; + dst += dstskip; + } + } +} + +SDL_FORCE_INLINE void BlitBto4Key(SDL_BlitInfo *info, const Uint32 srcbpp) +{ + const Uint32 mask = (1 << srcbpp) - 1; + const Uint32 align = (8 / srcbpp) - 1; + + int width = info->dst_w; + int height = info->dst_h; + Uint8 *src = info->src; + Uint32 *dstp = (Uint32 *)info->dst; + int srcskip = info->src_skip; + int dstskip = info->dst_skip; + Uint32 ckey = info->colorkey; + Uint8 *palmap = info->table; + int c; + + /* Set up some basic variables */ + if (srcbpp == 4) + srcskip += width - (width + 1) / 2; + else if (srcbpp == 2) + srcskip += width - (width + 3) / 4; + else if (srcbpp == 1) + srcskip += width - (width + 7) / 8; + dstskip /= 4; + + if (SDL_PIXELORDER(info->src_fmt->format) == SDL_BITMAPORDER_4321) { + while (height--) { + Uint8 byte = 0, bit; + for (c = 0; c < width; ++c) { + if (!(c & align)) { + byte = *src++; + } + bit = (byte & mask); + if (bit != ckey) { + *dstp = ((Uint32 *)palmap)[bit]; + } + byte >>= srcbpp; + dstp++; + } + src += srcskip; + dstp += dstskip; + } + } else { + while (height--) { + Uint8 byte = 0, bit; + for (c = 0; c < width; ++c) { + if (!(c & align)) { + byte = *src++; + } + bit = (byte >> (8 - srcbpp)) & mask; + if (bit != ckey) { + *dstp = ((Uint32 *)palmap)[bit]; + } + byte <<= srcbpp; + dstp++; + } + src += srcskip; + dstp += dstskip; + } + } +} + +SDL_FORCE_INLINE void BlitBtoNAlpha(SDL_BlitInfo *info, const Uint32 srcbpp) +{ + const Uint32 mask = (1 << srcbpp) - 1; + const Uint32 align = (8 / srcbpp) - 1; + + int width = info->dst_w; + int height = info->dst_h; + Uint8 *src = info->src; + Uint8 *dst = info->dst; + int srcskip = info->src_skip; + int dstskip = info->dst_skip; + const SDL_Color *srcpal = info->src_fmt->palette->colors; + SDL_PixelFormat *dstfmt = info->dst_fmt; + int dstbpp; + int c; + Uint32 pixel; + unsigned sR, sG, sB; + unsigned dR, dG, dB, dA; + const unsigned A = info->a; + + /* Set up some basic variables */ + dstbpp = dstfmt->BytesPerPixel; + if (srcbpp == 4) + srcskip += width - (width + 1) / 2; + else if (srcbpp == 2) + srcskip += width - (width + 3) / 4; + else if (srcbpp == 1) + srcskip += width - (width + 7) / 8; + + if (SDL_PIXELORDER(info->src_fmt->format) == SDL_BITMAPORDER_4321) { + while (height--) { + Uint8 byte = 0, bit; + for (c = 0; c < width; ++c) { + if (!(c & align)) { + byte = *src++; + } + bit = (byte & mask); + if (1) { + sR = srcpal[bit].r; + sG = srcpal[bit].g; + sB = srcpal[bit].b; + DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB, dA); + ALPHA_BLEND_RGBA(sR, sG, sB, A, dR, dG, dB, dA); + ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA); + } + byte >>= srcbpp; + dst += dstbpp; + } + src += srcskip; + dst += dstskip; + } + } else { + while (height--) { + Uint8 byte = 0, bit; + for (c = 0; c < width; ++c) { + if (!(c & align)) { + byte = *src++; + } + bit = (byte >> (8 - srcbpp)) & mask; + if (1) { + sR = srcpal[bit].r; + sG = srcpal[bit].g; + sB = srcpal[bit].b; + DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB, dA); + ALPHA_BLEND_RGBA(sR, sG, sB, A, dR, dG, dB, dA); + ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA); + } + byte <<= srcbpp; + dst += dstbpp; + } + src += srcskip; + dst += dstskip; + } + } +} + +SDL_FORCE_INLINE void BlitBtoNAlphaKey(SDL_BlitInfo *info, const Uint32 srcbpp) +{ + const Uint32 mask = (1 << srcbpp) - 1; + const Uint32 align = (8 / srcbpp) - 1; + + int width = info->dst_w; + int height = info->dst_h; + Uint8 *src = info->src; + Uint8 *dst = info->dst; + int srcskip = info->src_skip; + int dstskip = info->dst_skip; + SDL_PixelFormat *srcfmt = info->src_fmt; + SDL_PixelFormat *dstfmt = info->dst_fmt; + const SDL_Color *srcpal = srcfmt->palette->colors; + int dstbpp; + int c; + Uint32 pixel; + unsigned sR, sG, sB; + unsigned dR, dG, dB, dA; + const unsigned A = info->a; + Uint32 ckey = info->colorkey; + + /* Set up some basic variables */ + dstbpp = dstfmt->BytesPerPixel; + if (srcbpp == 4) + srcskip += width - (width + 1) / 2; + else if (srcbpp == 2) + srcskip += width - (width + 3) / 4; + else if (srcbpp == 1) + srcskip += width - (width + 7) / 8; + + if (SDL_PIXELORDER(info->src_fmt->format) == SDL_BITMAPORDER_4321) { + while (height--) { + Uint8 byte = 0, bit; + for (c = 0; c < width; ++c) { + if (!(c & align)) { + byte = *src++; + } + bit = (byte & mask); + if (bit != ckey) { + sR = srcpal[bit].r; + sG = srcpal[bit].g; + sB = srcpal[bit].b; + DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB, dA); + ALPHA_BLEND_RGBA(sR, sG, sB, A, dR, dG, dB, dA); + ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA); + } + byte >>= srcbpp; + dst += dstbpp; + } + src += srcskip; + dst += dstskip; + } + } else { + while (height--) { + Uint8 byte = 0, bit; + for (c = 0; c < width; ++c) { + if (!(c & align)) { + byte = *src++; + } + bit = (byte >> (8 - srcbpp)) & mask; + if (bit != ckey) { + sR = srcpal[bit].r; + sG = srcpal[bit].g; + sB = srcpal[bit].b; + DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB, dA); + ALPHA_BLEND_RGBA(sR, sG, sB, A, dR, dG, dB, dA); + ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA); + } + byte <<= srcbpp; + dst += dstbpp; + } + src += srcskip; + dst += dstskip; + } + } +} + + + +static void Blit1bto1(SDL_BlitInfo *info) { + BlitBto1(info, 1); +} + +static void Blit1bto2(SDL_BlitInfo *info) { + BlitBto2(info, 1); +} + +static void Blit1bto3(SDL_BlitInfo *info) { + BlitBto3(info, 1); +} + +static void Blit1bto4(SDL_BlitInfo *info) { + BlitBto4(info, 1); +} + +static const SDL_BlitFunc bitmap_blit_1b[] = { + (SDL_BlitFunc)NULL, Blit1bto1, Blit1bto2, Blit1bto3, Blit1bto4 +}; + +static void Blit1bto1Key(SDL_BlitInfo *info) { + BlitBto1Key(info, 1); +} + +static void Blit1bto2Key(SDL_BlitInfo *info) { + BlitBto2Key(info, 1); +} + +static void Blit1bto3Key(SDL_BlitInfo *info) { + BlitBto3Key(info, 1); +} + +static void Blit1bto4Key(SDL_BlitInfo *info) { + BlitBto4Key(info, 1); +} + +static const SDL_BlitFunc colorkey_blit_1b[] = { + (SDL_BlitFunc)NULL, Blit1bto1Key, Blit1bto2Key, Blit1bto3Key, Blit1bto4Key +}; + +static void Blit1btoNAlpha(SDL_BlitInfo *info) +{ + BlitBtoNAlpha(info, 1); +} + +static void Blit1btoNAlphaKey(SDL_BlitInfo *info) +{ + BlitBtoNAlphaKey(info, 1); +} + + + +static void Blit2bto1(SDL_BlitInfo *info) { + BlitBto1(info, 2); +} + +static void Blit2bto2(SDL_BlitInfo *info) { + BlitBto2(info, 2); +} + +static void Blit2bto3(SDL_BlitInfo *info) { + BlitBto3(info, 2); +} + +static void Blit2bto4(SDL_BlitInfo *info) { + BlitBto4(info, 2); +} + +static const SDL_BlitFunc bitmap_blit_2b[] = { + (SDL_BlitFunc)NULL, Blit2bto1, Blit2bto2, Blit2bto3, Blit2bto4 +}; + +static void Blit2bto1Key(SDL_BlitInfo *info) { + BlitBto1Key(info, 2); +} + +static void Blit2bto2Key(SDL_BlitInfo *info) { + BlitBto2Key(info, 2); +} + +static void Blit2bto3Key(SDL_BlitInfo *info) { + BlitBto3Key(info, 2); +} + +static void Blit2bto4Key(SDL_BlitInfo *info) { + BlitBto4Key(info, 2); +} + +static const SDL_BlitFunc colorkey_blit_2b[] = { + (SDL_BlitFunc)NULL, Blit2bto1Key, Blit2bto2Key, Blit2bto3Key, Blit2bto4Key +}; + +static void Blit2btoNAlpha(SDL_BlitInfo *info) +{ + BlitBtoNAlpha(info, 2); +} + +static void Blit2btoNAlphaKey(SDL_BlitInfo *info) +{ + BlitBtoNAlphaKey(info, 2); +} + + + +static void Blit4bto1(SDL_BlitInfo *info) { + BlitBto1(info, 4); +} + +static void Blit4bto2(SDL_BlitInfo *info) { + BlitBto2(info, 4); +} + +static void Blit4bto3(SDL_BlitInfo *info) { + BlitBto3(info, 4); +} + +static void Blit4bto4(SDL_BlitInfo *info) { + BlitBto4(info, 4); +} + +static const SDL_BlitFunc bitmap_blit_4b[] = { + (SDL_BlitFunc)NULL, Blit4bto1, Blit4bto2, Blit4bto3, Blit4bto4 +}; + +static void Blit4bto1Key(SDL_BlitInfo *info) { + BlitBto1Key(info, 4); +} + +static void Blit4bto2Key(SDL_BlitInfo *info) { + BlitBto2Key(info, 4); +} + +static void Blit4bto3Key(SDL_BlitInfo *info) { + BlitBto3Key(info, 4); +} + +static void Blit4bto4Key(SDL_BlitInfo *info) { + BlitBto4Key(info, 4); +} + +static const SDL_BlitFunc colorkey_blit_4b[] = { + (SDL_BlitFunc)NULL, Blit4bto1Key, Blit4bto2Key, Blit4bto3Key, Blit4bto4Key +}; + +static void Blit4btoNAlpha(SDL_BlitInfo *info) +{ + BlitBtoNAlpha(info, 4); +} + +static void Blit4btoNAlphaKey(SDL_BlitInfo *info) +{ + BlitBtoNAlphaKey(info, 4); +} + + + +SDL_BlitFunc SDL_CalculateBlit0(SDL_Surface *surface) +{ + int which; + + if (surface->map->dst->format->BitsPerPixel < 8) { + which = 0; + } else { + which = surface->map->dst->format->BytesPerPixel; + } + + if (SDL_PIXELTYPE(surface->format->format) == SDL_PIXELTYPE_INDEX1) { + switch (surface->map->info.flags & ~SDL_COPY_RLE_MASK) { + case 0: + return bitmap_blit_1b[which]; + + case SDL_COPY_COLORKEY: + return colorkey_blit_1b[which]; + + case SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND: + return which >= 2 ? Blit1btoNAlpha : (SDL_BlitFunc)NULL; + + case SDL_COPY_COLORKEY | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND: + return which >= 2 ? Blit1btoNAlphaKey : (SDL_BlitFunc)NULL; + } + return NULL; + } + + if (SDL_PIXELTYPE(surface->format->format) == SDL_PIXELTYPE_INDEX2) { + switch (surface->map->info.flags & ~SDL_COPY_RLE_MASK) { + case 0: + return bitmap_blit_2b[which]; + + case SDL_COPY_COLORKEY: + return colorkey_blit_2b[which]; + + case SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND: + return which >= 2 ? Blit2btoNAlpha : (SDL_BlitFunc)NULL; + + case SDL_COPY_COLORKEY | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND: + return which >= 2 ? Blit2btoNAlphaKey : (SDL_BlitFunc)NULL; + } + return NULL; + } + + if (SDL_PIXELTYPE(surface->format->format) == SDL_PIXELTYPE_INDEX4) { + switch (surface->map->info.flags & ~SDL_COPY_RLE_MASK) { + case 0: + return bitmap_blit_4b[which]; + + case SDL_COPY_COLORKEY: + return colorkey_blit_4b[which]; + + case SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND: + return which >= 2 ? Blit4btoNAlpha : (SDL_BlitFunc)NULL; + + case SDL_COPY_COLORKEY | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND: + return which >= 2 ? Blit4btoNAlphaKey : (SDL_BlitFunc)NULL; + } + return NULL; + } + + return NULL; +} + +#endif /* SDL_HAVE_BLIT_0 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/SDL_blit_1.c b/SDL2-2.30.5/src/video/SDL_blit_1.c similarity index 76% rename from SDL2-2.0.12/src/video/SDL_blit_1.c rename to SDL2-2.30.5/src/video/SDL_blit_1.c index d75caff..93fdb3e 100644 --- a/SDL2-2.0.12/src/video/SDL_blit_1.c +++ b/SDL2-2.30.5/src/video/SDL_blit_1.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -29,8 +29,7 @@ /* Functions to blit from 8-bit surfaces to other surfaces */ -static void -Blit1to1(SDL_BlitInfo * info) +static void Blit1to1(SDL_BlitInfo *info) { #ifndef USE_DUFFS_LOOP int c; @@ -50,7 +49,7 @@ Blit1to1(SDL_BlitInfo * info) while (height--) { #ifdef USE_DUFFS_LOOP - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { *dst = map[*src]; @@ -58,7 +57,7 @@ Blit1to1(SDL_BlitInfo * info) dst++; src++; , width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ #else for (c = width; c; --c) { *dst = map[*src]; @@ -73,16 +72,15 @@ Blit1to1(SDL_BlitInfo * info) /* This is now endian dependent */ #ifndef USE_DUFFS_LOOP -# if ( SDL_BYTEORDER == SDL_LIL_ENDIAN ) -# define HI 1 -# define LO 0 -# else /* ( SDL_BYTEORDER == SDL_BIG_ENDIAN ) */ -# define HI 0 -# define LO 1 -# endif +#if (SDL_BYTEORDER == SDL_LIL_ENDIAN) +#define HI 1 +#define LO 0 +#else /* ( SDL_BYTEORDER == SDL_BIG_ENDIAN ) */ +#define HI 0 +#define LO 1 #endif -static void -Blit1to2(SDL_BlitInfo * info) +#endif +static void Blit1to2(SDL_BlitInfo *info) { #ifndef USE_DUFFS_LOOP int c; @@ -99,24 +97,24 @@ Blit1to2(SDL_BlitInfo * info) srcskip = info->src_skip; dst = info->dst; dstskip = info->dst_skip; - map = (Uint16 *) info->table; + map = (Uint16 *)info->table; #ifdef USE_DUFFS_LOOP while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { *(Uint16 *)dst = map[*src++]; dst += 2; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } #else /* Memory align at 4-byte boundary, if necessary */ - if ((long) dst & 0x03) { + if ((long)dst & 0x03) { /* Don't do anything if width is 0 */ if (width == 0) { return; @@ -125,30 +123,31 @@ Blit1to2(SDL_BlitInfo * info) while (height--) { /* Perform copy alignment */ - *(Uint16 *) dst = map[*src++]; + *(Uint16 *)dst = map[*src++]; dst += 2; /* Copy in 4 pixel chunks */ for (c = width / 4; c; --c) { - *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]); + *(Uint32 *)dst = (map[src[HI]] << 16) | (map[src[LO]]); src += 2; dst += 4; - *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]); + *(Uint32 *)dst = (map[src[HI]] << 16) | (map[src[LO]]); src += 2; dst += 4; } /* Get any leftovers */ switch (width & 3) { case 3: - *(Uint16 *) dst = map[*src++]; + *(Uint16 *)dst = map[*src++]; dst += 2; + SDL_FALLTHROUGH; case 2: - *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]); + *(Uint32 *)dst = (map[src[HI]] << 16) | (map[src[LO]]); src += 2; dst += 4; break; case 1: - *(Uint16 *) dst = map[*src++]; + *(Uint16 *)dst = map[*src++]; dst += 2; break; } @@ -159,25 +158,26 @@ Blit1to2(SDL_BlitInfo * info) while (height--) { /* Copy in 4 pixel chunks */ for (c = width / 4; c; --c) { - *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]); + *(Uint32 *)dst = (map[src[HI]] << 16) | (map[src[LO]]); src += 2; dst += 4; - *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]); + *(Uint32 *)dst = (map[src[HI]] << 16) | (map[src[LO]]); src += 2; dst += 4; } /* Get any leftovers */ switch (width & 3) { case 3: - *(Uint16 *) dst = map[*src++]; + *(Uint16 *)dst = map[*src++]; dst += 2; + SDL_FALLTHROUGH; case 2: - *(Uint32 *) dst = (map[src[HI]] << 16) | (map[src[LO]]); + *(Uint32 *)dst = (map[src[HI]] << 16) | (map[src[LO]]); src += 2; dst += 4; break; case 1: - *(Uint16 *) dst = map[*src++]; + *(Uint16 *)dst = map[*src++]; dst += 2; break; } @@ -188,8 +188,7 @@ Blit1to2(SDL_BlitInfo * info) #endif /* USE_DUFFS_LOOP */ } -static void -Blit1to3(SDL_BlitInfo * info) +static void Blit1to3(SDL_BlitInfo *info) { #ifndef USE_DUFFS_LOOP int c; @@ -210,7 +209,7 @@ Blit1to3(SDL_BlitInfo * info) while (height--) { #ifdef USE_DUFFS_LOOP - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { o = *src * 4; @@ -221,7 +220,7 @@ Blit1to3(SDL_BlitInfo * info) src++; dst += 3; , width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ #else for (c = width; c; --c) { o = *src * 4; @@ -237,8 +236,7 @@ Blit1to3(SDL_BlitInfo * info) } } -static void -Blit1to4(SDL_BlitInfo * info) +static void Blit1to4(SDL_BlitInfo *info) { #ifndef USE_DUFFS_LOOP int c; @@ -253,17 +251,17 @@ Blit1to4(SDL_BlitInfo * info) height = info->dst_h; src = info->src; srcskip = info->src_skip; - dst = (Uint32 *) info->dst; + dst = (Uint32 *)info->dst; dstskip = info->dst_skip / 4; - map = (Uint32 *) info->table; + map = (Uint32 *)info->table; while (height--) { #ifdef USE_DUFFS_LOOP - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( *dst++ = map[*src++]; , width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ #else for (c = width / 4; c; --c) { *dst++ = map[*src++]; @@ -274,8 +272,10 @@ Blit1to4(SDL_BlitInfo * info) switch (width & 3) { case 3: *dst++ = map[*src++]; + SDL_FALLTHROUGH; case 2: *dst++ = map[*src++]; + SDL_FALLTHROUGH; case 1: *dst++ = map[*src++]; } @@ -285,8 +285,7 @@ Blit1to4(SDL_BlitInfo * info) } } -static void -Blit1to1Key(SDL_BlitInfo * info) +static void Blit1to1Key(SDL_BlitInfo *info) { int width = info->dst_w; int height = info->dst_h; @@ -299,7 +298,7 @@ Blit1to1Key(SDL_BlitInfo * info) if (palmap) { while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { if ( *src != ckey ) { @@ -309,13 +308,13 @@ Blit1to1Key(SDL_BlitInfo * info) src++; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } } else { while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { if ( *src != ckey ) { @@ -325,30 +324,29 @@ Blit1to1Key(SDL_BlitInfo * info) src++; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } } } -static void -Blit1to2Key(SDL_BlitInfo * info) +static void Blit1to2Key(SDL_BlitInfo *info) { int width = info->dst_w; int height = info->dst_h; Uint8 *src = info->src; int srcskip = info->src_skip; - Uint16 *dstp = (Uint16 *) info->dst; + Uint16 *dstp = (Uint16 *)info->dst; int dstskip = info->dst_skip; - Uint16 *palmap = (Uint16 *) info->table; + Uint16 *palmap = (Uint16 *)info->table; Uint32 ckey = info->colorkey; /* Set up some basic variables */ dstskip /= 2; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { if ( *src != ckey ) { @@ -358,14 +356,13 @@ Blit1to2Key(SDL_BlitInfo * info) dstp++; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dstp += dstskip; } } -static void -Blit1to3Key(SDL_BlitInfo * info) +static void Blit1to3Key(SDL_BlitInfo *info) { int width = info->dst_w; int height = info->dst_h; @@ -378,7 +375,7 @@ Blit1to3Key(SDL_BlitInfo * info) int o; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { if ( *src != ckey ) { @@ -391,29 +388,28 @@ Blit1to3Key(SDL_BlitInfo * info) dst += 3; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } } -static void -Blit1to4Key(SDL_BlitInfo * info) +static void Blit1to4Key(SDL_BlitInfo *info) { int width = info->dst_w; int height = info->dst_h; Uint8 *src = info->src; int srcskip = info->src_skip; - Uint32 *dstp = (Uint32 *) info->dst; + Uint32 *dstp = (Uint32 *)info->dst; int dstskip = info->dst_skip; - Uint32 *palmap = (Uint32 *) info->table; + Uint32 *palmap = (Uint32 *)info->table; Uint32 ckey = info->colorkey; /* Set up some basic variables */ dstskip /= 4; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { if ( *src != ckey ) { @@ -423,14 +419,13 @@ Blit1to4Key(SDL_BlitInfo * info) dstp++; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dstp += dstskip; } } -static void -Blit1toNAlpha(SDL_BlitInfo * info) +static void Blit1toNAlpha(SDL_BlitInfo *info) { int width = info->dst_w; int height = info->dst_h; @@ -450,7 +445,7 @@ Blit1toNAlpha(SDL_BlitInfo * info) dstbpp = dstfmt->BytesPerPixel; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP4( { sR = srcpal[*src].r; @@ -463,14 +458,13 @@ Blit1toNAlpha(SDL_BlitInfo * info) dst += dstbpp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } } -static void -Blit1toNAlphaKey(SDL_BlitInfo * info) +static void Blit1toNAlphaKey(SDL_BlitInfo *info) { int width = info->dst_w; int height = info->dst_h; @@ -491,7 +485,7 @@ Blit1toNAlphaKey(SDL_BlitInfo * info) dstbpp = dstfmt->BytesPerPixel; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { if ( *src != ckey ) { @@ -506,22 +500,21 @@ Blit1toNAlphaKey(SDL_BlitInfo * info) dst += dstbpp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } } static const SDL_BlitFunc one_blit[] = { - (SDL_BlitFunc) NULL, Blit1to1, Blit1to2, Blit1to3, Blit1to4 + (SDL_BlitFunc)NULL, Blit1to1, Blit1to2, Blit1to3, Blit1to4 }; static const SDL_BlitFunc one_blitkey[] = { - (SDL_BlitFunc) NULL, Blit1to1Key, Blit1to2Key, Blit1to3Key, Blit1to4Key + (SDL_BlitFunc)NULL, Blit1to1Key, Blit1to2Key, Blit1to3Key, Blit1to4Key }; -SDL_BlitFunc -SDL_CalculateBlit1(SDL_Surface * surface) +SDL_BlitFunc SDL_CalculateBlit1(SDL_Surface *surface) { int which; SDL_PixelFormat *dstfmt; @@ -539,16 +532,19 @@ SDL_CalculateBlit1(SDL_Surface * surface) case SDL_COPY_COLORKEY: return one_blitkey[which]; + case SDL_COPY_COLORKEY | SDL_COPY_BLEND: /* this is not super-robust but handles a specific case we found sdl12-compat. */ + return (surface->map->info.a == 255) ? one_blitkey[which] : (SDL_BlitFunc)NULL; + case SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND: /* Supporting 8bpp->8bpp alpha is doable but requires lots of tables which consume space and takes time to precompute, so is better left to the user */ - return which >= 2 ? Blit1toNAlpha : (SDL_BlitFunc) NULL; + return which >= 2 ? Blit1toNAlpha : (SDL_BlitFunc)NULL; case SDL_COPY_COLORKEY | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND: - return which >= 2 ? Blit1toNAlphaKey : (SDL_BlitFunc) NULL; + return which >= 2 ? Blit1toNAlphaKey : (SDL_BlitFunc)NULL; } - return (SDL_BlitFunc) NULL; + return (SDL_BlitFunc)NULL; } #endif /* SDL_HAVE_BLIT_1 */ diff --git a/SDL2-2.0.12/src/video/SDL_blit_A.c b/SDL2-2.30.5/src/video/SDL_blit_A.c similarity index 69% rename from SDL2-2.0.12/src/video/SDL_blit_A.c rename to SDL2-2.30.5/src/video/SDL_blit_A.c index c9c37f0..2cf00e0 100644 --- a/SDL2-2.0.12/src/video/SDL_blit_A.c +++ b/SDL2-2.30.5/src/video/SDL_blit_A.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -28,8 +28,7 @@ /* Functions to perform alpha blended blitting */ /* N->1 blending with per-surface alpha */ -static void -BlitNto1SurfaceAlpha(SDL_BlitInfo * info) +static void BlitNto1SurfaceAlpha(SDL_BlitInfo *info) { int width = info->dst_w; int height = info->dst_h; @@ -47,7 +46,7 @@ BlitNto1SurfaceAlpha(SDL_BlitInfo * info) const unsigned A = info->a; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP4( { DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB); @@ -68,15 +67,14 @@ BlitNto1SurfaceAlpha(SDL_BlitInfo * info) src += srcbpp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } } /* N->1 blending with pixel alpha */ -static void -BlitNto1PixelAlpha(SDL_BlitInfo * info) +static void BlitNto1PixelAlpha(SDL_BlitInfo *info) { int width = info->dst_w; int height = info->dst_h; @@ -93,7 +91,7 @@ BlitNto1PixelAlpha(SDL_BlitInfo * info) unsigned dR, dG, dB; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP4( { DISEMBLE_RGBA(src,srcbpp,srcfmt,Pixel,sR,sG,sB,sA); @@ -114,15 +112,14 @@ BlitNto1PixelAlpha(SDL_BlitInfo * info) src += srcbpp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } } /* colorkeyed N->1 blending with per-surface alpha */ -static void -BlitNto1SurfaceAlphaKey(SDL_BlitInfo * info) +static void BlitNto1SurfaceAlphaKey(SDL_BlitInfo *info) { int width = info->dst_w; int height = info->dst_h; @@ -141,7 +138,7 @@ BlitNto1SurfaceAlphaKey(SDL_BlitInfo * info) const unsigned A = info->a; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB); @@ -164,7 +161,7 @@ BlitNto1SurfaceAlphaKey(SDL_BlitInfo * info) src += srcbpp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -173,51 +170,49 @@ BlitNto1SurfaceAlphaKey(SDL_BlitInfo * info) #ifdef __MMX__ /* fast RGB888->(A)RGB888 blending with surface alpha=128 special case */ -static void -BlitRGBtoRGBSurfaceAlpha128MMX(SDL_BlitInfo * info) +static void BlitRGBtoRGBSurfaceAlpha128MMX(SDL_BlitInfo *info) { int width = info->dst_w; int height = info->dst_h; - Uint32 *srcp = (Uint32 *) info->src; + Uint32 *srcp = (Uint32 *)info->src; int srcskip = info->src_skip >> 2; - Uint32 *dstp = (Uint32 *) info->dst; + Uint32 *dstp = (Uint32 *)info->dst; int dstskip = info->dst_skip >> 2; Uint32 dalpha = info->dst_fmt->Amask; __m64 src1, src2, dst1, dst2, lmask, hmask, dsta; - hmask = _mm_set_pi32(0x00fefefe, 0x00fefefe); /* alpha128 mask -> hmask */ - lmask = _mm_set_pi32(0x00010101, 0x00010101); /* !alpha128 mask -> lmask */ - dsta = _mm_set_pi32(dalpha, dalpha); /* dst alpha mask -> dsta */ + hmask = _mm_set_pi32(0x00fefefe, 0x00fefefe); /* alpha128 mask -> hmask */ + lmask = _mm_set_pi32(0x00010101, 0x00010101); /* !alpha128 mask -> lmask */ + dsta = _mm_set_pi32(dalpha, dalpha); /* dst alpha mask -> dsta */ while (height--) { int n = width; if (n & 1) { Uint32 s = *srcp++; Uint32 d = *dstp; - *dstp++ = ((((s & 0x00fefefe) + (d & 0x00fefefe)) >> 1) - + (s & d & 0x00010101)) | dalpha; + *dstp++ = ((((s & 0x00fefefe) + (d & 0x00fefefe)) >> 1) + (s & d & 0x00010101)) | dalpha; n--; } for (n >>= 1; n > 0; --n) { - dst1 = *(__m64 *) dstp; /* 2 x dst -> dst1(ARGBARGB) */ - dst2 = dst1; /* 2 x dst -> dst2(ARGBARGB) */ + dst1 = *(__m64 *)dstp; /* 2 x dst -> dst1(ARGBARGB) */ + dst2 = dst1; /* 2 x dst -> dst2(ARGBARGB) */ - src1 = *(__m64 *) srcp; /* 2 x src -> src1(ARGBARGB) */ - src2 = src1; /* 2 x src -> src2(ARGBARGB) */ + src1 = *(__m64 *)srcp; /* 2 x src -> src1(ARGBARGB) */ + src2 = src1; /* 2 x src -> src2(ARGBARGB) */ - dst2 = _mm_and_si64(dst2, hmask); /* dst & mask -> dst2 */ - src2 = _mm_and_si64(src2, hmask); /* src & mask -> src2 */ - src2 = _mm_add_pi32(src2, dst2); /* dst2 + src2 -> src2 */ - src2 = _mm_srli_pi32(src2, 1); /* src2 >> 1 -> src2 */ + dst2 = _mm_and_si64(dst2, hmask); /* dst & mask -> dst2 */ + src2 = _mm_and_si64(src2, hmask); /* src & mask -> src2 */ + src2 = _mm_add_pi32(src2, dst2); /* dst2 + src2 -> src2 */ + src2 = _mm_srli_pi32(src2, 1); /* src2 >> 1 -> src2 */ - dst1 = _mm_and_si64(dst1, src1); /* src & dst -> dst1 */ - dst1 = _mm_and_si64(dst1, lmask); /* dst1 & !mask -> dst1 */ - dst1 = _mm_add_pi32(dst1, src2); /* src2 + dst1 -> dst1 */ - dst1 = _mm_or_si64(dst1, dsta); /* dsta(full alpha) | dst1 -> dst1 */ + dst1 = _mm_and_si64(dst1, src1); /* src & dst -> dst1 */ + dst1 = _mm_and_si64(dst1, lmask); /* dst1 & !mask -> dst1 */ + dst1 = _mm_add_pi32(dst1, src2); /* src2 + dst1 -> dst1 */ + dst1 = _mm_or_si64(dst1, dsta); /* dsta(full alpha) | dst1 -> dst1 */ - *(__m64 *) dstp = dst1; /* dst1 -> 2 x dst pixels */ + *(__m64 *)dstp = dst1; /* dst1 -> 2 x dst pixels */ dstp += 2; srcp += 2; } @@ -229,8 +224,7 @@ BlitRGBtoRGBSurfaceAlpha128MMX(SDL_BlitInfo * info) } /* fast RGB888->(A)RGB888 blending with surface alpha */ -static void -BlitRGBtoRGBSurfaceAlphaMMX(SDL_BlitInfo * info) +static void BlitRGBtoRGBSurfaceAlphaMMX(SDL_BlitInfo *info) { SDL_PixelFormat *df = info->dst_fmt; Uint32 chanmask; @@ -242,45 +236,44 @@ BlitRGBtoRGBSurfaceAlphaMMX(SDL_BlitInfo * info) } else { int width = info->dst_w; int height = info->dst_h; - Uint32 *srcp = (Uint32 *) info->src; + Uint32 *srcp = (Uint32 *)info->src; int srcskip = info->src_skip >> 2; - Uint32 *dstp = (Uint32 *) info->dst; + Uint32 *dstp = (Uint32 *)info->dst; int dstskip = info->dst_skip >> 2; Uint32 dalpha = df->Amask; Uint32 amult; __m64 src1, src2, dst1, dst2, mm_alpha, mm_zero, dsta; - mm_zero = _mm_setzero_si64(); /* 0 -> mm_zero */ + mm_zero = _mm_setzero_si64(); /* 0 -> mm_zero */ /* form the alpha mult */ amult = alpha | (alpha << 8); amult = amult | (amult << 16); chanmask = - (0xff << df->Rshift) | (0xff << df-> - Gshift) | (0xff << df->Bshift); + (0xff << df->Rshift) | (0xff << df->Gshift) | (0xff << df->Bshift); mm_alpha = _mm_set_pi32(0, amult & chanmask); /* 0000AAAA -> mm_alpha, minus 1 chan */ mm_alpha = _mm_unpacklo_pi8(mm_alpha, mm_zero); /* 0A0A0A0A -> mm_alpha, minus 1 chan */ /* at this point mm_alpha can be 000A0A0A or 0A0A0A00 or another combo */ - dsta = _mm_set_pi32(dalpha, dalpha); /* dst alpha mask -> dsta */ + dsta = _mm_set_pi32(dalpha, dalpha); /* dst alpha mask -> dsta */ while (height--) { int n = width; if (n & 1) { /* One Pixel Blend */ - src2 = _mm_cvtsi32_si64(*srcp); /* src(ARGB) -> src2 (0000ARGB) */ + src2 = _mm_cvtsi32_si64(*srcp); /* src(ARGB) -> src2 (0000ARGB) */ src2 = _mm_unpacklo_pi8(src2, mm_zero); /* 0A0R0G0B -> src2 */ - dst1 = _mm_cvtsi32_si64(*dstp); /* dst(ARGB) -> dst1 (0000ARGB) */ + dst1 = _mm_cvtsi32_si64(*dstp); /* dst(ARGB) -> dst1 (0000ARGB) */ dst1 = _mm_unpacklo_pi8(dst1, mm_zero); /* 0A0R0G0B -> dst1 */ - src2 = _mm_sub_pi16(src2, dst1); /* src2 - dst2 -> src2 */ - src2 = _mm_mullo_pi16(src2, mm_alpha); /* src2 * alpha -> src2 */ - src2 = _mm_srli_pi16(src2, 8); /* src2 >> 8 -> src2 */ - dst1 = _mm_add_pi8(src2, dst1); /* src2 + dst1 -> dst1 */ + src2 = _mm_sub_pi16(src2, dst1); /* src2 - dst2 -> src2 */ + src2 = _mm_mullo_pi16(src2, mm_alpha); /* src2 * alpha -> src2 */ + src2 = _mm_srli_pi16(src2, 8); /* src2 >> 8 -> src2 */ + dst1 = _mm_add_pi8(src2, dst1); /* src2 + dst1 -> dst1 */ - dst1 = _mm_packs_pu16(dst1, mm_zero); /* 0000ARGB -> dst1 */ - dst1 = _mm_or_si64(dst1, dsta); /* dsta | dst1 -> dst1 */ - *dstp = _mm_cvtsi64_si32(dst1); /* dst1 -> pixel */ + dst1 = _mm_packs_pu16(dst1, mm_zero); /* 0000ARGB -> dst1 */ + dst1 = _mm_or_si64(dst1, dsta); /* dsta | dst1 -> dst1 */ + *dstp = _mm_cvtsi64_si32(dst1); /* dst1 -> pixel */ ++srcp; ++dstp; @@ -290,30 +283,30 @@ BlitRGBtoRGBSurfaceAlphaMMX(SDL_BlitInfo * info) for (n >>= 1; n > 0; --n) { /* Two Pixels Blend */ - src1 = *(__m64 *) srcp; /* 2 x src -> src1(ARGBARGB) */ - src2 = src1; /* 2 x src -> src2(ARGBARGB) */ + src1 = *(__m64 *)srcp; /* 2 x src -> src1(ARGBARGB) */ + src2 = src1; /* 2 x src -> src2(ARGBARGB) */ src1 = _mm_unpacklo_pi8(src1, mm_zero); /* low - 0A0R0G0B -> src1 */ src2 = _mm_unpackhi_pi8(src2, mm_zero); /* high - 0A0R0G0B -> src2 */ - dst1 = *(__m64 *) dstp; /* 2 x dst -> dst1(ARGBARGB) */ - dst2 = dst1; /* 2 x dst -> dst2(ARGBARGB) */ + dst1 = *(__m64 *)dstp; /* 2 x dst -> dst1(ARGBARGB) */ + dst2 = dst1; /* 2 x dst -> dst2(ARGBARGB) */ dst1 = _mm_unpacklo_pi8(dst1, mm_zero); /* low - 0A0R0G0B -> dst1 */ dst2 = _mm_unpackhi_pi8(dst2, mm_zero); /* high - 0A0R0G0B -> dst2 */ - src1 = _mm_sub_pi16(src1, dst1); /* src1 - dst1 -> src1 */ - src1 = _mm_mullo_pi16(src1, mm_alpha); /* src1 * alpha -> src1 */ - src1 = _mm_srli_pi16(src1, 8); /* src1 >> 8 -> src1 */ - dst1 = _mm_add_pi8(src1, dst1); /* src1 + dst1(dst1) -> dst1 */ + src1 = _mm_sub_pi16(src1, dst1); /* src1 - dst1 -> src1 */ + src1 = _mm_mullo_pi16(src1, mm_alpha); /* src1 * alpha -> src1 */ + src1 = _mm_srli_pi16(src1, 8); /* src1 >> 8 -> src1 */ + dst1 = _mm_add_pi8(src1, dst1); /* src1 + dst1(dst1) -> dst1 */ - src2 = _mm_sub_pi16(src2, dst2); /* src2 - dst2 -> src2 */ - src2 = _mm_mullo_pi16(src2, mm_alpha); /* src2 * alpha -> src2 */ - src2 = _mm_srli_pi16(src2, 8); /* src2 >> 8 -> src2 */ - dst2 = _mm_add_pi8(src2, dst2); /* src2 + dst2(dst2) -> dst2 */ + src2 = _mm_sub_pi16(src2, dst2); /* src2 - dst2 -> src2 */ + src2 = _mm_mullo_pi16(src2, mm_alpha); /* src2 * alpha -> src2 */ + src2 = _mm_srli_pi16(src2, 8); /* src2 >> 8 -> src2 */ + dst2 = _mm_add_pi8(src2, dst2); /* src2 + dst2(dst2) -> dst2 */ - dst1 = _mm_packs_pu16(dst1, dst2); /* 0A0R0G0B(res1), 0A0R0G0B(res2) -> dst1(ARGBARGB) */ - dst1 = _mm_or_si64(dst1, dsta); /* dsta | dst1 -> dst1 */ + dst1 = _mm_packs_pu16(dst1, dst2); /* 0A0R0G0B(res1), 0A0R0G0B(res2) -> dst1(ARGBARGB) */ + dst1 = _mm_or_si64(dst1, dsta); /* dsta | dst1 -> dst1 */ - *(__m64 *) dstp = dst1; /* dst1 -> 2 x pixel */ + *(__m64 *)dstp = dst1; /* dst1 -> 2 x pixel */ srcp += 2; dstp += 2; @@ -326,29 +319,38 @@ BlitRGBtoRGBSurfaceAlphaMMX(SDL_BlitInfo * info) } /* fast ARGB888->(A)RGB888 blending with pixel alpha */ -static void -BlitRGBtoRGBPixelAlphaMMX(SDL_BlitInfo * info) +static void BlitRGBtoRGBPixelAlphaMMX(SDL_BlitInfo *info) { int width = info->dst_w; int height = info->dst_h; - Uint32 *srcp = (Uint32 *) info->src; + Uint32 *srcp = (Uint32 *)info->src; int srcskip = info->src_skip >> 2; - Uint32 *dstp = (Uint32 *) info->dst; + Uint32 *dstp = (Uint32 *)info->dst; int dstskip = info->dst_skip >> 2; SDL_PixelFormat *sf = info->src_fmt; Uint32 amask = sf->Amask; Uint32 ashift = sf->Ashift; Uint64 multmask, multmask2; - __m64 src1, dst1, mm_alpha, mm_zero, mm_alpha2; + __m64 src1, dst1, mm_alpha, mm_zero, mm_alpha2, mm_one_alpha; + + mm_zero = _mm_setzero_si64(); /* 0 -> mm_zero */ + if (amask == 0xFF000000) { /* 1 in the alpha channel -> mm_one_alpha */ + mm_one_alpha = _mm_set_pi16(1, 0, 0, 0); + } else if (amask == 0x00FF0000) { + mm_one_alpha = _mm_set_pi16(0, 1, 0, 0); + } else if (amask == 0x0000FF00) { + mm_one_alpha = _mm_set_pi16(0, 0, 1, 0); + } else { + mm_one_alpha = _mm_set_pi16(0, 0, 0, 1); + } - mm_zero = _mm_setzero_si64(); /* 0 -> mm_zero */ multmask = 0x00FF; multmask <<= (ashift * 2); multmask2 = 0x00FF00FF00FF00FFULL; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP4({ Uint32 alpha = *srcp & amask; if (alpha == 0) { @@ -369,20 +371,39 @@ BlitRGBtoRGBPixelAlphaMMX(SDL_BlitInfo * info) mm_alpha = _mm_or_si64(mm_alpha2, *(__m64 *) & multmask); /* 0F0A0A0A -> mm_alpha */ mm_alpha2 = _mm_xor_si64(mm_alpha2, *(__m64 *) & multmask2); /* 255 - mm_alpha -> mm_alpha */ - /* blend */ + /* + Alpha blending is: + dstRGB = (srcRGB * srcA) + (dstRGB * (1-srcA)) + dstA = srcA + (dstA * (1-srcA)) * + + Here, 'src1' is: + srcRGB * srcA + srcA + And 'dst1' is: + dstRGB * (1-srcA) + dstA * (1-srcA) + so that *dstp is 'src1 + dst1' + + src1 is computed using mullo_pi16: (X * mask) >> 8, but is approximate for srcA ((srcA * 255) >> 8). + + need to a 1 to get an exact result: (srcA * 256) >> 8 == srcA + */ + mm_alpha = _mm_add_pi16(mm_alpha, mm_one_alpha); + + /* blend */ src1 = _mm_mullo_pi16(src1, mm_alpha); src1 = _mm_srli_pi16(src1, 8); dst1 = _mm_mullo_pi16(dst1, mm_alpha2); dst1 = _mm_srli_pi16(dst1, 8); dst1 = _mm_add_pi16(src1, dst1); dst1 = _mm_packs_pu16(dst1, mm_zero); - + *dstp = _mm_cvtsi64_si32(dst1); /* dst1 -> pixel */ } ++srcp; ++dstp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ srcp += srcskip; dstp += dstskip; } @@ -391,26 +412,24 @@ BlitRGBtoRGBPixelAlphaMMX(SDL_BlitInfo * info) #endif /* __MMX__ */ -#if SDL_ARM_SIMD_BLITTERS +#ifdef SDL_ARM_SIMD_BLITTERS void BlitARGBto565PixelAlphaARMSIMDAsm(int32_t w, int32_t h, uint16_t *dst, int32_t dst_stride, uint32_t *src, int32_t src_stride); -static void -BlitARGBto565PixelAlphaARMSIMD(SDL_BlitInfo * info) +static void BlitARGBto565PixelAlphaARMSIMD(SDL_BlitInfo *info) { - int32_t width = info->dst_w; - int32_t height = info->dst_h; - uint16_t *dstp = (uint16_t *)info->dst; - int32_t dststride = width + (info->dst_skip >> 1); - uint32_t *srcp = (uint32_t *)info->src; - int32_t srcstride = width + (info->src_skip >> 2); + int32_t width = info->dst_w; + int32_t height = info->dst_h; + uint16_t *dstp = (uint16_t *)info->dst; + int32_t dststride = width + (info->dst_skip >> 1); + uint32_t *srcp = (uint32_t *)info->src; + int32_t srcstride = width + (info->src_skip >> 2); - BlitARGBto565PixelAlphaARMSIMDAsm(width, height, dstp, dststride, srcp, srcstride); + BlitARGBto565PixelAlphaARMSIMDAsm(width, height, dstp, dststride, srcp, srcstride); } void BlitRGBtoRGBPixelAlphaARMSIMDAsm(int32_t w, int32_t h, uint32_t *dst, int32_t dst_stride, uint32_t *src, int32_t src_stride); -static void -BlitRGBtoRGBPixelAlphaARMSIMD(SDL_BlitInfo * info) +static void BlitRGBtoRGBPixelAlphaARMSIMD(SDL_BlitInfo *info) { int32_t width = info->dst_w; int32_t height = info->dst_h; @@ -423,11 +442,10 @@ BlitRGBtoRGBPixelAlphaARMSIMD(SDL_BlitInfo * info) } #endif -#if SDL_ARM_NEON_BLITTERS +#ifdef SDL_ARM_NEON_BLITTERS void BlitARGBto565PixelAlphaARMNEONAsm(int32_t w, int32_t h, uint16_t *dst, int32_t dst_stride, uint32_t *src, int32_t src_stride); -static void -BlitARGBto565PixelAlphaARMNEON(SDL_BlitInfo * info) +static void BlitARGBto565PixelAlphaARMNEON(SDL_BlitInfo *info) { int32_t width = info->dst_w; int32_t height = info->dst_h; @@ -441,48 +459,45 @@ BlitARGBto565PixelAlphaARMNEON(SDL_BlitInfo * info) void BlitRGBtoRGBPixelAlphaARMNEONAsm(int32_t w, int32_t h, uint32_t *dst, int32_t dst_stride, uint32_t *src, int32_t src_stride); -static void -BlitRGBtoRGBPixelAlphaARMNEON(SDL_BlitInfo * info) +static void BlitRGBtoRGBPixelAlphaARMNEON(SDL_BlitInfo *info) { - int32_t width = info->dst_w; - int32_t height = info->dst_h; - uint32_t *dstp = (uint32_t *)info->dst; - int32_t dststride = width + (info->dst_skip >> 2); - uint32_t *srcp = (uint32_t *)info->src; - int32_t srcstride = width + (info->src_skip >> 2); + int32_t width = info->dst_w; + int32_t height = info->dst_h; + uint32_t *dstp = (uint32_t *)info->dst; + int32_t dststride = width + (info->dst_skip >> 2); + uint32_t *srcp = (uint32_t *)info->src; + int32_t srcstride = width + (info->src_skip >> 2); - BlitRGBtoRGBPixelAlphaARMNEONAsm(width, height, dstp, dststride, srcp, srcstride); + BlitRGBtoRGBPixelAlphaARMNEONAsm(width, height, dstp, dststride, srcp, srcstride); } #endif /* fast RGB888->(A)RGB888 blending with surface alpha=128 special case */ -static void -BlitRGBtoRGBSurfaceAlpha128(SDL_BlitInfo * info) +static void BlitRGBtoRGBSurfaceAlpha128(SDL_BlitInfo *info) { int width = info->dst_w; int height = info->dst_h; - Uint32 *srcp = (Uint32 *) info->src; + Uint32 *srcp = (Uint32 *)info->src; int srcskip = info->src_skip >> 2; - Uint32 *dstp = (Uint32 *) info->dst; + Uint32 *dstp = (Uint32 *)info->dst; int dstskip = info->dst_skip >> 2; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP4({ Uint32 s = *srcp++; Uint32 d = *dstp; *dstp++ = ((((s & 0x00fefefe) + (d & 0x00fefefe)) >> 1) + (s & d & 0x00010101)) | 0xff000000; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ srcp += srcskip; dstp += dstskip; } } /* fast RGB888->(A)RGB888 blending with surface alpha */ -static void -BlitRGBtoRGBSurfaceAlpha(SDL_BlitInfo * info) +static void BlitRGBtoRGBSurfaceAlpha(SDL_BlitInfo *info) { unsigned alpha = info->a; if (alpha == 128) { @@ -490,9 +505,9 @@ BlitRGBtoRGBSurfaceAlpha(SDL_BlitInfo * info) } else { int width = info->dst_w; int height = info->dst_h; - Uint32 *srcp = (Uint32 *) info->src; + Uint32 *srcp = (Uint32 *)info->src; int srcskip = info->src_skip >> 2; - Uint32 *dstp = (Uint32 *) info->dst; + Uint32 *dstp = (Uint32 *)info->dst; int dstskip = info->dst_skip >> 2; Uint32 s; Uint32 d; @@ -500,7 +515,7 @@ BlitRGBtoRGBSurfaceAlpha(SDL_BlitInfo * info) Uint32 d1; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP4({ s = *srcp; d = *dstp; @@ -515,7 +530,7 @@ BlitRGBtoRGBSurfaceAlpha(SDL_BlitInfo * info) ++srcp; ++dstp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ srcp += srcskip; dstp += dstskip; } @@ -523,18 +538,17 @@ BlitRGBtoRGBSurfaceAlpha(SDL_BlitInfo * info) } /* fast ARGB888->(A)RGB888 blending with pixel alpha */ -static void -BlitRGBtoRGBPixelAlpha(SDL_BlitInfo * info) +static void BlitRGBtoRGBPixelAlpha(SDL_BlitInfo *info) { int width = info->dst_w; int height = info->dst_h; - Uint32 *srcp = (Uint32 *) info->src; + Uint32 *srcp = (Uint32 *)info->src; int srcskip = info->src_skip >> 2; - Uint32 *dstp = (Uint32 *) info->dst; + Uint32 *dstp = (Uint32 *)info->dst; int dstskip = info->dst_skip >> 2; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP4({ Uint32 dalpha; Uint32 d; @@ -569,7 +583,61 @@ BlitRGBtoRGBPixelAlpha(SDL_BlitInfo * info) ++srcp; ++dstp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ + srcp += srcskip; + dstp += dstskip; + } +} + +/* fast ARGB888->(A)BGR888 blending with pixel alpha */ +static void BlitRGBtoBGRPixelAlpha(SDL_BlitInfo *info) +{ + int width = info->dst_w; + int height = info->dst_h; + Uint32 *srcp = (Uint32 *)info->src; + int srcskip = info->src_skip >> 2; + Uint32 *dstp = (Uint32 *)info->dst; + int dstskip = info->dst_skip >> 2; + + while (height--) { + /* *INDENT-OFF* */ /* clang-format off */ + DUFFS_LOOP4({ + Uint32 dalpha; + Uint32 d; + Uint32 s1; + Uint32 d1; + Uint32 s = *srcp; + Uint32 alpha = s >> 24; + /* FIXME: Here we special-case opaque alpha since the + compositioning used (>>8 instead of /255) doesn't handle + it correctly. Also special-case alpha=0 for speed? + Benchmark this! */ + if (alpha) { + /* + * take out the middle component (green), and process + * the other two in parallel. One multiply less. + */ + s1 = s & 0xff00ff; + s1 = (s1 >> 16) | (s1 << 16); + s &= 0xff00; + + if (alpha == SDL_ALPHA_OPAQUE) { + *dstp = 0xff000000 | s | s1; + } else { + d = *dstp; + dalpha = d >> 24; + d1 = d & 0xff00ff; + d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff; + d &= 0xff00; + d = (d + ((s - d) * alpha >> 8)) & 0xff00; + dalpha = alpha + (dalpha * (alpha ^ 0xFF) >> 8); + *dstp = d1 | d | (dalpha << 24); + } + } + ++srcp; + ++dstp; + }, width); + /* *INDENT-ON* */ /* clang-format on */ srcp += srcskip; dstp += dstskip; } @@ -577,29 +645,38 @@ BlitRGBtoRGBPixelAlpha(SDL_BlitInfo * info) #ifdef __3dNOW__ /* fast (as in MMX with prefetch) ARGB888->(A)RGB888 blending with pixel alpha */ -static void -BlitRGBtoRGBPixelAlphaMMX3DNOW(SDL_BlitInfo * info) +static void BlitRGBtoRGBPixelAlphaMMX3DNOW(SDL_BlitInfo *info) { int width = info->dst_w; int height = info->dst_h; - Uint32 *srcp = (Uint32 *) info->src; + Uint32 *srcp = (Uint32 *)info->src; int srcskip = info->src_skip >> 2; - Uint32 *dstp = (Uint32 *) info->dst; + Uint32 *dstp = (Uint32 *)info->dst; int dstskip = info->dst_skip >> 2; SDL_PixelFormat *sf = info->src_fmt; Uint32 amask = sf->Amask; Uint32 ashift = sf->Ashift; Uint64 multmask, multmask2; - __m64 src1, dst1, mm_alpha, mm_zero, mm_alpha2; + __m64 src1, dst1, mm_alpha, mm_zero, mm_alpha2, mm_one_alpha; + + mm_zero = _mm_setzero_si64(); /* 0 -> mm_zero */ + if (amask == 0xFF000000) { /* 1 in the alpha channel -> mm_one_alpha */ + mm_one_alpha = _mm_set_pi16(1, 0, 0, 0); + } else if (amask == 0x00FF0000) { + mm_one_alpha = _mm_set_pi16(0, 1, 0, 0); + } else if (amask == 0x0000FF00) { + mm_one_alpha = _mm_set_pi16(0, 0, 1, 0); + } else { + mm_one_alpha = _mm_set_pi16(0, 0, 0, 1); + } - mm_zero = _mm_setzero_si64(); /* 0 -> mm_zero */ multmask = 0x00FF; multmask <<= (ashift * 2); multmask2 = 0x00FF00FF00FF00FFULL; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP4({ Uint32 alpha; @@ -625,21 +702,39 @@ BlitRGBtoRGBPixelAlphaMMX3DNOW(SDL_BlitInfo * info) mm_alpha = _mm_or_si64(mm_alpha2, *(__m64 *) & multmask); /* 0F0A0A0A -> mm_alpha */ mm_alpha2 = _mm_xor_si64(mm_alpha2, *(__m64 *) & multmask2); /* 255 - mm_alpha -> mm_alpha */ + /* + Alpha blending is: + dstRGB = (srcRGB * srcA) + (dstRGB * (1-srcA)) + dstA = srcA + (dstA * (1-srcA)) * - /* blend */ + Here, 'src1' is: + srcRGB * srcA + srcA + And 'dst1' is: + dstRGB * (1-srcA) + dstA * (1-srcA) + so that *dstp is 'src1 + dst1' + + src1 is computed using mullo_pi16: (X * mask) >> 8, but is approximate for srcA ((srcA * 255) >> 8). + + need to a 1 to get an exact result: (srcA * 256) >> 8 == srcA + */ + mm_alpha = _mm_add_pi16(mm_alpha, mm_one_alpha); + + /* blend */ src1 = _mm_mullo_pi16(src1, mm_alpha); src1 = _mm_srli_pi16(src1, 8); dst1 = _mm_mullo_pi16(dst1, mm_alpha2); dst1 = _mm_srli_pi16(dst1, 8); dst1 = _mm_add_pi16(src1, dst1); dst1 = _mm_packs_pu16(dst1, mm_zero); - + *dstp = _mm_cvtsi64_si32(dst1); /* dst1 -> pixel */ } ++srcp; ++dstp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ srcp += srcskip; dstp += dstskip; } @@ -651,26 +746,24 @@ BlitRGBtoRGBPixelAlphaMMX3DNOW(SDL_BlitInfo * info) /* 16bpp special case for per-surface alpha=50%: blend 2 pixels in parallel */ /* blend a single 16 bit pixel at 50% */ -#define BLEND16_50(d, s, mask) \ +#define BLEND16_50(d, s, mask) \ ((((s & mask) + (d & mask)) >> 1) + (s & d & (~mask & 0xffff))) /* blend two 16 bit pixels at 50% */ -#define BLEND2x16_50(d, s, mask) \ - (((s & (mask | mask << 16)) >> 1) + ((d & (mask | mask << 16)) >> 1) \ - + (s & d & (~(mask | mask << 16)))) +#define BLEND2x16_50(d, s, mask) \ + (((s & (mask | mask << 16)) >> 1) + ((d & (mask | mask << 16)) >> 1) + (s & d & (~(mask | mask << 16)))) -static void -Blit16to16SurfaceAlpha128(SDL_BlitInfo * info, Uint16 mask) +static void Blit16to16SurfaceAlpha128(SDL_BlitInfo *info, Uint16 mask) { int width = info->dst_w; int height = info->dst_h; - Uint16 *srcp = (Uint16 *) info->src; + Uint16 *srcp = (Uint16 *)info->src; int srcskip = info->src_skip >> 1; - Uint16 *dstp = (Uint16 *) info->dst; + Uint16 *dstp = (Uint16 *)info->dst; int dstskip = info->dst_skip >> 1; while (height--) { - if (((uintptr_t) srcp ^ (uintptr_t) dstp) & 2) { + if (((uintptr_t)srcp ^ (uintptr_t)dstp) & 2) { /* * Source and destination not aligned, pipeline it. * This is mostly a win for big blits but no loss for @@ -680,29 +773,29 @@ Blit16to16SurfaceAlpha128(SDL_BlitInfo * info, Uint16 mask) int w = width; /* handle odd destination */ - if ((uintptr_t) dstp & 2) { + if ((uintptr_t)dstp & 2) { Uint16 d = *dstp, s = *srcp; *dstp = BLEND16_50(d, s, mask); dstp++; srcp++; w--; } - srcp++; /* srcp is now 32-bit aligned */ + srcp++; /* srcp is now 32-bit aligned */ /* bootstrap pipeline with first halfword */ - prev_sw = ((Uint32 *) srcp)[-1]; + prev_sw = ((Uint32 *)srcp)[-1]; while (w > 1) { Uint32 sw, dw, s; - sw = *(Uint32 *) srcp; - dw = *(Uint32 *) dstp; + sw = *(Uint32 *)srcp; + dw = *(Uint32 *)dstp; #if SDL_BYTEORDER == SDL_BIG_ENDIAN s = (prev_sw << 16) + (sw >> 16); #else s = (prev_sw >> 16) + (sw << 16); #endif prev_sw = sw; - *(Uint32 *) dstp = BLEND2x16_50(dw, s, mask); + *(Uint32 *)dstp = BLEND2x16_50(dw, s, mask); dstp += 2; srcp += 2; w -= 2; @@ -712,9 +805,9 @@ Blit16to16SurfaceAlpha128(SDL_BlitInfo * info, Uint16 mask) if (w) { Uint16 d = *dstp, s; #if SDL_BYTEORDER == SDL_BIG_ENDIAN - s = (Uint16) prev_sw; + s = (Uint16)prev_sw; #else - s = (Uint16) (prev_sw >> 16); + s = (Uint16)(prev_sw >> 16); #endif *dstp = BLEND16_50(d, s, mask); srcp++; @@ -727,7 +820,7 @@ Blit16to16SurfaceAlpha128(SDL_BlitInfo * info, Uint16 mask) int w = width; /* first odd pixel? */ - if ((uintptr_t) srcp & 2) { + if ((uintptr_t)srcp & 2) { Uint16 d = *dstp, s = *srcp; *dstp = BLEND16_50(d, s, mask); srcp++; @@ -737,9 +830,9 @@ Blit16to16SurfaceAlpha128(SDL_BlitInfo * info, Uint16 mask) /* srcp and dstp are now 32-bit aligned */ while (w > 1) { - Uint32 sw = *(Uint32 *) srcp; - Uint32 dw = *(Uint32 *) dstp; - *(Uint32 *) dstp = BLEND2x16_50(dw, sw, mask); + Uint32 sw = *(Uint32 *)srcp; + Uint32 dw = *(Uint32 *)dstp; + *(Uint32 *)dstp = BLEND2x16_50(dw, sw, mask); srcp += 2; dstp += 2; w -= 2; @@ -761,8 +854,7 @@ Blit16to16SurfaceAlpha128(SDL_BlitInfo * info, Uint16 mask) #ifdef __MMX__ /* fast RGB565->RGB565 blending with surface alpha */ -static void -Blit565to565SurfaceAlphaMMX(SDL_BlitInfo * info) +static void Blit565to565SurfaceAlphaMMX(SDL_BlitInfo *info) { unsigned alpha = info->a; if (alpha == 128) { @@ -770,30 +862,32 @@ Blit565to565SurfaceAlphaMMX(SDL_BlitInfo * info) } else { int width = info->dst_w; int height = info->dst_h; - Uint16 *srcp = (Uint16 *) info->src; + Uint16 *srcp = (Uint16 *)info->src; int srcskip = info->src_skip >> 1; - Uint16 *dstp = (Uint16 *) info->dst; + Uint16 *dstp = (Uint16 *)info->dst; int dstskip = info->dst_skip >> 1; Uint32 s, d; +#ifdef USE_DUFFS_LOOP __m64 src1, dst1, src2, dst2, gmask, bmask, mm_res, mm_alpha; - alpha &= ~(1 + 2 + 4); /* cut alpha to get the exact same behaviour */ - mm_alpha = _mm_set_pi32(0, alpha); /* 0000000A -> mm_alpha */ - alpha >>= 3; /* downscale alpha to 5 bits */ + alpha &= ~(1 + 2 + 4); /* cut alpha to get the exact same behaviour */ + mm_alpha = _mm_set_pi32(0, alpha); /* 0000000A -> mm_alpha */ + alpha >>= 3; /* downscale alpha to 5 bits */ - mm_alpha = _mm_unpacklo_pi16(mm_alpha, mm_alpha); /* 00000A0A -> mm_alpha */ - mm_alpha = _mm_unpacklo_pi32(mm_alpha, mm_alpha); /* 0A0A0A0A -> mm_alpha */ + mm_alpha = _mm_unpacklo_pi16(mm_alpha, mm_alpha); /* 00000A0A -> mm_alpha */ + mm_alpha = _mm_unpacklo_pi32(mm_alpha, mm_alpha); /* 0A0A0A0A -> mm_alpha */ /* position alpha to allow for mullo and mulhi on diff channels to reduce the number of operations */ mm_alpha = _mm_slli_si64(mm_alpha, 3); /* Setup the 565 color channel masks */ - gmask = _mm_set_pi32(0x07E007E0, 0x07E007E0); /* MASKGREEN -> gmask */ - bmask = _mm_set_pi32(0x001F001F, 0x001F001F); /* MASKBLUE -> bmask */ + gmask = _mm_set_pi32(0x07E007E0, 0x07E007E0); /* MASKGREEN -> gmask */ + bmask = _mm_set_pi32(0x001F001F, 0x001F001F); /* MASKBLUE -> bmask */ +#endif while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP_124( { s = *srcp++; @@ -889,7 +983,7 @@ Blit565to565SurfaceAlphaMMX(SDL_BlitInfo * info) srcp += 4; dstp += 4; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ srcp += srcskip; dstp += dstskip; } @@ -898,8 +992,7 @@ Blit565to565SurfaceAlphaMMX(SDL_BlitInfo * info) } /* fast RGB555->RGB555 blending with surface alpha */ -static void -Blit555to555SurfaceAlphaMMX(SDL_BlitInfo * info) +static void Blit555to555SurfaceAlphaMMX(SDL_BlitInfo *info) { unsigned alpha = info->a; if (alpha == 128) { @@ -907,31 +1000,32 @@ Blit555to555SurfaceAlphaMMX(SDL_BlitInfo * info) } else { int width = info->dst_w; int height = info->dst_h; - Uint16 *srcp = (Uint16 *) info->src; + Uint16 *srcp = (Uint16 *)info->src; int srcskip = info->src_skip >> 1; - Uint16 *dstp = (Uint16 *) info->dst; + Uint16 *dstp = (Uint16 *)info->dst; int dstskip = info->dst_skip >> 1; Uint32 s, d; +#ifdef USE_DUFFS_LOOP __m64 src1, dst1, src2, dst2, rmask, gmask, bmask, mm_res, mm_alpha; - alpha &= ~(1 + 2 + 4); /* cut alpha to get the exact same behaviour */ - mm_alpha = _mm_set_pi32(0, alpha); /* 0000000A -> mm_alpha */ - alpha >>= 3; /* downscale alpha to 5 bits */ + alpha &= ~(1 + 2 + 4); /* cut alpha to get the exact same behaviour */ + mm_alpha = _mm_set_pi32(0, alpha); /* 0000000A -> mm_alpha */ + alpha >>= 3; /* downscale alpha to 5 bits */ - mm_alpha = _mm_unpacklo_pi16(mm_alpha, mm_alpha); /* 00000A0A -> mm_alpha */ - mm_alpha = _mm_unpacklo_pi32(mm_alpha, mm_alpha); /* 0A0A0A0A -> mm_alpha */ + mm_alpha = _mm_unpacklo_pi16(mm_alpha, mm_alpha); /* 00000A0A -> mm_alpha */ + mm_alpha = _mm_unpacklo_pi32(mm_alpha, mm_alpha); /* 0A0A0A0A -> mm_alpha */ /* position alpha to allow for mullo and mulhi on diff channels to reduce the number of operations */ mm_alpha = _mm_slli_si64(mm_alpha, 3); /* Setup the 555 color channel masks */ - rmask = _mm_set_pi32(0x7C007C00, 0x7C007C00); /* MASKRED -> rmask */ - gmask = _mm_set_pi32(0x03E003E0, 0x03E003E0); /* MASKGREEN -> gmask */ - bmask = _mm_set_pi32(0x001F001F, 0x001F001F); /* MASKBLUE -> bmask */ - + rmask = _mm_set_pi32(0x7C007C00, 0x7C007C00); /* MASKRED -> rmask */ + gmask = _mm_set_pi32(0x03E003E0, 0x03E003E0); /* MASKGREEN -> gmask */ + bmask = _mm_set_pi32(0x001F001F, 0x001F001F); /* MASKBLUE -> bmask */ +#endif while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP_124( { s = *srcp++; @@ -990,7 +1084,7 @@ Blit555to555SurfaceAlphaMMX(SDL_BlitInfo * info) dst2 = _mm_and_si64(dst2, rmask); /* dst2 & MASKRED -> dst2 */ mm_res = dst2; /* RED -> mm_res */ - + /* green -- process the bits in place */ src2 = src1; src2 = _mm_and_si64(src2, gmask); /* src & MASKGREEN -> src2 */ @@ -1027,7 +1121,7 @@ Blit555to555SurfaceAlphaMMX(SDL_BlitInfo * info) srcp += 4; dstp += 4; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ srcp += srcskip; dstp += dstskip; } @@ -1038,8 +1132,7 @@ Blit555to555SurfaceAlphaMMX(SDL_BlitInfo * info) #endif /* __MMX__ */ /* fast RGB565->RGB565 blending with surface alpha */ -static void -Blit565to565SurfaceAlpha(SDL_BlitInfo * info) +static void Blit565to565SurfaceAlpha(SDL_BlitInfo *info) { unsigned alpha = info->a; if (alpha == 128) { @@ -1047,14 +1140,14 @@ Blit565to565SurfaceAlpha(SDL_BlitInfo * info) } else { int width = info->dst_w; int height = info->dst_h; - Uint16 *srcp = (Uint16 *) info->src; + Uint16 *srcp = (Uint16 *)info->src; int srcskip = info->src_skip >> 1; - Uint16 *dstp = (Uint16 *) info->dst; + Uint16 *dstp = (Uint16 *)info->dst; int dstskip = info->dst_skip >> 1; - alpha >>= 3; /* downscale alpha to 5 bits */ + alpha >>= 3; /* downscale alpha to 5 bits */ while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP4({ Uint32 s = *srcp++; Uint32 d = *dstp; @@ -1069,7 +1162,7 @@ Blit565to565SurfaceAlpha(SDL_BlitInfo * info) d &= 0x07e0f81f; *dstp++ = (Uint16)(d | d >> 16); }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ srcp += srcskip; dstp += dstskip; } @@ -1077,23 +1170,22 @@ Blit565to565SurfaceAlpha(SDL_BlitInfo * info) } /* fast RGB555->RGB555 blending with surface alpha */ -static void -Blit555to555SurfaceAlpha(SDL_BlitInfo * info) +static void Blit555to555SurfaceAlpha(SDL_BlitInfo *info) { - unsigned alpha = info->a; /* downscale alpha to 5 bits */ + unsigned alpha = info->a; /* downscale alpha to 5 bits */ if (alpha == 128) { Blit16to16SurfaceAlpha128(info, 0xfbde); } else { int width = info->dst_w; int height = info->dst_h; - Uint16 *srcp = (Uint16 *) info->src; + Uint16 *srcp = (Uint16 *)info->src; int srcskip = info->src_skip >> 1; - Uint16 *dstp = (Uint16 *) info->dst; + Uint16 *dstp = (Uint16 *)info->dst; int dstskip = info->dst_skip >> 1; - alpha >>= 3; /* downscale alpha to 5 bits */ + alpha >>= 3; /* downscale alpha to 5 bits */ while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP4({ Uint32 s = *srcp++; Uint32 d = *dstp; @@ -1108,7 +1200,7 @@ Blit555to555SurfaceAlpha(SDL_BlitInfo * info) d &= 0x03e07c1f; *dstp++ = (Uint16)(d | d >> 16); }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ srcp += srcskip; dstp += dstskip; } @@ -1116,18 +1208,17 @@ Blit555to555SurfaceAlpha(SDL_BlitInfo * info) } /* fast ARGB8888->RGB565 blending with pixel alpha */ -static void -BlitARGBto565PixelAlpha(SDL_BlitInfo * info) +static void BlitARGBto565PixelAlpha(SDL_BlitInfo *info) { int width = info->dst_w; int height = info->dst_h; - Uint32 *srcp = (Uint32 *) info->src; + Uint32 *srcp = (Uint32 *)info->src; int srcskip = info->src_skip >> 2; - Uint16 *dstp = (Uint16 *) info->dst; + Uint16 *dstp = (Uint16 *)info->dst; int dstskip = info->dst_skip >> 1; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP4({ Uint32 s = *srcp; unsigned alpha = s >> 27; /* downscale alpha to 5 bits */ @@ -1135,8 +1226,8 @@ BlitARGBto565PixelAlpha(SDL_BlitInfo * info) compositioning used (>>8 instead of /255) doesn't handle it correctly. Also special-case alpha=0 for speed? Benchmark this! */ - if(alpha) { - if(alpha == (SDL_ALPHA_OPAQUE >> 3)) { + if (alpha) { + if (alpha == (SDL_ALPHA_OPAQUE >> 3)) { *dstp = (Uint16)((s >> 8 & 0xf800) + (s >> 5 & 0x7e0) + (s >> 3 & 0x1f)); } else { Uint32 d = *dstp; @@ -1155,25 +1246,24 @@ BlitARGBto565PixelAlpha(SDL_BlitInfo * info) srcp++; dstp++; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ srcp += srcskip; dstp += dstskip; } } /* fast ARGB8888->RGB555 blending with pixel alpha */ -static void -BlitARGBto555PixelAlpha(SDL_BlitInfo * info) +static void BlitARGBto555PixelAlpha(SDL_BlitInfo *info) { int width = info->dst_w; int height = info->dst_h; - Uint32 *srcp = (Uint32 *) info->src; + Uint32 *srcp = (Uint32 *)info->src; int srcskip = info->src_skip >> 2; - Uint16 *dstp = (Uint16 *) info->dst; + Uint16 *dstp = (Uint16 *)info->dst; int dstskip = info->dst_skip >> 1; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP4({ unsigned alpha; Uint32 s = *srcp; @@ -1182,8 +1272,8 @@ BlitARGBto555PixelAlpha(SDL_BlitInfo * info) compositioning used (>>8 instead of /255) doesn't handle it correctly. Also special-case alpha=0 for speed? Benchmark this! */ - if(alpha) { - if(alpha == (SDL_ALPHA_OPAQUE >> 3)) { + if (alpha) { + if (alpha == (SDL_ALPHA_OPAQUE >> 3)) { *dstp = (Uint16)((s >> 9 & 0x7c00) + (s >> 6 & 0x3e0) + (s >> 3 & 0x1f)); } else { Uint32 d = *dstp; @@ -1202,15 +1292,14 @@ BlitARGBto555PixelAlpha(SDL_BlitInfo * info) srcp++; dstp++; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ srcp += srcskip; dstp += dstskip; } } /* General (slow) N->N blending with per-surface alpha */ -static void -BlitNtoNSurfaceAlpha(SDL_BlitInfo * info) +static void BlitNtoNSurfaceAlpha(SDL_BlitInfo *info) { int width = info->dst_w; int height = info->dst_h; @@ -1229,7 +1318,7 @@ BlitNtoNSurfaceAlpha(SDL_BlitInfo * info) if (sA) { while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP4( { DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB); @@ -1240,7 +1329,7 @@ BlitNtoNSurfaceAlpha(SDL_BlitInfo * info) dst += dstbpp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -1248,8 +1337,7 @@ BlitNtoNSurfaceAlpha(SDL_BlitInfo * info) } /* General (slow) colorkeyed N->N blending with per-surface alpha */ -static void -BlitNtoNSurfaceAlphaKey(SDL_BlitInfo * info) +static void BlitNtoNSurfaceAlphaKey(SDL_BlitInfo *info) { int width = info->dst_w; int height = info->dst_h; @@ -1268,11 +1356,11 @@ BlitNtoNSurfaceAlphaKey(SDL_BlitInfo * info) const unsigned sA = info->a; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP4( { RETRIEVE_RGB_PIXEL(src, srcbpp, Pixel); - if(sA && Pixel != ckey) { + if (sA && Pixel != ckey) { RGB_FROM_PIXEL(Pixel, srcfmt, sR, sG, sB); DISEMBLE_RGBA(dst, dstbpp, dstfmt, Pixel, dR, dG, dB, dA); ALPHA_BLEND_RGBA(sR, sG, sB, sA, dR, dG, dB, dA); @@ -1282,15 +1370,14 @@ BlitNtoNSurfaceAlphaKey(SDL_BlitInfo * info) dst += dstbpp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } } /* General (slow) N->N blending with pixel alpha */ -static void -BlitNtoNPixelAlpha(SDL_BlitInfo * info) +static void BlitNtoNPixelAlpha(SDL_BlitInfo *info) { int width = info->dst_w; int height = info->dst_h; @@ -1311,11 +1398,11 @@ BlitNtoNPixelAlpha(SDL_BlitInfo * info) dstbpp = dstfmt->BytesPerPixel; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP4( { DISEMBLE_RGBA(src, srcbpp, srcfmt, Pixel, sR, sG, sB, sA); - if(sA) { + if (sA) { DISEMBLE_RGBA(dst, dstbpp, dstfmt, Pixel, dR, dG, dB, dA); ALPHA_BLEND_RGBA(sR, sG, sB, sA, dR, dG, dB, dA); ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA); @@ -1324,15 +1411,13 @@ BlitNtoNPixelAlpha(SDL_BlitInfo * info) dst += dstbpp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } } - -SDL_BlitFunc -SDL_CalculateBlitA(SDL_Surface * surface) +SDL_BlitFunc SDL_CalculateBlitA(SDL_Surface *surface) { SDL_PixelFormat *sf = surface->format; SDL_PixelFormat *df = surface->map->dst->format; @@ -1342,7 +1427,7 @@ SDL_CalculateBlitA(SDL_Surface * surface) /* Per-pixel alpha blits */ switch (df->BytesPerPixel) { case 1: - if (df->palette != NULL) { + if (df->palette) { return BlitNto1PixelAlpha; } else { /* RGB332 has no palette ! */ @@ -1350,63 +1435,62 @@ SDL_CalculateBlitA(SDL_Surface * surface) } case 2: -#if SDL_ARM_NEON_BLITTERS || SDL_ARM_SIMD_BLITTERS - if (sf->BytesPerPixel == 4 && sf->Amask == 0xff000000 - && sf->Gmask == 0xff00 && df->Gmask == 0x7e0 - && ((sf->Rmask == 0xff && df->Rmask == 0x1f) - || (sf->Bmask == 0xff && df->Bmask == 0x1f))) - { -#if SDL_ARM_NEON_BLITTERS - if (SDL_HasNEON()) - return BlitARGBto565PixelAlphaARMNEON; -#endif -#if SDL_ARM_SIMD_BLITTERS - if (SDL_HasARMSIMD()) - return BlitARGBto565PixelAlphaARMSIMD; -#endif +#if defined(SDL_ARM_NEON_BLITTERS) || defined(SDL_ARM_SIMD_BLITTERS) + if (sf->BytesPerPixel == 4 && sf->Amask == 0xff000000 && sf->Gmask == 0xff00 && df->Gmask == 0x7e0 && ((sf->Rmask == 0xff && df->Rmask == 0x1f) || (sf->Bmask == 0xff && df->Bmask == 0x1f))) { +#ifdef SDL_ARM_NEON_BLITTERS + if (SDL_HasNEON()) { + return BlitARGBto565PixelAlphaARMNEON; } #endif - if (sf->BytesPerPixel == 4 && sf->Amask == 0xff000000 - && sf->Gmask == 0xff00 - && ((sf->Rmask == 0xff && df->Rmask == 0x1f) - || (sf->Bmask == 0xff && df->Bmask == 0x1f))) { - if (df->Gmask == 0x7e0) +#ifdef SDL_ARM_SIMD_BLITTERS + if (SDL_HasARMSIMD()) { + return BlitARGBto565PixelAlphaARMSIMD; + } +#endif + } +#endif + if (sf->BytesPerPixel == 4 && sf->Amask == 0xff000000 && sf->Gmask == 0xff00 && ((sf->Rmask == 0xff && df->Rmask == 0x1f) || (sf->Bmask == 0xff && df->Bmask == 0x1f))) { + if (df->Gmask == 0x7e0) { return BlitARGBto565PixelAlpha; - else if (df->Gmask == 0x3e0) + } else if (df->Gmask == 0x3e0) { return BlitARGBto555PixelAlpha; + } } return BlitNtoNPixelAlpha; case 4: - if (sf->Rmask == df->Rmask - && sf->Gmask == df->Gmask - && sf->Bmask == df->Bmask && sf->BytesPerPixel == 4) { + if (sf->Rmask == df->Rmask && sf->Gmask == df->Gmask && sf->Bmask == df->Bmask && sf->BytesPerPixel == 4) { #if defined(__MMX__) || defined(__3dNOW__) - if (sf->Rshift % 8 == 0 - && sf->Gshift % 8 == 0 - && sf->Bshift % 8 == 0 - && sf->Ashift % 8 == 0 && sf->Aloss == 0) { + if (sf->Rshift % 8 == 0 && sf->Gshift % 8 == 0 && sf->Bshift % 8 == 0 && sf->Ashift % 8 == 0 && sf->Aloss == 0) { #ifdef __3dNOW__ - if (SDL_Has3DNow()) + if (SDL_Has3DNow()) { return BlitRGBtoRGBPixelAlphaMMX3DNOW; + } #endif #ifdef __MMX__ - if (SDL_HasMMX()) + if (SDL_HasMMX()) { return BlitRGBtoRGBPixelAlphaMMX; + } #endif } #endif /* __MMX__ || __3dNOW__ */ if (sf->Amask == 0xff000000) { -#if SDL_ARM_NEON_BLITTERS - if (SDL_HasNEON()) +#ifdef SDL_ARM_NEON_BLITTERS + if (SDL_HasNEON()) { return BlitRGBtoRGBPixelAlphaARMNEON; + } #endif -#if SDL_ARM_SIMD_BLITTERS - if (SDL_HasARMSIMD()) +#ifdef SDL_ARM_SIMD_BLITTERS + if (SDL_HasARMSIMD()) { return BlitRGBtoRGBPixelAlphaARMSIMD; + } #endif return BlitRGBtoRGBPixelAlpha; } + } else if (sf->Rmask == df->Bmask && sf->Gmask == df->Gmask && sf->Bmask == df->Rmask && sf->BytesPerPixel == 4) { + if (sf->Amask == 0xff000000) { + return BlitRGBtoBGRPixelAlpha; + } } return BlitNtoNPixelAlpha; @@ -1421,7 +1505,7 @@ SDL_CalculateBlitA(SDL_Surface * surface) /* Per-surface alpha blits */ switch (df->BytesPerPixel) { case 1: - if (df->palette != NULL) { + if (df->palette) { return BlitNto1SurfaceAlpha; } else { /* RGB332 has no palette ! */ @@ -1432,31 +1516,32 @@ SDL_CalculateBlitA(SDL_Surface * surface) if (surface->map->identity) { if (df->Gmask == 0x7e0) { #ifdef __MMX__ - if (SDL_HasMMX()) + if (SDL_HasMMX()) { return Blit565to565SurfaceAlphaMMX; - else + } else #endif + { return Blit565to565SurfaceAlpha; + } } else if (df->Gmask == 0x3e0) { #ifdef __MMX__ - if (SDL_HasMMX()) + if (SDL_HasMMX()) { return Blit555to555SurfaceAlphaMMX; - else + } else #endif + { return Blit555to555SurfaceAlpha; + } } } return BlitNtoNSurfaceAlpha; case 4: - if (sf->Rmask == df->Rmask - && sf->Gmask == df->Gmask - && sf->Bmask == df->Bmask && sf->BytesPerPixel == 4) { + if (sf->Rmask == df->Rmask && sf->Gmask == df->Gmask && sf->Bmask == df->Bmask && sf->BytesPerPixel == 4) { #ifdef __MMX__ - if (sf->Rshift % 8 == 0 - && sf->Gshift % 8 == 0 - && sf->Bshift % 8 == 0 && SDL_HasMMX()) + if (sf->Rshift % 8 == 0 && sf->Gshift % 8 == 0 && sf->Bshift % 8 == 0 && SDL_HasMMX()) { return BlitRGBtoRGBSurfaceAlphaMMX; + } #endif if ((sf->Rmask | sf->Gmask | sf->Bmask) == 0xffffff) { return BlitRGBtoRGBSurfaceAlpha; @@ -1475,7 +1560,7 @@ SDL_CalculateBlitA(SDL_Surface * surface) if (sf->Amask == 0) { if (df->BytesPerPixel == 1) { - if (df->palette != NULL) { + if (df->palette) { return BlitNto1SurfaceAlphaKey; } else { /* RGB332 has no palette ! */ diff --git a/SDL2-2.0.12/src/video/SDL_blit_N.c b/SDL2-2.30.5/src/video/SDL_blit_N.c similarity index 75% rename from SDL2-2.0.12/src/video/SDL_blit_N.c rename to SDL2-2.30.5/src/video/SDL_blit_N.c index 39c08f6..123d0aa 100644 --- a/SDL2-2.0.12/src/video/SDL_blit_N.c +++ b/SDL2-2.30.5/src/video/SDL_blit_N.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,51 +26,49 @@ #include "SDL_endian.h" #include "SDL_cpuinfo.h" #include "SDL_blit.h" - -#include "SDL_assert.h" +#include "SDL_blit_copy.h" /* General optimized routines that write char by char */ #define HAVE_FAST_WRITE_INT8 1 /* On some CPU, it's slower than combining and write a word */ -#if defined(__MIPS__) -# undef HAVE_FAST_WRITE_INT8 -# define HAVE_FAST_WRITE_INT8 0 +#if defined(__MIPS__) +#undef HAVE_FAST_WRITE_INT8 +#define HAVE_FAST_WRITE_INT8 0 #endif /* Functions to blit from N-bit surfaces to other surfaces */ -enum blit_features { - BLIT_FEATURE_NONE = 0, - BLIT_FEATURE_HAS_MMX = 1, - BLIT_FEATURE_HAS_ALTIVEC = 2, - BLIT_FEATURE_ALTIVEC_DONT_USE_PREFETCH = 4, - BLIT_FEATURE_HAS_ARM_SIMD = 8 +enum blit_features +{ + BLIT_FEATURE_NONE = 0, + BLIT_FEATURE_HAS_MMX = 1, + BLIT_FEATURE_HAS_ALTIVEC = 2, + BLIT_FEATURE_ALTIVEC_DONT_USE_PREFETCH = 4, + BLIT_FEATURE_HAS_ARM_SIMD = 8 }; -#if SDL_ALTIVEC_BLITTERS +#ifdef SDL_ALTIVEC_BLITTERS #ifdef HAVE_ALTIVEC_H #include #endif #ifdef __MACOSX__ #include -static size_t -GetL3CacheSize(void) +static size_t GetL3CacheSize(void) { const char key[] = "hw.l3cachesize"; u_int64_t result = 0; size_t typeSize = sizeof(result); - int err = sysctlbyname(key, &result, &typeSize, NULL, 0); - if (0 != err) + if (0 != err) { return 0; + } return result; } #else -static size_t -GetL3CacheSize(void) +static size_t GetL3CacheSize(void) { /* XXX: Just guess G4 */ return 2097152; @@ -83,24 +81,29 @@ GetL3CacheSize(void) #define VECUINT16_LITERAL(a,b,c,d,e,f,g,h) \ (vector unsigned short) ( a,b,c,d,e,f,g,h ) #else -#define VECUINT8_LITERAL(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) \ - (vector unsigned char) { a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p } -#define VECUINT16_LITERAL(a,b,c,d,e,f,g,h) \ - (vector unsigned short) { a,b,c,d,e,f,g,h } +#define VECUINT8_LITERAL(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) \ + (vector unsigned char) \ + { \ + a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p \ + } +#define VECUINT16_LITERAL(a, b, c, d, e, f, g, h) \ + (vector unsigned short) \ + { \ + a, b, c, d, e, f, g, h \ + } #endif -#define UNALIGNED_PTR(x) (((size_t) x) & 0x0000000F) -#define VSWIZZLE32(a,b,c,d) (vector unsigned char) \ - ( 0x00+a, 0x00+b, 0x00+c, 0x00+d, \ - 0x04+a, 0x04+b, 0x04+c, 0x04+d, \ - 0x08+a, 0x08+b, 0x08+c, 0x08+d, \ - 0x0C+a, 0x0C+b, 0x0C+c, 0x0C+d ) +#define UNALIGNED_PTR(x) (((size_t)x) & 0x0000000F) +#define VSWIZZLE32(a, b, c, d) (vector unsigned char)(0x00 + a, 0x00 + b, 0x00 + c, 0x00 + d, \ + 0x04 + a, 0x04 + b, 0x04 + c, 0x04 + d, \ + 0x08 + a, 0x08 + b, 0x08 + c, 0x08 + d, \ + 0x0C + a, 0x0C + b, 0x0C + c, 0x0C + d) -#define MAKE8888(dstfmt, r, g, b, a) \ - ( ((r<Rshift)&dstfmt->Rmask) | \ - ((g<Gshift)&dstfmt->Gmask) | \ - ((b<Bshift)&dstfmt->Bmask) | \ - ((a<Ashift)&dstfmt->Amask) ) +#define MAKE8888(dstfmt, r, g, b, a) \ + (((r << dstfmt->Rshift) & dstfmt->Rmask) | \ + ((g << dstfmt->Gshift) & dstfmt->Gmask) | \ + ((b << dstfmt->Bshift) & dstfmt->Bmask) | \ + ((a << dstfmt->Ashift) & dstfmt->Amask)) /* * Data Stream Touch...Altivec cache prefetching. @@ -108,20 +111,19 @@ GetL3CacheSize(void) * Don't use this on a G5...however, the speed boost is very significant * on a G4. */ -#define DST_CHAN_SRC 1 +#define DST_CHAN_SRC 1 #define DST_CHAN_DEST 2 /* macro to set DST control word value... */ #define DST_CTRL(size, count, stride) \ (((size) << 24) | ((count) << 16) | (stride)) -#define VEC_ALIGNER(src) ((UNALIGNED_PTR(src)) \ - ? vec_lvsl(0, src) \ - : vec_add(vec_lvsl(8, src), vec_splat_u8(8))) +#define VEC_ALIGNER(src) ((UNALIGNED_PTR(src)) \ + ? vec_lvsl(0, src) \ + : vec_add(vec_lvsl(8, src), vec_splat_u8(8))) /* Calculate the permute vector used for 32->32 swizzling */ -static vector unsigned char -calc_swizzle32(const SDL_PixelFormat * srcfmt, const SDL_PixelFormat * dstfmt) +static vector unsigned char calc_swizzle32(const SDL_PixelFormat *srcfmt, const SDL_PixelFormat *dstfmt) { /* * We have to assume that the bits that aren't used by other @@ -129,13 +131,8 @@ calc_swizzle32(const SDL_PixelFormat * srcfmt, const SDL_PixelFormat * dstfmt) * leave alpha with a zero mask, but we should still swizzle the bits. */ /* ARGB */ - const static const struct SDL_PixelFormat default_pixel_format = { - 0, NULL, 0, 0, - {0, 0}, - 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000, - 0, 0, 0, 0, - 16, 8, 0, 24, - 0, NULL + static const struct SDL_PixelFormat default_pixel_format = { + 0, NULL, 0, 0, { 0, 0 }, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000, 0, 0, 0, 0, 16, 8, 0, 24, 0, NULL }; const vector unsigned char plus = VECUINT8_LITERAL(0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, @@ -161,8 +158,7 @@ calc_swizzle32(const SDL_PixelFormat * srcfmt, const SDL_PixelFormat * dstfmt) /* Use zero for alpha if either surface doesn't have alpha */ if (dstfmt->Amask) { amask = - ((srcfmt->Amask) ? RESHIFT(srcfmt-> - Ashift) : 0x10) << (dstfmt->Ashift); + ((srcfmt->Amask) ? RESHIFT(srcfmt->Ashift) : 0x10) << (dstfmt->Ashift); } else { amask = 0x10101010 & ((dstfmt->Rmask | dstfmt->Gmask | dstfmt->Bmask) ^ @@ -170,19 +166,19 @@ calc_swizzle32(const SDL_PixelFormat * srcfmt, const SDL_PixelFormat * dstfmt) } #undef RESHIFT - ((unsigned int *) (char *) &srcvec)[0] = (rmask | gmask | bmask | amask); - vswiz = vec_add(plus, (vector unsigned char) vec_splat(srcvec, 0)); + ((unsigned int *)(char *)&srcvec)[0] = (rmask | gmask | bmask | amask); + vswiz = vec_add(plus, (vector unsigned char)vec_splat(srcvec, 0)); return (vswiz); } -#if defined(__powerpc__) && (SDL_BYTEORDER == SDL_LIL_ENDIAN) +#if SDL_BYTEORDER == SDL_LIL_ENDIAN /* reorder bytes for PowerPC little endian */ static vector unsigned char reorder_ppc64le_vec(vector unsigned char vpermute) { /* The result vector of calc_swizzle32 reorder bytes using vec_perm. The LE transformation for vec_perm has an implicit assumption that the permutation is being used to reorder vector elements, - not to reorder bytes within those elements. + not to reorder bytes within those elements. Unfortunatly the result order is not the expected one for powerpc little endian when the two first vector parameters of vec_perm are not of type 'vector char'. This is because the numbering from the @@ -192,25 +188,24 @@ static vector unsigned char reorder_ppc64le_vec(vector unsigned char vpermute) */ const vector unsigned char ppc64le_reorder = VECUINT8_LITERAL( - 0x01, 0x00, 0x03, 0x02, - 0x05, 0x04, 0x07, 0x06, - 0x09, 0x08, 0x0B, 0x0A, - 0x0D, 0x0C, 0x0F, 0x0E ); + 0x01, 0x00, 0x03, 0x02, + 0x05, 0x04, 0x07, 0x06, + 0x09, 0x08, 0x0B, 0x0A, + 0x0D, 0x0C, 0x0F, 0x0E); vector unsigned char vswiz_ppc64le; vswiz_ppc64le = vec_perm(vpermute, vpermute, ppc64le_reorder); - return(vswiz_ppc64le); + return (vswiz_ppc64le); } #endif -static void Blit_RGB888_RGB565(SDL_BlitInfo * info); -static void -Blit_RGB888_RGB565Altivec(SDL_BlitInfo * info) +static void Blit_RGB888_RGB565(SDL_BlitInfo *info); +static void Blit_RGB888_RGB565Altivec(SDL_BlitInfo *info) { int height = info->dst_h; - Uint8 *src = (Uint8 *) info->src; + Uint8 *src = (Uint8 *)info->src; int srcskip = info->src_skip; - Uint8 *dst = (Uint8 *) info->dst; + Uint8 *dst = (Uint8 *)info->dst; int dstskip = info->dst_skip; SDL_PixelFormat *srcfmt = info->src_fmt; vector unsigned char valpha = vec_splat_u8(0); @@ -227,7 +222,7 @@ Blit_RGB888_RGB565Altivec(SDL_BlitInfo * info) vector unsigned short vfc = VECUINT16_LITERAL(0x00fc, 0x00fc, 0x00fc, 0x00fc, 0x00fc, 0x00fc, 0x00fc, 0x00fc); - vector unsigned short vf800 = (vector unsigned short) vec_splat_u8(-7); + vector unsigned short vf800 = (vector unsigned short)vec_splat_u8(-7); vf800 = vec_sl(vf800, vec_splat_u16(8)); while (height--) { @@ -239,24 +234,24 @@ Blit_RGB888_RGB565Altivec(SDL_BlitInfo * info) int extrawidth; /* do scalar until we can align... */ -#define ONE_PIXEL_BLEND(condition, widthvar) \ - while (condition) { \ - Uint32 Pixel; \ - unsigned sR, sG, sB, sA; \ - DISEMBLE_RGBA((Uint8 *)src, 4, srcfmt, Pixel, \ - sR, sG, sB, sA); \ - *(Uint16 *)(dst) = (((sR << 8) & 0x0000F800) | \ - ((sG << 3) & 0x000007E0) | \ - ((sB >> 3) & 0x0000001F)); \ - dst += 2; \ - src += 4; \ - widthvar--; \ - } +#define ONE_PIXEL_BLEND(condition, widthvar) \ + while (condition) { \ + Uint32 Pixel; \ + unsigned sR, sG, sB, sA; \ + DISEMBLE_RGBA((Uint8 *)src, 4, srcfmt, Pixel, \ + sR, sG, sB, sA); \ + *(Uint16 *)(dst) = (((sR << 8) & 0x0000F800) | \ + ((sG << 3) & 0x000007E0) | \ + ((sB >> 3) & 0x0000001F)); \ + dst += 2; \ + src += 4; \ + widthvar--; \ + } ONE_PIXEL_BLEND(((UNALIGNED_PTR(dst)) && (width)), width); /* After all that work, here's the vector part! */ - extrawidth = (width % 8); /* trailing unaligned stores */ + extrawidth = (width % 8); /* trailing unaligned stores */ width -= extrawidth; vsrc = vec_ld(0, src); valigner = VEC_ALIGNER(src); @@ -268,25 +263,25 @@ Blit_RGB888_RGB565Altivec(SDL_BlitInfo * info) voverflow = vec_ld(15, src); vsrc = vec_perm(vsrc, voverflow, valigner); - vsrc1 = (vector unsigned int) vec_perm(vsrc, valpha, vpermute); + vsrc1 = (vector unsigned int)vec_perm(vsrc, valpha, vpermute); src += 16; vsrc = voverflow; voverflow = vec_ld(15, src); vsrc = vec_perm(vsrc, voverflow, valigner); - vsrc2 = (vector unsigned int) vec_perm(vsrc, valpha, vpermute); + vsrc2 = (vector unsigned int)vec_perm(vsrc, valpha, vpermute); /* 1555 */ - vpixel = (vector unsigned short) vec_packpx(vsrc1, vsrc2); - vgpixel = (vector unsigned short) vec_perm(vsrc1, vsrc2, vgmerge); + vpixel = (vector unsigned short)vec_packpx(vsrc1, vsrc2); + vgpixel = (vector unsigned short)vec_perm(vsrc1, vsrc2, vgmerge); vgpixel = vec_and(vgpixel, vfc); vgpixel = vec_sl(vgpixel, v3); vrpixel = vec_sl(vpixel, v1); vrpixel = vec_and(vrpixel, vf800); vbpixel = vec_and(vpixel, v3f); vdst = - vec_or((vector unsigned char) vrpixel, - (vector unsigned char) vgpixel); + vec_or((vector unsigned char)vrpixel, + (vector unsigned char)vgpixel); /* 565 */ - vdst = vec_or(vdst, (vector unsigned char) vbpixel); + vdst = vec_or(vdst, (vector unsigned char)vbpixel); vec_st(vdst, 0, dst); width -= 8; @@ -301,20 +296,17 @@ Blit_RGB888_RGB565Altivec(SDL_BlitInfo * info) ONE_PIXEL_BLEND((extrawidth), extrawidth); #undef ONE_PIXEL_BLEND - src += srcskip; /* move to next row, accounting for pitch. */ + src += srcskip; /* move to next row, accounting for pitch. */ dst += dstskip; } - - } -static void -Blit_RGB565_32Altivec(SDL_BlitInfo * info) +static void Blit_RGB565_32Altivec(SDL_BlitInfo *info) { int height = info->dst_h; - Uint8 *src = (Uint8 *) info->src; + Uint8 *src = (Uint8 *)info->src; int srcskip = info->src_skip; - Uint8 *dst = (Uint8 *) info->dst; + Uint8 *dst = (Uint8 *)info->dst; int dstskip = info->dst_skip; SDL_PixelFormat *srcfmt = info->src_fmt; SDL_PixelFormat *dstfmt = info->dst_fmt; @@ -337,9 +329,7 @@ Blit_RGB565_32Altivec(SDL_BlitInfo * info) 0x10, 0x06, 0x01, 0x01); vector unsigned char vredalpha2 = - (vector unsigned - char) (vec_add((vector unsigned int) vredalpha1, vec_sl(v8, v16)) - ); + (vector unsigned char)(vec_add((vector unsigned int)vredalpha1, vec_sl(v8, v16))); /* 0x00 - 0x0f is ARxx ARxx ARxx ARxx 0x11 - 0x0f odds are blue @@ -349,8 +339,7 @@ Blit_RGB565_32Altivec(SDL_BlitInfo * info) 0x08, 0x09, 0x0a, 0x15, 0x0c, 0x0d, 0x0e, 0x17); vector unsigned char vblue2 = - (vector unsigned char) (vec_add((vector unsigned int) vblue1, v8) - ); + (vector unsigned char)(vec_add((vector unsigned int)vblue1, v8)); /* 0x00 - 0x0f is ARxB ARxB ARxB ARxB 0x10 - 0x0e evens are green @@ -360,18 +349,16 @@ Blit_RGB565_32Altivec(SDL_BlitInfo * info) 0x08, 0x09, 0x14, 0x0b, 0x0c, 0x0d, 0x16, 0x0f); vector unsigned char vgreen2 = - (vector unsigned - char) (vec_add((vector unsigned int) vgreen1, vec_sl(v8, v8)) - ); + (vector unsigned char)(vec_add((vector unsigned int)vgreen1, vec_sl(v8, v8))); SDL_assert(srcfmt->BytesPerPixel == 2); SDL_assert(dstfmt->BytesPerPixel == 4); - vf800 = (vector unsigned short) vec_splat_u8(-7); + vf800 = (vector unsigned short)vec_splat_u8(-7); vf800 = vec_sl(vf800, vec_splat_u16(8)); if (dstfmt->Amask && info->a) { - ((unsigned char *) &valpha)[0] = alpha = info->a; + ((unsigned char *)&valpha)[0] = alpha = info->a; valpha = vec_splat(valpha, 0); } else { alpha = 0; @@ -388,22 +375,22 @@ Blit_RGB565_32Altivec(SDL_BlitInfo * info) int extrawidth; /* do scalar until we can align... */ -#define ONE_PIXEL_BLEND(condition, widthvar) \ - while (condition) { \ - unsigned sR, sG, sB; \ - unsigned short Pixel = *((unsigned short *)src); \ - sR = (Pixel >> 8) & 0xf8; \ - sG = (Pixel >> 3) & 0xfc; \ - sB = (Pixel << 3) & 0xf8; \ - ASSEMBLE_RGBA(dst, 4, dstfmt, sR, sG, sB, alpha); \ - src += 2; \ - dst += 4; \ - widthvar--; \ - } +#define ONE_PIXEL_BLEND(condition, widthvar) \ + while (condition) { \ + unsigned sR, sG, sB; \ + unsigned short Pixel = *((unsigned short *)src); \ + sR = (Pixel >> 8) & 0xf8; \ + sG = (Pixel >> 3) & 0xfc; \ + sB = (Pixel << 3) & 0xf8; \ + ASSEMBLE_RGBA(dst, 4, dstfmt, sR, sG, sB, alpha); \ + src += 2; \ + dst += 4; \ + widthvar--; \ + } ONE_PIXEL_BLEND(((UNALIGNED_PTR(dst)) && (width)), width); /* After all that work, here's the vector part! */ - extrawidth = (width % 8); /* trailing unaligned stores */ + extrawidth = (width % 8); /* trailing unaligned stores */ width -= extrawidth; vsrc = vec_ld(0, src); valigner = VEC_ALIGNER(src); @@ -415,23 +402,23 @@ Blit_RGB565_32Altivec(SDL_BlitInfo * info) voverflow = vec_ld(15, src); vsrc = vec_perm(vsrc, voverflow, valigner); - vR = vec_and((vector unsigned short) vsrc, vf800); - vB = vec_sl((vector unsigned short) vsrc, v3); + vR = vec_and((vector unsigned short)vsrc, vf800); + vB = vec_sl((vector unsigned short)vsrc, v3); vG = vec_sl(vB, v2); vdst1 = - (vector unsigned char) vec_perm((vector unsigned char) vR, - valpha, vredalpha1); - vdst1 = vec_perm(vdst1, (vector unsigned char) vB, vblue1); - vdst1 = vec_perm(vdst1, (vector unsigned char) vG, vgreen1); + (vector unsigned char)vec_perm((vector unsigned char)vR, + valpha, vredalpha1); + vdst1 = vec_perm(vdst1, (vector unsigned char)vB, vblue1); + vdst1 = vec_perm(vdst1, (vector unsigned char)vG, vgreen1); vdst1 = vec_perm(vdst1, valpha, vpermute); vec_st(vdst1, 0, dst); vdst2 = - (vector unsigned char) vec_perm((vector unsigned char) vR, - valpha, vredalpha2); - vdst2 = vec_perm(vdst2, (vector unsigned char) vB, vblue2); - vdst2 = vec_perm(vdst2, (vector unsigned char) vG, vgreen2); + (vector unsigned char)vec_perm((vector unsigned char)vR, + valpha, vredalpha2); + vdst2 = vec_perm(vdst2, (vector unsigned char)vB, vblue2); + vdst2 = vec_perm(vdst2, (vector unsigned char)vG, vgreen2); vdst2 = vec_perm(vdst2, valpha, vpermute); vec_st(vdst2, 16, dst); @@ -443,25 +430,21 @@ Blit_RGB565_32Altivec(SDL_BlitInfo * info) SDL_assert(width == 0); - /* do scalar until we can align... */ ONE_PIXEL_BLEND((extrawidth), extrawidth); #undef ONE_PIXEL_BLEND - src += srcskip; /* move to next row, accounting for pitch. */ + src += srcskip; /* move to next row, accounting for pitch. */ dst += dstskip; } - } - -static void -Blit_RGB555_32Altivec(SDL_BlitInfo * info) +static void Blit_RGB555_32Altivec(SDL_BlitInfo *info) { int height = info->dst_h; - Uint8 *src = (Uint8 *) info->src; + Uint8 *src = (Uint8 *)info->src; int srcskip = info->src_skip; - Uint8 *dst = (Uint8 *) info->dst; + Uint8 *dst = (Uint8 *)info->dst; int dstskip = info->dst_skip; SDL_PixelFormat *srcfmt = info->src_fmt; SDL_PixelFormat *dstfmt = info->dst_fmt; @@ -484,9 +467,7 @@ Blit_RGB555_32Altivec(SDL_BlitInfo * info) 0x10, 0x06, 0x01, 0x01); vector unsigned char vredalpha2 = - (vector unsigned - char) (vec_add((vector unsigned int) vredalpha1, vec_sl(v8, v16)) - ); + (vector unsigned char)(vec_add((vector unsigned int)vredalpha1, vec_sl(v8, v16))); /* 0x00 - 0x0f is ARxx ARxx ARxx ARxx 0x11 - 0x0f odds are blue @@ -496,8 +477,7 @@ Blit_RGB555_32Altivec(SDL_BlitInfo * info) 0x08, 0x09, 0x0a, 0x15, 0x0c, 0x0d, 0x0e, 0x17); vector unsigned char vblue2 = - (vector unsigned char) (vec_add((vector unsigned int) vblue1, v8) - ); + (vector unsigned char)(vec_add((vector unsigned int)vblue1, v8)); /* 0x00 - 0x0f is ARxB ARxB ARxB ARxB 0x10 - 0x0e evens are green @@ -507,18 +487,16 @@ Blit_RGB555_32Altivec(SDL_BlitInfo * info) 0x08, 0x09, 0x14, 0x0b, 0x0c, 0x0d, 0x16, 0x0f); vector unsigned char vgreen2 = - (vector unsigned - char) (vec_add((vector unsigned int) vgreen1, vec_sl(v8, v8)) - ); + (vector unsigned char)(vec_add((vector unsigned int)vgreen1, vec_sl(v8, v8))); SDL_assert(srcfmt->BytesPerPixel == 2); SDL_assert(dstfmt->BytesPerPixel == 4); - vf800 = (vector unsigned short) vec_splat_u8(-7); + vf800 = (vector unsigned short)vec_splat_u8(-7); vf800 = vec_sl(vf800, vec_splat_u16(8)); if (dstfmt->Amask && info->a) { - ((unsigned char *) &valpha)[0] = alpha = info->a; + ((unsigned char *)&valpha)[0] = alpha = info->a; valpha = vec_splat(valpha, 0); } else { alpha = 0; @@ -535,22 +513,22 @@ Blit_RGB555_32Altivec(SDL_BlitInfo * info) int extrawidth; /* do scalar until we can align... */ -#define ONE_PIXEL_BLEND(condition, widthvar) \ - while (condition) { \ - unsigned sR, sG, sB; \ - unsigned short Pixel = *((unsigned short *)src); \ - sR = (Pixel >> 7) & 0xf8; \ - sG = (Pixel >> 2) & 0xf8; \ - sB = (Pixel << 3) & 0xf8; \ - ASSEMBLE_RGBA(dst, 4, dstfmt, sR, sG, sB, alpha); \ - src += 2; \ - dst += 4; \ - widthvar--; \ - } +#define ONE_PIXEL_BLEND(condition, widthvar) \ + while (condition) { \ + unsigned sR, sG, sB; \ + unsigned short Pixel = *((unsigned short *)src); \ + sR = (Pixel >> 7) & 0xf8; \ + sG = (Pixel >> 2) & 0xf8; \ + sB = (Pixel << 3) & 0xf8; \ + ASSEMBLE_RGBA(dst, 4, dstfmt, sR, sG, sB, alpha); \ + src += 2; \ + dst += 4; \ + widthvar--; \ + } ONE_PIXEL_BLEND(((UNALIGNED_PTR(dst)) && (width)), width); /* After all that work, here's the vector part! */ - extrawidth = (width % 8); /* trailing unaligned stores */ + extrawidth = (width % 8); /* trailing unaligned stores */ width -= extrawidth; vsrc = vec_ld(0, src); valigner = VEC_ALIGNER(src); @@ -562,23 +540,23 @@ Blit_RGB555_32Altivec(SDL_BlitInfo * info) voverflow = vec_ld(15, src); vsrc = vec_perm(vsrc, voverflow, valigner); - vR = vec_and(vec_sl((vector unsigned short) vsrc, v1), vf800); - vB = vec_sl((vector unsigned short) vsrc, v3); + vR = vec_and(vec_sl((vector unsigned short)vsrc, v1), vf800); + vB = vec_sl((vector unsigned short)vsrc, v3); vG = vec_sl(vB, v3); vdst1 = - (vector unsigned char) vec_perm((vector unsigned char) vR, - valpha, vredalpha1); - vdst1 = vec_perm(vdst1, (vector unsigned char) vB, vblue1); - vdst1 = vec_perm(vdst1, (vector unsigned char) vG, vgreen1); + (vector unsigned char)vec_perm((vector unsigned char)vR, + valpha, vredalpha1); + vdst1 = vec_perm(vdst1, (vector unsigned char)vB, vblue1); + vdst1 = vec_perm(vdst1, (vector unsigned char)vG, vgreen1); vdst1 = vec_perm(vdst1, valpha, vpermute); vec_st(vdst1, 0, dst); vdst2 = - (vector unsigned char) vec_perm((vector unsigned char) vR, - valpha, vredalpha2); - vdst2 = vec_perm(vdst2, (vector unsigned char) vB, vblue2); - vdst2 = vec_perm(vdst2, (vector unsigned char) vG, vgreen2); + (vector unsigned char)vec_perm((vector unsigned char)vR, + valpha, vredalpha2); + vdst2 = vec_perm(vdst2, (vector unsigned char)vB, vblue2); + vdst2 = vec_perm(vdst2, (vector unsigned char)vG, vgreen2); vdst2 = vec_perm(vdst2, valpha, vpermute); vec_st(vdst2, 16, dst); @@ -590,26 +568,23 @@ Blit_RGB555_32Altivec(SDL_BlitInfo * info) SDL_assert(width == 0); - /* do scalar until we can align... */ ONE_PIXEL_BLEND((extrawidth), extrawidth); #undef ONE_PIXEL_BLEND - src += srcskip; /* move to next row, accounting for pitch. */ + src += srcskip; /* move to next row, accounting for pitch. */ dst += dstskip; } - } -static void BlitNtoNKey(SDL_BlitInfo * info); -static void BlitNtoNKeyCopyAlpha(SDL_BlitInfo * info); -static void -Blit32to32KeyAltivec(SDL_BlitInfo * info) +static void BlitNtoNKey(SDL_BlitInfo *info); +static void BlitNtoNKeyCopyAlpha(SDL_BlitInfo *info); +static void Blit32to32KeyAltivec(SDL_BlitInfo *info) { int height = info->dst_h; - Uint32 *srcp = (Uint32 *) info->src; + Uint32 *srcp = (Uint32 *)info->src; int srcskip = info->src_skip / 4; - Uint32 *dstp = (Uint32 *) info->dst; + Uint32 *dstp = (Uint32 *)info->dst; int dstskip = info->dst_skip / 4; SDL_PixelFormat *srcfmt = info->src_fmt; int srcbpp = srcfmt->BytesPerPixel; @@ -635,49 +610,54 @@ Blit32to32KeyAltivec(SDL_BlitInfo * info) } vzero = vec_splat_u8(0); if (alpha) { - ((unsigned char *) &valpha)[0] = (unsigned char) alpha; + ((unsigned char *)&valpha)[0] = (unsigned char)alpha; valpha = - (vector unsigned int) vec_splat((vector unsigned char) valpha, 0); + (vector unsigned int)vec_splat((vector unsigned char)valpha, 0); } else { - valpha = (vector unsigned int) vzero; + valpha = (vector unsigned int)vzero; } ckey &= rgbmask; - ((unsigned int *) (char *) &vckey)[0] = ckey; + ((unsigned int *)(char *)&vckey)[0] = ckey; vckey = vec_splat(vckey, 0); - ((unsigned int *) (char *) &vrgbmask)[0] = rgbmask; + ((unsigned int *)(char *)&vrgbmask)[0] = rgbmask; vrgbmask = vec_splat(vrgbmask, 0); +#if SDL_BYTEORDER == SDL_LIL_ENDIAN + /* reorder bytes for PowerPC little endian */ + vpermute = reorder_ppc64le_vec(vpermute); +#endif + while (height--) { -#define ONE_PIXEL_BLEND(condition, widthvar) \ - if (copy_alpha) { \ - while (condition) { \ - Uint32 Pixel; \ - unsigned sR, sG, sB, sA; \ - DISEMBLE_RGBA((Uint8 *)srcp, srcbpp, srcfmt, Pixel, \ - sR, sG, sB, sA); \ - if ( (Pixel & rgbmask) != ckey ) { \ - ASSEMBLE_RGBA((Uint8 *)dstp, dstbpp, dstfmt, \ - sR, sG, sB, sA); \ - } \ - dstp = (Uint32 *) (((Uint8 *) dstp) + dstbpp); \ - srcp = (Uint32 *) (((Uint8 *) srcp) + srcbpp); \ - widthvar--; \ - } \ - } else { \ - while (condition) { \ - Uint32 Pixel; \ - unsigned sR, sG, sB; \ - RETRIEVE_RGB_PIXEL((Uint8 *)srcp, srcbpp, Pixel); \ - if ( Pixel != ckey ) { \ - RGB_FROM_PIXEL(Pixel, srcfmt, sR, sG, sB); \ - ASSEMBLE_RGBA((Uint8 *)dstp, dstbpp, dstfmt, \ - sR, sG, sB, alpha); \ - } \ - dstp = (Uint32 *) (((Uint8 *)dstp) + dstbpp); \ - srcp = (Uint32 *) (((Uint8 *)srcp) + srcbpp); \ - widthvar--; \ - } \ - } +#define ONE_PIXEL_BLEND(condition, widthvar) \ + if (copy_alpha) { \ + while (condition) { \ + Uint32 Pixel; \ + unsigned sR, sG, sB, sA; \ + DISEMBLE_RGBA((Uint8 *)srcp, srcbpp, srcfmt, Pixel, \ + sR, sG, sB, sA); \ + if ((Pixel & rgbmask) != ckey) { \ + ASSEMBLE_RGBA((Uint8 *)dstp, dstbpp, dstfmt, \ + sR, sG, sB, sA); \ + } \ + dstp = (Uint32 *)(((Uint8 *)dstp) + dstbpp); \ + srcp = (Uint32 *)(((Uint8 *)srcp) + srcbpp); \ + widthvar--; \ + } \ + } else { \ + while (condition) { \ + Uint32 Pixel; \ + unsigned sR, sG, sB; \ + RETRIEVE_RGB_PIXEL((Uint8 *)srcp, srcbpp, Pixel); \ + if (Pixel != ckey) { \ + RGB_FROM_PIXEL(Pixel, srcfmt, sR, sG, sB); \ + ASSEMBLE_RGBA((Uint8 *)dstp, dstbpp, dstfmt, \ + sR, sG, sB, alpha); \ + } \ + dstp = (Uint32 *)(((Uint8 *)dstp) + dstbpp); \ + srcp = (Uint32 *)(((Uint8 *)srcp) + srcbpp); \ + widthvar--; \ + } \ + } int width = info->dst_w; ONE_PIXEL_BLEND((UNALIGNED_PTR(dstp)) && (width), width); SDL_assert(width > 0); @@ -694,20 +674,16 @@ Blit32to32KeyAltivec(SDL_BlitInfo * info) /* load the source vec */ vs = vec_perm(vs, voverflow, valigner); /* vsel is set for items that match the key */ - vsel = (vector unsigned char) vec_and(vs, vrgbmask); - vsel = (vector unsigned char) vec_cmpeq(vs, vckey); -#if defined(__powerpc__) && (SDL_BYTEORDER == SDL_LIL_ENDIAN) - /* reorder bytes for PowerPC little endian */ - vpermute = reorder_ppc64le_vec(vpermute); -#endif + vsel = (vector unsigned char)vec_and(vs, vrgbmask); + vsel = (vector unsigned char)vec_cmpeq(vs, vckey); /* permute the src vec to the dest format */ vs = vec_perm(vs, valpha, vpermute); /* load the destination vec */ vd = vec_ld(0, dstp); /* select the source and dest into vs */ - vd = (vector unsigned int) vec_sel((vector unsigned char) vs, - (vector unsigned char) vd, - vsel); + vd = (vector unsigned int)vec_sel((vector unsigned char)vs, + (vector unsigned char)vd, + vsel); vec_st(vd, 0, dstp); srcp += 4; @@ -725,13 +701,12 @@ Blit32to32KeyAltivec(SDL_BlitInfo * info) /* Altivec code to swizzle one 32-bit surface to a different 32-bit format. */ /* Use this on a G5 */ -static void -ConvertAltivec32to32_noprefetch(SDL_BlitInfo * info) +static void ConvertAltivec32to32_noprefetch(SDL_BlitInfo *info) { int height = info->dst_h; - Uint32 *src = (Uint32 *) info->src; + Uint32 *src = (Uint32 *)info->src; int srcskip = info->src_skip / 4; - Uint32 *dst = (Uint32 *) info->dst; + Uint32 *dst = (Uint32 *)info->dst; int dstskip = info->dst_skip / 4; SDL_PixelFormat *srcfmt = info->src_fmt; SDL_PixelFormat *dstfmt = info->dst_fmt; @@ -740,14 +715,19 @@ ConvertAltivec32to32_noprefetch(SDL_BlitInfo * info) if (dstfmt->Amask && !srcfmt->Amask) { if (info->a) { vector unsigned char valpha; - ((unsigned char *) &valpha)[0] = info->a; - vzero = (vector unsigned int) vec_splat(valpha, 0); + ((unsigned char *)&valpha)[0] = info->a; + vzero = (vector unsigned int)vec_splat(valpha, 0); } } SDL_assert(srcfmt->BytesPerPixel == 4); SDL_assert(dstfmt->BytesPerPixel == 4); +#if SDL_BYTEORDER == SDL_LIL_ENDIAN + /* reorder bytes for PowerPC little endian */ + vpermute = reorder_ppc64le_vec(vpermute); +#endif + while (height--) { vector unsigned char valigner; vector unsigned int vbits; @@ -762,8 +742,8 @@ ConvertAltivec32to32_noprefetch(SDL_BlitInfo * info) while ((UNALIGNED_PTR(dst)) && (width)) { bits = *(src++); RGBA_FROM_8888(bits, srcfmt, r, g, b, a); - if(!srcfmt->Amask) - a = info->a; + if (!srcfmt->Amask) + a = info->a; *(dst++) = MAKE8888(dstfmt, r, g, b, a); width--; } @@ -778,13 +758,9 @@ ConvertAltivec32to32_noprefetch(SDL_BlitInfo * info) voverflow = vec_ld(15, src); src += 4; width -= 4; - vbits = vec_perm(vbits, voverflow, valigner); /* src is ready. */ -#if defined(__powerpc__) && (SDL_BYTEORDER == SDL_LIL_ENDIAN) - /* reorder bytes for PowerPC little endian */ - vpermute = reorder_ppc64le_vec(vpermute); -#endif - vbits = vec_perm(vbits, vzero, vpermute); /* swizzle it. */ - vec_st(vbits, 0, dst); /* store it back out. */ + vbits = vec_perm(vbits, voverflow, valigner); /* src is ready. */ + vbits = vec_perm(vbits, vzero, vpermute); /* swizzle it. */ + vec_st(vbits, 0, dst); /* store it back out. */ dst += 4; vbits = voverflow; } @@ -793,10 +769,10 @@ ConvertAltivec32to32_noprefetch(SDL_BlitInfo * info) /* cover pixels at the end of the row that didn't fit in 16 bytes. */ while (extrawidth) { - bits = *(src++); /* max 7 pixels, don't bother with prefetch. */ + bits = *(src++); /* max 7 pixels, don't bother with prefetch. */ RGBA_FROM_8888(bits, srcfmt, r, g, b, a); - if(!srcfmt->Amask) - a = info->a; + if (!srcfmt->Amask) + a = info->a; *(dst++) = MAKE8888(dstfmt, r, g, b, a); extrawidth--; } @@ -804,21 +780,19 @@ ConvertAltivec32to32_noprefetch(SDL_BlitInfo * info) src += srcskip; dst += dstskip; } - } /* Altivec code to swizzle one 32-bit surface to a different 32-bit format. */ /* Use this on a G4 */ -static void -ConvertAltivec32to32_prefetch(SDL_BlitInfo * info) +static void ConvertAltivec32to32_prefetch(SDL_BlitInfo *info) { const int scalar_dst_lead = sizeof(Uint32) * 4; const int vector_dst_lead = sizeof(Uint32) * 16; int height = info->dst_h; - Uint32 *src = (Uint32 *) info->src; + Uint32 *src = (Uint32 *)info->src; int srcskip = info->src_skip / 4; - Uint32 *dst = (Uint32 *) info->dst; + Uint32 *dst = (Uint32 *)info->dst; int dstskip = info->dst_skip / 4; SDL_PixelFormat *srcfmt = info->src_fmt; SDL_PixelFormat *dstfmt = info->dst_fmt; @@ -827,14 +801,19 @@ ConvertAltivec32to32_prefetch(SDL_BlitInfo * info) if (dstfmt->Amask && !srcfmt->Amask) { if (info->a) { vector unsigned char valpha; - ((unsigned char *) &valpha)[0] = info->a; - vzero = (vector unsigned int) vec_splat(valpha, 0); + ((unsigned char *)&valpha)[0] = info->a; + vzero = (vector unsigned int)vec_splat(valpha, 0); } } SDL_assert(srcfmt->BytesPerPixel == 4); SDL_assert(dstfmt->BytesPerPixel == 4); +#if SDL_BYTEORDER == SDL_LIL_ENDIAN + /* reorder bytes for PowerPC little endian */ + vpermute = reorder_ppc64le_vec(vpermute); +#endif + while (height--) { vector unsigned char valigner; vector unsigned int vbits; @@ -853,8 +832,8 @@ ConvertAltivec32to32_prefetch(SDL_BlitInfo * info) DST_CHAN_DEST); bits = *(src++); RGBA_FROM_8888(bits, srcfmt, r, g, b, a); - if(!srcfmt->Amask) - a = info->a; + if (!srcfmt->Amask) + a = info->a; *(dst++) = MAKE8888(dstfmt, r, g, b, a); width--; } @@ -873,13 +852,9 @@ ConvertAltivec32to32_prefetch(SDL_BlitInfo * info) voverflow = vec_ld(15, src); src += 4; width -= 4; - vbits = vec_perm(vbits, voverflow, valigner); /* src is ready. */ -#if defined(__powerpc__) && (SDL_BYTEORDER == SDL_LIL_ENDIAN) - /* reorder bytes for PowerPC little endian */ - vpermute = reorder_ppc64le_vec(vpermute); -#endif - vbits = vec_perm(vbits, vzero, vpermute); /* swizzle it. */ - vec_st(vbits, 0, dst); /* store it back out. */ + vbits = vec_perm(vbits, voverflow, valigner); /* src is ready. */ + vbits = vec_perm(vbits, vzero, vpermute); /* swizzle it. */ + vec_st(vbits, 0, dst); /* store it back out. */ dst += 4; vbits = voverflow; } @@ -888,10 +863,10 @@ ConvertAltivec32to32_prefetch(SDL_BlitInfo * info) /* cover pixels at the end of the row that didn't fit in 16 bytes. */ while (extrawidth) { - bits = *(src++); /* max 7 pixels, don't bother with prefetch. */ + bits = *(src++); /* max 7 pixels, don't bother with prefetch. */ RGBA_FROM_8888(bits, srcfmt, r, g, b, a); - if(!srcfmt->Amask) - a = info->a; + if (!srcfmt->Amask) + a = info->a; *(dst++) = MAKE8888(dstfmt, r, g, b, a); extrawidth--; } @@ -904,33 +879,31 @@ ConvertAltivec32to32_prefetch(SDL_BlitInfo * info) vec_dss(DST_CHAN_DEST); } -static enum blit_features -GetBlitFeatures(void) +static enum blit_features GetBlitFeatures(void) { static enum blit_features features = -1; - if (features == (enum blit_features) -1) { + if (features == (enum blit_features) - 1) { /* Provide an override for testing .. */ char *override = SDL_getenv("SDL_ALTIVEC_BLIT_FEATURES"); if (override) { unsigned int features_as_uint = 0; SDL_sscanf(override, "%u", &features_as_uint); - features = (enum blit_features) features_as_uint; + features = (enum blit_features)features_as_uint; } else { features = (0 /* Feature 1 is has-MMX */ - | ((SDL_HasMMX())? BLIT_FEATURE_HAS_MMX : 0) + | ((SDL_HasMMX()) ? BLIT_FEATURE_HAS_MMX : 0) /* Feature 2 is has-AltiVec */ - | ((SDL_HasAltiVec())? BLIT_FEATURE_HAS_ALTIVEC : 0) + | ((SDL_HasAltiVec()) ? BLIT_FEATURE_HAS_ALTIVEC : 0) /* Feature 4 is dont-use-prefetch */ /* !!!! FIXME: Check for G5 or later, not the cache size! Always prefetch on a G4. */ - | ((GetL3CacheSize() == 0) ? BLIT_FEATURE_ALTIVEC_DONT_USE_PREFETCH : 0) - ); + | ((GetL3CacheSize() == 0) ? BLIT_FEATURE_ALTIVEC_DONT_USE_PREFETCH : 0)); } } return features; } -#if __MWERKS__ +#ifdef __MWERKS__ #pragma altivec_model off #endif #else @@ -938,55 +911,53 @@ GetBlitFeatures(void) #define GetBlitFeatures() ((SDL_HasMMX() ? BLIT_FEATURE_HAS_MMX : 0) | (SDL_HasARMSIMD() ? BLIT_FEATURE_HAS_ARM_SIMD : 0)) #endif -#if SDL_ARM_SIMD_BLITTERS +#ifdef SDL_ARM_SIMD_BLITTERS void Blit_BGR888_RGB888ARMSIMDAsm(int32_t w, int32_t h, uint32_t *dst, int32_t dst_stride, uint32_t *src, int32_t src_stride); -static void -Blit_BGR888_RGB888ARMSIMD(SDL_BlitInfo * info) +static void Blit_BGR888_RGB888ARMSIMD(SDL_BlitInfo *info) { - int32_t width = info->dst_w; - int32_t height = info->dst_h; - uint32_t *dstp = (uint32_t *)info->dst; - int32_t dststride = width + (info->dst_skip >> 2); - uint32_t *srcp = (uint32_t *)info->src; - int32_t srcstride = width + (info->src_skip >> 2); + int32_t width = info->dst_w; + int32_t height = info->dst_h; + uint32_t *dstp = (uint32_t *)info->dst; + int32_t dststride = width + (info->dst_skip >> 2); + uint32_t *srcp = (uint32_t *)info->src; + int32_t srcstride = width + (info->src_skip >> 2); - Blit_BGR888_RGB888ARMSIMDAsm(width, height, dstp, dststride, srcp, srcstride); + Blit_BGR888_RGB888ARMSIMDAsm(width, height, dstp, dststride, srcp, srcstride); } void Blit_RGB444_RGB888ARMSIMDAsm(int32_t w, int32_t h, uint32_t *dst, int32_t dst_stride, uint16_t *src, int32_t src_stride); -static void -Blit_RGB444_RGB888ARMSIMD(SDL_BlitInfo * info) +static void Blit_RGB444_RGB888ARMSIMD(SDL_BlitInfo *info) { - int32_t width = info->dst_w; - int32_t height = info->dst_h; - uint32_t *dstp = (uint32_t *)info->dst; - int32_t dststride = width + (info->dst_skip >> 2); - uint16_t *srcp = (uint16_t *)info->src; - int32_t srcstride = width + (info->src_skip >> 1); + int32_t width = info->dst_w; + int32_t height = info->dst_h; + uint32_t *dstp = (uint32_t *)info->dst; + int32_t dststride = width + (info->dst_skip >> 2); + uint16_t *srcp = (uint16_t *)info->src; + int32_t srcstride = width + (info->src_skip >> 1); - Blit_RGB444_RGB888ARMSIMDAsm(width, height, dstp, dststride, srcp, srcstride); + Blit_RGB444_RGB888ARMSIMDAsm(width, height, dstp, dststride, srcp, srcstride); } #endif /* This is now endian dependent */ #if SDL_BYTEORDER == SDL_LIL_ENDIAN -#define HI 1 -#define LO 0 +#define HI 1 +#define LO 0 #else /* SDL_BYTEORDER == SDL_BIG_ENDIAN */ -#define HI 0 -#define LO 1 +#define HI 0 +#define LO 1 #endif /* Special optimized blit for RGB 8-8-8 --> RGB 3-3-2 */ -#define RGB888_RGB332(dst, src) { \ - dst = (Uint8)((((src)&0x00E00000)>>16)| \ - (((src)&0x0000E000)>>11)| \ - (((src)&0x000000C0)>>6)); \ -} -static void -Blit_RGB888_index8(SDL_BlitInfo * info) +#define RGB888_RGB332(dst, src) \ + { \ + dst = (Uint8)((((src)&0x00E00000) >> 16) | \ + (((src)&0x0000E000) >> 11) | \ + (((src)&0x000000C0) >> 6)); \ + } +static void Blit_RGB888_index8(SDL_BlitInfo *info) { #ifndef USE_DUFFS_LOOP int c; @@ -1000,20 +971,20 @@ Blit_RGB888_index8(SDL_BlitInfo * info) /* Set up some basic variables */ width = info->dst_w; height = info->dst_h; - src = (Uint32 *) info->src; + src = (Uint32 *)info->src; srcskip = info->src_skip / 4; dst = info->dst; dstskip = info->dst_skip; map = info->table; - if (map == NULL) { + if (!map) { while (height--) { #ifdef USE_DUFFS_LOOP - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( RGB888_RGB332(*dst++, *src); , width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ #else for (c = width / 4; c; --c) { /* Pack RGB into 8bit pixel */ @@ -1029,9 +1000,11 @@ Blit_RGB888_index8(SDL_BlitInfo * info) case 3: RGB888_RGB332(*dst++, *src); ++src; + SDL_FALLTHROUGH; case 2: RGB888_RGB332(*dst++, *src); ++src; + SDL_FALLTHROUGH; case 1: RGB888_RGB332(*dst++, *src); ++src; @@ -1045,13 +1018,13 @@ Blit_RGB888_index8(SDL_BlitInfo * info) while (height--) { #ifdef USE_DUFFS_LOOP - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( RGB888_RGB332(Pixel, *src); *dst++ = map[Pixel]; ++src; , width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ #else for (c = width / 4; c; --c) { /* Pack RGB into 8bit pixel */ @@ -1073,10 +1046,12 @@ Blit_RGB888_index8(SDL_BlitInfo * info) RGB888_RGB332(Pixel, *src); *dst++ = map[Pixel]; ++src; + SDL_FALLTHROUGH; case 2: RGB888_RGB332(Pixel, *src); *dst++ = map[Pixel]; ++src; + SDL_FALLTHROUGH; case 1: RGB888_RGB332(Pixel, *src); *dst++ = map[Pixel]; @@ -1090,13 +1065,13 @@ Blit_RGB888_index8(SDL_BlitInfo * info) } /* Special optimized blit for RGB 10-10-10 --> RGB 3-3-2 */ -#define RGB101010_RGB332(dst, src) { \ - dst = (Uint8)((((src)&0x38000000)>>22)| \ - (((src)&0x000E0000)>>15)| \ - (((src)&0x00000300)>>8)); \ -} -static void -Blit_RGB101010_index8(SDL_BlitInfo * info) +#define RGB101010_RGB332(dst, src) \ + { \ + dst = (Uint8)((((src)&0x38000000) >> 22) | \ + (((src)&0x000E0000) >> 15) | \ + (((src)&0x00000300) >> 8)); \ + } +static void Blit_RGB101010_index8(SDL_BlitInfo *info) { #ifndef USE_DUFFS_LOOP int c; @@ -1110,20 +1085,20 @@ Blit_RGB101010_index8(SDL_BlitInfo * info) /* Set up some basic variables */ width = info->dst_w; height = info->dst_h; - src = (Uint32 *) info->src; + src = (Uint32 *)info->src; srcskip = info->src_skip / 4; dst = info->dst; dstskip = info->dst_skip; map = info->table; - if (map == NULL) { + if (!map) { while (height--) { #ifdef USE_DUFFS_LOOP - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( RGB101010_RGB332(*dst++, *src); , width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ #else for (c = width / 4; c; --c) { /* Pack RGB into 8bit pixel */ @@ -1139,9 +1114,11 @@ Blit_RGB101010_index8(SDL_BlitInfo * info) case 3: RGB101010_RGB332(*dst++, *src); ++src; + SDL_FALLTHROUGH; case 2: RGB101010_RGB332(*dst++, *src); ++src; + SDL_FALLTHROUGH; case 1: RGB101010_RGB332(*dst++, *src); ++src; @@ -1155,13 +1132,13 @@ Blit_RGB101010_index8(SDL_BlitInfo * info) while (height--) { #ifdef USE_DUFFS_LOOP - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( RGB101010_RGB332(Pixel, *src); *dst++ = map[Pixel]; ++src; , width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ #else for (c = width / 4; c; --c) { /* Pack RGB into 8bit pixel */ @@ -1183,10 +1160,12 @@ Blit_RGB101010_index8(SDL_BlitInfo * info) RGB101010_RGB332(Pixel, *src); *dst++ = map[Pixel]; ++src; + SDL_FALLTHROUGH; case 2: RGB101010_RGB332(Pixel, *src); *dst++ = map[Pixel]; ++src; + SDL_FALLTHROUGH; case 1: RGB101010_RGB332(Pixel, *src); *dst++ = map[Pixel]; @@ -1200,23 +1179,25 @@ Blit_RGB101010_index8(SDL_BlitInfo * info) } /* Special optimized blit for RGB 8-8-8 --> RGB 5-5-5 */ -#define RGB888_RGB555(dst, src) { \ - *(Uint16 *)(dst) = (Uint16)((((*src)&0x00F80000)>>9)| \ - (((*src)&0x0000F800)>>6)| \ - (((*src)&0x000000F8)>>3)); \ -} +#define RGB888_RGB555(dst, src) \ + { \ + *(Uint16 *)(dst) = (Uint16)((((*src) & 0x00F80000) >> 9) | \ + (((*src) & 0x0000F800) >> 6) | \ + (((*src) & 0x000000F8) >> 3)); \ + } #ifndef USE_DUFFS_LOOP -#define RGB888_RGB555_TWO(dst, src) { \ - *(Uint32 *)(dst) = (((((src[HI])&0x00F80000)>>9)| \ - (((src[HI])&0x0000F800)>>6)| \ - (((src[HI])&0x000000F8)>>3))<<16)| \ - (((src[LO])&0x00F80000)>>9)| \ - (((src[LO])&0x0000F800)>>6)| \ - (((src[LO])&0x000000F8)>>3); \ -} +#define RGB888_RGB555_TWO(dst, src) \ + { \ + *(Uint32 *)(dst) = (((((src[HI]) & 0x00F80000) >> 9) | \ + (((src[HI]) & 0x0000F800) >> 6) | \ + (((src[HI]) & 0x000000F8) >> 3)) \ + << 16) | \ + (((src[LO]) & 0x00F80000) >> 9) | \ + (((src[LO]) & 0x0000F800) >> 6) | \ + (((src[LO]) & 0x000000F8) >> 3); \ + } #endif -static void -Blit_RGB888_RGB555(SDL_BlitInfo * info) +static void Blit_RGB888_RGB555(SDL_BlitInfo *info) { #ifndef USE_DUFFS_LOOP int c; @@ -1229,26 +1210,26 @@ Blit_RGB888_RGB555(SDL_BlitInfo * info) /* Set up some basic variables */ width = info->dst_w; height = info->dst_h; - src = (Uint32 *) info->src; + src = (Uint32 *)info->src; srcskip = info->src_skip / 4; - dst = (Uint16 *) info->dst; + dst = (Uint16 *)info->dst; dstskip = info->dst_skip / 2; #ifdef USE_DUFFS_LOOP while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( RGB888_RGB555(dst, src); ++src; ++dst; , width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } #else /* Memory align at 4-byte boundary, if necessary */ - if ((long) dst & 0x03) { + if ((long)dst & 0x03) { /* Don't do anything if width is 0 */ if (width == 0) { return; @@ -1276,6 +1257,7 @@ Blit_RGB888_RGB555(SDL_BlitInfo * info) RGB888_RGB555(dst, src); ++src; ++dst; + SDL_FALLTHROUGH; case 2: RGB888_RGB555_TWO(dst, src); src += 2; @@ -1307,6 +1289,7 @@ Blit_RGB888_RGB555(SDL_BlitInfo * info) RGB888_RGB555(dst, src); ++src; ++dst; + SDL_FALLTHROUGH; case 2: RGB888_RGB555_TWO(dst, src); src += 2; @@ -1326,23 +1309,25 @@ Blit_RGB888_RGB555(SDL_BlitInfo * info) } /* Special optimized blit for RGB 8-8-8 --> RGB 5-6-5 */ -#define RGB888_RGB565(dst, src) { \ - *(Uint16 *)(dst) = (Uint16)((((*src)&0x00F80000)>>8)| \ - (((*src)&0x0000FC00)>>5)| \ - (((*src)&0x000000F8)>>3)); \ -} +#define RGB888_RGB565(dst, src) \ + { \ + *(Uint16 *)(dst) = (Uint16)((((*src) & 0x00F80000) >> 8) | \ + (((*src) & 0x0000FC00) >> 5) | \ + (((*src) & 0x000000F8) >> 3)); \ + } #ifndef USE_DUFFS_LOOP -#define RGB888_RGB565_TWO(dst, src) { \ - *(Uint32 *)(dst) = (((((src[HI])&0x00F80000)>>8)| \ - (((src[HI])&0x0000FC00)>>5)| \ - (((src[HI])&0x000000F8)>>3))<<16)| \ - (((src[LO])&0x00F80000)>>8)| \ - (((src[LO])&0x0000FC00)>>5)| \ - (((src[LO])&0x000000F8)>>3); \ -} +#define RGB888_RGB565_TWO(dst, src) \ + { \ + *(Uint32 *)(dst) = (((((src[HI]) & 0x00F80000) >> 8) | \ + (((src[HI]) & 0x0000FC00) >> 5) | \ + (((src[HI]) & 0x000000F8) >> 3)) \ + << 16) | \ + (((src[LO]) & 0x00F80000) >> 8) | \ + (((src[LO]) & 0x0000FC00) >> 5) | \ + (((src[LO]) & 0x000000F8) >> 3); \ + } #endif -static void -Blit_RGB888_RGB565(SDL_BlitInfo * info) +static void Blit_RGB888_RGB565(SDL_BlitInfo *info) { #ifndef USE_DUFFS_LOOP int c; @@ -1355,26 +1340,26 @@ Blit_RGB888_RGB565(SDL_BlitInfo * info) /* Set up some basic variables */ width = info->dst_w; height = info->dst_h; - src = (Uint32 *) info->src; + src = (Uint32 *)info->src; srcskip = info->src_skip / 4; - dst = (Uint16 *) info->dst; + dst = (Uint16 *)info->dst; dstskip = info->dst_skip / 2; #ifdef USE_DUFFS_LOOP while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( RGB888_RGB565(dst, src); ++src; ++dst; , width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } #else /* Memory align at 4-byte boundary, if necessary */ - if ((long) dst & 0x03) { + if ((long)dst & 0x03) { /* Don't do anything if width is 0 */ if (width == 0) { return; @@ -1402,6 +1387,7 @@ Blit_RGB888_RGB565(SDL_BlitInfo * info) RGB888_RGB565(dst, src); ++src; ++dst; + SDL_FALLTHROUGH; case 2: RGB888_RGB565_TWO(dst, src); src += 2; @@ -1433,6 +1419,7 @@ Blit_RGB888_RGB565(SDL_BlitInfo * info) RGB888_RGB565(dst, src); ++src; ++dst; + SDL_FALLTHROUGH; case 2: RGB888_RGB565_TWO(dst, src); src += 2; @@ -1451,13 +1438,11 @@ Blit_RGB888_RGB565(SDL_BlitInfo * info) #endif /* USE_DUFFS_LOOP */ } - #if SDL_HAVE_BLIT_N_RGB565 /* Special optimized blit for RGB 5-6-5 --> 32-bit RGB surfaces */ -#define RGB565_32(dst, src, map) (map[src[LO]*2] + map[src[HI]*2+1]) -static void -Blit_RGB565_32(SDL_BlitInfo * info, const Uint32 * map) +#define RGB565_32(dst, src, map) (map[src[LO] * 2] + map[src[HI] * 2 + 1]) +static void Blit_RGB565_32(SDL_BlitInfo *info, const Uint32 *map) { #ifndef USE_DUFFS_LOOP int c; @@ -1472,19 +1457,19 @@ Blit_RGB565_32(SDL_BlitInfo * info, const Uint32 * map) height = info->dst_h; src = info->src; srcskip = info->src_skip; - dst = (Uint32 *) info->dst; + dst = (Uint32 *)info->dst; dstskip = info->dst_skip / 4; #ifdef USE_DUFFS_LOOP while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { *dst++ = RGB565_32(dst, src, map); src += 2; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -1506,9 +1491,11 @@ Blit_RGB565_32(SDL_BlitInfo * info, const Uint32 * map) case 3: *dst++ = RGB565_32(dst, src, map); src += 2; + SDL_FALLTHROUGH; case 2: *dst++ = RGB565_32(dst, src, map); src += 2; + SDL_FALLTHROUGH; case 1: *dst++ = RGB565_32(dst, src, map); src += 2; @@ -1520,6 +1507,8 @@ Blit_RGB565_32(SDL_BlitInfo * info, const Uint32 * map) #endif /* USE_DUFFS_LOOP */ } +/* *INDENT-OFF* */ /* clang-format off */ + /* Special optimized blit for RGB 5-6-5 --> ARGB 8-8-8-8 */ static const Uint32 RGB565_ARGB8888_LUT[512] = { 0x00000000, 0xff000000, 0x00000008, 0xff002000, @@ -1652,8 +1641,7 @@ static const Uint32 RGB565_ARGB8888_LUT[512] = { 0x00001cf6, 0xffffc200, 0x00001cff, 0xffffe200 }; -static void -Blit_RGB565_ARGB8888(SDL_BlitInfo * info) +static void Blit_RGB565_ARGB8888(SDL_BlitInfo * info) { Blit_RGB565_32(info, RGB565_ARGB8888_LUT); } @@ -1790,8 +1778,7 @@ static const Uint32 RGB565_ABGR8888_LUT[512] = { 0xfff61c00, 0x0000c2ff, 0xffff1c00, 0x0000e2ff }; -static void -Blit_RGB565_ABGR8888(SDL_BlitInfo * info) +static void Blit_RGB565_ABGR8888(SDL_BlitInfo * info) { Blit_RGB565_32(info, RGB565_ABGR8888_LUT); } @@ -1928,8 +1915,7 @@ static const Uint32 RGB565_RGBA8888_LUT[512] = { 0x001cf6ff, 0xffc20000, 0x001cffff, 0xffe20000, }; -static void -Blit_RGB565_RGBA8888(SDL_BlitInfo * info) +static void Blit_RGB565_RGBA8888(SDL_BlitInfo * info) { Blit_RGB565_32(info, RGB565_RGBA8888_LUT); } @@ -2066,16 +2052,44 @@ static const Uint32 RGB565_BGRA8888_LUT[512] = { 0xf61c0000, 0x00c2ffff, 0xff1c0000, 0x00e2ffff }; -static void -Blit_RGB565_BGRA8888(SDL_BlitInfo * info) +static void Blit_RGB565_BGRA8888(SDL_BlitInfo * info) { Blit_RGB565_32(info, RGB565_BGRA8888_LUT); } +/* *INDENT-ON* */ /* clang-format on */ + #endif /* SDL_HAVE_BLIT_N_RGB565 */ -static void -BlitNto1(SDL_BlitInfo * info) +/* RGB555->ARGB1555, and BGR555->ABGR1555, SET_ALPHA */ +static void Blit_RGB555_ARGB1555(SDL_BlitInfo *info) +{ + int width = info->dst_w; + int height = info->dst_h; + Uint16 *src = (Uint16 *)info->src; + int srcskip = info->src_skip; + Uint16 *dst = (Uint16 *)info->dst; + int dstskip = info->dst_skip; + SDL_PixelFormat *dstfmt = info->dst_fmt; + + Uint16 mask = ((Uint32)info->a >> dstfmt->Aloss) << dstfmt->Ashift; + + while (height--) { + /* *INDENT-OFF* */ /* clang-format off */ + DUFFS_LOOP( + { + *dst = *src | mask; + ++dst; + ++src; + }, + width); + /* *INDENT-ON* */ /* clang-format on */ + src = (Uint16 *)((Uint8 *)src + srcskip); + dst = (Uint16 *)((Uint8 *)dst + dstskip); + } +} + +static void BlitNto1(SDL_BlitInfo *info) { #ifndef USE_DUFFS_LOOP int c; @@ -2101,10 +2115,10 @@ BlitNto1(SDL_BlitInfo * info) srcfmt = info->src_fmt; srcbpp = srcfmt->BytesPerPixel; - if (map == NULL) { + if (!map) { while (height--) { #ifdef USE_DUFFS_LOOP - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB); @@ -2117,14 +2131,14 @@ BlitNto1(SDL_BlitInfo * info) dst++; src += srcbpp; , width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ #else for (c = width; c; --c) { DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB); if (1) { /* Pack RGB into 8bit pixel */ *dst = ((sR >> 5) << (3 + 2)) | - ((sG >> 5) << (2)) | ((sB >> 6) << (0)); + ((sG >> 5) << (2)) | ((sB >> 6) << (0)); } dst++; src += srcbpp; @@ -2136,7 +2150,7 @@ BlitNto1(SDL_BlitInfo * info) } else { while (height--) { #ifdef USE_DUFFS_LOOP - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB); @@ -2149,7 +2163,7 @@ BlitNto1(SDL_BlitInfo * info) dst++; src += srcbpp; , width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ #else for (c = width; c; --c) { DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, sR, sG, sB); @@ -2169,24 +2183,23 @@ BlitNto1(SDL_BlitInfo * info) } /* blits 32 bit RGB<->RGBA with both surfaces having the same R,G,B fields */ -static void -Blit4to4MaskAlpha(SDL_BlitInfo * info) +static void Blit4to4MaskAlpha(SDL_BlitInfo *info) { int width = info->dst_w; int height = info->dst_h; - Uint32 *src = (Uint32 *) info->src; + Uint32 *src = (Uint32 *)info->src; int srcskip = info->src_skip; - Uint32 *dst = (Uint32 *) info->dst; + Uint32 *dst = (Uint32 *)info->dst; int dstskip = info->dst_skip; SDL_PixelFormat *srcfmt = info->src_fmt; SDL_PixelFormat *dstfmt = info->dst_fmt; if (dstfmt->Amask) { /* RGB->RGBA, SET_ALPHA */ - Uint32 mask = (info->a >> dstfmt->Aloss) << dstfmt->Ashift; + Uint32 mask = ((Uint32)info->a >> dstfmt->Aloss) << dstfmt->Ashift; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { *dst = *src | mask; @@ -2194,16 +2207,16 @@ Blit4to4MaskAlpha(SDL_BlitInfo * info) ++src; }, width); - /* *INDENT-ON* */ - src = (Uint32 *) ((Uint8 *) src + srcskip); - dst = (Uint32 *) ((Uint8 *) dst + dstskip); + /* *INDENT-ON* */ /* clang-format on */ + src = (Uint32 *)((Uint8 *)src + srcskip); + dst = (Uint32 *)((Uint8 *)dst + dstskip); } } else { /* RGBA->RGB, NO_ALPHA */ Uint32 mask = srcfmt->Rmask | srcfmt->Gmask | srcfmt->Bmask; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { *dst = *src & mask; @@ -2211,44 +2224,16 @@ Blit4to4MaskAlpha(SDL_BlitInfo * info) ++src; }, width); - /* *INDENT-ON* */ - src = (Uint32 *) ((Uint8 *) src + srcskip); - dst = (Uint32 *) ((Uint8 *) dst + dstskip); + /* *INDENT-ON* */ /* clang-format on */ + src = (Uint32 *)((Uint8 *)src + srcskip); + dst = (Uint32 *)((Uint8 *)dst + dstskip); } } } -/* blits 32 bit RGBA<->RGBA with both surfaces having the same R,G,B,A fields */ -static void -Blit4to4CopyAlpha(SDL_BlitInfo * info) -{ - int width = info->dst_w; - int height = info->dst_h; - Uint32 *src = (Uint32 *) info->src; - int srcskip = info->src_skip; - Uint32 *dst = (Uint32 *) info->dst; - int dstskip = info->dst_skip; - - /* RGBA->RGBA, COPY_ALPHA */ - while (height--) { - /* *INDENT-OFF* */ - DUFFS_LOOP( - { - *dst = *src; - ++dst; - ++src; - }, - width); - /* *INDENT-ON* */ - src = (Uint32 *) ((Uint8 *) src + srcskip); - dst = (Uint32 *) ((Uint8 *) dst + dstskip); - } -} - /* permutation for mapping srcfmt to dstfmt, overloading or not the alpha channel */ -static void -get_permutation(SDL_PixelFormat *srcfmt, SDL_PixelFormat *dstfmt, - int *_p0 , int *_p1, int *_p2, int *_p3, int *_alpha_channel) +static void get_permutation(SDL_PixelFormat *srcfmt, SDL_PixelFormat *dstfmt, + int *_p0, int *_p1, int *_p2, int *_p3, int *_alpha_channel) { int alpha_channel = 0, p0, p1, p2, p3; #if SDL_BYTEORDER == SDL_LIL_ENDIAN @@ -2305,10 +2290,18 @@ get_permutation(SDL_PixelFormat *srcfmt, SDL_PixelFormat *dstfmt, #if SDL_BYTEORDER == SDL_LIL_ENDIAN #else if (srcbpp == 3 && dstbpp == 4) { - if (p0 != 1) p0--; - if (p1 != 1) p1--; - if (p2 != 1) p2--; - if (p3 != 1) p3--; + if (p0 != 1) { + p0--; + } + if (p1 != 1) { + p1--; + } + if (p2 != 1) { + p2--; + } + if (p3 != 1) { + p3--; + } } else if (srcbpp == 4 && dstbpp == 3) { p0 = p1; p1 = p2; @@ -2325,9 +2318,7 @@ get_permutation(SDL_PixelFormat *srcfmt, SDL_PixelFormat *dstfmt, } } - -static void -BlitNtoN(SDL_BlitInfo * info) +static void BlitNtoN(SDL_BlitInfo *info) { int width = info->dst_w; int height = info->dst_h; @@ -2352,7 +2343,7 @@ BlitNtoN(SDL_BlitInfo * info) get_permutation(srcfmt, dstfmt, &p0, &p1, &p2, &p3, &alpha_channel); while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { dst[0] = src[p0]; @@ -2363,7 +2354,7 @@ BlitNtoN(SDL_BlitInfo * info) src += 4; dst += 4; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -2380,7 +2371,7 @@ BlitNtoN(SDL_BlitInfo * info) get_permutation(srcfmt, dstfmt, &p0, &p1, &p2, &p3, NULL); while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { dst[0] = src[p0]; @@ -2389,7 +2380,7 @@ BlitNtoN(SDL_BlitInfo * info) src += 4; dst += 3; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -2406,7 +2397,7 @@ BlitNtoN(SDL_BlitInfo * info) get_permutation(srcfmt, dstfmt, &p0, &p1, &p2, &p3, &alpha_channel); while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { dst[0] = src[p0]; @@ -2417,7 +2408,7 @@ BlitNtoN(SDL_BlitInfo * info) src += 3; dst += 4; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -2426,7 +2417,7 @@ BlitNtoN(SDL_BlitInfo * info) #endif while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { Uint32 Pixel; @@ -2439,14 +2430,13 @@ BlitNtoN(SDL_BlitInfo * info) src += srcbpp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } } -static void -BlitNtoNCopyAlpha(SDL_BlitInfo * info) +static void BlitNtoNCopyAlpha(SDL_BlitInfo *info) { int width = info->dst_w; int height = info->dst_h; @@ -2471,7 +2461,7 @@ BlitNtoNCopyAlpha(SDL_BlitInfo * info) get_permutation(srcfmt, dstfmt, &p0, &p1, &p2, &p3, NULL); while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { dst[0] = src[p0]; @@ -2481,7 +2471,7 @@ BlitNtoNCopyAlpha(SDL_BlitInfo * info) src += 4; dst += 4; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -2503,8 +2493,7 @@ BlitNtoNCopyAlpha(SDL_BlitInfo * info) } } -static void -BlitNto1Key(SDL_BlitInfo * info) +static void BlitNto1Key(SDL_BlitInfo *info) { int width = info->dst_w; int height = info->dst_h; @@ -2524,9 +2513,9 @@ BlitNto1Key(SDL_BlitInfo * info) srcbpp = srcfmt->BytesPerPixel; ckey &= rgbmask; - if (palmap == NULL) { + if (!palmap) { while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, @@ -2541,13 +2530,13 @@ BlitNto1Key(SDL_BlitInfo * info) src += srcbpp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } } else { while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { DISEMBLE_RGB(src, srcbpp, srcfmt, Pixel, @@ -2562,21 +2551,20 @@ BlitNto1Key(SDL_BlitInfo * info) src += srcbpp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } } } -static void -Blit2to2Key(SDL_BlitInfo * info) +static void Blit2to2Key(SDL_BlitInfo *info) { int width = info->dst_w; int height = info->dst_h; - Uint16 *srcp = (Uint16 *) info->src; + Uint16 *srcp = (Uint16 *)info->src; int srcskip = info->src_skip; - Uint16 *dstp = (Uint16 *) info->dst; + Uint16 *dstp = (Uint16 *)info->dst; int dstskip = info->dst_skip; Uint32 ckey = info->colorkey; Uint32 rgbmask = ~info->src_fmt->Amask; @@ -2587,7 +2575,7 @@ Blit2to2Key(SDL_BlitInfo * info) ckey &= rgbmask; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { if ( (*srcp & rgbmask) != ckey ) { @@ -2597,14 +2585,13 @@ Blit2to2Key(SDL_BlitInfo * info) srcp++; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ srcp += srcskip; dstp += dstskip; } } -static void -BlitNtoNKey(SDL_BlitInfo * info) +static void BlitNtoNKey(SDL_BlitInfo *info) { int width = info->dst_w; int height = info->dst_h; @@ -2627,14 +2614,14 @@ BlitNtoNKey(SDL_BlitInfo * info) /* BPP 4, same rgb */ if (srcbpp == 4 && dstbpp == 4 && srcfmt->Rmask == dstfmt->Rmask && srcfmt->Gmask == dstfmt->Gmask && srcfmt->Bmask == dstfmt->Bmask) { - Uint32 *src32 = (Uint32*)src; - Uint32 *dst32 = (Uint32*)dst; + Uint32 *src32 = (Uint32 *)src; + Uint32 *dst32 = (Uint32 *)dst; if (dstfmt->Amask) { /* RGB->RGBA, SET_ALPHA */ - Uint32 mask = info->a << dstfmt->Ashift; + Uint32 mask = ((Uint32)info->a) << dstfmt->Ashift; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { if ((*src32 & rgbmask) != ckey) { @@ -2643,16 +2630,16 @@ BlitNtoNKey(SDL_BlitInfo * info) ++dst32; ++src32; }, width); - /* *INDENT-ON* */ - src32 = (Uint32 *) ((Uint8 *) src32 + srcskip); - dst32 = (Uint32 *) ((Uint8 *) dst32 + dstskip); + /* *INDENT-ON* */ /* clang-format on */ + src32 = (Uint32 *)((Uint8 *)src32 + srcskip); + dst32 = (Uint32 *)((Uint8 *)dst32 + dstskip); } return; } else { /* RGBA->RGB, NO_ALPHA */ Uint32 mask = srcfmt->Rmask | srcfmt->Gmask | srcfmt->Bmask; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { if ((*src32 & rgbmask) != ckey) { @@ -2661,9 +2648,9 @@ BlitNtoNKey(SDL_BlitInfo * info) ++dst32; ++src32; }, width); - /* *INDENT-ON* */ - src32 = (Uint32 *) ((Uint8 *) src32 + srcskip); - dst32 = (Uint32 *) ((Uint8 *) dst32 + dstskip); + /* *INDENT-ON* */ /* clang-format on */ + src32 = (Uint32 *)((Uint8 *)src32 + srcskip); + dst32 = (Uint32 *)((Uint8 *)dst32 + dstskip); } return; } @@ -2680,7 +2667,7 @@ BlitNtoNKey(SDL_BlitInfo * info) get_permutation(srcfmt, dstfmt, &p0, &p1, &p2, &p3, &alpha_channel); while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { Uint32 *src32 = (Uint32*)src; @@ -2695,7 +2682,7 @@ BlitNtoNKey(SDL_BlitInfo * info) src += 4; dst += 4; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -2709,7 +2696,7 @@ BlitNtoNKey(SDL_BlitInfo * info) #if SDL_BYTEORDER == SDL_LIL_ENDIAN Uint8 k0 = ckey & 0xFF; - Uint8 k1 = (ckey >> 8) & 0xFF; + Uint8 k1 = (ckey >> 8) & 0xFF; Uint8 k2 = (ckey >> 16) & 0xFF; #else Uint8 k0 = (ckey >> 16) & 0xFF; @@ -2718,7 +2705,7 @@ BlitNtoNKey(SDL_BlitInfo * info) #endif while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { Uint8 s0 = src[0]; @@ -2734,7 +2721,7 @@ BlitNtoNKey(SDL_BlitInfo * info) dst += 3; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -2747,7 +2734,7 @@ BlitNtoNKey(SDL_BlitInfo * info) #if SDL_BYTEORDER == SDL_LIL_ENDIAN Uint8 k0 = ckey & 0xFF; - Uint8 k1 = (ckey >> 8) & 0xFF; + Uint8 k1 = (ckey >> 8) & 0xFF; Uint8 k2 = (ckey >> 16) & 0xFF; #else Uint8 k0 = (ckey >> 16) & 0xFF; @@ -2756,7 +2743,7 @@ BlitNtoNKey(SDL_BlitInfo * info) #endif while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { Uint8 s0 = src[0]; @@ -2772,7 +2759,7 @@ BlitNtoNKey(SDL_BlitInfo * info) dst += 3; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -2788,7 +2775,7 @@ BlitNtoNKey(SDL_BlitInfo * info) get_permutation(srcfmt, dstfmt, &p0, &p1, &p2, &p3, NULL); while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { Uint32 *src32 = (Uint32*)src; @@ -2800,7 +2787,7 @@ BlitNtoNKey(SDL_BlitInfo * info) src += 4; dst += 3; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -2814,12 +2801,12 @@ BlitNtoNKey(SDL_BlitInfo * info) #if SDL_BYTEORDER == SDL_LIL_ENDIAN Uint8 k0 = ckey & 0xFF; - Uint8 k1 = (ckey >> 8) & 0xFF; + Uint8 k1 = (ckey >> 8) & 0xFF; Uint8 k2 = (ckey >> 16) & 0xFF; #else Uint8 k0 = (ckey >> 16) & 0xFF; Uint8 k1 = (ckey >> 8) & 0xFF; - Uint8 k2 = ckey & 0xFF; + Uint8 k2 = ckey & 0xFF; #endif /* Find the appropriate permutation */ @@ -2827,7 +2814,7 @@ BlitNtoNKey(SDL_BlitInfo * info) get_permutation(srcfmt, dstfmt, &p0, &p1, &p2, &p3, &alpha_channel); while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { Uint8 s0 = src[0]; @@ -2844,7 +2831,7 @@ BlitNtoNKey(SDL_BlitInfo * info) src += 3; dst += 4; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -2853,7 +2840,7 @@ BlitNtoNKey(SDL_BlitInfo * info) #endif while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { Uint32 Pixel; @@ -2869,14 +2856,13 @@ BlitNtoNKey(SDL_BlitInfo * info) src += srcbpp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } } -static void -BlitNtoNKeyCopyAlpha(SDL_BlitInfo * info) +static void BlitNtoNKeyCopyAlpha(SDL_BlitInfo *info) { int width = info->dst_w; int height = info->dst_h; @@ -2907,10 +2893,10 @@ BlitNtoNKeyCopyAlpha(SDL_BlitInfo * info) srcfmt->format == SDL_PIXELFORMAT_BGRA8888 || srcfmt->format == SDL_PIXELFORMAT_RGBA8888) { - Uint32 *src32 = (Uint32*)src; - Uint32 *dst32 = (Uint32*)dst; + Uint32 *src32 = (Uint32 *)src; + Uint32 *dst32 = (Uint32 *)dst; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { if ((*src32 & rgbmask) != ckey) { @@ -2920,7 +2906,7 @@ BlitNtoNKeyCopyAlpha(SDL_BlitInfo * info) ++dst32; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src32 = (Uint32 *)((Uint8 *)src32 + srcskip); dst32 = (Uint32 *)((Uint8 *)dst32 + dstskip); } @@ -2939,7 +2925,7 @@ BlitNtoNKeyCopyAlpha(SDL_BlitInfo * info) get_permutation(srcfmt, dstfmt, &p0, &p1, &p2, &p3, NULL); while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { Uint32 *src32 = (Uint32*)src; @@ -2952,7 +2938,7 @@ BlitNtoNKeyCopyAlpha(SDL_BlitInfo * info) src += 4; dst += 4; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -2961,7 +2947,7 @@ BlitNtoNKeyCopyAlpha(SDL_BlitInfo * info) #endif while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { DISEMBLE_RGBA(src, srcbpp, srcfmt, Pixel, sR, sG, sB, sA); @@ -2972,15 +2958,14 @@ BlitNtoNKeyCopyAlpha(SDL_BlitInfo * info) src += srcbpp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } } /* Special optimized blit for ARGB 2-10-10-10 --> RGBA */ -static void -Blit2101010toN(SDL_BlitInfo * info) +static void Blit2101010toN(SDL_BlitInfo *info) { int width = info->dst_w; int height = info->dst_h; @@ -2994,7 +2979,7 @@ Blit2101010toN(SDL_BlitInfo * info) unsigned sR, sG, sB, sA; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { Pixel = *(Uint32 *)src; @@ -3004,15 +2989,14 @@ Blit2101010toN(SDL_BlitInfo * info) src += 4; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } } /* Special optimized blit for RGBA --> ARGB 2-10-10-10 */ -static void -BlitNto2101010(SDL_BlitInfo * info) +static void BlitNto2101010(SDL_BlitInfo *info) { int width = info->dst_w; int height = info->dst_h; @@ -3026,7 +3010,7 @@ BlitNto2101010(SDL_BlitInfo * info) unsigned sR, sG, sB, sA; while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { DISEMBLE_RGBA(src, srcbpp, srcfmt, Pixel, sR, sG, sB, sA); @@ -3036,15 +3020,14 @@ BlitNto2101010(SDL_BlitInfo * info) src += srcbpp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } } /* Blit_3or4_to_3or4__same_rgb: 3 or 4 bpp, same RGB triplet */ -static void -Blit_3or4_to_3or4__same_rgb(SDL_BlitInfo * info) +static void Blit_3or4_to_3or4__same_rgb(SDL_BlitInfo *info) { int width = info->dst_w; int height = info->dst_h; @@ -3059,7 +3042,7 @@ Blit_3or4_to_3or4__same_rgb(SDL_BlitInfo * info) if (dstfmt->Amask) { /* SET_ALPHA */ - Uint32 mask = info->a << dstfmt->Ashift; + Uint32 mask = ((Uint32)info->a) << dstfmt->Ashift; #if SDL_BYTEORDER == SDL_LIL_ENDIAN int i0 = 0, i1 = 1, i2 = 2; #else @@ -3068,7 +3051,7 @@ Blit_3or4_to_3or4__same_rgb(SDL_BlitInfo * info) int i2 = srcbpp - 1 - 2; #endif while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { Uint32 *dst32 = (Uint32*)dst; @@ -3079,7 +3062,7 @@ Blit_3or4_to_3or4__same_rgb(SDL_BlitInfo * info) dst += 4; src += srcbpp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -3097,7 +3080,7 @@ Blit_3or4_to_3or4__same_rgb(SDL_BlitInfo * info) int j2 = dstbpp - 1 - 2; #endif while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { Uint8 s0 = src[i0]; @@ -3109,7 +3092,7 @@ Blit_3or4_to_3or4__same_rgb(SDL_BlitInfo * info) dst += dstbpp; src += srcbpp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -3117,8 +3100,7 @@ Blit_3or4_to_3or4__same_rgb(SDL_BlitInfo * info) } /* Blit_3or4_to_3or4__inversed_rgb: 3 or 4 bpp, inversed RGB triplet */ -static void -Blit_3or4_to_3or4__inversed_rgb(SDL_BlitInfo * info) +static void Blit_3or4_to_3or4__inversed_rgb(SDL_BlitInfo *info) { int width = info->dst_w; int height = info->dst_h; @@ -3141,26 +3123,26 @@ Blit_3or4_to_3or4__inversed_rgb(SDL_BlitInfo * info) #else int i0 = 3, i1 = 2, i2 = 1, i3 = 0; #endif - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { Uint32 *dst32 = (Uint32*)dst; Uint8 s0 = src[i0]; Uint8 s1 = src[i1]; Uint8 s2 = src[i2]; - Uint32 alphashift = src[i3] << dstfmt->Ashift; + Uint32 alphashift = ((Uint32)src[i3]) << dstfmt->Ashift; /* inversed, compared to Blit_3or4_to_3or4__same_rgb */ *dst32 = (s0 << 16) | (s1 << 8) | (s2) | alphashift; dst += 4; src += 4; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } } else { /* SET_ALPHA */ - Uint32 mask = info->a << dstfmt->Ashift; + Uint32 mask = ((Uint32)info->a) << dstfmt->Ashift; #if SDL_BYTEORDER == SDL_LIL_ENDIAN int i0 = 0, i1 = 1, i2 = 2; #else @@ -3169,7 +3151,7 @@ Blit_3or4_to_3or4__inversed_rgb(SDL_BlitInfo * info) int i2 = srcbpp - 1 - 2; #endif while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { Uint32 *dst32 = (Uint32*)dst; @@ -3181,7 +3163,7 @@ Blit_3or4_to_3or4__inversed_rgb(SDL_BlitInfo * info) dst += 4; src += srcbpp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -3200,7 +3182,7 @@ Blit_3or4_to_3or4__inversed_rgb(SDL_BlitInfo * info) int j2 = dstbpp - 1 - 0; #endif while (height--) { - /* *INDENT-OFF* */ + /* *INDENT-OFF* */ /* clang-format off */ DUFFS_LOOP( { Uint8 s0 = src[i0]; @@ -3213,7 +3195,7 @@ Blit_3or4_to_3or4__inversed_rgb(SDL_BlitInfo * info) dst += dstbpp; src += srcbpp; }, width); - /* *INDENT-ON* */ + /* *INDENT-ON* */ /* clang-format on */ src += srcskip; dst += dstskip; } @@ -3231,122 +3213,126 @@ struct blit_table Uint32 dstR, dstG, dstB; enum blit_features blit_features; SDL_BlitFunc blitfunc; - Uint32 alpha; /* bitwise NO_ALPHA, SET_ALPHA, COPY_ALPHA */ + Uint32 alpha; /* bitwise NO_ALPHA, SET_ALPHA, COPY_ALPHA */ }; static const struct blit_table normal_blit_1[] = { /* Default for 8-bit RGB source, never optimized */ - {0, 0, 0, 0, 0, 0, 0, 0, BlitNtoN, 0} + { 0, 0, 0, 0, 0, 0, 0, 0, BlitNtoN, 0 } }; static const struct blit_table normal_blit_2[] = { -#if SDL_ALTIVEC_BLITTERS +#ifdef SDL_ALTIVEC_BLITTERS /* has-altivec */ - {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x00000000, 0x00000000, 0x00000000, - BLIT_FEATURE_HAS_ALTIVEC, Blit_RGB565_32Altivec, NO_ALPHA | COPY_ALPHA | SET_ALPHA}, - {0x00007C00, 0x000003E0, 0x0000001F, 4, 0x00000000, 0x00000000, 0x00000000, - BLIT_FEATURE_HAS_ALTIVEC, Blit_RGB555_32Altivec, NO_ALPHA | COPY_ALPHA | SET_ALPHA}, + { 0x0000F800, 0x000007E0, 0x0000001F, 4, 0x00000000, 0x00000000, 0x00000000, + BLIT_FEATURE_HAS_ALTIVEC, Blit_RGB565_32Altivec, NO_ALPHA | COPY_ALPHA | SET_ALPHA }, + { 0x00007C00, 0x000003E0, 0x0000001F, 4, 0x00000000, 0x00000000, 0x00000000, + BLIT_FEATURE_HAS_ALTIVEC, Blit_RGB555_32Altivec, NO_ALPHA | COPY_ALPHA | SET_ALPHA }, #endif -#if SDL_ARM_SIMD_BLITTERS - {0x00000F00, 0x000000F0, 0x0000000F, 4, 0x00FF0000, 0x0000FF00, 0x000000FF, - BLIT_FEATURE_HAS_ARM_SIMD, Blit_RGB444_RGB888ARMSIMD, NO_ALPHA | COPY_ALPHA}, +#ifdef SDL_ARM_SIMD_BLITTERS + { 0x00000F00, 0x000000F0, 0x0000000F, 4, 0x00FF0000, 0x0000FF00, 0x000000FF, + BLIT_FEATURE_HAS_ARM_SIMD, Blit_RGB444_RGB888ARMSIMD, NO_ALPHA | COPY_ALPHA }, #endif #if SDL_HAVE_BLIT_N_RGB565 - {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x00FF0000, 0x0000FF00, 0x000000FF, - 0, Blit_RGB565_ARGB8888, NO_ALPHA | COPY_ALPHA | SET_ALPHA}, - {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x000000FF, 0x0000FF00, 0x00FF0000, - 0, Blit_RGB565_ABGR8888, NO_ALPHA | COPY_ALPHA | SET_ALPHA}, - {0x0000F800, 0x000007E0, 0x0000001F, 4, 0xFF000000, 0x00FF0000, 0x0000FF00, - 0, Blit_RGB565_RGBA8888, NO_ALPHA | COPY_ALPHA | SET_ALPHA}, - {0x0000F800, 0x000007E0, 0x0000001F, 4, 0x0000FF00, 0x00FF0000, 0xFF000000, - 0, Blit_RGB565_BGRA8888, NO_ALPHA | COPY_ALPHA | SET_ALPHA}, + { 0x0000F800, 0x000007E0, 0x0000001F, 4, 0x00FF0000, 0x0000FF00, 0x000000FF, + 0, Blit_RGB565_ARGB8888, NO_ALPHA | COPY_ALPHA | SET_ALPHA }, + { 0x0000F800, 0x000007E0, 0x0000001F, 4, 0x000000FF, 0x0000FF00, 0x00FF0000, + 0, Blit_RGB565_ABGR8888, NO_ALPHA | COPY_ALPHA | SET_ALPHA }, + { 0x0000F800, 0x000007E0, 0x0000001F, 4, 0xFF000000, 0x00FF0000, 0x0000FF00, + 0, Blit_RGB565_RGBA8888, NO_ALPHA | COPY_ALPHA | SET_ALPHA }, + { 0x0000F800, 0x000007E0, 0x0000001F, 4, 0x0000FF00, 0x00FF0000, 0xFF000000, + 0, Blit_RGB565_BGRA8888, NO_ALPHA | COPY_ALPHA | SET_ALPHA }, #endif + { 0x00007C00, 0x000003E0, 0x0000001F, 2, 0x00007C00, 0x000003E0, 0x0000001F, + 0, Blit_RGB555_ARGB1555, SET_ALPHA }, + { 0x0000001F, 0x000003E0, 0x00007C00, 2, 0x0000001F, 0x000003E0, 0x00007C00, + 0, Blit_RGB555_ARGB1555, SET_ALPHA }, /* Default for 16-bit RGB source, used if no other blitter matches */ - {0, 0, 0, 0, 0, 0, 0, 0, BlitNtoN, 0} + { 0, 0, 0, 0, 0, 0, 0, 0, BlitNtoN, 0 } }; static const struct blit_table normal_blit_3[] = { /* 3->4 with same rgb triplet */ - {0x000000FF, 0x0000FF00, 0x00FF0000, 4, 0x000000FF, 0x0000FF00, 0x00FF0000, - 0, Blit_3or4_to_3or4__same_rgb, + { 0x000000FF, 0x0000FF00, 0x00FF0000, 4, 0x000000FF, 0x0000FF00, 0x00FF0000, + 0, Blit_3or4_to_3or4__same_rgb, #if HAVE_FAST_WRITE_INT8 - NO_ALPHA | + NO_ALPHA | #endif - SET_ALPHA}, - {0x00FF0000, 0x0000FF00, 0x000000FF, 4, 0x00FF0000, 0x0000FF00, 0x000000FF, - 0, Blit_3or4_to_3or4__same_rgb, + SET_ALPHA }, + { 0x00FF0000, 0x0000FF00, 0x000000FF, 4, 0x00FF0000, 0x0000FF00, 0x000000FF, + 0, Blit_3or4_to_3or4__same_rgb, #if HAVE_FAST_WRITE_INT8 - NO_ALPHA | + NO_ALPHA | #endif - SET_ALPHA}, + SET_ALPHA }, /* 3->4 with inversed rgb triplet */ - {0x000000FF, 0x0000FF00, 0x00FF0000, 4, 0x00FF0000, 0x0000FF00, 0x000000FF, - 0, Blit_3or4_to_3or4__inversed_rgb, + { 0x000000FF, 0x0000FF00, 0x00FF0000, 4, 0x00FF0000, 0x0000FF00, 0x000000FF, + 0, Blit_3or4_to_3or4__inversed_rgb, #if HAVE_FAST_WRITE_INT8 - NO_ALPHA | + NO_ALPHA | #endif - SET_ALPHA}, - {0x00FF0000, 0x0000FF00, 0x000000FF, 4, 0x000000FF, 0x0000FF00, 0x00FF0000, - 0, Blit_3or4_to_3or4__inversed_rgb, + SET_ALPHA }, + { 0x00FF0000, 0x0000FF00, 0x000000FF, 4, 0x000000FF, 0x0000FF00, 0x00FF0000, + 0, Blit_3or4_to_3or4__inversed_rgb, #if HAVE_FAST_WRITE_INT8 - NO_ALPHA | + NO_ALPHA | #endif - SET_ALPHA}, + SET_ALPHA }, /* 3->3 to switch RGB 24 <-> BGR 24 */ - {0x000000FF, 0x0000FF00, 0x00FF0000, 3, 0x00FF0000, 0x0000FF00, 0x000000FF, - 0, Blit_3or4_to_3or4__inversed_rgb, NO_ALPHA }, - {0x00FF0000, 0x0000FF00, 0x000000FF, 3, 0x000000FF, 0x0000FF00, 0x00FF0000, - 0, Blit_3or4_to_3or4__inversed_rgb, NO_ALPHA }, + { 0x000000FF, 0x0000FF00, 0x00FF0000, 3, 0x00FF0000, 0x0000FF00, 0x000000FF, + 0, Blit_3or4_to_3or4__inversed_rgb, NO_ALPHA }, + { 0x00FF0000, 0x0000FF00, 0x000000FF, 3, 0x000000FF, 0x0000FF00, 0x00FF0000, + 0, Blit_3or4_to_3or4__inversed_rgb, NO_ALPHA }, /* Default for 24-bit RGB source, never optimized */ - {0, 0, 0, 0, 0, 0, 0, 0, BlitNtoN, 0} + { 0, 0, 0, 0, 0, 0, 0, 0, BlitNtoN, 0 } }; static const struct blit_table normal_blit_4[] = { -#if SDL_ALTIVEC_BLITTERS +#ifdef SDL_ALTIVEC_BLITTERS /* has-altivec | dont-use-prefetch */ - {0x00000000, 0x00000000, 0x00000000, 4, 0x00000000, 0x00000000, 0x00000000, - BLIT_FEATURE_HAS_ALTIVEC | BLIT_FEATURE_ALTIVEC_DONT_USE_PREFETCH, ConvertAltivec32to32_noprefetch, NO_ALPHA | COPY_ALPHA | SET_ALPHA}, + { 0x00000000, 0x00000000, 0x00000000, 4, 0x00000000, 0x00000000, 0x00000000, + BLIT_FEATURE_HAS_ALTIVEC | BLIT_FEATURE_ALTIVEC_DONT_USE_PREFETCH, ConvertAltivec32to32_noprefetch, NO_ALPHA | COPY_ALPHA | SET_ALPHA }, /* has-altivec */ - {0x00000000, 0x00000000, 0x00000000, 4, 0x00000000, 0x00000000, 0x00000000, - BLIT_FEATURE_HAS_ALTIVEC, ConvertAltivec32to32_prefetch, NO_ALPHA | COPY_ALPHA | SET_ALPHA}, + { 0x00000000, 0x00000000, 0x00000000, 4, 0x00000000, 0x00000000, 0x00000000, + BLIT_FEATURE_HAS_ALTIVEC, ConvertAltivec32to32_prefetch, NO_ALPHA | COPY_ALPHA | SET_ALPHA }, /* has-altivec */ - {0x00000000, 0x00000000, 0x00000000, 2, 0x0000F800, 0x000007E0, 0x0000001F, - BLIT_FEATURE_HAS_ALTIVEC, Blit_RGB888_RGB565Altivec, NO_ALPHA}, + { 0x00000000, 0x00000000, 0x00000000, 2, 0x0000F800, 0x000007E0, 0x0000001F, + BLIT_FEATURE_HAS_ALTIVEC, Blit_RGB888_RGB565Altivec, NO_ALPHA }, #endif -#if SDL_ARM_SIMD_BLITTERS - {0x000000FF, 0x0000FF00, 0x00FF0000, 4, 0x00FF0000, 0x0000FF00, 0x000000FF, - BLIT_FEATURE_HAS_ARM_SIMD, Blit_BGR888_RGB888ARMSIMD, NO_ALPHA | COPY_ALPHA }, +#ifdef SDL_ARM_SIMD_BLITTERS + { 0x000000FF, 0x0000FF00, 0x00FF0000, 4, 0x00FF0000, 0x0000FF00, 0x000000FF, + BLIT_FEATURE_HAS_ARM_SIMD, Blit_BGR888_RGB888ARMSIMD, NO_ALPHA | COPY_ALPHA }, #endif /* 4->3 with same rgb triplet */ - {0x000000FF, 0x0000FF00, 0x00FF0000, 3, 0x000000FF, 0x0000FF00, 0x00FF0000, - 0, Blit_3or4_to_3or4__same_rgb, NO_ALPHA | SET_ALPHA}, - {0x00FF0000, 0x0000FF00, 0x000000FF, 3, 0x00FF0000, 0x0000FF00, 0x000000FF, - 0, Blit_3or4_to_3or4__same_rgb, NO_ALPHA | SET_ALPHA}, + { 0x000000FF, 0x0000FF00, 0x00FF0000, 3, 0x000000FF, 0x0000FF00, 0x00FF0000, + 0, Blit_3or4_to_3or4__same_rgb, NO_ALPHA | SET_ALPHA }, + { 0x00FF0000, 0x0000FF00, 0x000000FF, 3, 0x00FF0000, 0x0000FF00, 0x000000FF, + 0, Blit_3or4_to_3or4__same_rgb, NO_ALPHA | SET_ALPHA }, /* 4->3 with inversed rgb triplet */ - {0x000000FF, 0x0000FF00, 0x00FF0000, 3, 0x00FF0000, 0x0000FF00, 0x000000FF, - 0, Blit_3or4_to_3or4__inversed_rgb, NO_ALPHA | SET_ALPHA}, - {0x00FF0000, 0x0000FF00, 0x000000FF, 3, 0x000000FF, 0x0000FF00, 0x00FF0000, - 0, Blit_3or4_to_3or4__inversed_rgb, NO_ALPHA | SET_ALPHA}, + { 0x000000FF, 0x0000FF00, 0x00FF0000, 3, 0x00FF0000, 0x0000FF00, 0x000000FF, + 0, Blit_3or4_to_3or4__inversed_rgb, NO_ALPHA | SET_ALPHA }, + { 0x00FF0000, 0x0000FF00, 0x000000FF, 3, 0x000000FF, 0x0000FF00, 0x00FF0000, + 0, Blit_3or4_to_3or4__inversed_rgb, NO_ALPHA | SET_ALPHA }, /* 4->4 with inversed rgb triplet, and COPY_ALPHA to switch ABGR8888 <-> ARGB8888 */ - {0x000000FF, 0x0000FF00, 0x00FF0000, 4, 0x00FF0000, 0x0000FF00, 0x000000FF, - 0, Blit_3or4_to_3or4__inversed_rgb, + { 0x000000FF, 0x0000FF00, 0x00FF0000, 4, 0x00FF0000, 0x0000FF00, 0x000000FF, + 0, Blit_3or4_to_3or4__inversed_rgb, #if HAVE_FAST_WRITE_INT8 - NO_ALPHA | + NO_ALPHA | #endif - SET_ALPHA | COPY_ALPHA}, - {0x00FF0000, 0x0000FF00, 0x000000FF, 4, 0x000000FF, 0x0000FF00, 0x00FF0000, - 0, Blit_3or4_to_3or4__inversed_rgb, + SET_ALPHA | COPY_ALPHA }, + { 0x00FF0000, 0x0000FF00, 0x000000FF, 4, 0x000000FF, 0x0000FF00, 0x00FF0000, + 0, Blit_3or4_to_3or4__inversed_rgb, #if HAVE_FAST_WRITE_INT8 - NO_ALPHA | + NO_ALPHA | #endif - SET_ALPHA | COPY_ALPHA}, + SET_ALPHA | COPY_ALPHA }, /* RGB 888 and RGB 565 */ - {0x00FF0000, 0x0000FF00, 0x000000FF, 2, 0x0000F800, 0x000007E0, 0x0000001F, - 0, Blit_RGB888_RGB565, NO_ALPHA}, - {0x00FF0000, 0x0000FF00, 0x000000FF, 2, 0x00007C00, 0x000003E0, 0x0000001F, - 0, Blit_RGB888_RGB555, NO_ALPHA}, + { 0x00FF0000, 0x0000FF00, 0x000000FF, 2, 0x0000F800, 0x000007E0, 0x0000001F, + 0, Blit_RGB888_RGB565, NO_ALPHA }, + { 0x00FF0000, 0x0000FF00, 0x000000FF, 2, 0x00007C00, 0x000003E0, 0x0000001F, + 0, Blit_RGB888_RGB555, NO_ALPHA }, /* Default for 32-bit RGB source, used if no other blitter matches */ - {0, 0, 0, 0, 0, 0, 0, 0, BlitNtoN, 0} + { 0, 0, 0, 0, 0, 0, 0, 0, BlitNtoN, 0 } }; static const struct blit_table *const normal_blit[] = { @@ -3356,8 +3342,7 @@ static const struct blit_table *const normal_blit[] = { /* Mask matches table, or table entry is zero */ #define MASKOK(x, y) (((x) == (y)) || ((y) == 0x00000000)) -SDL_BlitFunc -SDL_CalculateBlitN(SDL_Surface * surface) +SDL_BlitFunc SDL_CalculateBlitN(SDL_Surface *surface) { SDL_PixelFormat *srcfmt; SDL_PixelFormat *dstfmt; @@ -3371,7 +3356,7 @@ SDL_CalculateBlitN(SDL_Surface * surface) /* We don't support destinations less than 8-bits */ if (dstfmt->BitsPerPixel < 8) { - return (NULL); + return NULL; } switch (surface->map->info.flags & ~SDL_COPY_RLE_MASK) { @@ -3384,9 +3369,9 @@ SDL_CalculateBlitN(SDL_Surface * surface) (srcfmt->Bmask == 0x000000FF)) { blitfun = Blit_RGB888_index8; } else if ((srcfmt->BytesPerPixel == 4) && - (srcfmt->Rmask == 0x3FF00000) && - (srcfmt->Gmask == 0x000FFC00) && - (srcfmt->Bmask == 0x000003FF)) { + (srcfmt->Rmask == 0x3FF00000) && + (srcfmt->Gmask == 0x000FFC00) && + (srcfmt->Bmask == 0x000003FF)) { blitfun = Blit_RGB101010_index8; } else { blitfun = BlitNto1; @@ -3394,8 +3379,9 @@ SDL_CalculateBlitN(SDL_Surface * surface) } else { /* Now the meat, choose the blitter we want */ Uint32 a_need = NO_ALPHA; - if (dstfmt->Amask) + if (dstfmt->Amask) { a_need = srcfmt->Amask ? COPY_ALPHA : SET_ALPHA; + } table = normal_blit[srcfmt->BytesPerPixel - 1]; for (which = 0; table[which].dstbpp; ++which) { if (MASKOK(srcfmt->Rmask, table[which].srcR) && @@ -3407,25 +3393,26 @@ SDL_CalculateBlitN(SDL_Surface * surface) dstfmt->BytesPerPixel == table[which].dstbpp && (a_need & table[which].alpha) == a_need && ((table[which].blit_features & GetBlitFeatures()) == - table[which].blit_features)) + table[which].blit_features)) { break; + } } blitfun = table[which].blitfunc; - if (blitfun == BlitNtoN) { /* default C fallback catch-all. Slow! */ + if (blitfun == BlitNtoN) { /* default C fallback catch-all. Slow! */ if (srcfmt->format == SDL_PIXELFORMAT_ARGB2101010) { blitfun = Blit2101010toN; } else if (dstfmt->format == SDL_PIXELFORMAT_ARGB2101010) { blitfun = BlitNto2101010; } else if (srcfmt->BytesPerPixel == 4 && - dstfmt->BytesPerPixel == 4 && - srcfmt->Rmask == dstfmt->Rmask && - srcfmt->Gmask == dstfmt->Gmask && - srcfmt->Bmask == dstfmt->Bmask) { + dstfmt->BytesPerPixel == 4 && + srcfmt->Rmask == dstfmt->Rmask && + srcfmt->Gmask == dstfmt->Gmask && + srcfmt->Bmask == dstfmt->Bmask) { if (a_need == COPY_ALPHA) { if (srcfmt->Amask == dstfmt->Amask) { /* Fastpath C fallback: 32bit RGBA<->RGBA blit with matching RGBA */ - blitfun = Blit4to4CopyAlpha; + blitfun = SDL_BlitCopy; } else { blitfun = BlitNtoNCopyAlpha; } @@ -3438,25 +3425,24 @@ SDL_CalculateBlitN(SDL_Surface * surface) } } } - return (blitfun); + return blitfun; case SDL_COPY_COLORKEY: /* colorkey blit: Here we don't have too many options, mostly because RLE is the preferred fast way to deal with this. If a particular case turns out to be useful we'll add it. */ - if (srcfmt->BytesPerPixel == 2 && surface->map->identity) + if (srcfmt->BytesPerPixel == 2 && surface->map->identity != 0) { return Blit2to2Key; - else if (dstfmt->BytesPerPixel == 1) + } else if (dstfmt->BytesPerPixel == 1) { return BlitNto1Key; - else { -#if SDL_ALTIVEC_BLITTERS - if ((srcfmt->BytesPerPixel == 4) && (dstfmt->BytesPerPixel == 4) - && SDL_HasAltiVec()) { + } else { +#ifdef SDL_ALTIVEC_BLITTERS + if ((srcfmt->BytesPerPixel == 4) && (dstfmt->BytesPerPixel == 4) && SDL_HasAltiVec()) { return Blit32to32KeyAltivec; } else #endif - if (srcfmt->Amask && dstfmt->Amask) { + if (srcfmt->Amask && dstfmt->Amask) { return BlitNtoNKeyCopyAlpha; } else { return BlitNtoNKey; diff --git a/SDL2-2.0.12/src/video/SDL_blit_auto.c b/SDL2-2.30.5/src/video/SDL_blit_auto.c similarity index 84% rename from SDL2-2.0.12/src/video/SDL_blit_auto.c rename to SDL2-2.30.5/src/video/SDL_blit_auto.c index 7aff395..b05dc4a 100644 --- a/SDL2-2.0.12/src/video/SDL_blit_auto.c +++ b/SDL2-2.30.5/src/video/SDL_blit_auto.c @@ -1,7 +1,7 @@ /* DO NOT EDIT! This file is generated by sdlgenblit.pl */ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,7 +23,7 @@ #if SDL_HAVE_BLIT_AUTO -/* *INDENT-OFF* */ +/* *INDENT-OFF* */ /* clang-format off */ #include "SDL_video.h" #include "SDL_blit.h" @@ -31,33 +31,24 @@ static void SDL_Blit_RGB888_RGB888_Scale(SDL_BlitInfo *info) { - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); *dst = *src; posx += incx; ++dst; @@ -123,33 +114,24 @@ static void SDL_Blit_RGB888_RGB888_Blend_Scale(SDL_BlitInfo *info) Uint32 srcR, srcG, srcB; Uint32 dstpixel; Uint32 dstR, dstG, dstB; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; dstpixel = *dst; @@ -225,33 +207,24 @@ static void SDL_Blit_RGB888_RGB888_Modulate_Scale(SDL_BlitInfo *info) const Uint32 modulateB = info->b; Uint32 pixel; Uint32 R, G, B; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; R = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); B = (Uint8)pixel; if (flags & SDL_COPY_MODULATE_COLOR) { @@ -348,33 +321,24 @@ static void SDL_Blit_RGB888_RGB888_Modulate_Blend_Scale(SDL_BlitInfo *info) Uint32 srcR, srcG, srcB; Uint32 dstpixel; Uint32 dstR, dstG, dstB; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; dstpixel = *dst; @@ -428,33 +392,24 @@ static void SDL_Blit_RGB888_BGR888_Scale(SDL_BlitInfo *info) { Uint32 pixel; Uint32 R, G, B; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; R = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); B = (Uint8)pixel; pixel = (B << 16) | (G << 8) | R; @@ -523,33 +478,24 @@ static void SDL_Blit_RGB888_BGR888_Blend_Scale(SDL_BlitInfo *info) Uint32 srcR, srcG, srcB; Uint32 dstpixel; Uint32 dstR, dstG, dstB; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; dstpixel = *dst; @@ -625,33 +571,24 @@ static void SDL_Blit_RGB888_BGR888_Modulate_Scale(SDL_BlitInfo *info) const Uint32 modulateB = info->b; Uint32 pixel; Uint32 R, G, B; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; R = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); B = (Uint8)pixel; if (flags & SDL_COPY_MODULATE_COLOR) { @@ -748,33 +685,24 @@ static void SDL_Blit_RGB888_BGR888_Modulate_Blend_Scale(SDL_BlitInfo *info) Uint32 srcR, srcG, srcB; Uint32 dstpixel; Uint32 dstR, dstG, dstB; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; dstpixel = *dst; @@ -828,37 +756,26 @@ static void SDL_Blit_RGB888_ARGB8888_Scale(SDL_BlitInfo *info) { Uint32 pixel; const Uint32 A = 0xFF; - Uint32 R, G, B; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; - R = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); B = (Uint8)pixel; - pixel = (A << 24) | (R << 16) | (G << 8) | B; + pixel |= (A << 24); *dst = pixel; posx += incx; ++dst; @@ -906,7 +823,6 @@ static void SDL_Blit_RGB888_ARGB8888_Blend(SDL_BlitInfo *info) dstR = (srcR * dstR) / 255; dstG = (srcG * dstG) / 255; dstB = (srcB * dstB) / 255; - dstA = 0xFF; break; } dstpixel = (dstA << 24) | (dstR << 16) | (dstG << 8) | dstB; @@ -926,33 +842,24 @@ static void SDL_Blit_RGB888_ARGB8888_Blend_Scale(SDL_BlitInfo *info) Uint32 srcR, srcG, srcB; Uint32 dstpixel; Uint32 dstR, dstG, dstB, dstA; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; dstpixel = *dst; @@ -978,7 +885,6 @@ static void SDL_Blit_RGB888_ARGB8888_Blend_Scale(SDL_BlitInfo *info) dstR = (srcR * dstR) / 255; dstG = (srcG * dstG) / 255; dstB = (srcB * dstB) / 255; - dstA = 0xFF; break; } dstpixel = (dstA << 24) | (dstR << 16) | (dstG << 8) | dstB; @@ -1034,33 +940,24 @@ static void SDL_Blit_RGB888_ARGB8888_Modulate_Scale(SDL_BlitInfo *info) Uint32 pixel; const Uint32 A = (flags & SDL_COPY_MODULATE_ALPHA) ? modulateA : 0xFF; Uint32 R, G, B; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; R = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); B = (Uint8)pixel; if (flags & SDL_COPY_MODULATE_COLOR) { @@ -1134,7 +1031,6 @@ static void SDL_Blit_RGB888_ARGB8888_Modulate_Blend(SDL_BlitInfo *info) dstR = ((srcR * dstR) + (dstR * (255 - srcA))) / 255; if (dstR > 255) dstR = 255; dstG = ((srcG * dstG) + (dstG * (255 - srcA))) / 255; if (dstG > 255) dstG = 255; dstB = ((srcB * dstB) + (dstB * (255 - srcA))) / 255; if (dstB > 255) dstB = 255; - dstA = ((srcA * dstA) + (dstA * (255 - srcA))) / 255; if (dstA > 255) dstA = 255; break; } dstpixel = (dstA << 24) | (dstR << 16) | (dstG << 8) | dstB; @@ -1159,33 +1055,24 @@ static void SDL_Blit_RGB888_ARGB8888_Modulate_Blend_Scale(SDL_BlitInfo *info) Uint32 srcR, srcG, srcB; Uint32 dstpixel; Uint32 dstR, dstG, dstB, dstA; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; dstpixel = *dst; @@ -1224,7 +1111,6 @@ static void SDL_Blit_RGB888_ARGB8888_Modulate_Blend_Scale(SDL_BlitInfo *info) dstR = ((srcR * dstR) + (dstR * (255 - srcA))) / 255; if (dstR > 255) dstR = 255; dstG = ((srcG * dstG) + (dstG * (255 - srcA))) / 255; if (dstG > 255) dstG = 255; dstB = ((srcB * dstB) + (dstB * (255 - srcA))) / 255; if (dstB > 255) dstB = 255; - dstA = ((srcA * dstA) + (dstA * (255 - srcA))) / 255; if (dstA > 255) dstA = 255; break; } dstpixel = (dstA << 24) | (dstR << 16) | (dstG << 8) | dstB; @@ -1241,33 +1127,24 @@ static void SDL_Blit_BGR888_RGB888_Scale(SDL_BlitInfo *info) { Uint32 pixel; Uint32 R, G, B; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; B = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); R = (Uint8)pixel; pixel = (R << 16) | (G << 8) | B; @@ -1336,33 +1213,24 @@ static void SDL_Blit_BGR888_RGB888_Blend_Scale(SDL_BlitInfo *info) Uint32 srcR, srcG, srcB; Uint32 dstpixel; Uint32 dstR, dstG, dstB; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; dstpixel = *dst; @@ -1438,33 +1306,24 @@ static void SDL_Blit_BGR888_RGB888_Modulate_Scale(SDL_BlitInfo *info) const Uint32 modulateB = info->b; Uint32 pixel; Uint32 R, G, B; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; B = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); R = (Uint8)pixel; if (flags & SDL_COPY_MODULATE_COLOR) { @@ -1561,33 +1420,24 @@ static void SDL_Blit_BGR888_RGB888_Modulate_Blend_Scale(SDL_BlitInfo *info) Uint32 srcR, srcG, srcB; Uint32 dstpixel; Uint32 dstR, dstG, dstB; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; dstpixel = *dst; @@ -1639,33 +1489,24 @@ static void SDL_Blit_BGR888_RGB888_Modulate_Blend_Scale(SDL_BlitInfo *info) static void SDL_Blit_BGR888_BGR888_Scale(SDL_BlitInfo *info) { - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); *dst = *src; posx += incx; ++dst; @@ -1731,33 +1572,24 @@ static void SDL_Blit_BGR888_BGR888_Blend_Scale(SDL_BlitInfo *info) Uint32 srcR, srcG, srcB; Uint32 dstpixel; Uint32 dstR, dstG, dstB; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; dstpixel = *dst; @@ -1833,33 +1665,24 @@ static void SDL_Blit_BGR888_BGR888_Modulate_Scale(SDL_BlitInfo *info) const Uint32 modulateB = info->b; Uint32 pixel; Uint32 R, G, B; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; B = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); R = (Uint8)pixel; if (flags & SDL_COPY_MODULATE_COLOR) { @@ -1956,33 +1779,24 @@ static void SDL_Blit_BGR888_BGR888_Modulate_Blend_Scale(SDL_BlitInfo *info) Uint32 srcR, srcG, srcB; Uint32 dstpixel; Uint32 dstR, dstG, dstB; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; dstpixel = *dst; @@ -2037,33 +1851,24 @@ static void SDL_Blit_BGR888_ARGB8888_Scale(SDL_BlitInfo *info) Uint32 pixel; const Uint32 A = 0xFF; Uint32 R, G, B; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; B = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); R = (Uint8)pixel; pixel = (A << 24) | (R << 16) | (G << 8) | B; @@ -2114,7 +1919,6 @@ static void SDL_Blit_BGR888_ARGB8888_Blend(SDL_BlitInfo *info) dstR = (srcR * dstR) / 255; dstG = (srcG * dstG) / 255; dstB = (srcB * dstB) / 255; - dstA = 0xFF; break; } dstpixel = (dstA << 24) | (dstR << 16) | (dstG << 8) | dstB; @@ -2134,33 +1938,24 @@ static void SDL_Blit_BGR888_ARGB8888_Blend_Scale(SDL_BlitInfo *info) Uint32 srcR, srcG, srcB; Uint32 dstpixel; Uint32 dstR, dstG, dstB, dstA; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; dstpixel = *dst; @@ -2186,7 +1981,6 @@ static void SDL_Blit_BGR888_ARGB8888_Blend_Scale(SDL_BlitInfo *info) dstR = (srcR * dstR) / 255; dstG = (srcG * dstG) / 255; dstB = (srcB * dstB) / 255; - dstA = 0xFF; break; } dstpixel = (dstA << 24) | (dstR << 16) | (dstG << 8) | dstB; @@ -2242,33 +2036,24 @@ static void SDL_Blit_BGR888_ARGB8888_Modulate_Scale(SDL_BlitInfo *info) Uint32 pixel; const Uint32 A = (flags & SDL_COPY_MODULATE_ALPHA) ? modulateA : 0xFF; Uint32 R, G, B; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; B = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); R = (Uint8)pixel; if (flags & SDL_COPY_MODULATE_COLOR) { @@ -2342,7 +2127,6 @@ static void SDL_Blit_BGR888_ARGB8888_Modulate_Blend(SDL_BlitInfo *info) dstR = ((srcR * dstR) + (dstR * (255 - srcA))) / 255; if (dstR > 255) dstR = 255; dstG = ((srcG * dstG) + (dstG * (255 - srcA))) / 255; if (dstG > 255) dstG = 255; dstB = ((srcB * dstB) + (dstB * (255 - srcA))) / 255; if (dstB > 255) dstB = 255; - dstA = ((srcA * dstA) + (dstA * (255 - srcA))) / 255; if (dstA > 255) dstA = 255; break; } dstpixel = (dstA << 24) | (dstR << 16) | (dstG << 8) | dstB; @@ -2367,33 +2151,24 @@ static void SDL_Blit_BGR888_ARGB8888_Modulate_Blend_Scale(SDL_BlitInfo *info) Uint32 srcR, srcG, srcB; Uint32 dstpixel; Uint32 dstR, dstG, dstB, dstA; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; dstpixel = *dst; @@ -2432,7 +2207,6 @@ static void SDL_Blit_BGR888_ARGB8888_Modulate_Blend_Scale(SDL_BlitInfo *info) dstR = ((srcR * dstR) + (dstR * (255 - srcA))) / 255; if (dstR > 255) dstR = 255; dstG = ((srcG * dstG) + (dstG * (255 - srcA))) / 255; if (dstG > 255) dstG = 255; dstB = ((srcB * dstB) + (dstB * (255 - srcA))) / 255; if (dstB > 255) dstB = 255; - dstA = ((srcA * dstA) + (dstA * (255 - srcA))) / 255; if (dstA > 255) dstA = 255; break; } dstpixel = (dstA << 24) | (dstR << 16) | (dstG << 8) | dstB; @@ -2448,37 +2222,26 @@ static void SDL_Blit_BGR888_ARGB8888_Modulate_Blend_Scale(SDL_BlitInfo *info) static void SDL_Blit_ARGB8888_RGB888_Scale(SDL_BlitInfo *info) { Uint32 pixel; - Uint32 R, G, B; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; - R = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); B = (Uint8)pixel; - pixel = (R << 16) | (G << 8) | B; + pixel &= 0xFFFFFF; *dst = pixel; posx += incx; ++dst; @@ -2552,33 +2315,24 @@ static void SDL_Blit_ARGB8888_RGB888_Blend_Scale(SDL_BlitInfo *info) Uint32 srcR, srcG, srcB, srcA; Uint32 dstpixel; Uint32 dstR, dstG, dstB; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24); dstpixel = *dst; @@ -2662,33 +2416,24 @@ static void SDL_Blit_ARGB8888_RGB888_Modulate_Scale(SDL_BlitInfo *info) const Uint32 modulateB = info->b; Uint32 pixel; Uint32 R, G, B; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; R = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); B = (Uint8)pixel; if (flags & SDL_COPY_MODULATE_COLOR) { @@ -2786,33 +2531,24 @@ static void SDL_Blit_ARGB8888_RGB888_Modulate_Blend_Scale(SDL_BlitInfo *info) Uint32 srcR, srcG, srcB, srcA; Uint32 dstpixel; Uint32 dstR, dstG, dstB; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24); dstpixel = *dst; @@ -2869,33 +2605,24 @@ static void SDL_Blit_ARGB8888_BGR888_Scale(SDL_BlitInfo *info) { Uint32 pixel; Uint32 R, G, B; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; R = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); B = (Uint8)pixel; pixel = (B << 16) | (G << 8) | R; @@ -2972,33 +2699,24 @@ static void SDL_Blit_ARGB8888_BGR888_Blend_Scale(SDL_BlitInfo *info) Uint32 srcR, srcG, srcB, srcA; Uint32 dstpixel; Uint32 dstR, dstG, dstB; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24); dstpixel = *dst; @@ -3082,33 +2800,24 @@ static void SDL_Blit_ARGB8888_BGR888_Modulate_Scale(SDL_BlitInfo *info) const Uint32 modulateB = info->b; Uint32 pixel; Uint32 R, G, B; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; R = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); B = (Uint8)pixel; if (flags & SDL_COPY_MODULATE_COLOR) { @@ -3206,33 +2915,24 @@ static void SDL_Blit_ARGB8888_BGR888_Modulate_Blend_Scale(SDL_BlitInfo *info) Uint32 srcR, srcG, srcB, srcA; Uint32 dstpixel; Uint32 dstR, dstG, dstB; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24); dstpixel = *dst; @@ -3287,33 +2987,24 @@ static void SDL_Blit_ARGB8888_BGR888_Modulate_Blend_Scale(SDL_BlitInfo *info) static void SDL_Blit_ARGB8888_ARGB8888_Scale(SDL_BlitInfo *info) { - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); *dst = *src; posx += incx; ++dst; @@ -3369,7 +3060,6 @@ static void SDL_Blit_ARGB8888_ARGB8888_Blend(SDL_BlitInfo *info) dstR = ((srcR * dstR) + (dstR * (255 - srcA))) / 255; if (dstR > 255) dstR = 255; dstG = ((srcG * dstG) + (dstG * (255 - srcA))) / 255; if (dstG > 255) dstG = 255; dstB = ((srcB * dstB) + (dstB * (255 - srcA))) / 255; if (dstB > 255) dstB = 255; - dstA = ((srcA * dstA) + (dstA * (255 - srcA))) / 255; if (dstA > 255) dstA = 255; break; } dstpixel = (dstA << 24) | (dstR << 16) | (dstG << 8) | dstB; @@ -3389,33 +3079,24 @@ static void SDL_Blit_ARGB8888_ARGB8888_Blend_Scale(SDL_BlitInfo *info) Uint32 srcR, srcG, srcB, srcA; Uint32 dstpixel; Uint32 dstR, dstG, dstB, dstA; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24); dstpixel = *dst; @@ -3449,7 +3130,6 @@ static void SDL_Blit_ARGB8888_ARGB8888_Blend_Scale(SDL_BlitInfo *info) dstR = ((srcR * dstR) + (dstR * (255 - srcA))) / 255; if (dstR > 255) dstR = 255; dstG = ((srcG * dstG) + (dstG * (255 - srcA))) / 255; if (dstG > 255) dstG = 255; dstB = ((srcB * dstB) + (dstB * (255 - srcA))) / 255; if (dstB > 255) dstB = 255; - dstA = ((srcA * dstA) + (dstA * (255 - srcA))) / 255; if (dstA > 255) dstA = 255; break; } dstpixel = (dstA << 24) | (dstR << 16) | (dstG << 8) | dstB; @@ -3506,33 +3186,24 @@ static void SDL_Blit_ARGB8888_ARGB8888_Modulate_Scale(SDL_BlitInfo *info) const Uint32 modulateA = info->a; Uint32 pixel; Uint32 R, G, B, A; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; R = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); B = (Uint8)pixel; A = (Uint8)(pixel >> 24); if (flags & SDL_COPY_MODULATE_COLOR) { @@ -3611,7 +3282,6 @@ static void SDL_Blit_ARGB8888_ARGB8888_Modulate_Blend(SDL_BlitInfo *info) dstR = ((srcR * dstR) + (dstR * (255 - srcA))) / 255; if (dstR > 255) dstR = 255; dstG = ((srcG * dstG) + (dstG * (255 - srcA))) / 255; if (dstG > 255) dstG = 255; dstB = ((srcB * dstB) + (dstB * (255 - srcA))) / 255; if (dstB > 255) dstB = 255; - dstA = ((srcA * dstA) + (dstA * (255 - srcA))) / 255; if (dstA > 255) dstA = 255; break; } dstpixel = (dstA << 24) | (dstR << 16) | (dstG << 8) | dstB; @@ -3635,33 +3305,24 @@ static void SDL_Blit_ARGB8888_ARGB8888_Modulate_Blend_Scale(SDL_BlitInfo *info) Uint32 srcR, srcG, srcB, srcA; Uint32 dstpixel; Uint32 dstR, dstG, dstB, dstA; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcR = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcB = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24); dstpixel = *dst; @@ -3703,7 +3364,6 @@ static void SDL_Blit_ARGB8888_ARGB8888_Modulate_Blend_Scale(SDL_BlitInfo *info) dstR = ((srcR * dstR) + (dstR * (255 - srcA))) / 255; if (dstR > 255) dstR = 255; dstG = ((srcG * dstG) + (dstG * (255 - srcA))) / 255; if (dstG > 255) dstG = 255; dstB = ((srcB * dstB) + (dstB * (255 - srcA))) / 255; if (dstB > 255) dstB = 255; - dstA = ((srcA * dstA) + (dstA * (255 - srcA))) / 255; if (dstA > 255) dstA = 255; break; } dstpixel = (dstA << 24) | (dstR << 16) | (dstG << 8) | dstB; @@ -3719,37 +3379,26 @@ static void SDL_Blit_ARGB8888_ARGB8888_Modulate_Blend_Scale(SDL_BlitInfo *info) static void SDL_Blit_RGBA8888_RGB888_Scale(SDL_BlitInfo *info) { Uint32 pixel; - Uint32 R, G, B; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; - R = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); B = (Uint8)(pixel >> 8); - pixel = (R << 16) | (G << 8) | B; + pixel >>= 8; *dst = pixel; posx += incx; ++dst; @@ -3823,33 +3472,24 @@ static void SDL_Blit_RGBA8888_RGB888_Blend_Scale(SDL_BlitInfo *info) Uint32 srcR, srcG, srcB, srcA; Uint32 dstpixel; Uint32 dstR, dstG, dstB; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcR = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcB = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel; dstpixel = *dst; @@ -3933,33 +3573,24 @@ static void SDL_Blit_RGBA8888_RGB888_Modulate_Scale(SDL_BlitInfo *info) const Uint32 modulateB = info->b; Uint32 pixel; Uint32 R, G, B; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; R = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); B = (Uint8)(pixel >> 8); if (flags & SDL_COPY_MODULATE_COLOR) { @@ -4057,33 +3688,24 @@ static void SDL_Blit_RGBA8888_RGB888_Modulate_Blend_Scale(SDL_BlitInfo *info) Uint32 srcR, srcG, srcB, srcA; Uint32 dstpixel; Uint32 dstR, dstG, dstB; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcR = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcB = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel; dstpixel = *dst; @@ -4140,33 +3762,24 @@ static void SDL_Blit_RGBA8888_BGR888_Scale(SDL_BlitInfo *info) { Uint32 pixel; Uint32 R, G, B; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; R = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); B = (Uint8)(pixel >> 8); pixel = (B << 16) | (G << 8) | R; @@ -4243,33 +3856,24 @@ static void SDL_Blit_RGBA8888_BGR888_Blend_Scale(SDL_BlitInfo *info) Uint32 srcR, srcG, srcB, srcA; Uint32 dstpixel; Uint32 dstR, dstG, dstB; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcR = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcB = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel; dstpixel = *dst; @@ -4353,33 +3957,24 @@ static void SDL_Blit_RGBA8888_BGR888_Modulate_Scale(SDL_BlitInfo *info) const Uint32 modulateB = info->b; Uint32 pixel; Uint32 R, G, B; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; R = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); B = (Uint8)(pixel >> 8); if (flags & SDL_COPY_MODULATE_COLOR) { @@ -4477,33 +4072,24 @@ static void SDL_Blit_RGBA8888_BGR888_Modulate_Blend_Scale(SDL_BlitInfo *info) Uint32 srcR, srcG, srcB, srcA; Uint32 dstpixel; Uint32 dstR, dstG, dstB; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcR = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcB = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel; dstpixel = *dst; @@ -4559,37 +4145,26 @@ static void SDL_Blit_RGBA8888_BGR888_Modulate_Blend_Scale(SDL_BlitInfo *info) static void SDL_Blit_RGBA8888_ARGB8888_Scale(SDL_BlitInfo *info) { Uint32 pixel; - Uint32 R, G, B, A; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; - R = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); B = (Uint8)(pixel >> 8); A = (Uint8)pixel; - pixel = (A << 24) | (R << 16) | (G << 8) | B; + pixel = (pixel >> 8) | (pixel << 24); *dst = pixel; posx += incx; ++dst; @@ -4645,7 +4220,6 @@ static void SDL_Blit_RGBA8888_ARGB8888_Blend(SDL_BlitInfo *info) dstR = ((srcR * dstR) + (dstR * (255 - srcA))) / 255; if (dstR > 255) dstR = 255; dstG = ((srcG * dstG) + (dstG * (255 - srcA))) / 255; if (dstG > 255) dstG = 255; dstB = ((srcB * dstB) + (dstB * (255 - srcA))) / 255; if (dstB > 255) dstB = 255; - dstA = ((srcA * dstA) + (dstA * (255 - srcA))) / 255; if (dstA > 255) dstA = 255; break; } dstpixel = (dstA << 24) | (dstR << 16) | (dstG << 8) | dstB; @@ -4665,33 +4239,24 @@ static void SDL_Blit_RGBA8888_ARGB8888_Blend_Scale(SDL_BlitInfo *info) Uint32 srcR, srcG, srcB, srcA; Uint32 dstpixel; Uint32 dstR, dstG, dstB, dstA; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcR = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcB = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel; dstpixel = *dst; @@ -4725,7 +4290,6 @@ static void SDL_Blit_RGBA8888_ARGB8888_Blend_Scale(SDL_BlitInfo *info) dstR = ((srcR * dstR) + (dstR * (255 - srcA))) / 255; if (dstR > 255) dstR = 255; dstG = ((srcG * dstG) + (dstG * (255 - srcA))) / 255; if (dstG > 255) dstG = 255; dstB = ((srcB * dstB) + (dstB * (255 - srcA))) / 255; if (dstB > 255) dstB = 255; - dstA = ((srcA * dstA) + (dstA * (255 - srcA))) / 255; if (dstA > 255) dstA = 255; break; } dstpixel = (dstA << 24) | (dstR << 16) | (dstG << 8) | dstB; @@ -4782,33 +4346,24 @@ static void SDL_Blit_RGBA8888_ARGB8888_Modulate_Scale(SDL_BlitInfo *info) const Uint32 modulateA = info->a; Uint32 pixel; Uint32 R, G, B, A; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; R = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); B = (Uint8)(pixel >> 8); A = (Uint8)pixel; if (flags & SDL_COPY_MODULATE_COLOR) { @@ -4887,7 +4442,6 @@ static void SDL_Blit_RGBA8888_ARGB8888_Modulate_Blend(SDL_BlitInfo *info) dstR = ((srcR * dstR) + (dstR * (255 - srcA))) / 255; if (dstR > 255) dstR = 255; dstG = ((srcG * dstG) + (dstG * (255 - srcA))) / 255; if (dstG > 255) dstG = 255; dstB = ((srcB * dstB) + (dstB * (255 - srcA))) / 255; if (dstB > 255) dstB = 255; - dstA = ((srcA * dstA) + (dstA * (255 - srcA))) / 255; if (dstA > 255) dstA = 255; break; } dstpixel = (dstA << 24) | (dstR << 16) | (dstG << 8) | dstB; @@ -4911,33 +4465,24 @@ static void SDL_Blit_RGBA8888_ARGB8888_Modulate_Blend_Scale(SDL_BlitInfo *info) Uint32 srcR, srcG, srcB, srcA; Uint32 dstpixel; Uint32 dstR, dstG, dstB, dstA; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcR = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcB = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel; dstpixel = *dst; @@ -4979,7 +4524,6 @@ static void SDL_Blit_RGBA8888_ARGB8888_Modulate_Blend_Scale(SDL_BlitInfo *info) dstR = ((srcR * dstR) + (dstR * (255 - srcA))) / 255; if (dstR > 255) dstR = 255; dstG = ((srcG * dstG) + (dstG * (255 - srcA))) / 255; if (dstG > 255) dstG = 255; dstB = ((srcB * dstB) + (dstB * (255 - srcA))) / 255; if (dstB > 255) dstB = 255; - dstA = ((srcA * dstA) + (dstA * (255 - srcA))) / 255; if (dstA > 255) dstA = 255; break; } dstpixel = (dstA << 24) | (dstR << 16) | (dstG << 8) | dstB; @@ -4996,33 +4540,24 @@ static void SDL_Blit_ABGR8888_RGB888_Scale(SDL_BlitInfo *info) { Uint32 pixel; Uint32 R, G, B; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; B = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); R = (Uint8)pixel; pixel = (R << 16) | (G << 8) | B; @@ -5099,33 +4634,24 @@ static void SDL_Blit_ABGR8888_RGB888_Blend_Scale(SDL_BlitInfo *info) Uint32 srcR, srcG, srcB, srcA; Uint32 dstpixel; Uint32 dstR, dstG, dstB; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24); dstpixel = *dst; @@ -5209,33 +4735,24 @@ static void SDL_Blit_ABGR8888_RGB888_Modulate_Scale(SDL_BlitInfo *info) const Uint32 modulateB = info->b; Uint32 pixel; Uint32 R, G, B; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; B = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); R = (Uint8)pixel; if (flags & SDL_COPY_MODULATE_COLOR) { @@ -5333,33 +4850,24 @@ static void SDL_Blit_ABGR8888_RGB888_Modulate_Blend_Scale(SDL_BlitInfo *info) Uint32 srcR, srcG, srcB, srcA; Uint32 dstpixel; Uint32 dstR, dstG, dstB; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24); dstpixel = *dst; @@ -5415,37 +4923,26 @@ static void SDL_Blit_ABGR8888_RGB888_Modulate_Blend_Scale(SDL_BlitInfo *info) static void SDL_Blit_ABGR8888_BGR888_Scale(SDL_BlitInfo *info) { Uint32 pixel; - Uint32 R, G, B; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; - B = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); R = (Uint8)pixel; - pixel = (B << 16) | (G << 8) | R; + pixel &= 0xFFFFFF; *dst = pixel; posx += incx; ++dst; @@ -5519,33 +5016,24 @@ static void SDL_Blit_ABGR8888_BGR888_Blend_Scale(SDL_BlitInfo *info) Uint32 srcR, srcG, srcB, srcA; Uint32 dstpixel; Uint32 dstR, dstG, dstB; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24); dstpixel = *dst; @@ -5629,33 +5117,24 @@ static void SDL_Blit_ABGR8888_BGR888_Modulate_Scale(SDL_BlitInfo *info) const Uint32 modulateB = info->b; Uint32 pixel; Uint32 R, G, B; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; B = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); R = (Uint8)pixel; if (flags & SDL_COPY_MODULATE_COLOR) { @@ -5753,33 +5232,24 @@ static void SDL_Blit_ABGR8888_BGR888_Modulate_Blend_Scale(SDL_BlitInfo *info) Uint32 srcR, srcG, srcB, srcA; Uint32 dstpixel; Uint32 dstR, dstG, dstB; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24); dstpixel = *dst; @@ -5836,33 +5306,24 @@ static void SDL_Blit_ABGR8888_ARGB8888_Scale(SDL_BlitInfo *info) { Uint32 pixel; Uint32 R, G, B, A; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; B = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); R = (Uint8)pixel; A = (Uint8)(pixel >> 24); pixel = (A << 24) | (R << 16) | (G << 8) | B; @@ -5921,7 +5382,6 @@ static void SDL_Blit_ABGR8888_ARGB8888_Blend(SDL_BlitInfo *info) dstR = ((srcR * dstR) + (dstR * (255 - srcA))) / 255; if (dstR > 255) dstR = 255; dstG = ((srcG * dstG) + (dstG * (255 - srcA))) / 255; if (dstG > 255) dstG = 255; dstB = ((srcB * dstB) + (dstB * (255 - srcA))) / 255; if (dstB > 255) dstB = 255; - dstA = ((srcA * dstA) + (dstA * (255 - srcA))) / 255; if (dstA > 255) dstA = 255; break; } dstpixel = (dstA << 24) | (dstR << 16) | (dstG << 8) | dstB; @@ -5941,33 +5401,24 @@ static void SDL_Blit_ABGR8888_ARGB8888_Blend_Scale(SDL_BlitInfo *info) Uint32 srcR, srcG, srcB, srcA; Uint32 dstpixel; Uint32 dstR, dstG, dstB, dstA; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24); dstpixel = *dst; @@ -6001,7 +5452,6 @@ static void SDL_Blit_ABGR8888_ARGB8888_Blend_Scale(SDL_BlitInfo *info) dstR = ((srcR * dstR) + (dstR * (255 - srcA))) / 255; if (dstR > 255) dstR = 255; dstG = ((srcG * dstG) + (dstG * (255 - srcA))) / 255; if (dstG > 255) dstG = 255; dstB = ((srcB * dstB) + (dstB * (255 - srcA))) / 255; if (dstB > 255) dstB = 255; - dstA = ((srcA * dstA) + (dstA * (255 - srcA))) / 255; if (dstA > 255) dstA = 255; break; } dstpixel = (dstA << 24) | (dstR << 16) | (dstG << 8) | dstB; @@ -6058,33 +5508,24 @@ static void SDL_Blit_ABGR8888_ARGB8888_Modulate_Scale(SDL_BlitInfo *info) const Uint32 modulateA = info->a; Uint32 pixel; Uint32 R, G, B, A; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; B = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); R = (Uint8)pixel; A = (Uint8)(pixel >> 24); if (flags & SDL_COPY_MODULATE_COLOR) { @@ -6163,7 +5604,6 @@ static void SDL_Blit_ABGR8888_ARGB8888_Modulate_Blend(SDL_BlitInfo *info) dstR = ((srcR * dstR) + (dstR * (255 - srcA))) / 255; if (dstR > 255) dstR = 255; dstG = ((srcG * dstG) + (dstG * (255 - srcA))) / 255; if (dstG > 255) dstG = 255; dstB = ((srcB * dstB) + (dstB * (255 - srcA))) / 255; if (dstB > 255) dstB = 255; - dstA = ((srcA * dstA) + (dstA * (255 - srcA))) / 255; if (dstA > 255) dstA = 255; break; } dstpixel = (dstA << 24) | (dstR << 16) | (dstG << 8) | dstB; @@ -6187,33 +5627,24 @@ static void SDL_Blit_ABGR8888_ARGB8888_Modulate_Blend_Scale(SDL_BlitInfo *info) Uint32 srcR, srcG, srcB, srcA; Uint32 dstpixel; Uint32 dstR, dstG, dstB, dstA; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcB = (Uint8)(srcpixel >> 16); srcG = (Uint8)(srcpixel >> 8); srcR = (Uint8)srcpixel; srcA = (Uint8)(srcpixel >> 24); dstpixel = *dst; @@ -6255,7 +5686,6 @@ static void SDL_Blit_ABGR8888_ARGB8888_Modulate_Blend_Scale(SDL_BlitInfo *info) dstR = ((srcR * dstR) + (dstR * (255 - srcA))) / 255; if (dstR > 255) dstR = 255; dstG = ((srcG * dstG) + (dstG * (255 - srcA))) / 255; if (dstG > 255) dstG = 255; dstB = ((srcB * dstB) + (dstB * (255 - srcA))) / 255; if (dstB > 255) dstB = 255; - dstA = ((srcA * dstA) + (dstA * (255 - srcA))) / 255; if (dstA > 255) dstA = 255; break; } dstpixel = (dstA << 24) | (dstR << 16) | (dstG << 8) | dstB; @@ -6272,33 +5702,24 @@ static void SDL_Blit_BGRA8888_RGB888_Scale(SDL_BlitInfo *info) { Uint32 pixel; Uint32 R, G, B; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; B = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); R = (Uint8)(pixel >> 8); pixel = (R << 16) | (G << 8) | B; @@ -6375,33 +5796,24 @@ static void SDL_Blit_BGRA8888_RGB888_Blend_Scale(SDL_BlitInfo *info) Uint32 srcR, srcG, srcB, srcA; Uint32 dstpixel; Uint32 dstR, dstG, dstB; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcB = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcR = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel; dstpixel = *dst; @@ -6485,33 +5897,24 @@ static void SDL_Blit_BGRA8888_RGB888_Modulate_Scale(SDL_BlitInfo *info) const Uint32 modulateB = info->b; Uint32 pixel; Uint32 R, G, B; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; B = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); R = (Uint8)(pixel >> 8); if (flags & SDL_COPY_MODULATE_COLOR) { @@ -6609,33 +6012,24 @@ static void SDL_Blit_BGRA8888_RGB888_Modulate_Blend_Scale(SDL_BlitInfo *info) Uint32 srcR, srcG, srcB, srcA; Uint32 dstpixel; Uint32 dstR, dstG, dstB; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcB = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcR = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel; dstpixel = *dst; @@ -6691,37 +6085,26 @@ static void SDL_Blit_BGRA8888_RGB888_Modulate_Blend_Scale(SDL_BlitInfo *info) static void SDL_Blit_BGRA8888_BGR888_Scale(SDL_BlitInfo *info) { Uint32 pixel; - Uint32 R, G, B; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; - B = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); R = (Uint8)(pixel >> 8); - pixel = (B << 16) | (G << 8) | R; + pixel >>= 8; *dst = pixel; posx += incx; ++dst; @@ -6795,33 +6178,24 @@ static void SDL_Blit_BGRA8888_BGR888_Blend_Scale(SDL_BlitInfo *info) Uint32 srcR, srcG, srcB, srcA; Uint32 dstpixel; Uint32 dstR, dstG, dstB; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcB = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcR = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel; dstpixel = *dst; @@ -6905,33 +6279,24 @@ static void SDL_Blit_BGRA8888_BGR888_Modulate_Scale(SDL_BlitInfo *info) const Uint32 modulateB = info->b; Uint32 pixel; Uint32 R, G, B; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; B = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); R = (Uint8)(pixel >> 8); if (flags & SDL_COPY_MODULATE_COLOR) { @@ -7029,33 +6394,24 @@ static void SDL_Blit_BGRA8888_BGR888_Modulate_Blend_Scale(SDL_BlitInfo *info) Uint32 srcR, srcG, srcB, srcA; Uint32 dstpixel; Uint32 dstR, dstG, dstB; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcB = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcR = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel; dstpixel = *dst; @@ -7112,33 +6468,24 @@ static void SDL_Blit_BGRA8888_ARGB8888_Scale(SDL_BlitInfo *info) { Uint32 pixel; Uint32 R, G, B, A; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; B = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); R = (Uint8)(pixel >> 8); A = (Uint8)pixel; pixel = (A << 24) | (R << 16) | (G << 8) | B; @@ -7197,7 +6544,6 @@ static void SDL_Blit_BGRA8888_ARGB8888_Blend(SDL_BlitInfo *info) dstR = ((srcR * dstR) + (dstR * (255 - srcA))) / 255; if (dstR > 255) dstR = 255; dstG = ((srcG * dstG) + (dstG * (255 - srcA))) / 255; if (dstG > 255) dstG = 255; dstB = ((srcB * dstB) + (dstB * (255 - srcA))) / 255; if (dstB > 255) dstB = 255; - dstA = ((srcA * dstA) + (dstA * (255 - srcA))) / 255; if (dstA > 255) dstA = 255; break; } dstpixel = (dstA << 24) | (dstR << 16) | (dstG << 8) | dstB; @@ -7217,33 +6563,24 @@ static void SDL_Blit_BGRA8888_ARGB8888_Blend_Scale(SDL_BlitInfo *info) Uint32 srcR, srcG, srcB, srcA; Uint32 dstpixel; Uint32 dstR, dstG, dstB, dstA; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcB = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcR = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel; dstpixel = *dst; @@ -7277,7 +6614,6 @@ static void SDL_Blit_BGRA8888_ARGB8888_Blend_Scale(SDL_BlitInfo *info) dstR = ((srcR * dstR) + (dstR * (255 - srcA))) / 255; if (dstR > 255) dstR = 255; dstG = ((srcG * dstG) + (dstG * (255 - srcA))) / 255; if (dstG > 255) dstG = 255; dstB = ((srcB * dstB) + (dstB * (255 - srcA))) / 255; if (dstB > 255) dstB = 255; - dstA = ((srcA * dstA) + (dstA * (255 - srcA))) / 255; if (dstA > 255) dstA = 255; break; } dstpixel = (dstA << 24) | (dstR << 16) | (dstG << 8) | dstB; @@ -7334,33 +6670,24 @@ static void SDL_Blit_BGRA8888_ARGB8888_Modulate_Scale(SDL_BlitInfo *info) const Uint32 modulateA = info->a; Uint32 pixel; Uint32 R, G, B, A; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); pixel = *src; B = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); R = (Uint8)(pixel >> 8); A = (Uint8)pixel; if (flags & SDL_COPY_MODULATE_COLOR) { @@ -7439,7 +6766,6 @@ static void SDL_Blit_BGRA8888_ARGB8888_Modulate_Blend(SDL_BlitInfo *info) dstR = ((srcR * dstR) + (dstR * (255 - srcA))) / 255; if (dstR > 255) dstR = 255; dstG = ((srcG * dstG) + (dstG * (255 - srcA))) / 255; if (dstG > 255) dstG = 255; dstB = ((srcB * dstB) + (dstB * (255 - srcA))) / 255; if (dstB > 255) dstB = 255; - dstA = ((srcA * dstA) + (dstA * (255 - srcA))) / 255; if (dstA > 255) dstA = 255; break; } dstpixel = (dstA << 24) | (dstR << 16) | (dstG << 8) | dstB; @@ -7463,33 +6789,24 @@ static void SDL_Blit_BGRA8888_ARGB8888_Modulate_Blend_Scale(SDL_BlitInfo *info) Uint32 srcR, srcG, srcB, srcA; Uint32 dstpixel; Uint32 dstR, dstG, dstB, dstA; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { Uint32 *src = 0; Uint32 *dst = (Uint32 *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); - } + srcx = posx >> 16; + src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4)); srcpixel = *src; srcB = (Uint8)(srcpixel >> 24); srcG = (Uint8)(srcpixel >> 16); srcR = (Uint8)(srcpixel >> 8); srcA = (Uint8)srcpixel; dstpixel = *dst; @@ -7531,7 +6848,6 @@ static void SDL_Blit_BGRA8888_ARGB8888_Modulate_Blend_Scale(SDL_BlitInfo *info) dstR = ((srcR * dstR) + (dstR * (255 - srcA))) / 255; if (dstR > 255) dstR = 255; dstG = ((srcG * dstG) + (dstG * (255 - srcA))) / 255; if (dstG > 255) dstG = 255; dstB = ((srcB * dstB) + (dstB * (255 - srcA))) / 255; if (dstB > 255) dstB = 255; - dstA = ((srcA * dstA) + (dstA * (255 - srcA))) / 255; if (dstA > 255) dstA = 255; break; } dstpixel = (dstA << 24) | (dstR << 16) | (dstG << 8) | dstB; @@ -7674,7 +6990,7 @@ SDL_BlitFuncEntry SDL_GeneratedBlitFuncTable[] = { { 0, 0, 0, 0, NULL } }; -/* *INDENT-ON* */ +/* *INDENT-ON* */ /* clang-format on */ #endif /* SDL_HAVE_BLIT_AUTO */ diff --git a/SDL2-2.0.12/src/video/SDL_blit_auto.h b/SDL2-2.30.5/src/video/SDL_blit_auto.h similarity index 88% rename from SDL2-2.0.12/src/video/SDL_blit_auto.h rename to SDL2-2.30.5/src/video/SDL_blit_auto.h index 53deacb..1b7f227 100644 --- a/SDL2-2.0.12/src/video/SDL_blit_auto.h +++ b/SDL2-2.30.5/src/video/SDL_blit_auto.h @@ -1,7 +1,7 @@ /* DO NOT EDIT! This file is generated by sdlgenblit.pl */ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,11 +23,11 @@ #if SDL_HAVE_BLIT_AUTO -/* *INDENT-OFF* */ +/* *INDENT-OFF* */ /* clang-format off */ extern SDL_BlitFuncEntry SDL_GeneratedBlitFuncTable[]; -/* *INDENT-ON* */ +/* *INDENT-ON* */ /* clang-format on */ #endif /* SDL_HAVE_BLIT_AUTO */ diff --git a/SDL2-2.0.12/src/video/SDL_blit_copy.c b/SDL2-2.30.5/src/video/SDL_blit_copy.c similarity index 62% rename from SDL2-2.0.12/src/video/SDL_blit_copy.c rename to SDL2-2.30.5/src/video/SDL_blit_copy.c index 6dbc36f..47dafb5 100644 --- a/SDL2-2.0.12/src/video/SDL_blit_copy.c +++ b/SDL2-2.30.5/src/video/SDL_blit_copy.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -24,48 +24,46 @@ #include "SDL_blit.h" #include "SDL_blit_copy.h" - #ifdef __SSE__ /* This assumes 16-byte aligned src and dst */ -static SDL_INLINE void -SDL_memcpySSE(Uint8 * dst, const Uint8 * src, int len) +static SDL_INLINE void SDL_memcpySSE(Uint8 *dst, const Uint8 *src, int len) { int i; __m128 values[4]; for (i = len / 64; i--;) { - _mm_prefetch(src, _MM_HINT_NTA); - values[0] = *(__m128 *) (src + 0); - values[1] = *(__m128 *) (src + 16); - values[2] = *(__m128 *) (src + 32); - values[3] = *(__m128 *) (src + 48); - _mm_stream_ps((float *) (dst + 0), values[0]); - _mm_stream_ps((float *) (dst + 16), values[1]); - _mm_stream_ps((float *) (dst + 32), values[2]); - _mm_stream_ps((float *) (dst + 48), values[3]); + _mm_prefetch((const char *)src, _MM_HINT_NTA); + values[0] = *(__m128 *)(src + 0); + values[1] = *(__m128 *)(src + 16); + values[2] = *(__m128 *)(src + 32); + values[3] = *(__m128 *)(src + 48); + _mm_stream_ps((float *)(dst + 0), values[0]); + _mm_stream_ps((float *)(dst + 16), values[1]); + _mm_stream_ps((float *)(dst + 32), values[2]); + _mm_stream_ps((float *)(dst + 48), values[3]); src += 64; dst += 64; } - if (len & 63) + if (len & 63) { SDL_memcpy(dst, src, len & 63); + } } #endif /* __SSE__ */ #ifdef __MMX__ #ifdef _MSC_VER -#pragma warning(disable:4799) +#pragma warning(disable : 4799) #endif -static SDL_INLINE void -SDL_memcpyMMX(Uint8 * dst, const Uint8 * src, int len) +static SDL_INLINE void SDL_memcpyMMX(Uint8 *dst, const Uint8 *src, int len) { - const int remain = (len & 63); + int remain = len & 63; int i; - __m64* d64 = (__m64*)dst; - __m64* s64 = (__m64*)src; + __m64 *d64 = (__m64 *)dst; + __m64 *s64 = (__m64 *)src; - for(i= len / 64; i--;) { + for (i = len / 64; i--;) { d64[0] = s64[0]; d64[1] = s64[1]; d64[2] = s64[2]; @@ -79,16 +77,18 @@ SDL_memcpyMMX(Uint8 * dst, const Uint8 * src, int len) s64 += 8; } - if (remain) - { + if (remain) { const int skip = len - remain; - SDL_memcpy(dst + skip, src + skip, remain); + dst += skip; + src += skip; + while (remain--) { + *dst++ = *src++; + } } } #endif /* __MMX__ */ -void -SDL_BlitCopy(SDL_BlitInfo * info) +void SDL_BlitCopy(SDL_BlitInfo *info) { SDL_bool overlap; Uint8 *src, *dst; @@ -104,33 +104,33 @@ SDL_BlitCopy(SDL_BlitInfo * info) /* Properly handle overlapping blits */ if (src < dst) { - overlap = (dst < (src + h*srcskip)); + overlap = (dst < (src + h * srcskip)); } else { - overlap = (src < (dst + h*dstskip)); + overlap = (src < (dst + h * dstskip)); } if (overlap) { - if ( dst < src ) { - while ( h-- ) { - SDL_memmove(dst, src, w); - src += srcskip; - dst += dstskip; - } + if (dst < src) { + while (h--) { + SDL_memmove(dst, src, w); + src += srcskip; + dst += dstskip; + } } else { - src += ((h-1) * srcskip); - dst += ((h-1) * dstskip); - while ( h-- ) { - SDL_memmove(dst, src, w); - src -= srcskip; - dst -= dstskip; - } + src += ((h - 1) * srcskip); + dst += ((h - 1) * dstskip); + while (h--) { + SDL_memmove(dst, src, w); + src -= srcskip; + dst -= dstskip; + } } return; } #ifdef __SSE__ if (SDL_HasSSE() && - !((uintptr_t) src & 15) && !(srcskip & 15) && - !((uintptr_t) dst & 15) && !(dstskip & 15)) { + !((uintptr_t)src & 15) && !(srcskip & 15) && + !((uintptr_t)dst & 15) && !(dstskip & 15)) { while (h--) { SDL_memcpySSE(dst, src, w); src += srcskip; diff --git a/SDL2-2.0.12/src/video/SDL_blit_copy.h b/SDL2-2.30.5/src/video/SDL_blit_copy.h similarity index 90% rename from SDL2-2.0.12/src/video/SDL_blit_copy.h rename to SDL2-2.30.5/src/video/SDL_blit_copy.h index 16c4e8d..0979a87 100644 --- a/SDL2-2.0.12/src/video/SDL_blit_copy.h +++ b/SDL2-2.30.5/src/video/SDL_blit_copy.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -22,7 +22,7 @@ #ifndef SDL_blit_copy_h_ #define SDL_blit_copy_h_ -void SDL_BlitCopy(SDL_BlitInfo * info); +void SDL_BlitCopy(SDL_BlitInfo *info); #endif /* SDL_blit_copy_h_ */ diff --git a/SDL2-2.0.12/src/video/SDL_blit_slow.c b/SDL2-2.30.5/src/video/SDL_blit_slow.c similarity index 62% rename from SDL2-2.0.12/src/video/SDL_blit_slow.c rename to SDL2-2.30.5/src/video/SDL_blit_slow.c index 1c0b43e..7696dcf 100644 --- a/SDL2-2.0.12/src/video/SDL_blit_slow.c +++ b/SDL2-2.30.5/src/video/SDL_blit_slow.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -24,11 +24,26 @@ #include "SDL_blit.h" #include "SDL_blit_slow.h" +#define FORMAT_ALPHA 0 +#define FORMAT_NO_ALPHA -1 +#define FORMAT_2101010 1 +#define FORMAT_HAS_ALPHA(format) format == 0 +#define FORMAT_HAS_NO_ALPHA(format) format < 0 +static int SDL_INLINE detect_format(SDL_PixelFormat *pf) +{ + if (pf->format == SDL_PIXELFORMAT_ARGB2101010) { + return FORMAT_2101010; + } else if (pf->Amask) { + return FORMAT_ALPHA; + } else { + return FORMAT_NO_ALPHA; + } +} + /* The ONE TRUE BLITTER * This puppy has to handle all the unoptimized cases - yes, it's slow. */ -void -SDL_Blit_Slow(SDL_BlitInfo * info) +void SDL_Blit_Slow(SDL_BlitInfo *info) { const int flags = info->flags; const Uint32 modulateR = info->r; @@ -39,53 +54,51 @@ SDL_Blit_Slow(SDL_BlitInfo * info) Uint32 srcR, srcG, srcB, srcA; Uint32 dstpixel; Uint32 dstR, dstG, dstB, dstA; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; SDL_PixelFormat *src_fmt = info->src_fmt; SDL_PixelFormat *dst_fmt = info->dst_fmt; int srcbpp = src_fmt->BytesPerPixel; int dstbpp = dst_fmt->BytesPerPixel; + int srcfmt_val; + int dstfmt_val; Uint32 rgbmask = ~src_fmt->Amask; Uint32 ckey = info->colorkey & rgbmask; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + srcfmt_val = detect_format(src_fmt); + dstfmt_val = detect_format(dst_fmt); + + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; /* start at the middle of pixel */ while (info->dst_h--) { Uint8 *src = 0; Uint8 *dst = info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; /* start at the middle of pixel */ + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = - (info->src + (srcy * info->src_pitch) + (srcx * srcbpp)); - } - if (src_fmt->Amask) { - DISEMBLE_RGBA(src, srcbpp, src_fmt, srcpixel, srcR, srcG, - srcB, srcA); - } else { - DISEMBLE_RGB(src, srcbpp, src_fmt, srcpixel, srcR, srcG, - srcB); + srcx = posx >> 16; + src = (info->src + (srcy * info->src_pitch) + (srcx * srcbpp)); + + if (FORMAT_HAS_ALPHA(srcfmt_val)) { + DISEMBLE_RGBA(src, srcbpp, src_fmt, srcpixel, srcR, srcG, srcB, srcA); + } else if (FORMAT_HAS_NO_ALPHA(srcfmt_val)) { + DISEMBLE_RGB(src, srcbpp, src_fmt, srcpixel, srcR, srcG, srcB); srcA = 0xFF; + } else { + /* SDL_PIXELFORMAT_ARGB2101010 */ + srcpixel = *((Uint32 *)(src)); + RGBA_FROM_ARGB2101010(srcpixel, srcR, srcG, srcB, srcA); } + if (flags & SDL_COPY_COLORKEY) { /* srcpixel isn't set for 24 bpp */ if (srcbpp == 3) { srcpixel = (srcR << src_fmt->Rshift) | - (srcG << src_fmt->Gshift) | (srcB << src_fmt->Bshift); + (srcG << src_fmt->Gshift) | (srcB << src_fmt->Bshift); } if ((srcpixel & rgbmask) == ckey) { posx += incx; @@ -93,13 +106,20 @@ SDL_Blit_Slow(SDL_BlitInfo * info) continue; } } - if (dst_fmt->Amask) { - DISEMBLE_RGBA(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG, - dstB, dstA); + if ((flags & (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_MUL))) { + if (FORMAT_HAS_ALPHA(dstfmt_val)) { + DISEMBLE_RGBA(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG, dstB, dstA); + } else if (FORMAT_HAS_NO_ALPHA(dstfmt_val)) { + DISEMBLE_RGB(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG, dstB); + dstA = 0xFF; + } else { + /* SDL_PIXELFORMAT_ARGB2101010 */ + dstpixel = *((Uint32 *) (dst)); + RGBA_FROM_ARGB2101010(dstpixel, dstR, dstG, dstB, dstA); + } } else { - DISEMBLE_RGB(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG, - dstB); - dstA = 0xFF; + /* don't care */ + dstR = dstG = dstB = dstA = 0; } if (flags & SDL_COPY_MODULATE_COLOR) { @@ -133,14 +153,17 @@ SDL_Blit_Slow(SDL_BlitInfo * info) break; case SDL_COPY_ADD: dstR = srcR + dstR; - if (dstR > 255) + if (dstR > 255) { dstR = 255; + } dstG = srcG + dstG; - if (dstG > 255) + if (dstG > 255) { dstG = 255; + } dstB = srcB + dstB; - if (dstB > 255) + if (dstB > 255) { dstB = 255; + } break; case SDL_COPY_MOD: dstR = (srcR * dstR) / 255; @@ -149,23 +172,28 @@ SDL_Blit_Slow(SDL_BlitInfo * info) break; case SDL_COPY_MUL: dstR = ((srcR * dstR) + (dstR * (255 - srcA))) / 255; - if (dstR > 255) + if (dstR > 255) { dstR = 255; + } dstG = ((srcG * dstG) + (dstG * (255 - srcA))) / 255; - if (dstG > 255) + if (dstG > 255) { dstG = 255; + } dstB = ((srcB * dstB) + (dstB * (255 - srcA))) / 255; - if (dstB > 255) + if (dstB > 255) { dstB = 255; - dstA = ((srcA * dstA) + (dstA * (255 - srcA))) / 255; - if (dstA > 255) - dstA = 255; + } break; } - if (dst_fmt->Amask) { + if (FORMAT_HAS_ALPHA(dstfmt_val)) { ASSEMBLE_RGBA(dst, dstbpp, dst_fmt, dstR, dstG, dstB, dstA); - } else { + } else if (FORMAT_HAS_NO_ALPHA(dstfmt_val)) { ASSEMBLE_RGB(dst, dstbpp, dst_fmt, dstR, dstG, dstB); + } else { + /* SDL_PIXELFORMAT_ARGB2101010 */ + Uint32 pixel; + ARGB2101010_FROM_RGBA(pixel, dstR, dstG, dstB, dstA); + *(Uint32 *)dst = pixel; } posx += incx; dst += dstbpp; diff --git a/SDL2-2.0.12/src/video/SDL_blit_slow.h b/SDL2-2.30.5/src/video/SDL_blit_slow.h similarity index 90% rename from SDL2-2.0.12/src/video/SDL_blit_slow.h rename to SDL2-2.30.5/src/video/SDL_blit_slow.h index 082654e..05b1dca 100644 --- a/SDL2-2.0.12/src/video/SDL_blit_slow.h +++ b/SDL2-2.30.5/src/video/SDL_blit_slow.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -24,7 +24,7 @@ #include "../SDL_internal.h" -extern void SDL_Blit_Slow(SDL_BlitInfo * info); +extern void SDL_Blit_Slow(SDL_BlitInfo *info); #endif /* SDL_blit_slow_h_ */ diff --git a/SDL2-2.0.12/src/video/SDL_bmp.c b/SDL2-2.30.5/src/video/SDL_bmp.c similarity index 71% rename from SDL2-2.0.12/src/video/SDL_bmp.c rename to SDL2-2.30.5/src/video/SDL_bmp.c index 40ac0eb..10e99fb 100644 --- a/SDL2-2.0.12/src/video/SDL_bmp.c +++ b/SDL2-2.30.5/src/video/SDL_bmp.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -34,7 +34,6 @@ #include "SDL_hints.h" #include "SDL_video.h" -#include "SDL_assert.h" #include "SDL_endian.h" #include "SDL_pixels_c.h" @@ -42,19 +41,19 @@ /* Compression encodings for BMP files */ #ifndef BI_RGB -#define BI_RGB 0 -#define BI_RLE8 1 -#define BI_RLE4 2 -#define BI_BITFIELDS 3 +#define BI_RGB 0 +#define BI_RLE8 1 +#define BI_RLE4 2 +#define BI_BITFIELDS 3 #endif /* Logical color space values for BMP files */ #ifndef LCS_WINDOWS_COLOR_SPACE /* 0x57696E20 == "Win " */ -#define LCS_WINDOWS_COLOR_SPACE 0x57696E20 +#define LCS_WINDOWS_COLOR_SPACE 0x57696E20 #endif -static int readRlePixels(SDL_Surface * surface, SDL_RWops * src, int isRle8) +static SDL_bool readRlePixels(SDL_Surface *surface, SDL_RWops *src, int isRle8) { /* | Sets the surface pixels from src. A bmp image is upside down. @@ -62,35 +61,46 @@ static int readRlePixels(SDL_Surface * surface, SDL_RWops * src, int isRle8) int pitch = surface->pitch; int height = surface->h; Uint8 *start = (Uint8 *)surface->pixels; - Uint8 *end = start + (height*pitch); - Uint8 *bits = end-pitch, *spot; + Uint8 *end = start + (height * pitch); + Uint8 *bits = end - pitch, *spot; int ofs = 0; Uint8 ch; Uint8 needsPad; -#define COPY_PIXEL(x) spot = &bits[ofs++]; if(spot >= start && spot < end) *spot = (x) +#define COPY_PIXEL(x) \ + spot = &bits[ofs++]; \ + if (spot >= start && spot < end) \ + *spot = (x) for (;;) { - if (!SDL_RWread(src, &ch, 1, 1)) return 1; + if (!SDL_RWread(src, &ch, 1, 1)) { + return SDL_TRUE; + } /* | encoded mode starts with a run length, and then a byte | with two colour indexes to alternate between for the run */ if (ch) { Uint8 pixel; - if (!SDL_RWread(src, &pixel, 1, 1)) return 1; - if (isRle8) { /* 256-color bitmap, compressed */ + if (!SDL_RWread(src, &pixel, 1, 1)) { + return SDL_TRUE; + } + if (isRle8) { /* 256-color bitmap, compressed */ do { COPY_PIXEL(pixel); } while (--ch); - } else { /* 16-color bitmap, compressed */ + } else { /* 16-color bitmap, compressed */ Uint8 pixel0 = pixel >> 4; Uint8 pixel1 = pixel & 0x0F; for (;;) { COPY_PIXEL(pixel0); /* even count, high nibble */ - if (!--ch) break; + if (!--ch) { + break; + } COPY_PIXEL(pixel1); /* odd count, low nibble */ - if (!--ch) break; + if (!--ch) { + break; + } } } } else { @@ -99,41 +109,57 @@ static int readRlePixels(SDL_Surface * surface, SDL_RWops * src, int isRle8) | a cursor move, or some absolute data. | zero tag may be absolute mode or an escape */ - if (!SDL_RWread(src, &ch, 1, 1)) return 1; + if (!SDL_RWread(src, &ch, 1, 1)) { + return SDL_TRUE; + } switch (ch) { - case 0: /* end of line */ + case 0: /* end of line */ ofs = 0; - bits -= pitch; /* go to previous */ + bits -= pitch; /* go to previous */ break; - case 1: /* end of bitmap */ - return 0; /* success! */ - case 2: /* delta */ - if (!SDL_RWread(src, &ch, 1, 1)) return 1; + case 1: /* end of bitmap */ + return SDL_FALSE; /* success! */ + case 2: /* delta */ + if (!SDL_RWread(src, &ch, 1, 1)) { + return SDL_TRUE; + } ofs += ch; - if (!SDL_RWread(src, &ch, 1, 1)) return 1; + if (!SDL_RWread(src, &ch, 1, 1)) { + return SDL_TRUE; + } bits -= (ch * pitch); break; - default: /* no compression */ + default: /* no compression */ if (isRle8) { needsPad = (ch & 1); do { Uint8 pixel; - if (!SDL_RWread(src, &pixel, 1, 1)) return 1; + if (!SDL_RWread(src, &pixel, 1, 1)) { + return SDL_TRUE; + } COPY_PIXEL(pixel); } while (--ch); } else { - needsPad = (((ch+1)>>1) & 1); /* (ch+1)>>1: bytes size */ + needsPad = (((ch + 1) >> 1) & 1); /* (ch+1)>>1: bytes size */ for (;;) { Uint8 pixel; - if (!SDL_RWread(src, &pixel, 1, 1)) return 1; + if (!SDL_RWread(src, &pixel, 1, 1)) { + return SDL_TRUE; + } COPY_PIXEL(pixel >> 4); - if (!--ch) break; + if (!--ch) { + break; + } COPY_PIXEL(pixel & 0x0F); - if (!--ch) break; + if (!--ch) { + break; + } } } /* pad at even boundary */ - if (needsPad && !SDL_RWread(src, &ch, 1, 1)) return 1; + if (needsPad && !SDL_RWread(src, &ch, 1, 1)) { + return SDL_TRUE; + } break; } } @@ -149,7 +175,7 @@ static void CorrectAlphaChannel(SDL_Surface *surface) #else int alphaChannelOffset = 3; #endif - Uint8 *alpha = ((Uint8*)surface->pixels) + alphaChannelOffset; + Uint8 *alpha = ((Uint8 *)surface->pixels) + alphaChannelOffset; Uint8 *end = alpha + surface->h * surface->pitch; while (alpha < end) { @@ -161,7 +187,7 @@ static void CorrectAlphaChannel(SDL_Surface *surface) } if (!hasAlpha) { - alpha = ((Uint8*)surface->pixels) + alphaChannelOffset; + alpha = ((Uint8 *)surface->pixels) + alphaChannelOffset; while (alpha < end) { *alpha = SDL_ALPHA_OPAQUE; alpha += 4; @@ -169,8 +195,7 @@ static void CorrectAlphaChannel(SDL_Surface *surface) } } -SDL_Surface * -SDL_LoadBMP_RW(SDL_RWops * src, int freesrc) +SDL_Surface *SDL_LoadBMP_RW(SDL_RWops *src, int freesrc) { SDL_bool was_error; Sint64 fp_offset = 0; @@ -213,13 +238,18 @@ SDL_LoadBMP_RW(SDL_RWops * src, int freesrc) /* Make sure we are passed a valid data source */ surface = NULL; was_error = SDL_FALSE; - if (src == NULL) { + if (!src) { + SDL_InvalidParamError("src"); was_error = SDL_TRUE; goto done; } /* Read in the BMP file header */ fp_offset = SDL_RWtell(src); + if (fp_offset < 0) { + was_error = SDL_TRUE; + goto done; + } SDL_ClearError(); if (SDL_RWread(src, magic, 1, 2) != 2) { SDL_Error(SDL_EFREAD); @@ -234,13 +264,13 @@ SDL_LoadBMP_RW(SDL_RWops * src, int freesrc) /* bfSize = */ SDL_ReadLE32(src); /* bfReserved1 = */ SDL_ReadLE16(src); /* bfReserved2 = */ SDL_ReadLE16(src); - bfOffBits = SDL_ReadLE32(src); + bfOffBits = SDL_ReadLE32(src); /* Read the Win32 BITMAPINFOHEADER */ biSize = SDL_ReadLE32(src); - if (biSize == 12) { /* really old BITMAPCOREHEADER */ - biWidth = (Uint32) SDL_ReadLE16(src); - biHeight = (Uint32) SDL_ReadLE16(src); + if (biSize == 12) { /* really old BITMAPCOREHEADER */ + biWidth = (Uint32)SDL_ReadLE16(src); + biHeight = (Uint32)SDL_ReadLE16(src); /* biPlanes = */ SDL_ReadLE16(src); biBitCount = SDL_ReadLE16(src); biCompression = BI_RGB; @@ -249,7 +279,7 @@ SDL_LoadBMP_RW(SDL_RWops * src, int freesrc) /* biYPelsPerMeter = 0; */ biClrUsed = 0; /* biClrImportant = 0; */ - } else if (biSize >= 40) { /* some version of BITMAPINFOHEADER */ + } else if (biSize >= 40) { /* some version of BITMAPINFOHEADER */ Uint32 headerSize; biWidth = SDL_ReadLE32(src); biHeight = SDL_ReadLE32(src); @@ -278,18 +308,18 @@ SDL_LoadBMP_RW(SDL_RWops * src, int freesrc) Bmask = SDL_ReadLE32(src); /* ...v3 adds an alpha mask. */ - if (biSize >= 56) { /* BITMAPV3INFOHEADER; adds alpha mask */ + if (biSize >= 56) { /* BITMAPV3INFOHEADER; adds alpha mask */ haveAlphaMask = SDL_TRUE; Amask = SDL_ReadLE32(src); } } else { /* the mask fields are ignored for v2+ headers if not BI_BITFIELD. */ - if (biSize >= 52) { /* BITMAPV2INFOHEADER; adds RGB masks */ + if (biSize >= 52) { /* BITMAPV2INFOHEADER; adds RGB masks */ /*Rmask = */ SDL_ReadLE32(src); /*Gmask = */ SDL_ReadLE32(src); /*Bmask = */ SDL_ReadLE32(src); } - if (biSize >= 56) { /* BITMAPV3INFOHEADER; adds alpha mask */ + if (biSize >= 56) { /* BITMAPV3INFOHEADER; adds alpha mask */ /*Amask = */ SDL_ReadLE32(src); } } @@ -301,13 +331,13 @@ SDL_LoadBMP_RW(SDL_RWops * src, int freesrc) } /* skip any header bytes we didn't handle... */ - headerSize = (Uint32) (SDL_RWtell(src) - (fp_offset + 14)); + headerSize = (Uint32)(SDL_RWtell(src) - (fp_offset + 14)); if (biSize > headerSize) { SDL_RWseek(src, (biSize - headerSize), RW_SEEK_CUR); } } if (biWidth <= 0 || biHeight == 0) { - SDL_SetError("BMP file with bad dimensions (%dx%d)", biWidth, biHeight); + SDL_SetError("BMP file with bad dimensions (%" SDL_PRIs32 "x%" SDL_PRIs32 ")", biWidth, biHeight); was_error = SDL_TRUE; goto done; } @@ -324,15 +354,15 @@ SDL_LoadBMP_RW(SDL_RWops * src, int freesrc) goto done; } - /* Expand 1 and 4 bit bitmaps to 8 bits per pixel */ + /* Expand 1, 2 and 4 bit bitmaps to 8 bits per pixel */ switch (biBitCount) { case 1: + case 2: case 4: ExpandBMP = biBitCount; biBitCount = 8; break; case 0: - case 2: case 3: case 5: case 6: @@ -384,7 +414,7 @@ SDL_LoadBMP_RW(SDL_RWops * src, int freesrc) break; case BI_BITFIELDS: - break; /* we handled this in the info header. */ + break; /* we handled this in the info header. */ default: break; @@ -394,7 +424,7 @@ SDL_LoadBMP_RW(SDL_RWops * src, int freesrc) surface = SDL_CreateRGBSurface(0, biWidth, biHeight, biBitCount, Rmask, Gmask, Bmask, Amask); - if (surface == NULL) { + if (!surface) { was_error = SDL_TRUE; goto done; } @@ -402,28 +432,40 @@ SDL_LoadBMP_RW(SDL_RWops * src, int freesrc) /* Load the palette, if any */ palette = (surface->format)->palette; if (palette) { - if (SDL_RWseek(src, fp_offset+14+biSize, RW_SEEK_SET) < 0) { + if (SDL_RWseek(src, fp_offset + 14 + biSize, RW_SEEK_SET) < 0) { SDL_Error(SDL_EFSEEK); was_error = SDL_TRUE; goto done; } - /* - | guich: always use 1<= 32) { /* we shift biClrUsed by this value later. */ + SDL_SetError("Unsupported or incorrect biBitCount field"); + was_error = SDL_TRUE; + goto done; + } + + if (biClrUsed == 0) { + biClrUsed = 1 << biBitCount; + } + + if (biClrUsed > (Uint32)palette->ncolors) { + biClrUsed = 1 << biBitCount; /* try forcing it? */ + if (biClrUsed > (Uint32)palette->ncolors) { + SDL_SetError("Unsupported or incorrect biClrUsed field"); + was_error = SDL_TRUE; + goto done; + } + } + if (biSize == 12) { - for (i = 0; i < (int) biClrUsed; ++i) { + for (i = 0; i < (int)biClrUsed; ++i) { SDL_RWread(src, &palette->colors[i].b, 1, 1); SDL_RWread(src, &palette->colors[i].g, 1, 1); SDL_RWread(src, &palette->colors[i].r, 1, 1); palette->colors[i].a = SDL_ALPHA_OPAQUE; } } else { - for (i = 0; i < (int) biClrUsed; ++i) { + for (i = 0; i < (int)biClrUsed; ++i) { SDL_RWread(src, &palette->colors[i].b, 1, 1); SDL_RWread(src, &palette->colors[i].g, 1, 1); SDL_RWread(src, &palette->colors[i].r, 1, 1); @@ -446,17 +488,23 @@ SDL_LoadBMP_RW(SDL_RWops * src, int freesrc) goto done; } if ((biCompression == BI_RLE4) || (biCompression == BI_RLE8)) { - was_error = (SDL_bool)readRlePixels(surface, src, biCompression == BI_RLE8); - if (was_error) SDL_SetError("Error reading from BMP"); + was_error = readRlePixels(surface, src, biCompression == BI_RLE8); + if (was_error) { + SDL_Error(SDL_EFREAD); + } goto done; } top = (Uint8 *)surface->pixels; - end = (Uint8 *)surface->pixels+(surface->h*surface->pitch); + end = (Uint8 *)surface->pixels + (surface->h * surface->pitch); switch (ExpandBMP) { case 1: bmpPitch = (biWidth + 7) >> 3; pad = (((bmpPitch) % 4) ? (4 - ((bmpPitch) % 4)) : 0); break; + case 2: + bmpPitch = (biWidth + 3) >> 2; + pad = (((bmpPitch) % 4) ? (4 - ((bmpPitch) % 4)) : 0); + break; case 4: bmpPitch = (biWidth + 1) >> 1; pad = (((bmpPitch) % 4) ? (4 - ((bmpPitch) % 4)) : 0); @@ -473,27 +521,28 @@ SDL_LoadBMP_RW(SDL_RWops * src, int freesrc) while (bits >= top && bits < end) { switch (ExpandBMP) { case 1: - case 4:{ - Uint8 pixel = 0; - int shift = (8 - ExpandBMP); - for (i = 0; i < surface->w; ++i) { - if (i % (8 / ExpandBMP) == 0) { - if (!SDL_RWread(src, &pixel, 1, 1)) { - SDL_SetError("Error reading from BMP"); - was_error = SDL_TRUE; - goto done; - } - } - bits[i] = (pixel >> shift); - if (bits[i] >= biClrUsed) { - SDL_SetError("A BMP image contains a pixel with a color out of the palette"); + case 2: + case 4: + { + Uint8 pixel = 0; + int shift = (8 - ExpandBMP); + for (i = 0; i < surface->w; ++i) { + if (i % (8 / ExpandBMP) == 0) { + if (!SDL_RWread(src, &pixel, 1, 1)) { + SDL_Error(SDL_EFREAD); was_error = SDL_TRUE; goto done; } - pixel <<= ExpandBMP; } + bits[i] = (pixel >> shift); + if (bits[i] >= biClrUsed) { + SDL_SetError("A BMP image contains a pixel with a color out of the palette"); + was_error = SDL_TRUE; + goto done; + } + pixel <<= ExpandBMP; } - break; + } break; default: if (SDL_RWread(src, bits, 1, surface->pitch) != surface->pitch) { @@ -515,19 +564,23 @@ SDL_LoadBMP_RW(SDL_RWops * src, int freesrc) case has already been taken care of above. */ switch (biBitCount) { case 15: - case 16:{ - Uint16 *pix = (Uint16 *) bits; - for (i = 0; i < surface->w; i++) - pix[i] = SDL_Swap16(pix[i]); - break; + case 16: + { + Uint16 *pix = (Uint16 *)bits; + for (i = 0; i < surface->w; i++) { + pix[i] = SDL_Swap16(pix[i]); } + break; + } - case 32:{ - Uint32 *pix = (Uint32 *) bits; - for (i = 0; i < surface->w; i++) - pix[i] = SDL_Swap32(pix[i]); - break; + case 32: + { + Uint32 *pix = (Uint32 *)bits; + for (i = 0; i < surface->w; i++) { + pix[i] = SDL_Swap32(pix[i]); } + break; + } } #endif break; @@ -548,28 +601,25 @@ SDL_LoadBMP_RW(SDL_RWops * src, int freesrc) if (correctAlpha) { CorrectAlphaChannel(surface); } - done: +done: if (was_error) { if (src) { SDL_RWseek(src, fp_offset, RW_SEEK_SET); } - if (surface) { - SDL_FreeSurface(surface); - } + SDL_FreeSurface(surface); surface = NULL; } if (freesrc && src) { SDL_RWclose(src); } - return (surface); + return surface; } -int -SDL_SaveBMP_RW(SDL_Surface * saveme, SDL_RWops * dst, int freedst) +int SDL_SaveBMP_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst) { Sint64 fp_offset; int i, pad; - SDL_Surface *surface; + SDL_Surface *intermediate_surface; Uint8 *bits; SDL_bool save32bit = SDL_FALSE; SDL_bool saveLegacyBMP = SDL_FALSE; @@ -600,41 +650,42 @@ SDL_SaveBMP_RW(SDL_Surface * saveme, SDL_RWops * dst, int freedst) Uint32 bV4BlueMask = 0; Uint32 bV4AlphaMask = 0; Uint32 bV4CSType = 0; - Sint32 bV4Endpoints[3 * 3] = {0}; + Sint32 bV4Endpoints[3 * 3] = { 0 }; Uint32 bV4GammaRed = 0; Uint32 bV4GammaGreen = 0; Uint32 bV4GammaBlue = 0; /* Make sure we have somewhere to save */ - surface = NULL; + intermediate_surface = NULL; if (dst) { #ifdef SAVE_32BIT_BMP /* We can save alpha information in a 32-bit BMP */ - if (saveme->format->BitsPerPixel >= 8 && (saveme->format->Amask || - saveme->map->info.flags & SDL_COPY_COLORKEY)) { + if (surface->format->BitsPerPixel >= 8 && + (surface->format->Amask != 0 || + surface->map->info.flags & SDL_COPY_COLORKEY)) { save32bit = SDL_TRUE; } #endif /* SAVE_32BIT_BMP */ - if (saveme->format->palette && !save32bit) { - if (saveme->format->BitsPerPixel == 8) { - surface = saveme; + if (surface->format->palette && !save32bit) { + if (surface->format->BitsPerPixel == 8) { + intermediate_surface = surface; } else { SDL_SetError("%d bpp BMP files not supported", - saveme->format->BitsPerPixel); + surface->format->BitsPerPixel); } - } else if ((saveme->format->BitsPerPixel == 24) && !save32bit && + } else if ((surface->format->BitsPerPixel == 24) && !save32bit && #if SDL_BYTEORDER == SDL_LIL_ENDIAN - (saveme->format->Rmask == 0x00FF0000) && - (saveme->format->Gmask == 0x0000FF00) && - (saveme->format->Bmask == 0x000000FF) + (surface->format->Rmask == 0x00FF0000) && + (surface->format->Gmask == 0x0000FF00) && + (surface->format->Bmask == 0x000000FF) #else - (saveme->format->Rmask == 0x000000FF) && - (saveme->format->Gmask == 0x0000FF00) && - (saveme->format->Bmask == 0x00FF0000) + (surface->format->Rmask == 0x000000FF) && + (surface->format->Gmask == 0x0000FF00) && + (surface->format->Bmask == 0x00FF0000) #endif - ) { - surface = saveme; + ) { + intermediate_surface = surface; } else { SDL_PixelFormat format; @@ -645,8 +696,8 @@ SDL_SaveBMP_RW(SDL_Surface * saveme, SDL_RWops * dst, int freedst) } else { SDL_InitFormat(&format, SDL_PIXELFORMAT_BGR24); } - surface = SDL_ConvertSurface(saveme, &format, 0); - if (!surface) { + intermediate_surface = SDL_ConvertSurface(surface, &format, 0); + if (!intermediate_surface) { SDL_SetError("Couldn't convert image to %d bpp", format.BitsPerPixel); } @@ -661,14 +712,14 @@ SDL_SaveBMP_RW(SDL_Surface * saveme, SDL_RWops * dst, int freedst) saveLegacyBMP = SDL_GetHintBoolean(SDL_HINT_BMP_SAVE_LEGACY_FORMAT, SDL_FALSE); } - if (surface && (SDL_LockSurface(surface) == 0)) { - const int bw = surface->w * surface->format->BytesPerPixel; + if (intermediate_surface && (SDL_LockSurface(intermediate_surface) == 0)) { + const int bw = intermediate_surface->w * intermediate_surface->format->BytesPerPixel; /* Set the BMP file header values */ - bfSize = 0; /* We'll write this when we're done */ + bfSize = 0; /* We'll write this when we're done */ bfReserved1 = 0; bfReserved2 = 0; - bfOffBits = 0; /* We'll write this when we're done */ + bfOffBits = 0; /* We'll write this when we're done */ /* Write the BMP file header values */ fp_offset = SDL_RWtell(dst); @@ -681,16 +732,16 @@ SDL_SaveBMP_RW(SDL_Surface * saveme, SDL_RWops * dst, int freedst) /* Set the BMP info values */ biSize = 40; - biWidth = surface->w; - biHeight = surface->h; + biWidth = intermediate_surface->w; + biHeight = intermediate_surface->h; biPlanes = 1; - biBitCount = surface->format->BitsPerPixel; + biBitCount = intermediate_surface->format->BitsPerPixel; biCompression = BI_RGB; - biSizeImage = surface->h * surface->pitch; + biSizeImage = intermediate_surface->h * intermediate_surface->pitch; biXPelsPerMeter = 0; biYPelsPerMeter = 0; - if (surface->format->palette) { - biClrUsed = surface->format->palette->ncolors; + if (intermediate_surface->format->palette) { + biClrUsed = intermediate_surface->format->palette->ncolors; } else { biClrUsed = 0; } @@ -701,9 +752,9 @@ SDL_SaveBMP_RW(SDL_Surface * saveme, SDL_RWops * dst, int freedst) biSize = 108; biCompression = BI_BITFIELDS; /* The BMP format is always little endian, these masks stay the same */ - bV4RedMask = 0x00ff0000; + bV4RedMask = 0x00ff0000; bV4GreenMask = 0x0000ff00; - bV4BlueMask = 0x000000ff; + bV4BlueMask = 0x000000ff; bV4AlphaMask = 0xff000000; bV4CSType = LCS_WINDOWS_COLOR_SPACE; bV4GammaRed = 0; @@ -740,12 +791,12 @@ SDL_SaveBMP_RW(SDL_Surface * saveme, SDL_RWops * dst, int freedst) } /* Write the palette (in BGR color order) */ - if (surface->format->palette) { + if (intermediate_surface->format->palette) { SDL_Color *colors; int ncolors; - colors = surface->format->palette->colors; - ncolors = surface->format->palette->ncolors; + colors = intermediate_surface->format->palette->colors; + ncolors = intermediate_surface->format->palette->ncolors; for (i = 0; i < ncolors; ++i) { SDL_RWwrite(dst, &colors[i].b, 1, 1); SDL_RWwrite(dst, &colors[i].g, 1, 1); @@ -765,10 +816,10 @@ SDL_SaveBMP_RW(SDL_Surface * saveme, SDL_RWops * dst, int freedst) } /* Write the bitmap image upside down */ - bits = (Uint8 *) surface->pixels + (surface->h * surface->pitch); + bits = (Uint8 *)intermediate_surface->pixels + (intermediate_surface->h * intermediate_surface->pitch); pad = ((bw % 4) ? (4 - (bw % 4)) : 0); - while (bits > (Uint8 *) surface->pixels) { - bits -= surface->pitch; + while (bits > (Uint8 *)intermediate_surface->pixels) { + bits -= intermediate_surface->pitch; if (SDL_RWwrite(dst, bits, 1, bw) != bw) { SDL_Error(SDL_EFWRITE); break; @@ -792,16 +843,16 @@ SDL_SaveBMP_RW(SDL_Surface * saveme, SDL_RWops * dst, int freedst) } /* Close it up.. */ - SDL_UnlockSurface(surface); - if (surface != saveme) { - SDL_FreeSurface(surface); + SDL_UnlockSurface(intermediate_surface); + if (intermediate_surface != surface) { + SDL_FreeSurface(intermediate_surface); } } if (freedst && dst) { SDL_RWclose(dst); } - return ((SDL_strcmp(SDL_GetError(), "") == 0) ? 0 : -1); + return (SDL_strcmp(SDL_GetError(), "") == 0) ? 0 : -1; } /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/SDL_clipboard.c b/SDL2-2.30.5/src/video/SDL_clipboard.c similarity index 57% rename from SDL2-2.0.12/src/video/SDL_clipboard.c rename to SDL2-2.30.5/src/video/SDL_clipboard.c index f7ad9c3..3111a63 100644 --- a/SDL2-2.0.12/src/video/SDL_clipboard.c +++ b/SDL2-2.30.5/src/video/SDL_clipboard.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,9 +23,7 @@ #include "SDL_clipboard.h" #include "SDL_sysvideo.h" - -int -SDL_SetClipboardText(const char *text) +int SDL_SetClipboardText(const char *text) { SDL_VideoDevice *_this = SDL_GetVideoDevice(); @@ -45,8 +43,27 @@ SDL_SetClipboardText(const char *text) } } -char * -SDL_GetClipboardText(void) +int SDL_SetPrimarySelectionText(const char *text) +{ + SDL_VideoDevice *_this = SDL_GetVideoDevice(); + + if (!_this) { + return SDL_SetError("Video subsystem must be initialized to set primary selection text"); + } + + if (!text) { + text = ""; + } + if (_this->SetPrimarySelectionText) { + return _this->SetPrimarySelectionText(_this, text); + } else { + SDL_free(_this->primary_selection_text); + _this->primary_selection_text = SDL_strdup(text); + return 0; + } +} + +char *SDL_GetClipboardText(void) { SDL_VideoDevice *_this = SDL_GetVideoDevice(); @@ -66,8 +83,27 @@ SDL_GetClipboardText(void) } } -SDL_bool -SDL_HasClipboardText(void) +char *SDL_GetPrimarySelectionText(void) +{ + SDL_VideoDevice *_this = SDL_GetVideoDevice(); + + if (!_this) { + SDL_SetError("Video subsystem must be initialized to get primary selection text"); + return SDL_strdup(""); + } + + if (_this->GetPrimarySelectionText) { + return _this->GetPrimarySelectionText(_this); + } else { + const char *text = _this->primary_selection_text; + if (!text) { + text = ""; + } + return SDL_strdup(text); + } +} + +SDL_bool SDL_HasClipboardText(void) { SDL_VideoDevice *_this = SDL_GetVideoDevice(); @@ -87,4 +123,24 @@ SDL_HasClipboardText(void) } } +SDL_bool SDL_HasPrimarySelectionText(void) +{ + SDL_VideoDevice *_this = SDL_GetVideoDevice(); + + if (!_this) { + SDL_SetError("Video subsystem must be initialized to check primary selection text"); + return SDL_FALSE; + } + + if (_this->HasPrimarySelectionText) { + return _this->HasPrimarySelectionText(_this); + } + + if (_this->primary_selection_text && _this->primary_selection_text[0] != '\0') { + return SDL_TRUE; + } + + return SDL_FALSE; +} + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/SDL_egl.c b/SDL2-2.30.5/src/video/SDL_egl.c similarity index 56% rename from SDL2-2.0.12/src/video/SDL_egl.c rename to SDL2-2.30.5/src/video/SDL_egl.c index a8a1485..a89c0e8 100644 --- a/SDL2-2.0.12/src/video/SDL_egl.c +++ b/SDL2-2.30.5/src/video/SDL_egl.c @@ -1,15 +1,15 @@ /* * Simple DirectMedia Layer - * Copyright (C) 1997-2020 Sam Lantinga - * + * Copyright (C) 1997-2024 Sam Lantinga + * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * 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 @@ -20,18 +20,20 @@ */ #include "../SDL_internal.h" -#if SDL_VIDEO_OPENGL_EGL +#ifdef SDL_VIDEO_OPENGL_EGL -#if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT +#if defined(SDL_VIDEO_DRIVER_WINDOWS) || defined(SDL_VIDEO_DRIVER_WINRT) #include "../core/windows/SDL_windows.h" #endif -#if SDL_VIDEO_DRIVER_ANDROID +#ifdef SDL_VIDEO_DRIVER_ANDROID #include -#include "../core/android/SDL_android.h" +#include "../video/android/SDL_androidvideo.h" +#endif +#ifdef SDL_VIDEO_DRIVER_RPI +#include #endif #include "SDL_sysvideo.h" -#include "SDL_log.h" #include "SDL_egl_c.h" #include "SDL_loadso.h" #include "SDL_hints.h" @@ -43,45 +45,70 @@ #endif #endif /* EGL_KHR_create_context */ -#if SDL_VIDEO_DRIVER_RPI +#ifndef EGL_EXT_pixel_format_float +#define EGL_EXT_pixel_format_float +#define EGL_COLOR_COMPONENT_TYPE_EXT 0x3339 +#define EGL_COLOR_COMPONENT_TYPE_FIXED_EXT 0x333A +#define EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT 0x333B +#endif + +#ifndef EGL_EXT_present_opaque +#define EGL_EXT_present_opaque 1 +#define EGL_PRESENT_OPAQUE_EXT 0x31DF +#endif /* EGL_EXT_present_opaque */ + +#ifdef SDL_VIDEO_DRIVER_RPI /* Raspbian places the OpenGL ES/EGL binaries in a non standard path */ -#define DEFAULT_EGL ( vc4 ? "libEGL.so.1" : "libbrcmEGL.so" ) -#define DEFAULT_OGL_ES2 ( vc4 ? "libGLESv2.so.2" : "libbrcmGLESv2.so" ) -#define ALT_EGL "libEGL.so" -#define ALT_OGL_ES2 "libGLESv2.so" -#define DEFAULT_OGL_ES_PVR ( vc4 ? "libGLES_CM.so.1" : "libbrcmGLESv2.so" ) -#define DEFAULT_OGL_ES ( vc4 ? "libGLESv1_CM.so.1" : "libbrcmGLESv2.so" ) +#define DEFAULT_EGL (vc4 ? "libEGL.so.1" : "libbrcmEGL.so") +#define DEFAULT_OGL_ES2 (vc4 ? "libGLESv2.so.2" : "libbrcmGLESv2.so") +#define ALT_EGL "libEGL.so" +#define ALT_OGL_ES2 "libGLESv2.so" +#define DEFAULT_OGL_ES_PVR (vc4 ? "libGLES_CM.so.1" : "libbrcmGLESv2.so") +#define DEFAULT_OGL_ES (vc4 ? "libGLESv1_CM.so.1" : "libbrcmGLESv2.so") -#elif SDL_VIDEO_DRIVER_ANDROID || SDL_VIDEO_DRIVER_VIVANTE +#elif defined(SDL_VIDEO_DRIVER_ANDROID) || defined(SDL_VIDEO_DRIVER_VIVANTE) /* Android */ -#define DEFAULT_EGL "libEGL.so" -#define DEFAULT_OGL_ES2 "libGLESv2.so" +#define DEFAULT_EGL "libEGL.so" +#define DEFAULT_OGL_ES2 "libGLESv2.so" #define DEFAULT_OGL_ES_PVR "libGLES_CM.so" -#define DEFAULT_OGL_ES "libGLESv1_CM.so" +#define DEFAULT_OGL_ES "libGLESv1_CM.so" -#elif SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT +#elif defined(SDL_VIDEO_DRIVER_WINDOWS) || defined(SDL_VIDEO_DRIVER_WINRT) /* EGL AND OpenGL ES support via ANGLE */ #define DEFAULT_EGL "libEGL.dll" #define DEFAULT_OGL_ES2 "libGLESv2.dll" #define DEFAULT_OGL_ES_PVR "libGLES_CM.dll" -#define DEFAULT_OGL_ES "libGLESv1_CM.dll" +#define DEFAULT_OGL_ES "libGLESv1_CM.dll" -#elif SDL_VIDEO_DRIVER_COCOA +#elif defined(SDL_VIDEO_DRIVER_COCOA) /* EGL AND OpenGL ES support via ANGLE */ -#define DEFAULT_EGL "libEGL.dylib" -#define DEFAULT_OGL_ES2 "libGLESv2.dylib" +#define DEFAULT_EGL "libEGL.dylib" +#define DEFAULT_OGL_ES2 "libGLESv2.dylib" #define DEFAULT_OGL_ES_PVR "libGLES_CM.dylib" //??? -#define DEFAULT_OGL_ES "libGLESv1_CM.dylib" //??? +#define DEFAULT_OGL_ES "libGLESv1_CM.dylib" //??? + +#elif defined(__OpenBSD__) +/* OpenBSD */ +#define DEFAULT_OGL "libGL.so" +#define DEFAULT_EGL "libEGL.so" +#define DEFAULT_OGL_ES2 "libGLESv2.so" +#define DEFAULT_OGL_ES_PVR "libGLES_CM.so" +#define DEFAULT_OGL_ES "libGLESv1_CM.so" #else -/* Desktop Linux */ -#define DEFAULT_OGL "libGL.so.1" -#define DEFAULT_EGL "libEGL.so.1" -#define DEFAULT_OGL_ES2 "libGLESv2.so.2" +/* Desktop Linux/Unix-like */ +#define DEFAULT_OGL "libGL.so.1" +#define DEFAULT_EGL "libEGL.so.1" +#define ALT_OGL "libOpenGL.so.0" +#define DEFAULT_OGL_ES2 "libGLESv2.so.2" #define DEFAULT_OGL_ES_PVR "libGLES_CM.so.1" -#define DEFAULT_OGL_ES "libGLESv1_CM.so.1" +#define DEFAULT_OGL_ES "libGLESv1_CM.so.1" #endif /* SDL_VIDEO_DRIVER_RPI */ +#if defined(SDL_VIDEO_OPENGL) && !defined(SDL_VIDEO_VITA_PVR_OGL) +#include "SDL_opengl.h" +#endif + /** If we happen to not have this defined because of an older EGL version, just define it 0x0 as eglGetPlatformDisplayEXT will most likely be NULL if this is missing */ @@ -89,26 +116,26 @@ #define EGL_PLATFORM_DEVICE_EXT 0x0 #endif -#ifdef SDL_VIDEO_STATIC_ANGLE +#if defined(SDL_VIDEO_STATIC_ANGLE) || defined(SDL_VIDEO_DRIVER_VITA) #define LOAD_FUNC(NAME) \ -_this->egl_data->NAME = (void *)NAME; + _this->egl_data->NAME = (void *)NAME; #else -#define LOAD_FUNC(NAME) \ -_this->egl_data->NAME = SDL_LoadFunction(_this->egl_data->dll_handle, #NAME); \ -if (!_this->egl_data->NAME) \ -{ \ - return SDL_SetError("Could not retrieve EGL function " #NAME); \ -} +#define LOAD_FUNC(NAME) \ + _this->egl_data->NAME = SDL_LoadFunction(_this->egl_data->egl_dll_handle, #NAME); \ + if (!_this->egl_data->NAME) { \ + return SDL_SetError("Could not retrieve EGL function " #NAME); \ + } #endif /* it is allowed to not have some of the EGL extensions on start - attempts to use them will fail later. */ #define LOAD_FUNC_EGLEXT(NAME) \ _this->egl_data->NAME = _this->egl_data->eglGetProcAddress(#NAME); - -static const char * SDL_EGL_GetErrorName(EGLint eglErrorCode) +static const char *SDL_EGL_GetErrorName(EGLint eglErrorCode) { -#define SDL_EGL_ERROR_TRANSLATE(e) case e: return #e; +#define SDL_EGL_ERROR_TRANSLATE(e) \ + case e: \ + return #e; switch (eglErrorCode) { SDL_EGL_ERROR_TRANSLATE(EGL_SUCCESS); SDL_EGL_ERROR_TRANSLATE(EGL_NOT_INITIALIZED); @@ -129,25 +156,21 @@ static const char * SDL_EGL_GetErrorName(EGLint eglErrorCode) return ""; } -int SDL_EGL_SetErrorEx(const char * message, const char * eglFunctionName, EGLint eglErrorCode) +int SDL_EGL_SetErrorEx(const char *message, const char *eglFunctionName, EGLint eglErrorCode) { - const char * errorText = SDL_EGL_GetErrorName(eglErrorCode); + const char *errorText = SDL_EGL_GetErrorName(eglErrorCode); char altErrorText[32]; if (errorText[0] == '\0') { /* An unknown-to-SDL error code was reported. Report its hexadecimal value, instead of its name. */ - SDL_snprintf(altErrorText, SDL_arraysize(altErrorText), "0x%x", (unsigned int)eglErrorCode); + (void)SDL_snprintf(altErrorText, SDL_arraysize(altErrorText), "0x%x", (unsigned int)eglErrorCode); errorText = altErrorText; } return SDL_SetError("%s (call to %s failed, reporting an error of %s)", message, eglFunctionName, errorText); } /* EGL implementation of SDL OpenGL ES support */ -typedef enum { - SDL_EGL_DISPLAY_EXTENSION, - SDL_EGL_CLIENT_EXTENSION -} SDL_EGL_ExtensionType; -static SDL_bool SDL_EGL_HasExtension(_THIS, SDL_EGL_ExtensionType type, const char *ext) +SDL_bool SDL_EGL_HasExtension(_THIS, SDL_EGL_ExtensionType type, const char *ext) { size_t ext_len; const char *ext_override; @@ -155,7 +178,7 @@ static SDL_bool SDL_EGL_HasExtension(_THIS, SDL_EGL_ExtensionType type, const ch const char *ext_start; /* Invalid extensions can be rejected early */ - if (ext == NULL || *ext == 0 || SDL_strchr(ext, ' ') != NULL) { + if (!ext || *ext == 0 || SDL_strchr(ext, ' ') != NULL) { /* SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "SDL_EGL_HasExtension: Invalid EGL extension"); */ return SDL_FALSE; } @@ -168,7 +191,7 @@ static SDL_bool SDL_EGL_HasExtension(_THIS, SDL_EGL_ExtensionType type, const ch * 1 If set, the client extension is masked and not present to SDL. */ ext_override = SDL_getenv(ext); - if (ext_override != NULL) { + if (ext_override) { int disable_ext = SDL_atoi(ext_override); if (disable_ext & 0x01 && type == SDL_EGL_DISPLAY_EXTENSION) { return SDL_FALSE; @@ -194,12 +217,12 @@ static SDL_bool SDL_EGL_HasExtension(_THIS, SDL_EGL_ExtensionType type, const ch return SDL_FALSE; } - if (egl_extstr != NULL) { + if (egl_extstr) { ext_start = egl_extstr; while (*ext_start) { ext_start = SDL_strstr(ext_start, ext); - if (ext_start == NULL) { + if (!ext_start) { return SDL_FALSE; } /* Check if the match is not just a substring of one of the extensions */ @@ -219,43 +242,34 @@ static SDL_bool SDL_EGL_HasExtension(_THIS, SDL_EGL_ExtensionType type, const ch return SDL_FALSE; } -void * -SDL_EGL_GetProcAddress(_THIS, const char *proc) +void *SDL_EGL_GetProcAddress(_THIS, const char *proc) { - const Uint32 eglver = (((Uint32) _this->egl_data->egl_version_major) << 16) | ((Uint32) _this->egl_data->egl_version_minor); - const SDL_bool is_egl_15_or_later = eglver >= ((((Uint32) 1) << 16) | 5); void *retval = NULL; + if (_this->egl_data) { + const Uint32 eglver = (((Uint32)_this->egl_data->egl_version_major) << 16) | ((Uint32)_this->egl_data->egl_version_minor); + const SDL_bool is_egl_15_or_later = eglver >= ((((Uint32)1) << 16) | 5); - /* EGL 1.5 can use eglGetProcAddress() for any symbol. 1.4 and earlier can't use it for core entry points. */ - if (!retval && is_egl_15_or_later && _this->egl_data->eglGetProcAddress) { - retval = _this->egl_data->eglGetProcAddress(proc); - } + /* EGL 1.5 can use eglGetProcAddress() for any symbol. 1.4 and earlier can't use it for core entry points. */ + if (!retval && is_egl_15_or_later && _this->egl_data->eglGetProcAddress) { + retval = _this->egl_data->eglGetProcAddress(proc); + } - /* Try SDL_LoadFunction() first for EGL <= 1.4, or as a fallback for >= 1.5. */ - if (!retval) { - static char procname[64]; - retval = SDL_LoadFunction(_this->egl_data->egl_dll_handle, proc); - /* just in case you need an underscore prepended... */ - if (!retval && (SDL_strlen(proc) < (sizeof (procname) - 1))) { - procname[0] = '_'; - SDL_strlcpy(procname + 1, proc, sizeof (procname) - 1); - retval = SDL_LoadFunction(_this->egl_data->egl_dll_handle, procname); +#if !defined(__EMSCRIPTEN__) && !defined(SDL_VIDEO_DRIVER_VITA) /* LoadFunction isn't needed on Emscripten and will call dlsym(), causing other problems. */ + /* Try SDL_LoadFunction() first for EGL <= 1.4, or as a fallback for >= 1.5. */ + if (!retval) { + retval = SDL_LoadFunction(_this->egl_data->opengl_dll_handle, proc); + } +#endif + + /* Try eglGetProcAddress if we're on <= 1.4 and still searching... */ + if (!retval && !is_egl_15_or_later && _this->egl_data->eglGetProcAddress) { + retval = _this->egl_data->eglGetProcAddress(proc); } } - - /* Try eglGetProcAddress if we on <= 1.4 and still searching... */ - if (!retval && !is_egl_15_or_later && _this->egl_data->eglGetProcAddress) { - retval = _this->egl_data->eglGetProcAddress(proc); - if (retval) { - return retval; - } - } - return retval; } -void -SDL_EGL_UnloadLibrary(_THIS) +void SDL_EGL_UnloadLibrary(_THIS) { if (_this->egl_data) { if (_this->egl_data->egl_display) { @@ -263,42 +277,32 @@ SDL_EGL_UnloadLibrary(_THIS) _this->egl_data->egl_display = NULL; } - if (_this->egl_data->dll_handle) { - SDL_UnloadObject(_this->egl_data->dll_handle); - _this->egl_data->dll_handle = NULL; - } if (_this->egl_data->egl_dll_handle) { SDL_UnloadObject(_this->egl_data->egl_dll_handle); _this->egl_data->egl_dll_handle = NULL; } - + if (_this->egl_data->opengl_dll_handle) { + SDL_UnloadObject(_this->egl_data->opengl_dll_handle); + _this->egl_data->opengl_dll_handle = NULL; + } + SDL_free(_this->egl_data); _this->egl_data = NULL; } } -int -SDL_EGL_LoadLibraryOnly(_THIS, const char *egl_path) +static int SDL_EGL_LoadLibraryInternal(_THIS, const char *egl_path) { - void *dll_handle = NULL, *egl_dll_handle = NULL; /* The naming is counter intuitive, but hey, I just work here -- Gabriel */ + void *egl_dll_handle = NULL, *opengl_dll_handle = NULL; const char *path = NULL; -#if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT +#if defined(SDL_VIDEO_DRIVER_WINDOWS) || defined(SDL_VIDEO_DRIVER_WINRT) const char *d3dcompiler; #endif -#if SDL_VIDEO_DRIVER_RPI +#ifdef SDL_VIDEO_DRIVER_RPI SDL_bool vc4 = (0 == access("/sys/module/vc4/", F_OK)); #endif - if (_this->egl_data) { - return SDL_SetError("EGL context already created"); - } - - _this->egl_data = (struct SDL_EGL_VideoData *) SDL_calloc(1, sizeof(SDL_EGL_VideoData)); - if (!_this->egl_data) { - return SDL_OutOfMemory(); - } - -#if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT +#if defined(SDL_VIDEO_DRIVER_WINDOWS) || defined(SDL_VIDEO_DRIVER_WINRT) d3dcompiler = SDL_GetHint(SDL_HINT_VIDEO_WIN_D3DCOMPILER); if (d3dcompiler) { if (SDL_strcasecmp(d3dcompiler, "none") != 0) { @@ -310,7 +314,8 @@ SDL_EGL_LoadLibraryOnly(_THIS, const char *egl_path) if (WIN_IsWindowsVistaOrGreater()) { /* Try the newer d3d compilers first */ const char *d3dcompiler_list[] = { - "d3dcompiler_47.dll", "d3dcompiler_46.dll", + "d3dcompiler_47.dll", + "d3dcompiler_46.dll", }; int i; @@ -328,78 +333,84 @@ SDL_EGL_LoadLibraryOnly(_THIS, const char *egl_path) } #endif -#ifndef SDL_VIDEO_STATIC_ANGLE +#if !defined(SDL_VIDEO_STATIC_ANGLE) && !defined(SDL_VIDEO_DRIVER_VITA) /* A funny thing, loading EGL.so first does not work on the Raspberry, so we load libGL* first */ path = SDL_getenv("SDL_VIDEO_GL_DRIVER"); - if (path != NULL) { - egl_dll_handle = SDL_LoadObject(path); + if (path) { + opengl_dll_handle = SDL_LoadObject(path); } - if (egl_dll_handle == NULL) { + if (!opengl_dll_handle) { if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) { if (_this->gl_config.major_version > 1) { path = DEFAULT_OGL_ES2; - egl_dll_handle = SDL_LoadObject(path); + opengl_dll_handle = SDL_LoadObject(path); #ifdef ALT_OGL_ES2 - if (egl_dll_handle == NULL && !vc4) { + if (!opengl_dll_handle && !vc4) { path = ALT_OGL_ES2; - egl_dll_handle = SDL_LoadObject(path); + opengl_dll_handle = SDL_LoadObject(path); } #endif } else { path = DEFAULT_OGL_ES; - egl_dll_handle = SDL_LoadObject(path); - if (egl_dll_handle == NULL) { + opengl_dll_handle = SDL_LoadObject(path); + if (!opengl_dll_handle) { path = DEFAULT_OGL_ES_PVR; - egl_dll_handle = SDL_LoadObject(path); + opengl_dll_handle = SDL_LoadObject(path); } #ifdef ALT_OGL_ES2 - if (egl_dll_handle == NULL && !vc4) { + if (!opengl_dll_handle && !vc4) { path = ALT_OGL_ES2; - egl_dll_handle = SDL_LoadObject(path); + opengl_dll_handle = SDL_LoadObject(path); } #endif } } -#ifdef DEFAULT_OGL +#ifdef DEFAULT_OGL else { path = DEFAULT_OGL; - egl_dll_handle = SDL_LoadObject(path); + opengl_dll_handle = SDL_LoadObject(path); +#ifdef ALT_OGL + if (!opengl_dll_handle) { + path = ALT_OGL; + opengl_dll_handle = SDL_LoadObject(path); + } +#endif } -#endif +#endif } - _this->egl_data->egl_dll_handle = egl_dll_handle; + _this->egl_data->opengl_dll_handle = opengl_dll_handle; - if (egl_dll_handle == NULL) { + if (!opengl_dll_handle) { return SDL_SetError("Could not initialize OpenGL / GLES library"); } /* Loading libGL* in the previous step took care of loading libEGL.so, but we future proof by double checking */ - if (egl_path != NULL) { - dll_handle = SDL_LoadObject(egl_path); - } + if (egl_path) { + egl_dll_handle = SDL_LoadObject(egl_path); + } /* Try loading a EGL symbol, if it does not work try the default library paths */ - if (dll_handle == NULL || SDL_LoadFunction(dll_handle, "eglChooseConfig") == NULL) { - if (dll_handle != NULL) { - SDL_UnloadObject(dll_handle); + if (!egl_dll_handle || SDL_LoadFunction(egl_dll_handle, "eglChooseConfig") == NULL) { + if (egl_dll_handle) { + SDL_UnloadObject(egl_dll_handle); } path = SDL_getenv("SDL_VIDEO_EGL_DRIVER"); - if (path == NULL) { + if (!path) { path = DEFAULT_EGL; } - dll_handle = SDL_LoadObject(path); + egl_dll_handle = SDL_LoadObject(path); #ifdef ALT_EGL - if (dll_handle == NULL && !vc4) { + if (!egl_dll_handle && !vc4) { path = ALT_EGL; - dll_handle = SDL_LoadObject(path); + egl_dll_handle = SDL_LoadObject(path); } #endif - if (dll_handle == NULL || SDL_LoadFunction(dll_handle, "eglChooseConfig") == NULL) { - if (dll_handle != NULL) { - SDL_UnloadObject(dll_handle); + if (!egl_dll_handle || SDL_LoadFunction(egl_dll_handle, "eglChooseConfig") == NULL) { + if (egl_dll_handle) { + SDL_UnloadObject(egl_dll_handle); } return SDL_SetError("Could not load EGL library"); } @@ -407,7 +418,10 @@ SDL_EGL_LoadLibraryOnly(_THIS, const char *egl_path) } #endif - _this->egl_data->dll_handle = dll_handle; + _this->egl_data->egl_dll_handle = egl_dll_handle; +#ifdef SDL_VIDEO_DRIVER_VITA + _this->egl_data->opengl_dll_handle = opengl_dll_handle; +#endif /* Load new function pointers */ LOAD_FUNC(eglGetDisplay); @@ -432,8 +446,13 @@ SDL_EGL_LoadLibraryOnly(_THIS, const char *egl_path) LOAD_FUNC(eglGetError); LOAD_FUNC_EGLEXT(eglQueryDevicesEXT); LOAD_FUNC_EGLEXT(eglGetPlatformDisplayEXT); - - _this->gl_config.driver_loaded = 1; + /* Atomic functions */ + LOAD_FUNC_EGLEXT(eglCreateSyncKHR); + LOAD_FUNC_EGLEXT(eglDestroySyncKHR); + LOAD_FUNC_EGLEXT(eglDupNativeFenceFDANDROID); + LOAD_FUNC_EGLEXT(eglWaitSyncKHR); + LOAD_FUNC_EGLEXT(eglClientWaitSyncKHR); + /* Atomic functions end */ if (path) { SDL_strlcpy(_this->gl_config.driver_path, path, sizeof(_this->gl_config.driver_path) - 1); @@ -444,8 +463,27 @@ SDL_EGL_LoadLibraryOnly(_THIS, const char *egl_path) return 0; } -static void -SDL_EGL_GetVersion(_THIS) { +int SDL_EGL_LoadLibraryOnly(_THIS, const char *egl_path) +{ + if (_this->egl_data) { + return SDL_SetError("EGL context already created"); + } + + _this->egl_data = (struct SDL_EGL_VideoData *)SDL_calloc(1, sizeof(SDL_EGL_VideoData)); + if (!_this->egl_data) { + return SDL_OutOfMemory(); + } + + if (SDL_EGL_LoadLibraryInternal(_this, egl_path) < 0) { + SDL_free(_this->egl_data); + _this->egl_data = NULL; + return -1; + } + return 0; +} + +static void SDL_EGL_GetVersion(_THIS) +{ if (_this->egl_data->eglQueryString) { const char *egl_version = _this->egl_data->eglQueryString(_this->egl_data->egl_display, EGL_VERSION); if (egl_version) { @@ -460,41 +498,44 @@ SDL_EGL_GetVersion(_THIS) { } } -int -SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_display, EGLenum platform) +int SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_display, EGLenum platform) { - int egl_version_major, egl_version_minor; int library_load_retcode = SDL_EGL_LoadLibraryOnly(_this, egl_path); if (library_load_retcode != 0) { return library_load_retcode; } - /* EGL 1.5 allows querying for client version with EGL_NO_DISPLAY */ - SDL_EGL_GetVersion(_this); - - egl_version_major = _this->egl_data->egl_version_major; - egl_version_minor = _this->egl_data->egl_version_minor; - - if (egl_version_major == 1 && egl_version_minor == 5) { - LOAD_FUNC(eglGetPlatformDisplay); - } - _this->egl_data->egl_display = EGL_NO_DISPLAY; + #if !defined(__WINRT__) +#if !defined(SDL_VIDEO_DRIVER_VITA) if (platform) { - if (egl_version_major == 1 && egl_version_minor == 5) { - _this->egl_data->egl_display = _this->egl_data->eglGetPlatformDisplay(platform, (void *)(size_t)native_display, NULL); + /* EGL 1.5 allows querying for client version with EGL_NO_DISPLAY + * -- + * Khronos doc: "EGL_BAD_DISPLAY is generated if display is not an EGL display connection, unless display is EGL_NO_DISPLAY and name is EGL_EXTENSIONS." + * Therefore SDL_EGL_GetVersion() shouldn't work with uninitialized display. + * - it actually doesn't work on Android that has 1.5 egl client + * - it works on desktop X11 (using SDL_VIDEO_X11_FORCE_EGL=1) */ + SDL_EGL_GetVersion(_this); + + if (_this->egl_data->egl_version_major == 1 && _this->egl_data->egl_version_minor == 5) { + LOAD_FUNC(eglGetPlatformDisplay); + } + + if (_this->egl_data->eglGetPlatformDisplay) { + _this->egl_data->egl_display = _this->egl_data->eglGetPlatformDisplay(platform, (void *)(uintptr_t)native_display, NULL); } else { if (SDL_EGL_HasExtension(_this, SDL_EGL_CLIENT_EXTENSION, "EGL_EXT_platform_base")) { _this->egl_data->eglGetPlatformDisplayEXT = SDL_EGL_GetProcAddress(_this, "eglGetPlatformDisplayEXT"); if (_this->egl_data->eglGetPlatformDisplayEXT) { - _this->egl_data->egl_display = _this->egl_data->eglGetPlatformDisplayEXT(platform, (void *)(size_t)native_display, NULL); + _this->egl_data->egl_display = _this->egl_data->eglGetPlatformDisplayEXT(platform, (void *)(uintptr_t)native_display, NULL); } } } } +#endif /* Try the implementation-specific eglGetDisplay even if eglGetPlatformDisplay fails */ - if (_this->egl_data->egl_display == EGL_NO_DISPLAY) { + if ((_this->egl_data->egl_display == EGL_NO_DISPLAY) && (_this->egl_data->eglGetDisplay)) { _this->egl_data->egl_display = _this->egl_data->eglGetDisplay(native_display); } if (_this->egl_data->egl_display == EGL_NO_DISPLAY) { @@ -502,7 +543,7 @@ SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_displa *_this->gl_config.driver_path = '\0'; return SDL_SetError("Could not get EGL display"); } - + if (_this->egl_data->eglInitialize(_this->egl_data->egl_display, NULL, NULL) != EGL_TRUE) { _this->gl_config.driver_loaded = 0; *_this->gl_config.driver_path = '\0'; @@ -513,7 +554,7 @@ SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_displa /* Get the EGL version with a valid egl_display, for EGL <= 1.4 */ SDL_EGL_GetVersion(_this); - _this->egl_data->is_offscreen = 0; + _this->egl_data->is_offscreen = SDL_FALSE; return 0; } @@ -526,23 +567,22 @@ SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_displa valid available GPU for EGL to use. */ -int -SDL_EGL_InitializeOffscreen(_THIS, int device) +int SDL_EGL_InitializeOffscreen(_THIS, int device) { void *egl_devices[SDL_EGL_MAX_DEVICES]; EGLint num_egl_devices = 0; const char *egl_device_hint; - if (_this->gl_config.driver_loaded != 1) { + if (_this->gl_config.driver_loaded <= 0) { return SDL_SetError("SDL_EGL_LoadLibraryOnly() has not been called or has failed."); } /* Check for all extensions that are optional until used and fail if any is missing */ - if (_this->egl_data->eglQueryDevicesEXT == NULL) { + if (!_this->egl_data->eglQueryDevicesEXT) { return SDL_SetError("eglQueryDevicesEXT is missing (EXT_device_enumeration not supported by the drivers?)"); } - if (_this->egl_data->eglGetPlatformDisplayEXT == NULL) { + if (!_this->egl_data->eglGetPlatformDisplayEXT) { return SDL_SetError("eglGetPlatformDisplayEXT is missing (EXT_platform_base not supported by the drivers?)"); } @@ -567,8 +607,7 @@ SDL_EGL_InitializeOffscreen(_THIS, int device) if (_this->egl_data->eglInitialize(_this->egl_data->egl_display, NULL, NULL) != EGL_TRUE) { return SDL_SetError("Could not initialize EGL"); } - } - else { + } else { int i; SDL_bool found = SDL_FALSE; EGLDisplay attempted_egl_display; @@ -601,90 +640,88 @@ SDL_EGL_InitializeOffscreen(_THIS, int device) /* Get the EGL version with a valid egl_display, for EGL <= 1.4 */ SDL_EGL_GetVersion(_this); - _this->egl_data->is_offscreen = 1; + _this->egl_data->is_offscreen = SDL_TRUE; return 0; } -void -SDL_EGL_SetRequiredVisualId(_THIS, int visual_id) +void SDL_EGL_SetRequiredVisualId(_THIS, int visual_id) { - _this->egl_data->egl_required_visual_id=visual_id; + _this->egl_data->egl_required_visual_id = visual_id; } #ifdef DUMP_EGL_CONFIG -#define ATTRIBUTE(_attr) { _attr, #_attr } +#define ATTRIBUTE(_attr) \ + { \ + _attr, #_attr \ + } -typedef struct { +typedef struct +{ EGLint attribute; - char const* name; + char const *name; } Attribute; -Attribute attributes[] = { - ATTRIBUTE( EGL_BUFFER_SIZE ), - ATTRIBUTE( EGL_ALPHA_SIZE ), - ATTRIBUTE( EGL_BLUE_SIZE ), - ATTRIBUTE( EGL_GREEN_SIZE ), - ATTRIBUTE( EGL_RED_SIZE ), - ATTRIBUTE( EGL_DEPTH_SIZE ), - ATTRIBUTE( EGL_STENCIL_SIZE ), - ATTRIBUTE( EGL_CONFIG_CAVEAT ), - ATTRIBUTE( EGL_CONFIG_ID ), - ATTRIBUTE( EGL_LEVEL ), - ATTRIBUTE( EGL_MAX_PBUFFER_HEIGHT ), - ATTRIBUTE( EGL_MAX_PBUFFER_WIDTH ), - ATTRIBUTE( EGL_MAX_PBUFFER_PIXELS ), - ATTRIBUTE( EGL_NATIVE_RENDERABLE ), - ATTRIBUTE( EGL_NATIVE_VISUAL_ID ), - ATTRIBUTE( EGL_NATIVE_VISUAL_TYPE ), - ATTRIBUTE( EGL_SAMPLES ), - ATTRIBUTE( EGL_SAMPLE_BUFFERS ), - ATTRIBUTE( EGL_SURFACE_TYPE ), - ATTRIBUTE( EGL_TRANSPARENT_TYPE ), - ATTRIBUTE( EGL_TRANSPARENT_BLUE_VALUE ), - ATTRIBUTE( EGL_TRANSPARENT_GREEN_VALUE ), - ATTRIBUTE( EGL_TRANSPARENT_RED_VALUE ), - ATTRIBUTE( EGL_BIND_TO_TEXTURE_RGB ), - ATTRIBUTE( EGL_BIND_TO_TEXTURE_RGBA ), - ATTRIBUTE( EGL_MIN_SWAP_INTERVAL ), - ATTRIBUTE( EGL_MAX_SWAP_INTERVAL ), - ATTRIBUTE( EGL_LUMINANCE_SIZE ), - ATTRIBUTE( EGL_ALPHA_MASK_SIZE ), - ATTRIBUTE( EGL_COLOR_BUFFER_TYPE ), - ATTRIBUTE( EGL_RENDERABLE_TYPE ), - ATTRIBUTE( EGL_MATCH_NATIVE_PIXMAP ), - ATTRIBUTE( EGL_CONFORMANT ), +static Attribute all_attributes[] = { + ATTRIBUTE(EGL_BUFFER_SIZE), + ATTRIBUTE(EGL_ALPHA_SIZE), + ATTRIBUTE(EGL_BLUE_SIZE), + ATTRIBUTE(EGL_GREEN_SIZE), + ATTRIBUTE(EGL_RED_SIZE), + ATTRIBUTE(EGL_DEPTH_SIZE), + ATTRIBUTE(EGL_STENCIL_SIZE), + ATTRIBUTE(EGL_CONFIG_CAVEAT), + ATTRIBUTE(EGL_CONFIG_ID), + ATTRIBUTE(EGL_LEVEL), + ATTRIBUTE(EGL_MAX_PBUFFER_HEIGHT), + ATTRIBUTE(EGL_MAX_PBUFFER_WIDTH), + ATTRIBUTE(EGL_MAX_PBUFFER_PIXELS), + ATTRIBUTE(EGL_NATIVE_RENDERABLE), + ATTRIBUTE(EGL_NATIVE_VISUAL_ID), + ATTRIBUTE(EGL_NATIVE_VISUAL_TYPE), + ATTRIBUTE(EGL_SAMPLES), + ATTRIBUTE(EGL_SAMPLE_BUFFERS), + ATTRIBUTE(EGL_SURFACE_TYPE), + ATTRIBUTE(EGL_TRANSPARENT_TYPE), + ATTRIBUTE(EGL_TRANSPARENT_BLUE_VALUE), + ATTRIBUTE(EGL_TRANSPARENT_GREEN_VALUE), + ATTRIBUTE(EGL_TRANSPARENT_RED_VALUE), + ATTRIBUTE(EGL_BIND_TO_TEXTURE_RGB), + ATTRIBUTE(EGL_BIND_TO_TEXTURE_RGBA), + ATTRIBUTE(EGL_MIN_SWAP_INTERVAL), + ATTRIBUTE(EGL_MAX_SWAP_INTERVAL), + ATTRIBUTE(EGL_LUMINANCE_SIZE), + ATTRIBUTE(EGL_ALPHA_MASK_SIZE), + ATTRIBUTE(EGL_COLOR_BUFFER_TYPE), + ATTRIBUTE(EGL_RENDERABLE_TYPE), + ATTRIBUTE(EGL_MATCH_NATIVE_PIXMAP), + ATTRIBUTE(EGL_CONFORMANT), }; - static void dumpconfig(_THIS, EGLConfig config) { int attr; - for (attr = 0 ; attregl_data->eglGetConfigAttrib(_this->egl_data->egl_display, config, attributes[attr].attribute, &value); - SDL_Log("\t%-32s: %10d (0x%08x)\n", attributes[attr].name, value, value); + _this->egl_data->eglGetConfigAttrib(_this->egl_data->egl_display, config, all_attributes[attr].attribute, &value); + SDL_Log("\t%-32s: %10d (0x%08x)\n", all_attributes[attr].name, value, value); } } #endif /* DUMP_EGL_CONFIG */ -int -SDL_EGL_ChooseConfig(_THIS) +static int SDL_EGL_PrivateChooseConfig(_THIS, SDL_bool set_config_caveat_none) { -/* 64 seems nice. */ + /* 64 seems nice. */ EGLint attribs[64]; EGLint found_configs = 0, value; /* 128 seems even nicer here */ EGLConfig configs[128]; - int i, j, best_bitdiff = -1, bitdiff; - - if (!_this->egl_data) { - /* The EGL library wasn't loaded, SDL_GetError() should have info */ - return -1; - } - + SDL_bool has_matching_format = SDL_FALSE; + int i, j, best_bitdiff = -1, best_truecolor_bitdiff = -1; + int truecolor_config_idx = -1; + /* Get a valid EGL configuration */ i = 0; attribs[i++] = EGL_RED_SIZE; @@ -693,35 +730,47 @@ SDL_EGL_ChooseConfig(_THIS) attribs[i++] = _this->gl_config.green_size; attribs[i++] = EGL_BLUE_SIZE; attribs[i++] = _this->gl_config.blue_size; - + + if (set_config_caveat_none) { + attribs[i++] = EGL_CONFIG_CAVEAT; + attribs[i++] = EGL_NONE; + } + if (_this->gl_config.alpha_size) { attribs[i++] = EGL_ALPHA_SIZE; attribs[i++] = _this->gl_config.alpha_size; } - + if (_this->gl_config.buffer_size) { attribs[i++] = EGL_BUFFER_SIZE; attribs[i++] = _this->gl_config.buffer_size; } - - attribs[i++] = EGL_DEPTH_SIZE; - attribs[i++] = _this->gl_config.depth_size; - + + if (_this->gl_config.depth_size) { + attribs[i++] = EGL_DEPTH_SIZE; + attribs[i++] = _this->gl_config.depth_size; + } + if (_this->gl_config.stencil_size) { attribs[i++] = EGL_STENCIL_SIZE; attribs[i++] = _this->gl_config.stencil_size; } - + if (_this->gl_config.multisamplebuffers) { attribs[i++] = EGL_SAMPLE_BUFFERS; attribs[i++] = _this->gl_config.multisamplebuffers; } - + if (_this->gl_config.multisamplesamples) { attribs[i++] = EGL_SAMPLES; attribs[i++] = _this->gl_config.multisamplesamples; } + if (_this->gl_config.floatbuffers) { + attribs[i++] = EGL_COLOR_COMPONENT_TYPE_EXT; + attribs[i++] = EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT; + } + if (_this->egl_data->is_offscreen) { attribs[i++] = EGL_SURFACE_TYPE; attribs[i++] = EGL_PBUFFER_BIT; @@ -735,7 +784,7 @@ SDL_EGL_ChooseConfig(_THIS) attribs[i++] = EGL_OPENGL_ES3_BIT_KHR; } else #endif - if (_this->gl_config.major_version >= 2) { + if (_this->gl_config.major_version >= 2) { attribs[i++] = EGL_OPENGL_ES2_BIT; } else { attribs[i++] = EGL_OPENGL_ES_BIT; @@ -753,66 +802,138 @@ SDL_EGL_ChooseConfig(_THIS) attribs[i++] = EGL_NONE; + SDL_assert(i < SDL_arraysize(attribs)); + if (_this->egl_data->eglChooseConfig(_this->egl_data->egl_display, - attribs, - configs, SDL_arraysize(configs), - &found_configs) == EGL_FALSE || + attribs, + configs, SDL_arraysize(configs), + &found_configs) == EGL_FALSE || found_configs == 0) { - return SDL_EGL_SetError("Couldn't find matching EGL config", "eglChooseConfig"); + return -1; + } + + /* first ensure that a found config has a matching format, or the function will fall through. */ + if (_this->egl_data->egl_required_visual_id) { + for (i = 0; i < found_configs; i++) { + EGLint format; + _this->egl_data->eglGetConfigAttrib(_this->egl_data->egl_display, + configs[i], + EGL_NATIVE_VISUAL_ID, &format); + if (_this->egl_data->egl_required_visual_id == format) { + has_matching_format = SDL_TRUE; + break; + } + } } /* eglChooseConfig returns a number of configurations that match or exceed the requested attribs. */ /* From those, we select the one that matches our requirements more closely via a makeshift algorithm */ - for (i = 0; i < found_configs; i++ ) { - if (_this->egl_data->egl_required_visual_id) - { + for (i = 0; i < found_configs; i++) { + SDL_bool is_truecolor = SDL_FALSE; + int bitdiff = 0; + + if (has_matching_format && _this->egl_data->egl_required_visual_id) { EGLint format; _this->egl_data->eglGetConfigAttrib(_this->egl_data->egl_display, - configs[i], - EGL_NATIVE_VISUAL_ID, &format); - if (_this->egl_data->egl_required_visual_id != format) + configs[i], + EGL_NATIVE_VISUAL_ID, &format); + if (_this->egl_data->egl_required_visual_id != format) { continue; + } + } + + _this->egl_data->eglGetConfigAttrib(_this->egl_data->egl_display, configs[i], EGL_RED_SIZE, &value); + if (value == 8) { + _this->egl_data->eglGetConfigAttrib(_this->egl_data->egl_display, configs[i], EGL_GREEN_SIZE, &value); + if (value == 8) { + _this->egl_data->eglGetConfigAttrib(_this->egl_data->egl_display, configs[i], EGL_BLUE_SIZE, &value); + if (value == 8) { + is_truecolor = SDL_TRUE; + } + } } - bitdiff = 0; for (j = 0; j < SDL_arraysize(attribs) - 1; j += 2) { if (attribs[j] == EGL_NONE) { - break; + break; } - - if ( attribs[j+1] != EGL_DONT_CARE && ( - attribs[j] == EGL_RED_SIZE || - attribs[j] == EGL_GREEN_SIZE || - attribs[j] == EGL_BLUE_SIZE || - attribs[j] == EGL_ALPHA_SIZE || - attribs[j] == EGL_DEPTH_SIZE || - attribs[j] == EGL_STENCIL_SIZE)) { + + if (attribs[j + 1] != EGL_DONT_CARE && (attribs[j] == EGL_RED_SIZE || + attribs[j] == EGL_GREEN_SIZE || + attribs[j] == EGL_BLUE_SIZE || + attribs[j] == EGL_ALPHA_SIZE || + attribs[j] == EGL_DEPTH_SIZE || + attribs[j] == EGL_STENCIL_SIZE)) { _this->egl_data->eglGetConfigAttrib(_this->egl_data->egl_display, configs[i], attribs[j], &value); bitdiff += value - attribs[j + 1]; /* value is always >= attrib */ } } - if (bitdiff < best_bitdiff || best_bitdiff == -1) { + if ((bitdiff < best_bitdiff) || (best_bitdiff == -1)) { _this->egl_data->egl_config = configs[i]; - best_bitdiff = bitdiff; } - if (bitdiff == 0) { - break; /* we found an exact match! */ + if (is_truecolor && ((bitdiff < best_truecolor_bitdiff) || (best_truecolor_bitdiff == -1))) { + truecolor_config_idx = i; + best_truecolor_bitdiff = bitdiff; } } +#define FAVOR_TRUECOLOR 1 +#if FAVOR_TRUECOLOR + /* Some apps request a low color depth, either because they _assume_ + they'll get a larger one but don't want to fail if only smaller ones + are available, or they just never called SDL_GL_SetAttribute at all and + got a tiny default. For these cases, a game that would otherwise run + at 24-bit color might get dithered down to something smaller, which is + worth avoiding. If the app requested <= 16 bit color and an exact 24-bit + match is available, favor that. Otherwise, we look for the closest + match. Note that while the API promises what you request _or better_, + it's feasible this can be disastrous for performance for custom software + on small hardware that all expected to actually get 16-bit color. In this + case, turn off FAVOR_TRUECOLOR (and maybe send a patch to make this more + flexible). */ + if (((_this->gl_config.red_size + _this->gl_config.blue_size + _this->gl_config.green_size) <= 16)) { + if (truecolor_config_idx != -1) { + _this->egl_data->egl_config = configs[truecolor_config_idx]; + } + } +#endif + #ifdef DUMP_EGL_CONFIG dumpconfig(_this, _this->egl_data->egl_config); #endif - + return 0; } -SDL_GLContext -SDL_EGL_CreateContext(_THIS, EGLSurface egl_surface) +int SDL_EGL_ChooseConfig(_THIS) +{ + int ret; + + if (!_this->egl_data) { + return SDL_SetError("EGL not initialized"); + } + + /* Try with EGL_CONFIG_CAVEAT set to EGL_NONE, to avoid any EGL_SLOW_CONFIG or EGL_NON_CONFORMANT_CONFIG */ + ret = SDL_EGL_PrivateChooseConfig(_this, SDL_TRUE); + if (ret == 0) { + return 0; + } + + /* Fallback with all configs */ + ret = SDL_EGL_PrivateChooseConfig(_this, SDL_FALSE); + if (ret == 0) { + SDL_Log("SDL_EGL_ChooseConfig: found a slow EGL config"); + return 0; + } + + return SDL_EGL_SetError("Couldn't find matching EGL config", "eglChooseConfig"); +} + +SDL_GLContext SDL_EGL_CreateContext(_THIS, EGLSurface egl_surface) { /* max 14 values plus terminator. */ EGLint attribs[15]; @@ -825,7 +946,7 @@ SDL_EGL_CreateContext(_THIS, EGLSurface egl_surface) SDL_bool profile_es = (profile_mask == SDL_GL_CONTEXT_PROFILE_ES); if (!_this->egl_data) { - /* The EGL library wasn't loaded, SDL_GetError() should have info */ + SDL_SetError("EGL not initialized"); return NULL; } @@ -833,8 +954,8 @@ SDL_EGL_CreateContext(_THIS, EGLSurface egl_surface) share_context = (EGLContext)SDL_GL_GetCurrentContext(); } -#if SDL_VIDEO_DRIVER_ANDROID - if ((_this->gl_config.flags & SDL_GL_CONTEXT_DEBUG_FLAG) != 0) { +#ifdef SDL_VIDEO_DRIVER_ANDROID + if (_this->gl_config.flags & SDL_GL_CONTEXT_DEBUG_FLAG) { /* If SDL_GL_CONTEXT_DEBUG_FLAG is set but EGL_KHR_debug unsupported, unset. * This is required because some Android devices like to complain about it * by "silently" failing, logging a hint which could be easily overlooked: @@ -895,31 +1016,28 @@ SDL_EGL_CreateContext(_THIS, EGLSurface egl_surface) } } - if (_this->gl_config.no_error) { #ifdef EGL_KHR_create_context_no_error + if (_this->gl_config.no_error) { if (SDL_EGL_HasExtension(_this, SDL_EGL_DISPLAY_EXTENSION, "EGL_KHR_create_context_no_error")) { attribs[attr++] = EGL_CONTEXT_OPENGL_NO_ERROR_KHR; attribs[attr++] = _this->gl_config.no_error; - } else -#endif - { - SDL_SetError("EGL implementation does not support no_error contexts"); - return NULL; } } +#endif attribs[attr++] = EGL_NONE; /* Bind the API */ if (profile_es) { - _this->egl_data->eglBindAPI(EGL_OPENGL_ES_API); + _this->egl_data->apitype = EGL_OPENGL_ES_API; } else { - _this->egl_data->eglBindAPI(EGL_OPENGL_API); + _this->egl_data->apitype = EGL_OPENGL_API; } + _this->egl_data->eglBindAPI(_this->egl_data->apitype); egl_context = _this->egl_data->eglCreateContext(_this->egl_data->egl_display, - _this->egl_data->egl_config, - share_context, attribs); + _this->egl_data->egl_config, + share_context, attribs); if (egl_context == EGL_NO_CONTEXT) { SDL_EGL_SetError("Could not create EGL context", "eglCreateContext"); @@ -929,77 +1047,115 @@ SDL_EGL_CreateContext(_THIS, EGLSurface egl_surface) _this->egl_data->egl_swapinterval = 0; if (SDL_EGL_MakeCurrent(_this, egl_surface, egl_context) < 0) { - /* Save the SDL error set by SDL_EGL_MakeCurrent */ - char errorText[1024]; - SDL_strlcpy(errorText, SDL_GetError(), SDL_arraysize(errorText)); - - /* Delete the context, which may alter the value returned by SDL_GetError() */ + /* Delete the context */ SDL_EGL_DeleteContext(_this, egl_context); - - /* Restore the SDL error */ - SDL_SetError("%s", errorText); - return NULL; } - return (SDL_GLContext) egl_context; -} - -int -SDL_EGL_MakeCurrent(_THIS, EGLSurface egl_surface, SDL_GLContext context) -{ - EGLContext egl_context = (EGLContext) context; - - if (!_this->egl_data) { - return SDL_SetError("OpenGL not initialized"); - } - - /* The android emulator crashes badly if you try to eglMakeCurrent - * with a valid context and invalid surface, so we have to check for both here. - */ - if (!egl_context || !egl_surface) { - _this->egl_data->eglMakeCurrent(_this->egl_data->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - } else { - if (!_this->egl_data->eglMakeCurrent(_this->egl_data->egl_display, - egl_surface, egl_surface, egl_context)) { - return SDL_EGL_SetError("Unable to make EGL context current", "eglMakeCurrent"); + /* Check whether making contexts current without a surface is supported. + * First condition: EGL must support it. That's the case for EGL 1.5 + * or later, or if the EGL_KHR_surfaceless_context extension is present. */ + if ((_this->egl_data->egl_version_major > 1) || + ((_this->egl_data->egl_version_major == 1) && (_this->egl_data->egl_version_minor >= 5)) || + SDL_EGL_HasExtension(_this, SDL_EGL_DISPLAY_EXTENSION, "EGL_KHR_surfaceless_context")) { + /* Secondary condition: The client API must support it. */ + if (profile_es) { + /* On OpenGL ES, the GL_OES_surfaceless_context extension must be + * present. */ + if (SDL_GL_ExtensionSupported("GL_OES_surfaceless_context")) { + _this->gl_allow_no_surface = SDL_TRUE; + } +#if defined(SDL_VIDEO_OPENGL) && !defined(SDL_VIDEO_DRIVER_VITA) + } else { + /* Desktop OpenGL supports it by default from version 3.0 on. */ + void(APIENTRY * glGetIntegervFunc)(GLenum pname, GLint * params); + glGetIntegervFunc = SDL_GL_GetProcAddress("glGetIntegerv"); + if (glGetIntegervFunc) { + GLint v = 0; + glGetIntegervFunc(GL_MAJOR_VERSION, &v); + if (v >= 3) { + _this->gl_allow_no_surface = SDL_TRUE; + } + } +#endif } } - - return 0; + + return (SDL_GLContext)egl_context; } -int -SDL_EGL_SetSwapInterval(_THIS, int interval) +int SDL_EGL_MakeCurrent(_THIS, EGLSurface egl_surface, SDL_GLContext context) { - EGLBoolean status; - + EGLContext egl_context = (EGLContext)context; + if (!_this->egl_data) { return SDL_SetError("EGL not initialized"); } - + + if (!_this->egl_data->eglMakeCurrent) { + if (!egl_surface && !context) { + /* Can't do the nothing there is to do? Probably trying to cleanup a failed startup, just return. */ + return 0; + } else { + return SDL_SetError("EGL not initialized"); /* something clearly went wrong somewhere. */ + } + } + + /* Make sure current thread has a valid API bound to it. */ + if (_this->egl_data->eglBindAPI) { + _this->egl_data->eglBindAPI(_this->egl_data->apitype); + } + + /* The android emulator crashes badly if you try to eglMakeCurrent + * with a valid context and invalid surface, so we have to check for both here. + */ + if (!egl_context || (!egl_surface && !_this->gl_allow_no_surface)) { + _this->egl_data->eglMakeCurrent(_this->egl_data->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + } else { + if (!_this->egl_data->eglMakeCurrent(_this->egl_data->egl_display, + egl_surface, egl_surface, egl_context)) { + return SDL_EGL_SetError("Unable to make EGL context current", "eglMakeCurrent"); + } + } + + return 0; +} + +int SDL_EGL_SetSwapInterval(_THIS, int interval) +{ + EGLBoolean status; + + if (!_this->egl_data) { + return SDL_SetError("EGL not initialized"); + } + + /* FIXME: Revisit this check when EGL_EXT_swap_control_tear is published: + * https://github.com/KhronosGroup/EGL-Registry/pull/113 + */ + if (interval < 0) { + return SDL_SetError("Late swap tearing currently unsupported"); + } + status = _this->egl_data->eglSwapInterval(_this->egl_data->egl_display, interval); if (status == EGL_TRUE) { _this->egl_data->egl_swapinterval = interval; return 0; } - + return SDL_EGL_SetError("Unable to set the EGL swap interval", "eglSwapInterval"); } -int -SDL_EGL_GetSwapInterval(_THIS) +int SDL_EGL_GetSwapInterval(_THIS) { if (!_this->egl_data) { SDL_SetError("EGL not initialized"); return 0; } - + return _this->egl_data->egl_swapinterval; } -int -SDL_EGL_SwapBuffers(_THIS, EGLSurface egl_surface) +int SDL_EGL_SwapBuffers(_THIS, EGLSurface egl_surface) { if (!_this->egl_data->eglSwapBuffers(_this->egl_data->egl_display, egl_surface)) { return SDL_EGL_SetError("unable to show color buffer in an OS-native window", "eglSwapBuffers"); @@ -1007,52 +1163,47 @@ SDL_EGL_SwapBuffers(_THIS, EGLSurface egl_surface) return 0; } -void -SDL_EGL_DeleteContext(_THIS, SDL_GLContext context) +void SDL_EGL_DeleteContext(_THIS, SDL_GLContext context) { - EGLContext egl_context = (EGLContext) context; + EGLContext egl_context = (EGLContext)context; /* Clean up GLES and EGL */ if (!_this->egl_data) { return; } - + if (egl_context != NULL && egl_context != EGL_NO_CONTEXT) { _this->egl_data->eglDestroyContext(_this->egl_data->egl_display, egl_context); } - } -EGLSurface * -SDL_EGL_CreateSurface(_THIS, NativeWindowType nw) +EGLSurface *SDL_EGL_CreateSurface(_THIS, NativeWindowType nw) { - /* max 2 values plus terminator. */ - EGLint attribs[3]; +#ifdef SDL_VIDEO_DRIVER_ANDROID + EGLint format_wanted; + EGLint format_got; +#endif + /* max 2 key+value pairs, plus terminator. */ + EGLint attribs[5]; int attr = 0; - EGLSurface * surface; + EGLSurface *surface; if (SDL_EGL_ChooseConfig(_this) != 0) { return EGL_NO_SURFACE; } - -#if SDL_VIDEO_DRIVER_ANDROID - { - /* Android docs recommend doing this! - * Ref: http://developer.android.com/reference/android/app/NativeActivity.html - */ - EGLint format; - _this->egl_data->eglGetConfigAttrib(_this->egl_data->egl_display, - _this->egl_data->egl_config, - EGL_NATIVE_VISUAL_ID, &format); - ANativeWindow_setBuffersGeometry(nw, 0, 0, format); +#ifdef SDL_VIDEO_DRIVER_ANDROID + /* On Android, EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is + * guaranteed to be accepted by ANativeWindow_setBuffersGeometry(). */ + _this->egl_data->eglGetConfigAttrib(_this->egl_data->egl_display, + _this->egl_data->egl_config, + EGL_NATIVE_VISUAL_ID, &format_wanted); + + /* Format based on selected egl config. */ + ANativeWindow_setBuffersGeometry(nw, 0, 0, format_wanted); +#endif - /* Update SurfaceView holder format. - * May triggers a sequence surfaceDestroyed(), surfaceCreated(), surfaceChanged(). */ - Android_JNI_SetSurfaceViewFormat(format); - } -#endif if (_this->gl_config.framebuffer_srgb_capable) { #ifdef EGL_KHR_gl_colorspace if (SDL_EGL_HasExtension(_this, SDL_EGL_DISPLAY_EXTENSION, "EGL_KHR_gl_colorspace")) { @@ -1066,15 +1217,29 @@ SDL_EGL_CreateSurface(_THIS, NativeWindowType nw) } } +#ifdef EGL_EXT_present_opaque + if (SDL_EGL_HasExtension(_this, SDL_EGL_DISPLAY_EXTENSION, "EGL_EXT_present_opaque")) { + const SDL_bool allow_transparent = SDL_GetHintBoolean(SDL_HINT_VIDEO_EGL_ALLOW_TRANSPARENCY, SDL_FALSE); + attribs[attr++] = EGL_PRESENT_OPAQUE_EXT; + attribs[attr++] = allow_transparent ? EGL_FALSE : EGL_TRUE; + } +#endif + attribs[attr++] = EGL_NONE; - + surface = _this->egl_data->eglCreateWindowSurface( - _this->egl_data->egl_display, - _this->egl_data->egl_config, - nw, &attribs[0]); + _this->egl_data->egl_display, + _this->egl_data->egl_config, + nw, &attribs[0]); if (surface == EGL_NO_SURFACE) { SDL_EGL_SetError("unable to create an EGL window surface", "eglCreateWindowSurface"); } + +#ifdef SDL_VIDEO_DRIVER_ANDROID + format_got = ANativeWindow_getFormat(nw); + Android_SetFormat(format_wanted, format_got); +#endif + return surface; } @@ -1082,10 +1247,12 @@ EGLSurface SDL_EGL_CreateOffscreenSurface(_THIS, int width, int height) { EGLint attributes[] = { - EGL_WIDTH, width, - EGL_HEIGHT, height, + EGL_WIDTH, 0, + EGL_HEIGHT, 0, EGL_NONE }; + attributes[1] = width; + attributes[3] = height; if (SDL_EGL_ChooseConfig(_this) != 0) { return EGL_NO_SURFACE; @@ -1097,13 +1264,12 @@ SDL_EGL_CreateOffscreenSurface(_THIS, int width, int height) attributes); } -void -SDL_EGL_DestroySurface(_THIS, EGLSurface egl_surface) +void SDL_EGL_DestroySurface(_THIS, EGLSurface egl_surface) { if (!_this->egl_data) { return; } - + if (egl_surface != EGL_NO_SURFACE) { _this->egl_data->eglDestroySurface(_this->egl_data->egl_display, egl_surface); } @@ -1112,4 +1278,3 @@ SDL_EGL_DestroySurface(_THIS, EGLSurface egl_surface) #endif /* SDL_VIDEO_OPENGL_EGL */ /* vi: set ts=4 sw=4 expandtab: */ - diff --git a/SDL2-2.0.12/src/video/SDL_egl_c.h b/SDL2-2.30.5/src/video/SDL_egl_c.h similarity index 66% rename from SDL2-2.0.12/src/video/SDL_egl_c.h rename to SDL2-2.30.5/src/video/SDL_egl_c.h index 83bd634..3fc2977 100644 --- a/SDL2-2.0.12/src/video/SDL_egl_c.h +++ b/SDL2-2.30.5/src/video/SDL_egl_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,24 +23,26 @@ #ifndef SDL_egl_h_ #define SDL_egl_h_ -#if SDL_VIDEO_OPENGL_EGL +#ifdef SDL_VIDEO_OPENGL_EGL #include "SDL_egl.h" #include "SDL_sysvideo.h" -#define SDL_EGL_MAX_DEVICES 8 +#define SDL_EGL_MAX_DEVICES 8 typedef struct SDL_EGL_VideoData { - void *egl_dll_handle, *dll_handle; + void *opengl_dll_handle, *egl_dll_handle; EGLDisplay egl_display; EGLConfig egl_config; int egl_swapinterval; int egl_surfacetype; int egl_version_major, egl_version_minor; EGLint egl_required_visual_id; - + SDL_bool is_offscreen; /* whether EGL display was offscreen */ + EGLenum apitype; /* EGL_OPENGL_ES_API, EGL_OPENGL_API, etc */ + EGLDisplay(EGLAPIENTRY *eglGetDisplay) (NativeDisplayType display); EGLDisplay(EGLAPIENTRY *eglGetPlatformDisplay) (EGLenum platform, void *native_display, @@ -51,21 +53,21 @@ typedef struct SDL_EGL_VideoData EGLBoolean(EGLAPIENTRY *eglInitialize) (EGLDisplay dpy, EGLint * major, EGLint * minor); EGLBoolean(EGLAPIENTRY *eglTerminate) (EGLDisplay dpy); - + void *(EGLAPIENTRY *eglGetProcAddress) (const char * procName); - + EGLBoolean(EGLAPIENTRY *eglChooseConfig) (EGLDisplay dpy, const EGLint * attrib_list, EGLConfig * configs, EGLint config_size, EGLint * num_config); - + EGLContext(EGLAPIENTRY *eglCreateContext) (EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint * attrib_list); - + EGLBoolean(EGLAPIENTRY *eglDestroyContext) (EGLDisplay dpy, EGLContext ctx); - + EGLSurface(EGLAPIENTRY *eglCreatePbufferSurface)(EGLDisplay dpy, EGLConfig config, EGLint const* attrib_list); @@ -74,25 +76,25 @@ typedef struct SDL_EGL_VideoData NativeWindowType window, const EGLint * attrib_list); EGLBoolean(EGLAPIENTRY *eglDestroySurface) (EGLDisplay dpy, EGLSurface surface); - + EGLBoolean(EGLAPIENTRY *eglMakeCurrent) (EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx); - + EGLBoolean(EGLAPIENTRY *eglSwapBuffers) (EGLDisplay dpy, EGLSurface draw); - + EGLBoolean(EGLAPIENTRY *eglSwapInterval) (EGLDisplay dpy, EGLint interval); - + const char *(EGLAPIENTRY *eglQueryString) (EGLDisplay dpy, EGLint name); EGLenum(EGLAPIENTRY *eglQueryAPI)(void); - + EGLBoolean(EGLAPIENTRY *eglGetConfigAttrib) (EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint * value); - + EGLBoolean(EGLAPIENTRY *eglWaitNative) (EGLint engine); EGLBoolean(EGLAPIENTRY *eglWaitGL)(void); - + EGLBoolean(EGLAPIENTRY *eglBindAPI)(EGLenum); EGLint(EGLAPIENTRY *eglGetError)(void); @@ -101,12 +103,30 @@ typedef struct SDL_EGL_VideoData void **devices, EGLint *num_devices); - /* whether EGL display was offscreen */ - int is_offscreen; + /* Atomic functions */ + EGLSyncKHR(EGLAPIENTRY *eglCreateSyncKHR)(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list); + + EGLBoolean(EGLAPIENTRY *eglDestroySyncKHR)(EGLDisplay dpy, EGLSyncKHR sync); + + EGLint(EGLAPIENTRY *eglDupNativeFenceFDANDROID)(EGLDisplay dpy, EGLSyncKHR sync); + + EGLint(EGLAPIENTRY *eglWaitSyncKHR)(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags); + + EGLint(EGLAPIENTRY *eglClientWaitSyncKHR)(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout); + + /* Atomic functions end */ } SDL_EGL_VideoData; /* OpenGLES functions */ +typedef enum SDL_EGL_ExtensionType +{ + SDL_EGL_DISPLAY_EXTENSION, + SDL_EGL_CLIENT_EXTENSION +} SDL_EGL_ExtensionType; + +extern SDL_bool SDL_EGL_HasExtension(_THIS, SDL_EGL_ExtensionType type, const char *ext); + extern int SDL_EGL_GetAttribute(_THIS, SDL_GLattr attrib, int *value); /* SDL_EGL_LoadLibrary can get a display for a specific platform (EGL_PLATFORM_*) * or, if 0 is passed, let the implementation decide. @@ -133,33 +153,31 @@ extern int SDL_EGL_MakeCurrent(_THIS, EGLSurface egl_surface, SDL_GLContext cont extern int SDL_EGL_SwapBuffers(_THIS, EGLSurface egl_surface); /* SDL Error-reporting */ -extern int SDL_EGL_SetErrorEx(const char * message, const char * eglFunctionName, EGLint eglErrorCode); +extern int SDL_EGL_SetErrorEx(const char *message, const char *eglFunctionName, EGLint eglErrorCode); #define SDL_EGL_SetError(message, eglFunctionName) SDL_EGL_SetErrorEx(message, eglFunctionName, _this->egl_data->eglGetError()) /* A few of useful macros */ -#define SDL_EGL_SwapWindow_impl(BACKEND) int \ -BACKEND ## _GLES_SwapWindow(_THIS, SDL_Window * window) \ -{\ - return SDL_EGL_SwapBuffers(_this, ((SDL_WindowData *) window->driverdata)->egl_surface);\ -} +#define SDL_EGL_SwapWindow_impl(BACKEND) \ + int \ + BACKEND##_GLES_SwapWindow(_THIS, SDL_Window *window) \ + { \ + return SDL_EGL_SwapBuffers(_this, ((SDL_WindowData *)window->driverdata)->egl_surface); \ + } -#define SDL_EGL_MakeCurrent_impl(BACKEND) int \ -BACKEND ## _GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) \ -{\ - if (window && context) { \ - return SDL_EGL_MakeCurrent(_this, ((SDL_WindowData *) window->driverdata)->egl_surface, context); \ - }\ - else {\ - return SDL_EGL_MakeCurrent(_this, NULL, NULL);\ - }\ -} +#define SDL_EGL_MakeCurrent_impl(BACKEND) \ + int \ + BACKEND##_GLES_MakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context) \ + { \ + return SDL_EGL_MakeCurrent(_this, window ? ((SDL_WindowData *)window->driverdata)->egl_surface : EGL_NO_SURFACE, context); \ + } -#define SDL_EGL_CreateContext_impl(BACKEND) SDL_GLContext \ -BACKEND ## _GLES_CreateContext(_THIS, SDL_Window * window) \ -{\ - return SDL_EGL_CreateContext(_this, ((SDL_WindowData *) window->driverdata)->egl_surface);\ -} +#define SDL_EGL_CreateContext_impl(BACKEND) \ + SDL_GLContext \ + BACKEND##_GLES_CreateContext(_THIS, SDL_Window *window) \ + { \ + return SDL_EGL_CreateContext(_this, ((SDL_WindowData *)window->driverdata)->egl_surface); \ + } #endif /* SDL_VIDEO_OPENGL_EGL */ diff --git a/SDL2-2.0.12/src/video/SDL_fillrect.c b/SDL2-2.30.5/src/video/SDL_fillrect.c similarity index 60% rename from SDL2-2.0.12/src/video/SDL_fillrect.c rename to SDL2-2.30.5/src/video/SDL_fillrect.c index ecc5fe5..d7d112f 100644 --- a/SDL2-2.0.12/src/video/SDL_fillrect.c +++ b/SDL2-2.30.5/src/video/SDL_fillrect.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -24,11 +24,10 @@ #include "SDL_blit.h" #include "SDL_cpuinfo.h" - #ifdef __SSE__ -/* *INDENT-OFF* */ +/* *INDENT-OFF* */ /* clang-format off */ -#ifdef _MSC_VER +#if defined(_MSC_VER) && !defined(__clang__) #define SSE_BEGIN \ __m128 c128; \ c128.m128_u32[0] = color; \ @@ -58,8 +57,7 @@ #define SSE_END #define DEFINE_SSE_FILLRECT(bpp, type) \ -static void \ -SDL_FillRect##bpp##SSE(Uint8 *pixels, int pitch, Uint32 color, int w, int h) \ +static void SDL_FillRect##bpp##SSE(Uint8 *pixels, int pitch, Uint32 color, int w, int h) \ { \ int i, n; \ Uint8 *p = NULL; \ @@ -96,8 +94,7 @@ SDL_FillRect##bpp##SSE(Uint8 *pixels, int pitch, Uint32 color, int w, int h) \ SSE_END; \ } -static void -SDL_FillRect1SSE(Uint8 *pixels, int pitch, Uint32 color, int w, int h) +static void SDL_FillRect1SSE(Uint8 *pixels, int pitch, Uint32 color, int w, int h) { int i, n; @@ -128,30 +125,31 @@ SDL_FillRect1SSE(Uint8 *pixels, int pitch, Uint32 color, int w, int h) DEFINE_SSE_FILLRECT(2, Uint16) DEFINE_SSE_FILLRECT(4, Uint32) -/* *INDENT-ON* */ -#endif /* __SSE__ */ +/* *INDENT-ON* */ /* clang-format on */ +#endif /* __SSE__ */ -static void -SDL_FillRect1(Uint8 * pixels, int pitch, Uint32 color, int w, int h) +static void SDL_FillRect1(Uint8 *pixels, int pitch, Uint32 color, int w, int h) { int n; Uint8 *p = NULL; - + while (h--) { n = w; p = pixels; if (n > 3) { - switch ((uintptr_t) p & 3) { + switch ((uintptr_t)p & 3) { case 1: - *p++ = (Uint8) color; - --n; /* fallthrough */ + *p++ = (Uint8)color; + --n; + SDL_FALLTHROUGH; case 2: - *p++ = (Uint8) color; - --n; /* fallthrough */ + *p++ = (Uint8)color; + --n; + SDL_FALLTHROUGH; case 3: - *p++ = (Uint8) color; - --n; /* fallthrough */ + *p++ = (Uint8)color; + --n; } SDL_memset4(p, color, (n >> 2)); } @@ -159,52 +157,52 @@ SDL_FillRect1(Uint8 * pixels, int pitch, Uint32 color, int w, int h) p += (n & ~3); switch (n & 3) { case 3: - *p++ = (Uint8) color; /* fallthrough */ + *p++ = (Uint8)color; + SDL_FALLTHROUGH; case 2: - *p++ = (Uint8) color; /* fallthrough */ + *p++ = (Uint8)color; + SDL_FALLTHROUGH; case 1: - *p++ = (Uint8) color; /* fallthrough */ + *p++ = (Uint8)color; } } pixels += pitch; } } -static void -SDL_FillRect2(Uint8 * pixels, int pitch, Uint32 color, int w, int h) +static void SDL_FillRect2(Uint8 *pixels, int pitch, Uint32 color, int w, int h) { int n; Uint16 *p = NULL; - + while (h--) { n = w; - p = (Uint16 *) pixels; + p = (Uint16 *)pixels; if (n > 1) { - if ((uintptr_t) p & 2) { - *p++ = (Uint16) color; + if ((uintptr_t)p & 2) { + *p++ = (Uint16)color; --n; } SDL_memset4(p, color, (n >> 1)); } if (n & 1) { - p[n - 1] = (Uint16) color; + p[n - 1] = (Uint16)color; } pixels += pitch; } } -static void -SDL_FillRect3(Uint8 * pixels, int pitch, Uint32 color, int w, int h) +static void SDL_FillRect3(Uint8 *pixels, int pitch, Uint32 color, int w, int h) { #if SDL_BYTEORDER == SDL_LIL_ENDIAN - Uint8 b1 = (Uint8) (color & 0xFF); - Uint8 b2 = (Uint8) ((color >> 8) & 0xFF); - Uint8 b3 = (Uint8) ((color >> 16) & 0xFF); + Uint8 b1 = (Uint8)(color & 0xFF); + Uint8 b2 = (Uint8)((color >> 8) & 0xFF); + Uint8 b3 = (Uint8)((color >> 16) & 0xFF); #elif SDL_BYTEORDER == SDL_BIG_ENDIAN - Uint8 b1 = (Uint8) ((color >> 16) & 0xFF); - Uint8 b2 = (Uint8) ((color >> 8) & 0xFF); - Uint8 b3 = (Uint8) (color & 0xFF); + Uint8 b1 = (Uint8)((color >> 16) & 0xFF); + Uint8 b2 = (Uint8)((color >> 8) & 0xFF); + Uint8 b3 = (Uint8)(color & 0xFF); #endif int n; Uint8 *p = NULL; @@ -222,8 +220,7 @@ SDL_FillRect3(Uint8 * pixels, int pitch, Uint32 color, int w, int h) } } -static void -SDL_FillRect4(Uint8 * pixels, int pitch, Uint32 color, int w, int h) +static void SDL_FillRect4(Uint8 *pixels, int pitch, Uint32 color, int w, int h) { while (h--) { SDL_memset4(pixels, color, w); @@ -231,14 +228,13 @@ SDL_FillRect4(Uint8 * pixels, int pitch, Uint32 color, int w, int h) } } -/* +/* * This function performs a fast fill of the given rectangle with 'color' */ -int -SDL_FillRect(SDL_Surface * dst, const SDL_Rect * rect, Uint32 color) +int SDL_FillRect(SDL_Surface *dst, const SDL_Rect *rect, Uint32 color) { if (!dst) { - return SDL_SetError("Passed NULL destination surface"); + return SDL_InvalidParamError("SDL_FillRect(): dst"); } /* If 'rect' == NULL, then fill the whole surface */ @@ -253,78 +249,100 @@ SDL_FillRect(SDL_Surface * dst, const SDL_Rect * rect, Uint32 color) return SDL_FillRects(dst, rect, 1, color); } -#if SDL_ARM_NEON_BLITTERS +#ifdef SDL_ARM_NEON_BLITTERS void FillRect8ARMNEONAsm(int32_t w, int32_t h, uint8_t *dst, int32_t dst_stride, uint8_t src); void FillRect16ARMNEONAsm(int32_t w, int32_t h, uint16_t *dst, int32_t dst_stride, uint16_t src); void FillRect32ARMNEONAsm(int32_t w, int32_t h, uint32_t *dst, int32_t dst_stride, uint32_t src); -static void fill_8_neon(Uint8 * pixels, int pitch, Uint32 color, int w, int h) { - FillRect8ARMNEONAsm(w, h, (uint8_t *) pixels, pitch >> 0, color); +static void fill_8_neon(Uint8 *pixels, int pitch, Uint32 color, int w, int h) +{ + FillRect8ARMNEONAsm(w, h, (uint8_t *)pixels, pitch >> 0, color); return; } -static void fill_16_neon(Uint8 * pixels, int pitch, Uint32 color, int w, int h) { - FillRect16ARMNEONAsm(w, h, (uint16_t *) pixels, pitch >> 1, color); +static void fill_16_neon(Uint8 *pixels, int pitch, Uint32 color, int w, int h) +{ + FillRect16ARMNEONAsm(w, h, (uint16_t *)pixels, pitch >> 1, color); return; } -static void fill_32_neon(Uint8 * pixels, int pitch, Uint32 color, int w, int h) { - FillRect32ARMNEONAsm(w, h, (uint32_t *) pixels, pitch >> 2, color); +static void fill_32_neon(Uint8 *pixels, int pitch, Uint32 color, int w, int h) +{ + FillRect32ARMNEONAsm(w, h, (uint32_t *)pixels, pitch >> 2, color); return; } #endif -#if SDL_ARM_SIMD_BLITTERS +#ifdef SDL_ARM_SIMD_BLITTERS void FillRect8ARMSIMDAsm(int32_t w, int32_t h, uint8_t *dst, int32_t dst_stride, uint8_t src); void FillRect16ARMSIMDAsm(int32_t w, int32_t h, uint16_t *dst, int32_t dst_stride, uint16_t src); void FillRect32ARMSIMDAsm(int32_t w, int32_t h, uint32_t *dst, int32_t dst_stride, uint32_t src); -static void fill_8_simd(Uint8 * pixels, int pitch, Uint32 color, int w, int h) { - FillRect8ARMSIMDAsm(w, h, (uint8_t *) pixels, pitch >> 0, color); +static void fill_8_simd(Uint8 *pixels, int pitch, Uint32 color, int w, int h) +{ + FillRect8ARMSIMDAsm(w, h, (uint8_t *)pixels, pitch >> 0, color); return; } -static void fill_16_simd(Uint8 * pixels, int pitch, Uint32 color, int w, int h) { - FillRect16ARMSIMDAsm(w, h, (uint16_t *) pixels, pitch >> 1, color); +static void fill_16_simd(Uint8 *pixels, int pitch, Uint32 color, int w, int h) +{ + FillRect16ARMSIMDAsm(w, h, (uint16_t *)pixels, pitch >> 1, color); return; } -static void fill_32_simd(Uint8 * pixels, int pitch, Uint32 color, int w, int h) { - FillRect32ARMSIMDAsm(w, h, (uint32_t *) pixels, pitch >> 2, color); +static void fill_32_simd(Uint8 *pixels, int pitch, Uint32 color, int w, int h) +{ + FillRect32ARMSIMDAsm(w, h, (uint32_t *)pixels, pitch >> 2, color); return; } #endif -int -SDL_FillRects(SDL_Surface * dst, const SDL_Rect * rects, int count, - Uint32 color) +int SDL_FillRects(SDL_Surface *dst, const SDL_Rect *rects, int count, + Uint32 color) { SDL_Rect clipped; Uint8 *pixels; - const SDL_Rect* rect; + const SDL_Rect *rect; void (*fill_function)(Uint8 * pixels, int pitch, Uint32 color, int w, int h) = NULL; int i; if (!dst) { - return SDL_SetError("Passed NULL destination surface"); + return SDL_InvalidParamError("SDL_FillRects(): dst"); } - /* This function doesn't work on surfaces < 8 bpp */ - if (dst->format->BitsPerPixel < 8) { - return SDL_SetError("SDL_FillRect(): Unsupported surface format"); + /* Nothing to do */ + if (dst->w == 0 || dst->h == 0) { + return 0; } /* Perform software fill */ if (!dst->pixels) { - return SDL_SetError("SDL_FillRect(): You must lock the surface"); + return SDL_SetError("SDL_FillRects(): You must lock the surface"); } if (!rects) { - return SDL_SetError("SDL_FillRects() passed NULL rects"); + return SDL_InvalidParamError("SDL_FillRects(): rects"); } -#if SDL_ARM_NEON_BLITTERS - if (SDL_HasNEON() && dst->format->BytesPerPixel != 3 && fill_function == NULL) { + /* This function doesn't usually work on surfaces < 8 bpp + * Except: support for 4bits, when filling full size. + */ + if (dst->format->BitsPerPixel < 8) { + if (count == 1) { + const SDL_Rect *r = &rects[0]; + if (r->x == 0 && r->y == 0 && r->w == dst->w && r->h == dst->h) { + if (dst->format->BitsPerPixel == 4) { + Uint8 b = (((Uint8)color << 4) | (Uint8)color); + SDL_memset(dst->pixels, b, (size_t)dst->h * dst->pitch); + return 1; + } + } + } + return SDL_SetError("SDL_FillRects(): Unsupported surface format"); + } + +#ifdef SDL_ARM_NEON_BLITTERS + if (SDL_HasNEON() && dst->format->BytesPerPixel != 3 && !fill_function) { switch (dst->format->BytesPerPixel) { case 1: fill_function = fill_8_neon; @@ -338,8 +356,8 @@ SDL_FillRects(SDL_Surface * dst, const SDL_Rect * rects, int count, } } #endif -#if SDL_ARM_SIMD_BLITTERS - if (SDL_HasARMSIMD() && dst->format->BytesPerPixel != 3 && fill_function == NULL) { +#ifdef SDL_ARM_SIMD_BLITTERS + if (SDL_HasARMSIMD() && dst->format->BytesPerPixel != 3 && !fill_function) { switch (dst->format->BytesPerPixel) { case 1: fill_function = fill_8_simd; @@ -354,34 +372,34 @@ SDL_FillRects(SDL_Surface * dst, const SDL_Rect * rects, int count, } #endif - if (fill_function == NULL) { + if (!fill_function) { switch (dst->format->BytesPerPixel) { case 1: - { - color |= (color << 8); - color |= (color << 16); + { + color |= (color << 8); + color |= (color << 16); #ifdef __SSE__ - if (SDL_HasSSE()) { - fill_function = SDL_FillRect1SSE; - break; - } -#endif - fill_function = SDL_FillRect1; + if (SDL_HasSSE()) { + fill_function = SDL_FillRect1SSE; break; } +#endif + fill_function = SDL_FillRect1; + break; + } case 2: - { - color |= (color << 16); + { + color |= (color << 16); #ifdef __SSE__ - if (SDL_HasSSE()) { - fill_function = SDL_FillRect2SSE; - break; - } -#endif - fill_function = SDL_FillRect2; + if (SDL_HasSSE()) { + fill_function = SDL_FillRect2SSE; break; } +#endif + fill_function = SDL_FillRect2; + break; + } case 3: /* 24-bit RGB is a slow path, at least for now. */ @@ -391,16 +409,16 @@ SDL_FillRects(SDL_Surface * dst, const SDL_Rect * rects, int count, } case 4: - { + { #ifdef __SSE__ - if (SDL_HasSSE()) { - fill_function = SDL_FillRect4SSE; - break; - } -#endif - fill_function = SDL_FillRect4; + if (SDL_HasSSE()) { + fill_function = SDL_FillRect4SSE; break; } +#endif + fill_function = SDL_FillRect4; + break; + } default: return SDL_SetError("Unsupported pixel format"); @@ -415,8 +433,8 @@ SDL_FillRects(SDL_Surface * dst, const SDL_Rect * rects, int count, } rect = &clipped; - pixels = (Uint8 *) dst->pixels + rect->y * dst->pitch + - rect->x * dst->format->BytesPerPixel; + pixels = (Uint8 *)dst->pixels + rect->y * dst->pitch + + rect->x * dst->format->BytesPerPixel; fill_function(pixels, dst->pitch, color, rect->w, rect->h); } diff --git a/SDL2-2.0.12/src/video/SDL_pixels.c b/SDL2-2.30.5/src/video/SDL_pixels.c similarity index 68% rename from SDL2-2.0.12/src/video/SDL_pixels.c rename to SDL2-2.30.5/src/video/SDL_pixels.c index f02a2bd..a682178 100644 --- a/SDL2-2.0.12/src/video/SDL_pixels.c +++ b/SDL2-2.30.5/src/video/SDL_pixels.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -28,47 +28,47 @@ #include "SDL_blit.h" #include "SDL_pixels_c.h" #include "SDL_RLEaccel_c.h" - +#include "../SDL_list.h" /* Lookup tables to expand partial bytes to the full 0..255 range */ static Uint8 lookup_0[] = { -0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 }; static Uint8 lookup_1[] = { -0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222, 224, 226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 255 + 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222, 224, 226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 255 }; static Uint8 lookup_2[] = { -0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125, 129, 133, 137, 141, 145, 149, 153, 157, 161, 165, 170, 174, 178, 182, 186, 190, 194, 198, 202, 206, 210, 214, 218, 222, 226, 230, 234, 238, 242, 246, 250, 255 + 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125, 129, 133, 137, 141, 145, 149, 153, 157, 161, 165, 170, 174, 178, 182, 186, 190, 194, 198, 202, 206, 210, 214, 218, 222, 226, 230, 234, 238, 242, 246, 250, 255 }; static Uint8 lookup_3[] = { -0, 8, 16, 24, 32, 41, 49, 57, 65, 74, 82, 90, 98, 106, 115, 123, 131, 139, 148, 156, 164, 172, 180, 189, 197, 205, 213, 222, 230, 238, 246, 255 + 0, 8, 16, 24, 32, 41, 49, 57, 65, 74, 82, 90, 98, 106, 115, 123, 131, 139, 148, 156, 164, 172, 180, 189, 197, 205, 213, 222, 230, 238, 246, 255 }; static Uint8 lookup_4[] = { -0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255 + 0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255 }; static Uint8 lookup_5[] = { -0, 36, 72, 109, 145, 182, 218, 255 + 0, 36, 72, 109, 145, 182, 218, 255 }; static Uint8 lookup_6[] = { -0, 85, 170, 255 + 0, 85, 170, 255 }; static Uint8 lookup_7[] = { -0, 255 + 0, 255 }; static Uint8 lookup_8[] = { -255 + 255 }; -Uint8* SDL_expand_byte[9] = { +Uint8 *SDL_expand_byte[9] = { lookup_0, lookup_1, lookup_2, @@ -82,58 +82,63 @@ Uint8* SDL_expand_byte[9] = { /* Helper functions */ -const char* -SDL_GetPixelFormatName(Uint32 format) +#define CASE(X) \ + case X: \ + return #X; +const char *SDL_GetPixelFormatName(Uint32 format) { switch (format) { -#define CASE(X) case X: return #X; - CASE(SDL_PIXELFORMAT_INDEX1LSB) - CASE(SDL_PIXELFORMAT_INDEX1MSB) - CASE(SDL_PIXELFORMAT_INDEX4LSB) - CASE(SDL_PIXELFORMAT_INDEX4MSB) - CASE(SDL_PIXELFORMAT_INDEX8) - CASE(SDL_PIXELFORMAT_RGB332) - CASE(SDL_PIXELFORMAT_RGB444) - CASE(SDL_PIXELFORMAT_BGR444) - CASE(SDL_PIXELFORMAT_RGB555) - CASE(SDL_PIXELFORMAT_BGR555) - CASE(SDL_PIXELFORMAT_ARGB4444) - CASE(SDL_PIXELFORMAT_RGBA4444) - CASE(SDL_PIXELFORMAT_ABGR4444) - CASE(SDL_PIXELFORMAT_BGRA4444) - CASE(SDL_PIXELFORMAT_ARGB1555) - CASE(SDL_PIXELFORMAT_RGBA5551) - CASE(SDL_PIXELFORMAT_ABGR1555) - CASE(SDL_PIXELFORMAT_BGRA5551) - CASE(SDL_PIXELFORMAT_RGB565) - CASE(SDL_PIXELFORMAT_BGR565) - CASE(SDL_PIXELFORMAT_RGB24) - CASE(SDL_PIXELFORMAT_BGR24) - CASE(SDL_PIXELFORMAT_RGB888) - CASE(SDL_PIXELFORMAT_RGBX8888) - CASE(SDL_PIXELFORMAT_BGR888) - CASE(SDL_PIXELFORMAT_BGRX8888) - CASE(SDL_PIXELFORMAT_ARGB8888) - CASE(SDL_PIXELFORMAT_RGBA8888) - CASE(SDL_PIXELFORMAT_ABGR8888) - CASE(SDL_PIXELFORMAT_BGRA8888) - CASE(SDL_PIXELFORMAT_ARGB2101010) - CASE(SDL_PIXELFORMAT_YV12) - CASE(SDL_PIXELFORMAT_IYUV) - CASE(SDL_PIXELFORMAT_YUY2) - CASE(SDL_PIXELFORMAT_UYVY) - CASE(SDL_PIXELFORMAT_YVYU) - CASE(SDL_PIXELFORMAT_NV12) - CASE(SDL_PIXELFORMAT_NV21) -#undef CASE + + CASE(SDL_PIXELFORMAT_INDEX1LSB) + CASE(SDL_PIXELFORMAT_INDEX1MSB) + CASE(SDL_PIXELFORMAT_INDEX2LSB) + CASE(SDL_PIXELFORMAT_INDEX2MSB) + CASE(SDL_PIXELFORMAT_INDEX4LSB) + CASE(SDL_PIXELFORMAT_INDEX4MSB) + CASE(SDL_PIXELFORMAT_INDEX8) + CASE(SDL_PIXELFORMAT_RGB332) + CASE(SDL_PIXELFORMAT_RGB444) + CASE(SDL_PIXELFORMAT_BGR444) + CASE(SDL_PIXELFORMAT_RGB555) + CASE(SDL_PIXELFORMAT_BGR555) + CASE(SDL_PIXELFORMAT_ARGB4444) + CASE(SDL_PIXELFORMAT_RGBA4444) + CASE(SDL_PIXELFORMAT_ABGR4444) + CASE(SDL_PIXELFORMAT_BGRA4444) + CASE(SDL_PIXELFORMAT_ARGB1555) + CASE(SDL_PIXELFORMAT_RGBA5551) + CASE(SDL_PIXELFORMAT_ABGR1555) + CASE(SDL_PIXELFORMAT_BGRA5551) + CASE(SDL_PIXELFORMAT_RGB565) + CASE(SDL_PIXELFORMAT_BGR565) + CASE(SDL_PIXELFORMAT_RGB24) + CASE(SDL_PIXELFORMAT_BGR24) + CASE(SDL_PIXELFORMAT_RGB888) + CASE(SDL_PIXELFORMAT_RGBX8888) + CASE(SDL_PIXELFORMAT_BGR888) + CASE(SDL_PIXELFORMAT_BGRX8888) + CASE(SDL_PIXELFORMAT_ARGB8888) + CASE(SDL_PIXELFORMAT_RGBA8888) + CASE(SDL_PIXELFORMAT_ABGR8888) + CASE(SDL_PIXELFORMAT_BGRA8888) + CASE(SDL_PIXELFORMAT_ARGB2101010) + CASE(SDL_PIXELFORMAT_YV12) + CASE(SDL_PIXELFORMAT_IYUV) + CASE(SDL_PIXELFORMAT_YUY2) + CASE(SDL_PIXELFORMAT_UYVY) + CASE(SDL_PIXELFORMAT_YVYU) + CASE(SDL_PIXELFORMAT_NV12) + CASE(SDL_PIXELFORMAT_NV21) + CASE(SDL_PIXELFORMAT_EXTERNAL_OES) + default: return "SDL_PIXELFORMAT_UNKNOWN"; } } +#undef CASE -SDL_bool -SDL_PixelFormatEnumToMasks(Uint32 format, int *bpp, Uint32 * Rmask, - Uint32 * Gmask, Uint32 * Bmask, Uint32 * Amask) +SDL_bool SDL_PixelFormatEnumToMasks(Uint32 format, int *bpp, Uint32 *Rmask, + Uint32 *Gmask, Uint32 *Bmask, Uint32 *Amask) { Uint32 masks[4]; @@ -290,14 +295,15 @@ SDL_PixelFormatEnumToMasks(Uint32 format, int *bpp, Uint32 * Rmask, return SDL_TRUE; } -Uint32 -SDL_MasksToPixelFormatEnum(int bpp, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, - Uint32 Amask) +Uint32 SDL_MasksToPixelFormatEnum(int bpp, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) { switch (bpp) { case 1: /* SDL defaults to MSB ordering */ return SDL_PIXELFORMAT_INDEX1MSB; + case 2: + /* SDL defaults to MSB ordering */ + return SDL_PIXELFORMAT_INDEX2MSB; case 4: /* SDL defaults to MSB ordering */ return SDL_PIXELFORMAT_INDEX4MSB; @@ -333,7 +339,7 @@ SDL_MasksToPixelFormatEnum(int bpp, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, if (Rmask == 0) { return SDL_PIXELFORMAT_RGB555; } - /* fallthrough */ + SDL_FALLTHROUGH; case 16: if (Rmask == 0) { return SDL_PIXELFORMAT_RGB565; @@ -434,6 +440,7 @@ SDL_MasksToPixelFormatEnum(int bpp, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, return SDL_PIXELFORMAT_RGB24; #endif } + break; case 32: if (Rmask == 0) { return SDL_PIXELFORMAT_RGB888; @@ -499,8 +506,7 @@ SDL_MasksToPixelFormatEnum(int bpp, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, static SDL_PixelFormat *formats; static SDL_SpinLock formats_lock = 0; -SDL_PixelFormat * -SDL_AllocFormat(Uint32 pixel_format) +SDL_PixelFormat *SDL_AllocFormat(Uint32 pixel_format) { SDL_PixelFormat *format; @@ -517,7 +523,7 @@ SDL_AllocFormat(Uint32 pixel_format) /* Allocate an empty pixel format structure, and initialize it */ format = SDL_malloc(sizeof(*format)); - if (format == NULL) { + if (!format) { SDL_AtomicUnlock(&formats_lock); SDL_OutOfMemory(); return NULL; @@ -525,7 +531,6 @@ SDL_AllocFormat(Uint32 pixel_format) if (SDL_InitFormat(format, pixel_format) < 0) { SDL_AtomicUnlock(&formats_lock); SDL_free(format); - SDL_InvalidParamError("format"); return NULL; } @@ -540,8 +545,7 @@ SDL_AllocFormat(Uint32 pixel_format) return format; } -int -SDL_InitFormat(SDL_PixelFormat * format, Uint32 pixel_format) +int SDL_InitFormat(SDL_PixelFormat *format, Uint32 pixel_format) { int bpp; Uint32 Rmask, Gmask, Bmask, Amask; @@ -562,40 +566,48 @@ SDL_InitFormat(SDL_PixelFormat * format, Uint32 pixel_format) format->Rshift = 0; format->Rloss = 8; if (Rmask) { - for (mask = Rmask; !(mask & 0x01); mask >>= 1) + for (mask = Rmask; !(mask & 0x01); mask >>= 1) { ++format->Rshift; - for (; (mask & 0x01); mask >>= 1) + } + for (; (mask & 0x01); mask >>= 1) { --format->Rloss; + } } format->Gmask = Gmask; format->Gshift = 0; format->Gloss = 8; if (Gmask) { - for (mask = Gmask; !(mask & 0x01); mask >>= 1) + for (mask = Gmask; !(mask & 0x01); mask >>= 1) { ++format->Gshift; - for (; (mask & 0x01); mask >>= 1) + } + for (; (mask & 0x01); mask >>= 1) { --format->Gloss; + } } format->Bmask = Bmask; format->Bshift = 0; format->Bloss = 8; if (Bmask) { - for (mask = Bmask; !(mask & 0x01); mask >>= 1) + for (mask = Bmask; !(mask & 0x01); mask >>= 1) { ++format->Bshift; - for (; (mask & 0x01); mask >>= 1) + } + for (; (mask & 0x01); mask >>= 1) { --format->Bloss; + } } format->Amask = Amask; format->Ashift = 0; format->Aloss = 8; if (Amask) { - for (mask = Amask; !(mask & 0x01); mask >>= 1) + for (mask = Amask; !(mask & 0x01); mask >>= 1) { ++format->Ashift; - for (; (mask & 0x01); mask >>= 1) + } + for (; (mask & 0x01); mask >>= 1) { --format->Aloss; + } } format->palette = NULL; @@ -605,8 +617,7 @@ SDL_InitFormat(SDL_PixelFormat * format, Uint32 pixel_format) return 0; } -void -SDL_FreeFormat(SDL_PixelFormat *format) +void SDL_FreeFormat(SDL_PixelFormat *format) { SDL_PixelFormat *prev; @@ -642,26 +653,26 @@ SDL_FreeFormat(SDL_PixelFormat *format) SDL_free(format); } -SDL_Palette * -SDL_AllocPalette(int ncolors) +SDL_Palette *SDL_AllocPalette(int ncolors) { SDL_Palette *palette; /* Input validation */ if (ncolors < 1) { - SDL_InvalidParamError("ncolors"); - return NULL; + SDL_InvalidParamError("ncolors"); + return NULL; } - palette = (SDL_Palette *) SDL_malloc(sizeof(*palette)); + palette = (SDL_Palette *)SDL_malloc(sizeof(*palette)); if (!palette) { SDL_OutOfMemory(); return NULL; } palette->colors = - (SDL_Color *) SDL_malloc(ncolors * sizeof(*palette->colors)); + (SDL_Color *)SDL_malloc(ncolors * sizeof(*palette->colors)); if (!palette->colors) { SDL_free(palette); + SDL_OutOfMemory(); return NULL; } palette->ncolors = ncolors; @@ -673,11 +684,10 @@ SDL_AllocPalette(int ncolors) return palette; } -int -SDL_SetPixelFormatPalette(SDL_PixelFormat * format, SDL_Palette *palette) +int SDL_SetPixelFormatPalette(SDL_PixelFormat *format, SDL_Palette *palette) { if (!format) { - return SDL_SetError("SDL_SetPixelFormatPalette() passed NULL format"); + return SDL_InvalidParamError("SDL_SetPixelFormatPalette(): format"); } if (palette && palette->ncolors > (1 << format->BitsPerPixel)) { @@ -701,9 +711,8 @@ SDL_SetPixelFormatPalette(SDL_PixelFormat * format, SDL_Palette *palette) return 0; } -int -SDL_SetPaletteColors(SDL_Palette * palette, const SDL_Color * colors, - int firstcolor, int ncolors) +int SDL_SetPaletteColors(SDL_Palette *palette, const SDL_Color *colors, + int firstcolor, int ncolors) { int status = 0; @@ -728,8 +737,7 @@ SDL_SetPaletteColors(SDL_Palette * palette, const SDL_Color * colors, return status; } -void -SDL_FreePalette(SDL_Palette * palette) +void SDL_FreePalette(SDL_Palette *palette) { if (!palette) { SDL_InvalidParamError("palette"); @@ -745,12 +753,12 @@ SDL_FreePalette(SDL_Palette * palette) /* * Calculate an 8-bit (3 red, 3 green, 2 blue) dithered palette of colors */ -void -SDL_DitherColors(SDL_Color * colors, int bpp) +void SDL_DitherColors(SDL_Color *colors, int bpp) { int i; - if (bpp != 8) - return; /* only 8bpp supported right now */ + if (bpp != 8) { + return; /* only 8bpp supported right now */ + } for (i = 0; i < 256; i++) { int r, g, b; @@ -773,8 +781,7 @@ SDL_DitherColors(SDL_Color * colors, int bpp) /* * Match an RGB value to a particular palette index */ -Uint8 -SDL_FindColor(SDL_Palette * pal, Uint8 r, Uint8 g, Uint8 b, Uint8 a) +Uint8 SDL_FindColor(SDL_Palette *pal, Uint8 r, Uint8 g, Uint8 b, Uint8 a) { /* Do colorspace distance matching */ unsigned int smallest; @@ -792,48 +799,93 @@ SDL_FindColor(SDL_Palette * pal, Uint8 r, Uint8 g, Uint8 b, Uint8 a) distance = (rd * rd) + (gd * gd) + (bd * bd) + (ad * ad); if (distance < smallest) { pixel = i; - if (distance == 0) { /* Perfect match! */ + if (distance == 0) { /* Perfect match! */ break; } smallest = distance; } } - return (pixel); + return pixel; +} + +/* Tell whether palette is opaque, and if it has an alpha_channel */ +void SDL_DetectPalette(SDL_Palette *pal, SDL_bool *is_opaque, SDL_bool *has_alpha_channel) +{ + int i; + + { + SDL_bool all_opaque = SDL_TRUE; + for (i = 0; i < pal->ncolors; i++) { + Uint8 alpha_value = pal->colors[i].a; + if (alpha_value != SDL_ALPHA_OPAQUE) { + all_opaque = SDL_FALSE; + break; + } + } + + if (all_opaque) { + /* Palette is opaque, with an alpha channel */ + *is_opaque = SDL_TRUE; + *has_alpha_channel = SDL_TRUE; + return; + } + } + + { + SDL_bool all_transparent = SDL_TRUE; + for (i = 0; i < pal->ncolors; i++) { + Uint8 alpha_value = pal->colors[i].a; + if (alpha_value != SDL_ALPHA_TRANSPARENT) { + all_transparent = SDL_FALSE; + break; + } + } + + if (all_transparent) { + /* Palette is opaque, without an alpha channel */ + *is_opaque = SDL_TRUE; + *has_alpha_channel = SDL_FALSE; + return; + } + } + + /* Palette has alpha values */ + *is_opaque = SDL_FALSE; + *has_alpha_channel = SDL_TRUE; } /* Find the opaque pixel value corresponding to an RGB triple */ -Uint32 -SDL_MapRGB(const SDL_PixelFormat * format, Uint8 r, Uint8 g, Uint8 b) +Uint32 SDL_MapRGB(const SDL_PixelFormat *format, Uint8 r, Uint8 g, Uint8 b) { - if (format->palette == NULL) { - return (r >> format->Rloss) << format->Rshift - | (g >> format->Gloss) << format->Gshift - | (b >> format->Bloss) << format->Bshift | format->Amask; + if (!format) { + SDL_InvalidParamError("format"); + return 0; + } + if (!format->palette) { + return (r >> format->Rloss) << format->Rshift | (g >> format->Gloss) << format->Gshift | (b >> format->Bloss) << format->Bshift | format->Amask; } else { return SDL_FindColor(format->palette, r, g, b, SDL_ALPHA_OPAQUE); } } /* Find the pixel value corresponding to an RGBA quadruple */ -Uint32 -SDL_MapRGBA(const SDL_PixelFormat * format, Uint8 r, Uint8 g, Uint8 b, - Uint8 a) +Uint32 SDL_MapRGBA(const SDL_PixelFormat *format, Uint8 r, Uint8 g, Uint8 b, Uint8 a) { - if (format->palette == NULL) { - return (r >> format->Rloss) << format->Rshift - | (g >> format->Gloss) << format->Gshift - | (b >> format->Bloss) << format->Bshift - | ((a >> format->Aloss) << format->Ashift & format->Amask); + if (!format) { + SDL_InvalidParamError("format"); + return 0; + } + if (!format->palette) { + return (r >> format->Rloss) << format->Rshift | (g >> format->Gloss) << format->Gshift | (b >> format->Bloss) << format->Bshift | ((Uint32)(a >> format->Aloss) << format->Ashift & format->Amask); } else { return SDL_FindColor(format->palette, r, g, b, a); } } -void -SDL_GetRGB(Uint32 pixel, const SDL_PixelFormat * format, Uint8 * r, Uint8 * g, - Uint8 * b) +void SDL_GetRGB(Uint32 pixel, const SDL_PixelFormat *format, Uint8 *r, Uint8 *g, + Uint8 *b) { - if (format->palette == NULL) { + if (!format->palette) { unsigned v; v = (pixel & format->Rmask) >> format->Rshift; *r = SDL_expand_byte[format->Rloss][v]; @@ -852,11 +904,10 @@ SDL_GetRGB(Uint32 pixel, const SDL_PixelFormat * format, Uint8 * r, Uint8 * g, } } -void -SDL_GetRGBA(Uint32 pixel, const SDL_PixelFormat * format, - Uint8 * r, Uint8 * g, Uint8 * b, Uint8 * a) +void SDL_GetRGBA(Uint32 pixel, const SDL_PixelFormat *format, + Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a) { - if (format->palette == NULL) { + if (!format->palette) { unsigned v; v = (pixel & format->Rmask) >> format->Rshift; *r = SDL_expand_byte[format->Rloss][v]; @@ -879,8 +930,7 @@ SDL_GetRGBA(Uint32 pixel, const SDL_PixelFormat * format, } /* Map from Palette to Palette */ -static Uint8 * -Map1to1(SDL_Palette * src, SDL_Palette * dst, int *identical) +static Uint8 *Map1to1(SDL_Palette *src, SDL_Palette *dst, int *identical) { Uint8 *map; int i; @@ -888,34 +938,31 @@ Map1to1(SDL_Palette * src, SDL_Palette * dst, int *identical) if (identical) { if (src->ncolors <= dst->ncolors) { /* If an identical palette, no need to map */ - if (src == dst - || - (SDL_memcmp - (src->colors, dst->colors, - src->ncolors * sizeof(SDL_Color)) == 0)) { + if (src == dst || + (SDL_memcmp(src->colors, dst->colors, + src->ncolors * sizeof(SDL_Color)) == 0)) { *identical = 1; - return (NULL); + return NULL; } } *identical = 0; } - map = (Uint8 *) SDL_malloc(src->ncolors); - if (map == NULL) { + map = (Uint8 *)SDL_calloc(256, sizeof(Uint8)); + if (!map) { SDL_OutOfMemory(); - return (NULL); + return NULL; } for (i = 0; i < src->ncolors; ++i) { map[i] = SDL_FindColor(dst, src->colors[i].r, src->colors[i].g, src->colors[i].b, src->colors[i].a); } - return (map); + return map; } /* Map from Palette to BitField */ -static Uint8 * -Map1toN(SDL_PixelFormat * src, Uint8 Rmod, Uint8 Gmod, Uint8 Bmod, Uint8 Amod, - SDL_PixelFormat * dst) +static Uint8 *Map1toN(SDL_PixelFormat *src, Uint8 Rmod, Uint8 Gmod, Uint8 Bmod, Uint8 Amod, + SDL_PixelFormat *dst) { Uint8 *map; int i; @@ -923,26 +970,25 @@ Map1toN(SDL_PixelFormat * src, Uint8 Rmod, Uint8 Gmod, Uint8 Bmod, Uint8 Amod, SDL_Palette *pal = src->palette; bpp = ((dst->BytesPerPixel == 3) ? 4 : dst->BytesPerPixel); - map = (Uint8 *) SDL_malloc(pal->ncolors * bpp); - if (map == NULL) { + map = (Uint8 *)SDL_calloc(256, bpp); + if (!map) { SDL_OutOfMemory(); - return (NULL); + return NULL; } /* We memory copy to the pixel map so the endianness is preserved */ for (i = 0; i < pal->ncolors; ++i) { - Uint8 R = (Uint8) ((pal->colors[i].r * Rmod) / 255); - Uint8 G = (Uint8) ((pal->colors[i].g * Gmod) / 255); - Uint8 B = (Uint8) ((pal->colors[i].b * Bmod) / 255); - Uint8 A = (Uint8) ((pal->colors[i].a * Amod) / 255); - ASSEMBLE_RGBA(&map[i * bpp], dst->BytesPerPixel, dst, R, G, B, A); + Uint8 R = (Uint8)((pal->colors[i].r * Rmod) / 255); + Uint8 G = (Uint8)((pal->colors[i].g * Gmod) / 255); + Uint8 B = (Uint8)((pal->colors[i].b * Bmod) / 255); + Uint8 A = (Uint8)((pal->colors[i].a * Amod) / 255); + ASSEMBLE_RGBA(&map[i * bpp], dst->BytesPerPixel, dst, (Uint32)R, (Uint32)G, (Uint32)B, (Uint32)A); } - return (map); + return map; } /* Map from BitField to Dithered-Palette to Palette */ -static Uint8 * -MapNto1(SDL_PixelFormat * src, SDL_PixelFormat * dst, int *identical) +static Uint8 *MapNto1(SDL_PixelFormat *src, SDL_PixelFormat *dst, int *identical) { /* Generate a 256 color dither palette */ SDL_Palette dithered; @@ -952,19 +998,18 @@ MapNto1(SDL_PixelFormat * src, SDL_PixelFormat * dst, int *identical) dithered.ncolors = 256; SDL_DitherColors(colors, 8); dithered.colors = colors; - return (Map1to1(&dithered, pal, identical)); + return Map1to1(&dithered, pal, identical); } -SDL_BlitMap * -SDL_AllocBlitMap(void) +SDL_BlitMap *SDL_AllocBlitMap(void) { SDL_BlitMap *map; /* Allocate the empty map */ - map = (SDL_BlitMap *) SDL_calloc(1, sizeof(*map)); - if (map == NULL) { + map = (SDL_BlitMap *)SDL_calloc(1, sizeof(*map)); + if (!map) { SDL_OutOfMemory(); - return (NULL); + return NULL; } map->info.r = 0xFF; map->info.g = 0xFF; @@ -972,20 +1017,31 @@ SDL_AllocBlitMap(void) map->info.a = 0xFF; /* It's ready to go */ - return (map); + return map; } -void -SDL_InvalidateMap(SDL_BlitMap * map) +void SDL_InvalidateAllBlitMap(SDL_Surface *surface) +{ + SDL_ListNode *l = surface->list_blitmap; + + surface->list_blitmap = NULL; + + while (l) { + SDL_ListNode *tmp = l; + SDL_InvalidateMap((SDL_BlitMap *)l->entry); + l = l->next; + SDL_free(tmp); + } +} + +void SDL_InvalidateMap(SDL_BlitMap *map) { if (!map) { return; } if (map->dst) { - /* Release our reference to the surface - see the note below */ - if (--map->dst->refcount <= 0) { - SDL_FreeSurface(map->dst); - } + /* Un-register from the destination surface */ + SDL_ListRemove((SDL_ListNode **)&(map->dst->list_blitmap), map); } map->dst = NULL; map->src_palette_version = 0; @@ -994,8 +1050,7 @@ SDL_InvalidateMap(SDL_BlitMap * map) map->info.table = NULL; } -int -SDL_MapSurface(SDL_Surface * src, SDL_Surface * dst) +int SDL_MapSurface(SDL_Surface *src, SDL_Surface *dst) { SDL_PixelFormat *srcfmt; SDL_PixelFormat *dstfmt; @@ -1020,19 +1075,20 @@ SDL_MapSurface(SDL_Surface * src, SDL_Surface * dst) map->info.table = Map1to1(srcfmt->palette, dstfmt->palette, &map->identity); if (!map->identity) { - if (map->info.table == NULL) { - return (-1); + if (!map->info.table) { + return -1; } } - if (srcfmt->BitsPerPixel != dstfmt->BitsPerPixel) + if (srcfmt->BitsPerPixel != dstfmt->BitsPerPixel) { map->identity = 0; + } } else { /* Palette --> BitField */ map->info.table = Map1toN(srcfmt, src->map->info.r, src->map->info.g, src->map->info.b, src->map->info.a, dstfmt); - if (map->info.table == NULL) { - return (-1); + if (!map->info.table) { + return -1; } } } else { @@ -1040,11 +1096,11 @@ SDL_MapSurface(SDL_Surface * src, SDL_Surface * dst) /* BitField --> Palette */ map->info.table = MapNto1(srcfmt, dstfmt, &map->identity); if (!map->identity) { - if (map->info.table == NULL) { - return (-1); + if (!map->info.table) { + return -1; } } - map->identity = 0; /* Don't optimize to copy */ + map->identity = 0; /* Don't optimize to copy */ } else { /* BitField --> BitField */ if (srcfmt == dstfmt) { @@ -1056,14 +1112,8 @@ SDL_MapSurface(SDL_Surface * src, SDL_Surface * dst) map->dst = dst; if (map->dst) { - /* Keep a reference to this surface so it doesn't get deleted - while we're still pointing at it. - - A better method would be for the destination surface to keep - track of surfaces that are mapped to it and automatically - invalidate them when it is freed, but this will do for now. - */ - ++map->dst->refcount; + /* Register BlitMap to the destination surface, to be invalidated when needed */ + SDL_ListAdd((SDL_ListNode **)&(map->dst->list_blitmap), map); } if (dstfmt->palette) { @@ -1079,11 +1129,10 @@ SDL_MapSurface(SDL_Surface * src, SDL_Surface * dst) } /* Choose your blitters wisely */ - return (SDL_CalculateBlit(src)); + return SDL_CalculateBlit(src); } -void -SDL_FreeBlitMap(SDL_BlitMap * map) +void SDL_FreeBlitMap(SDL_BlitMap *map) { if (map) { SDL_InvalidateMap(map); @@ -1091,8 +1140,7 @@ SDL_FreeBlitMap(SDL_BlitMap * map) } } -void -SDL_CalculateGammaRamp(float gamma, Uint16 * ramp) +void SDL_CalculateGammaRamp(float gamma, Uint16 * ramp) { int i; @@ -1101,7 +1149,7 @@ SDL_CalculateGammaRamp(float gamma, Uint16 * ramp) SDL_InvalidParamError("gamma"); return; } - if (ramp == NULL) { + if (!ramp) { SDL_InvalidParamError("ramp"); return; } diff --git a/SDL2-2.0.12/src/video/SDL_pixels_c.h b/SDL2-2.30.5/src/video/SDL_pixels_c.h similarity index 67% rename from SDL2-2.0.12/src/video/SDL_pixels_c.h rename to SDL2-2.30.5/src/video/SDL_pixels_c.h index c4baf41..7b5eff3 100644 --- a/SDL2-2.0.12/src/video/SDL_pixels_c.h +++ b/SDL2-2.30.5/src/video/SDL_pixels_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -29,17 +29,20 @@ #include "SDL_blit.h" /* Pixel format functions */ -extern int SDL_InitFormat(SDL_PixelFormat * format, Uint32 pixel_format); +extern int SDL_InitFormat(SDL_PixelFormat *format, Uint32 pixel_format); /* Blit mapping functions */ extern SDL_BlitMap *SDL_AllocBlitMap(void); -extern void SDL_InvalidateMap(SDL_BlitMap * map); -extern int SDL_MapSurface(SDL_Surface * src, SDL_Surface * dst); -extern void SDL_FreeBlitMap(SDL_BlitMap * map); +extern void SDL_InvalidateMap(SDL_BlitMap *map); +extern int SDL_MapSurface(SDL_Surface *src, SDL_Surface *dst); +extern void SDL_FreeBlitMap(SDL_BlitMap *map); + +extern void SDL_InvalidateAllBlitMap(SDL_Surface *surface); /* Miscellaneous functions */ -extern void SDL_DitherColors(SDL_Color * colors, int bpp); -extern Uint8 SDL_FindColor(SDL_Palette * pal, Uint8 r, Uint8 g, Uint8 b, Uint8 a); +extern void SDL_DitherColors(SDL_Color *colors, int bpp); +extern Uint8 SDL_FindColor(SDL_Palette *pal, Uint8 r, Uint8 g, Uint8 b, Uint8 a); +extern void SDL_DetectPalette(SDL_Palette *pal, SDL_bool *is_opaque, SDL_bool *has_alpha_channel); #endif /* SDL_pixels_c_h_ */ diff --git a/SDL2-2.30.5/src/video/SDL_rect.c b/SDL2-2.30.5/src/video/SDL_rect.c new file mode 100644 index 0000000..7af1125 --- /dev/null +++ b/SDL2-2.30.5/src/video/SDL_rect.c @@ -0,0 +1,115 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_rect.h" +#include "SDL_rect_c.h" + +/* There's no float version of this at the moment, because it's not a public API + and internally we only need the int version. */ +SDL_bool SDL_GetSpanEnclosingRect(int width, int height, + int numrects, const SDL_Rect *rects, SDL_Rect *span) +{ + int i; + int span_y1, span_y2; + int rect_y1, rect_y2; + + if (width < 1) { + SDL_InvalidParamError("width"); + return SDL_FALSE; + } else if (height < 1) { + SDL_InvalidParamError("height"); + return SDL_FALSE; + } else if (!rects) { + SDL_InvalidParamError("rects"); + return SDL_FALSE; + } else if (!span) { + SDL_InvalidParamError("span"); + return SDL_FALSE; + } else if (numrects < 1) { + SDL_InvalidParamError("numrects"); + return SDL_FALSE; + } + + /* Initialize to empty rect */ + span_y1 = height; + span_y2 = 0; + + for (i = 0; i < numrects; ++i) { + rect_y1 = rects[i].y; + rect_y2 = rect_y1 + rects[i].h; + + /* Clip out of bounds rectangles, and expand span rect */ + if (rect_y1 < 0) { + span_y1 = 0; + } else if (rect_y1 < span_y1) { + span_y1 = rect_y1; + } + if (rect_y2 > height) { + span_y2 = height; + } else if (rect_y2 > span_y2) { + span_y2 = rect_y2; + } + } + if (span_y2 > span_y1) { + span->x = 0; + span->y = span_y1; + span->w = width; + span->h = (span_y2 - span_y1); + return SDL_TRUE; + } + return SDL_FALSE; +} + +/* For use with the Cohen-Sutherland algorithm for line clipping, in SDL_rect_impl.h */ +#define CODE_BOTTOM 1 +#define CODE_TOP 2 +#define CODE_LEFT 4 +#define CODE_RIGHT 8 + +/* Same code twice, for float and int versions... */ +#define RECTTYPE SDL_Rect +#define POINTTYPE SDL_Point +#define SCALARTYPE int +#define BIGSCALARTYPE Sint64 +#define COMPUTEOUTCODE ComputeOutCode +#define SDL_HASINTERSECTION SDL_HasIntersection +#define SDL_INTERSECTRECT SDL_IntersectRect +#define SDL_RECTEMPTY SDL_RectEmpty +#define SDL_UNIONRECT SDL_UnionRect +#define SDL_ENCLOSEPOINTS SDL_EnclosePoints +#define SDL_INTERSECTRECTANDLINE SDL_IntersectRectAndLine +#include "SDL_rect_impl.h" + +#define RECTTYPE SDL_FRect +#define POINTTYPE SDL_FPoint +#define SCALARTYPE float +#define BIGSCALARTYPE double +#define COMPUTEOUTCODE ComputeOutCodeF +#define SDL_HASINTERSECTION SDL_HasIntersectionF +#define SDL_INTERSECTRECT SDL_IntersectFRect +#define SDL_RECTEMPTY SDL_FRectEmpty +#define SDL_UNIONRECT SDL_UnionFRect +#define SDL_ENCLOSEPOINTS SDL_EncloseFPoints +#define SDL_INTERSECTRECTANDLINE SDL_IntersectFRectAndLine +#include "SDL_rect_impl.h" + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/SDL_rect_c.h b/SDL2-2.30.5/src/video/SDL_rect_c.h similarity index 90% rename from SDL2-2.0.12/src/video/SDL_rect_c.h rename to SDL2-2.30.5/src/video/SDL_rect_c.h index f194938..b7d6e7f 100644 --- a/SDL2-2.0.12/src/video/SDL_rect_c.h +++ b/SDL2-2.30.5/src/video/SDL_rect_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -24,7 +24,7 @@ #include "../SDL_internal.h" -extern SDL_bool SDL_GetSpanEnclosingRect(int width, int height, int numrects, const SDL_Rect * rects, SDL_Rect *span); +extern SDL_bool SDL_GetSpanEnclosingRect(int width, int height, int numrects, const SDL_Rect *rects, SDL_Rect *span); #endif /* SDL_rect_c_h_ */ diff --git a/SDL2-2.0.12/src/video/SDL_rect.c b/SDL2-2.30.5/src/video/SDL_rect_impl.h similarity index 62% rename from SDL2-2.0.12/src/video/SDL_rect.c rename to SDL2-2.30.5/src/video/SDL_rect_impl.h index ac5f0cb..288a727 100644 --- a/SDL2-2.0.12/src/video/SDL_rect.c +++ b/SDL2-2.30.5/src/video/SDL_rect_impl.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -18,30 +18,21 @@ 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_rect.h" -#include "SDL_rect_c.h" -#include "SDL_assert.h" +/* This file is #included twice to support int and float versions with the same code. */ -SDL_bool -SDL_HasIntersection(const SDL_Rect * A, const SDL_Rect * B) +SDL_bool SDL_HASINTERSECTION(const RECTTYPE *A, const RECTTYPE *B) { - int Amin, Amax, Bmin, Bmax; + SCALARTYPE Amin, Amax, Bmin, Bmax; if (!A) { SDL_InvalidParamError("A"); return SDL_FALSE; - } - - if (!B) { + } else if (!B) { SDL_InvalidParamError("B"); return SDL_FALSE; - } - - /* Special cases for empty rects */ - if (SDL_RectEmpty(A) || SDL_RectEmpty(B)) { - return SDL_FALSE; + } else if (SDL_RECTEMPTY(A) || SDL_RECTEMPTY(B)) { + return SDL_FALSE; /* Special cases for empty rects */ } /* Horizontal intersection */ @@ -49,50 +40,46 @@ SDL_HasIntersection(const SDL_Rect * A, const SDL_Rect * B) Amax = Amin + A->w; Bmin = B->x; Bmax = Bmin + B->w; - if (Bmin > Amin) + if (Bmin > Amin) { Amin = Bmin; - if (Bmax < Amax) + } + if (Bmax < Amax) { Amax = Bmax; - if (Amax <= Amin) + } + if (Amax <= Amin) { return SDL_FALSE; - + } /* Vertical intersection */ Amin = A->y; Amax = Amin + A->h; Bmin = B->y; Bmax = Bmin + B->h; - if (Bmin > Amin) + if (Bmin > Amin) { Amin = Bmin; - if (Bmax < Amax) + } + if (Bmax < Amax) { Amax = Bmax; - if (Amax <= Amin) + } + if (Amax <= Amin) { return SDL_FALSE; - + } return SDL_TRUE; } -SDL_bool -SDL_IntersectRect(const SDL_Rect * A, const SDL_Rect * B, SDL_Rect * result) +SDL_bool SDL_INTERSECTRECT(const RECTTYPE *A, const RECTTYPE *B, RECTTYPE *result) { - int Amin, Amax, Bmin, Bmax; + SCALARTYPE Amin, Amax, Bmin, Bmax; if (!A) { SDL_InvalidParamError("A"); return SDL_FALSE; - } - - if (!B) { + } else if (!B) { SDL_InvalidParamError("B"); return SDL_FALSE; - } - - if (!result) { + } else if (!result) { SDL_InvalidParamError("result"); return SDL_FALSE; - } - - /* Special cases for empty rects */ - if (SDL_RectEmpty(A) || SDL_RectEmpty(B)) { + } else if (SDL_RECTEMPTY(A) || SDL_RECTEMPTY(B)) { /* Special cases for empty rects */ result->w = 0; result->h = 0; return SDL_FALSE; @@ -103,11 +90,13 @@ SDL_IntersectRect(const SDL_Rect * A, const SDL_Rect * B, SDL_Rect * result) Amax = Amin + A->w; Bmin = B->x; Bmax = Bmin + B->w; - if (Bmin > Amin) + if (Bmin > Amin) { Amin = Bmin; + } result->x = Amin; - if (Bmax < Amax) + if (Bmax < Amax) { Amax = Bmax; + } result->w = Amax - Amin; /* Vertical intersection */ @@ -115,52 +104,41 @@ SDL_IntersectRect(const SDL_Rect * A, const SDL_Rect * B, SDL_Rect * result) Amax = Amin + A->h; Bmin = B->y; Bmax = Bmin + B->h; - if (Bmin > Amin) + if (Bmin > Amin) { Amin = Bmin; + } result->y = Amin; - if (Bmax < Amax) + if (Bmax < Amax) { Amax = Bmax; + } result->h = Amax - Amin; - return !SDL_RectEmpty(result); + return !SDL_RECTEMPTY(result); } -void -SDL_UnionRect(const SDL_Rect * A, const SDL_Rect * B, SDL_Rect * result) +void SDL_UNIONRECT(const RECTTYPE *A, const RECTTYPE *B, RECTTYPE *result) { - int Amin, Amax, Bmin, Bmax; + SCALARTYPE Amin, Amax, Bmin, Bmax; if (!A) { SDL_InvalidParamError("A"); return; - } - - if (!B) { + } else if (!B) { SDL_InvalidParamError("B"); return; - } - - if (!result) { + } else if (!result) { SDL_InvalidParamError("result"); return; - } - - /* Special cases for empty Rects */ - if (SDL_RectEmpty(A)) { - if (SDL_RectEmpty(B)) { - /* A and B empty */ - return; - } else { - /* A empty, B not empty */ - *result = *B; - return; - } - } else { - if (SDL_RectEmpty(B)) { - /* A not empty, B empty */ - *result = *A; - return; - } + } else if (SDL_RECTEMPTY(A)) { /* Special cases for empty Rects */ + if (SDL_RECTEMPTY(B)) { /* A and B empty */ + SDL_zerop(result); + } else { /* A empty, B not empty */ + *result = *B; + } + return; + } else if (SDL_RECTEMPTY(B)) { /* A not empty, B empty */ + *result = *A; + return; } /* Horizontal union */ @@ -168,11 +146,13 @@ SDL_UnionRect(const SDL_Rect * A, const SDL_Rect * B, SDL_Rect * result) Amax = Amin + A->w; Bmin = B->x; Bmax = Bmin + B->w; - if (Bmin < Amin) + if (Bmin < Amin) { Amin = Bmin; + } result->x = Amin; - if (Bmax > Amax) + if (Bmax > Amax) { Amax = Bmax; + } result->w = Amax - Amin; /* Vertical union */ @@ -180,43 +160,43 @@ SDL_UnionRect(const SDL_Rect * A, const SDL_Rect * B, SDL_Rect * result) Amax = Amin + A->h; Bmin = B->y; Bmax = Bmin + B->h; - if (Bmin < Amin) + if (Bmin < Amin) { Amin = Bmin; + } result->y = Amin; - if (Bmax > Amax) + if (Bmax > Amax) { Amax = Bmax; + } result->h = Amax - Amin; } -SDL_bool -SDL_EnclosePoints(const SDL_Point * points, int count, const SDL_Rect * clip, - SDL_Rect * result) +SDL_bool SDL_ENCLOSEPOINTS(const POINTTYPE *points, int count, const RECTTYPE *clip, + RECTTYPE *result) { - int minx = 0; - int miny = 0; - int maxx = 0; - int maxy = 0; - int x, y, i; + SCALARTYPE minx = 0; + SCALARTYPE miny = 0; + SCALARTYPE maxx = 0; + SCALARTYPE maxy = 0; + SCALARTYPE x, y; + int i; if (!points) { SDL_InvalidParamError("points"); return SDL_FALSE; - } - - if (count < 1) { + } else if (count < 1) { SDL_InvalidParamError("count"); return SDL_FALSE; } if (clip) { SDL_bool added = SDL_FALSE; - const int clip_minx = clip->x; - const int clip_miny = clip->y; - const int clip_maxx = clip->x+clip->w-1; - const int clip_maxy = clip->y+clip->h-1; + const SCALARTYPE clip_minx = clip->x; + const SCALARTYPE clip_miny = clip->y; + const SCALARTYPE clip_maxx = clip->x + clip->w - 1; + const SCALARTYPE clip_maxy = clip->y + clip->h - 1; /* Special case for empty rectangle */ - if (SDL_RectEmpty(clip)) { + if (SDL_RECTEMPTY(clip)) { return SDL_FALSE; } @@ -230,7 +210,7 @@ SDL_EnclosePoints(const SDL_Point * points, int count, const SDL_Rect * clip, } if (!added) { /* Special case: if no result was requested, we are done */ - if (result == NULL) { + if (!result) { return SDL_TRUE; } @@ -256,7 +236,7 @@ SDL_EnclosePoints(const SDL_Point * points, int count, const SDL_Rect * clip, } } else { /* Special case: if no result was requested, we are done */ - if (result == NULL) { + if (!result) { return SDL_TRUE; } @@ -284,20 +264,14 @@ SDL_EnclosePoints(const SDL_Point * points, int count, const SDL_Rect * clip, if (result) { result->x = minx; result->y = miny; - result->w = (maxx-minx)+1; - result->h = (maxy-miny)+1; + result->w = (maxx - minx) + 1; + result->h = (maxy - miny) + 1; } return SDL_TRUE; } /* Use the Cohen-Sutherland algorithm for line clipping */ -#define CODE_BOTTOM 1 -#define CODE_TOP 2 -#define CODE_LEFT 4 -#define CODE_RIGHT 8 - -static int -ComputeOutCode(const SDL_Rect * rect, int x, int y) +static int COMPUTEOUTCODE(const RECTTYPE *rect, SCALARTYPE x, SCALARTYPE y) { int code = 0; if (y < rect->y) { @@ -313,48 +287,35 @@ ComputeOutCode(const SDL_Rect * rect, int x, int y) return code; } -SDL_bool -SDL_IntersectRectAndLine(const SDL_Rect * rect, int *X1, int *Y1, int *X2, - int *Y2) +SDL_bool SDL_INTERSECTRECTANDLINE(const RECTTYPE *rect, SCALARTYPE *X1, SCALARTYPE *Y1, SCALARTYPE *X2, SCALARTYPE *Y2) { - int x = 0; - int y = 0; - int x1, y1; - int x2, y2; - int rectx1; - int recty1; - int rectx2; - int recty2; + SCALARTYPE x = 0; + SCALARTYPE y = 0; + SCALARTYPE x1, y1; + SCALARTYPE x2, y2; + SCALARTYPE rectx1; + SCALARTYPE recty1; + SCALARTYPE rectx2; + SCALARTYPE recty2; int outcode1, outcode2; if (!rect) { SDL_InvalidParamError("rect"); return SDL_FALSE; - } - - if (!X1) { + } else if (!X1) { SDL_InvalidParamError("X1"); return SDL_FALSE; - } - - if (!Y1) { + } else if (!Y1) { SDL_InvalidParamError("Y1"); return SDL_FALSE; - } - - if (!X2) { + } else if (!X2) { SDL_InvalidParamError("X2"); return SDL_FALSE; - } - - if (!Y2) { + } else if (!Y2) { SDL_InvalidParamError("Y2"); return SDL_FALSE; - } - - /* Special case for empty rect */ - if (SDL_RectEmpty(rect)) { - return SDL_FALSE; + } else if (SDL_RECTEMPTY(rect)) { + return SDL_FALSE; /* Special case for empty rect */ } x1 = *X1; @@ -378,8 +339,7 @@ SDL_IntersectRectAndLine(const SDL_Rect * rect, int *X1, int *Y1, int *X2, return SDL_FALSE; } - if (y1 == y2) { - /* Horizontal line, easy to clip */ + if (y1 == y2) { /* Horizontal line, easy to clip */ if (x1 < rectx1) { *X1 = rectx1; } else if (x1 > rectx2) { @@ -393,8 +353,7 @@ SDL_IntersectRectAndLine(const SDL_Rect * rect, int *X1, int *Y1, int *X2, return SDL_TRUE; } - if (x1 == x2) { - /* Vertical line, easy to clip */ + if (x1 == x2) { /* Vertical line, easy to clip */ if (y1 < recty1) { *Y1 = recty1; } else if (y1 > recty2) { @@ -409,8 +368,8 @@ SDL_IntersectRectAndLine(const SDL_Rect * rect, int *X1, int *Y1, int *X2, } /* More complicated Cohen-Sutherland algorithm */ - outcode1 = ComputeOutCode(rect, x1, y1); - outcode2 = ComputeOutCode(rect, x2, y2); + outcode1 = COMPUTEOUTCODE(rect, x1, y1); + outcode2 = COMPUTEOUTCODE(rect, x2, y2); while (outcode1 || outcode2) { if (outcode1 & outcode2) { return SDL_FALSE; @@ -419,43 +378,45 @@ SDL_IntersectRectAndLine(const SDL_Rect * rect, int *X1, int *Y1, int *X2, if (outcode1) { if (outcode1 & CODE_TOP) { y = recty1; - x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1); + x = (SCALARTYPE) (x1 + ((BIGSCALARTYPE)(x2 - x1) * (y - y1)) / (y2 - y1)); } else if (outcode1 & CODE_BOTTOM) { y = recty2; - x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1); + x = (SCALARTYPE) (x1 + ((BIGSCALARTYPE)(x2 - x1) * (y - y1)) / (y2 - y1)); } else if (outcode1 & CODE_LEFT) { x = rectx1; - y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1); + y = (SCALARTYPE) (y1 + ((BIGSCALARTYPE)(y2 - y1) * (x - x1)) / (x2 - x1)); } else if (outcode1 & CODE_RIGHT) { x = rectx2; - y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1); + y = (SCALARTYPE) (y1 + ((BIGSCALARTYPE)(y2 - y1) * (x - x1)) / (x2 - x1)); } x1 = x; y1 = y; - outcode1 = ComputeOutCode(rect, x, y); + outcode1 = COMPUTEOUTCODE(rect, x, y); } else { if (outcode2 & CODE_TOP) { + SDL_assert(y2 != y1); /* if equal: division by zero. */ y = recty1; - x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1); + x = (SCALARTYPE) (x1 + ((BIGSCALARTYPE)(x2 - x1) * (y - y1)) / (y2 - y1)); } else if (outcode2 & CODE_BOTTOM) { + SDL_assert(y2 != y1); /* if equal: division by zero. */ y = recty2; - x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1); + x = (SCALARTYPE) (x1 + ((BIGSCALARTYPE)(x2 - x1) * (y - y1)) / (y2 - y1)); } else if (outcode2 & CODE_LEFT) { /* If this assertion ever fires, here's the static analysis that warned about it: http://buildbot.libsdl.org/sdl-static-analysis/sdl-macosx-static-analysis/sdl-macosx-static-analysis-1101/report-b0d01a.html#EndPath */ - SDL_assert(x2 != x1); /* if equal: division by zero. */ + SDL_assert(x2 != x1); /* if equal: division by zero. */ x = rectx1; - y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1); + y = (SCALARTYPE) (y1 + ((BIGSCALARTYPE)(y2 - y1) * (x - x1)) / (x2 - x1)); } else if (outcode2 & CODE_RIGHT) { /* If this assertion ever fires, here's the static analysis that warned about it: http://buildbot.libsdl.org/sdl-static-analysis/sdl-macosx-static-analysis/sdl-macosx-static-analysis-1101/report-39b114.html#EndPath */ - SDL_assert(x2 != x1); /* if equal: division by zero. */ + SDL_assert(x2 != x1); /* if equal: division by zero. */ x = rectx2; - y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1); + y = (SCALARTYPE) (y1 + ((BIGSCALARTYPE)(y2 - y1) * (x - x1)) / (x2 - x1)); } x2 = x; y2 = y; - outcode2 = ComputeOutCode(rect, x, y); + outcode2 = COMPUTEOUTCODE(rect, x, y); } } *X1 = x1; @@ -465,67 +426,16 @@ SDL_IntersectRectAndLine(const SDL_Rect * rect, int *X1, int *Y1, int *X2, return SDL_TRUE; } -SDL_bool -SDL_GetSpanEnclosingRect(int width, int height, - int numrects, const SDL_Rect * rects, SDL_Rect *span) -{ - int i; - int span_y1, span_y2; - int rect_y1, rect_y2; - - if (width < 1) { - SDL_InvalidParamError("width"); - return SDL_FALSE; - } - - if (height < 1) { - SDL_InvalidParamError("height"); - return SDL_FALSE; - } - - if (!rects) { - SDL_InvalidParamError("rects"); - return SDL_FALSE; - } - - if (!span) { - SDL_InvalidParamError("span"); - return SDL_FALSE; - } - - if (numrects < 1) { - SDL_InvalidParamError("numrects"); - return SDL_FALSE; - } - - /* Initialize to empty rect */ - span_y1 = height; - span_y2 = 0; - - for (i = 0; i < numrects; ++i) { - rect_y1 = rects[i].y; - rect_y2 = rect_y1 + rects[i].h; - - /* Clip out of bounds rectangles, and expand span rect */ - if (rect_y1 < 0) { - span_y1 = 0; - } else if (rect_y1 < span_y1) { - span_y1 = rect_y1; - } - if (rect_y2 > height) { - span_y2 = height; - } else if (rect_y2 > span_y2) { - span_y2 = rect_y2; - } - } - if (span_y2 > span_y1) { - span->x = 0; - span->y = span_y1; - span->w = width; - span->h = (span_y2 - span_y1); - return SDL_TRUE; - } - return SDL_FALSE; -} +#undef RECTTYPE +#undef POINTTYPE +#undef SCALARTYPE +#undef BIGSCALARTYPE +#undef COMPUTEOUTCODE +#undef SDL_HASINTERSECTION +#undef SDL_INTERSECTRECT +#undef SDL_RECTEMPTY +#undef SDL_UNIONRECT +#undef SDL_ENCLOSEPOINTS +#undef SDL_INTERSECTRECTANDLINE /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/SDL_shape.c b/SDL2-2.30.5/src/video/SDL_shape.c new file mode 100644 index 0000000..77cc8dc --- /dev/null +++ b/SDL2-2.30.5/src/video/SDL_shape.c @@ -0,0 +1,341 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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.h" +#include "SDL_video.h" +#include "SDL_sysvideo.h" +#include "SDL_pixels.h" +#include "SDL_surface.h" +#include "SDL_shape.h" +#include "SDL_shape_internals.h" + +SDL_Window *SDL_CreateShapedWindow(const char *title, unsigned int x, unsigned int y, unsigned int w, unsigned int h, Uint32 flags) +{ + SDL_Window *result = NULL; + result = SDL_CreateWindow(title, -1000, -1000, w, h, (flags | SDL_WINDOW_BORDERLESS) & (~SDL_WINDOW_FULLSCREEN) & (~SDL_WINDOW_RESIZABLE) /* & (~SDL_WINDOW_SHOWN) */); + if (result) { + if (SDL_GetVideoDevice()->shape_driver.CreateShaper == NULL) { + SDL_DestroyWindow(result); + return NULL; + } + result->shaper = SDL_GetVideoDevice()->shape_driver.CreateShaper(result); + if (result->shaper) { + result->shaper->userx = x; + result->shaper->usery = y; + result->shaper->mode.mode = ShapeModeDefault; + result->shaper->mode.parameters.binarizationCutoff = 1; + result->shaper->hasshape = SDL_FALSE; + return result; + } else { + SDL_DestroyWindow(result); + return NULL; + } + } + return NULL; +} + +SDL_bool SDL_IsShapedWindow(const SDL_Window *window) +{ + if (window == NULL) { + return SDL_FALSE; + } + return (SDL_bool)(window->shaper != NULL); +} + +/* REQUIRES that bitmap point to a w-by-h bitmap with ppb pixels-per-byte. */ +void SDL_CalculateShapeBitmap(SDL_WindowShapeMode mode, SDL_Surface *shape, Uint8 *bitmap, Uint8 ppb) +{ + int x = 0; + int y = 0; + Uint8 r = 0, g = 0, b = 0, alpha = 0; + Uint8 *pixel = NULL; + Uint32 pixel_value = 0, mask_value = 0; + size_t bytes_per_scanline = (size_t)(shape->w + (ppb - 1)) / ppb; + Uint8 *bitmap_scanline; + SDL_Color key; + + if (SDL_MUSTLOCK(shape)) { + SDL_LockSurface(shape); + } + + SDL_memset(bitmap, 0, shape->h * bytes_per_scanline); + + for (y = 0; y < shape->h; y++) { + bitmap_scanline = bitmap + y * bytes_per_scanline; + for (x = 0; x < shape->w; x++) { + alpha = 0; + pixel_value = 0; + pixel = (Uint8 *)(shape->pixels) + (y * shape->pitch) + (x * shape->format->BytesPerPixel); + switch (shape->format->BytesPerPixel) { + case (1): + pixel_value = *pixel; + break; + case (2): + pixel_value = *(Uint16 *)pixel; + break; + case (3): + pixel_value = *(Uint32 *)pixel & (~shape->format->Amask); + break; + case (4): + pixel_value = *(Uint32 *)pixel; + break; + } + SDL_GetRGBA(pixel_value, shape->format, &r, &g, &b, &alpha); + switch (mode.mode) { + case (ShapeModeDefault): + mask_value = (alpha >= 1 ? 1 : 0); + break; + case (ShapeModeBinarizeAlpha): + mask_value = (alpha >= mode.parameters.binarizationCutoff ? 1 : 0); + break; + case (ShapeModeReverseBinarizeAlpha): + mask_value = (alpha <= mode.parameters.binarizationCutoff ? 1 : 0); + break; + case (ShapeModeColorKey): + key = mode.parameters.colorKey; + mask_value = ((key.r != r || key.g != g || key.b != b) ? 1 : 0); + break; + } + bitmap_scanline[x / ppb] |= mask_value << (x % ppb); + } + } + + if (SDL_MUSTLOCK(shape)) { + SDL_UnlockSurface(shape); + } +} + +static SDL_ShapeTree *RecursivelyCalculateShapeTree(SDL_WindowShapeMode mode, SDL_Surface *mask, SDL_Rect dimensions) +{ + int x = 0, y = 0; + Uint8 *pixel = NULL; + Uint32 pixel_value = 0; + Uint8 r = 0, g = 0, b = 0, a = 0; + SDL_bool pixel_opaque = SDL_FALSE; + int last_opaque = -1; + SDL_Color key; + SDL_ShapeTree *result = (SDL_ShapeTree *)SDL_malloc(sizeof(SDL_ShapeTree)); + SDL_Rect next = { 0, 0, 0, 0 }; + + if (!result) { + SDL_OutOfMemory(); + return NULL; + } + + for (y = dimensions.y; y < dimensions.y + dimensions.h; y++) { + for (x = dimensions.x; x < dimensions.x + dimensions.w; x++) { + pixel_value = 0; + pixel = (Uint8 *)(mask->pixels) + (y * mask->pitch) + (x * mask->format->BytesPerPixel); + switch (mask->format->BytesPerPixel) { + case (1): + pixel_value = *pixel; + break; + case (2): + pixel_value = *(Uint16 *)pixel; + break; + case (3): + pixel_value = *(Uint32 *)pixel & (~mask->format->Amask); + break; + case (4): + pixel_value = *(Uint32 *)pixel; + break; + } + SDL_GetRGBA(pixel_value, mask->format, &r, &g, &b, &a); + switch (mode.mode) { + case (ShapeModeDefault): + pixel_opaque = (a >= 1 ? SDL_TRUE : SDL_FALSE); + break; + case (ShapeModeBinarizeAlpha): + pixel_opaque = (a >= mode.parameters.binarizationCutoff ? SDL_TRUE : SDL_FALSE); + break; + case (ShapeModeReverseBinarizeAlpha): + pixel_opaque = (a <= mode.parameters.binarizationCutoff ? SDL_TRUE : SDL_FALSE); + break; + case (ShapeModeColorKey): + key = mode.parameters.colorKey; + pixel_opaque = ((key.r != r || key.g != g || key.b != b) ? SDL_TRUE : SDL_FALSE); + break; + } + if (last_opaque == -1) { + last_opaque = pixel_opaque; + } + if (last_opaque != pixel_opaque) { + const int halfwidth = dimensions.w / 2; + const int halfheight = dimensions.h / 2; + + result->kind = QuadShape; + + next.x = dimensions.x; + next.y = dimensions.y; + next.w = halfwidth; + next.h = halfheight; + result->data.children.upleft = (struct SDL_ShapeTree *)RecursivelyCalculateShapeTree(mode, mask, next); + + next.x = dimensions.x + halfwidth; + next.w = dimensions.w - halfwidth; + result->data.children.upright = (struct SDL_ShapeTree *)RecursivelyCalculateShapeTree(mode, mask, next); + + next.x = dimensions.x; + next.w = halfwidth; + next.y = dimensions.y + halfheight; + next.h = dimensions.h - halfheight; + result->data.children.downleft = (struct SDL_ShapeTree *)RecursivelyCalculateShapeTree(mode, mask, next); + + next.x = dimensions.x + halfwidth; + next.w = dimensions.w - halfwidth; + result->data.children.downright = (struct SDL_ShapeTree *)RecursivelyCalculateShapeTree(mode, mask, next); + + return result; + } + } + } + + /* If we never recursed, all the pixels in this quadrant have the same "value". */ + result->kind = (last_opaque == SDL_TRUE ? OpaqueShape : TransparentShape); + result->data.shape = dimensions; + return result; +} + +SDL_ShapeTree *SDL_CalculateShapeTree(SDL_WindowShapeMode mode, SDL_Surface *shape) +{ + SDL_Rect dimensions; + SDL_ShapeTree *result = NULL; + + dimensions.x = 0; + dimensions.y = 0; + dimensions.w = shape->w; + dimensions.h = shape->h; + + if (SDL_MUSTLOCK(shape)) { + SDL_LockSurface(shape); + } + result = RecursivelyCalculateShapeTree(mode, shape, dimensions); + if (SDL_MUSTLOCK(shape)) { + SDL_UnlockSurface(shape); + } + return result; +} + +void SDL_TraverseShapeTree(SDL_ShapeTree *tree, SDL_TraversalFunction function, void *closure) +{ + SDL_assert(tree != NULL); + if (tree->kind == QuadShape) { + SDL_TraverseShapeTree((SDL_ShapeTree *)tree->data.children.upleft, function, closure); + SDL_TraverseShapeTree((SDL_ShapeTree *)tree->data.children.upright, function, closure); + SDL_TraverseShapeTree((SDL_ShapeTree *)tree->data.children.downleft, function, closure); + SDL_TraverseShapeTree((SDL_ShapeTree *)tree->data.children.downright, function, closure); + } else { + function(tree, closure); + } +} + +void SDL_FreeShapeTree(SDL_ShapeTree **shape_tree) +{ + if ((*shape_tree)->kind == QuadShape) { + SDL_FreeShapeTree((SDL_ShapeTree **)(char *)&(*shape_tree)->data.children.upleft); + SDL_FreeShapeTree((SDL_ShapeTree **)(char *)&(*shape_tree)->data.children.upright); + SDL_FreeShapeTree((SDL_ShapeTree **)(char *)&(*shape_tree)->data.children.downleft); + SDL_FreeShapeTree((SDL_ShapeTree **)(char *)&(*shape_tree)->data.children.downright); + } + SDL_free(*shape_tree); + *shape_tree = NULL; +} + +int SDL_SetWindowShape(SDL_Window *window, SDL_Surface *shape, SDL_WindowShapeMode *shape_mode) +{ + SDL_VideoDevice *_this = SDL_GetVideoDevice(); + int result; + + if (!window || !SDL_IsShapedWindow(window)) { + /* The window given was not a shapeable window. */ + return SDL_NONSHAPEABLE_WINDOW; + } + if (!shape) { + /* Invalid shape argument. */ + return SDL_INVALID_SHAPE_ARGUMENT; + } + + if (shape_mode) { + window->shaper->mode = *shape_mode; + } + result = _this->shape_driver.SetWindowShape(window->shaper, shape, shape_mode); + window->shaper->hasshape = SDL_TRUE; + if (window->shaper->userx != 0 && window->shaper->usery != 0) { + int x = window->shaper->userx; + int y = window->shaper->usery; + + if (SDL_WINDOWPOS_ISUNDEFINED(x) || SDL_WINDOWPOS_ISUNDEFINED(y) || + SDL_WINDOWPOS_ISCENTERED(x) || SDL_WINDOWPOS_ISCENTERED(y)) { + int displayIndex; + SDL_Rect bounds; + + if (SDL_WINDOWPOS_ISUNDEFINED(x) || SDL_WINDOWPOS_ISCENTERED(x)) { + displayIndex = (x & 0xFFFF); + if (displayIndex >= _this->num_displays) { + displayIndex = 0; + } + } else { + displayIndex = (y & 0xFFFF); + if (displayIndex >= _this->num_displays) { + displayIndex = 0; + } + } + + SDL_GetDisplayBounds(displayIndex, &bounds); + if (SDL_WINDOWPOS_ISUNDEFINED(x) || SDL_WINDOWPOS_ISCENTERED(x)) { + window->x = bounds.x + (bounds.w - window->w) / 2; + } + if (SDL_WINDOWPOS_ISUNDEFINED(y) || SDL_WINDOWPOS_ISCENTERED(y)) { + window->y = bounds.y + (bounds.h - window->h) / 2; + } + } + SDL_SetWindowPosition(window, x, y); + window->shaper->userx = 0; + window->shaper->usery = 0; + } + return result; +} + +static SDL_bool SDL_WindowHasAShape(SDL_Window *window) +{ + if (!window || !SDL_IsShapedWindow(window)) { + return SDL_FALSE; + } + return window->shaper->hasshape; +} + +int SDL_GetShapedWindowMode(SDL_Window *window, SDL_WindowShapeMode *shape_mode) +{ + if (window && SDL_IsShapedWindow(window)) { + if (!shape_mode) { + if (SDL_WindowHasAShape(window)) { + return 0; /* The window given has a shape. */ + } else { + return SDL_WINDOW_LACKS_SHAPE; /* The window given is shapeable but lacks a shape. */ + } + } else { + *shape_mode = window->shaper->mode; + return 0; + } + } + return SDL_NONSHAPEABLE_WINDOW; /* The window given is not a valid shapeable window. */ +} diff --git a/SDL2-2.0.12/src/video/SDL_shape_internals.h b/SDL2-2.30.5/src/video/SDL_shape_internals.h similarity index 67% rename from SDL2-2.0.12/src/video/SDL_shape_internals.h rename to SDL2-2.30.5/src/video/SDL_shape_internals.h index b5663ca..ed0b0d0 100644 --- a/SDL2-2.0.12/src/video/SDL_shape_internals.h +++ b/SDL2-2.30.5/src/video/SDL_shape_internals.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -35,28 +35,38 @@ extern "C" { /* *INDENT-ON* */ #endif -typedef struct { - struct SDL_ShapeTree *upleft,*upright,*downleft,*downright; +struct SDL_ShapeTree; + +typedef struct +{ + struct SDL_ShapeTree *upleft, *upright, *downleft, *downright; } SDL_QuadTreeChildren; -typedef union { +typedef union +{ SDL_QuadTreeChildren children; SDL_Rect shape; } SDL_ShapeUnion; -typedef enum { QuadShape,TransparentShape,OpaqueShape } SDL_ShapeKind; +typedef enum +{ + QuadShape, + TransparentShape, + OpaqueShape +} SDL_ShapeKind; -typedef struct { +typedef struct SDL_ShapeTree +{ SDL_ShapeKind kind; SDL_ShapeUnion data; } SDL_ShapeTree; -typedef void(*SDL_TraversalFunction)(SDL_ShapeTree*,void*); +typedef void (*SDL_TraversalFunction)(SDL_ShapeTree *, void *); -extern void SDL_CalculateShapeBitmap(SDL_WindowShapeMode mode,SDL_Surface *shape,Uint8* bitmap,Uint8 ppb); -extern SDL_ShapeTree* SDL_CalculateShapeTree(SDL_WindowShapeMode mode,SDL_Surface* shape); -extern void SDL_TraverseShapeTree(SDL_ShapeTree *tree,SDL_TraversalFunction function,void* closure); -extern void SDL_FreeShapeTree(SDL_ShapeTree** shape_tree); +extern void SDL_CalculateShapeBitmap(SDL_WindowShapeMode mode, SDL_Surface *shape, Uint8 *bitmap, Uint8 ppb); +extern SDL_ShapeTree *SDL_CalculateShapeTree(SDL_WindowShapeMode mode, SDL_Surface *shape); +extern void SDL_TraverseShapeTree(SDL_ShapeTree *tree, SDL_TraversalFunction function, void *closure); +extern void SDL_FreeShapeTree(SDL_ShapeTree **shape_tree); /* Ends C function definitions when using C++ */ #ifdef __cplusplus diff --git a/SDL2-2.30.5/src/video/SDL_stretch.c b/SDL2-2.30.5/src/video/SDL_stretch.c new file mode 100644 index 0000000..a2bae05 --- /dev/null +++ b/SDL2-2.30.5/src/video/SDL_stretch.c @@ -0,0 +1,958 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_video.h" +#include "SDL_blit.h" +#include "SDL_render.h" + +static int SDL_LowerSoftStretchNearest(SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surface *dst, const SDL_Rect *dstrect); +static int SDL_LowerSoftStretchLinear(SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surface *dst, const SDL_Rect *dstrect); +static int SDL_UpperSoftStretch(SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surface *dst, const SDL_Rect *dstrect, SDL_ScaleMode scaleMode); + +int SDL_SoftStretch(SDL_Surface *src, const SDL_Rect *srcrect, + SDL_Surface *dst, const SDL_Rect *dstrect) +{ + return SDL_UpperSoftStretch(src, srcrect, dst, dstrect, SDL_ScaleModeNearest); +} + +int SDL_SoftStretchLinear(SDL_Surface *src, const SDL_Rect *srcrect, + SDL_Surface *dst, const SDL_Rect *dstrect) +{ + return SDL_UpperSoftStretch(src, srcrect, dst, dstrect, SDL_ScaleModeLinear); +} + +static int SDL_UpperSoftStretch(SDL_Surface *src, const SDL_Rect *srcrect, + SDL_Surface *dst, const SDL_Rect *dstrect, SDL_ScaleMode scaleMode) +{ + int ret; + int src_locked; + int dst_locked; + SDL_Rect full_src; + SDL_Rect full_dst; + + if (src->format->format != dst->format->format) { + return SDL_SetError("Only works with same format surfaces"); + } + + if (scaleMode != SDL_ScaleModeNearest) { + if (src->format->BytesPerPixel != 4 || src->format->format == SDL_PIXELFORMAT_ARGB2101010) { + return SDL_SetError("Wrong format"); + } + } + + /* Verify the blit rectangles */ + if (srcrect) { + if ((srcrect->x < 0) || (srcrect->y < 0) || + ((srcrect->x + srcrect->w) > src->w) || + ((srcrect->y + srcrect->h) > src->h)) { + return SDL_SetError("Invalid source blit rectangle"); + } + } else { + full_src.x = 0; + full_src.y = 0; + full_src.w = src->w; + full_src.h = src->h; + srcrect = &full_src; + } + if (dstrect) { + if ((dstrect->x < 0) || (dstrect->y < 0) || + ((dstrect->x + dstrect->w) > dst->w) || + ((dstrect->y + dstrect->h) > dst->h)) { + return SDL_SetError("Invalid destination blit rectangle"); + } + } else { + full_dst.x = 0; + full_dst.y = 0; + full_dst.w = dst->w; + full_dst.h = dst->h; + dstrect = &full_dst; + } + + if (dstrect->w <= 0 || dstrect->h <= 0) { + return 0; + } + + if (srcrect->w > SDL_MAX_UINT16 || srcrect->h > SDL_MAX_UINT16 || + dstrect->w > SDL_MAX_UINT16 || dstrect->h > SDL_MAX_UINT16) { + return SDL_SetError("Size too large for scaling"); + } + + /* Lock the destination if it's in hardware */ + dst_locked = 0; + if (SDL_MUSTLOCK(dst)) { + if (SDL_LockSurface(dst) < 0) { + return SDL_SetError("Unable to lock destination surface"); + } + dst_locked = 1; + } + /* Lock the source if it's in hardware */ + src_locked = 0; + if (SDL_MUSTLOCK(src)) { + if (SDL_LockSurface(src) < 0) { + if (dst_locked) { + SDL_UnlockSurface(dst); + } + return SDL_SetError("Unable to lock source surface"); + } + src_locked = 1; + } + + if (scaleMode == SDL_ScaleModeNearest) { + ret = SDL_LowerSoftStretchNearest(src, srcrect, dst, dstrect); + } else { + ret = SDL_LowerSoftStretchLinear(src, srcrect, dst, dstrect); + } + + /* We need to unlock the surfaces if they're locked */ + if (dst_locked) { + SDL_UnlockSurface(dst); + } + if (src_locked) { + SDL_UnlockSurface(src); + } + + return ret; +} + +/* bilinear interpolation precision must be < 8 + Because with SSE: add-multiply: _mm_madd_epi16 works with signed int + so pixels 0xb1...... are negatives and false the result + same in NEON probably */ +#define PRECISION 7 + +#define FIXED_POINT(i) ((Uint32)(i) << 16) +#define SRC_INDEX(fp) ((Uint32)(fp) >> 16) +#define INTEGER(fp) ((Uint32)(fp) >> PRECISION) +#define FRAC(fp) ((Uint32)(fp >> (16 - PRECISION)) & ((1 << PRECISION) - 1)) +#define FRAC_ZERO 0 +#define FRAC_ONE (1 << PRECISION) +#define FP_ONE FIXED_POINT(1) + +#define BILINEAR___START \ + int i; \ + Sint64 fp_sum_h; \ + int fp_step_h, left_pad_h, right_pad_h; \ + Sint64 fp_sum_w; \ + int fp_step_w, left_pad_w, right_pad_w; \ + Sint64 fp_sum_w_init; \ + int left_pad_w_init, right_pad_w_init, dst_gap, middle_init; \ + get_scaler_datas(src_h, dst_h, &fp_sum_h, &fp_step_h, &left_pad_h, &right_pad_h); \ + get_scaler_datas(src_w, dst_w, &fp_sum_w, &fp_step_w, &left_pad_w, &right_pad_w); \ + fp_sum_w_init = fp_sum_w + left_pad_w * fp_step_w; \ + left_pad_w_init = left_pad_w; \ + right_pad_w_init = right_pad_w; \ + dst_gap = dst_pitch - 4 * dst_w; \ + middle_init = dst_w - left_pad_w - right_pad_w; + +#define BILINEAR___HEIGHT \ + int index_h, frac_h0, frac_h1, middle; \ + const Uint32 *src_h0, *src_h1; \ + int no_padding; \ + Uint64 incr_h0, incr_h1; \ + \ + no_padding = !(i < left_pad_h || i > dst_h - 1 - right_pad_h); \ + index_h = SRC_INDEX(fp_sum_h); \ + frac_h0 = FRAC(fp_sum_h); \ + \ + index_h = no_padding ? index_h : (i < left_pad_h ? 0 : src_h - 1); \ + frac_h0 = no_padding ? frac_h0 : 0; \ + incr_h1 = no_padding ? src_pitch : 0; \ + incr_h0 = (Uint64)index_h * src_pitch; \ + \ + src_h0 = (const Uint32 *)((const Uint8 *)src + incr_h0); \ + src_h1 = (const Uint32 *)((const Uint8 *)src_h0 + incr_h1); \ + \ + fp_sum_h += fp_step_h; \ + \ + frac_h1 = FRAC_ONE - frac_h0; \ + fp_sum_w = fp_sum_w_init; \ + right_pad_w = right_pad_w_init; \ + left_pad_w = left_pad_w_init; \ + middle = middle_init; + +#if defined(__clang__) +// Remove inlining of this function +// Compiler crash with clang 9.0.8 / android-ndk-r21d +// Compiler crash with clang 11.0.3 / Xcode +// OK with clang 11.0.5 / android-ndk-22 +// OK with clang 12.0.0 / Xcode +__attribute__((noinline)) +#endif +static void get_scaler_datas(int src_nb, int dst_nb, Sint64 *fp_start, int *fp_step, int *left_pad, int *right_pad) +{ + + int step = FIXED_POINT(src_nb) / (dst_nb); /* source step in fixed point */ + int x0 = FP_ONE / 2; /* dst first pixel center at 0.5 in fixed point */ + Sint64 fp_sum; + int i; +#if 0 + /* scale to source coordinates */ + x0 *= src_nb; + x0 /= dst_nb; /* x0 == step / 2 */ +#else + /* Use this code for perfect match with pixman */ + Sint64 tmp[2]; + tmp[0] = (Sint64)step * (x0 >> 16); + tmp[1] = (Sint64)step * (x0 & 0xFFFF); + x0 = (int)(tmp[0] + ((tmp[1] + 0x8000) >> 16)); /* x0 == (step + 1) / 2 */ +#endif + /* -= 0.5, get back the pixel origin, in source coordinates */ + x0 -= FP_ONE / 2; + + *fp_start = x0; + *fp_step = step; + *left_pad = 0; + *right_pad = 0; + + fp_sum = x0; + for (i = 0; i < dst_nb; i++) { + if (fp_sum < 0) { + *left_pad += 1; + } else { + int index = SRC_INDEX(fp_sum); + if (index > src_nb - 2) { + *right_pad += 1; + } + } + fp_sum += step; + } + // SDL_Log("%d -> %d x0=%d step=%d left_pad=%d right_pad=%d", src_nb, dst_nb, *fp_start, *fp_step, *left_pad, *right_pad); +} + +typedef struct color_t +{ + Uint8 a; + Uint8 b; + Uint8 c; + Uint8 d; +} color_t; + +#if 0 +static void printf_64(const char *str, void *var) +{ + uint8_t *val = (uint8_t*) var; + printf(" * %s: %02x %02x %02x %02x _ %02x %02x %02x %02x\n", + str, val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7]); +} +#endif + +/* Interpolated == x0 + frac * (x1 - x0) == x0 * (1 - frac) + x1 * frac */ + +static SDL_INLINE void INTERPOL(const Uint32 *src_x0, const Uint32 *src_x1, int frac0, int frac1, Uint32 *dst) +{ + const color_t *c0 = (const color_t *)src_x0; + const color_t *c1 = (const color_t *)src_x1; + color_t *cx = (color_t *)dst; +#if 0 + cx->a = c0->a + INTEGER(frac0 * (c1->a - c0->a)); + cx->b = c0->b + INTEGER(frac0 * (c1->b - c0->b)); + cx->c = c0->c + INTEGER(frac0 * (c1->c - c0->c)); + cx->d = c0->d + INTEGER(frac0 * (c1->d - c0->d)); +#else + cx->a = INTEGER(frac1 * c0->a + frac0 * c1->a); + cx->b = INTEGER(frac1 * c0->b + frac0 * c1->b); + cx->c = INTEGER(frac1 * c0->c + frac0 * c1->c); + cx->d = INTEGER(frac1 * c0->d + frac0 * c1->d); +#endif +} + +static SDL_INLINE void INTERPOL_BILINEAR(const Uint32 *s0, const Uint32 *s1, int frac_w0, int frac_h0, int frac_h1, Uint32 *dst) +{ + Uint32 tmp[2]; + unsigned int frac_w1 = FRAC_ONE - frac_w0; + + /* Vertical first, store to 'tmp' */ + INTERPOL(s0, s1, frac_h0, frac_h1, tmp); + INTERPOL(s0 + 1, s1 + 1, frac_h0, frac_h1, tmp + 1); + + /* Horizontal, store to 'dst' */ + INTERPOL(tmp, tmp + 1, frac_w0, frac_w1, dst); +} + +static int scale_mat(const Uint32 *src, int src_w, int src_h, int src_pitch, + Uint32 *dst, int dst_w, int dst_h, int dst_pitch) +{ + BILINEAR___START + + for (i = 0; i < dst_h; i++) { + + BILINEAR___HEIGHT + + while (left_pad_w--) { + INTERPOL_BILINEAR(src_h0, src_h1, FRAC_ZERO, frac_h0, frac_h1, dst); + dst += 1; + } + + while (middle--) { + const Uint32 *s_00_01; + const Uint32 *s_10_11; + int index_w = 4 * SRC_INDEX(fp_sum_w); + int frac_w = FRAC(fp_sum_w); + fp_sum_w += fp_step_w; + + /* + x00 ... x0_ ..... x01 + . . . + . x . + . . . + . . . + x10 ... x1_ ..... x11 + */ + s_00_01 = (const Uint32 *)((const Uint8 *)src_h0 + index_w); + s_10_11 = (const Uint32 *)((const Uint8 *)src_h1 + index_w); + + INTERPOL_BILINEAR(s_00_01, s_10_11, frac_w, frac_h0, frac_h1, dst); + + dst += 1; + } + + while (right_pad_w--) { + int index_w = 4 * (src_w - 2); + const Uint32 *s_00_01 = (const Uint32 *)((const Uint8 *)src_h0 + index_w); + const Uint32 *s_10_11 = (const Uint32 *)((const Uint8 *)src_h1 + index_w); + INTERPOL_BILINEAR(s_00_01, s_10_11, FRAC_ONE, frac_h0, frac_h1, dst); + dst += 1; + } + dst = (Uint32 *)((Uint8 *)dst + dst_gap); + } + return 0; +} + +#if defined(__SSE2__) +#define HAVE_SSE2_INTRINSICS +#endif + +#if defined(__ARM_NEON) +#define HAVE_NEON_INTRINSICS 1 +#define CAST_uint8x8_t (uint8x8_t) +#define CAST_uint32x2_t (uint32x2_t) +#endif + +#if defined(__WINRT__) || defined(_MSC_VER) +#if defined(HAVE_NEON_INTRINSICS) +#undef CAST_uint8x8_t +#undef CAST_uint32x2_t +#define CAST_uint8x8_t +#define CAST_uint32x2_t +#endif +#endif + +#if defined(HAVE_SSE2_INTRINSICS) + +#if 0 +static void printf_128(const char *str, __m128i var) +{ + uint16_t *val = (uint16_t*) &var; + printf(" * %s: %04x %04x %04x %04x _ %04x %04x %04x %04x\n", + str, val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7]); +} +#endif + +static SDL_INLINE int hasSSE2() +{ + static int val = -1; + if (val != -1) { + return val; + } + val = SDL_HasSSE2(); + return val; +} + +static SDL_INLINE void INTERPOL_BILINEAR_SSE(const Uint32 *s0, const Uint32 *s1, int frac_w, __m128i v_frac_h0, __m128i v_frac_h1, Uint32 *dst, __m128i zero) +{ + __m128i x_00_01, x_10_11; /* Pixels in 4*uint8 in row */ + __m128i v_frac_w0, k0, l0, d0, e0; + + int f, f2; + f = frac_w; + f2 = FRAC_ONE - frac_w; + v_frac_w0 = _mm_set_epi16(f, f2, f, f2, f, f2, f, f2); + + x_00_01 = _mm_loadl_epi64((const __m128i *)s0); /* Load x00 and x01 */ + x_10_11 = _mm_loadl_epi64((const __m128i *)s1); + + /* Interpolated == x0 + frac * (x1 - x0) == x0 * (1 - frac) + x1 * frac */ + + /* Interpolation vertical */ + k0 = _mm_mullo_epi16(_mm_unpacklo_epi8(x_00_01, zero), v_frac_h1); + l0 = _mm_mullo_epi16(_mm_unpacklo_epi8(x_10_11, zero), v_frac_h0); + k0 = _mm_add_epi16(k0, l0); + + /* For perfect match, clear the factionnal part eventually. */ + /* + k0 = _mm_srli_epi16(k0, PRECISION); + k0 = _mm_slli_epi16(k0, PRECISION); + */ + + /* Interpolation horizontal */ + l0 = _mm_unpacklo_epi64(/* unused */ l0, k0); + k0 = _mm_madd_epi16(_mm_unpackhi_epi16(l0, k0), v_frac_w0); + + /* Store 1 pixel */ + d0 = _mm_srli_epi32(k0, PRECISION * 2); + e0 = _mm_packs_epi32(d0, d0); + e0 = _mm_packus_epi16(e0, e0); + *dst = _mm_cvtsi128_si32(e0); +} + +static int scale_mat_SSE(const Uint32 *src, int src_w, int src_h, int src_pitch, Uint32 *dst, int dst_w, int dst_h, int dst_pitch) +{ + BILINEAR___START + + for (i = 0; i < dst_h; i++) { + int nb_block2; + __m128i v_frac_h0; + __m128i v_frac_h1; + __m128i zero; + + BILINEAR___HEIGHT + + nb_block2 = middle / 2; + + v_frac_h0 = _mm_set_epi16(frac_h0, frac_h0, frac_h0, frac_h0, frac_h0, frac_h0, frac_h0, frac_h0); + v_frac_h1 = _mm_set_epi16(frac_h1, frac_h1, frac_h1, frac_h1, frac_h1, frac_h1, frac_h1, frac_h1); + zero = _mm_setzero_si128(); + + while (left_pad_w--) { + INTERPOL_BILINEAR_SSE(src_h0, src_h1, FRAC_ZERO, v_frac_h0, v_frac_h1, dst, zero); + dst += 1; + } + + while (nb_block2--) { + int index_w_0, frac_w_0; + int index_w_1, frac_w_1; + + const Uint32 *s_00_01, *s_02_03, *s_10_11, *s_12_13; + + __m128i x_00_01, x_10_11, x_02_03, x_12_13; /* Pixels in 4*uint8 in row */ + __m128i v_frac_w0, k0, l0, d0, e0; + __m128i v_frac_w1, k1, l1, d1, e1; + + int f, f2; + index_w_0 = 4 * SRC_INDEX(fp_sum_w); + frac_w_0 = FRAC(fp_sum_w); + fp_sum_w += fp_step_w; + index_w_1 = 4 * SRC_INDEX(fp_sum_w); + frac_w_1 = FRAC(fp_sum_w); + fp_sum_w += fp_step_w; + /* + x00............ x01 x02...........x03 + . . . . . . + j0 f0 j1 j2 f1 j3 + . . . . . . + . . . . . . + . . . . . . + x10............ x11 x12...........x13 + */ + s_00_01 = (const Uint32 *)((const Uint8 *)src_h0 + index_w_0); + s_02_03 = (const Uint32 *)((const Uint8 *)src_h0 + index_w_1); + s_10_11 = (const Uint32 *)((const Uint8 *)src_h1 + index_w_0); + s_12_13 = (const Uint32 *)((const Uint8 *)src_h1 + index_w_1); + + f = frac_w_0; + f2 = FRAC_ONE - frac_w_0; + v_frac_w0 = _mm_set_epi16(f, f2, f, f2, f, f2, f, f2); + + f = frac_w_1; + f2 = FRAC_ONE - frac_w_1; + v_frac_w1 = _mm_set_epi16(f, f2, f, f2, f, f2, f, f2); + + x_00_01 = _mm_loadl_epi64((const __m128i *)s_00_01); /* Load x00 and x01 */ + x_02_03 = _mm_loadl_epi64((const __m128i *)s_02_03); + x_10_11 = _mm_loadl_epi64((const __m128i *)s_10_11); + x_12_13 = _mm_loadl_epi64((const __m128i *)s_12_13); + + /* Interpolation vertical */ + k0 = _mm_mullo_epi16(_mm_unpacklo_epi8(x_00_01, zero), v_frac_h1); + l0 = _mm_mullo_epi16(_mm_unpacklo_epi8(x_10_11, zero), v_frac_h0); + k0 = _mm_add_epi16(k0, l0); + k1 = _mm_mullo_epi16(_mm_unpacklo_epi8(x_02_03, zero), v_frac_h1); + l1 = _mm_mullo_epi16(_mm_unpacklo_epi8(x_12_13, zero), v_frac_h0); + k1 = _mm_add_epi16(k1, l1); + + /* Interpolation horizontal */ + l0 = _mm_unpacklo_epi64(/* unused */ l0, k0); + k0 = _mm_madd_epi16(_mm_unpackhi_epi16(l0, k0), v_frac_w0); + l1 = _mm_unpacklo_epi64(/* unused */ l1, k1); + k1 = _mm_madd_epi16(_mm_unpackhi_epi16(l1, k1), v_frac_w1); + + /* Store 1 pixel */ + d0 = _mm_srli_epi32(k0, PRECISION * 2); + e0 = _mm_packs_epi32(d0, d0); + e0 = _mm_packus_epi16(e0, e0); + *dst++ = _mm_cvtsi128_si32(e0); + + /* Store 1 pixel */ + d1 = _mm_srli_epi32(k1, PRECISION * 2); + e1 = _mm_packs_epi32(d1, d1); + e1 = _mm_packus_epi16(e1, e1); + *dst++ = _mm_cvtsi128_si32(e1); + } + + /* Last point */ + if (middle & 0x1) { + const Uint32 *s_00_01; + const Uint32 *s_10_11; + int index_w = 4 * SRC_INDEX(fp_sum_w); + int frac_w = FRAC(fp_sum_w); + fp_sum_w += fp_step_w; + s_00_01 = (const Uint32 *)((const Uint8 *)src_h0 + index_w); + s_10_11 = (const Uint32 *)((const Uint8 *)src_h1 + index_w); + INTERPOL_BILINEAR_SSE(s_00_01, s_10_11, frac_w, v_frac_h0, v_frac_h1, dst, zero); + dst += 1; + } + + while (right_pad_w--) { + int index_w = 4 * (src_w - 2); + const Uint32 *s_00_01 = (const Uint32 *)((const Uint8 *)src_h0 + index_w); + const Uint32 *s_10_11 = (const Uint32 *)((const Uint8 *)src_h1 + index_w); + INTERPOL_BILINEAR_SSE(s_00_01, s_10_11, FRAC_ONE, v_frac_h0, v_frac_h1, dst, zero); + dst += 1; + } + dst = (Uint32 *)((Uint8 *)dst + dst_gap); + } + return 0; +} +#endif + +#if defined(HAVE_NEON_INTRINSICS) + +static SDL_INLINE int hasNEON(void) +{ + static int val = -1; + if (val != -1) { + return val; + } + val = SDL_HasNEON(); + return val; +} + +static SDL_INLINE void INTERPOL_BILINEAR_NEON(const Uint32 *s0, const Uint32 *s1, int frac_w, uint8x8_t v_frac_h0, uint8x8_t v_frac_h1, Uint32 *dst) +{ + uint8x8_t x_00_01, x_10_11; /* Pixels in 4*uint8 in row */ + uint16x8_t k0; + uint32x4_t l0; + uint16x8_t d0; + uint8x8_t e0; + + x_00_01 = CAST_uint8x8_t vld1_u32(s0); /* Load 2 pixels */ + x_10_11 = CAST_uint8x8_t vld1_u32(s1); + + /* Interpolated == x0 + frac * (x1 - x0) == x0 * (1 - frac) + x1 * frac */ + k0 = vmull_u8(x_00_01, v_frac_h1); /* k0 := x0 * (1 - frac) */ + k0 = vmlal_u8(k0, x_10_11, v_frac_h0); /* k0 += x1 * frac */ + + /* k0 now contains 2 interpolated pixels { j0, j1 } */ + l0 = vshll_n_u16(vget_low_u16(k0), PRECISION); + l0 = vmlsl_n_u16(l0, vget_low_u16(k0), frac_w); + l0 = vmlal_n_u16(l0, vget_high_u16(k0), frac_w); + + /* Shift and narrow */ + d0 = vcombine_u16( + /* uint16x4_t */ vshrn_n_u32(l0, 2 * PRECISION), + /* uint16x4_t */ vshrn_n_u32(l0, 2 * PRECISION)); + + /* Narrow again */ + e0 = vmovn_u16(d0); + + /* Store 1 pixel */ + *dst = vget_lane_u32(CAST_uint32x2_t e0, 0); +} + +static int scale_mat_NEON(const Uint32 *src, int src_w, int src_h, int src_pitch, Uint32 *dst, int dst_w, int dst_h, int dst_pitch) +{ + BILINEAR___START + + for (i = 0; i < dst_h; i++) { + int nb_block4; + uint8x8_t v_frac_h0, v_frac_h1; + + BILINEAR___HEIGHT + + nb_block4 = middle / 4; + + v_frac_h0 = vmov_n_u8(frac_h0); + v_frac_h1 = vmov_n_u8(frac_h1); + + while (left_pad_w--) { + INTERPOL_BILINEAR_NEON(src_h0, src_h1, FRAC_ZERO, v_frac_h0, v_frac_h1, dst); + dst += 1; + } + + while (nb_block4--) { + int index_w_0, frac_w_0; + int index_w_1, frac_w_1; + int index_w_2, frac_w_2; + int index_w_3, frac_w_3; + + const Uint32 *s_00_01, *s_02_03, *s_04_05, *s_06_07; + const Uint32 *s_10_11, *s_12_13, *s_14_15, *s_16_17; + + uint8x8_t x_00_01, x_10_11, x_02_03, x_12_13; /* Pixels in 4*uint8 in row */ + uint8x8_t x_04_05, x_14_15, x_06_07, x_16_17; + + uint16x8_t k0, k1, k2, k3; + uint32x4_t l0, l1, l2, l3; + uint16x8_t d0, d1; + uint8x8_t e0, e1; + uint32x4_t f0; + + index_w_0 = 4 * SRC_INDEX(fp_sum_w); + frac_w_0 = FRAC(fp_sum_w); + fp_sum_w += fp_step_w; + index_w_1 = 4 * SRC_INDEX(fp_sum_w); + frac_w_1 = FRAC(fp_sum_w); + fp_sum_w += fp_step_w; + index_w_2 = 4 * SRC_INDEX(fp_sum_w); + frac_w_2 = FRAC(fp_sum_w); + fp_sum_w += fp_step_w; + index_w_3 = 4 * SRC_INDEX(fp_sum_w); + frac_w_3 = FRAC(fp_sum_w); + fp_sum_w += fp_step_w; + + s_00_01 = (const Uint32 *)((const Uint8 *)src_h0 + index_w_0); + s_02_03 = (const Uint32 *)((const Uint8 *)src_h0 + index_w_1); + s_04_05 = (const Uint32 *)((const Uint8 *)src_h0 + index_w_2); + s_06_07 = (const Uint32 *)((const Uint8 *)src_h0 + index_w_3); + s_10_11 = (const Uint32 *)((const Uint8 *)src_h1 + index_w_0); + s_12_13 = (const Uint32 *)((const Uint8 *)src_h1 + index_w_1); + s_14_15 = (const Uint32 *)((const Uint8 *)src_h1 + index_w_2); + s_16_17 = (const Uint32 *)((const Uint8 *)src_h1 + index_w_3); + + /* Interpolation vertical */ + x_00_01 = CAST_uint8x8_t vld1_u32(s_00_01); /* Load 2 pixels */ + x_02_03 = CAST_uint8x8_t vld1_u32(s_02_03); + x_04_05 = CAST_uint8x8_t vld1_u32(s_04_05); + x_06_07 = CAST_uint8x8_t vld1_u32(s_06_07); + x_10_11 = CAST_uint8x8_t vld1_u32(s_10_11); + x_12_13 = CAST_uint8x8_t vld1_u32(s_12_13); + x_14_15 = CAST_uint8x8_t vld1_u32(s_14_15); + x_16_17 = CAST_uint8x8_t vld1_u32(s_16_17); + + /* Interpolated == x0 + frac * (x1 - x0) == x0 * (1 - frac) + x1 * frac */ + k0 = vmull_u8(x_00_01, v_frac_h1); /* k0 := x0 * (1 - frac) */ + k0 = vmlal_u8(k0, x_10_11, v_frac_h0); /* k0 += x1 * frac */ + + k1 = vmull_u8(x_02_03, v_frac_h1); + k1 = vmlal_u8(k1, x_12_13, v_frac_h0); + + k2 = vmull_u8(x_04_05, v_frac_h1); + k2 = vmlal_u8(k2, x_14_15, v_frac_h0); + + k3 = vmull_u8(x_06_07, v_frac_h1); + k3 = vmlal_u8(k3, x_16_17, v_frac_h0); + + /* k0 now contains 2 interpolated pixels { j0, j1 } */ + /* k1 now contains 2 interpolated pixels { j2, j3 } */ + /* k2 now contains 2 interpolated pixels { j4, j5 } */ + /* k3 now contains 2 interpolated pixels { j6, j7 } */ + + l0 = vshll_n_u16(vget_low_u16(k0), PRECISION); + l0 = vmlsl_n_u16(l0, vget_low_u16(k0), frac_w_0); + l0 = vmlal_n_u16(l0, vget_high_u16(k0), frac_w_0); + + l1 = vshll_n_u16(vget_low_u16(k1), PRECISION); + l1 = vmlsl_n_u16(l1, vget_low_u16(k1), frac_w_1); + l1 = vmlal_n_u16(l1, vget_high_u16(k1), frac_w_1); + + l2 = vshll_n_u16(vget_low_u16(k2), PRECISION); + l2 = vmlsl_n_u16(l2, vget_low_u16(k2), frac_w_2); + l2 = vmlal_n_u16(l2, vget_high_u16(k2), frac_w_2); + + l3 = vshll_n_u16(vget_low_u16(k3), PRECISION); + l3 = vmlsl_n_u16(l3, vget_low_u16(k3), frac_w_3); + l3 = vmlal_n_u16(l3, vget_high_u16(k3), frac_w_3); + + /* shift and narrow */ + d0 = vcombine_u16( + /* uint16x4_t */ vshrn_n_u32(l0, 2 * PRECISION), + /* uint16x4_t */ vshrn_n_u32(l1, 2 * PRECISION)); + /* narrow again */ + e0 = vmovn_u16(d0); + + /* Shift and narrow */ + d1 = vcombine_u16( + /* uint16x4_t */ vshrn_n_u32(l2, 2 * PRECISION), + /* uint16x4_t */ vshrn_n_u32(l3, 2 * PRECISION)); + /* Narrow again */ + e1 = vmovn_u16(d1); + + f0 = vcombine_u32(CAST_uint32x2_t e0, CAST_uint32x2_t e1); + /* Store 4 pixels */ + vst1q_u32(dst, f0); + + dst += 4; + } + + if (middle & 0x2) { + int index_w_0, frac_w_0; + int index_w_1, frac_w_1; + const Uint32 *s_00_01, *s_02_03; + const Uint32 *s_10_11, *s_12_13; + uint8x8_t x_00_01, x_10_11, x_02_03, x_12_13; /* Pixels in 4*uint8 in row */ + uint16x8_t k0, k1; + uint32x4_t l0, l1; + uint16x8_t d0; + uint8x8_t e0; + + index_w_0 = 4 * SRC_INDEX(fp_sum_w); + frac_w_0 = FRAC(fp_sum_w); + fp_sum_w += fp_step_w; + index_w_1 = 4 * SRC_INDEX(fp_sum_w); + frac_w_1 = FRAC(fp_sum_w); + fp_sum_w += fp_step_w; + /* + x00............ x01 x02...........x03 + . . . . . . + j0 dest0 j1 j2 dest1 j3 + . . . . . . + . . . . . . + . . . . . . + x10............ x11 x12...........x13 + */ + s_00_01 = (const Uint32 *)((const Uint8 *)src_h0 + index_w_0); + s_02_03 = (const Uint32 *)((const Uint8 *)src_h0 + index_w_1); + s_10_11 = (const Uint32 *)((const Uint8 *)src_h1 + index_w_0); + s_12_13 = (const Uint32 *)((const Uint8 *)src_h1 + index_w_1); + + /* Interpolation vertical */ + x_00_01 = CAST_uint8x8_t vld1_u32(s_00_01); /* Load 2 pixels */ + x_02_03 = CAST_uint8x8_t vld1_u32(s_02_03); + x_10_11 = CAST_uint8x8_t vld1_u32(s_10_11); + x_12_13 = CAST_uint8x8_t vld1_u32(s_12_13); + + /* Interpolated == x0 + frac * (x1 - x0) == x0 * (1 - frac) + x1 * frac */ + k0 = vmull_u8(x_00_01, v_frac_h1); /* k0 := x0 * (1 - frac) */ + k0 = vmlal_u8(k0, x_10_11, v_frac_h0); /* k0 += x1 * frac */ + + k1 = vmull_u8(x_02_03, v_frac_h1); + k1 = vmlal_u8(k1, x_12_13, v_frac_h0); + + /* k0 now contains 2 interpolated pixels { j0, j1 } */ + /* k1 now contains 2 interpolated pixels { j2, j3 } */ + + l0 = vshll_n_u16(vget_low_u16(k0), PRECISION); + l0 = vmlsl_n_u16(l0, vget_low_u16(k0), frac_w_0); + l0 = vmlal_n_u16(l0, vget_high_u16(k0), frac_w_0); + + l1 = vshll_n_u16(vget_low_u16(k1), PRECISION); + l1 = vmlsl_n_u16(l1, vget_low_u16(k1), frac_w_1); + l1 = vmlal_n_u16(l1, vget_high_u16(k1), frac_w_1); + + /* Shift and narrow */ + + d0 = vcombine_u16( + /* uint16x4_t */ vshrn_n_u32(l0, 2 * PRECISION), + /* uint16x4_t */ vshrn_n_u32(l1, 2 * PRECISION)); + + /* Narrow again */ + e0 = vmovn_u16(d0); + + /* Store 2 pixels */ + vst1_u32(dst, CAST_uint32x2_t e0); + dst += 2; + } + + /* Last point */ + if (middle & 0x1) { + int index_w = 4 * SRC_INDEX(fp_sum_w); + int frac_w = FRAC(fp_sum_w); + const Uint32 *s_00_01 = (const Uint32 *)((const Uint8 *)src_h0 + index_w); + const Uint32 *s_10_11 = (const Uint32 *)((const Uint8 *)src_h1 + index_w); + INTERPOL_BILINEAR_NEON(s_00_01, s_10_11, frac_w, v_frac_h0, v_frac_h1, dst); + dst += 1; + } + + while (right_pad_w--) { + int index_w = 4 * (src_w - 2); + const Uint32 *s_00_01 = (const Uint32 *)((const Uint8 *)src_h0 + index_w); + const Uint32 *s_10_11 = (const Uint32 *)((const Uint8 *)src_h1 + index_w); + INTERPOL_BILINEAR_NEON(s_00_01, s_10_11, FRAC_ONE, v_frac_h0, v_frac_h1, dst); + dst += 1; + } + + dst = (Uint32 *)((Uint8 *)dst + dst_gap); + } + return 0; +} +#endif + +int SDL_LowerSoftStretchLinear(SDL_Surface *s, const SDL_Rect *srcrect, + SDL_Surface *d, const SDL_Rect *dstrect) +{ + int ret = -1; + int src_w = srcrect->w; + int src_h = srcrect->h; + int dst_w = dstrect->w; + int dst_h = dstrect->h; + int src_pitch = s->pitch; + int dst_pitch = d->pitch; + Uint32 *src = (Uint32 *)((Uint8 *)s->pixels + srcrect->x * 4 + srcrect->y * src_pitch); + Uint32 *dst = (Uint32 *)((Uint8 *)d->pixels + dstrect->x * 4 + dstrect->y * dst_pitch); + +#if defined(HAVE_NEON_INTRINSICS) + if (ret == -1 && hasNEON()) { + ret = scale_mat_NEON(src, src_w, src_h, src_pitch, dst, dst_w, dst_h, dst_pitch); + } +#endif + +#if defined(HAVE_SSE2_INTRINSICS) + if (ret == -1 && hasSSE2()) { + ret = scale_mat_SSE(src, src_w, src_h, src_pitch, dst, dst_w, dst_h, dst_pitch); + } +#endif + + if (ret == -1) { + ret = scale_mat(src, src_w, src_h, src_pitch, dst, dst_w, dst_h, dst_pitch); + } + + return ret; +} + +#define SDL_SCALE_NEAREST__START \ + int i; \ + Uint64 posy, incy; \ + Uint64 posx, incx; \ + Uint64 srcy, srcx; \ + int dst_gap, n; \ + const Uint32 *src_h0; \ + incy = ((Uint64)src_h << 16) / dst_h; \ + incx = ((Uint64)src_w << 16) / dst_w; \ + dst_gap = dst_pitch - bpp * dst_w; \ + posy = incy / 2; + +#define SDL_SCALE_NEAREST__HEIGHT \ + srcy = (posy >> 16); \ + src_h0 = (const Uint32 *)((const Uint8 *)src_ptr + srcy * src_pitch); \ + posy += incy; \ + posx = incx / 2; \ + n = dst_w; + +static int scale_mat_nearest_1(const Uint32 *src_ptr, int src_w, int src_h, int src_pitch, + Uint32 *dst, int dst_w, int dst_h, int dst_pitch) +{ + Uint32 bpp = 1; + SDL_SCALE_NEAREST__START + for (i = 0; i < dst_h; i++) { + SDL_SCALE_NEAREST__HEIGHT + while (n--) { + const Uint8 *src; + srcx = bpp * (posx >> 16); + posx += incx; + src = (const Uint8 *)src_h0 + srcx; + *(Uint8 *)dst = *src; + dst = (Uint32 *)((Uint8 *)dst + bpp); + } + dst = (Uint32 *)((Uint8 *)dst + dst_gap); + } + return 0; +} + +static int scale_mat_nearest_2(const Uint32 *src_ptr, int src_w, int src_h, int src_pitch, + Uint32 *dst, int dst_w, int dst_h, int dst_pitch) +{ + Uint32 bpp = 2; + SDL_SCALE_NEAREST__START + for (i = 0; i < dst_h; i++) { + SDL_SCALE_NEAREST__HEIGHT + while (n--) { + const Uint16 *src; + srcx = bpp * (posx >> 16); + posx += incx; + src = (const Uint16 *)((const Uint8 *)src_h0 + srcx); + *(Uint16 *)dst = *src; + dst = (Uint32 *)((Uint8 *)dst + bpp); + } + dst = (Uint32 *)((Uint8 *)dst + dst_gap); + } + return 0; +} + +static int scale_mat_nearest_3(const Uint32 *src_ptr, int src_w, int src_h, int src_pitch, + Uint32 *dst, int dst_w, int dst_h, int dst_pitch) +{ + Uint32 bpp = 3; + SDL_SCALE_NEAREST__START + for (i = 0; i < dst_h; i++) { + SDL_SCALE_NEAREST__HEIGHT + while (n--) { + const Uint8 *src; + srcx = bpp * (posx >> 16); + posx += incx; + src = (const Uint8 *)src_h0 + srcx; + ((Uint8 *)dst)[0] = src[0]; + ((Uint8 *)dst)[1] = src[1]; + ((Uint8 *)dst)[2] = src[2]; + dst = (Uint32 *)((Uint8 *)dst + bpp); + } + dst = (Uint32 *)((Uint8 *)dst + dst_gap); + } + return 0; +} + +static int scale_mat_nearest_4(const Uint32 *src_ptr, int src_w, int src_h, int src_pitch, + Uint32 *dst, int dst_w, int dst_h, int dst_pitch) +{ + Uint32 bpp = 4; + SDL_SCALE_NEAREST__START + for (i = 0; i < dst_h; i++) { + SDL_SCALE_NEAREST__HEIGHT + while (n--) { + const Uint32 *src; + srcx = bpp * (posx >> 16); + posx += incx; + src = (const Uint32 *)((const Uint8 *)src_h0 + srcx); + *dst = *src; + dst = (Uint32 *)((Uint8 *)dst + bpp); + } + dst = (Uint32 *)((Uint8 *)dst + dst_gap); + } + return 0; +} + +int SDL_LowerSoftStretchNearest(SDL_Surface *s, const SDL_Rect *srcrect, + SDL_Surface *d, const SDL_Rect *dstrect) +{ + int src_w = srcrect->w; + int src_h = srcrect->h; + int dst_w = dstrect->w; + int dst_h = dstrect->h; + int src_pitch = s->pitch; + int dst_pitch = d->pitch; + + const int bpp = d->format->BytesPerPixel; + + Uint32 *src = (Uint32 *)((Uint8 *)s->pixels + srcrect->x * bpp + srcrect->y * src_pitch); + Uint32 *dst = (Uint32 *)((Uint8 *)d->pixels + dstrect->x * bpp + dstrect->y * dst_pitch); + + if (bpp == 4) { + return scale_mat_nearest_4(src, src_w, src_h, src_pitch, dst, dst_w, dst_h, dst_pitch); + } else if (bpp == 3) { + return scale_mat_nearest_3(src, src_w, src_h, src_pitch, dst, dst_w, dst_h, dst_pitch); + } else if (bpp == 2) { + return scale_mat_nearest_2(src, src_w, src_h, src_pitch, dst, dst_w, dst_h, dst_pitch); + } else { + return scale_mat_nearest_1(src, src_w, src_h, src_pitch, dst, dst_w, dst_h, dst_pitch); + } +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/SDL_surface.c b/SDL2-2.30.5/src/video/SDL_surface.c similarity index 55% rename from SDL2-2.0.12/src/video/SDL_surface.c rename to SDL2-2.30.5/src/video/SDL_surface.c index 3795b94..9db0c50 100644 --- a/SDL2-2.0.12/src/video/SDL_surface.c +++ b/SDL2-2.30.5/src/video/SDL_surface.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,47 +26,88 @@ #include "SDL_RLEaccel_c.h" #include "SDL_pixels_c.h" #include "SDL_yuv_c.h" - +#include "../render/SDL_sysrender.h" /* 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)); + sizeof(int) == sizeof(Sint32) && sizeof(size_t) >= sizeof(Sint32)); + +SDL_COMPILE_TIME_ASSERT(can_indicate_overflow, SDL_SIZE_MAX > SDL_MAX_SINT32); /* Public routines */ /* - * Calculate the pad-aligned scanline width of a surface + * Calculate the pad-aligned scanline width of a surface. + * Return SDL_SIZE_MAX on overflow. + * + * for FOURCC, use SDL_CalculateYUVSize() */ -static int -SDL_CalculatePitch(Uint32 format, int width) +static size_t SDL_CalculatePitch(Uint32 format, size_t width, SDL_bool minimal) { - int pitch; + size_t pitch; - if (SDL_ISPIXELFORMAT_FOURCC(format) || SDL_BITSPERPIXEL(format) >= 8) { - pitch = (width * SDL_BYTESPERPIXEL(format)); + if (SDL_BITSPERPIXEL(format) >= 8) { + if (SDL_size_mul_overflow(width, SDL_BYTESPERPIXEL(format), &pitch)) { + return SDL_SIZE_MAX; + } } else { - pitch = ((width * SDL_BITSPERPIXEL(format)) + 7) / 8; + if (SDL_size_mul_overflow(width, SDL_BITSPERPIXEL(format), &pitch)) { + return SDL_SIZE_MAX; + } + if (SDL_size_add_overflow(pitch, 7, &pitch)) { + return SDL_SIZE_MAX; + } + pitch /= 8; + } + if (!minimal) { + /* 4-byte aligning for speed */ + if (SDL_size_add_overflow(pitch, 3, &pitch)) { + return SDL_SIZE_MAX; + } + pitch &= ~3; } - pitch = (pitch + 3) & ~3; /* 4-byte aligning for speed */ return pitch; } +/* TODO: In SDL 3, drop the unused flags and depth parameters */ /* * Create an empty RGB surface of the appropriate depth using the given * enum SDL_PIXELFORMAT_* format */ -SDL_Surface * -SDL_CreateRGBSurfaceWithFormat(Uint32 flags, int width, int height, int depth, +SDL_Surface *SDL_CreateRGBSurfaceWithFormat(Uint32 flags, int width, int height, int depth, Uint32 format) { + size_t pitch; SDL_Surface *surface; /* The flags are no longer used, make the compiler happy */ (void)flags; + if (width < 0) { + SDL_InvalidParamError("width"); + return NULL; + } + + if (height < 0) { + SDL_InvalidParamError("height"); + return NULL; + } + + if (SDL_ISPIXELFORMAT_FOURCC(format)) { + SDL_SetError("invalid format"); + return NULL; + } else { + pitch = SDL_CalculatePitch(format, width, SDL_FALSE); + if (pitch > SDL_MAX_SINT32) { + /* Overflow... */ + SDL_OutOfMemory(); + return NULL; + } + } + /* Allocate the surface */ - surface = (SDL_Surface *) SDL_calloc(1, sizeof(*surface)); - if (surface == NULL) { + surface = (SDL_Surface *)SDL_calloc(1, sizeof(*surface)); + if (!surface) { SDL_OutOfMemory(); return NULL; } @@ -78,7 +119,7 @@ SDL_CreateRGBSurfaceWithFormat(Uint32 flags, int width, int height, int depth, } surface->w = width; surface->h = height; - surface->pitch = SDL_CalculatePitch(format, width); + surface->pitch = (int)pitch; SDL_SetClipRect(surface, NULL); if (SDL_ISPIXELFORMAT_INDEXED(surface->format->format)) { @@ -104,15 +145,15 @@ SDL_CreateRGBSurfaceWithFormat(Uint32 flags, int width, int height, int depth, /* Get the pixels */ if (surface->w && surface->h) { /* Assumptions checked in surface_size_assumptions assert above */ - Sint64 size = ((Sint64)surface->h * surface->pitch); - if (size < 0 || size > SDL_MAX_SINT32) { + size_t size; + if (SDL_size_mul_overflow(surface->h, surface->pitch, &size)) { /* Overflow... */ SDL_FreeSurface(surface); SDL_OutOfMemory(); return NULL; } - surface->pixels = SDL_SIMDAlloc((size_t)size); + surface->pixels = SDL_SIMDAlloc(size); if (!surface->pixels) { SDL_FreeSurface(surface); SDL_OutOfMemory(); @@ -120,7 +161,7 @@ SDL_CreateRGBSurfaceWithFormat(Uint32 flags, int width, int height, int depth, } surface->flags |= SDL_SIMD_ALIGNED; /* This is important for bitmaps */ - SDL_memset(surface->pixels, 0, surface->h * surface->pitch); + SDL_memset(surface->pixels, 0, size); } /* Allocate an empty mapping */ @@ -140,11 +181,11 @@ SDL_CreateRGBSurfaceWithFormat(Uint32 flags, int width, int height, int depth, return surface; } +/* TODO: In SDL 3, drop the unused flags parameter */ /* * Create an empty RGB surface of the appropriate depth */ -SDL_Surface * -SDL_CreateRGBSurface(Uint32 flags, +SDL_Surface *SDL_CreateRGBSurface(Uint32 flags, int width, int height, int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) { @@ -163,16 +204,41 @@ SDL_CreateRGBSurface(Uint32 flags, /* * Create an RGB surface from an existing memory buffer */ -SDL_Surface * -SDL_CreateRGBSurfaceFrom(void *pixels, +SDL_Surface *SDL_CreateRGBSurfaceFrom(void *pixels, int width, int height, int depth, int pitch, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) { SDL_Surface *surface; + Uint32 format; + size_t minimalPitch; - surface = SDL_CreateRGBSurface(0, 0, 0, depth, Rmask, Gmask, Bmask, Amask); - if (surface != NULL) { + if (width < 0) { + SDL_InvalidParamError("width"); + return NULL; + } + + if (height < 0) { + SDL_InvalidParamError("height"); + return NULL; + } + + format = SDL_MasksToPixelFormatEnum(depth, Rmask, Gmask, Bmask, Amask); + + if (format == SDL_PIXELFORMAT_UNKNOWN) { + SDL_SetError("Unknown pixel format"); + return NULL; + } + + minimalPitch = SDL_CalculatePitch(format, width, SDL_TRUE); + + if (pitch < 0 || (pitch > 0 && ((size_t)pitch) < minimalPitch)) { + SDL_InvalidParamError("pitch"); + return NULL; + } + + surface = SDL_CreateRGBSurfaceWithFormat(0, 0, 0, depth, format); + if (surface) { surface->flags |= SDL_PREALLOC; surface->pixels = pixels; surface->w = width; @@ -183,19 +249,42 @@ SDL_CreateRGBSurfaceFrom(void *pixels, return surface; } +/* TODO: In SDL 3, drop the unused depth parameter */ /* * Create an RGB surface from an existing memory buffer using the given given * enum SDL_PIXELFORMAT_* format */ -SDL_Surface * -SDL_CreateRGBSurfaceWithFormatFrom(void *pixels, +SDL_Surface *SDL_CreateRGBSurfaceWithFormatFrom(void *pixels, int width, int height, int depth, int pitch, Uint32 format) { SDL_Surface *surface; + size_t minimalPitch; + + if (width < 0) { + SDL_InvalidParamError("width"); + return NULL; + } + + if (height < 0) { + SDL_InvalidParamError("height"); + return NULL; + } + + if (SDL_ISPIXELFORMAT_FOURCC(format)) { + SDL_SetError("invalid format"); + return NULL; + } else { + minimalPitch = SDL_CalculatePitch(format, width, SDL_TRUE); + } + + if (pitch < 0 || (pitch > 0 && ((size_t)pitch) < minimalPitch)) { + SDL_InvalidParamError("pitch"); + return NULL; + } surface = SDL_CreateRGBSurfaceWithFormat(0, 0, 0, depth, format); - if (surface != NULL) { + if (surface) { surface->flags |= SDL_PREALLOC; surface->pixels = pixels; surface->w = width; @@ -206,11 +295,10 @@ SDL_CreateRGBSurfaceWithFormatFrom(void *pixels, return surface; } -int -SDL_SetSurfacePalette(SDL_Surface * surface, SDL_Palette * palette) +int SDL_SetSurfacePalette(SDL_Surface *surface, SDL_Palette *palette) { if (!surface) { - return SDL_SetError("SDL_SetSurfacePalette() passed a NULL surface"); + return SDL_InvalidParamError("SDL_SetSurfacePalette(): surface"); } if (SDL_SetPixelFormatPalette(surface->format, palette) < 0) { return -1; @@ -220,13 +308,12 @@ SDL_SetSurfacePalette(SDL_Surface * surface, SDL_Palette * palette) return 0; } -int -SDL_SetSurfaceRLE(SDL_Surface * surface, int flag) +int SDL_SetSurfaceRLE(SDL_Surface *surface, int flag) { int flags; if (!surface) { - return -1; + return SDL_InvalidParamError("surface"); } flags = surface->map->info.flags; @@ -241,8 +328,20 @@ SDL_SetSurfaceRLE(SDL_Surface * surface, int flag) return 0; } -int -SDL_SetColorKey(SDL_Surface * surface, int flag, Uint32 key) +SDL_bool SDL_HasSurfaceRLE(SDL_Surface *surface) +{ + if (!surface) { + return SDL_FALSE; + } + + if (!(surface->map->info.flags & SDL_COPY_RLE_DESIRED)) { + return SDL_FALSE; + } + + return SDL_TRUE; +} + +int SDL_SetColorKey(SDL_Surface *surface, int flag, Uint32 key) { int flags; @@ -250,7 +349,7 @@ SDL_SetColorKey(SDL_Surface * surface, int flag, Uint32 key) return SDL_InvalidParamError("surface"); } - if (surface->format->palette && key >= ((Uint32) surface->format->palette->ncolors)) { + if (surface->format->palette && key >= ((Uint32)surface->format->palette->ncolors)) { return SDL_InvalidParamError("key"); } @@ -272,8 +371,7 @@ SDL_SetColorKey(SDL_Surface * surface, int flag, Uint32 key) return 0; } -SDL_bool -SDL_HasColorKey(SDL_Surface * surface) +SDL_bool SDL_HasColorKey(SDL_Surface *surface) { if (!surface) { return SDL_FALSE; @@ -286,8 +384,7 @@ SDL_HasColorKey(SDL_Surface * surface) return SDL_TRUE; } -int -SDL_GetColorKey(SDL_Surface * surface, Uint32 * key) +int SDL_GetColorKey(SDL_Surface *surface, Uint32 *key) { if (!surface) { return SDL_InvalidParamError("surface"); @@ -303,11 +400,11 @@ SDL_GetColorKey(SDL_Surface * surface, Uint32 * key) return 0; } -/* This is a fairly slow function to switch from colorkey to alpha */ -static void -SDL_ConvertColorkeyToAlpha(SDL_Surface * surface, SDL_bool ignore_alpha) +/* This is a fairly slow function to switch from colorkey to alpha + NB: it doesn't handle bpp 1 or 3, because they have no alpha channel */ +static void SDL_ConvertColorkeyToAlpha(SDL_Surface *surface, SDL_bool ignore_alpha) { - int x, y; + int x, y, bpp; if (!surface) { return; @@ -318,82 +415,74 @@ SDL_ConvertColorkeyToAlpha(SDL_Surface * surface, SDL_bool ignore_alpha) return; } + bpp = surface->format->BytesPerPixel; + SDL_LockSurface(surface); - switch (surface->format->BytesPerPixel) { - case 2: - { - Uint16 *row, *spot; - Uint16 ckey = (Uint16) surface->map->info.colorkey; - Uint16 mask = (Uint16) (~surface->format->Amask); + if (bpp == 2) { + Uint16 *row, *spot; + Uint16 ckey = (Uint16)surface->map->info.colorkey; + Uint16 mask = (Uint16)(~surface->format->Amask); - /* Ignore, or not, alpha in colorkey comparison */ - if (ignore_alpha) { - ckey &= mask; - row = (Uint16 *) surface->pixels; - for (y = surface->h; y--;) { - spot = row; - for (x = surface->w; x--;) { - if ((*spot & mask) == ckey) { - *spot &= mask; - } - ++spot; + /* Ignore, or not, alpha in colorkey comparison */ + if (ignore_alpha) { + ckey &= mask; + row = (Uint16 *)surface->pixels; + for (y = surface->h; y--;) { + spot = row; + for (x = surface->w; x--;) { + if ((*spot & mask) == ckey) { + *spot &= mask; } - row += surface->pitch / 2; + ++spot; } - } else { - row = (Uint16 *) surface->pixels; - for (y = surface->h; y--;) { - spot = row; - for (x = surface->w; x--;) { - if (*spot == ckey) { - *spot &= mask; - } - ++spot; + row += surface->pitch / 2; + } + } else { + row = (Uint16 *)surface->pixels; + for (y = surface->h; y--;) { + spot = row; + for (x = surface->w; x--;) { + if (*spot == ckey) { + *spot &= mask; } - row += surface->pitch / 2; + ++spot; } + row += surface->pitch / 2; } } - break; - case 3: - /* FIXME */ - break; - case 4: - { - Uint32 *row, *spot; - Uint32 ckey = surface->map->info.colorkey; - Uint32 mask = ~surface->format->Amask; + } else if (bpp == 4) { + Uint32 *row, *spot; + Uint32 ckey = surface->map->info.colorkey; + Uint32 mask = ~surface->format->Amask; - /* Ignore, or not, alpha in colorkey comparison */ - if (ignore_alpha) { - ckey &= mask; - row = (Uint32 *) surface->pixels; - for (y = surface->h; y--;) { - spot = row; - for (x = surface->w; x--;) { - if ((*spot & mask) == ckey) { - *spot &= mask; - } - ++spot; + /* Ignore, or not, alpha in colorkey comparison */ + if (ignore_alpha) { + ckey &= mask; + row = (Uint32 *)surface->pixels; + for (y = surface->h; y--;) { + spot = row; + for (x = surface->w; x--;) { + if ((*spot & mask) == ckey) { + *spot &= mask; } - row += surface->pitch / 4; + ++spot; } - } else { - row = (Uint32 *) surface->pixels; - for (y = surface->h; y--;) { - spot = row; - for (x = surface->w; x--;) { - if (*spot == ckey) { - *spot &= mask; - } - ++spot; + row += surface->pitch / 4; + } + } else { + row = (Uint32 *)surface->pixels; + for (y = surface->h; y--;) { + spot = row; + for (x = surface->w; x--;) { + if (*spot == ckey) { + *spot &= mask; } - row += surface->pitch / 4; + ++spot; } + row += surface->pitch / 4; } } - break; } SDL_UnlockSurface(surface); @@ -402,13 +491,12 @@ SDL_ConvertColorkeyToAlpha(SDL_Surface * surface, SDL_bool ignore_alpha) SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_BLEND); } -int -SDL_SetSurfaceColorMod(SDL_Surface * surface, Uint8 r, Uint8 g, Uint8 b) +int SDL_SetSurfaceColorMod(SDL_Surface *surface, Uint8 r, Uint8 g, Uint8 b) { int flags; if (!surface) { - return -1; + return SDL_InvalidParamError("surface"); } surface->map->info.r = r; @@ -427,12 +515,10 @@ SDL_SetSurfaceColorMod(SDL_Surface * surface, Uint8 r, Uint8 g, Uint8 b) return 0; } - -int -SDL_GetSurfaceColorMod(SDL_Surface * surface, Uint8 * r, Uint8 * g, Uint8 * b) +int SDL_GetSurfaceColorMod(SDL_Surface *surface, Uint8 *r, Uint8 *g, Uint8 *b) { if (!surface) { - return -1; + return SDL_InvalidParamError("surface"); } if (r) { @@ -447,13 +533,12 @@ SDL_GetSurfaceColorMod(SDL_Surface * surface, Uint8 * r, Uint8 * g, Uint8 * b) return 0; } -int -SDL_SetSurfaceAlphaMod(SDL_Surface * surface, Uint8 alpha) +int SDL_SetSurfaceAlphaMod(SDL_Surface *surface, Uint8 alpha) { int flags; if (!surface) { - return -1; + return SDL_InvalidParamError("surface"); } surface->map->info.a = alpha; @@ -470,11 +555,10 @@ SDL_SetSurfaceAlphaMod(SDL_Surface * surface, Uint8 alpha) return 0; } -int -SDL_GetSurfaceAlphaMod(SDL_Surface * surface, Uint8 * alpha) +int SDL_GetSurfaceAlphaMod(SDL_Surface *surface, Uint8 *alpha) { if (!surface) { - return -1; + return SDL_InvalidParamError("surface"); } if (alpha) { @@ -483,13 +567,12 @@ SDL_GetSurfaceAlphaMod(SDL_Surface * surface, Uint8 * alpha) return 0; } -int -SDL_SetSurfaceBlendMode(SDL_Surface * surface, SDL_BlendMode blendMode) +int SDL_SetSurfaceBlendMode(SDL_Surface *surface, SDL_BlendMode blendMode) { int flags, status; if (!surface) { - return -1; + return SDL_InvalidParamError("surface"); } status = 0; @@ -523,19 +606,17 @@ SDL_SetSurfaceBlendMode(SDL_Surface * surface, SDL_BlendMode blendMode) return status; } -int -SDL_GetSurfaceBlendMode(SDL_Surface * surface, SDL_BlendMode *blendMode) +int SDL_GetSurfaceBlendMode(SDL_Surface *surface, SDL_BlendMode *blendMode) { if (!surface) { - return -1; + return SDL_InvalidParamError("surface"); } if (!blendMode) { return 0; } - switch (surface->map-> - info.flags & (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_MUL)) { + switch (surface->map->info.flags & (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_MUL)) { case SDL_COPY_BLEND: *blendMode = SDL_BLENDMODE_BLEND; break; @@ -555,8 +636,7 @@ SDL_GetSurfaceBlendMode(SDL_Surface * surface, SDL_BlendMode *blendMode) return 0; } -SDL_bool -SDL_SetClipRect(SDL_Surface * surface, const SDL_Rect * rect) +SDL_bool SDL_SetClipRect(SDL_Surface *surface, const SDL_Rect *rect) { SDL_Rect full_rect; @@ -579,8 +659,7 @@ SDL_SetClipRect(SDL_Surface * surface, const SDL_Rect * rect) return SDL_IntersectRect(rect, &full_rect, &surface->clip_rect); } -void -SDL_GetClipRect(SDL_Surface * surface, SDL_Rect * rect) +void SDL_GetClipRect(SDL_Surface *surface, SDL_Rect *rect) { if (surface && rect) { *rect = surface->clip_rect; @@ -598,9 +677,8 @@ SDL_GetClipRect(SDL_Surface * surface, SDL_Rect * rect) * you know exactly what you are doing, you can optimize your code * by calling the one(s) you need. */ -int -SDL_LowerBlit(SDL_Surface * src, SDL_Rect * srcrect, - SDL_Surface * dst, SDL_Rect * dstrect) +int SDL_LowerBlit(SDL_Surface *src, SDL_Rect *srcrect, + SDL_Surface *dst, SDL_Rect *dstrect) { /* Check to make sure the blit mapping is valid */ if ((src->map->dst != dst) || @@ -609,97 +687,79 @@ SDL_LowerBlit(SDL_Surface * src, SDL_Rect * srcrect, (src->format->palette && src->map->src_palette_version != src->format->palette->version)) { if (SDL_MapSurface(src, dst) < 0) { - return (-1); + return -1; } /* just here for debugging */ -/* printf */ -/* ("src = 0x%08X src->flags = %08X src->map->info.flags = %08x\ndst = 0x%08X dst->flags = %08X dst->map->info.flags = %08X\nsrc->map->blit = 0x%08x\n", */ -/* src, dst->flags, src->map->info.flags, dst, dst->flags, */ -/* dst->map->info.flags, src->map->blit); */ + /* printf */ + /* ("src = 0x%08X src->flags = %08X src->map->info.flags = %08x\ndst = 0x%08X dst->flags = %08X dst->map->info.flags = %08X\nsrc->map->blit = 0x%08x\n", */ + /* src, dst->flags, src->map->info.flags, dst, dst->flags, */ + /* dst->map->info.flags, src->map->blit); */ } - return (src->map->blit(src, srcrect, dst, dstrect)); + return src->map->blit(src, srcrect, dst, dstrect); } - -int -SDL_UpperBlit(SDL_Surface * src, const SDL_Rect * srcrect, - SDL_Surface * dst, SDL_Rect * dstrect) +int SDL_UpperBlit(SDL_Surface *src, const SDL_Rect *srcrect, + SDL_Surface *dst, SDL_Rect *dstrect) { - SDL_Rect fulldst; - int srcx, srcy, w, h; + SDL_Rect r_src, r_dst; /* Make sure the surfaces aren't locked */ - if (!src || !dst) { - return SDL_SetError("SDL_UpperBlit: passed a NULL surface"); - } - if (src->locked || dst->locked) { + if (!src) { + return SDL_InvalidParamError("src"); + } else if (!dst) { + return SDL_InvalidParamError("dst"); + } else if (src->locked || dst->locked) { return SDL_SetError("Surfaces must not be locked during blit"); } - /* If the destination rectangle is NULL, use the entire dest surface */ - if (dstrect == NULL) { - fulldst.x = fulldst.y = 0; - fulldst.w = dst->w; - fulldst.h = dst->h; - dstrect = &fulldst; + /* Full src surface */ + r_src.x = 0; + r_src.y = 0; + r_src.w = src->w; + r_src.h = src->h; + + if (dstrect) { + r_dst.x = dstrect->x; + r_dst.y = dstrect->y; + } else { + r_dst.x = 0; + r_dst.y = 0; } /* clip the source rectangle to the source surface */ if (srcrect) { - int maxw, maxh; - - srcx = srcrect->x; - w = srcrect->w; - if (srcx < 0) { - w += srcx; - dstrect->x -= srcx; - srcx = 0; + SDL_Rect tmp; + if (SDL_IntersectRect(srcrect, &r_src, &tmp) == SDL_FALSE) { + goto end; } - maxw = src->w - srcx; - if (maxw < w) - w = maxw; - srcy = srcrect->y; - h = srcrect->h; - if (srcy < 0) { - h += srcy; - dstrect->y -= srcy; - srcy = 0; - } - maxh = src->h - srcy; - if (maxh < h) - h = maxh; + /* Shift dstrect, if srcrect origin has changed */ + r_dst.x += tmp.x - srcrect->x; + r_dst.y += tmp.y - srcrect->y; - } else { - srcx = srcy = 0; - w = src->w; - h = src->h; + /* Update srcrect */ + r_src = tmp; } + /* There're no dstrect.w/h parameters. It's the same as srcrect */ + r_dst.w = r_src.w; + r_dst.h = r_src.h; + /* clip the destination rectangle against the clip rectangle */ { - SDL_Rect *clip = &dst->clip_rect; - int dx, dy; - - dx = clip->x - dstrect->x; - if (dx > 0) { - w -= dx; - dstrect->x += dx; - srcx += dx; + SDL_Rect tmp; + if (SDL_IntersectRect(&r_dst, &dst->clip_rect, &tmp) == SDL_FALSE) { + goto end; } - dx = dstrect->x + w - clip->x - clip->w; - if (dx > 0) - w -= dx; - dy = clip->y - dstrect->y; - if (dy > 0) { - h -= dy; - dstrect->y += dy; - srcy += dy; - } - dy = dstrect->y + h - clip->y - clip->h; - if (dy > 0) - h -= dy; + /* Shift srcrect, if dstrect has changed */ + r_src.x += tmp.x - r_dst.x; + r_src.y += tmp.y - r_dst.y; + r_src.w = tmp.w; + r_src.h = tmp.h; + + /* Update dstrect */ + r_dst = tmp; } /* Switch back to a fast blit if we were previously stretching */ @@ -708,21 +768,28 @@ SDL_UpperBlit(SDL_Surface * src, const SDL_Rect * srcrect, SDL_InvalidateMap(src->map); } - if (w > 0 && h > 0) { - SDL_Rect sr; - sr.x = srcx; - sr.y = srcy; - sr.w = dstrect->w = w; - sr.h = dstrect->h = h; - return SDL_LowerBlit(src, &sr, dst, dstrect); + if (r_dst.w > 0 && r_dst.h > 0) { + if (dstrect) { /* update output parameter */ + *dstrect = r_dst; + } + return SDL_LowerBlit(src, &r_src, dst, &r_dst); + } + +end: + if (dstrect) { /* update output parameter */ + dstrect->w = dstrect->h = 0; } - dstrect->w = dstrect->h = 0; return 0; } -int -SDL_UpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect, - SDL_Surface * dst, SDL_Rect * dstrect) +int SDL_UpperBlitScaled(SDL_Surface *src, const SDL_Rect *srcrect, + SDL_Surface *dst, SDL_Rect *dstrect) +{ + return SDL_PrivateUpperBlitScaled(src, srcrect, dst, dstrect, SDL_ScaleModeNearest); +} + +int SDL_PrivateUpperBlitScaled(SDL_Surface *src, const SDL_Rect *srcrect, + SDL_Surface *dst, SDL_Rect *dstrect, SDL_ScaleMode scaleMode) { double src_x0, src_y0, src_x1, src_y1; double dst_x0, dst_y0, dst_x1, dst_y1; @@ -733,13 +800,13 @@ SDL_UpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect, /* Make sure the surfaces aren't locked */ if (!src || !dst) { - return SDL_SetError("SDL_UpperBlitScaled: passed a NULL surface"); + return SDL_InvalidParamError("SDL_UpperBlitScaled(): src/dst"); } if (src->locked || dst->locked) { return SDL_SetError("Surfaces must not be locked during blit"); } - if (NULL == srcrect) { + if (!srcrect) { src_w = src->w; src_h = src->h; } else { @@ -747,7 +814,7 @@ SDL_UpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect, src_h = srcrect->h; } - if (NULL == dstrect) { + if (!dstrect) { dst_w = dst->w; dst_h = dst->h; } else { @@ -763,28 +830,28 @@ SDL_UpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect, scaling_w = (double)dst_w / src_w; scaling_h = (double)dst_h / src_h; - if (NULL == dstrect) { + if (!dstrect) { dst_x0 = 0; dst_y0 = 0; - dst_x1 = dst_w - 1; - dst_y1 = dst_h - 1; + dst_x1 = dst_w; + dst_y1 = dst_h; } else { dst_x0 = dstrect->x; dst_y0 = dstrect->y; - dst_x1 = dst_x0 + dst_w - 1; - dst_y1 = dst_y0 + dst_h - 1; + dst_x1 = dst_x0 + dst_w; + dst_y1 = dst_y0 + dst_h; } - if (NULL == srcrect) { + if (!srcrect) { src_x0 = 0; src_y0 = 0; - src_x1 = src_w - 1; - src_y1 = src_h - 1; + src_x1 = src_w; + src_y1 = src_h; } else { src_x0 = srcrect->x; src_y0 = srcrect->y; - src_x1 = src_x0 + src_w - 1; - src_y1 = src_y0 + src_h - 1; + src_x1 = src_x0 + src_w; + src_y1 = src_y0 + src_h; /* Clip source rectangle to the source surface */ @@ -793,9 +860,9 @@ SDL_UpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect, src_x0 = 0; } - if (src_x1 >= src->w) { - dst_x1 -= (src_x1 - src->w + 1) * scaling_w; - src_x1 = src->w - 1; + if (src_x1 > src->w) { + dst_x1 -= (src_x1 - src->w) * scaling_w; + src_x1 = src->w; } if (src_y0 < 0) { @@ -803,9 +870,9 @@ SDL_UpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect, src_y0 = 0; } - if (src_y1 >= src->h) { - dst_y1 -= (src_y1 - src->h + 1) * scaling_h; - src_y1 = src->h - 1; + if (src_y1 > src->h) { + dst_y1 -= (src_y1 - src->h) * scaling_h; + src_y1 = src->h; } } @@ -822,9 +889,9 @@ SDL_UpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect, dst_x0 = 0; } - if (dst_x1 >= dst->clip_rect.w) { - src_x1 -= (dst_x1 - dst->clip_rect.w + 1) / scaling_w; - dst_x1 = dst->clip_rect.w - 1; + if (dst_x1 > dst->clip_rect.w) { + src_x1 -= (dst_x1 - dst->clip_rect.w) / scaling_w; + dst_x1 = dst->clip_rect.w; } if (dst_y0 < 0) { @@ -832,9 +899,9 @@ SDL_UpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect, dst_y0 = 0; } - if (dst_y1 >= dst->clip_rect.h) { - src_y1 -= (dst_y1 - dst->clip_rect.h + 1) / scaling_h; - dst_y1 = dst->clip_rect.h - 1; + if (dst_y1 > dst->clip_rect.h) { + src_y1 -= (dst_y1 - dst->clip_rect.h) / scaling_h; + dst_y1 = dst->clip_rect.h; } /* Translate back to surface coordinates */ @@ -843,23 +910,32 @@ SDL_UpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect, dst_y0 += dst->clip_rect.y; dst_y1 += dst->clip_rect.y; - final_src.x = (int)SDL_floor(src_x0 + 0.5); - final_src.y = (int)SDL_floor(src_y0 + 0.5); - final_src.w = (int)SDL_floor(src_x1 + 1 + 0.5) - (int)SDL_floor(src_x0 + 0.5); - final_src.h = (int)SDL_floor(src_y1 + 1 + 0.5) - (int)SDL_floor(src_y0 + 0.5); + final_src.x = (int)SDL_round(src_x0); + final_src.y = (int)SDL_round(src_y0); + final_src.w = (int)SDL_round(src_x1 - src_x0); + final_src.h = (int)SDL_round(src_y1 - src_y0); - final_dst.x = (int)SDL_floor(dst_x0 + 0.5); - final_dst.y = (int)SDL_floor(dst_y0 + 0.5); - final_dst.w = (int)SDL_floor(dst_x1 - dst_x0 + 1.5); - final_dst.h = (int)SDL_floor(dst_y1 - dst_y0 + 1.5); + final_dst.x = (int)SDL_round(dst_x0); + final_dst.y = (int)SDL_round(dst_y0); + final_dst.w = (int)SDL_round(dst_x1 - dst_x0); + final_dst.h = (int)SDL_round(dst_y1 - dst_y0); - if (final_dst.w < 0) - final_dst.w = 0; - if (final_dst.h < 0) - final_dst.h = 0; + /* Clip again */ + { + SDL_Rect tmp; + tmp.x = 0; + tmp.y = 0; + tmp.w = src->w; + tmp.h = src->h; + SDL_IntersectRect(&tmp, &final_src, &final_src); + } - if (dstrect) + /* Clip again */ + SDL_IntersectRect(&dst->clip_rect, &final_dst, &final_dst); + + if (dstrect) { *dstrect = final_dst; + } if (final_dst.w == 0 || final_dst.h == 0 || final_src.w <= 0 || final_src.h <= 0) { @@ -867,49 +943,136 @@ SDL_UpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect, return 0; } - return SDL_LowerBlitScaled(src, &final_src, dst, &final_dst); + return SDL_PrivateLowerBlitScaled(src, &final_src, dst, &final_dst, scaleMode); } /** * This is a semi-private blit function and it performs low-level surface * scaled blitting only. */ -int -SDL_LowerBlitScaled(SDL_Surface * src, SDL_Rect * srcrect, - SDL_Surface * dst, SDL_Rect * dstrect) +int SDL_LowerBlitScaled(SDL_Surface *src, SDL_Rect *srcrect, + SDL_Surface *dst, SDL_Rect *dstrect) { - static const Uint32 complex_copy_flags = ( - SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | - SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_MUL | - SDL_COPY_COLORKEY - ); + return SDL_PrivateLowerBlitScaled(src, srcrect, dst, dstrect, SDL_ScaleModeNearest); +} + +int SDL_PrivateLowerBlitScaled(SDL_Surface *src, SDL_Rect *srcrect, + SDL_Surface *dst, SDL_Rect *dstrect, SDL_ScaleMode scaleMode) +{ + static const Uint32 complex_copy_flags = (SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA | + SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_MUL | + SDL_COPY_COLORKEY); + + if (srcrect->w > SDL_MAX_UINT16 || srcrect->h > SDL_MAX_UINT16 || + dstrect->w > SDL_MAX_UINT16 || dstrect->h > SDL_MAX_UINT16) { + return SDL_SetError("Size too large for scaling"); + } if (!(src->map->info.flags & SDL_COPY_NEAREST)) { src->map->info.flags |= SDL_COPY_NEAREST; SDL_InvalidateMap(src->map); } - if ( !(src->map->info.flags & complex_copy_flags) && - src->format->format == dst->format->format && - !SDL_ISPIXELFORMAT_INDEXED(src->format->format) ) { - return SDL_SoftStretch( src, srcrect, dst, dstrect ); + if (scaleMode == SDL_ScaleModeNearest) { + if (!(src->map->info.flags & complex_copy_flags) && + src->format->format == dst->format->format && + !SDL_ISPIXELFORMAT_INDEXED(src->format->format)) { + return SDL_SoftStretch(src, srcrect, dst, dstrect); + } else { + return SDL_LowerBlit(src, srcrect, dst, dstrect); + } } else { - return SDL_LowerBlit( src, srcrect, dst, dstrect ); + if (!(src->map->info.flags & complex_copy_flags) && + src->format->format == dst->format->format && + !SDL_ISPIXELFORMAT_INDEXED(src->format->format) && + src->format->BytesPerPixel == 4 && + src->format->format != SDL_PIXELFORMAT_ARGB2101010) { + /* fast path */ + return SDL_SoftStretchLinear(src, srcrect, dst, dstrect); + } else { + /* Use intermediate surface(s) */ + SDL_Surface *tmp1 = NULL; + int ret; + SDL_Rect srcrect2; + int is_complex_copy_flags = (src->map->info.flags & complex_copy_flags); + + Uint32 flags; + Uint8 r, g, b; + Uint8 alpha; + SDL_BlendMode blendMode; + + /* Save source infos */ + flags = src->flags; + SDL_GetSurfaceColorMod(src, &r, &g, &b); + SDL_GetSurfaceAlphaMod(src, &alpha); + SDL_GetSurfaceBlendMode(src, &blendMode); + srcrect2.x = srcrect->x; + srcrect2.y = srcrect->y; + srcrect2.w = srcrect->w; + srcrect2.h = srcrect->h; + + /* Change source format if not appropriate for scaling */ + if (src->format->BytesPerPixel != 4 || src->format->format == SDL_PIXELFORMAT_ARGB2101010) { + SDL_Rect tmprect; + int fmt; + tmprect.x = 0; + tmprect.y = 0; + tmprect.w = src->w; + tmprect.h = src->h; + if (dst->format->BytesPerPixel == 4 && dst->format->format != SDL_PIXELFORMAT_ARGB2101010) { + fmt = dst->format->format; + } else { + fmt = SDL_PIXELFORMAT_ARGB8888; + } + tmp1 = SDL_CreateRGBSurfaceWithFormat(flags, src->w, src->h, 0, fmt); + SDL_LowerBlit(src, srcrect, tmp1, &tmprect); + + srcrect2.x = 0; + srcrect2.y = 0; + SDL_SetSurfaceColorMod(tmp1, r, g, b); + SDL_SetSurfaceAlphaMod(tmp1, alpha); + SDL_SetSurfaceBlendMode(tmp1, blendMode); + + src = tmp1; + } + + /* Intermediate scaling */ + if (is_complex_copy_flags || src->format->format != dst->format->format) { + SDL_Rect tmprect; + SDL_Surface *tmp2 = SDL_CreateRGBSurfaceWithFormat(flags, dstrect->w, dstrect->h, 0, src->format->format); + SDL_SoftStretchLinear(src, &srcrect2, tmp2, NULL); + + SDL_SetSurfaceColorMod(tmp2, r, g, b); + SDL_SetSurfaceAlphaMod(tmp2, alpha); + SDL_SetSurfaceBlendMode(tmp2, blendMode); + + tmprect.x = 0; + tmprect.y = 0; + tmprect.w = dstrect->w; + tmprect.h = dstrect->h; + ret = SDL_LowerBlit(tmp2, &tmprect, dst, dstrect); + SDL_FreeSurface(tmp2); + } else { + ret = SDL_SoftStretchLinear(src, &srcrect2, dst, dstrect); + } + + SDL_FreeSurface(tmp1); + return ret; + } } } /* * Lock a surface to directly access the pixels */ -int -SDL_LockSurface(SDL_Surface * surface) +int SDL_LockSurface(SDL_Surface *surface) { if (!surface->locked) { #if SDL_HAVE_RLE /* Perform the lock */ if (surface->flags & SDL_RLEACCEL) { SDL_UnRLESurface(surface, 1); - surface->flags |= SDL_RLEACCEL; /* save accel'd state */ + surface->flags |= SDL_RLEACCEL; /* save accel'd state */ } #endif } @@ -918,14 +1081,13 @@ SDL_LockSurface(SDL_Surface * surface) ++surface->locked; /* Ready to go.. */ - return (0); + return 0; } /* * Unlock a previously locked surface */ -void -SDL_UnlockSurface(SDL_Surface * surface) +void SDL_UnlockSurface(SDL_Surface *surface) { /* Only perform an unlock if we are locked */ if (!surface->locked || (--surface->locked > 0)) { @@ -935,7 +1097,7 @@ SDL_UnlockSurface(SDL_Surface * surface) #if SDL_HAVE_RLE /* Update RLE encoded surface with new data */ if ((surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL) { - surface->flags &= ~SDL_RLEACCEL; /* stop lying */ + surface->flags &= ~SDL_RLEACCEL; /* stop lying */ SDL_RLESurface(surface); } #endif @@ -944,8 +1106,7 @@ SDL_UnlockSurface(SDL_Surface * surface) /* * Creates a new surface identical to the existing surface */ -SDL_Surface * -SDL_DuplicateSurface(SDL_Surface * surface) +SDL_Surface *SDL_DuplicateSurface(SDL_Surface *surface) { return SDL_ConvertSurface(surface, surface->format, surface->flags); } @@ -953,8 +1114,7 @@ SDL_DuplicateSurface(SDL_Surface * surface) /* * Convert a surface into the specified pixel format. */ -SDL_Surface * -SDL_ConvertSurface(SDL_Surface * surface, const SDL_PixelFormat * format, +SDL_Surface *SDL_ConvertSurface(SDL_Surface * surface, const SDL_PixelFormat * format, Uint32 flags) { SDL_Surface *convert; @@ -966,6 +1126,7 @@ SDL_ConvertSurface(SDL_Surface * surface, const SDL_PixelFormat * format, int palette_ck_value = 0; SDL_bool palette_has_alpha = SDL_FALSE; Uint8 *palette_saved_alpha = NULL; + int palette_saved_alpha_ncolors = 0; if (!surface) { SDL_InvalidParamError("surface"); @@ -977,17 +1138,16 @@ SDL_ConvertSurface(SDL_Surface * surface, const SDL_PixelFormat * format, } /* Check for empty destination palette! (results in empty image) */ - if (format->palette != NULL) { + if (format->palette) { int i; for (i = 0; i < format->palette->ncolors; ++i) { - if ((format->palette->colors[i].r != 0xFF) || - (format->palette->colors[i].g != 0xFF) || - (format->palette->colors[i].b != 0xFF)) + if ((format->palette->colors[i].r != 0xFF) || (format->palette->colors[i].g != 0xFF) || (format->palette->colors[i].b != 0xFF)) { break; + } } if (i == format->palette->ncolors) { SDL_SetError("Empty destination palette"); - return (NULL); + return NULL; } } @@ -996,8 +1156,8 @@ SDL_ConvertSurface(SDL_Surface * surface, const SDL_PixelFormat * format, format->BitsPerPixel, format->Rmask, format->Gmask, format->Bmask, format->Amask); - if (convert == NULL) { - return (NULL); + if (!convert) { + return NULL; } /* Copy the palette if any */ @@ -1018,7 +1178,7 @@ SDL_ConvertSurface(SDL_Surface * surface, const SDL_PixelFormat * format, surface->map->info.g = 0xFF; surface->map->info.b = 0xFF; surface->map->info.a = 0xFF; - surface->map->info.flags = 0; + surface->map->info.flags = (copy_flags & (SDL_COPY_RLE_COLORKEY | SDL_COPY_RLE_ALPHAKEY)); SDL_InvalidateMap(surface->map); /* Copy over the image data */ @@ -1032,29 +1192,24 @@ SDL_ConvertSurface(SDL_Surface * surface, const SDL_PixelFormat * format, * -> set alpha channel to be opaque */ if (surface->format->palette && format->Amask) { SDL_bool set_opaque = SDL_FALSE; - { - int i; - for (i = 0; i < surface->format->palette->ncolors; i++) { - Uint8 alpha_value = surface->format->palette->colors[i].a; - if (alpha_value != 0 && alpha_value != SDL_ALPHA_OPAQUE) { - /* Palette has at least one alpha value. Don't do anything */ - set_opaque = SDL_FALSE; - palette_has_alpha = SDL_TRUE; - break; - } + SDL_bool is_opaque, has_alpha_channel; + SDL_DetectPalette(surface->format->palette, &is_opaque, &has_alpha_channel); - if (alpha_value == 0) { - set_opaque = SDL_TRUE; - } + if (is_opaque) { + if (!has_alpha_channel) { + set_opaque = SDL_TRUE; } + } else { + palette_has_alpha = SDL_TRUE; } /* Set opaque and backup palette alpha values */ if (set_opaque) { int i; - palette_saved_alpha = SDL_stack_alloc(Uint8, surface->format->palette->ncolors); - for (i = 0; i < surface->format->palette->ncolors; i++) { + palette_saved_alpha_ncolors = surface->format->palette->ncolors; + palette_saved_alpha = SDL_stack_alloc(Uint8, palette_saved_alpha_ncolors); + for (i = 0; i < palette_saved_alpha_ncolors; i++) { palette_saved_alpha[i] = surface->format->palette->colors[i].a; surface->format->palette->colors[i].a = SDL_ALPHA_OPAQUE; } @@ -1081,7 +1236,7 @@ SDL_ConvertSurface(SDL_Surface * surface, const SDL_PixelFormat * format, /* Restore palette alpha values */ if (palette_saved_alpha) { int i; - for (i = 0; i < surface->format->palette->ncolors; i++) { + for (i = 0; i < palette_saved_alpha_ncolors; i++) { surface->format->palette->colors[i].a = palette_saved_alpha[i]; } SDL_stack_free(palette_saved_alpha); @@ -1094,8 +1249,7 @@ SDL_ConvertSurface(SDL_Surface * surface, const SDL_PixelFormat * format, convert->map->info.a = copy_color.a; convert->map->info.flags = (copy_flags & - ~(SDL_COPY_COLORKEY | SDL_COPY_BLEND - | SDL_COPY_RLE_DESIRED | SDL_COPY_RLE_COLORKEY | + ~(SDL_COPY_COLORKEY | SDL_COPY_BLEND | SDL_COPY_RLE_DESIRED | SDL_COPY_RLE_COLORKEY | SDL_COPY_RLE_ALPHAKEY)); surface->map->info.r = copy_color.r; surface->map->info.g = copy_color.g; @@ -1112,16 +1266,23 @@ SDL_ConvertSurface(SDL_Surface * surface, const SDL_PixelFormat * format, if (copy_flags & SDL_COPY_COLORKEY) { SDL_bool set_colorkey_by_color = SDL_FALSE; + SDL_bool convert_colorkey = SDL_TRUE; if (surface->format->palette) { if (format->palette && surface->format->palette->ncolors <= format->palette->ncolors && (SDL_memcmp(surface->format->palette->colors, format->palette->colors, - surface->format->palette->ncolors * sizeof(SDL_Color)) == 0)) { + surface->format->palette->ncolors * sizeof(SDL_Color)) == 0)) { /* The palette is identical, just set the same colorkey */ SDL_SetColorKey(convert, 1, surface->map->info.colorkey); } else if (!format->palette) { - /* Was done by 'palette_ck_transform' */ + if (format->Amask) { + /* No need to add the colorkey, transparency is in the alpha channel*/ + } else { + /* Only set the colorkey information */ + set_colorkey_by_color = SDL_TRUE; + convert_colorkey = SDL_FALSE; + } } else { set_colorkey_by_color = SDL_TRUE; } @@ -1162,7 +1323,9 @@ SDL_ConvertSurface(SDL_Surface * surface, const SDL_PixelFormat * format, SDL_SetColorKey(convert, 1, converted_colorkey); /* This is needed when converting for 3D texture upload */ - SDL_ConvertColorkeyToAlpha(convert, SDL_TRUE); + if (convert_colorkey) { + SDL_ConvertColorkeyToAlpha(convert, SDL_TRUE); + } } } SDL_SetClipRect(convert, &surface->clip_rect); @@ -1179,11 +1342,10 @@ SDL_ConvertSurface(SDL_Surface * surface, const SDL_PixelFormat * format, } /* We're ready to go! */ - return (convert); + return convert; } -SDL_Surface * -SDL_ConvertSurfaceFormat(SDL_Surface * surface, Uint32 pixel_format, +SDL_Surface *SDL_ConvertSurfaceFormat(SDL_Surface * surface, Uint32 pixel_format, Uint32 flags) { SDL_PixelFormat *fmt; @@ -1200,10 +1362,9 @@ SDL_ConvertSurfaceFormat(SDL_Surface * surface, Uint32 pixel_format, /* * Create a surface on the stack for quick blit operations */ -static SDL_INLINE SDL_bool -SDL_CreateSurfaceOnStack(int width, int height, Uint32 pixel_format, - void * pixels, int pitch, SDL_Surface * surface, - SDL_PixelFormat * format, SDL_BlitMap * blitmap) +static SDL_INLINE SDL_bool SDL_CreateSurfaceOnStack(int width, int height, Uint32 pixel_format, + void *pixels, int pitch, SDL_Surface *surface, + SDL_PixelFormat *format, SDL_BlitMap *blitmap) { if (SDL_ISPIXELFORMAT_INDEXED(pixel_format)) { SDL_SetError("Indexed pixel formats not supported"); @@ -1240,16 +1401,22 @@ SDL_CreateSurfaceOnStack(int width, int height, Uint32 pixel_format, * Copy a block of pixels of one format to another format */ int SDL_ConvertPixels(int width, int height, - Uint32 src_format, const void * src, int src_pitch, - Uint32 dst_format, void * dst, int dst_pitch) + Uint32 src_format, const void *src, int src_pitch, + Uint32 dst_format, void *dst, int dst_pitch) { SDL_Surface src_surface, dst_surface; SDL_PixelFormat src_fmt, dst_fmt; SDL_BlitMap src_blitmap, dst_blitmap; SDL_Rect rect; - void *nonconst_src = (void *) src; + void *nonconst_src = (void *)src; + int ret; - /* Check to make sure we are blitting somewhere, so we don't crash */ + if (!src) { + return SDL_InvalidParamError("src"); + } + if (!src_pitch) { + return SDL_InvalidParamError("src_pitch"); + } if (!dst) { return SDL_InvalidParamError("dst"); } @@ -1267,8 +1434,7 @@ int SDL_ConvertPixels(int width, int height, } #else if (SDL_ISPIXELFORMAT_FOURCC(src_format) || SDL_ISPIXELFORMAT_FOURCC(dst_format)) { - SDL_SetError("SDL not built with YUV support"); - return -1; + return SDL_SetError("SDL not built with YUV support"); } #endif @@ -1279,8 +1445,8 @@ int SDL_ConvertPixels(int width, int height, width *= bpp; for (i = height; i--;) { SDL_memcpy(dst, src, width); - src = (const Uint8*)src + src_pitch; - dst = (Uint8*)dst + dst_pitch; + src = (const Uint8 *)src + src_pitch; + dst = (Uint8 *)dst + dst_pitch; } return 0; } @@ -1300,16 +1466,82 @@ int SDL_ConvertPixels(int width, int height, rect.y = 0; rect.w = width; rect.h = height; - return SDL_LowerBlit(&src_surface, &rect, &dst_surface, &rect); + ret = SDL_LowerBlit(&src_surface, &rect, &dst_surface, &rect); + + /* Free blitmap reference, after blitting between stack'ed surfaces */ + SDL_InvalidateMap(src_surface.map); + + return ret; +} + +/* + * Premultiply the alpha on a block of pixels + * + * This is currently only implemented for SDL_PIXELFORMAT_ARGB8888 + * + * Here are some ideas for optimization: + * https://github.com/Wizermil/premultiply_alpha/tree/master/premultiply_alpha + * https://developer.arm.com/documentation/101964/0201/Pre-multiplied-alpha-channel-data + */ +int SDL_PremultiplyAlpha(int width, int height, + Uint32 src_format, const void *src, int src_pitch, + Uint32 dst_format, void *dst, int dst_pitch) +{ + int c; + Uint32 srcpixel; + Uint32 srcR, srcG, srcB, srcA; + Uint32 dstpixel; + Uint32 dstR, dstG, dstB, dstA; + + if (!src) { + return SDL_InvalidParamError("src"); + } + if (!src_pitch) { + return SDL_InvalidParamError("src_pitch"); + } + if (!dst) { + return SDL_InvalidParamError("dst"); + } + if (!dst_pitch) { + return SDL_InvalidParamError("dst_pitch"); + } + if (src_format != SDL_PIXELFORMAT_ARGB8888) { + return SDL_InvalidParamError("src_format"); + } + if (dst_format != SDL_PIXELFORMAT_ARGB8888) { + return SDL_InvalidParamError("dst_format"); + } + + while (height--) { + const Uint32 *src_px = (const Uint32 *)src; + Uint32 *dst_px = (Uint32 *)dst; + for (c = width; c; --c) { + /* Component bytes extraction. */ + srcpixel = *src_px++; + RGBA_FROM_ARGB8888(srcpixel, srcR, srcG, srcB, srcA); + + /* Alpha pre-multiplication of each component. */ + dstA = srcA; + dstR = (srcA * srcR) / 255; + dstG = (srcA * srcG) / 255; + dstB = (srcA * srcB) / 255; + + /* ARGB8888 pixel recomposition. */ + ARGB8888_FROM_RGBA(dstpixel, dstR, dstG, dstB, dstA); + *dst_px++ = dstpixel; + } + src = (const Uint8 *)src + src_pitch; + dst = (Uint8 *)dst + dst_pitch; + } + return 0; } /* * Free a surface created by the above function. */ -void -SDL_FreeSurface(SDL_Surface * surface) +void SDL_FreeSurface(SDL_Surface *surface) { - if (surface == NULL) { + if (!surface) { return; } if (surface->flags & SDL_DONTFREE) { @@ -1317,6 +1549,8 @@ SDL_FreeSurface(SDL_Surface * surface) } SDL_InvalidateMap(surface->map); + SDL_InvalidateAllBlitMap(surface); + if (--surface->refcount > 0) { return; } diff --git a/SDL2-2.0.12/src/video/SDL_sysvideo.h b/SDL2-2.30.5/src/video/SDL_sysvideo.h similarity index 60% rename from SDL2-2.0.12/src/video/SDL_sysvideo.h rename to SDL2-2.30.5/src/video/SDL_sysvideo.h index 38ed971..344efec 100644 --- a/SDL2-2.0.12/src/video/SDL_sysvideo.h +++ b/SDL2-2.30.5/src/video/SDL_sysvideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -24,6 +24,7 @@ #define SDL_sysvideo_h_ #include "SDL_messagebox.h" +#include "SDL_mouse.h" #include "SDL_shape.h" #include "SDL_thread.h" #include "SDL_metal.h" @@ -44,7 +45,7 @@ struct SDL_WindowShaper SDL_Window *window; /* The user's specified coordinates for the window, for once we give it a shape. */ - Uint32 userx,usery; + Uint32 userx, usery; /* The parameters for shape calculation. */ SDL_WindowShapeMode mode; @@ -58,8 +59,8 @@ struct SDL_WindowShaper /* Define the SDL shape driver structure */ struct SDL_ShapeDriver { - SDL_WindowShaper *(*CreateShaper)(SDL_Window * window); - int (*SetWindowShape)(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shape_mode); + SDL_WindowShaper *(*CreateShaper)(SDL_Window *window); + int (*SetWindowShape)(SDL_WindowShaper *shaper, SDL_Surface *shape, SDL_WindowShapeMode *shape_mode); int (*ResizeWindowShape)(SDL_Window *window); }; @@ -83,6 +84,7 @@ struct SDL_Window int max_w, max_h; Uint32 flags; Uint32 last_fullscreen_flags; + Uint32 display_index; /* Stored position and size for windowed mode */ SDL_Rect windowed; @@ -100,7 +102,9 @@ struct SDL_Window SDL_bool is_hiding; SDL_bool is_destroying; - SDL_bool is_dropping; /* drag/drop in progress, expecting SDL_SendDropComplete(). */ + SDL_bool is_dropping; /* drag/drop in progress, expecting SDL_SendDropComplete(). */ + + SDL_Rect mouse_rect; SDL_WindowShaper *shaper; @@ -114,9 +118,9 @@ struct SDL_Window SDL_Window *prev; SDL_Window *next; }; -#define FULLSCREEN_VISIBLE(W) \ +#define FULLSCREEN_VISIBLE(W) \ (((W)->flags & SDL_WINDOW_FULLSCREEN) && \ - ((W)->flags & SDL_WINDOW_SHOWN) && \ + ((W)->flags & SDL_WINDOW_SHOWN) && \ !((W)->flags & SDL_WINDOW_MINIMIZED)) /* @@ -144,7 +148,14 @@ struct SDL_VideoDisplay struct SDL_SysWMinfo; /* Define the SDL video driver structure */ -#define _THIS SDL_VideoDevice *_this +#define _THIS SDL_VideoDevice *_this + +/* Video device flags */ +typedef enum +{ + VIDEO_DEVICE_QUIRK_DISABLE_DISPLAY_MODE_SWITCHING = 0x01, + VIDEO_DEVICE_QUIRK_DISABLE_UNSET_FULLSCREEN_ON_MINIMIZE = 0x02, +} DeviceQuirkFlags; struct SDL_VideoDevice { @@ -159,43 +170,48 @@ struct SDL_VideoDevice * Initialize the native video subsystem, filling in the list of * displays for this driver, returning 0 or -1 if there's an error. */ - int (*VideoInit) (_THIS); + int (*VideoInit)(_THIS); /* * Reverse the effects VideoInit() -- called if VideoInit() fails or * if the application is shutting down the video subsystem. */ - void (*VideoQuit) (_THIS); + void (*VideoQuit)(_THIS); /* * Reinitialize the touch devices -- called if an unknown touch ID occurs. */ - void (*ResetTouch) (_THIS); + void (*ResetTouch)(_THIS); /* * * */ /* * Display functions */ + /* + * Refresh the display list + */ + void (*RefreshDisplays)(_THIS); + /* * Get the bounds of a display */ - int (*GetDisplayBounds) (_THIS, SDL_VideoDisplay * display, SDL_Rect * rect); + int (*GetDisplayBounds)(_THIS, SDL_VideoDisplay *display, SDL_Rect *rect); /* * Get the usable bounds of a display (bounds minus menubar or whatever) */ - int (*GetDisplayUsableBounds) (_THIS, SDL_VideoDisplay * display, SDL_Rect * rect); + int (*GetDisplayUsableBounds)(_THIS, SDL_VideoDisplay *display, SDL_Rect *rect); /* * Get the dots/pixels-per-inch of a display */ - int (*GetDisplayDPI) (_THIS, SDL_VideoDisplay * display, float * ddpi, float * hdpi, float * vdpi); + int (*GetDisplayDPI)(_THIS, SDL_VideoDisplay *display, float *ddpi, float *hdpi, float *vdpi); /* * Get a list of the available display modes for a display. */ - void (*GetDisplayModes) (_THIS, SDL_VideoDisplay * display); + void (*GetDisplayModes)(_THIS, SDL_VideoDisplay *display); /* * Setting the display mode is independent of creating windows, so @@ -203,21 +219,22 @@ struct SDL_VideoDevice * their data updated accordingly, including the display surfaces * associated with them. */ - int (*SetDisplayMode) (_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode); + int (*SetDisplayMode)(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode); /* * * */ /* * Window functions */ - int (*CreateSDLWindow) (_THIS, SDL_Window * window); - int (*CreateSDLWindowFrom) (_THIS, SDL_Window * window, const void *data); - void (*SetWindowTitle) (_THIS, SDL_Window * window); - void (*SetWindowIcon) (_THIS, SDL_Window * window, SDL_Surface * icon); - void (*SetWindowPosition) (_THIS, SDL_Window * window); - void (*SetWindowSize) (_THIS, SDL_Window * window); - void (*SetWindowMinimumSize) (_THIS, SDL_Window * window); - void (*SetWindowMaximumSize) (_THIS, SDL_Window * window); - int (*GetWindowBordersSize) (_THIS, SDL_Window * window, int *top, int *left, int *bottom, int *right); + int (*CreateSDLWindow)(_THIS, SDL_Window *window); + int (*CreateSDLWindowFrom)(_THIS, SDL_Window *window, const void *data); + void (*SetWindowTitle)(_THIS, SDL_Window *window); + void (*SetWindowIcon)(_THIS, SDL_Window *window, SDL_Surface *icon); + void (*SetWindowPosition)(_THIS, SDL_Window *window); + void (*SetWindowSize)(_THIS, SDL_Window *window); + void (*SetWindowMinimumSize)(_THIS, SDL_Window *window); + void (*SetWindowMaximumSize)(_THIS, SDL_Window *window); + int (*GetWindowBordersSize)(_THIS, SDL_Window *window, int *top, int *left, int *bottom, int *right); + void (*GetWindowSizeInPixels)(_THIS, SDL_Window *window, int *w, int *h); int (*SetWindowOpacity) (_THIS, SDL_Window * window, float opacity); int (*SetWindowModalFor) (_THIS, SDL_Window * modal_window, SDL_Window * parent_window); int (*SetWindowInputFocus) (_THIS, SDL_Window * window); @@ -229,15 +246,21 @@ struct SDL_VideoDevice void (*RestoreWindow) (_THIS, SDL_Window * window); void (*SetWindowBordered) (_THIS, SDL_Window * window, SDL_bool bordered); void (*SetWindowResizable) (_THIS, SDL_Window * window, SDL_bool resizable); + void (*SetWindowAlwaysOnTop) (_THIS, SDL_Window * window, SDL_bool on_top); void (*SetWindowFullscreen) (_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen); int (*SetWindowGammaRamp) (_THIS, SDL_Window * window, const Uint16 * ramp); int (*GetWindowGammaRamp) (_THIS, SDL_Window * window, Uint16 * ramp); - void (*SetWindowGrab) (_THIS, SDL_Window * window, SDL_bool grabbed); + void* (*GetWindowICCProfile) (_THIS, SDL_Window * window, size_t* size); + int (*GetWindowDisplayIndex)(_THIS, SDL_Window * window); + void (*SetWindowMouseRect)(_THIS, SDL_Window * window); + void (*SetWindowMouseGrab) (_THIS, SDL_Window * window, SDL_bool grabbed); + void (*SetWindowKeyboardGrab) (_THIS, SDL_Window * window, SDL_bool grabbed); void (*DestroyWindow) (_THIS, SDL_Window * window); int (*CreateWindowFramebuffer) (_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch); int (*UpdateWindowFramebuffer) (_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects); void (*DestroyWindowFramebuffer) (_THIS, SDL_Window * window); void (*OnWindowEnter) (_THIS, SDL_Window * window); + int (*FlashWindow) (_THIS, SDL_Window * window, SDL_FlashOperation operation); /* * * */ /* @@ -269,57 +292,70 @@ struct SDL_VideoDevice /* * Vulkan support */ - int (*Vulkan_LoadLibrary) (_THIS, const char *path); - void (*Vulkan_UnloadLibrary) (_THIS); - SDL_bool (*Vulkan_GetInstanceExtensions) (_THIS, SDL_Window *window, unsigned *count, const char **names); - SDL_bool (*Vulkan_CreateSurface) (_THIS, SDL_Window *window, VkInstance instance, VkSurfaceKHR *surface); - void (*Vulkan_GetDrawableSize) (_THIS, SDL_Window * window, int *w, int *h); + int (*Vulkan_LoadLibrary)(_THIS, const char *path); + void (*Vulkan_UnloadLibrary)(_THIS); + SDL_bool (*Vulkan_GetInstanceExtensions)(_THIS, SDL_Window *window, unsigned *count, const char **names); + SDL_bool (*Vulkan_CreateSurface)(_THIS, SDL_Window *window, VkInstance instance, VkSurfaceKHR *surface); + void (*Vulkan_GetDrawableSize)(_THIS, SDL_Window *window, int *w, int *h); /* * * */ /* * Metal support */ - SDL_MetalView (*Metal_CreateView) (_THIS, SDL_Window * window); - void (*Metal_DestroyView) (_THIS, SDL_MetalView view); + SDL_MetalView (*Metal_CreateView)(_THIS, SDL_Window *window); + void (*Metal_DestroyView)(_THIS, SDL_MetalView view); + void *(*Metal_GetLayer)(_THIS, SDL_MetalView view); + void (*Metal_GetDrawableSize)(_THIS, SDL_Window *window, int *w, int *h); /* * * */ /* * Event manager functions */ - void (*PumpEvents) (_THIS); + int (*WaitEventTimeout)(_THIS, int timeout); + void (*SendWakeupEvent)(_THIS, SDL_Window *window); + void (*PumpEvents)(_THIS); /* Suspend the screensaver */ - void (*SuspendScreenSaver) (_THIS); + void (*SuspendScreenSaver)(_THIS); /* Text input */ - void (*StartTextInput) (_THIS); - void (*StopTextInput) (_THIS); - void (*SetTextInputRect) (_THIS, SDL_Rect *rect); + void (*StartTextInput)(_THIS); + void (*StopTextInput)(_THIS); + void (*SetTextInputRect)(_THIS, const SDL_Rect *rect); + void (*ClearComposition)(_THIS); + SDL_bool (*IsTextInputShown)(_THIS); /* Screen keyboard */ - SDL_bool (*HasScreenKeyboardSupport) (_THIS); - void (*ShowScreenKeyboard) (_THIS, SDL_Window *window); - void (*HideScreenKeyboard) (_THIS, SDL_Window *window); - SDL_bool (*IsScreenKeyboardShown) (_THIS, SDL_Window *window); + SDL_bool (*HasScreenKeyboardSupport)(_THIS); + void (*ShowScreenKeyboard)(_THIS, SDL_Window *window); + void (*HideScreenKeyboard)(_THIS, SDL_Window *window); + SDL_bool (*IsScreenKeyboardShown)(_THIS, SDL_Window *window); /* Clipboard */ - int (*SetClipboardText) (_THIS, const char *text); - char * (*GetClipboardText) (_THIS); - SDL_bool (*HasClipboardText) (_THIS); + int (*SetClipboardText)(_THIS, const char *text); + char *(*GetClipboardText)(_THIS); + SDL_bool (*HasClipboardText)(_THIS); + int (*SetPrimarySelectionText)(_THIS, const char *text); + char *(*GetPrimarySelectionText)(_THIS); + SDL_bool (*HasPrimarySelectionText)(_THIS); /* MessageBox */ - int (*ShowMessageBox) (_THIS, const SDL_MessageBoxData *messageboxdata, int *buttonid); + int (*ShowMessageBox)(_THIS, const SDL_MessageBoxData *messageboxdata, int *buttonid); /* Hit-testing */ - int (*SetWindowHitTest)(SDL_Window * window, SDL_bool enabled); + int (*SetWindowHitTest)(SDL_Window *window, SDL_bool enabled); /* Tell window that app enabled drag'n'drop events */ - void (*AcceptDragAndDrop)(SDL_Window * window, SDL_bool accept); + void (*AcceptDragAndDrop)(SDL_Window *window, SDL_bool accept); /* * * */ /* Data common to all drivers */ + SDL_threadID thread; + SDL_bool checked_texture_framebuffer; SDL_bool is_dummy; SDL_bool suspend_screensaver; + SDL_Window *wakeup_window; + SDL_mutex *wakeup_lock; /* Initialized only if WaitEventTimeout/SendWakeupEvent are supported */ int num_displays; SDL_VideoDisplay *displays; SDL_Window *windows; @@ -327,6 +363,9 @@ struct SDL_VideoDevice Uint8 window_magic; Uint32 next_object_id; char *clipboard_text; + char *primary_selection_text; + SDL_bool setting_display_mode; + Uint32 quirk_flags; /* * * */ /* Data used by the GL drivers */ @@ -347,6 +386,7 @@ struct SDL_VideoDevice int stereo; int multisamplebuffers; int multisamplesamples; + int floatbuffers; int accelerated; int major_version; int minor_version; @@ -373,6 +413,11 @@ struct SDL_VideoDevice SDL_TLSID current_glwin_tls; SDL_TLSID current_glctx_tls; + /* Flag that stores whether it's allowed to call SDL_GL_MakeCurrent() + * with a NULL window, but a non-NULL context. (Not allowed in most cases, + * except on EGL under some circumstances.) */ + SDL_bool gl_allow_no_surface; + /* * * */ /* Data used by the Vulkan drivers */ struct @@ -388,26 +433,26 @@ struct SDL_VideoDevice /* Data private to this driver */ void *driverdata; struct SDL_GLDriverData *gl_data; - -#if SDL_VIDEO_OPENGL_EGL + +#ifdef SDL_VIDEO_OPENGL_EGL struct SDL_EGL_VideoData *egl_data; #endif - -#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 + +#if defined(SDL_VIDEO_OPENGL_ES) || defined(SDL_VIDEO_OPENGL_ES2) struct SDL_PrivateGLESData *gles_data; #endif /* * * */ /* The function used to dispose of this structure */ - void (*free) (_THIS); + void (*free)(_THIS); }; typedef struct VideoBootStrap { const char *name; const char *desc; - int (*available) (void); - SDL_VideoDevice *(*create) (int devindex); + SDL_VideoDevice *(*create)(void); + int (*ShowMessageBox)(const SDL_MessageBoxData *messageboxdata, int *buttonid); /* can be done without initializing backend! */ } VideoBootStrap; /* Not all of these are available in a given build. Use #ifdefs, etc. */ @@ -420,43 +465,60 @@ extern VideoBootStrap HAIKU_bootstrap; extern VideoBootStrap PND_bootstrap; extern VideoBootStrap UIKIT_bootstrap; extern VideoBootStrap Android_bootstrap; +extern VideoBootStrap PS2_bootstrap; extern VideoBootStrap PSP_bootstrap; +extern VideoBootStrap VITA_bootstrap; +extern VideoBootStrap RISCOS_bootstrap; +extern VideoBootStrap N3DS_bootstrap; extern VideoBootStrap RPI_bootstrap; extern VideoBootStrap KMSDRM_bootstrap; +extern VideoBootStrap KMSDRM_LEGACY_bootstrap; extern VideoBootStrap DUMMY_bootstrap; +extern VideoBootStrap DUMMY_evdev_bootstrap; extern VideoBootStrap Wayland_bootstrap; extern VideoBootStrap NACL_bootstrap; extern VideoBootStrap VIVANTE_bootstrap; extern VideoBootStrap Emscripten_bootstrap; extern VideoBootStrap QNX_bootstrap; extern VideoBootStrap OFFSCREEN_bootstrap; +extern VideoBootStrap NGAGE_bootstrap; +extern VideoBootStrap OS2DIVE_bootstrap; +extern VideoBootStrap OS2VMAN_bootstrap; +/* Use SDL_OnVideoThread() sparingly, to avoid regressions in use cases that currently happen to work */ +extern SDL_bool SDL_OnVideoThread(void); extern SDL_VideoDevice *SDL_GetVideoDevice(void); -extern int SDL_AddBasicVideoDisplay(const SDL_DisplayMode * desktop_mode); -extern int SDL_AddVideoDisplay(const SDL_VideoDisplay * display); -extern SDL_bool SDL_AddDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode * mode); +extern int SDL_AddBasicVideoDisplay(const SDL_DisplayMode *desktop_mode); +extern int SDL_AddVideoDisplay(const SDL_VideoDisplay *display, SDL_bool send_event); +extern void SDL_DelVideoDisplay(int index); +extern SDL_bool SDL_AddDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode); +extern void SDL_SetCurrentDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode); +extern void SDL_SetDesktopDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode); +extern void SDL_ResetDisplayModes(int displayIndex); extern int SDL_GetIndexOfDisplay(SDL_VideoDisplay *display); extern SDL_VideoDisplay *SDL_GetDisplay(int displayIndex); extern SDL_VideoDisplay *SDL_GetDisplayForWindow(SDL_Window *window); -extern void *SDL_GetDisplayDriverData( int displayIndex ); +extern void *SDL_GetDisplayDriverData(int displayIndex); extern SDL_bool SDL_IsVideoContextExternal(void); +extern int SDL_GetMessageBoxCount(void); -extern void SDL_GL_DeduceMaxSupportedESProfile(int* major, int* minor); +extern void SDL_GL_DeduceMaxSupportedESProfile(int *major, int *minor); -extern int SDL_RecreateWindow(SDL_Window * window, Uint32 flags); +extern int SDL_RecreateWindow(SDL_Window *window, Uint32 flags); extern SDL_bool SDL_HasWindows(void); -extern void SDL_OnWindowShown(SDL_Window * window); -extern void SDL_OnWindowHidden(SDL_Window * window); -extern void SDL_OnWindowResized(SDL_Window * window); -extern void SDL_OnWindowMinimized(SDL_Window * window); -extern void SDL_OnWindowRestored(SDL_Window * window); -extern void SDL_OnWindowEnter(SDL_Window * window); -extern void SDL_OnWindowLeave(SDL_Window * window); -extern void SDL_OnWindowFocusGained(SDL_Window * window); -extern void SDL_OnWindowFocusLost(SDL_Window * window); -extern void SDL_UpdateWindowGrab(SDL_Window * window); -extern SDL_Window * SDL_GetFocusWindow(void); +extern void SDL_OnWindowShown(SDL_Window *window); +extern void SDL_OnWindowHidden(SDL_Window *window); +extern void SDL_OnWindowMoved(SDL_Window *window); +extern void SDL_OnWindowResized(SDL_Window *window); +extern void SDL_OnWindowMinimized(SDL_Window *window); +extern void SDL_OnWindowRestored(SDL_Window *window); +extern void SDL_OnWindowEnter(SDL_Window *window); +extern void SDL_OnWindowLeave(SDL_Window *window); +extern void SDL_OnWindowFocusGained(SDL_Window *window); +extern void SDL_OnWindowFocusLost(SDL_Window *window); +extern void SDL_UpdateWindowGrab(SDL_Window *window); +extern SDL_Window *SDL_GetFocusWindow(void); extern SDL_bool SDL_ShouldAllowTopmost(void); @@ -464,6 +526,14 @@ extern float SDL_ComputeDiagonalDPI(int hpix, int vpix, float hinches, float vin extern void SDL_ToggleDragAndDropSupport(void); +extern int SDL_GetPointDisplayIndex(const SDL_Point *point); + +extern int SDL_GL_SwapWindowWithResult(SDL_Window *window); + +#if defined(SDL_VIDEO_DRIVER_X11) || defined(SDL_VIDEO_DRIVER_WAYLAND) || defined(SDL_VIDEO_DRIVER_EMSCRIPTEN) +const char *SDL_GetCSSCursorName(SDL_SystemCursor id, const char **fallback_name); +#endif + #endif /* SDL_sysvideo_h_ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/SDL_video.c b/SDL2-2.30.5/src/video/SDL_video.c similarity index 57% rename from SDL2-2.0.12/src/video/SDL_video.c rename to SDL2-2.30.5/src/video/SDL_video.c index de0bc1c..c1a2dbd 100644 --- a/SDL2-2.0.12/src/video/SDL_video.c +++ b/SDL2-2.30.5/src/video/SDL_video.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -18,6 +18,7 @@ misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ + #include "../SDL_internal.h" /* The high-level video driver subsystem */ @@ -33,20 +34,20 @@ #include "SDL_syswm.h" -#if SDL_VIDEO_OPENGL +#ifdef SDL_VIDEO_OPENGL #include "SDL_opengl.h" #endif /* SDL_VIDEO_OPENGL */ -#if SDL_VIDEO_OPENGL_ES && !SDL_VIDEO_OPENGL +#if defined(SDL_VIDEO_OPENGL_ES) && !defined(SDL_VIDEO_OPENGL) #include "SDL_opengles.h" #endif /* SDL_VIDEO_OPENGL_ES && !SDL_VIDEO_OPENGL */ /* GL and GLES2 headers conflict on Linux 32 bits */ -#if SDL_VIDEO_OPENGL_ES2 && !SDL_VIDEO_OPENGL +#if defined(SDL_VIDEO_OPENGL_ES2) && !defined(SDL_VIDEO_OPENGL) #include "SDL_opengles2.h" #endif /* SDL_VIDEO_OPENGL_ES2 && !SDL_VIDEO_OPENGL */ -#if !SDL_VIDEO_OPENGL +#ifndef SDL_VIDEO_OPENGL #ifndef GL_CONTEXT_RELEASE_BEHAVIOR_KHR #define GL_CONTEXT_RELEASE_BEHAVIOR_KHR 0x82FB #endif @@ -56,108 +57,143 @@ #include #endif +#ifdef __LINUX__ +#include +#include +#include +#include +#endif + /* Available video drivers */ static VideoBootStrap *bootstrap[] = { -#if SDL_VIDEO_DRIVER_COCOA +#ifdef SDL_VIDEO_DRIVER_COCOA &COCOA_bootstrap, #endif -#if SDL_VIDEO_DRIVER_X11 +#ifdef SDL_VIDEO_DRIVER_X11 &X11_bootstrap, #endif -#if SDL_VIDEO_DRIVER_WAYLAND +#ifdef SDL_VIDEO_DRIVER_WAYLAND &Wayland_bootstrap, #endif -#if SDL_VIDEO_DRIVER_VIVANTE +#ifdef SDL_VIDEO_DRIVER_VIVANTE &VIVANTE_bootstrap, #endif -#if SDL_VIDEO_DRIVER_DIRECTFB +#ifdef SDL_VIDEO_DRIVER_DIRECTFB &DirectFB_bootstrap, #endif -#if SDL_VIDEO_DRIVER_WINDOWS +#ifdef SDL_VIDEO_DRIVER_WINDOWS &WINDOWS_bootstrap, #endif -#if SDL_VIDEO_DRIVER_WINRT +#ifdef SDL_VIDEO_DRIVER_WINRT &WINRT_bootstrap, #endif -#if SDL_VIDEO_DRIVER_HAIKU +#ifdef SDL_VIDEO_DRIVER_HAIKU &HAIKU_bootstrap, #endif -#if SDL_VIDEO_DRIVER_PANDORA +#ifdef SDL_VIDEO_DRIVER_PANDORA &PND_bootstrap, #endif -#if SDL_VIDEO_DRIVER_UIKIT +#ifdef SDL_VIDEO_DRIVER_UIKIT &UIKIT_bootstrap, #endif -#if SDL_VIDEO_DRIVER_ANDROID +#ifdef SDL_VIDEO_DRIVER_ANDROID &Android_bootstrap, #endif -#if SDL_VIDEO_DRIVER_PSP +#ifdef SDL_VIDEO_DRIVER_PS2 + &PS2_bootstrap, +#endif +#ifdef SDL_VIDEO_DRIVER_PSP &PSP_bootstrap, #endif -#if SDL_VIDEO_DRIVER_KMSDRM +#ifdef SDL_VIDEO_DRIVER_VITA + &VITA_bootstrap, +#endif +#ifdef SDL_VIDEO_DRIVER_N3DS + &N3DS_bootstrap, +#endif +#ifdef SDL_VIDEO_DRIVER_KMSDRM &KMSDRM_bootstrap, #endif -#if SDL_VIDEO_DRIVER_RPI +#ifdef SDL_VIDEO_DRIVER_RISCOS + &RISCOS_bootstrap, +#endif +#ifdef SDL_VIDEO_DRIVER_RPI &RPI_bootstrap, #endif -#if SDL_VIDEO_DRIVER_NACL +#ifdef SDL_VIDEO_DRIVER_NACL &NACL_bootstrap, #endif -#if SDL_VIDEO_DRIVER_EMSCRIPTEN +#ifdef SDL_VIDEO_DRIVER_EMSCRIPTEN &Emscripten_bootstrap, #endif -#if SDL_VIDEO_DRIVER_QNX +#ifdef SDL_VIDEO_DRIVER_QNX &QNX_bootstrap, #endif -#if SDL_VIDEO_DRIVER_OFFSCREEN +#ifdef SDL_VIDEO_DRIVER_OS2 + &OS2DIVE_bootstrap, + &OS2VMAN_bootstrap, +#endif +#ifdef SDL_VIDEO_DRIVER_NGAGE + &NGAGE_bootstrap, +#endif +#ifdef SDL_VIDEO_DRIVER_OFFSCREEN &OFFSCREEN_bootstrap, #endif -#if SDL_VIDEO_DRIVER_DUMMY +#ifdef SDL_VIDEO_DRIVER_DUMMY &DUMMY_bootstrap, +#ifdef SDL_INPUT_LINUXEV + &DUMMY_evdev_bootstrap, +#endif #endif NULL }; -static SDL_VideoDevice *_this = NULL; - -#define CHECK_WINDOW_MAGIC(window, retval) \ - if (!_this) { \ - SDL_UninitializedVideo(); \ - return retval; \ - } \ - SDL_assert(window && window->magic == &_this->window_magic); \ +#define CHECK_WINDOW_MAGIC(window, retval) \ + if (!_this) { \ + SDL_UninitializedVideo(); \ + return retval; \ + } \ if (!window || window->magic != &_this->window_magic) { \ - SDL_SetError("Invalid window"); \ - return retval; \ + SDL_SetError("Invalid window"); \ + return retval; \ } -#define CHECK_DISPLAY_INDEX(displayIndex, retval) \ - if (!_this) { \ - SDL_UninitializedVideo(); \ - return retval; \ - } \ - SDL_assert(_this->displays != NULL); \ - SDL_assert(displayIndex >= 0 && displayIndex < _this->num_displays); \ +#define CHECK_DISPLAY_INDEX(displayIndex, retval) \ + if (!_this) { \ + SDL_UninitializedVideo(); \ + return retval; \ + } \ if (displayIndex < 0 || displayIndex >= _this->num_displays) { \ - SDL_SetError("displayIndex must be in the range 0 - %d", \ - _this->num_displays - 1); \ - return retval; \ + SDL_SetError("displayIndex must be in the range 0 - %d", \ + _this->num_displays - 1); \ + return retval; \ } #define FULLSCREEN_MASK (SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_FULLSCREEN) -#ifdef __MACOSX__ +#if defined(__MACOSX__) && defined(SDL_VIDEO_DRIVER_COCOA) /* Support for Mac OS X fullscreen spaces */ extern SDL_bool Cocoa_IsWindowInFullscreenSpace(SDL_Window * window); extern SDL_bool Cocoa_SetWindowFullscreenSpace(SDL_Window * window, SDL_bool state); #endif +/* Convenience functions for reading driver flags */ +static SDL_bool DisableDisplayModeSwitching(_THIS) +{ + return !!(_this->quirk_flags & VIDEO_DEVICE_QUIRK_DISABLE_DISPLAY_MODE_SWITCHING); +} + +static SDL_bool DisableUnsetFullscreenOnMinimize(_THIS) +{ + return !!(_this->quirk_flags & VIDEO_DEVICE_QUIRK_DISABLE_UNSET_FULLSCREEN_ON_MINIMIZE); +} /* Support for framebuffer emulation using an accelerated renderer */ -#define SDL_WINDOWTEXTUREDATA "_SDL_WindowTextureData" +#define SDL_WINDOWTEXTUREDATA "_SDL_WindowTextureData" -typedef struct { +typedef struct +{ SDL_Renderer *renderer; SDL_Texture *texture; void *pixels; @@ -165,137 +201,85 @@ typedef struct { int bytes_per_pixel; } SDL_WindowTextureData; -static SDL_bool -ShouldUseTextureFramebuffer() +static Uint32 SDL_DefaultGraphicsBackends(SDL_VideoDevice *_this) { - const char *hint; - - /* If there's no native framebuffer support then there's no option */ - if (!_this->CreateWindowFramebuffer) { - return SDL_TRUE; +#if (defined(SDL_VIDEO_OPENGL) && defined(__MACOSX__)) || (defined(__IPHONEOS__) && !TARGET_OS_MACCATALYST) || defined(__ANDROID__) || defined(__NACL__) + if (_this->GL_CreateContext) { + return SDL_WINDOW_OPENGL; } - - /* If this is the dummy driver there is no texture support */ - if (_this->is_dummy) { - return SDL_FALSE; - } - - /* If the user has specified a software renderer we can't use a - texture framebuffer, or renderer creation will go recursive. - */ - hint = SDL_GetHint(SDL_HINT_RENDER_DRIVER); - if (hint && SDL_strcasecmp(hint, "software") == 0) { - return SDL_FALSE; - } - - /* See if the user or application wants a specific behavior */ - hint = SDL_GetHint(SDL_HINT_FRAMEBUFFER_ACCELERATION); - if (hint) { - if (*hint == '0' || SDL_strcasecmp(hint, "false") == 0) { - return SDL_FALSE; - } else { - return SDL_TRUE; - } - } - - /* Each platform has different performance characteristics */ -#if defined(__WIN32__) - /* GDI BitBlt() is way faster than Direct3D dynamic textures right now. - */ - return SDL_FALSE; - -#elif defined(__MACOSX__) - /* Mac OS X uses OpenGL as the native fast path (for cocoa and X11) */ - return SDL_TRUE; - -#elif defined(__LINUX__) - /* Properly configured OpenGL drivers are faster than MIT-SHM */ -#if SDL_VIDEO_OPENGL - /* Ugh, find a way to cache this value! */ - { - SDL_Window *window; - SDL_GLContext context; - SDL_bool hasAcceleratedOpenGL = SDL_FALSE; - - window = SDL_CreateWindow("OpenGL test", -32, -32, 32, 32, SDL_WINDOW_OPENGL|SDL_WINDOW_HIDDEN); - if (window) { - context = SDL_GL_CreateContext(window); - if (context) { - const GLubyte *(APIENTRY * glGetStringFunc) (GLenum); - const char *vendor = NULL; - - glGetStringFunc = SDL_GL_GetProcAddress("glGetString"); - if (glGetStringFunc) { - vendor = (const char *) glGetStringFunc(GL_VENDOR); - } - /* Add more vendors here at will... */ - if (vendor && - (SDL_strstr(vendor, "ATI Technologies") || - SDL_strstr(vendor, "NVIDIA"))) { - hasAcceleratedOpenGL = SDL_TRUE; - } - SDL_GL_DeleteContext(context); - } - SDL_DestroyWindow(window); - } - return hasAcceleratedOpenGL; - } -#elif SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 - /* Let's be optimistic about this! */ - return SDL_TRUE; -#else - return SDL_FALSE; #endif - -#else - /* Play it safe, assume that if there is a framebuffer driver that it's - optimized for the current platform. - */ - return SDL_FALSE; +#if defined(SDL_VIDEO_METAL) && (TARGET_OS_MACCATALYST || defined(__MACOSX__) || defined(__IPHONEOS__)) + if (_this->Metal_CreateView) { + return SDL_WINDOW_METAL; + } #endif + return 0; } -static int -SDL_CreateWindowTexture(SDL_VideoDevice *unused, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch) +static int SDL_CreateWindowTexture(SDL_VideoDevice *_this, SDL_Window *window, Uint32 *format, void **pixels, int *pitch) { - SDL_WindowTextureData *data; + SDL_RendererInfo info; + SDL_WindowTextureData *data = SDL_GetWindowData(window, SDL_WINDOWTEXTUREDATA); + int i; + int w, h; + + SDL_GetWindowSizeInPixels(window, &w, &h); - data = SDL_GetWindowData(window, SDL_WINDOWTEXTUREDATA); if (!data) { SDL_Renderer *renderer = NULL; - int i; - const char *hint = SDL_GetHint(SDL_HINT_FRAMEBUFFER_ACCELERATION); + const char *render_driver = NULL; + const char *hint; - /* Check to see if there's a specific driver requested */ + /* See if there's a render driver being requested */ + hint = SDL_GetHint(SDL_HINT_FRAMEBUFFER_ACCELERATION); if (hint && *hint != '0' && *hint != '1' && SDL_strcasecmp(hint, "true") != 0 && SDL_strcasecmp(hint, "false") != 0 && SDL_strcasecmp(hint, "software") != 0) { + render_driver = hint; + } + + if (!render_driver) { + hint = SDL_GetHint(SDL_HINT_RENDER_DRIVER); + if (hint && *hint && SDL_strcasecmp(hint, "software") != 0) { + render_driver = hint; + } + } + + /* Check to see if there's a specific driver requested */ + if (render_driver) { for (i = 0; i < SDL_GetNumRenderDrivers(); ++i) { - SDL_RendererInfo info; SDL_GetRenderDriverInfo(i, &info); - if (SDL_strcasecmp(info.name, hint) == 0) { + if (SDL_strcasecmp(info.name, render_driver) == 0) { renderer = SDL_CreateRenderer(window, i, 0); break; } } - } - - if (!renderer) { + if (!renderer) { + /* The error for this specific renderer has already been set */ + return -1; + } + /* if it was specifically requested, even if SDL_RENDERER_ACCELERATED isn't set, we'll accept this renderer. */ + } else { for (i = 0; i < SDL_GetNumRenderDrivers(); ++i) { - SDL_RendererInfo info; SDL_GetRenderDriverInfo(i, &info); if (SDL_strcmp(info.name, "software") != 0) { renderer = SDL_CreateRenderer(window, i, 0); - if (renderer) { - break; + if (renderer && (SDL_GetRendererInfo(renderer, &info) == 0) && (info.flags & SDL_RENDERER_ACCELERATED)) { + break; /* this will work. */ + } + if (renderer) { /* wasn't accelerated, etc, skip it. */ + SDL_DestroyRenderer(renderer); + renderer = NULL; } } } + if (!renderer) { + return SDL_SetError("No hardware accelerated renderers available"); + } } - if (!renderer) { - return SDL_SetError("No hardware accelerated renderers available"); - } + + SDL_assert(renderer != NULL); /* should have explicitly checked this above. */ /* Create the data after we successfully create the renderer (bug #1116) */ data = (SDL_WindowTextureData *)SDL_calloc(1, sizeof(*data)); @@ -306,6 +290,10 @@ SDL_CreateWindowTexture(SDL_VideoDevice *unused, SDL_Window * window, Uint32 * f SDL_SetWindowData(window, SDL_WINDOWTEXTUREDATA, data); data->renderer = renderer; + } else { + if (SDL_GetRendererInfo(data->renderer, &info) == -1) { + return -1; + } } /* Free any old texture and pixel data */ @@ -316,40 +304,32 @@ SDL_CreateWindowTexture(SDL_VideoDevice *unused, SDL_Window * window, Uint32 * f SDL_free(data->pixels); data->pixels = NULL; - { - SDL_RendererInfo info; - Uint32 i; + /* Find the first format without an alpha channel */ + *format = info.texture_formats[0]; - if (SDL_GetRendererInfo(data->renderer, &info) < 0) { - return -1; - } - - /* Find the first format without an alpha channel */ - *format = info.texture_formats[0]; - - for (i = 0; i < info.num_texture_formats; ++i) { - if (!SDL_ISPIXELFORMAT_FOURCC(info.texture_formats[i]) && - !SDL_ISPIXELFORMAT_ALPHA(info.texture_formats[i])) { - *format = info.texture_formats[i]; - break; - } + for (i = 0; i < (int)info.num_texture_formats; ++i) { + if (!SDL_ISPIXELFORMAT_FOURCC(info.texture_formats[i]) && + !SDL_ISPIXELFORMAT_ALPHA(info.texture_formats[i])) { + *format = info.texture_formats[i]; + break; } } data->texture = SDL_CreateTexture(data->renderer, *format, SDL_TEXTUREACCESS_STREAMING, - window->w, window->h); + w, h); if (!data->texture) { - return -1; + /* codechecker_false_positive [Malloc] Static analyzer doesn't realize allocated `data` is saved to SDL_WINDOWTEXTUREDATA and not leaked here. */ + return -1; /* NOLINT(clang-analyzer-unix.Malloc) */ } /* Create framebuffer data */ data->bytes_per_pixel = SDL_BYTESPERPIXEL(*format); - data->pitch = (((window->w * data->bytes_per_pixel) + 3) & ~3); + data->pitch = (((w * data->bytes_per_pixel) + 3) & ~3); { - /* Make static analysis happy about potential malloc(0) calls. */ - const size_t allocsize = window->h * data->pitch; + /* Make static analysis happy about potential SDL_malloc(0) calls. */ + const size_t allocsize = (size_t)h * data->pitch; data->pixels = SDL_malloc((allocsize > 0) ? allocsize : 1); if (!data->pixels) { return SDL_OutOfMemory(); @@ -365,12 +345,17 @@ SDL_CreateWindowTexture(SDL_VideoDevice *unused, SDL_Window * window, Uint32 * f return 0; } -static int -SDL_UpdateWindowTexture(SDL_VideoDevice *unused, SDL_Window * window, const SDL_Rect * rects, int numrects) +static SDL_VideoDevice *_this = NULL; +static SDL_atomic_t SDL_messagebox_count; + +static int SDL_UpdateWindowTexture(SDL_VideoDevice *unused, SDL_Window *window, const SDL_Rect *rects, int numrects) { SDL_WindowTextureData *data; SDL_Rect rect; void *src; + int w, h; + + SDL_GetWindowSizeInPixels(window, &w, &h); data = SDL_GetWindowData(window, SDL_WINDOWTEXTUREDATA); if (!data || !data->texture) { @@ -378,10 +363,10 @@ SDL_UpdateWindowTexture(SDL_VideoDevice *unused, SDL_Window * window, const SDL_ } /* Update a single rect that contains subrects for best DMA performance */ - if (SDL_GetSpanEnclosingRect(window->w, window->h, numrects, rects, &rect)) { + if (SDL_GetSpanEnclosingRect(w, h, numrects, rects, &rect)) { src = (void *)((Uint8 *)data->pixels + - rect.y * data->pitch + - rect.x * data->bytes_per_pixel); + rect.y * data->pitch + + rect.x * data->bytes_per_pixel); if (SDL_UpdateTexture(data->texture, &rect, src, data->pitch) < 0) { return -1; } @@ -395,8 +380,7 @@ SDL_UpdateWindowTexture(SDL_VideoDevice *unused, SDL_Window * window, const SDL_ return 0; } -static void -SDL_DestroyWindowTexture(SDL_VideoDevice *unused, SDL_Window * window) +static void SDL_DestroyWindowTexture(SDL_VideoDevice *unused, SDL_Window *window) { SDL_WindowTextureData *data; @@ -414,12 +398,10 @@ SDL_DestroyWindowTexture(SDL_VideoDevice *unused, SDL_Window * window) SDL_free(data); } - -static int -cmpmodes(const void *A, const void *B) +static int SDLCALL cmpmodes(const void *A, const void *B) { - const SDL_DisplayMode *a = (const SDL_DisplayMode *) A; - const SDL_DisplayMode *b = (const SDL_DisplayMode *) B; + const SDL_DisplayMode *a = (const SDL_DisplayMode *)A; + const SDL_DisplayMode *b = (const SDL_DisplayMode *)B; if (a == b) { return 0; } else if (a->w != b->w) { @@ -436,20 +418,17 @@ cmpmodes(const void *A, const void *B) return 0; } -static int -SDL_UninitializedVideo() +static int SDL_UninitializedVideo(void) { return SDL_SetError("Video subsystem has not been initialized"); } -int -SDL_GetNumVideoDrivers(void) +int SDL_GetNumVideoDrivers(void) { return SDL_arraysize(bootstrap) - 1; } -const char * -SDL_GetVideoDriver(int index) +const char *SDL_GetVideoDriver(int index) { if (index >= 0 && index < SDL_GetNumVideoDrivers()) { return bootstrap[index]->name; @@ -460,65 +439,109 @@ SDL_GetVideoDriver(int index) /* * Initialize the video and event subsystems -- determine native pixel format */ -int -SDL_VideoInit(const char *driver_name) +int SDL_VideoInit(const char *driver_name) { SDL_VideoDevice *video; - int index; - int i; + SDL_bool init_events = SDL_FALSE; + SDL_bool init_keyboard = SDL_FALSE; + SDL_bool init_mouse = SDL_FALSE; + SDL_bool init_touch = SDL_FALSE; + int i = 0; /* Check to make sure we don't overwrite '_this' */ - if (_this != NULL) { + if (_this) { SDL_VideoQuit(); } -#if !SDL_TIMERS_DISABLED +#ifndef SDL_TIMERS_DISABLED SDL_TicksInit(); #endif /* Start the event loop */ - if (SDL_InitSubSystem(SDL_INIT_EVENTS) < 0 || - SDL_KeyboardInit() < 0 || - SDL_MouseInit() < 0 || - SDL_TouchInit() < 0) { - return -1; + if (SDL_InitSubSystem(SDL_INIT_EVENTS) < 0) { + goto pre_driver_error; } + init_events = SDL_TRUE; + if (SDL_KeyboardInit() < 0) { + goto pre_driver_error; + } + init_keyboard = SDL_TRUE; + if (SDL_MousePreInit() < 0) { + goto pre_driver_error; + } + init_mouse = SDL_TRUE; + if (SDL_TouchInit() < 0) { + goto pre_driver_error; + } + init_touch = SDL_TRUE; /* Select the proper video driver */ - index = 0; video = NULL; - if (driver_name == NULL) { - driver_name = SDL_getenv("SDL_VIDEODRIVER"); + if (!driver_name) { + driver_name = SDL_GetHint(SDL_HINT_VIDEODRIVER); } - if (driver_name != NULL) { - for (i = 0; bootstrap[i]; ++i) { - if (SDL_strncasecmp(bootstrap[i]->name, driver_name, SDL_strlen(driver_name)) == 0) { - if (bootstrap[i]->available()) { - video = bootstrap[i]->create(index); +#if defined(__LINUX__) && defined(SDL_VIDEO_DRIVER_X11) + if (!driver_name) { + /* See if it looks like we need X11 */ + SDL_bool force_x11 = SDL_FALSE; + void *global_symbols = dlopen(NULL, RTLD_LOCAL|RTLD_NOW); + + /* Use linked libraries to detect what quirks we are likely to need */ + if (global_symbols != NULL) { + if (dlsym(global_symbols, "glxewInit") != NULL) { /* GLEW (e.g. Frogatto, SLUDGE) */ + force_x11 = SDL_TRUE; + } else if (dlsym(global_symbols, "cgGLEnableProgramProfiles") != NULL) { /* NVIDIA Cg (e.g. Awesomenauts, Braid) */ + force_x11 = SDL_TRUE; + } else if (dlsym(global_symbols, "_Z7ssgInitv") != NULL) { /* ::ssgInit(void) in plib (e.g. crrcsim) */ + force_x11 = SDL_TRUE; + } + dlclose(global_symbols); + } + if (force_x11) { + driver_name = "x11"; + } + } +#endif + if (driver_name && *driver_name != 0) { + const char *driver_attempt = driver_name; + while (driver_attempt && *driver_attempt != 0 && !video) { + const char *driver_attempt_end = SDL_strchr(driver_attempt, ','); + size_t driver_attempt_len = (driver_attempt_end) ? (driver_attempt_end - driver_attempt) + : SDL_strlen(driver_attempt); + + for (i = 0; bootstrap[i]; ++i) { + if ((driver_attempt_len == SDL_strlen(bootstrap[i]->name)) && + (SDL_strncasecmp(bootstrap[i]->name, driver_attempt, driver_attempt_len) == 0)) { + video = bootstrap[i]->create(); break; } } + + driver_attempt = (driver_attempt_end) ? (driver_attempt_end + 1) : NULL; } } else { for (i = 0; bootstrap[i]; ++i) { - if (bootstrap[i]->available()) { - video = bootstrap[i]->create(index); - if (video != NULL) { - break; - } + video = bootstrap[i]->create(); + if (video) { + break; } } } - if (video == NULL) { + if (!video) { if (driver_name) { - return SDL_SetError("%s not available", driver_name); + SDL_SetError("%s not available", driver_name); + goto pre_driver_error; } - return SDL_SetError("No available video device"); + SDL_SetError("No available video device"); + goto pre_driver_error; } + + /* From this point on, use SDL_VideoQuit to cleanup on error, rather than + pre_driver_error. */ _this = video; _this->name = bootstrap[i]->name; _this->next_object_id = 1; - + _this->thread = SDL_ThreadID(); /* Set some very sane GL defaults */ _this->gl_config.driver_loaded = 0; @@ -540,13 +563,6 @@ SDL_VideoInit(const char *driver_name) return SDL_SetError("The video driver did not add any displays"); } - /* Add the renderer framebuffer emulation if desired */ - if (ShouldUseTextureFramebuffer()) { - _this->CreateWindowFramebuffer = SDL_CreateWindowTexture; - _this->UpdateWindowFramebuffer = SDL_UpdateWindowTexture; - _this->DestroyWindowFramebuffer = SDL_DestroyWindowTexture; - } - /* Disable the screen saver by default. This is a change from <= 2.0.1, but most things using SDL are games or media players; you wouldn't want a screensaver to trigger if you're playing exclusively with a @@ -557,23 +573,45 @@ SDL_VideoInit(const char *driver_name) SDL_DisableScreenSaver(); } - /* If we don't use a screen keyboard, turn on text input by default, - otherwise programs that expect to get text events without enabling - UNICODE input won't get any events. - - Actually, come to think of it, you needed to call SDL_EnableUNICODE(1) - in SDL 1.2 before you got text input events. Hmm... +#if !defined(SDL_VIDEO_DRIVER_N3DS) + /* In the initial state we don't want to pop up an on-screen keyboard, + * but we do want to allow text input from other mechanisms. */ - if (!SDL_HasScreenKeyboardSupport()) { + { + const char *hint = SDL_GetHint(SDL_HINT_ENABLE_SCREEN_KEYBOARD); + if (!hint) { + SDL_SetHint(SDL_HINT_ENABLE_SCREEN_KEYBOARD, "0"); + } SDL_StartTextInput(); + if (!hint) { + SDL_SetHint(SDL_HINT_ENABLE_SCREEN_KEYBOARD, NULL); + } } +#endif /* !SDL_VIDEO_DRIVER_N3DS */ + + SDL_MousePostInit(); /* We're ready to go! */ return 0; + +pre_driver_error: + SDL_assert(_this == NULL); + if (init_touch) { + SDL_TouchQuit(); + } + if (init_mouse) { + SDL_MouseQuit(); + } + if (init_keyboard) { + SDL_KeyboardQuit(); + } + if (init_events) { + SDL_QuitSubSystem(SDL_INIT_EVENTS); + } + return -1; } -const char * -SDL_GetCurrentVideoDriver() +const char *SDL_GetCurrentVideoDriver(void) { if (!_this) { SDL_UninitializedVideo(); @@ -582,14 +620,17 @@ SDL_GetCurrentVideoDriver() return _this->name; } -SDL_VideoDevice * -SDL_GetVideoDevice(void) +SDL_VideoDevice *SDL_GetVideoDevice(void) { return _this; } -int -SDL_AddBasicVideoDisplay(const SDL_DisplayMode * desktop_mode) +SDL_bool SDL_OnVideoThread(void) +{ + return (_this && SDL_ThreadID() == _this->thread) ? SDL_TRUE : SDL_FALSE; +} + +int SDL_AddBasicVideoDisplay(const SDL_DisplayMode *desktop_mode) { SDL_VideoDisplay display; @@ -599,11 +640,10 @@ SDL_AddBasicVideoDisplay(const SDL_DisplayMode * desktop_mode) } display.current_mode = display.desktop_mode; - return SDL_AddVideoDisplay(&display); + return SDL_AddVideoDisplay(&display, SDL_FALSE); } -int -SDL_AddVideoDisplay(const SDL_VideoDisplay * display) +int SDL_AddVideoDisplay(const SDL_VideoDisplay *display, SDL_bool send_event) { SDL_VideoDisplay *displays; int index = -1; @@ -625,14 +665,33 @@ SDL_AddVideoDisplay(const SDL_VideoDisplay * display) SDL_itoa(index, name, 10); displays[index].name = SDL_strdup(name); } + + if (send_event) { + SDL_SendDisplayEvent(&_this->displays[index], SDL_DISPLAYEVENT_CONNECTED, 0); + } } else { SDL_OutOfMemory(); } return index; } -int -SDL_GetNumVideoDisplays(void) +void SDL_DelVideoDisplay(int index) +{ + if (index < 0 || index >= _this->num_displays) { + return; + } + + SDL_SendDisplayEvent(&_this->displays[index], SDL_DISPLAYEVENT_DISCONNECTED, 0); + + SDL_free(_this->displays[index].driverdata); + SDL_free(_this->displays[index].name); + if (index < (_this->num_displays - 1)) { + SDL_memmove(&_this->displays[index], &_this->displays[index + 1], (_this->num_displays - index - 1) * sizeof(_this->displays[index])); + } + --_this->num_displays; +} + +int SDL_GetNumVideoDisplays(void) { if (!_this) { SDL_UninitializedVideo(); @@ -641,8 +700,7 @@ SDL_GetNumVideoDisplays(void) return _this->num_displays; } -int -SDL_GetIndexOfDisplay(SDL_VideoDisplay *display) +int SDL_GetIndexOfDisplay(SDL_VideoDisplay *display) { int displayIndex; @@ -656,89 +714,89 @@ SDL_GetIndexOfDisplay(SDL_VideoDisplay *display) return 0; } -void * -SDL_GetDisplayDriverData(int displayIndex) +void *SDL_GetDisplayDriverData(int displayIndex) { CHECK_DISPLAY_INDEX(displayIndex, NULL); return _this->displays[displayIndex].driverdata; } -SDL_bool -SDL_IsVideoContextExternal(void) +SDL_bool SDL_IsVideoContextExternal(void) { return SDL_GetHintBoolean(SDL_HINT_VIDEO_EXTERNAL_CONTEXT, SDL_FALSE); } -const char * -SDL_GetDisplayName(int displayIndex) +const char *SDL_GetDisplayName(int displayIndex) { CHECK_DISPLAY_INDEX(displayIndex, NULL); return _this->displays[displayIndex].name; } -int -SDL_GetDisplayBounds(int displayIndex, SDL_Rect * rect) +int SDL_GetDisplayBounds(int displayIndex, SDL_Rect *rect) { + SDL_VideoDisplay *display; + CHECK_DISPLAY_INDEX(displayIndex, -1); - if (rect) { - SDL_VideoDisplay *display = &_this->displays[displayIndex]; - - if (_this->GetDisplayBounds) { - if (_this->GetDisplayBounds(_this, display, rect) == 0) { - return 0; - } - } - - /* Assume that the displays are left to right */ - if (displayIndex == 0) { - rect->x = 0; - rect->y = 0; - } else { - SDL_GetDisplayBounds(displayIndex-1, rect); - rect->x += rect->w; - } - rect->w = display->current_mode.w; - rect->h = display->current_mode.h; + if (!rect) { + return SDL_InvalidParamError("rect"); } - return 0; /* !!! FIXME: should this be an error if (rect==NULL) ? */ + + display = &_this->displays[displayIndex]; + + if (_this->GetDisplayBounds) { + if (_this->GetDisplayBounds(_this, display, rect) == 0) { + return 0; + } + } + + /* Assume that the displays are left to right */ + if (displayIndex == 0) { + rect->x = 0; + rect->y = 0; + } else { + SDL_GetDisplayBounds(displayIndex - 1, rect); + rect->x += rect->w; + } + rect->w = display->current_mode.w; + rect->h = display->current_mode.h; + return 0; } -static int -ParseDisplayUsableBoundsHint(SDL_Rect *rect) +static int ParseDisplayUsableBoundsHint(SDL_Rect *rect) { const char *hint = SDL_GetHint(SDL_HINT_DISPLAY_USABLE_BOUNDS); return hint && (SDL_sscanf(hint, "%d,%d,%d,%d", &rect->x, &rect->y, &rect->w, &rect->h) == 4); } -int -SDL_GetDisplayUsableBounds(int displayIndex, SDL_Rect * rect) +int SDL_GetDisplayUsableBounds(int displayIndex, SDL_Rect *rect) { + SDL_VideoDisplay *display; + CHECK_DISPLAY_INDEX(displayIndex, -1); - if (rect) { - SDL_VideoDisplay *display = &_this->displays[displayIndex]; + if (!rect) { + return SDL_InvalidParamError("rect"); + } - if ((displayIndex == 0) && ParseDisplayUsableBoundsHint(rect)) { + display = &_this->displays[displayIndex]; + + if ((displayIndex == 0) && ParseDisplayUsableBoundsHint(rect)) { + return 0; + } + + if (_this->GetDisplayUsableBounds) { + if (_this->GetDisplayUsableBounds(_this, display, rect) == 0) { return 0; } - - if (_this->GetDisplayUsableBounds) { - if (_this->GetDisplayUsableBounds(_this, display, rect) == 0) { - return 0; - } - } - - /* Oh well, just give the entire display bounds. */ - return SDL_GetDisplayBounds(displayIndex, rect); } - return 0; /* !!! FIXME: should this be an error if (rect==NULL) ? */ + + /* Oh well, just give the entire display bounds. */ + return SDL_GetDisplayBounds(displayIndex, rect); } -int -SDL_GetDisplayDPI(int displayIndex, float * ddpi, float * hdpi, float * vdpi) +int SDL_GetDisplayDPI(int displayIndex, float *ddpi, float *hdpi, float *vdpi) { SDL_VideoDisplay *display; @@ -757,8 +815,7 @@ SDL_GetDisplayDPI(int displayIndex, float * ddpi, float * hdpi, float * vdpi) return -1; } -SDL_DisplayOrientation -SDL_GetDisplayOrientation(int displayIndex) +SDL_DisplayOrientation SDL_GetDisplayOrientation(int displayIndex) { SDL_VideoDisplay *display; @@ -768,8 +825,7 @@ SDL_GetDisplayOrientation(int displayIndex) return display->orientation; } -SDL_bool -SDL_AddDisplayMode(SDL_VideoDisplay * display, const SDL_DisplayMode * mode) +SDL_bool SDL_AddDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode) { SDL_DisplayMode *modes; int i, nmodes; @@ -804,8 +860,20 @@ SDL_AddDisplayMode(SDL_VideoDisplay * display, const SDL_DisplayMode * mode) return SDL_TRUE; } -static int -SDL_GetNumDisplayModesForDisplay(SDL_VideoDisplay * display) +void SDL_SetCurrentDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode) +{ + SDL_memcpy(&display->current_mode, mode, sizeof(*mode)); +} + +void SDL_SetDesktopDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode) +{ + if (display->desktop_mode.driverdata) { + SDL_free(display->desktop_mode.driverdata); + } + SDL_memcpy(&display->desktop_mode, mode, sizeof(*mode)); +} + +static int SDL_GetNumDisplayModesForDisplay(SDL_VideoDisplay *display) { if (!display->num_display_modes && _this->GetDisplayModes) { _this->GetDisplayModes(_this, display); @@ -815,16 +883,32 @@ SDL_GetNumDisplayModesForDisplay(SDL_VideoDisplay * display) return display->num_display_modes; } -int -SDL_GetNumDisplayModes(int displayIndex) +int SDL_GetNumDisplayModes(int displayIndex) { CHECK_DISPLAY_INDEX(displayIndex, -1); return SDL_GetNumDisplayModesForDisplay(&_this->displays[displayIndex]); } -int -SDL_GetDisplayMode(int displayIndex, int index, SDL_DisplayMode * mode) +void SDL_ResetDisplayModes(int displayIndex) +{ + SDL_VideoDisplay *display; + int i; + + CHECK_DISPLAY_INDEX(displayIndex, ); + + display = &_this->displays[displayIndex]; + for (i = display->num_display_modes; i--;) { + SDL_free(display->display_modes[i].driverdata); + display->display_modes[i].driverdata = NULL; + } + SDL_free(display->display_modes); + display->display_modes = NULL; + display->num_display_modes = 0; + display->max_display_modes = 0; +} + +int SDL_GetDisplayMode(int displayIndex, int index, SDL_DisplayMode *mode) { SDL_VideoDisplay *display; @@ -832,8 +916,7 @@ SDL_GetDisplayMode(int displayIndex, int index, SDL_DisplayMode * mode) display = &_this->displays[displayIndex]; if (index < 0 || index >= SDL_GetNumDisplayModesForDisplay(display)) { - return SDL_SetError("index must be in the range of 0 - %d", - SDL_GetNumDisplayModesForDisplay(display) - 1); + return SDL_SetError("index must be in the range of 0 - %d", SDL_GetNumDisplayModesForDisplay(display) - 1); } if (mode) { *mode = display->display_modes[index]; @@ -841,8 +924,7 @@ SDL_GetDisplayMode(int displayIndex, int index, SDL_DisplayMode * mode) return 0; } -int -SDL_GetDesktopDisplayMode(int displayIndex, SDL_DisplayMode * mode) +int SDL_GetDesktopDisplayMode(int displayIndex, SDL_DisplayMode *mode) { SDL_VideoDisplay *display; @@ -855,8 +937,7 @@ SDL_GetDesktopDisplayMode(int displayIndex, SDL_DisplayMode * mode) return 0; } -int -SDL_GetCurrentDisplayMode(int displayIndex, SDL_DisplayMode * mode) +int SDL_GetCurrentDisplayMode(int displayIndex, SDL_DisplayMode *mode) { SDL_VideoDisplay *display; @@ -869,10 +950,9 @@ SDL_GetCurrentDisplayMode(int displayIndex, SDL_DisplayMode * mode) return 0; } -static SDL_DisplayMode * -SDL_GetClosestDisplayModeForDisplay(SDL_VideoDisplay * display, - const SDL_DisplayMode * mode, - SDL_DisplayMode * closest) +static SDL_DisplayMode *SDL_GetClosestDisplayModeForDisplay(SDL_VideoDisplay *display, + const SDL_DisplayMode *mode, + SDL_DisplayMode *closest) { Uint32 target_format; int target_refresh_rate; @@ -880,7 +960,7 @@ SDL_GetClosestDisplayModeForDisplay(SDL_VideoDisplay * display, SDL_DisplayMode *current, *match; if (!mode || !closest) { - SDL_SetError("Missing desired mode or closest mode parameter"); + SDL_InvalidParamError("mode/closest"); return NULL; } @@ -924,9 +1004,9 @@ SDL_GetClosestDisplayModeForDisplay(SDL_VideoDisplay * display, /* Sorted highest depth to lowest */ if (current->format == target_format || (SDL_BITSPERPIXEL(current->format) >= - SDL_BITSPERPIXEL(target_format) - && SDL_PIXELTYPE(current->format) == - SDL_PIXELTYPE(target_format))) { + SDL_BITSPERPIXEL(target_format) && + SDL_PIXELTYPE(current->format) == + SDL_PIXELTYPE(target_format))) { match = current; } continue; @@ -976,10 +1056,9 @@ SDL_GetClosestDisplayModeForDisplay(SDL_VideoDisplay * display, return NULL; } -SDL_DisplayMode * -SDL_GetClosestDisplayMode(int displayIndex, - const SDL_DisplayMode * mode, - SDL_DisplayMode * closest) +SDL_DisplayMode *SDL_GetClosestDisplayMode(int displayIndex, + const SDL_DisplayMode *mode, + SDL_DisplayMode *closest) { SDL_VideoDisplay *display; @@ -989,11 +1068,16 @@ SDL_GetClosestDisplayMode(int displayIndex, return SDL_GetClosestDisplayModeForDisplay(display, mode, closest); } -static int -SDL_SetDisplayModeForDisplay(SDL_VideoDisplay * display, const SDL_DisplayMode * mode) +static int SDL_SetDisplayModeForDisplay(SDL_VideoDisplay *display, const SDL_DisplayMode *mode) { SDL_DisplayMode display_mode; SDL_DisplayMode current_mode; + int result; + + /* Mode switching disabled via driver quirk flag, nothing to do and cannot fail. */ + if (DisableDisplayModeSwitching(_this)) { + return 0; + } if (mode) { display_mode = *mode; @@ -1014,8 +1098,7 @@ SDL_SetDisplayModeForDisplay(SDL_VideoDisplay * display, const SDL_DisplayMode * /* Get a good video mode, the closest one possible */ if (!SDL_GetClosestDisplayModeForDisplay(display, &display_mode, &display_mode)) { - return SDL_SetError("No video mode large enough for %dx%d", - display_mode.w, display_mode.h); + return SDL_SetError("No video mode large enough for %dx%d", display_mode.w, display_mode.h); } } else { display_mode = display->desktop_mode; @@ -1031,83 +1114,161 @@ SDL_SetDisplayModeForDisplay(SDL_VideoDisplay * display, const SDL_DisplayMode * if (!_this->SetDisplayMode) { return SDL_SetError("SDL video driver doesn't support changing display mode"); } - if (_this->SetDisplayMode(_this, display, &display_mode) < 0) { + _this->setting_display_mode = SDL_TRUE; + result = _this->SetDisplayMode(_this, display, &display_mode); + _this->setting_display_mode = SDL_FALSE; + if (result < 0) { return -1; } - display->current_mode = display_mode; + SDL_SetCurrentDisplayMode(display, &display_mode); return 0; } -SDL_VideoDisplay * -SDL_GetDisplay(int displayIndex) +SDL_VideoDisplay *SDL_GetDisplay(int displayIndex) { CHECK_DISPLAY_INDEX(displayIndex, NULL); return &_this->displays[displayIndex]; } -int -SDL_GetWindowDisplayIndex(SDL_Window * window) +/** + * If x, y are outside of rect, snaps them to the closest point inside rect + * (between rect->x, rect->y, inclusive, and rect->x + w, rect->y + h, exclusive) + */ +static void SDL_GetClosestPointOnRect(const SDL_Rect *rect, SDL_Point *point) +{ + const int right = rect->x + rect->w - 1; + const int bottom = rect->y + rect->h - 1; + + if (point->x < rect->x) { + point->x = rect->x; + } else if (point->x > right) { + point->x = right; + } + + if (point->y < rect->y) { + point->y = rect->y; + } else if (point->y > bottom) { + point->y = bottom; + } +} + +static int GetRectDisplayIndex(int x, int y, int w, int h) { - int displayIndex; int i, dist; int closest = -1; int closest_dist = 0x7FFFFFFF; - SDL_Point center; + SDL_Point closest_point_on_display; SDL_Point delta; - SDL_Rect rect; + SDL_Point center; + center.x = x + w / 2; + center.y = y + h / 2; - CHECK_WINDOW_MAGIC(window, -1); + if (_this) { + for (i = 0; i < _this->num_displays; ++i) { + SDL_Rect display_rect; + SDL_GetDisplayBounds(i, &display_rect); - if (SDL_WINDOWPOS_ISUNDEFINED(window->x) || - SDL_WINDOWPOS_ISCENTERED(window->x)) { - displayIndex = (window->x & 0xFFFF); - if (displayIndex >= _this->num_displays) { - displayIndex = 0; - } - return displayIndex; - } - if (SDL_WINDOWPOS_ISUNDEFINED(window->y) || - SDL_WINDOWPOS_ISCENTERED(window->y)) { - displayIndex = (window->y & 0xFFFF); - if (displayIndex >= _this->num_displays) { - displayIndex = 0; - } - return displayIndex; - } + /* Check if the window is fully enclosed */ + if (SDL_EnclosePoints(¢er, 1, &display_rect, NULL)) { + return i; + } - /* Find the display containing the window */ - for (i = 0; i < _this->num_displays; ++i) { - SDL_VideoDisplay *display = &_this->displays[i]; + /* Snap window center to the display rect */ + closest_point_on_display = center; + SDL_GetClosestPointOnRect(&display_rect, &closest_point_on_display); - if (display->fullscreen_window == window) { - return i; + delta.x = center.x - closest_point_on_display.x; + delta.y = center.y - closest_point_on_display.y; + dist = (delta.x * delta.x + delta.y * delta.y); + if (dist < closest_dist) { + closest = i; + closest_dist = dist; + } } } - center.x = window->x + window->w / 2; - center.y = window->y + window->h / 2; - for (i = 0; i < _this->num_displays; ++i) { - SDL_GetDisplayBounds(i, &rect); - if (SDL_EnclosePoints(¢er, 1, &rect, NULL)) { - return i; - } - delta.x = center.x - (rect.x + rect.w / 2); - delta.y = center.y - (rect.y + rect.h / 2); - dist = (delta.x*delta.x + delta.y*delta.y); - if (dist < closest_dist) { - closest = i; - closest_dist = dist; - } - } if (closest < 0) { SDL_SetError("Couldn't find any displays"); } + return closest; } -SDL_VideoDisplay * -SDL_GetDisplayForWindow(SDL_Window *window) +int SDL_GetPointDisplayIndex(const SDL_Point *point) +{ + return GetRectDisplayIndex(point->x, point->y, 1, 1); +} + +int SDL_GetRectDisplayIndex(const SDL_Rect *rect) +{ + return GetRectDisplayIndex(rect->x, rect->y, rect->w, rect->h); +} + +int SDL_GetWindowDisplayIndex(SDL_Window *window) +{ + int displayIndex = -1; + + CHECK_WINDOW_MAGIC(window, -1); + if (_this->GetWindowDisplayIndex) { + displayIndex = _this->GetWindowDisplayIndex(_this, window); + } + + /* A backend implementation may fail to get a display index for the window + * (for example if the window is off-screen), but other code may expect it + * to succeed in that situation, so we fall back to a generic position- + * based implementation in that case. */ + if (displayIndex >= 0) { + return displayIndex; + } else { + int i; + if (SDL_WINDOWPOS_ISUNDEFINED(window->x) || + SDL_WINDOWPOS_ISCENTERED(window->x)) { + displayIndex = (window->x & 0xFFFF); + if (displayIndex >= _this->num_displays) { + displayIndex = 0; + } + return displayIndex; + } + if (SDL_WINDOWPOS_ISUNDEFINED(window->y) || + SDL_WINDOWPOS_ISCENTERED(window->y)) { + displayIndex = (window->y & 0xFFFF); + if (displayIndex >= _this->num_displays) { + displayIndex = 0; + } + return displayIndex; + } + + displayIndex = GetRectDisplayIndex(window->x, window->y, window->w, window->h); + + /* Find the display containing the window if fullscreen */ + for (i = 0; i < _this->num_displays; ++i) { + SDL_VideoDisplay *display = &_this->displays[i]; + + if (display->fullscreen_window == window) { + if (displayIndex != i) { + if (displayIndex < 0) { + displayIndex = i; + } else { + SDL_VideoDisplay *new_display = &_this->displays[displayIndex]; + + /* The window was moved to a different display */ + if (new_display->fullscreen_window) { + /* Uh oh, there's already a fullscreen window here */ + } else { + new_display->fullscreen_window = window; + } + display->fullscreen_window = NULL; + } + } + break; + } + } + return displayIndex; + } +} + +SDL_VideoDisplay *SDL_GetDisplayForWindow(SDL_Window *window) { int displayIndex = SDL_GetWindowDisplayIndex(window); if (displayIndex >= 0) { @@ -1117,8 +1278,7 @@ SDL_GetDisplayForWindow(SDL_Window *window) } } -int -SDL_SetWindowDisplayMode(SDL_Window * window, const SDL_DisplayMode * mode) +int SDL_SetWindowDisplayMode(SDL_Window *window, const SDL_DisplayMode *mode) { CHECK_WINDOW_MAGIC(window, -1); @@ -1131,14 +1291,22 @@ SDL_SetWindowDisplayMode(SDL_Window * window, const SDL_DisplayMode * mode) if (FULLSCREEN_VISIBLE(window) && (window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP) { SDL_DisplayMode fullscreen_mode; if (SDL_GetWindowDisplayMode(window, &fullscreen_mode) == 0) { - SDL_SetDisplayModeForDisplay(SDL_GetDisplayForWindow(window), &fullscreen_mode); + if (SDL_SetDisplayModeForDisplay(SDL_GetDisplayForWindow(window), &fullscreen_mode) == 0) { +#ifndef __ANDROID__ + /* Android may not resize the window to exactly what our fullscreen mode is, especially on + * windowed Android environments like the Chromebook or Samsung DeX. Given this, we shouldn't + * use fullscreen_mode.w and fullscreen_mode.h, but rather get our current native size. As such, + * Android's SetWindowFullscreen will generate the window event for us with the proper final size. + */ + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, fullscreen_mode.w, fullscreen_mode.h); +#endif + } } } return 0; } -int -SDL_GetWindowDisplayMode(SDL_Window * window, SDL_DisplayMode * mode) +int SDL_GetWindowDisplayMode(SDL_Window *window, SDL_DisplayMode *mode) { SDL_DisplayMode fullscreen_mode; SDL_VideoDisplay *display; @@ -1163,19 +1331,27 @@ SDL_GetWindowDisplayMode(SDL_Window * window, SDL_DisplayMode * mode) if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) { fullscreen_mode = display->desktop_mode; } else if (!SDL_GetClosestDisplayModeForDisplay(SDL_GetDisplayForWindow(window), - &fullscreen_mode, - &fullscreen_mode)) { + &fullscreen_mode, + &fullscreen_mode)) { + SDL_zerop(mode); return SDL_SetError("Couldn't find display mode match"); } - if (mode) { - *mode = fullscreen_mode; - } + *mode = fullscreen_mode; + return 0; } -Uint32 -SDL_GetWindowPixelFormat(SDL_Window * window) +void *SDL_GetWindowICCProfile(SDL_Window *window, size_t *size) +{ + if (!_this->GetWindowICCProfile) { + SDL_Unsupported(); + return NULL; + } + return _this->GetWindowICCProfile(_this, window, size); +} + +Uint32 SDL_GetWindowPixelFormat(SDL_Window *window) { SDL_VideoDisplay *display; @@ -1185,8 +1361,7 @@ SDL_GetWindowPixelFormat(SDL_Window * window) return display->current_mode.format; } -static void -SDL_RestoreMousePosition(SDL_Window *window) +static void SDL_RestoreMousePosition(SDL_Window *window) { int x, y; @@ -1196,31 +1371,32 @@ SDL_RestoreMousePosition(SDL_Window *window) } } -#if __WINRT__ -extern Uint32 WINRT_DetectWindowFlags(SDL_Window * window); +#ifdef __WINRT__ +extern Uint32 WINRT_DetectWindowFlags(SDL_Window *window); #endif -static int -SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool fullscreen) +static int SDL_UpdateFullscreenMode(SDL_Window *window, SDL_bool fullscreen) { SDL_VideoDisplay *display; SDL_Window *other; + SDL_bool resized = SDL_FALSE; - CHECK_WINDOW_MAGIC(window,-1); + CHECK_WINDOW_MAGIC(window, -1); /* if we are in the process of hiding don't go back to fullscreen */ if (window->is_hiding && fullscreen) { return 0; } -#ifdef __MACOSX__ +#if defined(__MACOSX__) && defined(SDL_VIDEO_DRIVER_COCOA) /* if the window is going away and no resolution change is necessary, do nothing, or else we may trigger an ugly double-transition */ - if (SDL_strcmp(_this->name, "cocoa") == 0) { /* don't do this for X11, etc */ - if (window->is_destroying && (window->last_fullscreen_flags & FULLSCREEN_MASK) == SDL_WINDOW_FULLSCREEN_DESKTOP) + if (SDL_strcmp(_this->name, "cocoa") == 0) { /* don't do this for X11, etc */ + if (window->is_destroying && (window->last_fullscreen_flags & FULLSCREEN_MASK) == SDL_WINDOW_FULLSCREEN_DESKTOP) { return 0; - + } + /* If we're switching between a fullscreen Space and "normal" fullscreen, we need to get back to normal first. */ if (fullscreen && ((window->last_fullscreen_flags & FULLSCREEN_MASK) == SDL_WINDOW_FULLSCREEN_DESKTOP) && ((window->flags & FULLSCREEN_MASK) == SDL_WINDOW_FULLSCREEN)) { if (!Cocoa_SetWindowFullscreenSpace(window, SDL_FALSE)) { @@ -1242,7 +1418,7 @@ SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool fullscreen) return 0; } } -#elif __WINRT__ && (NTDDI_VERSION < NTDDI_WIN10) +#elif defined(__WINRT__) && (NTDDI_VERSION < NTDDI_WIN10) /* HACK: WinRT 8.x apps can't choose whether or not they are fullscreen or not. The user can choose this, via OS-provided UI, but this can't be set programmatically. @@ -1269,6 +1445,9 @@ SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool fullscreen) #endif display = SDL_GetDisplayForWindow(window); + if (!display) { /* No display connected, nothing to do. */ + return 0; + } if (fullscreen) { /* Hide any other fullscreen windows */ @@ -1283,6 +1462,13 @@ SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool fullscreen) if ((window->last_fullscreen_flags & FULLSCREEN_MASK) == (window->flags & FULLSCREEN_MASK)) { return 0; } + if (!fullscreen) { + if (_this->SetWindowFullscreen) { + _this->SetWindowFullscreen(_this, window, display, SDL_FALSE); + } + window->last_fullscreen_flags = window->flags; + return 0; + } } /* See if there are any fullscreen windows */ @@ -1302,14 +1488,14 @@ SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool fullscreen) SDL_zero(fullscreen_mode); if (SDL_GetWindowDisplayMode(other, &fullscreen_mode) == 0) { - SDL_bool resized = SDL_TRUE; + resized = SDL_TRUE; if (other->w == fullscreen_mode.w && other->h == fullscreen_mode.h) { resized = SDL_FALSE; } /* only do the mode change if we want exclusive fullscreen */ - if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP) { + if ((other->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP) { if (SDL_SetDisplayModeForDisplay(display, &fullscreen_mode) < 0) { return -1; } @@ -1326,15 +1512,21 @@ SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool fullscreen) /* Generate a mode change event here */ if (resized) { -#ifndef ANDROID - // Android may not resize the window to exactly what our fullscreen mode is, especially on - // windowed Android environments like the Chromebook or Samsung DeX. Given this, we shouldn't - // use fullscreen_mode.w and fullscreen_mode.h, but rather get our current native size. As such, - // Android's SetWindowFullscreen will generate the window event for us with the proper final size. + if (SDL_strcmp(_this->name, "Android") != 0 && SDL_strcmp(_this->name, "windows") != 0) { + /* Android may not resize the window to exactly what our fullscreen mode is, especially on + * windowed Android environments like the Chromebook or Samsung DeX. Given this, we shouldn't + * use fullscreen_mode.w and fullscreen_mode.h, but rather get our current native size. As such, + * Android's SetWindowFullscreen will generate the window event for us with the proper final size. + */ + + /* This is also unnecessary on Win32 (WIN_SetWindowFullscreen calls SetWindowPos, + * WM_WINDOWPOSCHANGED will send SDL_WINDOWEVENT_RESIZED). Also, on Windows with DPI scaling enabled, + * we're keeping modes in pixels, but window sizes in dpi-scaled points, so this would be a unit mismatch. + */ + SDL_SendWindowEvent(other, SDL_WINDOWEVENT_RESIZED, + fullscreen_mode.w, fullscreen_mode.h); + } - SDL_SendWindowEvent(other, SDL_WINDOWEVENT_RESIZED, - fullscreen_mode.w, fullscreen_mode.h); -#endif } else { SDL_OnWindowResized(other); } @@ -1352,11 +1544,18 @@ SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool fullscreen) if (_this->SetWindowFullscreen) { _this->SetWindowFullscreen(_this, window, display, SDL_FALSE); + } else { + resized = SDL_TRUE; } display->fullscreen_window = NULL; - /* Generate a mode change event here */ - SDL_OnWindowResized(window); + if (!resized) { + /* Generate a mode change event here */ + SDL_OnWindowResized(window); + } else { + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, + window->windowed.w, window->windowed.h); + } /* Restore the cursor position */ SDL_RestoreMousePosition(window); @@ -1366,10 +1565,9 @@ SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool fullscreen) } #define CREATE_FLAGS \ - (SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_ALWAYS_ON_TOP | SDL_WINDOW_SKIP_TASKBAR | SDL_WINDOW_POPUP_MENU | SDL_WINDOW_UTILITY | SDL_WINDOW_TOOLTIP | SDL_WINDOW_VULKAN | SDL_WINDOW_MINIMIZED) + (SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_ALWAYS_ON_TOP | SDL_WINDOW_SKIP_TASKBAR | SDL_WINDOW_POPUP_MENU | SDL_WINDOW_UTILITY | SDL_WINDOW_TOOLTIP | SDL_WINDOW_VULKAN | SDL_WINDOW_MINIMIZED | SDL_WINDOW_METAL) -static SDL_INLINE SDL_bool -IsAcceptingDragAndDrop(void) +static SDL_INLINE SDL_bool IsAcceptingDragAndDrop(void) { if ((SDL_GetEventState(SDL_DROPFILE) == SDL_ENABLE) || (SDL_GetEventState(SDL_DROPTEXT) == SDL_ENABLE)) { @@ -1379,8 +1577,7 @@ IsAcceptingDragAndDrop(void) } /* prepare a newly-created window */ -static SDL_INLINE void -PrepareDragAndDropSupport(SDL_Window *window) +static SDL_INLINE void PrepareDragAndDropSupport(SDL_Window *window) { if (_this->AcceptDragAndDrop) { _this->AcceptDragAndDrop(window, IsAcceptingDragAndDrop()); @@ -1388,8 +1585,7 @@ PrepareDragAndDropSupport(SDL_Window *window) } /* toggle d'n'd for all existing windows. */ -void -SDL_ToggleDragAndDropSupport(void) +void SDL_ToggleDragAndDropSupport(void) { if (_this && _this->AcceptDragAndDrop) { const SDL_bool enable = IsAcceptingDragAndDrop(); @@ -1400,8 +1596,7 @@ SDL_ToggleDragAndDropSupport(void) } } -static void -SDL_FinishWindowCreation(SDL_Window *window, Uint32 flags) +static void SDL_FinishWindowCreation(SDL_Window *window, Uint32 flags) { PrepareDragAndDropSupport(window); @@ -1414,27 +1609,61 @@ SDL_FinishWindowCreation(SDL_Window *window, Uint32 flags) if (flags & SDL_WINDOW_FULLSCREEN) { SDL_SetWindowFullscreen(window, flags); } - if (flags & SDL_WINDOW_INPUT_GRABBED) { + if (flags & SDL_WINDOW_MOUSE_GRABBED) { + /* We must specifically call SDL_SetWindowGrab() and not + SDL_SetWindowMouseGrab() here because older applications may use + this flag plus SDL_HINT_GRAB_KEYBOARD to indicate that they want + the keyboard grabbed too and SDL_SetWindowMouseGrab() won't do that. + */ SDL_SetWindowGrab(window, SDL_TRUE); } + if (flags & SDL_WINDOW_KEYBOARD_GRABBED) { + SDL_SetWindowKeyboardGrab(window, SDL_TRUE); + } if (!(flags & SDL_WINDOW_HIDDEN)) { SDL_ShowWindow(window); } } -SDL_Window * -SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags) +static int SDL_ContextNotSupported(const char *name) +{ + return SDL_SetError("%s support is either not configured in SDL " + "or not available in current SDL video driver " + "(%s) or platform", + name, + _this->name); +} + +static int SDL_DllNotSupported(const char *name) +{ + return SDL_SetError("No dynamic %s support in current SDL video driver (%s)", name, _this->name); +} + +SDL_Window *SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags) { SDL_Window *window; + Uint32 type_flags, graphics_flags; if (!_this) { /* Initialize the video system if needed */ - if (SDL_VideoInit(NULL) < 0) { + if (SDL_Init(SDL_INIT_VIDEO) < 0) { + return NULL; + } + + /* Make clang-tidy happy */ + if (!_this) { return NULL; } } - if ((((flags & SDL_WINDOW_UTILITY) != 0) + ((flags & SDL_WINDOW_TOOLTIP) != 0) + ((flags & SDL_WINDOW_POPUP_MENU) != 0)) > 1) { + /* Make sure the display list is up to date for window placement */ + if (_this->RefreshDisplays) { + _this->RefreshDisplays(_this); + } + + /* ensure no more than one of these flags is set */ + type_flags = flags & (SDL_WINDOW_UTILITY | SDL_WINDOW_TOOLTIP | SDL_WINDOW_POPUP_MENU); + if (type_flags & (type_flags - 1)) { SDL_SetError("Conflicting window flags specified"); return NULL; } @@ -1448,22 +1677,28 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags) } /* Some platforms blow up if the windows are too large. Raise it later? */ - if ((w > 16384) || (h > 16384)) { - SDL_SetError("Window is too large."); + if (w > 16384) { + w = 16384; + } + if (h > 16384) { + h = 16384; + } + + /* ensure no more than one of these flags is set */ + graphics_flags = flags & (SDL_WINDOW_OPENGL | SDL_WINDOW_METAL | SDL_WINDOW_VULKAN); + if (graphics_flags & (graphics_flags - 1)) { + SDL_SetError("Conflicting window flags specified"); return NULL; } - /* Some platforms have OpenGL enabled by default */ -#if (SDL_VIDEO_OPENGL && __MACOSX__) || __IPHONEOS__ || __ANDROID__ || __NACL__ - if (!_this->is_dummy && !(flags & SDL_WINDOW_VULKAN) && !SDL_IsVideoContextExternal()) { - flags |= SDL_WINDOW_OPENGL; + /* Some platforms have certain graphics backends enabled by default */ + if (!graphics_flags && !SDL_IsVideoContextExternal()) { + flags |= SDL_DefaultGraphicsBackends(_this); } -#endif + if (flags & SDL_WINDOW_OPENGL) { if (!_this->GL_CreateContext) { - SDL_SetError("OpenGL support is either not configured in SDL " - "or not available in current SDL video driver " - "(%s) or platform", _this->name); + SDL_ContextNotSupported("OpenGL"); return NULL; } if (SDL_GL_LoadLibrary(NULL) < 0) { @@ -1473,13 +1708,7 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags) if (flags & SDL_WINDOW_VULKAN) { if (!_this->Vulkan_CreateSurface) { - SDL_SetError("Vulkan support is either not configured in SDL " - "or not available in current SDL video driver " - "(%s) or platform", _this->name); - return NULL; - } - if (flags & SDL_WINDOW_OPENGL) { - SDL_SetError("Vulkan and OpenGL not supported on same window"); + SDL_ContextNotSupported("Vulkan"); return NULL; } if (SDL_Vulkan_LoadLibrary(NULL) < 0) { @@ -1487,6 +1716,13 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags) } } + if (flags & SDL_WINDOW_METAL) { + if (!_this->Metal_CreateView) { + SDL_ContextNotSupported("Metal"); + return NULL; + } + } + /* Unless the user has specified the high-DPI disabling hint, respect the * SDL_WINDOW_ALLOW_HIGHDPI flag. */ @@ -1535,6 +1771,21 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags) displayIndex = SDL_GetIndexOfDisplay(display); SDL_GetDisplayBounds(displayIndex, &bounds); + /* for real fullscreen we might switch the resolution, so get width and height + * from closest supported mode and use that instead of current resolution + */ + if ((flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP && (bounds.w != w || bounds.h != h)) { + SDL_DisplayMode fullscreen_mode, closest_mode; + SDL_zero(fullscreen_mode); + fullscreen_mode.w = w; + fullscreen_mode.h = h; + if (SDL_GetClosestDisplayModeForDisplay(display, &fullscreen_mode, &closest_mode) != NULL) { + bounds.w = closest_mode.w; + bounds.h = closest_mode.h; + } + } + window->fullscreen_mode.w = bounds.w; + window->fullscreen_mode.h = bounds.h; window->x = bounds.x; window->y = bounds.y; window->w = bounds.w; @@ -1547,6 +1798,7 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags) window->brightness = 1.0f; window->next = _this->windows; window->is_destroying = SDL_FALSE; + window->display_index = SDL_GetWindowDisplayIndex(window); if (_this->windows) { _this->windows->prev = window; @@ -1561,13 +1813,13 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags) /* Clear minimized if not on windows, only windows handles it at create rather than FinishWindowCreation, * but it's important or window focus will get broken on windows! */ -#if !defined(__WIN32__) +#if !defined(__WIN32__) && !defined(__GDK__) if (window->flags & SDL_WINDOW_MINIMIZED) { window->flags &= ~SDL_WINDOW_MINIMIZED; } #endif -#if __WINRT__ && (NTDDI_VERSION < NTDDI_WIN10) +#if defined(__WINRT__) && (NTDDI_VERSION < NTDDI_WIN10) /* HACK: WinRT 8.x apps can't choose whether or not they are fullscreen or not. The user can choose this, via OS-provided UI, but this can't be set programmatically. @@ -1590,10 +1842,10 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags) return window; } -SDL_Window * -SDL_CreateWindowFrom(const void *data) +SDL_Window *SDL_CreateWindowFrom(const void *data) { SDL_Window *window; + Uint32 flags = SDL_WINDOW_FOREIGN; if (!_this) { SDL_UninitializedVideo(); @@ -1603,6 +1855,33 @@ SDL_CreateWindowFrom(const void *data) SDL_Unsupported(); return NULL; } + + if (SDL_GetHintBoolean(SDL_HINT_VIDEO_FOREIGN_WINDOW_OPENGL, SDL_FALSE)) { + if (!_this->GL_CreateContext) { + SDL_ContextNotSupported("OpenGL"); + return NULL; + } + if (SDL_GL_LoadLibrary(NULL) < 0) { + return NULL; + } + flags |= SDL_WINDOW_OPENGL; + } + + if (SDL_GetHintBoolean(SDL_HINT_VIDEO_FOREIGN_WINDOW_VULKAN, SDL_FALSE)) { + if (!_this->Vulkan_CreateSurface) { + SDL_ContextNotSupported("Vulkan"); + return NULL; + } + if (flags & SDL_WINDOW_OPENGL) { + SDL_SetError("Vulkan and OpenGL not supported on same window"); + return NULL; + } + if (SDL_Vulkan_LoadLibrary(NULL) < 0) { + return NULL; + } + flags |= SDL_WINDOW_VULKAN; + } + window = (SDL_Window *)SDL_calloc(1, sizeof(*window)); if (!window) { SDL_OutOfMemory(); @@ -1610,7 +1889,7 @@ SDL_CreateWindowFrom(const void *data) } window->magic = &_this->window_magic; window->id = _this->next_object_id++; - window->flags = SDL_WINDOW_FOREIGN; + window->flags = flags; window->last_fullscreen_flags = window->flags; window->is_destroying = SDL_FALSE; window->opacity = 1.0f; @@ -1626,20 +1905,36 @@ SDL_CreateWindowFrom(const void *data) return NULL; } + window->display_index = SDL_GetWindowDisplayIndex(window); PrepareDragAndDropSupport(window); return window; } -int -SDL_RecreateWindow(SDL_Window * window, Uint32 flags) +int SDL_RecreateWindow(SDL_Window *window, Uint32 flags) { SDL_bool loaded_opengl = SDL_FALSE; + SDL_bool need_gl_unload = SDL_FALSE; + SDL_bool need_gl_load = SDL_FALSE; + SDL_bool loaded_vulkan = SDL_FALSE; + SDL_bool need_vulkan_unload = SDL_FALSE; + SDL_bool need_vulkan_load = SDL_FALSE; + Uint32 graphics_flags; + + /* ensure no more than one of these flags is set */ + graphics_flags = flags & (SDL_WINDOW_OPENGL | SDL_WINDOW_METAL | SDL_WINDOW_VULKAN); + if (graphics_flags & (graphics_flags - 1)) { + return SDL_SetError("Conflicting window flags specified"); + } if ((flags & SDL_WINDOW_OPENGL) && !_this->GL_CreateContext) { - return SDL_SetError("OpenGL support is either not configured in SDL " - "or not available in current SDL video driver " - "(%s) or platform", _this->name); + return SDL_ContextNotSupported("OpenGL"); + } + if ((flags & SDL_WINDOW_VULKAN) && !_this->Vulkan_CreateSurface) { + return SDL_ContextNotSupported("Vulkan"); + } + if ((flags & SDL_WINDOW_METAL) && !_this->Metal_CreateView) { + return SDL_ContextNotSupported("Metal"); } if (window->flags & SDL_WINDOW_FOREIGN) { @@ -1650,47 +1945,59 @@ SDL_RecreateWindow(SDL_Window * window, Uint32 flags) } /* Restore video mode, etc. */ - SDL_HideWindow(window); + if (!(window->flags & SDL_WINDOW_FOREIGN)) { + SDL_HideWindow(window); + } /* Tear down the old native window */ - if (window->surface) { - window->surface->flags &= ~SDL_DONTFREE; - SDL_FreeSurface(window->surface); - window->surface = NULL; - window->surface_valid = SDL_FALSE; - } - if (_this->DestroyWindowFramebuffer) { - _this->DestroyWindowFramebuffer(_this, window); - } + SDL_DestroyWindowSurface(window); + if (_this->DestroyWindow && !(flags & SDL_WINDOW_FOREIGN)) { _this->DestroyWindow(_this, window); } if ((window->flags & SDL_WINDOW_OPENGL) != (flags & SDL_WINDOW_OPENGL)) { if (flags & SDL_WINDOW_OPENGL) { - if (SDL_GL_LoadLibrary(NULL) < 0) { - return -1; - } - loaded_opengl = SDL_TRUE; + need_gl_load = SDL_TRUE; } else { - SDL_GL_UnloadLibrary(); + need_gl_unload = SDL_TRUE; } } else if (window->flags & SDL_WINDOW_OPENGL) { + need_gl_unload = SDL_TRUE; + need_gl_load = SDL_TRUE; + } + + if ((window->flags & SDL_WINDOW_VULKAN) != (flags & SDL_WINDOW_VULKAN)) { + if (flags & SDL_WINDOW_VULKAN) { + need_vulkan_load = SDL_TRUE; + } else { + need_vulkan_unload = SDL_TRUE; + } + } else if (window->flags & SDL_WINDOW_VULKAN) { + need_vulkan_unload = SDL_TRUE; + need_vulkan_load = SDL_TRUE; + } + + if (need_gl_unload) { SDL_GL_UnloadLibrary(); + } + + if (need_vulkan_unload) { + SDL_Vulkan_UnloadLibrary(); + } + + if (need_gl_load) { if (SDL_GL_LoadLibrary(NULL) < 0) { return -1; } loaded_opengl = SDL_TRUE; } - if ((window->flags & SDL_WINDOW_VULKAN) != (flags & SDL_WINDOW_VULKAN)) { - SDL_SetError("Can't change SDL_WINDOW_VULKAN window flag"); - return -1; - } - - if ((window->flags & SDL_WINDOW_VULKAN) && (flags & SDL_WINDOW_OPENGL)) { - SDL_SetError("Vulkan and OpenGL not supported on same window"); - return -1; + if (need_vulkan_load) { + if (SDL_Vulkan_LoadLibrary(NULL) < 0) { + return -1; + } + loaded_vulkan = SDL_TRUE; } window->flags = ((flags & CREATE_FLAGS) | SDL_WINDOW_HIDDEN); @@ -1703,6 +2010,10 @@ SDL_RecreateWindow(SDL_Window * window, Uint32 flags) SDL_GL_UnloadLibrary(); window->flags &= ~SDL_WINDOW_OPENGL; } + if (loaded_vulkan) { + SDL_Vulkan_UnloadLibrary(); + window->flags &= ~SDL_WINDOW_VULKAN; + } return -1; } } @@ -1719,6 +2030,14 @@ SDL_RecreateWindow(SDL_Window * window, Uint32 flags) _this->SetWindowIcon(_this, window, window->icon); } + if (_this->SetWindowMinimumSize && (window->min_w || window->min_h)) { + _this->SetWindowMinimumSize(_this, window); + } + + if (_this->SetWindowMaximumSize && (window->max_w || window->max_h)) { + _this->SetWindowMaximumSize(_this, window); + } + if (window->hit_test) { _this->SetWindowHitTest(window, SDL_TRUE); } @@ -1728,22 +2047,19 @@ SDL_RecreateWindow(SDL_Window * window, Uint32 flags) return 0; } -SDL_bool -SDL_HasWindows(void) +SDL_bool SDL_HasWindows(void) { - return (_this && _this->windows != NULL); + return _this && _this->windows; } -Uint32 -SDL_GetWindowID(SDL_Window * window) +Uint32 SDL_GetWindowID(SDL_Window *window) { CHECK_WINDOW_MAGIC(window, 0); return window->id; } -SDL_Window * -SDL_GetWindowFromID(Uint32 id) +SDL_Window *SDL_GetWindowFromID(Uint32 id) { SDL_Window *window; @@ -1758,18 +2074,16 @@ SDL_GetWindowFromID(Uint32 id) return NULL; } -Uint32 -SDL_GetWindowFlags(SDL_Window * window) +Uint32 SDL_GetWindowFlags(SDL_Window *window) { CHECK_WINDOW_MAGIC(window, 0); return window->flags; } -void -SDL_SetWindowTitle(SDL_Window * window, const char *title) +void SDL_SetWindowTitle(SDL_Window *window, const char *title) { - CHECK_WINDOW_MAGIC(window,); + CHECK_WINDOW_MAGIC(window, ); if (title == window->title) { return; @@ -1783,18 +2097,16 @@ SDL_SetWindowTitle(SDL_Window * window, const char *title) } } -const char * -SDL_GetWindowTitle(SDL_Window * window) +const char *SDL_GetWindowTitle(SDL_Window *window) { CHECK_WINDOW_MAGIC(window, ""); return window->title ? window->title : ""; } -void -SDL_SetWindowIcon(SDL_Window * window, SDL_Surface * icon) +void SDL_SetWindowIcon(SDL_Window *window, SDL_Surface *icon) { - CHECK_WINDOW_MAGIC(window,); + CHECK_WINDOW_MAGIC(window, ); if (!icon) { return; @@ -1813,8 +2125,7 @@ SDL_SetWindowIcon(SDL_Window * window, SDL_Surface * icon) } } -void* -SDL_SetWindowData(SDL_Window * window, const char *name, void *userdata) +void *SDL_SetWindowData(SDL_Window *window, const char *name, void *userdata) { SDL_WindowUserData *prev, *data; @@ -1822,8 +2133,8 @@ SDL_SetWindowData(SDL_Window * window, const char *name, void *userdata) /* Input validation */ if (name == NULL || name[0] == '\0') { - SDL_InvalidParamError("name"); - return NULL; + SDL_InvalidParamError("name"); + return NULL; } /* See if the named data already exists */ @@ -1860,8 +2171,7 @@ SDL_SetWindowData(SDL_Window * window, const char *name, void *userdata) return NULL; } -void * -SDL_GetWindowData(SDL_Window * window, const char *name) +void *SDL_GetWindowData(SDL_Window *window, const char *name) { SDL_WindowUserData *data; @@ -1869,8 +2179,8 @@ SDL_GetWindowData(SDL_Window * window, const char *name) /* Input validation */ if (name == NULL || name[0] == '\0') { - SDL_InvalidParamError("name"); - return NULL; + SDL_InvalidParamError("name"); + return NULL; } for (data = window->data; data; data = data->next) { @@ -1881,10 +2191,9 @@ SDL_GetWindowData(SDL_Window * window, const char *name) return NULL; } -void -SDL_SetWindowPosition(SDL_Window * window, int x, int y) +void SDL_SetWindowPosition(SDL_Window *window, int x, int y) { - CHECK_WINDOW_MAGIC(window,); + CHECK_WINDOW_MAGIC(window, ); if (SDL_WINDOWPOS_ISCENTERED(x) || SDL_WINDOWPOS_ISCENTERED(y)) { int displayIndex = (x & 0xFFFF); @@ -1897,10 +2206,10 @@ SDL_SetWindowPosition(SDL_Window * window, int x, int y) SDL_GetDisplayBounds(displayIndex, &bounds); if (SDL_WINDOWPOS_ISCENTERED(x)) { - x = bounds.x + (bounds.w - window->w) / 2; + x = bounds.x + (bounds.w - window->windowed.w) / 2; } if (SDL_WINDOWPOS_ISCENTERED(y)) { - y = bounds.y + (bounds.h - window->h) / 2; + y = bounds.y + (bounds.h - window->windowed.h) / 2; } } @@ -1925,15 +2234,14 @@ SDL_SetWindowPosition(SDL_Window * window, int x, int y) } } -void -SDL_GetWindowPosition(SDL_Window * window, int *x, int *y) +void SDL_GetWindowPosition(SDL_Window *window, int *x, int *y) { - CHECK_WINDOW_MAGIC(window,); + CHECK_WINDOW_MAGIC(window, ); /* Fullscreen windows are always at their display's origin */ if (window->flags & SDL_WINDOW_FULLSCREEN) { int displayIndex; - + if (x) { *x = 0; } @@ -1967,30 +2275,28 @@ SDL_GetWindowPosition(SDL_Window * window, int *x, int *y) } } -void -SDL_SetWindowBordered(SDL_Window * window, SDL_bool bordered) +void SDL_SetWindowBordered(SDL_Window *window, SDL_bool bordered) { - CHECK_WINDOW_MAGIC(window,); + CHECK_WINDOW_MAGIC(window, ); if (!(window->flags & SDL_WINDOW_FULLSCREEN)) { - const int want = (bordered != SDL_FALSE); /* normalize the flag. */ - const int have = ((window->flags & SDL_WINDOW_BORDERLESS) == 0); + const int want = (bordered != SDL_FALSE); /* normalize the flag. */ + const int have = !(window->flags & SDL_WINDOW_BORDERLESS); if ((want != have) && (_this->SetWindowBordered)) { if (want) { window->flags &= ~SDL_WINDOW_BORDERLESS; } else { window->flags |= SDL_WINDOW_BORDERLESS; } - _this->SetWindowBordered(_this, window, (SDL_bool) want); + _this->SetWindowBordered(_this, window, (SDL_bool)want); } } } -void -SDL_SetWindowResizable(SDL_Window * window, SDL_bool resizable) +void SDL_SetWindowResizable(SDL_Window *window, SDL_bool resizable) { - CHECK_WINDOW_MAGIC(window,); + CHECK_WINDOW_MAGIC(window, ); if (!(window->flags & SDL_WINDOW_FULLSCREEN)) { - const int want = (resizable != SDL_FALSE); /* normalize the flag. */ + const int want = (resizable != SDL_FALSE); /* normalize the flag. */ const int have = ((window->flags & SDL_WINDOW_RESIZABLE) != 0); if ((want != have) && (_this->SetWindowResizable)) { if (want) { @@ -1998,15 +2304,32 @@ SDL_SetWindowResizable(SDL_Window * window, SDL_bool resizable) } else { window->flags &= ~SDL_WINDOW_RESIZABLE; } - _this->SetWindowResizable(_this, window, (SDL_bool) want); + _this->SetWindowResizable(_this, window, (SDL_bool)want); } } } -void -SDL_SetWindowSize(SDL_Window * window, int w, int h) +void SDL_SetWindowAlwaysOnTop(SDL_Window *window, SDL_bool on_top) { - CHECK_WINDOW_MAGIC(window,); + CHECK_WINDOW_MAGIC(window, ); + if (!(window->flags & SDL_WINDOW_FULLSCREEN)) { + const int want = (on_top != SDL_FALSE); /* normalize the flag. */ + const int have = ((window->flags & SDL_WINDOW_ALWAYS_ON_TOP) != 0); + if ((want != have) && (_this->SetWindowAlwaysOnTop)) { + if (want) { + window->flags |= SDL_WINDOW_ALWAYS_ON_TOP; + } else { + window->flags &= ~SDL_WINDOW_ALWAYS_ON_TOP; + } + + _this->SetWindowAlwaysOnTop(_this, window, (SDL_bool)want); + } + } +} + +void SDL_SetWindowSize(SDL_Window *window, int w, int h) +{ + CHECK_WINDOW_MAGIC(window, ); if (w <= 0) { SDL_InvalidParamError("w"); return; @@ -2039,22 +2362,23 @@ SDL_SetWindowSize(SDL_Window * window, int w, int h) SDL_UpdateFullscreenMode(window, SDL_TRUE); } } else { + int old_w = window->w; + int old_h = window->h; window->w = w; window->h = h; if (_this->SetWindowSize) { _this->SetWindowSize(_this, window); } - if (window->w == w && window->h == h) { + if (window->w != old_w || window->h != old_h) { /* We didn't get a SDL_WINDOWEVENT_RESIZED event (by design) */ SDL_OnWindowResized(window); } } } -void -SDL_GetWindowSize(SDL_Window * window, int *w, int *h) +void SDL_GetWindowSize(SDL_Window *window, int *w, int *h) { - CHECK_WINDOW_MAGIC(window,); + CHECK_WINDOW_MAGIC(window, ); if (w) { *w = window->w; } @@ -2063,15 +2387,22 @@ SDL_GetWindowSize(SDL_Window * window, int *w, int *h) } } -int -SDL_GetWindowBordersSize(SDL_Window * window, int *top, int *left, int *bottom, int *right) +int SDL_GetWindowBordersSize(SDL_Window *window, int *top, int *left, int *bottom, int *right) { int dummy = 0; - if (!top) { top = &dummy; } - if (!left) { left = &dummy; } - if (!right) { right = &dummy; } - if (!bottom) { bottom = &dummy; } + if (!top) { + top = &dummy; + } + if (!left) { + left = &dummy; + } + if (!right) { + right = &dummy; + } + if (!bottom) { + bottom = &dummy; + } /* Always initialize, so applications don't have to care */ *top = *left = *bottom = *right = 0; @@ -2085,10 +2416,30 @@ SDL_GetWindowBordersSize(SDL_Window * window, int *top, int *left, int *bottom, return _this->GetWindowBordersSize(_this, window, top, left, bottom, right); } -void -SDL_SetWindowMinimumSize(SDL_Window * window, int min_w, int min_h) +void SDL_GetWindowSizeInPixels(SDL_Window *window, int *w, int *h) { - CHECK_WINDOW_MAGIC(window,); + int filter; + + CHECK_WINDOW_MAGIC(window, ); + + if (!w) { + w = &filter; + } + + if (!h) { + h = &filter; + } + + if (_this->GetWindowSizeInPixels) { + _this->GetWindowSizeInPixels(_this, window, w, h); + } else { + SDL_GetWindowSize(window, w, h); + } +} + +void SDL_SetWindowMinimumSize(SDL_Window *window, int min_w, int min_h) +{ + CHECK_WINDOW_MAGIC(window, ); if (min_w <= 0) { SDL_InvalidParamError("min_w"); return; @@ -2098,8 +2449,8 @@ SDL_SetWindowMinimumSize(SDL_Window * window, int min_w, int min_h) return; } - if ((window->max_w && min_w >= window->max_w) || - (window->max_h && min_h >= window->max_h)) { + if ((window->max_w && min_w > window->max_w) || + (window->max_h && min_h > window->max_h)) { SDL_SetError("SDL_SetWindowMinimumSize(): Tried to set minimum size larger than maximum size"); return; } @@ -2116,10 +2467,9 @@ SDL_SetWindowMinimumSize(SDL_Window * window, int min_w, int min_h) } } -void -SDL_GetWindowMinimumSize(SDL_Window * window, int *min_w, int *min_h) +void SDL_GetWindowMinimumSize(SDL_Window *window, int *min_w, int *min_h) { - CHECK_WINDOW_MAGIC(window,); + CHECK_WINDOW_MAGIC(window, ); if (min_w) { *min_w = window->min_w; } @@ -2128,10 +2478,9 @@ SDL_GetWindowMinimumSize(SDL_Window * window, int *min_w, int *min_h) } } -void -SDL_SetWindowMaximumSize(SDL_Window * window, int max_w, int max_h) +void SDL_SetWindowMaximumSize(SDL_Window *window, int max_w, int max_h) { - CHECK_WINDOW_MAGIC(window,); + CHECK_WINDOW_MAGIC(window, ); if (max_w <= 0) { SDL_InvalidParamError("max_w"); return; @@ -2141,7 +2490,7 @@ SDL_SetWindowMaximumSize(SDL_Window * window, int max_w, int max_h) return; } - if (max_w <= window->min_w || max_h <= window->min_h) { + if (max_w < window->min_w || max_h < window->min_h) { SDL_SetError("SDL_SetWindowMaximumSize(): Tried to set maximum size smaller than minimum size"); return; } @@ -2158,10 +2507,9 @@ SDL_SetWindowMaximumSize(SDL_Window * window, int max_w, int max_h) } } -void -SDL_GetWindowMaximumSize(SDL_Window * window, int *max_w, int *max_h) +void SDL_GetWindowMaximumSize(SDL_Window *window, int *max_w, int *max_h) { - CHECK_WINDOW_MAGIC(window,); + CHECK_WINDOW_MAGIC(window, ); if (max_w) { *max_w = window->max_w; } @@ -2170,10 +2518,9 @@ SDL_GetWindowMaximumSize(SDL_Window * window, int *max_w, int *max_h) } } -void -SDL_ShowWindow(SDL_Window * window) +void SDL_ShowWindow(SDL_Window *window) { - CHECK_WINDOW_MAGIC(window,); + CHECK_WINDOW_MAGIC(window, ); if (window->flags & SDL_WINDOW_SHOWN) { return; @@ -2181,14 +2528,16 @@ SDL_ShowWindow(SDL_Window * window) if (_this->ShowWindow) { _this->ShowWindow(_this, window); + } else { + SDL_SetMouseFocus(window); + SDL_SetKeyboardFocus(window); } SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SHOWN, 0, 0); } -void -SDL_HideWindow(SDL_Window * window) +void SDL_HideWindow(SDL_Window *window) { - CHECK_WINDOW_MAGIC(window,); + CHECK_WINDOW_MAGIC(window, ); if (!(window->flags & SDL_WINDOW_SHOWN)) { return; @@ -2199,15 +2548,17 @@ SDL_HideWindow(SDL_Window * window) if (_this->HideWindow) { _this->HideWindow(_this, window); + } else { + SDL_SetMouseFocus(NULL); + SDL_SetKeyboardFocus(NULL); } window->is_hiding = SDL_FALSE; SDL_SendWindowEvent(window, SDL_WINDOWEVENT_HIDDEN, 0, 0); } -void -SDL_RaiseWindow(SDL_Window * window) +void SDL_RaiseWindow(SDL_Window *window) { - CHECK_WINDOW_MAGIC(window,); + CHECK_WINDOW_MAGIC(window, ); if (!(window->flags & SDL_WINDOW_SHOWN)) { return; @@ -2217,10 +2568,9 @@ SDL_RaiseWindow(SDL_Window * window) } } -void -SDL_MaximizeWindow(SDL_Window * window) +void SDL_MaximizeWindow(SDL_Window *window) { - CHECK_WINDOW_MAGIC(window,); + CHECK_WINDOW_MAGIC(window, ); if (window->flags & SDL_WINDOW_MAXIMIZED) { return; @@ -2233,8 +2583,7 @@ SDL_MaximizeWindow(SDL_Window * window) } } -static SDL_bool -CanMinimizeWindow(SDL_Window * window) +static SDL_bool CanMinimizeWindow(SDL_Window *window) { if (!_this->MinimizeWindow) { return SDL_FALSE; @@ -2242,10 +2591,9 @@ CanMinimizeWindow(SDL_Window * window) return SDL_TRUE; } -void -SDL_MinimizeWindow(SDL_Window * window) +void SDL_MinimizeWindow(SDL_Window *window) { - CHECK_WINDOW_MAGIC(window,); + CHECK_WINDOW_MAGIC(window, ); if (window->flags & SDL_WINDOW_MINIMIZED) { return; @@ -2255,17 +2603,18 @@ SDL_MinimizeWindow(SDL_Window * window) return; } - SDL_UpdateFullscreenMode(window, SDL_FALSE); + if (!DisableUnsetFullscreenOnMinimize(_this)) { + SDL_UpdateFullscreenMode(window, SDL_FALSE); + } if (_this->MinimizeWindow) { _this->MinimizeWindow(_this, window); } } -void -SDL_RestoreWindow(SDL_Window * window) +void SDL_RestoreWindow(SDL_Window *window) { - CHECK_WINDOW_MAGIC(window,); + CHECK_WINDOW_MAGIC(window, ); if (!(window->flags & (SDL_WINDOW_MAXIMIZED | SDL_WINDOW_MINIMIZED))) { return; @@ -2276,8 +2625,7 @@ SDL_RestoreWindow(SDL_Window * window) } } -int -SDL_SetWindowFullscreen(SDL_Window * window, Uint32 flags) +int SDL_SetWindowFullscreen(SDL_Window *window, Uint32 flags) { Uint32 oldflags; CHECK_WINDOW_MAGIC(window, -1); @@ -2296,38 +2644,129 @@ SDL_SetWindowFullscreen(SDL_Window * window, Uint32 flags) if (SDL_UpdateFullscreenMode(window, FULLSCREEN_VISIBLE(window)) == 0) { return 0; } - + window->flags &= ~FULLSCREEN_MASK; window->flags |= oldflags; return -1; } -static SDL_Surface * -SDL_CreateWindowFramebuffer(SDL_Window * window) +static SDL_bool ShouldAttemptTextureFramebuffer(void) { - Uint32 format; - void *pixels; - int pitch; - int bpp; - Uint32 Rmask, Gmask, Bmask, Amask; + const char *hint; + SDL_bool attempt_texture_framebuffer = SDL_TRUE; - if (!_this->CreateWindowFramebuffer || !_this->UpdateWindowFramebuffer) { - return NULL; + /* The dummy driver never has GPU support, of course. */ + if (_this->is_dummy) { + return SDL_FALSE; } - if (_this->CreateWindowFramebuffer(_this, window, &format, &pixels, &pitch) < 0) { - return NULL; + /* See if there's a hint override */ + hint = SDL_GetHint(SDL_HINT_FRAMEBUFFER_ACCELERATION); + if (hint && *hint) { + if (*hint == '0' || SDL_strcasecmp(hint, "false") == 0 || SDL_strcasecmp(hint, "software") == 0) { + attempt_texture_framebuffer = SDL_FALSE; + } else { + attempt_texture_framebuffer = SDL_TRUE; + } + } else { + /* Check for platform specific defaults */ +#if defined(__LINUX__) + /* On WSL, direct X11 is faster than using OpenGL for window framebuffers, so try to detect WSL and avoid texture framebuffer. */ + if ((_this->CreateWindowFramebuffer) && (SDL_strcmp(_this->name, "x11") == 0)) { + struct stat sb; + if ((stat("/proc/sys/fs/binfmt_misc/WSLInterop", &sb) == 0) || (stat("/run/WSL", &sb) == 0)) { /* if either of these exist, we're on WSL. */ + attempt_texture_framebuffer = SDL_FALSE; + } + } +#endif +#if defined(__WIN32__) || defined(__WINGDK__) /* GDI BitBlt() is way faster than Direct3D dynamic textures right now. (!!! FIXME: is this still true?) */ + if (_this->CreateWindowFramebuffer && (SDL_strcmp(_this->name, "windows") == 0)) { + attempt_texture_framebuffer = SDL_FALSE; + } +#endif +#if defined(__EMSCRIPTEN__) + attempt_texture_framebuffer = SDL_FALSE; +#endif + } + + if (attempt_texture_framebuffer) { + /* Using a software renderer will try to display on a window surface, so avoid recursion here */ + hint = SDL_GetHint(SDL_HINT_RENDER_DRIVER); + if (hint && SDL_strcasecmp(hint, "software") == 0) { + attempt_texture_framebuffer = SDL_FALSE; + } + } + return attempt_texture_framebuffer; +} + +static SDL_Surface *SDL_CreateWindowFramebuffer(SDL_Window *window) +{ + Uint32 format = 0; + void *pixels = NULL; + int pitch = 0; + int bpp; + Uint32 Rmask, Gmask, Bmask, Amask; + SDL_bool created_framebuffer = SDL_FALSE; + int w, h; + + SDL_GetWindowSizeInPixels(window, &w, &h); + + /* This will switch the video backend from using a software surface to + using a GPU texture through the 2D render API, if we think this would + be more efficient. This only checks once, on demand. */ + if (!_this->checked_texture_framebuffer) { + if (ShouldAttemptTextureFramebuffer()) { + if (SDL_CreateWindowTexture(_this, window, &format, &pixels, &pitch) < 0) { + /* !!! FIXME: if this failed halfway (made renderer, failed to make texture, etc), + !!! FIXME: we probably need to clean this up so it doesn't interfere with + !!! FIXME: a software fallback at the system level (can we blit to an + !!! FIXME: OpenGL window? etc). */ + } else { + /* future attempts will just try to use a texture framebuffer. */ + /* !!! FIXME: maybe we shouldn't override these but check if we used a texture + !!! FIXME: framebuffer at the right places; is it feasible we could have an + !!! FIXME: accelerated OpenGL window and a second ends up in software? */ + _this->CreateWindowFramebuffer = SDL_CreateWindowTexture; + _this->UpdateWindowFramebuffer = SDL_UpdateWindowTexture; + _this->DestroyWindowFramebuffer = SDL_DestroyWindowTexture; + created_framebuffer = SDL_TRUE; + } + } + + _this->checked_texture_framebuffer = SDL_TRUE; /* don't check this again. */ + } + + if (!created_framebuffer) { + if (!_this->CreateWindowFramebuffer || !_this->UpdateWindowFramebuffer) { + SDL_SetError("Window framebuffer support not available"); + return NULL; + } + + if (_this->CreateWindowFramebuffer(_this, window, &format, &pixels, &pitch) < 0) { + return NULL; + } + } + + if (window->surface) { + /* We may have gone recursive and already created the surface */ + return window->surface; } if (!SDL_PixelFormatEnumToMasks(format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) { return NULL; } - return SDL_CreateRGBSurfaceFrom(pixels, window->w, window->h, bpp, pitch, Rmask, Gmask, Bmask, Amask); + return SDL_CreateRGBSurfaceFrom(pixels, w, h, bpp, pitch, Rmask, Gmask, Bmask, Amask); } -SDL_Surface * -SDL_GetWindowSurface(SDL_Window * window) +SDL_bool SDL_HasWindowSurface(SDL_Window *window) +{ + CHECK_WINDOW_MAGIC(window, SDL_FALSE); + + return window->surface ? SDL_TRUE : SDL_FALSE; +} + +SDL_Surface *SDL_GetWindowSurface(SDL_Window *window) { CHECK_WINDOW_MAGIC(window, NULL); @@ -2335,7 +2774,9 @@ SDL_GetWindowSurface(SDL_Window * window) if (window->surface) { window->surface->flags &= ~SDL_DONTFREE; SDL_FreeSurface(window->surface); + window->surface = NULL; } + window->surface = SDL_CreateWindowFramebuffer(window); if (window->surface) { window->surface_valid = SDL_TRUE; @@ -2345,8 +2786,7 @@ SDL_GetWindowSurface(SDL_Window * window) return window->surface; } -int -SDL_UpdateWindowSurface(SDL_Window * window) +int SDL_UpdateWindowSurface(SDL_Window *window) { SDL_Rect full_rect; @@ -2354,14 +2794,13 @@ SDL_UpdateWindowSurface(SDL_Window * window) full_rect.x = 0; full_rect.y = 0; - full_rect.w = window->w; - full_rect.h = window->h; + SDL_GetWindowSizeInPixels(window, &full_rect.w, &full_rect.h); + return SDL_UpdateWindowSurfaceRects(window, &full_rect, 1); } -int -SDL_UpdateWindowSurfaceRects(SDL_Window * window, const SDL_Rect * rects, - int numrects) +int SDL_UpdateWindowSurfaceRects(SDL_Window *window, const SDL_Rect *rects, + int numrects) { CHECK_WINDOW_MAGIC(window, -1); @@ -2369,11 +2808,31 @@ SDL_UpdateWindowSurfaceRects(SDL_Window * window, const SDL_Rect * rects, return SDL_SetError("Window surface is invalid, please call SDL_GetWindowSurface() to get a new surface"); } + SDL_assert(_this->checked_texture_framebuffer); /* we should have done this before we had a valid surface. */ + return _this->UpdateWindowFramebuffer(_this, window, rects, numrects); } -int -SDL_SetWindowBrightness(SDL_Window * window, float brightness) +int SDL_DestroyWindowSurface(SDL_Window *window) +{ + CHECK_WINDOW_MAGIC(window, -1); + + if (window->surface) { + window->surface->flags &= ~SDL_DONTFREE; + SDL_FreeSurface(window->surface); + window->surface = NULL; + window->surface_valid = SDL_FALSE; + } + + if (_this->checked_texture_framebuffer) { /* never checked? No framebuffer to destroy. Don't risk calling the wrong implementation. */ + if (_this->DestroyWindowFramebuffer) { + _this->DestroyWindowFramebuffer(_this, window); + } + } + return 0; +} + +int SDL_SetWindowBrightness(SDL_Window * window, float brightness) { Uint16 ramp[256]; int status; @@ -2388,16 +2847,14 @@ SDL_SetWindowBrightness(SDL_Window * window, float brightness) return status; } -float -SDL_GetWindowBrightness(SDL_Window * window) +float SDL_GetWindowBrightness(SDL_Window * window) { CHECK_WINDOW_MAGIC(window, 1.0f); return window->brightness; } -int -SDL_SetWindowOpacity(SDL_Window * window, float opacity) +int SDL_SetWindowOpacity(SDL_Window * window, float opacity) { int retval; CHECK_WINDOW_MAGIC(window, -1); @@ -2420,8 +2877,7 @@ SDL_SetWindowOpacity(SDL_Window * window, float opacity) return retval; } -int -SDL_GetWindowOpacity(SDL_Window * window, float * out_opacity) +int SDL_GetWindowOpacity(SDL_Window *window, float *out_opacity) { CHECK_WINDOW_MAGIC(window, -1); @@ -2432,8 +2888,7 @@ SDL_GetWindowOpacity(SDL_Window * window, float * out_opacity) return 0; } -int -SDL_SetWindowModalFor(SDL_Window * modal_window, SDL_Window * parent_window) +int SDL_SetWindowModalFor(SDL_Window *modal_window, SDL_Window *parent_window) { CHECK_WINDOW_MAGIC(modal_window, -1); CHECK_WINDOW_MAGIC(parent_window, -1); @@ -2441,25 +2896,23 @@ SDL_SetWindowModalFor(SDL_Window * modal_window, SDL_Window * parent_window) if (!_this->SetWindowModalFor) { return SDL_Unsupported(); } - + return _this->SetWindowModalFor(_this, modal_window, parent_window); } -int -SDL_SetWindowInputFocus(SDL_Window * window) +int SDL_SetWindowInputFocus(SDL_Window *window) { CHECK_WINDOW_MAGIC(window, -1); if (!_this->SetWindowInputFocus) { return SDL_Unsupported(); } - + return _this->SetWindowInputFocus(_this, window); } -int -SDL_SetWindowGammaRamp(SDL_Window * window, const Uint16 * red, +int SDL_SetWindowGammaRamp(SDL_Window * window, const Uint16 * red, const Uint16 * green, const Uint16 * blue) { @@ -2492,8 +2945,7 @@ SDL_SetWindowGammaRamp(SDL_Window * window, const Uint16 * red, } } -int -SDL_GetWindowGammaRamp(SDL_Window * window, Uint16 * red, +int SDL_GetWindowGammaRamp(SDL_Window * window, Uint16 * red, Uint16 * green, Uint16 * blue) { @@ -2537,95 +2989,200 @@ SDL_GetWindowGammaRamp(SDL_Window * window, Uint16 * red, return 0; } -void -SDL_UpdateWindowGrab(SDL_Window * window) +void SDL_UpdateWindowGrab(SDL_Window * window) { - SDL_Window *grabbed_window; - SDL_bool grabbed; - if ((SDL_GetMouse()->relative_mode || (window->flags & SDL_WINDOW_INPUT_GRABBED)) && - (window->flags & SDL_WINDOW_INPUT_FOCUS)) { - grabbed = SDL_TRUE; + SDL_bool keyboard_grabbed, mouse_grabbed; + + if (window->flags & SDL_WINDOW_INPUT_FOCUS) { + if (SDL_GetMouse()->relative_mode || (window->flags & SDL_WINDOW_MOUSE_GRABBED)) { + mouse_grabbed = SDL_TRUE; + } else { + mouse_grabbed = SDL_FALSE; + } + + if (window->flags & SDL_WINDOW_KEYBOARD_GRABBED) { + keyboard_grabbed = SDL_TRUE; + } else { + keyboard_grabbed = SDL_FALSE; + } } else { - grabbed = SDL_FALSE; + mouse_grabbed = SDL_FALSE; + keyboard_grabbed = SDL_FALSE; } - grabbed_window = _this->grabbed_window; - if (grabbed) { - if (grabbed_window && (grabbed_window != window)) { + if (mouse_grabbed || keyboard_grabbed) { + if (_this->grabbed_window && (_this->grabbed_window != window)) { /* stealing a grab from another window! */ - grabbed_window->flags &= ~SDL_WINDOW_INPUT_GRABBED; - if (_this->SetWindowGrab) { - _this->SetWindowGrab(_this, grabbed_window, SDL_FALSE); + _this->grabbed_window->flags &= ~(SDL_WINDOW_MOUSE_GRABBED | SDL_WINDOW_KEYBOARD_GRABBED); + if (_this->SetWindowMouseGrab) { + _this->SetWindowMouseGrab(_this, _this->grabbed_window, SDL_FALSE); + } + if (_this->SetWindowKeyboardGrab) { + _this->SetWindowKeyboardGrab(_this, _this->grabbed_window, SDL_FALSE); } } _this->grabbed_window = window; - } else if (grabbed_window == window) { - _this->grabbed_window = NULL; /* ungrabbing. */ + } else if (_this->grabbed_window == window) { + _this->grabbed_window = NULL; /* ungrabbing input. */ } - if (_this->SetWindowGrab) { - _this->SetWindowGrab(_this, window, grabbed); + if (_this->SetWindowMouseGrab) { + _this->SetWindowMouseGrab(_this, window, mouse_grabbed); + } + if (_this->SetWindowKeyboardGrab) { + _this->SetWindowKeyboardGrab(_this, window, keyboard_grabbed); } } -void -SDL_SetWindowGrab(SDL_Window * window, SDL_bool grabbed) +void SDL_SetWindowGrab(SDL_Window *window, SDL_bool grabbed) { - CHECK_WINDOW_MAGIC(window,); + CHECK_WINDOW_MAGIC(window, ); - if (!!grabbed == !!(window->flags & SDL_WINDOW_INPUT_GRABBED)) { + SDL_SetWindowMouseGrab(window, grabbed); + + if (SDL_GetHintBoolean(SDL_HINT_GRAB_KEYBOARD, SDL_FALSE)) { + SDL_SetWindowKeyboardGrab(window, grabbed); + } +} + +void SDL_SetWindowKeyboardGrab(SDL_Window *window, SDL_bool grabbed) +{ + CHECK_WINDOW_MAGIC(window, ); + + if (!!grabbed == !!(window->flags & SDL_WINDOW_KEYBOARD_GRABBED)) { return; } if (grabbed) { - window->flags |= SDL_WINDOW_INPUT_GRABBED; + window->flags |= SDL_WINDOW_KEYBOARD_GRABBED; } else { - window->flags &= ~SDL_WINDOW_INPUT_GRABBED; + window->flags &= ~SDL_WINDOW_KEYBOARD_GRABBED; } SDL_UpdateWindowGrab(window); } -SDL_bool -SDL_GetWindowGrab(SDL_Window * window) +void SDL_SetWindowMouseGrab(SDL_Window *window, SDL_bool grabbed) +{ + CHECK_WINDOW_MAGIC(window, ); + + if (!!grabbed == !!(window->flags & SDL_WINDOW_MOUSE_GRABBED)) { + return; + } + if (grabbed) { + window->flags |= SDL_WINDOW_MOUSE_GRABBED; + } else { + window->flags &= ~SDL_WINDOW_MOUSE_GRABBED; + } + SDL_UpdateWindowGrab(window); +} + +SDL_bool SDL_GetWindowGrab(SDL_Window *window) +{ + return SDL_GetWindowKeyboardGrab(window) || SDL_GetWindowMouseGrab(window); +} + +SDL_bool SDL_GetWindowKeyboardGrab(SDL_Window *window) { CHECK_WINDOW_MAGIC(window, SDL_FALSE); - SDL_assert(!_this->grabbed_window || ((_this->grabbed_window->flags & SDL_WINDOW_INPUT_GRABBED) != 0)); - return window == _this->grabbed_window; + return window == _this->grabbed_window && (_this->grabbed_window->flags & SDL_WINDOW_KEYBOARD_GRABBED); } -SDL_Window * -SDL_GetGrabbedWindow(void) +SDL_bool SDL_GetWindowMouseGrab(SDL_Window *window) { - SDL_assert(!_this->grabbed_window || ((_this->grabbed_window->flags & SDL_WINDOW_INPUT_GRABBED) != 0)); - return _this->grabbed_window; + CHECK_WINDOW_MAGIC(window, SDL_FALSE); + return window == _this->grabbed_window && (_this->grabbed_window->flags & SDL_WINDOW_MOUSE_GRABBED); } -void -SDL_OnWindowShown(SDL_Window * window) +SDL_Window *SDL_GetGrabbedWindow(void) +{ + if (_this->grabbed_window && + (_this->grabbed_window->flags & (SDL_WINDOW_MOUSE_GRABBED | SDL_WINDOW_KEYBOARD_GRABBED))) { + return _this->grabbed_window; + } else { + return NULL; + } +} + +int SDL_SetWindowMouseRect(SDL_Window *window, const SDL_Rect *rect) +{ + CHECK_WINDOW_MAGIC(window, -1); + + if (rect) { + SDL_memcpy(&window->mouse_rect, rect, sizeof(*rect)); + } else { + SDL_zero(window->mouse_rect); + } + + if (_this->SetWindowMouseRect) { + _this->SetWindowMouseRect(_this, window); + } + return 0; +} + +const SDL_Rect *SDL_GetWindowMouseRect(SDL_Window *window) +{ + CHECK_WINDOW_MAGIC(window, NULL); + + if (SDL_RectEmpty(&window->mouse_rect)) { + return NULL; + } else { + return &window->mouse_rect; + } +} + +int SDL_FlashWindow(SDL_Window *window, SDL_FlashOperation operation) +{ + CHECK_WINDOW_MAGIC(window, -1); + + if (_this->FlashWindow) { + return _this->FlashWindow(_this, window, operation); + } + + return SDL_Unsupported(); +} + +void SDL_OnWindowShown(SDL_Window *window) { SDL_OnWindowRestored(window); } -void -SDL_OnWindowHidden(SDL_Window * window) +void SDL_OnWindowHidden(SDL_Window *window) { SDL_UpdateFullscreenMode(window, SDL_FALSE); } -void -SDL_OnWindowResized(SDL_Window * window) +void SDL_OnWindowResized(SDL_Window *window) { + int display_index = SDL_GetWindowDisplayIndex(window); window->surface_valid = SDL_FALSE; - SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SIZE_CHANGED, window->w, window->h); + + if (!window->is_destroying) { + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SIZE_CHANGED, window->w, window->h); + + if (display_index != window->display_index && display_index != -1) { + window->display_index = display_index; + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_DISPLAY_CHANGED, window->display_index, 0); + } + } } -void -SDL_OnWindowMinimized(SDL_Window * window) +void SDL_OnWindowMoved(SDL_Window *window) { - SDL_UpdateFullscreenMode(window, SDL_FALSE); + int display_index = SDL_GetWindowDisplayIndex(window); + + if (!window->is_destroying && display_index != window->display_index && display_index != -1) { + window->display_index = display_index; + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_DISPLAY_CHANGED, window->display_index, 0); + } } -void -SDL_OnWindowRestored(SDL_Window * window) +void SDL_OnWindowMinimized(SDL_Window *window) +{ + if (!DisableUnsetFullscreenOnMinimize(_this)) { + SDL_UpdateFullscreenMode(window, SDL_FALSE); + } +} + +void SDL_OnWindowRestored(SDL_Window *window) { /* * FIXME: Is this fine to just remove this, or should it be preserved just @@ -2640,21 +3197,18 @@ SDL_OnWindowRestored(SDL_Window * window) } } -void -SDL_OnWindowEnter(SDL_Window * window) +void SDL_OnWindowEnter(SDL_Window *window) { if (_this->OnWindowEnter) { _this->OnWindowEnter(_this, window); } } -void -SDL_OnWindowLeave(SDL_Window * window) +void SDL_OnWindowLeave(SDL_Window *window) { } -void -SDL_OnWindowFocusGained(SDL_Window * window) +void SDL_OnWindowFocusGained(SDL_Window *window) { SDL_Mouse *mouse = SDL_GetMouse(); @@ -2664,20 +3218,23 @@ SDL_OnWindowFocusGained(SDL_Window * window) if (mouse && mouse->relative_mode) { SDL_SetMouseFocus(window); - SDL_WarpMouseInWindow(window, window->w/2, window->h/2); + if (mouse->relative_mode_warp) { + SDL_PerformWarpMouseInWindow(window, window->w / 2, window->h / 2, SDL_TRUE); + } } SDL_UpdateWindowGrab(window); } -static SDL_bool -ShouldMinimizeOnFocusLoss(SDL_Window * window) +static SDL_bool ShouldMinimizeOnFocusLoss(SDL_Window *window) { + const char *hint; + if (!(window->flags & SDL_WINDOW_FULLSCREEN) || window->is_destroying) { return SDL_FALSE; } -#ifdef __MACOSX__ +#if defined(__MACOSX__) && defined(SDL_VIDEO_DRIVER_COCOA) if (SDL_strcmp(_this->name, "cocoa") == 0) { /* don't do this for X11, etc */ if (Cocoa_IsWindowInFullscreenSpace(window)) { return SDL_FALSE; @@ -2688,17 +3245,26 @@ ShouldMinimizeOnFocusLoss(SDL_Window * window) #ifdef __ANDROID__ { extern SDL_bool Android_JNI_ShouldMinimizeOnFocusLoss(void); - if (! Android_JNI_ShouldMinimizeOnFocusLoss()) { + if (!Android_JNI_ShouldMinimizeOnFocusLoss()) { return SDL_FALSE; } } #endif - return SDL_GetHintBoolean(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, SDL_TRUE); + /* Real fullscreen windows should minimize on focus loss so the desktop video mode is restored */ + hint = SDL_GetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS); + if (!hint || !*hint || SDL_strcasecmp(hint, "auto") == 0) { + if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP || + DisableDisplayModeSwitching(_this) == SDL_TRUE) { + return SDL_FALSE; + } else { + return SDL_TRUE; + } + } + return SDL_GetHintBoolean(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, SDL_FALSE); } -void -SDL_OnWindowFocusLost(SDL_Window * window) +void SDL_OnWindowFocusLost(SDL_Window *window) { if (window->gamma && _this->SetWindowGammaRamp) { _this->SetWindowGammaRamp(_this, window, window->saved_gamma); @@ -2713,8 +3279,7 @@ SDL_OnWindowFocusLost(SDL_Window * window) /* !!! FIXME: is this different than SDL_GetKeyboardFocus()? !!! FIXME: Also, SDL_GetKeyboardFocus() is O(1), this isn't. */ -SDL_Window * -SDL_GetFocusWindow(void) +SDL_Window *SDL_GetFocusWindow(void) { SDL_Window *window; @@ -2729,17 +3294,18 @@ SDL_GetFocusWindow(void) return NULL; } -void -SDL_DestroyWindow(SDL_Window * window) +void SDL_DestroyWindow(SDL_Window *window) { SDL_VideoDisplay *display; - CHECK_WINDOW_MAGIC(window,); + CHECK_WINDOW_MAGIC(window, ); window->is_destroying = SDL_TRUE; /* Restore video mode, etc. */ - SDL_HideWindow(window); + if (!(window->flags & SDL_WINDOW_FOREIGN)) { + SDL_HideWindow(window); + } /* Make sure this window no longer has focus */ if (SDL_GetKeyboardFocus() == window) { @@ -2749,20 +3315,15 @@ SDL_DestroyWindow(SDL_Window * window) SDL_SetMouseFocus(NULL); } - /* make no context current if this is the current context window. */ + SDL_DestroyWindowSurface(window); + + /* Make no context current if this is the current context window */ if (window->flags & SDL_WINDOW_OPENGL) { if (_this->current_glwin == window) { SDL_GL_MakeCurrent(window, NULL); } } - if (window->surface) { - window->surface->flags &= ~SDL_DONTFREE; - SDL_FreeSurface(window->surface); - } - if (_this->DestroyWindowFramebuffer) { - _this->DestroyWindowFramebuffer(_this, window); - } if (_this->DestroyWindow) { _this->DestroyWindow(_this, window); } @@ -2778,6 +3339,18 @@ SDL_DestroyWindow(SDL_Window * window) display->fullscreen_window = NULL; } + if (_this->grabbed_window == window) { + _this->grabbed_window = NULL; /* ungrabbing input. */ + } + + if (_this->current_glwin == window) { + _this->current_glwin = NULL; + } + + if (_this->wakeup_window == window) { + _this->wakeup_window = NULL; + } + /* Now invalidate magic */ window->magic = NULL; @@ -2806,8 +3379,7 @@ SDL_DestroyWindow(SDL_Window * window) SDL_free(window); } -SDL_bool -SDL_IsScreenSaverEnabled() +SDL_bool SDL_IsScreenSaverEnabled(void) { if (!_this) { return SDL_TRUE; @@ -2815,8 +3387,7 @@ SDL_IsScreenSaverEnabled() return _this->suspend_screensaver ? SDL_FALSE : SDL_TRUE; } -void -SDL_EnableScreenSaver() +void SDL_EnableScreenSaver(void) { if (!_this) { return; @@ -2830,8 +3401,7 @@ SDL_EnableScreenSaver() } } -void -SDL_DisableScreenSaver() +void SDL_DisableScreenSaver(void) { if (!_this) { return; @@ -2845,10 +3415,9 @@ SDL_DisableScreenSaver() } } -void -SDL_VideoQuit(void) +void SDL_VideoQuit(void) { - int i, j; + int i; if (!_this) { return; @@ -2870,33 +3439,23 @@ SDL_VideoQuit(void) for (i = 0; i < _this->num_displays; ++i) { SDL_VideoDisplay *display = &_this->displays[i]; - for (j = display->num_display_modes; j--;) { - SDL_free(display->display_modes[j].driverdata); - display->display_modes[j].driverdata = NULL; - } - SDL_free(display->display_modes); - display->display_modes = NULL; + SDL_ResetDisplayModes(i); SDL_free(display->desktop_mode.driverdata); - display->desktop_mode.driverdata = NULL; SDL_free(display->driverdata); - display->driverdata = NULL; - } - if (_this->displays) { - for (i = 0; i < _this->num_displays; ++i) { - SDL_free(_this->displays[i].name); - } - SDL_free(_this->displays); - _this->displays = NULL; - _this->num_displays = 0; + SDL_free(display->name); } + + SDL_free(_this->displays); + _this->displays = NULL; + _this->num_displays = 0; + SDL_free(_this->clipboard_text); _this->clipboard_text = NULL; _this->free(_this); _this = NULL; } -int -SDL_GL_LoadLibrary(const char *path) +int SDL_GL_LoadLibrary(const char *path) { int retval; @@ -2910,7 +3469,7 @@ SDL_GL_LoadLibrary(const char *path) retval = 0; } else { if (!_this->GL_LoadLibrary) { - return SDL_SetError("No dynamic GL support in current SDL video driver (%s)", _this->name); + return SDL_DllNotSupported("OpenGL"); } retval = _this->GL_LoadLibrary(_this, path); } @@ -2921,11 +3480,10 @@ SDL_GL_LoadLibrary(const char *path) _this->GL_UnloadLibrary(_this); } } - return (retval); + return retval; } -void * -SDL_GL_GetProcAddress(const char *proc) +void *SDL_GL_GetProcAddress(const char *proc) { void *func; @@ -2946,8 +3504,7 @@ SDL_GL_GetProcAddress(const char *proc) return func; } -void -SDL_GL_UnloadLibrary(void) +void SDL_GL_UnloadLibrary(void) { if (!_this) { SDL_UninitializedVideo(); @@ -2963,19 +3520,17 @@ SDL_GL_UnloadLibrary(void) } } -#if SDL_VIDEO_OPENGL || SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 -static SDL_INLINE SDL_bool -isAtLeastGL3(const char *verstr) +#if defined(SDL_VIDEO_OPENGL) || defined(SDL_VIDEO_OPENGL_ES) || defined(SDL_VIDEO_OPENGL_ES2) +static SDL_INLINE SDL_bool isAtLeastGL3(const char *verstr) { - return (verstr && (SDL_atoi(verstr) >= 3)); + return verstr && (SDL_atoi(verstr) >= 3); } #endif -SDL_bool -SDL_GL_ExtensionSupported(const char *extension) +SDL_bool SDL_GL_ExtensionSupported(const char *extension) { -#if SDL_VIDEO_OPENGL || SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 - const GLubyte *(APIENTRY * glGetStringFunc) (GLenum); +#if defined(SDL_VIDEO_OPENGL) || defined(SDL_VIDEO_OPENGL_ES) || defined(SDL_VIDEO_OPENGL_ES2) + const GLubyte *(APIENTRY * glGetStringFunc)(GLenum); const char *extensions; const char *start; const char *where, *terminator; @@ -2998,9 +3553,9 @@ SDL_GL_ExtensionSupported(const char *extension) return SDL_FALSE; } - if (isAtLeastGL3((const char *) glGetStringFunc(GL_VERSION))) { - const GLubyte *(APIENTRY * glGetStringiFunc) (GLenum, GLuint); - void (APIENTRY * glGetIntegervFunc) (GLenum pname, GLint * params); + if (isAtLeastGL3((const char *)glGetStringFunc(GL_VERSION))) { + const GLubyte *(APIENTRY * glGetStringiFunc)(GLenum, GLuint); + void(APIENTRY * glGetIntegervFunc)(GLenum pname, GLint * params); GLint num_exts = 0; GLint i; @@ -3010,12 +3565,12 @@ SDL_GL_ExtensionSupported(const char *extension) return SDL_FALSE; } - #ifndef GL_NUM_EXTENSIONS - #define GL_NUM_EXTENSIONS 0x821D - #endif +#ifndef GL_NUM_EXTENSIONS +#define GL_NUM_EXTENSIONS 0x821D +#endif glGetIntegervFunc(GL_NUM_EXTENSIONS, &num_exts); for (i = 0; i < num_exts; i++) { - const char *thisext = (const char *) glGetStringiFunc(GL_EXTENSIONS, i); + const char *thisext = (const char *)glGetStringiFunc(GL_EXTENSIONS, i); if (SDL_strcmp(thisext, extension) == 0) { return SDL_TRUE; } @@ -3026,7 +3581,7 @@ SDL_GL_ExtensionSupported(const char *extension) /* Try the old way with glGetString(GL_EXTENSIONS) ... */ - extensions = (const char *) glGetStringFunc(GL_EXTENSIONS); + extensions = (const char *)glGetStringFunc(GL_EXTENSIONS); if (!extensions) { return SDL_FALSE; } @@ -3039,13 +3594,16 @@ SDL_GL_ExtensionSupported(const char *extension) for (;;) { where = SDL_strstr(start, extension); - if (!where) + if (!where) { break; + } terminator = where + SDL_strlen(extension); - if (where == extensions || *(where - 1) == ' ') - if (*terminator == ' ' || *terminator == '\0') + if (where == extensions || *(where - 1) == ' ') { + if (*terminator == ' ' || *terminator == '\0') { return SDL_TRUE; + } + } start = terminator; } @@ -3057,16 +3615,15 @@ SDL_GL_ExtensionSupported(const char *extension) /* Deduce supported ES profile versions from the supported ARB_ES*_compatibility extensions. There is no direct query. - + This is normally only called when the OpenGL driver supports {GLX,WGL}_EXT_create_context_es2_profile. */ -void -SDL_GL_DeduceMaxSupportedESProfile(int* major, int* minor) +void SDL_GL_DeduceMaxSupportedESProfile(int *major, int *minor) { /* THIS REQUIRES AN EXISTING GL CONTEXT THAT HAS BEEN MADE CURRENT. */ /* Please refer to https://bugzilla.libsdl.org/show_bug.cgi?id=3725 for discussion. */ -#if SDL_VIDEO_OPENGL || SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 +#if defined(SDL_VIDEO_OPENGL) || defined(SDL_VIDEO_OPENGL_ES) || defined(SDL_VIDEO_OPENGL_ES2) /* XXX This is fragile; it will break in the event of release of * new versions of OpenGL ES. */ @@ -3086,8 +3643,7 @@ SDL_GL_DeduceMaxSupportedESProfile(int* major, int* minor) #endif } -void -SDL_GL_ResetAttributes() +void SDL_GL_ResetAttributes(void) { if (!_this) { return; @@ -3108,27 +3664,28 @@ SDL_GL_ResetAttributes() _this->gl_config.stereo = 0; _this->gl_config.multisamplebuffers = 0; _this->gl_config.multisamplesamples = 0; + _this->gl_config.floatbuffers = 0; _this->gl_config.retained_backing = 1; - _this->gl_config.accelerated = -1; /* accelerated or not, both are fine */ + _this->gl_config.accelerated = -1; /* accelerated or not, both are fine */ + +#ifdef SDL_VIDEO_OPENGL + _this->gl_config.major_version = 2; + _this->gl_config.minor_version = 1; + _this->gl_config.profile_mask = 0; +#elif defined(SDL_VIDEO_OPENGL_ES2) + _this->gl_config.major_version = 2; + _this->gl_config.minor_version = 0; + _this->gl_config.profile_mask = SDL_GL_CONTEXT_PROFILE_ES; +#elif defined(SDL_VIDEO_OPENGL_ES) + _this->gl_config.major_version = 1; + _this->gl_config.minor_version = 1; + _this->gl_config.profile_mask = SDL_GL_CONTEXT_PROFILE_ES; +#endif if (_this->GL_DefaultProfileConfig) { _this->GL_DefaultProfileConfig(_this, &_this->gl_config.profile_mask, &_this->gl_config.major_version, &_this->gl_config.minor_version); - } else { -#if SDL_VIDEO_OPENGL - _this->gl_config.major_version = 2; - _this->gl_config.minor_version = 1; - _this->gl_config.profile_mask = 0; -#elif SDL_VIDEO_OPENGL_ES2 - _this->gl_config.major_version = 2; - _this->gl_config.minor_version = 0; - _this->gl_config.profile_mask = SDL_GL_CONTEXT_PROFILE_ES; -#elif SDL_VIDEO_OPENGL_ES - _this->gl_config.major_version = 1; - _this->gl_config.minor_version = 1; - _this->gl_config.profile_mask = SDL_GL_CONTEXT_PROFILE_ES; -#endif } _this->gl_config.flags = 0; @@ -3140,10 +3697,9 @@ SDL_GL_ResetAttributes() _this->gl_config.share_with_current_context = 0; } -int -SDL_GL_SetAttribute(SDL_GLattr attr, int value) +int SDL_GL_SetAttribute(SDL_GLattr attr, int value) { -#if SDL_VIDEO_OPENGL || SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 +#if defined(SDL_VIDEO_OPENGL) || defined(SDL_VIDEO_OPENGL_ES) || defined(SDL_VIDEO_OPENGL_ES2) int retval; if (!_this) { @@ -3196,6 +3752,9 @@ SDL_GL_SetAttribute(SDL_GLattr attr, int value) case SDL_GL_MULTISAMPLESAMPLES: _this->gl_config.multisamplesamples = value; break; + case SDL_GL_FLOATBUFFERS: + _this->gl_config.floatbuffers = value; + break; case SDL_GL_ACCELERATED_VISUAL: _this->gl_config.accelerated = value; break; @@ -3214,7 +3773,7 @@ SDL_GL_SetAttribute(SDL_GLattr attr, int value) SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); } else { SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, 0); - }; + } break; case SDL_GL_CONTEXT_FLAGS: if (value & ~(SDL_GL_CONTEXT_DEBUG_FLAG | @@ -3261,11 +3820,10 @@ SDL_GL_SetAttribute(SDL_GLattr attr, int value) #endif /* SDL_VIDEO_OPENGL */ } -int -SDL_GL_GetAttribute(SDL_GLattr attr, int *value) +int SDL_GL_GetAttribute(SDL_GLattr attr, int *value) { -#if SDL_VIDEO_OPENGL || SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 - GLenum (APIENTRY *glGetErrorFunc) (void); +#if defined(SDL_VIDEO_OPENGL) || defined(SDL_VIDEO_OPENGL_ES) || defined(SDL_VIDEO_OPENGL_ES2) + GLenum(APIENTRY * glGetErrorFunc)(void); GLenum attrib = 0; GLenum error = 0; @@ -3275,9 +3833,9 @@ SDL_GL_GetAttribute(SDL_GLattr attr, int *value) * the enums we use for the former function don't exist in OpenGL ES 2, and * the function itself doesn't exist prior to OpenGL 3 and OpenGL ES 2. */ -#if SDL_VIDEO_OPENGL - const GLubyte *(APIENTRY *glGetStringFunc) (GLenum name); - void (APIENTRY *glGetFramebufferAttachmentParameterivFunc) (GLenum target, GLenum attachment, GLenum pname, GLint* params); +#ifdef SDL_VIDEO_OPENGL + const GLubyte *(APIENTRY * glGetStringFunc)(GLenum name); + void(APIENTRY * glGetFramebufferAttachmentParameterivFunc)(GLenum target, GLenum attachment, GLenum pname, GLint * params); GLenum attachment = GL_BACK_LEFT; GLenum attachmentattrib = 0; #endif @@ -3295,31 +3853,31 @@ SDL_GL_GetAttribute(SDL_GLattr attr, int *value) switch (attr) { case SDL_GL_RED_SIZE: -#if SDL_VIDEO_OPENGL +#ifdef SDL_VIDEO_OPENGL attachmentattrib = GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE; #endif attrib = GL_RED_BITS; break; case SDL_GL_BLUE_SIZE: -#if SDL_VIDEO_OPENGL +#ifdef SDL_VIDEO_OPENGL attachmentattrib = GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE; #endif attrib = GL_BLUE_BITS; break; case SDL_GL_GREEN_SIZE: -#if SDL_VIDEO_OPENGL +#ifdef SDL_VIDEO_OPENGL attachmentattrib = GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE; #endif attrib = GL_GREEN_BITS; break; case SDL_GL_ALPHA_SIZE: -#if SDL_VIDEO_OPENGL +#ifdef SDL_VIDEO_OPENGL attachmentattrib = GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE; #endif attrib = GL_ALPHA_BITS; break; case SDL_GL_DOUBLEBUFFER: -#if SDL_VIDEO_OPENGL +#ifdef SDL_VIDEO_OPENGL attrib = GL_DOUBLEBUFFER; break; #else @@ -3330,20 +3888,20 @@ SDL_GL_GetAttribute(SDL_GLattr attr, int *value) return 0; #endif case SDL_GL_DEPTH_SIZE: -#if SDL_VIDEO_OPENGL +#ifdef SDL_VIDEO_OPENGL attachment = GL_DEPTH; attachmentattrib = GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE; #endif attrib = GL_DEPTH_BITS; break; case SDL_GL_STENCIL_SIZE: -#if SDL_VIDEO_OPENGL +#ifdef SDL_VIDEO_OPENGL attachment = GL_STENCIL; attachmentattrib = GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE; #endif attrib = GL_STENCIL_BITS; break; -#if SDL_VIDEO_OPENGL +#ifdef SDL_VIDEO_OPENGL case SDL_GL_ACCUM_RED_SIZE: attrib = GL_ACCUM_RED_BITS; break; @@ -3376,85 +3934,84 @@ SDL_GL_GetAttribute(SDL_GLattr attr, int *value) attrib = GL_SAMPLES; break; case SDL_GL_CONTEXT_RELEASE_BEHAVIOR: -#if SDL_VIDEO_OPENGL +#ifdef SDL_VIDEO_OPENGL attrib = GL_CONTEXT_RELEASE_BEHAVIOR; #else attrib = GL_CONTEXT_RELEASE_BEHAVIOR_KHR; #endif break; case SDL_GL_BUFFER_SIZE: - { - int rsize = 0, gsize = 0, bsize = 0, asize = 0; + { + int rsize = 0, gsize = 0, bsize = 0, asize = 0; - /* There doesn't seem to be a single flag in OpenGL for this! */ - if (SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &rsize) < 0) { - return -1; - } - if (SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &gsize) < 0) { - return -1; - } - if (SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &bsize) < 0) { - return -1; - } - if (SDL_GL_GetAttribute(SDL_GL_ALPHA_SIZE, &asize) < 0) { - return -1; - } - - *value = rsize + gsize + bsize + asize; - return 0; + /* There doesn't seem to be a single flag in OpenGL for this! */ + if (SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &rsize) < 0) { + return -1; } + if (SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &gsize) < 0) { + return -1; + } + if (SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &bsize) < 0) { + return -1; + } + if (SDL_GL_GetAttribute(SDL_GL_ALPHA_SIZE, &asize) < 0) { + return -1; + } + + *value = rsize + gsize + bsize + asize; + return 0; + } case SDL_GL_ACCELERATED_VISUAL: - { - /* FIXME: How do we get this information? */ - *value = (_this->gl_config.accelerated != 0); - return 0; - } + { + /* FIXME: How do we get this information? */ + *value = (_this->gl_config.accelerated != 0); + return 0; + } case SDL_GL_RETAINED_BACKING: - { - *value = _this->gl_config.retained_backing; - return 0; - } + { + *value = _this->gl_config.retained_backing; + return 0; + } case SDL_GL_CONTEXT_MAJOR_VERSION: - { - *value = _this->gl_config.major_version; - return 0; - } + { + *value = _this->gl_config.major_version; + return 0; + } case SDL_GL_CONTEXT_MINOR_VERSION: - { - *value = _this->gl_config.minor_version; - return 0; - } + { + *value = _this->gl_config.minor_version; + return 0; + } case SDL_GL_CONTEXT_EGL: /* FIXME: SDL_GL_CONTEXT_EGL to be deprecated in SDL 2.1 */ { if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) { *value = 1; - } - else { + } else { *value = 0; } return 0; } case SDL_GL_CONTEXT_FLAGS: - { - *value = _this->gl_config.flags; - return 0; - } + { + *value = _this->gl_config.flags; + return 0; + } case SDL_GL_CONTEXT_PROFILE_MASK: - { - *value = _this->gl_config.profile_mask; - return 0; - } + { + *value = _this->gl_config.profile_mask; + return 0; + } case SDL_GL_SHARE_WITH_CURRENT_CONTEXT: - { - *value = _this->gl_config.share_with_current_context; - return 0; - } + { + *value = _this->gl_config.share_with_current_context; + return 0; + } case SDL_GL_FRAMEBUFFER_SRGB_CAPABLE: - { - *value = _this->gl_config.framebuffer_srgb_capable; - return 0; - } + { + *value = _this->gl_config.framebuffer_srgb_capable; + return 0; + } case SDL_GL_CONTEXT_NO_ERROR: { *value = _this->gl_config.no_error; @@ -3464,27 +4021,40 @@ SDL_GL_GetAttribute(SDL_GLattr attr, int *value) return SDL_SetError("Unknown OpenGL attribute"); } -#if SDL_VIDEO_OPENGL +#ifdef SDL_VIDEO_OPENGL glGetStringFunc = SDL_GL_GetProcAddress("glGetString"); if (!glGetStringFunc) { return -1; } - if (attachmentattrib && isAtLeastGL3((const char *) glGetStringFunc(GL_VERSION))) { - glGetFramebufferAttachmentParameterivFunc = SDL_GL_GetProcAddress("glGetFramebufferAttachmentParameteriv"); + if (attachmentattrib && isAtLeastGL3((const char *)glGetStringFunc(GL_VERSION))) { + /* glGetFramebufferAttachmentParameteriv needs to operate on the window framebuffer for this, so bind FBO 0 if necessary. */ + GLint current_fbo = 0; + void(APIENTRY * glGetIntegervFunc)(GLenum pname, GLint * params) = SDL_GL_GetProcAddress("glGetIntegerv"); + void(APIENTRY * glBindFramebufferFunc)(GLenum target, GLuint fbo) = SDL_GL_GetProcAddress("glBindFramebuffer"); + if (glGetIntegervFunc && glBindFramebufferFunc) { + glGetIntegervFunc(GL_DRAW_FRAMEBUFFER_BINDING, ¤t_fbo); + } + glGetFramebufferAttachmentParameterivFunc = SDL_GL_GetProcAddress("glGetFramebufferAttachmentParameteriv"); if (glGetFramebufferAttachmentParameterivFunc) { - glGetFramebufferAttachmentParameterivFunc(GL_FRAMEBUFFER, attachment, attachmentattrib, (GLint *) value); + if (glBindFramebufferFunc && (current_fbo != 0)) { + glBindFramebufferFunc(GL_DRAW_FRAMEBUFFER, 0); + } + glGetFramebufferAttachmentParameterivFunc(GL_FRAMEBUFFER, attachment, attachmentattrib, (GLint *)value); + if (glBindFramebufferFunc && (current_fbo != 0)) { + glBindFramebufferFunc(GL_DRAW_FRAMEBUFFER, current_fbo); + } } else { return -1; } } else #endif { - void (APIENTRY *glGetIntegervFunc) (GLenum pname, GLint * params); + void(APIENTRY * glGetIntegervFunc)(GLenum pname, GLint * params); glGetIntegervFunc = SDL_GL_GetProcAddress("glGetIntegerv"); if (glGetIntegervFunc) { - glGetIntegervFunc(attrib, (GLint *) value); + glGetIntegervFunc(attrib, (GLint *)value); } else { return -1; } @@ -3510,14 +4080,15 @@ SDL_GL_GetAttribute(SDL_GLattr attr, int *value) #endif /* SDL_VIDEO_OPENGL */ } -SDL_GLContext -SDL_GL_CreateContext(SDL_Window * window) +#define NOT_AN_OPENGL_WINDOW "The specified window isn't an OpenGL window" + +SDL_GLContext SDL_GL_CreateContext(SDL_Window *window) { SDL_GLContext ctx = NULL; CHECK_WINDOW_MAGIC(window, NULL); if (!(window->flags & SDL_WINDOW_OPENGL)) { - SDL_SetError("The specified window isn't an OpenGL window"); + SDL_SetError(NOT_AN_OPENGL_WINDOW); return NULL; } @@ -3533,39 +4104,43 @@ SDL_GL_CreateContext(SDL_Window * window) return ctx; } -int -SDL_GL_MakeCurrent(SDL_Window * window, SDL_GLContext ctx) +int SDL_GL_MakeCurrent(SDL_Window *window, SDL_GLContext context) { int retval; + if (!_this) { + return SDL_UninitializedVideo(); + } + if (window == SDL_GL_GetCurrentWindow() && - ctx == SDL_GL_GetCurrentContext()) { + context == SDL_GL_GetCurrentContext()) { /* We're already current. */ return 0; } - if (!ctx) { + if (!context) { window = NULL; - } else { + } else if (window) { CHECK_WINDOW_MAGIC(window, -1); if (!(window->flags & SDL_WINDOW_OPENGL)) { - return SDL_SetError("The specified window isn't an OpenGL window"); + return SDL_SetError(NOT_AN_OPENGL_WINDOW); } + } else if (!_this->gl_allow_no_surface) { + return SDL_SetError("Use of OpenGL without a window is not supported on this platform"); } - retval = _this->GL_MakeCurrent(_this, window, ctx); + retval = _this->GL_MakeCurrent(_this, window, context); if (retval == 0) { _this->current_glwin = window; - _this->current_glctx = ctx; + _this->current_glctx = context; SDL_TLSSet(_this->current_glwin_tls, window, NULL); - SDL_TLSSet(_this->current_glctx_tls, ctx, NULL); + SDL_TLSSet(_this->current_glctx_tls, context, NULL); } return retval; } -SDL_Window * -SDL_GL_GetCurrentWindow(void) +SDL_Window *SDL_GL_GetCurrentWindow(void) { if (!_this) { SDL_UninitializedVideo(); @@ -3574,8 +4149,7 @@ SDL_GL_GetCurrentWindow(void) return (SDL_Window *)SDL_TLSGet(_this->current_glwin_tls); } -SDL_GLContext -SDL_GL_GetCurrentContext(void) +SDL_GLContext SDL_GL_GetCurrentContext(void) { if (!_this) { SDL_UninitializedVideo(); @@ -3586,17 +4160,16 @@ SDL_GL_GetCurrentContext(void) void SDL_GL_GetDrawableSize(SDL_Window * window, int *w, int *h) { - CHECK_WINDOW_MAGIC(window,); + CHECK_WINDOW_MAGIC(window, ); if (_this->GL_GetDrawableSize) { _this->GL_GetDrawableSize(_this, window, w, h); } else { - SDL_GetWindowSize(window, w, h); + SDL_GetWindowSizeInPixels(window, w, h); } } -int -SDL_GL_SetSwapInterval(int interval) +int SDL_GL_SetSwapInterval(int interval) { if (!_this) { return SDL_UninitializedVideo(); @@ -3609,8 +4182,7 @@ SDL_GL_SetSwapInterval(int interval) } } -int -SDL_GL_GetSwapInterval(void) +int SDL_GL_GetSwapInterval(void) { if (!_this) { return 0; @@ -3623,26 +4195,27 @@ SDL_GL_GetSwapInterval(void) } } -void -SDL_GL_SwapWindow(SDL_Window * window) +int SDL_GL_SwapWindowWithResult(SDL_Window *window) { - CHECK_WINDOW_MAGIC(window,); + CHECK_WINDOW_MAGIC(window, -1); if (!(window->flags & SDL_WINDOW_OPENGL)) { - SDL_SetError("The specified window isn't an OpenGL window"); - return; + return SDL_SetError(NOT_AN_OPENGL_WINDOW); } if (SDL_GL_GetCurrentWindow() != window) { - SDL_SetError("The specified window has not been made current"); - return; + return SDL_SetError("The specified window has not been made current"); } - _this->GL_SwapWindow(_this, window); + return _this->GL_SwapWindow(_this, window); } -void -SDL_GL_DeleteContext(SDL_GLContext context) +void SDL_GL_SwapWindow(SDL_Window *window) +{ + SDL_GL_SwapWindowWithResult(window); +} + +void SDL_GL_DeleteContext(SDL_GLContext context) { if (!_this || !context) { return; @@ -3655,18 +4228,17 @@ SDL_GL_DeleteContext(SDL_GLContext context) _this->GL_DeleteContext(_this, context); } -#if 0 /* FIXME */ +#if 0 /* FIXME */ /* * Utility function used by SDL_WM_SetIcon(); flags & 1 for color key, flags * & 2 for alpha channel. */ -static void -CreateMaskFromColorKeyOrAlpha(SDL_Surface * icon, Uint8 * mask, int flags) +static void CreateMaskFromColorKeyOrAlpha(SDL_Surface * icon, Uint8 * mask, int flags) { int x, y; Uint32 colorkey; #define SET_MASKBIT(icon, x, y, mask) \ - mask[(y*((icon->w+7)/8))+(x/8)] &= ~(0x01<<(7-(x%8))) + mask[(y * ((icon->w + 7) / 8)) + (x / 8)] &= ~(0x01 << (7 - (x % 8))) colorkey = icon->format->colorkey; switch (icon->format->BytesPerPixel) { @@ -3725,8 +4297,7 @@ CreateMaskFromColorKeyOrAlpha(SDL_Surface * icon, Uint8 * mask, int flags) /* * Sets the window manager icon for the display window. */ -void -SDL_WM_SetIcon(SDL_Surface * icon, Uint8 * mask) +void SDL_WM_SetIcon(SDL_Surface * icon, Uint8 * mask) { if (icon && _this->SetIcon) { /* Generate a mask if necessary, and create the icon! */ @@ -3754,8 +4325,7 @@ SDL_WM_SetIcon(SDL_Surface * icon, Uint8 * mask) } #endif -SDL_bool -SDL_GetWindowWMInfo(SDL_Window * window, struct SDL_SysWMinfo *info) +SDL_bool SDL_GetWindowWMInfo(SDL_Window * window, struct SDL_SysWMinfo *info) { CHECK_WINDOW_MAGIC(window, SDL_FALSE); @@ -3772,19 +4342,20 @@ SDL_GetWindowWMInfo(SDL_Window * window, struct SDL_SysWMinfo *info) return (_this->GetWindowWMInfo(_this, window, info)); } -void -SDL_StartTextInput(void) +void SDL_StartTextInput(void) { SDL_Window *window; /* First, enable text events */ - SDL_EventState(SDL_TEXTINPUT, SDL_ENABLE); - SDL_EventState(SDL_TEXTEDITING, SDL_ENABLE); + (void)SDL_EventState(SDL_TEXTINPUT, SDL_ENABLE); + (void)SDL_EventState(SDL_TEXTEDITING, SDL_ENABLE); /* Then show the on-screen keyboard, if any */ - window = SDL_GetFocusWindow(); - if (window && _this && _this->ShowScreenKeyboard) { - _this->ShowScreenKeyboard(_this, window); + if (SDL_GetHintBoolean(SDL_HINT_ENABLE_SCREEN_KEYBOARD, SDL_TRUE)) { + window = SDL_GetFocusWindow(); + if (window && _this && _this->ShowScreenKeyboard) { + _this->ShowScreenKeyboard(_this, window); + } } /* Finally start the text input system */ @@ -3793,14 +4364,28 @@ SDL_StartTextInput(void) } } -SDL_bool -SDL_IsTextInputActive(void) +void SDL_ClearComposition(void) { - return (SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE); + if (_this && _this->ClearComposition) { + _this->ClearComposition(_this); + } } -void -SDL_StopTextInput(void) +SDL_bool SDL_IsTextInputShown(void) +{ + if (_this && _this->IsTextInputShown) { + return _this->IsTextInputShown(_this); + } + + return SDL_FALSE; +} + +SDL_bool SDL_IsTextInputActive(void) +{ + return SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE; +} + +void SDL_StopTextInput(void) { SDL_Window *window; @@ -3810,26 +4395,26 @@ SDL_StopTextInput(void) } /* Hide the on-screen keyboard, if any */ - window = SDL_GetFocusWindow(); - if (window && _this && _this->HideScreenKeyboard) { - _this->HideScreenKeyboard(_this, window); + if (SDL_GetHintBoolean(SDL_HINT_ENABLE_SCREEN_KEYBOARD, SDL_TRUE)) { + window = SDL_GetFocusWindow(); + if (window && _this && _this->HideScreenKeyboard) { + _this->HideScreenKeyboard(_this, window); + } } /* Finally disable text events */ - SDL_EventState(SDL_TEXTINPUT, SDL_DISABLE); - SDL_EventState(SDL_TEXTEDITING, SDL_DISABLE); + (void)SDL_EventState(SDL_TEXTINPUT, SDL_DISABLE); + (void)SDL_EventState(SDL_TEXTEDITING, SDL_DISABLE); } -void -SDL_SetTextInputRect(SDL_Rect *rect) +void SDL_SetTextInputRect(const SDL_Rect *rect) { if (_this && _this->SetTextInputRect) { _this->SetTextInputRect(_this, rect); } } -SDL_bool -SDL_HasScreenKeyboardSupport(void) +SDL_bool SDL_HasScreenKeyboardSupport(void) { if (_this && _this->HasScreenKeyboardSupport) { return _this->HasScreenKeyboardSupport(_this); @@ -3837,8 +4422,7 @@ SDL_HasScreenKeyboardSupport(void) return SDL_FALSE; } -SDL_bool -SDL_IsScreenKeyboardShown(SDL_Window *window) +SDL_bool SDL_IsScreenKeyboardShown(SDL_Window *window) { if (window && _this && _this->IsScreenKeyboardShown) { return _this->IsScreenKeyboardShown(_this, window); @@ -3846,57 +4430,19 @@ SDL_IsScreenKeyboardShown(SDL_Window *window) return SDL_FALSE; } -#if SDL_VIDEO_DRIVER_ANDROID -#include "android/SDL_androidmessagebox.h" -#endif -#if SDL_VIDEO_DRIVER_WINDOWS -#include "windows/SDL_windowsmessagebox.h" -#endif -#if SDL_VIDEO_DRIVER_WINRT -#include "winrt/SDL_winrtmessagebox.h" -#endif -#if SDL_VIDEO_DRIVER_COCOA -#include "cocoa/SDL_cocoamessagebox.h" -#endif -#if SDL_VIDEO_DRIVER_UIKIT -#include "uikit/SDL_uikitmessagebox.h" -#endif -#if SDL_VIDEO_DRIVER_X11 -#include "x11/SDL_x11messagebox.h" -#endif -#if SDL_VIDEO_DRIVER_HAIKU -#include "haiku/SDL_bmessagebox.h" -#endif - - -#if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT || SDL_VIDEO_DRIVER_COCOA || SDL_VIDEO_DRIVER_UIKIT || SDL_VIDEO_DRIVER_X11 || SDL_VIDEO_DRIVER_HAIKU -static SDL_bool SDL_MessageboxValidForDriver(const SDL_MessageBoxData *messageboxdata, SDL_SYSWM_TYPE drivertype) +int SDL_GetMessageBoxCount(void) { - SDL_SysWMinfo info; - SDL_Window *window = messageboxdata->window; - - if (!window) { - return SDL_TRUE; - } - - SDL_VERSION(&info.version); - if (!SDL_GetWindowWMInfo(window, &info)) { - return SDL_TRUE; - } else { - return (info.subsystem == drivertype); - } + return SDL_AtomicGet(&SDL_messagebox_count); } -#endif -int -SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) +int SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) { int dummybutton; int retval = -1; SDL_bool relative_mode; int show_cursor_prev; - SDL_bool mouse_captured; SDL_Window *current_window; + SDL_MessageBoxData mbdata; if (!messageboxdata) { return SDL_InvalidParamError("messageboxdata"); @@ -3904,10 +4450,11 @@ SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) return SDL_SetError("Invalid number of buttons"); } + (void)SDL_AtomicIncRef(&SDL_messagebox_count); + current_window = SDL_GetKeyboardFocus(); - mouse_captured = current_window && ((SDL_GetWindowFlags(current_window) & SDL_WINDOW_MOUSE_CAPTURE) != 0); relative_mode = SDL_GetRelativeMouseMode(); - SDL_CaptureMouse(SDL_FALSE); + SDL_UpdateMouseCapture(SDL_FALSE); SDL_SetRelativeMouseMode(SDL_FALSE); show_cursor_prev = SDL_ShowCursor(1); SDL_ResetKeyboard(); @@ -3916,87 +4463,89 @@ SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) buttonid = &dummybutton; } + SDL_memcpy(&mbdata, messageboxdata, sizeof(*messageboxdata)); + if (!mbdata.title) { + mbdata.title = ""; + } + if (!mbdata.message) { + mbdata.message = ""; + } + messageboxdata = &mbdata; + + SDL_ClearError(); + if (_this && _this->ShowMessageBox) { retval = _this->ShowMessageBox(_this, messageboxdata, buttonid); + } else { + /* It's completely fine to call this function before video is initialized */ + const char *driver_name = SDL_GetHint(SDL_HINT_VIDEODRIVER); + int i; + if (driver_name && *driver_name != 0) { + const char *driver_attempt = driver_name; + while (driver_attempt && (*driver_attempt != 0) && (retval == -1)) { + const char *driver_attempt_end = SDL_strchr(driver_attempt, ','); + size_t driver_attempt_len = (driver_attempt_end) ? (driver_attempt_end - driver_attempt) + : SDL_strlen(driver_attempt); + for (i = 0; bootstrap[i]; ++i) { + if (bootstrap[i]->ShowMessageBox && (driver_attempt_len == SDL_strlen(bootstrap[i]->name)) && + (SDL_strncasecmp(bootstrap[i]->name, driver_attempt, driver_attempt_len) == 0)) { + if (bootstrap[i]->ShowMessageBox(messageboxdata, buttonid) == 0) { + retval = 0; + } + break; + } + } + + driver_attempt = (driver_attempt_end) ? (driver_attempt_end + 1) : NULL; + } + } else { + for (i = 0; bootstrap[i]; ++i) { + if (bootstrap[i]->ShowMessageBox && bootstrap[i]->ShowMessageBox(messageboxdata, buttonid) == 0) { + retval = 0; + break; + } + } + } } - /* It's completely fine to call this function before video is initialized */ -#if SDL_VIDEO_DRIVER_ANDROID - if (retval == -1 && - Android_ShowMessageBox(messageboxdata, buttonid) == 0) { - retval = 0; - } -#endif -#if SDL_VIDEO_DRIVER_WINDOWS - if (retval == -1 && - SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_WINDOWS) && - WIN_ShowMessageBox(messageboxdata, buttonid) == 0) { - retval = 0; - } -#endif -#if SDL_VIDEO_DRIVER_WINRT - if (retval == -1 && - SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_WINRT) && - WINRT_ShowMessageBox(messageboxdata, buttonid) == 0) { - retval = 0; - } -#endif -#if SDL_VIDEO_DRIVER_COCOA - if (retval == -1 && - SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_COCOA) && - Cocoa_ShowMessageBox(messageboxdata, buttonid) == 0) { - retval = 0; - } -#endif -#if SDL_VIDEO_DRIVER_UIKIT - if (retval == -1 && - SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_UIKIT) && - UIKit_ShowMessageBox(messageboxdata, buttonid) == 0) { - retval = 0; - } -#endif -#if SDL_VIDEO_DRIVER_X11 - if (retval == -1 && - SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_X11) && - X11_ShowMessageBox(messageboxdata, buttonid) == 0) { - retval = 0; - } -#endif -#if SDL_VIDEO_DRIVER_HAIKU - if (retval == -1 && - SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_HAIKU) && - HAIKU_ShowMessageBox(messageboxdata, buttonid) == 0) { - retval = 0; - } -#endif if (retval == -1) { - SDL_SetError("No message system available"); + const char *error = SDL_GetError(); + + if (!*error) { + SDL_SetError("No message system available"); + } } + (void)SDL_AtomicDecRef(&SDL_messagebox_count); + if (current_window) { SDL_RaiseWindow(current_window); - if (mouse_captured) { - SDL_CaptureMouse(SDL_TRUE); - } } SDL_ShowCursor(show_cursor_prev); SDL_SetRelativeMouseMode(relative_mode); + SDL_UpdateMouseCapture(SDL_FALSE); return retval; } -int -SDL_ShowSimpleMessageBox(Uint32 flags, const char *title, const char *message, SDL_Window *window) +int SDL_ShowSimpleMessageBox(Uint32 flags, const char *title, const char *message, SDL_Window *window) { #ifdef __EMSCRIPTEN__ /* !!! FIXME: propose a browser API for this, get this #ifdef out of here? */ /* Web browsers don't (currently) have an API for a custom message box that can block, but for the most common case (SDL_ShowSimpleMessageBox), we can use the standard Javascript alert() function. */ - EM_ASM_({ + if (!title) { + title = ""; + } + if (!message) { + message = ""; + } + EM_ASM({ alert(UTF8ToString($0) + "\n\n" + UTF8ToString($1)); - }, title, message); + }, + title, message); return 0; #else SDL_MessageBoxData data; @@ -4019,14 +4568,12 @@ SDL_ShowSimpleMessageBox(Uint32 flags, const char *title, const char *message, S #endif } -SDL_bool -SDL_ShouldAllowTopmost(void) +SDL_bool SDL_ShouldAllowTopmost(void) { return SDL_GetHintBoolean(SDL_HINT_ALLOW_TOPMOST, SDL_TRUE); } -int -SDL_SetWindowHitTest(SDL_Window * window, SDL_HitTest callback, void *userdata) +int SDL_SetWindowHitTest(SDL_Window *window, SDL_HitTest callback, void *callback_data) { CHECK_WINDOW_MAGIC(window, -1); @@ -4037,21 +4584,19 @@ SDL_SetWindowHitTest(SDL_Window * window, SDL_HitTest callback, void *userdata) } window->hit_test = callback; - window->hit_test_data = userdata; + window->hit_test_data = callback_data; return 0; } -float -SDL_ComputeDiagonalDPI(int hpix, int vpix, float hinches, float vinches) +float SDL_ComputeDiagonalDPI(int hpix, int vpix, float hinches, float vinches) { float den2 = hinches * hinches + vinches * vinches; if (den2 <= 0.0f) { return 0.0f; } - return (float)(SDL_sqrt((double)hpix * (double)hpix + (double)vpix * (double)vpix) / - SDL_sqrt((double)den2)); + return (float)(SDL_sqrt((double)hpix * (double)hpix + (double)vpix * (double)vpix) / SDL_sqrt((double)den2)); } /* @@ -4071,7 +4616,7 @@ void SDL_OnApplicationWillResignActive(void) { if (_this) { SDL_Window *window; - for (window = _this->windows; window != NULL; window = window->next) { + for (window = _this->windows; window; window = window->next) { SDL_SendWindowEvent(window, SDL_WINDOWEVENT_FOCUS_LOST, 0, 0); SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MINIMIZED, 0, 0); } @@ -4095,7 +4640,7 @@ void SDL_OnApplicationDidBecomeActive(void) if (_this) { SDL_Window *window; - for (window = _this->windows; window != NULL; window = window->next) { + for (window = _this->windows; window; window = window->next) { SDL_SendWindowEvent(window, SDL_WINDOWEVENT_FOCUS_GAINED, 0, 0); SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESTORED, 0, 0); } @@ -4118,9 +4663,7 @@ int SDL_Vulkan_LoadLibrary(const char *path) retval = 0; } else { if (!_this->Vulkan_LoadLibrary) { - return SDL_SetError("Vulkan support is either not configured in SDL " - "or not available in current SDL video driver " - "(%s) or platform", _this->name); + return SDL_DllNotSupported("Vulkan"); } retval = _this->Vulkan_LoadLibrary(_this, path); } @@ -4164,8 +4707,7 @@ SDL_bool SDL_Vulkan_GetInstanceExtensions(SDL_Window *window, unsigned *count, c if (window) { CHECK_WINDOW_MAGIC(window, SDL_FALSE); - if (!(window->flags & SDL_WINDOW_VULKAN)) - { + if (!(window->flags & SDL_WINDOW_VULKAN)) { SDL_SetError(NOT_A_VULKAN_WINDOW); return SDL_FALSE; } @@ -4203,36 +4745,157 @@ SDL_bool SDL_Vulkan_CreateSurface(SDL_Window *window, return _this->Vulkan_CreateSurface(_this, window, instance, surface); } -void SDL_Vulkan_GetDrawableSize(SDL_Window * window, int *w, int *h) +void SDL_Vulkan_GetDrawableSize(SDL_Window *window, int *w, int *h) { - CHECK_WINDOW_MAGIC(window,); + CHECK_WINDOW_MAGIC(window, ); if (_this->Vulkan_GetDrawableSize) { _this->Vulkan_GetDrawableSize(_this, window, w, h); } else { - SDL_GetWindowSize(window, w, h); + SDL_GetWindowSizeInPixels(window, w, h); } } -SDL_MetalView -SDL_Metal_CreateView(SDL_Window * window) +SDL_MetalView SDL_Metal_CreateView(SDL_Window *window) { CHECK_WINDOW_MAGIC(window, NULL); - if (_this->Metal_CreateView) { - return _this->Metal_CreateView(_this, window); - } else { - SDL_SetError("Metal is not supported."); - return NULL; + if (!(window->flags & SDL_WINDOW_METAL)) { + /* No problem, we can convert to Metal */ + if (window->flags & SDL_WINDOW_OPENGL) { + window->flags &= ~SDL_WINDOW_OPENGL; + SDL_GL_UnloadLibrary(); + } + if (window->flags & SDL_WINDOW_VULKAN) { + window->flags &= ~SDL_WINDOW_VULKAN; + SDL_Vulkan_UnloadLibrary(); + } + window->flags |= SDL_WINDOW_METAL; } + + return _this->Metal_CreateView(_this, window); } -void -SDL_Metal_DestroyView(SDL_MetalView view) +void SDL_Metal_DestroyView(SDL_MetalView view) { if (_this && view && _this->Metal_DestroyView) { _this->Metal_DestroyView(_this, view); } } +void *SDL_Metal_GetLayer(SDL_MetalView view) +{ + if (_this && _this->Metal_GetLayer) { + if (view) { + return _this->Metal_GetLayer(_this, view); + } else { + SDL_InvalidParamError("view"); + return NULL; + } + } else { + SDL_SetError("Metal is not supported."); + return NULL; + } +} + +void SDL_Metal_GetDrawableSize(SDL_Window *window, int *w, int *h) +{ + CHECK_WINDOW_MAGIC(window, ); + + if (_this->Metal_GetDrawableSize) { + _this->Metal_GetDrawableSize(_this, window, w, h); + } else { + SDL_GetWindowSizeInPixels(window, w, h); + } +} + +#if defined(SDL_VIDEO_DRIVER_X11) || defined(SDL_VIDEO_DRIVER_WAYLAND) || defined(SDL_VIDEO_DRIVER_EMSCRIPTEN) +const char *SDL_GetCSSCursorName(SDL_SystemCursor id, const char **fallback_name) +{ + /* Reference: https://www.w3.org/TR/css-ui-4/#cursor */ + /* Also in: https://www.freedesktop.org/wiki/Specifications/cursor-spec/ */ + switch (id) { + case SDL_SYSTEM_CURSOR_ARROW: + return "default"; + + case SDL_SYSTEM_CURSOR_IBEAM: + return "text"; + + case SDL_SYSTEM_CURSOR_WAIT: + return "wait"; + + case SDL_SYSTEM_CURSOR_CROSSHAIR: + return "crosshair"; + + case SDL_SYSTEM_CURSOR_WAITARROW: + return "progress"; + + case SDL_SYSTEM_CURSOR_SIZENWSE: + if (fallback_name) { + /* only a single arrow */ + *fallback_name = "nw-resize"; + } + return "nwse-resize"; + + case SDL_SYSTEM_CURSOR_SIZENESW: + if (fallback_name) { + /* only a single arrow */ + *fallback_name = "ne-resize"; + } + return "nesw-resize"; + + case SDL_SYSTEM_CURSOR_SIZEWE: + if (fallback_name) { + *fallback_name = "col-resize"; + } + return "ew-resize"; + + case SDL_SYSTEM_CURSOR_SIZENS: + if (fallback_name) { + *fallback_name = "row-resize"; + } + return "ns-resize"; + + case SDL_SYSTEM_CURSOR_SIZEALL: + return "all-scroll"; + + case SDL_SYSTEM_CURSOR_NO: + return "not-allowed"; + + case SDL_SYSTEM_CURSOR_HAND: + return "pointer"; + +#if 0 + case SDL_SYSTEM_CURSOR_WINDOW_TOPLEFT: + return "nw-resize"; + + case SDL_SYSTEM_CURSOR_WINDOW_TOP: + return "n-resize"; + + case SDL_SYSTEM_CURSOR_WINDOW_TOPRIGHT: + return "ne-resize"; + + case SDL_SYSTEM_CURSOR_WINDOW_RIGHT: + return "e-resize"; + + case SDL_SYSTEM_CURSOR_WINDOW_BOTTOMRIGHT: + return "se-resize"; + + case SDL_SYSTEM_CURSOR_WINDOW_BOTTOM: + return "s-resize"; + + case SDL_SYSTEM_CURSOR_WINDOW_BOTTOMLEFT: + return "sw-resize"; + + case SDL_SYSTEM_CURSOR_WINDOW_LEFT: + return "w-resize"; +#endif + + default: + SDL_assert(0); + return "default"; + } +} +#endif + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/SDL_vulkan_internal.h b/SDL2-2.30.5/src/video/SDL_vulkan_internal.h similarity index 82% rename from SDL2-2.0.12/src/video/SDL_vulkan_internal.h rename to SDL2-2.30.5/src/video/SDL_vulkan_internal.h index 4e0ecbe..28728fa 100644 --- a/SDL2-2.0.12/src/video/SDL_vulkan_internal.h +++ b/SDL2-2.30.5/src/video/SDL_vulkan_internal.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -25,31 +25,34 @@ #include "SDL_stdinc.h" -#if defined(SDL_LOADSO_DISABLED) -#undef SDL_VIDEO_VULKAN -#define SDL_VIDEO_VULKAN 0 +#ifdef SDL_VIDEO_VULKAN +#if defined(SDL_LOADSO_DISABLED) || defined(SDL_LOADSO_DUMMY) +#error You should not be here. #endif -#if SDL_VIDEO_VULKAN - -#if SDL_VIDEO_DRIVER_ANDROID +#ifdef SDL_VIDEO_DRIVER_ANDROID #define VK_USE_PLATFORM_ANDROID_KHR #endif -#if SDL_VIDEO_DRIVER_COCOA +#ifdef SDL_VIDEO_DRIVER_COCOA +#define VK_USE_PLATFORM_METAL_EXT #define VK_USE_PLATFORM_MACOS_MVK #endif -#if SDL_VIDEO_DRIVER_UIKIT +#ifdef SDL_VIDEO_DRIVER_DIRECTFB +#define VK_USE_PLATFORM_DIRECTFB_EXT +#endif +#ifdef SDL_VIDEO_DRIVER_UIKIT +#define VK_USE_PLATFORM_METAL_EXT #define VK_USE_PLATFORM_IOS_MVK #endif -#if SDL_VIDEO_DRIVER_WAYLAND +#ifdef SDL_VIDEO_DRIVER_WAYLAND #define VK_USE_PLATFORM_WAYLAND_KHR #include "wayland/SDL_waylanddyn.h" #endif -#if SDL_VIDEO_DRIVER_WINDOWS +#ifdef SDL_VIDEO_DRIVER_WINDOWS #define VK_USE_PLATFORM_WIN32_KHR #include "../core/windows/SDL_windows.h" #endif -#if SDL_VIDEO_DRIVER_X11 +#ifdef SDL_VIDEO_DRIVER_X11 #define VK_USE_PLATFORM_XLIB_KHR #define VK_USE_PLATFORM_XCB_KHR #endif @@ -59,7 +62,6 @@ #include "SDL_vulkan.h" - extern const char *SDL_Vulkan_GetResultString(VkResult result); extern VkExtensionProperties *SDL_Vulkan_CreateInstanceExtensionsList( @@ -85,8 +87,8 @@ extern SDL_bool SDL_Vulkan_Display_CreateSurface(void *vkGetInstanceProcAddr, /* No SDL Vulkan support, just include the header for typedefs */ #include "SDL_vulkan.h" -typedef void (*PFN_vkGetInstanceProcAddr) (void); -typedef int (*PFN_vkEnumerateInstanceExtensionProperties) (void); +typedef void (*PFN_vkGetInstanceProcAddr)(void); +typedef int (*PFN_vkEnumerateInstanceExtensionProperties)(void); #endif /* SDL_VIDEO_VULKAN */ diff --git a/SDL2-2.0.12/src/video/SDL_vulkan_utils.c b/SDL2-2.30.5/src/video/SDL_vulkan_utils.c similarity index 74% rename from SDL2-2.0.12/src/video/SDL_vulkan_utils.c rename to SDL2-2.30.5/src/video/SDL_vulkan_utils.c index 472acfa..7a1579d 100644 --- a/SDL2-2.0.12/src/video/SDL_vulkan_utils.c +++ b/SDL2-2.30.5/src/video/SDL_vulkan_utils.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -22,16 +22,12 @@ #include "SDL_vulkan_internal.h" #include "SDL_error.h" -#include "SDL_log.h" -/* !!! FIXME: this file doesn't match coding standards for SDL (brace position, etc). */ - -#if SDL_VIDEO_VULKAN +#ifdef SDL_VIDEO_VULKAN const char *SDL_Vulkan_GetResultString(VkResult result) { - switch((int)result) - { + switch ((int)result) { case VK_SUCCESS: return "VK_SUCCESS"; case VK_NOT_READY: @@ -68,6 +64,16 @@ const char *SDL_Vulkan_GetResultString(VkResult result) return "VK_ERROR_FORMAT_NOT_SUPPORTED"; case VK_ERROR_FRAGMENTED_POOL: return "VK_ERROR_FRAGMENTED_POOL"; + case VK_ERROR_UNKNOWN: + return "VK_ERROR_UNKNOWN"; + case VK_ERROR_OUT_OF_POOL_MEMORY: + return "VK_ERROR_OUT_OF_POOL_MEMORY"; + case VK_ERROR_INVALID_EXTERNAL_HANDLE: + return "VK_ERROR_INVALID_EXTERNAL_HANDLE"; + case VK_ERROR_FRAGMENTATION: + return "VK_ERROR_FRAGMENTATION"; + case VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS: + return "VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS"; case VK_ERROR_SURFACE_LOST_KHR: return "VK_ERROR_SURFACE_LOST_KHR"; case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR: @@ -80,16 +86,34 @@ const char *SDL_Vulkan_GetResultString(VkResult result) return "VK_ERROR_INCOMPATIBLE_DISPLAY_KHR"; case VK_ERROR_VALIDATION_FAILED_EXT: return "VK_ERROR_VALIDATION_FAILED_EXT"; - case VK_ERROR_OUT_OF_POOL_MEMORY_KHR: - return "VK_ERROR_OUT_OF_POOL_MEMORY_KHR"; case VK_ERROR_INVALID_SHADER_NV: return "VK_ERROR_INVALID_SHADER_NV"; - case VK_RESULT_MAX_ENUM: - case VK_RESULT_RANGE_SIZE: +#if VK_HEADER_VERSION >= 135 && VK_HEADER_VERSION < 162 + case VK_ERROR_INCOMPATIBLE_VERSION_KHR: + return "VK_ERROR_INCOMPATIBLE_VERSION_KHR"; +#endif + case VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT: + return "VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT"; + case VK_ERROR_NOT_PERMITTED_EXT: + return "VK_ERROR_NOT_PERMITTED_EXT"; + case VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT: + return "VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT"; + case VK_THREAD_IDLE_KHR: + return "VK_THREAD_IDLE_KHR"; + case VK_THREAD_DONE_KHR: + return "VK_THREAD_DONE_KHR"; + case VK_OPERATION_DEFERRED_KHR: + return "VK_OPERATION_DEFERRED_KHR"; + case VK_OPERATION_NOT_DEFERRED_KHR: + return "VK_OPERATION_NOT_DEFERRED_KHR"; + case VK_PIPELINE_COMPILE_REQUIRED_EXT: + return "VK_PIPELINE_COMPILE_REQUIRED_EXT"; + default: break; } - if(result < 0) + if (result < 0) { return "VK_ERROR_"; + } return "VK_"; } @@ -100,11 +124,9 @@ VkExtensionProperties *SDL_Vulkan_CreateInstanceExtensionsList( Uint32 count = 0; VkResult result = vkEnumerateInstanceExtensionProperties(NULL, &count, NULL); VkExtensionProperties *retval; - if(result == VK_ERROR_INCOMPATIBLE_DRIVER) - { - /* Avoid the ERR_MAX_STRLEN limit by passing part of the message - * as a string argument. - */ + + if (result == VK_ERROR_INCOMPATIBLE_DRIVER) { + /* Avoid the ERR_MAX_STRLEN limit by passing part of the message as a string argument. */ SDL_SetError( "You probably don't have a working Vulkan driver installed. %s %s %s(%d)", "Getting Vulkan extensions failed:", @@ -112,9 +134,7 @@ VkExtensionProperties *SDL_Vulkan_CreateInstanceExtensionsList( SDL_Vulkan_GetResultString(result), (int)result); return NULL; - } - else if(result != VK_SUCCESS) - { + } else if (result != VK_SUCCESS) { SDL_SetError( "Getting Vulkan extensions failed: vkEnumerateInstanceExtensionProperties returned " "%s(%d)", @@ -122,22 +142,20 @@ VkExtensionProperties *SDL_Vulkan_CreateInstanceExtensionsList( (int)result); return NULL; } - if(count == 0) - { + + if (count == 0) { retval = SDL_calloc(1, sizeof(VkExtensionProperties)); // so we can return non-null - } - else - { + } else { retval = SDL_calloc(count, sizeof(VkExtensionProperties)); } - if(!retval) - { + + if (!retval) { SDL_OutOfMemory(); return NULL; } + result = vkEnumerateInstanceExtensionProperties(NULL, &count, retval); - if(result != VK_SUCCESS) - { + if (result != VK_SUCCESS) { SDL_SetError( "Getting Vulkan extensions failed: vkEnumerateInstanceExtensionProperties returned " "%s(%d)", @@ -162,6 +180,7 @@ SDL_bool SDL_Vulkan_GetInstanceExtensions_Helper(unsigned *userCount, SDL_SetError("Output array for SDL_Vulkan_GetInstanceExtensions needs to be at least %d big", nameCount); return SDL_FALSE; } + for (i = 0; i < nameCount; i++) { userNames[i] = names[i]; } @@ -179,12 +198,12 @@ static const VkDisplayPlaneAlphaFlagBitsKHR alphaModes[4] = { }; SDL_bool SDL_Vulkan_Display_CreateSurface(void *vkGetInstanceProcAddr_, - VkInstance instance, - VkSurfaceKHR *surface) + VkInstance instance, + VkSurfaceKHR *surface) { PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)vkGetInstanceProcAddr_; -#define VULKAN_INSTANCE_FUNCTION(name) \ +#define VULKAN_INSTANCE_FUNCTION(name) \ PFN_##name name = (PFN_##name)vkGetInstanceProcAddr((VkInstance)instance, #name) VULKAN_INSTANCE_FUNCTION(vkEnumeratePhysicalDevices); VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceDisplayPropertiesKHR); @@ -202,55 +221,47 @@ SDL_bool SDL_Vulkan_Display_CreateSurface(void *vkGetInstanceProcAddr_, const char *chosenDisplayId; int displayId = 0; /* Counting from physical device 0, display 0 */ - if(!vkEnumeratePhysicalDevices || - !vkGetPhysicalDeviceDisplayPropertiesKHR || - !vkGetDisplayModePropertiesKHR || - !vkGetPhysicalDeviceDisplayPlanePropertiesKHR || - !vkGetDisplayPlaneCapabilitiesKHR || - !vkGetDisplayPlaneSupportedDisplaysKHR || - !vkCreateDisplayPlaneSurfaceKHR) - { - SDL_SetError(VK_KHR_DISPLAY_EXTENSION_NAME - " extension is not enabled in the Vulkan instance."); + if (!vkEnumeratePhysicalDevices || + !vkGetPhysicalDeviceDisplayPropertiesKHR || + !vkGetDisplayModePropertiesKHR || + !vkGetPhysicalDeviceDisplayPlanePropertiesKHR || + !vkGetDisplayPlaneCapabilitiesKHR || + !vkGetDisplayPlaneSupportedDisplaysKHR || + !vkCreateDisplayPlaneSurfaceKHR) { + SDL_SetError(VK_KHR_DISPLAY_EXTENSION_NAME " extension is not enabled in the Vulkan instance."); goto error; } - - if ((chosenDisplayId = SDL_getenv("SDL_VULKAN_DISPLAY")) != NULL) - { + chosenDisplayId = SDL_getenv("SDL_VULKAN_DISPLAY"); + if (chosenDisplayId) { displayId = SDL_atoi(chosenDisplayId); } /* Enumerate physical devices */ - result = - vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, NULL); - if(result != VK_SUCCESS) - { + result = vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, NULL); + if (result != VK_SUCCESS) { SDL_SetError("Could not enumerate Vulkan physical devices"); goto error; } - if(physicalDeviceCount == 0) - { + + if (physicalDeviceCount == 0) { SDL_SetError("No Vulkan physical devices"); goto error; } + physicalDevices = SDL_malloc(sizeof(VkPhysicalDevice) * physicalDeviceCount); - if(!physicalDevices) - { + if (!physicalDevices) { SDL_OutOfMemory(); goto error; } - result = - vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, physicalDevices); - if(result != VK_SUCCESS) - { + + result = vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, physicalDevices); + if (result != VK_SUCCESS) { SDL_SetError("Error enumerating physical devices"); goto error; } - for(physicalDeviceIndex = 0; physicalDeviceIndex < physicalDeviceCount; - physicalDeviceIndex++) - { - VkPhysicalDevice physicalDevice = physicalDevices[physicalDeviceIndex]; + for (physicalDeviceIndex = 0; physicalDeviceIndex < physicalDeviceCount; physicalDeviceIndex++) { + VkPhysicalDevice physicalDevice = physicalDevices[physicalDeviceIndex]; uint32_t displayPropertiesCount = 0; VkDisplayPropertiesKHR *displayProperties = NULL; uint32_t displayModePropertiesCount = 0; @@ -266,32 +277,27 @@ SDL_bool SDL_Vulkan_Display_CreateSurface(void *vkGetInstanceProcAddr_, VkDisplayPlaneCapabilitiesKHR planeCaps; /* Get information about the physical displays */ - result = - vkGetPhysicalDeviceDisplayPropertiesKHR(physicalDevice, &displayPropertiesCount, NULL); - if (result != VK_SUCCESS || displayPropertiesCount == 0) - { + result = vkGetPhysicalDeviceDisplayPropertiesKHR(physicalDevice, &displayPropertiesCount, NULL); + if (result != VK_SUCCESS || displayPropertiesCount == 0) { /* This device has no physical device display properties, move on to next. */ continue; } SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "vulkandisplay: Number of display properties for device %u: %u", - physicalDeviceIndex, displayPropertiesCount); + physicalDeviceIndex, displayPropertiesCount); - if ( (displayId < 0) || (((uint32_t) displayId) >= displayPropertiesCount) ) - { + if (displayId < 0 || (uint32_t)displayId >= displayPropertiesCount) { /* Display id specified was higher than number of available displays, move to next physical device. */ displayId -= displayPropertiesCount; continue; } displayProperties = SDL_malloc(sizeof(VkDisplayPropertiesKHR) * displayPropertiesCount); - if(!displayProperties) - { + if (!displayProperties) { SDL_OutOfMemory(); goto error; } - result = - vkGetPhysicalDeviceDisplayPropertiesKHR(physicalDevice, &displayPropertiesCount, displayProperties); + result = vkGetPhysicalDeviceDisplayPropertiesKHR(physicalDevice, &displayPropertiesCount, displayProperties); if (result != VK_SUCCESS || displayPropertiesCount == 0) { SDL_free(displayProperties); SDL_SetError("Error enumerating physical device displays"); @@ -301,30 +307,26 @@ SDL_bool SDL_Vulkan_Display_CreateSurface(void *vkGetInstanceProcAddr_, display = displayProperties[displayId].display; extent = displayProperties[displayId].physicalResolution; SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "vulkandisplay: Display: %s Native resolution: %ux%u", - displayProperties[displayId].displayName, extent.width, extent.height); + displayProperties[displayId].displayName, extent.width, extent.height); SDL_free(displayProperties); displayProperties = NULL; /* Get display mode properties for the chosen display */ - result = - vkGetDisplayModePropertiesKHR(physicalDevice, display, &displayModePropertiesCount, NULL); - if (result != VK_SUCCESS || displayModePropertiesCount == 0) - { + result = vkGetDisplayModePropertiesKHR(physicalDevice, display, &displayModePropertiesCount, NULL); + if (result != VK_SUCCESS || displayModePropertiesCount == 0) { SDL_SetError("Error enumerating display modes"); goto error; } SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "vulkandisplay: Number of display modes: %u", displayModePropertiesCount); displayModeProperties = SDL_malloc(sizeof(VkDisplayModePropertiesKHR) * displayModePropertiesCount); - if(!displayModeProperties) - { + if (!displayModeProperties) { SDL_OutOfMemory(); goto error; } - result = - vkGetDisplayModePropertiesKHR(physicalDevice, display, &displayModePropertiesCount, displayModeProperties); + result = vkGetDisplayModePropertiesKHR(physicalDevice, display, &displayModePropertiesCount, displayModeProperties); if (result != VK_SUCCESS || displayModePropertiesCount == 0) { SDL_SetError("Error enumerating display modes"); SDL_free(displayModeProperties); @@ -332,18 +334,16 @@ SDL_bool SDL_Vulkan_Display_CreateSurface(void *vkGetInstanceProcAddr_, } /* Try to find a display mode that matches the native resolution */ - for (i = 0; i < displayModePropertiesCount; ++i) - { + for (i = 0; i < displayModePropertiesCount; ++i) { if (displayModeProperties[i].parameters.visibleRegion.width == extent.width && displayModeProperties[i].parameters.visibleRegion.height == extent.height && - displayModeProperties[i].parameters.refreshRate > refreshRate) - { + displayModeProperties[i].parameters.refreshRate > refreshRate) { bestMatchIndex = i; refreshRate = displayModeProperties[i].parameters.refreshRate; } } - if (bestMatchIndex < 0) - { + + if (bestMatchIndex < 0) { SDL_SetError("Found no matching display mode"); SDL_free(displayModeProperties); goto error; @@ -352,91 +352,80 @@ SDL_bool SDL_Vulkan_Display_CreateSurface(void *vkGetInstanceProcAddr_, SDL_zero(createInfo); createInfo.displayMode = displayModeProperties[bestMatchIndex].displayMode; SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "vulkandisplay: Matching mode %ux%u with refresh rate %u", - displayModeProperties[bestMatchIndex].parameters.visibleRegion.width, - displayModeProperties[bestMatchIndex].parameters.visibleRegion.height, - refreshRate); + displayModeProperties[bestMatchIndex].parameters.visibleRegion.width, + displayModeProperties[bestMatchIndex].parameters.visibleRegion.height, + refreshRate); SDL_free(displayModeProperties); displayModeProperties = NULL; /* Try to find a plane index that supports our display */ - result = - vkGetPhysicalDeviceDisplayPlanePropertiesKHR(physicalDevice, &displayPlanePropertiesCount, NULL); - if (result != VK_SUCCESS || displayPlanePropertiesCount == 0) - { + result = vkGetPhysicalDeviceDisplayPlanePropertiesKHR(physicalDevice, &displayPlanePropertiesCount, NULL); + if (result != VK_SUCCESS || displayPlanePropertiesCount == 0) { SDL_SetError("Error enumerating display planes"); goto error; } SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "vulkandisplay: Number of display planes: %u", displayPlanePropertiesCount); displayPlaneProperties = SDL_malloc(sizeof(VkDisplayPlanePropertiesKHR) * displayPlanePropertiesCount); - if(!displayPlaneProperties) - { + if (!displayPlaneProperties) { SDL_OutOfMemory(); goto error; } - result = - vkGetPhysicalDeviceDisplayPlanePropertiesKHR(physicalDevice, &displayPlanePropertiesCount, displayPlaneProperties); - if (result != VK_SUCCESS || displayPlanePropertiesCount == 0) - { + result = vkGetPhysicalDeviceDisplayPlanePropertiesKHR(physicalDevice, &displayPlanePropertiesCount, displayPlaneProperties); + if (result != VK_SUCCESS || displayPlanePropertiesCount == 0) { SDL_SetError("Error enumerating display plane properties"); SDL_free(displayPlaneProperties); goto error; } - for (i = 0; i < displayPlanePropertiesCount; ++i) - { + for (i = 0; i < displayPlanePropertiesCount; ++i) { uint32_t planeSupportedDisplaysCount = 0; VkDisplayKHR *planeSupportedDisplays = NULL; uint32_t j; /* Check if plane is attached to a display, if not, continue. */ - if (displayPlaneProperties[i].currentDisplay == VK_NULL_HANDLE) + if (displayPlaneProperties[i].currentDisplay == VK_NULL_HANDLE) { continue; + } /* Check supported displays for this plane. */ - result = - vkGetDisplayPlaneSupportedDisplaysKHR(physicalDevice, i, &planeSupportedDisplaysCount, NULL); - if (result != VK_SUCCESS || planeSupportedDisplaysCount == 0) - { - continue; /* No supported displays, on to next plane. */ + result = vkGetDisplayPlaneSupportedDisplaysKHR(physicalDevice, i, &planeSupportedDisplaysCount, NULL); + if (result != VK_SUCCESS || planeSupportedDisplaysCount == 0) { + continue; /* No supported displays, on to next plane. */ } + SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "vulkandisplay: Number of supported displays for plane %u: %u", i, planeSupportedDisplaysCount); planeSupportedDisplays = SDL_malloc(sizeof(VkDisplayKHR) * planeSupportedDisplaysCount); - if(!planeSupportedDisplays) - { + if (!planeSupportedDisplays) { SDL_free(displayPlaneProperties); SDL_OutOfMemory(); goto error; } - result = - vkGetDisplayPlaneSupportedDisplaysKHR(physicalDevice, i, &planeSupportedDisplaysCount, planeSupportedDisplays); - if (result != VK_SUCCESS || planeSupportedDisplaysCount == 0) - { + result = vkGetDisplayPlaneSupportedDisplaysKHR(physicalDevice, i, &planeSupportedDisplaysCount, planeSupportedDisplays); + if (result != VK_SUCCESS || planeSupportedDisplaysCount == 0) { SDL_SetError("Error enumerating supported displays, or no supported displays"); SDL_free(planeSupportedDisplays); SDL_free(displayPlaneProperties); goto error; } - for (j = 0; j < planeSupportedDisplaysCount && planeSupportedDisplays[j] != display; ++j) - ; + for (j = 0; j < planeSupportedDisplaysCount && planeSupportedDisplays[j] != display; ++j) { + } SDL_free(planeSupportedDisplays); planeSupportedDisplays = NULL; - if (j == planeSupportedDisplaysCount) - { + if (j == planeSupportedDisplaysCount) { /* This display is not supported for this plane, move on. */ continue; } result = vkGetDisplayPlaneCapabilitiesKHR(physicalDevice, createInfo.displayMode, i, &planeCaps); - if (result != VK_SUCCESS) - { + if (result != VK_SUCCESS) { SDL_SetError("Error getting display plane capabilities"); SDL_free(displayPlaneProperties); goto error; @@ -444,19 +433,17 @@ SDL_bool SDL_Vulkan_Display_CreateSurface(void *vkGetInstanceProcAddr_, /* Check if plane fulfills extent requirements. */ if (extent.width >= planeCaps.minDstExtent.width && extent.height >= planeCaps.minDstExtent.height && - extent.width <= planeCaps.maxDstExtent.width && extent.height <= planeCaps.maxDstExtent.height) - { + extent.width <= planeCaps.maxDstExtent.width && extent.height <= planeCaps.maxDstExtent.height) { /* If it does, choose this plane. */ SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "vulkandisplay: Choosing plane %d, minimum extent %dx%d maximum extent %dx%d", i, - planeCaps.minDstExtent.width, planeCaps.minDstExtent.height, - planeCaps.maxDstExtent.width, planeCaps.maxDstExtent.height); + planeCaps.minDstExtent.width, planeCaps.minDstExtent.height, + planeCaps.maxDstExtent.width, planeCaps.maxDstExtent.height); planeIndex = i; break; } } - if (planeIndex < 0) - { + if (planeIndex < 0) { SDL_SetError("No plane supports the selected resolution"); SDL_free(displayPlaneProperties); goto error; @@ -485,8 +472,7 @@ SDL_bool SDL_Vulkan_Display_CreateSurface(void *vkGetInstanceProcAddr_, SDL_free(physicalDevices); physicalDevices = NULL; - if (physicalDeviceIndex == physicalDeviceCount) - { + if (physicalDeviceIndex == physicalDeviceCount) { SDL_SetError("No usable displays found or requested display out of range"); return SDL_FALSE; } @@ -495,16 +481,14 @@ SDL_bool SDL_Vulkan_Display_CreateSurface(void *vkGetInstanceProcAddr_, createInfo.transform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; createInfo.globalAlpha = 1.0f; - result = vkCreateDisplayPlaneSurfaceKHR(instance, &createInfo, - NULL, surface); - if(result != VK_SUCCESS) - { - SDL_SetError("vkCreateDisplayPlaneSurfaceKHR failed: %s", - SDL_Vulkan_GetResultString(result)); + result = vkCreateDisplayPlaneSurfaceKHR(instance, &createInfo, NULL, surface); + if (result != VK_SUCCESS) { + SDL_SetError("vkCreateDisplayPlaneSurfaceKHR failed: %s", SDL_Vulkan_GetResultString(result)); return SDL_FALSE; } SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "vulkandisplay: Created surface"); return SDL_TRUE; + error: SDL_free(physicalDevices); return SDL_FALSE; diff --git a/SDL2-2.0.12/src/video/SDL_yuv.c b/SDL2-2.30.5/src/video/SDL_yuv.c similarity index 63% rename from SDL2-2.0.12/src/video/SDL_yuv.c rename to SDL2-2.30.5/src/video/SDL_yuv.c index 4b9755d..14f5746 100644 --- a/SDL2-2.0.12/src/video/SDL_yuv.c +++ b/SDL2-2.30.5/src/video/SDL_yuv.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -27,18 +27,20 @@ #include "yuv2rgb/yuv_rgb.h" -#define SDL_YUV_SD_THRESHOLD 576 - +#define SDL_YUV_SD_THRESHOLD 576 static SDL_YUV_CONVERSION_MODE SDL_YUV_ConversionMode = SDL_YUV_CONVERSION_BT601; +#if SDL_HAVE_YUV +static SDL_bool IsPlanar2x2Format(Uint32 format); +#endif void SDL_SetYUVConversionMode(SDL_YUV_CONVERSION_MODE mode) { SDL_YUV_ConversionMode = mode; } -SDL_YUV_CONVERSION_MODE SDL_GetYUVConversionMode() +SDL_YUV_CONVERSION_MODE SDL_GetYUVConversionMode(void) { return SDL_YUV_ConversionMode; } @@ -56,6 +58,133 @@ SDL_YUV_CONVERSION_MODE SDL_GetYUVConversionModeForResolution(int width, int hei return mode; } +/* + * Calculate YUV size and pitch. Check for overflow. + * Output 'pitch' that can be used with SDL_ConvertPixels() + * + * return 0 on success, -1 on error + */ +int SDL_CalculateYUVSize(Uint32 format, int w, int h, size_t *size, int *pitch) +{ +#if SDL_HAVE_YUV + int sz_plane = 0, sz_plane_chroma = 0, sz_plane_packed = 0; + + if (IsPlanar2x2Format(format) == SDL_TRUE) { + { + /* sz_plane == w * h; */ + size_t s1; + if (SDL_size_mul_overflow(w, h, &s1) < 0) { + return -1; + } + sz_plane = (int) s1; + } + + { + /* sz_plane_chroma == ((w + 1) / 2) * ((h + 1) / 2); */ + size_t s1, s2, s3; + if (SDL_size_add_overflow(w, 1, &s1) < 0) { + return -1; + } + s1 = s1 / 2; + if (SDL_size_add_overflow(h, 1, &s2) < 0) { + return -1; + } + s2 = s2 / 2; + if (SDL_size_mul_overflow(s1, s2, &s3) < 0) { + return -1; + } + sz_plane_chroma = (int) s3; + } + } else { + /* sz_plane_packed == ((w + 1) / 2) * h; */ + size_t s1, s2; + if (SDL_size_add_overflow(w, 1, &s1) < 0) { + return -1; + } + s1 = s1 / 2; + if (SDL_size_mul_overflow(s1, h, &s2) < 0) { + return -1; + } + sz_plane_packed = (int) s2; + } + + switch (format) { + case SDL_PIXELFORMAT_YV12: /**< Planar mode: Y + V + U (3 planes) */ + case SDL_PIXELFORMAT_IYUV: /**< Planar mode: Y + U + V (3 planes) */ + + if (pitch) { + *pitch = w; + } + + if (size) { + /* dst_size == sz_plane + sz_plane_chroma + sz_plane_chroma; */ + size_t s1, s2; + if (SDL_size_add_overflow(sz_plane, sz_plane_chroma, &s1) < 0) { + return -1; + } + if (SDL_size_add_overflow(s1, sz_plane_chroma, &s2) < 0) { + return -1; + } + *size = (int)s2; + } + 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) */ + + if (pitch) { + /* pitch == ((w + 1) / 2) * 4; */ + size_t p1, p2; + if (SDL_size_add_overflow(w, 1, &p1) < 0) { + return -1; + } + p1 = p1 / 2; + if (SDL_size_mul_overflow(p1, 4, &p2) < 0) { + return -1; + } + *pitch = (int) p2; + } + + if (size) { + /* dst_size == 4 * sz_plane_packed; */ + size_t s1; + if (SDL_size_mul_overflow(sz_plane_packed, 4, &s1) < 0) { + return -1; + } + *size = (int) s1; + } + 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) */ + if (pitch) { + *pitch = w; + } + + if (size) { + /* dst_size == sz_plane + sz_plane_chroma + sz_plane_chroma; */ + size_t s1, s2; + if (SDL_size_add_overflow(sz_plane, sz_plane_chroma, &s1) < 0) { + return -1; + } + if (SDL_size_add_overflow(s1, sz_plane_chroma, &s2) < 0) { + return -1; + } + *size = (int) s2; + } + break; + + default: + return -1; + } + + return 0; +#else + return -1; +#endif +} + #if SDL_HAVE_YUV static int GetYUVConversionType(int width, int height, YCbCrType *yuv_type) @@ -78,17 +207,12 @@ static int GetYUVConversionType(int width, int height, YCbCrType *yuv_type) static SDL_bool IsPlanar2x2Format(Uint32 format) { - return (format == SDL_PIXELFORMAT_YV12 || - format == SDL_PIXELFORMAT_IYUV || - format == SDL_PIXELFORMAT_NV12 || - format == SDL_PIXELFORMAT_NV21); + return format == SDL_PIXELFORMAT_YV12 || format == SDL_PIXELFORMAT_IYUV || format == SDL_PIXELFORMAT_NV12 || format == SDL_PIXELFORMAT_NV21; } static SDL_bool IsPacked4Format(Uint32 format) { - return (format == SDL_PIXELFORMAT_YUY2 || - format == SDL_PIXELFORMAT_UYVY || - format == SDL_PIXELFORMAT_YVYU); + return format == SDL_PIXELFORMAT_YUY2 || format == SDL_PIXELFORMAT_UYVY || format == SDL_PIXELFORMAT_YVYU; } static int GetYUVPlanes(int width, int height, Uint32 format, const void *yuv, int yuv_pitch, @@ -183,9 +307,9 @@ static int GetYUVPlanes(int width, int height, Uint32 format, const void *yuv, i static SDL_bool yuv_rgb_sse( Uint32 src_format, Uint32 dst_format, - Uint32 width, Uint32 height, - const Uint8 *y, const Uint8 *u, const Uint8 *v, Uint32 y_stride, Uint32 uv_stride, - Uint8 *rgb, Uint32 rgb_stride, + Uint32 width, Uint32 height, + const Uint8 *y, const Uint8 *u, const Uint8 *v, Uint32 y_stride, Uint32 uv_stride, + Uint8 *rgb, Uint32 rgb_stride, YCbCrType yuv_type) { #ifdef __SSE2__ @@ -290,11 +414,53 @@ static SDL_bool yuv_rgb_sse( return SDL_FALSE; } +static SDL_bool yuv_rgb_lsx( + Uint32 src_format, Uint32 dst_format, + Uint32 width, Uint32 height, + const Uint8 *y, const Uint8 *u, const Uint8 *v, Uint32 y_stride, Uint32 uv_stride, + Uint8 *rgb, Uint32 rgb_stride, + YCbCrType yuv_type) +{ +#ifdef __loongarch_sx + if (!SDL_HasLSX()) { + return SDL_FALSE; + } + if (src_format == SDL_PIXELFORMAT_YV12 || + src_format == SDL_PIXELFORMAT_IYUV) { + + switch (dst_format) { + case SDL_PIXELFORMAT_RGB24: + yuv420_rgb24_lsx(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type); + return SDL_TRUE; + case SDL_PIXELFORMAT_RGBX8888: + case SDL_PIXELFORMAT_RGBA8888: + yuv420_rgba_lsx(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type); + return SDL_TRUE; + case SDL_PIXELFORMAT_BGRX8888: + case SDL_PIXELFORMAT_BGRA8888: + yuv420_bgra_lsx(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type); + return SDL_TRUE; + case SDL_PIXELFORMAT_RGB888: + case SDL_PIXELFORMAT_ARGB8888: + yuv420_argb_lsx(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type); + return SDL_TRUE; + case SDL_PIXELFORMAT_BGR888: + case SDL_PIXELFORMAT_ABGR8888: + yuv420_abgr_lsx(width, height, y, u, v, y_stride, uv_stride, rgb, rgb_stride, yuv_type); + return SDL_TRUE; + default: + break; + } + } +#endif + return SDL_FALSE; +} + static SDL_bool yuv_rgb_std( Uint32 src_format, Uint32 dst_format, - Uint32 width, Uint32 height, - const Uint8 *y, const Uint8 *u, const Uint8 *v, Uint32 y_stride, Uint32 uv_stride, - Uint8 *rgb, Uint32 rgb_stride, + Uint32 width, Uint32 height, + const Uint8 *y, const Uint8 *u, const Uint8 *v, Uint32 y_stride, Uint32 uv_stride, + Uint8 *rgb, Uint32 rgb_stride, YCbCrType yuv_type) { if (src_format == SDL_PIXELFORMAT_YV12 || @@ -393,10 +559,9 @@ static SDL_bool yuv_rgb_std( return SDL_FALSE; } -int -SDL_ConvertPixels_YUV_to_RGB(int width, int height, - Uint32 src_format, const void *src, int src_pitch, - Uint32 dst_format, void *dst, int dst_pitch) +int SDL_ConvertPixels_YUV_to_RGB(int width, int height, + Uint32 src_format, const void *src, int src_pitch, + Uint32 dst_format, void *dst, int dst_pitch) { const Uint8 *y = NULL; const Uint8 *u = NULL; @@ -413,11 +578,15 @@ SDL_ConvertPixels_YUV_to_RGB(int width, int height, return -1; } - if (yuv_rgb_sse(src_format, dst_format, width, height, y, u, v, y_stride, uv_stride, (Uint8*)dst, dst_pitch, yuv_type)) { + if (yuv_rgb_sse(src_format, dst_format, width, height, y, u, v, y_stride, uv_stride, (Uint8 *)dst, dst_pitch, yuv_type)) { return 0; } - if (yuv_rgb_std(src_format, dst_format, width, height, y, u, v, y_stride, uv_stride, (Uint8*)dst, dst_pitch, yuv_type)) { + if (yuv_rgb_lsx(src_format, dst_format, width, height, y, u, v, y_stride, uv_stride, (Uint8 *)dst, dst_pitch, yuv_type)) { + return 0; + } + + if (yuv_rgb_std(src_format, dst_format, width, height, y, u, v, y_stride, uv_stride, (Uint8 *)dst, dst_pitch, yuv_type)) { return 0; } @@ -427,8 +596,8 @@ SDL_ConvertPixels_YUV_to_RGB(int width, int height, void *tmp; int tmp_pitch = (width * sizeof(Uint32)); - tmp = SDL_malloc(tmp_pitch * height); - if (tmp == NULL) { + tmp = SDL_malloc((size_t)tmp_pitch * height); + if (!tmp) { return SDL_OutOfMemory(); } @@ -456,37 +625,35 @@ struct RGB2YUVFactors float v[3]; /* Rfactor, Gfactor, Bfactor */ }; -static int -SDL_ConvertPixels_ARGB8888_to_YUV(int width, int height, const void *src, int src_pitch, Uint32 dst_format, 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, int dst_pitch) { - const int src_pitch_x_2 = src_pitch * 2; - const int height_half = height / 2; + const int src_pitch_x_2 = src_pitch * 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); + const int width_half = width / 2; + const int width_remainder = (width & 0x1); int i, j; - - static struct RGB2YUVFactors RGB2YUVFactorTables[SDL_YUV_CONVERSION_BT709 + 1] = - { + + static struct RGB2YUVFactors RGB2YUVFactorTables[SDL_YUV_CONVERSION_BT709 + 1] = { /* ITU-T T.871 (JPEG) */ { 0, - { 0.2990f, 0.5870f, 0.1140f }, - { -0.1687f, -0.3313f, 0.5000f }, - { 0.5000f, -0.4187f, -0.0813f }, + { 0.2990f, 0.5870f, 0.1140f }, + { -0.1687f, -0.3313f, 0.5000f }, + { 0.5000f, -0.4187f, -0.0813f }, }, /* ITU-R BT.601-7 */ { 16, - { 0.2568f, 0.5041f, 0.0979f }, - { -0.1482f, -0.2910f, 0.4392f }, - { 0.4392f, -0.3678f, -0.0714f }, + { 0.2568f, 0.5041f, 0.0979f }, + { -0.1482f, -0.2910f, 0.4392f }, + { 0.4392f, -0.3678f, -0.0714f }, }, /* ITU-R BT.709-6 */ { 16, - { 0.1826f, 0.6142f, 0.0620f }, - {-0.1006f, -0.3386f, 0.4392f }, + { 0.1826f, 0.6142f, 0.0620f }, + { -0.1006f, -0.3386f, 0.4392f }, { 0.4392f, -0.3989f, -0.0403f }, }, }; @@ -496,276 +663,266 @@ SDL_ConvertPixels_ARGB8888_to_YUV(int width, int height, const void *src, int sr #define MAKE_U(r, g, b) (Uint8)((int)(cvt->u[0] * (r) + cvt->u[1] * (g) + cvt->u[2] * (b) + 0.5f) + 128) #define MAKE_V(r, g, b) (Uint8)((int)(cvt->v[0] * (r) + cvt->v[1] * (g) + cvt->v[2] * (b) + 0.5f) + 128) -#define READ_2x2_PIXELS \ - 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 r = ((p1 & 0x00ff0000) + (p2 & 0x00ff0000) + (p3 & 0x00ff0000) + (p4 & 0x00ff0000)) >> 18; \ - const Uint32 g = ((p1 & 0x0000ff00) + (p2 & 0x0000ff00) + (p3 & 0x0000ff00) + (p4 & 0x0000ff00)) >> 10; \ - const Uint32 b = ((p1 & 0x000000ff) + (p2 & 0x000000ff) + (p3 & 0x000000ff) + (p4 & 0x000000ff)) >> 2; \ +#define READ_2x2_PIXELS \ + 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 r = ((p1 & 0x00ff0000) + (p2 & 0x00ff0000) + (p3 & 0x00ff0000) + (p4 & 0x00ff0000)) >> 18; \ + const Uint32 g = ((p1 & 0x0000ff00) + (p2 & 0x0000ff00) + (p3 & 0x0000ff00) + (p4 & 0x0000ff00)) >> 10; \ + const Uint32 b = ((p1 & 0x000000ff) + (p2 & 0x000000ff) + (p3 & 0x000000ff) + (p4 & 0x000000ff)) >> 2; -#define READ_2x1_PIXELS \ - const Uint32 p1 = ((const Uint32 *)curr_row)[2 * i]; \ - const Uint32 p2 = ((const Uint32 *)next_row)[2 * i]; \ - const Uint32 r = ((p1 & 0x00ff0000) + (p2 & 0x00ff0000)) >> 17; \ - const Uint32 g = ((p1 & 0x0000ff00) + (p2 & 0x0000ff00)) >> 9; \ - const Uint32 b = ((p1 & 0x000000ff) + (p2 & 0x000000ff)) >> 1; \ +#define READ_2x1_PIXELS \ + const Uint32 p1 = ((const Uint32 *)curr_row)[2 * i]; \ + const Uint32 p2 = ((const Uint32 *)next_row)[2 * i]; \ + const Uint32 r = ((p1 & 0x00ff0000) + (p2 & 0x00ff0000)) >> 17; \ + const Uint32 g = ((p1 & 0x0000ff00) + (p2 & 0x0000ff00)) >> 9; \ + const Uint32 b = ((p1 & 0x000000ff) + (p2 & 0x000000ff)) >> 1; -#define READ_1x2_PIXELS \ - const Uint32 p1 = ((const Uint32 *)curr_row)[2 * i]; \ - const Uint32 p2 = ((const Uint32 *)curr_row)[2 * i + 1]; \ - const Uint32 r = ((p1 & 0x00ff0000) + (p2 & 0x00ff0000)) >> 17; \ - const Uint32 g = ((p1 & 0x0000ff00) + (p2 & 0x0000ff00)) >> 9; \ - const Uint32 b = ((p1 & 0x000000ff) + (p2 & 0x000000ff)) >> 1; \ +#define READ_1x2_PIXELS \ + const Uint32 p1 = ((const Uint32 *)curr_row)[2 * i]; \ + const Uint32 p2 = ((const Uint32 *)curr_row)[2 * i + 1]; \ + const Uint32 r = ((p1 & 0x00ff0000) + (p2 & 0x00ff0000)) >> 17; \ + const Uint32 g = ((p1 & 0x0000ff00) + (p2 & 0x0000ff00)) >> 9; \ + const Uint32 b = ((p1 & 0x000000ff) + (p2 & 0x000000ff)) >> 1; -#define READ_1x1_PIXEL \ - const Uint32 p = ((const Uint32 *)curr_row)[2 * i]; \ - const Uint32 r = (p & 0x00ff0000) >> 16; \ - const Uint32 g = (p & 0x0000ff00) >> 8; \ - const Uint32 b = (p & 0x000000ff); \ +#define READ_1x1_PIXEL \ + const Uint32 p = ((const Uint32 *)curr_row)[2 * i]; \ + const Uint32 r = (p & 0x00ff0000) >> 16; \ + const Uint32 g = (p & 0x0000ff00) >> 8; \ + const Uint32 b = (p & 0x000000ff); -#define READ_TWO_RGB_PIXELS \ - const Uint32 p = ((const Uint32 *)curr_row)[2 * i]; \ - const Uint32 r = (p & 0x00ff0000) >> 16; \ - const Uint32 g = (p & 0x0000ff00) >> 8; \ - const Uint32 b = (p & 0x000000ff); \ - const Uint32 p1 = ((const Uint32 *)curr_row)[2 * i + 1]; \ - const Uint32 r1 = (p1 & 0x00ff0000) >> 16; \ - const Uint32 g1 = (p1 & 0x0000ff00) >> 8; \ - const Uint32 b1 = (p1 & 0x000000ff); \ - const Uint32 R = (r + r1)/2; \ - const Uint32 G = (g + g1)/2; \ - const Uint32 B = (b + b1)/2; \ +#define READ_TWO_RGB_PIXELS \ + const Uint32 p = ((const Uint32 *)curr_row)[2 * i]; \ + const Uint32 r = (p & 0x00ff0000) >> 16; \ + const Uint32 g = (p & 0x0000ff00) >> 8; \ + const Uint32 b = (p & 0x000000ff); \ + const Uint32 p1 = ((const Uint32 *)curr_row)[2 * i + 1]; \ + const Uint32 r1 = (p1 & 0x00ff0000) >> 16; \ + const Uint32 g1 = (p1 & 0x0000ff00) >> 8; \ + const Uint32 b1 = (p1 & 0x000000ff); \ + const Uint32 R = (r + r1) / 2; \ + const Uint32 G = (g + g1) / 2; \ + const Uint32 B = (b + b1) / 2; -#define READ_ONE_RGB_PIXEL READ_1x1_PIXEL +#define READ_ONE_RGB_PIXEL READ_1x1_PIXEL - switch (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 *plane_u; - Uint8 *plane_v; - Uint8 *plane_interleaved_uv; - Uint32 y_stride, uv_stride, y_skip, uv_skip; + { + const Uint8 *curr_row, *next_row; - GetYUVPlanes(width, height, dst_format, dst, dst_pitch, + Uint8 *plane_y; + Uint8 *plane_u; + Uint8 *plane_v; + Uint8 *plane_interleaved_uv; + Uint32 y_stride, uv_stride, y_skip, uv_skip; + + if (GetYUVPlanes(width, height, dst_format, dst, dst_pitch, (const Uint8 **)&plane_y, (const Uint8 **)&plane_u, (const Uint8 **)&plane_v, - &y_stride, &uv_stride); - plane_interleaved_uv = (plane_y + height * y_stride); - y_skip = (y_stride - width); + &y_stride, &uv_stride) != 0) { + return -1; + } - curr_row = (const Uint8*)src; + plane_interleaved_uv = (plane_y + height * y_stride); + y_skip = (y_stride - width); - /* Write Y plane */ - for (j = 0; j < height; j++) { - for (i = 0; i < width; i++) { - const Uint32 p1 = ((const Uint32 *)curr_row)[i]; - const Uint32 r = (p1 & 0x00ff0000) >> 16; - const Uint32 g = (p1 & 0x0000ff00) >> 8; - const Uint32 b = (p1 & 0x000000ff); - *plane_y++ = MAKE_Y(r, g, b); - } - plane_y += y_skip; - curr_row += src_pitch; + curr_row = (const Uint8 *)src; + + /* Write Y plane */ + for (j = 0; j < height; j++) { + for (i = 0; i < width; i++) { + const Uint32 p1 = ((const Uint32 *)curr_row)[i]; + const Uint32 r = (p1 & 0x00ff0000) >> 16; + const Uint32 g = (p1 & 0x0000ff00) >> 8; + const Uint32 b = (p1 & 0x000000ff); + *plane_y++ = MAKE_Y(r, g, b); } + plane_y += y_skip; + curr_row += src_pitch; + } - curr_row = (const Uint8*)src; - next_row = (const Uint8*)src; - next_row += src_pitch; + curr_row = (const Uint8 *)src; + next_row = (const Uint8 *)src; + next_row += src_pitch; - if (dst_format == SDL_PIXELFORMAT_YV12 || dst_format == SDL_PIXELFORMAT_IYUV) - { - /* Write UV planes, not interleaved */ - uv_skip = (uv_stride - (width + 1)/2); - 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); - } - plane_u += uv_skip; - plane_v += uv_skip; - curr_row += src_pitch_x_2; - next_row += src_pitch_x_2; + if (dst_format == SDL_PIXELFORMAT_YV12 || dst_format == SDL_PIXELFORMAT_IYUV) { + /* Write UV planes, not interleaved */ + uv_skip = (uv_stride - (width + 1) / 2); + 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 (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); - } - plane_u += uv_skip; - plane_v += uv_skip; + if (width_remainder) { + READ_2x1_PIXELS; + *plane_u++ = MAKE_U(r, g, b); + *plane_v++ = MAKE_V(r, g, b); + } + plane_u += uv_skip; + plane_v += uv_skip; + 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); + } + plane_u += uv_skip; + plane_v += uv_skip; + } + } else if (dst_format == SDL_PIXELFORMAT_NV12) { + uv_skip = (uv_stride - ((width + 1) / 2) * 2); + 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); + } + plane_interleaved_uv += uv_skip; + 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 if (dst_format == SDL_PIXELFORMAT_NV12) - { - uv_skip = (uv_stride - ((width + 1)/2)*2); - 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); - } - plane_interleaved_uv += uv_skip; - curr_row += src_pitch_x_2; - next_row += src_pitch_x_2; + } else /* dst_format == SDL_PIXELFORMAT_NV21 */ { + uv_skip = (uv_stride - ((width + 1) / 2) * 2); + 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 (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); - } + if (width_remainder) { + READ_2x1_PIXELS; + *plane_interleaved_uv++ = MAKE_V(r, g, b); + *plane_interleaved_uv++ = MAKE_U(r, g, b); } - } - else /* dst_format == SDL_PIXELFORMAT_NV21 */ - { - uv_skip = (uv_stride - ((width + 1)/2)*2); - 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); - } - plane_interleaved_uv += uv_skip; - curr_row += src_pitch_x_2; - next_row += src_pitch_x_2; + plane_interleaved_uv += uv_skip; + 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 (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); - } + if (width_remainder) { + READ_1x1_PIXEL; + *plane_interleaved_uv++ = MAKE_V(r, g, b); + *plane_interleaved_uv++ = MAKE_U(r, g, b); } } } - break; + } break; case SDL_PIXELFORMAT_YUY2: case SDL_PIXELFORMAT_UYVY: case SDL_PIXELFORMAT_YVYU: - { - const Uint8 *curr_row = (const Uint8*) src; - Uint8 *plane = (Uint8*) dst; - const int row_size = (4 * ((width + 1) / 2)); - int plane_skip; + { + const Uint8 *curr_row = (const Uint8 *)src; + Uint8 *plane = (Uint8 *)dst; + const int row_size = (4 * ((width + 1) / 2)); + int plane_skip; - if (dst_pitch < row_size) { - return SDL_SetError("Destination pitch is too small, expected at least %d\n", row_size); - } - plane_skip = (dst_pitch - row_size); + if (dst_pitch < row_size) { + return SDL_SetError("Destination pitch is too small, expected at least %d\n", row_size); + } + plane_skip = (dst_pitch - row_size); - /* 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); - } - plane += plane_skip; - curr_row += src_pitch; + /* 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); } - } - 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); - } - plane += plane_skip; - curr_row += src_pitch; + 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); } + plane += plane_skip; + 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); - } - plane += plane_skip; - 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); + } + plane += plane_skip; + 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); + } + plane += plane_skip; + curr_row += src_pitch; } } - break; + } break; default: return SDL_SetError("Unsupported YUV destination format: %s", SDL_GetPixelFormatName(dst_format)); @@ -782,10 +939,9 @@ SDL_ConvertPixels_ARGB8888_to_YUV(int width, int height, const void *src, int sr return 0; } -int -SDL_ConvertPixels_RGB_to_YUV(int width, int height, - Uint32 src_format, const void *src, int src_pitch, - Uint32 dst_format, void *dst, int dst_pitch) +int SDL_ConvertPixels_RGB_to_YUV(int width, int height, + Uint32 src_format, const void *src, int src_pitch, + Uint32 dst_format, void *dst, int dst_pitch) { #if 0 /* Doesn't handle odd widths */ /* RGB24 to FOURCC */ @@ -821,8 +977,8 @@ SDL_ConvertPixels_RGB_to_YUV(int width, int height, void *tmp; int tmp_pitch = (width * sizeof(Uint32)); - tmp = SDL_malloc(tmp_pitch * height); - if (tmp == NULL) { + tmp = SDL_malloc((size_t)tmp_pitch * height); + if (!tmp) { return SDL_OutOfMemory(); } @@ -840,9 +996,8 @@ SDL_ConvertPixels_RGB_to_YUV(int width, int height, } } -static int -SDL_ConvertPixels_YUV_to_YUV_Copy(int width, int height, Uint32 format, - const void *src, int src_pitch, void *dst, int dst_pitch) +static int SDL_ConvertPixels_YUV_to_YUV_Copy(int width, int height, Uint32 format, + const void *src, int src_pitch, void *dst, int dst_pitch) { int i; @@ -850,8 +1005,8 @@ SDL_ConvertPixels_YUV_to_YUV_Copy(int width, int height, Uint32 format, /* Y plane */ for (i = height; i--;) { SDL_memcpy(dst, src, width); - src = (const Uint8*)src + src_pitch; - dst = (Uint8*)dst + dst_pitch; + src = (const Uint8 *)src + src_pitch; + dst = (Uint8 *)dst + dst_pitch; } if (format == SDL_PIXELFORMAT_YV12 || format == SDL_PIXELFORMAT_IYUV) { @@ -862,19 +1017,19 @@ SDL_ConvertPixels_YUV_to_YUV_Copy(int width, int height, Uint32 format, dst_pitch = (dst_pitch + 1) / 2; for (i = height * 2; i--;) { SDL_memcpy(dst, src, width); - src = (const Uint8*)src + src_pitch; - dst = (Uint8*)dst + dst_pitch; + src = (const Uint8 *)src + src_pitch; + dst = (Uint8 *)dst + dst_pitch; } } else if (format == SDL_PIXELFORMAT_NV12 || format == SDL_PIXELFORMAT_NV21) { /* U/V plane is half the height of the Y plane, rounded up */ height = (height + 1) / 2; - width = ((width + 1) / 2)*2; - src_pitch = ((src_pitch + 1) / 2)*2; - dst_pitch = ((dst_pitch + 1) / 2)*2; + width = ((width + 1) / 2) * 2; + src_pitch = ((src_pitch + 1) / 2) * 2; + dst_pitch = ((dst_pitch + 1) / 2) * 2; for (i = height; i--;) { SDL_memcpy(dst, src, width); - src = (const Uint8*)src + src_pitch; - dst = (Uint8*)dst + dst_pitch; + src = (const Uint8 *)src + src_pitch; + dst = (Uint8 *)dst + dst_pitch; } } return 0; @@ -885,8 +1040,8 @@ SDL_ConvertPixels_YUV_to_YUV_Copy(int width, int height, Uint32 format, 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; + src = (const Uint8 *)src + src_pitch; + dst = (Uint8 *)dst + dst_pitch; } return 0; } @@ -894,19 +1049,18 @@ SDL_ConvertPixels_YUV_to_YUV_Copy(int width, int height, Uint32 format, return SDL_SetError("SDL_ConvertPixels_YUV_to_YUV_Copy: Unsupported YUV format: %s", SDL_GetPixelFormatName(format)); } -static int -SDL_ConvertPixels_SwapUVPlanes(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch) +static int SDL_ConvertPixels_SwapUVPlanes(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch) { int y; - const int UVwidth = (width + 1)/2; - const int UVheight = (height + 1)/2; + const int UVwidth = (width + 1) / 2; + const int UVheight = (height + 1) / 2; /* Skip the Y plane */ src = (const Uint8 *)src + height * src_pitch; dst = (Uint8 *)dst + height * dst_pitch; if (src == dst) { - int UVpitch = (dst_pitch + 1)/2; + int UVpitch = (dst_pitch + 1) / 2; Uint8 *tmp; Uint8 *row1 = dst; Uint8 *row2 = (Uint8 *)dst + UVheight * UVpitch; @@ -927,8 +1081,8 @@ SDL_ConvertPixels_SwapUVPlanes(int width, int height, const void *src, int src_p } else { const Uint8 *srcUV; Uint8 *dstUV; - int srcUVPitch = ((src_pitch + 1)/2); - int dstUVPitch = ((dst_pitch + 1)/2); + int srcUVPitch = ((src_pitch + 1) / 2); + int dstUVPitch = ((dst_pitch + 1) / 2); /* Copy the first plane */ srcUV = (const Uint8 *)src; @@ -950,16 +1104,15 @@ SDL_ConvertPixels_SwapUVPlanes(int width, int height, const void *src, int src_p return 0; } -static int -SDL_ConvertPixels_PackUVPlanes_to_NV(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch, SDL_bool reverseUV) +static int SDL_ConvertPixels_PackUVPlanes_to_NV(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch, SDL_bool reverseUV) { int x, y; - const int UVwidth = (width + 1)/2; - const int UVheight = (height + 1)/2; - const int srcUVPitch = ((src_pitch + 1)/2); + const int UVwidth = (width + 1) / 2; + const int UVheight = (height + 1) / 2; + const int srcUVPitch = ((src_pitch + 1) / 2); const int srcUVPitchLeft = srcUVPitch - UVwidth; - const int dstUVPitch = ((dst_pitch + 1)/2)*2; - const int dstUVPitchLeft = dstUVPitch - UVwidth*2; + const int dstUVPitch = ((dst_pitch + 1) / 2) * 2; + const int dstUVPitchLeft = dstUVPitch - UVwidth * 2; const Uint8 *src1, *src2; Uint8 *dstUV; Uint8 *tmp = NULL; @@ -973,11 +1126,11 @@ SDL_ConvertPixels_PackUVPlanes_to_NV(int width, int height, const void *src, int if (src == dst) { /* Need to make a copy of the buffer so we don't clobber it while converting */ - tmp = (Uint8 *)SDL_malloc(2*UVheight*srcUVPitch); + tmp = (Uint8 *)SDL_malloc((size_t)2 * UVheight * srcUVPitch); if (!tmp) { return SDL_OutOfMemory(); } - SDL_memcpy(tmp, src, 2*UVheight*srcUVPitch); + SDL_memcpy(tmp, src, (size_t)2 * UVheight * srcUVPitch); src = tmp; } @@ -1000,8 +1153,8 @@ SDL_ConvertPixels_PackUVPlanes_to_NV(int width, int height, const void *src, int __m128i v = _mm_loadu_si128((__m128i *)src2); __m128i uv1 = _mm_unpacklo_epi8(u, v); __m128i uv2 = _mm_unpackhi_epi8(u, v); - _mm_storeu_si128((__m128i*)dstUV, uv1); - _mm_storeu_si128((__m128i*)(dstUV + 16), uv2); + _mm_storeu_si128((__m128i *)dstUV, uv1); + _mm_storeu_si128((__m128i *)(dstUV + 16), uv2); src1 += 16; src2 += 16; dstUV += 32; @@ -1024,15 +1177,14 @@ SDL_ConvertPixels_PackUVPlanes_to_NV(int width, int height, const void *src, int return 0; } -static int -SDL_ConvertPixels_SplitNV_to_UVPlanes(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch, SDL_bool reverseUV) +static int SDL_ConvertPixels_SplitNV_to_UVPlanes(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch, SDL_bool reverseUV) { int x, y; - const int UVwidth = (width + 1)/2; - const int UVheight = (height + 1)/2; - const int srcUVPitch = ((src_pitch + 1)/2)*2; - const int srcUVPitchLeft = srcUVPitch - UVwidth*2; - const int dstUVPitch = ((dst_pitch + 1)/2); + const int UVwidth = (width + 1) / 2; + const int UVheight = (height + 1) / 2; + const int srcUVPitch = ((src_pitch + 1) / 2) * 2; + const int srcUVPitchLeft = srcUVPitch - UVwidth * 2; + const int dstUVPitch = ((dst_pitch + 1) / 2); const int dstUVPitchLeft = dstUVPitch - UVwidth; const Uint8 *srcUV; Uint8 *dst1, *dst2; @@ -1047,11 +1199,11 @@ SDL_ConvertPixels_SplitNV_to_UVPlanes(int width, int height, const void *src, in if (src == dst) { /* Need to make a copy of the buffer so we don't clobber it while converting */ - tmp = (Uint8 *)SDL_malloc(UVheight*srcUVPitch); + tmp = (Uint8 *)SDL_malloc((size_t)UVheight * srcUVPitch); if (!tmp) { return SDL_OutOfMemory(); } - SDL_memcpy(tmp, src, UVheight*srcUVPitch); + SDL_memcpy(tmp, src, (size_t)UVheight * srcUVPitch); src = tmp; } @@ -1071,16 +1223,16 @@ SDL_ConvertPixels_SplitNV_to_UVPlanes(int width, int height, const void *src, in if (use_SSE2) { __m128i mask = _mm_set1_epi16(0x00FF); while (x >= 16) { - __m128i uv1 = _mm_loadu_si128((__m128i*)srcUV); - __m128i uv2 = _mm_loadu_si128((__m128i*)(srcUV+16)); + __m128i uv1 = _mm_loadu_si128((__m128i *)srcUV); + __m128i uv2 = _mm_loadu_si128((__m128i *)(srcUV + 16)); __m128i u1 = _mm_and_si128(uv1, mask); __m128i u2 = _mm_and_si128(uv2, mask); __m128i u = _mm_packus_epi16(u1, u2); __m128i v1 = _mm_srli_epi16(uv1, 8); __m128i v2 = _mm_srli_epi16(uv2, 8); __m128i v = _mm_packus_epi16(v1, v2); - _mm_storeu_si128((__m128i*)dst1, u); - _mm_storeu_si128((__m128i*)dst2, v); + _mm_storeu_si128((__m128i *)dst1, u); + _mm_storeu_si128((__m128i *)dst2, v); srcUV += 32; dst1 += 16; dst2 += 16; @@ -1103,16 +1255,15 @@ SDL_ConvertPixels_SplitNV_to_UVPlanes(int width, int height, const void *src, in return 0; } -static int -SDL_ConvertPixels_SwapNV(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch) +static int SDL_ConvertPixels_SwapNV(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch) { int x, y; - const int UVwidth = (width + 1)/2; - const int UVheight = (height + 1)/2; - const int srcUVPitch = ((src_pitch + 1)/2)*2; - const int srcUVPitchLeft = (srcUVPitch - UVwidth*2)/sizeof(Uint16); - const int dstUVPitch = ((dst_pitch + 1)/2)*2; - const int dstUVPitchLeft = (dstUVPitch - UVwidth*2)/sizeof(Uint16); + const int UVwidth = (width + 1) / 2; + const int UVheight = (height + 1) / 2; + const int srcUVPitch = ((src_pitch + 1) / 2) * 2; + const int srcUVPitchLeft = (srcUVPitch - UVwidth * 2) / sizeof(Uint16); + const int dstUVPitch = ((dst_pitch + 1) / 2) * 2; + const int dstUVPitchLeft = (dstUVPitch - UVwidth * 2) / sizeof(Uint16); const Uint16 *srcUV; Uint16 *dstUV; #ifdef __SSE2__ @@ -1131,11 +1282,11 @@ SDL_ConvertPixels_SwapNV(int width, int height, const void *src, int src_pitch, #ifdef __SSE2__ if (use_SSE2) { while (x >= 8) { - __m128i uv = _mm_loadu_si128((__m128i*)srcUV); + __m128i uv = _mm_loadu_si128((__m128i *)srcUV); __m128i v = _mm_slli_epi16(uv, 8); __m128i u = _mm_srli_epi16(uv, 8); __m128i vu = _mm_or_si128(v, u); - _mm_storeu_si128((__m128i*)dstUV, vu); + _mm_storeu_si128((__m128i *)dstUV, vu); srcUV += 8; dstUV += 8; x -= 8; @@ -1151,17 +1302,16 @@ SDL_ConvertPixels_SwapNV(int width, int height, const void *src, int src_pitch, return 0; } -static int -SDL_ConvertPixels_Planar2x2_to_Planar2x2(int width, int height, - Uint32 src_format, const void *src, int src_pitch, - Uint32 dst_format, void *dst, int dst_pitch) +static int SDL_ConvertPixels_Planar2x2_to_Planar2x2(int width, int height, + Uint32 src_format, const void *src, int src_pitch, + Uint32 dst_format, void *dst, int dst_pitch) { if (src != dst) { /* Copy Y plane */ int i; const Uint8 *srcY = (const Uint8 *)src; Uint8 *dstY = (Uint8 *)dst; - for (i = height; i--; ) { + for (i = height; i--;) { SDL_memcpy(dstY, srcY, width); srcY += src_pitch; dstY += dst_pitch; @@ -1220,35 +1370,35 @@ SDL_ConvertPixels_Planar2x2_to_Planar2x2(int width, int height, default: break; } - return SDL_SetError("SDL_ConvertPixels_Planar2x2_to_Planar2x2: Unsupported YUV conversion: %s -> %s", SDL_GetPixelFormatName(src_format), SDL_GetPixelFormatName(dst_format)); + return SDL_SetError("SDL_ConvertPixels_Planar2x2_to_Planar2x2: Unsupported YUV conversion: %s -> %s", SDL_GetPixelFormatName(src_format), + SDL_GetPixelFormatName(dst_format)); } #ifdef __SSE2__ -#define PACKED4_TO_PACKED4_ROW_SSE2(shuffle) \ - while (x >= 4) { \ - __m128i yuv = _mm_loadu_si128((__m128i*)srcYUV); \ - __m128i lo = _mm_unpacklo_epi8(yuv, _mm_setzero_si128()); \ - __m128i hi = _mm_unpackhi_epi8(yuv, _mm_setzero_si128()); \ - lo = _mm_shufflelo_epi16(lo, shuffle); \ - lo = _mm_shufflehi_epi16(lo, shuffle); \ - hi = _mm_shufflelo_epi16(hi, shuffle); \ - hi = _mm_shufflehi_epi16(hi, shuffle); \ - yuv = _mm_packus_epi16(lo, hi); \ - _mm_storeu_si128((__m128i*)dstYUV, yuv); \ - srcYUV += 16; \ - dstYUV += 16; \ - x -= 4; \ - } \ +#define PACKED4_TO_PACKED4_ROW_SSE2(shuffle) \ + while (x >= 4) { \ + __m128i yuv = _mm_loadu_si128((__m128i *)srcYUV); \ + __m128i lo = _mm_unpacklo_epi8(yuv, _mm_setzero_si128()); \ + __m128i hi = _mm_unpackhi_epi8(yuv, _mm_setzero_si128()); \ + lo = _mm_shufflelo_epi16(lo, shuffle); \ + lo = _mm_shufflehi_epi16(lo, shuffle); \ + hi = _mm_shufflelo_epi16(hi, shuffle); \ + hi = _mm_shufflehi_epi16(hi, shuffle); \ + yuv = _mm_packus_epi16(lo, hi); \ + _mm_storeu_si128((__m128i *)dstYUV, yuv); \ + srcYUV += 16; \ + dstYUV += 16; \ + x -= 4; \ + } #endif -static int -SDL_ConvertPixels_YUY2_to_UYVY(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch) +static int SDL_ConvertPixels_YUY2_to_UYVY(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch) { int x, y; - const int YUVwidth = (width + 1)/2; - const int srcYUVPitchLeft = (src_pitch - YUVwidth*4); - const int dstYUVPitchLeft = (dst_pitch - YUVwidth*4); + const int YUVwidth = (width + 1) / 2; + const int srcYUVPitchLeft = (src_pitch - YUVwidth * 4); + const int dstYUVPitchLeft = (dst_pitch - YUVwidth * 4); const Uint8 *srcYUV = (const Uint8 *)src; Uint8 *dstYUV = (Uint8 *)dst; #ifdef __SSE2__ @@ -1284,13 +1434,12 @@ SDL_ConvertPixels_YUY2_to_UYVY(int width, int height, const void *src, int src_p return 0; } -static int -SDL_ConvertPixels_YUY2_to_YVYU(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch) +static int SDL_ConvertPixels_YUY2_to_YVYU(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch) { int x, y; - const int YUVwidth = (width + 1)/2; - const int srcYUVPitchLeft = (src_pitch - YUVwidth*4); - const int dstYUVPitchLeft = (dst_pitch - YUVwidth*4); + const int YUVwidth = (width + 1) / 2; + const int srcYUVPitchLeft = (src_pitch - YUVwidth * 4); + const int dstYUVPitchLeft = (dst_pitch - YUVwidth * 4); const Uint8 *srcYUV = (const Uint8 *)src; Uint8 *dstYUV = (Uint8 *)dst; #ifdef __SSE2__ @@ -1326,13 +1475,12 @@ SDL_ConvertPixels_YUY2_to_YVYU(int width, int height, const void *src, int src_p return 0; } -static int -SDL_ConvertPixels_UYVY_to_YUY2(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch) +static int SDL_ConvertPixels_UYVY_to_YUY2(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch) { int x, y; - const int YUVwidth = (width + 1)/2; - const int srcYUVPitchLeft = (src_pitch - YUVwidth*4); - const int dstYUVPitchLeft = (dst_pitch - YUVwidth*4); + const int YUVwidth = (width + 1) / 2; + const int srcYUVPitchLeft = (src_pitch - YUVwidth * 4); + const int dstYUVPitchLeft = (dst_pitch - YUVwidth * 4); const Uint8 *srcYUV = (const Uint8 *)src; Uint8 *dstYUV = (Uint8 *)dst; #ifdef __SSE2__ @@ -1368,13 +1516,12 @@ SDL_ConvertPixels_UYVY_to_YUY2(int width, int height, const void *src, int src_p return 0; } -static int -SDL_ConvertPixels_UYVY_to_YVYU(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch) +static int SDL_ConvertPixels_UYVY_to_YVYU(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch) { int x, y; - const int YUVwidth = (width + 1)/2; - const int srcYUVPitchLeft = (src_pitch - YUVwidth*4); - const int dstYUVPitchLeft = (dst_pitch - YUVwidth*4); + const int YUVwidth = (width + 1) / 2; + const int srcYUVPitchLeft = (src_pitch - YUVwidth * 4); + const int dstYUVPitchLeft = (dst_pitch - YUVwidth * 4); const Uint8 *srcYUV = (const Uint8 *)src; Uint8 *dstYUV = (Uint8 *)dst; #ifdef __SSE2__ @@ -1410,13 +1557,12 @@ SDL_ConvertPixels_UYVY_to_YVYU(int width, int height, const void *src, int src_p return 0; } -static int -SDL_ConvertPixels_YVYU_to_YUY2(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch) +static int SDL_ConvertPixels_YVYU_to_YUY2(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch) { int x, y; - const int YUVwidth = (width + 1)/2; - const int srcYUVPitchLeft = (src_pitch - YUVwidth*4); - const int dstYUVPitchLeft = (dst_pitch - YUVwidth*4); + const int YUVwidth = (width + 1) / 2; + const int srcYUVPitchLeft = (src_pitch - YUVwidth * 4); + const int dstYUVPitchLeft = (dst_pitch - YUVwidth * 4); const Uint8 *srcYUV = (const Uint8 *)src; Uint8 *dstYUV = (Uint8 *)dst; #ifdef __SSE2__ @@ -1452,13 +1598,12 @@ SDL_ConvertPixels_YVYU_to_YUY2(int width, int height, const void *src, int src_p return 0; } -static int -SDL_ConvertPixels_YVYU_to_UYVY(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch) +static int SDL_ConvertPixels_YVYU_to_UYVY(int width, int height, const void *src, int src_pitch, void *dst, int dst_pitch) { int x, y; - const int YUVwidth = (width + 1)/2; - const int srcYUVPitchLeft = (src_pitch - YUVwidth*4); - const int dstYUVPitchLeft = (dst_pitch - YUVwidth*4); + const int YUVwidth = (width + 1) / 2; + const int srcYUVPitchLeft = (src_pitch - YUVwidth * 4); + const int dstYUVPitchLeft = (dst_pitch - YUVwidth * 4); const Uint8 *srcYUV = (const Uint8 *)src; Uint8 *dstYUV = (Uint8 *)dst; #ifdef __SSE2__ @@ -1494,10 +1639,9 @@ SDL_ConvertPixels_YVYU_to_UYVY(int width, int height, const void *src, int src_p return 0; } -static int -SDL_ConvertPixels_Packed4_to_Packed4(int width, int height, - Uint32 src_format, const void *src, int src_pitch, - Uint32 dst_format, void *dst, int dst_pitch) +static int SDL_ConvertPixels_Packed4_to_Packed4(int width, int height, + Uint32 src_format, const void *src, int src_pitch, + Uint32 dst_format, void *dst, int dst_pitch) { switch (src_format) { case SDL_PIXELFORMAT_YUY2: @@ -1533,13 +1677,13 @@ SDL_ConvertPixels_Packed4_to_Packed4(int width, int height, default: break; } - return SDL_SetError("SDL_ConvertPixels_Packed4_to_Packed4: Unsupported YUV conversion: %s -> %s", SDL_GetPixelFormatName(src_format), SDL_GetPixelFormatName(dst_format)); + return SDL_SetError("SDL_ConvertPixels_Packed4_to_Packed4: Unsupported YUV conversion: %s -> %s", SDL_GetPixelFormatName(src_format), + SDL_GetPixelFormatName(dst_format)); } -static int -SDL_ConvertPixels_Planar2x2_to_Packed4(int width, int height, - Uint32 src_format, const void *src, int src_pitch, - Uint32 dst_format, void *dst, int dst_pitch) +static int SDL_ConvertPixels_Planar2x2_to_Packed4(int width, int height, + Uint32 src_format, const void *src, int src_pitch, + Uint32 dst_format, void *dst, int dst_pitch) { int x, y; const Uint8 *srcY1, *srcY2, *srcU, *srcV; @@ -1562,10 +1706,10 @@ SDL_ConvertPixels_Planar2x2_to_Packed4(int width, int height, if (src_format == SDL_PIXELFORMAT_NV12 || src_format == SDL_PIXELFORMAT_NV21) { srcUV_pixel_stride = 2; - srcUV_pitch_left = (srcUV_pitch - 2*((width + 1)/2)); + srcUV_pitch_left = (srcUV_pitch - 2 * ((width + 1) / 2)); } else { srcUV_pixel_stride = 1; - srcUV_pitch_left = (srcUV_pitch - ((width + 1)/2)); + srcUV_pitch_left = (srcUV_pitch - ((width + 1) / 2)); } if (GetYUVPlanes(width, height, dst_format, dst, dst_pitch, @@ -1576,7 +1720,7 @@ SDL_ConvertPixels_Planar2x2_to_Packed4(int width, int height, dstY2 = dstY1 + dstY_pitch; dstU2 = dstU1 + dstUV_pitch; dstV2 = dstV1 + dstUV_pitch; - dst_pitch_left = (dstY_pitch - 4*((width + 1)/2)); + dst_pitch_left = (dstY_pitch - 4 * ((width + 1) / 2)); /* Copy 2x2 blocks of pixels at a time */ for (y = 0; y < (height - 1); y += 2) { @@ -1679,10 +1823,9 @@ SDL_ConvertPixels_Planar2x2_to_Packed4(int width, int height, return 0; } -static int -SDL_ConvertPixels_Packed4_to_Planar2x2(int width, int height, - Uint32 src_format, const void *src, int src_pitch, - Uint32 dst_format, void *dst, int dst_pitch) +static int SDL_ConvertPixels_Packed4_to_Planar2x2(int width, int height, + Uint32 src_format, const void *src, int src_pitch, + Uint32 dst_format, void *dst, int dst_pitch) { int x, y; const Uint8 *srcY1, *srcY2, *srcU1, *srcU2, *srcV1, *srcV2; @@ -1703,7 +1846,7 @@ SDL_ConvertPixels_Packed4_to_Planar2x2(int width, int height, srcY2 = srcY1 + srcY_pitch; srcU2 = srcU1 + srcUV_pitch; srcV2 = srcV1 + srcUV_pitch; - src_pitch_left = (srcY_pitch - 4*((width + 1)/2)); + src_pitch_left = (srcY_pitch - 4 * ((width + 1) / 2)); if (GetYUVPlanes(width, height, dst_format, dst, dst_pitch, (const Uint8 **)&dstY1, (const Uint8 **)&dstU, (const Uint8 **)&dstV, @@ -1715,10 +1858,10 @@ SDL_ConvertPixels_Packed4_to_Planar2x2(int width, int height, if (dst_format == SDL_PIXELFORMAT_NV12 || dst_format == SDL_PIXELFORMAT_NV21) { dstUV_pixel_stride = 2; - dstUV_pitch_left = (dstUV_pitch - 2*((width + 1)/2)); + dstUV_pitch_left = (dstUV_pitch - 2 * ((width + 1) / 2)); } else { dstUV_pixel_stride = 1; - dstUV_pitch_left = (dstUV_pitch - ((width + 1)/2)); + dstUV_pitch_left = (dstUV_pitch - ((width + 1) / 2)); } /* Copy 2x2 blocks of pixels at a time */ @@ -1736,8 +1879,8 @@ SDL_ConvertPixels_Packed4_to_Planar2x2(int width, int height, *dstY2++ = *srcY2; srcY2 += 2; - *dstU = (Uint8)(((Uint32)*srcU1 + *srcU2)/2); - *dstV = (Uint8)(((Uint32)*srcV1 + *srcV2)/2); + *dstU = (Uint8)(((Uint32)*srcU1 + *srcU2) / 2); + *dstV = (Uint8)(((Uint32)*srcV1 + *srcV2) / 2); srcU1 += 4; srcU2 += 4; @@ -1761,8 +1904,8 @@ SDL_ConvertPixels_Packed4_to_Planar2x2(int width, int height, *dstY2++ = *srcY2; srcY2 += 2; - *dstU = (Uint8)(((Uint32)*srcU1 + *srcU2)/2); - *dstV = (Uint8)(((Uint32)*srcV1 + *srcV2)/2); + *dstU = (Uint8)(((Uint32)*srcU1 + *srcU2) / 2); + *dstV = (Uint8)(((Uint32)*srcV1 + *srcV2) / 2); srcU1 += 4; srcU2 += 4; @@ -1813,10 +1956,9 @@ SDL_ConvertPixels_Packed4_to_Planar2x2(int width, int height, #endif /* SDL_HAVE_YUV */ -int -SDL_ConvertPixels_YUV_to_YUV(int width, int height, - Uint32 src_format, const void *src, int src_pitch, - Uint32 dst_format, void *dst, int dst_pitch) +int SDL_ConvertPixels_YUV_to_YUV(int width, int height, + Uint32 src_format, const void *src, int src_pitch, + Uint32 dst_format, void *dst, int dst_pitch) { #if SDL_HAVE_YUV if (src_format == dst_format) { @@ -1836,10 +1978,11 @@ SDL_ConvertPixels_YUV_to_YUV(int width, int height, } else if (IsPacked4Format(src_format) && IsPlanar2x2Format(dst_format)) { return SDL_ConvertPixels_Packed4_to_Planar2x2(width, height, src_format, src, src_pitch, dst_format, dst, dst_pitch); } else { - return SDL_SetError("SDL_ConvertPixels_YUV_to_YUV: Unsupported YUV conversion: %s -> %s", SDL_GetPixelFormatName(src_format), SDL_GetPixelFormatName(dst_format)); + return SDL_SetError("SDL_ConvertPixels_YUV_to_YUV: Unsupported YUV conversion: %s -> %s", SDL_GetPixelFormatName(src_format), + SDL_GetPixelFormatName(dst_format)); } #else - return SDL_SetError("SDL not built with YUV support"); + return SDL_SetError("SDL not built with YUV support"); #endif } diff --git a/SDL2-2.0.12/src/video/SDL_yuv_c.h b/SDL2-2.30.5/src/video/SDL_yuv_c.h similarity index 91% rename from SDL2-2.0.12/src/video/SDL_yuv_c.h rename to SDL2-2.30.5/src/video/SDL_yuv_c.h index 9b43631..3fda84b 100644 --- a/SDL2-2.0.12/src/video/SDL_yuv_c.h +++ b/SDL2-2.30.5/src/video/SDL_yuv_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -24,13 +24,15 @@ #include "../SDL_internal.h" - /* YUV conversion functions */ extern int SDL_ConvertPixels_YUV_to_RGB(int width, int height, Uint32 src_format, const void *src, int src_pitch, Uint32 dst_format, void *dst, int dst_pitch); extern int SDL_ConvertPixels_RGB_to_YUV(int width, int height, Uint32 src_format, const void *src, int src_pitch, Uint32 dst_format, void *dst, int dst_pitch); extern int SDL_ConvertPixels_YUV_to_YUV(int width, int height, Uint32 src_format, const void *src, int src_pitch, Uint32 dst_format, void *dst, int dst_pitch); + +extern int SDL_CalculateYUVSize(Uint32 format, int w, int h, size_t *size, int *pitch); + #endif /* SDL_yuv_c_h_ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/android/SDL_androidclipboard.c b/SDL2-2.30.5/src/video/android/SDL_androidclipboard.c similarity index 87% rename from SDL2-2.0.12/src/video/android/SDL_androidclipboard.c rename to SDL2-2.30.5/src/video/android/SDL_androidclipboard.c index 19c2262..afd729e 100644 --- a/SDL2-2.0.12/src/video/android/SDL_androidclipboard.c +++ b/SDL2-2.30.5/src/video/android/SDL_androidclipboard.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,20 +20,18 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_ANDROID +#ifdef SDL_VIDEO_DRIVER_ANDROID #include "SDL_androidvideo.h" #include "SDL_androidclipboard.h" #include "../../core/android/SDL_android.h" -int -Android_SetClipboardText(_THIS, const char *text) +int Android_SetClipboardText(_THIS, const char *text) { return Android_JNI_SetClipboardText(text); } -char * -Android_GetClipboardText(_THIS) +char *Android_GetClipboardText(_THIS) { return Android_JNI_GetClipboardText(); } diff --git a/SDL2-2.0.12/src/video/android/SDL_androidclipboard.h b/SDL2-2.30.5/src/video/android/SDL_androidclipboard.h similarity index 95% rename from SDL2-2.0.12/src/video/android/SDL_androidclipboard.h rename to SDL2-2.30.5/src/video/android/SDL_androidclipboard.h index 94c6674..8097d71 100644 --- a/SDL2-2.0.12/src/video/android/SDL_androidclipboard.h +++ b/SDL2-2.30.5/src/video/android/SDL_androidclipboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/video/android/SDL_androidevents.c b/SDL2-2.30.5/src/video/android/SDL_androidevents.c similarity index 76% rename from SDL2-2.0.12/src/video/android/SDL_androidevents.c rename to SDL2-2.30.5/src/video/android/SDL_androidevents.c index 51d2a57..d125c92 100644 --- a/SDL2-2.0.12/src/video/android/SDL_androidevents.c +++ b/SDL2-2.30.5/src/video/android/SDL_androidevents.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,10 +20,11 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_ANDROID +#ifdef SDL_VIDEO_DRIVER_ANDROID #include "SDL_androidevents.h" #include "SDL_events.h" +#include "SDL_hints.h" #include "SDL_androidkeyboard.h" #include "SDL_androidwindow.h" #include "../SDL_sysvideo.h" @@ -32,7 +33,7 @@ /* Can't include sysaudio "../../audio/android/SDL_androidaudio.h" * because of THIS redefinition */ -#if !SDL_AUDIO_DISABLED && SDL_AUDIO_DRIVER_ANDROID +#if !defined(SDL_AUDIO_DISABLED) && defined(SDL_AUDIO_DRIVER_ANDROID) extern void ANDROIDAUDIO_ResumeDevices(void); extern void ANDROIDAUDIO_PauseDevices(void); #else @@ -40,31 +41,45 @@ static void ANDROIDAUDIO_ResumeDevices(void) {} static void ANDROIDAUDIO_PauseDevices(void) {} #endif -#if !SDL_AUDIO_DISABLED && SDL_AUDIO_DRIVER_OPENSLES +#if !defined(SDL_AUDIO_DISABLED) && defined(SDL_AUDIO_DRIVER_OPENSLES) extern void openslES_ResumeDevices(void); extern void openslES_PauseDevices(void); #else -static void openslES_ResumeDevices(void) {} +static void openslES_ResumeDevices(void) +{ +} static void openslES_PauseDevices(void) {} #endif +#if !defined(SDL_AUDIO_DISABLED) && defined(SDL_AUDIO_DRIVER_AAUDIO) +extern void aaudio_ResumeDevices(void); +extern void aaudio_PauseDevices(void); +SDL_bool aaudio_DetectBrokenPlayState(void); +#else +static void aaudio_ResumeDevices(void) +{ +} +static void aaudio_PauseDevices(void) {} +static SDL_bool aaudio_DetectBrokenPlayState(void) { return SDL_FALSE; } +#endif + /* Number of 'type' events in the event queue */ -static int -SDL_NumberOfEvents(Uint32 type) +static int SDL_NumberOfEvents(Uint32 type) { return SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, type, type); } -static void -android_egl_context_restore(SDL_Window *window) +#ifdef SDL_VIDEO_OPENGL_EGL +static void android_egl_context_restore(SDL_Window *window) { if (window) { SDL_Event event; - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - if (SDL_GL_MakeCurrent(window, (SDL_GLContext) data->egl_context) < 0) { + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + SDL_GL_MakeCurrent(window, NULL); + if (SDL_GL_MakeCurrent(window, (SDL_GLContext)data->egl_context) < 0) { /* The context is no longer valid, create a new one */ - data->egl_context = (EGLContext) SDL_GL_CreateContext(window); - SDL_GL_MakeCurrent(window, (SDL_GLContext) data->egl_context); + data->egl_context = (EGLContext)SDL_GL_CreateContext(window); + SDL_GL_MakeCurrent(window, (SDL_GLContext)data->egl_context); event.type = SDL_RENDER_DEVICE_RESET; SDL_PushEvent(&event); } @@ -72,19 +87,18 @@ android_egl_context_restore(SDL_Window *window) } } -static void -android_egl_context_backup(SDL_Window *window) +static void android_egl_context_backup(SDL_Window *window) { if (window) { /* Keep a copy of the EGL Context so we can try to restore it when we resume */ - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; data->egl_context = SDL_GL_GetCurrentContext(); /* We need to do this so the EGLSurface can be freed */ SDL_GL_MakeCurrent(window, NULL); data->backup_done = 1; } } - +#endif /* * Android_ResumeSem and Android_PauseSem are signaled from Java_org_libsdl_app_SDLActivity_nativePause and Java_org_libsdl_app_SDLActivity_nativeResume @@ -93,23 +107,25 @@ android_egl_context_backup(SDL_Window *window) * No polling necessary */ -void -Android_PumpEvents_Blocking(_THIS) +void Android_PumpEvents_Blocking(_THIS) { SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; if (videodata->isPaused) { SDL_bool isContextExternal = SDL_IsVideoContextExternal(); +#ifdef SDL_VIDEO_OPENGL_EGL /* Make sure this is the last thing we do before pausing */ if (!isContextExternal) { SDL_LockMutex(Android_ActivityMutex); android_egl_context_backup(Android_Window); SDL_UnlockMutex(Android_ActivityMutex); } +#endif ANDROIDAUDIO_PauseDevices(); openslES_PauseDevices(); + aaudio_PauseDevices(); if (SDL_SemWait(Android_ResumeSem) == 0) { @@ -122,18 +138,19 @@ Android_PumpEvents_Blocking(_THIS) ANDROIDAUDIO_ResumeDevices(); openslES_ResumeDevices(); + aaudio_ResumeDevices(); /* Restore the GL Context from here, as this operation is thread dependent */ +#ifdef SDL_VIDEO_OPENGL_EGL if (!isContextExternal && !SDL_HasEvent(SDL_QUIT)) { SDL_LockMutex(Android_ActivityMutex); android_egl_context_restore(Android_Window); SDL_UnlockMutex(Android_ActivityMutex); } +#endif /* Make sure SW Keyboard is restored when an app becomes foreground */ - if (SDL_IsTextInputActive()) { - Android_StartTextInput(_this); /* Only showTextInput */ - } + Android_RestoreScreenKeyboardOnResume(_this, Android_Window); } } else { if (videodata->isPausing || SDL_SemTryWait(Android_PauseSem) == 0) { @@ -156,10 +173,14 @@ Android_PumpEvents_Blocking(_THIS) } } } + + if (aaudio_DetectBrokenPlayState()) { + aaudio_PauseDevices(); + aaudio_ResumeDevices(); + } } -void -Android_PumpEvents_NonBlocking(_THIS) +void Android_PumpEvents_NonBlocking(_THIS) { SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; static int backup_context = 0; @@ -169,19 +190,23 @@ Android_PumpEvents_NonBlocking(_THIS) SDL_bool isContextExternal = SDL_IsVideoContextExternal(); if (backup_context) { +#ifdef SDL_VIDEO_OPENGL_EGL if (!isContextExternal) { SDL_LockMutex(Android_ActivityMutex); android_egl_context_backup(Android_Window); SDL_UnlockMutex(Android_ActivityMutex); } +#endif - ANDROIDAUDIO_PauseDevices(); - openslES_PauseDevices(); + if (videodata->pauseAudio) { + ANDROIDAUDIO_PauseDevices(); + openslES_PauseDevices(); + aaudio_PauseDevices(); + } backup_context = 0; } - if (SDL_SemTryWait(Android_ResumeSem) == 0) { videodata->isPaused = 0; @@ -191,20 +216,23 @@ Android_PumpEvents_NonBlocking(_THIS) SDL_SendAppEvent(SDL_APP_DIDENTERFOREGROUND); SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_RESTORED, 0, 0); - ANDROIDAUDIO_ResumeDevices(); - openslES_ResumeDevices(); + if (videodata->pauseAudio) { + ANDROIDAUDIO_ResumeDevices(); + openslES_ResumeDevices(); + aaudio_ResumeDevices(); + } +#ifdef SDL_VIDEO_OPENGL_EGL /* Restore the GL Context from here, as this operation is thread dependent */ if (!isContextExternal && !SDL_HasEvent(SDL_QUIT)) { SDL_LockMutex(Android_ActivityMutex); android_egl_context_restore(Android_Window); SDL_UnlockMutex(Android_ActivityMutex); } +#endif /* Make sure SW Keyboard is restored when an app becomes foreground */ - if (SDL_IsTextInputActive()) { - Android_StartTextInput(_this); /* Only showTextInput */ - } + Android_RestoreScreenKeyboardOnResume(_this, Android_Window); } } else { if (videodata->isPausing || SDL_SemTryWait(Android_PauseSem) == 0) { @@ -228,6 +256,11 @@ Android_PumpEvents_NonBlocking(_THIS) } } } + + if (aaudio_DetectBrokenPlayState()) { + aaudio_PauseDevices(); + aaudio_ResumeDevices(); + } } #endif /* SDL_VIDEO_DRIVER_ANDROID */ diff --git a/SDL2-2.0.12/src/video/android/SDL_androidevents.h b/SDL2-2.30.5/src/video/android/SDL_androidevents.h similarity index 94% rename from SDL2-2.0.12/src/video/android/SDL_androidevents.h rename to SDL2-2.30.5/src/video/android/SDL_androidevents.h index d985ea2..921daa6 100644 --- a/SDL2-2.0.12/src/video/android/SDL_androidevents.h +++ b/SDL2-2.30.5/src/video/android/SDL_androidevents.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/video/android/SDL_androidgl.c b/SDL2-2.30.5/src/video/android/SDL_androidgl.c similarity index 71% rename from SDL2-2.0.12/src/video/android/SDL_androidgl.c rename to SDL2-2.30.5/src/video/android/SDL_androidgl.c index 8c02084..5e5ef60 100644 --- a/SDL2-2.0.12/src/video/android/SDL_androidgl.c +++ b/SDL2-2.30.5/src/video/android/SDL_androidgl.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_ANDROID +#if defined(SDL_VIDEO_DRIVER_ANDROID) && defined(SDL_VIDEO_OPENGL_EGL) /* Android SDL video driver implementation */ @@ -36,32 +36,29 @@ #include -int -Android_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) +int Android_GLES_MakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context) { if (window && context) { - return SDL_EGL_MakeCurrent(_this, ((SDL_WindowData *) window->driverdata)->egl_surface, context); + return SDL_EGL_MakeCurrent(_this, ((SDL_WindowData *)window->driverdata)->egl_surface, context); } else { return SDL_EGL_MakeCurrent(_this, NULL, NULL); } } -SDL_GLContext -Android_GLES_CreateContext(_THIS, SDL_Window * window) +SDL_GLContext Android_GLES_CreateContext(_THIS, SDL_Window *window) { SDL_GLContext ret; Android_ActivityMutex_Lock_Running(); - ret = SDL_EGL_CreateContext(_this, ((SDL_WindowData *) window->driverdata)->egl_surface); + ret = SDL_EGL_CreateContext(_this, ((SDL_WindowData *)window->driverdata)->egl_surface); SDL_UnlockMutex(Android_ActivityMutex); return ret; } -int -Android_GLES_SwapWindow(_THIS, SDL_Window * window) +int Android_GLES_SwapWindow(_THIS, SDL_Window *window) { int retval; @@ -69,21 +66,21 @@ Android_GLES_SwapWindow(_THIS, SDL_Window * window) /* The following two calls existed in the original Java code * If you happen to have a device that's affected by their removal, - * please report to Bugzilla. -- Gabriel + * please report to our bug tracker. -- Gabriel */ /*_this->egl_data->eglWaitNative(EGL_CORE_NATIVE_ENGINE); _this->egl_data->eglWaitGL();*/ - retval = SDL_EGL_SwapBuffers(_this, ((SDL_WindowData *) window->driverdata)->egl_surface); + retval = SDL_EGL_SwapBuffers(_this, ((SDL_WindowData *)window->driverdata)->egl_surface); SDL_UnlockMutex(Android_ActivityMutex); return retval; } -int -Android_GLES_LoadLibrary(_THIS, const char *path) { - return SDL_EGL_LoadLibrary(_this, path, (NativeDisplayType) 0, 0); +int Android_GLES_LoadLibrary(_THIS, const char *path) +{ + return SDL_EGL_LoadLibrary(_this, path, (NativeDisplayType)0, 0); } #endif /* SDL_VIDEO_DRIVER_ANDROID */ diff --git a/SDL2-2.0.12/src/video/android/SDL_androidgl.h b/SDL2-2.30.5/src/video/android/SDL_androidgl.h similarity index 80% rename from SDL2-2.0.12/src/video/android/SDL_androidgl.h rename to SDL2-2.30.5/src/video/android/SDL_androidgl.h index 5cbdaba..4fb505c 100644 --- a/SDL2-2.0.12/src/video/android/SDL_androidgl.h +++ b/SDL2-2.30.5/src/video/android/SDL_androidgl.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,12 +23,11 @@ #ifndef SDL_androidgl_h_ #define SDL_androidgl_h_ -SDL_GLContext Android_GLES_CreateContext(_THIS, SDL_Window * window); -int Android_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context); -int Android_GLES_SwapWindow(_THIS, SDL_Window * window); +SDL_GLContext Android_GLES_CreateContext(_THIS, SDL_Window *window); +int Android_GLES_MakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context); +int Android_GLES_SwapWindow(_THIS, SDL_Window *window); int Android_GLES_LoadLibrary(_THIS, const char *path); - #endif /* SDL_androidgl_h_ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/android/SDL_androidkeyboard.c b/SDL2-2.30.5/src/video/android/SDL_androidkeyboard.c new file mode 100644 index 0000000..b55de02 --- /dev/null +++ b/SDL2-2.30.5/src/video/android/SDL_androidkeyboard.c @@ -0,0 +1,385 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_ANDROID + +#include + +#include "../../events/SDL_events_c.h" + +#include "SDL_androidkeyboard.h" + +#include "../../core/android/SDL_android.h" + +static SDL_Scancode Android_Keycodes[] = { + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_UNKNOWN */ + SDL_SCANCODE_SOFTLEFT, /* AKEYCODE_SOFT_LEFT */ + SDL_SCANCODE_SOFTRIGHT, /* AKEYCODE_SOFT_RIGHT */ + SDL_SCANCODE_AC_HOME, /* AKEYCODE_HOME */ + SDL_SCANCODE_AC_BACK, /* AKEYCODE_BACK */ + SDL_SCANCODE_CALL, /* AKEYCODE_CALL */ + SDL_SCANCODE_ENDCALL, /* AKEYCODE_ENDCALL */ + SDL_SCANCODE_0, /* AKEYCODE_0 */ + SDL_SCANCODE_1, /* AKEYCODE_1 */ + SDL_SCANCODE_2, /* AKEYCODE_2 */ + SDL_SCANCODE_3, /* AKEYCODE_3 */ + SDL_SCANCODE_4, /* AKEYCODE_4 */ + SDL_SCANCODE_5, /* AKEYCODE_5 */ + SDL_SCANCODE_6, /* AKEYCODE_6 */ + SDL_SCANCODE_7, /* AKEYCODE_7 */ + SDL_SCANCODE_8, /* AKEYCODE_8 */ + SDL_SCANCODE_9, /* AKEYCODE_9 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_STAR */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_POUND */ + SDL_SCANCODE_UP, /* AKEYCODE_DPAD_UP */ + SDL_SCANCODE_DOWN, /* AKEYCODE_DPAD_DOWN */ + SDL_SCANCODE_LEFT, /* AKEYCODE_DPAD_LEFT */ + SDL_SCANCODE_RIGHT, /* AKEYCODE_DPAD_RIGHT */ + SDL_SCANCODE_SELECT, /* AKEYCODE_DPAD_CENTER */ + SDL_SCANCODE_VOLUMEUP, /* AKEYCODE_VOLUME_UP */ + SDL_SCANCODE_VOLUMEDOWN, /* AKEYCODE_VOLUME_DOWN */ + SDL_SCANCODE_POWER, /* AKEYCODE_POWER */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_CAMERA */ + SDL_SCANCODE_CLEAR, /* AKEYCODE_CLEAR */ + SDL_SCANCODE_A, /* AKEYCODE_A */ + SDL_SCANCODE_B, /* AKEYCODE_B */ + SDL_SCANCODE_C, /* AKEYCODE_C */ + SDL_SCANCODE_D, /* AKEYCODE_D */ + SDL_SCANCODE_E, /* AKEYCODE_E */ + SDL_SCANCODE_F, /* AKEYCODE_F */ + SDL_SCANCODE_G, /* AKEYCODE_G */ + SDL_SCANCODE_H, /* AKEYCODE_H */ + SDL_SCANCODE_I, /* AKEYCODE_I */ + SDL_SCANCODE_J, /* AKEYCODE_J */ + SDL_SCANCODE_K, /* AKEYCODE_K */ + SDL_SCANCODE_L, /* AKEYCODE_L */ + SDL_SCANCODE_M, /* AKEYCODE_M */ + SDL_SCANCODE_N, /* AKEYCODE_N */ + SDL_SCANCODE_O, /* AKEYCODE_O */ + SDL_SCANCODE_P, /* AKEYCODE_P */ + SDL_SCANCODE_Q, /* AKEYCODE_Q */ + SDL_SCANCODE_R, /* AKEYCODE_R */ + SDL_SCANCODE_S, /* AKEYCODE_S */ + SDL_SCANCODE_T, /* AKEYCODE_T */ + SDL_SCANCODE_U, /* AKEYCODE_U */ + SDL_SCANCODE_V, /* AKEYCODE_V */ + SDL_SCANCODE_W, /* AKEYCODE_W */ + SDL_SCANCODE_X, /* AKEYCODE_X */ + SDL_SCANCODE_Y, /* AKEYCODE_Y */ + SDL_SCANCODE_Z, /* AKEYCODE_Z */ + SDL_SCANCODE_COMMA, /* AKEYCODE_COMMA */ + SDL_SCANCODE_PERIOD, /* AKEYCODE_PERIOD */ + SDL_SCANCODE_LALT, /* AKEYCODE_ALT_LEFT */ + SDL_SCANCODE_RALT, /* AKEYCODE_ALT_RIGHT */ + SDL_SCANCODE_LSHIFT, /* AKEYCODE_SHIFT_LEFT */ + SDL_SCANCODE_RSHIFT, /* AKEYCODE_SHIFT_RIGHT */ + SDL_SCANCODE_TAB, /* AKEYCODE_TAB */ + SDL_SCANCODE_SPACE, /* AKEYCODE_SPACE */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_SYM */ + SDL_SCANCODE_WWW, /* AKEYCODE_EXPLORER */ + SDL_SCANCODE_MAIL, /* AKEYCODE_ENVELOPE */ + SDL_SCANCODE_RETURN, /* AKEYCODE_ENTER */ + SDL_SCANCODE_BACKSPACE, /* AKEYCODE_DEL */ + SDL_SCANCODE_GRAVE, /* AKEYCODE_GRAVE */ + SDL_SCANCODE_MINUS, /* AKEYCODE_MINUS */ + SDL_SCANCODE_EQUALS, /* AKEYCODE_EQUALS */ + SDL_SCANCODE_LEFTBRACKET, /* AKEYCODE_LEFT_BRACKET */ + SDL_SCANCODE_RIGHTBRACKET, /* AKEYCODE_RIGHT_BRACKET */ + SDL_SCANCODE_BACKSLASH, /* AKEYCODE_BACKSLASH */ + SDL_SCANCODE_SEMICOLON, /* AKEYCODE_SEMICOLON */ + SDL_SCANCODE_APOSTROPHE, /* AKEYCODE_APOSTROPHE */ + SDL_SCANCODE_SLASH, /* AKEYCODE_SLASH */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_AT */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_NUM */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_HEADSETHOOK */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_FOCUS */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_PLUS */ + SDL_SCANCODE_MENU, /* AKEYCODE_MENU */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_NOTIFICATION */ + SDL_SCANCODE_AC_SEARCH, /* AKEYCODE_SEARCH */ + SDL_SCANCODE_AUDIOPLAY, /* AKEYCODE_MEDIA_PLAY_PAUSE */ + SDL_SCANCODE_AUDIOSTOP, /* AKEYCODE_MEDIA_STOP */ + SDL_SCANCODE_AUDIONEXT, /* AKEYCODE_MEDIA_NEXT */ + SDL_SCANCODE_AUDIOPREV, /* AKEYCODE_MEDIA_PREVIOUS */ + SDL_SCANCODE_AUDIOREWIND, /* AKEYCODE_MEDIA_REWIND */ + SDL_SCANCODE_AUDIOFASTFORWARD, /* AKEYCODE_MEDIA_FAST_FORWARD */ + SDL_SCANCODE_MUTE, /* AKEYCODE_MUTE */ + SDL_SCANCODE_PAGEUP, /* AKEYCODE_PAGE_UP */ + SDL_SCANCODE_PAGEDOWN, /* AKEYCODE_PAGE_DOWN */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_PICTSYMBOLS */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_SWITCH_CHARSET */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_A */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_B */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_C */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_X */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_Y */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_Z */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_L1 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_R1 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_L2 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_R2 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_THUMBL */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_THUMBR */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_START */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_SELECT */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_MODE */ + SDL_SCANCODE_ESCAPE, /* AKEYCODE_ESCAPE */ + SDL_SCANCODE_DELETE, /* AKEYCODE_FORWARD_DEL */ + SDL_SCANCODE_LCTRL, /* AKEYCODE_CTRL_LEFT */ + SDL_SCANCODE_RCTRL, /* AKEYCODE_CTRL_RIGHT */ + SDL_SCANCODE_CAPSLOCK, /* AKEYCODE_CAPS_LOCK */ + SDL_SCANCODE_SCROLLLOCK, /* AKEYCODE_SCROLL_LOCK */ + SDL_SCANCODE_LGUI, /* AKEYCODE_META_LEFT */ + SDL_SCANCODE_RGUI, /* AKEYCODE_META_RIGHT */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_FUNCTION */ + SDL_SCANCODE_PRINTSCREEN, /* AKEYCODE_SYSRQ */ + SDL_SCANCODE_PAUSE, /* AKEYCODE_BREAK */ + SDL_SCANCODE_HOME, /* AKEYCODE_MOVE_HOME */ + SDL_SCANCODE_END, /* AKEYCODE_MOVE_END */ + SDL_SCANCODE_INSERT, /* AKEYCODE_INSERT */ + SDL_SCANCODE_AC_FORWARD, /* AKEYCODE_FORWARD */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_PLAY */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_PAUSE */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_CLOSE */ + SDL_SCANCODE_EJECT, /* AKEYCODE_MEDIA_EJECT */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_RECORD */ + SDL_SCANCODE_F1, /* AKEYCODE_F1 */ + SDL_SCANCODE_F2, /* AKEYCODE_F2 */ + SDL_SCANCODE_F3, /* AKEYCODE_F3 */ + SDL_SCANCODE_F4, /* AKEYCODE_F4 */ + SDL_SCANCODE_F5, /* AKEYCODE_F5 */ + SDL_SCANCODE_F6, /* AKEYCODE_F6 */ + SDL_SCANCODE_F7, /* AKEYCODE_F7 */ + SDL_SCANCODE_F8, /* AKEYCODE_F8 */ + SDL_SCANCODE_F9, /* AKEYCODE_F9 */ + SDL_SCANCODE_F10, /* AKEYCODE_F10 */ + SDL_SCANCODE_F11, /* AKEYCODE_F11 */ + SDL_SCANCODE_F12, /* AKEYCODE_F12 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_NUM_LOCK */ + SDL_SCANCODE_KP_0, /* AKEYCODE_NUMPAD_0 */ + SDL_SCANCODE_KP_1, /* AKEYCODE_NUMPAD_1 */ + SDL_SCANCODE_KP_2, /* AKEYCODE_NUMPAD_2 */ + SDL_SCANCODE_KP_3, /* AKEYCODE_NUMPAD_3 */ + SDL_SCANCODE_KP_4, /* AKEYCODE_NUMPAD_4 */ + SDL_SCANCODE_KP_5, /* AKEYCODE_NUMPAD_5 */ + SDL_SCANCODE_KP_6, /* AKEYCODE_NUMPAD_6 */ + SDL_SCANCODE_KP_7, /* AKEYCODE_NUMPAD_7 */ + SDL_SCANCODE_KP_8, /* AKEYCODE_NUMPAD_8 */ + SDL_SCANCODE_KP_9, /* AKEYCODE_NUMPAD_9 */ + SDL_SCANCODE_KP_DIVIDE, /* AKEYCODE_NUMPAD_DIVIDE */ + SDL_SCANCODE_KP_MULTIPLY, /* AKEYCODE_NUMPAD_MULTIPLY */ + SDL_SCANCODE_KP_MINUS, /* AKEYCODE_NUMPAD_SUBTRACT */ + SDL_SCANCODE_KP_PLUS, /* AKEYCODE_NUMPAD_ADD */ + SDL_SCANCODE_KP_PERIOD, /* AKEYCODE_NUMPAD_DOT */ + SDL_SCANCODE_KP_COMMA, /* AKEYCODE_NUMPAD_COMMA */ + SDL_SCANCODE_KP_ENTER, /* AKEYCODE_NUMPAD_ENTER */ + SDL_SCANCODE_KP_EQUALS, /* AKEYCODE_NUMPAD_EQUALS */ + SDL_SCANCODE_KP_LEFTPAREN, /* AKEYCODE_NUMPAD_LEFT_PAREN */ + SDL_SCANCODE_KP_RIGHTPAREN, /* AKEYCODE_NUMPAD_RIGHT_PAREN */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_VOLUME_MUTE */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_INFO */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_CHANNEL_UP */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_CHANNEL_DOWN */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_ZOOM_IN */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_ZOOM_OUT */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_WINDOW */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_GUIDE */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_DVR */ + SDL_SCANCODE_AC_BOOKMARKS, /* AKEYCODE_BOOKMARK */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_CAPTIONS */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_SETTINGS */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_POWER */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_INPUT */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_STB_POWER */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_STB_INPUT */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_AVR_POWER */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_AVR_INPUT */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_PROG_RED */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_PROG_GREEN */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_PROG_YELLOW */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_PROG_BLUE */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_APP_SWITCH */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_1 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_2 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_3 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_4 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_5 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_6 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_7 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_8 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_9 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_10 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_11 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_12 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_13 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_14 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_15 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_16 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_LANGUAGE_SWITCH */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MANNER_MODE */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_3D_MODE */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_CONTACTS */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_CALENDAR */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MUSIC */ + SDL_SCANCODE_CALCULATOR, /* AKEYCODE_CALCULATOR */ + SDL_SCANCODE_LANG5, /* AKEYCODE_ZENKAKU_HANKAKU */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_EISU */ + SDL_SCANCODE_INTERNATIONAL5, /* AKEYCODE_MUHENKAN */ + SDL_SCANCODE_INTERNATIONAL4, /* AKEYCODE_HENKAN */ + SDL_SCANCODE_LANG3, /* AKEYCODE_KATAKANA_HIRAGANA */ + SDL_SCANCODE_INTERNATIONAL3, /* AKEYCODE_YEN */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_RO */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_KANA */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_ASSIST */ + SDL_SCANCODE_BRIGHTNESSDOWN, /* AKEYCODE_BRIGHTNESS_DOWN */ + SDL_SCANCODE_BRIGHTNESSUP, /* AKEYCODE_BRIGHTNESS_UP */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_AUDIO_TRACK */ + SDL_SCANCODE_SLEEP, /* AKEYCODE_SLEEP */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_WAKEUP */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_PAIRING */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_TOP_MENU */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_11 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_12 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_LAST_CHANNEL */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_DATA_SERVICE */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_VOICE_ASSIST */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_RADIO_SERVICE */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_TELETEXT */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_NUMBER_ENTRY */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_TERRESTRIAL_ANALOG */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_TERRESTRIAL_DIGITAL */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_SATELLITE */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_SATELLITE_BS */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_SATELLITE_CS */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_SATELLITE_SERVICE */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_NETWORK */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_ANTENNA_CABLE */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_INPUT_HDMI_1 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_INPUT_HDMI_2 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_INPUT_HDMI_3 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_INPUT_HDMI_4 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_INPUT_COMPOSITE_1 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_INPUT_COMPOSITE_2 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_INPUT_COMPONENT_1 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_INPUT_COMPONENT_2 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_INPUT_VGA_1 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_AUDIO_DESCRIPTION */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_AUDIO_DESCRIPTION_MIX_UP */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_AUDIO_DESCRIPTION_MIX_DOWN */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_ZOOM_MODE */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_CONTENTS_MENU */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_MEDIA_CONTEXT_MENU */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_TIMER_PROGRAMMING */ + SDL_SCANCODE_HELP, /* AKEYCODE_HELP */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_NAVIGATE_PREVIOUS */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_NAVIGATE_NEXT */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_NAVIGATE_IN */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_NAVIGATE_OUT */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_STEM_PRIMARY */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_STEM_1 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_STEM_2 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_STEM_3 */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_DPAD_UP_LEFT */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_DPAD_DOWN_LEFT */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_DPAD_UP_RIGHT */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_DPAD_DOWN_RIGHT */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_SKIP_FORWARD */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_SKIP_BACKWARD */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_STEP_FORWARD */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_STEP_BACKWARD */ + SDL_SCANCODE_UNKNOWN, /* AKEYCODE_SOFT_SLEEP */ + SDL_SCANCODE_CUT, /* AKEYCODE_CUT */ + SDL_SCANCODE_COPY, /* AKEYCODE_COPY */ + SDL_SCANCODE_PASTE, /* AKEYCODE_PASTE */ +}; + +static SDL_bool SDL_screen_keyboard_shown; + +static SDL_Scancode TranslateKeycode(int keycode) +{ + SDL_Scancode scancode = SDL_SCANCODE_UNKNOWN; + + if (keycode < SDL_arraysize(Android_Keycodes)) { + scancode = Android_Keycodes[keycode]; + } + if (scancode == SDL_SCANCODE_UNKNOWN) { + __android_log_print(ANDROID_LOG_INFO, "SDL", "Unknown keycode %d", keycode); + } + return scancode; +} + +int Android_OnKeyDown(int keycode) +{ + return SDL_SendKeyboardKey(SDL_PRESSED, TranslateKeycode(keycode)); +} + +int Android_OnKeyUp(int keycode) +{ + return SDL_SendKeyboardKey(SDL_RELEASED, TranslateKeycode(keycode)); +} + +SDL_bool Android_HasScreenKeyboardSupport(_THIS) +{ + return SDL_TRUE; +} + +void Android_ShowScreenKeyboard(_THIS, SDL_Window *window) +{ + SDL_VideoData *videodata = _this->driverdata; + Android_JNI_ShowScreenKeyboard(&videodata->textRect); + SDL_screen_keyboard_shown = SDL_TRUE; +} + +void Android_HideScreenKeyboard(_THIS, SDL_Window *window) +{ + Android_JNI_HideScreenKeyboard(); + SDL_screen_keyboard_shown = SDL_FALSE; +} + +void Android_RestoreScreenKeyboardOnResume(_THIS, SDL_Window *window) +{ + if (SDL_screen_keyboard_shown) { + Android_ShowScreenKeyboard(_this, window); + } +} + +SDL_bool Android_IsScreenKeyboardShown(_THIS, SDL_Window *window) +{ + return Android_JNI_IsScreenKeyboardShown(); +} + +void Android_SetTextInputRect(_THIS, const SDL_Rect *rect) +{ + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + + if (!rect) { + SDL_InvalidParamError("rect"); + return; + } + + videodata->textRect = *rect; +} + +#endif /* SDL_VIDEO_DRIVER_ANDROID */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/android/SDL_androidkeyboard.h b/SDL2-2.30.5/src/video/android/SDL_androidkeyboard.h similarity index 77% rename from SDL2-2.0.12/src/video/android/SDL_androidkeyboard.h rename to SDL2-2.30.5/src/video/android/SDL_androidkeyboard.h index c617d41..4081ac6 100644 --- a/SDL2-2.0.12/src/video/android/SDL_androidkeyboard.h +++ b/SDL2-2.30.5/src/video/android/SDL_androidkeyboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -22,15 +22,14 @@ #include "SDL_androidvideo.h" -extern void Android_InitKeyboard(void); extern int Android_OnKeyDown(int keycode); extern int Android_OnKeyUp(int keycode); extern SDL_bool Android_HasScreenKeyboardSupport(_THIS); -extern SDL_bool Android_IsScreenKeyboardShown(_THIS, SDL_Window * window); - -extern void Android_StartTextInput(_THIS); -extern void Android_StopTextInput(_THIS); -extern void Android_SetTextInputRect(_THIS, SDL_Rect *rect); +extern void Android_ShowScreenKeyboard(_THIS, SDL_Window *window); +extern void Android_HideScreenKeyboard(_THIS, SDL_Window *window); +extern void Android_RestoreScreenKeyboardOnResume(_THIS, SDL_Window *window); +extern SDL_bool Android_IsScreenKeyboardShown(_THIS, SDL_Window *window); +extern void Android_SetTextInputRect(_THIS, const SDL_Rect *rect); /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/android/SDL_androidmessagebox.c b/SDL2-2.30.5/src/video/android/SDL_androidmessagebox.c similarity index 86% rename from SDL2-2.0.12/src/video/android/SDL_androidmessagebox.c rename to SDL2-2.30.5/src/video/android/SDL_androidmessagebox.c index abc2ce9..cb2ad28 100644 --- a/SDL2-2.0.12/src/video/android/SDL_androidmessagebox.c +++ b/SDL2-2.30.5/src/video/android/SDL_androidmessagebox.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,14 +20,13 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_ANDROID +#ifdef SDL_VIDEO_DRIVER_ANDROID #include "SDL_messagebox.h" #include "SDL_androidmessagebox.h" #include "../../core/android/SDL_android.h" -int -Android_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) +int Android_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) { return Android_JNI_ShowMessageBox(messageboxdata, buttonid); } diff --git a/SDL2-2.0.12/src/video/android/SDL_androidmessagebox.h b/SDL2-2.30.5/src/video/android/SDL_androidmessagebox.h similarity index 92% rename from SDL2-2.0.12/src/video/android/SDL_androidmessagebox.h rename to SDL2-2.30.5/src/video/android/SDL_androidmessagebox.h index d9eb984..7c93c0e 100644 --- a/SDL2-2.0.12/src/video/android/SDL_androidmessagebox.h +++ b/SDL2-2.30.5/src/video/android/SDL_androidmessagebox.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_ANDROID +#ifdef SDL_VIDEO_DRIVER_ANDROID extern int Android_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid); diff --git a/SDL2-2.0.12/src/video/android/SDL_androidmouse.c b/SDL2-2.30.5/src/video/android/SDL_androidmouse.c similarity index 68% rename from SDL2-2.0.12/src/video/android/SDL_androidmouse.c rename to SDL2-2.30.5/src/video/android/SDL_androidmouse.c index 8f49862..29ee05e 100644 --- a/SDL2-2.0.12/src/video/android/SDL_androidmouse.c +++ b/SDL2-2.30.5/src/video/android/SDL_androidmouse.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -21,7 +21,7 @@ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_ANDROID +#ifdef SDL_VIDEO_DRIVER_ANDROID #include "SDL_androidmouse.h" @@ -31,16 +31,16 @@ #include "../../core/android/SDL_android.h" /* See Android's MotionEvent class for constants */ -#define ACTION_DOWN 0 -#define ACTION_UP 1 -#define ACTION_MOVE 2 +#define ACTION_DOWN 0 +#define ACTION_UP 1 +#define ACTION_MOVE 2 #define ACTION_HOVER_MOVE 7 -#define ACTION_SCROLL 8 -#define BUTTON_PRIMARY 1 -#define BUTTON_SECONDARY 2 -#define BUTTON_TERTIARY 4 -#define BUTTON_BACK 8 -#define BUTTON_FORWARD 16 +#define ACTION_SCROLL 8 +#define BUTTON_PRIMARY 1 +#define BUTTON_SECONDARY 2 +#define BUTTON_TERTIARY 4 +#define BUTTON_BACK 8 +#define BUTTON_FORWARD 16 typedef struct { @@ -55,8 +55,7 @@ static int last_state; /* Blank cursor */ static SDL_Cursor *empty_cursor; -static SDL_Cursor * -Android_WrapCursor(int custom_cursor, int system_cursor) +static SDL_Cursor *Android_WrapCursor(int custom_cursor, int system_cursor) { SDL_Cursor *cursor; @@ -79,14 +78,12 @@ Android_WrapCursor(int custom_cursor, int system_cursor) return cursor; } -static SDL_Cursor * -Android_CreateDefaultCursor() +static SDL_Cursor *Android_CreateDefaultCursor() { return Android_WrapCursor(0, SDL_SYSTEM_CURSOR_ARROW); } -static SDL_Cursor * -Android_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y) +static SDL_Cursor *Android_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y) { int custom_cursor; SDL_Surface *converted; @@ -104,26 +101,27 @@ Android_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y) return Android_WrapCursor(custom_cursor, 0); } -static SDL_Cursor * -Android_CreateSystemCursor(SDL_SystemCursor id) +static SDL_Cursor *Android_CreateSystemCursor(SDL_SystemCursor id) { return Android_WrapCursor(0, id); } -static void -Android_FreeCursor(SDL_Cursor * cursor) +static void Android_FreeCursor(SDL_Cursor *cursor) { + SDL_AndroidCursorData *data = (SDL_AndroidCursorData *)cursor->driverdata; + if (data->custom_cursor != 0) { + Android_JNI_DestroyCustomCursor(data->custom_cursor); + } SDL_free(cursor->driverdata); SDL_free(cursor); } -static SDL_Cursor * -Android_CreateEmptyCursor() +static SDL_Cursor *Android_CreateEmptyCursor() { if (!empty_cursor) { SDL_Surface *empty_surface = SDL_CreateRGBSurfaceWithFormat(0, 1, 1, 32, SDL_PIXELFORMAT_ARGB8888); if (empty_surface) { - SDL_memset(empty_surface->pixels, 0, empty_surface->h * empty_surface->pitch); + SDL_memset(empty_surface->pixels, 0, (size_t)empty_surface->h * empty_surface->pitch); empty_cursor = Android_CreateCursor(empty_surface, 0, 0); SDL_FreeSurface(empty_surface); } @@ -131,8 +129,7 @@ Android_CreateEmptyCursor() return empty_cursor; } -static void -Android_DestroyEmptyCursor() +static void Android_DestroyEmptyCursor() { if (empty_cursor) { Android_FreeCursor(empty_cursor); @@ -140,8 +137,7 @@ Android_DestroyEmptyCursor() } } -static int -Android_ShowCursor(SDL_Cursor *cursor) +static int Android_ShowCursor(SDL_Cursor *cursor) { if (!cursor) { cursor = Android_CreateEmptyCursor(); @@ -164,8 +160,7 @@ Android_ShowCursor(SDL_Cursor *cursor) } } -static int -Android_SetRelativeMouseMode(SDL_bool enabled) +static int Android_SetRelativeMouseMode(SDL_bool enabled) { if (!Android_JNI_SupportsRelativeMouse()) { return SDL_Unsupported(); @@ -178,8 +173,7 @@ Android_SetRelativeMouseMode(SDL_bool enabled) return 0; } -void -Android_InitMouse(void) +void Android_InitMouse(void) { SDL_Mouse *mouse = SDL_GetMouse(); @@ -194,15 +188,13 @@ Android_InitMouse(void) last_state = 0; } -void -Android_QuitMouse(void) +void Android_QuitMouse(void) { Android_DestroyEmptyCursor(); } /* Translate Android mouse button state to SDL mouse button */ -static Uint8 -TranslateButton(int state) +static Uint8 TranslateButton(int state) { if (state & BUTTON_PRIMARY) { return SDL_BUTTON_LEFT; @@ -219,8 +211,7 @@ TranslateButton(int state) } } -void -Android_OnMouse(SDL_Window *window, int state, int action, float x, float y, SDL_bool relative) +void Android_OnMouse(SDL_Window *window, int state, int action, float x, float y, SDL_bool relative) { int changes; Uint8 button; @@ -229,38 +220,37 @@ Android_OnMouse(SDL_Window *window, int state, int action, float x, float y, SDL return; } - switch(action) { - case ACTION_DOWN: - changes = state & ~last_state; - button = TranslateButton(changes); - last_state = state; - SDL_SendMouseMotion(window, 0, relative, (int)x, (int)y); - SDL_SendMouseButton(window, 0, SDL_PRESSED, button); - break; + switch (action) { + case ACTION_DOWN: + changes = state & ~last_state; + button = TranslateButton(changes); + last_state = state; + SDL_SendMouseMotion(window, 0, relative, (int)x, (int)y); + SDL_SendMouseButton(window, 0, SDL_PRESSED, button); + break; - case ACTION_UP: - changes = last_state & ~state; - button = TranslateButton(changes); - last_state = state; - SDL_SendMouseMotion(window, 0, relative, (int)x, (int)y); - SDL_SendMouseButton(window, 0, SDL_RELEASED, button); - break; + case ACTION_UP: + changes = last_state & ~state; + button = TranslateButton(changes); + last_state = state; + SDL_SendMouseMotion(window, 0, relative, (int)x, (int)y); + SDL_SendMouseButton(window, 0, SDL_RELEASED, button); + break; - case ACTION_MOVE: - case ACTION_HOVER_MOVE: - SDL_SendMouseMotion(window, 0, relative, (int)x, (int)y); - break; + case ACTION_MOVE: + case ACTION_HOVER_MOVE: + SDL_SendMouseMotion(window, 0, relative, (int)x, (int)y); + break; - case ACTION_SCROLL: - SDL_SendMouseWheel(window, 0, x, y, SDL_MOUSEWHEEL_NORMAL); - break; + case ACTION_SCROLL: + SDL_SendMouseWheel(window, 0, x, y, SDL_MOUSEWHEEL_NORMAL); + break; - default: - break; + default: + break; } } #endif /* SDL_VIDEO_DRIVER_ANDROID */ /* vi: set ts=4 sw=4 expandtab: */ - diff --git a/SDL2-2.0.12/src/video/android/SDL_androidmouse.h b/SDL2-2.30.5/src/video/android/SDL_androidmouse.h similarity index 95% rename from SDL2-2.0.12/src/video/android/SDL_androidmouse.h rename to SDL2-2.30.5/src/video/android/SDL_androidmouse.h index 71d4d29..6ff7249 100644 --- a/SDL2-2.0.12/src/video/android/SDL_androidmouse.h +++ b/SDL2-2.30.5/src/video/android/SDL_androidmouse.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/video/android/SDL_androidtouch.c b/SDL2-2.30.5/src/video/android/SDL_androidtouch.c similarity index 76% rename from SDL2-2.0.12/src/video/android/SDL_androidtouch.c rename to SDL2-2.30.5/src/video/android/SDL_androidtouch.c index 013eba9..c44f2b0 100644 --- a/SDL2-2.0.12/src/video/android/SDL_androidtouch.c +++ b/SDL2-2.30.5/src/video/android/SDL_androidtouch.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,25 +20,24 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_ANDROID +#ifdef SDL_VIDEO_DRIVER_ANDROID #include #include "SDL_hints.h" #include "SDL_events.h" -#include "SDL_log.h" #include "SDL_androidtouch.h" #include "../../events/SDL_mouse_c.h" #include "../../events/SDL_touch_c.h" #include "../../core/android/SDL_android.h" #define ACTION_DOWN 0 -#define ACTION_UP 1 +#define ACTION_UP 1 #define ACTION_MOVE 2 /* #define ACTION_CANCEL 3 */ /* #define ACTION_OUTSIDE 4 */ #define ACTION_POINTER_DOWN 5 -#define ACTION_POINTER_UP 6 +#define ACTION_POINTER_UP 6 void Android_InitTouch(void) { @@ -66,22 +65,22 @@ void Android_OnTouch(SDL_Window *window, int touch_device_id_in, int pointer_fin fingerId = (SDL_FingerID)pointer_finger_id_in; switch (action) { - case ACTION_DOWN: - case ACTION_POINTER_DOWN: - SDL_SendTouch(touchDeviceId, fingerId, window, SDL_TRUE, x, y, p); - break; + case ACTION_DOWN: + case ACTION_POINTER_DOWN: + SDL_SendTouch(touchDeviceId, fingerId, window, SDL_TRUE, x, y, p); + break; - case ACTION_MOVE: - SDL_SendTouchMotion(touchDeviceId, fingerId, window, x, y, p); - break; + case ACTION_MOVE: + SDL_SendTouchMotion(touchDeviceId, fingerId, window, x, y, p); + break; - case ACTION_UP: - case ACTION_POINTER_UP: - SDL_SendTouch(touchDeviceId, fingerId, window, SDL_FALSE, x, y, p); - break; + case ACTION_UP: + case ACTION_POINTER_UP: + SDL_SendTouch(touchDeviceId, fingerId, window, SDL_FALSE, x, y, p); + break; - default: - break; + default: + break; } } diff --git a/SDL2-2.0.12/src/video/android/SDL_androidtouch.h b/SDL2-2.30.5/src/video/android/SDL_androidtouch.h similarity index 95% rename from SDL2-2.0.12/src/video/android/SDL_androidtouch.h rename to SDL2-2.30.5/src/video/android/SDL_androidtouch.h index 50c57de..067842a 100644 --- a/SDL2-2.0.12/src/video/android/SDL_androidtouch.h +++ b/SDL2-2.30.5/src/video/android/SDL_androidtouch.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/video/android/SDL_androidvideo.c b/SDL2-2.30.5/src/video/android/SDL_androidvideo.c similarity index 62% rename from SDL2-2.0.12/src/video/android/SDL_androidvideo.c rename to SDL2-2.30.5/src/video/android/SDL_androidvideo.c index af0b3e5..f54b4c3 100644 --- a/SDL2-2.0.12/src/video/android/SDL_androidvideo.c +++ b/SDL2-2.30.5/src/video/android/SDL_androidvideo.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_ANDROID +#ifdef SDL_VIDEO_DRIVER_ANDROID /* Android SDL video driver implementation */ @@ -41,6 +41,7 @@ #include "SDL_androidtouch.h" #include "SDL_androidwindow.h" #include "SDL_androidvulkan.h" +#include "SDL_androidmessagebox.h" #define ANDROID_VID_DRIVER_NAME "Android" @@ -54,56 +55,46 @@ int Android_GetDisplayDPI(_THIS, SDL_VideoDisplay *display, float *ddpi, float * #define Android_GLES_UnloadLibrary SDL_EGL_UnloadLibrary #define Android_GLES_SetSwapInterval SDL_EGL_SetSwapInterval #define Android_GLES_GetSwapInterval SDL_EGL_GetSwapInterval -#define Android_GLES_DeleteContext SDL_EGL_DeleteContext +#define Android_GLES_DeleteContext SDL_EGL_DeleteContext /* Android driver bootstrap functions */ - /* These are filled in with real values in Android_SetScreenResolution on init (before SDL_main()) */ -int Android_SurfaceWidth = 0; -int Android_SurfaceHeight = 0; -static int Android_DeviceWidth = 0; -static int Android_DeviceHeight = 0; -static Uint32 Android_ScreenFormat = SDL_PIXELFORMAT_UNKNOWN; -static int Android_ScreenRate = 0; -SDL_sem *Android_PauseSem = NULL; -SDL_sem *Android_ResumeSem = NULL; -SDL_mutex *Android_ActivityMutex = NULL; +int Android_SurfaceWidth = 0; +int Android_SurfaceHeight = 0; +static int Android_DeviceWidth = 0; +static int Android_DeviceHeight = 0; +static Uint32 Android_ScreenFormat = SDL_PIXELFORMAT_RGB565; /* Default SurfaceView format, in case this is queried before being filled */ +static int Android_ScreenRate = 0; +SDL_sem *Android_PauseSem = NULL; +SDL_sem *Android_ResumeSem = NULL; +SDL_mutex *Android_ActivityMutex = NULL; -static int -Android_Available(void) -{ - return 1; -} - -static void -Android_SuspendScreenSaver(_THIS) +static void Android_SuspendScreenSaver(_THIS) { Android_JNI_SuspendScreenSaver(_this->suspend_screensaver); } -static void -Android_DeleteDevice(SDL_VideoDevice *device) +static void Android_DeleteDevice(SDL_VideoDevice *device) { SDL_free(device->driverdata); SDL_free(device); } -static SDL_VideoDevice * -Android_CreateDevice(int devindex) +static SDL_VideoDevice *Android_CreateDevice(void) { SDL_VideoDevice *device; SDL_VideoData *data; SDL_bool block_on_pause; /* Initialize all variables that we clean on shutdown */ - device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice)); + device = (SDL_VideoDevice *)SDL_calloc(1, sizeof(SDL_VideoDevice)); if (!device) { SDL_OutOfMemory(); return NULL; } - data = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData)); + data = (SDL_VideoData *)SDL_calloc(1, sizeof(SDL_VideoData)); if (!data) { SDL_OutOfMemory(); SDL_free(device); @@ -128,12 +119,14 @@ Android_CreateDevice(int devindex) device->SetWindowTitle = Android_SetWindowTitle; device->SetWindowFullscreen = Android_SetWindowFullscreen; device->MinimizeWindow = Android_MinimizeWindow; + device->SetWindowResizable = Android_SetWindowResizable; device->DestroyWindow = Android_DestroyWindow; device->GetWindowWMInfo = Android_GetWindowWMInfo; device->free = Android_DeleteDevice; /* GL pointers */ +#ifdef SDL_VIDEO_OPENGL_EGL device->GL_LoadLibrary = Android_GLES_LoadLibrary; device->GL_GetProcAddress = Android_GLES_GetProcAddress; device->GL_UnloadLibrary = Android_GLES_UnloadLibrary; @@ -143,8 +136,9 @@ Android_CreateDevice(int devindex) device->GL_GetSwapInterval = Android_GLES_GetSwapInterval; device->GL_SwapWindow = Android_GLES_SwapWindow; device->GL_DeleteContext = Android_GLES_DeleteContext; +#endif -#if SDL_VIDEO_VULKAN +#ifdef SDL_VIDEO_VULKAN device->Vulkan_LoadLibrary = Android_Vulkan_LoadLibrary; device->Vulkan_UnloadLibrary = Android_Vulkan_UnloadLibrary; device->Vulkan_GetInstanceExtensions = Android_Vulkan_GetInstanceExtensions; @@ -155,12 +149,12 @@ Android_CreateDevice(int devindex) device->SuspendScreenSaver = Android_SuspendScreenSaver; /* Text input */ - device->StartTextInput = Android_StartTextInput; - device->StopTextInput = Android_StopTextInput; device->SetTextInputRect = Android_SetTextInputRect; /* Screen keyboard */ device->HasScreenKeyboardSupport = Android_HasScreenKeyboardSupport; + device->ShowScreenKeyboard = Android_ShowScreenKeyboard; + device->HideScreenKeyboard = Android_HideScreenKeyboard; device->IsScreenKeyboardShown = Android_IsScreenKeyboardShown; /* Clipboard */ @@ -173,38 +167,36 @@ Android_CreateDevice(int devindex) VideoBootStrap Android_bootstrap = { ANDROID_VID_DRIVER_NAME, "SDL Android video driver", - Android_Available, Android_CreateDevice + Android_CreateDevice, + Android_ShowMessageBox }; - -int -Android_VideoInit(_THIS) +int Android_VideoInit(_THIS) { SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; int display_index; SDL_VideoDisplay *display; SDL_DisplayMode mode; - videodata->isPaused = SDL_FALSE; + videodata->isPaused = SDL_FALSE; videodata->isPausing = SDL_FALSE; + videodata->pauseAudio = SDL_GetHintBoolean(SDL_HINT_ANDROID_BLOCK_ON_PAUSE_PAUSEAUDIO, SDL_TRUE); - mode.format = Android_ScreenFormat; - mode.w = Android_DeviceWidth; - mode.h = Android_DeviceHeight; - mode.refresh_rate = Android_ScreenRate; - mode.driverdata = NULL; + mode.format = Android_ScreenFormat; + mode.w = Android_DeviceWidth; + mode.h = Android_DeviceHeight; + mode.refresh_rate = Android_ScreenRate; + mode.driverdata = NULL; display_index = SDL_AddBasicVideoDisplay(&mode); if (display_index < 0) { return -1; } display = SDL_GetDisplay(display_index); - display->orientation = Android_JNI_GetDisplayOrientation(); + display->orientation = Android_JNI_GetDisplayOrientation(); SDL_AddDisplayMode(&_this->displays[0], &mode); - Android_InitKeyboard(); - Android_InitTouch(); Android_InitMouse(); @@ -213,28 +205,65 @@ Android_VideoInit(_THIS) return 0; } -void -Android_VideoQuit(_THIS) +void Android_VideoQuit(_THIS) { Android_QuitMouse(); Android_QuitTouch(); } -int -Android_GetDisplayDPI(_THIS, SDL_VideoDisplay *display, float *ddpi, float *hdpi, float *vdpi) +int Android_GetDisplayDPI(_THIS, SDL_VideoDisplay *display, float *ddpi, float *hdpi, float *vdpi) { return Android_JNI_GetDisplayDPI(ddpi, hdpi, vdpi); } -void -Android_SetScreenResolution(int surfaceWidth, int surfaceHeight, int deviceWidth, int deviceHeight, Uint32 format, float rate) +void Android_SetScreenResolution(int surfaceWidth, int surfaceHeight, int deviceWidth, int deviceHeight, float rate) { - Android_SurfaceWidth = surfaceWidth; + Android_SurfaceWidth = surfaceWidth; Android_SurfaceHeight = surfaceHeight; - Android_DeviceWidth = deviceWidth; - Android_DeviceHeight = deviceHeight; - Android_ScreenFormat = format; - Android_ScreenRate = (int)rate; + Android_DeviceWidth = deviceWidth; + Android_DeviceHeight = deviceHeight; + Android_ScreenRate = (int)rate; +} + +static Uint32 format_to_pixelFormat(int format) +{ + Uint32 pf; + if (format == AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM) { /* 1 */ + pf = SDL_PIXELFORMAT_RGBA8888; + } else if (format == AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM) { /* 2 */ + pf = SDL_PIXELFORMAT_RGBX8888; + } else if (format == AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM) { /* 3 */ + pf = SDL_PIXELFORMAT_RGB24; + } else if (format == AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM) { /* 4*/ + pf = SDL_PIXELFORMAT_RGB565; + } else if (format == 5) { + pf = SDL_PIXELFORMAT_BGRA8888; + } else if (format == 6) { + pf = SDL_PIXELFORMAT_RGBA5551; + } else if (format == 7) { + pf = SDL_PIXELFORMAT_RGBA4444; + } else if (format == 0x115) { + /* HAL_PIXEL_FORMAT_BGR_565 */ + pf = SDL_PIXELFORMAT_RGB565; + } else { + pf = SDL_PIXELFORMAT_UNKNOWN; + } + return pf; +} + +void Android_SetFormat(int format_wanted, int format_got) +{ + Uint32 pf_wanted; + Uint32 pf_got; + + pf_wanted = format_to_pixelFormat(format_wanted); + pf_got = format_to_pixelFormat(format_got); + + Android_ScreenFormat = pf_got; + + SDL_Log("pixel format wanted %s (%d), got %s (%d)", + SDL_GetPixelFormatName(pf_wanted), format_wanted, + SDL_GetPixelFormatName(pf_got), format_got); } void Android_SendResize(SDL_Window *window) @@ -246,24 +275,23 @@ void Android_SendResize(SDL_Window *window) which can happen after VideoInit(). */ SDL_VideoDevice *device = SDL_GetVideoDevice(); - if (device && device->num_displays > 0) - { - SDL_VideoDisplay *display = &device->displays[0]; - display->desktop_mode.format = Android_ScreenFormat; - display->desktop_mode.w = Android_DeviceWidth; - display->desktop_mode.h = Android_DeviceHeight; + if (device && device->num_displays > 0) { + SDL_VideoDisplay *display = &device->displays[0]; + display->desktop_mode.format = Android_ScreenFormat; + display->desktop_mode.w = Android_DeviceWidth; + display->desktop_mode.h = Android_DeviceHeight; display->desktop_mode.refresh_rate = Android_ScreenRate; } if (window) { /* Force the current mode to match the resize otherwise the SDL_WINDOWEVENT_RESTORED event * will fall back to the old mode */ - SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); - display->display_modes[0].format = Android_ScreenFormat; - display->display_modes[0].w = Android_DeviceWidth; - display->display_modes[0].h = Android_DeviceHeight; + SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); + display->display_modes[0].format = Android_ScreenFormat; + display->display_modes[0].w = Android_DeviceWidth; + display->display_modes[0].h = Android_DeviceHeight; display->display_modes[0].refresh_rate = Android_ScreenRate; - display->current_mode = display->display_modes[0]; + display->current_mode = display->display_modes[0]; SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, Android_SurfaceWidth, Android_SurfaceHeight); } diff --git a/SDL2-2.0.12/src/video/android/SDL_androidvideo.h b/SDL2-2.30.5/src/video/android/SDL_androidvideo.h similarity index 86% rename from SDL2-2.0.12/src/video/android/SDL_androidvideo.h rename to SDL2-2.30.5/src/video/android/SDL_androidvideo.h index 4ab22e1..7eb4f9a 100644 --- a/SDL2-2.0.12/src/video/android/SDL_androidvideo.h +++ b/SDL2-2.30.5/src/video/android/SDL_androidvideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -28,7 +28,8 @@ #include "../SDL_sysvideo.h" /* Called by the JNI layer when the screen changes size or format */ -extern void Android_SetScreenResolution(int surfaceWidth, int surfaceHeight, int deviceWidth, int deviceHeight, Uint32 format, float rate); +extern void Android_SetScreenResolution(int surfaceWidth, int surfaceHeight, int deviceWidth, int deviceHeight, float rate); +extern void Android_SetFormat(int format_wanted, int format_got); extern void Android_SendResize(SDL_Window *window); /* Private display data */ @@ -36,8 +37,9 @@ extern void Android_SendResize(SDL_Window *window); typedef struct SDL_VideoData { SDL_Rect textRect; - int isPaused; - int isPausing; + int isPaused; + int isPausing; + int pauseAudio; } SDL_VideoData; extern int Android_SurfaceWidth; diff --git a/SDL2-2.0.12/src/video/android/SDL_androidvulkan.c b/SDL2-2.30.5/src/video/android/SDL_androidvulkan.c similarity index 72% rename from SDL2-2.0.12/src/video/android/SDL_androidvulkan.c rename to SDL2-2.30.5/src/video/android/SDL_androidvulkan.c index ef15fd5..6ade57e 100644 --- a/SDL2-2.0.12/src/video/android/SDL_androidvulkan.c +++ b/SDL2-2.30.5/src/video/android/SDL_androidvulkan.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,11 +26,10 @@ #include "../../SDL_internal.h" -#if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_ANDROID +#if defined(SDL_VIDEO_VULKAN) && defined(SDL_VIDEO_DRIVER_ANDROID) #include "SDL_androidvideo.h" #include "SDL_androidwindow.h" -#include "SDL_assert.h" #include "SDL_loadso.h" #include "SDL_androidvulkan.h" @@ -43,53 +42,55 @@ int Android_Vulkan_LoadLibrary(_THIS, const char *path) SDL_bool hasSurfaceExtension = SDL_FALSE; SDL_bool hasAndroidSurfaceExtension = SDL_FALSE; PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL; - if(_this->vulkan_config.loader_handle) + if (_this->vulkan_config.loader_handle) { return SDL_SetError("Vulkan already loaded"); + } /* Load the Vulkan loader library */ - if(!path) + if (!path) { path = SDL_getenv("SDL_VULKAN_LIBRARY"); - if(!path) + } + if (!path) { path = "libvulkan.so"; + } _this->vulkan_config.loader_handle = SDL_LoadObject(path); - if(!_this->vulkan_config.loader_handle) + if (!_this->vulkan_config.loader_handle) { return -1; + } SDL_strlcpy(_this->vulkan_config.loader_path, path, SDL_arraysize(_this->vulkan_config.loader_path)); vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)SDL_LoadFunction( _this->vulkan_config.loader_handle, "vkGetInstanceProcAddr"); - if(!vkGetInstanceProcAddr) + if (!vkGetInstanceProcAddr) { goto fail; + } _this->vulkan_config.vkGetInstanceProcAddr = (void *)vkGetInstanceProcAddr; _this->vulkan_config.vkEnumerateInstanceExtensionProperties = (void *)((PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr)( VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties"); - if(!_this->vulkan_config.vkEnumerateInstanceExtensionProperties) + if (!_this->vulkan_config.vkEnumerateInstanceExtensionProperties) { goto fail; + } extensions = SDL_Vulkan_CreateInstanceExtensionsList( (PFN_vkEnumerateInstanceExtensionProperties) _this->vulkan_config.vkEnumerateInstanceExtensionProperties, &extensionCount); - if(!extensions) + if (!extensions) { goto fail; - for(i = 0; i < extensionCount; i++) - { - if(SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) + } + for (i = 0; i < extensionCount; i++) { + if (SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) { hasSurfaceExtension = SDL_TRUE; - else if(SDL_strcmp(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) + } else if (SDL_strcmp(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) { hasAndroidSurfaceExtension = SDL_TRUE; + } } SDL_free(extensions); - if(!hasSurfaceExtension) - { - SDL_SetError("Installed Vulkan doesn't implement the " - VK_KHR_SURFACE_EXTENSION_NAME " extension"); + if (!hasSurfaceExtension) { + SDL_SetError("Installed Vulkan doesn't implement the " VK_KHR_SURFACE_EXTENSION_NAME " extension"); goto fail; - } - else if(!hasAndroidSurfaceExtension) - { - SDL_SetError("Installed Vulkan doesn't implement the " - VK_KHR_ANDROID_SURFACE_EXTENSION_NAME "extension"); + } else if (!hasAndroidSurfaceExtension) { + SDL_SetError("Installed Vulkan doesn't implement the " VK_KHR_ANDROID_SURFACE_EXTENSION_NAME "extension"); goto fail; } return 0; @@ -102,54 +103,50 @@ fail: void Android_Vulkan_UnloadLibrary(_THIS) { - if(_this->vulkan_config.loader_handle) - { + if (_this->vulkan_config.loader_handle) { SDL_UnloadObject(_this->vulkan_config.loader_handle); _this->vulkan_config.loader_handle = NULL; } } SDL_bool Android_Vulkan_GetInstanceExtensions(_THIS, - SDL_Window *window, - unsigned *count, - const char **names) + SDL_Window *window, + unsigned *count, + const char **names) { static const char *const extensionsForAndroid[] = { VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_ANDROID_SURFACE_EXTENSION_NAME }; - if(!_this->vulkan_config.loader_handle) - { + if (!_this->vulkan_config.loader_handle) { SDL_SetError("Vulkan is not loaded"); return SDL_FALSE; } return SDL_Vulkan_GetInstanceExtensions_Helper( - count, names, SDL_arraysize(extensionsForAndroid), - extensionsForAndroid); + count, names, SDL_arraysize(extensionsForAndroid), + extensionsForAndroid); } SDL_bool Android_Vulkan_CreateSurface(_THIS, - SDL_Window *window, - VkInstance instance, - VkSurfaceKHR *surface) + SDL_Window *window, + VkInstance instance, + VkSurfaceKHR *surface) { SDL_WindowData *windowData = (SDL_WindowData *)window->driverdata; PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr; PFN_vkCreateAndroidSurfaceKHR vkCreateAndroidSurfaceKHR = (PFN_vkCreateAndroidSurfaceKHR)vkGetInstanceProcAddr( - instance, - "vkCreateAndroidSurfaceKHR"); + instance, + "vkCreateAndroidSurfaceKHR"); VkAndroidSurfaceCreateInfoKHR createInfo; VkResult result; - if(!_this->vulkan_config.loader_handle) - { + if (!_this->vulkan_config.loader_handle) { SDL_SetError("Vulkan is not loaded"); return SDL_FALSE; } - if(!vkCreateAndroidSurfaceKHR) - { + if (!vkCreateAndroidSurfaceKHR) { SDL_SetError(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME " extension is not enabled in the Vulkan instance."); return SDL_FALSE; @@ -161,8 +158,7 @@ SDL_bool Android_Vulkan_CreateSurface(_THIS, createInfo.window = windowData->native_window; result = vkCreateAndroidSurfaceKHR(instance, &createInfo, NULL, surface); - if(result != VK_SUCCESS) - { + if (result != VK_SUCCESS) { SDL_SetError("vkCreateAndroidSurfaceKHR failed: %s", SDL_Vulkan_GetResultString(result)); return SDL_FALSE; diff --git a/SDL2-2.0.12/src/video/android/SDL_androidvulkan.h b/SDL2-2.30.5/src/video/android/SDL_androidvulkan.h similarity index 73% rename from SDL2-2.0.12/src/video/android/SDL_androidvulkan.h rename to SDL2-2.30.5/src/video/android/SDL_androidvulkan.h index ee18c36..caee0a6 100644 --- a/SDL2-2.0.12/src/video/android/SDL_androidvulkan.h +++ b/SDL2-2.30.5/src/video/android/SDL_androidvulkan.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -32,18 +32,18 @@ #include "../SDL_vulkan_internal.h" #include "../SDL_sysvideo.h" -#if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_ANDROID +#if defined(SDL_VIDEO_VULKAN) && defined(SDL_VIDEO_DRIVER_ANDROID) int Android_Vulkan_LoadLibrary(_THIS, const char *path); void Android_Vulkan_UnloadLibrary(_THIS); SDL_bool Android_Vulkan_GetInstanceExtensions(_THIS, - SDL_Window *window, - unsigned *count, - const char **names); + SDL_Window *window, + unsigned *count, + const char **names); SDL_bool Android_Vulkan_CreateSurface(_THIS, - SDL_Window *window, - VkInstance instance, - VkSurfaceKHR *surface); + SDL_Window *window, + VkInstance instance, + VkSurfaceKHR *surface); #endif diff --git a/SDL2-2.0.12/src/video/android/SDL_androidwindow.c b/SDL2-2.30.5/src/video/android/SDL_androidwindow.c similarity index 75% rename from SDL2-2.0.12/src/video/android/SDL_androidwindow.c rename to SDL2-2.30.5/src/video/android/SDL_androidwindow.c index bf4bc91..2624331 100644 --- a/SDL2-2.0.12/src/video/android/SDL_androidwindow.c +++ b/SDL2-2.30.5/src/video/android/SDL_androidwindow.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_ANDROID +#ifdef SDL_VIDEO_DRIVER_ANDROID #include "SDL_syswm.h" #include "../SDL_sysvideo.h" @@ -36,8 +36,7 @@ /* Currently only one window */ SDL_Window *Android_Window = NULL; -int -Android_CreateWindow(_THIS, SDL_Window * window) +int Android_CreateWindow(_THIS, SDL_Window *window) { SDL_WindowData *data; int retval = 0; @@ -59,13 +58,13 @@ Android_CreateWindow(_THIS, SDL_Window * window) window->h = Android_SurfaceHeight; window->flags &= ~SDL_WINDOW_HIDDEN; - window->flags |= SDL_WINDOW_SHOWN; /* only one window on Android */ + window->flags |= SDL_WINDOW_SHOWN; /* only one window on Android */ /* One window, it always has focus */ SDL_SetMouseFocus(window); SDL_SetKeyboardFocus(window); - data = (SDL_WindowData *) SDL_calloc(1, sizeof(*data)); + data = (SDL_WindowData *)SDL_calloc(1, sizeof(*data)); if (!data) { retval = SDL_OutOfMemory(); goto endfunction; @@ -81,8 +80,9 @@ Android_CreateWindow(_THIS, SDL_Window * window) /* Do not create EGLSurface for Vulkan window since it will then make the window incompatible with vkCreateAndroidSurfaceKHR */ - if ((window->flags & SDL_WINDOW_OPENGL) != 0) { - data->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) data->native_window); +#ifdef SDL_VIDEO_OPENGL_EGL + if (window->flags & SDL_WINDOW_OPENGL) { + data->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType)data->native_window); if (data->egl_surface == EGL_NO_SURFACE) { ANativeWindow_release(data->native_window); @@ -91,6 +91,7 @@ Android_CreateWindow(_THIS, SDL_Window * window) goto endfunction; } } +#endif window->driverdata = data; Android_Window = window; @@ -102,18 +103,18 @@ endfunction: return retval; } -void -Android_SetWindowTitle(_THIS, SDL_Window *window) +void Android_SetWindowTitle(_THIS, SDL_Window *window) { Android_JNI_SetActivityTitle(window->title); } -void -Android_SetWindowFullscreen(_THIS, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen) +void Android_SetWindowFullscreen(_THIS, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen) { SDL_LockMutex(Android_ActivityMutex); if (window == Android_Window) { + SDL_WindowData *data; + int old_w, old_h, new_w, new_h; /* If the window is being destroyed don't change visible state */ if (!window->is_destroying) { @@ -130,8 +131,7 @@ Android_SetWindowFullscreen(_THIS, SDL_Window *window, SDL_VideoDisplay *display goto endfunction; } - SDL_WindowData *data = (SDL_WindowData *)window->driverdata; - + data = (SDL_WindowData *)window->driverdata; if (!data || !data->native_window) { if (data && !data->native_window) { SDL_SetError("Missing native window"); @@ -139,11 +139,11 @@ Android_SetWindowFullscreen(_THIS, SDL_Window *window, SDL_VideoDisplay *display goto endfunction; } - int old_w = window->w; - int old_h = window->h; + old_w = window->w; + old_h = window->h; - int new_w = ANativeWindow_getWidth(data->native_window); - int new_h = ANativeWindow_getHeight(data->native_window); + new_w = ANativeWindow_getWidth(data->native_window); + new_h = ANativeWindow_getHeight(data->native_window); if (new_w < 0 || new_h < 0) { SDL_SetError("ANativeWindow_getWidth/Height() fails"); @@ -159,14 +159,18 @@ endfunction: SDL_UnlockMutex(Android_ActivityMutex); } -void -Android_MinimizeWindow(_THIS, SDL_Window *window) +void Android_MinimizeWindow(_THIS, SDL_Window *window) { Android_JNI_MinizeWindow(); } -void -Android_DestroyWindow(_THIS, SDL_Window *window) +void Android_SetWindowResizable(_THIS, SDL_Window *window, SDL_bool resizable) +{ + /* Set orientation */ + Android_JNI_SetOrientation(window->w, window->h, window->flags & SDL_WINDOW_RESIZABLE, SDL_GetHint(SDL_HINT_ORIENTATIONS)); +} + +void Android_DestroyWindow(_THIS, SDL_Window *window) { SDL_LockMutex(Android_ActivityMutex); @@ -174,10 +178,14 @@ Android_DestroyWindow(_THIS, SDL_Window *window) Android_Window = NULL; if (window->driverdata) { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + +#ifdef SDL_VIDEO_OPENGL_EGL if (data->egl_surface != EGL_NO_SURFACE) { SDL_EGL_DestroySurface(_this, data->egl_surface); } +#endif + if (data->native_window) { ANativeWindow_release(data->native_window); } @@ -189,20 +197,22 @@ Android_DestroyWindow(_THIS, SDL_Window *window) SDL_UnlockMutex(Android_ActivityMutex); } -SDL_bool -Android_GetWindowWMInfo(_THIS, SDL_Window *window, SDL_SysWMinfo *info) +SDL_bool Android_GetWindowWMInfo(_THIS, SDL_Window *window, SDL_SysWMinfo *info) { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; - if (info->version.major == SDL_MAJOR_VERSION && - info->version.minor == SDL_MINOR_VERSION) { + if (info->version.major == SDL_MAJOR_VERSION) { info->subsystem = SDL_SYSWM_ANDROID; info->info.android.window = data->native_window; + +#ifdef SDL_VIDEO_OPENGL_EGL info->info.android.surface = data->egl_surface; +#endif + return SDL_TRUE; } else { - SDL_SetError("Application not compiled with SDL %d.%d", - SDL_MAJOR_VERSION, SDL_MINOR_VERSION); + SDL_SetError("Application not compiled with SDL %d", + SDL_MAJOR_VERSION); return SDL_FALSE; } } diff --git a/SDL2-2.0.12/src/video/android/SDL_androidwindow.h b/SDL2-2.30.5/src/video/android/SDL_androidwindow.h similarity index 89% rename from SDL2-2.0.12/src/video/android/SDL_androidwindow.h rename to SDL2-2.30.5/src/video/android/SDL_androidwindow.h index c26a072..240c77c 100644 --- a/SDL2-2.0.12/src/video/android/SDL_androidwindow.h +++ b/SDL2-2.30.5/src/video/android/SDL_androidwindow.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -30,6 +30,7 @@ extern int Android_CreateWindow(_THIS, SDL_Window *window); extern void Android_SetWindowTitle(_THIS, SDL_Window *window); extern void Android_SetWindowFullscreen(_THIS, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen); extern void Android_MinimizeWindow(_THIS, SDL_Window *window); +extern void Android_SetWindowResizable(_THIS, SDL_Window *window, SDL_bool resizable); extern void Android_DestroyWindow(_THIS, SDL_Window *window); extern SDL_bool Android_GetWindowWMInfo(_THIS, SDL_Window *window, struct SDL_SysWMinfo *info); @@ -37,11 +38,13 @@ extern SDL_Window *Android_Window; typedef struct { +#ifdef SDL_VIDEO_OPENGL_EGL EGLSurface egl_surface; EGLContext egl_context; /* We use this to preserve the context when losing focus */ - SDL_bool backup_done; +#endif + SDL_bool backup_done; ANativeWindow *native_window; - + } SDL_WindowData; #endif /* SDL_androidwindow_h_ */ diff --git a/SDL2-2.0.12/src/video/arm/pixman-arm-asm.h b/SDL2-2.30.5/src/video/arm/pixman-arm-asm.h similarity index 100% rename from SDL2-2.0.12/src/video/arm/pixman-arm-asm.h rename to SDL2-2.30.5/src/video/arm/pixman-arm-asm.h diff --git a/SDL2-2.0.12/src/video/arm/pixman-arm-neon-asm.S b/SDL2-2.30.5/src/video/arm/pixman-arm-neon-asm.S similarity index 100% rename from SDL2-2.0.12/src/video/arm/pixman-arm-neon-asm.S rename to SDL2-2.30.5/src/video/arm/pixman-arm-neon-asm.S diff --git a/SDL2-2.0.12/src/video/arm/pixman-arm-neon-asm.h b/SDL2-2.30.5/src/video/arm/pixman-arm-neon-asm.h similarity index 100% rename from SDL2-2.0.12/src/video/arm/pixman-arm-neon-asm.h rename to SDL2-2.30.5/src/video/arm/pixman-arm-neon-asm.h diff --git a/SDL2-2.0.12/src/video/arm/pixman-arm-simd-asm.S b/SDL2-2.30.5/src/video/arm/pixman-arm-simd-asm.S similarity index 100% rename from SDL2-2.0.12/src/video/arm/pixman-arm-simd-asm.S rename to SDL2-2.30.5/src/video/arm/pixman-arm-simd-asm.S diff --git a/SDL2-2.0.12/src/video/arm/pixman-arm-simd-asm.h b/SDL2-2.30.5/src/video/arm/pixman-arm-simd-asm.h similarity index 100% rename from SDL2-2.0.12/src/video/arm/pixman-arm-simd-asm.h rename to SDL2-2.30.5/src/video/arm/pixman-arm-simd-asm.h diff --git a/SDL2-2.0.12/src/video/cocoa/SDL_cocoaclipboard.h b/SDL2-2.30.5/src/video/cocoa/SDL_cocoaclipboard.h similarity index 89% rename from SDL2-2.0.12/src/video/cocoa/SDL_cocoaclipboard.h rename to SDL2-2.30.5/src/video/cocoa/SDL_cocoaclipboard.h index 26e741e..a7b7a54 100644 --- a/SDL2-2.0.12/src/video/cocoa/SDL_cocoaclipboard.h +++ b/SDL2-2.30.5/src/video/cocoa/SDL_cocoaclipboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -24,12 +24,12 @@ #define SDL_cocoaclipboard_h_ /* Forward declaration */ -struct SDL_VideoData; +@class SDL_VideoData; extern int Cocoa_SetClipboardText(_THIS, const char *text); extern char *Cocoa_GetClipboardText(_THIS); extern SDL_bool Cocoa_HasClipboardText(_THIS); -extern void Cocoa_CheckClipboardUpdate(struct SDL_VideoData * data); +extern void Cocoa_CheckClipboardUpdate(SDL_VideoData * data); #endif /* SDL_cocoaclipboard_h_ */ diff --git a/SDL2-2.0.12/src/video/cocoa/SDL_cocoaclipboard.m b/SDL2-2.30.5/src/video/cocoa/SDL_cocoaclipboard.m similarity index 73% rename from SDL2-2.0.12/src/video/cocoa/SDL_cocoaclipboard.m rename to SDL2-2.30.5/src/video/cocoa/SDL_cocoaclipboard.m index 0ff90d0..136dba4 100644 --- a/SDL2-2.0.12/src/video/cocoa/SDL_cocoaclipboard.m +++ b/SDL2-2.30.5/src/video/cocoa/SDL_cocoaclipboard.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,28 +20,30 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_COCOA +#ifdef SDL_VIDEO_DRIVER_COCOA #include "SDL_cocoavideo.h" #include "../../events/SDL_clipboardevents_c.h" -int -Cocoa_SetClipboardText(_THIS, const char *text) +int Cocoa_SetClipboardText(_THIS, const char *text) { @autoreleasepool { - SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + SDL_VideoData *data = (__bridge SDL_VideoData *) _this->driverdata; NSPasteboard *pasteboard; NSString *format = NSPasteboardTypeString; + NSString *nsstr = [NSString stringWithUTF8String:text]; + if (nsstr == nil) { + return SDL_SetError("Couldn't create NSString; is your string data in UTF-8 format?"); + } pasteboard = [NSPasteboard generalPasteboard]; - data->clipboard_count = [pasteboard declareTypes:[NSArray arrayWithObject:format] owner:nil]; - [pasteboard setString:[NSString stringWithUTF8String:text] forType:format]; + data.clipboard_count = [pasteboard declareTypes:[NSArray arrayWithObject:format] owner:nil]; + [pasteboard setString:nsstr forType:format]; return 0; }} -char * -Cocoa_GetClipboardText(_THIS) +char *Cocoa_GetClipboardText(_THIS) { @autoreleasepool { NSPasteboard *pasteboard; @@ -61,7 +63,7 @@ Cocoa_GetClipboardText(_THIS) } else { utf8 = [string UTF8String]; } - text = SDL_strdup(utf8); + text = SDL_strdup(utf8 ? utf8 : ""); } else { text = SDL_strdup(""); } @@ -69,8 +71,7 @@ Cocoa_GetClipboardText(_THIS) return text; }} -SDL_bool -Cocoa_HasClipboardText(_THIS) +SDL_bool Cocoa_HasClipboardText(_THIS) { SDL_bool result = SDL_FALSE; char *text = Cocoa_GetClipboardText(_this); @@ -81,8 +82,7 @@ Cocoa_HasClipboardText(_THIS) return result; } -void -Cocoa_CheckClipboardUpdate(struct SDL_VideoData * data) +void Cocoa_CheckClipboardUpdate(SDL_VideoData * data) { @autoreleasepool { NSPasteboard *pasteboard; @@ -90,11 +90,11 @@ Cocoa_CheckClipboardUpdate(struct SDL_VideoData * data) pasteboard = [NSPasteboard generalPasteboard]; count = [pasteboard changeCount]; - if (count != data->clipboard_count) { - if (data->clipboard_count) { + if (count != data.clipboard_count) { + if (data.clipboard_count) { SDL_SendClipboardUpdate(); } - data->clipboard_count = count; + data.clipboard_count = count; } }} diff --git a/SDL2-2.0.12/src/video/cocoa/SDL_cocoaevents.h b/SDL2-2.30.5/src/video/cocoa/SDL_cocoaevents.h similarity index 86% rename from SDL2-2.0.12/src/video/cocoa/SDL_cocoaevents.h rename to SDL2-2.30.5/src/video/cocoa/SDL_cocoaevents.h index 7653c45..421df3a 100644 --- a/SDL2-2.0.12/src/video/cocoa/SDL_cocoaevents.h +++ b/SDL2-2.30.5/src/video/cocoa/SDL_cocoaevents.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -25,6 +25,8 @@ extern void Cocoa_RegisterApp(void); extern void Cocoa_PumpEvents(_THIS); +extern int Cocoa_WaitEventTimeout(_THIS, int timeout); +extern void Cocoa_SendWakeupEvent(_THIS, SDL_Window *window); extern void Cocoa_SuspendScreenSaver(_THIS); #endif /* SDL_cocoaevents_h_ */ diff --git a/SDL2-2.0.12/src/video/cocoa/SDL_cocoaevents.m b/SDL2-2.30.5/src/video/cocoa/SDL_cocoaevents.m similarity index 70% rename from SDL2-2.0.12/src/video/cocoa/SDL_cocoaevents.m rename to SDL2-2.30.5/src/video/cocoa/SDL_cocoaevents.m index 0de74df..441985d 100644 --- a/SDL2-2.0.12/src/video/cocoa/SDL_cocoaevents.m +++ b/SDL2-2.30.5/src/video/cocoa/SDL_cocoaevents.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,19 +20,40 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_COCOA +#ifdef SDL_VIDEO_DRIVER_COCOA #include "SDL_timer.h" #include "SDL_cocoavideo.h" #include "../../events/SDL_events_c.h" -#include "SDL_assert.h" #include "SDL_hints.h" /* This define was added in the 10.9 SDK. */ #ifndef kIOPMAssertPreventUserIdleDisplaySleep #define kIOPMAssertPreventUserIdleDisplaySleep kIOPMAssertionTypePreventUserIdleDisplaySleep #endif +#ifndef NSAppKitVersionNumber10_8 +#define NSAppKitVersionNumber10_8 1187 +#endif +#ifndef MAC_OS_X_VERSION_10_12 +#define NSEventTypeApplicationDefined NSApplicationDefined +#endif + +static SDL_Window *FindSDLWindowForNSWindow(NSWindow *win) +{ + SDL_Window *sdlwindow = NULL; + SDL_VideoDevice *device = SDL_GetVideoDevice(); + if (device && device->windows) { + for (sdlwindow = device->windows; sdlwindow; sdlwindow = sdlwindow->next) { + NSWindow *nswindow = ((__bridge SDL_WindowData *) sdlwindow->driverdata).nswindow; + if (win == nswindow) { + return sdlwindow; + } + } + } + + return sdlwindow; +} @interface SDLApplication : NSApplication @@ -101,7 +122,6 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent) [NSNumber numberWithBool:YES], @"ApplePersistenceIgnoreState", nil]; [[NSUserDefaults standardUserDefaults] registerDefaults:appDefaults]; - [appDefaults release]; } @end // SDLApplication @@ -117,6 +137,8 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent) } - (id)init; +- (void)localeDidChange:(NSNotification *)notification; +- (BOOL)applicationSupportsSecureRestorableState:(NSApplication *)app; @end @implementation SDLAppDelegate : NSObject @@ -137,6 +159,11 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent) selector:@selector(focusSomeWindow:) name:NSApplicationDidBecomeActiveNotification object:nil]; + + [center addObserver:self + selector:@selector(localeDidChange:) + name:NSCurrentLocaleDidChangeNotification + object:nil]; } return self; @@ -148,8 +175,14 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent) [center removeObserver:self name:NSWindowWillCloseNotification object:nil]; [center removeObserver:self name:NSApplicationDidBecomeActiveNotification object:nil]; + [center removeObserver:self name:NSCurrentLocaleDidChangeNotification object:nil]; - [super dealloc]; + /* Remove our URL event handler only if we set it */ + if ([NSApp delegate] == self) { + [[NSAppleEventManager sharedAppleEventManager] + removeEventHandlerForEventClass:kInternetEventClass + andEventID:kAEGetURL]; + } } - (void)windowWillClose:(NSNotification *)notification; @@ -160,6 +193,11 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent) return; } + /* Don't do anything if this was not an SDL window that was closed */ + if (FindSDLWindowForNSWindow(win) == NULL) { + return; + } + /* HACK: Make the next window in the z-order key when the key window is * closed. The custom event loop and/or windowing code we have seems to * prevent the normal behavior: https://bugzilla.libsdl.org/show_bug.cgi?id=1825 @@ -194,6 +232,7 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent) - (void)focusSomeWindow:(NSNotification *)aNotification { + SDL_VideoDevice *device; /* HACK: Ignore the first call. The application gets a * applicationDidBecomeActive: a little bit after the first window is * created, and if we don't ignore it, a window that has been created with @@ -204,7 +243,14 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent) return; } - SDL_VideoDevice *device = SDL_GetVideoDevice(); + /* Don't do anything if the application already has a key window + * that is not an SDL window. + */ + if ([NSApp keyWindow] && FindSDLWindowForNSWindow([NSApp keyWindow]) == NULL) { + return; + } + + device = SDL_GetVideoDevice(); if (device && device->windows) { SDL_Window *window = device->windows; int i; @@ -226,6 +272,11 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent) } } +- (void)localeDidChange:(NSNotification *)notification; +{ + SDL_SendLocaleChangedEvent(); +} + - (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename { return (BOOL)SDL_SendDropFile(NULL, [filename UTF8String]) && SDL_SendDropComplete(NULL); @@ -252,12 +303,35 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent) * about ApplePersistenceIgnoreState. */ [SDLApplication registerUserDefaults]; } + +- (void)handleURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent +{ + NSString* path = [[event paramDescriptorForKeyword:keyDirectObject] stringValue]; + SDL_SendDropFile(NULL, [path UTF8String]); + SDL_SendDropComplete(NULL); +} + +- (BOOL)applicationSupportsSecureRestorableState:(NSApplication *)app +{ + // This just tells Cocoa that we didn't do any custom save state magic for the app, + // so the system is safe to use NSSecureCoding internally, instead of using unencrypted + // save states for backwards compatibility. If we don't return YES here, we'll get a + // warning on the console at startup: + // + // ``` + // WARNING: Secure coding is not enabled for restorable state! Enable secure coding by implementing NSApplicationDelegate.applicationSupportsSecureRestorableState: and returning YES. + // ``` + // + // More-detailed explanation: + // https://stackoverflow.com/questions/77283578/sonoma-and-nsapplicationdelegate-applicationsupportssecurerestorablestate/77320845#77320845 + return YES; +} + @end static SDLAppDelegate *appDelegate = nil; -static NSString * -GetApplicationName(void) +static NSString *GetApplicationName(void) { NSString *appName; @@ -274,27 +348,32 @@ GetApplicationName(void) return appName; } -static bool -LoadMainMenuNibIfAvailable(void) +static bool LoadMainMenuNibIfAvailable(void) { +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080 NSDictionary *infoDict; NSString *mainNibFileName; bool success = false; - + + if (floor(NSAppKitVersionNumber) < NSAppKitVersionNumber10_8) { + return false; + } infoDict = [[NSBundle mainBundle] infoDictionary]; if (infoDict) { mainNibFileName = [infoDict valueForKey:@"NSMainNibFile"]; - + if (mainNibFileName) { success = [[NSBundle mainBundle] loadNibNamed:mainNibFileName owner:[NSApplication sharedApplication] topLevelObjects:nil]; } } - + return success; +#else + return false; +#endif } -static void -CreateApplicationMenus(void) +static void CreateApplicationMenus(void) { NSString *appName; NSString *title; @@ -307,15 +386,12 @@ CreateApplicationMenus(void) if (NSApp == nil) { return; } - + mainMenu = [[NSMenu alloc] init]; /* Create the main menu bar */ [NSApp setMainMenu:mainMenu]; - [mainMenu release]; /* we're done with it, let NSApp own it. */ - mainMenu = nil; - /* Create the application menu */ appName = GetApplicationName(); appleMenu = [[NSMenu alloc] initWithTitle:@""]; @@ -331,11 +407,10 @@ CreateApplicationMenus(void) [appleMenu addItem:[NSMenuItem separatorItem]]; serviceMenu = [[NSMenu alloc] initWithTitle:@""]; - menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Services" action:nil keyEquivalent:@""]; + menuItem = [appleMenu addItemWithTitle:@"Services" action:nil keyEquivalent:@""]; [menuItem setSubmenu:serviceMenu]; [NSApp setServicesMenu:serviceMenu]; - [serviceMenu release]; [appleMenu addItem:[NSMenuItem separatorItem]]; @@ -356,12 +431,9 @@ CreateApplicationMenus(void) menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""]; [menuItem setSubmenu:appleMenu]; [[NSApp mainMenu] addItem:menuItem]; - [menuItem release]; /* Tell the application object that this is now the application menu */ [NSApp setAppleMenu:appleMenu]; - [appleMenu release]; - /* Create the window menu */ windowMenu = [[NSMenu alloc] initWithTitle:@"Window"]; @@ -372,31 +444,25 @@ CreateApplicationMenus(void) [windowMenu addItemWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"]; [windowMenu addItemWithTitle:@"Zoom" action:@selector(performZoom:) keyEquivalent:@""]; - - /* Add the fullscreen toggle menu option, if supported */ - if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) { - /* Cocoa should update the title to Enter or Exit Full Screen automatically. - * But if not, then just fallback to Toggle Full Screen. - */ - menuItem = [[NSMenuItem alloc] initWithTitle:@"Toggle Full Screen" action:@selector(toggleFullScreen:) keyEquivalent:@"f"]; - [menuItem setKeyEquivalentModifierMask:NSEventModifierFlagControl | NSEventModifierFlagCommand]; - [windowMenu addItem:menuItem]; - [menuItem release]; - } + + /* Add the fullscreen toggle menu option. */ + /* Cocoa should update the title to Enter or Exit Full Screen automatically. + * But if not, then just fallback to Toggle Full Screen. + */ + menuItem = [[NSMenuItem alloc] initWithTitle:@"Toggle Full Screen" action:@selector(toggleFullScreen:) keyEquivalent:@"f"]; + [menuItem setKeyEquivalentModifierMask:NSEventModifierFlagControl | NSEventModifierFlagCommand]; + [windowMenu addItem:menuItem]; /* Put menu into the menubar */ menuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""]; [menuItem setSubmenu:windowMenu]; [[NSApp mainMenu] addItem:menuItem]; - [menuItem release]; /* Tell the application object that this is now the window menu */ [NSApp setWindowsMenu:windowMenu]; - [windowMenu release]; } -void -Cocoa_RegisterApp(void) +void Cocoa_RegisterApp(void) { @autoreleasepool { /* This can get called more than once! Be careful what you initialize! */ @@ -417,7 +483,7 @@ Cocoa_RegisterApp(void) */ if ([NSApp mainMenu] == nil) { bool nibLoaded; - + nibLoaded = LoadMainMenuNibIfAvailable(); if (!nibLoaded) { CreateApplicationMenus(); @@ -438,6 +504,15 @@ Cocoa_RegisterApp(void) * termination into SDL_Quit, and we can't handle application:openFile: */ if (![NSApp delegate]) { + /* Only register the URL event handler if we are being set as the + * app delegate to avoid replacing any existing event handler. + */ + [[NSAppleEventManager sharedAppleEventManager] + setEventHandler:appDelegate + andSelector:@selector(handleURLEvent:withReplyEvent:) + forEventClass:kInternetEventClass + andEventID:kAEGetURL]; + [(NSApplication *)NSApp setDelegate:appDelegate]; } else { appDelegate->seenFirstActivate = YES; @@ -445,27 +520,12 @@ Cocoa_RegisterApp(void) } }} -void -Cocoa_PumpEvents(_THIS) -{ @autoreleasepool +int Cocoa_PumpEventsUntilDate(_THIS, NSDate *expiration, bool accumulate) { -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070 - /* Update activity every 30 seconds to prevent screensaver */ - SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; - if (_this->suspend_screensaver && !data->screensaver_use_iopm) { - Uint32 now = SDL_GetTicks(); - if (!data->screensaver_activity || - SDL_TICKS_PASSED(now, data->screensaver_activity + 30000)) { - UpdateSystemActivity(UsrActivity); - data->screensaver_activity = now; - } - } -#endif - for ( ; ; ) { - NSEvent *event = [NSApp nextEventMatchingMask:NSEventMaskAny untilDate:[NSDate distantPast] inMode:NSDefaultRunLoopMode dequeue:YES ]; + NSEvent *event = [NSApp nextEventMatchingMask:NSEventMaskAny untilDate:expiration inMode:NSDefaultRunLoopMode dequeue:YES ]; if ( event == nil ) { - break; + return 0; } if (!s_bShouldHandleEventsInSDLApplication) { @@ -474,22 +534,58 @@ Cocoa_PumpEvents(_THIS) // Pass events down to SDLApplication to be handled in sendEvent: [NSApp sendEvent:event]; + if ( !accumulate) { + break; + } } -}} + return 1; +} -void -Cocoa_SuspendScreenSaver(_THIS) +int Cocoa_WaitEventTimeout(_THIS, int timeout) { @autoreleasepool { - SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; - - if (!data->screensaver_use_iopm) { - return; + if (timeout > 0) { + NSDate *limitDate = [NSDate dateWithTimeIntervalSinceNow: (double) timeout / 1000.0]; + return Cocoa_PumpEventsUntilDate(_this, limitDate, false); + } else if (timeout == 0) { + return Cocoa_PumpEventsUntilDate(_this, [NSDate distantPast], false); + } else { + while (Cocoa_PumpEventsUntilDate(_this, [NSDate distantFuture], false) == 0) { + } } + return 1; +}} - if (data->screensaver_assertion) { - IOPMAssertionRelease(data->screensaver_assertion); - data->screensaver_assertion = 0; +void Cocoa_PumpEvents(_THIS) +{ @autoreleasepool +{ + Cocoa_PumpEventsUntilDate(_this, [NSDate distantPast], true); +}} + +void Cocoa_SendWakeupEvent(_THIS, SDL_Window *window) +{ @autoreleasepool +{ + NSEvent* event = [NSEvent otherEventWithType: NSEventTypeApplicationDefined + location: NSMakePoint(0,0) + modifierFlags: 0 + timestamp: 0.0 + windowNumber: ((__bridge SDL_WindowData *) window->driverdata).window_number + context: nil + subtype: 0 + data1: 0 + data2: 0]; + + [NSApp postEvent: event atStart: YES]; +}} + +void Cocoa_SuspendScreenSaver(_THIS) +{ @autoreleasepool +{ + SDL_VideoData *data = (__bridge SDL_VideoData *)_this->driverdata; + + if (data.screensaver_assertion) { + IOPMAssertionRelease(data.screensaver_assertion); + data.screensaver_assertion = kIOPMNullAssertionID; } if (_this->suspend_screensaver) { @@ -498,11 +594,13 @@ Cocoa_SuspendScreenSaver(_THIS) * seen by OS X power users. there's an additional optional human-readable * (localized) reason parameter which we don't set. */ + IOPMAssertionID assertion = kIOPMNullAssertionID; NSString *name = [GetApplicationName() stringByAppendingString:@" using SDL_DisableScreenSaver"]; IOPMAssertionCreateWithDescription(kIOPMAssertPreventUserIdleDisplaySleep, - (CFStringRef) name, + (__bridge CFStringRef) name, NULL, NULL, NULL, 0, NULL, - &data->screensaver_assertion); + &assertion); + data.screensaver_assertion = assertion; } }} diff --git a/SDL2-2.0.12/src/video/cocoa/SDL_cocoakeyboard.h b/SDL2-2.30.5/src/video/cocoa/SDL_cocoakeyboard.h similarity index 85% rename from SDL2-2.0.12/src/video/cocoa/SDL_cocoakeyboard.h rename to SDL2-2.30.5/src/video/cocoa/SDL_cocoakeyboard.h index e81f616..d080664 100644 --- a/SDL2-2.0.12/src/video/cocoa/SDL_cocoakeyboard.h +++ b/SDL2-2.30.5/src/video/cocoa/SDL_cocoakeyboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -29,7 +29,9 @@ extern void Cocoa_QuitKeyboard(_THIS); extern void Cocoa_StartTextInput(_THIS); extern void Cocoa_StopTextInput(_THIS); -extern void Cocoa_SetTextInputRect(_THIS, SDL_Rect *rect); +extern void Cocoa_SetTextInputRect(_THIS, const SDL_Rect *rect); + +extern void Cocoa_SetWindowKeyboardGrab(_THIS, SDL_Window * window, SDL_bool grabbed); #endif /* SDL_cocoakeyboard_h_ */ diff --git a/SDL2-2.30.5/src/video/cocoa/SDL_cocoakeyboard.m b/SDL2-2.30.5/src/video/cocoa/SDL_cocoakeyboard.m new file mode 100644 index 0000000..605a4d4 --- /dev/null +++ b/SDL2-2.30.5/src/video/cocoa/SDL_cocoakeyboard.m @@ -0,0 +1,480 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_COCOA + +#include "SDL_cocoavideo.h" + +#include "../../events/SDL_events_c.h" +#include "../../events/SDL_keyboard_c.h" +#include "../../events/scancodes_darwin.h" + +#include + +/*#define DEBUG_IME NSLog */ +#define DEBUG_IME(...) + +@interface SDLTranslatorResponder : NSView { + NSString *_markedText; + NSRange _markedRange; + NSRange _selectedRange; + SDL_Rect _inputRect; +} +- (void)doCommandBySelector:(SEL)myselector; +- (void)setInputRect:(const SDL_Rect *)rect; +@end + +@implementation SDLTranslatorResponder + +- (void)setInputRect:(const SDL_Rect *)rect +{ + _inputRect = *rect; +} + +- (void)insertText:(id)aString replacementRange:(NSRange)replacementRange +{ + /* TODO: Make use of replacementRange? */ + + const char *str; + + DEBUG_IME(@"insertText: %@", aString); + + /* Could be NSString or NSAttributedString, so we have + * to test and convert it before return as SDL event */ + if ([aString isKindOfClass: [NSAttributedString class]]) { + str = [[aString string] UTF8String]; + } else { + str = [aString UTF8String]; + } + + /* We're likely sending the composed text, so we reset the IME status. */ + if ([self hasMarkedText]) { + [self unmarkText]; + } + + SDL_SendKeyboardText(str); +} + +- (void)doCommandBySelector:(SEL)myselector +{ + /* No need to do anything since we are not using Cocoa + selectors to handle special keys, instead we use SDL + key events to do the same job. + */ +} + +- (BOOL)hasMarkedText +{ + return _markedText != nil; +} + +- (NSRange)markedRange +{ + return _markedRange; +} + +- (NSRange)selectedRange +{ + return _selectedRange; +} + +- (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange +{ + if ([aString isKindOfClass:[NSAttributedString class]]) { + aString = [aString string]; + } + + if ([aString length] == 0) { + [self unmarkText]; + return; + } + + if (_markedText != aString) { + _markedText = aString; + } + + _selectedRange = selectedRange; + _markedRange = NSMakeRange(0, [aString length]); + + SDL_SendEditingText([aString UTF8String], + (int) selectedRange.location, (int) selectedRange.length); + + DEBUG_IME(@"setMarkedText: %@, (%d, %d)", _markedText, + selectedRange.location, selectedRange.length); +} + +- (void)unmarkText +{ + _markedText = nil; + + SDL_SendEditingText("", 0, 0); +} + +- (NSRect)firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange +{ + NSWindow *window = [self window]; + NSRect contentRect = [window contentRectForFrameRect:[window frame]]; + float windowHeight = contentRect.size.height; + NSRect rect = NSMakeRect(_inputRect.x, windowHeight - _inputRect.y - _inputRect.h, + _inputRect.w, _inputRect.h); + + if (actualRange) { + *actualRange = aRange; + } + + DEBUG_IME(@"firstRectForCharacterRange: (%d, %d): windowHeight = %g, rect = %@", + aRange.location, aRange.length, windowHeight, + NSStringFromRect(rect)); + + rect = [window convertRectToScreen:rect]; + + return rect; +} + +- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange +{ + DEBUG_IME(@"attributedSubstringFromRange: (%d, %d)", aRange.location, aRange.length); + return nil; +} + +- (NSInteger)conversationIdentifier +{ + return (NSInteger) self; +} + +/* This method returns the index for character that is + * nearest to thePoint. thPoint is in screen coordinate system. + */ +- (NSUInteger)characterIndexForPoint:(NSPoint)thePoint +{ + DEBUG_IME(@"characterIndexForPoint: (%g, %g)", thePoint.x, thePoint.y); + return 0; +} + +/* This method is the key to attribute extension. + * We could add new attributes through this method. + * NSInputServer examines the return value of this + * method & constructs appropriate attributed string. + */ +- (NSArray *)validAttributesForMarkedText +{ + return [NSArray array]; +} + +@end + +static bool IsModifierKeyPressed(unsigned int flags, + unsigned int target_mask, + unsigned int other_mask, + unsigned int either_mask) +{ + bool target_pressed = (flags & target_mask) != 0; + bool other_pressed = (flags & other_mask) != 0; + bool either_pressed = (flags & either_mask) != 0; + + if (either_pressed != (target_pressed || other_pressed)) + return either_pressed; + + return target_pressed; +} + +static void HandleModifiers(_THIS, SDL_Scancode code, unsigned int modifierFlags) +{ + bool pressed = false; + + if (code == SDL_SCANCODE_LSHIFT) { + pressed = IsModifierKeyPressed(modifierFlags, NX_DEVICELSHIFTKEYMASK, + NX_DEVICERSHIFTKEYMASK, NX_SHIFTMASK); + } else if (code == SDL_SCANCODE_LCTRL) { + pressed = IsModifierKeyPressed(modifierFlags, NX_DEVICELCTLKEYMASK, + NX_DEVICERCTLKEYMASK, NX_CONTROLMASK); + } else if (code == SDL_SCANCODE_LALT) { + pressed = IsModifierKeyPressed(modifierFlags, NX_DEVICELALTKEYMASK, + NX_DEVICERALTKEYMASK, NX_ALTERNATEMASK); + } else if (code == SDL_SCANCODE_LGUI) { + pressed = IsModifierKeyPressed(modifierFlags, NX_DEVICELCMDKEYMASK, + NX_DEVICERCMDKEYMASK, NX_COMMANDMASK); + } else if (code == SDL_SCANCODE_RSHIFT) { + pressed = IsModifierKeyPressed(modifierFlags, NX_DEVICERSHIFTKEYMASK, + NX_DEVICELSHIFTKEYMASK, NX_SHIFTMASK); + } else if (code == SDL_SCANCODE_RCTRL) { + pressed = IsModifierKeyPressed(modifierFlags, NX_DEVICERCTLKEYMASK, + NX_DEVICELCTLKEYMASK, NX_CONTROLMASK); + } else if (code == SDL_SCANCODE_RALT) { + pressed = IsModifierKeyPressed(modifierFlags, NX_DEVICERALTKEYMASK, + NX_DEVICELALTKEYMASK, NX_ALTERNATEMASK); + } else if (code == SDL_SCANCODE_RGUI) { + pressed = IsModifierKeyPressed(modifierFlags, NX_DEVICERCMDKEYMASK, + NX_DEVICELCMDKEYMASK, NX_COMMANDMASK); + } else { + return; + } + + if (pressed) { + SDL_SendKeyboardKey(SDL_PRESSED, code); + } else { + SDL_SendKeyboardKey(SDL_RELEASED, code); + } +} + +static void UpdateKeymap(SDL_VideoData *data, SDL_bool send_event) +{ + TISInputSourceRef key_layout; + const void *chr_data; + int i; + SDL_Scancode scancode; + SDL_Keycode keymap[SDL_NUM_SCANCODES]; + CFDataRef uchrDataRef; + + /* See if the keymap needs to be updated */ + key_layout = TISCopyCurrentKeyboardLayoutInputSource(); + if (key_layout == data.key_layout) { + return; + } + data.key_layout = key_layout; + + SDL_GetDefaultKeymap(keymap); + + /* Try Unicode data first */ + uchrDataRef = TISGetInputSourceProperty(key_layout, kTISPropertyUnicodeKeyLayoutData); + if (uchrDataRef) { + chr_data = CFDataGetBytePtr(uchrDataRef); + } else { + goto cleanup; + } + + if (chr_data) { + UInt32 keyboard_type = LMGetKbdType(); + OSStatus err; + + for (i = 0; i < SDL_arraysize(darwin_scancode_table); i++) { + UniChar s[8]; + UniCharCount len; + UInt32 dead_key_state; + + /* Make sure this scancode is a valid character scancode */ + scancode = darwin_scancode_table[i]; + if (scancode == SDL_SCANCODE_UNKNOWN || + (keymap[scancode] & SDLK_SCANCODE_MASK)) { + continue; + } + + /* + * Swap the scancode for these two wrongly translated keys + * UCKeyTranslate() function does not do its job properly for ISO layout keyboards, where the key '@', + * which is located in the top left corner of the keyboard right under the Escape key, and the additional + * key '<', which is on the right of the Shift key, are inverted + */ + if ((scancode == SDL_SCANCODE_NONUSBACKSLASH || scancode == SDL_SCANCODE_GRAVE) && KBGetLayoutType(LMGetKbdType()) == kKeyboardISO) { + /* see comments in scancodes_darwin.h */ + scancode = (SDL_Scancode)((SDL_SCANCODE_NONUSBACKSLASH + SDL_SCANCODE_GRAVE) - scancode); + } + + dead_key_state = 0; + err = UCKeyTranslate ((UCKeyboardLayout *) chr_data, + i, kUCKeyActionDown, + 0, keyboard_type, + kUCKeyTranslateNoDeadKeysMask, + &dead_key_state, 8, &len, s); + if (err != noErr) { + continue; + } + + if (len > 0 && s[0] != 0x10) { + keymap[scancode] = s[0]; + } + } + SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES, send_event); + return; + } + +cleanup: + CFRelease(key_layout); +} + +void Cocoa_InitKeyboard(_THIS) +{ + SDL_VideoData *data = (__bridge SDL_VideoData *) _this->driverdata; + + UpdateKeymap(data, SDL_FALSE); + + /* Set our own names for the platform-dependent but layout-independent keys */ + /* This key is NumLock on the MacBook keyboard. :) */ + /*SDL_SetScancodeName(SDL_SCANCODE_NUMLOCKCLEAR, "Clear");*/ + SDL_SetScancodeName(SDL_SCANCODE_LALT, "Left Option"); + SDL_SetScancodeName(SDL_SCANCODE_LGUI, "Left Command"); + SDL_SetScancodeName(SDL_SCANCODE_RALT, "Right Option"); + SDL_SetScancodeName(SDL_SCANCODE_RGUI, "Right Command"); + + data.modifierFlags = (unsigned int)[NSEvent modifierFlags]; + SDL_ToggleModState(KMOD_CAPS, (data.modifierFlags & NSEventModifierFlagCapsLock) ? SDL_TRUE : SDL_FALSE); +} + +void Cocoa_StartTextInput(_THIS) +{ @autoreleasepool +{ + NSView *parentView; + SDL_VideoData *data = (__bridge SDL_VideoData *) _this->driverdata; + SDL_Window *window = SDL_GetKeyboardFocus(); + NSWindow *nswindow = nil; + if (window) { + nswindow = ((__bridge SDL_WindowData*)window->driverdata).nswindow; + } + + parentView = [nswindow contentView]; + + /* We only keep one field editor per process, since only the front most + * window can receive text input events, so it make no sense to keep more + * than one copy. When we switched to another window and requesting for + * text input, simply remove the field editor from its superview then add + * it to the front most window's content view */ + if (!data.fieldEdit) { + data.fieldEdit = + [[SDLTranslatorResponder alloc] initWithFrame: NSMakeRect(0.0, 0.0, 0.0, 0.0)]; + } + + if (![[data.fieldEdit superview] isEqual:parentView]) { + /* DEBUG_IME(@"add fieldEdit to window contentView"); */ + [data.fieldEdit removeFromSuperview]; + [parentView addSubview: data.fieldEdit]; + [nswindow makeFirstResponder: data.fieldEdit]; + } +}} + +void Cocoa_StopTextInput(_THIS) +{ @autoreleasepool +{ + SDL_VideoData *data = (__bridge SDL_VideoData *) _this->driverdata; + + if (data && data.fieldEdit) { + [data.fieldEdit removeFromSuperview]; + data.fieldEdit = nil; + } +}} + +void Cocoa_SetTextInputRect(_THIS, const SDL_Rect *rect) +{ + SDL_VideoData *data = (__bridge SDL_VideoData *) _this->driverdata; + + if (!rect) { + SDL_InvalidParamError("rect"); + return; + } + + [data.fieldEdit setInputRect:rect]; +} + +void Cocoa_HandleKeyEvent(_THIS, NSEvent *event) +{ + unsigned short scancode; + SDL_Scancode code; + SDL_VideoData *data = _this ? ((__bridge SDL_VideoData *) _this->driverdata) : nil; + if (!data) { + return; /* can happen when returning from fullscreen Space on shutdown */ + } + + scancode = [event keyCode]; +#if 0 + const char *text; +#endif + + if ((scancode == 10 || scancode == 50) && KBGetLayoutType(LMGetKbdType()) == kKeyboardISO) { + /* see comments in scancodes_darwin.h */ + scancode = 60 - scancode; + } + + if (scancode < SDL_arraysize(darwin_scancode_table)) { + code = darwin_scancode_table[scancode]; + } else { + /* Hmm, does this ever happen? If so, need to extend the keymap... */ + code = SDL_SCANCODE_UNKNOWN; + } + + switch ([event type]) { + case NSEventTypeKeyDown: + if (![event isARepeat]) { + /* See if we need to rebuild the keyboard layout */ + UpdateKeymap(data, SDL_TRUE); + } + + SDL_SendKeyboardKey(SDL_PRESSED, code); +#ifdef DEBUG_SCANCODES + if (code == SDL_SCANCODE_UNKNOWN) { + SDL_Log("The key you just pressed is not recognized by SDL. To help get this fixed, report this to the SDL forums/mailing list or to Christian Walther . Mac virtual key code is %d.\n", scancode); + } +#endif + if (SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) { + /* FIXME CW 2007-08-16: only send those events to the field editor for which we actually want text events, not e.g. esc or function keys. Arrow keys in particular seem to produce crashes sometimes. */ + [data.fieldEdit interpretKeyEvents:[NSArray arrayWithObject:event]]; +#if 0 + text = [[event characters] UTF8String]; + if(text && *text) { + SDL_SendKeyboardText(text); + [data->fieldEdit setString:@""]; + } +#endif + } + break; + case NSEventTypeKeyUp: + SDL_SendKeyboardKey(SDL_RELEASED, code); + break; + case NSEventTypeFlagsChanged: { + // see if the new modifierFlags mean any existing keys should be pressed/released... + const unsigned int modflags = (unsigned int)[event modifierFlags]; + HandleModifiers(_this, SDL_SCANCODE_LSHIFT, modflags); + HandleModifiers(_this, SDL_SCANCODE_LCTRL, modflags); + HandleModifiers(_this, SDL_SCANCODE_LALT, modflags); + HandleModifiers(_this, SDL_SCANCODE_LGUI, modflags); + HandleModifiers(_this, SDL_SCANCODE_RSHIFT, modflags); + HandleModifiers(_this, SDL_SCANCODE_RCTRL, modflags); + HandleModifiers(_this, SDL_SCANCODE_RALT, modflags); + HandleModifiers(_this, SDL_SCANCODE_RGUI, modflags); + break; + } + default: /* just to avoid compiler warnings */ + break; + } +} + +void Cocoa_QuitKeyboard(_THIS) +{ +} + +typedef int CGSConnection; +typedef enum { + CGSGlobalHotKeyEnable = 0, + CGSGlobalHotKeyDisable = 1, +} CGSGlobalHotKeyOperatingMode; + +extern CGSConnection _CGSDefaultConnection(void); +extern CGError CGSSetGlobalHotKeyOperatingMode(CGSConnection connection, CGSGlobalHotKeyOperatingMode mode); + +void Cocoa_SetWindowKeyboardGrab(_THIS, SDL_Window * window, SDL_bool grabbed) +{ +#ifdef SDL_MAC_NO_SANDBOX + CGSSetGlobalHotKeyOperatingMode(_CGSDefaultConnection(), grabbed ? CGSGlobalHotKeyDisable : CGSGlobalHotKeyEnable); +#endif +} + +#endif /* SDL_VIDEO_DRIVER_COCOA */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/cocoa/SDL_cocoamessagebox.h b/SDL2-2.30.5/src/video/cocoa/SDL_cocoamessagebox.h similarity index 92% rename from SDL2-2.0.12/src/video/cocoa/SDL_cocoamessagebox.h rename to SDL2-2.30.5/src/video/cocoa/SDL_cocoamessagebox.h index 15bcfba..765ffe7 100644 --- a/SDL2-2.0.12/src/video/cocoa/SDL_cocoamessagebox.h +++ b/SDL2-2.30.5/src/video/cocoa/SDL_cocoamessagebox.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_COCOA +#ifdef SDL_VIDEO_DRIVER_COCOA extern int Cocoa_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid); diff --git a/SDL2-2.0.12/src/video/cocoa/SDL_cocoamessagebox.m b/SDL2-2.30.5/src/video/cocoa/SDL_cocoamessagebox.m similarity index 64% rename from SDL2-2.0.12/src/video/cocoa/SDL_cocoamessagebox.m rename to SDL2-2.30.5/src/video/cocoa/SDL_cocoamessagebox.m index 173225b..4e342c1 100644 --- a/SDL2-2.0.12/src/video/cocoa/SDL_cocoamessagebox.m +++ b/SDL2-2.30.5/src/video/cocoa/SDL_cocoamessagebox.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_COCOA +#ifdef SDL_VIDEO_DRIVER_COCOA #include "SDL_events.h" #include "SDL_timer.h" @@ -32,8 +32,7 @@ NSInteger clicked; NSWindow *nswindow; } -- (id) initWithParentWindow:(SDL_Window *)window; -- (void) alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo; +- (id)initWithParentWindow:(SDL_Window *)window; @end @implementation SDLMessageBoxPresenter @@ -45,9 +44,9 @@ /* Retain the NSWindow because we'll show the alert later on the main thread */ if (window) { - nswindow = [((SDL_WindowData *) window->driverdata)->nswindow retain]; + nswindow = ((__bridge SDL_WindowData *) window->driverdata).nswindow; } else { - nswindow = NULL; + nswindow = nil; } } @@ -57,46 +56,29 @@ - (void)showAlert:(NSAlert*)alert { if (nswindow) { -#ifdef MAC_OS_X_VERSION_10_9 - if ([alert respondsToSelector:@selector(beginSheetModalForWindow:completionHandler:)]) { - [alert beginSheetModalForWindow:nswindow completionHandler:^(NSModalResponse returnCode) { - clicked = returnCode; - }]; - } else -#endif - { -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1090 - [alert beginSheetModalForWindow:nswindow modalDelegate:self didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:nil]; -#endif - } - - while (clicked < 0) { - SDL_PumpEvents(); - SDL_Delay(100); - } - - [nswindow release]; + [alert beginSheetModalForWindow:nswindow + completionHandler:^(NSModalResponse returnCode) { + [NSApp stopModalWithCode:returnCode]; + }]; + clicked = [NSApp runModalForWindow:nswindow]; + nswindow = nil; } else { clicked = [alert runModal]; } } - -- (void) alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo -{ - clicked = returnCode; -} - @end -/* Display a Cocoa message box */ -int -Cocoa_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) -{ @autoreleasepool +static void Cocoa_ShowMessageBoxImpl(const SDL_MessageBoxData *messageboxdata, int *buttonid, int *returnValue) { + NSAlert* alert; + const SDL_MessageBoxButtonData *buttons = messageboxdata->buttons; + SDLMessageBoxPresenter* presenter; + NSInteger clicked; + int i; Cocoa_RegisterApp(); - NSAlert* alert = [[[NSAlert alloc] init] autorelease]; + alert = [[NSAlert alloc] init]; if (messageboxdata->flags & SDL_MESSAGEBOX_ERROR) { [alert setAlertStyle:NSAlertStyleCritical]; @@ -109,11 +91,9 @@ Cocoa_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) [alert setMessageText:[NSString stringWithUTF8String:messageboxdata->title]]; [alert setInformativeText:[NSString stringWithUTF8String:messageboxdata->message]]; - const SDL_MessageBoxButtonData *buttons = messageboxdata->buttons; - int i; for (i = 0; i < messageboxdata->numbuttons; ++i) { const SDL_MessageBoxButtonData *sdlButton; - NSButton *button; + NSButton *button; if (messageboxdata->flags & SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT) { sdlButton = &messageboxdata->buttons[messageboxdata->numbuttons - 1 - i]; @@ -131,24 +111,34 @@ Cocoa_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) } } - SDLMessageBoxPresenter* presenter = [[[SDLMessageBoxPresenter alloc] initWithParentWindow:messageboxdata->window] autorelease]; + presenter = [[SDLMessageBoxPresenter alloc] initWithParentWindow:messageboxdata->window]; - [presenter performSelectorOnMainThread:@selector(showAlert:) - withObject:alert - waitUntilDone:YES]; + [presenter showAlert:alert]; - int returnValue = 0; - NSInteger clicked = presenter->clicked; + clicked = presenter->clicked; if (clicked >= NSAlertFirstButtonReturn) { clicked -= NSAlertFirstButtonReturn; if (messageboxdata->flags & SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT) { - clicked = messageboxdata->numbuttons - 1 - clicked; - } + clicked = messageboxdata->numbuttons - 1 - clicked; + } *buttonid = buttons[clicked].buttonid; + *returnValue = 0; } else { - returnValue = SDL_SetError("Did not get a valid `clicked button' id: %ld", (long)clicked); + *returnValue = SDL_SetError("Did not get a valid `clicked button' id: %ld", (long)clicked); } +} +/* Display a Cocoa message box */ +int Cocoa_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) +{ @autoreleasepool +{ + __block int returnValue = 0; + + if ([NSThread isMainThread]) { + Cocoa_ShowMessageBoxImpl(messageboxdata, buttonid, &returnValue); + } else { + dispatch_sync(dispatch_get_main_queue(), ^{ Cocoa_ShowMessageBoxImpl(messageboxdata, buttonid, &returnValue); }); + } return returnValue; }} diff --git a/SDL2-2.0.12/src/video/cocoa/SDL_cocoametalview.h b/SDL2-2.30.5/src/video/cocoa/SDL_cocoametalview.h similarity index 81% rename from SDL2-2.0.12/src/video/cocoa/SDL_cocoametalview.h rename to SDL2-2.30.5/src/video/cocoa/SDL_cocoametalview.h index 4dc5fa9..d4a5374 100644 --- a/SDL2-2.0.12/src/video/cocoa/SDL_cocoametalview.h +++ b/SDL2-2.30.5/src/video/cocoa/SDL_cocoametalview.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -21,15 +21,15 @@ /* * @author Mark Callow, www.edgewise-consulting.com. * - * Thanks to Alex Szpakowski, @slime73 on GitHub, for his gist showing - * how to add a CAMetalLayer backed view. + * Thanks to @slime73 on GitHub for their gist showing how to add a CAMetalLayer + * backed view. */ #include "../../SDL_internal.h" #ifndef SDL_cocoametalview_h_ #define SDL_cocoametalview_h_ -#if SDL_VIDEO_DRIVER_COCOA && (SDL_VIDEO_VULKAN || SDL_VIDEO_METAL) +#if defined(SDL_VIDEO_DRIVER_COCOA) && (defined(SDL_VIDEO_VULKAN) || defined(SDL_VIDEO_METAL)) #import "../SDL_sysvideo.h" @@ -39,7 +39,6 @@ #import #import -#define METALVIEW_TAG 255 @interface SDL_cocoametalview : NSView @@ -48,6 +47,7 @@ windowID:(Uint32)windowID; - (void)updateDrawableSize; +- (NSView *)hitTest:(NSPoint)point; /* Override superclass tag so this class can set it. */ @property (assign, readonly) NSInteger tag; @@ -59,8 +59,8 @@ SDL_MetalView Cocoa_Metal_CreateView(_THIS, SDL_Window * window); void Cocoa_Metal_DestroyView(_THIS, SDL_MetalView view); - -void Cocoa_Metal_GetDrawableSize(SDL_Window * window, int * w, int * h); +void *Cocoa_Metal_GetLayer(_THIS, SDL_MetalView view); +void Cocoa_Metal_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h); #endif /* SDL_VIDEO_DRIVER_COCOA && (SDL_VIDEO_VULKAN || SDL_VIDEO_METAL) */ diff --git a/SDL2-2.0.12/src/video/cocoa/SDL_cocoametalview.m b/SDL2-2.30.5/src/video/cocoa/SDL_cocoametalview.m similarity index 76% rename from SDL2-2.0.12/src/video/cocoa/SDL_cocoametalview.m rename to SDL2-2.30.5/src/video/cocoa/SDL_cocoametalview.m index 1c67c9f..d71f651 100644 --- a/SDL2-2.0.12/src/video/cocoa/SDL_cocoametalview.m +++ b/SDL2-2.30.5/src/video/cocoa/SDL_cocoametalview.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -21,16 +21,18 @@ /* * @author Mark Callow, www.edgewise-consulting.com. * - * Thanks to Alex Szpakowski, @slime73 on GitHub, for his gist showing - * how to add a CAMetalLayer backed view. + * Thanks to @slime73 on GitHub for their gist showing how to add a CAMetalLayer + * backed view. */ +#include "../../SDL_internal.h" #import "SDL_cocoametalview.h" -#if SDL_VIDEO_DRIVER_COCOA && (SDL_VIDEO_VULKAN || SDL_VIDEO_METAL) +#if defined(SDL_VIDEO_DRIVER_COCOA) && (defined(SDL_VIDEO_VULKAN) || defined(SDL_VIDEO_METAL)) -#include "SDL_assert.h" #include "SDL_events.h" +#include "SDL_syswm.h" + static int SDLCALL SDL_MetalViewEventWatch(void *userdata, SDL_Event *event) @@ -79,7 +81,8 @@ SDL_MetalViewEventWatch(void *userdata, SDL_Event *event) highDPI:(BOOL)highDPI windowID:(Uint32)windowID; { - if ((self = [super initWithFrame:frame])) { + self = [super initWithFrame:frame]; + if (self != nil) { self.highDPI = highDPI; self.sdlWindowID = windowID; self.wantsLayer = YES; @@ -87,23 +90,22 @@ SDL_MetalViewEventWatch(void *userdata, SDL_Event *event) /* Allow resize. */ self.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable; - SDL_AddEventWatch(SDL_MetalViewEventWatch, self); + SDL_AddEventWatch(SDL_MetalViewEventWatch, (__bridge void *)(self)); [self updateDrawableSize]; } - + return self; } - (void)dealloc { - SDL_DelEventWatch(SDL_MetalViewEventWatch, self); - [super dealloc]; + SDL_DelEventWatch(SDL_MetalViewEventWatch, (__bridge void *)(self)); } - (NSInteger)tag { - return METALVIEW_TAG; + return SDL_METALVIEW_TAG; } - (void)updateDrawableSize @@ -123,13 +125,16 @@ SDL_MetalViewEventWatch(void *userdata, SDL_Event *event) metalLayer.drawableSize = NSSizeToCGSize(backingSize); } +- (NSView *)hitTest:(NSPoint)point { + return nil; +} + @end -SDL_MetalView -Cocoa_Metal_CreateView(_THIS, SDL_Window * window) +SDL_MetalView Cocoa_Metal_CreateView(_THIS, SDL_Window * window) { @autoreleasepool { SDL_WindowData* data = (__bridge SDL_WindowData *)window->driverdata; - NSView *view = data->nswindow.contentView; + NSView *view = data.nswindow.contentView; BOOL highDPI = (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) != 0; Uint32 windowID = SDL_GetWindowID(window); SDL_cocoametalview *newview; @@ -139,30 +144,37 @@ Cocoa_Metal_CreateView(_THIS, SDL_Window * window) highDPI:highDPI windowID:windowID]; if (newview == nil) { + SDL_OutOfMemory(); return NULL; } [view addSubview:newview]; + /* Make sure the drawable size is up to date after attaching the view. */ + [newview updateDrawableSize]; + metalview = (SDL_MetalView)CFBridgingRetain(newview); - [newview release]; return metalview; }} -void -Cocoa_Metal_DestroyView(_THIS, SDL_MetalView view) +void Cocoa_Metal_DestroyView(_THIS, SDL_MetalView view) { @autoreleasepool { SDL_cocoametalview *metalview = CFBridgingRelease(view); [metalview removeFromSuperview]; }} -void -Cocoa_Metal_GetDrawableSize(SDL_Window * window, int * w, int * h) +void *Cocoa_Metal_GetLayer(_THIS, SDL_MetalView view) +{ @autoreleasepool { + SDL_cocoametalview *cocoaview = (__bridge SDL_cocoametalview *)view; + return (__bridge void *)cocoaview.layer; +}} + +void Cocoa_Metal_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h) { @autoreleasepool { SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata; - NSView *view = data->nswindow.contentView; - SDL_cocoametalview* metalview = [view viewWithTag:METALVIEW_TAG]; + NSView *contentView = data.sdlContentView; + SDL_cocoametalview* metalview = [contentView viewWithTag:SDL_METALVIEW_TAG]; if (metalview) { CAMetalLayer *layer = (CAMetalLayer*)metalview.layer; SDL_assert(layer != NULL); @@ -173,7 +185,8 @@ Cocoa_Metal_GetDrawableSize(SDL_Window * window, int * w, int * h) *h = layer.drawableSize.height; } } else { - SDL_GetWindowSize(window, w, h); + /* Fall back to the viewport size. */ + SDL_GetWindowSizeInPixels(window, w, h); } }} diff --git a/SDL2-2.0.12/src/video/cocoa/SDL_cocoamodes.h b/SDL2-2.30.5/src/video/cocoa/SDL_cocoamodes.h similarity index 96% rename from SDL2-2.0.12/src/video/cocoa/SDL_cocoamodes.h rename to SDL2-2.30.5/src/video/cocoa/SDL_cocoamodes.h index 836fda7..426036e 100644 --- a/SDL2-2.0.12/src/video/cocoa/SDL_cocoamodes.h +++ b/SDL2-2.30.5/src/video/cocoa/SDL_cocoamodes.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/video/cocoa/SDL_cocoamodes.m b/SDL2-2.30.5/src/video/cocoa/SDL_cocoamodes.m similarity index 78% rename from SDL2-2.0.12/src/video/cocoa/SDL_cocoamodes.m rename to SDL2-2.30.5/src/video/cocoa/SDL_cocoamodes.m index c40e418..d1ef99e 100644 --- a/SDL2-2.0.12/src/video/cocoa/SDL_cocoamodes.m +++ b/SDL2-2.30.5/src/video/cocoa/SDL_cocoamodes.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -19,9 +19,8 @@ 3. This notice may not be removed or altered from any source distribution. */ #include "../../SDL_internal.h" -#include "SDL_assert.h" -#if SDL_VIDEO_DRIVER_COCOA +#ifdef SDL_VIDEO_DRIVER_COCOA #include "SDL_cocoavideo.h" @@ -32,36 +31,18 @@ #include #include -/* we need this for ShowMenuBar() and HideMenuBar(). */ -#include - /* This gets us MAC_OS_X_VERSION_MIN_REQUIRED... */ #include #ifndef MAC_OS_X_VERSION_10_13 #define NSAppKitVersionNumber10_12 1504 #endif - - -static void -Cocoa_ToggleMenuBar(const BOOL show) -{ - /* !!! FIXME: keep an eye on this. - * ShowMenuBar/HideMenuBar is officially unavailable for 64-bit binaries. - * It happens to work, as of 10.7, but we're going to see if - * we can just simply do without it on newer OSes... - */ -#if (MAC_OS_X_VERSION_MIN_REQUIRED < 1070) && !defined(__LP64__) - if (show) { - ShowMenuBar(); - } else { - HideMenuBar(); - } +#if (IOGRAPHICSTYPES_REV < 40) +#define kDisplayModeNativeFlag 0x02000000 #endif -} -static int -CG_SetError(const char *prefix, CGDisplayErr result) + +static int CG_SetError(const char *prefix, CGDisplayErr result) { const char *error; @@ -103,8 +84,7 @@ CG_SetError(const char *prefix, CGDisplayErr result) return SDL_SetError("%s: %s", prefix, error); } -static int -GetDisplayModeRefreshRate(CGDisplayModeRef vidmode, CVDisplayLinkRef link) +static int GetDisplayModeRefreshRate(CGDisplayModeRef vidmode, CVDisplayLinkRef link) { int refreshRate = (int) (CGDisplayModeGetRefreshRate(vidmode) + 0.5); @@ -119,8 +99,7 @@ GetDisplayModeRefreshRate(CGDisplayModeRef vidmode, CVDisplayLinkRef link) return refreshRate; } -static SDL_bool -HasValidDisplayModeFlags(CGDisplayModeRef vidmode) +static SDL_bool HasValidDisplayModeFlags(CGDisplayModeRef vidmode) { uint32_t ioflags = CGDisplayModeGetIOFlags(vidmode); @@ -137,8 +116,7 @@ HasValidDisplayModeFlags(CGDisplayModeRef vidmode) return SDL_TRUE; } -static Uint32 -GetDisplayModePixelFormat(CGDisplayModeRef vidmode) +static Uint32 GetDisplayModePixelFormat(CGDisplayModeRef vidmode) { /* This API is deprecated in 10.11 with no good replacement (as of 10.15). */ CFStringRef fmt = CGDisplayModeCopyPixelEncoding(vidmode); @@ -162,8 +140,7 @@ GetDisplayModePixelFormat(CGDisplayModeRef vidmode) return pixelformat; } -static SDL_bool -GetDisplayMode(_THIS, CGDisplayModeRef vidmode, CFArrayRef modelist, CVDisplayLinkRef link, SDL_DisplayMode *mode) +static SDL_bool GetDisplayMode(_THIS, CGDisplayModeRef vidmode, SDL_bool vidmodeCurrent, CFArrayRef modelist, CVDisplayLinkRef link, SDL_DisplayMode *mode) { SDL_DisplayModeData *data; bool usableForGUI = CGDisplayModeIsUsableForDesktopGUI(vidmode); @@ -179,7 +156,9 @@ GetDisplayMode(_THIS, CGDisplayModeRef vidmode, CFArrayRef modelist, CVDisplayLi return SDL_FALSE; } - if (!HasValidDisplayModeFlags(vidmode)) { + /* Don't fail the current mode based on flags because this could prevent Cocoa_InitModes from + * succeeding if the current mode lacks certain flags (esp kDisplayModeSafeFlag). */ + if (!vidmodeCurrent && !HasValidDisplayModeFlags(vidmode)) { return SDL_FALSE; } @@ -198,8 +177,12 @@ GetDisplayMode(_THIS, CGDisplayModeRef vidmode, CFArrayRef modelist, CVDisplayLi int pixelH = (int) CGDisplayModeGetPixelHeight(vidmode); CFIndex modescount = CFArrayGetCount(modelist); + int i; - for (int i = 0; i < modescount; i++) { + for (i = 0; i < modescount; i++) { + int otherW, otherH, otherpixelW, otherpixelH, otherrefresh; + Uint32 otherformat; + bool otherGUI; CGDisplayModeRef othermode = (CGDisplayModeRef) CFArrayGetValueAtIndex(modelist, i); uint32_t otherioflags = CGDisplayModeGetIOFlags(othermode); @@ -211,13 +194,13 @@ GetDisplayMode(_THIS, CGDisplayModeRef vidmode, CFArrayRef modelist, CVDisplayLi continue; } - int otherW = (int) CGDisplayModeGetWidth(othermode); - int otherH = (int) CGDisplayModeGetHeight(othermode); - int otherpixelW = (int) CGDisplayModeGetPixelWidth(othermode); - int otherpixelH = (int) CGDisplayModeGetPixelHeight(othermode); - int otherrefresh = GetDisplayModeRefreshRate(othermode, link); - Uint32 otherformat = GetDisplayModePixelFormat(othermode); - bool otherGUI = CGDisplayModeIsUsableForDesktopGUI(othermode); + otherW = (int) CGDisplayModeGetWidth(othermode); + otherH = (int) CGDisplayModeGetHeight(othermode); + otherpixelW = (int) CGDisplayModeGetPixelWidth(othermode); + otherpixelH = (int) CGDisplayModeGetPixelHeight(othermode); + otherrefresh = GetDisplayModeRefreshRate(othermode, link); + otherformat = GetDisplayModePixelFormat(othermode); + otherGUI = CGDisplayModeIsUsableForDesktopGUI(othermode); /* Ignore this mode if it's low-dpi (@1x) and we have a high-dpi * mode in the list with the same size in points. @@ -295,13 +278,12 @@ GetDisplayMode(_THIS, CGDisplayModeRef vidmode, CFArrayRef modelist, CVDisplayLi return SDL_TRUE; } -static const char * -Cocoa_GetDisplayName(CGDirectDisplayID displayID) +static const char *Cocoa_GetDisplayName(CGDirectDisplayID displayID) { /* This API is deprecated in 10.9 with no good replacement (as of 10.15). */ io_service_t servicePort = CGDisplayIOServicePort(displayID); CFDictionaryRef deviceInfo = IODisplayCreateInfoDictionary(servicePort, kIODisplayOnlyPreferredName); - NSDictionary *localizedNames = [(NSDictionary *)deviceInfo objectForKey:[NSString stringWithUTF8String:kDisplayProductName]]; + NSDictionary *localizedNames = [(__bridge NSDictionary *)deviceInfo objectForKey:[NSString stringWithUTF8String:kDisplayProductName]]; const char* displayName = NULL; if ([localizedNames count] > 0) { @@ -311,8 +293,7 @@ Cocoa_GetDisplayName(CGDirectDisplayID displayID) return displayName; } -void -Cocoa_InitModes(_THIS) +void Cocoa_InitModes(_THIS) { @autoreleasepool { CGDisplayErr result; @@ -375,7 +356,7 @@ Cocoa_InitModes(_THIS) SDL_zero(display); /* this returns a stddup'ed string */ display.name = (char *)Cocoa_GetDisplayName(displays[i]); - if (!GetDisplayMode(_this, moderef, NULL, link, &mode)) { + if (!GetDisplayMode(_this, moderef, SDL_TRUE, NULL, link, &mode)) { CVDisplayLinkRelease(link); CGDisplayModeRelease(moderef); SDL_free(display.name); @@ -389,15 +370,14 @@ Cocoa_InitModes(_THIS) display.desktop_mode = mode; display.current_mode = mode; display.driverdata = displaydata; - SDL_AddVideoDisplay(&display); + SDL_AddVideoDisplay(&display, SDL_FALSE); SDL_free(display.name); } } SDL_small_free(displays, isstack); }} -int -Cocoa_GetDisplayBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect) +int Cocoa_GetDisplayBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect) { SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata; CGRect cgrect; @@ -410,8 +390,7 @@ Cocoa_GetDisplayBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect) return 0; } -int -Cocoa_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect) +int Cocoa_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect) { SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata; const CGDirectDisplayID cgdisplay = displaydata->display; @@ -432,17 +411,18 @@ Cocoa_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect) return -1; } - const NSRect frame = [screen visibleFrame]; - rect->x = (int)frame.origin.x; - rect->y = (int)(CGDisplayPixelsHigh(kCGDirectMainDisplay) - frame.origin.y - frame.size.height); - rect->w = (int)frame.size.width; - rect->h = (int)frame.size.height; + { + const NSRect frame = [screen visibleFrame]; + rect->x = (int)frame.origin.x; + rect->y = (int)(CGDisplayPixelsHigh(kCGDirectMainDisplay) - frame.origin.y - frame.size.height); + rect->w = (int)frame.size.width; + rect->h = (int)frame.size.height; + } return 0; } -int -Cocoa_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi, float * hdpi, float * vdpi) +int Cocoa_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi, float * hdpi, float * vdpi) { @autoreleasepool { const float MM_IN_INCH = 25.4f; @@ -452,35 +432,75 @@ Cocoa_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi, float * hdp /* we need the backingScaleFactor for Retina displays, which is only exposed through NSScreen, not CGDisplay, afaik, so find our screen... */ CGFloat scaleFactor = 1.0f; NSArray *screens = [NSScreen screens]; + NSSize displayNativeSize; + displayNativeSize.width = (int) CGDisplayPixelsWide(data->display); + displayNativeSize.height = (int) CGDisplayPixelsHigh(data->display); + for (NSScreen *screen in screens) { const CGDirectDisplayID dpyid = (const CGDirectDisplayID ) [[[screen deviceDescription] objectForKey:@"NSScreenNumber"] unsignedIntValue]; if (dpyid == data->display) { - if ([screen respondsToSelector:@selector(backingScaleFactor)]) { // Mac OS X 10.7 and later +#ifdef MAC_OS_X_VERSION_10_8 + /* Neither CGDisplayScreenSize(description's NSScreenNumber) nor [NSScreen backingScaleFactor] can calculate the correct dpi in macOS. E.g. backingScaleFactor is always 2 in all display modes for rMBP 16" */ + if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_7) { + CFStringRef dmKeys[1] = { kCGDisplayShowDuplicateLowResolutionModes }; + CFBooleanRef dmValues[1] = { kCFBooleanTrue }; + CFDictionaryRef dmOptions = CFDictionaryCreate(kCFAllocatorDefault, (const void**) dmKeys, (const void**) dmValues, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks ); + CFArrayRef allDisplayModes = CGDisplayCopyAllDisplayModes(dpyid, dmOptions); + CFIndex n = CFArrayGetCount(allDisplayModes); + for(CFIndex i = 0; i < n; ++i) { + CGDisplayModeRef m = (CGDisplayModeRef)CFArrayGetValueAtIndex(allDisplayModes, i); + CGFloat width = CGDisplayModeGetPixelWidth(m); + CGFloat height = CGDisplayModeGetPixelHeight(m); + CGFloat HiDPIWidth = CGDisplayModeGetWidth(m); + + //Only check 1x mode + if(width == HiDPIWidth) { + if (CGDisplayModeGetIOFlags(m) & kDisplayModeNativeFlag) { + displayNativeSize.width = width; + displayNativeSize.height = height; + break; + } + + //Get the largest size even if kDisplayModeNativeFlag is not present e.g. iMac 27-Inch with 5K Retina + if(width > displayNativeSize.width) { + displayNativeSize.width = width; + displayNativeSize.height = height; + } + } + } + CFRelease(allDisplayModes); + CFRelease(dmOptions); + } else +#endif + { + // fallback for 10.7 scaleFactor = [screen backingScaleFactor]; + displayNativeSize.width = displayNativeSize.width * scaleFactor; + displayNativeSize.height = displayNativeSize.height * scaleFactor; break; } } } - const CGSize displaySize = CGDisplayScreenSize(data->display); - const int pixelWidth = (int) CGDisplayPixelsWide(data->display); - const int pixelHeight = (int) CGDisplayPixelsHigh(data->display); + { + const CGSize displaySize = CGDisplayScreenSize(data->display); + const int pixelWidth = displayNativeSize.width; + const int pixelHeight = displayNativeSize.height; - if (ddpi) { - *ddpi = (SDL_ComputeDiagonalDPI(pixelWidth, pixelHeight, displaySize.width / MM_IN_INCH, displaySize.height / MM_IN_INCH)) * scaleFactor; + if (ddpi) { + *ddpi = (SDL_ComputeDiagonalDPI(pixelWidth, pixelHeight, displaySize.width / MM_IN_INCH, displaySize.height / MM_IN_INCH)); + } + if (hdpi) { + *hdpi = (pixelWidth * MM_IN_INCH / displaySize.width); + } + if (vdpi) { + *vdpi = (pixelHeight * MM_IN_INCH / displaySize.height); + } } - if (hdpi) { - *hdpi = (pixelWidth * MM_IN_INCH / displaySize.width) * scaleFactor; - } - if (vdpi) { - *vdpi = (pixelHeight * MM_IN_INCH / displaySize.height) * scaleFactor; - } - return 0; }} -void -Cocoa_GetDisplayModes(_THIS, SDL_VideoDisplay * display) +void Cocoa_GetDisplayModes(_THIS, SDL_VideoDisplay * display) { SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata; CVDisplayLinkRef link = NULL; @@ -499,7 +519,7 @@ Cocoa_GetDisplayModes(_THIS, SDL_VideoDisplay * display) * sure there are no duplicates so it's safe to always add the desktop mode * even in cases where it is in the CopyAllDisplayModes list. */ - if (desktopmoderef && GetDisplayMode(_this, desktopmoderef, NULL, link, &desktopmode)) { + if (desktopmoderef && GetDisplayMode(_this, desktopmoderef, SDL_TRUE, NULL, link, &desktopmode)) { if (!SDL_AddDisplayMode(display, &desktopmode)) { CFRelease(((SDL_DisplayModeData*)desktopmode.driverdata)->modes); SDL_free(desktopmode.driverdata); @@ -546,7 +566,7 @@ Cocoa_GetDisplayModes(_THIS, SDL_VideoDisplay * display) CGDisplayModeRef moderef = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i); SDL_DisplayMode mode; - if (GetDisplayMode(_this, moderef, modes, link, &mode)) { + if (GetDisplayMode(_this, moderef, SDL_FALSE, modes, link, &mode)) { if (!SDL_AddDisplayMode(display, &mode)) { CFRelease(((SDL_DisplayModeData*)mode.driverdata)->modes); SDL_free(mode.driverdata); @@ -560,8 +580,7 @@ Cocoa_GetDisplayModes(_THIS, SDL_VideoDisplay * display) CVDisplayLinkRelease(link); } -static CGError -SetDisplayModeForDisplay(CGDirectDisplayID display, SDL_DisplayModeData *data) +static CGError SetDisplayModeForDisplay(CGDirectDisplayID display, SDL_DisplayModeData *data) { /* SDL_DisplayModeData can contain multiple CGDisplayModes to try (with * identical properties), some of which might not work. See GetDisplayMode. @@ -579,8 +598,7 @@ SetDisplayModeForDisplay(CGDirectDisplayID display, SDL_DisplayModeData *data) return result; } -int -Cocoa_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) +int Cocoa_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) { SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata; SDL_DisplayModeData *data = (SDL_DisplayModeData *) mode->driverdata; @@ -601,10 +619,6 @@ Cocoa_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) } else { CGDisplayRelease(displaydata->display); } - - if (CGDisplayIsMain(displaydata->display)) { - Cocoa_ToggleMenuBar(YES); - } } else { /* Put up the blanking window (a window above all other windows) */ if (CGDisplayIsMain(displaydata->display)) { @@ -624,11 +638,6 @@ Cocoa_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) CG_SetError("CGDisplaySwitchToMode()", result); goto ERR_NO_SWITCH; } - - /* Hide the menu bar so it doesn't intercept events */ - if (CGDisplayIsMain(displaydata->display)) { - Cocoa_ToggleMenuBar(NO); - } } /* Fade in again (asynchronously) */ @@ -654,8 +663,7 @@ ERR_NO_CAPTURE: return -1; } -void -Cocoa_QuitModes(_THIS) +void Cocoa_QuitModes(_THIS) { int i, j; @@ -675,7 +683,6 @@ Cocoa_QuitModes(_THIS) CFRelease(mode->modes); } } - Cocoa_ToggleMenuBar(YES); } #endif /* SDL_VIDEO_DRIVER_COCOA */ diff --git a/SDL2-2.0.12/src/video/cocoa/SDL_cocoamouse.h b/SDL2-2.30.5/src/video/cocoa/SDL_cocoamouse.h similarity index 86% rename from SDL2-2.0.12/src/video/cocoa/SDL_cocoamouse.h rename to SDL2-2.30.5/src/video/cocoa/SDL_cocoamouse.h index cde24c8..0d5f5db 100644 --- a/SDL2-2.0.12/src/video/cocoa/SDL_cocoamouse.h +++ b/SDL2-2.30.5/src/video/cocoa/SDL_cocoamouse.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -32,7 +32,7 @@ extern void Cocoa_HandleMouseWarp(CGFloat x, CGFloat y); extern void Cocoa_QuitMouse(_THIS); typedef struct { - /* Wether we've seen a cursor warp since the last move event. */ + /* Whether we've seen a cursor warp since the last move event. */ SDL_bool seenWarp; /* What location our last cursor warp was to. */ CGFloat lastWarpX; @@ -40,7 +40,8 @@ typedef struct { /* What location we last saw the cursor move to. */ CGFloat lastMoveX; CGFloat lastMoveY; - void *tapdata; + /* If we just turned on relative mode, and should skip a single mouse motion event. */ + SDL_bool justEnabledRelative; } SDL_MouseData; @interface NSCursor (InvisibleCursor) diff --git a/SDL2-2.0.12/src/video/cocoa/SDL_cocoamouse.m b/SDL2-2.30.5/src/video/cocoa/SDL_cocoamouse.m similarity index 52% rename from SDL2-2.0.12/src/video/cocoa/SDL_cocoamouse.m rename to SDL2-2.30.5/src/video/cocoa/SDL_cocoamouse.m index 98f23cb..c14f9ab 100644 --- a/SDL2-2.0.12/src/video/cocoa/SDL_cocoamouse.m +++ b/SDL2-2.30.5/src/video/cocoa/SDL_cocoamouse.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,12 +20,10 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_COCOA +#ifdef SDL_VIDEO_DRIVER_COCOA -#include "SDL_assert.h" #include "SDL_events.h" #include "SDL_cocoamouse.h" -#include "SDL_cocoamousetap.h" #include "SDL_cocoavideo.h" #include "../../events/SDL_mouse_c.h" @@ -55,7 +53,7 @@ NSData *cursorData = [NSData dataWithBytesNoCopy:&cursorBytes[0] length:sizeof(cursorBytes) freeWhenDone:NO]; - NSImage *cursorImage = [[[NSImage alloc] initWithData:cursorData] autorelease]; + NSImage *cursorImage = [[NSImage alloc] initWithData:cursorData]; invisibleCursor = [[NSCursor alloc] initWithImage:cursorImage hotSpot:NSZeroPoint]; } @@ -65,8 +63,7 @@ @end -static SDL_Cursor * -Cocoa_CreateDefaultCursor() +static SDL_Cursor *Cocoa_CreateDefaultCursor() { @autoreleasepool { NSCursor *nscursor; @@ -77,16 +74,14 @@ Cocoa_CreateDefaultCursor() if (nscursor) { cursor = SDL_calloc(1, sizeof(*cursor)); if (cursor) { - cursor->driverdata = nscursor; - [nscursor retain]; + cursor->driverdata = (void *)CFBridgingRetain(nscursor); } } return cursor; }} -static SDL_Cursor * -Cocoa_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y) +static SDL_Cursor *Cocoa_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y) { @autoreleasepool { NSImage *nsimage; @@ -101,17 +96,54 @@ Cocoa_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y) if (nscursor) { cursor = SDL_calloc(1, sizeof(*cursor)); if (cursor) { - cursor->driverdata = nscursor; - } else { - [nscursor release]; + cursor->driverdata = (void *)CFBridgingRetain(nscursor); } } return cursor; }} -static SDL_Cursor * -Cocoa_CreateSystemCursor(SDL_SystemCursor id) +/* there are .pdf files of some of the cursors we need, installed by default on macOS, but not available through NSCursor. + If we can load them ourselves, use them, otherwise fallback to something standard but not super-great. + Since these are under /System, they should be available even to sandboxed apps. */ +static NSCursor *LoadHiddenSystemCursor(NSString *cursorName, SEL fallback) +{ + NSString *cursorPath = [@"/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/HIServices.framework/Versions/A/Resources/cursors" stringByAppendingPathComponent:cursorName]; + NSDictionary *info = [NSDictionary dictionaryWithContentsOfFile:[cursorPath stringByAppendingPathComponent:@"info.plist"]]; + /* we can't do animation atm. :/ */ + const int frames = (int)[[info valueForKey:@"frames"] integerValue]; + NSCursor *cursor; + NSImage *image = [[NSImage alloc] initWithContentsOfFile:[cursorPath stringByAppendingPathComponent:@"cursor.pdf"]]; + if ((image == nil) || (image.isValid == NO)) { + return [NSCursor performSelector:fallback]; + } + + if (frames > 1) { + #ifdef MAC_OS_VERSION_12_0 /* same value as deprecated symbol. */ + const NSCompositingOperation operation = NSCompositingOperationCopy; + #else + const NSCompositingOperation operation = NSCompositeCopy; + #endif + const NSSize cropped_size = NSMakeSize(image.size.width, (int) (image.size.height / frames)); + NSImage *cropped = [[NSImage alloc] initWithSize:cropped_size]; + if (cropped == nil) { + return [NSCursor performSelector:fallback]; + } + + [cropped lockFocus]; + { + const NSRect cropped_rect = NSMakeRect(0, 0, cropped_size.width, cropped_size.height); + [image drawInRect:cropped_rect fromRect:cropped_rect operation:operation fraction:1]; + } + [cropped unlockFocus]; + image = cropped; + } + + cursor = [[NSCursor alloc] initWithImage:image hotSpot:NSMakePoint([[info valueForKey:@"hotx"] doubleValue], [[info valueForKey:@"hoty"] doubleValue])]; + return cursor; +} + +static SDL_Cursor *Cocoa_CreateSystemCursor(SDL_SystemCursor id) { @autoreleasepool { NSCursor *nscursor = NULL; @@ -124,27 +156,29 @@ Cocoa_CreateSystemCursor(SDL_SystemCursor id) case SDL_SYSTEM_CURSOR_IBEAM: nscursor = [NSCursor IBeamCursor]; break; - case SDL_SYSTEM_CURSOR_WAIT: - nscursor = [NSCursor arrowCursor]; - break; case SDL_SYSTEM_CURSOR_CROSSHAIR: nscursor = [NSCursor crosshairCursor]; break; - case SDL_SYSTEM_CURSOR_WAITARROW: - nscursor = [NSCursor arrowCursor]; + case SDL_SYSTEM_CURSOR_WAIT: /* !!! FIXME: this is more like WAITARROW */ + nscursor = LoadHiddenSystemCursor(@"busybutclickable", @selector(arrowCursor)); + break; + case SDL_SYSTEM_CURSOR_WAITARROW: /* !!! FIXME: this is meant to be animated */ + nscursor = LoadHiddenSystemCursor(@"busybutclickable", @selector(arrowCursor)); break; case SDL_SYSTEM_CURSOR_SIZENWSE: + nscursor = LoadHiddenSystemCursor(@"resizenorthwestsoutheast", @selector(closedHandCursor)); + break; case SDL_SYSTEM_CURSOR_SIZENESW: - nscursor = [NSCursor closedHandCursor]; + nscursor = LoadHiddenSystemCursor(@"resizenortheastsouthwest", @selector(closedHandCursor)); break; case SDL_SYSTEM_CURSOR_SIZEWE: - nscursor = [NSCursor resizeLeftRightCursor]; + nscursor = LoadHiddenSystemCursor(@"resizeeastwest", @selector(resizeLeftRightCursor)); break; case SDL_SYSTEM_CURSOR_SIZENS: - nscursor = [NSCursor resizeUpDownCursor]; + nscursor = LoadHiddenSystemCursor(@"resizenorthsouth", @selector(resizeUpDownCursor)); break; case SDL_SYSTEM_CURSOR_SIZEALL: - nscursor = [NSCursor closedHandCursor]; + nscursor = LoadHiddenSystemCursor(@"move", @selector(closedHandCursor)); break; case SDL_SYSTEM_CURSOR_NO: nscursor = [NSCursor operationNotAllowedCursor]; @@ -161,43 +195,37 @@ Cocoa_CreateSystemCursor(SDL_SystemCursor id) cursor = SDL_calloc(1, sizeof(*cursor)); if (cursor) { /* We'll free it later, so retain it here */ - [nscursor retain]; - cursor->driverdata = nscursor; + cursor->driverdata = (void *)CFBridgingRetain(nscursor); } } return cursor; }} -static void -Cocoa_FreeCursor(SDL_Cursor * cursor) +static void Cocoa_FreeCursor(SDL_Cursor * cursor) { @autoreleasepool { - NSCursor *nscursor = (NSCursor *)cursor->driverdata; - - [nscursor release]; + CFBridgingRelease(cursor->driverdata); SDL_free(cursor); }} -static int -Cocoa_ShowCursor(SDL_Cursor * cursor) +static int Cocoa_ShowCursor(SDL_Cursor * cursor) { @autoreleasepool { SDL_VideoDevice *device = SDL_GetVideoDevice(); SDL_Window *window = (device ? device->windows : NULL); for (; window != NULL; window = window->next) { - SDL_WindowData *driverdata = (SDL_WindowData *)window->driverdata; + SDL_WindowData *driverdata = (__bridge SDL_WindowData *)window->driverdata; if (driverdata) { - [driverdata->nswindow performSelectorOnMainThread:@selector(invalidateCursorRectsForView:) - withObject:[driverdata->nswindow contentView] - waitUntilDone:NO]; + [driverdata.nswindow performSelectorOnMainThread:@selector(invalidateCursorRectsForView:) + withObject:[driverdata.nswindow contentView] + waitUntilDone:NO]; } } return 0; }} -static SDL_Window * -SDL_FindWindowAtPoint(const int x, const int y) +static SDL_Window *SDL_FindWindowAtPoint(const int x, const int y) { const SDL_Point pt = { x, y }; SDL_Window *i; @@ -211,19 +239,19 @@ SDL_FindWindowAtPoint(const int x, const int y) return NULL; } -static int -Cocoa_WarpMouseGlobal(int x, int y) +static int Cocoa_WarpMouseGlobal(int x, int y) { + CGPoint point; SDL_Mouse *mouse = SDL_GetMouse(); if (mouse->focus) { - SDL_WindowData *data = (SDL_WindowData *) mouse->focus->driverdata; - if ([data->listener isMoving]) { - DLog("Postponing warp, window being moved."); - [data->listener setPendingMoveX:x Y:y]; + SDL_WindowData *data = (__bridge SDL_WindowData *) mouse->focus->driverdata; + if ([data.listener isMovingOrFocusClickPending]) { + DLog("Postponing warp, window being moved or focused."); + [data.listener setPendingMoveX:x Y:y]; return 0; } } - const CGPoint point = CGPointMake((float)x, (float)y); + point = CGPointMake((float)x, (float)y); Cocoa_HandleMouseWarp(point.x, point.y); @@ -252,33 +280,26 @@ Cocoa_WarpMouseGlobal(int x, int y) return 0; } -static void -Cocoa_WarpMouse(SDL_Window * window, int x, int y) +static void Cocoa_WarpMouse(SDL_Window * window, int x, int y) { - Cocoa_WarpMouseGlobal(x + window->x, y + window->y); + Cocoa_WarpMouseGlobal(window->x + x, window->y + y); } -static int -Cocoa_SetRelativeMouseMode(SDL_bool enabled) +static int Cocoa_SetRelativeMouseMode(SDL_bool enabled) { - /* We will re-apply the relative mode when the window gets focus, if it - * doesn't have focus right now. - */ - SDL_Window *window = SDL_GetMouseFocus(); - if (!window) { - return 0; - } - - /* We will re-apply the relative mode when the window finishes being moved, - * if it is being moved right now. - */ - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - if ([data->listener isMoving]) { - return 0; - } - + SDL_Window *window = SDL_GetKeyboardFocus(); CGError result; + SDL_WindowData *data; if (enabled) { + if (window) { + /* make sure the mouse isn't at the corner of the window, as this can confuse things if macOS thinks a window resize is happening on the first click. */ + SDL_MouseData *mousedriverdata = (SDL_MouseData*)SDL_GetMouse()->driverdata; + const CGPoint point = CGPointMake((float)(window->x + (window->w / 2)), (float)(window->y + (window->h / 2))); + if (mousedriverdata) { + mousedriverdata->justEnabledRelative = SDL_TRUE; + } + CGWarpMouseCursorPosition(point); + } DLog("Turning on."); result = CGAssociateMouseAndMouseCursorPosition(NO); } else { @@ -289,6 +310,21 @@ Cocoa_SetRelativeMouseMode(SDL_bool enabled) return SDL_SetError("CGAssociateMouseAndMouseCursorPosition() failed"); } + /* We will re-apply the non-relative mode when the window gets focus, if it + * doesn't have focus right now. + */ + if (!window) { + return 0; + } + + /* We will re-apply the non-relative mode when the window finishes being moved, + * if it is being moved right now. + */ + data = (__bridge SDL_WindowData *) window->driverdata; + if ([data.listener isMovingOrFocusClickPending]) { + return 0; + } + /* The hide/unhide calls are redundant most of the time, but they fix * https://bugzilla.libsdl.org/show_bug.cgi?id=2550 */ @@ -300,16 +336,14 @@ Cocoa_SetRelativeMouseMode(SDL_bool enabled) return 0; } -static int -Cocoa_CaptureMouse(SDL_Window *window) +static int Cocoa_CaptureMouse(SDL_Window *window) { /* our Cocoa event code already tracks the mouse outside the window, so all we have to do here is say "okay" and do what we always do. */ return 0; } -static Uint32 -Cocoa_GetGlobalMouseState(int *x, int *y) +static Uint32 Cocoa_GetGlobalMouseState(int *x, int *y) { const NSUInteger cocoaButtons = [NSEvent pressedMouseButtons]; const NSPoint cocoaLocation = [NSEvent mouseLocation]; @@ -327,9 +361,9 @@ Cocoa_GetGlobalMouseState(int *x, int *y) return retval; } -int -Cocoa_InitMouse(_THIS) +int Cocoa_InitMouse(_THIS) { + NSPoint location; SDL_Mouse *mouse = SDL_GetMouse(); SDL_MouseData *driverdata = (SDL_MouseData*) SDL_calloc(1, sizeof(SDL_MouseData)); if (driverdata == NULL) { @@ -349,17 +383,54 @@ Cocoa_InitMouse(_THIS) SDL_SetDefaultCursor(Cocoa_CreateDefaultCursor()); - Cocoa_InitMouseEventTap(driverdata); - - const NSPoint location = [NSEvent mouseLocation]; + location = [NSEvent mouseLocation]; driverdata->lastMoveX = location.x; driverdata->lastMoveY = location.y; return 0; } -void -Cocoa_HandleMouseEvent(_THIS, NSEvent *event) +static void Cocoa_HandleTitleButtonEvent(_THIS, NSEvent *event) { + SDL_Window *window; + NSWindow *nswindow = [event window]; + + /* You might land in this function before SDL_Init if showing a message box. + Don't derefence a NULL pointer if that happens. */ + if (_this == NULL) { + return; + } + + for (window = _this->windows; window; window = window->next) { + SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata; + if (data && data.nswindow == nswindow) { + switch ([event type]) { + case NSEventTypeLeftMouseDown: + case NSEventTypeRightMouseDown: + case NSEventTypeOtherMouseDown: + [data.listener setFocusClickPending:[event buttonNumber]]; + break; + case NSEventTypeLeftMouseUp: + case NSEventTypeRightMouseUp: + case NSEventTypeOtherMouseUp: + [data.listener clearFocusClickPending:[event buttonNumber]]; + break; + default: + break; + } + break; + } + } +} + +void Cocoa_HandleMouseEvent(_THIS, NSEvent *event) +{ + SDL_Mouse *mouse; + SDL_MouseData *driverdata; + SDL_MouseID mouseID; + NSPoint location; + CGFloat lastMoveX, lastMoveY; + float deltaX, deltaY; + SDL_bool seenWarp; switch ([event type]) { case NSEventTypeMouseMoved: case NSEventTypeLeftMouseDragged: @@ -367,24 +438,44 @@ Cocoa_HandleMouseEvent(_THIS, NSEvent *event) case NSEventTypeOtherMouseDragged: break; + case NSEventTypeLeftMouseDown: + case NSEventTypeLeftMouseUp: + case NSEventTypeRightMouseDown: + case NSEventTypeRightMouseUp: + case NSEventTypeOtherMouseDown: + case NSEventTypeOtherMouseUp: + if ([event window]) { + NSRect windowRect = [[[event window] contentView] frame]; + if (!NSMouseInRect([event locationInWindow], windowRect, NO)) { + Cocoa_HandleTitleButtonEvent(_this, event); + return; + } + } + return; + default: /* Ignore any other events. */ return; } - SDL_Mouse *mouse = SDL_GetMouse(); - SDL_MouseData *driverdata = (SDL_MouseData*)mouse->driverdata; + mouse = SDL_GetMouse(); + driverdata = (SDL_MouseData*)mouse->driverdata; if (!driverdata) { return; /* can happen when returning from fullscreen Space on shutdown */ } - SDL_MouseID mouseID = mouse ? mouse->mouseID : 0; - const SDL_bool seenWarp = driverdata->seenWarp; + mouseID = mouse ? mouse->mouseID : 0; + seenWarp = driverdata->seenWarp; driverdata->seenWarp = NO; - const NSPoint location = [NSEvent mouseLocation]; - const CGFloat lastMoveX = driverdata->lastMoveX; - const CGFloat lastMoveY = driverdata->lastMoveY; + if (driverdata->justEnabledRelative) { + driverdata->justEnabledRelative = SDL_FALSE; + return; // dump the first event back. + } + + location = [NSEvent mouseLocation]; + lastMoveX = driverdata->lastMoveX; + lastMoveY = driverdata->lastMoveY; driverdata->lastMoveX = location.x; driverdata->lastMoveY = location.y; DLog("Last seen mouse: (%g, %g)", location.x, location.y); @@ -402,8 +493,8 @@ Cocoa_HandleMouseEvent(_THIS, NSEvent *event) } } - float deltaX = [event deltaX]; - float deltaY = [event deltaY]; + deltaX = [event deltaX]; + deltaY = [event deltaY]; if (seenWarp) { deltaX += (lastMoveX - driverdata->lastWarpX); @@ -415,41 +506,44 @@ Cocoa_HandleMouseEvent(_THIS, NSEvent *event) SDL_SendMouseMotion(mouse->focus, mouseID, 1, (int)deltaX, (int)deltaY); } -void -Cocoa_HandleMouseWheel(SDL_Window *window, NSEvent *event) +void Cocoa_HandleMouseWheel(SDL_Window *window, NSEvent *event) { + SDL_MouseID mouseID; + SDL_MouseWheelDirection direction; + CGFloat x, y; SDL_Mouse *mouse = SDL_GetMouse(); if (!mouse) { return; } - SDL_MouseID mouseID = mouse->mouseID; - CGFloat x = -[event deltaX]; - CGFloat y = [event deltaY]; - SDL_MouseWheelDirection direction = SDL_MOUSEWHEEL_NORMAL; + mouseID = mouse->mouseID; + x = -[event deltaX]; + y = [event deltaY]; + direction = SDL_MOUSEWHEEL_NORMAL; - if ([event respondsToSelector:@selector(isDirectionInvertedFromDevice)]) { - if ([event isDirectionInvertedFromDevice] == YES) { - direction = SDL_MOUSEWHEEL_FLIPPED; + if ([event isDirectionInvertedFromDevice] == YES) { + direction = SDL_MOUSEWHEEL_FLIPPED; + } + + /* For discrete scroll events from conventional mice, always send a full tick. + For continuous scroll events from trackpads, send fractional deltas for smoother scrolling. */ + if (![event hasPreciseScrollingDeltas]) { + if (x > 0) { + x = SDL_ceil(x); + } else if (x < 0) { + x = SDL_floor(x); + } + if (y > 0) { + y = SDL_ceil(y); + } else if (y < 0) { + y = SDL_floor(y); } - } - - if (x > 0) { - x = SDL_ceil(x); - } else if (x < 0) { - x = SDL_floor(x); - } - if (y > 0) { - y = SDL_ceil(y); - } else if (y < 0) { - y = SDL_floor(y); } SDL_SendMouseWheel(window, mouseID, x, y, direction); } -void -Cocoa_HandleMouseWarp(CGFloat x, CGFloat y) +void Cocoa_HandleMouseWarp(CGFloat x, CGFloat y) { /* This makes Cocoa_HandleMouseEvent ignore the delta caused by the warp, * since it gets included in the next movement event. @@ -462,14 +556,11 @@ Cocoa_HandleMouseWarp(CGFloat x, CGFloat y) DLog("(%g, %g)", x, y); } -void -Cocoa_QuitMouse(_THIS) +void Cocoa_QuitMouse(_THIS) { SDL_Mouse *mouse = SDL_GetMouse(); if (mouse) { if (mouse->driverdata) { - Cocoa_QuitMouseEventTap(((SDL_MouseData*)mouse->driverdata)); - SDL_free(mouse->driverdata); mouse->driverdata = NULL; } diff --git a/SDL2-2.0.12/src/video/cocoa/SDL_cocoaopengl.h b/SDL2-2.30.5/src/video/cocoa/SDL_cocoaopengl.h similarity index 80% rename from SDL2-2.0.12/src/video/cocoa/SDL_cocoaopengl.h rename to SDL2-2.30.5/src/video/cocoa/SDL_cocoaopengl.h index 5debd23..26462bb 100644 --- a/SDL2-2.0.12/src/video/cocoa/SDL_cocoaopengl.h +++ b/SDL2-2.30.5/src/video/cocoa/SDL_cocoaopengl.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,10 +23,11 @@ #ifndef SDL_cocoaopengl_h_ #define SDL_cocoaopengl_h_ -#if SDL_VIDEO_OPENGL_CGL +#ifdef SDL_VIDEO_OPENGL_CGL #include "SDL_atomic.h" #import +#import /* We still support OpenGL as long as Apple offers it, deprecated or not, so disable deprecation warnings about it. */ #ifdef __clang__ @@ -42,13 +43,24 @@ struct SDL_GLDriverData @interface SDLOpenGLContext : NSOpenGLContext { SDL_atomic_t dirty; SDL_Window *window; + CVDisplayLinkRef displayLink; + @public SDL_mutex *swapIntervalMutex; + @public SDL_cond *swapIntervalCond; + @public SDL_atomic_t swapIntervalSetting; + @public SDL_atomic_t swapIntervalsPassed; } - (id)initWithFormat:(NSOpenGLPixelFormat *)format shareContext:(NSOpenGLContext *)share; - (void)scheduleUpdate; - (void)updateIfNeeded; +- (void)movedToNewScreen; - (void)setWindow:(SDL_Window *)window; +- (SDL_Window*)window; +- (void)explicitUpdate; +- (void)cleanup; + +@property (retain, nonatomic) NSOpenGLPixelFormat* openglPixelFormat; // macOS 10.10 has -[NSOpenGLContext pixelFormat] but this handles older OS releases. @end @@ -59,8 +71,6 @@ extern void Cocoa_GL_UnloadLibrary(_THIS); extern SDL_GLContext Cocoa_GL_CreateContext(_THIS, SDL_Window * window); extern int Cocoa_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context); -extern void Cocoa_GL_GetDrawableSize(_THIS, SDL_Window * window, - int * w, int * h); extern int Cocoa_GL_SetSwapInterval(_THIS, int interval); extern int Cocoa_GL_GetSwapInterval(_THIS); extern int Cocoa_GL_SwapWindow(_THIS, SDL_Window * window); diff --git a/SDL2-2.0.12/src/video/cocoa/SDL_cocoaopengl.m b/SDL2-2.30.5/src/video/cocoa/SDL_cocoaopengl.m similarity index 55% rename from SDL2-2.0.12/src/video/cocoa/SDL_cocoaopengl.m rename to SDL2-2.30.5/src/video/cocoa/SDL_cocoaopengl.m index 75a63df..bda9315 100644 --- a/SDL2-2.0.12/src/video/cocoa/SDL_cocoaopengl.m +++ b/SDL2-2.30.5/src/video/cocoa/SDL_cocoaopengl.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -22,7 +22,7 @@ /* NSOpenGL implementation of SDL OpenGL support */ -#if SDL_VIDEO_OPENGL_CGL +#ifdef SDL_VIDEO_OPENGL_CGL #include "SDL_cocoavideo.h" #include "SDL_cocoaopengl.h" #include "SDL_cocoaopengles.h" @@ -31,8 +31,10 @@ #include #include +#include "SDL_hints.h" #include "SDL_loadso.h" #include "SDL_opengl.h" +#include "../../SDL_hints_c.h" #define DEFAULT_OPENGL "/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib" @@ -42,6 +44,40 @@ #pragma clang diagnostic ignored "-Wdeprecated-declarations" #endif +/* _Nullable is available starting Xcode 7 */ +#ifdef __has_feature +#if __has_feature(nullability) +#define HAS_FEATURE_NULLABLE +#endif +#endif +#ifndef HAS_FEATURE_NULLABLE +#define _Nullable +#endif + +static SDL_bool SDL_opengl_async_dispatch = SDL_FALSE; + +static void SDLCALL +SDL_OpenGLAsyncDispatchChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + SDL_opengl_async_dispatch = SDL_GetStringBoolean(hint, SDL_FALSE); +} + +static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp* now, const CVTimeStamp* outputTime, CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* displayLinkContext) +{ + SDLOpenGLContext *nscontext = (__bridge SDLOpenGLContext *) displayLinkContext; + + /*printf("DISPLAY LINK! %u\n", (unsigned int) SDL_GetTicks()); */ + const int setting = SDL_AtomicGet(&nscontext->swapIntervalSetting); + if (setting != 0) { /* nothing to do if vsync is disabled, don't even lock */ + SDL_LockMutex(nscontext->swapIntervalMutex); + SDL_AtomicAdd(&nscontext->swapIntervalsPassed, 1); + SDL_CondSignal(nscontext->swapIntervalCond); + SDL_UnlockMutex(nscontext->swapIntervalMutex); + } + + return kCVReturnSuccess; +} + @implementation SDLOpenGLContext : NSOpenGLContext - (id)initWithFormat:(NSOpenGLPixelFormat *)format @@ -49,12 +85,35 @@ { self = [super initWithFormat:format shareContext:share]; if (self) { + self.openglPixelFormat = format; SDL_AtomicSet(&self->dirty, 0); self->window = NULL; + SDL_AtomicSet(&self->swapIntervalSetting, 0); + SDL_AtomicSet(&self->swapIntervalsPassed, 0); + self->swapIntervalCond = SDL_CreateCond(); + self->swapIntervalMutex = SDL_CreateMutex(); + if (!self->swapIntervalCond || !self->swapIntervalMutex) { + return nil; + } + + /* !!! FIXME: check return values. */ + CVDisplayLinkCreateWithActiveCGDisplays(&self->displayLink); + CVDisplayLinkSetOutputCallback(self->displayLink, &DisplayLinkCallback, (__bridge void * _Nullable) self); + CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(self->displayLink, [self CGLContextObj], [format CGLPixelFormatObj]); + CVDisplayLinkStart(displayLink); } + + SDL_AddHintCallback(SDL_HINT_MAC_OPENGL_ASYNC_DISPATCH, SDL_OpenGLAsyncDispatchChanged, NULL); return self; } +- (void)movedToNewScreen +{ + if (self->displayLink) { + CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(self->displayLink, [self CGLContextObj], [[self openglPixelFormat] CGLPixelFormatObj]); + } +} + - (void)scheduleUpdate { SDL_AtomicAdd(&self->dirty, 1); @@ -63,10 +122,10 @@ /* This should only be called on the thread on which a user is using the context. */ - (void)updateIfNeeded { - int value = SDL_AtomicSet(&self->dirty, 0); + const int value = SDL_AtomicSet(&self->dirty, 0); if (value > 0) { /* We call the real underlying update here, since -[SDLOpenGLContext update] just calls us. */ - [super update]; + [self explicitUpdate]; } } @@ -82,10 +141,10 @@ - (void)setWindow:(SDL_Window *)newWindow { if (self->window) { - SDL_WindowData *oldwindowdata = (SDL_WindowData *)self->window->driverdata; + SDL_WindowData *oldwindowdata = (__bridge SDL_WindowData *)self->window->driverdata; /* Make sure to remove us from the old window's context list, or we'll get scheduled updates from it too. */ - NSMutableArray *contexts = oldwindowdata->nscontexts; + NSMutableArray *contexts = oldwindowdata.nscontexts; @synchronized (contexts) { [contexts removeObject:self]; } @@ -94,49 +153,77 @@ self->window = newWindow; if (newWindow) { - SDL_WindowData *windowdata = (SDL_WindowData *)newWindow->driverdata; - NSView *contentview = windowdata->sdlContentView; - - /* This should never be nil since sdlContentView is only nil if the - window was created via SDL_CreateWindowFrom, and SDL doesn't allow - OpenGL contexts to be created in that case. However, it doesn't hurt - to check. */ - if (contentview == nil) { - /* Prefer to access the cached content view above instead of this, - since as of Xcode 11 + SDK 10.15, [window contentView] causes - Apple's Main Thread Checker to output a warning. */ - contentview = [windowdata->nswindow contentView]; - } + SDL_WindowData *windowdata = (__bridge SDL_WindowData *)newWindow->driverdata; + NSView *contentview = windowdata.sdlContentView; /* Now sign up for scheduled updates for the new window. */ - NSMutableArray *contexts = windowdata->nscontexts; + NSMutableArray *contexts = windowdata.nscontexts; @synchronized (contexts) { [contexts addObject:self]; } if ([self view] != contentview) { - [self setView:contentview]; + if ([NSThread isMainThread]) { + [self setView:contentview]; + } else { + dispatch_sync(dispatch_get_main_queue(), ^{ [self setView:contentview]; }); + } if (self == [NSOpenGLContext currentContext]) { - [self update]; + [self explicitUpdate]; } else { [self scheduleUpdate]; } } } else { - [self clearDrawable]; - if (self == [NSOpenGLContext currentContext]) { - [self update]; + if ([NSThread isMainThread]) { + [self setView:nil]; } else { - [self scheduleUpdate]; + dispatch_sync(dispatch_get_main_queue(), ^{ [self setView:nil]; }); } } } +- (SDL_Window*)window +{ + return self->window; +} + +- (void)explicitUpdate +{ + if ([NSThread isMainThread]) { + [super update]; + } else { + if (SDL_opengl_async_dispatch) { + dispatch_async(dispatch_get_main_queue(), ^{ [super update]; }); + } else { + dispatch_sync(dispatch_get_main_queue(), ^{ [super update]; }); + } + } +} + +- (void)cleanup +{ + [self setWindow:NULL]; + + SDL_DelHintCallback(SDL_HINT_MAC_OPENGL_ASYNC_DISPATCH, SDL_OpenGLAsyncDispatchChanged, NULL); + if (self->displayLink) { + CVDisplayLinkRelease(self->displayLink); + self->displayLink = nil; + } + if (self->swapIntervalCond) { + SDL_DestroyCond(self->swapIntervalCond); + self->swapIntervalCond = NULL; + } + if (self->swapIntervalMutex) { + SDL_DestroyMutex(self->swapIntervalMutex); + self->swapIntervalMutex = NULL; + } +} + @end -int -Cocoa_GL_LoadLibrary(_THIS, const char *path) +int Cocoa_GL_LoadLibrary(_THIS, const char *path) { /* Load the OpenGL library */ if (path == NULL) { @@ -154,37 +241,36 @@ Cocoa_GL_LoadLibrary(_THIS, const char *path) return 0; } -void * -Cocoa_GL_GetProcAddress(_THIS, const char *proc) +void *Cocoa_GL_GetProcAddress(_THIS, const char *proc) { return SDL_LoadFunction(_this->gl_config.dll_handle, proc); } -void -Cocoa_GL_UnloadLibrary(_THIS) +void Cocoa_GL_UnloadLibrary(_THIS) { SDL_UnloadObject(_this->gl_config.dll_handle); _this->gl_config.dll_handle = NULL; } -SDL_GLContext -Cocoa_GL_CreateContext(_THIS, SDL_Window * window) +SDL_GLContext Cocoa_GL_CreateContext(_THIS, SDL_Window * window) { @autoreleasepool { SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); SDL_DisplayData *displaydata = (SDL_DisplayData *)display->driverdata; - SDL_bool lion_or_later = floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6; NSOpenGLPixelFormatAttribute attr[32]; NSOpenGLPixelFormat *fmt; SDLOpenGLContext *context; + SDL_GLContext sdlcontext; NSOpenGLContext *share_context = nil; int i = 0; const char *glversion; int glversion_major; int glversion_minor; + NSOpenGLPixelFormatAttribute profile; + int interval; if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) { -#if SDL_VIDEO_OPENGL_EGL +#ifdef SDL_VIDEO_OPENGL_EGL /* Switch to EGL based functions */ Cocoa_GL_UnloadLibrary(_this); _this->GL_LoadLibrary = Cocoa_GLES_LoadLibrary; @@ -196,7 +282,7 @@ Cocoa_GL_CreateContext(_THIS, SDL_Window * window) _this->GL_GetSwapInterval = Cocoa_GLES_GetSwapInterval; _this->GL_SwapWindow = Cocoa_GLES_SwapWindow; _this->GL_DeleteContext = Cocoa_GLES_DeleteContext; - + if (Cocoa_GLES_LoadLibrary(_this, NULL) != 0) { return NULL; } @@ -206,22 +292,15 @@ Cocoa_GL_CreateContext(_THIS, SDL_Window * window) return NULL; #endif } - if ((_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_CORE) && !lion_or_later) { - SDL_SetError ("OpenGL Core Profile is not supported on this platform version"); - return NULL; - } attr[i++] = NSOpenGLPFAAllowOfflineRenderers; - /* specify a profile if we're on Lion (10.7) or later. */ - if (lion_or_later) { - NSOpenGLPixelFormatAttribute profile = NSOpenGLProfileVersionLegacy; - if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_CORE) { - profile = NSOpenGLProfileVersion3_2Core; - } - attr[i++] = NSOpenGLPFAOpenGLProfile; - attr[i++] = profile; + profile = NSOpenGLProfileVersionLegacy; + if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_CORE) { + profile = NSOpenGLProfileVersion3_2Core; } + attr[i++] = NSOpenGLPFAOpenGLProfile; + attr[i++] = profile; attr[i++] = NSOpenGLPFAColorSize; attr[i++] = SDL_BYTESPERPIXEL(display->current_mode.format)*8; @@ -260,6 +339,9 @@ Cocoa_GL_CreateContext(_THIS, SDL_Window * window) attr[i++] = _this->gl_config.multisamplesamples; attr[i++] = NSOpenGLPFANoRecovery; } + if (_this->gl_config.floatbuffers) { + attr[i++] = NSOpenGLPFAColorFloat; + } if (_this->gl_config.accelerated >= 0) { if (_this->gl_config.accelerated) { @@ -281,20 +363,24 @@ Cocoa_GL_CreateContext(_THIS, SDL_Window * window) } if (_this->gl_config.share_with_current_context) { - share_context = (NSOpenGLContext*)SDL_GL_GetCurrentContext(); + share_context = (__bridge NSOpenGLContext*)SDL_GL_GetCurrentContext(); } context = [[SDLOpenGLContext alloc] initWithFormat:fmt shareContext:share_context]; - [fmt release]; - if (context == nil) { SDL_SetError("Failed creating OpenGL context"); return NULL; } - if ( Cocoa_GL_MakeCurrent(_this, window, context) < 0 ) { - Cocoa_GL_DeleteContext(_this, context); + sdlcontext = (SDL_GLContext)CFBridgingRetain(context); + + /* vsync is handled separately by synchronizing with a display link. */ + interval = 0; + [context setValues:&interval forParameter:NSOpenGLCPSwapInterval]; + + if (Cocoa_GL_MakeCurrent(_this, window, sdlcontext) < 0) { + SDL_GL_DeleteContext(sdlcontext); SDL_SetError("Failed making OpenGL context current"); return NULL; } @@ -308,27 +394,27 @@ Cocoa_GL_CreateContext(_THIS, SDL_Window * window) glGetStringFunc = (const GLubyte *(APIENTRY *)(GLenum)) SDL_GL_GetProcAddress("glGetString"); if (!glGetStringFunc) { - Cocoa_GL_DeleteContext(_this, context); + SDL_GL_DeleteContext(sdlcontext); SDL_SetError ("Failed getting OpenGL glGetString entry point"); return NULL; } glversion = (const char *)glGetStringFunc(GL_VERSION); if (glversion == NULL) { - Cocoa_GL_DeleteContext(_this, context); + SDL_GL_DeleteContext(sdlcontext); SDL_SetError ("Failed getting OpenGL context version"); return NULL; } if (SDL_sscanf(glversion, "%d.%d", &glversion_major, &glversion_minor) != 2) { - Cocoa_GL_DeleteContext(_this, context); + SDL_GL_DeleteContext(sdlcontext); SDL_SetError ("Failed parsing OpenGL context version"); return NULL; } if ((glversion_major < _this->gl_config.major_version) || ((glversion_major == _this->gl_config.major_version) && (glversion_minor < _this->gl_config.minor_version))) { - Cocoa_GL_DeleteContext(_this, context); + SDL_GL_DeleteContext(sdlcontext); SDL_SetError ("Failed creating OpenGL context at version requested"); return NULL; } @@ -339,17 +425,18 @@ Cocoa_GL_CreateContext(_THIS, SDL_Window * window) /*_this->gl_config.major_version = glversion_major;*/ /*_this->gl_config.minor_version = glversion_minor;*/ } - return context; + return sdlcontext; }} -int -Cocoa_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) +int Cocoa_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) { @autoreleasepool { if (context) { - SDLOpenGLContext *nscontext = (SDLOpenGLContext *)context; - [nscontext setWindow:window]; - [nscontext updateIfNeeded]; + SDLOpenGLContext *nscontext = (__bridge SDLOpenGLContext *)context; + if ([nscontext window] != window) { + [nscontext setWindow:window]; + [nscontext updateIfNeeded]; + } [nscontext makeCurrentContext]; } else { [NSOpenGLContext clearCurrentContext]; @@ -358,95 +445,74 @@ Cocoa_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) return 0; }} -void -Cocoa_GL_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h) -{ - SDL_WindowData *windata = (SDL_WindowData *) window->driverdata; - NSView *contentView = [windata->nswindow contentView]; - NSRect viewport = [contentView bounds]; - - if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) { - /* This gives us the correct viewport for a Retina-enabled view, only - * supported on 10.7+. */ - if ([contentView respondsToSelector:@selector(convertRectToBacking:)]) { - viewport = [contentView convertRectToBacking:viewport]; - } - } - - if (w) { - *w = viewport.size.width; - } - - if (h) { - *h = viewport.size.height; - } -} - -int -Cocoa_GL_SetSwapInterval(_THIS, int interval) +int Cocoa_GL_SetSwapInterval(_THIS, int interval) { @autoreleasepool { - NSOpenGLContext *nscontext; - GLint value; + SDLOpenGLContext *nscontext = (__bridge SDLOpenGLContext *) SDL_GL_GetCurrentContext(); int status; - if (interval < 0) { /* no extension for this on Mac OS X at the moment. */ - return SDL_SetError("Late swap tearing currently unsupported"); - } - - nscontext = (NSOpenGLContext*)SDL_GL_GetCurrentContext(); - if (nscontext != nil) { - value = interval; - [nscontext setValues:&value forParameter:NSOpenGLCPSwapInterval]; - status = 0; - } else { + if (nscontext == nil) { status = SDL_SetError("No current OpenGL context"); + } else { + SDL_LockMutex(nscontext->swapIntervalMutex); + SDL_AtomicSet(&nscontext->swapIntervalsPassed, 0); + SDL_AtomicSet(&nscontext->swapIntervalSetting, interval); + SDL_UnlockMutex(nscontext->swapIntervalMutex); + status = 0; } return status; }} -int -Cocoa_GL_GetSwapInterval(_THIS) +int Cocoa_GL_GetSwapInterval(_THIS) { @autoreleasepool { - NSOpenGLContext *nscontext; - GLint value; - int status = 0; - - nscontext = (NSOpenGLContext*)SDL_GL_GetCurrentContext(); - if (nscontext != nil) { - [nscontext getValues:&value forParameter:NSOpenGLCPSwapInterval]; - status = (int)value; - } - - return status; + SDLOpenGLContext* nscontext = (__bridge SDLOpenGLContext*)SDL_GL_GetCurrentContext(); + return nscontext ? SDL_AtomicGet(&nscontext->swapIntervalSetting) : 0; }} -int -Cocoa_GL_SwapWindow(_THIS, SDL_Window * window) +int Cocoa_GL_SwapWindow(_THIS, SDL_Window * window) { @autoreleasepool { - SDLOpenGLContext* nscontext = (SDLOpenGLContext*)SDL_GL_GetCurrentContext(); - SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; + SDLOpenGLContext* nscontext = (__bridge SDLOpenGLContext*)SDL_GL_GetCurrentContext(); + SDL_VideoData *videodata = (__bridge SDL_VideoData *) _this->driverdata; + const int setting = SDL_AtomicGet(&nscontext->swapIntervalSetting); + + if (setting == 0) { + /* nothing to do if vsync is disabled, don't even lock */ + } else if (setting < 0) { /* late swap tearing */ + SDL_LockMutex(nscontext->swapIntervalMutex); + while (SDL_AtomicGet(&nscontext->swapIntervalsPassed) == 0) { + SDL_CondWait(nscontext->swapIntervalCond, nscontext->swapIntervalMutex); + } + SDL_AtomicSet(&nscontext->swapIntervalsPassed, 0); + SDL_UnlockMutex(nscontext->swapIntervalMutex); + } else { + SDL_LockMutex(nscontext->swapIntervalMutex); + do { /* always wait here so we know we just hit a swap interval. */ + SDL_CondWait(nscontext->swapIntervalCond, nscontext->swapIntervalMutex); + } while ((SDL_AtomicGet(&nscontext->swapIntervalsPassed) % setting) != 0); + SDL_AtomicSet(&nscontext->swapIntervalsPassed, 0); + SDL_UnlockMutex(nscontext->swapIntervalMutex); + } + + /*{ static Uint64 prev = 0; const Uint64 now = SDL_GetTicks64(); const unsigned int diff = (unsigned int) (now - prev); prev = now; printf("GLSWAPBUFFERS TICKS %u\n", diff); }*/ /* on 10.14 ("Mojave") and later, this deadlocks if two contexts in two threads try to swap at the same time, so put a mutex around it. */ - SDL_LockMutex(videodata->swaplock); + SDL_LockMutex(videodata.swaplock); [nscontext flushBuffer]; [nscontext updateIfNeeded]; - SDL_UnlockMutex(videodata->swaplock); + SDL_UnlockMutex(videodata.swaplock); return 0; }} -void -Cocoa_GL_DeleteContext(_THIS, SDL_GLContext context) +void Cocoa_GL_DeleteContext(_THIS, SDL_GLContext context) { @autoreleasepool { - SDLOpenGLContext *nscontext = (SDLOpenGLContext *)context; - - [nscontext setWindow:NULL]; - [nscontext release]; + SDLOpenGLContext *nscontext = (__bridge SDLOpenGLContext *)context; + [nscontext cleanup]; + CFRelease(context); }} /* We still support OpenGL as long as Apple offers it, deprecated or not, so disable deprecation warnings about it. */ diff --git a/SDL2-2.0.12/src/video/cocoa/SDL_cocoaopengles.h b/SDL2-2.30.5/src/video/cocoa/SDL_cocoaopengles.h similarity index 95% rename from SDL2-2.0.12/src/video/cocoa/SDL_cocoaopengles.h rename to SDL2-2.30.5/src/video/cocoa/SDL_cocoaopengles.h index a079601..0729b6b 100644 --- a/SDL2-2.0.12/src/video/cocoa/SDL_cocoaopengles.h +++ b/SDL2-2.30.5/src/video/cocoa/SDL_cocoaopengles.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,7 +23,7 @@ #ifndef SDL_cocoaopengles_h_ #define SDL_cocoaopengles_h_ -#if SDL_VIDEO_OPENGL_EGL +#ifdef SDL_VIDEO_OPENGL_EGL #include "../SDL_sysvideo.h" #include "../SDL_egl_c.h" diff --git a/SDL2-2.0.12/src/video/cocoa/SDL_cocoaopengles.m b/SDL2-2.30.5/src/video/cocoa/SDL_cocoaopengles.m similarity index 67% rename from SDL2-2.0.12/src/video/cocoa/SDL_cocoaopengles.m rename to SDL2-2.30.5/src/video/cocoa/SDL_cocoaopengles.m index 326a2ee..abb2014 100644 --- a/SDL2-2.0.12/src/video/cocoa/SDL_cocoaopengles.m +++ b/SDL2-2.30.5/src/video/cocoa/SDL_cocoaopengles.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,21 +20,19 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_COCOA && SDL_VIDEO_OPENGL_EGL +#if defined(SDL_VIDEO_DRIVER_COCOA) && defined(SDL_VIDEO_OPENGL_EGL) #include "SDL_cocoavideo.h" #include "SDL_cocoaopengles.h" #include "SDL_cocoaopengl.h" -#include "SDL_log.h" /* EGL implementation of SDL OpenGL support */ -int -Cocoa_GLES_LoadLibrary(_THIS, const char *path) { - +int Cocoa_GLES_LoadLibrary(_THIS, const char *path) +{ /* If the profile requested is not GL ES, switch over to WIN_GL functions */ if (_this->gl_config.profile_mask != SDL_GL_CONTEXT_PROFILE_ES) { -#if SDL_VIDEO_OPENGL_CGL +#ifdef SDL_VIDEO_OPENGL_CGL Cocoa_GLES_UnloadLibrary(_this); _this->GL_LoadLibrary = Cocoa_GL_LoadLibrary; _this->GL_GetProcAddress = Cocoa_GL_GetProcAddress; @@ -50,7 +48,7 @@ Cocoa_GLES_LoadLibrary(_THIS, const char *path) { return SDL_SetError("SDL not configured with OpenGL/CGL support"); #endif } - + if (_this->egl_data == NULL) { return SDL_EGL_LoadLibrary(_this, NULL, EGL_DEFAULT_DISPLAY, 0); } @@ -58,13 +56,13 @@ Cocoa_GLES_LoadLibrary(_THIS, const char *path) { return 0; } -SDL_GLContext -Cocoa_GLES_CreateContext(_THIS, SDL_Window * window) +SDL_GLContext Cocoa_GLES_CreateContext(_THIS, SDL_Window * window) +{ @autoreleasepool { SDL_GLContext context; - SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata; -#if SDL_VIDEO_OPENGL_CGL +#ifdef SDL_VIDEO_OPENGL_CGL if (_this->gl_config.profile_mask != SDL_GL_CONTEXT_PROFILE_ES) { /* Switch to CGL based functions */ Cocoa_GLES_UnloadLibrary(_this); @@ -86,41 +84,54 @@ Cocoa_GLES_CreateContext(_THIS, SDL_Window * window) } #endif - context = SDL_EGL_CreateContext(_this, data->egl_surface); + context = SDL_EGL_CreateContext(_this, data.egl_surface); return context; -} +}} -void -Cocoa_GLES_DeleteContext(_THIS, SDL_GLContext context) +void Cocoa_GLES_DeleteContext(_THIS, SDL_GLContext context) +{ @autoreleasepool { SDL_EGL_DeleteContext(_this, context); - Cocoa_GLES_UnloadLibrary(_this); -} +}} -SDL_EGL_SwapWindow_impl(Cocoa) -SDL_EGL_MakeCurrent_impl(Cocoa) - -int -Cocoa_GLES_SetupWindow(_THIS, SDL_Window * window) +int Cocoa_GLES_SwapWindow(_THIS, SDL_Window * window) +{ @autoreleasepool { + return SDL_EGL_SwapBuffers(_this, ((__bridge SDL_WindowData *) window->driverdata).egl_surface); +}} + +int Cocoa_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) +{ @autoreleasepool +{ + return SDL_EGL_MakeCurrent(_this, window ? ((__bridge SDL_WindowData *) window->driverdata).egl_surface : EGL_NO_SURFACE, context); +}} + +int Cocoa_GLES_SetupWindow(_THIS, SDL_Window * window) +{ + NSView* v; /* The current context is lost in here; save it and reset it. */ - SDL_WindowData *windowdata = (SDL_WindowData *) window->driverdata; + SDL_WindowData *windowdata = (__bridge SDL_WindowData *) window->driverdata; SDL_Window *current_win = SDL_GL_GetCurrentWindow(); SDL_GLContext current_ctx = SDL_GL_GetCurrentContext(); if (_this->egl_data == NULL) { + /* !!! FIXME: commenting out this assertion is (I think) incorrect; figure out why driver_loaded is wrong for ANGLE instead. --ryan. */ + #if 0 /* When hint SDL_HINT_OPENGL_ES_DRIVER is set to "1" (e.g. for ANGLE support), _this->gl_config.driver_loaded can be 1, while the below lines function. */ + SDL_assert(!_this->gl_config.driver_loaded); + #endif if (SDL_EGL_LoadLibrary(_this, NULL, EGL_DEFAULT_DISPLAY, 0) < 0) { SDL_EGL_UnloadLibrary(_this); return -1; } + _this->gl_config.driver_loaded = 1; } - - /* Create the GLES window surface */ - NSView* v = windowdata->nswindow.contentView; - windowdata->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType)[v layer]); - if (windowdata->egl_surface == EGL_NO_SURFACE) { + /* Create the GLES window surface */ + v = windowdata.nswindow.contentView; + windowdata.egl_surface = SDL_EGL_CreateSurface(_this, (__bridge NativeWindowType)[v layer]); + + if (windowdata.egl_surface == EGL_NO_SURFACE) { return SDL_SetError("Could not create GLES window surface"); } diff --git a/SDL2-2.0.12/src/video/cocoa/SDL_cocoashape.h b/SDL2-2.30.5/src/video/cocoa/SDL_cocoashape.h similarity index 84% rename from SDL2-2.0.12/src/video/cocoa/SDL_cocoashape.h rename to SDL2-2.30.5/src/video/cocoa/SDL_cocoashape.h index 739f762..f37c2d4 100644 --- a/SDL2-2.0.12/src/video/cocoa/SDL_cocoashape.h +++ b/SDL2-2.30.5/src/video/cocoa/SDL_cocoashape.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -29,12 +29,11 @@ #include "SDL_shape.h" #include "../SDL_shape_internals.h" -typedef struct { - NSGraphicsContext* context; - SDL_bool saved; - - SDL_ShapeTree* shape; -} SDL_ShapeData; +@interface SDL_ShapeData : NSObject + @property (nonatomic) NSGraphicsContext* context; + @property (nonatomic) SDL_bool saved; + @property (nonatomic) SDL_ShapeTree* shape; +@end extern SDL_WindowShaper* Cocoa_CreateShaper(SDL_Window* window); extern int Cocoa_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shape_mode); diff --git a/SDL2-2.30.5/src/video/cocoa/SDL_cocoashape.m b/SDL2-2.30.5/src/video/cocoa/SDL_cocoashape.m new file mode 100644 index 0000000..11642de --- /dev/null +++ b/SDL2-2.30.5/src/video/cocoa/SDL_cocoashape.m @@ -0,0 +1,127 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_COCOA + +#include "SDL_cocoavideo.h" +#include "SDL_shape.h" +#include "SDL_cocoashape.h" +#include "../SDL_sysvideo.h" + +@implementation SDL_ShapeData +@end + +@interface SDL_CocoaClosure : NSObject + @property (nonatomic) NSView* view; + @property (nonatomic) NSBezierPath* path; + @property (nonatomic) SDL_Window* window; +@end + +@implementation SDL_CocoaClosure +@end + +SDL_WindowShaper *Cocoa_CreateShaper(SDL_Window* window) +{ @autoreleasepool +{ + SDL_WindowShaper* result; + SDL_ShapeData* data; + int resized_properly; + SDL_WindowData* windata = (__bridge SDL_WindowData*)window->driverdata; + + result = (SDL_WindowShaper *)SDL_malloc(sizeof(SDL_WindowShaper)); + if (!result) { + SDL_OutOfMemory(); + return NULL; + } + + [windata.nswindow setOpaque:NO]; + + [windata.nswindow setStyleMask:NSWindowStyleMaskBorderless]; + + result->window = window; + result->mode.mode = ShapeModeDefault; + result->mode.parameters.binarizationCutoff = 1; + result->userx = result->usery = 0; + window->shaper = result; + + data = [[SDL_ShapeData alloc] init]; + data.context = [windata.nswindow graphicsContext]; + data.saved = SDL_FALSE; + data.shape = NULL; + + /* TODO: There's no place to release this... */ + result->driverdata = (void*) CFBridgingRetain(data); + + resized_properly = Cocoa_ResizeWindowShape(window); + SDL_assert(resized_properly == 0); + return result; +}} + +static void ConvertRects(SDL_ShapeTree* tree, void* closure) +{ + SDL_CocoaClosure* data = (__bridge SDL_CocoaClosure*)closure; + if(tree->kind == OpaqueShape) { + NSRect rect = NSMakeRect(tree->data.shape.x, data.window->h - tree->data.shape.y, tree->data.shape.w, tree->data.shape.h); + [data.path appendBezierPathWithRect:[data.view convertRect:rect toView:nil]]; + } +} + +int Cocoa_SetWindowShape(SDL_WindowShaper *shaper, SDL_Surface *shape, SDL_WindowShapeMode *shape_mode) +{ @autoreleasepool +{ + SDL_ShapeData* data = (__bridge SDL_ShapeData*)shaper->driverdata; + SDL_WindowData* windata = (__bridge SDL_WindowData*)shaper->window->driverdata; + SDL_CocoaClosure* closure; + if(data.saved == SDL_TRUE) { + [data.context restoreGraphicsState]; + data.saved = SDL_FALSE; + } + + /*[data.context saveGraphicsState];*/ + /*data.saved = SDL_TRUE;*/ + [NSGraphicsContext setCurrentContext:data.context]; + + [[NSColor clearColor] set]; + NSRectFill([windata.sdlContentView frame]); + data.shape = SDL_CalculateShapeTree(*shape_mode, shape); + + closure = [[SDL_CocoaClosure alloc] init]; + + closure.view = windata.sdlContentView; + closure.path = [NSBezierPath bezierPath]; + closure.window = shaper->window; + SDL_TraverseShapeTree(data.shape, &ConvertRects, (__bridge void*)closure); + [closure.path addClip]; + + return 0; +}} + +int Cocoa_ResizeWindowShape(SDL_Window *window) +{ @autoreleasepool { + SDL_ShapeData* data = (__bridge SDL_ShapeData*)window->shaper->driverdata; + SDL_assert(data != NULL); + return 0; +}} + +#endif /* SDL_VIDEO_DRIVER_COCOA */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/cocoa/SDL_cocoavideo.h b/SDL2-2.30.5/src/video/cocoa/SDL_cocoavideo.h similarity index 87% rename from SDL2-2.0.12/src/video/cocoa/SDL_cocoavideo.h rename to SDL2-2.30.5/src/video/cocoa/SDL_cocoavideo.h index 75b2642..0082171 100644 --- a/SDL2-2.0.12/src/video/cocoa/SDL_cocoavideo.h +++ b/SDL2-2.30.5/src/video/cocoa/SDL_cocoavideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -97,18 +97,16 @@ DECLARE_ALERT_STYLE(Critical); @class SDLTranslatorResponder; -typedef struct SDL_VideoData -{ - int allow_spaces; - unsigned int modifierFlags; - void *key_layout; - SDLTranslatorResponder *fieldEdit; - NSInteger clipboard_count; - Uint32 screensaver_activity; - BOOL screensaver_use_iopm; - IOPMAssertionID screensaver_assertion; - SDL_mutex *swaplock; -} SDL_VideoData; +@interface SDL_VideoData : NSObject + @property (nonatomic) int allow_spaces; + @property (nonatomic) int trackpad_is_touch_only; + @property (nonatomic) unsigned int modifierFlags; + @property (nonatomic) void *key_layout; + @property (nonatomic) SDLTranslatorResponder *fieldEdit; + @property (nonatomic) NSInteger clipboard_count; + @property (nonatomic) IOPMAssertionID screensaver_assertion; + @property (nonatomic) SDL_mutex *swaplock; +@end /* Utility functions */ extern NSImage * Cocoa_CreateImage(SDL_Surface * surface); diff --git a/SDL2-2.0.12/src/video/cocoa/SDL_cocoavideo.m b/SDL2-2.30.5/src/video/cocoa/SDL_cocoavideo.m similarity index 73% rename from SDL2-2.0.12/src/video/cocoa/SDL_cocoavideo.m rename to SDL2-2.30.5/src/video/cocoa/SDL_cocoavideo.m index f51c98c..156af89 100644 --- a/SDL2-2.0.12/src/video/cocoa/SDL_cocoavideo.m +++ b/SDL2-2.30.5/src/video/cocoa/SDL_cocoavideo.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,11 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_COCOA +#ifdef SDL_VIDEO_DRIVER_COCOA + +#if !__has_feature(objc_arc) +#error SDL must be built with Objective-C ARC (automatic reference counting) enabled +#endif #include "SDL.h" #include "SDL_endian.h" @@ -28,7 +32,12 @@ #include "SDL_cocoashape.h" #include "SDL_cocoavulkan.h" #include "SDL_cocoametalview.h" -#include "SDL_assert.h" +#include "SDL_cocoaopengles.h" +#include "SDL_cocoamessagebox.h" + +@implementation SDL_VideoData + +@end /* Initialization/Query functions */ static int Cocoa_VideoInit(_THIS); @@ -36,21 +45,18 @@ static void Cocoa_VideoQuit(_THIS); /* Cocoa driver bootstrap functions */ -static int -Cocoa_Available(void) +static void Cocoa_DeleteDevice(SDL_VideoDevice * device) +{ @autoreleasepool { - return (1); -} - -static void -Cocoa_DeleteDevice(SDL_VideoDevice * device) -{ - SDL_free(device->driverdata); + if (device->wakeup_lock) { + SDL_DestroyMutex(device->wakeup_lock); + } + CFBridgingRelease(device->driverdata); SDL_free(device); -} +}} -static SDL_VideoDevice * -Cocoa_CreateDevice(int devindex) +static SDL_VideoDevice *Cocoa_CreateDevice(void) +{ @autoreleasepool { SDL_VideoDevice *device; SDL_VideoData *data; @@ -60,16 +66,17 @@ Cocoa_CreateDevice(int devindex) /* Initialize all variables that we clean on shutdown */ device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice)); if (device) { - data = (struct SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData)); + data = [[SDL_VideoData alloc] init]; } else { - data = NULL; + data = nil; } if (!data) { SDL_OutOfMemory(); SDL_free(device); return NULL; } - device->driverdata = data; + device->driverdata = (void *)CFBridgingRetain(data); + device->wakeup_lock = SDL_CreateMutex(); /* Set the function pointers */ device->VideoInit = Cocoa_VideoInit; @@ -80,6 +87,8 @@ Cocoa_CreateDevice(int devindex) device->GetDisplayModes = Cocoa_GetDisplayModes; device->SetDisplayMode = Cocoa_SetDisplayMode; device->PumpEvents = Cocoa_PumpEvents; + device->WaitEventTimeout = Cocoa_WaitEventTimeout; + device->SendWakeupEvent = Cocoa_SendWakeupEvent; device->SuspendScreenSaver = Cocoa_SuspendScreenSaver; device->CreateSDLWindow = Cocoa_CreateWindow; @@ -91,6 +100,7 @@ Cocoa_CreateDevice(int devindex) device->SetWindowMinimumSize = Cocoa_SetWindowMinimumSize; device->SetWindowMaximumSize = Cocoa_SetWindowMaximumSize; device->SetWindowOpacity = Cocoa_SetWindowOpacity; + device->GetWindowSizeInPixels = Cocoa_GetWindowSizeInPixels; device->ShowWindow = Cocoa_ShowWindow; device->HideWindow = Cocoa_HideWindow; device->RaiseWindow = Cocoa_RaiseWindow; @@ -99,31 +109,36 @@ Cocoa_CreateDevice(int devindex) device->RestoreWindow = Cocoa_RestoreWindow; device->SetWindowBordered = Cocoa_SetWindowBordered; device->SetWindowResizable = Cocoa_SetWindowResizable; + device->SetWindowAlwaysOnTop = Cocoa_SetWindowAlwaysOnTop; device->SetWindowFullscreen = Cocoa_SetWindowFullscreen; device->SetWindowGammaRamp = Cocoa_SetWindowGammaRamp; device->GetWindowGammaRamp = Cocoa_GetWindowGammaRamp; - device->SetWindowGrab = Cocoa_SetWindowGrab; + device->GetWindowICCProfile = Cocoa_GetWindowICCProfile; + device->GetWindowDisplayIndex = Cocoa_GetWindowDisplayIndex; + device->SetWindowMouseRect = Cocoa_SetWindowMouseRect; + device->SetWindowMouseGrab = Cocoa_SetWindowMouseGrab; + device->SetWindowKeyboardGrab = Cocoa_SetWindowKeyboardGrab; device->DestroyWindow = Cocoa_DestroyWindow; device->GetWindowWMInfo = Cocoa_GetWindowWMInfo; device->SetWindowHitTest = Cocoa_SetWindowHitTest; device->AcceptDragAndDrop = Cocoa_AcceptDragAndDrop; + device->FlashWindow = Cocoa_FlashWindow; device->shape_driver.CreateShaper = Cocoa_CreateShaper; device->shape_driver.SetWindowShape = Cocoa_SetWindowShape; device->shape_driver.ResizeWindowShape = Cocoa_ResizeWindowShape; -#if SDL_VIDEO_OPENGL_CGL +#ifdef SDL_VIDEO_OPENGL_CGL device->GL_LoadLibrary = Cocoa_GL_LoadLibrary; device->GL_GetProcAddress = Cocoa_GL_GetProcAddress; device->GL_UnloadLibrary = Cocoa_GL_UnloadLibrary; device->GL_CreateContext = Cocoa_GL_CreateContext; device->GL_MakeCurrent = Cocoa_GL_MakeCurrent; - device->GL_GetDrawableSize = Cocoa_GL_GetDrawableSize; device->GL_SetSwapInterval = Cocoa_GL_SetSwapInterval; device->GL_GetSwapInterval = Cocoa_GL_GetSwapInterval; device->GL_SwapWindow = Cocoa_GL_SwapWindow; device->GL_DeleteContext = Cocoa_GL_DeleteContext; -#elif SDL_VIDEO_OPENGL_EGL +#elif defined(SDL_VIDEO_OPENGL_EGL) device->GL_LoadLibrary = Cocoa_GLES_LoadLibrary; device->GL_GetProcAddress = Cocoa_GLES_GetProcAddress; device->GL_UnloadLibrary = Cocoa_GLES_UnloadLibrary; @@ -135,7 +150,7 @@ Cocoa_CreateDevice(int devindex) device->GL_DeleteContext = Cocoa_GLES_DeleteContext; #endif -#if SDL_VIDEO_VULKAN +#ifdef SDL_VIDEO_VULKAN device->Vulkan_LoadLibrary = Cocoa_Vulkan_LoadLibrary; device->Vulkan_UnloadLibrary = Cocoa_Vulkan_UnloadLibrary; device->Vulkan_GetInstanceExtensions = Cocoa_Vulkan_GetInstanceExtensions; @@ -143,9 +158,11 @@ Cocoa_CreateDevice(int devindex) device->Vulkan_GetDrawableSize = Cocoa_Vulkan_GetDrawableSize; #endif -#if SDL_VIDEO_METAL +#ifdef SDL_VIDEO_METAL device->Metal_CreateView = Cocoa_Metal_CreateView; device->Metal_DestroyView = Cocoa_Metal_DestroyView; + device->Metal_GetLayer = Cocoa_Metal_GetLayer; + device->Metal_GetDrawableSize = Cocoa_Metal_GetDrawableSize; #endif device->StartTextInput = Cocoa_StartTextInput; @@ -159,18 +176,19 @@ Cocoa_CreateDevice(int devindex) device->free = Cocoa_DeleteDevice; return device; -} +}} VideoBootStrap COCOA_bootstrap = { "cocoa", "SDL Cocoa video driver", - Cocoa_Available, Cocoa_CreateDevice + Cocoa_CreateDevice, + Cocoa_ShowMessageBox }; -int -Cocoa_VideoInit(_THIS) +int Cocoa_VideoInit(_THIS) +{ @autoreleasepool { - SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + SDL_VideoData *data = (__bridge SDL_VideoData *) _this->driverdata; Cocoa_InitModes(_this); Cocoa_InitKeyboard(_this); @@ -178,33 +196,30 @@ Cocoa_VideoInit(_THIS) return -1; } - data->allow_spaces = ((floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) && SDL_GetHintBoolean(SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES, SDL_TRUE)); + data.allow_spaces = SDL_GetHintBoolean(SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES, SDL_TRUE); + data.trackpad_is_touch_only = SDL_GetHintBoolean(SDL_HINT_TRACKPAD_IS_TOUCH_ONLY, SDL_FALSE); - /* The IOPM assertion API can disable the screensaver as of 10.7. */ - data->screensaver_use_iopm = floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6; - - data->swaplock = SDL_CreateMutex(); - if (!data->swaplock) { + data.swaplock = SDL_CreateMutex(); + if (!data.swaplock) { return -1; } return 0; -} +}} -void -Cocoa_VideoQuit(_THIS) +void Cocoa_VideoQuit(_THIS) +{ @autoreleasepool { - SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + SDL_VideoData *data = (__bridge SDL_VideoData *) _this->driverdata; Cocoa_QuitModes(_this); Cocoa_QuitKeyboard(_this); Cocoa_QuitMouse(_this); - SDL_DestroyMutex(data->swaplock); - data->swaplock = NULL; -} + SDL_DestroyMutex(data.swaplock); + data.swaplock = NULL; +}} /* This function assumes that it's called from within an autorelease pool */ -NSImage * -Cocoa_CreateImage(SDL_Surface * surface) +NSImage *Cocoa_CreateImage(SDL_Surface * surface) { SDL_Surface *converted; NSBitmapImageRep *imgrep; @@ -217,7 +232,7 @@ Cocoa_CreateImage(SDL_Surface * surface) return nil; } - imgrep = [[[NSBitmapImageRep alloc] initWithBitmapDataPlanes: NULL + imgrep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes: NULL pixelsWide: converted->w pixelsHigh: converted->h bitsPerSample: 8 @@ -226,7 +241,7 @@ Cocoa_CreateImage(SDL_Surface * surface) isPlanar: NO colorSpaceName: NSDeviceRGBColorSpace bytesPerRow: converted->pitch - bitsPerPixel: converted->format->BitsPerPixel] autorelease]; + bitsPerPixel: converted->format->BitsPerPixel]; if (imgrep == nil) { SDL_FreeSurface(converted); return nil; @@ -246,7 +261,7 @@ Cocoa_CreateImage(SDL_Surface * surface) pixels += 4; } - img = [[[NSImage alloc] initWithSize: NSMakeSize(surface->w, surface->h)] autorelease]; + img = [[NSImage alloc] initWithSize: NSMakeSize(surface->w, surface->h)]; if (img != nil) { [img addRepresentation: imgrep]; } @@ -263,9 +278,17 @@ Cocoa_CreateImage(SDL_Surface * surface) * versions remain identical! */ -void SDL_NSLog(const char *text) +void SDL_NSLog(const char *prefix, const char *text) { - NSLog(@"%s", text); + @autoreleasepool { + NSString *nsText = [NSString stringWithUTF8String:text]; + if (prefix) { + NSString *nsPrefix = [NSString stringWithUTF8String:prefix]; + NSLog(@"%@: %@", nsPrefix, nsText); + } else { + NSLog(@"%@", nsText); + } + } } #endif /* SDL_VIDEO_DRIVER_COCOA */ diff --git a/SDL2-2.0.12/src/video/cocoa/SDL_cocoavulkan.h b/SDL2-2.30.5/src/video/cocoa/SDL_cocoavulkan.h similarity index 93% rename from SDL2-2.0.12/src/video/cocoa/SDL_cocoavulkan.h rename to SDL2-2.30.5/src/video/cocoa/SDL_cocoavulkan.h index 33dc892..fc90ee1 100644 --- a/SDL2-2.0.12/src/video/cocoa/SDL_cocoavulkan.h +++ b/SDL2-2.30.5/src/video/cocoa/SDL_cocoavulkan.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -33,7 +33,7 @@ #include "../SDL_vulkan_internal.h" #include "../SDL_sysvideo.h" -#if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_COCOA +#if defined(SDL_VIDEO_VULKAN) && defined(SDL_VIDEO_DRIVER_COCOA) int Cocoa_Vulkan_LoadLibrary(_THIS, const char *path); void Cocoa_Vulkan_UnloadLibrary(_THIS); diff --git a/SDL2-2.0.12/src/video/cocoa/SDL_cocoavulkan.m b/SDL2-2.30.5/src/video/cocoa/SDL_cocoavulkan.m similarity index 75% rename from SDL2-2.0.12/src/video/cocoa/SDL_cocoavulkan.m rename to SDL2-2.30.5/src/video/cocoa/SDL_cocoavulkan.m index af41b9e..d1ea16f 100644 --- a/SDL2-2.0.12/src/video/cocoa/SDL_cocoavulkan.m +++ b/SDL2-2.30.5/src/video/cocoa/SDL_cocoavulkan.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -25,11 +25,10 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_COCOA +#if defined(SDL_VIDEO_VULKAN) && defined(SDL_VIDEO_DRIVER_COCOA) #include "SDL_cocoavideo.h" #include "SDL_cocoawindow.h" -#include "SDL_assert.h" #include "SDL_loadso.h" #include "SDL_cocoametalview.h" @@ -54,6 +53,7 @@ int Cocoa_Vulkan_LoadLibrary(_THIS, const char *path) VkExtensionProperties *extensions = NULL; Uint32 extensionCount = 0; SDL_bool hasSurfaceExtension = SDL_FALSE; + SDL_bool hasMetalSurfaceExtension = SDL_FALSE; SDL_bool hasMacOSSurfaceExtension = SDL_FALSE; PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL; @@ -131,6 +131,8 @@ int Cocoa_Vulkan_LoadLibrary(_THIS, const char *path) for (Uint32 i = 0; i < extensionCount; i++) { if (SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) { hasSurfaceExtension = SDL_TRUE; + } else if (SDL_strcmp(VK_EXT_METAL_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) { + hasMetalSurfaceExtension = SDL_TRUE; } else if (SDL_strcmp(VK_MVK_MACOS_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) { hasMacOSSurfaceExtension = SDL_TRUE; } @@ -140,9 +142,10 @@ int Cocoa_Vulkan_LoadLibrary(_THIS, const char *path) SDL_SetError("Installed Vulkan Portability library doesn't implement the " VK_KHR_SURFACE_EXTENSION_NAME " extension"); goto fail; - } else if (!hasMacOSSurfaceExtension) { + } else if (!hasMetalSurfaceExtension && !hasMacOSSurfaceExtension) { SDL_SetError("Installed Vulkan Portability library doesn't implement the " - VK_MVK_MACOS_SURFACE_EXTENSION_NAME "extension"); + VK_EXT_METAL_SURFACE_EXTENSION_NAME " or " + VK_MVK_MACOS_SURFACE_EXTENSION_NAME " extensions"); goto fail; } return 0; @@ -169,7 +172,7 @@ SDL_bool Cocoa_Vulkan_GetInstanceExtensions(_THIS, const char **names) { static const char *const extensionsForCocoa[] = { - VK_KHR_SURFACE_EXTENSION_NAME, VK_MVK_MACOS_SURFACE_EXTENSION_NAME + VK_KHR_SURFACE_EXTENSION_NAME, VK_EXT_METAL_SURFACE_EXTENSION_NAME }; if (!_this->vulkan_config.loader_handle) { SDL_SetError("Vulkan is not loaded"); @@ -187,11 +190,14 @@ SDL_bool Cocoa_Vulkan_CreateSurface(_THIS, { PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr; + PFN_vkCreateMetalSurfaceEXT vkCreateMetalSurfaceEXT = + (PFN_vkCreateMetalSurfaceEXT)vkGetInstanceProcAddr( + (VkInstance)instance, + "vkCreateMetalSurfaceEXT"); PFN_vkCreateMacOSSurfaceMVK vkCreateMacOSSurfaceMVK = (PFN_vkCreateMacOSSurfaceMVK)vkGetInstanceProcAddr( (VkInstance)instance, "vkCreateMacOSSurfaceMVK"); - VkMacOSSurfaceCreateInfoMVK createInfo = {}; VkResult result; SDL_MetalView metalview; @@ -200,9 +206,10 @@ SDL_bool Cocoa_Vulkan_CreateSurface(_THIS, return SDL_FALSE; } - if (!vkCreateMacOSSurfaceMVK) { - SDL_SetError(VK_MVK_MACOS_SURFACE_EXTENSION_NAME - " extension is not enabled in the Vulkan instance."); + if (!vkCreateMetalSurfaceEXT && !vkCreateMacOSSurfaceMVK) { + SDL_SetError(VK_EXT_METAL_SURFACE_EXTENSION_NAME " or " + VK_MVK_MACOS_SURFACE_EXTENSION_NAME + " extensions are not enabled in the Vulkan instance."); return SDL_FALSE; } @@ -211,17 +218,34 @@ SDL_bool Cocoa_Vulkan_CreateSurface(_THIS, return SDL_FALSE; } - createInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK; - createInfo.pNext = NULL; - createInfo.flags = 0; - createInfo.pView = (const void *)metalview; - result = vkCreateMacOSSurfaceMVK(instance, &createInfo, - NULL, surface); - if (result != VK_SUCCESS) { - Cocoa_Metal_DestroyView(_this, metalview); - SDL_SetError("vkCreateMacOSSurfaceMVK failed: %s", - SDL_Vulkan_GetResultString(result)); - return SDL_FALSE; + if (vkCreateMetalSurfaceEXT) { + VkMetalSurfaceCreateInfoEXT createInfo = {}; + createInfo.sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT; + createInfo.pNext = NULL; + createInfo.flags = 0; + createInfo.pLayer = (__bridge const CAMetalLayer *) + Cocoa_Metal_GetLayer(_this, metalview); + result = vkCreateMetalSurfaceEXT(instance, &createInfo, NULL, surface); + if (result != VK_SUCCESS) { + Cocoa_Metal_DestroyView(_this, metalview); + SDL_SetError("vkCreateMetalSurfaceEXT failed: %s", + SDL_Vulkan_GetResultString(result)); + return SDL_FALSE; + } + } else { + VkMacOSSurfaceCreateInfoMVK createInfo = {}; + createInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK; + createInfo.pNext = NULL; + createInfo.flags = 0; + createInfo.pView = (const void *)metalview; + result = vkCreateMacOSSurfaceMVK(instance, &createInfo, + NULL, surface); + if (result != VK_SUCCESS) { + Cocoa_Metal_DestroyView(_this, metalview); + SDL_SetError("vkCreateMacOSSurfaceMVK failed: %s", + SDL_Vulkan_GetResultString(result)); + return SDL_FALSE; + } } /* Unfortunately there's no SDL_Vulkan_DestroySurface function we can call @@ -236,7 +260,7 @@ SDL_bool Cocoa_Vulkan_CreateSurface(_THIS, void Cocoa_Vulkan_GetDrawableSize(_THIS, SDL_Window *window, int *w, int *h) { - Cocoa_Metal_GetDrawableSize(window, w, h); + Cocoa_Metal_GetDrawableSize(_this, window, w, h); } #endif diff --git a/SDL2-2.0.12/src/video/cocoa/SDL_cocoawindow.h b/SDL2-2.30.5/src/video/cocoa/SDL_cocoawindow.h similarity index 74% rename from SDL2-2.0.12/src/video/cocoa/SDL_cocoawindow.h rename to SDL2-2.30.5/src/video/cocoa/SDL_cocoawindow.h index 049d00f..0cf9e9a 100644 --- a/SDL2-2.0.12/src/video/cocoa/SDL_cocoawindow.h +++ b/SDL2-2.30.5/src/video/cocoa/SDL_cocoawindow.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -25,11 +25,11 @@ #import -#if SDL_VIDEO_OPENGL_EGL +#ifdef SDL_VIDEO_OPENGL_EGL #include "../SDL_egl_c.h" #endif -typedef struct SDL_WindowData SDL_WindowData; +@class SDL_WindowData; typedef enum { @@ -40,7 +40,10 @@ typedef enum } PendingWindowOperation; @interface Cocoa_WindowListener : NSResponder { - SDL_WindowData *_data; + /* SDL_WindowData owns this Listener and has a strong reference to it. + * To avoid reference cycles, we could have either a weak or an + * unretained ref to the WindowData. */ + __weak SDL_WindowData *_data; BOOL observingVisible; BOOL wasCtrlLeft; BOOL wasVisible; @@ -48,10 +51,12 @@ typedef enum BOOL inFullscreenTransition; PendingWindowOperation pendingWindowOperation; BOOL isMoving; + NSInteger focusClickPending; int pendingWindowWarpX, pendingWindowWarpY; BOOL isDragAreaRunning; } +-(BOOL) isTouchFromTrackpad:(NSEvent *)theEvent; -(void) listen:(SDL_WindowData *) data; -(void) pauseVisibleObservation; -(void) resumeVisibleObservation; @@ -62,8 +67,12 @@ typedef enum -(void) close; -(BOOL) isMoving; +-(BOOL) isMovingOrFocusClickPending; +-(void) setFocusClickPending:(NSInteger) button; +-(void) clearFocusClickPending:(NSInteger) button; -(void) setPendingMoveX:(int)x Y:(int)y; -(void) windowDidFinishMoving; +-(void) onMovingOrFocusClickPendingStateCleared; /* Window delegate functionality */ -(BOOL) windowShouldClose:(id) sender; @@ -75,6 +84,8 @@ typedef enum -(void) windowDidBecomeKey:(NSNotification *) aNotification; -(void) windowDidResignKey:(NSNotification *) aNotification; -(void) windowDidChangeBackingProperties:(NSNotification *) aNotification; +-(void) windowDidChangeScreenProfile:(NSNotification *) aNotification; +-(void) windowDidChangeScreen:(NSNotification *) aNotification; -(void) windowWillEnterFullScreen:(NSNotification *) aNotification; -(void) windowDidEnterFullScreen:(NSNotification *) aNotification; -(void) windowWillExitFullScreen:(NSNotification *) aNotification; @@ -108,21 +119,23 @@ typedef enum /* *INDENT-ON* */ @class SDLOpenGLContext; +@class SDL_VideoData; -struct SDL_WindowData -{ - SDL_Window *window; - NSWindow *nswindow; - NSView *sdlContentView; /* nil if window is created via CreateWindowFrom */ - NSMutableArray *nscontexts; - SDL_bool created; - SDL_bool inWindowFullscreenTransition; - Cocoa_WindowListener *listener; - struct SDL_VideoData *videodata; -#if SDL_VIDEO_OPENGL_EGL - EGLSurface egl_surface; +@interface SDL_WindowData : NSObject + @property (nonatomic) SDL_Window *window; + @property (nonatomic) NSWindow *nswindow; + @property (nonatomic) NSView *sdlContentView; + @property (nonatomic) NSMutableArray *nscontexts; + @property (nonatomic) SDL_bool created; + @property (nonatomic) SDL_bool inWindowFullscreenTransition; + @property (nonatomic) NSInteger window_number; + @property (nonatomic) NSInteger flash_request; + @property (nonatomic) Cocoa_WindowListener *listener; + @property (nonatomic) SDL_VideoData *videodata; +#ifdef SDL_VIDEO_OPENGL_EGL + @property (nonatomic) EGLSurface egl_surface; #endif -}; +@end extern int Cocoa_CreateWindow(_THIS, SDL_Window * window); extern int Cocoa_CreateWindowFrom(_THIS, SDL_Window * window, @@ -133,6 +146,7 @@ extern void Cocoa_SetWindowPosition(_THIS, SDL_Window * window); extern void Cocoa_SetWindowSize(_THIS, SDL_Window * window); extern void Cocoa_SetWindowMinimumSize(_THIS, SDL_Window * window); extern void Cocoa_SetWindowMaximumSize(_THIS, SDL_Window * window); +extern void Cocoa_GetWindowSizeInPixels(_THIS, SDL_Window * window, int *w, int *h); extern int Cocoa_SetWindowOpacity(_THIS, SDL_Window * window, float opacity); extern void Cocoa_ShowWindow(_THIS, SDL_Window * window); extern void Cocoa_HideWindow(_THIS, SDL_Window * window); @@ -142,14 +156,19 @@ extern void Cocoa_MinimizeWindow(_THIS, SDL_Window * window); extern void Cocoa_RestoreWindow(_THIS, SDL_Window * window); extern void Cocoa_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered); extern void Cocoa_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable); +extern void Cocoa_SetWindowAlwaysOnTop(_THIS, SDL_Window * window, SDL_bool on_top); extern void Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen); extern int Cocoa_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp); +extern void* Cocoa_GetWindowICCProfile(_THIS, SDL_Window * window, size_t * size); +extern int Cocoa_GetWindowDisplayIndex(_THIS, SDL_Window * window); extern int Cocoa_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp); -extern void Cocoa_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed); +extern void Cocoa_SetWindowMouseRect(_THIS, SDL_Window * window); +extern void Cocoa_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed); extern void Cocoa_DestroyWindow(_THIS, SDL_Window * window); extern SDL_bool Cocoa_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info); extern int Cocoa_SetWindowHitTest(SDL_Window *window, SDL_bool enabled); extern void Cocoa_AcceptDragAndDrop(SDL_Window * window, SDL_bool accept); +extern int Cocoa_FlashWindow(_THIS, SDL_Window * window, SDL_FlashOperation operation); #endif /* SDL_cocoawindow_h_ */ diff --git a/SDL2-2.0.12/src/video/cocoa/SDL_cocoawindow.m b/SDL2-2.30.5/src/video/cocoa/SDL_cocoawindow.m similarity index 63% rename from SDL2-2.0.12/src/video/cocoa/SDL_cocoawindow.m rename to SDL2-2.30.5/src/video/cocoa/SDL_cocoawindow.m index b5b1952..8283660 100644 --- a/SDL2-2.0.12/src/video/cocoa/SDL_cocoawindow.m +++ b/SDL2-2.30.5/src/video/cocoa/SDL_cocoawindow.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_COCOA +#ifdef SDL_VIDEO_DRIVER_COCOA #if MAC_OS_X_VERSION_MAX_ALLOWED < 1070 # error SDL for Mac OS X must be built with a 10.7 SDK or above. @@ -38,10 +38,8 @@ #include "SDL_cocoavideo.h" #include "SDL_cocoashape.h" #include "SDL_cocoamouse.h" -#include "SDL_cocoamousetap.h" #include "SDL_cocoaopengl.h" #include "SDL_cocoaopengles.h" -#include "SDL_assert.h" /* #define DEBUG_COCOAWINDOW */ @@ -57,6 +55,25 @@ #ifndef MAC_OS_X_VERSION_10_12 #define NSEventModifierFlagCapsLock NSAlphaShiftKeyMask #endif +#ifndef NSAppKitVersionNumber10_13_2 +#define NSAppKitVersionNumber10_13_2 1561.2 +#endif +#ifndef NSAppKitVersionNumber10_14 +#define NSAppKitVersionNumber10_14 1671 +#endif + +@implementation SDL_WindowData + +@end + +@interface NSWindow (SDL) +#if MAC_OS_X_VERSION_MAX_ALLOWED < 101000 /* Added in the 10.10 SDK */ +@property (readonly) NSRect contentLayoutRect; +#endif + +/* This is available as of 10.13.2, but isn't in public headers */ +@property (nonatomic) NSRect mouseConfinementRect; +@end @interface SDLWindow : NSWindow /* These are needed for borderless/fullscreen windows */ @@ -85,7 +102,7 @@ SDL_Window *window = [self findSDLWindow]; if (window == NULL) { return NO; - } else if ((window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_FULLSCREEN_DESKTOP)) != 0) { + } else if (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_FULLSCREEN_DESKTOP)) { return NO; } else if ((window->flags & SDL_WINDOW_RESIZABLE) == 0) { return NO; @@ -106,13 +123,14 @@ - (void)sendEvent:(NSEvent *)event { + id delegate; [super sendEvent:event]; if ([event type] != NSEventTypeLeftMouseUp) { return; } - id delegate = [self delegate]; + delegate = [self delegate]; if (![delegate isKindOfClass:[Cocoa_WindowListener class]]) { return; } @@ -146,18 +164,33 @@ NSArray *types = [NSArray arrayWithObject:NSFilenamesPboardType]; NSString *desiredType = [pasteboard availableTypeFromArray:types]; SDL_Window *sdlwindow = [self findSDLWindow]; + NSData *data; + NSArray *array; + NSPoint point; + SDL_Mouse *mouse; + int x, y; if (desiredType == nil) { return NO; /* can't accept anything that's being dropped here. */ } - NSData *data = [pasteboard dataForType:desiredType]; + data = [pasteboard dataForType:desiredType]; if (data == nil) { return NO; } SDL_assert([desiredType isEqualToString:NSFilenamesPboardType]); - NSArray *array = [pasteboard propertyListForType:@"NSFilenamesPboardType"]; + array = [pasteboard propertyListForType:@"NSFilenamesPboardType"]; + + /* Code addon to update the mouse location */ + point = [sender draggingLocation]; + mouse = SDL_GetMouse(); + x = (int)point.x; + y = (int)(sdlwindow->h - point.y); + if (x >= 0 && x < sdlwindow->w && y >= 0 && y < sdlwindow->h) { + SDL_SendMouseMotion(sdlwindow, mouse->mouseID, 0, x, y); + } + /* Code addon to update the mouse location */ for (NSString *path in array) { NSURL *fileURL = [NSURL fileURLWithPath:path]; @@ -204,7 +237,7 @@ /* !!! FIXME: is there a better way to do this? */ if (_this) { for (sdlwindow = _this->windows; sdlwindow; sdlwindow = sdlwindow->next) { - NSWindow *nswindow = ((SDL_WindowData *) sdlwindow->driverdata)->nswindow; + NSWindow *nswindow = ((__bridge SDL_WindowData *) sdlwindow->driverdata).nswindow; if (nswindow == self) { break; } @@ -224,21 +257,24 @@ static void ConvertNSRect(NSScreen *screen, BOOL fullscreen, NSRect *r) r->origin.y = CGDisplayPixelsHigh(kCGDirectMainDisplay) - r->origin.y - r->size.height; } -static void -ScheduleContextUpdates(SDL_WindowData *data) +static void ScheduleContextUpdates(SDL_WindowData *data) { - if (!data || !data->nscontexts) { - return; - } - /* We still support OpenGL as long as Apple offers it, deprecated or not, so disable deprecation warnings about it. */ + #ifdef SDL_VIDEO_OPENGL + #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" #endif - NSOpenGLContext *currentContext = [NSOpenGLContext currentContext]; - NSMutableArray *contexts = data->nscontexts; + NSOpenGLContext *currentContext; + NSMutableArray *contexts; + if (!data || !data.nscontexts) { + return; + } + + currentContext = [NSOpenGLContext currentContext]; + contexts = data.nscontexts; @synchronized (contexts) { for (SDLOpenGLContext *context in contexts) { if (context == currentContext) { @@ -252,24 +288,29 @@ ScheduleContextUpdates(SDL_WindowData *data) #ifdef __clang__ #pragma clang diagnostic pop #endif + + #endif /* SDL_VIDEO_OPENGL */ } /* !!! FIXME: this should use a hint callback. */ -static int -GetHintCtrlClickEmulateRightClick() +static int GetHintCtrlClickEmulateRightClick() { return SDL_GetHintBoolean(SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK, SDL_FALSE); } -static NSUInteger -GetWindowWindowedStyle(SDL_Window * window) +static NSUInteger GetWindowWindowedStyle(SDL_Window * window) { - NSUInteger style = 0; + /* IF YOU CHANGE ANY FLAGS IN HERE, PLEASE READ + the NSWindowStyleMaskBorderless comments in SetupWindowData()! */ + + /* always allow miniaturization, otherwise you can't programatically + minimize the window, whether there's a title bar or not */ + NSUInteger style = NSWindowStyleMaskMiniaturizable; if (window->flags & SDL_WINDOW_BORDERLESS) { - style = NSWindowStyleMaskBorderless; + style |= NSWindowStyleMaskBorderless; } else { - style = (NSWindowStyleMaskTitled|NSWindowStyleMaskClosable|NSWindowStyleMaskMiniaturizable); + style |= (NSWindowStyleMaskTitled|NSWindowStyleMaskClosable); } if (window->flags & SDL_WINDOW_RESIZABLE) { style |= NSWindowStyleMaskResizable; @@ -277,8 +318,7 @@ GetWindowWindowedStyle(SDL_Window * window) return style; } -static NSUInteger -GetWindowStyle(SDL_Window * window) +static NSUInteger GetWindowStyle(SDL_Window * window) { NSUInteger style = 0; @@ -290,35 +330,155 @@ GetWindowStyle(SDL_Window * window) return style; } -static SDL_bool -SetWindowStyle(SDL_Window * window, NSUInteger style) +static SDL_bool SetWindowStyle(SDL_Window * window, NSUInteger style) { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - NSWindow *nswindow = data->nswindow; + SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata; + NSWindow *nswindow = data.nswindow; /* The view responder chain gets messed with during setStyleMask */ - if ([[nswindow contentView] nextResponder] == data->listener) { - [[nswindow contentView] setNextResponder:nil]; + if ([data.sdlContentView nextResponder] == data.listener) { + [data.sdlContentView setNextResponder:nil]; } [nswindow setStyleMask:style]; /* The view responder chain gets messed with during setStyleMask */ - if ([[nswindow contentView] nextResponder] != data->listener) { - [[nswindow contentView] setNextResponder:data->listener]; + if ([data.sdlContentView nextResponder] != data.listener) { + [data.sdlContentView setNextResponder:data.listener]; } return SDL_TRUE; } +static SDL_bool ShouldAdjustCoordinatesForGrab(SDL_Window * window) +{ + SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata; + + if (!data || [data.listener isMovingOrFocusClickPending]) { + return SDL_FALSE; + } + + if (!(window->flags & SDL_WINDOW_INPUT_FOCUS)) { + return SDL_FALSE; + } + + if ((window->flags & SDL_WINDOW_MOUSE_GRABBED) || (window->mouse_rect.w > 0 && window->mouse_rect.h > 0)) { + return SDL_TRUE; + } + return SDL_FALSE; +} + +static SDL_bool AdjustCoordinatesForGrab(SDL_Window * window, int x, int y, CGPoint *adjusted) +{ + if (window->mouse_rect.w > 0 && window->mouse_rect.h > 0) { + SDL_Rect window_rect; + SDL_Rect mouse_rect; + + window_rect.x = 0; + window_rect.y = 0; + window_rect.w = window->w; + window_rect.h = window->h; + + if (SDL_IntersectRect(&window->mouse_rect, &window_rect, &mouse_rect)) { + int left = window->x + mouse_rect.x; + int right = left + mouse_rect.w - 1; + int top = window->y + mouse_rect.y; + int bottom = top + mouse_rect.h - 1; + if (x < left || x > right || y < top || y > bottom) { + adjusted->x = SDL_clamp(x, left, right); + adjusted->y = SDL_clamp(y, top, bottom); + return SDL_TRUE; + } + return SDL_FALSE; + } + } + + if (window->flags & SDL_WINDOW_MOUSE_GRABBED) { + int left = window->x; + int right = left + window->w - 1; + int top = window->y; + int bottom = top + window->h - 1; + if (x < left || x > right || y < top || y > bottom) { + adjusted->x = SDL_clamp(x, left, right); + adjusted->y = SDL_clamp(y, top, bottom); + return SDL_TRUE; + } + } + return SDL_FALSE; +} + +static void Cocoa_UpdateClipCursor(SDL_Window * window) +{ + SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata; + + if (NSAppKitVersionNumber >= NSAppKitVersionNumber10_13_2) { + NSWindow *nswindow = data.nswindow; + SDL_Rect mouse_rect; + + SDL_zero(mouse_rect); + + if (ShouldAdjustCoordinatesForGrab(window)) { + SDL_Rect window_rect; + + window_rect.x = 0; + window_rect.y = 0; + window_rect.w = window->w; + window_rect.h = window->h; + + if (window->mouse_rect.w > 0 && window->mouse_rect.h > 0) { + SDL_IntersectRect(&window->mouse_rect, &window_rect, &mouse_rect); + } + + if ((window->flags & SDL_WINDOW_MOUSE_GRABBED) != 0 && + SDL_RectEmpty(&mouse_rect)) { + SDL_memcpy(&mouse_rect, &window_rect, sizeof(mouse_rect)); + } + } + + if (SDL_RectEmpty(&mouse_rect)) { + nswindow.mouseConfinementRect = NSZeroRect; + } else { + NSRect rect; + rect.origin.x = mouse_rect.x; + rect.origin.y = [nswindow contentLayoutRect].size.height - mouse_rect.y - mouse_rect.h; + rect.size.width = mouse_rect.w; + rect.size.height = mouse_rect.h; + nswindow.mouseConfinementRect = rect; + } + } else { + /* Move the cursor to the nearest point in the window */ + if (ShouldAdjustCoordinatesForGrab(window)) { + int x, y; + CGPoint cgpoint; + + SDL_GetGlobalMouseState(&x, &y); + if (AdjustCoordinatesForGrab(window, x, y, &cgpoint)) { + Cocoa_HandleMouseWarp(cgpoint.x, cgpoint.y); + CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, cgpoint); + } + } + } +} + +static NSCursor *Cocoa_GetDesiredCursor(void) +{ + SDL_Mouse *mouse = SDL_GetMouse(); + + if (mouse->cursor_shown && mouse->cur_cursor && !mouse->relative_mode) { + return (__bridge NSCursor *)mouse->cur_cursor->driverdata; + } + + return [NSCursor invisibleCursor]; +} + @implementation Cocoa_WindowListener - (void)listen:(SDL_WindowData *)data { NSNotificationCenter *center; - NSWindow *window = data->nswindow; - NSView *view = [window contentView]; + NSWindow *window = data.nswindow; + NSView *view = data.sdlContentView; _data = data; observingVisible = YES; @@ -329,6 +489,7 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) pendingWindowOperation = PENDING_OPERATION_NONE; isMoving = NO; isDragAreaRunning = NO; + pendingWindowWarpX = pendingWindowWarpY = INT_MAX; center = [NSNotificationCenter defaultCenter]; @@ -341,6 +502,8 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) [center addObserver:self selector:@selector(windowDidBecomeKey:) name:NSWindowDidBecomeKeyNotification object:window]; [center addObserver:self selector:@selector(windowDidResignKey:) name:NSWindowDidResignKeyNotification object:window]; [center addObserver:self selector:@selector(windowDidChangeBackingProperties:) name:NSWindowDidChangeBackingPropertiesNotification object:window]; + [center addObserver:self selector:@selector(windowDidChangeScreenProfile:) name:NSWindowDidChangeScreenProfileNotification object:window]; + [center addObserver:self selector:@selector(windowDidChangeScreen:) name:NSWindowDidChangeScreenNotification object:window]; [center addObserver:self selector:@selector(windowWillEnterFullScreen:) name:NSWindowWillEnterFullScreenNotification object:window]; [center addObserver:self selector:@selector(windowDidEnterFullScreen:) name:NSWindowDidEnterFullScreenNotification object:window]; [center addObserver:self selector:@selector(windowWillExitFullScreen:) name:NSWindowWillExitFullScreenNotification object:window]; @@ -377,12 +540,12 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) return; } - if (object == _data->nswindow && [keyPath isEqualToString:@"visible"]) { + if (object == _data.nswindow && [keyPath isEqualToString:@"visible"]) { int newVisibility = [[change objectForKey:@"new"] intValue]; if (newVisibility) { - SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_SHOWN, 0, 0); + SDL_SendWindowEvent(_data.window, SDL_WINDOWEVENT_SHOWN, 0, 0); } else { - SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_HIDDEN, 0, 0); + SDL_SendWindowEvent(_data.window, SDL_WINDOWEVENT_HIDDEN, 0, 0); } } } @@ -390,18 +553,18 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) -(void) pauseVisibleObservation { observingVisible = NO; - wasVisible = [_data->nswindow isVisible]; + wasVisible = [_data.nswindow isVisible]; } -(void) resumeVisibleObservation { - BOOL isVisible = [_data->nswindow isVisible]; + BOOL isVisible = [_data.nswindow isVisible]; observingVisible = YES; if (wasVisible != isVisible) { if (isVisible) { - SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_SHOWN, 0, 0); + SDL_SendWindowEvent(_data.window, SDL_WINDOWEVENT_SHOWN, 0, 0); } else { - SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_HIDDEN, 0, 0); + SDL_SendWindowEvent(_data.window, SDL_WINDOWEVENT_HIDDEN, 0, 0); } wasVisible = isVisible; @@ -410,11 +573,11 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) -(BOOL) setFullscreenSpace:(BOOL) state { - SDL_Window *window = _data->window; - NSWindow *nswindow = _data->nswindow; - SDL_VideoData *videodata = ((SDL_WindowData *) window->driverdata)->videodata; + SDL_Window *window = _data.window; + NSWindow *nswindow = _data.nswindow; + SDL_VideoData *videodata = ((__bridge SDL_WindowData *) window->driverdata).videodata; - if (!videodata->allow_spaces) { + if (!videodata.allow_spaces) { return NO; /* Spaces are forcibly disabled. */ } else if (state && ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP)) { return NO; /* we only allow you to make a Space on FULLSCREEN_DESKTOP windows. */ @@ -458,7 +621,7 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) - (void)close { NSNotificationCenter *center; - NSWindow *window = _data->nswindow; + NSWindow *window = _data.nswindow; NSView *view = [window contentView]; center = [NSNotificationCenter defaultCenter]; @@ -472,6 +635,8 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) [center removeObserver:self name:NSWindowDidBecomeKeyNotification object:window]; [center removeObserver:self name:NSWindowDidResignKeyNotification object:window]; [center removeObserver:self name:NSWindowDidChangeBackingPropertiesNotification object:window]; + [center removeObserver:self name:NSWindowDidChangeScreenProfileNotification object:window]; + [center removeObserver:self name:NSWindowDidChangeScreenNotification object:window]; [center removeObserver:self name:NSWindowWillEnterFullScreenNotification object:window]; [center removeObserver:self name:NSWindowDidEnterFullScreenNotification object:window]; [center removeObserver:self name:NSWindowWillExitFullScreenNotification object:window]; @@ -497,6 +662,26 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) return isMoving; } +- (BOOL)isMovingOrFocusClickPending +{ + return isMoving || (focusClickPending != 0); +} + +-(void) setFocusClickPending:(NSInteger) button +{ + focusClickPending |= (1 << button); +} + +-(void) clearFocusClickPending:(NSInteger) button +{ + if (focusClickPending & (1 << button)) { + focusClickPending &= ~(1 << button); + if (focusClickPending == 0) { + [self onMovingOrFocusClickPendingStateCleared]; + } + } +} + -(void) setPendingMoveX:(int)x Y:(int)y { pendingWindowWarpX = x; @@ -505,34 +690,57 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) - (void)windowDidFinishMoving { - if ([self isMoving]) { + if (isMoving) { isMoving = NO; + [self onMovingOrFocusClickPendingStateCleared]; + } +} +- (void)onMovingOrFocusClickPendingStateCleared +{ + if (![self isMovingOrFocusClickPending]) { SDL_Mouse *mouse = SDL_GetMouse(); if (pendingWindowWarpX != INT_MAX && pendingWindowWarpY != INT_MAX) { mouse->WarpMouseGlobal(pendingWindowWarpX, pendingWindowWarpY); pendingWindowWarpX = pendingWindowWarpY = INT_MAX; } - if (mouse->relative_mode && !mouse->relative_mode_warp && mouse->focus == _data->window) { + if (mouse->relative_mode && !mouse->relative_mode_warp && mouse->focus == _data.window) { + /* Move the cursor to the nearest point in the window */ + { + int x, y; + CGPoint cgpoint; + + SDL_GetMouseState(&x, &y); + cgpoint.x = _data.window->x + x; + cgpoint.y = _data.window->y + y; + + Cocoa_HandleMouseWarp(cgpoint.x, cgpoint.y); + + DLog("Returning cursor to (%g, %g)", cgpoint.x, cgpoint.y); + CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, cgpoint); + } + mouse->SetRelativeMouseMode(SDL_TRUE); + } else { + Cocoa_UpdateClipCursor(_data.window); } } } - (BOOL)windowShouldClose:(id)sender { - SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_CLOSE, 0, 0); + SDL_SendWindowEvent(_data.window, SDL_WINDOWEVENT_CLOSE, 0, 0); return NO; } - (void)windowDidExpose:(NSNotification *)aNotification { - SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_EXPOSED, 0, 0); + SDL_SendWindowEvent(_data.window, SDL_WINDOWEVENT_EXPOSED, 0, 0); } - (void)windowWillMove:(NSNotification *)aNotification { - if ([_data->nswindow isKindOfClass:[SDLWindow class]]) { + if ([_data.nswindow isKindOfClass:[SDLWindow class]]) { pendingWindowWarpX = pendingWindowWarpY = INT_MAX; isMoving = YES; } @@ -541,8 +749,8 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) - (void)windowDidMove:(NSNotification *)aNotification { int x, y; - SDL_Window *window = _data->window; - NSWindow *nswindow = _data->nswindow; + SDL_Window *window = _data.window; + NSWindow *nswindow = _data.nswindow; BOOL fullscreen = window->flags & FULLSCREEN_MASK; NSRect rect = [nswindow contentRectForFrameRect:[nswindow frame]]; ConvertNSRect([nswindow screen], fullscreen, &rect); @@ -577,15 +785,24 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) - (void)windowDidResize:(NSNotification *)aNotification { + SDL_Window *window; + NSWindow *nswindow; + NSRect rect; + int x, y, w, h; + BOOL zoomed; if (inFullscreenTransition) { /* We'll take care of this at the end of the transition */ return; } - SDL_Window *window = _data->window; - NSWindow *nswindow = _data->nswindow; - int x, y, w, h; - NSRect rect = [nswindow contentRectForFrameRect:[nswindow frame]]; + if (focusClickPending) { + focusClickPending = 0; + [self onMovingOrFocusClickPendingStateCleared]; + } + + window = _data.window; + nswindow = _data.nswindow; + rect = [nswindow contentRectForFrameRect:[nswindow frame]]; ConvertNSRect([nswindow screen], (window->flags & FULLSCREEN_MASK), &rect); x = (int)rect.origin.x; y = (int)rect.origin.y; @@ -603,7 +820,12 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MOVED, x, y); SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, w, h); - const BOOL zoomed = [nswindow isZoomed]; + /* isZoomed always returns true if the window is not resizable */ + if ((window->flags & SDL_WINDOW_RESIZABLE) && [nswindow isZoomed]) { + zoomed = YES; + } else { + zoomed = NO; + } if (!zoomed) { SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESTORED, 0, 0); } else if (zoomed) { @@ -613,24 +835,28 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) - (void)windowDidMiniaturize:(NSNotification *)aNotification { - SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_MINIMIZED, 0, 0); + if (focusClickPending) { + focusClickPending = 0; + [self onMovingOrFocusClickPendingStateCleared]; + } + SDL_SendWindowEvent(_data.window, SDL_WINDOWEVENT_MINIMIZED, 0, 0); } - (void)windowDidDeminiaturize:(NSNotification *)aNotification { - SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_RESTORED, 0, 0); + SDL_SendWindowEvent(_data.window, SDL_WINDOWEVENT_RESTORED, 0, 0); } - (void)windowDidBecomeKey:(NSNotification *)aNotification { - SDL_Window *window = _data->window; + SDL_Window *window = _data.window; SDL_Mouse *mouse = SDL_GetMouse(); /* We're going to get keyboard events, since we're key. */ /* This needs to be done before restoring the relative mouse mode. */ SDL_SetKeyboardFocus(window); - if (mouse->relative_mode && !mouse->relative_mode_warp && ![self isMoving]) { + if (mouse->relative_mode && !mouse->relative_mode_warp && ![self isMovingOrFocusClickPending]) { mouse->SetRelativeMouseMode(SDL_TRUE); } @@ -639,7 +865,7 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) NSPoint point; int x, y; - point = [_data->nswindow mouseLocationOutsideOfEventStream]; + point = [_data.nswindow mouseLocationOutsideOfEventStream]; x = (int)point.x; y = (int)(window->h - point.y); @@ -649,15 +875,16 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) } /* Check to see if someone updated the clipboard */ - Cocoa_CheckClipboardUpdate(_data->videodata); + Cocoa_CheckClipboardUpdate(_data.videodata); if ((isFullscreenSpace) && ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP)) { [NSMenu setMenuBarVisible:NO]; } - - const unsigned int newflags = [NSEvent modifierFlags] & NSEventModifierFlagCapsLock; - _data->videodata->modifierFlags = (_data->videodata->modifierFlags & ~NSEventModifierFlagCapsLock) | newflags; - SDL_ToggleModState(KMOD_CAPS, newflags != 0); + { + const unsigned int newflags = [NSEvent modifierFlags] & NSEventModifierFlagCapsLock; + _data.videodata.modifierFlags = (_data.videodata.modifierFlags & ~NSEventModifierFlagCapsLock) | newflags; + SDL_ToggleModState(KMOD_CAPS, newflags ? SDL_TRUE : SDL_FALSE); + } } - (void)windowDidResignKey:(NSNotification *)aNotification @@ -668,12 +895,12 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) } /* Some other window will get mouse events, since we're not key. */ - if (SDL_GetMouseFocus() == _data->window) { + if (SDL_GetMouseFocus() == _data.window) { SDL_SetMouseFocus(NULL); } /* Some other window will get keyboard events, since we're not key. */ - if (SDL_GetKeyboardFocus() == _data->window) { + if (SDL_GetKeyboardFocus() == _data.window) { SDL_SetKeyboardFocus(NULL); } @@ -690,17 +917,32 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) return; } - if ([oldscale doubleValue] != [_data->nswindow backingScaleFactor]) { + if ([oldscale doubleValue] != [_data.nswindow backingScaleFactor]) { /* Force a resize event when the backing scale factor changes. */ - _data->window->w = 0; - _data->window->h = 0; + _data.window->w = 0; + _data.window->h = 0; [self windowDidResize:aNotification]; } } +- (void)windowDidChangeScreenProfile:(NSNotification *)aNotification +{ + SDL_SendWindowEvent(_data.window, SDL_WINDOWEVENT_ICCPROF_CHANGED, 0, 0); +} + +- (void)windowDidChangeScreen:(NSNotification *)aNotification +{ + /*printf("WINDOWDIDCHANGESCREEN\n");*/ + if (_data && _data.nscontexts) { + for (SDLOpenGLContext *context in _data.nscontexts) { + [context movedToNewScreen]; + } + } +} + - (void)windowWillEnterFullScreen:(NSNotification *)aNotification { - SDL_Window *window = _data->window; + SDL_Window *window = _data.window; SetWindowStyle(window, (NSWindowStyleMaskTitled|NSWindowStyleMaskClosable|NSWindowStyleMaskMiniaturizable|NSWindowStyleMaskResizable)); @@ -710,7 +952,7 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) - (void)windowDidFailToEnterFullScreen:(NSNotification *)aNotification { - SDL_Window *window = _data->window; + SDL_Window *window = _data.window; if (window->is_destroying) { return; @@ -720,15 +962,13 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) isFullscreenSpace = NO; inFullscreenTransition = NO; - + [self windowDidExitFullScreen:nil]; } - (void)windowDidEnterFullScreen:(NSNotification *)aNotification { - SDL_Window *window = _data->window; - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - NSWindow *nswindow = data->nswindow; + SDL_Window *window = _data.window; inFullscreenTransition = NO; @@ -736,11 +976,6 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) pendingWindowOperation = PENDING_OPERATION_NONE; [self setFullscreenSpace:NO]; } else { - /* Unset the resizable flag. - This is a workaround for https://bugzilla.libsdl.org/show_bug.cgi?id=3697 - */ - SetWindowStyle(window, [nswindow styleMask] & (~NSWindowStyleMaskResizable)); - if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) { [NSMenu setMenuBarVisible:NO]; } @@ -758,7 +993,7 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) - (void)windowWillExitFullScreen:(NSNotification *)aNotification { - SDL_Window *window = _data->window; + SDL_Window *window = _data.window; isFullscreenSpace = NO; inFullscreenTransition = YES; @@ -776,24 +1011,24 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) - (void)windowDidFailToExitFullScreen:(NSNotification *)aNotification { - SDL_Window *window = _data->window; - + SDL_Window *window = _data.window; + if (window->is_destroying) { return; } SetWindowStyle(window, (NSWindowStyleMaskTitled|NSWindowStyleMaskClosable|NSWindowStyleMaskMiniaturizable|NSWindowStyleMaskResizable)); - + isFullscreenSpace = YES; inFullscreenTransition = NO; - + [self windowDidEnterFullScreen:nil]; } - (void)windowDidExitFullScreen:(NSNotification *)aNotification { - SDL_Window *window = _data->window; - NSWindow *nswindow = _data->nswindow; + SDL_Window *window = _data.window; + NSWindow *nswindow = _data.nswindow; NSButton *button = nil; inFullscreenTransition = NO; @@ -886,7 +1121,7 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) -(NSApplicationPresentationOptions)window:(NSWindow *)window willUseFullScreenPresentationOptions:(NSApplicationPresentationOptions)proposedOptions { - if ((_data->window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) { + if ((_data.window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) { return NSApplicationPresentationFullScreen | NSApplicationPresentationHideDock | NSApplicationPresentationHideMenuBar; } else { return proposedOptions; @@ -912,11 +1147,9 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) keypresses; it won't toggle the mod state if you send a keyrelease. */ const SDL_bool osenabled = ([theEvent modifierFlags] & NSEventModifierFlagCapsLock) ? SDL_TRUE : SDL_FALSE; const SDL_bool sdlenabled = (SDL_GetModState() & KMOD_CAPS) ? SDL_TRUE : SDL_FALSE; - if (!osenabled && sdlenabled) { - SDL_ToggleModState(KMOD_CAPS, SDL_FALSE); - SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_CAPSLOCK); - } else if (osenabled && !sdlenabled) { + if (osenabled ^ sdlenabled) { SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_CAPSLOCK); + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_CAPSLOCK); } } - (void)keyDown:(NSEvent *)theEvent @@ -938,16 +1171,16 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) - (BOOL)processHitTest:(NSEvent *)theEvent { - SDL_assert(isDragAreaRunning == [_data->nswindow isMovableByWindowBackground]); + SDL_assert(isDragAreaRunning == [_data.nswindow isMovableByWindowBackground]); - if (_data->window->hit_test) { /* if no hit-test, skip this. */ + if (_data.window->hit_test) { /* if no hit-test, skip this. */ const NSPoint location = [theEvent locationInWindow]; - const SDL_Point point = { (int) location.x, _data->window->h - (((int) location.y)-1) }; - const SDL_HitTestResult rc = _data->window->hit_test(_data->window, &point, _data->window->hit_test_data); + const SDL_Point point = { (int) location.x, _data.window->h - (((int) location.y)-1) }; + const SDL_HitTestResult rc = _data.window->hit_test(_data.window, &point, _data.window->hit_test_data); if (rc == SDL_HITTEST_DRAGGABLE) { if (!isDragAreaRunning) { isDragAreaRunning = YES; - [_data->nswindow setMovableByWindowBackground:YES]; + [_data.nswindow setMovableByWindowBackground:YES]; } return YES; /* dragging! */ } @@ -955,24 +1188,50 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) if (isDragAreaRunning) { isDragAreaRunning = NO; - [_data->nswindow setMovableByWindowBackground:NO]; + [_data.nswindow setMovableByWindowBackground:NO]; return YES; /* was dragging, drop event. */ } return NO; /* not a special area, carry on. */ } +static int Cocoa_SendMouseButtonClicks(SDL_Mouse * mouse, NSEvent *theEvent, SDL_Window * window, const Uint8 state, const Uint8 button) +{ + const SDL_MouseID mouseID = mouse->mouseID; + const int clicks = (int) [theEvent clickCount]; + SDL_Window *focus = SDL_GetKeyboardFocus(); + int rc; + + // macOS will send non-left clicks to background windows without raising them, so we need to + // temporarily adjust the mouse position when this happens, as `mouse` will be tracking + // the position in the currently-focused window. We don't (currently) send a mousemove + // event for the background window, this just makes sure the button is reported at the + // correct position in its own event. + if ( focus && ([theEvent window] == ((__bridge SDL_WindowData *) focus->driverdata).nswindow) ) { + rc = SDL_SendMouseButtonClicks(window, mouseID, state, button, clicks); + } else { + const int orig_x = mouse->x; + const int orig_y = mouse->y; + const NSPoint point = [theEvent locationInWindow]; + mouse->x = (int) point.x; + mouse->y = (int) (window->h - point.y); + rc = SDL_SendMouseButtonClicks(window, mouseID, state, button, clicks); + mouse->x = orig_x; + mouse->y = orig_y; + } + + return rc; +} + - (void)mouseDown:(NSEvent *)theEvent { - const SDL_Mouse *mouse = SDL_GetMouse(); + SDL_Mouse *mouse = SDL_GetMouse(); + int button; + if (!mouse) { return; } - const SDL_MouseID mouseID = mouse->mouseID; - int button; - int clicks; - /* Ignore events that aren't inside the client area (i.e. title bar.) */ if ([theEvent window]) { NSRect windowRect = [[[theEvent window] contentView] frame]; @@ -982,7 +1241,7 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) } if ([self processHitTest:theEvent]) { - SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_HIT_TEST, 0, 0); + SDL_SendWindowEvent(_data.window, SDL_WINDOWEVENT_HIT_TEST, 0, 0); return; /* dragging, drop event. */ } @@ -1008,9 +1267,7 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) break; } - clicks = (int) [theEvent clickCount]; - - SDL_SendMouseButtonClicks(_data->window, mouseID, SDL_PRESSED, button, clicks); + Cocoa_SendMouseButtonClicks(mouse, theEvent, _data.window, SDL_PRESSED, button); } - (void)rightMouseDown:(NSEvent *)theEvent @@ -1025,17 +1282,15 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) - (void)mouseUp:(NSEvent *)theEvent { - const SDL_Mouse *mouse = SDL_GetMouse(); + SDL_Mouse *mouse = SDL_GetMouse(); + int button; + if (!mouse) { return; } - const SDL_MouseID mouseID = mouse->mouseID; - int button; - int clicks; - if ([self processHitTest:theEvent]) { - SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_HIT_TEST, 0, 0); + SDL_SendWindowEvent(_data.window, SDL_WINDOWEVENT_HIT_TEST, 0, 0); return; /* stopped dragging, drop event. */ } @@ -1059,9 +1314,7 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) break; } - clicks = (int) [theEvent clickCount]; - - SDL_SendMouseButtonClicks(_data->window, mouseID, SDL_RELEASED, button, clicks); + Cocoa_SendMouseButtonClicks(mouse, theEvent, _data.window, SDL_RELEASED, button); } - (void)rightMouseUp:(NSEvent *)theEvent @@ -1077,14 +1330,29 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) - (void)mouseMoved:(NSEvent *)theEvent { SDL_Mouse *mouse = SDL_GetMouse(); + SDL_MouseID mouseID; + NSPoint point; + int x, y; + SDL_Window *window; + NSView *contentView; + if (!mouse) { return; } - const SDL_MouseID mouseID = mouse->mouseID; - SDL_Window *window = _data->window; - NSPoint point; - int x, y; + mouseID = mouse->mouseID; + window = _data.window; + contentView = _data.sdlContentView; + point = [theEvent locationInWindow]; + + if ([contentView mouse:[contentView convertPoint:point fromView:nil] inRect:[contentView bounds]] && + [NSCursor currentCursor] != Cocoa_GetDesiredCursor()) { + // The wrong cursor is on screen, fix it. This fixes an macOS bug that is only known to + // occur in fullscreen windows on the built-in displays of newer MacBooks with camera + // notches. When the mouse is moved near the top of such a window (within about 44 units) + // and then moved back down, the cursor rects aren't respected. + [_data.nswindow invalidateCursorRectsForView:contentView]; + } if ([self processHitTest:theEvent]) { SDL_SendWindowEvent(window, SDL_WINDOWEVENT_HIT_TEST, 0, 0); @@ -1095,38 +1363,18 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) return; } - point = [theEvent locationInWindow]; x = (int)point.x; y = (int)(window->h - point.y); - if (window->flags & SDL_WINDOW_INPUT_GRABBED) { - if (x < 0 || x >= window->w || y < 0 || y >= window->h) { - if (x < 0) { - x = 0; - } else if (x >= window->w) { - x = window->w - 1; - } - if (y < 0) { - y = 0; - } else if (y >= window->h) { - y = window->h - 1; - } - -#if !SDL_MAC_NO_SANDBOX - CGPoint cgpoint; - - /* When SDL_MAC_NO_SANDBOX is set, this is handled by - * SDL_cocoamousetap.m. - */ - - cgpoint.x = window->x + x; - cgpoint.y = window->y + y; - + if (NSAppKitVersionNumber >= NSAppKitVersionNumber10_13_2) { + /* Mouse grab is taken care of by the confinement rect */ + } else { + CGPoint cgpoint; + if (ShouldAdjustCoordinatesForGrab(window) && + AdjustCoordinatesForGrab(window, window->x + x, window->y + y, &cgpoint)) { + Cocoa_HandleMouseWarp(cgpoint.x, cgpoint.y); CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, cgpoint); CGAssociateMouseAndMouseCursorPosition(YES); - - Cocoa_HandleMouseWarp(cgpoint.x, cgpoint.y); -#endif } } @@ -1150,18 +1398,46 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) - (void)scrollWheel:(NSEvent *)theEvent { - Cocoa_HandleMouseWheel(_data->window, theEvent); + Cocoa_HandleMouseWheel(_data.window, theEvent); +} + + +- (BOOL)isTouchFromTrackpad:(NSEvent *)theEvent +{ + SDL_Window *window = _data.window; + SDL_VideoData *videodata = ((__bridge SDL_WindowData *) window->driverdata).videodata; + + /* if this a MacBook trackpad, we'll make input look like a synthesized + event. This is backwards from reality, but better matches user + expectations. You can make it look like a generic touch device instead + with the SDL_HINT_TRACKPAD_IS_TOUCH_ONLY hint. */ + BOOL istrackpad = NO; + if (!videodata.trackpad_is_touch_only) { + @try { + istrackpad = ([theEvent subtype] == NSEventSubtypeMouseEvent); + } + @catch (NSException *e) { + /* if NSEvent type doesn't have subtype, such as NSEventTypeBeginGesture on + * macOS 10.5 to 10.10, then NSInternalInconsistencyException is thrown. + * This still prints a message to terminal so catching it's not an ideal solution. + * + * *** Assertion failure in -[NSEvent subtype] + */ + } + } + return istrackpad; } - (void)touchesBeganWithEvent:(NSEvent *) theEvent { - /* probably a MacBook trackpad; make this look like a synthesized event. - This is backwards from reality, but better matches user expectations. */ - const BOOL istrackpad = ([theEvent subtype] == NSEventSubtypeMouseEvent); + NSSet *touches; + SDL_TouchID touchID; + int existingTouchCount; + const BOOL istrackpad = [self isTouchFromTrackpad:theEvent]; - NSSet *touches = [theEvent touchesMatchingPhase:NSTouchPhaseAny inView:nil]; - const SDL_TouchID touchID = istrackpad ? SDL_MOUSE_TOUCHID : (SDL_TouchID)(intptr_t)[[touches anyObject] device]; - int existingTouchCount = 0; + touches = [theEvent touchesMatchingPhase:NSTouchPhaseAny inView:nil]; + touchID = istrackpad ? SDL_MOUSE_TOUCHID : (SDL_TouchID)(intptr_t)[[touches anyObject] device]; + existingTouchCount = 0; for (NSTouch* touch in touches) { if ([touch phase] != NSTouchPhaseBegan) { @@ -1205,10 +1481,9 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) - (void)handleTouches:(NSTouchPhase) phase withEvent:(NSEvent *) theEvent { NSSet *touches = [theEvent touchesMatchingPhase:phase inView:nil]; - - /* probably a MacBook trackpad; make this look like a synthesized event. - This is backwards from reality, but better matches user expectations. */ - const BOOL istrackpad = ([theEvent subtype] == NSEventSubtypeMouseEvent); + const BOOL istrackpad = [self isTouchFromTrackpad:theEvent]; + SDL_FingerID fingerId; + float x, y; for (NSTouch *touch in touches) { const SDL_TouchID touchId = istrackpad ? SDL_MOUSE_TOUCHID : (SDL_TouchID)(intptr_t)[touch device]; @@ -1240,9 +1515,9 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) return; } - const SDL_FingerID fingerId = (SDL_FingerID)(intptr_t)[touch identity]; - float x = [touch normalizedPosition].x; - float y = [touch normalizedPosition].y; + fingerId = (SDL_FingerID)(intptr_t)[touch identity]; + x = [touch normalizedPosition].x; + y = [touch normalizedPosition].y; /* Make the origin the upper left instead of the lower left */ y = 1.0f - y; @@ -1318,7 +1593,7 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) white until the app is ready to draw. In practice on modern macOS, this only gets called for window creation and other extraordinary events. */ self.layer.backgroundColor = CGColorGetConstantColor(kCGColorBlack); - ScheduleContextUpdates((SDL_WindowData *) _sdlWindow->driverdata); + ScheduleContextUpdates((__bridge SDL_WindowData *) _sdlWindow->driverdata); SDL_SendWindowEvent(_sdlWindow, SDL_WINDOWEVENT_EXPOSED, 0, 0); } @@ -1338,15 +1613,8 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) - (void)resetCursorRects { [super resetCursorRects]; - SDL_Mouse *mouse = SDL_GetMouse(); - - if (mouse->cursor_shown && mouse->cur_cursor && !mouse->relative_mode) { - [self addCursorRect:[self bounds] - cursor:mouse->cur_cursor->driverdata]; - } else { - [self addCursorRect:[self bounds] - cursor:[NSCursor invisibleCursor]]; - } + [self addCursorRect:[self bounds] + cursor:Cocoa_GetDesiredCursor()]; } - (BOOL)acceptsFirstMouse:(NSEvent *)theEvent @@ -1359,31 +1627,27 @@ SetWindowStyle(SDL_Window * window, NSUInteger style) } @end -static int -SetupWindowData(_THIS, SDL_Window * window, NSWindow *nswindow, SDL_bool created) +static int SetupWindowData(_THIS, SDL_Window * window, NSWindow *nswindow, NSView *nsview, SDL_bool created) { @autoreleasepool { - SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; + SDL_VideoData *videodata = (__bridge SDL_VideoData *) _this->driverdata; SDL_WindowData *data; /* Allocate the window data */ - window->driverdata = data = (SDL_WindowData *) SDL_calloc(1, sizeof(*data)); + data = [[SDL_WindowData alloc] init]; if (!data) { return SDL_OutOfMemory(); } - data->window = window; - data->nswindow = nswindow; - data->created = created; - data->videodata = videodata; - data->nscontexts = [[NSMutableArray alloc] init]; - - /* Only store this for windows created by us since the content view might - * get replaced from under us otherwise, and we only need it when the - * window is guaranteed to be created by us (OpenGL contexts). */ - data->sdlContentView = created ? [nswindow contentView] : nil; + data.window = window; + data.nswindow = nswindow; + data.created = created; + data.videodata = videodata; + data.window_number = nswindow.windowNumber; + data.nscontexts = [[NSMutableArray alloc] init]; + data.sdlContentView = nsview; /* Create an event listener for the window */ - data->listener = [[Cocoa_WindowListener alloc] init]; + data.listener = [[Cocoa_WindowListener alloc] init]; /* Fill in the SDL window with the window data */ { @@ -1396,7 +1660,7 @@ SetupWindowData(_THIS, SDL_Window * window, NSWindow *nswindow, SDL_bool created } /* Set up the listener after we create the view */ - [data->listener listen:data]; + [data.listener listen:data]; if ([nswindow isVisible]) { window->flags |= SDL_WINDOW_SHOWN; @@ -1407,7 +1671,10 @@ SetupWindowData(_THIS, SDL_Window * window, NSWindow *nswindow, SDL_bool created { unsigned long style = [nswindow styleMask]; - if (style == NSWindowStyleMaskBorderless) { + /* NSWindowStyleMaskBorderless is zero, and it's possible to be + Resizeable _and_ borderless, so we can't do a simple bitwise AND + of NSWindowStyleMaskBorderless here. */ + if ((style & ~(NSWindowStyleMaskResizable|NSWindowStyleMaskMiniaturizable)) == NSWindowStyleMaskBorderless) { window->flags |= SDL_WINDOW_BORDERLESS; } else { window->flags &= ~SDL_WINDOW_BORDERLESS; @@ -1434,30 +1701,38 @@ SetupWindowData(_THIS, SDL_Window * window, NSWindow *nswindow, SDL_bool created if ([nswindow isKeyWindow]) { window->flags |= SDL_WINDOW_INPUT_FOCUS; - SDL_SetKeyboardFocus(data->window); + SDL_SetKeyboardFocus(data.window); } + /* SDL_WindowData will be holding a strong reference to the NSWindow, and + * it will also call [NSWindow close] in DestroyWindow before releasing the + * NSWindow, so the extra release provided by releasedWhenClosed isn't + * necessary. */ + nswindow.releasedWhenClosed = NO; + /* Prevents the window's "window device" from being destroyed when it is * hidden. See http://www.mikeash.com/pyblog/nsopenglcontext-and-one-shot.html */ [nswindow setOneShot:NO]; /* All done! */ - window->driverdata = data; + window->driverdata = (void *)CFBridgingRetain(data); return 0; }} -int -Cocoa_CreateWindow(_THIS, SDL_Window * window) +int Cocoa_CreateWindow(_THIS, SDL_Window * window) { @autoreleasepool { - SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; + SDL_VideoData *videodata = (__bridge SDL_VideoData *) _this->driverdata; NSWindow *nswindow; SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); NSRect rect; SDL_Rect bounds; NSUInteger style; NSArray *screens = [NSScreen screens]; + NSScreen *screen = nil; + SDLView *contentView; + BOOL highdpi; Cocoa_GetDisplayBounds(_this, display, &bounds); rect.origin.x = window->x; @@ -1469,7 +1744,6 @@ Cocoa_CreateWindow(_THIS, SDL_Window * window) style = GetWindowStyle(window); /* Figure out which screen to place this window */ - NSScreen *screen = nil; for (NSScreen *candidate in screens) { NSRect screenRect = [candidate frame]; if (rect.origin.x >= screenRect.origin.x && @@ -1489,6 +1763,8 @@ Cocoa_CreateWindow(_THIS, SDL_Window * window) return SDL_SetError("%s", [[e reason] UTF8String]); } + [nswindow setColorSpace:[NSColorSpace sRGBColorSpace]]; + #if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200 /* Added in the 10.12.0 SDK. */ /* By default, don't allow users to make our window tabbed in 10.12 or later */ if ([nswindow respondsToSelector:@selector(setTabbingMode:)]) { @@ -1496,9 +1772,7 @@ Cocoa_CreateWindow(_THIS, SDL_Window * window) } #endif - if (videodata->allow_spaces) { - SDL_assert(floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6); - SDL_assert([nswindow respondsToSelector:@selector(toggleFullScreen:)]); + if (videodata.allow_spaces) { /* we put FULLSCREEN_DESKTOP windows in their own Space, without a toggle button or menubar, later */ if (window->flags & SDL_WINDOW_RESIZABLE) { /* resizable windows are Spaces-friendly: they get the "go fullscreen" toggle button on their titlebar. */ @@ -1512,7 +1786,7 @@ Cocoa_CreateWindow(_THIS, SDL_Window * window) /* Create a default view for this window */ rect = [nswindow contentRectForFrameRect:[nswindow frame]]; - SDLView *contentView = [[SDLView alloc] initWithFrame:rect]; + contentView = [[SDLView alloc] initWithFrame:rect]; [contentView setSDLWindow:window]; /* We still support OpenGL as long as Apple offers it, deprecated or not, so disable deprecation warnings about it. */ @@ -1522,16 +1796,14 @@ Cocoa_CreateWindow(_THIS, SDL_Window * window) #endif /* Note: as of the macOS 10.15 SDK, this defaults to YES instead of NO when * the NSHighResolutionCapable boolean is set in Info.plist. */ - if ([contentView respondsToSelector:@selector(setWantsBestResolutionOpenGLSurface:)]) { - BOOL highdpi = (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) != 0; - [contentView setWantsBestResolutionOpenGLSurface:highdpi]; - } + highdpi = (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) != 0; + [contentView setWantsBestResolutionOpenGLSurface:highdpi]; #ifdef __clang__ #pragma clang diagnostic pop #endif -#if SDL_VIDEO_OPENGL_ES2 -#if SDL_VIDEO_OPENGL_EGL +#ifdef SDL_VIDEO_OPENGL_ES2 +#ifdef SDL_VIDEO_OPENGL_EGL if ((window->flags & SDL_WINDOW_OPENGL) && _this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) { [contentView setWantsLayer:TRUE]; @@ -1539,21 +1811,19 @@ Cocoa_CreateWindow(_THIS, SDL_Window * window) #endif /* SDL_VIDEO_OPENGL_EGL */ #endif /* SDL_VIDEO_OPENGL_ES2 */ [nswindow setContentView:contentView]; - [contentView release]; - if (SetupWindowData(_this, window, nswindow, SDL_TRUE) < 0) { - [nswindow release]; + if (SetupWindowData(_this, window, nswindow, contentView, SDL_TRUE) < 0) { return -1; } if (!(window->flags & SDL_WINDOW_OPENGL)) { return 0; } - + /* The rest of this macro mess is for OpenGL or OpenGL ES windows */ -#if SDL_VIDEO_OPENGL_ES2 +#ifdef SDL_VIDEO_OPENGL_ES2 if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) { -#if SDL_VIDEO_OPENGL_EGL +#ifdef SDL_VIDEO_OPENGL_EGL if (Cocoa_GLES_SetupWindow(_this, window) < 0) { Cocoa_DestroyWindow(_this, window); return -1; @@ -1567,12 +1837,23 @@ Cocoa_CreateWindow(_THIS, SDL_Window * window) return 0; }} -int -Cocoa_CreateWindowFrom(_THIS, SDL_Window * window, const void *data) +int Cocoa_CreateWindowFrom(_THIS, SDL_Window * window, const void *data) { @autoreleasepool { - NSWindow *nswindow = (NSWindow *) data; + NSView* nsview = nil; + NSWindow *nswindow = nil; NSString *title; + BOOL highdpi; + + if ([(__bridge id)data isKindOfClass:[NSWindow class]]) { + nswindow = (__bridge NSWindow*)data; + nsview = [nswindow contentView]; + } else if ([(__bridge id)data isKindOfClass:[NSView class]]) { + nsview = (__bridge NSView*)data; + nswindow = [nsview window]; + } else { + SDL_assert(false); + } /* Query the title from the existing window */ title = [nswindow title]; @@ -1580,22 +1861,32 @@ Cocoa_CreateWindowFrom(_THIS, SDL_Window * window, const void *data) window->title = SDL_strdup([title UTF8String]); } - return SetupWindowData(_this, window, nswindow, SDL_FALSE); + /* We still support OpenGL as long as Apple offers it, deprecated or not, so disable deprecation warnings about it. */ + #ifdef __clang__ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-declarations" + #endif + /* Note: as of the macOS 10.15 SDK, this defaults to YES instead of NO when + * the NSHighResolutionCapable boolean is set in Info.plist. */ + highdpi = (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) != 0; + [nsview setWantsBestResolutionOpenGLSurface:highdpi]; + #ifdef __clang__ + #pragma clang diagnostic pop + #endif + + return SetupWindowData(_this, window, nswindow, nsview, SDL_FALSE); }} -void -Cocoa_SetWindowTitle(_THIS, SDL_Window * window) +void Cocoa_SetWindowTitle(_THIS, SDL_Window * window) { @autoreleasepool { const char *title = window->title ? window->title : ""; - NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow; + NSWindow *nswindow = ((__bridge SDL_WindowData *) window->driverdata).nswindow; NSString *string = [[NSString alloc] initWithUTF8String:title]; [nswindow setTitle:string]; - [string release]; }} -void -Cocoa_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon) +void Cocoa_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon) { @autoreleasepool { NSImage *nsimage = Cocoa_CreateImage(icon); @@ -1605,12 +1896,11 @@ Cocoa_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon) } }} -void -Cocoa_SetWindowPosition(_THIS, SDL_Window * window) +void Cocoa_SetWindowPosition(_THIS, SDL_Window * window) { @autoreleasepool { - SDL_WindowData *windata = (SDL_WindowData *) window->driverdata; - NSWindow *nswindow = windata->nswindow; + SDL_WindowData *windata = (__bridge SDL_WindowData *) window->driverdata; + NSWindow *nswindow = windata.nswindow; NSRect rect; Uint32 moveHack; @@ -1628,12 +1918,11 @@ Cocoa_SetWindowPosition(_THIS, SDL_Window * window) ScheduleContextUpdates(windata); }} -void -Cocoa_SetWindowSize(_THIS, SDL_Window * window) +void Cocoa_SetWindowSize(_THIS, SDL_Window * window) { @autoreleasepool { - SDL_WindowData *windata = (SDL_WindowData *) window->driverdata; - NSWindow *nswindow = windata->nswindow; + SDL_WindowData *windata = (__bridge SDL_WindowData *) window->driverdata; + NSWindow *nswindow = windata.nswindow; NSRect rect; Uint32 moveHack; @@ -1655,103 +1944,112 @@ Cocoa_SetWindowSize(_THIS, SDL_Window * window) ScheduleContextUpdates(windata); }} -void -Cocoa_SetWindowMinimumSize(_THIS, SDL_Window * window) +void Cocoa_SetWindowMinimumSize(_THIS, SDL_Window * window) { @autoreleasepool { - SDL_WindowData *windata = (SDL_WindowData *) window->driverdata; + SDL_WindowData *windata = (__bridge SDL_WindowData *) window->driverdata; NSSize minSize; minSize.width = window->min_w; minSize.height = window->min_h; - [windata->nswindow setContentMinSize:minSize]; + [windata.nswindow setContentMinSize:minSize]; }} -void -Cocoa_SetWindowMaximumSize(_THIS, SDL_Window * window) +void Cocoa_SetWindowMaximumSize(_THIS, SDL_Window * window) { @autoreleasepool { - SDL_WindowData *windata = (SDL_WindowData *) window->driverdata; + SDL_WindowData *windata = (__bridge SDL_WindowData *) window->driverdata; NSSize maxSize; maxSize.width = window->max_w; maxSize.height = window->max_h; - [windata->nswindow setContentMaxSize:maxSize]; + [windata.nswindow setContentMaxSize:maxSize]; }} -void -Cocoa_ShowWindow(_THIS, SDL_Window * window) +void Cocoa_GetWindowSizeInPixels(_THIS, SDL_Window * window, int *w, int *h) { @autoreleasepool { - SDL_WindowData *windowData = ((SDL_WindowData *) window->driverdata); - NSWindow *nswindow = windowData->nswindow; + SDL_WindowData *windata = (__bridge SDL_WindowData *) window->driverdata; + NSView *contentView = windata.sdlContentView; + NSRect viewport = [contentView bounds]; + + if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) { + /* This gives us the correct viewport for a Retina-enabled view. */ + viewport = [contentView convertRectToBacking:viewport]; + } + + *w = viewport.size.width; + *h = viewport.size.height; +}} + + +void Cocoa_ShowWindow(_THIS, SDL_Window * window) +{ @autoreleasepool +{ + SDL_WindowData *windowData = ((__bridge SDL_WindowData *) window->driverdata); + NSWindow *nswindow = windowData.nswindow; if (![nswindow isMiniaturized]) { - [windowData->listener pauseVisibleObservation]; + [windowData.listener pauseVisibleObservation]; [nswindow makeKeyAndOrderFront:nil]; - [windowData->listener resumeVisibleObservation]; + [windowData.listener resumeVisibleObservation]; } }} -void -Cocoa_HideWindow(_THIS, SDL_Window * window) +void Cocoa_HideWindow(_THIS, SDL_Window * window) { @autoreleasepool { - NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow; + NSWindow *nswindow = ((__bridge SDL_WindowData *) window->driverdata).nswindow; [nswindow orderOut:nil]; }} -void -Cocoa_RaiseWindow(_THIS, SDL_Window * window) +void Cocoa_RaiseWindow(_THIS, SDL_Window * window) { @autoreleasepool { - SDL_WindowData *windowData = ((SDL_WindowData *) window->driverdata); - NSWindow *nswindow = windowData->nswindow; + SDL_WindowData *windowData = ((__bridge SDL_WindowData *) window->driverdata); + NSWindow *nswindow = windowData.nswindow; /* makeKeyAndOrderFront: has the side-effect of deminiaturizing and showing a minimized or hidden window, so check for that before showing it. */ - [windowData->listener pauseVisibleObservation]; + [windowData.listener pauseVisibleObservation]; if (![nswindow isMiniaturized] && [nswindow isVisible]) { [NSApp activateIgnoringOtherApps:YES]; [nswindow makeKeyAndOrderFront:nil]; } - [windowData->listener resumeVisibleObservation]; + [windowData.listener resumeVisibleObservation]; }} -void -Cocoa_MaximizeWindow(_THIS, SDL_Window * window) +void Cocoa_MaximizeWindow(_THIS, SDL_Window * window) { @autoreleasepool { - SDL_WindowData *windata = (SDL_WindowData *) window->driverdata; - NSWindow *nswindow = windata->nswindow; + SDL_WindowData *windata = (__bridge SDL_WindowData *) window->driverdata; + NSWindow *nswindow = windata.nswindow; [nswindow zoom:nil]; ScheduleContextUpdates(windata); }} -void -Cocoa_MinimizeWindow(_THIS, SDL_Window * window) +void Cocoa_MinimizeWindow(_THIS, SDL_Window * window) { @autoreleasepool { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - NSWindow *nswindow = data->nswindow; - if ([data->listener isInFullscreenSpaceTransition]) { - [data->listener addPendingWindowOperation:PENDING_OPERATION_MINIMIZE]; + SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata; + NSWindow *nswindow = data.nswindow; + if ([data.listener isInFullscreenSpaceTransition]) { + [data.listener addPendingWindowOperation:PENDING_OPERATION_MINIMIZE]; } else { [nswindow miniaturize:nil]; } }} -void -Cocoa_RestoreWindow(_THIS, SDL_Window * window) +void Cocoa_RestoreWindow(_THIS, SDL_Window * window) { @autoreleasepool { - NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow; + NSWindow *nswindow = ((__bridge SDL_WindowData *) window->driverdata).nswindow; if ([nswindow isMiniaturized]) { [nswindow deminiaturize:nil]; @@ -1760,8 +2058,7 @@ Cocoa_RestoreWindow(_THIS, SDL_Window * window) } }} -void -Cocoa_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered) +void Cocoa_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered) { @autoreleasepool { if (SetWindowStyle(window, GetWindowStyle(window))) { @@ -1771,32 +2068,51 @@ Cocoa_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered) } }} -void -Cocoa_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable) +void Cocoa_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable) { @autoreleasepool { /* Don't set this if we're in a space! * The window will get permanently stuck if resizable is false. * -flibit */ - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - Cocoa_WindowListener *listener = data->listener; + SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata; + Cocoa_WindowListener *listener = data.listener; + NSWindow *nswindow = data.nswindow; + SDL_VideoData *videodata = data.videodata; if (![listener isInFullscreenSpace]) { SetWindowStyle(window, GetWindowStyle(window)); } + if (videodata.allow_spaces) { + if (resizable) { + /* resizable windows are Spaces-friendly: they get the "go fullscreen" toggle button on their titlebar. */ + [nswindow setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; + } else { + [nswindow setCollectionBehavior:NSWindowCollectionBehaviorManaged]; + } + } }} -void -Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen) +void Cocoa_SetWindowAlwaysOnTop(_THIS, SDL_Window * window, SDL_bool on_top) +{ @autoreleasepool + { + NSWindow *nswindow = ((__bridge SDL_WindowData *) window->driverdata).nswindow; + if (on_top) { + [nswindow setLevel:NSFloatingWindowLevel]; + } else { + [nswindow setLevel:kCGNormalWindowLevel]; + } + }} + +void Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen) { @autoreleasepool { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - NSWindow *nswindow = data->nswindow; + SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata; + NSWindow *nswindow = data.nswindow; NSRect rect; /* The view responder chain gets messed with during setStyleMask */ - if ([[nswindow contentView] nextResponder] == data->listener) { - [[nswindow contentView] setNextResponder:nil]; + if ([data.sdlContentView nextResponder] == data.listener) { + [data.sdlContentView setNextResponder:nil]; } if (fullscreen) { @@ -1812,10 +2128,7 @@ Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display /* Hack to fix origin on Mac OS X 10.4 This is no longer needed as of Mac OS X 10.15, according to bug 4822. */ - NSProcessInfo *processInfo = [NSProcessInfo processInfo]; - NSOperatingSystemVersion version = { 10, 15, 0 }; - if (![processInfo respondsToSelector:@selector(isOperatingSystemAtLeastVersion:)] || - ![processInfo isOperatingSystemAtLeastVersion:version]) { + if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_14) { NSRect screenRect = [[nswindow screen] frame]; if (screenRect.size.height >= 1.0f) { rect.origin.y += (screenRect.size.height - rect.size.height); @@ -1824,6 +2137,7 @@ Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display [nswindow setStyleMask:NSWindowStyleMaskBorderless]; } else { + NSRect frameRect; rect.origin.x = window->windowed.x; rect.origin.y = window->windowed.y; rect.size.width = window->windowed.w; @@ -1839,14 +2153,14 @@ Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display [nswindow setStyleMask:GetWindowWindowedStyle(window)]; /* Hack to restore window decorations on Mac OS X 10.10 */ - NSRect frameRect = [nswindow frame]; + frameRect = [nswindow frame]; [nswindow setFrame:NSMakeRect(frameRect.origin.x, frameRect.origin.y, frameRect.size.width + 1, frameRect.size.height) display:NO]; [nswindow setFrame:frameRect display:NO]; } /* The view responder chain gets messed with during setStyleMask */ - if ([[nswindow contentView] nextResponder] != data->listener) { - [[nswindow contentView] setNextResponder:data->listener]; + if ([data.sdlContentView nextResponder] != data.listener) { + [data.sdlContentView setNextResponder:data.listener]; } s_moveHack = 0; @@ -1869,16 +2183,16 @@ Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display } if ([nswindow isVisible] || fullscreen) { - [data->listener pauseVisibleObservation]; + [data.listener pauseVisibleObservation]; [nswindow makeKeyAndOrderFront:nil]; - [data->listener resumeVisibleObservation]; + [data.listener resumeVisibleObservation]; } ScheduleContextUpdates(data); }} -int -Cocoa_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp) +int Cocoa_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp) +{ @autoreleasepool { SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); CGDirectDisplayID display_id = ((SDL_DisplayData *)display->driverdata)->display; @@ -1901,10 +2215,83 @@ Cocoa_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp) return SDL_SetError("CGSetDisplayTransferByTable()"); } return 0; -} +}} -int -Cocoa_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp) +void *Cocoa_GetWindowICCProfile(_THIS, SDL_Window * window, size_t * size) +{ @autoreleasepool +{ + SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata; + NSWindow *nswindow = data.nswindow; + NSScreen *screen = [nswindow screen]; + NSData* iccProfileData = nil; + void* retIccProfileData = NULL; + + if (screen == nil) { + SDL_SetError("Could not get screen of window."); + return NULL; + } + + if ([screen colorSpace] == nil) { + SDL_SetError("Could not get colorspace information of screen."); + return NULL; + } + + iccProfileData = [[screen colorSpace] ICCProfileData]; + if (iccProfileData == nil) { + SDL_SetError("Could not get ICC profile data."); + return NULL; + } + + retIccProfileData = SDL_malloc([iccProfileData length]); + if (!retIccProfileData) { + SDL_OutOfMemory(); + return NULL; + } + + [iccProfileData getBytes:retIccProfileData length:[iccProfileData length]]; + *size = [iccProfileData length]; + return retIccProfileData; +}} + +int Cocoa_GetWindowDisplayIndex(_THIS, SDL_Window * window) +{ @autoreleasepool +{ + NSScreen *screen; + SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata; + + /* Not recognized via CHECK_WINDOW_MAGIC */ + if (data == nil) { + /* Don't set the error here, it hides other errors and is ignored anyway */ + /*return SDL_SetError("Window data not set");*/ + return -1; + } + + /* NSWindow.screen may be nil when the window is off-screen. */ + screen = data.nswindow.screen; + + if (screen != nil) { + CGDirectDisplayID displayid; + int i; + + /* https://developer.apple.com/documentation/appkit/nsscreen/1388360-devicedescription?language=objc */ + displayid = [[screen.deviceDescription objectForKey:@"NSScreenNumber"] unsignedIntValue]; + + for (i = 0; i < _this->num_displays; i++) { + SDL_DisplayData *displaydata = (SDL_DisplayData *)_this->displays[i].driverdata; + if (displaydata != NULL && displaydata->display == displayid) { + return i; + } + } + } + + /* Other code may expect SDL_GetWindowDisplayIndex to always return a valid + * index for a window. The higher level GetWindowDisplayIndex code will fall + * back to a generic position-based query if the backend implementation + * fails. */ + return SDL_SetError("Couldn't find the display where the window is located."); +}} + +int Cocoa_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp) { SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); CGDirectDisplayID display_id = ((SDL_DisplayData *)display->driverdata)->display; @@ -1927,115 +2314,109 @@ Cocoa_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp) return 0; } -void -Cocoa_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed) +void Cocoa_SetWindowMouseRect(_THIS, SDL_Window * window) { - SDL_Mouse *mouse = SDL_GetMouse(); - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - - /* Enable or disable the event tap as necessary */ - Cocoa_EnableMouseEventTap(mouse->driverdata, grabbed); - - /* Move the cursor to the nearest point in the window */ - if (grabbed && data && ![data->listener isMoving]) { - int x, y; - CGPoint cgpoint; - - SDL_GetMouseState(&x, &y); - cgpoint.x = window->x + x; - cgpoint.y = window->y + y; - - Cocoa_HandleMouseWarp(cgpoint.x, cgpoint.y); - - DLog("Returning cursor to (%g, %g)", cgpoint.x, cgpoint.y); - CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, cgpoint); - } - - if ( data && (window->flags & SDL_WINDOW_FULLSCREEN) ) { - if (SDL_ShouldAllowTopmost() && (window->flags & SDL_WINDOW_INPUT_FOCUS) - && ![data->listener isInFullscreenSpace]) { - /* OpenGL is rendering to the window, so make it visible! */ - /* Doing this in 10.11 while in a Space breaks things (bug #3152) */ - [data->nswindow setLevel:CGShieldingWindowLevel()]; - } else if (window->flags & SDL_WINDOW_ALWAYS_ON_TOP) { - [data->nswindow setLevel:NSFloatingWindowLevel]; - } else { - [data->nswindow setLevel:kCGNormalWindowLevel]; - } - } + Cocoa_UpdateClipCursor(window); } -void -Cocoa_DestroyWindow(_THIS, SDL_Window * window) +void Cocoa_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed) { @autoreleasepool { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata; + + Cocoa_UpdateClipCursor(window); + + if (data && (window->flags & SDL_WINDOW_FULLSCREEN)) { + if (SDL_ShouldAllowTopmost() && (window->flags & SDL_WINDOW_INPUT_FOCUS) + && ![data.listener isInFullscreenSpace]) { + /* OpenGL is rendering to the window, so make it visible! */ + /* Doing this in 10.11 while in a Space breaks things (bug #3152) */ + [data.nswindow setLevel:CGShieldingWindowLevel()]; + } else if (window->flags & SDL_WINDOW_ALWAYS_ON_TOP) { + [data.nswindow setLevel:NSFloatingWindowLevel]; + } else { + [data.nswindow setLevel:kCGNormalWindowLevel]; + } + } +}} + +void Cocoa_DestroyWindow(_THIS, SDL_Window * window) +{ @autoreleasepool +{ + SDL_WindowData *data = (SDL_WindowData *) CFBridgingRelease(window->driverdata); if (data) { - if ([data->listener isInFullscreenSpace]) { + NSArray *contexts; + if ([data.listener isInFullscreenSpace]) { [NSMenu setMenuBarVisible:YES]; } - [data->listener close]; - [data->listener release]; - if (data->created) { + [data.listener close]; + data.listener = nil; + if (data.created) { /* Release the content view to avoid further updateLayer callbacks */ - [data->nswindow setContentView:nil]; - [data->nswindow close]; + [data.nswindow setContentView:nil]; + [data.nswindow close]; } - NSArray *contexts = [[data->nscontexts copy] autorelease]; + #ifdef SDL_VIDEO_OPENGL + + contexts = [data.nscontexts copy]; for (SDLOpenGLContext *context in contexts) { - /* Calling setWindow:NULL causes the context to remove itself from the context list. */ + /* Calling setWindow:NULL causes the context to remove itself from the context list. */ [context setWindow:NULL]; } - [data->nscontexts release]; - SDL_free(data); + #endif /* SDL_VIDEO_OPENGL */ + + if (window->shaper) { + CFBridgingRelease(window->shaper->driverdata); + SDL_free(window->shaper); + window->shaper = NULL; + } } window->driverdata = NULL; }} -SDL_bool -Cocoa_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info) +SDL_bool Cocoa_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info) +{ @autoreleasepool { - NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow; + NSWindow *nswindow = ((__bridge SDL_WindowData *) window->driverdata).nswindow; if (info->version.major <= SDL_MAJOR_VERSION) { info->subsystem = SDL_SYSWM_COCOA; info->info.cocoa.window = nswindow; return SDL_TRUE; } else { - SDL_SetError("Application not compiled with SDL %d.%d", - SDL_MAJOR_VERSION, SDL_MINOR_VERSION); + SDL_SetError("Application not compiled with SDL %d", + SDL_MAJOR_VERSION); return SDL_FALSE; } -} +}} -SDL_bool -Cocoa_IsWindowInFullscreenSpace(SDL_Window * window) +SDL_bool Cocoa_IsWindowInFullscreenSpace(SDL_Window * window) +{ @autoreleasepool { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata; - if ([data->listener isInFullscreenSpace]) { + if ([data.listener isInFullscreenSpace]) { return SDL_TRUE; } else { return SDL_FALSE; } -} +}} -SDL_bool -Cocoa_SetWindowFullscreenSpace(SDL_Window * window, SDL_bool state) +SDL_bool Cocoa_SetWindowFullscreenSpace(SDL_Window * window, SDL_bool state) { @autoreleasepool { SDL_bool succeeded = SDL_FALSE; - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata; - if (data->inWindowFullscreenTransition) { + if (data.inWindowFullscreenTransition) { return SDL_FALSE; } - data->inWindowFullscreenTransition = SDL_TRUE; - if ([data->listener setFullscreenSpace:(state ? YES : NO)]) { + data.inWindowFullscreenTransition = SDL_TRUE; + if ([data.listener setFullscreenSpace:(state ? YES : NO)]) { const int maxattempts = 3; int attempt = 0; while (++attempt <= maxattempts) { @@ -2044,7 +2425,7 @@ Cocoa_SetWindowFullscreenSpace(SDL_Window * window, SDL_bool state) */ const int limit = 10000; int count = 0; - while ([data->listener isInFullscreenSpaceTransition]) { + while ([data.listener isInFullscreenSpaceTransition]) { if ( ++count == limit ) { /* Uh oh, transition isn't completing. Should we assert? */ break; @@ -2052,44 +2433,70 @@ Cocoa_SetWindowFullscreenSpace(SDL_Window * window, SDL_bool state) SDL_Delay(1); SDL_PumpEvents(); } - if ([data->listener isInFullscreenSpace] == (state ? YES : NO)) + if ([data.listener isInFullscreenSpace] == (state ? YES : NO)) break; /* Try again, the last attempt was interrupted by user gestures */ - if (![data->listener setFullscreenSpace:(state ? YES : NO)]) + if (![data.listener setFullscreenSpace:(state ? YES : NO)]) break; /* ??? */ } /* Return TRUE to prevent non-space fullscreen logic from running */ succeeded = SDL_TRUE; } - data->inWindowFullscreenTransition = SDL_FALSE; + data.inWindowFullscreenTransition = SDL_FALSE; return succeeded; }} -int -Cocoa_SetWindowHitTest(SDL_Window * window, SDL_bool enabled) +int Cocoa_SetWindowHitTest(SDL_Window * window, SDL_bool enabled) { return 0; /* just succeed, the real work is done elsewhere. */ } -void -Cocoa_AcceptDragAndDrop(SDL_Window * window, SDL_bool accept) +void Cocoa_AcceptDragAndDrop(SDL_Window * window, SDL_bool accept) +{ @autoreleasepool { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata; if (accept) { - [data->nswindow registerForDraggedTypes:[NSArray arrayWithObject:(NSString *)kUTTypeFileURL]]; + [data.nswindow registerForDraggedTypes:[NSArray arrayWithObject:(NSString *)kUTTypeFileURL]]; } else { - [data->nswindow unregisterDraggedTypes]; + [data.nswindow unregisterDraggedTypes]; } -} +}} -int -Cocoa_SetWindowOpacity(_THIS, SDL_Window * window, float opacity) +int Cocoa_FlashWindow(_THIS, SDL_Window *window, SDL_FlashOperation operation) +{ @autoreleasepool { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - [data->nswindow setAlphaValue:opacity]; + /* Note that this is app-wide and not window-specific! */ + SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata; + + if (data.flash_request) { + [NSApp cancelUserAttentionRequest:data.flash_request]; + data.flash_request = 0; + } + + switch (operation) { + case SDL_FLASH_CANCEL: + /* Canceled above */ + break; + case SDL_FLASH_BRIEFLY: + data.flash_request = [NSApp requestUserAttention:NSInformationalRequest]; + break; + case SDL_FLASH_UNTIL_FOCUSED: + data.flash_request = [NSApp requestUserAttention:NSCriticalRequest]; + break; + default: + return SDL_Unsupported(); + } return 0; -} +}} + +int Cocoa_SetWindowOpacity(_THIS, SDL_Window * window, float opacity) +{ @autoreleasepool +{ + SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata; + [data.nswindow setAlphaValue:opacity]; + return 0; +}} #endif /* SDL_VIDEO_DRIVER_COCOA */ diff --git a/SDL2-2.0.12/src/video/directfb/SDL_DirectFB_WM.c b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_WM.c similarity index 89% rename from SDL2-2.0.12/src/video/directfb/SDL_DirectFB_WM.c rename to SDL2-2.30.5/src/video/directfb/SDL_DirectFB_WM.c index bb9acb1..d32ab5d 100644 --- a/SDL2-2.0.12/src/video/directfb/SDL_DirectFB_WM.c +++ b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_WM.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_DIRECTFB +#ifdef SDL_VIDEO_DRIVER_DIRECTFB #include "SDL_DirectFB_video.h" #include "SDL_DirectFB_window.h" @@ -51,8 +51,7 @@ static DFB_Theme theme_none = { NULL }; -static void -DrawTriangle(IDirectFBSurface * s, int down, int x, int y, int w) +static void DrawTriangle(IDirectFBSurface * s, int down, int x, int y, int w) { int x1, x2, x3; int y1, y2, y3; @@ -75,19 +74,18 @@ DrawTriangle(IDirectFBSurface * s, int down, int x, int y, int w) s->FillTriangle(s, x1, y1, x2, y2, x3, y3); } -static void -LoadFont(_THIS, SDL_Window * window) +static void LoadFont(_THIS, SDL_Window * window) { SDL_DFB_DEVICEDATA(_this); SDL_DFB_WINDOWDATA(window); - if (windata->font != NULL) { + if (windata->font) { SDL_DFB_RELEASE(windata->font); windata->font = NULL; SDL_DFB_CHECK(windata->window_surface->SetFont(windata->window_surface, windata->font)); } - if (windata->theme.font != NULL) + if (windata->theme.font) { DFBFontDescription fdesc; @@ -101,8 +99,7 @@ LoadFont(_THIS, SDL_Window * window) } } -static void -DrawCraption(_THIS, IDirectFBSurface * s, int x, int y, char *text) +static void DrawCraption(_THIS, IDirectFBSurface * s, int x, int y, char *text) { DFBSurfaceTextFlags flags; @@ -111,8 +108,7 @@ DrawCraption(_THIS, IDirectFBSurface * s, int x, int y, char *text) s->DrawString(s, text, -1, x, y, flags); } -void -DirectFB_WM_RedrawLayout(_THIS, SDL_Window * window) +void DirectFB_WM_RedrawLayout(_THIS, SDL_Window * window) { SDL_DFB_WINDOWDATA(window); IDirectFBSurface *s = windata->window_surface; @@ -180,8 +176,7 @@ DirectFB_WM_RedrawLayout(_THIS, SDL_Window * window) windata->wm_needs_redraw = 0; } -DFBResult -DirectFB_WM_GetClientSize(_THIS, SDL_Window * window, int *cw, int *ch) +DFBResult DirectFB_WM_GetClientSize(_THIS, SDL_Window * window, int *cw, int *ch) { SDL_DFB_WINDOWDATA(window); IDirectFBWindow *dfbwin = windata->dfbwin; @@ -195,8 +190,7 @@ DirectFB_WM_GetClientSize(_THIS, SDL_Window * window, int *cw, int *ch) return DFB_OK; } -void -DirectFB_WM_AdjustWindowLayout(SDL_Window * window, int flags, int w, int h) +void DirectFB_WM_AdjustWindowLayout(SDL_Window * window, int flags, int w, int h) { SDL_DFB_WINDOWDATA(window); @@ -241,8 +235,7 @@ enum WM_POS_BOTTOM = 0x40, }; -static int -WMIsClient(DFB_WindowData * p, int x, int y) +static int WMIsClient(DFB_WindowData * p, int x, int y) { x -= p->client.x; y -= p->client.y; @@ -253,8 +246,7 @@ WMIsClient(DFB_WindowData * p, int x, int y) return 1; } -static int -WMPos(DFB_WindowData * p, int x, int y) +static int WMPos(DFB_WindowData * p, int x, int y) { int pos = WM_POS_NONE; @@ -284,12 +276,10 @@ WMPos(DFB_WindowData * p, int x, int y) return pos; } -int -DirectFB_WM_ProcessEvent(_THIS, SDL_Window * window, DFBWindowEvent * evt) +int DirectFB_WM_ProcessEvent(_THIS, SDL_Window * window, DFBWindowEvent * evt) { - SDL_DFB_DEVICEDATA(_this); SDL_DFB_WINDOWDATA(window); - DFB_WindowData *gwindata = ((devdata->grabbed_window) ? (DFB_WindowData *) ((devdata->grabbed_window)->driverdata) : NULL); + SDL_Window *grabbed_window = SDL_GetGrabbedWindow(); IDirectFBWindow *dfbwin = windata->dfbwin; DFBWindowOptions wopts; @@ -324,12 +314,12 @@ DirectFB_WM_ProcessEvent(_THIS, SDL_Window * window, DFBWindowEvent * evt) } if (window->flags & SDL_WINDOW_MAXIMIZED) return 1; - /* fall through */ + SDL_FALLTHROUGH; default: windata->wm_grab = pos; - if (gwindata != NULL) - SDL_DFB_CHECK(gwindata->dfbwin->UngrabPointer(gwindata->dfbwin)); - SDL_DFB_CHECK(dfbwin->GrabPointer(dfbwin)); + if (grabbed_window) + DirectFB_SetWindowMouseGrab(_this, grabbed_window, SDL_FALSE); + DirectFB_SetWindowMouseGrab(_this, window, SDL_TRUE); windata->wm_lastx = evt->cx; windata->wm_lasty = evt->cy; } @@ -359,9 +349,9 @@ DirectFB_WM_ProcessEvent(_THIS, SDL_Window * window, DFBWindowEvent * evt) SDL_DFB_CHECK(dfbwin->Resize(dfbwin, cw + dx, ch + dy)); } } - SDL_DFB_CHECK(dfbwin->UngrabPointer(dfbwin)); - if (gwindata != NULL) - SDL_DFB_CHECK(gwindata->dfbwin->GrabPointer(gwindata->dfbwin)); + DirectFB_SetWindowMouseGrab(_this, window, SDL_FALSE); + if (grabbed_window) + DirectFB_SetWindowMouseGrab(_this, grabbed_window, SDL_TRUE); windata->wm_grab = WM_POS_NONE; return 1; } diff --git a/SDL2-2.0.12/src/video/directfb/SDL_DirectFB_WM.h b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_WM.h similarity index 96% rename from SDL2-2.0.12/src/video/directfb/SDL_DirectFB_WM.h rename to SDL2-2.30.5/src/video/directfb/SDL_DirectFB_WM.h index 965081f..d373ee6 100644 --- a/SDL2-2.0.12/src/video/directfb/SDL_DirectFB_WM.h +++ b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_WM.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/video/directfb/SDL_DirectFB_dyn.c b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_dyn.c similarity index 92% rename from SDL2-2.0.12/src/video/directfb/SDL_DirectFB_dyn.c rename to SDL2-2.30.5/src/video/directfb/SDL_DirectFB_dyn.c index 94626af..b4c734a 100644 --- a/SDL2-2.0.12/src/video/directfb/SDL_DirectFB_dyn.c +++ b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_dyn.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_DIRECTFB +#ifdef SDL_VIDEO_DRIVER_DIRECTFB #include "SDL_DirectFB_video.h" #include "SDL_DirectFB_dyn.h" @@ -45,8 +45,7 @@ DFB_SYMS static void *handle = NULL; -int -SDL_DirectFB_LoadLibrary(void) +int SDL_DirectFB_LoadLibrary(void) { int retval = 0; @@ -92,26 +91,25 @@ SDL_DirectFB_LoadLibrary(void) return retval; } -void -SDL_DirectFB_UnLoadLibrary(void) +void SDL_DirectFB_UnLoadLibrary(void) { - if (handle != NULL) { + if (handle) { SDL_UnloadObject(handle); handle = NULL; } } #else -int -SDL_DirectFB_LoadLibrary(void) + +int SDL_DirectFB_LoadLibrary(void) { return 1; } -void -SDL_DirectFB_UnLoadLibrary(void) +void SDL_DirectFB_UnLoadLibrary(void) { } + #endif #endif /* SDL_VIDEO_DRIVER_DIRECTFB */ diff --git a/SDL2-2.0.12/src/video/directfb/SDL_DirectFB_dyn.h b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_dyn.h similarity index 97% rename from SDL2-2.0.12/src/video/directfb/SDL_DirectFB_dyn.h rename to SDL2-2.30.5/src/video/directfb/SDL_DirectFB_dyn.h index f067245..dc08d98 100644 --- a/SDL2-2.0.12/src/video/directfb/SDL_DirectFB_dyn.h +++ b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_dyn.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/video/directfb/SDL_DirectFB_events.c b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_events.c similarity index 89% rename from SDL2-2.0.12/src/video/directfb/SDL_DirectFB_events.c rename to SDL2-2.30.5/src/video/directfb/SDL_DirectFB_events.c index 251d697..1b2d654 100644 --- a/SDL2-2.0.12/src/video/directfb/SDL_DirectFB_events.c +++ b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_events.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_DIRECTFB +#ifdef SDL_VIDEO_DRIVER_DIRECTFB /* Handle the event stream, converting DirectFB input events into SDL events */ @@ -34,8 +34,7 @@ #include "../../events/SDL_keyboard_c.h" #include "../../events/SDL_windowevents_c.h" #include "../../events/SDL_events_c.h" -#include "../../events/scancodes_linux.h" -#include "../../events/scancodes_xfree86.h" +#include "../../events/SDL_scancode_tables_c.h" #include "SDL_DirectFB_events.h" @@ -92,8 +91,7 @@ static void UnicodeToUtf8( Uint16 w , char *utf8buf) } } -static void -FocusAllMice(_THIS, SDL_Window *window) +static void FocusAllMice(_THIS, SDL_Window *window) { #if USE_MULTI_API SDL_DFB_DEVICEDATA(_this); @@ -107,8 +105,7 @@ FocusAllMice(_THIS, SDL_Window *window) } -static void -FocusAllKeyboards(_THIS, SDL_Window *window) +static void FocusAllKeyboards(_THIS, SDL_Window *window) { #if USE_MULTI_API SDL_DFB_DEVICEDATA(_this); @@ -121,8 +118,7 @@ FocusAllKeyboards(_THIS, SDL_Window *window) #endif } -static void -MotionAllMice(_THIS, int x, int y) +static void MotionAllMice(_THIS, int x, int y) { #if USE_MULTI_API SDL_DFB_DEVICEDATA(_this); @@ -137,8 +133,7 @@ MotionAllMice(_THIS, int x, int y) #endif } -static int -KbdIndex(_THIS, int id) +static int KbdIndex(_THIS, int id) { SDL_DFB_DEVICEDATA(_this); int index; @@ -150,8 +145,7 @@ KbdIndex(_THIS, int id) return -1; } -static int -ClientXY(DFB_WindowData * p, int *x, int *y) +static int ClientXY(DFB_WindowData * p, int *x, int *y) { int cx, cy; @@ -170,8 +164,7 @@ ClientXY(DFB_WindowData * p, int *x, int *y) return 1; } -static void -ProcessWindowEvent(_THIS, SDL_Window *sdlwin, DFBWindowEvent * evt) +static void ProcessWindowEvent(_THIS, SDL_Window *sdlwin, DFBWindowEvent * evt) { SDL_DFB_DEVICEDATA(_this); SDL_DFB_WINDOWDATA(sdlwin); @@ -212,7 +205,7 @@ ProcessWindowEvent(_THIS, SDL_Window *sdlwin, DFBWindowEvent * evt) case DWET_MOTION: if (ClientXY(windata, &evt->x, &evt->y)) { if (!devdata->use_linux_input) { - if (!(sdlwin->flags & SDL_WINDOW_INPUT_GRABBED)) + if (!(sdlwin->flags & SDL_WINDOW_MOUSE_GRABBED)) SDL_SendMouseMotion_ex(sdlwin, devdata->mouse_id[0], 0, evt->x, evt->y, 0); } else { @@ -261,7 +254,7 @@ ProcessWindowEvent(_THIS, SDL_Window *sdlwin, DFBWindowEvent * evt) SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_MOVED, evt->x, evt->y); } - /* fall throught */ + SDL_FALLTHROUGH; case DWET_SIZE: /* FIXME: what about < 0 */ evt->w -= (windata->theme.right_size + windata->theme.left_size); @@ -304,23 +297,23 @@ ProcessWindowEvent(_THIS, SDL_Window *sdlwin, DFBWindowEvent * evt) printf("Event Clazz %d\n", evt->clazz); } -static void -ProcessInputEvent(_THIS, DFBInputEvent * ievt) +static void ProcessInputEvent(_THIS, DFBInputEvent * ievt) { SDL_DFB_DEVICEDATA(_this); SDL_Keysym keysym; int kbd_idx; Uint32 unicode; char text[SDL_TEXTINPUTEVENT_TEXT_SIZE]; + SDL_Window* grabbed_window = SDL_GetGrabbedWindow(); if (!devdata->use_linux_input) { if (ievt->type == DIET_AXISMOTION) { - if ((devdata->grabbed_window != NULL) && (ievt->flags & DIEF_AXISREL)) { + if ((grabbed_window) && (ievt->flags & DIEF_AXISREL)) { if (ievt->axis == DIAI_X) - SDL_SendMouseMotion_ex(devdata->grabbed_window, ievt->device_id, 1, + SDL_SendMouseMotion_ex(grabbed_window, ievt->device_id, 1, ievt->axisrel, 0, 0); else if (ievt->axis == DIAI_Y) - SDL_SendMouseMotion_ex(devdata->grabbed_window, ievt->device_id, 1, 0, + SDL_SendMouseMotion_ex(grabbed_window, ievt->device_id, 1, 0, ievt->axisrel, 0); } } @@ -339,7 +332,7 @@ ProcessInputEvent(_THIS, DFBInputEvent * ievt) SDL_Mouse *mouse = SDL_GetMouse(ievt->device_id); SDL_Window *window = SDL_GetWindowFromID(mouse->focus); #else - SDL_Window *window = devdata->grabbed_window; + SDL_Window *window = grabbed_window; #endif if (window) { DFB_WindowData *windata = @@ -359,10 +352,10 @@ ProcessInputEvent(_THIS, DFBInputEvent * ievt) } } else if (ievt->flags & DIEF_AXISREL) { if (ievt->axis == DIAI_X) - SDL_SendMouseMotion_ex(devdata->grabbed_window, ievt->device_id, 1, + SDL_SendMouseMotion_ex(grabbed_window, ievt->device_id, 1, ievt->axisrel, 0, 0); else if (ievt->axis == DIAI_Y) - SDL_SendMouseMotion_ex(devdata->grabbed_window, ievt->device_id, 1, 0, + SDL_SendMouseMotion_ex(grabbed_window, ievt->device_id, 1, 0, ievt->axisrel, 0); } break; @@ -386,19 +379,19 @@ ProcessInputEvent(_THIS, DFBInputEvent * ievt) break; case DIET_BUTTONPRESS: if (ievt->buttons & DIBM_LEFT) - SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_PRESSED, 1); + SDL_SendMouseButton_ex(grabbed_window, ievt->device_id, SDL_PRESSED, 1); if (ievt->buttons & DIBM_MIDDLE) - SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_PRESSED, 2); + SDL_SendMouseButton_ex(grabbed_window, ievt->device_id, SDL_PRESSED, 2); if (ievt->buttons & DIBM_RIGHT) - SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_PRESSED, 3); + SDL_SendMouseButton_ex(grabbed_window, ievt->device_id, SDL_PRESSED, 3); break; case DIET_BUTTONRELEASE: if (!(ievt->buttons & DIBM_LEFT)) - SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_RELEASED, 1); + SDL_SendMouseButton_ex(grabbed_window, ievt->device_id, SDL_RELEASED, 1); if (!(ievt->buttons & DIBM_MIDDLE)) - SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_RELEASED, 2); + SDL_SendMouseButton_ex(grabbed_window, ievt->device_id, SDL_RELEASED, 2); if (!(ievt->buttons & DIBM_RIGHT)) - SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_RELEASED, 3); + SDL_SendMouseButton_ex(grabbed_window, ievt->device_id, SDL_RELEASED, 3); break; default: break; /* please gcc */ @@ -406,14 +399,13 @@ ProcessInputEvent(_THIS, DFBInputEvent * ievt) } } -void -DirectFB_PumpEventsWindow(_THIS) +void DirectFB_PumpEventsWindow(_THIS) { SDL_DFB_DEVICEDATA(_this); DFBInputEvent ievt; SDL_Window *w; - for (w = devdata->firstwin; w != NULL; w = w->next) { + for (w = devdata->firstwin; w; w = w->next) { SDL_DFB_WINDOWDATA(w); DFBWindowEvent evt; @@ -448,8 +440,7 @@ DirectFB_PumpEventsWindow(_THIS) } } -void -DirectFB_InitOSKeymap(_THIS, SDL_Scancode * keymap, int numkeys) +void DirectFB_InitOSKeymap(_THIS, SDL_Scancode * keymap, int numkeys) { int i; @@ -576,8 +567,7 @@ DirectFB_InitOSKeymap(_THIS, SDL_Scancode * keymap, int numkeys) } -static SDL_Keysym * -DirectFB_TranslateKey(_THIS, DFBWindowEvent * evt, SDL_Keysym * keysym, Uint32 *unicode) +static SDL_Keysym *DirectFB_TranslateKey(_THIS, DFBWindowEvent * evt, SDL_Keysym * keysym, Uint32 *unicode) { SDL_DFB_DEVICEDATA(_this); int kbd_idx = 0; /* Window events lag the device source KbdIndex(_this, evt->device_id); */ @@ -606,8 +596,7 @@ DirectFB_TranslateKey(_THIS, DFBWindowEvent * evt, SDL_Keysym * keysym, Uint32 * return keysym; } -static SDL_Keysym * -DirectFB_TranslateKeyInputEvent(_THIS, DFBInputEvent * evt, +static SDL_Keysym *DirectFB_TranslateKeyInputEvent(_THIS, DFBInputEvent * evt, SDL_Keysym * keysym, Uint32 *unicode) { SDL_DFB_DEVICEDATA(_this); @@ -636,8 +625,7 @@ DirectFB_TranslateKeyInputEvent(_THIS, DFBInputEvent * evt, return keysym; } -static int -DirectFB_TranslateButton(DFBInputDeviceButtonIdentifier button) +static int DirectFB_TranslateButton(DFBInputDeviceButtonIdentifier button) { switch (button) { case DIBI_LEFT: @@ -651,16 +639,13 @@ DirectFB_TranslateButton(DFBInputDeviceButtonIdentifier button) } } -static DFBEnumerationResult -EnumKeyboards(DFBInputDeviceID device_id, - DFBInputDeviceDescription desc, void *callbackdata) +static DFBEnumerationResult EnumKeyboards(DFBInputDeviceID device_id, DFBInputDeviceDescription desc, void *callbackdata) { cb_data *cb = callbackdata; DFB_DeviceData *devdata = cb->devdata; #if USE_MULTI_API SDL_Keyboard keyboard; #endif - SDL_Keycode keymap[SDL_NUM_SCANCODES]; if (!cb->sys_kbd) { if (cb->sys_ids) { @@ -682,25 +667,17 @@ EnumKeyboards(DFBInputDeviceID device_id, #endif devdata->keyboard[devdata->num_keyboard].id = device_id; devdata->keyboard[devdata->num_keyboard].is_generic = 0; - if (!strncmp("X11", desc.name, 3)) + if (!SDL_strncmp("X11", desc.name, 3)) { - devdata->keyboard[devdata->num_keyboard].map = xfree86_scancode_table2; - devdata->keyboard[devdata->num_keyboard].map_size = SDL_arraysize(xfree86_scancode_table2); + devdata->keyboard[devdata->num_keyboard].map = SDL_GetScancodeTable(SDL_SCANCODE_TABLE_XFREE86_2, &devdata->keyboard[devdata->num_keyboard].map_size); devdata->keyboard[devdata->num_keyboard].map_adjust = 8; } else { - devdata->keyboard[devdata->num_keyboard].map = linux_scancode_table; - devdata->keyboard[devdata->num_keyboard].map_size = SDL_arraysize(linux_scancode_table); + devdata->keyboard[devdata->num_keyboard].map = SDL_GetScancodeTable(SDL_SCANCODE_TABLE_LINUX, &devdata->keyboard[devdata->num_keyboard].map_size); devdata->keyboard[devdata->num_keyboard].map_adjust = 0; } SDL_DFB_LOG("Keyboard %d - %s\n", device_id, desc.name); - SDL_GetDefaultKeymap(keymap); -#if USE_MULTI_API - SDL_SetKeymap(devdata->num_keyboard, 0, keymap, SDL_NUM_SCANCODES); -#else - SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES); -#endif devdata->num_keyboard++; if (cb->sys_kbd) @@ -709,8 +686,7 @@ EnumKeyboards(DFBInputDeviceID device_id, return DFENUM_OK; } -void -DirectFB_InitKeyboard(_THIS) +void DirectFB_InitKeyboard(_THIS) { SDL_DFB_DEVICEDATA(_this); cb_data cb; @@ -739,8 +715,7 @@ DirectFB_InitKeyboard(_THIS) } } -void -DirectFB_QuitKeyboard(_THIS) +void DirectFB_QuitKeyboard(_THIS) { /* SDL_DFB_DEVICEDATA(_this); */ } diff --git a/SDL2-2.0.12/src/video/directfb/SDL_DirectFB_events.h b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_events.h similarity index 95% rename from SDL2-2.0.12/src/video/directfb/SDL_DirectFB_events.h rename to SDL2-2.30.5/src/video/directfb/SDL_DirectFB_events.h index e1bddd5..65ee229 100644 --- a/SDL2-2.0.12/src/video/directfb/SDL_DirectFB_events.h +++ b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_events.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/video/directfb/SDL_DirectFB_modes.c b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_modes.c similarity index 93% rename from SDL2-2.0.12/src/video/directfb/SDL_DirectFB_modes.c rename to SDL2-2.30.5/src/video/directfb/SDL_DirectFB_modes.c index 5b3e534..3c69a82 100644 --- a/SDL2-2.0.12/src/video/directfb/SDL_DirectFB_modes.c +++ b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_modes.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_DIRECTFB +#ifdef SDL_VIDEO_DRIVER_DIRECTFB #include "SDL_DirectFB_video.h" #include "SDL_DirectFB_modes.h" @@ -42,8 +42,7 @@ struct modes_callback_t SDL_DisplayMode *modelist; }; -static DFBEnumerationResult -EnumModesCallback(int width, int height, int bpp, void *data) +static DFBEnumerationResult EnumModesCallback(int width, int height, int bpp, void *data) { struct modes_callback_t *modedata = (struct modes_callback_t *) data; SDL_DisplayMode mode; @@ -61,9 +60,7 @@ EnumModesCallback(int width, int height, int bpp, void *data) return DFENUM_OK; } -static DFBEnumerationResult -EnumScreensCallback(DFBScreenID screen_id, DFBScreenDescription desc, - void *callbackdata) +static DFBEnumerationResult EnumScreensCallback(DFBScreenID screen_id, DFBScreenDescription desc, void *callbackdata) { struct screen_callback_t *devdata = (struct screen_callback_t *) callbackdata; @@ -71,9 +68,7 @@ EnumScreensCallback(DFBScreenID screen_id, DFBScreenDescription desc, return DFENUM_OK; } -static DFBEnumerationResult -EnumLayersCallback(DFBDisplayLayerID layer_id, DFBDisplayLayerDescription desc, - void *callbackdata) +static DFBEnumerationResult EnumLayersCallback(DFBDisplayLayerID layer_id, DFBDisplayLayerDescription desc, void *callbackdata) { struct screen_callback_t *devdata = (struct screen_callback_t *) callbackdata; @@ -89,8 +84,7 @@ EnumLayersCallback(DFBDisplayLayerID layer_id, DFBDisplayLayerDescription desc, return DFENUM_OK; } -static void -CheckSetDisplayMode(_THIS, SDL_VideoDisplay * display, DFB_DisplayData * data, SDL_DisplayMode * mode) +static void CheckSetDisplayMode(_THIS, SDL_VideoDisplay * display, DFB_DisplayData * data, SDL_DisplayMode * mode) { SDL_DFB_DEVICEDATA(_this); DFBDisplayLayerConfig config; @@ -125,8 +119,7 @@ CheckSetDisplayMode(_THIS, SDL_VideoDisplay * display, DFB_DisplayData * data, S } -void -DirectFB_SetContext(_THIS, SDL_Window *window) +void DirectFB_SetContext(_THIS, SDL_Window *window) { #if (DFB_VERSION_ATLEAST(1,0,0)) /* FIXME: does not work on 1.0/1.2 with radeon driver @@ -144,8 +137,7 @@ DirectFB_SetContext(_THIS, SDL_Window *window) #endif } -void -DirectFB_InitModes(_THIS) +void DirectFB_InitModes(_THIS) { SDL_DFB_DEVICEDATA(_this); IDirectFBDisplayLayer *layer = NULL; @@ -258,7 +250,7 @@ DirectFB_InitModes(_THIS) SDL_DFB_CHECKERR(layer->SetCooperativeLevel(layer, DLSCL_SHARED)); - SDL_AddVideoDisplay(&display); + SDL_AddVideoDisplay(&display, SDL_FALSE); } SDL_DFB_FREE(screencbdata); return; @@ -269,8 +261,7 @@ DirectFB_InitModes(_THIS) return; } -void -DirectFB_GetDisplayModes(_THIS, SDL_VideoDisplay * display) +void DirectFB_GetDisplayModes(_THIS, SDL_VideoDisplay * display) { SDL_DFB_DEVICEDATA(_this); DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata; @@ -304,8 +295,7 @@ error: return; } -int -DirectFB_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) +int DirectFB_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) { /* * FIXME: video mode switch is currently broken for 1.2.0 @@ -375,8 +365,7 @@ DirectFB_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mod return -1; } -void -DirectFB_QuitModes(_THIS) +void DirectFB_QuitModes(_THIS) { SDL_DisplayMode tmode; int i; diff --git a/SDL2-2.0.12/src/video/directfb/SDL_DirectFB_modes.h b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_modes.h similarity index 97% rename from SDL2-2.0.12/src/video/directfb/SDL_DirectFB_modes.h rename to SDL2-2.30.5/src/video/directfb/SDL_DirectFB_modes.h index 43b07fe..236ea8b 100644 --- a/SDL2-2.0.12/src/video/directfb/SDL_DirectFB_modes.h +++ b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_modes.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/video/directfb/SDL_DirectFB_mouse.c b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_mouse.c similarity index 92% rename from SDL2-2.0.12/src/video/directfb/SDL_DirectFB_mouse.c rename to SDL2-2.30.5/src/video/directfb/SDL_DirectFB_mouse.c index 7cda0ee..363509e 100644 --- a/SDL2-2.0.12/src/video/directfb/SDL_DirectFB_mouse.c +++ b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_mouse.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,9 +20,8 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_DIRECTFB +#ifdef SDL_VIDEO_DRIVER_DIRECTFB -#include "SDL_assert.h" #include "SDL_DirectFB_video.h" #include "SDL_DirectFB_mouse.h" @@ -75,8 +74,7 @@ static const char *arrow[] = { " ", }; -static SDL_Cursor * -DirectFB_CreateDefaultCursor(void) +static SDL_Cursor *DirectFB_CreateDefaultCursor(void) { SDL_VideoDevice *dev = SDL_GetVideoDevice(); @@ -128,8 +126,7 @@ DirectFB_CreateDefaultCursor(void) } /* Create a cursor from a surface */ -static SDL_Cursor * -DirectFB_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y) +static SDL_Cursor *DirectFB_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y) { SDL_VideoDevice *dev = SDL_GetVideoDevice(); @@ -165,7 +162,7 @@ DirectFB_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y) p = surface->pixels; for (i = 0; i < surface->h; i++) - memcpy((char *) dest + i * pitch, + SDL_memcpy((char *) dest + i * pitch, (char *) p + i * surface->pitch, 4 * surface->w); curdata->surf->Unlock(curdata->surf); @@ -175,8 +172,7 @@ DirectFB_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y) } /* Show the specified cursor, or hide if cursor is NULL */ -static int -DirectFB_ShowCursor(SDL_Cursor * cursor) +static int DirectFB_ShowCursor(SDL_Cursor * cursor) { SDL_DFB_CURSORDATA(cursor); SDL_Window *window; @@ -216,8 +212,7 @@ DirectFB_ShowCursor(SDL_Cursor * cursor) } /* Free a window manager cursor */ -static void -DirectFB_FreeCursor(SDL_Cursor * cursor) +static void DirectFB_FreeCursor(SDL_Cursor * cursor) { SDL_DFB_CURSORDATA(cursor); @@ -227,8 +222,7 @@ DirectFB_FreeCursor(SDL_Cursor * cursor) } /* Warp the mouse to (x,y) */ -static void -DirectFB_WarpMouse(SDL_Window * window, int x, int y) +static void DirectFB_WarpMouse(SDL_Window * window, int x, int y) { SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata; @@ -253,9 +247,7 @@ static void DirectFB_FreeMouse(SDL_Mouse * mouse); static int id_mask; -static DFBEnumerationResult -EnumMice(DFBInputDeviceID device_id, DFBInputDeviceDescription desc, - void *callbackdata) +static DFBEnumerationResult EnumMice(DFBInputDeviceID device_id, DFBInputDeviceDescription desc, void *callbackdata) { DFB_DeviceData *devdata = callbackdata; @@ -278,8 +270,7 @@ EnumMice(DFBInputDeviceID device_id, DFBInputDeviceDescription desc, return DFENUM_OK; } -void -DirectFB_InitMouse(_THIS) +void DirectFB_InitMouse(_THIS) { SDL_DFB_DEVICEDATA(_this); @@ -311,8 +302,7 @@ DirectFB_InitMouse(_THIS) } } -void -DirectFB_QuitMouse(_THIS) +void DirectFB_QuitMouse(_THIS) { SDL_DFB_DEVICEDATA(_this); @@ -325,15 +315,13 @@ DirectFB_QuitMouse(_THIS) /* This is called when a mouse motion event occurs */ -static void -DirectFB_MoveCursor(SDL_Cursor * cursor) +static void DirectFB_MoveCursor(SDL_Cursor * cursor) { } /* Warp the mouse to (x,y) */ -static void -DirectFB_WarpMouse(SDL_Mouse * mouse, SDL_Window * window, int x, int y) +static void DirectFB_WarpMouse(SDL_Mouse * mouse, SDL_Window * window, int x, int y) { SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata; @@ -351,16 +339,14 @@ DirectFB_WarpMouse(SDL_Mouse * mouse, SDL_Window * window, int x, int y) } /* Free the mouse when it's time */ -static void -DirectFB_FreeMouse(SDL_Mouse * mouse) +static void DirectFB_FreeMouse(SDL_Mouse * mouse) { /* nothing yet */ } #else /* USE_MULTI_API */ -void -DirectFB_InitMouse(_THIS) +void DirectFB_InitMouse(_THIS) { SDL_DFB_DEVICEDATA(_this); @@ -376,12 +362,10 @@ DirectFB_InitMouse(_THIS) devdata->num_mice = 1; } -void -DirectFB_QuitMouse(_THIS) +void DirectFB_QuitMouse(_THIS) { } - #endif #endif /* SDL_VIDEO_DRIVER_DIRECTFB */ diff --git a/SDL2-2.0.12/src/video/directfb/SDL_DirectFB_mouse.h b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_mouse.h similarity index 95% rename from SDL2-2.0.12/src/video/directfb/SDL_DirectFB_mouse.h rename to SDL2-2.30.5/src/video/directfb/SDL_DirectFB_mouse.h index 43a705f..6d90970 100644 --- a/SDL2-2.0.12/src/video/directfb/SDL_DirectFB_mouse.h +++ b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_mouse.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/video/directfb/SDL_DirectFB_opengl.c b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_opengl.c similarity index 83% rename from SDL2-2.0.12/src/video/directfb/SDL_DirectFB_opengl.c rename to SDL2-2.30.5/src/video/directfb/SDL_DirectFB_opengl.c index 7a841ec..338d53a 100644 --- a/SDL2-2.0.12/src/video/directfb/SDL_DirectFB_opengl.c +++ b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_opengl.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,11 +20,11 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_DIRECTFB +#ifdef SDL_VIDEO_DRIVER_DIRECTFB #include "SDL_DirectFB_video.h" -#if SDL_DIRECTFB_OPENGL +#ifdef SDL_DIRECTFB_OPENGL #include "SDL_DirectFB_opengl.h" #include "SDL_DirectFB_window.h" @@ -33,7 +33,7 @@ #include "SDL_loadso.h" #endif -#if SDL_DIRECTFB_OPENGL +#ifdef SDL_DIRECTFB_OPENGL struct SDL_GLDriverData { @@ -47,7 +47,7 @@ struct SDL_GLDriverData }; #define OPENGL_REQUIRS_DLOPEN -#if defined(OPENGL_REQUIRS_DLOPEN) && defined(SDL_LOADSO_DLOPEN) +#if defined(OPENGL_REQUIRS_DLOPEN) && defined(HAVE_DLOPEN) #include #define GL_LoadObject(X) dlopen(X, (RTLD_NOW|RTLD_GLOBAL)) #define GL_LoadFunction dlsym @@ -60,8 +60,7 @@ struct SDL_GLDriverData static void DirectFB_GL_UnloadLibrary(_THIS); -int -DirectFB_GL_Initialize(_THIS) +int DirectFB_GL_Initialize(_THIS) { if (_this->gl_data) { return 0; @@ -91,8 +90,7 @@ DirectFB_GL_Initialize(_THIS) return 0; } -void -DirectFB_GL_Shutdown(_THIS) +void DirectFB_GL_Shutdown(_THIS) { if (!_this->gl_data || (--_this->gl_data->initialized > 0)) { return; @@ -104,8 +102,7 @@ DirectFB_GL_Shutdown(_THIS) _this->gl_data = NULL; } -int -DirectFB_GL_LoadLibrary(_THIS, const char *path) +int DirectFB_GL_LoadLibrary(_THIS, const char *path) { void *handle = NULL; @@ -116,15 +113,15 @@ DirectFB_GL_LoadLibrary(_THIS, const char *path) } - if (path == NULL) { + if (!path) { path = SDL_getenv("SDL_OPENGL_LIBRARY"); - if (path == NULL) { + if (!path) { path = "libGL.so.1"; } } handle = GL_LoadObject(path); - if (handle == NULL) { + if (!handle) { SDL_DFB_ERR("Library not found: %s\n", path); /* SDL_LoadObject() will call SDL_SetError() for us. */ return -1; @@ -146,8 +143,7 @@ DirectFB_GL_LoadLibrary(_THIS, const char *path) return 0; } -static void -DirectFB_GL_UnloadLibrary(_THIS) +static void DirectFB_GL_UnloadLibrary(_THIS) { #if 0 int ret = GL_UnloadObject(_this->gl_config.dll_handle); @@ -160,8 +156,7 @@ DirectFB_GL_UnloadLibrary(_THIS) _this->gl_data = NULL; } -void * -DirectFB_GL_GetProcAddress(_THIS, const char *proc) +void *DirectFB_GL_GetProcAddress(_THIS, const char *proc) { void *handle; @@ -169,8 +164,7 @@ DirectFB_GL_GetProcAddress(_THIS, const char *proc) return GL_LoadFunction(handle, proc); } -SDL_GLContext -DirectFB_GL_CreateContext(_THIS, SDL_Window * window) +SDL_GLContext DirectFB_GL_CreateContext(_THIS, SDL_Window * window) { SDL_DFB_WINDOWDATA(window); DirectFB_GLContext *context; @@ -202,8 +196,7 @@ DirectFB_GL_CreateContext(_THIS, SDL_Window * window) return NULL; } -int -DirectFB_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) +int DirectFB_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) { DirectFB_GLContext *ctx = (DirectFB_GLContext *) context; DirectFB_GLContext *p; @@ -217,7 +210,7 @@ DirectFB_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) } - if (ctx != NULL) { + if (ctx) { SDL_DFB_CHECKERR(ctx->context->Lock(ctx->context)); ctx->is_locked = 1; } @@ -227,20 +220,17 @@ DirectFB_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) return -1; } -int -DirectFB_GL_SetSwapInterval(_THIS, int interval) +int DirectFB_GL_SetSwapInterval(_THIS, int interval) { return SDL_Unsupported(); } -int -DirectFB_GL_GetSwapInterval(_THIS) +int DirectFB_GL_GetSwapInterval(_THIS) { return 0; } -int -DirectFB_GL_SwapWindow(_THIS, SDL_Window * window) +int DirectFB_GL_SwapWindow(_THIS, SDL_Window * window) { SDL_DFB_WINDOWDATA(window); DirectFB_GLContext *p; @@ -252,7 +242,7 @@ DirectFB_GL_SwapWindow(_THIS, SDL_Window * window) devdata->glFlush(); #endif - for (p = _this->gl_data->firstgl; p != NULL; p = p->next) + for (p = _this->gl_data->firstgl; p; p = p->next) if (p->sdl_window == window && p->is_locked) { SDL_DFB_CHECKERR(p->context->Unlock(p->context)); @@ -265,8 +255,7 @@ DirectFB_GL_SwapWindow(_THIS, SDL_Window * window) return -1; } -void -DirectFB_GL_DeleteContext(_THIS, SDL_GLContext context) +void DirectFB_GL_DeleteContext(_THIS, SDL_GLContext context) { DirectFB_GLContext *ctx = (DirectFB_GLContext *) context; DirectFB_GLContext *p; @@ -285,12 +274,11 @@ DirectFB_GL_DeleteContext(_THIS, SDL_GLContext context) SDL_DFB_FREE(ctx); } -void -DirectFB_GL_FreeWindowContexts(_THIS, SDL_Window * window) +void DirectFB_GL_FreeWindowContexts(_THIS, SDL_Window * window) { DirectFB_GLContext *p; - for (p = _this->gl_data->firstgl; p != NULL; p = p->next) + for (p = _this->gl_data->firstgl; p; p = p->next) if (p->sdl_window == window) { if (p->is_locked) @@ -299,12 +287,11 @@ DirectFB_GL_FreeWindowContexts(_THIS, SDL_Window * window) } } -void -DirectFB_GL_ReAllocWindowContexts(_THIS, SDL_Window * window) +void DirectFB_GL_ReAllocWindowContexts(_THIS, SDL_Window * window) { DirectFB_GLContext *p; - for (p = _this->gl_data->firstgl; p != NULL; p = p->next) + for (p = _this->gl_data->firstgl; p; p = p->next) if (p->sdl_window == window) { SDL_DFB_WINDOWDATA(window); @@ -315,12 +302,11 @@ DirectFB_GL_ReAllocWindowContexts(_THIS, SDL_Window * window) } } -void -DirectFB_GL_DestroyWindowContexts(_THIS, SDL_Window * window) +void DirectFB_GL_DestroyWindowContexts(_THIS, SDL_Window * window) { DirectFB_GLContext *p; - for (p = _this->gl_data->firstgl; p != NULL; p = p->next) + for (p = _this->gl_data->firstgl; p; p = p->next) if (p->sdl_window == window) DirectFB_GL_DeleteContext(_this, p); } diff --git a/SDL2-2.0.12/src/video/directfb/SDL_DirectFB_opengl.h b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_opengl.h similarity index 96% rename from SDL2-2.0.12/src/video/directfb/SDL_DirectFB_opengl.h rename to SDL2-2.30.5/src/video/directfb/SDL_DirectFB_opengl.h index c4e05a2..3700da7 100644 --- a/SDL2-2.0.12/src/video/directfb/SDL_DirectFB_opengl.h +++ b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_opengl.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -25,7 +25,7 @@ #include "SDL_DirectFB_video.h" -#if SDL_DIRECTFB_OPENGL +#ifdef SDL_DIRECTFB_OPENGL #include "SDL_opengl.h" diff --git a/SDL2-2.0.12/src/video/directfb/SDL_DirectFB_render.c b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_render.c similarity index 77% rename from SDL2-2.0.12/src/video/directfb/SDL_DirectFB_render.c rename to SDL2-2.30.5/src/video/directfb/SDL_DirectFB_render.c index 6180098..0d96f86 100644 --- a/SDL2-2.0.12/src/video/directfb/SDL_DirectFB_render.c +++ b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_render.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_DIRECTFB +#ifdef SDL_VIDEO_DRIVER_DIRECTFB #include "SDL_DirectFB_window.h" #include "SDL_DirectFB_modes.h" @@ -79,16 +79,14 @@ typedef struct #endif } DirectFB_TextureData; -static SDL_INLINE void -SDLtoDFBRect(const SDL_Rect * sr, DFBRectangle * dr) +static void SDLtoDFBRect(const SDL_Rect * sr, DFBRectangle * dr) { dr->x = sr->x; dr->y = sr->y; dr->h = sr->h; dr->w = sr->w; } -static SDL_INLINE void -SDLtoDFBRect_Float(const SDL_FRect * sr, DFBRectangle * dr) +static void SDLtoDFBRect_Float(const SDL_FRect * sr, DFBRectangle * dr) { dr->x = sr->x; dr->y = sr->y; @@ -97,8 +95,7 @@ SDLtoDFBRect_Float(const SDL_FRect * sr, DFBRectangle * dr) } -static int -TextureHasAlpha(DirectFB_TextureData * data) +static int TextureHasAlpha(DirectFB_TextureData * data) { /* Drawing primitive ? */ if (!data) @@ -149,9 +146,7 @@ static SDL_INLINE IDirectFBWindow *get_dfb_window(SDL_Window *window) return wm_info.info.dfb.window; } -static void -SetBlendMode(DirectFB_RenderData * data, int blendMode, - DirectFB_TextureData * source) +static void SetBlendMode(DirectFB_RenderData * data, int blendMode, DirectFB_TextureData * source) { IDirectFBSurface *destsurf = data->target; @@ -198,11 +193,11 @@ SetBlendMode(DirectFB_RenderData * data, int blendMode, SDL_DFB_CHECK(destsurf->SetDstBlendFunction(destsurf, DSBF_SRCCOLOR)); break; - } case SDL_BLENDMODE_MUL: data->blitFlags = DSBLIT_BLEND_ALPHACHANNEL; data->drawFlags = DSDRAW_BLEND; - SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_DSTCOLOR)); + /* FIXME SDL_BLENDMODE_MUL is simplified, and dstA is in fact un-changed.*/ + SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_DESTCOLOR)); SDL_DFB_CHECK(destsurf->SetDstBlendFunction(destsurf, DSBF_INVSRCALPHA)); break; @@ -211,8 +206,7 @@ SetBlendMode(DirectFB_RenderData * data, int blendMode, } } -static int -PrepareDraw(SDL_Renderer * renderer, const SDL_RenderCommand *cmd) +static int PrepareDraw(SDL_Renderer * renderer, const SDL_RenderCommand *cmd) { DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata; IDirectFBSurface *destsurf = data->target; @@ -246,8 +240,7 @@ PrepareDraw(SDL_Renderer * renderer, const SDL_RenderCommand *cmd) return -1; } -static void -DirectFB_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event) +static void DirectFB_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event) { SDL_DFB_RENDERERDATA(renderer); @@ -259,8 +252,7 @@ DirectFB_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event) } } -static void -DirectFB_ActivateRenderer(SDL_Renderer * renderer) +static void DirectFB_ActivateRenderer(SDL_Renderer * renderer) { SDL_DFB_RENDERERDATA(renderer); @@ -269,8 +261,7 @@ DirectFB_ActivateRenderer(SDL_Renderer * renderer) } } -static int -DirectFB_AcquireVidLayer(SDL_Renderer * renderer, SDL_Texture * texture) +static int DirectFB_AcquireVidLayer(SDL_Renderer * renderer, SDL_Texture * texture) { SDL_Window *window = renderer->window; SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); @@ -325,8 +316,23 @@ DirectFB_AcquireVidLayer(SDL_Renderer * renderer, SDL_Texture * texture) return 1; } -static int -DirectFB_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) + +/* Copy the SDL_Surface palette to the DirectFB texture palette */ +void DirectFB_SetTexturePalette(SDL_Renderer *renderer, SDL_Texture *texture, SDL_Palette *pal) +{ + int i; + DFBColor dfbpal[256]; + DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata; + for (i = 0; i < pal->ncolors; i++) { + dfbpal[i].a = pal->colors[i].a; + dfbpal[i].r = pal->colors[i].r; + dfbpal[i].g = pal->colors[i].g; + dfbpal[i].b = pal->colors[i].b; + } + data->palette->SetEntries(data->palette, dfbpal, pal->ncolors, 0); +} + +static int DirectFB_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) { SDL_Window *window = renderer->window; SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); @@ -421,8 +427,7 @@ DirectFB_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) } #if 0 -static int -DirectFB_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture) +static int DirectFB_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture) { #if (DFB_VERSION_ATLEAST(1,2,0)) @@ -450,8 +455,7 @@ DirectFB_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture) } #endif -static int -DirectFB_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, +static int DirectFB_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, const void *pixels, int pitch) { DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata; @@ -507,8 +511,7 @@ DirectFB_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, } -static int -DirectFB_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, +static int DirectFB_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, void **pixels, int *pitch) { DirectFB_TextureData *texturedata = @@ -545,8 +548,7 @@ DirectFB_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, return -1; } -static void -DirectFB_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) +static void DirectFB_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) { DirectFB_TextureData *texturedata = (DirectFB_TextureData *) texture->driverdata; @@ -559,14 +561,12 @@ DirectFB_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) } } -static void -DirectFB_SetTextureScaleMode() +static void DirectFB_SetTextureScaleMode() { } #if 0 -static void -DirectFB_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture, +static void DirectFB_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture, int numrects, const SDL_Rect * rects) { DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata; @@ -595,16 +595,14 @@ static int DirectFB_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * textu } -static int -DirectFB_QueueSetViewport(SDL_Renderer * renderer, SDL_RenderCommand *cmd) +static int DirectFB_QueueSetViewport(SDL_Renderer * renderer, SDL_RenderCommand *cmd) { return 0; /* nothing to do in this backend. */ } -static int -DirectFB_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count) +static int DirectFB_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count) { - const size_t len = count * sizeof (SDL_FPoint); + const size_t len = count * sizeof(SDL_FPoint); SDL_FPoint *verts = (SDL_FPoint *) SDL_AllocateRenderVertices(renderer, len, 0, &cmd->data.draw.first); if (!verts) { @@ -616,10 +614,61 @@ DirectFB_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const return 0; } -static int -DirectFB_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRect * rects, int count) +static int DirectFB_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, + const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride, + int num_vertices, const void *indices, int num_indices, int size_indices, + float scale_x, float scale_y) { - const size_t len = count * sizeof (SDL_FRect); + int i; + int count = indices ? num_indices : num_vertices; + float *verts; + int sz = 2 + 4 + (texture ? 2 : 0); + + verts = (float *) SDL_AllocateRenderVertices(renderer, count * sz * sizeof(float), 0, &cmd->data.draw.first); + if (!verts) { + return -1; + } + + cmd->data.draw.count = count; + size_indices = indices ? size_indices : 0; + + for (i = 0; i < count; i++) { + int j; + float *xy_; + SDL_Color col_; + if (size_indices == 4) { + j = ((const Uint32 *)indices)[i]; + } else if (size_indices == 2) { + j = ((const Uint16 *)indices)[i]; + } else if (size_indices == 1) { + j = ((const Uint8 *)indices)[i]; + } else { + j = i; + } + + xy_ = (float *)((char*)xy + j * xy_stride); + col_ = *(SDL_Color *)((char*)color + j * color_stride); + + *(verts++) = xy_[0] * scale_x; + *(verts++) = xy_[1] * scale_y; + + *(verts++) = col_.r; + *(verts++) = col_.g; + *(verts++) = col_.b; + *(verts++) = col_.a; + + if (texture) { + float *uv_ = (float *)((char*)uv + j * uv_stride); + *(verts++) = uv_[0]; + *(verts++) = uv_[1]; + } + } + return 0; +} + +static int DirectFB_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRect * rects, int count) +{ + const size_t len = count * sizeof(SDL_FRect); SDL_FRect *verts = (SDL_FRect *) SDL_AllocateRenderVertices(renderer, len, 0, &cmd->data.draw.first); if (!verts) { @@ -627,15 +676,14 @@ DirectFB_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const S } cmd->data.draw.count = count; - SDL_memcpy(verts, rects, count); + SDL_memcpy(verts, rects, len); return 0; } -static int -DirectFB_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture, +static int DirectFB_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture, const SDL_Rect * srcrect, const SDL_FRect * dstrect) { - DFBRectangle *verts = (DFBRectangle *) SDL_AllocateRenderVertices(renderer, 2 * sizeof (DFBRectangle), 0, &cmd->data.draw.first); + DFBRectangle *verts = (DFBRectangle *) SDL_AllocateRenderVertices(renderer, 2 * sizeof(DFBRectangle), 0, &cmd->data.draw.first); if (!verts) { return -1; @@ -649,17 +697,7 @@ DirectFB_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture return 0; } -static int -DirectFB_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture, - const SDL_Rect * srcrect, const SDL_FRect * dstrect, - const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip) -{ - return SDL_Unsupported(); -} - - -static int -DirectFB_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize) +static int DirectFB_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize) { /* !!! FIXME: there are probably some good optimization wins in here if someone wants to look it over. */ DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata; @@ -815,8 +853,145 @@ DirectFB_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void * break; } - case SDL_RENDERCMD_COPY_EX: - break; /* unsupported */ + + case SDL_RENDERCMD_GEOMETRY: { + const float *verts = (float *) (((Uint8 *) vertices) + cmd->data.draw.first); + SDL_Texture *texture = cmd->data.draw.texture; + const size_t count = cmd->data.draw.count; + + Uint8 save_r = cmd->data.draw.r; + Uint8 save_g = cmd->data.draw.g; + Uint8 save_b = cmd->data.draw.b; + Uint8 save_a = cmd->data.draw.a; + + int j; + for (j = 0; j < count; j += 3) + { + float x1, y1, r1, g1, b1, a1, u1, v1; + float x2, y2, r2, g2, b2, a2, u2, v2; + float x3, y3, r3, g3, b3, a3, u3, v3; + + x1 = *(verts++); + y1 = *(verts++); + r1 = *(verts++); + g1 = *(verts++); + b1 = *(verts++); + a1 = *(verts++); + if (texture) { + u1 = *(verts++); + v1 = *(verts++); + } + x2 = *(verts++); + y2 = *(verts++); + r2 = *(verts++); + g2 = *(verts++); + b2 = *(verts++); + a2 = *(verts++); + if (texture) { + u2 = *(verts++); + v2 = *(verts++); + } + x3 = *(verts++); + y3 = *(verts++); + r3 = *(verts++); + g3 = *(verts++); + b3 = *(verts++); + a3 = *(verts++); + if (texture) { + u3 = *(verts++); + v3 = *(verts++); + } + + + if (texture) { + DFBVertex vertices[3]; + + DirectFB_TextureData *texturedata = (DirectFB_TextureData *) texture->driverdata; + + DFBSurfaceBlittingFlags flags = 0; + + int r = (r1 + r2 + r3) / 3; + int g = (g1 + g2 + g3) / 3; + int b = (b1 + b2 + b3) / 3; + int a = (a1 + a2 + a3) / 3; + + + if (texturedata->isDirty) { + const SDL_Rect rect = { 0, 0, texture->w, texture->h }; + DirectFB_UpdateTexture(renderer, texture, &rect, texturedata->pixels, texturedata->pitch); + } + + if (a != 0xFF) { + flags |= DSBLIT_BLEND_COLORALPHA; + } + + if ((r & g & b) != 0xFF) { + flags |= DSBLIT_COLORIZE; + } + + destsurf->SetColor(destsurf, r, g, b, a); + + /* ???? flags |= DSBLIT_SRC_PREMULTCOLOR; */ + + SetBlendMode(data, texture->blendMode, texturedata); + + destsurf->SetBlittingFlags(destsurf, data->blitFlags | flags); + +#if (DFB_VERSION_ATLEAST(1,2,0)) + destsurf->SetRenderOptions(destsurf, texturedata->render_options); +#endif + + vertices[0].x = x1; + vertices[0].y = y1; + vertices[0].z = 0; + vertices[0].w = 0; + vertices[0].s = u1; + vertices[0].t = v1; + + vertices[1].x = x2; + vertices[1].y = y2; + vertices[1].z = 0; + vertices[1].w = 0; + vertices[1].s = u2; + vertices[1].t = v2; + + vertices[2].x = x3; + vertices[2].y = y3; + vertices[2].z = 0; + vertices[2].w = 0; + vertices[2].s = u3; + vertices[2].t = v3; + + destsurf->TextureTriangles(destsurf, texturedata->surface, vertices, NULL, 3, DTTF_LIST); + } else { + DFBTriangle tris; + tris.x1 = x1; + tris.y1 = y1; + tris.x2 = x2; + tris.y2 = y2; + tris.x3 = x3; + tris.y3 = y3; + + cmd->data.draw.r = (r1 + r2 + r3) / 3; + cmd->data.draw.g = (g1 + g2 + g3) / 3; + cmd->data.draw.b = (b1 + b2 + b3) / 3; + cmd->data.draw.a = (a1 + a2 + a3) / 3; + + PrepareDraw(renderer, cmd); + + destsurf->FillTriangles(destsurf, &tris, 1); + } + } + + cmd->data.draw.r = save_r; + cmd->data.draw.g = save_g; + cmd->data.draw.b = save_b; + cmd->data.draw.a = save_a; + break; + } + + case SDL_RENDERCMD_COPY_EX: /* unused */ + break; case SDL_RENDERCMD_NO_OP: break; @@ -829,8 +1004,7 @@ DirectFB_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void * } -static void -DirectFB_RenderPresent(SDL_Renderer * renderer) +static int DirectFB_RenderPresent(SDL_Renderer * renderer) { DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata; SDL_Window *window = renderer->window; @@ -860,10 +1034,10 @@ DirectFB_RenderPresent(SDL_Renderer * renderer) /* Send the data to the display */ SDL_DFB_CHECK(windata->window_surface->Flip(windata->window_surface, NULL, data->flipflags)); + return 0; } -static void -DirectFB_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) +static void DirectFB_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) { DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata; @@ -888,8 +1062,7 @@ DirectFB_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) texture->driverdata = NULL; } -static void -DirectFB_DestroyRenderer(SDL_Renderer * renderer) +static void DirectFB_DestroyRenderer(SDL_Renderer * renderer) { DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata; #if 0 @@ -903,8 +1076,7 @@ DirectFB_DestroyRenderer(SDL_Renderer * renderer) SDL_free(renderer); } -static int -DirectFB_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, +static int DirectFB_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 format, void * pixels, int pitch) { Uint32 sdl_format; @@ -931,8 +1103,7 @@ DirectFB_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, } #if 0 -static int -DirectFB_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect, +static int DirectFB_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 format, const void * pixels, int pitch) { SDL_Window *window = renderer->window; @@ -959,8 +1130,7 @@ DirectFB_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect, #endif -SDL_Renderer * -DirectFB_CreateRenderer(SDL_Window * window, Uint32 flags) +SDL_Renderer *DirectFB_CreateRenderer(SDL_Window * window, Uint32 flags) { IDirectFBSurface *winsurf = get_dfb_surface(window); /*SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);*/ @@ -985,9 +1155,9 @@ DirectFB_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->QueueSetDrawColor = DirectFB_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */ renderer->QueueDrawPoints = DirectFB_QueueDrawPoints; renderer->QueueDrawLines = DirectFB_QueueDrawPoints; /* lines and points queue vertices the same way. */ + renderer->QueueGeometry = DirectFB_QueueGeometry; renderer->QueueFillRects = DirectFB_QueueFillRects; renderer->QueueCopy = DirectFB_QueueCopy; - renderer->QueueCopyEx = DirectFB_QueueCopyEx; renderer->RunCommandQueue = DirectFB_RunCommandQueue; renderer->RenderPresent = DirectFB_RenderPresent; diff --git a/SDL2-2.0.12/src/video/directfb/SDL_DirectFB_render.h b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_render.h similarity index 94% rename from SDL2-2.0.12/src/video/directfb/SDL_DirectFB_render.h rename to SDL2-2.30.5/src/video/directfb/SDL_DirectFB_render.h index aa0ceb4..7637039 100644 --- a/SDL2-2.0.12/src/video/directfb/SDL_DirectFB_render.h +++ b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_render.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/video/directfb/SDL_DirectFB_shape.c b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_shape.c similarity index 83% rename from SDL2-2.0.12/src/video/directfb/SDL_DirectFB_shape.c rename to SDL2-2.30.5/src/video/directfb/SDL_DirectFB_shape.c index 3009de3..f738605 100644 --- a/SDL2-2.0.12/src/video/directfb/SDL_DirectFB_shape.c +++ b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_shape.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,27 +20,35 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_DIRECTFB +#ifdef SDL_VIDEO_DRIVER_DIRECTFB -#include "SDL_assert.h" #include "SDL_DirectFB_video.h" #include "SDL_DirectFB_shape.h" #include "SDL_DirectFB_window.h" #include "../SDL_shape_internals.h" -SDL_WindowShaper* -DirectFB_CreateShaper(SDL_Window* window) { +SDL_WindowShaper *DirectFB_CreateShaper(SDL_Window* window) +{ SDL_WindowShaper* result = NULL; SDL_ShapeData* data; int resized_properly; - result = malloc(sizeof(SDL_WindowShaper)); + result = SDL_malloc(sizeof(SDL_WindowShaper)); + if (!result) { + SDL_OutOfMemory(); + return NULL; + } result->window = window; result->mode.mode = ShapeModeDefault; result->mode.parameters.binarizationCutoff = 1; result->userx = result->usery = 0; data = SDL_malloc(sizeof(SDL_ShapeData)); + if (!data) { + SDL_free(result); + SDL_OutOfMemory(); + return NULL; + } result->driverdata = data; data->surface = NULL; window->shaper = result; @@ -50,8 +58,8 @@ DirectFB_CreateShaper(SDL_Window* window) { return result; } -int -DirectFB_ResizeWindowShape(SDL_Window* window) { +int DirectFB_ResizeWindowShape(SDL_Window* window) +{ SDL_ShapeData* data = window->shaper->driverdata; SDL_assert(data != NULL); @@ -65,10 +73,10 @@ DirectFB_ResizeWindowShape(SDL_Window* window) { return 0; } -int -DirectFB_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shape_mode) { +int DirectFB_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shape_mode) +{ - if(shaper == NULL || shape == NULL || shaper->driverdata == NULL) + if(!shaper || !shape || !shaper->driverdata) return -1; if(shape->format->Amask == 0 && SDL_SHAPEMODEALPHA(shape_mode->mode)) return -2; @@ -95,10 +103,9 @@ DirectFB_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowSh dsc.pixelformat = DSPF_ARGB; SDL_DFB_CHECKERR(devdata->dfb->CreateSurface(devdata->dfb, &dsc, &data->surface)); - + SDL_DFB_CALLOC(bitmap, shape->w * shape->h, 1); /* Assume that shaper->alphacutoff already has a value, because SDL_SetWindowShape() should have given it one. */ - SDL_DFB_ALLOC_CLEAR(bitmap, shape->w * shape->h); - SDL_CalculateShapeBitmap(shaper->mode,shape,bitmap,1); + SDL_CalculateShapeBitmap(shaper->mode, shape, bitmap, 1); src = bitmap; diff --git a/SDL2-2.0.12/src/video/directfb/SDL_DirectFB_shape.h b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_shape.h similarity index 95% rename from SDL2-2.0.12/src/video/directfb/SDL_DirectFB_shape.h rename to SDL2-2.30.5/src/video/directfb/SDL_DirectFB_shape.h index b98901b..a34b571 100644 --- a/SDL2-2.0.12/src/video/directfb/SDL_DirectFB_shape.h +++ b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_shape.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/video/directfb/SDL_DirectFB_video.c b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_video.c similarity index 92% rename from SDL2-2.0.12/src/video/directfb/SDL_DirectFB_video.c rename to SDL2-2.30.5/src/video/directfb/SDL_DirectFB_video.c index a1e5a8b..931a705 100644 --- a/SDL2-2.0.12/src/video/directfb/SDL_DirectFB_video.c +++ b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_video.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,13 +20,14 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_DIRECTFB +#ifdef SDL_VIDEO_DRIVER_DIRECTFB /* * #include "SDL_DirectFB_keyboard.h" */ #include "SDL_DirectFB_modes.h" #include "SDL_DirectFB_opengl.h" +#include "SDL_DirectFB_vulkan.h" #include "SDL_DirectFB_window.h" #include "SDL_DirectFB_WM.h" @@ -60,12 +61,12 @@ static int DirectFB_VideoInit(_THIS); static void DirectFB_VideoQuit(_THIS); -static int DirectFB_Available(void); -static SDL_VideoDevice *DirectFB_CreateDevice(int devindex); +static SDL_VideoDevice *DirectFB_CreateDevice(void); VideoBootStrap DirectFB_bootstrap = { "directfb", "DirectFB", - DirectFB_Available, DirectFB_CreateDevice + DirectFB_CreateDevice, + NULL /* no ShowMessageBox implementation */ }; static const DirectFBSurfaceDrawingFlagsNames(drawing_flags); @@ -74,25 +75,14 @@ static const DirectFBAccelerationMaskNames(acceleration_mask); /* DirectFB driver bootstrap functions */ -static int -DirectFB_Available(void) -{ - if (!SDL_DirectFB_LoadLibrary()) - return 0; - SDL_DirectFB_UnLoadLibrary(); - return 1; -} - -static void -DirectFB_DeleteDevice(SDL_VideoDevice * device) +static void DirectFB_DeleteDevice(SDL_VideoDevice * device) { SDL_DirectFB_UnLoadLibrary(); SDL_DFB_FREE(device->driverdata); SDL_DFB_FREE(device); } -static SDL_VideoDevice * -DirectFB_CreateDevice(int devindex) +static SDL_VideoDevice *DirectFB_CreateDevice(void) { SDL_VideoDevice *device; @@ -122,13 +112,14 @@ DirectFB_CreateDevice(int devindex) device->MaximizeWindow = DirectFB_MaximizeWindow; device->MinimizeWindow = DirectFB_MinimizeWindow; device->RestoreWindow = DirectFB_RestoreWindow; - device->SetWindowGrab = DirectFB_SetWindowGrab; + device->SetWindowMouseGrab = DirectFB_SetWindowMouseGrab; + device->SetWindowKeyboardGrab = DirectFB_SetWindowKeyboardGrab; device->DestroyWindow = DirectFB_DestroyWindow; device->GetWindowWMInfo = DirectFB_GetWindowWMInfo; /* !!! FIXME: implement SetWindowBordered */ -#if SDL_DIRECTFB_OPENGL +#ifdef SDL_DIRECTFB_OPENGL device->GL_LoadLibrary = DirectFB_GL_LoadLibrary; device->GL_GetProcAddress = DirectFB_GL_GetProcAddress; device->GL_MakeCurrent = DirectFB_GL_MakeCurrent; @@ -146,6 +137,13 @@ DirectFB_CreateDevice(int devindex) device->shape_driver.SetWindowShape = DirectFB_SetWindowShape; device->shape_driver.ResizeWindowShape = DirectFB_ResizeWindowShape; +#ifdef SDL_VIDEO_VULKAN + device->Vulkan_LoadLibrary = DirectFB_Vulkan_LoadLibrary; + device->Vulkan_UnloadLibrary = DirectFB_Vulkan_UnloadLibrary; + device->Vulkan_GetInstanceExtensions = DirectFB_Vulkan_GetInstanceExtensions; + device->Vulkan_CreateSurface = DirectFB_Vulkan_CreateSurface; +#endif + device->free = DirectFB_DeleteDevice; return device; @@ -155,8 +153,7 @@ DirectFB_CreateDevice(int devindex) return (0); } -static void -DirectFB_DeviceInformation(IDirectFB * dfb) +static void DirectFB_DeviceInformation(IDirectFB * dfb) { DFBGraphicsDeviceDescription desc; int n; @@ -202,13 +199,12 @@ static int readBoolEnv(const char *env_name, int def_val) stemp = SDL_getenv(env_name); if (stemp) - return atoi(stemp); + return SDL_atoi(stemp); else return def_val; } -static int -DirectFB_VideoInit(_THIS) +static int DirectFB_VideoInit(_THIS) { IDirectFB *dfb = NULL; DFB_DeviceData *devdata = NULL; @@ -262,13 +258,12 @@ DirectFB_VideoInit(_THIS) devdata->dfb = dfb; devdata->firstwin = NULL; - devdata->grabbed_window = NULL; _this->driverdata = devdata; DirectFB_InitModes(_this); -#if SDL_DIRECTFB_OPENGL +#ifdef SDL_DIRECTFB_OPENGL DirectFB_GL_Initialize(_this); #endif @@ -284,8 +279,7 @@ DirectFB_VideoInit(_THIS) return -1; } -static void -DirectFB_VideoQuit(_THIS) +static void DirectFB_VideoQuit(_THIS) { DFB_DeviceData *devdata = (DFB_DeviceData *) _this->driverdata; @@ -297,7 +291,7 @@ DirectFB_VideoQuit(_THIS) SDL_DFB_RELEASE(devdata->events); SDL_DFB_RELEASE(devdata->dfb); -#if SDL_DIRECTFB_OPENGL +#ifdef SDL_DIRECTFB_OPENGL DirectFB_GL_Shutdown(_this); #endif @@ -324,7 +318,9 @@ static const struct { { DSPF_YUY2, SDL_PIXELFORMAT_YUY2 }, /* 16 bit YUV (4 byte/ 2 pixel, macropixel contains CbYCrY [31:0]) */ { DSPF_UYVY, SDL_PIXELFORMAT_UYVY }, /* 16 bit YUV (4 byte/ 2 pixel, macropixel contains YCbYCr [31:0]) */ { DSPF_RGB555, SDL_PIXELFORMAT_RGB555 }, /* 16 bit RGB (2 byte, nothing @15, red 5@10, green 5@5, blue 5@0) */ +#if (DFB_VERSION_ATLEAST(1,5,0)) { DSPF_ABGR, SDL_PIXELFORMAT_ABGR8888 }, /* 32 bit ABGR (4 byte, alpha 8@24, blue 8@16, green 8@8, red 8@0) */ +#endif #if (ENABLE_LUT8) { DSPF_LUT8, SDL_PIXELFORMAT_INDEX8 }, /* 8 bit LUT (8 bit color and alpha lookup from palette) */ #endif @@ -379,8 +375,7 @@ static const struct { { DSPF_UNKNOWN, SDL_PIXELFORMAT_YVYU }, /**< Packed mode: Y0+V0+Y1+U0 (1 pla */ }; -Uint32 -DirectFB_DFBToSDLPixelFormat(DFBSurfacePixelFormat pixelformat) +Uint32 DirectFB_DFBToSDLPixelFormat(DFBSurfacePixelFormat pixelformat) { int i; @@ -392,8 +387,7 @@ DirectFB_DFBToSDLPixelFormat(DFBSurfacePixelFormat pixelformat) return SDL_PIXELFORMAT_UNKNOWN; } -DFBSurfacePixelFormat -DirectFB_SDLToDFBPixelFormat(Uint32 format) +DFBSurfacePixelFormat DirectFB_SDLToDFBPixelFormat(Uint32 format) { int i; diff --git a/SDL2-2.0.12/src/video/directfb/SDL_DirectFB_video.h b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_video.h similarity index 97% rename from SDL2-2.0.12/src/video/directfb/SDL_DirectFB_video.h rename to SDL2-2.30.5/src/video/directfb/SDL_DirectFB_video.h index 9596449..958caef 100644 --- a/SDL2-2.0.12/src/video/directfb/SDL_DirectFB_video.h +++ b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_video.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -31,7 +31,6 @@ #include "SDL_scancode.h" #include "SDL_render.h" -#include "SDL_log.h" #define DFB_VERSIONNUM(X, Y, Z) \ ((X)*1000 + (Y)*100 + (Z)) @@ -154,10 +153,6 @@ struct _DFB_DeviceData int use_linux_input; int has_own_wm; - - /* window grab */ - SDL_Window *grabbed_window; - /* global events */ IDirectFBEventBuffer *events; }; diff --git a/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_vulkan.c b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_vulkan.c new file mode 100644 index 0000000..5dcd021 --- /dev/null +++ b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_vulkan.c @@ -0,0 +1,169 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#if defined(SDL_VIDEO_VULKAN) && defined(SDL_VIDEO_DRIVER_DIRECTFB) + +#include "SDL_DirectFB_window.h" + +#include "SDL_loadso.h" +#include "SDL_DirectFB_vulkan.h" + +int DirectFB_Vulkan_LoadLibrary(_THIS, const char *path) +{ + VkExtensionProperties *extensions = NULL; + Uint32 i, extensionCount = 0; + SDL_bool hasSurfaceExtension = SDL_FALSE; + SDL_bool hasDirectFBSurfaceExtension = SDL_FALSE; + PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL; + if(_this->vulkan_config.loader_handle) + return SDL_SetError("Vulkan already loaded"); + + /* Load the Vulkan loader library */ + if(!path) + path = SDL_getenv("SDL_VULKAN_LIBRARY"); + if(!path) + path = "libvulkan.so.1"; + _this->vulkan_config.loader_handle = SDL_LoadObject(path); + if(!_this->vulkan_config.loader_handle) + return -1; + SDL_strlcpy(_this->vulkan_config.loader_path, path, + SDL_arraysize(_this->vulkan_config.loader_path)); + vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)SDL_LoadFunction( + _this->vulkan_config.loader_handle, "vkGetInstanceProcAddr"); + if(!vkGetInstanceProcAddr) + goto fail; + _this->vulkan_config.vkGetInstanceProcAddr = (void *)vkGetInstanceProcAddr; + _this->vulkan_config.vkEnumerateInstanceExtensionProperties = + (void *)((PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr)( + VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties"); + if(!_this->vulkan_config.vkEnumerateInstanceExtensionProperties) + goto fail; + extensions = SDL_Vulkan_CreateInstanceExtensionsList( + (PFN_vkEnumerateInstanceExtensionProperties) + _this->vulkan_config.vkEnumerateInstanceExtensionProperties, + &extensionCount); + if(!extensions) + goto fail; + for(i = 0; i < extensionCount; i++) + { + if(SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) + hasSurfaceExtension = SDL_TRUE; + else if(SDL_strcmp(VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) + hasDirectFBSurfaceExtension = SDL_TRUE; + } + SDL_free(extensions); + if(!hasSurfaceExtension) + { + SDL_SetError("Installed Vulkan doesn't implement the " + VK_KHR_SURFACE_EXTENSION_NAME " extension"); + goto fail; + } + else if(!hasDirectFBSurfaceExtension) + { + SDL_SetError("Installed Vulkan doesn't implement the " + VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME "extension"); + goto fail; + } + return 0; + +fail: + SDL_UnloadObject(_this->vulkan_config.loader_handle); + _this->vulkan_config.loader_handle = NULL; + return -1; +} + +void DirectFB_Vulkan_UnloadLibrary(_THIS) +{ + if(_this->vulkan_config.loader_handle) + { + SDL_UnloadObject(_this->vulkan_config.loader_handle); + _this->vulkan_config.loader_handle = NULL; + } +} + +SDL_bool DirectFB_Vulkan_GetInstanceExtensions(_THIS, + SDL_Window *window, + unsigned *count, + const char **names) +{ + static const char *const extensionsForDirectFB[] = { + VK_KHR_SURFACE_EXTENSION_NAME, VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME + }; + if(!_this->vulkan_config.loader_handle) + { + SDL_SetError("Vulkan is not loaded"); + return SDL_FALSE; + } + return SDL_Vulkan_GetInstanceExtensions_Helper( + count, names, SDL_arraysize(extensionsForDirectFB), + extensionsForDirectFB); +} + +SDL_bool DirectFB_Vulkan_CreateSurface(_THIS, + SDL_Window *window, + VkInstance instance, + VkSurfaceKHR *surface) +{ + SDL_DFB_DEVICEDATA(_this); + SDL_DFB_WINDOWDATA(window); + PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = + (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr; + PFN_vkCreateDirectFBSurfaceEXT vkCreateDirectFBSurfaceEXT = + (PFN_vkCreateDirectFBSurfaceEXT)vkGetInstanceProcAddr( + instance, + "vkCreateDirectFBSurfaceEXT"); + VkDirectFBSurfaceCreateInfoEXT createInfo; + VkResult result; + + if(!_this->vulkan_config.loader_handle) + { + SDL_SetError("Vulkan is not loaded"); + return SDL_FALSE; + } + + if(!vkCreateDirectFBSurfaceEXT) + { + SDL_SetError(VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME + " extension is not enabled in the Vulkan instance."); + return SDL_FALSE; + } + SDL_zero(createInfo); + createInfo.sType = VK_STRUCTURE_TYPE_DIRECTFB_SURFACE_CREATE_INFO_EXT; + createInfo.pNext = NULL; + createInfo.flags = 0; + createInfo.dfb = devdata->dfb; + createInfo.surface = windata->surface; + result = vkCreateDirectFBSurfaceEXT(instance, &createInfo, + NULL, surface); + if(result != VK_SUCCESS) + { + SDL_SetError("vkCreateDirectFBSurfaceEXT failed: %s", + SDL_Vulkan_GetResultString(result)); + return SDL_FALSE; + } + return SDL_TRUE; +} + +#endif + +/* vim: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_vulkan.h b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_vulkan.h new file mode 100644 index 0000000..de04213 --- /dev/null +++ b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_vulkan.h @@ -0,0 +1,47 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifndef SDL_DirectFB_vulkan_h_ +#define SDL_DirectFB_vulkan_h_ + +#include "../SDL_vulkan_internal.h" +#include "../SDL_sysvideo.h" + +#if defined(SDL_VIDEO_VULKAN) && defined(SDL_VIDEO_DRIVER_DIRECTFB) + +int DirectFB_Vulkan_LoadLibrary(_THIS, const char *path); +void DirectFB_Vulkan_UnloadLibrary(_THIS); +SDL_bool DirectFB_Vulkan_GetInstanceExtensions(_THIS, + SDL_Window *window, + unsigned *count, + const char **names); +SDL_bool DirectFB_Vulkan_CreateSurface(_THIS, + SDL_Window *window, + VkInstance instance, + VkSurfaceKHR *surface); + +#endif + +#endif /* SDL_DirectFB_vulkan_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/directfb/SDL_DirectFB_window.c b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_window.c similarity index 89% rename from SDL2-2.0.12/src/video/directfb/SDL_DirectFB_window.c rename to SDL2-2.30.5/src/video/directfb/SDL_DirectFB_window.c index fdba402..fb9ce7b 100644 --- a/SDL2-2.0.12/src/video/directfb/SDL_DirectFB_window.c +++ b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_window.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,14 +20,14 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_DIRECTFB +#ifdef SDL_VIDEO_DRIVER_DIRECTFB #include "SDL_DirectFB_video.h" #include "SDL_DirectFB_modes.h" #include "SDL_DirectFB_window.h" #include "SDL_DirectFB_shape.h" -#if SDL_DIRECTFB_OPENGL +#ifdef SDL_DIRECTFB_OPENGL #include "SDL_DirectFB_opengl.h" #endif @@ -35,8 +35,7 @@ #include "../SDL_pixels_c.h" -int -DirectFB_CreateWindow(_THIS, SDL_Window * window) +int DirectFB_CreateWindow(_THIS, SDL_Window * window) { SDL_DFB_DEVICEDATA(_this); SDL_DFB_DISPLAYDATA(window); @@ -173,14 +172,12 @@ DirectFB_CreateWindow(_THIS, SDL_Window * window) return -1; } -int -DirectFB_CreateWindowFrom(_THIS, SDL_Window * window, const void *data) +int DirectFB_CreateWindowFrom(_THIS, SDL_Window * window, const void *data) { return SDL_Unsupported(); } -void -DirectFB_SetWindowTitle(_THIS, SDL_Window * window) +void DirectFB_SetWindowTitle(_THIS, SDL_Window * window) { SDL_DFB_WINDOWDATA(window); @@ -192,8 +189,7 @@ DirectFB_SetWindowTitle(_THIS, SDL_Window * window) } } -void -DirectFB_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon) +void DirectFB_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon) { SDL_DFB_DEVICEDATA(_this); SDL_DFB_WINDOWDATA(window); @@ -227,7 +223,7 @@ DirectFB_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon) p = surface->pixels; for (i = 0; i < surface->h; i++) - memcpy((char *) dest + i * pitch, + SDL_memcpy((char *) dest + i * pitch, (char *) p + i * surface->pitch, 4 * surface->w); SDL_DFB_CHECK(windata->icon->Unlock(windata->icon)); @@ -242,8 +238,7 @@ DirectFB_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon) return; } -void -DirectFB_SetWindowPosition(_THIS, SDL_Window * window) +void DirectFB_SetWindowPosition(_THIS, SDL_Window * window) { SDL_DFB_WINDOWDATA(window); int x, y; @@ -255,8 +250,7 @@ DirectFB_SetWindowPosition(_THIS, SDL_Window * window) SDL_DFB_CHECK(windata->dfbwin->MoveTo(windata->dfbwin, x, y)); } -void -DirectFB_SetWindowSize(_THIS, SDL_Window * window) +void DirectFB_SetWindowSize(_THIS, SDL_Window * window) { SDL_DFB_WINDOWDATA(window); @@ -294,8 +288,7 @@ DirectFB_SetWindowSize(_THIS, SDL_Window * window) return; } -void -DirectFB_ShowWindow(_THIS, SDL_Window * window) +void DirectFB_ShowWindow(_THIS, SDL_Window * window) { SDL_DFB_WINDOWDATA(window); @@ -303,8 +296,7 @@ DirectFB_ShowWindow(_THIS, SDL_Window * window) } -void -DirectFB_HideWindow(_THIS, SDL_Window * window) +void DirectFB_HideWindow(_THIS, SDL_Window * window) { SDL_DFB_WINDOWDATA(window); @@ -312,8 +304,7 @@ DirectFB_HideWindow(_THIS, SDL_Window * window) SDL_DFB_CHECK(windata->dfbwin->SetOpacity(windata->dfbwin, 0)); } -void -DirectFB_RaiseWindow(_THIS, SDL_Window * window) +void DirectFB_RaiseWindow(_THIS, SDL_Window * window) { SDL_DFB_WINDOWDATA(window); @@ -321,8 +312,7 @@ DirectFB_RaiseWindow(_THIS, SDL_Window * window) SDL_DFB_CHECK(windata->dfbwin->RequestFocus(windata->dfbwin)); } -void -DirectFB_MaximizeWindow(_THIS, SDL_Window * window) +void DirectFB_MaximizeWindow(_THIS, SDL_Window * window) { SDL_DFB_WINDOWDATA(window); SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); @@ -345,16 +335,14 @@ DirectFB_MaximizeWindow(_THIS, SDL_Window * window) SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts)); } -void -DirectFB_MinimizeWindow(_THIS, SDL_Window * window) +void DirectFB_MinimizeWindow(_THIS, SDL_Window * window) { /* FIXME: Size to 32x32 ? */ SDL_Unsupported(); } -void -DirectFB_RestoreWindow(_THIS, SDL_Window * window) +void DirectFB_RestoreWindow(_THIS, SDL_Window * window) { SDL_DFB_WINDOWDATA(window); DFBWindowOptions wopts; @@ -382,31 +370,29 @@ DirectFB_RestoreWindow(_THIS, SDL_Window * window) } -void -DirectFB_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed) +void DirectFB_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed) { - SDL_DFB_DEVICEDATA(_this); SDL_DFB_WINDOWDATA(window); - DFB_WindowData *gwindata = ((devdata->grabbed_window) ? (DFB_WindowData *) ((devdata->grabbed_window)->driverdata) : NULL); - if ((window->flags & SDL_WINDOW_INPUT_GRABBED)) { - if (gwindata != NULL) - { - SDL_DFB_CHECK(gwindata->dfbwin->UngrabPointer(gwindata->dfbwin)); - SDL_DFB_CHECK(gwindata->dfbwin->UngrabKeyboard(gwindata->dfbwin)); - } + if (grabbed) { SDL_DFB_CHECK(windata->dfbwin->GrabPointer(windata->dfbwin)); - SDL_DFB_CHECK(windata->dfbwin->GrabKeyboard(windata->dfbwin)); - devdata->grabbed_window = window; } else { SDL_DFB_CHECK(windata->dfbwin->UngrabPointer(windata->dfbwin)); - SDL_DFB_CHECK(windata->dfbwin->UngrabKeyboard(windata->dfbwin)); - devdata->grabbed_window = NULL; } } -void -DirectFB_DestroyWindow(_THIS, SDL_Window * window) +void DirectFB_SetWindowKeyboardGrab(_THIS, SDL_Window * window, SDL_bool grabbed) +{ + SDL_DFB_WINDOWDATA(window); + + if (grabbed) { + SDL_DFB_CHECK(windata->dfbwin->GrabKeyboard(windata->dfbwin)); + } else { + SDL_DFB_CHECK(windata->dfbwin->UngrabKeyboard(windata->dfbwin)); + } +} + +void DirectFB_DestroyWindow(_THIS, SDL_Window * window) { SDL_DFB_DEVICEDATA(_this); SDL_DFB_WINDOWDATA(window); @@ -416,7 +402,7 @@ DirectFB_DestroyWindow(_THIS, SDL_Window * window) SDL_DFB_CHECK(windata->dfbwin->UngrabPointer(windata->dfbwin)); SDL_DFB_CHECK(windata->dfbwin->UngrabKeyboard(windata->dfbwin)); -#if SDL_DIRECTFB_OPENGL +#ifdef SDL_DIRECTFB_OPENGL DirectFB_GL_DestroyWindowContexts(_this, window); #endif @@ -454,8 +440,7 @@ DirectFB_DestroyWindow(_THIS, SDL_Window * window) return; } -SDL_bool -DirectFB_GetWindowWMInfo(_THIS, SDL_Window * window, +SDL_bool DirectFB_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo * info) { const Uint32 version = ((((Uint32) info->version.major) * 1000000) + @@ -481,22 +466,20 @@ DirectFB_GetWindowWMInfo(_THIS, SDL_Window * window, return SDL_FALSE; } - if (info->version.major == SDL_MAJOR_VERSION && - info->version.minor == SDL_MINOR_VERSION) { + if (info->version.major == SDL_MAJOR_VERSION) { info->subsystem = SDL_SYSWM_DIRECTFB; info->info.dfb.dfb = devdata->dfb; info->info.dfb.window = windata->dfbwin; info->info.dfb.surface = windata->surface; return SDL_TRUE; } else { - SDL_SetError("Application not compiled with SDL %d.%d", - SDL_MAJOR_VERSION, SDL_MINOR_VERSION); + SDL_SetError("Application not compiled with SDL %d", + SDL_MAJOR_VERSION); return SDL_FALSE; } } -void -DirectFB_AdjustWindowSurface(SDL_Window * window) +void DirectFB_AdjustWindowSurface(SDL_Window * window) { SDL_DFB_WINDOWDATA(window); int adjust = windata->wm_needs_redraw; @@ -512,7 +495,7 @@ DirectFB_AdjustWindowSurface(SDL_Window * window) } if (adjust) { -#if SDL_DIRECTFB_OPENGL +#ifdef SDL_DIRECTFB_OPENGL DirectFB_GL_FreeWindowContexts(SDL_GetVideoDevice(), window); #endif @@ -541,7 +524,7 @@ DirectFB_AdjustWindowSurface(SDL_Window * window) #endif DirectFB_WM_RedrawLayout(SDL_GetVideoDevice(), window); -#if SDL_DIRECTFB_OPENGL +#ifdef SDL_DIRECTFB_OPENGL DirectFB_GL_ReAllocWindowContexts(SDL_GetVideoDevice(), window); #endif } @@ -549,8 +532,7 @@ DirectFB_AdjustWindowSurface(SDL_Window * window) return; } -int -DirectFB_SetWindowOpacity(_THIS, SDL_Window * window, float opacity) +int DirectFB_SetWindowOpacity(_THIS, SDL_Window * window, float opacity) { const Uint8 alpha = (Uint8) ((unsigned int) (opacity * 255.0f)); SDL_DFB_WINDOWDATA(window); diff --git a/SDL2-2.0.12/src/video/directfb/SDL_DirectFB_window.h b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_window.h similarity index 93% rename from SDL2-2.0.12/src/video/directfb/SDL_DirectFB_window.h rename to SDL2-2.30.5/src/video/directfb/SDL_DirectFB_window.h index 1d789c7..f736e1e 100644 --- a/SDL2-2.0.12/src/video/directfb/SDL_DirectFB_window.h +++ b/SDL2-2.30.5/src/video/directfb/SDL_DirectFB_window.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -69,7 +69,8 @@ extern void DirectFB_RaiseWindow(_THIS, SDL_Window * window); extern void DirectFB_MaximizeWindow(_THIS, SDL_Window * window); extern void DirectFB_MinimizeWindow(_THIS, SDL_Window * window); extern void DirectFB_RestoreWindow(_THIS, SDL_Window * window); -extern void DirectFB_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed); +extern void DirectFB_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed); +extern void DirectFB_SetWindowKeyboardGrab(_THIS, SDL_Window * window, SDL_bool grabbed); extern void DirectFB_DestroyWindow(_THIS, SDL_Window * window); extern SDL_bool DirectFB_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info); diff --git a/SDL2-2.0.12/src/video/dummy/SDL_nullevents.c b/SDL2-2.30.5/src/video/dummy/SDL_nullevents.c similarity index 91% rename from SDL2-2.0.12/src/video/dummy/SDL_nullevents.c rename to SDL2-2.30.5/src/video/dummy/SDL_nullevents.c index 4db63b6..bbe02e0 100644 --- a/SDL2-2.0.12/src/video/dummy/SDL_nullevents.c +++ b/SDL2-2.30.5/src/video/dummy/SDL_nullevents.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_DUMMY +#ifdef SDL_VIDEO_DRIVER_DUMMY /* Being a null driver, there's no event stream. We just define stubs for most of the API. */ @@ -30,8 +30,7 @@ #include "SDL_nullvideo.h" #include "SDL_nullevents_c.h" -void -DUMMY_PumpEvents(_THIS) +void DUMMY_PumpEvents(_THIS) { /* do nothing. */ } diff --git a/SDL2-2.0.12/src/video/dummy/SDL_nullevents_c.h b/SDL2-2.30.5/src/video/dummy/SDL_nullevents_c.h similarity index 94% rename from SDL2-2.0.12/src/video/dummy/SDL_nullevents_c.h rename to SDL2-2.30.5/src/video/dummy/SDL_nullevents_c.h index ac56d68..14021c5 100644 --- a/SDL2-2.0.12/src/video/dummy/SDL_nullevents_c.h +++ b/SDL2-2.30.5/src/video/dummy/SDL_nullevents_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/video/dummy/SDL_nullframebuffer.c b/SDL2-2.30.5/src/video/dummy/SDL_nullframebuffer.c similarity index 63% rename from SDL2-2.0.12/src/video/dummy/SDL_nullframebuffer.c rename to SDL2-2.30.5/src/video/dummy/SDL_nullframebuffer.c index 803f131..22a9d27 100644 --- a/SDL2-2.0.12/src/video/dummy/SDL_nullframebuffer.c +++ b/SDL2-2.30.5/src/video/dummy/SDL_nullframebuffer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,30 +20,25 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_DUMMY +#ifdef SDL_VIDEO_DRIVER_DUMMY #include "../SDL_sysvideo.h" #include "SDL_nullframebuffer_c.h" +#define DUMMY_SURFACE "_SDL_DummySurface" -#define DUMMY_SURFACE "_SDL_DummySurface" - -int SDL_DUMMY_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch) +int SDL_DUMMY_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format, void **pixels, int *pitch) { SDL_Surface *surface; const Uint32 surface_format = SDL_PIXELFORMAT_RGB888; int w, h; - int bpp; - Uint32 Rmask, Gmask, Bmask, Amask; /* Free the old framebuffer surface */ - surface = (SDL_Surface *) SDL_GetWindowData(window, DUMMY_SURFACE); - SDL_FreeSurface(surface); + SDL_DUMMY_DestroyWindowFramebuffer(_this, window); /* Create a new one */ - SDL_PixelFormatEnumToMasks(surface_format, &bpp, &Rmask, &Gmask, &Bmask, &Amask); - SDL_GetWindowSize(window, &w, &h); - surface = SDL_CreateRGBSurface(0, w, h, bpp, Rmask, Gmask, Bmask, Amask); + SDL_GetWindowSizeInPixels(window, &w, &h); + surface = SDL_CreateRGBSurfaceWithFormat(0, w, h, 0, surface_format); if (!surface) { return -1; } @@ -56,12 +51,12 @@ int SDL_DUMMY_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * forma return 0; } -int SDL_DUMMY_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects) +int SDL_DUMMY_UpdateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_Rect *rects, int numrects) { static int frame_number; SDL_Surface *surface; - surface = (SDL_Surface *) SDL_GetWindowData(window, DUMMY_SURFACE); + surface = (SDL_Surface *)SDL_GetWindowData(window, DUMMY_SURFACE); if (!surface) { return SDL_SetError("Couldn't find dummy surface for window"); } @@ -69,18 +64,18 @@ int SDL_DUMMY_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect /* Send the data to the display */ if (SDL_getenv("SDL_VIDEO_DUMMY_SAVE_FRAMES")) { char file[128]; - SDL_snprintf(file, sizeof(file), "SDL_window%d-%8.8d.bmp", - SDL_GetWindowID(window), ++frame_number); + (void)SDL_snprintf(file, sizeof(file), "SDL_window%" SDL_PRIu32 "-%8.8d.bmp", + SDL_GetWindowID(window), ++frame_number); SDL_SaveBMP(surface, file); } return 0; } -void SDL_DUMMY_DestroyWindowFramebuffer(_THIS, SDL_Window * window) +void SDL_DUMMY_DestroyWindowFramebuffer(_THIS, SDL_Window *window) { SDL_Surface *surface; - surface = (SDL_Surface *) SDL_SetWindowData(window, DUMMY_SURFACE, NULL); + surface = (SDL_Surface *)SDL_SetWindowData(window, DUMMY_SURFACE, NULL); SDL_FreeSurface(surface); } diff --git a/SDL2-2.0.12/src/video/dummy/SDL_nullframebuffer_c.h b/SDL2-2.30.5/src/video/dummy/SDL_nullframebuffer_c.h similarity index 87% rename from SDL2-2.0.12/src/video/dummy/SDL_nullframebuffer_c.h rename to SDL2-2.30.5/src/video/dummy/SDL_nullframebuffer_c.h index 5b1dea3..dea414e 100644 --- a/SDL2-2.0.12/src/video/dummy/SDL_nullframebuffer_c.h +++ b/SDL2-2.30.5/src/video/dummy/SDL_nullframebuffer_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -24,9 +24,9 @@ #include "../../SDL_internal.h" -extern int SDL_DUMMY_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch); -extern int SDL_DUMMY_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects); -extern void SDL_DUMMY_DestroyWindowFramebuffer(_THIS, SDL_Window * window); +extern int SDL_DUMMY_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format, void **pixels, int *pitch); +extern int SDL_DUMMY_UpdateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_Rect *rects, int numrects); +extern void SDL_DUMMY_DestroyWindowFramebuffer(_THIS, SDL_Window *window); #endif /* SDL_nullframebuffer_c_h_ */ diff --git a/SDL2-2.0.12/src/video/dummy/SDL_nullvideo.c b/SDL2-2.30.5/src/video/dummy/SDL_nullvideo.c similarity index 67% rename from SDL2-2.0.12/src/video/dummy/SDL_nullvideo.c rename to SDL2-2.30.5/src/video/dummy/SDL_nullvideo.c index d293723..930e989 100644 --- a/SDL2-2.0.12/src/video/dummy/SDL_nullvideo.c +++ b/SDL2-2.30.5/src/video/dummy/SDL_nullvideo.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_DUMMY +#ifdef SDL_VIDEO_DRIVER_DUMMY /* Dummy SDL video driver implementation; this is just enough to make an * SDL-based application THINK it's got a working video driver, for @@ -46,51 +46,69 @@ #include "SDL_nullvideo.h" #include "SDL_nullevents_c.h" #include "SDL_nullframebuffer_c.h" +#include "SDL_hints.h" -#define DUMMYVID_DRIVER_NAME "dummy" +#define DUMMYVID_DRIVER_NAME "dummy" +#define DUMMYVID_DRIVER_EVDEV_NAME "evdev" /* Initialization/Query functions */ static int DUMMY_VideoInit(_THIS); -static int DUMMY_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode); static void DUMMY_VideoQuit(_THIS); +#ifdef SDL_INPUT_LINUXEV +static int evdev = 0; +static void DUMMY_EVDEV_Poll(_THIS); +#endif + /* DUMMY driver bootstrap functions */ -static int -DUMMY_Available(void) +static int DUMMY_Available(void) { - const char *envr = SDL_getenv("SDL_VIDEODRIVER"); - if ((envr) && (SDL_strcmp(envr, DUMMYVID_DRIVER_NAME) == 0)) { - return (1); + const char *envr = SDL_GetHint(SDL_HINT_VIDEODRIVER); + if (envr) { + if (SDL_strcmp(envr, DUMMYVID_DRIVER_NAME) == 0) { + return 1; + } +#ifdef SDL_INPUT_LINUXEV + if (SDL_strcmp(envr, DUMMYVID_DRIVER_EVDEV_NAME) == 0) { + evdev = 1; + return 1; + } +#endif } - - return (0); + return 0; } -static void -DUMMY_DeleteDevice(SDL_VideoDevice * device) +static void DUMMY_DeleteDevice(SDL_VideoDevice *device) { SDL_free(device); } -static SDL_VideoDevice * -DUMMY_CreateDevice(int devindex) +static SDL_VideoDevice *DUMMY_CreateDevice(void) { SDL_VideoDevice *device; + if (!DUMMY_Available()) { + return 0; + } + /* Initialize all variables that we clean on shutdown */ - device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice)); + device = (SDL_VideoDevice *)SDL_calloc(1, sizeof(SDL_VideoDevice)); if (!device) { SDL_OutOfMemory(); - return (0); + return 0; } device->is_dummy = SDL_TRUE; /* Set the function pointers */ device->VideoInit = DUMMY_VideoInit; device->VideoQuit = DUMMY_VideoQuit; - device->SetDisplayMode = DUMMY_SetDisplayMode; device->PumpEvents = DUMMY_PumpEvents; +#ifdef SDL_INPUT_LINUXEV + if (evdev) { + device->PumpEvents = DUMMY_EVDEV_Poll; + } +#endif device->CreateWindowFramebuffer = SDL_DUMMY_CreateWindowFramebuffer; device->UpdateWindowFramebuffer = SDL_DUMMY_UpdateWindowFramebuffer; device->DestroyWindowFramebuffer = SDL_DUMMY_DestroyWindowFramebuffer; @@ -102,41 +120,56 @@ DUMMY_CreateDevice(int devindex) VideoBootStrap DUMMY_bootstrap = { DUMMYVID_DRIVER_NAME, "SDL dummy video driver", - DUMMY_Available, DUMMY_CreateDevice + DUMMY_CreateDevice, + NULL /* no ShowMessageBox implementation */ }; +#ifdef SDL_INPUT_LINUXEV +VideoBootStrap DUMMY_evdev_bootstrap = { + DUMMYVID_DRIVER_EVDEV_NAME, "SDL dummy video driver with evdev", + DUMMY_CreateDevice, + NULL /* no ShowMessageBox implementation */ +}; +void SDL_EVDEV_Init(void); +void SDL_EVDEV_Poll(); +void SDL_EVDEV_Quit(void); +static void DUMMY_EVDEV_Poll(_THIS) +{ + (void)_this; + SDL_EVDEV_Poll(); +} +#endif -int -DUMMY_VideoInit(_THIS) +int DUMMY_VideoInit(_THIS) { SDL_DisplayMode mode; /* Use a fake 32-bpp desktop mode */ + SDL_zero(mode); mode.format = SDL_PIXELFORMAT_RGB888; mode.w = 1024; mode.h = 768; - mode.refresh_rate = 0; + mode.refresh_rate = 60; mode.driverdata = NULL; if (SDL_AddBasicVideoDisplay(&mode) < 0) { return -1; } - SDL_zero(mode); SDL_AddDisplayMode(&_this->displays[0], &mode); +#ifdef SDL_INPUT_LINUXEV + SDL_EVDEV_Init(); +#endif + /* We're done! */ return 0; } -static int -DUMMY_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) -{ - return 0; -} - -void -DUMMY_VideoQuit(_THIS) +void DUMMY_VideoQuit(_THIS) { +#ifdef SDL_INPUT_LINUXEV + SDL_EVDEV_Quit(); +#endif } #endif /* SDL_VIDEO_DRIVER_DUMMY */ diff --git a/SDL2-2.0.12/src/video/dummy/SDL_nullvideo.h b/SDL2-2.30.5/src/video/dummy/SDL_nullvideo.h similarity index 94% rename from SDL2-2.0.12/src/video/dummy/SDL_nullvideo.h rename to SDL2-2.30.5/src/video/dummy/SDL_nullvideo.h index e5c01d9..84a18a9 100644 --- a/SDL2-2.0.12/src/video/dummy/SDL_nullvideo.h +++ b/SDL2-2.30.5/src/video/dummy/SDL_nullvideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.30.5/src/video/emscripten/SDL_emscriptenevents.c b/SDL2-2.30.5/src/video/emscripten/SDL_emscriptenevents.c new file mode 100644 index 0000000..2017a6a --- /dev/null +++ b/SDL2-2.30.5/src/video/emscripten/SDL_emscriptenevents.c @@ -0,0 +1,1029 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_EMSCRIPTEN + +#include +#include + +#include "../../events/SDL_events_c.h" +#include "../../events/SDL_keyboard_c.h" +#include "../../events/SDL_touch_c.h" + +#include "SDL_emscriptenevents.h" +#include "SDL_emscriptenvideo.h" + +#include "SDL_hints.h" + +#define FULLSCREEN_MASK ( SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_FULLSCREEN ) + +/* +.keyCode to SDL keycode +https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent +https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode +*/ +static const SDL_Keycode emscripten_keycode_table[] = { + /* 0 */ SDLK_UNKNOWN, + /* 1 */ SDLK_UNKNOWN, + /* 2 */ SDLK_UNKNOWN, + /* 3 */ SDLK_CANCEL, + /* 4 */ SDLK_UNKNOWN, + /* 5 */ SDLK_UNKNOWN, + /* 6 */ SDLK_HELP, + /* 7 */ SDLK_UNKNOWN, + /* 8 */ SDLK_BACKSPACE, + /* 9 */ SDLK_TAB, + /* 10 */ SDLK_UNKNOWN, + /* 11 */ SDLK_UNKNOWN, + /* 12 */ SDLK_KP_5, + /* 13 */ SDLK_RETURN, + /* 14 */ SDLK_UNKNOWN, + /* 15 */ SDLK_UNKNOWN, + /* 16 */ SDLK_LSHIFT, + /* 17 */ SDLK_LCTRL, + /* 18 */ SDLK_LALT, + /* 19 */ SDLK_PAUSE, + /* 20 */ SDLK_CAPSLOCK, + /* 21 */ SDLK_UNKNOWN, + /* 22 */ SDLK_UNKNOWN, + /* 23 */ SDLK_UNKNOWN, + /* 24 */ SDLK_UNKNOWN, + /* 25 */ SDLK_UNKNOWN, + /* 26 */ SDLK_UNKNOWN, + /* 27 */ SDLK_ESCAPE, + /* 28 */ SDLK_UNKNOWN, + /* 29 */ SDLK_UNKNOWN, + /* 30 */ SDLK_UNKNOWN, + /* 31 */ SDLK_UNKNOWN, + /* 32 */ SDLK_SPACE, + /* 33 */ SDLK_PAGEUP, + /* 34 */ SDLK_PAGEDOWN, + /* 35 */ SDLK_END, + /* 36 */ SDLK_HOME, + /* 37 */ SDLK_LEFT, + /* 38 */ SDLK_UP, + /* 39 */ SDLK_RIGHT, + /* 40 */ SDLK_DOWN, + /* 41 */ SDLK_UNKNOWN, + /* 42 */ SDLK_UNKNOWN, + /* 43 */ SDLK_UNKNOWN, + /* 44 */ SDLK_UNKNOWN, + /* 45 */ SDLK_INSERT, + /* 46 */ SDLK_DELETE, + /* 47 */ SDLK_UNKNOWN, + /* 48 */ SDLK_0, + /* 49 */ SDLK_1, + /* 50 */ SDLK_2, + /* 51 */ SDLK_3, + /* 52 */ SDLK_4, + /* 53 */ SDLK_5, + /* 54 */ SDLK_6, + /* 55 */ SDLK_7, + /* 56 */ SDLK_8, + /* 57 */ SDLK_9, + /* 58 */ SDLK_UNKNOWN, + /* 59 */ SDLK_SEMICOLON, + /* 60 */ SDLK_BACKSLASH /*SDL_SCANCODE_NONUSBACKSLASH*/, + /* 61 */ SDLK_EQUALS, + /* 62 */ SDLK_UNKNOWN, + /* 63 */ SDLK_MINUS, + /* 64 */ SDLK_UNKNOWN, + /* 65 */ SDLK_a, + /* 66 */ SDLK_b, + /* 67 */ SDLK_c, + /* 68 */ SDLK_d, + /* 69 */ SDLK_e, + /* 70 */ SDLK_f, + /* 71 */ SDLK_g, + /* 72 */ SDLK_h, + /* 73 */ SDLK_i, + /* 74 */ SDLK_j, + /* 75 */ SDLK_k, + /* 76 */ SDLK_l, + /* 77 */ SDLK_m, + /* 78 */ SDLK_n, + /* 79 */ SDLK_o, + /* 80 */ SDLK_p, + /* 81 */ SDLK_q, + /* 82 */ SDLK_r, + /* 83 */ SDLK_s, + /* 84 */ SDLK_t, + /* 85 */ SDLK_u, + /* 86 */ SDLK_v, + /* 87 */ SDLK_w, + /* 88 */ SDLK_x, + /* 89 */ SDLK_y, + /* 90 */ SDLK_z, + /* 91 */ SDLK_LGUI, + /* 92 */ SDLK_UNKNOWN, + /* 93 */ SDLK_APPLICATION, + /* 94 */ SDLK_UNKNOWN, + /* 95 */ SDLK_UNKNOWN, + /* 96 */ SDLK_KP_0, + /* 97 */ SDLK_KP_1, + /* 98 */ SDLK_KP_2, + /* 99 */ SDLK_KP_3, + /* 100 */ SDLK_KP_4, + /* 101 */ SDLK_KP_5, + /* 102 */ SDLK_KP_6, + /* 103 */ SDLK_KP_7, + /* 104 */ SDLK_KP_8, + /* 105 */ SDLK_KP_9, + /* 106 */ SDLK_KP_MULTIPLY, + /* 107 */ SDLK_KP_PLUS, + /* 108 */ SDLK_UNKNOWN, + /* 109 */ SDLK_KP_MINUS, + /* 110 */ SDLK_KP_PERIOD, + /* 111 */ SDLK_KP_DIVIDE, + /* 112 */ SDLK_F1, + /* 113 */ SDLK_F2, + /* 114 */ SDLK_F3, + /* 115 */ SDLK_F4, + /* 116 */ SDLK_F5, + /* 117 */ SDLK_F6, + /* 118 */ SDLK_F7, + /* 119 */ SDLK_F8, + /* 120 */ SDLK_F9, + /* 121 */ SDLK_F10, + /* 122 */ SDLK_F11, + /* 123 */ SDLK_F12, + /* 124 */ SDLK_F13, + /* 125 */ SDLK_F14, + /* 126 */ SDLK_F15, + /* 127 */ SDLK_F16, + /* 128 */ SDLK_F17, + /* 129 */ SDLK_F18, + /* 130 */ SDLK_F19, + /* 131 */ SDLK_F20, + /* 132 */ SDLK_F21, + /* 133 */ SDLK_F22, + /* 134 */ SDLK_F23, + /* 135 */ SDLK_F24, + /* 136 */ SDLK_UNKNOWN, + /* 137 */ SDLK_UNKNOWN, + /* 138 */ SDLK_UNKNOWN, + /* 139 */ SDLK_UNKNOWN, + /* 140 */ SDLK_UNKNOWN, + /* 141 */ SDLK_UNKNOWN, + /* 142 */ SDLK_UNKNOWN, + /* 143 */ SDLK_UNKNOWN, + /* 144 */ SDLK_NUMLOCKCLEAR, + /* 145 */ SDLK_SCROLLLOCK, + /* 146 */ SDLK_UNKNOWN, + /* 147 */ SDLK_UNKNOWN, + /* 148 */ SDLK_UNKNOWN, + /* 149 */ SDLK_UNKNOWN, + /* 150 */ SDLK_UNKNOWN, + /* 151 */ SDLK_UNKNOWN, + /* 152 */ SDLK_UNKNOWN, + /* 153 */ SDLK_UNKNOWN, + /* 154 */ SDLK_UNKNOWN, + /* 155 */ SDLK_UNKNOWN, + /* 156 */ SDLK_UNKNOWN, + /* 157 */ SDLK_UNKNOWN, + /* 158 */ SDLK_UNKNOWN, + /* 159 */ SDLK_UNKNOWN, + /* 160 */ SDLK_BACKQUOTE, + /* 161 */ SDLK_UNKNOWN, + /* 162 */ SDLK_UNKNOWN, + /* 163 */ SDLK_KP_HASH, /*KaiOS phone keypad*/ + /* 164 */ SDLK_UNKNOWN, + /* 165 */ SDLK_UNKNOWN, + /* 166 */ SDLK_UNKNOWN, + /* 167 */ SDLK_UNKNOWN, + /* 168 */ SDLK_UNKNOWN, + /* 169 */ SDLK_UNKNOWN, + /* 170 */ SDLK_KP_MULTIPLY, /*KaiOS phone keypad*/ + /* 171 */ SDLK_RIGHTBRACKET, + /* 172 */ SDLK_UNKNOWN, + /* 173 */ SDLK_MINUS, /*FX*/ + /* 174 */ SDLK_VOLUMEDOWN, /*IE, Chrome*/ + /* 175 */ SDLK_VOLUMEUP, /*IE, Chrome*/ + /* 176 */ SDLK_AUDIONEXT, /*IE, Chrome*/ + /* 177 */ SDLK_AUDIOPREV, /*IE, Chrome*/ + /* 178 */ SDLK_UNKNOWN, + /* 179 */ SDLK_AUDIOPLAY, /*IE, Chrome*/ + /* 180 */ SDLK_UNKNOWN, + /* 181 */ SDLK_AUDIOMUTE, /*FX*/ + /* 182 */ SDLK_VOLUMEDOWN, /*FX*/ + /* 183 */ SDLK_VOLUMEUP, /*FX*/ + /* 184 */ SDLK_UNKNOWN, + /* 185 */ SDLK_UNKNOWN, + /* 186 */ SDLK_SEMICOLON, /*IE, Chrome, D3E legacy*/ + /* 187 */ SDLK_EQUALS, /*IE, Chrome, D3E legacy*/ + /* 188 */ SDLK_COMMA, + /* 189 */ SDLK_MINUS, /*IE, Chrome, D3E legacy*/ + /* 190 */ SDLK_PERIOD, + /* 191 */ SDLK_SLASH, + /* 192 */ SDLK_BACKQUOTE, /*FX, D3E legacy (SDLK_APOSTROPHE in IE/Chrome)*/ + /* 193 */ SDLK_UNKNOWN, + /* 194 */ SDLK_UNKNOWN, + /* 195 */ SDLK_UNKNOWN, + /* 196 */ SDLK_UNKNOWN, + /* 197 */ SDLK_UNKNOWN, + /* 198 */ SDLK_UNKNOWN, + /* 199 */ SDLK_UNKNOWN, + /* 200 */ SDLK_UNKNOWN, + /* 201 */ SDLK_UNKNOWN, + /* 202 */ SDLK_UNKNOWN, + /* 203 */ SDLK_UNKNOWN, + /* 204 */ SDLK_UNKNOWN, + /* 205 */ SDLK_UNKNOWN, + /* 206 */ SDLK_UNKNOWN, + /* 207 */ SDLK_UNKNOWN, + /* 208 */ SDLK_UNKNOWN, + /* 209 */ SDLK_UNKNOWN, + /* 210 */ SDLK_UNKNOWN, + /* 211 */ SDLK_UNKNOWN, + /* 212 */ SDLK_UNKNOWN, + /* 213 */ SDLK_UNKNOWN, + /* 214 */ SDLK_UNKNOWN, + /* 215 */ SDLK_UNKNOWN, + /* 216 */ SDLK_UNKNOWN, + /* 217 */ SDLK_UNKNOWN, + /* 218 */ SDLK_UNKNOWN, + /* 219 */ SDLK_LEFTBRACKET, + /* 220 */ SDLK_BACKSLASH, + /* 221 */ SDLK_RIGHTBRACKET, + /* 222 */ SDLK_QUOTE, /*FX, D3E legacy*/ +}; + +/* +Emscripten PK code to scancode +https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent +https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code +*/ +static const SDL_Scancode emscripten_scancode_table[] = { + /* 0x00 "Unidentified" */ SDL_SCANCODE_UNKNOWN, + /* 0x01 "Escape" */ SDL_SCANCODE_ESCAPE, + /* 0x02 "Digit0" */ SDL_SCANCODE_0, + /* 0x03 "Digit1" */ SDL_SCANCODE_1, + /* 0x04 "Digit2" */ SDL_SCANCODE_2, + /* 0x05 "Digit3" */ SDL_SCANCODE_3, + /* 0x06 "Digit4" */ SDL_SCANCODE_4, + /* 0x07 "Digit5" */ SDL_SCANCODE_5, + /* 0x08 "Digit6" */ SDL_SCANCODE_6, + /* 0x09 "Digit7" */ SDL_SCANCODE_7, + /* 0x0A "Digit8" */ SDL_SCANCODE_8, + /* 0x0B "Digit9" */ SDL_SCANCODE_9, + /* 0x0C "Minus" */ SDL_SCANCODE_MINUS, + /* 0x0D "Equal" */ SDL_SCANCODE_EQUALS, + /* 0x0E "Backspace" */ SDL_SCANCODE_BACKSPACE, + /* 0x0F "Tab" */ SDL_SCANCODE_TAB, + /* 0x10 "KeyQ" */ SDL_SCANCODE_Q, + /* 0x11 "KeyW" */ SDL_SCANCODE_W, + /* 0x12 "KeyE" */ SDL_SCANCODE_E, + /* 0x13 "KeyR" */ SDL_SCANCODE_R, + /* 0x14 "KeyT" */ SDL_SCANCODE_T, + /* 0x15 "KeyY" */ SDL_SCANCODE_Y, + /* 0x16 "KeyU" */ SDL_SCANCODE_U, + /* 0x17 "KeyI" */ SDL_SCANCODE_I, + /* 0x18 "KeyO" */ SDL_SCANCODE_O, + /* 0x19 "KeyP" */ SDL_SCANCODE_P, + /* 0x1A "BracketLeft" */ SDL_SCANCODE_LEFTBRACKET, + /* 0x1B "BracketRight" */ SDL_SCANCODE_RIGHTBRACKET, + /* 0x1C "Enter" */ SDL_SCANCODE_RETURN, + /* 0x1D "ControlLeft" */ SDL_SCANCODE_LCTRL, + /* 0x1E "KeyA" */ SDL_SCANCODE_A, + /* 0x1F "KeyS" */ SDL_SCANCODE_S, + /* 0x20 "KeyD" */ SDL_SCANCODE_D, + /* 0x21 "KeyF" */ SDL_SCANCODE_F, + /* 0x22 "KeyG" */ SDL_SCANCODE_G, + /* 0x23 "KeyH" */ SDL_SCANCODE_H, + /* 0x24 "KeyJ" */ SDL_SCANCODE_J, + /* 0x25 "KeyK" */ SDL_SCANCODE_K, + /* 0x26 "KeyL" */ SDL_SCANCODE_L, + /* 0x27 "Semicolon" */ SDL_SCANCODE_SEMICOLON, + /* 0x28 "Quote" */ SDL_SCANCODE_APOSTROPHE, + /* 0x29 "Backquote" */ SDL_SCANCODE_GRAVE, + /* 0x2A "ShiftLeft" */ SDL_SCANCODE_LSHIFT, + /* 0x2B "Backslash" */ SDL_SCANCODE_BACKSLASH, + /* 0x2C "KeyZ" */ SDL_SCANCODE_Z, + /* 0x2D "KeyX" */ SDL_SCANCODE_X, + /* 0x2E "KeyC" */ SDL_SCANCODE_C, + /* 0x2F "KeyV" */ SDL_SCANCODE_V, + /* 0x30 "KeyB" */ SDL_SCANCODE_B, + /* 0x31 "KeyN" */ SDL_SCANCODE_N, + /* 0x32 "KeyM" */ SDL_SCANCODE_M, + /* 0x33 "Comma" */ SDL_SCANCODE_COMMA, + /* 0x34 "Period" */ SDL_SCANCODE_PERIOD, + /* 0x35 "Slash" */ SDL_SCANCODE_SLASH, + /* 0x36 "ShiftRight" */ SDL_SCANCODE_RSHIFT, + /* 0x37 "NumpadMultiply" */ SDL_SCANCODE_KP_MULTIPLY, + /* 0x38 "AltLeft" */ SDL_SCANCODE_LALT, + /* 0x39 "Space" */ SDL_SCANCODE_SPACE, + /* 0x3A "CapsLock" */ SDL_SCANCODE_CAPSLOCK, + /* 0x3B "F1" */ SDL_SCANCODE_F1, + /* 0x3C "F2" */ SDL_SCANCODE_F2, + /* 0x3D "F3" */ SDL_SCANCODE_F3, + /* 0x3E "F4" */ SDL_SCANCODE_F4, + /* 0x3F "F5" */ SDL_SCANCODE_F5, + /* 0x40 "F6" */ SDL_SCANCODE_F6, + /* 0x41 "F7" */ SDL_SCANCODE_F7, + /* 0x42 "F8" */ SDL_SCANCODE_F8, + /* 0x43 "F9" */ SDL_SCANCODE_F9, + /* 0x44 "F10" */ SDL_SCANCODE_F10, + /* 0x45 "Pause" */ SDL_SCANCODE_PAUSE, + /* 0x46 "ScrollLock" */ SDL_SCANCODE_SCROLLLOCK, + /* 0x47 "Numpad7" */ SDL_SCANCODE_KP_7, + /* 0x48 "Numpad8" */ SDL_SCANCODE_KP_8, + /* 0x49 "Numpad9" */ SDL_SCANCODE_KP_9, + /* 0x4A "NumpadSubtract" */ SDL_SCANCODE_KP_MINUS, + /* 0x4B "Numpad4" */ SDL_SCANCODE_KP_4, + /* 0x4C "Numpad5" */ SDL_SCANCODE_KP_5, + /* 0x4D "Numpad6" */ SDL_SCANCODE_KP_6, + /* 0x4E "NumpadAdd" */ SDL_SCANCODE_KP_PLUS, + /* 0x4F "Numpad1" */ SDL_SCANCODE_KP_1, + /* 0x50 "Numpad2" */ SDL_SCANCODE_KP_2, + /* 0x51 "Numpad3" */ SDL_SCANCODE_KP_3, + /* 0x52 "Numpad0" */ SDL_SCANCODE_KP_0, + /* 0x53 "NumpadDecimal" */ SDL_SCANCODE_KP_PERIOD, + /* 0x54 "PrintScreen" */ SDL_SCANCODE_PRINTSCREEN, + /* 0x55 */ SDL_SCANCODE_UNKNOWN, + /* 0x56 "IntlBackslash" */ SDL_SCANCODE_NONUSBACKSLASH, + /* 0x57 "F11" */ SDL_SCANCODE_F11, + /* 0x58 "F12" */ SDL_SCANCODE_F12, + /* 0x59 "NumpadEqual" */ SDL_SCANCODE_KP_EQUALS, + /* 0x5A */ SDL_SCANCODE_UNKNOWN, + /* 0x5B */ SDL_SCANCODE_UNKNOWN, + /* 0x5C */ SDL_SCANCODE_UNKNOWN, + /* 0x5D */ SDL_SCANCODE_UNKNOWN, + /* 0x5E */ SDL_SCANCODE_UNKNOWN, + /* 0x5F */ SDL_SCANCODE_UNKNOWN, + /* 0x60 */ SDL_SCANCODE_UNKNOWN, + /* 0x61 */ SDL_SCANCODE_UNKNOWN, + /* 0x62 */ SDL_SCANCODE_UNKNOWN, + /* 0x63 */ SDL_SCANCODE_UNKNOWN, + /* 0x64 "F13" */ SDL_SCANCODE_F13, + /* 0x65 "F14" */ SDL_SCANCODE_F14, + /* 0x66 "F15" */ SDL_SCANCODE_F15, + /* 0x67 "F16" */ SDL_SCANCODE_F16, + /* 0x68 "F17" */ SDL_SCANCODE_F17, + /* 0x69 "F18" */ SDL_SCANCODE_F18, + /* 0x6A "F19" */ SDL_SCANCODE_F19, + /* 0x6B "F20" */ SDL_SCANCODE_F20, + /* 0x6C "F21" */ SDL_SCANCODE_F21, + /* 0x6D "F22" */ SDL_SCANCODE_F22, + /* 0x6E "F23" */ SDL_SCANCODE_F23, + /* 0x6F */ SDL_SCANCODE_UNKNOWN, + /* 0x70 "KanaMode" */ SDL_SCANCODE_INTERNATIONAL2, + /* 0x71 "Lang2" */ SDL_SCANCODE_LANG2, + /* 0x72 "Lang1" */ SDL_SCANCODE_LANG1, + /* 0x73 "IntlRo" */ SDL_SCANCODE_INTERNATIONAL1, + /* 0x74 */ SDL_SCANCODE_UNKNOWN, + /* 0x75 */ SDL_SCANCODE_UNKNOWN, + /* 0x76 "F24" */ SDL_SCANCODE_F24, + /* 0x77 */ SDL_SCANCODE_UNKNOWN, + /* 0x78 */ SDL_SCANCODE_UNKNOWN, + /* 0x79 "Convert" */ SDL_SCANCODE_INTERNATIONAL4, + /* 0x7A */ SDL_SCANCODE_UNKNOWN, + /* 0x7B "NonConvert" */ SDL_SCANCODE_INTERNATIONAL5, + /* 0x7C */ SDL_SCANCODE_UNKNOWN, + /* 0x7D "IntlYen" */ SDL_SCANCODE_INTERNATIONAL3, + /* 0x7E "NumpadComma" */ SDL_SCANCODE_KP_COMMA +}; + +static SDL_Scancode Emscripten_MapScanCode(const char *code) +{ + const DOM_PK_CODE_TYPE pk_code = emscripten_compute_dom_pk_code(code); + if (pk_code < SDL_arraysize(emscripten_scancode_table)) { + return emscripten_scancode_table[pk_code]; + } + + switch (pk_code) { + case DOM_PK_PASTE: + return SDL_SCANCODE_PASTE; + case DOM_PK_MEDIA_TRACK_PREVIOUS: + return SDL_SCANCODE_AUDIOPREV; + case DOM_PK_CUT: + return SDL_SCANCODE_CUT; + case DOM_PK_COPY: + return SDL_SCANCODE_COPY; + case DOM_PK_MEDIA_TRACK_NEXT: + return SDL_SCANCODE_AUDIONEXT; + case DOM_PK_NUMPAD_ENTER: + return SDL_SCANCODE_KP_ENTER; + case DOM_PK_CONTROL_RIGHT: + return SDL_SCANCODE_RCTRL; + case DOM_PK_AUDIO_VOLUME_MUTE: + return SDL_SCANCODE_AUDIOMUTE; + case DOM_PK_LAUNCH_APP_2: + return SDL_SCANCODE_CALCULATOR; + case DOM_PK_MEDIA_PLAY_PAUSE: + return SDL_SCANCODE_AUDIOPLAY; + case DOM_PK_MEDIA_STOP: + return SDL_SCANCODE_AUDIOSTOP; + case DOM_PK_EJECT: + return SDL_SCANCODE_EJECT; + case DOM_PK_AUDIO_VOLUME_DOWN: + return SDL_SCANCODE_VOLUMEDOWN; + case DOM_PK_AUDIO_VOLUME_UP: + return SDL_SCANCODE_VOLUMEUP; + case DOM_PK_BROWSER_HOME: + return SDL_SCANCODE_AC_HOME; + case DOM_PK_NUMPAD_DIVIDE: + return SDL_SCANCODE_KP_DIVIDE; + case DOM_PK_ALT_RIGHT: + return SDL_SCANCODE_RALT; + case DOM_PK_HELP: + return SDL_SCANCODE_HELP; + case DOM_PK_NUM_LOCK: + return SDL_SCANCODE_NUMLOCKCLEAR; + case DOM_PK_HOME: + return SDL_SCANCODE_HOME; + case DOM_PK_ARROW_UP: + return SDL_SCANCODE_UP; + case DOM_PK_PAGE_UP: + return SDL_SCANCODE_PAGEUP; + case DOM_PK_ARROW_LEFT: + return SDL_SCANCODE_LEFT; + case DOM_PK_ARROW_RIGHT: + return SDL_SCANCODE_RIGHT; + case DOM_PK_END: + return SDL_SCANCODE_END; + case DOM_PK_ARROW_DOWN: + return SDL_SCANCODE_DOWN; + case DOM_PK_PAGE_DOWN: + return SDL_SCANCODE_PAGEDOWN; + case DOM_PK_INSERT: + return SDL_SCANCODE_INSERT; + case DOM_PK_DELETE: + return SDL_SCANCODE_DELETE; + case DOM_PK_META_LEFT: + return SDL_SCANCODE_LGUI; + case DOM_PK_META_RIGHT: + return SDL_SCANCODE_RGUI; + case DOM_PK_CONTEXT_MENU: + return SDL_SCANCODE_APPLICATION; + case DOM_PK_POWER: + return SDL_SCANCODE_POWER; + case DOM_PK_BROWSER_SEARCH: + return SDL_SCANCODE_AC_SEARCH; + case DOM_PK_BROWSER_FAVORITES: + return SDL_SCANCODE_AC_BOOKMARKS; + case DOM_PK_BROWSER_REFRESH: + return SDL_SCANCODE_AC_REFRESH; + case DOM_PK_BROWSER_STOP: + return SDL_SCANCODE_AC_STOP; + case DOM_PK_BROWSER_FORWARD: + return SDL_SCANCODE_AC_FORWARD; + case DOM_PK_BROWSER_BACK: + return SDL_SCANCODE_AC_BACK; + case DOM_PK_LAUNCH_APP_1: + return SDL_SCANCODE_COMPUTER; + case DOM_PK_LAUNCH_MAIL: + return SDL_SCANCODE_MAIL; + case DOM_PK_MEDIA_SELECT: + return SDL_SCANCODE_MEDIASELECT; + } + + return SDL_SCANCODE_UNKNOWN; +} + +static SDL_Keycode Emscripten_MapKeyCode(const EmscriptenKeyboardEvent *keyEvent) +{ + SDL_Keycode keycode = SDLK_UNKNOWN; + if (keyEvent->keyCode < SDL_arraysize(emscripten_keycode_table)) { + keycode = emscripten_keycode_table[keyEvent->keyCode]; + if (keycode != SDLK_UNKNOWN) { + if (keyEvent->location == DOM_KEY_LOCATION_RIGHT) { + switch (keycode) { + case SDLK_LSHIFT: + keycode = SDLK_RSHIFT; + break; + case SDLK_LCTRL: + keycode = SDLK_RCTRL; + break; + case SDLK_LALT: + keycode = SDLK_RALT; + break; + case SDLK_LGUI: + keycode = SDLK_RGUI; + break; + } + } else if (keyEvent->location == DOM_KEY_LOCATION_NUMPAD) { + switch (keycode) { + case SDLK_0: + case SDLK_INSERT: + keycode = SDLK_KP_0; + break; + case SDLK_1: + case SDLK_END: + keycode = SDLK_KP_1; + break; + case SDLK_2: + case SDLK_DOWN: + keycode = SDLK_KP_2; + break; + case SDLK_3: + case SDLK_PAGEDOWN: + keycode = SDLK_KP_3; + break; + case SDLK_4: + case SDLK_LEFT: + keycode = SDLK_KP_4; + break; + case SDLK_5: + keycode = SDLK_KP_5; + break; + case SDLK_6: + case SDLK_RIGHT: + keycode = SDLK_KP_6; + break; + case SDLK_7: + case SDLK_HOME: + keycode = SDLK_KP_7; + break; + case SDLK_8: + case SDLK_UP: + keycode = SDLK_KP_8; + break; + case SDLK_9: + case SDLK_PAGEUP: + keycode = SDLK_KP_9; + break; + case SDLK_RETURN: + keycode = SDLK_KP_ENTER; + break; + case SDLK_DELETE: + keycode = SDLK_KP_PERIOD; + break; + } + } + } + } + + return keycode; +} + +/* "borrowed" from SDL_windowsevents.c */ +static int Emscripten_ConvertUTF32toUTF8(Uint32 codepoint, char *text) +{ + if (codepoint <= 0x7F) { + text[0] = (char)codepoint; + text[1] = '\0'; + } else if (codepoint <= 0x7FF) { + text[0] = 0xC0 | (char)((codepoint >> 6) & 0x1F); + text[1] = 0x80 | (char)(codepoint & 0x3F); + text[2] = '\0'; + } else if (codepoint <= 0xFFFF) { + text[0] = 0xE0 | (char)((codepoint >> 12) & 0x0F); + text[1] = 0x80 | (char)((codepoint >> 6) & 0x3F); + text[2] = 0x80 | (char)(codepoint & 0x3F); + text[3] = '\0'; + } else if (codepoint <= 0x10FFFF) { + text[0] = 0xF0 | (char)((codepoint >> 18) & 0x0F); + text[1] = 0x80 | (char)((codepoint >> 12) & 0x3F); + text[2] = 0x80 | (char)((codepoint >> 6) & 0x3F); + text[3] = 0x80 | (char)(codepoint & 0x3F); + text[4] = '\0'; + } else { + return SDL_FALSE; + } + return SDL_TRUE; +} + +static EM_BOOL Emscripten_HandlePointerLockChange(int eventType, const EmscriptenPointerlockChangeEvent *changeEvent, void *userData) +{ + SDL_WindowData *window_data = (SDL_WindowData *)userData; + /* keep track of lock losses, so we can regrab if/when appropriate. */ + window_data->has_pointer_lock = changeEvent->isActive; + return 0; +} + +static EM_BOOL Emscripten_HandleMouseMove(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData) +{ + SDL_WindowData *window_data = userData; + const int isPointerLocked = window_data->has_pointer_lock; + int mx, my; + static double residualx = 0, residualy = 0; + + /* rescale (in case canvas is being scaled)*/ + double client_w, client_h, xscale, yscale; + emscripten_get_element_css_size(window_data->canvas_id, &client_w, &client_h); + xscale = window_data->window->w / client_w; + yscale = window_data->window->h / client_h; + + if (isPointerLocked) { + residualx += mouseEvent->movementX * xscale; + residualy += mouseEvent->movementY * yscale; + /* Let slow sub-pixel motion accumulate. Don't lose it. */ + mx = residualx; + residualx -= mx; + my = residualy; + residualy -= my; + } else { + mx = mouseEvent->targetX * xscale; + my = mouseEvent->targetY * yscale; + } + + SDL_SendMouseMotion(window_data->window, 0, isPointerLocked, mx, my); + return 0; +} + +static EM_BOOL Emscripten_HandleMouseButton(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData) +{ + SDL_WindowData *window_data = userData; + Uint8 sdl_button; + Uint8 sdl_button_state; + SDL_EventType sdl_event_type; + double css_w, css_h; + SDL_bool prevent_default = SDL_FALSE; /* needed for iframe implementation in Chrome-based browsers. */ + + switch (mouseEvent->button) { + case 0: + sdl_button = SDL_BUTTON_LEFT; + break; + case 1: + sdl_button = SDL_BUTTON_MIDDLE; + break; + case 2: + sdl_button = SDL_BUTTON_RIGHT; + break; + default: + return 0; + } + + if (eventType == EMSCRIPTEN_EVENT_MOUSEDOWN) { + if (SDL_GetMouse()->relative_mode && !window_data->has_pointer_lock) { + emscripten_request_pointerlock(window_data->canvas_id, 0); /* try to regrab lost pointer lock. */ + } + sdl_button_state = SDL_PRESSED; + sdl_event_type = SDL_MOUSEBUTTONDOWN; + } else { + sdl_button_state = SDL_RELEASED; + sdl_event_type = SDL_MOUSEBUTTONUP; + prevent_default = SDL_GetEventState(sdl_event_type) == SDL_ENABLE; + } + SDL_SendMouseButton(window_data->window, 0, sdl_button_state, sdl_button); + + /* Do not consume the event if the mouse is outside of the canvas. */ + emscripten_get_element_css_size(window_data->canvas_id, &css_w, &css_h); + if (mouseEvent->targetX < 0 || mouseEvent->targetX >= css_w || + mouseEvent->targetY < 0 || mouseEvent->targetY >= css_h) { + return 0; + } + + return prevent_default; +} + +static EM_BOOL Emscripten_HandleMouseFocus(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData) +{ + SDL_WindowData *window_data = userData; + + int mx = mouseEvent->targetX, my = mouseEvent->targetY; + const int isPointerLocked = window_data->has_pointer_lock; + + if (!isPointerLocked) { + /* rescale (in case canvas is being scaled)*/ + double client_w, client_h; + emscripten_get_element_css_size(window_data->canvas_id, &client_w, &client_h); + + mx = mx * (window_data->window->w / client_w); + my = my * (window_data->window->h / client_h); + SDL_SendMouseMotion(window_data->window, 0, isPointerLocked, mx, my); + } + + SDL_SetMouseFocus(eventType == EMSCRIPTEN_EVENT_MOUSEENTER ? window_data->window : NULL); + return SDL_GetEventState(SDL_WINDOWEVENT) == SDL_ENABLE; +} + +static EM_BOOL Emscripten_HandleWheel(int eventType, const EmscriptenWheelEvent *wheelEvent, void *userData) +{ + SDL_WindowData *window_data = userData; + + float deltaY = wheelEvent->deltaY; + + switch (wheelEvent->deltaMode) { + case DOM_DELTA_PIXEL: + deltaY /= 100; /* 100 pixels make up a step */ + break; + case DOM_DELTA_LINE: + deltaY /= 3; /* 3 lines make up a step */ + break; + case DOM_DELTA_PAGE: + deltaY *= 80; /* A page makes up 80 steps */ + break; + } + + SDL_SendMouseWheel(window_data->window, 0, (float)wheelEvent->deltaX, -deltaY, SDL_MOUSEWHEEL_NORMAL); + return SDL_GetEventState(SDL_MOUSEWHEEL) == SDL_ENABLE; +} + +static EM_BOOL Emscripten_HandleFocus(int eventType, const EmscriptenFocusEvent *wheelEvent, void *userData) +{ + SDL_WindowData *window_data = userData; + /* If the user switches away while keys are pressed (such as + * via Alt+Tab), key release events won't be received. */ + if (eventType == EMSCRIPTEN_EVENT_BLUR) { + SDL_ResetKeyboard(); + } + + SDL_SendWindowEvent(window_data->window, eventType == EMSCRIPTEN_EVENT_FOCUS ? SDL_WINDOWEVENT_FOCUS_GAINED : SDL_WINDOWEVENT_FOCUS_LOST, 0, 0); + return SDL_GetEventState(SDL_WINDOWEVENT) == SDL_ENABLE; +} + +static EM_BOOL Emscripten_HandleTouch(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData) +{ + SDL_WindowData *window_data = (SDL_WindowData *)userData; + int i; + double client_w, client_h; + int preventDefault = 0; + + SDL_TouchID deviceId = 1; + if (SDL_AddTouch(deviceId, SDL_TOUCH_DEVICE_DIRECT, "") < 0) { + return 0; + } + + emscripten_get_element_css_size(window_data->canvas_id, &client_w, &client_h); + + for (i = 0; i < touchEvent->numTouches; i++) { + SDL_FingerID id; + float x, y; + + if (!touchEvent->touches[i].isChanged) { + continue; + } + + id = touchEvent->touches[i].identifier; + x = touchEvent->touches[i].targetX / client_w; + y = touchEvent->touches[i].targetY / client_h; + + if (eventType == EMSCRIPTEN_EVENT_TOUCHSTART) { + SDL_SendTouch(deviceId, id, window_data->window, SDL_TRUE, x, y, 1.0f); + + /* disable browser scrolling/pinch-to-zoom if app handles touch events */ + if (!preventDefault && SDL_GetEventState(SDL_FINGERDOWN) == SDL_ENABLE) { + preventDefault = 1; + } + } else if (eventType == EMSCRIPTEN_EVENT_TOUCHMOVE) { + SDL_SendTouchMotion(deviceId, id, window_data->window, x, y, 1.0f); + } else { + SDL_SendTouch(deviceId, id, window_data->window, SDL_FALSE, x, y, 1.0f); + + /* block browser's simulated mousedown/mouseup on touchscreen devices */ + preventDefault = 1; + } + } + + return preventDefault; +} + +static EM_BOOL Emscripten_HandleKey(int eventType, const EmscriptenKeyboardEvent *keyEvent, void *userData) +{ + const SDL_Keycode keycode = Emscripten_MapKeyCode(keyEvent); + SDL_Scancode scancode = Emscripten_MapScanCode(keyEvent->code); + SDL_bool prevent_default = SDL_TRUE; + SDL_bool is_nav_key = SDL_FALSE; + + if (scancode == SDL_SCANCODE_UNKNOWN) { + /* KaiOS Left Soft Key and Right Soft Key, they act as OK/Next/Menu and Cancel/Back/Clear */ + if (SDL_strncmp(keyEvent->key, "SoftLeft", 9) == 0) { + scancode = SDL_SCANCODE_AC_FORWARD; + } else if (SDL_strncmp(keyEvent->key, "SoftRight", 10) == 0) { + scancode = SDL_SCANCODE_AC_BACK; + } + } + + if (scancode != SDL_SCANCODE_UNKNOWN) { + SDL_SendKeyboardKeyAndKeycode(eventType == EMSCRIPTEN_EVENT_KEYDOWN ? SDL_PRESSED : SDL_RELEASED, scancode, keycode); + } + + /* if TEXTINPUT events are enabled we can't prevent keydown or we won't get keypress + * we need to ALWAYS prevent backspace and tab otherwise chrome takes action and does bad navigation UX + */ + if ((scancode == SDL_SCANCODE_BACKSPACE) || + (scancode == SDL_SCANCODE_TAB) || + (scancode == SDL_SCANCODE_LEFT) || + (scancode == SDL_SCANCODE_UP) || + (scancode == SDL_SCANCODE_RIGHT) || + (scancode == SDL_SCANCODE_DOWN) || + ((scancode >= SDL_SCANCODE_F1) && (scancode <= SDL_SCANCODE_F15)) || + keyEvent->ctrlKey) { + is_nav_key = SDL_TRUE; + } + + if ((eventType == EMSCRIPTEN_EVENT_KEYDOWN) && (SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE) && !is_nav_key) { + prevent_default = SDL_FALSE; + } + + return prevent_default; +} + +static EM_BOOL Emscripten_HandleKeyPress(int eventType, const EmscriptenKeyboardEvent *keyEvent, void *userData) +{ + char text[5]; + if (Emscripten_ConvertUTF32toUTF8(keyEvent->charCode, text)) { + SDL_SendKeyboardText(text); + } + return SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE; +} + +static EM_BOOL Emscripten_HandleFullscreenChange(int eventType, const EmscriptenFullscreenChangeEvent *fullscreenChangeEvent, void *userData) +{ + SDL_WindowData *window_data = userData; + SDL_VideoDisplay *display; + + if (fullscreenChangeEvent->isFullscreen) { + window_data->window->flags |= window_data->requested_fullscreen_mode; + + window_data->requested_fullscreen_mode = 0; + } else { + window_data->window->flags &= ~FULLSCREEN_MASK; + + /* reset fullscreen window if the browser left fullscreen */ + display = SDL_GetDisplayForWindow(window_data->window); + + if (display->fullscreen_window == window_data->window) { + display->fullscreen_window = NULL; + } + } + + return 0; +} + +static EM_BOOL Emscripten_HandleResize(int eventType, const EmscriptenUiEvent *uiEvent, void *userData) +{ + SDL_WindowData *window_data = userData; + SDL_bool force = SDL_FALSE; + + /* update pixel ratio */ + if (window_data->window->flags & SDL_WINDOW_ALLOW_HIGHDPI) { + if (window_data->pixel_ratio != emscripten_get_device_pixel_ratio()) { + window_data->pixel_ratio = emscripten_get_device_pixel_ratio(); + force = SDL_TRUE; + } + } + + if (!(window_data->window->flags & FULLSCREEN_MASK)) { + /* this will only work if the canvas size is set through css */ + if (window_data->window->flags & SDL_WINDOW_RESIZABLE) { + double w = window_data->window->w; + double h = window_data->window->h; + + if (window_data->external_size) { + emscripten_get_element_css_size(window_data->canvas_id, &w, &h); + } + + emscripten_set_canvas_element_size(window_data->canvas_id, w * window_data->pixel_ratio, h * window_data->pixel_ratio); + + /* set_canvas_size unsets this */ + if (!window_data->external_size && window_data->pixel_ratio != 1.0f) { + emscripten_set_element_css_size(window_data->canvas_id, w, h); + } + + if (force) { + /* force the event to trigger, so pixel ratio changes can be handled */ + window_data->window->w = 0; + window_data->window->h = 0; + } + + SDL_SendWindowEvent(window_data->window, SDL_WINDOWEVENT_RESIZED, w, h); + } + } + + return 0; +} + +EM_BOOL +Emscripten_HandleCanvasResize(int eventType, const void *reserved, void *userData) +{ + /*this is used during fullscreen changes*/ + SDL_WindowData *window_data = userData; + + if (window_data->fullscreen_resize) { + double css_w, css_h; + emscripten_get_element_css_size(window_data->canvas_id, &css_w, &css_h); + SDL_SendWindowEvent(window_data->window, SDL_WINDOWEVENT_RESIZED, css_w, css_h); + } + + return 0; +} + +static EM_BOOL Emscripten_HandleVisibilityChange(int eventType, const EmscriptenVisibilityChangeEvent *visEvent, void *userData) +{ + SDL_WindowData *window_data = userData; + SDL_SendWindowEvent(window_data->window, visEvent->hidden ? SDL_WINDOWEVENT_HIDDEN : SDL_WINDOWEVENT_SHOWN, 0, 0); + return 0; +} + +static const char *Emscripten_HandleBeforeUnload(int eventType, const void *reserved, void *userData) +{ + /* This event will need to be handled synchronously, e.g. using + SDL_AddEventWatch, as the page is being closed *now*. */ + /* No need to send a SDL_QUIT, the app won't get control again. */ + SDL_SendAppEvent(SDL_APP_TERMINATING); + return ""; /* don't trigger confirmation dialog */ +} + +void Emscripten_RegisterEventHandlers(SDL_WindowData *data) +{ + const char *keyElement; + + /* There is only one window and that window is the canvas */ + emscripten_set_mousemove_callback(data->canvas_id, data, 0, Emscripten_HandleMouseMove); + + emscripten_set_mousedown_callback(data->canvas_id, data, 0, Emscripten_HandleMouseButton); + emscripten_set_mouseup_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, data, 0, Emscripten_HandleMouseButton); + + emscripten_set_mouseenter_callback(data->canvas_id, data, 0, Emscripten_HandleMouseFocus); + emscripten_set_mouseleave_callback(data->canvas_id, data, 0, Emscripten_HandleMouseFocus); + + emscripten_set_wheel_callback(data->canvas_id, data, 0, Emscripten_HandleWheel); + + emscripten_set_focus_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, data, 0, Emscripten_HandleFocus); + emscripten_set_blur_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, data, 0, Emscripten_HandleFocus); + + emscripten_set_touchstart_callback(data->canvas_id, data, 0, Emscripten_HandleTouch); + emscripten_set_touchend_callback(data->canvas_id, data, 0, Emscripten_HandleTouch); + emscripten_set_touchmove_callback(data->canvas_id, data, 0, Emscripten_HandleTouch); + emscripten_set_touchcancel_callback(data->canvas_id, data, 0, Emscripten_HandleTouch); + + emscripten_set_pointerlockchange_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, data, 0, Emscripten_HandlePointerLockChange); + + /* Keyboard events are awkward */ + keyElement = SDL_GetHint(SDL_HINT_EMSCRIPTEN_KEYBOARD_ELEMENT); + if (!keyElement) { + keyElement = EMSCRIPTEN_EVENT_TARGET_WINDOW; + } + + emscripten_set_keydown_callback(keyElement, data, 0, Emscripten_HandleKey); + emscripten_set_keyup_callback(keyElement, data, 0, Emscripten_HandleKey); + emscripten_set_keypress_callback(keyElement, data, 0, Emscripten_HandleKeyPress); + + emscripten_set_fullscreenchange_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, data, 0, Emscripten_HandleFullscreenChange); + + emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, data, 0, Emscripten_HandleResize); + + emscripten_set_visibilitychange_callback(data, 0, Emscripten_HandleVisibilityChange); + + emscripten_set_beforeunload_callback(data, Emscripten_HandleBeforeUnload); +} + +void Emscripten_UnregisterEventHandlers(SDL_WindowData *data) +{ + const char *target; + + /* only works due to having one window */ + emscripten_set_mousemove_callback(data->canvas_id, NULL, 0, NULL); + + emscripten_set_mousedown_callback(data->canvas_id, NULL, 0, NULL); + emscripten_set_mouseup_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, NULL, 0, NULL); + + emscripten_set_mouseenter_callback(data->canvas_id, NULL, 0, NULL); + emscripten_set_mouseleave_callback(data->canvas_id, NULL, 0, NULL); + + emscripten_set_wheel_callback(data->canvas_id, NULL, 0, NULL); + + emscripten_set_focus_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, 0, NULL); + emscripten_set_blur_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, 0, NULL); + + emscripten_set_touchstart_callback(data->canvas_id, NULL, 0, NULL); + emscripten_set_touchend_callback(data->canvas_id, NULL, 0, NULL); + emscripten_set_touchmove_callback(data->canvas_id, NULL, 0, NULL); + emscripten_set_touchcancel_callback(data->canvas_id, NULL, 0, NULL); + + emscripten_set_pointerlockchange_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, NULL, 0, NULL); + + target = SDL_GetHint(SDL_HINT_EMSCRIPTEN_KEYBOARD_ELEMENT); + if (!target) { + target = EMSCRIPTEN_EVENT_TARGET_WINDOW; + } + + emscripten_set_keydown_callback(target, NULL, 0, NULL); + emscripten_set_keyup_callback(target, NULL, 0, NULL); + emscripten_set_keypress_callback(target, NULL, 0, NULL); + + emscripten_set_fullscreenchange_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, NULL, 0, NULL); + + emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, 0, NULL); + + emscripten_set_visibilitychange_callback(NULL, 0, NULL); + + emscripten_set_beforeunload_callback(NULL, NULL); +} + +#endif /* SDL_VIDEO_DRIVER_EMSCRIPTEN */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/emscripten/SDL_emscriptenevents.h b/SDL2-2.30.5/src/video/emscripten/SDL_emscriptenevents.h similarity index 95% rename from SDL2-2.0.12/src/video/emscripten/SDL_emscriptenevents.h rename to SDL2-2.30.5/src/video/emscripten/SDL_emscriptenevents.h index 04f038e..502236a 100644 --- a/SDL2-2.0.12/src/video/emscripten/SDL_emscriptenevents.h +++ b/SDL2-2.30.5/src/video/emscripten/SDL_emscriptenevents.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -19,7 +19,6 @@ 3. This notice may not be removed or altered from any source distribution. */ - #ifndef SDL_emscriptenevents_h_ #define SDL_emscriptenevents_h_ @@ -37,4 +36,3 @@ Emscripten_HandleCanvasResize(int eventType, const void *reserved, void *userDat #endif /* SDL_emscriptenevents_h_ */ /* vi: set ts=4 sw=4 expandtab: */ - diff --git a/SDL2-2.0.12/src/video/emscripten/SDL_emscriptenframebuffer.c b/SDL2-2.30.5/src/video/emscripten/SDL_emscriptenframebuffer.c similarity index 83% rename from SDL2-2.0.12/src/video/emscripten/SDL_emscriptenframebuffer.c rename to SDL2-2.30.5/src/video/emscripten/SDL_emscriptenframebuffer.c index 3c07d31..6a0e78f 100644 --- a/SDL2-2.0.12/src/video/emscripten/SDL_emscriptenframebuffer.c +++ b/SDL2-2.30.5/src/video/emscripten/SDL_emscriptenframebuffer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,13 +20,15 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_EMSCRIPTEN +#ifdef SDL_VIDEO_DRIVER_EMSCRIPTEN #include "SDL_emscriptenvideo.h" #include "SDL_emscriptenframebuffer.h" +#include "SDL_hints.h" +#include -int Emscripten_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch) +int Emscripten_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format, void **pixels, int *pitch) { SDL_Surface *surface; const Uint32 surface_format = SDL_PIXELFORMAT_BGR888; @@ -35,13 +37,13 @@ int Emscripten_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * form Uint32 Rmask, Gmask, Bmask, Amask; /* Free the old framebuffer surface */ - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; surface = data->surface; SDL_FreeSurface(surface); /* Create a new one */ SDL_PixelFormatEnumToMasks(surface_format, &bpp, &Rmask, &Gmask, &Bmask, &Amask); - SDL_GetWindowSize(window, &w, &h); + SDL_GetWindowSizeInPixels(window, &w, &h); surface = SDL_CreateRGBSurface(0, w, h, bpp, Rmask, Gmask, Bmask, Amask); if (!surface) { @@ -56,11 +58,11 @@ int Emscripten_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * form return 0; } -int Emscripten_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects) +int Emscripten_UpdateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_Rect *rects, int numrects) { SDL_Surface *surface; - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; surface = data->surface; if (!surface) { return SDL_SetError("Couldn't find framebuffer surface for window"); @@ -68,7 +70,8 @@ int Emscripten_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rec /* Send the data to the display */ - EM_ASM_INT({ + /* *INDENT-OFF* */ /* clang-format off */ + MAIN_THREAD_EM_ASM({ var w = $0; var h = $1; var pixels = $2; @@ -108,6 +111,7 @@ int Emscripten_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rec if (SDL2.data32Data !== data) { SDL2.data32 = new Int32Array(data.buffer); SDL2.data8 = new Uint8Array(data.buffer); + SDL2.data32Data = data; } var data32 = SDL2.data32; num = data32.length; @@ -117,7 +121,7 @@ int Emscripten_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rec // } // the following code is faster though, because // .set() is almost free - easily 10x faster due to - // native memcpy efficiencies, and the remaining loop + // native SDL_memcpy efficiencies, and the remaining loop // just stores, not load + store, so it is faster data32.set(HEAP32.subarray(src, src + num)); var data8 = SDL2.data8; @@ -152,22 +156,19 @@ int Emscripten_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rec } SDL2.ctx.putImageData(SDL2.image, 0, 0); - return 0; }, surface->w, surface->h, surface->pixels); - /*if (SDL_getenv("SDL_VIDEO_Emscripten_SAVE_FRAMES")) { - static int frame_number = 0; - char file[128]; - SDL_snprintf(file, sizeof(file), "SDL_window%d-%8.8d.bmp", - SDL_GetWindowID(window), ++frame_number); - SDL_SaveBMP(surface, file); - }*/ + if (emscripten_has_asyncify() && SDL_GetHintBoolean(SDL_HINT_EMSCRIPTEN_ASYNCIFY, SDL_TRUE)) { + /* give back control to browser for screen refresh */ + emscripten_sleep(0); + } + return 0; } -void Emscripten_DestroyWindowFramebuffer(_THIS, SDL_Window * window) +void Emscripten_DestroyWindowFramebuffer(_THIS, SDL_Window *window) { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; SDL_FreeSurface(data->surface); data->surface = NULL; diff --git a/SDL2-2.0.12/src/video/emscripten/SDL_emscriptenframebuffer.h b/SDL2-2.30.5/src/video/emscripten/SDL_emscriptenframebuffer.h similarity index 87% rename from SDL2-2.0.12/src/video/emscripten/SDL_emscriptenframebuffer.h rename to SDL2-2.30.5/src/video/emscripten/SDL_emscriptenframebuffer.h index 6d413dd..fdf1c35 100644 --- a/SDL2-2.0.12/src/video/emscripten/SDL_emscriptenframebuffer.h +++ b/SDL2-2.30.5/src/video/emscripten/SDL_emscriptenframebuffer.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,9 +23,9 @@ #ifndef SDL_emscriptenframebuffer_h_ #define SDL_emscriptenframebuffer_h_ -extern int Emscripten_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch); -extern int Emscripten_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects); -extern void Emscripten_DestroyWindowFramebuffer(_THIS, SDL_Window * window); +extern int Emscripten_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format, void **pixels, int *pitch); +extern int Emscripten_UpdateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_Rect *rects, int numrects); +extern void Emscripten_DestroyWindowFramebuffer(_THIS, SDL_Window *window); #endif /* SDL_emscriptenframebuffer_h_ */ diff --git a/SDL2-2.0.12/src/video/emscripten/SDL_emscriptenmouse.c b/SDL2-2.30.5/src/video/emscripten/SDL_emscriptenmouse.c similarity index 61% rename from SDL2-2.0.12/src/video/emscripten/SDL_emscriptenmouse.c rename to SDL2-2.30.5/src/video/emscripten/SDL_emscriptenmouse.c index ac118e2..d189e53 100644 --- a/SDL2-2.0.12/src/video/emscripten/SDL_emscriptenmouse.c +++ b/SDL2-2.30.5/src/video/emscripten/SDL_emscriptenmouse.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -18,29 +18,36 @@ misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ - - #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_EMSCRIPTEN +#ifdef SDL_VIDEO_DRIVER_EMSCRIPTEN #include #include +#include #include "SDL_emscriptenmouse.h" +#include "SDL_emscriptenvideo.h" #include "../../events/SDL_mouse_c.h" -#include "SDL_assert.h" -static SDL_Cursor* -Emscripten_CreateCursorFromString(const char* cursor_str, SDL_bool is_custom) +/* older Emscriptens don't have this, but we need to for wasm64 compatibility. */ +#ifndef MAIN_THREAD_EM_ASM_PTR + #ifdef __wasm64__ + #error You need to upgrade your Emscripten compiler to support wasm64 + #else + #define MAIN_THREAD_EM_ASM_PTR MAIN_THREAD_EM_ASM_INT + #endif +#endif + +static SDL_Cursor *Emscripten_CreateCursorFromString(const char *cursor_str, SDL_bool is_custom) { - SDL_Cursor* cursor; + SDL_Cursor *cursor; Emscripten_CursorData *curdata; cursor = SDL_calloc(1, sizeof(SDL_Cursor)); if (cursor) { - curdata = (Emscripten_CursorData *) SDL_calloc(1, sizeof(*curdata)); + curdata = (Emscripten_CursorData *)SDL_calloc(1, sizeof(*curdata)); if (!curdata) { SDL_OutOfMemory(); SDL_free(cursor); @@ -50,22 +57,21 @@ Emscripten_CreateCursorFromString(const char* cursor_str, SDL_bool is_custom) curdata->system_cursor = cursor_str; curdata->is_custom = is_custom; cursor->driverdata = curdata; - } - else { + } else { SDL_OutOfMemory(); } return cursor; } -static SDL_Cursor* -Emscripten_CreateDefaultCursor() +static SDL_Cursor *Emscripten_CreateDefaultCursor() { return Emscripten_CreateCursorFromString("default", SDL_FALSE); } -static SDL_Cursor* -Emscripten_CreateCursor(SDL_Surface* surface, int hot_x, int hot_y) +EM_JS_DEPS(sdlmouse, "$stringToUTF8,$UTF8ToString"); + +static SDL_Cursor *Emscripten_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y) { const char *cursor_url = NULL; SDL_Surface *conv_surf; @@ -76,7 +82,8 @@ Emscripten_CreateCursor(SDL_Surface* surface, int hot_x, int hot_y) return NULL; } - cursor_url = (const char *)EM_ASM_INT({ + /* *INDENT-OFF* */ /* clang-format off */ + cursor_url = (const char *)MAIN_THREAD_EM_ASM_PTR({ var w = $0; var h = $1; var hot_x = $2; @@ -125,70 +132,27 @@ Emscripten_CreateCursor(SDL_Surface* surface, int hot_x, int hot_y) return urlBuf; }, surface->w, surface->h, hot_x, hot_y, conv_surf->pixels); + /* *INDENT-ON* */ /* clang-format on */ SDL_FreeSurface(conv_surf); return Emscripten_CreateCursorFromString(cursor_url, SDL_TRUE); } -static SDL_Cursor* -Emscripten_CreateSystemCursor(SDL_SystemCursor id) +static SDL_Cursor *Emscripten_CreateSystemCursor(SDL_SystemCursor id) { - const char *cursor_name = NULL; - - switch(id) { - case SDL_SYSTEM_CURSOR_ARROW: - cursor_name = "default"; - break; - case SDL_SYSTEM_CURSOR_IBEAM: - cursor_name = "text"; - break; - case SDL_SYSTEM_CURSOR_WAIT: - cursor_name = "wait"; - break; - case SDL_SYSTEM_CURSOR_CROSSHAIR: - cursor_name = "crosshair"; - break; - case SDL_SYSTEM_CURSOR_WAITARROW: - cursor_name = "progress"; - break; - case SDL_SYSTEM_CURSOR_SIZENWSE: - cursor_name = "nwse-resize"; - break; - case SDL_SYSTEM_CURSOR_SIZENESW: - cursor_name = "nesw-resize"; - break; - case SDL_SYSTEM_CURSOR_SIZEWE: - cursor_name = "ew-resize"; - break; - case SDL_SYSTEM_CURSOR_SIZENS: - cursor_name = "ns-resize"; - break; - case SDL_SYSTEM_CURSOR_SIZEALL: - cursor_name = "move"; - break; - case SDL_SYSTEM_CURSOR_NO: - cursor_name = "not-allowed"; - break; - case SDL_SYSTEM_CURSOR_HAND: - cursor_name = "pointer"; - break; - default: - SDL_assert(0); - return NULL; - } + const char *cursor_name = SDL_GetCSSCursorName(id, NULL); return Emscripten_CreateCursorFromString(cursor_name, SDL_FALSE); } -static void -Emscripten_FreeCursor(SDL_Cursor* cursor) +static void Emscripten_FreeCursor(SDL_Cursor *cursor) { Emscripten_CursorData *curdata; if (cursor) { - curdata = (Emscripten_CursorData *) cursor->driverdata; + curdata = (Emscripten_CursorData *)cursor->driverdata; - if (curdata != NULL) { + if (curdata) { if (curdata->is_custom) { SDL_free((char *)curdata->system_cursor); } @@ -199,77 +163,83 @@ Emscripten_FreeCursor(SDL_Cursor* cursor) } } -static int -Emscripten_ShowCursor(SDL_Cursor* cursor) +static int Emscripten_ShowCursor(SDL_Cursor *cursor) { Emscripten_CursorData *curdata; if (SDL_GetMouseFocus() != NULL) { - if(cursor && cursor->driverdata) { - curdata = (Emscripten_CursorData *) cursor->driverdata; + if (cursor && cursor->driverdata) { + curdata = (Emscripten_CursorData *)cursor->driverdata; - if(curdata->system_cursor) { - EM_ASM_INT({ + if (curdata->system_cursor) { + /* *INDENT-OFF* */ /* clang-format off */ + MAIN_THREAD_EM_ASM({ if (Module['canvas']) { Module['canvas'].style['cursor'] = UTF8ToString($0); } - return 0; }, curdata->system_cursor); + /* *INDENT-ON* */ /* clang-format on */ } - } - else { - EM_ASM( + } else { + /* *INDENT-OFF* */ /* clang-format off */ + MAIN_THREAD_EM_ASM( if (Module['canvas']) { Module['canvas'].style['cursor'] = 'none'; } ); + /* *INDENT-ON* */ /* clang-format on */ } } return 0; } -static void -Emscripten_WarpMouse(SDL_Window* window, int x, int y) +static void Emscripten_WarpMouse(SDL_Window *window, int x, int y) { SDL_Unsupported(); } -static int -Emscripten_SetRelativeMouseMode(SDL_bool enabled) +static int Emscripten_SetRelativeMouseMode(SDL_bool enabled) { + SDL_Window *window; + SDL_WindowData *window_data; + /* TODO: pointer lock isn't actually enabled yet */ - if(enabled) { - if(emscripten_request_pointerlock(NULL, 1) >= EMSCRIPTEN_RESULT_SUCCESS) { + if (enabled) { + window = SDL_GetMouseFocus(); + if (!window) { + return -1; + } + + window_data = (SDL_WindowData *)window->driverdata; + + if (emscripten_request_pointerlock(window_data->canvas_id, 1) >= EMSCRIPTEN_RESULT_SUCCESS) { return 0; } } else { - if(emscripten_exit_pointerlock() >= EMSCRIPTEN_RESULT_SUCCESS) { + if (emscripten_exit_pointerlock() >= EMSCRIPTEN_RESULT_SUCCESS) { return 0; } } return -1; } -void -Emscripten_InitMouse() +void Emscripten_InitMouse() { - SDL_Mouse* mouse = SDL_GetMouse(); + SDL_Mouse *mouse = SDL_GetMouse(); - mouse->CreateCursor = Emscripten_CreateCursor; - mouse->ShowCursor = Emscripten_ShowCursor; - mouse->FreeCursor = Emscripten_FreeCursor; - mouse->WarpMouse = Emscripten_WarpMouse; - mouse->CreateSystemCursor = Emscripten_CreateSystemCursor; + mouse->CreateCursor = Emscripten_CreateCursor; + mouse->ShowCursor = Emscripten_ShowCursor; + mouse->FreeCursor = Emscripten_FreeCursor; + mouse->WarpMouse = Emscripten_WarpMouse; + mouse->CreateSystemCursor = Emscripten_CreateSystemCursor; mouse->SetRelativeMouseMode = Emscripten_SetRelativeMouseMode; SDL_SetDefaultCursor(Emscripten_CreateDefaultCursor()); } -void -Emscripten_FiniMouse() +void Emscripten_FiniMouse() { } #endif /* SDL_VIDEO_DRIVER_EMSCRIPTEN */ /* vi: set ts=4 sw=4 expandtab: */ - diff --git a/SDL2-2.0.12/src/video/emscripten/SDL_emscriptenmouse.h b/SDL2-2.30.5/src/video/emscripten/SDL_emscriptenmouse.h similarity index 95% rename from SDL2-2.0.12/src/video/emscripten/SDL_emscriptenmouse.h rename to SDL2-2.30.5/src/video/emscripten/SDL_emscriptenmouse.h index 0a9c0d8..10cd24e 100644 --- a/SDL2-2.0.12/src/video/emscripten/SDL_emscriptenmouse.h +++ b/SDL2-2.30.5/src/video/emscripten/SDL_emscriptenmouse.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -19,7 +19,6 @@ 3. This notice may not be removed or altered from any source distribution. */ - #ifndef SDL_emscriptenmouse_h_ #define SDL_emscriptenmouse_h_ diff --git a/SDL2-2.0.12/src/video/emscripten/SDL_emscriptenopengles.c b/SDL2-2.30.5/src/video/emscripten/SDL_emscriptenopengles.c similarity index 83% rename from SDL2-2.0.12/src/video/emscripten/SDL_emscriptenopengles.c rename to SDL2-2.30.5/src/video/emscripten/SDL_emscriptenopengles.c index f806bbe..baf9eb7 100644 --- a/SDL2-2.0.12/src/video/emscripten/SDL_emscriptenopengles.c +++ b/SDL2-2.30.5/src/video/emscripten/SDL_emscriptenopengles.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,20 +20,21 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_EMSCRIPTEN && SDL_VIDEO_OPENGL_EGL +#if defined(SDL_VIDEO_DRIVER_EMSCRIPTEN) && defined(SDL_VIDEO_OPENGL_EGL) #include #include #include "SDL_emscriptenvideo.h" #include "SDL_emscriptenopengles.h" +#include "SDL_hints.h" #define LOAD_FUNC(NAME) _this->egl_data->NAME = NAME; /* EGL implementation of SDL OpenGL support */ -int -Emscripten_GLES_LoadLibrary(_THIS, const char *path) { +int Emscripten_GLES_LoadLibrary(_THIS, const char *path) +{ /*we can't load EGL dynamically*/ _this->egl_data = (struct SDL_EGL_VideoData *) SDL_calloc(1, sizeof(SDL_EGL_VideoData)); if (!_this->egl_data) { @@ -67,7 +68,7 @@ Emscripten_GLES_LoadLibrary(_THIS, const char *path) { if (!_this->egl_data->egl_display) { return SDL_SetError("Could not get EGL display"); } - + if (_this->egl_data->eglInitialize(_this->egl_data->egl_display, NULL, NULL) != EGL_TRUE) { return SDL_SetError("Could not initialize EGL"); } @@ -77,32 +78,23 @@ Emscripten_GLES_LoadLibrary(_THIS, const char *path) { } else { *_this->gl_config.driver_path = '\0'; } - + return 0; } SDL_EGL_CreateContext_impl(Emscripten) -SDL_EGL_SwapWindow_impl(Emscripten) SDL_EGL_MakeCurrent_impl(Emscripten) -void -Emscripten_GLES_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h) +int Emscripten_GLES_SwapWindow(_THIS, SDL_Window *window) { - SDL_WindowData *data; - if (window->driverdata) { - data = (SDL_WindowData *) window->driverdata; - - if (w) { - *w = window->w * data->pixel_ratio; - } - - if (h) { - *h = window->h * data->pixel_ratio; - } + EGLBoolean ret = SDL_EGL_SwapBuffers(_this, ((SDL_WindowData *) window->driverdata)->egl_surface); + if (emscripten_has_asyncify() && SDL_GetHintBoolean(SDL_HINT_EMSCRIPTEN_ASYNCIFY, SDL_TRUE)) { + /* give back control to browser for screen refresh */ + emscripten_sleep(0); } + return ret; } #endif /* SDL_VIDEO_DRIVER_EMSCRIPTEN && SDL_VIDEO_OPENGL_EGL */ /* vi: set ts=4 sw=4 expandtab: */ - diff --git a/SDL2-2.0.12/src/video/emscripten/SDL_emscriptenopengles.h b/SDL2-2.30.5/src/video/emscripten/SDL_emscriptenopengles.h similarity index 90% rename from SDL2-2.0.12/src/video/emscripten/SDL_emscriptenopengles.h rename to SDL2-2.30.5/src/video/emscripten/SDL_emscriptenopengles.h index 8a8c5f8..184d0f2 100644 --- a/SDL2-2.0.12/src/video/emscripten/SDL_emscriptenopengles.h +++ b/SDL2-2.30.5/src/video/emscripten/SDL_emscriptenopengles.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,7 +23,7 @@ #ifndef SDL_emscriptenopengles_h_ #define SDL_emscriptenopengles_h_ -#if SDL_VIDEO_DRIVER_EMSCRIPTEN && SDL_VIDEO_OPENGL_EGL +#if defined(SDL_VIDEO_DRIVER_EMSCRIPTEN) && defined(SDL_VIDEO_OPENGL_EGL) #include "../SDL_sysvideo.h" #include "../SDL_egl_c.h" @@ -40,7 +40,6 @@ extern int Emscripten_GLES_LoadLibrary(_THIS, const char *path); extern SDL_GLContext Emscripten_GLES_CreateContext(_THIS, SDL_Window * window); extern int Emscripten_GLES_SwapWindow(_THIS, SDL_Window * window); extern int Emscripten_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context); -extern void Emscripten_GLES_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h); #endif /* SDL_VIDEO_DRIVER_EMSCRIPTEN && SDL_VIDEO_OPENGL_EGL */ diff --git a/SDL2-2.0.12/src/video/emscripten/SDL_emscriptenvideo.c b/SDL2-2.30.5/src/video/emscripten/SDL_emscriptenvideo.c similarity index 70% rename from SDL2-2.0.12/src/video/emscripten/SDL_emscriptenvideo.c rename to SDL2-2.30.5/src/video/emscripten/SDL_emscriptenvideo.c index 7535390..6319f92 100644 --- a/SDL2-2.0.12/src/video/emscripten/SDL_emscriptenvideo.c +++ b/SDL2-2.30.5/src/video/emscripten/SDL_emscriptenvideo.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_EMSCRIPTEN +#ifdef SDL_VIDEO_DRIVER_EMSCRIPTEN #include "SDL_video.h" #include "SDL_mouse.h" @@ -40,55 +40,50 @@ /* Initialization/Query functions */ static int Emscripten_VideoInit(_THIS); -static int Emscripten_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode); +static int Emscripten_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode); static void Emscripten_VideoQuit(_THIS); +static int Emscripten_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay *display, SDL_Rect *rect); +static int Emscripten_GetDisplayDPI(_THIS, SDL_VideoDisplay *display, float *ddpi, float *hdpi, float *vdpi); -static int Emscripten_CreateWindow(_THIS, SDL_Window * window); -static void Emscripten_SetWindowSize(_THIS, SDL_Window * window); -static void Emscripten_DestroyWindow(_THIS, SDL_Window * window); -static void Emscripten_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen); +static int Emscripten_CreateWindow(_THIS, SDL_Window *window); +static void Emscripten_SetWindowSize(_THIS, SDL_Window *window); +static void Emscripten_GetWindowSizeInPixels(_THIS, SDL_Window *window, int *w, int *h); +static void Emscripten_DestroyWindow(_THIS, SDL_Window *window); +static void Emscripten_SetWindowFullscreen(_THIS, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen); static void Emscripten_PumpEvents(_THIS); -static void Emscripten_SetWindowTitle(_THIS, SDL_Window * window); - +static void Emscripten_SetWindowTitle(_THIS, SDL_Window *window); /* Emscripten driver bootstrap functions */ -static int -Emscripten_Available(void) -{ - return (1); -} - -static void -Emscripten_DeleteDevice(SDL_VideoDevice * device) +static void Emscripten_DeleteDevice(SDL_VideoDevice *device) { SDL_free(device); } -static SDL_VideoDevice * -Emscripten_CreateDevice(int devindex) +static SDL_VideoDevice *Emscripten_CreateDevice(void) { SDL_VideoDevice *device; /* Initialize all variables that we clean on shutdown */ - device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice)); + device = (SDL_VideoDevice *)SDL_calloc(1, sizeof(SDL_VideoDevice)); if (!device) { SDL_OutOfMemory(); - return (0); + return 0; } /* Firefox sends blur event which would otherwise prevent full screen * when the user clicks to allow full screen. * See https://bugzilla.mozilla.org/show_bug.cgi?id=1144964 - */ + */ SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0"); /* Set the function pointers */ device->VideoInit = Emscripten_VideoInit; device->VideoQuit = Emscripten_VideoQuit; + device->GetDisplayUsableBounds = Emscripten_GetDisplayUsableBounds; + device->GetDisplayDPI = Emscripten_GetDisplayDPI; device->SetDisplayMode = Emscripten_SetDisplayMode; - device->PumpEvents = Emscripten_PumpEvents; device->CreateSDLWindow = Emscripten_CreateWindow; @@ -102,7 +97,8 @@ Emscripten_CreateDevice(int devindex) device->MaximizeWindow = Emscripten_MaximizeWindow; device->MinimizeWindow = Emscripten_MinimizeWindow; device->RestoreWindow = Emscripten_RestoreWindow; - device->SetWindowGrab = Emscripten_SetWindowGrab;*/ + device->SetWindowMouseGrab = Emscripten_SetWindowMouseGrab;*/ + device->GetWindowSizeInPixels = Emscripten_GetWindowSizeInPixels; device->DestroyWindow = Emscripten_DestroyWindow; device->SetWindowFullscreen = Emscripten_SetWindowFullscreen; @@ -110,7 +106,7 @@ Emscripten_CreateDevice(int devindex) device->UpdateWindowFramebuffer = Emscripten_UpdateWindowFramebuffer; device->DestroyWindowFramebuffer = Emscripten_DestroyWindowFramebuffer; -#if SDL_VIDEO_OPENGL_EGL +#ifdef SDL_VIDEO_OPENGL_EGL device->GL_LoadLibrary = Emscripten_GLES_LoadLibrary; device->GL_GetProcAddress = Emscripten_GLES_GetProcAddress; device->GL_UnloadLibrary = Emscripten_GLES_UnloadLibrary; @@ -120,7 +116,6 @@ Emscripten_CreateDevice(int devindex) device->GL_GetSwapInterval = Emscripten_GLES_GetSwapInterval; device->GL_SwapWindow = Emscripten_GLES_SwapWindow; device->GL_DeleteContext = Emscripten_GLES_DeleteContext; - device->GL_GetDrawableSize = Emscripten_GLES_GetDrawableSize; #endif device->free = Emscripten_DeleteDevice; @@ -130,25 +125,17 @@ Emscripten_CreateDevice(int devindex) VideoBootStrap Emscripten_bootstrap = { EMSCRIPTENVID_DRIVER_NAME, "SDL emscripten video driver", - Emscripten_Available, Emscripten_CreateDevice + Emscripten_CreateDevice, + NULL /* no ShowMessageBox implementation */ }; - -int -Emscripten_VideoInit(_THIS) +int Emscripten_VideoInit(_THIS) { SDL_DisplayMode mode; /* Use a fake 32-bpp desktop mode */ mode.format = SDL_PIXELFORMAT_RGB888; - - mode.w = EM_ASM_INT_V({ - return screen.width; - }); - - mode.h = EM_ASM_INT_V({ - return screen.height; - }); + emscripten_get_screen_size(&mode.w, &mode.h); mode.refresh_rate = 0; mode.driverdata = NULL; @@ -164,35 +151,66 @@ Emscripten_VideoInit(_THIS) return 0; } -static int -Emscripten_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) +static int Emscripten_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode) { /* can't do this */ return 0; } -static void -Emscripten_VideoQuit(_THIS) +static void Emscripten_VideoQuit(_THIS) { Emscripten_FiniMouse(); } -static void -Emscripten_PumpEvents(_THIS) +static int Emscripten_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay *display, SDL_Rect *rect) +{ + if (rect) { + rect->x = 0; + rect->y = 0; + rect->w = MAIN_THREAD_EM_ASM_INT({ + return window.innerWidth; + }); + rect->h = MAIN_THREAD_EM_ASM_INT({ + return window.innerHeight; + }); + } + return 0; +} + +static int Emscripten_GetDisplayDPI(_THIS, SDL_VideoDisplay *display, float *ddpi_out, float *hdpi_out, float *vdpi_out) +{ + const float dpi_reference = 96.0f; + float dpi; + + dpi = (float)emscripten_get_device_pixel_ratio() * dpi_reference; + + if (ddpi_out) { + *ddpi_out = dpi; + } + if (hdpi_out) { + *hdpi_out = dpi; + } + if (vdpi_out) { + *vdpi_out = dpi; + } + + return 0; +} + +static void Emscripten_PumpEvents(_THIS) { /* do nothing. */ } -static int -Emscripten_CreateWindow(_THIS, SDL_Window * window) +static int Emscripten_CreateWindow(_THIS, SDL_Window *window) { SDL_WindowData *wdata; double scaled_w, scaled_h; double css_w, css_h; /* Allocate window internal data */ - wdata = (SDL_WindowData *) SDL_calloc(1, sizeof(SDL_WindowData)); - if (wdata == NULL) { + wdata = (SDL_WindowData *)SDL_calloc(1, sizeof(SDL_WindowData)); + if (!wdata) { return SDL_OutOfMemory(); } @@ -230,7 +248,7 @@ Emscripten_CreateWindow(_THIS, SDL_Window * window) } } -#if SDL_VIDEO_OPENGL_EGL +#ifdef SDL_VIDEO_OPENGL_EGL if (window->flags & SDL_WINDOW_OPENGL) { if (!_this->egl_data) { if (SDL_GL_LoadLibrary(NULL) < 0) { @@ -260,12 +278,12 @@ Emscripten_CreateWindow(_THIS, SDL_Window * window) return 0; } -static void Emscripten_SetWindowSize(_THIS, SDL_Window * window) +static void Emscripten_SetWindowSize(_THIS, SDL_Window *window) { SDL_WindowData *data; if (window->driverdata) { - data = (SDL_WindowData *) window->driverdata; + data = (SDL_WindowData *)window->driverdata; /* update pixel ratio */ if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) { data->pixel_ratio = emscripten_get_device_pixel_ratio(); @@ -279,16 +297,25 @@ static void Emscripten_SetWindowSize(_THIS, SDL_Window * window) } } -static void -Emscripten_DestroyWindow(_THIS, SDL_Window * window) +static void Emscripten_GetWindowSizeInPixels(_THIS, SDL_Window *window, int *w, int *h) +{ + SDL_WindowData *data; + if (window->driverdata) { + data = (SDL_WindowData *)window->driverdata; + *w = window->w * data->pixel_ratio; + *h = window->h * data->pixel_ratio; + } +} + +static void Emscripten_DestroyWindow(_THIS, SDL_Window *window) { SDL_WindowData *data; - if(window->driverdata) { - data = (SDL_WindowData *) window->driverdata; + if (window->driverdata) { + data = (SDL_WindowData *)window->driverdata; Emscripten_UnregisterEventHandlers(data); -#if SDL_VIDEO_OPENGL_EGL +#ifdef SDL_VIDEO_OPENGL_EGL if (data->egl_surface != EGL_NO_SURFACE) { SDL_EGL_DestroySurface(_this, data->egl_surface); data->egl_surface = EGL_NO_SURFACE; @@ -304,23 +331,23 @@ Emscripten_DestroyWindow(_THIS, SDL_Window * window) } } -static void -Emscripten_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen) +static void Emscripten_SetWindowFullscreen(_THIS, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen) { SDL_WindowData *data; - if(window->driverdata) { - data = (SDL_WindowData *) window->driverdata; + if (window->driverdata) { + data = (SDL_WindowData *)window->driverdata; - if(fullscreen) { + if (fullscreen) { EmscriptenFullscreenStrategy strategy; SDL_bool is_desktop_fullscreen = (window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP; int res; + SDL_zero(strategy); strategy.scaleMode = is_desktop_fullscreen ? EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH : EMSCRIPTEN_FULLSCREEN_SCALE_ASPECT; - if(!is_desktop_fullscreen) { + if (!is_desktop_fullscreen) { strategy.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_NONE; - } else if(window->flags & SDL_WINDOW_ALLOW_HIGHDPI) { + } else if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) { strategy.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_HIDEF; } else { strategy.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF; @@ -335,24 +362,18 @@ Emscripten_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * di data->fullscreen_resize = is_desktop_fullscreen; res = emscripten_request_fullscreen_strategy(data->canvas_id, 1, &strategy); - if(res != EMSCRIPTEN_RESULT_SUCCESS && res != EMSCRIPTEN_RESULT_DEFERRED) { + if (res != EMSCRIPTEN_RESULT_SUCCESS && res != EMSCRIPTEN_RESULT_DEFERRED) { /* unset flags, fullscreen failed */ window->flags &= ~(SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_FULLSCREEN); } - } - else + } else emscripten_exit_fullscreen(); } } -static void -Emscripten_SetWindowTitle(_THIS, SDL_Window * window) { - EM_ASM_INT({ - if (typeof Module['setWindowTitle'] !== 'undefined') { - Module['setWindowTitle'](UTF8ToString($0)); - } - return 0; - }, window->title); +static void Emscripten_SetWindowTitle(_THIS, SDL_Window *window) +{ + emscripten_set_window_title(window->title); } #endif /* SDL_VIDEO_DRIVER_EMSCRIPTEN */ diff --git a/SDL2-2.0.12/src/video/emscripten/SDL_emscriptenvideo.h b/SDL2-2.30.5/src/video/emscripten/SDL_emscriptenvideo.h similarity index 92% rename from SDL2-2.0.12/src/video/emscripten/SDL_emscriptenvideo.h rename to SDL2-2.30.5/src/video/emscripten/SDL_emscriptenvideo.h index d15800f..2cbb671 100644 --- a/SDL2-2.0.12/src/video/emscripten/SDL_emscriptenvideo.h +++ b/SDL2-2.30.5/src/video/emscripten/SDL_emscriptenvideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -28,13 +28,13 @@ #include #include -#if SDL_VIDEO_OPENGL_EGL +#ifdef SDL_VIDEO_OPENGL_EGL #include #endif typedef struct SDL_WindowData { -#if SDL_VIDEO_OPENGL_EGL +#ifdef SDL_VIDEO_OPENGL_EGL EGLSurface egl_surface; #endif SDL_Window *window; diff --git a/SDL2-2.30.5/src/video/haiku/SDL_BApp.h b/SDL2-2.30.5/src/video/haiku/SDL_BApp.h new file mode 100644 index 0000000..284445d --- /dev/null +++ b/SDL2-2.30.5/src/video/haiku/SDL_BApp.h @@ -0,0 +1,427 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ +#ifndef SDL_BAPP_H +#define SDL_BAPP_H + +#include +#include +#include +#ifdef SDL_VIDEO_OPENGL +#include +#endif + +#include "../../video/haiku/SDL_bkeyboard.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#include "../../SDL_internal.h" + +#include "SDL_video.h" + +/* Local includes */ +#include "../../events/SDL_events_c.h" +#include "../../video/haiku/SDL_bframebuffer.h" + +#ifdef __cplusplus +} +#endif + +#include + +/* Forward declarations */ +class SDL_BLooper; +class SDL_BWin; + +/* Message constants */ +enum ToSDL +{ + /* Intercepted by BWindow on its way to BView */ + BAPP_MOUSE_MOVED, + BAPP_MOUSE_BUTTON, + BAPP_MOUSE_WHEEL, + BAPP_KEY, + BAPP_REPAINT, /* from _UPDATE_ */ + /* From BWindow */ + BAPP_MAXIMIZE, /* from B_ZOOM */ + BAPP_MINIMIZE, + BAPP_RESTORE, /* TODO: IMPLEMENT! */ + BAPP_SHOW, + BAPP_HIDE, + BAPP_MOUSE_FOCUS, /* caused by MOUSE_MOVE */ + BAPP_KEYBOARD_FOCUS, /* from WINDOW_ACTIVATED */ + BAPP_WINDOW_CLOSE_REQUESTED, + BAPP_WINDOW_MOVED, + BAPP_WINDOW_RESIZED, + BAPP_SCREEN_CHANGED +}; + + +extern "C" SDL_BLooper *SDL_Looper; + + +/* Create a descendant of BLooper */ +class SDL_BLooper : public BLooper +{ + public: + SDL_BLooper(const char* name) : BLooper(name) + { +#ifdef SDL_VIDEO_OPENGL + _current_context = NULL; +#endif + } + + virtual ~SDL_BLooper() + { + } + + /* Event-handling functions */ + virtual void MessageReceived(BMessage *message) + { + /* Sort out SDL-related messages */ + switch (message->what) { + case BAPP_MOUSE_MOVED: + _HandleMouseMove(message); + break; + + case BAPP_MOUSE_BUTTON: + _HandleMouseButton(message); + break; + + case BAPP_MOUSE_WHEEL: + _HandleMouseWheel(message); + break; + + case BAPP_KEY: + _HandleKey(message); + break; + + case BAPP_REPAINT: + _HandleBasicWindowEvent(message, SDL_WINDOWEVENT_EXPOSED); + break; + + case BAPP_MAXIMIZE: + _HandleBasicWindowEvent(message, SDL_WINDOWEVENT_MAXIMIZED); + break; + + case BAPP_MINIMIZE: + _HandleBasicWindowEvent(message, SDL_WINDOWEVENT_MINIMIZED); + break; + + case BAPP_SHOW: + _HandleBasicWindowEvent(message, SDL_WINDOWEVENT_SHOWN); + break; + + case BAPP_HIDE: + _HandleBasicWindowEvent(message, SDL_WINDOWEVENT_HIDDEN); + break; + + case BAPP_MOUSE_FOCUS: + _HandleMouseFocus(message); + break; + + case BAPP_KEYBOARD_FOCUS: + _HandleKeyboardFocus(message); + break; + + case BAPP_WINDOW_CLOSE_REQUESTED: + _HandleBasicWindowEvent(message, SDL_WINDOWEVENT_CLOSE); + break; + + case BAPP_WINDOW_MOVED: + _HandleWindowMoved(message); + break; + + case BAPP_WINDOW_RESIZED: + _HandleWindowResized(message); + break; + + case B_LOCALE_CHANGED: + SDL_SendLocaleChangedEvent(); + break; + + case BAPP_SCREEN_CHANGED: + /* TODO: Handle screen resize or workspace change */ + break; + + default: + BLooper::MessageReceived(message); + break; + } + } + + /* Window creation/destruction methods */ + int32 GetID(SDL_Window *win) + { + int32 i; + for (i = 0; i < _GetNumWindowSlots(); ++i) { + if (GetSDLWindow(i) == NULL) { + _SetSDLWindow(win, i); + return i; + } + } + + /* Expand the vector if all slots are full */ + if (i == _GetNumWindowSlots()) { + _PushBackWindow(win); + return i; + } + + /* TODO: error handling */ + return 0; + } + + /* FIXME: Bad coding practice, but I can't include SDL_BWin.h here. Is + there another way to do this? */ + void ClearID(SDL_BWin *bwin); /* Defined in SDL_BeApp.cc */ + + SDL_Window *GetSDLWindow(int32 winID) + { + return _window_map[winID]; + } + +#ifdef SDL_VIDEO_OPENGL + BGLView *GetCurrentContext() + { + return _current_context; + } + + void SetCurrentContext(BGLView *newContext) + { + if (_current_context) + _current_context->UnlockGL(); + _current_context = newContext; + if (_current_context) + _current_context->LockGL(); + } +#endif + + private: + /* Event management */ + void _HandleBasicWindowEvent(BMessage *msg, int32 sdlEventType) + { + SDL_Window *win; + int32 winID; + if ( + !_GetWinID(msg, &winID)) { + return; + } + win = GetSDLWindow(winID); + SDL_SendWindowEvent(win, sdlEventType, 0, 0); + } + + void _HandleMouseMove(BMessage *msg) + { + SDL_Window *win; + int32 winID; + int32 x = 0, y = 0; + if ( + !_GetWinID(msg, &winID) || + msg->FindInt32("x", &x) != B_OK || /* x movement */ + msg->FindInt32("y", &y) != B_OK /* y movement */ + ) { + return; + } + win = GetSDLWindow(winID); + + // Simple relative mode support for mouse. + if (SDL_GetMouse()->relative_mode) { + int winWidth, winHeight, winPosX, winPosY; + SDL_GetWindowSize(win, &winWidth, &winHeight); + SDL_GetWindowPosition(win, &winPosX, &winPosY); + int dx = x - (winWidth / 2); + int dy = y - (winHeight / 2); + SDL_SendMouseMotion(win, 0, SDL_GetMouse()->relative_mode, dx, dy); + set_mouse_position((winPosX + winWidth / 2), (winPosY + winHeight / 2)); + if (!be_app->IsCursorHidden()) + be_app->HideCursor(); + } else { + SDL_SendMouseMotion(win, 0, 0, x, y); + if (SDL_ShowCursor(-1) && be_app->IsCursorHidden()) + be_app->ShowCursor(); + } + } + + void _HandleMouseButton(BMessage *msg) + { + SDL_Window *win; + int32 winID; + int32 button, state; /* left/middle/right, pressed/released */ + if ( + !_GetWinID(msg, &winID) || + msg->FindInt32("button-id", &button) != B_OK || + msg->FindInt32("button-state", &state) != B_OK) { + return; + } + win = GetSDLWindow(winID); + SDL_SendMouseButton(win, 0, state, button); + } + + void _HandleMouseWheel(BMessage *msg) + { + SDL_Window *win; + int32 winID; + int32 xTicks, yTicks; + if ( + !_GetWinID(msg, &winID) || + msg->FindInt32("xticks", &xTicks) != B_OK || + msg->FindInt32("yticks", &yTicks) != B_OK) { + return; + } + win = GetSDLWindow(winID); + SDL_SendMouseWheel(win, 0, xTicks, -yTicks, SDL_MOUSEWHEEL_NORMAL); + } + + void _HandleKey(BMessage *msg) + { + int32 scancode, state; /* scancode, pressed/released */ + if ( + msg->FindInt32("key-state", &state) != B_OK || + msg->FindInt32("key-scancode", &scancode) != B_OK) { + return; + } + + /* Make sure this isn't a repeated event (key pressed and held) */ + if (state == SDL_PRESSED && HAIKU_GetKeyState(scancode) == SDL_PRESSED) { + return; + } + HAIKU_SetKeyState(scancode, state); + SDL_SendKeyboardKey(state, HAIKU_GetScancodeFromBeKey(scancode)); + + if (state == SDL_PRESSED && SDL_EventState(SDL_TEXTINPUT, SDL_QUERY)) { + const int8 *keyUtf8; + ssize_t count; + if (msg->FindData("key-utf8", B_INT8_TYPE, (const void **)&keyUtf8, &count) == B_OK) { + char text[SDL_TEXTINPUTEVENT_TEXT_SIZE]; + SDL_zeroa(text); + SDL_memcpy(text, keyUtf8, count); + SDL_SendKeyboardText(text); + } + } + } + + void _HandleMouseFocus(BMessage *msg) + { + SDL_Window *win; + int32 winID; + bool bSetFocus; /* If false, lose focus */ + if ( + !_GetWinID(msg, &winID) || + msg->FindBool("focusGained", &bSetFocus) != B_OK) { + return; + } + win = GetSDLWindow(winID); + if (bSetFocus) { + SDL_SetMouseFocus(win); + } else if (SDL_GetMouseFocus() == win) { + /* Only lose all focus if this window was the current focus */ + SDL_SetMouseFocus(NULL); + } + } + + void _HandleKeyboardFocus(BMessage *msg) + { + SDL_Window *win; + int32 winID; + bool bSetFocus; /* If false, lose focus */ + if ( + !_GetWinID(msg, &winID) || + msg->FindBool("focusGained", &bSetFocus) != B_OK) { + return; + } + win = GetSDLWindow(winID); + if (bSetFocus) { + SDL_SetKeyboardFocus(win); + } else if (SDL_GetKeyboardFocus() == win) { + /* Only lose all focus if this window was the current focus */ + SDL_SetKeyboardFocus(NULL); + } + } + + void _HandleWindowMoved(BMessage *msg) + { + SDL_Window *win; + int32 winID; + int32 xPos, yPos; + /* Get the window id and new x/y position of the window */ + if ( + !_GetWinID(msg, &winID) || + msg->FindInt32("window-x", &xPos) != B_OK || + msg->FindInt32("window-y", &yPos) != B_OK) { + return; + } + win = GetSDLWindow(winID); + SDL_SendWindowEvent(win, SDL_WINDOWEVENT_MOVED, xPos, yPos); + } + + void _HandleWindowResized(BMessage *msg) + { + SDL_Window *win; + int32 winID; + int32 w, h; + /* Get the window id ]and new x/y position of the window */ + if ( + !_GetWinID(msg, &winID) || + msg->FindInt32("window-w", &w) != B_OK || + msg->FindInt32("window-h", &h) != B_OK) { + return; + } + win = GetSDLWindow(winID); + SDL_SendWindowEvent(win, SDL_WINDOWEVENT_RESIZED, w, h); + } + + bool _GetWinID(BMessage *msg, int32 *winID) + { + return msg->FindInt32("window-id", winID) == B_OK; + } + + /* Vector functions: Wraps vector stuff in case we need to change + implementation */ + void _SetSDLWindow(SDL_Window *win, int32 winID) + { + _window_map[winID] = win; + } + + int32 _GetNumWindowSlots() + { + return _window_map.size(); + } + + void _PopBackWindow() + { + _window_map.pop_back(); + } + + void _PushBackWindow(SDL_Window *win) + { + _window_map.push_back(win); + } + + /* Members */ + std::vector _window_map; /* Keeps track of SDL_Windows by index-id */ + +#ifdef SDL_VIDEO_OPENGL + BGLView *_current_context; +#endif +}; + +#endif diff --git a/SDL2-2.30.5/src/video/haiku/SDL_BWin.h b/SDL2-2.30.5/src/video/haiku/SDL_BWin.h new file mode 100644 index 0000000..f1ad1ea --- /dev/null +++ b/SDL2-2.30.5/src/video/haiku/SDL_BWin.h @@ -0,0 +1,754 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#ifndef SDL_BWin_h_ +#define SDL_BWin_h_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "../../SDL_internal.h" +#include "SDL.h" +#include "SDL_syswm.h" +#include "SDL_bframebuffer.h" + +#ifdef __cplusplus +} +#endif + +#include +#include +#include +#include +#ifdef SDL_VIDEO_OPENGL +#include +#endif +#include "SDL_events.h" +#include "../../main/haiku/SDL_BApp.h" + +enum WinCommands +{ + BWIN_MOVE_WINDOW, + BWIN_RESIZE_WINDOW, + BWIN_SHOW_WINDOW, + BWIN_HIDE_WINDOW, + BWIN_MAXIMIZE_WINDOW, + BWIN_MINIMIZE_WINDOW, + BWIN_RESTORE_WINDOW, + BWIN_SET_TITLE, + BWIN_SET_BORDERED, + BWIN_SET_RESIZABLE, + BWIN_FULLSCREEN, + BWIN_UPDATE_FRAMEBUFFER, + BWIN_MINIMUM_SIZE_WINDOW +}; + +// non-OpenGL framebuffer view +class SDL_BView : public BView +{ + public: + SDL_BView(BRect frame, const char *name, uint32 resizingMode) + : BView(frame, name, resizingMode, B_WILL_DRAW), + fBitmap(NULL) + { + } + + void Draw(BRect dirty) + { + if (fBitmap != NULL) + DrawBitmap(fBitmap, B_ORIGIN); + } + + void SetBitmap(BBitmap *bitmap) + { + fBitmap = bitmap; + } + + private: + BBitmap *fBitmap; +}; + +class SDL_BWin : public BWindow +{ + public: + /* Constructor/Destructor */ + SDL_BWin(BRect bounds, window_look look, uint32 flags) + : BWindow(bounds, "Untitled", look, B_NORMAL_WINDOW_FEEL, flags) + { + _last_buttons = 0; + + _cur_view = NULL; + _SDL_View = NULL; + +#ifdef SDL_VIDEO_OPENGL + _SDL_GLView = NULL; + _gl_type = 0; +#endif + _shown = false; + _inhibit_resize = false; + _mouse_focused = false; + _prev_frame = NULL; + _fullscreen = NULL; + + /* Handle framebuffer stuff */ + _buffer_locker = new BLocker(); + _bitmap = NULL; + } + + virtual ~SDL_BWin() + { + Lock(); + + if (_SDL_View != NULL && _SDL_View != _cur_view) { + delete _SDL_View; + _SDL_View = NULL; + } + +#ifdef SDL_VIDEO_OPENGL + if (_SDL_GLView) { + if (SDL_Looper->GetCurrentContext() == _SDL_GLView) + SDL_Looper->SetCurrentContext(NULL); + if (_SDL_GLView == _cur_view) + RemoveChild(_SDL_GLView); + _SDL_GLView = NULL; + // _SDL_GLView deleted by HAIKU_GL_DeleteContext + } + +#endif + Unlock(); + + delete _prev_frame; + + /* Clean up framebuffer stuff */ + _buffer_locker->Lock(); + delete _buffer_locker; + } + + void SetCurrentView(BView *view) + { + if (_cur_view != view) { + if (_cur_view != NULL) + RemoveChild(_cur_view); + _cur_view = view; + if (_cur_view != NULL) + AddChild(_cur_view); + } + } + + void UpdateCurrentView() + { + if (_SDL_GLView != NULL) { + SetCurrentView(_SDL_GLView); + } else if (_SDL_View != NULL) { + SetCurrentView(_SDL_View); + } else { + SetCurrentView(NULL); + } + } + + SDL_BView *CreateView() + { + Lock(); + if (_SDL_View == NULL) { + _SDL_View = new SDL_BView(Bounds(), "SDL View", B_FOLLOW_ALL_SIDES); + UpdateCurrentView(); + } + Unlock(); + return _SDL_View; + } + + void RemoveView() + { + Lock(); + if (_SDL_View != NULL) { + SDL_BView *oldView = _SDL_View; + _SDL_View = NULL; + UpdateCurrentView(); + delete oldView; + } + Unlock(); + } + + /* * * * * OpenGL functionality * * * * */ +#ifdef SDL_VIDEO_OPENGL + BGLView *CreateGLView(Uint32 gl_flags) + { + Lock(); + if (_SDL_GLView == NULL) { + _SDL_GLView = new BGLView(Bounds(), "SDL GLView", + B_FOLLOW_ALL_SIDES, + (B_WILL_DRAW | B_FRAME_EVENTS), + gl_flags); + _gl_type = gl_flags; + UpdateCurrentView(); + } + Unlock(); + return _SDL_GLView; + } + + void RemoveGLView() + { + Lock(); + if (_SDL_GLView != NULL) { + if (SDL_Looper->GetCurrentContext() == _SDL_GLView) + SDL_Looper->SetCurrentContext(NULL); + _SDL_GLView = NULL; + UpdateCurrentView(); + // _SDL_GLView deleted by HAIKU_GL_DeleteContext + } + Unlock(); + } + + void SwapBuffers(void) + { + _SDL_GLView->SwapBuffers(); + } +#endif + + /* * * * * Event sending * * * * */ + /* Hook functions */ + virtual void FrameMoved(BPoint origin) + { + /* Post a message to the BApp so that it can handle the window event */ + BMessage msg(BAPP_WINDOW_MOVED); + msg.AddInt32("window-x", (int)origin.x); + msg.AddInt32("window-y", (int)origin.y); + _PostWindowEvent(msg); + + /* Perform normal hook operations */ + BWindow::FrameMoved(origin); + } + + void FrameResized(float width, float height) + { + /* Post a message to the BApp so that it can handle the window event */ + BMessage msg(BAPP_WINDOW_RESIZED); + + msg.AddInt32("window-w", (int)width + 1); + msg.AddInt32("window-h", (int)height + 1); + _PostWindowEvent(msg); + + /* Perform normal hook operations */ + BWindow::FrameResized(width, height); + } + + bool QuitRequested() + { + BMessage msg(BAPP_WINDOW_CLOSE_REQUESTED); + _PostWindowEvent(msg); + + /* We won't allow a quit unless asked by DestroyWindow() */ + return false; + } + + void WindowActivated(bool active) + { + BMessage msg(BAPP_KEYBOARD_FOCUS); /* Mouse focus sold separately */ + msg.AddBool("focusGained", active); + _PostWindowEvent(msg); + } + + void Zoom(BPoint origin, + float width, + float height) + { + BMessage msg(BAPP_MAXIMIZE); /* Closest thing to maximization Haiku has */ + _PostWindowEvent(msg); + + /* Before the window zooms, record its size */ + if (!_prev_frame) + _prev_frame = new BRect(Frame()); + + /* Perform normal hook operations */ + BWindow::Zoom(origin, width, height); + } + + /* Member functions */ + void Show() + { + while (IsHidden()) { + BWindow::Show(); + } + _shown = true; + + BMessage msg(BAPP_SHOW); + _PostWindowEvent(msg); + } + + void Hide() + { + BWindow::Hide(); + _shown = false; + + BMessage msg(BAPP_HIDE); + _PostWindowEvent(msg); + } + + void Minimize(bool minimize) + { + BWindow::Minimize(minimize); + int32 minState = (minimize ? BAPP_MINIMIZE : BAPP_RESTORE); + + BMessage msg(minState); + _PostWindowEvent(msg); + } + + void ScreenChanged(BRect screenFrame, color_space depth) + { + if (_fullscreen) { + MoveTo(screenFrame.left, screenFrame.top); + ResizeTo(screenFrame.Width(), screenFrame.Height()); + } + } + + /* BView message interruption */ + void DispatchMessage(BMessage *msg, BHandler *target) + { + BPoint where; /* Used by mouse moved */ + int32 buttons; /* Used for mouse button events */ + int32 key; /* Used for key events */ + + switch (msg->what) { + case B_MOUSE_MOVED: + int32 transit; + if (msg->FindPoint("where", &where) == B_OK && msg->FindInt32("be:transit", &transit) == B_OK) { + _MouseMotionEvent(where, transit); + } + break; + + case B_MOUSE_DOWN: + if (msg->FindInt32("buttons", &buttons) == B_OK) { + _MouseButtonEvent(buttons, SDL_PRESSED); + } + break; + + case B_MOUSE_UP: + if (msg->FindInt32("buttons", &buttons) == B_OK) { + _MouseButtonEvent(buttons, SDL_RELEASED); + } + break; + + case B_MOUSE_WHEEL_CHANGED: + float x, y; + if (msg->FindFloat("be:wheel_delta_x", &x) == B_OK && msg->FindFloat("be:wheel_delta_y", &y) == B_OK) { + _MouseWheelEvent((int)x, (int)y); + } + break; + + case B_KEY_DOWN: + { + int32 i = 0; + int8 byte; + int8 bytes[4] = { 0, 0, 0, 0 }; + while (i < 4 && msg->FindInt8("byte", i, &byte) == B_OK) { + bytes[i] = byte; + i++; + } + if (msg->FindInt32("key", &key) == B_OK) { + _KeyEvent((SDL_Scancode)key, &bytes[0], i, SDL_PRESSED); + } + } break; + + case B_UNMAPPED_KEY_DOWN: /* modifier keys are unmapped */ + if (msg->FindInt32("key", &key) == B_OK) { + _KeyEvent((SDL_Scancode)key, NULL, 0, SDL_PRESSED); + } + break; + + case B_KEY_UP: + case B_UNMAPPED_KEY_UP: /* modifier keys are unmapped */ + if (msg->FindInt32("key", &key) == B_OK) { + _KeyEvent(key, NULL, 0, SDL_RELEASED); + } + break; + + default: + /* move it after switch{} so it's always handled + that way we keep Haiku features like: + - CTRL+Q to close window (and other shortcuts) + - PrintScreen to make screenshot into /boot/home + - etc.. */ + /* BWindow::DispatchMessage(msg, target); */ + break; + } + + BWindow::DispatchMessage(msg, target); + } + + /* Handle command messages */ + void MessageReceived(BMessage *message) + { + switch (message->what) { + /* Handle commands from SDL */ + case BWIN_SET_TITLE: + _SetTitle(message); + break; + case BWIN_MOVE_WINDOW: + _MoveTo(message); + break; + case BWIN_RESIZE_WINDOW: + _ResizeTo(message); + break; + case BWIN_SET_BORDERED: + { + bool bEnabled; + if (message->FindBool("window-border", &bEnabled) == B_OK) + _SetBordered(bEnabled); + break; + } + case BWIN_SET_RESIZABLE: + { + bool bEnabled; + if (message->FindBool("window-resizable", &bEnabled) == B_OK) + _SetResizable(bEnabled); + break; + } + case BWIN_SHOW_WINDOW: + Show(); + break; + case BWIN_HIDE_WINDOW: + Hide(); + break; + case BWIN_MAXIMIZE_WINDOW: + BWindow::Zoom(); + break; + case BWIN_MINIMIZE_WINDOW: + Minimize(true); + break; + case BWIN_RESTORE_WINDOW: + _Restore(); + break; + case BWIN_FULLSCREEN: + { + bool fullscreen; + if (message->FindBool("fullscreen", &fullscreen) == B_OK) + _SetFullScreen(fullscreen); + break; + } + case BWIN_MINIMUM_SIZE_WINDOW: + _SetMinimumSize(message); + break; + case BWIN_UPDATE_FRAMEBUFFER: + { + BMessage *pendingMessage; + while ((pendingMessage = MessageQueue()->FindMessage(BWIN_UPDATE_FRAMEBUFFER, 0))) { + MessageQueue()->RemoveMessage(pendingMessage); + delete pendingMessage; + } + if (_bitmap != NULL) { + if (_SDL_View != NULL && _cur_view == _SDL_View) + _SDL_View->Draw(Bounds()); + else if (_SDL_GLView != NULL && _cur_view == _SDL_GLView) { + _SDL_GLView->CopyPixelsIn(_bitmap, B_ORIGIN); + } + } + break; + } + default: + /* Perform normal message handling */ + BWindow::MessageReceived(message); + break; + } + } + + /* Accessor methods */ + bool IsShown() { return _shown; } + int32 GetID() { return _id; } + BBitmap *GetBitmap() { return _bitmap; } + BView *GetCurView() { return _cur_view; } + SDL_BView *GetView() { return _SDL_View; } +#ifdef SDL_VIDEO_OPENGL + BGLView *GetGLView() + { + return _SDL_GLView; + } + Uint32 GetGLType() { return _gl_type; } +#endif + + /* Setter methods */ + void SetID(int32 id) { _id = id; } + void LockBuffer() { _buffer_locker->Lock(); } + void UnlockBuffer() { _buffer_locker->Unlock(); } + void SetBitmap(BBitmap *bitmap) + { + _bitmap = bitmap; + if (_SDL_View != NULL) + _SDL_View->SetBitmap(bitmap); + } + + private: + /* Event redirection */ + void _MouseMotionEvent(BPoint &where, int32 transit) + { + if (transit == B_EXITED_VIEW) { + /* Change mouse focus */ + if (_mouse_focused) { + _MouseFocusEvent(false); + } + } else { + /* Change mouse focus */ + if (!_mouse_focused) { + _MouseFocusEvent(true); + } + BMessage msg(BAPP_MOUSE_MOVED); + msg.AddInt32("x", (int)where.x); + msg.AddInt32("y", (int)where.y); + + _PostWindowEvent(msg); + } + } + + void _MouseFocusEvent(bool focusGained) + { + _mouse_focused = focusGained; + BMessage msg(BAPP_MOUSE_FOCUS); + msg.AddBool("focusGained", focusGained); + _PostWindowEvent(msg); + + /* FIXME: Why were these here? + if false: be_app->SetCursor(B_HAND_CURSOR); + if true: SDL_SetCursor(NULL); */ + } + + void _MouseButtonEvent(int32 buttons, Uint8 state) + { + int32 buttonStateChange = buttons ^ _last_buttons; + + if (buttonStateChange & B_PRIMARY_MOUSE_BUTTON) { + _SendMouseButton(SDL_BUTTON_LEFT, state); + } + if (buttonStateChange & B_SECONDARY_MOUSE_BUTTON) { + _SendMouseButton(SDL_BUTTON_RIGHT, state); + } + if (buttonStateChange & B_TERTIARY_MOUSE_BUTTON) { + _SendMouseButton(SDL_BUTTON_MIDDLE, state); + } + + _last_buttons = buttons; + } + + void _SendMouseButton(int32 button, int32 state) + { + BMessage msg(BAPP_MOUSE_BUTTON); + msg.AddInt32("button-id", button); + msg.AddInt32("button-state", state); + _PostWindowEvent(msg); + } + + void _MouseWheelEvent(int32 x, int32 y) + { + /* Create a message to pass along to the BeApp thread */ + BMessage msg(BAPP_MOUSE_WHEEL); + msg.AddInt32("xticks", x); + msg.AddInt32("yticks", y); + _PostWindowEvent(msg); + } + + void _KeyEvent(int32 keyCode, const int8 *keyUtf8, const ssize_t &len, int32 keyState) + { + /* Create a message to pass along to the BeApp thread */ + BMessage msg(BAPP_KEY); + msg.AddInt32("key-state", keyState); + msg.AddInt32("key-scancode", keyCode); + if (keyUtf8 != NULL) { + msg.AddData("key-utf8", B_INT8_TYPE, (const void *)keyUtf8, len); + } + SDL_Looper->PostMessage(&msg); + } + + void _RepaintEvent() + { + /* Force a repaint: Call the SDL exposed event */ + BMessage msg(BAPP_REPAINT); + _PostWindowEvent(msg); + } + void _PostWindowEvent(BMessage &msg) + { + msg.AddInt32("window-id", _id); + SDL_Looper->PostMessage(&msg); + } + + /* Command methods (functions called upon by SDL) */ + void _SetTitle(BMessage *msg) + { + const char *title; + if ( + msg->FindString("window-title", &title) != B_OK) { + return; + } + SetTitle(title); + } + + void _MoveTo(BMessage *msg) + { + int32 x, y; + if ( + msg->FindInt32("window-x", &x) != B_OK || + msg->FindInt32("window-y", &y) != B_OK) { + return; + } + if (_fullscreen) + _non_fullscreen_frame.OffsetTo(x, y); + else + MoveTo(x, y); + } + + void _ResizeTo(BMessage *msg) + { + int32 w, h; + if ( + msg->FindInt32("window-w", &w) != B_OK || + msg->FindInt32("window-h", &h) != B_OK) { + return; + } + if (_fullscreen) { + _non_fullscreen_frame.right = _non_fullscreen_frame.left + w; + _non_fullscreen_frame.bottom = _non_fullscreen_frame.top + h; + } else + ResizeTo(w, h); + } + + void _SetBordered(bool bEnabled) + { + if (_fullscreen) + _bordered = bEnabled; + else + SetLook(bEnabled ? B_TITLED_WINDOW_LOOK : B_NO_BORDER_WINDOW_LOOK); + } + + void _SetResizable(bool bEnabled) + { + if (_fullscreen) + _resizable = bEnabled; + else { + if (bEnabled) { + SetFlags(Flags() & ~(B_NOT_RESIZABLE | B_NOT_ZOOMABLE)); + } else { + SetFlags(Flags() | (B_NOT_RESIZABLE | B_NOT_ZOOMABLE)); + } + } + } + + void _SetMinimumSize(BMessage *msg) + { + float maxHeight; + float maxWidth; + float _; + int32 minHeight; + int32 minWidth; + + // This is a bit convoluted, we only want to set the minimum not the maximum + // But there is no direct call to do that, so store the maximum size beforehand + GetSizeLimits(&_, &maxWidth, &_, &maxHeight); + if (msg->FindInt32("window-w", &minWidth) != B_OK) + return; + if (msg->FindInt32("window-h", &minHeight) != B_OK) + return; + SetSizeLimits((float)minWidth, maxWidth, (float)minHeight, maxHeight); + UpdateSizeLimits(); + } + + void _Restore() + { + if (IsMinimized()) { + Minimize(false); + } else if (IsHidden()) { + Show(); + } else if (_fullscreen) { + + } else if (_prev_frame != NULL) { /* Zoomed */ + MoveTo(_prev_frame->left, _prev_frame->top); + ResizeTo(_prev_frame->Width(), _prev_frame->Height()); + } + } + + void _SetFullScreen(bool fullscreen) + { + if (fullscreen != _fullscreen) { + if (fullscreen) { + BScreen screen(this); + BRect screenFrame = screen.Frame(); + printf("screen frame: "); + screenFrame.PrintToStream(); + printf("\n"); + _bordered = Look() != B_NO_BORDER_WINDOW_LOOK; + _resizable = !(Flags() & B_NOT_RESIZABLE); + _non_fullscreen_frame = Frame(); + _SetBordered(false); + _SetResizable(false); + MoveTo(screenFrame.left, screenFrame.top); + ResizeTo(screenFrame.Width(), screenFrame.Height()); + _fullscreen = fullscreen; + } else { + _fullscreen = fullscreen; + MoveTo(_non_fullscreen_frame.left, _non_fullscreen_frame.top); + ResizeTo(_non_fullscreen_frame.Width(), _non_fullscreen_frame.Height()); + _SetBordered(_bordered); + _SetResizable(_resizable); + } + } + } + + /* Members */ + + BView *_cur_view; + SDL_BView *_SDL_View; +#ifdef SDL_VIDEO_OPENGL + BGLView *_SDL_GLView; + Uint32 _gl_type; +#endif + + int32 _last_buttons; + int32 _id; /* Window id used by SDL_BApp */ + bool _mouse_focused; /* Does this window have mouse focus? */ + bool _shown; + bool _inhibit_resize; + + BRect *_prev_frame; /* Previous position and size of the window */ + bool _fullscreen; + // valid only if fullscreen + BRect _non_fullscreen_frame; + bool _bordered; + bool _resizable; + + /* Framebuffer members */ + BLocker *_buffer_locker; + BBitmap *_bitmap; +}; + +/* FIXME: + * An explanation of framebuffer flags. + * + * _connected - Original variable used to let the drawing thread know + * when changes are being made to the other framebuffer + * members. + * _connection_disabled - Used to signal to the drawing thread that the window + * is closing, and the thread should exit. + * _buffer_created - True if the current buffer is valid + * _buffer_dirty - True if the window should be redrawn. + * _trash_window_buffer - True if the window buffer needs to be trashed partway + * through a draw cycle. Occurs when the previous + * buffer provided by DirectConnected() is invalidated. + */ +#endif /* SDL_BWin_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/haiku/SDL_bclipboard.cc b/SDL2-2.30.5/src/video/haiku/SDL_bclipboard.cc similarity index 89% rename from SDL2-2.0.12/src/video/haiku/SDL_bclipboard.cc rename to SDL2-2.30.5/src/video/haiku/SDL_bclipboard.cc index 50dc9d6..11e79f3 100644 --- a/SDL2-2.0.12/src/video/haiku/SDL_bclipboard.cc +++ b/SDL2-2.30.5/src/video/haiku/SDL_bclipboard.cc @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_HAIKU +#ifdef SDL_VIDEO_DRIVER_HAIKU /* BWindow based clipboard implementation */ @@ -37,12 +37,12 @@ extern "C" { int HAIKU_SetClipboardText(_THIS, const char *text) { BMessage *clip = NULL; - if(be_clipboard->Lock()) { + if (be_clipboard->Lock()) { be_clipboard->Clear(); - if((clip = be_clipboard->Data())) { + if ((clip = be_clipboard->Data())) { /* Presumably the string of characters is ascii-format */ ssize_t asciiLength = 0; - for(; text[asciiLength] != 0; ++asciiLength) {} + for (; text[asciiLength] != 0; ++asciiLength) {} clip->AddData("text/plain", B_MIME_TYPE, text, asciiLength); be_clipboard->Commit(); } @@ -56,8 +56,8 @@ char *HAIKU_GetClipboardText(_THIS) { const char *text = NULL; ssize_t length; char *result; - if(be_clipboard->Lock()) { - if((clip = be_clipboard->Data())) { + if (be_clipboard->Lock()) { + if ((clip = be_clipboard->Data())) { /* Presumably the string of characters is ascii-format */ clip->FindData("text/plain", B_MIME_TYPE, (const void**)&text, &length); diff --git a/SDL2-2.0.12/src/video/haiku/SDL_bclipboard.h b/SDL2-2.30.5/src/video/haiku/SDL_bclipboard.h similarity index 95% rename from SDL2-2.0.12/src/video/haiku/SDL_bclipboard.h rename to SDL2-2.30.5/src/video/haiku/SDL_bclipboard.h index a52758e..89e9e90 100644 --- a/SDL2-2.0.12/src/video/haiku/SDL_bclipboard.h +++ b/SDL2-2.30.5/src/video/haiku/SDL_bclipboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/video/haiku/SDL_bevents.cc b/SDL2-2.30.5/src/video/haiku/SDL_bevents.cc similarity index 92% rename from SDL2-2.0.12/src/video/haiku/SDL_bevents.cc rename to SDL2-2.30.5/src/video/haiku/SDL_bevents.cc index 95df72c..45727a6 100644 --- a/SDL2-2.0.12/src/video/haiku/SDL_bevents.cc +++ b/SDL2-2.30.5/src/video/haiku/SDL_bevents.cc @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_HAIKU +#ifdef SDL_VIDEO_DRIVER_HAIKU #include "SDL_bevents.h" diff --git a/SDL2-2.0.12/src/video/haiku/SDL_bevents.h b/SDL2-2.30.5/src/video/haiku/SDL_bevents.h similarity index 94% rename from SDL2-2.0.12/src/video/haiku/SDL_bevents.h rename to SDL2-2.30.5/src/video/haiku/SDL_bevents.h index fa9e79a..1afd33a 100644 --- a/SDL2-2.0.12/src/video/haiku/SDL_bevents.h +++ b/SDL2-2.30.5/src/video/haiku/SDL_bevents.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.30.5/src/video/haiku/SDL_bframebuffer.cc b/SDL2-2.30.5/src/video/haiku/SDL_bframebuffer.cc new file mode 100644 index 0000000..1961cea --- /dev/null +++ b/SDL2-2.30.5/src/video/haiku/SDL_bframebuffer.cc @@ -0,0 +1,129 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_HAIKU + +#include "SDL_bframebuffer.h" + +#include +#include +#include "SDL_bmodes.h" +#include "SDL_BWin.h" + +#include "../../main/haiku/SDL_BApp.h" + +#ifdef __cplusplus +extern "C" { +#endif + +static SDL_INLINE SDL_BWin *_ToBeWin(SDL_Window *window) { + return (SDL_BWin *)(window->driverdata); +} + +static SDL_INLINE SDL_BLooper *_GetBeLooper() { + return SDL_Looper; +} + +int HAIKU_CreateWindowFramebuffer(_THIS, SDL_Window * window, + Uint32 * format, + void ** pixels, int *pitch) { + SDL_BWin *bwin = _ToBeWin(window); + BScreen bscreen; + if (!bscreen.IsValid()) { + return -1; + } + + /* Make sure we have exclusive access to frame buffer data */ + bwin->LockBuffer(); + + bwin->CreateView(); + + /* format */ + display_mode bmode; + bscreen.GetMode(&bmode); + *format = HAIKU_ColorSpaceToSDLPxFormat(bmode.space); + + /* Create the new bitmap object */ + BBitmap *bitmap = bwin->GetBitmap(); + + if (bitmap) { + delete bitmap; + } + bitmap = new BBitmap(bwin->Bounds(), (color_space)bmode.space, + false, /* Views not accepted */ + true); /* Contiguous memory required */ + + if (bitmap->InitCheck() != B_OK) { + delete bitmap; + return SDL_SetError("Could not initialize back buffer!"); + } + + + bwin->SetBitmap(bitmap); + + /* Set the pixel pointer */ + *pixels = bitmap->Bits(); + + /* pitch = width of window, in bytes */ + *pitch = bitmap->BytesPerRow(); + + bwin->UnlockBuffer(); + return 0; +} + + + +int HAIKU_UpdateWindowFramebuffer(_THIS, SDL_Window * window, + const SDL_Rect * rects, int numrects) { + if (!window) { + return 0; + } + + SDL_BWin *bwin = _ToBeWin(window); + + bwin->PostMessage(BWIN_UPDATE_FRAMEBUFFER); + + return 0; +} + +void HAIKU_DestroyWindowFramebuffer(_THIS, SDL_Window * window) { + SDL_BWin *bwin = _ToBeWin(window); + + bwin->LockBuffer(); + + /* Free and clear the window buffer */ + BBitmap *bitmap = bwin->GetBitmap(); + delete bitmap; + bwin->SetBitmap(NULL); + + bwin->RemoveView(); + + bwin->UnlockBuffer(); +} + +#ifdef __cplusplus +} +#endif + +#endif /* SDL_VIDEO_DRIVER_HAIKU */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/haiku/SDL_bframebuffer.h b/SDL2-2.30.5/src/video/haiku/SDL_bframebuffer.h similarity index 71% rename from SDL2-2.0.12/src/video/haiku/SDL_bframebuffer.h rename to SDL2-2.30.5/src/video/haiku/SDL_bframebuffer.h index 62665ae..ce3649c 100644 --- a/SDL2-2.0.12/src/video/haiku/SDL_bframebuffer.h +++ b/SDL2-2.30.5/src/video/haiku/SDL_bframebuffer.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -30,12 +30,12 @@ extern "C" { #include "../SDL_sysvideo.h" -extern int HAIKU_CreateWindowFramebuffer(_THIS, SDL_Window * window, - Uint32 * format, - void ** pixels, int *pitch); -extern int HAIKU_UpdateWindowFramebuffer(_THIS, SDL_Window * window, - const SDL_Rect * rects, int numrects); -extern void HAIKU_DestroyWindowFramebuffer(_THIS, SDL_Window * window); +extern int HAIKU_CreateWindowFramebuffer(_THIS, SDL_Window *window, + Uint32 *format, + void **pixels, int *pitch); +extern int HAIKU_UpdateWindowFramebuffer(_THIS, SDL_Window *window, + const SDL_Rect *rects, int numrects); +extern void HAIKU_DestroyWindowFramebuffer(_THIS, SDL_Window *window); extern int32 HAIKU_DrawThread(void *data); #ifdef __cplusplus diff --git a/SDL2-2.0.12/src/video/haiku/SDL_bkeyboard.cc b/SDL2-2.30.5/src/video/haiku/SDL_bkeyboard.cc similarity index 96% rename from SDL2-2.0.12/src/video/haiku/SDL_bkeyboard.cc rename to SDL2-2.30.5/src/video/haiku/SDL_bkeyboard.cc index 064249f..b9499ed 100644 --- a/SDL2-2.0.12/src/video/haiku/SDL_bkeyboard.cc +++ b/SDL2-2.30.5/src/video/haiku/SDL_bkeyboard.cc @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_HAIKU +#ifdef SDL_VIDEO_DRIVER_HAIKU #include #include @@ -42,11 +42,11 @@ static SDL_Scancode keymap[KEYMAP_SIZE]; static int8 keystate[KEYMAP_SIZE]; void HAIKU_InitOSKeymap(void) { - for( uint i = 0; i < SDL_TABLESIZE(keymap); ++i ) { + for ( uint i = 0; i < SDL_TABLESIZE(keymap); ++i ) { keymap[i] = SDL_SCANCODE_UNKNOWN; } - for( uint i = 0; i < KEYMAP_SIZE; ++i ) { + for ( uint i = 0; i < KEYMAP_SIZE; ++i ) { keystate[i] = SDL_RELEASED; } @@ -160,7 +160,7 @@ void HAIKU_InitOSKeymap(void) { } SDL_Scancode HAIKU_GetScancodeFromBeKey(int32 bkey) { - if(bkey > 0 && bkey < (int32)SDL_TABLESIZE(keymap)) { + if (bkey > 0 && bkey < (int32)SDL_TABLESIZE(keymap)) { return keymap[bkey]; } else { return SDL_SCANCODE_UNKNOWN; @@ -168,7 +168,7 @@ SDL_Scancode HAIKU_GetScancodeFromBeKey(int32 bkey) { } int8 HAIKU_GetKeyState(int32 bkey) { - if(bkey > 0 && bkey < KEYMAP_SIZE) { + if (bkey > 0 && bkey < KEYMAP_SIZE) { return keystate[bkey]; } else { return SDL_RELEASED; @@ -176,7 +176,7 @@ int8 HAIKU_GetKeyState(int32 bkey) { } void HAIKU_SetKeyState(int32 bkey, int8 state) { - if(bkey > 0 && bkey < KEYMAP_SIZE) { + if (bkey > 0 && bkey < KEYMAP_SIZE) { keystate[bkey] = state; } } diff --git a/SDL2-2.0.12/src/video/haiku/SDL_bkeyboard.h b/SDL2-2.30.5/src/video/haiku/SDL_bkeyboard.h similarity index 95% rename from SDL2-2.0.12/src/video/haiku/SDL_bkeyboard.h rename to SDL2-2.30.5/src/video/haiku/SDL_bkeyboard.h index a0ddeed..46fd9d6 100644 --- a/SDL2-2.0.12/src/video/haiku/SDL_bkeyboard.h +++ b/SDL2-2.30.5/src/video/haiku/SDL_bkeyboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/video/haiku/SDL_bmessagebox.cc b/SDL2-2.30.5/src/video/haiku/SDL_bmessagebox.cc similarity index 90% rename from SDL2-2.0.12/src/video/haiku/SDL_bmessagebox.cc rename to SDL2-2.30.5/src/video/haiku/SDL_bmessagebox.cc index cf33033..d0c43e2 100644 --- a/SDL2-2.0.12/src/video/haiku/SDL_bmessagebox.cc +++ b/SDL2-2.30.5/src/video/haiku/SDL_bmessagebox.cc @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga Copyright (C) 2018-2019 EXL This software is provided 'as-is', without any express or implied @@ -22,7 +22,7 @@ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_HAIKU +#ifdef SDL_VIDEO_DRIVER_HAIKU #include "SDL_messagebox.h" @@ -131,32 +131,27 @@ class HAIKU_SDL_MessageBox : public BAlert void ParseSdlMessageBoxData(const SDL_MessageBoxData *aMessageBoxData) { - if (aMessageBoxData == NULL) - { + if (aMessageBoxData == NULL) { SetTitle(HAIKU_SDL_DefTitle); SetMessageText(HAIKU_SDL_DefMessage); AddButton(HAIKU_SDL_DefButton); return; } - if (aMessageBoxData->numbuttons <= 0) - { + if (aMessageBoxData->numbuttons <= 0) { AddButton(HAIKU_SDL_DefButton); - } - else - { + } else { AddSdlButtons(aMessageBoxData->buttons, aMessageBoxData->numbuttons); } - if (aMessageBoxData->colorScheme != NULL) - { + if (aMessageBoxData->colorScheme != NULL) { fCustomColorScheme = true; ApplyAndParseColorScheme(aMessageBoxData->colorScheme); } - (aMessageBoxData->title != NULL) ? + (aMessageBoxData->title[0]) ? SetTitle(aMessageBoxData->title) : SetTitle(HAIKU_SDL_DefTitle); - (aMessageBoxData->message != NULL) ? + (aMessageBoxData->message[0]) ? SetMessageText(aMessageBoxData->message) : SetMessageText(HAIKU_SDL_DefMessage); SetType(ConvertMessageBoxType(static_cast(aMessageBoxData->flags))); @@ -179,11 +174,9 @@ class HAIKU_SDL_MessageBox : public BAlert const SDL_MessageBoxColor *aTextColor, const SDL_MessageBoxColor *aSelectedColor) { - if (fCustomColorScheme) - { + if (fCustomColorScheme) { int32 countButtons = CountButtons(); - for (int i = 0; i < countButtons; ++i) - { + for (int i = 0; i < countButtons; ++i) { ButtonAt(i)->SetViewColor(ConvertColorType(aBorderColor)); ButtonAt(i)->SetLowColor(ConvertColorType(aBackgroundColor)); @@ -218,15 +211,12 @@ class HAIKU_SDL_MessageBox : public BAlert BString message = aMessage; int32 length = message.CountChars(); - for (int i = 0, c = 0; i < length; ++i) - { + for (int i = 0, c = 0; i < length; ++i) { c++; - if (*(message.CharAt(i)) == '\n') - { + if (*(message.CharAt(i)) == '\n') { c = 0; } - if (c > final) - { + if (c > final) { final = c; } } @@ -238,20 +228,17 @@ class HAIKU_SDL_MessageBox : public BAlert SetMessageText(const char *aMessage) { fThereIsLongLine = CheckLongLines(aMessage); - if (fThereIsLongLine) - { + if (fThereIsLongLine) { fMessageBoxTextView->SetWordWrap(true); } rgb_color textColor = ui_color(B_PANEL_TEXT_COLOR); - if (fCustomColorScheme) - { + if (fCustomColorScheme) { textColor = fTextColor; } /* - if (fNoTitledWindow) - { + if (fNoTitledWindow) { fMessageBoxTextView->SetFontAndColor(be_bold_font); fMessageBoxTextView->Insert(fTitle); fMessageBoxTextView->Insert("\n\n"); @@ -269,16 +256,14 @@ class HAIKU_SDL_MessageBox : public BAlert void AddSdlButtons(const SDL_MessageBoxButtonData *aButtons, int aNumButtons) { - for (int i = 0; i < aNumButtons; ++i) - { + for (int i = 0; i < aNumButtons; ++i) { fButtons.push_back(&aButtons[i]); } std::sort(fButtons.begin(), fButtons.end(), &HAIKU_SDL_MessageBox::SortButtonsPredicate); size_t countButtons = fButtons.size(); - for (size_t i = 0; i < countButtons; ++i) - { + for (size_t i = 0; i < countButtons; ++i) { switch (fButtons[i]->flags) { case SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT: @@ -342,12 +327,9 @@ protected: virtual void FrameResized(float aNewWidth, float aNewHeight) { - if (fComputedMessageBoxWidth > aNewWidth) - { + if (fComputedMessageBoxWidth > aNewWidth) { ResizeTo(fComputedMessageBoxWidth, aNewHeight); - } - else - { + } else { BAlert::FrameResized(aNewWidth, aNewHeight); } } @@ -364,8 +346,7 @@ protected: extern "C" { #endif -int -HAIKU_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) +int HAIKU_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) { // Initialize button by closed or error value first. *buttonid = G_CLOSE_BUTTON_ID; @@ -375,38 +356,32 @@ HAIKU_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) // "You need a valid BApplication object before interacting with the app_server." // "2 BApplication objects were created. Only one is allowed." BApplication *application = NULL; - if (be_app == NULL) - { - application = new(std::nothrow) BApplication(signature); - if (application == NULL) - { + if (!be_app) { + application = new(std::nothrow) BApplication(SDL_signature); + if (!application) { return SDL_SetError("Cannot create the BApplication object. Lack of memory?"); } } HAIKU_SDL_MessageBox *SDL_MessageBox = new(std::nothrow) HAIKU_SDL_MessageBox(messageboxdata); - if (SDL_MessageBox == NULL) - { + if (!SDL_MessageBox) { return SDL_SetError("Cannot create the HAIKU_SDL_MessageBox (BAlert inheritor) object. Lack of memory?"); } const int closeButton = SDL_MessageBox->GetCloseButtonId(); int pushedButton = SDL_MessageBox->Go(); // The close button is equivalent to pressing Escape. - if (closeButton != G_CLOSE_BUTTON_ID && pushedButton == G_CLOSE_BUTTON_ID) - { + if (closeButton != G_CLOSE_BUTTON_ID && pushedButton == G_CLOSE_BUTTON_ID) { pushedButton = closeButton; } // It's deleted by itself after the "Go()" method was executed. /* - if (messageBox != NULL) - { + if (messageBox != NULL) { delete messageBox; } */ - if (application != NULL) - { + if (application) { delete application; } diff --git a/SDL2-2.0.12/src/video/haiku/SDL_bmessagebox.h b/SDL2-2.30.5/src/video/haiku/SDL_bmessagebox.h similarity index 93% rename from SDL2-2.0.12/src/video/haiku/SDL_bmessagebox.h rename to SDL2-2.30.5/src/video/haiku/SDL_bmessagebox.h index 927400e..822d7c2 100644 --- a/SDL2-2.0.12/src/video/haiku/SDL_bmessagebox.h +++ b/SDL2-2.30.5/src/video/haiku/SDL_bmessagebox.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga Copyright (C) 2018-2019 EXL This software is provided 'as-is', without any express or implied @@ -25,7 +25,7 @@ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_HAIKU +#ifdef SDL_VIDEO_DRIVER_HAIKU #ifdef __cplusplus extern "C" { diff --git a/SDL2-2.0.12/src/video/haiku/SDL_bmodes.cc b/SDL2-2.30.5/src/video/haiku/SDL_bmodes.cc similarity index 74% rename from SDL2-2.0.12/src/video/haiku/SDL_bmodes.cc rename to SDL2-2.30.5/src/video/haiku/SDL_bmodes.cc index 5fa147f..6a162f6 100644 --- a/SDL2-2.0.12/src/video/haiku/SDL_bmodes.cc +++ b/SDL2-2.30.5/src/video/haiku/SDL_bmodes.cc @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,14 +20,14 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_HAIKU +#ifdef SDL_VIDEO_DRIVER_HAIKU #include #include #include "SDL_bmodes.h" #include "SDL_BWin.h" -#if SDL_VIDEO_OPENGL +#ifdef SDL_VIDEO_OPENGL #include "SDL_bopengl.h" #endif @@ -49,18 +49,18 @@ struct SDL_DisplayModeData { #endif static SDL_INLINE SDL_BWin *_ToBeWin(SDL_Window *window) { - return ((SDL_BWin*)(window->driverdata)); + return (SDL_BWin *)(window->driverdata); } -static SDL_INLINE SDL_BApp *_GetBeApp() { - return ((SDL_BApp*)be_app); +static SDL_INLINE SDL_BLooper *_GetBeLooper() { + return SDL_Looper; } static SDL_INLINE display_mode * _ExtractBMode(SDL_DisplayMode *mode) { #if WRAP_BMODE - return ((SDL_DisplayModeData*)mode->driverdata)->bmode; + return ((SDL_DisplayModeData *)mode->driverdata)->bmode; #else - return (display_mode*)(mode->driverdata); + return (display_mode *)(mode->driverdata); #endif } @@ -80,24 +80,24 @@ void _SpoutModeData(display_mode *bmode) { printf("\tw,h = (%i,%i)\n", bmode->virtual_width, bmode->virtual_height); printf("\th,v = (%i,%i)\n", bmode->h_display_start, bmode->v_display_start); - if(bmode->flags) { + if (bmode->flags) { printf("\tFlags:\n"); - if(bmode->flags & B_SCROLL) { + if (bmode->flags & B_SCROLL) { printf("\t\tB_SCROLL\n"); } - if(bmode->flags & B_8_BIT_DAC) { + if (bmode->flags & B_8_BIT_DAC) { printf("\t\tB_8_BIT_DAC\n"); } - if(bmode->flags & B_HARDWARE_CURSOR) { + if (bmode->flags & B_HARDWARE_CURSOR) { printf("\t\tB_HARDWARE_CURSOR\n"); } - if(bmode->flags & B_PARALLEL_ACCESS) { + if (bmode->flags & B_PARALLEL_ACCESS) { printf("\t\tB_PARALLEL_ACCESS\n"); } - if(bmode->flags & B_DPMS) { + if (bmode->flags & B_DPMS) { printf("\t\tB_DPMS\n"); } - if(bmode->flags & B_IO_FB_NA) { + if (bmode->flags & B_IO_FB_NA) { printf("\t\tB_IO_FB_NA\n"); } } @@ -109,21 +109,21 @@ void _SpoutModeData(display_mode *bmode) { printf("\t\tv - display: %i sync start: %i sync end: %i total: %i\n", bmode->timing.v_display, bmode->timing.v_sync_start, bmode->timing.v_sync_end, bmode->timing.v_total); - if(bmode->timing.flags) { + if (bmode->timing.flags) { printf("\t\tFlags:\n"); - if(bmode->timing.flags & B_BLANK_PEDESTAL) { + if (bmode->timing.flags & B_BLANK_PEDESTAL) { printf("\t\t\tB_BLANK_PEDESTAL\n"); } - if(bmode->timing.flags & B_TIMING_INTERLACED) { + if (bmode->timing.flags & B_TIMING_INTERLACED) { printf("\t\t\tB_TIMING_INTERLACED\n"); } - if(bmode->timing.flags & B_POSITIVE_HSYNC) { + if (bmode->timing.flags & B_POSITIVE_HSYNC) { printf("\t\t\tB_POSITIVE_HSYNC\n"); } - if(bmode->timing.flags & B_POSITIVE_VSYNC) { + if (bmode->timing.flags & B_POSITIVE_VSYNC) { printf("\t\t\tB_POSITIVE_VSYNC\n"); } - if(bmode->timing.flags & B_SYNC_ON_GREEN) { + if (bmode->timing.flags & B_SYNC_ON_GREEN) { printf("\t\t\tB_SYNC_ON_GREEN\n"); } } @@ -132,62 +132,36 @@ void _SpoutModeData(display_mode *bmode) { -int32 HAIKU_ColorSpaceToBitsPerPixel(uint32 colorspace) +int32 HAIKU_ColorSpaceToSDLPxFormat(uint32 colorspace) { - int bitsperpixel; - - bitsperpixel = 0; switch (colorspace) { - case B_CMAP8: - bitsperpixel = 8; - break; - case B_RGB15: - case B_RGBA15: - case B_RGB15_BIG: - case B_RGBA15_BIG: - bitsperpixel = 15; - break; - case B_RGB16: - case B_RGB16_BIG: - bitsperpixel = 16; - break; - case B_RGB32: - case B_RGBA32: - case B_RGB32_BIG: - case B_RGBA32_BIG: - bitsperpixel = 32; - break; - default: - break; - } - return(bitsperpixel); -} - -int32 HAIKU_BPPToSDLPxFormat(int32 bpp) { - /* Translation taken from SDL_windowsmodes.c */ - switch (bpp) { - case 32: - return SDL_PIXELFORMAT_RGB888; - break; - case 24: /* May not be supported by Haiku */ - return SDL_PIXELFORMAT_RGB24; - break; - case 16: - return SDL_PIXELFORMAT_RGB565; - break; - case 15: - return SDL_PIXELFORMAT_RGB555; - break; - case 8: + case B_CMAP8: return SDL_PIXELFORMAT_INDEX8; break; - case 4: /* May not be supported by Haiku */ - return SDL_PIXELFORMAT_INDEX4LSB; + case B_RGB15: + case B_RGBA15: + case B_RGB15_BIG: + case B_RGBA15_BIG: + return SDL_PIXELFORMAT_RGB555; + break; + case B_RGB16: + case B_RGB16_BIG: + return SDL_PIXELFORMAT_RGB565; + break; + case B_RGB24: + case B_RGB24_BIG: + return SDL_PIXELFORMAT_BGR24; + break; + case B_RGB32: + case B_RGBA32: + case B_RGB32_BIG: + case B_RGBA32_BIG: + return SDL_PIXELFORMAT_RGB888; break; } /* May never get here, but safer and needed to shut up compiler */ - SDL_SetError("Invalid bpp value"); + SDL_SetError("Invalid color space"); return 0; } @@ -210,8 +184,7 @@ static void _BDisplayModeToSdlDisplayMode(display_mode *bmode, #endif /* Set the format */ - int32 bpp = HAIKU_ColorSpaceToBitsPerPixel(bmode->space); - mode->format = HAIKU_BPPToSDLPxFormat(bpp); + mode->format = HAIKU_ColorSpaceToSDLPxFormat(bmode->space); } /* Later, there may be more than one monitor available */ @@ -228,7 +201,7 @@ static void _AddDisplay(BScreen *screen) { display.desktop_mode = *mode; display.current_mode = *mode; - SDL_AddVideoDisplay(&display); + SDL_AddVideoDisplay(&display, SDL_FALSE); } /* @@ -274,21 +247,21 @@ void HAIKU_GetDisplayModes(_THIS, SDL_VideoDisplay *display) { bscreen.GetModeList(&bmodes, &count); bscreen.GetMode(&this_bmode); - for(i = 0; i < count; ++i) { + for (i = 0; i < count; ++i) { // FIXME: Apparently there are errors with colorspace changes if (bmodes[i].space == this_bmode.space) { _BDisplayModeToSdlDisplayMode(&bmodes[i], &mode); SDL_AddDisplayMode(display, &mode); } } - free(bmodes); + free(bmodes); /* This should not be SDL_free() */ } -int HAIKU_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode){ +int HAIKU_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode) { /* Get the current screen */ BScreen bscreen; - if(!bscreen.IsValid()) { + if (!bscreen.IsValid()) { printf(__FILE__": %d - ERROR: BAD SCREEN\n", __LINE__); } @@ -300,8 +273,8 @@ int HAIKU_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode uint32 c = 0, i; display_mode *bmode_list; bscreen.GetModeList(&bmode_list, &c); - for(i = 0; i < c; ++i) { - if( bmode_list[i].space == bmode->space && + for (i = 0; i < c; ++i) { + if ( bmode_list[i].space == bmode->space && bmode_list[i].virtual_width == bmode->virtual_width && bmode_list[i].virtual_height == bmode->virtual_height ) { bmode = &bmode_list[i]; @@ -309,13 +282,13 @@ int HAIKU_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode } } - if(bscreen.SetMode(bmode) != B_OK) { + if (bscreen.SetMode(bmode) != B_OK) { return SDL_SetError("Bad video mode"); } - free(bmode_list); + free(bmode_list); /* This should not be SDL_free() */ -#if SDL_VIDEO_OPENGL +#ifdef SDL_VIDEO_OPENGL /* FIXME: Is there some way to reboot the OpenGL context? This doesn't help */ // HAIKU_GL_RebootContexts(_this); diff --git a/SDL2-2.0.12/src/video/haiku/SDL_bmodes.h b/SDL2-2.30.5/src/video/haiku/SDL_bmodes.h similarity index 85% rename from SDL2-2.0.12/src/video/haiku/SDL_bmodes.h rename to SDL2-2.30.5/src/video/haiku/SDL_bmodes.h index e4e60d0..e0d6f04 100644 --- a/SDL2-2.0.12/src/video/haiku/SDL_bmodes.h +++ b/SDL2-2.30.5/src/video/haiku/SDL_bmodes.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -28,16 +28,15 @@ extern "C" { #include "../SDL_sysvideo.h" -extern int32 HAIKU_ColorSpaceToBitsPerPixel(uint32 colorspace); -extern int32 HAIKU_BPPToSDLPxFormat(int32 bpp); +extern int32 HAIKU_ColorSpaceToSDLPxFormat(uint32 colorspace); extern int HAIKU_InitModes(_THIS); extern int HAIKU_QuitModes(_THIS); extern int HAIKU_GetDisplayBounds(_THIS, SDL_VideoDisplay *display, - SDL_Rect *rect); + SDL_Rect *rect); extern void HAIKU_GetDisplayModes(_THIS, SDL_VideoDisplay *display); extern int HAIKU_SetDisplayMode(_THIS, SDL_VideoDisplay *display, - SDL_DisplayMode *mode); + SDL_DisplayMode *mode); #ifdef __cplusplus } diff --git a/SDL2-2.0.12/src/video/haiku/SDL_bopengl.cc b/SDL2-2.30.5/src/video/haiku/SDL_bopengl.cc similarity index 74% rename from SDL2-2.0.12/src/video/haiku/SDL_bopengl.cc rename to SDL2-2.30.5/src/video/haiku/SDL_bopengl.cc index b193979..d34d592 100644 --- a/SDL2-2.0.12/src/video/haiku/SDL_bopengl.cc +++ b/SDL2-2.30.5/src/video/haiku/SDL_bopengl.cc @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_HAIKU && SDL_VIDEO_OPENGL +#if defined(SDL_VIDEO_DRIVER_HAIKU) && defined(SDL_VIDEO_OPENGL) #include "SDL_bopengl.h" @@ -36,11 +36,11 @@ extern "C" { static SDL_INLINE SDL_BWin *_ToBeWin(SDL_Window *window) { - return ((SDL_BWin*)(window->driverdata)); + return (SDL_BWin *)(window->driverdata); } -static SDL_INLINE SDL_BApp *_GetBeApp() { - return ((SDL_BApp*)be_app); +static SDL_INLINE SDL_BLooper *_GetBeLooper() { + return SDL_Looper; } /* Passing a NULL path means load pointers from the application */ @@ -51,7 +51,7 @@ int HAIKU_GL_LoadLibrary(_THIS, const char *path) int32 cookie = 0; while (get_next_image_info(0, &cookie, &info) == B_OK) { void *location = NULL; - if( get_image_symbol(info.id, "glBegin", B_SYMBOL_TYPE_ANY, + if ( get_image_symbol(info.id, "glBegin", B_SYMBOL_TYPE_ANY, &location) == B_OK) { _this->gl_config.dll_handle = (void *) (addr_t) info.id; @@ -65,7 +65,7 @@ int HAIKU_GL_LoadLibrary(_THIS, const char *path) void *HAIKU_GL_GetProcAddress(_THIS, const char *proc) { - if (_this->gl_config.dll_handle != NULL) { + if (_this->gl_config.dll_handle) { void *location = NULL; status_t err; if ((err = @@ -84,16 +84,20 @@ void *HAIKU_GL_GetProcAddress(_THIS, const char *proc) } - - int HAIKU_GL_SwapWindow(_THIS, SDL_Window * window) { _ToBeWin(window)->SwapBuffers(); return 0; } int HAIKU_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) { - SDL_BWin* win = (SDL_BWin*)context; - _GetBeApp()->SetCurrentContext(win ? win->GetGLView() : NULL); + BGLView* glView = (BGLView*)context; + // printf("HAIKU_GL_MakeCurrent(%llx), win = %llx, thread = %d\n", (uint64)context, (uint64)window, find_thread(NULL)); + if (glView) { + if ((glView->Window() == NULL) || (!window) || (_ToBeWin(window)->GetGLView() != glView)) { + return SDL_SetError("MakeCurrent failed"); + } + } + _GetBeLooper()->SetCurrentContext(glView); return 0; } @@ -102,6 +106,11 @@ SDL_GLContext HAIKU_GL_CreateContext(_THIS, SDL_Window * window) { /* FIXME: Not sure what flags should be included here; may want to have most of them */ SDL_BWin *bwin = _ToBeWin(window); + // printf("HAIKU_GL_CreateContext, win = %llx, thread = %d\n", (uint64)window, find_thread(NULL)); + if (bwin->GetGLView() != NULL) { + SDL_SetError("Context already creaded"); + return NULL; + } Uint32 gl_flags = BGL_RGB; if (_this->gl_config.alpha_size) { gl_flags |= BGL_ALPHA; @@ -123,13 +132,25 @@ SDL_GLContext HAIKU_GL_CreateContext(_THIS, SDL_Window * window) { _this->gl_config.accum_alpha_size) { gl_flags |= BGL_ACCUM; } +#if __GNUC__ > 3 + if (_this->gl_config.share_with_current_context) { + gl_flags |= BGL_SHARE_CONTEXT; + } +#endif bwin->CreateGLView(gl_flags); - return (SDL_GLContext)(bwin); + _GetBeLooper()->SetCurrentContext(bwin->GetGLView()); + return (SDL_GLContext)(bwin->GetGLView()); } void HAIKU_GL_DeleteContext(_THIS, SDL_GLContext context) { - /* Currently, automatically unlocks the view */ - ((SDL_BWin*)context)->RemoveGLView(); + // printf("HAIKU_GL_DeleteContext(%llx), thread = %d\n", (uint64)context, find_thread(NULL)); + BGLView* glView = (BGLView*)context; + SDL_BWin *bwin = (SDL_BWin*)glView->Window(); + if (!bwin) { + delete glView; + } else { + bwin->RemoveGLView(); + } } @@ -154,9 +175,9 @@ void HAIKU_GL_UnloadLibrary(_THIS) { currently in use. */ void HAIKU_GL_RebootContexts(_THIS) { SDL_Window *window = _this->windows; - while(window) { + while (window) { SDL_BWin *bwin = _ToBeWin(window); - if(bwin->GetGLView()) { + if (bwin->GetGLView()) { bwin->LockLooper(); bwin->RemoveGLView(); bwin->CreateGLView(bwin->GetGLType()); diff --git a/SDL2-2.0.12/src/video/haiku/SDL_bopengl.h b/SDL2-2.30.5/src/video/haiku/SDL_bopengl.h similarity index 61% rename from SDL2-2.0.12/src/video/haiku/SDL_bopengl.h rename to SDL2-2.30.5/src/video/haiku/SDL_bopengl.h index 947331d..0905b7c 100644 --- a/SDL2-2.0.12/src/video/haiku/SDL_bopengl.h +++ b/SDL2-2.30.5/src/video/haiku/SDL_bopengl.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -22,7 +22,7 @@ #ifndef SDL_BOPENGL_H #define SDL_BOPENGL_H -#if SDL_VIDEO_DRIVER_HAIKU && SDL_VIDEO_OPENGL +#if defined(SDL_VIDEO_DRIVER_HAIKU) && defined(SDL_VIDEO_OPENGL) #ifdef __cplusplus extern "C" { @@ -30,16 +30,15 @@ extern "C" { #include "../SDL_sysvideo.h" - -extern int HAIKU_GL_LoadLibrary(_THIS, const char *path); /* FIXME */ -extern void *HAIKU_GL_GetProcAddress(_THIS, const char *proc); /* FIXME */ -extern void HAIKU_GL_UnloadLibrary(_THIS); /* TODO */ -extern int HAIKU_GL_MakeCurrent(_THIS, SDL_Window * window, - SDL_GLContext context); -extern int HAIKU_GL_SetSwapInterval(_THIS, int interval); /* TODO */ -extern int HAIKU_GL_GetSwapInterval(_THIS); /* TODO */ -extern int HAIKU_GL_SwapWindow(_THIS, SDL_Window * window); -extern SDL_GLContext HAIKU_GL_CreateContext(_THIS, SDL_Window * window); +extern int HAIKU_GL_LoadLibrary(_THIS, const char *path); /* FIXME */ +extern void *HAIKU_GL_GetProcAddress(_THIS, const char *proc); /* FIXME */ +extern void HAIKU_GL_UnloadLibrary(_THIS); /* TODO */ +extern int HAIKU_GL_MakeCurrent(_THIS, SDL_Window *window, + SDL_GLContext context); +extern int HAIKU_GL_SetSwapInterval(_THIS, int interval); /* TODO */ +extern int HAIKU_GL_GetSwapInterval(_THIS); /* TODO */ +extern int HAIKU_GL_SwapWindow(_THIS, SDL_Window *window); +extern SDL_GLContext HAIKU_GL_CreateContext(_THIS, SDL_Window *window); extern void HAIKU_GL_DeleteContext(_THIS, SDL_GLContext context); extern void HAIKU_GL_RebootContexts(_THIS); diff --git a/SDL2-2.0.12/src/video/haiku/SDL_bvideo.cc b/SDL2-2.30.5/src/video/haiku/SDL_bvideo.cc similarity index 56% rename from SDL2-2.0.12/src/video/haiku/SDL_bvideo.cc rename to SDL2-2.30.5/src/video/haiku/SDL_bvideo.cc index 9071df5..aac091a 100644 --- a/SDL2-2.0.12/src/video/haiku/SDL_bvideo.cc +++ b/SDL2-2.30.5/src/video/haiku/SDL_bvideo.cc @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -18,11 +18,14 @@ misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ + #include "../../SDL_internal.h" #include "../../main/haiku/SDL_BApp.h" -#if SDL_VIDEO_DRIVER_HAIKU +#ifdef SDL_VIDEO_DRIVER_HAIKU +#include "SDL_BWin.h" +#include #ifdef __cplusplus extern "C" { @@ -36,6 +39,11 @@ extern "C" { #include "SDL_bmodes.h" #include "SDL_bframebuffer.h" #include "SDL_bevents.h" +#include "SDL_bmessagebox.h" + +static SDL_INLINE SDL_BWin *_ToBeWin(SDL_Window *window) { + return (SDL_BWin *)(window->driverdata); +} /* FIXME: Undefined functions */ // #define HAIKU_PumpEvents NULL @@ -47,8 +55,7 @@ extern "C" { /* End undefined functions */ -static SDL_VideoDevice * -HAIKU_CreateDevice(int devindex) +static SDL_VideoDevice * HAIKU_CreateDevice(void) { SDL_VideoDevice *device; /*SDL_VideoData *data;*/ @@ -86,7 +93,8 @@ HAIKU_CreateDevice(int devindex) device->SetWindowFullscreen = HAIKU_SetWindowFullscreen; device->SetWindowGammaRamp = HAIKU_SetWindowGammaRamp; device->GetWindowGammaRamp = HAIKU_GetWindowGammaRamp; - device->SetWindowGrab = HAIKU_SetWindowGrab; + device->SetWindowMouseGrab = HAIKU_SetWindowMouseGrab; + device->SetWindowMinimumSize = HAIKU_SetWindowMinimumSize; device->DestroyWindow = HAIKU_DestroyWindow; device->GetWindowWMInfo = HAIKU_GetWindowWMInfo; device->CreateWindowFramebuffer = HAIKU_CreateWindowFramebuffer; @@ -97,7 +105,7 @@ HAIKU_CreateDevice(int devindex) device->shape_driver.SetWindowShape = NULL; device->shape_driver.ResizeWindowShape = NULL; -#if SDL_VIDEO_OPENGL +#ifdef SDL_VIDEO_OPENGL device->GL_LoadLibrary = HAIKU_GL_LoadLibrary; device->GL_GetProcAddress = HAIKU_GL_GetProcAddress; device->GL_UnloadLibrary = HAIKU_GL_UnloadLibrary; @@ -124,7 +132,8 @@ HAIKU_CreateDevice(int devindex) VideoBootStrap HAIKU_bootstrap = { "haiku", "Haiku graphics", - HAIKU_Available, HAIKU_CreateDevice + HAIKU_CreateDevice, + HAIKU_ShowMessageBox }; void HAIKU_DeleteDevice(SDL_VideoDevice * device) @@ -133,31 +142,130 @@ void HAIKU_DeleteDevice(SDL_VideoDevice * device) SDL_free(device); } -static int HAIKU_ShowCursor(SDL_Cursor *cur) +static SDL_Cursor * HAIKU_CreateSystemCursor(SDL_SystemCursor id) +{ + SDL_Cursor *cursor; + BCursorID cursorId = B_CURSOR_ID_SYSTEM_DEFAULT; + + switch(id) + { + default: + SDL_assert(0); + return NULL; + case SDL_SYSTEM_CURSOR_ARROW: cursorId = B_CURSOR_ID_SYSTEM_DEFAULT; break; + case SDL_SYSTEM_CURSOR_IBEAM: cursorId = B_CURSOR_ID_I_BEAM; break; + case SDL_SYSTEM_CURSOR_WAIT: cursorId = B_CURSOR_ID_PROGRESS; break; + case SDL_SYSTEM_CURSOR_CROSSHAIR: cursorId = B_CURSOR_ID_CROSS_HAIR; break; + case SDL_SYSTEM_CURSOR_WAITARROW: cursorId = B_CURSOR_ID_PROGRESS; break; + case SDL_SYSTEM_CURSOR_SIZENWSE: cursorId = B_CURSOR_ID_RESIZE_NORTH_WEST_SOUTH_EAST; break; + case SDL_SYSTEM_CURSOR_SIZENESW: cursorId = B_CURSOR_ID_RESIZE_NORTH_EAST_SOUTH_WEST; break; + case SDL_SYSTEM_CURSOR_SIZEWE: cursorId = B_CURSOR_ID_RESIZE_EAST_WEST; break; + case SDL_SYSTEM_CURSOR_SIZENS: cursorId = B_CURSOR_ID_RESIZE_NORTH_SOUTH; break; + case SDL_SYSTEM_CURSOR_SIZEALL: cursorId = B_CURSOR_ID_MOVE; break; + case SDL_SYSTEM_CURSOR_NO: cursorId = B_CURSOR_ID_NOT_ALLOWED; break; + case SDL_SYSTEM_CURSOR_HAND: cursorId = B_CURSOR_ID_FOLLOW_LINK; break; + } + + cursor = (SDL_Cursor *) SDL_calloc(1, sizeof(*cursor)); + if (cursor) { + cursor->driverdata = (void *)new BCursor(cursorId); + } else { + SDL_OutOfMemory(); + } + + return cursor; +} + +static SDL_Cursor * HAIKU_CreateDefaultCursor() +{ + return HAIKU_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); +} + +static void HAIKU_FreeCursor(SDL_Cursor * cursor) +{ + if (cursor->driverdata) { + delete (BCursor*) cursor->driverdata; + } + SDL_free(cursor); +} + +static SDL_Cursor * HAIKU_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y) +{ + SDL_Cursor *cursor; + SDL_Surface *converted; + + converted = SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_ARGB8888, 0); + if (!converted) { + return NULL; + } + + BBitmap *cursorBitmap = new BBitmap(BRect(0, 0, surface->w - 1, surface->h - 1), B_RGBA32); + cursorBitmap->SetBits(converted->pixels, converted->h * converted->pitch, 0, B_RGBA32); + SDL_FreeSurface(converted); + + cursor = (SDL_Cursor *) SDL_calloc(1, sizeof(*cursor)); + if (cursor) { + cursor->driverdata = (void *)new BCursor(cursorBitmap, BPoint(hot_x, hot_y)); + } else { + return NULL; + } + + return cursor; +} + +static int HAIKU_ShowCursor(SDL_Cursor *cursor) { SDL_Mouse *mouse = SDL_GetMouse(); - int show; - if (!mouse) + + if (!mouse) { return 0; - show = (cur || !mouse->focus); - if (show) { - if (be_app->IsCursorHidden()) - be_app->ShowCursor(); - } else { - if (!be_app->IsCursorHidden()) - be_app->HideCursor(); } + + if (cursor) { + BCursor *hCursor = (BCursor*)cursor->driverdata; + be_app->SetCursor(hCursor); + } else { + BCursor *hCursor = new BCursor(B_CURSOR_ID_NO_CURSOR); + be_app->SetCursor(hCursor); + delete hCursor; + } + return 0; } +static int HAIKU_SetRelativeMouseMode(SDL_bool enabled) +{ + SDL_Window *window = SDL_GetMouseFocus(); + if (!window) { + return 0; + } + + SDL_BWin *bewin = _ToBeWin(window); + BGLView *_SDL_GLView = bewin->GetGLView(); + + bewin->Lock(); + if (enabled) + _SDL_GLView->SetEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY); + else + _SDL_GLView->SetEventMask(0, 0); + bewin->Unlock(); + + return 0; +} + static void HAIKU_MouseInit(_THIS) { SDL_Mouse *mouse = SDL_GetMouse(); - if (!mouse) + if (!mouse) { return; + } + mouse->CreateCursor = HAIKU_CreateCursor; + mouse->CreateSystemCursor = HAIKU_CreateSystemCursor; mouse->ShowCursor = HAIKU_ShowCursor; - mouse->cur_cursor = (SDL_Cursor*)0x1; - mouse->def_cursor = (SDL_Cursor*)0x2; + mouse->FreeCursor = HAIKU_FreeCursor; + mouse->SetRelativeMouseMode = HAIKU_SetRelativeMouseMode; + + SDL_SetDefaultCursor(HAIKU_CreateDefaultCursor()); } int HAIKU_VideoInit(_THIS) @@ -175,19 +283,14 @@ int HAIKU_VideoInit(_THIS) HAIKU_MouseInit(_this); -#if SDL_VIDEO_OPENGL +#ifdef SDL_VIDEO_OPENGL /* testgl application doesn't load library, just tries to load symbols */ /* is it correct? if so we have to load library here */ HAIKU_GL_LoadLibrary(_this, NULL); #endif /* We're done! */ - return (0); -} - -int HAIKU_Available(void) -{ - return (1); + return 0; } void HAIKU_VideoQuit(_THIS) @@ -198,6 +301,15 @@ void HAIKU_VideoQuit(_THIS) SDL_QuitBeApp(); } +// just sticking this function in here so it's in a C++ source file. +extern "C" { int HAIKU_OpenURL(const char *url); } +int HAIKU_OpenURL(const char *url) +{ + BUrl burl(url); + const status_t rc = burl.OpenWithPreferredApplication(false); + return (rc == B_NO_ERROR) ? 0 : SDL_SetError("URL open failed (err=%d)", (int)rc); +} + #ifdef __cplusplus } #endif diff --git a/SDL2-2.0.12/src/video/haiku/SDL_bvideo.h b/SDL2-2.30.5/src/video/haiku/SDL_bvideo.h similarity index 92% rename from SDL2-2.0.12/src/video/haiku/SDL_bvideo.h rename to SDL2-2.30.5/src/video/haiku/SDL_bvideo.h index 064a4b8..6c42048 100644 --- a/SDL2-2.0.12/src/video/haiku/SDL_bvideo.h +++ b/SDL2-2.30.5/src/video/haiku/SDL_bvideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -29,11 +29,9 @@ extern "C" { #include "../../main/haiku/SDL_BeApp.h" #include "../SDL_sysvideo.h" - extern void HAIKU_VideoQuit(_THIS); extern int HAIKU_VideoInit(_THIS); extern void HAIKU_DeleteDevice(_THIS); -extern int HAIKU_Available(void); #ifdef __cplusplus } diff --git a/SDL2-2.0.12/src/video/haiku/SDL_bwindow.cc b/SDL2-2.30.5/src/video/haiku/SDL_bwindow.cc similarity index 85% rename from SDL2-2.0.12/src/video/haiku/SDL_bwindow.cc rename to SDL2-2.30.5/src/video/haiku/SDL_bwindow.cc index addf206..38863ab 100644 --- a/SDL2-2.0.12/src/video/haiku/SDL_bwindow.cc +++ b/SDL2-2.30.5/src/video/haiku/SDL_bwindow.cc @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_HAIKU +#ifdef SDL_VIDEO_DRIVER_HAIKU #include "../SDL_sysvideo.h" #include "SDL_BWin.h" @@ -34,11 +34,11 @@ extern "C" { #endif static SDL_INLINE SDL_BWin *_ToBeWin(SDL_Window *window) { - return ((SDL_BWin*)(window->driverdata)); + return (SDL_BWin *)(window->driverdata); } -static SDL_INLINE SDL_BApp *_GetBeApp() { - return ((SDL_BApp*)be_app); +static SDL_INLINE SDL_BLooper *_GetBeLooper() { + return SDL_Looper; } static int _InitWindow(_THIS, SDL_Window *window) { @@ -52,26 +52,27 @@ static int _InitWindow(_THIS, SDL_Window *window) { window->y + window->h - 1 ); - if(window->flags & SDL_WINDOW_FULLSCREEN) { + if (window->flags & SDL_WINDOW_FULLSCREEN) { /* TODO: Add support for this flag */ printf(__FILE__": %d!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n",__LINE__); } - if(window->flags & SDL_WINDOW_OPENGL) { + if (window->flags & SDL_WINDOW_OPENGL) { /* TODO: Add support for this flag */ } - if(!(window->flags & SDL_WINDOW_RESIZABLE)) { + if (!(window->flags & SDL_WINDOW_RESIZABLE)) { flags |= B_NOT_RESIZABLE | B_NOT_ZOOMABLE; } - if(window->flags & SDL_WINDOW_BORDERLESS) { + if (window->flags & SDL_WINDOW_BORDERLESS) { look = B_NO_BORDER_WINDOW_LOOK; } SDL_BWin *bwin = new(std::nothrow) SDL_BWin(bounds, look, flags); - if(bwin == NULL) + if (!bwin) { return -1; + } window->driverdata = bwin; - int32 winID = _GetBeApp()->GetID(window); + int32 winID = _GetBeLooper()->GetID(window); bwin->SetID(winID); return 0; @@ -90,8 +91,9 @@ int HAIKU_CreateWindow(_THIS, SDL_Window *window) { int HAIKU_CreateWindowFrom(_THIS, SDL_Window * window, const void *data) { SDL_BWin *otherBWin = (SDL_BWin*)data; - if(!otherBWin->LockLooper()) + if (!otherBWin->LockLooper()) { return -1; + } /* Create the new window and initialize its members */ window->x = (int)otherBWin->Frame().left; @@ -100,7 +102,7 @@ int HAIKU_CreateWindowFrom(_THIS, SDL_Window * window, const void *data) { window->h = (int)otherBWin->Frame().Height(); /* Set SDL flags */ - if(!(otherBWin->Flags() & B_NOT_RESIZABLE)) { + if (!(otherBWin->Flags() & B_NOT_RESIZABLE)) { window->flags |= SDL_WINDOW_RESIZABLE; } @@ -205,13 +207,20 @@ int HAIKU_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp) { } -void HAIKU_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed) { +void HAIKU_SetWindowMinimumSize(_THIS, SDL_Window * window) { + BMessage msg(BWIN_MINIMUM_SIZE_WINDOW); + msg.AddInt32("window-w", window->w -1); + msg.AddInt32("window-h", window->h -1); + _ToBeWin(window)->PostMessage(&msg); +} + +void HAIKU_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed) { /* TODO: Implement this! */ } void HAIKU_DestroyWindow(_THIS, SDL_Window * window) { _ToBeWin(window)->LockLooper(); /* This MUST be locked */ - _GetBeApp()->ClearID(_ToBeWin(window)); + _GetBeLooper()->ClearID(_ToBeWin(window)); _ToBeWin(window)->Quit(); window->driverdata = NULL; } @@ -219,13 +228,12 @@ void HAIKU_DestroyWindow(_THIS, SDL_Window * window) { SDL_bool HAIKU_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info) { /* FIXME: What is the point of this? What information should be included? */ - if (info->version.major == SDL_MAJOR_VERSION && - info->version.minor == SDL_MINOR_VERSION) { + if (info->version.major == SDL_MAJOR_VERSION) { info->subsystem = SDL_SYSWM_HAIKU; return SDL_TRUE; } else { - SDL_SetError("Application not compiled with SDL %d.%d", - SDL_MAJOR_VERSION, SDL_MINOR_VERSION); + SDL_SetError("Application not compiled with SDL %d", + SDL_MAJOR_VERSION); return SDL_FALSE; } } diff --git a/SDL2-2.0.12/src/video/haiku/SDL_bwindow.h b/SDL2-2.30.5/src/video/haiku/SDL_bwindow.h similarity index 91% rename from SDL2-2.0.12/src/video/haiku/SDL_bwindow.h rename to SDL2-2.30.5/src/video/haiku/SDL_bwindow.h index b6b8a8e..cf0bdfd 100644 --- a/SDL2-2.0.12/src/video/haiku/SDL_bwindow.h +++ b/SDL2-2.30.5/src/video/haiku/SDL_bwindow.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -22,16 +22,15 @@ #ifndef SDL_BWINDOW_H #define SDL_BWINDOW_H - #include "../SDL_sysvideo.h" - extern int HAIKU_CreateWindow(_THIS, SDL_Window *window); extern int HAIKU_CreateWindowFrom(_THIS, SDL_Window * window, const void *data); extern void HAIKU_SetWindowTitle(_THIS, SDL_Window * window); extern void HAIKU_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon); extern void HAIKU_SetWindowPosition(_THIS, SDL_Window * window); extern void HAIKU_SetWindowSize(_THIS, SDL_Window * window); +extern void HAIKU_SetWindowMinimumSize(_THIS, SDL_Window * window); extern void HAIKU_ShowWindow(_THIS, SDL_Window * window); extern void HAIKU_HideWindow(_THIS, SDL_Window * window); extern void HAIKU_RaiseWindow(_THIS, SDL_Window * window); @@ -43,13 +42,11 @@ extern void HAIKU_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resiza extern void HAIKU_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen); extern int HAIKU_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp); extern int HAIKU_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp); -extern void HAIKU_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed); +extern void HAIKU_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed); extern void HAIKU_DestroyWindow(_THIS, SDL_Window * window); extern SDL_bool HAIKU_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info); - - #endif /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/khronos/EGL/egl.h b/SDL2-2.30.5/src/video/khronos/EGL/egl.h similarity index 72% rename from SDL2-2.0.12/src/video/khronos/EGL/egl.h rename to SDL2-2.30.5/src/video/khronos/EGL/egl.h index 93a2187..c58f552 100644 --- a/SDL2-2.0.12/src/video/khronos/EGL/egl.h +++ b/SDL2-2.30.5/src/video/khronos/EGL/egl.h @@ -6,39 +6,24 @@ extern "C" { #endif /* -** Copyright (c) 2013-2017 The Khronos Group Inc. +** Copyright 2013-2020 The Khronos Group Inc. +** SPDX-License-Identifier: Apache-2.0 ** -** Permission is hereby granted, free of charge, to any person obtaining a -** copy of this software and/or associated documentation files (the -** "Materials"), to deal in the Materials without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Materials, and to -** permit persons to whom the Materials are furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be included -** in all copies or substantial portions of the Materials. -** -** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. -*/ -/* -** This header is generated from the Khronos OpenGL / OpenGL ES XML -** API Registry. The current version of the Registry, generator scripts +** This header is generated from the Khronos EGL XML API Registry. +** The current version of the Registry, generator scripts ** used to make the header, and the header can be found at ** http://www.khronos.org/registry/egl ** -** Khronos $Git commit SHA1: a732b061e7 $ on $Git commit date: 2017-06-17 23:27:53 +0100 $ +** Khronos $Git commit SHA1: f4cc936b88 $ on $Git commit date: 2023-12-16 01:21:49 -0500 $ */ #include -/* Generated on date 20170627 */ +#ifndef EGL_EGL_PROTOTYPES +#define EGL_EGL_PROTOTYPES 1 +#endif + +/* Generated on date 20231215 */ /* Generated C header for: * API: egl @@ -118,6 +103,31 @@ typedef void (*__eglMustCastToProperFunctionPointerType)(void); #define EGL_VERSION 0x3054 #define EGL_WIDTH 0x3057 #define EGL_WINDOW_BIT 0x0004 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCHOOSECONFIGPROC) (EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOPYBUFFERSPROC) (EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target); +typedef EGLContext (EGLAPIENTRYP PFNEGLCREATECONTEXTPROC) (EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list); +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPBUFFERSURFACEPROC) (EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list); +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPIXMAPSURFACEPROC) (EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list); +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEWINDOWSURFACEPROC) (EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYCONTEXTPROC) (EGLDisplay dpy, EGLContext ctx); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSURFACEPROC) (EGLDisplay dpy, EGLSurface surface); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETCONFIGATTRIBPROC) (EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETCONFIGSPROC) (EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config); +typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETCURRENTDISPLAYPROC) (void); +typedef EGLSurface (EGLAPIENTRYP PFNEGLGETCURRENTSURFACEPROC) (EGLint readdraw); +typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETDISPLAYPROC) (EGLNativeDisplayType display_id); +typedef EGLint (EGLAPIENTRYP PFNEGLGETERRORPROC) (void); +typedef __eglMustCastToProperFunctionPointerType (EGLAPIENTRYP PFNEGLGETPROCADDRESSPROC) (const char *procname); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLINITIALIZEPROC) (EGLDisplay dpy, EGLint *major, EGLint *minor); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLMAKECURRENTPROC) (EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYCONTEXTPROC) (EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value); +typedef const char *(EGLAPIENTRYP PFNEGLQUERYSTRINGPROC) (EGLDisplay dpy, EGLint name); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSPROC) (EGLDisplay dpy, EGLSurface surface); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLTERMINATEPROC) (EGLDisplay dpy); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLWAITGLPROC) (void); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLWAITNATIVEPROC) (EGLint engine); +#if EGL_EGL_PROTOTYPES EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig (EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config); EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers (EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target); EGLAPI EGLContext EGLAPIENTRY eglCreateContext (EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list); @@ -142,6 +152,7 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers (EGLDisplay dpy, EGLSurface surface EGLAPI EGLBoolean EGLAPIENTRY eglTerminate (EGLDisplay dpy); EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL (void); EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative (EGLint engine); +#endif #endif /* EGL_VERSION_1_0 */ #ifndef EGL_VERSION_1_1 @@ -160,10 +171,16 @@ EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative (EGLint engine); #define EGL_TEXTURE_RGB 0x305D #define EGL_TEXTURE_RGBA 0x305E #define EGL_TEXTURE_TARGET 0x3081 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLBINDTEXIMAGEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint buffer); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLRELEASETEXIMAGEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint buffer); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSURFACEATTRIBPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPINTERVALPROC) (EGLDisplay dpy, EGLint interval); +#if EGL_EGL_PROTOTYPES EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage (EGLDisplay dpy, EGLSurface surface, EGLint buffer); EGLAPI EGLBoolean EGLAPIENTRY eglReleaseTexImage (EGLDisplay dpy, EGLSurface surface, EGLint buffer); EGLAPI EGLBoolean EGLAPIENTRY eglSurfaceAttrib (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value); EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval (EGLDisplay dpy, EGLint interval); +#endif #endif /* EGL_VERSION_1_1 */ #ifndef EGL_VERSION_1_2 @@ -199,11 +216,18 @@ typedef void *EGLClientBuffer; #define EGL_SWAP_BEHAVIOR 0x3093 #define EGL_UNKNOWN EGL_CAST(EGLint,-1) #define EGL_VERTICAL_RESOLUTION 0x3091 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLBINDAPIPROC) (EGLenum api); +typedef EGLenum (EGLAPIENTRYP PFNEGLQUERYAPIPROC) (void); +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPBUFFERFROMCLIENTBUFFERPROC) (EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLRELEASETHREADPROC) (void); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLWAITCLIENTPROC) (void); +#if EGL_EGL_PROTOTYPES EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI (EGLenum api); EGLAPI EGLenum EGLAPIENTRY eglQueryAPI (void); EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer (EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list); EGLAPI EGLBoolean EGLAPIENTRY eglReleaseThread (void); EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient (void); +#endif #endif /* EGL_VERSION_1_2 */ #ifndef EGL_VERSION_1_3 @@ -232,7 +256,10 @@ EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient (void); #define EGL_OPENGL_API 0x30A2 #define EGL_OPENGL_BIT 0x0008 #define EGL_SWAP_BEHAVIOR_PRESERVED_BIT 0x0400 +typedef EGLContext (EGLAPIENTRYP PFNEGLGETCURRENTCONTEXTPROC) (void); +#if EGL_EGL_PROTOTYPES EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext (void); +#endif #endif /* EGL_VERSION_1_4 */ #ifndef EGL_VERSION_1_5 @@ -284,6 +311,17 @@ typedef void *EGLImage; #define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x30B8 #define EGL_IMAGE_PRESERVED 0x30D2 #define EGL_NO_IMAGE EGL_CAST(EGLImage,0) +typedef EGLSync (EGLAPIENTRYP PFNEGLCREATESYNCPROC) (EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCPROC) (EGLDisplay dpy, EGLSync sync); +typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCPROC) (EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBPROC) (EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value); +typedef EGLImage (EGLAPIENTRYP PFNEGLCREATEIMAGEPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEPROC) (EGLDisplay dpy, EGLImage image); +typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYPROC) (EGLenum platform, void *native_display, const EGLAttrib *attrib_list); +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMWINDOWSURFACEPROC) (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list); +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC) (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLWAITSYNCPROC) (EGLDisplay dpy, EGLSync sync, EGLint flags); +#if EGL_EGL_PROTOTYPES EGLAPI EGLSync EGLAPIENTRY eglCreateSync (EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list); EGLAPI EGLBoolean EGLAPIENTRY eglDestroySync (EGLDisplay dpy, EGLSync sync); EGLAPI EGLint EGLAPIENTRY eglClientWaitSync (EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout); @@ -294,6 +332,7 @@ EGLAPI EGLDisplay EGLAPIENTRY eglGetPlatformDisplay (EGLenum platform, void *nat EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformWindowSurface (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list); EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurface (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list); EGLAPI EGLBoolean EGLAPIENTRY eglWaitSync (EGLDisplay dpy, EGLSync sync, EGLint flags); +#endif #endif /* EGL_VERSION_1_5 */ #ifdef __cplusplus diff --git a/SDL2-2.0.12/src/video/khronos/EGL/eglext.h b/SDL2-2.30.5/src/video/khronos/EGL/eglext.h similarity index 79% rename from SDL2-2.0.12/src/video/khronos/EGL/eglext.h rename to SDL2-2.30.5/src/video/khronos/EGL/eglext.h index d2def03..9932ebe 100644 --- a/SDL2-2.0.12/src/video/khronos/EGL/eglext.h +++ b/SDL2-2.30.5/src/video/khronos/EGL/eglext.h @@ -6,39 +6,20 @@ extern "C" { #endif /* -** Copyright (c) 2013-2017 The Khronos Group Inc. +** Copyright 2013-2020 The Khronos Group Inc. +** SPDX-License-Identifier: Apache-2.0 ** -** Permission is hereby granted, free of charge, to any person obtaining a -** copy of this software and/or associated documentation files (the -** "Materials"), to deal in the Materials without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Materials, and to -** permit persons to whom the Materials are furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be included -** in all copies or substantial portions of the Materials. -** -** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. -*/ -/* -** This header is generated from the Khronos OpenGL / OpenGL ES XML -** API Registry. The current version of the Registry, generator scripts +** This header is generated from the Khronos EGL XML API Registry. +** The current version of the Registry, generator scripts ** used to make the header, and the header can be found at ** http://www.khronos.org/registry/egl ** -** Khronos $Git commit SHA1: a732b061e7 $ on $Git commit date: 2017-06-17 23:27:53 +0100 $ +** Khronos $Git commit SHA1: f4cc936b88 $ on $Git commit date: 2023-12-16 01:21:49 -0500 $ */ #include -#define EGL_EGLEXT_VERSION 20170627 +#define EGL_EGLEXT_VERSION 20231215 /* Generated C header for: * API: egl @@ -443,9 +424,9 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreateStreamProducerSurfaceKHR (EGLDisplay dpy, #ifndef EGL_KHR_swap_buffers_with_damage #define EGL_KHR_swap_buffers_with_damage 1 -typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC) (EGLDisplay dpy, EGLSurface surface, const EGLint *rects, EGLint n_rects); #ifdef EGL_EGLEXT_PROTOTYPES -EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageKHR (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects); +EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageKHR (EGLDisplay dpy, EGLSurface surface, const EGLint *rects, EGLint n_rects); #endif #endif /* EGL_KHR_swap_buffers_with_damage */ @@ -462,6 +443,10 @@ EGLAPI EGLint EGLAPIENTRY eglWaitSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLin #endif #endif /* EGL_KHR_wait_sync */ +#ifndef EGL_ANDROID_GLES_layers +#define EGL_ANDROID_GLES_layers 1 +#endif /* EGL_ANDROID_GLES_layers */ + #ifndef EGL_ANDROID_blob_cache #define EGL_ANDROID_blob_cache 1 typedef khronos_ssize_t EGLsizeiANDROID; @@ -495,6 +480,47 @@ EGLAPI EGLClientBuffer EGLAPIENTRY eglCreateNativeClientBufferANDROID (const EGL #define EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID 0x314C #endif /* EGL_ANDROID_front_buffer_auto_refresh */ +#ifndef EGL_ANDROID_get_frame_timestamps +#define EGL_ANDROID_get_frame_timestamps 1 +typedef khronos_stime_nanoseconds_t EGLnsecsANDROID; +#define EGL_TIMESTAMP_PENDING_ANDROID EGL_CAST(EGLnsecsANDROID,-2) +#define EGL_TIMESTAMP_INVALID_ANDROID EGL_CAST(EGLnsecsANDROID,-1) +#define EGL_TIMESTAMPS_ANDROID 0x3430 +#define EGL_COMPOSITE_DEADLINE_ANDROID 0x3431 +#define EGL_COMPOSITE_INTERVAL_ANDROID 0x3432 +#define EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID 0x3433 +#define EGL_REQUESTED_PRESENT_TIME_ANDROID 0x3434 +#define EGL_RENDERING_COMPLETE_TIME_ANDROID 0x3435 +#define EGL_COMPOSITION_LATCH_TIME_ANDROID 0x3436 +#define EGL_FIRST_COMPOSITION_START_TIME_ANDROID 0x3437 +#define EGL_LAST_COMPOSITION_START_TIME_ANDROID 0x3438 +#define EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID 0x3439 +#define EGL_DISPLAY_PRESENT_TIME_ANDROID 0x343A +#define EGL_DEQUEUE_READY_TIME_ANDROID 0x343B +#define EGL_READS_DONE_TIME_ANDROID 0x343C +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETCOMPOSITORTIMINGSUPPORTEDANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLint name); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETCOMPOSITORTIMINGANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLint numTimestamps, const EGLint *names, EGLnsecsANDROID *values); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETNEXTFRAMEIDANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLuint64KHR *frameId); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETFRAMETIMESTAMPSUPPORTEDANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLint timestamp); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETFRAMETIMESTAMPSANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLuint64KHR frameId, EGLint numTimestamps, const EGLint *timestamps, EGLnsecsANDROID *values); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglGetCompositorTimingSupportedANDROID (EGLDisplay dpy, EGLSurface surface, EGLint name); +EGLAPI EGLBoolean EGLAPIENTRY eglGetCompositorTimingANDROID (EGLDisplay dpy, EGLSurface surface, EGLint numTimestamps, const EGLint *names, EGLnsecsANDROID *values); +EGLAPI EGLBoolean EGLAPIENTRY eglGetNextFrameIdANDROID (EGLDisplay dpy, EGLSurface surface, EGLuint64KHR *frameId); +EGLAPI EGLBoolean EGLAPIENTRY eglGetFrameTimestampSupportedANDROID (EGLDisplay dpy, EGLSurface surface, EGLint timestamp); +EGLAPI EGLBoolean EGLAPIENTRY eglGetFrameTimestampsANDROID (EGLDisplay dpy, EGLSurface surface, EGLuint64KHR frameId, EGLint numTimestamps, const EGLint *timestamps, EGLnsecsANDROID *values); +#endif +#endif /* EGL_ANDROID_get_frame_timestamps */ + +#ifndef EGL_ANDROID_get_native_client_buffer +#define EGL_ANDROID_get_native_client_buffer 1 +struct AHardwareBuffer; +typedef EGLClientBuffer (EGLAPIENTRYP PFNEGLGETNATIVECLIENTBUFFERANDROIDPROC) (const struct AHardwareBuffer *buffer); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLClientBuffer EGLAPIENTRY eglGetNativeClientBufferANDROID (const struct AHardwareBuffer *buffer); +#endif +#endif /* EGL_ANDROID_get_native_client_buffer */ + #ifndef EGL_ANDROID_image_native_buffer #define EGL_ANDROID_image_native_buffer 1 #define EGL_NATIVE_BUFFER_ANDROID 0x3140 @@ -514,7 +540,6 @@ EGLAPI EGLint EGLAPIENTRY eglDupNativeFenceFDANDROID (EGLDisplay dpy, EGLSyncKHR #ifndef EGL_ANDROID_presentation_time #define EGL_ANDROID_presentation_time 1 -typedef khronos_stime_nanoseconds_t EGLnsecsANDROID; typedef EGLBoolean (EGLAPIENTRYP PFNEGLPRESENTATIONTIMEANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLnsecsANDROID time); #ifdef EGL_EGLEXT_PROTOTYPES EGLAPI EGLBoolean EGLAPIENTRY eglPresentationTimeANDROID (EGLDisplay dpy, EGLSurface surface, EGLnsecsANDROID time); @@ -549,11 +574,25 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSu #define EGL_ANGLE_surface_d3d_texture_2d_share_handle 1 #endif /* EGL_ANGLE_surface_d3d_texture_2d_share_handle */ +#ifndef EGL_ANGLE_sync_control_rate +#define EGL_ANGLE_sync_control_rate 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETMSCRATEANGLEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *numerator, EGLint *denominator); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglGetMscRateANGLE (EGLDisplay dpy, EGLSurface surface, EGLint *numerator, EGLint *denominator); +#endif +#endif /* EGL_ANGLE_sync_control_rate */ + #ifndef EGL_ANGLE_window_fixed_size #define EGL_ANGLE_window_fixed_size 1 #define EGL_FIXED_SIZE_ANGLE 0x3201 #endif /* EGL_ANGLE_window_fixed_size */ +#ifndef EGL_ARM_image_format +#define EGL_ARM_image_format 1 +#define EGL_COLOR_COMPONENT_TYPE_UNSIGNED_INTEGER_ARM 0x3287 +#define EGL_COLOR_COMPONENT_TYPE_INTEGER_ARM 0x3288 +#endif /* EGL_ARM_image_format */ + #ifndef EGL_ARM_implicit_external_sync #define EGL_ARM_implicit_external_sync 1 #define EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM 0x328A @@ -578,6 +617,16 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSu #define EGL_EXT_client_extensions 1 #endif /* EGL_EXT_client_extensions */ +#ifndef EGL_EXT_client_sync +#define EGL_EXT_client_sync 1 +#define EGL_SYNC_CLIENT_EXT 0x3364 +#define EGL_SYNC_CLIENT_SIGNAL_EXT 0x3365 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLCLIENTSIGNALSYNCEXTPROC) (EGLDisplay dpy, EGLSync sync, const EGLAttrib *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglClientSignalSyncEXT (EGLDisplay dpy, EGLSync sync, const EGLAttrib *attrib_list); +#endif +#endif /* EGL_EXT_client_sync */ + #ifndef EGL_EXT_compositor #define EGL_EXT_compositor 1 #define EGL_PRIMARY_COMPOSITOR_CONTEXT_EXT 0x3460 @@ -602,6 +651,11 @@ EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSwapPolicyEXT (EGLint external_win_id #endif #endif /* EGL_EXT_compositor */ +#ifndef EGL_EXT_config_select_group +#define EGL_EXT_config_select_group 1 +#define EGL_CONFIG_SELECT_GROUP_EXT 0x34C0 +#endif /* EGL_EXT_config_select_group */ + #ifndef EGL_EXT_create_context_robustness #define EGL_EXT_create_context_robustness 1 #define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT 0x30BF @@ -631,8 +685,14 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribEXT (EGLDisplay dpy, EGLint a #ifndef EGL_EXT_device_drm #define EGL_EXT_device_drm 1 #define EGL_DRM_DEVICE_FILE_EXT 0x3233 +#define EGL_DRM_MASTER_FD_EXT 0x333C #endif /* EGL_EXT_device_drm */ +#ifndef EGL_EXT_device_drm_render_node +#define EGL_EXT_device_drm_render_node 1 +#define EGL_DRM_RENDER_NODE_FILE_EXT 0x3377 +#endif /* EGL_EXT_device_drm_render_node */ + #ifndef EGL_EXT_device_enumeration #define EGL_EXT_device_enumeration 1 #endif /* EGL_EXT_device_enumeration */ @@ -640,12 +700,38 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribEXT (EGLDisplay dpy, EGLint a #ifndef EGL_EXT_device_openwf #define EGL_EXT_device_openwf 1 #define EGL_OPENWF_DEVICE_ID_EXT 0x3237 +#define EGL_OPENWF_DEVICE_EXT 0x333D #endif /* EGL_EXT_device_openwf */ +#ifndef EGL_EXT_device_persistent_id +#define EGL_EXT_device_persistent_id 1 +#define EGL_DEVICE_UUID_EXT 0x335C +#define EGL_DRIVER_UUID_EXT 0x335D +#define EGL_DRIVER_NAME_EXT 0x335E +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEVICEBINARYEXTPROC) (EGLDeviceEXT device, EGLint name, EGLint max_size, void *value, EGLint *size); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQueryDeviceBinaryEXT (EGLDeviceEXT device, EGLint name, EGLint max_size, void *value, EGLint *size); +#endif +#endif /* EGL_EXT_device_persistent_id */ + #ifndef EGL_EXT_device_query #define EGL_EXT_device_query 1 #endif /* EGL_EXT_device_query */ +#ifndef EGL_EXT_device_query_name +#define EGL_EXT_device_query_name 1 +#define EGL_RENDERER_EXT 0x335F +#endif /* EGL_EXT_device_query_name */ + +#ifndef EGL_EXT_explicit_device +#define EGL_EXT_explicit_device 1 +#endif /* EGL_EXT_explicit_device */ + +#ifndef EGL_EXT_gl_colorspace_bt2020_hlg +#define EGL_EXT_gl_colorspace_bt2020_hlg 1 +#define EGL_GL_COLORSPACE_BT2020_HLG_EXT 0x3540 +#endif /* EGL_EXT_gl_colorspace_bt2020_hlg */ + #ifndef EGL_EXT_gl_colorspace_bt2020_linear #define EGL_EXT_gl_colorspace_bt2020_linear 1 #define EGL_GL_COLORSPACE_BT2020_LINEAR_EXT 0x333F @@ -666,6 +752,11 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribEXT (EGLDisplay dpy, EGLint a #define EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT 0x3362 #endif /* EGL_EXT_gl_colorspace_display_p3_linear */ +#ifndef EGL_EXT_gl_colorspace_display_p3_passthrough +#define EGL_EXT_gl_colorspace_display_p3_passthrough 1 +#define EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT 0x3490 +#endif /* EGL_EXT_gl_colorspace_display_p3_passthrough */ + #ifndef EGL_EXT_gl_colorspace_scrgb #define EGL_EXT_gl_colorspace_scrgb 1 #define EGL_GL_COLORSPACE_SCRGB_EXT 0x3351 @@ -723,6 +814,11 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQueryDmaBufModifiersEXT (EGLDisplay dpy, EGLint #endif #endif /* EGL_EXT_image_dma_buf_import_modifiers */ +#ifndef EGL_EXT_image_gl_colorspace +#define EGL_EXT_image_gl_colorspace 1 +#define EGL_GL_COLORSPACE_DEFAULT_EXT 0x314D +#endif /* EGL_EXT_image_gl_colorspace */ + #ifndef EGL_EXT_image_implicit_sync_control #define EGL_EXT_image_implicit_sync_control 1 #define EGL_IMPORT_SYNC_TYPE_EXT 0x3470 @@ -812,6 +908,17 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurfaceEXT (EGLDisplay dpy, #define EGL_PLATFORM_X11_SCREEN_EXT 0x31D6 #endif /* EGL_EXT_platform_x11 */ +#ifndef EGL_EXT_platform_xcb +#define EGL_EXT_platform_xcb 1 +#define EGL_PLATFORM_XCB_EXT 0x31DC +#define EGL_PLATFORM_XCB_SCREEN_EXT 0x31DE +#endif /* EGL_EXT_platform_xcb */ + +#ifndef EGL_EXT_present_opaque +#define EGL_EXT_present_opaque 1 +#define EGL_PRESENT_OPAQUE_EXT 0x31DF +#endif /* EGL_EXT_present_opaque */ + #ifndef EGL_EXT_protected_content #define EGL_EXT_protected_content 1 #define EGL_PROTECTED_CONTENT_EXT 0x32C0 @@ -821,6 +928,10 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurfaceEXT (EGLDisplay dpy, #define EGL_EXT_protected_surface 1 #endif /* EGL_EXT_protected_surface */ +#ifndef EGL_EXT_query_reset_notification_strategy +#define EGL_EXT_query_reset_notification_strategy 1 +#endif /* EGL_EXT_query_reset_notification_strategy */ + #ifndef EGL_EXT_stream_consumer_egloutput #define EGL_EXT_stream_consumer_egloutput 1 typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMEROUTPUTEXTPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLOutputLayerEXT layer); @@ -850,14 +961,47 @@ EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerOutputEXT (EGLDisplay dpy, EGLStr #define EGL_METADATA_SCALING_EXT 50000 #endif /* EGL_EXT_surface_SMPTE2086_metadata */ +#ifndef EGL_EXT_surface_compression +#define EGL_EXT_surface_compression 1 +#define EGL_SURFACE_COMPRESSION_EXT 0x34B0 +#define EGL_SURFACE_COMPRESSION_PLANE1_EXT 0x328E +#define EGL_SURFACE_COMPRESSION_PLANE2_EXT 0x328F +#define EGL_SURFACE_COMPRESSION_FIXED_RATE_NONE_EXT 0x34B1 +#define EGL_SURFACE_COMPRESSION_FIXED_RATE_DEFAULT_EXT 0x34B2 +#define EGL_SURFACE_COMPRESSION_FIXED_RATE_1BPC_EXT 0x34B4 +#define EGL_SURFACE_COMPRESSION_FIXED_RATE_2BPC_EXT 0x34B5 +#define EGL_SURFACE_COMPRESSION_FIXED_RATE_3BPC_EXT 0x34B6 +#define EGL_SURFACE_COMPRESSION_FIXED_RATE_4BPC_EXT 0x34B7 +#define EGL_SURFACE_COMPRESSION_FIXED_RATE_5BPC_EXT 0x34B8 +#define EGL_SURFACE_COMPRESSION_FIXED_RATE_6BPC_EXT 0x34B9 +#define EGL_SURFACE_COMPRESSION_FIXED_RATE_7BPC_EXT 0x34BA +#define EGL_SURFACE_COMPRESSION_FIXED_RATE_8BPC_EXT 0x34BB +#define EGL_SURFACE_COMPRESSION_FIXED_RATE_9BPC_EXT 0x34BC +#define EGL_SURFACE_COMPRESSION_FIXED_RATE_10BPC_EXT 0x34BD +#define EGL_SURFACE_COMPRESSION_FIXED_RATE_11BPC_EXT 0x34BE +#define EGL_SURFACE_COMPRESSION_FIXED_RATE_12BPC_EXT 0x34BF +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSUPPORTEDCOMPRESSIONRATESEXTPROC) (EGLDisplay dpy, EGLConfig config, const EGLAttrib *attrib_list, EGLint *rates, EGLint rate_size, EGLint *num_rates); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglQuerySupportedCompressionRatesEXT (EGLDisplay dpy, EGLConfig config, const EGLAttrib *attrib_list, EGLint *rates, EGLint rate_size, EGLint *num_rates); +#endif +#endif /* EGL_EXT_surface_compression */ + #ifndef EGL_EXT_swap_buffers_with_damage #define EGL_EXT_swap_buffers_with_damage 1 -typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC) (EGLDisplay dpy, EGLSurface surface, const EGLint *rects, EGLint n_rects); #ifdef EGL_EGLEXT_PROTOTYPES -EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageEXT (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects); +EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageEXT (EGLDisplay dpy, EGLSurface surface, const EGLint *rects, EGLint n_rects); #endif #endif /* EGL_EXT_swap_buffers_with_damage */ +#ifndef EGL_EXT_sync_reuse +#define EGL_EXT_sync_reuse 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNSIGNALSYNCEXTPROC) (EGLDisplay dpy, EGLSync sync, const EGLAttrib *attrib_list); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglUnsignalSyncEXT (EGLDisplay dpy, EGLSync sync, const EGLAttrib *attrib_list); +#endif +#endif /* EGL_EXT_sync_reuse */ + #ifndef EGL_EXT_yuv_surface #define EGL_EXT_yuv_surface 1 #define EGL_YUV_ORDER_EXT 0x3301 @@ -933,6 +1077,7 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurfaceHI (EGLDisplay dpy, EGLConfi #define EGL_DRM_BUFFER_STRIDE_MESA 0x31D4 #define EGL_DRM_BUFFER_USE_SCANOUT_MESA 0x00000001 #define EGL_DRM_BUFFER_USE_SHARE_MESA 0x00000002 +#define EGL_DRM_BUFFER_USE_CURSOR_MESA 0x00000004 typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEDRMIMAGEMESAPROC) (EGLDisplay dpy, const EGLint *attrib_list); typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDRMIMAGEMESAPROC) (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride); #ifdef EGL_EGLEXT_PROTOTYPES @@ -961,6 +1106,16 @@ EGLAPI EGLBoolean EGLAPIENTRY eglExportDMABUFImageMESA (EGLDisplay dpy, EGLImage #define EGL_PLATFORM_SURFACELESS_MESA 0x31DD #endif /* EGL_MESA_platform_surfaceless */ +#ifndef EGL_MESA_query_driver +#define EGL_MESA_query_driver 1 +typedef char *(EGLAPIENTRYP PFNEGLGETDISPLAYDRIVERCONFIGPROC) (EGLDisplay dpy); +typedef const char *(EGLAPIENTRYP PFNEGLGETDISPLAYDRIVERNAMEPROC) (EGLDisplay dpy); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI char *EGLAPIENTRY eglGetDisplayDriverConfig (EGLDisplay dpy); +EGLAPI const char *EGLAPIENTRY eglGetDisplayDriverName (EGLDisplay dpy); +#endif +#endif /* EGL_MESA_query_driver */ + #ifndef EGL_NOK_swap_region #define EGL_NOK_swap_region 1 typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGIONNOKPROC) (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects); @@ -987,6 +1142,11 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersRegion2NOK (EGLDisplay dpy, EGLSurfa #define EGL_AUTO_STEREO_NV 0x3136 #endif /* EGL_NV_3dvision_surface */ +#ifndef EGL_NV_context_priority_realtime +#define EGL_NV_context_priority_realtime 1 +#define EGL_CONTEXT_PRIORITY_REALTIME_NV 0x3357 +#endif /* EGL_NV_context_priority_realtime */ + #ifndef EGL_NV_coverage_sample #define EGL_NV_coverage_sample 1 #define EGL_COVERAGE_BUFFERS_NV 0x30E0 @@ -1044,19 +1204,47 @@ EGLAPI EGLBoolean EGLAPIENTRY eglPostSubBufferNV (EGLDisplay dpy, EGLSurface sur #endif #endif /* EGL_NV_post_sub_buffer */ +#ifndef EGL_NV_quadruple_buffer +#define EGL_NV_quadruple_buffer 1 +#define EGL_QUADRUPLE_BUFFER_NV 0x3231 +#endif /* EGL_NV_quadruple_buffer */ + #ifndef EGL_NV_robustness_video_memory_purge #define EGL_NV_robustness_video_memory_purge 1 #define EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV 0x334C #endif /* EGL_NV_robustness_video_memory_purge */ +#ifndef EGL_NV_stream_consumer_eglimage +#define EGL_NV_stream_consumer_eglimage 1 +#define EGL_STREAM_CONSUMER_IMAGE_NV 0x3373 +#define EGL_STREAM_IMAGE_ADD_NV 0x3374 +#define EGL_STREAM_IMAGE_REMOVE_NV 0x3375 +#define EGL_STREAM_IMAGE_AVAILABLE_NV 0x3376 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMIMAGECONSUMERCONNECTNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLint num_modifiers, const EGLuint64KHR *modifiers, const EGLAttrib *attrib_list); +typedef EGLint (EGLAPIENTRYP PFNEGLQUERYSTREAMCONSUMEREVENTNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLTime timeout, EGLenum *event, EGLAttrib *aux); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMACQUIREIMAGENVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLImage *pImage, EGLSync sync); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMRELEASEIMAGENVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLImage image, EGLSync sync); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglStreamImageConsumerConnectNV (EGLDisplay dpy, EGLStreamKHR stream, EGLint num_modifiers, const EGLuint64KHR *modifiers, const EGLAttrib *attrib_list); +EGLAPI EGLint EGLAPIENTRY eglQueryStreamConsumerEventNV (EGLDisplay dpy, EGLStreamKHR stream, EGLTime timeout, EGLenum *event, EGLAttrib *aux); +EGLAPI EGLBoolean EGLAPIENTRY eglStreamAcquireImageNV (EGLDisplay dpy, EGLStreamKHR stream, EGLImage *pImage, EGLSync sync); +EGLAPI EGLBoolean EGLAPIENTRY eglStreamReleaseImageNV (EGLDisplay dpy, EGLStreamKHR stream, EGLImage image, EGLSync sync); +#endif +#endif /* EGL_NV_stream_consumer_eglimage */ + +#ifndef EGL_NV_stream_consumer_eglimage_use_scanout_attrib +#define EGL_NV_stream_consumer_eglimage_use_scanout_attrib 1 +#define EGL_STREAM_CONSUMER_IMAGE_USE_SCANOUT_NV 0x3378 +#endif /* EGL_NV_stream_consumer_eglimage_use_scanout_attrib */ + #ifndef EGL_NV_stream_consumer_gltexture_yuv #define EGL_NV_stream_consumer_gltexture_yuv 1 #define EGL_YUV_PLANE0_TEXTURE_UNIT_NV 0x332C #define EGL_YUV_PLANE1_TEXTURE_UNIT_NV 0x332D #define EGL_YUV_PLANE2_TEXTURE_UNIT_NV 0x332E -typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALATTRIBSNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLAttrib *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALATTRIBSNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list); #ifdef EGL_EGLEXT_PROTOTYPES -EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalAttribsNV (EGLDisplay dpy, EGLStreamKHR stream, EGLAttrib *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalAttribsNV (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list); #endif #endif /* EGL_NV_stream_consumer_gltexture_yuv */ @@ -1085,6 +1273,12 @@ EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalAttribsNV (EGLDi #define EGL_STREAM_CROSS_SYSTEM_NV 0x334F #endif /* EGL_NV_stream_cross_system */ +#ifndef EGL_NV_stream_dma +#define EGL_NV_stream_dma 1 +#define EGL_STREAM_DMA_NV 0x3371 +#define EGL_STREAM_DMA_SERVER_NV 0x3372 +#endif /* EGL_NV_stream_dma */ + #ifndef EGL_NV_stream_fifo_next #define EGL_NV_stream_fifo_next 1 #define EGL_PENDING_FRAME_NV 0x3329 @@ -1096,6 +1290,14 @@ EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalAttribsNV (EGLDi #define EGL_STREAM_FIFO_SYNCHRONOUS_NV 0x3336 #endif /* EGL_NV_stream_fifo_synchronous */ +#ifndef EGL_NV_stream_flush +#define EGL_NV_stream_flush 1 +typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMFLUSHNVPROC) (EGLDisplay dpy, EGLStreamKHR stream); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglStreamFlushNV (EGLDisplay dpy, EGLStreamKHR stream); +#endif +#endif /* EGL_NV_stream_flush */ + #ifndef EGL_NV_stream_frame_limits #define EGL_NV_stream_frame_limits 1 #define EGL_PRODUCER_MAX_FRAME_HINT_NV 0x3337 @@ -1128,6 +1330,21 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamMetadataNV (EGLDisplay dpy, EGLStrea #endif #endif /* EGL_NV_stream_metadata */ +#ifndef EGL_NV_stream_origin +#define EGL_NV_stream_origin 1 +#define EGL_STREAM_FRAME_ORIGIN_X_NV 0x3366 +#define EGL_STREAM_FRAME_ORIGIN_Y_NV 0x3367 +#define EGL_STREAM_FRAME_MAJOR_AXIS_NV 0x3368 +#define EGL_CONSUMER_AUTO_ORIENTATION_NV 0x3369 +#define EGL_PRODUCER_AUTO_ORIENTATION_NV 0x336A +#define EGL_LEFT_NV 0x336B +#define EGL_RIGHT_NV 0x336C +#define EGL_TOP_NV 0x336D +#define EGL_BOTTOM_NV 0x336E +#define EGL_X_AXIS_NV 0x336F +#define EGL_Y_AXIS_NV 0x3370 +#endif /* EGL_NV_stream_origin */ + #ifndef EGL_NV_stream_remote #define EGL_NV_stream_remote 1 #define EGL_STREAM_STATE_INITIALIZING_NV 0x3240 @@ -1224,6 +1441,21 @@ EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeNV (void); #endif /* KHRONOS_SUPPORT_INT64 */ #endif /* EGL_NV_system_time */ +#ifndef EGL_NV_triple_buffer +#define EGL_NV_triple_buffer 1 +#define EGL_TRIPLE_BUFFER_NV 0x3230 +#endif /* EGL_NV_triple_buffer */ + +#ifndef EGL_QNX_image_native_buffer +#define EGL_QNX_image_native_buffer 1 +#define EGL_NATIVE_BUFFER_QNX 0x3551 +#endif /* EGL_QNX_image_native_buffer */ + +#ifndef EGL_QNX_platform_screen +#define EGL_QNX_platform_screen 1 +#define EGL_PLATFORM_SCREEN_QNX 0x3550 +#endif /* EGL_QNX_platform_screen */ + #ifndef EGL_TIZEN_image_native_buffer #define EGL_TIZEN_image_native_buffer 1 #define EGL_NATIVE_BUFFER_TIZEN 0x32A0 @@ -1234,6 +1466,40 @@ EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeNV (void); #define EGL_NATIVE_SURFACE_TIZEN 0x32A1 #endif /* EGL_TIZEN_image_native_surface */ +#ifndef EGL_WL_bind_wayland_display +#define EGL_WL_bind_wayland_display 1 +#define PFNEGLBINDWAYLANDDISPLAYWL PFNEGLBINDWAYLANDDISPLAYWLPROC +#define PFNEGLUNBINDWAYLANDDISPLAYWL PFNEGLUNBINDWAYLANDDISPLAYWLPROC +#define PFNEGLQUERYWAYLANDBUFFERWL PFNEGLQUERYWAYLANDBUFFERWLPROC +struct wl_display; +struct wl_resource; +#define EGL_WAYLAND_BUFFER_WL 0x31D5 +#define EGL_WAYLAND_PLANE_WL 0x31D6 +#define EGL_TEXTURE_Y_U_V_WL 0x31D7 +#define EGL_TEXTURE_Y_UV_WL 0x31D8 +#define EGL_TEXTURE_Y_XUXV_WL 0x31D9 +#define EGL_TEXTURE_EXTERNAL_WL 0x31DA +#define EGL_WAYLAND_Y_INVERTED_WL 0x31DB +typedef EGLBoolean (EGLAPIENTRYP PFNEGLBINDWAYLANDDISPLAYWLPROC) (EGLDisplay dpy, struct wl_display *display); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNBINDWAYLANDDISPLAYWLPROC) (EGLDisplay dpy, struct wl_display *display); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYWAYLANDBUFFERWLPROC) (EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglBindWaylandDisplayWL (EGLDisplay dpy, struct wl_display *display); +EGLAPI EGLBoolean EGLAPIENTRY eglUnbindWaylandDisplayWL (EGLDisplay dpy, struct wl_display *display); +EGLAPI EGLBoolean EGLAPIENTRY eglQueryWaylandBufferWL (EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value); +#endif +#endif /* EGL_WL_bind_wayland_display */ + +#ifndef EGL_WL_create_wayland_buffer_from_image +#define EGL_WL_create_wayland_buffer_from_image 1 +#define PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWL PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWLPROC +struct wl_buffer; +typedef struct wl_buffer *(EGLAPIENTRYP PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWLPROC) (EGLDisplay dpy, EGLImageKHR image); +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI struct wl_buffer *EGLAPIENTRY eglCreateWaylandBufferFromImageWL (EGLDisplay dpy, EGLImageKHR image); +#endif +#endif /* EGL_WL_create_wayland_buffer_from_image */ + #ifdef __cplusplus } #endif diff --git a/SDL2-2.0.12/src/video/khronos/EGL/eglplatform.h b/SDL2-2.30.5/src/video/khronos/EGL/eglplatform.h similarity index 60% rename from SDL2-2.0.12/src/video/khronos/EGL/eglplatform.h rename to SDL2-2.30.5/src/video/khronos/EGL/eglplatform.h index c77c333..6786afd 100644 --- a/SDL2-2.0.12/src/video/khronos/EGL/eglplatform.h +++ b/SDL2-2.30.5/src/video/khronos/EGL/eglplatform.h @@ -2,36 +2,17 @@ #define __eglplatform_h_ /* -** Copyright (c) 2007-2016 The Khronos Group Inc. -** -** Permission is hereby granted, free of charge, to any person obtaining a -** copy of this software and/or associated documentation files (the -** "Materials"), to deal in the Materials without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Materials, and to -** permit persons to whom the Materials are furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be included -** in all copies or substantial portions of the Materials. -** -** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +** Copyright 2007-2020 The Khronos Group Inc. +** SPDX-License-Identifier: Apache-2.0 */ /* Platform-specific types and definitions for egl.h - * $Revision: 30994 $ on $Date: 2015-04-30 13:36:48 -0700 (Thu, 30 Apr 2015) $ * * Adopters may modify khrplatform.h and this file to suit their platform. * You are encouraged to submit all modifications to the Khronos group so that * they can be included in future versions of this file. Please submit changes - * by sending them to the public Khronos Bugzilla (http://khronos.org/bugzilla) - * by filing a bug against product "EGL" component "Registry". + * by filing an issue or pull request on the public Khronos EGL Registry, at + * https://www.github.com/KhronosGroup/EGL-Registry/ */ #include @@ -67,7 +48,13 @@ * implementations. */ -#if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */ +#if defined(EGL_NO_PLATFORM_SPECIFIC_TYPES) + +typedef void *EGLNativeDisplayType; +typedef void *EGLNativePixmapType; +typedef void *EGLNativeWindowType; + +#elif defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */ #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN 1 #endif @@ -77,22 +64,52 @@ typedef HDC EGLNativeDisplayType; typedef HBITMAP EGLNativePixmapType; typedef HWND EGLNativeWindowType; -#elif defined(__APPLE__) || defined(__WINSCW__) || defined(__SYMBIAN32__) /* Symbian */ +#elif defined(__QNX__) + +typedef khronos_uintptr_t EGLNativeDisplayType; +typedef struct _screen_pixmap* EGLNativePixmapType; /* screen_pixmap_t */ +typedef struct _screen_window* EGLNativeWindowType; /* screen_window_t */ + +#elif defined(__EMSCRIPTEN__) + +typedef int EGLNativeDisplayType; +typedef int EGLNativePixmapType; +typedef int EGLNativeWindowType; + +#elif defined(__WINSCW__) || defined(__SYMBIAN32__) /* Symbian */ typedef int EGLNativeDisplayType; -typedef void *EGLNativeWindowType; typedef void *EGLNativePixmapType; +typedef void *EGLNativeWindowType; + +#elif defined(WL_EGL_PLATFORM) + +typedef struct wl_display *EGLNativeDisplayType; +typedef struct wl_egl_pixmap *EGLNativePixmapType; +typedef struct wl_egl_window *EGLNativeWindowType; + +#elif defined(__GBM__) + +typedef struct gbm_device *EGLNativeDisplayType; +typedef struct gbm_bo *EGLNativePixmapType; +typedef void *EGLNativeWindowType; #elif defined(__ANDROID__) || defined(ANDROID) struct ANativeWindow; struct egl_native_pixmap_t; -typedef struct ANativeWindow* EGLNativeWindowType; -typedef struct egl_native_pixmap_t* EGLNativePixmapType; typedef void* EGLNativeDisplayType; +typedef struct egl_native_pixmap_t* EGLNativePixmapType; +typedef struct ANativeWindow* EGLNativeWindowType; -#elif defined(__unix__) +#elif defined(USE_OZONE) + +typedef intptr_t EGLNativeDisplayType; +typedef intptr_t EGLNativePixmapType; +typedef intptr_t EGLNativeWindowType; + +#elif defined(USE_X11) /* X11 (tentative) */ #include @@ -102,6 +119,32 @@ typedef Display *EGLNativeDisplayType; typedef Pixmap EGLNativePixmapType; typedef Window EGLNativeWindowType; +#elif defined(__unix__) + +typedef void *EGLNativeDisplayType; +typedef khronos_uintptr_t EGLNativePixmapType; +typedef khronos_uintptr_t EGLNativeWindowType; + +#elif defined(__APPLE__) + +typedef int EGLNativeDisplayType; +typedef void *EGLNativePixmapType; +typedef void *EGLNativeWindowType; + +#elif defined(__HAIKU__) + +#include + +typedef void *EGLNativeDisplayType; +typedef khronos_uintptr_t EGLNativePixmapType; +typedef khronos_uintptr_t EGLNativeWindowType; + +#elif defined(__Fuchsia__) + +typedef void *EGLNativeDisplayType; +typedef khronos_uintptr_t EGLNativePixmapType; +typedef khronos_uintptr_t EGLNativeWindowType; + #else #error "Platform not recognized" #endif diff --git a/SDL2-2.0.12/src/video/khronos/GLES2/gl2.h b/SDL2-2.30.5/src/video/khronos/GLES2/gl2.h similarity index 96% rename from SDL2-2.0.12/src/video/khronos/GLES2/gl2.h rename to SDL2-2.30.5/src/video/khronos/GLES2/gl2.h index 8ba1642..6be4e36 100644 --- a/SDL2-2.0.12/src/video/khronos/GLES2/gl2.h +++ b/SDL2-2.30.5/src/video/khronos/GLES2/gl2.h @@ -1,33 +1,14 @@ -#ifndef __gl2_h_ -#define __gl2_h_ 1 +#ifndef __gles2_gl2_h_ +#define __gles2_gl2_h_ 1 #ifdef __cplusplus extern "C" { #endif /* -** Copyright (c) 2013-2017 The Khronos Group Inc. +** Copyright 2013-2020 The Khronos Group Inc. +** SPDX-License-Identifier: MIT ** -** Permission is hereby granted, free of charge, to any person obtaining a -** copy of this software and/or associated documentation files (the -** "Materials"), to deal in the Materials without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Materials, and to -** permit persons to whom the Materials are furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be included -** in all copies or substantial portions of the Materials. -** -** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. -*/ -/* ** This header is generated from the Khronos OpenGL / OpenGL ES XML ** API Registry. The current version of the Registry, generator scripts ** used to make the header, and the header can be found at @@ -44,7 +25,7 @@ extern "C" { #define GL_GLES_PROTOTYPES 1 #endif -/* Generated on date 20170817 */ +/* Generated on date 20231129 */ /* Generated C header for: * API: gles2 @@ -62,8 +43,8 @@ extern "C" { typedef khronos_int8_t GLbyte; typedef khronos_float_t GLclampf; typedef khronos_int32_t GLfixed; -typedef short GLshort; -typedef unsigned short GLushort; +typedef khronos_int16_t GLshort; +typedef khronos_uint16_t GLushort; typedef void GLvoid; typedef struct __GLsync *GLsync; typedef khronos_int64_t GLint64; @@ -477,7 +458,7 @@ typedef void (GL_APIENTRYP PFNGLRELEASESHADERCOMPILERPROC) (void); typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); typedef void (GL_APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLfloat value, GLboolean invert); typedef void (GL_APIENTRYP PFNGLSCISSORPROC) (GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (GL_APIENTRYP PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length); +typedef void (GL_APIENTRYP PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint *shaders, GLenum binaryFormat, const void *binary, GLsizei length); typedef void (GL_APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length); typedef void (GL_APIENTRYP PFNGLSTENCILFUNCPROC) (GLenum func, GLint ref, GLuint mask); typedef void (GL_APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC) (GLenum face, GLenum func, GLint ref, GLuint mask); @@ -620,7 +601,7 @@ GL_APICALL void GL_APIENTRY glReleaseShaderCompiler (void); GL_APICALL void GL_APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); GL_APICALL void GL_APIENTRY glSampleCoverage (GLfloat value, GLboolean invert); GL_APICALL void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height); -GL_APICALL void GL_APIENTRY glShaderBinary (GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length); +GL_APICALL void GL_APIENTRY glShaderBinary (GLsizei count, const GLuint *shaders, GLenum binaryFormat, const void *binary, GLsizei length); GL_APICALL void GL_APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length); GL_APICALL void GL_APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask); GL_APICALL void GL_APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask); diff --git a/SDL2-2.0.12/src/video/khronos/GLES2/gl2ext.h b/SDL2-2.30.5/src/video/khronos/GLES2/gl2ext.h similarity index 84% rename from SDL2-2.0.12/src/video/khronos/GLES2/gl2ext.h rename to SDL2-2.30.5/src/video/khronos/GLES2/gl2ext.h index 4e1488c..63b530b 100644 --- a/SDL2-2.0.12/src/video/khronos/GLES2/gl2ext.h +++ b/SDL2-2.30.5/src/video/khronos/GLES2/gl2ext.h @@ -1,33 +1,14 @@ -#ifndef __gl2ext_h_ -#define __gl2ext_h_ 1 +#ifndef __gles2_gl2ext_h_ +#define __gles2_gl2ext_h_ 1 #ifdef __cplusplus extern "C" { #endif /* -** Copyright (c) 2013-2017 The Khronos Group Inc. +** Copyright 2013-2020 The Khronos Group Inc. +** SPDX-License-Identifier: MIT ** -** Permission is hereby granted, free of charge, to any person obtaining a -** copy of this software and/or associated documentation files (the -** "Materials"), to deal in the Materials without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Materials, and to -** permit persons to whom the Materials are furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be included -** in all copies or substantial portions of the Materials. -** -** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. -*/ -/* ** This header is generated from the Khronos OpenGL / OpenGL ES XML ** API Registry. The current version of the Registry, generator scripts ** used to make the header, and the header can be found at @@ -38,7 +19,7 @@ extern "C" { #define GL_APIENTRYP GL_APIENTRY* #endif -/* Generated on date 20170817 */ +/* Generated on date 20231129 */ /* Generated C header for: * API: gles2 @@ -197,6 +178,22 @@ GL_APICALL void GL_APIENTRY glGetnUniformuivKHR (GLuint program, GLint location, #endif #endif /* GL_KHR_robustness */ +#ifndef GL_KHR_shader_subgroup +#define GL_KHR_shader_subgroup 1 +#define GL_SUBGROUP_SIZE_KHR 0x9532 +#define GL_SUBGROUP_SUPPORTED_STAGES_KHR 0x9533 +#define GL_SUBGROUP_SUPPORTED_FEATURES_KHR 0x9534 +#define GL_SUBGROUP_QUAD_ALL_STAGES_KHR 0x9535 +#define GL_SUBGROUP_FEATURE_BASIC_BIT_KHR 0x00000001 +#define GL_SUBGROUP_FEATURE_VOTE_BIT_KHR 0x00000002 +#define GL_SUBGROUP_FEATURE_ARITHMETIC_BIT_KHR 0x00000004 +#define GL_SUBGROUP_FEATURE_BALLOT_BIT_KHR 0x00000008 +#define GL_SUBGROUP_FEATURE_SHUFFLE_BIT_KHR 0x00000010 +#define GL_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT_KHR 0x00000020 +#define GL_SUBGROUP_FEATURE_CLUSTERED_BIT_KHR 0x00000040 +#define GL_SUBGROUP_FEATURE_QUAD_BIT_KHR 0x00000080 +#endif /* GL_KHR_shader_subgroup */ + #ifndef GL_KHR_texture_compression_astc_hdr #define GL_KHR_texture_compression_astc_hdr 1 #define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0 @@ -334,12 +331,12 @@ GL_APICALL GLboolean GL_APIENTRY glIsEnablediOES (GLenum target, GLuint index); typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXOESPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex); typedef void (GL_APIENTRYP PFNGLDRAWRANGEELEMENTSBASEVERTEXOESPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex); typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXOESPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex); -typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSBASEVERTEXEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount, const GLint *basevertex); +typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSBASEVERTEXEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount, const GLint *basevertex); #ifdef GL_GLEXT_PROTOTYPES GL_APICALL void GL_APIENTRY glDrawElementsBaseVertexOES (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex); GL_APICALL void GL_APIENTRY glDrawRangeElementsBaseVertexOES (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex); GL_APICALL void GL_APIENTRY glDrawElementsInstancedBaseVertexOES (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex); -GL_APICALL void GL_APIENTRY glMultiDrawElementsBaseVertexEXT (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount, const GLint *basevertex); +GL_APICALL void GL_APIENTRY glMultiDrawElementsBaseVertexEXT (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount, const GLint *basevertex); #endif #endif /* GL_OES_draw_elements_base_vertex */ @@ -801,6 +798,22 @@ GL_APICALL void GL_APIENTRY glGetFloati_vOES (GLenum target, GLuint index, GLflo #define GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD 0x87EE #endif /* GL_AMD_compressed_ATC_texture */ +#ifndef GL_AMD_framebuffer_multisample_advanced +#define GL_AMD_framebuffer_multisample_advanced 1 +#define GL_RENDERBUFFER_STORAGE_SAMPLES_AMD 0x91B2 +#define GL_MAX_COLOR_FRAMEBUFFER_SAMPLES_AMD 0x91B3 +#define GL_MAX_COLOR_FRAMEBUFFER_STORAGE_SAMPLES_AMD 0x91B4 +#define GL_MAX_DEPTH_STENCIL_FRAMEBUFFER_SAMPLES_AMD 0x91B5 +#define GL_NUM_SUPPORTED_MULTISAMPLE_MODES_AMD 0x91B6 +#define GL_SUPPORTED_MULTISAMPLE_MODES_AMD 0x91B7 +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC) (GLenum target, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC) (GLuint renderbuffer, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleAdvancedAMD (GLenum target, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glNamedRenderbufferStorageMultisampleAdvancedAMD (GLuint renderbuffer, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height); +#endif +#endif /* GL_AMD_framebuffer_multisample_advanced */ + #ifndef GL_AMD_performance_monitor #define GL_AMD_performance_monitor 1 #define GL_COUNTER_TYPE_AMD 0x8BC0 @@ -914,9 +927,9 @@ GL_APICALL void GL_APIENTRY glVertexAttribDivisorANGLE (GLuint index, GLuint div #ifndef GL_ANGLE_translated_shader_source #define GL_ANGLE_translated_shader_source 1 #define GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE 0x93A0 -typedef void (GL_APIENTRYP PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC) (GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source); +typedef void (GL_APIENTRYP PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); #ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glGetTranslatedShaderSourceANGLE (GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source); +GL_APICALL void GL_APIENTRY glGetTranslatedShaderSourceANGLE (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); #endif #endif /* GL_ANGLE_translated_shader_source */ @@ -994,7 +1007,7 @@ typedef void (GL_APIENTRYP PFNGLDELETESYNCAPPLEPROC) (GLsync sync); typedef GLenum (GL_APIENTRYP PFNGLCLIENTWAITSYNCAPPLEPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); typedef void (GL_APIENTRYP PFNGLWAITSYNCAPPLEPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); typedef void (GL_APIENTRYP PFNGLGETINTEGER64VAPPLEPROC) (GLenum pname, GLint64 *params); -typedef void (GL_APIENTRYP PFNGLGETSYNCIVAPPLEPROC) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +typedef void (GL_APIENTRYP PFNGLGETSYNCIVAPPLEPROC) (GLsync sync, GLenum pname, GLsizei count, GLsizei *length, GLint *values); #ifdef GL_GLEXT_PROTOTYPES GL_APICALL GLsync GL_APIENTRY glFenceSyncAPPLE (GLenum condition, GLbitfield flags); GL_APICALL GLboolean GL_APIENTRY glIsSyncAPPLE (GLsync sync); @@ -1002,7 +1015,7 @@ GL_APICALL void GL_APIENTRY glDeleteSyncAPPLE (GLsync sync); GL_APICALL GLenum GL_APIENTRY glClientWaitSyncAPPLE (GLsync sync, GLbitfield flags, GLuint64 timeout); GL_APICALL void GL_APIENTRY glWaitSyncAPPLE (GLsync sync, GLbitfield flags, GLuint64 timeout); GL_APICALL void GL_APIENTRY glGetInteger64vAPPLE (GLenum pname, GLint64 *params); -GL_APICALL void GL_APIENTRY glGetSyncivAPPLE (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); +GL_APICALL void GL_APIENTRY glGetSyncivAPPLE (GLsync sync, GLenum pname, GLsizei count, GLsizei *length, GLint *values); #endif #endif /* GL_APPLE_sync */ @@ -1039,6 +1052,21 @@ GL_APICALL void GL_APIENTRY glGetSyncivAPPLE (GLsync sync, GLenum pname, GLsizei #define GL_ARM_rgba8 1 #endif /* GL_ARM_rgba8 */ +#ifndef GL_ARM_shader_core_properties +#define GL_ARM_shader_core_properties 1 +#define GL_SHADER_CORE_COUNT_ARM 0x96F0 +#define GL_SHADER_CORE_ACTIVE_COUNT_ARM 0x96F1 +#define GL_SHADER_CORE_PRESENT_MASK_ARM 0x96F2 +#define GL_SHADER_CORE_MAX_WARP_COUNT_ARM 0x96F3 +#define GL_SHADER_CORE_PIXEL_RATE_ARM 0x96F4 +#define GL_SHADER_CORE_TEXEL_RATE_ARM 0x96F5 +#define GL_SHADER_CORE_FMA_RATE_ARM 0x96F6 +typedef void (GL_APIENTRYP PFNGLMAXACTIVESHADERCORESARMPROC) (GLuint count); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glMaxActiveShaderCoresARM (GLuint count); +#endif +#endif /* GL_ARM_shader_core_properties */ + #ifndef GL_ARM_shader_framebuffer_fetch #define GL_ARM_shader_framebuffer_fetch 1 #define GL_FETCH_PER_SAMPLE_ARM 0x8F65 @@ -1049,6 +1077,11 @@ GL_APICALL void GL_APIENTRY glGetSyncivAPPLE (GLsync sync, GLenum pname, GLsizei #define GL_ARM_shader_framebuffer_fetch_depth_stencil 1 #endif /* GL_ARM_shader_framebuffer_fetch_depth_stencil */ +#ifndef GL_ARM_texture_unnormalized_coordinates +#define GL_ARM_texture_unnormalized_coordinates 1 +#define GL_TEXTURE_UNNORMALIZED_COORDINATES_ARM 0x8F6A +#endif /* GL_ARM_texture_unnormalized_coordinates */ + #ifndef GL_DMP_program_binary #define GL_DMP_program_binary 1 #define GL_SMAPHS30_PROGRAM_BINARY_DMP 0x9251 @@ -1065,6 +1098,23 @@ GL_APICALL void GL_APIENTRY glGetSyncivAPPLE (GLsync sync, GLenum pname, GLsizei #define GL_EXT_EGL_image_array 1 #endif /* GL_EXT_EGL_image_array */ +#ifndef GL_EXT_EGL_image_storage +#define GL_EXT_EGL_image_storage 1 +typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXSTORAGEEXTPROC) (GLenum target, GLeglImageOES image, const GLint* attrib_list); +typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXTURESTORAGEEXTPROC) (GLuint texture, GLeglImageOES image, const GLint* attrib_list); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glEGLImageTargetTexStorageEXT (GLenum target, GLeglImageOES image, const GLint* attrib_list); +GL_APICALL void GL_APIENTRY glEGLImageTargetTextureStorageEXT (GLuint texture, GLeglImageOES image, const GLint* attrib_list); +#endif +#endif /* GL_EXT_EGL_image_storage */ + +#ifndef GL_EXT_EGL_image_storage_compression +#define GL_EXT_EGL_image_storage_compression 1 +#define GL_SURFACE_COMPRESSION_EXT 0x96C0 +#define GL_SURFACE_COMPRESSION_FIXED_RATE_NONE_EXT 0x96C1 +#define GL_SURFACE_COMPRESSION_FIXED_RATE_DEFAULT_EXT 0x96C2 +#endif /* GL_EXT_EGL_image_storage_compression */ + #ifndef GL_EXT_YUV_target #define GL_EXT_YUV_target 1 #define GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT 0x8BE7 @@ -1220,6 +1270,11 @@ GL_APICALL void GL_APIENTRY glPopGroupMarkerEXT (void); #endif #endif /* GL_EXT_debug_marker */ +#ifndef GL_EXT_depth_clamp +#define GL_EXT_depth_clamp 1 +#define GL_DEPTH_CLAMP_EXT 0x864F +#endif /* GL_EXT_depth_clamp */ + #ifndef GL_EXT_discard_framebuffer #define GL_EXT_discard_framebuffer 1 #define GL_COLOR_EXT 0x1800 @@ -1251,6 +1306,7 @@ typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTIVEXTPROC) (GLuint id, GLenum pnam typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTUIVEXTPROC) (GLuint id, GLenum pname, GLuint *params); typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTI64VEXTPROC) (GLuint id, GLenum pname, GLint64 *params); typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTUI64VEXTPROC) (GLuint id, GLenum pname, GLuint64 *params); +typedef void (GL_APIENTRYP PFNGLGETINTEGER64VEXTPROC) (GLenum pname, GLint64 *data); #ifdef GL_GLEXT_PROTOTYPES GL_APICALL void GL_APIENTRY glGenQueriesEXT (GLsizei n, GLuint *ids); GL_APICALL void GL_APIENTRY glDeleteQueriesEXT (GLsizei n, const GLuint *ids); @@ -1263,6 +1319,7 @@ GL_APICALL void GL_APIENTRY glGetQueryObjectivEXT (GLuint id, GLenum pname, GLin GL_APICALL void GL_APIENTRY glGetQueryObjectuivEXT (GLuint id, GLenum pname, GLuint *params); GL_APICALL void GL_APIENTRY glGetQueryObjecti64vEXT (GLuint id, GLenum pname, GLint64 *params); GL_APICALL void GL_APIENTRY glGetQueryObjectui64vEXT (GLuint id, GLenum pname, GLuint64 *params); +GL_APICALL void GL_APIENTRY glGetInteger64vEXT (GLenum pname, GLint64 *data); #endif #endif /* GL_EXT_disjoint_timer_query */ @@ -1377,6 +1434,56 @@ GL_APICALL void GL_APIENTRY glNamedBufferStorageExternalEXT (GLuint buffer, GLin #define GL_EXT_float_blend 1 #endif /* GL_EXT_float_blend */ +#ifndef GL_EXT_fragment_shading_rate +#define GL_EXT_fragment_shading_rate 1 +#define GL_SHADING_RATE_1X1_PIXELS_EXT 0x96A6 +#define GL_SHADING_RATE_1X2_PIXELS_EXT 0x96A7 +#define GL_SHADING_RATE_2X1_PIXELS_EXT 0x96A8 +#define GL_SHADING_RATE_2X2_PIXELS_EXT 0x96A9 +#define GL_SHADING_RATE_1X4_PIXELS_EXT 0x96AA +#define GL_SHADING_RATE_4X1_PIXELS_EXT 0x96AB +#define GL_SHADING_RATE_4X2_PIXELS_EXT 0x96AC +#define GL_SHADING_RATE_2X4_PIXELS_EXT 0x96AD +#define GL_SHADING_RATE_4X4_PIXELS_EXT 0x96AE +#define GL_SHADING_RATE_EXT 0x96D0 +#define GL_SHADING_RATE_ATTACHMENT_EXT 0x96D1 +#define GL_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_EXT 0x96D2 +#define GL_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_EXT 0x96D3 +#define GL_FRAGMENT_SHADING_RATE_COMBINER_OP_MIN_EXT 0x96D4 +#define GL_FRAGMENT_SHADING_RATE_COMBINER_OP_MAX_EXT 0x96D5 +#define GL_FRAGMENT_SHADING_RATE_COMBINER_OP_MUL_EXT 0x96D6 +#define GL_MIN_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_WIDTH_EXT 0x96D7 +#define GL_MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_WIDTH_EXT 0x96D8 +#define GL_MIN_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_HEIGHT_EXT 0x96D9 +#define GL_MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_HEIGHT_EXT 0x96DA +#define GL_MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_TEXEL_ASPECT_RATIO_EXT 0x96DB +#define GL_MAX_FRAGMENT_SHADING_RATE_ATTACHMENT_LAYERS_EXT 0x96DC +#define GL_FRAGMENT_SHADING_RATE_WITH_SHADER_DEPTH_STENCIL_WRITES_SUPPORTED_EXT 0x96DD +#define GL_FRAGMENT_SHADING_RATE_WITH_SAMPLE_MASK_SUPPORTED_EXT 0x96DE +#define GL_FRAGMENT_SHADING_RATE_ATTACHMENT_WITH_DEFAULT_FRAMEBUFFER_SUPPORTED_EXT 0x96DF +#define GL_FRAGMENT_SHADING_RATE_NON_TRIVIAL_COMBINERS_SUPPORTED_EXT 0x8F6F +typedef void (GL_APIENTRYP PFNGLGETFRAGMENTSHADINGRATESEXTPROC) (GLsizei samples, GLsizei maxCount, GLsizei *count, GLenum *shadingRates); +typedef void (GL_APIENTRYP PFNGLSHADINGRATEEXTPROC) (GLenum rate); +typedef void (GL_APIENTRYP PFNGLSHADINGRATECOMBINEROPSEXTPROC) (GLenum combinerOp0, GLenum combinerOp1); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERSHADINGRATEEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint baseLayer, GLsizei numLayers, GLsizei texelWidth, GLsizei texelHeight); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGetFragmentShadingRatesEXT (GLsizei samples, GLsizei maxCount, GLsizei *count, GLenum *shadingRates); +GL_APICALL void GL_APIENTRY glShadingRateEXT (GLenum rate); +GL_APICALL void GL_APIENTRY glShadingRateCombinerOpsEXT (GLenum combinerOp0, GLenum combinerOp1); +GL_APICALL void GL_APIENTRY glFramebufferShadingRateEXT (GLenum target, GLenum attachment, GLuint texture, GLint baseLayer, GLsizei numLayers, GLsizei texelWidth, GLsizei texelHeight); +#endif +#endif /* GL_EXT_fragment_shading_rate */ + +#ifndef GL_EXT_framebuffer_blit_layers +#define GL_EXT_framebuffer_blit_layers 1 +typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERLAYERSEXTPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERLAYEREXTPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint srcLayer, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLint dstLayer, GLbitfield mask, GLenum filter); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glBlitFramebufferLayersEXT (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +GL_APICALL void GL_APIENTRY glBlitFramebufferLayerEXT (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint srcLayer, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLint dstLayer, GLbitfield mask, GLenum filter); +#endif +#endif /* GL_EXT_framebuffer_blit_layers */ + #ifndef GL_EXT_geometry_point_size #define GL_EXT_geometry_point_size 1 #endif /* GL_EXT_geometry_point_size */ @@ -1570,6 +1677,10 @@ GL_APICALL void GL_APIENTRY glFramebufferTexture2DMultisampleEXT (GLenum target, #endif #endif /* GL_EXT_multisampled_render_to_texture */ +#ifndef GL_EXT_multisampled_render_to_texture2 +#define GL_EXT_multisampled_render_to_texture2 1 +#endif /* GL_EXT_multisampled_render_to_texture2 */ + #ifndef GL_EXT_multiview_draw_buffers #define GL_EXT_multiview_draw_buffers 1 #define GL_COLOR_ATTACHMENT_EXT 0x90F0 @@ -1587,6 +1698,18 @@ GL_APICALL void GL_APIENTRY glGetIntegeri_vEXT (GLenum target, GLuint index, GLi #endif #endif /* GL_EXT_multiview_draw_buffers */ +#ifndef GL_EXT_multiview_tessellation_geometry_shader +#define GL_EXT_multiview_tessellation_geometry_shader 1 +#endif /* GL_EXT_multiview_tessellation_geometry_shader */ + +#ifndef GL_EXT_multiview_texture_multisample +#define GL_EXT_multiview_texture_multisample 1 +#endif /* GL_EXT_multiview_texture_multisample */ + +#ifndef GL_EXT_multiview_timer_query +#define GL_EXT_multiview_timer_query 1 +#endif /* GL_EXT_multiview_timer_query */ + #ifndef GL_EXT_occlusion_query_boolean #define GL_EXT_occlusion_query_boolean 1 #define GL_ANY_SAMPLES_PASSED_EXT 0x8C2F @@ -1704,6 +1827,8 @@ GL_APICALL void GL_APIENTRY glGetnUniformivEXT (GLuint program, GLint location, #define GL_LAYOUT_SHADER_READ_ONLY_EXT 0x9591 #define GL_LAYOUT_TRANSFER_SRC_EXT 0x9592 #define GL_LAYOUT_TRANSFER_DST_EXT 0x9593 +#define GL_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_EXT 0x9530 +#define GL_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_EXT 0x9531 typedef void (GL_APIENTRYP PFNGLGENSEMAPHORESEXTPROC) (GLsizei n, GLuint *semaphores); typedef void (GL_APIENTRYP PFNGLDELETESEMAPHORESEXTPROC) (GLsizei n, const GLuint *semaphores); typedef GLboolean (GL_APIENTRYP PFNGLISSEMAPHOREEXTPROC) (GLuint semaphore); @@ -1742,6 +1867,10 @@ GL_APICALL void GL_APIENTRY glImportSemaphoreWin32NameEXT (GLuint semaphore, GLe #endif #endif /* GL_EXT_semaphore_win32 */ +#ifndef GL_EXT_separate_depth_stencil +#define GL_EXT_separate_depth_stencil 1 +#endif /* GL_EXT_separate_depth_stencil */ + #ifndef GL_EXT_separate_shader_objects #define GL_EXT_separate_shader_objects 1 #define GL_ACTIVE_PROGRAM_EXT 0x8259 @@ -1752,7 +1881,7 @@ GL_APICALL void GL_APIENTRY glImportSemaphoreWin32NameEXT (GLuint semaphore, GLe #define GL_PROGRAM_PIPELINE_BINDING_EXT 0x825A typedef void (GL_APIENTRYP PFNGLACTIVESHADERPROGRAMEXTPROC) (GLuint pipeline, GLuint program); typedef void (GL_APIENTRYP PFNGLBINDPROGRAMPIPELINEEXTPROC) (GLuint pipeline); -typedef GLuint (GL_APIENTRYP PFNGLCREATESHADERPROGRAMVEXTPROC) (GLenum type, GLsizei count, const GLchar **strings); +typedef GLuint (GL_APIENTRYP PFNGLCREATESHADERPROGRAMVEXTPROC) (GLenum type, GLsizei count, const GLchar *const*strings); typedef void (GL_APIENTRYP PFNGLDELETEPROGRAMPIPELINESEXTPROC) (GLsizei n, const GLuint *pipelines); typedef void (GL_APIENTRYP PFNGLGENPROGRAMPIPELINESEXTPROC) (GLsizei n, GLuint *pipelines); typedef void (GL_APIENTRYP PFNGLGETPROGRAMPIPELINEINFOLOGEXTPROC) (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); @@ -1797,7 +1926,7 @@ typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC) (GLuint progra #ifdef GL_GLEXT_PROTOTYPES GL_APICALL void GL_APIENTRY glActiveShaderProgramEXT (GLuint pipeline, GLuint program); GL_APICALL void GL_APIENTRY glBindProgramPipelineEXT (GLuint pipeline); -GL_APICALL GLuint GL_APIENTRY glCreateShaderProgramvEXT (GLenum type, GLsizei count, const GLchar **strings); +GL_APICALL GLuint GL_APIENTRY glCreateShaderProgramvEXT (GLenum type, GLsizei count, const GLchar *const*strings); GL_APICALL void GL_APIENTRY glDeleteProgramPipelinesEXT (GLsizei n, const GLuint *pipelines); GL_APICALL void GL_APIENTRY glGenProgramPipelinesEXT (GLsizei n, GLuint *pipelines); GL_APICALL void GL_APIENTRY glGetProgramPipelineInfoLogEXT (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); @@ -1847,6 +1976,14 @@ GL_APICALL void GL_APIENTRY glProgramUniformMatrix4x3fvEXT (GLuint program, GLin #define GL_FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT 0x8A52 #endif /* GL_EXT_shader_framebuffer_fetch */ +#ifndef GL_EXT_shader_framebuffer_fetch_non_coherent +#define GL_EXT_shader_framebuffer_fetch_non_coherent 1 +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERFETCHBARRIEREXTPROC) (void); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glFramebufferFetchBarrierEXT (void); +#endif +#endif /* GL_EXT_shader_framebuffer_fetch_non_coherent */ + #ifndef GL_EXT_shader_group_vote #define GL_EXT_shader_group_vote 1 #endif /* GL_EXT_shader_group_vote */ @@ -1889,6 +2026,10 @@ GL_APICALL void GL_APIENTRY glClearPixelLocalStorageuiEXT (GLsizei offset, GLsiz #endif #endif /* GL_EXT_shader_pixel_local_storage2 */ +#ifndef GL_EXT_shader_samples_identical +#define GL_EXT_shader_samples_identical 1 +#endif /* GL_EXT_shader_samples_identical */ + #ifndef GL_EXT_shader_texture_lod #define GL_EXT_shader_texture_lod 1 #endif /* GL_EXT_shader_texture_lod */ @@ -2091,12 +2232,24 @@ GL_APICALL void GL_APIENTRY glTexBufferRangeEXT (GLenum target, GLenum internalf #ifndef GL_EXT_texture_filter_minmax #define GL_EXT_texture_filter_minmax 1 +#define GL_TEXTURE_REDUCTION_MODE_EXT 0x9366 +#define GL_WEIGHTED_AVERAGE_EXT 0x9367 #endif /* GL_EXT_texture_filter_minmax */ #ifndef GL_EXT_texture_format_BGRA8888 #define GL_EXT_texture_format_BGRA8888 1 #endif /* GL_EXT_texture_format_BGRA8888 */ +#ifndef GL_EXT_texture_format_sRGB_override +#define GL_EXT_texture_format_sRGB_override 1 +#define GL_TEXTURE_FORMAT_SRGB_OVERRIDE_EXT 0x8FBF +#endif /* GL_EXT_texture_format_sRGB_override */ + +#ifndef GL_EXT_texture_mirror_clamp_to_edge +#define GL_EXT_texture_mirror_clamp_to_edge 1 +#define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743 +#endif /* GL_EXT_texture_mirror_clamp_to_edge */ + #ifndef GL_EXT_texture_norm16 #define GL_EXT_texture_norm16 1 #define GL_R16_EXT 0x822A @@ -2106,6 +2259,10 @@ GL_APICALL void GL_APIENTRY glTexBufferRangeEXT (GLenum target, GLenum internalf #define GL_RGB16_SNORM_EXT 0x8F9A #endif /* GL_EXT_texture_norm16 */ +#ifndef GL_EXT_texture_query_lod +#define GL_EXT_texture_query_lod 1 +#endif /* GL_EXT_texture_query_lod */ + #ifndef GL_EXT_texture_rg #define GL_EXT_texture_rg 1 #define GL_RED_EXT 0x1903 @@ -2131,6 +2288,10 @@ GL_APICALL void GL_APIENTRY glTexBufferRangeEXT (GLenum target, GLenum internalf #define GL_SKIP_DECODE_EXT 0x8A4A #endif /* GL_EXT_texture_sRGB_decode */ +#ifndef GL_EXT_texture_shadow_lod +#define GL_EXT_texture_shadow_lod 1 +#endif /* GL_EXT_texture_shadow_lod */ + #ifndef GL_EXT_texture_storage #define GL_EXT_texture_storage 1 #define GL_TEXTURE_IMMUTABLE_FORMAT_EXT 0x912F @@ -2163,6 +2324,29 @@ GL_APICALL void GL_APIENTRY glTextureStorage3DEXT (GLuint texture, GLenum target #endif #endif /* GL_EXT_texture_storage */ +#ifndef GL_EXT_texture_storage_compression +#define GL_EXT_texture_storage_compression 1 +#define GL_NUM_SURFACE_COMPRESSION_FIXED_RATES_EXT 0x8F6E +#define GL_SURFACE_COMPRESSION_FIXED_RATE_1BPC_EXT 0x96C4 +#define GL_SURFACE_COMPRESSION_FIXED_RATE_2BPC_EXT 0x96C5 +#define GL_SURFACE_COMPRESSION_FIXED_RATE_3BPC_EXT 0x96C6 +#define GL_SURFACE_COMPRESSION_FIXED_RATE_4BPC_EXT 0x96C7 +#define GL_SURFACE_COMPRESSION_FIXED_RATE_5BPC_EXT 0x96C8 +#define GL_SURFACE_COMPRESSION_FIXED_RATE_6BPC_EXT 0x96C9 +#define GL_SURFACE_COMPRESSION_FIXED_RATE_7BPC_EXT 0x96CA +#define GL_SURFACE_COMPRESSION_FIXED_RATE_8BPC_EXT 0x96CB +#define GL_SURFACE_COMPRESSION_FIXED_RATE_9BPC_EXT 0x96CC +#define GL_SURFACE_COMPRESSION_FIXED_RATE_10BPC_EXT 0x96CD +#define GL_SURFACE_COMPRESSION_FIXED_RATE_11BPC_EXT 0x96CE +#define GL_SURFACE_COMPRESSION_FIXED_RATE_12BPC_EXT 0x96CF +typedef void (GL_APIENTRYP PFNGLTEXSTORAGEATTRIBS2DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, const GLint* attrib_list); +typedef void (GL_APIENTRYP PFNGLTEXSTORAGEATTRIBS3DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, const GLint* attrib_list); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glTexStorageAttribs2DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, const GLint* attrib_list); +GL_APICALL void GL_APIENTRY glTexStorageAttribs3DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, const GLint* attrib_list); +#endif +#endif /* GL_EXT_texture_storage_compression */ + #ifndef GL_EXT_texture_type_2_10_10_10_REV #define GL_EXT_texture_type_2_10_10_10_REV 1 #define GL_UNSIGNED_INT_2_10_10_10_REV_EXT 0x8368 @@ -2299,6 +2483,11 @@ GL_APICALL void GL_APIENTRY glFramebufferTexture2DMultisampleIMG (GLenum target, #define GL_CUBIC_MIPMAP_LINEAR_IMG 0x913B #endif /* GL_IMG_texture_filter_cubic */ +#ifndef GL_INTEL_blackhole_render +#define GL_INTEL_blackhole_render 1 +#define GL_BLACKHOLE_RENDER_INTEL 0x83FC +#endif /* GL_INTEL_blackhole_render */ + #ifndef GL_INTEL_conservative_rasterization #define GL_INTEL_conservative_rasterization 1 #define GL_CONSERVATIVE_RASTERIZATION_INTEL 0x83FE @@ -2341,7 +2530,7 @@ typedef void (GL_APIENTRYP PFNGLENDPERFQUERYINTELPROC) (GLuint queryHandle); typedef void (GL_APIENTRYP PFNGLGETFIRSTPERFQUERYIDINTELPROC) (GLuint *queryId); typedef void (GL_APIENTRYP PFNGLGETNEXTPERFQUERYIDINTELPROC) (GLuint queryId, GLuint *nextQueryId); typedef void (GL_APIENTRYP PFNGLGETPERFCOUNTERINFOINTELPROC) (GLuint queryId, GLuint counterId, GLuint counterNameLength, GLchar *counterName, GLuint counterDescLength, GLchar *counterDesc, GLuint *counterOffset, GLuint *counterDataSize, GLuint *counterTypeEnum, GLuint *counterDataTypeEnum, GLuint64 *rawCounterMaxValue); -typedef void (GL_APIENTRYP PFNGLGETPERFQUERYDATAINTELPROC) (GLuint queryHandle, GLuint flags, GLsizei dataSize, GLvoid *data, GLuint *bytesWritten); +typedef void (GL_APIENTRYP PFNGLGETPERFQUERYDATAINTELPROC) (GLuint queryHandle, GLuint flags, GLsizei dataSize, void *data, GLuint *bytesWritten); typedef void (GL_APIENTRYP PFNGLGETPERFQUERYIDBYNAMEINTELPROC) (GLchar *queryName, GLuint *queryId); typedef void (GL_APIENTRYP PFNGLGETPERFQUERYINFOINTELPROC) (GLuint queryId, GLuint queryNameLength, GLchar *queryName, GLuint *dataSize, GLuint *noCounters, GLuint *noInstances, GLuint *capsMask); #ifdef GL_GLEXT_PROTOTYPES @@ -2352,12 +2541,70 @@ GL_APICALL void GL_APIENTRY glEndPerfQueryINTEL (GLuint queryHandle); GL_APICALL void GL_APIENTRY glGetFirstPerfQueryIdINTEL (GLuint *queryId); GL_APICALL void GL_APIENTRY glGetNextPerfQueryIdINTEL (GLuint queryId, GLuint *nextQueryId); GL_APICALL void GL_APIENTRY glGetPerfCounterInfoINTEL (GLuint queryId, GLuint counterId, GLuint counterNameLength, GLchar *counterName, GLuint counterDescLength, GLchar *counterDesc, GLuint *counterOffset, GLuint *counterDataSize, GLuint *counterTypeEnum, GLuint *counterDataTypeEnum, GLuint64 *rawCounterMaxValue); -GL_APICALL void GL_APIENTRY glGetPerfQueryDataINTEL (GLuint queryHandle, GLuint flags, GLsizei dataSize, GLvoid *data, GLuint *bytesWritten); +GL_APICALL void GL_APIENTRY glGetPerfQueryDataINTEL (GLuint queryHandle, GLuint flags, GLsizei dataSize, void *data, GLuint *bytesWritten); GL_APICALL void GL_APIENTRY glGetPerfQueryIdByNameINTEL (GLchar *queryName, GLuint *queryId); GL_APICALL void GL_APIENTRY glGetPerfQueryInfoINTEL (GLuint queryId, GLuint queryNameLength, GLchar *queryName, GLuint *dataSize, GLuint *noCounters, GLuint *noInstances, GLuint *capsMask); #endif #endif /* GL_INTEL_performance_query */ +#ifndef GL_MESA_bgra +#define GL_MESA_bgra 1 +#define GL_BGR_EXT 0x80E0 +#endif /* GL_MESA_bgra */ + +#ifndef GL_MESA_framebuffer_flip_x +#define GL_MESA_framebuffer_flip_x 1 +#define GL_FRAMEBUFFER_FLIP_X_MESA 0x8BBC +#endif /* GL_MESA_framebuffer_flip_x */ + +#ifndef GL_MESA_framebuffer_flip_y +#define GL_MESA_framebuffer_flip_y 1 +#define GL_FRAMEBUFFER_FLIP_Y_MESA 0x8BBB +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERPARAMETERIMESAPROC) (GLenum target, GLenum pname, GLint param); +typedef void (GL_APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVMESAPROC) (GLenum target, GLenum pname, GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glFramebufferParameteriMESA (GLenum target, GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glGetFramebufferParameterivMESA (GLenum target, GLenum pname, GLint *params); +#endif +#endif /* GL_MESA_framebuffer_flip_y */ + +#ifndef GL_MESA_framebuffer_swap_xy +#define GL_MESA_framebuffer_swap_xy 1 +#define GL_FRAMEBUFFER_SWAP_XY_MESA 0x8BBD +#endif /* GL_MESA_framebuffer_swap_xy */ + +#ifndef GL_MESA_program_binary_formats +#define GL_MESA_program_binary_formats 1 +#define GL_PROGRAM_BINARY_FORMAT_MESA 0x875F +#endif /* GL_MESA_program_binary_formats */ + +#ifndef GL_MESA_sampler_objects +#define GL_MESA_sampler_objects 1 +#define GL_SAMPLER_BINDING 0x8919 +typedef void (GL_APIENTRYP PFNGLGENSAMPLERSPROC) (GLsizei count, GLuint *samplers); +typedef void (GL_APIENTRYP PFNGLDELETESAMPLERSPROC) (GLsizei count, const GLuint *samplers); +typedef GLboolean (GL_APIENTRYP PFNGLISSAMPLERPROC) (GLuint sampler); +typedef void (GL_APIENTRYP PFNGLBINDSAMPLERPROC) (GLuint unit, GLuint sampler); +typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIPROC) (GLuint sampler, GLenum pname, GLint param); +typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, const GLint *param); +typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERFPROC) (GLuint sampler, GLenum pname, GLfloat param); +typedef void (GL_APIENTRYP PFNGLSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, const GLfloat *param); +typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, GLfloat *params); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGenSamplers (GLsizei count, GLuint *samplers); +GL_APICALL void GL_APIENTRY glDeleteSamplers (GLsizei count, const GLuint *samplers); +GL_APICALL GLboolean GL_APIENTRY glIsSampler (GLuint sampler); +GL_APICALL void GL_APIENTRY glBindSampler (GLuint unit, GLuint sampler); +GL_APICALL void GL_APIENTRY glSamplerParameteri (GLuint sampler, GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glSamplerParameteriv (GLuint sampler, GLenum pname, const GLint *param); +GL_APICALL void GL_APIENTRY glSamplerParameterf (GLuint sampler, GLenum pname, GLfloat param); +GL_APICALL void GL_APIENTRY glSamplerParameterfv (GLuint sampler, GLenum pname, const GLfloat *param); +GL_APICALL void GL_APIENTRY glGetSamplerParameteriv (GLuint sampler, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetSamplerParameterfv (GLuint sampler, GLenum pname, GLfloat *params); +#endif +#endif /* GL_MESA_sampler_objects */ + #ifndef GL_MESA_shader_integer_functions #define GL_MESA_shader_integer_functions 1 #endif /* GL_MESA_shader_integer_functions */ @@ -2468,6 +2715,21 @@ GL_APICALL void GL_APIENTRY glBlendBarrierNV (void); #define GL_FACTOR_MAX_AMD 0x901D #endif /* GL_NV_blend_minmax_factor */ +#ifndef GL_NV_clip_space_w_scaling +#define GL_NV_clip_space_w_scaling 1 +#define GL_VIEWPORT_POSITION_W_SCALE_NV 0x937C +#define GL_VIEWPORT_POSITION_W_SCALE_X_COEFF_NV 0x937D +#define GL_VIEWPORT_POSITION_W_SCALE_Y_COEFF_NV 0x937E +typedef void (GL_APIENTRYP PFNGLVIEWPORTPOSITIONWSCALENVPROC) (GLuint index, GLfloat xcoeff, GLfloat ycoeff); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glViewportPositionWScaleNV (GLuint index, GLfloat xcoeff, GLfloat ycoeff); +#endif +#endif /* GL_NV_clip_space_w_scaling */ + +#ifndef GL_NV_compute_shader_derivatives +#define GL_NV_compute_shader_derivatives 1 +#endif /* GL_NV_compute_shader_derivatives */ + #ifndef GL_NV_conditional_render #define GL_NV_conditional_render 1 #define GL_QUERY_WAIT_NV 0x8E13 @@ -2494,6 +2756,11 @@ GL_APICALL void GL_APIENTRY glSubpixelPrecisionBiasNV (GLuint xbits, GLuint ybit #endif #endif /* GL_NV_conservative_raster */ +#ifndef GL_NV_conservative_raster_pre_snap +#define GL_NV_conservative_raster_pre_snap 1 +#define GL_CONSERVATIVE_RASTER_MODE_PRE_SNAP_NV 0x9550 +#endif /* GL_NV_conservative_raster_pre_snap */ + #ifndef GL_NV_conservative_raster_pre_snap_triangles #define GL_NV_conservative_raster_pre_snap_triangles 1 #define GL_CONSERVATIVE_RASTER_MODE_NV 0x954D @@ -2654,6 +2921,10 @@ GL_APICALL void GL_APIENTRY glFragmentCoverageColorNV (GLuint color); #endif #endif /* GL_NV_fragment_coverage_to_color */ +#ifndef GL_NV_fragment_shader_barycentric +#define GL_NV_fragment_shader_barycentric 1 +#endif /* GL_NV_fragment_shader_barycentric */ + #ifndef GL_NV_fragment_shader_interlock #define GL_NV_fragment_shader_interlock 1 #endif /* GL_NV_fragment_shader_interlock */ @@ -2681,11 +2952,11 @@ GL_APICALL void GL_APIENTRY glBlitFramebufferNV (GLint srcX0, GLint srcY0, GLint #define GL_COVERAGE_MODULATION_NV 0x9332 #define GL_COVERAGE_MODULATION_TABLE_SIZE_NV 0x9333 typedef void (GL_APIENTRYP PFNGLCOVERAGEMODULATIONTABLENVPROC) (GLsizei n, const GLfloat *v); -typedef void (GL_APIENTRYP PFNGLGETCOVERAGEMODULATIONTABLENVPROC) (GLsizei bufsize, GLfloat *v); +typedef void (GL_APIENTRYP PFNGLGETCOVERAGEMODULATIONTABLENVPROC) (GLsizei bufSize, GLfloat *v); typedef void (GL_APIENTRYP PFNGLCOVERAGEMODULATIONNVPROC) (GLenum components); #ifdef GL_GLEXT_PROTOTYPES GL_APICALL void GL_APIENTRY glCoverageModulationTableNV (GLsizei n, const GLfloat *v); -GL_APICALL void GL_APIENTRY glGetCoverageModulationTableNV (GLsizei bufsize, GLfloat *v); +GL_APICALL void GL_APIENTRY glGetCoverageModulationTableNV (GLsizei bufSize, GLfloat *v); GL_APICALL void GL_APIENTRY glCoverageModulationNV (GLenum components); #endif #endif /* GL_NV_framebuffer_mixed_samples */ @@ -2833,12 +3104,116 @@ GL_APICALL void GL_APIENTRY glVertexAttribDivisorNV (GLuint index, GLuint diviso #define GL_SUPERSAMPLE_SCALE_X_NV 0x9372 #define GL_SUPERSAMPLE_SCALE_Y_NV 0x9373 #define GL_CONFORMANT_NV 0x9374 -typedef void (GL_APIENTRYP PFNGLGETINTERNALFORMATSAMPLEIVNVPROC) (GLenum target, GLenum internalformat, GLsizei samples, GLenum pname, GLsizei bufSize, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETINTERNALFORMATSAMPLEIVNVPROC) (GLenum target, GLenum internalformat, GLsizei samples, GLenum pname, GLsizei count, GLint *params); #ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glGetInternalformatSampleivNV (GLenum target, GLenum internalformat, GLsizei samples, GLenum pname, GLsizei bufSize, GLint *params); +GL_APICALL void GL_APIENTRY glGetInternalformatSampleivNV (GLenum target, GLenum internalformat, GLsizei samples, GLenum pname, GLsizei count, GLint *params); #endif #endif /* GL_NV_internalformat_sample_query */ +#ifndef GL_NV_memory_attachment +#define GL_NV_memory_attachment 1 +#define GL_ATTACHED_MEMORY_OBJECT_NV 0x95A4 +#define GL_ATTACHED_MEMORY_OFFSET_NV 0x95A5 +#define GL_MEMORY_ATTACHABLE_ALIGNMENT_NV 0x95A6 +#define GL_MEMORY_ATTACHABLE_SIZE_NV 0x95A7 +#define GL_MEMORY_ATTACHABLE_NV 0x95A8 +#define GL_DETACHED_MEMORY_INCARNATION_NV 0x95A9 +#define GL_DETACHED_TEXTURES_NV 0x95AA +#define GL_DETACHED_BUFFERS_NV 0x95AB +#define GL_MAX_DETACHED_TEXTURES_NV 0x95AC +#define GL_MAX_DETACHED_BUFFERS_NV 0x95AD +typedef void (GL_APIENTRYP PFNGLGETMEMORYOBJECTDETACHEDRESOURCESUIVNVPROC) (GLuint memory, GLenum pname, GLint first, GLsizei count, GLuint *params); +typedef void (GL_APIENTRYP PFNGLRESETMEMORYOBJECTPARAMETERNVPROC) (GLuint memory, GLenum pname); +typedef void (GL_APIENTRYP PFNGLTEXATTACHMEMORYNVPROC) (GLenum target, GLuint memory, GLuint64 offset); +typedef void (GL_APIENTRYP PFNGLBUFFERATTACHMEMORYNVPROC) (GLenum target, GLuint memory, GLuint64 offset); +typedef void (GL_APIENTRYP PFNGLTEXTUREATTACHMEMORYNVPROC) (GLuint texture, GLuint memory, GLuint64 offset); +typedef void (GL_APIENTRYP PFNGLNAMEDBUFFERATTACHMEMORYNVPROC) (GLuint buffer, GLuint memory, GLuint64 offset); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGetMemoryObjectDetachedResourcesuivNV (GLuint memory, GLenum pname, GLint first, GLsizei count, GLuint *params); +GL_APICALL void GL_APIENTRY glResetMemoryObjectParameterNV (GLuint memory, GLenum pname); +GL_APICALL void GL_APIENTRY glTexAttachMemoryNV (GLenum target, GLuint memory, GLuint64 offset); +GL_APICALL void GL_APIENTRY glBufferAttachMemoryNV (GLenum target, GLuint memory, GLuint64 offset); +GL_APICALL void GL_APIENTRY glTextureAttachMemoryNV (GLuint texture, GLuint memory, GLuint64 offset); +GL_APICALL void GL_APIENTRY glNamedBufferAttachMemoryNV (GLuint buffer, GLuint memory, GLuint64 offset); +#endif +#endif /* GL_NV_memory_attachment */ + +#ifndef GL_NV_memory_object_sparse +#define GL_NV_memory_object_sparse 1 +typedef void (GL_APIENTRYP PFNGLBUFFERPAGECOMMITMENTMEMNVPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLuint memory, GLuint64 memOffset, GLboolean commit); +typedef void (GL_APIENTRYP PFNGLTEXPAGECOMMITMENTMEMNVPROC) (GLenum target, GLint layer, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset, GLboolean commit); +typedef void (GL_APIENTRYP PFNGLNAMEDBUFFERPAGECOMMITMENTMEMNVPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, GLuint memory, GLuint64 memOffset, GLboolean commit); +typedef void (GL_APIENTRYP PFNGLTEXTUREPAGECOMMITMENTMEMNVPROC) (GLuint texture, GLint layer, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset, GLboolean commit); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glBufferPageCommitmentMemNV (GLenum target, GLintptr offset, GLsizeiptr size, GLuint memory, GLuint64 memOffset, GLboolean commit); +GL_APICALL void GL_APIENTRY glTexPageCommitmentMemNV (GLenum target, GLint layer, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset, GLboolean commit); +GL_APICALL void GL_APIENTRY glNamedBufferPageCommitmentMemNV (GLuint buffer, GLintptr offset, GLsizeiptr size, GLuint memory, GLuint64 memOffset, GLboolean commit); +GL_APICALL void GL_APIENTRY glTexturePageCommitmentMemNV (GLuint texture, GLint layer, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset, GLboolean commit); +#endif +#endif /* GL_NV_memory_object_sparse */ + +#ifndef GL_NV_mesh_shader +#define GL_NV_mesh_shader 1 +#define GL_MESH_SHADER_NV 0x9559 +#define GL_TASK_SHADER_NV 0x955A +#define GL_MAX_MESH_UNIFORM_BLOCKS_NV 0x8E60 +#define GL_MAX_MESH_TEXTURE_IMAGE_UNITS_NV 0x8E61 +#define GL_MAX_MESH_IMAGE_UNIFORMS_NV 0x8E62 +#define GL_MAX_MESH_UNIFORM_COMPONENTS_NV 0x8E63 +#define GL_MAX_MESH_ATOMIC_COUNTER_BUFFERS_NV 0x8E64 +#define GL_MAX_MESH_ATOMIC_COUNTERS_NV 0x8E65 +#define GL_MAX_MESH_SHADER_STORAGE_BLOCKS_NV 0x8E66 +#define GL_MAX_COMBINED_MESH_UNIFORM_COMPONENTS_NV 0x8E67 +#define GL_MAX_TASK_UNIFORM_BLOCKS_NV 0x8E68 +#define GL_MAX_TASK_TEXTURE_IMAGE_UNITS_NV 0x8E69 +#define GL_MAX_TASK_IMAGE_UNIFORMS_NV 0x8E6A +#define GL_MAX_TASK_UNIFORM_COMPONENTS_NV 0x8E6B +#define GL_MAX_TASK_ATOMIC_COUNTER_BUFFERS_NV 0x8E6C +#define GL_MAX_TASK_ATOMIC_COUNTERS_NV 0x8E6D +#define GL_MAX_TASK_SHADER_STORAGE_BLOCKS_NV 0x8E6E +#define GL_MAX_COMBINED_TASK_UNIFORM_COMPONENTS_NV 0x8E6F +#define GL_MAX_MESH_WORK_GROUP_INVOCATIONS_NV 0x95A2 +#define GL_MAX_TASK_WORK_GROUP_INVOCATIONS_NV 0x95A3 +#define GL_MAX_MESH_TOTAL_MEMORY_SIZE_NV 0x9536 +#define GL_MAX_TASK_TOTAL_MEMORY_SIZE_NV 0x9537 +#define GL_MAX_MESH_OUTPUT_VERTICES_NV 0x9538 +#define GL_MAX_MESH_OUTPUT_PRIMITIVES_NV 0x9539 +#define GL_MAX_TASK_OUTPUT_COUNT_NV 0x953A +#define GL_MAX_DRAW_MESH_TASKS_COUNT_NV 0x953D +#define GL_MAX_MESH_VIEWS_NV 0x9557 +#define GL_MESH_OUTPUT_PER_VERTEX_GRANULARITY_NV 0x92DF +#define GL_MESH_OUTPUT_PER_PRIMITIVE_GRANULARITY_NV 0x9543 +#define GL_MAX_MESH_WORK_GROUP_SIZE_NV 0x953B +#define GL_MAX_TASK_WORK_GROUP_SIZE_NV 0x953C +#define GL_MESH_WORK_GROUP_SIZE_NV 0x953E +#define GL_TASK_WORK_GROUP_SIZE_NV 0x953F +#define GL_MESH_VERTICES_OUT_NV 0x9579 +#define GL_MESH_PRIMITIVES_OUT_NV 0x957A +#define GL_MESH_OUTPUT_TYPE_NV 0x957B +#define GL_UNIFORM_BLOCK_REFERENCED_BY_MESH_SHADER_NV 0x959C +#define GL_UNIFORM_BLOCK_REFERENCED_BY_TASK_SHADER_NV 0x959D +#define GL_REFERENCED_BY_MESH_SHADER_NV 0x95A0 +#define GL_REFERENCED_BY_TASK_SHADER_NV 0x95A1 +#define GL_MESH_SHADER_BIT_NV 0x00000040 +#define GL_TASK_SHADER_BIT_NV 0x00000080 +#define GL_MESH_SUBROUTINE_NV 0x957C +#define GL_TASK_SUBROUTINE_NV 0x957D +#define GL_MESH_SUBROUTINE_UNIFORM_NV 0x957E +#define GL_TASK_SUBROUTINE_UNIFORM_NV 0x957F +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_MESH_SHADER_NV 0x959E +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TASK_SHADER_NV 0x959F +typedef void (GL_APIENTRYP PFNGLDRAWMESHTASKSNVPROC) (GLuint first, GLuint count); +typedef void (GL_APIENTRYP PFNGLDRAWMESHTASKSINDIRECTNVPROC) (GLintptr indirect); +typedef void (GL_APIENTRYP PFNGLMULTIDRAWMESHTASKSINDIRECTNVPROC) (GLintptr indirect, GLsizei drawcount, GLsizei stride); +typedef void (GL_APIENTRYP PFNGLMULTIDRAWMESHTASKSINDIRECTCOUNTNVPROC) (GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDrawMeshTasksNV (GLuint first, GLuint count); +GL_APICALL void GL_APIENTRY glDrawMeshTasksIndirectNV (GLintptr indirect); +GL_APICALL void GL_APIENTRY glMultiDrawMeshTasksIndirectNV (GLintptr indirect, GLsizei drawcount, GLsizei stride); +GL_APICALL void GL_APIENTRY glMultiDrawMeshTasksIndirectCountNV (GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); +#endif +#endif /* GL_NV_mesh_shader */ + #ifndef GL_NV_non_square_matrices #define GL_NV_non_square_matrices 1 #define GL_FLOAT_MAT2x3_NV 0x8B65 @@ -2863,8 +3238,16 @@ GL_APICALL void GL_APIENTRY glUniformMatrix4x3fvNV (GLint location, GLsizei coun #endif #endif /* GL_NV_non_square_matrices */ +#ifndef GL_NV_pack_subimage +#define GL_NV_pack_subimage 1 +#define GL_PACK_ROW_LENGTH_NV 0x0D02 +#define GL_PACK_SKIP_ROWS_NV 0x0D03 +#define GL_PACK_SKIP_PIXELS_NV 0x0D04 +#endif /* GL_NV_pack_subimage */ + #ifndef GL_NV_path_rendering #define GL_NV_path_rendering 1 +typedef double GLdouble; #define GL_PATH_FORMAT_SVG_NV 0x9070 #define GL_PATH_FORMAT_PS_NV 0x9071 #define GL_STANDARD_FONT_NAME_NV 0x9072 @@ -3070,11 +3453,30 @@ typedef void (GL_APIENTRYP PFNGLSTENCILTHENCOVERFILLPATHNVPROC) (GLuint path, GL typedef void (GL_APIENTRYP PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC) (GLuint path, GLint reference, GLuint mask, GLenum coverMode); typedef void (GL_APIENTRYP PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); typedef void (GL_APIENTRYP PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); -typedef GLenum (GL_APIENTRYP PFNGLPATHGLYPHINDEXRANGENVPROC) (GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint pathParameterTemplate, GLfloat emScale, GLuint baseAndCount[2]); +typedef GLenum (GL_APIENTRYP PFNGLPATHGLYPHINDEXRANGENVPROC) (GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint pathParameterTemplate, GLfloat emScale, GLuint *baseAndCount); typedef GLenum (GL_APIENTRYP PFNGLPATHGLYPHINDEXARRAYNVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); typedef GLenum (GL_APIENTRYP PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC) (GLuint firstPathName, GLenum fontTarget, GLsizeiptr fontSize, const void *fontData, GLsizei faceIndex, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); typedef void (GL_APIENTRYP PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC) (GLuint program, GLint location, GLenum genMode, GLint components, const GLfloat *coeffs); -typedef void (GL_APIENTRYP PFNGLGETPROGRAMRESOURCEFVNVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLfloat *params); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMRESOURCEFVNVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei count, GLsizei *length, GLfloat *params); +typedef void (GL_APIENTRYP PFNGLMATRIXFRUSTUMEXTPROC) (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +typedef void (GL_APIENTRYP PFNGLMATRIXLOADIDENTITYEXTPROC) (GLenum mode); +typedef void (GL_APIENTRYP PFNGLMATRIXLOADTRANSPOSEFEXTPROC) (GLenum mode, const GLfloat *m); +typedef void (GL_APIENTRYP PFNGLMATRIXLOADTRANSPOSEDEXTPROC) (GLenum mode, const GLdouble *m); +typedef void (GL_APIENTRYP PFNGLMATRIXLOADFEXTPROC) (GLenum mode, const GLfloat *m); +typedef void (GL_APIENTRYP PFNGLMATRIXLOADDEXTPROC) (GLenum mode, const GLdouble *m); +typedef void (GL_APIENTRYP PFNGLMATRIXMULTTRANSPOSEFEXTPROC) (GLenum mode, const GLfloat *m); +typedef void (GL_APIENTRYP PFNGLMATRIXMULTTRANSPOSEDEXTPROC) (GLenum mode, const GLdouble *m); +typedef void (GL_APIENTRYP PFNGLMATRIXMULTFEXTPROC) (GLenum mode, const GLfloat *m); +typedef void (GL_APIENTRYP PFNGLMATRIXMULTDEXTPROC) (GLenum mode, const GLdouble *m); +typedef void (GL_APIENTRYP PFNGLMATRIXORTHOEXTPROC) (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +typedef void (GL_APIENTRYP PFNGLMATRIXPOPEXTPROC) (GLenum mode); +typedef void (GL_APIENTRYP PFNGLMATRIXPUSHEXTPROC) (GLenum mode); +typedef void (GL_APIENTRYP PFNGLMATRIXROTATEFEXTPROC) (GLenum mode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z); +typedef void (GL_APIENTRYP PFNGLMATRIXROTATEDEXTPROC) (GLenum mode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z); +typedef void (GL_APIENTRYP PFNGLMATRIXSCALEFEXTPROC) (GLenum mode, GLfloat x, GLfloat y, GLfloat z); +typedef void (GL_APIENTRYP PFNGLMATRIXSCALEDEXTPROC) (GLenum mode, GLdouble x, GLdouble y, GLdouble z); +typedef void (GL_APIENTRYP PFNGLMATRIXTRANSLATEFEXTPROC) (GLenum mode, GLfloat x, GLfloat y, GLfloat z); +typedef void (GL_APIENTRYP PFNGLMATRIXTRANSLATEDEXTPROC) (GLenum mode, GLdouble x, GLdouble y, GLdouble z); #ifdef GL_GLEXT_PROTOTYPES GL_APICALL GLuint GL_APIENTRY glGenPathsNV (GLsizei range); GL_APICALL void GL_APIENTRY glDeletePathsNV (GLuint path, GLsizei range); @@ -3128,11 +3530,30 @@ GL_APICALL void GL_APIENTRY glStencilThenCoverFillPathNV (GLuint path, GLenum fi GL_APICALL void GL_APIENTRY glStencilThenCoverStrokePathNV (GLuint path, GLint reference, GLuint mask, GLenum coverMode); GL_APICALL void GL_APIENTRY glStencilThenCoverFillPathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); GL_APICALL void GL_APIENTRY glStencilThenCoverStrokePathInstancedNV (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); -GL_APICALL GLenum GL_APIENTRY glPathGlyphIndexRangeNV (GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint pathParameterTemplate, GLfloat emScale, GLuint baseAndCount[2]); +GL_APICALL GLenum GL_APIENTRY glPathGlyphIndexRangeNV (GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint pathParameterTemplate, GLfloat emScale, GLuint *baseAndCount); GL_APICALL GLenum GL_APIENTRY glPathGlyphIndexArrayNV (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); GL_APICALL GLenum GL_APIENTRY glPathMemoryGlyphIndexArrayNV (GLuint firstPathName, GLenum fontTarget, GLsizeiptr fontSize, const void *fontData, GLsizei faceIndex, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); GL_APICALL void GL_APIENTRY glProgramPathFragmentInputGenNV (GLuint program, GLint location, GLenum genMode, GLint components, const GLfloat *coeffs); -GL_APICALL void GL_APIENTRY glGetProgramResourcefvNV (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLfloat *params); +GL_APICALL void GL_APIENTRY glGetProgramResourcefvNV (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei count, GLsizei *length, GLfloat *params); +GL_APICALL void GL_APIENTRY glMatrixFrustumEXT (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +GL_APICALL void GL_APIENTRY glMatrixLoadIdentityEXT (GLenum mode); +GL_APICALL void GL_APIENTRY glMatrixLoadTransposefEXT (GLenum mode, const GLfloat *m); +GL_APICALL void GL_APIENTRY glMatrixLoadTransposedEXT (GLenum mode, const GLdouble *m); +GL_APICALL void GL_APIENTRY glMatrixLoadfEXT (GLenum mode, const GLfloat *m); +GL_APICALL void GL_APIENTRY glMatrixLoaddEXT (GLenum mode, const GLdouble *m); +GL_APICALL void GL_APIENTRY glMatrixMultTransposefEXT (GLenum mode, const GLfloat *m); +GL_APICALL void GL_APIENTRY glMatrixMultTransposedEXT (GLenum mode, const GLdouble *m); +GL_APICALL void GL_APIENTRY glMatrixMultfEXT (GLenum mode, const GLfloat *m); +GL_APICALL void GL_APIENTRY glMatrixMultdEXT (GLenum mode, const GLdouble *m); +GL_APICALL void GL_APIENTRY glMatrixOrthoEXT (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +GL_APICALL void GL_APIENTRY glMatrixPopEXT (GLenum mode); +GL_APICALL void GL_APIENTRY glMatrixPushEXT (GLenum mode); +GL_APICALL void GL_APIENTRY glMatrixRotatefEXT (GLenum mode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z); +GL_APICALL void GL_APIENTRY glMatrixRotatedEXT (GLenum mode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z); +GL_APICALL void GL_APIENTRY glMatrixScalefEXT (GLenum mode, GLfloat x, GLfloat y, GLfloat z); +GL_APICALL void GL_APIENTRY glMatrixScaledEXT (GLenum mode, GLdouble x, GLdouble y, GLdouble z); +GL_APICALL void GL_APIENTRY glMatrixTranslatefEXT (GLenum mode, GLfloat x, GLfloat y, GLfloat z); +GL_APICALL void GL_APIENTRY glMatrixTranslatedEXT (GLenum mode, GLdouble x, GLdouble y, GLdouble z); #endif #endif /* GL_NV_path_rendering */ @@ -3163,6 +3584,12 @@ GL_APICALL void GL_APIENTRY glPolygonModeNV (GLenum face, GLenum mode); #endif #endif /* GL_NV_polygon_mode */ +#ifndef GL_NV_primitive_shading_rate +#define GL_NV_primitive_shading_rate 1 +#define GL_SHADING_RATE_IMAGE_PER_PRIMITIVE_NV 0x95B1 +#define GL_SHADING_RATE_IMAGE_PALETTE_COUNT_NV 0x95B2 +#endif /* GL_NV_primitive_shading_rate */ + #ifndef GL_NV_read_buffer #define GL_NV_read_buffer 1 #define GL_READ_BUFFER_NV 0x0C02 @@ -3188,6 +3615,11 @@ GL_APICALL void GL_APIENTRY glReadBufferNV (GLenum mode); #define GL_NV_read_stencil 1 #endif /* GL_NV_read_stencil */ +#ifndef GL_NV_representative_fragment_test +#define GL_NV_representative_fragment_test 1 +#define GL_REPRESENTATIVE_FRAGMENT_TEST_NV 0x937F +#endif /* GL_NV_representative_fragment_test */ + #ifndef GL_NV_sRGB_formats #define GL_NV_sRGB_formats 1 #define GL_SLUMINANCE_NV 0x8C46 @@ -3226,6 +3658,18 @@ GL_APICALL void GL_APIENTRY glResolveDepthValuesNV (void); #define GL_NV_sample_mask_override_coverage 1 #endif /* GL_NV_sample_mask_override_coverage */ +#ifndef GL_NV_scissor_exclusive +#define GL_NV_scissor_exclusive 1 +#define GL_SCISSOR_TEST_EXCLUSIVE_NV 0x9555 +#define GL_SCISSOR_BOX_EXCLUSIVE_NV 0x9556 +typedef void (GL_APIENTRYP PFNGLSCISSOREXCLUSIVENVPROC) (GLint x, GLint y, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLSCISSOREXCLUSIVEARRAYVNVPROC) (GLuint first, GLsizei count, const GLint *v); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glScissorExclusiveNV (GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glScissorExclusiveArrayvNV (GLuint first, GLsizei count, const GLint *v); +#endif +#endif /* GL_NV_scissor_exclusive */ + #ifndef GL_NV_shader_atomic_fp16_vector #define GL_NV_shader_atomic_fp16_vector 1 #endif /* GL_NV_shader_atomic_fp16_vector */ @@ -3234,6 +3678,56 @@ GL_APICALL void GL_APIENTRY glResolveDepthValuesNV (void); #define GL_NV_shader_noperspective_interpolation 1 #endif /* GL_NV_shader_noperspective_interpolation */ +#ifndef GL_NV_shader_subgroup_partitioned +#define GL_NV_shader_subgroup_partitioned 1 +#define GL_SUBGROUP_FEATURE_PARTITIONED_BIT_NV 0x00000100 +#endif /* GL_NV_shader_subgroup_partitioned */ + +#ifndef GL_NV_shader_texture_footprint +#define GL_NV_shader_texture_footprint 1 +#endif /* GL_NV_shader_texture_footprint */ + +#ifndef GL_NV_shading_rate_image +#define GL_NV_shading_rate_image 1 +#define GL_SHADING_RATE_IMAGE_NV 0x9563 +#define GL_SHADING_RATE_NO_INVOCATIONS_NV 0x9564 +#define GL_SHADING_RATE_1_INVOCATION_PER_PIXEL_NV 0x9565 +#define GL_SHADING_RATE_1_INVOCATION_PER_1X2_PIXELS_NV 0x9566 +#define GL_SHADING_RATE_1_INVOCATION_PER_2X1_PIXELS_NV 0x9567 +#define GL_SHADING_RATE_1_INVOCATION_PER_2X2_PIXELS_NV 0x9568 +#define GL_SHADING_RATE_1_INVOCATION_PER_2X4_PIXELS_NV 0x9569 +#define GL_SHADING_RATE_1_INVOCATION_PER_4X2_PIXELS_NV 0x956A +#define GL_SHADING_RATE_1_INVOCATION_PER_4X4_PIXELS_NV 0x956B +#define GL_SHADING_RATE_2_INVOCATIONS_PER_PIXEL_NV 0x956C +#define GL_SHADING_RATE_4_INVOCATIONS_PER_PIXEL_NV 0x956D +#define GL_SHADING_RATE_8_INVOCATIONS_PER_PIXEL_NV 0x956E +#define GL_SHADING_RATE_16_INVOCATIONS_PER_PIXEL_NV 0x956F +#define GL_SHADING_RATE_IMAGE_BINDING_NV 0x955B +#define GL_SHADING_RATE_IMAGE_TEXEL_WIDTH_NV 0x955C +#define GL_SHADING_RATE_IMAGE_TEXEL_HEIGHT_NV 0x955D +#define GL_SHADING_RATE_IMAGE_PALETTE_SIZE_NV 0x955E +#define GL_MAX_COARSE_FRAGMENT_SAMPLES_NV 0x955F +#define GL_SHADING_RATE_SAMPLE_ORDER_DEFAULT_NV 0x95AE +#define GL_SHADING_RATE_SAMPLE_ORDER_PIXEL_MAJOR_NV 0x95AF +#define GL_SHADING_RATE_SAMPLE_ORDER_SAMPLE_MAJOR_NV 0x95B0 +typedef void (GL_APIENTRYP PFNGLBINDSHADINGRATEIMAGENVPROC) (GLuint texture); +typedef void (GL_APIENTRYP PFNGLGETSHADINGRATEIMAGEPALETTENVPROC) (GLuint viewport, GLuint entry, GLenum *rate); +typedef void (GL_APIENTRYP PFNGLGETSHADINGRATESAMPLELOCATIONIVNVPROC) (GLenum rate, GLuint samples, GLuint index, GLint *location); +typedef void (GL_APIENTRYP PFNGLSHADINGRATEIMAGEBARRIERNVPROC) (GLboolean synchronize); +typedef void (GL_APIENTRYP PFNGLSHADINGRATEIMAGEPALETTENVPROC) (GLuint viewport, GLuint first, GLsizei count, const GLenum *rates); +typedef void (GL_APIENTRYP PFNGLSHADINGRATESAMPLEORDERNVPROC) (GLenum order); +typedef void (GL_APIENTRYP PFNGLSHADINGRATESAMPLEORDERCUSTOMNVPROC) (GLenum rate, GLuint samples, const GLint *locations); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glBindShadingRateImageNV (GLuint texture); +GL_APICALL void GL_APIENTRY glGetShadingRateImagePaletteNV (GLuint viewport, GLuint entry, GLenum *rate); +GL_APICALL void GL_APIENTRY glGetShadingRateSampleLocationivNV (GLenum rate, GLuint samples, GLuint index, GLint *location); +GL_APICALL void GL_APIENTRY glShadingRateImageBarrierNV (GLboolean synchronize); +GL_APICALL void GL_APIENTRY glShadingRateImagePaletteNV (GLuint viewport, GLuint first, GLsizei count, const GLenum *rates); +GL_APICALL void GL_APIENTRY glShadingRateSampleOrderNV (GLenum order); +GL_APICALL void GL_APIENTRY glShadingRateSampleOrderCustomNV (GLenum rate, GLuint samples, const GLint *locations); +#endif +#endif /* GL_NV_shading_rate_image */ + #ifndef GL_NV_shadow_samplers_array #define GL_NV_shadow_samplers_array 1 #define GL_SAMPLER_2D_ARRAY_SHADOW_NV 0x8DC4 @@ -3244,6 +3738,10 @@ GL_APICALL void GL_APIENTRY glResolveDepthValuesNV (void); #define GL_SAMPLER_CUBE_SHADOW_NV 0x8DC5 #endif /* GL_NV_shadow_samplers_cube */ +#ifndef GL_NV_stereo_view_rendering +#define GL_NV_stereo_view_rendering 1 +#endif /* GL_NV_stereo_view_rendering */ + #ifndef GL_NV_texture_border_clamp #define GL_NV_texture_border_clamp 1 #define GL_TEXTURE_BORDER_COLOR_NV 0x1004 @@ -3258,6 +3756,23 @@ GL_APICALL void GL_APIENTRY glResolveDepthValuesNV (void); #define GL_NV_texture_npot_2D_mipmap 1 #endif /* GL_NV_texture_npot_2D_mipmap */ +#ifndef GL_NV_timeline_semaphore +#define GL_NV_timeline_semaphore 1 +#define GL_TIMELINE_SEMAPHORE_VALUE_NV 0x9595 +#define GL_SEMAPHORE_TYPE_NV 0x95B3 +#define GL_SEMAPHORE_TYPE_BINARY_NV 0x95B4 +#define GL_SEMAPHORE_TYPE_TIMELINE_NV 0x95B5 +#define GL_MAX_TIMELINE_SEMAPHORE_VALUE_DIFFERENCE_NV 0x95B6 +typedef void (GL_APIENTRYP PFNGLCREATESEMAPHORESNVPROC) (GLsizei n, GLuint *semaphores); +typedef void (GL_APIENTRYP PFNGLSEMAPHOREPARAMETERIVNVPROC) (GLuint semaphore, GLenum pname, const GLint *params); +typedef void (GL_APIENTRYP PFNGLGETSEMAPHOREPARAMETERIVNVPROC) (GLuint semaphore, GLenum pname, GLint *params); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glCreateSemaphoresNV (GLsizei n, GLuint *semaphores); +GL_APICALL void GL_APIENTRY glSemaphoreParameterivNV (GLuint semaphore, GLenum pname, const GLint *params); +GL_APICALL void GL_APIENTRY glGetSemaphoreParameterivNV (GLuint semaphore, GLenum pname, GLint *params); +#endif +#endif /* GL_NV_timeline_semaphore */ + #ifndef GL_NV_viewport_array #define GL_NV_viewport_array 1 #define GL_MAX_VIEWPORTS_NV 0x825B @@ -3340,6 +3855,10 @@ GL_APICALL void GL_APIENTRY glFramebufferTextureMultisampleMultiviewOVR (GLenum #endif #endif /* GL_OVR_multiview_multisampled_render_to_texture */ +#ifndef GL_QCOM_YUV_texture_gather +#define GL_QCOM_YUV_texture_gather 1 +#endif /* GL_QCOM_YUV_texture_gather */ + #ifndef GL_QCOM_alpha_test #define GL_QCOM_alpha_test 1 #define GL_ALPHA_TEST_QCOM 0x0BC0 @@ -3420,6 +3939,14 @@ GL_APICALL void GL_APIENTRY glExtGetProgramBinarySourceQCOM (GLuint program, GLe #endif #endif /* GL_QCOM_extended_get2 */ +#ifndef GL_QCOM_frame_extrapolation +#define GL_QCOM_frame_extrapolation 1 +typedef void (GL_APIENTRYP PFNGLEXTRAPOLATETEX2DQCOMPROC) (GLuint src1, GLuint src2, GLuint output, GLfloat scaleFactor); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glExtrapolateTex2DQCOM (GLuint src1, GLuint src2, GLuint output, GLfloat scaleFactor); +#endif +#endif /* GL_QCOM_frame_extrapolation */ + #ifndef GL_QCOM_framebuffer_foveated #define GL_QCOM_framebuffer_foveated 1 #define GL_FOVEATION_ENABLE_BIT_QCOM 0x00000001 @@ -3432,11 +3959,31 @@ GL_APICALL void GL_APIENTRY glFramebufferFoveationParametersQCOM (GLuint framebu #endif #endif /* GL_QCOM_framebuffer_foveated */ +#ifndef GL_QCOM_motion_estimation +#define GL_QCOM_motion_estimation 1 +#define GL_MOTION_ESTIMATION_SEARCH_BLOCK_X_QCOM 0x8C90 +#define GL_MOTION_ESTIMATION_SEARCH_BLOCK_Y_QCOM 0x8C91 +typedef void (GL_APIENTRYP PFNGLTEXESTIMATEMOTIONQCOMPROC) (GLuint ref, GLuint target, GLuint output); +typedef void (GL_APIENTRYP PFNGLTEXESTIMATEMOTIONREGIONSQCOMPROC) (GLuint ref, GLuint target, GLuint output, GLuint mask); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glTexEstimateMotionQCOM (GLuint ref, GLuint target, GLuint output); +GL_APICALL void GL_APIENTRY glTexEstimateMotionRegionsQCOM (GLuint ref, GLuint target, GLuint output, GLuint mask); +#endif +#endif /* GL_QCOM_motion_estimation */ + #ifndef GL_QCOM_perfmon_global_mode #define GL_QCOM_perfmon_global_mode 1 #define GL_PERFMON_GLOBAL_MODE_QCOM 0x8FA0 #endif /* GL_QCOM_perfmon_global_mode */ +#ifndef GL_QCOM_render_sRGB_R8_RG8 +#define GL_QCOM_render_sRGB_R8_RG8 1 +#endif /* GL_QCOM_render_sRGB_R8_RG8 */ + +#ifndef GL_QCOM_render_shared_exponent +#define GL_QCOM_render_shared_exponent 1 +#endif /* GL_QCOM_render_shared_exponent */ + #ifndef GL_QCOM_shader_framebuffer_fetch_noncoherent #define GL_QCOM_shader_framebuffer_fetch_noncoherent 1 #define GL_FRAMEBUFFER_FETCH_NONCOHERENT_QCOM 0x96A2 @@ -3446,6 +3993,55 @@ GL_APICALL void GL_APIENTRY glFramebufferFetchBarrierQCOM (void); #endif #endif /* GL_QCOM_shader_framebuffer_fetch_noncoherent */ +#ifndef GL_QCOM_shader_framebuffer_fetch_rate +#define GL_QCOM_shader_framebuffer_fetch_rate 1 +#endif /* GL_QCOM_shader_framebuffer_fetch_rate */ + +#ifndef GL_QCOM_shading_rate +#define GL_QCOM_shading_rate 1 +#define GL_SHADING_RATE_QCOM 0x96A4 +#define GL_SHADING_RATE_PRESERVE_ASPECT_RATIO_QCOM 0x96A5 +#define GL_SHADING_RATE_1X1_PIXELS_QCOM 0x96A6 +#define GL_SHADING_RATE_1X2_PIXELS_QCOM 0x96A7 +#define GL_SHADING_RATE_2X1_PIXELS_QCOM 0x96A8 +#define GL_SHADING_RATE_2X2_PIXELS_QCOM 0x96A9 +#define GL_SHADING_RATE_4X2_PIXELS_QCOM 0x96AC +#define GL_SHADING_RATE_4X4_PIXELS_QCOM 0x96AE +typedef void (GL_APIENTRYP PFNGLSHADINGRATEQCOMPROC) (GLenum rate); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glShadingRateQCOM (GLenum rate); +#endif +#endif /* GL_QCOM_shading_rate */ + +#ifndef GL_QCOM_texture_foveated +#define GL_QCOM_texture_foveated 1 +#define GL_TEXTURE_FOVEATED_FEATURE_BITS_QCOM 0x8BFB +#define GL_TEXTURE_FOVEATED_MIN_PIXEL_DENSITY_QCOM 0x8BFC +#define GL_TEXTURE_FOVEATED_FEATURE_QUERY_QCOM 0x8BFD +#define GL_TEXTURE_FOVEATED_NUM_FOCAL_POINTS_QUERY_QCOM 0x8BFE +#define GL_FRAMEBUFFER_INCOMPLETE_FOVEATION_QCOM 0x8BFF +typedef void (GL_APIENTRYP PFNGLTEXTUREFOVEATIONPARAMETERSQCOMPROC) (GLuint texture, GLuint layer, GLuint focalPoint, GLfloat focalX, GLfloat focalY, GLfloat gainX, GLfloat gainY, GLfloat foveaArea); +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glTextureFoveationParametersQCOM (GLuint texture, GLuint layer, GLuint focalPoint, GLfloat focalX, GLfloat focalY, GLfloat gainX, GLfloat gainY, GLfloat foveaArea); +#endif +#endif /* GL_QCOM_texture_foveated */ + +#ifndef GL_QCOM_texture_foveated2 +#define GL_QCOM_texture_foveated2 1 +#define GL_TEXTURE_FOVEATED_CUTOFF_DENSITY_QCOM 0x96A0 +#endif /* GL_QCOM_texture_foveated2 */ + +#ifndef GL_QCOM_texture_foveated_subsampled_layout +#define GL_QCOM_texture_foveated_subsampled_layout 1 +#define GL_FOVEATION_SUBSAMPLED_LAYOUT_METHOD_BIT_QCOM 0x00000004 +#define GL_MAX_SHADER_SUBSAMPLED_IMAGE_UNITS_QCOM 0x8FA1 +#endif /* GL_QCOM_texture_foveated_subsampled_layout */ + +#ifndef GL_QCOM_texture_lod_bias +#define GL_QCOM_texture_lod_bias 1 +#define GL_TEXTURE_LOD_BIAS_QCOM 0x8C96 +#endif /* GL_QCOM_texture_lod_bias */ + #ifndef GL_QCOM_tiled_rendering #define GL_QCOM_tiled_rendering 1 #define GL_COLOR_BUFFER_BIT0_QCOM 0x00000001 diff --git a/SDL2-2.30.5/src/video/khronos/GLES2/gl2platform.h b/SDL2-2.30.5/src/video/khronos/GLES2/gl2platform.h new file mode 100644 index 0000000..5bcce6d --- /dev/null +++ b/SDL2-2.30.5/src/video/khronos/GLES2/gl2platform.h @@ -0,0 +1,27 @@ +#ifndef __gl2platform_h_ +#define __gl2platform_h_ + +/* +** Copyright 2017-2020 The Khronos Group Inc. +** SPDX-License-Identifier: Apache-2.0 +*/ + +/* Platform-specific types and definitions for OpenGL ES 2.X gl2.h + * + * Adopters may modify khrplatform.h and this file to suit their platform. + * Please contribute modifications back to Khronos as pull requests on the + * public github repository: + * https://github.com/KhronosGroup/OpenGL-Registry + */ + +#include + +#ifndef GL_APICALL +#define GL_APICALL KHRONOS_APICALL +#endif + +#ifndef GL_APIENTRY +#define GL_APIENTRY KHRONOS_APIENTRY +#endif + +#endif /* __gl2platform_h_ */ diff --git a/SDL2-2.0.12/src/video/khronos/KHR/khrplatform.h b/SDL2-2.30.5/src/video/khronos/KHR/khrplatform.h similarity index 85% rename from SDL2-2.0.12/src/video/khronos/KHR/khrplatform.h rename to SDL2-2.30.5/src/video/khronos/KHR/khrplatform.h index 1ad3554..0164644 100644 --- a/SDL2-2.0.12/src/video/khronos/KHR/khrplatform.h +++ b/SDL2-2.30.5/src/video/khronos/KHR/khrplatform.h @@ -2,7 +2,7 @@ #define __khrplatform_h_ /* -** Copyright (c) 2008-2009 The Khronos Group Inc. +** Copyright (c) 2008-2018 The Khronos Group Inc. ** ** Permission is hereby granted, free of charge, to any person obtaining a ** copy of this software and/or associated documentation files (the @@ -26,18 +26,16 @@ /* Khronos platform-specific types and definitions. * - * $Revision: 32517 $ on $Date: 2016-03-11 02:41:19 -0800 (Fri, 11 Mar 2016) $ + * The master copy of khrplatform.h is maintained in the Khronos EGL + * Registry repository at https://github.com/KhronosGroup/EGL-Registry + * The last semantic modification to khrplatform.h was at commit ID: + * 67a3e0864c2d75ea5287b9f3d2eb74a745936692 * * Adopters may modify this file to suit their platform. Adopters are * encouraged to submit platform specific modifications to the Khronos * group so that they can be included in future versions of this file. - * Please submit changes by sending them to the public Khronos Bugzilla - * (http://khronos.org/bugzilla) by filing a bug against product - * "Khronos (general)" component "Registry". - * - * A predefined template which fills in some of the bug fields can be - * reached using http://tinyurl.com/khrplatform-h-bugreport, but you - * must create a Bugzilla login first. + * Please submit changes by filing pull requests or issues on + * the EGL Registry repository linked above. * * * See the Implementer's Guidelines for information about where this file @@ -92,12 +90,20 @@ * int arg2) KHRONOS_APIATTRIBUTES; */ +#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC) +# define KHRONOS_STATIC 1 +#endif + /*------------------------------------------------------------------------- * Definition of KHRONOS_APICALL *------------------------------------------------------------------------- * This precedes the return type of the function in the function prototype. */ -#if defined(_WIN32) && !defined(__SCITECH_SNAP__) +#if defined(KHRONOS_STATIC) + /* If the preprocessor constant KHRONOS_STATIC is defined, make the + * header compatible with static linking. */ +# define KHRONOS_APICALL +#elif defined(_WIN32) # define KHRONOS_APICALL __declspec(dllimport) #elif defined (__SYMBIAN32__) # define KHRONOS_APICALL IMPORT_C @@ -147,6 +153,20 @@ typedef int64_t khronos_int64_t; typedef uint64_t khronos_uint64_t; #define KHRONOS_SUPPORT_INT64 1 #define KHRONOS_SUPPORT_FLOAT 1 +/* + * To support platform where unsigned long cannot be used interchangeably with + * inptr_t (e.g. CHERI-extended ISAs), we can use the stdint.h intptr_t. + * Ideally, we could just use (u)intptr_t everywhere, but this could result in + * ABI breakage if khronos_uintptr_t is changed from unsigned long to + * unsigned long long or similar (this results in different C++ name mangling). + * To avoid changes for existing platforms, we restrict usage of intptr_t to + * platforms where the size of a pointer is larger than the size of long. + */ +#if defined(__SIZEOF_LONG__) && defined(__SIZEOF_POINTER__) +#if __SIZEOF_POINTER__ > __SIZEOF_LONG__ +#define KHRONOS_USE_INTPTR_T +#endif +#endif #elif defined(__VMS ) || defined(__sgi) @@ -229,14 +249,21 @@ typedef unsigned short int khronos_uint16_t; * pointers are 64 bits, but 'long' is still 32 bits. Win64 appears * to be the only LLP64 architecture in current use. */ -#ifdef _WIN64 +#ifdef KHRONOS_USE_INTPTR_T +typedef intptr_t khronos_intptr_t; +typedef uintptr_t khronos_uintptr_t; +#elif defined(_WIN64) typedef signed long long int khronos_intptr_t; typedef unsigned long long int khronos_uintptr_t; -typedef signed long long int khronos_ssize_t; -typedef unsigned long long int khronos_usize_t; #else typedef signed long int khronos_intptr_t; typedef unsigned long int khronos_uintptr_t; +#endif + +#if defined(_WIN64) +typedef signed long long int khronos_ssize_t; +typedef unsigned long long int khronos_usize_t; +#else typedef signed long int khronos_ssize_t; typedef unsigned long int khronos_usize_t; #endif diff --git a/SDL2-2.30.5/src/video/khronos/vk_video/vulkan_video_codec_h264std.h b/SDL2-2.30.5/src/video/khronos/vk_video/vulkan_video_codec_h264std.h new file mode 100644 index 0000000..6d27af3 --- /dev/null +++ b/SDL2-2.30.5/src/video/khronos/vk_video/vulkan_video_codec_h264std.h @@ -0,0 +1,312 @@ +#ifndef VULKAN_VIDEO_CODEC_H264STD_H_ +#define VULKAN_VIDEO_CODEC_H264STD_H_ 1 + +/* +** Copyright 2015-2024 The Khronos Group Inc. +** +** SPDX-License-Identifier: Apache-2.0 +*/ + +/* +** This header is generated from the Khronos Vulkan XML API Registry. +** +*/ + + +#ifdef __cplusplus +extern "C" { +#endif + + + +// vulkan_video_codec_h264std is a preprocessor guard. Do not pass it to API calls. +#define vulkan_video_codec_h264std 1 +#include "vulkan_video_codecs_common.h" +#define STD_VIDEO_H264_CPB_CNT_LIST_SIZE 32 +#define STD_VIDEO_H264_SCALING_LIST_4X4_NUM_LISTS 6 +#define STD_VIDEO_H264_SCALING_LIST_4X4_NUM_ELEMENTS 16 +#define STD_VIDEO_H264_SCALING_LIST_8X8_NUM_LISTS 6 +#define STD_VIDEO_H264_SCALING_LIST_8X8_NUM_ELEMENTS 64 +#define STD_VIDEO_H264_MAX_NUM_LIST_REF 32 +#define STD_VIDEO_H264_MAX_CHROMA_PLANES 2 +#define STD_VIDEO_H264_NO_REFERENCE_PICTURE 0xFF + +typedef enum StdVideoH264ChromaFormatIdc { + STD_VIDEO_H264_CHROMA_FORMAT_IDC_MONOCHROME = 0, + STD_VIDEO_H264_CHROMA_FORMAT_IDC_420 = 1, + STD_VIDEO_H264_CHROMA_FORMAT_IDC_422 = 2, + STD_VIDEO_H264_CHROMA_FORMAT_IDC_444 = 3, + STD_VIDEO_H264_CHROMA_FORMAT_IDC_INVALID = 0x7FFFFFFF, + STD_VIDEO_H264_CHROMA_FORMAT_IDC_MAX_ENUM = 0x7FFFFFFF +} StdVideoH264ChromaFormatIdc; + +typedef enum StdVideoH264ProfileIdc { + STD_VIDEO_H264_PROFILE_IDC_BASELINE = 66, + STD_VIDEO_H264_PROFILE_IDC_MAIN = 77, + STD_VIDEO_H264_PROFILE_IDC_HIGH = 100, + STD_VIDEO_H264_PROFILE_IDC_HIGH_444_PREDICTIVE = 244, + STD_VIDEO_H264_PROFILE_IDC_INVALID = 0x7FFFFFFF, + STD_VIDEO_H264_PROFILE_IDC_MAX_ENUM = 0x7FFFFFFF +} StdVideoH264ProfileIdc; + +typedef enum StdVideoH264LevelIdc { + STD_VIDEO_H264_LEVEL_IDC_1_0 = 0, + STD_VIDEO_H264_LEVEL_IDC_1_1 = 1, + STD_VIDEO_H264_LEVEL_IDC_1_2 = 2, + STD_VIDEO_H264_LEVEL_IDC_1_3 = 3, + STD_VIDEO_H264_LEVEL_IDC_2_0 = 4, + STD_VIDEO_H264_LEVEL_IDC_2_1 = 5, + STD_VIDEO_H264_LEVEL_IDC_2_2 = 6, + STD_VIDEO_H264_LEVEL_IDC_3_0 = 7, + STD_VIDEO_H264_LEVEL_IDC_3_1 = 8, + STD_VIDEO_H264_LEVEL_IDC_3_2 = 9, + STD_VIDEO_H264_LEVEL_IDC_4_0 = 10, + STD_VIDEO_H264_LEVEL_IDC_4_1 = 11, + STD_VIDEO_H264_LEVEL_IDC_4_2 = 12, + STD_VIDEO_H264_LEVEL_IDC_5_0 = 13, + STD_VIDEO_H264_LEVEL_IDC_5_1 = 14, + STD_VIDEO_H264_LEVEL_IDC_5_2 = 15, + STD_VIDEO_H264_LEVEL_IDC_6_0 = 16, + STD_VIDEO_H264_LEVEL_IDC_6_1 = 17, + STD_VIDEO_H264_LEVEL_IDC_6_2 = 18, + STD_VIDEO_H264_LEVEL_IDC_INVALID = 0x7FFFFFFF, + STD_VIDEO_H264_LEVEL_IDC_MAX_ENUM = 0x7FFFFFFF +} StdVideoH264LevelIdc; + +typedef enum StdVideoH264PocType { + STD_VIDEO_H264_POC_TYPE_0 = 0, + STD_VIDEO_H264_POC_TYPE_1 = 1, + STD_VIDEO_H264_POC_TYPE_2 = 2, + STD_VIDEO_H264_POC_TYPE_INVALID = 0x7FFFFFFF, + STD_VIDEO_H264_POC_TYPE_MAX_ENUM = 0x7FFFFFFF +} StdVideoH264PocType; + +typedef enum StdVideoH264AspectRatioIdc { + STD_VIDEO_H264_ASPECT_RATIO_IDC_UNSPECIFIED = 0, + STD_VIDEO_H264_ASPECT_RATIO_IDC_SQUARE = 1, + STD_VIDEO_H264_ASPECT_RATIO_IDC_12_11 = 2, + STD_VIDEO_H264_ASPECT_RATIO_IDC_10_11 = 3, + STD_VIDEO_H264_ASPECT_RATIO_IDC_16_11 = 4, + STD_VIDEO_H264_ASPECT_RATIO_IDC_40_33 = 5, + STD_VIDEO_H264_ASPECT_RATIO_IDC_24_11 = 6, + STD_VIDEO_H264_ASPECT_RATIO_IDC_20_11 = 7, + STD_VIDEO_H264_ASPECT_RATIO_IDC_32_11 = 8, + STD_VIDEO_H264_ASPECT_RATIO_IDC_80_33 = 9, + STD_VIDEO_H264_ASPECT_RATIO_IDC_18_11 = 10, + STD_VIDEO_H264_ASPECT_RATIO_IDC_15_11 = 11, + STD_VIDEO_H264_ASPECT_RATIO_IDC_64_33 = 12, + STD_VIDEO_H264_ASPECT_RATIO_IDC_160_99 = 13, + STD_VIDEO_H264_ASPECT_RATIO_IDC_4_3 = 14, + STD_VIDEO_H264_ASPECT_RATIO_IDC_3_2 = 15, + STD_VIDEO_H264_ASPECT_RATIO_IDC_2_1 = 16, + STD_VIDEO_H264_ASPECT_RATIO_IDC_EXTENDED_SAR = 255, + STD_VIDEO_H264_ASPECT_RATIO_IDC_INVALID = 0x7FFFFFFF, + STD_VIDEO_H264_ASPECT_RATIO_IDC_MAX_ENUM = 0x7FFFFFFF +} StdVideoH264AspectRatioIdc; + +typedef enum StdVideoH264WeightedBipredIdc { + STD_VIDEO_H264_WEIGHTED_BIPRED_IDC_DEFAULT = 0, + STD_VIDEO_H264_WEIGHTED_BIPRED_IDC_EXPLICIT = 1, + STD_VIDEO_H264_WEIGHTED_BIPRED_IDC_IMPLICIT = 2, + STD_VIDEO_H264_WEIGHTED_BIPRED_IDC_INVALID = 0x7FFFFFFF, + STD_VIDEO_H264_WEIGHTED_BIPRED_IDC_MAX_ENUM = 0x7FFFFFFF +} StdVideoH264WeightedBipredIdc; + +typedef enum StdVideoH264ModificationOfPicNumsIdc { + STD_VIDEO_H264_MODIFICATION_OF_PIC_NUMS_IDC_SHORT_TERM_SUBTRACT = 0, + STD_VIDEO_H264_MODIFICATION_OF_PIC_NUMS_IDC_SHORT_TERM_ADD = 1, + STD_VIDEO_H264_MODIFICATION_OF_PIC_NUMS_IDC_LONG_TERM = 2, + STD_VIDEO_H264_MODIFICATION_OF_PIC_NUMS_IDC_END = 3, + STD_VIDEO_H264_MODIFICATION_OF_PIC_NUMS_IDC_INVALID = 0x7FFFFFFF, + STD_VIDEO_H264_MODIFICATION_OF_PIC_NUMS_IDC_MAX_ENUM = 0x7FFFFFFF +} StdVideoH264ModificationOfPicNumsIdc; + +typedef enum StdVideoH264MemMgmtControlOp { + STD_VIDEO_H264_MEM_MGMT_CONTROL_OP_END = 0, + STD_VIDEO_H264_MEM_MGMT_CONTROL_OP_UNMARK_SHORT_TERM = 1, + STD_VIDEO_H264_MEM_MGMT_CONTROL_OP_UNMARK_LONG_TERM = 2, + STD_VIDEO_H264_MEM_MGMT_CONTROL_OP_MARK_LONG_TERM = 3, + STD_VIDEO_H264_MEM_MGMT_CONTROL_OP_SET_MAX_LONG_TERM_INDEX = 4, + STD_VIDEO_H264_MEM_MGMT_CONTROL_OP_UNMARK_ALL = 5, + STD_VIDEO_H264_MEM_MGMT_CONTROL_OP_MARK_CURRENT_AS_LONG_TERM = 6, + STD_VIDEO_H264_MEM_MGMT_CONTROL_OP_INVALID = 0x7FFFFFFF, + STD_VIDEO_H264_MEM_MGMT_CONTROL_OP_MAX_ENUM = 0x7FFFFFFF +} StdVideoH264MemMgmtControlOp; + +typedef enum StdVideoH264CabacInitIdc { + STD_VIDEO_H264_CABAC_INIT_IDC_0 = 0, + STD_VIDEO_H264_CABAC_INIT_IDC_1 = 1, + STD_VIDEO_H264_CABAC_INIT_IDC_2 = 2, + STD_VIDEO_H264_CABAC_INIT_IDC_INVALID = 0x7FFFFFFF, + STD_VIDEO_H264_CABAC_INIT_IDC_MAX_ENUM = 0x7FFFFFFF +} StdVideoH264CabacInitIdc; + +typedef enum StdVideoH264DisableDeblockingFilterIdc { + STD_VIDEO_H264_DISABLE_DEBLOCKING_FILTER_IDC_DISABLED = 0, + STD_VIDEO_H264_DISABLE_DEBLOCKING_FILTER_IDC_ENABLED = 1, + STD_VIDEO_H264_DISABLE_DEBLOCKING_FILTER_IDC_PARTIAL = 2, + STD_VIDEO_H264_DISABLE_DEBLOCKING_FILTER_IDC_INVALID = 0x7FFFFFFF, + STD_VIDEO_H264_DISABLE_DEBLOCKING_FILTER_IDC_MAX_ENUM = 0x7FFFFFFF +} StdVideoH264DisableDeblockingFilterIdc; + +typedef enum StdVideoH264SliceType { + STD_VIDEO_H264_SLICE_TYPE_P = 0, + STD_VIDEO_H264_SLICE_TYPE_B = 1, + STD_VIDEO_H264_SLICE_TYPE_I = 2, + STD_VIDEO_H264_SLICE_TYPE_INVALID = 0x7FFFFFFF, + STD_VIDEO_H264_SLICE_TYPE_MAX_ENUM = 0x7FFFFFFF +} StdVideoH264SliceType; + +typedef enum StdVideoH264PictureType { + STD_VIDEO_H264_PICTURE_TYPE_P = 0, + STD_VIDEO_H264_PICTURE_TYPE_B = 1, + STD_VIDEO_H264_PICTURE_TYPE_I = 2, + STD_VIDEO_H264_PICTURE_TYPE_IDR = 5, + STD_VIDEO_H264_PICTURE_TYPE_INVALID = 0x7FFFFFFF, + STD_VIDEO_H264_PICTURE_TYPE_MAX_ENUM = 0x7FFFFFFF +} StdVideoH264PictureType; + +typedef enum StdVideoH264NonVclNaluType { + STD_VIDEO_H264_NON_VCL_NALU_TYPE_SPS = 0, + STD_VIDEO_H264_NON_VCL_NALU_TYPE_PPS = 1, + STD_VIDEO_H264_NON_VCL_NALU_TYPE_AUD = 2, + STD_VIDEO_H264_NON_VCL_NALU_TYPE_PREFIX = 3, + STD_VIDEO_H264_NON_VCL_NALU_TYPE_END_OF_SEQUENCE = 4, + STD_VIDEO_H264_NON_VCL_NALU_TYPE_END_OF_STREAM = 5, + STD_VIDEO_H264_NON_VCL_NALU_TYPE_PRECODED = 6, + STD_VIDEO_H264_NON_VCL_NALU_TYPE_INVALID = 0x7FFFFFFF, + STD_VIDEO_H264_NON_VCL_NALU_TYPE_MAX_ENUM = 0x7FFFFFFF +} StdVideoH264NonVclNaluType; +typedef struct StdVideoH264SpsVuiFlags { + uint32_t aspect_ratio_info_present_flag : 1; + uint32_t overscan_info_present_flag : 1; + uint32_t overscan_appropriate_flag : 1; + uint32_t video_signal_type_present_flag : 1; + uint32_t video_full_range_flag : 1; + uint32_t color_description_present_flag : 1; + uint32_t chroma_loc_info_present_flag : 1; + uint32_t timing_info_present_flag : 1; + uint32_t fixed_frame_rate_flag : 1; + uint32_t bitstream_restriction_flag : 1; + uint32_t nal_hrd_parameters_present_flag : 1; + uint32_t vcl_hrd_parameters_present_flag : 1; +} StdVideoH264SpsVuiFlags; + +typedef struct StdVideoH264HrdParameters { + uint8_t cpb_cnt_minus1; + uint8_t bit_rate_scale; + uint8_t cpb_size_scale; + uint8_t reserved1; + uint32_t bit_rate_value_minus1[STD_VIDEO_H264_CPB_CNT_LIST_SIZE]; + uint32_t cpb_size_value_minus1[STD_VIDEO_H264_CPB_CNT_LIST_SIZE]; + uint8_t cbr_flag[STD_VIDEO_H264_CPB_CNT_LIST_SIZE]; + uint32_t initial_cpb_removal_delay_length_minus1; + uint32_t cpb_removal_delay_length_minus1; + uint32_t dpb_output_delay_length_minus1; + uint32_t time_offset_length; +} StdVideoH264HrdParameters; + +typedef struct StdVideoH264SequenceParameterSetVui { + StdVideoH264SpsVuiFlags flags; + StdVideoH264AspectRatioIdc aspect_ratio_idc; + uint16_t sar_width; + uint16_t sar_height; + uint8_t video_format; + uint8_t colour_primaries; + uint8_t transfer_characteristics; + uint8_t matrix_coefficients; + uint32_t num_units_in_tick; + uint32_t time_scale; + uint8_t max_num_reorder_frames; + uint8_t max_dec_frame_buffering; + uint8_t chroma_sample_loc_type_top_field; + uint8_t chroma_sample_loc_type_bottom_field; + uint32_t reserved1; + const StdVideoH264HrdParameters* pHrdParameters; +} StdVideoH264SequenceParameterSetVui; + +typedef struct StdVideoH264SpsFlags { + uint32_t constraint_set0_flag : 1; + uint32_t constraint_set1_flag : 1; + uint32_t constraint_set2_flag : 1; + uint32_t constraint_set3_flag : 1; + uint32_t constraint_set4_flag : 1; + uint32_t constraint_set5_flag : 1; + uint32_t direct_8x8_inference_flag : 1; + uint32_t mb_adaptive_frame_field_flag : 1; + uint32_t frame_mbs_only_flag : 1; + uint32_t delta_pic_order_always_zero_flag : 1; + uint32_t separate_colour_plane_flag : 1; + uint32_t gaps_in_frame_num_value_allowed_flag : 1; + uint32_t qpprime_y_zero_transform_bypass_flag : 1; + uint32_t frame_cropping_flag : 1; + uint32_t seq_scaling_matrix_present_flag : 1; + uint32_t vui_parameters_present_flag : 1; +} StdVideoH264SpsFlags; + +typedef struct StdVideoH264ScalingLists { + uint16_t scaling_list_present_mask; + uint16_t use_default_scaling_matrix_mask; + uint8_t ScalingList4x4[STD_VIDEO_H264_SCALING_LIST_4X4_NUM_LISTS][STD_VIDEO_H264_SCALING_LIST_4X4_NUM_ELEMENTS]; + uint8_t ScalingList8x8[STD_VIDEO_H264_SCALING_LIST_8X8_NUM_LISTS][STD_VIDEO_H264_SCALING_LIST_8X8_NUM_ELEMENTS]; +} StdVideoH264ScalingLists; + +typedef struct StdVideoH264SequenceParameterSet { + StdVideoH264SpsFlags flags; + StdVideoH264ProfileIdc profile_idc; + StdVideoH264LevelIdc level_idc; + StdVideoH264ChromaFormatIdc chroma_format_idc; + uint8_t seq_parameter_set_id; + uint8_t bit_depth_luma_minus8; + uint8_t bit_depth_chroma_minus8; + uint8_t log2_max_frame_num_minus4; + StdVideoH264PocType pic_order_cnt_type; + int32_t offset_for_non_ref_pic; + int32_t offset_for_top_to_bottom_field; + uint8_t log2_max_pic_order_cnt_lsb_minus4; + uint8_t num_ref_frames_in_pic_order_cnt_cycle; + uint8_t max_num_ref_frames; + uint8_t reserved1; + uint32_t pic_width_in_mbs_minus1; + uint32_t pic_height_in_map_units_minus1; + uint32_t frame_crop_left_offset; + uint32_t frame_crop_right_offset; + uint32_t frame_crop_top_offset; + uint32_t frame_crop_bottom_offset; + uint32_t reserved2; + const int32_t* pOffsetForRefFrame; + const StdVideoH264ScalingLists* pScalingLists; + const StdVideoH264SequenceParameterSetVui* pSequenceParameterSetVui; +} StdVideoH264SequenceParameterSet; + +typedef struct StdVideoH264PpsFlags { + uint32_t transform_8x8_mode_flag : 1; + uint32_t redundant_pic_cnt_present_flag : 1; + uint32_t constrained_intra_pred_flag : 1; + uint32_t deblocking_filter_control_present_flag : 1; + uint32_t weighted_pred_flag : 1; + uint32_t bottom_field_pic_order_in_frame_present_flag : 1; + uint32_t entropy_coding_mode_flag : 1; + uint32_t pic_scaling_matrix_present_flag : 1; +} StdVideoH264PpsFlags; + +typedef struct StdVideoH264PictureParameterSet { + StdVideoH264PpsFlags flags; + uint8_t seq_parameter_set_id; + uint8_t pic_parameter_set_id; + uint8_t num_ref_idx_l0_default_active_minus1; + uint8_t num_ref_idx_l1_default_active_minus1; + StdVideoH264WeightedBipredIdc weighted_bipred_idc; + int8_t pic_init_qp_minus26; + int8_t pic_init_qs_minus26; + int8_t chroma_qp_index_offset; + int8_t second_chroma_qp_index_offset; + const StdVideoH264ScalingLists* pScalingLists; +} StdVideoH264PictureParameterSet; + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/SDL2-2.30.5/src/video/khronos/vk_video/vulkan_video_codec_h264std_decode.h b/SDL2-2.30.5/src/video/khronos/vk_video/vulkan_video_codec_h264std_decode.h new file mode 100644 index 0000000..439cb88 --- /dev/null +++ b/SDL2-2.30.5/src/video/khronos/vk_video/vulkan_video_codec_h264std_decode.h @@ -0,0 +1,77 @@ +#ifndef VULKAN_VIDEO_CODEC_H264STD_DECODE_H_ +#define VULKAN_VIDEO_CODEC_H264STD_DECODE_H_ 1 + +/* +** Copyright 2015-2024 The Khronos Group Inc. +** +** SPDX-License-Identifier: Apache-2.0 +*/ + +/* +** This header is generated from the Khronos Vulkan XML API Registry. +** +*/ + + +#ifdef __cplusplus +extern "C" { +#endif + + + +// vulkan_video_codec_h264std_decode is a preprocessor guard. Do not pass it to API calls. +#define vulkan_video_codec_h264std_decode 1 +#include "vulkan_video_codec_h264std.h" + +#define VK_STD_VULKAN_VIDEO_CODEC_H264_DECODE_API_VERSION_1_0_0 VK_MAKE_VIDEO_STD_VERSION(1, 0, 0) + +#define VK_STD_VULKAN_VIDEO_CODEC_H264_DECODE_SPEC_VERSION VK_STD_VULKAN_VIDEO_CODEC_H264_DECODE_API_VERSION_1_0_0 +#define VK_STD_VULKAN_VIDEO_CODEC_H264_DECODE_EXTENSION_NAME "VK_STD_vulkan_video_codec_h264_decode" +#define STD_VIDEO_DECODE_H264_FIELD_ORDER_COUNT_LIST_SIZE 2 + +typedef enum StdVideoDecodeH264FieldOrderCount { + STD_VIDEO_DECODE_H264_FIELD_ORDER_COUNT_TOP = 0, + STD_VIDEO_DECODE_H264_FIELD_ORDER_COUNT_BOTTOM = 1, + STD_VIDEO_DECODE_H264_FIELD_ORDER_COUNT_INVALID = 0x7FFFFFFF, + STD_VIDEO_DECODE_H264_FIELD_ORDER_COUNT_MAX_ENUM = 0x7FFFFFFF +} StdVideoDecodeH264FieldOrderCount; +typedef struct StdVideoDecodeH264PictureInfoFlags { + uint32_t field_pic_flag : 1; + uint32_t is_intra : 1; + uint32_t IdrPicFlag : 1; + uint32_t bottom_field_flag : 1; + uint32_t is_reference : 1; + uint32_t complementary_field_pair : 1; +} StdVideoDecodeH264PictureInfoFlags; + +typedef struct StdVideoDecodeH264PictureInfo { + StdVideoDecodeH264PictureInfoFlags flags; + uint8_t seq_parameter_set_id; + uint8_t pic_parameter_set_id; + uint8_t reserved1; + uint8_t reserved2; + uint16_t frame_num; + uint16_t idr_pic_id; + int32_t PicOrderCnt[STD_VIDEO_DECODE_H264_FIELD_ORDER_COUNT_LIST_SIZE]; +} StdVideoDecodeH264PictureInfo; + +typedef struct StdVideoDecodeH264ReferenceInfoFlags { + uint32_t top_field_flag : 1; + uint32_t bottom_field_flag : 1; + uint32_t used_for_long_term_reference : 1; + uint32_t is_non_existing : 1; +} StdVideoDecodeH264ReferenceInfoFlags; + +typedef struct StdVideoDecodeH264ReferenceInfo { + StdVideoDecodeH264ReferenceInfoFlags flags; + uint16_t FrameNum; + uint16_t reserved; + int32_t PicOrderCnt[STD_VIDEO_DECODE_H264_FIELD_ORDER_COUNT_LIST_SIZE]; +} StdVideoDecodeH264ReferenceInfo; + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/SDL2-2.30.5/src/video/khronos/vk_video/vulkan_video_codec_h264std_encode.h b/SDL2-2.30.5/src/video/khronos/vk_video/vulkan_video_codec_h264std_encode.h new file mode 100644 index 0000000..9e24aa5 --- /dev/null +++ b/SDL2-2.30.5/src/video/khronos/vk_video/vulkan_video_codec_h264std_encode.h @@ -0,0 +1,147 @@ +#ifndef VULKAN_VIDEO_CODEC_H264STD_ENCODE_H_ +#define VULKAN_VIDEO_CODEC_H264STD_ENCODE_H_ 1 + +/* +** Copyright 2015-2024 The Khronos Group Inc. +** +** SPDX-License-Identifier: Apache-2.0 +*/ + +/* +** This header is generated from the Khronos Vulkan XML API Registry. +** +*/ + + +#ifdef __cplusplus +extern "C" { +#endif + + + +// vulkan_video_codec_h264std_encode is a preprocessor guard. Do not pass it to API calls. +#define vulkan_video_codec_h264std_encode 1 +#include "vulkan_video_codec_h264std.h" + +#define VK_STD_VULKAN_VIDEO_CODEC_H264_ENCODE_API_VERSION_1_0_0 VK_MAKE_VIDEO_STD_VERSION(1, 0, 0) + +#define VK_STD_VULKAN_VIDEO_CODEC_H264_ENCODE_SPEC_VERSION VK_STD_VULKAN_VIDEO_CODEC_H264_ENCODE_API_VERSION_1_0_0 +#define VK_STD_VULKAN_VIDEO_CODEC_H264_ENCODE_EXTENSION_NAME "VK_STD_vulkan_video_codec_h264_encode" +typedef struct StdVideoEncodeH264WeightTableFlags { + uint32_t luma_weight_l0_flag; + uint32_t chroma_weight_l0_flag; + uint32_t luma_weight_l1_flag; + uint32_t chroma_weight_l1_flag; +} StdVideoEncodeH264WeightTableFlags; + +typedef struct StdVideoEncodeH264WeightTable { + StdVideoEncodeH264WeightTableFlags flags; + uint8_t luma_log2_weight_denom; + uint8_t chroma_log2_weight_denom; + int8_t luma_weight_l0[STD_VIDEO_H264_MAX_NUM_LIST_REF]; + int8_t luma_offset_l0[STD_VIDEO_H264_MAX_NUM_LIST_REF]; + int8_t chroma_weight_l0[STD_VIDEO_H264_MAX_NUM_LIST_REF][STD_VIDEO_H264_MAX_CHROMA_PLANES]; + int8_t chroma_offset_l0[STD_VIDEO_H264_MAX_NUM_LIST_REF][STD_VIDEO_H264_MAX_CHROMA_PLANES]; + int8_t luma_weight_l1[STD_VIDEO_H264_MAX_NUM_LIST_REF]; + int8_t luma_offset_l1[STD_VIDEO_H264_MAX_NUM_LIST_REF]; + int8_t chroma_weight_l1[STD_VIDEO_H264_MAX_NUM_LIST_REF][STD_VIDEO_H264_MAX_CHROMA_PLANES]; + int8_t chroma_offset_l1[STD_VIDEO_H264_MAX_NUM_LIST_REF][STD_VIDEO_H264_MAX_CHROMA_PLANES]; +} StdVideoEncodeH264WeightTable; + +typedef struct StdVideoEncodeH264SliceHeaderFlags { + uint32_t direct_spatial_mv_pred_flag : 1; + uint32_t num_ref_idx_active_override_flag : 1; + uint32_t reserved : 30; +} StdVideoEncodeH264SliceHeaderFlags; + +typedef struct StdVideoEncodeH264PictureInfoFlags { + uint32_t IdrPicFlag : 1; + uint32_t is_reference : 1; + uint32_t no_output_of_prior_pics_flag : 1; + uint32_t long_term_reference_flag : 1; + uint32_t adaptive_ref_pic_marking_mode_flag : 1; + uint32_t reserved : 27; +} StdVideoEncodeH264PictureInfoFlags; + +typedef struct StdVideoEncodeH264ReferenceInfoFlags { + uint32_t used_for_long_term_reference : 1; + uint32_t reserved : 31; +} StdVideoEncodeH264ReferenceInfoFlags; + +typedef struct StdVideoEncodeH264ReferenceListsInfoFlags { + uint32_t ref_pic_list_modification_flag_l0 : 1; + uint32_t ref_pic_list_modification_flag_l1 : 1; + uint32_t reserved : 30; +} StdVideoEncodeH264ReferenceListsInfoFlags; + +typedef struct StdVideoEncodeH264RefListModEntry { + StdVideoH264ModificationOfPicNumsIdc modification_of_pic_nums_idc; + uint16_t abs_diff_pic_num_minus1; + uint16_t long_term_pic_num; +} StdVideoEncodeH264RefListModEntry; + +typedef struct StdVideoEncodeH264RefPicMarkingEntry { + StdVideoH264MemMgmtControlOp memory_management_control_operation; + uint16_t difference_of_pic_nums_minus1; + uint16_t long_term_pic_num; + uint16_t long_term_frame_idx; + uint16_t max_long_term_frame_idx_plus1; +} StdVideoEncodeH264RefPicMarkingEntry; + +typedef struct StdVideoEncodeH264ReferenceListsInfo { + StdVideoEncodeH264ReferenceListsInfoFlags flags; + uint8_t num_ref_idx_l0_active_minus1; + uint8_t num_ref_idx_l1_active_minus1; + uint8_t RefPicList0[STD_VIDEO_H264_MAX_NUM_LIST_REF]; + uint8_t RefPicList1[STD_VIDEO_H264_MAX_NUM_LIST_REF]; + uint8_t refList0ModOpCount; + uint8_t refList1ModOpCount; + uint8_t refPicMarkingOpCount; + uint8_t reserved1[7]; + const StdVideoEncodeH264RefListModEntry* pRefList0ModOperations; + const StdVideoEncodeH264RefListModEntry* pRefList1ModOperations; + const StdVideoEncodeH264RefPicMarkingEntry* pRefPicMarkingOperations; +} StdVideoEncodeH264ReferenceListsInfo; + +typedef struct StdVideoEncodeH264PictureInfo { + StdVideoEncodeH264PictureInfoFlags flags; + uint8_t seq_parameter_set_id; + uint8_t pic_parameter_set_id; + uint16_t idr_pic_id; + StdVideoH264PictureType primary_pic_type; + uint32_t frame_num; + int32_t PicOrderCnt; + uint8_t temporal_id; + uint8_t reserved1[3]; + const StdVideoEncodeH264ReferenceListsInfo* pRefLists; +} StdVideoEncodeH264PictureInfo; + +typedef struct StdVideoEncodeH264ReferenceInfo { + StdVideoEncodeH264ReferenceInfoFlags flags; + StdVideoH264PictureType primary_pic_type; + uint32_t FrameNum; + int32_t PicOrderCnt; + uint16_t long_term_pic_num; + uint16_t long_term_frame_idx; + uint8_t temporal_id; +} StdVideoEncodeH264ReferenceInfo; + +typedef struct StdVideoEncodeH264SliceHeader { + StdVideoEncodeH264SliceHeaderFlags flags; + uint32_t first_mb_in_slice; + StdVideoH264SliceType slice_type; + int8_t slice_alpha_c0_offset_div2; + int8_t slice_beta_offset_div2; + int8_t slice_qp_delta; + uint8_t reserved1; + StdVideoH264CabacInitIdc cabac_init_idc; + StdVideoH264DisableDeblockingFilterIdc disable_deblocking_filter_idc; + const StdVideoEncodeH264WeightTable* pWeightTable; +} StdVideoEncodeH264SliceHeader; + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/SDL2-2.30.5/src/video/khronos/vk_video/vulkan_video_codec_h265std.h b/SDL2-2.30.5/src/video/khronos/vk_video/vulkan_video_codec_h265std.h new file mode 100644 index 0000000..d0a1bac --- /dev/null +++ b/SDL2-2.30.5/src/video/khronos/vk_video/vulkan_video_codec_h265std.h @@ -0,0 +1,446 @@ +#ifndef VULKAN_VIDEO_CODEC_H265STD_H_ +#define VULKAN_VIDEO_CODEC_H265STD_H_ 1 + +/* +** Copyright 2015-2024 The Khronos Group Inc. +** +** SPDX-License-Identifier: Apache-2.0 +*/ + +/* +** This header is generated from the Khronos Vulkan XML API Registry. +** +*/ + + +#ifdef __cplusplus +extern "C" { +#endif + + + +// vulkan_video_codec_h265std is a preprocessor guard. Do not pass it to API calls. +#define vulkan_video_codec_h265std 1 +#include "vulkan_video_codecs_common.h" +#define STD_VIDEO_H265_CPB_CNT_LIST_SIZE 32 +#define STD_VIDEO_H265_SUBLAYERS_LIST_SIZE 7 +#define STD_VIDEO_H265_SCALING_LIST_4X4_NUM_LISTS 6 +#define STD_VIDEO_H265_SCALING_LIST_4X4_NUM_ELEMENTS 16 +#define STD_VIDEO_H265_SCALING_LIST_8X8_NUM_LISTS 6 +#define STD_VIDEO_H265_SCALING_LIST_8X8_NUM_ELEMENTS 64 +#define STD_VIDEO_H265_SCALING_LIST_16X16_NUM_LISTS 6 +#define STD_VIDEO_H265_SCALING_LIST_16X16_NUM_ELEMENTS 64 +#define STD_VIDEO_H265_SCALING_LIST_32X32_NUM_LISTS 2 +#define STD_VIDEO_H265_SCALING_LIST_32X32_NUM_ELEMENTS 64 +#define STD_VIDEO_H265_CHROMA_QP_OFFSET_LIST_SIZE 6 +#define STD_VIDEO_H265_CHROMA_QP_OFFSET_TILE_COLS_LIST_SIZE 19 +#define STD_VIDEO_H265_CHROMA_QP_OFFSET_TILE_ROWS_LIST_SIZE 21 +#define STD_VIDEO_H265_PREDICTOR_PALETTE_COMPONENTS_LIST_SIZE 3 +#define STD_VIDEO_H265_PREDICTOR_PALETTE_COMP_ENTRIES_LIST_SIZE 128 +#define STD_VIDEO_H265_MAX_NUM_LIST_REF 15 +#define STD_VIDEO_H265_MAX_CHROMA_PLANES 2 +#define STD_VIDEO_H265_MAX_SHORT_TERM_REF_PIC_SETS 64 +#define STD_VIDEO_H265_MAX_DPB_SIZE 16 +#define STD_VIDEO_H265_MAX_LONG_TERM_REF_PICS_SPS 32 +#define STD_VIDEO_H265_MAX_LONG_TERM_PICS 16 +#define STD_VIDEO_H265_MAX_DELTA_POC 48 +#define STD_VIDEO_H265_NO_REFERENCE_PICTURE 0xFF + +typedef enum StdVideoH265ChromaFormatIdc { + STD_VIDEO_H265_CHROMA_FORMAT_IDC_MONOCHROME = 0, + STD_VIDEO_H265_CHROMA_FORMAT_IDC_420 = 1, + STD_VIDEO_H265_CHROMA_FORMAT_IDC_422 = 2, + STD_VIDEO_H265_CHROMA_FORMAT_IDC_444 = 3, + STD_VIDEO_H265_CHROMA_FORMAT_IDC_INVALID = 0x7FFFFFFF, + STD_VIDEO_H265_CHROMA_FORMAT_IDC_MAX_ENUM = 0x7FFFFFFF +} StdVideoH265ChromaFormatIdc; + +typedef enum StdVideoH265ProfileIdc { + STD_VIDEO_H265_PROFILE_IDC_MAIN = 1, + STD_VIDEO_H265_PROFILE_IDC_MAIN_10 = 2, + STD_VIDEO_H265_PROFILE_IDC_MAIN_STILL_PICTURE = 3, + STD_VIDEO_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSIONS = 4, + STD_VIDEO_H265_PROFILE_IDC_SCC_EXTENSIONS = 9, + STD_VIDEO_H265_PROFILE_IDC_INVALID = 0x7FFFFFFF, + STD_VIDEO_H265_PROFILE_IDC_MAX_ENUM = 0x7FFFFFFF +} StdVideoH265ProfileIdc; + +typedef enum StdVideoH265LevelIdc { + STD_VIDEO_H265_LEVEL_IDC_1_0 = 0, + STD_VIDEO_H265_LEVEL_IDC_2_0 = 1, + STD_VIDEO_H265_LEVEL_IDC_2_1 = 2, + STD_VIDEO_H265_LEVEL_IDC_3_0 = 3, + STD_VIDEO_H265_LEVEL_IDC_3_1 = 4, + STD_VIDEO_H265_LEVEL_IDC_4_0 = 5, + STD_VIDEO_H265_LEVEL_IDC_4_1 = 6, + STD_VIDEO_H265_LEVEL_IDC_5_0 = 7, + STD_VIDEO_H265_LEVEL_IDC_5_1 = 8, + STD_VIDEO_H265_LEVEL_IDC_5_2 = 9, + STD_VIDEO_H265_LEVEL_IDC_6_0 = 10, + STD_VIDEO_H265_LEVEL_IDC_6_1 = 11, + STD_VIDEO_H265_LEVEL_IDC_6_2 = 12, + STD_VIDEO_H265_LEVEL_IDC_INVALID = 0x7FFFFFFF, + STD_VIDEO_H265_LEVEL_IDC_MAX_ENUM = 0x7FFFFFFF +} StdVideoH265LevelIdc; + +typedef enum StdVideoH265SliceType { + STD_VIDEO_H265_SLICE_TYPE_B = 0, + STD_VIDEO_H265_SLICE_TYPE_P = 1, + STD_VIDEO_H265_SLICE_TYPE_I = 2, + STD_VIDEO_H265_SLICE_TYPE_INVALID = 0x7FFFFFFF, + STD_VIDEO_H265_SLICE_TYPE_MAX_ENUM = 0x7FFFFFFF +} StdVideoH265SliceType; + +typedef enum StdVideoH265PictureType { + STD_VIDEO_H265_PICTURE_TYPE_P = 0, + STD_VIDEO_H265_PICTURE_TYPE_B = 1, + STD_VIDEO_H265_PICTURE_TYPE_I = 2, + STD_VIDEO_H265_PICTURE_TYPE_IDR = 3, + STD_VIDEO_H265_PICTURE_TYPE_INVALID = 0x7FFFFFFF, + STD_VIDEO_H265_PICTURE_TYPE_MAX_ENUM = 0x7FFFFFFF +} StdVideoH265PictureType; + +typedef enum StdVideoH265AspectRatioIdc { + STD_VIDEO_H265_ASPECT_RATIO_IDC_UNSPECIFIED = 0, + STD_VIDEO_H265_ASPECT_RATIO_IDC_SQUARE = 1, + STD_VIDEO_H265_ASPECT_RATIO_IDC_12_11 = 2, + STD_VIDEO_H265_ASPECT_RATIO_IDC_10_11 = 3, + STD_VIDEO_H265_ASPECT_RATIO_IDC_16_11 = 4, + STD_VIDEO_H265_ASPECT_RATIO_IDC_40_33 = 5, + STD_VIDEO_H265_ASPECT_RATIO_IDC_24_11 = 6, + STD_VIDEO_H265_ASPECT_RATIO_IDC_20_11 = 7, + STD_VIDEO_H265_ASPECT_RATIO_IDC_32_11 = 8, + STD_VIDEO_H265_ASPECT_RATIO_IDC_80_33 = 9, + STD_VIDEO_H265_ASPECT_RATIO_IDC_18_11 = 10, + STD_VIDEO_H265_ASPECT_RATIO_IDC_15_11 = 11, + STD_VIDEO_H265_ASPECT_RATIO_IDC_64_33 = 12, + STD_VIDEO_H265_ASPECT_RATIO_IDC_160_99 = 13, + STD_VIDEO_H265_ASPECT_RATIO_IDC_4_3 = 14, + STD_VIDEO_H265_ASPECT_RATIO_IDC_3_2 = 15, + STD_VIDEO_H265_ASPECT_RATIO_IDC_2_1 = 16, + STD_VIDEO_H265_ASPECT_RATIO_IDC_EXTENDED_SAR = 255, + STD_VIDEO_H265_ASPECT_RATIO_IDC_INVALID = 0x7FFFFFFF, + STD_VIDEO_H265_ASPECT_RATIO_IDC_MAX_ENUM = 0x7FFFFFFF +} StdVideoH265AspectRatioIdc; +typedef struct StdVideoH265DecPicBufMgr { + uint32_t max_latency_increase_plus1[STD_VIDEO_H265_SUBLAYERS_LIST_SIZE]; + uint8_t max_dec_pic_buffering_minus1[STD_VIDEO_H265_SUBLAYERS_LIST_SIZE]; + uint8_t max_num_reorder_pics[STD_VIDEO_H265_SUBLAYERS_LIST_SIZE]; +} StdVideoH265DecPicBufMgr; + +typedef struct StdVideoH265SubLayerHrdParameters { + uint32_t bit_rate_value_minus1[STD_VIDEO_H265_CPB_CNT_LIST_SIZE]; + uint32_t cpb_size_value_minus1[STD_VIDEO_H265_CPB_CNT_LIST_SIZE]; + uint32_t cpb_size_du_value_minus1[STD_VIDEO_H265_CPB_CNT_LIST_SIZE]; + uint32_t bit_rate_du_value_minus1[STD_VIDEO_H265_CPB_CNT_LIST_SIZE]; + uint32_t cbr_flag; +} StdVideoH265SubLayerHrdParameters; + +typedef struct StdVideoH265HrdFlags { + uint32_t nal_hrd_parameters_present_flag : 1; + uint32_t vcl_hrd_parameters_present_flag : 1; + uint32_t sub_pic_hrd_params_present_flag : 1; + uint32_t sub_pic_cpb_params_in_pic_timing_sei_flag : 1; + uint32_t fixed_pic_rate_general_flag : 8; + uint32_t fixed_pic_rate_within_cvs_flag : 8; + uint32_t low_delay_hrd_flag : 8; +} StdVideoH265HrdFlags; + +typedef struct StdVideoH265HrdParameters { + StdVideoH265HrdFlags flags; + uint8_t tick_divisor_minus2; + uint8_t du_cpb_removal_delay_increment_length_minus1; + uint8_t dpb_output_delay_du_length_minus1; + uint8_t bit_rate_scale; + uint8_t cpb_size_scale; + uint8_t cpb_size_du_scale; + uint8_t initial_cpb_removal_delay_length_minus1; + uint8_t au_cpb_removal_delay_length_minus1; + uint8_t dpb_output_delay_length_minus1; + uint8_t cpb_cnt_minus1[STD_VIDEO_H265_SUBLAYERS_LIST_SIZE]; + uint16_t elemental_duration_in_tc_minus1[STD_VIDEO_H265_SUBLAYERS_LIST_SIZE]; + uint16_t reserved[3]; + const StdVideoH265SubLayerHrdParameters* pSubLayerHrdParametersNal; + const StdVideoH265SubLayerHrdParameters* pSubLayerHrdParametersVcl; +} StdVideoH265HrdParameters; + +typedef struct StdVideoH265VpsFlags { + uint32_t vps_temporal_id_nesting_flag : 1; + uint32_t vps_sub_layer_ordering_info_present_flag : 1; + uint32_t vps_timing_info_present_flag : 1; + uint32_t vps_poc_proportional_to_timing_flag : 1; +} StdVideoH265VpsFlags; + +typedef struct StdVideoH265ProfileTierLevelFlags { + uint32_t general_tier_flag : 1; + uint32_t general_progressive_source_flag : 1; + uint32_t general_interlaced_source_flag : 1; + uint32_t general_non_packed_constraint_flag : 1; + uint32_t general_frame_only_constraint_flag : 1; +} StdVideoH265ProfileTierLevelFlags; + +typedef struct StdVideoH265ProfileTierLevel { + StdVideoH265ProfileTierLevelFlags flags; + StdVideoH265ProfileIdc general_profile_idc; + StdVideoH265LevelIdc general_level_idc; +} StdVideoH265ProfileTierLevel; + +typedef struct StdVideoH265VideoParameterSet { + StdVideoH265VpsFlags flags; + uint8_t vps_video_parameter_set_id; + uint8_t vps_max_sub_layers_minus1; + uint8_t reserved1; + uint8_t reserved2; + uint32_t vps_num_units_in_tick; + uint32_t vps_time_scale; + uint32_t vps_num_ticks_poc_diff_one_minus1; + uint32_t reserved3; + const StdVideoH265DecPicBufMgr* pDecPicBufMgr; + const StdVideoH265HrdParameters* pHrdParameters; + const StdVideoH265ProfileTierLevel* pProfileTierLevel; +} StdVideoH265VideoParameterSet; + +typedef struct StdVideoH265ScalingLists { + uint8_t ScalingList4x4[STD_VIDEO_H265_SCALING_LIST_4X4_NUM_LISTS][STD_VIDEO_H265_SCALING_LIST_4X4_NUM_ELEMENTS]; + uint8_t ScalingList8x8[STD_VIDEO_H265_SCALING_LIST_8X8_NUM_LISTS][STD_VIDEO_H265_SCALING_LIST_8X8_NUM_ELEMENTS]; + uint8_t ScalingList16x16[STD_VIDEO_H265_SCALING_LIST_16X16_NUM_LISTS][STD_VIDEO_H265_SCALING_LIST_16X16_NUM_ELEMENTS]; + uint8_t ScalingList32x32[STD_VIDEO_H265_SCALING_LIST_32X32_NUM_LISTS][STD_VIDEO_H265_SCALING_LIST_32X32_NUM_ELEMENTS]; + uint8_t ScalingListDCCoef16x16[STD_VIDEO_H265_SCALING_LIST_16X16_NUM_LISTS]; + uint8_t ScalingListDCCoef32x32[STD_VIDEO_H265_SCALING_LIST_32X32_NUM_LISTS]; +} StdVideoH265ScalingLists; + +typedef struct StdVideoH265SpsVuiFlags { + uint32_t aspect_ratio_info_present_flag : 1; + uint32_t overscan_info_present_flag : 1; + uint32_t overscan_appropriate_flag : 1; + uint32_t video_signal_type_present_flag : 1; + uint32_t video_full_range_flag : 1; + uint32_t colour_description_present_flag : 1; + uint32_t chroma_loc_info_present_flag : 1; + uint32_t neutral_chroma_indication_flag : 1; + uint32_t field_seq_flag : 1; + uint32_t frame_field_info_present_flag : 1; + uint32_t default_display_window_flag : 1; + uint32_t vui_timing_info_present_flag : 1; + uint32_t vui_poc_proportional_to_timing_flag : 1; + uint32_t vui_hrd_parameters_present_flag : 1; + uint32_t bitstream_restriction_flag : 1; + uint32_t tiles_fixed_structure_flag : 1; + uint32_t motion_vectors_over_pic_boundaries_flag : 1; + uint32_t restricted_ref_pic_lists_flag : 1; +} StdVideoH265SpsVuiFlags; + +typedef struct StdVideoH265SequenceParameterSetVui { + StdVideoH265SpsVuiFlags flags; + StdVideoH265AspectRatioIdc aspect_ratio_idc; + uint16_t sar_width; + uint16_t sar_height; + uint8_t video_format; + uint8_t colour_primaries; + uint8_t transfer_characteristics; + uint8_t matrix_coeffs; + uint8_t chroma_sample_loc_type_top_field; + uint8_t chroma_sample_loc_type_bottom_field; + uint8_t reserved1; + uint8_t reserved2; + uint16_t def_disp_win_left_offset; + uint16_t def_disp_win_right_offset; + uint16_t def_disp_win_top_offset; + uint16_t def_disp_win_bottom_offset; + uint32_t vui_num_units_in_tick; + uint32_t vui_time_scale; + uint32_t vui_num_ticks_poc_diff_one_minus1; + uint16_t min_spatial_segmentation_idc; + uint16_t reserved3; + uint8_t max_bytes_per_pic_denom; + uint8_t max_bits_per_min_cu_denom; + uint8_t log2_max_mv_length_horizontal; + uint8_t log2_max_mv_length_vertical; + const StdVideoH265HrdParameters* pHrdParameters; +} StdVideoH265SequenceParameterSetVui; + +typedef struct StdVideoH265PredictorPaletteEntries { + uint16_t PredictorPaletteEntries[STD_VIDEO_H265_PREDICTOR_PALETTE_COMPONENTS_LIST_SIZE][STD_VIDEO_H265_PREDICTOR_PALETTE_COMP_ENTRIES_LIST_SIZE]; +} StdVideoH265PredictorPaletteEntries; + +typedef struct StdVideoH265SpsFlags { + uint32_t sps_temporal_id_nesting_flag : 1; + uint32_t separate_colour_plane_flag : 1; + uint32_t conformance_window_flag : 1; + uint32_t sps_sub_layer_ordering_info_present_flag : 1; + uint32_t scaling_list_enabled_flag : 1; + uint32_t sps_scaling_list_data_present_flag : 1; + uint32_t amp_enabled_flag : 1; + uint32_t sample_adaptive_offset_enabled_flag : 1; + uint32_t pcm_enabled_flag : 1; + uint32_t pcm_loop_filter_disabled_flag : 1; + uint32_t long_term_ref_pics_present_flag : 1; + uint32_t sps_temporal_mvp_enabled_flag : 1; + uint32_t strong_intra_smoothing_enabled_flag : 1; + uint32_t vui_parameters_present_flag : 1; + uint32_t sps_extension_present_flag : 1; + uint32_t sps_range_extension_flag : 1; + uint32_t transform_skip_rotation_enabled_flag : 1; + uint32_t transform_skip_context_enabled_flag : 1; + uint32_t implicit_rdpcm_enabled_flag : 1; + uint32_t explicit_rdpcm_enabled_flag : 1; + uint32_t extended_precision_processing_flag : 1; + uint32_t intra_smoothing_disabled_flag : 1; + uint32_t high_precision_offsets_enabled_flag : 1; + uint32_t persistent_rice_adaptation_enabled_flag : 1; + uint32_t cabac_bypass_alignment_enabled_flag : 1; + uint32_t sps_scc_extension_flag : 1; + uint32_t sps_curr_pic_ref_enabled_flag : 1; + uint32_t palette_mode_enabled_flag : 1; + uint32_t sps_palette_predictor_initializers_present_flag : 1; + uint32_t intra_boundary_filtering_disabled_flag : 1; +} StdVideoH265SpsFlags; + +typedef struct StdVideoH265ShortTermRefPicSetFlags { + uint32_t inter_ref_pic_set_prediction_flag : 1; + uint32_t delta_rps_sign : 1; +} StdVideoH265ShortTermRefPicSetFlags; + +typedef struct StdVideoH265ShortTermRefPicSet { + StdVideoH265ShortTermRefPicSetFlags flags; + uint32_t delta_idx_minus1; + uint16_t use_delta_flag; + uint16_t abs_delta_rps_minus1; + uint16_t used_by_curr_pic_flag; + uint16_t used_by_curr_pic_s0_flag; + uint16_t used_by_curr_pic_s1_flag; + uint16_t reserved1; + uint8_t reserved2; + uint8_t reserved3; + uint8_t num_negative_pics; + uint8_t num_positive_pics; + uint16_t delta_poc_s0_minus1[STD_VIDEO_H265_MAX_DPB_SIZE]; + uint16_t delta_poc_s1_minus1[STD_VIDEO_H265_MAX_DPB_SIZE]; +} StdVideoH265ShortTermRefPicSet; + +typedef struct StdVideoH265LongTermRefPicsSps { + uint32_t used_by_curr_pic_lt_sps_flag; + uint32_t lt_ref_pic_poc_lsb_sps[STD_VIDEO_H265_MAX_LONG_TERM_REF_PICS_SPS]; +} StdVideoH265LongTermRefPicsSps; + +typedef struct StdVideoH265SequenceParameterSet { + StdVideoH265SpsFlags flags; + StdVideoH265ChromaFormatIdc chroma_format_idc; + uint32_t pic_width_in_luma_samples; + uint32_t pic_height_in_luma_samples; + uint8_t sps_video_parameter_set_id; + uint8_t sps_max_sub_layers_minus1; + uint8_t sps_seq_parameter_set_id; + uint8_t bit_depth_luma_minus8; + uint8_t bit_depth_chroma_minus8; + uint8_t log2_max_pic_order_cnt_lsb_minus4; + uint8_t log2_min_luma_coding_block_size_minus3; + uint8_t log2_diff_max_min_luma_coding_block_size; + uint8_t log2_min_luma_transform_block_size_minus2; + uint8_t log2_diff_max_min_luma_transform_block_size; + uint8_t max_transform_hierarchy_depth_inter; + uint8_t max_transform_hierarchy_depth_intra; + uint8_t num_short_term_ref_pic_sets; + uint8_t num_long_term_ref_pics_sps; + uint8_t pcm_sample_bit_depth_luma_minus1; + uint8_t pcm_sample_bit_depth_chroma_minus1; + uint8_t log2_min_pcm_luma_coding_block_size_minus3; + uint8_t log2_diff_max_min_pcm_luma_coding_block_size; + uint8_t reserved1; + uint8_t reserved2; + uint8_t palette_max_size; + uint8_t delta_palette_max_predictor_size; + uint8_t motion_vector_resolution_control_idc; + uint8_t sps_num_palette_predictor_initializers_minus1; + uint32_t conf_win_left_offset; + uint32_t conf_win_right_offset; + uint32_t conf_win_top_offset; + uint32_t conf_win_bottom_offset; + const StdVideoH265ProfileTierLevel* pProfileTierLevel; + const StdVideoH265DecPicBufMgr* pDecPicBufMgr; + const StdVideoH265ScalingLists* pScalingLists; + const StdVideoH265ShortTermRefPicSet* pShortTermRefPicSet; + const StdVideoH265LongTermRefPicsSps* pLongTermRefPicsSps; + const StdVideoH265SequenceParameterSetVui* pSequenceParameterSetVui; + const StdVideoH265PredictorPaletteEntries* pPredictorPaletteEntries; +} StdVideoH265SequenceParameterSet; + +typedef struct StdVideoH265PpsFlags { + uint32_t dependent_slice_segments_enabled_flag : 1; + uint32_t output_flag_present_flag : 1; + uint32_t sign_data_hiding_enabled_flag : 1; + uint32_t cabac_init_present_flag : 1; + uint32_t constrained_intra_pred_flag : 1; + uint32_t transform_skip_enabled_flag : 1; + uint32_t cu_qp_delta_enabled_flag : 1; + uint32_t pps_slice_chroma_qp_offsets_present_flag : 1; + uint32_t weighted_pred_flag : 1; + uint32_t weighted_bipred_flag : 1; + uint32_t transquant_bypass_enabled_flag : 1; + uint32_t tiles_enabled_flag : 1; + uint32_t entropy_coding_sync_enabled_flag : 1; + uint32_t uniform_spacing_flag : 1; + uint32_t loop_filter_across_tiles_enabled_flag : 1; + uint32_t pps_loop_filter_across_slices_enabled_flag : 1; + uint32_t deblocking_filter_control_present_flag : 1; + uint32_t deblocking_filter_override_enabled_flag : 1; + uint32_t pps_deblocking_filter_disabled_flag : 1; + uint32_t pps_scaling_list_data_present_flag : 1; + uint32_t lists_modification_present_flag : 1; + uint32_t slice_segment_header_extension_present_flag : 1; + uint32_t pps_extension_present_flag : 1; + uint32_t cross_component_prediction_enabled_flag : 1; + uint32_t chroma_qp_offset_list_enabled_flag : 1; + uint32_t pps_curr_pic_ref_enabled_flag : 1; + uint32_t residual_adaptive_colour_transform_enabled_flag : 1; + uint32_t pps_slice_act_qp_offsets_present_flag : 1; + uint32_t pps_palette_predictor_initializers_present_flag : 1; + uint32_t monochrome_palette_flag : 1; + uint32_t pps_range_extension_flag : 1; +} StdVideoH265PpsFlags; + +typedef struct StdVideoH265PictureParameterSet { + StdVideoH265PpsFlags flags; + uint8_t pps_pic_parameter_set_id; + uint8_t pps_seq_parameter_set_id; + uint8_t sps_video_parameter_set_id; + uint8_t num_extra_slice_header_bits; + uint8_t num_ref_idx_l0_default_active_minus1; + uint8_t num_ref_idx_l1_default_active_minus1; + int8_t init_qp_minus26; + uint8_t diff_cu_qp_delta_depth; + int8_t pps_cb_qp_offset; + int8_t pps_cr_qp_offset; + int8_t pps_beta_offset_div2; + int8_t pps_tc_offset_div2; + uint8_t log2_parallel_merge_level_minus2; + uint8_t log2_max_transform_skip_block_size_minus2; + uint8_t diff_cu_chroma_qp_offset_depth; + uint8_t chroma_qp_offset_list_len_minus1; + int8_t cb_qp_offset_list[STD_VIDEO_H265_CHROMA_QP_OFFSET_LIST_SIZE]; + int8_t cr_qp_offset_list[STD_VIDEO_H265_CHROMA_QP_OFFSET_LIST_SIZE]; + uint8_t log2_sao_offset_scale_luma; + uint8_t log2_sao_offset_scale_chroma; + int8_t pps_act_y_qp_offset_plus5; + int8_t pps_act_cb_qp_offset_plus5; + int8_t pps_act_cr_qp_offset_plus3; + uint8_t pps_num_palette_predictor_initializers; + uint8_t luma_bit_depth_entry_minus8; + uint8_t chroma_bit_depth_entry_minus8; + uint8_t num_tile_columns_minus1; + uint8_t num_tile_rows_minus1; + uint8_t reserved1; + uint8_t reserved2; + uint16_t column_width_minus1[STD_VIDEO_H265_CHROMA_QP_OFFSET_TILE_COLS_LIST_SIZE]; + uint16_t row_height_minus1[STD_VIDEO_H265_CHROMA_QP_OFFSET_TILE_ROWS_LIST_SIZE]; + uint32_t reserved3; + const StdVideoH265ScalingLists* pScalingLists; + const StdVideoH265PredictorPaletteEntries* pPredictorPaletteEntries; +} StdVideoH265PictureParameterSet; + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/SDL2-2.30.5/src/video/khronos/vk_video/vulkan_video_codec_h265std_decode.h b/SDL2-2.30.5/src/video/khronos/vk_video/vulkan_video_codec_h265std_decode.h new file mode 100644 index 0000000..0178793 --- /dev/null +++ b/SDL2-2.30.5/src/video/khronos/vk_video/vulkan_video_codec_h265std_decode.h @@ -0,0 +1,67 @@ +#ifndef VULKAN_VIDEO_CODEC_H265STD_DECODE_H_ +#define VULKAN_VIDEO_CODEC_H265STD_DECODE_H_ 1 + +/* +** Copyright 2015-2024 The Khronos Group Inc. +** +** SPDX-License-Identifier: Apache-2.0 +*/ + +/* +** This header is generated from the Khronos Vulkan XML API Registry. +** +*/ + + +#ifdef __cplusplus +extern "C" { +#endif + + + +// vulkan_video_codec_h265std_decode is a preprocessor guard. Do not pass it to API calls. +#define vulkan_video_codec_h265std_decode 1 +#include "vulkan_video_codec_h265std.h" + +#define VK_STD_VULKAN_VIDEO_CODEC_H265_DECODE_API_VERSION_1_0_0 VK_MAKE_VIDEO_STD_VERSION(1, 0, 0) + +#define VK_STD_VULKAN_VIDEO_CODEC_H265_DECODE_SPEC_VERSION VK_STD_VULKAN_VIDEO_CODEC_H265_DECODE_API_VERSION_1_0_0 +#define VK_STD_VULKAN_VIDEO_CODEC_H265_DECODE_EXTENSION_NAME "VK_STD_vulkan_video_codec_h265_decode" +#define STD_VIDEO_DECODE_H265_REF_PIC_SET_LIST_SIZE 8 +typedef struct StdVideoDecodeH265PictureInfoFlags { + uint32_t IrapPicFlag : 1; + uint32_t IdrPicFlag : 1; + uint32_t IsReference : 1; + uint32_t short_term_ref_pic_set_sps_flag : 1; +} StdVideoDecodeH265PictureInfoFlags; + +typedef struct StdVideoDecodeH265PictureInfo { + StdVideoDecodeH265PictureInfoFlags flags; + uint8_t sps_video_parameter_set_id; + uint8_t pps_seq_parameter_set_id; + uint8_t pps_pic_parameter_set_id; + uint8_t NumDeltaPocsOfRefRpsIdx; + int32_t PicOrderCntVal; + uint16_t NumBitsForSTRefPicSetInSlice; + uint16_t reserved; + uint8_t RefPicSetStCurrBefore[STD_VIDEO_DECODE_H265_REF_PIC_SET_LIST_SIZE]; + uint8_t RefPicSetStCurrAfter[STD_VIDEO_DECODE_H265_REF_PIC_SET_LIST_SIZE]; + uint8_t RefPicSetLtCurr[STD_VIDEO_DECODE_H265_REF_PIC_SET_LIST_SIZE]; +} StdVideoDecodeH265PictureInfo; + +typedef struct StdVideoDecodeH265ReferenceInfoFlags { + uint32_t used_for_long_term_reference : 1; + uint32_t unused_for_reference : 1; +} StdVideoDecodeH265ReferenceInfoFlags; + +typedef struct StdVideoDecodeH265ReferenceInfo { + StdVideoDecodeH265ReferenceInfoFlags flags; + int32_t PicOrderCntVal; +} StdVideoDecodeH265ReferenceInfo; + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/SDL2-2.30.5/src/video/khronos/vk_video/vulkan_video_codec_h265std_encode.h b/SDL2-2.30.5/src/video/khronos/vk_video/vulkan_video_codec_h265std_encode.h new file mode 100644 index 0000000..ee34491 --- /dev/null +++ b/SDL2-2.30.5/src/video/khronos/vk_video/vulkan_video_codec_h265std_encode.h @@ -0,0 +1,157 @@ +#ifndef VULKAN_VIDEO_CODEC_H265STD_ENCODE_H_ +#define VULKAN_VIDEO_CODEC_H265STD_ENCODE_H_ 1 + +/* +** Copyright 2015-2024 The Khronos Group Inc. +** +** SPDX-License-Identifier: Apache-2.0 +*/ + +/* +** This header is generated from the Khronos Vulkan XML API Registry. +** +*/ + + +#ifdef __cplusplus +extern "C" { +#endif + + + +// vulkan_video_codec_h265std_encode is a preprocessor guard. Do not pass it to API calls. +#define vulkan_video_codec_h265std_encode 1 +#include "vulkan_video_codec_h265std.h" + +#define VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_API_VERSION_1_0_0 VK_MAKE_VIDEO_STD_VERSION(1, 0, 0) + +#define VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_SPEC_VERSION VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_API_VERSION_1_0_0 +#define VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_EXTENSION_NAME "VK_STD_vulkan_video_codec_h265_encode" +typedef struct StdVideoEncodeH265WeightTableFlags { + uint16_t luma_weight_l0_flag; + uint16_t chroma_weight_l0_flag; + uint16_t luma_weight_l1_flag; + uint16_t chroma_weight_l1_flag; +} StdVideoEncodeH265WeightTableFlags; + +typedef struct StdVideoEncodeH265WeightTable { + StdVideoEncodeH265WeightTableFlags flags; + uint8_t luma_log2_weight_denom; + int8_t delta_chroma_log2_weight_denom; + int8_t delta_luma_weight_l0[STD_VIDEO_H265_MAX_NUM_LIST_REF]; + int8_t luma_offset_l0[STD_VIDEO_H265_MAX_NUM_LIST_REF]; + int8_t delta_chroma_weight_l0[STD_VIDEO_H265_MAX_NUM_LIST_REF][STD_VIDEO_H265_MAX_CHROMA_PLANES]; + int8_t delta_chroma_offset_l0[STD_VIDEO_H265_MAX_NUM_LIST_REF][STD_VIDEO_H265_MAX_CHROMA_PLANES]; + int8_t delta_luma_weight_l1[STD_VIDEO_H265_MAX_NUM_LIST_REF]; + int8_t luma_offset_l1[STD_VIDEO_H265_MAX_NUM_LIST_REF]; + int8_t delta_chroma_weight_l1[STD_VIDEO_H265_MAX_NUM_LIST_REF][STD_VIDEO_H265_MAX_CHROMA_PLANES]; + int8_t delta_chroma_offset_l1[STD_VIDEO_H265_MAX_NUM_LIST_REF][STD_VIDEO_H265_MAX_CHROMA_PLANES]; +} StdVideoEncodeH265WeightTable; + +typedef struct StdVideoEncodeH265SliceSegmentHeaderFlags { + uint32_t first_slice_segment_in_pic_flag : 1; + uint32_t dependent_slice_segment_flag : 1; + uint32_t slice_sao_luma_flag : 1; + uint32_t slice_sao_chroma_flag : 1; + uint32_t num_ref_idx_active_override_flag : 1; + uint32_t mvd_l1_zero_flag : 1; + uint32_t cabac_init_flag : 1; + uint32_t cu_chroma_qp_offset_enabled_flag : 1; + uint32_t deblocking_filter_override_flag : 1; + uint32_t slice_deblocking_filter_disabled_flag : 1; + uint32_t collocated_from_l0_flag : 1; + uint32_t slice_loop_filter_across_slices_enabled_flag : 1; + uint32_t reserved : 20; +} StdVideoEncodeH265SliceSegmentHeaderFlags; + +typedef struct StdVideoEncodeH265SliceSegmentHeader { + StdVideoEncodeH265SliceSegmentHeaderFlags flags; + StdVideoH265SliceType slice_type; + uint32_t slice_segment_address; + uint8_t collocated_ref_idx; + uint8_t MaxNumMergeCand; + int8_t slice_cb_qp_offset; + int8_t slice_cr_qp_offset; + int8_t slice_beta_offset_div2; + int8_t slice_tc_offset_div2; + int8_t slice_act_y_qp_offset; + int8_t slice_act_cb_qp_offset; + int8_t slice_act_cr_qp_offset; + int8_t slice_qp_delta; + uint16_t reserved1; + const StdVideoEncodeH265WeightTable* pWeightTable; +} StdVideoEncodeH265SliceSegmentHeader; + +typedef struct StdVideoEncodeH265ReferenceListsInfoFlags { + uint32_t ref_pic_list_modification_flag_l0 : 1; + uint32_t ref_pic_list_modification_flag_l1 : 1; + uint32_t reserved : 30; +} StdVideoEncodeH265ReferenceListsInfoFlags; + +typedef struct StdVideoEncodeH265ReferenceListsInfo { + StdVideoEncodeH265ReferenceListsInfoFlags flags; + uint8_t num_ref_idx_l0_active_minus1; + uint8_t num_ref_idx_l1_active_minus1; + uint8_t RefPicList0[STD_VIDEO_H265_MAX_NUM_LIST_REF]; + uint8_t RefPicList1[STD_VIDEO_H265_MAX_NUM_LIST_REF]; + uint8_t list_entry_l0[STD_VIDEO_H265_MAX_NUM_LIST_REF]; + uint8_t list_entry_l1[STD_VIDEO_H265_MAX_NUM_LIST_REF]; +} StdVideoEncodeH265ReferenceListsInfo; + +typedef struct StdVideoEncodeH265PictureInfoFlags { + uint32_t is_reference : 1; + uint32_t IrapPicFlag : 1; + uint32_t used_for_long_term_reference : 1; + uint32_t discardable_flag : 1; + uint32_t cross_layer_bla_flag : 1; + uint32_t pic_output_flag : 1; + uint32_t no_output_of_prior_pics_flag : 1; + uint32_t short_term_ref_pic_set_sps_flag : 1; + uint32_t slice_temporal_mvp_enabled_flag : 1; + uint32_t reserved : 23; +} StdVideoEncodeH265PictureInfoFlags; + +typedef struct StdVideoEncodeH265LongTermRefPics { + uint8_t num_long_term_sps; + uint8_t num_long_term_pics; + uint8_t lt_idx_sps[STD_VIDEO_H265_MAX_LONG_TERM_REF_PICS_SPS]; + uint8_t poc_lsb_lt[STD_VIDEO_H265_MAX_LONG_TERM_PICS]; + uint16_t used_by_curr_pic_lt_flag; + uint8_t delta_poc_msb_present_flag[STD_VIDEO_H265_MAX_DELTA_POC]; + uint8_t delta_poc_msb_cycle_lt[STD_VIDEO_H265_MAX_DELTA_POC]; +} StdVideoEncodeH265LongTermRefPics; + +typedef struct StdVideoEncodeH265PictureInfo { + StdVideoEncodeH265PictureInfoFlags flags; + StdVideoH265PictureType pic_type; + uint8_t sps_video_parameter_set_id; + uint8_t pps_seq_parameter_set_id; + uint8_t pps_pic_parameter_set_id; + uint8_t short_term_ref_pic_set_idx; + int32_t PicOrderCntVal; + uint8_t TemporalId; + uint8_t reserved1[7]; + const StdVideoEncodeH265ReferenceListsInfo* pRefLists; + const StdVideoH265ShortTermRefPicSet* pShortTermRefPicSet; + const StdVideoEncodeH265LongTermRefPics* pLongTermRefPics; +} StdVideoEncodeH265PictureInfo; + +typedef struct StdVideoEncodeH265ReferenceInfoFlags { + uint32_t used_for_long_term_reference : 1; + uint32_t unused_for_reference : 1; + uint32_t reserved : 30; +} StdVideoEncodeH265ReferenceInfoFlags; + +typedef struct StdVideoEncodeH265ReferenceInfo { + StdVideoEncodeH265ReferenceInfoFlags flags; + StdVideoH265PictureType pic_type; + int32_t PicOrderCntVal; + uint8_t TemporalId; +} StdVideoEncodeH265ReferenceInfo; + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/SDL2-2.30.5/src/video/khronos/vk_video/vulkan_video_codecs_common.h b/SDL2-2.30.5/src/video/khronos/vk_video/vulkan_video_codecs_common.h new file mode 100644 index 0000000..5e6ef1d --- /dev/null +++ b/SDL2-2.30.5/src/video/khronos/vk_video/vulkan_video_codecs_common.h @@ -0,0 +1,36 @@ +#ifndef VULKAN_VIDEO_CODECS_COMMON_H_ +#define VULKAN_VIDEO_CODECS_COMMON_H_ 1 + +/* +** Copyright 2015-2024 The Khronos Group Inc. +** +** SPDX-License-Identifier: Apache-2.0 +*/ + +/* +** This header is generated from the Khronos Vulkan XML API Registry. +** +*/ + + +#ifdef __cplusplus +extern "C" { +#endif + + + +// vulkan_video_codecs_common is a preprocessor guard. Do not pass it to API calls. +#define vulkan_video_codecs_common 1 +#if !defined(VK_NO_STDINT_H) + #include +#endif + +#define VK_MAKE_VIDEO_STD_VERSION(major, minor, patch) \ + ((((uint32_t)(major)) << 22) | (((uint32_t)(minor)) << 12) | ((uint32_t)(patch))) + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/SDL2-2.0.12/src/video/khronos/vulkan/vk_icd.h b/SDL2-2.30.5/src/video/khronos/vulkan/vk_icd.h similarity index 54% rename from SDL2-2.0.12/src/video/khronos/vulkan/vk_icd.h rename to SDL2-2.30.5/src/video/khronos/vulkan/vk_icd.h index b935fa1..59204a3 100644 --- a/SDL2-2.0.12/src/video/khronos/vulkan/vk_icd.h +++ b/SDL2-2.30.5/src/video/khronos/vulkan/vk_icd.h @@ -1,27 +1,11 @@ -// -// File: vk_icd.h -// /* - * Copyright (c) 2015-2016 The Khronos Group Inc. - * Copyright (c) 2015-2016 Valve Corporation - * Copyright (c) 2015-2016 LunarG, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2015-2023 The Khronos Group Inc. + * Copyright 2015-2023 Valve Corporation + * Copyright 2015-2023 LunarG, Inc. * + * SPDX-License-Identifier: Apache-2.0 */ - -#ifndef VKICD_H -#define VKICD_H +#pragma once #include "vulkan.h" #include @@ -33,7 +17,7 @@ // Version 2 - Add Loader/ICD Interface version negotiation // via vk_icdNegotiateLoaderICDInterfaceVersion. // Version 3 - Add ICD creation/destruction of KHR_surface objects. -// Version 4 - Add unknown physical device extension qyering via +// Version 4 - Add unknown physical device extension querying via // vk_icdGetPhysicalDeviceProcAddr. // Version 5 - Tells ICDs that the loader is now paying attention to the // application version of Vulkan passed into the ApplicationInfo @@ -41,17 +25,55 @@ // that if the loader is older, it should automatically fail a // call for any API version > 1.0. Otherwise, the loader will // manually determine if it can support the expected version. -#define CURRENT_LOADER_ICD_INTERFACE_VERSION 5 +// Version 6 - Add support for vk_icdEnumerateAdapterPhysicalDevices. +// Version 7 - If an ICD supports any of the following functions, they must be +// queryable with vk_icdGetInstanceProcAddr: +// vk_icdNegotiateLoaderICDInterfaceVersion +// vk_icdGetPhysicalDeviceProcAddr +// vk_icdEnumerateAdapterPhysicalDevices (Windows only) +// In addition, these functions no longer need to be exported directly. +// This version allows drivers provided through the extension +// VK_LUNARG_direct_driver_loading be able to support the entire +// Driver-Loader interface. + +#define CURRENT_LOADER_ICD_INTERFACE_VERSION 7 #define MIN_SUPPORTED_LOADER_ICD_INTERFACE_VERSION 0 #define MIN_PHYS_DEV_EXTENSION_ICD_INTERFACE_VERSION 4 -typedef VkResult(VKAPI_PTR *PFN_vkNegotiateLoaderICDInterfaceVersion)(uint32_t *pVersion); +// Old typedefs that don't follow a proper naming convention but are preserved for compatibility +typedef VkResult(VKAPI_PTR *PFN_vkNegotiateLoaderICDInterfaceVersion)(uint32_t *pVersion); // This is defined in vk_layer.h which will be found by the loader, but if an ICD is building against this // file directly, it won't be found. #ifndef PFN_GetPhysicalDeviceProcAddr typedef PFN_vkVoidFunction(VKAPI_PTR *PFN_GetPhysicalDeviceProcAddr)(VkInstance instance, const char *pName); #endif +// Typedefs for loader/ICD interface +typedef VkResult (VKAPI_PTR *PFN_vk_icdNegotiateLoaderICDInterfaceVersion)(uint32_t* pVersion); +typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_vk_icdGetInstanceProcAddr)(VkInstance instance, const char* pName); +typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_vk_icdGetPhysicalDeviceProcAddr)(VkInstance instance, const char* pName); +#if defined(VK_USE_PLATFORM_WIN32_KHR) +typedef VkResult (VKAPI_PTR *PFN_vk_icdEnumerateAdapterPhysicalDevices)(VkInstance instance, LUID adapterLUID, + uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices); +#endif + +// Prototypes for loader/ICD interface +#if !defined(VK_NO_PROTOTYPES) +#ifdef __cplusplus +extern "C" { +#endif + VKAPI_ATTR VkResult VKAPI_CALL vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pVersion); + VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetInstanceProcAddr(VkInstance instance, const char* pName); + VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetPhysicalDeviceProcAddr(VkInstance instance, const char* pName); +#if defined(VK_USE_PLATFORM_WIN32_KHR) + VKAPI_ATTR VkResult VKAPI_CALL vk_icdEnumerateAdapterPhysicalDevices(VkInstance instance, LUID adapterLUID, + uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices); +#endif +#ifdef __cplusplus +} +#endif +#endif + /* * The ICD must reserve space for a pointer for the loader's dispatch * table, at the start of . @@ -88,7 +110,14 @@ typedef enum { VK_ICD_WSI_PLATFORM_ANDROID, VK_ICD_WSI_PLATFORM_MACOS, VK_ICD_WSI_PLATFORM_IOS, - VK_ICD_WSI_PLATFORM_DISPLAY + VK_ICD_WSI_PLATFORM_DISPLAY, + VK_ICD_WSI_PLATFORM_HEADLESS, + VK_ICD_WSI_PLATFORM_METAL, + VK_ICD_WSI_PLATFORM_DIRECTFB, + VK_ICD_WSI_PLATFORM_VI, + VK_ICD_WSI_PLATFORM_GGP, + VK_ICD_WSI_PLATFORM_SCREEN, + VK_ICD_WSI_PLATFORM_FUCHSIA, } VkIcdWsiPlatform; typedef struct { @@ -135,6 +164,14 @@ typedef struct { } VkIcdSurfaceXlib; #endif // VK_USE_PLATFORM_XLIB_KHR +#ifdef VK_USE_PLATFORM_DIRECTFB_EXT +typedef struct { + VkIcdSurfaceBase base; + IDirectFB *dfb; + IDirectFBSurface *surface; +} VkIcdSurfaceDirectFB; +#endif // VK_USE_PLATFORM_DIRECTFB_EXT + #ifdef VK_USE_PLATFORM_ANDROID_KHR typedef struct { VkIcdSurfaceBase base; @@ -156,6 +193,13 @@ typedef struct { } VkIcdSurfaceIOS; #endif // VK_USE_PLATFORM_IOS_MVK +#ifdef VK_USE_PLATFORM_GGP +typedef struct { + VkIcdSurfaceBase base; + GgpStreamDescriptor streamDescriptor; +} VkIcdSurfaceGgp; +#endif // VK_USE_PLATFORM_GGP + typedef struct { VkIcdSurfaceBase base; VkDisplayModeKHR displayMode; @@ -167,4 +211,34 @@ typedef struct { VkExtent2D imageExtent; } VkIcdSurfaceDisplay; -#endif // VKICD_H +typedef struct { + VkIcdSurfaceBase base; +} VkIcdSurfaceHeadless; + +#ifdef VK_USE_PLATFORM_METAL_EXT +typedef struct { + VkIcdSurfaceBase base; + const CAMetalLayer *pLayer; +} VkIcdSurfaceMetal; +#endif // VK_USE_PLATFORM_METAL_EXT + +#ifdef VK_USE_PLATFORM_VI_NN +typedef struct { + VkIcdSurfaceBase base; + void *window; +} VkIcdSurfaceVi; +#endif // VK_USE_PLATFORM_VI_NN + +#ifdef VK_USE_PLATFORM_SCREEN_QNX +typedef struct { + VkIcdSurfaceBase base; + struct _screen_context *context; + struct _screen_window *window; +} VkIcdSurfaceScreen; +#endif // VK_USE_PLATFORM_SCREEN_QNX + +#ifdef VK_USE_PLATFORM_FUCHSIA +typedef struct { + VkIcdSurfaceBase base; +} VkIcdSurfaceImagePipe; +#endif // VK_USE_PLATFORM_FUCHSIA diff --git a/SDL2-2.0.12/src/video/khronos/vulkan/vk_layer.h b/SDL2-2.30.5/src/video/khronos/vulkan/vk_layer.h similarity index 84% rename from SDL2-2.0.12/src/video/khronos/vulkan/vk_layer.h rename to SDL2-2.30.5/src/video/khronos/vulkan/vk_layer.h index 823c88a..19d88fc 100644 --- a/SDL2-2.0.12/src/video/khronos/vulkan/vk_layer.h +++ b/SDL2-2.30.5/src/video/khronos/vulkan/vk_layer.h @@ -1,39 +1,18 @@ -// -// File: vk_layer.h -// /* - * Copyright (c) 2015-2017 The Khronos Group Inc. - * Copyright (c) 2015-2017 Valve Corporation - * Copyright (c) 2015-2017 LunarG, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2015-2023 The Khronos Group Inc. + * Copyright 2015-2023 Valve Corporation + * Copyright 2015-2023 LunarG, Inc. * + * SPDX-License-Identifier: Apache-2.0 */ +#pragma once /* Need to define dispatch table * Core struct can then have ptr to dispatch table at the top * Along with object ptrs for current and next OBJ */ -#pragma once -#include "vulkan.h" -#if defined(__GNUC__) && __GNUC__ >= 4 -#define VK_LAYER_EXPORT __attribute__((visibility("default"))) -#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590) -#define VK_LAYER_EXPORT __attribute__((visibility("default"))) -#else -#define VK_LAYER_EXPORT -#endif +#include "vulkan_core.h" #define MAX_NUM_UNKNOWN_EXTS 250 @@ -82,7 +61,9 @@ typedef VkResult(VKAPI_PTR *PFN_PhysDevExt)(VkPhysicalDevice phys_device); */ typedef enum VkLayerFunction_ { VK_LAYER_LINK_INFO = 0, - VK_LOADER_DATA_CALLBACK = 1 + VK_LOADER_DATA_CALLBACK = 1, + VK_LOADER_LAYER_CREATE_DEVICE_CALLBACK = 2, + VK_LOADER_FEATURES = 3, } VkLayerFunction; typedef struct VkLayerInstanceLink_ { @@ -107,6 +88,14 @@ typedef VkResult (VKAPI_PTR *PFN_vkSetInstanceLoaderData)(VkInstance instance, void *object); typedef VkResult (VKAPI_PTR *PFN_vkSetDeviceLoaderData)(VkDevice device, void *object); +typedef VkResult (VKAPI_PTR *PFN_vkLayerCreateDevice)(VkInstance instance, VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkDevice *pDevice, PFN_vkGetInstanceProcAddr layerGIPA, PFN_vkGetDeviceProcAddr *nextGDPA); +typedef void (VKAPI_PTR *PFN_vkLayerDestroyDevice)(VkDevice physicalDevice, const VkAllocationCallbacks *pAllocator, PFN_vkDestroyDevice destroyFunction); + +typedef enum VkLoaderFeastureFlagBits { + VK_LOADER_FEATURE_PHYSICAL_DEVICE_SORTING = 0x00000001, +} VkLoaderFlagBits; +typedef VkFlags VkLoaderFeatureFlags; typedef struct { VkStructureType sType; // VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO @@ -115,6 +104,11 @@ typedef struct { union { VkLayerInstanceLink *pLayerInfo; PFN_vkSetInstanceLoaderData pfnSetInstanceLoaderData; + struct { + PFN_vkLayerCreateDevice pfnLayerCreateDevice; + PFN_vkLayerDestroyDevice pfnLayerDestroyDevice; + } layerDevice; + VkLoaderFeatureFlags loaderFeatures; } u; } VkLayerInstanceCreateInfo; diff --git a/SDL2-2.0.12/src/video/khronos/vulkan/vk_platform.h b/SDL2-2.30.5/src/video/khronos/vulkan/vk_platform.h similarity index 79% rename from SDL2-2.0.12/src/video/khronos/vulkan/vk_platform.h rename to SDL2-2.30.5/src/video/khronos/vulkan/vk_platform.h index 7289299..0ecd4f6 100644 --- a/SDL2-2.0.12/src/video/khronos/vulkan/vk_platform.h +++ b/SDL2-2.30.5/src/video/khronos/vulkan/vk_platform.h @@ -2,19 +2,9 @@ // File: vk_platform.h // /* -** Copyright (c) 2014-2017 The Khronos Group Inc. +** Copyright 2014-2024 The Khronos Group Inc. ** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. +** SPDX-License-Identifier: Apache-2.0 */ @@ -52,7 +42,7 @@ extern "C" #define VKAPI_CALL __stdcall #define VKAPI_PTR VKAPI_CALL #elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH < 7 - #error "Vulkan isn't supported for the 'armeabi' NDK ABI" + #error "Vulkan is not supported for the 'armeabi' NDK ABI" #elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7 && defined(__ARM_32BIT_STATE) // On Android 32-bit ARM targets, Vulkan functions use the "hardfloat" // calling convention, i.e. float parameters are passed in registers. This @@ -68,7 +58,9 @@ extern "C" #define VKAPI_PTR #endif -#include +#if !defined(VK_NO_STDDEF_H) + #include +#endif // !defined(VK_NO_STDDEF_H) #if !defined(VK_NO_STDINT_H) #if defined(_MSC_VER) && (_MSC_VER < 1600) diff --git a/SDL2-2.0.12/src/video/khronos/vulkan/vk_sdk_platform.h b/SDL2-2.30.5/src/video/khronos/vulkan/vk_sdk_platform.h similarity index 100% rename from SDL2-2.0.12/src/video/khronos/vulkan/vk_sdk_platform.h rename to SDL2-2.30.5/src/video/khronos/vulkan/vk_sdk_platform.h diff --git a/SDL2-2.0.12/src/video/khronos/vulkan/vulkan.h b/SDL2-2.30.5/src/video/khronos/vulkan/vulkan.h similarity index 59% rename from SDL2-2.0.12/src/video/khronos/vulkan/vulkan.h rename to SDL2-2.30.5/src/video/khronos/vulkan/vulkan.h index 77da637..ef94006 100644 --- a/SDL2-2.0.12/src/video/khronos/vulkan/vulkan.h +++ b/SDL2-2.30.5/src/video/khronos/vulkan/vulkan.h @@ -2,19 +2,9 @@ #define VULKAN_H_ 1 /* -** Copyright (c) 2015-2018 The Khronos Group Inc. +** Copyright 2015-2024 The Khronos Group Inc. ** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. +** SPDX-License-Identifier: Apache-2.0 */ #include "vk_platform.h" @@ -38,6 +28,9 @@ #include "vulkan_macos.h" #endif +#ifdef VK_USE_PLATFORM_METAL_EXT +#include "vulkan_metal.h" +#endif #ifdef VK_USE_PLATFORM_VI_NN #include "vulkan_vi.h" @@ -45,7 +38,6 @@ #ifdef VK_USE_PLATFORM_WAYLAND_KHR -#include #include "vulkan_wayland.h" #endif @@ -68,10 +60,40 @@ #endif +#ifdef VK_USE_PLATFORM_DIRECTFB_EXT +#include +#include "vulkan_directfb.h" +#endif + + #ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT #include #include #include "vulkan_xlib_xrandr.h" #endif + +#ifdef VK_USE_PLATFORM_GGP +#include +#include "vulkan_ggp.h" +#endif + + +#ifdef VK_USE_PLATFORM_SCREEN_QNX +#include +#include "vulkan_screen.h" +#endif + + +#ifdef VK_USE_PLATFORM_SCI +#include +#include +#include "vulkan_sci.h" +#endif + + +#ifdef VK_ENABLE_BETA_EXTENSIONS +#include "vulkan_beta.h" +#endif + #endif // VULKAN_H_ diff --git a/SDL2-2.0.12/src/video/khronos/vulkan/vulkan_android.h b/SDL2-2.30.5/src/video/khronos/vulkan/vulkan_android.h similarity index 66% rename from SDL2-2.0.12/src/video/khronos/vulkan/vulkan_android.h rename to SDL2-2.30.5/src/video/khronos/vulkan/vulkan_android.h index 07aaeda..61ff40b 100644 --- a/SDL2-2.0.12/src/video/khronos/vulkan/vulkan_android.h +++ b/SDL2-2.30.5/src/video/khronos/vulkan/vulkan_android.h @@ -1,24 +1,10 @@ #ifndef VULKAN_ANDROID_H_ #define VULKAN_ANDROID_H_ 1 -#ifdef __cplusplus -extern "C" { -#endif - /* -** Copyright (c) 2015-2018 The Khronos Group Inc. +** Copyright 2015-2024 The Khronos Group Inc. ** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. +** SPDX-License-Identifier: Apache-2.0 */ /* @@ -27,14 +13,18 @@ extern "C" { */ +#ifdef __cplusplus +extern "C" { +#endif + + + +// VK_KHR_android_surface is a preprocessor guard. Do not pass it to API calls. #define VK_KHR_android_surface 1 struct ANativeWindow; - #define VK_KHR_ANDROID_SURFACE_SPEC_VERSION 6 #define VK_KHR_ANDROID_SURFACE_EXTENSION_NAME "VK_KHR_android_surface" - typedef VkFlags VkAndroidSurfaceCreateFlagsKHR; - typedef struct VkAndroidSurfaceCreateInfoKHR { VkStructureType sType; const void* pNext; @@ -42,7 +32,6 @@ typedef struct VkAndroidSurfaceCreateInfoKHR { struct ANativeWindow* window; } VkAndroidSurfaceCreateInfoKHR; - typedef VkResult (VKAPI_PTR *PFN_vkCreateAndroidSurfaceKHR)(VkInstance instance, const VkAndroidSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); #ifndef VK_NO_PROTOTYPES @@ -53,12 +42,12 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateAndroidSurfaceKHR( VkSurfaceKHR* pSurface); #endif + +// VK_ANDROID_external_memory_android_hardware_buffer is a preprocessor guard. Do not pass it to API calls. #define VK_ANDROID_external_memory_android_hardware_buffer 1 struct AHardwareBuffer; - -#define VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_SPEC_VERSION 3 +#define VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_SPEC_VERSION 5 #define VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME "VK_ANDROID_external_memory_android_hardware_buffer" - typedef struct VkAndroidHardwareBufferUsageANDROID { VkStructureType sType; void* pNext; @@ -103,6 +92,18 @@ typedef struct VkExternalFormatANDROID { uint64_t externalFormat; } VkExternalFormatANDROID; +typedef struct VkAndroidHardwareBufferFormatProperties2ANDROID { + VkStructureType sType; + void* pNext; + VkFormat format; + uint64_t externalFormat; + VkFormatFeatureFlags2 formatFeatures; + VkComponentMapping samplerYcbcrConversionComponents; + VkSamplerYcbcrModelConversion suggestedYcbcrModel; + VkSamplerYcbcrRange suggestedYcbcrRange; + VkChromaLocation suggestedXChromaOffset; + VkChromaLocation suggestedYChromaOffset; +} VkAndroidHardwareBufferFormatProperties2ANDROID; typedef VkResult (VKAPI_PTR *PFN_vkGetAndroidHardwareBufferPropertiesANDROID)(VkDevice device, const struct AHardwareBuffer* buffer, VkAndroidHardwareBufferPropertiesANDROID* pProperties); typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryAndroidHardwareBufferANDROID)(VkDevice device, const VkMemoryGetAndroidHardwareBufferInfoANDROID* pInfo, struct AHardwareBuffer** pBuffer); @@ -119,6 +120,32 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryAndroidHardwareBufferANDROID( struct AHardwareBuffer** pBuffer); #endif + +// VK_ANDROID_external_format_resolve is a preprocessor guard. Do not pass it to API calls. +#define VK_ANDROID_external_format_resolve 1 +#define VK_ANDROID_EXTERNAL_FORMAT_RESOLVE_SPEC_VERSION 1 +#define VK_ANDROID_EXTERNAL_FORMAT_RESOLVE_EXTENSION_NAME "VK_ANDROID_external_format_resolve" +typedef struct VkPhysicalDeviceExternalFormatResolveFeaturesANDROID { + VkStructureType sType; + void* pNext; + VkBool32 externalFormatResolve; +} VkPhysicalDeviceExternalFormatResolveFeaturesANDROID; + +typedef struct VkPhysicalDeviceExternalFormatResolvePropertiesANDROID { + VkStructureType sType; + void* pNext; + VkBool32 nullColorAttachmentWithExternalFormatResolve; + VkChromaLocation externalFormatResolveChromaOffsetX; + VkChromaLocation externalFormatResolveChromaOffsetY; +} VkPhysicalDeviceExternalFormatResolvePropertiesANDROID; + +typedef struct VkAndroidHardwareBufferFormatResolvePropertiesANDROID { + VkStructureType sType; + void* pNext; + VkFormat colorAttachmentFormat; +} VkAndroidHardwareBufferFormatResolvePropertiesANDROID; + + #ifdef __cplusplus } #endif diff --git a/SDL2-2.30.5/src/video/khronos/vulkan/vulkan_beta.h b/SDL2-2.30.5/src/video/khronos/vulkan/vulkan_beta.h new file mode 100644 index 0000000..df18b40 --- /dev/null +++ b/SDL2-2.30.5/src/video/khronos/vulkan/vulkan_beta.h @@ -0,0 +1,216 @@ +#ifndef VULKAN_BETA_H_ +#define VULKAN_BETA_H_ 1 + +/* +** Copyright 2015-2024 The Khronos Group Inc. +** +** SPDX-License-Identifier: Apache-2.0 +*/ + +/* +** This header is generated from the Khronos Vulkan XML API Registry. +** +*/ + + +#ifdef __cplusplus +extern "C" { +#endif + + + +// VK_KHR_portability_subset is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_portability_subset 1 +#define VK_KHR_PORTABILITY_SUBSET_SPEC_VERSION 1 +#define VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME "VK_KHR_portability_subset" +typedef struct VkPhysicalDevicePortabilitySubsetFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 constantAlphaColorBlendFactors; + VkBool32 events; + VkBool32 imageViewFormatReinterpretation; + VkBool32 imageViewFormatSwizzle; + VkBool32 imageView2DOn3DImage; + VkBool32 multisampleArrayImage; + VkBool32 mutableComparisonSamplers; + VkBool32 pointPolygons; + VkBool32 samplerMipLodBias; + VkBool32 separateStencilMaskRef; + VkBool32 shaderSampleRateInterpolationFunctions; + VkBool32 tessellationIsolines; + VkBool32 tessellationPointMode; + VkBool32 triangleFans; + VkBool32 vertexAttributeAccessBeyondStride; +} VkPhysicalDevicePortabilitySubsetFeaturesKHR; + +typedef struct VkPhysicalDevicePortabilitySubsetPropertiesKHR { + VkStructureType sType; + void* pNext; + uint32_t minVertexInputBindingStrideAlignment; +} VkPhysicalDevicePortabilitySubsetPropertiesKHR; + + + +// VK_AMDX_shader_enqueue is a preprocessor guard. Do not pass it to API calls. +#define VK_AMDX_shader_enqueue 1 +#define VK_AMDX_SHADER_ENQUEUE_SPEC_VERSION 1 +#define VK_AMDX_SHADER_ENQUEUE_EXTENSION_NAME "VK_AMDX_shader_enqueue" +#define VK_SHADER_INDEX_UNUSED_AMDX (~0U) +typedef struct VkPhysicalDeviceShaderEnqueueFeaturesAMDX { + VkStructureType sType; + void* pNext; + VkBool32 shaderEnqueue; +} VkPhysicalDeviceShaderEnqueueFeaturesAMDX; + +typedef struct VkPhysicalDeviceShaderEnqueuePropertiesAMDX { + VkStructureType sType; + void* pNext; + uint32_t maxExecutionGraphDepth; + uint32_t maxExecutionGraphShaderOutputNodes; + uint32_t maxExecutionGraphShaderPayloadSize; + uint32_t maxExecutionGraphShaderPayloadCount; + uint32_t executionGraphDispatchAddressAlignment; +} VkPhysicalDeviceShaderEnqueuePropertiesAMDX; + +typedef struct VkExecutionGraphPipelineScratchSizeAMDX { + VkStructureType sType; + void* pNext; + VkDeviceSize size; +} VkExecutionGraphPipelineScratchSizeAMDX; + +typedef struct VkExecutionGraphPipelineCreateInfoAMDX { + VkStructureType sType; + const void* pNext; + VkPipelineCreateFlags flags; + uint32_t stageCount; + const VkPipelineShaderStageCreateInfo* pStages; + const VkPipelineLibraryCreateInfoKHR* pLibraryInfo; + VkPipelineLayout layout; + VkPipeline basePipelineHandle; + int32_t basePipelineIndex; +} VkExecutionGraphPipelineCreateInfoAMDX; + +typedef union VkDeviceOrHostAddressConstAMDX { + VkDeviceAddress deviceAddress; + const void* hostAddress; +} VkDeviceOrHostAddressConstAMDX; + +typedef struct VkDispatchGraphInfoAMDX { + uint32_t nodeIndex; + uint32_t payloadCount; + VkDeviceOrHostAddressConstAMDX payloads; + uint64_t payloadStride; +} VkDispatchGraphInfoAMDX; + +typedef struct VkDispatchGraphCountInfoAMDX { + uint32_t count; + VkDeviceOrHostAddressConstAMDX infos; + uint64_t stride; +} VkDispatchGraphCountInfoAMDX; + +typedef struct VkPipelineShaderStageNodeCreateInfoAMDX { + VkStructureType sType; + const void* pNext; + const char* pName; + uint32_t index; +} VkPipelineShaderStageNodeCreateInfoAMDX; + +typedef VkResult (VKAPI_PTR *PFN_vkCreateExecutionGraphPipelinesAMDX)(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkExecutionGraphPipelineCreateInfoAMDX* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines); +typedef VkResult (VKAPI_PTR *PFN_vkGetExecutionGraphPipelineScratchSizeAMDX)(VkDevice device, VkPipeline executionGraph, VkExecutionGraphPipelineScratchSizeAMDX* pSizeInfo); +typedef VkResult (VKAPI_PTR *PFN_vkGetExecutionGraphPipelineNodeIndexAMDX)(VkDevice device, VkPipeline executionGraph, const VkPipelineShaderStageNodeCreateInfoAMDX* pNodeInfo, uint32_t* pNodeIndex); +typedef void (VKAPI_PTR *PFN_vkCmdInitializeGraphScratchMemoryAMDX)(VkCommandBuffer commandBuffer, VkDeviceAddress scratch); +typedef void (VKAPI_PTR *PFN_vkCmdDispatchGraphAMDX)(VkCommandBuffer commandBuffer, VkDeviceAddress scratch, const VkDispatchGraphCountInfoAMDX* pCountInfo); +typedef void (VKAPI_PTR *PFN_vkCmdDispatchGraphIndirectAMDX)(VkCommandBuffer commandBuffer, VkDeviceAddress scratch, const VkDispatchGraphCountInfoAMDX* pCountInfo); +typedef void (VKAPI_PTR *PFN_vkCmdDispatchGraphIndirectCountAMDX)(VkCommandBuffer commandBuffer, VkDeviceAddress scratch, VkDeviceAddress countInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateExecutionGraphPipelinesAMDX( + VkDevice device, + VkPipelineCache pipelineCache, + uint32_t createInfoCount, + const VkExecutionGraphPipelineCreateInfoAMDX* pCreateInfos, + const VkAllocationCallbacks* pAllocator, + VkPipeline* pPipelines); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetExecutionGraphPipelineScratchSizeAMDX( + VkDevice device, + VkPipeline executionGraph, + VkExecutionGraphPipelineScratchSizeAMDX* pSizeInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetExecutionGraphPipelineNodeIndexAMDX( + VkDevice device, + VkPipeline executionGraph, + const VkPipelineShaderStageNodeCreateInfoAMDX* pNodeInfo, + uint32_t* pNodeIndex); + +VKAPI_ATTR void VKAPI_CALL vkCmdInitializeGraphScratchMemoryAMDX( + VkCommandBuffer commandBuffer, + VkDeviceAddress scratch); + +VKAPI_ATTR void VKAPI_CALL vkCmdDispatchGraphAMDX( + VkCommandBuffer commandBuffer, + VkDeviceAddress scratch, + const VkDispatchGraphCountInfoAMDX* pCountInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdDispatchGraphIndirectAMDX( + VkCommandBuffer commandBuffer, + VkDeviceAddress scratch, + const VkDispatchGraphCountInfoAMDX* pCountInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdDispatchGraphIndirectCountAMDX( + VkCommandBuffer commandBuffer, + VkDeviceAddress scratch, + VkDeviceAddress countInfo); +#endif + + +// VK_NV_displacement_micromap is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_displacement_micromap 1 +#define VK_NV_DISPLACEMENT_MICROMAP_SPEC_VERSION 2 +#define VK_NV_DISPLACEMENT_MICROMAP_EXTENSION_NAME "VK_NV_displacement_micromap" + +typedef enum VkDisplacementMicromapFormatNV { + VK_DISPLACEMENT_MICROMAP_FORMAT_64_TRIANGLES_64_BYTES_NV = 1, + VK_DISPLACEMENT_MICROMAP_FORMAT_256_TRIANGLES_128_BYTES_NV = 2, + VK_DISPLACEMENT_MICROMAP_FORMAT_1024_TRIANGLES_128_BYTES_NV = 3, + VK_DISPLACEMENT_MICROMAP_FORMAT_MAX_ENUM_NV = 0x7FFFFFFF +} VkDisplacementMicromapFormatNV; +typedef struct VkPhysicalDeviceDisplacementMicromapFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 displacementMicromap; +} VkPhysicalDeviceDisplacementMicromapFeaturesNV; + +typedef struct VkPhysicalDeviceDisplacementMicromapPropertiesNV { + VkStructureType sType; + void* pNext; + uint32_t maxDisplacementMicromapSubdivisionLevel; +} VkPhysicalDeviceDisplacementMicromapPropertiesNV; + +typedef struct VkAccelerationStructureTrianglesDisplacementMicromapNV { + VkStructureType sType; + void* pNext; + VkFormat displacementBiasAndScaleFormat; + VkFormat displacementVectorFormat; + VkDeviceOrHostAddressConstKHR displacementBiasAndScaleBuffer; + VkDeviceSize displacementBiasAndScaleStride; + VkDeviceOrHostAddressConstKHR displacementVectorBuffer; + VkDeviceSize displacementVectorStride; + VkDeviceOrHostAddressConstKHR displacedMicromapPrimitiveFlags; + VkDeviceSize displacedMicromapPrimitiveFlagsStride; + VkIndexType indexType; + VkDeviceOrHostAddressConstKHR indexBuffer; + VkDeviceSize indexStride; + uint32_t baseTriangle; + uint32_t usageCountsCount; + const VkMicromapUsageEXT* pUsageCounts; + const VkMicromapUsageEXT* const* ppUsageCounts; + VkMicromapEXT micromap; +} VkAccelerationStructureTrianglesDisplacementMicromapNV; + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/SDL2-2.30.5/src/video/khronos/vulkan/vulkan_core.h b/SDL2-2.30.5/src/video/khronos/vulkan/vulkan_core.h new file mode 100644 index 0000000..5354f61 --- /dev/null +++ b/SDL2-2.30.5/src/video/khronos/vulkan/vulkan_core.h @@ -0,0 +1,19371 @@ +#ifndef VULKAN_CORE_H_ +#define VULKAN_CORE_H_ 1 + +/* +** Copyright 2015-2024 The Khronos Group Inc. +** +** SPDX-License-Identifier: Apache-2.0 +*/ + +/* +** This header is generated from the Khronos Vulkan XML API Registry. +** +*/ + + +#ifdef __cplusplus +extern "C" { +#endif + + + +// VK_VERSION_1_0 is a preprocessor guard. Do not pass it to API calls. +#define VK_VERSION_1_0 1 +#include "vk_platform.h" + +#define VK_DEFINE_HANDLE(object) typedef struct object##_T* object; + + +#ifndef VK_USE_64_BIT_PTR_DEFINES + #if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__) || (defined(__riscv) && __riscv_xlen == 64) + #define VK_USE_64_BIT_PTR_DEFINES 1 + #else + #define VK_USE_64_BIT_PTR_DEFINES 0 + #endif +#endif + + +#ifndef VK_DEFINE_NON_DISPATCHABLE_HANDLE + #if (VK_USE_64_BIT_PTR_DEFINES==1) + #if (defined(__cplusplus) && (__cplusplus >= 201103L)) || (defined(_MSVC_LANG) && (_MSVC_LANG >= 201103L)) + #define VK_NULL_HANDLE nullptr + #else + #define VK_NULL_HANDLE ((void*)0) + #endif + #else + #define VK_NULL_HANDLE 0ULL + #endif +#endif +#ifndef VK_NULL_HANDLE + #define VK_NULL_HANDLE 0 +#endif + + +#ifndef VK_DEFINE_NON_DISPATCHABLE_HANDLE + #if (VK_USE_64_BIT_PTR_DEFINES==1) + #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T *object; + #else + #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object; + #endif +#endif + +#define VK_MAKE_API_VERSION(variant, major, minor, patch) \ + ((((uint32_t)(variant)) << 29U) | (((uint32_t)(major)) << 22U) | (((uint32_t)(minor)) << 12U) | ((uint32_t)(patch))) + +// DEPRECATED: This define has been removed. Specific version defines (e.g. VK_API_VERSION_1_0), or the VK_MAKE_VERSION macro, should be used instead. +//#define VK_API_VERSION VK_MAKE_API_VERSION(0, 1, 0, 0) // Patch version should always be set to 0 + +// Vulkan 1.0 version number +#define VK_API_VERSION_1_0 VK_MAKE_API_VERSION(0, 1, 0, 0)// Patch version should always be set to 0 + +// Version of this file +#define VK_HEADER_VERSION 275 + +// Complete version of this file +#define VK_HEADER_VERSION_COMPLETE VK_MAKE_API_VERSION(0, 1, 3, VK_HEADER_VERSION) + +// DEPRECATED: This define is deprecated. VK_MAKE_API_VERSION should be used instead. +#define VK_MAKE_VERSION(major, minor, patch) \ + ((((uint32_t)(major)) << 22U) | (((uint32_t)(minor)) << 12U) | ((uint32_t)(patch))) + +// DEPRECATED: This define is deprecated. VK_API_VERSION_MAJOR should be used instead. +#define VK_VERSION_MAJOR(version) ((uint32_t)(version) >> 22U) + +// DEPRECATED: This define is deprecated. VK_API_VERSION_MINOR should be used instead. +#define VK_VERSION_MINOR(version) (((uint32_t)(version) >> 12U) & 0x3FFU) + +// DEPRECATED: This define is deprecated. VK_API_VERSION_PATCH should be used instead. +#define VK_VERSION_PATCH(version) ((uint32_t)(version) & 0xFFFU) + +#define VK_API_VERSION_VARIANT(version) ((uint32_t)(version) >> 29U) +#define VK_API_VERSION_MAJOR(version) (((uint32_t)(version) >> 22U) & 0x7FU) +#define VK_API_VERSION_MINOR(version) (((uint32_t)(version) >> 12U) & 0x3FFU) +#define VK_API_VERSION_PATCH(version) ((uint32_t)(version) & 0xFFFU) +typedef uint32_t VkBool32; +typedef uint64_t VkDeviceAddress; +typedef uint64_t VkDeviceSize; +typedef uint32_t VkFlags; +typedef uint32_t VkSampleMask; +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBuffer) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkImage) +VK_DEFINE_HANDLE(VkInstance) +VK_DEFINE_HANDLE(VkPhysicalDevice) +VK_DEFINE_HANDLE(VkDevice) +VK_DEFINE_HANDLE(VkQueue) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSemaphore) +VK_DEFINE_HANDLE(VkCommandBuffer) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkFence) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDeviceMemory) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkEvent) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkQueryPool) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBufferView) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkImageView) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkShaderModule) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipelineCache) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipelineLayout) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPipeline) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkRenderPass) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorSetLayout) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSampler) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorSet) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorPool) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkFramebuffer) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCommandPool) +#define VK_ATTACHMENT_UNUSED (~0U) +#define VK_FALSE 0U +#define VK_LOD_CLAMP_NONE 1000.0F +#define VK_QUEUE_FAMILY_IGNORED (~0U) +#define VK_REMAINING_ARRAY_LAYERS (~0U) +#define VK_REMAINING_MIP_LEVELS (~0U) +#define VK_SUBPASS_EXTERNAL (~0U) +#define VK_TRUE 1U +#define VK_WHOLE_SIZE (~0ULL) +#define VK_MAX_MEMORY_TYPES 32U +#define VK_MAX_PHYSICAL_DEVICE_NAME_SIZE 256U +#define VK_UUID_SIZE 16U +#define VK_MAX_EXTENSION_NAME_SIZE 256U +#define VK_MAX_DESCRIPTION_SIZE 256U +#define VK_MAX_MEMORY_HEAPS 16U + +typedef enum VkResult { + VK_SUCCESS = 0, + VK_NOT_READY = 1, + VK_TIMEOUT = 2, + VK_EVENT_SET = 3, + VK_EVENT_RESET = 4, + VK_INCOMPLETE = 5, + VK_ERROR_OUT_OF_HOST_MEMORY = -1, + VK_ERROR_OUT_OF_DEVICE_MEMORY = -2, + VK_ERROR_INITIALIZATION_FAILED = -3, + VK_ERROR_DEVICE_LOST = -4, + VK_ERROR_MEMORY_MAP_FAILED = -5, + VK_ERROR_LAYER_NOT_PRESENT = -6, + VK_ERROR_EXTENSION_NOT_PRESENT = -7, + VK_ERROR_FEATURE_NOT_PRESENT = -8, + VK_ERROR_INCOMPATIBLE_DRIVER = -9, + VK_ERROR_TOO_MANY_OBJECTS = -10, + VK_ERROR_FORMAT_NOT_SUPPORTED = -11, + VK_ERROR_FRAGMENTED_POOL = -12, + VK_ERROR_UNKNOWN = -13, + VK_ERROR_OUT_OF_POOL_MEMORY = -1000069000, + VK_ERROR_INVALID_EXTERNAL_HANDLE = -1000072003, + VK_ERROR_FRAGMENTATION = -1000161000, + VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS = -1000257000, + VK_PIPELINE_COMPILE_REQUIRED = 1000297000, + VK_ERROR_SURFACE_LOST_KHR = -1000000000, + VK_ERROR_NATIVE_WINDOW_IN_USE_KHR = -1000000001, + VK_SUBOPTIMAL_KHR = 1000001003, + VK_ERROR_OUT_OF_DATE_KHR = -1000001004, + VK_ERROR_INCOMPATIBLE_DISPLAY_KHR = -1000003001, + VK_ERROR_VALIDATION_FAILED_EXT = -1000011001, + VK_ERROR_INVALID_SHADER_NV = -1000012000, + VK_ERROR_IMAGE_USAGE_NOT_SUPPORTED_KHR = -1000023000, + VK_ERROR_VIDEO_PICTURE_LAYOUT_NOT_SUPPORTED_KHR = -1000023001, + VK_ERROR_VIDEO_PROFILE_OPERATION_NOT_SUPPORTED_KHR = -1000023002, + VK_ERROR_VIDEO_PROFILE_FORMAT_NOT_SUPPORTED_KHR = -1000023003, + VK_ERROR_VIDEO_PROFILE_CODEC_NOT_SUPPORTED_KHR = -1000023004, + VK_ERROR_VIDEO_STD_VERSION_NOT_SUPPORTED_KHR = -1000023005, + VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT = -1000158000, + VK_ERROR_NOT_PERMITTED_KHR = -1000174001, + VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT = -1000255000, + VK_THREAD_IDLE_KHR = 1000268000, + VK_THREAD_DONE_KHR = 1000268001, + VK_OPERATION_DEFERRED_KHR = 1000268002, + VK_OPERATION_NOT_DEFERRED_KHR = 1000268003, + VK_ERROR_INVALID_VIDEO_STD_PARAMETERS_KHR = -1000299000, + VK_ERROR_COMPRESSION_EXHAUSTED_EXT = -1000338000, + VK_ERROR_INCOMPATIBLE_SHADER_BINARY_EXT = 1000482000, + VK_ERROR_OUT_OF_POOL_MEMORY_KHR = VK_ERROR_OUT_OF_POOL_MEMORY, + VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR = VK_ERROR_INVALID_EXTERNAL_HANDLE, + VK_ERROR_FRAGMENTATION_EXT = VK_ERROR_FRAGMENTATION, + VK_ERROR_NOT_PERMITTED_EXT = VK_ERROR_NOT_PERMITTED_KHR, + VK_ERROR_INVALID_DEVICE_ADDRESS_EXT = VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS, + VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS_KHR = VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS, + VK_PIPELINE_COMPILE_REQUIRED_EXT = VK_PIPELINE_COMPILE_REQUIRED, + VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT = VK_PIPELINE_COMPILE_REQUIRED, + VK_RESULT_MAX_ENUM = 0x7FFFFFFF +} VkResult; + +typedef enum VkStructureType { + VK_STRUCTURE_TYPE_APPLICATION_INFO = 0, + VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO = 1, + VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO = 2, + VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO = 3, + VK_STRUCTURE_TYPE_SUBMIT_INFO = 4, + VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO = 5, + VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE = 6, + VK_STRUCTURE_TYPE_BIND_SPARSE_INFO = 7, + VK_STRUCTURE_TYPE_FENCE_CREATE_INFO = 8, + VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO = 9, + VK_STRUCTURE_TYPE_EVENT_CREATE_INFO = 10, + VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO = 11, + VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO = 12, + VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO = 13, + VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO = 14, + VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO = 15, + VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO = 16, + VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO = 17, + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO = 18, + VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO = 19, + VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO = 20, + VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO = 21, + VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO = 22, + VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO = 23, + VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO = 24, + VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO = 25, + VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO = 26, + VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO = 27, + VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO = 28, + VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO = 29, + VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO = 30, + VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO = 31, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO = 32, + VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO = 33, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO = 34, + VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET = 35, + VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET = 36, + VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO = 37, + VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO = 38, + VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO = 39, + VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO = 40, + VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO = 41, + VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO = 42, + VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO = 43, + VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER = 44, + VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER = 45, + VK_STRUCTURE_TYPE_MEMORY_BARRIER = 46, + VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO = 47, + VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO = 48, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES = 1000094000, + VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO = 1000157000, + VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO = 1000157001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES = 1000083000, + VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS = 1000127000, + VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO = 1000127001, + VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO = 1000060000, + VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO = 1000060003, + VK_STRUCTURE_TYPE_DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO = 1000060004, + VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO = 1000060005, + VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO = 1000060006, + VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO = 1000060013, + VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO = 1000060014, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES = 1000070000, + VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO = 1000070001, + VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2 = 1000146000, + VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2 = 1000146001, + VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2 = 1000146002, + VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2 = 1000146003, + VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2 = 1000146004, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2 = 1000059000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2 = 1000059001, + VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2 = 1000059002, + VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2 = 1000059003, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2 = 1000059004, + VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2 = 1000059005, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2 = 1000059006, + VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2 = 1000059007, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2 = 1000059008, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES = 1000117000, + VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO = 1000117001, + VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO = 1000117002, + VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO = 1000117003, + VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO = 1000053000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES = 1000053001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES = 1000053002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES = 1000120000, + VK_STRUCTURE_TYPE_PROTECTED_SUBMIT_INFO = 1000145000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES = 1000145001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES = 1000145002, + VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2 = 1000145003, + VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO = 1000156000, + VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO = 1000156001, + VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO = 1000156002, + VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO = 1000156003, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES = 1000156004, + VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES = 1000156005, + VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO = 1000085000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO = 1000071000, + VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES = 1000071001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO = 1000071002, + VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES = 1000071003, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES = 1000071004, + VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO = 1000072000, + VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO = 1000072001, + VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO = 1000072002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO = 1000112000, + VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES = 1000112001, + VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO = 1000113000, + VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO = 1000077000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO = 1000076000, + VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES = 1000076001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES = 1000168000, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT = 1000168001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES = 1000063000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES = 49, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES = 50, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES = 51, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES = 52, + VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO = 1000147000, + VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2 = 1000109000, + VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2 = 1000109001, + VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2 = 1000109002, + VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2 = 1000109003, + VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2 = 1000109004, + VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO = 1000109005, + VK_STRUCTURE_TYPE_SUBPASS_END_INFO = 1000109006, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES = 1000177000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES = 1000196000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES = 1000180000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES = 1000082000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES = 1000197000, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO = 1000161000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES = 1000161001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES = 1000161002, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO = 1000161003, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT = 1000161004, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES = 1000199000, + VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE = 1000199001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES = 1000221000, + VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO = 1000246000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES = 1000130000, + VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO = 1000130001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES = 1000211000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES = 1000108000, + VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO = 1000108001, + VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO = 1000108002, + VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO = 1000108003, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES = 1000253000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES = 1000175000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES = 1000241000, + VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT = 1000241001, + VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT = 1000241002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES = 1000261000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES = 1000207000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES = 1000207001, + VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO = 1000207002, + VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO = 1000207003, + VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO = 1000207004, + VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO = 1000207005, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES = 1000257000, + VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO = 1000244001, + VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO = 1000257002, + VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO = 1000257003, + VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO = 1000257004, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES = 53, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_PROPERTIES = 54, + VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO = 1000192000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES = 1000215000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES = 1000245000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES = 1000276000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES = 1000295000, + VK_STRUCTURE_TYPE_DEVICE_PRIVATE_DATA_CREATE_INFO = 1000295001, + VK_STRUCTURE_TYPE_PRIVATE_DATA_SLOT_CREATE_INFO = 1000295002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES = 1000297000, + VK_STRUCTURE_TYPE_MEMORY_BARRIER_2 = 1000314000, + VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2 = 1000314001, + VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2 = 1000314002, + VK_STRUCTURE_TYPE_DEPENDENCY_INFO = 1000314003, + VK_STRUCTURE_TYPE_SUBMIT_INFO_2 = 1000314004, + VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO = 1000314005, + VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO = 1000314006, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES = 1000314007, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES = 1000325000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES = 1000335000, + VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2 = 1000337000, + VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2 = 1000337001, + VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2 = 1000337002, + VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2 = 1000337003, + VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2 = 1000337004, + VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2 = 1000337005, + VK_STRUCTURE_TYPE_BUFFER_COPY_2 = 1000337006, + VK_STRUCTURE_TYPE_IMAGE_COPY_2 = 1000337007, + VK_STRUCTURE_TYPE_IMAGE_BLIT_2 = 1000337008, + VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2 = 1000337009, + VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2 = 1000337010, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES = 1000225000, + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO = 1000225001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES = 1000225002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES = 1000138000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES = 1000138001, + VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK = 1000138002, + VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO = 1000138003, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES = 1000066000, + VK_STRUCTURE_TYPE_RENDERING_INFO = 1000044000, + VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO = 1000044001, + VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO = 1000044002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES = 1000044003, + VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO = 1000044004, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES = 1000280000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES = 1000280001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES = 1000281001, + VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3 = 1000360000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES = 1000413000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES = 1000413001, + VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS = 1000413002, + VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS = 1000413003, + VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR = 1000001000, + VK_STRUCTURE_TYPE_PRESENT_INFO_KHR = 1000001001, + VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHR = 1000060007, + VK_STRUCTURE_TYPE_IMAGE_SWAPCHAIN_CREATE_INFO_KHR = 1000060008, + VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR = 1000060009, + VK_STRUCTURE_TYPE_ACQUIRE_NEXT_IMAGE_INFO_KHR = 1000060010, + VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_INFO_KHR = 1000060011, + VK_STRUCTURE_TYPE_DEVICE_GROUP_SWAPCHAIN_CREATE_INFO_KHR = 1000060012, + VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR = 1000002000, + VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR = 1000002001, + VK_STRUCTURE_TYPE_DISPLAY_PRESENT_INFO_KHR = 1000003000, + VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR = 1000004000, + VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR = 1000005000, + VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR = 1000006000, + VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR = 1000008000, + VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000, + VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT = 1000011000, + VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_RASTERIZATION_ORDER_AMD = 1000018000, + VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_NAME_INFO_EXT = 1000022000, + VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_TAG_INFO_EXT = 1000022001, + VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT = 1000022002, + VK_STRUCTURE_TYPE_VIDEO_PROFILE_INFO_KHR = 1000023000, + VK_STRUCTURE_TYPE_VIDEO_CAPABILITIES_KHR = 1000023001, + VK_STRUCTURE_TYPE_VIDEO_PICTURE_RESOURCE_INFO_KHR = 1000023002, + VK_STRUCTURE_TYPE_VIDEO_SESSION_MEMORY_REQUIREMENTS_KHR = 1000023003, + VK_STRUCTURE_TYPE_BIND_VIDEO_SESSION_MEMORY_INFO_KHR = 1000023004, + VK_STRUCTURE_TYPE_VIDEO_SESSION_CREATE_INFO_KHR = 1000023005, + VK_STRUCTURE_TYPE_VIDEO_SESSION_PARAMETERS_CREATE_INFO_KHR = 1000023006, + VK_STRUCTURE_TYPE_VIDEO_SESSION_PARAMETERS_UPDATE_INFO_KHR = 1000023007, + VK_STRUCTURE_TYPE_VIDEO_BEGIN_CODING_INFO_KHR = 1000023008, + VK_STRUCTURE_TYPE_VIDEO_END_CODING_INFO_KHR = 1000023009, + VK_STRUCTURE_TYPE_VIDEO_CODING_CONTROL_INFO_KHR = 1000023010, + VK_STRUCTURE_TYPE_VIDEO_REFERENCE_SLOT_INFO_KHR = 1000023011, + VK_STRUCTURE_TYPE_QUEUE_FAMILY_VIDEO_PROPERTIES_KHR = 1000023012, + VK_STRUCTURE_TYPE_VIDEO_PROFILE_LIST_INFO_KHR = 1000023013, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_FORMAT_INFO_KHR = 1000023014, + VK_STRUCTURE_TYPE_VIDEO_FORMAT_PROPERTIES_KHR = 1000023015, + VK_STRUCTURE_TYPE_QUEUE_FAMILY_QUERY_RESULT_STATUS_PROPERTIES_KHR = 1000023016, + VK_STRUCTURE_TYPE_VIDEO_DECODE_INFO_KHR = 1000024000, + VK_STRUCTURE_TYPE_VIDEO_DECODE_CAPABILITIES_KHR = 1000024001, + VK_STRUCTURE_TYPE_VIDEO_DECODE_USAGE_INFO_KHR = 1000024002, + VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV = 1000026000, + VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV = 1000026001, + VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV = 1000026002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT = 1000028000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT = 1000028001, + VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_STREAM_CREATE_INFO_EXT = 1000028002, + VK_STRUCTURE_TYPE_CU_MODULE_CREATE_INFO_NVX = 1000029000, + VK_STRUCTURE_TYPE_CU_FUNCTION_CREATE_INFO_NVX = 1000029001, + VK_STRUCTURE_TYPE_CU_LAUNCH_INFO_NVX = 1000029002, + VK_STRUCTURE_TYPE_IMAGE_VIEW_HANDLE_INFO_NVX = 1000030000, + VK_STRUCTURE_TYPE_IMAGE_VIEW_ADDRESS_PROPERTIES_NVX = 1000030001, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_CAPABILITIES_KHR = 1000038000, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_SESSION_PARAMETERS_CREATE_INFO_KHR = 1000038001, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_SESSION_PARAMETERS_ADD_INFO_KHR = 1000038002, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_PICTURE_INFO_KHR = 1000038003, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_DPB_SLOT_INFO_KHR = 1000038004, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_NALU_SLICE_INFO_KHR = 1000038005, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_GOP_REMAINING_FRAME_INFO_KHR = 1000038006, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_PROFILE_INFO_KHR = 1000038007, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_RATE_CONTROL_INFO_KHR = 1000038008, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_RATE_CONTROL_LAYER_INFO_KHR = 1000038009, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_SESSION_CREATE_INFO_KHR = 1000038010, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_QUALITY_LEVEL_PROPERTIES_KHR = 1000038011, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_SESSION_PARAMETERS_GET_INFO_KHR = 1000038012, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H264_SESSION_PARAMETERS_FEEDBACK_INFO_KHR = 1000038013, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_CAPABILITIES_KHR = 1000039000, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_SESSION_PARAMETERS_CREATE_INFO_KHR = 1000039001, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_SESSION_PARAMETERS_ADD_INFO_KHR = 1000039002, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_PICTURE_INFO_KHR = 1000039003, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_DPB_SLOT_INFO_KHR = 1000039004, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_NALU_SLICE_SEGMENT_INFO_KHR = 1000039005, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_GOP_REMAINING_FRAME_INFO_KHR = 1000039006, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_PROFILE_INFO_KHR = 1000039007, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_RATE_CONTROL_INFO_KHR = 1000039009, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_RATE_CONTROL_LAYER_INFO_KHR = 1000039010, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_SESSION_CREATE_INFO_KHR = 1000039011, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_QUALITY_LEVEL_PROPERTIES_KHR = 1000039012, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_SESSION_PARAMETERS_GET_INFO_KHR = 1000039013, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_H265_SESSION_PARAMETERS_FEEDBACK_INFO_KHR = 1000039014, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_CAPABILITIES_KHR = 1000040000, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PICTURE_INFO_KHR = 1000040001, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PROFILE_INFO_KHR = 1000040003, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_SESSION_PARAMETERS_CREATE_INFO_KHR = 1000040004, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_SESSION_PARAMETERS_ADD_INFO_KHR = 1000040005, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_DPB_SLOT_INFO_KHR = 1000040006, + VK_STRUCTURE_TYPE_TEXTURE_LOD_GATHER_FORMAT_PROPERTIES_AMD = 1000041000, + VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR = 1000044006, + VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_INFO_EXT = 1000044007, + VK_STRUCTURE_TYPE_ATTACHMENT_SAMPLE_COUNT_INFO_AMD = 1000044008, + VK_STRUCTURE_TYPE_MULTIVIEW_PER_VIEW_ATTRIBUTES_INFO_NVX = 1000044009, + VK_STRUCTURE_TYPE_STREAM_DESCRIPTOR_SURFACE_CREATE_INFO_GGP = 1000049000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CORNER_SAMPLED_IMAGE_FEATURES_NV = 1000050000, + VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_NV = 1000056000, + VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_NV = 1000056001, + VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_NV = 1000057000, + VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_NV = 1000057001, + VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV = 1000058000, + VK_STRUCTURE_TYPE_VALIDATION_FLAGS_EXT = 1000061000, + VK_STRUCTURE_TYPE_VI_SURFACE_CREATE_INFO_NN = 1000062000, + VK_STRUCTURE_TYPE_IMAGE_VIEW_ASTC_DECODE_MODE_EXT = 1000067000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ASTC_DECODE_FEATURES_EXT = 1000067001, + VK_STRUCTURE_TYPE_PIPELINE_ROBUSTNESS_CREATE_INFO_EXT = 1000068000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_ROBUSTNESS_FEATURES_EXT = 1000068001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_ROBUSTNESS_PROPERTIES_EXT = 1000068002, + VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR = 1000073000, + VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_KHR = 1000073001, + VK_STRUCTURE_TYPE_MEMORY_WIN32_HANDLE_PROPERTIES_KHR = 1000073002, + VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR = 1000073003, + VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR = 1000074000, + VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR = 1000074001, + VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR = 1000074002, + VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_KHR = 1000075000, + VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR = 1000078000, + VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR = 1000078001, + VK_STRUCTURE_TYPE_D3D12_FENCE_SUBMIT_INFO_KHR = 1000078002, + VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR = 1000078003, + VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR = 1000079000, + VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR = 1000079001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR = 1000080000, + VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_CONDITIONAL_RENDERING_INFO_EXT = 1000081000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT = 1000081001, + VK_STRUCTURE_TYPE_CONDITIONAL_RENDERING_BEGIN_INFO_EXT = 1000081002, + VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR = 1000084000, + VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_W_SCALING_STATE_CREATE_INFO_NV = 1000087000, + VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT = 1000090000, + VK_STRUCTURE_TYPE_DISPLAY_POWER_INFO_EXT = 1000091000, + VK_STRUCTURE_TYPE_DEVICE_EVENT_INFO_EXT = 1000091001, + VK_STRUCTURE_TYPE_DISPLAY_EVENT_INFO_EXT = 1000091002, + VK_STRUCTURE_TYPE_SWAPCHAIN_COUNTER_CREATE_INFO_EXT = 1000091003, + VK_STRUCTURE_TYPE_PRESENT_TIMES_INFO_GOOGLE = 1000092000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_ATTRIBUTES_PROPERTIES_NVX = 1000097000, + VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SWIZZLE_STATE_CREATE_INFO_NV = 1000098000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT = 1000099000, + VK_STRUCTURE_TYPE_PIPELINE_DISCARD_RECTANGLE_STATE_CREATE_INFO_EXT = 1000099001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONSERVATIVE_RASTERIZATION_PROPERTIES_EXT = 1000101000, + VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT = 1000101001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT = 1000102000, + VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT = 1000102001, + VK_STRUCTURE_TYPE_HDR_METADATA_EXT = 1000105000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RELAXED_LINE_RASTERIZATION_FEATURES_IMG = 1000110000, + VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR = 1000111000, + VK_STRUCTURE_TYPE_IMPORT_FENCE_WIN32_HANDLE_INFO_KHR = 1000114000, + VK_STRUCTURE_TYPE_EXPORT_FENCE_WIN32_HANDLE_INFO_KHR = 1000114001, + VK_STRUCTURE_TYPE_FENCE_GET_WIN32_HANDLE_INFO_KHR = 1000114002, + VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR = 1000115000, + VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR = 1000115001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_FEATURES_KHR = 1000116000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_PROPERTIES_KHR = 1000116001, + VK_STRUCTURE_TYPE_QUERY_POOL_PERFORMANCE_CREATE_INFO_KHR = 1000116002, + VK_STRUCTURE_TYPE_PERFORMANCE_QUERY_SUBMIT_INFO_KHR = 1000116003, + VK_STRUCTURE_TYPE_ACQUIRE_PROFILING_LOCK_INFO_KHR = 1000116004, + VK_STRUCTURE_TYPE_PERFORMANCE_COUNTER_KHR = 1000116005, + VK_STRUCTURE_TYPE_PERFORMANCE_COUNTER_DESCRIPTION_KHR = 1000116006, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR = 1000119000, + VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR = 1000119001, + VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR = 1000119002, + VK_STRUCTURE_TYPE_DISPLAY_PROPERTIES_2_KHR = 1000121000, + VK_STRUCTURE_TYPE_DISPLAY_PLANE_PROPERTIES_2_KHR = 1000121001, + VK_STRUCTURE_TYPE_DISPLAY_MODE_PROPERTIES_2_KHR = 1000121002, + VK_STRUCTURE_TYPE_DISPLAY_PLANE_INFO_2_KHR = 1000121003, + VK_STRUCTURE_TYPE_DISPLAY_PLANE_CAPABILITIES_2_KHR = 1000121004, + VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK = 1000122000, + VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK = 1000123000, + VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT = 1000128000, + VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_TAG_INFO_EXT = 1000128001, + VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT = 1000128002, + VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT = 1000128003, + VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT = 1000128004, + VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID = 1000129000, + VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID = 1000129001, + VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID = 1000129002, + VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID = 1000129003, + VK_STRUCTURE_TYPE_MEMORY_GET_ANDROID_HARDWARE_BUFFER_INFO_ANDROID = 1000129004, + VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID = 1000129005, + VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_2_ANDROID = 1000129006, +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ENQUEUE_FEATURES_AMDX = 1000134000, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ENQUEUE_PROPERTIES_AMDX = 1000134001, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_EXECUTION_GRAPH_PIPELINE_SCRATCH_SIZE_AMDX = 1000134002, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_EXECUTION_GRAPH_PIPELINE_CREATE_INFO_AMDX = 1000134003, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_NODE_CREATE_INFO_AMDX = 1000134004, +#endif + VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT = 1000143000, + VK_STRUCTURE_TYPE_RENDER_PASS_SAMPLE_LOCATIONS_BEGIN_INFO_EXT = 1000143001, + VK_STRUCTURE_TYPE_PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT = 1000143002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLE_LOCATIONS_PROPERTIES_EXT = 1000143003, + VK_STRUCTURE_TYPE_MULTISAMPLE_PROPERTIES_EXT = 1000143004, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT = 1000148000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_PROPERTIES_EXT = 1000148001, + VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_ADVANCED_STATE_CREATE_INFO_EXT = 1000148002, + VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_TO_COLOR_STATE_CREATE_INFO_NV = 1000149000, + VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR = 1000150007, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR = 1000150000, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR = 1000150002, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_AABBS_DATA_KHR = 1000150003, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_INSTANCES_DATA_KHR = 1000150004, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR = 1000150005, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR = 1000150006, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_VERSION_INFO_KHR = 1000150009, + VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_INFO_KHR = 1000150010, + VK_STRUCTURE_TYPE_COPY_ACCELERATION_STRUCTURE_TO_MEMORY_INFO_KHR = 1000150011, + VK_STRUCTURE_TYPE_COPY_MEMORY_TO_ACCELERATION_STRUCTURE_INFO_KHR = 1000150012, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR = 1000150013, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_PROPERTIES_KHR = 1000150014, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR = 1000150017, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR = 1000150020, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR = 1000347000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_PROPERTIES_KHR = 1000347001, + VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_KHR = 1000150015, + VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_KHR = 1000150016, + VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_INTERFACE_CREATE_INFO_KHR = 1000150018, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_QUERY_FEATURES_KHR = 1000348013, + VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_MODULATION_STATE_CREATE_INFO_NV = 1000152000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SM_BUILTINS_FEATURES_NV = 1000154000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SM_BUILTINS_PROPERTIES_NV = 1000154001, + VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT = 1000158000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT = 1000158002, + VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT = 1000158003, + VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT = 1000158004, + VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT = 1000158005, + VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_2_EXT = 1000158006, + VK_STRUCTURE_TYPE_VALIDATION_CACHE_CREATE_INFO_EXT = 1000160000, + VK_STRUCTURE_TYPE_SHADER_MODULE_VALIDATION_CACHE_CREATE_INFO_EXT = 1000160001, +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_KHR = 1000163000, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_PROPERTIES_KHR = 1000163001, +#endif + VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SHADING_RATE_IMAGE_STATE_CREATE_INFO_NV = 1000164000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_FEATURES_NV = 1000164001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_PROPERTIES_NV = 1000164002, + VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_COARSE_SAMPLE_ORDER_STATE_CREATE_INFO_NV = 1000164005, + VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_NV = 1000165000, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NV = 1000165001, + VK_STRUCTURE_TYPE_GEOMETRY_NV = 1000165003, + VK_STRUCTURE_TYPE_GEOMETRY_TRIANGLES_NV = 1000165004, + VK_STRUCTURE_TYPE_GEOMETRY_AABB_NV = 1000165005, + VK_STRUCTURE_TYPE_BIND_ACCELERATION_STRUCTURE_MEMORY_INFO_NV = 1000165006, + VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_NV = 1000165007, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV = 1000165008, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PROPERTIES_NV = 1000165009, + VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_NV = 1000165011, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV = 1000165012, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_REPRESENTATIVE_FRAGMENT_TEST_FEATURES_NV = 1000166000, + VK_STRUCTURE_TYPE_PIPELINE_REPRESENTATIVE_FRAGMENT_TEST_STATE_CREATE_INFO_NV = 1000166001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_IMAGE_FORMAT_INFO_EXT = 1000170000, + VK_STRUCTURE_TYPE_FILTER_CUBIC_IMAGE_VIEW_IMAGE_FORMAT_PROPERTIES_EXT = 1000170001, + VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT = 1000178000, + VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT = 1000178001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT = 1000178002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CLOCK_FEATURES_KHR = 1000181000, + VK_STRUCTURE_TYPE_PIPELINE_COMPILER_CONTROL_CREATE_INFO_AMD = 1000183000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_AMD = 1000185000, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_CAPABILITIES_KHR = 1000187000, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_SESSION_PARAMETERS_CREATE_INFO_KHR = 1000187001, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_SESSION_PARAMETERS_ADD_INFO_KHR = 1000187002, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PROFILE_INFO_KHR = 1000187003, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PICTURE_INFO_KHR = 1000187004, + VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_DPB_SLOT_INFO_KHR = 1000187005, + VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_KHR = 1000174000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_KHR = 1000388000, + VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_KHR = 1000388001, + VK_STRUCTURE_TYPE_DEVICE_MEMORY_OVERALLOCATION_CREATE_INFO_AMD = 1000189000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT = 1000190000, + VK_STRUCTURE_TYPE_PRESENT_FRAME_TOKEN_GGP = 1000191000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_NV = 1000201000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_NV = 1000202000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_PROPERTIES_NV = 1000202001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_FOOTPRINT_FEATURES_NV = 1000204000, + VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_EXCLUSIVE_SCISSOR_STATE_CREATE_INFO_NV = 1000205000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXCLUSIVE_SCISSOR_FEATURES_NV = 1000205002, + VK_STRUCTURE_TYPE_CHECKPOINT_DATA_NV = 1000206000, + VK_STRUCTURE_TYPE_QUEUE_FAMILY_CHECKPOINT_PROPERTIES_NV = 1000206001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_FUNCTIONS_2_FEATURES_INTEL = 1000209000, + VK_STRUCTURE_TYPE_QUERY_POOL_PERFORMANCE_QUERY_CREATE_INFO_INTEL = 1000210000, + VK_STRUCTURE_TYPE_INITIALIZE_PERFORMANCE_API_INFO_INTEL = 1000210001, + VK_STRUCTURE_TYPE_PERFORMANCE_MARKER_INFO_INTEL = 1000210002, + VK_STRUCTURE_TYPE_PERFORMANCE_STREAM_MARKER_INFO_INTEL = 1000210003, + VK_STRUCTURE_TYPE_PERFORMANCE_OVERRIDE_INFO_INTEL = 1000210004, + VK_STRUCTURE_TYPE_PERFORMANCE_CONFIGURATION_ACQUIRE_INFO_INTEL = 1000210005, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT = 1000212000, + VK_STRUCTURE_TYPE_DISPLAY_NATIVE_HDR_SURFACE_CAPABILITIES_AMD = 1000213000, + VK_STRUCTURE_TYPE_SWAPCHAIN_DISPLAY_NATIVE_HDR_CREATE_INFO_AMD = 1000213001, + VK_STRUCTURE_TYPE_IMAGEPIPE_SURFACE_CREATE_INFO_FUCHSIA = 1000214000, + VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT = 1000217000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT = 1000218000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_PROPERTIES_EXT = 1000218001, + VK_STRUCTURE_TYPE_RENDER_PASS_FRAGMENT_DENSITY_MAP_CREATE_INFO_EXT = 1000218002, + VK_STRUCTURE_TYPE_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR = 1000226000, + VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR = 1000226001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_PROPERTIES_KHR = 1000226002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR = 1000226003, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_KHR = 1000226004, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_2_AMD = 1000227000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COHERENT_MEMORY_FEATURES_AMD = 1000229000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_ATOMIC_INT64_FEATURES_EXT = 1000234000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT = 1000237000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT = 1000238000, + VK_STRUCTURE_TYPE_MEMORY_PRIORITY_ALLOCATE_INFO_EXT = 1000238001, + VK_STRUCTURE_TYPE_SURFACE_PROTECTED_CAPABILITIES_KHR = 1000239000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEDICATED_ALLOCATION_IMAGE_ALIASING_FEATURES_NV = 1000240000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT = 1000244000, + VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_CREATE_INFO_EXT = 1000244002, + VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT = 1000247000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_WAIT_FEATURES_KHR = 1000248000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_NV = 1000249000, + VK_STRUCTURE_TYPE_COOPERATIVE_MATRIX_PROPERTIES_NV = 1000249001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_PROPERTIES_NV = 1000249002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COVERAGE_REDUCTION_MODE_FEATURES_NV = 1000250000, + VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_REDUCTION_STATE_CREATE_INFO_NV = 1000250001, + VK_STRUCTURE_TYPE_FRAMEBUFFER_MIXED_SAMPLES_COMBINATION_NV = 1000250002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT = 1000251000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_IMAGE_ARRAYS_FEATURES_EXT = 1000252000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT = 1000254000, + VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT = 1000254001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_PROPERTIES_EXT = 1000254002, + VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT = 1000255000, + VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_FULL_SCREEN_EXCLUSIVE_EXT = 1000255002, + VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_WIN32_INFO_EXT = 1000255001, + VK_STRUCTURE_TYPE_HEADLESS_SURFACE_CREATE_INFO_EXT = 1000256000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT = 1000259000, + VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT = 1000259001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT = 1000259002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT = 1000260000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT = 1000265000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT = 1000267000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR = 1000269000, + VK_STRUCTURE_TYPE_PIPELINE_INFO_KHR = 1000269001, + VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_PROPERTIES_KHR = 1000269002, + VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INFO_KHR = 1000269003, + VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_STATISTIC_KHR = 1000269004, + VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INTERNAL_REPRESENTATION_KHR = 1000269005, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_IMAGE_COPY_FEATURES_EXT = 1000270000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_IMAGE_COPY_PROPERTIES_EXT = 1000270001, + VK_STRUCTURE_TYPE_MEMORY_TO_IMAGE_COPY_EXT = 1000270002, + VK_STRUCTURE_TYPE_IMAGE_TO_MEMORY_COPY_EXT = 1000270003, + VK_STRUCTURE_TYPE_COPY_IMAGE_TO_MEMORY_INFO_EXT = 1000270004, + VK_STRUCTURE_TYPE_COPY_MEMORY_TO_IMAGE_INFO_EXT = 1000270005, + VK_STRUCTURE_TYPE_HOST_IMAGE_LAYOUT_TRANSITION_INFO_EXT = 1000270006, + VK_STRUCTURE_TYPE_COPY_IMAGE_TO_IMAGE_INFO_EXT = 1000270007, + VK_STRUCTURE_TYPE_SUBRESOURCE_HOST_MEMCPY_SIZE_EXT = 1000270008, + VK_STRUCTURE_TYPE_HOST_IMAGE_COPY_DEVICE_PERFORMANCE_QUERY_EXT = 1000270009, + VK_STRUCTURE_TYPE_MEMORY_MAP_INFO_KHR = 1000271000, + VK_STRUCTURE_TYPE_MEMORY_UNMAP_INFO_KHR = 1000271001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_2_FEATURES_EXT = 1000273000, + VK_STRUCTURE_TYPE_SURFACE_PRESENT_MODE_EXT = 1000274000, + VK_STRUCTURE_TYPE_SURFACE_PRESENT_SCALING_CAPABILITIES_EXT = 1000274001, + VK_STRUCTURE_TYPE_SURFACE_PRESENT_MODE_COMPATIBILITY_EXT = 1000274002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SWAPCHAIN_MAINTENANCE_1_FEATURES_EXT = 1000275000, + VK_STRUCTURE_TYPE_SWAPCHAIN_PRESENT_FENCE_INFO_EXT = 1000275001, + VK_STRUCTURE_TYPE_SWAPCHAIN_PRESENT_MODES_CREATE_INFO_EXT = 1000275002, + VK_STRUCTURE_TYPE_SWAPCHAIN_PRESENT_MODE_INFO_EXT = 1000275003, + VK_STRUCTURE_TYPE_SWAPCHAIN_PRESENT_SCALING_CREATE_INFO_EXT = 1000275004, + VK_STRUCTURE_TYPE_RELEASE_SWAPCHAIN_IMAGES_INFO_EXT = 1000275005, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_PROPERTIES_NV = 1000277000, + VK_STRUCTURE_TYPE_GRAPHICS_SHADER_GROUP_CREATE_INFO_NV = 1000277001, + VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_SHADER_GROUPS_CREATE_INFO_NV = 1000277002, + VK_STRUCTURE_TYPE_INDIRECT_COMMANDS_LAYOUT_TOKEN_NV = 1000277003, + VK_STRUCTURE_TYPE_INDIRECT_COMMANDS_LAYOUT_CREATE_INFO_NV = 1000277004, + VK_STRUCTURE_TYPE_GENERATED_COMMANDS_INFO_NV = 1000277005, + VK_STRUCTURE_TYPE_GENERATED_COMMANDS_MEMORY_REQUIREMENTS_INFO_NV = 1000277006, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_FEATURES_NV = 1000277007, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INHERITED_VIEWPORT_SCISSOR_FEATURES_NV = 1000278000, + VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_VIEWPORT_SCISSOR_INFO_NV = 1000278001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT = 1000281000, + VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDER_PASS_TRANSFORM_INFO_QCOM = 1000282000, + VK_STRUCTURE_TYPE_RENDER_PASS_TRANSFORM_BEGIN_INFO_QCOM = 1000282001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_BIAS_CONTROL_FEATURES_EXT = 1000283000, + VK_STRUCTURE_TYPE_DEPTH_BIAS_INFO_EXT = 1000283001, + VK_STRUCTURE_TYPE_DEPTH_BIAS_REPRESENTATION_INFO_EXT = 1000283002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_MEMORY_REPORT_FEATURES_EXT = 1000284000, + VK_STRUCTURE_TYPE_DEVICE_DEVICE_MEMORY_REPORT_CREATE_INFO_EXT = 1000284001, + VK_STRUCTURE_TYPE_DEVICE_MEMORY_REPORT_CALLBACK_DATA_EXT = 1000284002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT = 1000286000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_PROPERTIES_EXT = 1000286001, + VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT = 1000287000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_PROPERTIES_EXT = 1000287001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT = 1000287002, + VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR = 1000290000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_BARRIER_FEATURES_NV = 1000292000, + VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_PRESENT_BARRIER_NV = 1000292001, + VK_STRUCTURE_TYPE_SWAPCHAIN_PRESENT_BARRIER_CREATE_INFO_NV = 1000292002, + VK_STRUCTURE_TYPE_PRESENT_ID_KHR = 1000294000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_ID_FEATURES_KHR = 1000294001, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_INFO_KHR = 1000299000, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_RATE_CONTROL_INFO_KHR = 1000299001, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_RATE_CONTROL_LAYER_INFO_KHR = 1000299002, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_CAPABILITIES_KHR = 1000299003, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_USAGE_INFO_KHR = 1000299004, + VK_STRUCTURE_TYPE_QUERY_POOL_VIDEO_ENCODE_FEEDBACK_CREATE_INFO_KHR = 1000299005, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_ENCODE_QUALITY_LEVEL_INFO_KHR = 1000299006, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_QUALITY_LEVEL_PROPERTIES_KHR = 1000299007, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_QUALITY_LEVEL_INFO_KHR = 1000299008, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_SESSION_PARAMETERS_GET_INFO_KHR = 1000299009, + VK_STRUCTURE_TYPE_VIDEO_ENCODE_SESSION_PARAMETERS_FEEDBACK_INFO_KHR = 1000299010, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DIAGNOSTICS_CONFIG_FEATURES_NV = 1000300000, + VK_STRUCTURE_TYPE_DEVICE_DIAGNOSTICS_CONFIG_CREATE_INFO_NV = 1000300001, + VK_STRUCTURE_TYPE_CUDA_MODULE_CREATE_INFO_NV = 1000307000, + VK_STRUCTURE_TYPE_CUDA_FUNCTION_CREATE_INFO_NV = 1000307001, + VK_STRUCTURE_TYPE_CUDA_LAUNCH_INFO_NV = 1000307002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUDA_KERNEL_LAUNCH_FEATURES_NV = 1000307003, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUDA_KERNEL_LAUNCH_PROPERTIES_NV = 1000307004, + VK_STRUCTURE_TYPE_QUERY_LOW_LATENCY_SUPPORT_NV = 1000310000, + VK_STRUCTURE_TYPE_EXPORT_METAL_OBJECT_CREATE_INFO_EXT = 1000311000, + VK_STRUCTURE_TYPE_EXPORT_METAL_OBJECTS_INFO_EXT = 1000311001, + VK_STRUCTURE_TYPE_EXPORT_METAL_DEVICE_INFO_EXT = 1000311002, + VK_STRUCTURE_TYPE_EXPORT_METAL_COMMAND_QUEUE_INFO_EXT = 1000311003, + VK_STRUCTURE_TYPE_EXPORT_METAL_BUFFER_INFO_EXT = 1000311004, + VK_STRUCTURE_TYPE_IMPORT_METAL_BUFFER_INFO_EXT = 1000311005, + VK_STRUCTURE_TYPE_EXPORT_METAL_TEXTURE_INFO_EXT = 1000311006, + VK_STRUCTURE_TYPE_IMPORT_METAL_TEXTURE_INFO_EXT = 1000311007, + VK_STRUCTURE_TYPE_EXPORT_METAL_IO_SURFACE_INFO_EXT = 1000311008, + VK_STRUCTURE_TYPE_IMPORT_METAL_IO_SURFACE_INFO_EXT = 1000311009, + VK_STRUCTURE_TYPE_EXPORT_METAL_SHARED_EVENT_INFO_EXT = 1000311010, + VK_STRUCTURE_TYPE_IMPORT_METAL_SHARED_EVENT_INFO_EXT = 1000311011, + VK_STRUCTURE_TYPE_QUEUE_FAMILY_CHECKPOINT_PROPERTIES_2_NV = 1000314008, + VK_STRUCTURE_TYPE_CHECKPOINT_DATA_2_NV = 1000314009, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_BUFFER_PROPERTIES_EXT = 1000316000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_BUFFER_DENSITY_MAP_PROPERTIES_EXT = 1000316001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_BUFFER_FEATURES_EXT = 1000316002, + VK_STRUCTURE_TYPE_DESCRIPTOR_ADDRESS_INFO_EXT = 1000316003, + VK_STRUCTURE_TYPE_DESCRIPTOR_GET_INFO_EXT = 1000316004, + VK_STRUCTURE_TYPE_BUFFER_CAPTURE_DESCRIPTOR_DATA_INFO_EXT = 1000316005, + VK_STRUCTURE_TYPE_IMAGE_CAPTURE_DESCRIPTOR_DATA_INFO_EXT = 1000316006, + VK_STRUCTURE_TYPE_IMAGE_VIEW_CAPTURE_DESCRIPTOR_DATA_INFO_EXT = 1000316007, + VK_STRUCTURE_TYPE_SAMPLER_CAPTURE_DESCRIPTOR_DATA_INFO_EXT = 1000316008, + VK_STRUCTURE_TYPE_OPAQUE_CAPTURE_DESCRIPTOR_DATA_CREATE_INFO_EXT = 1000316010, + VK_STRUCTURE_TYPE_DESCRIPTOR_BUFFER_BINDING_INFO_EXT = 1000316011, + VK_STRUCTURE_TYPE_DESCRIPTOR_BUFFER_BINDING_PUSH_DESCRIPTOR_BUFFER_HANDLE_EXT = 1000316012, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CAPTURE_DESCRIPTOR_DATA_INFO_EXT = 1000316009, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_FEATURES_EXT = 1000320000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_PROPERTIES_EXT = 1000320001, + VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT = 1000320002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_EARLY_AND_LATE_FRAGMENT_TESTS_FEATURES_AMD = 1000321000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_KHR = 1000203000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_PROPERTIES_KHR = 1000322000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_FEATURES_KHR = 1000323000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_ENUMS_PROPERTIES_NV = 1000326000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_ENUMS_FEATURES_NV = 1000326001, + VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_ENUM_STATE_CREATE_INFO_NV = 1000326002, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_MOTION_TRIANGLES_DATA_NV = 1000327000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_MOTION_BLUR_FEATURES_NV = 1000327001, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MOTION_INFO_NV = 1000327002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_EXT = 1000328000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_PROPERTIES_EXT = 1000328001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_2_PLANE_444_FORMATS_FEATURES_EXT = 1000330000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_2_FEATURES_EXT = 1000332000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_2_PROPERTIES_EXT = 1000332001, + VK_STRUCTURE_TYPE_COPY_COMMAND_TRANSFORM_INFO_QCOM = 1000333000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_FEATURES_KHR = 1000336000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_FEATURES_EXT = 1000338000, + VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_CONTROL_EXT = 1000338001, + VK_STRUCTURE_TYPE_IMAGE_COMPRESSION_PROPERTIES_EXT = 1000338004, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_FEATURES_EXT = 1000339000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT = 1000340000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FAULT_FEATURES_EXT = 1000341000, + VK_STRUCTURE_TYPE_DEVICE_FAULT_COUNTS_EXT = 1000341001, + VK_STRUCTURE_TYPE_DEVICE_FAULT_INFO_EXT = 1000341002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RGBA10X6_FORMATS_FEATURES_EXT = 1000344000, + VK_STRUCTURE_TYPE_DIRECTFB_SURFACE_CREATE_INFO_EXT = 1000346000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_INPUT_DYNAMIC_STATE_FEATURES_EXT = 1000352000, + VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT = 1000352001, + VK_STRUCTURE_TYPE_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT = 1000352002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRM_PROPERTIES_EXT = 1000353000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ADDRESS_BINDING_REPORT_FEATURES_EXT = 1000354000, + VK_STRUCTURE_TYPE_DEVICE_ADDRESS_BINDING_CALLBACK_DATA_EXT = 1000354001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_CONTROL_FEATURES_EXT = 1000355000, + VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_DEPTH_CLIP_CONTROL_CREATE_INFO_EXT = 1000355001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT = 1000356000, + VK_STRUCTURE_TYPE_IMPORT_MEMORY_ZIRCON_HANDLE_INFO_FUCHSIA = 1000364000, + VK_STRUCTURE_TYPE_MEMORY_ZIRCON_HANDLE_PROPERTIES_FUCHSIA = 1000364001, + VK_STRUCTURE_TYPE_MEMORY_GET_ZIRCON_HANDLE_INFO_FUCHSIA = 1000364002, + VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_ZIRCON_HANDLE_INFO_FUCHSIA = 1000365000, + VK_STRUCTURE_TYPE_SEMAPHORE_GET_ZIRCON_HANDLE_INFO_FUCHSIA = 1000365001, + VK_STRUCTURE_TYPE_BUFFER_COLLECTION_CREATE_INFO_FUCHSIA = 1000366000, + VK_STRUCTURE_TYPE_IMPORT_MEMORY_BUFFER_COLLECTION_FUCHSIA = 1000366001, + VK_STRUCTURE_TYPE_BUFFER_COLLECTION_IMAGE_CREATE_INFO_FUCHSIA = 1000366002, + VK_STRUCTURE_TYPE_BUFFER_COLLECTION_PROPERTIES_FUCHSIA = 1000366003, + VK_STRUCTURE_TYPE_BUFFER_CONSTRAINTS_INFO_FUCHSIA = 1000366004, + VK_STRUCTURE_TYPE_BUFFER_COLLECTION_BUFFER_CREATE_INFO_FUCHSIA = 1000366005, + VK_STRUCTURE_TYPE_IMAGE_CONSTRAINTS_INFO_FUCHSIA = 1000366006, + VK_STRUCTURE_TYPE_IMAGE_FORMAT_CONSTRAINTS_INFO_FUCHSIA = 1000366007, + VK_STRUCTURE_TYPE_SYSMEM_COLOR_SPACE_FUCHSIA = 1000366008, + VK_STRUCTURE_TYPE_BUFFER_COLLECTION_CONSTRAINTS_INFO_FUCHSIA = 1000366009, + VK_STRUCTURE_TYPE_SUBPASS_SHADING_PIPELINE_CREATE_INFO_HUAWEI = 1000369000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBPASS_SHADING_FEATURES_HUAWEI = 1000369001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBPASS_SHADING_PROPERTIES_HUAWEI = 1000369002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INVOCATION_MASK_FEATURES_HUAWEI = 1000370000, + VK_STRUCTURE_TYPE_MEMORY_GET_REMOTE_ADDRESS_INFO_NV = 1000371000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_RDMA_FEATURES_NV = 1000371001, + VK_STRUCTURE_TYPE_PIPELINE_PROPERTIES_IDENTIFIER_EXT = 1000372000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_PROPERTIES_FEATURES_EXT = 1000372001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAME_BOUNDARY_FEATURES_EXT = 1000375000, + VK_STRUCTURE_TYPE_FRAME_BOUNDARY_EXT = 1000375001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_FEATURES_EXT = 1000376000, + VK_STRUCTURE_TYPE_SUBPASS_RESOLVE_PERFORMANCE_QUERY_EXT = 1000376001, + VK_STRUCTURE_TYPE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_INFO_EXT = 1000376002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_2_FEATURES_EXT = 1000377000, + VK_STRUCTURE_TYPE_SCREEN_SURFACE_CREATE_INFO_QNX = 1000378000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COLOR_WRITE_ENABLE_FEATURES_EXT = 1000381000, + VK_STRUCTURE_TYPE_PIPELINE_COLOR_WRITE_CREATE_INFO_EXT = 1000381001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVES_GENERATED_QUERY_FEATURES_EXT = 1000382000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_MAINTENANCE_1_FEATURES_KHR = 1000386000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_VIEW_MIN_LOD_FEATURES_EXT = 1000391000, + VK_STRUCTURE_TYPE_IMAGE_VIEW_MIN_LOD_CREATE_INFO_EXT = 1000391001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_FEATURES_EXT = 1000392000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_PROPERTIES_EXT = 1000392001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_2D_VIEW_OF_3D_FEATURES_EXT = 1000393000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TILE_IMAGE_FEATURES_EXT = 1000395000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TILE_IMAGE_PROPERTIES_EXT = 1000395001, + VK_STRUCTURE_TYPE_MICROMAP_BUILD_INFO_EXT = 1000396000, + VK_STRUCTURE_TYPE_MICROMAP_VERSION_INFO_EXT = 1000396001, + VK_STRUCTURE_TYPE_COPY_MICROMAP_INFO_EXT = 1000396002, + VK_STRUCTURE_TYPE_COPY_MICROMAP_TO_MEMORY_INFO_EXT = 1000396003, + VK_STRUCTURE_TYPE_COPY_MEMORY_TO_MICROMAP_INFO_EXT = 1000396004, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_OPACITY_MICROMAP_FEATURES_EXT = 1000396005, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_OPACITY_MICROMAP_PROPERTIES_EXT = 1000396006, + VK_STRUCTURE_TYPE_MICROMAP_CREATE_INFO_EXT = 1000396007, + VK_STRUCTURE_TYPE_MICROMAP_BUILD_SIZES_INFO_EXT = 1000396008, + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_TRIANGLES_OPACITY_MICROMAP_EXT = 1000396009, +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISPLACEMENT_MICROMAP_FEATURES_NV = 1000397000, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISPLACEMENT_MICROMAP_PROPERTIES_NV = 1000397001, +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_TRIANGLES_DISPLACEMENT_MICROMAP_NV = 1000397002, +#endif + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CLUSTER_CULLING_SHADER_FEATURES_HUAWEI = 1000404000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CLUSTER_CULLING_SHADER_PROPERTIES_HUAWEI = 1000404001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CLUSTER_CULLING_SHADER_VRS_FEATURES_HUAWEI = 1000404002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BORDER_COLOR_SWIZZLE_FEATURES_EXT = 1000411000, + VK_STRUCTURE_TYPE_SAMPLER_BORDER_COLOR_COMPONENT_MAPPING_CREATE_INFO_EXT = 1000411001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PAGEABLE_DEVICE_LOCAL_MEMORY_FEATURES_EXT = 1000412000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_ARM = 1000415000, + VK_STRUCTURE_TYPE_DEVICE_QUEUE_SHADER_CORE_CONTROL_CREATE_INFO_ARM = 1000417000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCHEDULING_CONTROLS_FEATURES_ARM = 1000417001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCHEDULING_CONTROLS_PROPERTIES_ARM = 1000417002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_SLICED_VIEW_OF_3D_FEATURES_EXT = 1000418000, + VK_STRUCTURE_TYPE_IMAGE_VIEW_SLICED_CREATE_INFO_EXT = 1000418001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_SET_HOST_MAPPING_FEATURES_VALVE = 1000420000, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_BINDING_REFERENCE_VALVE = 1000420001, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_HOST_MAPPING_INFO_VALVE = 1000420002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLAMP_ZERO_ONE_FEATURES_EXT = 1000421000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_NON_SEAMLESS_CUBE_MAP_FEATURES_EXT = 1000422000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RENDER_PASS_STRIPED_FEATURES_ARM = 1000424000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RENDER_PASS_STRIPED_PROPERTIES_ARM = 1000424001, + VK_STRUCTURE_TYPE_RENDER_PASS_STRIPE_BEGIN_INFO_ARM = 1000424002, + VK_STRUCTURE_TYPE_RENDER_PASS_STRIPE_INFO_ARM = 1000424003, + VK_STRUCTURE_TYPE_RENDER_PASS_STRIPE_SUBMIT_INFO_ARM = 1000424004, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_FEATURES_QCOM = 1000425000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_OFFSET_PROPERTIES_QCOM = 1000425001, + VK_STRUCTURE_TYPE_SUBPASS_FRAGMENT_DENSITY_MAP_OFFSET_END_INFO_QCOM = 1000425002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COPY_MEMORY_INDIRECT_FEATURES_NV = 1000426000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COPY_MEMORY_INDIRECT_PROPERTIES_NV = 1000426001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_DECOMPRESSION_FEATURES_NV = 1000427000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_DECOMPRESSION_PROPERTIES_NV = 1000427001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_COMPUTE_FEATURES_NV = 1000428000, + VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_INDIRECT_BUFFER_INFO_NV = 1000428001, + VK_STRUCTURE_TYPE_PIPELINE_INDIRECT_DEVICE_ADDRESS_INFO_NV = 1000428002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINEAR_COLOR_ATTACHMENT_FEATURES_NV = 1000430000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_FEATURES_EXT = 1000437000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_PROCESSING_FEATURES_QCOM = 1000440000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_PROCESSING_PROPERTIES_QCOM = 1000440001, + VK_STRUCTURE_TYPE_IMAGE_VIEW_SAMPLE_WEIGHT_CREATE_INFO_QCOM = 1000440002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_NESTED_COMMAND_BUFFER_FEATURES_EXT = 1000451000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_NESTED_COMMAND_BUFFER_PROPERTIES_EXT = 1000451001, + VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_ACQUIRE_UNMODIFIED_EXT = 1000453000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_3_FEATURES_EXT = 1000455000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_3_PROPERTIES_EXT = 1000455001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBPASS_MERGE_FEEDBACK_FEATURES_EXT = 1000458000, + VK_STRUCTURE_TYPE_RENDER_PASS_CREATION_CONTROL_EXT = 1000458001, + VK_STRUCTURE_TYPE_RENDER_PASS_CREATION_FEEDBACK_CREATE_INFO_EXT = 1000458002, + VK_STRUCTURE_TYPE_RENDER_PASS_SUBPASS_FEEDBACK_CREATE_INFO_EXT = 1000458003, + VK_STRUCTURE_TYPE_DIRECT_DRIVER_LOADING_INFO_LUNARG = 1000459000, + VK_STRUCTURE_TYPE_DIRECT_DRIVER_LOADING_LIST_LUNARG = 1000459001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MODULE_IDENTIFIER_FEATURES_EXT = 1000462000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MODULE_IDENTIFIER_PROPERTIES_EXT = 1000462001, + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_MODULE_IDENTIFIER_CREATE_INFO_EXT = 1000462002, + VK_STRUCTURE_TYPE_SHADER_MODULE_IDENTIFIER_EXT = 1000462003, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_EXT = 1000342000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_OPTICAL_FLOW_FEATURES_NV = 1000464000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_OPTICAL_FLOW_PROPERTIES_NV = 1000464001, + VK_STRUCTURE_TYPE_OPTICAL_FLOW_IMAGE_FORMAT_INFO_NV = 1000464002, + VK_STRUCTURE_TYPE_OPTICAL_FLOW_IMAGE_FORMAT_PROPERTIES_NV = 1000464003, + VK_STRUCTURE_TYPE_OPTICAL_FLOW_SESSION_CREATE_INFO_NV = 1000464004, + VK_STRUCTURE_TYPE_OPTICAL_FLOW_EXECUTE_INFO_NV = 1000464005, + VK_STRUCTURE_TYPE_OPTICAL_FLOW_SESSION_CREATE_PRIVATE_DATA_INFO_NV = 1000464010, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LEGACY_DITHERING_FEATURES_EXT = 1000465000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_PROTECTED_ACCESS_FEATURES_EXT = 1000466000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FORMAT_RESOLVE_FEATURES_ANDROID = 1000468000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FORMAT_RESOLVE_PROPERTIES_ANDROID = 1000468001, + VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_RESOLVE_PROPERTIES_ANDROID = 1000468002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_5_FEATURES_KHR = 1000470000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_5_PROPERTIES_KHR = 1000470001, + VK_STRUCTURE_TYPE_RENDERING_AREA_INFO_KHR = 1000470003, + VK_STRUCTURE_TYPE_DEVICE_IMAGE_SUBRESOURCE_INFO_KHR = 1000470004, + VK_STRUCTURE_TYPE_SUBRESOURCE_LAYOUT_2_KHR = 1000338002, + VK_STRUCTURE_TYPE_IMAGE_SUBRESOURCE_2_KHR = 1000338003, + VK_STRUCTURE_TYPE_PIPELINE_CREATE_FLAGS_2_CREATE_INFO_KHR = 1000470005, + VK_STRUCTURE_TYPE_BUFFER_USAGE_FLAGS_2_CREATE_INFO_KHR = 1000470006, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_POSITION_FETCH_FEATURES_KHR = 1000481000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_OBJECT_FEATURES_EXT = 1000482000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_OBJECT_PROPERTIES_EXT = 1000482001, + VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT = 1000482002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TILE_PROPERTIES_FEATURES_QCOM = 1000484000, + VK_STRUCTURE_TYPE_TILE_PROPERTIES_QCOM = 1000484001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_AMIGO_PROFILING_FEATURES_SEC = 1000485000, + VK_STRUCTURE_TYPE_AMIGO_PROFILING_SUBMIT_INFO_SEC = 1000485001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_VIEWPORTS_FEATURES_QCOM = 1000488000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_INVOCATION_REORDER_FEATURES_NV = 1000490000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_INVOCATION_REORDER_PROPERTIES_NV = 1000490001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_SPARSE_ADDRESS_SPACE_FEATURES_NV = 1000492000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_SPARSE_ADDRESS_SPACE_PROPERTIES_NV = 1000492001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_EXT = 1000351000, + VK_STRUCTURE_TYPE_MUTABLE_DESCRIPTOR_TYPE_CREATE_INFO_EXT = 1000351002, + VK_STRUCTURE_TYPE_LAYER_SETTINGS_CREATE_INFO_EXT = 1000496000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_BUILTINS_FEATURES_ARM = 1000497000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_BUILTINS_PROPERTIES_ARM = 1000497001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_LIBRARY_GROUP_HANDLES_FEATURES_EXT = 1000498000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_UNUSED_ATTACHMENTS_FEATURES_EXT = 1000499000, + VK_STRUCTURE_TYPE_LATENCY_SLEEP_MODE_INFO_NV = 1000505000, + VK_STRUCTURE_TYPE_LATENCY_SLEEP_INFO_NV = 1000505001, + VK_STRUCTURE_TYPE_SET_LATENCY_MARKER_INFO_NV = 1000505002, + VK_STRUCTURE_TYPE_GET_LATENCY_MARKER_INFO_NV = 1000505003, + VK_STRUCTURE_TYPE_LATENCY_TIMINGS_FRAME_REPORT_NV = 1000505004, + VK_STRUCTURE_TYPE_LATENCY_SUBMISSION_PRESENT_ID_NV = 1000505005, + VK_STRUCTURE_TYPE_OUT_OF_BAND_QUEUE_TYPE_INFO_NV = 1000505006, + VK_STRUCTURE_TYPE_SWAPCHAIN_LATENCY_CREATE_INFO_NV = 1000505007, + VK_STRUCTURE_TYPE_LATENCY_SURFACE_CAPABILITIES_NV = 1000505008, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_KHR = 1000506000, + VK_STRUCTURE_TYPE_COOPERATIVE_MATRIX_PROPERTIES_KHR = 1000506001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_PROPERTIES_KHR = 1000506002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_RENDER_AREAS_FEATURES_QCOM = 1000510000, + VK_STRUCTURE_TYPE_MULTIVIEW_PER_VIEW_RENDER_AREAS_RENDER_PASS_BEGIN_INFO_QCOM = 1000510001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VIDEO_MAINTENANCE_1_FEATURES_KHR = 1000515000, + VK_STRUCTURE_TYPE_VIDEO_INLINE_QUERY_INFO_KHR = 1000515001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PER_STAGE_DESCRIPTOR_SET_FEATURES_NV = 1000516000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_PROCESSING_2_FEATURES_QCOM = 1000518000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_PROCESSING_2_PROPERTIES_QCOM = 1000518001, + VK_STRUCTURE_TYPE_SAMPLER_BLOCK_MATCH_WINDOW_CREATE_INFO_QCOM = 1000518002, + VK_STRUCTURE_TYPE_SAMPLER_CUBIC_WEIGHTS_CREATE_INFO_QCOM = 1000519000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUBIC_WEIGHTS_FEATURES_QCOM = 1000519001, + VK_STRUCTURE_TYPE_BLIT_IMAGE_CUBIC_WEIGHTS_INFO_QCOM = 1000519002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_DEGAMMA_FEATURES_QCOM = 1000520000, + VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_YCBCR_DEGAMMA_CREATE_INFO_QCOM = 1000520001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUBIC_CLAMP_FEATURES_QCOM = 1000521000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ATTACHMENT_FEEDBACK_LOOP_DYNAMIC_STATE_FEATURES_EXT = 1000524000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_KHR = 1000525000, + VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_KHR = 1000190001, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_KHR = 1000190002, + VK_STRUCTURE_TYPE_SCREEN_BUFFER_PROPERTIES_QNX = 1000529000, + VK_STRUCTURE_TYPE_SCREEN_BUFFER_FORMAT_PROPERTIES_QNX = 1000529001, + VK_STRUCTURE_TYPE_IMPORT_SCREEN_BUFFER_INFO_QNX = 1000529002, + VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_QNX = 1000529003, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_SCREEN_BUFFER_FEATURES_QNX = 1000529004, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LAYERED_DRIVER_PROPERTIES_MSFT = 1000530000, + VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_KHR = 1000184000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_6_FEATURES_KHR = 1000545000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_6_PROPERTIES_KHR = 1000545001, + VK_STRUCTURE_TYPE_BIND_MEMORY_STATUS_KHR = 1000545002, + VK_STRUCTURE_TYPE_BIND_DESCRIPTOR_SETS_INFO_KHR = 1000545003, + VK_STRUCTURE_TYPE_PUSH_CONSTANTS_INFO_KHR = 1000545004, + VK_STRUCTURE_TYPE_PUSH_DESCRIPTOR_SET_INFO_KHR = 1000545005, + VK_STRUCTURE_TYPE_PUSH_DESCRIPTOR_SET_WITH_TEMPLATE_INFO_KHR = 1000545006, + VK_STRUCTURE_TYPE_SET_DESCRIPTOR_BUFFER_OFFSETS_INFO_EXT = 1000545007, + VK_STRUCTURE_TYPE_BIND_DESCRIPTOR_BUFFER_EMBEDDED_SAMPLERS_INFO_EXT = 1000545008, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_POOL_OVERALLOCATION_FEATURES_NV = 1000546000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETER_FEATURES = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES, + VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT, + VK_STRUCTURE_TYPE_RENDERING_INFO_KHR = VK_STRUCTURE_TYPE_RENDERING_INFO, + VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, + VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES, + VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO_KHR = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO, + VK_STRUCTURE_TYPE_ATTACHMENT_SAMPLE_COUNT_INFO_NV = VK_STRUCTURE_TYPE_ATTACHMENT_SAMPLE_COUNT_INFO_AMD, + VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, + VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2, + VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2_KHR = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, + VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2_KHR = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2, + VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2_KHR = VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2, + VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO_KHR = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO, + VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO, + VK_STRUCTURE_TYPE_DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO, + VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO, + VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO, + VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO_KHR = VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO, + VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO_KHR = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXTURE_COMPRESSION_ASTC_HDR_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES, + VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO, + VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO, + VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES_KHR = VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES, + VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO, + VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO, + VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO, + VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES, + VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES, + VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO, + VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES2_EXT = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES, + VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO, + VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO_KHR = VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO, + VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO_KHR = VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO, + VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, + VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, + VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2, + VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2_KHR = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2, + VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2, + VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO_KHR = VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO, + VK_STRUCTURE_TYPE_SUBPASS_END_INFO_KHR = VK_STRUCTURE_TYPE_SUBPASS_END_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO, + VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES, + VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES, + VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO, + VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO, + VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES_KHR, + VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS, + VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES, + VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES, + VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK, + VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO, + VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2, + VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2, + VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2_KHR = VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2, + VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, + VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2_KHR = VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2, + VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO, + VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO, + VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO_KHR = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO, + VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO_KHR = VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO, + VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO_KHR = VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES, + VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES_KHR = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES, + VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO_KHR = VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO, + VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO_KHR = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT_EXT = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES, + VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT_KHR = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT, + VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_KHR, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES, + VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_EXT = VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_KHR, + VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_KHR, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_KHR, + VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_PIPELINE_CREATION_FEEDBACK_CREATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES, + VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_NV = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_KHR, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES, + VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO, + VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO, + VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO_KHR = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO, + VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO_KHR = VK_STRUCTURE_TYPE_SEMAPHORE_SIGNAL_INFO, + VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO_INTEL = VK_STRUCTURE_TYPE_QUERY_POOL_PERFORMANCE_QUERY_CREATE_INFO_INTEL, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES, + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES, + VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT, + VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT_KHR = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_ADDRESS_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT, + VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_EXT = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TOOL_PROPERTIES, + VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES, + VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO, + VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_BUFFER_OPAQUE_CAPTURE_ADDRESS_CREATE_INFO, + VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO_KHR = VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO, + VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_MEMORY_OPAQUE_CAPTURE_ADDRESS_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES, + VK_STRUCTURE_TYPE_DEVICE_PRIVATE_DATA_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DEVICE_PRIVATE_DATA_CREATE_INFO, + VK_STRUCTURE_TYPE_PRIVATE_DATA_SLOT_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_PRIVATE_DATA_SLOT_CREATE_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES, + VK_STRUCTURE_TYPE_MEMORY_BARRIER_2_KHR = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2, + VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2_KHR = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2, + VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2_KHR = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, + VK_STRUCTURE_TYPE_DEPENDENCY_INFO_KHR = VK_STRUCTURE_TYPE_DEPENDENCY_INFO, + VK_STRUCTURE_TYPE_SUBMIT_INFO_2_KHR = VK_STRUCTURE_TYPE_SUBMIT_INFO_2, + VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO_KHR = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO, + VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO_KHR = VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES, + VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2_KHR = VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2, + VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR = VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2, + VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR = VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2, + VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2_KHR = VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2, + VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR = VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2, + VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2_KHR = VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2, + VK_STRUCTURE_TYPE_BUFFER_COPY_2_KHR = VK_STRUCTURE_TYPE_BUFFER_COPY_2, + VK_STRUCTURE_TYPE_IMAGE_COPY_2_KHR = VK_STRUCTURE_TYPE_IMAGE_COPY_2, + VK_STRUCTURE_TYPE_IMAGE_BLIT_2_KHR = VK_STRUCTURE_TYPE_IMAGE_BLIT_2, + VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2_KHR = VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2, + VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR = VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2, + VK_STRUCTURE_TYPE_SUBRESOURCE_LAYOUT_2_EXT = VK_STRUCTURE_TYPE_SUBRESOURCE_LAYOUT_2_KHR, + VK_STRUCTURE_TYPE_IMAGE_SUBRESOURCE_2_EXT = VK_STRUCTURE_TYPE_IMAGE_SUBRESOURCE_2_KHR, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_ARM = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_EXT, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_VALVE = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_EXT, + VK_STRUCTURE_TYPE_MUTABLE_DESCRIPTOR_TYPE_CREATE_INFO_VALVE = VK_STRUCTURE_TYPE_MUTABLE_DESCRIPTOR_TYPE_CREATE_INFO_EXT, + VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3_KHR = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3, + VK_STRUCTURE_TYPE_PIPELINE_INFO_EXT = VK_STRUCTURE_TYPE_PIPELINE_INFO_KHR, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_EXT = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GLOBAL_PRIORITY_QUERY_FEATURES_KHR, + VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_EXT = VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_KHR, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES, + VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS_KHR = VK_STRUCTURE_TYPE_DEVICE_BUFFER_MEMORY_REQUIREMENTS, + VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS_KHR = VK_STRUCTURE_TYPE_DEVICE_IMAGE_MEMORY_REQUIREMENTS, + VK_STRUCTURE_TYPE_SHADER_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO, + VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkStructureType; + +typedef enum VkPipelineCacheHeaderVersion { + VK_PIPELINE_CACHE_HEADER_VERSION_ONE = 1, + VK_PIPELINE_CACHE_HEADER_VERSION_MAX_ENUM = 0x7FFFFFFF +} VkPipelineCacheHeaderVersion; + +typedef enum VkImageLayout { + VK_IMAGE_LAYOUT_UNDEFINED = 0, + VK_IMAGE_LAYOUT_GENERAL = 1, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL = 2, + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL = 3, + VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL = 4, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL = 5, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL = 6, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL = 7, + VK_IMAGE_LAYOUT_PREINITIALIZED = 8, + VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL = 1000117000, + VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL = 1000117001, + VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL = 1000241000, + VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL = 1000241001, + VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL = 1000241002, + VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL = 1000241003, + VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL = 1000314000, + VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL = 1000314001, + VK_IMAGE_LAYOUT_PRESENT_SRC_KHR = 1000001002, + VK_IMAGE_LAYOUT_VIDEO_DECODE_DST_KHR = 1000024000, + VK_IMAGE_LAYOUT_VIDEO_DECODE_SRC_KHR = 1000024001, + VK_IMAGE_LAYOUT_VIDEO_DECODE_DPB_KHR = 1000024002, + VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR = 1000111000, + VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT = 1000218000, + VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR = 1000164003, + VK_IMAGE_LAYOUT_VIDEO_ENCODE_DST_KHR = 1000299000, + VK_IMAGE_LAYOUT_VIDEO_ENCODE_SRC_KHR = 1000299001, + VK_IMAGE_LAYOUT_VIDEO_ENCODE_DPB_KHR = 1000299002, + VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT = 1000339000, + VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, + VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV = VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR, + VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL, + VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL, + VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR = VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL, + VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_MAX_ENUM = 0x7FFFFFFF +} VkImageLayout; + +typedef enum VkObjectType { + VK_OBJECT_TYPE_UNKNOWN = 0, + VK_OBJECT_TYPE_INSTANCE = 1, + VK_OBJECT_TYPE_PHYSICAL_DEVICE = 2, + VK_OBJECT_TYPE_DEVICE = 3, + VK_OBJECT_TYPE_QUEUE = 4, + VK_OBJECT_TYPE_SEMAPHORE = 5, + VK_OBJECT_TYPE_COMMAND_BUFFER = 6, + VK_OBJECT_TYPE_FENCE = 7, + VK_OBJECT_TYPE_DEVICE_MEMORY = 8, + VK_OBJECT_TYPE_BUFFER = 9, + VK_OBJECT_TYPE_IMAGE = 10, + VK_OBJECT_TYPE_EVENT = 11, + VK_OBJECT_TYPE_QUERY_POOL = 12, + VK_OBJECT_TYPE_BUFFER_VIEW = 13, + VK_OBJECT_TYPE_IMAGE_VIEW = 14, + VK_OBJECT_TYPE_SHADER_MODULE = 15, + VK_OBJECT_TYPE_PIPELINE_CACHE = 16, + VK_OBJECT_TYPE_PIPELINE_LAYOUT = 17, + VK_OBJECT_TYPE_RENDER_PASS = 18, + VK_OBJECT_TYPE_PIPELINE = 19, + VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT = 20, + VK_OBJECT_TYPE_SAMPLER = 21, + VK_OBJECT_TYPE_DESCRIPTOR_POOL = 22, + VK_OBJECT_TYPE_DESCRIPTOR_SET = 23, + VK_OBJECT_TYPE_FRAMEBUFFER = 24, + VK_OBJECT_TYPE_COMMAND_POOL = 25, + VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION = 1000156000, + VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE = 1000085000, + VK_OBJECT_TYPE_PRIVATE_DATA_SLOT = 1000295000, + VK_OBJECT_TYPE_SURFACE_KHR = 1000000000, + VK_OBJECT_TYPE_SWAPCHAIN_KHR = 1000001000, + VK_OBJECT_TYPE_DISPLAY_KHR = 1000002000, + VK_OBJECT_TYPE_DISPLAY_MODE_KHR = 1000002001, + VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT = 1000011000, + VK_OBJECT_TYPE_VIDEO_SESSION_KHR = 1000023000, + VK_OBJECT_TYPE_VIDEO_SESSION_PARAMETERS_KHR = 1000023001, + VK_OBJECT_TYPE_CU_MODULE_NVX = 1000029000, + VK_OBJECT_TYPE_CU_FUNCTION_NVX = 1000029001, + VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT = 1000128000, + VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR = 1000150000, + VK_OBJECT_TYPE_VALIDATION_CACHE_EXT = 1000160000, + VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV = 1000165000, + VK_OBJECT_TYPE_PERFORMANCE_CONFIGURATION_INTEL = 1000210000, + VK_OBJECT_TYPE_DEFERRED_OPERATION_KHR = 1000268000, + VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NV = 1000277000, + VK_OBJECT_TYPE_CUDA_MODULE_NV = 1000307000, + VK_OBJECT_TYPE_CUDA_FUNCTION_NV = 1000307001, + VK_OBJECT_TYPE_BUFFER_COLLECTION_FUCHSIA = 1000366000, + VK_OBJECT_TYPE_MICROMAP_EXT = 1000396000, + VK_OBJECT_TYPE_OPTICAL_FLOW_SESSION_NV = 1000464000, + VK_OBJECT_TYPE_SHADER_EXT = 1000482000, + VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR = VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE, + VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR = VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION, + VK_OBJECT_TYPE_PRIVATE_DATA_SLOT_EXT = VK_OBJECT_TYPE_PRIVATE_DATA_SLOT, + VK_OBJECT_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkObjectType; + +typedef enum VkVendorId { + VK_VENDOR_ID_VIV = 0x10001, + VK_VENDOR_ID_VSI = 0x10002, + VK_VENDOR_ID_KAZAN = 0x10003, + VK_VENDOR_ID_CODEPLAY = 0x10004, + VK_VENDOR_ID_MESA = 0x10005, + VK_VENDOR_ID_POCL = 0x10006, + VK_VENDOR_ID_MOBILEYE = 0x10007, + VK_VENDOR_ID_MAX_ENUM = 0x7FFFFFFF +} VkVendorId; + +typedef enum VkSystemAllocationScope { + VK_SYSTEM_ALLOCATION_SCOPE_COMMAND = 0, + VK_SYSTEM_ALLOCATION_SCOPE_OBJECT = 1, + VK_SYSTEM_ALLOCATION_SCOPE_CACHE = 2, + VK_SYSTEM_ALLOCATION_SCOPE_DEVICE = 3, + VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE = 4, + VK_SYSTEM_ALLOCATION_SCOPE_MAX_ENUM = 0x7FFFFFFF +} VkSystemAllocationScope; + +typedef enum VkInternalAllocationType { + VK_INTERNAL_ALLOCATION_TYPE_EXECUTABLE = 0, + VK_INTERNAL_ALLOCATION_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkInternalAllocationType; + +typedef enum VkFormat { + VK_FORMAT_UNDEFINED = 0, + VK_FORMAT_R4G4_UNORM_PACK8 = 1, + VK_FORMAT_R4G4B4A4_UNORM_PACK16 = 2, + VK_FORMAT_B4G4R4A4_UNORM_PACK16 = 3, + VK_FORMAT_R5G6B5_UNORM_PACK16 = 4, + VK_FORMAT_B5G6R5_UNORM_PACK16 = 5, + VK_FORMAT_R5G5B5A1_UNORM_PACK16 = 6, + VK_FORMAT_B5G5R5A1_UNORM_PACK16 = 7, + VK_FORMAT_A1R5G5B5_UNORM_PACK16 = 8, + VK_FORMAT_R8_UNORM = 9, + VK_FORMAT_R8_SNORM = 10, + VK_FORMAT_R8_USCALED = 11, + VK_FORMAT_R8_SSCALED = 12, + VK_FORMAT_R8_UINT = 13, + VK_FORMAT_R8_SINT = 14, + VK_FORMAT_R8_SRGB = 15, + VK_FORMAT_R8G8_UNORM = 16, + VK_FORMAT_R8G8_SNORM = 17, + VK_FORMAT_R8G8_USCALED = 18, + VK_FORMAT_R8G8_SSCALED = 19, + VK_FORMAT_R8G8_UINT = 20, + VK_FORMAT_R8G8_SINT = 21, + VK_FORMAT_R8G8_SRGB = 22, + VK_FORMAT_R8G8B8_UNORM = 23, + VK_FORMAT_R8G8B8_SNORM = 24, + VK_FORMAT_R8G8B8_USCALED = 25, + VK_FORMAT_R8G8B8_SSCALED = 26, + VK_FORMAT_R8G8B8_UINT = 27, + VK_FORMAT_R8G8B8_SINT = 28, + VK_FORMAT_R8G8B8_SRGB = 29, + VK_FORMAT_B8G8R8_UNORM = 30, + VK_FORMAT_B8G8R8_SNORM = 31, + VK_FORMAT_B8G8R8_USCALED = 32, + VK_FORMAT_B8G8R8_SSCALED = 33, + VK_FORMAT_B8G8R8_UINT = 34, + VK_FORMAT_B8G8R8_SINT = 35, + VK_FORMAT_B8G8R8_SRGB = 36, + VK_FORMAT_R8G8B8A8_UNORM = 37, + VK_FORMAT_R8G8B8A8_SNORM = 38, + VK_FORMAT_R8G8B8A8_USCALED = 39, + VK_FORMAT_R8G8B8A8_SSCALED = 40, + VK_FORMAT_R8G8B8A8_UINT = 41, + VK_FORMAT_R8G8B8A8_SINT = 42, + VK_FORMAT_R8G8B8A8_SRGB = 43, + VK_FORMAT_B8G8R8A8_UNORM = 44, + VK_FORMAT_B8G8R8A8_SNORM = 45, + VK_FORMAT_B8G8R8A8_USCALED = 46, + VK_FORMAT_B8G8R8A8_SSCALED = 47, + VK_FORMAT_B8G8R8A8_UINT = 48, + VK_FORMAT_B8G8R8A8_SINT = 49, + VK_FORMAT_B8G8R8A8_SRGB = 50, + VK_FORMAT_A8B8G8R8_UNORM_PACK32 = 51, + VK_FORMAT_A8B8G8R8_SNORM_PACK32 = 52, + VK_FORMAT_A8B8G8R8_USCALED_PACK32 = 53, + VK_FORMAT_A8B8G8R8_SSCALED_PACK32 = 54, + VK_FORMAT_A8B8G8R8_UINT_PACK32 = 55, + VK_FORMAT_A8B8G8R8_SINT_PACK32 = 56, + VK_FORMAT_A8B8G8R8_SRGB_PACK32 = 57, + VK_FORMAT_A2R10G10B10_UNORM_PACK32 = 58, + VK_FORMAT_A2R10G10B10_SNORM_PACK32 = 59, + VK_FORMAT_A2R10G10B10_USCALED_PACK32 = 60, + VK_FORMAT_A2R10G10B10_SSCALED_PACK32 = 61, + VK_FORMAT_A2R10G10B10_UINT_PACK32 = 62, + VK_FORMAT_A2R10G10B10_SINT_PACK32 = 63, + VK_FORMAT_A2B10G10R10_UNORM_PACK32 = 64, + VK_FORMAT_A2B10G10R10_SNORM_PACK32 = 65, + VK_FORMAT_A2B10G10R10_USCALED_PACK32 = 66, + VK_FORMAT_A2B10G10R10_SSCALED_PACK32 = 67, + VK_FORMAT_A2B10G10R10_UINT_PACK32 = 68, + VK_FORMAT_A2B10G10R10_SINT_PACK32 = 69, + VK_FORMAT_R16_UNORM = 70, + VK_FORMAT_R16_SNORM = 71, + VK_FORMAT_R16_USCALED = 72, + VK_FORMAT_R16_SSCALED = 73, + VK_FORMAT_R16_UINT = 74, + VK_FORMAT_R16_SINT = 75, + VK_FORMAT_R16_SFLOAT = 76, + VK_FORMAT_R16G16_UNORM = 77, + VK_FORMAT_R16G16_SNORM = 78, + VK_FORMAT_R16G16_USCALED = 79, + VK_FORMAT_R16G16_SSCALED = 80, + VK_FORMAT_R16G16_UINT = 81, + VK_FORMAT_R16G16_SINT = 82, + VK_FORMAT_R16G16_SFLOAT = 83, + VK_FORMAT_R16G16B16_UNORM = 84, + VK_FORMAT_R16G16B16_SNORM = 85, + VK_FORMAT_R16G16B16_USCALED = 86, + VK_FORMAT_R16G16B16_SSCALED = 87, + VK_FORMAT_R16G16B16_UINT = 88, + VK_FORMAT_R16G16B16_SINT = 89, + VK_FORMAT_R16G16B16_SFLOAT = 90, + VK_FORMAT_R16G16B16A16_UNORM = 91, + VK_FORMAT_R16G16B16A16_SNORM = 92, + VK_FORMAT_R16G16B16A16_USCALED = 93, + VK_FORMAT_R16G16B16A16_SSCALED = 94, + VK_FORMAT_R16G16B16A16_UINT = 95, + VK_FORMAT_R16G16B16A16_SINT = 96, + VK_FORMAT_R16G16B16A16_SFLOAT = 97, + VK_FORMAT_R32_UINT = 98, + VK_FORMAT_R32_SINT = 99, + VK_FORMAT_R32_SFLOAT = 100, + VK_FORMAT_R32G32_UINT = 101, + VK_FORMAT_R32G32_SINT = 102, + VK_FORMAT_R32G32_SFLOAT = 103, + VK_FORMAT_R32G32B32_UINT = 104, + VK_FORMAT_R32G32B32_SINT = 105, + VK_FORMAT_R32G32B32_SFLOAT = 106, + VK_FORMAT_R32G32B32A32_UINT = 107, + VK_FORMAT_R32G32B32A32_SINT = 108, + VK_FORMAT_R32G32B32A32_SFLOAT = 109, + VK_FORMAT_R64_UINT = 110, + VK_FORMAT_R64_SINT = 111, + VK_FORMAT_R64_SFLOAT = 112, + VK_FORMAT_R64G64_UINT = 113, + VK_FORMAT_R64G64_SINT = 114, + VK_FORMAT_R64G64_SFLOAT = 115, + VK_FORMAT_R64G64B64_UINT = 116, + VK_FORMAT_R64G64B64_SINT = 117, + VK_FORMAT_R64G64B64_SFLOAT = 118, + VK_FORMAT_R64G64B64A64_UINT = 119, + VK_FORMAT_R64G64B64A64_SINT = 120, + VK_FORMAT_R64G64B64A64_SFLOAT = 121, + VK_FORMAT_B10G11R11_UFLOAT_PACK32 = 122, + VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 = 123, + VK_FORMAT_D16_UNORM = 124, + VK_FORMAT_X8_D24_UNORM_PACK32 = 125, + VK_FORMAT_D32_SFLOAT = 126, + VK_FORMAT_S8_UINT = 127, + VK_FORMAT_D16_UNORM_S8_UINT = 128, + VK_FORMAT_D24_UNORM_S8_UINT = 129, + VK_FORMAT_D32_SFLOAT_S8_UINT = 130, + VK_FORMAT_BC1_RGB_UNORM_BLOCK = 131, + VK_FORMAT_BC1_RGB_SRGB_BLOCK = 132, + VK_FORMAT_BC1_RGBA_UNORM_BLOCK = 133, + VK_FORMAT_BC1_RGBA_SRGB_BLOCK = 134, + VK_FORMAT_BC2_UNORM_BLOCK = 135, + VK_FORMAT_BC2_SRGB_BLOCK = 136, + VK_FORMAT_BC3_UNORM_BLOCK = 137, + VK_FORMAT_BC3_SRGB_BLOCK = 138, + VK_FORMAT_BC4_UNORM_BLOCK = 139, + VK_FORMAT_BC4_SNORM_BLOCK = 140, + VK_FORMAT_BC5_UNORM_BLOCK = 141, + VK_FORMAT_BC5_SNORM_BLOCK = 142, + VK_FORMAT_BC6H_UFLOAT_BLOCK = 143, + VK_FORMAT_BC6H_SFLOAT_BLOCK = 144, + VK_FORMAT_BC7_UNORM_BLOCK = 145, + VK_FORMAT_BC7_SRGB_BLOCK = 146, + VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK = 147, + VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK = 148, + VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK = 149, + VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK = 150, + VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK = 151, + VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK = 152, + VK_FORMAT_EAC_R11_UNORM_BLOCK = 153, + VK_FORMAT_EAC_R11_SNORM_BLOCK = 154, + VK_FORMAT_EAC_R11G11_UNORM_BLOCK = 155, + VK_FORMAT_EAC_R11G11_SNORM_BLOCK = 156, + VK_FORMAT_ASTC_4x4_UNORM_BLOCK = 157, + VK_FORMAT_ASTC_4x4_SRGB_BLOCK = 158, + VK_FORMAT_ASTC_5x4_UNORM_BLOCK = 159, + VK_FORMAT_ASTC_5x4_SRGB_BLOCK = 160, + VK_FORMAT_ASTC_5x5_UNORM_BLOCK = 161, + VK_FORMAT_ASTC_5x5_SRGB_BLOCK = 162, + VK_FORMAT_ASTC_6x5_UNORM_BLOCK = 163, + VK_FORMAT_ASTC_6x5_SRGB_BLOCK = 164, + VK_FORMAT_ASTC_6x6_UNORM_BLOCK = 165, + VK_FORMAT_ASTC_6x6_SRGB_BLOCK = 166, + VK_FORMAT_ASTC_8x5_UNORM_BLOCK = 167, + VK_FORMAT_ASTC_8x5_SRGB_BLOCK = 168, + VK_FORMAT_ASTC_8x6_UNORM_BLOCK = 169, + VK_FORMAT_ASTC_8x6_SRGB_BLOCK = 170, + VK_FORMAT_ASTC_8x8_UNORM_BLOCK = 171, + VK_FORMAT_ASTC_8x8_SRGB_BLOCK = 172, + VK_FORMAT_ASTC_10x5_UNORM_BLOCK = 173, + VK_FORMAT_ASTC_10x5_SRGB_BLOCK = 174, + VK_FORMAT_ASTC_10x6_UNORM_BLOCK = 175, + VK_FORMAT_ASTC_10x6_SRGB_BLOCK = 176, + VK_FORMAT_ASTC_10x8_UNORM_BLOCK = 177, + VK_FORMAT_ASTC_10x8_SRGB_BLOCK = 178, + VK_FORMAT_ASTC_10x10_UNORM_BLOCK = 179, + VK_FORMAT_ASTC_10x10_SRGB_BLOCK = 180, + VK_FORMAT_ASTC_12x10_UNORM_BLOCK = 181, + VK_FORMAT_ASTC_12x10_SRGB_BLOCK = 182, + VK_FORMAT_ASTC_12x12_UNORM_BLOCK = 183, + VK_FORMAT_ASTC_12x12_SRGB_BLOCK = 184, + VK_FORMAT_G8B8G8R8_422_UNORM = 1000156000, + VK_FORMAT_B8G8R8G8_422_UNORM = 1000156001, + VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM = 1000156002, + VK_FORMAT_G8_B8R8_2PLANE_420_UNORM = 1000156003, + VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM = 1000156004, + VK_FORMAT_G8_B8R8_2PLANE_422_UNORM = 1000156005, + VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM = 1000156006, + VK_FORMAT_R10X6_UNORM_PACK16 = 1000156007, + VK_FORMAT_R10X6G10X6_UNORM_2PACK16 = 1000156008, + VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16 = 1000156009, + VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16 = 1000156010, + VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16 = 1000156011, + VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16 = 1000156012, + VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16 = 1000156013, + VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16 = 1000156014, + VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16 = 1000156015, + VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16 = 1000156016, + VK_FORMAT_R12X4_UNORM_PACK16 = 1000156017, + VK_FORMAT_R12X4G12X4_UNORM_2PACK16 = 1000156018, + VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16 = 1000156019, + VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16 = 1000156020, + VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16 = 1000156021, + VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16 = 1000156022, + VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16 = 1000156023, + VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16 = 1000156024, + VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16 = 1000156025, + VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16 = 1000156026, + VK_FORMAT_G16B16G16R16_422_UNORM = 1000156027, + VK_FORMAT_B16G16R16G16_422_UNORM = 1000156028, + VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM = 1000156029, + VK_FORMAT_G16_B16R16_2PLANE_420_UNORM = 1000156030, + VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM = 1000156031, + VK_FORMAT_G16_B16R16_2PLANE_422_UNORM = 1000156032, + VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM = 1000156033, + VK_FORMAT_G8_B8R8_2PLANE_444_UNORM = 1000330000, + VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16 = 1000330001, + VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16 = 1000330002, + VK_FORMAT_G16_B16R16_2PLANE_444_UNORM = 1000330003, + VK_FORMAT_A4R4G4B4_UNORM_PACK16 = 1000340000, + VK_FORMAT_A4B4G4R4_UNORM_PACK16 = 1000340001, + VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK = 1000066000, + VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK = 1000066001, + VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK = 1000066002, + VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK = 1000066003, + VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK = 1000066004, + VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK = 1000066005, + VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK = 1000066006, + VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK = 1000066007, + VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK = 1000066008, + VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK = 1000066009, + VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK = 1000066010, + VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK = 1000066011, + VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK = 1000066012, + VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK = 1000066013, + VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG = 1000054000, + VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG = 1000054001, + VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG = 1000054002, + VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG = 1000054003, + VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG = 1000054004, + VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG = 1000054005, + VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG = 1000054006, + VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG = 1000054007, + VK_FORMAT_R16G16_S10_5_NV = 1000464000, + VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR = 1000470000, + VK_FORMAT_A8_UNORM_KHR = 1000470001, + VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK, + VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK, + VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK, + VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK, + VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK, + VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK, + VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK, + VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK, + VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK, + VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK, + VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK, + VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK, + VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK, + VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK, + VK_FORMAT_G8B8G8R8_422_UNORM_KHR = VK_FORMAT_G8B8G8R8_422_UNORM, + VK_FORMAT_B8G8R8G8_422_UNORM_KHR = VK_FORMAT_B8G8R8G8_422_UNORM, + VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM, + VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, + VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM_KHR = VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM, + VK_FORMAT_G8_B8R8_2PLANE_422_UNORM_KHR = VK_FORMAT_G8_B8R8_2PLANE_422_UNORM, + VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM_KHR = VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM, + VK_FORMAT_R10X6_UNORM_PACK16_KHR = VK_FORMAT_R10X6_UNORM_PACK16, + VK_FORMAT_R10X6G10X6_UNORM_2PACK16_KHR = VK_FORMAT_R10X6G10X6_UNORM_2PACK16, + VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16_KHR = VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16, + VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16_KHR = VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16, + VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16_KHR = VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16, + VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_KHR = VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16, + VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_KHR = VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16, + VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16_KHR = VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16, + VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16_KHR = VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16, + VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16_KHR = VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16, + VK_FORMAT_R12X4_UNORM_PACK16_KHR = VK_FORMAT_R12X4_UNORM_PACK16, + VK_FORMAT_R12X4G12X4_UNORM_2PACK16_KHR = VK_FORMAT_R12X4G12X4_UNORM_2PACK16, + VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16_KHR = VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16, + VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16_KHR = VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16, + VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16_KHR = VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16, + VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_KHR = VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16, + VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_KHR = VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16, + VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16_KHR = VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16, + VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16_KHR = VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16, + VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16_KHR = VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16, + VK_FORMAT_G16B16G16R16_422_UNORM_KHR = VK_FORMAT_G16B16G16R16_422_UNORM, + VK_FORMAT_B16G16R16G16_422_UNORM_KHR = VK_FORMAT_B16G16R16G16_422_UNORM, + VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM_KHR = VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM, + VK_FORMAT_G16_B16R16_2PLANE_420_UNORM_KHR = VK_FORMAT_G16_B16R16_2PLANE_420_UNORM, + VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM_KHR = VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM, + VK_FORMAT_G16_B16R16_2PLANE_422_UNORM_KHR = VK_FORMAT_G16_B16R16_2PLANE_422_UNORM, + VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM_KHR = VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM, + VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT = VK_FORMAT_G8_B8R8_2PLANE_444_UNORM, + VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT = VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16, + VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT = VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16, + VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT = VK_FORMAT_G16_B16R16_2PLANE_444_UNORM, + VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT = VK_FORMAT_A4R4G4B4_UNORM_PACK16, + VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT = VK_FORMAT_A4B4G4R4_UNORM_PACK16, + VK_FORMAT_MAX_ENUM = 0x7FFFFFFF +} VkFormat; + +typedef enum VkImageTiling { + VK_IMAGE_TILING_OPTIMAL = 0, + VK_IMAGE_TILING_LINEAR = 1, + VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT = 1000158000, + VK_IMAGE_TILING_MAX_ENUM = 0x7FFFFFFF +} VkImageTiling; + +typedef enum VkImageType { + VK_IMAGE_TYPE_1D = 0, + VK_IMAGE_TYPE_2D = 1, + VK_IMAGE_TYPE_3D = 2, + VK_IMAGE_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkImageType; + +typedef enum VkPhysicalDeviceType { + VK_PHYSICAL_DEVICE_TYPE_OTHER = 0, + VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU = 1, + VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU = 2, + VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU = 3, + VK_PHYSICAL_DEVICE_TYPE_CPU = 4, + VK_PHYSICAL_DEVICE_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkPhysicalDeviceType; + +typedef enum VkQueryType { + VK_QUERY_TYPE_OCCLUSION = 0, + VK_QUERY_TYPE_PIPELINE_STATISTICS = 1, + VK_QUERY_TYPE_TIMESTAMP = 2, + VK_QUERY_TYPE_RESULT_STATUS_ONLY_KHR = 1000023000, + VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT = 1000028004, + VK_QUERY_TYPE_PERFORMANCE_QUERY_KHR = 1000116000, + VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR = 1000150000, + VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR = 1000150001, + VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_NV = 1000165000, + VK_QUERY_TYPE_PERFORMANCE_QUERY_INTEL = 1000210000, + VK_QUERY_TYPE_VIDEO_ENCODE_FEEDBACK_KHR = 1000299000, + VK_QUERY_TYPE_MESH_PRIMITIVES_GENERATED_EXT = 1000328000, + VK_QUERY_TYPE_PRIMITIVES_GENERATED_EXT = 1000382000, + VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_BOTTOM_LEVEL_POINTERS_KHR = 1000386000, + VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SIZE_KHR = 1000386001, + VK_QUERY_TYPE_MICROMAP_SERIALIZATION_SIZE_EXT = 1000396000, + VK_QUERY_TYPE_MICROMAP_COMPACTED_SIZE_EXT = 1000396001, + VK_QUERY_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkQueryType; + +typedef enum VkSharingMode { + VK_SHARING_MODE_EXCLUSIVE = 0, + VK_SHARING_MODE_CONCURRENT = 1, + VK_SHARING_MODE_MAX_ENUM = 0x7FFFFFFF +} VkSharingMode; + +typedef enum VkComponentSwizzle { + VK_COMPONENT_SWIZZLE_IDENTITY = 0, + VK_COMPONENT_SWIZZLE_ZERO = 1, + VK_COMPONENT_SWIZZLE_ONE = 2, + VK_COMPONENT_SWIZZLE_R = 3, + VK_COMPONENT_SWIZZLE_G = 4, + VK_COMPONENT_SWIZZLE_B = 5, + VK_COMPONENT_SWIZZLE_A = 6, + VK_COMPONENT_SWIZZLE_MAX_ENUM = 0x7FFFFFFF +} VkComponentSwizzle; + +typedef enum VkImageViewType { + VK_IMAGE_VIEW_TYPE_1D = 0, + VK_IMAGE_VIEW_TYPE_2D = 1, + VK_IMAGE_VIEW_TYPE_3D = 2, + VK_IMAGE_VIEW_TYPE_CUBE = 3, + VK_IMAGE_VIEW_TYPE_1D_ARRAY = 4, + VK_IMAGE_VIEW_TYPE_2D_ARRAY = 5, + VK_IMAGE_VIEW_TYPE_CUBE_ARRAY = 6, + VK_IMAGE_VIEW_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkImageViewType; + +typedef enum VkBlendFactor { + VK_BLEND_FACTOR_ZERO = 0, + VK_BLEND_FACTOR_ONE = 1, + VK_BLEND_FACTOR_SRC_COLOR = 2, + VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR = 3, + VK_BLEND_FACTOR_DST_COLOR = 4, + VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR = 5, + VK_BLEND_FACTOR_SRC_ALPHA = 6, + VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA = 7, + VK_BLEND_FACTOR_DST_ALPHA = 8, + VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA = 9, + VK_BLEND_FACTOR_CONSTANT_COLOR = 10, + VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR = 11, + VK_BLEND_FACTOR_CONSTANT_ALPHA = 12, + VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA = 13, + VK_BLEND_FACTOR_SRC_ALPHA_SATURATE = 14, + VK_BLEND_FACTOR_SRC1_COLOR = 15, + VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR = 16, + VK_BLEND_FACTOR_SRC1_ALPHA = 17, + VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA = 18, + VK_BLEND_FACTOR_MAX_ENUM = 0x7FFFFFFF +} VkBlendFactor; + +typedef enum VkBlendOp { + VK_BLEND_OP_ADD = 0, + VK_BLEND_OP_SUBTRACT = 1, + VK_BLEND_OP_REVERSE_SUBTRACT = 2, + VK_BLEND_OP_MIN = 3, + VK_BLEND_OP_MAX = 4, + VK_BLEND_OP_ZERO_EXT = 1000148000, + VK_BLEND_OP_SRC_EXT = 1000148001, + VK_BLEND_OP_DST_EXT = 1000148002, + VK_BLEND_OP_SRC_OVER_EXT = 1000148003, + VK_BLEND_OP_DST_OVER_EXT = 1000148004, + VK_BLEND_OP_SRC_IN_EXT = 1000148005, + VK_BLEND_OP_DST_IN_EXT = 1000148006, + VK_BLEND_OP_SRC_OUT_EXT = 1000148007, + VK_BLEND_OP_DST_OUT_EXT = 1000148008, + VK_BLEND_OP_SRC_ATOP_EXT = 1000148009, + VK_BLEND_OP_DST_ATOP_EXT = 1000148010, + VK_BLEND_OP_XOR_EXT = 1000148011, + VK_BLEND_OP_MULTIPLY_EXT = 1000148012, + VK_BLEND_OP_SCREEN_EXT = 1000148013, + VK_BLEND_OP_OVERLAY_EXT = 1000148014, + VK_BLEND_OP_DARKEN_EXT = 1000148015, + VK_BLEND_OP_LIGHTEN_EXT = 1000148016, + VK_BLEND_OP_COLORDODGE_EXT = 1000148017, + VK_BLEND_OP_COLORBURN_EXT = 1000148018, + VK_BLEND_OP_HARDLIGHT_EXT = 1000148019, + VK_BLEND_OP_SOFTLIGHT_EXT = 1000148020, + VK_BLEND_OP_DIFFERENCE_EXT = 1000148021, + VK_BLEND_OP_EXCLUSION_EXT = 1000148022, + VK_BLEND_OP_INVERT_EXT = 1000148023, + VK_BLEND_OP_INVERT_RGB_EXT = 1000148024, + VK_BLEND_OP_LINEARDODGE_EXT = 1000148025, + VK_BLEND_OP_LINEARBURN_EXT = 1000148026, + VK_BLEND_OP_VIVIDLIGHT_EXT = 1000148027, + VK_BLEND_OP_LINEARLIGHT_EXT = 1000148028, + VK_BLEND_OP_PINLIGHT_EXT = 1000148029, + VK_BLEND_OP_HARDMIX_EXT = 1000148030, + VK_BLEND_OP_HSL_HUE_EXT = 1000148031, + VK_BLEND_OP_HSL_SATURATION_EXT = 1000148032, + VK_BLEND_OP_HSL_COLOR_EXT = 1000148033, + VK_BLEND_OP_HSL_LUMINOSITY_EXT = 1000148034, + VK_BLEND_OP_PLUS_EXT = 1000148035, + VK_BLEND_OP_PLUS_CLAMPED_EXT = 1000148036, + VK_BLEND_OP_PLUS_CLAMPED_ALPHA_EXT = 1000148037, + VK_BLEND_OP_PLUS_DARKER_EXT = 1000148038, + VK_BLEND_OP_MINUS_EXT = 1000148039, + VK_BLEND_OP_MINUS_CLAMPED_EXT = 1000148040, + VK_BLEND_OP_CONTRAST_EXT = 1000148041, + VK_BLEND_OP_INVERT_OVG_EXT = 1000148042, + VK_BLEND_OP_RED_EXT = 1000148043, + VK_BLEND_OP_GREEN_EXT = 1000148044, + VK_BLEND_OP_BLUE_EXT = 1000148045, + VK_BLEND_OP_MAX_ENUM = 0x7FFFFFFF +} VkBlendOp; + +typedef enum VkCompareOp { + VK_COMPARE_OP_NEVER = 0, + VK_COMPARE_OP_LESS = 1, + VK_COMPARE_OP_EQUAL = 2, + VK_COMPARE_OP_LESS_OR_EQUAL = 3, + VK_COMPARE_OP_GREATER = 4, + VK_COMPARE_OP_NOT_EQUAL = 5, + VK_COMPARE_OP_GREATER_OR_EQUAL = 6, + VK_COMPARE_OP_ALWAYS = 7, + VK_COMPARE_OP_MAX_ENUM = 0x7FFFFFFF +} VkCompareOp; + +typedef enum VkDynamicState { + VK_DYNAMIC_STATE_VIEWPORT = 0, + VK_DYNAMIC_STATE_SCISSOR = 1, + VK_DYNAMIC_STATE_LINE_WIDTH = 2, + VK_DYNAMIC_STATE_DEPTH_BIAS = 3, + VK_DYNAMIC_STATE_BLEND_CONSTANTS = 4, + VK_DYNAMIC_STATE_DEPTH_BOUNDS = 5, + VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK = 6, + VK_DYNAMIC_STATE_STENCIL_WRITE_MASK = 7, + VK_DYNAMIC_STATE_STENCIL_REFERENCE = 8, + VK_DYNAMIC_STATE_CULL_MODE = 1000267000, + VK_DYNAMIC_STATE_FRONT_FACE = 1000267001, + VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY = 1000267002, + VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT = 1000267003, + VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT = 1000267004, + VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE = 1000267005, + VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE = 1000267006, + VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE = 1000267007, + VK_DYNAMIC_STATE_DEPTH_COMPARE_OP = 1000267008, + VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE = 1000267009, + VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE = 1000267010, + VK_DYNAMIC_STATE_STENCIL_OP = 1000267011, + VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE = 1000377001, + VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE = 1000377002, + VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE = 1000377004, + VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV = 1000087000, + VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT = 1000099000, + VK_DYNAMIC_STATE_DISCARD_RECTANGLE_ENABLE_EXT = 1000099001, + VK_DYNAMIC_STATE_DISCARD_RECTANGLE_MODE_EXT = 1000099002, + VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT = 1000143000, + VK_DYNAMIC_STATE_RAY_TRACING_PIPELINE_STACK_SIZE_KHR = 1000347000, + VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV = 1000164004, + VK_DYNAMIC_STATE_VIEWPORT_COARSE_SAMPLE_ORDER_NV = 1000164006, + VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_ENABLE_NV = 1000205000, + VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV = 1000205001, + VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR = 1000226000, + VK_DYNAMIC_STATE_LINE_STIPPLE_EXT = 1000259000, + VK_DYNAMIC_STATE_VERTEX_INPUT_EXT = 1000352000, + VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT = 1000377000, + VK_DYNAMIC_STATE_LOGIC_OP_EXT = 1000377003, + VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT = 1000381000, + VK_DYNAMIC_STATE_TESSELLATION_DOMAIN_ORIGIN_EXT = 1000455002, + VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT = 1000455003, + VK_DYNAMIC_STATE_POLYGON_MODE_EXT = 1000455004, + VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT = 1000455005, + VK_DYNAMIC_STATE_SAMPLE_MASK_EXT = 1000455006, + VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT = 1000455007, + VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT = 1000455008, + VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT = 1000455009, + VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT = 1000455010, + VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT = 1000455011, + VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT = 1000455012, + VK_DYNAMIC_STATE_RASTERIZATION_STREAM_EXT = 1000455013, + VK_DYNAMIC_STATE_CONSERVATIVE_RASTERIZATION_MODE_EXT = 1000455014, + VK_DYNAMIC_STATE_EXTRA_PRIMITIVE_OVERESTIMATION_SIZE_EXT = 1000455015, + VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT = 1000455016, + VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_ENABLE_EXT = 1000455017, + VK_DYNAMIC_STATE_COLOR_BLEND_ADVANCED_EXT = 1000455018, + VK_DYNAMIC_STATE_PROVOKING_VERTEX_MODE_EXT = 1000455019, + VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT = 1000455020, + VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT = 1000455021, + VK_DYNAMIC_STATE_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT = 1000455022, + VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_ENABLE_NV = 1000455023, + VK_DYNAMIC_STATE_VIEWPORT_SWIZZLE_NV = 1000455024, + VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_ENABLE_NV = 1000455025, + VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_LOCATION_NV = 1000455026, + VK_DYNAMIC_STATE_COVERAGE_MODULATION_MODE_NV = 1000455027, + VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_ENABLE_NV = 1000455028, + VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_NV = 1000455029, + VK_DYNAMIC_STATE_SHADING_RATE_IMAGE_ENABLE_NV = 1000455030, + VK_DYNAMIC_STATE_REPRESENTATIVE_FRAGMENT_TEST_ENABLE_NV = 1000455031, + VK_DYNAMIC_STATE_COVERAGE_REDUCTION_MODE_NV = 1000455032, + VK_DYNAMIC_STATE_ATTACHMENT_FEEDBACK_LOOP_ENABLE_EXT = 1000524000, + VK_DYNAMIC_STATE_CULL_MODE_EXT = VK_DYNAMIC_STATE_CULL_MODE, + VK_DYNAMIC_STATE_FRONT_FACE_EXT = VK_DYNAMIC_STATE_FRONT_FACE, + VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT = VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY, + VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT = VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT, + VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT = VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT, + VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT = VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE, + VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT = VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE, + VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT = VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE, + VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT = VK_DYNAMIC_STATE_DEPTH_COMPARE_OP, + VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT = VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE, + VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT = VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE, + VK_DYNAMIC_STATE_STENCIL_OP_EXT = VK_DYNAMIC_STATE_STENCIL_OP, + VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT = VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE, + VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT = VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE, + VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT = VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE, + VK_DYNAMIC_STATE_MAX_ENUM = 0x7FFFFFFF +} VkDynamicState; + +typedef enum VkFrontFace { + VK_FRONT_FACE_COUNTER_CLOCKWISE = 0, + VK_FRONT_FACE_CLOCKWISE = 1, + VK_FRONT_FACE_MAX_ENUM = 0x7FFFFFFF +} VkFrontFace; + +typedef enum VkVertexInputRate { + VK_VERTEX_INPUT_RATE_VERTEX = 0, + VK_VERTEX_INPUT_RATE_INSTANCE = 1, + VK_VERTEX_INPUT_RATE_MAX_ENUM = 0x7FFFFFFF +} VkVertexInputRate; + +typedef enum VkPrimitiveTopology { + VK_PRIMITIVE_TOPOLOGY_POINT_LIST = 0, + VK_PRIMITIVE_TOPOLOGY_LINE_LIST = 1, + VK_PRIMITIVE_TOPOLOGY_LINE_STRIP = 2, + VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST = 3, + VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP = 4, + VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN = 5, + VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY = 6, + VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY = 7, + VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY = 8, + VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY = 9, + VK_PRIMITIVE_TOPOLOGY_PATCH_LIST = 10, + VK_PRIMITIVE_TOPOLOGY_MAX_ENUM = 0x7FFFFFFF +} VkPrimitiveTopology; + +typedef enum VkPolygonMode { + VK_POLYGON_MODE_FILL = 0, + VK_POLYGON_MODE_LINE = 1, + VK_POLYGON_MODE_POINT = 2, + VK_POLYGON_MODE_FILL_RECTANGLE_NV = 1000153000, + VK_POLYGON_MODE_MAX_ENUM = 0x7FFFFFFF +} VkPolygonMode; + +typedef enum VkStencilOp { + VK_STENCIL_OP_KEEP = 0, + VK_STENCIL_OP_ZERO = 1, + VK_STENCIL_OP_REPLACE = 2, + VK_STENCIL_OP_INCREMENT_AND_CLAMP = 3, + VK_STENCIL_OP_DECREMENT_AND_CLAMP = 4, + VK_STENCIL_OP_INVERT = 5, + VK_STENCIL_OP_INCREMENT_AND_WRAP = 6, + VK_STENCIL_OP_DECREMENT_AND_WRAP = 7, + VK_STENCIL_OP_MAX_ENUM = 0x7FFFFFFF +} VkStencilOp; + +typedef enum VkLogicOp { + VK_LOGIC_OP_CLEAR = 0, + VK_LOGIC_OP_AND = 1, + VK_LOGIC_OP_AND_REVERSE = 2, + VK_LOGIC_OP_COPY = 3, + VK_LOGIC_OP_AND_INVERTED = 4, + VK_LOGIC_OP_NO_OP = 5, + VK_LOGIC_OP_XOR = 6, + VK_LOGIC_OP_OR = 7, + VK_LOGIC_OP_NOR = 8, + VK_LOGIC_OP_EQUIVALENT = 9, + VK_LOGIC_OP_INVERT = 10, + VK_LOGIC_OP_OR_REVERSE = 11, + VK_LOGIC_OP_COPY_INVERTED = 12, + VK_LOGIC_OP_OR_INVERTED = 13, + VK_LOGIC_OP_NAND = 14, + VK_LOGIC_OP_SET = 15, + VK_LOGIC_OP_MAX_ENUM = 0x7FFFFFFF +} VkLogicOp; + +typedef enum VkBorderColor { + VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK = 0, + VK_BORDER_COLOR_INT_TRANSPARENT_BLACK = 1, + VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK = 2, + VK_BORDER_COLOR_INT_OPAQUE_BLACK = 3, + VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE = 4, + VK_BORDER_COLOR_INT_OPAQUE_WHITE = 5, + VK_BORDER_COLOR_FLOAT_CUSTOM_EXT = 1000287003, + VK_BORDER_COLOR_INT_CUSTOM_EXT = 1000287004, + VK_BORDER_COLOR_MAX_ENUM = 0x7FFFFFFF +} VkBorderColor; + +typedef enum VkFilter { + VK_FILTER_NEAREST = 0, + VK_FILTER_LINEAR = 1, + VK_FILTER_CUBIC_EXT = 1000015000, + VK_FILTER_CUBIC_IMG = VK_FILTER_CUBIC_EXT, + VK_FILTER_MAX_ENUM = 0x7FFFFFFF +} VkFilter; + +typedef enum VkSamplerAddressMode { + VK_SAMPLER_ADDRESS_MODE_REPEAT = 0, + VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT = 1, + VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE = 2, + VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER = 3, + VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE = 4, + VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE_KHR = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, + VK_SAMPLER_ADDRESS_MODE_MAX_ENUM = 0x7FFFFFFF +} VkSamplerAddressMode; + +typedef enum VkSamplerMipmapMode { + VK_SAMPLER_MIPMAP_MODE_NEAREST = 0, + VK_SAMPLER_MIPMAP_MODE_LINEAR = 1, + VK_SAMPLER_MIPMAP_MODE_MAX_ENUM = 0x7FFFFFFF +} VkSamplerMipmapMode; + +typedef enum VkDescriptorType { + VK_DESCRIPTOR_TYPE_SAMPLER = 0, + VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER = 1, + VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE = 2, + VK_DESCRIPTOR_TYPE_STORAGE_IMAGE = 3, + VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER = 4, + VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER = 5, + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER = 6, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER = 7, + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC = 8, + VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC = 9, + VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT = 10, + VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK = 1000138000, + VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR = 1000150000, + VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV = 1000165000, + VK_DESCRIPTOR_TYPE_SAMPLE_WEIGHT_IMAGE_QCOM = 1000440000, + VK_DESCRIPTOR_TYPE_BLOCK_MATCH_IMAGE_QCOM = 1000440001, + VK_DESCRIPTOR_TYPE_MUTABLE_EXT = 1000351000, + VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT = VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK, + VK_DESCRIPTOR_TYPE_MUTABLE_VALVE = VK_DESCRIPTOR_TYPE_MUTABLE_EXT, + VK_DESCRIPTOR_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkDescriptorType; + +typedef enum VkAttachmentLoadOp { + VK_ATTACHMENT_LOAD_OP_LOAD = 0, + VK_ATTACHMENT_LOAD_OP_CLEAR = 1, + VK_ATTACHMENT_LOAD_OP_DONT_CARE = 2, + VK_ATTACHMENT_LOAD_OP_NONE_EXT = 1000400000, + VK_ATTACHMENT_LOAD_OP_MAX_ENUM = 0x7FFFFFFF +} VkAttachmentLoadOp; + +typedef enum VkAttachmentStoreOp { + VK_ATTACHMENT_STORE_OP_STORE = 0, + VK_ATTACHMENT_STORE_OP_DONT_CARE = 1, + VK_ATTACHMENT_STORE_OP_NONE = 1000301000, + VK_ATTACHMENT_STORE_OP_NONE_KHR = VK_ATTACHMENT_STORE_OP_NONE, + VK_ATTACHMENT_STORE_OP_NONE_QCOM = VK_ATTACHMENT_STORE_OP_NONE, + VK_ATTACHMENT_STORE_OP_NONE_EXT = VK_ATTACHMENT_STORE_OP_NONE, + VK_ATTACHMENT_STORE_OP_MAX_ENUM = 0x7FFFFFFF +} VkAttachmentStoreOp; + +typedef enum VkPipelineBindPoint { + VK_PIPELINE_BIND_POINT_GRAPHICS = 0, + VK_PIPELINE_BIND_POINT_COMPUTE = 1, +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_PIPELINE_BIND_POINT_EXECUTION_GRAPH_AMDX = 1000134000, +#endif + VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR = 1000165000, + VK_PIPELINE_BIND_POINT_SUBPASS_SHADING_HUAWEI = 1000369003, + VK_PIPELINE_BIND_POINT_RAY_TRACING_NV = VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, + VK_PIPELINE_BIND_POINT_MAX_ENUM = 0x7FFFFFFF +} VkPipelineBindPoint; + +typedef enum VkCommandBufferLevel { + VK_COMMAND_BUFFER_LEVEL_PRIMARY = 0, + VK_COMMAND_BUFFER_LEVEL_SECONDARY = 1, + VK_COMMAND_BUFFER_LEVEL_MAX_ENUM = 0x7FFFFFFF +} VkCommandBufferLevel; + +typedef enum VkIndexType { + VK_INDEX_TYPE_UINT16 = 0, + VK_INDEX_TYPE_UINT32 = 1, + VK_INDEX_TYPE_NONE_KHR = 1000165000, + VK_INDEX_TYPE_UINT8_EXT = 1000265000, + VK_INDEX_TYPE_NONE_NV = VK_INDEX_TYPE_NONE_KHR, + VK_INDEX_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkIndexType; + +typedef enum VkSubpassContents { + VK_SUBPASS_CONTENTS_INLINE = 0, + VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS = 1, + VK_SUBPASS_CONTENTS_INLINE_AND_SECONDARY_COMMAND_BUFFERS_EXT = 1000451000, + VK_SUBPASS_CONTENTS_MAX_ENUM = 0x7FFFFFFF +} VkSubpassContents; + +typedef enum VkAccessFlagBits { + VK_ACCESS_INDIRECT_COMMAND_READ_BIT = 0x00000001, + VK_ACCESS_INDEX_READ_BIT = 0x00000002, + VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT = 0x00000004, + VK_ACCESS_UNIFORM_READ_BIT = 0x00000008, + VK_ACCESS_INPUT_ATTACHMENT_READ_BIT = 0x00000010, + VK_ACCESS_SHADER_READ_BIT = 0x00000020, + VK_ACCESS_SHADER_WRITE_BIT = 0x00000040, + VK_ACCESS_COLOR_ATTACHMENT_READ_BIT = 0x00000080, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT = 0x00000100, + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT = 0x00000200, + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT = 0x00000400, + VK_ACCESS_TRANSFER_READ_BIT = 0x00000800, + VK_ACCESS_TRANSFER_WRITE_BIT = 0x00001000, + VK_ACCESS_HOST_READ_BIT = 0x00002000, + VK_ACCESS_HOST_WRITE_BIT = 0x00004000, + VK_ACCESS_MEMORY_READ_BIT = 0x00008000, + VK_ACCESS_MEMORY_WRITE_BIT = 0x00010000, + VK_ACCESS_NONE = 0, + VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT = 0x02000000, + VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT = 0x04000000, + VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT = 0x08000000, + VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT = 0x00100000, + VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT = 0x00080000, + VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR = 0x00200000, + VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR = 0x00400000, + VK_ACCESS_FRAGMENT_DENSITY_MAP_READ_BIT_EXT = 0x01000000, + VK_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR = 0x00800000, + VK_ACCESS_COMMAND_PREPROCESS_READ_BIT_NV = 0x00020000, + VK_ACCESS_COMMAND_PREPROCESS_WRITE_BIT_NV = 0x00040000, + VK_ACCESS_SHADING_RATE_IMAGE_READ_BIT_NV = VK_ACCESS_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR, + VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_NV = VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR, + VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_NV = VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR, + VK_ACCESS_NONE_KHR = VK_ACCESS_NONE, + VK_ACCESS_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkAccessFlagBits; +typedef VkFlags VkAccessFlags; + +typedef enum VkImageAspectFlagBits { + VK_IMAGE_ASPECT_COLOR_BIT = 0x00000001, + VK_IMAGE_ASPECT_DEPTH_BIT = 0x00000002, + VK_IMAGE_ASPECT_STENCIL_BIT = 0x00000004, + VK_IMAGE_ASPECT_METADATA_BIT = 0x00000008, + VK_IMAGE_ASPECT_PLANE_0_BIT = 0x00000010, + VK_IMAGE_ASPECT_PLANE_1_BIT = 0x00000020, + VK_IMAGE_ASPECT_PLANE_2_BIT = 0x00000040, + VK_IMAGE_ASPECT_NONE = 0, + VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT = 0x00000080, + VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT = 0x00000100, + VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT = 0x00000200, + VK_IMAGE_ASPECT_MEMORY_PLANE_3_BIT_EXT = 0x00000400, + VK_IMAGE_ASPECT_PLANE_0_BIT_KHR = VK_IMAGE_ASPECT_PLANE_0_BIT, + VK_IMAGE_ASPECT_PLANE_1_BIT_KHR = VK_IMAGE_ASPECT_PLANE_1_BIT, + VK_IMAGE_ASPECT_PLANE_2_BIT_KHR = VK_IMAGE_ASPECT_PLANE_2_BIT, + VK_IMAGE_ASPECT_NONE_KHR = VK_IMAGE_ASPECT_NONE, + VK_IMAGE_ASPECT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkImageAspectFlagBits; +typedef VkFlags VkImageAspectFlags; + +typedef enum VkFormatFeatureFlagBits { + VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT = 0x00000001, + VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT = 0x00000002, + VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT = 0x00000004, + VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT = 0x00000008, + VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT = 0x00000010, + VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT = 0x00000020, + VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT = 0x00000040, + VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT = 0x00000080, + VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT = 0x00000100, + VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT = 0x00000200, + VK_FORMAT_FEATURE_BLIT_SRC_BIT = 0x00000400, + VK_FORMAT_FEATURE_BLIT_DST_BIT = 0x00000800, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT = 0x00001000, + VK_FORMAT_FEATURE_TRANSFER_SRC_BIT = 0x00004000, + VK_FORMAT_FEATURE_TRANSFER_DST_BIT = 0x00008000, + VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT = 0x00020000, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT = 0x00040000, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT = 0x00080000, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT = 0x00100000, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT = 0x00200000, + VK_FORMAT_FEATURE_DISJOINT_BIT = 0x00400000, + VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT = 0x00800000, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT = 0x00010000, + VK_FORMAT_FEATURE_VIDEO_DECODE_OUTPUT_BIT_KHR = 0x02000000, + VK_FORMAT_FEATURE_VIDEO_DECODE_DPB_BIT_KHR = 0x04000000, + VK_FORMAT_FEATURE_ACCELERATION_STRUCTURE_VERTEX_BUFFER_BIT_KHR = 0x20000000, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT = 0x00002000, + VK_FORMAT_FEATURE_FRAGMENT_DENSITY_MAP_BIT_EXT = 0x01000000, + VK_FORMAT_FEATURE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x40000000, + VK_FORMAT_FEATURE_VIDEO_ENCODE_INPUT_BIT_KHR = 0x08000000, + VK_FORMAT_FEATURE_VIDEO_ENCODE_DPB_BIT_KHR = 0x10000000, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG = VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT, + VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT, + VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR = VK_FORMAT_FEATURE_TRANSFER_DST_BIT, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT = VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT, + VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT_KHR = VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT_KHR = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT_KHR = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT_KHR = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT, + VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT_KHR = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT, + VK_FORMAT_FEATURE_DISJOINT_BIT_KHR = VK_FORMAT_FEATURE_DISJOINT_BIT, + VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT_KHR = VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT, + VK_FORMAT_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkFormatFeatureFlagBits; +typedef VkFlags VkFormatFeatureFlags; + +typedef enum VkImageCreateFlagBits { + VK_IMAGE_CREATE_SPARSE_BINDING_BIT = 0x00000001, + VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT = 0x00000002, + VK_IMAGE_CREATE_SPARSE_ALIASED_BIT = 0x00000004, + VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT = 0x00000008, + VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT = 0x00000010, + VK_IMAGE_CREATE_ALIAS_BIT = 0x00000400, + VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT = 0x00000040, + VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT = 0x00000020, + VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT = 0x00000080, + VK_IMAGE_CREATE_EXTENDED_USAGE_BIT = 0x00000100, + VK_IMAGE_CREATE_PROTECTED_BIT = 0x00000800, + VK_IMAGE_CREATE_DISJOINT_BIT = 0x00000200, + VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV = 0x00002000, + VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT = 0x00001000, + VK_IMAGE_CREATE_SUBSAMPLED_BIT_EXT = 0x00004000, + VK_IMAGE_CREATE_DESCRIPTOR_BUFFER_CAPTURE_REPLAY_BIT_EXT = 0x00010000, + VK_IMAGE_CREATE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_BIT_EXT = 0x00040000, + VK_IMAGE_CREATE_2D_VIEW_COMPATIBLE_BIT_EXT = 0x00020000, + VK_IMAGE_CREATE_FRAGMENT_DENSITY_MAP_OFFSET_BIT_QCOM = 0x00008000, + VK_IMAGE_CREATE_VIDEO_PROFILE_INDEPENDENT_BIT_KHR = 0x00100000, + VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR = VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT, + VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR = VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT, + VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT_KHR = VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT, + VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR = VK_IMAGE_CREATE_EXTENDED_USAGE_BIT, + VK_IMAGE_CREATE_DISJOINT_BIT_KHR = VK_IMAGE_CREATE_DISJOINT_BIT, + VK_IMAGE_CREATE_ALIAS_BIT_KHR = VK_IMAGE_CREATE_ALIAS_BIT, + VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkImageCreateFlagBits; +typedef VkFlags VkImageCreateFlags; + +typedef enum VkSampleCountFlagBits { + VK_SAMPLE_COUNT_1_BIT = 0x00000001, + VK_SAMPLE_COUNT_2_BIT = 0x00000002, + VK_SAMPLE_COUNT_4_BIT = 0x00000004, + VK_SAMPLE_COUNT_8_BIT = 0x00000008, + VK_SAMPLE_COUNT_16_BIT = 0x00000010, + VK_SAMPLE_COUNT_32_BIT = 0x00000020, + VK_SAMPLE_COUNT_64_BIT = 0x00000040, + VK_SAMPLE_COUNT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkSampleCountFlagBits; +typedef VkFlags VkSampleCountFlags; + +typedef enum VkImageUsageFlagBits { + VK_IMAGE_USAGE_TRANSFER_SRC_BIT = 0x00000001, + VK_IMAGE_USAGE_TRANSFER_DST_BIT = 0x00000002, + VK_IMAGE_USAGE_SAMPLED_BIT = 0x00000004, + VK_IMAGE_USAGE_STORAGE_BIT = 0x00000008, + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT = 0x00000010, + VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT = 0x00000020, + VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT = 0x00000040, + VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT = 0x00000080, + VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR = 0x00000400, + VK_IMAGE_USAGE_VIDEO_DECODE_SRC_BIT_KHR = 0x00000800, + VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR = 0x00001000, + VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT = 0x00000200, + VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x00000100, + VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT = 0x00400000, + VK_IMAGE_USAGE_VIDEO_ENCODE_DST_BIT_KHR = 0x00002000, + VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR = 0x00004000, + VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR = 0x00008000, + VK_IMAGE_USAGE_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT = 0x00080000, + VK_IMAGE_USAGE_INVOCATION_MASK_BIT_HUAWEI = 0x00040000, + VK_IMAGE_USAGE_SAMPLE_WEIGHT_BIT_QCOM = 0x00100000, + VK_IMAGE_USAGE_SAMPLE_BLOCK_MATCH_BIT_QCOM = 0x00200000, + VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV = VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR, + VK_IMAGE_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkImageUsageFlagBits; +typedef VkFlags VkImageUsageFlags; + +typedef enum VkInstanceCreateFlagBits { + VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR = 0x00000001, + VK_INSTANCE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkInstanceCreateFlagBits; +typedef VkFlags VkInstanceCreateFlags; + +typedef enum VkMemoryHeapFlagBits { + VK_MEMORY_HEAP_DEVICE_LOCAL_BIT = 0x00000001, + VK_MEMORY_HEAP_MULTI_INSTANCE_BIT = 0x00000002, + VK_MEMORY_HEAP_MULTI_INSTANCE_BIT_KHR = VK_MEMORY_HEAP_MULTI_INSTANCE_BIT, + VK_MEMORY_HEAP_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkMemoryHeapFlagBits; +typedef VkFlags VkMemoryHeapFlags; + +typedef enum VkMemoryPropertyFlagBits { + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT = 0x00000001, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT = 0x00000002, + VK_MEMORY_PROPERTY_HOST_COHERENT_BIT = 0x00000004, + VK_MEMORY_PROPERTY_HOST_CACHED_BIT = 0x00000008, + VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT = 0x00000010, + VK_MEMORY_PROPERTY_PROTECTED_BIT = 0x00000020, + VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD = 0x00000040, + VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD = 0x00000080, + VK_MEMORY_PROPERTY_RDMA_CAPABLE_BIT_NV = 0x00000100, + VK_MEMORY_PROPERTY_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkMemoryPropertyFlagBits; +typedef VkFlags VkMemoryPropertyFlags; + +typedef enum VkQueueFlagBits { + VK_QUEUE_GRAPHICS_BIT = 0x00000001, + VK_QUEUE_COMPUTE_BIT = 0x00000002, + VK_QUEUE_TRANSFER_BIT = 0x00000004, + VK_QUEUE_SPARSE_BINDING_BIT = 0x00000008, + VK_QUEUE_PROTECTED_BIT = 0x00000010, + VK_QUEUE_VIDEO_DECODE_BIT_KHR = 0x00000020, + VK_QUEUE_VIDEO_ENCODE_BIT_KHR = 0x00000040, + VK_QUEUE_OPTICAL_FLOW_BIT_NV = 0x00000100, + VK_QUEUE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkQueueFlagBits; +typedef VkFlags VkQueueFlags; +typedef VkFlags VkDeviceCreateFlags; + +typedef enum VkDeviceQueueCreateFlagBits { + VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT = 0x00000001, + VK_DEVICE_QUEUE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkDeviceQueueCreateFlagBits; +typedef VkFlags VkDeviceQueueCreateFlags; + +typedef enum VkPipelineStageFlagBits { + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT = 0x00000001, + VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT = 0x00000002, + VK_PIPELINE_STAGE_VERTEX_INPUT_BIT = 0x00000004, + VK_PIPELINE_STAGE_VERTEX_SHADER_BIT = 0x00000008, + VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT = 0x00000010, + VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT = 0x00000020, + VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT = 0x00000040, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT = 0x00000080, + VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT = 0x00000100, + VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT = 0x00000200, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT = 0x00000400, + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT = 0x00000800, + VK_PIPELINE_STAGE_TRANSFER_BIT = 0x00001000, + VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT = 0x00002000, + VK_PIPELINE_STAGE_HOST_BIT = 0x00004000, + VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT = 0x00008000, + VK_PIPELINE_STAGE_ALL_COMMANDS_BIT = 0x00010000, + VK_PIPELINE_STAGE_NONE = 0, + VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT = 0x01000000, + VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT = 0x00040000, + VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR = 0x02000000, + VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR = 0x00200000, + VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT = 0x00800000, + VK_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x00400000, + VK_PIPELINE_STAGE_COMMAND_PREPROCESS_BIT_NV = 0x00020000, + VK_PIPELINE_STAGE_TASK_SHADER_BIT_EXT = 0x00080000, + VK_PIPELINE_STAGE_MESH_SHADER_BIT_EXT = 0x00100000, + VK_PIPELINE_STAGE_SHADING_RATE_IMAGE_BIT_NV = VK_PIPELINE_STAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR, + VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_NV = VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, + VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_NV = VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, + VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV = VK_PIPELINE_STAGE_TASK_SHADER_BIT_EXT, + VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV = VK_PIPELINE_STAGE_MESH_SHADER_BIT_EXT, + VK_PIPELINE_STAGE_NONE_KHR = VK_PIPELINE_STAGE_NONE, + VK_PIPELINE_STAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkPipelineStageFlagBits; +typedef VkFlags VkPipelineStageFlags; +typedef VkFlags VkMemoryMapFlags; + +typedef enum VkSparseMemoryBindFlagBits { + VK_SPARSE_MEMORY_BIND_METADATA_BIT = 0x00000001, + VK_SPARSE_MEMORY_BIND_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkSparseMemoryBindFlagBits; +typedef VkFlags VkSparseMemoryBindFlags; + +typedef enum VkSparseImageFormatFlagBits { + VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT = 0x00000001, + VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BIT = 0x00000002, + VK_SPARSE_IMAGE_FORMAT_NONSTANDARD_BLOCK_SIZE_BIT = 0x00000004, + VK_SPARSE_IMAGE_FORMAT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkSparseImageFormatFlagBits; +typedef VkFlags VkSparseImageFormatFlags; + +typedef enum VkFenceCreateFlagBits { + VK_FENCE_CREATE_SIGNALED_BIT = 0x00000001, + VK_FENCE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkFenceCreateFlagBits; +typedef VkFlags VkFenceCreateFlags; +typedef VkFlags VkSemaphoreCreateFlags; + +typedef enum VkEventCreateFlagBits { + VK_EVENT_CREATE_DEVICE_ONLY_BIT = 0x00000001, + VK_EVENT_CREATE_DEVICE_ONLY_BIT_KHR = VK_EVENT_CREATE_DEVICE_ONLY_BIT, + VK_EVENT_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkEventCreateFlagBits; +typedef VkFlags VkEventCreateFlags; + +typedef enum VkQueryPipelineStatisticFlagBits { + VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_VERTICES_BIT = 0x00000001, + VK_QUERY_PIPELINE_STATISTIC_INPUT_ASSEMBLY_PRIMITIVES_BIT = 0x00000002, + VK_QUERY_PIPELINE_STATISTIC_VERTEX_SHADER_INVOCATIONS_BIT = 0x00000004, + VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_INVOCATIONS_BIT = 0x00000008, + VK_QUERY_PIPELINE_STATISTIC_GEOMETRY_SHADER_PRIMITIVES_BIT = 0x00000010, + VK_QUERY_PIPELINE_STATISTIC_CLIPPING_INVOCATIONS_BIT = 0x00000020, + VK_QUERY_PIPELINE_STATISTIC_CLIPPING_PRIMITIVES_BIT = 0x00000040, + VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT = 0x00000080, + VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_CONTROL_SHADER_PATCHES_BIT = 0x00000100, + VK_QUERY_PIPELINE_STATISTIC_TESSELLATION_EVALUATION_SHADER_INVOCATIONS_BIT = 0x00000200, + VK_QUERY_PIPELINE_STATISTIC_COMPUTE_SHADER_INVOCATIONS_BIT = 0x00000400, + VK_QUERY_PIPELINE_STATISTIC_TASK_SHADER_INVOCATIONS_BIT_EXT = 0x00000800, + VK_QUERY_PIPELINE_STATISTIC_MESH_SHADER_INVOCATIONS_BIT_EXT = 0x00001000, + VK_QUERY_PIPELINE_STATISTIC_CLUSTER_CULLING_SHADER_INVOCATIONS_BIT_HUAWEI = 0x00002000, + VK_QUERY_PIPELINE_STATISTIC_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkQueryPipelineStatisticFlagBits; +typedef VkFlags VkQueryPipelineStatisticFlags; +typedef VkFlags VkQueryPoolCreateFlags; + +typedef enum VkQueryResultFlagBits { + VK_QUERY_RESULT_64_BIT = 0x00000001, + VK_QUERY_RESULT_WAIT_BIT = 0x00000002, + VK_QUERY_RESULT_WITH_AVAILABILITY_BIT = 0x00000004, + VK_QUERY_RESULT_PARTIAL_BIT = 0x00000008, + VK_QUERY_RESULT_WITH_STATUS_BIT_KHR = 0x00000010, + VK_QUERY_RESULT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkQueryResultFlagBits; +typedef VkFlags VkQueryResultFlags; + +typedef enum VkBufferCreateFlagBits { + VK_BUFFER_CREATE_SPARSE_BINDING_BIT = 0x00000001, + VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT = 0x00000002, + VK_BUFFER_CREATE_SPARSE_ALIASED_BIT = 0x00000004, + VK_BUFFER_CREATE_PROTECTED_BIT = 0x00000008, + VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT = 0x00000010, + VK_BUFFER_CREATE_DESCRIPTOR_BUFFER_CAPTURE_REPLAY_BIT_EXT = 0x00000020, + VK_BUFFER_CREATE_VIDEO_PROFILE_INDEPENDENT_BIT_KHR = 0x00000040, + VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_EXT = VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT, + VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR = VK_BUFFER_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT, + VK_BUFFER_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkBufferCreateFlagBits; +typedef VkFlags VkBufferCreateFlags; + +typedef enum VkBufferUsageFlagBits { + VK_BUFFER_USAGE_TRANSFER_SRC_BIT = 0x00000001, + VK_BUFFER_USAGE_TRANSFER_DST_BIT = 0x00000002, + VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT = 0x00000004, + VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT = 0x00000008, + VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT = 0x00000010, + VK_BUFFER_USAGE_STORAGE_BUFFER_BIT = 0x00000020, + VK_BUFFER_USAGE_INDEX_BUFFER_BIT = 0x00000040, + VK_BUFFER_USAGE_VERTEX_BUFFER_BIT = 0x00000080, + VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT = 0x00000100, + VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT = 0x00020000, + VK_BUFFER_USAGE_VIDEO_DECODE_SRC_BIT_KHR = 0x00002000, + VK_BUFFER_USAGE_VIDEO_DECODE_DST_BIT_KHR = 0x00004000, + VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT = 0x00000800, + VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT = 0x00001000, + VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT = 0x00000200, +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_BUFFER_USAGE_EXECUTION_GRAPH_SCRATCH_BIT_AMDX = 0x02000000, +#endif + VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR = 0x00080000, + VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR = 0x00100000, + VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR = 0x00000400, + VK_BUFFER_USAGE_VIDEO_ENCODE_DST_BIT_KHR = 0x00008000, + VK_BUFFER_USAGE_VIDEO_ENCODE_SRC_BIT_KHR = 0x00010000, + VK_BUFFER_USAGE_SAMPLER_DESCRIPTOR_BUFFER_BIT_EXT = 0x00200000, + VK_BUFFER_USAGE_RESOURCE_DESCRIPTOR_BUFFER_BIT_EXT = 0x00400000, + VK_BUFFER_USAGE_PUSH_DESCRIPTORS_DESCRIPTOR_BUFFER_BIT_EXT = 0x04000000, + VK_BUFFER_USAGE_MICROMAP_BUILD_INPUT_READ_ONLY_BIT_EXT = 0x00800000, + VK_BUFFER_USAGE_MICROMAP_STORAGE_BIT_EXT = 0x01000000, + VK_BUFFER_USAGE_RAY_TRACING_BIT_NV = VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR, + VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_EXT = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, + VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_KHR = VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, + VK_BUFFER_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkBufferUsageFlagBits; +typedef VkFlags VkBufferUsageFlags; +typedef VkFlags VkBufferViewCreateFlags; + +typedef enum VkImageViewCreateFlagBits { + VK_IMAGE_VIEW_CREATE_FRAGMENT_DENSITY_MAP_DYNAMIC_BIT_EXT = 0x00000001, + VK_IMAGE_VIEW_CREATE_DESCRIPTOR_BUFFER_CAPTURE_REPLAY_BIT_EXT = 0x00000004, + VK_IMAGE_VIEW_CREATE_FRAGMENT_DENSITY_MAP_DEFERRED_BIT_EXT = 0x00000002, + VK_IMAGE_VIEW_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkImageViewCreateFlagBits; +typedef VkFlags VkImageViewCreateFlags; +typedef VkFlags VkShaderModuleCreateFlags; + +typedef enum VkPipelineCacheCreateFlagBits { + VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT = 0x00000001, + VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT_EXT = VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT, + VK_PIPELINE_CACHE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkPipelineCacheCreateFlagBits; +typedef VkFlags VkPipelineCacheCreateFlags; + +typedef enum VkColorComponentFlagBits { + VK_COLOR_COMPONENT_R_BIT = 0x00000001, + VK_COLOR_COMPONENT_G_BIT = 0x00000002, + VK_COLOR_COMPONENT_B_BIT = 0x00000004, + VK_COLOR_COMPONENT_A_BIT = 0x00000008, + VK_COLOR_COMPONENT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkColorComponentFlagBits; +typedef VkFlags VkColorComponentFlags; + +typedef enum VkPipelineCreateFlagBits { + VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT = 0x00000001, + VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT = 0x00000002, + VK_PIPELINE_CREATE_DERIVATIVE_BIT = 0x00000004, + VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT = 0x00000008, + VK_PIPELINE_CREATE_DISPATCH_BASE_BIT = 0x00000010, + VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT = 0x00000100, + VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT = 0x00000200, + VK_PIPELINE_CREATE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x00200000, + VK_PIPELINE_CREATE_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT = 0x00400000, + VK_PIPELINE_CREATE_RAY_TRACING_NO_NULL_ANY_HIT_SHADERS_BIT_KHR = 0x00004000, + VK_PIPELINE_CREATE_RAY_TRACING_NO_NULL_CLOSEST_HIT_SHADERS_BIT_KHR = 0x00008000, + VK_PIPELINE_CREATE_RAY_TRACING_NO_NULL_MISS_SHADERS_BIT_KHR = 0x00010000, + VK_PIPELINE_CREATE_RAY_TRACING_NO_NULL_INTERSECTION_SHADERS_BIT_KHR = 0x00020000, + VK_PIPELINE_CREATE_RAY_TRACING_SKIP_TRIANGLES_BIT_KHR = 0x00001000, + VK_PIPELINE_CREATE_RAY_TRACING_SKIP_AABBS_BIT_KHR = 0x00002000, + VK_PIPELINE_CREATE_RAY_TRACING_SHADER_GROUP_HANDLE_CAPTURE_REPLAY_BIT_KHR = 0x00080000, + VK_PIPELINE_CREATE_DEFER_COMPILE_BIT_NV = 0x00000020, + VK_PIPELINE_CREATE_CAPTURE_STATISTICS_BIT_KHR = 0x00000040, + VK_PIPELINE_CREATE_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR = 0x00000080, + VK_PIPELINE_CREATE_INDIRECT_BINDABLE_BIT_NV = 0x00040000, + VK_PIPELINE_CREATE_LIBRARY_BIT_KHR = 0x00000800, + VK_PIPELINE_CREATE_DESCRIPTOR_BUFFER_BIT_EXT = 0x20000000, + VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT = 0x00800000, + VK_PIPELINE_CREATE_LINK_TIME_OPTIMIZATION_BIT_EXT = 0x00000400, + VK_PIPELINE_CREATE_RAY_TRACING_ALLOW_MOTION_BIT_NV = 0x00100000, + VK_PIPELINE_CREATE_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT = 0x02000000, + VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT = 0x04000000, + VK_PIPELINE_CREATE_RAY_TRACING_OPACITY_MICROMAP_BIT_EXT = 0x01000000, +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_PIPELINE_CREATE_RAY_TRACING_DISPLACEMENT_MICROMAP_BIT_NV = 0x10000000, +#endif + VK_PIPELINE_CREATE_NO_PROTECTED_ACCESS_BIT_EXT = 0x08000000, + VK_PIPELINE_CREATE_PROTECTED_ACCESS_ONLY_BIT_EXT = 0x40000000, + VK_PIPELINE_CREATE_DISPATCH_BASE = VK_PIPELINE_CREATE_DISPATCH_BASE_BIT, + VK_PIPELINE_RASTERIZATION_STATE_CREATE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = VK_PIPELINE_CREATE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR, + VK_PIPELINE_RASTERIZATION_STATE_CREATE_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT = VK_PIPELINE_CREATE_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT, + VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT_KHR = VK_PIPELINE_CREATE_VIEW_INDEX_FROM_DEVICE_INDEX_BIT, + VK_PIPELINE_CREATE_DISPATCH_BASE_KHR = VK_PIPELINE_CREATE_DISPATCH_BASE, + VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_EXT = VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT, + VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT_EXT = VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT, + VK_PIPELINE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkPipelineCreateFlagBits; +typedef VkFlags VkPipelineCreateFlags; + +typedef enum VkPipelineShaderStageCreateFlagBits { + VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT = 0x00000001, + VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT = 0x00000002, + VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT_EXT = VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT, + VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT_EXT = VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT, + VK_PIPELINE_SHADER_STAGE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkPipelineShaderStageCreateFlagBits; +typedef VkFlags VkPipelineShaderStageCreateFlags; + +typedef enum VkShaderStageFlagBits { + VK_SHADER_STAGE_VERTEX_BIT = 0x00000001, + VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT = 0x00000002, + VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT = 0x00000004, + VK_SHADER_STAGE_GEOMETRY_BIT = 0x00000008, + VK_SHADER_STAGE_FRAGMENT_BIT = 0x00000010, + VK_SHADER_STAGE_COMPUTE_BIT = 0x00000020, + VK_SHADER_STAGE_ALL_GRAPHICS = 0x0000001F, + VK_SHADER_STAGE_ALL = 0x7FFFFFFF, + VK_SHADER_STAGE_RAYGEN_BIT_KHR = 0x00000100, + VK_SHADER_STAGE_ANY_HIT_BIT_KHR = 0x00000200, + VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR = 0x00000400, + VK_SHADER_STAGE_MISS_BIT_KHR = 0x00000800, + VK_SHADER_STAGE_INTERSECTION_BIT_KHR = 0x00001000, + VK_SHADER_STAGE_CALLABLE_BIT_KHR = 0x00002000, + VK_SHADER_STAGE_TASK_BIT_EXT = 0x00000040, + VK_SHADER_STAGE_MESH_BIT_EXT = 0x00000080, + VK_SHADER_STAGE_SUBPASS_SHADING_BIT_HUAWEI = 0x00004000, + VK_SHADER_STAGE_CLUSTER_CULLING_BIT_HUAWEI = 0x00080000, + VK_SHADER_STAGE_RAYGEN_BIT_NV = VK_SHADER_STAGE_RAYGEN_BIT_KHR, + VK_SHADER_STAGE_ANY_HIT_BIT_NV = VK_SHADER_STAGE_ANY_HIT_BIT_KHR, + VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV = VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, + VK_SHADER_STAGE_MISS_BIT_NV = VK_SHADER_STAGE_MISS_BIT_KHR, + VK_SHADER_STAGE_INTERSECTION_BIT_NV = VK_SHADER_STAGE_INTERSECTION_BIT_KHR, + VK_SHADER_STAGE_CALLABLE_BIT_NV = VK_SHADER_STAGE_CALLABLE_BIT_KHR, + VK_SHADER_STAGE_TASK_BIT_NV = VK_SHADER_STAGE_TASK_BIT_EXT, + VK_SHADER_STAGE_MESH_BIT_NV = VK_SHADER_STAGE_MESH_BIT_EXT, + VK_SHADER_STAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkShaderStageFlagBits; + +typedef enum VkCullModeFlagBits { + VK_CULL_MODE_NONE = 0, + VK_CULL_MODE_FRONT_BIT = 0x00000001, + VK_CULL_MODE_BACK_BIT = 0x00000002, + VK_CULL_MODE_FRONT_AND_BACK = 0x00000003, + VK_CULL_MODE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkCullModeFlagBits; +typedef VkFlags VkCullModeFlags; +typedef VkFlags VkPipelineVertexInputStateCreateFlags; +typedef VkFlags VkPipelineInputAssemblyStateCreateFlags; +typedef VkFlags VkPipelineTessellationStateCreateFlags; +typedef VkFlags VkPipelineViewportStateCreateFlags; +typedef VkFlags VkPipelineRasterizationStateCreateFlags; +typedef VkFlags VkPipelineMultisampleStateCreateFlags; + +typedef enum VkPipelineDepthStencilStateCreateFlagBits { + VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_EXT = 0x00000001, + VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_EXT = 0x00000002, + VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_ARM = VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_EXT, + VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_ARM = VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_EXT, + VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkPipelineDepthStencilStateCreateFlagBits; +typedef VkFlags VkPipelineDepthStencilStateCreateFlags; + +typedef enum VkPipelineColorBlendStateCreateFlagBits { + VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_EXT = 0x00000001, + VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_ARM = VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_EXT, + VK_PIPELINE_COLOR_BLEND_STATE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkPipelineColorBlendStateCreateFlagBits; +typedef VkFlags VkPipelineColorBlendStateCreateFlags; +typedef VkFlags VkPipelineDynamicStateCreateFlags; + +typedef enum VkPipelineLayoutCreateFlagBits { + VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT = 0x00000002, + VK_PIPELINE_LAYOUT_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkPipelineLayoutCreateFlagBits; +typedef VkFlags VkPipelineLayoutCreateFlags; +typedef VkFlags VkShaderStageFlags; + +typedef enum VkSamplerCreateFlagBits { + VK_SAMPLER_CREATE_SUBSAMPLED_BIT_EXT = 0x00000001, + VK_SAMPLER_CREATE_SUBSAMPLED_COARSE_RECONSTRUCTION_BIT_EXT = 0x00000002, + VK_SAMPLER_CREATE_DESCRIPTOR_BUFFER_CAPTURE_REPLAY_BIT_EXT = 0x00000008, + VK_SAMPLER_CREATE_NON_SEAMLESS_CUBE_MAP_BIT_EXT = 0x00000004, + VK_SAMPLER_CREATE_IMAGE_PROCESSING_BIT_QCOM = 0x00000010, + VK_SAMPLER_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkSamplerCreateFlagBits; +typedef VkFlags VkSamplerCreateFlags; + +typedef enum VkDescriptorPoolCreateFlagBits { + VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT = 0x00000001, + VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT = 0x00000002, + VK_DESCRIPTOR_POOL_CREATE_HOST_ONLY_BIT_EXT = 0x00000004, + VK_DESCRIPTOR_POOL_CREATE_ALLOW_OVERALLOCATION_SETS_BIT_NV = 0x00000008, + VK_DESCRIPTOR_POOL_CREATE_ALLOW_OVERALLOCATION_POOLS_BIT_NV = 0x00000010, + VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT, + VK_DESCRIPTOR_POOL_CREATE_HOST_ONLY_BIT_VALVE = VK_DESCRIPTOR_POOL_CREATE_HOST_ONLY_BIT_EXT, + VK_DESCRIPTOR_POOL_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkDescriptorPoolCreateFlagBits; +typedef VkFlags VkDescriptorPoolCreateFlags; +typedef VkFlags VkDescriptorPoolResetFlags; + +typedef enum VkDescriptorSetLayoutCreateFlagBits { + VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT = 0x00000002, + VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR = 0x00000001, + VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT = 0x00000010, + VK_DESCRIPTOR_SET_LAYOUT_CREATE_EMBEDDED_IMMUTABLE_SAMPLERS_BIT_EXT = 0x00000020, + VK_DESCRIPTOR_SET_LAYOUT_CREATE_INDIRECT_BINDABLE_BIT_NV = 0x00000080, + VK_DESCRIPTOR_SET_LAYOUT_CREATE_HOST_ONLY_POOL_BIT_EXT = 0x00000004, + VK_DESCRIPTOR_SET_LAYOUT_CREATE_PER_STAGE_BIT_NV = 0x00000040, + VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT, + VK_DESCRIPTOR_SET_LAYOUT_CREATE_HOST_ONLY_POOL_BIT_VALVE = VK_DESCRIPTOR_SET_LAYOUT_CREATE_HOST_ONLY_POOL_BIT_EXT, + VK_DESCRIPTOR_SET_LAYOUT_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkDescriptorSetLayoutCreateFlagBits; +typedef VkFlags VkDescriptorSetLayoutCreateFlags; + +typedef enum VkAttachmentDescriptionFlagBits { + VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT = 0x00000001, + VK_ATTACHMENT_DESCRIPTION_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkAttachmentDescriptionFlagBits; +typedef VkFlags VkAttachmentDescriptionFlags; + +typedef enum VkDependencyFlagBits { + VK_DEPENDENCY_BY_REGION_BIT = 0x00000001, + VK_DEPENDENCY_DEVICE_GROUP_BIT = 0x00000004, + VK_DEPENDENCY_VIEW_LOCAL_BIT = 0x00000002, + VK_DEPENDENCY_FEEDBACK_LOOP_BIT_EXT = 0x00000008, + VK_DEPENDENCY_VIEW_LOCAL_BIT_KHR = VK_DEPENDENCY_VIEW_LOCAL_BIT, + VK_DEPENDENCY_DEVICE_GROUP_BIT_KHR = VK_DEPENDENCY_DEVICE_GROUP_BIT, + VK_DEPENDENCY_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkDependencyFlagBits; +typedef VkFlags VkDependencyFlags; + +typedef enum VkFramebufferCreateFlagBits { + VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT = 0x00000001, + VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR = VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT, + VK_FRAMEBUFFER_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkFramebufferCreateFlagBits; +typedef VkFlags VkFramebufferCreateFlags; + +typedef enum VkRenderPassCreateFlagBits { + VK_RENDER_PASS_CREATE_TRANSFORM_BIT_QCOM = 0x00000002, + VK_RENDER_PASS_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkRenderPassCreateFlagBits; +typedef VkFlags VkRenderPassCreateFlags; + +typedef enum VkSubpassDescriptionFlagBits { + VK_SUBPASS_DESCRIPTION_PER_VIEW_ATTRIBUTES_BIT_NVX = 0x00000001, + VK_SUBPASS_DESCRIPTION_PER_VIEW_POSITION_X_ONLY_BIT_NVX = 0x00000002, + VK_SUBPASS_DESCRIPTION_FRAGMENT_REGION_BIT_QCOM = 0x00000004, + VK_SUBPASS_DESCRIPTION_SHADER_RESOLVE_BIT_QCOM = 0x00000008, + VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_COLOR_ACCESS_BIT_EXT = 0x00000010, + VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_EXT = 0x00000020, + VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_EXT = 0x00000040, + VK_SUBPASS_DESCRIPTION_ENABLE_LEGACY_DITHERING_BIT_EXT = 0x00000080, + VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_COLOR_ACCESS_BIT_ARM = VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_COLOR_ACCESS_BIT_EXT, + VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_ARM = VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_EXT, + VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_ARM = VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_EXT, + VK_SUBPASS_DESCRIPTION_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkSubpassDescriptionFlagBits; +typedef VkFlags VkSubpassDescriptionFlags; + +typedef enum VkCommandPoolCreateFlagBits { + VK_COMMAND_POOL_CREATE_TRANSIENT_BIT = 0x00000001, + VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT = 0x00000002, + VK_COMMAND_POOL_CREATE_PROTECTED_BIT = 0x00000004, + VK_COMMAND_POOL_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkCommandPoolCreateFlagBits; +typedef VkFlags VkCommandPoolCreateFlags; + +typedef enum VkCommandPoolResetFlagBits { + VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT = 0x00000001, + VK_COMMAND_POOL_RESET_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkCommandPoolResetFlagBits; +typedef VkFlags VkCommandPoolResetFlags; + +typedef enum VkCommandBufferUsageFlagBits { + VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT = 0x00000001, + VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT = 0x00000002, + VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT = 0x00000004, + VK_COMMAND_BUFFER_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkCommandBufferUsageFlagBits; +typedef VkFlags VkCommandBufferUsageFlags; + +typedef enum VkQueryControlFlagBits { + VK_QUERY_CONTROL_PRECISE_BIT = 0x00000001, + VK_QUERY_CONTROL_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkQueryControlFlagBits; +typedef VkFlags VkQueryControlFlags; + +typedef enum VkCommandBufferResetFlagBits { + VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT = 0x00000001, + VK_COMMAND_BUFFER_RESET_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkCommandBufferResetFlagBits; +typedef VkFlags VkCommandBufferResetFlags; + +typedef enum VkStencilFaceFlagBits { + VK_STENCIL_FACE_FRONT_BIT = 0x00000001, + VK_STENCIL_FACE_BACK_BIT = 0x00000002, + VK_STENCIL_FACE_FRONT_AND_BACK = 0x00000003, + VK_STENCIL_FRONT_AND_BACK = VK_STENCIL_FACE_FRONT_AND_BACK, + VK_STENCIL_FACE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkStencilFaceFlagBits; +typedef VkFlags VkStencilFaceFlags; +typedef struct VkExtent2D { + uint32_t width; + uint32_t height; +} VkExtent2D; + +typedef struct VkExtent3D { + uint32_t width; + uint32_t height; + uint32_t depth; +} VkExtent3D; + +typedef struct VkOffset2D { + int32_t x; + int32_t y; +} VkOffset2D; + +typedef struct VkOffset3D { + int32_t x; + int32_t y; + int32_t z; +} VkOffset3D; + +typedef struct VkRect2D { + VkOffset2D offset; + VkExtent2D extent; +} VkRect2D; + +typedef struct VkBaseInStructure { + VkStructureType sType; + const struct VkBaseInStructure* pNext; +} VkBaseInStructure; + +typedef struct VkBaseOutStructure { + VkStructureType sType; + struct VkBaseOutStructure* pNext; +} VkBaseOutStructure; + +typedef struct VkBufferMemoryBarrier { + VkStructureType sType; + const void* pNext; + VkAccessFlags srcAccessMask; + VkAccessFlags dstAccessMask; + uint32_t srcQueueFamilyIndex; + uint32_t dstQueueFamilyIndex; + VkBuffer buffer; + VkDeviceSize offset; + VkDeviceSize size; +} VkBufferMemoryBarrier; + +typedef struct VkDispatchIndirectCommand { + uint32_t x; + uint32_t y; + uint32_t z; +} VkDispatchIndirectCommand; + +typedef struct VkDrawIndexedIndirectCommand { + uint32_t indexCount; + uint32_t instanceCount; + uint32_t firstIndex; + int32_t vertexOffset; + uint32_t firstInstance; +} VkDrawIndexedIndirectCommand; + +typedef struct VkDrawIndirectCommand { + uint32_t vertexCount; + uint32_t instanceCount; + uint32_t firstVertex; + uint32_t firstInstance; +} VkDrawIndirectCommand; + +typedef struct VkImageSubresourceRange { + VkImageAspectFlags aspectMask; + uint32_t baseMipLevel; + uint32_t levelCount; + uint32_t baseArrayLayer; + uint32_t layerCount; +} VkImageSubresourceRange; + +typedef struct VkImageMemoryBarrier { + VkStructureType sType; + const void* pNext; + VkAccessFlags srcAccessMask; + VkAccessFlags dstAccessMask; + VkImageLayout oldLayout; + VkImageLayout newLayout; + uint32_t srcQueueFamilyIndex; + uint32_t dstQueueFamilyIndex; + VkImage image; + VkImageSubresourceRange subresourceRange; +} VkImageMemoryBarrier; + +typedef struct VkMemoryBarrier { + VkStructureType sType; + const void* pNext; + VkAccessFlags srcAccessMask; + VkAccessFlags dstAccessMask; +} VkMemoryBarrier; + +typedef struct VkPipelineCacheHeaderVersionOne { + uint32_t headerSize; + VkPipelineCacheHeaderVersion headerVersion; + uint32_t vendorID; + uint32_t deviceID; + uint8_t pipelineCacheUUID[VK_UUID_SIZE]; +} VkPipelineCacheHeaderVersionOne; + +typedef void* (VKAPI_PTR *PFN_vkAllocationFunction)( + void* pUserData, + size_t size, + size_t alignment, + VkSystemAllocationScope allocationScope); + +typedef void (VKAPI_PTR *PFN_vkFreeFunction)( + void* pUserData, + void* pMemory); + +typedef void (VKAPI_PTR *PFN_vkInternalAllocationNotification)( + void* pUserData, + size_t size, + VkInternalAllocationType allocationType, + VkSystemAllocationScope allocationScope); + +typedef void (VKAPI_PTR *PFN_vkInternalFreeNotification)( + void* pUserData, + size_t size, + VkInternalAllocationType allocationType, + VkSystemAllocationScope allocationScope); + +typedef void* (VKAPI_PTR *PFN_vkReallocationFunction)( + void* pUserData, + void* pOriginal, + size_t size, + size_t alignment, + VkSystemAllocationScope allocationScope); + +typedef void (VKAPI_PTR *PFN_vkVoidFunction)(void); +typedef struct VkAllocationCallbacks { + void* pUserData; + PFN_vkAllocationFunction pfnAllocation; + PFN_vkReallocationFunction pfnReallocation; + PFN_vkFreeFunction pfnFree; + PFN_vkInternalAllocationNotification pfnInternalAllocation; + PFN_vkInternalFreeNotification pfnInternalFree; +} VkAllocationCallbacks; + +typedef struct VkApplicationInfo { + VkStructureType sType; + const void* pNext; + const char* pApplicationName; + uint32_t applicationVersion; + const char* pEngineName; + uint32_t engineVersion; + uint32_t apiVersion; +} VkApplicationInfo; + +typedef struct VkFormatProperties { + VkFormatFeatureFlags linearTilingFeatures; + VkFormatFeatureFlags optimalTilingFeatures; + VkFormatFeatureFlags bufferFeatures; +} VkFormatProperties; + +typedef struct VkImageFormatProperties { + VkExtent3D maxExtent; + uint32_t maxMipLevels; + uint32_t maxArrayLayers; + VkSampleCountFlags sampleCounts; + VkDeviceSize maxResourceSize; +} VkImageFormatProperties; + +typedef struct VkInstanceCreateInfo { + VkStructureType sType; + const void* pNext; + VkInstanceCreateFlags flags; + const VkApplicationInfo* pApplicationInfo; + uint32_t enabledLayerCount; + const char* const* ppEnabledLayerNames; + uint32_t enabledExtensionCount; + const char* const* ppEnabledExtensionNames; +} VkInstanceCreateInfo; + +typedef struct VkMemoryHeap { + VkDeviceSize size; + VkMemoryHeapFlags flags; +} VkMemoryHeap; + +typedef struct VkMemoryType { + VkMemoryPropertyFlags propertyFlags; + uint32_t heapIndex; +} VkMemoryType; + +typedef struct VkPhysicalDeviceFeatures { + VkBool32 robustBufferAccess; + VkBool32 fullDrawIndexUint32; + VkBool32 imageCubeArray; + VkBool32 independentBlend; + VkBool32 geometryShader; + VkBool32 tessellationShader; + VkBool32 sampleRateShading; + VkBool32 dualSrcBlend; + VkBool32 logicOp; + VkBool32 multiDrawIndirect; + VkBool32 drawIndirectFirstInstance; + VkBool32 depthClamp; + VkBool32 depthBiasClamp; + VkBool32 fillModeNonSolid; + VkBool32 depthBounds; + VkBool32 wideLines; + VkBool32 largePoints; + VkBool32 alphaToOne; + VkBool32 multiViewport; + VkBool32 samplerAnisotropy; + VkBool32 textureCompressionETC2; + VkBool32 textureCompressionASTC_LDR; + VkBool32 textureCompressionBC; + VkBool32 occlusionQueryPrecise; + VkBool32 pipelineStatisticsQuery; + VkBool32 vertexPipelineStoresAndAtomics; + VkBool32 fragmentStoresAndAtomics; + VkBool32 shaderTessellationAndGeometryPointSize; + VkBool32 shaderImageGatherExtended; + VkBool32 shaderStorageImageExtendedFormats; + VkBool32 shaderStorageImageMultisample; + VkBool32 shaderStorageImageReadWithoutFormat; + VkBool32 shaderStorageImageWriteWithoutFormat; + VkBool32 shaderUniformBufferArrayDynamicIndexing; + VkBool32 shaderSampledImageArrayDynamicIndexing; + VkBool32 shaderStorageBufferArrayDynamicIndexing; + VkBool32 shaderStorageImageArrayDynamicIndexing; + VkBool32 shaderClipDistance; + VkBool32 shaderCullDistance; + VkBool32 shaderFloat64; + VkBool32 shaderInt64; + VkBool32 shaderInt16; + VkBool32 shaderResourceResidency; + VkBool32 shaderResourceMinLod; + VkBool32 sparseBinding; + VkBool32 sparseResidencyBuffer; + VkBool32 sparseResidencyImage2D; + VkBool32 sparseResidencyImage3D; + VkBool32 sparseResidency2Samples; + VkBool32 sparseResidency4Samples; + VkBool32 sparseResidency8Samples; + VkBool32 sparseResidency16Samples; + VkBool32 sparseResidencyAliased; + VkBool32 variableMultisampleRate; + VkBool32 inheritedQueries; +} VkPhysicalDeviceFeatures; + +typedef struct VkPhysicalDeviceLimits { + uint32_t maxImageDimension1D; + uint32_t maxImageDimension2D; + uint32_t maxImageDimension3D; + uint32_t maxImageDimensionCube; + uint32_t maxImageArrayLayers; + uint32_t maxTexelBufferElements; + uint32_t maxUniformBufferRange; + uint32_t maxStorageBufferRange; + uint32_t maxPushConstantsSize; + uint32_t maxMemoryAllocationCount; + uint32_t maxSamplerAllocationCount; + VkDeviceSize bufferImageGranularity; + VkDeviceSize sparseAddressSpaceSize; + uint32_t maxBoundDescriptorSets; + uint32_t maxPerStageDescriptorSamplers; + uint32_t maxPerStageDescriptorUniformBuffers; + uint32_t maxPerStageDescriptorStorageBuffers; + uint32_t maxPerStageDescriptorSampledImages; + uint32_t maxPerStageDescriptorStorageImages; + uint32_t maxPerStageDescriptorInputAttachments; + uint32_t maxPerStageResources; + uint32_t maxDescriptorSetSamplers; + uint32_t maxDescriptorSetUniformBuffers; + uint32_t maxDescriptorSetUniformBuffersDynamic; + uint32_t maxDescriptorSetStorageBuffers; + uint32_t maxDescriptorSetStorageBuffersDynamic; + uint32_t maxDescriptorSetSampledImages; + uint32_t maxDescriptorSetStorageImages; + uint32_t maxDescriptorSetInputAttachments; + uint32_t maxVertexInputAttributes; + uint32_t maxVertexInputBindings; + uint32_t maxVertexInputAttributeOffset; + uint32_t maxVertexInputBindingStride; + uint32_t maxVertexOutputComponents; + uint32_t maxTessellationGenerationLevel; + uint32_t maxTessellationPatchSize; + uint32_t maxTessellationControlPerVertexInputComponents; + uint32_t maxTessellationControlPerVertexOutputComponents; + uint32_t maxTessellationControlPerPatchOutputComponents; + uint32_t maxTessellationControlTotalOutputComponents; + uint32_t maxTessellationEvaluationInputComponents; + uint32_t maxTessellationEvaluationOutputComponents; + uint32_t maxGeometryShaderInvocations; + uint32_t maxGeometryInputComponents; + uint32_t maxGeometryOutputComponents; + uint32_t maxGeometryOutputVertices; + uint32_t maxGeometryTotalOutputComponents; + uint32_t maxFragmentInputComponents; + uint32_t maxFragmentOutputAttachments; + uint32_t maxFragmentDualSrcAttachments; + uint32_t maxFragmentCombinedOutputResources; + uint32_t maxComputeSharedMemorySize; + uint32_t maxComputeWorkGroupCount[3]; + uint32_t maxComputeWorkGroupInvocations; + uint32_t maxComputeWorkGroupSize[3]; + uint32_t subPixelPrecisionBits; + uint32_t subTexelPrecisionBits; + uint32_t mipmapPrecisionBits; + uint32_t maxDrawIndexedIndexValue; + uint32_t maxDrawIndirectCount; + float maxSamplerLodBias; + float maxSamplerAnisotropy; + uint32_t maxViewports; + uint32_t maxViewportDimensions[2]; + float viewportBoundsRange[2]; + uint32_t viewportSubPixelBits; + size_t minMemoryMapAlignment; + VkDeviceSize minTexelBufferOffsetAlignment; + VkDeviceSize minUniformBufferOffsetAlignment; + VkDeviceSize minStorageBufferOffsetAlignment; + int32_t minTexelOffset; + uint32_t maxTexelOffset; + int32_t minTexelGatherOffset; + uint32_t maxTexelGatherOffset; + float minInterpolationOffset; + float maxInterpolationOffset; + uint32_t subPixelInterpolationOffsetBits; + uint32_t maxFramebufferWidth; + uint32_t maxFramebufferHeight; + uint32_t maxFramebufferLayers; + VkSampleCountFlags framebufferColorSampleCounts; + VkSampleCountFlags framebufferDepthSampleCounts; + VkSampleCountFlags framebufferStencilSampleCounts; + VkSampleCountFlags framebufferNoAttachmentsSampleCounts; + uint32_t maxColorAttachments; + VkSampleCountFlags sampledImageColorSampleCounts; + VkSampleCountFlags sampledImageIntegerSampleCounts; + VkSampleCountFlags sampledImageDepthSampleCounts; + VkSampleCountFlags sampledImageStencilSampleCounts; + VkSampleCountFlags storageImageSampleCounts; + uint32_t maxSampleMaskWords; + VkBool32 timestampComputeAndGraphics; + float timestampPeriod; + uint32_t maxClipDistances; + uint32_t maxCullDistances; + uint32_t maxCombinedClipAndCullDistances; + uint32_t discreteQueuePriorities; + float pointSizeRange[2]; + float lineWidthRange[2]; + float pointSizeGranularity; + float lineWidthGranularity; + VkBool32 strictLines; + VkBool32 standardSampleLocations; + VkDeviceSize optimalBufferCopyOffsetAlignment; + VkDeviceSize optimalBufferCopyRowPitchAlignment; + VkDeviceSize nonCoherentAtomSize; +} VkPhysicalDeviceLimits; + +typedef struct VkPhysicalDeviceMemoryProperties { + uint32_t memoryTypeCount; + VkMemoryType memoryTypes[VK_MAX_MEMORY_TYPES]; + uint32_t memoryHeapCount; + VkMemoryHeap memoryHeaps[VK_MAX_MEMORY_HEAPS]; +} VkPhysicalDeviceMemoryProperties; + +typedef struct VkPhysicalDeviceSparseProperties { + VkBool32 residencyStandard2DBlockShape; + VkBool32 residencyStandard2DMultisampleBlockShape; + VkBool32 residencyStandard3DBlockShape; + VkBool32 residencyAlignedMipSize; + VkBool32 residencyNonResidentStrict; +} VkPhysicalDeviceSparseProperties; + +typedef struct VkPhysicalDeviceProperties { + uint32_t apiVersion; + uint32_t driverVersion; + uint32_t vendorID; + uint32_t deviceID; + VkPhysicalDeviceType deviceType; + char deviceName[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE]; + uint8_t pipelineCacheUUID[VK_UUID_SIZE]; + VkPhysicalDeviceLimits limits; + VkPhysicalDeviceSparseProperties sparseProperties; +} VkPhysicalDeviceProperties; + +typedef struct VkQueueFamilyProperties { + VkQueueFlags queueFlags; + uint32_t queueCount; + uint32_t timestampValidBits; + VkExtent3D minImageTransferGranularity; +} VkQueueFamilyProperties; + +typedef struct VkDeviceQueueCreateInfo { + VkStructureType sType; + const void* pNext; + VkDeviceQueueCreateFlags flags; + uint32_t queueFamilyIndex; + uint32_t queueCount; + const float* pQueuePriorities; +} VkDeviceQueueCreateInfo; + +typedef struct VkDeviceCreateInfo { + VkStructureType sType; + const void* pNext; + VkDeviceCreateFlags flags; + uint32_t queueCreateInfoCount; + const VkDeviceQueueCreateInfo* pQueueCreateInfos; + uint32_t enabledLayerCount; + const char* const* ppEnabledLayerNames; + uint32_t enabledExtensionCount; + const char* const* ppEnabledExtensionNames; + const VkPhysicalDeviceFeatures* pEnabledFeatures; +} VkDeviceCreateInfo; + +typedef struct VkExtensionProperties { + char extensionName[VK_MAX_EXTENSION_NAME_SIZE]; + uint32_t specVersion; +} VkExtensionProperties; + +typedef struct VkLayerProperties { + char layerName[VK_MAX_EXTENSION_NAME_SIZE]; + uint32_t specVersion; + uint32_t implementationVersion; + char description[VK_MAX_DESCRIPTION_SIZE]; +} VkLayerProperties; + +typedef struct VkSubmitInfo { + VkStructureType sType; + const void* pNext; + uint32_t waitSemaphoreCount; + const VkSemaphore* pWaitSemaphores; + const VkPipelineStageFlags* pWaitDstStageMask; + uint32_t commandBufferCount; + const VkCommandBuffer* pCommandBuffers; + uint32_t signalSemaphoreCount; + const VkSemaphore* pSignalSemaphores; +} VkSubmitInfo; + +typedef struct VkMappedMemoryRange { + VkStructureType sType; + const void* pNext; + VkDeviceMemory memory; + VkDeviceSize offset; + VkDeviceSize size; +} VkMappedMemoryRange; + +typedef struct VkMemoryAllocateInfo { + VkStructureType sType; + const void* pNext; + VkDeviceSize allocationSize; + uint32_t memoryTypeIndex; +} VkMemoryAllocateInfo; + +typedef struct VkMemoryRequirements { + VkDeviceSize size; + VkDeviceSize alignment; + uint32_t memoryTypeBits; +} VkMemoryRequirements; + +typedef struct VkSparseMemoryBind { + VkDeviceSize resourceOffset; + VkDeviceSize size; + VkDeviceMemory memory; + VkDeviceSize memoryOffset; + VkSparseMemoryBindFlags flags; +} VkSparseMemoryBind; + +typedef struct VkSparseBufferMemoryBindInfo { + VkBuffer buffer; + uint32_t bindCount; + const VkSparseMemoryBind* pBinds; +} VkSparseBufferMemoryBindInfo; + +typedef struct VkSparseImageOpaqueMemoryBindInfo { + VkImage image; + uint32_t bindCount; + const VkSparseMemoryBind* pBinds; +} VkSparseImageOpaqueMemoryBindInfo; + +typedef struct VkImageSubresource { + VkImageAspectFlags aspectMask; + uint32_t mipLevel; + uint32_t arrayLayer; +} VkImageSubresource; + +typedef struct VkSparseImageMemoryBind { + VkImageSubresource subresource; + VkOffset3D offset; + VkExtent3D extent; + VkDeviceMemory memory; + VkDeviceSize memoryOffset; + VkSparseMemoryBindFlags flags; +} VkSparseImageMemoryBind; + +typedef struct VkSparseImageMemoryBindInfo { + VkImage image; + uint32_t bindCount; + const VkSparseImageMemoryBind* pBinds; +} VkSparseImageMemoryBindInfo; + +typedef struct VkBindSparseInfo { + VkStructureType sType; + const void* pNext; + uint32_t waitSemaphoreCount; + const VkSemaphore* pWaitSemaphores; + uint32_t bufferBindCount; + const VkSparseBufferMemoryBindInfo* pBufferBinds; + uint32_t imageOpaqueBindCount; + const VkSparseImageOpaqueMemoryBindInfo* pImageOpaqueBinds; + uint32_t imageBindCount; + const VkSparseImageMemoryBindInfo* pImageBinds; + uint32_t signalSemaphoreCount; + const VkSemaphore* pSignalSemaphores; +} VkBindSparseInfo; + +typedef struct VkSparseImageFormatProperties { + VkImageAspectFlags aspectMask; + VkExtent3D imageGranularity; + VkSparseImageFormatFlags flags; +} VkSparseImageFormatProperties; + +typedef struct VkSparseImageMemoryRequirements { + VkSparseImageFormatProperties formatProperties; + uint32_t imageMipTailFirstLod; + VkDeviceSize imageMipTailSize; + VkDeviceSize imageMipTailOffset; + VkDeviceSize imageMipTailStride; +} VkSparseImageMemoryRequirements; + +typedef struct VkFenceCreateInfo { + VkStructureType sType; + const void* pNext; + VkFenceCreateFlags flags; +} VkFenceCreateInfo; + +typedef struct VkSemaphoreCreateInfo { + VkStructureType sType; + const void* pNext; + VkSemaphoreCreateFlags flags; +} VkSemaphoreCreateInfo; + +typedef struct VkEventCreateInfo { + VkStructureType sType; + const void* pNext; + VkEventCreateFlags flags; +} VkEventCreateInfo; + +typedef struct VkQueryPoolCreateInfo { + VkStructureType sType; + const void* pNext; + VkQueryPoolCreateFlags flags; + VkQueryType queryType; + uint32_t queryCount; + VkQueryPipelineStatisticFlags pipelineStatistics; +} VkQueryPoolCreateInfo; + +typedef struct VkBufferCreateInfo { + VkStructureType sType; + const void* pNext; + VkBufferCreateFlags flags; + VkDeviceSize size; + VkBufferUsageFlags usage; + VkSharingMode sharingMode; + uint32_t queueFamilyIndexCount; + const uint32_t* pQueueFamilyIndices; +} VkBufferCreateInfo; + +typedef struct VkBufferViewCreateInfo { + VkStructureType sType; + const void* pNext; + VkBufferViewCreateFlags flags; + VkBuffer buffer; + VkFormat format; + VkDeviceSize offset; + VkDeviceSize range; +} VkBufferViewCreateInfo; + +typedef struct VkImageCreateInfo { + VkStructureType sType; + const void* pNext; + VkImageCreateFlags flags; + VkImageType imageType; + VkFormat format; + VkExtent3D extent; + uint32_t mipLevels; + uint32_t arrayLayers; + VkSampleCountFlagBits samples; + VkImageTiling tiling; + VkImageUsageFlags usage; + VkSharingMode sharingMode; + uint32_t queueFamilyIndexCount; + const uint32_t* pQueueFamilyIndices; + VkImageLayout initialLayout; +} VkImageCreateInfo; + +typedef struct VkSubresourceLayout { + VkDeviceSize offset; + VkDeviceSize size; + VkDeviceSize rowPitch; + VkDeviceSize arrayPitch; + VkDeviceSize depthPitch; +} VkSubresourceLayout; + +typedef struct VkComponentMapping { + VkComponentSwizzle r; + VkComponentSwizzle g; + VkComponentSwizzle b; + VkComponentSwizzle a; +} VkComponentMapping; + +typedef struct VkImageViewCreateInfo { + VkStructureType sType; + const void* pNext; + VkImageViewCreateFlags flags; + VkImage image; + VkImageViewType viewType; + VkFormat format; + VkComponentMapping components; + VkImageSubresourceRange subresourceRange; +} VkImageViewCreateInfo; + +typedef struct VkShaderModuleCreateInfo { + VkStructureType sType; + const void* pNext; + VkShaderModuleCreateFlags flags; + size_t codeSize; + const uint32_t* pCode; +} VkShaderModuleCreateInfo; + +typedef struct VkPipelineCacheCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineCacheCreateFlags flags; + size_t initialDataSize; + const void* pInitialData; +} VkPipelineCacheCreateInfo; + +typedef struct VkSpecializationMapEntry { + uint32_t constantID; + uint32_t offset; + size_t size; +} VkSpecializationMapEntry; + +typedef struct VkSpecializationInfo { + uint32_t mapEntryCount; + const VkSpecializationMapEntry* pMapEntries; + size_t dataSize; + const void* pData; +} VkSpecializationInfo; + +typedef struct VkPipelineShaderStageCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineShaderStageCreateFlags flags; + VkShaderStageFlagBits stage; + VkShaderModule module; + const char* pName; + const VkSpecializationInfo* pSpecializationInfo; +} VkPipelineShaderStageCreateInfo; + +typedef struct VkComputePipelineCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineCreateFlags flags; + VkPipelineShaderStageCreateInfo stage; + VkPipelineLayout layout; + VkPipeline basePipelineHandle; + int32_t basePipelineIndex; +} VkComputePipelineCreateInfo; + +typedef struct VkVertexInputBindingDescription { + uint32_t binding; + uint32_t stride; + VkVertexInputRate inputRate; +} VkVertexInputBindingDescription; + +typedef struct VkVertexInputAttributeDescription { + uint32_t location; + uint32_t binding; + VkFormat format; + uint32_t offset; +} VkVertexInputAttributeDescription; + +typedef struct VkPipelineVertexInputStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineVertexInputStateCreateFlags flags; + uint32_t vertexBindingDescriptionCount; + const VkVertexInputBindingDescription* pVertexBindingDescriptions; + uint32_t vertexAttributeDescriptionCount; + const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; +} VkPipelineVertexInputStateCreateInfo; + +typedef struct VkPipelineInputAssemblyStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineInputAssemblyStateCreateFlags flags; + VkPrimitiveTopology topology; + VkBool32 primitiveRestartEnable; +} VkPipelineInputAssemblyStateCreateInfo; + +typedef struct VkPipelineTessellationStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineTessellationStateCreateFlags flags; + uint32_t patchControlPoints; +} VkPipelineTessellationStateCreateInfo; + +typedef struct VkViewport { + float x; + float y; + float width; + float height; + float minDepth; + float maxDepth; +} VkViewport; + +typedef struct VkPipelineViewportStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineViewportStateCreateFlags flags; + uint32_t viewportCount; + const VkViewport* pViewports; + uint32_t scissorCount; + const VkRect2D* pScissors; +} VkPipelineViewportStateCreateInfo; + +typedef struct VkPipelineRasterizationStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineRasterizationStateCreateFlags flags; + VkBool32 depthClampEnable; + VkBool32 rasterizerDiscardEnable; + VkPolygonMode polygonMode; + VkCullModeFlags cullMode; + VkFrontFace frontFace; + VkBool32 depthBiasEnable; + float depthBiasConstantFactor; + float depthBiasClamp; + float depthBiasSlopeFactor; + float lineWidth; +} VkPipelineRasterizationStateCreateInfo; + +typedef struct VkPipelineMultisampleStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineMultisampleStateCreateFlags flags; + VkSampleCountFlagBits rasterizationSamples; + VkBool32 sampleShadingEnable; + float minSampleShading; + const VkSampleMask* pSampleMask; + VkBool32 alphaToCoverageEnable; + VkBool32 alphaToOneEnable; +} VkPipelineMultisampleStateCreateInfo; + +typedef struct VkStencilOpState { + VkStencilOp failOp; + VkStencilOp passOp; + VkStencilOp depthFailOp; + VkCompareOp compareOp; + uint32_t compareMask; + uint32_t writeMask; + uint32_t reference; +} VkStencilOpState; + +typedef struct VkPipelineDepthStencilStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineDepthStencilStateCreateFlags flags; + VkBool32 depthTestEnable; + VkBool32 depthWriteEnable; + VkCompareOp depthCompareOp; + VkBool32 depthBoundsTestEnable; + VkBool32 stencilTestEnable; + VkStencilOpState front; + VkStencilOpState back; + float minDepthBounds; + float maxDepthBounds; +} VkPipelineDepthStencilStateCreateInfo; + +typedef struct VkPipelineColorBlendAttachmentState { + VkBool32 blendEnable; + VkBlendFactor srcColorBlendFactor; + VkBlendFactor dstColorBlendFactor; + VkBlendOp colorBlendOp; + VkBlendFactor srcAlphaBlendFactor; + VkBlendFactor dstAlphaBlendFactor; + VkBlendOp alphaBlendOp; + VkColorComponentFlags colorWriteMask; +} VkPipelineColorBlendAttachmentState; + +typedef struct VkPipelineColorBlendStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineColorBlendStateCreateFlags flags; + VkBool32 logicOpEnable; + VkLogicOp logicOp; + uint32_t attachmentCount; + const VkPipelineColorBlendAttachmentState* pAttachments; + float blendConstants[4]; +} VkPipelineColorBlendStateCreateInfo; + +typedef struct VkPipelineDynamicStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineDynamicStateCreateFlags flags; + uint32_t dynamicStateCount; + const VkDynamicState* pDynamicStates; +} VkPipelineDynamicStateCreateInfo; + +typedef struct VkGraphicsPipelineCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineCreateFlags flags; + uint32_t stageCount; + const VkPipelineShaderStageCreateInfo* pStages; + const VkPipelineVertexInputStateCreateInfo* pVertexInputState; + const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; + const VkPipelineTessellationStateCreateInfo* pTessellationState; + const VkPipelineViewportStateCreateInfo* pViewportState; + const VkPipelineRasterizationStateCreateInfo* pRasterizationState; + const VkPipelineMultisampleStateCreateInfo* pMultisampleState; + const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; + const VkPipelineColorBlendStateCreateInfo* pColorBlendState; + const VkPipelineDynamicStateCreateInfo* pDynamicState; + VkPipelineLayout layout; + VkRenderPass renderPass; + uint32_t subpass; + VkPipeline basePipelineHandle; + int32_t basePipelineIndex; +} VkGraphicsPipelineCreateInfo; + +typedef struct VkPushConstantRange { + VkShaderStageFlags stageFlags; + uint32_t offset; + uint32_t size; +} VkPushConstantRange; + +typedef struct VkPipelineLayoutCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineLayoutCreateFlags flags; + uint32_t setLayoutCount; + const VkDescriptorSetLayout* pSetLayouts; + uint32_t pushConstantRangeCount; + const VkPushConstantRange* pPushConstantRanges; +} VkPipelineLayoutCreateInfo; + +typedef struct VkSamplerCreateInfo { + VkStructureType sType; + const void* pNext; + VkSamplerCreateFlags flags; + VkFilter magFilter; + VkFilter minFilter; + VkSamplerMipmapMode mipmapMode; + VkSamplerAddressMode addressModeU; + VkSamplerAddressMode addressModeV; + VkSamplerAddressMode addressModeW; + float mipLodBias; + VkBool32 anisotropyEnable; + float maxAnisotropy; + VkBool32 compareEnable; + VkCompareOp compareOp; + float minLod; + float maxLod; + VkBorderColor borderColor; + VkBool32 unnormalizedCoordinates; +} VkSamplerCreateInfo; + +typedef struct VkCopyDescriptorSet { + VkStructureType sType; + const void* pNext; + VkDescriptorSet srcSet; + uint32_t srcBinding; + uint32_t srcArrayElement; + VkDescriptorSet dstSet; + uint32_t dstBinding; + uint32_t dstArrayElement; + uint32_t descriptorCount; +} VkCopyDescriptorSet; + +typedef struct VkDescriptorBufferInfo { + VkBuffer buffer; + VkDeviceSize offset; + VkDeviceSize range; +} VkDescriptorBufferInfo; + +typedef struct VkDescriptorImageInfo { + VkSampler sampler; + VkImageView imageView; + VkImageLayout imageLayout; +} VkDescriptorImageInfo; + +typedef struct VkDescriptorPoolSize { + VkDescriptorType type; + uint32_t descriptorCount; +} VkDescriptorPoolSize; + +typedef struct VkDescriptorPoolCreateInfo { + VkStructureType sType; + const void* pNext; + VkDescriptorPoolCreateFlags flags; + uint32_t maxSets; + uint32_t poolSizeCount; + const VkDescriptorPoolSize* pPoolSizes; +} VkDescriptorPoolCreateInfo; + +typedef struct VkDescriptorSetAllocateInfo { + VkStructureType sType; + const void* pNext; + VkDescriptorPool descriptorPool; + uint32_t descriptorSetCount; + const VkDescriptorSetLayout* pSetLayouts; +} VkDescriptorSetAllocateInfo; + +typedef struct VkDescriptorSetLayoutBinding { + uint32_t binding; + VkDescriptorType descriptorType; + uint32_t descriptorCount; + VkShaderStageFlags stageFlags; + const VkSampler* pImmutableSamplers; +} VkDescriptorSetLayoutBinding; + +typedef struct VkDescriptorSetLayoutCreateInfo { + VkStructureType sType; + const void* pNext; + VkDescriptorSetLayoutCreateFlags flags; + uint32_t bindingCount; + const VkDescriptorSetLayoutBinding* pBindings; +} VkDescriptorSetLayoutCreateInfo; + +typedef struct VkWriteDescriptorSet { + VkStructureType sType; + const void* pNext; + VkDescriptorSet dstSet; + uint32_t dstBinding; + uint32_t dstArrayElement; + uint32_t descriptorCount; + VkDescriptorType descriptorType; + const VkDescriptorImageInfo* pImageInfo; + const VkDescriptorBufferInfo* pBufferInfo; + const VkBufferView* pTexelBufferView; +} VkWriteDescriptorSet; + +typedef struct VkAttachmentDescription { + VkAttachmentDescriptionFlags flags; + VkFormat format; + VkSampleCountFlagBits samples; + VkAttachmentLoadOp loadOp; + VkAttachmentStoreOp storeOp; + VkAttachmentLoadOp stencilLoadOp; + VkAttachmentStoreOp stencilStoreOp; + VkImageLayout initialLayout; + VkImageLayout finalLayout; +} VkAttachmentDescription; + +typedef struct VkAttachmentReference { + uint32_t attachment; + VkImageLayout layout; +} VkAttachmentReference; + +typedef struct VkFramebufferCreateInfo { + VkStructureType sType; + const void* pNext; + VkFramebufferCreateFlags flags; + VkRenderPass renderPass; + uint32_t attachmentCount; + const VkImageView* pAttachments; + uint32_t width; + uint32_t height; + uint32_t layers; +} VkFramebufferCreateInfo; + +typedef struct VkSubpassDescription { + VkSubpassDescriptionFlags flags; + VkPipelineBindPoint pipelineBindPoint; + uint32_t inputAttachmentCount; + const VkAttachmentReference* pInputAttachments; + uint32_t colorAttachmentCount; + const VkAttachmentReference* pColorAttachments; + const VkAttachmentReference* pResolveAttachments; + const VkAttachmentReference* pDepthStencilAttachment; + uint32_t preserveAttachmentCount; + const uint32_t* pPreserveAttachments; +} VkSubpassDescription; + +typedef struct VkSubpassDependency { + uint32_t srcSubpass; + uint32_t dstSubpass; + VkPipelineStageFlags srcStageMask; + VkPipelineStageFlags dstStageMask; + VkAccessFlags srcAccessMask; + VkAccessFlags dstAccessMask; + VkDependencyFlags dependencyFlags; +} VkSubpassDependency; + +typedef struct VkRenderPassCreateInfo { + VkStructureType sType; + const void* pNext; + VkRenderPassCreateFlags flags; + uint32_t attachmentCount; + const VkAttachmentDescription* pAttachments; + uint32_t subpassCount; + const VkSubpassDescription* pSubpasses; + uint32_t dependencyCount; + const VkSubpassDependency* pDependencies; +} VkRenderPassCreateInfo; + +typedef struct VkCommandPoolCreateInfo { + VkStructureType sType; + const void* pNext; + VkCommandPoolCreateFlags flags; + uint32_t queueFamilyIndex; +} VkCommandPoolCreateInfo; + +typedef struct VkCommandBufferAllocateInfo { + VkStructureType sType; + const void* pNext; + VkCommandPool commandPool; + VkCommandBufferLevel level; + uint32_t commandBufferCount; +} VkCommandBufferAllocateInfo; + +typedef struct VkCommandBufferInheritanceInfo { + VkStructureType sType; + const void* pNext; + VkRenderPass renderPass; + uint32_t subpass; + VkFramebuffer framebuffer; + VkBool32 occlusionQueryEnable; + VkQueryControlFlags queryFlags; + VkQueryPipelineStatisticFlags pipelineStatistics; +} VkCommandBufferInheritanceInfo; + +typedef struct VkCommandBufferBeginInfo { + VkStructureType sType; + const void* pNext; + VkCommandBufferUsageFlags flags; + const VkCommandBufferInheritanceInfo* pInheritanceInfo; +} VkCommandBufferBeginInfo; + +typedef struct VkBufferCopy { + VkDeviceSize srcOffset; + VkDeviceSize dstOffset; + VkDeviceSize size; +} VkBufferCopy; + +typedef struct VkImageSubresourceLayers { + VkImageAspectFlags aspectMask; + uint32_t mipLevel; + uint32_t baseArrayLayer; + uint32_t layerCount; +} VkImageSubresourceLayers; + +typedef struct VkBufferImageCopy { + VkDeviceSize bufferOffset; + uint32_t bufferRowLength; + uint32_t bufferImageHeight; + VkImageSubresourceLayers imageSubresource; + VkOffset3D imageOffset; + VkExtent3D imageExtent; +} VkBufferImageCopy; + +typedef union VkClearColorValue { + float float32[4]; + int32_t int32[4]; + uint32_t uint32[4]; +} VkClearColorValue; + +typedef struct VkClearDepthStencilValue { + float depth; + uint32_t stencil; +} VkClearDepthStencilValue; + +typedef union VkClearValue { + VkClearColorValue color; + VkClearDepthStencilValue depthStencil; +} VkClearValue; + +typedef struct VkClearAttachment { + VkImageAspectFlags aspectMask; + uint32_t colorAttachment; + VkClearValue clearValue; +} VkClearAttachment; + +typedef struct VkClearRect { + VkRect2D rect; + uint32_t baseArrayLayer; + uint32_t layerCount; +} VkClearRect; + +typedef struct VkImageBlit { + VkImageSubresourceLayers srcSubresource; + VkOffset3D srcOffsets[2]; + VkImageSubresourceLayers dstSubresource; + VkOffset3D dstOffsets[2]; +} VkImageBlit; + +typedef struct VkImageCopy { + VkImageSubresourceLayers srcSubresource; + VkOffset3D srcOffset; + VkImageSubresourceLayers dstSubresource; + VkOffset3D dstOffset; + VkExtent3D extent; +} VkImageCopy; + +typedef struct VkImageResolve { + VkImageSubresourceLayers srcSubresource; + VkOffset3D srcOffset; + VkImageSubresourceLayers dstSubresource; + VkOffset3D dstOffset; + VkExtent3D extent; +} VkImageResolve; + +typedef struct VkRenderPassBeginInfo { + VkStructureType sType; + const void* pNext; + VkRenderPass renderPass; + VkFramebuffer framebuffer; + VkRect2D renderArea; + uint32_t clearValueCount; + const VkClearValue* pClearValues; +} VkRenderPassBeginInfo; + +typedef VkResult (VKAPI_PTR *PFN_vkCreateInstance)(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance); +typedef void (VKAPI_PTR *PFN_vkDestroyInstance)(VkInstance instance, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkEnumeratePhysicalDevices)(VkInstance instance, uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFeatures)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures* pFeatures); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFormatProperties)(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties* pFormatProperties); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceImageFormatProperties)(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags, VkImageFormatProperties* pImageFormatProperties); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceProperties)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties* pProperties); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceQueueFamilyProperties)(VkPhysicalDevice physicalDevice, uint32_t* pQueueFamilyPropertyCount, VkQueueFamilyProperties* pQueueFamilyProperties); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceMemoryProperties)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties* pMemoryProperties); +typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_vkGetInstanceProcAddr)(VkInstance instance, const char* pName); +typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_vkGetDeviceProcAddr)(VkDevice device, const char* pName); +typedef VkResult (VKAPI_PTR *PFN_vkCreateDevice)(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice); +typedef void (VKAPI_PTR *PFN_vkDestroyDevice)(VkDevice device, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkEnumerateInstanceExtensionProperties)(const char* pLayerName, uint32_t* pPropertyCount, VkExtensionProperties* pProperties); +typedef VkResult (VKAPI_PTR *PFN_vkEnumerateDeviceExtensionProperties)(VkPhysicalDevice physicalDevice, const char* pLayerName, uint32_t* pPropertyCount, VkExtensionProperties* pProperties); +typedef VkResult (VKAPI_PTR *PFN_vkEnumerateInstanceLayerProperties)(uint32_t* pPropertyCount, VkLayerProperties* pProperties); +typedef VkResult (VKAPI_PTR *PFN_vkEnumerateDeviceLayerProperties)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkLayerProperties* pProperties); +typedef void (VKAPI_PTR *PFN_vkGetDeviceQueue)(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue* pQueue); +typedef VkResult (VKAPI_PTR *PFN_vkQueueSubmit)(VkQueue queue, uint32_t submitCount, const VkSubmitInfo* pSubmits, VkFence fence); +typedef VkResult (VKAPI_PTR *PFN_vkQueueWaitIdle)(VkQueue queue); +typedef VkResult (VKAPI_PTR *PFN_vkDeviceWaitIdle)(VkDevice device); +typedef VkResult (VKAPI_PTR *PFN_vkAllocateMemory)(VkDevice device, const VkMemoryAllocateInfo* pAllocateInfo, const VkAllocationCallbacks* pAllocator, VkDeviceMemory* pMemory); +typedef void (VKAPI_PTR *PFN_vkFreeMemory)(VkDevice device, VkDeviceMemory memory, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkMapMemory)(VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void** ppData); +typedef void (VKAPI_PTR *PFN_vkUnmapMemory)(VkDevice device, VkDeviceMemory memory); +typedef VkResult (VKAPI_PTR *PFN_vkFlushMappedMemoryRanges)(VkDevice device, uint32_t memoryRangeCount, const VkMappedMemoryRange* pMemoryRanges); +typedef VkResult (VKAPI_PTR *PFN_vkInvalidateMappedMemoryRanges)(VkDevice device, uint32_t memoryRangeCount, const VkMappedMemoryRange* pMemoryRanges); +typedef void (VKAPI_PTR *PFN_vkGetDeviceMemoryCommitment)(VkDevice device, VkDeviceMemory memory, VkDeviceSize* pCommittedMemoryInBytes); +typedef VkResult (VKAPI_PTR *PFN_vkBindBufferMemory)(VkDevice device, VkBuffer buffer, VkDeviceMemory memory, VkDeviceSize memoryOffset); +typedef VkResult (VKAPI_PTR *PFN_vkBindImageMemory)(VkDevice device, VkImage image, VkDeviceMemory memory, VkDeviceSize memoryOffset); +typedef void (VKAPI_PTR *PFN_vkGetBufferMemoryRequirements)(VkDevice device, VkBuffer buffer, VkMemoryRequirements* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetImageMemoryRequirements)(VkDevice device, VkImage image, VkMemoryRequirements* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetImageSparseMemoryRequirements)(VkDevice device, VkImage image, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements* pSparseMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceSparseImageFormatProperties)(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling, uint32_t* pPropertyCount, VkSparseImageFormatProperties* pProperties); +typedef VkResult (VKAPI_PTR *PFN_vkQueueBindSparse)(VkQueue queue, uint32_t bindInfoCount, const VkBindSparseInfo* pBindInfo, VkFence fence); +typedef VkResult (VKAPI_PTR *PFN_vkCreateFence)(VkDevice device, const VkFenceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkFence* pFence); +typedef void (VKAPI_PTR *PFN_vkDestroyFence)(VkDevice device, VkFence fence, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkResetFences)(VkDevice device, uint32_t fenceCount, const VkFence* pFences); +typedef VkResult (VKAPI_PTR *PFN_vkGetFenceStatus)(VkDevice device, VkFence fence); +typedef VkResult (VKAPI_PTR *PFN_vkWaitForFences)(VkDevice device, uint32_t fenceCount, const VkFence* pFences, VkBool32 waitAll, uint64_t timeout); +typedef VkResult (VKAPI_PTR *PFN_vkCreateSemaphore)(VkDevice device, const VkSemaphoreCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSemaphore* pSemaphore); +typedef void (VKAPI_PTR *PFN_vkDestroySemaphore)(VkDevice device, VkSemaphore semaphore, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreateEvent)(VkDevice device, const VkEventCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkEvent* pEvent); +typedef void (VKAPI_PTR *PFN_vkDestroyEvent)(VkDevice device, VkEvent event, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkGetEventStatus)(VkDevice device, VkEvent event); +typedef VkResult (VKAPI_PTR *PFN_vkSetEvent)(VkDevice device, VkEvent event); +typedef VkResult (VKAPI_PTR *PFN_vkResetEvent)(VkDevice device, VkEvent event); +typedef VkResult (VKAPI_PTR *PFN_vkCreateQueryPool)(VkDevice device, const VkQueryPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkQueryPool* pQueryPool); +typedef void (VKAPI_PTR *PFN_vkDestroyQueryPool)(VkDevice device, VkQueryPool queryPool, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkGetQueryPoolResults)(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, size_t dataSize, void* pData, VkDeviceSize stride, VkQueryResultFlags flags); +typedef VkResult (VKAPI_PTR *PFN_vkCreateBuffer)(VkDevice device, const VkBufferCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkBuffer* pBuffer); +typedef void (VKAPI_PTR *PFN_vkDestroyBuffer)(VkDevice device, VkBuffer buffer, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreateBufferView)(VkDevice device, const VkBufferViewCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkBufferView* pView); +typedef void (VKAPI_PTR *PFN_vkDestroyBufferView)(VkDevice device, VkBufferView bufferView, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreateImage)(VkDevice device, const VkImageCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkImage* pImage); +typedef void (VKAPI_PTR *PFN_vkDestroyImage)(VkDevice device, VkImage image, const VkAllocationCallbacks* pAllocator); +typedef void (VKAPI_PTR *PFN_vkGetImageSubresourceLayout)(VkDevice device, VkImage image, const VkImageSubresource* pSubresource, VkSubresourceLayout* pLayout); +typedef VkResult (VKAPI_PTR *PFN_vkCreateImageView)(VkDevice device, const VkImageViewCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkImageView* pView); +typedef void (VKAPI_PTR *PFN_vkDestroyImageView)(VkDevice device, VkImageView imageView, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreateShaderModule)(VkDevice device, const VkShaderModuleCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkShaderModule* pShaderModule); +typedef void (VKAPI_PTR *PFN_vkDestroyShaderModule)(VkDevice device, VkShaderModule shaderModule, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreatePipelineCache)(VkDevice device, const VkPipelineCacheCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPipelineCache* pPipelineCache); +typedef void (VKAPI_PTR *PFN_vkDestroyPipelineCache)(VkDevice device, VkPipelineCache pipelineCache, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkGetPipelineCacheData)(VkDevice device, VkPipelineCache pipelineCache, size_t* pDataSize, void* pData); +typedef VkResult (VKAPI_PTR *PFN_vkMergePipelineCaches)(VkDevice device, VkPipelineCache dstCache, uint32_t srcCacheCount, const VkPipelineCache* pSrcCaches); +typedef VkResult (VKAPI_PTR *PFN_vkCreateGraphicsPipelines)(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkGraphicsPipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines); +typedef VkResult (VKAPI_PTR *PFN_vkCreateComputePipelines)(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkComputePipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines); +typedef void (VKAPI_PTR *PFN_vkDestroyPipeline)(VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreatePipelineLayout)(VkDevice device, const VkPipelineLayoutCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPipelineLayout* pPipelineLayout); +typedef void (VKAPI_PTR *PFN_vkDestroyPipelineLayout)(VkDevice device, VkPipelineLayout pipelineLayout, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreateSampler)(VkDevice device, const VkSamplerCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSampler* pSampler); +typedef void (VKAPI_PTR *PFN_vkDestroySampler)(VkDevice device, VkSampler sampler, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreateDescriptorSetLayout)(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDescriptorSetLayout* pSetLayout); +typedef void (VKAPI_PTR *PFN_vkDestroyDescriptorSetLayout)(VkDevice device, VkDescriptorSetLayout descriptorSetLayout, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreateDescriptorPool)(VkDevice device, const VkDescriptorPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDescriptorPool* pDescriptorPool); +typedef void (VKAPI_PTR *PFN_vkDestroyDescriptorPool)(VkDevice device, VkDescriptorPool descriptorPool, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkResetDescriptorPool)(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorPoolResetFlags flags); +typedef VkResult (VKAPI_PTR *PFN_vkAllocateDescriptorSets)(VkDevice device, const VkDescriptorSetAllocateInfo* pAllocateInfo, VkDescriptorSet* pDescriptorSets); +typedef VkResult (VKAPI_PTR *PFN_vkFreeDescriptorSets)(VkDevice device, VkDescriptorPool descriptorPool, uint32_t descriptorSetCount, const VkDescriptorSet* pDescriptorSets); +typedef void (VKAPI_PTR *PFN_vkUpdateDescriptorSets)(VkDevice device, uint32_t descriptorWriteCount, const VkWriteDescriptorSet* pDescriptorWrites, uint32_t descriptorCopyCount, const VkCopyDescriptorSet* pDescriptorCopies); +typedef VkResult (VKAPI_PTR *PFN_vkCreateFramebuffer)(VkDevice device, const VkFramebufferCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkFramebuffer* pFramebuffer); +typedef void (VKAPI_PTR *PFN_vkDestroyFramebuffer)(VkDevice device, VkFramebuffer framebuffer, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreateRenderPass)(VkDevice device, const VkRenderPassCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass); +typedef void (VKAPI_PTR *PFN_vkDestroyRenderPass)(VkDevice device, VkRenderPass renderPass, const VkAllocationCallbacks* pAllocator); +typedef void (VKAPI_PTR *PFN_vkGetRenderAreaGranularity)(VkDevice device, VkRenderPass renderPass, VkExtent2D* pGranularity); +typedef VkResult (VKAPI_PTR *PFN_vkCreateCommandPool)(VkDevice device, const VkCommandPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkCommandPool* pCommandPool); +typedef void (VKAPI_PTR *PFN_vkDestroyCommandPool)(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkResetCommandPool)(VkDevice device, VkCommandPool commandPool, VkCommandPoolResetFlags flags); +typedef VkResult (VKAPI_PTR *PFN_vkAllocateCommandBuffers)(VkDevice device, const VkCommandBufferAllocateInfo* pAllocateInfo, VkCommandBuffer* pCommandBuffers); +typedef void (VKAPI_PTR *PFN_vkFreeCommandBuffers)(VkDevice device, VkCommandPool commandPool, uint32_t commandBufferCount, const VkCommandBuffer* pCommandBuffers); +typedef VkResult (VKAPI_PTR *PFN_vkBeginCommandBuffer)(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo* pBeginInfo); +typedef VkResult (VKAPI_PTR *PFN_vkEndCommandBuffer)(VkCommandBuffer commandBuffer); +typedef VkResult (VKAPI_PTR *PFN_vkResetCommandBuffer)(VkCommandBuffer commandBuffer, VkCommandBufferResetFlags flags); +typedef void (VKAPI_PTR *PFN_vkCmdBindPipeline)(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline); +typedef void (VKAPI_PTR *PFN_vkCmdSetViewport)(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkViewport* pViewports); +typedef void (VKAPI_PTR *PFN_vkCmdSetScissor)(VkCommandBuffer commandBuffer, uint32_t firstScissor, uint32_t scissorCount, const VkRect2D* pScissors); +typedef void (VKAPI_PTR *PFN_vkCmdSetLineWidth)(VkCommandBuffer commandBuffer, float lineWidth); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthBias)(VkCommandBuffer commandBuffer, float depthBiasConstantFactor, float depthBiasClamp, float depthBiasSlopeFactor); +typedef void (VKAPI_PTR *PFN_vkCmdSetBlendConstants)(VkCommandBuffer commandBuffer, const float blendConstants[4]); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthBounds)(VkCommandBuffer commandBuffer, float minDepthBounds, float maxDepthBounds); +typedef void (VKAPI_PTR *PFN_vkCmdSetStencilCompareMask)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t compareMask); +typedef void (VKAPI_PTR *PFN_vkCmdSetStencilWriteMask)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t writeMask); +typedef void (VKAPI_PTR *PFN_vkCmdSetStencilReference)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, uint32_t reference); +typedef void (VKAPI_PTR *PFN_vkCmdBindDescriptorSets)(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t firstSet, uint32_t descriptorSetCount, const VkDescriptorSet* pDescriptorSets, uint32_t dynamicOffsetCount, const uint32_t* pDynamicOffsets); +typedef void (VKAPI_PTR *PFN_vkCmdBindIndexBuffer)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType); +typedef void (VKAPI_PTR *PFN_vkCmdBindVertexBuffers)(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, const VkBuffer* pBuffers, const VkDeviceSize* pOffsets); +typedef void (VKAPI_PTR *PFN_vkCmdDraw)(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance); +typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexed)(VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance); +typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirect)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride); +typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexedIndirect)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride); +typedef void (VKAPI_PTR *PFN_vkCmdDispatch)(VkCommandBuffer commandBuffer, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ); +typedef void (VKAPI_PTR *PFN_vkCmdDispatchIndirect)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset); +typedef void (VKAPI_PTR *PFN_vkCmdCopyBuffer)(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferCopy* pRegions); +typedef void (VKAPI_PTR *PFN_vkCmdCopyImage)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageCopy* pRegions); +typedef void (VKAPI_PTR *PFN_vkCmdBlitImage)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageBlit* pRegions, VkFilter filter); +typedef void (VKAPI_PTR *PFN_vkCmdCopyBufferToImage)(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkBufferImageCopy* pRegions); +typedef void (VKAPI_PTR *PFN_vkCmdCopyImageToBuffer)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferImageCopy* pRegions); +typedef void (VKAPI_PTR *PFN_vkCmdUpdateBuffer)(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize dataSize, const void* pData); +typedef void (VKAPI_PTR *PFN_vkCmdFillBuffer)(VkCommandBuffer commandBuffer, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data); +typedef void (VKAPI_PTR *PFN_vkCmdClearColorImage)(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, const VkClearColorValue* pColor, uint32_t rangeCount, const VkImageSubresourceRange* pRanges); +typedef void (VKAPI_PTR *PFN_vkCmdClearDepthStencilImage)(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout imageLayout, const VkClearDepthStencilValue* pDepthStencil, uint32_t rangeCount, const VkImageSubresourceRange* pRanges); +typedef void (VKAPI_PTR *PFN_vkCmdClearAttachments)(VkCommandBuffer commandBuffer, uint32_t attachmentCount, const VkClearAttachment* pAttachments, uint32_t rectCount, const VkClearRect* pRects); +typedef void (VKAPI_PTR *PFN_vkCmdResolveImage)(VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageResolve* pRegions); +typedef void (VKAPI_PTR *PFN_vkCmdSetEvent)(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask); +typedef void (VKAPI_PTR *PFN_vkCmdResetEvent)(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask); +typedef void (VKAPI_PTR *PFN_vkCmdWaitEvents)(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent* pEvents, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, uint32_t memoryBarrierCount, const VkMemoryBarrier* pMemoryBarriers, uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier* pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier* pImageMemoryBarriers); +typedef void (VKAPI_PTR *PFN_vkCmdPipelineBarrier)(VkCommandBuffer commandBuffer, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkDependencyFlags dependencyFlags, uint32_t memoryBarrierCount, const VkMemoryBarrier* pMemoryBarriers, uint32_t bufferMemoryBarrierCount, const VkBufferMemoryBarrier* pBufferMemoryBarriers, uint32_t imageMemoryBarrierCount, const VkImageMemoryBarrier* pImageMemoryBarriers); +typedef void (VKAPI_PTR *PFN_vkCmdBeginQuery)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags); +typedef void (VKAPI_PTR *PFN_vkCmdEndQuery)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query); +typedef void (VKAPI_PTR *PFN_vkCmdResetQueryPool)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount); +typedef void (VKAPI_PTR *PFN_vkCmdWriteTimestamp)(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage, VkQueryPool queryPool, uint32_t query); +typedef void (VKAPI_PTR *PFN_vkCmdCopyQueryPoolResults)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount, VkBuffer dstBuffer, VkDeviceSize dstOffset, VkDeviceSize stride, VkQueryResultFlags flags); +typedef void (VKAPI_PTR *PFN_vkCmdPushConstants)(VkCommandBuffer commandBuffer, VkPipelineLayout layout, VkShaderStageFlags stageFlags, uint32_t offset, uint32_t size, const void* pValues); +typedef void (VKAPI_PTR *PFN_vkCmdBeginRenderPass)(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, VkSubpassContents contents); +typedef void (VKAPI_PTR *PFN_vkCmdNextSubpass)(VkCommandBuffer commandBuffer, VkSubpassContents contents); +typedef void (VKAPI_PTR *PFN_vkCmdEndRenderPass)(VkCommandBuffer commandBuffer); +typedef void (VKAPI_PTR *PFN_vkCmdExecuteCommands)(VkCommandBuffer commandBuffer, uint32_t commandBufferCount, const VkCommandBuffer* pCommandBuffers); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateInstance( + const VkInstanceCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkInstance* pInstance); + +VKAPI_ATTR void VKAPI_CALL vkDestroyInstance( + VkInstance instance, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDevices( + VkInstance instance, + uint32_t* pPhysicalDeviceCount, + VkPhysicalDevice* pPhysicalDevices); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFeatures( + VkPhysicalDevice physicalDevice, + VkPhysicalDeviceFeatures* pFeatures); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFormatProperties( + VkPhysicalDevice physicalDevice, + VkFormat format, + VkFormatProperties* pFormatProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceImageFormatProperties( + VkPhysicalDevice physicalDevice, + VkFormat format, + VkImageType type, + VkImageTiling tiling, + VkImageUsageFlags usage, + VkImageCreateFlags flags, + VkImageFormatProperties* pImageFormatProperties); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties( + VkPhysicalDevice physicalDevice, + VkPhysicalDeviceProperties* pProperties); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyProperties( + VkPhysicalDevice physicalDevice, + uint32_t* pQueueFamilyPropertyCount, + VkQueueFamilyProperties* pQueueFamilyProperties); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties( + VkPhysicalDevice physicalDevice, + VkPhysicalDeviceMemoryProperties* pMemoryProperties); + +VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr( + VkInstance instance, + const char* pName); + +VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr( + VkDevice device, + const char* pName); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice( + VkPhysicalDevice physicalDevice, + const VkDeviceCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkDevice* pDevice); + +VKAPI_ATTR void VKAPI_CALL vkDestroyDevice( + VkDevice device, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties( + const char* pLayerName, + uint32_t* pPropertyCount, + VkExtensionProperties* pProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties( + VkPhysicalDevice physicalDevice, + const char* pLayerName, + uint32_t* pPropertyCount, + VkExtensionProperties* pProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties( + uint32_t* pPropertyCount, + VkLayerProperties* pProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties( + VkPhysicalDevice physicalDevice, + uint32_t* pPropertyCount, + VkLayerProperties* pProperties); + +VKAPI_ATTR void VKAPI_CALL vkGetDeviceQueue( + VkDevice device, + uint32_t queueFamilyIndex, + uint32_t queueIndex, + VkQueue* pQueue); + +VKAPI_ATTR VkResult VKAPI_CALL vkQueueSubmit( + VkQueue queue, + uint32_t submitCount, + const VkSubmitInfo* pSubmits, + VkFence fence); + +VKAPI_ATTR VkResult VKAPI_CALL vkQueueWaitIdle( + VkQueue queue); + +VKAPI_ATTR VkResult VKAPI_CALL vkDeviceWaitIdle( + VkDevice device); + +VKAPI_ATTR VkResult VKAPI_CALL vkAllocateMemory( + VkDevice device, + const VkMemoryAllocateInfo* pAllocateInfo, + const VkAllocationCallbacks* pAllocator, + VkDeviceMemory* pMemory); + +VKAPI_ATTR void VKAPI_CALL vkFreeMemory( + VkDevice device, + VkDeviceMemory memory, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkMapMemory( + VkDevice device, + VkDeviceMemory memory, + VkDeviceSize offset, + VkDeviceSize size, + VkMemoryMapFlags flags, + void** ppData); + +VKAPI_ATTR void VKAPI_CALL vkUnmapMemory( + VkDevice device, + VkDeviceMemory memory); + +VKAPI_ATTR VkResult VKAPI_CALL vkFlushMappedMemoryRanges( + VkDevice device, + uint32_t memoryRangeCount, + const VkMappedMemoryRange* pMemoryRanges); + +VKAPI_ATTR VkResult VKAPI_CALL vkInvalidateMappedMemoryRanges( + VkDevice device, + uint32_t memoryRangeCount, + const VkMappedMemoryRange* pMemoryRanges); + +VKAPI_ATTR void VKAPI_CALL vkGetDeviceMemoryCommitment( + VkDevice device, + VkDeviceMemory memory, + VkDeviceSize* pCommittedMemoryInBytes); + +VKAPI_ATTR VkResult VKAPI_CALL vkBindBufferMemory( + VkDevice device, + VkBuffer buffer, + VkDeviceMemory memory, + VkDeviceSize memoryOffset); + +VKAPI_ATTR VkResult VKAPI_CALL vkBindImageMemory( + VkDevice device, + VkImage image, + VkDeviceMemory memory, + VkDeviceSize memoryOffset); + +VKAPI_ATTR void VKAPI_CALL vkGetBufferMemoryRequirements( + VkDevice device, + VkBuffer buffer, + VkMemoryRequirements* pMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkGetImageMemoryRequirements( + VkDevice device, + VkImage image, + VkMemoryRequirements* pMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkGetImageSparseMemoryRequirements( + VkDevice device, + VkImage image, + uint32_t* pSparseMemoryRequirementCount, + VkSparseImageMemoryRequirements* pSparseMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceSparseImageFormatProperties( + VkPhysicalDevice physicalDevice, + VkFormat format, + VkImageType type, + VkSampleCountFlagBits samples, + VkImageUsageFlags usage, + VkImageTiling tiling, + uint32_t* pPropertyCount, + VkSparseImageFormatProperties* pProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkQueueBindSparse( + VkQueue queue, + uint32_t bindInfoCount, + const VkBindSparseInfo* pBindInfo, + VkFence fence); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateFence( + VkDevice device, + const VkFenceCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkFence* pFence); + +VKAPI_ATTR void VKAPI_CALL vkDestroyFence( + VkDevice device, + VkFence fence, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkResetFences( + VkDevice device, + uint32_t fenceCount, + const VkFence* pFences); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetFenceStatus( + VkDevice device, + VkFence fence); + +VKAPI_ATTR VkResult VKAPI_CALL vkWaitForFences( + VkDevice device, + uint32_t fenceCount, + const VkFence* pFences, + VkBool32 waitAll, + uint64_t timeout); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateSemaphore( + VkDevice device, + const VkSemaphoreCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSemaphore* pSemaphore); + +VKAPI_ATTR void VKAPI_CALL vkDestroySemaphore( + VkDevice device, + VkSemaphore semaphore, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateEvent( + VkDevice device, + const VkEventCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkEvent* pEvent); + +VKAPI_ATTR void VKAPI_CALL vkDestroyEvent( + VkDevice device, + VkEvent event, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetEventStatus( + VkDevice device, + VkEvent event); + +VKAPI_ATTR VkResult VKAPI_CALL vkSetEvent( + VkDevice device, + VkEvent event); + +VKAPI_ATTR VkResult VKAPI_CALL vkResetEvent( + VkDevice device, + VkEvent event); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateQueryPool( + VkDevice device, + const VkQueryPoolCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkQueryPool* pQueryPool); + +VKAPI_ATTR void VKAPI_CALL vkDestroyQueryPool( + VkDevice device, + VkQueryPool queryPool, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetQueryPoolResults( + VkDevice device, + VkQueryPool queryPool, + uint32_t firstQuery, + uint32_t queryCount, + size_t dataSize, + void* pData, + VkDeviceSize stride, + VkQueryResultFlags flags); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateBuffer( + VkDevice device, + const VkBufferCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkBuffer* pBuffer); + +VKAPI_ATTR void VKAPI_CALL vkDestroyBuffer( + VkDevice device, + VkBuffer buffer, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateBufferView( + VkDevice device, + const VkBufferViewCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkBufferView* pView); + +VKAPI_ATTR void VKAPI_CALL vkDestroyBufferView( + VkDevice device, + VkBufferView bufferView, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateImage( + VkDevice device, + const VkImageCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkImage* pImage); + +VKAPI_ATTR void VKAPI_CALL vkDestroyImage( + VkDevice device, + VkImage image, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR void VKAPI_CALL vkGetImageSubresourceLayout( + VkDevice device, + VkImage image, + const VkImageSubresource* pSubresource, + VkSubresourceLayout* pLayout); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateImageView( + VkDevice device, + const VkImageViewCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkImageView* pView); + +VKAPI_ATTR void VKAPI_CALL vkDestroyImageView( + VkDevice device, + VkImageView imageView, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateShaderModule( + VkDevice device, + const VkShaderModuleCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkShaderModule* pShaderModule); + +VKAPI_ATTR void VKAPI_CALL vkDestroyShaderModule( + VkDevice device, + VkShaderModule shaderModule, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreatePipelineCache( + VkDevice device, + const VkPipelineCacheCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkPipelineCache* pPipelineCache); + +VKAPI_ATTR void VKAPI_CALL vkDestroyPipelineCache( + VkDevice device, + VkPipelineCache pipelineCache, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelineCacheData( + VkDevice device, + VkPipelineCache pipelineCache, + size_t* pDataSize, + void* pData); + +VKAPI_ATTR VkResult VKAPI_CALL vkMergePipelineCaches( + VkDevice device, + VkPipelineCache dstCache, + uint32_t srcCacheCount, + const VkPipelineCache* pSrcCaches); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateGraphicsPipelines( + VkDevice device, + VkPipelineCache pipelineCache, + uint32_t createInfoCount, + const VkGraphicsPipelineCreateInfo* pCreateInfos, + const VkAllocationCallbacks* pAllocator, + VkPipeline* pPipelines); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateComputePipelines( + VkDevice device, + VkPipelineCache pipelineCache, + uint32_t createInfoCount, + const VkComputePipelineCreateInfo* pCreateInfos, + const VkAllocationCallbacks* pAllocator, + VkPipeline* pPipelines); + +VKAPI_ATTR void VKAPI_CALL vkDestroyPipeline( + VkDevice device, + VkPipeline pipeline, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreatePipelineLayout( + VkDevice device, + const VkPipelineLayoutCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkPipelineLayout* pPipelineLayout); + +VKAPI_ATTR void VKAPI_CALL vkDestroyPipelineLayout( + VkDevice device, + VkPipelineLayout pipelineLayout, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateSampler( + VkDevice device, + const VkSamplerCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSampler* pSampler); + +VKAPI_ATTR void VKAPI_CALL vkDestroySampler( + VkDevice device, + VkSampler sampler, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorSetLayout( + VkDevice device, + const VkDescriptorSetLayoutCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkDescriptorSetLayout* pSetLayout); + +VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorSetLayout( + VkDevice device, + VkDescriptorSetLayout descriptorSetLayout, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorPool( + VkDevice device, + const VkDescriptorPoolCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkDescriptorPool* pDescriptorPool); + +VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorPool( + VkDevice device, + VkDescriptorPool descriptorPool, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkResetDescriptorPool( + VkDevice device, + VkDescriptorPool descriptorPool, + VkDescriptorPoolResetFlags flags); + +VKAPI_ATTR VkResult VKAPI_CALL vkAllocateDescriptorSets( + VkDevice device, + const VkDescriptorSetAllocateInfo* pAllocateInfo, + VkDescriptorSet* pDescriptorSets); + +VKAPI_ATTR VkResult VKAPI_CALL vkFreeDescriptorSets( + VkDevice device, + VkDescriptorPool descriptorPool, + uint32_t descriptorSetCount, + const VkDescriptorSet* pDescriptorSets); + +VKAPI_ATTR void VKAPI_CALL vkUpdateDescriptorSets( + VkDevice device, + uint32_t descriptorWriteCount, + const VkWriteDescriptorSet* pDescriptorWrites, + uint32_t descriptorCopyCount, + const VkCopyDescriptorSet* pDescriptorCopies); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateFramebuffer( + VkDevice device, + const VkFramebufferCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkFramebuffer* pFramebuffer); + +VKAPI_ATTR void VKAPI_CALL vkDestroyFramebuffer( + VkDevice device, + VkFramebuffer framebuffer, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass( + VkDevice device, + const VkRenderPassCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkRenderPass* pRenderPass); + +VKAPI_ATTR void VKAPI_CALL vkDestroyRenderPass( + VkDevice device, + VkRenderPass renderPass, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR void VKAPI_CALL vkGetRenderAreaGranularity( + VkDevice device, + VkRenderPass renderPass, + VkExtent2D* pGranularity); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateCommandPool( + VkDevice device, + const VkCommandPoolCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkCommandPool* pCommandPool); + +VKAPI_ATTR void VKAPI_CALL vkDestroyCommandPool( + VkDevice device, + VkCommandPool commandPool, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkResetCommandPool( + VkDevice device, + VkCommandPool commandPool, + VkCommandPoolResetFlags flags); + +VKAPI_ATTR VkResult VKAPI_CALL vkAllocateCommandBuffers( + VkDevice device, + const VkCommandBufferAllocateInfo* pAllocateInfo, + VkCommandBuffer* pCommandBuffers); + +VKAPI_ATTR void VKAPI_CALL vkFreeCommandBuffers( + VkDevice device, + VkCommandPool commandPool, + uint32_t commandBufferCount, + const VkCommandBuffer* pCommandBuffers); + +VKAPI_ATTR VkResult VKAPI_CALL vkBeginCommandBuffer( + VkCommandBuffer commandBuffer, + const VkCommandBufferBeginInfo* pBeginInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkEndCommandBuffer( + VkCommandBuffer commandBuffer); + +VKAPI_ATTR VkResult VKAPI_CALL vkResetCommandBuffer( + VkCommandBuffer commandBuffer, + VkCommandBufferResetFlags flags); + +VKAPI_ATTR void VKAPI_CALL vkCmdBindPipeline( + VkCommandBuffer commandBuffer, + VkPipelineBindPoint pipelineBindPoint, + VkPipeline pipeline); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetViewport( + VkCommandBuffer commandBuffer, + uint32_t firstViewport, + uint32_t viewportCount, + const VkViewport* pViewports); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetScissor( + VkCommandBuffer commandBuffer, + uint32_t firstScissor, + uint32_t scissorCount, + const VkRect2D* pScissors); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetLineWidth( + VkCommandBuffer commandBuffer, + float lineWidth); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBias( + VkCommandBuffer commandBuffer, + float depthBiasConstantFactor, + float depthBiasClamp, + float depthBiasSlopeFactor); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetBlendConstants( + VkCommandBuffer commandBuffer, + const float blendConstants[4]); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBounds( + VkCommandBuffer commandBuffer, + float minDepthBounds, + float maxDepthBounds); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilCompareMask( + VkCommandBuffer commandBuffer, + VkStencilFaceFlags faceMask, + uint32_t compareMask); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilWriteMask( + VkCommandBuffer commandBuffer, + VkStencilFaceFlags faceMask, + uint32_t writeMask); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilReference( + VkCommandBuffer commandBuffer, + VkStencilFaceFlags faceMask, + uint32_t reference); + +VKAPI_ATTR void VKAPI_CALL vkCmdBindDescriptorSets( + VkCommandBuffer commandBuffer, + VkPipelineBindPoint pipelineBindPoint, + VkPipelineLayout layout, + uint32_t firstSet, + uint32_t descriptorSetCount, + const VkDescriptorSet* pDescriptorSets, + uint32_t dynamicOffsetCount, + const uint32_t* pDynamicOffsets); + +VKAPI_ATTR void VKAPI_CALL vkCmdBindIndexBuffer( + VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset, + VkIndexType indexType); + +VKAPI_ATTR void VKAPI_CALL vkCmdBindVertexBuffers( + VkCommandBuffer commandBuffer, + uint32_t firstBinding, + uint32_t bindingCount, + const VkBuffer* pBuffers, + const VkDeviceSize* pOffsets); + +VKAPI_ATTR void VKAPI_CALL vkCmdDraw( + VkCommandBuffer commandBuffer, + uint32_t vertexCount, + uint32_t instanceCount, + uint32_t firstVertex, + uint32_t firstInstance); + +VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexed( + VkCommandBuffer commandBuffer, + uint32_t indexCount, + uint32_t instanceCount, + uint32_t firstIndex, + int32_t vertexOffset, + uint32_t firstInstance); + +VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirect( + VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset, + uint32_t drawCount, + uint32_t stride); + +VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirect( + VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset, + uint32_t drawCount, + uint32_t stride); + +VKAPI_ATTR void VKAPI_CALL vkCmdDispatch( + VkCommandBuffer commandBuffer, + uint32_t groupCountX, + uint32_t groupCountY, + uint32_t groupCountZ); + +VKAPI_ATTR void VKAPI_CALL vkCmdDispatchIndirect( + VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyBuffer( + VkCommandBuffer commandBuffer, + VkBuffer srcBuffer, + VkBuffer dstBuffer, + uint32_t regionCount, + const VkBufferCopy* pRegions); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyImage( + VkCommandBuffer commandBuffer, + VkImage srcImage, + VkImageLayout srcImageLayout, + VkImage dstImage, + VkImageLayout dstImageLayout, + uint32_t regionCount, + const VkImageCopy* pRegions); + +VKAPI_ATTR void VKAPI_CALL vkCmdBlitImage( + VkCommandBuffer commandBuffer, + VkImage srcImage, + VkImageLayout srcImageLayout, + VkImage dstImage, + VkImageLayout dstImageLayout, + uint32_t regionCount, + const VkImageBlit* pRegions, + VkFilter filter); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyBufferToImage( + VkCommandBuffer commandBuffer, + VkBuffer srcBuffer, + VkImage dstImage, + VkImageLayout dstImageLayout, + uint32_t regionCount, + const VkBufferImageCopy* pRegions); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyImageToBuffer( + VkCommandBuffer commandBuffer, + VkImage srcImage, + VkImageLayout srcImageLayout, + VkBuffer dstBuffer, + uint32_t regionCount, + const VkBufferImageCopy* pRegions); + +VKAPI_ATTR void VKAPI_CALL vkCmdUpdateBuffer( + VkCommandBuffer commandBuffer, + VkBuffer dstBuffer, + VkDeviceSize dstOffset, + VkDeviceSize dataSize, + const void* pData); + +VKAPI_ATTR void VKAPI_CALL vkCmdFillBuffer( + VkCommandBuffer commandBuffer, + VkBuffer dstBuffer, + VkDeviceSize dstOffset, + VkDeviceSize size, + uint32_t data); + +VKAPI_ATTR void VKAPI_CALL vkCmdClearColorImage( + VkCommandBuffer commandBuffer, + VkImage image, + VkImageLayout imageLayout, + const VkClearColorValue* pColor, + uint32_t rangeCount, + const VkImageSubresourceRange* pRanges); + +VKAPI_ATTR void VKAPI_CALL vkCmdClearDepthStencilImage( + VkCommandBuffer commandBuffer, + VkImage image, + VkImageLayout imageLayout, + const VkClearDepthStencilValue* pDepthStencil, + uint32_t rangeCount, + const VkImageSubresourceRange* pRanges); + +VKAPI_ATTR void VKAPI_CALL vkCmdClearAttachments( + VkCommandBuffer commandBuffer, + uint32_t attachmentCount, + const VkClearAttachment* pAttachments, + uint32_t rectCount, + const VkClearRect* pRects); + +VKAPI_ATTR void VKAPI_CALL vkCmdResolveImage( + VkCommandBuffer commandBuffer, + VkImage srcImage, + VkImageLayout srcImageLayout, + VkImage dstImage, + VkImageLayout dstImageLayout, + uint32_t regionCount, + const VkImageResolve* pRegions); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetEvent( + VkCommandBuffer commandBuffer, + VkEvent event, + VkPipelineStageFlags stageMask); + +VKAPI_ATTR void VKAPI_CALL vkCmdResetEvent( + VkCommandBuffer commandBuffer, + VkEvent event, + VkPipelineStageFlags stageMask); + +VKAPI_ATTR void VKAPI_CALL vkCmdWaitEvents( + VkCommandBuffer commandBuffer, + uint32_t eventCount, + const VkEvent* pEvents, + VkPipelineStageFlags srcStageMask, + VkPipelineStageFlags dstStageMask, + uint32_t memoryBarrierCount, + const VkMemoryBarrier* pMemoryBarriers, + uint32_t bufferMemoryBarrierCount, + const VkBufferMemoryBarrier* pBufferMemoryBarriers, + uint32_t imageMemoryBarrierCount, + const VkImageMemoryBarrier* pImageMemoryBarriers); + +VKAPI_ATTR void VKAPI_CALL vkCmdPipelineBarrier( + VkCommandBuffer commandBuffer, + VkPipelineStageFlags srcStageMask, + VkPipelineStageFlags dstStageMask, + VkDependencyFlags dependencyFlags, + uint32_t memoryBarrierCount, + const VkMemoryBarrier* pMemoryBarriers, + uint32_t bufferMemoryBarrierCount, + const VkBufferMemoryBarrier* pBufferMemoryBarriers, + uint32_t imageMemoryBarrierCount, + const VkImageMemoryBarrier* pImageMemoryBarriers); + +VKAPI_ATTR void VKAPI_CALL vkCmdBeginQuery( + VkCommandBuffer commandBuffer, + VkQueryPool queryPool, + uint32_t query, + VkQueryControlFlags flags); + +VKAPI_ATTR void VKAPI_CALL vkCmdEndQuery( + VkCommandBuffer commandBuffer, + VkQueryPool queryPool, + uint32_t query); + +VKAPI_ATTR void VKAPI_CALL vkCmdResetQueryPool( + VkCommandBuffer commandBuffer, + VkQueryPool queryPool, + uint32_t firstQuery, + uint32_t queryCount); + +VKAPI_ATTR void VKAPI_CALL vkCmdWriteTimestamp( + VkCommandBuffer commandBuffer, + VkPipelineStageFlagBits pipelineStage, + VkQueryPool queryPool, + uint32_t query); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyQueryPoolResults( + VkCommandBuffer commandBuffer, + VkQueryPool queryPool, + uint32_t firstQuery, + uint32_t queryCount, + VkBuffer dstBuffer, + VkDeviceSize dstOffset, + VkDeviceSize stride, + VkQueryResultFlags flags); + +VKAPI_ATTR void VKAPI_CALL vkCmdPushConstants( + VkCommandBuffer commandBuffer, + VkPipelineLayout layout, + VkShaderStageFlags stageFlags, + uint32_t offset, + uint32_t size, + const void* pValues); + +VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderPass( + VkCommandBuffer commandBuffer, + const VkRenderPassBeginInfo* pRenderPassBegin, + VkSubpassContents contents); + +VKAPI_ATTR void VKAPI_CALL vkCmdNextSubpass( + VkCommandBuffer commandBuffer, + VkSubpassContents contents); + +VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderPass( + VkCommandBuffer commandBuffer); + +VKAPI_ATTR void VKAPI_CALL vkCmdExecuteCommands( + VkCommandBuffer commandBuffer, + uint32_t commandBufferCount, + const VkCommandBuffer* pCommandBuffers); +#endif + + +// VK_VERSION_1_1 is a preprocessor guard. Do not pass it to API calls. +#define VK_VERSION_1_1 1 +// Vulkan 1.1 version number +#define VK_API_VERSION_1_1 VK_MAKE_API_VERSION(0, 1, 1, 0)// Patch version should always be set to 0 + +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSamplerYcbcrConversion) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDescriptorUpdateTemplate) +#define VK_MAX_DEVICE_GROUP_SIZE 32U +#define VK_LUID_SIZE 8U +#define VK_QUEUE_FAMILY_EXTERNAL (~1U) + +typedef enum VkPointClippingBehavior { + VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES = 0, + VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY = 1, + VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES_KHR = VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES, + VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY_KHR = VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY, + VK_POINT_CLIPPING_BEHAVIOR_MAX_ENUM = 0x7FFFFFFF +} VkPointClippingBehavior; + +typedef enum VkTessellationDomainOrigin { + VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT = 0, + VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT = 1, + VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT_KHR = VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT, + VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT_KHR = VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT, + VK_TESSELLATION_DOMAIN_ORIGIN_MAX_ENUM = 0x7FFFFFFF +} VkTessellationDomainOrigin; + +typedef enum VkSamplerYcbcrModelConversion { + VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY = 0, + VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY = 1, + VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709 = 2, + VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601 = 3, + VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020 = 4, + VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY_KHR = VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY, + VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY_KHR = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY, + VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709_KHR = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709, + VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601_KHR = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601, + VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020_KHR = VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020, + VK_SAMPLER_YCBCR_MODEL_CONVERSION_MAX_ENUM = 0x7FFFFFFF +} VkSamplerYcbcrModelConversion; + +typedef enum VkSamplerYcbcrRange { + VK_SAMPLER_YCBCR_RANGE_ITU_FULL = 0, + VK_SAMPLER_YCBCR_RANGE_ITU_NARROW = 1, + VK_SAMPLER_YCBCR_RANGE_ITU_FULL_KHR = VK_SAMPLER_YCBCR_RANGE_ITU_FULL, + VK_SAMPLER_YCBCR_RANGE_ITU_NARROW_KHR = VK_SAMPLER_YCBCR_RANGE_ITU_NARROW, + VK_SAMPLER_YCBCR_RANGE_MAX_ENUM = 0x7FFFFFFF +} VkSamplerYcbcrRange; + +typedef enum VkChromaLocation { + VK_CHROMA_LOCATION_COSITED_EVEN = 0, + VK_CHROMA_LOCATION_MIDPOINT = 1, + VK_CHROMA_LOCATION_COSITED_EVEN_KHR = VK_CHROMA_LOCATION_COSITED_EVEN, + VK_CHROMA_LOCATION_MIDPOINT_KHR = VK_CHROMA_LOCATION_MIDPOINT, + VK_CHROMA_LOCATION_MAX_ENUM = 0x7FFFFFFF +} VkChromaLocation; + +typedef enum VkDescriptorUpdateTemplateType { + VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET = 0, + VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR = 1, + VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET, + VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkDescriptorUpdateTemplateType; + +typedef enum VkSubgroupFeatureFlagBits { + VK_SUBGROUP_FEATURE_BASIC_BIT = 0x00000001, + VK_SUBGROUP_FEATURE_VOTE_BIT = 0x00000002, + VK_SUBGROUP_FEATURE_ARITHMETIC_BIT = 0x00000004, + VK_SUBGROUP_FEATURE_BALLOT_BIT = 0x00000008, + VK_SUBGROUP_FEATURE_SHUFFLE_BIT = 0x00000010, + VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT = 0x00000020, + VK_SUBGROUP_FEATURE_CLUSTERED_BIT = 0x00000040, + VK_SUBGROUP_FEATURE_QUAD_BIT = 0x00000080, + VK_SUBGROUP_FEATURE_PARTITIONED_BIT_NV = 0x00000100, + VK_SUBGROUP_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkSubgroupFeatureFlagBits; +typedef VkFlags VkSubgroupFeatureFlags; + +typedef enum VkPeerMemoryFeatureFlagBits { + VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT = 0x00000001, + VK_PEER_MEMORY_FEATURE_COPY_DST_BIT = 0x00000002, + VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT = 0x00000004, + VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT = 0x00000008, + VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT_KHR = VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT, + VK_PEER_MEMORY_FEATURE_COPY_DST_BIT_KHR = VK_PEER_MEMORY_FEATURE_COPY_DST_BIT, + VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT_KHR = VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT, + VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT_KHR = VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT, + VK_PEER_MEMORY_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkPeerMemoryFeatureFlagBits; +typedef VkFlags VkPeerMemoryFeatureFlags; + +typedef enum VkMemoryAllocateFlagBits { + VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT = 0x00000001, + VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT = 0x00000002, + VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT = 0x00000004, + VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT_KHR = VK_MEMORY_ALLOCATE_DEVICE_MASK_BIT, + VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT, + VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT, + VK_MEMORY_ALLOCATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkMemoryAllocateFlagBits; +typedef VkFlags VkMemoryAllocateFlags; +typedef VkFlags VkCommandPoolTrimFlags; +typedef VkFlags VkDescriptorUpdateTemplateCreateFlags; + +typedef enum VkExternalMemoryHandleTypeFlagBits { + VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT = 0x00000001, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT = 0x00000002, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT = 0x00000004, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT = 0x00000008, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT = 0x00000010, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT = 0x00000020, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT = 0x00000040, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT = 0x00000200, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID = 0x00000400, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT = 0x00000080, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_MAPPED_FOREIGN_MEMORY_BIT_EXT = 0x00000100, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_ZIRCON_VMO_BIT_FUCHSIA = 0x00000800, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_RDMA_ADDRESS_BIT_NV = 0x00001000, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_SCREEN_BUFFER_BIT_QNX = 0x00004000, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT_KHR = VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkExternalMemoryHandleTypeFlagBits; +typedef VkFlags VkExternalMemoryHandleTypeFlags; + +typedef enum VkExternalMemoryFeatureFlagBits { + VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT = 0x00000001, + VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT = 0x00000002, + VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT = 0x00000004, + VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHR = VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT, + VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT, + VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT, + VK_EXTERNAL_MEMORY_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkExternalMemoryFeatureFlagBits; +typedef VkFlags VkExternalMemoryFeatureFlags; + +typedef enum VkExternalFenceHandleTypeFlagBits { + VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT = 0x00000001, + VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT = 0x00000002, + VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT = 0x00000004, + VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT = 0x00000008, + VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR = VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT, + VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR = VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT, + VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR = VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT, + VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR = VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT, + VK_EXTERNAL_FENCE_HANDLE_TYPE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkExternalFenceHandleTypeFlagBits; +typedef VkFlags VkExternalFenceHandleTypeFlags; + +typedef enum VkExternalFenceFeatureFlagBits { + VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT = 0x00000001, + VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT = 0x00000002, + VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT_KHR = VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT, + VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT_KHR = VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT, + VK_EXTERNAL_FENCE_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkExternalFenceFeatureFlagBits; +typedef VkFlags VkExternalFenceFeatureFlags; + +typedef enum VkFenceImportFlagBits { + VK_FENCE_IMPORT_TEMPORARY_BIT = 0x00000001, + VK_FENCE_IMPORT_TEMPORARY_BIT_KHR = VK_FENCE_IMPORT_TEMPORARY_BIT, + VK_FENCE_IMPORT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkFenceImportFlagBits; +typedef VkFlags VkFenceImportFlags; + +typedef enum VkSemaphoreImportFlagBits { + VK_SEMAPHORE_IMPORT_TEMPORARY_BIT = 0x00000001, + VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT, + VK_SEMAPHORE_IMPORT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkSemaphoreImportFlagBits; +typedef VkFlags VkSemaphoreImportFlags; + +typedef enum VkExternalSemaphoreHandleTypeFlagBits { + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT = 0x00000001, + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT = 0x00000002, + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT = 0x00000004, + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT = 0x00000008, + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT = 0x00000010, + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_ZIRCON_EVENT_BIT_FUCHSIA = 0x00000080, + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D11_FENCE_BIT = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT, + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT, + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT, + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT, + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT_KHR = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT, + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT_KHR = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT, + VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkExternalSemaphoreHandleTypeFlagBits; +typedef VkFlags VkExternalSemaphoreHandleTypeFlags; + +typedef enum VkExternalSemaphoreFeatureFlagBits { + VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT = 0x00000001, + VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT = 0x00000002, + VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT_KHR = VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT, + VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT_KHR = VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT, + VK_EXTERNAL_SEMAPHORE_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkExternalSemaphoreFeatureFlagBits; +typedef VkFlags VkExternalSemaphoreFeatureFlags; +typedef struct VkPhysicalDeviceSubgroupProperties { + VkStructureType sType; + void* pNext; + uint32_t subgroupSize; + VkShaderStageFlags supportedStages; + VkSubgroupFeatureFlags supportedOperations; + VkBool32 quadOperationsInAllStages; +} VkPhysicalDeviceSubgroupProperties; + +typedef struct VkBindBufferMemoryInfo { + VkStructureType sType; + const void* pNext; + VkBuffer buffer; + VkDeviceMemory memory; + VkDeviceSize memoryOffset; +} VkBindBufferMemoryInfo; + +typedef struct VkBindImageMemoryInfo { + VkStructureType sType; + const void* pNext; + VkImage image; + VkDeviceMemory memory; + VkDeviceSize memoryOffset; +} VkBindImageMemoryInfo; + +typedef struct VkPhysicalDevice16BitStorageFeatures { + VkStructureType sType; + void* pNext; + VkBool32 storageBuffer16BitAccess; + VkBool32 uniformAndStorageBuffer16BitAccess; + VkBool32 storagePushConstant16; + VkBool32 storageInputOutput16; +} VkPhysicalDevice16BitStorageFeatures; + +typedef struct VkMemoryDedicatedRequirements { + VkStructureType sType; + void* pNext; + VkBool32 prefersDedicatedAllocation; + VkBool32 requiresDedicatedAllocation; +} VkMemoryDedicatedRequirements; + +typedef struct VkMemoryDedicatedAllocateInfo { + VkStructureType sType; + const void* pNext; + VkImage image; + VkBuffer buffer; +} VkMemoryDedicatedAllocateInfo; + +typedef struct VkMemoryAllocateFlagsInfo { + VkStructureType sType; + const void* pNext; + VkMemoryAllocateFlags flags; + uint32_t deviceMask; +} VkMemoryAllocateFlagsInfo; + +typedef struct VkDeviceGroupRenderPassBeginInfo { + VkStructureType sType; + const void* pNext; + uint32_t deviceMask; + uint32_t deviceRenderAreaCount; + const VkRect2D* pDeviceRenderAreas; +} VkDeviceGroupRenderPassBeginInfo; + +typedef struct VkDeviceGroupCommandBufferBeginInfo { + VkStructureType sType; + const void* pNext; + uint32_t deviceMask; +} VkDeviceGroupCommandBufferBeginInfo; + +typedef struct VkDeviceGroupSubmitInfo { + VkStructureType sType; + const void* pNext; + uint32_t waitSemaphoreCount; + const uint32_t* pWaitSemaphoreDeviceIndices; + uint32_t commandBufferCount; + const uint32_t* pCommandBufferDeviceMasks; + uint32_t signalSemaphoreCount; + const uint32_t* pSignalSemaphoreDeviceIndices; +} VkDeviceGroupSubmitInfo; + +typedef struct VkDeviceGroupBindSparseInfo { + VkStructureType sType; + const void* pNext; + uint32_t resourceDeviceIndex; + uint32_t memoryDeviceIndex; +} VkDeviceGroupBindSparseInfo; + +typedef struct VkBindBufferMemoryDeviceGroupInfo { + VkStructureType sType; + const void* pNext; + uint32_t deviceIndexCount; + const uint32_t* pDeviceIndices; +} VkBindBufferMemoryDeviceGroupInfo; + +typedef struct VkBindImageMemoryDeviceGroupInfo { + VkStructureType sType; + const void* pNext; + uint32_t deviceIndexCount; + const uint32_t* pDeviceIndices; + uint32_t splitInstanceBindRegionCount; + const VkRect2D* pSplitInstanceBindRegions; +} VkBindImageMemoryDeviceGroupInfo; + +typedef struct VkPhysicalDeviceGroupProperties { + VkStructureType sType; + void* pNext; + uint32_t physicalDeviceCount; + VkPhysicalDevice physicalDevices[VK_MAX_DEVICE_GROUP_SIZE]; + VkBool32 subsetAllocation; +} VkPhysicalDeviceGroupProperties; + +typedef struct VkDeviceGroupDeviceCreateInfo { + VkStructureType sType; + const void* pNext; + uint32_t physicalDeviceCount; + const VkPhysicalDevice* pPhysicalDevices; +} VkDeviceGroupDeviceCreateInfo; + +typedef struct VkBufferMemoryRequirementsInfo2 { + VkStructureType sType; + const void* pNext; + VkBuffer buffer; +} VkBufferMemoryRequirementsInfo2; + +typedef struct VkImageMemoryRequirementsInfo2 { + VkStructureType sType; + const void* pNext; + VkImage image; +} VkImageMemoryRequirementsInfo2; + +typedef struct VkImageSparseMemoryRequirementsInfo2 { + VkStructureType sType; + const void* pNext; + VkImage image; +} VkImageSparseMemoryRequirementsInfo2; + +typedef struct VkMemoryRequirements2 { + VkStructureType sType; + void* pNext; + VkMemoryRequirements memoryRequirements; +} VkMemoryRequirements2; + +typedef struct VkSparseImageMemoryRequirements2 { + VkStructureType sType; + void* pNext; + VkSparseImageMemoryRequirements memoryRequirements; +} VkSparseImageMemoryRequirements2; + +typedef struct VkPhysicalDeviceFeatures2 { + VkStructureType sType; + void* pNext; + VkPhysicalDeviceFeatures features; +} VkPhysicalDeviceFeatures2; + +typedef struct VkPhysicalDeviceProperties2 { + VkStructureType sType; + void* pNext; + VkPhysicalDeviceProperties properties; +} VkPhysicalDeviceProperties2; + +typedef struct VkFormatProperties2 { + VkStructureType sType; + void* pNext; + VkFormatProperties formatProperties; +} VkFormatProperties2; + +typedef struct VkImageFormatProperties2 { + VkStructureType sType; + void* pNext; + VkImageFormatProperties imageFormatProperties; +} VkImageFormatProperties2; + +typedef struct VkPhysicalDeviceImageFormatInfo2 { + VkStructureType sType; + const void* pNext; + VkFormat format; + VkImageType type; + VkImageTiling tiling; + VkImageUsageFlags usage; + VkImageCreateFlags flags; +} VkPhysicalDeviceImageFormatInfo2; + +typedef struct VkQueueFamilyProperties2 { + VkStructureType sType; + void* pNext; + VkQueueFamilyProperties queueFamilyProperties; +} VkQueueFamilyProperties2; + +typedef struct VkPhysicalDeviceMemoryProperties2 { + VkStructureType sType; + void* pNext; + VkPhysicalDeviceMemoryProperties memoryProperties; +} VkPhysicalDeviceMemoryProperties2; + +typedef struct VkSparseImageFormatProperties2 { + VkStructureType sType; + void* pNext; + VkSparseImageFormatProperties properties; +} VkSparseImageFormatProperties2; + +typedef struct VkPhysicalDeviceSparseImageFormatInfo2 { + VkStructureType sType; + const void* pNext; + VkFormat format; + VkImageType type; + VkSampleCountFlagBits samples; + VkImageUsageFlags usage; + VkImageTiling tiling; +} VkPhysicalDeviceSparseImageFormatInfo2; + +typedef struct VkPhysicalDevicePointClippingProperties { + VkStructureType sType; + void* pNext; + VkPointClippingBehavior pointClippingBehavior; +} VkPhysicalDevicePointClippingProperties; + +typedef struct VkInputAttachmentAspectReference { + uint32_t subpass; + uint32_t inputAttachmentIndex; + VkImageAspectFlags aspectMask; +} VkInputAttachmentAspectReference; + +typedef struct VkRenderPassInputAttachmentAspectCreateInfo { + VkStructureType sType; + const void* pNext; + uint32_t aspectReferenceCount; + const VkInputAttachmentAspectReference* pAspectReferences; +} VkRenderPassInputAttachmentAspectCreateInfo; + +typedef struct VkImageViewUsageCreateInfo { + VkStructureType sType; + const void* pNext; + VkImageUsageFlags usage; +} VkImageViewUsageCreateInfo; + +typedef struct VkPipelineTessellationDomainOriginStateCreateInfo { + VkStructureType sType; + const void* pNext; + VkTessellationDomainOrigin domainOrigin; +} VkPipelineTessellationDomainOriginStateCreateInfo; + +typedef struct VkRenderPassMultiviewCreateInfo { + VkStructureType sType; + const void* pNext; + uint32_t subpassCount; + const uint32_t* pViewMasks; + uint32_t dependencyCount; + const int32_t* pViewOffsets; + uint32_t correlationMaskCount; + const uint32_t* pCorrelationMasks; +} VkRenderPassMultiviewCreateInfo; + +typedef struct VkPhysicalDeviceMultiviewFeatures { + VkStructureType sType; + void* pNext; + VkBool32 multiview; + VkBool32 multiviewGeometryShader; + VkBool32 multiviewTessellationShader; +} VkPhysicalDeviceMultiviewFeatures; + +typedef struct VkPhysicalDeviceMultiviewProperties { + VkStructureType sType; + void* pNext; + uint32_t maxMultiviewViewCount; + uint32_t maxMultiviewInstanceIndex; +} VkPhysicalDeviceMultiviewProperties; + +typedef struct VkPhysicalDeviceVariablePointersFeatures { + VkStructureType sType; + void* pNext; + VkBool32 variablePointersStorageBuffer; + VkBool32 variablePointers; +} VkPhysicalDeviceVariablePointersFeatures; + +typedef VkPhysicalDeviceVariablePointersFeatures VkPhysicalDeviceVariablePointerFeatures; + +typedef struct VkPhysicalDeviceProtectedMemoryFeatures { + VkStructureType sType; + void* pNext; + VkBool32 protectedMemory; +} VkPhysicalDeviceProtectedMemoryFeatures; + +typedef struct VkPhysicalDeviceProtectedMemoryProperties { + VkStructureType sType; + void* pNext; + VkBool32 protectedNoFault; +} VkPhysicalDeviceProtectedMemoryProperties; + +typedef struct VkDeviceQueueInfo2 { + VkStructureType sType; + const void* pNext; + VkDeviceQueueCreateFlags flags; + uint32_t queueFamilyIndex; + uint32_t queueIndex; +} VkDeviceQueueInfo2; + +typedef struct VkProtectedSubmitInfo { + VkStructureType sType; + const void* pNext; + VkBool32 protectedSubmit; +} VkProtectedSubmitInfo; + +typedef struct VkSamplerYcbcrConversionCreateInfo { + VkStructureType sType; + const void* pNext; + VkFormat format; + VkSamplerYcbcrModelConversion ycbcrModel; + VkSamplerYcbcrRange ycbcrRange; + VkComponentMapping components; + VkChromaLocation xChromaOffset; + VkChromaLocation yChromaOffset; + VkFilter chromaFilter; + VkBool32 forceExplicitReconstruction; +} VkSamplerYcbcrConversionCreateInfo; + +typedef struct VkSamplerYcbcrConversionInfo { + VkStructureType sType; + const void* pNext; + VkSamplerYcbcrConversion conversion; +} VkSamplerYcbcrConversionInfo; + +typedef struct VkBindImagePlaneMemoryInfo { + VkStructureType sType; + const void* pNext; + VkImageAspectFlagBits planeAspect; +} VkBindImagePlaneMemoryInfo; + +typedef struct VkImagePlaneMemoryRequirementsInfo { + VkStructureType sType; + const void* pNext; + VkImageAspectFlagBits planeAspect; +} VkImagePlaneMemoryRequirementsInfo; + +typedef struct VkPhysicalDeviceSamplerYcbcrConversionFeatures { + VkStructureType sType; + void* pNext; + VkBool32 samplerYcbcrConversion; +} VkPhysicalDeviceSamplerYcbcrConversionFeatures; + +typedef struct VkSamplerYcbcrConversionImageFormatProperties { + VkStructureType sType; + void* pNext; + uint32_t combinedImageSamplerDescriptorCount; +} VkSamplerYcbcrConversionImageFormatProperties; + +typedef struct VkDescriptorUpdateTemplateEntry { + uint32_t dstBinding; + uint32_t dstArrayElement; + uint32_t descriptorCount; + VkDescriptorType descriptorType; + size_t offset; + size_t stride; +} VkDescriptorUpdateTemplateEntry; + +typedef struct VkDescriptorUpdateTemplateCreateInfo { + VkStructureType sType; + const void* pNext; + VkDescriptorUpdateTemplateCreateFlags flags; + uint32_t descriptorUpdateEntryCount; + const VkDescriptorUpdateTemplateEntry* pDescriptorUpdateEntries; + VkDescriptorUpdateTemplateType templateType; + VkDescriptorSetLayout descriptorSetLayout; + VkPipelineBindPoint pipelineBindPoint; + VkPipelineLayout pipelineLayout; + uint32_t set; +} VkDescriptorUpdateTemplateCreateInfo; + +typedef struct VkExternalMemoryProperties { + VkExternalMemoryFeatureFlags externalMemoryFeatures; + VkExternalMemoryHandleTypeFlags exportFromImportedHandleTypes; + VkExternalMemoryHandleTypeFlags compatibleHandleTypes; +} VkExternalMemoryProperties; + +typedef struct VkPhysicalDeviceExternalImageFormatInfo { + VkStructureType sType; + const void* pNext; + VkExternalMemoryHandleTypeFlagBits handleType; +} VkPhysicalDeviceExternalImageFormatInfo; + +typedef struct VkExternalImageFormatProperties { + VkStructureType sType; + void* pNext; + VkExternalMemoryProperties externalMemoryProperties; +} VkExternalImageFormatProperties; + +typedef struct VkPhysicalDeviceExternalBufferInfo { + VkStructureType sType; + const void* pNext; + VkBufferCreateFlags flags; + VkBufferUsageFlags usage; + VkExternalMemoryHandleTypeFlagBits handleType; +} VkPhysicalDeviceExternalBufferInfo; + +typedef struct VkExternalBufferProperties { + VkStructureType sType; + void* pNext; + VkExternalMemoryProperties externalMemoryProperties; +} VkExternalBufferProperties; + +typedef struct VkPhysicalDeviceIDProperties { + VkStructureType sType; + void* pNext; + uint8_t deviceUUID[VK_UUID_SIZE]; + uint8_t driverUUID[VK_UUID_SIZE]; + uint8_t deviceLUID[VK_LUID_SIZE]; + uint32_t deviceNodeMask; + VkBool32 deviceLUIDValid; +} VkPhysicalDeviceIDProperties; + +typedef struct VkExternalMemoryImageCreateInfo { + VkStructureType sType; + const void* pNext; + VkExternalMemoryHandleTypeFlags handleTypes; +} VkExternalMemoryImageCreateInfo; + +typedef struct VkExternalMemoryBufferCreateInfo { + VkStructureType sType; + const void* pNext; + VkExternalMemoryHandleTypeFlags handleTypes; +} VkExternalMemoryBufferCreateInfo; + +typedef struct VkExportMemoryAllocateInfo { + VkStructureType sType; + const void* pNext; + VkExternalMemoryHandleTypeFlags handleTypes; +} VkExportMemoryAllocateInfo; + +typedef struct VkPhysicalDeviceExternalFenceInfo { + VkStructureType sType; + const void* pNext; + VkExternalFenceHandleTypeFlagBits handleType; +} VkPhysicalDeviceExternalFenceInfo; + +typedef struct VkExternalFenceProperties { + VkStructureType sType; + void* pNext; + VkExternalFenceHandleTypeFlags exportFromImportedHandleTypes; + VkExternalFenceHandleTypeFlags compatibleHandleTypes; + VkExternalFenceFeatureFlags externalFenceFeatures; +} VkExternalFenceProperties; + +typedef struct VkExportFenceCreateInfo { + VkStructureType sType; + const void* pNext; + VkExternalFenceHandleTypeFlags handleTypes; +} VkExportFenceCreateInfo; + +typedef struct VkExportSemaphoreCreateInfo { + VkStructureType sType; + const void* pNext; + VkExternalSemaphoreHandleTypeFlags handleTypes; +} VkExportSemaphoreCreateInfo; + +typedef struct VkPhysicalDeviceExternalSemaphoreInfo { + VkStructureType sType; + const void* pNext; + VkExternalSemaphoreHandleTypeFlagBits handleType; +} VkPhysicalDeviceExternalSemaphoreInfo; + +typedef struct VkExternalSemaphoreProperties { + VkStructureType sType; + void* pNext; + VkExternalSemaphoreHandleTypeFlags exportFromImportedHandleTypes; + VkExternalSemaphoreHandleTypeFlags compatibleHandleTypes; + VkExternalSemaphoreFeatureFlags externalSemaphoreFeatures; +} VkExternalSemaphoreProperties; + +typedef struct VkPhysicalDeviceMaintenance3Properties { + VkStructureType sType; + void* pNext; + uint32_t maxPerSetDescriptors; + VkDeviceSize maxMemoryAllocationSize; +} VkPhysicalDeviceMaintenance3Properties; + +typedef struct VkDescriptorSetLayoutSupport { + VkStructureType sType; + void* pNext; + VkBool32 supported; +} VkDescriptorSetLayoutSupport; + +typedef struct VkPhysicalDeviceShaderDrawParametersFeatures { + VkStructureType sType; + void* pNext; + VkBool32 shaderDrawParameters; +} VkPhysicalDeviceShaderDrawParametersFeatures; + +typedef VkPhysicalDeviceShaderDrawParametersFeatures VkPhysicalDeviceShaderDrawParameterFeatures; + +typedef VkResult (VKAPI_PTR *PFN_vkEnumerateInstanceVersion)(uint32_t* pApiVersion); +typedef VkResult (VKAPI_PTR *PFN_vkBindBufferMemory2)(VkDevice device, uint32_t bindInfoCount, const VkBindBufferMemoryInfo* pBindInfos); +typedef VkResult (VKAPI_PTR *PFN_vkBindImageMemory2)(VkDevice device, uint32_t bindInfoCount, const VkBindImageMemoryInfo* pBindInfos); +typedef void (VKAPI_PTR *PFN_vkGetDeviceGroupPeerMemoryFeatures)(VkDevice device, uint32_t heapIndex, uint32_t localDeviceIndex, uint32_t remoteDeviceIndex, VkPeerMemoryFeatureFlags* pPeerMemoryFeatures); +typedef void (VKAPI_PTR *PFN_vkCmdSetDeviceMask)(VkCommandBuffer commandBuffer, uint32_t deviceMask); +typedef void (VKAPI_PTR *PFN_vkCmdDispatchBase)(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY, uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ); +typedef VkResult (VKAPI_PTR *PFN_vkEnumeratePhysicalDeviceGroups)(VkInstance instance, uint32_t* pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties); +typedef void (VKAPI_PTR *PFN_vkGetImageMemoryRequirements2)(VkDevice device, const VkImageMemoryRequirementsInfo2* pInfo, VkMemoryRequirements2* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetBufferMemoryRequirements2)(VkDevice device, const VkBufferMemoryRequirementsInfo2* pInfo, VkMemoryRequirements2* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetImageSparseMemoryRequirements2)(VkDevice device, const VkImageSparseMemoryRequirementsInfo2* pInfo, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2* pSparseMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFeatures2)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures2* pFeatures); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceProperties2)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2* pProperties); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFormatProperties2)(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties2* pFormatProperties); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceImageFormatProperties2)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo, VkImageFormatProperties2* pImageFormatProperties); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceQueueFamilyProperties2)(VkPhysicalDevice physicalDevice, uint32_t* pQueueFamilyPropertyCount, VkQueueFamilyProperties2* pQueueFamilyProperties); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceMemoryProperties2)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties2* pMemoryProperties); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceSparseImageFormatProperties2)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2* pFormatInfo, uint32_t* pPropertyCount, VkSparseImageFormatProperties2* pProperties); +typedef void (VKAPI_PTR *PFN_vkTrimCommandPool)(VkDevice device, VkCommandPool commandPool, VkCommandPoolTrimFlags flags); +typedef void (VKAPI_PTR *PFN_vkGetDeviceQueue2)(VkDevice device, const VkDeviceQueueInfo2* pQueueInfo, VkQueue* pQueue); +typedef VkResult (VKAPI_PTR *PFN_vkCreateSamplerYcbcrConversion)(VkDevice device, const VkSamplerYcbcrConversionCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSamplerYcbcrConversion* pYcbcrConversion); +typedef void (VKAPI_PTR *PFN_vkDestroySamplerYcbcrConversion)(VkDevice device, VkSamplerYcbcrConversion ycbcrConversion, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkCreateDescriptorUpdateTemplate)(VkDevice device, const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate); +typedef void (VKAPI_PTR *PFN_vkDestroyDescriptorUpdateTemplate)(VkDevice device, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const VkAllocationCallbacks* pAllocator); +typedef void (VKAPI_PTR *PFN_vkUpdateDescriptorSetWithTemplate)(VkDevice device, VkDescriptorSet descriptorSet, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const void* pData); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalBufferProperties)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo, VkExternalBufferProperties* pExternalBufferProperties); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalFenceProperties)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo, VkExternalFenceProperties* pExternalFenceProperties); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalSemaphoreProperties)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo, VkExternalSemaphoreProperties* pExternalSemaphoreProperties); +typedef void (VKAPI_PTR *PFN_vkGetDescriptorSetLayoutSupport)(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, VkDescriptorSetLayoutSupport* pSupport); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceVersion( + uint32_t* pApiVersion); + +VKAPI_ATTR VkResult VKAPI_CALL vkBindBufferMemory2( + VkDevice device, + uint32_t bindInfoCount, + const VkBindBufferMemoryInfo* pBindInfos); + +VKAPI_ATTR VkResult VKAPI_CALL vkBindImageMemory2( + VkDevice device, + uint32_t bindInfoCount, + const VkBindImageMemoryInfo* pBindInfos); + +VKAPI_ATTR void VKAPI_CALL vkGetDeviceGroupPeerMemoryFeatures( + VkDevice device, + uint32_t heapIndex, + uint32_t localDeviceIndex, + uint32_t remoteDeviceIndex, + VkPeerMemoryFeatureFlags* pPeerMemoryFeatures); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDeviceMask( + VkCommandBuffer commandBuffer, + uint32_t deviceMask); + +VKAPI_ATTR void VKAPI_CALL vkCmdDispatchBase( + VkCommandBuffer commandBuffer, + uint32_t baseGroupX, + uint32_t baseGroupY, + uint32_t baseGroupZ, + uint32_t groupCountX, + uint32_t groupCountY, + uint32_t groupCountZ); + +VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDeviceGroups( + VkInstance instance, + uint32_t* pPhysicalDeviceGroupCount, + VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties); + +VKAPI_ATTR void VKAPI_CALL vkGetImageMemoryRequirements2( + VkDevice device, + const VkImageMemoryRequirementsInfo2* pInfo, + VkMemoryRequirements2* pMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkGetBufferMemoryRequirements2( + VkDevice device, + const VkBufferMemoryRequirementsInfo2* pInfo, + VkMemoryRequirements2* pMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkGetImageSparseMemoryRequirements2( + VkDevice device, + const VkImageSparseMemoryRequirementsInfo2* pInfo, + uint32_t* pSparseMemoryRequirementCount, + VkSparseImageMemoryRequirements2* pSparseMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFeatures2( + VkPhysicalDevice physicalDevice, + VkPhysicalDeviceFeatures2* pFeatures); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties2( + VkPhysicalDevice physicalDevice, + VkPhysicalDeviceProperties2* pProperties); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFormatProperties2( + VkPhysicalDevice physicalDevice, + VkFormat format, + VkFormatProperties2* pFormatProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceImageFormatProperties2( + VkPhysicalDevice physicalDevice, + const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo, + VkImageFormatProperties2* pImageFormatProperties); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyProperties2( + VkPhysicalDevice physicalDevice, + uint32_t* pQueueFamilyPropertyCount, + VkQueueFamilyProperties2* pQueueFamilyProperties); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties2( + VkPhysicalDevice physicalDevice, + VkPhysicalDeviceMemoryProperties2* pMemoryProperties); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceSparseImageFormatProperties2( + VkPhysicalDevice physicalDevice, + const VkPhysicalDeviceSparseImageFormatInfo2* pFormatInfo, + uint32_t* pPropertyCount, + VkSparseImageFormatProperties2* pProperties); + +VKAPI_ATTR void VKAPI_CALL vkTrimCommandPool( + VkDevice device, + VkCommandPool commandPool, + VkCommandPoolTrimFlags flags); + +VKAPI_ATTR void VKAPI_CALL vkGetDeviceQueue2( + VkDevice device, + const VkDeviceQueueInfo2* pQueueInfo, + VkQueue* pQueue); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateSamplerYcbcrConversion( + VkDevice device, + const VkSamplerYcbcrConversionCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSamplerYcbcrConversion* pYcbcrConversion); + +VKAPI_ATTR void VKAPI_CALL vkDestroySamplerYcbcrConversion( + VkDevice device, + VkSamplerYcbcrConversion ycbcrConversion, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorUpdateTemplate( + VkDevice device, + const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate); + +VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorUpdateTemplate( + VkDevice device, + VkDescriptorUpdateTemplate descriptorUpdateTemplate, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR void VKAPI_CALL vkUpdateDescriptorSetWithTemplate( + VkDevice device, + VkDescriptorSet descriptorSet, + VkDescriptorUpdateTemplate descriptorUpdateTemplate, + const void* pData); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalBufferProperties( + VkPhysicalDevice physicalDevice, + const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo, + VkExternalBufferProperties* pExternalBufferProperties); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalFenceProperties( + VkPhysicalDevice physicalDevice, + const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo, + VkExternalFenceProperties* pExternalFenceProperties); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalSemaphoreProperties( + VkPhysicalDevice physicalDevice, + const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo, + VkExternalSemaphoreProperties* pExternalSemaphoreProperties); + +VKAPI_ATTR void VKAPI_CALL vkGetDescriptorSetLayoutSupport( + VkDevice device, + const VkDescriptorSetLayoutCreateInfo* pCreateInfo, + VkDescriptorSetLayoutSupport* pSupport); +#endif + + +// VK_VERSION_1_2 is a preprocessor guard. Do not pass it to API calls. +#define VK_VERSION_1_2 1 +// Vulkan 1.2 version number +#define VK_API_VERSION_1_2 VK_MAKE_API_VERSION(0, 1, 2, 0)// Patch version should always be set to 0 + +#define VK_MAX_DRIVER_NAME_SIZE 256U +#define VK_MAX_DRIVER_INFO_SIZE 256U + +typedef enum VkDriverId { + VK_DRIVER_ID_AMD_PROPRIETARY = 1, + VK_DRIVER_ID_AMD_OPEN_SOURCE = 2, + VK_DRIVER_ID_MESA_RADV = 3, + VK_DRIVER_ID_NVIDIA_PROPRIETARY = 4, + VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS = 5, + VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA = 6, + VK_DRIVER_ID_IMAGINATION_PROPRIETARY = 7, + VK_DRIVER_ID_QUALCOMM_PROPRIETARY = 8, + VK_DRIVER_ID_ARM_PROPRIETARY = 9, + VK_DRIVER_ID_GOOGLE_SWIFTSHADER = 10, + VK_DRIVER_ID_GGP_PROPRIETARY = 11, + VK_DRIVER_ID_BROADCOM_PROPRIETARY = 12, + VK_DRIVER_ID_MESA_LLVMPIPE = 13, + VK_DRIVER_ID_MOLTENVK = 14, + VK_DRIVER_ID_COREAVI_PROPRIETARY = 15, + VK_DRIVER_ID_JUICE_PROPRIETARY = 16, + VK_DRIVER_ID_VERISILICON_PROPRIETARY = 17, + VK_DRIVER_ID_MESA_TURNIP = 18, + VK_DRIVER_ID_MESA_V3DV = 19, + VK_DRIVER_ID_MESA_PANVK = 20, + VK_DRIVER_ID_SAMSUNG_PROPRIETARY = 21, + VK_DRIVER_ID_MESA_VENUS = 22, + VK_DRIVER_ID_MESA_DOZEN = 23, + VK_DRIVER_ID_MESA_NVK = 24, + VK_DRIVER_ID_IMAGINATION_OPEN_SOURCE_MESA = 25, + VK_DRIVER_ID_MESA_AGXV = 26, + VK_DRIVER_ID_AMD_PROPRIETARY_KHR = VK_DRIVER_ID_AMD_PROPRIETARY, + VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR = VK_DRIVER_ID_AMD_OPEN_SOURCE, + VK_DRIVER_ID_MESA_RADV_KHR = VK_DRIVER_ID_MESA_RADV, + VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR = VK_DRIVER_ID_NVIDIA_PROPRIETARY, + VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR = VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS, + VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA_KHR = VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA, + VK_DRIVER_ID_IMAGINATION_PROPRIETARY_KHR = VK_DRIVER_ID_IMAGINATION_PROPRIETARY, + VK_DRIVER_ID_QUALCOMM_PROPRIETARY_KHR = VK_DRIVER_ID_QUALCOMM_PROPRIETARY, + VK_DRIVER_ID_ARM_PROPRIETARY_KHR = VK_DRIVER_ID_ARM_PROPRIETARY, + VK_DRIVER_ID_GOOGLE_SWIFTSHADER_KHR = VK_DRIVER_ID_GOOGLE_SWIFTSHADER, + VK_DRIVER_ID_GGP_PROPRIETARY_KHR = VK_DRIVER_ID_GGP_PROPRIETARY, + VK_DRIVER_ID_BROADCOM_PROPRIETARY_KHR = VK_DRIVER_ID_BROADCOM_PROPRIETARY, + VK_DRIVER_ID_MAX_ENUM = 0x7FFFFFFF +} VkDriverId; + +typedef enum VkShaderFloatControlsIndependence { + VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY = 0, + VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL = 1, + VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE = 2, + VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY_KHR = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY, + VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL_KHR = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL, + VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE_KHR = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE, + VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_MAX_ENUM = 0x7FFFFFFF +} VkShaderFloatControlsIndependence; + +typedef enum VkSamplerReductionMode { + VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE = 0, + VK_SAMPLER_REDUCTION_MODE_MIN = 1, + VK_SAMPLER_REDUCTION_MODE_MAX = 2, + VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_RANGECLAMP_QCOM = 1000521000, + VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT = VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE, + VK_SAMPLER_REDUCTION_MODE_MIN_EXT = VK_SAMPLER_REDUCTION_MODE_MIN, + VK_SAMPLER_REDUCTION_MODE_MAX_EXT = VK_SAMPLER_REDUCTION_MODE_MAX, + VK_SAMPLER_REDUCTION_MODE_MAX_ENUM = 0x7FFFFFFF +} VkSamplerReductionMode; + +typedef enum VkSemaphoreType { + VK_SEMAPHORE_TYPE_BINARY = 0, + VK_SEMAPHORE_TYPE_TIMELINE = 1, + VK_SEMAPHORE_TYPE_BINARY_KHR = VK_SEMAPHORE_TYPE_BINARY, + VK_SEMAPHORE_TYPE_TIMELINE_KHR = VK_SEMAPHORE_TYPE_TIMELINE, + VK_SEMAPHORE_TYPE_MAX_ENUM = 0x7FFFFFFF +} VkSemaphoreType; + +typedef enum VkResolveModeFlagBits { + VK_RESOLVE_MODE_NONE = 0, + VK_RESOLVE_MODE_SAMPLE_ZERO_BIT = 0x00000001, + VK_RESOLVE_MODE_AVERAGE_BIT = 0x00000002, + VK_RESOLVE_MODE_MIN_BIT = 0x00000004, + VK_RESOLVE_MODE_MAX_BIT = 0x00000008, + VK_RESOLVE_MODE_EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID = 0x00000010, + VK_RESOLVE_MODE_NONE_KHR = VK_RESOLVE_MODE_NONE, + VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT, + VK_RESOLVE_MODE_AVERAGE_BIT_KHR = VK_RESOLVE_MODE_AVERAGE_BIT, + VK_RESOLVE_MODE_MIN_BIT_KHR = VK_RESOLVE_MODE_MIN_BIT, + VK_RESOLVE_MODE_MAX_BIT_KHR = VK_RESOLVE_MODE_MAX_BIT, + VK_RESOLVE_MODE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkResolveModeFlagBits; +typedef VkFlags VkResolveModeFlags; + +typedef enum VkDescriptorBindingFlagBits { + VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT = 0x00000001, + VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT = 0x00000002, + VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT = 0x00000004, + VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT = 0x00000008, + VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT = VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT, + VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT_EXT = VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT, + VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT = VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT, + VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT = VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT, + VK_DESCRIPTOR_BINDING_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkDescriptorBindingFlagBits; +typedef VkFlags VkDescriptorBindingFlags; + +typedef enum VkSemaphoreWaitFlagBits { + VK_SEMAPHORE_WAIT_ANY_BIT = 0x00000001, + VK_SEMAPHORE_WAIT_ANY_BIT_KHR = VK_SEMAPHORE_WAIT_ANY_BIT, + VK_SEMAPHORE_WAIT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkSemaphoreWaitFlagBits; +typedef VkFlags VkSemaphoreWaitFlags; +typedef struct VkPhysicalDeviceVulkan11Features { + VkStructureType sType; + void* pNext; + VkBool32 storageBuffer16BitAccess; + VkBool32 uniformAndStorageBuffer16BitAccess; + VkBool32 storagePushConstant16; + VkBool32 storageInputOutput16; + VkBool32 multiview; + VkBool32 multiviewGeometryShader; + VkBool32 multiviewTessellationShader; + VkBool32 variablePointersStorageBuffer; + VkBool32 variablePointers; + VkBool32 protectedMemory; + VkBool32 samplerYcbcrConversion; + VkBool32 shaderDrawParameters; +} VkPhysicalDeviceVulkan11Features; + +typedef struct VkPhysicalDeviceVulkan11Properties { + VkStructureType sType; + void* pNext; + uint8_t deviceUUID[VK_UUID_SIZE]; + uint8_t driverUUID[VK_UUID_SIZE]; + uint8_t deviceLUID[VK_LUID_SIZE]; + uint32_t deviceNodeMask; + VkBool32 deviceLUIDValid; + uint32_t subgroupSize; + VkShaderStageFlags subgroupSupportedStages; + VkSubgroupFeatureFlags subgroupSupportedOperations; + VkBool32 subgroupQuadOperationsInAllStages; + VkPointClippingBehavior pointClippingBehavior; + uint32_t maxMultiviewViewCount; + uint32_t maxMultiviewInstanceIndex; + VkBool32 protectedNoFault; + uint32_t maxPerSetDescriptors; + VkDeviceSize maxMemoryAllocationSize; +} VkPhysicalDeviceVulkan11Properties; + +typedef struct VkPhysicalDeviceVulkan12Features { + VkStructureType sType; + void* pNext; + VkBool32 samplerMirrorClampToEdge; + VkBool32 drawIndirectCount; + VkBool32 storageBuffer8BitAccess; + VkBool32 uniformAndStorageBuffer8BitAccess; + VkBool32 storagePushConstant8; + VkBool32 shaderBufferInt64Atomics; + VkBool32 shaderSharedInt64Atomics; + VkBool32 shaderFloat16; + VkBool32 shaderInt8; + VkBool32 descriptorIndexing; + VkBool32 shaderInputAttachmentArrayDynamicIndexing; + VkBool32 shaderUniformTexelBufferArrayDynamicIndexing; + VkBool32 shaderStorageTexelBufferArrayDynamicIndexing; + VkBool32 shaderUniformBufferArrayNonUniformIndexing; + VkBool32 shaderSampledImageArrayNonUniformIndexing; + VkBool32 shaderStorageBufferArrayNonUniformIndexing; + VkBool32 shaderStorageImageArrayNonUniformIndexing; + VkBool32 shaderInputAttachmentArrayNonUniformIndexing; + VkBool32 shaderUniformTexelBufferArrayNonUniformIndexing; + VkBool32 shaderStorageTexelBufferArrayNonUniformIndexing; + VkBool32 descriptorBindingUniformBufferUpdateAfterBind; + VkBool32 descriptorBindingSampledImageUpdateAfterBind; + VkBool32 descriptorBindingStorageImageUpdateAfterBind; + VkBool32 descriptorBindingStorageBufferUpdateAfterBind; + VkBool32 descriptorBindingUniformTexelBufferUpdateAfterBind; + VkBool32 descriptorBindingStorageTexelBufferUpdateAfterBind; + VkBool32 descriptorBindingUpdateUnusedWhilePending; + VkBool32 descriptorBindingPartiallyBound; + VkBool32 descriptorBindingVariableDescriptorCount; + VkBool32 runtimeDescriptorArray; + VkBool32 samplerFilterMinmax; + VkBool32 scalarBlockLayout; + VkBool32 imagelessFramebuffer; + VkBool32 uniformBufferStandardLayout; + VkBool32 shaderSubgroupExtendedTypes; + VkBool32 separateDepthStencilLayouts; + VkBool32 hostQueryReset; + VkBool32 timelineSemaphore; + VkBool32 bufferDeviceAddress; + VkBool32 bufferDeviceAddressCaptureReplay; + VkBool32 bufferDeviceAddressMultiDevice; + VkBool32 vulkanMemoryModel; + VkBool32 vulkanMemoryModelDeviceScope; + VkBool32 vulkanMemoryModelAvailabilityVisibilityChains; + VkBool32 shaderOutputViewportIndex; + VkBool32 shaderOutputLayer; + VkBool32 subgroupBroadcastDynamicId; +} VkPhysicalDeviceVulkan12Features; + +typedef struct VkConformanceVersion { + uint8_t major; + uint8_t minor; + uint8_t subminor; + uint8_t patch; +} VkConformanceVersion; + +typedef struct VkPhysicalDeviceVulkan12Properties { + VkStructureType sType; + void* pNext; + VkDriverId driverID; + char driverName[VK_MAX_DRIVER_NAME_SIZE]; + char driverInfo[VK_MAX_DRIVER_INFO_SIZE]; + VkConformanceVersion conformanceVersion; + VkShaderFloatControlsIndependence denormBehaviorIndependence; + VkShaderFloatControlsIndependence roundingModeIndependence; + VkBool32 shaderSignedZeroInfNanPreserveFloat16; + VkBool32 shaderSignedZeroInfNanPreserveFloat32; + VkBool32 shaderSignedZeroInfNanPreserveFloat64; + VkBool32 shaderDenormPreserveFloat16; + VkBool32 shaderDenormPreserveFloat32; + VkBool32 shaderDenormPreserveFloat64; + VkBool32 shaderDenormFlushToZeroFloat16; + VkBool32 shaderDenormFlushToZeroFloat32; + VkBool32 shaderDenormFlushToZeroFloat64; + VkBool32 shaderRoundingModeRTEFloat16; + VkBool32 shaderRoundingModeRTEFloat32; + VkBool32 shaderRoundingModeRTEFloat64; + VkBool32 shaderRoundingModeRTZFloat16; + VkBool32 shaderRoundingModeRTZFloat32; + VkBool32 shaderRoundingModeRTZFloat64; + uint32_t maxUpdateAfterBindDescriptorsInAllPools; + VkBool32 shaderUniformBufferArrayNonUniformIndexingNative; + VkBool32 shaderSampledImageArrayNonUniformIndexingNative; + VkBool32 shaderStorageBufferArrayNonUniformIndexingNative; + VkBool32 shaderStorageImageArrayNonUniformIndexingNative; + VkBool32 shaderInputAttachmentArrayNonUniformIndexingNative; + VkBool32 robustBufferAccessUpdateAfterBind; + VkBool32 quadDivergentImplicitLod; + uint32_t maxPerStageDescriptorUpdateAfterBindSamplers; + uint32_t maxPerStageDescriptorUpdateAfterBindUniformBuffers; + uint32_t maxPerStageDescriptorUpdateAfterBindStorageBuffers; + uint32_t maxPerStageDescriptorUpdateAfterBindSampledImages; + uint32_t maxPerStageDescriptorUpdateAfterBindStorageImages; + uint32_t maxPerStageDescriptorUpdateAfterBindInputAttachments; + uint32_t maxPerStageUpdateAfterBindResources; + uint32_t maxDescriptorSetUpdateAfterBindSamplers; + uint32_t maxDescriptorSetUpdateAfterBindUniformBuffers; + uint32_t maxDescriptorSetUpdateAfterBindUniformBuffersDynamic; + uint32_t maxDescriptorSetUpdateAfterBindStorageBuffers; + uint32_t maxDescriptorSetUpdateAfterBindStorageBuffersDynamic; + uint32_t maxDescriptorSetUpdateAfterBindSampledImages; + uint32_t maxDescriptorSetUpdateAfterBindStorageImages; + uint32_t maxDescriptorSetUpdateAfterBindInputAttachments; + VkResolveModeFlags supportedDepthResolveModes; + VkResolveModeFlags supportedStencilResolveModes; + VkBool32 independentResolveNone; + VkBool32 independentResolve; + VkBool32 filterMinmaxSingleComponentFormats; + VkBool32 filterMinmaxImageComponentMapping; + uint64_t maxTimelineSemaphoreValueDifference; + VkSampleCountFlags framebufferIntegerColorSampleCounts; +} VkPhysicalDeviceVulkan12Properties; + +typedef struct VkImageFormatListCreateInfo { + VkStructureType sType; + const void* pNext; + uint32_t viewFormatCount; + const VkFormat* pViewFormats; +} VkImageFormatListCreateInfo; + +typedef struct VkAttachmentDescription2 { + VkStructureType sType; + const void* pNext; + VkAttachmentDescriptionFlags flags; + VkFormat format; + VkSampleCountFlagBits samples; + VkAttachmentLoadOp loadOp; + VkAttachmentStoreOp storeOp; + VkAttachmentLoadOp stencilLoadOp; + VkAttachmentStoreOp stencilStoreOp; + VkImageLayout initialLayout; + VkImageLayout finalLayout; +} VkAttachmentDescription2; + +typedef struct VkAttachmentReference2 { + VkStructureType sType; + const void* pNext; + uint32_t attachment; + VkImageLayout layout; + VkImageAspectFlags aspectMask; +} VkAttachmentReference2; + +typedef struct VkSubpassDescription2 { + VkStructureType sType; + const void* pNext; + VkSubpassDescriptionFlags flags; + VkPipelineBindPoint pipelineBindPoint; + uint32_t viewMask; + uint32_t inputAttachmentCount; + const VkAttachmentReference2* pInputAttachments; + uint32_t colorAttachmentCount; + const VkAttachmentReference2* pColorAttachments; + const VkAttachmentReference2* pResolveAttachments; + const VkAttachmentReference2* pDepthStencilAttachment; + uint32_t preserveAttachmentCount; + const uint32_t* pPreserveAttachments; +} VkSubpassDescription2; + +typedef struct VkSubpassDependency2 { + VkStructureType sType; + const void* pNext; + uint32_t srcSubpass; + uint32_t dstSubpass; + VkPipelineStageFlags srcStageMask; + VkPipelineStageFlags dstStageMask; + VkAccessFlags srcAccessMask; + VkAccessFlags dstAccessMask; + VkDependencyFlags dependencyFlags; + int32_t viewOffset; +} VkSubpassDependency2; + +typedef struct VkRenderPassCreateInfo2 { + VkStructureType sType; + const void* pNext; + VkRenderPassCreateFlags flags; + uint32_t attachmentCount; + const VkAttachmentDescription2* pAttachments; + uint32_t subpassCount; + const VkSubpassDescription2* pSubpasses; + uint32_t dependencyCount; + const VkSubpassDependency2* pDependencies; + uint32_t correlatedViewMaskCount; + const uint32_t* pCorrelatedViewMasks; +} VkRenderPassCreateInfo2; + +typedef struct VkSubpassBeginInfo { + VkStructureType sType; + const void* pNext; + VkSubpassContents contents; +} VkSubpassBeginInfo; + +typedef struct VkSubpassEndInfo { + VkStructureType sType; + const void* pNext; +} VkSubpassEndInfo; + +typedef struct VkPhysicalDevice8BitStorageFeatures { + VkStructureType sType; + void* pNext; + VkBool32 storageBuffer8BitAccess; + VkBool32 uniformAndStorageBuffer8BitAccess; + VkBool32 storagePushConstant8; +} VkPhysicalDevice8BitStorageFeatures; + +typedef struct VkPhysicalDeviceDriverProperties { + VkStructureType sType; + void* pNext; + VkDriverId driverID; + char driverName[VK_MAX_DRIVER_NAME_SIZE]; + char driverInfo[VK_MAX_DRIVER_INFO_SIZE]; + VkConformanceVersion conformanceVersion; +} VkPhysicalDeviceDriverProperties; + +typedef struct VkPhysicalDeviceShaderAtomicInt64Features { + VkStructureType sType; + void* pNext; + VkBool32 shaderBufferInt64Atomics; + VkBool32 shaderSharedInt64Atomics; +} VkPhysicalDeviceShaderAtomicInt64Features; + +typedef struct VkPhysicalDeviceShaderFloat16Int8Features { + VkStructureType sType; + void* pNext; + VkBool32 shaderFloat16; + VkBool32 shaderInt8; +} VkPhysicalDeviceShaderFloat16Int8Features; + +typedef struct VkPhysicalDeviceFloatControlsProperties { + VkStructureType sType; + void* pNext; + VkShaderFloatControlsIndependence denormBehaviorIndependence; + VkShaderFloatControlsIndependence roundingModeIndependence; + VkBool32 shaderSignedZeroInfNanPreserveFloat16; + VkBool32 shaderSignedZeroInfNanPreserveFloat32; + VkBool32 shaderSignedZeroInfNanPreserveFloat64; + VkBool32 shaderDenormPreserveFloat16; + VkBool32 shaderDenormPreserveFloat32; + VkBool32 shaderDenormPreserveFloat64; + VkBool32 shaderDenormFlushToZeroFloat16; + VkBool32 shaderDenormFlushToZeroFloat32; + VkBool32 shaderDenormFlushToZeroFloat64; + VkBool32 shaderRoundingModeRTEFloat16; + VkBool32 shaderRoundingModeRTEFloat32; + VkBool32 shaderRoundingModeRTEFloat64; + VkBool32 shaderRoundingModeRTZFloat16; + VkBool32 shaderRoundingModeRTZFloat32; + VkBool32 shaderRoundingModeRTZFloat64; +} VkPhysicalDeviceFloatControlsProperties; + +typedef struct VkDescriptorSetLayoutBindingFlagsCreateInfo { + VkStructureType sType; + const void* pNext; + uint32_t bindingCount; + const VkDescriptorBindingFlags* pBindingFlags; +} VkDescriptorSetLayoutBindingFlagsCreateInfo; + +typedef struct VkPhysicalDeviceDescriptorIndexingFeatures { + VkStructureType sType; + void* pNext; + VkBool32 shaderInputAttachmentArrayDynamicIndexing; + VkBool32 shaderUniformTexelBufferArrayDynamicIndexing; + VkBool32 shaderStorageTexelBufferArrayDynamicIndexing; + VkBool32 shaderUniformBufferArrayNonUniformIndexing; + VkBool32 shaderSampledImageArrayNonUniformIndexing; + VkBool32 shaderStorageBufferArrayNonUniformIndexing; + VkBool32 shaderStorageImageArrayNonUniformIndexing; + VkBool32 shaderInputAttachmentArrayNonUniformIndexing; + VkBool32 shaderUniformTexelBufferArrayNonUniformIndexing; + VkBool32 shaderStorageTexelBufferArrayNonUniformIndexing; + VkBool32 descriptorBindingUniformBufferUpdateAfterBind; + VkBool32 descriptorBindingSampledImageUpdateAfterBind; + VkBool32 descriptorBindingStorageImageUpdateAfterBind; + VkBool32 descriptorBindingStorageBufferUpdateAfterBind; + VkBool32 descriptorBindingUniformTexelBufferUpdateAfterBind; + VkBool32 descriptorBindingStorageTexelBufferUpdateAfterBind; + VkBool32 descriptorBindingUpdateUnusedWhilePending; + VkBool32 descriptorBindingPartiallyBound; + VkBool32 descriptorBindingVariableDescriptorCount; + VkBool32 runtimeDescriptorArray; +} VkPhysicalDeviceDescriptorIndexingFeatures; + +typedef struct VkPhysicalDeviceDescriptorIndexingProperties { + VkStructureType sType; + void* pNext; + uint32_t maxUpdateAfterBindDescriptorsInAllPools; + VkBool32 shaderUniformBufferArrayNonUniformIndexingNative; + VkBool32 shaderSampledImageArrayNonUniformIndexingNative; + VkBool32 shaderStorageBufferArrayNonUniformIndexingNative; + VkBool32 shaderStorageImageArrayNonUniformIndexingNative; + VkBool32 shaderInputAttachmentArrayNonUniformIndexingNative; + VkBool32 robustBufferAccessUpdateAfterBind; + VkBool32 quadDivergentImplicitLod; + uint32_t maxPerStageDescriptorUpdateAfterBindSamplers; + uint32_t maxPerStageDescriptorUpdateAfterBindUniformBuffers; + uint32_t maxPerStageDescriptorUpdateAfterBindStorageBuffers; + uint32_t maxPerStageDescriptorUpdateAfterBindSampledImages; + uint32_t maxPerStageDescriptorUpdateAfterBindStorageImages; + uint32_t maxPerStageDescriptorUpdateAfterBindInputAttachments; + uint32_t maxPerStageUpdateAfterBindResources; + uint32_t maxDescriptorSetUpdateAfterBindSamplers; + uint32_t maxDescriptorSetUpdateAfterBindUniformBuffers; + uint32_t maxDescriptorSetUpdateAfterBindUniformBuffersDynamic; + uint32_t maxDescriptorSetUpdateAfterBindStorageBuffers; + uint32_t maxDescriptorSetUpdateAfterBindStorageBuffersDynamic; + uint32_t maxDescriptorSetUpdateAfterBindSampledImages; + uint32_t maxDescriptorSetUpdateAfterBindStorageImages; + uint32_t maxDescriptorSetUpdateAfterBindInputAttachments; +} VkPhysicalDeviceDescriptorIndexingProperties; + +typedef struct VkDescriptorSetVariableDescriptorCountAllocateInfo { + VkStructureType sType; + const void* pNext; + uint32_t descriptorSetCount; + const uint32_t* pDescriptorCounts; +} VkDescriptorSetVariableDescriptorCountAllocateInfo; + +typedef struct VkDescriptorSetVariableDescriptorCountLayoutSupport { + VkStructureType sType; + void* pNext; + uint32_t maxVariableDescriptorCount; +} VkDescriptorSetVariableDescriptorCountLayoutSupport; + +typedef struct VkSubpassDescriptionDepthStencilResolve { + VkStructureType sType; + const void* pNext; + VkResolveModeFlagBits depthResolveMode; + VkResolveModeFlagBits stencilResolveMode; + const VkAttachmentReference2* pDepthStencilResolveAttachment; +} VkSubpassDescriptionDepthStencilResolve; + +typedef struct VkPhysicalDeviceDepthStencilResolveProperties { + VkStructureType sType; + void* pNext; + VkResolveModeFlags supportedDepthResolveModes; + VkResolveModeFlags supportedStencilResolveModes; + VkBool32 independentResolveNone; + VkBool32 independentResolve; +} VkPhysicalDeviceDepthStencilResolveProperties; + +typedef struct VkPhysicalDeviceScalarBlockLayoutFeatures { + VkStructureType sType; + void* pNext; + VkBool32 scalarBlockLayout; +} VkPhysicalDeviceScalarBlockLayoutFeatures; + +typedef struct VkImageStencilUsageCreateInfo { + VkStructureType sType; + const void* pNext; + VkImageUsageFlags stencilUsage; +} VkImageStencilUsageCreateInfo; + +typedef struct VkSamplerReductionModeCreateInfo { + VkStructureType sType; + const void* pNext; + VkSamplerReductionMode reductionMode; +} VkSamplerReductionModeCreateInfo; + +typedef struct VkPhysicalDeviceSamplerFilterMinmaxProperties { + VkStructureType sType; + void* pNext; + VkBool32 filterMinmaxSingleComponentFormats; + VkBool32 filterMinmaxImageComponentMapping; +} VkPhysicalDeviceSamplerFilterMinmaxProperties; + +typedef struct VkPhysicalDeviceVulkanMemoryModelFeatures { + VkStructureType sType; + void* pNext; + VkBool32 vulkanMemoryModel; + VkBool32 vulkanMemoryModelDeviceScope; + VkBool32 vulkanMemoryModelAvailabilityVisibilityChains; +} VkPhysicalDeviceVulkanMemoryModelFeatures; + +typedef struct VkPhysicalDeviceImagelessFramebufferFeatures { + VkStructureType sType; + void* pNext; + VkBool32 imagelessFramebuffer; +} VkPhysicalDeviceImagelessFramebufferFeatures; + +typedef struct VkFramebufferAttachmentImageInfo { + VkStructureType sType; + const void* pNext; + VkImageCreateFlags flags; + VkImageUsageFlags usage; + uint32_t width; + uint32_t height; + uint32_t layerCount; + uint32_t viewFormatCount; + const VkFormat* pViewFormats; +} VkFramebufferAttachmentImageInfo; + +typedef struct VkFramebufferAttachmentsCreateInfo { + VkStructureType sType; + const void* pNext; + uint32_t attachmentImageInfoCount; + const VkFramebufferAttachmentImageInfo* pAttachmentImageInfos; +} VkFramebufferAttachmentsCreateInfo; + +typedef struct VkRenderPassAttachmentBeginInfo { + VkStructureType sType; + const void* pNext; + uint32_t attachmentCount; + const VkImageView* pAttachments; +} VkRenderPassAttachmentBeginInfo; + +typedef struct VkPhysicalDeviceUniformBufferStandardLayoutFeatures { + VkStructureType sType; + void* pNext; + VkBool32 uniformBufferStandardLayout; +} VkPhysicalDeviceUniformBufferStandardLayoutFeatures; + +typedef struct VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures { + VkStructureType sType; + void* pNext; + VkBool32 shaderSubgroupExtendedTypes; +} VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures; + +typedef struct VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures { + VkStructureType sType; + void* pNext; + VkBool32 separateDepthStencilLayouts; +} VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures; + +typedef struct VkAttachmentReferenceStencilLayout { + VkStructureType sType; + void* pNext; + VkImageLayout stencilLayout; +} VkAttachmentReferenceStencilLayout; + +typedef struct VkAttachmentDescriptionStencilLayout { + VkStructureType sType; + void* pNext; + VkImageLayout stencilInitialLayout; + VkImageLayout stencilFinalLayout; +} VkAttachmentDescriptionStencilLayout; + +typedef struct VkPhysicalDeviceHostQueryResetFeatures { + VkStructureType sType; + void* pNext; + VkBool32 hostQueryReset; +} VkPhysicalDeviceHostQueryResetFeatures; + +typedef struct VkPhysicalDeviceTimelineSemaphoreFeatures { + VkStructureType sType; + void* pNext; + VkBool32 timelineSemaphore; +} VkPhysicalDeviceTimelineSemaphoreFeatures; + +typedef struct VkPhysicalDeviceTimelineSemaphoreProperties { + VkStructureType sType; + void* pNext; + uint64_t maxTimelineSemaphoreValueDifference; +} VkPhysicalDeviceTimelineSemaphoreProperties; + +typedef struct VkSemaphoreTypeCreateInfo { + VkStructureType sType; + const void* pNext; + VkSemaphoreType semaphoreType; + uint64_t initialValue; +} VkSemaphoreTypeCreateInfo; + +typedef struct VkTimelineSemaphoreSubmitInfo { + VkStructureType sType; + const void* pNext; + uint32_t waitSemaphoreValueCount; + const uint64_t* pWaitSemaphoreValues; + uint32_t signalSemaphoreValueCount; + const uint64_t* pSignalSemaphoreValues; +} VkTimelineSemaphoreSubmitInfo; + +typedef struct VkSemaphoreWaitInfo { + VkStructureType sType; + const void* pNext; + VkSemaphoreWaitFlags flags; + uint32_t semaphoreCount; + const VkSemaphore* pSemaphores; + const uint64_t* pValues; +} VkSemaphoreWaitInfo; + +typedef struct VkSemaphoreSignalInfo { + VkStructureType sType; + const void* pNext; + VkSemaphore semaphore; + uint64_t value; +} VkSemaphoreSignalInfo; + +typedef struct VkPhysicalDeviceBufferDeviceAddressFeatures { + VkStructureType sType; + void* pNext; + VkBool32 bufferDeviceAddress; + VkBool32 bufferDeviceAddressCaptureReplay; + VkBool32 bufferDeviceAddressMultiDevice; +} VkPhysicalDeviceBufferDeviceAddressFeatures; + +typedef struct VkBufferDeviceAddressInfo { + VkStructureType sType; + const void* pNext; + VkBuffer buffer; +} VkBufferDeviceAddressInfo; + +typedef struct VkBufferOpaqueCaptureAddressCreateInfo { + VkStructureType sType; + const void* pNext; + uint64_t opaqueCaptureAddress; +} VkBufferOpaqueCaptureAddressCreateInfo; + +typedef struct VkMemoryOpaqueCaptureAddressAllocateInfo { + VkStructureType sType; + const void* pNext; + uint64_t opaqueCaptureAddress; +} VkMemoryOpaqueCaptureAddressAllocateInfo; + +typedef struct VkDeviceMemoryOpaqueCaptureAddressInfo { + VkStructureType sType; + const void* pNext; + VkDeviceMemory memory; +} VkDeviceMemoryOpaqueCaptureAddressInfo; + +typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirectCount)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); +typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexedIndirectCount)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); +typedef VkResult (VKAPI_PTR *PFN_vkCreateRenderPass2)(VkDevice device, const VkRenderPassCreateInfo2* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass); +typedef void (VKAPI_PTR *PFN_vkCmdBeginRenderPass2)(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, const VkSubpassBeginInfo* pSubpassBeginInfo); +typedef void (VKAPI_PTR *PFN_vkCmdNextSubpass2)(VkCommandBuffer commandBuffer, const VkSubpassBeginInfo* pSubpassBeginInfo, const VkSubpassEndInfo* pSubpassEndInfo); +typedef void (VKAPI_PTR *PFN_vkCmdEndRenderPass2)(VkCommandBuffer commandBuffer, const VkSubpassEndInfo* pSubpassEndInfo); +typedef void (VKAPI_PTR *PFN_vkResetQueryPool)(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount); +typedef VkResult (VKAPI_PTR *PFN_vkGetSemaphoreCounterValue)(VkDevice device, VkSemaphore semaphore, uint64_t* pValue); +typedef VkResult (VKAPI_PTR *PFN_vkWaitSemaphores)(VkDevice device, const VkSemaphoreWaitInfo* pWaitInfo, uint64_t timeout); +typedef VkResult (VKAPI_PTR *PFN_vkSignalSemaphore)(VkDevice device, const VkSemaphoreSignalInfo* pSignalInfo); +typedef VkDeviceAddress (VKAPI_PTR *PFN_vkGetBufferDeviceAddress)(VkDevice device, const VkBufferDeviceAddressInfo* pInfo); +typedef uint64_t (VKAPI_PTR *PFN_vkGetBufferOpaqueCaptureAddress)(VkDevice device, const VkBufferDeviceAddressInfo* pInfo); +typedef uint64_t (VKAPI_PTR *PFN_vkGetDeviceMemoryOpaqueCaptureAddress)(VkDevice device, const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirectCount( + VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset, + VkBuffer countBuffer, + VkDeviceSize countBufferOffset, + uint32_t maxDrawCount, + uint32_t stride); + +VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirectCount( + VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset, + VkBuffer countBuffer, + VkDeviceSize countBufferOffset, + uint32_t maxDrawCount, + uint32_t stride); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass2( + VkDevice device, + const VkRenderPassCreateInfo2* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkRenderPass* pRenderPass); + +VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderPass2( + VkCommandBuffer commandBuffer, + const VkRenderPassBeginInfo* pRenderPassBegin, + const VkSubpassBeginInfo* pSubpassBeginInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdNextSubpass2( + VkCommandBuffer commandBuffer, + const VkSubpassBeginInfo* pSubpassBeginInfo, + const VkSubpassEndInfo* pSubpassEndInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderPass2( + VkCommandBuffer commandBuffer, + const VkSubpassEndInfo* pSubpassEndInfo); + +VKAPI_ATTR void VKAPI_CALL vkResetQueryPool( + VkDevice device, + VkQueryPool queryPool, + uint32_t firstQuery, + uint32_t queryCount); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreCounterValue( + VkDevice device, + VkSemaphore semaphore, + uint64_t* pValue); + +VKAPI_ATTR VkResult VKAPI_CALL vkWaitSemaphores( + VkDevice device, + const VkSemaphoreWaitInfo* pWaitInfo, + uint64_t timeout); + +VKAPI_ATTR VkResult VKAPI_CALL vkSignalSemaphore( + VkDevice device, + const VkSemaphoreSignalInfo* pSignalInfo); + +VKAPI_ATTR VkDeviceAddress VKAPI_CALL vkGetBufferDeviceAddress( + VkDevice device, + const VkBufferDeviceAddressInfo* pInfo); + +VKAPI_ATTR uint64_t VKAPI_CALL vkGetBufferOpaqueCaptureAddress( + VkDevice device, + const VkBufferDeviceAddressInfo* pInfo); + +VKAPI_ATTR uint64_t VKAPI_CALL vkGetDeviceMemoryOpaqueCaptureAddress( + VkDevice device, + const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo); +#endif + + +// VK_VERSION_1_3 is a preprocessor guard. Do not pass it to API calls. +#define VK_VERSION_1_3 1 +// Vulkan 1.3 version number +#define VK_API_VERSION_1_3 VK_MAKE_API_VERSION(0, 1, 3, 0)// Patch version should always be set to 0 + +typedef uint64_t VkFlags64; +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPrivateDataSlot) + +typedef enum VkPipelineCreationFeedbackFlagBits { + VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT = 0x00000001, + VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT = 0x00000002, + VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT = 0x00000004, + VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT_EXT = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT, + VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT_EXT = VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT, + VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT_EXT = VK_PIPELINE_CREATION_FEEDBACK_BASE_PIPELINE_ACCELERATION_BIT, + VK_PIPELINE_CREATION_FEEDBACK_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkPipelineCreationFeedbackFlagBits; +typedef VkFlags VkPipelineCreationFeedbackFlags; + +typedef enum VkToolPurposeFlagBits { + VK_TOOL_PURPOSE_VALIDATION_BIT = 0x00000001, + VK_TOOL_PURPOSE_PROFILING_BIT = 0x00000002, + VK_TOOL_PURPOSE_TRACING_BIT = 0x00000004, + VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT = 0x00000008, + VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT = 0x00000010, + VK_TOOL_PURPOSE_DEBUG_REPORTING_BIT_EXT = 0x00000020, + VK_TOOL_PURPOSE_DEBUG_MARKERS_BIT_EXT = 0x00000040, + VK_TOOL_PURPOSE_VALIDATION_BIT_EXT = VK_TOOL_PURPOSE_VALIDATION_BIT, + VK_TOOL_PURPOSE_PROFILING_BIT_EXT = VK_TOOL_PURPOSE_PROFILING_BIT, + VK_TOOL_PURPOSE_TRACING_BIT_EXT = VK_TOOL_PURPOSE_TRACING_BIT, + VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT_EXT = VK_TOOL_PURPOSE_ADDITIONAL_FEATURES_BIT, + VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT_EXT = VK_TOOL_PURPOSE_MODIFYING_FEATURES_BIT, + VK_TOOL_PURPOSE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkToolPurposeFlagBits; +typedef VkFlags VkToolPurposeFlags; +typedef VkFlags VkPrivateDataSlotCreateFlags; +typedef VkFlags64 VkPipelineStageFlags2; + +// Flag bits for VkPipelineStageFlagBits2 +typedef VkFlags64 VkPipelineStageFlagBits2; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_NONE = 0ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_NONE_KHR = 0ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT = 0x00000001ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR = 0x00000001ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT = 0x00000002ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT_KHR = 0x00000002ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_INPUT_BIT = 0x00000004ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_INPUT_BIT_KHR = 0x00000004ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT = 0x00000008ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT_KHR = 0x00000008ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TESSELLATION_CONTROL_SHADER_BIT = 0x00000010ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TESSELLATION_CONTROL_SHADER_BIT_KHR = 0x00000010ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TESSELLATION_EVALUATION_SHADER_BIT = 0x00000020ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TESSELLATION_EVALUATION_SHADER_BIT_KHR = 0x00000020ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_GEOMETRY_SHADER_BIT = 0x00000040ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_GEOMETRY_SHADER_BIT_KHR = 0x00000040ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT = 0x00000080ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT_KHR = 0x00000080ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT = 0x00000100ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT_KHR = 0x00000100ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT = 0x00000200ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT_KHR = 0x00000200ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT = 0x00000400ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR = 0x00000400ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT = 0x00000800ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT_KHR = 0x00000800ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT = 0x00001000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT_KHR = 0x00001000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TRANSFER_BIT = 0x00001000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR = 0x00001000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT = 0x00002000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR = 0x00002000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_HOST_BIT = 0x00004000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_HOST_BIT_KHR = 0x00004000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT = 0x00008000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT_KHR = 0x00008000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT = 0x00010000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR = 0x00010000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COPY_BIT = 0x100000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COPY_BIT_KHR = 0x100000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_RESOLVE_BIT = 0x200000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_RESOLVE_BIT_KHR = 0x200000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_BLIT_BIT = 0x400000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_BLIT_BIT_KHR = 0x400000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_CLEAR_BIT = 0x800000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_CLEAR_BIT_KHR = 0x800000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT = 0x1000000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT_KHR = 0x1000000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT = 0x2000000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT_KHR = 0x2000000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_PRE_RASTERIZATION_SHADERS_BIT = 0x4000000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_PRE_RASTERIZATION_SHADERS_BIT_KHR = 0x4000000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR = 0x04000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR = 0x08000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TRANSFORM_FEEDBACK_BIT_EXT = 0x01000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_CONDITIONAL_RENDERING_BIT_EXT = 0x00040000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_COMMAND_PREPROCESS_BIT_NV = 0x00020000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x00400000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_SHADING_RATE_IMAGE_BIT_NV = 0x00400000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_KHR = 0x02000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_RAY_TRACING_SHADER_BIT_KHR = 0x00200000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_RAY_TRACING_SHADER_BIT_NV = 0x00200000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_NV = 0x02000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_FRAGMENT_DENSITY_PROCESS_BIT_EXT = 0x00800000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TASK_SHADER_BIT_NV = 0x00080000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_MESH_SHADER_BIT_NV = 0x00100000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_TASK_SHADER_BIT_EXT = 0x00080000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_MESH_SHADER_BIT_EXT = 0x00100000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_SUBPASS_SHADER_BIT_HUAWEI = 0x8000000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_SUBPASS_SHADING_BIT_HUAWEI = 0x8000000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_INVOCATION_MASK_BIT_HUAWEI = 0x10000000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_COPY_BIT_KHR = 0x10000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_MICROMAP_BUILD_BIT_EXT = 0x40000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_CLUSTER_CULLING_SHADER_BIT_HUAWEI = 0x20000000000ULL; +static const VkPipelineStageFlagBits2 VK_PIPELINE_STAGE_2_OPTICAL_FLOW_BIT_NV = 0x20000000ULL; + +typedef VkFlags64 VkAccessFlags2; + +// Flag bits for VkAccessFlagBits2 +typedef VkFlags64 VkAccessFlagBits2; +static const VkAccessFlagBits2 VK_ACCESS_2_NONE = 0ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_NONE_KHR = 0ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT = 0x00000001ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT_KHR = 0x00000001ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_INDEX_READ_BIT = 0x00000002ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_INDEX_READ_BIT_KHR = 0x00000002ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT = 0x00000004ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT_KHR = 0x00000004ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_UNIFORM_READ_BIT = 0x00000008ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_UNIFORM_READ_BIT_KHR = 0x00000008ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT = 0x00000010ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT_KHR = 0x00000010ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_READ_BIT = 0x00000020ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_READ_BIT_KHR = 0x00000020ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_WRITE_BIT = 0x00000040ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_WRITE_BIT_KHR = 0x00000040ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT = 0x00000080ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT_KHR = 0x00000080ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT = 0x00000100ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT_KHR = 0x00000100ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT = 0x00000200ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT_KHR = 0x00000200ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT = 0x00000400ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT_KHR = 0x00000400ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFER_READ_BIT = 0x00000800ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFER_READ_BIT_KHR = 0x00000800ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFER_WRITE_BIT = 0x00001000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR = 0x00001000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_HOST_READ_BIT = 0x00002000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_HOST_READ_BIT_KHR = 0x00002000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_HOST_WRITE_BIT = 0x00004000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_HOST_WRITE_BIT_KHR = 0x00004000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_MEMORY_READ_BIT = 0x00008000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_MEMORY_READ_BIT_KHR = 0x00008000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_MEMORY_WRITE_BIT = 0x00010000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_MEMORY_WRITE_BIT_KHR = 0x00010000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_SAMPLED_READ_BIT = 0x100000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_SAMPLED_READ_BIT_KHR = 0x100000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_STORAGE_READ_BIT = 0x200000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_STORAGE_READ_BIT_KHR = 0x200000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT = 0x400000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT_KHR = 0x400000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_VIDEO_DECODE_READ_BIT_KHR = 0x800000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_VIDEO_DECODE_WRITE_BIT_KHR = 0x1000000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_VIDEO_ENCODE_READ_BIT_KHR = 0x2000000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_VIDEO_ENCODE_WRITE_BIT_KHR = 0x4000000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFORM_FEEDBACK_WRITE_BIT_EXT = 0x02000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT = 0x04000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT = 0x08000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_CONDITIONAL_RENDERING_READ_BIT_EXT = 0x00100000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_COMMAND_PREPROCESS_READ_BIT_NV = 0x00020000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_COMMAND_PREPROCESS_WRITE_BIT_NV = 0x00040000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR = 0x00800000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADING_RATE_IMAGE_READ_BIT_NV = 0x00800000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_ACCELERATION_STRUCTURE_READ_BIT_KHR = 0x00200000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_ACCELERATION_STRUCTURE_WRITE_BIT_KHR = 0x00400000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_ACCELERATION_STRUCTURE_READ_BIT_NV = 0x00200000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_ACCELERATION_STRUCTURE_WRITE_BIT_NV = 0x00400000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_FRAGMENT_DENSITY_MAP_READ_BIT_EXT = 0x01000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT = 0x00080000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_DESCRIPTOR_BUFFER_READ_BIT_EXT = 0x20000000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_INVOCATION_MASK_READ_BIT_HUAWEI = 0x8000000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_SHADER_BINDING_TABLE_READ_BIT_KHR = 0x10000000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_MICROMAP_READ_BIT_EXT = 0x100000000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_MICROMAP_WRITE_BIT_EXT = 0x200000000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_OPTICAL_FLOW_READ_BIT_NV = 0x40000000000ULL; +static const VkAccessFlagBits2 VK_ACCESS_2_OPTICAL_FLOW_WRITE_BIT_NV = 0x80000000000ULL; + + +typedef enum VkSubmitFlagBits { + VK_SUBMIT_PROTECTED_BIT = 0x00000001, + VK_SUBMIT_PROTECTED_BIT_KHR = VK_SUBMIT_PROTECTED_BIT, + VK_SUBMIT_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkSubmitFlagBits; +typedef VkFlags VkSubmitFlags; + +typedef enum VkRenderingFlagBits { + VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT = 0x00000001, + VK_RENDERING_SUSPENDING_BIT = 0x00000002, + VK_RENDERING_RESUMING_BIT = 0x00000004, + VK_RENDERING_CONTENTS_INLINE_BIT_EXT = 0x00000010, + VK_RENDERING_ENABLE_LEGACY_DITHERING_BIT_EXT = 0x00000008, + VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT_KHR = VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT, + VK_RENDERING_SUSPENDING_BIT_KHR = VK_RENDERING_SUSPENDING_BIT, + VK_RENDERING_RESUMING_BIT_KHR = VK_RENDERING_RESUMING_BIT, + VK_RENDERING_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF +} VkRenderingFlagBits; +typedef VkFlags VkRenderingFlags; +typedef VkFlags64 VkFormatFeatureFlags2; + +// Flag bits for VkFormatFeatureFlagBits2 +typedef VkFlags64 VkFormatFeatureFlagBits2; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT = 0x00000001ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT_KHR = 0x00000001ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT = 0x00000002ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR = 0x00000002ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_IMAGE_ATOMIC_BIT = 0x00000004ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_IMAGE_ATOMIC_BIT_KHR = 0x00000004ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT = 0x00000008ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT_KHR = 0x00000008ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT = 0x00000010ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT_KHR = 0x00000010ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_ATOMIC_BIT = 0x00000020ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_ATOMIC_BIT_KHR = 0x00000020ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT = 0x00000040ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT_KHR = 0x00000040ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT = 0x00000080ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT_KHR = 0x00000080ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT = 0x00000100ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT_KHR = 0x00000100ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT = 0x00000200ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT_KHR = 0x00000200ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLIT_SRC_BIT = 0x00000400ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLIT_SRC_BIT_KHR = 0x00000400ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLIT_DST_BIT = 0x00000800ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLIT_DST_BIT_KHR = 0x00000800ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT = 0x00001000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT_KHR = 0x00001000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_CUBIC_BIT = 0x00002000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT = 0x00002000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT = 0x00004000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT_KHR = 0x00004000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT = 0x00008000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT_KHR = 0x00008000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_MINMAX_BIT = 0x00010000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_MINMAX_BIT_KHR = 0x00010000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT = 0x00020000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT_KHR = 0x00020000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT = 0x00040000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT_KHR = 0x00040000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT = 0x00080000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT_KHR = 0x00080000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT = 0x00100000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT_KHR = 0x00100000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT = 0x00200000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT_KHR = 0x00200000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_DISJOINT_BIT = 0x00400000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_DISJOINT_BIT_KHR = 0x00400000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COSITED_CHROMA_SAMPLES_BIT = 0x00800000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_COSITED_CHROMA_SAMPLES_BIT_KHR = 0x00800000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT = 0x80000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR = 0x80000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT = 0x100000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR = 0x100000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT = 0x200000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT_KHR = 0x200000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VIDEO_DECODE_OUTPUT_BIT_KHR = 0x02000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VIDEO_DECODE_DPB_BIT_KHR = 0x04000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_ACCELERATION_STRUCTURE_VERTEX_BUFFER_BIT_KHR = 0x20000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_FRAGMENT_DENSITY_MAP_BIT_EXT = 0x01000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x40000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_HOST_IMAGE_TRANSFER_BIT_EXT = 0x400000000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VIDEO_ENCODE_INPUT_BIT_KHR = 0x08000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_VIDEO_ENCODE_DPB_BIT_KHR = 0x10000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_LINEAR_COLOR_ATTACHMENT_BIT_NV = 0x4000000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_WEIGHT_IMAGE_BIT_QCOM = 0x400000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_WEIGHT_SAMPLED_IMAGE_BIT_QCOM = 0x800000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BLOCK_MATCHING_BIT_QCOM = 0x1000000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_BOX_FILTER_SAMPLED_BIT_QCOM = 0x2000000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_OPTICAL_FLOW_IMAGE_BIT_NV = 0x10000000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_OPTICAL_FLOW_VECTOR_BIT_NV = 0x20000000000ULL; +static const VkFormatFeatureFlagBits2 VK_FORMAT_FEATURE_2_OPTICAL_FLOW_COST_BIT_NV = 0x40000000000ULL; + +typedef struct VkPhysicalDeviceVulkan13Features { + VkStructureType sType; + void* pNext; + VkBool32 robustImageAccess; + VkBool32 inlineUniformBlock; + VkBool32 descriptorBindingInlineUniformBlockUpdateAfterBind; + VkBool32 pipelineCreationCacheControl; + VkBool32 privateData; + VkBool32 shaderDemoteToHelperInvocation; + VkBool32 shaderTerminateInvocation; + VkBool32 subgroupSizeControl; + VkBool32 computeFullSubgroups; + VkBool32 synchronization2; + VkBool32 textureCompressionASTC_HDR; + VkBool32 shaderZeroInitializeWorkgroupMemory; + VkBool32 dynamicRendering; + VkBool32 shaderIntegerDotProduct; + VkBool32 maintenance4; +} VkPhysicalDeviceVulkan13Features; + +typedef struct VkPhysicalDeviceVulkan13Properties { + VkStructureType sType; + void* pNext; + uint32_t minSubgroupSize; + uint32_t maxSubgroupSize; + uint32_t maxComputeWorkgroupSubgroups; + VkShaderStageFlags requiredSubgroupSizeStages; + uint32_t maxInlineUniformBlockSize; + uint32_t maxPerStageDescriptorInlineUniformBlocks; + uint32_t maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks; + uint32_t maxDescriptorSetInlineUniformBlocks; + uint32_t maxDescriptorSetUpdateAfterBindInlineUniformBlocks; + uint32_t maxInlineUniformTotalSize; + VkBool32 integerDotProduct8BitUnsignedAccelerated; + VkBool32 integerDotProduct8BitSignedAccelerated; + VkBool32 integerDotProduct8BitMixedSignednessAccelerated; + VkBool32 integerDotProduct4x8BitPackedUnsignedAccelerated; + VkBool32 integerDotProduct4x8BitPackedSignedAccelerated; + VkBool32 integerDotProduct4x8BitPackedMixedSignednessAccelerated; + VkBool32 integerDotProduct16BitUnsignedAccelerated; + VkBool32 integerDotProduct16BitSignedAccelerated; + VkBool32 integerDotProduct16BitMixedSignednessAccelerated; + VkBool32 integerDotProduct32BitUnsignedAccelerated; + VkBool32 integerDotProduct32BitSignedAccelerated; + VkBool32 integerDotProduct32BitMixedSignednessAccelerated; + VkBool32 integerDotProduct64BitUnsignedAccelerated; + VkBool32 integerDotProduct64BitSignedAccelerated; + VkBool32 integerDotProduct64BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating8BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating8BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating16BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating16BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating32BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating32BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating64BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating64BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated; + VkDeviceSize storageTexelBufferOffsetAlignmentBytes; + VkBool32 storageTexelBufferOffsetSingleTexelAlignment; + VkDeviceSize uniformTexelBufferOffsetAlignmentBytes; + VkBool32 uniformTexelBufferOffsetSingleTexelAlignment; + VkDeviceSize maxBufferSize; +} VkPhysicalDeviceVulkan13Properties; + +typedef struct VkPipelineCreationFeedback { + VkPipelineCreationFeedbackFlags flags; + uint64_t duration; +} VkPipelineCreationFeedback; + +typedef struct VkPipelineCreationFeedbackCreateInfo { + VkStructureType sType; + const void* pNext; + VkPipelineCreationFeedback* pPipelineCreationFeedback; + uint32_t pipelineStageCreationFeedbackCount; + VkPipelineCreationFeedback* pPipelineStageCreationFeedbacks; +} VkPipelineCreationFeedbackCreateInfo; + +typedef struct VkPhysicalDeviceShaderTerminateInvocationFeatures { + VkStructureType sType; + void* pNext; + VkBool32 shaderTerminateInvocation; +} VkPhysicalDeviceShaderTerminateInvocationFeatures; + +typedef struct VkPhysicalDeviceToolProperties { + VkStructureType sType; + void* pNext; + char name[VK_MAX_EXTENSION_NAME_SIZE]; + char version[VK_MAX_EXTENSION_NAME_SIZE]; + VkToolPurposeFlags purposes; + char description[VK_MAX_DESCRIPTION_SIZE]; + char layer[VK_MAX_EXTENSION_NAME_SIZE]; +} VkPhysicalDeviceToolProperties; + +typedef struct VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures { + VkStructureType sType; + void* pNext; + VkBool32 shaderDemoteToHelperInvocation; +} VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures; + +typedef struct VkPhysicalDevicePrivateDataFeatures { + VkStructureType sType; + void* pNext; + VkBool32 privateData; +} VkPhysicalDevicePrivateDataFeatures; + +typedef struct VkDevicePrivateDataCreateInfo { + VkStructureType sType; + const void* pNext; + uint32_t privateDataSlotRequestCount; +} VkDevicePrivateDataCreateInfo; + +typedef struct VkPrivateDataSlotCreateInfo { + VkStructureType sType; + const void* pNext; + VkPrivateDataSlotCreateFlags flags; +} VkPrivateDataSlotCreateInfo; + +typedef struct VkPhysicalDevicePipelineCreationCacheControlFeatures { + VkStructureType sType; + void* pNext; + VkBool32 pipelineCreationCacheControl; +} VkPhysicalDevicePipelineCreationCacheControlFeatures; + +typedef struct VkMemoryBarrier2 { + VkStructureType sType; + const void* pNext; + VkPipelineStageFlags2 srcStageMask; + VkAccessFlags2 srcAccessMask; + VkPipelineStageFlags2 dstStageMask; + VkAccessFlags2 dstAccessMask; +} VkMemoryBarrier2; + +typedef struct VkBufferMemoryBarrier2 { + VkStructureType sType; + const void* pNext; + VkPipelineStageFlags2 srcStageMask; + VkAccessFlags2 srcAccessMask; + VkPipelineStageFlags2 dstStageMask; + VkAccessFlags2 dstAccessMask; + uint32_t srcQueueFamilyIndex; + uint32_t dstQueueFamilyIndex; + VkBuffer buffer; + VkDeviceSize offset; + VkDeviceSize size; +} VkBufferMemoryBarrier2; + +typedef struct VkImageMemoryBarrier2 { + VkStructureType sType; + const void* pNext; + VkPipelineStageFlags2 srcStageMask; + VkAccessFlags2 srcAccessMask; + VkPipelineStageFlags2 dstStageMask; + VkAccessFlags2 dstAccessMask; + VkImageLayout oldLayout; + VkImageLayout newLayout; + uint32_t srcQueueFamilyIndex; + uint32_t dstQueueFamilyIndex; + VkImage image; + VkImageSubresourceRange subresourceRange; +} VkImageMemoryBarrier2; + +typedef struct VkDependencyInfo { + VkStructureType sType; + const void* pNext; + VkDependencyFlags dependencyFlags; + uint32_t memoryBarrierCount; + const VkMemoryBarrier2* pMemoryBarriers; + uint32_t bufferMemoryBarrierCount; + const VkBufferMemoryBarrier2* pBufferMemoryBarriers; + uint32_t imageMemoryBarrierCount; + const VkImageMemoryBarrier2* pImageMemoryBarriers; +} VkDependencyInfo; + +typedef struct VkSemaphoreSubmitInfo { + VkStructureType sType; + const void* pNext; + VkSemaphore semaphore; + uint64_t value; + VkPipelineStageFlags2 stageMask; + uint32_t deviceIndex; +} VkSemaphoreSubmitInfo; + +typedef struct VkCommandBufferSubmitInfo { + VkStructureType sType; + const void* pNext; + VkCommandBuffer commandBuffer; + uint32_t deviceMask; +} VkCommandBufferSubmitInfo; + +typedef struct VkSubmitInfo2 { + VkStructureType sType; + const void* pNext; + VkSubmitFlags flags; + uint32_t waitSemaphoreInfoCount; + const VkSemaphoreSubmitInfo* pWaitSemaphoreInfos; + uint32_t commandBufferInfoCount; + const VkCommandBufferSubmitInfo* pCommandBufferInfos; + uint32_t signalSemaphoreInfoCount; + const VkSemaphoreSubmitInfo* pSignalSemaphoreInfos; +} VkSubmitInfo2; + +typedef struct VkPhysicalDeviceSynchronization2Features { + VkStructureType sType; + void* pNext; + VkBool32 synchronization2; +} VkPhysicalDeviceSynchronization2Features; + +typedef struct VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures { + VkStructureType sType; + void* pNext; + VkBool32 shaderZeroInitializeWorkgroupMemory; +} VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures; + +typedef struct VkPhysicalDeviceImageRobustnessFeatures { + VkStructureType sType; + void* pNext; + VkBool32 robustImageAccess; +} VkPhysicalDeviceImageRobustnessFeatures; + +typedef struct VkBufferCopy2 { + VkStructureType sType; + const void* pNext; + VkDeviceSize srcOffset; + VkDeviceSize dstOffset; + VkDeviceSize size; +} VkBufferCopy2; + +typedef struct VkCopyBufferInfo2 { + VkStructureType sType; + const void* pNext; + VkBuffer srcBuffer; + VkBuffer dstBuffer; + uint32_t regionCount; + const VkBufferCopy2* pRegions; +} VkCopyBufferInfo2; + +typedef struct VkImageCopy2 { + VkStructureType sType; + const void* pNext; + VkImageSubresourceLayers srcSubresource; + VkOffset3D srcOffset; + VkImageSubresourceLayers dstSubresource; + VkOffset3D dstOffset; + VkExtent3D extent; +} VkImageCopy2; + +typedef struct VkCopyImageInfo2 { + VkStructureType sType; + const void* pNext; + VkImage srcImage; + VkImageLayout srcImageLayout; + VkImage dstImage; + VkImageLayout dstImageLayout; + uint32_t regionCount; + const VkImageCopy2* pRegions; +} VkCopyImageInfo2; + +typedef struct VkBufferImageCopy2 { + VkStructureType sType; + const void* pNext; + VkDeviceSize bufferOffset; + uint32_t bufferRowLength; + uint32_t bufferImageHeight; + VkImageSubresourceLayers imageSubresource; + VkOffset3D imageOffset; + VkExtent3D imageExtent; +} VkBufferImageCopy2; + +typedef struct VkCopyBufferToImageInfo2 { + VkStructureType sType; + const void* pNext; + VkBuffer srcBuffer; + VkImage dstImage; + VkImageLayout dstImageLayout; + uint32_t regionCount; + const VkBufferImageCopy2* pRegions; +} VkCopyBufferToImageInfo2; + +typedef struct VkCopyImageToBufferInfo2 { + VkStructureType sType; + const void* pNext; + VkImage srcImage; + VkImageLayout srcImageLayout; + VkBuffer dstBuffer; + uint32_t regionCount; + const VkBufferImageCopy2* pRegions; +} VkCopyImageToBufferInfo2; + +typedef struct VkImageBlit2 { + VkStructureType sType; + const void* pNext; + VkImageSubresourceLayers srcSubresource; + VkOffset3D srcOffsets[2]; + VkImageSubresourceLayers dstSubresource; + VkOffset3D dstOffsets[2]; +} VkImageBlit2; + +typedef struct VkBlitImageInfo2 { + VkStructureType sType; + const void* pNext; + VkImage srcImage; + VkImageLayout srcImageLayout; + VkImage dstImage; + VkImageLayout dstImageLayout; + uint32_t regionCount; + const VkImageBlit2* pRegions; + VkFilter filter; +} VkBlitImageInfo2; + +typedef struct VkImageResolve2 { + VkStructureType sType; + const void* pNext; + VkImageSubresourceLayers srcSubresource; + VkOffset3D srcOffset; + VkImageSubresourceLayers dstSubresource; + VkOffset3D dstOffset; + VkExtent3D extent; +} VkImageResolve2; + +typedef struct VkResolveImageInfo2 { + VkStructureType sType; + const void* pNext; + VkImage srcImage; + VkImageLayout srcImageLayout; + VkImage dstImage; + VkImageLayout dstImageLayout; + uint32_t regionCount; + const VkImageResolve2* pRegions; +} VkResolveImageInfo2; + +typedef struct VkPhysicalDeviceSubgroupSizeControlFeatures { + VkStructureType sType; + void* pNext; + VkBool32 subgroupSizeControl; + VkBool32 computeFullSubgroups; +} VkPhysicalDeviceSubgroupSizeControlFeatures; + +typedef struct VkPhysicalDeviceSubgroupSizeControlProperties { + VkStructureType sType; + void* pNext; + uint32_t minSubgroupSize; + uint32_t maxSubgroupSize; + uint32_t maxComputeWorkgroupSubgroups; + VkShaderStageFlags requiredSubgroupSizeStages; +} VkPhysicalDeviceSubgroupSizeControlProperties; + +typedef struct VkPipelineShaderStageRequiredSubgroupSizeCreateInfo { + VkStructureType sType; + void* pNext; + uint32_t requiredSubgroupSize; +} VkPipelineShaderStageRequiredSubgroupSizeCreateInfo; + +typedef struct VkPhysicalDeviceInlineUniformBlockFeatures { + VkStructureType sType; + void* pNext; + VkBool32 inlineUniformBlock; + VkBool32 descriptorBindingInlineUniformBlockUpdateAfterBind; +} VkPhysicalDeviceInlineUniformBlockFeatures; + +typedef struct VkPhysicalDeviceInlineUniformBlockProperties { + VkStructureType sType; + void* pNext; + uint32_t maxInlineUniformBlockSize; + uint32_t maxPerStageDescriptorInlineUniformBlocks; + uint32_t maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks; + uint32_t maxDescriptorSetInlineUniformBlocks; + uint32_t maxDescriptorSetUpdateAfterBindInlineUniformBlocks; +} VkPhysicalDeviceInlineUniformBlockProperties; + +typedef struct VkWriteDescriptorSetInlineUniformBlock { + VkStructureType sType; + const void* pNext; + uint32_t dataSize; + const void* pData; +} VkWriteDescriptorSetInlineUniformBlock; + +typedef struct VkDescriptorPoolInlineUniformBlockCreateInfo { + VkStructureType sType; + const void* pNext; + uint32_t maxInlineUniformBlockBindings; +} VkDescriptorPoolInlineUniformBlockCreateInfo; + +typedef struct VkPhysicalDeviceTextureCompressionASTCHDRFeatures { + VkStructureType sType; + void* pNext; + VkBool32 textureCompressionASTC_HDR; +} VkPhysicalDeviceTextureCompressionASTCHDRFeatures; + +typedef struct VkRenderingAttachmentInfo { + VkStructureType sType; + const void* pNext; + VkImageView imageView; + VkImageLayout imageLayout; + VkResolveModeFlagBits resolveMode; + VkImageView resolveImageView; + VkImageLayout resolveImageLayout; + VkAttachmentLoadOp loadOp; + VkAttachmentStoreOp storeOp; + VkClearValue clearValue; +} VkRenderingAttachmentInfo; + +typedef struct VkRenderingInfo { + VkStructureType sType; + const void* pNext; + VkRenderingFlags flags; + VkRect2D renderArea; + uint32_t layerCount; + uint32_t viewMask; + uint32_t colorAttachmentCount; + const VkRenderingAttachmentInfo* pColorAttachments; + const VkRenderingAttachmentInfo* pDepthAttachment; + const VkRenderingAttachmentInfo* pStencilAttachment; +} VkRenderingInfo; + +typedef struct VkPipelineRenderingCreateInfo { + VkStructureType sType; + const void* pNext; + uint32_t viewMask; + uint32_t colorAttachmentCount; + const VkFormat* pColorAttachmentFormats; + VkFormat depthAttachmentFormat; + VkFormat stencilAttachmentFormat; +} VkPipelineRenderingCreateInfo; + +typedef struct VkPhysicalDeviceDynamicRenderingFeatures { + VkStructureType sType; + void* pNext; + VkBool32 dynamicRendering; +} VkPhysicalDeviceDynamicRenderingFeatures; + +typedef struct VkCommandBufferInheritanceRenderingInfo { + VkStructureType sType; + const void* pNext; + VkRenderingFlags flags; + uint32_t viewMask; + uint32_t colorAttachmentCount; + const VkFormat* pColorAttachmentFormats; + VkFormat depthAttachmentFormat; + VkFormat stencilAttachmentFormat; + VkSampleCountFlagBits rasterizationSamples; +} VkCommandBufferInheritanceRenderingInfo; + +typedef struct VkPhysicalDeviceShaderIntegerDotProductFeatures { + VkStructureType sType; + void* pNext; + VkBool32 shaderIntegerDotProduct; +} VkPhysicalDeviceShaderIntegerDotProductFeatures; + +typedef struct VkPhysicalDeviceShaderIntegerDotProductProperties { + VkStructureType sType; + void* pNext; + VkBool32 integerDotProduct8BitUnsignedAccelerated; + VkBool32 integerDotProduct8BitSignedAccelerated; + VkBool32 integerDotProduct8BitMixedSignednessAccelerated; + VkBool32 integerDotProduct4x8BitPackedUnsignedAccelerated; + VkBool32 integerDotProduct4x8BitPackedSignedAccelerated; + VkBool32 integerDotProduct4x8BitPackedMixedSignednessAccelerated; + VkBool32 integerDotProduct16BitUnsignedAccelerated; + VkBool32 integerDotProduct16BitSignedAccelerated; + VkBool32 integerDotProduct16BitMixedSignednessAccelerated; + VkBool32 integerDotProduct32BitUnsignedAccelerated; + VkBool32 integerDotProduct32BitSignedAccelerated; + VkBool32 integerDotProduct32BitMixedSignednessAccelerated; + VkBool32 integerDotProduct64BitUnsignedAccelerated; + VkBool32 integerDotProduct64BitSignedAccelerated; + VkBool32 integerDotProduct64BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating8BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating8BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating16BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating16BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating32BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating32BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated; + VkBool32 integerDotProductAccumulatingSaturating64BitUnsignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating64BitSignedAccelerated; + VkBool32 integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated; +} VkPhysicalDeviceShaderIntegerDotProductProperties; + +typedef struct VkPhysicalDeviceTexelBufferAlignmentProperties { + VkStructureType sType; + void* pNext; + VkDeviceSize storageTexelBufferOffsetAlignmentBytes; + VkBool32 storageTexelBufferOffsetSingleTexelAlignment; + VkDeviceSize uniformTexelBufferOffsetAlignmentBytes; + VkBool32 uniformTexelBufferOffsetSingleTexelAlignment; +} VkPhysicalDeviceTexelBufferAlignmentProperties; + +typedef struct VkFormatProperties3 { + VkStructureType sType; + void* pNext; + VkFormatFeatureFlags2 linearTilingFeatures; + VkFormatFeatureFlags2 optimalTilingFeatures; + VkFormatFeatureFlags2 bufferFeatures; +} VkFormatProperties3; + +typedef struct VkPhysicalDeviceMaintenance4Features { + VkStructureType sType; + void* pNext; + VkBool32 maintenance4; +} VkPhysicalDeviceMaintenance4Features; + +typedef struct VkPhysicalDeviceMaintenance4Properties { + VkStructureType sType; + void* pNext; + VkDeviceSize maxBufferSize; +} VkPhysicalDeviceMaintenance4Properties; + +typedef struct VkDeviceBufferMemoryRequirements { + VkStructureType sType; + const void* pNext; + const VkBufferCreateInfo* pCreateInfo; +} VkDeviceBufferMemoryRequirements; + +typedef struct VkDeviceImageMemoryRequirements { + VkStructureType sType; + const void* pNext; + const VkImageCreateInfo* pCreateInfo; + VkImageAspectFlagBits planeAspect; +} VkDeviceImageMemoryRequirements; + +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceToolProperties)(VkPhysicalDevice physicalDevice, uint32_t* pToolCount, VkPhysicalDeviceToolProperties* pToolProperties); +typedef VkResult (VKAPI_PTR *PFN_vkCreatePrivateDataSlot)(VkDevice device, const VkPrivateDataSlotCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPrivateDataSlot* pPrivateDataSlot); +typedef void (VKAPI_PTR *PFN_vkDestroyPrivateDataSlot)(VkDevice device, VkPrivateDataSlot privateDataSlot, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkSetPrivateData)(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlot privateDataSlot, uint64_t data); +typedef void (VKAPI_PTR *PFN_vkGetPrivateData)(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlot privateDataSlot, uint64_t* pData); +typedef void (VKAPI_PTR *PFN_vkCmdSetEvent2)(VkCommandBuffer commandBuffer, VkEvent event, const VkDependencyInfo* pDependencyInfo); +typedef void (VKAPI_PTR *PFN_vkCmdResetEvent2)(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags2 stageMask); +typedef void (VKAPI_PTR *PFN_vkCmdWaitEvents2)(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent* pEvents, const VkDependencyInfo* pDependencyInfos); +typedef void (VKAPI_PTR *PFN_vkCmdPipelineBarrier2)(VkCommandBuffer commandBuffer, const VkDependencyInfo* pDependencyInfo); +typedef void (VKAPI_PTR *PFN_vkCmdWriteTimestamp2)(VkCommandBuffer commandBuffer, VkPipelineStageFlags2 stage, VkQueryPool queryPool, uint32_t query); +typedef VkResult (VKAPI_PTR *PFN_vkQueueSubmit2)(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2* pSubmits, VkFence fence); +typedef void (VKAPI_PTR *PFN_vkCmdCopyBuffer2)(VkCommandBuffer commandBuffer, const VkCopyBufferInfo2* pCopyBufferInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyImage2)(VkCommandBuffer commandBuffer, const VkCopyImageInfo2* pCopyImageInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyBufferToImage2)(VkCommandBuffer commandBuffer, const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyImageToBuffer2)(VkCommandBuffer commandBuffer, const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo); +typedef void (VKAPI_PTR *PFN_vkCmdBlitImage2)(VkCommandBuffer commandBuffer, const VkBlitImageInfo2* pBlitImageInfo); +typedef void (VKAPI_PTR *PFN_vkCmdResolveImage2)(VkCommandBuffer commandBuffer, const VkResolveImageInfo2* pResolveImageInfo); +typedef void (VKAPI_PTR *PFN_vkCmdBeginRendering)(VkCommandBuffer commandBuffer, const VkRenderingInfo* pRenderingInfo); +typedef void (VKAPI_PTR *PFN_vkCmdEndRendering)(VkCommandBuffer commandBuffer); +typedef void (VKAPI_PTR *PFN_vkCmdSetCullMode)(VkCommandBuffer commandBuffer, VkCullModeFlags cullMode); +typedef void (VKAPI_PTR *PFN_vkCmdSetFrontFace)(VkCommandBuffer commandBuffer, VkFrontFace frontFace); +typedef void (VKAPI_PTR *PFN_vkCmdSetPrimitiveTopology)(VkCommandBuffer commandBuffer, VkPrimitiveTopology primitiveTopology); +typedef void (VKAPI_PTR *PFN_vkCmdSetViewportWithCount)(VkCommandBuffer commandBuffer, uint32_t viewportCount, const VkViewport* pViewports); +typedef void (VKAPI_PTR *PFN_vkCmdSetScissorWithCount)(VkCommandBuffer commandBuffer, uint32_t scissorCount, const VkRect2D* pScissors); +typedef void (VKAPI_PTR *PFN_vkCmdBindVertexBuffers2)(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, const VkBuffer* pBuffers, const VkDeviceSize* pOffsets, const VkDeviceSize* pSizes, const VkDeviceSize* pStrides); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthTestEnable)(VkCommandBuffer commandBuffer, VkBool32 depthTestEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthWriteEnable)(VkCommandBuffer commandBuffer, VkBool32 depthWriteEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthCompareOp)(VkCommandBuffer commandBuffer, VkCompareOp depthCompareOp); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthBoundsTestEnable)(VkCommandBuffer commandBuffer, VkBool32 depthBoundsTestEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetStencilTestEnable)(VkCommandBuffer commandBuffer, VkBool32 stencilTestEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetStencilOp)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, VkStencilOp failOp, VkStencilOp passOp, VkStencilOp depthFailOp, VkCompareOp compareOp); +typedef void (VKAPI_PTR *PFN_vkCmdSetRasterizerDiscardEnable)(VkCommandBuffer commandBuffer, VkBool32 rasterizerDiscardEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthBiasEnable)(VkCommandBuffer commandBuffer, VkBool32 depthBiasEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetPrimitiveRestartEnable)(VkCommandBuffer commandBuffer, VkBool32 primitiveRestartEnable); +typedef void (VKAPI_PTR *PFN_vkGetDeviceBufferMemoryRequirements)(VkDevice device, const VkDeviceBufferMemoryRequirements* pInfo, VkMemoryRequirements2* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetDeviceImageMemoryRequirements)(VkDevice device, const VkDeviceImageMemoryRequirements* pInfo, VkMemoryRequirements2* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetDeviceImageSparseMemoryRequirements)(VkDevice device, const VkDeviceImageMemoryRequirements* pInfo, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2* pSparseMemoryRequirements); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceToolProperties( + VkPhysicalDevice physicalDevice, + uint32_t* pToolCount, + VkPhysicalDeviceToolProperties* pToolProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreatePrivateDataSlot( + VkDevice device, + const VkPrivateDataSlotCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkPrivateDataSlot* pPrivateDataSlot); + +VKAPI_ATTR void VKAPI_CALL vkDestroyPrivateDataSlot( + VkDevice device, + VkPrivateDataSlot privateDataSlot, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkSetPrivateData( + VkDevice device, + VkObjectType objectType, + uint64_t objectHandle, + VkPrivateDataSlot privateDataSlot, + uint64_t data); + +VKAPI_ATTR void VKAPI_CALL vkGetPrivateData( + VkDevice device, + VkObjectType objectType, + uint64_t objectHandle, + VkPrivateDataSlot privateDataSlot, + uint64_t* pData); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetEvent2( + VkCommandBuffer commandBuffer, + VkEvent event, + const VkDependencyInfo* pDependencyInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdResetEvent2( + VkCommandBuffer commandBuffer, + VkEvent event, + VkPipelineStageFlags2 stageMask); + +VKAPI_ATTR void VKAPI_CALL vkCmdWaitEvents2( + VkCommandBuffer commandBuffer, + uint32_t eventCount, + const VkEvent* pEvents, + const VkDependencyInfo* pDependencyInfos); + +VKAPI_ATTR void VKAPI_CALL vkCmdPipelineBarrier2( + VkCommandBuffer commandBuffer, + const VkDependencyInfo* pDependencyInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdWriteTimestamp2( + VkCommandBuffer commandBuffer, + VkPipelineStageFlags2 stage, + VkQueryPool queryPool, + uint32_t query); + +VKAPI_ATTR VkResult VKAPI_CALL vkQueueSubmit2( + VkQueue queue, + uint32_t submitCount, + const VkSubmitInfo2* pSubmits, + VkFence fence); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyBuffer2( + VkCommandBuffer commandBuffer, + const VkCopyBufferInfo2* pCopyBufferInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyImage2( + VkCommandBuffer commandBuffer, + const VkCopyImageInfo2* pCopyImageInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyBufferToImage2( + VkCommandBuffer commandBuffer, + const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyImageToBuffer2( + VkCommandBuffer commandBuffer, + const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdBlitImage2( + VkCommandBuffer commandBuffer, + const VkBlitImageInfo2* pBlitImageInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdResolveImage2( + VkCommandBuffer commandBuffer, + const VkResolveImageInfo2* pResolveImageInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdBeginRendering( + VkCommandBuffer commandBuffer, + const VkRenderingInfo* pRenderingInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdEndRendering( + VkCommandBuffer commandBuffer); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetCullMode( + VkCommandBuffer commandBuffer, + VkCullModeFlags cullMode); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetFrontFace( + VkCommandBuffer commandBuffer, + VkFrontFace frontFace); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetPrimitiveTopology( + VkCommandBuffer commandBuffer, + VkPrimitiveTopology primitiveTopology); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetViewportWithCount( + VkCommandBuffer commandBuffer, + uint32_t viewportCount, + const VkViewport* pViewports); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetScissorWithCount( + VkCommandBuffer commandBuffer, + uint32_t scissorCount, + const VkRect2D* pScissors); + +VKAPI_ATTR void VKAPI_CALL vkCmdBindVertexBuffers2( + VkCommandBuffer commandBuffer, + uint32_t firstBinding, + uint32_t bindingCount, + const VkBuffer* pBuffers, + const VkDeviceSize* pOffsets, + const VkDeviceSize* pSizes, + const VkDeviceSize* pStrides); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthTestEnable( + VkCommandBuffer commandBuffer, + VkBool32 depthTestEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthWriteEnable( + VkCommandBuffer commandBuffer, + VkBool32 depthWriteEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthCompareOp( + VkCommandBuffer commandBuffer, + VkCompareOp depthCompareOp); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBoundsTestEnable( + VkCommandBuffer commandBuffer, + VkBool32 depthBoundsTestEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilTestEnable( + VkCommandBuffer commandBuffer, + VkBool32 stencilTestEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilOp( + VkCommandBuffer commandBuffer, + VkStencilFaceFlags faceMask, + VkStencilOp failOp, + VkStencilOp passOp, + VkStencilOp depthFailOp, + VkCompareOp compareOp); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetRasterizerDiscardEnable( + VkCommandBuffer commandBuffer, + VkBool32 rasterizerDiscardEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBiasEnable( + VkCommandBuffer commandBuffer, + VkBool32 depthBiasEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetPrimitiveRestartEnable( + VkCommandBuffer commandBuffer, + VkBool32 primitiveRestartEnable); + +VKAPI_ATTR void VKAPI_CALL vkGetDeviceBufferMemoryRequirements( + VkDevice device, + const VkDeviceBufferMemoryRequirements* pInfo, + VkMemoryRequirements2* pMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkGetDeviceImageMemoryRequirements( + VkDevice device, + const VkDeviceImageMemoryRequirements* pInfo, + VkMemoryRequirements2* pMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkGetDeviceImageSparseMemoryRequirements( + VkDevice device, + const VkDeviceImageMemoryRequirements* pInfo, + uint32_t* pSparseMemoryRequirementCount, + VkSparseImageMemoryRequirements2* pSparseMemoryRequirements); +#endif + + +// VK_KHR_surface is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_surface 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR) +#define VK_KHR_SURFACE_SPEC_VERSION 25 +#define VK_KHR_SURFACE_EXTENSION_NAME "VK_KHR_surface" + +typedef enum VkPresentModeKHR { + VK_PRESENT_MODE_IMMEDIATE_KHR = 0, + VK_PRESENT_MODE_MAILBOX_KHR = 1, + VK_PRESENT_MODE_FIFO_KHR = 2, + VK_PRESENT_MODE_FIFO_RELAXED_KHR = 3, + VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR = 1000111000, + VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR = 1000111001, + VK_PRESENT_MODE_MAX_ENUM_KHR = 0x7FFFFFFF +} VkPresentModeKHR; + +typedef enum VkColorSpaceKHR { + VK_COLOR_SPACE_SRGB_NONLINEAR_KHR = 0, + VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT = 1000104001, + VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT = 1000104002, + VK_COLOR_SPACE_DISPLAY_P3_LINEAR_EXT = 1000104003, + VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT = 1000104004, + VK_COLOR_SPACE_BT709_LINEAR_EXT = 1000104005, + VK_COLOR_SPACE_BT709_NONLINEAR_EXT = 1000104006, + VK_COLOR_SPACE_BT2020_LINEAR_EXT = 1000104007, + VK_COLOR_SPACE_HDR10_ST2084_EXT = 1000104008, + VK_COLOR_SPACE_DOLBYVISION_EXT = 1000104009, + VK_COLOR_SPACE_HDR10_HLG_EXT = 1000104010, + VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT = 1000104011, + VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT = 1000104012, + VK_COLOR_SPACE_PASS_THROUGH_EXT = 1000104013, + VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT = 1000104014, + VK_COLOR_SPACE_DISPLAY_NATIVE_AMD = 1000213000, + VK_COLORSPACE_SRGB_NONLINEAR_KHR = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, + VK_COLOR_SPACE_DCI_P3_LINEAR_EXT = VK_COLOR_SPACE_DISPLAY_P3_LINEAR_EXT, + VK_COLOR_SPACE_MAX_ENUM_KHR = 0x7FFFFFFF +} VkColorSpaceKHR; + +typedef enum VkSurfaceTransformFlagBitsKHR { + VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR = 0x00000001, + VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR = 0x00000002, + VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR = 0x00000004, + VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR = 0x00000008, + VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR = 0x00000010, + VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR = 0x00000020, + VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR = 0x00000040, + VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR = 0x00000080, + VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR = 0x00000100, + VK_SURFACE_TRANSFORM_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkSurfaceTransformFlagBitsKHR; + +typedef enum VkCompositeAlphaFlagBitsKHR { + VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR = 0x00000001, + VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR = 0x00000002, + VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR = 0x00000004, + VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR = 0x00000008, + VK_COMPOSITE_ALPHA_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkCompositeAlphaFlagBitsKHR; +typedef VkFlags VkCompositeAlphaFlagsKHR; +typedef VkFlags VkSurfaceTransformFlagsKHR; +typedef struct VkSurfaceCapabilitiesKHR { + uint32_t minImageCount; + uint32_t maxImageCount; + VkExtent2D currentExtent; + VkExtent2D minImageExtent; + VkExtent2D maxImageExtent; + uint32_t maxImageArrayLayers; + VkSurfaceTransformFlagsKHR supportedTransforms; + VkSurfaceTransformFlagBitsKHR currentTransform; + VkCompositeAlphaFlagsKHR supportedCompositeAlpha; + VkImageUsageFlags supportedUsageFlags; +} VkSurfaceCapabilitiesKHR; + +typedef struct VkSurfaceFormatKHR { + VkFormat format; + VkColorSpaceKHR colorSpace; +} VkSurfaceFormatKHR; + +typedef void (VKAPI_PTR *PFN_vkDestroySurfaceKHR)(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, VkSurfaceKHR surface, VkBool32* pSupported); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR* pSurfaceCapabilities); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceFormatsKHR)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t* pSurfaceFormatCount, VkSurfaceFormatKHR* pSurfaceFormats); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfacePresentModesKHR)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t* pPresentModeCount, VkPresentModeKHR* pPresentModes); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkDestroySurfaceKHR( + VkInstance instance, + VkSurfaceKHR surface, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceSupportKHR( + VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex, + VkSurfaceKHR surface, + VkBool32* pSupported); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilitiesKHR( + VkPhysicalDevice physicalDevice, + VkSurfaceKHR surface, + VkSurfaceCapabilitiesKHR* pSurfaceCapabilities); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceFormatsKHR( + VkPhysicalDevice physicalDevice, + VkSurfaceKHR surface, + uint32_t* pSurfaceFormatCount, + VkSurfaceFormatKHR* pSurfaceFormats); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfacePresentModesKHR( + VkPhysicalDevice physicalDevice, + VkSurfaceKHR surface, + uint32_t* pPresentModeCount, + VkPresentModeKHR* pPresentModes); +#endif + + +// VK_KHR_swapchain is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_swapchain 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSwapchainKHR) +#define VK_KHR_SWAPCHAIN_SPEC_VERSION 70 +#define VK_KHR_SWAPCHAIN_EXTENSION_NAME "VK_KHR_swapchain" + +typedef enum VkSwapchainCreateFlagBitsKHR { + VK_SWAPCHAIN_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_KHR = 0x00000001, + VK_SWAPCHAIN_CREATE_PROTECTED_BIT_KHR = 0x00000002, + VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR = 0x00000004, + VK_SWAPCHAIN_CREATE_DEFERRED_MEMORY_ALLOCATION_BIT_EXT = 0x00000008, + VK_SWAPCHAIN_CREATE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkSwapchainCreateFlagBitsKHR; +typedef VkFlags VkSwapchainCreateFlagsKHR; + +typedef enum VkDeviceGroupPresentModeFlagBitsKHR { + VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR = 0x00000001, + VK_DEVICE_GROUP_PRESENT_MODE_REMOTE_BIT_KHR = 0x00000002, + VK_DEVICE_GROUP_PRESENT_MODE_SUM_BIT_KHR = 0x00000004, + VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_MULTI_DEVICE_BIT_KHR = 0x00000008, + VK_DEVICE_GROUP_PRESENT_MODE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkDeviceGroupPresentModeFlagBitsKHR; +typedef VkFlags VkDeviceGroupPresentModeFlagsKHR; +typedef struct VkSwapchainCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkSwapchainCreateFlagsKHR flags; + VkSurfaceKHR surface; + uint32_t minImageCount; + VkFormat imageFormat; + VkColorSpaceKHR imageColorSpace; + VkExtent2D imageExtent; + uint32_t imageArrayLayers; + VkImageUsageFlags imageUsage; + VkSharingMode imageSharingMode; + uint32_t queueFamilyIndexCount; + const uint32_t* pQueueFamilyIndices; + VkSurfaceTransformFlagBitsKHR preTransform; + VkCompositeAlphaFlagBitsKHR compositeAlpha; + VkPresentModeKHR presentMode; + VkBool32 clipped; + VkSwapchainKHR oldSwapchain; +} VkSwapchainCreateInfoKHR; + +typedef struct VkPresentInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t waitSemaphoreCount; + const VkSemaphore* pWaitSemaphores; + uint32_t swapchainCount; + const VkSwapchainKHR* pSwapchains; + const uint32_t* pImageIndices; + VkResult* pResults; +} VkPresentInfoKHR; + +typedef struct VkImageSwapchainCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkSwapchainKHR swapchain; +} VkImageSwapchainCreateInfoKHR; + +typedef struct VkBindImageMemorySwapchainInfoKHR { + VkStructureType sType; + const void* pNext; + VkSwapchainKHR swapchain; + uint32_t imageIndex; +} VkBindImageMemorySwapchainInfoKHR; + +typedef struct VkAcquireNextImageInfoKHR { + VkStructureType sType; + const void* pNext; + VkSwapchainKHR swapchain; + uint64_t timeout; + VkSemaphore semaphore; + VkFence fence; + uint32_t deviceMask; +} VkAcquireNextImageInfoKHR; + +typedef struct VkDeviceGroupPresentCapabilitiesKHR { + VkStructureType sType; + void* pNext; + uint32_t presentMask[VK_MAX_DEVICE_GROUP_SIZE]; + VkDeviceGroupPresentModeFlagsKHR modes; +} VkDeviceGroupPresentCapabilitiesKHR; + +typedef struct VkDeviceGroupPresentInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t swapchainCount; + const uint32_t* pDeviceMasks; + VkDeviceGroupPresentModeFlagBitsKHR mode; +} VkDeviceGroupPresentInfoKHR; + +typedef struct VkDeviceGroupSwapchainCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkDeviceGroupPresentModeFlagsKHR modes; +} VkDeviceGroupSwapchainCreateInfoKHR; + +typedef VkResult (VKAPI_PTR *PFN_vkCreateSwapchainKHR)(VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchain); +typedef void (VKAPI_PTR *PFN_vkDestroySwapchainKHR)(VkDevice device, VkSwapchainKHR swapchain, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainImagesKHR)(VkDevice device, VkSwapchainKHR swapchain, uint32_t* pSwapchainImageCount, VkImage* pSwapchainImages); +typedef VkResult (VKAPI_PTR *PFN_vkAcquireNextImageKHR)(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t* pImageIndex); +typedef VkResult (VKAPI_PTR *PFN_vkQueuePresentKHR)(VkQueue queue, const VkPresentInfoKHR* pPresentInfo); +typedef VkResult (VKAPI_PTR *PFN_vkGetDeviceGroupPresentCapabilitiesKHR)(VkDevice device, VkDeviceGroupPresentCapabilitiesKHR* pDeviceGroupPresentCapabilities); +typedef VkResult (VKAPI_PTR *PFN_vkGetDeviceGroupSurfacePresentModesKHR)(VkDevice device, VkSurfaceKHR surface, VkDeviceGroupPresentModeFlagsKHR* pModes); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDevicePresentRectanglesKHR)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint32_t* pRectCount, VkRect2D* pRects); +typedef VkResult (VKAPI_PTR *PFN_vkAcquireNextImage2KHR)(VkDevice device, const VkAcquireNextImageInfoKHR* pAcquireInfo, uint32_t* pImageIndex); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateSwapchainKHR( + VkDevice device, + const VkSwapchainCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSwapchainKHR* pSwapchain); + +VKAPI_ATTR void VKAPI_CALL vkDestroySwapchainKHR( + VkDevice device, + VkSwapchainKHR swapchain, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainImagesKHR( + VkDevice device, + VkSwapchainKHR swapchain, + uint32_t* pSwapchainImageCount, + VkImage* pSwapchainImages); + +VKAPI_ATTR VkResult VKAPI_CALL vkAcquireNextImageKHR( + VkDevice device, + VkSwapchainKHR swapchain, + uint64_t timeout, + VkSemaphore semaphore, + VkFence fence, + uint32_t* pImageIndex); + +VKAPI_ATTR VkResult VKAPI_CALL vkQueuePresentKHR( + VkQueue queue, + const VkPresentInfoKHR* pPresentInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceGroupPresentCapabilitiesKHR( + VkDevice device, + VkDeviceGroupPresentCapabilitiesKHR* pDeviceGroupPresentCapabilities); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceGroupSurfacePresentModesKHR( + VkDevice device, + VkSurfaceKHR surface, + VkDeviceGroupPresentModeFlagsKHR* pModes); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDevicePresentRectanglesKHR( + VkPhysicalDevice physicalDevice, + VkSurfaceKHR surface, + uint32_t* pRectCount, + VkRect2D* pRects); + +VKAPI_ATTR VkResult VKAPI_CALL vkAcquireNextImage2KHR( + VkDevice device, + const VkAcquireNextImageInfoKHR* pAcquireInfo, + uint32_t* pImageIndex); +#endif + + +// VK_KHR_display is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_display 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDisplayKHR) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDisplayModeKHR) +#define VK_KHR_DISPLAY_SPEC_VERSION 23 +#define VK_KHR_DISPLAY_EXTENSION_NAME "VK_KHR_display" +typedef VkFlags VkDisplayModeCreateFlagsKHR; + +typedef enum VkDisplayPlaneAlphaFlagBitsKHR { + VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR = 0x00000001, + VK_DISPLAY_PLANE_ALPHA_GLOBAL_BIT_KHR = 0x00000002, + VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_BIT_KHR = 0x00000004, + VK_DISPLAY_PLANE_ALPHA_PER_PIXEL_PREMULTIPLIED_BIT_KHR = 0x00000008, + VK_DISPLAY_PLANE_ALPHA_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkDisplayPlaneAlphaFlagBitsKHR; +typedef VkFlags VkDisplayPlaneAlphaFlagsKHR; +typedef VkFlags VkDisplaySurfaceCreateFlagsKHR; +typedef struct VkDisplayModeParametersKHR { + VkExtent2D visibleRegion; + uint32_t refreshRate; +} VkDisplayModeParametersKHR; + +typedef struct VkDisplayModeCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkDisplayModeCreateFlagsKHR flags; + VkDisplayModeParametersKHR parameters; +} VkDisplayModeCreateInfoKHR; + +typedef struct VkDisplayModePropertiesKHR { + VkDisplayModeKHR displayMode; + VkDisplayModeParametersKHR parameters; +} VkDisplayModePropertiesKHR; + +typedef struct VkDisplayPlaneCapabilitiesKHR { + VkDisplayPlaneAlphaFlagsKHR supportedAlpha; + VkOffset2D minSrcPosition; + VkOffset2D maxSrcPosition; + VkExtent2D minSrcExtent; + VkExtent2D maxSrcExtent; + VkOffset2D minDstPosition; + VkOffset2D maxDstPosition; + VkExtent2D minDstExtent; + VkExtent2D maxDstExtent; +} VkDisplayPlaneCapabilitiesKHR; + +typedef struct VkDisplayPlanePropertiesKHR { + VkDisplayKHR currentDisplay; + uint32_t currentStackIndex; +} VkDisplayPlanePropertiesKHR; + +typedef struct VkDisplayPropertiesKHR { + VkDisplayKHR display; + const char* displayName; + VkExtent2D physicalDimensions; + VkExtent2D physicalResolution; + VkSurfaceTransformFlagsKHR supportedTransforms; + VkBool32 planeReorderPossible; + VkBool32 persistentContent; +} VkDisplayPropertiesKHR; + +typedef struct VkDisplaySurfaceCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkDisplaySurfaceCreateFlagsKHR flags; + VkDisplayModeKHR displayMode; + uint32_t planeIndex; + uint32_t planeStackIndex; + VkSurfaceTransformFlagBitsKHR transform; + float globalAlpha; + VkDisplayPlaneAlphaFlagBitsKHR alphaMode; + VkExtent2D imageExtent; +} VkDisplaySurfaceCreateInfoKHR; + +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceDisplayPropertiesKHR)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkDisplayPropertiesKHR* pProperties); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkDisplayPlanePropertiesKHR* pProperties); +typedef VkResult (VKAPI_PTR *PFN_vkGetDisplayPlaneSupportedDisplaysKHR)(VkPhysicalDevice physicalDevice, uint32_t planeIndex, uint32_t* pDisplayCount, VkDisplayKHR* pDisplays); +typedef VkResult (VKAPI_PTR *PFN_vkGetDisplayModePropertiesKHR)(VkPhysicalDevice physicalDevice, VkDisplayKHR display, uint32_t* pPropertyCount, VkDisplayModePropertiesKHR* pProperties); +typedef VkResult (VKAPI_PTR *PFN_vkCreateDisplayModeKHR)(VkPhysicalDevice physicalDevice, VkDisplayKHR display, const VkDisplayModeCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDisplayModeKHR* pMode); +typedef VkResult (VKAPI_PTR *PFN_vkGetDisplayPlaneCapabilitiesKHR)(VkPhysicalDevice physicalDevice, VkDisplayModeKHR mode, uint32_t planeIndex, VkDisplayPlaneCapabilitiesKHR* pCapabilities); +typedef VkResult (VKAPI_PTR *PFN_vkCreateDisplayPlaneSurfaceKHR)(VkInstance instance, const VkDisplaySurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPropertiesKHR( + VkPhysicalDevice physicalDevice, + uint32_t* pPropertyCount, + VkDisplayPropertiesKHR* pProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPlanePropertiesKHR( + VkPhysicalDevice physicalDevice, + uint32_t* pPropertyCount, + VkDisplayPlanePropertiesKHR* pProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneSupportedDisplaysKHR( + VkPhysicalDevice physicalDevice, + uint32_t planeIndex, + uint32_t* pDisplayCount, + VkDisplayKHR* pDisplays); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayModePropertiesKHR( + VkPhysicalDevice physicalDevice, + VkDisplayKHR display, + uint32_t* pPropertyCount, + VkDisplayModePropertiesKHR* pProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateDisplayModeKHR( + VkPhysicalDevice physicalDevice, + VkDisplayKHR display, + const VkDisplayModeCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkDisplayModeKHR* pMode); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneCapabilitiesKHR( + VkPhysicalDevice physicalDevice, + VkDisplayModeKHR mode, + uint32_t planeIndex, + VkDisplayPlaneCapabilitiesKHR* pCapabilities); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateDisplayPlaneSurfaceKHR( + VkInstance instance, + const VkDisplaySurfaceCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface); +#endif + + +// VK_KHR_display_swapchain is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_display_swapchain 1 +#define VK_KHR_DISPLAY_SWAPCHAIN_SPEC_VERSION 10 +#define VK_KHR_DISPLAY_SWAPCHAIN_EXTENSION_NAME "VK_KHR_display_swapchain" +typedef struct VkDisplayPresentInfoKHR { + VkStructureType sType; + const void* pNext; + VkRect2D srcRect; + VkRect2D dstRect; + VkBool32 persistent; +} VkDisplayPresentInfoKHR; + +typedef VkResult (VKAPI_PTR *PFN_vkCreateSharedSwapchainsKHR)(VkDevice device, uint32_t swapchainCount, const VkSwapchainCreateInfoKHR* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchains); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateSharedSwapchainsKHR( + VkDevice device, + uint32_t swapchainCount, + const VkSwapchainCreateInfoKHR* pCreateInfos, + const VkAllocationCallbacks* pAllocator, + VkSwapchainKHR* pSwapchains); +#endif + + +// VK_KHR_sampler_mirror_clamp_to_edge is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_sampler_mirror_clamp_to_edge 1 +#define VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_SPEC_VERSION 3 +#define VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME "VK_KHR_sampler_mirror_clamp_to_edge" + + +// VK_KHR_video_queue is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_video_queue 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkVideoSessionKHR) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkVideoSessionParametersKHR) +#define VK_KHR_VIDEO_QUEUE_SPEC_VERSION 8 +#define VK_KHR_VIDEO_QUEUE_EXTENSION_NAME "VK_KHR_video_queue" + +typedef enum VkQueryResultStatusKHR { + VK_QUERY_RESULT_STATUS_ERROR_KHR = -1, + VK_QUERY_RESULT_STATUS_NOT_READY_KHR = 0, + VK_QUERY_RESULT_STATUS_COMPLETE_KHR = 1, + VK_QUERY_RESULT_STATUS_INSUFFICIENT_BITSTREAM_BUFFER_RANGE_KHR = -1000299000, + VK_QUERY_RESULT_STATUS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkQueryResultStatusKHR; + +typedef enum VkVideoCodecOperationFlagBitsKHR { + VK_VIDEO_CODEC_OPERATION_NONE_KHR = 0, + VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_KHR = 0x00010000, + VK_VIDEO_CODEC_OPERATION_ENCODE_H265_BIT_KHR = 0x00020000, + VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR = 0x00000001, + VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR = 0x00000002, + VK_VIDEO_CODEC_OPERATION_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkVideoCodecOperationFlagBitsKHR; +typedef VkFlags VkVideoCodecOperationFlagsKHR; + +typedef enum VkVideoChromaSubsamplingFlagBitsKHR { + VK_VIDEO_CHROMA_SUBSAMPLING_INVALID_KHR = 0, + VK_VIDEO_CHROMA_SUBSAMPLING_MONOCHROME_BIT_KHR = 0x00000001, + VK_VIDEO_CHROMA_SUBSAMPLING_420_BIT_KHR = 0x00000002, + VK_VIDEO_CHROMA_SUBSAMPLING_422_BIT_KHR = 0x00000004, + VK_VIDEO_CHROMA_SUBSAMPLING_444_BIT_KHR = 0x00000008, + VK_VIDEO_CHROMA_SUBSAMPLING_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkVideoChromaSubsamplingFlagBitsKHR; +typedef VkFlags VkVideoChromaSubsamplingFlagsKHR; + +typedef enum VkVideoComponentBitDepthFlagBitsKHR { + VK_VIDEO_COMPONENT_BIT_DEPTH_INVALID_KHR = 0, + VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR = 0x00000001, + VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR = 0x00000004, + VK_VIDEO_COMPONENT_BIT_DEPTH_12_BIT_KHR = 0x00000010, + VK_VIDEO_COMPONENT_BIT_DEPTH_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkVideoComponentBitDepthFlagBitsKHR; +typedef VkFlags VkVideoComponentBitDepthFlagsKHR; + +typedef enum VkVideoCapabilityFlagBitsKHR { + VK_VIDEO_CAPABILITY_PROTECTED_CONTENT_BIT_KHR = 0x00000001, + VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR = 0x00000002, + VK_VIDEO_CAPABILITY_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkVideoCapabilityFlagBitsKHR; +typedef VkFlags VkVideoCapabilityFlagsKHR; + +typedef enum VkVideoSessionCreateFlagBitsKHR { + VK_VIDEO_SESSION_CREATE_PROTECTED_CONTENT_BIT_KHR = 0x00000001, + VK_VIDEO_SESSION_CREATE_ALLOW_ENCODE_PARAMETER_OPTIMIZATIONS_BIT_KHR = 0x00000002, + VK_VIDEO_SESSION_CREATE_INLINE_QUERIES_BIT_KHR = 0x00000004, + VK_VIDEO_SESSION_CREATE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkVideoSessionCreateFlagBitsKHR; +typedef VkFlags VkVideoSessionCreateFlagsKHR; +typedef VkFlags VkVideoSessionParametersCreateFlagsKHR; +typedef VkFlags VkVideoBeginCodingFlagsKHR; +typedef VkFlags VkVideoEndCodingFlagsKHR; + +typedef enum VkVideoCodingControlFlagBitsKHR { + VK_VIDEO_CODING_CONTROL_RESET_BIT_KHR = 0x00000001, + VK_VIDEO_CODING_CONTROL_ENCODE_RATE_CONTROL_BIT_KHR = 0x00000002, + VK_VIDEO_CODING_CONTROL_ENCODE_QUALITY_LEVEL_BIT_KHR = 0x00000004, + VK_VIDEO_CODING_CONTROL_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkVideoCodingControlFlagBitsKHR; +typedef VkFlags VkVideoCodingControlFlagsKHR; +typedef struct VkQueueFamilyQueryResultStatusPropertiesKHR { + VkStructureType sType; + void* pNext; + VkBool32 queryResultStatusSupport; +} VkQueueFamilyQueryResultStatusPropertiesKHR; + +typedef struct VkQueueFamilyVideoPropertiesKHR { + VkStructureType sType; + void* pNext; + VkVideoCodecOperationFlagsKHR videoCodecOperations; +} VkQueueFamilyVideoPropertiesKHR; + +typedef struct VkVideoProfileInfoKHR { + VkStructureType sType; + const void* pNext; + VkVideoCodecOperationFlagBitsKHR videoCodecOperation; + VkVideoChromaSubsamplingFlagsKHR chromaSubsampling; + VkVideoComponentBitDepthFlagsKHR lumaBitDepth; + VkVideoComponentBitDepthFlagsKHR chromaBitDepth; +} VkVideoProfileInfoKHR; + +typedef struct VkVideoProfileListInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t profileCount; + const VkVideoProfileInfoKHR* pProfiles; +} VkVideoProfileListInfoKHR; + +typedef struct VkVideoCapabilitiesKHR { + VkStructureType sType; + void* pNext; + VkVideoCapabilityFlagsKHR flags; + VkDeviceSize minBitstreamBufferOffsetAlignment; + VkDeviceSize minBitstreamBufferSizeAlignment; + VkExtent2D pictureAccessGranularity; + VkExtent2D minCodedExtent; + VkExtent2D maxCodedExtent; + uint32_t maxDpbSlots; + uint32_t maxActiveReferencePictures; + VkExtensionProperties stdHeaderVersion; +} VkVideoCapabilitiesKHR; + +typedef struct VkPhysicalDeviceVideoFormatInfoKHR { + VkStructureType sType; + const void* pNext; + VkImageUsageFlags imageUsage; +} VkPhysicalDeviceVideoFormatInfoKHR; + +typedef struct VkVideoFormatPropertiesKHR { + VkStructureType sType; + void* pNext; + VkFormat format; + VkComponentMapping componentMapping; + VkImageCreateFlags imageCreateFlags; + VkImageType imageType; + VkImageTiling imageTiling; + VkImageUsageFlags imageUsageFlags; +} VkVideoFormatPropertiesKHR; + +typedef struct VkVideoPictureResourceInfoKHR { + VkStructureType sType; + const void* pNext; + VkOffset2D codedOffset; + VkExtent2D codedExtent; + uint32_t baseArrayLayer; + VkImageView imageViewBinding; +} VkVideoPictureResourceInfoKHR; + +typedef struct VkVideoReferenceSlotInfoKHR { + VkStructureType sType; + const void* pNext; + int32_t slotIndex; + const VkVideoPictureResourceInfoKHR* pPictureResource; +} VkVideoReferenceSlotInfoKHR; + +typedef struct VkVideoSessionMemoryRequirementsKHR { + VkStructureType sType; + void* pNext; + uint32_t memoryBindIndex; + VkMemoryRequirements memoryRequirements; +} VkVideoSessionMemoryRequirementsKHR; + +typedef struct VkBindVideoSessionMemoryInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t memoryBindIndex; + VkDeviceMemory memory; + VkDeviceSize memoryOffset; + VkDeviceSize memorySize; +} VkBindVideoSessionMemoryInfoKHR; + +typedef struct VkVideoSessionCreateInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t queueFamilyIndex; + VkVideoSessionCreateFlagsKHR flags; + const VkVideoProfileInfoKHR* pVideoProfile; + VkFormat pictureFormat; + VkExtent2D maxCodedExtent; + VkFormat referencePictureFormat; + uint32_t maxDpbSlots; + uint32_t maxActiveReferencePictures; + const VkExtensionProperties* pStdHeaderVersion; +} VkVideoSessionCreateInfoKHR; + +typedef struct VkVideoSessionParametersCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkVideoSessionParametersCreateFlagsKHR flags; + VkVideoSessionParametersKHR videoSessionParametersTemplate; + VkVideoSessionKHR videoSession; +} VkVideoSessionParametersCreateInfoKHR; + +typedef struct VkVideoSessionParametersUpdateInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t updateSequenceCount; +} VkVideoSessionParametersUpdateInfoKHR; + +typedef struct VkVideoBeginCodingInfoKHR { + VkStructureType sType; + const void* pNext; + VkVideoBeginCodingFlagsKHR flags; + VkVideoSessionKHR videoSession; + VkVideoSessionParametersKHR videoSessionParameters; + uint32_t referenceSlotCount; + const VkVideoReferenceSlotInfoKHR* pReferenceSlots; +} VkVideoBeginCodingInfoKHR; + +typedef struct VkVideoEndCodingInfoKHR { + VkStructureType sType; + const void* pNext; + VkVideoEndCodingFlagsKHR flags; +} VkVideoEndCodingInfoKHR; + +typedef struct VkVideoCodingControlInfoKHR { + VkStructureType sType; + const void* pNext; + VkVideoCodingControlFlagsKHR flags; +} VkVideoCodingControlInfoKHR; + +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceVideoCapabilitiesKHR)(VkPhysicalDevice physicalDevice, const VkVideoProfileInfoKHR* pVideoProfile, VkVideoCapabilitiesKHR* pCapabilities); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceVideoFormatPropertiesKHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceVideoFormatInfoKHR* pVideoFormatInfo, uint32_t* pVideoFormatPropertyCount, VkVideoFormatPropertiesKHR* pVideoFormatProperties); +typedef VkResult (VKAPI_PTR *PFN_vkCreateVideoSessionKHR)(VkDevice device, const VkVideoSessionCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkVideoSessionKHR* pVideoSession); +typedef void (VKAPI_PTR *PFN_vkDestroyVideoSessionKHR)(VkDevice device, VkVideoSessionKHR videoSession, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkGetVideoSessionMemoryRequirementsKHR)(VkDevice device, VkVideoSessionKHR videoSession, uint32_t* pMemoryRequirementsCount, VkVideoSessionMemoryRequirementsKHR* pMemoryRequirements); +typedef VkResult (VKAPI_PTR *PFN_vkBindVideoSessionMemoryKHR)(VkDevice device, VkVideoSessionKHR videoSession, uint32_t bindSessionMemoryInfoCount, const VkBindVideoSessionMemoryInfoKHR* pBindSessionMemoryInfos); +typedef VkResult (VKAPI_PTR *PFN_vkCreateVideoSessionParametersKHR)(VkDevice device, const VkVideoSessionParametersCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkVideoSessionParametersKHR* pVideoSessionParameters); +typedef VkResult (VKAPI_PTR *PFN_vkUpdateVideoSessionParametersKHR)(VkDevice device, VkVideoSessionParametersKHR videoSessionParameters, const VkVideoSessionParametersUpdateInfoKHR* pUpdateInfo); +typedef void (VKAPI_PTR *PFN_vkDestroyVideoSessionParametersKHR)(VkDevice device, VkVideoSessionParametersKHR videoSessionParameters, const VkAllocationCallbacks* pAllocator); +typedef void (VKAPI_PTR *PFN_vkCmdBeginVideoCodingKHR)(VkCommandBuffer commandBuffer, const VkVideoBeginCodingInfoKHR* pBeginInfo); +typedef void (VKAPI_PTR *PFN_vkCmdEndVideoCodingKHR)(VkCommandBuffer commandBuffer, const VkVideoEndCodingInfoKHR* pEndCodingInfo); +typedef void (VKAPI_PTR *PFN_vkCmdControlVideoCodingKHR)(VkCommandBuffer commandBuffer, const VkVideoCodingControlInfoKHR* pCodingControlInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceVideoCapabilitiesKHR( + VkPhysicalDevice physicalDevice, + const VkVideoProfileInfoKHR* pVideoProfile, + VkVideoCapabilitiesKHR* pCapabilities); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceVideoFormatPropertiesKHR( + VkPhysicalDevice physicalDevice, + const VkPhysicalDeviceVideoFormatInfoKHR* pVideoFormatInfo, + uint32_t* pVideoFormatPropertyCount, + VkVideoFormatPropertiesKHR* pVideoFormatProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateVideoSessionKHR( + VkDevice device, + const VkVideoSessionCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkVideoSessionKHR* pVideoSession); + +VKAPI_ATTR void VKAPI_CALL vkDestroyVideoSessionKHR( + VkDevice device, + VkVideoSessionKHR videoSession, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetVideoSessionMemoryRequirementsKHR( + VkDevice device, + VkVideoSessionKHR videoSession, + uint32_t* pMemoryRequirementsCount, + VkVideoSessionMemoryRequirementsKHR* pMemoryRequirements); + +VKAPI_ATTR VkResult VKAPI_CALL vkBindVideoSessionMemoryKHR( + VkDevice device, + VkVideoSessionKHR videoSession, + uint32_t bindSessionMemoryInfoCount, + const VkBindVideoSessionMemoryInfoKHR* pBindSessionMemoryInfos); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateVideoSessionParametersKHR( + VkDevice device, + const VkVideoSessionParametersCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkVideoSessionParametersKHR* pVideoSessionParameters); + +VKAPI_ATTR VkResult VKAPI_CALL vkUpdateVideoSessionParametersKHR( + VkDevice device, + VkVideoSessionParametersKHR videoSessionParameters, + const VkVideoSessionParametersUpdateInfoKHR* pUpdateInfo); + +VKAPI_ATTR void VKAPI_CALL vkDestroyVideoSessionParametersKHR( + VkDevice device, + VkVideoSessionParametersKHR videoSessionParameters, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR void VKAPI_CALL vkCmdBeginVideoCodingKHR( + VkCommandBuffer commandBuffer, + const VkVideoBeginCodingInfoKHR* pBeginInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdEndVideoCodingKHR( + VkCommandBuffer commandBuffer, + const VkVideoEndCodingInfoKHR* pEndCodingInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdControlVideoCodingKHR( + VkCommandBuffer commandBuffer, + const VkVideoCodingControlInfoKHR* pCodingControlInfo); +#endif + + +// VK_KHR_video_decode_queue is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_video_decode_queue 1 +#define VK_KHR_VIDEO_DECODE_QUEUE_SPEC_VERSION 8 +#define VK_KHR_VIDEO_DECODE_QUEUE_EXTENSION_NAME "VK_KHR_video_decode_queue" + +typedef enum VkVideoDecodeCapabilityFlagBitsKHR { + VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR = 0x00000001, + VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_DISTINCT_BIT_KHR = 0x00000002, + VK_VIDEO_DECODE_CAPABILITY_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkVideoDecodeCapabilityFlagBitsKHR; +typedef VkFlags VkVideoDecodeCapabilityFlagsKHR; + +typedef enum VkVideoDecodeUsageFlagBitsKHR { + VK_VIDEO_DECODE_USAGE_DEFAULT_KHR = 0, + VK_VIDEO_DECODE_USAGE_TRANSCODING_BIT_KHR = 0x00000001, + VK_VIDEO_DECODE_USAGE_OFFLINE_BIT_KHR = 0x00000002, + VK_VIDEO_DECODE_USAGE_STREAMING_BIT_KHR = 0x00000004, + VK_VIDEO_DECODE_USAGE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkVideoDecodeUsageFlagBitsKHR; +typedef VkFlags VkVideoDecodeUsageFlagsKHR; +typedef VkFlags VkVideoDecodeFlagsKHR; +typedef struct VkVideoDecodeCapabilitiesKHR { + VkStructureType sType; + void* pNext; + VkVideoDecodeCapabilityFlagsKHR flags; +} VkVideoDecodeCapabilitiesKHR; + +typedef struct VkVideoDecodeUsageInfoKHR { + VkStructureType sType; + const void* pNext; + VkVideoDecodeUsageFlagsKHR videoUsageHints; +} VkVideoDecodeUsageInfoKHR; + +typedef struct VkVideoDecodeInfoKHR { + VkStructureType sType; + const void* pNext; + VkVideoDecodeFlagsKHR flags; + VkBuffer srcBuffer; + VkDeviceSize srcBufferOffset; + VkDeviceSize srcBufferRange; + VkVideoPictureResourceInfoKHR dstPictureResource; + const VkVideoReferenceSlotInfoKHR* pSetupReferenceSlot; + uint32_t referenceSlotCount; + const VkVideoReferenceSlotInfoKHR* pReferenceSlots; +} VkVideoDecodeInfoKHR; + +typedef void (VKAPI_PTR *PFN_vkCmdDecodeVideoKHR)(VkCommandBuffer commandBuffer, const VkVideoDecodeInfoKHR* pDecodeInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdDecodeVideoKHR( + VkCommandBuffer commandBuffer, + const VkVideoDecodeInfoKHR* pDecodeInfo); +#endif + + +// VK_KHR_video_encode_h264 is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_video_encode_h264 1 +#include "../vk_video/vulkan_video_codec_h264std.h" +#include "../vk_video/vulkan_video_codec_h264std_encode.h" +#define VK_KHR_VIDEO_ENCODE_H264_SPEC_VERSION 14 +#define VK_KHR_VIDEO_ENCODE_H264_EXTENSION_NAME "VK_KHR_video_encode_h264" + +typedef enum VkVideoEncodeH264CapabilityFlagBitsKHR { + VK_VIDEO_ENCODE_H264_CAPABILITY_HRD_COMPLIANCE_BIT_KHR = 0x00000001, + VK_VIDEO_ENCODE_H264_CAPABILITY_PREDICTION_WEIGHT_TABLE_GENERATED_BIT_KHR = 0x00000002, + VK_VIDEO_ENCODE_H264_CAPABILITY_ROW_UNALIGNED_SLICE_BIT_KHR = 0x00000004, + VK_VIDEO_ENCODE_H264_CAPABILITY_DIFFERENT_SLICE_TYPE_BIT_KHR = 0x00000008, + VK_VIDEO_ENCODE_H264_CAPABILITY_B_FRAME_IN_L0_LIST_BIT_KHR = 0x00000010, + VK_VIDEO_ENCODE_H264_CAPABILITY_B_FRAME_IN_L1_LIST_BIT_KHR = 0x00000020, + VK_VIDEO_ENCODE_H264_CAPABILITY_PER_PICTURE_TYPE_MIN_MAX_QP_BIT_KHR = 0x00000040, + VK_VIDEO_ENCODE_H264_CAPABILITY_PER_SLICE_CONSTANT_QP_BIT_KHR = 0x00000080, + VK_VIDEO_ENCODE_H264_CAPABILITY_GENERATE_PREFIX_NALU_BIT_KHR = 0x00000100, + VK_VIDEO_ENCODE_H264_CAPABILITY_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkVideoEncodeH264CapabilityFlagBitsKHR; +typedef VkFlags VkVideoEncodeH264CapabilityFlagsKHR; + +typedef enum VkVideoEncodeH264StdFlagBitsKHR { + VK_VIDEO_ENCODE_H264_STD_SEPARATE_COLOR_PLANE_FLAG_SET_BIT_KHR = 0x00000001, + VK_VIDEO_ENCODE_H264_STD_QPPRIME_Y_ZERO_TRANSFORM_BYPASS_FLAG_SET_BIT_KHR = 0x00000002, + VK_VIDEO_ENCODE_H264_STD_SCALING_MATRIX_PRESENT_FLAG_SET_BIT_KHR = 0x00000004, + VK_VIDEO_ENCODE_H264_STD_CHROMA_QP_INDEX_OFFSET_BIT_KHR = 0x00000008, + VK_VIDEO_ENCODE_H264_STD_SECOND_CHROMA_QP_INDEX_OFFSET_BIT_KHR = 0x00000010, + VK_VIDEO_ENCODE_H264_STD_PIC_INIT_QP_MINUS26_BIT_KHR = 0x00000020, + VK_VIDEO_ENCODE_H264_STD_WEIGHTED_PRED_FLAG_SET_BIT_KHR = 0x00000040, + VK_VIDEO_ENCODE_H264_STD_WEIGHTED_BIPRED_IDC_EXPLICIT_BIT_KHR = 0x00000080, + VK_VIDEO_ENCODE_H264_STD_WEIGHTED_BIPRED_IDC_IMPLICIT_BIT_KHR = 0x00000100, + VK_VIDEO_ENCODE_H264_STD_TRANSFORM_8X8_MODE_FLAG_SET_BIT_KHR = 0x00000200, + VK_VIDEO_ENCODE_H264_STD_DIRECT_SPATIAL_MV_PRED_FLAG_UNSET_BIT_KHR = 0x00000400, + VK_VIDEO_ENCODE_H264_STD_ENTROPY_CODING_MODE_FLAG_UNSET_BIT_KHR = 0x00000800, + VK_VIDEO_ENCODE_H264_STD_ENTROPY_CODING_MODE_FLAG_SET_BIT_KHR = 0x00001000, + VK_VIDEO_ENCODE_H264_STD_DIRECT_8X8_INFERENCE_FLAG_UNSET_BIT_KHR = 0x00002000, + VK_VIDEO_ENCODE_H264_STD_CONSTRAINED_INTRA_PRED_FLAG_SET_BIT_KHR = 0x00004000, + VK_VIDEO_ENCODE_H264_STD_DEBLOCKING_FILTER_DISABLED_BIT_KHR = 0x00008000, + VK_VIDEO_ENCODE_H264_STD_DEBLOCKING_FILTER_ENABLED_BIT_KHR = 0x00010000, + VK_VIDEO_ENCODE_H264_STD_DEBLOCKING_FILTER_PARTIAL_BIT_KHR = 0x00020000, + VK_VIDEO_ENCODE_H264_STD_SLICE_QP_DELTA_BIT_KHR = 0x00080000, + VK_VIDEO_ENCODE_H264_STD_DIFFERENT_SLICE_QP_DELTA_BIT_KHR = 0x00100000, + VK_VIDEO_ENCODE_H264_STD_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkVideoEncodeH264StdFlagBitsKHR; +typedef VkFlags VkVideoEncodeH264StdFlagsKHR; + +typedef enum VkVideoEncodeH264RateControlFlagBitsKHR { + VK_VIDEO_ENCODE_H264_RATE_CONTROL_ATTEMPT_HRD_COMPLIANCE_BIT_KHR = 0x00000001, + VK_VIDEO_ENCODE_H264_RATE_CONTROL_REGULAR_GOP_BIT_KHR = 0x00000002, + VK_VIDEO_ENCODE_H264_RATE_CONTROL_REFERENCE_PATTERN_FLAT_BIT_KHR = 0x00000004, + VK_VIDEO_ENCODE_H264_RATE_CONTROL_REFERENCE_PATTERN_DYADIC_BIT_KHR = 0x00000008, + VK_VIDEO_ENCODE_H264_RATE_CONTROL_TEMPORAL_LAYER_PATTERN_DYADIC_BIT_KHR = 0x00000010, + VK_VIDEO_ENCODE_H264_RATE_CONTROL_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkVideoEncodeH264RateControlFlagBitsKHR; +typedef VkFlags VkVideoEncodeH264RateControlFlagsKHR; +typedef struct VkVideoEncodeH264CapabilitiesKHR { + VkStructureType sType; + void* pNext; + VkVideoEncodeH264CapabilityFlagsKHR flags; + StdVideoH264LevelIdc maxLevelIdc; + uint32_t maxSliceCount; + uint32_t maxPPictureL0ReferenceCount; + uint32_t maxBPictureL0ReferenceCount; + uint32_t maxL1ReferenceCount; + uint32_t maxTemporalLayerCount; + VkBool32 expectDyadicTemporalLayerPattern; + int32_t minQp; + int32_t maxQp; + VkBool32 prefersGopRemainingFrames; + VkBool32 requiresGopRemainingFrames; + VkVideoEncodeH264StdFlagsKHR stdSyntaxFlags; +} VkVideoEncodeH264CapabilitiesKHR; + +typedef struct VkVideoEncodeH264QpKHR { + int32_t qpI; + int32_t qpP; + int32_t qpB; +} VkVideoEncodeH264QpKHR; + +typedef struct VkVideoEncodeH264QualityLevelPropertiesKHR { + VkStructureType sType; + void* pNext; + VkVideoEncodeH264RateControlFlagsKHR preferredRateControlFlags; + uint32_t preferredGopFrameCount; + uint32_t preferredIdrPeriod; + uint32_t preferredConsecutiveBFrameCount; + uint32_t preferredTemporalLayerCount; + VkVideoEncodeH264QpKHR preferredConstantQp; + uint32_t preferredMaxL0ReferenceCount; + uint32_t preferredMaxL1ReferenceCount; + VkBool32 preferredStdEntropyCodingModeFlag; +} VkVideoEncodeH264QualityLevelPropertiesKHR; + +typedef struct VkVideoEncodeH264SessionCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkBool32 useMaxLevelIdc; + StdVideoH264LevelIdc maxLevelIdc; +} VkVideoEncodeH264SessionCreateInfoKHR; + +typedef struct VkVideoEncodeH264SessionParametersAddInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t stdSPSCount; + const StdVideoH264SequenceParameterSet* pStdSPSs; + uint32_t stdPPSCount; + const StdVideoH264PictureParameterSet* pStdPPSs; +} VkVideoEncodeH264SessionParametersAddInfoKHR; + +typedef struct VkVideoEncodeH264SessionParametersCreateInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t maxStdSPSCount; + uint32_t maxStdPPSCount; + const VkVideoEncodeH264SessionParametersAddInfoKHR* pParametersAddInfo; +} VkVideoEncodeH264SessionParametersCreateInfoKHR; + +typedef struct VkVideoEncodeH264SessionParametersGetInfoKHR { + VkStructureType sType; + const void* pNext; + VkBool32 writeStdSPS; + VkBool32 writeStdPPS; + uint32_t stdSPSId; + uint32_t stdPPSId; +} VkVideoEncodeH264SessionParametersGetInfoKHR; + +typedef struct VkVideoEncodeH264SessionParametersFeedbackInfoKHR { + VkStructureType sType; + void* pNext; + VkBool32 hasStdSPSOverrides; + VkBool32 hasStdPPSOverrides; +} VkVideoEncodeH264SessionParametersFeedbackInfoKHR; + +typedef struct VkVideoEncodeH264NaluSliceInfoKHR { + VkStructureType sType; + const void* pNext; + int32_t constantQp; + const StdVideoEncodeH264SliceHeader* pStdSliceHeader; +} VkVideoEncodeH264NaluSliceInfoKHR; + +typedef struct VkVideoEncodeH264PictureInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t naluSliceEntryCount; + const VkVideoEncodeH264NaluSliceInfoKHR* pNaluSliceEntries; + const StdVideoEncodeH264PictureInfo* pStdPictureInfo; + VkBool32 generatePrefixNalu; +} VkVideoEncodeH264PictureInfoKHR; + +typedef struct VkVideoEncodeH264DpbSlotInfoKHR { + VkStructureType sType; + const void* pNext; + const StdVideoEncodeH264ReferenceInfo* pStdReferenceInfo; +} VkVideoEncodeH264DpbSlotInfoKHR; + +typedef struct VkVideoEncodeH264ProfileInfoKHR { + VkStructureType sType; + const void* pNext; + StdVideoH264ProfileIdc stdProfileIdc; +} VkVideoEncodeH264ProfileInfoKHR; + +typedef struct VkVideoEncodeH264RateControlInfoKHR { + VkStructureType sType; + const void* pNext; + VkVideoEncodeH264RateControlFlagsKHR flags; + uint32_t gopFrameCount; + uint32_t idrPeriod; + uint32_t consecutiveBFrameCount; + uint32_t temporalLayerCount; +} VkVideoEncodeH264RateControlInfoKHR; + +typedef struct VkVideoEncodeH264FrameSizeKHR { + uint32_t frameISize; + uint32_t framePSize; + uint32_t frameBSize; +} VkVideoEncodeH264FrameSizeKHR; + +typedef struct VkVideoEncodeH264RateControlLayerInfoKHR { + VkStructureType sType; + const void* pNext; + VkBool32 useMinQp; + VkVideoEncodeH264QpKHR minQp; + VkBool32 useMaxQp; + VkVideoEncodeH264QpKHR maxQp; + VkBool32 useMaxFrameSize; + VkVideoEncodeH264FrameSizeKHR maxFrameSize; +} VkVideoEncodeH264RateControlLayerInfoKHR; + +typedef struct VkVideoEncodeH264GopRemainingFrameInfoKHR { + VkStructureType sType; + const void* pNext; + VkBool32 useGopRemainingFrames; + uint32_t gopRemainingI; + uint32_t gopRemainingP; + uint32_t gopRemainingB; +} VkVideoEncodeH264GopRemainingFrameInfoKHR; + + + +// VK_KHR_video_encode_h265 is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_video_encode_h265 1 +#include "../vk_video/vulkan_video_codec_h265std.h" +#include "../vk_video/vulkan_video_codec_h265std_encode.h" +#define VK_KHR_VIDEO_ENCODE_H265_SPEC_VERSION 14 +#define VK_KHR_VIDEO_ENCODE_H265_EXTENSION_NAME "VK_KHR_video_encode_h265" + +typedef enum VkVideoEncodeH265CapabilityFlagBitsKHR { + VK_VIDEO_ENCODE_H265_CAPABILITY_HRD_COMPLIANCE_BIT_KHR = 0x00000001, + VK_VIDEO_ENCODE_H265_CAPABILITY_PREDICTION_WEIGHT_TABLE_GENERATED_BIT_KHR = 0x00000002, + VK_VIDEO_ENCODE_H265_CAPABILITY_ROW_UNALIGNED_SLICE_SEGMENT_BIT_KHR = 0x00000004, + VK_VIDEO_ENCODE_H265_CAPABILITY_DIFFERENT_SLICE_SEGMENT_TYPE_BIT_KHR = 0x00000008, + VK_VIDEO_ENCODE_H265_CAPABILITY_B_FRAME_IN_L0_LIST_BIT_KHR = 0x00000010, + VK_VIDEO_ENCODE_H265_CAPABILITY_B_FRAME_IN_L1_LIST_BIT_KHR = 0x00000020, + VK_VIDEO_ENCODE_H265_CAPABILITY_PER_PICTURE_TYPE_MIN_MAX_QP_BIT_KHR = 0x00000040, + VK_VIDEO_ENCODE_H265_CAPABILITY_PER_SLICE_SEGMENT_CONSTANT_QP_BIT_KHR = 0x00000080, + VK_VIDEO_ENCODE_H265_CAPABILITY_MULTIPLE_TILES_PER_SLICE_SEGMENT_BIT_KHR = 0x00000100, + VK_VIDEO_ENCODE_H265_CAPABILITY_MULTIPLE_SLICE_SEGMENTS_PER_TILE_BIT_KHR = 0x00000200, + VK_VIDEO_ENCODE_H265_CAPABILITY_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkVideoEncodeH265CapabilityFlagBitsKHR; +typedef VkFlags VkVideoEncodeH265CapabilityFlagsKHR; + +typedef enum VkVideoEncodeH265StdFlagBitsKHR { + VK_VIDEO_ENCODE_H265_STD_SEPARATE_COLOR_PLANE_FLAG_SET_BIT_KHR = 0x00000001, + VK_VIDEO_ENCODE_H265_STD_SAMPLE_ADAPTIVE_OFFSET_ENABLED_FLAG_SET_BIT_KHR = 0x00000002, + VK_VIDEO_ENCODE_H265_STD_SCALING_LIST_DATA_PRESENT_FLAG_SET_BIT_KHR = 0x00000004, + VK_VIDEO_ENCODE_H265_STD_PCM_ENABLED_FLAG_SET_BIT_KHR = 0x00000008, + VK_VIDEO_ENCODE_H265_STD_SPS_TEMPORAL_MVP_ENABLED_FLAG_SET_BIT_KHR = 0x00000010, + VK_VIDEO_ENCODE_H265_STD_INIT_QP_MINUS26_BIT_KHR = 0x00000020, + VK_VIDEO_ENCODE_H265_STD_WEIGHTED_PRED_FLAG_SET_BIT_KHR = 0x00000040, + VK_VIDEO_ENCODE_H265_STD_WEIGHTED_BIPRED_FLAG_SET_BIT_KHR = 0x00000080, + VK_VIDEO_ENCODE_H265_STD_LOG2_PARALLEL_MERGE_LEVEL_MINUS2_BIT_KHR = 0x00000100, + VK_VIDEO_ENCODE_H265_STD_SIGN_DATA_HIDING_ENABLED_FLAG_SET_BIT_KHR = 0x00000200, + VK_VIDEO_ENCODE_H265_STD_TRANSFORM_SKIP_ENABLED_FLAG_SET_BIT_KHR = 0x00000400, + VK_VIDEO_ENCODE_H265_STD_TRANSFORM_SKIP_ENABLED_FLAG_UNSET_BIT_KHR = 0x00000800, + VK_VIDEO_ENCODE_H265_STD_PPS_SLICE_CHROMA_QP_OFFSETS_PRESENT_FLAG_SET_BIT_KHR = 0x00001000, + VK_VIDEO_ENCODE_H265_STD_TRANSQUANT_BYPASS_ENABLED_FLAG_SET_BIT_KHR = 0x00002000, + VK_VIDEO_ENCODE_H265_STD_CONSTRAINED_INTRA_PRED_FLAG_SET_BIT_KHR = 0x00004000, + VK_VIDEO_ENCODE_H265_STD_ENTROPY_CODING_SYNC_ENABLED_FLAG_SET_BIT_KHR = 0x00008000, + VK_VIDEO_ENCODE_H265_STD_DEBLOCKING_FILTER_OVERRIDE_ENABLED_FLAG_SET_BIT_KHR = 0x00010000, + VK_VIDEO_ENCODE_H265_STD_DEPENDENT_SLICE_SEGMENTS_ENABLED_FLAG_SET_BIT_KHR = 0x00020000, + VK_VIDEO_ENCODE_H265_STD_DEPENDENT_SLICE_SEGMENT_FLAG_SET_BIT_KHR = 0x00040000, + VK_VIDEO_ENCODE_H265_STD_SLICE_QP_DELTA_BIT_KHR = 0x00080000, + VK_VIDEO_ENCODE_H265_STD_DIFFERENT_SLICE_QP_DELTA_BIT_KHR = 0x00100000, + VK_VIDEO_ENCODE_H265_STD_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkVideoEncodeH265StdFlagBitsKHR; +typedef VkFlags VkVideoEncodeH265StdFlagsKHR; + +typedef enum VkVideoEncodeH265CtbSizeFlagBitsKHR { + VK_VIDEO_ENCODE_H265_CTB_SIZE_16_BIT_KHR = 0x00000001, + VK_VIDEO_ENCODE_H265_CTB_SIZE_32_BIT_KHR = 0x00000002, + VK_VIDEO_ENCODE_H265_CTB_SIZE_64_BIT_KHR = 0x00000004, + VK_VIDEO_ENCODE_H265_CTB_SIZE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkVideoEncodeH265CtbSizeFlagBitsKHR; +typedef VkFlags VkVideoEncodeH265CtbSizeFlagsKHR; + +typedef enum VkVideoEncodeH265TransformBlockSizeFlagBitsKHR { + VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_4_BIT_KHR = 0x00000001, + VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_8_BIT_KHR = 0x00000002, + VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_16_BIT_KHR = 0x00000004, + VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_32_BIT_KHR = 0x00000008, + VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkVideoEncodeH265TransformBlockSizeFlagBitsKHR; +typedef VkFlags VkVideoEncodeH265TransformBlockSizeFlagsKHR; + +typedef enum VkVideoEncodeH265RateControlFlagBitsKHR { + VK_VIDEO_ENCODE_H265_RATE_CONTROL_ATTEMPT_HRD_COMPLIANCE_BIT_KHR = 0x00000001, + VK_VIDEO_ENCODE_H265_RATE_CONTROL_REGULAR_GOP_BIT_KHR = 0x00000002, + VK_VIDEO_ENCODE_H265_RATE_CONTROL_REFERENCE_PATTERN_FLAT_BIT_KHR = 0x00000004, + VK_VIDEO_ENCODE_H265_RATE_CONTROL_REFERENCE_PATTERN_DYADIC_BIT_KHR = 0x00000008, + VK_VIDEO_ENCODE_H265_RATE_CONTROL_TEMPORAL_SUB_LAYER_PATTERN_DYADIC_BIT_KHR = 0x00000010, + VK_VIDEO_ENCODE_H265_RATE_CONTROL_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkVideoEncodeH265RateControlFlagBitsKHR; +typedef VkFlags VkVideoEncodeH265RateControlFlagsKHR; +typedef struct VkVideoEncodeH265CapabilitiesKHR { + VkStructureType sType; + void* pNext; + VkVideoEncodeH265CapabilityFlagsKHR flags; + StdVideoH265LevelIdc maxLevelIdc; + uint32_t maxSliceSegmentCount; + VkExtent2D maxTiles; + VkVideoEncodeH265CtbSizeFlagsKHR ctbSizes; + VkVideoEncodeH265TransformBlockSizeFlagsKHR transformBlockSizes; + uint32_t maxPPictureL0ReferenceCount; + uint32_t maxBPictureL0ReferenceCount; + uint32_t maxL1ReferenceCount; + uint32_t maxSubLayerCount; + VkBool32 expectDyadicTemporalSubLayerPattern; + int32_t minQp; + int32_t maxQp; + VkBool32 prefersGopRemainingFrames; + VkBool32 requiresGopRemainingFrames; + VkVideoEncodeH265StdFlagsKHR stdSyntaxFlags; +} VkVideoEncodeH265CapabilitiesKHR; + +typedef struct VkVideoEncodeH265SessionCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkBool32 useMaxLevelIdc; + StdVideoH265LevelIdc maxLevelIdc; +} VkVideoEncodeH265SessionCreateInfoKHR; + +typedef struct VkVideoEncodeH265QpKHR { + int32_t qpI; + int32_t qpP; + int32_t qpB; +} VkVideoEncodeH265QpKHR; + +typedef struct VkVideoEncodeH265QualityLevelPropertiesKHR { + VkStructureType sType; + void* pNext; + VkVideoEncodeH265RateControlFlagsKHR preferredRateControlFlags; + uint32_t preferredGopFrameCount; + uint32_t preferredIdrPeriod; + uint32_t preferredConsecutiveBFrameCount; + uint32_t preferredSubLayerCount; + VkVideoEncodeH265QpKHR preferredConstantQp; + uint32_t preferredMaxL0ReferenceCount; + uint32_t preferredMaxL1ReferenceCount; +} VkVideoEncodeH265QualityLevelPropertiesKHR; + +typedef struct VkVideoEncodeH265SessionParametersAddInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t stdVPSCount; + const StdVideoH265VideoParameterSet* pStdVPSs; + uint32_t stdSPSCount; + const StdVideoH265SequenceParameterSet* pStdSPSs; + uint32_t stdPPSCount; + const StdVideoH265PictureParameterSet* pStdPPSs; +} VkVideoEncodeH265SessionParametersAddInfoKHR; + +typedef struct VkVideoEncodeH265SessionParametersCreateInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t maxStdVPSCount; + uint32_t maxStdSPSCount; + uint32_t maxStdPPSCount; + const VkVideoEncodeH265SessionParametersAddInfoKHR* pParametersAddInfo; +} VkVideoEncodeH265SessionParametersCreateInfoKHR; + +typedef struct VkVideoEncodeH265SessionParametersGetInfoKHR { + VkStructureType sType; + const void* pNext; + VkBool32 writeStdVPS; + VkBool32 writeStdSPS; + VkBool32 writeStdPPS; + uint32_t stdVPSId; + uint32_t stdSPSId; + uint32_t stdPPSId; +} VkVideoEncodeH265SessionParametersGetInfoKHR; + +typedef struct VkVideoEncodeH265SessionParametersFeedbackInfoKHR { + VkStructureType sType; + void* pNext; + VkBool32 hasStdVPSOverrides; + VkBool32 hasStdSPSOverrides; + VkBool32 hasStdPPSOverrides; +} VkVideoEncodeH265SessionParametersFeedbackInfoKHR; + +typedef struct VkVideoEncodeH265NaluSliceSegmentInfoKHR { + VkStructureType sType; + const void* pNext; + int32_t constantQp; + const StdVideoEncodeH265SliceSegmentHeader* pStdSliceSegmentHeader; +} VkVideoEncodeH265NaluSliceSegmentInfoKHR; + +typedef struct VkVideoEncodeH265PictureInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t naluSliceSegmentEntryCount; + const VkVideoEncodeH265NaluSliceSegmentInfoKHR* pNaluSliceSegmentEntries; + const StdVideoEncodeH265PictureInfo* pStdPictureInfo; +} VkVideoEncodeH265PictureInfoKHR; + +typedef struct VkVideoEncodeH265DpbSlotInfoKHR { + VkStructureType sType; + const void* pNext; + const StdVideoEncodeH265ReferenceInfo* pStdReferenceInfo; +} VkVideoEncodeH265DpbSlotInfoKHR; + +typedef struct VkVideoEncodeH265ProfileInfoKHR { + VkStructureType sType; + const void* pNext; + StdVideoH265ProfileIdc stdProfileIdc; +} VkVideoEncodeH265ProfileInfoKHR; + +typedef struct VkVideoEncodeH265RateControlInfoKHR { + VkStructureType sType; + const void* pNext; + VkVideoEncodeH265RateControlFlagsKHR flags; + uint32_t gopFrameCount; + uint32_t idrPeriod; + uint32_t consecutiveBFrameCount; + uint32_t subLayerCount; +} VkVideoEncodeH265RateControlInfoKHR; + +typedef struct VkVideoEncodeH265FrameSizeKHR { + uint32_t frameISize; + uint32_t framePSize; + uint32_t frameBSize; +} VkVideoEncodeH265FrameSizeKHR; + +typedef struct VkVideoEncodeH265RateControlLayerInfoKHR { + VkStructureType sType; + const void* pNext; + VkBool32 useMinQp; + VkVideoEncodeH265QpKHR minQp; + VkBool32 useMaxQp; + VkVideoEncodeH265QpKHR maxQp; + VkBool32 useMaxFrameSize; + VkVideoEncodeH265FrameSizeKHR maxFrameSize; +} VkVideoEncodeH265RateControlLayerInfoKHR; + +typedef struct VkVideoEncodeH265GopRemainingFrameInfoKHR { + VkStructureType sType; + const void* pNext; + VkBool32 useGopRemainingFrames; + uint32_t gopRemainingI; + uint32_t gopRemainingP; + uint32_t gopRemainingB; +} VkVideoEncodeH265GopRemainingFrameInfoKHR; + + + +// VK_KHR_video_decode_h264 is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_video_decode_h264 1 +#include "../vk_video/vulkan_video_codec_h264std_decode.h" +#define VK_KHR_VIDEO_DECODE_H264_SPEC_VERSION 9 +#define VK_KHR_VIDEO_DECODE_H264_EXTENSION_NAME "VK_KHR_video_decode_h264" + +typedef enum VkVideoDecodeH264PictureLayoutFlagBitsKHR { + VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_PROGRESSIVE_KHR = 0, + VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_INTERLEAVED_LINES_BIT_KHR = 0x00000001, + VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_SEPARATE_PLANES_BIT_KHR = 0x00000002, + VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkVideoDecodeH264PictureLayoutFlagBitsKHR; +typedef VkFlags VkVideoDecodeH264PictureLayoutFlagsKHR; +typedef struct VkVideoDecodeH264ProfileInfoKHR { + VkStructureType sType; + const void* pNext; + StdVideoH264ProfileIdc stdProfileIdc; + VkVideoDecodeH264PictureLayoutFlagBitsKHR pictureLayout; +} VkVideoDecodeH264ProfileInfoKHR; + +typedef struct VkVideoDecodeH264CapabilitiesKHR { + VkStructureType sType; + void* pNext; + StdVideoH264LevelIdc maxLevelIdc; + VkOffset2D fieldOffsetGranularity; +} VkVideoDecodeH264CapabilitiesKHR; + +typedef struct VkVideoDecodeH264SessionParametersAddInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t stdSPSCount; + const StdVideoH264SequenceParameterSet* pStdSPSs; + uint32_t stdPPSCount; + const StdVideoH264PictureParameterSet* pStdPPSs; +} VkVideoDecodeH264SessionParametersAddInfoKHR; + +typedef struct VkVideoDecodeH264SessionParametersCreateInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t maxStdSPSCount; + uint32_t maxStdPPSCount; + const VkVideoDecodeH264SessionParametersAddInfoKHR* pParametersAddInfo; +} VkVideoDecodeH264SessionParametersCreateInfoKHR; + +typedef struct VkVideoDecodeH264PictureInfoKHR { + VkStructureType sType; + const void* pNext; + const StdVideoDecodeH264PictureInfo* pStdPictureInfo; + uint32_t sliceCount; + const uint32_t* pSliceOffsets; +} VkVideoDecodeH264PictureInfoKHR; + +typedef struct VkVideoDecodeH264DpbSlotInfoKHR { + VkStructureType sType; + const void* pNext; + const StdVideoDecodeH264ReferenceInfo* pStdReferenceInfo; +} VkVideoDecodeH264DpbSlotInfoKHR; + + + +// VK_KHR_dynamic_rendering is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_dynamic_rendering 1 +#define VK_KHR_DYNAMIC_RENDERING_SPEC_VERSION 1 +#define VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME "VK_KHR_dynamic_rendering" +typedef VkRenderingFlags VkRenderingFlagsKHR; + +typedef VkRenderingFlagBits VkRenderingFlagBitsKHR; + +typedef VkRenderingInfo VkRenderingInfoKHR; + +typedef VkRenderingAttachmentInfo VkRenderingAttachmentInfoKHR; + +typedef VkPipelineRenderingCreateInfo VkPipelineRenderingCreateInfoKHR; + +typedef VkPhysicalDeviceDynamicRenderingFeatures VkPhysicalDeviceDynamicRenderingFeaturesKHR; + +typedef VkCommandBufferInheritanceRenderingInfo VkCommandBufferInheritanceRenderingInfoKHR; + +typedef struct VkRenderingFragmentShadingRateAttachmentInfoKHR { + VkStructureType sType; + const void* pNext; + VkImageView imageView; + VkImageLayout imageLayout; + VkExtent2D shadingRateAttachmentTexelSize; +} VkRenderingFragmentShadingRateAttachmentInfoKHR; + +typedef struct VkRenderingFragmentDensityMapAttachmentInfoEXT { + VkStructureType sType; + const void* pNext; + VkImageView imageView; + VkImageLayout imageLayout; +} VkRenderingFragmentDensityMapAttachmentInfoEXT; + +typedef struct VkAttachmentSampleCountInfoAMD { + VkStructureType sType; + const void* pNext; + uint32_t colorAttachmentCount; + const VkSampleCountFlagBits* pColorAttachmentSamples; + VkSampleCountFlagBits depthStencilAttachmentSamples; +} VkAttachmentSampleCountInfoAMD; + +typedef VkAttachmentSampleCountInfoAMD VkAttachmentSampleCountInfoNV; + +typedef struct VkMultiviewPerViewAttributesInfoNVX { + VkStructureType sType; + const void* pNext; + VkBool32 perViewAttributes; + VkBool32 perViewAttributesPositionXOnly; +} VkMultiviewPerViewAttributesInfoNVX; + +typedef void (VKAPI_PTR *PFN_vkCmdBeginRenderingKHR)(VkCommandBuffer commandBuffer, const VkRenderingInfo* pRenderingInfo); +typedef void (VKAPI_PTR *PFN_vkCmdEndRenderingKHR)(VkCommandBuffer commandBuffer); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderingKHR( + VkCommandBuffer commandBuffer, + const VkRenderingInfo* pRenderingInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderingKHR( + VkCommandBuffer commandBuffer); +#endif + + +// VK_KHR_multiview is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_multiview 1 +#define VK_KHR_MULTIVIEW_SPEC_VERSION 1 +#define VK_KHR_MULTIVIEW_EXTENSION_NAME "VK_KHR_multiview" +typedef VkRenderPassMultiviewCreateInfo VkRenderPassMultiviewCreateInfoKHR; + +typedef VkPhysicalDeviceMultiviewFeatures VkPhysicalDeviceMultiviewFeaturesKHR; + +typedef VkPhysicalDeviceMultiviewProperties VkPhysicalDeviceMultiviewPropertiesKHR; + + + +// VK_KHR_get_physical_device_properties2 is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_get_physical_device_properties2 1 +#define VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_SPEC_VERSION 2 +#define VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME "VK_KHR_get_physical_device_properties2" +typedef VkPhysicalDeviceFeatures2 VkPhysicalDeviceFeatures2KHR; + +typedef VkPhysicalDeviceProperties2 VkPhysicalDeviceProperties2KHR; + +typedef VkFormatProperties2 VkFormatProperties2KHR; + +typedef VkImageFormatProperties2 VkImageFormatProperties2KHR; + +typedef VkPhysicalDeviceImageFormatInfo2 VkPhysicalDeviceImageFormatInfo2KHR; + +typedef VkQueueFamilyProperties2 VkQueueFamilyProperties2KHR; + +typedef VkPhysicalDeviceMemoryProperties2 VkPhysicalDeviceMemoryProperties2KHR; + +typedef VkSparseImageFormatProperties2 VkSparseImageFormatProperties2KHR; + +typedef VkPhysicalDeviceSparseImageFormatInfo2 VkPhysicalDeviceSparseImageFormatInfo2KHR; + +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFeatures2KHR)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures2* pFeatures); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceProperties2KHR)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2* pProperties); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFormatProperties2KHR)(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties2* pFormatProperties); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceImageFormatProperties2KHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo, VkImageFormatProperties2* pImageFormatProperties); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR)(VkPhysicalDevice physicalDevice, uint32_t* pQueueFamilyPropertyCount, VkQueueFamilyProperties2* pQueueFamilyProperties); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceMemoryProperties2KHR)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties2* pMemoryProperties); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceSparseImageFormatProperties2KHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2* pFormatInfo, uint32_t* pPropertyCount, VkSparseImageFormatProperties2* pProperties); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFeatures2KHR( + VkPhysicalDevice physicalDevice, + VkPhysicalDeviceFeatures2* pFeatures); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties2KHR( + VkPhysicalDevice physicalDevice, + VkPhysicalDeviceProperties2* pProperties); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFormatProperties2KHR( + VkPhysicalDevice physicalDevice, + VkFormat format, + VkFormatProperties2* pFormatProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceImageFormatProperties2KHR( + VkPhysicalDevice physicalDevice, + const VkPhysicalDeviceImageFormatInfo2* pImageFormatInfo, + VkImageFormatProperties2* pImageFormatProperties); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyProperties2KHR( + VkPhysicalDevice physicalDevice, + uint32_t* pQueueFamilyPropertyCount, + VkQueueFamilyProperties2* pQueueFamilyProperties); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties2KHR( + VkPhysicalDevice physicalDevice, + VkPhysicalDeviceMemoryProperties2* pMemoryProperties); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceSparseImageFormatProperties2KHR( + VkPhysicalDevice physicalDevice, + const VkPhysicalDeviceSparseImageFormatInfo2* pFormatInfo, + uint32_t* pPropertyCount, + VkSparseImageFormatProperties2* pProperties); +#endif + + +// VK_KHR_device_group is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_device_group 1 +#define VK_KHR_DEVICE_GROUP_SPEC_VERSION 4 +#define VK_KHR_DEVICE_GROUP_EXTENSION_NAME "VK_KHR_device_group" +typedef VkPeerMemoryFeatureFlags VkPeerMemoryFeatureFlagsKHR; + +typedef VkPeerMemoryFeatureFlagBits VkPeerMemoryFeatureFlagBitsKHR; + +typedef VkMemoryAllocateFlags VkMemoryAllocateFlagsKHR; + +typedef VkMemoryAllocateFlagBits VkMemoryAllocateFlagBitsKHR; + +typedef VkMemoryAllocateFlagsInfo VkMemoryAllocateFlagsInfoKHR; + +typedef VkDeviceGroupRenderPassBeginInfo VkDeviceGroupRenderPassBeginInfoKHR; + +typedef VkDeviceGroupCommandBufferBeginInfo VkDeviceGroupCommandBufferBeginInfoKHR; + +typedef VkDeviceGroupSubmitInfo VkDeviceGroupSubmitInfoKHR; + +typedef VkDeviceGroupBindSparseInfo VkDeviceGroupBindSparseInfoKHR; + +typedef VkBindBufferMemoryDeviceGroupInfo VkBindBufferMemoryDeviceGroupInfoKHR; + +typedef VkBindImageMemoryDeviceGroupInfo VkBindImageMemoryDeviceGroupInfoKHR; + +typedef void (VKAPI_PTR *PFN_vkGetDeviceGroupPeerMemoryFeaturesKHR)(VkDevice device, uint32_t heapIndex, uint32_t localDeviceIndex, uint32_t remoteDeviceIndex, VkPeerMemoryFeatureFlags* pPeerMemoryFeatures); +typedef void (VKAPI_PTR *PFN_vkCmdSetDeviceMaskKHR)(VkCommandBuffer commandBuffer, uint32_t deviceMask); +typedef void (VKAPI_PTR *PFN_vkCmdDispatchBaseKHR)(VkCommandBuffer commandBuffer, uint32_t baseGroupX, uint32_t baseGroupY, uint32_t baseGroupZ, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkGetDeviceGroupPeerMemoryFeaturesKHR( + VkDevice device, + uint32_t heapIndex, + uint32_t localDeviceIndex, + uint32_t remoteDeviceIndex, + VkPeerMemoryFeatureFlags* pPeerMemoryFeatures); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDeviceMaskKHR( + VkCommandBuffer commandBuffer, + uint32_t deviceMask); + +VKAPI_ATTR void VKAPI_CALL vkCmdDispatchBaseKHR( + VkCommandBuffer commandBuffer, + uint32_t baseGroupX, + uint32_t baseGroupY, + uint32_t baseGroupZ, + uint32_t groupCountX, + uint32_t groupCountY, + uint32_t groupCountZ); +#endif + + +// VK_KHR_shader_draw_parameters is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_shader_draw_parameters 1 +#define VK_KHR_SHADER_DRAW_PARAMETERS_SPEC_VERSION 1 +#define VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME "VK_KHR_shader_draw_parameters" + + +// VK_KHR_maintenance1 is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_maintenance1 1 +#define VK_KHR_MAINTENANCE_1_SPEC_VERSION 2 +#define VK_KHR_MAINTENANCE_1_EXTENSION_NAME "VK_KHR_maintenance1" +#define VK_KHR_MAINTENANCE1_SPEC_VERSION VK_KHR_MAINTENANCE_1_SPEC_VERSION +#define VK_KHR_MAINTENANCE1_EXTENSION_NAME VK_KHR_MAINTENANCE_1_EXTENSION_NAME +typedef VkCommandPoolTrimFlags VkCommandPoolTrimFlagsKHR; + +typedef void (VKAPI_PTR *PFN_vkTrimCommandPoolKHR)(VkDevice device, VkCommandPool commandPool, VkCommandPoolTrimFlags flags); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkTrimCommandPoolKHR( + VkDevice device, + VkCommandPool commandPool, + VkCommandPoolTrimFlags flags); +#endif + + +// VK_KHR_device_group_creation is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_device_group_creation 1 +#define VK_KHR_DEVICE_GROUP_CREATION_SPEC_VERSION 1 +#define VK_KHR_DEVICE_GROUP_CREATION_EXTENSION_NAME "VK_KHR_device_group_creation" +#define VK_MAX_DEVICE_GROUP_SIZE_KHR VK_MAX_DEVICE_GROUP_SIZE +typedef VkPhysicalDeviceGroupProperties VkPhysicalDeviceGroupPropertiesKHR; + +typedef VkDeviceGroupDeviceCreateInfo VkDeviceGroupDeviceCreateInfoKHR; + +typedef VkResult (VKAPI_PTR *PFN_vkEnumeratePhysicalDeviceGroupsKHR)(VkInstance instance, uint32_t* pPhysicalDeviceGroupCount, VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDeviceGroupsKHR( + VkInstance instance, + uint32_t* pPhysicalDeviceGroupCount, + VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties); +#endif + + +// VK_KHR_external_memory_capabilities is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_external_memory_capabilities 1 +#define VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_SPEC_VERSION 1 +#define VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME "VK_KHR_external_memory_capabilities" +#define VK_LUID_SIZE_KHR VK_LUID_SIZE +typedef VkExternalMemoryHandleTypeFlags VkExternalMemoryHandleTypeFlagsKHR; + +typedef VkExternalMemoryHandleTypeFlagBits VkExternalMemoryHandleTypeFlagBitsKHR; + +typedef VkExternalMemoryFeatureFlags VkExternalMemoryFeatureFlagsKHR; + +typedef VkExternalMemoryFeatureFlagBits VkExternalMemoryFeatureFlagBitsKHR; + +typedef VkExternalMemoryProperties VkExternalMemoryPropertiesKHR; + +typedef VkPhysicalDeviceExternalImageFormatInfo VkPhysicalDeviceExternalImageFormatInfoKHR; + +typedef VkExternalImageFormatProperties VkExternalImageFormatPropertiesKHR; + +typedef VkPhysicalDeviceExternalBufferInfo VkPhysicalDeviceExternalBufferInfoKHR; + +typedef VkExternalBufferProperties VkExternalBufferPropertiesKHR; + +typedef VkPhysicalDeviceIDProperties VkPhysicalDeviceIDPropertiesKHR; + +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalBufferPropertiesKHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo, VkExternalBufferProperties* pExternalBufferProperties); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalBufferPropertiesKHR( + VkPhysicalDevice physicalDevice, + const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo, + VkExternalBufferProperties* pExternalBufferProperties); +#endif + + +// VK_KHR_external_memory is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_external_memory 1 +#define VK_KHR_EXTERNAL_MEMORY_SPEC_VERSION 1 +#define VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME "VK_KHR_external_memory" +#define VK_QUEUE_FAMILY_EXTERNAL_KHR VK_QUEUE_FAMILY_EXTERNAL +typedef VkExternalMemoryImageCreateInfo VkExternalMemoryImageCreateInfoKHR; + +typedef VkExternalMemoryBufferCreateInfo VkExternalMemoryBufferCreateInfoKHR; + +typedef VkExportMemoryAllocateInfo VkExportMemoryAllocateInfoKHR; + + + +// VK_KHR_external_memory_fd is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_external_memory_fd 1 +#define VK_KHR_EXTERNAL_MEMORY_FD_SPEC_VERSION 1 +#define VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME "VK_KHR_external_memory_fd" +typedef struct VkImportMemoryFdInfoKHR { + VkStructureType sType; + const void* pNext; + VkExternalMemoryHandleTypeFlagBits handleType; + int fd; +} VkImportMemoryFdInfoKHR; + +typedef struct VkMemoryFdPropertiesKHR { + VkStructureType sType; + void* pNext; + uint32_t memoryTypeBits; +} VkMemoryFdPropertiesKHR; + +typedef struct VkMemoryGetFdInfoKHR { + VkStructureType sType; + const void* pNext; + VkDeviceMemory memory; + VkExternalMemoryHandleTypeFlagBits handleType; +} VkMemoryGetFdInfoKHR; + +typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryFdKHR)(VkDevice device, const VkMemoryGetFdInfoKHR* pGetFdInfo, int* pFd); +typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryFdPropertiesKHR)(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, int fd, VkMemoryFdPropertiesKHR* pMemoryFdProperties); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryFdKHR( + VkDevice device, + const VkMemoryGetFdInfoKHR* pGetFdInfo, + int* pFd); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryFdPropertiesKHR( + VkDevice device, + VkExternalMemoryHandleTypeFlagBits handleType, + int fd, + VkMemoryFdPropertiesKHR* pMemoryFdProperties); +#endif + + +// VK_KHR_external_semaphore_capabilities is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_external_semaphore_capabilities 1 +#define VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_SPEC_VERSION 1 +#define VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME "VK_KHR_external_semaphore_capabilities" +typedef VkExternalSemaphoreHandleTypeFlags VkExternalSemaphoreHandleTypeFlagsKHR; + +typedef VkExternalSemaphoreHandleTypeFlagBits VkExternalSemaphoreHandleTypeFlagBitsKHR; + +typedef VkExternalSemaphoreFeatureFlags VkExternalSemaphoreFeatureFlagsKHR; + +typedef VkExternalSemaphoreFeatureFlagBits VkExternalSemaphoreFeatureFlagBitsKHR; + +typedef VkPhysicalDeviceExternalSemaphoreInfo VkPhysicalDeviceExternalSemaphoreInfoKHR; + +typedef VkExternalSemaphoreProperties VkExternalSemaphorePropertiesKHR; + +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalSemaphorePropertiesKHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo, VkExternalSemaphoreProperties* pExternalSemaphoreProperties); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalSemaphorePropertiesKHR( + VkPhysicalDevice physicalDevice, + const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo, + VkExternalSemaphoreProperties* pExternalSemaphoreProperties); +#endif + + +// VK_KHR_external_semaphore is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_external_semaphore 1 +#define VK_KHR_EXTERNAL_SEMAPHORE_SPEC_VERSION 1 +#define VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME "VK_KHR_external_semaphore" +typedef VkSemaphoreImportFlags VkSemaphoreImportFlagsKHR; + +typedef VkSemaphoreImportFlagBits VkSemaphoreImportFlagBitsKHR; + +typedef VkExportSemaphoreCreateInfo VkExportSemaphoreCreateInfoKHR; + + + +// VK_KHR_external_semaphore_fd is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_external_semaphore_fd 1 +#define VK_KHR_EXTERNAL_SEMAPHORE_FD_SPEC_VERSION 1 +#define VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME "VK_KHR_external_semaphore_fd" +typedef struct VkImportSemaphoreFdInfoKHR { + VkStructureType sType; + const void* pNext; + VkSemaphore semaphore; + VkSemaphoreImportFlags flags; + VkExternalSemaphoreHandleTypeFlagBits handleType; + int fd; +} VkImportSemaphoreFdInfoKHR; + +typedef struct VkSemaphoreGetFdInfoKHR { + VkStructureType sType; + const void* pNext; + VkSemaphore semaphore; + VkExternalSemaphoreHandleTypeFlagBits handleType; +} VkSemaphoreGetFdInfoKHR; + +typedef VkResult (VKAPI_PTR *PFN_vkImportSemaphoreFdKHR)(VkDevice device, const VkImportSemaphoreFdInfoKHR* pImportSemaphoreFdInfo); +typedef VkResult (VKAPI_PTR *PFN_vkGetSemaphoreFdKHR)(VkDevice device, const VkSemaphoreGetFdInfoKHR* pGetFdInfo, int* pFd); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkImportSemaphoreFdKHR( + VkDevice device, + const VkImportSemaphoreFdInfoKHR* pImportSemaphoreFdInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreFdKHR( + VkDevice device, + const VkSemaphoreGetFdInfoKHR* pGetFdInfo, + int* pFd); +#endif + + +// VK_KHR_push_descriptor is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_push_descriptor 1 +#define VK_KHR_PUSH_DESCRIPTOR_SPEC_VERSION 2 +#define VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME "VK_KHR_push_descriptor" +typedef struct VkPhysicalDevicePushDescriptorPropertiesKHR { + VkStructureType sType; + void* pNext; + uint32_t maxPushDescriptors; +} VkPhysicalDevicePushDescriptorPropertiesKHR; + +typedef void (VKAPI_PTR *PFN_vkCmdPushDescriptorSetKHR)(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t set, uint32_t descriptorWriteCount, const VkWriteDescriptorSet* pDescriptorWrites); +typedef void (VKAPI_PTR *PFN_vkCmdPushDescriptorSetWithTemplateKHR)(VkCommandBuffer commandBuffer, VkDescriptorUpdateTemplate descriptorUpdateTemplate, VkPipelineLayout layout, uint32_t set, const void* pData); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdPushDescriptorSetKHR( + VkCommandBuffer commandBuffer, + VkPipelineBindPoint pipelineBindPoint, + VkPipelineLayout layout, + uint32_t set, + uint32_t descriptorWriteCount, + const VkWriteDescriptorSet* pDescriptorWrites); + +VKAPI_ATTR void VKAPI_CALL vkCmdPushDescriptorSetWithTemplateKHR( + VkCommandBuffer commandBuffer, + VkDescriptorUpdateTemplate descriptorUpdateTemplate, + VkPipelineLayout layout, + uint32_t set, + const void* pData); +#endif + + +// VK_KHR_shader_float16_int8 is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_shader_float16_int8 1 +#define VK_KHR_SHADER_FLOAT16_INT8_SPEC_VERSION 1 +#define VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME "VK_KHR_shader_float16_int8" +typedef VkPhysicalDeviceShaderFloat16Int8Features VkPhysicalDeviceShaderFloat16Int8FeaturesKHR; + +typedef VkPhysicalDeviceShaderFloat16Int8Features VkPhysicalDeviceFloat16Int8FeaturesKHR; + + + +// VK_KHR_16bit_storage is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_16bit_storage 1 +#define VK_KHR_16BIT_STORAGE_SPEC_VERSION 1 +#define VK_KHR_16BIT_STORAGE_EXTENSION_NAME "VK_KHR_16bit_storage" +typedef VkPhysicalDevice16BitStorageFeatures VkPhysicalDevice16BitStorageFeaturesKHR; + + + +// VK_KHR_incremental_present is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_incremental_present 1 +#define VK_KHR_INCREMENTAL_PRESENT_SPEC_VERSION 2 +#define VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME "VK_KHR_incremental_present" +typedef struct VkRectLayerKHR { + VkOffset2D offset; + VkExtent2D extent; + uint32_t layer; +} VkRectLayerKHR; + +typedef struct VkPresentRegionKHR { + uint32_t rectangleCount; + const VkRectLayerKHR* pRectangles; +} VkPresentRegionKHR; + +typedef struct VkPresentRegionsKHR { + VkStructureType sType; + const void* pNext; + uint32_t swapchainCount; + const VkPresentRegionKHR* pRegions; +} VkPresentRegionsKHR; + + + +// VK_KHR_descriptor_update_template is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_descriptor_update_template 1 +typedef VkDescriptorUpdateTemplate VkDescriptorUpdateTemplateKHR; + +#define VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_SPEC_VERSION 1 +#define VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_EXTENSION_NAME "VK_KHR_descriptor_update_template" +typedef VkDescriptorUpdateTemplateType VkDescriptorUpdateTemplateTypeKHR; + +typedef VkDescriptorUpdateTemplateCreateFlags VkDescriptorUpdateTemplateCreateFlagsKHR; + +typedef VkDescriptorUpdateTemplateEntry VkDescriptorUpdateTemplateEntryKHR; + +typedef VkDescriptorUpdateTemplateCreateInfo VkDescriptorUpdateTemplateCreateInfoKHR; + +typedef VkResult (VKAPI_PTR *PFN_vkCreateDescriptorUpdateTemplateKHR)(VkDevice device, const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate); +typedef void (VKAPI_PTR *PFN_vkDestroyDescriptorUpdateTemplateKHR)(VkDevice device, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const VkAllocationCallbacks* pAllocator); +typedef void (VKAPI_PTR *PFN_vkUpdateDescriptorSetWithTemplateKHR)(VkDevice device, VkDescriptorSet descriptorSet, VkDescriptorUpdateTemplate descriptorUpdateTemplate, const void* pData); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateDescriptorUpdateTemplateKHR( + VkDevice device, + const VkDescriptorUpdateTemplateCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkDescriptorUpdateTemplate* pDescriptorUpdateTemplate); + +VKAPI_ATTR void VKAPI_CALL vkDestroyDescriptorUpdateTemplateKHR( + VkDevice device, + VkDescriptorUpdateTemplate descriptorUpdateTemplate, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR void VKAPI_CALL vkUpdateDescriptorSetWithTemplateKHR( + VkDevice device, + VkDescriptorSet descriptorSet, + VkDescriptorUpdateTemplate descriptorUpdateTemplate, + const void* pData); +#endif + + +// VK_KHR_imageless_framebuffer is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_imageless_framebuffer 1 +#define VK_KHR_IMAGELESS_FRAMEBUFFER_SPEC_VERSION 1 +#define VK_KHR_IMAGELESS_FRAMEBUFFER_EXTENSION_NAME "VK_KHR_imageless_framebuffer" +typedef VkPhysicalDeviceImagelessFramebufferFeatures VkPhysicalDeviceImagelessFramebufferFeaturesKHR; + +typedef VkFramebufferAttachmentsCreateInfo VkFramebufferAttachmentsCreateInfoKHR; + +typedef VkFramebufferAttachmentImageInfo VkFramebufferAttachmentImageInfoKHR; + +typedef VkRenderPassAttachmentBeginInfo VkRenderPassAttachmentBeginInfoKHR; + + + +// VK_KHR_create_renderpass2 is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_create_renderpass2 1 +#define VK_KHR_CREATE_RENDERPASS_2_SPEC_VERSION 1 +#define VK_KHR_CREATE_RENDERPASS_2_EXTENSION_NAME "VK_KHR_create_renderpass2" +typedef VkRenderPassCreateInfo2 VkRenderPassCreateInfo2KHR; + +typedef VkAttachmentDescription2 VkAttachmentDescription2KHR; + +typedef VkAttachmentReference2 VkAttachmentReference2KHR; + +typedef VkSubpassDescription2 VkSubpassDescription2KHR; + +typedef VkSubpassDependency2 VkSubpassDependency2KHR; + +typedef VkSubpassBeginInfo VkSubpassBeginInfoKHR; + +typedef VkSubpassEndInfo VkSubpassEndInfoKHR; + +typedef VkResult (VKAPI_PTR *PFN_vkCreateRenderPass2KHR)(VkDevice device, const VkRenderPassCreateInfo2* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkRenderPass* pRenderPass); +typedef void (VKAPI_PTR *PFN_vkCmdBeginRenderPass2KHR)(VkCommandBuffer commandBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, const VkSubpassBeginInfo* pSubpassBeginInfo); +typedef void (VKAPI_PTR *PFN_vkCmdNextSubpass2KHR)(VkCommandBuffer commandBuffer, const VkSubpassBeginInfo* pSubpassBeginInfo, const VkSubpassEndInfo* pSubpassEndInfo); +typedef void (VKAPI_PTR *PFN_vkCmdEndRenderPass2KHR)(VkCommandBuffer commandBuffer, const VkSubpassEndInfo* pSubpassEndInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateRenderPass2KHR( + VkDevice device, + const VkRenderPassCreateInfo2* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkRenderPass* pRenderPass); + +VKAPI_ATTR void VKAPI_CALL vkCmdBeginRenderPass2KHR( + VkCommandBuffer commandBuffer, + const VkRenderPassBeginInfo* pRenderPassBegin, + const VkSubpassBeginInfo* pSubpassBeginInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdNextSubpass2KHR( + VkCommandBuffer commandBuffer, + const VkSubpassBeginInfo* pSubpassBeginInfo, + const VkSubpassEndInfo* pSubpassEndInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdEndRenderPass2KHR( + VkCommandBuffer commandBuffer, + const VkSubpassEndInfo* pSubpassEndInfo); +#endif + + +// VK_KHR_shared_presentable_image is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_shared_presentable_image 1 +#define VK_KHR_SHARED_PRESENTABLE_IMAGE_SPEC_VERSION 1 +#define VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME "VK_KHR_shared_presentable_image" +typedef struct VkSharedPresentSurfaceCapabilitiesKHR { + VkStructureType sType; + void* pNext; + VkImageUsageFlags sharedPresentSupportedUsageFlags; +} VkSharedPresentSurfaceCapabilitiesKHR; + +typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainStatusKHR)(VkDevice device, VkSwapchainKHR swapchain); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainStatusKHR( + VkDevice device, + VkSwapchainKHR swapchain); +#endif + + +// VK_KHR_external_fence_capabilities is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_external_fence_capabilities 1 +#define VK_KHR_EXTERNAL_FENCE_CAPABILITIES_SPEC_VERSION 1 +#define VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME "VK_KHR_external_fence_capabilities" +typedef VkExternalFenceHandleTypeFlags VkExternalFenceHandleTypeFlagsKHR; + +typedef VkExternalFenceHandleTypeFlagBits VkExternalFenceHandleTypeFlagBitsKHR; + +typedef VkExternalFenceFeatureFlags VkExternalFenceFeatureFlagsKHR; + +typedef VkExternalFenceFeatureFlagBits VkExternalFenceFeatureFlagBitsKHR; + +typedef VkPhysicalDeviceExternalFenceInfo VkPhysicalDeviceExternalFenceInfoKHR; + +typedef VkExternalFenceProperties VkExternalFencePropertiesKHR; + +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalFencePropertiesKHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo, VkExternalFenceProperties* pExternalFenceProperties); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceExternalFencePropertiesKHR( + VkPhysicalDevice physicalDevice, + const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo, + VkExternalFenceProperties* pExternalFenceProperties); +#endif + + +// VK_KHR_external_fence is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_external_fence 1 +#define VK_KHR_EXTERNAL_FENCE_SPEC_VERSION 1 +#define VK_KHR_EXTERNAL_FENCE_EXTENSION_NAME "VK_KHR_external_fence" +typedef VkFenceImportFlags VkFenceImportFlagsKHR; + +typedef VkFenceImportFlagBits VkFenceImportFlagBitsKHR; + +typedef VkExportFenceCreateInfo VkExportFenceCreateInfoKHR; + + + +// VK_KHR_external_fence_fd is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_external_fence_fd 1 +#define VK_KHR_EXTERNAL_FENCE_FD_SPEC_VERSION 1 +#define VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME "VK_KHR_external_fence_fd" +typedef struct VkImportFenceFdInfoKHR { + VkStructureType sType; + const void* pNext; + VkFence fence; + VkFenceImportFlags flags; + VkExternalFenceHandleTypeFlagBits handleType; + int fd; +} VkImportFenceFdInfoKHR; + +typedef struct VkFenceGetFdInfoKHR { + VkStructureType sType; + const void* pNext; + VkFence fence; + VkExternalFenceHandleTypeFlagBits handleType; +} VkFenceGetFdInfoKHR; + +typedef VkResult (VKAPI_PTR *PFN_vkImportFenceFdKHR)(VkDevice device, const VkImportFenceFdInfoKHR* pImportFenceFdInfo); +typedef VkResult (VKAPI_PTR *PFN_vkGetFenceFdKHR)(VkDevice device, const VkFenceGetFdInfoKHR* pGetFdInfo, int* pFd); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkImportFenceFdKHR( + VkDevice device, + const VkImportFenceFdInfoKHR* pImportFenceFdInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetFenceFdKHR( + VkDevice device, + const VkFenceGetFdInfoKHR* pGetFdInfo, + int* pFd); +#endif + + +// VK_KHR_performance_query is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_performance_query 1 +#define VK_KHR_PERFORMANCE_QUERY_SPEC_VERSION 1 +#define VK_KHR_PERFORMANCE_QUERY_EXTENSION_NAME "VK_KHR_performance_query" + +typedef enum VkPerformanceCounterUnitKHR { + VK_PERFORMANCE_COUNTER_UNIT_GENERIC_KHR = 0, + VK_PERFORMANCE_COUNTER_UNIT_PERCENTAGE_KHR = 1, + VK_PERFORMANCE_COUNTER_UNIT_NANOSECONDS_KHR = 2, + VK_PERFORMANCE_COUNTER_UNIT_BYTES_KHR = 3, + VK_PERFORMANCE_COUNTER_UNIT_BYTES_PER_SECOND_KHR = 4, + VK_PERFORMANCE_COUNTER_UNIT_KELVIN_KHR = 5, + VK_PERFORMANCE_COUNTER_UNIT_WATTS_KHR = 6, + VK_PERFORMANCE_COUNTER_UNIT_VOLTS_KHR = 7, + VK_PERFORMANCE_COUNTER_UNIT_AMPS_KHR = 8, + VK_PERFORMANCE_COUNTER_UNIT_HERTZ_KHR = 9, + VK_PERFORMANCE_COUNTER_UNIT_CYCLES_KHR = 10, + VK_PERFORMANCE_COUNTER_UNIT_MAX_ENUM_KHR = 0x7FFFFFFF +} VkPerformanceCounterUnitKHR; + +typedef enum VkPerformanceCounterScopeKHR { + VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_BUFFER_KHR = 0, + VK_PERFORMANCE_COUNTER_SCOPE_RENDER_PASS_KHR = 1, + VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_KHR = 2, + VK_QUERY_SCOPE_COMMAND_BUFFER_KHR = VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_BUFFER_KHR, + VK_QUERY_SCOPE_RENDER_PASS_KHR = VK_PERFORMANCE_COUNTER_SCOPE_RENDER_PASS_KHR, + VK_QUERY_SCOPE_COMMAND_KHR = VK_PERFORMANCE_COUNTER_SCOPE_COMMAND_KHR, + VK_PERFORMANCE_COUNTER_SCOPE_MAX_ENUM_KHR = 0x7FFFFFFF +} VkPerformanceCounterScopeKHR; + +typedef enum VkPerformanceCounterStorageKHR { + VK_PERFORMANCE_COUNTER_STORAGE_INT32_KHR = 0, + VK_PERFORMANCE_COUNTER_STORAGE_INT64_KHR = 1, + VK_PERFORMANCE_COUNTER_STORAGE_UINT32_KHR = 2, + VK_PERFORMANCE_COUNTER_STORAGE_UINT64_KHR = 3, + VK_PERFORMANCE_COUNTER_STORAGE_FLOAT32_KHR = 4, + VK_PERFORMANCE_COUNTER_STORAGE_FLOAT64_KHR = 5, + VK_PERFORMANCE_COUNTER_STORAGE_MAX_ENUM_KHR = 0x7FFFFFFF +} VkPerformanceCounterStorageKHR; + +typedef enum VkPerformanceCounterDescriptionFlagBitsKHR { + VK_PERFORMANCE_COUNTER_DESCRIPTION_PERFORMANCE_IMPACTING_BIT_KHR = 0x00000001, + VK_PERFORMANCE_COUNTER_DESCRIPTION_CONCURRENTLY_IMPACTED_BIT_KHR = 0x00000002, + VK_PERFORMANCE_COUNTER_DESCRIPTION_PERFORMANCE_IMPACTING_KHR = VK_PERFORMANCE_COUNTER_DESCRIPTION_PERFORMANCE_IMPACTING_BIT_KHR, + VK_PERFORMANCE_COUNTER_DESCRIPTION_CONCURRENTLY_IMPACTED_KHR = VK_PERFORMANCE_COUNTER_DESCRIPTION_CONCURRENTLY_IMPACTED_BIT_KHR, + VK_PERFORMANCE_COUNTER_DESCRIPTION_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkPerformanceCounterDescriptionFlagBitsKHR; +typedef VkFlags VkPerformanceCounterDescriptionFlagsKHR; + +typedef enum VkAcquireProfilingLockFlagBitsKHR { + VK_ACQUIRE_PROFILING_LOCK_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkAcquireProfilingLockFlagBitsKHR; +typedef VkFlags VkAcquireProfilingLockFlagsKHR; +typedef struct VkPhysicalDevicePerformanceQueryFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 performanceCounterQueryPools; + VkBool32 performanceCounterMultipleQueryPools; +} VkPhysicalDevicePerformanceQueryFeaturesKHR; + +typedef struct VkPhysicalDevicePerformanceQueryPropertiesKHR { + VkStructureType sType; + void* pNext; + VkBool32 allowCommandBufferQueryCopies; +} VkPhysicalDevicePerformanceQueryPropertiesKHR; + +typedef struct VkPerformanceCounterKHR { + VkStructureType sType; + void* pNext; + VkPerformanceCounterUnitKHR unit; + VkPerformanceCounterScopeKHR scope; + VkPerformanceCounterStorageKHR storage; + uint8_t uuid[VK_UUID_SIZE]; +} VkPerformanceCounterKHR; + +typedef struct VkPerformanceCounterDescriptionKHR { + VkStructureType sType; + void* pNext; + VkPerformanceCounterDescriptionFlagsKHR flags; + char name[VK_MAX_DESCRIPTION_SIZE]; + char category[VK_MAX_DESCRIPTION_SIZE]; + char description[VK_MAX_DESCRIPTION_SIZE]; +} VkPerformanceCounterDescriptionKHR; + +typedef struct VkQueryPoolPerformanceCreateInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t queueFamilyIndex; + uint32_t counterIndexCount; + const uint32_t* pCounterIndices; +} VkQueryPoolPerformanceCreateInfoKHR; + +typedef union VkPerformanceCounterResultKHR { + int32_t int32; + int64_t int64; + uint32_t uint32; + uint64_t uint64; + float float32; + double float64; +} VkPerformanceCounterResultKHR; + +typedef struct VkAcquireProfilingLockInfoKHR { + VkStructureType sType; + const void* pNext; + VkAcquireProfilingLockFlagsKHR flags; + uint64_t timeout; +} VkAcquireProfilingLockInfoKHR; + +typedef struct VkPerformanceQuerySubmitInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t counterPassIndex; +} VkPerformanceQuerySubmitInfoKHR; + +typedef VkResult (VKAPI_PTR *PFN_vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, uint32_t* pCounterCount, VkPerformanceCounterKHR* pCounters, VkPerformanceCounterDescriptionKHR* pCounterDescriptions); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR)(VkPhysicalDevice physicalDevice, const VkQueryPoolPerformanceCreateInfoKHR* pPerformanceQueryCreateInfo, uint32_t* pNumPasses); +typedef VkResult (VKAPI_PTR *PFN_vkAcquireProfilingLockKHR)(VkDevice device, const VkAcquireProfilingLockInfoKHR* pInfo); +typedef void (VKAPI_PTR *PFN_vkReleaseProfilingLockKHR)(VkDevice device); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkEnumeratePhysicalDeviceQueueFamilyPerformanceQueryCountersKHR( + VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex, + uint32_t* pCounterCount, + VkPerformanceCounterKHR* pCounters, + VkPerformanceCounterDescriptionKHR* pCounterDescriptions); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyPerformanceQueryPassesKHR( + VkPhysicalDevice physicalDevice, + const VkQueryPoolPerformanceCreateInfoKHR* pPerformanceQueryCreateInfo, + uint32_t* pNumPasses); + +VKAPI_ATTR VkResult VKAPI_CALL vkAcquireProfilingLockKHR( + VkDevice device, + const VkAcquireProfilingLockInfoKHR* pInfo); + +VKAPI_ATTR void VKAPI_CALL vkReleaseProfilingLockKHR( + VkDevice device); +#endif + + +// VK_KHR_maintenance2 is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_maintenance2 1 +#define VK_KHR_MAINTENANCE_2_SPEC_VERSION 1 +#define VK_KHR_MAINTENANCE_2_EXTENSION_NAME "VK_KHR_maintenance2" +#define VK_KHR_MAINTENANCE2_SPEC_VERSION VK_KHR_MAINTENANCE_2_SPEC_VERSION +#define VK_KHR_MAINTENANCE2_EXTENSION_NAME VK_KHR_MAINTENANCE_2_EXTENSION_NAME +typedef VkPointClippingBehavior VkPointClippingBehaviorKHR; + +typedef VkTessellationDomainOrigin VkTessellationDomainOriginKHR; + +typedef VkPhysicalDevicePointClippingProperties VkPhysicalDevicePointClippingPropertiesKHR; + +typedef VkRenderPassInputAttachmentAspectCreateInfo VkRenderPassInputAttachmentAspectCreateInfoKHR; + +typedef VkInputAttachmentAspectReference VkInputAttachmentAspectReferenceKHR; + +typedef VkImageViewUsageCreateInfo VkImageViewUsageCreateInfoKHR; + +typedef VkPipelineTessellationDomainOriginStateCreateInfo VkPipelineTessellationDomainOriginStateCreateInfoKHR; + + + +// VK_KHR_get_surface_capabilities2 is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_get_surface_capabilities2 1 +#define VK_KHR_GET_SURFACE_CAPABILITIES_2_SPEC_VERSION 1 +#define VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME "VK_KHR_get_surface_capabilities2" +typedef struct VkPhysicalDeviceSurfaceInfo2KHR { + VkStructureType sType; + const void* pNext; + VkSurfaceKHR surface; +} VkPhysicalDeviceSurfaceInfo2KHR; + +typedef struct VkSurfaceCapabilities2KHR { + VkStructureType sType; + void* pNext; + VkSurfaceCapabilitiesKHR surfaceCapabilities; +} VkSurfaceCapabilities2KHR; + +typedef struct VkSurfaceFormat2KHR { + VkStructureType sType; + void* pNext; + VkSurfaceFormatKHR surfaceFormat; +} VkSurfaceFormat2KHR; + +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, VkSurfaceCapabilities2KHR* pSurfaceCapabilities); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceFormats2KHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, uint32_t* pSurfaceFormatCount, VkSurfaceFormat2KHR* pSurfaceFormats); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilities2KHR( + VkPhysicalDevice physicalDevice, + const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, + VkSurfaceCapabilities2KHR* pSurfaceCapabilities); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceFormats2KHR( + VkPhysicalDevice physicalDevice, + const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, + uint32_t* pSurfaceFormatCount, + VkSurfaceFormat2KHR* pSurfaceFormats); +#endif + + +// VK_KHR_variable_pointers is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_variable_pointers 1 +#define VK_KHR_VARIABLE_POINTERS_SPEC_VERSION 1 +#define VK_KHR_VARIABLE_POINTERS_EXTENSION_NAME "VK_KHR_variable_pointers" +typedef VkPhysicalDeviceVariablePointersFeatures VkPhysicalDeviceVariablePointerFeaturesKHR; + +typedef VkPhysicalDeviceVariablePointersFeatures VkPhysicalDeviceVariablePointersFeaturesKHR; + + + +// VK_KHR_get_display_properties2 is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_get_display_properties2 1 +#define VK_KHR_GET_DISPLAY_PROPERTIES_2_SPEC_VERSION 1 +#define VK_KHR_GET_DISPLAY_PROPERTIES_2_EXTENSION_NAME "VK_KHR_get_display_properties2" +typedef struct VkDisplayProperties2KHR { + VkStructureType sType; + void* pNext; + VkDisplayPropertiesKHR displayProperties; +} VkDisplayProperties2KHR; + +typedef struct VkDisplayPlaneProperties2KHR { + VkStructureType sType; + void* pNext; + VkDisplayPlanePropertiesKHR displayPlaneProperties; +} VkDisplayPlaneProperties2KHR; + +typedef struct VkDisplayModeProperties2KHR { + VkStructureType sType; + void* pNext; + VkDisplayModePropertiesKHR displayModeProperties; +} VkDisplayModeProperties2KHR; + +typedef struct VkDisplayPlaneInfo2KHR { + VkStructureType sType; + const void* pNext; + VkDisplayModeKHR mode; + uint32_t planeIndex; +} VkDisplayPlaneInfo2KHR; + +typedef struct VkDisplayPlaneCapabilities2KHR { + VkStructureType sType; + void* pNext; + VkDisplayPlaneCapabilitiesKHR capabilities; +} VkDisplayPlaneCapabilities2KHR; + +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceDisplayProperties2KHR)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkDisplayProperties2KHR* pProperties); +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceDisplayPlaneProperties2KHR)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkDisplayPlaneProperties2KHR* pProperties); +typedef VkResult (VKAPI_PTR *PFN_vkGetDisplayModeProperties2KHR)(VkPhysicalDevice physicalDevice, VkDisplayKHR display, uint32_t* pPropertyCount, VkDisplayModeProperties2KHR* pProperties); +typedef VkResult (VKAPI_PTR *PFN_vkGetDisplayPlaneCapabilities2KHR)(VkPhysicalDevice physicalDevice, const VkDisplayPlaneInfo2KHR* pDisplayPlaneInfo, VkDisplayPlaneCapabilities2KHR* pCapabilities); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayProperties2KHR( + VkPhysicalDevice physicalDevice, + uint32_t* pPropertyCount, + VkDisplayProperties2KHR* pProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceDisplayPlaneProperties2KHR( + VkPhysicalDevice physicalDevice, + uint32_t* pPropertyCount, + VkDisplayPlaneProperties2KHR* pProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayModeProperties2KHR( + VkPhysicalDevice physicalDevice, + VkDisplayKHR display, + uint32_t* pPropertyCount, + VkDisplayModeProperties2KHR* pProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneCapabilities2KHR( + VkPhysicalDevice physicalDevice, + const VkDisplayPlaneInfo2KHR* pDisplayPlaneInfo, + VkDisplayPlaneCapabilities2KHR* pCapabilities); +#endif + + +// VK_KHR_dedicated_allocation is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_dedicated_allocation 1 +#define VK_KHR_DEDICATED_ALLOCATION_SPEC_VERSION 3 +#define VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME "VK_KHR_dedicated_allocation" +typedef VkMemoryDedicatedRequirements VkMemoryDedicatedRequirementsKHR; + +typedef VkMemoryDedicatedAllocateInfo VkMemoryDedicatedAllocateInfoKHR; + + + +// VK_KHR_storage_buffer_storage_class is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_storage_buffer_storage_class 1 +#define VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_SPEC_VERSION 1 +#define VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_EXTENSION_NAME "VK_KHR_storage_buffer_storage_class" + + +// VK_KHR_relaxed_block_layout is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_relaxed_block_layout 1 +#define VK_KHR_RELAXED_BLOCK_LAYOUT_SPEC_VERSION 1 +#define VK_KHR_RELAXED_BLOCK_LAYOUT_EXTENSION_NAME "VK_KHR_relaxed_block_layout" + + +// VK_KHR_get_memory_requirements2 is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_get_memory_requirements2 1 +#define VK_KHR_GET_MEMORY_REQUIREMENTS_2_SPEC_VERSION 1 +#define VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME "VK_KHR_get_memory_requirements2" +typedef VkBufferMemoryRequirementsInfo2 VkBufferMemoryRequirementsInfo2KHR; + +typedef VkImageMemoryRequirementsInfo2 VkImageMemoryRequirementsInfo2KHR; + +typedef VkImageSparseMemoryRequirementsInfo2 VkImageSparseMemoryRequirementsInfo2KHR; + +typedef VkMemoryRequirements2 VkMemoryRequirements2KHR; + +typedef VkSparseImageMemoryRequirements2 VkSparseImageMemoryRequirements2KHR; + +typedef void (VKAPI_PTR *PFN_vkGetImageMemoryRequirements2KHR)(VkDevice device, const VkImageMemoryRequirementsInfo2* pInfo, VkMemoryRequirements2* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetBufferMemoryRequirements2KHR)(VkDevice device, const VkBufferMemoryRequirementsInfo2* pInfo, VkMemoryRequirements2* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetImageSparseMemoryRequirements2KHR)(VkDevice device, const VkImageSparseMemoryRequirementsInfo2* pInfo, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2* pSparseMemoryRequirements); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkGetImageMemoryRequirements2KHR( + VkDevice device, + const VkImageMemoryRequirementsInfo2* pInfo, + VkMemoryRequirements2* pMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkGetBufferMemoryRequirements2KHR( + VkDevice device, + const VkBufferMemoryRequirementsInfo2* pInfo, + VkMemoryRequirements2* pMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkGetImageSparseMemoryRequirements2KHR( + VkDevice device, + const VkImageSparseMemoryRequirementsInfo2* pInfo, + uint32_t* pSparseMemoryRequirementCount, + VkSparseImageMemoryRequirements2* pSparseMemoryRequirements); +#endif + + +// VK_KHR_image_format_list is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_image_format_list 1 +#define VK_KHR_IMAGE_FORMAT_LIST_SPEC_VERSION 1 +#define VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME "VK_KHR_image_format_list" +typedef VkImageFormatListCreateInfo VkImageFormatListCreateInfoKHR; + + + +// VK_KHR_sampler_ycbcr_conversion is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_sampler_ycbcr_conversion 1 +typedef VkSamplerYcbcrConversion VkSamplerYcbcrConversionKHR; + +#define VK_KHR_SAMPLER_YCBCR_CONVERSION_SPEC_VERSION 14 +#define VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME "VK_KHR_sampler_ycbcr_conversion" +typedef VkSamplerYcbcrModelConversion VkSamplerYcbcrModelConversionKHR; + +typedef VkSamplerYcbcrRange VkSamplerYcbcrRangeKHR; + +typedef VkChromaLocation VkChromaLocationKHR; + +typedef VkSamplerYcbcrConversionCreateInfo VkSamplerYcbcrConversionCreateInfoKHR; + +typedef VkSamplerYcbcrConversionInfo VkSamplerYcbcrConversionInfoKHR; + +typedef VkBindImagePlaneMemoryInfo VkBindImagePlaneMemoryInfoKHR; + +typedef VkImagePlaneMemoryRequirementsInfo VkImagePlaneMemoryRequirementsInfoKHR; + +typedef VkPhysicalDeviceSamplerYcbcrConversionFeatures VkPhysicalDeviceSamplerYcbcrConversionFeaturesKHR; + +typedef VkSamplerYcbcrConversionImageFormatProperties VkSamplerYcbcrConversionImageFormatPropertiesKHR; + +typedef VkResult (VKAPI_PTR *PFN_vkCreateSamplerYcbcrConversionKHR)(VkDevice device, const VkSamplerYcbcrConversionCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSamplerYcbcrConversion* pYcbcrConversion); +typedef void (VKAPI_PTR *PFN_vkDestroySamplerYcbcrConversionKHR)(VkDevice device, VkSamplerYcbcrConversion ycbcrConversion, const VkAllocationCallbacks* pAllocator); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateSamplerYcbcrConversionKHR( + VkDevice device, + const VkSamplerYcbcrConversionCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSamplerYcbcrConversion* pYcbcrConversion); + +VKAPI_ATTR void VKAPI_CALL vkDestroySamplerYcbcrConversionKHR( + VkDevice device, + VkSamplerYcbcrConversion ycbcrConversion, + const VkAllocationCallbacks* pAllocator); +#endif + + +// VK_KHR_bind_memory2 is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_bind_memory2 1 +#define VK_KHR_BIND_MEMORY_2_SPEC_VERSION 1 +#define VK_KHR_BIND_MEMORY_2_EXTENSION_NAME "VK_KHR_bind_memory2" +typedef VkBindBufferMemoryInfo VkBindBufferMemoryInfoKHR; + +typedef VkBindImageMemoryInfo VkBindImageMemoryInfoKHR; + +typedef VkResult (VKAPI_PTR *PFN_vkBindBufferMemory2KHR)(VkDevice device, uint32_t bindInfoCount, const VkBindBufferMemoryInfo* pBindInfos); +typedef VkResult (VKAPI_PTR *PFN_vkBindImageMemory2KHR)(VkDevice device, uint32_t bindInfoCount, const VkBindImageMemoryInfo* pBindInfos); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkBindBufferMemory2KHR( + VkDevice device, + uint32_t bindInfoCount, + const VkBindBufferMemoryInfo* pBindInfos); + +VKAPI_ATTR VkResult VKAPI_CALL vkBindImageMemory2KHR( + VkDevice device, + uint32_t bindInfoCount, + const VkBindImageMemoryInfo* pBindInfos); +#endif + + +// VK_KHR_maintenance3 is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_maintenance3 1 +#define VK_KHR_MAINTENANCE_3_SPEC_VERSION 1 +#define VK_KHR_MAINTENANCE_3_EXTENSION_NAME "VK_KHR_maintenance3" +#define VK_KHR_MAINTENANCE3_SPEC_VERSION VK_KHR_MAINTENANCE_3_SPEC_VERSION +#define VK_KHR_MAINTENANCE3_EXTENSION_NAME VK_KHR_MAINTENANCE_3_EXTENSION_NAME +typedef VkPhysicalDeviceMaintenance3Properties VkPhysicalDeviceMaintenance3PropertiesKHR; + +typedef VkDescriptorSetLayoutSupport VkDescriptorSetLayoutSupportKHR; + +typedef void (VKAPI_PTR *PFN_vkGetDescriptorSetLayoutSupportKHR)(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, VkDescriptorSetLayoutSupport* pSupport); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkGetDescriptorSetLayoutSupportKHR( + VkDevice device, + const VkDescriptorSetLayoutCreateInfo* pCreateInfo, + VkDescriptorSetLayoutSupport* pSupport); +#endif + + +// VK_KHR_draw_indirect_count is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_draw_indirect_count 1 +#define VK_KHR_DRAW_INDIRECT_COUNT_SPEC_VERSION 1 +#define VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME "VK_KHR_draw_indirect_count" +typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirectCountKHR)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); +typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexedIndirectCountKHR)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirectCountKHR( + VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset, + VkBuffer countBuffer, + VkDeviceSize countBufferOffset, + uint32_t maxDrawCount, + uint32_t stride); + +VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirectCountKHR( + VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset, + VkBuffer countBuffer, + VkDeviceSize countBufferOffset, + uint32_t maxDrawCount, + uint32_t stride); +#endif + + +// VK_KHR_shader_subgroup_extended_types is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_shader_subgroup_extended_types 1 +#define VK_KHR_SHADER_SUBGROUP_EXTENDED_TYPES_SPEC_VERSION 1 +#define VK_KHR_SHADER_SUBGROUP_EXTENDED_TYPES_EXTENSION_NAME "VK_KHR_shader_subgroup_extended_types" +typedef VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR; + + + +// VK_KHR_8bit_storage is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_8bit_storage 1 +#define VK_KHR_8BIT_STORAGE_SPEC_VERSION 1 +#define VK_KHR_8BIT_STORAGE_EXTENSION_NAME "VK_KHR_8bit_storage" +typedef VkPhysicalDevice8BitStorageFeatures VkPhysicalDevice8BitStorageFeaturesKHR; + + + +// VK_KHR_shader_atomic_int64 is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_shader_atomic_int64 1 +#define VK_KHR_SHADER_ATOMIC_INT64_SPEC_VERSION 1 +#define VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME "VK_KHR_shader_atomic_int64" +typedef VkPhysicalDeviceShaderAtomicInt64Features VkPhysicalDeviceShaderAtomicInt64FeaturesKHR; + + + +// VK_KHR_shader_clock is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_shader_clock 1 +#define VK_KHR_SHADER_CLOCK_SPEC_VERSION 1 +#define VK_KHR_SHADER_CLOCK_EXTENSION_NAME "VK_KHR_shader_clock" +typedef struct VkPhysicalDeviceShaderClockFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 shaderSubgroupClock; + VkBool32 shaderDeviceClock; +} VkPhysicalDeviceShaderClockFeaturesKHR; + + + +// VK_KHR_video_decode_h265 is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_video_decode_h265 1 +#include "../vk_video/vulkan_video_codec_h265std_decode.h" +#define VK_KHR_VIDEO_DECODE_H265_SPEC_VERSION 8 +#define VK_KHR_VIDEO_DECODE_H265_EXTENSION_NAME "VK_KHR_video_decode_h265" +typedef struct VkVideoDecodeH265ProfileInfoKHR { + VkStructureType sType; + const void* pNext; + StdVideoH265ProfileIdc stdProfileIdc; +} VkVideoDecodeH265ProfileInfoKHR; + +typedef struct VkVideoDecodeH265CapabilitiesKHR { + VkStructureType sType; + void* pNext; + StdVideoH265LevelIdc maxLevelIdc; +} VkVideoDecodeH265CapabilitiesKHR; + +typedef struct VkVideoDecodeH265SessionParametersAddInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t stdVPSCount; + const StdVideoH265VideoParameterSet* pStdVPSs; + uint32_t stdSPSCount; + const StdVideoH265SequenceParameterSet* pStdSPSs; + uint32_t stdPPSCount; + const StdVideoH265PictureParameterSet* pStdPPSs; +} VkVideoDecodeH265SessionParametersAddInfoKHR; + +typedef struct VkVideoDecodeH265SessionParametersCreateInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t maxStdVPSCount; + uint32_t maxStdSPSCount; + uint32_t maxStdPPSCount; + const VkVideoDecodeH265SessionParametersAddInfoKHR* pParametersAddInfo; +} VkVideoDecodeH265SessionParametersCreateInfoKHR; + +typedef struct VkVideoDecodeH265PictureInfoKHR { + VkStructureType sType; + const void* pNext; + const StdVideoDecodeH265PictureInfo* pStdPictureInfo; + uint32_t sliceSegmentCount; + const uint32_t* pSliceSegmentOffsets; +} VkVideoDecodeH265PictureInfoKHR; + +typedef struct VkVideoDecodeH265DpbSlotInfoKHR { + VkStructureType sType; + const void* pNext; + const StdVideoDecodeH265ReferenceInfo* pStdReferenceInfo; +} VkVideoDecodeH265DpbSlotInfoKHR; + + + +// VK_KHR_global_priority is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_global_priority 1 +#define VK_MAX_GLOBAL_PRIORITY_SIZE_KHR 16U +#define VK_KHR_GLOBAL_PRIORITY_SPEC_VERSION 1 +#define VK_KHR_GLOBAL_PRIORITY_EXTENSION_NAME "VK_KHR_global_priority" + +typedef enum VkQueueGlobalPriorityKHR { + VK_QUEUE_GLOBAL_PRIORITY_LOW_KHR = 128, + VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_KHR = 256, + VK_QUEUE_GLOBAL_PRIORITY_HIGH_KHR = 512, + VK_QUEUE_GLOBAL_PRIORITY_REALTIME_KHR = 1024, + VK_QUEUE_GLOBAL_PRIORITY_LOW_EXT = VK_QUEUE_GLOBAL_PRIORITY_LOW_KHR, + VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT = VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_KHR, + VK_QUEUE_GLOBAL_PRIORITY_HIGH_EXT = VK_QUEUE_GLOBAL_PRIORITY_HIGH_KHR, + VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT = VK_QUEUE_GLOBAL_PRIORITY_REALTIME_KHR, + VK_QUEUE_GLOBAL_PRIORITY_MAX_ENUM_KHR = 0x7FFFFFFF +} VkQueueGlobalPriorityKHR; +typedef struct VkDeviceQueueGlobalPriorityCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkQueueGlobalPriorityKHR globalPriority; +} VkDeviceQueueGlobalPriorityCreateInfoKHR; + +typedef struct VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 globalPriorityQuery; +} VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR; + +typedef struct VkQueueFamilyGlobalPriorityPropertiesKHR { + VkStructureType sType; + void* pNext; + uint32_t priorityCount; + VkQueueGlobalPriorityKHR priorities[VK_MAX_GLOBAL_PRIORITY_SIZE_KHR]; +} VkQueueFamilyGlobalPriorityPropertiesKHR; + + + +// VK_KHR_driver_properties is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_driver_properties 1 +#define VK_KHR_DRIVER_PROPERTIES_SPEC_VERSION 1 +#define VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME "VK_KHR_driver_properties" +#define VK_MAX_DRIVER_NAME_SIZE_KHR VK_MAX_DRIVER_NAME_SIZE +#define VK_MAX_DRIVER_INFO_SIZE_KHR VK_MAX_DRIVER_INFO_SIZE +typedef VkDriverId VkDriverIdKHR; + +typedef VkConformanceVersion VkConformanceVersionKHR; + +typedef VkPhysicalDeviceDriverProperties VkPhysicalDeviceDriverPropertiesKHR; + + + +// VK_KHR_shader_float_controls is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_shader_float_controls 1 +#define VK_KHR_SHADER_FLOAT_CONTROLS_SPEC_VERSION 4 +#define VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME "VK_KHR_shader_float_controls" +typedef VkShaderFloatControlsIndependence VkShaderFloatControlsIndependenceKHR; + +typedef VkPhysicalDeviceFloatControlsProperties VkPhysicalDeviceFloatControlsPropertiesKHR; + + + +// VK_KHR_depth_stencil_resolve is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_depth_stencil_resolve 1 +#define VK_KHR_DEPTH_STENCIL_RESOLVE_SPEC_VERSION 1 +#define VK_KHR_DEPTH_STENCIL_RESOLVE_EXTENSION_NAME "VK_KHR_depth_stencil_resolve" +typedef VkResolveModeFlagBits VkResolveModeFlagBitsKHR; + +typedef VkResolveModeFlags VkResolveModeFlagsKHR; + +typedef VkSubpassDescriptionDepthStencilResolve VkSubpassDescriptionDepthStencilResolveKHR; + +typedef VkPhysicalDeviceDepthStencilResolveProperties VkPhysicalDeviceDepthStencilResolvePropertiesKHR; + + + +// VK_KHR_swapchain_mutable_format is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_swapchain_mutable_format 1 +#define VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_SPEC_VERSION 1 +#define VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_EXTENSION_NAME "VK_KHR_swapchain_mutable_format" + + +// VK_KHR_timeline_semaphore is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_timeline_semaphore 1 +#define VK_KHR_TIMELINE_SEMAPHORE_SPEC_VERSION 2 +#define VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME "VK_KHR_timeline_semaphore" +typedef VkSemaphoreType VkSemaphoreTypeKHR; + +typedef VkSemaphoreWaitFlagBits VkSemaphoreWaitFlagBitsKHR; + +typedef VkSemaphoreWaitFlags VkSemaphoreWaitFlagsKHR; + +typedef VkPhysicalDeviceTimelineSemaphoreFeatures VkPhysicalDeviceTimelineSemaphoreFeaturesKHR; + +typedef VkPhysicalDeviceTimelineSemaphoreProperties VkPhysicalDeviceTimelineSemaphorePropertiesKHR; + +typedef VkSemaphoreTypeCreateInfo VkSemaphoreTypeCreateInfoKHR; + +typedef VkTimelineSemaphoreSubmitInfo VkTimelineSemaphoreSubmitInfoKHR; + +typedef VkSemaphoreWaitInfo VkSemaphoreWaitInfoKHR; + +typedef VkSemaphoreSignalInfo VkSemaphoreSignalInfoKHR; + +typedef VkResult (VKAPI_PTR *PFN_vkGetSemaphoreCounterValueKHR)(VkDevice device, VkSemaphore semaphore, uint64_t* pValue); +typedef VkResult (VKAPI_PTR *PFN_vkWaitSemaphoresKHR)(VkDevice device, const VkSemaphoreWaitInfo* pWaitInfo, uint64_t timeout); +typedef VkResult (VKAPI_PTR *PFN_vkSignalSemaphoreKHR)(VkDevice device, const VkSemaphoreSignalInfo* pSignalInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreCounterValueKHR( + VkDevice device, + VkSemaphore semaphore, + uint64_t* pValue); + +VKAPI_ATTR VkResult VKAPI_CALL vkWaitSemaphoresKHR( + VkDevice device, + const VkSemaphoreWaitInfo* pWaitInfo, + uint64_t timeout); + +VKAPI_ATTR VkResult VKAPI_CALL vkSignalSemaphoreKHR( + VkDevice device, + const VkSemaphoreSignalInfo* pSignalInfo); +#endif + + +// VK_KHR_vulkan_memory_model is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_vulkan_memory_model 1 +#define VK_KHR_VULKAN_MEMORY_MODEL_SPEC_VERSION 3 +#define VK_KHR_VULKAN_MEMORY_MODEL_EXTENSION_NAME "VK_KHR_vulkan_memory_model" +typedef VkPhysicalDeviceVulkanMemoryModelFeatures VkPhysicalDeviceVulkanMemoryModelFeaturesKHR; + + + +// VK_KHR_shader_terminate_invocation is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_shader_terminate_invocation 1 +#define VK_KHR_SHADER_TERMINATE_INVOCATION_SPEC_VERSION 1 +#define VK_KHR_SHADER_TERMINATE_INVOCATION_EXTENSION_NAME "VK_KHR_shader_terminate_invocation" +typedef VkPhysicalDeviceShaderTerminateInvocationFeatures VkPhysicalDeviceShaderTerminateInvocationFeaturesKHR; + + + +// VK_KHR_fragment_shading_rate is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_fragment_shading_rate 1 +#define VK_KHR_FRAGMENT_SHADING_RATE_SPEC_VERSION 2 +#define VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME "VK_KHR_fragment_shading_rate" + +typedef enum VkFragmentShadingRateCombinerOpKHR { + VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR = 0, + VK_FRAGMENT_SHADING_RATE_COMBINER_OP_REPLACE_KHR = 1, + VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MIN_KHR = 2, + VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MAX_KHR = 3, + VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MUL_KHR = 4, + VK_FRAGMENT_SHADING_RATE_COMBINER_OP_MAX_ENUM_KHR = 0x7FFFFFFF +} VkFragmentShadingRateCombinerOpKHR; +typedef struct VkFragmentShadingRateAttachmentInfoKHR { + VkStructureType sType; + const void* pNext; + const VkAttachmentReference2* pFragmentShadingRateAttachment; + VkExtent2D shadingRateAttachmentTexelSize; +} VkFragmentShadingRateAttachmentInfoKHR; + +typedef struct VkPipelineFragmentShadingRateStateCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkExtent2D fragmentSize; + VkFragmentShadingRateCombinerOpKHR combinerOps[2]; +} VkPipelineFragmentShadingRateStateCreateInfoKHR; + +typedef struct VkPhysicalDeviceFragmentShadingRateFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 pipelineFragmentShadingRate; + VkBool32 primitiveFragmentShadingRate; + VkBool32 attachmentFragmentShadingRate; +} VkPhysicalDeviceFragmentShadingRateFeaturesKHR; + +typedef struct VkPhysicalDeviceFragmentShadingRatePropertiesKHR { + VkStructureType sType; + void* pNext; + VkExtent2D minFragmentShadingRateAttachmentTexelSize; + VkExtent2D maxFragmentShadingRateAttachmentTexelSize; + uint32_t maxFragmentShadingRateAttachmentTexelSizeAspectRatio; + VkBool32 primitiveFragmentShadingRateWithMultipleViewports; + VkBool32 layeredShadingRateAttachments; + VkBool32 fragmentShadingRateNonTrivialCombinerOps; + VkExtent2D maxFragmentSize; + uint32_t maxFragmentSizeAspectRatio; + uint32_t maxFragmentShadingRateCoverageSamples; + VkSampleCountFlagBits maxFragmentShadingRateRasterizationSamples; + VkBool32 fragmentShadingRateWithShaderDepthStencilWrites; + VkBool32 fragmentShadingRateWithSampleMask; + VkBool32 fragmentShadingRateWithShaderSampleMask; + VkBool32 fragmentShadingRateWithConservativeRasterization; + VkBool32 fragmentShadingRateWithFragmentShaderInterlock; + VkBool32 fragmentShadingRateWithCustomSampleLocations; + VkBool32 fragmentShadingRateStrictMultiplyCombiner; +} VkPhysicalDeviceFragmentShadingRatePropertiesKHR; + +typedef struct VkPhysicalDeviceFragmentShadingRateKHR { + VkStructureType sType; + void* pNext; + VkSampleCountFlags sampleCounts; + VkExtent2D fragmentSize; +} VkPhysicalDeviceFragmentShadingRateKHR; + +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceFragmentShadingRatesKHR)(VkPhysicalDevice physicalDevice, uint32_t* pFragmentShadingRateCount, VkPhysicalDeviceFragmentShadingRateKHR* pFragmentShadingRates); +typedef void (VKAPI_PTR *PFN_vkCmdSetFragmentShadingRateKHR)(VkCommandBuffer commandBuffer, const VkExtent2D* pFragmentSize, const VkFragmentShadingRateCombinerOpKHR combinerOps[2]); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceFragmentShadingRatesKHR( + VkPhysicalDevice physicalDevice, + uint32_t* pFragmentShadingRateCount, + VkPhysicalDeviceFragmentShadingRateKHR* pFragmentShadingRates); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetFragmentShadingRateKHR( + VkCommandBuffer commandBuffer, + const VkExtent2D* pFragmentSize, + const VkFragmentShadingRateCombinerOpKHR combinerOps[2]); +#endif + + +// VK_KHR_spirv_1_4 is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_spirv_1_4 1 +#define VK_KHR_SPIRV_1_4_SPEC_VERSION 1 +#define VK_KHR_SPIRV_1_4_EXTENSION_NAME "VK_KHR_spirv_1_4" + + +// VK_KHR_surface_protected_capabilities is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_surface_protected_capabilities 1 +#define VK_KHR_SURFACE_PROTECTED_CAPABILITIES_SPEC_VERSION 1 +#define VK_KHR_SURFACE_PROTECTED_CAPABILITIES_EXTENSION_NAME "VK_KHR_surface_protected_capabilities" +typedef struct VkSurfaceProtectedCapabilitiesKHR { + VkStructureType sType; + const void* pNext; + VkBool32 supportsProtected; +} VkSurfaceProtectedCapabilitiesKHR; + + + +// VK_KHR_separate_depth_stencil_layouts is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_separate_depth_stencil_layouts 1 +#define VK_KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS_SPEC_VERSION 1 +#define VK_KHR_SEPARATE_DEPTH_STENCIL_LAYOUTS_EXTENSION_NAME "VK_KHR_separate_depth_stencil_layouts" +typedef VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR; + +typedef VkAttachmentReferenceStencilLayout VkAttachmentReferenceStencilLayoutKHR; + +typedef VkAttachmentDescriptionStencilLayout VkAttachmentDescriptionStencilLayoutKHR; + + + +// VK_KHR_present_wait is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_present_wait 1 +#define VK_KHR_PRESENT_WAIT_SPEC_VERSION 1 +#define VK_KHR_PRESENT_WAIT_EXTENSION_NAME "VK_KHR_present_wait" +typedef struct VkPhysicalDevicePresentWaitFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 presentWait; +} VkPhysicalDevicePresentWaitFeaturesKHR; + +typedef VkResult (VKAPI_PTR *PFN_vkWaitForPresentKHR)(VkDevice device, VkSwapchainKHR swapchain, uint64_t presentId, uint64_t timeout); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkWaitForPresentKHR( + VkDevice device, + VkSwapchainKHR swapchain, + uint64_t presentId, + uint64_t timeout); +#endif + + +// VK_KHR_uniform_buffer_standard_layout is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_uniform_buffer_standard_layout 1 +#define VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_SPEC_VERSION 1 +#define VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME "VK_KHR_uniform_buffer_standard_layout" +typedef VkPhysicalDeviceUniformBufferStandardLayoutFeatures VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR; + + + +// VK_KHR_buffer_device_address is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_buffer_device_address 1 +#define VK_KHR_BUFFER_DEVICE_ADDRESS_SPEC_VERSION 1 +#define VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME "VK_KHR_buffer_device_address" +typedef VkPhysicalDeviceBufferDeviceAddressFeatures VkPhysicalDeviceBufferDeviceAddressFeaturesKHR; + +typedef VkBufferDeviceAddressInfo VkBufferDeviceAddressInfoKHR; + +typedef VkBufferOpaqueCaptureAddressCreateInfo VkBufferOpaqueCaptureAddressCreateInfoKHR; + +typedef VkMemoryOpaqueCaptureAddressAllocateInfo VkMemoryOpaqueCaptureAddressAllocateInfoKHR; + +typedef VkDeviceMemoryOpaqueCaptureAddressInfo VkDeviceMemoryOpaqueCaptureAddressInfoKHR; + +typedef VkDeviceAddress (VKAPI_PTR *PFN_vkGetBufferDeviceAddressKHR)(VkDevice device, const VkBufferDeviceAddressInfo* pInfo); +typedef uint64_t (VKAPI_PTR *PFN_vkGetBufferOpaqueCaptureAddressKHR)(VkDevice device, const VkBufferDeviceAddressInfo* pInfo); +typedef uint64_t (VKAPI_PTR *PFN_vkGetDeviceMemoryOpaqueCaptureAddressKHR)(VkDevice device, const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkDeviceAddress VKAPI_CALL vkGetBufferDeviceAddressKHR( + VkDevice device, + const VkBufferDeviceAddressInfo* pInfo); + +VKAPI_ATTR uint64_t VKAPI_CALL vkGetBufferOpaqueCaptureAddressKHR( + VkDevice device, + const VkBufferDeviceAddressInfo* pInfo); + +VKAPI_ATTR uint64_t VKAPI_CALL vkGetDeviceMemoryOpaqueCaptureAddressKHR( + VkDevice device, + const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo); +#endif + + +// VK_KHR_deferred_host_operations is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_deferred_host_operations 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDeferredOperationKHR) +#define VK_KHR_DEFERRED_HOST_OPERATIONS_SPEC_VERSION 4 +#define VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME "VK_KHR_deferred_host_operations" +typedef VkResult (VKAPI_PTR *PFN_vkCreateDeferredOperationKHR)(VkDevice device, const VkAllocationCallbacks* pAllocator, VkDeferredOperationKHR* pDeferredOperation); +typedef void (VKAPI_PTR *PFN_vkDestroyDeferredOperationKHR)(VkDevice device, VkDeferredOperationKHR operation, const VkAllocationCallbacks* pAllocator); +typedef uint32_t (VKAPI_PTR *PFN_vkGetDeferredOperationMaxConcurrencyKHR)(VkDevice device, VkDeferredOperationKHR operation); +typedef VkResult (VKAPI_PTR *PFN_vkGetDeferredOperationResultKHR)(VkDevice device, VkDeferredOperationKHR operation); +typedef VkResult (VKAPI_PTR *PFN_vkDeferredOperationJoinKHR)(VkDevice device, VkDeferredOperationKHR operation); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateDeferredOperationKHR( + VkDevice device, + const VkAllocationCallbacks* pAllocator, + VkDeferredOperationKHR* pDeferredOperation); + +VKAPI_ATTR void VKAPI_CALL vkDestroyDeferredOperationKHR( + VkDevice device, + VkDeferredOperationKHR operation, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR uint32_t VKAPI_CALL vkGetDeferredOperationMaxConcurrencyKHR( + VkDevice device, + VkDeferredOperationKHR operation); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetDeferredOperationResultKHR( + VkDevice device, + VkDeferredOperationKHR operation); + +VKAPI_ATTR VkResult VKAPI_CALL vkDeferredOperationJoinKHR( + VkDevice device, + VkDeferredOperationKHR operation); +#endif + + +// VK_KHR_pipeline_executable_properties is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_pipeline_executable_properties 1 +#define VK_KHR_PIPELINE_EXECUTABLE_PROPERTIES_SPEC_VERSION 1 +#define VK_KHR_PIPELINE_EXECUTABLE_PROPERTIES_EXTENSION_NAME "VK_KHR_pipeline_executable_properties" + +typedef enum VkPipelineExecutableStatisticFormatKHR { + VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_BOOL32_KHR = 0, + VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_INT64_KHR = 1, + VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR = 2, + VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_FLOAT64_KHR = 3, + VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_MAX_ENUM_KHR = 0x7FFFFFFF +} VkPipelineExecutableStatisticFormatKHR; +typedef struct VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 pipelineExecutableInfo; +} VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR; + +typedef struct VkPipelineInfoKHR { + VkStructureType sType; + const void* pNext; + VkPipeline pipeline; +} VkPipelineInfoKHR; + +typedef struct VkPipelineExecutablePropertiesKHR { + VkStructureType sType; + void* pNext; + VkShaderStageFlags stages; + char name[VK_MAX_DESCRIPTION_SIZE]; + char description[VK_MAX_DESCRIPTION_SIZE]; + uint32_t subgroupSize; +} VkPipelineExecutablePropertiesKHR; + +typedef struct VkPipelineExecutableInfoKHR { + VkStructureType sType; + const void* pNext; + VkPipeline pipeline; + uint32_t executableIndex; +} VkPipelineExecutableInfoKHR; + +typedef union VkPipelineExecutableStatisticValueKHR { + VkBool32 b32; + int64_t i64; + uint64_t u64; + double f64; +} VkPipelineExecutableStatisticValueKHR; + +typedef struct VkPipelineExecutableStatisticKHR { + VkStructureType sType; + void* pNext; + char name[VK_MAX_DESCRIPTION_SIZE]; + char description[VK_MAX_DESCRIPTION_SIZE]; + VkPipelineExecutableStatisticFormatKHR format; + VkPipelineExecutableStatisticValueKHR value; +} VkPipelineExecutableStatisticKHR; + +typedef struct VkPipelineExecutableInternalRepresentationKHR { + VkStructureType sType; + void* pNext; + char name[VK_MAX_DESCRIPTION_SIZE]; + char description[VK_MAX_DESCRIPTION_SIZE]; + VkBool32 isText; + size_t dataSize; + void* pData; +} VkPipelineExecutableInternalRepresentationKHR; + +typedef VkResult (VKAPI_PTR *PFN_vkGetPipelineExecutablePropertiesKHR)(VkDevice device, const VkPipelineInfoKHR* pPipelineInfo, uint32_t* pExecutableCount, VkPipelineExecutablePropertiesKHR* pProperties); +typedef VkResult (VKAPI_PTR *PFN_vkGetPipelineExecutableStatisticsKHR)(VkDevice device, const VkPipelineExecutableInfoKHR* pExecutableInfo, uint32_t* pStatisticCount, VkPipelineExecutableStatisticKHR* pStatistics); +typedef VkResult (VKAPI_PTR *PFN_vkGetPipelineExecutableInternalRepresentationsKHR)(VkDevice device, const VkPipelineExecutableInfoKHR* pExecutableInfo, uint32_t* pInternalRepresentationCount, VkPipelineExecutableInternalRepresentationKHR* pInternalRepresentations); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelineExecutablePropertiesKHR( + VkDevice device, + const VkPipelineInfoKHR* pPipelineInfo, + uint32_t* pExecutableCount, + VkPipelineExecutablePropertiesKHR* pProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelineExecutableStatisticsKHR( + VkDevice device, + const VkPipelineExecutableInfoKHR* pExecutableInfo, + uint32_t* pStatisticCount, + VkPipelineExecutableStatisticKHR* pStatistics); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelineExecutableInternalRepresentationsKHR( + VkDevice device, + const VkPipelineExecutableInfoKHR* pExecutableInfo, + uint32_t* pInternalRepresentationCount, + VkPipelineExecutableInternalRepresentationKHR* pInternalRepresentations); +#endif + + +// VK_KHR_map_memory2 is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_map_memory2 1 +#define VK_KHR_MAP_MEMORY_2_SPEC_VERSION 1 +#define VK_KHR_MAP_MEMORY_2_EXTENSION_NAME "VK_KHR_map_memory2" +typedef VkFlags VkMemoryUnmapFlagsKHR; +typedef struct VkMemoryMapInfoKHR { + VkStructureType sType; + const void* pNext; + VkMemoryMapFlags flags; + VkDeviceMemory memory; + VkDeviceSize offset; + VkDeviceSize size; +} VkMemoryMapInfoKHR; + +typedef struct VkMemoryUnmapInfoKHR { + VkStructureType sType; + const void* pNext; + VkMemoryUnmapFlagsKHR flags; + VkDeviceMemory memory; +} VkMemoryUnmapInfoKHR; + +typedef VkResult (VKAPI_PTR *PFN_vkMapMemory2KHR)(VkDevice device, const VkMemoryMapInfoKHR* pMemoryMapInfo, void** ppData); +typedef VkResult (VKAPI_PTR *PFN_vkUnmapMemory2KHR)(VkDevice device, const VkMemoryUnmapInfoKHR* pMemoryUnmapInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkMapMemory2KHR( + VkDevice device, + const VkMemoryMapInfoKHR* pMemoryMapInfo, + void** ppData); + +VKAPI_ATTR VkResult VKAPI_CALL vkUnmapMemory2KHR( + VkDevice device, + const VkMemoryUnmapInfoKHR* pMemoryUnmapInfo); +#endif + + +// VK_KHR_shader_integer_dot_product is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_shader_integer_dot_product 1 +#define VK_KHR_SHADER_INTEGER_DOT_PRODUCT_SPEC_VERSION 1 +#define VK_KHR_SHADER_INTEGER_DOT_PRODUCT_EXTENSION_NAME "VK_KHR_shader_integer_dot_product" +typedef VkPhysicalDeviceShaderIntegerDotProductFeatures VkPhysicalDeviceShaderIntegerDotProductFeaturesKHR; + +typedef VkPhysicalDeviceShaderIntegerDotProductProperties VkPhysicalDeviceShaderIntegerDotProductPropertiesKHR; + + + +// VK_KHR_pipeline_library is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_pipeline_library 1 +#define VK_KHR_PIPELINE_LIBRARY_SPEC_VERSION 1 +#define VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME "VK_KHR_pipeline_library" +typedef struct VkPipelineLibraryCreateInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t libraryCount; + const VkPipeline* pLibraries; +} VkPipelineLibraryCreateInfoKHR; + + + +// VK_KHR_shader_non_semantic_info is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_shader_non_semantic_info 1 +#define VK_KHR_SHADER_NON_SEMANTIC_INFO_SPEC_VERSION 1 +#define VK_KHR_SHADER_NON_SEMANTIC_INFO_EXTENSION_NAME "VK_KHR_shader_non_semantic_info" + + +// VK_KHR_present_id is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_present_id 1 +#define VK_KHR_PRESENT_ID_SPEC_VERSION 1 +#define VK_KHR_PRESENT_ID_EXTENSION_NAME "VK_KHR_present_id" +typedef struct VkPresentIdKHR { + VkStructureType sType; + const void* pNext; + uint32_t swapchainCount; + const uint64_t* pPresentIds; +} VkPresentIdKHR; + +typedef struct VkPhysicalDevicePresentIdFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 presentId; +} VkPhysicalDevicePresentIdFeaturesKHR; + + + +// VK_KHR_video_encode_queue is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_video_encode_queue 1 +#define VK_KHR_VIDEO_ENCODE_QUEUE_SPEC_VERSION 12 +#define VK_KHR_VIDEO_ENCODE_QUEUE_EXTENSION_NAME "VK_KHR_video_encode_queue" + +typedef enum VkVideoEncodeTuningModeKHR { + VK_VIDEO_ENCODE_TUNING_MODE_DEFAULT_KHR = 0, + VK_VIDEO_ENCODE_TUNING_MODE_HIGH_QUALITY_KHR = 1, + VK_VIDEO_ENCODE_TUNING_MODE_LOW_LATENCY_KHR = 2, + VK_VIDEO_ENCODE_TUNING_MODE_ULTRA_LOW_LATENCY_KHR = 3, + VK_VIDEO_ENCODE_TUNING_MODE_LOSSLESS_KHR = 4, + VK_VIDEO_ENCODE_TUNING_MODE_MAX_ENUM_KHR = 0x7FFFFFFF +} VkVideoEncodeTuningModeKHR; +typedef VkFlags VkVideoEncodeFlagsKHR; + +typedef enum VkVideoEncodeCapabilityFlagBitsKHR { + VK_VIDEO_ENCODE_CAPABILITY_PRECEDING_EXTERNALLY_ENCODED_BYTES_BIT_KHR = 0x00000001, + VK_VIDEO_ENCODE_CAPABILITY_INSUFFICIENT_BITSTREAM_BUFFER_RANGE_DETECTION_BIT_KHR = 0x00000002, + VK_VIDEO_ENCODE_CAPABILITY_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkVideoEncodeCapabilityFlagBitsKHR; +typedef VkFlags VkVideoEncodeCapabilityFlagsKHR; + +typedef enum VkVideoEncodeRateControlModeFlagBitsKHR { + VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DEFAULT_KHR = 0, + VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR = 0x00000001, + VK_VIDEO_ENCODE_RATE_CONTROL_MODE_CBR_BIT_KHR = 0x00000002, + VK_VIDEO_ENCODE_RATE_CONTROL_MODE_VBR_BIT_KHR = 0x00000004, + VK_VIDEO_ENCODE_RATE_CONTROL_MODE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkVideoEncodeRateControlModeFlagBitsKHR; +typedef VkFlags VkVideoEncodeRateControlModeFlagsKHR; + +typedef enum VkVideoEncodeFeedbackFlagBitsKHR { + VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BUFFER_OFFSET_BIT_KHR = 0x00000001, + VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_BYTES_WRITTEN_BIT_KHR = 0x00000002, + VK_VIDEO_ENCODE_FEEDBACK_BITSTREAM_HAS_OVERRIDES_BIT_KHR = 0x00000004, + VK_VIDEO_ENCODE_FEEDBACK_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkVideoEncodeFeedbackFlagBitsKHR; +typedef VkFlags VkVideoEncodeFeedbackFlagsKHR; + +typedef enum VkVideoEncodeUsageFlagBitsKHR { + VK_VIDEO_ENCODE_USAGE_DEFAULT_KHR = 0, + VK_VIDEO_ENCODE_USAGE_TRANSCODING_BIT_KHR = 0x00000001, + VK_VIDEO_ENCODE_USAGE_STREAMING_BIT_KHR = 0x00000002, + VK_VIDEO_ENCODE_USAGE_RECORDING_BIT_KHR = 0x00000004, + VK_VIDEO_ENCODE_USAGE_CONFERENCING_BIT_KHR = 0x00000008, + VK_VIDEO_ENCODE_USAGE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkVideoEncodeUsageFlagBitsKHR; +typedef VkFlags VkVideoEncodeUsageFlagsKHR; + +typedef enum VkVideoEncodeContentFlagBitsKHR { + VK_VIDEO_ENCODE_CONTENT_DEFAULT_KHR = 0, + VK_VIDEO_ENCODE_CONTENT_CAMERA_BIT_KHR = 0x00000001, + VK_VIDEO_ENCODE_CONTENT_DESKTOP_BIT_KHR = 0x00000002, + VK_VIDEO_ENCODE_CONTENT_RENDERED_BIT_KHR = 0x00000004, + VK_VIDEO_ENCODE_CONTENT_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkVideoEncodeContentFlagBitsKHR; +typedef VkFlags VkVideoEncodeContentFlagsKHR; +typedef VkFlags VkVideoEncodeRateControlFlagsKHR; +typedef struct VkVideoEncodeInfoKHR { + VkStructureType sType; + const void* pNext; + VkVideoEncodeFlagsKHR flags; + VkBuffer dstBuffer; + VkDeviceSize dstBufferOffset; + VkDeviceSize dstBufferRange; + VkVideoPictureResourceInfoKHR srcPictureResource; + const VkVideoReferenceSlotInfoKHR* pSetupReferenceSlot; + uint32_t referenceSlotCount; + const VkVideoReferenceSlotInfoKHR* pReferenceSlots; + uint32_t precedingExternallyEncodedBytes; +} VkVideoEncodeInfoKHR; + +typedef struct VkVideoEncodeCapabilitiesKHR { + VkStructureType sType; + void* pNext; + VkVideoEncodeCapabilityFlagsKHR flags; + VkVideoEncodeRateControlModeFlagsKHR rateControlModes; + uint32_t maxRateControlLayers; + uint64_t maxBitrate; + uint32_t maxQualityLevels; + VkExtent2D encodeInputPictureGranularity; + VkVideoEncodeFeedbackFlagsKHR supportedEncodeFeedbackFlags; +} VkVideoEncodeCapabilitiesKHR; + +typedef struct VkQueryPoolVideoEncodeFeedbackCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkVideoEncodeFeedbackFlagsKHR encodeFeedbackFlags; +} VkQueryPoolVideoEncodeFeedbackCreateInfoKHR; + +typedef struct VkVideoEncodeUsageInfoKHR { + VkStructureType sType; + const void* pNext; + VkVideoEncodeUsageFlagsKHR videoUsageHints; + VkVideoEncodeContentFlagsKHR videoContentHints; + VkVideoEncodeTuningModeKHR tuningMode; +} VkVideoEncodeUsageInfoKHR; + +typedef struct VkVideoEncodeRateControlLayerInfoKHR { + VkStructureType sType; + const void* pNext; + uint64_t averageBitrate; + uint64_t maxBitrate; + uint32_t frameRateNumerator; + uint32_t frameRateDenominator; +} VkVideoEncodeRateControlLayerInfoKHR; + +typedef struct VkVideoEncodeRateControlInfoKHR { + VkStructureType sType; + const void* pNext; + VkVideoEncodeRateControlFlagsKHR flags; + VkVideoEncodeRateControlModeFlagBitsKHR rateControlMode; + uint32_t layerCount; + const VkVideoEncodeRateControlLayerInfoKHR* pLayers; + uint32_t virtualBufferSizeInMs; + uint32_t initialVirtualBufferSizeInMs; +} VkVideoEncodeRateControlInfoKHR; + +typedef struct VkPhysicalDeviceVideoEncodeQualityLevelInfoKHR { + VkStructureType sType; + const void* pNext; + const VkVideoProfileInfoKHR* pVideoProfile; + uint32_t qualityLevel; +} VkPhysicalDeviceVideoEncodeQualityLevelInfoKHR; + +typedef struct VkVideoEncodeQualityLevelPropertiesKHR { + VkStructureType sType; + void* pNext; + VkVideoEncodeRateControlModeFlagBitsKHR preferredRateControlMode; + uint32_t preferredRateControlLayerCount; +} VkVideoEncodeQualityLevelPropertiesKHR; + +typedef struct VkVideoEncodeQualityLevelInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t qualityLevel; +} VkVideoEncodeQualityLevelInfoKHR; + +typedef struct VkVideoEncodeSessionParametersGetInfoKHR { + VkStructureType sType; + const void* pNext; + VkVideoSessionParametersKHR videoSessionParameters; +} VkVideoEncodeSessionParametersGetInfoKHR; + +typedef struct VkVideoEncodeSessionParametersFeedbackInfoKHR { + VkStructureType sType; + void* pNext; + VkBool32 hasOverrides; +} VkVideoEncodeSessionParametersFeedbackInfoKHR; + +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceVideoEncodeQualityLevelPropertiesKHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceVideoEncodeQualityLevelInfoKHR* pQualityLevelInfo, VkVideoEncodeQualityLevelPropertiesKHR* pQualityLevelProperties); +typedef VkResult (VKAPI_PTR *PFN_vkGetEncodedVideoSessionParametersKHR)(VkDevice device, const VkVideoEncodeSessionParametersGetInfoKHR* pVideoSessionParametersInfo, VkVideoEncodeSessionParametersFeedbackInfoKHR* pFeedbackInfo, size_t* pDataSize, void* pData); +typedef void (VKAPI_PTR *PFN_vkCmdEncodeVideoKHR)(VkCommandBuffer commandBuffer, const VkVideoEncodeInfoKHR* pEncodeInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceVideoEncodeQualityLevelPropertiesKHR( + VkPhysicalDevice physicalDevice, + const VkPhysicalDeviceVideoEncodeQualityLevelInfoKHR* pQualityLevelInfo, + VkVideoEncodeQualityLevelPropertiesKHR* pQualityLevelProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetEncodedVideoSessionParametersKHR( + VkDevice device, + const VkVideoEncodeSessionParametersGetInfoKHR* pVideoSessionParametersInfo, + VkVideoEncodeSessionParametersFeedbackInfoKHR* pFeedbackInfo, + size_t* pDataSize, + void* pData); + +VKAPI_ATTR void VKAPI_CALL vkCmdEncodeVideoKHR( + VkCommandBuffer commandBuffer, + const VkVideoEncodeInfoKHR* pEncodeInfo); +#endif + + +// VK_KHR_synchronization2 is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_synchronization2 1 +#define VK_KHR_SYNCHRONIZATION_2_SPEC_VERSION 1 +#define VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME "VK_KHR_synchronization2" +typedef VkPipelineStageFlags2 VkPipelineStageFlags2KHR; + +typedef VkPipelineStageFlagBits2 VkPipelineStageFlagBits2KHR; + +typedef VkAccessFlags2 VkAccessFlags2KHR; + +typedef VkAccessFlagBits2 VkAccessFlagBits2KHR; + +typedef VkSubmitFlagBits VkSubmitFlagBitsKHR; + +typedef VkSubmitFlags VkSubmitFlagsKHR; + +typedef VkMemoryBarrier2 VkMemoryBarrier2KHR; + +typedef VkBufferMemoryBarrier2 VkBufferMemoryBarrier2KHR; + +typedef VkImageMemoryBarrier2 VkImageMemoryBarrier2KHR; + +typedef VkDependencyInfo VkDependencyInfoKHR; + +typedef VkSubmitInfo2 VkSubmitInfo2KHR; + +typedef VkSemaphoreSubmitInfo VkSemaphoreSubmitInfoKHR; + +typedef VkCommandBufferSubmitInfo VkCommandBufferSubmitInfoKHR; + +typedef VkPhysicalDeviceSynchronization2Features VkPhysicalDeviceSynchronization2FeaturesKHR; + +typedef struct VkQueueFamilyCheckpointProperties2NV { + VkStructureType sType; + void* pNext; + VkPipelineStageFlags2 checkpointExecutionStageMask; +} VkQueueFamilyCheckpointProperties2NV; + +typedef struct VkCheckpointData2NV { + VkStructureType sType; + void* pNext; + VkPipelineStageFlags2 stage; + void* pCheckpointMarker; +} VkCheckpointData2NV; + +typedef void (VKAPI_PTR *PFN_vkCmdSetEvent2KHR)(VkCommandBuffer commandBuffer, VkEvent event, const VkDependencyInfo* pDependencyInfo); +typedef void (VKAPI_PTR *PFN_vkCmdResetEvent2KHR)(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags2 stageMask); +typedef void (VKAPI_PTR *PFN_vkCmdWaitEvents2KHR)(VkCommandBuffer commandBuffer, uint32_t eventCount, const VkEvent* pEvents, const VkDependencyInfo* pDependencyInfos); +typedef void (VKAPI_PTR *PFN_vkCmdPipelineBarrier2KHR)(VkCommandBuffer commandBuffer, const VkDependencyInfo* pDependencyInfo); +typedef void (VKAPI_PTR *PFN_vkCmdWriteTimestamp2KHR)(VkCommandBuffer commandBuffer, VkPipelineStageFlags2 stage, VkQueryPool queryPool, uint32_t query); +typedef VkResult (VKAPI_PTR *PFN_vkQueueSubmit2KHR)(VkQueue queue, uint32_t submitCount, const VkSubmitInfo2* pSubmits, VkFence fence); +typedef void (VKAPI_PTR *PFN_vkCmdWriteBufferMarker2AMD)(VkCommandBuffer commandBuffer, VkPipelineStageFlags2 stage, VkBuffer dstBuffer, VkDeviceSize dstOffset, uint32_t marker); +typedef void (VKAPI_PTR *PFN_vkGetQueueCheckpointData2NV)(VkQueue queue, uint32_t* pCheckpointDataCount, VkCheckpointData2NV* pCheckpointData); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdSetEvent2KHR( + VkCommandBuffer commandBuffer, + VkEvent event, + const VkDependencyInfo* pDependencyInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdResetEvent2KHR( + VkCommandBuffer commandBuffer, + VkEvent event, + VkPipelineStageFlags2 stageMask); + +VKAPI_ATTR void VKAPI_CALL vkCmdWaitEvents2KHR( + VkCommandBuffer commandBuffer, + uint32_t eventCount, + const VkEvent* pEvents, + const VkDependencyInfo* pDependencyInfos); + +VKAPI_ATTR void VKAPI_CALL vkCmdPipelineBarrier2KHR( + VkCommandBuffer commandBuffer, + const VkDependencyInfo* pDependencyInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdWriteTimestamp2KHR( + VkCommandBuffer commandBuffer, + VkPipelineStageFlags2 stage, + VkQueryPool queryPool, + uint32_t query); + +VKAPI_ATTR VkResult VKAPI_CALL vkQueueSubmit2KHR( + VkQueue queue, + uint32_t submitCount, + const VkSubmitInfo2* pSubmits, + VkFence fence); + +VKAPI_ATTR void VKAPI_CALL vkCmdWriteBufferMarker2AMD( + VkCommandBuffer commandBuffer, + VkPipelineStageFlags2 stage, + VkBuffer dstBuffer, + VkDeviceSize dstOffset, + uint32_t marker); + +VKAPI_ATTR void VKAPI_CALL vkGetQueueCheckpointData2NV( + VkQueue queue, + uint32_t* pCheckpointDataCount, + VkCheckpointData2NV* pCheckpointData); +#endif + + +// VK_KHR_fragment_shader_barycentric is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_fragment_shader_barycentric 1 +#define VK_KHR_FRAGMENT_SHADER_BARYCENTRIC_SPEC_VERSION 1 +#define VK_KHR_FRAGMENT_SHADER_BARYCENTRIC_EXTENSION_NAME "VK_KHR_fragment_shader_barycentric" +typedef struct VkPhysicalDeviceFragmentShaderBarycentricFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 fragmentShaderBarycentric; +} VkPhysicalDeviceFragmentShaderBarycentricFeaturesKHR; + +typedef struct VkPhysicalDeviceFragmentShaderBarycentricPropertiesKHR { + VkStructureType sType; + void* pNext; + VkBool32 triStripVertexOrderIndependentOfProvokingVertex; +} VkPhysicalDeviceFragmentShaderBarycentricPropertiesKHR; + + + +// VK_KHR_shader_subgroup_uniform_control_flow is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_shader_subgroup_uniform_control_flow 1 +#define VK_KHR_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_SPEC_VERSION 1 +#define VK_KHR_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_EXTENSION_NAME "VK_KHR_shader_subgroup_uniform_control_flow" +typedef struct VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 shaderSubgroupUniformControlFlow; +} VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR; + + + +// VK_KHR_zero_initialize_workgroup_memory is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_zero_initialize_workgroup_memory 1 +#define VK_KHR_ZERO_INITIALIZE_WORKGROUP_MEMORY_SPEC_VERSION 1 +#define VK_KHR_ZERO_INITIALIZE_WORKGROUP_MEMORY_EXTENSION_NAME "VK_KHR_zero_initialize_workgroup_memory" +typedef VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeatures VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeaturesKHR; + + + +// VK_KHR_workgroup_memory_explicit_layout is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_workgroup_memory_explicit_layout 1 +#define VK_KHR_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_SPEC_VERSION 1 +#define VK_KHR_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_EXTENSION_NAME "VK_KHR_workgroup_memory_explicit_layout" +typedef struct VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 workgroupMemoryExplicitLayout; + VkBool32 workgroupMemoryExplicitLayoutScalarBlockLayout; + VkBool32 workgroupMemoryExplicitLayout8BitAccess; + VkBool32 workgroupMemoryExplicitLayout16BitAccess; +} VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR; + + + +// VK_KHR_copy_commands2 is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_copy_commands2 1 +#define VK_KHR_COPY_COMMANDS_2_SPEC_VERSION 1 +#define VK_KHR_COPY_COMMANDS_2_EXTENSION_NAME "VK_KHR_copy_commands2" +typedef VkCopyBufferInfo2 VkCopyBufferInfo2KHR; + +typedef VkCopyImageInfo2 VkCopyImageInfo2KHR; + +typedef VkCopyBufferToImageInfo2 VkCopyBufferToImageInfo2KHR; + +typedef VkCopyImageToBufferInfo2 VkCopyImageToBufferInfo2KHR; + +typedef VkBlitImageInfo2 VkBlitImageInfo2KHR; + +typedef VkResolveImageInfo2 VkResolveImageInfo2KHR; + +typedef VkBufferCopy2 VkBufferCopy2KHR; + +typedef VkImageCopy2 VkImageCopy2KHR; + +typedef VkImageBlit2 VkImageBlit2KHR; + +typedef VkBufferImageCopy2 VkBufferImageCopy2KHR; + +typedef VkImageResolve2 VkImageResolve2KHR; + +typedef void (VKAPI_PTR *PFN_vkCmdCopyBuffer2KHR)(VkCommandBuffer commandBuffer, const VkCopyBufferInfo2* pCopyBufferInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyImage2KHR)(VkCommandBuffer commandBuffer, const VkCopyImageInfo2* pCopyImageInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyBufferToImage2KHR)(VkCommandBuffer commandBuffer, const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyImageToBuffer2KHR)(VkCommandBuffer commandBuffer, const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo); +typedef void (VKAPI_PTR *PFN_vkCmdBlitImage2KHR)(VkCommandBuffer commandBuffer, const VkBlitImageInfo2* pBlitImageInfo); +typedef void (VKAPI_PTR *PFN_vkCmdResolveImage2KHR)(VkCommandBuffer commandBuffer, const VkResolveImageInfo2* pResolveImageInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdCopyBuffer2KHR( + VkCommandBuffer commandBuffer, + const VkCopyBufferInfo2* pCopyBufferInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyImage2KHR( + VkCommandBuffer commandBuffer, + const VkCopyImageInfo2* pCopyImageInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyBufferToImage2KHR( + VkCommandBuffer commandBuffer, + const VkCopyBufferToImageInfo2* pCopyBufferToImageInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyImageToBuffer2KHR( + VkCommandBuffer commandBuffer, + const VkCopyImageToBufferInfo2* pCopyImageToBufferInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdBlitImage2KHR( + VkCommandBuffer commandBuffer, + const VkBlitImageInfo2* pBlitImageInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdResolveImage2KHR( + VkCommandBuffer commandBuffer, + const VkResolveImageInfo2* pResolveImageInfo); +#endif + + +// VK_KHR_format_feature_flags2 is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_format_feature_flags2 1 +#define VK_KHR_FORMAT_FEATURE_FLAGS_2_SPEC_VERSION 2 +#define VK_KHR_FORMAT_FEATURE_FLAGS_2_EXTENSION_NAME "VK_KHR_format_feature_flags2" +typedef VkFormatFeatureFlags2 VkFormatFeatureFlags2KHR; + +typedef VkFormatFeatureFlagBits2 VkFormatFeatureFlagBits2KHR; + +typedef VkFormatProperties3 VkFormatProperties3KHR; + + + +// VK_KHR_ray_tracing_maintenance1 is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_ray_tracing_maintenance1 1 +#define VK_KHR_RAY_TRACING_MAINTENANCE_1_SPEC_VERSION 1 +#define VK_KHR_RAY_TRACING_MAINTENANCE_1_EXTENSION_NAME "VK_KHR_ray_tracing_maintenance1" +typedef struct VkPhysicalDeviceRayTracingMaintenance1FeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 rayTracingMaintenance1; + VkBool32 rayTracingPipelineTraceRaysIndirect2; +} VkPhysicalDeviceRayTracingMaintenance1FeaturesKHR; + +typedef struct VkTraceRaysIndirectCommand2KHR { + VkDeviceAddress raygenShaderRecordAddress; + VkDeviceSize raygenShaderRecordSize; + VkDeviceAddress missShaderBindingTableAddress; + VkDeviceSize missShaderBindingTableSize; + VkDeviceSize missShaderBindingTableStride; + VkDeviceAddress hitShaderBindingTableAddress; + VkDeviceSize hitShaderBindingTableSize; + VkDeviceSize hitShaderBindingTableStride; + VkDeviceAddress callableShaderBindingTableAddress; + VkDeviceSize callableShaderBindingTableSize; + VkDeviceSize callableShaderBindingTableStride; + uint32_t width; + uint32_t height; + uint32_t depth; +} VkTraceRaysIndirectCommand2KHR; + +typedef void (VKAPI_PTR *PFN_vkCmdTraceRaysIndirect2KHR)(VkCommandBuffer commandBuffer, VkDeviceAddress indirectDeviceAddress); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdTraceRaysIndirect2KHR( + VkCommandBuffer commandBuffer, + VkDeviceAddress indirectDeviceAddress); +#endif + + +// VK_KHR_portability_enumeration is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_portability_enumeration 1 +#define VK_KHR_PORTABILITY_ENUMERATION_SPEC_VERSION 1 +#define VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME "VK_KHR_portability_enumeration" + + +// VK_KHR_maintenance4 is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_maintenance4 1 +#define VK_KHR_MAINTENANCE_4_SPEC_VERSION 2 +#define VK_KHR_MAINTENANCE_4_EXTENSION_NAME "VK_KHR_maintenance4" +typedef VkPhysicalDeviceMaintenance4Features VkPhysicalDeviceMaintenance4FeaturesKHR; + +typedef VkPhysicalDeviceMaintenance4Properties VkPhysicalDeviceMaintenance4PropertiesKHR; + +typedef VkDeviceBufferMemoryRequirements VkDeviceBufferMemoryRequirementsKHR; + +typedef VkDeviceImageMemoryRequirements VkDeviceImageMemoryRequirementsKHR; + +typedef void (VKAPI_PTR *PFN_vkGetDeviceBufferMemoryRequirementsKHR)(VkDevice device, const VkDeviceBufferMemoryRequirements* pInfo, VkMemoryRequirements2* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetDeviceImageMemoryRequirementsKHR)(VkDevice device, const VkDeviceImageMemoryRequirements* pInfo, VkMemoryRequirements2* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkGetDeviceImageSparseMemoryRequirementsKHR)(VkDevice device, const VkDeviceImageMemoryRequirements* pInfo, uint32_t* pSparseMemoryRequirementCount, VkSparseImageMemoryRequirements2* pSparseMemoryRequirements); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkGetDeviceBufferMemoryRequirementsKHR( + VkDevice device, + const VkDeviceBufferMemoryRequirements* pInfo, + VkMemoryRequirements2* pMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkGetDeviceImageMemoryRequirementsKHR( + VkDevice device, + const VkDeviceImageMemoryRequirements* pInfo, + VkMemoryRequirements2* pMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkGetDeviceImageSparseMemoryRequirementsKHR( + VkDevice device, + const VkDeviceImageMemoryRequirements* pInfo, + uint32_t* pSparseMemoryRequirementCount, + VkSparseImageMemoryRequirements2* pSparseMemoryRequirements); +#endif + + +// VK_KHR_maintenance5 is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_maintenance5 1 +#define VK_KHR_MAINTENANCE_5_SPEC_VERSION 1 +#define VK_KHR_MAINTENANCE_5_EXTENSION_NAME "VK_KHR_maintenance5" +typedef VkFlags64 VkPipelineCreateFlags2KHR; + +// Flag bits for VkPipelineCreateFlagBits2KHR +typedef VkFlags64 VkPipelineCreateFlagBits2KHR; +static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_DISABLE_OPTIMIZATION_BIT_KHR = 0x00000001ULL; +static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_ALLOW_DERIVATIVES_BIT_KHR = 0x00000002ULL; +static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_DERIVATIVE_BIT_KHR = 0x00000004ULL; +static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_VIEW_INDEX_FROM_DEVICE_INDEX_BIT_KHR = 0x00000008ULL; +static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_DISPATCH_BASE_BIT_KHR = 0x00000010ULL; +static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_DEFER_COMPILE_BIT_NV = 0x00000020ULL; +static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_CAPTURE_STATISTICS_BIT_KHR = 0x00000040ULL; +static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR = 0x00000080ULL; +static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_KHR = 0x00000100ULL; +static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_EARLY_RETURN_ON_FAILURE_BIT_KHR = 0x00000200ULL; +static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_LINK_TIME_OPTIMIZATION_BIT_EXT = 0x00000400ULL; +static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT = 0x00800000ULL; +static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_LIBRARY_BIT_KHR = 0x00000800ULL; +static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_RAY_TRACING_SKIP_TRIANGLES_BIT_KHR = 0x00001000ULL; +static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_RAY_TRACING_SKIP_AABBS_BIT_KHR = 0x00002000ULL; +static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_RAY_TRACING_NO_NULL_ANY_HIT_SHADERS_BIT_KHR = 0x00004000ULL; +static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_RAY_TRACING_NO_NULL_CLOSEST_HIT_SHADERS_BIT_KHR = 0x00008000ULL; +static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_RAY_TRACING_NO_NULL_MISS_SHADERS_BIT_KHR = 0x00010000ULL; +static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_RAY_TRACING_NO_NULL_INTERSECTION_SHADERS_BIT_KHR = 0x00020000ULL; +static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_RAY_TRACING_SHADER_GROUP_HANDLE_CAPTURE_REPLAY_BIT_KHR = 0x00080000ULL; +static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_INDIRECT_BINDABLE_BIT_NV = 0x00040000ULL; +static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_RAY_TRACING_ALLOW_MOTION_BIT_NV = 0x00100000ULL; +static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR = 0x00200000ULL; +static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT = 0x00400000ULL; +static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_RAY_TRACING_OPACITY_MICROMAP_BIT_EXT = 0x01000000ULL; +static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT = 0x02000000ULL; +static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT = 0x04000000ULL; +static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_NO_PROTECTED_ACCESS_BIT_EXT = 0x08000000ULL; +static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_PROTECTED_ACCESS_ONLY_BIT_EXT = 0x40000000ULL; +static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_RAY_TRACING_DISPLACEMENT_MICROMAP_BIT_NV = 0x10000000ULL; +static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_DESCRIPTOR_BUFFER_BIT_EXT = 0x20000000ULL; + +typedef VkFlags64 VkBufferUsageFlags2KHR; + +// Flag bits for VkBufferUsageFlagBits2KHR +typedef VkFlags64 VkBufferUsageFlagBits2KHR; +static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_TRANSFER_SRC_BIT_KHR = 0x00000001ULL; +static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_TRANSFER_DST_BIT_KHR = 0x00000002ULL; +static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_UNIFORM_TEXEL_BUFFER_BIT_KHR = 0x00000004ULL; +static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_STORAGE_TEXEL_BUFFER_BIT_KHR = 0x00000008ULL; +static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_UNIFORM_BUFFER_BIT_KHR = 0x00000010ULL; +static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_STORAGE_BUFFER_BIT_KHR = 0x00000020ULL; +static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_INDEX_BUFFER_BIT_KHR = 0x00000040ULL; +static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_VERTEX_BUFFER_BIT_KHR = 0x00000080ULL; +static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_INDIRECT_BUFFER_BIT_KHR = 0x00000100ULL; +static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_EXECUTION_GRAPH_SCRATCH_BIT_AMDX = 0x02000000ULL; +static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_CONDITIONAL_RENDERING_BIT_EXT = 0x00000200ULL; +static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_SHADER_BINDING_TABLE_BIT_KHR = 0x00000400ULL; +static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_RAY_TRACING_BIT_NV = 0x00000400ULL; +static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT = 0x00000800ULL; +static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT = 0x00001000ULL; +static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_VIDEO_DECODE_SRC_BIT_KHR = 0x00002000ULL; +static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_VIDEO_DECODE_DST_BIT_KHR = 0x00004000ULL; +#ifdef VK_ENABLE_BETA_EXTENSIONS +static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_VIDEO_ENCODE_DST_BIT_KHR = 0x00008000ULL; +#endif +#ifdef VK_ENABLE_BETA_EXTENSIONS +static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_VIDEO_ENCODE_SRC_BIT_KHR = 0x00010000ULL; +#endif +static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT_KHR = 0x00020000ULL; +static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR = 0x00080000ULL; +static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR = 0x00100000ULL; +static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_SAMPLER_DESCRIPTOR_BUFFER_BIT_EXT = 0x00200000ULL; +static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_RESOURCE_DESCRIPTOR_BUFFER_BIT_EXT = 0x00400000ULL; +static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_PUSH_DESCRIPTORS_DESCRIPTOR_BUFFER_BIT_EXT = 0x04000000ULL; +static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_MICROMAP_BUILD_INPUT_READ_ONLY_BIT_EXT = 0x00800000ULL; +static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_MICROMAP_STORAGE_BIT_EXT = 0x01000000ULL; + +typedef struct VkPhysicalDeviceMaintenance5FeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 maintenance5; +} VkPhysicalDeviceMaintenance5FeaturesKHR; + +typedef struct VkPhysicalDeviceMaintenance5PropertiesKHR { + VkStructureType sType; + void* pNext; + VkBool32 earlyFragmentMultisampleCoverageAfterSampleCounting; + VkBool32 earlyFragmentSampleMaskTestBeforeSampleCounting; + VkBool32 depthStencilSwizzleOneSupport; + VkBool32 polygonModePointSize; + VkBool32 nonStrictSinglePixelWideLinesUseParallelogram; + VkBool32 nonStrictWideLinesUseParallelogram; +} VkPhysicalDeviceMaintenance5PropertiesKHR; + +typedef struct VkRenderingAreaInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t viewMask; + uint32_t colorAttachmentCount; + const VkFormat* pColorAttachmentFormats; + VkFormat depthAttachmentFormat; + VkFormat stencilAttachmentFormat; +} VkRenderingAreaInfoKHR; + +typedef struct VkImageSubresource2KHR { + VkStructureType sType; + void* pNext; + VkImageSubresource imageSubresource; +} VkImageSubresource2KHR; + +typedef struct VkDeviceImageSubresourceInfoKHR { + VkStructureType sType; + const void* pNext; + const VkImageCreateInfo* pCreateInfo; + const VkImageSubresource2KHR* pSubresource; +} VkDeviceImageSubresourceInfoKHR; + +typedef struct VkSubresourceLayout2KHR { + VkStructureType sType; + void* pNext; + VkSubresourceLayout subresourceLayout; +} VkSubresourceLayout2KHR; + +typedef struct VkPipelineCreateFlags2CreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkPipelineCreateFlags2KHR flags; +} VkPipelineCreateFlags2CreateInfoKHR; + +typedef struct VkBufferUsageFlags2CreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkBufferUsageFlags2KHR usage; +} VkBufferUsageFlags2CreateInfoKHR; + +typedef void (VKAPI_PTR *PFN_vkCmdBindIndexBuffer2KHR)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkDeviceSize size, VkIndexType indexType); +typedef void (VKAPI_PTR *PFN_vkGetRenderingAreaGranularityKHR)(VkDevice device, const VkRenderingAreaInfoKHR* pRenderingAreaInfo, VkExtent2D* pGranularity); +typedef void (VKAPI_PTR *PFN_vkGetDeviceImageSubresourceLayoutKHR)(VkDevice device, const VkDeviceImageSubresourceInfoKHR* pInfo, VkSubresourceLayout2KHR* pLayout); +typedef void (VKAPI_PTR *PFN_vkGetImageSubresourceLayout2KHR)(VkDevice device, VkImage image, const VkImageSubresource2KHR* pSubresource, VkSubresourceLayout2KHR* pLayout); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdBindIndexBuffer2KHR( + VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset, + VkDeviceSize size, + VkIndexType indexType); + +VKAPI_ATTR void VKAPI_CALL vkGetRenderingAreaGranularityKHR( + VkDevice device, + const VkRenderingAreaInfoKHR* pRenderingAreaInfo, + VkExtent2D* pGranularity); + +VKAPI_ATTR void VKAPI_CALL vkGetDeviceImageSubresourceLayoutKHR( + VkDevice device, + const VkDeviceImageSubresourceInfoKHR* pInfo, + VkSubresourceLayout2KHR* pLayout); + +VKAPI_ATTR void VKAPI_CALL vkGetImageSubresourceLayout2KHR( + VkDevice device, + VkImage image, + const VkImageSubresource2KHR* pSubresource, + VkSubresourceLayout2KHR* pLayout); +#endif + + +// VK_KHR_ray_tracing_position_fetch is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_ray_tracing_position_fetch 1 +#define VK_KHR_RAY_TRACING_POSITION_FETCH_SPEC_VERSION 1 +#define VK_KHR_RAY_TRACING_POSITION_FETCH_EXTENSION_NAME "VK_KHR_ray_tracing_position_fetch" +typedef struct VkPhysicalDeviceRayTracingPositionFetchFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 rayTracingPositionFetch; +} VkPhysicalDeviceRayTracingPositionFetchFeaturesKHR; + + + +// VK_KHR_cooperative_matrix is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_cooperative_matrix 1 +#define VK_KHR_COOPERATIVE_MATRIX_SPEC_VERSION 2 +#define VK_KHR_COOPERATIVE_MATRIX_EXTENSION_NAME "VK_KHR_cooperative_matrix" + +typedef enum VkComponentTypeKHR { + VK_COMPONENT_TYPE_FLOAT16_KHR = 0, + VK_COMPONENT_TYPE_FLOAT32_KHR = 1, + VK_COMPONENT_TYPE_FLOAT64_KHR = 2, + VK_COMPONENT_TYPE_SINT8_KHR = 3, + VK_COMPONENT_TYPE_SINT16_KHR = 4, + VK_COMPONENT_TYPE_SINT32_KHR = 5, + VK_COMPONENT_TYPE_SINT64_KHR = 6, + VK_COMPONENT_TYPE_UINT8_KHR = 7, + VK_COMPONENT_TYPE_UINT16_KHR = 8, + VK_COMPONENT_TYPE_UINT32_KHR = 9, + VK_COMPONENT_TYPE_UINT64_KHR = 10, + VK_COMPONENT_TYPE_FLOAT16_NV = VK_COMPONENT_TYPE_FLOAT16_KHR, + VK_COMPONENT_TYPE_FLOAT32_NV = VK_COMPONENT_TYPE_FLOAT32_KHR, + VK_COMPONENT_TYPE_FLOAT64_NV = VK_COMPONENT_TYPE_FLOAT64_KHR, + VK_COMPONENT_TYPE_SINT8_NV = VK_COMPONENT_TYPE_SINT8_KHR, + VK_COMPONENT_TYPE_SINT16_NV = VK_COMPONENT_TYPE_SINT16_KHR, + VK_COMPONENT_TYPE_SINT32_NV = VK_COMPONENT_TYPE_SINT32_KHR, + VK_COMPONENT_TYPE_SINT64_NV = VK_COMPONENT_TYPE_SINT64_KHR, + VK_COMPONENT_TYPE_UINT8_NV = VK_COMPONENT_TYPE_UINT8_KHR, + VK_COMPONENT_TYPE_UINT16_NV = VK_COMPONENT_TYPE_UINT16_KHR, + VK_COMPONENT_TYPE_UINT32_NV = VK_COMPONENT_TYPE_UINT32_KHR, + VK_COMPONENT_TYPE_UINT64_NV = VK_COMPONENT_TYPE_UINT64_KHR, + VK_COMPONENT_TYPE_MAX_ENUM_KHR = 0x7FFFFFFF +} VkComponentTypeKHR; + +typedef enum VkScopeKHR { + VK_SCOPE_DEVICE_KHR = 1, + VK_SCOPE_WORKGROUP_KHR = 2, + VK_SCOPE_SUBGROUP_KHR = 3, + VK_SCOPE_QUEUE_FAMILY_KHR = 5, + VK_SCOPE_DEVICE_NV = VK_SCOPE_DEVICE_KHR, + VK_SCOPE_WORKGROUP_NV = VK_SCOPE_WORKGROUP_KHR, + VK_SCOPE_SUBGROUP_NV = VK_SCOPE_SUBGROUP_KHR, + VK_SCOPE_QUEUE_FAMILY_NV = VK_SCOPE_QUEUE_FAMILY_KHR, + VK_SCOPE_MAX_ENUM_KHR = 0x7FFFFFFF +} VkScopeKHR; +typedef struct VkCooperativeMatrixPropertiesKHR { + VkStructureType sType; + void* pNext; + uint32_t MSize; + uint32_t NSize; + uint32_t KSize; + VkComponentTypeKHR AType; + VkComponentTypeKHR BType; + VkComponentTypeKHR CType; + VkComponentTypeKHR ResultType; + VkBool32 saturatingAccumulation; + VkScopeKHR scope; +} VkCooperativeMatrixPropertiesKHR; + +typedef struct VkPhysicalDeviceCooperativeMatrixFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 cooperativeMatrix; + VkBool32 cooperativeMatrixRobustBufferAccess; +} VkPhysicalDeviceCooperativeMatrixFeaturesKHR; + +typedef struct VkPhysicalDeviceCooperativeMatrixPropertiesKHR { + VkStructureType sType; + void* pNext; + VkShaderStageFlags cooperativeMatrixSupportedStages; +} VkPhysicalDeviceCooperativeMatrixPropertiesKHR; + +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceCooperativeMatrixPropertiesKHR)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkCooperativeMatrixPropertiesKHR* pProperties); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceCooperativeMatrixPropertiesKHR( + VkPhysicalDevice physicalDevice, + uint32_t* pPropertyCount, + VkCooperativeMatrixPropertiesKHR* pProperties); +#endif + + +// VK_KHR_video_maintenance1 is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_video_maintenance1 1 +#define VK_KHR_VIDEO_MAINTENANCE_1_SPEC_VERSION 1 +#define VK_KHR_VIDEO_MAINTENANCE_1_EXTENSION_NAME "VK_KHR_video_maintenance1" +typedef struct VkPhysicalDeviceVideoMaintenance1FeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 videoMaintenance1; +} VkPhysicalDeviceVideoMaintenance1FeaturesKHR; + +typedef struct VkVideoInlineQueryInfoKHR { + VkStructureType sType; + const void* pNext; + VkQueryPool queryPool; + uint32_t firstQuery; + uint32_t queryCount; +} VkVideoInlineQueryInfoKHR; + + + +// VK_KHR_vertex_attribute_divisor is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_vertex_attribute_divisor 1 +#define VK_KHR_VERTEX_ATTRIBUTE_DIVISOR_SPEC_VERSION 1 +#define VK_KHR_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME "VK_KHR_vertex_attribute_divisor" +typedef struct VkPhysicalDeviceVertexAttributeDivisorPropertiesKHR { + VkStructureType sType; + void* pNext; + uint32_t maxVertexAttribDivisor; + VkBool32 supportsNonZeroFirstInstance; +} VkPhysicalDeviceVertexAttributeDivisorPropertiesKHR; + +typedef struct VkVertexInputBindingDivisorDescriptionKHR { + uint32_t binding; + uint32_t divisor; +} VkVertexInputBindingDivisorDescriptionKHR; + +typedef struct VkPipelineVertexInputDivisorStateCreateInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t vertexBindingDivisorCount; + const VkVertexInputBindingDivisorDescriptionKHR* pVertexBindingDivisors; +} VkPipelineVertexInputDivisorStateCreateInfoKHR; + +typedef struct VkPhysicalDeviceVertexAttributeDivisorFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 vertexAttributeInstanceRateDivisor; + VkBool32 vertexAttributeInstanceRateZeroDivisor; +} VkPhysicalDeviceVertexAttributeDivisorFeaturesKHR; + + + +// VK_KHR_calibrated_timestamps is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_calibrated_timestamps 1 +#define VK_KHR_CALIBRATED_TIMESTAMPS_SPEC_VERSION 1 +#define VK_KHR_CALIBRATED_TIMESTAMPS_EXTENSION_NAME "VK_KHR_calibrated_timestamps" + +typedef enum VkTimeDomainKHR { + VK_TIME_DOMAIN_DEVICE_KHR = 0, + VK_TIME_DOMAIN_CLOCK_MONOTONIC_KHR = 1, + VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_KHR = 2, + VK_TIME_DOMAIN_QUERY_PERFORMANCE_COUNTER_KHR = 3, + VK_TIME_DOMAIN_DEVICE_EXT = VK_TIME_DOMAIN_DEVICE_KHR, + VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT = VK_TIME_DOMAIN_CLOCK_MONOTONIC_KHR, + VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT = VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_KHR, + VK_TIME_DOMAIN_QUERY_PERFORMANCE_COUNTER_EXT = VK_TIME_DOMAIN_QUERY_PERFORMANCE_COUNTER_KHR, + VK_TIME_DOMAIN_MAX_ENUM_KHR = 0x7FFFFFFF +} VkTimeDomainKHR; +typedef struct VkCalibratedTimestampInfoKHR { + VkStructureType sType; + const void* pNext; + VkTimeDomainKHR timeDomain; +} VkCalibratedTimestampInfoKHR; + +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsKHR)(VkPhysicalDevice physicalDevice, uint32_t* pTimeDomainCount, VkTimeDomainKHR* pTimeDomains); +typedef VkResult (VKAPI_PTR *PFN_vkGetCalibratedTimestampsKHR)(VkDevice device, uint32_t timestampCount, const VkCalibratedTimestampInfoKHR* pTimestampInfos, uint64_t* pTimestamps, uint64_t* pMaxDeviation); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceCalibrateableTimeDomainsKHR( + VkPhysicalDevice physicalDevice, + uint32_t* pTimeDomainCount, + VkTimeDomainKHR* pTimeDomains); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetCalibratedTimestampsKHR( + VkDevice device, + uint32_t timestampCount, + const VkCalibratedTimestampInfoKHR* pTimestampInfos, + uint64_t* pTimestamps, + uint64_t* pMaxDeviation); +#endif + + +// VK_KHR_maintenance6 is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_maintenance6 1 +#define VK_KHR_MAINTENANCE_6_SPEC_VERSION 1 +#define VK_KHR_MAINTENANCE_6_EXTENSION_NAME "VK_KHR_maintenance6" +typedef struct VkPhysicalDeviceMaintenance6FeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 maintenance6; +} VkPhysicalDeviceMaintenance6FeaturesKHR; + +typedef struct VkPhysicalDeviceMaintenance6PropertiesKHR { + VkStructureType sType; + void* pNext; + VkBool32 blockTexelViewCompatibleMultipleLayers; + uint32_t maxCombinedImageSamplerDescriptorCount; + VkBool32 fragmentShadingRateClampCombinerInputs; +} VkPhysicalDeviceMaintenance6PropertiesKHR; + +typedef struct VkBindMemoryStatusKHR { + VkStructureType sType; + const void* pNext; + VkResult* pResult; +} VkBindMemoryStatusKHR; + +typedef struct VkBindDescriptorSetsInfoKHR { + VkStructureType sType; + const void* pNext; + VkShaderStageFlags stageFlags; + VkPipelineLayout layout; + uint32_t firstSet; + uint32_t descriptorSetCount; + const VkDescriptorSet* pDescriptorSets; + uint32_t dynamicOffsetCount; + const uint32_t* pDynamicOffsets; +} VkBindDescriptorSetsInfoKHR; + +typedef struct VkPushConstantsInfoKHR { + VkStructureType sType; + const void* pNext; + VkPipelineLayout layout; + VkShaderStageFlags stageFlags; + uint32_t offset; + uint32_t size; + const void* pValues; +} VkPushConstantsInfoKHR; + +typedef struct VkPushDescriptorSetInfoKHR { + VkStructureType sType; + const void* pNext; + VkShaderStageFlags stageFlags; + VkPipelineLayout layout; + uint32_t set; + uint32_t descriptorWriteCount; + const VkWriteDescriptorSet* pDescriptorWrites; +} VkPushDescriptorSetInfoKHR; + +typedef struct VkPushDescriptorSetWithTemplateInfoKHR { + VkStructureType sType; + const void* pNext; + VkDescriptorUpdateTemplate descriptorUpdateTemplate; + VkPipelineLayout layout; + uint32_t set; + const void* pData; +} VkPushDescriptorSetWithTemplateInfoKHR; + +typedef struct VkSetDescriptorBufferOffsetsInfoEXT { + VkStructureType sType; + const void* pNext; + VkShaderStageFlags stageFlags; + VkPipelineLayout layout; + uint32_t firstSet; + uint32_t setCount; + const uint32_t* pBufferIndices; + const VkDeviceSize* pOffsets; +} VkSetDescriptorBufferOffsetsInfoEXT; + +typedef struct VkBindDescriptorBufferEmbeddedSamplersInfoEXT { + VkStructureType sType; + const void* pNext; + VkShaderStageFlags stageFlags; + VkPipelineLayout layout; + uint32_t set; +} VkBindDescriptorBufferEmbeddedSamplersInfoEXT; + +typedef void (VKAPI_PTR *PFN_vkCmdBindDescriptorSets2KHR)(VkCommandBuffer commandBuffer, const VkBindDescriptorSetsInfoKHR* pBindDescriptorSetsInfo); +typedef void (VKAPI_PTR *PFN_vkCmdPushConstants2KHR)(VkCommandBuffer commandBuffer, const VkPushConstantsInfoKHR* pPushConstantsInfo); +typedef void (VKAPI_PTR *PFN_vkCmdPushDescriptorSet2KHR)(VkCommandBuffer commandBuffer, const VkPushDescriptorSetInfoKHR* pPushDescriptorSetInfo); +typedef void (VKAPI_PTR *PFN_vkCmdPushDescriptorSetWithTemplate2KHR)(VkCommandBuffer commandBuffer, const VkPushDescriptorSetWithTemplateInfoKHR* pPushDescriptorSetWithTemplateInfo); +typedef void (VKAPI_PTR *PFN_vkCmdSetDescriptorBufferOffsets2EXT)(VkCommandBuffer commandBuffer, const VkSetDescriptorBufferOffsetsInfoEXT* pSetDescriptorBufferOffsetsInfo); +typedef void (VKAPI_PTR *PFN_vkCmdBindDescriptorBufferEmbeddedSamplers2EXT)(VkCommandBuffer commandBuffer, const VkBindDescriptorBufferEmbeddedSamplersInfoEXT* pBindDescriptorBufferEmbeddedSamplersInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdBindDescriptorSets2KHR( + VkCommandBuffer commandBuffer, + const VkBindDescriptorSetsInfoKHR* pBindDescriptorSetsInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdPushConstants2KHR( + VkCommandBuffer commandBuffer, + const VkPushConstantsInfoKHR* pPushConstantsInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdPushDescriptorSet2KHR( + VkCommandBuffer commandBuffer, + const VkPushDescriptorSetInfoKHR* pPushDescriptorSetInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdPushDescriptorSetWithTemplate2KHR( + VkCommandBuffer commandBuffer, + const VkPushDescriptorSetWithTemplateInfoKHR* pPushDescriptorSetWithTemplateInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDescriptorBufferOffsets2EXT( + VkCommandBuffer commandBuffer, + const VkSetDescriptorBufferOffsetsInfoEXT* pSetDescriptorBufferOffsetsInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdBindDescriptorBufferEmbeddedSamplers2EXT( + VkCommandBuffer commandBuffer, + const VkBindDescriptorBufferEmbeddedSamplersInfoEXT* pBindDescriptorBufferEmbeddedSamplersInfo); +#endif + + +// VK_EXT_debug_report is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_debug_report 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDebugReportCallbackEXT) +#define VK_EXT_DEBUG_REPORT_SPEC_VERSION 10 +#define VK_EXT_DEBUG_REPORT_EXTENSION_NAME "VK_EXT_debug_report" + +typedef enum VkDebugReportObjectTypeEXT { + VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT = 0, + VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT = 1, + VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT = 2, + VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT = 3, + VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT = 4, + VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT = 5, + VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT = 6, + VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT = 7, + VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT = 8, + VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT = 9, + VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT = 10, + VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT = 11, + VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT = 12, + VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT = 13, + VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT = 14, + VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT = 15, + VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT = 16, + VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT = 17, + VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT = 18, + VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT = 19, + VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT = 20, + VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT = 21, + VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT = 22, + VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT = 23, + VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT = 24, + VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT = 25, + VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT = 26, + VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT = 27, + VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT = 28, + VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_KHR_EXT = 29, + VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_MODE_KHR_EXT = 30, + VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT = 33, + VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_EXT = 1000156000, + VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT = 1000085000, + VK_DEBUG_REPORT_OBJECT_TYPE_CU_MODULE_NVX_EXT = 1000029000, + VK_DEBUG_REPORT_OBJECT_TYPE_CU_FUNCTION_NVX_EXT = 1000029001, + VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR_EXT = 1000150000, + VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV_EXT = 1000165000, + VK_DEBUG_REPORT_OBJECT_TYPE_CUDA_MODULE_NV_EXT = 1000307000, + VK_DEBUG_REPORT_OBJECT_TYPE_CUDA_FUNCTION_NV_EXT = 1000307001, + VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_COLLECTION_FUCHSIA_EXT = 1000366000, + VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT_EXT, + VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_VALIDATION_CACHE_EXT_EXT, + VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_EXT, + VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_KHR_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION_EXT, + VK_DEBUG_REPORT_OBJECT_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF +} VkDebugReportObjectTypeEXT; + +typedef enum VkDebugReportFlagBitsEXT { + VK_DEBUG_REPORT_INFORMATION_BIT_EXT = 0x00000001, + VK_DEBUG_REPORT_WARNING_BIT_EXT = 0x00000002, + VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT = 0x00000004, + VK_DEBUG_REPORT_ERROR_BIT_EXT = 0x00000008, + VK_DEBUG_REPORT_DEBUG_BIT_EXT = 0x00000010, + VK_DEBUG_REPORT_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkDebugReportFlagBitsEXT; +typedef VkFlags VkDebugReportFlagsEXT; +typedef VkBool32 (VKAPI_PTR *PFN_vkDebugReportCallbackEXT)( + VkDebugReportFlagsEXT flags, + VkDebugReportObjectTypeEXT objectType, + uint64_t object, + size_t location, + int32_t messageCode, + const char* pLayerPrefix, + const char* pMessage, + void* pUserData); + +typedef struct VkDebugReportCallbackCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkDebugReportFlagsEXT flags; + PFN_vkDebugReportCallbackEXT pfnCallback; + void* pUserData; +} VkDebugReportCallbackCreateInfoEXT; + +typedef VkResult (VKAPI_PTR *PFN_vkCreateDebugReportCallbackEXT)(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT* pCallback); +typedef void (VKAPI_PTR *PFN_vkDestroyDebugReportCallbackEXT)(VkInstance instance, VkDebugReportCallbackEXT callback, const VkAllocationCallbacks* pAllocator); +typedef void (VKAPI_PTR *PFN_vkDebugReportMessageEXT)(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugReportCallbackEXT( + VkInstance instance, + const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkDebugReportCallbackEXT* pCallback); + +VKAPI_ATTR void VKAPI_CALL vkDestroyDebugReportCallbackEXT( + VkInstance instance, + VkDebugReportCallbackEXT callback, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR void VKAPI_CALL vkDebugReportMessageEXT( + VkInstance instance, + VkDebugReportFlagsEXT flags, + VkDebugReportObjectTypeEXT objectType, + uint64_t object, + size_t location, + int32_t messageCode, + const char* pLayerPrefix, + const char* pMessage); +#endif + + +// VK_NV_glsl_shader is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_glsl_shader 1 +#define VK_NV_GLSL_SHADER_SPEC_VERSION 1 +#define VK_NV_GLSL_SHADER_EXTENSION_NAME "VK_NV_glsl_shader" + + +// VK_EXT_depth_range_unrestricted is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_depth_range_unrestricted 1 +#define VK_EXT_DEPTH_RANGE_UNRESTRICTED_SPEC_VERSION 1 +#define VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME "VK_EXT_depth_range_unrestricted" + + +// VK_IMG_filter_cubic is a preprocessor guard. Do not pass it to API calls. +#define VK_IMG_filter_cubic 1 +#define VK_IMG_FILTER_CUBIC_SPEC_VERSION 1 +#define VK_IMG_FILTER_CUBIC_EXTENSION_NAME "VK_IMG_filter_cubic" + + +// VK_AMD_rasterization_order is a preprocessor guard. Do not pass it to API calls. +#define VK_AMD_rasterization_order 1 +#define VK_AMD_RASTERIZATION_ORDER_SPEC_VERSION 1 +#define VK_AMD_RASTERIZATION_ORDER_EXTENSION_NAME "VK_AMD_rasterization_order" + +typedef enum VkRasterizationOrderAMD { + VK_RASTERIZATION_ORDER_STRICT_AMD = 0, + VK_RASTERIZATION_ORDER_RELAXED_AMD = 1, + VK_RASTERIZATION_ORDER_MAX_ENUM_AMD = 0x7FFFFFFF +} VkRasterizationOrderAMD; +typedef struct VkPipelineRasterizationStateRasterizationOrderAMD { + VkStructureType sType; + const void* pNext; + VkRasterizationOrderAMD rasterizationOrder; +} VkPipelineRasterizationStateRasterizationOrderAMD; + + + +// VK_AMD_shader_trinary_minmax is a preprocessor guard. Do not pass it to API calls. +#define VK_AMD_shader_trinary_minmax 1 +#define VK_AMD_SHADER_TRINARY_MINMAX_SPEC_VERSION 1 +#define VK_AMD_SHADER_TRINARY_MINMAX_EXTENSION_NAME "VK_AMD_shader_trinary_minmax" + + +// VK_AMD_shader_explicit_vertex_parameter is a preprocessor guard. Do not pass it to API calls. +#define VK_AMD_shader_explicit_vertex_parameter 1 +#define VK_AMD_SHADER_EXPLICIT_VERTEX_PARAMETER_SPEC_VERSION 1 +#define VK_AMD_SHADER_EXPLICIT_VERTEX_PARAMETER_EXTENSION_NAME "VK_AMD_shader_explicit_vertex_parameter" + + +// VK_EXT_debug_marker is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_debug_marker 1 +#define VK_EXT_DEBUG_MARKER_SPEC_VERSION 4 +#define VK_EXT_DEBUG_MARKER_EXTENSION_NAME "VK_EXT_debug_marker" +typedef struct VkDebugMarkerObjectNameInfoEXT { + VkStructureType sType; + const void* pNext; + VkDebugReportObjectTypeEXT objectType; + uint64_t object; + const char* pObjectName; +} VkDebugMarkerObjectNameInfoEXT; + +typedef struct VkDebugMarkerObjectTagInfoEXT { + VkStructureType sType; + const void* pNext; + VkDebugReportObjectTypeEXT objectType; + uint64_t object; + uint64_t tagName; + size_t tagSize; + const void* pTag; +} VkDebugMarkerObjectTagInfoEXT; + +typedef struct VkDebugMarkerMarkerInfoEXT { + VkStructureType sType; + const void* pNext; + const char* pMarkerName; + float color[4]; +} VkDebugMarkerMarkerInfoEXT; + +typedef VkResult (VKAPI_PTR *PFN_vkDebugMarkerSetObjectTagEXT)(VkDevice device, const VkDebugMarkerObjectTagInfoEXT* pTagInfo); +typedef VkResult (VKAPI_PTR *PFN_vkDebugMarkerSetObjectNameEXT)(VkDevice device, const VkDebugMarkerObjectNameInfoEXT* pNameInfo); +typedef void (VKAPI_PTR *PFN_vkCmdDebugMarkerBeginEXT)(VkCommandBuffer commandBuffer, const VkDebugMarkerMarkerInfoEXT* pMarkerInfo); +typedef void (VKAPI_PTR *PFN_vkCmdDebugMarkerEndEXT)(VkCommandBuffer commandBuffer); +typedef void (VKAPI_PTR *PFN_vkCmdDebugMarkerInsertEXT)(VkCommandBuffer commandBuffer, const VkDebugMarkerMarkerInfoEXT* pMarkerInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkDebugMarkerSetObjectTagEXT( + VkDevice device, + const VkDebugMarkerObjectTagInfoEXT* pTagInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkDebugMarkerSetObjectNameEXT( + VkDevice device, + const VkDebugMarkerObjectNameInfoEXT* pNameInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdDebugMarkerBeginEXT( + VkCommandBuffer commandBuffer, + const VkDebugMarkerMarkerInfoEXT* pMarkerInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdDebugMarkerEndEXT( + VkCommandBuffer commandBuffer); + +VKAPI_ATTR void VKAPI_CALL vkCmdDebugMarkerInsertEXT( + VkCommandBuffer commandBuffer, + const VkDebugMarkerMarkerInfoEXT* pMarkerInfo); +#endif + + +// VK_AMD_gcn_shader is a preprocessor guard. Do not pass it to API calls. +#define VK_AMD_gcn_shader 1 +#define VK_AMD_GCN_SHADER_SPEC_VERSION 1 +#define VK_AMD_GCN_SHADER_EXTENSION_NAME "VK_AMD_gcn_shader" + + +// VK_NV_dedicated_allocation is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_dedicated_allocation 1 +#define VK_NV_DEDICATED_ALLOCATION_SPEC_VERSION 1 +#define VK_NV_DEDICATED_ALLOCATION_EXTENSION_NAME "VK_NV_dedicated_allocation" +typedef struct VkDedicatedAllocationImageCreateInfoNV { + VkStructureType sType; + const void* pNext; + VkBool32 dedicatedAllocation; +} VkDedicatedAllocationImageCreateInfoNV; + +typedef struct VkDedicatedAllocationBufferCreateInfoNV { + VkStructureType sType; + const void* pNext; + VkBool32 dedicatedAllocation; +} VkDedicatedAllocationBufferCreateInfoNV; + +typedef struct VkDedicatedAllocationMemoryAllocateInfoNV { + VkStructureType sType; + const void* pNext; + VkImage image; + VkBuffer buffer; +} VkDedicatedAllocationMemoryAllocateInfoNV; + + + +// VK_EXT_transform_feedback is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_transform_feedback 1 +#define VK_EXT_TRANSFORM_FEEDBACK_SPEC_VERSION 1 +#define VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME "VK_EXT_transform_feedback" +typedef VkFlags VkPipelineRasterizationStateStreamCreateFlagsEXT; +typedef struct VkPhysicalDeviceTransformFeedbackFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 transformFeedback; + VkBool32 geometryStreams; +} VkPhysicalDeviceTransformFeedbackFeaturesEXT; + +typedef struct VkPhysicalDeviceTransformFeedbackPropertiesEXT { + VkStructureType sType; + void* pNext; + uint32_t maxTransformFeedbackStreams; + uint32_t maxTransformFeedbackBuffers; + VkDeviceSize maxTransformFeedbackBufferSize; + uint32_t maxTransformFeedbackStreamDataSize; + uint32_t maxTransformFeedbackBufferDataSize; + uint32_t maxTransformFeedbackBufferDataStride; + VkBool32 transformFeedbackQueries; + VkBool32 transformFeedbackStreamsLinesTriangles; + VkBool32 transformFeedbackRasterizationStreamSelect; + VkBool32 transformFeedbackDraw; +} VkPhysicalDeviceTransformFeedbackPropertiesEXT; + +typedef struct VkPipelineRasterizationStateStreamCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkPipelineRasterizationStateStreamCreateFlagsEXT flags; + uint32_t rasterizationStream; +} VkPipelineRasterizationStateStreamCreateInfoEXT; + +typedef void (VKAPI_PTR *PFN_vkCmdBindTransformFeedbackBuffersEXT)(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, const VkBuffer* pBuffers, const VkDeviceSize* pOffsets, const VkDeviceSize* pSizes); +typedef void (VKAPI_PTR *PFN_vkCmdBeginTransformFeedbackEXT)(VkCommandBuffer commandBuffer, uint32_t firstCounterBuffer, uint32_t counterBufferCount, const VkBuffer* pCounterBuffers, const VkDeviceSize* pCounterBufferOffsets); +typedef void (VKAPI_PTR *PFN_vkCmdEndTransformFeedbackEXT)(VkCommandBuffer commandBuffer, uint32_t firstCounterBuffer, uint32_t counterBufferCount, const VkBuffer* pCounterBuffers, const VkDeviceSize* pCounterBufferOffsets); +typedef void (VKAPI_PTR *PFN_vkCmdBeginQueryIndexedEXT)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags, uint32_t index); +typedef void (VKAPI_PTR *PFN_vkCmdEndQueryIndexedEXT)(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t query, uint32_t index); +typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirectByteCountEXT)(VkCommandBuffer commandBuffer, uint32_t instanceCount, uint32_t firstInstance, VkBuffer counterBuffer, VkDeviceSize counterBufferOffset, uint32_t counterOffset, uint32_t vertexStride); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdBindTransformFeedbackBuffersEXT( + VkCommandBuffer commandBuffer, + uint32_t firstBinding, + uint32_t bindingCount, + const VkBuffer* pBuffers, + const VkDeviceSize* pOffsets, + const VkDeviceSize* pSizes); + +VKAPI_ATTR void VKAPI_CALL vkCmdBeginTransformFeedbackEXT( + VkCommandBuffer commandBuffer, + uint32_t firstCounterBuffer, + uint32_t counterBufferCount, + const VkBuffer* pCounterBuffers, + const VkDeviceSize* pCounterBufferOffsets); + +VKAPI_ATTR void VKAPI_CALL vkCmdEndTransformFeedbackEXT( + VkCommandBuffer commandBuffer, + uint32_t firstCounterBuffer, + uint32_t counterBufferCount, + const VkBuffer* pCounterBuffers, + const VkDeviceSize* pCounterBufferOffsets); + +VKAPI_ATTR void VKAPI_CALL vkCmdBeginQueryIndexedEXT( + VkCommandBuffer commandBuffer, + VkQueryPool queryPool, + uint32_t query, + VkQueryControlFlags flags, + uint32_t index); + +VKAPI_ATTR void VKAPI_CALL vkCmdEndQueryIndexedEXT( + VkCommandBuffer commandBuffer, + VkQueryPool queryPool, + uint32_t query, + uint32_t index); + +VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirectByteCountEXT( + VkCommandBuffer commandBuffer, + uint32_t instanceCount, + uint32_t firstInstance, + VkBuffer counterBuffer, + VkDeviceSize counterBufferOffset, + uint32_t counterOffset, + uint32_t vertexStride); +#endif + + +// VK_NVX_binary_import is a preprocessor guard. Do not pass it to API calls. +#define VK_NVX_binary_import 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCuModuleNVX) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCuFunctionNVX) +#define VK_NVX_BINARY_IMPORT_SPEC_VERSION 1 +#define VK_NVX_BINARY_IMPORT_EXTENSION_NAME "VK_NVX_binary_import" +typedef struct VkCuModuleCreateInfoNVX { + VkStructureType sType; + const void* pNext; + size_t dataSize; + const void* pData; +} VkCuModuleCreateInfoNVX; + +typedef struct VkCuFunctionCreateInfoNVX { + VkStructureType sType; + const void* pNext; + VkCuModuleNVX module; + const char* pName; +} VkCuFunctionCreateInfoNVX; + +typedef struct VkCuLaunchInfoNVX { + VkStructureType sType; + const void* pNext; + VkCuFunctionNVX function; + uint32_t gridDimX; + uint32_t gridDimY; + uint32_t gridDimZ; + uint32_t blockDimX; + uint32_t blockDimY; + uint32_t blockDimZ; + uint32_t sharedMemBytes; + size_t paramCount; + const void* const * pParams; + size_t extraCount; + const void* const * pExtras; +} VkCuLaunchInfoNVX; + +typedef VkResult (VKAPI_PTR *PFN_vkCreateCuModuleNVX)(VkDevice device, const VkCuModuleCreateInfoNVX* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkCuModuleNVX* pModule); +typedef VkResult (VKAPI_PTR *PFN_vkCreateCuFunctionNVX)(VkDevice device, const VkCuFunctionCreateInfoNVX* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkCuFunctionNVX* pFunction); +typedef void (VKAPI_PTR *PFN_vkDestroyCuModuleNVX)(VkDevice device, VkCuModuleNVX module, const VkAllocationCallbacks* pAllocator); +typedef void (VKAPI_PTR *PFN_vkDestroyCuFunctionNVX)(VkDevice device, VkCuFunctionNVX function, const VkAllocationCallbacks* pAllocator); +typedef void (VKAPI_PTR *PFN_vkCmdCuLaunchKernelNVX)(VkCommandBuffer commandBuffer, const VkCuLaunchInfoNVX* pLaunchInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateCuModuleNVX( + VkDevice device, + const VkCuModuleCreateInfoNVX* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkCuModuleNVX* pModule); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateCuFunctionNVX( + VkDevice device, + const VkCuFunctionCreateInfoNVX* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkCuFunctionNVX* pFunction); + +VKAPI_ATTR void VKAPI_CALL vkDestroyCuModuleNVX( + VkDevice device, + VkCuModuleNVX module, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR void VKAPI_CALL vkDestroyCuFunctionNVX( + VkDevice device, + VkCuFunctionNVX function, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR void VKAPI_CALL vkCmdCuLaunchKernelNVX( + VkCommandBuffer commandBuffer, + const VkCuLaunchInfoNVX* pLaunchInfo); +#endif + + +// VK_NVX_image_view_handle is a preprocessor guard. Do not pass it to API calls. +#define VK_NVX_image_view_handle 1 +#define VK_NVX_IMAGE_VIEW_HANDLE_SPEC_VERSION 2 +#define VK_NVX_IMAGE_VIEW_HANDLE_EXTENSION_NAME "VK_NVX_image_view_handle" +typedef struct VkImageViewHandleInfoNVX { + VkStructureType sType; + const void* pNext; + VkImageView imageView; + VkDescriptorType descriptorType; + VkSampler sampler; +} VkImageViewHandleInfoNVX; + +typedef struct VkImageViewAddressPropertiesNVX { + VkStructureType sType; + void* pNext; + VkDeviceAddress deviceAddress; + VkDeviceSize size; +} VkImageViewAddressPropertiesNVX; + +typedef uint32_t (VKAPI_PTR *PFN_vkGetImageViewHandleNVX)(VkDevice device, const VkImageViewHandleInfoNVX* pInfo); +typedef VkResult (VKAPI_PTR *PFN_vkGetImageViewAddressNVX)(VkDevice device, VkImageView imageView, VkImageViewAddressPropertiesNVX* pProperties); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR uint32_t VKAPI_CALL vkGetImageViewHandleNVX( + VkDevice device, + const VkImageViewHandleInfoNVX* pInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetImageViewAddressNVX( + VkDevice device, + VkImageView imageView, + VkImageViewAddressPropertiesNVX* pProperties); +#endif + + +// VK_AMD_draw_indirect_count is a preprocessor guard. Do not pass it to API calls. +#define VK_AMD_draw_indirect_count 1 +#define VK_AMD_DRAW_INDIRECT_COUNT_SPEC_VERSION 2 +#define VK_AMD_DRAW_INDIRECT_COUNT_EXTENSION_NAME "VK_AMD_draw_indirect_count" +typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirectCountAMD)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); +typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexedIndirectCountAMD)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndirectCountAMD( + VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset, + VkBuffer countBuffer, + VkDeviceSize countBufferOffset, + uint32_t maxDrawCount, + uint32_t stride); + +VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirectCountAMD( + VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset, + VkBuffer countBuffer, + VkDeviceSize countBufferOffset, + uint32_t maxDrawCount, + uint32_t stride); +#endif + + +// VK_AMD_negative_viewport_height is a preprocessor guard. Do not pass it to API calls. +#define VK_AMD_negative_viewport_height 1 +#define VK_AMD_NEGATIVE_VIEWPORT_HEIGHT_SPEC_VERSION 1 +#define VK_AMD_NEGATIVE_VIEWPORT_HEIGHT_EXTENSION_NAME "VK_AMD_negative_viewport_height" + + +// VK_AMD_gpu_shader_half_float is a preprocessor guard. Do not pass it to API calls. +#define VK_AMD_gpu_shader_half_float 1 +#define VK_AMD_GPU_SHADER_HALF_FLOAT_SPEC_VERSION 2 +#define VK_AMD_GPU_SHADER_HALF_FLOAT_EXTENSION_NAME "VK_AMD_gpu_shader_half_float" + + +// VK_AMD_shader_ballot is a preprocessor guard. Do not pass it to API calls. +#define VK_AMD_shader_ballot 1 +#define VK_AMD_SHADER_BALLOT_SPEC_VERSION 1 +#define VK_AMD_SHADER_BALLOT_EXTENSION_NAME "VK_AMD_shader_ballot" + + +// VK_AMD_texture_gather_bias_lod is a preprocessor guard. Do not pass it to API calls. +#define VK_AMD_texture_gather_bias_lod 1 +#define VK_AMD_TEXTURE_GATHER_BIAS_LOD_SPEC_VERSION 1 +#define VK_AMD_TEXTURE_GATHER_BIAS_LOD_EXTENSION_NAME "VK_AMD_texture_gather_bias_lod" +typedef struct VkTextureLODGatherFormatPropertiesAMD { + VkStructureType sType; + void* pNext; + VkBool32 supportsTextureGatherLODBiasAMD; +} VkTextureLODGatherFormatPropertiesAMD; + + + +// VK_AMD_shader_info is a preprocessor guard. Do not pass it to API calls. +#define VK_AMD_shader_info 1 +#define VK_AMD_SHADER_INFO_SPEC_VERSION 1 +#define VK_AMD_SHADER_INFO_EXTENSION_NAME "VK_AMD_shader_info" + +typedef enum VkShaderInfoTypeAMD { + VK_SHADER_INFO_TYPE_STATISTICS_AMD = 0, + VK_SHADER_INFO_TYPE_BINARY_AMD = 1, + VK_SHADER_INFO_TYPE_DISASSEMBLY_AMD = 2, + VK_SHADER_INFO_TYPE_MAX_ENUM_AMD = 0x7FFFFFFF +} VkShaderInfoTypeAMD; +typedef struct VkShaderResourceUsageAMD { + uint32_t numUsedVgprs; + uint32_t numUsedSgprs; + uint32_t ldsSizePerLocalWorkGroup; + size_t ldsUsageSizeInBytes; + size_t scratchMemUsageInBytes; +} VkShaderResourceUsageAMD; + +typedef struct VkShaderStatisticsInfoAMD { + VkShaderStageFlags shaderStageMask; + VkShaderResourceUsageAMD resourceUsage; + uint32_t numPhysicalVgprs; + uint32_t numPhysicalSgprs; + uint32_t numAvailableVgprs; + uint32_t numAvailableSgprs; + uint32_t computeWorkGroupSize[3]; +} VkShaderStatisticsInfoAMD; + +typedef VkResult (VKAPI_PTR *PFN_vkGetShaderInfoAMD)(VkDevice device, VkPipeline pipeline, VkShaderStageFlagBits shaderStage, VkShaderInfoTypeAMD infoType, size_t* pInfoSize, void* pInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetShaderInfoAMD( + VkDevice device, + VkPipeline pipeline, + VkShaderStageFlagBits shaderStage, + VkShaderInfoTypeAMD infoType, + size_t* pInfoSize, + void* pInfo); +#endif + + +// VK_AMD_shader_image_load_store_lod is a preprocessor guard. Do not pass it to API calls. +#define VK_AMD_shader_image_load_store_lod 1 +#define VK_AMD_SHADER_IMAGE_LOAD_STORE_LOD_SPEC_VERSION 1 +#define VK_AMD_SHADER_IMAGE_LOAD_STORE_LOD_EXTENSION_NAME "VK_AMD_shader_image_load_store_lod" + + +// VK_NV_corner_sampled_image is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_corner_sampled_image 1 +#define VK_NV_CORNER_SAMPLED_IMAGE_SPEC_VERSION 2 +#define VK_NV_CORNER_SAMPLED_IMAGE_EXTENSION_NAME "VK_NV_corner_sampled_image" +typedef struct VkPhysicalDeviceCornerSampledImageFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 cornerSampledImage; +} VkPhysicalDeviceCornerSampledImageFeaturesNV; + + + +// VK_IMG_format_pvrtc is a preprocessor guard. Do not pass it to API calls. +#define VK_IMG_format_pvrtc 1 +#define VK_IMG_FORMAT_PVRTC_SPEC_VERSION 1 +#define VK_IMG_FORMAT_PVRTC_EXTENSION_NAME "VK_IMG_format_pvrtc" + + +// VK_NV_external_memory_capabilities is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_external_memory_capabilities 1 +#define VK_NV_EXTERNAL_MEMORY_CAPABILITIES_SPEC_VERSION 1 +#define VK_NV_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME "VK_NV_external_memory_capabilities" + +typedef enum VkExternalMemoryHandleTypeFlagBitsNV { + VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_NV = 0x00000001, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_NV = 0x00000002, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_IMAGE_BIT_NV = 0x00000004, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_IMAGE_KMT_BIT_NV = 0x00000008, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF +} VkExternalMemoryHandleTypeFlagBitsNV; +typedef VkFlags VkExternalMemoryHandleTypeFlagsNV; + +typedef enum VkExternalMemoryFeatureFlagBitsNV { + VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_NV = 0x00000001, + VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_NV = 0x00000002, + VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_NV = 0x00000004, + VK_EXTERNAL_MEMORY_FEATURE_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF +} VkExternalMemoryFeatureFlagBitsNV; +typedef VkFlags VkExternalMemoryFeatureFlagsNV; +typedef struct VkExternalImageFormatPropertiesNV { + VkImageFormatProperties imageFormatProperties; + VkExternalMemoryFeatureFlagsNV externalMemoryFeatures; + VkExternalMemoryHandleTypeFlagsNV exportFromImportedHandleTypes; + VkExternalMemoryHandleTypeFlagsNV compatibleHandleTypes; +} VkExternalImageFormatPropertiesNV; + +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceExternalImageFormatPropertiesNV)(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags, VkExternalMemoryHandleTypeFlagsNV externalHandleType, VkExternalImageFormatPropertiesNV* pExternalImageFormatProperties); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceExternalImageFormatPropertiesNV( + VkPhysicalDevice physicalDevice, + VkFormat format, + VkImageType type, + VkImageTiling tiling, + VkImageUsageFlags usage, + VkImageCreateFlags flags, + VkExternalMemoryHandleTypeFlagsNV externalHandleType, + VkExternalImageFormatPropertiesNV* pExternalImageFormatProperties); +#endif + + +// VK_NV_external_memory is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_external_memory 1 +#define VK_NV_EXTERNAL_MEMORY_SPEC_VERSION 1 +#define VK_NV_EXTERNAL_MEMORY_EXTENSION_NAME "VK_NV_external_memory" +typedef struct VkExternalMemoryImageCreateInfoNV { + VkStructureType sType; + const void* pNext; + VkExternalMemoryHandleTypeFlagsNV handleTypes; +} VkExternalMemoryImageCreateInfoNV; + +typedef struct VkExportMemoryAllocateInfoNV { + VkStructureType sType; + const void* pNext; + VkExternalMemoryHandleTypeFlagsNV handleTypes; +} VkExportMemoryAllocateInfoNV; + + + +// VK_EXT_validation_flags is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_validation_flags 1 +#define VK_EXT_VALIDATION_FLAGS_SPEC_VERSION 3 +#define VK_EXT_VALIDATION_FLAGS_EXTENSION_NAME "VK_EXT_validation_flags" + +typedef enum VkValidationCheckEXT { + VK_VALIDATION_CHECK_ALL_EXT = 0, + VK_VALIDATION_CHECK_SHADERS_EXT = 1, + VK_VALIDATION_CHECK_MAX_ENUM_EXT = 0x7FFFFFFF +} VkValidationCheckEXT; +typedef struct VkValidationFlagsEXT { + VkStructureType sType; + const void* pNext; + uint32_t disabledValidationCheckCount; + const VkValidationCheckEXT* pDisabledValidationChecks; +} VkValidationFlagsEXT; + + + +// VK_EXT_shader_subgroup_ballot is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_shader_subgroup_ballot 1 +#define VK_EXT_SHADER_SUBGROUP_BALLOT_SPEC_VERSION 1 +#define VK_EXT_SHADER_SUBGROUP_BALLOT_EXTENSION_NAME "VK_EXT_shader_subgroup_ballot" + + +// VK_EXT_shader_subgroup_vote is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_shader_subgroup_vote 1 +#define VK_EXT_SHADER_SUBGROUP_VOTE_SPEC_VERSION 1 +#define VK_EXT_SHADER_SUBGROUP_VOTE_EXTENSION_NAME "VK_EXT_shader_subgroup_vote" + + +// VK_EXT_texture_compression_astc_hdr is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_texture_compression_astc_hdr 1 +#define VK_EXT_TEXTURE_COMPRESSION_ASTC_HDR_SPEC_VERSION 1 +#define VK_EXT_TEXTURE_COMPRESSION_ASTC_HDR_EXTENSION_NAME "VK_EXT_texture_compression_astc_hdr" +typedef VkPhysicalDeviceTextureCompressionASTCHDRFeatures VkPhysicalDeviceTextureCompressionASTCHDRFeaturesEXT; + + + +// VK_EXT_astc_decode_mode is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_astc_decode_mode 1 +#define VK_EXT_ASTC_DECODE_MODE_SPEC_VERSION 1 +#define VK_EXT_ASTC_DECODE_MODE_EXTENSION_NAME "VK_EXT_astc_decode_mode" +typedef struct VkImageViewASTCDecodeModeEXT { + VkStructureType sType; + const void* pNext; + VkFormat decodeMode; +} VkImageViewASTCDecodeModeEXT; + +typedef struct VkPhysicalDeviceASTCDecodeFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 decodeModeSharedExponent; +} VkPhysicalDeviceASTCDecodeFeaturesEXT; + + + +// VK_EXT_pipeline_robustness is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_pipeline_robustness 1 +#define VK_EXT_PIPELINE_ROBUSTNESS_SPEC_VERSION 1 +#define VK_EXT_PIPELINE_ROBUSTNESS_EXTENSION_NAME "VK_EXT_pipeline_robustness" + +typedef enum VkPipelineRobustnessBufferBehaviorEXT { + VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DEVICE_DEFAULT_EXT = 0, + VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DISABLED_EXT = 1, + VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_EXT = 2, + VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_2_EXT = 3, + VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_MAX_ENUM_EXT = 0x7FFFFFFF +} VkPipelineRobustnessBufferBehaviorEXT; + +typedef enum VkPipelineRobustnessImageBehaviorEXT { + VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_DEVICE_DEFAULT_EXT = 0, + VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_DISABLED_EXT = 1, + VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_ROBUST_IMAGE_ACCESS_EXT = 2, + VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_ROBUST_IMAGE_ACCESS_2_EXT = 3, + VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_MAX_ENUM_EXT = 0x7FFFFFFF +} VkPipelineRobustnessImageBehaviorEXT; +typedef struct VkPhysicalDevicePipelineRobustnessFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 pipelineRobustness; +} VkPhysicalDevicePipelineRobustnessFeaturesEXT; + +typedef struct VkPhysicalDevicePipelineRobustnessPropertiesEXT { + VkStructureType sType; + void* pNext; + VkPipelineRobustnessBufferBehaviorEXT defaultRobustnessStorageBuffers; + VkPipelineRobustnessBufferBehaviorEXT defaultRobustnessUniformBuffers; + VkPipelineRobustnessBufferBehaviorEXT defaultRobustnessVertexInputs; + VkPipelineRobustnessImageBehaviorEXT defaultRobustnessImages; +} VkPhysicalDevicePipelineRobustnessPropertiesEXT; + +typedef struct VkPipelineRobustnessCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkPipelineRobustnessBufferBehaviorEXT storageBuffers; + VkPipelineRobustnessBufferBehaviorEXT uniformBuffers; + VkPipelineRobustnessBufferBehaviorEXT vertexInputs; + VkPipelineRobustnessImageBehaviorEXT images; +} VkPipelineRobustnessCreateInfoEXT; + + + +// VK_EXT_conditional_rendering is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_conditional_rendering 1 +#define VK_EXT_CONDITIONAL_RENDERING_SPEC_VERSION 2 +#define VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME "VK_EXT_conditional_rendering" + +typedef enum VkConditionalRenderingFlagBitsEXT { + VK_CONDITIONAL_RENDERING_INVERTED_BIT_EXT = 0x00000001, + VK_CONDITIONAL_RENDERING_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkConditionalRenderingFlagBitsEXT; +typedef VkFlags VkConditionalRenderingFlagsEXT; +typedef struct VkConditionalRenderingBeginInfoEXT { + VkStructureType sType; + const void* pNext; + VkBuffer buffer; + VkDeviceSize offset; + VkConditionalRenderingFlagsEXT flags; +} VkConditionalRenderingBeginInfoEXT; + +typedef struct VkPhysicalDeviceConditionalRenderingFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 conditionalRendering; + VkBool32 inheritedConditionalRendering; +} VkPhysicalDeviceConditionalRenderingFeaturesEXT; + +typedef struct VkCommandBufferInheritanceConditionalRenderingInfoEXT { + VkStructureType sType; + const void* pNext; + VkBool32 conditionalRenderingEnable; +} VkCommandBufferInheritanceConditionalRenderingInfoEXT; + +typedef void (VKAPI_PTR *PFN_vkCmdBeginConditionalRenderingEXT)(VkCommandBuffer commandBuffer, const VkConditionalRenderingBeginInfoEXT* pConditionalRenderingBegin); +typedef void (VKAPI_PTR *PFN_vkCmdEndConditionalRenderingEXT)(VkCommandBuffer commandBuffer); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdBeginConditionalRenderingEXT( + VkCommandBuffer commandBuffer, + const VkConditionalRenderingBeginInfoEXT* pConditionalRenderingBegin); + +VKAPI_ATTR void VKAPI_CALL vkCmdEndConditionalRenderingEXT( + VkCommandBuffer commandBuffer); +#endif + + +// VK_NV_clip_space_w_scaling is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_clip_space_w_scaling 1 +#define VK_NV_CLIP_SPACE_W_SCALING_SPEC_VERSION 1 +#define VK_NV_CLIP_SPACE_W_SCALING_EXTENSION_NAME "VK_NV_clip_space_w_scaling" +typedef struct VkViewportWScalingNV { + float xcoeff; + float ycoeff; +} VkViewportWScalingNV; + +typedef struct VkPipelineViewportWScalingStateCreateInfoNV { + VkStructureType sType; + const void* pNext; + VkBool32 viewportWScalingEnable; + uint32_t viewportCount; + const VkViewportWScalingNV* pViewportWScalings; +} VkPipelineViewportWScalingStateCreateInfoNV; + +typedef void (VKAPI_PTR *PFN_vkCmdSetViewportWScalingNV)(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkViewportWScalingNV* pViewportWScalings); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdSetViewportWScalingNV( + VkCommandBuffer commandBuffer, + uint32_t firstViewport, + uint32_t viewportCount, + const VkViewportWScalingNV* pViewportWScalings); +#endif + + +// VK_EXT_direct_mode_display is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_direct_mode_display 1 +#define VK_EXT_DIRECT_MODE_DISPLAY_SPEC_VERSION 1 +#define VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME "VK_EXT_direct_mode_display" +typedef VkResult (VKAPI_PTR *PFN_vkReleaseDisplayEXT)(VkPhysicalDevice physicalDevice, VkDisplayKHR display); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkReleaseDisplayEXT( + VkPhysicalDevice physicalDevice, + VkDisplayKHR display); +#endif + + +// VK_EXT_display_surface_counter is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_display_surface_counter 1 +#define VK_EXT_DISPLAY_SURFACE_COUNTER_SPEC_VERSION 1 +#define VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME "VK_EXT_display_surface_counter" + +typedef enum VkSurfaceCounterFlagBitsEXT { + VK_SURFACE_COUNTER_VBLANK_BIT_EXT = 0x00000001, + VK_SURFACE_COUNTER_VBLANK_EXT = VK_SURFACE_COUNTER_VBLANK_BIT_EXT, + VK_SURFACE_COUNTER_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkSurfaceCounterFlagBitsEXT; +typedef VkFlags VkSurfaceCounterFlagsEXT; +typedef struct VkSurfaceCapabilities2EXT { + VkStructureType sType; + void* pNext; + uint32_t minImageCount; + uint32_t maxImageCount; + VkExtent2D currentExtent; + VkExtent2D minImageExtent; + VkExtent2D maxImageExtent; + uint32_t maxImageArrayLayers; + VkSurfaceTransformFlagsKHR supportedTransforms; + VkSurfaceTransformFlagBitsKHR currentTransform; + VkCompositeAlphaFlagsKHR supportedCompositeAlpha; + VkImageUsageFlags supportedUsageFlags; + VkSurfaceCounterFlagsEXT supportedSurfaceCounters; +} VkSurfaceCapabilities2EXT; + +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceCapabilities2EXT)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilities2EXT* pSurfaceCapabilities); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilities2EXT( + VkPhysicalDevice physicalDevice, + VkSurfaceKHR surface, + VkSurfaceCapabilities2EXT* pSurfaceCapabilities); +#endif + + +// VK_EXT_display_control is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_display_control 1 +#define VK_EXT_DISPLAY_CONTROL_SPEC_VERSION 1 +#define VK_EXT_DISPLAY_CONTROL_EXTENSION_NAME "VK_EXT_display_control" + +typedef enum VkDisplayPowerStateEXT { + VK_DISPLAY_POWER_STATE_OFF_EXT = 0, + VK_DISPLAY_POWER_STATE_SUSPEND_EXT = 1, + VK_DISPLAY_POWER_STATE_ON_EXT = 2, + VK_DISPLAY_POWER_STATE_MAX_ENUM_EXT = 0x7FFFFFFF +} VkDisplayPowerStateEXT; + +typedef enum VkDeviceEventTypeEXT { + VK_DEVICE_EVENT_TYPE_DISPLAY_HOTPLUG_EXT = 0, + VK_DEVICE_EVENT_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF +} VkDeviceEventTypeEXT; + +typedef enum VkDisplayEventTypeEXT { + VK_DISPLAY_EVENT_TYPE_FIRST_PIXEL_OUT_EXT = 0, + VK_DISPLAY_EVENT_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF +} VkDisplayEventTypeEXT; +typedef struct VkDisplayPowerInfoEXT { + VkStructureType sType; + const void* pNext; + VkDisplayPowerStateEXT powerState; +} VkDisplayPowerInfoEXT; + +typedef struct VkDeviceEventInfoEXT { + VkStructureType sType; + const void* pNext; + VkDeviceEventTypeEXT deviceEvent; +} VkDeviceEventInfoEXT; + +typedef struct VkDisplayEventInfoEXT { + VkStructureType sType; + const void* pNext; + VkDisplayEventTypeEXT displayEvent; +} VkDisplayEventInfoEXT; + +typedef struct VkSwapchainCounterCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkSurfaceCounterFlagsEXT surfaceCounters; +} VkSwapchainCounterCreateInfoEXT; + +typedef VkResult (VKAPI_PTR *PFN_vkDisplayPowerControlEXT)(VkDevice device, VkDisplayKHR display, const VkDisplayPowerInfoEXT* pDisplayPowerInfo); +typedef VkResult (VKAPI_PTR *PFN_vkRegisterDeviceEventEXT)(VkDevice device, const VkDeviceEventInfoEXT* pDeviceEventInfo, const VkAllocationCallbacks* pAllocator, VkFence* pFence); +typedef VkResult (VKAPI_PTR *PFN_vkRegisterDisplayEventEXT)(VkDevice device, VkDisplayKHR display, const VkDisplayEventInfoEXT* pDisplayEventInfo, const VkAllocationCallbacks* pAllocator, VkFence* pFence); +typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainCounterEXT)(VkDevice device, VkSwapchainKHR swapchain, VkSurfaceCounterFlagBitsEXT counter, uint64_t* pCounterValue); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkDisplayPowerControlEXT( + VkDevice device, + VkDisplayKHR display, + const VkDisplayPowerInfoEXT* pDisplayPowerInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkRegisterDeviceEventEXT( + VkDevice device, + const VkDeviceEventInfoEXT* pDeviceEventInfo, + const VkAllocationCallbacks* pAllocator, + VkFence* pFence); + +VKAPI_ATTR VkResult VKAPI_CALL vkRegisterDisplayEventEXT( + VkDevice device, + VkDisplayKHR display, + const VkDisplayEventInfoEXT* pDisplayEventInfo, + const VkAllocationCallbacks* pAllocator, + VkFence* pFence); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainCounterEXT( + VkDevice device, + VkSwapchainKHR swapchain, + VkSurfaceCounterFlagBitsEXT counter, + uint64_t* pCounterValue); +#endif + + +// VK_GOOGLE_display_timing is a preprocessor guard. Do not pass it to API calls. +#define VK_GOOGLE_display_timing 1 +#define VK_GOOGLE_DISPLAY_TIMING_SPEC_VERSION 1 +#define VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME "VK_GOOGLE_display_timing" +typedef struct VkRefreshCycleDurationGOOGLE { + uint64_t refreshDuration; +} VkRefreshCycleDurationGOOGLE; + +typedef struct VkPastPresentationTimingGOOGLE { + uint32_t presentID; + uint64_t desiredPresentTime; + uint64_t actualPresentTime; + uint64_t earliestPresentTime; + uint64_t presentMargin; +} VkPastPresentationTimingGOOGLE; + +typedef struct VkPresentTimeGOOGLE { + uint32_t presentID; + uint64_t desiredPresentTime; +} VkPresentTimeGOOGLE; + +typedef struct VkPresentTimesInfoGOOGLE { + VkStructureType sType; + const void* pNext; + uint32_t swapchainCount; + const VkPresentTimeGOOGLE* pTimes; +} VkPresentTimesInfoGOOGLE; + +typedef VkResult (VKAPI_PTR *PFN_vkGetRefreshCycleDurationGOOGLE)(VkDevice device, VkSwapchainKHR swapchain, VkRefreshCycleDurationGOOGLE* pDisplayTimingProperties); +typedef VkResult (VKAPI_PTR *PFN_vkGetPastPresentationTimingGOOGLE)(VkDevice device, VkSwapchainKHR swapchain, uint32_t* pPresentationTimingCount, VkPastPresentationTimingGOOGLE* pPresentationTimings); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetRefreshCycleDurationGOOGLE( + VkDevice device, + VkSwapchainKHR swapchain, + VkRefreshCycleDurationGOOGLE* pDisplayTimingProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPastPresentationTimingGOOGLE( + VkDevice device, + VkSwapchainKHR swapchain, + uint32_t* pPresentationTimingCount, + VkPastPresentationTimingGOOGLE* pPresentationTimings); +#endif + + +// VK_NV_sample_mask_override_coverage is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_sample_mask_override_coverage 1 +#define VK_NV_SAMPLE_MASK_OVERRIDE_COVERAGE_SPEC_VERSION 1 +#define VK_NV_SAMPLE_MASK_OVERRIDE_COVERAGE_EXTENSION_NAME "VK_NV_sample_mask_override_coverage" + + +// VK_NV_geometry_shader_passthrough is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_geometry_shader_passthrough 1 +#define VK_NV_GEOMETRY_SHADER_PASSTHROUGH_SPEC_VERSION 1 +#define VK_NV_GEOMETRY_SHADER_PASSTHROUGH_EXTENSION_NAME "VK_NV_geometry_shader_passthrough" + + +// VK_NV_viewport_array2 is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_viewport_array2 1 +#define VK_NV_VIEWPORT_ARRAY_2_SPEC_VERSION 1 +#define VK_NV_VIEWPORT_ARRAY_2_EXTENSION_NAME "VK_NV_viewport_array2" +#define VK_NV_VIEWPORT_ARRAY2_SPEC_VERSION VK_NV_VIEWPORT_ARRAY_2_SPEC_VERSION +#define VK_NV_VIEWPORT_ARRAY2_EXTENSION_NAME VK_NV_VIEWPORT_ARRAY_2_EXTENSION_NAME + + +// VK_NVX_multiview_per_view_attributes is a preprocessor guard. Do not pass it to API calls. +#define VK_NVX_multiview_per_view_attributes 1 +#define VK_NVX_MULTIVIEW_PER_VIEW_ATTRIBUTES_SPEC_VERSION 1 +#define VK_NVX_MULTIVIEW_PER_VIEW_ATTRIBUTES_EXTENSION_NAME "VK_NVX_multiview_per_view_attributes" +typedef struct VkPhysicalDeviceMultiviewPerViewAttributesPropertiesNVX { + VkStructureType sType; + void* pNext; + VkBool32 perViewPositionAllComponents; +} VkPhysicalDeviceMultiviewPerViewAttributesPropertiesNVX; + + + +// VK_NV_viewport_swizzle is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_viewport_swizzle 1 +#define VK_NV_VIEWPORT_SWIZZLE_SPEC_VERSION 1 +#define VK_NV_VIEWPORT_SWIZZLE_EXTENSION_NAME "VK_NV_viewport_swizzle" + +typedef enum VkViewportCoordinateSwizzleNV { + VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_X_NV = 0, + VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_X_NV = 1, + VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Y_NV = 2, + VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_Y_NV = 3, + VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_Z_NV = 4, + VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_Z_NV = 5, + VK_VIEWPORT_COORDINATE_SWIZZLE_POSITIVE_W_NV = 6, + VK_VIEWPORT_COORDINATE_SWIZZLE_NEGATIVE_W_NV = 7, + VK_VIEWPORT_COORDINATE_SWIZZLE_MAX_ENUM_NV = 0x7FFFFFFF +} VkViewportCoordinateSwizzleNV; +typedef VkFlags VkPipelineViewportSwizzleStateCreateFlagsNV; +typedef struct VkViewportSwizzleNV { + VkViewportCoordinateSwizzleNV x; + VkViewportCoordinateSwizzleNV y; + VkViewportCoordinateSwizzleNV z; + VkViewportCoordinateSwizzleNV w; +} VkViewportSwizzleNV; + +typedef struct VkPipelineViewportSwizzleStateCreateInfoNV { + VkStructureType sType; + const void* pNext; + VkPipelineViewportSwizzleStateCreateFlagsNV flags; + uint32_t viewportCount; + const VkViewportSwizzleNV* pViewportSwizzles; +} VkPipelineViewportSwizzleStateCreateInfoNV; + + + +// VK_EXT_discard_rectangles is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_discard_rectangles 1 +#define VK_EXT_DISCARD_RECTANGLES_SPEC_VERSION 2 +#define VK_EXT_DISCARD_RECTANGLES_EXTENSION_NAME "VK_EXT_discard_rectangles" + +typedef enum VkDiscardRectangleModeEXT { + VK_DISCARD_RECTANGLE_MODE_INCLUSIVE_EXT = 0, + VK_DISCARD_RECTANGLE_MODE_EXCLUSIVE_EXT = 1, + VK_DISCARD_RECTANGLE_MODE_MAX_ENUM_EXT = 0x7FFFFFFF +} VkDiscardRectangleModeEXT; +typedef VkFlags VkPipelineDiscardRectangleStateCreateFlagsEXT; +typedef struct VkPhysicalDeviceDiscardRectanglePropertiesEXT { + VkStructureType sType; + void* pNext; + uint32_t maxDiscardRectangles; +} VkPhysicalDeviceDiscardRectanglePropertiesEXT; + +typedef struct VkPipelineDiscardRectangleStateCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkPipelineDiscardRectangleStateCreateFlagsEXT flags; + VkDiscardRectangleModeEXT discardRectangleMode; + uint32_t discardRectangleCount; + const VkRect2D* pDiscardRectangles; +} VkPipelineDiscardRectangleStateCreateInfoEXT; + +typedef void (VKAPI_PTR *PFN_vkCmdSetDiscardRectangleEXT)(VkCommandBuffer commandBuffer, uint32_t firstDiscardRectangle, uint32_t discardRectangleCount, const VkRect2D* pDiscardRectangles); +typedef void (VKAPI_PTR *PFN_vkCmdSetDiscardRectangleEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 discardRectangleEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetDiscardRectangleModeEXT)(VkCommandBuffer commandBuffer, VkDiscardRectangleModeEXT discardRectangleMode); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdSetDiscardRectangleEXT( + VkCommandBuffer commandBuffer, + uint32_t firstDiscardRectangle, + uint32_t discardRectangleCount, + const VkRect2D* pDiscardRectangles); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDiscardRectangleEnableEXT( + VkCommandBuffer commandBuffer, + VkBool32 discardRectangleEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDiscardRectangleModeEXT( + VkCommandBuffer commandBuffer, + VkDiscardRectangleModeEXT discardRectangleMode); +#endif + + +// VK_EXT_conservative_rasterization is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_conservative_rasterization 1 +#define VK_EXT_CONSERVATIVE_RASTERIZATION_SPEC_VERSION 1 +#define VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME "VK_EXT_conservative_rasterization" + +typedef enum VkConservativeRasterizationModeEXT { + VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT = 0, + VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT = 1, + VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT = 2, + VK_CONSERVATIVE_RASTERIZATION_MODE_MAX_ENUM_EXT = 0x7FFFFFFF +} VkConservativeRasterizationModeEXT; +typedef VkFlags VkPipelineRasterizationConservativeStateCreateFlagsEXT; +typedef struct VkPhysicalDeviceConservativeRasterizationPropertiesEXT { + VkStructureType sType; + void* pNext; + float primitiveOverestimationSize; + float maxExtraPrimitiveOverestimationSize; + float extraPrimitiveOverestimationSizeGranularity; + VkBool32 primitiveUnderestimation; + VkBool32 conservativePointAndLineRasterization; + VkBool32 degenerateTrianglesRasterized; + VkBool32 degenerateLinesRasterized; + VkBool32 fullyCoveredFragmentShaderInputVariable; + VkBool32 conservativeRasterizationPostDepthCoverage; +} VkPhysicalDeviceConservativeRasterizationPropertiesEXT; + +typedef struct VkPipelineRasterizationConservativeStateCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkPipelineRasterizationConservativeStateCreateFlagsEXT flags; + VkConservativeRasterizationModeEXT conservativeRasterizationMode; + float extraPrimitiveOverestimationSize; +} VkPipelineRasterizationConservativeStateCreateInfoEXT; + + + +// VK_EXT_depth_clip_enable is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_depth_clip_enable 1 +#define VK_EXT_DEPTH_CLIP_ENABLE_SPEC_VERSION 1 +#define VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME "VK_EXT_depth_clip_enable" +typedef VkFlags VkPipelineRasterizationDepthClipStateCreateFlagsEXT; +typedef struct VkPhysicalDeviceDepthClipEnableFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 depthClipEnable; +} VkPhysicalDeviceDepthClipEnableFeaturesEXT; + +typedef struct VkPipelineRasterizationDepthClipStateCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkPipelineRasterizationDepthClipStateCreateFlagsEXT flags; + VkBool32 depthClipEnable; +} VkPipelineRasterizationDepthClipStateCreateInfoEXT; + + + +// VK_EXT_swapchain_colorspace is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_swapchain_colorspace 1 +#define VK_EXT_SWAPCHAIN_COLOR_SPACE_SPEC_VERSION 4 +#define VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME "VK_EXT_swapchain_colorspace" + + +// VK_EXT_hdr_metadata is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_hdr_metadata 1 +#define VK_EXT_HDR_METADATA_SPEC_VERSION 2 +#define VK_EXT_HDR_METADATA_EXTENSION_NAME "VK_EXT_hdr_metadata" +typedef struct VkXYColorEXT { + float x; + float y; +} VkXYColorEXT; + +typedef struct VkHdrMetadataEXT { + VkStructureType sType; + const void* pNext; + VkXYColorEXT displayPrimaryRed; + VkXYColorEXT displayPrimaryGreen; + VkXYColorEXT displayPrimaryBlue; + VkXYColorEXT whitePoint; + float maxLuminance; + float minLuminance; + float maxContentLightLevel; + float maxFrameAverageLightLevel; +} VkHdrMetadataEXT; + +typedef void (VKAPI_PTR *PFN_vkSetHdrMetadataEXT)(VkDevice device, uint32_t swapchainCount, const VkSwapchainKHR* pSwapchains, const VkHdrMetadataEXT* pMetadata); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkSetHdrMetadataEXT( + VkDevice device, + uint32_t swapchainCount, + const VkSwapchainKHR* pSwapchains, + const VkHdrMetadataEXT* pMetadata); +#endif + + +// VK_IMG_relaxed_line_rasterization is a preprocessor guard. Do not pass it to API calls. +#define VK_IMG_relaxed_line_rasterization 1 +#define VK_IMG_RELAXED_LINE_RASTERIZATION_SPEC_VERSION 1 +#define VK_IMG_RELAXED_LINE_RASTERIZATION_EXTENSION_NAME "VK_IMG_relaxed_line_rasterization" +typedef struct VkPhysicalDeviceRelaxedLineRasterizationFeaturesIMG { + VkStructureType sType; + void* pNext; + VkBool32 relaxedLineRasterization; +} VkPhysicalDeviceRelaxedLineRasterizationFeaturesIMG; + + + +// VK_EXT_external_memory_dma_buf is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_external_memory_dma_buf 1 +#define VK_EXT_EXTERNAL_MEMORY_DMA_BUF_SPEC_VERSION 1 +#define VK_EXT_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_NAME "VK_EXT_external_memory_dma_buf" + + +// VK_EXT_queue_family_foreign is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_queue_family_foreign 1 +#define VK_EXT_QUEUE_FAMILY_FOREIGN_SPEC_VERSION 1 +#define VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME "VK_EXT_queue_family_foreign" +#define VK_QUEUE_FAMILY_FOREIGN_EXT (~2U) + + +// VK_EXT_debug_utils is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_debug_utils 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDebugUtilsMessengerEXT) +#define VK_EXT_DEBUG_UTILS_SPEC_VERSION 2 +#define VK_EXT_DEBUG_UTILS_EXTENSION_NAME "VK_EXT_debug_utils" +typedef VkFlags VkDebugUtilsMessengerCallbackDataFlagsEXT; + +typedef enum VkDebugUtilsMessageSeverityFlagBitsEXT { + VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT = 0x00000001, + VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT = 0x00000010, + VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT = 0x00000100, + VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT = 0x00001000, + VK_DEBUG_UTILS_MESSAGE_SEVERITY_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkDebugUtilsMessageSeverityFlagBitsEXT; + +typedef enum VkDebugUtilsMessageTypeFlagBitsEXT { + VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT = 0x00000001, + VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT = 0x00000002, + VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT = 0x00000004, + VK_DEBUG_UTILS_MESSAGE_TYPE_DEVICE_ADDRESS_BINDING_BIT_EXT = 0x00000008, + VK_DEBUG_UTILS_MESSAGE_TYPE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkDebugUtilsMessageTypeFlagBitsEXT; +typedef VkFlags VkDebugUtilsMessageTypeFlagsEXT; +typedef VkFlags VkDebugUtilsMessageSeverityFlagsEXT; +typedef VkFlags VkDebugUtilsMessengerCreateFlagsEXT; +typedef struct VkDebugUtilsLabelEXT { + VkStructureType sType; + const void* pNext; + const char* pLabelName; + float color[4]; +} VkDebugUtilsLabelEXT; + +typedef struct VkDebugUtilsObjectNameInfoEXT { + VkStructureType sType; + const void* pNext; + VkObjectType objectType; + uint64_t objectHandle; + const char* pObjectName; +} VkDebugUtilsObjectNameInfoEXT; + +typedef struct VkDebugUtilsMessengerCallbackDataEXT { + VkStructureType sType; + const void* pNext; + VkDebugUtilsMessengerCallbackDataFlagsEXT flags; + const char* pMessageIdName; + int32_t messageIdNumber; + const char* pMessage; + uint32_t queueLabelCount; + const VkDebugUtilsLabelEXT* pQueueLabels; + uint32_t cmdBufLabelCount; + const VkDebugUtilsLabelEXT* pCmdBufLabels; + uint32_t objectCount; + const VkDebugUtilsObjectNameInfoEXT* pObjects; +} VkDebugUtilsMessengerCallbackDataEXT; + +typedef VkBool32 (VKAPI_PTR *PFN_vkDebugUtilsMessengerCallbackEXT)( + VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, + VkDebugUtilsMessageTypeFlagsEXT messageTypes, + const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, + void* pUserData); + +typedef struct VkDebugUtilsMessengerCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkDebugUtilsMessengerCreateFlagsEXT flags; + VkDebugUtilsMessageSeverityFlagsEXT messageSeverity; + VkDebugUtilsMessageTypeFlagsEXT messageType; + PFN_vkDebugUtilsMessengerCallbackEXT pfnUserCallback; + void* pUserData; +} VkDebugUtilsMessengerCreateInfoEXT; + +typedef struct VkDebugUtilsObjectTagInfoEXT { + VkStructureType sType; + const void* pNext; + VkObjectType objectType; + uint64_t objectHandle; + uint64_t tagName; + size_t tagSize; + const void* pTag; +} VkDebugUtilsObjectTagInfoEXT; + +typedef VkResult (VKAPI_PTR *PFN_vkSetDebugUtilsObjectNameEXT)(VkDevice device, const VkDebugUtilsObjectNameInfoEXT* pNameInfo); +typedef VkResult (VKAPI_PTR *PFN_vkSetDebugUtilsObjectTagEXT)(VkDevice device, const VkDebugUtilsObjectTagInfoEXT* pTagInfo); +typedef void (VKAPI_PTR *PFN_vkQueueBeginDebugUtilsLabelEXT)(VkQueue queue, const VkDebugUtilsLabelEXT* pLabelInfo); +typedef void (VKAPI_PTR *PFN_vkQueueEndDebugUtilsLabelEXT)(VkQueue queue); +typedef void (VKAPI_PTR *PFN_vkQueueInsertDebugUtilsLabelEXT)(VkQueue queue, const VkDebugUtilsLabelEXT* pLabelInfo); +typedef void (VKAPI_PTR *PFN_vkCmdBeginDebugUtilsLabelEXT)(VkCommandBuffer commandBuffer, const VkDebugUtilsLabelEXT* pLabelInfo); +typedef void (VKAPI_PTR *PFN_vkCmdEndDebugUtilsLabelEXT)(VkCommandBuffer commandBuffer); +typedef void (VKAPI_PTR *PFN_vkCmdInsertDebugUtilsLabelEXT)(VkCommandBuffer commandBuffer, const VkDebugUtilsLabelEXT* pLabelInfo); +typedef VkResult (VKAPI_PTR *PFN_vkCreateDebugUtilsMessengerEXT)(VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugUtilsMessengerEXT* pMessenger); +typedef void (VKAPI_PTR *PFN_vkDestroyDebugUtilsMessengerEXT)(VkInstance instance, VkDebugUtilsMessengerEXT messenger, const VkAllocationCallbacks* pAllocator); +typedef void (VKAPI_PTR *PFN_vkSubmitDebugUtilsMessageEXT)(VkInstance instance, VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageTypes, const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkSetDebugUtilsObjectNameEXT( + VkDevice device, + const VkDebugUtilsObjectNameInfoEXT* pNameInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkSetDebugUtilsObjectTagEXT( + VkDevice device, + const VkDebugUtilsObjectTagInfoEXT* pTagInfo); + +VKAPI_ATTR void VKAPI_CALL vkQueueBeginDebugUtilsLabelEXT( + VkQueue queue, + const VkDebugUtilsLabelEXT* pLabelInfo); + +VKAPI_ATTR void VKAPI_CALL vkQueueEndDebugUtilsLabelEXT( + VkQueue queue); + +VKAPI_ATTR void VKAPI_CALL vkQueueInsertDebugUtilsLabelEXT( + VkQueue queue, + const VkDebugUtilsLabelEXT* pLabelInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdBeginDebugUtilsLabelEXT( + VkCommandBuffer commandBuffer, + const VkDebugUtilsLabelEXT* pLabelInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdEndDebugUtilsLabelEXT( + VkCommandBuffer commandBuffer); + +VKAPI_ATTR void VKAPI_CALL vkCmdInsertDebugUtilsLabelEXT( + VkCommandBuffer commandBuffer, + const VkDebugUtilsLabelEXT* pLabelInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugUtilsMessengerEXT( + VkInstance instance, + const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkDebugUtilsMessengerEXT* pMessenger); + +VKAPI_ATTR void VKAPI_CALL vkDestroyDebugUtilsMessengerEXT( + VkInstance instance, + VkDebugUtilsMessengerEXT messenger, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR void VKAPI_CALL vkSubmitDebugUtilsMessageEXT( + VkInstance instance, + VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, + VkDebugUtilsMessageTypeFlagsEXT messageTypes, + const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData); +#endif + + +// VK_EXT_sampler_filter_minmax is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_sampler_filter_minmax 1 +#define VK_EXT_SAMPLER_FILTER_MINMAX_SPEC_VERSION 2 +#define VK_EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME "VK_EXT_sampler_filter_minmax" +typedef VkSamplerReductionMode VkSamplerReductionModeEXT; + +typedef VkSamplerReductionModeCreateInfo VkSamplerReductionModeCreateInfoEXT; + +typedef VkPhysicalDeviceSamplerFilterMinmaxProperties VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT; + + + +// VK_AMD_gpu_shader_int16 is a preprocessor guard. Do not pass it to API calls. +#define VK_AMD_gpu_shader_int16 1 +#define VK_AMD_GPU_SHADER_INT16_SPEC_VERSION 2 +#define VK_AMD_GPU_SHADER_INT16_EXTENSION_NAME "VK_AMD_gpu_shader_int16" + + +// VK_AMD_mixed_attachment_samples is a preprocessor guard. Do not pass it to API calls. +#define VK_AMD_mixed_attachment_samples 1 +#define VK_AMD_MIXED_ATTACHMENT_SAMPLES_SPEC_VERSION 1 +#define VK_AMD_MIXED_ATTACHMENT_SAMPLES_EXTENSION_NAME "VK_AMD_mixed_attachment_samples" + + +// VK_AMD_shader_fragment_mask is a preprocessor guard. Do not pass it to API calls. +#define VK_AMD_shader_fragment_mask 1 +#define VK_AMD_SHADER_FRAGMENT_MASK_SPEC_VERSION 1 +#define VK_AMD_SHADER_FRAGMENT_MASK_EXTENSION_NAME "VK_AMD_shader_fragment_mask" + + +// VK_EXT_inline_uniform_block is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_inline_uniform_block 1 +#define VK_EXT_INLINE_UNIFORM_BLOCK_SPEC_VERSION 1 +#define VK_EXT_INLINE_UNIFORM_BLOCK_EXTENSION_NAME "VK_EXT_inline_uniform_block" +typedef VkPhysicalDeviceInlineUniformBlockFeatures VkPhysicalDeviceInlineUniformBlockFeaturesEXT; + +typedef VkPhysicalDeviceInlineUniformBlockProperties VkPhysicalDeviceInlineUniformBlockPropertiesEXT; + +typedef VkWriteDescriptorSetInlineUniformBlock VkWriteDescriptorSetInlineUniformBlockEXT; + +typedef VkDescriptorPoolInlineUniformBlockCreateInfo VkDescriptorPoolInlineUniformBlockCreateInfoEXT; + + + +// VK_EXT_shader_stencil_export is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_shader_stencil_export 1 +#define VK_EXT_SHADER_STENCIL_EXPORT_SPEC_VERSION 1 +#define VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME "VK_EXT_shader_stencil_export" + + +// VK_EXT_sample_locations is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_sample_locations 1 +#define VK_EXT_SAMPLE_LOCATIONS_SPEC_VERSION 1 +#define VK_EXT_SAMPLE_LOCATIONS_EXTENSION_NAME "VK_EXT_sample_locations" +typedef struct VkSampleLocationEXT { + float x; + float y; +} VkSampleLocationEXT; + +typedef struct VkSampleLocationsInfoEXT { + VkStructureType sType; + const void* pNext; + VkSampleCountFlagBits sampleLocationsPerPixel; + VkExtent2D sampleLocationGridSize; + uint32_t sampleLocationsCount; + const VkSampleLocationEXT* pSampleLocations; +} VkSampleLocationsInfoEXT; + +typedef struct VkAttachmentSampleLocationsEXT { + uint32_t attachmentIndex; + VkSampleLocationsInfoEXT sampleLocationsInfo; +} VkAttachmentSampleLocationsEXT; + +typedef struct VkSubpassSampleLocationsEXT { + uint32_t subpassIndex; + VkSampleLocationsInfoEXT sampleLocationsInfo; +} VkSubpassSampleLocationsEXT; + +typedef struct VkRenderPassSampleLocationsBeginInfoEXT { + VkStructureType sType; + const void* pNext; + uint32_t attachmentInitialSampleLocationsCount; + const VkAttachmentSampleLocationsEXT* pAttachmentInitialSampleLocations; + uint32_t postSubpassSampleLocationsCount; + const VkSubpassSampleLocationsEXT* pPostSubpassSampleLocations; +} VkRenderPassSampleLocationsBeginInfoEXT; + +typedef struct VkPipelineSampleLocationsStateCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkBool32 sampleLocationsEnable; + VkSampleLocationsInfoEXT sampleLocationsInfo; +} VkPipelineSampleLocationsStateCreateInfoEXT; + +typedef struct VkPhysicalDeviceSampleLocationsPropertiesEXT { + VkStructureType sType; + void* pNext; + VkSampleCountFlags sampleLocationSampleCounts; + VkExtent2D maxSampleLocationGridSize; + float sampleLocationCoordinateRange[2]; + uint32_t sampleLocationSubPixelBits; + VkBool32 variableSampleLocations; +} VkPhysicalDeviceSampleLocationsPropertiesEXT; + +typedef struct VkMultisamplePropertiesEXT { + VkStructureType sType; + void* pNext; + VkExtent2D maxSampleLocationGridSize; +} VkMultisamplePropertiesEXT; + +typedef void (VKAPI_PTR *PFN_vkCmdSetSampleLocationsEXT)(VkCommandBuffer commandBuffer, const VkSampleLocationsInfoEXT* pSampleLocationsInfo); +typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceMultisamplePropertiesEXT)(VkPhysicalDevice physicalDevice, VkSampleCountFlagBits samples, VkMultisamplePropertiesEXT* pMultisampleProperties); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdSetSampleLocationsEXT( + VkCommandBuffer commandBuffer, + const VkSampleLocationsInfoEXT* pSampleLocationsInfo); + +VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMultisamplePropertiesEXT( + VkPhysicalDevice physicalDevice, + VkSampleCountFlagBits samples, + VkMultisamplePropertiesEXT* pMultisampleProperties); +#endif + + +// VK_EXT_blend_operation_advanced is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_blend_operation_advanced 1 +#define VK_EXT_BLEND_OPERATION_ADVANCED_SPEC_VERSION 2 +#define VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME "VK_EXT_blend_operation_advanced" + +typedef enum VkBlendOverlapEXT { + VK_BLEND_OVERLAP_UNCORRELATED_EXT = 0, + VK_BLEND_OVERLAP_DISJOINT_EXT = 1, + VK_BLEND_OVERLAP_CONJOINT_EXT = 2, + VK_BLEND_OVERLAP_MAX_ENUM_EXT = 0x7FFFFFFF +} VkBlendOverlapEXT; +typedef struct VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 advancedBlendCoherentOperations; +} VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT; + +typedef struct VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT { + VkStructureType sType; + void* pNext; + uint32_t advancedBlendMaxColorAttachments; + VkBool32 advancedBlendIndependentBlend; + VkBool32 advancedBlendNonPremultipliedSrcColor; + VkBool32 advancedBlendNonPremultipliedDstColor; + VkBool32 advancedBlendCorrelatedOverlap; + VkBool32 advancedBlendAllOperations; +} VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT; + +typedef struct VkPipelineColorBlendAdvancedStateCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkBool32 srcPremultiplied; + VkBool32 dstPremultiplied; + VkBlendOverlapEXT blendOverlap; +} VkPipelineColorBlendAdvancedStateCreateInfoEXT; + + + +// VK_NV_fragment_coverage_to_color is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_fragment_coverage_to_color 1 +#define VK_NV_FRAGMENT_COVERAGE_TO_COLOR_SPEC_VERSION 1 +#define VK_NV_FRAGMENT_COVERAGE_TO_COLOR_EXTENSION_NAME "VK_NV_fragment_coverage_to_color" +typedef VkFlags VkPipelineCoverageToColorStateCreateFlagsNV; +typedef struct VkPipelineCoverageToColorStateCreateInfoNV { + VkStructureType sType; + const void* pNext; + VkPipelineCoverageToColorStateCreateFlagsNV flags; + VkBool32 coverageToColorEnable; + uint32_t coverageToColorLocation; +} VkPipelineCoverageToColorStateCreateInfoNV; + + + +// VK_NV_framebuffer_mixed_samples is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_framebuffer_mixed_samples 1 +#define VK_NV_FRAMEBUFFER_MIXED_SAMPLES_SPEC_VERSION 1 +#define VK_NV_FRAMEBUFFER_MIXED_SAMPLES_EXTENSION_NAME "VK_NV_framebuffer_mixed_samples" + +typedef enum VkCoverageModulationModeNV { + VK_COVERAGE_MODULATION_MODE_NONE_NV = 0, + VK_COVERAGE_MODULATION_MODE_RGB_NV = 1, + VK_COVERAGE_MODULATION_MODE_ALPHA_NV = 2, + VK_COVERAGE_MODULATION_MODE_RGBA_NV = 3, + VK_COVERAGE_MODULATION_MODE_MAX_ENUM_NV = 0x7FFFFFFF +} VkCoverageModulationModeNV; +typedef VkFlags VkPipelineCoverageModulationStateCreateFlagsNV; +typedef struct VkPipelineCoverageModulationStateCreateInfoNV { + VkStructureType sType; + const void* pNext; + VkPipelineCoverageModulationStateCreateFlagsNV flags; + VkCoverageModulationModeNV coverageModulationMode; + VkBool32 coverageModulationTableEnable; + uint32_t coverageModulationTableCount; + const float* pCoverageModulationTable; +} VkPipelineCoverageModulationStateCreateInfoNV; + + + +// VK_NV_fill_rectangle is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_fill_rectangle 1 +#define VK_NV_FILL_RECTANGLE_SPEC_VERSION 1 +#define VK_NV_FILL_RECTANGLE_EXTENSION_NAME "VK_NV_fill_rectangle" + + +// VK_NV_shader_sm_builtins is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_shader_sm_builtins 1 +#define VK_NV_SHADER_SM_BUILTINS_SPEC_VERSION 1 +#define VK_NV_SHADER_SM_BUILTINS_EXTENSION_NAME "VK_NV_shader_sm_builtins" +typedef struct VkPhysicalDeviceShaderSMBuiltinsPropertiesNV { + VkStructureType sType; + void* pNext; + uint32_t shaderSMCount; + uint32_t shaderWarpsPerSM; +} VkPhysicalDeviceShaderSMBuiltinsPropertiesNV; + +typedef struct VkPhysicalDeviceShaderSMBuiltinsFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 shaderSMBuiltins; +} VkPhysicalDeviceShaderSMBuiltinsFeaturesNV; + + + +// VK_EXT_post_depth_coverage is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_post_depth_coverage 1 +#define VK_EXT_POST_DEPTH_COVERAGE_SPEC_VERSION 1 +#define VK_EXT_POST_DEPTH_COVERAGE_EXTENSION_NAME "VK_EXT_post_depth_coverage" + + +// VK_EXT_image_drm_format_modifier is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_image_drm_format_modifier 1 +#define VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_SPEC_VERSION 2 +#define VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME "VK_EXT_image_drm_format_modifier" +typedef struct VkDrmFormatModifierPropertiesEXT { + uint64_t drmFormatModifier; + uint32_t drmFormatModifierPlaneCount; + VkFormatFeatureFlags drmFormatModifierTilingFeatures; +} VkDrmFormatModifierPropertiesEXT; + +typedef struct VkDrmFormatModifierPropertiesListEXT { + VkStructureType sType; + void* pNext; + uint32_t drmFormatModifierCount; + VkDrmFormatModifierPropertiesEXT* pDrmFormatModifierProperties; +} VkDrmFormatModifierPropertiesListEXT; + +typedef struct VkPhysicalDeviceImageDrmFormatModifierInfoEXT { + VkStructureType sType; + const void* pNext; + uint64_t drmFormatModifier; + VkSharingMode sharingMode; + uint32_t queueFamilyIndexCount; + const uint32_t* pQueueFamilyIndices; +} VkPhysicalDeviceImageDrmFormatModifierInfoEXT; + +typedef struct VkImageDrmFormatModifierListCreateInfoEXT { + VkStructureType sType; + const void* pNext; + uint32_t drmFormatModifierCount; + const uint64_t* pDrmFormatModifiers; +} VkImageDrmFormatModifierListCreateInfoEXT; + +typedef struct VkImageDrmFormatModifierExplicitCreateInfoEXT { + VkStructureType sType; + const void* pNext; + uint64_t drmFormatModifier; + uint32_t drmFormatModifierPlaneCount; + const VkSubresourceLayout* pPlaneLayouts; +} VkImageDrmFormatModifierExplicitCreateInfoEXT; + +typedef struct VkImageDrmFormatModifierPropertiesEXT { + VkStructureType sType; + void* pNext; + uint64_t drmFormatModifier; +} VkImageDrmFormatModifierPropertiesEXT; + +typedef struct VkDrmFormatModifierProperties2EXT { + uint64_t drmFormatModifier; + uint32_t drmFormatModifierPlaneCount; + VkFormatFeatureFlags2 drmFormatModifierTilingFeatures; +} VkDrmFormatModifierProperties2EXT; + +typedef struct VkDrmFormatModifierPropertiesList2EXT { + VkStructureType sType; + void* pNext; + uint32_t drmFormatModifierCount; + VkDrmFormatModifierProperties2EXT* pDrmFormatModifierProperties; +} VkDrmFormatModifierPropertiesList2EXT; + +typedef VkResult (VKAPI_PTR *PFN_vkGetImageDrmFormatModifierPropertiesEXT)(VkDevice device, VkImage image, VkImageDrmFormatModifierPropertiesEXT* pProperties); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetImageDrmFormatModifierPropertiesEXT( + VkDevice device, + VkImage image, + VkImageDrmFormatModifierPropertiesEXT* pProperties); +#endif + + +// VK_EXT_validation_cache is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_validation_cache 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkValidationCacheEXT) +#define VK_EXT_VALIDATION_CACHE_SPEC_VERSION 1 +#define VK_EXT_VALIDATION_CACHE_EXTENSION_NAME "VK_EXT_validation_cache" + +typedef enum VkValidationCacheHeaderVersionEXT { + VK_VALIDATION_CACHE_HEADER_VERSION_ONE_EXT = 1, + VK_VALIDATION_CACHE_HEADER_VERSION_MAX_ENUM_EXT = 0x7FFFFFFF +} VkValidationCacheHeaderVersionEXT; +typedef VkFlags VkValidationCacheCreateFlagsEXT; +typedef struct VkValidationCacheCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkValidationCacheCreateFlagsEXT flags; + size_t initialDataSize; + const void* pInitialData; +} VkValidationCacheCreateInfoEXT; + +typedef struct VkShaderModuleValidationCacheCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkValidationCacheEXT validationCache; +} VkShaderModuleValidationCacheCreateInfoEXT; + +typedef VkResult (VKAPI_PTR *PFN_vkCreateValidationCacheEXT)(VkDevice device, const VkValidationCacheCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkValidationCacheEXT* pValidationCache); +typedef void (VKAPI_PTR *PFN_vkDestroyValidationCacheEXT)(VkDevice device, VkValidationCacheEXT validationCache, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkMergeValidationCachesEXT)(VkDevice device, VkValidationCacheEXT dstCache, uint32_t srcCacheCount, const VkValidationCacheEXT* pSrcCaches); +typedef VkResult (VKAPI_PTR *PFN_vkGetValidationCacheDataEXT)(VkDevice device, VkValidationCacheEXT validationCache, size_t* pDataSize, void* pData); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateValidationCacheEXT( + VkDevice device, + const VkValidationCacheCreateInfoEXT* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkValidationCacheEXT* pValidationCache); + +VKAPI_ATTR void VKAPI_CALL vkDestroyValidationCacheEXT( + VkDevice device, + VkValidationCacheEXT validationCache, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkMergeValidationCachesEXT( + VkDevice device, + VkValidationCacheEXT dstCache, + uint32_t srcCacheCount, + const VkValidationCacheEXT* pSrcCaches); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetValidationCacheDataEXT( + VkDevice device, + VkValidationCacheEXT validationCache, + size_t* pDataSize, + void* pData); +#endif + + +// VK_EXT_descriptor_indexing is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_descriptor_indexing 1 +#define VK_EXT_DESCRIPTOR_INDEXING_SPEC_VERSION 2 +#define VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME "VK_EXT_descriptor_indexing" +typedef VkDescriptorBindingFlagBits VkDescriptorBindingFlagBitsEXT; + +typedef VkDescriptorBindingFlags VkDescriptorBindingFlagsEXT; + +typedef VkDescriptorSetLayoutBindingFlagsCreateInfo VkDescriptorSetLayoutBindingFlagsCreateInfoEXT; + +typedef VkPhysicalDeviceDescriptorIndexingFeatures VkPhysicalDeviceDescriptorIndexingFeaturesEXT; + +typedef VkPhysicalDeviceDescriptorIndexingProperties VkPhysicalDeviceDescriptorIndexingPropertiesEXT; + +typedef VkDescriptorSetVariableDescriptorCountAllocateInfo VkDescriptorSetVariableDescriptorCountAllocateInfoEXT; + +typedef VkDescriptorSetVariableDescriptorCountLayoutSupport VkDescriptorSetVariableDescriptorCountLayoutSupportEXT; + + + +// VK_EXT_shader_viewport_index_layer is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_shader_viewport_index_layer 1 +#define VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_SPEC_VERSION 1 +#define VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME "VK_EXT_shader_viewport_index_layer" + + +// VK_NV_shading_rate_image is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_shading_rate_image 1 +#define VK_NV_SHADING_RATE_IMAGE_SPEC_VERSION 3 +#define VK_NV_SHADING_RATE_IMAGE_EXTENSION_NAME "VK_NV_shading_rate_image" + +typedef enum VkShadingRatePaletteEntryNV { + VK_SHADING_RATE_PALETTE_ENTRY_NO_INVOCATIONS_NV = 0, + VK_SHADING_RATE_PALETTE_ENTRY_16_INVOCATIONS_PER_PIXEL_NV = 1, + VK_SHADING_RATE_PALETTE_ENTRY_8_INVOCATIONS_PER_PIXEL_NV = 2, + VK_SHADING_RATE_PALETTE_ENTRY_4_INVOCATIONS_PER_PIXEL_NV = 3, + VK_SHADING_RATE_PALETTE_ENTRY_2_INVOCATIONS_PER_PIXEL_NV = 4, + VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_PIXEL_NV = 5, + VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X1_PIXELS_NV = 6, + VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_1X2_PIXELS_NV = 7, + VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X2_PIXELS_NV = 8, + VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X2_PIXELS_NV = 9, + VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X4_PIXELS_NV = 10, + VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X4_PIXELS_NV = 11, + VK_SHADING_RATE_PALETTE_ENTRY_MAX_ENUM_NV = 0x7FFFFFFF +} VkShadingRatePaletteEntryNV; + +typedef enum VkCoarseSampleOrderTypeNV { + VK_COARSE_SAMPLE_ORDER_TYPE_DEFAULT_NV = 0, + VK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV = 1, + VK_COARSE_SAMPLE_ORDER_TYPE_PIXEL_MAJOR_NV = 2, + VK_COARSE_SAMPLE_ORDER_TYPE_SAMPLE_MAJOR_NV = 3, + VK_COARSE_SAMPLE_ORDER_TYPE_MAX_ENUM_NV = 0x7FFFFFFF +} VkCoarseSampleOrderTypeNV; +typedef struct VkShadingRatePaletteNV { + uint32_t shadingRatePaletteEntryCount; + const VkShadingRatePaletteEntryNV* pShadingRatePaletteEntries; +} VkShadingRatePaletteNV; + +typedef struct VkPipelineViewportShadingRateImageStateCreateInfoNV { + VkStructureType sType; + const void* pNext; + VkBool32 shadingRateImageEnable; + uint32_t viewportCount; + const VkShadingRatePaletteNV* pShadingRatePalettes; +} VkPipelineViewportShadingRateImageStateCreateInfoNV; + +typedef struct VkPhysicalDeviceShadingRateImageFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 shadingRateImage; + VkBool32 shadingRateCoarseSampleOrder; +} VkPhysicalDeviceShadingRateImageFeaturesNV; + +typedef struct VkPhysicalDeviceShadingRateImagePropertiesNV { + VkStructureType sType; + void* pNext; + VkExtent2D shadingRateTexelSize; + uint32_t shadingRatePaletteSize; + uint32_t shadingRateMaxCoarseSamples; +} VkPhysicalDeviceShadingRateImagePropertiesNV; + +typedef struct VkCoarseSampleLocationNV { + uint32_t pixelX; + uint32_t pixelY; + uint32_t sample; +} VkCoarseSampleLocationNV; + +typedef struct VkCoarseSampleOrderCustomNV { + VkShadingRatePaletteEntryNV shadingRate; + uint32_t sampleCount; + uint32_t sampleLocationCount; + const VkCoarseSampleLocationNV* pSampleLocations; +} VkCoarseSampleOrderCustomNV; + +typedef struct VkPipelineViewportCoarseSampleOrderStateCreateInfoNV { + VkStructureType sType; + const void* pNext; + VkCoarseSampleOrderTypeNV sampleOrderType; + uint32_t customSampleOrderCount; + const VkCoarseSampleOrderCustomNV* pCustomSampleOrders; +} VkPipelineViewportCoarseSampleOrderStateCreateInfoNV; + +typedef void (VKAPI_PTR *PFN_vkCmdBindShadingRateImageNV)(VkCommandBuffer commandBuffer, VkImageView imageView, VkImageLayout imageLayout); +typedef void (VKAPI_PTR *PFN_vkCmdSetViewportShadingRatePaletteNV)(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkShadingRatePaletteNV* pShadingRatePalettes); +typedef void (VKAPI_PTR *PFN_vkCmdSetCoarseSampleOrderNV)(VkCommandBuffer commandBuffer, VkCoarseSampleOrderTypeNV sampleOrderType, uint32_t customSampleOrderCount, const VkCoarseSampleOrderCustomNV* pCustomSampleOrders); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdBindShadingRateImageNV( + VkCommandBuffer commandBuffer, + VkImageView imageView, + VkImageLayout imageLayout); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetViewportShadingRatePaletteNV( + VkCommandBuffer commandBuffer, + uint32_t firstViewport, + uint32_t viewportCount, + const VkShadingRatePaletteNV* pShadingRatePalettes); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetCoarseSampleOrderNV( + VkCommandBuffer commandBuffer, + VkCoarseSampleOrderTypeNV sampleOrderType, + uint32_t customSampleOrderCount, + const VkCoarseSampleOrderCustomNV* pCustomSampleOrders); +#endif + + +// VK_NV_ray_tracing is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_ray_tracing 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkAccelerationStructureNV) +#define VK_NV_RAY_TRACING_SPEC_VERSION 3 +#define VK_NV_RAY_TRACING_EXTENSION_NAME "VK_NV_ray_tracing" +#define VK_SHADER_UNUSED_KHR (~0U) +#define VK_SHADER_UNUSED_NV VK_SHADER_UNUSED_KHR + +typedef enum VkRayTracingShaderGroupTypeKHR { + VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR = 0, + VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_KHR = 1, + VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_KHR = 2, + VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_NV = VK_RAY_TRACING_SHADER_GROUP_TYPE_GENERAL_KHR, + VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_NV = VK_RAY_TRACING_SHADER_GROUP_TYPE_TRIANGLES_HIT_GROUP_KHR, + VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_NV = VK_RAY_TRACING_SHADER_GROUP_TYPE_PROCEDURAL_HIT_GROUP_KHR, + VK_RAY_TRACING_SHADER_GROUP_TYPE_MAX_ENUM_KHR = 0x7FFFFFFF +} VkRayTracingShaderGroupTypeKHR; +typedef VkRayTracingShaderGroupTypeKHR VkRayTracingShaderGroupTypeNV; + + +typedef enum VkGeometryTypeKHR { + VK_GEOMETRY_TYPE_TRIANGLES_KHR = 0, + VK_GEOMETRY_TYPE_AABBS_KHR = 1, + VK_GEOMETRY_TYPE_INSTANCES_KHR = 2, + VK_GEOMETRY_TYPE_TRIANGLES_NV = VK_GEOMETRY_TYPE_TRIANGLES_KHR, + VK_GEOMETRY_TYPE_AABBS_NV = VK_GEOMETRY_TYPE_AABBS_KHR, + VK_GEOMETRY_TYPE_MAX_ENUM_KHR = 0x7FFFFFFF +} VkGeometryTypeKHR; +typedef VkGeometryTypeKHR VkGeometryTypeNV; + + +typedef enum VkAccelerationStructureTypeKHR { + VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR = 0, + VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR = 1, + VK_ACCELERATION_STRUCTURE_TYPE_GENERIC_KHR = 2, + VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV = VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_KHR, + VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR, + VK_ACCELERATION_STRUCTURE_TYPE_MAX_ENUM_KHR = 0x7FFFFFFF +} VkAccelerationStructureTypeKHR; +typedef VkAccelerationStructureTypeKHR VkAccelerationStructureTypeNV; + + +typedef enum VkCopyAccelerationStructureModeKHR { + VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_KHR = 0, + VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_KHR = 1, + VK_COPY_ACCELERATION_STRUCTURE_MODE_SERIALIZE_KHR = 2, + VK_COPY_ACCELERATION_STRUCTURE_MODE_DESERIALIZE_KHR = 3, + VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_NV = VK_COPY_ACCELERATION_STRUCTURE_MODE_CLONE_KHR, + VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_NV = VK_COPY_ACCELERATION_STRUCTURE_MODE_COMPACT_KHR, + VK_COPY_ACCELERATION_STRUCTURE_MODE_MAX_ENUM_KHR = 0x7FFFFFFF +} VkCopyAccelerationStructureModeKHR; +typedef VkCopyAccelerationStructureModeKHR VkCopyAccelerationStructureModeNV; + + +typedef enum VkAccelerationStructureMemoryRequirementsTypeNV { + VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_OBJECT_NV = 0, + VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_BUILD_SCRATCH_NV = 1, + VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_UPDATE_SCRATCH_NV = 2, + VK_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_TYPE_MAX_ENUM_NV = 0x7FFFFFFF +} VkAccelerationStructureMemoryRequirementsTypeNV; + +typedef enum VkGeometryFlagBitsKHR { + VK_GEOMETRY_OPAQUE_BIT_KHR = 0x00000001, + VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_KHR = 0x00000002, + VK_GEOMETRY_OPAQUE_BIT_NV = VK_GEOMETRY_OPAQUE_BIT_KHR, + VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_NV = VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_KHR, + VK_GEOMETRY_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkGeometryFlagBitsKHR; +typedef VkFlags VkGeometryFlagsKHR; +typedef VkGeometryFlagsKHR VkGeometryFlagsNV; + +typedef VkGeometryFlagBitsKHR VkGeometryFlagBitsNV; + + +typedef enum VkGeometryInstanceFlagBitsKHR { + VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR = 0x00000001, + VK_GEOMETRY_INSTANCE_TRIANGLE_FLIP_FACING_BIT_KHR = 0x00000002, + VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR = 0x00000004, + VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_KHR = 0x00000008, + VK_GEOMETRY_INSTANCE_FORCE_OPACITY_MICROMAP_2_STATE_EXT = 0x00000010, + VK_GEOMETRY_INSTANCE_DISABLE_OPACITY_MICROMAPS_EXT = 0x00000020, + VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_KHR = VK_GEOMETRY_INSTANCE_TRIANGLE_FLIP_FACING_BIT_KHR, + VK_GEOMETRY_INSTANCE_TRIANGLE_CULL_DISABLE_BIT_NV = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR, + VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_NV = VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_KHR, + VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_NV = VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR, + VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_NV = VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_KHR, + VK_GEOMETRY_INSTANCE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkGeometryInstanceFlagBitsKHR; +typedef VkFlags VkGeometryInstanceFlagsKHR; +typedef VkGeometryInstanceFlagsKHR VkGeometryInstanceFlagsNV; + +typedef VkGeometryInstanceFlagBitsKHR VkGeometryInstanceFlagBitsNV; + + +typedef enum VkBuildAccelerationStructureFlagBitsKHR { + VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR = 0x00000001, + VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR = 0x00000002, + VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR = 0x00000004, + VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR = 0x00000008, + VK_BUILD_ACCELERATION_STRUCTURE_LOW_MEMORY_BIT_KHR = 0x00000010, + VK_BUILD_ACCELERATION_STRUCTURE_MOTION_BIT_NV = 0x00000020, + VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_OPACITY_MICROMAP_UPDATE_EXT = 0x00000040, + VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_DISABLE_OPACITY_MICROMAPS_EXT = 0x00000080, + VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_OPACITY_MICROMAP_DATA_UPDATE_EXT = 0x00000100, +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_DISPLACEMENT_MICROMAP_UPDATE_NV = 0x00000200, +#endif + VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_DATA_ACCESS_KHR = 0x00000800, + VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_NV = VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR, + VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_NV = VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR, + VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_NV = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR, + VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_NV = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR, + VK_BUILD_ACCELERATION_STRUCTURE_LOW_MEMORY_BIT_NV = VK_BUILD_ACCELERATION_STRUCTURE_LOW_MEMORY_BIT_KHR, + VK_BUILD_ACCELERATION_STRUCTURE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkBuildAccelerationStructureFlagBitsKHR; +typedef VkFlags VkBuildAccelerationStructureFlagsKHR; +typedef VkBuildAccelerationStructureFlagsKHR VkBuildAccelerationStructureFlagsNV; + +typedef VkBuildAccelerationStructureFlagBitsKHR VkBuildAccelerationStructureFlagBitsNV; + +typedef struct VkRayTracingShaderGroupCreateInfoNV { + VkStructureType sType; + const void* pNext; + VkRayTracingShaderGroupTypeKHR type; + uint32_t generalShader; + uint32_t closestHitShader; + uint32_t anyHitShader; + uint32_t intersectionShader; +} VkRayTracingShaderGroupCreateInfoNV; + +typedef struct VkRayTracingPipelineCreateInfoNV { + VkStructureType sType; + const void* pNext; + VkPipelineCreateFlags flags; + uint32_t stageCount; + const VkPipelineShaderStageCreateInfo* pStages; + uint32_t groupCount; + const VkRayTracingShaderGroupCreateInfoNV* pGroups; + uint32_t maxRecursionDepth; + VkPipelineLayout layout; + VkPipeline basePipelineHandle; + int32_t basePipelineIndex; +} VkRayTracingPipelineCreateInfoNV; + +typedef struct VkGeometryTrianglesNV { + VkStructureType sType; + const void* pNext; + VkBuffer vertexData; + VkDeviceSize vertexOffset; + uint32_t vertexCount; + VkDeviceSize vertexStride; + VkFormat vertexFormat; + VkBuffer indexData; + VkDeviceSize indexOffset; + uint32_t indexCount; + VkIndexType indexType; + VkBuffer transformData; + VkDeviceSize transformOffset; +} VkGeometryTrianglesNV; + +typedef struct VkGeometryAABBNV { + VkStructureType sType; + const void* pNext; + VkBuffer aabbData; + uint32_t numAABBs; + uint32_t stride; + VkDeviceSize offset; +} VkGeometryAABBNV; + +typedef struct VkGeometryDataNV { + VkGeometryTrianglesNV triangles; + VkGeometryAABBNV aabbs; +} VkGeometryDataNV; + +typedef struct VkGeometryNV { + VkStructureType sType; + const void* pNext; + VkGeometryTypeKHR geometryType; + VkGeometryDataNV geometry; + VkGeometryFlagsKHR flags; +} VkGeometryNV; + +typedef struct VkAccelerationStructureInfoNV { + VkStructureType sType; + const void* pNext; + VkAccelerationStructureTypeNV type; + VkBuildAccelerationStructureFlagsNV flags; + uint32_t instanceCount; + uint32_t geometryCount; + const VkGeometryNV* pGeometries; +} VkAccelerationStructureInfoNV; + +typedef struct VkAccelerationStructureCreateInfoNV { + VkStructureType sType; + const void* pNext; + VkDeviceSize compactedSize; + VkAccelerationStructureInfoNV info; +} VkAccelerationStructureCreateInfoNV; + +typedef struct VkBindAccelerationStructureMemoryInfoNV { + VkStructureType sType; + const void* pNext; + VkAccelerationStructureNV accelerationStructure; + VkDeviceMemory memory; + VkDeviceSize memoryOffset; + uint32_t deviceIndexCount; + const uint32_t* pDeviceIndices; +} VkBindAccelerationStructureMemoryInfoNV; + +typedef struct VkWriteDescriptorSetAccelerationStructureNV { + VkStructureType sType; + const void* pNext; + uint32_t accelerationStructureCount; + const VkAccelerationStructureNV* pAccelerationStructures; +} VkWriteDescriptorSetAccelerationStructureNV; + +typedef struct VkAccelerationStructureMemoryRequirementsInfoNV { + VkStructureType sType; + const void* pNext; + VkAccelerationStructureMemoryRequirementsTypeNV type; + VkAccelerationStructureNV accelerationStructure; +} VkAccelerationStructureMemoryRequirementsInfoNV; + +typedef struct VkPhysicalDeviceRayTracingPropertiesNV { + VkStructureType sType; + void* pNext; + uint32_t shaderGroupHandleSize; + uint32_t maxRecursionDepth; + uint32_t maxShaderGroupStride; + uint32_t shaderGroupBaseAlignment; + uint64_t maxGeometryCount; + uint64_t maxInstanceCount; + uint64_t maxTriangleCount; + uint32_t maxDescriptorSetAccelerationStructures; +} VkPhysicalDeviceRayTracingPropertiesNV; + +typedef struct VkTransformMatrixKHR { + float matrix[3][4]; +} VkTransformMatrixKHR; + +typedef VkTransformMatrixKHR VkTransformMatrixNV; + +typedef struct VkAabbPositionsKHR { + float minX; + float minY; + float minZ; + float maxX; + float maxY; + float maxZ; +} VkAabbPositionsKHR; + +typedef VkAabbPositionsKHR VkAabbPositionsNV; + +typedef struct VkAccelerationStructureInstanceKHR { + VkTransformMatrixKHR transform; + uint32_t instanceCustomIndex:24; + uint32_t mask:8; + uint32_t instanceShaderBindingTableRecordOffset:24; + VkGeometryInstanceFlagsKHR flags:8; + uint64_t accelerationStructureReference; +} VkAccelerationStructureInstanceKHR; + +typedef VkAccelerationStructureInstanceKHR VkAccelerationStructureInstanceNV; + +typedef VkResult (VKAPI_PTR *PFN_vkCreateAccelerationStructureNV)(VkDevice device, const VkAccelerationStructureCreateInfoNV* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkAccelerationStructureNV* pAccelerationStructure); +typedef void (VKAPI_PTR *PFN_vkDestroyAccelerationStructureNV)(VkDevice device, VkAccelerationStructureNV accelerationStructure, const VkAllocationCallbacks* pAllocator); +typedef void (VKAPI_PTR *PFN_vkGetAccelerationStructureMemoryRequirementsNV)(VkDevice device, const VkAccelerationStructureMemoryRequirementsInfoNV* pInfo, VkMemoryRequirements2KHR* pMemoryRequirements); +typedef VkResult (VKAPI_PTR *PFN_vkBindAccelerationStructureMemoryNV)(VkDevice device, uint32_t bindInfoCount, const VkBindAccelerationStructureMemoryInfoNV* pBindInfos); +typedef void (VKAPI_PTR *PFN_vkCmdBuildAccelerationStructureNV)(VkCommandBuffer commandBuffer, const VkAccelerationStructureInfoNV* pInfo, VkBuffer instanceData, VkDeviceSize instanceOffset, VkBool32 update, VkAccelerationStructureNV dst, VkAccelerationStructureNV src, VkBuffer scratch, VkDeviceSize scratchOffset); +typedef void (VKAPI_PTR *PFN_vkCmdCopyAccelerationStructureNV)(VkCommandBuffer commandBuffer, VkAccelerationStructureNV dst, VkAccelerationStructureNV src, VkCopyAccelerationStructureModeKHR mode); +typedef void (VKAPI_PTR *PFN_vkCmdTraceRaysNV)(VkCommandBuffer commandBuffer, VkBuffer raygenShaderBindingTableBuffer, VkDeviceSize raygenShaderBindingOffset, VkBuffer missShaderBindingTableBuffer, VkDeviceSize missShaderBindingOffset, VkDeviceSize missShaderBindingStride, VkBuffer hitShaderBindingTableBuffer, VkDeviceSize hitShaderBindingOffset, VkDeviceSize hitShaderBindingStride, VkBuffer callableShaderBindingTableBuffer, VkDeviceSize callableShaderBindingOffset, VkDeviceSize callableShaderBindingStride, uint32_t width, uint32_t height, uint32_t depth); +typedef VkResult (VKAPI_PTR *PFN_vkCreateRayTracingPipelinesNV)(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkRayTracingPipelineCreateInfoNV* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines); +typedef VkResult (VKAPI_PTR *PFN_vkGetRayTracingShaderGroupHandlesKHR)(VkDevice device, VkPipeline pipeline, uint32_t firstGroup, uint32_t groupCount, size_t dataSize, void* pData); +typedef VkResult (VKAPI_PTR *PFN_vkGetRayTracingShaderGroupHandlesNV)(VkDevice device, VkPipeline pipeline, uint32_t firstGroup, uint32_t groupCount, size_t dataSize, void* pData); +typedef VkResult (VKAPI_PTR *PFN_vkGetAccelerationStructureHandleNV)(VkDevice device, VkAccelerationStructureNV accelerationStructure, size_t dataSize, void* pData); +typedef void (VKAPI_PTR *PFN_vkCmdWriteAccelerationStructuresPropertiesNV)(VkCommandBuffer commandBuffer, uint32_t accelerationStructureCount, const VkAccelerationStructureNV* pAccelerationStructures, VkQueryType queryType, VkQueryPool queryPool, uint32_t firstQuery); +typedef VkResult (VKAPI_PTR *PFN_vkCompileDeferredNV)(VkDevice device, VkPipeline pipeline, uint32_t shader); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateAccelerationStructureNV( + VkDevice device, + const VkAccelerationStructureCreateInfoNV* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkAccelerationStructureNV* pAccelerationStructure); + +VKAPI_ATTR void VKAPI_CALL vkDestroyAccelerationStructureNV( + VkDevice device, + VkAccelerationStructureNV accelerationStructure, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR void VKAPI_CALL vkGetAccelerationStructureMemoryRequirementsNV( + VkDevice device, + const VkAccelerationStructureMemoryRequirementsInfoNV* pInfo, + VkMemoryRequirements2KHR* pMemoryRequirements); + +VKAPI_ATTR VkResult VKAPI_CALL vkBindAccelerationStructureMemoryNV( + VkDevice device, + uint32_t bindInfoCount, + const VkBindAccelerationStructureMemoryInfoNV* pBindInfos); + +VKAPI_ATTR void VKAPI_CALL vkCmdBuildAccelerationStructureNV( + VkCommandBuffer commandBuffer, + const VkAccelerationStructureInfoNV* pInfo, + VkBuffer instanceData, + VkDeviceSize instanceOffset, + VkBool32 update, + VkAccelerationStructureNV dst, + VkAccelerationStructureNV src, + VkBuffer scratch, + VkDeviceSize scratchOffset); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyAccelerationStructureNV( + VkCommandBuffer commandBuffer, + VkAccelerationStructureNV dst, + VkAccelerationStructureNV src, + VkCopyAccelerationStructureModeKHR mode); + +VKAPI_ATTR void VKAPI_CALL vkCmdTraceRaysNV( + VkCommandBuffer commandBuffer, + VkBuffer raygenShaderBindingTableBuffer, + VkDeviceSize raygenShaderBindingOffset, + VkBuffer missShaderBindingTableBuffer, + VkDeviceSize missShaderBindingOffset, + VkDeviceSize missShaderBindingStride, + VkBuffer hitShaderBindingTableBuffer, + VkDeviceSize hitShaderBindingOffset, + VkDeviceSize hitShaderBindingStride, + VkBuffer callableShaderBindingTableBuffer, + VkDeviceSize callableShaderBindingOffset, + VkDeviceSize callableShaderBindingStride, + uint32_t width, + uint32_t height, + uint32_t depth); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateRayTracingPipelinesNV( + VkDevice device, + VkPipelineCache pipelineCache, + uint32_t createInfoCount, + const VkRayTracingPipelineCreateInfoNV* pCreateInfos, + const VkAllocationCallbacks* pAllocator, + VkPipeline* pPipelines); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetRayTracingShaderGroupHandlesKHR( + VkDevice device, + VkPipeline pipeline, + uint32_t firstGroup, + uint32_t groupCount, + size_t dataSize, + void* pData); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetRayTracingShaderGroupHandlesNV( + VkDevice device, + VkPipeline pipeline, + uint32_t firstGroup, + uint32_t groupCount, + size_t dataSize, + void* pData); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetAccelerationStructureHandleNV( + VkDevice device, + VkAccelerationStructureNV accelerationStructure, + size_t dataSize, + void* pData); + +VKAPI_ATTR void VKAPI_CALL vkCmdWriteAccelerationStructuresPropertiesNV( + VkCommandBuffer commandBuffer, + uint32_t accelerationStructureCount, + const VkAccelerationStructureNV* pAccelerationStructures, + VkQueryType queryType, + VkQueryPool queryPool, + uint32_t firstQuery); + +VKAPI_ATTR VkResult VKAPI_CALL vkCompileDeferredNV( + VkDevice device, + VkPipeline pipeline, + uint32_t shader); +#endif + + +// VK_NV_representative_fragment_test is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_representative_fragment_test 1 +#define VK_NV_REPRESENTATIVE_FRAGMENT_TEST_SPEC_VERSION 2 +#define VK_NV_REPRESENTATIVE_FRAGMENT_TEST_EXTENSION_NAME "VK_NV_representative_fragment_test" +typedef struct VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 representativeFragmentTest; +} VkPhysicalDeviceRepresentativeFragmentTestFeaturesNV; + +typedef struct VkPipelineRepresentativeFragmentTestStateCreateInfoNV { + VkStructureType sType; + const void* pNext; + VkBool32 representativeFragmentTestEnable; +} VkPipelineRepresentativeFragmentTestStateCreateInfoNV; + + + +// VK_EXT_filter_cubic is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_filter_cubic 1 +#define VK_EXT_FILTER_CUBIC_SPEC_VERSION 3 +#define VK_EXT_FILTER_CUBIC_EXTENSION_NAME "VK_EXT_filter_cubic" +typedef struct VkPhysicalDeviceImageViewImageFormatInfoEXT { + VkStructureType sType; + void* pNext; + VkImageViewType imageViewType; +} VkPhysicalDeviceImageViewImageFormatInfoEXT; + +typedef struct VkFilterCubicImageViewImageFormatPropertiesEXT { + VkStructureType sType; + void* pNext; + VkBool32 filterCubic; + VkBool32 filterCubicMinmax; +} VkFilterCubicImageViewImageFormatPropertiesEXT; + + + +// VK_QCOM_render_pass_shader_resolve is a preprocessor guard. Do not pass it to API calls. +#define VK_QCOM_render_pass_shader_resolve 1 +#define VK_QCOM_RENDER_PASS_SHADER_RESOLVE_SPEC_VERSION 4 +#define VK_QCOM_RENDER_PASS_SHADER_RESOLVE_EXTENSION_NAME "VK_QCOM_render_pass_shader_resolve" + + +// VK_EXT_global_priority is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_global_priority 1 +#define VK_EXT_GLOBAL_PRIORITY_SPEC_VERSION 2 +#define VK_EXT_GLOBAL_PRIORITY_EXTENSION_NAME "VK_EXT_global_priority" +typedef VkQueueGlobalPriorityKHR VkQueueGlobalPriorityEXT; + +typedef VkDeviceQueueGlobalPriorityCreateInfoKHR VkDeviceQueueGlobalPriorityCreateInfoEXT; + + + +// VK_EXT_external_memory_host is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_external_memory_host 1 +#define VK_EXT_EXTERNAL_MEMORY_HOST_SPEC_VERSION 1 +#define VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME "VK_EXT_external_memory_host" +typedef struct VkImportMemoryHostPointerInfoEXT { + VkStructureType sType; + const void* pNext; + VkExternalMemoryHandleTypeFlagBits handleType; + void* pHostPointer; +} VkImportMemoryHostPointerInfoEXT; + +typedef struct VkMemoryHostPointerPropertiesEXT { + VkStructureType sType; + void* pNext; + uint32_t memoryTypeBits; +} VkMemoryHostPointerPropertiesEXT; + +typedef struct VkPhysicalDeviceExternalMemoryHostPropertiesEXT { + VkStructureType sType; + void* pNext; + VkDeviceSize minImportedHostPointerAlignment; +} VkPhysicalDeviceExternalMemoryHostPropertiesEXT; + +typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryHostPointerPropertiesEXT)(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, const void* pHostPointer, VkMemoryHostPointerPropertiesEXT* pMemoryHostPointerProperties); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryHostPointerPropertiesEXT( + VkDevice device, + VkExternalMemoryHandleTypeFlagBits handleType, + const void* pHostPointer, + VkMemoryHostPointerPropertiesEXT* pMemoryHostPointerProperties); +#endif + + +// VK_AMD_buffer_marker is a preprocessor guard. Do not pass it to API calls. +#define VK_AMD_buffer_marker 1 +#define VK_AMD_BUFFER_MARKER_SPEC_VERSION 1 +#define VK_AMD_BUFFER_MARKER_EXTENSION_NAME "VK_AMD_buffer_marker" +typedef void (VKAPI_PTR *PFN_vkCmdWriteBufferMarkerAMD)(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits pipelineStage, VkBuffer dstBuffer, VkDeviceSize dstOffset, uint32_t marker); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdWriteBufferMarkerAMD( + VkCommandBuffer commandBuffer, + VkPipelineStageFlagBits pipelineStage, + VkBuffer dstBuffer, + VkDeviceSize dstOffset, + uint32_t marker); +#endif + + +// VK_AMD_pipeline_compiler_control is a preprocessor guard. Do not pass it to API calls. +#define VK_AMD_pipeline_compiler_control 1 +#define VK_AMD_PIPELINE_COMPILER_CONTROL_SPEC_VERSION 1 +#define VK_AMD_PIPELINE_COMPILER_CONTROL_EXTENSION_NAME "VK_AMD_pipeline_compiler_control" + +typedef enum VkPipelineCompilerControlFlagBitsAMD { + VK_PIPELINE_COMPILER_CONTROL_FLAG_BITS_MAX_ENUM_AMD = 0x7FFFFFFF +} VkPipelineCompilerControlFlagBitsAMD; +typedef VkFlags VkPipelineCompilerControlFlagsAMD; +typedef struct VkPipelineCompilerControlCreateInfoAMD { + VkStructureType sType; + const void* pNext; + VkPipelineCompilerControlFlagsAMD compilerControlFlags; +} VkPipelineCompilerControlCreateInfoAMD; + + + +// VK_EXT_calibrated_timestamps is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_calibrated_timestamps 1 +#define VK_EXT_CALIBRATED_TIMESTAMPS_SPEC_VERSION 2 +#define VK_EXT_CALIBRATED_TIMESTAMPS_EXTENSION_NAME "VK_EXT_calibrated_timestamps" +typedef VkTimeDomainKHR VkTimeDomainEXT; + +typedef VkCalibratedTimestampInfoKHR VkCalibratedTimestampInfoEXT; + +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceCalibrateableTimeDomainsEXT)(VkPhysicalDevice physicalDevice, uint32_t* pTimeDomainCount, VkTimeDomainKHR* pTimeDomains); +typedef VkResult (VKAPI_PTR *PFN_vkGetCalibratedTimestampsEXT)(VkDevice device, uint32_t timestampCount, const VkCalibratedTimestampInfoKHR* pTimestampInfos, uint64_t* pTimestamps, uint64_t* pMaxDeviation); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceCalibrateableTimeDomainsEXT( + VkPhysicalDevice physicalDevice, + uint32_t* pTimeDomainCount, + VkTimeDomainKHR* pTimeDomains); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetCalibratedTimestampsEXT( + VkDevice device, + uint32_t timestampCount, + const VkCalibratedTimestampInfoKHR* pTimestampInfos, + uint64_t* pTimestamps, + uint64_t* pMaxDeviation); +#endif + + +// VK_AMD_shader_core_properties is a preprocessor guard. Do not pass it to API calls. +#define VK_AMD_shader_core_properties 1 +#define VK_AMD_SHADER_CORE_PROPERTIES_SPEC_VERSION 2 +#define VK_AMD_SHADER_CORE_PROPERTIES_EXTENSION_NAME "VK_AMD_shader_core_properties" +typedef struct VkPhysicalDeviceShaderCorePropertiesAMD { + VkStructureType sType; + void* pNext; + uint32_t shaderEngineCount; + uint32_t shaderArraysPerEngineCount; + uint32_t computeUnitsPerShaderArray; + uint32_t simdPerComputeUnit; + uint32_t wavefrontsPerSimd; + uint32_t wavefrontSize; + uint32_t sgprsPerSimd; + uint32_t minSgprAllocation; + uint32_t maxSgprAllocation; + uint32_t sgprAllocationGranularity; + uint32_t vgprsPerSimd; + uint32_t minVgprAllocation; + uint32_t maxVgprAllocation; + uint32_t vgprAllocationGranularity; +} VkPhysicalDeviceShaderCorePropertiesAMD; + + + +// VK_AMD_memory_overallocation_behavior is a preprocessor guard. Do not pass it to API calls. +#define VK_AMD_memory_overallocation_behavior 1 +#define VK_AMD_MEMORY_OVERALLOCATION_BEHAVIOR_SPEC_VERSION 1 +#define VK_AMD_MEMORY_OVERALLOCATION_BEHAVIOR_EXTENSION_NAME "VK_AMD_memory_overallocation_behavior" + +typedef enum VkMemoryOverallocationBehaviorAMD { + VK_MEMORY_OVERALLOCATION_BEHAVIOR_DEFAULT_AMD = 0, + VK_MEMORY_OVERALLOCATION_BEHAVIOR_ALLOWED_AMD = 1, + VK_MEMORY_OVERALLOCATION_BEHAVIOR_DISALLOWED_AMD = 2, + VK_MEMORY_OVERALLOCATION_BEHAVIOR_MAX_ENUM_AMD = 0x7FFFFFFF +} VkMemoryOverallocationBehaviorAMD; +typedef struct VkDeviceMemoryOverallocationCreateInfoAMD { + VkStructureType sType; + const void* pNext; + VkMemoryOverallocationBehaviorAMD overallocationBehavior; +} VkDeviceMemoryOverallocationCreateInfoAMD; + + + +// VK_EXT_vertex_attribute_divisor is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_vertex_attribute_divisor 1 +#define VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_SPEC_VERSION 3 +#define VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME "VK_EXT_vertex_attribute_divisor" +typedef struct VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT { + VkStructureType sType; + void* pNext; + uint32_t maxVertexAttribDivisor; +} VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT; + +typedef VkVertexInputBindingDivisorDescriptionKHR VkVertexInputBindingDivisorDescriptionEXT; + +typedef VkPipelineVertexInputDivisorStateCreateInfoKHR VkPipelineVertexInputDivisorStateCreateInfoEXT; + +typedef VkPhysicalDeviceVertexAttributeDivisorFeaturesKHR VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT; + + + +// VK_EXT_pipeline_creation_feedback is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_pipeline_creation_feedback 1 +#define VK_EXT_PIPELINE_CREATION_FEEDBACK_SPEC_VERSION 1 +#define VK_EXT_PIPELINE_CREATION_FEEDBACK_EXTENSION_NAME "VK_EXT_pipeline_creation_feedback" +typedef VkPipelineCreationFeedbackFlagBits VkPipelineCreationFeedbackFlagBitsEXT; + +typedef VkPipelineCreationFeedbackFlags VkPipelineCreationFeedbackFlagsEXT; + +typedef VkPipelineCreationFeedbackCreateInfo VkPipelineCreationFeedbackCreateInfoEXT; + +typedef VkPipelineCreationFeedback VkPipelineCreationFeedbackEXT; + + + +// VK_NV_shader_subgroup_partitioned is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_shader_subgroup_partitioned 1 +#define VK_NV_SHADER_SUBGROUP_PARTITIONED_SPEC_VERSION 1 +#define VK_NV_SHADER_SUBGROUP_PARTITIONED_EXTENSION_NAME "VK_NV_shader_subgroup_partitioned" + + +// VK_NV_compute_shader_derivatives is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_compute_shader_derivatives 1 +#define VK_NV_COMPUTE_SHADER_DERIVATIVES_SPEC_VERSION 1 +#define VK_NV_COMPUTE_SHADER_DERIVATIVES_EXTENSION_NAME "VK_NV_compute_shader_derivatives" +typedef struct VkPhysicalDeviceComputeShaderDerivativesFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 computeDerivativeGroupQuads; + VkBool32 computeDerivativeGroupLinear; +} VkPhysicalDeviceComputeShaderDerivativesFeaturesNV; + + + +// VK_NV_mesh_shader is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_mesh_shader 1 +#define VK_NV_MESH_SHADER_SPEC_VERSION 1 +#define VK_NV_MESH_SHADER_EXTENSION_NAME "VK_NV_mesh_shader" +typedef struct VkPhysicalDeviceMeshShaderFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 taskShader; + VkBool32 meshShader; +} VkPhysicalDeviceMeshShaderFeaturesNV; + +typedef struct VkPhysicalDeviceMeshShaderPropertiesNV { + VkStructureType sType; + void* pNext; + uint32_t maxDrawMeshTasksCount; + uint32_t maxTaskWorkGroupInvocations; + uint32_t maxTaskWorkGroupSize[3]; + uint32_t maxTaskTotalMemorySize; + uint32_t maxTaskOutputCount; + uint32_t maxMeshWorkGroupInvocations; + uint32_t maxMeshWorkGroupSize[3]; + uint32_t maxMeshTotalMemorySize; + uint32_t maxMeshOutputVertices; + uint32_t maxMeshOutputPrimitives; + uint32_t maxMeshMultiviewViewCount; + uint32_t meshOutputPerVertexGranularity; + uint32_t meshOutputPerPrimitiveGranularity; +} VkPhysicalDeviceMeshShaderPropertiesNV; + +typedef struct VkDrawMeshTasksIndirectCommandNV { + uint32_t taskCount; + uint32_t firstTask; +} VkDrawMeshTasksIndirectCommandNV; + +typedef void (VKAPI_PTR *PFN_vkCmdDrawMeshTasksNV)(VkCommandBuffer commandBuffer, uint32_t taskCount, uint32_t firstTask); +typedef void (VKAPI_PTR *PFN_vkCmdDrawMeshTasksIndirectNV)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride); +typedef void (VKAPI_PTR *PFN_vkCmdDrawMeshTasksIndirectCountNV)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdDrawMeshTasksNV( + VkCommandBuffer commandBuffer, + uint32_t taskCount, + uint32_t firstTask); + +VKAPI_ATTR void VKAPI_CALL vkCmdDrawMeshTasksIndirectNV( + VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset, + uint32_t drawCount, + uint32_t stride); + +VKAPI_ATTR void VKAPI_CALL vkCmdDrawMeshTasksIndirectCountNV( + VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset, + VkBuffer countBuffer, + VkDeviceSize countBufferOffset, + uint32_t maxDrawCount, + uint32_t stride); +#endif + + +// VK_NV_fragment_shader_barycentric is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_fragment_shader_barycentric 1 +#define VK_NV_FRAGMENT_SHADER_BARYCENTRIC_SPEC_VERSION 1 +#define VK_NV_FRAGMENT_SHADER_BARYCENTRIC_EXTENSION_NAME "VK_NV_fragment_shader_barycentric" +typedef VkPhysicalDeviceFragmentShaderBarycentricFeaturesKHR VkPhysicalDeviceFragmentShaderBarycentricFeaturesNV; + + + +// VK_NV_shader_image_footprint is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_shader_image_footprint 1 +#define VK_NV_SHADER_IMAGE_FOOTPRINT_SPEC_VERSION 2 +#define VK_NV_SHADER_IMAGE_FOOTPRINT_EXTENSION_NAME "VK_NV_shader_image_footprint" +typedef struct VkPhysicalDeviceShaderImageFootprintFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 imageFootprint; +} VkPhysicalDeviceShaderImageFootprintFeaturesNV; + + + +// VK_NV_scissor_exclusive is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_scissor_exclusive 1 +#define VK_NV_SCISSOR_EXCLUSIVE_SPEC_VERSION 2 +#define VK_NV_SCISSOR_EXCLUSIVE_EXTENSION_NAME "VK_NV_scissor_exclusive" +typedef struct VkPipelineViewportExclusiveScissorStateCreateInfoNV { + VkStructureType sType; + const void* pNext; + uint32_t exclusiveScissorCount; + const VkRect2D* pExclusiveScissors; +} VkPipelineViewportExclusiveScissorStateCreateInfoNV; + +typedef struct VkPhysicalDeviceExclusiveScissorFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 exclusiveScissor; +} VkPhysicalDeviceExclusiveScissorFeaturesNV; + +typedef void (VKAPI_PTR *PFN_vkCmdSetExclusiveScissorEnableNV)(VkCommandBuffer commandBuffer, uint32_t firstExclusiveScissor, uint32_t exclusiveScissorCount, const VkBool32* pExclusiveScissorEnables); +typedef void (VKAPI_PTR *PFN_vkCmdSetExclusiveScissorNV)(VkCommandBuffer commandBuffer, uint32_t firstExclusiveScissor, uint32_t exclusiveScissorCount, const VkRect2D* pExclusiveScissors); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdSetExclusiveScissorEnableNV( + VkCommandBuffer commandBuffer, + uint32_t firstExclusiveScissor, + uint32_t exclusiveScissorCount, + const VkBool32* pExclusiveScissorEnables); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetExclusiveScissorNV( + VkCommandBuffer commandBuffer, + uint32_t firstExclusiveScissor, + uint32_t exclusiveScissorCount, + const VkRect2D* pExclusiveScissors); +#endif + + +// VK_NV_device_diagnostic_checkpoints is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_device_diagnostic_checkpoints 1 +#define VK_NV_DEVICE_DIAGNOSTIC_CHECKPOINTS_SPEC_VERSION 2 +#define VK_NV_DEVICE_DIAGNOSTIC_CHECKPOINTS_EXTENSION_NAME "VK_NV_device_diagnostic_checkpoints" +typedef struct VkQueueFamilyCheckpointPropertiesNV { + VkStructureType sType; + void* pNext; + VkPipelineStageFlags checkpointExecutionStageMask; +} VkQueueFamilyCheckpointPropertiesNV; + +typedef struct VkCheckpointDataNV { + VkStructureType sType; + void* pNext; + VkPipelineStageFlagBits stage; + void* pCheckpointMarker; +} VkCheckpointDataNV; + +typedef void (VKAPI_PTR *PFN_vkCmdSetCheckpointNV)(VkCommandBuffer commandBuffer, const void* pCheckpointMarker); +typedef void (VKAPI_PTR *PFN_vkGetQueueCheckpointDataNV)(VkQueue queue, uint32_t* pCheckpointDataCount, VkCheckpointDataNV* pCheckpointData); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdSetCheckpointNV( + VkCommandBuffer commandBuffer, + const void* pCheckpointMarker); + +VKAPI_ATTR void VKAPI_CALL vkGetQueueCheckpointDataNV( + VkQueue queue, + uint32_t* pCheckpointDataCount, + VkCheckpointDataNV* pCheckpointData); +#endif + + +// VK_INTEL_shader_integer_functions2 is a preprocessor guard. Do not pass it to API calls. +#define VK_INTEL_shader_integer_functions2 1 +#define VK_INTEL_SHADER_INTEGER_FUNCTIONS_2_SPEC_VERSION 1 +#define VK_INTEL_SHADER_INTEGER_FUNCTIONS_2_EXTENSION_NAME "VK_INTEL_shader_integer_functions2" +typedef struct VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL { + VkStructureType sType; + void* pNext; + VkBool32 shaderIntegerFunctions2; +} VkPhysicalDeviceShaderIntegerFunctions2FeaturesINTEL; + + + +// VK_INTEL_performance_query is a preprocessor guard. Do not pass it to API calls. +#define VK_INTEL_performance_query 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkPerformanceConfigurationINTEL) +#define VK_INTEL_PERFORMANCE_QUERY_SPEC_VERSION 2 +#define VK_INTEL_PERFORMANCE_QUERY_EXTENSION_NAME "VK_INTEL_performance_query" + +typedef enum VkPerformanceConfigurationTypeINTEL { + VK_PERFORMANCE_CONFIGURATION_TYPE_COMMAND_QUEUE_METRICS_DISCOVERY_ACTIVATED_INTEL = 0, + VK_PERFORMANCE_CONFIGURATION_TYPE_MAX_ENUM_INTEL = 0x7FFFFFFF +} VkPerformanceConfigurationTypeINTEL; + +typedef enum VkQueryPoolSamplingModeINTEL { + VK_QUERY_POOL_SAMPLING_MODE_MANUAL_INTEL = 0, + VK_QUERY_POOL_SAMPLING_MODE_MAX_ENUM_INTEL = 0x7FFFFFFF +} VkQueryPoolSamplingModeINTEL; + +typedef enum VkPerformanceOverrideTypeINTEL { + VK_PERFORMANCE_OVERRIDE_TYPE_NULL_HARDWARE_INTEL = 0, + VK_PERFORMANCE_OVERRIDE_TYPE_FLUSH_GPU_CACHES_INTEL = 1, + VK_PERFORMANCE_OVERRIDE_TYPE_MAX_ENUM_INTEL = 0x7FFFFFFF +} VkPerformanceOverrideTypeINTEL; + +typedef enum VkPerformanceParameterTypeINTEL { + VK_PERFORMANCE_PARAMETER_TYPE_HW_COUNTERS_SUPPORTED_INTEL = 0, + VK_PERFORMANCE_PARAMETER_TYPE_STREAM_MARKER_VALID_BITS_INTEL = 1, + VK_PERFORMANCE_PARAMETER_TYPE_MAX_ENUM_INTEL = 0x7FFFFFFF +} VkPerformanceParameterTypeINTEL; + +typedef enum VkPerformanceValueTypeINTEL { + VK_PERFORMANCE_VALUE_TYPE_UINT32_INTEL = 0, + VK_PERFORMANCE_VALUE_TYPE_UINT64_INTEL = 1, + VK_PERFORMANCE_VALUE_TYPE_FLOAT_INTEL = 2, + VK_PERFORMANCE_VALUE_TYPE_BOOL_INTEL = 3, + VK_PERFORMANCE_VALUE_TYPE_STRING_INTEL = 4, + VK_PERFORMANCE_VALUE_TYPE_MAX_ENUM_INTEL = 0x7FFFFFFF +} VkPerformanceValueTypeINTEL; +typedef union VkPerformanceValueDataINTEL { + uint32_t value32; + uint64_t value64; + float valueFloat; + VkBool32 valueBool; + const char* valueString; +} VkPerformanceValueDataINTEL; + +typedef struct VkPerformanceValueINTEL { + VkPerformanceValueTypeINTEL type; + VkPerformanceValueDataINTEL data; +} VkPerformanceValueINTEL; + +typedef struct VkInitializePerformanceApiInfoINTEL { + VkStructureType sType; + const void* pNext; + void* pUserData; +} VkInitializePerformanceApiInfoINTEL; + +typedef struct VkQueryPoolPerformanceQueryCreateInfoINTEL { + VkStructureType sType; + const void* pNext; + VkQueryPoolSamplingModeINTEL performanceCountersSampling; +} VkQueryPoolPerformanceQueryCreateInfoINTEL; + +typedef VkQueryPoolPerformanceQueryCreateInfoINTEL VkQueryPoolCreateInfoINTEL; + +typedef struct VkPerformanceMarkerInfoINTEL { + VkStructureType sType; + const void* pNext; + uint64_t marker; +} VkPerformanceMarkerInfoINTEL; + +typedef struct VkPerformanceStreamMarkerInfoINTEL { + VkStructureType sType; + const void* pNext; + uint32_t marker; +} VkPerformanceStreamMarkerInfoINTEL; + +typedef struct VkPerformanceOverrideInfoINTEL { + VkStructureType sType; + const void* pNext; + VkPerformanceOverrideTypeINTEL type; + VkBool32 enable; + uint64_t parameter; +} VkPerformanceOverrideInfoINTEL; + +typedef struct VkPerformanceConfigurationAcquireInfoINTEL { + VkStructureType sType; + const void* pNext; + VkPerformanceConfigurationTypeINTEL type; +} VkPerformanceConfigurationAcquireInfoINTEL; + +typedef VkResult (VKAPI_PTR *PFN_vkInitializePerformanceApiINTEL)(VkDevice device, const VkInitializePerformanceApiInfoINTEL* pInitializeInfo); +typedef void (VKAPI_PTR *PFN_vkUninitializePerformanceApiINTEL)(VkDevice device); +typedef VkResult (VKAPI_PTR *PFN_vkCmdSetPerformanceMarkerINTEL)(VkCommandBuffer commandBuffer, const VkPerformanceMarkerInfoINTEL* pMarkerInfo); +typedef VkResult (VKAPI_PTR *PFN_vkCmdSetPerformanceStreamMarkerINTEL)(VkCommandBuffer commandBuffer, const VkPerformanceStreamMarkerInfoINTEL* pMarkerInfo); +typedef VkResult (VKAPI_PTR *PFN_vkCmdSetPerformanceOverrideINTEL)(VkCommandBuffer commandBuffer, const VkPerformanceOverrideInfoINTEL* pOverrideInfo); +typedef VkResult (VKAPI_PTR *PFN_vkAcquirePerformanceConfigurationINTEL)(VkDevice device, const VkPerformanceConfigurationAcquireInfoINTEL* pAcquireInfo, VkPerformanceConfigurationINTEL* pConfiguration); +typedef VkResult (VKAPI_PTR *PFN_vkReleasePerformanceConfigurationINTEL)(VkDevice device, VkPerformanceConfigurationINTEL configuration); +typedef VkResult (VKAPI_PTR *PFN_vkQueueSetPerformanceConfigurationINTEL)(VkQueue queue, VkPerformanceConfigurationINTEL configuration); +typedef VkResult (VKAPI_PTR *PFN_vkGetPerformanceParameterINTEL)(VkDevice device, VkPerformanceParameterTypeINTEL parameter, VkPerformanceValueINTEL* pValue); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkInitializePerformanceApiINTEL( + VkDevice device, + const VkInitializePerformanceApiInfoINTEL* pInitializeInfo); + +VKAPI_ATTR void VKAPI_CALL vkUninitializePerformanceApiINTEL( + VkDevice device); + +VKAPI_ATTR VkResult VKAPI_CALL vkCmdSetPerformanceMarkerINTEL( + VkCommandBuffer commandBuffer, + const VkPerformanceMarkerInfoINTEL* pMarkerInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkCmdSetPerformanceStreamMarkerINTEL( + VkCommandBuffer commandBuffer, + const VkPerformanceStreamMarkerInfoINTEL* pMarkerInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkCmdSetPerformanceOverrideINTEL( + VkCommandBuffer commandBuffer, + const VkPerformanceOverrideInfoINTEL* pOverrideInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkAcquirePerformanceConfigurationINTEL( + VkDevice device, + const VkPerformanceConfigurationAcquireInfoINTEL* pAcquireInfo, + VkPerformanceConfigurationINTEL* pConfiguration); + +VKAPI_ATTR VkResult VKAPI_CALL vkReleasePerformanceConfigurationINTEL( + VkDevice device, + VkPerformanceConfigurationINTEL configuration); + +VKAPI_ATTR VkResult VKAPI_CALL vkQueueSetPerformanceConfigurationINTEL( + VkQueue queue, + VkPerformanceConfigurationINTEL configuration); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPerformanceParameterINTEL( + VkDevice device, + VkPerformanceParameterTypeINTEL parameter, + VkPerformanceValueINTEL* pValue); +#endif + + +// VK_EXT_pci_bus_info is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_pci_bus_info 1 +#define VK_EXT_PCI_BUS_INFO_SPEC_VERSION 2 +#define VK_EXT_PCI_BUS_INFO_EXTENSION_NAME "VK_EXT_pci_bus_info" +typedef struct VkPhysicalDevicePCIBusInfoPropertiesEXT { + VkStructureType sType; + void* pNext; + uint32_t pciDomain; + uint32_t pciBus; + uint32_t pciDevice; + uint32_t pciFunction; +} VkPhysicalDevicePCIBusInfoPropertiesEXT; + + + +// VK_AMD_display_native_hdr is a preprocessor guard. Do not pass it to API calls. +#define VK_AMD_display_native_hdr 1 +#define VK_AMD_DISPLAY_NATIVE_HDR_SPEC_VERSION 1 +#define VK_AMD_DISPLAY_NATIVE_HDR_EXTENSION_NAME "VK_AMD_display_native_hdr" +typedef struct VkDisplayNativeHdrSurfaceCapabilitiesAMD { + VkStructureType sType; + void* pNext; + VkBool32 localDimmingSupport; +} VkDisplayNativeHdrSurfaceCapabilitiesAMD; + +typedef struct VkSwapchainDisplayNativeHdrCreateInfoAMD { + VkStructureType sType; + const void* pNext; + VkBool32 localDimmingEnable; +} VkSwapchainDisplayNativeHdrCreateInfoAMD; + +typedef void (VKAPI_PTR *PFN_vkSetLocalDimmingAMD)(VkDevice device, VkSwapchainKHR swapChain, VkBool32 localDimmingEnable); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkSetLocalDimmingAMD( + VkDevice device, + VkSwapchainKHR swapChain, + VkBool32 localDimmingEnable); +#endif + + +// VK_EXT_fragment_density_map is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_fragment_density_map 1 +#define VK_EXT_FRAGMENT_DENSITY_MAP_SPEC_VERSION 2 +#define VK_EXT_FRAGMENT_DENSITY_MAP_EXTENSION_NAME "VK_EXT_fragment_density_map" +typedef struct VkPhysicalDeviceFragmentDensityMapFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 fragmentDensityMap; + VkBool32 fragmentDensityMapDynamic; + VkBool32 fragmentDensityMapNonSubsampledImages; +} VkPhysicalDeviceFragmentDensityMapFeaturesEXT; + +typedef struct VkPhysicalDeviceFragmentDensityMapPropertiesEXT { + VkStructureType sType; + void* pNext; + VkExtent2D minFragmentDensityTexelSize; + VkExtent2D maxFragmentDensityTexelSize; + VkBool32 fragmentDensityInvocations; +} VkPhysicalDeviceFragmentDensityMapPropertiesEXT; + +typedef struct VkRenderPassFragmentDensityMapCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkAttachmentReference fragmentDensityMapAttachment; +} VkRenderPassFragmentDensityMapCreateInfoEXT; + + + +// VK_EXT_scalar_block_layout is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_scalar_block_layout 1 +#define VK_EXT_SCALAR_BLOCK_LAYOUT_SPEC_VERSION 1 +#define VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME "VK_EXT_scalar_block_layout" +typedef VkPhysicalDeviceScalarBlockLayoutFeatures VkPhysicalDeviceScalarBlockLayoutFeaturesEXT; + + + +// VK_GOOGLE_hlsl_functionality1 is a preprocessor guard. Do not pass it to API calls. +#define VK_GOOGLE_hlsl_functionality1 1 +#define VK_GOOGLE_HLSL_FUNCTIONALITY_1_SPEC_VERSION 1 +#define VK_GOOGLE_HLSL_FUNCTIONALITY_1_EXTENSION_NAME "VK_GOOGLE_hlsl_functionality1" +#define VK_GOOGLE_HLSL_FUNCTIONALITY1_SPEC_VERSION VK_GOOGLE_HLSL_FUNCTIONALITY_1_SPEC_VERSION +#define VK_GOOGLE_HLSL_FUNCTIONALITY1_EXTENSION_NAME VK_GOOGLE_HLSL_FUNCTIONALITY_1_EXTENSION_NAME + + +// VK_GOOGLE_decorate_string is a preprocessor guard. Do not pass it to API calls. +#define VK_GOOGLE_decorate_string 1 +#define VK_GOOGLE_DECORATE_STRING_SPEC_VERSION 1 +#define VK_GOOGLE_DECORATE_STRING_EXTENSION_NAME "VK_GOOGLE_decorate_string" + + +// VK_EXT_subgroup_size_control is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_subgroup_size_control 1 +#define VK_EXT_SUBGROUP_SIZE_CONTROL_SPEC_VERSION 2 +#define VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME "VK_EXT_subgroup_size_control" +typedef VkPhysicalDeviceSubgroupSizeControlFeatures VkPhysicalDeviceSubgroupSizeControlFeaturesEXT; + +typedef VkPhysicalDeviceSubgroupSizeControlProperties VkPhysicalDeviceSubgroupSizeControlPropertiesEXT; + +typedef VkPipelineShaderStageRequiredSubgroupSizeCreateInfo VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT; + + + +// VK_AMD_shader_core_properties2 is a preprocessor guard. Do not pass it to API calls. +#define VK_AMD_shader_core_properties2 1 +#define VK_AMD_SHADER_CORE_PROPERTIES_2_SPEC_VERSION 1 +#define VK_AMD_SHADER_CORE_PROPERTIES_2_EXTENSION_NAME "VK_AMD_shader_core_properties2" + +typedef enum VkShaderCorePropertiesFlagBitsAMD { + VK_SHADER_CORE_PROPERTIES_FLAG_BITS_MAX_ENUM_AMD = 0x7FFFFFFF +} VkShaderCorePropertiesFlagBitsAMD; +typedef VkFlags VkShaderCorePropertiesFlagsAMD; +typedef struct VkPhysicalDeviceShaderCoreProperties2AMD { + VkStructureType sType; + void* pNext; + VkShaderCorePropertiesFlagsAMD shaderCoreFeatures; + uint32_t activeComputeUnitCount; +} VkPhysicalDeviceShaderCoreProperties2AMD; + + + +// VK_AMD_device_coherent_memory is a preprocessor guard. Do not pass it to API calls. +#define VK_AMD_device_coherent_memory 1 +#define VK_AMD_DEVICE_COHERENT_MEMORY_SPEC_VERSION 1 +#define VK_AMD_DEVICE_COHERENT_MEMORY_EXTENSION_NAME "VK_AMD_device_coherent_memory" +typedef struct VkPhysicalDeviceCoherentMemoryFeaturesAMD { + VkStructureType sType; + void* pNext; + VkBool32 deviceCoherentMemory; +} VkPhysicalDeviceCoherentMemoryFeaturesAMD; + + + +// VK_EXT_shader_image_atomic_int64 is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_shader_image_atomic_int64 1 +#define VK_EXT_SHADER_IMAGE_ATOMIC_INT64_SPEC_VERSION 1 +#define VK_EXT_SHADER_IMAGE_ATOMIC_INT64_EXTENSION_NAME "VK_EXT_shader_image_atomic_int64" +typedef struct VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 shaderImageInt64Atomics; + VkBool32 sparseImageInt64Atomics; +} VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT; + + + +// VK_EXT_memory_budget is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_memory_budget 1 +#define VK_EXT_MEMORY_BUDGET_SPEC_VERSION 1 +#define VK_EXT_MEMORY_BUDGET_EXTENSION_NAME "VK_EXT_memory_budget" +typedef struct VkPhysicalDeviceMemoryBudgetPropertiesEXT { + VkStructureType sType; + void* pNext; + VkDeviceSize heapBudget[VK_MAX_MEMORY_HEAPS]; + VkDeviceSize heapUsage[VK_MAX_MEMORY_HEAPS]; +} VkPhysicalDeviceMemoryBudgetPropertiesEXT; + + + +// VK_EXT_memory_priority is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_memory_priority 1 +#define VK_EXT_MEMORY_PRIORITY_SPEC_VERSION 1 +#define VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME "VK_EXT_memory_priority" +typedef struct VkPhysicalDeviceMemoryPriorityFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 memoryPriority; +} VkPhysicalDeviceMemoryPriorityFeaturesEXT; + +typedef struct VkMemoryPriorityAllocateInfoEXT { + VkStructureType sType; + const void* pNext; + float priority; +} VkMemoryPriorityAllocateInfoEXT; + + + +// VK_NV_dedicated_allocation_image_aliasing is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_dedicated_allocation_image_aliasing 1 +#define VK_NV_DEDICATED_ALLOCATION_IMAGE_ALIASING_SPEC_VERSION 1 +#define VK_NV_DEDICATED_ALLOCATION_IMAGE_ALIASING_EXTENSION_NAME "VK_NV_dedicated_allocation_image_aliasing" +typedef struct VkPhysicalDeviceDedicatedAllocationImageAliasingFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 dedicatedAllocationImageAliasing; +} VkPhysicalDeviceDedicatedAllocationImageAliasingFeaturesNV; + + + +// VK_EXT_buffer_device_address is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_buffer_device_address 1 +#define VK_EXT_BUFFER_DEVICE_ADDRESS_SPEC_VERSION 2 +#define VK_EXT_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME "VK_EXT_buffer_device_address" +typedef struct VkPhysicalDeviceBufferDeviceAddressFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 bufferDeviceAddress; + VkBool32 bufferDeviceAddressCaptureReplay; + VkBool32 bufferDeviceAddressMultiDevice; +} VkPhysicalDeviceBufferDeviceAddressFeaturesEXT; + +typedef VkPhysicalDeviceBufferDeviceAddressFeaturesEXT VkPhysicalDeviceBufferAddressFeaturesEXT; + +typedef VkBufferDeviceAddressInfo VkBufferDeviceAddressInfoEXT; + +typedef struct VkBufferDeviceAddressCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkDeviceAddress deviceAddress; +} VkBufferDeviceAddressCreateInfoEXT; + +typedef VkDeviceAddress (VKAPI_PTR *PFN_vkGetBufferDeviceAddressEXT)(VkDevice device, const VkBufferDeviceAddressInfo* pInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkDeviceAddress VKAPI_CALL vkGetBufferDeviceAddressEXT( + VkDevice device, + const VkBufferDeviceAddressInfo* pInfo); +#endif + + +// VK_EXT_tooling_info is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_tooling_info 1 +#define VK_EXT_TOOLING_INFO_SPEC_VERSION 1 +#define VK_EXT_TOOLING_INFO_EXTENSION_NAME "VK_EXT_tooling_info" +typedef VkToolPurposeFlagBits VkToolPurposeFlagBitsEXT; + +typedef VkToolPurposeFlags VkToolPurposeFlagsEXT; + +typedef VkPhysicalDeviceToolProperties VkPhysicalDeviceToolPropertiesEXT; + +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceToolPropertiesEXT)(VkPhysicalDevice physicalDevice, uint32_t* pToolCount, VkPhysicalDeviceToolProperties* pToolProperties); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceToolPropertiesEXT( + VkPhysicalDevice physicalDevice, + uint32_t* pToolCount, + VkPhysicalDeviceToolProperties* pToolProperties); +#endif + + +// VK_EXT_separate_stencil_usage is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_separate_stencil_usage 1 +#define VK_EXT_SEPARATE_STENCIL_USAGE_SPEC_VERSION 1 +#define VK_EXT_SEPARATE_STENCIL_USAGE_EXTENSION_NAME "VK_EXT_separate_stencil_usage" +typedef VkImageStencilUsageCreateInfo VkImageStencilUsageCreateInfoEXT; + + + +// VK_EXT_validation_features is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_validation_features 1 +#define VK_EXT_VALIDATION_FEATURES_SPEC_VERSION 6 +#define VK_EXT_VALIDATION_FEATURES_EXTENSION_NAME "VK_EXT_validation_features" + +typedef enum VkValidationFeatureEnableEXT { + VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT = 0, + VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_RESERVE_BINDING_SLOT_EXT = 1, + VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES_EXT = 2, + VK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT = 3, + VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT = 4, + VK_VALIDATION_FEATURE_ENABLE_MAX_ENUM_EXT = 0x7FFFFFFF +} VkValidationFeatureEnableEXT; + +typedef enum VkValidationFeatureDisableEXT { + VK_VALIDATION_FEATURE_DISABLE_ALL_EXT = 0, + VK_VALIDATION_FEATURE_DISABLE_SHADERS_EXT = 1, + VK_VALIDATION_FEATURE_DISABLE_THREAD_SAFETY_EXT = 2, + VK_VALIDATION_FEATURE_DISABLE_API_PARAMETERS_EXT = 3, + VK_VALIDATION_FEATURE_DISABLE_OBJECT_LIFETIMES_EXT = 4, + VK_VALIDATION_FEATURE_DISABLE_CORE_CHECKS_EXT = 5, + VK_VALIDATION_FEATURE_DISABLE_UNIQUE_HANDLES_EXT = 6, + VK_VALIDATION_FEATURE_DISABLE_SHADER_VALIDATION_CACHE_EXT = 7, + VK_VALIDATION_FEATURE_DISABLE_MAX_ENUM_EXT = 0x7FFFFFFF +} VkValidationFeatureDisableEXT; +typedef struct VkValidationFeaturesEXT { + VkStructureType sType; + const void* pNext; + uint32_t enabledValidationFeatureCount; + const VkValidationFeatureEnableEXT* pEnabledValidationFeatures; + uint32_t disabledValidationFeatureCount; + const VkValidationFeatureDisableEXT* pDisabledValidationFeatures; +} VkValidationFeaturesEXT; + + + +// VK_NV_cooperative_matrix is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_cooperative_matrix 1 +#define VK_NV_COOPERATIVE_MATRIX_SPEC_VERSION 1 +#define VK_NV_COOPERATIVE_MATRIX_EXTENSION_NAME "VK_NV_cooperative_matrix" +typedef VkComponentTypeKHR VkComponentTypeNV; + +typedef VkScopeKHR VkScopeNV; + +typedef struct VkCooperativeMatrixPropertiesNV { + VkStructureType sType; + void* pNext; + uint32_t MSize; + uint32_t NSize; + uint32_t KSize; + VkComponentTypeNV AType; + VkComponentTypeNV BType; + VkComponentTypeNV CType; + VkComponentTypeNV DType; + VkScopeNV scope; +} VkCooperativeMatrixPropertiesNV; + +typedef struct VkPhysicalDeviceCooperativeMatrixFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 cooperativeMatrix; + VkBool32 cooperativeMatrixRobustBufferAccess; +} VkPhysicalDeviceCooperativeMatrixFeaturesNV; + +typedef struct VkPhysicalDeviceCooperativeMatrixPropertiesNV { + VkStructureType sType; + void* pNext; + VkShaderStageFlags cooperativeMatrixSupportedStages; +} VkPhysicalDeviceCooperativeMatrixPropertiesNV; + +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceCooperativeMatrixPropertiesNV)(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkCooperativeMatrixPropertiesNV* pProperties); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceCooperativeMatrixPropertiesNV( + VkPhysicalDevice physicalDevice, + uint32_t* pPropertyCount, + VkCooperativeMatrixPropertiesNV* pProperties); +#endif + + +// VK_NV_coverage_reduction_mode is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_coverage_reduction_mode 1 +#define VK_NV_COVERAGE_REDUCTION_MODE_SPEC_VERSION 1 +#define VK_NV_COVERAGE_REDUCTION_MODE_EXTENSION_NAME "VK_NV_coverage_reduction_mode" + +typedef enum VkCoverageReductionModeNV { + VK_COVERAGE_REDUCTION_MODE_MERGE_NV = 0, + VK_COVERAGE_REDUCTION_MODE_TRUNCATE_NV = 1, + VK_COVERAGE_REDUCTION_MODE_MAX_ENUM_NV = 0x7FFFFFFF +} VkCoverageReductionModeNV; +typedef VkFlags VkPipelineCoverageReductionStateCreateFlagsNV; +typedef struct VkPhysicalDeviceCoverageReductionModeFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 coverageReductionMode; +} VkPhysicalDeviceCoverageReductionModeFeaturesNV; + +typedef struct VkPipelineCoverageReductionStateCreateInfoNV { + VkStructureType sType; + const void* pNext; + VkPipelineCoverageReductionStateCreateFlagsNV flags; + VkCoverageReductionModeNV coverageReductionMode; +} VkPipelineCoverageReductionStateCreateInfoNV; + +typedef struct VkFramebufferMixedSamplesCombinationNV { + VkStructureType sType; + void* pNext; + VkCoverageReductionModeNV coverageReductionMode; + VkSampleCountFlagBits rasterizationSamples; + VkSampleCountFlags depthStencilSamples; + VkSampleCountFlags colorSamples; +} VkFramebufferMixedSamplesCombinationNV; + +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV)(VkPhysicalDevice physicalDevice, uint32_t* pCombinationCount, VkFramebufferMixedSamplesCombinationNV* pCombinations); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV( + VkPhysicalDevice physicalDevice, + uint32_t* pCombinationCount, + VkFramebufferMixedSamplesCombinationNV* pCombinations); +#endif + + +// VK_EXT_fragment_shader_interlock is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_fragment_shader_interlock 1 +#define VK_EXT_FRAGMENT_SHADER_INTERLOCK_SPEC_VERSION 1 +#define VK_EXT_FRAGMENT_SHADER_INTERLOCK_EXTENSION_NAME "VK_EXT_fragment_shader_interlock" +typedef struct VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 fragmentShaderSampleInterlock; + VkBool32 fragmentShaderPixelInterlock; + VkBool32 fragmentShaderShadingRateInterlock; +} VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT; + + + +// VK_EXT_ycbcr_image_arrays is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_ycbcr_image_arrays 1 +#define VK_EXT_YCBCR_IMAGE_ARRAYS_SPEC_VERSION 1 +#define VK_EXT_YCBCR_IMAGE_ARRAYS_EXTENSION_NAME "VK_EXT_ycbcr_image_arrays" +typedef struct VkPhysicalDeviceYcbcrImageArraysFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 ycbcrImageArrays; +} VkPhysicalDeviceYcbcrImageArraysFeaturesEXT; + + + +// VK_EXT_provoking_vertex is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_provoking_vertex 1 +#define VK_EXT_PROVOKING_VERTEX_SPEC_VERSION 1 +#define VK_EXT_PROVOKING_VERTEX_EXTENSION_NAME "VK_EXT_provoking_vertex" + +typedef enum VkProvokingVertexModeEXT { + VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT = 0, + VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT = 1, + VK_PROVOKING_VERTEX_MODE_MAX_ENUM_EXT = 0x7FFFFFFF +} VkProvokingVertexModeEXT; +typedef struct VkPhysicalDeviceProvokingVertexFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 provokingVertexLast; + VkBool32 transformFeedbackPreservesProvokingVertex; +} VkPhysicalDeviceProvokingVertexFeaturesEXT; + +typedef struct VkPhysicalDeviceProvokingVertexPropertiesEXT { + VkStructureType sType; + void* pNext; + VkBool32 provokingVertexModePerPipeline; + VkBool32 transformFeedbackPreservesTriangleFanProvokingVertex; +} VkPhysicalDeviceProvokingVertexPropertiesEXT; + +typedef struct VkPipelineRasterizationProvokingVertexStateCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkProvokingVertexModeEXT provokingVertexMode; +} VkPipelineRasterizationProvokingVertexStateCreateInfoEXT; + + + +// VK_EXT_headless_surface is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_headless_surface 1 +#define VK_EXT_HEADLESS_SURFACE_SPEC_VERSION 1 +#define VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME "VK_EXT_headless_surface" +typedef VkFlags VkHeadlessSurfaceCreateFlagsEXT; +typedef struct VkHeadlessSurfaceCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkHeadlessSurfaceCreateFlagsEXT flags; +} VkHeadlessSurfaceCreateInfoEXT; + +typedef VkResult (VKAPI_PTR *PFN_vkCreateHeadlessSurfaceEXT)(VkInstance instance, const VkHeadlessSurfaceCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateHeadlessSurfaceEXT( + VkInstance instance, + const VkHeadlessSurfaceCreateInfoEXT* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface); +#endif + + +// VK_EXT_line_rasterization is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_line_rasterization 1 +#define VK_EXT_LINE_RASTERIZATION_SPEC_VERSION 1 +#define VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME "VK_EXT_line_rasterization" + +typedef enum VkLineRasterizationModeEXT { + VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT = 0, + VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT = 1, + VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT = 2, + VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT = 3, + VK_LINE_RASTERIZATION_MODE_MAX_ENUM_EXT = 0x7FFFFFFF +} VkLineRasterizationModeEXT; +typedef struct VkPhysicalDeviceLineRasterizationFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 rectangularLines; + VkBool32 bresenhamLines; + VkBool32 smoothLines; + VkBool32 stippledRectangularLines; + VkBool32 stippledBresenhamLines; + VkBool32 stippledSmoothLines; +} VkPhysicalDeviceLineRasterizationFeaturesEXT; + +typedef struct VkPhysicalDeviceLineRasterizationPropertiesEXT { + VkStructureType sType; + void* pNext; + uint32_t lineSubPixelPrecisionBits; +} VkPhysicalDeviceLineRasterizationPropertiesEXT; + +typedef struct VkPipelineRasterizationLineStateCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkLineRasterizationModeEXT lineRasterizationMode; + VkBool32 stippledLineEnable; + uint32_t lineStippleFactor; + uint16_t lineStipplePattern; +} VkPipelineRasterizationLineStateCreateInfoEXT; + +typedef void (VKAPI_PTR *PFN_vkCmdSetLineStippleEXT)(VkCommandBuffer commandBuffer, uint32_t lineStippleFactor, uint16_t lineStipplePattern); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdSetLineStippleEXT( + VkCommandBuffer commandBuffer, + uint32_t lineStippleFactor, + uint16_t lineStipplePattern); +#endif + + +// VK_EXT_shader_atomic_float is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_shader_atomic_float 1 +#define VK_EXT_SHADER_ATOMIC_FLOAT_SPEC_VERSION 1 +#define VK_EXT_SHADER_ATOMIC_FLOAT_EXTENSION_NAME "VK_EXT_shader_atomic_float" +typedef struct VkPhysicalDeviceShaderAtomicFloatFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 shaderBufferFloat32Atomics; + VkBool32 shaderBufferFloat32AtomicAdd; + VkBool32 shaderBufferFloat64Atomics; + VkBool32 shaderBufferFloat64AtomicAdd; + VkBool32 shaderSharedFloat32Atomics; + VkBool32 shaderSharedFloat32AtomicAdd; + VkBool32 shaderSharedFloat64Atomics; + VkBool32 shaderSharedFloat64AtomicAdd; + VkBool32 shaderImageFloat32Atomics; + VkBool32 shaderImageFloat32AtomicAdd; + VkBool32 sparseImageFloat32Atomics; + VkBool32 sparseImageFloat32AtomicAdd; +} VkPhysicalDeviceShaderAtomicFloatFeaturesEXT; + + + +// VK_EXT_host_query_reset is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_host_query_reset 1 +#define VK_EXT_HOST_QUERY_RESET_SPEC_VERSION 1 +#define VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME "VK_EXT_host_query_reset" +typedef VkPhysicalDeviceHostQueryResetFeatures VkPhysicalDeviceHostQueryResetFeaturesEXT; + +typedef void (VKAPI_PTR *PFN_vkResetQueryPoolEXT)(VkDevice device, VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkResetQueryPoolEXT( + VkDevice device, + VkQueryPool queryPool, + uint32_t firstQuery, + uint32_t queryCount); +#endif + + +// VK_EXT_index_type_uint8 is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_index_type_uint8 1 +#define VK_EXT_INDEX_TYPE_UINT8_SPEC_VERSION 1 +#define VK_EXT_INDEX_TYPE_UINT8_EXTENSION_NAME "VK_EXT_index_type_uint8" +typedef struct VkPhysicalDeviceIndexTypeUint8FeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 indexTypeUint8; +} VkPhysicalDeviceIndexTypeUint8FeaturesEXT; + + + +// VK_EXT_extended_dynamic_state is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_extended_dynamic_state 1 +#define VK_EXT_EXTENDED_DYNAMIC_STATE_SPEC_VERSION 1 +#define VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME "VK_EXT_extended_dynamic_state" +typedef struct VkPhysicalDeviceExtendedDynamicStateFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 extendedDynamicState; +} VkPhysicalDeviceExtendedDynamicStateFeaturesEXT; + +typedef void (VKAPI_PTR *PFN_vkCmdSetCullModeEXT)(VkCommandBuffer commandBuffer, VkCullModeFlags cullMode); +typedef void (VKAPI_PTR *PFN_vkCmdSetFrontFaceEXT)(VkCommandBuffer commandBuffer, VkFrontFace frontFace); +typedef void (VKAPI_PTR *PFN_vkCmdSetPrimitiveTopologyEXT)(VkCommandBuffer commandBuffer, VkPrimitiveTopology primitiveTopology); +typedef void (VKAPI_PTR *PFN_vkCmdSetViewportWithCountEXT)(VkCommandBuffer commandBuffer, uint32_t viewportCount, const VkViewport* pViewports); +typedef void (VKAPI_PTR *PFN_vkCmdSetScissorWithCountEXT)(VkCommandBuffer commandBuffer, uint32_t scissorCount, const VkRect2D* pScissors); +typedef void (VKAPI_PTR *PFN_vkCmdBindVertexBuffers2EXT)(VkCommandBuffer commandBuffer, uint32_t firstBinding, uint32_t bindingCount, const VkBuffer* pBuffers, const VkDeviceSize* pOffsets, const VkDeviceSize* pSizes, const VkDeviceSize* pStrides); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthTestEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 depthTestEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthWriteEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 depthWriteEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthCompareOpEXT)(VkCommandBuffer commandBuffer, VkCompareOp depthCompareOp); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthBoundsTestEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 depthBoundsTestEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetStencilTestEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 stencilTestEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetStencilOpEXT)(VkCommandBuffer commandBuffer, VkStencilFaceFlags faceMask, VkStencilOp failOp, VkStencilOp passOp, VkStencilOp depthFailOp, VkCompareOp compareOp); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdSetCullModeEXT( + VkCommandBuffer commandBuffer, + VkCullModeFlags cullMode); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetFrontFaceEXT( + VkCommandBuffer commandBuffer, + VkFrontFace frontFace); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetPrimitiveTopologyEXT( + VkCommandBuffer commandBuffer, + VkPrimitiveTopology primitiveTopology); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetViewportWithCountEXT( + VkCommandBuffer commandBuffer, + uint32_t viewportCount, + const VkViewport* pViewports); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetScissorWithCountEXT( + VkCommandBuffer commandBuffer, + uint32_t scissorCount, + const VkRect2D* pScissors); + +VKAPI_ATTR void VKAPI_CALL vkCmdBindVertexBuffers2EXT( + VkCommandBuffer commandBuffer, + uint32_t firstBinding, + uint32_t bindingCount, + const VkBuffer* pBuffers, + const VkDeviceSize* pOffsets, + const VkDeviceSize* pSizes, + const VkDeviceSize* pStrides); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthTestEnableEXT( + VkCommandBuffer commandBuffer, + VkBool32 depthTestEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthWriteEnableEXT( + VkCommandBuffer commandBuffer, + VkBool32 depthWriteEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthCompareOpEXT( + VkCommandBuffer commandBuffer, + VkCompareOp depthCompareOp); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBoundsTestEnableEXT( + VkCommandBuffer commandBuffer, + VkBool32 depthBoundsTestEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilTestEnableEXT( + VkCommandBuffer commandBuffer, + VkBool32 stencilTestEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetStencilOpEXT( + VkCommandBuffer commandBuffer, + VkStencilFaceFlags faceMask, + VkStencilOp failOp, + VkStencilOp passOp, + VkStencilOp depthFailOp, + VkCompareOp compareOp); +#endif + + +// VK_EXT_host_image_copy is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_host_image_copy 1 +#define VK_EXT_HOST_IMAGE_COPY_SPEC_VERSION 1 +#define VK_EXT_HOST_IMAGE_COPY_EXTENSION_NAME "VK_EXT_host_image_copy" + +typedef enum VkHostImageCopyFlagBitsEXT { + VK_HOST_IMAGE_COPY_MEMCPY_EXT = 0x00000001, + VK_HOST_IMAGE_COPY_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkHostImageCopyFlagBitsEXT; +typedef VkFlags VkHostImageCopyFlagsEXT; +typedef struct VkPhysicalDeviceHostImageCopyFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 hostImageCopy; +} VkPhysicalDeviceHostImageCopyFeaturesEXT; + +typedef struct VkPhysicalDeviceHostImageCopyPropertiesEXT { + VkStructureType sType; + void* pNext; + uint32_t copySrcLayoutCount; + VkImageLayout* pCopySrcLayouts; + uint32_t copyDstLayoutCount; + VkImageLayout* pCopyDstLayouts; + uint8_t optimalTilingLayoutUUID[VK_UUID_SIZE]; + VkBool32 identicalMemoryTypeRequirements; +} VkPhysicalDeviceHostImageCopyPropertiesEXT; + +typedef struct VkMemoryToImageCopyEXT { + VkStructureType sType; + const void* pNext; + const void* pHostPointer; + uint32_t memoryRowLength; + uint32_t memoryImageHeight; + VkImageSubresourceLayers imageSubresource; + VkOffset3D imageOffset; + VkExtent3D imageExtent; +} VkMemoryToImageCopyEXT; + +typedef struct VkImageToMemoryCopyEXT { + VkStructureType sType; + const void* pNext; + void* pHostPointer; + uint32_t memoryRowLength; + uint32_t memoryImageHeight; + VkImageSubresourceLayers imageSubresource; + VkOffset3D imageOffset; + VkExtent3D imageExtent; +} VkImageToMemoryCopyEXT; + +typedef struct VkCopyMemoryToImageInfoEXT { + VkStructureType sType; + const void* pNext; + VkHostImageCopyFlagsEXT flags; + VkImage dstImage; + VkImageLayout dstImageLayout; + uint32_t regionCount; + const VkMemoryToImageCopyEXT* pRegions; +} VkCopyMemoryToImageInfoEXT; + +typedef struct VkCopyImageToMemoryInfoEXT { + VkStructureType sType; + const void* pNext; + VkHostImageCopyFlagsEXT flags; + VkImage srcImage; + VkImageLayout srcImageLayout; + uint32_t regionCount; + const VkImageToMemoryCopyEXT* pRegions; +} VkCopyImageToMemoryInfoEXT; + +typedef struct VkCopyImageToImageInfoEXT { + VkStructureType sType; + const void* pNext; + VkHostImageCopyFlagsEXT flags; + VkImage srcImage; + VkImageLayout srcImageLayout; + VkImage dstImage; + VkImageLayout dstImageLayout; + uint32_t regionCount; + const VkImageCopy2* pRegions; +} VkCopyImageToImageInfoEXT; + +typedef struct VkHostImageLayoutTransitionInfoEXT { + VkStructureType sType; + const void* pNext; + VkImage image; + VkImageLayout oldLayout; + VkImageLayout newLayout; + VkImageSubresourceRange subresourceRange; +} VkHostImageLayoutTransitionInfoEXT; + +typedef struct VkSubresourceHostMemcpySizeEXT { + VkStructureType sType; + void* pNext; + VkDeviceSize size; +} VkSubresourceHostMemcpySizeEXT; + +typedef struct VkHostImageCopyDevicePerformanceQueryEXT { + VkStructureType sType; + void* pNext; + VkBool32 optimalDeviceAccess; + VkBool32 identicalMemoryLayout; +} VkHostImageCopyDevicePerformanceQueryEXT; + +typedef VkSubresourceLayout2KHR VkSubresourceLayout2EXT; + +typedef VkImageSubresource2KHR VkImageSubresource2EXT; + +typedef VkResult (VKAPI_PTR *PFN_vkCopyMemoryToImageEXT)(VkDevice device, const VkCopyMemoryToImageInfoEXT* pCopyMemoryToImageInfo); +typedef VkResult (VKAPI_PTR *PFN_vkCopyImageToMemoryEXT)(VkDevice device, const VkCopyImageToMemoryInfoEXT* pCopyImageToMemoryInfo); +typedef VkResult (VKAPI_PTR *PFN_vkCopyImageToImageEXT)(VkDevice device, const VkCopyImageToImageInfoEXT* pCopyImageToImageInfo); +typedef VkResult (VKAPI_PTR *PFN_vkTransitionImageLayoutEXT)(VkDevice device, uint32_t transitionCount, const VkHostImageLayoutTransitionInfoEXT* pTransitions); +typedef void (VKAPI_PTR *PFN_vkGetImageSubresourceLayout2EXT)(VkDevice device, VkImage image, const VkImageSubresource2KHR* pSubresource, VkSubresourceLayout2KHR* pLayout); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCopyMemoryToImageEXT( + VkDevice device, + const VkCopyMemoryToImageInfoEXT* pCopyMemoryToImageInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkCopyImageToMemoryEXT( + VkDevice device, + const VkCopyImageToMemoryInfoEXT* pCopyImageToMemoryInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkCopyImageToImageEXT( + VkDevice device, + const VkCopyImageToImageInfoEXT* pCopyImageToImageInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkTransitionImageLayoutEXT( + VkDevice device, + uint32_t transitionCount, + const VkHostImageLayoutTransitionInfoEXT* pTransitions); + +VKAPI_ATTR void VKAPI_CALL vkGetImageSubresourceLayout2EXT( + VkDevice device, + VkImage image, + const VkImageSubresource2KHR* pSubresource, + VkSubresourceLayout2KHR* pLayout); +#endif + + +// VK_EXT_shader_atomic_float2 is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_shader_atomic_float2 1 +#define VK_EXT_SHADER_ATOMIC_FLOAT_2_SPEC_VERSION 1 +#define VK_EXT_SHADER_ATOMIC_FLOAT_2_EXTENSION_NAME "VK_EXT_shader_atomic_float2" +typedef struct VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 shaderBufferFloat16Atomics; + VkBool32 shaderBufferFloat16AtomicAdd; + VkBool32 shaderBufferFloat16AtomicMinMax; + VkBool32 shaderBufferFloat32AtomicMinMax; + VkBool32 shaderBufferFloat64AtomicMinMax; + VkBool32 shaderSharedFloat16Atomics; + VkBool32 shaderSharedFloat16AtomicAdd; + VkBool32 shaderSharedFloat16AtomicMinMax; + VkBool32 shaderSharedFloat32AtomicMinMax; + VkBool32 shaderSharedFloat64AtomicMinMax; + VkBool32 shaderImageFloat32AtomicMinMax; + VkBool32 sparseImageFloat32AtomicMinMax; +} VkPhysicalDeviceShaderAtomicFloat2FeaturesEXT; + + + +// VK_EXT_surface_maintenance1 is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_surface_maintenance1 1 +#define VK_EXT_SURFACE_MAINTENANCE_1_SPEC_VERSION 1 +#define VK_EXT_SURFACE_MAINTENANCE_1_EXTENSION_NAME "VK_EXT_surface_maintenance1" + +typedef enum VkPresentScalingFlagBitsEXT { + VK_PRESENT_SCALING_ONE_TO_ONE_BIT_EXT = 0x00000001, + VK_PRESENT_SCALING_ASPECT_RATIO_STRETCH_BIT_EXT = 0x00000002, + VK_PRESENT_SCALING_STRETCH_BIT_EXT = 0x00000004, + VK_PRESENT_SCALING_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkPresentScalingFlagBitsEXT; +typedef VkFlags VkPresentScalingFlagsEXT; + +typedef enum VkPresentGravityFlagBitsEXT { + VK_PRESENT_GRAVITY_MIN_BIT_EXT = 0x00000001, + VK_PRESENT_GRAVITY_MAX_BIT_EXT = 0x00000002, + VK_PRESENT_GRAVITY_CENTERED_BIT_EXT = 0x00000004, + VK_PRESENT_GRAVITY_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkPresentGravityFlagBitsEXT; +typedef VkFlags VkPresentGravityFlagsEXT; +typedef struct VkSurfacePresentModeEXT { + VkStructureType sType; + void* pNext; + VkPresentModeKHR presentMode; +} VkSurfacePresentModeEXT; + +typedef struct VkSurfacePresentScalingCapabilitiesEXT { + VkStructureType sType; + void* pNext; + VkPresentScalingFlagsEXT supportedPresentScaling; + VkPresentGravityFlagsEXT supportedPresentGravityX; + VkPresentGravityFlagsEXT supportedPresentGravityY; + VkExtent2D minScaledImageExtent; + VkExtent2D maxScaledImageExtent; +} VkSurfacePresentScalingCapabilitiesEXT; + +typedef struct VkSurfacePresentModeCompatibilityEXT { + VkStructureType sType; + void* pNext; + uint32_t presentModeCount; + VkPresentModeKHR* pPresentModes; +} VkSurfacePresentModeCompatibilityEXT; + + + +// VK_EXT_swapchain_maintenance1 is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_swapchain_maintenance1 1 +#define VK_EXT_SWAPCHAIN_MAINTENANCE_1_SPEC_VERSION 1 +#define VK_EXT_SWAPCHAIN_MAINTENANCE_1_EXTENSION_NAME "VK_EXT_swapchain_maintenance1" +typedef struct VkPhysicalDeviceSwapchainMaintenance1FeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 swapchainMaintenance1; +} VkPhysicalDeviceSwapchainMaintenance1FeaturesEXT; + +typedef struct VkSwapchainPresentFenceInfoEXT { + VkStructureType sType; + const void* pNext; + uint32_t swapchainCount; + const VkFence* pFences; +} VkSwapchainPresentFenceInfoEXT; + +typedef struct VkSwapchainPresentModesCreateInfoEXT { + VkStructureType sType; + const void* pNext; + uint32_t presentModeCount; + const VkPresentModeKHR* pPresentModes; +} VkSwapchainPresentModesCreateInfoEXT; + +typedef struct VkSwapchainPresentModeInfoEXT { + VkStructureType sType; + const void* pNext; + uint32_t swapchainCount; + const VkPresentModeKHR* pPresentModes; +} VkSwapchainPresentModeInfoEXT; + +typedef struct VkSwapchainPresentScalingCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkPresentScalingFlagsEXT scalingBehavior; + VkPresentGravityFlagsEXT presentGravityX; + VkPresentGravityFlagsEXT presentGravityY; +} VkSwapchainPresentScalingCreateInfoEXT; + +typedef struct VkReleaseSwapchainImagesInfoEXT { + VkStructureType sType; + const void* pNext; + VkSwapchainKHR swapchain; + uint32_t imageIndexCount; + const uint32_t* pImageIndices; +} VkReleaseSwapchainImagesInfoEXT; + +typedef VkResult (VKAPI_PTR *PFN_vkReleaseSwapchainImagesEXT)(VkDevice device, const VkReleaseSwapchainImagesInfoEXT* pReleaseInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkReleaseSwapchainImagesEXT( + VkDevice device, + const VkReleaseSwapchainImagesInfoEXT* pReleaseInfo); +#endif + + +// VK_EXT_shader_demote_to_helper_invocation is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_shader_demote_to_helper_invocation 1 +#define VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_SPEC_VERSION 1 +#define VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME "VK_EXT_shader_demote_to_helper_invocation" +typedef VkPhysicalDeviceShaderDemoteToHelperInvocationFeatures VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT; + + + +// VK_NV_device_generated_commands is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_device_generated_commands 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkIndirectCommandsLayoutNV) +#define VK_NV_DEVICE_GENERATED_COMMANDS_SPEC_VERSION 3 +#define VK_NV_DEVICE_GENERATED_COMMANDS_EXTENSION_NAME "VK_NV_device_generated_commands" + +typedef enum VkIndirectCommandsTokenTypeNV { + VK_INDIRECT_COMMANDS_TOKEN_TYPE_SHADER_GROUP_NV = 0, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_STATE_FLAGS_NV = 1, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_INDEX_BUFFER_NV = 2, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_VERTEX_BUFFER_NV = 3, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_PUSH_CONSTANT_NV = 4, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_INDEXED_NV = 5, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_NV = 6, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_TASKS_NV = 7, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_DRAW_MESH_TASKS_NV = 1000328000, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_PIPELINE_NV = 1000428003, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_DISPATCH_NV = 1000428004, + VK_INDIRECT_COMMANDS_TOKEN_TYPE_MAX_ENUM_NV = 0x7FFFFFFF +} VkIndirectCommandsTokenTypeNV; + +typedef enum VkIndirectStateFlagBitsNV { + VK_INDIRECT_STATE_FLAG_FRONTFACE_BIT_NV = 0x00000001, + VK_INDIRECT_STATE_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF +} VkIndirectStateFlagBitsNV; +typedef VkFlags VkIndirectStateFlagsNV; + +typedef enum VkIndirectCommandsLayoutUsageFlagBitsNV { + VK_INDIRECT_COMMANDS_LAYOUT_USAGE_EXPLICIT_PREPROCESS_BIT_NV = 0x00000001, + VK_INDIRECT_COMMANDS_LAYOUT_USAGE_INDEXED_SEQUENCES_BIT_NV = 0x00000002, + VK_INDIRECT_COMMANDS_LAYOUT_USAGE_UNORDERED_SEQUENCES_BIT_NV = 0x00000004, + VK_INDIRECT_COMMANDS_LAYOUT_USAGE_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF +} VkIndirectCommandsLayoutUsageFlagBitsNV; +typedef VkFlags VkIndirectCommandsLayoutUsageFlagsNV; +typedef struct VkPhysicalDeviceDeviceGeneratedCommandsPropertiesNV { + VkStructureType sType; + void* pNext; + uint32_t maxGraphicsShaderGroupCount; + uint32_t maxIndirectSequenceCount; + uint32_t maxIndirectCommandsTokenCount; + uint32_t maxIndirectCommandsStreamCount; + uint32_t maxIndirectCommandsTokenOffset; + uint32_t maxIndirectCommandsStreamStride; + uint32_t minSequencesCountBufferOffsetAlignment; + uint32_t minSequencesIndexBufferOffsetAlignment; + uint32_t minIndirectCommandsBufferOffsetAlignment; +} VkPhysicalDeviceDeviceGeneratedCommandsPropertiesNV; + +typedef struct VkPhysicalDeviceDeviceGeneratedCommandsFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 deviceGeneratedCommands; +} VkPhysicalDeviceDeviceGeneratedCommandsFeaturesNV; + +typedef struct VkGraphicsShaderGroupCreateInfoNV { + VkStructureType sType; + const void* pNext; + uint32_t stageCount; + const VkPipelineShaderStageCreateInfo* pStages; + const VkPipelineVertexInputStateCreateInfo* pVertexInputState; + const VkPipelineTessellationStateCreateInfo* pTessellationState; +} VkGraphicsShaderGroupCreateInfoNV; + +typedef struct VkGraphicsPipelineShaderGroupsCreateInfoNV { + VkStructureType sType; + const void* pNext; + uint32_t groupCount; + const VkGraphicsShaderGroupCreateInfoNV* pGroups; + uint32_t pipelineCount; + const VkPipeline* pPipelines; +} VkGraphicsPipelineShaderGroupsCreateInfoNV; + +typedef struct VkBindShaderGroupIndirectCommandNV { + uint32_t groupIndex; +} VkBindShaderGroupIndirectCommandNV; + +typedef struct VkBindIndexBufferIndirectCommandNV { + VkDeviceAddress bufferAddress; + uint32_t size; + VkIndexType indexType; +} VkBindIndexBufferIndirectCommandNV; + +typedef struct VkBindVertexBufferIndirectCommandNV { + VkDeviceAddress bufferAddress; + uint32_t size; + uint32_t stride; +} VkBindVertexBufferIndirectCommandNV; + +typedef struct VkSetStateFlagsIndirectCommandNV { + uint32_t data; +} VkSetStateFlagsIndirectCommandNV; + +typedef struct VkIndirectCommandsStreamNV { + VkBuffer buffer; + VkDeviceSize offset; +} VkIndirectCommandsStreamNV; + +typedef struct VkIndirectCommandsLayoutTokenNV { + VkStructureType sType; + const void* pNext; + VkIndirectCommandsTokenTypeNV tokenType; + uint32_t stream; + uint32_t offset; + uint32_t vertexBindingUnit; + VkBool32 vertexDynamicStride; + VkPipelineLayout pushconstantPipelineLayout; + VkShaderStageFlags pushconstantShaderStageFlags; + uint32_t pushconstantOffset; + uint32_t pushconstantSize; + VkIndirectStateFlagsNV indirectStateFlags; + uint32_t indexTypeCount; + const VkIndexType* pIndexTypes; + const uint32_t* pIndexTypeValues; +} VkIndirectCommandsLayoutTokenNV; + +typedef struct VkIndirectCommandsLayoutCreateInfoNV { + VkStructureType sType; + const void* pNext; + VkIndirectCommandsLayoutUsageFlagsNV flags; + VkPipelineBindPoint pipelineBindPoint; + uint32_t tokenCount; + const VkIndirectCommandsLayoutTokenNV* pTokens; + uint32_t streamCount; + const uint32_t* pStreamStrides; +} VkIndirectCommandsLayoutCreateInfoNV; + +typedef struct VkGeneratedCommandsInfoNV { + VkStructureType sType; + const void* pNext; + VkPipelineBindPoint pipelineBindPoint; + VkPipeline pipeline; + VkIndirectCommandsLayoutNV indirectCommandsLayout; + uint32_t streamCount; + const VkIndirectCommandsStreamNV* pStreams; + uint32_t sequencesCount; + VkBuffer preprocessBuffer; + VkDeviceSize preprocessOffset; + VkDeviceSize preprocessSize; + VkBuffer sequencesCountBuffer; + VkDeviceSize sequencesCountOffset; + VkBuffer sequencesIndexBuffer; + VkDeviceSize sequencesIndexOffset; +} VkGeneratedCommandsInfoNV; + +typedef struct VkGeneratedCommandsMemoryRequirementsInfoNV { + VkStructureType sType; + const void* pNext; + VkPipelineBindPoint pipelineBindPoint; + VkPipeline pipeline; + VkIndirectCommandsLayoutNV indirectCommandsLayout; + uint32_t maxSequencesCount; +} VkGeneratedCommandsMemoryRequirementsInfoNV; + +typedef void (VKAPI_PTR *PFN_vkGetGeneratedCommandsMemoryRequirementsNV)(VkDevice device, const VkGeneratedCommandsMemoryRequirementsInfoNV* pInfo, VkMemoryRequirements2* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkCmdPreprocessGeneratedCommandsNV)(VkCommandBuffer commandBuffer, const VkGeneratedCommandsInfoNV* pGeneratedCommandsInfo); +typedef void (VKAPI_PTR *PFN_vkCmdExecuteGeneratedCommandsNV)(VkCommandBuffer commandBuffer, VkBool32 isPreprocessed, const VkGeneratedCommandsInfoNV* pGeneratedCommandsInfo); +typedef void (VKAPI_PTR *PFN_vkCmdBindPipelineShaderGroupNV)(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline, uint32_t groupIndex); +typedef VkResult (VKAPI_PTR *PFN_vkCreateIndirectCommandsLayoutNV)(VkDevice device, const VkIndirectCommandsLayoutCreateInfoNV* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkIndirectCommandsLayoutNV* pIndirectCommandsLayout); +typedef void (VKAPI_PTR *PFN_vkDestroyIndirectCommandsLayoutNV)(VkDevice device, VkIndirectCommandsLayoutNV indirectCommandsLayout, const VkAllocationCallbacks* pAllocator); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkGetGeneratedCommandsMemoryRequirementsNV( + VkDevice device, + const VkGeneratedCommandsMemoryRequirementsInfoNV* pInfo, + VkMemoryRequirements2* pMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkCmdPreprocessGeneratedCommandsNV( + VkCommandBuffer commandBuffer, + const VkGeneratedCommandsInfoNV* pGeneratedCommandsInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdExecuteGeneratedCommandsNV( + VkCommandBuffer commandBuffer, + VkBool32 isPreprocessed, + const VkGeneratedCommandsInfoNV* pGeneratedCommandsInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdBindPipelineShaderGroupNV( + VkCommandBuffer commandBuffer, + VkPipelineBindPoint pipelineBindPoint, + VkPipeline pipeline, + uint32_t groupIndex); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateIndirectCommandsLayoutNV( + VkDevice device, + const VkIndirectCommandsLayoutCreateInfoNV* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkIndirectCommandsLayoutNV* pIndirectCommandsLayout); + +VKAPI_ATTR void VKAPI_CALL vkDestroyIndirectCommandsLayoutNV( + VkDevice device, + VkIndirectCommandsLayoutNV indirectCommandsLayout, + const VkAllocationCallbacks* pAllocator); +#endif + + +// VK_NV_inherited_viewport_scissor is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_inherited_viewport_scissor 1 +#define VK_NV_INHERITED_VIEWPORT_SCISSOR_SPEC_VERSION 1 +#define VK_NV_INHERITED_VIEWPORT_SCISSOR_EXTENSION_NAME "VK_NV_inherited_viewport_scissor" +typedef struct VkPhysicalDeviceInheritedViewportScissorFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 inheritedViewportScissor2D; +} VkPhysicalDeviceInheritedViewportScissorFeaturesNV; + +typedef struct VkCommandBufferInheritanceViewportScissorInfoNV { + VkStructureType sType; + const void* pNext; + VkBool32 viewportScissor2D; + uint32_t viewportDepthCount; + const VkViewport* pViewportDepths; +} VkCommandBufferInheritanceViewportScissorInfoNV; + + + +// VK_EXT_texel_buffer_alignment is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_texel_buffer_alignment 1 +#define VK_EXT_TEXEL_BUFFER_ALIGNMENT_SPEC_VERSION 1 +#define VK_EXT_TEXEL_BUFFER_ALIGNMENT_EXTENSION_NAME "VK_EXT_texel_buffer_alignment" +typedef struct VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 texelBufferAlignment; +} VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT; + +typedef VkPhysicalDeviceTexelBufferAlignmentProperties VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT; + + + +// VK_QCOM_render_pass_transform is a preprocessor guard. Do not pass it to API calls. +#define VK_QCOM_render_pass_transform 1 +#define VK_QCOM_RENDER_PASS_TRANSFORM_SPEC_VERSION 4 +#define VK_QCOM_RENDER_PASS_TRANSFORM_EXTENSION_NAME "VK_QCOM_render_pass_transform" +typedef struct VkRenderPassTransformBeginInfoQCOM { + VkStructureType sType; + void* pNext; + VkSurfaceTransformFlagBitsKHR transform; +} VkRenderPassTransformBeginInfoQCOM; + +typedef struct VkCommandBufferInheritanceRenderPassTransformInfoQCOM { + VkStructureType sType; + void* pNext; + VkSurfaceTransformFlagBitsKHR transform; + VkRect2D renderArea; +} VkCommandBufferInheritanceRenderPassTransformInfoQCOM; + + + +// VK_EXT_depth_bias_control is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_depth_bias_control 1 +#define VK_EXT_DEPTH_BIAS_CONTROL_SPEC_VERSION 1 +#define VK_EXT_DEPTH_BIAS_CONTROL_EXTENSION_NAME "VK_EXT_depth_bias_control" + +typedef enum VkDepthBiasRepresentationEXT { + VK_DEPTH_BIAS_REPRESENTATION_LEAST_REPRESENTABLE_VALUE_FORMAT_EXT = 0, + VK_DEPTH_BIAS_REPRESENTATION_LEAST_REPRESENTABLE_VALUE_FORCE_UNORM_EXT = 1, + VK_DEPTH_BIAS_REPRESENTATION_FLOAT_EXT = 2, + VK_DEPTH_BIAS_REPRESENTATION_MAX_ENUM_EXT = 0x7FFFFFFF +} VkDepthBiasRepresentationEXT; +typedef struct VkPhysicalDeviceDepthBiasControlFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 depthBiasControl; + VkBool32 leastRepresentableValueForceUnormRepresentation; + VkBool32 floatRepresentation; + VkBool32 depthBiasExact; +} VkPhysicalDeviceDepthBiasControlFeaturesEXT; + +typedef struct VkDepthBiasInfoEXT { + VkStructureType sType; + const void* pNext; + float depthBiasConstantFactor; + float depthBiasClamp; + float depthBiasSlopeFactor; +} VkDepthBiasInfoEXT; + +typedef struct VkDepthBiasRepresentationInfoEXT { + VkStructureType sType; + const void* pNext; + VkDepthBiasRepresentationEXT depthBiasRepresentation; + VkBool32 depthBiasExact; +} VkDepthBiasRepresentationInfoEXT; + +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthBias2EXT)(VkCommandBuffer commandBuffer, const VkDepthBiasInfoEXT* pDepthBiasInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBias2EXT( + VkCommandBuffer commandBuffer, + const VkDepthBiasInfoEXT* pDepthBiasInfo); +#endif + + +// VK_EXT_device_memory_report is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_device_memory_report 1 +#define VK_EXT_DEVICE_MEMORY_REPORT_SPEC_VERSION 2 +#define VK_EXT_DEVICE_MEMORY_REPORT_EXTENSION_NAME "VK_EXT_device_memory_report" + +typedef enum VkDeviceMemoryReportEventTypeEXT { + VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_ALLOCATE_EXT = 0, + VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_FREE_EXT = 1, + VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_IMPORT_EXT = 2, + VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_UNIMPORT_EXT = 3, + VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_ALLOCATION_FAILED_EXT = 4, + VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF +} VkDeviceMemoryReportEventTypeEXT; +typedef VkFlags VkDeviceMemoryReportFlagsEXT; +typedef struct VkPhysicalDeviceDeviceMemoryReportFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 deviceMemoryReport; +} VkPhysicalDeviceDeviceMemoryReportFeaturesEXT; + +typedef struct VkDeviceMemoryReportCallbackDataEXT { + VkStructureType sType; + void* pNext; + VkDeviceMemoryReportFlagsEXT flags; + VkDeviceMemoryReportEventTypeEXT type; + uint64_t memoryObjectId; + VkDeviceSize size; + VkObjectType objectType; + uint64_t objectHandle; + uint32_t heapIndex; +} VkDeviceMemoryReportCallbackDataEXT; + +typedef void (VKAPI_PTR *PFN_vkDeviceMemoryReportCallbackEXT)( + const VkDeviceMemoryReportCallbackDataEXT* pCallbackData, + void* pUserData); + +typedef struct VkDeviceDeviceMemoryReportCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkDeviceMemoryReportFlagsEXT flags; + PFN_vkDeviceMemoryReportCallbackEXT pfnUserCallback; + void* pUserData; +} VkDeviceDeviceMemoryReportCreateInfoEXT; + + + +// VK_EXT_acquire_drm_display is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_acquire_drm_display 1 +#define VK_EXT_ACQUIRE_DRM_DISPLAY_SPEC_VERSION 1 +#define VK_EXT_ACQUIRE_DRM_DISPLAY_EXTENSION_NAME "VK_EXT_acquire_drm_display" +typedef VkResult (VKAPI_PTR *PFN_vkAcquireDrmDisplayEXT)(VkPhysicalDevice physicalDevice, int32_t drmFd, VkDisplayKHR display); +typedef VkResult (VKAPI_PTR *PFN_vkGetDrmDisplayEXT)(VkPhysicalDevice physicalDevice, int32_t drmFd, uint32_t connectorId, VkDisplayKHR* display); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkAcquireDrmDisplayEXT( + VkPhysicalDevice physicalDevice, + int32_t drmFd, + VkDisplayKHR display); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetDrmDisplayEXT( + VkPhysicalDevice physicalDevice, + int32_t drmFd, + uint32_t connectorId, + VkDisplayKHR* display); +#endif + + +// VK_EXT_robustness2 is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_robustness2 1 +#define VK_EXT_ROBUSTNESS_2_SPEC_VERSION 1 +#define VK_EXT_ROBUSTNESS_2_EXTENSION_NAME "VK_EXT_robustness2" +typedef struct VkPhysicalDeviceRobustness2FeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 robustBufferAccess2; + VkBool32 robustImageAccess2; + VkBool32 nullDescriptor; +} VkPhysicalDeviceRobustness2FeaturesEXT; + +typedef struct VkPhysicalDeviceRobustness2PropertiesEXT { + VkStructureType sType; + void* pNext; + VkDeviceSize robustStorageBufferAccessSizeAlignment; + VkDeviceSize robustUniformBufferAccessSizeAlignment; +} VkPhysicalDeviceRobustness2PropertiesEXT; + + + +// VK_EXT_custom_border_color is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_custom_border_color 1 +#define VK_EXT_CUSTOM_BORDER_COLOR_SPEC_VERSION 12 +#define VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME "VK_EXT_custom_border_color" +typedef struct VkSamplerCustomBorderColorCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkClearColorValue customBorderColor; + VkFormat format; +} VkSamplerCustomBorderColorCreateInfoEXT; + +typedef struct VkPhysicalDeviceCustomBorderColorPropertiesEXT { + VkStructureType sType; + void* pNext; + uint32_t maxCustomBorderColorSamplers; +} VkPhysicalDeviceCustomBorderColorPropertiesEXT; + +typedef struct VkPhysicalDeviceCustomBorderColorFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 customBorderColors; + VkBool32 customBorderColorWithoutFormat; +} VkPhysicalDeviceCustomBorderColorFeaturesEXT; + + + +// VK_GOOGLE_user_type is a preprocessor guard. Do not pass it to API calls. +#define VK_GOOGLE_user_type 1 +#define VK_GOOGLE_USER_TYPE_SPEC_VERSION 1 +#define VK_GOOGLE_USER_TYPE_EXTENSION_NAME "VK_GOOGLE_user_type" + + +// VK_NV_present_barrier is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_present_barrier 1 +#define VK_NV_PRESENT_BARRIER_SPEC_VERSION 1 +#define VK_NV_PRESENT_BARRIER_EXTENSION_NAME "VK_NV_present_barrier" +typedef struct VkPhysicalDevicePresentBarrierFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 presentBarrier; +} VkPhysicalDevicePresentBarrierFeaturesNV; + +typedef struct VkSurfaceCapabilitiesPresentBarrierNV { + VkStructureType sType; + void* pNext; + VkBool32 presentBarrierSupported; +} VkSurfaceCapabilitiesPresentBarrierNV; + +typedef struct VkSwapchainPresentBarrierCreateInfoNV { + VkStructureType sType; + void* pNext; + VkBool32 presentBarrierEnable; +} VkSwapchainPresentBarrierCreateInfoNV; + + + +// VK_EXT_private_data is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_private_data 1 +typedef VkPrivateDataSlot VkPrivateDataSlotEXT; + +#define VK_EXT_PRIVATE_DATA_SPEC_VERSION 1 +#define VK_EXT_PRIVATE_DATA_EXTENSION_NAME "VK_EXT_private_data" +typedef VkPrivateDataSlotCreateFlags VkPrivateDataSlotCreateFlagsEXT; + +typedef VkPhysicalDevicePrivateDataFeatures VkPhysicalDevicePrivateDataFeaturesEXT; + +typedef VkDevicePrivateDataCreateInfo VkDevicePrivateDataCreateInfoEXT; + +typedef VkPrivateDataSlotCreateInfo VkPrivateDataSlotCreateInfoEXT; + +typedef VkResult (VKAPI_PTR *PFN_vkCreatePrivateDataSlotEXT)(VkDevice device, const VkPrivateDataSlotCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPrivateDataSlot* pPrivateDataSlot); +typedef void (VKAPI_PTR *PFN_vkDestroyPrivateDataSlotEXT)(VkDevice device, VkPrivateDataSlot privateDataSlot, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkSetPrivateDataEXT)(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlot privateDataSlot, uint64_t data); +typedef void (VKAPI_PTR *PFN_vkGetPrivateDataEXT)(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlot privateDataSlot, uint64_t* pData); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreatePrivateDataSlotEXT( + VkDevice device, + const VkPrivateDataSlotCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkPrivateDataSlot* pPrivateDataSlot); + +VKAPI_ATTR void VKAPI_CALL vkDestroyPrivateDataSlotEXT( + VkDevice device, + VkPrivateDataSlot privateDataSlot, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkSetPrivateDataEXT( + VkDevice device, + VkObjectType objectType, + uint64_t objectHandle, + VkPrivateDataSlot privateDataSlot, + uint64_t data); + +VKAPI_ATTR void VKAPI_CALL vkGetPrivateDataEXT( + VkDevice device, + VkObjectType objectType, + uint64_t objectHandle, + VkPrivateDataSlot privateDataSlot, + uint64_t* pData); +#endif + + +// VK_EXT_pipeline_creation_cache_control is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_pipeline_creation_cache_control 1 +#define VK_EXT_PIPELINE_CREATION_CACHE_CONTROL_SPEC_VERSION 3 +#define VK_EXT_PIPELINE_CREATION_CACHE_CONTROL_EXTENSION_NAME "VK_EXT_pipeline_creation_cache_control" +typedef VkPhysicalDevicePipelineCreationCacheControlFeatures VkPhysicalDevicePipelineCreationCacheControlFeaturesEXT; + + + +// VK_NV_device_diagnostics_config is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_device_diagnostics_config 1 +#define VK_NV_DEVICE_DIAGNOSTICS_CONFIG_SPEC_VERSION 2 +#define VK_NV_DEVICE_DIAGNOSTICS_CONFIG_EXTENSION_NAME "VK_NV_device_diagnostics_config" + +typedef enum VkDeviceDiagnosticsConfigFlagBitsNV { + VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_SHADER_DEBUG_INFO_BIT_NV = 0x00000001, + VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_RESOURCE_TRACKING_BIT_NV = 0x00000002, + VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_AUTOMATIC_CHECKPOINTS_BIT_NV = 0x00000004, + VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_SHADER_ERROR_REPORTING_BIT_NV = 0x00000008, + VK_DEVICE_DIAGNOSTICS_CONFIG_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF +} VkDeviceDiagnosticsConfigFlagBitsNV; +typedef VkFlags VkDeviceDiagnosticsConfigFlagsNV; +typedef struct VkPhysicalDeviceDiagnosticsConfigFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 diagnosticsConfig; +} VkPhysicalDeviceDiagnosticsConfigFeaturesNV; + +typedef struct VkDeviceDiagnosticsConfigCreateInfoNV { + VkStructureType sType; + const void* pNext; + VkDeviceDiagnosticsConfigFlagsNV flags; +} VkDeviceDiagnosticsConfigCreateInfoNV; + + + +// VK_QCOM_render_pass_store_ops is a preprocessor guard. Do not pass it to API calls. +#define VK_QCOM_render_pass_store_ops 1 +#define VK_QCOM_RENDER_PASS_STORE_OPS_SPEC_VERSION 2 +#define VK_QCOM_RENDER_PASS_STORE_OPS_EXTENSION_NAME "VK_QCOM_render_pass_store_ops" + + +// VK_NV_cuda_kernel_launch is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_cuda_kernel_launch 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCudaModuleNV) +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkCudaFunctionNV) +#define VK_NV_CUDA_KERNEL_LAUNCH_SPEC_VERSION 2 +#define VK_NV_CUDA_KERNEL_LAUNCH_EXTENSION_NAME "VK_NV_cuda_kernel_launch" +typedef struct VkCudaModuleCreateInfoNV { + VkStructureType sType; + const void* pNext; + size_t dataSize; + const void* pData; +} VkCudaModuleCreateInfoNV; + +typedef struct VkCudaFunctionCreateInfoNV { + VkStructureType sType; + const void* pNext; + VkCudaModuleNV module; + const char* pName; +} VkCudaFunctionCreateInfoNV; + +typedef struct VkCudaLaunchInfoNV { + VkStructureType sType; + const void* pNext; + VkCudaFunctionNV function; + uint32_t gridDimX; + uint32_t gridDimY; + uint32_t gridDimZ; + uint32_t blockDimX; + uint32_t blockDimY; + uint32_t blockDimZ; + uint32_t sharedMemBytes; + size_t paramCount; + const void* const * pParams; + size_t extraCount; + const void* const * pExtras; +} VkCudaLaunchInfoNV; + +typedef struct VkPhysicalDeviceCudaKernelLaunchFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 cudaKernelLaunchFeatures; +} VkPhysicalDeviceCudaKernelLaunchFeaturesNV; + +typedef struct VkPhysicalDeviceCudaKernelLaunchPropertiesNV { + VkStructureType sType; + void* pNext; + uint32_t computeCapabilityMinor; + uint32_t computeCapabilityMajor; +} VkPhysicalDeviceCudaKernelLaunchPropertiesNV; + +typedef VkResult (VKAPI_PTR *PFN_vkCreateCudaModuleNV)(VkDevice device, const VkCudaModuleCreateInfoNV* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkCudaModuleNV* pModule); +typedef VkResult (VKAPI_PTR *PFN_vkGetCudaModuleCacheNV)(VkDevice device, VkCudaModuleNV module, size_t* pCacheSize, void* pCacheData); +typedef VkResult (VKAPI_PTR *PFN_vkCreateCudaFunctionNV)(VkDevice device, const VkCudaFunctionCreateInfoNV* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkCudaFunctionNV* pFunction); +typedef void (VKAPI_PTR *PFN_vkDestroyCudaModuleNV)(VkDevice device, VkCudaModuleNV module, const VkAllocationCallbacks* pAllocator); +typedef void (VKAPI_PTR *PFN_vkDestroyCudaFunctionNV)(VkDevice device, VkCudaFunctionNV function, const VkAllocationCallbacks* pAllocator); +typedef void (VKAPI_PTR *PFN_vkCmdCudaLaunchKernelNV)(VkCommandBuffer commandBuffer, const VkCudaLaunchInfoNV* pLaunchInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateCudaModuleNV( + VkDevice device, + const VkCudaModuleCreateInfoNV* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkCudaModuleNV* pModule); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetCudaModuleCacheNV( + VkDevice device, + VkCudaModuleNV module, + size_t* pCacheSize, + void* pCacheData); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateCudaFunctionNV( + VkDevice device, + const VkCudaFunctionCreateInfoNV* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkCudaFunctionNV* pFunction); + +VKAPI_ATTR void VKAPI_CALL vkDestroyCudaModuleNV( + VkDevice device, + VkCudaModuleNV module, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR void VKAPI_CALL vkDestroyCudaFunctionNV( + VkDevice device, + VkCudaFunctionNV function, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR void VKAPI_CALL vkCmdCudaLaunchKernelNV( + VkCommandBuffer commandBuffer, + const VkCudaLaunchInfoNV* pLaunchInfo); +#endif + + +// VK_NV_low_latency is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_low_latency 1 +#define VK_NV_LOW_LATENCY_SPEC_VERSION 1 +#define VK_NV_LOW_LATENCY_EXTENSION_NAME "VK_NV_low_latency" +typedef struct VkQueryLowLatencySupportNV { + VkStructureType sType; + const void* pNext; + void* pQueriedLowLatencyData; +} VkQueryLowLatencySupportNV; + + + +// VK_EXT_descriptor_buffer is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_descriptor_buffer 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkAccelerationStructureKHR) +#define VK_EXT_DESCRIPTOR_BUFFER_SPEC_VERSION 1 +#define VK_EXT_DESCRIPTOR_BUFFER_EXTENSION_NAME "VK_EXT_descriptor_buffer" +typedef struct VkPhysicalDeviceDescriptorBufferPropertiesEXT { + VkStructureType sType; + void* pNext; + VkBool32 combinedImageSamplerDescriptorSingleArray; + VkBool32 bufferlessPushDescriptors; + VkBool32 allowSamplerImageViewPostSubmitCreation; + VkDeviceSize descriptorBufferOffsetAlignment; + uint32_t maxDescriptorBufferBindings; + uint32_t maxResourceDescriptorBufferBindings; + uint32_t maxSamplerDescriptorBufferBindings; + uint32_t maxEmbeddedImmutableSamplerBindings; + uint32_t maxEmbeddedImmutableSamplers; + size_t bufferCaptureReplayDescriptorDataSize; + size_t imageCaptureReplayDescriptorDataSize; + size_t imageViewCaptureReplayDescriptorDataSize; + size_t samplerCaptureReplayDescriptorDataSize; + size_t accelerationStructureCaptureReplayDescriptorDataSize; + size_t samplerDescriptorSize; + size_t combinedImageSamplerDescriptorSize; + size_t sampledImageDescriptorSize; + size_t storageImageDescriptorSize; + size_t uniformTexelBufferDescriptorSize; + size_t robustUniformTexelBufferDescriptorSize; + size_t storageTexelBufferDescriptorSize; + size_t robustStorageTexelBufferDescriptorSize; + size_t uniformBufferDescriptorSize; + size_t robustUniformBufferDescriptorSize; + size_t storageBufferDescriptorSize; + size_t robustStorageBufferDescriptorSize; + size_t inputAttachmentDescriptorSize; + size_t accelerationStructureDescriptorSize; + VkDeviceSize maxSamplerDescriptorBufferRange; + VkDeviceSize maxResourceDescriptorBufferRange; + VkDeviceSize samplerDescriptorBufferAddressSpaceSize; + VkDeviceSize resourceDescriptorBufferAddressSpaceSize; + VkDeviceSize descriptorBufferAddressSpaceSize; +} VkPhysicalDeviceDescriptorBufferPropertiesEXT; + +typedef struct VkPhysicalDeviceDescriptorBufferDensityMapPropertiesEXT { + VkStructureType sType; + void* pNext; + size_t combinedImageSamplerDensityMapDescriptorSize; +} VkPhysicalDeviceDescriptorBufferDensityMapPropertiesEXT; + +typedef struct VkPhysicalDeviceDescriptorBufferFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 descriptorBuffer; + VkBool32 descriptorBufferCaptureReplay; + VkBool32 descriptorBufferImageLayoutIgnored; + VkBool32 descriptorBufferPushDescriptors; +} VkPhysicalDeviceDescriptorBufferFeaturesEXT; + +typedef struct VkDescriptorAddressInfoEXT { + VkStructureType sType; + void* pNext; + VkDeviceAddress address; + VkDeviceSize range; + VkFormat format; +} VkDescriptorAddressInfoEXT; + +typedef struct VkDescriptorBufferBindingInfoEXT { + VkStructureType sType; + void* pNext; + VkDeviceAddress address; + VkBufferUsageFlags usage; +} VkDescriptorBufferBindingInfoEXT; + +typedef struct VkDescriptorBufferBindingPushDescriptorBufferHandleEXT { + VkStructureType sType; + void* pNext; + VkBuffer buffer; +} VkDescriptorBufferBindingPushDescriptorBufferHandleEXT; + +typedef union VkDescriptorDataEXT { + const VkSampler* pSampler; + const VkDescriptorImageInfo* pCombinedImageSampler; + const VkDescriptorImageInfo* pInputAttachmentImage; + const VkDescriptorImageInfo* pSampledImage; + const VkDescriptorImageInfo* pStorageImage; + const VkDescriptorAddressInfoEXT* pUniformTexelBuffer; + const VkDescriptorAddressInfoEXT* pStorageTexelBuffer; + const VkDescriptorAddressInfoEXT* pUniformBuffer; + const VkDescriptorAddressInfoEXT* pStorageBuffer; + VkDeviceAddress accelerationStructure; +} VkDescriptorDataEXT; + +typedef struct VkDescriptorGetInfoEXT { + VkStructureType sType; + const void* pNext; + VkDescriptorType type; + VkDescriptorDataEXT data; +} VkDescriptorGetInfoEXT; + +typedef struct VkBufferCaptureDescriptorDataInfoEXT { + VkStructureType sType; + const void* pNext; + VkBuffer buffer; +} VkBufferCaptureDescriptorDataInfoEXT; + +typedef struct VkImageCaptureDescriptorDataInfoEXT { + VkStructureType sType; + const void* pNext; + VkImage image; +} VkImageCaptureDescriptorDataInfoEXT; + +typedef struct VkImageViewCaptureDescriptorDataInfoEXT { + VkStructureType sType; + const void* pNext; + VkImageView imageView; +} VkImageViewCaptureDescriptorDataInfoEXT; + +typedef struct VkSamplerCaptureDescriptorDataInfoEXT { + VkStructureType sType; + const void* pNext; + VkSampler sampler; +} VkSamplerCaptureDescriptorDataInfoEXT; + +typedef struct VkOpaqueCaptureDescriptorDataCreateInfoEXT { + VkStructureType sType; + const void* pNext; + const void* opaqueCaptureDescriptorData; +} VkOpaqueCaptureDescriptorDataCreateInfoEXT; + +typedef struct VkAccelerationStructureCaptureDescriptorDataInfoEXT { + VkStructureType sType; + const void* pNext; + VkAccelerationStructureKHR accelerationStructure; + VkAccelerationStructureNV accelerationStructureNV; +} VkAccelerationStructureCaptureDescriptorDataInfoEXT; + +typedef void (VKAPI_PTR *PFN_vkGetDescriptorSetLayoutSizeEXT)(VkDevice device, VkDescriptorSetLayout layout, VkDeviceSize* pLayoutSizeInBytes); +typedef void (VKAPI_PTR *PFN_vkGetDescriptorSetLayoutBindingOffsetEXT)(VkDevice device, VkDescriptorSetLayout layout, uint32_t binding, VkDeviceSize* pOffset); +typedef void (VKAPI_PTR *PFN_vkGetDescriptorEXT)(VkDevice device, const VkDescriptorGetInfoEXT* pDescriptorInfo, size_t dataSize, void* pDescriptor); +typedef void (VKAPI_PTR *PFN_vkCmdBindDescriptorBuffersEXT)(VkCommandBuffer commandBuffer, uint32_t bufferCount, const VkDescriptorBufferBindingInfoEXT* pBindingInfos); +typedef void (VKAPI_PTR *PFN_vkCmdSetDescriptorBufferOffsetsEXT)(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t firstSet, uint32_t setCount, const uint32_t* pBufferIndices, const VkDeviceSize* pOffsets); +typedef void (VKAPI_PTR *PFN_vkCmdBindDescriptorBufferEmbeddedSamplersEXT)(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t set); +typedef VkResult (VKAPI_PTR *PFN_vkGetBufferOpaqueCaptureDescriptorDataEXT)(VkDevice device, const VkBufferCaptureDescriptorDataInfoEXT* pInfo, void* pData); +typedef VkResult (VKAPI_PTR *PFN_vkGetImageOpaqueCaptureDescriptorDataEXT)(VkDevice device, const VkImageCaptureDescriptorDataInfoEXT* pInfo, void* pData); +typedef VkResult (VKAPI_PTR *PFN_vkGetImageViewOpaqueCaptureDescriptorDataEXT)(VkDevice device, const VkImageViewCaptureDescriptorDataInfoEXT* pInfo, void* pData); +typedef VkResult (VKAPI_PTR *PFN_vkGetSamplerOpaqueCaptureDescriptorDataEXT)(VkDevice device, const VkSamplerCaptureDescriptorDataInfoEXT* pInfo, void* pData); +typedef VkResult (VKAPI_PTR *PFN_vkGetAccelerationStructureOpaqueCaptureDescriptorDataEXT)(VkDevice device, const VkAccelerationStructureCaptureDescriptorDataInfoEXT* pInfo, void* pData); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkGetDescriptorSetLayoutSizeEXT( + VkDevice device, + VkDescriptorSetLayout layout, + VkDeviceSize* pLayoutSizeInBytes); + +VKAPI_ATTR void VKAPI_CALL vkGetDescriptorSetLayoutBindingOffsetEXT( + VkDevice device, + VkDescriptorSetLayout layout, + uint32_t binding, + VkDeviceSize* pOffset); + +VKAPI_ATTR void VKAPI_CALL vkGetDescriptorEXT( + VkDevice device, + const VkDescriptorGetInfoEXT* pDescriptorInfo, + size_t dataSize, + void* pDescriptor); + +VKAPI_ATTR void VKAPI_CALL vkCmdBindDescriptorBuffersEXT( + VkCommandBuffer commandBuffer, + uint32_t bufferCount, + const VkDescriptorBufferBindingInfoEXT* pBindingInfos); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDescriptorBufferOffsetsEXT( + VkCommandBuffer commandBuffer, + VkPipelineBindPoint pipelineBindPoint, + VkPipelineLayout layout, + uint32_t firstSet, + uint32_t setCount, + const uint32_t* pBufferIndices, + const VkDeviceSize* pOffsets); + +VKAPI_ATTR void VKAPI_CALL vkCmdBindDescriptorBufferEmbeddedSamplersEXT( + VkCommandBuffer commandBuffer, + VkPipelineBindPoint pipelineBindPoint, + VkPipelineLayout layout, + uint32_t set); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetBufferOpaqueCaptureDescriptorDataEXT( + VkDevice device, + const VkBufferCaptureDescriptorDataInfoEXT* pInfo, + void* pData); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetImageOpaqueCaptureDescriptorDataEXT( + VkDevice device, + const VkImageCaptureDescriptorDataInfoEXT* pInfo, + void* pData); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetImageViewOpaqueCaptureDescriptorDataEXT( + VkDevice device, + const VkImageViewCaptureDescriptorDataInfoEXT* pInfo, + void* pData); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetSamplerOpaqueCaptureDescriptorDataEXT( + VkDevice device, + const VkSamplerCaptureDescriptorDataInfoEXT* pInfo, + void* pData); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetAccelerationStructureOpaqueCaptureDescriptorDataEXT( + VkDevice device, + const VkAccelerationStructureCaptureDescriptorDataInfoEXT* pInfo, + void* pData); +#endif + + +// VK_EXT_graphics_pipeline_library is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_graphics_pipeline_library 1 +#define VK_EXT_GRAPHICS_PIPELINE_LIBRARY_SPEC_VERSION 1 +#define VK_EXT_GRAPHICS_PIPELINE_LIBRARY_EXTENSION_NAME "VK_EXT_graphics_pipeline_library" + +typedef enum VkGraphicsPipelineLibraryFlagBitsEXT { + VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT = 0x00000001, + VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT = 0x00000002, + VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT = 0x00000004, + VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT = 0x00000008, + VK_GRAPHICS_PIPELINE_LIBRARY_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkGraphicsPipelineLibraryFlagBitsEXT; +typedef VkFlags VkGraphicsPipelineLibraryFlagsEXT; +typedef struct VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 graphicsPipelineLibrary; +} VkPhysicalDeviceGraphicsPipelineLibraryFeaturesEXT; + +typedef struct VkPhysicalDeviceGraphicsPipelineLibraryPropertiesEXT { + VkStructureType sType; + void* pNext; + VkBool32 graphicsPipelineLibraryFastLinking; + VkBool32 graphicsPipelineLibraryIndependentInterpolationDecoration; +} VkPhysicalDeviceGraphicsPipelineLibraryPropertiesEXT; + +typedef struct VkGraphicsPipelineLibraryCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkGraphicsPipelineLibraryFlagsEXT flags; +} VkGraphicsPipelineLibraryCreateInfoEXT; + + + +// VK_AMD_shader_early_and_late_fragment_tests is a preprocessor guard. Do not pass it to API calls. +#define VK_AMD_shader_early_and_late_fragment_tests 1 +#define VK_AMD_SHADER_EARLY_AND_LATE_FRAGMENT_TESTS_SPEC_VERSION 1 +#define VK_AMD_SHADER_EARLY_AND_LATE_FRAGMENT_TESTS_EXTENSION_NAME "VK_AMD_shader_early_and_late_fragment_tests" +typedef struct VkPhysicalDeviceShaderEarlyAndLateFragmentTestsFeaturesAMD { + VkStructureType sType; + void* pNext; + VkBool32 shaderEarlyAndLateFragmentTests; +} VkPhysicalDeviceShaderEarlyAndLateFragmentTestsFeaturesAMD; + + + +// VK_NV_fragment_shading_rate_enums is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_fragment_shading_rate_enums 1 +#define VK_NV_FRAGMENT_SHADING_RATE_ENUMS_SPEC_VERSION 1 +#define VK_NV_FRAGMENT_SHADING_RATE_ENUMS_EXTENSION_NAME "VK_NV_fragment_shading_rate_enums" + +typedef enum VkFragmentShadingRateTypeNV { + VK_FRAGMENT_SHADING_RATE_TYPE_FRAGMENT_SIZE_NV = 0, + VK_FRAGMENT_SHADING_RATE_TYPE_ENUMS_NV = 1, + VK_FRAGMENT_SHADING_RATE_TYPE_MAX_ENUM_NV = 0x7FFFFFFF +} VkFragmentShadingRateTypeNV; + +typedef enum VkFragmentShadingRateNV { + VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_PIXEL_NV = 0, + VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_1X2_PIXELS_NV = 1, + VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_2X1_PIXELS_NV = 4, + VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_2X2_PIXELS_NV = 5, + VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_2X4_PIXELS_NV = 6, + VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_4X2_PIXELS_NV = 9, + VK_FRAGMENT_SHADING_RATE_1_INVOCATION_PER_4X4_PIXELS_NV = 10, + VK_FRAGMENT_SHADING_RATE_2_INVOCATIONS_PER_PIXEL_NV = 11, + VK_FRAGMENT_SHADING_RATE_4_INVOCATIONS_PER_PIXEL_NV = 12, + VK_FRAGMENT_SHADING_RATE_8_INVOCATIONS_PER_PIXEL_NV = 13, + VK_FRAGMENT_SHADING_RATE_16_INVOCATIONS_PER_PIXEL_NV = 14, + VK_FRAGMENT_SHADING_RATE_NO_INVOCATIONS_NV = 15, + VK_FRAGMENT_SHADING_RATE_MAX_ENUM_NV = 0x7FFFFFFF +} VkFragmentShadingRateNV; +typedef struct VkPhysicalDeviceFragmentShadingRateEnumsFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 fragmentShadingRateEnums; + VkBool32 supersampleFragmentShadingRates; + VkBool32 noInvocationFragmentShadingRates; +} VkPhysicalDeviceFragmentShadingRateEnumsFeaturesNV; + +typedef struct VkPhysicalDeviceFragmentShadingRateEnumsPropertiesNV { + VkStructureType sType; + void* pNext; + VkSampleCountFlagBits maxFragmentShadingRateInvocationCount; +} VkPhysicalDeviceFragmentShadingRateEnumsPropertiesNV; + +typedef struct VkPipelineFragmentShadingRateEnumStateCreateInfoNV { + VkStructureType sType; + const void* pNext; + VkFragmentShadingRateTypeNV shadingRateType; + VkFragmentShadingRateNV shadingRate; + VkFragmentShadingRateCombinerOpKHR combinerOps[2]; +} VkPipelineFragmentShadingRateEnumStateCreateInfoNV; + +typedef void (VKAPI_PTR *PFN_vkCmdSetFragmentShadingRateEnumNV)(VkCommandBuffer commandBuffer, VkFragmentShadingRateNV shadingRate, const VkFragmentShadingRateCombinerOpKHR combinerOps[2]); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdSetFragmentShadingRateEnumNV( + VkCommandBuffer commandBuffer, + VkFragmentShadingRateNV shadingRate, + const VkFragmentShadingRateCombinerOpKHR combinerOps[2]); +#endif + + +// VK_NV_ray_tracing_motion_blur is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_ray_tracing_motion_blur 1 +#define VK_NV_RAY_TRACING_MOTION_BLUR_SPEC_VERSION 1 +#define VK_NV_RAY_TRACING_MOTION_BLUR_EXTENSION_NAME "VK_NV_ray_tracing_motion_blur" + +typedef enum VkAccelerationStructureMotionInstanceTypeNV { + VK_ACCELERATION_STRUCTURE_MOTION_INSTANCE_TYPE_STATIC_NV = 0, + VK_ACCELERATION_STRUCTURE_MOTION_INSTANCE_TYPE_MATRIX_MOTION_NV = 1, + VK_ACCELERATION_STRUCTURE_MOTION_INSTANCE_TYPE_SRT_MOTION_NV = 2, + VK_ACCELERATION_STRUCTURE_MOTION_INSTANCE_TYPE_MAX_ENUM_NV = 0x7FFFFFFF +} VkAccelerationStructureMotionInstanceTypeNV; +typedef VkFlags VkAccelerationStructureMotionInfoFlagsNV; +typedef VkFlags VkAccelerationStructureMotionInstanceFlagsNV; +typedef union VkDeviceOrHostAddressConstKHR { + VkDeviceAddress deviceAddress; + const void* hostAddress; +} VkDeviceOrHostAddressConstKHR; + +typedef struct VkAccelerationStructureGeometryMotionTrianglesDataNV { + VkStructureType sType; + const void* pNext; + VkDeviceOrHostAddressConstKHR vertexData; +} VkAccelerationStructureGeometryMotionTrianglesDataNV; + +typedef struct VkAccelerationStructureMotionInfoNV { + VkStructureType sType; + const void* pNext; + uint32_t maxInstances; + VkAccelerationStructureMotionInfoFlagsNV flags; +} VkAccelerationStructureMotionInfoNV; + +typedef struct VkAccelerationStructureMatrixMotionInstanceNV { + VkTransformMatrixKHR transformT0; + VkTransformMatrixKHR transformT1; + uint32_t instanceCustomIndex:24; + uint32_t mask:8; + uint32_t instanceShaderBindingTableRecordOffset:24; + VkGeometryInstanceFlagsKHR flags:8; + uint64_t accelerationStructureReference; +} VkAccelerationStructureMatrixMotionInstanceNV; + +typedef struct VkSRTDataNV { + float sx; + float a; + float b; + float pvx; + float sy; + float c; + float pvy; + float sz; + float pvz; + float qx; + float qy; + float qz; + float qw; + float tx; + float ty; + float tz; +} VkSRTDataNV; + +typedef struct VkAccelerationStructureSRTMotionInstanceNV { + VkSRTDataNV transformT0; + VkSRTDataNV transformT1; + uint32_t instanceCustomIndex:24; + uint32_t mask:8; + uint32_t instanceShaderBindingTableRecordOffset:24; + VkGeometryInstanceFlagsKHR flags:8; + uint64_t accelerationStructureReference; +} VkAccelerationStructureSRTMotionInstanceNV; + +typedef union VkAccelerationStructureMotionInstanceDataNV { + VkAccelerationStructureInstanceKHR staticInstance; + VkAccelerationStructureMatrixMotionInstanceNV matrixMotionInstance; + VkAccelerationStructureSRTMotionInstanceNV srtMotionInstance; +} VkAccelerationStructureMotionInstanceDataNV; + +typedef struct VkAccelerationStructureMotionInstanceNV { + VkAccelerationStructureMotionInstanceTypeNV type; + VkAccelerationStructureMotionInstanceFlagsNV flags; + VkAccelerationStructureMotionInstanceDataNV data; +} VkAccelerationStructureMotionInstanceNV; + +typedef struct VkPhysicalDeviceRayTracingMotionBlurFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 rayTracingMotionBlur; + VkBool32 rayTracingMotionBlurPipelineTraceRaysIndirect; +} VkPhysicalDeviceRayTracingMotionBlurFeaturesNV; + + + +// VK_EXT_ycbcr_2plane_444_formats is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_ycbcr_2plane_444_formats 1 +#define VK_EXT_YCBCR_2PLANE_444_FORMATS_SPEC_VERSION 1 +#define VK_EXT_YCBCR_2PLANE_444_FORMATS_EXTENSION_NAME "VK_EXT_ycbcr_2plane_444_formats" +typedef struct VkPhysicalDeviceYcbcr2Plane444FormatsFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 ycbcr2plane444Formats; +} VkPhysicalDeviceYcbcr2Plane444FormatsFeaturesEXT; + + + +// VK_EXT_fragment_density_map2 is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_fragment_density_map2 1 +#define VK_EXT_FRAGMENT_DENSITY_MAP_2_SPEC_VERSION 1 +#define VK_EXT_FRAGMENT_DENSITY_MAP_2_EXTENSION_NAME "VK_EXT_fragment_density_map2" +typedef struct VkPhysicalDeviceFragmentDensityMap2FeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 fragmentDensityMapDeferred; +} VkPhysicalDeviceFragmentDensityMap2FeaturesEXT; + +typedef struct VkPhysicalDeviceFragmentDensityMap2PropertiesEXT { + VkStructureType sType; + void* pNext; + VkBool32 subsampledLoads; + VkBool32 subsampledCoarseReconstructionEarlyAccess; + uint32_t maxSubsampledArrayLayers; + uint32_t maxDescriptorSetSubsampledSamplers; +} VkPhysicalDeviceFragmentDensityMap2PropertiesEXT; + + + +// VK_QCOM_rotated_copy_commands is a preprocessor guard. Do not pass it to API calls. +#define VK_QCOM_rotated_copy_commands 1 +#define VK_QCOM_ROTATED_COPY_COMMANDS_SPEC_VERSION 2 +#define VK_QCOM_ROTATED_COPY_COMMANDS_EXTENSION_NAME "VK_QCOM_rotated_copy_commands" +typedef struct VkCopyCommandTransformInfoQCOM { + VkStructureType sType; + const void* pNext; + VkSurfaceTransformFlagBitsKHR transform; +} VkCopyCommandTransformInfoQCOM; + + + +// VK_EXT_image_robustness is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_image_robustness 1 +#define VK_EXT_IMAGE_ROBUSTNESS_SPEC_VERSION 1 +#define VK_EXT_IMAGE_ROBUSTNESS_EXTENSION_NAME "VK_EXT_image_robustness" +typedef VkPhysicalDeviceImageRobustnessFeatures VkPhysicalDeviceImageRobustnessFeaturesEXT; + + + +// VK_EXT_image_compression_control is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_image_compression_control 1 +#define VK_EXT_IMAGE_COMPRESSION_CONTROL_SPEC_VERSION 1 +#define VK_EXT_IMAGE_COMPRESSION_CONTROL_EXTENSION_NAME "VK_EXT_image_compression_control" + +typedef enum VkImageCompressionFlagBitsEXT { + VK_IMAGE_COMPRESSION_DEFAULT_EXT = 0, + VK_IMAGE_COMPRESSION_FIXED_RATE_DEFAULT_EXT = 0x00000001, + VK_IMAGE_COMPRESSION_FIXED_RATE_EXPLICIT_EXT = 0x00000002, + VK_IMAGE_COMPRESSION_DISABLED_EXT = 0x00000004, + VK_IMAGE_COMPRESSION_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkImageCompressionFlagBitsEXT; +typedef VkFlags VkImageCompressionFlagsEXT; + +typedef enum VkImageCompressionFixedRateFlagBitsEXT { + VK_IMAGE_COMPRESSION_FIXED_RATE_NONE_EXT = 0, + VK_IMAGE_COMPRESSION_FIXED_RATE_1BPC_BIT_EXT = 0x00000001, + VK_IMAGE_COMPRESSION_FIXED_RATE_2BPC_BIT_EXT = 0x00000002, + VK_IMAGE_COMPRESSION_FIXED_RATE_3BPC_BIT_EXT = 0x00000004, + VK_IMAGE_COMPRESSION_FIXED_RATE_4BPC_BIT_EXT = 0x00000008, + VK_IMAGE_COMPRESSION_FIXED_RATE_5BPC_BIT_EXT = 0x00000010, + VK_IMAGE_COMPRESSION_FIXED_RATE_6BPC_BIT_EXT = 0x00000020, + VK_IMAGE_COMPRESSION_FIXED_RATE_7BPC_BIT_EXT = 0x00000040, + VK_IMAGE_COMPRESSION_FIXED_RATE_8BPC_BIT_EXT = 0x00000080, + VK_IMAGE_COMPRESSION_FIXED_RATE_9BPC_BIT_EXT = 0x00000100, + VK_IMAGE_COMPRESSION_FIXED_RATE_10BPC_BIT_EXT = 0x00000200, + VK_IMAGE_COMPRESSION_FIXED_RATE_11BPC_BIT_EXT = 0x00000400, + VK_IMAGE_COMPRESSION_FIXED_RATE_12BPC_BIT_EXT = 0x00000800, + VK_IMAGE_COMPRESSION_FIXED_RATE_13BPC_BIT_EXT = 0x00001000, + VK_IMAGE_COMPRESSION_FIXED_RATE_14BPC_BIT_EXT = 0x00002000, + VK_IMAGE_COMPRESSION_FIXED_RATE_15BPC_BIT_EXT = 0x00004000, + VK_IMAGE_COMPRESSION_FIXED_RATE_16BPC_BIT_EXT = 0x00008000, + VK_IMAGE_COMPRESSION_FIXED_RATE_17BPC_BIT_EXT = 0x00010000, + VK_IMAGE_COMPRESSION_FIXED_RATE_18BPC_BIT_EXT = 0x00020000, + VK_IMAGE_COMPRESSION_FIXED_RATE_19BPC_BIT_EXT = 0x00040000, + VK_IMAGE_COMPRESSION_FIXED_RATE_20BPC_BIT_EXT = 0x00080000, + VK_IMAGE_COMPRESSION_FIXED_RATE_21BPC_BIT_EXT = 0x00100000, + VK_IMAGE_COMPRESSION_FIXED_RATE_22BPC_BIT_EXT = 0x00200000, + VK_IMAGE_COMPRESSION_FIXED_RATE_23BPC_BIT_EXT = 0x00400000, + VK_IMAGE_COMPRESSION_FIXED_RATE_24BPC_BIT_EXT = 0x00800000, + VK_IMAGE_COMPRESSION_FIXED_RATE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkImageCompressionFixedRateFlagBitsEXT; +typedef VkFlags VkImageCompressionFixedRateFlagsEXT; +typedef struct VkPhysicalDeviceImageCompressionControlFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 imageCompressionControl; +} VkPhysicalDeviceImageCompressionControlFeaturesEXT; + +typedef struct VkImageCompressionControlEXT { + VkStructureType sType; + const void* pNext; + VkImageCompressionFlagsEXT flags; + uint32_t compressionControlPlaneCount; + VkImageCompressionFixedRateFlagsEXT* pFixedRateFlags; +} VkImageCompressionControlEXT; + +typedef struct VkImageCompressionPropertiesEXT { + VkStructureType sType; + void* pNext; + VkImageCompressionFlagsEXT imageCompressionFlags; + VkImageCompressionFixedRateFlagsEXT imageCompressionFixedRateFlags; +} VkImageCompressionPropertiesEXT; + + + +// VK_EXT_attachment_feedback_loop_layout is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_attachment_feedback_loop_layout 1 +#define VK_EXT_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_SPEC_VERSION 2 +#define VK_EXT_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_EXTENSION_NAME "VK_EXT_attachment_feedback_loop_layout" +typedef struct VkPhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 attachmentFeedbackLoopLayout; +} VkPhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT; + + + +// VK_EXT_4444_formats is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_4444_formats 1 +#define VK_EXT_4444_FORMATS_SPEC_VERSION 1 +#define VK_EXT_4444_FORMATS_EXTENSION_NAME "VK_EXT_4444_formats" +typedef struct VkPhysicalDevice4444FormatsFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 formatA4R4G4B4; + VkBool32 formatA4B4G4R4; +} VkPhysicalDevice4444FormatsFeaturesEXT; + + + +// VK_EXT_device_fault is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_device_fault 1 +#define VK_EXT_DEVICE_FAULT_SPEC_VERSION 2 +#define VK_EXT_DEVICE_FAULT_EXTENSION_NAME "VK_EXT_device_fault" + +typedef enum VkDeviceFaultAddressTypeEXT { + VK_DEVICE_FAULT_ADDRESS_TYPE_NONE_EXT = 0, + VK_DEVICE_FAULT_ADDRESS_TYPE_READ_INVALID_EXT = 1, + VK_DEVICE_FAULT_ADDRESS_TYPE_WRITE_INVALID_EXT = 2, + VK_DEVICE_FAULT_ADDRESS_TYPE_EXECUTE_INVALID_EXT = 3, + VK_DEVICE_FAULT_ADDRESS_TYPE_INSTRUCTION_POINTER_UNKNOWN_EXT = 4, + VK_DEVICE_FAULT_ADDRESS_TYPE_INSTRUCTION_POINTER_INVALID_EXT = 5, + VK_DEVICE_FAULT_ADDRESS_TYPE_INSTRUCTION_POINTER_FAULT_EXT = 6, + VK_DEVICE_FAULT_ADDRESS_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF +} VkDeviceFaultAddressTypeEXT; + +typedef enum VkDeviceFaultVendorBinaryHeaderVersionEXT { + VK_DEVICE_FAULT_VENDOR_BINARY_HEADER_VERSION_ONE_EXT = 1, + VK_DEVICE_FAULT_VENDOR_BINARY_HEADER_VERSION_MAX_ENUM_EXT = 0x7FFFFFFF +} VkDeviceFaultVendorBinaryHeaderVersionEXT; +typedef struct VkPhysicalDeviceFaultFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 deviceFault; + VkBool32 deviceFaultVendorBinary; +} VkPhysicalDeviceFaultFeaturesEXT; + +typedef struct VkDeviceFaultCountsEXT { + VkStructureType sType; + void* pNext; + uint32_t addressInfoCount; + uint32_t vendorInfoCount; + VkDeviceSize vendorBinarySize; +} VkDeviceFaultCountsEXT; + +typedef struct VkDeviceFaultAddressInfoEXT { + VkDeviceFaultAddressTypeEXT addressType; + VkDeviceAddress reportedAddress; + VkDeviceSize addressPrecision; +} VkDeviceFaultAddressInfoEXT; + +typedef struct VkDeviceFaultVendorInfoEXT { + char description[VK_MAX_DESCRIPTION_SIZE]; + uint64_t vendorFaultCode; + uint64_t vendorFaultData; +} VkDeviceFaultVendorInfoEXT; + +typedef struct VkDeviceFaultInfoEXT { + VkStructureType sType; + void* pNext; + char description[VK_MAX_DESCRIPTION_SIZE]; + VkDeviceFaultAddressInfoEXT* pAddressInfos; + VkDeviceFaultVendorInfoEXT* pVendorInfos; + void* pVendorBinaryData; +} VkDeviceFaultInfoEXT; + +typedef struct VkDeviceFaultVendorBinaryHeaderVersionOneEXT { + uint32_t headerSize; + VkDeviceFaultVendorBinaryHeaderVersionEXT headerVersion; + uint32_t vendorID; + uint32_t deviceID; + uint32_t driverVersion; + uint8_t pipelineCacheUUID[VK_UUID_SIZE]; + uint32_t applicationNameOffset; + uint32_t applicationVersion; + uint32_t engineNameOffset; + uint32_t engineVersion; + uint32_t apiVersion; +} VkDeviceFaultVendorBinaryHeaderVersionOneEXT; + +typedef VkResult (VKAPI_PTR *PFN_vkGetDeviceFaultInfoEXT)(VkDevice device, VkDeviceFaultCountsEXT* pFaultCounts, VkDeviceFaultInfoEXT* pFaultInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceFaultInfoEXT( + VkDevice device, + VkDeviceFaultCountsEXT* pFaultCounts, + VkDeviceFaultInfoEXT* pFaultInfo); +#endif + + +// VK_ARM_rasterization_order_attachment_access is a preprocessor guard. Do not pass it to API calls. +#define VK_ARM_rasterization_order_attachment_access 1 +#define VK_ARM_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_SPEC_VERSION 1 +#define VK_ARM_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_EXTENSION_NAME "VK_ARM_rasterization_order_attachment_access" +typedef struct VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 rasterizationOrderColorAttachmentAccess; + VkBool32 rasterizationOrderDepthAttachmentAccess; + VkBool32 rasterizationOrderStencilAttachmentAccess; +} VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT; + +typedef VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesARM; + + + +// VK_EXT_rgba10x6_formats is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_rgba10x6_formats 1 +#define VK_EXT_RGBA10X6_FORMATS_SPEC_VERSION 1 +#define VK_EXT_RGBA10X6_FORMATS_EXTENSION_NAME "VK_EXT_rgba10x6_formats" +typedef struct VkPhysicalDeviceRGBA10X6FormatsFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 formatRgba10x6WithoutYCbCrSampler; +} VkPhysicalDeviceRGBA10X6FormatsFeaturesEXT; + + + +// VK_VALVE_mutable_descriptor_type is a preprocessor guard. Do not pass it to API calls. +#define VK_VALVE_mutable_descriptor_type 1 +#define VK_VALVE_MUTABLE_DESCRIPTOR_TYPE_SPEC_VERSION 1 +#define VK_VALVE_MUTABLE_DESCRIPTOR_TYPE_EXTENSION_NAME "VK_VALVE_mutable_descriptor_type" +typedef struct VkPhysicalDeviceMutableDescriptorTypeFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 mutableDescriptorType; +} VkPhysicalDeviceMutableDescriptorTypeFeaturesEXT; + +typedef VkPhysicalDeviceMutableDescriptorTypeFeaturesEXT VkPhysicalDeviceMutableDescriptorTypeFeaturesVALVE; + +typedef struct VkMutableDescriptorTypeListEXT { + uint32_t descriptorTypeCount; + const VkDescriptorType* pDescriptorTypes; +} VkMutableDescriptorTypeListEXT; + +typedef VkMutableDescriptorTypeListEXT VkMutableDescriptorTypeListVALVE; + +typedef struct VkMutableDescriptorTypeCreateInfoEXT { + VkStructureType sType; + const void* pNext; + uint32_t mutableDescriptorTypeListCount; + const VkMutableDescriptorTypeListEXT* pMutableDescriptorTypeLists; +} VkMutableDescriptorTypeCreateInfoEXT; + +typedef VkMutableDescriptorTypeCreateInfoEXT VkMutableDescriptorTypeCreateInfoVALVE; + + + +// VK_EXT_vertex_input_dynamic_state is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_vertex_input_dynamic_state 1 +#define VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_SPEC_VERSION 2 +#define VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME "VK_EXT_vertex_input_dynamic_state" +typedef struct VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 vertexInputDynamicState; +} VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT; + +typedef struct VkVertexInputBindingDescription2EXT { + VkStructureType sType; + void* pNext; + uint32_t binding; + uint32_t stride; + VkVertexInputRate inputRate; + uint32_t divisor; +} VkVertexInputBindingDescription2EXT; + +typedef struct VkVertexInputAttributeDescription2EXT { + VkStructureType sType; + void* pNext; + uint32_t location; + uint32_t binding; + VkFormat format; + uint32_t offset; +} VkVertexInputAttributeDescription2EXT; + +typedef void (VKAPI_PTR *PFN_vkCmdSetVertexInputEXT)(VkCommandBuffer commandBuffer, uint32_t vertexBindingDescriptionCount, const VkVertexInputBindingDescription2EXT* pVertexBindingDescriptions, uint32_t vertexAttributeDescriptionCount, const VkVertexInputAttributeDescription2EXT* pVertexAttributeDescriptions); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdSetVertexInputEXT( + VkCommandBuffer commandBuffer, + uint32_t vertexBindingDescriptionCount, + const VkVertexInputBindingDescription2EXT* pVertexBindingDescriptions, + uint32_t vertexAttributeDescriptionCount, + const VkVertexInputAttributeDescription2EXT* pVertexAttributeDescriptions); +#endif + + +// VK_EXT_physical_device_drm is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_physical_device_drm 1 +#define VK_EXT_PHYSICAL_DEVICE_DRM_SPEC_VERSION 1 +#define VK_EXT_PHYSICAL_DEVICE_DRM_EXTENSION_NAME "VK_EXT_physical_device_drm" +typedef struct VkPhysicalDeviceDrmPropertiesEXT { + VkStructureType sType; + void* pNext; + VkBool32 hasPrimary; + VkBool32 hasRender; + int64_t primaryMajor; + int64_t primaryMinor; + int64_t renderMajor; + int64_t renderMinor; +} VkPhysicalDeviceDrmPropertiesEXT; + + + +// VK_EXT_device_address_binding_report is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_device_address_binding_report 1 +#define VK_EXT_DEVICE_ADDRESS_BINDING_REPORT_SPEC_VERSION 1 +#define VK_EXT_DEVICE_ADDRESS_BINDING_REPORT_EXTENSION_NAME "VK_EXT_device_address_binding_report" + +typedef enum VkDeviceAddressBindingTypeEXT { + VK_DEVICE_ADDRESS_BINDING_TYPE_BIND_EXT = 0, + VK_DEVICE_ADDRESS_BINDING_TYPE_UNBIND_EXT = 1, + VK_DEVICE_ADDRESS_BINDING_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF +} VkDeviceAddressBindingTypeEXT; + +typedef enum VkDeviceAddressBindingFlagBitsEXT { + VK_DEVICE_ADDRESS_BINDING_INTERNAL_OBJECT_BIT_EXT = 0x00000001, + VK_DEVICE_ADDRESS_BINDING_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkDeviceAddressBindingFlagBitsEXT; +typedef VkFlags VkDeviceAddressBindingFlagsEXT; +typedef struct VkPhysicalDeviceAddressBindingReportFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 reportAddressBinding; +} VkPhysicalDeviceAddressBindingReportFeaturesEXT; + +typedef struct VkDeviceAddressBindingCallbackDataEXT { + VkStructureType sType; + void* pNext; + VkDeviceAddressBindingFlagsEXT flags; + VkDeviceAddress baseAddress; + VkDeviceSize size; + VkDeviceAddressBindingTypeEXT bindingType; +} VkDeviceAddressBindingCallbackDataEXT; + + + +// VK_EXT_depth_clip_control is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_depth_clip_control 1 +#define VK_EXT_DEPTH_CLIP_CONTROL_SPEC_VERSION 1 +#define VK_EXT_DEPTH_CLIP_CONTROL_EXTENSION_NAME "VK_EXT_depth_clip_control" +typedef struct VkPhysicalDeviceDepthClipControlFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 depthClipControl; +} VkPhysicalDeviceDepthClipControlFeaturesEXT; + +typedef struct VkPipelineViewportDepthClipControlCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkBool32 negativeOneToOne; +} VkPipelineViewportDepthClipControlCreateInfoEXT; + + + +// VK_EXT_primitive_topology_list_restart is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_primitive_topology_list_restart 1 +#define VK_EXT_PRIMITIVE_TOPOLOGY_LIST_RESTART_SPEC_VERSION 1 +#define VK_EXT_PRIMITIVE_TOPOLOGY_LIST_RESTART_EXTENSION_NAME "VK_EXT_primitive_topology_list_restart" +typedef struct VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 primitiveTopologyListRestart; + VkBool32 primitiveTopologyPatchListRestart; +} VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT; + + + +// VK_HUAWEI_subpass_shading is a preprocessor guard. Do not pass it to API calls. +#define VK_HUAWEI_subpass_shading 1 +#define VK_HUAWEI_SUBPASS_SHADING_SPEC_VERSION 3 +#define VK_HUAWEI_SUBPASS_SHADING_EXTENSION_NAME "VK_HUAWEI_subpass_shading" +typedef struct VkSubpassShadingPipelineCreateInfoHUAWEI { + VkStructureType sType; + void* pNext; + VkRenderPass renderPass; + uint32_t subpass; +} VkSubpassShadingPipelineCreateInfoHUAWEI; + +typedef struct VkPhysicalDeviceSubpassShadingFeaturesHUAWEI { + VkStructureType sType; + void* pNext; + VkBool32 subpassShading; +} VkPhysicalDeviceSubpassShadingFeaturesHUAWEI; + +typedef struct VkPhysicalDeviceSubpassShadingPropertiesHUAWEI { + VkStructureType sType; + void* pNext; + uint32_t maxSubpassShadingWorkgroupSizeAspectRatio; +} VkPhysicalDeviceSubpassShadingPropertiesHUAWEI; + +typedef VkResult (VKAPI_PTR *PFN_vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI)(VkDevice device, VkRenderPass renderpass, VkExtent2D* pMaxWorkgroupSize); +typedef void (VKAPI_PTR *PFN_vkCmdSubpassShadingHUAWEI)(VkCommandBuffer commandBuffer); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceSubpassShadingMaxWorkgroupSizeHUAWEI( + VkDevice device, + VkRenderPass renderpass, + VkExtent2D* pMaxWorkgroupSize); + +VKAPI_ATTR void VKAPI_CALL vkCmdSubpassShadingHUAWEI( + VkCommandBuffer commandBuffer); +#endif + + +// VK_HUAWEI_invocation_mask is a preprocessor guard. Do not pass it to API calls. +#define VK_HUAWEI_invocation_mask 1 +#define VK_HUAWEI_INVOCATION_MASK_SPEC_VERSION 1 +#define VK_HUAWEI_INVOCATION_MASK_EXTENSION_NAME "VK_HUAWEI_invocation_mask" +typedef struct VkPhysicalDeviceInvocationMaskFeaturesHUAWEI { + VkStructureType sType; + void* pNext; + VkBool32 invocationMask; +} VkPhysicalDeviceInvocationMaskFeaturesHUAWEI; + +typedef void (VKAPI_PTR *PFN_vkCmdBindInvocationMaskHUAWEI)(VkCommandBuffer commandBuffer, VkImageView imageView, VkImageLayout imageLayout); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdBindInvocationMaskHUAWEI( + VkCommandBuffer commandBuffer, + VkImageView imageView, + VkImageLayout imageLayout); +#endif + + +// VK_NV_external_memory_rdma is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_external_memory_rdma 1 +typedef void* VkRemoteAddressNV; +#define VK_NV_EXTERNAL_MEMORY_RDMA_SPEC_VERSION 1 +#define VK_NV_EXTERNAL_MEMORY_RDMA_EXTENSION_NAME "VK_NV_external_memory_rdma" +typedef struct VkMemoryGetRemoteAddressInfoNV { + VkStructureType sType; + const void* pNext; + VkDeviceMemory memory; + VkExternalMemoryHandleTypeFlagBits handleType; +} VkMemoryGetRemoteAddressInfoNV; + +typedef struct VkPhysicalDeviceExternalMemoryRDMAFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 externalMemoryRDMA; +} VkPhysicalDeviceExternalMemoryRDMAFeaturesNV; + +typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryRemoteAddressNV)(VkDevice device, const VkMemoryGetRemoteAddressInfoNV* pMemoryGetRemoteAddressInfo, VkRemoteAddressNV* pAddress); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryRemoteAddressNV( + VkDevice device, + const VkMemoryGetRemoteAddressInfoNV* pMemoryGetRemoteAddressInfo, + VkRemoteAddressNV* pAddress); +#endif + + +// VK_EXT_pipeline_properties is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_pipeline_properties 1 +#define VK_EXT_PIPELINE_PROPERTIES_SPEC_VERSION 1 +#define VK_EXT_PIPELINE_PROPERTIES_EXTENSION_NAME "VK_EXT_pipeline_properties" +typedef VkPipelineInfoKHR VkPipelineInfoEXT; + +typedef struct VkPipelinePropertiesIdentifierEXT { + VkStructureType sType; + void* pNext; + uint8_t pipelineIdentifier[VK_UUID_SIZE]; +} VkPipelinePropertiesIdentifierEXT; + +typedef struct VkPhysicalDevicePipelinePropertiesFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 pipelinePropertiesIdentifier; +} VkPhysicalDevicePipelinePropertiesFeaturesEXT; + +typedef VkResult (VKAPI_PTR *PFN_vkGetPipelinePropertiesEXT)(VkDevice device, const VkPipelineInfoEXT* pPipelineInfo, VkBaseOutStructure* pPipelineProperties); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelinePropertiesEXT( + VkDevice device, + const VkPipelineInfoEXT* pPipelineInfo, + VkBaseOutStructure* pPipelineProperties); +#endif + + +// VK_EXT_frame_boundary is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_frame_boundary 1 +#define VK_EXT_FRAME_BOUNDARY_SPEC_VERSION 1 +#define VK_EXT_FRAME_BOUNDARY_EXTENSION_NAME "VK_EXT_frame_boundary" + +typedef enum VkFrameBoundaryFlagBitsEXT { + VK_FRAME_BOUNDARY_FRAME_END_BIT_EXT = 0x00000001, + VK_FRAME_BOUNDARY_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkFrameBoundaryFlagBitsEXT; +typedef VkFlags VkFrameBoundaryFlagsEXT; +typedef struct VkPhysicalDeviceFrameBoundaryFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 frameBoundary; +} VkPhysicalDeviceFrameBoundaryFeaturesEXT; + +typedef struct VkFrameBoundaryEXT { + VkStructureType sType; + const void* pNext; + VkFrameBoundaryFlagsEXT flags; + uint64_t frameID; + uint32_t imageCount; + const VkImage* pImages; + uint32_t bufferCount; + const VkBuffer* pBuffers; + uint64_t tagName; + size_t tagSize; + const void* pTag; +} VkFrameBoundaryEXT; + + + +// VK_EXT_multisampled_render_to_single_sampled is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_multisampled_render_to_single_sampled 1 +#define VK_EXT_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_SPEC_VERSION 1 +#define VK_EXT_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_EXTENSION_NAME "VK_EXT_multisampled_render_to_single_sampled" +typedef struct VkPhysicalDeviceMultisampledRenderToSingleSampledFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 multisampledRenderToSingleSampled; +} VkPhysicalDeviceMultisampledRenderToSingleSampledFeaturesEXT; + +typedef struct VkSubpassResolvePerformanceQueryEXT { + VkStructureType sType; + void* pNext; + VkBool32 optimal; +} VkSubpassResolvePerformanceQueryEXT; + +typedef struct VkMultisampledRenderToSingleSampledInfoEXT { + VkStructureType sType; + const void* pNext; + VkBool32 multisampledRenderToSingleSampledEnable; + VkSampleCountFlagBits rasterizationSamples; +} VkMultisampledRenderToSingleSampledInfoEXT; + + + +// VK_EXT_extended_dynamic_state2 is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_extended_dynamic_state2 1 +#define VK_EXT_EXTENDED_DYNAMIC_STATE_2_SPEC_VERSION 1 +#define VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME "VK_EXT_extended_dynamic_state2" +typedef struct VkPhysicalDeviceExtendedDynamicState2FeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 extendedDynamicState2; + VkBool32 extendedDynamicState2LogicOp; + VkBool32 extendedDynamicState2PatchControlPoints; +} VkPhysicalDeviceExtendedDynamicState2FeaturesEXT; + +typedef void (VKAPI_PTR *PFN_vkCmdSetPatchControlPointsEXT)(VkCommandBuffer commandBuffer, uint32_t patchControlPoints); +typedef void (VKAPI_PTR *PFN_vkCmdSetRasterizerDiscardEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 rasterizerDiscardEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthBiasEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 depthBiasEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetLogicOpEXT)(VkCommandBuffer commandBuffer, VkLogicOp logicOp); +typedef void (VKAPI_PTR *PFN_vkCmdSetPrimitiveRestartEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 primitiveRestartEnable); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdSetPatchControlPointsEXT( + VkCommandBuffer commandBuffer, + uint32_t patchControlPoints); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetRasterizerDiscardEnableEXT( + VkCommandBuffer commandBuffer, + VkBool32 rasterizerDiscardEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthBiasEnableEXT( + VkCommandBuffer commandBuffer, + VkBool32 depthBiasEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetLogicOpEXT( + VkCommandBuffer commandBuffer, + VkLogicOp logicOp); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetPrimitiveRestartEnableEXT( + VkCommandBuffer commandBuffer, + VkBool32 primitiveRestartEnable); +#endif + + +// VK_EXT_color_write_enable is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_color_write_enable 1 +#define VK_EXT_COLOR_WRITE_ENABLE_SPEC_VERSION 1 +#define VK_EXT_COLOR_WRITE_ENABLE_EXTENSION_NAME "VK_EXT_color_write_enable" +typedef struct VkPhysicalDeviceColorWriteEnableFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 colorWriteEnable; +} VkPhysicalDeviceColorWriteEnableFeaturesEXT; + +typedef struct VkPipelineColorWriteCreateInfoEXT { + VkStructureType sType; + const void* pNext; + uint32_t attachmentCount; + const VkBool32* pColorWriteEnables; +} VkPipelineColorWriteCreateInfoEXT; + +typedef void (VKAPI_PTR *PFN_vkCmdSetColorWriteEnableEXT)(VkCommandBuffer commandBuffer, uint32_t attachmentCount, const VkBool32* pColorWriteEnables); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdSetColorWriteEnableEXT( + VkCommandBuffer commandBuffer, + uint32_t attachmentCount, + const VkBool32* pColorWriteEnables); +#endif + + +// VK_EXT_primitives_generated_query is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_primitives_generated_query 1 +#define VK_EXT_PRIMITIVES_GENERATED_QUERY_SPEC_VERSION 1 +#define VK_EXT_PRIMITIVES_GENERATED_QUERY_EXTENSION_NAME "VK_EXT_primitives_generated_query" +typedef struct VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 primitivesGeneratedQuery; + VkBool32 primitivesGeneratedQueryWithRasterizerDiscard; + VkBool32 primitivesGeneratedQueryWithNonZeroStreams; +} VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT; + + + +// VK_EXT_global_priority_query is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_global_priority_query 1 +#define VK_EXT_GLOBAL_PRIORITY_QUERY_SPEC_VERSION 1 +#define VK_EXT_GLOBAL_PRIORITY_QUERY_EXTENSION_NAME "VK_EXT_global_priority_query" +#define VK_MAX_GLOBAL_PRIORITY_SIZE_EXT VK_MAX_GLOBAL_PRIORITY_SIZE_KHR +typedef VkPhysicalDeviceGlobalPriorityQueryFeaturesKHR VkPhysicalDeviceGlobalPriorityQueryFeaturesEXT; + +typedef VkQueueFamilyGlobalPriorityPropertiesKHR VkQueueFamilyGlobalPriorityPropertiesEXT; + + + +// VK_EXT_image_view_min_lod is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_image_view_min_lod 1 +#define VK_EXT_IMAGE_VIEW_MIN_LOD_SPEC_VERSION 1 +#define VK_EXT_IMAGE_VIEW_MIN_LOD_EXTENSION_NAME "VK_EXT_image_view_min_lod" +typedef struct VkPhysicalDeviceImageViewMinLodFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 minLod; +} VkPhysicalDeviceImageViewMinLodFeaturesEXT; + +typedef struct VkImageViewMinLodCreateInfoEXT { + VkStructureType sType; + const void* pNext; + float minLod; +} VkImageViewMinLodCreateInfoEXT; + + + +// VK_EXT_multi_draw is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_multi_draw 1 +#define VK_EXT_MULTI_DRAW_SPEC_VERSION 1 +#define VK_EXT_MULTI_DRAW_EXTENSION_NAME "VK_EXT_multi_draw" +typedef struct VkPhysicalDeviceMultiDrawFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 multiDraw; +} VkPhysicalDeviceMultiDrawFeaturesEXT; + +typedef struct VkPhysicalDeviceMultiDrawPropertiesEXT { + VkStructureType sType; + void* pNext; + uint32_t maxMultiDrawCount; +} VkPhysicalDeviceMultiDrawPropertiesEXT; + +typedef struct VkMultiDrawInfoEXT { + uint32_t firstVertex; + uint32_t vertexCount; +} VkMultiDrawInfoEXT; + +typedef struct VkMultiDrawIndexedInfoEXT { + uint32_t firstIndex; + uint32_t indexCount; + int32_t vertexOffset; +} VkMultiDrawIndexedInfoEXT; + +typedef void (VKAPI_PTR *PFN_vkCmdDrawMultiEXT)(VkCommandBuffer commandBuffer, uint32_t drawCount, const VkMultiDrawInfoEXT* pVertexInfo, uint32_t instanceCount, uint32_t firstInstance, uint32_t stride); +typedef void (VKAPI_PTR *PFN_vkCmdDrawMultiIndexedEXT)(VkCommandBuffer commandBuffer, uint32_t drawCount, const VkMultiDrawIndexedInfoEXT* pIndexInfo, uint32_t instanceCount, uint32_t firstInstance, uint32_t stride, const int32_t* pVertexOffset); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdDrawMultiEXT( + VkCommandBuffer commandBuffer, + uint32_t drawCount, + const VkMultiDrawInfoEXT* pVertexInfo, + uint32_t instanceCount, + uint32_t firstInstance, + uint32_t stride); + +VKAPI_ATTR void VKAPI_CALL vkCmdDrawMultiIndexedEXT( + VkCommandBuffer commandBuffer, + uint32_t drawCount, + const VkMultiDrawIndexedInfoEXT* pIndexInfo, + uint32_t instanceCount, + uint32_t firstInstance, + uint32_t stride, + const int32_t* pVertexOffset); +#endif + + +// VK_EXT_image_2d_view_of_3d is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_image_2d_view_of_3d 1 +#define VK_EXT_IMAGE_2D_VIEW_OF_3D_SPEC_VERSION 1 +#define VK_EXT_IMAGE_2D_VIEW_OF_3D_EXTENSION_NAME "VK_EXT_image_2d_view_of_3d" +typedef struct VkPhysicalDeviceImage2DViewOf3DFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 image2DViewOf3D; + VkBool32 sampler2DViewOf3D; +} VkPhysicalDeviceImage2DViewOf3DFeaturesEXT; + + + +// VK_EXT_shader_tile_image is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_shader_tile_image 1 +#define VK_EXT_SHADER_TILE_IMAGE_SPEC_VERSION 1 +#define VK_EXT_SHADER_TILE_IMAGE_EXTENSION_NAME "VK_EXT_shader_tile_image" +typedef struct VkPhysicalDeviceShaderTileImageFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 shaderTileImageColorReadAccess; + VkBool32 shaderTileImageDepthReadAccess; + VkBool32 shaderTileImageStencilReadAccess; +} VkPhysicalDeviceShaderTileImageFeaturesEXT; + +typedef struct VkPhysicalDeviceShaderTileImagePropertiesEXT { + VkStructureType sType; + void* pNext; + VkBool32 shaderTileImageCoherentReadAccelerated; + VkBool32 shaderTileImageReadSampleFromPixelRateInvocation; + VkBool32 shaderTileImageReadFromHelperInvocation; +} VkPhysicalDeviceShaderTileImagePropertiesEXT; + + + +// VK_EXT_opacity_micromap is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_opacity_micromap 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkMicromapEXT) +#define VK_EXT_OPACITY_MICROMAP_SPEC_VERSION 2 +#define VK_EXT_OPACITY_MICROMAP_EXTENSION_NAME "VK_EXT_opacity_micromap" + +typedef enum VkMicromapTypeEXT { + VK_MICROMAP_TYPE_OPACITY_MICROMAP_EXT = 0, +#ifdef VK_ENABLE_BETA_EXTENSIONS + VK_MICROMAP_TYPE_DISPLACEMENT_MICROMAP_NV = 1000397000, +#endif + VK_MICROMAP_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF +} VkMicromapTypeEXT; + +typedef enum VkBuildMicromapModeEXT { + VK_BUILD_MICROMAP_MODE_BUILD_EXT = 0, + VK_BUILD_MICROMAP_MODE_MAX_ENUM_EXT = 0x7FFFFFFF +} VkBuildMicromapModeEXT; + +typedef enum VkCopyMicromapModeEXT { + VK_COPY_MICROMAP_MODE_CLONE_EXT = 0, + VK_COPY_MICROMAP_MODE_SERIALIZE_EXT = 1, + VK_COPY_MICROMAP_MODE_DESERIALIZE_EXT = 2, + VK_COPY_MICROMAP_MODE_COMPACT_EXT = 3, + VK_COPY_MICROMAP_MODE_MAX_ENUM_EXT = 0x7FFFFFFF +} VkCopyMicromapModeEXT; + +typedef enum VkOpacityMicromapFormatEXT { + VK_OPACITY_MICROMAP_FORMAT_2_STATE_EXT = 1, + VK_OPACITY_MICROMAP_FORMAT_4_STATE_EXT = 2, + VK_OPACITY_MICROMAP_FORMAT_MAX_ENUM_EXT = 0x7FFFFFFF +} VkOpacityMicromapFormatEXT; + +typedef enum VkOpacityMicromapSpecialIndexEXT { + VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_TRANSPARENT_EXT = -1, + VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_OPAQUE_EXT = -2, + VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_UNKNOWN_TRANSPARENT_EXT = -3, + VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_UNKNOWN_OPAQUE_EXT = -4, + VK_OPACITY_MICROMAP_SPECIAL_INDEX_MAX_ENUM_EXT = 0x7FFFFFFF +} VkOpacityMicromapSpecialIndexEXT; + +typedef enum VkAccelerationStructureCompatibilityKHR { + VK_ACCELERATION_STRUCTURE_COMPATIBILITY_COMPATIBLE_KHR = 0, + VK_ACCELERATION_STRUCTURE_COMPATIBILITY_INCOMPATIBLE_KHR = 1, + VK_ACCELERATION_STRUCTURE_COMPATIBILITY_MAX_ENUM_KHR = 0x7FFFFFFF +} VkAccelerationStructureCompatibilityKHR; + +typedef enum VkAccelerationStructureBuildTypeKHR { + VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR = 0, + VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR = 1, + VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_OR_DEVICE_KHR = 2, + VK_ACCELERATION_STRUCTURE_BUILD_TYPE_MAX_ENUM_KHR = 0x7FFFFFFF +} VkAccelerationStructureBuildTypeKHR; + +typedef enum VkBuildMicromapFlagBitsEXT { + VK_BUILD_MICROMAP_PREFER_FAST_TRACE_BIT_EXT = 0x00000001, + VK_BUILD_MICROMAP_PREFER_FAST_BUILD_BIT_EXT = 0x00000002, + VK_BUILD_MICROMAP_ALLOW_COMPACTION_BIT_EXT = 0x00000004, + VK_BUILD_MICROMAP_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkBuildMicromapFlagBitsEXT; +typedef VkFlags VkBuildMicromapFlagsEXT; + +typedef enum VkMicromapCreateFlagBitsEXT { + VK_MICROMAP_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_EXT = 0x00000001, + VK_MICROMAP_CREATE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkMicromapCreateFlagBitsEXT; +typedef VkFlags VkMicromapCreateFlagsEXT; +typedef struct VkMicromapUsageEXT { + uint32_t count; + uint32_t subdivisionLevel; + uint32_t format; +} VkMicromapUsageEXT; + +typedef union VkDeviceOrHostAddressKHR { + VkDeviceAddress deviceAddress; + void* hostAddress; +} VkDeviceOrHostAddressKHR; + +typedef struct VkMicromapBuildInfoEXT { + VkStructureType sType; + const void* pNext; + VkMicromapTypeEXT type; + VkBuildMicromapFlagsEXT flags; + VkBuildMicromapModeEXT mode; + VkMicromapEXT dstMicromap; + uint32_t usageCountsCount; + const VkMicromapUsageEXT* pUsageCounts; + const VkMicromapUsageEXT* const* ppUsageCounts; + VkDeviceOrHostAddressConstKHR data; + VkDeviceOrHostAddressKHR scratchData; + VkDeviceOrHostAddressConstKHR triangleArray; + VkDeviceSize triangleArrayStride; +} VkMicromapBuildInfoEXT; + +typedef struct VkMicromapCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkMicromapCreateFlagsEXT createFlags; + VkBuffer buffer; + VkDeviceSize offset; + VkDeviceSize size; + VkMicromapTypeEXT type; + VkDeviceAddress deviceAddress; +} VkMicromapCreateInfoEXT; + +typedef struct VkPhysicalDeviceOpacityMicromapFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 micromap; + VkBool32 micromapCaptureReplay; + VkBool32 micromapHostCommands; +} VkPhysicalDeviceOpacityMicromapFeaturesEXT; + +typedef struct VkPhysicalDeviceOpacityMicromapPropertiesEXT { + VkStructureType sType; + void* pNext; + uint32_t maxOpacity2StateSubdivisionLevel; + uint32_t maxOpacity4StateSubdivisionLevel; +} VkPhysicalDeviceOpacityMicromapPropertiesEXT; + +typedef struct VkMicromapVersionInfoEXT { + VkStructureType sType; + const void* pNext; + const uint8_t* pVersionData; +} VkMicromapVersionInfoEXT; + +typedef struct VkCopyMicromapToMemoryInfoEXT { + VkStructureType sType; + const void* pNext; + VkMicromapEXT src; + VkDeviceOrHostAddressKHR dst; + VkCopyMicromapModeEXT mode; +} VkCopyMicromapToMemoryInfoEXT; + +typedef struct VkCopyMemoryToMicromapInfoEXT { + VkStructureType sType; + const void* pNext; + VkDeviceOrHostAddressConstKHR src; + VkMicromapEXT dst; + VkCopyMicromapModeEXT mode; +} VkCopyMemoryToMicromapInfoEXT; + +typedef struct VkCopyMicromapInfoEXT { + VkStructureType sType; + const void* pNext; + VkMicromapEXT src; + VkMicromapEXT dst; + VkCopyMicromapModeEXT mode; +} VkCopyMicromapInfoEXT; + +typedef struct VkMicromapBuildSizesInfoEXT { + VkStructureType sType; + const void* pNext; + VkDeviceSize micromapSize; + VkDeviceSize buildScratchSize; + VkBool32 discardable; +} VkMicromapBuildSizesInfoEXT; + +typedef struct VkAccelerationStructureTrianglesOpacityMicromapEXT { + VkStructureType sType; + void* pNext; + VkIndexType indexType; + VkDeviceOrHostAddressConstKHR indexBuffer; + VkDeviceSize indexStride; + uint32_t baseTriangle; + uint32_t usageCountsCount; + const VkMicromapUsageEXT* pUsageCounts; + const VkMicromapUsageEXT* const* ppUsageCounts; + VkMicromapEXT micromap; +} VkAccelerationStructureTrianglesOpacityMicromapEXT; + +typedef struct VkMicromapTriangleEXT { + uint32_t dataOffset; + uint16_t subdivisionLevel; + uint16_t format; +} VkMicromapTriangleEXT; + +typedef VkResult (VKAPI_PTR *PFN_vkCreateMicromapEXT)(VkDevice device, const VkMicromapCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkMicromapEXT* pMicromap); +typedef void (VKAPI_PTR *PFN_vkDestroyMicromapEXT)(VkDevice device, VkMicromapEXT micromap, const VkAllocationCallbacks* pAllocator); +typedef void (VKAPI_PTR *PFN_vkCmdBuildMicromapsEXT)(VkCommandBuffer commandBuffer, uint32_t infoCount, const VkMicromapBuildInfoEXT* pInfos); +typedef VkResult (VKAPI_PTR *PFN_vkBuildMicromapsEXT)(VkDevice device, VkDeferredOperationKHR deferredOperation, uint32_t infoCount, const VkMicromapBuildInfoEXT* pInfos); +typedef VkResult (VKAPI_PTR *PFN_vkCopyMicromapEXT)(VkDevice device, VkDeferredOperationKHR deferredOperation, const VkCopyMicromapInfoEXT* pInfo); +typedef VkResult (VKAPI_PTR *PFN_vkCopyMicromapToMemoryEXT)(VkDevice device, VkDeferredOperationKHR deferredOperation, const VkCopyMicromapToMemoryInfoEXT* pInfo); +typedef VkResult (VKAPI_PTR *PFN_vkCopyMemoryToMicromapEXT)(VkDevice device, VkDeferredOperationKHR deferredOperation, const VkCopyMemoryToMicromapInfoEXT* pInfo); +typedef VkResult (VKAPI_PTR *PFN_vkWriteMicromapsPropertiesEXT)(VkDevice device, uint32_t micromapCount, const VkMicromapEXT* pMicromaps, VkQueryType queryType, size_t dataSize, void* pData, size_t stride); +typedef void (VKAPI_PTR *PFN_vkCmdCopyMicromapEXT)(VkCommandBuffer commandBuffer, const VkCopyMicromapInfoEXT* pInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyMicromapToMemoryEXT)(VkCommandBuffer commandBuffer, const VkCopyMicromapToMemoryInfoEXT* pInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyMemoryToMicromapEXT)(VkCommandBuffer commandBuffer, const VkCopyMemoryToMicromapInfoEXT* pInfo); +typedef void (VKAPI_PTR *PFN_vkCmdWriteMicromapsPropertiesEXT)(VkCommandBuffer commandBuffer, uint32_t micromapCount, const VkMicromapEXT* pMicromaps, VkQueryType queryType, VkQueryPool queryPool, uint32_t firstQuery); +typedef void (VKAPI_PTR *PFN_vkGetDeviceMicromapCompatibilityEXT)(VkDevice device, const VkMicromapVersionInfoEXT* pVersionInfo, VkAccelerationStructureCompatibilityKHR* pCompatibility); +typedef void (VKAPI_PTR *PFN_vkGetMicromapBuildSizesEXT)(VkDevice device, VkAccelerationStructureBuildTypeKHR buildType, const VkMicromapBuildInfoEXT* pBuildInfo, VkMicromapBuildSizesInfoEXT* pSizeInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateMicromapEXT( + VkDevice device, + const VkMicromapCreateInfoEXT* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkMicromapEXT* pMicromap); + +VKAPI_ATTR void VKAPI_CALL vkDestroyMicromapEXT( + VkDevice device, + VkMicromapEXT micromap, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR void VKAPI_CALL vkCmdBuildMicromapsEXT( + VkCommandBuffer commandBuffer, + uint32_t infoCount, + const VkMicromapBuildInfoEXT* pInfos); + +VKAPI_ATTR VkResult VKAPI_CALL vkBuildMicromapsEXT( + VkDevice device, + VkDeferredOperationKHR deferredOperation, + uint32_t infoCount, + const VkMicromapBuildInfoEXT* pInfos); + +VKAPI_ATTR VkResult VKAPI_CALL vkCopyMicromapEXT( + VkDevice device, + VkDeferredOperationKHR deferredOperation, + const VkCopyMicromapInfoEXT* pInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkCopyMicromapToMemoryEXT( + VkDevice device, + VkDeferredOperationKHR deferredOperation, + const VkCopyMicromapToMemoryInfoEXT* pInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkCopyMemoryToMicromapEXT( + VkDevice device, + VkDeferredOperationKHR deferredOperation, + const VkCopyMemoryToMicromapInfoEXT* pInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkWriteMicromapsPropertiesEXT( + VkDevice device, + uint32_t micromapCount, + const VkMicromapEXT* pMicromaps, + VkQueryType queryType, + size_t dataSize, + void* pData, + size_t stride); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyMicromapEXT( + VkCommandBuffer commandBuffer, + const VkCopyMicromapInfoEXT* pInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyMicromapToMemoryEXT( + VkCommandBuffer commandBuffer, + const VkCopyMicromapToMemoryInfoEXT* pInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyMemoryToMicromapEXT( + VkCommandBuffer commandBuffer, + const VkCopyMemoryToMicromapInfoEXT* pInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdWriteMicromapsPropertiesEXT( + VkCommandBuffer commandBuffer, + uint32_t micromapCount, + const VkMicromapEXT* pMicromaps, + VkQueryType queryType, + VkQueryPool queryPool, + uint32_t firstQuery); + +VKAPI_ATTR void VKAPI_CALL vkGetDeviceMicromapCompatibilityEXT( + VkDevice device, + const VkMicromapVersionInfoEXT* pVersionInfo, + VkAccelerationStructureCompatibilityKHR* pCompatibility); + +VKAPI_ATTR void VKAPI_CALL vkGetMicromapBuildSizesEXT( + VkDevice device, + VkAccelerationStructureBuildTypeKHR buildType, + const VkMicromapBuildInfoEXT* pBuildInfo, + VkMicromapBuildSizesInfoEXT* pSizeInfo); +#endif + + +// VK_EXT_load_store_op_none is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_load_store_op_none 1 +#define VK_EXT_LOAD_STORE_OP_NONE_SPEC_VERSION 1 +#define VK_EXT_LOAD_STORE_OP_NONE_EXTENSION_NAME "VK_EXT_load_store_op_none" + + +// VK_HUAWEI_cluster_culling_shader is a preprocessor guard. Do not pass it to API calls. +#define VK_HUAWEI_cluster_culling_shader 1 +#define VK_HUAWEI_CLUSTER_CULLING_SHADER_SPEC_VERSION 3 +#define VK_HUAWEI_CLUSTER_CULLING_SHADER_EXTENSION_NAME "VK_HUAWEI_cluster_culling_shader" +typedef struct VkPhysicalDeviceClusterCullingShaderFeaturesHUAWEI { + VkStructureType sType; + void* pNext; + VkBool32 clustercullingShader; + VkBool32 multiviewClusterCullingShader; +} VkPhysicalDeviceClusterCullingShaderFeaturesHUAWEI; + +typedef struct VkPhysicalDeviceClusterCullingShaderPropertiesHUAWEI { + VkStructureType sType; + void* pNext; + uint32_t maxWorkGroupCount[3]; + uint32_t maxWorkGroupSize[3]; + uint32_t maxOutputClusterCount; + VkDeviceSize indirectBufferOffsetAlignment; +} VkPhysicalDeviceClusterCullingShaderPropertiesHUAWEI; + +typedef struct VkPhysicalDeviceClusterCullingShaderVrsFeaturesHUAWEI { + VkStructureType sType; + void* pNext; + VkBool32 clusterShadingRate; +} VkPhysicalDeviceClusterCullingShaderVrsFeaturesHUAWEI; + +typedef void (VKAPI_PTR *PFN_vkCmdDrawClusterHUAWEI)(VkCommandBuffer commandBuffer, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ); +typedef void (VKAPI_PTR *PFN_vkCmdDrawClusterIndirectHUAWEI)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdDrawClusterHUAWEI( + VkCommandBuffer commandBuffer, + uint32_t groupCountX, + uint32_t groupCountY, + uint32_t groupCountZ); + +VKAPI_ATTR void VKAPI_CALL vkCmdDrawClusterIndirectHUAWEI( + VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset); +#endif + + +// VK_EXT_border_color_swizzle is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_border_color_swizzle 1 +#define VK_EXT_BORDER_COLOR_SWIZZLE_SPEC_VERSION 1 +#define VK_EXT_BORDER_COLOR_SWIZZLE_EXTENSION_NAME "VK_EXT_border_color_swizzle" +typedef struct VkPhysicalDeviceBorderColorSwizzleFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 borderColorSwizzle; + VkBool32 borderColorSwizzleFromImage; +} VkPhysicalDeviceBorderColorSwizzleFeaturesEXT; + +typedef struct VkSamplerBorderColorComponentMappingCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkComponentMapping components; + VkBool32 srgb; +} VkSamplerBorderColorComponentMappingCreateInfoEXT; + + + +// VK_EXT_pageable_device_local_memory is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_pageable_device_local_memory 1 +#define VK_EXT_PAGEABLE_DEVICE_LOCAL_MEMORY_SPEC_VERSION 1 +#define VK_EXT_PAGEABLE_DEVICE_LOCAL_MEMORY_EXTENSION_NAME "VK_EXT_pageable_device_local_memory" +typedef struct VkPhysicalDevicePageableDeviceLocalMemoryFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 pageableDeviceLocalMemory; +} VkPhysicalDevicePageableDeviceLocalMemoryFeaturesEXT; + +typedef void (VKAPI_PTR *PFN_vkSetDeviceMemoryPriorityEXT)(VkDevice device, VkDeviceMemory memory, float priority); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkSetDeviceMemoryPriorityEXT( + VkDevice device, + VkDeviceMemory memory, + float priority); +#endif + + +// VK_ARM_shader_core_properties is a preprocessor guard. Do not pass it to API calls. +#define VK_ARM_shader_core_properties 1 +#define VK_ARM_SHADER_CORE_PROPERTIES_SPEC_VERSION 1 +#define VK_ARM_SHADER_CORE_PROPERTIES_EXTENSION_NAME "VK_ARM_shader_core_properties" +typedef struct VkPhysicalDeviceShaderCorePropertiesARM { + VkStructureType sType; + void* pNext; + uint32_t pixelRate; + uint32_t texelRate; + uint32_t fmaRate; +} VkPhysicalDeviceShaderCorePropertiesARM; + + + +// VK_ARM_scheduling_controls is a preprocessor guard. Do not pass it to API calls. +#define VK_ARM_scheduling_controls 1 +#define VK_ARM_SCHEDULING_CONTROLS_SPEC_VERSION 1 +#define VK_ARM_SCHEDULING_CONTROLS_EXTENSION_NAME "VK_ARM_scheduling_controls" +typedef VkFlags64 VkPhysicalDeviceSchedulingControlsFlagsARM; + +// Flag bits for VkPhysicalDeviceSchedulingControlsFlagBitsARM +typedef VkFlags64 VkPhysicalDeviceSchedulingControlsFlagBitsARM; +static const VkPhysicalDeviceSchedulingControlsFlagBitsARM VK_PHYSICAL_DEVICE_SCHEDULING_CONTROLS_SHADER_CORE_COUNT_ARM = 0x00000001ULL; + +typedef struct VkDeviceQueueShaderCoreControlCreateInfoARM { + VkStructureType sType; + void* pNext; + uint32_t shaderCoreCount; +} VkDeviceQueueShaderCoreControlCreateInfoARM; + +typedef struct VkPhysicalDeviceSchedulingControlsFeaturesARM { + VkStructureType sType; + void* pNext; + VkBool32 schedulingControls; +} VkPhysicalDeviceSchedulingControlsFeaturesARM; + +typedef struct VkPhysicalDeviceSchedulingControlsPropertiesARM { + VkStructureType sType; + void* pNext; + VkPhysicalDeviceSchedulingControlsFlagsARM schedulingControlsFlags; +} VkPhysicalDeviceSchedulingControlsPropertiesARM; + + + +// VK_EXT_image_sliced_view_of_3d is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_image_sliced_view_of_3d 1 +#define VK_EXT_IMAGE_SLICED_VIEW_OF_3D_SPEC_VERSION 1 +#define VK_EXT_IMAGE_SLICED_VIEW_OF_3D_EXTENSION_NAME "VK_EXT_image_sliced_view_of_3d" +#define VK_REMAINING_3D_SLICES_EXT (~0U) +typedef struct VkPhysicalDeviceImageSlicedViewOf3DFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 imageSlicedViewOf3D; +} VkPhysicalDeviceImageSlicedViewOf3DFeaturesEXT; + +typedef struct VkImageViewSlicedCreateInfoEXT { + VkStructureType sType; + const void* pNext; + uint32_t sliceOffset; + uint32_t sliceCount; +} VkImageViewSlicedCreateInfoEXT; + + + +// VK_VALVE_descriptor_set_host_mapping is a preprocessor guard. Do not pass it to API calls. +#define VK_VALVE_descriptor_set_host_mapping 1 +#define VK_VALVE_DESCRIPTOR_SET_HOST_MAPPING_SPEC_VERSION 1 +#define VK_VALVE_DESCRIPTOR_SET_HOST_MAPPING_EXTENSION_NAME "VK_VALVE_descriptor_set_host_mapping" +typedef struct VkPhysicalDeviceDescriptorSetHostMappingFeaturesVALVE { + VkStructureType sType; + void* pNext; + VkBool32 descriptorSetHostMapping; +} VkPhysicalDeviceDescriptorSetHostMappingFeaturesVALVE; + +typedef struct VkDescriptorSetBindingReferenceVALVE { + VkStructureType sType; + const void* pNext; + VkDescriptorSetLayout descriptorSetLayout; + uint32_t binding; +} VkDescriptorSetBindingReferenceVALVE; + +typedef struct VkDescriptorSetLayoutHostMappingInfoVALVE { + VkStructureType sType; + void* pNext; + size_t descriptorOffset; + uint32_t descriptorSize; +} VkDescriptorSetLayoutHostMappingInfoVALVE; + +typedef void (VKAPI_PTR *PFN_vkGetDescriptorSetLayoutHostMappingInfoVALVE)(VkDevice device, const VkDescriptorSetBindingReferenceVALVE* pBindingReference, VkDescriptorSetLayoutHostMappingInfoVALVE* pHostMapping); +typedef void (VKAPI_PTR *PFN_vkGetDescriptorSetHostMappingVALVE)(VkDevice device, VkDescriptorSet descriptorSet, void** ppData); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkGetDescriptorSetLayoutHostMappingInfoVALVE( + VkDevice device, + const VkDescriptorSetBindingReferenceVALVE* pBindingReference, + VkDescriptorSetLayoutHostMappingInfoVALVE* pHostMapping); + +VKAPI_ATTR void VKAPI_CALL vkGetDescriptorSetHostMappingVALVE( + VkDevice device, + VkDescriptorSet descriptorSet, + void** ppData); +#endif + + +// VK_EXT_depth_clamp_zero_one is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_depth_clamp_zero_one 1 +#define VK_EXT_DEPTH_CLAMP_ZERO_ONE_SPEC_VERSION 1 +#define VK_EXT_DEPTH_CLAMP_ZERO_ONE_EXTENSION_NAME "VK_EXT_depth_clamp_zero_one" +typedef struct VkPhysicalDeviceDepthClampZeroOneFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 depthClampZeroOne; +} VkPhysicalDeviceDepthClampZeroOneFeaturesEXT; + + + +// VK_EXT_non_seamless_cube_map is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_non_seamless_cube_map 1 +#define VK_EXT_NON_SEAMLESS_CUBE_MAP_SPEC_VERSION 1 +#define VK_EXT_NON_SEAMLESS_CUBE_MAP_EXTENSION_NAME "VK_EXT_non_seamless_cube_map" +typedef struct VkPhysicalDeviceNonSeamlessCubeMapFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 nonSeamlessCubeMap; +} VkPhysicalDeviceNonSeamlessCubeMapFeaturesEXT; + + + +// VK_ARM_render_pass_striped is a preprocessor guard. Do not pass it to API calls. +#define VK_ARM_render_pass_striped 1 +#define VK_ARM_RENDER_PASS_STRIPED_SPEC_VERSION 1 +#define VK_ARM_RENDER_PASS_STRIPED_EXTENSION_NAME "VK_ARM_render_pass_striped" +typedef struct VkPhysicalDeviceRenderPassStripedFeaturesARM { + VkStructureType sType; + void* pNext; + VkBool32 renderPassStriped; +} VkPhysicalDeviceRenderPassStripedFeaturesARM; + +typedef struct VkPhysicalDeviceRenderPassStripedPropertiesARM { + VkStructureType sType; + void* pNext; + VkExtent2D renderPassStripeGranularity; + uint32_t maxRenderPassStripes; +} VkPhysicalDeviceRenderPassStripedPropertiesARM; + +typedef struct VkRenderPassStripeInfoARM { + VkStructureType sType; + const void* pNext; + VkRect2D stripeArea; +} VkRenderPassStripeInfoARM; + +typedef struct VkRenderPassStripeBeginInfoARM { + VkStructureType sType; + const void* pNext; + uint32_t stripeInfoCount; + const VkRenderPassStripeInfoARM* pStripeInfos; +} VkRenderPassStripeBeginInfoARM; + +typedef struct VkRenderPassStripeSubmitInfoARM { + VkStructureType sType; + const void* pNext; + uint32_t stripeSemaphoreInfoCount; + const VkSemaphoreSubmitInfo* pStripeSemaphoreInfos; +} VkRenderPassStripeSubmitInfoARM; + + + +// VK_QCOM_fragment_density_map_offset is a preprocessor guard. Do not pass it to API calls. +#define VK_QCOM_fragment_density_map_offset 1 +#define VK_QCOM_FRAGMENT_DENSITY_MAP_OFFSET_SPEC_VERSION 1 +#define VK_QCOM_FRAGMENT_DENSITY_MAP_OFFSET_EXTENSION_NAME "VK_QCOM_fragment_density_map_offset" +typedef struct VkPhysicalDeviceFragmentDensityMapOffsetFeaturesQCOM { + VkStructureType sType; + void* pNext; + VkBool32 fragmentDensityMapOffset; +} VkPhysicalDeviceFragmentDensityMapOffsetFeaturesQCOM; + +typedef struct VkPhysicalDeviceFragmentDensityMapOffsetPropertiesQCOM { + VkStructureType sType; + void* pNext; + VkExtent2D fragmentDensityOffsetGranularity; +} VkPhysicalDeviceFragmentDensityMapOffsetPropertiesQCOM; + +typedef struct VkSubpassFragmentDensityMapOffsetEndInfoQCOM { + VkStructureType sType; + const void* pNext; + uint32_t fragmentDensityOffsetCount; + const VkOffset2D* pFragmentDensityOffsets; +} VkSubpassFragmentDensityMapOffsetEndInfoQCOM; + + + +// VK_NV_copy_memory_indirect is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_copy_memory_indirect 1 +#define VK_NV_COPY_MEMORY_INDIRECT_SPEC_VERSION 1 +#define VK_NV_COPY_MEMORY_INDIRECT_EXTENSION_NAME "VK_NV_copy_memory_indirect" +typedef struct VkCopyMemoryIndirectCommandNV { + VkDeviceAddress srcAddress; + VkDeviceAddress dstAddress; + VkDeviceSize size; +} VkCopyMemoryIndirectCommandNV; + +typedef struct VkCopyMemoryToImageIndirectCommandNV { + VkDeviceAddress srcAddress; + uint32_t bufferRowLength; + uint32_t bufferImageHeight; + VkImageSubresourceLayers imageSubresource; + VkOffset3D imageOffset; + VkExtent3D imageExtent; +} VkCopyMemoryToImageIndirectCommandNV; + +typedef struct VkPhysicalDeviceCopyMemoryIndirectFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 indirectCopy; +} VkPhysicalDeviceCopyMemoryIndirectFeaturesNV; + +typedef struct VkPhysicalDeviceCopyMemoryIndirectPropertiesNV { + VkStructureType sType; + void* pNext; + VkQueueFlags supportedQueues; +} VkPhysicalDeviceCopyMemoryIndirectPropertiesNV; + +typedef void (VKAPI_PTR *PFN_vkCmdCopyMemoryIndirectNV)(VkCommandBuffer commandBuffer, VkDeviceAddress copyBufferAddress, uint32_t copyCount, uint32_t stride); +typedef void (VKAPI_PTR *PFN_vkCmdCopyMemoryToImageIndirectNV)(VkCommandBuffer commandBuffer, VkDeviceAddress copyBufferAddress, uint32_t copyCount, uint32_t stride, VkImage dstImage, VkImageLayout dstImageLayout, const VkImageSubresourceLayers* pImageSubresources); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdCopyMemoryIndirectNV( + VkCommandBuffer commandBuffer, + VkDeviceAddress copyBufferAddress, + uint32_t copyCount, + uint32_t stride); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyMemoryToImageIndirectNV( + VkCommandBuffer commandBuffer, + VkDeviceAddress copyBufferAddress, + uint32_t copyCount, + uint32_t stride, + VkImage dstImage, + VkImageLayout dstImageLayout, + const VkImageSubresourceLayers* pImageSubresources); +#endif + + +// VK_NV_memory_decompression is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_memory_decompression 1 +#define VK_NV_MEMORY_DECOMPRESSION_SPEC_VERSION 1 +#define VK_NV_MEMORY_DECOMPRESSION_EXTENSION_NAME "VK_NV_memory_decompression" + +// Flag bits for VkMemoryDecompressionMethodFlagBitsNV +typedef VkFlags64 VkMemoryDecompressionMethodFlagBitsNV; +static const VkMemoryDecompressionMethodFlagBitsNV VK_MEMORY_DECOMPRESSION_METHOD_GDEFLATE_1_0_BIT_NV = 0x00000001ULL; + +typedef VkFlags64 VkMemoryDecompressionMethodFlagsNV; +typedef struct VkDecompressMemoryRegionNV { + VkDeviceAddress srcAddress; + VkDeviceAddress dstAddress; + VkDeviceSize compressedSize; + VkDeviceSize decompressedSize; + VkMemoryDecompressionMethodFlagsNV decompressionMethod; +} VkDecompressMemoryRegionNV; + +typedef struct VkPhysicalDeviceMemoryDecompressionFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 memoryDecompression; +} VkPhysicalDeviceMemoryDecompressionFeaturesNV; + +typedef struct VkPhysicalDeviceMemoryDecompressionPropertiesNV { + VkStructureType sType; + void* pNext; + VkMemoryDecompressionMethodFlagsNV decompressionMethods; + uint64_t maxDecompressionIndirectCount; +} VkPhysicalDeviceMemoryDecompressionPropertiesNV; + +typedef void (VKAPI_PTR *PFN_vkCmdDecompressMemoryNV)(VkCommandBuffer commandBuffer, uint32_t decompressRegionCount, const VkDecompressMemoryRegionNV* pDecompressMemoryRegions); +typedef void (VKAPI_PTR *PFN_vkCmdDecompressMemoryIndirectCountNV)(VkCommandBuffer commandBuffer, VkDeviceAddress indirectCommandsAddress, VkDeviceAddress indirectCommandsCountAddress, uint32_t stride); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdDecompressMemoryNV( + VkCommandBuffer commandBuffer, + uint32_t decompressRegionCount, + const VkDecompressMemoryRegionNV* pDecompressMemoryRegions); + +VKAPI_ATTR void VKAPI_CALL vkCmdDecompressMemoryIndirectCountNV( + VkCommandBuffer commandBuffer, + VkDeviceAddress indirectCommandsAddress, + VkDeviceAddress indirectCommandsCountAddress, + uint32_t stride); +#endif + + +// VK_NV_device_generated_commands_compute is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_device_generated_commands_compute 1 +#define VK_NV_DEVICE_GENERATED_COMMANDS_COMPUTE_SPEC_VERSION 2 +#define VK_NV_DEVICE_GENERATED_COMMANDS_COMPUTE_EXTENSION_NAME "VK_NV_device_generated_commands_compute" +typedef struct VkPhysicalDeviceDeviceGeneratedCommandsComputeFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 deviceGeneratedCompute; + VkBool32 deviceGeneratedComputePipelines; + VkBool32 deviceGeneratedComputeCaptureReplay; +} VkPhysicalDeviceDeviceGeneratedCommandsComputeFeaturesNV; + +typedef struct VkComputePipelineIndirectBufferInfoNV { + VkStructureType sType; + const void* pNext; + VkDeviceAddress deviceAddress; + VkDeviceSize size; + VkDeviceAddress pipelineDeviceAddressCaptureReplay; +} VkComputePipelineIndirectBufferInfoNV; + +typedef struct VkPipelineIndirectDeviceAddressInfoNV { + VkStructureType sType; + const void* pNext; + VkPipelineBindPoint pipelineBindPoint; + VkPipeline pipeline; +} VkPipelineIndirectDeviceAddressInfoNV; + +typedef struct VkBindPipelineIndirectCommandNV { + VkDeviceAddress pipelineAddress; +} VkBindPipelineIndirectCommandNV; + +typedef void (VKAPI_PTR *PFN_vkGetPipelineIndirectMemoryRequirementsNV)(VkDevice device, const VkComputePipelineCreateInfo* pCreateInfo, VkMemoryRequirements2* pMemoryRequirements); +typedef void (VKAPI_PTR *PFN_vkCmdUpdatePipelineIndirectBufferNV)(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline); +typedef VkDeviceAddress (VKAPI_PTR *PFN_vkGetPipelineIndirectDeviceAddressNV)(VkDevice device, const VkPipelineIndirectDeviceAddressInfoNV* pInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkGetPipelineIndirectMemoryRequirementsNV( + VkDevice device, + const VkComputePipelineCreateInfo* pCreateInfo, + VkMemoryRequirements2* pMemoryRequirements); + +VKAPI_ATTR void VKAPI_CALL vkCmdUpdatePipelineIndirectBufferNV( + VkCommandBuffer commandBuffer, + VkPipelineBindPoint pipelineBindPoint, + VkPipeline pipeline); + +VKAPI_ATTR VkDeviceAddress VKAPI_CALL vkGetPipelineIndirectDeviceAddressNV( + VkDevice device, + const VkPipelineIndirectDeviceAddressInfoNV* pInfo); +#endif + + +// VK_NV_linear_color_attachment is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_linear_color_attachment 1 +#define VK_NV_LINEAR_COLOR_ATTACHMENT_SPEC_VERSION 1 +#define VK_NV_LINEAR_COLOR_ATTACHMENT_EXTENSION_NAME "VK_NV_linear_color_attachment" +typedef struct VkPhysicalDeviceLinearColorAttachmentFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 linearColorAttachment; +} VkPhysicalDeviceLinearColorAttachmentFeaturesNV; + + + +// VK_GOOGLE_surfaceless_query is a preprocessor guard. Do not pass it to API calls. +#define VK_GOOGLE_surfaceless_query 1 +#define VK_GOOGLE_SURFACELESS_QUERY_SPEC_VERSION 2 +#define VK_GOOGLE_SURFACELESS_QUERY_EXTENSION_NAME "VK_GOOGLE_surfaceless_query" + + +// VK_EXT_image_compression_control_swapchain is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_image_compression_control_swapchain 1 +#define VK_EXT_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_SPEC_VERSION 1 +#define VK_EXT_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN_EXTENSION_NAME "VK_EXT_image_compression_control_swapchain" +typedef struct VkPhysicalDeviceImageCompressionControlSwapchainFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 imageCompressionControlSwapchain; +} VkPhysicalDeviceImageCompressionControlSwapchainFeaturesEXT; + + + +// VK_QCOM_image_processing is a preprocessor guard. Do not pass it to API calls. +#define VK_QCOM_image_processing 1 +#define VK_QCOM_IMAGE_PROCESSING_SPEC_VERSION 1 +#define VK_QCOM_IMAGE_PROCESSING_EXTENSION_NAME "VK_QCOM_image_processing" +typedef struct VkImageViewSampleWeightCreateInfoQCOM { + VkStructureType sType; + const void* pNext; + VkOffset2D filterCenter; + VkExtent2D filterSize; + uint32_t numPhases; +} VkImageViewSampleWeightCreateInfoQCOM; + +typedef struct VkPhysicalDeviceImageProcessingFeaturesQCOM { + VkStructureType sType; + void* pNext; + VkBool32 textureSampleWeighted; + VkBool32 textureBoxFilter; + VkBool32 textureBlockMatch; +} VkPhysicalDeviceImageProcessingFeaturesQCOM; + +typedef struct VkPhysicalDeviceImageProcessingPropertiesQCOM { + VkStructureType sType; + void* pNext; + uint32_t maxWeightFilterPhases; + VkExtent2D maxWeightFilterDimension; + VkExtent2D maxBlockMatchRegion; + VkExtent2D maxBoxFilterBlockSize; +} VkPhysicalDeviceImageProcessingPropertiesQCOM; + + + +// VK_EXT_nested_command_buffer is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_nested_command_buffer 1 +#define VK_EXT_NESTED_COMMAND_BUFFER_SPEC_VERSION 1 +#define VK_EXT_NESTED_COMMAND_BUFFER_EXTENSION_NAME "VK_EXT_nested_command_buffer" +typedef struct VkPhysicalDeviceNestedCommandBufferFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 nestedCommandBuffer; + VkBool32 nestedCommandBufferRendering; + VkBool32 nestedCommandBufferSimultaneousUse; +} VkPhysicalDeviceNestedCommandBufferFeaturesEXT; + +typedef struct VkPhysicalDeviceNestedCommandBufferPropertiesEXT { + VkStructureType sType; + void* pNext; + uint32_t maxCommandBufferNestingLevel; +} VkPhysicalDeviceNestedCommandBufferPropertiesEXT; + + + +// VK_EXT_external_memory_acquire_unmodified is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_external_memory_acquire_unmodified 1 +#define VK_EXT_EXTERNAL_MEMORY_ACQUIRE_UNMODIFIED_SPEC_VERSION 1 +#define VK_EXT_EXTERNAL_MEMORY_ACQUIRE_UNMODIFIED_EXTENSION_NAME "VK_EXT_external_memory_acquire_unmodified" +typedef struct VkExternalMemoryAcquireUnmodifiedEXT { + VkStructureType sType; + const void* pNext; + VkBool32 acquireUnmodifiedMemory; +} VkExternalMemoryAcquireUnmodifiedEXT; + + + +// VK_EXT_extended_dynamic_state3 is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_extended_dynamic_state3 1 +#define VK_EXT_EXTENDED_DYNAMIC_STATE_3_SPEC_VERSION 2 +#define VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME "VK_EXT_extended_dynamic_state3" +typedef struct VkPhysicalDeviceExtendedDynamicState3FeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 extendedDynamicState3TessellationDomainOrigin; + VkBool32 extendedDynamicState3DepthClampEnable; + VkBool32 extendedDynamicState3PolygonMode; + VkBool32 extendedDynamicState3RasterizationSamples; + VkBool32 extendedDynamicState3SampleMask; + VkBool32 extendedDynamicState3AlphaToCoverageEnable; + VkBool32 extendedDynamicState3AlphaToOneEnable; + VkBool32 extendedDynamicState3LogicOpEnable; + VkBool32 extendedDynamicState3ColorBlendEnable; + VkBool32 extendedDynamicState3ColorBlendEquation; + VkBool32 extendedDynamicState3ColorWriteMask; + VkBool32 extendedDynamicState3RasterizationStream; + VkBool32 extendedDynamicState3ConservativeRasterizationMode; + VkBool32 extendedDynamicState3ExtraPrimitiveOverestimationSize; + VkBool32 extendedDynamicState3DepthClipEnable; + VkBool32 extendedDynamicState3SampleLocationsEnable; + VkBool32 extendedDynamicState3ColorBlendAdvanced; + VkBool32 extendedDynamicState3ProvokingVertexMode; + VkBool32 extendedDynamicState3LineRasterizationMode; + VkBool32 extendedDynamicState3LineStippleEnable; + VkBool32 extendedDynamicState3DepthClipNegativeOneToOne; + VkBool32 extendedDynamicState3ViewportWScalingEnable; + VkBool32 extendedDynamicState3ViewportSwizzle; + VkBool32 extendedDynamicState3CoverageToColorEnable; + VkBool32 extendedDynamicState3CoverageToColorLocation; + VkBool32 extendedDynamicState3CoverageModulationMode; + VkBool32 extendedDynamicState3CoverageModulationTableEnable; + VkBool32 extendedDynamicState3CoverageModulationTable; + VkBool32 extendedDynamicState3CoverageReductionMode; + VkBool32 extendedDynamicState3RepresentativeFragmentTestEnable; + VkBool32 extendedDynamicState3ShadingRateImageEnable; +} VkPhysicalDeviceExtendedDynamicState3FeaturesEXT; + +typedef struct VkPhysicalDeviceExtendedDynamicState3PropertiesEXT { + VkStructureType sType; + void* pNext; + VkBool32 dynamicPrimitiveTopologyUnrestricted; +} VkPhysicalDeviceExtendedDynamicState3PropertiesEXT; + +typedef struct VkColorBlendEquationEXT { + VkBlendFactor srcColorBlendFactor; + VkBlendFactor dstColorBlendFactor; + VkBlendOp colorBlendOp; + VkBlendFactor srcAlphaBlendFactor; + VkBlendFactor dstAlphaBlendFactor; + VkBlendOp alphaBlendOp; +} VkColorBlendEquationEXT; + +typedef struct VkColorBlendAdvancedEXT { + VkBlendOp advancedBlendOp; + VkBool32 srcPremultiplied; + VkBool32 dstPremultiplied; + VkBlendOverlapEXT blendOverlap; + VkBool32 clampResults; +} VkColorBlendAdvancedEXT; + +typedef void (VKAPI_PTR *PFN_vkCmdSetTessellationDomainOriginEXT)(VkCommandBuffer commandBuffer, VkTessellationDomainOrigin domainOrigin); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthClampEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 depthClampEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetPolygonModeEXT)(VkCommandBuffer commandBuffer, VkPolygonMode polygonMode); +typedef void (VKAPI_PTR *PFN_vkCmdSetRasterizationSamplesEXT)(VkCommandBuffer commandBuffer, VkSampleCountFlagBits rasterizationSamples); +typedef void (VKAPI_PTR *PFN_vkCmdSetSampleMaskEXT)(VkCommandBuffer commandBuffer, VkSampleCountFlagBits samples, const VkSampleMask* pSampleMask); +typedef void (VKAPI_PTR *PFN_vkCmdSetAlphaToCoverageEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 alphaToCoverageEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetAlphaToOneEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 alphaToOneEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetLogicOpEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 logicOpEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetColorBlendEnableEXT)(VkCommandBuffer commandBuffer, uint32_t firstAttachment, uint32_t attachmentCount, const VkBool32* pColorBlendEnables); +typedef void (VKAPI_PTR *PFN_vkCmdSetColorBlendEquationEXT)(VkCommandBuffer commandBuffer, uint32_t firstAttachment, uint32_t attachmentCount, const VkColorBlendEquationEXT* pColorBlendEquations); +typedef void (VKAPI_PTR *PFN_vkCmdSetColorWriteMaskEXT)(VkCommandBuffer commandBuffer, uint32_t firstAttachment, uint32_t attachmentCount, const VkColorComponentFlags* pColorWriteMasks); +typedef void (VKAPI_PTR *PFN_vkCmdSetRasterizationStreamEXT)(VkCommandBuffer commandBuffer, uint32_t rasterizationStream); +typedef void (VKAPI_PTR *PFN_vkCmdSetConservativeRasterizationModeEXT)(VkCommandBuffer commandBuffer, VkConservativeRasterizationModeEXT conservativeRasterizationMode); +typedef void (VKAPI_PTR *PFN_vkCmdSetExtraPrimitiveOverestimationSizeEXT)(VkCommandBuffer commandBuffer, float extraPrimitiveOverestimationSize); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthClipEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 depthClipEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetSampleLocationsEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 sampleLocationsEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetColorBlendAdvancedEXT)(VkCommandBuffer commandBuffer, uint32_t firstAttachment, uint32_t attachmentCount, const VkColorBlendAdvancedEXT* pColorBlendAdvanced); +typedef void (VKAPI_PTR *PFN_vkCmdSetProvokingVertexModeEXT)(VkCommandBuffer commandBuffer, VkProvokingVertexModeEXT provokingVertexMode); +typedef void (VKAPI_PTR *PFN_vkCmdSetLineRasterizationModeEXT)(VkCommandBuffer commandBuffer, VkLineRasterizationModeEXT lineRasterizationMode); +typedef void (VKAPI_PTR *PFN_vkCmdSetLineStippleEnableEXT)(VkCommandBuffer commandBuffer, VkBool32 stippledLineEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetDepthClipNegativeOneToOneEXT)(VkCommandBuffer commandBuffer, VkBool32 negativeOneToOne); +typedef void (VKAPI_PTR *PFN_vkCmdSetViewportWScalingEnableNV)(VkCommandBuffer commandBuffer, VkBool32 viewportWScalingEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetViewportSwizzleNV)(VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount, const VkViewportSwizzleNV* pViewportSwizzles); +typedef void (VKAPI_PTR *PFN_vkCmdSetCoverageToColorEnableNV)(VkCommandBuffer commandBuffer, VkBool32 coverageToColorEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetCoverageToColorLocationNV)(VkCommandBuffer commandBuffer, uint32_t coverageToColorLocation); +typedef void (VKAPI_PTR *PFN_vkCmdSetCoverageModulationModeNV)(VkCommandBuffer commandBuffer, VkCoverageModulationModeNV coverageModulationMode); +typedef void (VKAPI_PTR *PFN_vkCmdSetCoverageModulationTableEnableNV)(VkCommandBuffer commandBuffer, VkBool32 coverageModulationTableEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetCoverageModulationTableNV)(VkCommandBuffer commandBuffer, uint32_t coverageModulationTableCount, const float* pCoverageModulationTable); +typedef void (VKAPI_PTR *PFN_vkCmdSetShadingRateImageEnableNV)(VkCommandBuffer commandBuffer, VkBool32 shadingRateImageEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetRepresentativeFragmentTestEnableNV)(VkCommandBuffer commandBuffer, VkBool32 representativeFragmentTestEnable); +typedef void (VKAPI_PTR *PFN_vkCmdSetCoverageReductionModeNV)(VkCommandBuffer commandBuffer, VkCoverageReductionModeNV coverageReductionMode); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdSetTessellationDomainOriginEXT( + VkCommandBuffer commandBuffer, + VkTessellationDomainOrigin domainOrigin); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthClampEnableEXT( + VkCommandBuffer commandBuffer, + VkBool32 depthClampEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetPolygonModeEXT( + VkCommandBuffer commandBuffer, + VkPolygonMode polygonMode); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetRasterizationSamplesEXT( + VkCommandBuffer commandBuffer, + VkSampleCountFlagBits rasterizationSamples); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetSampleMaskEXT( + VkCommandBuffer commandBuffer, + VkSampleCountFlagBits samples, + const VkSampleMask* pSampleMask); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetAlphaToCoverageEnableEXT( + VkCommandBuffer commandBuffer, + VkBool32 alphaToCoverageEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetAlphaToOneEnableEXT( + VkCommandBuffer commandBuffer, + VkBool32 alphaToOneEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetLogicOpEnableEXT( + VkCommandBuffer commandBuffer, + VkBool32 logicOpEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetColorBlendEnableEXT( + VkCommandBuffer commandBuffer, + uint32_t firstAttachment, + uint32_t attachmentCount, + const VkBool32* pColorBlendEnables); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetColorBlendEquationEXT( + VkCommandBuffer commandBuffer, + uint32_t firstAttachment, + uint32_t attachmentCount, + const VkColorBlendEquationEXT* pColorBlendEquations); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetColorWriteMaskEXT( + VkCommandBuffer commandBuffer, + uint32_t firstAttachment, + uint32_t attachmentCount, + const VkColorComponentFlags* pColorWriteMasks); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetRasterizationStreamEXT( + VkCommandBuffer commandBuffer, + uint32_t rasterizationStream); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetConservativeRasterizationModeEXT( + VkCommandBuffer commandBuffer, + VkConservativeRasterizationModeEXT conservativeRasterizationMode); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetExtraPrimitiveOverestimationSizeEXT( + VkCommandBuffer commandBuffer, + float extraPrimitiveOverestimationSize); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthClipEnableEXT( + VkCommandBuffer commandBuffer, + VkBool32 depthClipEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetSampleLocationsEnableEXT( + VkCommandBuffer commandBuffer, + VkBool32 sampleLocationsEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetColorBlendAdvancedEXT( + VkCommandBuffer commandBuffer, + uint32_t firstAttachment, + uint32_t attachmentCount, + const VkColorBlendAdvancedEXT* pColorBlendAdvanced); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetProvokingVertexModeEXT( + VkCommandBuffer commandBuffer, + VkProvokingVertexModeEXT provokingVertexMode); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetLineRasterizationModeEXT( + VkCommandBuffer commandBuffer, + VkLineRasterizationModeEXT lineRasterizationMode); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetLineStippleEnableEXT( + VkCommandBuffer commandBuffer, + VkBool32 stippledLineEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetDepthClipNegativeOneToOneEXT( + VkCommandBuffer commandBuffer, + VkBool32 negativeOneToOne); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetViewportWScalingEnableNV( + VkCommandBuffer commandBuffer, + VkBool32 viewportWScalingEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetViewportSwizzleNV( + VkCommandBuffer commandBuffer, + uint32_t firstViewport, + uint32_t viewportCount, + const VkViewportSwizzleNV* pViewportSwizzles); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetCoverageToColorEnableNV( + VkCommandBuffer commandBuffer, + VkBool32 coverageToColorEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetCoverageToColorLocationNV( + VkCommandBuffer commandBuffer, + uint32_t coverageToColorLocation); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetCoverageModulationModeNV( + VkCommandBuffer commandBuffer, + VkCoverageModulationModeNV coverageModulationMode); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetCoverageModulationTableEnableNV( + VkCommandBuffer commandBuffer, + VkBool32 coverageModulationTableEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetCoverageModulationTableNV( + VkCommandBuffer commandBuffer, + uint32_t coverageModulationTableCount, + const float* pCoverageModulationTable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetShadingRateImageEnableNV( + VkCommandBuffer commandBuffer, + VkBool32 shadingRateImageEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetRepresentativeFragmentTestEnableNV( + VkCommandBuffer commandBuffer, + VkBool32 representativeFragmentTestEnable); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetCoverageReductionModeNV( + VkCommandBuffer commandBuffer, + VkCoverageReductionModeNV coverageReductionMode); +#endif + + +// VK_EXT_subpass_merge_feedback is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_subpass_merge_feedback 1 +#define VK_EXT_SUBPASS_MERGE_FEEDBACK_SPEC_VERSION 2 +#define VK_EXT_SUBPASS_MERGE_FEEDBACK_EXTENSION_NAME "VK_EXT_subpass_merge_feedback" + +typedef enum VkSubpassMergeStatusEXT { + VK_SUBPASS_MERGE_STATUS_MERGED_EXT = 0, + VK_SUBPASS_MERGE_STATUS_DISALLOWED_EXT = 1, + VK_SUBPASS_MERGE_STATUS_NOT_MERGED_SIDE_EFFECTS_EXT = 2, + VK_SUBPASS_MERGE_STATUS_NOT_MERGED_SAMPLES_MISMATCH_EXT = 3, + VK_SUBPASS_MERGE_STATUS_NOT_MERGED_VIEWS_MISMATCH_EXT = 4, + VK_SUBPASS_MERGE_STATUS_NOT_MERGED_ALIASING_EXT = 5, + VK_SUBPASS_MERGE_STATUS_NOT_MERGED_DEPENDENCIES_EXT = 6, + VK_SUBPASS_MERGE_STATUS_NOT_MERGED_INCOMPATIBLE_INPUT_ATTACHMENT_EXT = 7, + VK_SUBPASS_MERGE_STATUS_NOT_MERGED_TOO_MANY_ATTACHMENTS_EXT = 8, + VK_SUBPASS_MERGE_STATUS_NOT_MERGED_INSUFFICIENT_STORAGE_EXT = 9, + VK_SUBPASS_MERGE_STATUS_NOT_MERGED_DEPTH_STENCIL_COUNT_EXT = 10, + VK_SUBPASS_MERGE_STATUS_NOT_MERGED_RESOLVE_ATTACHMENT_REUSE_EXT = 11, + VK_SUBPASS_MERGE_STATUS_NOT_MERGED_SINGLE_SUBPASS_EXT = 12, + VK_SUBPASS_MERGE_STATUS_NOT_MERGED_UNSPECIFIED_EXT = 13, + VK_SUBPASS_MERGE_STATUS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkSubpassMergeStatusEXT; +typedef struct VkPhysicalDeviceSubpassMergeFeedbackFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 subpassMergeFeedback; +} VkPhysicalDeviceSubpassMergeFeedbackFeaturesEXT; + +typedef struct VkRenderPassCreationControlEXT { + VkStructureType sType; + const void* pNext; + VkBool32 disallowMerging; +} VkRenderPassCreationControlEXT; + +typedef struct VkRenderPassCreationFeedbackInfoEXT { + uint32_t postMergeSubpassCount; +} VkRenderPassCreationFeedbackInfoEXT; + +typedef struct VkRenderPassCreationFeedbackCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkRenderPassCreationFeedbackInfoEXT* pRenderPassFeedback; +} VkRenderPassCreationFeedbackCreateInfoEXT; + +typedef struct VkRenderPassSubpassFeedbackInfoEXT { + VkSubpassMergeStatusEXT subpassMergeStatus; + char description[VK_MAX_DESCRIPTION_SIZE]; + uint32_t postMergeIndex; +} VkRenderPassSubpassFeedbackInfoEXT; + +typedef struct VkRenderPassSubpassFeedbackCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkRenderPassSubpassFeedbackInfoEXT* pSubpassFeedback; +} VkRenderPassSubpassFeedbackCreateInfoEXT; + + + +// VK_LUNARG_direct_driver_loading is a preprocessor guard. Do not pass it to API calls. +#define VK_LUNARG_direct_driver_loading 1 +#define VK_LUNARG_DIRECT_DRIVER_LOADING_SPEC_VERSION 1 +#define VK_LUNARG_DIRECT_DRIVER_LOADING_EXTENSION_NAME "VK_LUNARG_direct_driver_loading" + +typedef enum VkDirectDriverLoadingModeLUNARG { + VK_DIRECT_DRIVER_LOADING_MODE_EXCLUSIVE_LUNARG = 0, + VK_DIRECT_DRIVER_LOADING_MODE_INCLUSIVE_LUNARG = 1, + VK_DIRECT_DRIVER_LOADING_MODE_MAX_ENUM_LUNARG = 0x7FFFFFFF +} VkDirectDriverLoadingModeLUNARG; +typedef VkFlags VkDirectDriverLoadingFlagsLUNARG; +typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_vkGetInstanceProcAddrLUNARG)( + VkInstance instance, const char* pName); + +typedef struct VkDirectDriverLoadingInfoLUNARG { + VkStructureType sType; + void* pNext; + VkDirectDriverLoadingFlagsLUNARG flags; + PFN_vkGetInstanceProcAddrLUNARG pfnGetInstanceProcAddr; +} VkDirectDriverLoadingInfoLUNARG; + +typedef struct VkDirectDriverLoadingListLUNARG { + VkStructureType sType; + const void* pNext; + VkDirectDriverLoadingModeLUNARG mode; + uint32_t driverCount; + const VkDirectDriverLoadingInfoLUNARG* pDrivers; +} VkDirectDriverLoadingListLUNARG; + + + +// VK_EXT_shader_module_identifier is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_shader_module_identifier 1 +#define VK_MAX_SHADER_MODULE_IDENTIFIER_SIZE_EXT 32U +#define VK_EXT_SHADER_MODULE_IDENTIFIER_SPEC_VERSION 1 +#define VK_EXT_SHADER_MODULE_IDENTIFIER_EXTENSION_NAME "VK_EXT_shader_module_identifier" +typedef struct VkPhysicalDeviceShaderModuleIdentifierFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 shaderModuleIdentifier; +} VkPhysicalDeviceShaderModuleIdentifierFeaturesEXT; + +typedef struct VkPhysicalDeviceShaderModuleIdentifierPropertiesEXT { + VkStructureType sType; + void* pNext; + uint8_t shaderModuleIdentifierAlgorithmUUID[VK_UUID_SIZE]; +} VkPhysicalDeviceShaderModuleIdentifierPropertiesEXT; + +typedef struct VkPipelineShaderStageModuleIdentifierCreateInfoEXT { + VkStructureType sType; + const void* pNext; + uint32_t identifierSize; + const uint8_t* pIdentifier; +} VkPipelineShaderStageModuleIdentifierCreateInfoEXT; + +typedef struct VkShaderModuleIdentifierEXT { + VkStructureType sType; + void* pNext; + uint32_t identifierSize; + uint8_t identifier[VK_MAX_SHADER_MODULE_IDENTIFIER_SIZE_EXT]; +} VkShaderModuleIdentifierEXT; + +typedef void (VKAPI_PTR *PFN_vkGetShaderModuleIdentifierEXT)(VkDevice device, VkShaderModule shaderModule, VkShaderModuleIdentifierEXT* pIdentifier); +typedef void (VKAPI_PTR *PFN_vkGetShaderModuleCreateInfoIdentifierEXT)(VkDevice device, const VkShaderModuleCreateInfo* pCreateInfo, VkShaderModuleIdentifierEXT* pIdentifier); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkGetShaderModuleIdentifierEXT( + VkDevice device, + VkShaderModule shaderModule, + VkShaderModuleIdentifierEXT* pIdentifier); + +VKAPI_ATTR void VKAPI_CALL vkGetShaderModuleCreateInfoIdentifierEXT( + VkDevice device, + const VkShaderModuleCreateInfo* pCreateInfo, + VkShaderModuleIdentifierEXT* pIdentifier); +#endif + + +// VK_EXT_rasterization_order_attachment_access is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_rasterization_order_attachment_access 1 +#define VK_EXT_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_SPEC_VERSION 1 +#define VK_EXT_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_EXTENSION_NAME "VK_EXT_rasterization_order_attachment_access" + + +// VK_NV_optical_flow is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_optical_flow 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkOpticalFlowSessionNV) +#define VK_NV_OPTICAL_FLOW_SPEC_VERSION 1 +#define VK_NV_OPTICAL_FLOW_EXTENSION_NAME "VK_NV_optical_flow" + +typedef enum VkOpticalFlowPerformanceLevelNV { + VK_OPTICAL_FLOW_PERFORMANCE_LEVEL_UNKNOWN_NV = 0, + VK_OPTICAL_FLOW_PERFORMANCE_LEVEL_SLOW_NV = 1, + VK_OPTICAL_FLOW_PERFORMANCE_LEVEL_MEDIUM_NV = 2, + VK_OPTICAL_FLOW_PERFORMANCE_LEVEL_FAST_NV = 3, + VK_OPTICAL_FLOW_PERFORMANCE_LEVEL_MAX_ENUM_NV = 0x7FFFFFFF +} VkOpticalFlowPerformanceLevelNV; + +typedef enum VkOpticalFlowSessionBindingPointNV { + VK_OPTICAL_FLOW_SESSION_BINDING_POINT_UNKNOWN_NV = 0, + VK_OPTICAL_FLOW_SESSION_BINDING_POINT_INPUT_NV = 1, + VK_OPTICAL_FLOW_SESSION_BINDING_POINT_REFERENCE_NV = 2, + VK_OPTICAL_FLOW_SESSION_BINDING_POINT_HINT_NV = 3, + VK_OPTICAL_FLOW_SESSION_BINDING_POINT_FLOW_VECTOR_NV = 4, + VK_OPTICAL_FLOW_SESSION_BINDING_POINT_BACKWARD_FLOW_VECTOR_NV = 5, + VK_OPTICAL_FLOW_SESSION_BINDING_POINT_COST_NV = 6, + VK_OPTICAL_FLOW_SESSION_BINDING_POINT_BACKWARD_COST_NV = 7, + VK_OPTICAL_FLOW_SESSION_BINDING_POINT_GLOBAL_FLOW_NV = 8, + VK_OPTICAL_FLOW_SESSION_BINDING_POINT_MAX_ENUM_NV = 0x7FFFFFFF +} VkOpticalFlowSessionBindingPointNV; + +typedef enum VkOpticalFlowGridSizeFlagBitsNV { + VK_OPTICAL_FLOW_GRID_SIZE_UNKNOWN_NV = 0, + VK_OPTICAL_FLOW_GRID_SIZE_1X1_BIT_NV = 0x00000001, + VK_OPTICAL_FLOW_GRID_SIZE_2X2_BIT_NV = 0x00000002, + VK_OPTICAL_FLOW_GRID_SIZE_4X4_BIT_NV = 0x00000004, + VK_OPTICAL_FLOW_GRID_SIZE_8X8_BIT_NV = 0x00000008, + VK_OPTICAL_FLOW_GRID_SIZE_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF +} VkOpticalFlowGridSizeFlagBitsNV; +typedef VkFlags VkOpticalFlowGridSizeFlagsNV; + +typedef enum VkOpticalFlowUsageFlagBitsNV { + VK_OPTICAL_FLOW_USAGE_UNKNOWN_NV = 0, + VK_OPTICAL_FLOW_USAGE_INPUT_BIT_NV = 0x00000001, + VK_OPTICAL_FLOW_USAGE_OUTPUT_BIT_NV = 0x00000002, + VK_OPTICAL_FLOW_USAGE_HINT_BIT_NV = 0x00000004, + VK_OPTICAL_FLOW_USAGE_COST_BIT_NV = 0x00000008, + VK_OPTICAL_FLOW_USAGE_GLOBAL_FLOW_BIT_NV = 0x00000010, + VK_OPTICAL_FLOW_USAGE_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF +} VkOpticalFlowUsageFlagBitsNV; +typedef VkFlags VkOpticalFlowUsageFlagsNV; + +typedef enum VkOpticalFlowSessionCreateFlagBitsNV { + VK_OPTICAL_FLOW_SESSION_CREATE_ENABLE_HINT_BIT_NV = 0x00000001, + VK_OPTICAL_FLOW_SESSION_CREATE_ENABLE_COST_BIT_NV = 0x00000002, + VK_OPTICAL_FLOW_SESSION_CREATE_ENABLE_GLOBAL_FLOW_BIT_NV = 0x00000004, + VK_OPTICAL_FLOW_SESSION_CREATE_ALLOW_REGIONS_BIT_NV = 0x00000008, + VK_OPTICAL_FLOW_SESSION_CREATE_BOTH_DIRECTIONS_BIT_NV = 0x00000010, + VK_OPTICAL_FLOW_SESSION_CREATE_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF +} VkOpticalFlowSessionCreateFlagBitsNV; +typedef VkFlags VkOpticalFlowSessionCreateFlagsNV; + +typedef enum VkOpticalFlowExecuteFlagBitsNV { + VK_OPTICAL_FLOW_EXECUTE_DISABLE_TEMPORAL_HINTS_BIT_NV = 0x00000001, + VK_OPTICAL_FLOW_EXECUTE_FLAG_BITS_MAX_ENUM_NV = 0x7FFFFFFF +} VkOpticalFlowExecuteFlagBitsNV; +typedef VkFlags VkOpticalFlowExecuteFlagsNV; +typedef struct VkPhysicalDeviceOpticalFlowFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 opticalFlow; +} VkPhysicalDeviceOpticalFlowFeaturesNV; + +typedef struct VkPhysicalDeviceOpticalFlowPropertiesNV { + VkStructureType sType; + void* pNext; + VkOpticalFlowGridSizeFlagsNV supportedOutputGridSizes; + VkOpticalFlowGridSizeFlagsNV supportedHintGridSizes; + VkBool32 hintSupported; + VkBool32 costSupported; + VkBool32 bidirectionalFlowSupported; + VkBool32 globalFlowSupported; + uint32_t minWidth; + uint32_t minHeight; + uint32_t maxWidth; + uint32_t maxHeight; + uint32_t maxNumRegionsOfInterest; +} VkPhysicalDeviceOpticalFlowPropertiesNV; + +typedef struct VkOpticalFlowImageFormatInfoNV { + VkStructureType sType; + const void* pNext; + VkOpticalFlowUsageFlagsNV usage; +} VkOpticalFlowImageFormatInfoNV; + +typedef struct VkOpticalFlowImageFormatPropertiesNV { + VkStructureType sType; + const void* pNext; + VkFormat format; +} VkOpticalFlowImageFormatPropertiesNV; + +typedef struct VkOpticalFlowSessionCreateInfoNV { + VkStructureType sType; + void* pNext; + uint32_t width; + uint32_t height; + VkFormat imageFormat; + VkFormat flowVectorFormat; + VkFormat costFormat; + VkOpticalFlowGridSizeFlagsNV outputGridSize; + VkOpticalFlowGridSizeFlagsNV hintGridSize; + VkOpticalFlowPerformanceLevelNV performanceLevel; + VkOpticalFlowSessionCreateFlagsNV flags; +} VkOpticalFlowSessionCreateInfoNV; + +typedef struct VkOpticalFlowSessionCreatePrivateDataInfoNV { + VkStructureType sType; + void* pNext; + uint32_t id; + uint32_t size; + const void* pPrivateData; +} VkOpticalFlowSessionCreatePrivateDataInfoNV; + +typedef struct VkOpticalFlowExecuteInfoNV { + VkStructureType sType; + void* pNext; + VkOpticalFlowExecuteFlagsNV flags; + uint32_t regionCount; + const VkRect2D* pRegions; +} VkOpticalFlowExecuteInfoNV; + +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceOpticalFlowImageFormatsNV)(VkPhysicalDevice physicalDevice, const VkOpticalFlowImageFormatInfoNV* pOpticalFlowImageFormatInfo, uint32_t* pFormatCount, VkOpticalFlowImageFormatPropertiesNV* pImageFormatProperties); +typedef VkResult (VKAPI_PTR *PFN_vkCreateOpticalFlowSessionNV)(VkDevice device, const VkOpticalFlowSessionCreateInfoNV* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkOpticalFlowSessionNV* pSession); +typedef void (VKAPI_PTR *PFN_vkDestroyOpticalFlowSessionNV)(VkDevice device, VkOpticalFlowSessionNV session, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkBindOpticalFlowSessionImageNV)(VkDevice device, VkOpticalFlowSessionNV session, VkOpticalFlowSessionBindingPointNV bindingPoint, VkImageView view, VkImageLayout layout); +typedef void (VKAPI_PTR *PFN_vkCmdOpticalFlowExecuteNV)(VkCommandBuffer commandBuffer, VkOpticalFlowSessionNV session, const VkOpticalFlowExecuteInfoNV* pExecuteInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceOpticalFlowImageFormatsNV( + VkPhysicalDevice physicalDevice, + const VkOpticalFlowImageFormatInfoNV* pOpticalFlowImageFormatInfo, + uint32_t* pFormatCount, + VkOpticalFlowImageFormatPropertiesNV* pImageFormatProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateOpticalFlowSessionNV( + VkDevice device, + const VkOpticalFlowSessionCreateInfoNV* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkOpticalFlowSessionNV* pSession); + +VKAPI_ATTR void VKAPI_CALL vkDestroyOpticalFlowSessionNV( + VkDevice device, + VkOpticalFlowSessionNV session, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkBindOpticalFlowSessionImageNV( + VkDevice device, + VkOpticalFlowSessionNV session, + VkOpticalFlowSessionBindingPointNV bindingPoint, + VkImageView view, + VkImageLayout layout); + +VKAPI_ATTR void VKAPI_CALL vkCmdOpticalFlowExecuteNV( + VkCommandBuffer commandBuffer, + VkOpticalFlowSessionNV session, + const VkOpticalFlowExecuteInfoNV* pExecuteInfo); +#endif + + +// VK_EXT_legacy_dithering is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_legacy_dithering 1 +#define VK_EXT_LEGACY_DITHERING_SPEC_VERSION 1 +#define VK_EXT_LEGACY_DITHERING_EXTENSION_NAME "VK_EXT_legacy_dithering" +typedef struct VkPhysicalDeviceLegacyDitheringFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 legacyDithering; +} VkPhysicalDeviceLegacyDitheringFeaturesEXT; + + + +// VK_EXT_pipeline_protected_access is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_pipeline_protected_access 1 +#define VK_EXT_PIPELINE_PROTECTED_ACCESS_SPEC_VERSION 1 +#define VK_EXT_PIPELINE_PROTECTED_ACCESS_EXTENSION_NAME "VK_EXT_pipeline_protected_access" +typedef struct VkPhysicalDevicePipelineProtectedAccessFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 pipelineProtectedAccess; +} VkPhysicalDevicePipelineProtectedAccessFeaturesEXT; + + + +// VK_EXT_shader_object is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_shader_object 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkShaderEXT) +#define VK_EXT_SHADER_OBJECT_SPEC_VERSION 1 +#define VK_EXT_SHADER_OBJECT_EXTENSION_NAME "VK_EXT_shader_object" + +typedef enum VkShaderCodeTypeEXT { + VK_SHADER_CODE_TYPE_BINARY_EXT = 0, + VK_SHADER_CODE_TYPE_SPIRV_EXT = 1, + VK_SHADER_CODE_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF +} VkShaderCodeTypeEXT; + +typedef enum VkShaderCreateFlagBitsEXT { + VK_SHADER_CREATE_LINK_STAGE_BIT_EXT = 0x00000001, + VK_SHADER_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT_EXT = 0x00000002, + VK_SHADER_CREATE_REQUIRE_FULL_SUBGROUPS_BIT_EXT = 0x00000004, + VK_SHADER_CREATE_NO_TASK_SHADER_BIT_EXT = 0x00000008, + VK_SHADER_CREATE_DISPATCH_BASE_BIT_EXT = 0x00000010, + VK_SHADER_CREATE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_EXT = 0x00000020, + VK_SHADER_CREATE_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT = 0x00000040, + VK_SHADER_CREATE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkShaderCreateFlagBitsEXT; +typedef VkFlags VkShaderCreateFlagsEXT; +typedef struct VkPhysicalDeviceShaderObjectFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 shaderObject; +} VkPhysicalDeviceShaderObjectFeaturesEXT; + +typedef struct VkPhysicalDeviceShaderObjectPropertiesEXT { + VkStructureType sType; + void* pNext; + uint8_t shaderBinaryUUID[VK_UUID_SIZE]; + uint32_t shaderBinaryVersion; +} VkPhysicalDeviceShaderObjectPropertiesEXT; + +typedef struct VkShaderCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkShaderCreateFlagsEXT flags; + VkShaderStageFlagBits stage; + VkShaderStageFlags nextStage; + VkShaderCodeTypeEXT codeType; + size_t codeSize; + const void* pCode; + const char* pName; + uint32_t setLayoutCount; + const VkDescriptorSetLayout* pSetLayouts; + uint32_t pushConstantRangeCount; + const VkPushConstantRange* pPushConstantRanges; + const VkSpecializationInfo* pSpecializationInfo; +} VkShaderCreateInfoEXT; + +typedef VkPipelineShaderStageRequiredSubgroupSizeCreateInfo VkShaderRequiredSubgroupSizeCreateInfoEXT; + +typedef VkResult (VKAPI_PTR *PFN_vkCreateShadersEXT)(VkDevice device, uint32_t createInfoCount, const VkShaderCreateInfoEXT* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkShaderEXT* pShaders); +typedef void (VKAPI_PTR *PFN_vkDestroyShaderEXT)(VkDevice device, VkShaderEXT shader, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkGetShaderBinaryDataEXT)(VkDevice device, VkShaderEXT shader, size_t* pDataSize, void* pData); +typedef void (VKAPI_PTR *PFN_vkCmdBindShadersEXT)(VkCommandBuffer commandBuffer, uint32_t stageCount, const VkShaderStageFlagBits* pStages, const VkShaderEXT* pShaders); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateShadersEXT( + VkDevice device, + uint32_t createInfoCount, + const VkShaderCreateInfoEXT* pCreateInfos, + const VkAllocationCallbacks* pAllocator, + VkShaderEXT* pShaders); + +VKAPI_ATTR void VKAPI_CALL vkDestroyShaderEXT( + VkDevice device, + VkShaderEXT shader, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetShaderBinaryDataEXT( + VkDevice device, + VkShaderEXT shader, + size_t* pDataSize, + void* pData); + +VKAPI_ATTR void VKAPI_CALL vkCmdBindShadersEXT( + VkCommandBuffer commandBuffer, + uint32_t stageCount, + const VkShaderStageFlagBits* pStages, + const VkShaderEXT* pShaders); +#endif + + +// VK_QCOM_tile_properties is a preprocessor guard. Do not pass it to API calls. +#define VK_QCOM_tile_properties 1 +#define VK_QCOM_TILE_PROPERTIES_SPEC_VERSION 1 +#define VK_QCOM_TILE_PROPERTIES_EXTENSION_NAME "VK_QCOM_tile_properties" +typedef struct VkPhysicalDeviceTilePropertiesFeaturesQCOM { + VkStructureType sType; + void* pNext; + VkBool32 tileProperties; +} VkPhysicalDeviceTilePropertiesFeaturesQCOM; + +typedef struct VkTilePropertiesQCOM { + VkStructureType sType; + void* pNext; + VkExtent3D tileSize; + VkExtent2D apronSize; + VkOffset2D origin; +} VkTilePropertiesQCOM; + +typedef VkResult (VKAPI_PTR *PFN_vkGetFramebufferTilePropertiesQCOM)(VkDevice device, VkFramebuffer framebuffer, uint32_t* pPropertiesCount, VkTilePropertiesQCOM* pProperties); +typedef VkResult (VKAPI_PTR *PFN_vkGetDynamicRenderingTilePropertiesQCOM)(VkDevice device, const VkRenderingInfo* pRenderingInfo, VkTilePropertiesQCOM* pProperties); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetFramebufferTilePropertiesQCOM( + VkDevice device, + VkFramebuffer framebuffer, + uint32_t* pPropertiesCount, + VkTilePropertiesQCOM* pProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetDynamicRenderingTilePropertiesQCOM( + VkDevice device, + const VkRenderingInfo* pRenderingInfo, + VkTilePropertiesQCOM* pProperties); +#endif + + +// VK_SEC_amigo_profiling is a preprocessor guard. Do not pass it to API calls. +#define VK_SEC_amigo_profiling 1 +#define VK_SEC_AMIGO_PROFILING_SPEC_VERSION 1 +#define VK_SEC_AMIGO_PROFILING_EXTENSION_NAME "VK_SEC_amigo_profiling" +typedef struct VkPhysicalDeviceAmigoProfilingFeaturesSEC { + VkStructureType sType; + void* pNext; + VkBool32 amigoProfiling; +} VkPhysicalDeviceAmigoProfilingFeaturesSEC; + +typedef struct VkAmigoProfilingSubmitInfoSEC { + VkStructureType sType; + const void* pNext; + uint64_t firstDrawTimestamp; + uint64_t swapBufferTimestamp; +} VkAmigoProfilingSubmitInfoSEC; + + + +// VK_QCOM_multiview_per_view_viewports is a preprocessor guard. Do not pass it to API calls. +#define VK_QCOM_multiview_per_view_viewports 1 +#define VK_QCOM_MULTIVIEW_PER_VIEW_VIEWPORTS_SPEC_VERSION 1 +#define VK_QCOM_MULTIVIEW_PER_VIEW_VIEWPORTS_EXTENSION_NAME "VK_QCOM_multiview_per_view_viewports" +typedef struct VkPhysicalDeviceMultiviewPerViewViewportsFeaturesQCOM { + VkStructureType sType; + void* pNext; + VkBool32 multiviewPerViewViewports; +} VkPhysicalDeviceMultiviewPerViewViewportsFeaturesQCOM; + + + +// VK_NV_ray_tracing_invocation_reorder is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_ray_tracing_invocation_reorder 1 +#define VK_NV_RAY_TRACING_INVOCATION_REORDER_SPEC_VERSION 1 +#define VK_NV_RAY_TRACING_INVOCATION_REORDER_EXTENSION_NAME "VK_NV_ray_tracing_invocation_reorder" + +typedef enum VkRayTracingInvocationReorderModeNV { + VK_RAY_TRACING_INVOCATION_REORDER_MODE_NONE_NV = 0, + VK_RAY_TRACING_INVOCATION_REORDER_MODE_REORDER_NV = 1, + VK_RAY_TRACING_INVOCATION_REORDER_MODE_MAX_ENUM_NV = 0x7FFFFFFF +} VkRayTracingInvocationReorderModeNV; +typedef struct VkPhysicalDeviceRayTracingInvocationReorderPropertiesNV { + VkStructureType sType; + void* pNext; + VkRayTracingInvocationReorderModeNV rayTracingInvocationReorderReorderingHint; +} VkPhysicalDeviceRayTracingInvocationReorderPropertiesNV; + +typedef struct VkPhysicalDeviceRayTracingInvocationReorderFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 rayTracingInvocationReorder; +} VkPhysicalDeviceRayTracingInvocationReorderFeaturesNV; + + + +// VK_NV_extended_sparse_address_space is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_extended_sparse_address_space 1 +#define VK_NV_EXTENDED_SPARSE_ADDRESS_SPACE_SPEC_VERSION 1 +#define VK_NV_EXTENDED_SPARSE_ADDRESS_SPACE_EXTENSION_NAME "VK_NV_extended_sparse_address_space" +typedef struct VkPhysicalDeviceExtendedSparseAddressSpaceFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 extendedSparseAddressSpace; +} VkPhysicalDeviceExtendedSparseAddressSpaceFeaturesNV; + +typedef struct VkPhysicalDeviceExtendedSparseAddressSpacePropertiesNV { + VkStructureType sType; + void* pNext; + VkDeviceSize extendedSparseAddressSpaceSize; + VkImageUsageFlags extendedSparseImageUsageFlags; + VkBufferUsageFlags extendedSparseBufferUsageFlags; +} VkPhysicalDeviceExtendedSparseAddressSpacePropertiesNV; + + + +// VK_EXT_mutable_descriptor_type is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_mutable_descriptor_type 1 +#define VK_EXT_MUTABLE_DESCRIPTOR_TYPE_SPEC_VERSION 1 +#define VK_EXT_MUTABLE_DESCRIPTOR_TYPE_EXTENSION_NAME "VK_EXT_mutable_descriptor_type" + + +// VK_EXT_layer_settings is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_layer_settings 1 +#define VK_EXT_LAYER_SETTINGS_SPEC_VERSION 2 +#define VK_EXT_LAYER_SETTINGS_EXTENSION_NAME "VK_EXT_layer_settings" + +typedef enum VkLayerSettingTypeEXT { + VK_LAYER_SETTING_TYPE_BOOL32_EXT = 0, + VK_LAYER_SETTING_TYPE_INT32_EXT = 1, + VK_LAYER_SETTING_TYPE_INT64_EXT = 2, + VK_LAYER_SETTING_TYPE_UINT32_EXT = 3, + VK_LAYER_SETTING_TYPE_UINT64_EXT = 4, + VK_LAYER_SETTING_TYPE_FLOAT32_EXT = 5, + VK_LAYER_SETTING_TYPE_FLOAT64_EXT = 6, + VK_LAYER_SETTING_TYPE_STRING_EXT = 7, + VK_LAYER_SETTING_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF +} VkLayerSettingTypeEXT; +typedef struct VkLayerSettingEXT { + const char* pLayerName; + const char* pSettingName; + VkLayerSettingTypeEXT type; + uint32_t valueCount; + const void* pValues; +} VkLayerSettingEXT; + +typedef struct VkLayerSettingsCreateInfoEXT { + VkStructureType sType; + const void* pNext; + uint32_t settingCount; + const VkLayerSettingEXT* pSettings; +} VkLayerSettingsCreateInfoEXT; + + + +// VK_ARM_shader_core_builtins is a preprocessor guard. Do not pass it to API calls. +#define VK_ARM_shader_core_builtins 1 +#define VK_ARM_SHADER_CORE_BUILTINS_SPEC_VERSION 2 +#define VK_ARM_SHADER_CORE_BUILTINS_EXTENSION_NAME "VK_ARM_shader_core_builtins" +typedef struct VkPhysicalDeviceShaderCoreBuiltinsFeaturesARM { + VkStructureType sType; + void* pNext; + VkBool32 shaderCoreBuiltins; +} VkPhysicalDeviceShaderCoreBuiltinsFeaturesARM; + +typedef struct VkPhysicalDeviceShaderCoreBuiltinsPropertiesARM { + VkStructureType sType; + void* pNext; + uint64_t shaderCoreMask; + uint32_t shaderCoreCount; + uint32_t shaderWarpsPerCore; +} VkPhysicalDeviceShaderCoreBuiltinsPropertiesARM; + + + +// VK_EXT_pipeline_library_group_handles is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_pipeline_library_group_handles 1 +#define VK_EXT_PIPELINE_LIBRARY_GROUP_HANDLES_SPEC_VERSION 1 +#define VK_EXT_PIPELINE_LIBRARY_GROUP_HANDLES_EXTENSION_NAME "VK_EXT_pipeline_library_group_handles" +typedef struct VkPhysicalDevicePipelineLibraryGroupHandlesFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 pipelineLibraryGroupHandles; +} VkPhysicalDevicePipelineLibraryGroupHandlesFeaturesEXT; + + + +// VK_EXT_dynamic_rendering_unused_attachments is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_dynamic_rendering_unused_attachments 1 +#define VK_EXT_DYNAMIC_RENDERING_UNUSED_ATTACHMENTS_SPEC_VERSION 1 +#define VK_EXT_DYNAMIC_RENDERING_UNUSED_ATTACHMENTS_EXTENSION_NAME "VK_EXT_dynamic_rendering_unused_attachments" +typedef struct VkPhysicalDeviceDynamicRenderingUnusedAttachmentsFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 dynamicRenderingUnusedAttachments; +} VkPhysicalDeviceDynamicRenderingUnusedAttachmentsFeaturesEXT; + + + +// VK_NV_low_latency2 is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_low_latency2 1 +#define VK_NV_LOW_LATENCY_2_SPEC_VERSION 2 +#define VK_NV_LOW_LATENCY_2_EXTENSION_NAME "VK_NV_low_latency2" + +typedef enum VkLatencyMarkerNV { + VK_LATENCY_MARKER_SIMULATION_START_NV = 0, + VK_LATENCY_MARKER_SIMULATION_END_NV = 1, + VK_LATENCY_MARKER_RENDERSUBMIT_START_NV = 2, + VK_LATENCY_MARKER_RENDERSUBMIT_END_NV = 3, + VK_LATENCY_MARKER_PRESENT_START_NV = 4, + VK_LATENCY_MARKER_PRESENT_END_NV = 5, + VK_LATENCY_MARKER_INPUT_SAMPLE_NV = 6, + VK_LATENCY_MARKER_TRIGGER_FLASH_NV = 7, + VK_LATENCY_MARKER_OUT_OF_BAND_RENDERSUBMIT_START_NV = 8, + VK_LATENCY_MARKER_OUT_OF_BAND_RENDERSUBMIT_END_NV = 9, + VK_LATENCY_MARKER_OUT_OF_BAND_PRESENT_START_NV = 10, + VK_LATENCY_MARKER_OUT_OF_BAND_PRESENT_END_NV = 11, + VK_LATENCY_MARKER_MAX_ENUM_NV = 0x7FFFFFFF +} VkLatencyMarkerNV; + +typedef enum VkOutOfBandQueueTypeNV { + VK_OUT_OF_BAND_QUEUE_TYPE_RENDER_NV = 0, + VK_OUT_OF_BAND_QUEUE_TYPE_PRESENT_NV = 1, + VK_OUT_OF_BAND_QUEUE_TYPE_MAX_ENUM_NV = 0x7FFFFFFF +} VkOutOfBandQueueTypeNV; +typedef struct VkLatencySleepModeInfoNV { + VkStructureType sType; + const void* pNext; + VkBool32 lowLatencyMode; + VkBool32 lowLatencyBoost; + uint32_t minimumIntervalUs; +} VkLatencySleepModeInfoNV; + +typedef struct VkLatencySleepInfoNV { + VkStructureType sType; + const void* pNext; + VkSemaphore signalSemaphore; + uint64_t value; +} VkLatencySleepInfoNV; + +typedef struct VkSetLatencyMarkerInfoNV { + VkStructureType sType; + const void* pNext; + uint64_t presentID; + VkLatencyMarkerNV marker; +} VkSetLatencyMarkerInfoNV; + +typedef struct VkLatencyTimingsFrameReportNV { + VkStructureType sType; + const void* pNext; + uint64_t presentID; + uint64_t inputSampleTimeUs; + uint64_t simStartTimeUs; + uint64_t simEndTimeUs; + uint64_t renderSubmitStartTimeUs; + uint64_t renderSubmitEndTimeUs; + uint64_t presentStartTimeUs; + uint64_t presentEndTimeUs; + uint64_t driverStartTimeUs; + uint64_t driverEndTimeUs; + uint64_t osRenderQueueStartTimeUs; + uint64_t osRenderQueueEndTimeUs; + uint64_t gpuRenderStartTimeUs; + uint64_t gpuRenderEndTimeUs; +} VkLatencyTimingsFrameReportNV; + +typedef struct VkGetLatencyMarkerInfoNV { + VkStructureType sType; + const void* pNext; + uint32_t timingCount; + VkLatencyTimingsFrameReportNV* pTimings; +} VkGetLatencyMarkerInfoNV; + +typedef struct VkLatencySubmissionPresentIdNV { + VkStructureType sType; + const void* pNext; + uint64_t presentID; +} VkLatencySubmissionPresentIdNV; + +typedef struct VkSwapchainLatencyCreateInfoNV { + VkStructureType sType; + const void* pNext; + VkBool32 latencyModeEnable; +} VkSwapchainLatencyCreateInfoNV; + +typedef struct VkOutOfBandQueueTypeInfoNV { + VkStructureType sType; + const void* pNext; + VkOutOfBandQueueTypeNV queueType; +} VkOutOfBandQueueTypeInfoNV; + +typedef struct VkLatencySurfaceCapabilitiesNV { + VkStructureType sType; + const void* pNext; + uint32_t presentModeCount; + VkPresentModeKHR* pPresentModes; +} VkLatencySurfaceCapabilitiesNV; + +typedef VkResult (VKAPI_PTR *PFN_vkSetLatencySleepModeNV)(VkDevice device, VkSwapchainKHR swapchain, const VkLatencySleepModeInfoNV* pSleepModeInfo); +typedef VkResult (VKAPI_PTR *PFN_vkLatencySleepNV)(VkDevice device, VkSwapchainKHR swapchain, const VkLatencySleepInfoNV* pSleepInfo); +typedef void (VKAPI_PTR *PFN_vkSetLatencyMarkerNV)(VkDevice device, VkSwapchainKHR swapchain, const VkSetLatencyMarkerInfoNV* pLatencyMarkerInfo); +typedef void (VKAPI_PTR *PFN_vkGetLatencyTimingsNV)(VkDevice device, VkSwapchainKHR swapchain, VkGetLatencyMarkerInfoNV* pLatencyMarkerInfo); +typedef void (VKAPI_PTR *PFN_vkQueueNotifyOutOfBandNV)(VkQueue queue, const VkOutOfBandQueueTypeInfoNV* pQueueTypeInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkSetLatencySleepModeNV( + VkDevice device, + VkSwapchainKHR swapchain, + const VkLatencySleepModeInfoNV* pSleepModeInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkLatencySleepNV( + VkDevice device, + VkSwapchainKHR swapchain, + const VkLatencySleepInfoNV* pSleepInfo); + +VKAPI_ATTR void VKAPI_CALL vkSetLatencyMarkerNV( + VkDevice device, + VkSwapchainKHR swapchain, + const VkSetLatencyMarkerInfoNV* pLatencyMarkerInfo); + +VKAPI_ATTR void VKAPI_CALL vkGetLatencyTimingsNV( + VkDevice device, + VkSwapchainKHR swapchain, + VkGetLatencyMarkerInfoNV* pLatencyMarkerInfo); + +VKAPI_ATTR void VKAPI_CALL vkQueueNotifyOutOfBandNV( + VkQueue queue, + const VkOutOfBandQueueTypeInfoNV* pQueueTypeInfo); +#endif + + +// VK_QCOM_multiview_per_view_render_areas is a preprocessor guard. Do not pass it to API calls. +#define VK_QCOM_multiview_per_view_render_areas 1 +#define VK_QCOM_MULTIVIEW_PER_VIEW_RENDER_AREAS_SPEC_VERSION 1 +#define VK_QCOM_MULTIVIEW_PER_VIEW_RENDER_AREAS_EXTENSION_NAME "VK_QCOM_multiview_per_view_render_areas" +typedef struct VkPhysicalDeviceMultiviewPerViewRenderAreasFeaturesQCOM { + VkStructureType sType; + void* pNext; + VkBool32 multiviewPerViewRenderAreas; +} VkPhysicalDeviceMultiviewPerViewRenderAreasFeaturesQCOM; + +typedef struct VkMultiviewPerViewRenderAreasRenderPassBeginInfoQCOM { + VkStructureType sType; + const void* pNext; + uint32_t perViewRenderAreaCount; + const VkRect2D* pPerViewRenderAreas; +} VkMultiviewPerViewRenderAreasRenderPassBeginInfoQCOM; + + + +// VK_NV_per_stage_descriptor_set is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_per_stage_descriptor_set 1 +#define VK_NV_PER_STAGE_DESCRIPTOR_SET_SPEC_VERSION 1 +#define VK_NV_PER_STAGE_DESCRIPTOR_SET_EXTENSION_NAME "VK_NV_per_stage_descriptor_set" +typedef struct VkPhysicalDevicePerStageDescriptorSetFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 perStageDescriptorSet; + VkBool32 dynamicPipelineLayout; +} VkPhysicalDevicePerStageDescriptorSetFeaturesNV; + + + +// VK_QCOM_image_processing2 is a preprocessor guard. Do not pass it to API calls. +#define VK_QCOM_image_processing2 1 +#define VK_QCOM_IMAGE_PROCESSING_2_SPEC_VERSION 1 +#define VK_QCOM_IMAGE_PROCESSING_2_EXTENSION_NAME "VK_QCOM_image_processing2" + +typedef enum VkBlockMatchWindowCompareModeQCOM { + VK_BLOCK_MATCH_WINDOW_COMPARE_MODE_MIN_QCOM = 0, + VK_BLOCK_MATCH_WINDOW_COMPARE_MODE_MAX_QCOM = 1, + VK_BLOCK_MATCH_WINDOW_COMPARE_MODE_MAX_ENUM_QCOM = 0x7FFFFFFF +} VkBlockMatchWindowCompareModeQCOM; +typedef struct VkPhysicalDeviceImageProcessing2FeaturesQCOM { + VkStructureType sType; + void* pNext; + VkBool32 textureBlockMatch2; +} VkPhysicalDeviceImageProcessing2FeaturesQCOM; + +typedef struct VkPhysicalDeviceImageProcessing2PropertiesQCOM { + VkStructureType sType; + void* pNext; + VkExtent2D maxBlockMatchWindow; +} VkPhysicalDeviceImageProcessing2PropertiesQCOM; + +typedef struct VkSamplerBlockMatchWindowCreateInfoQCOM { + VkStructureType sType; + const void* pNext; + VkExtent2D windowExtent; + VkBlockMatchWindowCompareModeQCOM windowCompareMode; +} VkSamplerBlockMatchWindowCreateInfoQCOM; + + + +// VK_QCOM_filter_cubic_weights is a preprocessor guard. Do not pass it to API calls. +#define VK_QCOM_filter_cubic_weights 1 +#define VK_QCOM_FILTER_CUBIC_WEIGHTS_SPEC_VERSION 1 +#define VK_QCOM_FILTER_CUBIC_WEIGHTS_EXTENSION_NAME "VK_QCOM_filter_cubic_weights" + +typedef enum VkCubicFilterWeightsQCOM { + VK_CUBIC_FILTER_WEIGHTS_CATMULL_ROM_QCOM = 0, + VK_CUBIC_FILTER_WEIGHTS_ZERO_TANGENT_CARDINAL_QCOM = 1, + VK_CUBIC_FILTER_WEIGHTS_B_SPLINE_QCOM = 2, + VK_CUBIC_FILTER_WEIGHTS_MITCHELL_NETRAVALI_QCOM = 3, + VK_CUBIC_FILTER_WEIGHTS_MAX_ENUM_QCOM = 0x7FFFFFFF +} VkCubicFilterWeightsQCOM; +typedef struct VkPhysicalDeviceCubicWeightsFeaturesQCOM { + VkStructureType sType; + void* pNext; + VkBool32 selectableCubicWeights; +} VkPhysicalDeviceCubicWeightsFeaturesQCOM; + +typedef struct VkSamplerCubicWeightsCreateInfoQCOM { + VkStructureType sType; + const void* pNext; + VkCubicFilterWeightsQCOM cubicWeights; +} VkSamplerCubicWeightsCreateInfoQCOM; + +typedef struct VkBlitImageCubicWeightsInfoQCOM { + VkStructureType sType; + const void* pNext; + VkCubicFilterWeightsQCOM cubicWeights; +} VkBlitImageCubicWeightsInfoQCOM; + + + +// VK_QCOM_ycbcr_degamma is a preprocessor guard. Do not pass it to API calls. +#define VK_QCOM_ycbcr_degamma 1 +#define VK_QCOM_YCBCR_DEGAMMA_SPEC_VERSION 1 +#define VK_QCOM_YCBCR_DEGAMMA_EXTENSION_NAME "VK_QCOM_ycbcr_degamma" +typedef struct VkPhysicalDeviceYcbcrDegammaFeaturesQCOM { + VkStructureType sType; + void* pNext; + VkBool32 ycbcrDegamma; +} VkPhysicalDeviceYcbcrDegammaFeaturesQCOM; + +typedef struct VkSamplerYcbcrConversionYcbcrDegammaCreateInfoQCOM { + VkStructureType sType; + void* pNext; + VkBool32 enableYDegamma; + VkBool32 enableCbCrDegamma; +} VkSamplerYcbcrConversionYcbcrDegammaCreateInfoQCOM; + + + +// VK_QCOM_filter_cubic_clamp is a preprocessor guard. Do not pass it to API calls. +#define VK_QCOM_filter_cubic_clamp 1 +#define VK_QCOM_FILTER_CUBIC_CLAMP_SPEC_VERSION 1 +#define VK_QCOM_FILTER_CUBIC_CLAMP_EXTENSION_NAME "VK_QCOM_filter_cubic_clamp" +typedef struct VkPhysicalDeviceCubicClampFeaturesQCOM { + VkStructureType sType; + void* pNext; + VkBool32 cubicRangeClamp; +} VkPhysicalDeviceCubicClampFeaturesQCOM; + + + +// VK_EXT_attachment_feedback_loop_dynamic_state is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_attachment_feedback_loop_dynamic_state 1 +#define VK_EXT_ATTACHMENT_FEEDBACK_LOOP_DYNAMIC_STATE_SPEC_VERSION 1 +#define VK_EXT_ATTACHMENT_FEEDBACK_LOOP_DYNAMIC_STATE_EXTENSION_NAME "VK_EXT_attachment_feedback_loop_dynamic_state" +typedef struct VkPhysicalDeviceAttachmentFeedbackLoopDynamicStateFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 attachmentFeedbackLoopDynamicState; +} VkPhysicalDeviceAttachmentFeedbackLoopDynamicStateFeaturesEXT; + +typedef void (VKAPI_PTR *PFN_vkCmdSetAttachmentFeedbackLoopEnableEXT)(VkCommandBuffer commandBuffer, VkImageAspectFlags aspectMask); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdSetAttachmentFeedbackLoopEnableEXT( + VkCommandBuffer commandBuffer, + VkImageAspectFlags aspectMask); +#endif + + +// VK_MSFT_layered_driver is a preprocessor guard. Do not pass it to API calls. +#define VK_MSFT_layered_driver 1 +#define VK_MSFT_LAYERED_DRIVER_SPEC_VERSION 1 +#define VK_MSFT_LAYERED_DRIVER_EXTENSION_NAME "VK_MSFT_layered_driver" + +typedef enum VkLayeredDriverUnderlyingApiMSFT { + VK_LAYERED_DRIVER_UNDERLYING_API_NONE_MSFT = 0, + VK_LAYERED_DRIVER_UNDERLYING_API_D3D12_MSFT = 1, + VK_LAYERED_DRIVER_UNDERLYING_API_MAX_ENUM_MSFT = 0x7FFFFFFF +} VkLayeredDriverUnderlyingApiMSFT; +typedef struct VkPhysicalDeviceLayeredDriverPropertiesMSFT { + VkStructureType sType; + void* pNext; + VkLayeredDriverUnderlyingApiMSFT underlyingAPI; +} VkPhysicalDeviceLayeredDriverPropertiesMSFT; + + + +// VK_NV_descriptor_pool_overallocation is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_descriptor_pool_overallocation 1 +#define VK_NV_DESCRIPTOR_POOL_OVERALLOCATION_SPEC_VERSION 1 +#define VK_NV_DESCRIPTOR_POOL_OVERALLOCATION_EXTENSION_NAME "VK_NV_descriptor_pool_overallocation" +typedef struct VkPhysicalDeviceDescriptorPoolOverallocationFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 descriptorPoolOverallocation; +} VkPhysicalDeviceDescriptorPoolOverallocationFeaturesNV; + + + +// VK_KHR_acceleration_structure is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_acceleration_structure 1 +#define VK_KHR_ACCELERATION_STRUCTURE_SPEC_VERSION 13 +#define VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME "VK_KHR_acceleration_structure" + +typedef enum VkBuildAccelerationStructureModeKHR { + VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR = 0, + VK_BUILD_ACCELERATION_STRUCTURE_MODE_UPDATE_KHR = 1, + VK_BUILD_ACCELERATION_STRUCTURE_MODE_MAX_ENUM_KHR = 0x7FFFFFFF +} VkBuildAccelerationStructureModeKHR; + +typedef enum VkAccelerationStructureCreateFlagBitsKHR { + VK_ACCELERATION_STRUCTURE_CREATE_DEVICE_ADDRESS_CAPTURE_REPLAY_BIT_KHR = 0x00000001, + VK_ACCELERATION_STRUCTURE_CREATE_DESCRIPTOR_BUFFER_CAPTURE_REPLAY_BIT_EXT = 0x00000008, + VK_ACCELERATION_STRUCTURE_CREATE_MOTION_BIT_NV = 0x00000004, + VK_ACCELERATION_STRUCTURE_CREATE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF +} VkAccelerationStructureCreateFlagBitsKHR; +typedef VkFlags VkAccelerationStructureCreateFlagsKHR; +typedef struct VkAccelerationStructureBuildRangeInfoKHR { + uint32_t primitiveCount; + uint32_t primitiveOffset; + uint32_t firstVertex; + uint32_t transformOffset; +} VkAccelerationStructureBuildRangeInfoKHR; + +typedef struct VkAccelerationStructureGeometryTrianglesDataKHR { + VkStructureType sType; + const void* pNext; + VkFormat vertexFormat; + VkDeviceOrHostAddressConstKHR vertexData; + VkDeviceSize vertexStride; + uint32_t maxVertex; + VkIndexType indexType; + VkDeviceOrHostAddressConstKHR indexData; + VkDeviceOrHostAddressConstKHR transformData; +} VkAccelerationStructureGeometryTrianglesDataKHR; + +typedef struct VkAccelerationStructureGeometryAabbsDataKHR { + VkStructureType sType; + const void* pNext; + VkDeviceOrHostAddressConstKHR data; + VkDeviceSize stride; +} VkAccelerationStructureGeometryAabbsDataKHR; + +typedef struct VkAccelerationStructureGeometryInstancesDataKHR { + VkStructureType sType; + const void* pNext; + VkBool32 arrayOfPointers; + VkDeviceOrHostAddressConstKHR data; +} VkAccelerationStructureGeometryInstancesDataKHR; + +typedef union VkAccelerationStructureGeometryDataKHR { + VkAccelerationStructureGeometryTrianglesDataKHR triangles; + VkAccelerationStructureGeometryAabbsDataKHR aabbs; + VkAccelerationStructureGeometryInstancesDataKHR instances; +} VkAccelerationStructureGeometryDataKHR; + +typedef struct VkAccelerationStructureGeometryKHR { + VkStructureType sType; + const void* pNext; + VkGeometryTypeKHR geometryType; + VkAccelerationStructureGeometryDataKHR geometry; + VkGeometryFlagsKHR flags; +} VkAccelerationStructureGeometryKHR; + +typedef struct VkAccelerationStructureBuildGeometryInfoKHR { + VkStructureType sType; + const void* pNext; + VkAccelerationStructureTypeKHR type; + VkBuildAccelerationStructureFlagsKHR flags; + VkBuildAccelerationStructureModeKHR mode; + VkAccelerationStructureKHR srcAccelerationStructure; + VkAccelerationStructureKHR dstAccelerationStructure; + uint32_t geometryCount; + const VkAccelerationStructureGeometryKHR* pGeometries; + const VkAccelerationStructureGeometryKHR* const* ppGeometries; + VkDeviceOrHostAddressKHR scratchData; +} VkAccelerationStructureBuildGeometryInfoKHR; + +typedef struct VkAccelerationStructureCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkAccelerationStructureCreateFlagsKHR createFlags; + VkBuffer buffer; + VkDeviceSize offset; + VkDeviceSize size; + VkAccelerationStructureTypeKHR type; + VkDeviceAddress deviceAddress; +} VkAccelerationStructureCreateInfoKHR; + +typedef struct VkWriteDescriptorSetAccelerationStructureKHR { + VkStructureType sType; + const void* pNext; + uint32_t accelerationStructureCount; + const VkAccelerationStructureKHR* pAccelerationStructures; +} VkWriteDescriptorSetAccelerationStructureKHR; + +typedef struct VkPhysicalDeviceAccelerationStructureFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 accelerationStructure; + VkBool32 accelerationStructureCaptureReplay; + VkBool32 accelerationStructureIndirectBuild; + VkBool32 accelerationStructureHostCommands; + VkBool32 descriptorBindingAccelerationStructureUpdateAfterBind; +} VkPhysicalDeviceAccelerationStructureFeaturesKHR; + +typedef struct VkPhysicalDeviceAccelerationStructurePropertiesKHR { + VkStructureType sType; + void* pNext; + uint64_t maxGeometryCount; + uint64_t maxInstanceCount; + uint64_t maxPrimitiveCount; + uint32_t maxPerStageDescriptorAccelerationStructures; + uint32_t maxPerStageDescriptorUpdateAfterBindAccelerationStructures; + uint32_t maxDescriptorSetAccelerationStructures; + uint32_t maxDescriptorSetUpdateAfterBindAccelerationStructures; + uint32_t minAccelerationStructureScratchOffsetAlignment; +} VkPhysicalDeviceAccelerationStructurePropertiesKHR; + +typedef struct VkAccelerationStructureDeviceAddressInfoKHR { + VkStructureType sType; + const void* pNext; + VkAccelerationStructureKHR accelerationStructure; +} VkAccelerationStructureDeviceAddressInfoKHR; + +typedef struct VkAccelerationStructureVersionInfoKHR { + VkStructureType sType; + const void* pNext; + const uint8_t* pVersionData; +} VkAccelerationStructureVersionInfoKHR; + +typedef struct VkCopyAccelerationStructureToMemoryInfoKHR { + VkStructureType sType; + const void* pNext; + VkAccelerationStructureKHR src; + VkDeviceOrHostAddressKHR dst; + VkCopyAccelerationStructureModeKHR mode; +} VkCopyAccelerationStructureToMemoryInfoKHR; + +typedef struct VkCopyMemoryToAccelerationStructureInfoKHR { + VkStructureType sType; + const void* pNext; + VkDeviceOrHostAddressConstKHR src; + VkAccelerationStructureKHR dst; + VkCopyAccelerationStructureModeKHR mode; +} VkCopyMemoryToAccelerationStructureInfoKHR; + +typedef struct VkCopyAccelerationStructureInfoKHR { + VkStructureType sType; + const void* pNext; + VkAccelerationStructureKHR src; + VkAccelerationStructureKHR dst; + VkCopyAccelerationStructureModeKHR mode; +} VkCopyAccelerationStructureInfoKHR; + +typedef struct VkAccelerationStructureBuildSizesInfoKHR { + VkStructureType sType; + const void* pNext; + VkDeviceSize accelerationStructureSize; + VkDeviceSize updateScratchSize; + VkDeviceSize buildScratchSize; +} VkAccelerationStructureBuildSizesInfoKHR; + +typedef VkResult (VKAPI_PTR *PFN_vkCreateAccelerationStructureKHR)(VkDevice device, const VkAccelerationStructureCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkAccelerationStructureKHR* pAccelerationStructure); +typedef void (VKAPI_PTR *PFN_vkDestroyAccelerationStructureKHR)(VkDevice device, VkAccelerationStructureKHR accelerationStructure, const VkAllocationCallbacks* pAllocator); +typedef void (VKAPI_PTR *PFN_vkCmdBuildAccelerationStructuresKHR)(VkCommandBuffer commandBuffer, uint32_t infoCount, const VkAccelerationStructureBuildGeometryInfoKHR* pInfos, const VkAccelerationStructureBuildRangeInfoKHR* const* ppBuildRangeInfos); +typedef void (VKAPI_PTR *PFN_vkCmdBuildAccelerationStructuresIndirectKHR)(VkCommandBuffer commandBuffer, uint32_t infoCount, const VkAccelerationStructureBuildGeometryInfoKHR* pInfos, const VkDeviceAddress* pIndirectDeviceAddresses, const uint32_t* pIndirectStrides, const uint32_t* const* ppMaxPrimitiveCounts); +typedef VkResult (VKAPI_PTR *PFN_vkBuildAccelerationStructuresKHR)(VkDevice device, VkDeferredOperationKHR deferredOperation, uint32_t infoCount, const VkAccelerationStructureBuildGeometryInfoKHR* pInfos, const VkAccelerationStructureBuildRangeInfoKHR* const* ppBuildRangeInfos); +typedef VkResult (VKAPI_PTR *PFN_vkCopyAccelerationStructureKHR)(VkDevice device, VkDeferredOperationKHR deferredOperation, const VkCopyAccelerationStructureInfoKHR* pInfo); +typedef VkResult (VKAPI_PTR *PFN_vkCopyAccelerationStructureToMemoryKHR)(VkDevice device, VkDeferredOperationKHR deferredOperation, const VkCopyAccelerationStructureToMemoryInfoKHR* pInfo); +typedef VkResult (VKAPI_PTR *PFN_vkCopyMemoryToAccelerationStructureKHR)(VkDevice device, VkDeferredOperationKHR deferredOperation, const VkCopyMemoryToAccelerationStructureInfoKHR* pInfo); +typedef VkResult (VKAPI_PTR *PFN_vkWriteAccelerationStructuresPropertiesKHR)(VkDevice device, uint32_t accelerationStructureCount, const VkAccelerationStructureKHR* pAccelerationStructures, VkQueryType queryType, size_t dataSize, void* pData, size_t stride); +typedef void (VKAPI_PTR *PFN_vkCmdCopyAccelerationStructureKHR)(VkCommandBuffer commandBuffer, const VkCopyAccelerationStructureInfoKHR* pInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyAccelerationStructureToMemoryKHR)(VkCommandBuffer commandBuffer, const VkCopyAccelerationStructureToMemoryInfoKHR* pInfo); +typedef void (VKAPI_PTR *PFN_vkCmdCopyMemoryToAccelerationStructureKHR)(VkCommandBuffer commandBuffer, const VkCopyMemoryToAccelerationStructureInfoKHR* pInfo); +typedef VkDeviceAddress (VKAPI_PTR *PFN_vkGetAccelerationStructureDeviceAddressKHR)(VkDevice device, const VkAccelerationStructureDeviceAddressInfoKHR* pInfo); +typedef void (VKAPI_PTR *PFN_vkCmdWriteAccelerationStructuresPropertiesKHR)(VkCommandBuffer commandBuffer, uint32_t accelerationStructureCount, const VkAccelerationStructureKHR* pAccelerationStructures, VkQueryType queryType, VkQueryPool queryPool, uint32_t firstQuery); +typedef void (VKAPI_PTR *PFN_vkGetDeviceAccelerationStructureCompatibilityKHR)(VkDevice device, const VkAccelerationStructureVersionInfoKHR* pVersionInfo, VkAccelerationStructureCompatibilityKHR* pCompatibility); +typedef void (VKAPI_PTR *PFN_vkGetAccelerationStructureBuildSizesKHR)(VkDevice device, VkAccelerationStructureBuildTypeKHR buildType, const VkAccelerationStructureBuildGeometryInfoKHR* pBuildInfo, const uint32_t* pMaxPrimitiveCounts, VkAccelerationStructureBuildSizesInfoKHR* pSizeInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateAccelerationStructureKHR( + VkDevice device, + const VkAccelerationStructureCreateInfoKHR* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkAccelerationStructureKHR* pAccelerationStructure); + +VKAPI_ATTR void VKAPI_CALL vkDestroyAccelerationStructureKHR( + VkDevice device, + VkAccelerationStructureKHR accelerationStructure, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR void VKAPI_CALL vkCmdBuildAccelerationStructuresKHR( + VkCommandBuffer commandBuffer, + uint32_t infoCount, + const VkAccelerationStructureBuildGeometryInfoKHR* pInfos, + const VkAccelerationStructureBuildRangeInfoKHR* const* ppBuildRangeInfos); + +VKAPI_ATTR void VKAPI_CALL vkCmdBuildAccelerationStructuresIndirectKHR( + VkCommandBuffer commandBuffer, + uint32_t infoCount, + const VkAccelerationStructureBuildGeometryInfoKHR* pInfos, + const VkDeviceAddress* pIndirectDeviceAddresses, + const uint32_t* pIndirectStrides, + const uint32_t* const* ppMaxPrimitiveCounts); + +VKAPI_ATTR VkResult VKAPI_CALL vkBuildAccelerationStructuresKHR( + VkDevice device, + VkDeferredOperationKHR deferredOperation, + uint32_t infoCount, + const VkAccelerationStructureBuildGeometryInfoKHR* pInfos, + const VkAccelerationStructureBuildRangeInfoKHR* const* ppBuildRangeInfos); + +VKAPI_ATTR VkResult VKAPI_CALL vkCopyAccelerationStructureKHR( + VkDevice device, + VkDeferredOperationKHR deferredOperation, + const VkCopyAccelerationStructureInfoKHR* pInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkCopyAccelerationStructureToMemoryKHR( + VkDevice device, + VkDeferredOperationKHR deferredOperation, + const VkCopyAccelerationStructureToMemoryInfoKHR* pInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkCopyMemoryToAccelerationStructureKHR( + VkDevice device, + VkDeferredOperationKHR deferredOperation, + const VkCopyMemoryToAccelerationStructureInfoKHR* pInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkWriteAccelerationStructuresPropertiesKHR( + VkDevice device, + uint32_t accelerationStructureCount, + const VkAccelerationStructureKHR* pAccelerationStructures, + VkQueryType queryType, + size_t dataSize, + void* pData, + size_t stride); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyAccelerationStructureKHR( + VkCommandBuffer commandBuffer, + const VkCopyAccelerationStructureInfoKHR* pInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyAccelerationStructureToMemoryKHR( + VkCommandBuffer commandBuffer, + const VkCopyAccelerationStructureToMemoryInfoKHR* pInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdCopyMemoryToAccelerationStructureKHR( + VkCommandBuffer commandBuffer, + const VkCopyMemoryToAccelerationStructureInfoKHR* pInfo); + +VKAPI_ATTR VkDeviceAddress VKAPI_CALL vkGetAccelerationStructureDeviceAddressKHR( + VkDevice device, + const VkAccelerationStructureDeviceAddressInfoKHR* pInfo); + +VKAPI_ATTR void VKAPI_CALL vkCmdWriteAccelerationStructuresPropertiesKHR( + VkCommandBuffer commandBuffer, + uint32_t accelerationStructureCount, + const VkAccelerationStructureKHR* pAccelerationStructures, + VkQueryType queryType, + VkQueryPool queryPool, + uint32_t firstQuery); + +VKAPI_ATTR void VKAPI_CALL vkGetDeviceAccelerationStructureCompatibilityKHR( + VkDevice device, + const VkAccelerationStructureVersionInfoKHR* pVersionInfo, + VkAccelerationStructureCompatibilityKHR* pCompatibility); + +VKAPI_ATTR void VKAPI_CALL vkGetAccelerationStructureBuildSizesKHR( + VkDevice device, + VkAccelerationStructureBuildTypeKHR buildType, + const VkAccelerationStructureBuildGeometryInfoKHR* pBuildInfo, + const uint32_t* pMaxPrimitiveCounts, + VkAccelerationStructureBuildSizesInfoKHR* pSizeInfo); +#endif + + +// VK_KHR_ray_tracing_pipeline is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_ray_tracing_pipeline 1 +#define VK_KHR_RAY_TRACING_PIPELINE_SPEC_VERSION 1 +#define VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME "VK_KHR_ray_tracing_pipeline" + +typedef enum VkShaderGroupShaderKHR { + VK_SHADER_GROUP_SHADER_GENERAL_KHR = 0, + VK_SHADER_GROUP_SHADER_CLOSEST_HIT_KHR = 1, + VK_SHADER_GROUP_SHADER_ANY_HIT_KHR = 2, + VK_SHADER_GROUP_SHADER_INTERSECTION_KHR = 3, + VK_SHADER_GROUP_SHADER_MAX_ENUM_KHR = 0x7FFFFFFF +} VkShaderGroupShaderKHR; +typedef struct VkRayTracingShaderGroupCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkRayTracingShaderGroupTypeKHR type; + uint32_t generalShader; + uint32_t closestHitShader; + uint32_t anyHitShader; + uint32_t intersectionShader; + const void* pShaderGroupCaptureReplayHandle; +} VkRayTracingShaderGroupCreateInfoKHR; + +typedef struct VkRayTracingPipelineInterfaceCreateInfoKHR { + VkStructureType sType; + const void* pNext; + uint32_t maxPipelineRayPayloadSize; + uint32_t maxPipelineRayHitAttributeSize; +} VkRayTracingPipelineInterfaceCreateInfoKHR; + +typedef struct VkRayTracingPipelineCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkPipelineCreateFlags flags; + uint32_t stageCount; + const VkPipelineShaderStageCreateInfo* pStages; + uint32_t groupCount; + const VkRayTracingShaderGroupCreateInfoKHR* pGroups; + uint32_t maxPipelineRayRecursionDepth; + const VkPipelineLibraryCreateInfoKHR* pLibraryInfo; + const VkRayTracingPipelineInterfaceCreateInfoKHR* pLibraryInterface; + const VkPipelineDynamicStateCreateInfo* pDynamicState; + VkPipelineLayout layout; + VkPipeline basePipelineHandle; + int32_t basePipelineIndex; +} VkRayTracingPipelineCreateInfoKHR; + +typedef struct VkPhysicalDeviceRayTracingPipelineFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 rayTracingPipeline; + VkBool32 rayTracingPipelineShaderGroupHandleCaptureReplay; + VkBool32 rayTracingPipelineShaderGroupHandleCaptureReplayMixed; + VkBool32 rayTracingPipelineTraceRaysIndirect; + VkBool32 rayTraversalPrimitiveCulling; +} VkPhysicalDeviceRayTracingPipelineFeaturesKHR; + +typedef struct VkPhysicalDeviceRayTracingPipelinePropertiesKHR { + VkStructureType sType; + void* pNext; + uint32_t shaderGroupHandleSize; + uint32_t maxRayRecursionDepth; + uint32_t maxShaderGroupStride; + uint32_t shaderGroupBaseAlignment; + uint32_t shaderGroupHandleCaptureReplaySize; + uint32_t maxRayDispatchInvocationCount; + uint32_t shaderGroupHandleAlignment; + uint32_t maxRayHitAttributeSize; +} VkPhysicalDeviceRayTracingPipelinePropertiesKHR; + +typedef struct VkStridedDeviceAddressRegionKHR { + VkDeviceAddress deviceAddress; + VkDeviceSize stride; + VkDeviceSize size; +} VkStridedDeviceAddressRegionKHR; + +typedef struct VkTraceRaysIndirectCommandKHR { + uint32_t width; + uint32_t height; + uint32_t depth; +} VkTraceRaysIndirectCommandKHR; + +typedef void (VKAPI_PTR *PFN_vkCmdTraceRaysKHR)(VkCommandBuffer commandBuffer, const VkStridedDeviceAddressRegionKHR* pRaygenShaderBindingTable, const VkStridedDeviceAddressRegionKHR* pMissShaderBindingTable, const VkStridedDeviceAddressRegionKHR* pHitShaderBindingTable, const VkStridedDeviceAddressRegionKHR* pCallableShaderBindingTable, uint32_t width, uint32_t height, uint32_t depth); +typedef VkResult (VKAPI_PTR *PFN_vkCreateRayTracingPipelinesKHR)(VkDevice device, VkDeferredOperationKHR deferredOperation, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkRayTracingPipelineCreateInfoKHR* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines); +typedef VkResult (VKAPI_PTR *PFN_vkGetRayTracingCaptureReplayShaderGroupHandlesKHR)(VkDevice device, VkPipeline pipeline, uint32_t firstGroup, uint32_t groupCount, size_t dataSize, void* pData); +typedef void (VKAPI_PTR *PFN_vkCmdTraceRaysIndirectKHR)(VkCommandBuffer commandBuffer, const VkStridedDeviceAddressRegionKHR* pRaygenShaderBindingTable, const VkStridedDeviceAddressRegionKHR* pMissShaderBindingTable, const VkStridedDeviceAddressRegionKHR* pHitShaderBindingTable, const VkStridedDeviceAddressRegionKHR* pCallableShaderBindingTable, VkDeviceAddress indirectDeviceAddress); +typedef VkDeviceSize (VKAPI_PTR *PFN_vkGetRayTracingShaderGroupStackSizeKHR)(VkDevice device, VkPipeline pipeline, uint32_t group, VkShaderGroupShaderKHR groupShader); +typedef void (VKAPI_PTR *PFN_vkCmdSetRayTracingPipelineStackSizeKHR)(VkCommandBuffer commandBuffer, uint32_t pipelineStackSize); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdTraceRaysKHR( + VkCommandBuffer commandBuffer, + const VkStridedDeviceAddressRegionKHR* pRaygenShaderBindingTable, + const VkStridedDeviceAddressRegionKHR* pMissShaderBindingTable, + const VkStridedDeviceAddressRegionKHR* pHitShaderBindingTable, + const VkStridedDeviceAddressRegionKHR* pCallableShaderBindingTable, + uint32_t width, + uint32_t height, + uint32_t depth); + +VKAPI_ATTR VkResult VKAPI_CALL vkCreateRayTracingPipelinesKHR( + VkDevice device, + VkDeferredOperationKHR deferredOperation, + VkPipelineCache pipelineCache, + uint32_t createInfoCount, + const VkRayTracingPipelineCreateInfoKHR* pCreateInfos, + const VkAllocationCallbacks* pAllocator, + VkPipeline* pPipelines); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetRayTracingCaptureReplayShaderGroupHandlesKHR( + VkDevice device, + VkPipeline pipeline, + uint32_t firstGroup, + uint32_t groupCount, + size_t dataSize, + void* pData); + +VKAPI_ATTR void VKAPI_CALL vkCmdTraceRaysIndirectKHR( + VkCommandBuffer commandBuffer, + const VkStridedDeviceAddressRegionKHR* pRaygenShaderBindingTable, + const VkStridedDeviceAddressRegionKHR* pMissShaderBindingTable, + const VkStridedDeviceAddressRegionKHR* pHitShaderBindingTable, + const VkStridedDeviceAddressRegionKHR* pCallableShaderBindingTable, + VkDeviceAddress indirectDeviceAddress); + +VKAPI_ATTR VkDeviceSize VKAPI_CALL vkGetRayTracingShaderGroupStackSizeKHR( + VkDevice device, + VkPipeline pipeline, + uint32_t group, + VkShaderGroupShaderKHR groupShader); + +VKAPI_ATTR void VKAPI_CALL vkCmdSetRayTracingPipelineStackSizeKHR( + VkCommandBuffer commandBuffer, + uint32_t pipelineStackSize); +#endif + + +// VK_KHR_ray_query is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_ray_query 1 +#define VK_KHR_RAY_QUERY_SPEC_VERSION 1 +#define VK_KHR_RAY_QUERY_EXTENSION_NAME "VK_KHR_ray_query" +typedef struct VkPhysicalDeviceRayQueryFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 rayQuery; +} VkPhysicalDeviceRayQueryFeaturesKHR; + + + +// VK_EXT_mesh_shader is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_mesh_shader 1 +#define VK_EXT_MESH_SHADER_SPEC_VERSION 1 +#define VK_EXT_MESH_SHADER_EXTENSION_NAME "VK_EXT_mesh_shader" +typedef struct VkPhysicalDeviceMeshShaderFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 taskShader; + VkBool32 meshShader; + VkBool32 multiviewMeshShader; + VkBool32 primitiveFragmentShadingRateMeshShader; + VkBool32 meshShaderQueries; +} VkPhysicalDeviceMeshShaderFeaturesEXT; + +typedef struct VkPhysicalDeviceMeshShaderPropertiesEXT { + VkStructureType sType; + void* pNext; + uint32_t maxTaskWorkGroupTotalCount; + uint32_t maxTaskWorkGroupCount[3]; + uint32_t maxTaskWorkGroupInvocations; + uint32_t maxTaskWorkGroupSize[3]; + uint32_t maxTaskPayloadSize; + uint32_t maxTaskSharedMemorySize; + uint32_t maxTaskPayloadAndSharedMemorySize; + uint32_t maxMeshWorkGroupTotalCount; + uint32_t maxMeshWorkGroupCount[3]; + uint32_t maxMeshWorkGroupInvocations; + uint32_t maxMeshWorkGroupSize[3]; + uint32_t maxMeshSharedMemorySize; + uint32_t maxMeshPayloadAndSharedMemorySize; + uint32_t maxMeshOutputMemorySize; + uint32_t maxMeshPayloadAndOutputMemorySize; + uint32_t maxMeshOutputComponents; + uint32_t maxMeshOutputVertices; + uint32_t maxMeshOutputPrimitives; + uint32_t maxMeshOutputLayers; + uint32_t maxMeshMultiviewViewCount; + uint32_t meshOutputPerVertexGranularity; + uint32_t meshOutputPerPrimitiveGranularity; + uint32_t maxPreferredTaskWorkGroupInvocations; + uint32_t maxPreferredMeshWorkGroupInvocations; + VkBool32 prefersLocalInvocationVertexOutput; + VkBool32 prefersLocalInvocationPrimitiveOutput; + VkBool32 prefersCompactVertexOutput; + VkBool32 prefersCompactPrimitiveOutput; +} VkPhysicalDeviceMeshShaderPropertiesEXT; + +typedef struct VkDrawMeshTasksIndirectCommandEXT { + uint32_t groupCountX; + uint32_t groupCountY; + uint32_t groupCountZ; +} VkDrawMeshTasksIndirectCommandEXT; + +typedef void (VKAPI_PTR *PFN_vkCmdDrawMeshTasksEXT)(VkCommandBuffer commandBuffer, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ); +typedef void (VKAPI_PTR *PFN_vkCmdDrawMeshTasksIndirectEXT)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride); +typedef void (VKAPI_PTR *PFN_vkCmdDrawMeshTasksIndirectCountEXT)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkCmdDrawMeshTasksEXT( + VkCommandBuffer commandBuffer, + uint32_t groupCountX, + uint32_t groupCountY, + uint32_t groupCountZ); + +VKAPI_ATTR void VKAPI_CALL vkCmdDrawMeshTasksIndirectEXT( + VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset, + uint32_t drawCount, + uint32_t stride); + +VKAPI_ATTR void VKAPI_CALL vkCmdDrawMeshTasksIndirectCountEXT( + VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset, + VkBuffer countBuffer, + VkDeviceSize countBufferOffset, + uint32_t maxDrawCount, + uint32_t stride); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/SDL2-2.30.5/src/video/khronos/vulkan/vulkan_directfb.h b/SDL2-2.30.5/src/video/khronos/vulkan/vulkan_directfb.h new file mode 100644 index 0000000..f06f80b --- /dev/null +++ b/SDL2-2.30.5/src/video/khronos/vulkan/vulkan_directfb.h @@ -0,0 +1,55 @@ +#ifndef VULKAN_DIRECTFB_H_ +#define VULKAN_DIRECTFB_H_ 1 + +/* +** Copyright 2015-2024 The Khronos Group Inc. +** +** SPDX-License-Identifier: Apache-2.0 +*/ + +/* +** This header is generated from the Khronos Vulkan XML API Registry. +** +*/ + + +#ifdef __cplusplus +extern "C" { +#endif + + + +// VK_EXT_directfb_surface is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_directfb_surface 1 +#define VK_EXT_DIRECTFB_SURFACE_SPEC_VERSION 1 +#define VK_EXT_DIRECTFB_SURFACE_EXTENSION_NAME "VK_EXT_directfb_surface" +typedef VkFlags VkDirectFBSurfaceCreateFlagsEXT; +typedef struct VkDirectFBSurfaceCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkDirectFBSurfaceCreateFlagsEXT flags; + IDirectFB* dfb; + IDirectFBSurface* surface; +} VkDirectFBSurfaceCreateInfoEXT; + +typedef VkResult (VKAPI_PTR *PFN_vkCreateDirectFBSurfaceEXT)(VkInstance instance, const VkDirectFBSurfaceCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); +typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceDirectFBPresentationSupportEXT)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, IDirectFB* dfb); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateDirectFBSurfaceEXT( + VkInstance instance, + const VkDirectFBSurfaceCreateInfoEXT* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface); + +VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceDirectFBPresentationSupportEXT( + VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex, + IDirectFB* dfb); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/SDL2-2.30.5/src/video/khronos/vulkan/vulkan_fuchsia.h b/SDL2-2.30.5/src/video/khronos/vulkan/vulkan_fuchsia.h new file mode 100644 index 0000000..f60907d --- /dev/null +++ b/SDL2-2.30.5/src/video/khronos/vulkan/vulkan_fuchsia.h @@ -0,0 +1,262 @@ +#ifndef VULKAN_FUCHSIA_H_ +#define VULKAN_FUCHSIA_H_ 1 + +/* +** Copyright 2015-2024 The Khronos Group Inc. +** +** SPDX-License-Identifier: Apache-2.0 +*/ + +/* +** This header is generated from the Khronos Vulkan XML API Registry. +** +*/ + + +#ifdef __cplusplus +extern "C" { +#endif + + + +// VK_FUCHSIA_imagepipe_surface is a preprocessor guard. Do not pass it to API calls. +#define VK_FUCHSIA_imagepipe_surface 1 +#define VK_FUCHSIA_IMAGEPIPE_SURFACE_SPEC_VERSION 1 +#define VK_FUCHSIA_IMAGEPIPE_SURFACE_EXTENSION_NAME "VK_FUCHSIA_imagepipe_surface" +typedef VkFlags VkImagePipeSurfaceCreateFlagsFUCHSIA; +typedef struct VkImagePipeSurfaceCreateInfoFUCHSIA { + VkStructureType sType; + const void* pNext; + VkImagePipeSurfaceCreateFlagsFUCHSIA flags; + zx_handle_t imagePipeHandle; +} VkImagePipeSurfaceCreateInfoFUCHSIA; + +typedef VkResult (VKAPI_PTR *PFN_vkCreateImagePipeSurfaceFUCHSIA)(VkInstance instance, const VkImagePipeSurfaceCreateInfoFUCHSIA* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateImagePipeSurfaceFUCHSIA( + VkInstance instance, + const VkImagePipeSurfaceCreateInfoFUCHSIA* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface); +#endif + + +// VK_FUCHSIA_external_memory is a preprocessor guard. Do not pass it to API calls. +#define VK_FUCHSIA_external_memory 1 +#define VK_FUCHSIA_EXTERNAL_MEMORY_SPEC_VERSION 1 +#define VK_FUCHSIA_EXTERNAL_MEMORY_EXTENSION_NAME "VK_FUCHSIA_external_memory" +typedef struct VkImportMemoryZirconHandleInfoFUCHSIA { + VkStructureType sType; + const void* pNext; + VkExternalMemoryHandleTypeFlagBits handleType; + zx_handle_t handle; +} VkImportMemoryZirconHandleInfoFUCHSIA; + +typedef struct VkMemoryZirconHandlePropertiesFUCHSIA { + VkStructureType sType; + void* pNext; + uint32_t memoryTypeBits; +} VkMemoryZirconHandlePropertiesFUCHSIA; + +typedef struct VkMemoryGetZirconHandleInfoFUCHSIA { + VkStructureType sType; + const void* pNext; + VkDeviceMemory memory; + VkExternalMemoryHandleTypeFlagBits handleType; +} VkMemoryGetZirconHandleInfoFUCHSIA; + +typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryZirconHandleFUCHSIA)(VkDevice device, const VkMemoryGetZirconHandleInfoFUCHSIA* pGetZirconHandleInfo, zx_handle_t* pZirconHandle); +typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryZirconHandlePropertiesFUCHSIA)(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, zx_handle_t zirconHandle, VkMemoryZirconHandlePropertiesFUCHSIA* pMemoryZirconHandleProperties); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryZirconHandleFUCHSIA( + VkDevice device, + const VkMemoryGetZirconHandleInfoFUCHSIA* pGetZirconHandleInfo, + zx_handle_t* pZirconHandle); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryZirconHandlePropertiesFUCHSIA( + VkDevice device, + VkExternalMemoryHandleTypeFlagBits handleType, + zx_handle_t zirconHandle, + VkMemoryZirconHandlePropertiesFUCHSIA* pMemoryZirconHandleProperties); +#endif + + +// VK_FUCHSIA_external_semaphore is a preprocessor guard. Do not pass it to API calls. +#define VK_FUCHSIA_external_semaphore 1 +#define VK_FUCHSIA_EXTERNAL_SEMAPHORE_SPEC_VERSION 1 +#define VK_FUCHSIA_EXTERNAL_SEMAPHORE_EXTENSION_NAME "VK_FUCHSIA_external_semaphore" +typedef struct VkImportSemaphoreZirconHandleInfoFUCHSIA { + VkStructureType sType; + const void* pNext; + VkSemaphore semaphore; + VkSemaphoreImportFlags flags; + VkExternalSemaphoreHandleTypeFlagBits handleType; + zx_handle_t zirconHandle; +} VkImportSemaphoreZirconHandleInfoFUCHSIA; + +typedef struct VkSemaphoreGetZirconHandleInfoFUCHSIA { + VkStructureType sType; + const void* pNext; + VkSemaphore semaphore; + VkExternalSemaphoreHandleTypeFlagBits handleType; +} VkSemaphoreGetZirconHandleInfoFUCHSIA; + +typedef VkResult (VKAPI_PTR *PFN_vkImportSemaphoreZirconHandleFUCHSIA)(VkDevice device, const VkImportSemaphoreZirconHandleInfoFUCHSIA* pImportSemaphoreZirconHandleInfo); +typedef VkResult (VKAPI_PTR *PFN_vkGetSemaphoreZirconHandleFUCHSIA)(VkDevice device, const VkSemaphoreGetZirconHandleInfoFUCHSIA* pGetZirconHandleInfo, zx_handle_t* pZirconHandle); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkImportSemaphoreZirconHandleFUCHSIA( + VkDevice device, + const VkImportSemaphoreZirconHandleInfoFUCHSIA* pImportSemaphoreZirconHandleInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreZirconHandleFUCHSIA( + VkDevice device, + const VkSemaphoreGetZirconHandleInfoFUCHSIA* pGetZirconHandleInfo, + zx_handle_t* pZirconHandle); +#endif + + +// VK_FUCHSIA_buffer_collection is a preprocessor guard. Do not pass it to API calls. +#define VK_FUCHSIA_buffer_collection 1 +VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkBufferCollectionFUCHSIA) +#define VK_FUCHSIA_BUFFER_COLLECTION_SPEC_VERSION 2 +#define VK_FUCHSIA_BUFFER_COLLECTION_EXTENSION_NAME "VK_FUCHSIA_buffer_collection" +typedef VkFlags VkImageFormatConstraintsFlagsFUCHSIA; + +typedef enum VkImageConstraintsInfoFlagBitsFUCHSIA { + VK_IMAGE_CONSTRAINTS_INFO_CPU_READ_RARELY_FUCHSIA = 0x00000001, + VK_IMAGE_CONSTRAINTS_INFO_CPU_READ_OFTEN_FUCHSIA = 0x00000002, + VK_IMAGE_CONSTRAINTS_INFO_CPU_WRITE_RARELY_FUCHSIA = 0x00000004, + VK_IMAGE_CONSTRAINTS_INFO_CPU_WRITE_OFTEN_FUCHSIA = 0x00000008, + VK_IMAGE_CONSTRAINTS_INFO_PROTECTED_OPTIONAL_FUCHSIA = 0x00000010, + VK_IMAGE_CONSTRAINTS_INFO_FLAG_BITS_MAX_ENUM_FUCHSIA = 0x7FFFFFFF +} VkImageConstraintsInfoFlagBitsFUCHSIA; +typedef VkFlags VkImageConstraintsInfoFlagsFUCHSIA; +typedef struct VkBufferCollectionCreateInfoFUCHSIA { + VkStructureType sType; + const void* pNext; + zx_handle_t collectionToken; +} VkBufferCollectionCreateInfoFUCHSIA; + +typedef struct VkImportMemoryBufferCollectionFUCHSIA { + VkStructureType sType; + const void* pNext; + VkBufferCollectionFUCHSIA collection; + uint32_t index; +} VkImportMemoryBufferCollectionFUCHSIA; + +typedef struct VkBufferCollectionImageCreateInfoFUCHSIA { + VkStructureType sType; + const void* pNext; + VkBufferCollectionFUCHSIA collection; + uint32_t index; +} VkBufferCollectionImageCreateInfoFUCHSIA; + +typedef struct VkBufferCollectionConstraintsInfoFUCHSIA { + VkStructureType sType; + const void* pNext; + uint32_t minBufferCount; + uint32_t maxBufferCount; + uint32_t minBufferCountForCamping; + uint32_t minBufferCountForDedicatedSlack; + uint32_t minBufferCountForSharedSlack; +} VkBufferCollectionConstraintsInfoFUCHSIA; + +typedef struct VkBufferConstraintsInfoFUCHSIA { + VkStructureType sType; + const void* pNext; + VkBufferCreateInfo createInfo; + VkFormatFeatureFlags requiredFormatFeatures; + VkBufferCollectionConstraintsInfoFUCHSIA bufferCollectionConstraints; +} VkBufferConstraintsInfoFUCHSIA; + +typedef struct VkBufferCollectionBufferCreateInfoFUCHSIA { + VkStructureType sType; + const void* pNext; + VkBufferCollectionFUCHSIA collection; + uint32_t index; +} VkBufferCollectionBufferCreateInfoFUCHSIA; + +typedef struct VkSysmemColorSpaceFUCHSIA { + VkStructureType sType; + const void* pNext; + uint32_t colorSpace; +} VkSysmemColorSpaceFUCHSIA; + +typedef struct VkBufferCollectionPropertiesFUCHSIA { + VkStructureType sType; + void* pNext; + uint32_t memoryTypeBits; + uint32_t bufferCount; + uint32_t createInfoIndex; + uint64_t sysmemPixelFormat; + VkFormatFeatureFlags formatFeatures; + VkSysmemColorSpaceFUCHSIA sysmemColorSpaceIndex; + VkComponentMapping samplerYcbcrConversionComponents; + VkSamplerYcbcrModelConversion suggestedYcbcrModel; + VkSamplerYcbcrRange suggestedYcbcrRange; + VkChromaLocation suggestedXChromaOffset; + VkChromaLocation suggestedYChromaOffset; +} VkBufferCollectionPropertiesFUCHSIA; + +typedef struct VkImageFormatConstraintsInfoFUCHSIA { + VkStructureType sType; + const void* pNext; + VkImageCreateInfo imageCreateInfo; + VkFormatFeatureFlags requiredFormatFeatures; + VkImageFormatConstraintsFlagsFUCHSIA flags; + uint64_t sysmemPixelFormat; + uint32_t colorSpaceCount; + const VkSysmemColorSpaceFUCHSIA* pColorSpaces; +} VkImageFormatConstraintsInfoFUCHSIA; + +typedef struct VkImageConstraintsInfoFUCHSIA { + VkStructureType sType; + const void* pNext; + uint32_t formatConstraintsCount; + const VkImageFormatConstraintsInfoFUCHSIA* pFormatConstraints; + VkBufferCollectionConstraintsInfoFUCHSIA bufferCollectionConstraints; + VkImageConstraintsInfoFlagsFUCHSIA flags; +} VkImageConstraintsInfoFUCHSIA; + +typedef VkResult (VKAPI_PTR *PFN_vkCreateBufferCollectionFUCHSIA)(VkDevice device, const VkBufferCollectionCreateInfoFUCHSIA* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkBufferCollectionFUCHSIA* pCollection); +typedef VkResult (VKAPI_PTR *PFN_vkSetBufferCollectionImageConstraintsFUCHSIA)(VkDevice device, VkBufferCollectionFUCHSIA collection, const VkImageConstraintsInfoFUCHSIA* pImageConstraintsInfo); +typedef VkResult (VKAPI_PTR *PFN_vkSetBufferCollectionBufferConstraintsFUCHSIA)(VkDevice device, VkBufferCollectionFUCHSIA collection, const VkBufferConstraintsInfoFUCHSIA* pBufferConstraintsInfo); +typedef void (VKAPI_PTR *PFN_vkDestroyBufferCollectionFUCHSIA)(VkDevice device, VkBufferCollectionFUCHSIA collection, const VkAllocationCallbacks* pAllocator); +typedef VkResult (VKAPI_PTR *PFN_vkGetBufferCollectionPropertiesFUCHSIA)(VkDevice device, VkBufferCollectionFUCHSIA collection, VkBufferCollectionPropertiesFUCHSIA* pProperties); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateBufferCollectionFUCHSIA( + VkDevice device, + const VkBufferCollectionCreateInfoFUCHSIA* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkBufferCollectionFUCHSIA* pCollection); + +VKAPI_ATTR VkResult VKAPI_CALL vkSetBufferCollectionImageConstraintsFUCHSIA( + VkDevice device, + VkBufferCollectionFUCHSIA collection, + const VkImageConstraintsInfoFUCHSIA* pImageConstraintsInfo); + +VKAPI_ATTR VkResult VKAPI_CALL vkSetBufferCollectionBufferConstraintsFUCHSIA( + VkDevice device, + VkBufferCollectionFUCHSIA collection, + const VkBufferConstraintsInfoFUCHSIA* pBufferConstraintsInfo); + +VKAPI_ATTR void VKAPI_CALL vkDestroyBufferCollectionFUCHSIA( + VkDevice device, + VkBufferCollectionFUCHSIA collection, + const VkAllocationCallbacks* pAllocator); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetBufferCollectionPropertiesFUCHSIA( + VkDevice device, + VkBufferCollectionFUCHSIA collection, + VkBufferCollectionPropertiesFUCHSIA* pProperties); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/SDL2-2.30.5/src/video/khronos/vulkan/vulkan_ggp.h b/SDL2-2.30.5/src/video/khronos/vulkan/vulkan_ggp.h new file mode 100644 index 0000000..0a8863a --- /dev/null +++ b/SDL2-2.30.5/src/video/khronos/vulkan/vulkan_ggp.h @@ -0,0 +1,60 @@ +#ifndef VULKAN_GGP_H_ +#define VULKAN_GGP_H_ 1 + +/* +** Copyright 2015-2024 The Khronos Group Inc. +** +** SPDX-License-Identifier: Apache-2.0 +*/ + +/* +** This header is generated from the Khronos Vulkan XML API Registry. +** +*/ + + +#ifdef __cplusplus +extern "C" { +#endif + + + +// VK_GGP_stream_descriptor_surface is a preprocessor guard. Do not pass it to API calls. +#define VK_GGP_stream_descriptor_surface 1 +#define VK_GGP_STREAM_DESCRIPTOR_SURFACE_SPEC_VERSION 1 +#define VK_GGP_STREAM_DESCRIPTOR_SURFACE_EXTENSION_NAME "VK_GGP_stream_descriptor_surface" +typedef VkFlags VkStreamDescriptorSurfaceCreateFlagsGGP; +typedef struct VkStreamDescriptorSurfaceCreateInfoGGP { + VkStructureType sType; + const void* pNext; + VkStreamDescriptorSurfaceCreateFlagsGGP flags; + GgpStreamDescriptor streamDescriptor; +} VkStreamDescriptorSurfaceCreateInfoGGP; + +typedef VkResult (VKAPI_PTR *PFN_vkCreateStreamDescriptorSurfaceGGP)(VkInstance instance, const VkStreamDescriptorSurfaceCreateInfoGGP* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateStreamDescriptorSurfaceGGP( + VkInstance instance, + const VkStreamDescriptorSurfaceCreateInfoGGP* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface); +#endif + + +// VK_GGP_frame_token is a preprocessor guard. Do not pass it to API calls. +#define VK_GGP_frame_token 1 +#define VK_GGP_FRAME_TOKEN_SPEC_VERSION 1 +#define VK_GGP_FRAME_TOKEN_EXTENSION_NAME "VK_GGP_frame_token" +typedef struct VkPresentFrameTokenGGP { + VkStructureType sType; + const void* pNext; + GgpFrameToken frameToken; +} VkPresentFrameTokenGGP; + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/SDL2-2.0.12/src/video/khronos/vulkan/vulkan_ios.h b/SDL2-2.30.5/src/video/khronos/vulkan/vulkan_ios.h similarity index 62% rename from SDL2-2.0.12/src/video/khronos/vulkan/vulkan_ios.h rename to SDL2-2.30.5/src/video/khronos/vulkan/vulkan_ios.h index a092481..22ed2c0 100644 --- a/SDL2-2.0.12/src/video/khronos/vulkan/vulkan_ios.h +++ b/SDL2-2.30.5/src/video/khronos/vulkan/vulkan_ios.h @@ -1,24 +1,10 @@ #ifndef VULKAN_IOS_H_ #define VULKAN_IOS_H_ 1 -#ifdef __cplusplus -extern "C" { -#endif - /* -** Copyright (c) 2015-2018 The Khronos Group Inc. +** Copyright 2015-2024 The Khronos Group Inc. ** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. +** SPDX-License-Identifier: Apache-2.0 */ /* @@ -27,12 +13,17 @@ extern "C" { */ +#ifdef __cplusplus +extern "C" { +#endif + + + +// VK_MVK_ios_surface is a preprocessor guard. Do not pass it to API calls. #define VK_MVK_ios_surface 1 -#define VK_MVK_IOS_SURFACE_SPEC_VERSION 2 +#define VK_MVK_IOS_SURFACE_SPEC_VERSION 3 #define VK_MVK_IOS_SURFACE_EXTENSION_NAME "VK_MVK_ios_surface" - typedef VkFlags VkIOSSurfaceCreateFlagsMVK; - typedef struct VkIOSSurfaceCreateInfoMVK { VkStructureType sType; const void* pNext; @@ -40,7 +31,6 @@ typedef struct VkIOSSurfaceCreateInfoMVK { const void* pView; } VkIOSSurfaceCreateInfoMVK; - typedef VkResult (VKAPI_PTR *PFN_vkCreateIOSSurfaceMVK)(VkInstance instance, const VkIOSSurfaceCreateInfoMVK* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); #ifndef VK_NO_PROTOTYPES diff --git a/SDL2-2.0.12/src/video/khronos/vulkan/vulkan_macos.h b/SDL2-2.30.5/src/video/khronos/vulkan/vulkan_macos.h similarity index 63% rename from SDL2-2.0.12/src/video/khronos/vulkan/vulkan_macos.h rename to SDL2-2.30.5/src/video/khronos/vulkan/vulkan_macos.h index ff0b701..a7f5613 100644 --- a/SDL2-2.0.12/src/video/khronos/vulkan/vulkan_macos.h +++ b/SDL2-2.30.5/src/video/khronos/vulkan/vulkan_macos.h @@ -1,24 +1,10 @@ #ifndef VULKAN_MACOS_H_ #define VULKAN_MACOS_H_ 1 -#ifdef __cplusplus -extern "C" { -#endif - /* -** Copyright (c) 2015-2018 The Khronos Group Inc. +** Copyright 2015-2024 The Khronos Group Inc. ** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. +** SPDX-License-Identifier: Apache-2.0 */ /* @@ -27,12 +13,17 @@ extern "C" { */ +#ifdef __cplusplus +extern "C" { +#endif + + + +// VK_MVK_macos_surface is a preprocessor guard. Do not pass it to API calls. #define VK_MVK_macos_surface 1 -#define VK_MVK_MACOS_SURFACE_SPEC_VERSION 2 +#define VK_MVK_MACOS_SURFACE_SPEC_VERSION 3 #define VK_MVK_MACOS_SURFACE_EXTENSION_NAME "VK_MVK_macos_surface" - typedef VkFlags VkMacOSSurfaceCreateFlagsMVK; - typedef struct VkMacOSSurfaceCreateInfoMVK { VkStructureType sType; const void* pNext; @@ -40,7 +31,6 @@ typedef struct VkMacOSSurfaceCreateInfoMVK { const void* pView; } VkMacOSSurfaceCreateInfoMVK; - typedef VkResult (VKAPI_PTR *PFN_vkCreateMacOSSurfaceMVK)(VkInstance instance, const VkMacOSSurfaceCreateInfoMVK* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); #ifndef VK_NO_PROTOTYPES diff --git a/SDL2-2.30.5/src/video/khronos/vulkan/vulkan_metal.h b/SDL2-2.30.5/src/video/khronos/vulkan/vulkan_metal.h new file mode 100644 index 0000000..badb450 --- /dev/null +++ b/SDL2-2.30.5/src/video/khronos/vulkan/vulkan_metal.h @@ -0,0 +1,203 @@ +#ifndef VULKAN_METAL_H_ +#define VULKAN_METAL_H_ 1 + +/* +** Copyright 2015-2024 The Khronos Group Inc. +** +** SPDX-License-Identifier: Apache-2.0 +*/ + +/* +** This header is generated from the Khronos Vulkan XML API Registry. +** +*/ + + +#ifdef __cplusplus +extern "C" { +#endif + + + +// VK_EXT_metal_surface is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_metal_surface 1 +#ifdef __OBJC__ +@class CAMetalLayer; +#else +typedef void CAMetalLayer; +#endif + +#define SDL_UNSAFE_UNRETAINED +#if defined(__OBJC__) && defined(__has_feature) +#if __has_feature(objc_arc) +#undef SDL_UNSAFE_UNRETAINED +#define SDL_UNSAFE_UNRETAINED __unsafe_unretained +#endif +#endif + +#define VK_EXT_METAL_SURFACE_SPEC_VERSION 1 +#define VK_EXT_METAL_SURFACE_EXTENSION_NAME "VK_EXT_metal_surface" +typedef VkFlags VkMetalSurfaceCreateFlagsEXT; +typedef struct VkMetalSurfaceCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkMetalSurfaceCreateFlagsEXT flags; + const CAMetalLayer SDL_UNSAFE_UNRETAINED *pLayer; +} VkMetalSurfaceCreateInfoEXT; + +typedef VkResult (VKAPI_PTR *PFN_vkCreateMetalSurfaceEXT)(VkInstance instance, const VkMetalSurfaceCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateMetalSurfaceEXT( + VkInstance instance, + const VkMetalSurfaceCreateInfoEXT* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface); +#endif + + +// VK_EXT_metal_objects is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_metal_objects 1 +#ifdef __OBJC__ +@protocol MTLDevice; +typedef id MTLDevice_id; +#else +typedef void* MTLDevice_id; +#endif + +#ifdef __OBJC__ +@protocol MTLCommandQueue; +typedef id MTLCommandQueue_id; +#else +typedef void* MTLCommandQueue_id; +#endif + +#ifdef __OBJC__ +@protocol MTLBuffer; +typedef id MTLBuffer_id; +#else +typedef void* MTLBuffer_id; +#endif + +#ifdef __OBJC__ +@protocol MTLTexture; +typedef id MTLTexture_id; +#else +typedef void* MTLTexture_id; +#endif + +typedef struct __IOSurface* IOSurfaceRef; +#ifdef __OBJC__ +@protocol MTLSharedEvent; +typedef id MTLSharedEvent_id; +#else +typedef void* MTLSharedEvent_id; +#endif + +#define VK_EXT_METAL_OBJECTS_SPEC_VERSION 1 +#define VK_EXT_METAL_OBJECTS_EXTENSION_NAME "VK_EXT_metal_objects" + +typedef enum VkExportMetalObjectTypeFlagBitsEXT { + VK_EXPORT_METAL_OBJECT_TYPE_METAL_DEVICE_BIT_EXT = 0x00000001, + VK_EXPORT_METAL_OBJECT_TYPE_METAL_COMMAND_QUEUE_BIT_EXT = 0x00000002, + VK_EXPORT_METAL_OBJECT_TYPE_METAL_BUFFER_BIT_EXT = 0x00000004, + VK_EXPORT_METAL_OBJECT_TYPE_METAL_TEXTURE_BIT_EXT = 0x00000008, + VK_EXPORT_METAL_OBJECT_TYPE_METAL_IOSURFACE_BIT_EXT = 0x00000010, + VK_EXPORT_METAL_OBJECT_TYPE_METAL_SHARED_EVENT_BIT_EXT = 0x00000020, + VK_EXPORT_METAL_OBJECT_TYPE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF +} VkExportMetalObjectTypeFlagBitsEXT; +typedef VkFlags VkExportMetalObjectTypeFlagsEXT; +typedef struct VkExportMetalObjectCreateInfoEXT { + VkStructureType sType; + const void* pNext; + VkExportMetalObjectTypeFlagBitsEXT exportObjectType; +} VkExportMetalObjectCreateInfoEXT; + +typedef struct VkExportMetalObjectsInfoEXT { + VkStructureType sType; + const void* pNext; +} VkExportMetalObjectsInfoEXT; + +typedef struct VkExportMetalDeviceInfoEXT { + VkStructureType sType; + const void* pNext; + MTLDevice_id SDL_UNSAFE_UNRETAINED mtlDevice; +} VkExportMetalDeviceInfoEXT; + +typedef struct VkExportMetalCommandQueueInfoEXT { + VkStructureType sType; + const void* pNext; + VkQueue queue; + MTLCommandQueue_id SDL_UNSAFE_UNRETAINED mtlCommandQueue; +} VkExportMetalCommandQueueInfoEXT; + +typedef struct VkExportMetalBufferInfoEXT { + VkStructureType sType; + const void* pNext; + VkDeviceMemory memory; + MTLBuffer_id SDL_UNSAFE_UNRETAINED mtlBuffer; +} VkExportMetalBufferInfoEXT; + +typedef struct VkImportMetalBufferInfoEXT { + VkStructureType sType; + const void* pNext; + MTLBuffer_id SDL_UNSAFE_UNRETAINED mtlBuffer; +} VkImportMetalBufferInfoEXT; + +typedef struct VkExportMetalTextureInfoEXT { + VkStructureType sType; + const void* pNext; + VkImage image; + VkImageView imageView; + VkBufferView bufferView; + VkImageAspectFlagBits plane; + MTLTexture_id SDL_UNSAFE_UNRETAINED mtlTexture; +} VkExportMetalTextureInfoEXT; + +typedef struct VkImportMetalTextureInfoEXT { + VkStructureType sType; + const void* pNext; + VkImageAspectFlagBits plane; + MTLTexture_id SDL_UNSAFE_UNRETAINED mtlTexture; +} VkImportMetalTextureInfoEXT; + +typedef struct VkExportMetalIOSurfaceInfoEXT { + VkStructureType sType; + const void* pNext; + VkImage image; + IOSurfaceRef ioSurface; +} VkExportMetalIOSurfaceInfoEXT; + +typedef struct VkImportMetalIOSurfaceInfoEXT { + VkStructureType sType; + const void* pNext; + IOSurfaceRef ioSurface; +} VkImportMetalIOSurfaceInfoEXT; + +typedef struct VkExportMetalSharedEventInfoEXT { + VkStructureType sType; + const void* pNext; + VkSemaphore semaphore; + VkEvent event; + MTLSharedEvent_id SDL_UNSAFE_UNRETAINED mtlSharedEvent; +} VkExportMetalSharedEventInfoEXT; + +typedef struct VkImportMetalSharedEventInfoEXT { + VkStructureType sType; + const void* pNext; + MTLSharedEvent_id SDL_UNSAFE_UNRETAINED mtlSharedEvent; +} VkImportMetalSharedEventInfoEXT; + +typedef void (VKAPI_PTR *PFN_vkExportMetalObjectsEXT)(VkDevice device, VkExportMetalObjectsInfoEXT* pMetalObjectsInfo); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR void VKAPI_CALL vkExportMetalObjectsEXT( + VkDevice device, + VkExportMetalObjectsInfoEXT* pMetalObjectsInfo); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/SDL2-2.30.5/src/video/khronos/vulkan/vulkan_screen.h b/SDL2-2.30.5/src/video/khronos/vulkan/vulkan_screen.h new file mode 100644 index 0000000..7e84d4d --- /dev/null +++ b/SDL2-2.30.5/src/video/khronos/vulkan/vulkan_screen.h @@ -0,0 +1,108 @@ +#ifndef VULKAN_SCREEN_H_ +#define VULKAN_SCREEN_H_ 1 + +/* +** Copyright 2015-2024 The Khronos Group Inc. +** +** SPDX-License-Identifier: Apache-2.0 +*/ + +/* +** This header is generated from the Khronos Vulkan XML API Registry. +** +*/ + + +#ifdef __cplusplus +extern "C" { +#endif + + + +// VK_QNX_screen_surface is a preprocessor guard. Do not pass it to API calls. +#define VK_QNX_screen_surface 1 +#define VK_QNX_SCREEN_SURFACE_SPEC_VERSION 1 +#define VK_QNX_SCREEN_SURFACE_EXTENSION_NAME "VK_QNX_screen_surface" +typedef VkFlags VkScreenSurfaceCreateFlagsQNX; +typedef struct VkScreenSurfaceCreateInfoQNX { + VkStructureType sType; + const void* pNext; + VkScreenSurfaceCreateFlagsQNX flags; + struct _screen_context* context; + struct _screen_window* window; +} VkScreenSurfaceCreateInfoQNX; + +typedef VkResult (VKAPI_PTR *PFN_vkCreateScreenSurfaceQNX)(VkInstance instance, const VkScreenSurfaceCreateInfoQNX* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); +typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceScreenPresentationSupportQNX)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, struct _screen_window* window); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkCreateScreenSurfaceQNX( + VkInstance instance, + const VkScreenSurfaceCreateInfoQNX* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkSurfaceKHR* pSurface); + +VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceScreenPresentationSupportQNX( + VkPhysicalDevice physicalDevice, + uint32_t queueFamilyIndex, + struct _screen_window* window); +#endif + + +// VK_QNX_external_memory_screen_buffer is a preprocessor guard. Do not pass it to API calls. +#define VK_QNX_external_memory_screen_buffer 1 +#define VK_QNX_EXTERNAL_MEMORY_SCREEN_BUFFER_SPEC_VERSION 1 +#define VK_QNX_EXTERNAL_MEMORY_SCREEN_BUFFER_EXTENSION_NAME "VK_QNX_external_memory_screen_buffer" +typedef struct VkScreenBufferPropertiesQNX { + VkStructureType sType; + void* pNext; + VkDeviceSize allocationSize; + uint32_t memoryTypeBits; +} VkScreenBufferPropertiesQNX; + +typedef struct VkScreenBufferFormatPropertiesQNX { + VkStructureType sType; + void* pNext; + VkFormat format; + uint64_t externalFormat; + uint64_t screenUsage; + VkFormatFeatureFlags formatFeatures; + VkComponentMapping samplerYcbcrConversionComponents; + VkSamplerYcbcrModelConversion suggestedYcbcrModel; + VkSamplerYcbcrRange suggestedYcbcrRange; + VkChromaLocation suggestedXChromaOffset; + VkChromaLocation suggestedYChromaOffset; +} VkScreenBufferFormatPropertiesQNX; + +typedef struct VkImportScreenBufferInfoQNX { + VkStructureType sType; + const void* pNext; + struct _screen_buffer* buffer; +} VkImportScreenBufferInfoQNX; + +typedef struct VkExternalFormatQNX { + VkStructureType sType; + void* pNext; + uint64_t externalFormat; +} VkExternalFormatQNX; + +typedef struct VkPhysicalDeviceExternalMemoryScreenBufferFeaturesQNX { + VkStructureType sType; + void* pNext; + VkBool32 screenBufferImport; +} VkPhysicalDeviceExternalMemoryScreenBufferFeaturesQNX; + +typedef VkResult (VKAPI_PTR *PFN_vkGetScreenBufferPropertiesQNX)(VkDevice device, const struct _screen_buffer* buffer, VkScreenBufferPropertiesQNX* pProperties); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetScreenBufferPropertiesQNX( + VkDevice device, + const struct _screen_buffer* buffer, + VkScreenBufferPropertiesQNX* pProperties); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/SDL2-2.0.12/src/video/khronos/vulkan/vulkan_vi.h b/SDL2-2.30.5/src/video/khronos/vulkan/vulkan_vi.h similarity index 64% rename from SDL2-2.0.12/src/video/khronos/vulkan/vulkan_vi.h rename to SDL2-2.30.5/src/video/khronos/vulkan/vulkan_vi.h index 015166b..c145f4a 100644 --- a/SDL2-2.0.12/src/video/khronos/vulkan/vulkan_vi.h +++ b/SDL2-2.30.5/src/video/khronos/vulkan/vulkan_vi.h @@ -1,24 +1,10 @@ #ifndef VULKAN_VI_H_ #define VULKAN_VI_H_ 1 -#ifdef __cplusplus -extern "C" { -#endif - /* -** Copyright (c) 2015-2018 The Khronos Group Inc. +** Copyright 2015-2024 The Khronos Group Inc. ** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. +** SPDX-License-Identifier: Apache-2.0 */ /* @@ -27,12 +13,17 @@ extern "C" { */ +#ifdef __cplusplus +extern "C" { +#endif + + + +// VK_NN_vi_surface is a preprocessor guard. Do not pass it to API calls. #define VK_NN_vi_surface 1 #define VK_NN_VI_SURFACE_SPEC_VERSION 1 #define VK_NN_VI_SURFACE_EXTENSION_NAME "VK_NN_vi_surface" - typedef VkFlags VkViSurfaceCreateFlagsNN; - typedef struct VkViSurfaceCreateInfoNN { VkStructureType sType; const void* pNext; @@ -40,7 +31,6 @@ typedef struct VkViSurfaceCreateInfoNN { void* window; } VkViSurfaceCreateInfoNN; - typedef VkResult (VKAPI_PTR *PFN_vkCreateViSurfaceNN)(VkInstance instance, const VkViSurfaceCreateInfoNN* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); #ifndef VK_NO_PROTOTYPES diff --git a/SDL2-2.0.12/src/video/khronos/vulkan/vulkan_wayland.h b/SDL2-2.30.5/src/video/khronos/vulkan/vulkan_wayland.h similarity index 73% rename from SDL2-2.0.12/src/video/khronos/vulkan/vulkan_wayland.h rename to SDL2-2.30.5/src/video/khronos/vulkan/vulkan_wayland.h index 5ba0827..ec706a1 100644 --- a/SDL2-2.0.12/src/video/khronos/vulkan/vulkan_wayland.h +++ b/SDL2-2.30.5/src/video/khronos/vulkan/vulkan_wayland.h @@ -1,24 +1,10 @@ #ifndef VULKAN_WAYLAND_H_ #define VULKAN_WAYLAND_H_ 1 -#ifdef __cplusplus -extern "C" { -#endif - /* -** Copyright (c) 2015-2018 The Khronos Group Inc. +** Copyright 2015-2024 The Khronos Group Inc. ** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. +** SPDX-License-Identifier: Apache-2.0 */ /* @@ -27,12 +13,17 @@ extern "C" { */ +#ifdef __cplusplus +extern "C" { +#endif + + + +// VK_KHR_wayland_surface is a preprocessor guard. Do not pass it to API calls. #define VK_KHR_wayland_surface 1 #define VK_KHR_WAYLAND_SURFACE_SPEC_VERSION 6 #define VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME "VK_KHR_wayland_surface" - typedef VkFlags VkWaylandSurfaceCreateFlagsKHR; - typedef struct VkWaylandSurfaceCreateInfoKHR { VkStructureType sType; const void* pNext; @@ -41,7 +32,6 @@ typedef struct VkWaylandSurfaceCreateInfoKHR { struct wl_surface* surface; } VkWaylandSurfaceCreateInfoKHR; - typedef VkResult (VKAPI_PTR *PFN_vkCreateWaylandSurfaceKHR)(VkInstance instance, const VkWaylandSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, struct wl_display* display); diff --git a/SDL2-2.0.12/src/video/khronos/vulkan/vulkan_win32.h b/SDL2-2.30.5/src/video/khronos/vulkan/vulkan_win32.h similarity index 70% rename from SDL2-2.0.12/src/video/khronos/vulkan/vulkan_win32.h rename to SDL2-2.30.5/src/video/khronos/vulkan/vulkan_win32.h index 6a85409..d7a0b2b 100644 --- a/SDL2-2.0.12/src/video/khronos/vulkan/vulkan_win32.h +++ b/SDL2-2.30.5/src/video/khronos/vulkan/vulkan_win32.h @@ -1,24 +1,10 @@ #ifndef VULKAN_WIN32_H_ #define VULKAN_WIN32_H_ 1 -#ifdef __cplusplus -extern "C" { -#endif - /* -** Copyright (c) 2015-2018 The Khronos Group Inc. +** Copyright 2015-2024 The Khronos Group Inc. ** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. +** SPDX-License-Identifier: Apache-2.0 */ /* @@ -27,12 +13,17 @@ extern "C" { */ +#ifdef __cplusplus +extern "C" { +#endif + + + +// VK_KHR_win32_surface is a preprocessor guard. Do not pass it to API calls. #define VK_KHR_win32_surface 1 #define VK_KHR_WIN32_SURFACE_SPEC_VERSION 6 #define VK_KHR_WIN32_SURFACE_EXTENSION_NAME "VK_KHR_win32_surface" - typedef VkFlags VkWin32SurfaceCreateFlagsKHR; - typedef struct VkWin32SurfaceCreateInfoKHR { VkStructureType sType; const void* pNext; @@ -41,7 +32,6 @@ typedef struct VkWin32SurfaceCreateInfoKHR { HWND hwnd; } VkWin32SurfaceCreateInfoKHR; - typedef VkResult (VKAPI_PTR *PFN_vkCreateWin32SurfaceKHR)(VkInstance instance, const VkWin32SurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex); @@ -57,10 +47,11 @@ VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWin32PresentationSupportKHR( uint32_t queueFamilyIndex); #endif + +// VK_KHR_external_memory_win32 is a preprocessor guard. Do not pass it to API calls. #define VK_KHR_external_memory_win32 1 #define VK_KHR_EXTERNAL_MEMORY_WIN32_SPEC_VERSION 1 #define VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME "VK_KHR_external_memory_win32" - typedef struct VkImportMemoryWin32HandleInfoKHR { VkStructureType sType; const void* pNext; @@ -90,7 +81,6 @@ typedef struct VkMemoryGetWin32HandleInfoKHR { VkExternalMemoryHandleTypeFlagBits handleType; } VkMemoryGetWin32HandleInfoKHR; - typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryWin32HandleKHR)(VkDevice device, const VkMemoryGetWin32HandleInfoKHR* pGetWin32HandleInfo, HANDLE* pHandle); typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryWin32HandlePropertiesKHR)(VkDevice device, VkExternalMemoryHandleTypeFlagBits handleType, HANDLE handle, VkMemoryWin32HandlePropertiesKHR* pMemoryWin32HandleProperties); @@ -107,10 +97,11 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryWin32HandlePropertiesKHR( VkMemoryWin32HandlePropertiesKHR* pMemoryWin32HandleProperties); #endif + +// VK_KHR_win32_keyed_mutex is a preprocessor guard. Do not pass it to API calls. #define VK_KHR_win32_keyed_mutex 1 #define VK_KHR_WIN32_KEYED_MUTEX_SPEC_VERSION 1 #define VK_KHR_WIN32_KEYED_MUTEX_EXTENSION_NAME "VK_KHR_win32_keyed_mutex" - typedef struct VkWin32KeyedMutexAcquireReleaseInfoKHR { VkStructureType sType; const void* pNext; @@ -125,10 +116,10 @@ typedef struct VkWin32KeyedMutexAcquireReleaseInfoKHR { +// VK_KHR_external_semaphore_win32 is a preprocessor guard. Do not pass it to API calls. #define VK_KHR_external_semaphore_win32 1 #define VK_KHR_EXTERNAL_SEMAPHORE_WIN32_SPEC_VERSION 1 #define VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME "VK_KHR_external_semaphore_win32" - typedef struct VkImportSemaphoreWin32HandleInfoKHR { VkStructureType sType; const void* pNext; @@ -163,7 +154,6 @@ typedef struct VkSemaphoreGetWin32HandleInfoKHR { VkExternalSemaphoreHandleTypeFlagBits handleType; } VkSemaphoreGetWin32HandleInfoKHR; - typedef VkResult (VKAPI_PTR *PFN_vkImportSemaphoreWin32HandleKHR)(VkDevice device, const VkImportSemaphoreWin32HandleInfoKHR* pImportSemaphoreWin32HandleInfo); typedef VkResult (VKAPI_PTR *PFN_vkGetSemaphoreWin32HandleKHR)(VkDevice device, const VkSemaphoreGetWin32HandleInfoKHR* pGetWin32HandleInfo, HANDLE* pHandle); @@ -178,10 +168,11 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetSemaphoreWin32HandleKHR( HANDLE* pHandle); #endif + +// VK_KHR_external_fence_win32 is a preprocessor guard. Do not pass it to API calls. #define VK_KHR_external_fence_win32 1 #define VK_KHR_EXTERNAL_FENCE_WIN32_SPEC_VERSION 1 #define VK_KHR_EXTERNAL_FENCE_WIN32_EXTENSION_NAME "VK_KHR_external_fence_win32" - typedef struct VkImportFenceWin32HandleInfoKHR { VkStructureType sType; const void* pNext; @@ -207,7 +198,6 @@ typedef struct VkFenceGetWin32HandleInfoKHR { VkExternalFenceHandleTypeFlagBits handleType; } VkFenceGetWin32HandleInfoKHR; - typedef VkResult (VKAPI_PTR *PFN_vkImportFenceWin32HandleKHR)(VkDevice device, const VkImportFenceWin32HandleInfoKHR* pImportFenceWin32HandleInfo); typedef VkResult (VKAPI_PTR *PFN_vkGetFenceWin32HandleKHR)(VkDevice device, const VkFenceGetWin32HandleInfoKHR* pGetWin32HandleInfo, HANDLE* pHandle); @@ -222,10 +212,11 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetFenceWin32HandleKHR( HANDLE* pHandle); #endif + +// VK_NV_external_memory_win32 is a preprocessor guard. Do not pass it to API calls. #define VK_NV_external_memory_win32 1 #define VK_NV_EXTERNAL_MEMORY_WIN32_SPEC_VERSION 1 #define VK_NV_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME "VK_NV_external_memory_win32" - typedef struct VkImportMemoryWin32HandleInfoNV { VkStructureType sType; const void* pNext; @@ -240,7 +231,6 @@ typedef struct VkExportMemoryWin32HandleInfoNV { DWORD dwAccess; } VkExportMemoryWin32HandleInfoNV; - typedef VkResult (VKAPI_PTR *PFN_vkGetMemoryWin32HandleNV)(VkDevice device, VkDeviceMemory memory, VkExternalMemoryHandleTypeFlagsNV handleType, HANDLE* pHandle); #ifndef VK_NO_PROTOTYPES @@ -251,10 +241,11 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryWin32HandleNV( HANDLE* pHandle); #endif -#define VK_NV_win32_keyed_mutex 1 -#define VK_NV_WIN32_KEYED_MUTEX_SPEC_VERSION 1 -#define VK_NV_WIN32_KEYED_MUTEX_EXTENSION_NAME "VK_NV_win32_keyed_mutex" +// VK_NV_win32_keyed_mutex is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_win32_keyed_mutex 1 +#define VK_NV_WIN32_KEYED_MUTEX_SPEC_VERSION 2 +#define VK_NV_WIN32_KEYED_MUTEX_EXTENSION_NAME "VK_NV_win32_keyed_mutex" typedef struct VkWin32KeyedMutexAcquireReleaseInfoNV { VkStructureType sType; const void* pNext; @@ -269,6 +260,81 @@ typedef struct VkWin32KeyedMutexAcquireReleaseInfoNV { +// VK_EXT_full_screen_exclusive is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_full_screen_exclusive 1 +#define VK_EXT_FULL_SCREEN_EXCLUSIVE_SPEC_VERSION 4 +#define VK_EXT_FULL_SCREEN_EXCLUSIVE_EXTENSION_NAME "VK_EXT_full_screen_exclusive" + +typedef enum VkFullScreenExclusiveEXT { + VK_FULL_SCREEN_EXCLUSIVE_DEFAULT_EXT = 0, + VK_FULL_SCREEN_EXCLUSIVE_ALLOWED_EXT = 1, + VK_FULL_SCREEN_EXCLUSIVE_DISALLOWED_EXT = 2, + VK_FULL_SCREEN_EXCLUSIVE_APPLICATION_CONTROLLED_EXT = 3, + VK_FULL_SCREEN_EXCLUSIVE_MAX_ENUM_EXT = 0x7FFFFFFF +} VkFullScreenExclusiveEXT; +typedef struct VkSurfaceFullScreenExclusiveInfoEXT { + VkStructureType sType; + void* pNext; + VkFullScreenExclusiveEXT fullScreenExclusive; +} VkSurfaceFullScreenExclusiveInfoEXT; + +typedef struct VkSurfaceCapabilitiesFullScreenExclusiveEXT { + VkStructureType sType; + void* pNext; + VkBool32 fullScreenExclusiveSupported; +} VkSurfaceCapabilitiesFullScreenExclusiveEXT; + +typedef struct VkSurfaceFullScreenExclusiveWin32InfoEXT { + VkStructureType sType; + const void* pNext; + HMONITOR hmonitor; +} VkSurfaceFullScreenExclusiveWin32InfoEXT; + +typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfacePresentModes2EXT)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, uint32_t* pPresentModeCount, VkPresentModeKHR* pPresentModes); +typedef VkResult (VKAPI_PTR *PFN_vkAcquireFullScreenExclusiveModeEXT)(VkDevice device, VkSwapchainKHR swapchain); +typedef VkResult (VKAPI_PTR *PFN_vkReleaseFullScreenExclusiveModeEXT)(VkDevice device, VkSwapchainKHR swapchain); +typedef VkResult (VKAPI_PTR *PFN_vkGetDeviceGroupSurfacePresentModes2EXT)(VkDevice device, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, VkDeviceGroupPresentModeFlagsKHR* pModes); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfacePresentModes2EXT( + VkPhysicalDevice physicalDevice, + const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, + uint32_t* pPresentModeCount, + VkPresentModeKHR* pPresentModes); + +VKAPI_ATTR VkResult VKAPI_CALL vkAcquireFullScreenExclusiveModeEXT( + VkDevice device, + VkSwapchainKHR swapchain); + +VKAPI_ATTR VkResult VKAPI_CALL vkReleaseFullScreenExclusiveModeEXT( + VkDevice device, + VkSwapchainKHR swapchain); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetDeviceGroupSurfacePresentModes2EXT( + VkDevice device, + const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, + VkDeviceGroupPresentModeFlagsKHR* pModes); +#endif + + +// VK_NV_acquire_winrt_display is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_acquire_winrt_display 1 +#define VK_NV_ACQUIRE_WINRT_DISPLAY_SPEC_VERSION 1 +#define VK_NV_ACQUIRE_WINRT_DISPLAY_EXTENSION_NAME "VK_NV_acquire_winrt_display" +typedef VkResult (VKAPI_PTR *PFN_vkAcquireWinrtDisplayNV)(VkPhysicalDevice physicalDevice, VkDisplayKHR display); +typedef VkResult (VKAPI_PTR *PFN_vkGetWinrtDisplayNV)(VkPhysicalDevice physicalDevice, uint32_t deviceRelativeId, VkDisplayKHR* pDisplay); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkAcquireWinrtDisplayNV( + VkPhysicalDevice physicalDevice, + VkDisplayKHR display); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetWinrtDisplayNV( + VkPhysicalDevice physicalDevice, + uint32_t deviceRelativeId, + VkDisplayKHR* pDisplay); +#endif + #ifdef __cplusplus } #endif diff --git a/SDL2-2.0.12/src/video/khronos/vulkan/vulkan_xcb.h b/SDL2-2.30.5/src/video/khronos/vulkan/vulkan_xcb.h similarity index 73% rename from SDL2-2.0.12/src/video/khronos/vulkan/vulkan_xcb.h rename to SDL2-2.30.5/src/video/khronos/vulkan/vulkan_xcb.h index ba03600..cdf6b52 100644 --- a/SDL2-2.0.12/src/video/khronos/vulkan/vulkan_xcb.h +++ b/SDL2-2.30.5/src/video/khronos/vulkan/vulkan_xcb.h @@ -1,24 +1,10 @@ #ifndef VULKAN_XCB_H_ #define VULKAN_XCB_H_ 1 -#ifdef __cplusplus -extern "C" { -#endif - /* -** Copyright (c) 2015-2018 The Khronos Group Inc. +** Copyright 2015-2024 The Khronos Group Inc. ** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. +** SPDX-License-Identifier: Apache-2.0 */ /* @@ -27,12 +13,17 @@ extern "C" { */ +#ifdef __cplusplus +extern "C" { +#endif + + + +// VK_KHR_xcb_surface is a preprocessor guard. Do not pass it to API calls. #define VK_KHR_xcb_surface 1 #define VK_KHR_XCB_SURFACE_SPEC_VERSION 6 #define VK_KHR_XCB_SURFACE_EXTENSION_NAME "VK_KHR_xcb_surface" - typedef VkFlags VkXcbSurfaceCreateFlagsKHR; - typedef struct VkXcbSurfaceCreateInfoKHR { VkStructureType sType; const void* pNext; @@ -41,7 +32,6 @@ typedef struct VkXcbSurfaceCreateInfoKHR { xcb_window_t window; } VkXcbSurfaceCreateInfoKHR; - typedef VkResult (VKAPI_PTR *PFN_vkCreateXcbSurfaceKHR)(VkInstance instance, const VkXcbSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, xcb_connection_t* connection, xcb_visualid_t visual_id); diff --git a/SDL2-2.0.12/src/video/khronos/vulkan/vulkan_xlib.h b/SDL2-2.30.5/src/video/khronos/vulkan/vulkan_xlib.h similarity index 73% rename from SDL2-2.0.12/src/video/khronos/vulkan/vulkan_xlib.h rename to SDL2-2.30.5/src/video/khronos/vulkan/vulkan_xlib.h index e1d967e..b3c3e27 100644 --- a/SDL2-2.0.12/src/video/khronos/vulkan/vulkan_xlib.h +++ b/SDL2-2.30.5/src/video/khronos/vulkan/vulkan_xlib.h @@ -1,24 +1,10 @@ #ifndef VULKAN_XLIB_H_ #define VULKAN_XLIB_H_ 1 -#ifdef __cplusplus -extern "C" { -#endif - /* -** Copyright (c) 2015-2018 The Khronos Group Inc. +** Copyright 2015-2024 The Khronos Group Inc. ** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. +** SPDX-License-Identifier: Apache-2.0 */ /* @@ -27,12 +13,17 @@ extern "C" { */ +#ifdef __cplusplus +extern "C" { +#endif + + + +// VK_KHR_xlib_surface is a preprocessor guard. Do not pass it to API calls. #define VK_KHR_xlib_surface 1 #define VK_KHR_XLIB_SURFACE_SPEC_VERSION 6 #define VK_KHR_XLIB_SURFACE_EXTENSION_NAME "VK_KHR_xlib_surface" - typedef VkFlags VkXlibSurfaceCreateFlagsKHR; - typedef struct VkXlibSurfaceCreateInfoKHR { VkStructureType sType; const void* pNext; @@ -41,7 +32,6 @@ typedef struct VkXlibSurfaceCreateInfoKHR { Window window; } VkXlibSurfaceCreateInfoKHR; - typedef VkResult (VKAPI_PTR *PFN_vkCreateXlibSurfaceKHR)(VkInstance instance, const VkXlibSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, Display* dpy, VisualID visualID); diff --git a/SDL2-2.0.12/src/video/khronos/vulkan/vulkan_xlib_xrandr.h b/SDL2-2.30.5/src/video/khronos/vulkan/vulkan_xlib_xrandr.h similarity index 67% rename from SDL2-2.0.12/src/video/khronos/vulkan/vulkan_xlib_xrandr.h rename to SDL2-2.30.5/src/video/khronos/vulkan/vulkan_xlib_xrandr.h index 117d017..8e99190 100644 --- a/SDL2-2.0.12/src/video/khronos/vulkan/vulkan_xlib_xrandr.h +++ b/SDL2-2.30.5/src/video/khronos/vulkan/vulkan_xlib_xrandr.h @@ -1,24 +1,10 @@ #ifndef VULKAN_XLIB_XRANDR_H_ #define VULKAN_XLIB_XRANDR_H_ 1 -#ifdef __cplusplus -extern "C" { -#endif - /* -** Copyright (c) 2015-2018 The Khronos Group Inc. +** Copyright 2015-2024 The Khronos Group Inc. ** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. +** SPDX-License-Identifier: Apache-2.0 */ /* @@ -27,10 +13,16 @@ extern "C" { */ +#ifdef __cplusplus +extern "C" { +#endif + + + +// VK_EXT_acquire_xlib_display is a preprocessor guard. Do not pass it to API calls. #define VK_EXT_acquire_xlib_display 1 #define VK_EXT_ACQUIRE_XLIB_DISPLAY_SPEC_VERSION 1 #define VK_EXT_ACQUIRE_XLIB_DISPLAY_EXTENSION_NAME "VK_EXT_acquire_xlib_display" - typedef VkResult (VKAPI_PTR *PFN_vkAcquireXlibDisplayEXT)(VkPhysicalDevice physicalDevice, Display* dpy, VkDisplayKHR display); typedef VkResult (VKAPI_PTR *PFN_vkGetRandROutputDisplayEXT)(VkPhysicalDevice physicalDevice, Display* dpy, RROutput rrOutput, VkDisplayKHR* pDisplay); diff --git a/SDL2-2.0.12/src/video/kmsdrm/SDL_kmsdrmdyn.c b/SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmdyn.c similarity index 65% rename from SDL2-2.0.12/src/video/kmsdrm/SDL_kmsdrmdyn.c rename to SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmdyn.c index 9f9a087..750babb 100644 --- a/SDL2-2.0.12/src/video/kmsdrm/SDL_kmsdrmdyn.c +++ b/SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmdyn.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -21,16 +21,12 @@ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_KMSDRM +#ifdef SDL_VIDEO_DRIVER_KMSDRM #define DEBUG_DYNAMIC_KMSDRM 0 #include "SDL_kmsdrmdyn.h" -#if DEBUG_DYNAMIC_KMSDRM -#include "SDL_log.h" -#endif - #ifdef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC #include "SDL_name.h" @@ -42,40 +38,38 @@ typedef struct const char *libname; } kmsdrmdynlib; -#ifndef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC -#define SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC NULL -#endif #ifndef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC_GBM #define SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC_GBM NULL #endif static kmsdrmdynlib kmsdrmlibs[] = { - {NULL, SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC_GBM}, - {NULL, SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC} + { NULL, SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC_GBM }, + { NULL, SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC } }; -static void * -KMSDRM_GetSym(const char *fnname, int *pHasModule) +static void *KMSDRM_GetSym(const char *fnname, int *pHasModule) { int i; void *fn = NULL; for (i = 0; i < SDL_TABLESIZE(kmsdrmlibs); i++) { - if (kmsdrmlibs[i].lib != NULL) { + if (kmsdrmlibs[i].lib) { fn = SDL_LoadFunction(kmsdrmlibs[i].lib, fnname); - if (fn != NULL) + if (fn) { break; + } } } #if DEBUG_DYNAMIC_KMSDRM - if (fn != NULL) + if (fn) SDL_Log("KMSDRM: Found '%s' in %s (%p)\n", fnname, kmsdrmlibs[i].libname, fn); else SDL_Log("KMSDRM: Symbol '%s' NOT FOUND!\n", fnname); #endif - if (fn == NULL) - *pHasModule = 0; /* kill this module. */ + if (!fn) { + *pHasModule = 0; /* kill this module. */ + } return fn; } @@ -83,15 +77,14 @@ KMSDRM_GetSym(const char *fnname, int *pHasModule) #endif /* SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC */ /* Define all the function pointers and wrappers... */ -#define SDL_KMSDRM_MODULE(modname) int SDL_KMSDRM_HAVE_##modname = 0; -#define SDL_KMSDRM_SYM(rc,fn,params) SDL_DYNKMSDRMFN_##fn KMSDRM_##fn = NULL; -#define SDL_KMSDRM_SYM_CONST(type,name) SDL_DYNKMSDRMCONST_##name KMSDRM_##name = NULL; +#define SDL_KMSDRM_MODULE(modname) int SDL_KMSDRM_HAVE_##modname = 0; +#define SDL_KMSDRM_SYM(rc, fn, params) SDL_DYNKMSDRMFN_##fn KMSDRM_##fn = NULL; +#define SDL_KMSDRM_SYM_CONST(type, name) SDL_DYNKMSDRMCONST_##name KMSDRM_##name = NULL; #include "SDL_kmsdrmsym.h" static int kmsdrm_load_refcount = 0; -void -SDL_KMSDRM_UnloadSymbols(void) +void SDL_KMSDRM_UnloadSymbols(void) { /* Don't actually unload if more than one module is using the libs... */ if (kmsdrm_load_refcount > 0) { @@ -101,15 +94,14 @@ SDL_KMSDRM_UnloadSymbols(void) #endif /* set all the function pointers to NULL. */ -#define SDL_KMSDRM_MODULE(modname) SDL_KMSDRM_HAVE_##modname = 0; -#define SDL_KMSDRM_SYM(rc,fn,params) KMSDRM_##fn = NULL; -#define SDL_KMSDRM_SYM_CONST(type,name) KMSDRM_##name = NULL; +#define SDL_KMSDRM_MODULE(modname) SDL_KMSDRM_HAVE_##modname = 0; +#define SDL_KMSDRM_SYM(rc, fn, params) KMSDRM_##fn = NULL; +#define SDL_KMSDRM_SYM_CONST(type, name) KMSDRM_##name = NULL; #include "SDL_kmsdrmsym.h" - #ifdef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC for (i = 0; i < SDL_TABLESIZE(kmsdrmlibs); i++) { - if (kmsdrmlibs[i].lib != NULL) { + if (kmsdrmlibs[i].lib) { SDL_UnloadObject(kmsdrmlibs[i].lib); kmsdrmlibs[i].lib = NULL; } @@ -120,10 +112,9 @@ SDL_KMSDRM_UnloadSymbols(void) } /* returns non-zero if all needed symbols were loaded. */ -int -SDL_KMSDRM_LoadSymbols(void) +int SDL_KMSDRM_LoadSymbols(void) { - int rc = 1; /* always succeed if not using Dynamic KMSDRM stuff. */ + int rc = 1; /* always succeed if not using Dynamic KMSDRM stuff. */ /* deal with multiple modules needing these symbols... */ if (kmsdrm_load_refcount++ == 0) { @@ -131,7 +122,7 @@ SDL_KMSDRM_LoadSymbols(void) int i; int *thismod = NULL; for (i = 0; i < SDL_TABLESIZE(kmsdrmlibs); i++) { - if (kmsdrmlibs[i].libname != NULL) { + if (kmsdrmlibs[i].libname) { kmsdrmlibs[i].lib = SDL_LoadObject(kmsdrmlibs[i].libname); } } @@ -139,9 +130,9 @@ SDL_KMSDRM_LoadSymbols(void) #define SDL_KMSDRM_MODULE(modname) SDL_KMSDRM_HAVE_##modname = 1; /* default yes */ #include "SDL_kmsdrmsym.h" -#define SDL_KMSDRM_MODULE(modname) thismod = &SDL_KMSDRM_HAVE_##modname; -#define SDL_KMSDRM_SYM(rc,fn,params) KMSDRM_##fn = (SDL_DYNKMSDRMFN_##fn) KMSDRM_GetSym(#fn,thismod); -#define SDL_KMSDRM_SYM_CONST(type,name) KMSDRM_##name = *(SDL_DYNKMSDRMCONST_##name*) KMSDRM_GetSym(#name,thismod); +#define SDL_KMSDRM_MODULE(modname) thismod = &SDL_KMSDRM_HAVE_##modname; +#define SDL_KMSDRM_SYM(rc, fn, params) KMSDRM_##fn = (SDL_DYNKMSDRMFN_##fn)KMSDRM_GetSym(#fn, thismod); +#define SDL_KMSDRM_SYM_CONST(type, name) KMSDRM_##name = *(SDL_DYNKMSDRMCONST_##name *)KMSDRM_GetSym(#name, thismod); #include "SDL_kmsdrmsym.h" if ((SDL_KMSDRM_HAVE_LIBDRM) && (SDL_KMSDRM_HAVE_GBM)) { @@ -153,11 +144,11 @@ SDL_KMSDRM_LoadSymbols(void) rc = 0; } -#else /* no dynamic KMSDRM */ +#else /* no dynamic KMSDRM */ -#define SDL_KMSDRM_MODULE(modname) SDL_KMSDRM_HAVE_##modname = 1; /* default yes */ -#define SDL_KMSDRM_SYM(rc,fn,params) KMSDRM_##fn = fn; -#define SDL_KMSDRM_SYM_CONST(type,name) KMSDRM_##name = name; +#define SDL_KMSDRM_MODULE(modname) SDL_KMSDRM_HAVE_##modname = 1; /* default yes */ +#define SDL_KMSDRM_SYM(rc, fn, params) KMSDRM_##fn = fn; +#define SDL_KMSDRM_SYM_CONST(type, name) KMSDRM_##name = name; #include "SDL_kmsdrmsym.h" #endif diff --git a/SDL2-2.0.12/src/video/kmsdrm/SDL_kmsdrmdyn.h b/SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmdyn.h similarity index 87% rename from SDL2-2.0.12/src/video/kmsdrm/SDL_kmsdrmdyn.h rename to SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmdyn.h index 7f4f0a0..e6da337 100644 --- a/SDL2-2.0.12/src/video/kmsdrm/SDL_kmsdrmdyn.h +++ b/SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmdyn.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -36,10 +36,10 @@ int SDL_KMSDRM_LoadSymbols(void); void SDL_KMSDRM_UnloadSymbols(void); /* Declare all the function pointers and wrappers... */ -#define SDL_KMSDRM_SYM(rc,fn,params) \ - typedef rc (*SDL_DYNKMSDRMFN_##fn) params; \ +#define SDL_KMSDRM_SYM(rc, fn, params) \ + typedef rc(*SDL_DYNKMSDRMFN_##fn) params; \ extern SDL_DYNKMSDRMFN_##fn KMSDRM_##fn; -#define SDL_KMSDRM_SYM_CONST(type, name) \ +#define SDL_KMSDRM_SYM_CONST(type, name) \ typedef type SDL_DYNKMSDRMCONST_##name; \ extern SDL_DYNKMSDRMCONST_##name KMSDRM_##name; #include "SDL_kmsdrmsym.h" diff --git a/SDL2-2.0.12/src/video/kmsdrm/SDL_kmsdrmevents.c b/SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmevents.c similarity index 83% rename from SDL2-2.0.12/src/video/kmsdrm/SDL_kmsdrmevents.c rename to SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmevents.c index 1bf000f..a52f1b6 100644 --- a/SDL2-2.0.12/src/video/kmsdrm/SDL_kmsdrmevents.c +++ b/SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmevents.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -21,22 +21,24 @@ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_KMSDRM +#ifdef SDL_VIDEO_DRIVER_KMSDRM #include "SDL_kmsdrmvideo.h" #include "SDL_kmsdrmevents.h" #ifdef SDL_INPUT_LINUXEV #include "../../core/linux/SDL_evdev.h" +#elif defined SDL_INPUT_WSCONS +#include "../../core/openbsd/SDL_wscons.h" #endif void KMSDRM_PumpEvents(_THIS) { #ifdef SDL_INPUT_LINUXEV SDL_EVDEV_Poll(); +#elif defined SDL_INPUT_WSCONS + SDL_WSCONS_PumpEvents(); #endif - } #endif /* SDL_VIDEO_DRIVER_KMSDRM */ - diff --git a/SDL2-2.0.12/src/video/kmsdrm/SDL_kmsdrmevents.h b/SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmevents.h similarity index 88% rename from SDL2-2.0.12/src/video/kmsdrm/SDL_kmsdrmevents.h rename to SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmevents.h index e850031..74625e3 100644 --- a/SDL2-2.0.12/src/video/kmsdrm/SDL_kmsdrmevents.h +++ b/SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmevents.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -25,7 +25,5 @@ #define SDL_kmsdrmevents_h_ extern void KMSDRM_PumpEvents(_THIS); -extern void KMSDRM_EventInit(_THIS); -extern void KMSDRM_EventQuit(_THIS); #endif /* SDL_kmsdrmevents_h_ */ diff --git a/SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmmouse.c b/SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmmouse.c new file mode 100644 index 0000000..ec01004 --- /dev/null +++ b/SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmmouse.c @@ -0,0 +1,451 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_KMSDRM + +#include "SDL_kmsdrmvideo.h" +#include "SDL_kmsdrmmouse.h" +#include "SDL_kmsdrmdyn.h" + +#include "../../events/SDL_mouse_c.h" +#include "../../events/default_cursor.h" + +#include "../SDL_pixels_c.h" + +static SDL_Cursor *KMSDRM_CreateDefaultCursor(void); +static SDL_Cursor *KMSDRM_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y); +static int KMSDRM_ShowCursor(SDL_Cursor *cursor); +static void KMSDRM_MoveCursor(SDL_Cursor *cursor); +static void KMSDRM_FreeCursor(SDL_Cursor *cursor); +static void KMSDRM_WarpMouse(SDL_Window *window, int x, int y); +static int KMSDRM_WarpMouseGlobal(int x, int y); + +/**************************************************************************************/ +/* BEFORE CODING ANYTHING MOUSE/CURSOR RELATED, REMEMBER THIS. */ +/* How does SDL manage cursors internally? First, mouse =! cursor. The mouse can have */ +/* many cursors in mouse->cursors. */ +/* -SDL tells us to create a cursor with KMSDRM_CreateCursor(). It can create many */ +/* cursosr with this, not only one. */ +/* -SDL stores those cursors in a cursors array, in mouse->cursors. */ +/* -Whenever it wants (or the programmer wants) takes a cursor from that array */ +/* and shows it on screen with KMSDRM_ShowCursor(). */ +/* KMSDRM_ShowCursor() simply shows or hides the cursor it receives: it does NOT */ +/* mind if it's mouse->cur_cursor, etc. */ +/* -If KMSDRM_ShowCursor() returns succesfully, that cursor becomes mouse->cur_cursor */ +/* and mouse->cursor_shown is 1. */ +/**************************************************************************************/ + +static SDL_Cursor *KMSDRM_CreateDefaultCursor(void) +{ + return SDL_CreateCursor(default_cdata, default_cmask, DEFAULT_CWIDTH, DEFAULT_CHEIGHT, DEFAULT_CHOTX, DEFAULT_CHOTY); +} + +/* Given a display's driverdata, destroy the cursor BO for it. + To be called from KMSDRM_DestroyWindow(), as that's where we + destroy the driverdata for the window's display. */ +void KMSDRM_DestroyCursorBO(_THIS, SDL_VideoDisplay *display) +{ + SDL_DisplayData *dispdata = (SDL_DisplayData *)display->driverdata; + + /* Destroy the curso GBM BO. */ + if (dispdata->cursor_bo) { + KMSDRM_gbm_bo_destroy(dispdata->cursor_bo); + dispdata->cursor_bo = NULL; + dispdata->cursor_bo_drm_fd = -1; + } +} + +/* Given a display's driverdata, create the cursor BO for it. + To be called from KMSDRM_CreateWindow(), as that's where we + build a window and assign a display to it. */ +void KMSDRM_CreateCursorBO(SDL_VideoDisplay *display) +{ + + SDL_VideoDevice *dev = SDL_GetVideoDevice(); + SDL_VideoData *viddata = ((SDL_VideoData *)dev->driverdata); + SDL_DisplayData *dispdata = (SDL_DisplayData *)display->driverdata; + + if (!KMSDRM_gbm_device_is_format_supported(viddata->gbm_dev, + GBM_FORMAT_ARGB8888, + GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE)) { + SDL_SetError("Unsupported pixel format for cursor"); + return; + } + + if (KMSDRM_drmGetCap(viddata->drm_fd, + DRM_CAP_CURSOR_WIDTH, &dispdata->cursor_w) || + KMSDRM_drmGetCap(viddata->drm_fd, DRM_CAP_CURSOR_HEIGHT, + &dispdata->cursor_h)) { + SDL_SetError("Could not get the recommended GBM cursor size"); + return; + } + + if (dispdata->cursor_w == 0 || dispdata->cursor_h == 0) { + SDL_SetError("Could not get an usable GBM cursor size"); + return; + } + + dispdata->cursor_bo = KMSDRM_gbm_bo_create(viddata->gbm_dev, + dispdata->cursor_w, dispdata->cursor_h, + GBM_FORMAT_ARGB8888, GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE | GBM_BO_USE_LINEAR); + + if (!dispdata->cursor_bo) { + SDL_SetError("Could not create GBM cursor BO"); + return; + } + + dispdata->cursor_bo_drm_fd = viddata->drm_fd; +} + +/* Remove a cursor buffer from a display's DRM cursor BO. */ +static int KMSDRM_RemoveCursorFromBO(SDL_VideoDisplay *display) +{ + int ret = 0; + SDL_DisplayData *dispdata = (SDL_DisplayData *)display->driverdata; + SDL_VideoDevice *video_device = SDL_GetVideoDevice(); + SDL_VideoData *viddata = ((SDL_VideoData *)video_device->driverdata); + + ret = KMSDRM_drmModeSetCursor(viddata->drm_fd, + dispdata->crtc->crtc_id, 0, 0, 0); + + if (ret) { + ret = SDL_SetError("Could not hide current cursor with drmModeSetCursor()."); + } + + return ret; +} + +/* Dump a cursor buffer to a display's DRM cursor BO. */ +static int KMSDRM_DumpCursorToBO(SDL_VideoDisplay *display, SDL_Cursor *cursor) +{ + SDL_DisplayData *dispdata = (SDL_DisplayData *)display->driverdata; + KMSDRM_CursorData *curdata = (KMSDRM_CursorData *)cursor->driverdata; + SDL_VideoDevice *video_device = SDL_GetVideoDevice(); + SDL_VideoData *viddata = ((SDL_VideoData *)video_device->driverdata); + + uint32_t bo_handle; + size_t bo_stride; + size_t bufsize; + uint8_t *ready_buffer = NULL; + uint8_t *src_row; + + int i; + int ret; + + if (!curdata || !dispdata->cursor_bo) { + return SDL_SetError("Cursor or display not initialized properly."); + } + + /* Prepare a buffer we can dump to our GBM BO (different + size, alpha premultiplication...) */ + bo_stride = KMSDRM_gbm_bo_get_stride(dispdata->cursor_bo); + bufsize = bo_stride * dispdata->cursor_h; + + ready_buffer = (uint8_t *)SDL_calloc(1, bufsize); + + if (!ready_buffer) { + ret = SDL_OutOfMemory(); + goto cleanup; + } + + /* Copy from the cursor buffer to a buffer that we can dump to the GBM BO. */ + for (i = 0; i < curdata->h; i++) { + src_row = &((uint8_t *)curdata->buffer)[i * curdata->w * 4]; + SDL_memcpy(ready_buffer + (i * bo_stride), src_row, (size_t)4 * curdata->w); + } + + /* Dump the cursor buffer to our GBM BO. */ + if (KMSDRM_gbm_bo_write(dispdata->cursor_bo, ready_buffer, bufsize)) { + ret = SDL_SetError("Could not write to GBM cursor BO"); + goto cleanup; + } + + /* Put the GBM BO buffer on screen using the DRM interface. */ + bo_handle = KMSDRM_gbm_bo_get_handle(dispdata->cursor_bo).u32; + if (curdata->hot_x == 0 && curdata->hot_y == 0) { + ret = KMSDRM_drmModeSetCursor(viddata->drm_fd, dispdata->crtc->crtc_id, + bo_handle, dispdata->cursor_w, dispdata->cursor_h); + } else { + ret = KMSDRM_drmModeSetCursor2(viddata->drm_fd, dispdata->crtc->crtc_id, + bo_handle, dispdata->cursor_w, dispdata->cursor_h, curdata->hot_x, curdata->hot_y); + } + + if (ret) { + ret = SDL_SetError("Failed to set DRM cursor."); + goto cleanup; + } + + if (ret) { + ret = SDL_SetError("Failed to reset cursor position."); + goto cleanup; + } + +cleanup: + + if (ready_buffer) { + SDL_free(ready_buffer); + } + return ret; +} + +/* This is only for freeing the SDL_cursor.*/ +static void KMSDRM_FreeCursor(SDL_Cursor *cursor) +{ + KMSDRM_CursorData *curdata; + + /* Even if the cursor is not ours, free it. */ + if (cursor) { + curdata = (KMSDRM_CursorData *)cursor->driverdata; + /* Free cursor buffer */ + if (curdata->buffer) { + SDL_free(curdata->buffer); + curdata->buffer = NULL; + } + /* Free cursor itself */ + if (cursor->driverdata) { + SDL_free(cursor->driverdata); + } + SDL_free(cursor); + } +} + +/* This simply gets the cursor soft-buffer ready. + We don't copy it to a GBO BO until ShowCursor() because the cusor GBM BO (living + in dispata) is destroyed and recreated when we recreate windows, etc. */ +static SDL_Cursor *KMSDRM_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y) +{ + KMSDRM_CursorData *curdata; + SDL_Cursor *cursor, *ret; + + curdata = NULL; + ret = NULL; + + cursor = (SDL_Cursor *)SDL_calloc(1, sizeof(*cursor)); + if (!cursor) { + SDL_OutOfMemory(); + goto cleanup; + } + curdata = (KMSDRM_CursorData *)SDL_calloc(1, sizeof(*curdata)); + if (!curdata) { + SDL_OutOfMemory(); + goto cleanup; + } + + /* hox_x and hot_y are the coordinates of the "tip of the cursor" from it's base. */ + curdata->hot_x = hot_x; + curdata->hot_y = hot_y; + curdata->w = surface->w; + curdata->h = surface->h; + curdata->buffer = NULL; + + /* Configure the cursor buffer info. + This buffer has the original size of the cursor surface we are given. */ + curdata->buffer_pitch = surface->w; + curdata->buffer_size = (size_t)surface->w * surface->h * 4; + curdata->buffer = (uint32_t *)SDL_malloc(curdata->buffer_size); + + if (!curdata->buffer) { + SDL_OutOfMemory(); + goto cleanup; + } + + /* All code below assumes ARGB8888 format for the cursor surface, + like other backends do. Also, the GBM BO pixels have to be + alpha-premultiplied, but the SDL surface we receive has + straight-alpha pixels, so we always have to convert. */ + SDL_PremultiplyAlpha(surface->w, surface->h, + surface->format->format, surface->pixels, surface->pitch, + SDL_PIXELFORMAT_ARGB8888, curdata->buffer, surface->w * 4); + + cursor->driverdata = curdata; + + ret = cursor; + +cleanup: + if (!ret) { + if (curdata) { + if (curdata->buffer) { + SDL_free(curdata->buffer); + } + SDL_free(curdata); + } + if (cursor) { + SDL_free(cursor); + } + } + + return ret; +} + +/* Show the specified cursor, or hide if cursor is NULL or has no focus. */ +static int KMSDRM_ShowCursor(SDL_Cursor *cursor) +{ + SDL_VideoDisplay *display; + SDL_Window *window; + SDL_Mouse *mouse; + + int num_displays, i; + int ret = 0; + + /* Get the mouse focused window, if any. */ + + mouse = SDL_GetMouse(); + if (!mouse) { + return SDL_SetError("No mouse."); + } + + window = mouse->focus; + + if (!window || !cursor) { + + /* If no window is focused by mouse or cursor is NULL, + since we have no window (no mouse->focus) and hence + we have no display, we simply hide mouse on all displays. + This happens on video quit, where we get here after + the mouse focus has been unset, yet SDL wants to + restore the system default cursor (makes no sense here). */ + + num_displays = SDL_GetNumVideoDisplays(); + + /* Iterate on the displays hidding the cursor. */ + for (i = 0; i < num_displays; i++) { + display = SDL_GetDisplay(i); + ret = KMSDRM_RemoveCursorFromBO(display); + } + + } else { + + display = SDL_GetDisplayForWindow(window); + + if (display) { + + if (cursor) { + /* Dump the cursor to the display DRM cursor BO so it becomes visible + on that display. */ + ret = KMSDRM_DumpCursorToBO(display, cursor); + + } else { + /* Hide the cursor on that display. */ + ret = KMSDRM_RemoveCursorFromBO(display); + } + } + } + + return ret; +} + +/* Warp the mouse to (x,y) */ +static void KMSDRM_WarpMouse(SDL_Window *window, int x, int y) +{ + /* Only one global/fullscreen window is supported */ + KMSDRM_WarpMouseGlobal(x, y); +} + +/* Warp the mouse to (x,y) */ +static int KMSDRM_WarpMouseGlobal(int x, int y) +{ + SDL_Mouse *mouse = SDL_GetMouse(); + + if (mouse && mouse->cur_cursor && mouse->focus) { + + SDL_Window *window = mouse->focus; + SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayForWindow(window)->driverdata; + + /* Update internal mouse position. */ + SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 0, x, y); + + /* And now update the cursor graphic position on screen. */ + if (dispdata->cursor_bo) { + int ret = 0; + + ret = KMSDRM_drmModeMoveCursor(dispdata->cursor_bo_drm_fd, dispdata->crtc->crtc_id, x, y); + + if (ret) { + SDL_SetError("drmModeMoveCursor() failed."); + } + + return ret; + + } else { + return SDL_SetError("Cursor not initialized properly."); + } + + } else { + return SDL_SetError("No mouse or current cursor."); + } +} + +void KMSDRM_InitMouse(_THIS, SDL_VideoDisplay *display) +{ + SDL_Mouse *mouse = SDL_GetMouse(); + SDL_DisplayData *dispdata = (SDL_DisplayData *)display->driverdata; + + mouse->CreateCursor = KMSDRM_CreateCursor; + mouse->ShowCursor = KMSDRM_ShowCursor; + mouse->MoveCursor = KMSDRM_MoveCursor; + mouse->FreeCursor = KMSDRM_FreeCursor; + mouse->WarpMouse = KMSDRM_WarpMouse; + mouse->WarpMouseGlobal = KMSDRM_WarpMouseGlobal; + + /* Only create the default cursor for this display if we haven't done so before, + we don't want several cursors to be created for the same display. */ + if (!dispdata->default_cursor_init) { + SDL_SetDefaultCursor(KMSDRM_CreateDefaultCursor()); + dispdata->default_cursor_init = SDL_TRUE; + } +} + +void KMSDRM_QuitMouse(_THIS) +{ + /* TODO: ? */ +} + +/* This is called when a mouse motion event occurs */ +static void KMSDRM_MoveCursor(SDL_Cursor *cursor) +{ + SDL_Mouse *mouse = SDL_GetMouse(); + int ret = 0; + + /* We must NOT call SDL_SendMouseMotion() here or we will enter recursivity! + That's why we move the cursor graphic ONLY. */ + if (mouse && mouse->cur_cursor && mouse->focus) { + + SDL_Window *window = mouse->focus; + SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayForWindow(window)->driverdata; + + if (!dispdata->cursor_bo) { + SDL_SetError("Cursor not initialized properly."); + return; + } + + ret = KMSDRM_drmModeMoveCursor(dispdata->cursor_bo_drm_fd, dispdata->crtc->crtc_id, mouse->x, mouse->y); + + if (ret) { + SDL_SetError("drmModeMoveCursor() failed."); + } + } +} + +#endif /* SDL_VIDEO_DRIVER_KMSDRM */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/kmsdrm/SDL_kmsdrmmouse.h b/SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmmouse.h similarity index 67% rename from SDL2-2.0.12/src/video/kmsdrm/SDL_kmsdrmmouse.h rename to SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmmouse.h index 6eb7548..0485abf 100644 --- a/SDL2-2.0.12/src/video/kmsdrm/SDL_kmsdrmmouse.h +++ b/SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmmouse.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -31,15 +31,25 @@ typedef struct _KMSDRM_CursorData { - struct gbm_bo *bo; - uint32_t crtc_id; - int hot_x, hot_y; - int w, h; + int hot_x, hot_y; + int w, h; + + /* The buffer where we store the mouse bitmap ready to be used. + We get it ready and filled in CreateCursor(), and copy it + to a GBM BO in ShowCursor().*/ + uint32_t *buffer; + size_t buffer_size; + size_t buffer_pitch; + } KMSDRM_CursorData; -extern void KMSDRM_InitMouse(_THIS); +extern void KMSDRM_InitMouse(_THIS, SDL_VideoDisplay *display); extern void KMSDRM_QuitMouse(_THIS); +extern void KMSDRM_CreateCursorBO(SDL_VideoDisplay *display); +extern void KMSDRM_DestroyCursorBO(_THIS, SDL_VideoDisplay *display); +extern void KMSDRM_InitCursor(void); + #endif /* SDL_KMSDRM_mouse_h_ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmopengles.c b/SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmopengles.c new file mode 100644 index 0000000..9b34d68 --- /dev/null +++ b/SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmopengles.c @@ -0,0 +1,214 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_KMSDRM + +#include "SDL_log.h" +#include "SDL_timer.h" + +#include "SDL_kmsdrmvideo.h" +#include "SDL_kmsdrmopengles.h" +#include "SDL_kmsdrmdyn.h" +#include + +#ifndef EGL_PLATFORM_GBM_MESA +#define EGL_PLATFORM_GBM_MESA 0x31D7 +#endif + +/* EGL implementation of SDL OpenGL support */ + +void KMSDRM_GLES_DefaultProfileConfig(_THIS, int *mask, int *major, int *minor) +{ + /* if SDL was _also_ built with the Raspberry Pi driver (so we're + definitely a Pi device), default to GLES2. */ +#ifdef SDL_VIDEO_DRIVER_RPI + *mask = SDL_GL_CONTEXT_PROFILE_ES; + *major = 2; + *minor = 0; +#endif +} + +int KMSDRM_GLES_LoadLibrary(_THIS, const char *path) +{ + /* Just pretend you do this here, but don't do it until KMSDRM_CreateWindow(), + where we do the same library load we would normally do here. + because this gets called by SDL_CreateWindow() before KMSDR_CreateWindow(), + so gbm dev isn't yet created when this is called, AND we can't alter the + call order in SDL_CreateWindow(). */ +#if 0 + NativeDisplayType display = (NativeDisplayType)((SDL_VideoData *)_this->driverdata)->gbm_dev; + return SDL_EGL_LoadLibrary(_this, path, display, EGL_PLATFORM_GBM_MESA); +#endif + return 0; +} + +void KMSDRM_GLES_UnloadLibrary(_THIS) +{ + /* As with KMSDRM_GLES_LoadLibrary(), we define our own "dummy" unloading function + so we manually unload the library whenever we want. */ +} + +SDL_EGL_CreateContext_impl(KMSDRM) + + int KMSDRM_GLES_SetSwapInterval(_THIS, int interval) +{ + + if (!_this->egl_data) { + return SDL_SetError("EGL not initialized"); + } + + if (interval == 0 || interval == 1) { + _this->egl_data->egl_swapinterval = interval; + } else { + return SDL_SetError("Only swap intervals of 0 or 1 are supported"); + } + + return 0; +} + +int KMSDRM_GLES_SwapWindow(_THIS, SDL_Window *window) +{ + SDL_WindowData *windata = ((SDL_WindowData *)window->driverdata); + SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayForWindow(window)->driverdata; + SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); + KMSDRM_FBInfo *fb_info; + int ret = 0; + + /* Always wait for the previous issued flip before issuing a new one, + even if you do async flips. */ + uint32_t flip_flags = DRM_MODE_PAGE_FLIP_EVENT; + + /* Skip the swap if we've switched away to another VT */ + if (windata->egl_surface == EGL_NO_SURFACE) { + /* Wait a bit, throttling to ~100 FPS */ + SDL_Delay(10); + return 0; + } + + /* Recreate the GBM / EGL surfaces if the display mode has changed */ + if (windata->egl_surface_dirty) { + KMSDRM_CreateSurfaces(_this, window); + } + + /* Wait for confirmation that the next front buffer has been flipped, at which + point the previous front buffer can be released */ + if (!KMSDRM_WaitPageflip(_this, windata)) { + SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Wait for previous pageflip failed"); + return 0; + } + + /* Release the previous front buffer */ + if (windata->bo) { + KMSDRM_gbm_surface_release_buffer(windata->gs, windata->bo); + windata->bo = NULL; + } + + windata->bo = windata->next_bo; + + /* Mark a buffer to become the next front buffer. + This won't happen until pagelip completes. */ + if (!(_this->egl_data->eglSwapBuffers(_this->egl_data->egl_display, + windata->egl_surface))) { + SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "eglSwapBuffers failed"); + return 0; + } + + /* From the GBM surface, get the next BO to become the next front buffer, + and lock it so it can't be allocated as a back buffer (to prevent EGL + from drawing into it!) */ + windata->next_bo = KMSDRM_gbm_surface_lock_front_buffer(windata->gs); + if (!windata->next_bo) { + SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not lock front buffer on GBM surface"); + return 0; + } + + /* Get an actual usable fb for the next front buffer. */ + fb_info = KMSDRM_FBFromBO(_this, windata->next_bo); + if (!fb_info) { + SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not get a framebuffer"); + return 0; + } + + if (!windata->bo) { + /* On the first swap, immediately present the new front buffer. Before + drmModePageFlip can be used the CRTC has to be configured to use + the current connector and mode with drmModeSetCrtc */ + ret = KMSDRM_drmModeSetCrtc(viddata->drm_fd, + dispdata->crtc->crtc_id, fb_info->fb_id, 0, 0, + &dispdata->connector->connector_id, 1, &dispdata->mode); + + if (ret) { + SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not set videomode on CRTC."); + return 0; + } + } else { + /* On subsequent swaps, queue the new front buffer to be flipped during + the next vertical blank + + Remember: drmModePageFlip() never blocks, it just issues the flip, + which will be done during the next vblank, or immediately if + we pass the DRM_MODE_PAGE_FLIP_ASYNC flag. + Since calling drmModePageFlip() will return EBUSY if we call it + without having completed the last issued flip, we must pass the + DRM_MODE_PAGE_FLIP_ASYNC if we don't block on EGL (egl_swapinterval = 0). + That makes it flip immediately, without waiting for the next vblank + to do so, so even if we don't block on EGL, the flip will have completed + when we get here again. */ + if (_this->egl_data->egl_swapinterval == 0 && viddata->async_pageflip_support) { + flip_flags |= DRM_MODE_PAGE_FLIP_ASYNC; + } + + ret = KMSDRM_drmModePageFlip(viddata->drm_fd, dispdata->crtc->crtc_id, + fb_info->fb_id, flip_flags, &windata->waiting_for_flip); + + if (ret == 0) { + windata->waiting_for_flip = SDL_TRUE; + } else { + SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not queue pageflip: %d", ret); + } + + /* Wait immediately for vsync (as if we only had two buffers). + Even if we are already doing a WaitPageflip at the beginning of this + function, this is NOT redundant because here we wait immediately + after submitting the image to the screen, reducing lag, and if + we have waited here, there won't be a pending pageflip so the + WaitPageflip at the beginning of this function will be a no-op. + Just leave it here and don't worry. + Run your SDL2 program with "SDL_KMSDRM_DOUBLE_BUFFER=1 " + to enable this. */ + if (windata->double_buffer) { + if (!KMSDRM_WaitPageflip(_this, windata)) { + SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Immediate wait for previous pageflip failed"); + return 0; + } + } + } + + return 1; +} + +SDL_EGL_MakeCurrent_impl(KMSDRM) + +#endif /* SDL_VIDEO_DRIVER_KMSDRM */ + + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/kmsdrm/SDL_kmsdrmopengles.h b/SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmopengles.h similarity index 79% rename from SDL2-2.0.12/src/video/kmsdrm/SDL_kmsdrmopengles.h rename to SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmopengles.h index a414ea8..63e548a 100644 --- a/SDL2-2.0.12/src/video/kmsdrm/SDL_kmsdrmopengles.h +++ b/SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmopengles.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,7 +23,7 @@ #ifndef SDL_kmsdrmopengles_h_ #define SDL_kmsdrmopengles_h_ -#if SDL_VIDEO_DRIVER_KMSDRM && SDL_VIDEO_OPENGL_EGL +#ifdef SDL_VIDEO_DRIVER_KMSDRM #include "../SDL_sysvideo.h" #include "../SDL_egl_c.h" @@ -31,17 +31,17 @@ /* OpenGLES functions */ #define KMSDRM_GLES_GetAttribute SDL_EGL_GetAttribute #define KMSDRM_GLES_GetProcAddress SDL_EGL_GetProcAddress -#define KMSDRM_GLES_UnloadLibrary SDL_EGL_UnloadLibrary #define KMSDRM_GLES_DeleteContext SDL_EGL_DeleteContext #define KMSDRM_GLES_GetSwapInterval SDL_EGL_GetSwapInterval +extern void KMSDRM_GLES_DefaultProfileConfig(_THIS, int *mask, int *major, int *minor); extern int KMSDRM_GLES_SetSwapInterval(_THIS, int interval); extern int KMSDRM_GLES_LoadLibrary(_THIS, const char *path); -extern SDL_GLContext KMSDRM_GLES_CreateContext(_THIS, SDL_Window * window); -extern int KMSDRM_GLES_SwapWindow(_THIS, SDL_Window * window); -extern int KMSDRM_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context); +extern SDL_GLContext KMSDRM_GLES_CreateContext(_THIS, SDL_Window *window); +extern int KMSDRM_GLES_SwapWindow(_THIS, SDL_Window *window); +extern int KMSDRM_GLES_MakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context); -#endif /* SDL_VIDEO_DRIVER_KMSDRM && SDL_VIDEO_OPENGL_EGL */ +#endif /* SDL_VIDEO_DRIVER_KMSDRM */ #endif /* SDL_kmsdrmopengles_h_ */ diff --git a/SDL2-2.0.12/src/video/kmsdrm/SDL_kmsdrmsym.h b/SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmsym.h similarity index 59% rename from SDL2-2.0.12/src/video/kmsdrm/SDL_kmsdrmsym.h rename to SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmsym.h index e3e48ef..4968044 100644 --- a/SDL2-2.0.12/src/video/kmsdrm/SDL_kmsdrmsym.h +++ b/SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmsym.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -19,7 +19,7 @@ 3. This notice may not be removed or altered from any source distribution. */ -/* *INDENT-OFF* */ +/* *INDENT-OFF* */ /* clang-format off */ #ifndef SDL_KMSDRM_MODULE #define SDL_KMSDRM_MODULE(modname) @@ -40,16 +40,35 @@ SDL_KMSDRM_SYM(void,drmModeFreeFB,(drmModeFBPtr ptr)) SDL_KMSDRM_SYM(void,drmModeFreeCrtc,(drmModeCrtcPtr ptr)) SDL_KMSDRM_SYM(void,drmModeFreeConnector,(drmModeConnectorPtr ptr)) SDL_KMSDRM_SYM(void,drmModeFreeEncoder,(drmModeEncoderPtr ptr)) +SDL_KMSDRM_SYM(int,drmGetCap,(int fd, uint64_t capability, uint64_t *value)) +SDL_KMSDRM_SYM(int,drmSetMaster,(int fd)) +SDL_KMSDRM_SYM(int,drmDropMaster,(int fd)) +SDL_KMSDRM_SYM(int,drmAuthMagic,(int fd, drm_magic_t magic)) SDL_KMSDRM_SYM(drmModeResPtr,drmModeGetResources,(int fd)) SDL_KMSDRM_SYM(int,drmModeAddFB,(int fd, uint32_t width, uint32_t height, uint8_t depth, - uint8_t bpp, uint32_t pitch, uint32_t bo_handle, - uint32_t *buf_id)) + uint8_t bpp, uint32_t pitch, uint32_t bo_handle, + uint32_t *buf_id)) + +SDL_KMSDRM_SYM(int,drmModeAddFB2,(int fd, uint32_t width, uint32_t height, + uint32_t pixel_format, const uint32_t bo_handles[4], + const uint32_t pitches[4], const uint32_t offsets[4], + uint32_t *buf_id, uint32_t flags)) + +SDL_KMSDRM_SYM(int,drmModeAddFB2WithModifiers,(int fd, uint32_t width, + uint32_t height, uint32_t pixel_format, const uint32_t bo_handles[4], + const uint32_t pitches[4], const uint32_t offsets[4], + const uint64_t modifier[4], uint32_t *buf_id, uint32_t flags)) + SDL_KMSDRM_SYM(int,drmModeRmFB,(int fd, uint32_t bufferId)) SDL_KMSDRM_SYM(drmModeFBPtr,drmModeGetFB,(int fd, uint32_t buf)) SDL_KMSDRM_SYM(drmModeCrtcPtr,drmModeGetCrtc,(int fd, uint32_t crtcId)) SDL_KMSDRM_SYM(int,drmModeSetCrtc,(int fd, uint32_t crtcId, uint32_t bufferId, uint32_t x, uint32_t y, uint32_t *connectors, int count, drmModeModeInfoPtr mode)) +SDL_KMSDRM_SYM(int,drmModeCrtcGetGamma,(int fd, uint32_t crtc_id, uint32_t size, + uint16_t *red, uint16_t *green, uint16_t *blue)) +SDL_KMSDRM_SYM(int,drmModeCrtcSetGamma,(int fd, uint32_t crtc_id, uint32_t size, + const uint16_t *red, const uint16_t *green, const uint16_t *blue)) SDL_KMSDRM_SYM(int,drmModeSetCursor,(int fd, uint32_t crtcId, uint32_t bo_handle, uint32_t width, uint32_t height)) SDL_KMSDRM_SYM(int,drmModeSetCursor2,(int fd, uint32_t crtcId, uint32_t bo_handle, @@ -62,9 +81,29 @@ SDL_KMSDRM_SYM(int,drmHandleEvent,(int fd,drmEventContextPtr evctx)) SDL_KMSDRM_SYM(int,drmModePageFlip,(int fd, uint32_t crtc_id, uint32_t fb_id, uint32_t flags, void *user_data)) +/* Planes stuff. */ +SDL_KMSDRM_SYM(int,drmSetClientCap,(int fd, uint64_t capability, uint64_t value)) +SDL_KMSDRM_SYM(drmModePlaneResPtr,drmModeGetPlaneResources,(int fd)) +SDL_KMSDRM_SYM(drmModePlanePtr,drmModeGetPlane,(int fd, uint32_t plane_id)) +SDL_KMSDRM_SYM(drmModeObjectPropertiesPtr,drmModeObjectGetProperties,(int fd,uint32_t object_id,uint32_t object_type)) +SDL_KMSDRM_SYM(int,drmModeObjectSetProperty,(int fd, uint32_t object_id, + uint32_t object_type, uint32_t property_id, + uint64_t value)) +SDL_KMSDRM_SYM(drmModePropertyPtr,drmModeGetProperty,(int fd, uint32_t propertyId)) + +SDL_KMSDRM_SYM(void,drmModeFreeProperty,(drmModePropertyPtr ptr)) +SDL_KMSDRM_SYM(void,drmModeFreeObjectProperties,(drmModeObjectPropertiesPtr ptr)) +SDL_KMSDRM_SYM(void,drmModeFreePlane,(drmModePlanePtr ptr)) +SDL_KMSDRM_SYM(void,drmModeFreePlaneResources,(drmModePlaneResPtr ptr)) +SDL_KMSDRM_SYM(int,drmModeSetPlane,(int fd, uint32_t plane_id, uint32_t crtc_id, + uint32_t fb_id, uint32_t flags, + int32_t crtc_x, int32_t crtc_y, + uint32_t crtc_w, uint32_t crtc_h, + uint32_t src_x, uint32_t src_y, + uint32_t src_w, uint32_t src_h)) +/* Planes stuff ends. */ SDL_KMSDRM_MODULE(GBM) -SDL_KMSDRM_SYM(int,gbm_device_get_fd,(struct gbm_device *gbm)) SDL_KMSDRM_SYM(int,gbm_device_is_format_supported,(struct gbm_device *gbm, uint32_t format, uint32_t usage)) SDL_KMSDRM_SYM(void,gbm_device_destroy,(struct gbm_device *gbm)) @@ -72,6 +111,7 @@ SDL_KMSDRM_SYM(struct gbm_device *,gbm_create_device,(int fd)) SDL_KMSDRM_SYM(unsigned int,gbm_bo_get_width,(struct gbm_bo *bo)) SDL_KMSDRM_SYM(unsigned int,gbm_bo_get_height,(struct gbm_bo *bo)) SDL_KMSDRM_SYM(uint32_t,gbm_bo_get_stride,(struct gbm_bo *bo)) +SDL_KMSDRM_SYM(uint32_t,gbm_bo_get_format,(struct gbm_bo *bo)) SDL_KMSDRM_SYM(union gbm_bo_handle,gbm_bo_get_handle,(struct gbm_bo *bo)) SDL_KMSDRM_SYM(int,gbm_bo_write,(struct gbm_bo *bo, const void *buf, size_t count)) SDL_KMSDRM_SYM(struct gbm_device *,gbm_bo_get_device,(struct gbm_bo *bo)) @@ -89,11 +129,15 @@ SDL_KMSDRM_SYM(void,gbm_surface_destroy,(struct gbm_surface *surf)) SDL_KMSDRM_SYM(struct gbm_bo *,gbm_surface_lock_front_buffer,(struct gbm_surface *surf)) SDL_KMSDRM_SYM(void,gbm_surface_release_buffer,(struct gbm_surface *surf, struct gbm_bo *bo)) +SDL_KMSDRM_SYM(uint64_t,gbm_bo_get_modifier,(struct gbm_bo *bo)) +SDL_KMSDRM_SYM(int,gbm_bo_get_plane_count,(struct gbm_bo *bo)) +SDL_KMSDRM_SYM(uint32_t,gbm_bo_get_offset,(struct gbm_bo *bo, int plane)) +SDL_KMSDRM_SYM(uint32_t,gbm_bo_get_stride_for_plane,(struct gbm_bo *bo, int plane)) #undef SDL_KMSDRM_MODULE #undef SDL_KMSDRM_SYM #undef SDL_KMSDRM_SYM_CONST -/* *INDENT-ON* */ +/* *INDENT-ON* */ /* clang-format on */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmvideo.c b/SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmvideo.c new file mode 100644 index 0000000..2dab65c --- /dev/null +++ b/SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmvideo.c @@ -0,0 +1,1688 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_KMSDRM + +/* SDL internals */ +#include "../SDL_sysvideo.h" +#include "SDL_syswm.h" +#include "SDL_log.h" +#include "SDL_hints.h" +#include "../../events/SDL_events_c.h" +#include "../../events/SDL_mouse_c.h" +#include "../../events/SDL_keyboard_c.h" + +#ifdef SDL_INPUT_LINUXEV +#include "../../core/linux/SDL_evdev.h" +#elif defined SDL_INPUT_WSCONS +#include "../../core/openbsd/SDL_wscons.h" +#endif + +/* KMS/DRM declarations */ +#include "SDL_kmsdrmvideo.h" +#include "SDL_kmsdrmevents.h" +#include "SDL_kmsdrmopengles.h" +#include "SDL_kmsdrmmouse.h" +#include "SDL_kmsdrmdyn.h" +#include "SDL_kmsdrmvulkan.h" +#include +#include +#include +#include +#include +#include + +#ifdef __OpenBSD__ +static SDL_bool moderndri = SDL_FALSE; +#else +static SDL_bool moderndri = SDL_TRUE; +#endif + +static char kmsdrm_dri_path[16]; +static int kmsdrm_dri_pathsize = 0; +static char kmsdrm_dri_devname[8]; +static int kmsdrm_dri_devnamesize = 0; +static char kmsdrm_dri_cardpath[32]; + +#ifndef EGL_PLATFORM_GBM_MESA +#define EGL_PLATFORM_GBM_MESA 0x31D7 +#endif + +static int get_driindex(void) +{ + int available = -ENOENT; + char device[sizeof(kmsdrm_dri_cardpath)]; + int drm_fd; + int i; + int devindex = -1; + DIR *folder; + const char *hint; + struct dirent *res; + + hint = SDL_GetHint(SDL_HINT_KMSDRM_DEVICE_INDEX); + if (hint && *hint) { + char *endptr = NULL; + const int idx = (int)SDL_strtol(hint, &endptr, 10); + if ((*endptr == '\0') && (idx >= 0)) { /* *endptr==0 means "whole string was a valid number" */ + return idx; /* we'll take the user's request here. */ + } + } + + SDL_strlcpy(device, kmsdrm_dri_path, sizeof(device)); + folder = opendir(device); + if (!folder) { + SDL_SetError("Failed to open directory '%s'", device); + return -ENOENT; + } + + SDL_strlcpy(device + kmsdrm_dri_pathsize, kmsdrm_dri_devname, + sizeof(device) - kmsdrm_dri_devnamesize); + while((res = readdir(folder)) != NULL) { + if (SDL_memcmp(res->d_name, kmsdrm_dri_devname, + kmsdrm_dri_devnamesize) == 0) { + SDL_strlcpy(device + kmsdrm_dri_pathsize + kmsdrm_dri_devnamesize, + res->d_name + kmsdrm_dri_devnamesize, + sizeof(device) - kmsdrm_dri_pathsize - + kmsdrm_dri_devnamesize); + + drm_fd = open(device, O_RDWR | O_CLOEXEC); + if (drm_fd >= 0) { + devindex = SDL_atoi(device + kmsdrm_dri_pathsize + + kmsdrm_dri_devnamesize); + if (SDL_KMSDRM_LoadSymbols()) { + drmModeRes *resources = KMSDRM_drmModeGetResources(drm_fd); + if (resources) { + SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, + "%s%d connector, encoder and CRTC counts are: %d %d %d", + kmsdrm_dri_cardpath, devindex, + resources->count_connectors, + resources->count_encoders, + resources->count_crtcs); + + if (resources->count_connectors > 0 && + resources->count_encoders > 0 && + resources->count_crtcs > 0) { + available = -ENOENT; + for (i = 0; i < resources->count_connectors; i++) { + drmModeConnector *conn = + KMSDRM_drmModeGetConnector( + drm_fd, resources->connectors[i]); + + if (!conn) { + continue; + } + + if (conn->connection == DRM_MODE_CONNECTED && + conn->count_modes) { + if (SDL_GetHintBoolean( + SDL_HINT_KMSDRM_REQUIRE_DRM_MASTER, + SDL_TRUE)) { + /* Skip this device if we can't obtain + * DRM master */ + KMSDRM_drmSetMaster(drm_fd); + if (KMSDRM_drmAuthMagic(drm_fd, 0) == + -EACCES) { + continue; + } + } + + available = devindex; + break; + } + + KMSDRM_drmModeFreeConnector(conn); + } + } + KMSDRM_drmModeFreeResources(resources); + } + SDL_KMSDRM_UnloadSymbols(); + } + close(drm_fd); + } + + SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, + "Failed to open KMSDRM device %s, errno: %d\n", device, + errno); + } + } + + closedir(folder); + + return available; +} + +static int KMSDRM_Available(void) +{ +#ifdef __OpenBSD__ + struct utsname nameofsystem; + double releaseversion; +#endif + int ret = -ENOENT; + +#ifdef __OpenBSD__ + if (!(uname(&nameofsystem) < 0)) { + releaseversion = SDL_atof(nameofsystem.release); + if (releaseversion >= 6.9) { + moderndri = SDL_TRUE; + } + } +#endif + + if (moderndri) { + SDL_strlcpy(kmsdrm_dri_path, "/dev/dri/", sizeof(kmsdrm_dri_path)); + SDL_strlcpy(kmsdrm_dri_devname, "card", sizeof(kmsdrm_dri_devname)); + } else { + SDL_strlcpy(kmsdrm_dri_path, "/dev/", sizeof(kmsdrm_dri_path)); + SDL_strlcpy(kmsdrm_dri_devname, "drm", sizeof(kmsdrm_dri_devname)); + } + + kmsdrm_dri_pathsize = SDL_strlen(kmsdrm_dri_path); + kmsdrm_dri_devnamesize = SDL_strlen(kmsdrm_dri_devname); + (void)SDL_snprintf(kmsdrm_dri_cardpath, sizeof(kmsdrm_dri_cardpath), "%s%s", + kmsdrm_dri_path, kmsdrm_dri_devname); + + ret = get_driindex(); + if (ret >= 0) { + return 1; + } + + return ret; +} + +static void KMSDRM_DeleteDevice(SDL_VideoDevice *device) +{ + if (device->driverdata) { + SDL_free(device->driverdata); + device->driverdata = NULL; + } + + SDL_free(device); + + SDL_KMSDRM_UnloadSymbols(); +} + +static SDL_VideoDevice *KMSDRM_CreateDevice(void) +{ + SDL_VideoDevice *device; + SDL_VideoData *viddata; + int devindex; + + if (!KMSDRM_Available()) { + return NULL; + } + + devindex = get_driindex(); + if (devindex < 0) { + SDL_SetError("devindex (%d) must not be negative.", devindex); + return NULL; + } + + if (!SDL_KMSDRM_LoadSymbols()) { + return NULL; + } + + device = (SDL_VideoDevice *)SDL_calloc(1, sizeof(SDL_VideoDevice)); + if (!device) { + SDL_OutOfMemory(); + return NULL; + } + + viddata = (SDL_VideoData *)SDL_calloc(1, sizeof(SDL_VideoData)); + if (!viddata) { + SDL_OutOfMemory(); + goto cleanup; + } + viddata->devindex = devindex; + viddata->drm_fd = -1; + + device->driverdata = viddata; + + /* Setup all functions which we can handle */ + device->VideoInit = KMSDRM_VideoInit; + device->VideoQuit = KMSDRM_VideoQuit; + device->GetDisplayModes = KMSDRM_GetDisplayModes; + device->SetDisplayMode = KMSDRM_SetDisplayMode; + device->CreateSDLWindow = KMSDRM_CreateWindow; + device->CreateSDLWindowFrom = KMSDRM_CreateWindowFrom; + device->SetWindowTitle = KMSDRM_SetWindowTitle; + device->SetWindowIcon = KMSDRM_SetWindowIcon; + device->SetWindowPosition = KMSDRM_SetWindowPosition; + device->SetWindowSize = KMSDRM_SetWindowSize; + device->SetWindowFullscreen = KMSDRM_SetWindowFullscreen; + device->GetWindowGammaRamp = KMSDRM_GetWindowGammaRamp; + device->SetWindowGammaRamp = KMSDRM_SetWindowGammaRamp; + device->ShowWindow = KMSDRM_ShowWindow; + device->HideWindow = KMSDRM_HideWindow; + device->RaiseWindow = KMSDRM_RaiseWindow; + device->MaximizeWindow = KMSDRM_MaximizeWindow; + device->MinimizeWindow = KMSDRM_MinimizeWindow; + device->RestoreWindow = KMSDRM_RestoreWindow; + device->DestroyWindow = KMSDRM_DestroyWindow; + device->GetWindowWMInfo = KMSDRM_GetWindowWMInfo; + + device->GL_LoadLibrary = KMSDRM_GLES_LoadLibrary; + device->GL_GetProcAddress = KMSDRM_GLES_GetProcAddress; + device->GL_UnloadLibrary = KMSDRM_GLES_UnloadLibrary; + device->GL_CreateContext = KMSDRM_GLES_CreateContext; + device->GL_MakeCurrent = KMSDRM_GLES_MakeCurrent; + device->GL_SetSwapInterval = KMSDRM_GLES_SetSwapInterval; + device->GL_GetSwapInterval = KMSDRM_GLES_GetSwapInterval; + device->GL_SwapWindow = KMSDRM_GLES_SwapWindow; + device->GL_DeleteContext = KMSDRM_GLES_DeleteContext; + device->GL_DefaultProfileConfig = KMSDRM_GLES_DefaultProfileConfig; + +#ifdef SDL_VIDEO_VULKAN + device->Vulkan_LoadLibrary = KMSDRM_Vulkan_LoadLibrary; + device->Vulkan_UnloadLibrary = KMSDRM_Vulkan_UnloadLibrary; + device->Vulkan_GetInstanceExtensions = KMSDRM_Vulkan_GetInstanceExtensions; + device->Vulkan_CreateSurface = KMSDRM_Vulkan_CreateSurface; + device->Vulkan_GetDrawableSize = KMSDRM_Vulkan_GetDrawableSize; +#endif + + device->PumpEvents = KMSDRM_PumpEvents; + device->free = KMSDRM_DeleteDevice; + + return device; + +cleanup: + SDL_free(device); + + if (viddata) { + SDL_free(viddata); + } + return NULL; +} + +VideoBootStrap KMSDRM_bootstrap = { + "KMSDRM", + "KMS/DRM Video Driver", + KMSDRM_CreateDevice, + NULL /* no ShowMessageBox implementation */ +}; + +static void KMSDRM_FBDestroyCallback(struct gbm_bo *bo, void *data) +{ + KMSDRM_FBInfo *fb_info = (KMSDRM_FBInfo *)data; + + if (fb_info && fb_info->drm_fd >= 0 && fb_info->fb_id != 0) { + KMSDRM_drmModeRmFB(fb_info->drm_fd, fb_info->fb_id); + SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Delete DRM FB %u", fb_info->fb_id); + } + + SDL_free(fb_info); +} + +KMSDRM_FBInfo *KMSDRM_FBFromBO(_THIS, struct gbm_bo *bo) +{ + SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); + unsigned w, h; + int ret, num_planes = 0; + Uint32 format, strides[4] = { 0 }, handles[4] = { 0 }, offsets[4] = { 0 }, flags = 0; + uint64_t modifiers[4] = { 0 }; + + /* Check for an existing framebuffer */ + KMSDRM_FBInfo *fb_info = (KMSDRM_FBInfo *)KMSDRM_gbm_bo_get_user_data(bo); + + if (fb_info) { + return fb_info; + } + + /* Create a structure that contains enough info to remove the framebuffer + when the backing buffer is destroyed */ + fb_info = (KMSDRM_FBInfo *)SDL_calloc(1, sizeof(KMSDRM_FBInfo)); + + if (!fb_info) { + SDL_OutOfMemory(); + return NULL; + } + + fb_info->drm_fd = viddata->drm_fd; + + /* Create framebuffer object for the buffer using the modifiers requested by GBM. + Use of the modifiers is necessary on some platforms. */ + w = KMSDRM_gbm_bo_get_width(bo); + h = KMSDRM_gbm_bo_get_height(bo); + format = KMSDRM_gbm_bo_get_format(bo); + + modifiers[0] = KMSDRM_gbm_bo_get_modifier(bo); + num_planes = KMSDRM_gbm_bo_get_plane_count(bo); + for (int i = 0; i < num_planes; i++) { + strides[i] = KMSDRM_gbm_bo_get_stride_for_plane(bo, i); + handles[i] = KMSDRM_gbm_bo_get_handle(bo).u32; + offsets[i] = KMSDRM_gbm_bo_get_offset(bo, i); + modifiers[i] = modifiers[0]; + } + + if (modifiers[0]) { + flags = DRM_MODE_FB_MODIFIERS; + } + + ret = KMSDRM_drmModeAddFB2WithModifiers(viddata->drm_fd, w, h, format, handles, strides, offsets, modifiers, &fb_info->fb_id, flags); + if (ret) { + SDL_free(fb_info); + return NULL; + } + + SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "New DRM FB (%u): %ux%u, from BO %p", + fb_info->fb_id, w, h, (void *)bo); + + /* Associate our DRM framebuffer with this buffer object */ + KMSDRM_gbm_bo_set_user_data(bo, fb_info, KMSDRM_FBDestroyCallback); + + return fb_info; +} + +static void KMSDRM_FlipHandler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *data) +{ + *((SDL_bool *)data) = SDL_FALSE; +} + +SDL_bool KMSDRM_WaitPageflip(_THIS, SDL_WindowData *windata) +{ + + SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); + drmEventContext ev = { 0 }; + struct pollfd pfd = { 0 }; + int ret; + + ev.version = DRM_EVENT_CONTEXT_VERSION; + ev.page_flip_handler = KMSDRM_FlipHandler; + + pfd.fd = viddata->drm_fd; + pfd.events = POLLIN; + + /* Stay on the while loop until we get the desired event. + We need the while the loop because we could be in a situation where: + -We get and event on the FD in time, thus not on exiting on return number 1. + -The event is not an error, thus not exiting on return number 2. + -The event is of POLLIN type, but even then, if the event is not a pageflip, + drmHandleEvent() won't unset wait_for_pageflip, so we have to iterate + and go polling again. + + If it wasn't for the while loop, we could erroneously exit the function + without the pageflip event to arrive! + + For example, vblank events hit the FD and they are POLLIN events too (POLLIN + means "there's data to read on the FD"), but they are not the pageflip event + we are waiting for, so the drmEventHandle() doesn't run the flip handler, and + since waiting_for_flip is set on the pageflip handle, it's not set and we stay + on the loop, until we get the event for the pageflip, which is fine. + */ + while (windata->waiting_for_flip) { + + pfd.revents = 0; + + /* poll() waits for events arriving on the FD, and returns < 0 if timeout passes + with no events or a signal occurred before any requested event (-EINTR). + We wait forever (timeout = -1), but even if we DO get an event, we have yet + to see if it's of the required type, then if it's a pageflip, etc */ + ret = poll(&pfd, 1, -1); + + if (ret < 0) { + if (errno == EINTR) { + /* poll() returning < 0 and setting errno = EINTR means there was a signal before + any requested event, so we immediately poll again. */ + continue; + } else { + /* There was another error. Don't pull again or we could get into a busy loop. */ + SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "DRM poll error"); + return SDL_FALSE; /* Return number 1. */ + } + } + + if (pfd.revents & (POLLHUP | POLLERR)) { + /* An event arrived on the FD in time, but it's an error. */ + SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "DRM poll hup or error"); + return SDL_FALSE; /* Return number 2. */ + } + + if (pfd.revents & POLLIN) { + /* There is data to read on the FD! + Is the event a pageflip? We know it is a pageflip if it matches the + event we are passing in &ev. If it does, drmHandleEvent() will unset + windata->waiting_for_flip and we will get out of the "while" loop. + If it's not, we keep iterating on the loop. */ + KMSDRM_drmHandleEvent(viddata->drm_fd, &ev); + } + + /* If we got to this point in the loop, we may iterate or exit the loop: + -A legit (non-error) event arrived, and it was a POLLING event, and it was consumed + by drmHandleEvent(). + -If it was a PAGEFLIP event, waiting_for_flip will be unset by drmHandleEvent() + and we will exit the loop. + -If it wasn't a PAGEFLIP, drmHandleEvent() won't unset waiting_for_flip, so we + iterare back to polling. + -A legit (non-error) event arrived, but it's not a POLLIN event, so it hasn't to be + consumed by drmHandleEvent(), so waiting_for_flip isn't set and we iterate back + to polling. */ + } + + return SDL_TRUE; +} + +/* Given w, h and refresh rate, returns the closest DRM video mode + available on the DRM connector of the display. + We use the SDL mode list (which we filled in KMSDRM_GetDisplayModes) + because it's ordered, while the list on the connector is mostly random.*/ +static drmModeModeInfo *KMSDRM_GetClosestDisplayMode(SDL_VideoDisplay *display, + uint32_t width, uint32_t height, uint32_t refresh_rate) +{ + + SDL_DisplayData *dispdata = (SDL_DisplayData *)display->driverdata; + drmModeConnector *connector = dispdata->connector; + + SDL_DisplayMode target, closest; + drmModeModeInfo *drm_mode; + + target.w = width; + target.h = height; + target.format = 0; /* Will use the default mode format. */ + target.refresh_rate = refresh_rate; + target.driverdata = 0; /* Initialize to 0 */ + + if (!SDL_GetClosestDisplayMode(SDL_atoi(display->name), &target, &closest)) { + return NULL; + } else { + SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)closest.driverdata; + drm_mode = &connector->modes[modedata->mode_index]; + return drm_mode; + } +} + +/*****************************************************************************/ +/* SDL Video and Display initialization/handling functions */ +/* _this is a SDL_VideoDevice * */ +/*****************************************************************************/ + +/* Deinitializes the driverdata of the SDL Displays in the SDL display list. */ +static void KMSDRM_DeinitDisplays(_THIS) +{ + + SDL_DisplayData *dispdata; + int num_displays, i; + + num_displays = SDL_GetNumVideoDisplays(); + + /* Iterate on the SDL Display list. */ + for (i = 0; i < num_displays; i++) { + + /* Get the driverdata for this display */ + dispdata = (SDL_DisplayData *)SDL_GetDisplayDriverData(i); + + /* Free connector */ + if (dispdata && dispdata->connector) { + KMSDRM_drmModeFreeConnector(dispdata->connector); + dispdata->connector = NULL; + } + + /* Free CRTC */ + if (dispdata && dispdata->crtc) { + KMSDRM_drmModeFreeCrtc(dispdata->crtc); + dispdata->crtc = NULL; + } + } +} + +static uint32_t KMSDRM_CrtcGetPropId(uint32_t drm_fd, + drmModeObjectPropertiesPtr props, + char const *name) +{ + uint32_t i, prop_id = 0; + + for (i = 0; !prop_id && i < props->count_props; ++i) { + drmModePropertyPtr drm_prop = + KMSDRM_drmModeGetProperty(drm_fd, props->props[i]); + + if (!drm_prop) { + continue; + } + + if (SDL_strcmp(drm_prop->name, name) == 0) { + prop_id = drm_prop->prop_id; + } + + KMSDRM_drmModeFreeProperty(drm_prop); + } + + return prop_id; +} + +static SDL_bool KMSDRM_VrrPropId(uint32_t drm_fd, uint32_t crtc_id, uint32_t *vrr_prop_id) +{ + drmModeObjectPropertiesPtr drm_props; + + drm_props = KMSDRM_drmModeObjectGetProperties(drm_fd, + crtc_id, + DRM_MODE_OBJECT_CRTC); + + if (!drm_props) { + return SDL_FALSE; + } + + *vrr_prop_id = KMSDRM_CrtcGetPropId(drm_fd, + drm_props, + "VRR_ENABLED"); + + KMSDRM_drmModeFreeObjectProperties(drm_props); + + return SDL_TRUE; +} + +static SDL_bool KMSDRM_ConnectorCheckVrrCapable(uint32_t drm_fd, + uint32_t output_id, + char const *name) +{ + uint32_t i; + SDL_bool found = SDL_FALSE; + uint64_t prop_value = 0; + + drmModeObjectPropertiesPtr props = KMSDRM_drmModeObjectGetProperties(drm_fd, + output_id, + DRM_MODE_OBJECT_CONNECTOR); + + if (!props) { + return SDL_FALSE; + } + + for (i = 0; !found && i < props->count_props; ++i) { + drmModePropertyPtr drm_prop = KMSDRM_drmModeGetProperty(drm_fd, props->props[i]); + + if (!drm_prop) { + continue; + } + + if (SDL_strcasecmp(drm_prop->name, name) == 0) { + prop_value = props->prop_values[i]; + found = SDL_TRUE; + } + + KMSDRM_drmModeFreeProperty(drm_prop); + } + if (found) { + return prop_value ? SDL_TRUE : SDL_FALSE; + } + + return SDL_FALSE; +} + +void KMSDRM_CrtcSetVrr(uint32_t drm_fd, uint32_t crtc_id, SDL_bool enabled) +{ + uint32_t vrr_prop_id; + if (!KMSDRM_VrrPropId(drm_fd, crtc_id, &vrr_prop_id)) { + return; + } + + KMSDRM_drmModeObjectSetProperty(drm_fd, + crtc_id, + DRM_MODE_OBJECT_CRTC, + vrr_prop_id, + enabled); +} + +static SDL_bool KMSDRM_CrtcGetVrr(uint32_t drm_fd, uint32_t crtc_id) +{ + uint32_t object_prop_id, vrr_prop_id; + drmModeObjectPropertiesPtr props; + SDL_bool object_prop_value; + int i; + + if (!KMSDRM_VrrPropId(drm_fd, crtc_id, &vrr_prop_id)) { + return SDL_FALSE; + } + + props = KMSDRM_drmModeObjectGetProperties(drm_fd, + crtc_id, + DRM_MODE_OBJECT_CRTC); + + if (!props) { + return SDL_FALSE; + } + + for (i = 0; i < props->count_props; ++i) { + drmModePropertyPtr drm_prop = KMSDRM_drmModeGetProperty(drm_fd, props->props[i]); + + if (!drm_prop) { + continue; + } + + object_prop_id = drm_prop->prop_id; + object_prop_value = props->prop_values[i] ? SDL_TRUE : SDL_FALSE; + + KMSDRM_drmModeFreeProperty(drm_prop); + + if (object_prop_id == vrr_prop_id) { + return object_prop_value; + } + } + return SDL_FALSE; +} + +/* Gets a DRM connector, builds an SDL_Display with it, and adds it to the + list of SDL Displays in _this->displays[] */ +static void KMSDRM_AddDisplay(_THIS, drmModeConnector *connector, drmModeRes *resources) +{ + SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); + SDL_DisplayData *dispdata = NULL; + SDL_VideoDisplay display = { 0 }; + SDL_DisplayModeData *modedata = NULL; + drmModeEncoder *encoder = NULL; + drmModeCrtc *crtc = NULL; + int mode_index; + int i, j; + int ret = 0; + + /* Reserve memory for the new display's driverdata. */ + dispdata = (SDL_DisplayData *)SDL_calloc(1, sizeof(SDL_DisplayData)); + if (!dispdata) { + ret = SDL_OutOfMemory(); + goto cleanup; + } + + /* Initialize some of the members of the new display's driverdata + to sane values. */ + dispdata->cursor_bo = NULL; + dispdata->cursor_bo_drm_fd = -1; + + /* Since we create and show the default cursor on KMSDRM_InitMouse(), + and we call KMSDRM_InitMouse() when we create a window, we have to know + if the display used by the window already has a default cursor or not. + If we don't, new default cursors would stack up on mouse->cursors and SDL + would have to hide and delete them at quit, not to mention the memory leak... */ + dispdata->default_cursor_init = SDL_FALSE; + + /* Try to find the connector's current encoder */ + for (i = 0; i < resources->count_encoders; i++) { + encoder = KMSDRM_drmModeGetEncoder(viddata->drm_fd, resources->encoders[i]); + + if (!encoder) { + continue; + } + + if (encoder->encoder_id == connector->encoder_id) { + break; + } + + KMSDRM_drmModeFreeEncoder(encoder); + encoder = NULL; + } + + if (!encoder) { + /* No encoder was connected, find the first supported one */ + for (i = 0; i < resources->count_encoders; i++) { + encoder = KMSDRM_drmModeGetEncoder(viddata->drm_fd, + resources->encoders[i]); + + if (!encoder) { + continue; + } + + for (j = 0; j < connector->count_encoders; j++) { + if (connector->encoders[j] == encoder->encoder_id) { + break; + } + } + + if (j != connector->count_encoders) { + break; + } + + KMSDRM_drmModeFreeEncoder(encoder); + encoder = NULL; + } + } + + if (!encoder) { + ret = SDL_SetError("No connected encoder found for connector."); + goto cleanup; + } + + /* Try to find a CRTC connected to this encoder */ + crtc = KMSDRM_drmModeGetCrtc(viddata->drm_fd, encoder->crtc_id); + + /* If no CRTC was connected to the encoder, find the first CRTC + that is supported by the encoder, and use that. */ + if (!crtc) { + for (i = 0; i < resources->count_crtcs; i++) { + if (encoder->possible_crtcs & (1 << i)) { + encoder->crtc_id = resources->crtcs[i]; + crtc = KMSDRM_drmModeGetCrtc(viddata->drm_fd, encoder->crtc_id); + break; + } + } + } + + if (!crtc) { + ret = SDL_SetError("No CRTC found for connector."); + goto cleanup; + } + + /* Find the index of the mode attached to this CRTC */ + mode_index = -1; + + for (i = 0; i < connector->count_modes; i++) { + drmModeModeInfo *mode = &connector->modes[i]; + + if (!SDL_memcmp(mode, &crtc->mode, sizeof(crtc->mode))) { + mode_index = i; + break; + } + } + + if (mode_index == -1) { + int current_area, largest_area = 0; + + /* Find the preferred mode or the highest resolution mode */ + for (i = 0; i < connector->count_modes; i++) { + drmModeModeInfo *mode = &connector->modes[i]; + + if (mode->type & DRM_MODE_TYPE_PREFERRED) { + mode_index = i; + break; + } + + current_area = mode->hdisplay * mode->vdisplay; + if (current_area > largest_area) { + mode_index = i; + largest_area = current_area; + } + } + if (mode_index != -1) { + crtc->mode = connector->modes[mode_index]; + } + } + + if (mode_index == -1) { + ret = SDL_SetError("Failed to find index of mode attached to the CRTC."); + goto cleanup; + } + + /*********************************************/ + /* Create an SDL Display for this connector. */ + /*********************************************/ + + /*********************************************/ + /* Part 1: setup the SDL_Display driverdata. */ + /*********************************************/ + + /* Get the mode currently setup for this display, + which is the mode currently setup on the CRTC + we found for the active connector. */ + dispdata->mode = crtc->mode; + dispdata->original_mode = crtc->mode; + dispdata->fullscreen_mode = crtc->mode; + + if (dispdata->mode.hdisplay == 0 || dispdata->mode.vdisplay == 0) { + ret = SDL_SetError("Couldn't get a valid connector videomode."); + goto cleanup; + } + + /* Store the connector and crtc for this display. */ + dispdata->connector = connector; + dispdata->crtc = crtc; + + /* save previous vrr state */ + dispdata->saved_vrr = KMSDRM_CrtcGetVrr(viddata->drm_fd, crtc->crtc_id); + /* try to enable vrr */ + if (KMSDRM_ConnectorCheckVrrCapable(viddata->drm_fd, connector->connector_id, "VRR_CAPABLE")) { + SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Enabling VRR"); + KMSDRM_CrtcSetVrr(viddata->drm_fd, crtc->crtc_id, SDL_TRUE); + } + + /*****************************************/ + /* Part 2: setup the SDL_Display itself. */ + /*****************************************/ + + /* Setup the display. + There's no problem with it being still incomplete. */ + modedata = SDL_calloc(1, sizeof(SDL_DisplayModeData)); + + if (!modedata) { + ret = SDL_OutOfMemory(); + goto cleanup; + } + + modedata->mode_index = mode_index; + + display.driverdata = dispdata; + display.desktop_mode.w = dispdata->mode.hdisplay; + display.desktop_mode.h = dispdata->mode.vdisplay; + display.desktop_mode.refresh_rate = dispdata->mode.vrefresh; + display.desktop_mode.format = SDL_PIXELFORMAT_ARGB8888; + display.desktop_mode.driverdata = modedata; + display.current_mode = display.desktop_mode; + + /* Add the display to the list of SDL displays. */ + SDL_AddVideoDisplay(&display, SDL_FALSE); + +cleanup: + if (encoder) { + KMSDRM_drmModeFreeEncoder(encoder); + } + if (ret) { + /* Error (complete) cleanup */ + if (dispdata) { + if (dispdata->connector) { + KMSDRM_drmModeFreeConnector(dispdata->connector); + dispdata->connector = NULL; + } + if (dispdata->crtc) { + KMSDRM_drmModeFreeCrtc(dispdata->crtc); + dispdata->crtc = NULL; + } + SDL_free(dispdata); + } + } +} /* NOLINT(clang-analyzer-unix.Malloc): If no error `dispdata` is saved in the display */ + +/* Initializes the list of SDL displays: we build a new display for each + connecter connector we find. + Inoffeensive for VK compatibility, except we must leave the drm_fd + closed when we get to the end of this function. + This is to be called early, in VideoInit(), because it gets us + the videomode information, which SDL needs immediately after VideoInit(). */ +static int KMSDRM_InitDisplays(_THIS) +{ + + SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); + drmModeRes *resources = NULL; + + uint64_t async_pageflip = 0; + int ret = 0; + int i; + + /* Open /dev/dri/cardNN (/dev/drmN if on OpenBSD version less than 6.9) */ + (void)SDL_snprintf(viddata->devpath, sizeof(viddata->devpath), "%s%d", + kmsdrm_dri_cardpath, viddata->devindex); + + SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Opening device %s", viddata->devpath); + viddata->drm_fd = open(viddata->devpath, O_RDWR | O_CLOEXEC); + + if (viddata->drm_fd < 0) { + ret = SDL_SetError("Could not open %s", viddata->devpath); + goto cleanup; + } + + SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Opened DRM FD (%d)", viddata->drm_fd); + + /* Get all of the available connectors / devices / crtcs */ + resources = KMSDRM_drmModeGetResources(viddata->drm_fd); + if (!resources) { + ret = SDL_SetError("drmModeGetResources(%d) failed", viddata->drm_fd); + goto cleanup; + } + + /* Iterate on the available connectors. For every connected connector, + we create an SDL_Display and add it to the list of SDL Displays. */ + for (i = 0; i < resources->count_connectors; i++) { + drmModeConnector *connector = KMSDRM_drmModeGetConnector(viddata->drm_fd, + resources->connectors[i]); + + if (!connector) { + continue; + } + + if (connector->connection == DRM_MODE_CONNECTED && connector->count_modes) { + /* If it's a connected connector with available videomodes, try to add + an SDL Display representing it. KMSDRM_AddDisplay() is purposely void, + so if it fails (no encoder for connector, no valid video mode for + connector etc...) we can keep looking for connected connectors. */ + KMSDRM_AddDisplay(_this, connector, resources); + } else { + /* If it's not, free it now. */ + KMSDRM_drmModeFreeConnector(connector); + } + } + + /* Have we added any SDL displays? */ + if (!SDL_GetNumVideoDisplays()) { + ret = SDL_SetError("No connected displays found."); + goto cleanup; + } + + /* Determine if video hardware supports async pageflips. */ + ret = KMSDRM_drmGetCap(viddata->drm_fd, DRM_CAP_ASYNC_PAGE_FLIP, &async_pageflip); + if (ret) { + SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not determine async page flip capability."); + } + viddata->async_pageflip_support = async_pageflip ? SDL_TRUE : SDL_FALSE; + + /***********************************/ + /* Block for Vulkan compatibility. */ + /***********************************/ + + /* THIS IS FOR VULKAN! Leave the FD closed, so VK can work. + Will reopen this in CreateWindow, but only if requested a non-VK window. */ + close(viddata->drm_fd); + viddata->drm_fd = -1; + +cleanup: + if (resources) { + KMSDRM_drmModeFreeResources(resources); + } + if (ret) { + if (viddata->drm_fd >= 0) { + close(viddata->drm_fd); + viddata->drm_fd = -1; + } + } + return ret; +} + +/* Init the Vulkan-INCOMPATIBLE stuff: + Reopen FD, create gbm dev, create dumb buffer and setup display plane. + This is to be called late, in WindowCreate(), and ONLY if this is not + a Vulkan window. + We are doing this so late to allow Vulkan to work if we build a VK window. + These things are incompatible with Vulkan, which accesses the same resources + internally so they must be free when trying to build a Vulkan surface. +*/ +static int KMSDRM_GBMInit(_THIS, SDL_DisplayData *dispdata) +{ + SDL_VideoData *viddata = (SDL_VideoData *)_this->driverdata; + int ret = 0; + + /* Reopen the FD! */ + viddata->drm_fd = open(viddata->devpath, O_RDWR | O_CLOEXEC); + + /* Set the FD we just opened as current DRM master. */ + KMSDRM_drmSetMaster(viddata->drm_fd); + + /* Create the GBM device. */ + viddata->gbm_dev = KMSDRM_gbm_create_device(viddata->drm_fd); + if (!viddata->gbm_dev) { + ret = SDL_SetError("Couldn't create gbm device."); + } + + viddata->gbm_init = SDL_TRUE; + + return ret; +} + +/* Deinit the Vulkan-incompatible KMSDRM stuff. */ +static void KMSDRM_GBMDeinit(_THIS, SDL_DisplayData *dispdata) +{ + SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); + + /* Destroy GBM device. GBM surface is destroyed by DestroySurfaces(), + already called when we get here. */ + if (viddata->gbm_dev) { + KMSDRM_gbm_device_destroy(viddata->gbm_dev); + viddata->gbm_dev = NULL; + } + + /* Finally close DRM FD. May be reopen on next non-vulkan window creation. */ + if (viddata->drm_fd >= 0) { + close(viddata->drm_fd); + viddata->drm_fd = -1; + } + + viddata->gbm_init = SDL_FALSE; +} + +static void KMSDRM_DestroySurfaces(_THIS, SDL_Window *window) +{ + SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); + SDL_WindowData *windata = (SDL_WindowData *)window->driverdata; + SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayForWindow(window)->driverdata; + int ret; + + /**********************************************/ + /* Wait for last issued pageflip to complete. */ + /**********************************************/ + /*KMSDRM_WaitPageflip(_this, windata);*/ + + /***********************************************************************/ + /* Restore the original CRTC configuration: configue the crtc with the */ + /* original video mode and make it point to the original TTY buffer. */ + /***********************************************************************/ + + ret = KMSDRM_drmModeSetCrtc(viddata->drm_fd, dispdata->crtc->crtc_id, + dispdata->crtc->buffer_id, 0, 0, &dispdata->connector->connector_id, 1, + &dispdata->original_mode); + + /* If we failed to set the original mode, try to set the connector prefered mode. */ + if (ret && (dispdata->crtc->mode_valid == 0)) { + ret = KMSDRM_drmModeSetCrtc(viddata->drm_fd, dispdata->crtc->crtc_id, + dispdata->crtc->buffer_id, 0, 0, &dispdata->connector->connector_id, 1, + &dispdata->original_mode); + } + + if (ret) { + SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not restore CRTC"); + } + + /***************************/ + /* Destroy the EGL surface */ + /***************************/ + + SDL_EGL_MakeCurrent(_this, EGL_NO_SURFACE, EGL_NO_CONTEXT); + + if (windata->egl_surface != EGL_NO_SURFACE) { + SDL_EGL_DestroySurface(_this, windata->egl_surface); + windata->egl_surface = EGL_NO_SURFACE; + } + + /***************************/ + /* Destroy the GBM buffers */ + /***************************/ + + if (windata->bo) { + KMSDRM_gbm_surface_release_buffer(windata->gs, windata->bo); + windata->bo = NULL; + } + + if (windata->next_bo) { + KMSDRM_gbm_surface_release_buffer(windata->gs, windata->next_bo); + windata->next_bo = NULL; + } + + /***************************/ + /* Destroy the GBM surface */ + /***************************/ + + if (windata->gs) { + KMSDRM_gbm_surface_destroy(windata->gs); + windata->gs = NULL; + } +} + +static void KMSDRM_GetModeToSet(SDL_Window *window, drmModeModeInfo *out_mode) +{ + SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); + SDL_DisplayData *dispdata = (SDL_DisplayData *)display->driverdata; + + if ((window->flags & SDL_WINDOW_FULLSCREEN) == SDL_WINDOW_FULLSCREEN) { + *out_mode = dispdata->fullscreen_mode; + } else { + drmModeModeInfo *mode; + + mode = KMSDRM_GetClosestDisplayMode(display, + window->windowed.w, window->windowed.h, 0); + + if (mode) { + *out_mode = *mode; + } else { + *out_mode = dispdata->original_mode; + } + } +} + +static void KMSDRM_DirtySurfaces(SDL_Window *window) +{ + SDL_WindowData *windata = (SDL_WindowData *)window->driverdata; + drmModeModeInfo mode; + + /* Can't recreate EGL surfaces right now, need to wait until SwapWindow + so the correct thread-local surface and context state are available */ + windata->egl_surface_dirty = SDL_TRUE; + + /* The app may be waiting for the resize event after calling SetWindowSize + or SetWindowFullscreen, send a fake event for now since the actual + recreation is deferred */ + KMSDRM_GetModeToSet(window, &mode); + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, mode.hdisplay, mode.vdisplay); +} + +/* This determines the size of the fb, which comes from the GBM surface + that we create here. */ +int KMSDRM_CreateSurfaces(_THIS, SDL_Window *window) +{ + SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); + SDL_WindowData *windata = (SDL_WindowData *)window->driverdata; + SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); + SDL_DisplayData *dispdata = (SDL_DisplayData *)display->driverdata; + + uint32_t surface_fmt = GBM_FORMAT_ARGB8888; + uint32_t surface_flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING; + + EGLContext egl_context; + + int ret = 0; + + /* If the current window already has surfaces, destroy them before creating other. */ + if (windata->gs) { + KMSDRM_DestroySurfaces(_this, window); + } + + if (!KMSDRM_gbm_device_is_format_supported(viddata->gbm_dev, + surface_fmt, surface_flags)) { + SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, + "GBM surface format not supported. Trying anyway."); + } + + /* The KMSDRM backend doesn't always set the mode the higher-level code in + SDL_video.c expects. Hulk-smash the display's current_mode to keep the + mode that's set in sync with what SDL_video.c thinks is set */ + KMSDRM_GetModeToSet(window, &dispdata->mode); + + display->current_mode.w = dispdata->mode.hdisplay; + display->current_mode.h = dispdata->mode.vdisplay; + display->current_mode.refresh_rate = dispdata->mode.vrefresh; + display->current_mode.format = SDL_PIXELFORMAT_ARGB8888; + + windata->gs = KMSDRM_gbm_surface_create(viddata->gbm_dev, + dispdata->mode.hdisplay, dispdata->mode.vdisplay, + surface_fmt, surface_flags); + + if (!windata->gs) { + return SDL_SetError("Could not create GBM surface"); + } + + /* We can't get the EGL context yet because SDL_CreateRenderer has not been called, + but we need an EGL surface NOW, or GL won't be able to render into any surface + and we won't see the first frame. */ + SDL_EGL_SetRequiredVisualId(_this, surface_fmt); + windata->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType)windata->gs); + + if (windata->egl_surface == EGL_NO_SURFACE) { + ret = SDL_SetError("Could not create EGL window surface"); + goto cleanup; + } + + /* Current context passing to EGL is now done here. If something fails, + go back to delayed SDL_EGL_MakeCurrent() call in SwapWindow. */ + egl_context = (EGLContext)SDL_GL_GetCurrentContext(); + ret = SDL_EGL_MakeCurrent(_this, windata->egl_surface, egl_context); + + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, + dispdata->mode.hdisplay, dispdata->mode.vdisplay); + + windata->egl_surface_dirty = SDL_FALSE; + +cleanup: + + if (ret) { + /* Error (complete) cleanup. */ + if (windata->gs) { + KMSDRM_gbm_surface_destroy(windata->gs); + windata->gs = NULL; + } + } + + return ret; +} + +#ifdef SDL_INPUT_LINUXEV +static void KMSDRM_ReleaseVT(void *userdata) +{ + SDL_VideoDevice *_this = (SDL_VideoDevice *)userdata; + SDL_VideoData *viddata = _this->driverdata; + int i; + + for (i = 0; i < viddata->num_windows; i++) { + SDL_Window *window = viddata->windows[i]; + if (!(window->flags & SDL_WINDOW_VULKAN)) { + KMSDRM_DestroySurfaces(_this, window); + } + } + KMSDRM_drmDropMaster(viddata->drm_fd); +} + +static void KMSDRM_AcquireVT(void *userdata) +{ + SDL_VideoDevice *_this = (SDL_VideoDevice *)userdata; + SDL_VideoData *viddata = _this->driverdata; + int i; + + KMSDRM_drmSetMaster(viddata->drm_fd); + for (i = 0; i < viddata->num_windows; i++) { + SDL_Window *window = viddata->windows[i]; + if (!(window->flags & SDL_WINDOW_VULKAN)) { + KMSDRM_CreateSurfaces(_this, window); + } + } +} +#endif /* defined SDL_INPUT_LINUXEV */ + +int KMSDRM_VideoInit(_THIS) +{ + int ret = 0; + + SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); + SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "KMSDRM_VideoInit()"); + + viddata->video_init = SDL_FALSE; + viddata->gbm_init = SDL_FALSE; + + /* Get KMSDRM resources info and store what we need. Getting and storing + this info isn't a problem for VK compatibility. + For VK-incompatible initializations we have KMSDRM_GBMInit(), which is + called on window creation, and only when we know it's not a VK window. */ + if (KMSDRM_InitDisplays(_this)) { + ret = SDL_SetError("error getting KMSDRM displays information"); + } + +#ifdef SDL_INPUT_LINUXEV + SDL_EVDEV_Init(); + SDL_EVDEV_SetVTSwitchCallbacks(KMSDRM_ReleaseVT, _this, KMSDRM_AcquireVT, _this); +#elif defined(SDL_INPUT_WSCONS) + SDL_WSCONS_Init(); +#endif + + viddata->video_init = SDL_TRUE; + + return ret; +} + +/* The driverdata pointers, like dispdata, viddata, windata, etc... + are freed by SDL internals, so not our job. */ +void KMSDRM_VideoQuit(_THIS) +{ + SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); + + KMSDRM_DeinitDisplays(_this); + +#ifdef SDL_INPUT_LINUXEV + SDL_EVDEV_SetVTSwitchCallbacks(NULL, NULL, NULL, NULL); + SDL_EVDEV_Quit(); +#elif defined(SDL_INPUT_WSCONS) + SDL_WSCONS_Quit(); +#endif + + /* Clear out the window list */ + SDL_free(viddata->windows); + viddata->windows = NULL; + viddata->max_windows = 0; + viddata->num_windows = 0; + viddata->video_init = SDL_FALSE; +} + +/* Read modes from the connector modes, and store them in display->display_modes. */ +void KMSDRM_GetDisplayModes(_THIS, SDL_VideoDisplay *display) +{ + SDL_DisplayData *dispdata = display->driverdata; + drmModeConnector *conn = dispdata->connector; + SDL_DisplayMode mode; + int i; + + for (i = 0; i < conn->count_modes; i++) { + SDL_DisplayModeData *modedata = SDL_calloc(1, sizeof(SDL_DisplayModeData)); + + if (modedata) { + modedata->mode_index = i; + } + + mode.w = conn->modes[i].hdisplay; + mode.h = conn->modes[i].vdisplay; + mode.refresh_rate = conn->modes[i].vrefresh; + mode.format = SDL_PIXELFORMAT_ARGB8888; + mode.driverdata = modedata; + + if (!SDL_AddDisplayMode(display, &mode)) { + SDL_free(modedata); + } + } +} + +int KMSDRM_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode) +{ + /* Set the dispdata->mode to the new mode and leave actual modesetting + pending to be done on SwapWindow() via drmModeSetCrtc() */ + + SDL_VideoData *viddata = (SDL_VideoData *)_this->driverdata; + SDL_DisplayData *dispdata = (SDL_DisplayData *)display->driverdata; + SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)mode->driverdata; + drmModeConnector *conn = dispdata->connector; + int i; + + /* Don't do anything if we are in Vulkan mode. */ + if (viddata->vulkan_mode) { + return 0; + } + + if (!modedata) { + return SDL_SetError("Mode doesn't have an associated index"); + } + + /* Take note of the new mode to be set, and leave the CRTC modeset pending + so it's done in SwapWindow. */ + dispdata->fullscreen_mode = conn->modes[modedata->mode_index]; + + for (i = 0; i < viddata->num_windows; i++) { + KMSDRM_DirtySurfaces(viddata->windows[i]); + } + + return 0; +} + +void KMSDRM_DestroyWindow(_THIS, SDL_Window *window) +{ + SDL_WindowData *windata = (SDL_WindowData *)window->driverdata; + SDL_DisplayData *dispdata = (SDL_DisplayData *)SDL_GetDisplayForWindow(window)->driverdata; + SDL_VideoData *viddata; + SDL_bool is_vulkan = window->flags & SDL_WINDOW_VULKAN; /* Is this a VK window? */ + unsigned int i, j; + + if (!windata) { + return; + } + + /* restore vrr state */ + KMSDRM_CrtcSetVrr(windata->viddata->drm_fd, dispdata->crtc->crtc_id, dispdata->saved_vrr); + + viddata = windata->viddata; + + if (!is_vulkan && viddata->gbm_init) { + + /* Destroy cursor GBM BO of the display of this window. */ + KMSDRM_DestroyCursorBO(_this, SDL_GetDisplayForWindow(window)); + + /* Destroy GBM surface and buffers. */ + KMSDRM_DestroySurfaces(_this, window); + + /* Unload library and deinit GBM, but only if this is the last window. + Note that this is the right comparision because num_windows could be 1 + if there is a complete window, or 0 if we got here from SDL_CreateWindow() + because KMSDRM_CreateWindow() returned an error so the window wasn't + added to the windows list. */ + if (viddata->num_windows <= 1) { + + /* Unload EGL/GL library and free egl_data. */ + if (_this->egl_data) { + SDL_EGL_UnloadLibrary(_this); + _this->gl_config.driver_loaded = 0; + } + + /* Free display plane, and destroy GBM device. */ + KMSDRM_GBMDeinit(_this, dispdata); + } + + } else { + + /* If we were in Vulkan mode, get out of it. */ + if (viddata->vulkan_mode) { + viddata->vulkan_mode = SDL_FALSE; + } + } + + /********************************************/ + /* Remove from the internal SDL window list */ + /********************************************/ + + for (i = 0; i < viddata->num_windows; i++) { + if (viddata->windows[i] == window) { + viddata->num_windows--; + + for (j = i; j < viddata->num_windows; j++) { + viddata->windows[j] = viddata->windows[j + 1]; + } + + break; + } + } + + /*********************************************************************/ + /* Free the window driverdata. Bye bye, surface and buffer pointers! */ + /*********************************************************************/ + SDL_free(window->driverdata); + window->driverdata = NULL; +} + +/**********************************************************************/ +/* We simply IGNORE if it's a fullscreen window, window->flags don't */ +/* reflect it: if it's fullscreen, KMSDRM_SetWindwoFullscreen() will */ +/* be called by SDL later, and we can manage it there. */ +/**********************************************************************/ +int KMSDRM_CreateWindow(_THIS, SDL_Window *window) +{ + SDL_WindowData *windata = NULL; + SDL_VideoData *viddata = (SDL_VideoData *)_this->driverdata; + SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); + SDL_DisplayData *dispdata = display->driverdata; + SDL_bool is_vulkan = window->flags & SDL_WINDOW_VULKAN; /* Is this a VK window? */ + SDL_bool vulkan_mode = viddata->vulkan_mode; /* Do we have any Vulkan windows? */ + NativeDisplayType egl_display; + drmModeModeInfo *mode; + int ret = 0; + + /* Allocate window internal data */ + windata = (SDL_WindowData *)SDL_calloc(1, sizeof(SDL_WindowData)); + if (!windata) { + return SDL_OutOfMemory(); + } + + /* Setup driver data for this window */ + windata->viddata = viddata; + window->driverdata = windata; + + if (!is_vulkan && !vulkan_mode) { /* NON-Vulkan block. */ + + /* Maybe you didn't ask for an OPENGL window, but that's what you will get. + See following comments on why. */ + window->flags |= SDL_WINDOW_OPENGL; + + if (!(viddata->gbm_init)) { + + /* After SDL_CreateWindow, most SDL2 programs will do SDL_CreateRenderer(), + which will in turn call GL_CreateRenderer() or GLES2_CreateRenderer(). + In order for the GL_CreateRenderer() or GLES2_CreateRenderer() call to + succeed without an unnecessary window re-creation, we must: + -Mark the window as being OPENGL + -Load the GL library (which can't be done until the GBM device has been + created, so we have to do it here instead of doing it on VideoInit()) + and mark it as loaded by setting gl_config.driver_loaded to 1. + So if you ever see KMSDRM_CreateWindow() to be called two times in tests, + don't be shy to debug GL_CreateRenderer() or GLES2_CreateRenderer() + to find out why! + */ + + /* Reopen FD, create gbm dev, setup display plane, etc,. + but only when we come here for the first time, + and only if it's not a VK window. */ + ret = KMSDRM_GBMInit(_this, dispdata); + if (ret != 0) { + return SDL_SetError("Can't init GBM on window creation."); + } + } + + /* Manually load the GL library. KMSDRM_EGL_LoadLibrary() has already + been called by SDL_CreateWindow() but we don't do anything there, + our KMSDRM_EGL_LoadLibrary() is a dummy precisely to be able to load it here. + If we let SDL_CreateWindow() load the lib, it would be loaded + before we call KMSDRM_GBMInit(), causing all GLES programs to fail. */ + if (!_this->egl_data) { + egl_display = (NativeDisplayType)((SDL_VideoData *)_this->driverdata)->gbm_dev; + if (SDL_EGL_LoadLibrary(_this, NULL, egl_display, EGL_PLATFORM_GBM_MESA) < 0) { + /* Try again with OpenGL ES 2.0 */ + _this->gl_config.profile_mask = SDL_GL_CONTEXT_PROFILE_ES; + _this->gl_config.major_version = 2; + _this->gl_config.minor_version = 0; + if (SDL_EGL_LoadLibrary(_this, NULL, egl_display, EGL_PLATFORM_GBM_MESA) < 0) { + return SDL_SetError("Can't load EGL/GL library on window creation."); + } + } + + _this->gl_config.driver_loaded = 1; + } + + /* Create the cursor BO for the display of this window, + now that we know this is not a VK window. */ + KMSDRM_CreateCursorBO(display); + + /* Create and set the default cursor for the display + of this window, now that we know this is not a VK window. */ + KMSDRM_InitMouse(_this, display); + + /* The FULLSCREEN flags are cut out from window->flags at this point, + so we can't know if a window is fullscreen or not, hence all windows + are considered "windowed" at this point of their life. + If a window is fullscreen, SDL internals will call + KMSDRM_SetWindowFullscreen() to reconfigure it if necessary. */ + mode = KMSDRM_GetClosestDisplayMode(display, + window->windowed.w, window->windowed.h, 0); + + if (mode) { + dispdata->fullscreen_mode = *mode; + } else { + dispdata->fullscreen_mode = dispdata->original_mode; + } + + /* Create the window surfaces with the size we have just chosen. + Needs the window diverdata in place. */ + ret = KMSDRM_CreateSurfaces(_this, window); + if (ret != 0) { + return SDL_SetError("Can't window GBM/EGL surfaces on window creation."); + } + } /* NON-Vulkan block ends. */ + + /* Add window to the internal list of tracked windows. Note, while it may + seem odd to support multiple fullscreen windows, some apps create an + extra window as a dummy surface when working with multiple contexts */ + if (viddata->num_windows >= viddata->max_windows) { + unsigned int new_max_windows = viddata->max_windows + 1; + viddata->windows = (SDL_Window **)SDL_realloc(viddata->windows, + new_max_windows * sizeof(SDL_Window *)); + viddata->max_windows = new_max_windows; + + if (!viddata->windows) { + return SDL_OutOfMemory(); + } + } + + viddata->windows[viddata->num_windows++] = window; + + /* If we have just created a Vulkan window, establish that we are in Vulkan mode now. */ + viddata->vulkan_mode = is_vulkan; + + /* Focus on the newly created window. + SDL_SetMouseFocus() also takes care of calling KMSDRM_ShowCursor() if necessary. */ + SDL_SetMouseFocus(window); + SDL_SetKeyboardFocus(window); + + /* Tell the app that the window has moved to top-left. */ + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MOVED, 0, 0); + + /* Allocated windata will be freed in KMSDRM_DestroyWindow, + and KMSDRM_DestroyWindow() will be called by SDL_CreateWindow() + if we return error on any of the previous returns of the function. */ + return ret; +} + +int KMSDRM_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp) +{ + SDL_WindowData *windata = (SDL_WindowData*)window->driverdata; + SDL_VideoData *viddata = (SDL_VideoData*)windata->viddata; + SDL_VideoDisplay *disp = SDL_GetDisplayForWindow(window); + SDL_DisplayData* dispdata = (SDL_DisplayData*)disp->driverdata; + if (KMSDRM_drmModeCrtcGetGamma(viddata->drm_fd, dispdata->crtc->crtc_id, 256, &ramp[0*256], &ramp[1*256], &ramp[2*256]) == -1) + { + return SDL_SetError("Failed to get gamma ramp"); + } + return 0; +} + +int KMSDRM_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp) +{ + SDL_WindowData *windata = (SDL_WindowData*)window->driverdata; + SDL_VideoData *viddata = (SDL_VideoData*)windata->viddata; + SDL_VideoDisplay *disp = SDL_GetDisplayForWindow(window); + SDL_DisplayData* dispdata = (SDL_DisplayData*)disp->driverdata; + Uint16* tempRamp = SDL_calloc(3 * sizeof(Uint16), 256); + if (!tempRamp) + { + return SDL_OutOfMemory(); + } + SDL_memcpy(tempRamp, ramp, 3 * sizeof(Uint16) * 256); + if (KMSDRM_drmModeCrtcSetGamma(viddata->drm_fd, dispdata->crtc->crtc_id, 256, &tempRamp[0*256], &tempRamp[1*256], &tempRamp[2*256]) == -1) + { + SDL_free(tempRamp); + return SDL_SetError("Failed to set gamma ramp"); + } + SDL_free(tempRamp); + return 0; +} + +int KMSDRM_CreateWindowFrom(_THIS, SDL_Window * window, const void *data) +{ + return -1; +} + +void KMSDRM_SetWindowTitle(_THIS, SDL_Window *window) +{ +} +void KMSDRM_SetWindowIcon(_THIS, SDL_Window *window, SDL_Surface *icon) +{ +} +void KMSDRM_SetWindowPosition(_THIS, SDL_Window *window) +{ +} +void KMSDRM_SetWindowSize(_THIS, SDL_Window *window) +{ + SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); + if (!viddata->vulkan_mode) { + KMSDRM_DirtySurfaces(window); + } +} +void KMSDRM_SetWindowFullscreen(_THIS, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen) + +{ + SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); + if (!viddata->vulkan_mode) { + KMSDRM_DirtySurfaces(window); + } +} +void KMSDRM_ShowWindow(_THIS, SDL_Window *window) +{ +} +void KMSDRM_HideWindow(_THIS, SDL_Window *window) +{ +} +void KMSDRM_RaiseWindow(_THIS, SDL_Window *window) +{ +} +void KMSDRM_MaximizeWindow(_THIS, SDL_Window *window) +{ +} +void KMSDRM_MinimizeWindow(_THIS, SDL_Window *window) +{ +} +void KMSDRM_RestoreWindow(_THIS, SDL_Window *window) +{ +} + +/*****************************************************************************/ +/* SDL Window Manager function */ +/*****************************************************************************/ +SDL_bool KMSDRM_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info) +{ + SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); + const Uint32 version = SDL_VERSIONNUM((Uint32)info->version.major, + (Uint32)info->version.minor, + (Uint32)info->version.patch); + + if (version < SDL_VERSIONNUM(2, 0, 15)) { + SDL_SetError("Version must be 2.0.15 or newer"); + return SDL_FALSE; + } + + info->subsystem = SDL_SYSWM_KMSDRM; + info->info.kmsdrm.dev_index = viddata->devindex; + info->info.kmsdrm.drm_fd = viddata->drm_fd; + info->info.kmsdrm.gbm_dev = viddata->gbm_dev; + + return SDL_TRUE; +} + +#endif /* SDL_VIDEO_DRIVER_KMSDRM */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/kmsdrm/SDL_kmsdrmvideo.h b/SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmvideo.h similarity index 52% rename from SDL2-2.0.12/src/video/kmsdrm/SDL_kmsdrmvideo.h rename to SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmvideo.h index 63dcf6f..096f00c 100644 --- a/SDL2-2.0.12/src/video/kmsdrm/SDL_kmsdrmvideo.h +++ b/SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmvideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -31,62 +31,121 @@ #include #include #include -#if SDL_VIDEO_OPENGL_EGL #include + +#ifndef DRM_MODE_FB_MODIFIERS +#define DRM_MODE_FB_MODIFIERS 2 +#endif + +#ifndef DRM_MODE_PAGE_FLIP_ASYNC +#define DRM_MODE_PAGE_FLIP_ASYNC 2 +#endif + +#ifndef DRM_MODE_OBJECT_CONNECTOR +#define DRM_MODE_OBJECT_CONNECTOR 0xc0c0c0c0 +#endif + +#ifndef DRM_MODE_OBJECT_CRTC +#define DRM_MODE_OBJECT_CRTC 0xcccccccc +#endif + +#ifndef DRM_CAP_ASYNC_PAGE_FLIP +#define DRM_CAP_ASYNC_PAGE_FLIP 7 +#endif + +#ifndef DRM_CAP_CURSOR_WIDTH +#define DRM_CAP_CURSOR_WIDTH 8 +#endif + +#ifndef DRM_CAP_CURSOR_HEIGHT +#define DRM_CAP_CURSOR_HEIGHT 9 +#endif + +#ifndef GBM_FORMAT_ARGB8888 +#define GBM_FORMAT_ARGB8888 ((uint32_t)('A') | ((uint32_t)('R') << 8) | ((uint32_t)('2') << 16) | ((uint32_t)('4') << 24)) +#define GBM_BO_USE_CURSOR (1 << 1) +#define GBM_BO_USE_WRITE (1 << 3) +#define GBM_BO_USE_LINEAR (1 << 4) #endif typedef struct SDL_VideoData { - int devindex; /* device index that was passed on creation */ - int drm_fd; /* DRM file desc */ - struct gbm_device *gbm; + int devindex; /* device index that was passed on creation */ + int drm_fd; /* DRM file desc */ + char devpath[32]; /* DRM dev path. */ + + struct gbm_device *gbm_dev; + + SDL_bool video_init; /* Has VideoInit succeeded? */ + SDL_bool vulkan_mode; /* Are we in Vulkan mode? One VK window is enough to be. */ + SDL_bool async_pageflip_support; /* Does the hardware support async. pageflips? */ SDL_Window **windows; int max_windows; int num_windows; -} SDL_VideoData; + /* Even if we have several displays, we only have to + open 1 FD and create 1 gbm device. */ + SDL_bool gbm_init; + +} SDL_VideoData; typedef struct SDL_DisplayModeData { int mode_index; } SDL_DisplayModeData; - typedef struct SDL_DisplayData { - uint32_t crtc_id; - drmModeConnector *conn; + drmModeConnector *connector; + drmModeCrtc *crtc; drmModeModeInfo mode; - drmModeCrtc *saved_crtc; /* CRTC to restore on quit */ -} SDL_DisplayData; + drmModeModeInfo original_mode; + drmModeModeInfo fullscreen_mode; + drmModeCrtc *saved_crtc; /* CRTC to restore on quit */ + SDL_bool saved_vrr; + + /* DRM & GBM cursor stuff lives here, not in an SDL_Cursor's driverdata struct, + because setting/unsetting up these is done on window creation/destruction, + where we may not have an SDL_Cursor at all (so no SDL_Cursor driverdata). + There's only one cursor GBM BO because we only support one cursor. */ + struct gbm_bo *cursor_bo; + int cursor_bo_drm_fd; + uint64_t cursor_w, cursor_h; + + SDL_bool default_cursor_init; +} SDL_DisplayData; typedef struct SDL_WindowData { SDL_VideoData *viddata; + /* SDL internals expect EGL surface to be here, and in KMSDRM the GBM surface is + what supports the EGL surface on the driver side, so all these surfaces and buffers + are expected to be here, in the struct pointed by SDL_Window driverdata pointer: + this one. So don't try to move these to dispdata! */ struct gbm_surface *gs; - struct gbm_bo *curr_bo; + struct gbm_bo *bo; struct gbm_bo *next_bo; - struct gbm_bo *crtc_bo; + SDL_bool waiting_for_flip; SDL_bool double_buffer; -#if SDL_VIDEO_OPENGL_EGL - int egl_surface_dirty; + EGLSurface egl_surface; -#endif + SDL_bool egl_surface_dirty; } SDL_WindowData; typedef struct KMSDRM_FBInfo { - int drm_fd; /* DRM file desc */ - uint32_t fb_id; /* DRM framebuffer ID */ + int drm_fd; /* DRM file desc */ + uint32_t fb_id; /* DRM framebuffer ID */ } KMSDRM_FBInfo; /* Helper functions */ -int KMSDRM_CreateSurfaces(_THIS, SDL_Window * window); +int KMSDRM_CreateSurfaces(_THIS, SDL_Window *window); KMSDRM_FBInfo *KMSDRM_FBFromBO(_THIS, struct gbm_bo *bo); -SDL_bool KMSDRM_WaitPageFlip(_THIS, SDL_WindowData *windata, int timeout); +KMSDRM_FBInfo *KMSDRM_FBFromBO2(_THIS, struct gbm_bo *bo, int w, int h); +SDL_bool KMSDRM_WaitPageflip(_THIS, SDL_WindowData *windata); /****************************************************************************/ /* SDL_VideoDevice functions declaration */ @@ -103,13 +162,15 @@ void KMSDRM_SetWindowTitle(_THIS, SDL_Window * window); void KMSDRM_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon); void KMSDRM_SetWindowPosition(_THIS, SDL_Window * window); void KMSDRM_SetWindowSize(_THIS, SDL_Window * window); +void KMSDRM_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * _display, SDL_bool fullscreen); +int KMSDRM_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp); +int KMSDRM_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp); void KMSDRM_ShowWindow(_THIS, SDL_Window * window); void KMSDRM_HideWindow(_THIS, SDL_Window * window); void KMSDRM_RaiseWindow(_THIS, SDL_Window * window); void KMSDRM_MaximizeWindow(_THIS, SDL_Window * window); void KMSDRM_MinimizeWindow(_THIS, SDL_Window * window); void KMSDRM_RestoreWindow(_THIS, SDL_Window * window); -void KMSDRM_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed); void KMSDRM_DestroyWindow(_THIS, SDL_Window * window); /* Window manager function */ @@ -120,11 +181,11 @@ SDL_bool KMSDRM_GetWindowWMInfo(_THIS, SDL_Window * window, int KMSDRM_GLES_LoadLibrary(_THIS, const char *path); void *KMSDRM_GLES_GetProcAddress(_THIS, const char *proc); void KMSDRM_GLES_UnloadLibrary(_THIS); -SDL_GLContext KMSDRM_GLES_CreateContext(_THIS, SDL_Window * window); -int KMSDRM_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context); +SDL_GLContext KMSDRM_GLES_CreateContext(_THIS, SDL_Window *window); +int KMSDRM_GLES_MakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context); int KMSDRM_GLES_SetSwapInterval(_THIS, int interval); int KMSDRM_GLES_GetSwapInterval(_THIS); -int KMSDRM_GLES_SwapWindow(_THIS, SDL_Window * window); +int KMSDRM_GLES_SwapWindow(_THIS, SDL_Window *window); void KMSDRM_GLES_DeleteContext(_THIS, SDL_GLContext context); #endif /* __SDL_KMSDRMVIDEO_H__ */ diff --git a/SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmvulkan.c b/SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmvulkan.c new file mode 100644 index 0000000..b5dc7b8 --- /dev/null +++ b/SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmvulkan.c @@ -0,0 +1,528 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +/* + * @author Manuel Alfayate Corchere . + * Based on Jacob Lifshay's SDL_x11vulkan.c. + */ + +#include "../../SDL_internal.h" + +#if defined(SDL_VIDEO_VULKAN) && defined(SDL_VIDEO_DRIVER_KMSDRM) + +#include "SDL_kmsdrmvideo.h" +#include "SDL_kmsdrmdyn.h" +#include "SDL_assert.h" + +#include "SDL_loadso.h" +#include "SDL_kmsdrmvulkan.h" +#include "SDL_syswm.h" +#include "sys/ioctl.h" + +#if defined(__OpenBSD__) +#define DEFAULT_VULKAN "libvulkan.so" +#else +#define DEFAULT_VULKAN "libvulkan.so.1" +#endif + +int KMSDRM_Vulkan_LoadLibrary(_THIS, const char *path) +{ + VkExtensionProperties *extensions = NULL; + Uint32 i, extensionCount = 0; + SDL_bool hasSurfaceExtension = SDL_FALSE; + SDL_bool hasDisplayExtension = SDL_FALSE; + PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL; + + if (_this->vulkan_config.loader_handle) { + return SDL_SetError("Vulkan already loaded"); + } + + /* Load the Vulkan library */ + if (!path) { + path = SDL_getenv("SDL_VULKAN_LIBRARY"); + } + if (!path) { + path = DEFAULT_VULKAN; + } + + _this->vulkan_config.loader_handle = SDL_LoadObject(path); + + if (!_this->vulkan_config.loader_handle) { + return -1; + } + + SDL_strlcpy(_this->vulkan_config.loader_path, path, + SDL_arraysize(_this->vulkan_config.loader_path)); + + vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)SDL_LoadFunction( + _this->vulkan_config.loader_handle, "vkGetInstanceProcAddr"); + + if (!vkGetInstanceProcAddr) { + goto fail; + } + + _this->vulkan_config.vkGetInstanceProcAddr = (void *)vkGetInstanceProcAddr; + _this->vulkan_config.vkEnumerateInstanceExtensionProperties = + (void *)((PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr)( + VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties"); + + if (!_this->vulkan_config.vkEnumerateInstanceExtensionProperties) { + goto fail; + } + + extensions = SDL_Vulkan_CreateInstanceExtensionsList( + (PFN_vkEnumerateInstanceExtensionProperties) + _this->vulkan_config.vkEnumerateInstanceExtensionProperties, + &extensionCount); + + if (!extensions) { + goto fail; + } + + for (i = 0; i < extensionCount; i++) { + if (SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) { + hasSurfaceExtension = SDL_TRUE; + } else if (SDL_strcmp(VK_KHR_DISPLAY_EXTENSION_NAME, extensions[i].extensionName) == 0) { + hasDisplayExtension = SDL_TRUE; + } + } + + SDL_free(extensions); + + if (!hasSurfaceExtension) { + SDL_SetError("Installed Vulkan doesn't implement the " VK_KHR_SURFACE_EXTENSION_NAME " extension"); + goto fail; + } else if (!hasDisplayExtension) { + SDL_SetError("Installed Vulkan doesn't implement the " VK_KHR_DISPLAY_EXTENSION_NAME "extension"); + goto fail; + } + + return 0; + +fail: + SDL_UnloadObject(_this->vulkan_config.loader_handle); + _this->vulkan_config.loader_handle = NULL; + return -1; +} + +void KMSDRM_Vulkan_UnloadLibrary(_THIS) +{ + if (_this->vulkan_config.loader_handle) { + SDL_UnloadObject(_this->vulkan_config.loader_handle); + _this->vulkan_config.loader_handle = NULL; + } +} + +/*********************************************************************/ +/* Here we can put whatever Vulkan extensions we want to be enabled */ +/* at instance creation, which is done in the programs, not in SDL. */ +/* So: programs call SDL_Vulkan_GetInstanceExtensions() and here */ +/* we put the extensions specific to this backend so the programs */ +/* get a list with the extension we want, so they can include that */ +/* list in the ppEnabledExtensionNames and EnabledExtensionCount */ +/* members of the VkInstanceCreateInfo struct passed to */ +/* vkCreateInstance(). */ +/*********************************************************************/ +SDL_bool KMSDRM_Vulkan_GetInstanceExtensions(_THIS, + SDL_Window *window, + unsigned *count, + const char **names) +{ + static const char *const extensionsForKMSDRM[] = { + VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_DISPLAY_EXTENSION_NAME + }; + if (!_this->vulkan_config.loader_handle) { + SDL_SetError("Vulkan is not loaded"); + return SDL_FALSE; + } + return SDL_Vulkan_GetInstanceExtensions_Helper( + count, names, SDL_arraysize(extensionsForKMSDRM), + extensionsForKMSDRM); +} + +void KMSDRM_Vulkan_GetDrawableSize(_THIS, SDL_Window *window, int *w, int *h) +{ + if (w) { + *w = window->w; + } + + if (h) { + *h = window->h; + } +} + +/***********************************************************************/ +/* First thing to know is that we don't call vkCreateInstance() here. */ +/* Instead, programs using SDL and Vulkan create their Vulkan instance */ +/* and we get it here, ready to use. */ +/* Extensions specific for this platform are activated in */ +/* KMSDRM_Vulkan_GetInstanceExtensions(), like we do with */ +/* VK_KHR_DISPLAY_EXTENSION_NAME, which is what we need for x-less VK. */ +/***********************************************************************/ +SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS, + SDL_Window *window, + VkInstance instance, + VkSurfaceKHR *surface) +{ + VkPhysicalDevice gpu = NULL; + uint32_t gpu_count; + uint32_t display_count; + uint32_t mode_count; + uint32_t plane_count; + uint32_t plane = UINT32_MAX; + + VkPhysicalDevice *physical_devices = NULL; + VkPhysicalDeviceProperties *device_props = NULL; + VkDisplayPropertiesKHR *display_props = NULL; + VkDisplayModePropertiesKHR *mode_props = NULL; + VkDisplayPlanePropertiesKHR *plane_props = NULL; + VkDisplayPlaneCapabilitiesKHR plane_caps; + + VkDisplayModeCreateInfoKHR display_mode_create_info; + VkDisplaySurfaceCreateInfoKHR display_plane_surface_create_info; + + VkExtent2D image_size; + VkDisplayKHR display; + VkDisplayModeKHR display_mode = (VkDisplayModeKHR)0; + VkDisplayModePropertiesKHR display_mode_props = { 0 }; + VkDisplayModeParametersKHR new_mode_parameters = { { 0, 0 }, 0 }; + /* Prefer a plane that supports per-pixel alpha. */ + VkDisplayPlaneAlphaFlagBitsKHR alpha_mode = VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR; + + VkResult result; + SDL_bool ret = SDL_FALSE; + SDL_bool valid_gpu = SDL_FALSE; + SDL_bool mode_found = SDL_FALSE; + SDL_bool plane_supports_display = SDL_FALSE; + + /* Get the display index from the display being used by the window. */ + int display_index = SDL_atoi(SDL_GetDisplayForWindow(window)->name); + int i, j; + + /* Get the function pointers for the functions we will use. */ + PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = + (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr; + + PFN_vkCreateDisplayPlaneSurfaceKHR vkCreateDisplayPlaneSurfaceKHR = + (PFN_vkCreateDisplayPlaneSurfaceKHR)vkGetInstanceProcAddr( + instance, "vkCreateDisplayPlaneSurfaceKHR"); + + PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices = + (PFN_vkEnumeratePhysicalDevices)vkGetInstanceProcAddr( + instance, "vkEnumeratePhysicalDevices"); + + PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties = + (PFN_vkGetPhysicalDeviceProperties)vkGetInstanceProcAddr( + instance, "vkGetPhysicalDeviceProperties"); + + PFN_vkGetPhysicalDeviceDisplayPropertiesKHR vkGetPhysicalDeviceDisplayPropertiesKHR = + (PFN_vkGetPhysicalDeviceDisplayPropertiesKHR)vkGetInstanceProcAddr( + instance, "vkGetPhysicalDeviceDisplayPropertiesKHR"); + + PFN_vkGetDisplayModePropertiesKHR vkGetDisplayModePropertiesKHR = + (PFN_vkGetDisplayModePropertiesKHR)vkGetInstanceProcAddr( + instance, "vkGetDisplayModePropertiesKHR"); + + PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR vkGetPhysicalDeviceDisplayPlanePropertiesKHR = + (PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR)vkGetInstanceProcAddr( + instance, "vkGetPhysicalDeviceDisplayPlanePropertiesKHR"); + + PFN_vkGetDisplayPlaneSupportedDisplaysKHR vkGetDisplayPlaneSupportedDisplaysKHR = + (PFN_vkGetDisplayPlaneSupportedDisplaysKHR)vkGetInstanceProcAddr( + instance, "vkGetDisplayPlaneSupportedDisplaysKHR"); + + PFN_vkGetDisplayPlaneCapabilitiesKHR vkGetDisplayPlaneCapabilitiesKHR = + (PFN_vkGetDisplayPlaneCapabilitiesKHR)vkGetInstanceProcAddr( + instance, "vkGetDisplayPlaneCapabilitiesKHR"); + + PFN_vkCreateDisplayModeKHR vkCreateDisplayModeKHR = + (PFN_vkCreateDisplayModeKHR)vkGetInstanceProcAddr( + instance, "vkCreateDisplayModeKHR"); + + if (!_this->vulkan_config.loader_handle) { + SDL_SetError("Vulkan is not loaded"); + goto clean; + } + + /*************************************/ + /* Block for vulkan surface creation */ + /*************************************/ + + /****************************************************************/ + /* If we got vkCreateDisplayPlaneSurfaceKHR() pointer, it means */ + /* that the VK_KHR_Display extension is active on the instance. */ + /* That's the central extension we need for x-less VK! */ + /****************************************************************/ + if (!vkCreateDisplayPlaneSurfaceKHR) { + SDL_SetError(VK_KHR_DISPLAY_EXTENSION_NAME + " extension is not enabled in the Vulkan instance."); + goto clean; + } + + /* A GPU (or physical_device, in vkcube terms) is a physical GPU. + A machine with more than one video output doesn't need to have more than one GPU, + like the Pi4 which has 1 GPU and 2 video outputs. + Just in case, we test that the GPU we choose is Vulkan-capable. + If there are new reports about VK init failures, hardcode + gpu = physical_devices[0], instead of probing, and go with that. + */ + + /* Get the physical device count. */ + vkEnumeratePhysicalDevices(instance, &gpu_count, NULL); + + if (gpu_count == 0) { + SDL_SetError("Vulkan can't find physical devices (gpus)."); + goto clean; + } + + /* Get the physical devices. */ + physical_devices = SDL_malloc(sizeof(VkPhysicalDevice) * gpu_count); + device_props = SDL_malloc(sizeof(VkPhysicalDeviceProperties)); + vkEnumeratePhysicalDevices(instance, &gpu_count, physical_devices); + + /* Iterate on the physical devices. */ + for (i = 0; i < gpu_count; i++) { + + /* Get the physical device properties. */ + vkGetPhysicalDeviceProperties( + physical_devices[i], + device_props); + + /* Is this device a real GPU that supports API version 1 at least? */ + if (device_props->apiVersion >= 1 && + (device_props->deviceType == 1 || device_props->deviceType == 2)) { + gpu = physical_devices[i]; + valid_gpu = SDL_TRUE; + break; + } + } + + if (!valid_gpu) { + SDL_SetError("Vulkan can't find a valid physical device (gpu)."); + goto clean; + } + + /* A display is a video output. 1 GPU can have N displays. + Vulkan only counts the connected displays. + Get the display count of the GPU. */ + vkGetPhysicalDeviceDisplayPropertiesKHR(gpu, &display_count, NULL); + if (display_count == 0) { + SDL_SetError("Vulkan can't find any displays."); + goto clean; + } + + /* Get the props of the displays of the physical device. */ + display_props = (VkDisplayPropertiesKHR *)SDL_malloc(display_count * sizeof(*display_props)); + vkGetPhysicalDeviceDisplayPropertiesKHR(gpu, + &display_count, + display_props); + + /* Get the chosen display based on the display index. */ + display = display_props[display_index].display; + + /* Get the list of the display videomodes. */ + vkGetDisplayModePropertiesKHR(gpu, + display, + &mode_count, NULL); + + if (mode_count == 0) { + SDL_SetError("Vulkan can't find any video modes for display %i (%s)\n", 0, + display_props[display_index].displayName); + goto clean; + } + + mode_props = (VkDisplayModePropertiesKHR *)SDL_malloc(mode_count * sizeof(*mode_props)); + vkGetDisplayModePropertiesKHR(gpu, + display, + &mode_count, mode_props); + + /* Get a video mode equal to the window size among the predefined ones, + if possible. + REMEMBER: We have to get a small enough videomode for the window size, + because videomode determines how big the scanout region is and we can't + scanout a region bigger than the window (we would be reading past the + buffer, and Vulkan would give us a confusing VK_ERROR_SURFACE_LOST_KHR). */ + for (i = 0; i < mode_count; i++) { + if (mode_props[i].parameters.visibleRegion.width == window->w && + mode_props[i].parameters.visibleRegion.height == window->h) { + display_mode_props = mode_props[i]; + mode_found = SDL_TRUE; + break; + } + } + + if (mode_found && + display_mode_props.parameters.visibleRegion.width > 0 && + display_mode_props.parameters.visibleRegion.height > 0) { + /* Found a suitable mode among the predefined ones. Use that. */ + display_mode = display_mode_props.displayMode; + } else { + + /* Couldn't find a suitable mode among the predefined ones, so try to create our own. + This won't work for some video chips atm (like Pi's VideoCore) so these are limited + to supported resolutions. Don't try to use "closest" resolutions either, because + those are often bigger than the window size, thus causing out-of-bunds scanout. */ + new_mode_parameters.visibleRegion.width = window->w; + new_mode_parameters.visibleRegion.height = window->h; + /* SDL (and DRM, if we look at drmModeModeInfo vrefresh) uses plain integer Hz for + display mode refresh rate, but Vulkan expects higher precision. */ + new_mode_parameters.refreshRate = window->fullscreen_mode.refresh_rate * 1000; + + SDL_zero(display_mode_create_info); + display_mode_create_info.sType = VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR; + display_mode_create_info.parameters = new_mode_parameters; + result = vkCreateDisplayModeKHR(gpu, + display, + &display_mode_create_info, + NULL, &display_mode); + if (result != VK_SUCCESS) { + SDL_SetError("Vulkan couldn't find a predefined mode for that window size and couldn't create a suitable mode."); + goto clean; + } + } + + /* Just in case we get here without a display_mode. */ + if (!display_mode) { + SDL_SetError("Vulkan couldn't get a display mode."); + goto clean; + } + + /* Get the list of the physical device planes. */ + vkGetPhysicalDeviceDisplayPlanePropertiesKHR(gpu, &plane_count, NULL); + if (plane_count == 0) { + SDL_SetError("Vulkan can't find any planes."); + goto clean; + } + plane_props = SDL_malloc(sizeof(VkDisplayPlanePropertiesKHR) * plane_count); + vkGetPhysicalDeviceDisplayPlanePropertiesKHR(gpu, &plane_count, plane_props); + + /* Iterate on the list of planes of the physical device + to find a plane that matches these criteria: + -It must be compatible with the chosen display + mode. + -It isn't currently bound to another display. + -It supports per-pixel alpha, if possible. */ + for (i = 0; i < plane_count; i++) { + + uint32_t supported_displays_count = 0; + VkDisplayKHR *supported_displays; + + /* See if the plane is compatible with the current display. */ + vkGetDisplayPlaneSupportedDisplaysKHR(gpu, i, &supported_displays_count, NULL); + if (supported_displays_count == 0) { + /* This plane doesn't support any displays. Continue to the next plane. */ + continue; + } + + /* Get the list of displays supported by this plane. */ + supported_displays = (VkDisplayKHR *)SDL_malloc(sizeof(VkDisplayKHR) * supported_displays_count); + vkGetDisplayPlaneSupportedDisplaysKHR(gpu, i, + &supported_displays_count, supported_displays); + + /* The plane must be bound to the chosen display, or not in use. + If none of these is true, iterate to another plane. */ + if (!((plane_props[i].currentDisplay == display) || (plane_props[i].currentDisplay == VK_NULL_HANDLE))) { + continue; + } + + /* Iterate the list of displays supported by this plane + in order to find out if the chosen display is among them. */ + plane_supports_display = SDL_FALSE; + for (j = 0; j < supported_displays_count; j++) { + if (supported_displays[j] == display) { + plane_supports_display = SDL_TRUE; + break; + } + } + + /* Free the list of displays supported by this plane. */ + if (supported_displays) { + SDL_free(supported_displays); + } + + /* If the display is not supported by this plane, iterate to the next plane. */ + if (!plane_supports_display) { + continue; + } + + /* Want a plane that supports the alpha mode we have chosen. */ + vkGetDisplayPlaneCapabilitiesKHR(gpu, display_mode, i, &plane_caps); + if (plane_caps.supportedAlpha == alpha_mode) { + /* Yep, this plane is alright. */ + plane = i; + break; + } + } + + /* If we couldn't find an appropriate plane, error out. */ + if (plane == UINT32_MAX) { + SDL_SetError("Vulkan couldn't find an appropriate plane."); + goto clean; + } + + /********************************************/ + /* Let's finally create the Vulkan surface! */ + /********************************************/ + + image_size.width = window->w; + image_size.height = window->h; + + SDL_zero(display_plane_surface_create_info); + display_plane_surface_create_info.sType = VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR; + display_plane_surface_create_info.displayMode = display_mode; + display_plane_surface_create_info.planeIndex = plane; + display_plane_surface_create_info.imageExtent = image_size; + display_plane_surface_create_info.transform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; + display_plane_surface_create_info.alphaMode = alpha_mode; + result = vkCreateDisplayPlaneSurfaceKHR(instance, + &display_plane_surface_create_info, + NULL, + surface); + if (result != VK_SUCCESS) { + SDL_SetError("vkCreateDisplayPlaneSurfaceKHR failed: %s", + SDL_Vulkan_GetResultString(result)); + goto clean; + } + + ret = SDL_TRUE; + +clean: + if (physical_devices) { + SDL_free(physical_devices); + } + if (display_props) { + SDL_free(display_props); + } + if (device_props) { + SDL_free(device_props); + } + if (plane_props) { + SDL_free(plane_props); + } + if (mode_props) { + SDL_free(mode_props); + } + + return ret; +} + +#endif + +/* vim: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmvulkan.h b/SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmvulkan.h new file mode 100644 index 0000000..01a582a --- /dev/null +++ b/SDL2-2.30.5/src/video/kmsdrm/SDL_kmsdrmvulkan.h @@ -0,0 +1,53 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +/* + * @author Manuel Alfayate Corchere . + * Based on Jacob Lifshay's SDL_x11vulkan.c. + */ + +#include "../../SDL_internal.h" + +#ifndef SDL_kmsdrm_vulkan_h_ +#define SDL_kmsdrm_vulkan_h_ + +#include "../SDL_vulkan_internal.h" +#include "../SDL_sysvideo.h" + +#if defined(SDL_VIDEO_VULKAN) && defined(SDL_VIDEO_DRIVER_KMSDRM) + +int KMSDRM_Vulkan_LoadLibrary(_THIS, const char *path); +void KMSDRM_Vulkan_UnloadLibrary(_THIS); +SDL_bool KMSDRM_Vulkan_GetInstanceExtensions(_THIS, + SDL_Window *window, + unsigned *count, + const char **names); +void KMSDRM_Vulkan_GetDrawableSize(_THIS, SDL_Window *window, int *w, int *h); +SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS, + SDL_Window *window, + VkInstance instance, + VkSurfaceKHR *surface); + +#endif + +#endif /* SDL_kmsdrm_vulkan_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/n3ds/SDL_n3dsevents.c b/SDL2-2.30.5/src/video/n3ds/SDL_n3dsevents.c new file mode 100644 index 0000000..c45bb80 --- /dev/null +++ b/SDL2-2.30.5/src/video/n3ds/SDL_n3dsevents.c @@ -0,0 +1,46 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_N3DS + +#include <3ds.h> + +#include "../../events/SDL_events_c.h" +#include "SDL_n3dsevents_c.h" +#include "SDL_n3dstouch.h" + +void N3DS_PumpEvents(_THIS) +{ + hidScanInput(); + N3DS_PollTouch(); + + if (!aptMainLoop()) { + SDL_Event ev; + ev.type = SDL_QUIT; + SDL_PushEvent(&ev); + return; + } +} + +#endif /* SDL_VIDEO_DRIVER_N3DS */ + +/* vi: set sts=4 ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/n3ds/SDL_n3dsevents_c.h b/SDL2-2.30.5/src/video/n3ds/SDL_n3dsevents_c.h new file mode 100644 index 0000000..2e75951 --- /dev/null +++ b/SDL2-2.30.5/src/video/n3ds/SDL_n3dsevents_c.h @@ -0,0 +1,31 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#ifndef SDL_n3dsevents_c_h_ +#define SDL_n3dsevents_c_h_ + +#include "../../SDL_internal.h" + +extern void N3DS_PumpEvents(_THIS); + +#endif /* SDL_n3dsevents_c_h_ */ + +/* vi: set sts=4 ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/n3ds/SDL_n3dsframebuffer.c b/SDL2-2.30.5/src/video/n3ds/SDL_n3dsframebuffer.c new file mode 100644 index 0000000..784c2df --- /dev/null +++ b/SDL2-2.30.5/src/video/n3ds/SDL_n3dsframebuffer.c @@ -0,0 +1,145 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_N3DS + +#include "../SDL_sysvideo.h" +#include "SDL_n3dsframebuffer_c.h" +#include "SDL_n3dsvideo.h" + +#define N3DS_SURFACE "_SDL_N3DSSurface" + +typedef struct +{ + int width, height; +} Dimensions; + +SDL_FORCE_INLINE void FreePreviousWindowFramebuffer(SDL_Window *window); +SDL_FORCE_INLINE SDL_Surface *CreateNewWindowFramebuffer(SDL_Window *window); +SDL_FORCE_INLINE void CopyFramebuffertoN3DS(u32 *dest, const Dimensions dest_dim, const u32 *source, const Dimensions source_dim); +SDL_FORCE_INLINE int GetDestOffset(int x, int y, int dest_width); +SDL_FORCE_INLINE int GetSourceOffset(int x, int y, int source_width); +SDL_FORCE_INLINE void FlushN3DSBuffer(const void *buffer, u32 bufsize, gfxScreen_t screen); + +int SDL_N3DS_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format, void **pixels, int *pitch) +{ + SDL_Surface *framebuffer; + + FreePreviousWindowFramebuffer(window); + framebuffer = CreateNewWindowFramebuffer(window); + + if (!framebuffer) { + return SDL_OutOfMemory(); + } + + SDL_SetWindowData(window, N3DS_SURFACE, framebuffer); + *format = FRAMEBUFFER_FORMAT; + *pixels = framebuffer->pixels; + *pitch = framebuffer->pitch; + return 0; +} + +SDL_FORCE_INLINE void +FreePreviousWindowFramebuffer(SDL_Window *window) +{ + SDL_Surface *surface = (SDL_Surface *)SDL_GetWindowData(window, N3DS_SURFACE); + SDL_FreeSurface(surface); +} + +SDL_FORCE_INLINE SDL_Surface * +CreateNewWindowFramebuffer(SDL_Window *window) +{ + int w, h, bpp; + Uint32 Rmask, Gmask, Bmask, Amask; + SDL_PixelFormatEnumToMasks(FRAMEBUFFER_FORMAT, &bpp, &Rmask, &Gmask, &Bmask, &Amask); + SDL_GetWindowSizeInPixels(window, &w, &h); + return SDL_CreateRGBSurface(0, w, h, bpp, Rmask, Gmask, Bmask, Amask); +} + +int SDL_N3DS_UpdateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_Rect *rects, int numrects) +{ + SDL_WindowData *drv_data = (SDL_WindowData *)window->driverdata; + SDL_Surface *surface; + u16 width, height; + u32 *framebuffer; + u32 bufsize; + + surface = (SDL_Surface *)SDL_GetWindowData(window, N3DS_SURFACE); + if (!surface) { + return SDL_SetError("%s: Unable to get the window surface.", __func__); + } + + /* Get the N3DS internal framebuffer and its size */ + framebuffer = (u32 *)gfxGetFramebuffer(drv_data->screen, GFX_LEFT, &width, &height); + bufsize = width * height * 4; + + CopyFramebuffertoN3DS(framebuffer, (Dimensions){ width, height }, + surface->pixels, (Dimensions){ surface->w, surface->h }); + FlushN3DSBuffer(framebuffer, bufsize, drv_data->screen); + + return 0; +} + +SDL_FORCE_INLINE void +CopyFramebuffertoN3DS(u32 *dest, const Dimensions dest_dim, const u32 *source, const Dimensions source_dim) +{ + int rows = SDL_min(dest_dim.width, source_dim.height); + int cols = SDL_min(dest_dim.height, source_dim.width); + for (int y = 0; y < rows; ++y) { + for (int x = 0; x < cols; ++x) { + SDL_memcpy( + dest + GetDestOffset(x, y, dest_dim.width), + source + GetSourceOffset(x, y, source_dim.width), + 4); + } + } +} + +SDL_FORCE_INLINE int +GetDestOffset(int x, int y, int dest_width) +{ + return dest_width - y - 1 + dest_width * x; +} + +SDL_FORCE_INLINE int +GetSourceOffset(int x, int y, int source_width) +{ + return x + y * source_width; +} + +SDL_FORCE_INLINE void +FlushN3DSBuffer(const void *buffer, u32 bufsize, gfxScreen_t screen) +{ + GSPGPU_FlushDataCache(buffer, bufsize); + gfxScreenSwapBuffers(screen, false); +} + +void SDL_N3DS_DestroyWindowFramebuffer(_THIS, SDL_Window *window) +{ + SDL_Surface *surface; + surface = (SDL_Surface *)SDL_SetWindowData(window, N3DS_SURFACE, NULL); + SDL_FreeSurface(surface); +} + +#endif /* SDL_VIDEO_DRIVER_N3DS */ + +/* vi: set sts=4 ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/n3ds/SDL_n3dsframebuffer_c.h b/SDL2-2.30.5/src/video/n3ds/SDL_n3dsframebuffer_c.h new file mode 100644 index 0000000..19a9e95 --- /dev/null +++ b/SDL2-2.30.5/src/video/n3ds/SDL_n3dsframebuffer_c.h @@ -0,0 +1,33 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#ifndef SDL_n3dsframebuffer_c_h_ +#define SDL_n3dsframebuffer_c_h_ + +#include "../../SDL_internal.h" + +int SDL_N3DS_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format, void **pixels, int *pitch); +int SDL_N3DS_UpdateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_Rect *rects, int numrects); +void SDL_N3DS_DestroyWindowFramebuffer(_THIS, SDL_Window *window); + +#endif /* SDL_n3dsframebuffer_c_h_ */ + +/* vi: set sts=4 ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/n3ds/SDL_n3dsswkb.c b/SDL2-2.30.5/src/video/n3ds/SDL_n3dsswkb.c new file mode 100644 index 0000000..9a35d27 --- /dev/null +++ b/SDL2-2.30.5/src/video/n3ds/SDL_n3dsswkb.c @@ -0,0 +1,70 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_N3DS + +#include <3ds.h> + +#include "SDL_n3dsswkb.h" + +static SwkbdState sw_keyboard; +const static size_t BUFFER_SIZE = 256; + +void N3DS_SwkbInit() +{ + swkbdInit(&sw_keyboard, SWKBD_TYPE_NORMAL, 2, -1); +} + +void N3DS_SwkbPoll() +{ + return; +} + +void N3DS_SwkbQuit() +{ + return; +} + +SDL_bool N3DS_HasScreenKeyboardSupport(_THIS) +{ + return SDL_TRUE; +} + +void N3DS_StartTextInput(_THIS) +{ + char buffer[BUFFER_SIZE]; + SwkbdButton button_pressed; + button_pressed = swkbdInputText(&sw_keyboard, buffer, BUFFER_SIZE); + if (button_pressed == SWKBD_BUTTON_CONFIRM) { + SDL_SendKeyboardText(buffer); + } +} + +void N3DS_StopTextInput(_THIS) +{ + return; +} + +#endif /* SDL_VIDEO_DRIVER_N3DS */ + +/* vi: set sts=4 ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/n3ds/SDL_n3dsswkb.h b/SDL2-2.30.5/src/video/n3ds/SDL_n3dsswkb.h new file mode 100644 index 0000000..04a355b --- /dev/null +++ b/SDL2-2.30.5/src/video/n3ds/SDL_n3dsswkb.h @@ -0,0 +1,38 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#ifndef SDL_n3dskeyboard_h_ +#define SDL_n3dskeyboard_h_ + +#include "../../events/SDL_events_c.h" + +void N3DS_SwkbInit(); +void N3DS_SwkbPoll(); +void N3DS_SwkbQuit(); + +SDL_bool N3DS_HasScreenKeyboardSupport(_THIS); + +void N3DS_StartTextInput(_THIS); +void N3DS_StopTextInput(_THIS); + +#endif /* SDL_n3dskeyboard_h_ */ + +/* vi: set sts=4 ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/n3ds/SDL_n3dstouch.c b/SDL2-2.30.5/src/video/n3ds/SDL_n3dstouch.c new file mode 100644 index 0000000..982c578 --- /dev/null +++ b/SDL2-2.30.5/src/video/n3ds/SDL_n3dstouch.c @@ -0,0 +1,81 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_N3DS + +#include <3ds.h> + +#include "../../events/SDL_touch_c.h" +#include "SDL_n3dstouch.h" + +#define N3DS_TOUCH_ID 0 + +/* + Factors used to convert touchscreen coordinates to + SDL's 0-1 values. Note that the N3DS's screen is + internally in a portrait disposition so the + GSP_SCREEN constants are flipped. +*/ +#define TOUCHSCREEN_SCALE_X 1.0f / GSP_SCREEN_HEIGHT_BOTTOM +#define TOUCHSCREEN_SCALE_Y 1.0f / GSP_SCREEN_WIDTH + +void N3DS_InitTouch(void) +{ + SDL_AddTouch(N3DS_TOUCH_ID, SDL_TOUCH_DEVICE_DIRECT, "Touchscreen"); +} + +void N3DS_QuitTouch(void) +{ + SDL_DelTouch(N3DS_TOUCH_ID); +} + +void N3DS_PollTouch(void) +{ + touchPosition touch; + static SDL_bool was_pressed = SDL_FALSE; + SDL_bool pressed; + hidTouchRead(&touch); + pressed = (touch.px != 0 || touch.py != 0); + + if (pressed != was_pressed) { + was_pressed = pressed; + SDL_SendTouch(N3DS_TOUCH_ID, + 0, + NULL, + pressed, + touch.px * TOUCHSCREEN_SCALE_X, + touch.py * TOUCHSCREEN_SCALE_Y, + pressed ? 1.0f : 0.0f); + } else if (pressed) { + SDL_SendTouchMotion(N3DS_TOUCH_ID, + 0, + NULL, + touch.px * TOUCHSCREEN_SCALE_X, + touch.py * TOUCHSCREEN_SCALE_Y, + 1.0f); + } +} + +#endif /* SDL_VIDEO_DRIVER_N3DS */ + +/* vi: set sts=4 ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/n3ds/SDL_n3dstouch.h b/SDL2-2.30.5/src/video/n3ds/SDL_n3dstouch.h new file mode 100644 index 0000000..d99e5a3 --- /dev/null +++ b/SDL2-2.30.5/src/video/n3ds/SDL_n3dstouch.h @@ -0,0 +1,31 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#ifndef SDL_n3dstouch_h_ +#define SDL_n3dstouch_h_ + +void N3DS_InitTouch(void); +void N3DS_QuitTouch(void); +void N3DS_PollTouch(void); + +#endif /* SDL_n3dstouch_h_ */ + +/* vi: set sts=4 ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/n3ds/SDL_n3dsvideo.c b/SDL2-2.30.5/src/video/n3ds/SDL_n3dsvideo.c new file mode 100644 index 0000000..fc875d3 --- /dev/null +++ b/SDL2-2.30.5/src/video/n3ds/SDL_n3dsvideo.c @@ -0,0 +1,188 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_N3DS + +#include "../SDL_sysvideo.h" +#include "SDL_n3dsevents_c.h" +#include "SDL_n3dsframebuffer_c.h" +#include "SDL_n3dsswkb.h" +#include "SDL_n3dstouch.h" +#include "SDL_n3dsvideo.h" + +#define N3DSVID_DRIVER_NAME "n3ds" + +SDL_FORCE_INLINE void AddN3DSDisplay(gfxScreen_t screen); + +static int N3DS_VideoInit(_THIS); +static void N3DS_VideoQuit(_THIS); +static void N3DS_GetDisplayModes(_THIS, SDL_VideoDisplay *display); +static int N3DS_GetDisplayBounds(_THIS, SDL_VideoDisplay *display, SDL_Rect *rect); +static int N3DS_CreateWindow(_THIS, SDL_Window *window); +static void N3DS_DestroyWindow(_THIS, SDL_Window *window); + +typedef struct +{ + gfxScreen_t screen; +} DisplayDriverData; + +/* N3DS driver bootstrap functions */ + +static void N3DS_DeleteDevice(SDL_VideoDevice *device) +{ + SDL_free(device->displays); + SDL_free(device->driverdata); + SDL_free(device); +} + +static SDL_VideoDevice *N3DS_CreateDevice(void) +{ + SDL_VideoDevice *device = (SDL_VideoDevice *)SDL_calloc(1, sizeof(SDL_VideoDevice)); + if (!device) { + SDL_OutOfMemory(); + return 0; + } + + device->VideoInit = N3DS_VideoInit; + device->VideoQuit = N3DS_VideoQuit; + + device->GetDisplayModes = N3DS_GetDisplayModes; + device->GetDisplayBounds = N3DS_GetDisplayBounds; + + device->CreateSDLWindow = N3DS_CreateWindow; + device->DestroyWindow = N3DS_DestroyWindow; + + device->HasScreenKeyboardSupport = N3DS_HasScreenKeyboardSupport; + device->StartTextInput = N3DS_StartTextInput; + device->StopTextInput = N3DS_StopTextInput; + + device->PumpEvents = N3DS_PumpEvents; + + device->CreateWindowFramebuffer = SDL_N3DS_CreateWindowFramebuffer; + device->UpdateWindowFramebuffer = SDL_N3DS_UpdateWindowFramebuffer; + device->DestroyWindowFramebuffer = SDL_N3DS_DestroyWindowFramebuffer; + + device->free = N3DS_DeleteDevice; + + return device; +} + +VideoBootStrap N3DS_bootstrap = { N3DSVID_DRIVER_NAME, "N3DS Video Driver", N3DS_CreateDevice, NULL /* no ShowMessageBox implementation */ }; + +static int N3DS_VideoInit(_THIS) +{ + gfxInit(GSP_RGBA8_OES, GSP_RGBA8_OES, false); + hidInit(); + + AddN3DSDisplay(GFX_TOP); + AddN3DSDisplay(GFX_BOTTOM); + + N3DS_InitTouch(); + N3DS_SwkbInit(); + + return 0; +} + +SDL_FORCE_INLINE void +AddN3DSDisplay(gfxScreen_t screen) +{ + SDL_DisplayMode mode; + SDL_VideoDisplay display; + DisplayDriverData *display_driver_data = SDL_calloc(1, sizeof(DisplayDriverData)); + if (!display_driver_data) { + SDL_OutOfMemory(); + return; + } + + SDL_zero(mode); + SDL_zero(display); + + display_driver_data->screen = screen; + + mode.w = (screen == GFX_TOP) ? GSP_SCREEN_HEIGHT_TOP : GSP_SCREEN_HEIGHT_BOTTOM; + mode.h = GSP_SCREEN_WIDTH; + mode.refresh_rate = 60; + mode.format = FRAMEBUFFER_FORMAT; + mode.driverdata = NULL; + + display.name = (screen == GFX_TOP) ? "N3DS top screen" : "N3DS bottom screen"; + display.desktop_mode = mode; + display.current_mode = mode; + display.driverdata = display_driver_data; + + SDL_AddVideoDisplay(&display, SDL_FALSE); +} + +static void N3DS_VideoQuit(_THIS) +{ + N3DS_SwkbQuit(); + N3DS_QuitTouch(); + + hidExit(); + gfxExit(); +} + +static void N3DS_GetDisplayModes(_THIS, SDL_VideoDisplay *display) +{ + /* Each display only has a single mode */ + SDL_AddDisplayMode(display, &display->current_mode); +} + +static int N3DS_GetDisplayBounds(_THIS, SDL_VideoDisplay *display, SDL_Rect *rect) +{ + DisplayDriverData *driver_data = (DisplayDriverData *)display->driverdata; + if (!driver_data) { + return -1; + } + rect->x = 0; + rect->y = (driver_data->screen == GFX_TOP) ? 0 : GSP_SCREEN_WIDTH; + rect->w = display->current_mode.w; + rect->h = display->current_mode.h; + + return 0; +} + +static int N3DS_CreateWindow(_THIS, SDL_Window *window) +{ + DisplayDriverData *display_data; + SDL_WindowData *window_data = (SDL_WindowData *)SDL_calloc(1, sizeof(SDL_WindowData)); + if (!window_data) { + return SDL_OutOfMemory(); + } + display_data = (DisplayDriverData *)SDL_GetDisplayDriverData(window->display_index); + window_data->screen = display_data->screen; + window->driverdata = window_data; + SDL_SetKeyboardFocus(window); + return 0; +} + +static void N3DS_DestroyWindow(_THIS, SDL_Window *window) +{ + if (!window) { + return; + } + SDL_free(window->driverdata); +} + +#endif /* SDL_VIDEO_DRIVER_N3DS */ + +/* vi: set sts=4 ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/n3ds/SDL_n3dsvideo.h b/SDL2-2.30.5/src/video/n3ds/SDL_n3dsvideo.h new file mode 100644 index 0000000..455eaf4 --- /dev/null +++ b/SDL2-2.30.5/src/video/n3ds/SDL_n3dsvideo.h @@ -0,0 +1,38 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifndef SDL_n3dsvideo_h_ +#define SDL_n3dsvideo_h_ + +#include <3ds.h> + +#include "../SDL_sysvideo.h" +typedef struct SDL_WindowData +{ + gfxScreen_t screen; /**< Keeps track of which N3DS screen is targetted */ +} SDL_WindowData; + +#define FRAMEBUFFER_FORMAT SDL_PIXELFORMAT_RGBA8888 + +#endif /* SDL_n3dsvideo_h_ */ + +/* vi: set sts=4 ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/nacl/SDL_naclevents.c b/SDL2-2.30.5/src/video/nacl/SDL_naclevents.c similarity index 99% rename from SDL2-2.0.12/src/video/nacl/SDL_naclevents.c rename to SDL2-2.30.5/src/video/nacl/SDL_naclevents.c index 44f47ec..6e7226e 100644 --- a/SDL2-2.0.12/src/video/nacl/SDL_naclevents.c +++ b/SDL2-2.30.5/src/video/nacl/SDL_naclevents.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,11 +20,11 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_NACL +#ifdef SDL_VIDEO_DRIVER_NACL #include "SDL.h" -#include "../../events/SDL_sysevents.h" #include "../../events/SDL_events_c.h" +#include "../SDL_sysvideo.h" #include "SDL_naclevents_c.h" #include "SDL_naclvideo.h" #include "ppapi_simple/ps_event.h" @@ -305,17 +305,18 @@ static Uint8 SDL_NACL_translate_mouse_button(int32_t button) { } } -static SDL_Scancode -SDL_NACL_translate_keycode(int keycode) +static SDL_Scancode SDL_NACL_translate_keycode(int keycode) { SDL_Scancode scancode = SDL_SCANCODE_UNKNOWN; if (keycode < SDL_arraysize(NACL_Keycodes)) { scancode = NACL_Keycodes[keycode]; } +#ifdef DEBUG_SCANCODES if (scancode == SDL_SCANCODE_UNKNOWN) { SDL_Log("The key you just pressed is not recognized by SDL. To help get this fixed, please report this to the SDL forums/mailing list NACL KeyCode %d", keycode); } +#endif return scancode; } diff --git a/SDL2-2.0.12/src/video/nacl/SDL_naclevents_c.h b/SDL2-2.30.5/src/video/nacl/SDL_naclevents_c.h similarity index 94% rename from SDL2-2.0.12/src/video/nacl/SDL_naclevents_c.h rename to SDL2-2.30.5/src/video/nacl/SDL_naclevents_c.h index 555f6a4..4bf777a 100644 --- a/SDL2-2.0.12/src/video/nacl/SDL_naclevents_c.h +++ b/SDL2-2.30.5/src/video/nacl/SDL_naclevents_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/video/nacl/SDL_naclglue.c b/SDL2-2.30.5/src/video/nacl/SDL_naclglue.c similarity index 91% rename from SDL2-2.0.12/src/video/nacl/SDL_naclglue.c rename to SDL2-2.30.5/src/video/nacl/SDL_naclglue.c index 1361847..04b0823 100644 --- a/SDL2-2.0.12/src/video/nacl/SDL_naclglue.c +++ b/SDL2-2.30.5/src/video/nacl/SDL_naclglue.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,5 +20,5 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_NACL +#ifdef SDL_VIDEO_DRIVER_NACL #endif /* SDL_VIDEO_DRIVER_NACL */ diff --git a/SDL2-2.0.12/src/video/nacl/SDL_naclopengles.c b/SDL2-2.30.5/src/video/nacl/SDL_naclopengles.c similarity index 86% rename from SDL2-2.0.12/src/video/nacl/SDL_naclopengles.c rename to SDL2-2.30.5/src/video/nacl/SDL_naclopengles.c index 0bd9b13..fd121b7 100644 --- a/SDL2-2.0.12/src/video/nacl/SDL_naclopengles.c +++ b/SDL2-2.30.5/src/video/nacl/SDL_naclopengles.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,14 +20,14 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_NACL +#ifdef SDL_VIDEO_DRIVER_NACL /* NaCl SDL video GLES 2 driver implementation */ #include "SDL_video.h" #include "SDL_naclvideo.h" -#if SDL_LOADSO_DLOPEN +#ifdef HAVE_DLOPEN #include "dlfcn.h" #endif @@ -35,32 +35,28 @@ #include "ppapi_simple/ps.h" /* GL functions */ -int -NACL_GLES_LoadLibrary(_THIS, const char *path) +int NACL_GLES_LoadLibrary(_THIS, const char *path) { /* FIXME: Support dynamic linking when PNACL supports it */ return glInitializePPAPI(PSGetInterface) == 0; } -void * -NACL_GLES_GetProcAddress(_THIS, const char *proc) +void *NACL_GLES_GetProcAddress(_THIS, const char *proc) { -#if SDL_LOADSO_DLOPEN +#ifdef HAVE_DLOPEN return dlsym( 0 /* RTLD_DEFAULT */, proc); #else return NULL; #endif } -void -NACL_GLES_UnloadLibrary(_THIS) +void NACL_GLES_UnloadLibrary(_THIS) { /* FIXME: Support dynamic linking when PNACL supports it */ glTerminatePPAPI(); } -int -NACL_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext sdl_context) +int NACL_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext sdl_context) { SDL_VideoData *driverdata = (SDL_VideoData *) _this->driverdata; /* FIXME: Check threading issues...otherwise use a hardcoded _this->context across all threads */ @@ -69,21 +65,20 @@ NACL_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext sdl_context) return 0; } -SDL_GLContext -NACL_GLES_CreateContext(_THIS, SDL_Window * window) +SDL_GLContext NACL_GLES_CreateContext(_THIS, SDL_Window * window) { SDL_VideoData *driverdata = (SDL_VideoData *) _this->driverdata; PP_Resource context, share_context = 0; /* 64 seems nice. */ Sint32 attribs[64]; int i = 0; - + if (_this->gl_config.share_with_current_context) { share_context = (PP_Resource) SDL_GL_GetCurrentContext(); } /* FIXME: Some ATTRIBS from PP_Graphics3DAttrib are not set here */ - + attribs[i++] = PP_GRAPHICS3DATTRIB_WIDTH; attribs[i++] = window->w; attribs[i++] = PP_GRAPHICS3DATTRIB_HEIGHT; @@ -94,65 +89,62 @@ NACL_GLES_CreateContext(_THIS, SDL_Window * window) attribs[i++] = _this->gl_config.green_size; attribs[i++] = PP_GRAPHICS3DATTRIB_BLUE_SIZE; attribs[i++] = _this->gl_config.blue_size; - + if (_this->gl_config.alpha_size) { attribs[i++] = PP_GRAPHICS3DATTRIB_ALPHA_SIZE; attribs[i++] = _this->gl_config.alpha_size; } - + /*if (_this->gl_config.buffer_size) { attribs[i++] = EGL_BUFFER_SIZE; attribs[i++] = _this->gl_config.buffer_size; }*/ - + attribs[i++] = PP_GRAPHICS3DATTRIB_DEPTH_SIZE; attribs[i++] = _this->gl_config.depth_size; - + if (_this->gl_config.stencil_size) { attribs[i++] = PP_GRAPHICS3DATTRIB_STENCIL_SIZE; attribs[i++] = _this->gl_config.stencil_size; } - + if (_this->gl_config.multisamplebuffers) { attribs[i++] = PP_GRAPHICS3DATTRIB_SAMPLE_BUFFERS; attribs[i++] = _this->gl_config.multisamplebuffers; } - + if (_this->gl_config.multisamplesamples) { attribs[i++] = PP_GRAPHICS3DATTRIB_SAMPLES; attribs[i++] = _this->gl_config.multisamplesamples; } - + attribs[i++] = PP_GRAPHICS3DATTRIB_NONE; - + context = driverdata->ppb_graphics->Create(driverdata->instance, share_context, attribs); if (context) { /* We need to make the context current, otherwise nothing works */ SDL_GL_MakeCurrent(window, (SDL_GLContext) context); } - + return (SDL_GLContext) context; } -int -NACL_GLES_SetSwapInterval(_THIS, int interval) +int NACL_GLES_SetSwapInterval(_THIS, int interval) { /* STUB */ return SDL_Unsupported(); } -int -NACL_GLES_GetSwapInterval(_THIS) +int NACL_GLES_GetSwapInterval(_THIS) { /* STUB */ return 0; } -int -NACL_GLES_SwapWindow(_THIS, SDL_Window * window) +int NACL_GLES_SwapWindow(_THIS, SDL_Window * window) { SDL_VideoData *driverdata = (SDL_VideoData *) _this->driverdata; struct PP_CompletionCallback callback = { NULL, 0, PP_COMPLETIONCALLBACK_FLAG_NONE }; @@ -162,8 +154,7 @@ NACL_GLES_SwapWindow(_THIS, SDL_Window * window) return 0; } -void -NACL_GLES_DeleteContext(_THIS, SDL_GLContext context) +void NACL_GLES_DeleteContext(_THIS, SDL_GLContext context) { SDL_VideoData *driverdata = (SDL_VideoData *) _this->driverdata; driverdata->ppb_core->ReleaseResource((PP_Resource) context); diff --git a/SDL2-2.0.12/src/video/nacl/SDL_naclopengles.h b/SDL2-2.30.5/src/video/nacl/SDL_naclopengles.h similarity index 96% rename from SDL2-2.0.12/src/video/nacl/SDL_naclopengles.h rename to SDL2-2.30.5/src/video/nacl/SDL_naclopengles.h index b785101..5ae3946 100644 --- a/SDL2-2.0.12/src/video/nacl/SDL_naclopengles.h +++ b/SDL2-2.30.5/src/video/nacl/SDL_naclopengles.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/video/nacl/SDL_naclvideo.c b/SDL2-2.30.5/src/video/nacl/SDL_naclvideo.c similarity index 90% rename from SDL2-2.0.12/src/video/nacl/SDL_naclvideo.c rename to SDL2-2.30.5/src/video/nacl/SDL_naclvideo.c index 2d3f566..53fc679 100644 --- a/SDL2-2.0.12/src/video/nacl/SDL_naclvideo.c +++ b/SDL2-2.30.5/src/video/nacl/SDL_naclvideo.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_NACL +#ifdef SDL_VIDEO_DRIVER_NACL #include "ppapi/c/pp_errors.h" #include "ppapi/c/pp_instance.h" @@ -32,34 +32,33 @@ #include "SDL_naclvideo.h" #include "SDL_naclwindow.h" #include "SDL_naclevents_c.h" -#include "SDL_naclopengles.h" +#include "SDL_naclopengles.h" #include "SDL_video.h" #include "../SDL_sysvideo.h" #include "../../events/SDL_events_c.h" #define NACLVID_DRIVER_NAME "nacl" -/* Static init required because NACL_SetScreenResolution +/* Static init required because NACL_SetScreenResolution * may appear even before SDL starts and we want to remember * the window width and height */ static SDL_VideoData nacl = {0}; -void -NACL_SetScreenResolution(int width, int height, Uint32 format) +void NACL_SetScreenResolution(int width, int height, Uint32 format) { PP_Resource context; - + nacl.w = width; - nacl.h = height; + nacl.h = height; nacl.format = format; - + if (nacl.window) { nacl.window->w = width; nacl.window->h = height; SDL_SendWindowEvent(nacl.window, SDL_WINDOWEVENT_RESIZED, width, height); } - + /* FIXME: Check threading issues...otherwise use a hardcoded _this->context across all threads */ context = (PP_Resource) SDL_GL_GetCurrentContext(); if (context) { @@ -85,15 +84,18 @@ static void NACL_DeleteDevice(SDL_VideoDevice *device) { SDL_free(device); } -static int -NACL_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) +static int NACL_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) { return 0; } -static SDL_VideoDevice *NACL_CreateDevice(int devindex) { +static SDL_VideoDevice *NACL_CreateDevice(void) { SDL_VideoDevice *device; - + + if (!NACL_Available()) { + return NULL; + } + /* Initialize all variables that we clean on shutdown */ device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice)); if (!device) { @@ -101,20 +103,20 @@ static SDL_VideoDevice *NACL_CreateDevice(int devindex) { return NULL; } device->driverdata = &nacl; - + /* Set the function pointers */ device->VideoInit = NACL_VideoInit; device->VideoQuit = NACL_VideoQuit; device->PumpEvents = NACL_PumpEvents; - + device->CreateSDLWindow = NACL_CreateWindow; device->SetWindowTitle = NACL_SetWindowTitle; device->DestroyWindow = NACL_DestroyWindow; - + device->SetDisplayMode = NACL_SetDisplayMode; - + device->free = NACL_DeleteDevice; - + /* GL pointers */ device->GL_LoadLibrary = NACL_GLES_LoadLibrary; device->GL_GetProcAddress = NACL_GLES_GetProcAddress; @@ -125,14 +127,15 @@ static SDL_VideoDevice *NACL_CreateDevice(int devindex) { device->GL_GetSwapInterval = NACL_GLES_GetSwapInterval; device->GL_SwapWindow = NACL_GLES_SwapWindow; device->GL_DeleteContext = NACL_GLES_DeleteContext; - - + + return device; } VideoBootStrap NACL_bootstrap = { NACLVID_DRIVER_NAME, "SDL Native Client Video Driver", - NACL_Available, NACL_CreateDevice + NACL_CreateDevice, + NULL /* no ShowMessageBox implementation */ }; int NACL_VideoInit(_THIS) { @@ -150,7 +153,7 @@ int NACL_VideoInit(_THIS) { } SDL_AddDisplayMode(&_this->displays[0], &mode); - + PSInterfaceInit(); driverdata->instance = PSGetInstanceId(); driverdata->ppb_graphics = PSInterfaceGraphics3D(); @@ -166,12 +169,12 @@ int NACL_VideoInit(_THIS) { driverdata->ppb_mouse_input_event = (PPB_MouseInputEvent*) PSGetInterface(PPB_MOUSE_INPUT_EVENT_INTERFACE); driverdata->ppb_wheel_input_event = (PPB_WheelInputEvent*) PSGetInterface(PPB_WHEEL_INPUT_EVENT_INTERFACE); driverdata->ppb_touch_input_event = (PPB_TouchInputEvent*) PSGetInterface(PPB_TOUCH_INPUT_EVENT_INTERFACE); - - + + driverdata->message_loop = driverdata->ppb_message_loop->Create(driverdata->instance); - + PSEventSetFilter(PSE_ALL); - + /* We're done! */ return 0; } diff --git a/SDL2-2.0.12/src/video/nacl/SDL_naclvideo.h b/SDL2-2.30.5/src/video/nacl/SDL_naclvideo.h similarity index 97% rename from SDL2-2.0.12/src/video/nacl/SDL_naclvideo.h rename to SDL2-2.30.5/src/video/nacl/SDL_naclvideo.h index 613dd61..504f4d6 100644 --- a/SDL2-2.0.12/src/video/nacl/SDL_naclvideo.h +++ b/SDL2-2.30.5/src/video/nacl/SDL_naclvideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/video/nacl/SDL_naclwindow.c b/SDL2-2.30.5/src/video/nacl/SDL_naclwindow.c similarity index 85% rename from SDL2-2.0.12/src/video/nacl/SDL_naclwindow.c rename to SDL2-2.30.5/src/video/nacl/SDL_naclwindow.c index 979abcd..200b345 100644 --- a/SDL2-2.0.12/src/video/nacl/SDL_naclwindow.c +++ b/SDL2-2.30.5/src/video/nacl/SDL_naclwindow.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_NACL +#ifdef SDL_VIDEO_DRIVER_NACL #include "../SDL_sysvideo.h" @@ -29,14 +29,12 @@ #include "SDL_naclvideo.h" #include "SDL_naclwindow.h" -int -NACL_CreateWindow(_THIS, SDL_Window * window) +int NACL_CreateWindow(_THIS, SDL_Window * window) { SDL_VideoData *driverdata = (SDL_VideoData *) _this->driverdata; - + if (driverdata->window) { - SDL_SetError("NaCl only supports one window"); - return -1; + return SDL_SetError("NaCl only supports one window"); } driverdata->window = window; @@ -50,23 +48,21 @@ NACL_CreateWindow(_THIS, SDL_Window * window) window->flags |= SDL_WINDOW_FULLSCREEN; /* window is always fullscreen */ window->flags &= ~SDL_WINDOW_HIDDEN; window->flags |= SDL_WINDOW_SHOWN; /* only one window on NaCl */ - window->flags |= SDL_WINDOW_INPUT_FOCUS; /* always has input focus */ + window->flags |= SDL_WINDOW_INPUT_FOCUS; /* always has input focus */ window->flags |= SDL_WINDOW_OPENGL; - + SDL_SetMouseFocus(window); SDL_SetKeyboardFocus(window); - + return 0; } -void -NACL_SetWindowTitle(_THIS, SDL_Window * window) +void NACL_SetWindowTitle(_THIS, SDL_Window * window) { /* TODO */ } -void -NACL_DestroyWindow(_THIS, SDL_Window * window) +void NACL_DestroyWindow(_THIS, SDL_Window * window) { SDL_VideoData *driverdata = (SDL_VideoData *) _this->driverdata; if (window == driverdata->window) { diff --git a/SDL2-2.0.12/src/video/nacl/SDL_naclwindow.h b/SDL2-2.30.5/src/video/nacl/SDL_naclwindow.h similarity index 95% rename from SDL2-2.0.12/src/video/nacl/SDL_naclwindow.h rename to SDL2-2.30.5/src/video/nacl/SDL_naclwindow.h index 5726fca..9ac941c 100644 --- a/SDL2-2.0.12/src/video/nacl/SDL_naclwindow.h +++ b/SDL2-2.30.5/src/video/nacl/SDL_naclwindow.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.30.5/src/video/ngage/SDL_ngageevents.cpp b/SDL2-2.30.5/src/video/ngage/SDL_ngageevents.cpp new file mode 100644 index 0000000..3ecf164 --- /dev/null +++ b/SDL2-2.30.5/src/video/ngage/SDL_ngageevents.cpp @@ -0,0 +1,196 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_NGAGE + +/* Being a ngage driver, there's no event stream. We just define stubs for + most of the API. */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "../../events/SDL_events_c.h" +#include "../../events/SDL_keyboard_c.h" + +#ifdef __cplusplus +} +#endif + +#include "SDL_ngagevideo.h" +#include "SDL_ngageevents_c.h" + +int HandleWsEvent(_THIS, const TWsEvent &aWsEvent); + +void NGAGE_PumpEvents(_THIS) +{ + SDL_VideoData *phdata = (SDL_VideoData *)_this->driverdata; + + while (phdata->NGAGE_WsEventStatus != KRequestPending) { + phdata->NGAGE_WsSession.GetEvent(phdata->NGAGE_WsEvent); + + HandleWsEvent(_this, phdata->NGAGE_WsEvent); + + phdata->NGAGE_WsEventStatus = KRequestPending; + phdata->NGAGE_WsSession.EventReady(&phdata->NGAGE_WsEventStatus); + } +} + +/*****************************************************************************/ +/* Internal */ +/*****************************************************************************/ + +#include +#include + +extern void DisableKeyBlocking(_THIS); +extern void RedrawWindowL(_THIS); + +TBool isCursorVisible = EFalse; + +static SDL_Scancode ConvertScancode(_THIS, int key) +{ + SDL_Keycode keycode; + + switch (key) { + case EStdKeyBackspace: // Clear key + keycode = SDLK_BACKSPACE; + break; + case 0x31: // 1 + keycode = SDLK_1; + break; + case 0x32: // 2 + keycode = SDLK_2; + break; + case 0x33: // 3 + keycode = SDLK_3; + break; + case 0x34: // 4 + keycode = SDLK_4; + break; + case 0x35: // 5 + keycode = SDLK_5; + break; + case 0x36: // 6 + keycode = SDLK_6; + break; + case 0x37: // 7 + keycode = SDLK_7; + break; + case 0x38: // 8 + keycode = SDLK_8; + break; + case 0x39: // 9 + keycode = SDLK_9; + break; + case 0x30: // 0 + keycode = SDLK_0; + break; + case 0x2a: // Asterisk + keycode = SDLK_ASTERISK; + break; + case EStdKeyHash: // Hash + keycode = SDLK_HASH; + break; + case EStdKeyDevice0: // Left softkey + keycode = SDLK_SOFTLEFT; + break; + case EStdKeyDevice1: // Right softkey + keycode = SDLK_SOFTRIGHT; + break; + case EStdKeyApplication0: // Call softkey + keycode = SDLK_CALL; + break; + case EStdKeyApplication1: // End call softkey + keycode = SDLK_ENDCALL; + break; + case EStdKeyDevice3: // Middle softkey + keycode = SDLK_SELECT; + break; + case EStdKeyUpArrow: // Up arrow + keycode = SDLK_UP; + break; + case EStdKeyDownArrow: // Down arrow + keycode = SDLK_DOWN; + break; + case EStdKeyLeftArrow: // Left arrow + keycode = SDLK_LEFT; + break; + case EStdKeyRightArrow: // Right arrow + keycode = SDLK_RIGHT; + break; + default: + keycode = SDLK_UNKNOWN; + break; + } + + return SDL_GetScancodeFromKey(keycode); +} + +int HandleWsEvent(_THIS, const TWsEvent &aWsEvent) +{ + SDL_VideoData *phdata = (SDL_VideoData *)_this->driverdata; + int posted = 0; + + switch (aWsEvent.Type()) { + case EEventKeyDown: /* Key events */ + SDL_SendKeyboardKey(SDL_PRESSED, ConvertScancode(_this, aWsEvent.Key()->iScanCode)); + break; + case EEventKeyUp: /* Key events */ + SDL_SendKeyboardKey(SDL_RELEASED, ConvertScancode(_this, aWsEvent.Key()->iScanCode)); + break; + case EEventFocusGained: /* SDL window got focus */ + phdata->NGAGE_IsWindowFocused = ETrue; + /* Draw window background and screen buffer */ + DisableKeyBlocking(_this); + RedrawWindowL(_this); + break; + case EEventFocusLost: /* SDL window lost focus */ + { + phdata->NGAGE_IsWindowFocused = EFalse; + RWsSession s; + s.Connect(); + RWindowGroup g(s); + g.Construct(TUint32(&g), EFalse); + g.EnableReceiptOfFocus(EFalse); + RWindow w(s); + w.Construct(g, TUint32(&w)); + w.SetExtent(TPoint(0, 0), phdata->NGAGE_WsWindow.Size()); + w.SetOrdinalPosition(0); + w.Activate(); + w.Close(); + g.Close(); + s.Close(); + break; + } + case EEventModifiersChanged: + break; + default: + break; + } + return posted; +} + +#endif /* SDL_VIDEO_DRIVER_NGAGE */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/ngage/SDL_ngageevents_c.h b/SDL2-2.30.5/src/video/ngage/SDL_ngageevents_c.h new file mode 100644 index 0000000..e0ef5a0 --- /dev/null +++ b/SDL2-2.30.5/src/video/ngage/SDL_ngageevents_c.h @@ -0,0 +1,28 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_ngagevideo.h" + +extern void NGAGE_PumpEvents(_THIS); + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/ngage/SDL_ngageframebuffer.cpp b/SDL2-2.30.5/src/video/ngage/SDL_ngageframebuffer.cpp new file mode 100644 index 0000000..98fb495 --- /dev/null +++ b/SDL2-2.30.5/src/video/ngage/SDL_ngageframebuffer.cpp @@ -0,0 +1,399 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_NGAGE + +#include + +#include "../SDL_sysvideo.h" +#include "SDL_ngagevideo.h" +#include "SDL_ngageframebuffer_c.h" + +#define NGAGE_SURFACE "NGAGE_FrameBuffer" + +/* For 12 bit screen HW. Table for fast conversion from 8 bit to 12 bit + * + * TUint16 is enough, but using TUint32 so we can use better instruction + * selection on ARMI. + */ +static TUint32 NGAGE_HWPalette_256_to_Screen[256]; + +int GetBpp(TDisplayMode displaymode); +void DirectUpdate(_THIS, int numrects, SDL_Rect *rects); +void DrawBackground(_THIS); +void DirectDraw(_THIS, int numrects, SDL_Rect *rects, TUint16 *screenBuffer); +void RedrawWindowL(_THIS); + +int SDL_NGAGE_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format, void **pixels, int *pitch) +{ + SDL_VideoData *phdata = (SDL_VideoData *)_this->driverdata; + SDL_Surface *surface; + const Uint32 surface_format = SDL_PIXELFORMAT_RGB444; + int w, h; + + /* Free the old framebuffer surface */ + SDL_NGAGE_DestroyWindowFramebuffer(_this, window); + + /* Create a new one */ + SDL_GetWindowSizeInPixels(window, &w, &h); + surface = SDL_CreateRGBSurfaceWithFormat(0, w, h, 0, surface_format); + if (!surface) { + return -1; + } + + /* Save the info and return! */ + SDL_SetWindowData(window, NGAGE_SURFACE, surface); + *format = surface_format; + *pixels = surface->pixels; + *pitch = surface->pitch; + + /* Initialise Epoc frame buffer */ + + TDisplayMode displayMode = phdata->NGAGE_WsScreen->DisplayMode(); + + TScreenInfoV01 screenInfo; + TPckg sInfo(screenInfo); + UserSvr::ScreenInfo(sInfo); + + phdata->NGAGE_ScreenSize = screenInfo.iScreenSize; + phdata->NGAGE_DisplayMode = displayMode; + phdata->NGAGE_HasFrameBuffer = screenInfo.iScreenAddressValid; + phdata->NGAGE_FrameBuffer = phdata->NGAGE_HasFrameBuffer ? (TUint8 *)screenInfo.iScreenAddress : NULL; + phdata->NGAGE_BytesPerPixel = ((GetBpp(displayMode) - 1) / 8) + 1; + + phdata->NGAGE_BytesPerScanLine = screenInfo.iScreenSize.iWidth * phdata->NGAGE_BytesPerPixel; + phdata->NGAGE_BytesPerScreen = phdata->NGAGE_BytesPerScanLine * phdata->NGAGE_ScreenSize.iHeight; + + SDL_Log("Screen width %d", screenInfo.iScreenSize.iWidth); + SDL_Log("Screen height %d", screenInfo.iScreenSize.iHeight); + SDL_Log("Screen dmode %d", displayMode); + SDL_Log("Screen valid %d", screenInfo.iScreenAddressValid); + + SDL_Log("Bytes per pixel %d", phdata->NGAGE_BytesPerPixel); + SDL_Log("Bytes per scan line %d", phdata->NGAGE_BytesPerScanLine); + SDL_Log("Bytes per screen %d", phdata->NGAGE_BytesPerScreen); + + /* It seems that in SA1100 machines for 8bpp displays there is a 512 + * palette table at the beginning of the frame buffer. + * + * In 12 bpp machines the table has 16 entries. + */ + if (phdata->NGAGE_HasFrameBuffer && GetBpp(displayMode) == 8) { + phdata->NGAGE_FrameBuffer += 512; + } else { + phdata->NGAGE_FrameBuffer += 32; + } +#if 0 + if (phdata->NGAGE_HasFrameBuffer && GetBpp(displayMode) == 12) { + phdata->NGAGE_FrameBuffer += 16 * 2; + } + if (phdata->NGAGE_HasFrameBuffer && GetBpp(displayMode) == 16) { + phdata->NGAGE_FrameBuffer += 16 * 2; + } +#endif + + // Get draw device for updating the screen + TScreenInfoV01 screenInfo2; + + NGAGE_Runtime::GetScreenInfo(screenInfo2); + + TRAPD(status, phdata->NGAGE_DrawDevice = CFbsDrawDevice::NewScreenDeviceL(screenInfo2, displayMode)); + User::LeaveIfError(status); + + /* Activate events for me */ + phdata->NGAGE_WsEventStatus = KRequestPending; + phdata->NGAGE_WsSession.EventReady(&phdata->NGAGE_WsEventStatus); + + SDL_Log("SDL:WsEventStatus"); + User::WaitForRequest(phdata->NGAGE_WsEventStatus); + + phdata->NGAGE_RedrawEventStatus = KRequestPending; + phdata->NGAGE_WsSession.RedrawReady(&phdata->NGAGE_RedrawEventStatus); + + SDL_Log("SDL:RedrawEventStatus"); + User::WaitForRequest(phdata->NGAGE_RedrawEventStatus); + + phdata->NGAGE_WsWindow.PointerFilter(EPointerFilterDrag, 0); + + phdata->NGAGE_ScreenOffset = TPoint(0, 0); + + SDL_Log("SDL:DrawBackground"); + DrawBackground(_this); // Clear screen + + return 0; +} + +int SDL_NGAGE_UpdateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_Rect *rects, int numrects) +{ + static int frame_number; + SDL_Surface *surface; + + surface = (SDL_Surface *)SDL_GetWindowData(window, NGAGE_SURFACE); + if (!surface) { + return SDL_SetError("Couldn't find ngage surface for window"); + } + + /* Send the data to the display */ + if (SDL_getenv("SDL_VIDEO_NGAGE_SAVE_FRAMES")) { + char file[128]; + SDL_snprintf(file, sizeof(file), "SDL_window%d-%8.8d.bmp", + (int)SDL_GetWindowID(window), ++frame_number); + SDL_SaveBMP(surface, file); + } + + DirectUpdate(_this, numrects, (SDL_Rect *)rects); + + return 0; +} + +void SDL_NGAGE_DestroyWindowFramebuffer(_THIS, SDL_Window *window) +{ + SDL_Surface *surface; + + surface = (SDL_Surface *)SDL_SetWindowData(window, NGAGE_SURFACE, NULL); + SDL_FreeSurface(surface); +} + +/*****************************************************************************/ +/* Runtime */ +/*****************************************************************************/ + +#include +#include +#include + +EXPORT_C void NGAGE_Runtime::GetScreenInfo(TScreenInfoV01 &screenInfo2) +{ + TPckg sInfo2(screenInfo2); + UserSvr::ScreenInfo(sInfo2); +} + +/*****************************************************************************/ +/* Internal */ +/*****************************************************************************/ + +int GetBpp(TDisplayMode displaymode) +{ + return TDisplayModeUtils::NumDisplayModeBitsPerPixel(displaymode); +} + +void DrawBackground(_THIS) +{ + SDL_VideoData *phdata = (SDL_VideoData *)_this->driverdata; + /* Draw background */ + TUint16 *screenBuffer = (TUint16 *)phdata->NGAGE_FrameBuffer; + /* Draw black background */ + Mem::FillZ(screenBuffer, phdata->NGAGE_BytesPerScreen); +} + +void DirectDraw(_THIS, int numrects, SDL_Rect *rects, TUint16 *screenBuffer) +{ + SDL_VideoData *phdata = (SDL_VideoData *)_this->driverdata; + SDL_Surface *screen = (SDL_Surface *)SDL_GetWindowData(_this->windows, NGAGE_SURFACE); + + TInt i; + + TDisplayMode displayMode = phdata->NGAGE_DisplayMode; + const TInt sourceNumBytesPerPixel = ((GetBpp(displayMode) - 1) / 8) + 1; + + const TPoint fixedOffset = phdata->NGAGE_ScreenOffset; + const TInt screenW = screen->w; + const TInt screenH = screen->h; + const TInt sourceScanlineLength = screenW; + const TInt targetScanlineLength = phdata->NGAGE_ScreenSize.iWidth; + + /* Render the rectangles in the list */ + + for (i = 0; i < numrects; ++i) { + const SDL_Rect ¤tRect = rects[i]; + SDL_Rect rect2; + rect2.x = currentRect.x; + rect2.y = currentRect.y; + rect2.w = currentRect.w; + rect2.h = currentRect.h; + + if (rect2.w <= 0 || rect2.h <= 0) /* Sanity check */ { + continue; + } + + /* All variables are measured in pixels */ + + /* Check rects validity, i.e. upper and lower bounds */ + TInt maxX = Min(screenW - 1, rect2.x + rect2.w - 1); + TInt maxY = Min(screenH - 1, rect2.y + rect2.h - 1); + if (maxX < 0 || maxY < 0) /* sanity check */ { + continue; + } + /* Clip from bottom */ + + maxY = Min(maxY, phdata->NGAGE_ScreenSize.iHeight - 1); + /* TODO: Clip from the right side */ + + const TInt sourceRectWidth = maxX - rect2.x + 1; + const TInt sourceRectWidthInBytes = sourceRectWidth * sourceNumBytesPerPixel; + const TInt sourceRectHeight = maxY - rect2.y + 1; + const TInt sourceStartOffset = rect2.x + rect2.y * sourceScanlineLength; + const TUint skipValue = 1; /* 1 = No skip */ + + TInt targetStartOffset = fixedOffset.iX + rect2.x + (fixedOffset.iY + rect2.y) * targetScanlineLength; + + switch (screen->format->BitsPerPixel) { + case 12: + { + TUint16 *bitmapLine = (TUint16 *)screen->pixels + sourceStartOffset; + TUint16 *screenMemory = screenBuffer + targetStartOffset; + + if (skipValue == 1) { + for (TInt y = 0; y < sourceRectHeight; y++) { + Mem::Copy(screenMemory, bitmapLine, sourceRectWidthInBytes); + bitmapLine += sourceScanlineLength; + screenMemory += targetScanlineLength; + } + } else { + for (TInt y = 0; y < sourceRectHeight; y++) { + TUint16 *bitmapPos = bitmapLine; /* 2 bytes per pixel */ + TUint16 *screenMemoryLinePos = screenMemory; /* 2 bytes per pixel */ + for (TInt x = 0; x < sourceRectWidth; x++) { + __ASSERT_DEBUG(screenMemory < (screenBuffer + phdata->NGAGE_ScreenSize.iWidth * phdata->NGAGE_ScreenSize.iHeight), User::Panic(_L("SDL"), KErrCorrupt)); + __ASSERT_DEBUG(screenMemory >= screenBuffer, User::Panic(_L("SDL"), KErrCorrupt)); + __ASSERT_DEBUG(bitmapLine < ((TUint16 *)screen->pixels + (screen->w * screen->h)), User::Panic(_L("SDL"), KErrCorrupt)); + __ASSERT_DEBUG(bitmapLine >= (TUint16 *)screen->pixels, User::Panic(_L("SDL"), KErrCorrupt)); + + *screenMemoryLinePos++ = *bitmapPos; + bitmapPos += skipValue; + } + bitmapLine += sourceScanlineLength; + screenMemory += targetScanlineLength; + } + } + } break; + // 256 color paletted mode: 8 bpp --> 12 bpp + default: + { + if (phdata->NGAGE_BytesPerPixel <= 2) { + TUint8 *bitmapLine = (TUint8 *)screen->pixels + sourceStartOffset; + TUint16 *screenMemory = screenBuffer + targetStartOffset; + + for (TInt y = 0; y < sourceRectHeight; y++) { + TUint8 *bitmapPos = bitmapLine; /* 1 byte per pixel */ + TUint16 *screenMemoryLinePos = screenMemory; /* 2 bytes per pixel */ + /* Convert each pixel from 256 palette to 4k color values */ + for (TInt x = 0; x < sourceRectWidth; x++) { + __ASSERT_DEBUG(screenMemoryLinePos < (screenBuffer + (phdata->NGAGE_ScreenSize.iWidth * phdata->NGAGE_ScreenSize.iHeight)), User::Panic(_L("SDL"), KErrCorrupt)); + __ASSERT_DEBUG(screenMemoryLinePos >= screenBuffer, User::Panic(_L("SDL"), KErrCorrupt)); + __ASSERT_DEBUG(bitmapPos < ((TUint8 *)screen->pixels + (screen->w * screen->h)), User::Panic(_L("SDL"), KErrCorrupt)); + __ASSERT_DEBUG(bitmapPos >= (TUint8 *)screen->pixels, User::Panic(_L("SDL"), KErrCorrupt)); + *screenMemoryLinePos++ = NGAGE_HWPalette_256_to_Screen[*bitmapPos++]; + } + bitmapLine += sourceScanlineLength; + screenMemory += targetScanlineLength; + } + } else { + TUint8 *bitmapLine = (TUint8 *)screen->pixels + sourceStartOffset; + TUint32 *screenMemory = reinterpret_cast(screenBuffer + targetStartOffset); + for (TInt y = 0; y < sourceRectHeight; y++) { + TUint8 *bitmapPos = bitmapLine; /* 1 byte per pixel */ + TUint32 *screenMemoryLinePos = screenMemory; /* 2 bytes per pixel */ + /* Convert each pixel from 256 palette to 4k color values */ + for (TInt x = 0; x < sourceRectWidth; x++) { + __ASSERT_DEBUG(screenMemoryLinePos < (reinterpret_cast(screenBuffer) + (phdata->NGAGE_ScreenSize.iWidth * phdata->NGAGE_ScreenSize.iHeight)), User::Panic(_L("SDL"), KErrCorrupt)); + __ASSERT_DEBUG(screenMemoryLinePos >= reinterpret_cast(screenBuffer), User::Panic(_L("SDL"), KErrCorrupt)); + __ASSERT_DEBUG(bitmapPos < ((TUint8 *)screen->pixels + (screen->w * screen->h)), User::Panic(_L("SDL"), KErrCorrupt)); + __ASSERT_DEBUG(bitmapPos >= (TUint8 *)screen->pixels, User::Panic(_L("SDL"), KErrCorrupt)); + *screenMemoryLinePos++ = NGAGE_HWPalette_256_to_Screen[*bitmapPos++]; + } + bitmapLine += sourceScanlineLength; + screenMemory += targetScanlineLength; + } + } + } + } + } +} + +void DirectUpdate(_THIS, int numrects, SDL_Rect *rects) +{ + SDL_VideoData *phdata = (SDL_VideoData *)_this->driverdata; + + if (!phdata->NGAGE_IsWindowFocused) { + SDL_PauseAudio(1); + SDL_Delay(1000); + return; + } + + SDL_PauseAudio(0); + + TUint16 *screenBuffer = (TUint16 *)phdata->NGAGE_FrameBuffer; + +#if 0 + if (phdata->NGAGE_ScreenOrientation == CFbsBitGc::EGraphicsOrientationRotated270) { + // ... + } else +#endif + { + DirectDraw(_this, numrects, rects, screenBuffer); + } + + for (int i = 0; i < numrects; ++i) { + TInt aAx = rects[i].x; + TInt aAy = rects[i].y; + TInt aBx = rects[i].w; + TInt aBy = rects[i].h; + TRect rect2 = TRect(aAx, aAy, aBx, aBy); + + phdata->NGAGE_DrawDevice->UpdateRegion(rect2); /* Should we update rects parameter area only? */ + phdata->NGAGE_DrawDevice->Update(); + } +} + +void RedrawWindowL(_THIS) +{ + SDL_VideoData *phdata = (SDL_VideoData *)_this->driverdata; + SDL_Surface *screen = (SDL_Surface *)SDL_GetWindowData(_this->windows, NGAGE_SURFACE); + + int w = screen->w; + int h = screen->h; + if (phdata->NGAGE_ScreenOrientation == CFbsBitGc::EGraphicsOrientationRotated270) { + w = screen->h; + h = screen->w; + } + if ((w < phdata->NGAGE_ScreenSize.iWidth) || (h < phdata->NGAGE_ScreenSize.iHeight)) { + DrawBackground(_this); + } + + /* Tell the system that something has been drawn */ + TRect rect = TRect(phdata->NGAGE_WsWindow.Size()); + phdata->NGAGE_WsWindow.Invalidate(rect); + + /* Draw current buffer */ + SDL_Rect fullScreen; + fullScreen.x = 0; + fullScreen.y = 0; + fullScreen.w = screen->w; + fullScreen.h = screen->h; + DirectUpdate(_this, 1, &fullScreen); +} + +#endif /* SDL_VIDEO_DRIVER_NGAGE */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/ngage/SDL_ngageframebuffer_c.h b/SDL2-2.30.5/src/video/ngage/SDL_ngageframebuffer_c.h new file mode 100644 index 0000000..02c50ef --- /dev/null +++ b/SDL2-2.30.5/src/video/ngage/SDL_ngageframebuffer_c.h @@ -0,0 +1,38 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +extern int SDL_NGAGE_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format, void **pixels, int *pitch); +extern int SDL_NGAGE_UpdateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_Rect *rects, int numrects); +extern void SDL_NGAGE_DestroyWindowFramebuffer(_THIS, SDL_Window *window); + +/****************************************************************************/ +/* Runtime */ +/****************************************************************************/ + +class NGAGE_Runtime +{ + public: + IMPORT_C static void GetScreenInfo(TScreenInfoV01 &screenInfo2); +}; + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/ngage/SDL_ngagevideo.cpp b/SDL2-2.30.5/src/video/ngage/SDL_ngagevideo.cpp new file mode 100644 index 0000000..d18abc8 --- /dev/null +++ b/SDL2-2.30.5/src/video/ngage/SDL_ngagevideo.cpp @@ -0,0 +1,180 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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 +#ifdef NULL +#undef NULL +#endif +#include "../../SDL_internal.h" + +#ifdef SDL_VIDEO_DRIVER_NGAGE + +#ifdef __cplusplus +extern "C" { +#endif + +#include "SDL_video.h" +#include "../SDL_sysvideo.h" +#include "../SDL_pixels_c.h" +#include "../../events/SDL_events_c.h" + +#ifdef __cplusplus +} +#endif + +#include "SDL_ngagevideo.h" +#include "SDL_ngagewindow.h" +#include "SDL_ngageevents_c.h" +#include "SDL_ngageframebuffer_c.h" + +#define NGAGEVID_DRIVER_NAME "ngage" + +/* Initialization/Query functions */ +static int NGAGE_VideoInit(_THIS); +static int NGAGE_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode); +static void NGAGE_VideoQuit(_THIS); + +/* NGAGE driver bootstrap functions */ + +static void NGAGE_DeleteDevice(SDL_VideoDevice *device) +{ + SDL_VideoData *phdata = (SDL_VideoData *)device->driverdata; + + if (phdata) { + /* Free Epoc resources */ + + /* Disable events for me */ + if (phdata->NGAGE_WsEventStatus != KRequestPending) { + phdata->NGAGE_WsSession.EventReadyCancel(); + } + if (phdata->NGAGE_RedrawEventStatus != KRequestPending) { + phdata->NGAGE_WsSession.RedrawReadyCancel(); + } + + free(phdata->NGAGE_DrawDevice); + + if (phdata->NGAGE_WsWindow.WsHandle()) { + phdata->NGAGE_WsWindow.Close(); + } + + if (phdata->NGAGE_WsWindowGroup.WsHandle()) { + phdata->NGAGE_WsWindowGroup.Close(); + } + + delete phdata->NGAGE_WindowGc; + phdata->NGAGE_WindowGc = NULL; + + delete phdata->NGAGE_WsScreen; + phdata->NGAGE_WsScreen = NULL; + + if (phdata->NGAGE_WsSession.WsHandle()) { + phdata->NGAGE_WsSession.Close(); + } + + SDL_free(phdata); + phdata = NULL; + } + + if (device) { + SDL_free(device); + device = NULL; + } +} + +static SDL_VideoDevice *NGAGE_CreateDevice(void) +{ + SDL_VideoDevice *device; + SDL_VideoData *phdata; + + /* Initialize all variables that we clean on shutdown */ + device = (SDL_VideoDevice *)SDL_calloc(1, sizeof(SDL_VideoDevice)); + if (!device) { + SDL_OutOfMemory(); + return 0; + } + + /* Initialize internal N-Gage specific data */ + phdata = (SDL_VideoData *)SDL_calloc(1, sizeof(SDL_VideoData)); + if (!phdata) { + SDL_OutOfMemory(); + SDL_free(device); + return 0; + } + + /* General video */ + device->VideoInit = NGAGE_VideoInit; + device->VideoQuit = NGAGE_VideoQuit; + device->SetDisplayMode = NGAGE_SetDisplayMode; + device->PumpEvents = NGAGE_PumpEvents; + device->CreateWindowFramebuffer = SDL_NGAGE_CreateWindowFramebuffer; + device->UpdateWindowFramebuffer = SDL_NGAGE_UpdateWindowFramebuffer; + device->DestroyWindowFramebuffer = SDL_NGAGE_DestroyWindowFramebuffer; + device->free = NGAGE_DeleteDevice; + + /* "Window" */ + device->CreateSDLWindow = NGAGE_CreateWindow; + device->DestroyWindow = NGAGE_DestroyWindow; + + /* N-Gage specific data */ + device->driverdata = phdata; + + return device; +} + +VideoBootStrap NGAGE_bootstrap = { + NGAGEVID_DRIVER_NAME, "SDL ngage video driver", + NGAGE_CreateDevice, + NULL /* no ShowMessageBox implementation */ +}; + +int NGAGE_VideoInit(_THIS) +{ + SDL_DisplayMode mode; + + /* Use 12-bpp desktop mode */ + mode.format = SDL_PIXELFORMAT_RGB444; + mode.w = 176; + mode.h = 208; + mode.refresh_rate = 0; + mode.driverdata = NULL; + if (SDL_AddBasicVideoDisplay(&mode) < 0) { + return -1; + } + + SDL_zero(mode); + SDL_AddDisplayMode(&_this->displays[0], &mode); + + /* We're done! */ + return 0; +} + +static int NGAGE_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode) +{ + return 0; +} + +void NGAGE_VideoQuit(_THIS) +{ +} + +#endif /* SDL_VIDEO_DRIVER_NGAGE */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/ngage/SDL_ngagevideo.h b/SDL2-2.30.5/src/video/ngage/SDL_ngagevideo.h new file mode 100644 index 0000000..57386e1 --- /dev/null +++ b/SDL2-2.30.5/src/video/ngage/SDL_ngagevideo.h @@ -0,0 +1,68 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifndef _SDL_ngagevideo_h +#define _SDL_ngagevideo_h + +#include "../SDL_sysvideo.h" + +#include +#include +#include +#include +#include "bitdraw.h" // CFbsDrawDevice + +#define _THIS SDL_VideoDevice *_this + +typedef struct SDL_VideoData +{ + /* Epoc window server info */ + RWsSession NGAGE_WsSession; + RWindowGroup NGAGE_WsWindowGroup; + TInt NGAGE_WsWindowGroupID; + RWindow NGAGE_WsWindow; + CWsScreenDevice *NGAGE_WsScreen; + CWindowGc *NGAGE_WindowGc; + TRequestStatus NGAGE_WsEventStatus; + TRequestStatus NGAGE_RedrawEventStatus; + TWsEvent NGAGE_WsEvent; + CFbsDrawDevice *NGAGE_DrawDevice; + TBool NGAGE_IsWindowFocused; /* Not used yet */ + + /* Screen hardware frame buffer info */ + TBool NGAGE_HasFrameBuffer; + TInt NGAGE_BytesPerPixel; + TInt NGAGE_BytesPerScanLine; + TInt NGAGE_BytesPerScreen; + TDisplayMode NGAGE_DisplayMode; + TSize NGAGE_ScreenSize; + TUint8 *NGAGE_FrameBuffer; + TPoint NGAGE_ScreenOffset; + + CFbsBitGc::TGraphicsOrientation NGAGE_ScreenOrientation; + +} SDL_VideoData; + +#endif /* _SDL_ngagevideo_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/ngage/SDL_ngagewindow.cpp b/SDL2-2.30.5/src/video/ngage/SDL_ngagewindow.cpp new file mode 100644 index 0000000..37a6be0 --- /dev/null +++ b/SDL2-2.30.5/src/video/ngage/SDL_ngagewindow.cpp @@ -0,0 +1,127 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_NGAGE + +#include "../SDL_sysvideo.h" + +#include "SDL_ngagewindow.h" + +const TUint32 WindowClientHandle = 9210; + +void DisableKeyBlocking(_THIS); +void ConstructWindowL(_THIS); + +int NGAGE_CreateWindow(_THIS, SDL_Window *window) +{ + NGAGE_Window *ngage_window = (NGAGE_Window *)SDL_calloc(1, sizeof(NGAGE_Window)); + + if (!ngage_window) { + return SDL_OutOfMemory(); + } + + window->driverdata = ngage_window; + + if (window->x == SDL_WINDOWPOS_UNDEFINED) { + window->x = 0; + } + + if (window->y == SDL_WINDOWPOS_UNDEFINED) { + window->y = 0; + } + + ngage_window->sdl_window = window; + + ConstructWindowL(_this); + + return 0; +} + +void NGAGE_DestroyWindow(_THIS, SDL_Window *window) +{ + NGAGE_Window *ngage_window = (NGAGE_Window *)window->driverdata; + + if (ngage_window) { + SDL_free(ngage_window); + } + + window->driverdata = NULL; +} + +/*****************************************************************************/ +/* Internal */ +/*****************************************************************************/ + +void DisableKeyBlocking(_THIS) +{ + SDL_VideoData *phdata = (SDL_VideoData *)_this->driverdata; + TRawEvent event; + + event.Set((TRawEvent::TType) /*EDisableKeyBlock*/ 51); + phdata->NGAGE_WsSession.SimulateRawEvent(event); +} + +void ConstructWindowL(_THIS) +{ + SDL_VideoData *phdata = (SDL_VideoData *)_this->driverdata; + TInt error; + + error = phdata->NGAGE_WsSession.Connect(); + User::LeaveIfError(error); + phdata->NGAGE_WsScreen = new (ELeave) CWsScreenDevice(phdata->NGAGE_WsSession); + User::LeaveIfError(phdata->NGAGE_WsScreen->Construct()); + User::LeaveIfError(phdata->NGAGE_WsScreen->CreateContext(phdata->NGAGE_WindowGc)); + + phdata->NGAGE_WsWindowGroup = RWindowGroup(phdata->NGAGE_WsSession); + User::LeaveIfError(phdata->NGAGE_WsWindowGroup.Construct(WindowClientHandle)); + phdata->NGAGE_WsWindowGroup.SetOrdinalPosition(0); + + RProcess thisProcess; + TParse exeName; + exeName.Set(thisProcess.FileName(), NULL, NULL); + TBuf<32> winGroupName; + winGroupName.Append(0); + winGroupName.Append(0); + winGroupName.Append(0); // UID + winGroupName.Append(0); + winGroupName.Append(exeName.Name()); // Caption + winGroupName.Append(0); + winGroupName.Append(0); // DOC name + phdata->NGAGE_WsWindowGroup.SetName(winGroupName); + + phdata->NGAGE_WsWindow = RWindow(phdata->NGAGE_WsSession); + User::LeaveIfError(phdata->NGAGE_WsWindow.Construct(phdata->NGAGE_WsWindowGroup, WindowClientHandle - 1)); + phdata->NGAGE_WsWindow.SetBackgroundColor(KRgbWhite); + phdata->NGAGE_WsWindow.Activate(); + phdata->NGAGE_WsWindow.SetSize(phdata->NGAGE_WsScreen->SizeInPixels()); + phdata->NGAGE_WsWindow.SetVisible(ETrue); + + phdata->NGAGE_WsWindowGroupID = phdata->NGAGE_WsWindowGroup.Identifier(); + phdata->NGAGE_IsWindowFocused = EFalse; + + DisableKeyBlocking(_this); +} + +#endif /* SDL_VIDEO_DRIVER_NGAGE */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/ngage/SDL_ngagewindow.h b/SDL2-2.30.5/src/video/ngage/SDL_ngagewindow.h new file mode 100644 index 0000000..933ca8e --- /dev/null +++ b/SDL2-2.30.5/src/video/ngage/SDL_ngagewindow.h @@ -0,0 +1,44 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#ifndef _SDL_ngagewindow_h +#define _SDL_ngagewindow_h + +#include "../SDL_sysvideo.h" +#include "SDL_syswm.h" + +#include "SDL_ngagevideo.h" + +typedef struct +{ + SDL_Window *sdl_window; + +} NGAGE_Window; + +extern int +NGAGE_CreateWindow(_THIS, SDL_Window *window); + +extern void +NGAGE_DestroyWindow(_THIS, SDL_Window *window); + +#endif /* _SDL_ngagewindow */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/offscreen/SDL_offscreenevents.c b/SDL2-2.30.5/src/video/offscreen/SDL_offscreenevents.c similarity index 90% rename from SDL2-2.0.12/src/video/offscreen/SDL_offscreenevents.c rename to SDL2-2.30.5/src/video/offscreen/SDL_offscreenevents.c index e24d954..d825162 100644 --- a/SDL2-2.0.12/src/video/offscreen/SDL_offscreenevents.c +++ b/SDL2-2.30.5/src/video/offscreen/SDL_offscreenevents.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -18,10 +18,9 @@ misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ - #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_OFFSCREEN +#ifdef SDL_VIDEO_DRIVER_OFFSCREEN /* Being a offscreen driver, there's no event stream. We just define stubs for most of the API. */ @@ -31,8 +30,7 @@ #include "SDL_offscreenvideo.h" #include "SDL_offscreenevents_c.h" -void -OFFSCREEN_PumpEvents(_THIS) +void OFFSCREEN_PumpEvents(_THIS) { /* do nothing. */ } diff --git a/SDL2-2.0.12/src/video/offscreen/SDL_offscreenevents_c.h b/SDL2-2.30.5/src/video/offscreen/SDL_offscreenevents_c.h similarity index 91% rename from SDL2-2.0.12/src/video/offscreen/SDL_offscreenevents_c.h rename to SDL2-2.30.5/src/video/offscreen/SDL_offscreenevents_c.h index 768fb24..ccbef93 100644 --- a/SDL2-2.0.12/src/video/offscreen/SDL_offscreenevents_c.h +++ b/SDL2-2.30.5/src/video/offscreen/SDL_offscreenevents_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -18,11 +18,8 @@ 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_offscreenvideo.h" - extern void OFFSCREEN_PumpEvents(_THIS); /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/offscreen/SDL_offscreenframebuffer.c b/SDL2-2.30.5/src/video/offscreen/SDL_offscreenframebuffer.c similarity index 63% rename from SDL2-2.0.12/src/video/offscreen/SDL_offscreenframebuffer.c rename to SDL2-2.30.5/src/video/offscreen/SDL_offscreenframebuffer.c index 93fa368..2b9337b 100644 --- a/SDL2-2.0.12/src/video/offscreen/SDL_offscreenframebuffer.c +++ b/SDL2-2.30.5/src/video/offscreen/SDL_offscreenframebuffer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -18,33 +18,27 @@ misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ - #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_OFFSCREEN +#ifdef SDL_VIDEO_DRIVER_OFFSCREEN #include "../SDL_sysvideo.h" #include "SDL_offscreenframebuffer_c.h" +#define OFFSCREEN_SURFACE "_SDL_DummySurface" -#define OFFSCREEN_SURFACE "_SDL_DummySurface" - -int SDL_OFFSCREEN_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch) +int SDL_OFFSCREEN_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format, void **pixels, int *pitch) { SDL_Surface *surface; const Uint32 surface_format = SDL_PIXELFORMAT_RGB888; int w, h; - int bpp; - Uint32 Rmask, Gmask, Bmask, Amask; /* Free the old framebuffer surface */ - surface = (SDL_Surface *) SDL_GetWindowData(window, OFFSCREEN_SURFACE); - SDL_FreeSurface(surface); + SDL_OFFSCREEN_DestroyWindowFramebuffer(_this, window); /* Create a new one */ - SDL_PixelFormatEnumToMasks(surface_format, &bpp, &Rmask, &Gmask, &Bmask, &Amask); - SDL_GetWindowSize(window, &w, &h); - surface = SDL_CreateRGBSurface(0, w, h, bpp, Rmask, Gmask, Bmask, Amask); + SDL_GetWindowSizeInPixels(window, &w, &h); + surface = SDL_CreateRGBSurfaceWithFormat(0, w, h, 0, surface_format); if (!surface) { return -1; } @@ -54,15 +48,16 @@ int SDL_OFFSCREEN_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * f *format = surface_format; *pixels = surface->pixels; *pitch = surface->pitch; + return 0; } -int SDL_OFFSCREEN_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects) +int SDL_OFFSCREEN_UpdateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_Rect *rects, int numrects) { static int frame_number; SDL_Surface *surface; - surface = (SDL_Surface *) SDL_GetWindowData(window, OFFSCREEN_SURFACE); + surface = (SDL_Surface *)SDL_GetWindowData(window, OFFSCREEN_SURFACE); if (!surface) { return SDL_SetError("Couldn't find offscreen surface for window"); } @@ -70,18 +65,18 @@ int SDL_OFFSCREEN_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_ /* Send the data to the display */ if (SDL_getenv("SDL_VIDEO_OFFSCREEN_SAVE_FRAMES")) { char file[128]; - SDL_snprintf(file, sizeof(file), "SDL_window%d-%8.8d.bmp", - SDL_GetWindowID(window), ++frame_number); + (void)SDL_snprintf(file, sizeof(file), "SDL_window%" SDL_PRIu32 "-%8.8d.bmp", + SDL_GetWindowID(window), ++frame_number); SDL_SaveBMP(surface, file); } return 0; } -void SDL_OFFSCREEN_DestroyWindowFramebuffer(_THIS, SDL_Window * window) +void SDL_OFFSCREEN_DestroyWindowFramebuffer(_THIS, SDL_Window *window) { SDL_Surface *surface; - surface = (SDL_Surface *) SDL_SetWindowData(window, OFFSCREEN_SURFACE, NULL); + surface = (SDL_Surface *)SDL_SetWindowData(window, OFFSCREEN_SURFACE, NULL); SDL_FreeSurface(surface); } diff --git a/SDL2-2.0.12/src/video/offscreen/SDL_offscreenframebuffer_c.h b/SDL2-2.30.5/src/video/offscreen/SDL_offscreenframebuffer_c.h similarity index 85% rename from SDL2-2.0.12/src/video/offscreen/SDL_offscreenframebuffer_c.h rename to SDL2-2.30.5/src/video/offscreen/SDL_offscreenframebuffer_c.h index d8577c9..1151576 100644 --- a/SDL2-2.0.12/src/video/offscreen/SDL_offscreenframebuffer_c.h +++ b/SDL2-2.30.5/src/video/offscreen/SDL_offscreenframebuffer_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -18,11 +18,10 @@ misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ - #include "../../SDL_internal.h" -extern int SDL_OFFSCREEN_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch); -extern int SDL_OFFSCREEN_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects); -extern void SDL_OFFSCREEN_DestroyWindowFramebuffer(_THIS, SDL_Window * window); +extern int SDL_OFFSCREEN_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format, void **pixels, int *pitch); +extern int SDL_OFFSCREEN_UpdateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_Rect *rects, int numrects); +extern void SDL_OFFSCREEN_DestroyWindowFramebuffer(_THIS, SDL_Window *window); /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/offscreen/SDL_offscreenopengl.c b/SDL2-2.30.5/src/video/offscreen/SDL_offscreenopengles.c similarity index 51% rename from SDL2-2.0.12/src/video/offscreen/SDL_offscreenopengl.c rename to SDL2-2.30.5/src/video/offscreen/SDL_offscreenopengles.c index 92e37f2..a36cf51 100644 --- a/SDL2-2.0.12/src/video/offscreen/SDL_offscreenopengl.c +++ b/SDL2-2.30.5/src/video/offscreen/SDL_offscreenopengles.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -18,55 +18,30 @@ misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ - #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_OFFSCREEN +#if defined(SDL_VIDEO_DRIVER_OFFSCREEN) && defined(SDL_VIDEO_OPENGL_EGL) -#include "SDL_offscreenopengl.h" +#include "SDL_offscreenopengles.h" +#include "SDL_offscreenvideo.h" +#include "SDL_offscreenwindow.h" -#include "SDL_opengl.h" +/* EGL implementation of SDL OpenGL support */ -int -OFFSCREEN_GL_SwapWindow(_THIS, SDL_Window* window) -{ - OFFSCREEN_Window* offscreen_wind = window->driverdata; - - SDL_EGL_SwapBuffers(_this, offscreen_wind->egl_surface); - return 0; -} - -int -OFFSCREEN_GL_MakeCurrent(_THIS, SDL_Window* window, SDL_GLContext context) -{ - if (window) { - EGLSurface egl_surface = ((OFFSCREEN_Window*)window->driverdata)->egl_surface; - return SDL_EGL_MakeCurrent(_this, egl_surface, context); - } - - return SDL_EGL_MakeCurrent(_this, NULL, NULL); -} - -SDL_GLContext -OFFSCREEN_GL_CreateContext(_THIS, SDL_Window* window) -{ - OFFSCREEN_Window* offscreen_window = window->driverdata; - - SDL_GLContext context; - context = SDL_EGL_CreateContext(_this, offscreen_window->egl_surface); - - return context; -} - -int -OFFSCREEN_GL_LoadLibrary(_THIS, const char* path) +int OFFSCREEN_GLES_LoadLibrary(_THIS, const char *path) { int ret = SDL_EGL_LoadLibraryOnly(_this, path); if (ret != 0) { return ret; } + /* driver_loaded gets incremented by SDL_GL_LoadLibrary when we return, + but SDL_EGL_InitializeOffscreen checks that we're loaded before then, + so temporarily bump it since we know that LoadLibraryOnly succeeded. */ + + _this->gl_config.driver_loaded++; ret = SDL_EGL_InitializeOffscreen(_this, 0); + _this->gl_config.driver_loaded--; if (ret != 0) { return ret; } @@ -79,24 +54,33 @@ OFFSCREEN_GL_LoadLibrary(_THIS, const char* path) return 0; } -void -OFFSCREEN_GL_UnloadLibrary(_THIS) +SDL_GLContext OFFSCREEN_GLES_CreateContext(_THIS, SDL_Window *window) { - SDL_EGL_UnloadLibrary(_this); + OFFSCREEN_Window *offscreen_window = window->driverdata; + + SDL_GLContext context; + context = SDL_EGL_CreateContext(_this, offscreen_window->egl_surface); + + return context; } -void* -OFFSCREEN_GL_GetProcAddress(_THIS, const char* proc) +int OFFSCREEN_GLES_MakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context) { - void* proc_addr = SDL_EGL_GetProcAddress(_this, proc); - - if (!proc_addr) { - SDL_SetError("Failed to find proc address!"); + if (window) { + EGLSurface egl_surface = ((OFFSCREEN_Window *)window->driverdata)->egl_surface; + return SDL_EGL_MakeCurrent(_this, egl_surface, context); + } else { + return SDL_EGL_MakeCurrent(_this, NULL, NULL); } - - return proc_addr; } -#endif /* SDL_VIDEO_DRIVER_OFFSCREEN */ +int OFFSCREEN_GLES_SwapWindow(_THIS, SDL_Window *window) +{ + OFFSCREEN_Window *offscreen_wind = window->driverdata; + + return SDL_EGL_SwapBuffers(_this, offscreen_wind->egl_surface); +} + +#endif /* SDL_VIDEO_DRIVER_OFFSCREEN && SDL_VIDEO_OPENGL_EGL */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/offscreen/SDL_offscreenopengles.h b/SDL2-2.30.5/src/video/offscreen/SDL_offscreenopengles.h new file mode 100644 index 0000000..c8c23f1 --- /dev/null +++ b/SDL2-2.30.5/src/video/offscreen/SDL_offscreenopengles.h @@ -0,0 +1,46 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifndef _SDL_offscreenopengles_h +#define _SDL_offscreenopengles_h + +#if defined(SDL_VIDEO_DRIVER_OFFSCREEN) && defined(SDL_VIDEO_OPENGL_EGL) + +#include "../SDL_sysvideo.h" +#include "../SDL_egl_c.h" + +#define OFFSCREEN_GLES_GetProcAddress SDL_EGL_GetProcAddress +#define OFFSCREEN_GLES_UnloadLibrary SDL_EGL_UnloadLibrary +#define OFFSCREEN_GLES_GetSwapInterval SDL_EGL_GetSwapInterval +#define OFFSCREEN_GLES_SetSwapInterval SDL_EGL_SetSwapInterval +#define OFFSCREEN_GLES_DeleteContext SDL_EGL_DeleteContext + +extern int OFFSCREEN_GLES_LoadLibrary(_THIS, const char *path); +extern SDL_GLContext OFFSCREEN_GLES_CreateContext(_THIS, SDL_Window *window); +extern int OFFSCREEN_GLES_MakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context); +extern int OFFSCREEN_GLES_SwapWindow(_THIS, SDL_Window *window); + +#endif /* SDL_VIDEO_DRIVER_OFFSCREEN && SDL_VIDEO_OPENGL_EGL */ + +#endif /* _SDL_offscreenopengles_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/offscreen/SDL_offscreenvideo.c b/SDL2-2.30.5/src/video/offscreen/SDL_offscreenvideo.c similarity index 63% rename from SDL2-2.0.12/src/video/offscreen/SDL_offscreenvideo.c rename to SDL2-2.30.5/src/video/offscreen/SDL_offscreenvideo.c index 811eb4a..2d42374 100644 --- a/SDL2-2.0.12/src/video/offscreen/SDL_offscreenvideo.c +++ b/SDL2-2.30.5/src/video/offscreen/SDL_offscreenvideo.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -18,10 +18,9 @@ misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ - #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_OFFSCREEN +#ifdef SDL_VIDEO_DRIVER_OFFSCREEN /* Offscreen video driver is similar to dummy driver, however its purpose * is enabling applications to use some of the SDL video functionality @@ -32,48 +31,36 @@ */ #include "SDL_video.h" -#include "SDL_mouse.h" -#include "../SDL_sysvideo.h" -#include "../SDL_pixels_c.h" -#include "../../events/SDL_events_c.h" #include "SDL_offscreenvideo.h" #include "SDL_offscreenevents_c.h" #include "SDL_offscreenframebuffer_c.h" -#include "SDL_offscreenopengl.h" +#include "SDL_offscreenopengles.h" +#include "SDL_offscreenwindow.h" #define OFFSCREENVID_DRIVER_NAME "offscreen" /* Initialization/Query functions */ static int OFFSCREEN_VideoInit(_THIS); -static int OFFSCREEN_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode); +static int OFFSCREEN_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode); static void OFFSCREEN_VideoQuit(_THIS); /* OFFSCREEN driver bootstrap functions */ -static int -OFFSCREEN_Available(void) -{ - /* Consider it always available */ - return (1); -} - -static void -OFFSCREEN_DeleteDevice(SDL_VideoDevice * device) +static void OFFSCREEN_DeleteDevice(SDL_VideoDevice *device) { SDL_free(device); } -static SDL_VideoDevice * -OFFSCREEN_CreateDevice(int devindex) +static SDL_VideoDevice *OFFSCREEN_CreateDevice(void) { SDL_VideoDevice *device; /* Initialize all variables that we clean on shutdown */ - device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice)); + device = (SDL_VideoDevice *)SDL_calloc(1, sizeof(SDL_VideoDevice)); if (!device) { SDL_OutOfMemory(); - return (0); + return 0; } /* General video */ @@ -86,16 +73,18 @@ OFFSCREEN_CreateDevice(int devindex) device->DestroyWindowFramebuffer = SDL_OFFSCREEN_DestroyWindowFramebuffer; device->free = OFFSCREEN_DeleteDevice; +#ifdef SDL_VIDEO_OPENGL_EGL /* GL context */ - device->GL_SwapWindow = OFFSCREEN_GL_SwapWindow; - device->GL_MakeCurrent = OFFSCREEN_GL_MakeCurrent; - device->GL_CreateContext = OFFSCREEN_GL_CreateContext; - device->GL_DeleteContext = OFFSCREEN_GL_DeleteContext; - device->GL_LoadLibrary = OFFSCREEN_GL_LoadLibrary; - device->GL_UnloadLibrary = OFFSCREEN_GL_UnloadLibrary; - device->GL_GetProcAddress = OFFSCREEN_GL_GetProcAddress; - device->GL_GetSwapInterval = OFFSCREEN_GL_GetSwapInterval; - device->GL_SetSwapInterval = OFFSCREEN_GL_SetSwapInterval; + device->GL_SwapWindow = OFFSCREEN_GLES_SwapWindow; + device->GL_MakeCurrent = OFFSCREEN_GLES_MakeCurrent; + device->GL_CreateContext = OFFSCREEN_GLES_CreateContext; + device->GL_DeleteContext = OFFSCREEN_GLES_DeleteContext; + device->GL_LoadLibrary = OFFSCREEN_GLES_LoadLibrary; + device->GL_UnloadLibrary = OFFSCREEN_GLES_UnloadLibrary; + device->GL_GetProcAddress = OFFSCREEN_GLES_GetProcAddress; + device->GL_GetSwapInterval = OFFSCREEN_GLES_GetSwapInterval; + device->GL_SetSwapInterval = OFFSCREEN_GLES_SetSwapInterval; +#endif /* "Window" */ device->CreateSDLWindow = OFFSCREEN_CreateWindow; @@ -106,27 +95,13 @@ OFFSCREEN_CreateDevice(int devindex) VideoBootStrap OFFSCREEN_bootstrap = { OFFSCREENVID_DRIVER_NAME, "SDL offscreen video driver", - OFFSCREEN_Available, OFFSCREEN_CreateDevice + OFFSCREEN_CreateDevice, + NULL /* no ShowMessageBox implementation */ }; -static Uint32 -OFFSCREEN_GetGlobalMouseState(int *x, int *y) -{ - if (x) { - *x = 0; - } - - if (y) { - *y = 0; - } - return 0; -} - -int -OFFSCREEN_VideoInit(_THIS) +int OFFSCREEN_VideoInit(_THIS) { SDL_DisplayMode mode; - SDL_Mouse *mouse = NULL; /* Use a fake 32-bpp desktop mode */ mode.format = SDL_PIXELFORMAT_RGB888; @@ -141,23 +116,16 @@ OFFSCREEN_VideoInit(_THIS) SDL_zero(mode); SDL_AddDisplayMode(&_this->displays[0], &mode); - /* Init mouse */ - mouse = SDL_GetMouse(); - /* This function needs to be implemented by every driver */ - mouse->GetGlobalMouseState = OFFSCREEN_GetGlobalMouseState; - /* We're done! */ return 0; } -static int -OFFSCREEN_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) +static int OFFSCREEN_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode) { return 0; } -void -OFFSCREEN_VideoQuit(_THIS) +void OFFSCREEN_VideoQuit(_THIS) { } diff --git a/SDL2-2.0.12/src/video/offscreen/SDL_offscreenvideo.h b/SDL2-2.30.5/src/video/offscreen/SDL_offscreenvideo.h similarity index 92% rename from SDL2-2.0.12/src/video/offscreen/SDL_offscreenvideo.h rename to SDL2-2.30.5/src/video/offscreen/SDL_offscreenvideo.h index 843c34d..f4e3c8f 100644 --- a/SDL2-2.0.12/src/video/offscreen/SDL_offscreenvideo.h +++ b/SDL2-2.30.5/src/video/offscreen/SDL_offscreenvideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -18,14 +18,12 @@ misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ - #include "../../SDL_internal.h" #ifndef _SDL_offscreenvideo_h #define _SDL_offscreenvideo_h #include "../SDL_sysvideo.h" -#include "../SDL_egl_c.h" #endif /* _SDL_offscreenvideo_h */ diff --git a/SDL2-2.0.12/src/video/offscreen/SDL_offscreenwindow.c b/SDL2-2.30.5/src/video/offscreen/SDL_offscreenwindow.c similarity index 83% rename from SDL2-2.0.12/src/video/offscreen/SDL_offscreenwindow.c rename to SDL2-2.30.5/src/video/offscreen/SDL_offscreenwindow.c index 19e0097..58fc2e9 100644 --- a/SDL2-2.0.12/src/video/offscreen/SDL_offscreenwindow.c +++ b/SDL2-2.30.5/src/video/offscreen/SDL_offscreenwindow.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -18,20 +18,18 @@ misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ - #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_OFFSCREEN +#ifdef SDL_VIDEO_DRIVER_OFFSCREEN -#include "../SDL_egl_c.h" #include "../SDL_sysvideo.h" +#include "../SDL_egl_c.h" #include "SDL_offscreenwindow.h" -int -OFFSCREEN_CreateWindow(_THIS, SDL_Window* window) +int OFFSCREEN_CreateWindow(_THIS, SDL_Window *window) { - OFFSCREEN_Window* offscreen_window = SDL_calloc(1, sizeof(OFFSCREEN_Window)); + OFFSCREEN_Window *offscreen_window = SDL_calloc(1, sizeof(OFFSCREEN_Window)); if (!offscreen_window) { return SDL_OutOfMemory(); @@ -49,6 +47,7 @@ OFFSCREEN_CreateWindow(_THIS, SDL_Window* window) offscreen_window->sdl_window = window; +#ifdef SDL_VIDEO_OPENGL_EGL if (window->flags & SDL_WINDOW_OPENGL) { if (!_this->egl_data) { @@ -61,21 +60,22 @@ OFFSCREEN_CreateWindow(_THIS, SDL_Window* window) return SDL_SetError("Failed to created an offscreen surface (EGL display: %p)", _this->egl_data->egl_display); } - } - else { + } else { offscreen_window->egl_surface = EGL_NO_SURFACE; } +#endif /* SDL_VIDEO_OPENGL_EGL */ return 0; } -void -OFFSCREEN_DestroyWindow(_THIS, SDL_Window* window) +void OFFSCREEN_DestroyWindow(_THIS, SDL_Window *window) { - OFFSCREEN_Window* offscreen_window = window->driverdata; + OFFSCREEN_Window *offscreen_window = window->driverdata; if (offscreen_window) { +#ifdef SDL_VIDEO_OPENGL_EGL SDL_EGL_DestroySurface(_this, offscreen_window->egl_surface); +#endif SDL_free(offscreen_window); } diff --git a/SDL2-2.0.12/src/video/offscreen/SDL_offscreenwindow.h b/SDL2-2.30.5/src/video/offscreen/SDL_offscreenwindow.h similarity index 78% rename from SDL2-2.0.12/src/video/offscreen/SDL_offscreenwindow.h rename to SDL2-2.30.5/src/video/offscreen/SDL_offscreenwindow.h index e8802c6..aa189c0 100644 --- a/SDL2-2.0.12/src/video/offscreen/SDL_offscreenwindow.h +++ b/SDL2-2.30.5/src/video/offscreen/SDL_offscreenwindow.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -18,29 +18,25 @@ misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ +#include "../../SDL_internal.h" #ifndef _SDL_offscreenwindow_h #define _SDL_offscreenwindow_h -#include "../SDL_sysvideo.h" -#include "SDL_syswm.h" - #include "SDL_offscreenvideo.h" -typedef struct { - SDL_Window* sdl_window; +typedef struct +{ + SDL_Window *sdl_window; +#ifdef SDL_VIDEO_OPENGL_EGL EGLSurface egl_surface; +#endif } OFFSCREEN_Window; - -extern int -OFFSCREEN_CreateWindow(_THIS, SDL_Window* window); - -extern void -OFFSCREEN_DestroyWindow(_THIS, SDL_Window* window); +extern int OFFSCREEN_CreateWindow(_THIS, SDL_Window *window); +extern void OFFSCREEN_DestroyWindow(_THIS, SDL_Window *window); #endif /* _SDL_offscreenwindow */ /* vi: set ts=4 sw=4 expandtab: */ - diff --git a/SDL2-2.30.5/src/video/os2/SDL_gradd.h b/SDL2-2.30.5/src/video/os2/SDL_gradd.h new file mode 100644 index 0000000..a1369a2 --- /dev/null +++ b/SDL2-2.30.5/src/video/os2/SDL_gradd.h @@ -0,0 +1,171 @@ +/* +gradd.h structures and constants -- only the ones used by SDL_os2vman.c. + +Based on public knowledge from around the internet including pages from +http://www.osfree.org and http://www.edm2.com +*/ + +#ifndef SDL_gradd_h_ +#define SDL_gradd_h_ + +typedef struct _INITPROCOUT { + ULONG ulLength; /* Length of the INITPROCOUT data structure, in bytes. */ + ULONG ulVRAMVirt; /* 32-bit virtual address of VRAM. */ +} INITPROCOUT; +typedef INITPROCOUT *PINITPROCOUT; + +#define RC_SUCCESS 0 + +typedef ULONG GID; +typedef ULONG (_System FNVMIENTRY) ( + GID gid, ULONG ulFunction, + PVOID pIn, + PVOID pOut /* PINITPROCOUT */ +); + +#define VMI_CMD_INITPROC 1 +#define VMI_CMD_TERMPROC 3 +#define VMI_CMD_QUERYMODES 5 +#define VMI_CMD_SETMODE 6 +#define VMI_CMD_PALETTE 7 +#define VMI_CMD_BITBLT 8 +#define VMI_CMD_LINE 9 +#define VMI_CMD_REQUESTHW 14 +#define VMI_CMD_QUERYCURRENTMODE 0x1001 + +#define QUERYMODE_NUM_MODES 0x01 +#define QUERYMODE_MODE_DATA 0x02 + +typedef struct _HWPALETTEINFO { + ULONG ulLength; /* Size of the HWPALETTEINFO data structure, in bytes. */ + ULONG fFlags; /* Palette flag. */ + ULONG ulStartIndex; /* Starting palette index. */ + ULONG ulNumEntries; /* Number of palette slots to query or set. */ + PRGB2 pRGBs; /* Pointer to the array of RGB values. */ +} HWPALETTEINFO; +typedef HWPALETTEINFO *PHWPALETTEINFO; + +#define PALETTE_GET 0x01 +#define PALETTE_SET 0x02 + +typedef struct _BMAPINFO { + ULONG ulLength; /* Length of the BMAPINFO data structure, in bytes. */ + ULONG ulType; /* Description of the Blt. */ + ULONG ulWidth; /* Width in pels of the bit map. */ + ULONG ulHeight; /* Height in pels of the bit map. */ + ULONG ulBpp; /* Number of bits per pel/color depth. */ + ULONG ulBytesPerLine; /* Number of aligned bytes per line. */ + PBYTE pBits; /* Pointer to bit-map bits. */ +} BMAPINFO; +typedef BMAPINFO *PBMAPINFO; + +#define BMAP_VRAM 0 +#define BMAP_MEMORY 1 + +typedef struct _LINEPACK { + ULONG ulStyleStep; /* Value to be added to ulStyleValue. */ + ULONG ulStyleValue; /* Style value at the current pel. */ + ULONG ulFlags; /* Flags used for the LINEPACK data structure. */ + struct _LINEPACK *plpkNext; /* Pointer to next LINEPACK data structure. */ + ULONG ulAbsDeltaX; /* Clipped Bresenham Delta X, absolute. */ + ULONG ulAbsDeltaY; /* Clipped Bresenham Delta Y, absolute. */ + POINTL ptlClipStart; /* Pointer to location for device to perform Bresenham algorithm. */ + POINTL ptlClipEnd; /* Ending location for Bresenham algorithm (see ptlClipStart). */ + POINTL ptlStart; /* Pointer to starting location for line. */ + POINTL ptlEnd; /* Ending location for line. */ + LONG lClipStartError;/* Standard Bresenham error at the clipped start point. */ +} LINEPACK; +typedef LINEPACK *PLINEPACK; + +typedef struct _LINEINFO { + ULONG ulLength; /* Length of LINEINFO data structure. */ + ULONG ulType; /* Defines line type. */ + ULONG ulStyleMask; /* A 32-bit style mask. */ + ULONG cLines; /* Count of lines to be drawn. */ + ULONG ulFGColor; /* Line Foreground color. */ + ULONG ulBGColor; /* Line Background color. */ + USHORT usForeROP; /* Line Foreground mix. */ + USHORT usBackROP; /* Line Background mix. */ + PBMAPINFO pDstBmapInfo; /* Pointer to destination surface bit map. */ + PLINEPACK alpkLinePack; /* Pointer to LINEPACK data structure. */ + PRECTL prclBounds; /* Pointer to bounding rect of a clipped line. */ +} LINEINFO; +typedef LINEINFO *PLINEINFO; + +#define LINE_DO_FIRST_PEL 0x02 +#define LINE_DIR_Y_POSITIVE 0x04 +#define LINE_HORIZONTAL 0x08 +#define LINE_DIR_X_POSITIVE 0x20 +#define LINE_VERTICAL 0x1000 +#define LINE_DO_LAST_PEL 0x4000 +#define LINE_SOLID 0x01 + +typedef struct _BLTRECT { + ULONG ulXOrg; /* X origin of the destination Blt. */ + ULONG ulYOrg; /* Y origin of the destination Blt. */ + ULONG ulXExt; /* X extent of the BitBlt. */ + ULONG ulYExt; /* Y extent of the BitBlt. */ +} BLTRECT; +typedef BLTRECT *PBLTRECT; + +typedef struct _BITBLTINFO { + ULONG ulLength; /* Length of the BITBLTINFO data structure, in bytes. */ + ULONG ulBltFlags; /* Flags for rendering of rasterized data. */ + ULONG cBlits; /* Count of Blts to be performed. */ + ULONG ulROP; /* Raster operation. */ + ULONG ulMonoBackROP; /* Background mix if B_APPLY_BACK_ROP is set. */ + ULONG ulSrcFGColor; /* Monochrome source Foreground color. */ + ULONG ulSrcBGColor; /* Monochrome source Background color and transparent color. */ + ULONG ulPatFGColor; /* Monochrome pattern Foreground color. */ + ULONG ulPatBGColor; /* Monochrome pattern Background color. */ + PBYTE abColors; /* Pointer to color translation table. */ + PBMAPINFO pSrcBmapInfo; /* Pointer to source bit map (BMAPINFO) */ + PBMAPINFO pDstBmapInfo; /* Pointer to destination bit map (BMAPINFO). */ + PBMAPINFO pPatBmapInfo; /* Pointer to pattern bit map (BMAPINFO). */ + PPOINTL aptlSrcOrg; /* Pointer to array of source origin POINTLs. */ + PPOINTL aptlPatOrg; /* Pointer to array of pattern origin POINTLs. */ + PBLTRECT abrDst; /* Pointer to array of Blt rects. */ + PRECTL prclSrcBounds; /* Pointer to source bounding rect of source Blts. */ + PRECTL prclDstBounds; /* Pointer to destination bounding rect of destination Blts. */ +} BITBLTINFO; +typedef BITBLTINFO *PBITBLTINFO; + +#define BF_DEFAULT_STATE 0x0 +#define BF_ROP_INCL_SRC (0x01 << 2) +#define BF_PAT_HOLLOW (0x01 << 8) + +typedef struct _GDDMODEINFO { + ULONG ulLength; /* Size of the GDDMODEINFO data structure, in bytes. */ + ULONG ulModeId; /* ID used to make SETMODE request. */ + ULONG ulBpp; /* Number of colors (bpp). */ + ULONG ulHorizResolution;/* Number of horizontal pels. */ + ULONG ulVertResolution; /* Number of vertical scan lines. */ + ULONG ulRefreshRate; /* Refresh rate in Hz. */ + PBYTE pbVRAMPhys; /* Physical address of VRAM. */ + ULONG ulApertureSize; /* Size of VRAM, in bytes. */ + ULONG ulScanLineSize; /* Size of one scan line, in bytes. */ + + ULONG fccColorEncoding, ulTotalVRAMSize, cColors; +} GDDMODEINFO; +typedef GDDMODEINFO *PGDDMODEINFO; + +typedef struct _HWREQIN { + ULONG ulLength; /* Size of the HWREQIN data structure, in bytes. */ + ULONG ulFlags; /* Request option flags. */ + ULONG cScrChangeRects; /* Count of screen rectangles affected by HWREQIN. */ + PRECTL arectlScreen; /* Array of screen rectangles affected by HWREQIN. */ +} HWREQIN; +typedef HWREQIN *PHWREQIN; + +#define REQUEST_HW 0x01 + +/* +BOOL GreDeath(HDC hdc, PVOID pInstance, LONG lFunction); +LONG GreResurrection(HDC hdc, LONG cbVmem, PULONG pReserved, PVOID pInstance, LONG lFunction); +*/ +#define GreDeath(h) (BOOL)Gre32Entry3((ULONG)(h), 0, 0x40B7L) +#define GreResurrection(h,n,r) (LONG)Gre32Entry5((ULONG)(h), (ULONG)(n), (ULONG)(r), 0, 0x40B8L) +ULONG _System Gre32Entry3(ULONG, ULONG, ULONG); +ULONG _System Gre32Entry5(ULONG, ULONG, ULONG, ULONG, ULONG); + +#endif /* SDL_gradd_h_ */ diff --git a/SDL2-2.30.5/src/video/os2/SDL_os2dive.c b/SDL2-2.30.5/src/video/os2/SDL_os2dive.c new file mode 100644 index 0000000..0cb8735 --- /dev/null +++ b/SDL2-2.30.5/src/video/os2/SDL_os2dive.c @@ -0,0 +1,331 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_sysvideo.h" +#define INCL_WIN +#define INCL_GPI +#include +#define _MEERROR_H_ +#include +#include +#define INCL_MM_OS2 +#include +#include +#include "SDL_os2output.h" + +typedef struct _VODATA { + HDIVE hDive; + PVOID pBuffer; + ULONG ulDIVEBufNum; + FOURCC fccColorEncoding; + ULONG ulWidth; + ULONG ulHeight; + BOOL fBlitterReady; +} VODATA; + +static BOOL voQueryInfo(VIDEOOUTPUTINFO *pInfo); +static PVODATA voOpen(void); +static VOID voClose(PVODATA pVOData); +static BOOL voSetVisibleRegion(PVODATA pVOData, HWND hwnd, + SDL_DisplayMode *pSDLDisplayMode, + HRGN hrgnShape, BOOL fVisible); +static PVOID voVideoBufAlloc(PVODATA pVOData, ULONG ulWidth, ULONG ulHeight, + ULONG ulBPP, ULONG fccColorEncoding, + PULONG pulScanLineSize); +static VOID voVideoBufFree(PVODATA pVOData); +static BOOL voUpdate(PVODATA pVOData, HWND hwnd, SDL_Rect *pSDLRects, + ULONG cSDLRects); + +OS2VIDEOOUTPUT voDive = { + voQueryInfo, + voOpen, + voClose, + voSetVisibleRegion, + voVideoBufAlloc, + voVideoBufFree, + voUpdate +}; + + +static BOOL voQueryInfo(VIDEOOUTPUTINFO *pInfo) +{ + DIVE_CAPS sDiveCaps; + FOURCC fccFormats[100]; + + /* Query information about display hardware from DIVE. */ + SDL_zeroa(fccFormats); + SDL_zero(sDiveCaps); + sDiveCaps.pFormatData = fccFormats; + sDiveCaps.ulFormatLength = 100; + sDiveCaps.ulStructLen = sizeof(DIVE_CAPS); + + if (DiveQueryCaps(&sDiveCaps, DIVE_BUFFER_SCREEN)) { + debug_os2("DiveQueryCaps() failed."); + return FALSE; + } + + if (sDiveCaps.ulDepth < 8) { + debug_os2("Not enough screen colors to run DIVE. " + "Must be at least 256 colors."); + return FALSE; + } + + pInfo->ulBPP = sDiveCaps.ulDepth; + pInfo->fccColorEncoding = sDiveCaps.fccColorEncoding; + pInfo->ulScanLineSize = sDiveCaps.ulScanLineBytes; + pInfo->ulHorizResolution = sDiveCaps.ulHorizontalResolution; + pInfo->ulVertResolution = sDiveCaps.ulVerticalResolution; + + return TRUE; +} + +PVODATA voOpen(void) +{ + PVODATA pVOData = SDL_calloc(1, sizeof(VODATA)); + + if (!pVOData) { + SDL_OutOfMemory(); + return NULL; + } + + if (DiveOpen(&pVOData->hDive, FALSE, NULL) != DIVE_SUCCESS) { + SDL_free(pVOData); + SDL_SetError("DIVE: A display engine instance open failed"); + return NULL; + } + + return pVOData; +} + +static VOID voClose(PVODATA pVOData) +{ + voVideoBufFree(pVOData); + DiveClose(pVOData->hDive); + SDL_free(pVOData); +} + +static BOOL voSetVisibleRegion(PVODATA pVOData, HWND hwnd, + SDL_DisplayMode *pSDLDisplayMode, + HRGN hrgnShape, BOOL fVisible) +{ + HPS hps; + HRGN hrgn; + RGNRECT rgnCtl; + PRECTL prectl = NULL; + ULONG ulRC; + + if (!fVisible) { + if (pVOData->fBlitterReady) { + pVOData->fBlitterReady = FALSE; + DiveSetupBlitter(pVOData->hDive, 0); + debug_os2("DIVE blitter is tuned off"); + } + return TRUE; + } + + /* Query visible rectangles */ + hps = WinGetPS(hwnd); + hrgn = GpiCreateRegion(hps, 0, NULL); + if (hrgn == NULLHANDLE) { + WinReleasePS(hps); + SDL_SetError("GpiCreateRegion() failed"); + } else { + WinQueryVisibleRegion(hwnd, hrgn); + if (hrgnShape != NULLHANDLE) + GpiCombineRegion(hps, hrgn, hrgn, hrgnShape, CRGN_AND); + + rgnCtl.ircStart = 1; + rgnCtl.crc = 0; + rgnCtl.ulDirection = 1; + GpiQueryRegionRects(hps, hrgn, NULL, &rgnCtl, NULL); + if (rgnCtl.crcReturned != 0) { + prectl = SDL_malloc(rgnCtl.crcReturned * sizeof(RECTL)); + if (prectl != NULL) { + rgnCtl.ircStart = 1; + rgnCtl.crc = rgnCtl.crcReturned; + rgnCtl.ulDirection = 1; + GpiQueryRegionRects(hps, hrgn, NULL, &rgnCtl, prectl); + } else { + SDL_OutOfMemory(); + } + } + GpiDestroyRegion(hps, hrgn); + WinReleasePS(hps); + + if (prectl != NULL) { + /* Setup DIVE blitter. */ + SETUP_BLITTER sSetupBlitter; + SWP swp; + POINTL pointl = { 0,0 }; + + WinQueryWindowPos(hwnd, &swp); + WinMapWindowPoints(hwnd, HWND_DESKTOP, &pointl, 1); + + sSetupBlitter.ulStructLen = sizeof(SETUP_BLITTER); + sSetupBlitter.fccSrcColorFormat = pVOData->fccColorEncoding; + sSetupBlitter.fInvert = FALSE; + sSetupBlitter.ulSrcWidth = pVOData->ulWidth; + sSetupBlitter.ulSrcHeight = pVOData->ulHeight; + sSetupBlitter.ulSrcPosX = 0; + sSetupBlitter.ulSrcPosY = 0; + sSetupBlitter.ulDitherType = 0; + sSetupBlitter.fccDstColorFormat = FOURCC_SCRN; + sSetupBlitter.ulDstWidth = swp.cx; + sSetupBlitter.ulDstHeight = swp.cy; + sSetupBlitter.lDstPosX = 0; + sSetupBlitter.lDstPosY = 0; + sSetupBlitter.lScreenPosX = pointl.x; + sSetupBlitter.lScreenPosY = pointl.y; + + sSetupBlitter.ulNumDstRects = rgnCtl.crcReturned; + sSetupBlitter.pVisDstRects = prectl; + + ulRC = DiveSetupBlitter(pVOData->hDive, &sSetupBlitter); + SDL_free(prectl); + + if (ulRC == DIVE_SUCCESS) { + pVOData->fBlitterReady = TRUE; + WinInvalidateRect(hwnd, NULL, TRUE); + debug_os2("DIVE blitter is ready now."); + return TRUE; + } + + SDL_SetError("DiveSetupBlitter(), rc = 0x%X", ulRC); + } /* if (prectl != NULL) */ + } /* if (hrgn == NULLHANDLE) else */ + + pVOData->fBlitterReady = FALSE; + DiveSetupBlitter(pVOData->hDive, 0); + return FALSE; +} + +static PVOID voVideoBufAlloc(PVODATA pVOData, ULONG ulWidth, ULONG ulHeight, + ULONG ulBPP, FOURCC fccColorEncoding, + PULONG pulScanLineSize) +{ + ULONG ulRC; + ULONG ulScanLineSize = ulWidth * (ulBPP >> 3); + + /* Destroy previous buffer. */ + voVideoBufFree(pVOData); + + if (ulWidth == 0 || ulHeight == 0 || ulBPP == 0) + return NULL; + + /* Bytes per line. */ + ulScanLineSize = (ulScanLineSize + 3) & ~3; /* 4-byte aligning */ + *pulScanLineSize = ulScanLineSize; + + ulRC = DosAllocMem(&pVOData->pBuffer, + (ulHeight * ulScanLineSize) + sizeof(ULONG), + PAG_COMMIT | PAG_EXECUTE | PAG_READ | PAG_WRITE); + if (ulRC != NO_ERROR) { + debug_os2("DosAllocMem(), rc = %u", ulRC); + return NULL; + } + + ulRC = DiveAllocImageBuffer(pVOData->hDive, &pVOData->ulDIVEBufNum, + fccColorEncoding, ulWidth, ulHeight, + ulScanLineSize, pVOData->pBuffer); + if (ulRC != DIVE_SUCCESS) { + debug_os2("DiveAllocImageBuffer(), rc = 0x%X", ulRC); + DosFreeMem(pVOData->pBuffer); + pVOData->pBuffer = NULL; + pVOData->ulDIVEBufNum = 0; + return NULL; + } + + pVOData->fccColorEncoding = fccColorEncoding; + pVOData->ulWidth = ulWidth; + pVOData->ulHeight = ulHeight; + + debug_os2("buffer: 0x%P, DIVE buffer number: %u", + pVOData->pBuffer, pVOData->ulDIVEBufNum); + + return pVOData->pBuffer; +} + +static VOID voVideoBufFree(PVODATA pVOData) +{ + ULONG ulRC; + + if (pVOData->ulDIVEBufNum != 0) { + ulRC = DiveFreeImageBuffer(pVOData->hDive, pVOData->ulDIVEBufNum); + if (ulRC != DIVE_SUCCESS) { + debug_os2("DiveFreeImageBuffer(,%u), rc = %u", pVOData->ulDIVEBufNum, ulRC); + } else { + debug_os2("DIVE buffer %u destroyed", pVOData->ulDIVEBufNum); + } + pVOData->ulDIVEBufNum = 0; + } + + if (pVOData->pBuffer) { + ulRC = DosFreeMem(pVOData->pBuffer); + if (ulRC != NO_ERROR) { + debug_os2("DosFreeMem(), rc = %u", ulRC); + } + pVOData->pBuffer = NULL; + } +} + +static BOOL voUpdate(PVODATA pVOData, HWND hwnd, SDL_Rect *pSDLRects, + ULONG cSDLRects) +{ + ULONG ulRC; + + if (!pVOData->fBlitterReady || (pVOData->ulDIVEBufNum == 0)) { + debug_os2("DIVE blitter is not ready"); + return FALSE; + } + + if (pSDLRects) { + PBYTE pbLineMask; + + pbLineMask = SDL_stack_alloc(BYTE, pVOData->ulHeight); + if (!pbLineMask) { + debug_os2("Not enough stack size"); + return FALSE; + } + SDL_memset(pbLineMask, 0, pVOData->ulHeight); + + for ( ; ((LONG)cSDLRects) > 0; cSDLRects--, pSDLRects++) { + SDL_memset(&pbLineMask[pSDLRects->y], 1, pSDLRects->h); + } + + ulRC = DiveBlitImageLines(pVOData->hDive, pVOData->ulDIVEBufNum, + DIVE_BUFFER_SCREEN, pbLineMask); + SDL_stack_free(pbLineMask); + + if (ulRC != DIVE_SUCCESS) { + debug_os2("DiveBlitImageLines(), rc = 0x%X", ulRC); + } + } else { + ulRC = DiveBlitImage(pVOData->hDive, pVOData->ulDIVEBufNum, + DIVE_BUFFER_SCREEN); + if (ulRC != DIVE_SUCCESS) { + debug_os2("DiveBlitImage(), rc = 0x%X", ulRC); + } + } + + return ulRC == DIVE_SUCCESS; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/os2/SDL_os2messagebox.c b/SDL2-2.30.5/src/video/os2/SDL_os2messagebox.c new file mode 100644 index 0000000..e394635 --- /dev/null +++ b/SDL2-2.30.5/src/video/os2/SDL_os2messagebox.c @@ -0,0 +1,561 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_OS2 + +/* Display a OS/2 message box */ + +#include "SDL.h" +#include "../../core/os2/SDL_os2.h" +#include "SDL_os2video.h" +#define INCL_WIN +#include + +#define IDD_TEXT_MESSAGE 1001 +#define IDD_BITMAP 1002 +#define IDD_PB_FIRST 1003 + +typedef struct _MSGBOXDLGDATA { + USHORT cb; + HWND hwndUnder; +} MSGBOXDLGDATA; + +static VOID _wmInitDlg(HWND hwnd, MSGBOXDLGDATA *pDlgData) +{ + HPS hps = WinGetPS(hwnd); + POINTL aptText[TXTBOX_COUNT]; + HENUM hEnum; + HWND hWndNext; + CHAR acBuf[256]; + ULONG cbBuf; + ULONG cButtons = 0; + ULONG ulButtonsCY = 0; + ULONG ulButtonsCX = 0; + RECTL rectl; + ULONG ulX; + ULONG ulIdx; + struct _BUTTON { + HWND hwnd; /* Button window handle. */ + ULONG ulCX; /* Button width in dialog coordinates. */ + } aButtons[32]; + RECTL rectlItem; + HAB hab = WinQueryAnchorBlock(hwnd); + + /* --- Align the buttons to the right/bottom. --- */ + + /* Collect window handles of all buttons in dialog. */ + hEnum = WinBeginEnumWindows(hwnd); + + while ((hWndNext = WinGetNextWindow(hEnum)) != NULLHANDLE) { + if (WinQueryClassName(hWndNext, sizeof(acBuf), acBuf) == 0) { + continue; + } + if (SDL_strcmp(acBuf, "#3") == 0) { /* Class name of button. */ + if (cButtons < sizeof(aButtons) / sizeof(struct _BUTTON)) { + aButtons[cButtons].hwnd = hWndNext; + cButtons++; + } + } + } + WinEndEnumWindows(hEnum); + + /* Query size of text for each button, get width of each button, total + * buttons width (ulButtonsCX) and max. height (ulButtonsCX) in _dialog + * coordinates_. */ + hps = WinGetPS(hwnd); + + for(ulIdx = 0; ulIdx < cButtons; ulIdx++) { + /* Query size of text in window coordinates. */ + cbBuf = WinQueryWindowText(aButtons[ulIdx].hwnd, sizeof(acBuf), acBuf); + GpiQueryTextBox(hps, cbBuf, acBuf, TXTBOX_COUNT, aptText); + aptText[TXTBOX_TOPRIGHT].x -= aptText[TXTBOX_BOTTOMLEFT].x; + aptText[TXTBOX_TOPRIGHT].y -= aptText[TXTBOX_BOTTOMLEFT].y; + /* Convert text size to dialog coordinates. */ + WinMapDlgPoints(hwnd, &aptText[TXTBOX_TOPRIGHT], 1, FALSE); + /* Add vertical and horizontal space for button's frame (dialog coord.). */ + if (aptText[TXTBOX_TOPRIGHT].x < 30) { /* Minimal button width. */ + aptText[TXTBOX_TOPRIGHT].x = 30; + } else { + aptText[TXTBOX_TOPRIGHT].x += 4; + } + aptText[TXTBOX_TOPRIGHT].y += 3; + + aButtons[ulIdx].ulCX = aptText[TXTBOX_TOPRIGHT].x; /* Store button width */ + ulButtonsCX += aptText[TXTBOX_TOPRIGHT].x + 2; /* Add total btn. width */ + /* Get max. height for buttons. */ + if (ulButtonsCY < aptText[TXTBOX_TOPRIGHT].y) + ulButtonsCY = aptText[TXTBOX_TOPRIGHT].y + 1; + } + + WinReleasePS(hps); + + /* Expand horizontal size of the window to fit all buttons and move window + * to the center of parent window. */ + + /* Convert total width of buttons to window coordinates. */ + aptText[0].x = ulButtonsCX + 4; + WinMapDlgPoints(hwnd, &aptText[0], 1, TRUE); + /* Check width of the window and expand as needed. */ + WinQueryWindowRect(hwnd, &rectlItem); + if (rectlItem.xRight <= aptText[0].x) + rectlItem.xRight = aptText[0].x; + + /* Move window rectangle to the center of owner window. */ + WinQueryWindowRect(pDlgData->hwndUnder, &rectl); + /* Left-bottom point of centered dialog on owner window. */ + rectl.xLeft = (rectl.xRight - rectlItem.xRight) / 2; + rectl.yBottom = (rectl.yTop - rectlItem.yTop) / 2; + /* Map left-bottom point to desktop. */ + WinMapWindowPoints(pDlgData->hwndUnder, HWND_DESKTOP, (PPOINTL)&rectl, 1); + WinOffsetRect(hab, &rectlItem, rectl.xLeft, rectl.yBottom); + + /* Set new rectangle for the window. */ + WinSetWindowPos(hwnd, HWND_TOP, rectlItem.xLeft, rectlItem.yBottom, + rectlItem.xRight - rectlItem.xLeft, + rectlItem.yTop - rectlItem.yBottom, + SWP_SIZE | SWP_MOVE); + + /* Set buttons positions. */ + + /* Get horizontal position for the first button. */ + WinMapDlgPoints(hwnd, (PPOINTL)&rectlItem, 2, FALSE); /* Win size to dlg coord. */ + ulX = rectlItem.xRight - rectlItem.xLeft - ulButtonsCX - 2; /* First button position. */ + + /* Set positions and sizes for all buttons. */ + for (ulIdx = 0; ulIdx < cButtons; ulIdx++) { + /* Get poisition and size for the button in dialog coordinates. */ + aptText[0].x = ulX; + aptText[0].y = 2; + aptText[1].x = aButtons[ulIdx].ulCX; + aptText[1].y = ulButtonsCY; + /* Convert to window coordinates. */ + WinMapDlgPoints(hwnd, aptText, 2, TRUE); + + WinSetWindowPos(aButtons[ulIdx].hwnd, HWND_TOP, + aptText[0].x, aptText[0].y, aptText[1].x, aptText[1].y, + SWP_MOVE | SWP_SIZE); + + /* Offset horizontal position for the next button. */ + ulX += aButtons[ulIdx].ulCX + 2; + } + + /* Set right bound of the text to right bound of the last button and + * bottom bound of the text just above the buttons. */ + + aptText[2].x = 25; /* Left bound of text in dlg coordinates. */ + aptText[2].y = ulButtonsCY + 3; /* Bottom bound of the text in dlg coords. */ + WinMapDlgPoints(hwnd, &aptText[2], 1, TRUE); /* Convert ^^^ to win. coords */ + hWndNext = WinWindowFromID(hwnd, IDD_TEXT_MESSAGE); + WinQueryWindowRect(hWndNext, &rectlItem); + rectlItem.xLeft = aptText[2].x; + rectlItem.yBottom = aptText[2].y; + /* Right bound of the text equals right bound of the last button. */ + rectlItem.xRight = aptText[0].x + aptText[1].x; + WinSetWindowPos(hWndNext, HWND_TOP, rectlItem.xLeft, rectlItem.yBottom, + rectlItem.xRight - rectlItem.xLeft, + rectlItem.yTop - rectlItem.yBottom, + SWP_MOVE | SWP_SIZE); +} + +static MRESULT EXPENTRY DynDlgProc(HWND hwnd, USHORT message, MPARAM mp1, MPARAM mp2) +{ + switch (message) { + case WM_INITDLG: + _wmInitDlg(hwnd, (MSGBOXDLGDATA*)mp2); + break; + + case WM_COMMAND: + switch (SHORT1FROMMP(mp1)) { + case DID_OK: + WinDismissDlg(hwnd, FALSE); + break; + default: + break; + } + + default: + return(WinDefDlgProc(hwnd, message, mp1, mp2)); + } + + return FALSE; +} + +static HWND _makeDlg(const SDL_MessageBoxData *messageboxdata) +{ + SDL_MessageBoxButtonData* + pSDLBtnData = (SDL_MessageBoxButtonData *)messageboxdata->buttons; + ULONG cSDLBtnData = messageboxdata->numbuttons; + + PSZ pszTitle = OS2_UTF8ToSys(messageboxdata->title); + ULONG cbTitle = (!pszTitle)? 1 : (SDL_strlen(pszTitle) + 1); + PSZ pszText = OS2_UTF8ToSys(messageboxdata->message); + ULONG cbText = (!pszText)? 1 : (SDL_strlen(pszText) + 1); + + PDLGTEMPLATE pTemplate; + ULONG cbTemplate; + ULONG ulIdx; + PCHAR pcDlgData; + PDLGTITEM pDlgItem; + PSZ pszBtnText; + ULONG cbBtnText; + HWND hwnd; + + const SDL_MessageBoxColor* pSDLColors = (!messageboxdata->colorScheme)? + NULL : messageboxdata->colorScheme->colors; + const SDL_MessageBoxColor* pSDLColor; + + MSGBOXDLGDATA stDlgData; + + /* Build a dialog tamplate in memory */ + + /* Size of template */ + cbTemplate = sizeof(DLGTEMPLATE) + ((2 + cSDLBtnData) * sizeof(DLGTITEM)) + + sizeof(ULONG) + /* First item data - frame control data. */ + cbTitle + /* First item data - frame title + ZERO. */ + cbText + /* Second item data - ststic text + ZERO.*/ + 3; /* Third item data - system icon Id. */ + + /* Button items datas - text for buttons. */ + for (ulIdx = 0; ulIdx < cSDLBtnData; ulIdx++) { + pszBtnText = (PSZ)pSDLBtnData[ulIdx].text; + cbTemplate += (!pszBtnText)? 1 : (SDL_strlen(pszBtnText) + 1); + } + + /* Presentation parameter space. */ + if (pSDLColors) { + cbTemplate += 26 /* PP for frame. */ + + 26 /* PP for static text. */ + + (48 * cSDLBtnData); /* PP for buttons. */ + } + + /* Allocate memory for the dialog template. */ + pTemplate = (PDLGTEMPLATE) SDL_malloc(cbTemplate); + /* Pointer on data for dialog items in allocated memory. */ + pcDlgData = &((PCHAR)pTemplate)[sizeof(DLGTEMPLATE) + + ((2 + cSDLBtnData) * sizeof(DLGTITEM))]; + + /* Header info */ + pTemplate->cbTemplate = cbTemplate; /* size of dialog template to pass to WinCreateDlg() */ + pTemplate->type = 0; /* Currently always 0. */ + pTemplate->codepage = 0; + pTemplate->offadlgti = 14; /* Offset to array of DLGTITEMs. */ + pTemplate->fsTemplateStatus = 0; /* Reserved field? */ + + /* Index in array of dlg items of item to get focus, */ + /* if 0 then focus goes to first control that can have focus. */ + pTemplate->iItemFocus = 0; + pTemplate->coffPresParams = 0; + + /* First item info - frame */ + pDlgItem = pTemplate->adlgti; + pDlgItem->fsItemStatus = 0; /* Reserved? */ + /* Number of dialog item child windows owned by this item. */ + pDlgItem->cChildren = 2 + cSDLBtnData; /* Ststic text + buttons. */ + /* Length of class name, if 0 then offClassname contains a WC_ value. */ + pDlgItem->cchClassName = 0; + pDlgItem->offClassName = (USHORT)WC_FRAME; + /* Length of text. */ + pDlgItem->cchText = cbTitle; + pDlgItem->offText = pcDlgData - (PCHAR)pTemplate; /* Offset to title text. */ + /* Copy text for the title into the dialog template. */ + if (pszTitle != NULL) { + SDL_memcpy(pcDlgData, pszTitle, cbTitle); + } else { + *pcDlgData = '\0'; + } + pcDlgData += pDlgItem->cchText; + + pDlgItem->flStyle = WS_GROUP | WS_VISIBLE | WS_CLIPSIBLINGS | + FS_DLGBORDER | WS_SAVEBITS; + pDlgItem->x = 100; + pDlgItem->y = 100; + pDlgItem->cx = 175; + pDlgItem->cy = 65; + pDlgItem->id = DID_OK; /* An ID value? */ + if (!pSDLColors) + pDlgItem->offPresParams = 0; + else { + /* Presentation parameter for the frame - dialog colors. */ + pDlgItem->offPresParams = pcDlgData - (PCHAR)pTemplate; + ((PPRESPARAMS)pcDlgData)->cb = 22; + pcDlgData += 4; + ((PPARAM)pcDlgData)->id = PP_FOREGROUNDCOLOR; + ((PPARAM)pcDlgData)->cb = 3; + ((PPARAM)pcDlgData)->ab[0] = pSDLColors[SDL_MESSAGEBOX_COLOR_TEXT].b; + ((PPARAM)pcDlgData)->ab[1] = pSDLColors[SDL_MESSAGEBOX_COLOR_TEXT].g; + ((PPARAM)pcDlgData)->ab[2] = pSDLColors[SDL_MESSAGEBOX_COLOR_TEXT].r; + pcDlgData += 11; + ((PPARAM)pcDlgData)->id = PP_BACKGROUNDCOLOR; + ((PPARAM)pcDlgData)->cb = 3; + ((PPARAM)pcDlgData)->ab[0] = pSDLColors[SDL_MESSAGEBOX_COLOR_BACKGROUND].b; + ((PPARAM)pcDlgData)->ab[1] = pSDLColors[SDL_MESSAGEBOX_COLOR_BACKGROUND].g; + ((PPARAM)pcDlgData)->ab[2] = pSDLColors[SDL_MESSAGEBOX_COLOR_BACKGROUND].r; + pcDlgData += 11; + } + + /* Offset to ctl data. */ + pDlgItem->offCtlData = pcDlgData - (PCHAR)pTemplate; + /* Put CtlData for the dialog in here */ + *((PULONG)pcDlgData) = FCF_TITLEBAR | FCF_SYSMENU; + pcDlgData += sizeof(ULONG); + + /* Second item info - static text (message). */ + pDlgItem++; + pDlgItem->fsItemStatus = 0; + /* No children since its a control, it could have child control */ + /* (ex. a group box). */ + pDlgItem->cChildren = 0; + /* Length of class name, 0 - offClassname contains a WC_ constant. */ + pDlgItem->cchClassName = 0; + pDlgItem->offClassName = (USHORT)WC_STATIC; + + pDlgItem->cchText = cbText; + pDlgItem->offText = pcDlgData - (PCHAR)pTemplate; /* Offset to the text. */ + /* Copy message text into the dialog template. */ + if (pszText != NULL) { + SDL_memcpy(pcDlgData, pszText, cbText); + } else { + *pcDlgData = '\0'; + } + pcDlgData += pDlgItem->cchText; + + pDlgItem->flStyle = SS_TEXT | DT_TOP | DT_LEFT | DT_WORDBREAK | WS_VISIBLE; + /* It will be really set in _wmInitDlg(). */ + pDlgItem->x = 25; + pDlgItem->y = 13; + pDlgItem->cx = 147; + pDlgItem->cy = 62; /* It will be used. */ + + pDlgItem->id = IDD_TEXT_MESSAGE; /* an ID value */ + if (!pSDLColors) + pDlgItem->offPresParams = 0; + else { + /* Presentation parameter for the static text - dialog colors. */ + pDlgItem->offPresParams = pcDlgData - (PCHAR)pTemplate; + ((PPRESPARAMS)pcDlgData)->cb = 22; + pcDlgData += 4; + ((PPARAM)pcDlgData)->id = PP_FOREGROUNDCOLOR; + ((PPARAM)pcDlgData)->cb = 3; + ((PPARAM)pcDlgData)->ab[0] = pSDLColors[SDL_MESSAGEBOX_COLOR_TEXT].b; + ((PPARAM)pcDlgData)->ab[1] = pSDLColors[SDL_MESSAGEBOX_COLOR_TEXT].g; + ((PPARAM)pcDlgData)->ab[2] = pSDLColors[SDL_MESSAGEBOX_COLOR_TEXT].r; + pcDlgData += 11; + ((PPARAM)pcDlgData)->id = PP_BACKGROUNDCOLOR; + ((PPARAM)pcDlgData)->cb = 3; + ((PPARAM)pcDlgData)->ab[0] = pSDLColors[SDL_MESSAGEBOX_COLOR_BACKGROUND].b; + ((PPARAM)pcDlgData)->ab[1] = pSDLColors[SDL_MESSAGEBOX_COLOR_BACKGROUND].g; + ((PPARAM)pcDlgData)->ab[2] = pSDLColors[SDL_MESSAGEBOX_COLOR_BACKGROUND].r; + pcDlgData += 11; + } + pDlgItem->offCtlData = 0; + + /* Third item info - static bitmap. */ + pDlgItem++; + pDlgItem->fsItemStatus = 0; + pDlgItem->cChildren = 0; + pDlgItem->cchClassName = 0; + pDlgItem->offClassName = (USHORT)WC_STATIC; + + pDlgItem->cchText = 3; /* 0xFF, low byte of the icon Id, high byte of icon Id. */ + pDlgItem->offText = pcDlgData - (PCHAR)pTemplate; /* Offset to the Id. */ + /* Write system icon ID into dialog template. */ + *((PBYTE)pcDlgData) = 0xFF; /* First byte is 0xFF, next 2 are system pointer Id. */ + pcDlgData++; + *((PUSHORT)pcDlgData) = ((messageboxdata->flags & SDL_MESSAGEBOX_ERROR) != 0)? + SPTR_ICONERROR : + ((messageboxdata->flags & SDL_MESSAGEBOX_WARNING) != 0)? + SPTR_ICONWARNING : SPTR_ICONINFORMATION; + pcDlgData += 2; + + pDlgItem->flStyle = SS_SYSICON | WS_VISIBLE; + + pDlgItem->x = 4; + pDlgItem->y = 45; /* It will be really set in _wmInitDlg(). */ + pDlgItem->cx = 0; + pDlgItem->cy = 0; + + pDlgItem->id = IDD_BITMAP; + pDlgItem->offPresParams = 0; + pDlgItem->offCtlData = 0; + + /* Next items - buttons. */ + for (ulIdx = 0; ulIdx < cSDLBtnData; ulIdx++) { + pDlgItem++; + + pDlgItem->fsItemStatus = 0; + pDlgItem->cChildren = 0; /* No children. */ + pDlgItem->cchClassName = 0; /* 0 - offClassname is WC_ constant. */ + pDlgItem->offClassName = (USHORT)WC_BUTTON; + + pszBtnText = OS2_UTF8ToSys(pSDLBtnData[ulIdx].text); + cbBtnText = (!pszBtnText)? 1 : (SDL_strlen(pszBtnText) + 1); + pDlgItem->cchText = cbBtnText; + pDlgItem->offText = pcDlgData - (PCHAR)pTemplate; /* Offset to the text. */ + /* Copy text for the button into the dialog template. */ + if (pszBtnText != NULL) { + SDL_memcpy(pcDlgData, pszBtnText, cbBtnText); + } else { + *pcDlgData = '\0'; + } + pcDlgData += pDlgItem->cchText; + SDL_free(pszBtnText); + + pDlgItem->flStyle = BS_PUSHBUTTON | WS_TABSTOP | WS_VISIBLE; + if (pSDLBtnData[ulIdx].flags == SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT) { + pDlgItem->flStyle |= BS_DEFAULT; + pTemplate->iItemFocus = ulIdx + 3; /* +3 - frame, static text and icon. */ + pSDLColor = &pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED]; + } else { + pSDLColor = &pSDLColors[SDL_MESSAGEBOX_COLOR_TEXT]; + } + + /* It will be really set in _wmInitDlg() */ + pDlgItem->x = 10; + pDlgItem->y = 10; + pDlgItem->cx = 70; + pDlgItem->cy = 15; + + pDlgItem->id = IDD_PB_FIRST + ulIdx; /* an ID value */ + if (!pSDLColors) + pDlgItem->offPresParams = 0; + else { + /* Presentation parameter for the button - dialog colors. */ + pDlgItem->offPresParams = pcDlgData - (PCHAR)pTemplate; + ((PPRESPARAMS)pcDlgData)->cb = 44; + pcDlgData += 4; + ((PPARAM)pcDlgData)->id = PP_FOREGROUNDCOLOR; + ((PPARAM)pcDlgData)->cb = 3; + ((PPARAM)pcDlgData)->ab[0] = pSDLColor->b; + ((PPARAM)pcDlgData)->ab[1] = pSDLColor->g; + ((PPARAM)pcDlgData)->ab[2] = pSDLColor->r; + pcDlgData += 11; + ((PPARAM)pcDlgData)->id = PP_BACKGROUNDCOLOR; + ((PPARAM)pcDlgData)->cb = 3; + ((PPARAM)pcDlgData)->ab[0] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND].b; + ((PPARAM)pcDlgData)->ab[1] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND].g; + ((PPARAM)pcDlgData)->ab[2] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND].r; + pcDlgData += 11; + ((PPARAM)pcDlgData)->id = PP_BORDERLIGHTCOLOR; + ((PPARAM)pcDlgData)->cb = 3; + ((PPARAM)pcDlgData)->ab[0] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BORDER].b; + ((PPARAM)pcDlgData)->ab[1] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BORDER].g; + ((PPARAM)pcDlgData)->ab[2] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BORDER].r; + pcDlgData += 11; + ((PPARAM)pcDlgData)->id = PP_BORDERDARKCOLOR; + ((PPARAM)pcDlgData)->cb = 3; + ((PPARAM)pcDlgData)->ab[0] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BORDER].b; + ((PPARAM)pcDlgData)->ab[1] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BORDER].g; + ((PPARAM)pcDlgData)->ab[2] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BORDER].r; + pcDlgData += 11; + } + pDlgItem->offCtlData = 0; + } + /* Check, end of templ. data: &((PCHAR)pTemplate)[cbTemplate] == pcDlgData */ + + /* Create the dialog from template. */ + stDlgData.cb = sizeof(MSGBOXDLGDATA); + stDlgData.hwndUnder = (messageboxdata->window && messageboxdata->window->driverdata)? + ((WINDATA *)messageboxdata->window->driverdata)->hwnd : HWND_DESKTOP; + + hwnd = WinCreateDlg(HWND_DESKTOP, /* Parent is desktop. */ + stDlgData.hwndUnder, + (PFNWP)DynDlgProc, pTemplate, &stDlgData); + SDL_free(pTemplate); + SDL_free(pszTitle); + SDL_free(pszText); + + return hwnd; +} + + +int OS2_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) +{ + HWND hwnd; + ULONG ulRC; + SDL_MessageBoxButtonData + *pSDLBtnData = (SDL_MessageBoxButtonData *)messageboxdata->buttons; + ULONG cSDLBtnData = messageboxdata->numbuttons; + BOOL fVideoInitialized = SDL_WasInit(SDL_INIT_VIDEO); + HAB hab; + HMQ hmq; + BOOL fSuccess = FALSE; + + if (!fVideoInitialized) { + PTIB tib; + PPIB pib; + + DosGetInfoBlocks(&tib, &pib); + if (pib->pib_ultype == 2 || pib->pib_ultype == 0) { + /* VIO windowable or fullscreen protect-mode session */ + pib->pib_ultype = 3; /* Presentation Manager protect-mode session */ + } + + hab = WinInitialize(0); + if (hab == NULLHANDLE) { + debug_os2("WinInitialize() failed"); + return -1; + } + hmq = WinCreateMsgQueue(hab, 0); + if (hmq == NULLHANDLE) { + debug_os2("WinCreateMsgQueue() failed"); + return -1; + } + } + + /* Create dynamic dialog. */ + hwnd = _makeDlg(messageboxdata); + /* Show dialog and obtain button Id. */ + ulRC = WinProcessDlg(hwnd); + /* Destroy dialog, */ + WinDestroyWindow(hwnd); + + if (ulRC == DID_CANCEL) { + /* Window closed by ESC, Alt+F4 or system menu. */ + ULONG ulIdx; + + for (ulIdx = 0; ulIdx < cSDLBtnData; ulIdx++, pSDLBtnData++) { + if (pSDLBtnData->flags == SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT) { + *buttonid = pSDLBtnData->buttonid; + fSuccess = TRUE; + break; + } + } + } else { + /* Button pressed. */ + ulRC -= IDD_PB_FIRST; + if (ulRC < cSDLBtnData) { + *buttonid = pSDLBtnData[ulRC].buttonid; + fSuccess = TRUE; + } + } + + if (!fVideoInitialized) { + WinDestroyMsgQueue(hmq); + WinTerminate(hab); + } + + return (fSuccess)? 0 : -1; +} + +#endif /* SDL_VIDEO_DRIVER_OS2 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/os2/SDL_os2messagebox.h b/SDL2-2.30.5/src/video/os2/SDL_os2messagebox.h new file mode 100644 index 0000000..453d035 --- /dev/null +++ b/SDL2-2.30.5/src/video/os2/SDL_os2messagebox.h @@ -0,0 +1,29 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_OS2 + +extern int OS2_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid); + +#endif /* SDL_VIDEO_DRIVER_OS2 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/os2/SDL_os2mouse.c b/SDL2-2.30.5/src/video/os2/SDL_os2mouse.c new file mode 100644 index 0000000..220766a --- /dev/null +++ b/SDL2-2.30.5/src/video/os2/SDL_os2mouse.c @@ -0,0 +1,194 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_OS2 + +#include "SDL_os2video.h" +#include "../../events/SDL_mouse_c.h" +#include "SDL_os2util.h" + +HPOINTER hptrCursor = NULLHANDLE; + +static SDL_Cursor* OS2_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y) +{ + ULONG ulMaxW = WinQuerySysValue(HWND_DESKTOP, SV_CXPOINTER); + ULONG ulMaxH = WinQuerySysValue(HWND_DESKTOP, SV_CYPOINTER); + HPOINTER hptr; + SDL_Cursor* pSDLCursor; + + if (surface->w > ulMaxW || surface->h > ulMaxH) { + debug_os2("Given image size is %u x %u, maximum allowed size is %u x %u", + surface->w, surface->h, ulMaxW, ulMaxH); + return NULL; + } + + hptr = utilCreatePointer(surface, hot_x, ulMaxH - hot_y - 1); + if (hptr == NULLHANDLE) + return NULL; + + pSDLCursor = SDL_calloc(1, sizeof(SDL_Cursor)); + if (!pSDLCursor) { + WinDestroyPointer(hptr); + SDL_OutOfMemory(); + return NULL; + } + + pSDLCursor->driverdata = (void *)hptr; + return pSDLCursor; +} + +static SDL_Cursor* OS2_CreateSystemCursor(SDL_SystemCursor id) +{ + SDL_Cursor* pSDLCursor; + LONG lSysId; + HPOINTER hptr; + + switch (id) { + case SDL_SYSTEM_CURSOR_ARROW: lSysId = SPTR_ARROW; break; + case SDL_SYSTEM_CURSOR_IBEAM: lSysId = SPTR_TEXT; break; + case SDL_SYSTEM_CURSOR_WAIT: lSysId = SPTR_WAIT; break; + case SDL_SYSTEM_CURSOR_CROSSHAIR: lSysId = SPTR_MOVE; break; + case SDL_SYSTEM_CURSOR_WAITARROW: lSysId = SPTR_WAIT; break; + case SDL_SYSTEM_CURSOR_SIZENWSE: lSysId = SPTR_SIZENWSE; break; + case SDL_SYSTEM_CURSOR_SIZENESW: lSysId = SPTR_SIZENESW; break; + case SDL_SYSTEM_CURSOR_SIZEWE: lSysId = SPTR_SIZEWE; break; + case SDL_SYSTEM_CURSOR_SIZENS: lSysId = SPTR_SIZENS; break; + case SDL_SYSTEM_CURSOR_SIZEALL: lSysId = SPTR_MOVE; break; + case SDL_SYSTEM_CURSOR_NO: lSysId = SPTR_ILLEGAL; break; + case SDL_SYSTEM_CURSOR_HAND: lSysId = SPTR_ARROW; break; + default: + debug_os2("Unknown cursor id: %u", id); + return NULL; + } + + /* On eCS SPTR_WAIT for last paramether fCopy=TRUE/FALSE gives different + * "wait" icons. -=8( ) */ + hptr = WinQuerySysPointer(HWND_DESKTOP, lSysId, + id == SDL_SYSTEM_CURSOR_WAIT); + if (hptr == NULLHANDLE) { + debug_os2("Cannot load OS/2 system pointer %u for SDL cursor id %u", + lSysId, id); + return NULL; + } + + pSDLCursor = SDL_calloc(1, sizeof(SDL_Cursor)); + if (!pSDLCursor) { + WinDestroyPointer(hptr); + SDL_OutOfMemory(); + return NULL; + } + + pSDLCursor->driverdata = (void *)hptr; + return pSDLCursor; +} + +static void OS2_FreeCursor(SDL_Cursor *cursor) +{ + HPOINTER hptr = (HPOINTER)cursor->driverdata; + + WinDestroyPointer(hptr); + SDL_free(cursor); +} + +static int OS2_ShowCursor(SDL_Cursor *cursor) +{ + hptrCursor = (cursor)? (HPOINTER)cursor->driverdata : NULLHANDLE; + return ((SDL_GetMouseFocus() == NULL) || + WinSetPointer(HWND_DESKTOP, hptrCursor))? 0 : -1; +} + +static void OS2_WarpMouse(SDL_Window * window, int x, int y) +{ + WINDATA *pWinData = (WINDATA *)window->driverdata; + POINTL pointl; + + pointl.x = x; + pointl.y = window->h - y - 1; + WinMapWindowPoints(pWinData->hwnd, HWND_DESKTOP, &pointl, 1); + WinSetPointerPos(HWND_DESKTOP, pointl.x, pointl.y); + SDL_SendMouseMotion(window, SDL_GetMouse()->mouseID, 0, x, y); +} + +static int OS2_WarpMouseGlobal(int x, int y) +{ + WinSetPointerPos(HWND_DESKTOP, x, + WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN) - y); + return 0; +} + +static int OS2_CaptureMouse(SDL_Window *window) +{ + return WinSetCapture(HWND_DESKTOP, (!window)? NULLHANDLE : + ((WINDATA *)window->driverdata)->hwnd)? 0 : -1; +} + +static Uint32 OS2_GetGlobalMouseState(int *x, int *y) +{ + POINTL pointl; + ULONG ulRes; + + WinQueryPointerPos(HWND_DESKTOP, &pointl); + *x = pointl.x; + *y = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN) - pointl.y - 1; + + ulRes = (WinGetKeyState(HWND_DESKTOP, VK_BUTTON1) & 0x8000)? SDL_BUTTON_LMASK : 0; + if (WinGetKeyState(HWND_DESKTOP, VK_BUTTON2) & 0x8000) + ulRes |= SDL_BUTTON_RMASK; + if (WinGetKeyState(HWND_DESKTOP, VK_BUTTON3) & 0x8000) + ulRes |= SDL_BUTTON_MMASK; + + return ulRes; +} + + +void OS2_InitMouse(_THIS, ULONG hab) +{ + SDL_Mouse *pSDLMouse = SDL_GetMouse(); + + pSDLMouse->CreateCursor = OS2_CreateCursor; + pSDLMouse->CreateSystemCursor = OS2_CreateSystemCursor; + pSDLMouse->ShowCursor = OS2_ShowCursor; + pSDLMouse->FreeCursor = OS2_FreeCursor; + pSDLMouse->WarpMouse = OS2_WarpMouse; + pSDLMouse->WarpMouseGlobal = OS2_WarpMouseGlobal; + pSDLMouse->CaptureMouse = OS2_CaptureMouse; + pSDLMouse->GetGlobalMouseState = OS2_GetGlobalMouseState; + + SDL_SetDefaultCursor(OS2_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW)); + if (hptrCursor == NULLHANDLE) + hptrCursor = WinQuerySysPointer(HWND_DESKTOP, SPTR_ARROW, TRUE); +} + +void OS2_QuitMouse(_THIS) +{ + SDL_Mouse *pSDLMouse = SDL_GetMouse(); + + if (pSDLMouse->def_cursor) { + SDL_free(pSDLMouse->def_cursor); + pSDLMouse->def_cursor = NULL; + pSDLMouse->cur_cursor = NULL; + } +} + +#endif /* SDL_VIDEO_DRIVER_OS2 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/os2/SDL_os2mouse.h b/SDL2-2.30.5/src/video/os2/SDL_os2mouse.h new file mode 100644 index 0000000..ccd99da --- /dev/null +++ b/SDL2-2.30.5/src/video/os2/SDL_os2mouse.h @@ -0,0 +1,33 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifndef SDL_os2mouse_h_ +#define SDL_os2mouse_h_ + +extern HPOINTER hptrCursor; + +extern void OS2_InitMouse(_THIS, ULONG hab); +extern void OS2_QuitMouse(_THIS); + +#endif /* SDL_os2mouse_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/os2/SDL_os2output.h b/SDL2-2.30.5/src/video/os2/SDL_os2output.h new file mode 100644 index 0000000..7115ab7 --- /dev/null +++ b/SDL2-2.30.5/src/video/os2/SDL_os2output.h @@ -0,0 +1,59 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ +#ifndef SDL_os2output_ +#define SDL_os2output_ + +#include "../../core/os2/SDL_os2.h" + +typedef struct _VODATA *PVODATA; + +typedef struct _VIDEOOUTPUTINFO { + ULONG ulBPP; + ULONG fccColorEncoding; + ULONG ulScanLineSize; + ULONG ulHorizResolution; + ULONG ulVertResolution; +} VIDEOOUTPUTINFO; + +typedef struct _OS2VIDEOOUTPUT { + BOOL (*QueryInfo)(VIDEOOUTPUTINFO *pInfo); + PVODATA (*Open)(); + VOID (*Close)(PVODATA pVOData); + + BOOL (*SetVisibleRegion)(PVODATA pVOData, HWND hwnd, + SDL_DisplayMode *pSDLDisplayMode, HRGN hrgnShape, + BOOL fVisible); + + PVOID (*VideoBufAlloc)(PVODATA pVOData, ULONG ulWidth, ULONG ulHeight, + ULONG ulBPP, ULONG fccColorEncoding, + PULONG pulScanLineSize); + + VOID (*VideoBufFree)(PVODATA pVOData); + BOOL (*Update)(PVODATA pVOData, HWND hwnd, SDL_Rect *pSDLRects, + ULONG cSDLRects); +} OS2VIDEOOUTPUT; + +extern OS2VIDEOOUTPUT voDive; +extern OS2VIDEOOUTPUT voVMan; + +#endif /* SDL_os2output_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/os2/SDL_os2util.c b/SDL2-2.30.5/src/video/os2/SDL_os2util.c new file mode 100644 index 0000000..44450b6 --- /dev/null +++ b/SDL2-2.30.5/src/video/os2/SDL_os2util.c @@ -0,0 +1,114 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_OS2 + +#include "SDL_os2util.h" + +HPOINTER utilCreatePointer(SDL_Surface *surface, ULONG ulHotX, ULONG ulHotY) +{ + HBITMAP hbm; + BITMAPINFOHEADER2 bmih; + BITMAPINFO bmi; + HPS hps; + PULONG pulBitmap; + PULONG pulDst, pulSrc, pulDstMask; + ULONG ulY, ulX; + HPOINTER hptr = NULLHANDLE; + + if (surface->format->format != SDL_PIXELFORMAT_ARGB8888) { + debug_os2("Image format should be SDL_PIXELFORMAT_ARGB8888"); + return NULLHANDLE; + } + + pulBitmap = (PULONG) SDL_malloc(surface->h * surface->w * 2 * sizeof(ULONG)); + if (!pulBitmap) { + SDL_OutOfMemory(); + return NULLHANDLE; + } + + /* pulDst - last line of surface (image) part of the result bitmap */ + pulDst = &pulBitmap[ (surface->h - 1) * surface->w ]; + /* pulDstMask - last line of mask part of the result bitmap */ + pulDstMask = &pulBitmap[ (2 * surface->h - 1) * surface->w ]; + /* pulSrc - first line of source image */ + pulSrc = (PULONG)surface->pixels; + + for (ulY = 0; ulY < surface->h; ulY++) { + for (ulX = 0; ulX < surface->w; ulX++) { + if ((pulSrc[ulX] & 0xFF000000) == 0) { + pulDst[ulX] = 0; + pulDstMask[ulX] = 0xFFFFFFFF; + } else { + pulDst[ulX] = pulSrc[ulX] & 0xFFFFFF; + pulDstMask[ulX] = 0; + } + } + + /* Set image and mask pointers on one line up */ + pulDst -= surface->w; + pulDstMask -= surface->w; + /* Set source image pointer to the next line */ + pulSrc = (PULONG) (((PCHAR)pulSrc) + surface->pitch); + } + + /* Create system bitmap object. */ + SDL_zero(bmih); + SDL_zero(bmi); + + bmih.cbFix = sizeof(BITMAPINFOHEADER2); + bmih.cx = surface->w; + bmih.cy = 2 * surface->h; + bmih.cPlanes = 1; + bmih.cBitCount = 32; + bmih.ulCompression = BCA_UNCOMP; + bmih.cbImage = bmih.cx * bmih.cy * 4; + + bmi.cbFix = sizeof(BITMAPINFOHEADER); + bmi.cx = bmih.cx; + bmi.cy = bmih.cy; + bmi.cPlanes = 1; + bmi.cBitCount = 32; + + hps = WinGetPS(HWND_DESKTOP); + hbm = GpiCreateBitmap(hps, (PBITMAPINFOHEADER2)&bmih, CBM_INIT, + (PBYTE)pulBitmap, (PBITMAPINFO2)&bmi); + if (hbm == GPI_ERROR) { + debug_os2("GpiCreateBitmap() failed"); + } else { + /* Create a system pointer object. */ + hptr = WinCreatePointer(HWND_DESKTOP, hbm, TRUE, ulHotX, ulHotY); + if (hptr == NULLHANDLE) { + debug_os2("WinCreatePointer() failed"); + } + } + GpiDeleteBitmap(hbm); + + WinReleasePS(hps); + SDL_free(pulBitmap); + + return hptr; +} + +#endif /* SDL_VIDEO_DRIVER_OS2 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/os2/SDL_os2util.h b/SDL2-2.30.5/src/video/os2/SDL_os2util.h new file mode 100644 index 0000000..5def7b6 --- /dev/null +++ b/SDL2-2.30.5/src/video/os2/SDL_os2util.h @@ -0,0 +1,38 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#ifndef SDL_os2util_h_ +#define SDL_os2util_h_ + +#include "SDL_log.h" +#include "../SDL_sysvideo.h" +#include "../../core/os2/SDL_os2.h" + +#define INCL_WIN +#define INCL_GPI +#include + +HPOINTER utilCreatePointer(SDL_Surface *surface, ULONG ulHotX, ULONG ulHotY); + +#endif /* SDL_os2util_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ + diff --git a/SDL2-2.30.5/src/video/os2/SDL_os2video.c b/SDL2-2.30.5/src/video/os2/SDL_os2video.c new file mode 100644 index 0000000..8da1f4f --- /dev/null +++ b/SDL2-2.30.5/src/video/os2/SDL_os2video.c @@ -0,0 +1,1699 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_OS2 + +#include "SDL_video.h" +#include "SDL_mouse.h" +#include "../SDL_pixels_c.h" +#include "../SDL_shape_internals.h" +#include "../../events/SDL_events_c.h" +#include "SDL_os2video.h" +#include "SDL_syswm.h" +#include "SDL_os2util.h" +#include "SDL_os2messagebox.h" + +#define __MEERROR_H__ +#define _MEERROR_H_ +#include +#include +#ifndef FOURCC_R666 +#define FOURCC_R666 mmioFOURCC('R','6','6','6') +#endif + +#define WIN_CLIENT_CLASS "SDL2" +#define OS2DRIVER_NAME_DIVE "DIVE" +#define OS2DRIVER_NAME_VMAN "VMAN" + + +static const SDL_Scancode aSDLScancode[] = { + /* 0 1 2 3 4 5 6 7 */ + /* 8 9 A B C D E F */ + SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_ESCAPE, SDL_SCANCODE_1, SDL_SCANCODE_2, SDL_SCANCODE_3, SDL_SCANCODE_4, SDL_SCANCODE_5, SDL_SCANCODE_6, /* 0 */ + SDL_SCANCODE_7, SDL_SCANCODE_8, SDL_SCANCODE_9, SDL_SCANCODE_0, SDL_SCANCODE_MINUS, SDL_SCANCODE_EQUALS, SDL_SCANCODE_BACKSPACE, SDL_SCANCODE_TAB, /* 0 */ + + SDL_SCANCODE_Q, SDL_SCANCODE_W, SDL_SCANCODE_E, SDL_SCANCODE_R, SDL_SCANCODE_T, SDL_SCANCODE_Y, SDL_SCANCODE_U, SDL_SCANCODE_I, /* 1 */ + SDL_SCANCODE_O, SDL_SCANCODE_P, SDL_SCANCODE_LEFTBRACKET, SDL_SCANCODE_RIGHTBRACKET, SDL_SCANCODE_RETURN, SDL_SCANCODE_LCTRL, SDL_SCANCODE_A, SDL_SCANCODE_S, /* 1 */ + + SDL_SCANCODE_D, SDL_SCANCODE_F, SDL_SCANCODE_G, SDL_SCANCODE_H, SDL_SCANCODE_J, SDL_SCANCODE_K, SDL_SCANCODE_L, SDL_SCANCODE_SEMICOLON, /* 2 */ + SDL_SCANCODE_APOSTROPHE, SDL_SCANCODE_GRAVE, SDL_SCANCODE_LSHIFT, SDL_SCANCODE_BACKSLASH, SDL_SCANCODE_Z, SDL_SCANCODE_X, SDL_SCANCODE_C, SDL_SCANCODE_V, /* 2 */ + + SDL_SCANCODE_B, SDL_SCANCODE_N, SDL_SCANCODE_M, SDL_SCANCODE_COMMA, SDL_SCANCODE_PERIOD, SDL_SCANCODE_SLASH, SDL_SCANCODE_RSHIFT, /*55*/SDL_SCANCODE_KP_MULTIPLY,/* 3 */ + SDL_SCANCODE_LALT, SDL_SCANCODE_SPACE, SDL_SCANCODE_CAPSLOCK, SDL_SCANCODE_F1, SDL_SCANCODE_F2, SDL_SCANCODE_F3, SDL_SCANCODE_F4, SDL_SCANCODE_F5, /* 3 */ + + SDL_SCANCODE_F6, SDL_SCANCODE_F7, SDL_SCANCODE_F8, SDL_SCANCODE_F9, SDL_SCANCODE_F10, SDL_SCANCODE_NUMLOCKCLEAR, SDL_SCANCODE_SCROLLLOCK, SDL_SCANCODE_KP_7, /* 4 */ + /*72*/ SDL_SCANCODE_KP_8, /*73*/SDL_SCANCODE_KP_9, SDL_SCANCODE_KP_MINUS,/*75*/SDL_SCANCODE_KP_4, /*76*/SDL_SCANCODE_KP_5, /*77*/SDL_SCANCODE_KP_6, /*78*/SDL_SCANCODE_KP_PLUS, /*79*/SDL_SCANCODE_KP_1, /* 4 */ + + /*80*/ SDL_SCANCODE_KP_2, /*81*/SDL_SCANCODE_KP_3, SDL_SCANCODE_KP_0, /*83*/SDL_SCANCODE_KP_PERIOD, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_NONUSBACKSLASH,SDL_SCANCODE_F11, /* 5 */ + /*88*/ SDL_SCANCODE_F12, /*89*/SDL_SCANCODE_PAUSE, /*90*/SDL_SCANCODE_KP_ENTER,/*91*/SDL_SCANCODE_RCTRL, /*92*/SDL_SCANCODE_KP_DIVIDE, SDL_SCANCODE_APPLICATION, SDL_SCANCODE_RALT, /*95*/SDL_SCANCODE_UNKNOWN, /* 5 */ + + /*96*/ SDL_SCANCODE_HOME, /*97*/SDL_SCANCODE_UP, /*98*/SDL_SCANCODE_PAGEUP, SDL_SCANCODE_LEFT, /*100*/SDL_SCANCODE_RIGHT, SDL_SCANCODE_END, /*102*/SDL_SCANCODE_DOWN, /*103*/SDL_SCANCODE_PAGEDOWN, /* 6 */ +/*104*/ SDL_SCANCODE_F17, /*105*/SDL_SCANCODE_DELETE, SDL_SCANCODE_F19, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN,/*110*/SDL_SCANCODE_UNKNOWN,/*111*/SDL_SCANCODE_UNKNOWN, /* 6 */ + +/*112*/ SDL_SCANCODE_INTERNATIONAL2, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_INTERNATIONAL1,SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_UNKNOWN, /* 7 */ +/*120*/ SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_INTERNATIONAL4,SDL_SCANCODE_UNKNOWN, SDL_SCANCODE_INTERNATIONAL5,SDL_SCANCODE_APPLICATION,SDL_SCANCODE_INTERNATIONAL3,SDL_SCANCODE_LGUI, SDL_SCANCODE_RGUI /* 7 */ +}; + +/* Utilites. + * --------- + */ +static BOOL _getSDLPixelFormatData(SDL_PixelFormat *pSDLPixelFormat, + ULONG ulBPP, ULONG fccColorEncoding) +{ + ULONG ulRshift, ulGshift, ulBshift; + ULONG ulRmask, ulGmask, ulBmask; + ULONG ulRloss, ulGloss, ulBloss; + + pSDLPixelFormat->BitsPerPixel = ulBPP; + pSDLPixelFormat->BytesPerPixel = (pSDLPixelFormat->BitsPerPixel + 7) / 8; + + switch (fccColorEncoding) { + case FOURCC_LUT8: + ulRshift = 0; ulGshift = 0; ulBshift = 0; + ulRmask = 0; ulGmask = 0; ulBmask = 0; + ulRloss = 8; ulGloss = 8; ulBloss = 8; + break; + + case FOURCC_R555: + ulRshift = 10; ulGshift = 5; ulBshift = 0; + ulRmask = 0x7C00; ulGmask = 0x03E0; ulBmask = 0x001F; + ulRloss = 3; ulGloss = 3; ulBloss = 3; + break; + + case FOURCC_R565: + ulRshift = 11; ulGshift = 5; ulBshift = 0; + ulRmask = 0xF800; ulGmask = 0x07E0; ulBmask = 0x001F; + ulRloss = 3; ulGloss = 2; ulBloss = 3; + break; + + case FOURCC_R664: + ulRshift = 10; ulGshift = 4; ulBshift = 0; + ulRmask = 0xFC00; ulGmask = 0x03F0; ulBmask = 0x000F; + ulRloss = 2; ulGloss = 4; ulBloss = 3; + break; + + case FOURCC_R666: + ulRshift = 12; ulGshift = 6; ulBshift = 0; + ulRmask = 0x03F000; ulGmask = 0x000FC0; ulBmask = 0x00003F; + ulRloss = 2; ulGloss = 2; ulBloss = 2; + break; + + case FOURCC_RGB3: + case FOURCC_RGB4: + ulRshift = 0; ulGshift = 8; ulBshift = 16; + ulRmask = 0x0000FF; ulGmask = 0x00FF00; ulBmask = 0xFF0000; + ulRloss = 0x00; ulGloss = 0x00; ulBloss = 0x00; + break; + + case FOURCC_BGR3: + case FOURCC_BGR4: + ulRshift = 16; ulGshift = 8; ulBshift = 0; + ulRmask = 0xFF0000; ulGmask = 0x00FF00; ulBmask = 0x0000FF; + ulRloss = 0; ulGloss = 0; ulBloss = 0; + break; + + default: +/* printf("Unknown color encoding: %.4s\n", fccColorEncoding);*/ + SDL_memset(pSDLPixelFormat, 0, sizeof(SDL_PixelFormat)); + return FALSE; + } + + pSDLPixelFormat->Rshift = ulRshift; + pSDLPixelFormat->Gshift = ulGshift; + pSDLPixelFormat->Bshift = ulBshift; + pSDLPixelFormat->Rmask = ulRmask; + pSDLPixelFormat->Gmask = ulGmask; + pSDLPixelFormat->Bmask = ulBmask; + pSDLPixelFormat->Rloss = ulRloss; + pSDLPixelFormat->Gloss = ulGloss; + pSDLPixelFormat->Bloss = ulBloss; + + pSDLPixelFormat->Ashift = 0x00; + pSDLPixelFormat->Amask = 0x00; + pSDLPixelFormat->Aloss = 0x00; + + return TRUE; +} + +static Uint32 _getSDLPixelFormat(ULONG ulBPP, FOURCC fccColorEncoding) +{ + SDL_PixelFormat stSDLPixelFormat; + Uint32 uiResult = SDL_PIXELFORMAT_UNKNOWN; + + if (_getSDLPixelFormatData(&stSDLPixelFormat, ulBPP, fccColorEncoding)) + uiResult = SDL_MasksToPixelFormatEnum(ulBPP, stSDLPixelFormat.Rmask, + stSDLPixelFormat.Gmask, + stSDLPixelFormat.Bmask, 0); + + return uiResult; +} + +static SDL_DisplayMode *_getDisplayModeForSDLWindow(SDL_Window *window) +{ + SDL_VideoDisplay *pSDLDisplay = SDL_GetDisplayForWindow(window); + + if (!pSDLDisplay) { + debug_os2("No display for the window"); + return FALSE; + } + + return &pSDLDisplay->current_mode; +} + +static VOID _mouseCheck(WINDATA *pWinData) +{ + SDL_Mouse *pSDLMouse = SDL_GetMouse(); + + if ((pSDLMouse->relative_mode || (pWinData->window->flags & SDL_WINDOW_MOUSE_GRABBED) != 0) && + ((pWinData->window->flags & SDL_WINDOW_INPUT_FOCUS) != 0)) { + /* We will make a real capture in _wmMouseButton() */ + } else { + WinSetCapture(HWND_DESKTOP, NULLHANDLE); + } +} + + +/* PM window procedure. + * -------------------- + */ +static int OS2_ResizeWindowShape(SDL_Window *window); + +static VOID _setVisibleRegion(WINDATA *pWinData, BOOL fVisible) +{ + SDL_VideoDisplay *pSDLDisplay; + + if (!pWinData->pVOData) + return; + + pSDLDisplay = (fVisible)? SDL_GetDisplayForWindow(pWinData->window) : NULL; + pWinData->pOutput->SetVisibleRegion(pWinData->pVOData, pWinData->hwnd, + (!pSDLDisplay) ? + NULL : &pSDLDisplay->current_mode, + pWinData->hrgnShape, fVisible); +} + +static VOID _wmPaint(WINDATA *pWinData, HWND hwnd) +{ + if (!pWinData->pVOData || + !pWinData->pOutput->Update(pWinData->pVOData, hwnd, NULL, 0)) { + RECTL rectl; + HPS hps; + + hps = WinBeginPaint(hwnd, 0, &rectl); + WinFillRect(hps, &rectl, CLR_BLACK); + WinEndPaint(hps); + } +} + +static VOID _wmMouseMove(WINDATA *pWinData, SHORT lX, SHORT lY) +{ + SDL_Mouse *pSDLMouse = SDL_GetMouse(); + POINTL pointl; + BOOL fWinActive = (pWinData->window->flags & SDL_WINDOW_INPUT_FOCUS) != 0; + + if (!pSDLMouse->relative_mode || pSDLMouse->relative_mode_warp) { + if (!pSDLMouse->relative_mode && fWinActive && + ((pWinData->window->flags & SDL_WINDOW_MOUSE_GRABBED) != 0) && + (WinQueryCapture(HWND_DESKTOP) == pWinData->hwnd)) { + + pointl.x = lX; + pointl.y = lY; + + if (lX < 0) + lX = 0; + else if (lX >= pWinData->window->w) + lX = pWinData->window->w - 1; + + if (lY < 0) + lY = 0; + else if (lY >= pWinData->window->h) + lY = pWinData->window->h - 1; + + if (lX != pointl.x || lY != pointl.x) { + pointl.x = lX; + pointl.y = lY; + WinMapWindowPoints(pWinData->hwnd, HWND_DESKTOP, &pointl, 1); + pWinData->lSkipWMMouseMove++; + WinSetPointerPos(HWND_DESKTOP, pointl.x, pointl.y); + } + } + + SDL_SendMouseMotion(pWinData->window, 0, 0, lX, + pWinData->window->h - lY - 1); + return; + } + + if (fWinActive) { + pointl.x = pWinData->window->w / 2; + pointl.y = pWinData->window->h / 2; + WinMapWindowPoints(pWinData->hwnd, HWND_DESKTOP, &pointl, 1); + + SDL_SendMouseMotion(pWinData->window, 0, 1, + lX - pointl.x, pointl.y - lY); + + pWinData->lSkipWMMouseMove++; + WinSetPointerPos(HWND_DESKTOP, pointl.x, pointl.y); + } +} + +static VOID _wmMouseButton(WINDATA *pWinData, ULONG ulButton, BOOL fDown) +{ + static ULONG aBtnGROP2SDL[3] = { SDL_BUTTON_LEFT, SDL_BUTTON_RIGHT, + SDL_BUTTON_MIDDLE }; + SDL_Mouse *pSDLMouse = SDL_GetMouse(); + + if ((pSDLMouse->relative_mode || ((pWinData->window->flags & SDL_WINDOW_MOUSE_GRABBED) != 0)) && + ((pWinData->window->flags & SDL_WINDOW_INPUT_FOCUS) != 0) && + (WinQueryCapture(HWND_DESKTOP) != pWinData->hwnd)) { + /* Mouse should be captured. */ + if (pSDLMouse->relative_mode && !pSDLMouse->relative_mode_warp) { + POINTL pointl; + + pointl.x = pWinData->window->w / 2; + pointl.y = pWinData->window->h / 2; + WinMapWindowPoints(pWinData->hwnd, HWND_DESKTOP, &pointl, 1); + pWinData->lSkipWMMouseMove++; + WinSetPointerPos(HWND_DESKTOP, pointl.x, pointl.y); + } + + WinSetCapture(HWND_DESKTOP, pWinData->hwnd); + } + + SDL_SendMouseButton(pWinData->window, 0, + (fDown)? SDL_PRESSED : SDL_RELEASED, + aBtnGROP2SDL[ulButton]); +} + +static VOID _wmChar(WINDATA *pWinData, MPARAM mp1, MPARAM mp2) +{ + ULONG ulFlags = SHORT1FROMMP(mp1); /* WM_CHAR flags */ + ULONG ulVirtualKey = SHORT2FROMMP(mp2); /* Virtual key code VK_* */ + ULONG ulCharCode = SHORT1FROMMP(mp2); /* Character code */ + ULONG ulScanCode = CHAR4FROMMP(mp1); /* Scan code */ + + if (((ulFlags & (KC_VIRTUALKEY | KC_KEYUP | KC_ALT)) == (KC_VIRTUALKEY | KC_ALT)) && + (ulVirtualKey == VK_F4)) { + SDL_SendWindowEvent(pWinData->window, SDL_WINDOWEVENT_CLOSE, 0, 0); + } + + if ((ulFlags & KC_SCANCODE) != 0) { + SDL_SendKeyboardKey(((ulFlags & KC_KEYUP) == 0)? SDL_PRESSED : SDL_RELEASED, aSDLScancode[ulScanCode]); + } + + if ((ulFlags & KC_CHAR) != 0) { +#if defined(HAVE_ICONV) && defined(HAVE_ICONV_H) + char *utf8 = SDL_iconv_string("UTF-8", "", (char *)&ulCharCode, 1); + SDL_SendKeyboardText((utf8 && *utf8) ? utf8 : (char *)&ulCharCode); + SDL_free(utf8); +#else + char utf8[4]; + int rc = StrUTF8(1, utf8, sizeof(utf8), (char *)&ulCharCode, 1); + SDL_SendKeyboardText((rc > 0) ? utf8 : (char *) &ulCharCode); +#endif + } +} + +static VOID _wmMove(WINDATA *pWinData) +{ + SDL_DisplayMode *pSDLDisplayMode = _getDisplayModeForSDLWindow(pWinData->window); + POINTL pointl = { 0,0 }; + RECTL rectl; + + WinQueryWindowRect(pWinData->hwnd, &rectl); + WinMapWindowPoints(pWinData->hwnd, HWND_DESKTOP, (PPOINTL)&rectl, 2); + + WinMapWindowPoints(pWinData->hwnd, HWND_DESKTOP, &pointl, 1); + SDL_SendWindowEvent(pWinData->window, SDL_WINDOWEVENT_MOVED, rectl.xLeft, + pSDLDisplayMode->h - rectl.yTop); +} + +static MRESULT _wmDragOver(WINDATA *pWinData, PDRAGINFO pDragInfo) +{ + ULONG ulIdx; + PDRAGITEM pDragItem; + USHORT usDrag = DOR_NEVERDROP; + USHORT usDragOp = DO_UNKNOWN; + + if (!DrgAccessDraginfo(pDragInfo)) + return MRFROM2SHORT(DOR_NEVERDROP, DO_UNKNOWN); + + for (ulIdx = 0; ulIdx < pDragInfo->cditem; ulIdx++) { + pDragItem = DrgQueryDragitemPtr(pDragInfo, ulIdx); + + /* We accept WPS files only. */ + if (!DrgVerifyRMF(pDragItem, "DRM_OS2FILE", NULL)) { + usDrag = DOR_NEVERDROP; + usDragOp = DO_UNKNOWN; + break; + } + + if (pDragInfo->usOperation == DO_DEFAULT && + (pDragItem->fsSupportedOps & DO_COPYABLE) != 0) { + usDrag = DOR_DROP; + usDragOp = DO_COPY; + } else + if (pDragInfo->usOperation == DO_LINK && + (pDragItem->fsSupportedOps & DO_LINKABLE) != 0) { + usDrag = DOR_DROP; + usDragOp = DO_LINK; + } else { + usDrag = DOR_NODROPOP; + usDragOp = DO_UNKNOWN; + break; + } + } + + /* Update window (The DIVE surface spoiled while dragging) */ + WinInvalidateRect(pWinData->hwnd, NULL, FALSE); + WinUpdateWindow(pWinData->hwnd); + + DrgFreeDraginfo(pDragInfo); + return MPFROM2SHORT(usDrag, usDragOp); +} + +static MRESULT _wmDrop(WINDATA *pWinData, PDRAGINFO pDragInfo) +{ + ULONG ulIdx; + PDRAGITEM pDragItem; + CHAR acFName[CCHMAXPATH]; + PCHAR pcFName; + + if (!DrgAccessDraginfo(pDragInfo)) + return MRFROM2SHORT(DOR_NEVERDROP, 0); + + for (ulIdx = 0; ulIdx < pDragInfo->cditem; ulIdx++) { + pDragItem = DrgQueryDragitemPtr(pDragInfo, ulIdx); + + if (DrgVerifyRMF(pDragItem, "DRM_OS2FILE", NULL) && + pDragItem->hstrContainerName != NULLHANDLE && + pDragItem->hstrSourceName != NULLHANDLE) { + /* Get file name from the item. */ + DrgQueryStrName(pDragItem->hstrContainerName, sizeof(acFName), acFName); + pcFName = SDL_strchr(acFName, '\0'); + DrgQueryStrName(pDragItem->hstrSourceName, + sizeof(acFName) - (pcFName - acFName), pcFName); + + /* Send to SDL full file name converted to UTF-8. */ + pcFName = OS2_SysToUTF8(acFName); + SDL_SendDropFile(pWinData->window, pcFName); + SDL_free(pcFName); + + /* Notify a source that a drag operation is complete. */ + if (pDragItem->hwndItem) + DrgSendTransferMsg(pDragItem->hwndItem, DM_ENDCONVERSATION, + (MPARAM)pDragItem->ulItemID, + (MPARAM)DMFL_TARGETSUCCESSFUL); + } + } + + DrgDeleteDraginfoStrHandles(pDragInfo); + DrgFreeDraginfo(pDragInfo); + + SDL_SendDropComplete(pWinData->window); + + return (MRESULT)FALSE; +} + +static MRESULT EXPENTRY wndFrameProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) +{ + HWND hwndClient = WinQueryWindow(hwnd, QW_BOTTOM); + WINDATA * pWinData = (WINDATA *)WinQueryWindowULong(hwndClient, 0); + + if (!pWinData) + return WinDefWindowProc(hwnd, msg, mp1, mp2); + + /* Send a SDL_SYSWMEVENT if the application wants them */ + if (SDL_GetEventState(SDL_SYSWMEVENT) == SDL_ENABLE) { + SDL_SysWMmsg wmmsg; + + SDL_VERSION(&wmmsg.version); + wmmsg.subsystem = SDL_SYSWM_OS2; + wmmsg.msg.os2.fFrame = TRUE; + wmmsg.msg.os2.hwnd = hwnd; + wmmsg.msg.os2.msg = msg; + wmmsg.msg.os2.mp1 = mp1; + wmmsg.msg.os2.mp2 = mp2; + SDL_SendSysWMEvent(&wmmsg); + } + + switch (msg) { + case WM_MINMAXFRAME: + if ((((PSWP)mp1)->fl & SWP_RESTORE) != 0) { + pWinData->lSkipWMMove += 2; + SDL_SendWindowEvent(pWinData->window, SDL_WINDOWEVENT_RESTORED, 0, 0); + } + if ((((PSWP)mp1)->fl & SWP_MINIMIZE) != 0) { + pWinData->lSkipWMSize++; + pWinData->lSkipWMMove += 2; + SDL_SendWindowEvent(pWinData->window, SDL_WINDOWEVENT_MINIMIZED, 0, 0); + } + if ((((PSWP)mp1)->fl & SWP_MAXIMIZE) != 0) { + SDL_SendWindowEvent(pWinData->window, SDL_WINDOWEVENT_MAXIMIZED, 0, 0); + } + break; + + case WM_ADJUSTFRAMEPOS: + if (pWinData->lSkipWMAdjustFramePos > 0) { + pWinData->lSkipWMAdjustFramePos++; + break; + } + if ((pWinData->window->flags & SDL_WINDOW_FULLSCREEN) != 0 && + (((PSWP)mp1)->fl & SWP_RESTORE) != 0) { + /* Keep fullscreen window size on restore. */ + RECTL rectl; + + rectl.xLeft = 0; + rectl.yBottom = 0; + rectl.xRight = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN); + rectl.yTop = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN); + WinCalcFrameRect(hwnd, &rectl, FALSE); + ((PSWP)mp1)->x = rectl.xLeft; + ((PSWP)mp1)->y = rectl.yBottom; + ((PSWP)mp1)->cx = rectl.xRight - rectl.xLeft; + ((PSWP)mp1)->cy = rectl.yTop - rectl.yBottom; + } + if ((((PSWP)mp1)->fl & (SWP_SIZE | SWP_MINIMIZE)) == SWP_SIZE) { + if ((pWinData->window->flags & SDL_WINDOW_FULLSCREEN) != 0) { + /* SDL_WINDOW_FULLSCREEN_DESKTOP have flag SDL_WINDOW_FULLSCREEN... */ + if (SDL_IsShapedWindow(pWinData->window)) + OS2_ResizeWindowShape(pWinData->window); + break; + } + if ((SDL_GetWindowFlags(pWinData->window) & SDL_WINDOW_RESIZABLE) != 0) { + RECTL rectl; + int iMinW, iMinH, iMaxW, iMaxH; + int iWinW, iWinH; + + rectl.xLeft = 0; + rectl.yBottom = 0; + SDL_GetWindowSize(pWinData->window, + (int *)&rectl.xRight, (int *)&rectl.yTop); + iWinW = rectl.xRight; + iWinH = rectl.yTop; + + SDL_GetWindowMinimumSize(pWinData->window, &iMinW, &iMinH); + SDL_GetWindowMaximumSize(pWinData->window, &iMaxW, &iMaxH); + + if (iWinW < iMinW) + rectl.xRight = iMinW; + else if (iMaxW != 0 && iWinW > iMaxW) + rectl.xRight = iMaxW; + + if (iWinH < iMinH) + rectl.yTop = iMinW; + else if (iMaxH != 0 && iWinH > iMaxH) + rectl.yTop = iMaxH; + + if (rectl.xRight == iWinW && rectl.yTop == iWinH) { + if (SDL_IsShapedWindow(pWinData->window)) + OS2_ResizeWindowShape(pWinData->window); + break; + } + + WinCalcFrameRect(hwnd, &rectl, FALSE); + ((PSWP)mp1)->cx = rectl.xRight - rectl.xLeft; + ((PSWP)mp1)->cy = rectl.yTop - rectl.yBottom; + } + } + break; + } + + return pWinData->fnWndFrameProc(hwnd, msg, mp1, mp2); +} + +static MRESULT EXPENTRY wndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) +{ + WINDATA *pWinData = (WINDATA *)WinQueryWindowULong(hwnd, 0); + + if (!pWinData) + return WinDefWindowProc(hwnd, msg, mp1, mp2); + + /* Send a SDL_SYSWMEVENT if the application wants them */ + if (SDL_GetEventState(SDL_SYSWMEVENT) == SDL_ENABLE) { + SDL_SysWMmsg wmmsg; + + SDL_VERSION(&wmmsg.version); + wmmsg.subsystem = SDL_SYSWM_OS2; + wmmsg.msg.os2.fFrame = FALSE; + wmmsg.msg.os2.hwnd = hwnd; + wmmsg.msg.os2.msg = msg; + wmmsg.msg.os2.mp1 = mp1; + wmmsg.msg.os2.mp2 = mp2; + SDL_SendSysWMEvent(&wmmsg); + } + + switch (msg) { + case WM_CLOSE: + case WM_QUIT: + SDL_SendWindowEvent(pWinData->window, SDL_WINDOWEVENT_CLOSE, 0, 0); + if (!pWinData->fnUserWndProc) + return (MRESULT)FALSE; + break; + + case WM_PAINT: + _wmPaint(pWinData, hwnd); + break; + + case WM_SHOW: + SDL_SendWindowEvent(pWinData->window, (SHORT1FROMMP(mp1) == 0)? + SDL_WINDOWEVENT_HIDDEN : + SDL_WINDOWEVENT_SHOWN , + 0, 0); + break; + + case WM_UPDATEFRAME: + /* Return TRUE - no further action for the frame control window procedure */ + return (MRESULT)TRUE; + + case WM_ACTIVATE: + if ((BOOL)mp1) { + POINTL pointl; + + if (SDL_GetKeyboardFocus() != pWinData->window) + SDL_SetKeyboardFocus(pWinData->window); + + WinQueryPointerPos(HWND_DESKTOP, &pointl); + WinMapWindowPoints(HWND_DESKTOP, pWinData->hwnd, &pointl, 1); + SDL_SendMouseMotion(pWinData->window, 0, 0, + pointl.x, pWinData->window->h - pointl.y - 1); + } else { + if (SDL_GetKeyboardFocus() == pWinData->window) + SDL_SetKeyboardFocus(NULL); + + WinSetCapture(HWND_DESKTOP, NULLHANDLE); + } + break; + + case WM_MOUSEMOVE: + WinSetPointer(HWND_DESKTOP, hptrCursor); + + if (pWinData->lSkipWMMouseMove > 0) + pWinData->lSkipWMMouseMove--; + else { + _wmMouseMove(pWinData, SHORT1FROMMP(mp1), SHORT2FROMMP(mp1)); + } + return (MRESULT)FALSE; + + case WM_BUTTON1DOWN: + case WM_BUTTON1DBLCLK: + _wmMouseButton(pWinData, 0, TRUE); + break; + + case WM_BUTTON1UP: + _wmMouseButton(pWinData, 0, FALSE); + break; + + case WM_BUTTON2DOWN: + case WM_BUTTON2DBLCLK: + _wmMouseButton(pWinData, 1, TRUE); + break; + + case WM_BUTTON2UP: + _wmMouseButton(pWinData, 1, FALSE); + break; + + case WM_BUTTON3DOWN: + case WM_BUTTON3DBLCLK: + _wmMouseButton(pWinData, 2, TRUE); + break; + + case WM_BUTTON3UP: + _wmMouseButton(pWinData, 2, FALSE); + break; + + case WM_TRANSLATEACCEL: + /* ALT and acceleration keys not allowed (must be processed in WM_CHAR) */ + if (!mp1 || ((PQMSG)mp1)->msg != WM_CHAR) + break; + return (MRESULT)FALSE; + + case WM_CHAR: + _wmChar(pWinData, mp1, mp2); + break; + + case WM_SIZE: + if (pWinData->lSkipWMSize > 0) + pWinData->lSkipWMSize--; + else { + if ((pWinData->window->flags & SDL_WINDOW_FULLSCREEN) == 0) { + SDL_SendWindowEvent(pWinData->window, SDL_WINDOWEVENT_RESIZED, + SHORT1FROMMP(mp2), SHORT2FROMMP(mp2)); + } else { + pWinData->lSkipWMVRNEnabled++; + } + } + break; + + case WM_MOVE: + if (pWinData->lSkipWMMove > 0) + pWinData->lSkipWMMove--; + else if ((pWinData->window->flags & SDL_WINDOW_FULLSCREEN) == 0) { + _wmMove(pWinData); + } + break; + + case WM_VRNENABLED: + if (pWinData->lSkipWMVRNEnabled > 0) + pWinData->lSkipWMVRNEnabled--; + else { + _setVisibleRegion(pWinData, TRUE); + } + return (MRESULT)TRUE; + + case WM_VRNDISABLED: + _setVisibleRegion(pWinData, FALSE); + return (MRESULT)TRUE; + + case DM_DRAGOVER: + return _wmDragOver(pWinData, (PDRAGINFO)PVOIDFROMMP(mp1)); + + case DM_DROP: + return _wmDrop(pWinData, (PDRAGINFO)PVOIDFROMMP(mp1)); + } + + return (pWinData->fnUserWndProc)? + pWinData->fnUserWndProc(hwnd, msg, mp1, mp2) : + WinDefWindowProc(hwnd, msg, mp1, mp2); +} + + +/* SDL routines. + * ------------ + */ + +static void OS2_PumpEvents(_THIS) +{ + SDL_VideoData *pVData = (SDL_VideoData *)_this->driverdata; + QMSG qmsg; + + if (WinPeekMsg(pVData->hab, &qmsg, NULLHANDLE, 0, 0, PM_REMOVE)) + WinDispatchMsg(pVData->hab, &qmsg); +} + +static WINDATA *_setupWindow(_THIS, SDL_Window *window, HWND hwndFrame, + HWND hwnd) +{ + SDL_VideoData *pVData = (SDL_VideoData *)_this->driverdata; + WINDATA *pWinData = SDL_calloc(1, sizeof(WINDATA)); + + if (!pWinData) { + SDL_OutOfMemory(); + return NULL; + } + pWinData->hwnd = hwnd; + pWinData->hwndFrame = hwndFrame; + pWinData->window = window; + window->driverdata = pWinData; + + WinSetWindowULong(hwnd, 0, (ULONG)pWinData); + pWinData->fnWndFrameProc = WinSubclassWindow(hwndFrame, wndFrameProc); + + pWinData->pOutput = pVData->pOutput; + pWinData->pVOData = pVData->pOutput->Open(); + + WinSetVisibleRegionNotify(hwnd, TRUE); + + return pWinData; +} + +static int OS2_CreateWindow(_THIS, SDL_Window *window) +{ + RECTL rectl; + HWND hwndFrame, hwnd; + SDL_DisplayMode *pSDLDisplayMode = _getDisplayModeForSDLWindow(window); + ULONG ulFrameFlags = FCF_TASKLIST | FCF_TITLEBAR | FCF_SYSMENU | + FCF_MINBUTTON | FCF_SHELLPOSITION; + ULONG ulSWPFlags = SWP_SIZE | SWP_SHOW | SWP_ZORDER | SWP_ACTIVATE; + WINDATA *pWinData; + + if (!pSDLDisplayMode) + return -1; + + /* Create a PM window */ + if ((window->flags & SDL_WINDOW_RESIZABLE) != 0) + ulFrameFlags |= FCF_SIZEBORDER | FCF_DLGBORDER | FCF_MAXBUTTON; + else if ((window->flags & SDL_WINDOW_BORDERLESS) == 0) + ulFrameFlags |= FCF_DLGBORDER; + + if ((window->flags & SDL_WINDOW_MAXIMIZED) != 0) + ulSWPFlags |= SWP_MAXIMIZE; + else if ((window->flags & SDL_WINDOW_MINIMIZED) != 0) + ulSWPFlags |= SWP_MINIMIZE; + + hwndFrame = WinCreateStdWindow(HWND_DESKTOP, 0, &ulFrameFlags, + WIN_CLIENT_CLASS, "SDL2", 0, 0, 0, &hwnd); + if (hwndFrame == NULLHANDLE) + return SDL_SetError("Couldn't create window"); + + /* Setup window data and frame window procedure */ + pWinData = _setupWindow(_this, window, hwndFrame, hwnd); + if (!pWinData) { + WinDestroyWindow(hwndFrame); + return -1; + } + + /* Show window */ + rectl.xLeft = 0; + rectl.yBottom = 0; + rectl.xRight = window->w; + rectl.yTop = window->h; + WinCalcFrameRect(hwndFrame, &rectl, FALSE); + pWinData->lSkipWMSize++; + pWinData->lSkipWMMove++; + WinSetWindowPos(hwndFrame, HWND_TOP, rectl.xLeft, rectl.yBottom, + rectl.xRight - rectl.xLeft, rectl.yTop - rectl.yBottom, + ulSWPFlags); + + rectl.xLeft = 0; + rectl.yBottom = 0; + WinMapWindowPoints(hwnd, HWND_DESKTOP, (PPOINTL)&rectl, 1); + window->x = rectl.xLeft; + window->y = pSDLDisplayMode->h - (rectl.yBottom + window->h); + + window->flags |= SDL_WINDOW_SHOWN; + + return 0; +} + +static int OS2_CreateWindowFrom(_THIS, SDL_Window *window, const void *data) +{ + SDL_VideoData *pVData = (SDL_VideoData *)_this->driverdata; + CHAR acBuf[256]; + CLASSINFO stCI; + HWND hwndUser = (HWND)data; + HWND hwndFrame, hwnd; + ULONG cbText; + PSZ pszText; + WINDATA *pWinData; + SDL_DisplayMode *pSDLDisplayMode = _getDisplayModeForSDLWindow(window); + SWP swp; + POINTL pointl; + + debug_os2("Enter"); + if (!pSDLDisplayMode) + return -1; + + /* User can accept client OR frame window handle. + * Get client and frame window handles. */ + WinQueryClassName(hwndUser, sizeof(acBuf), acBuf); + if (!WinQueryClassInfo(pVData->hab, acBuf, &stCI)) + return SDL_SetError("Cannot get user window class information"); + + if ((stCI.flClassStyle & CS_FRAME) == 0) { + /* Client window handle is specified */ + hwndFrame = WinQueryWindow(hwndUser, QW_PARENT); + if (hwndFrame == NULLHANDLE) + return SDL_SetError("Cannot get parent window handle"); + + if ((ULONG)WinSendMsg(hwndFrame, WM_QUERYFRAMEINFO, 0, 0) == 0) + return SDL_SetError("Parent window is not a frame window"); + + hwnd = hwndUser; + } else { + /* Frame window handle is specified */ + hwnd = WinWindowFromID(hwndUser, FID_CLIENT); + if (hwnd == NULLHANDLE) + return SDL_SetError("Cannot get client window handle"); + + hwndFrame = hwndUser; + + WinQueryClassName(hwnd, sizeof(acBuf), acBuf); + if (!WinQueryClassInfo(pVData->hab, acBuf, &stCI)) + return SDL_SetError("Cannot get client window class information"); + } + + /* Check window's reserved storage */ + if (stCI.cbWindowData < sizeof(ULONG)) + return SDL_SetError("Reserved storage of window must be at least %u bytes", sizeof(ULONG)); + + /* Set SDL-window title */ + cbText = WinQueryWindowTextLength(hwndFrame); + pszText = SDL_stack_alloc(CHAR, cbText + 1); + + if (pszText != NULL) + cbText = (pszText != NULL)? WinQueryWindowText(hwndFrame, cbText, pszText) : 0; + + if (cbText != 0) + window->title = OS2_SysToUTF8(pszText); + + if (pszText != NULL) { + SDL_stack_free(pszText); + } + + /* Set SDL-window flags */ + window->flags &= ~(SDL_WINDOW_SHOWN | SDL_WINDOW_BORDERLESS | + SDL_WINDOW_RESIZABLE | SDL_WINDOW_MAXIMIZED | + SDL_WINDOW_MINIMIZED | SDL_WINDOW_INPUT_FOCUS); + + if (WinIsWindowVisible(hwnd)) + window->flags |= SDL_WINDOW_SHOWN; + + WinSendMsg(hwndFrame, WM_QUERYBORDERSIZE, MPFROMP(&pointl), 0); + if (pointl.y == WinQuerySysValue(HWND_DESKTOP, SV_CYSIZEBORDER)) + window->flags |= SDL_WINDOW_RESIZABLE; + else if (pointl.y <= WinQuerySysValue(HWND_DESKTOP, SV_CYBORDER)) + window->flags |= SDL_WINDOW_BORDERLESS; + + WinQueryWindowPos(hwndFrame, &swp); + + if ((swp.fl & SWP_MAXIMIZE) != 0) + window->flags |= SDL_WINDOW_MAXIMIZED; + if ((swp.fl & SWP_MINIMIZE) != 0) + window->flags |= SDL_WINDOW_MINIMIZED; + + pointl.x = 0; + pointl.y = 0; + WinMapWindowPoints(hwnd, HWND_DESKTOP, &pointl, 1); + window->x = pointl.x; + window->y = pSDLDisplayMode->h - (pointl.y + swp.cy); + + WinQueryWindowPos(hwnd, &swp); + window->w = swp.cx; + window->h = swp.cy; + + /* Setup window data and frame window procedure */ + pWinData = _setupWindow(_this, window, hwndFrame, hwnd); + if (!pWinData) { + SDL_free(window->title); + window->title = NULL; + return -1; + } + pWinData->fnUserWndProc = WinSubclassWindow(hwnd, wndProc); + + if (WinQueryActiveWindow(HWND_DESKTOP) == hwndFrame) + SDL_SetKeyboardFocus(window); + + return 0; +} + +static void OS2_DestroyWindow(_THIS, SDL_Window * window) +{ + SDL_VideoData *pVData = (SDL_VideoData *)_this->driverdata; + WINDATA *pWinData = (WINDATA *)window->driverdata; + + debug_os2("Enter"); + if (!pWinData) + return; + + if (pWinData->hrgnShape != NULLHANDLE) { + HPS hps = WinGetPS(pWinData->hwnd); + GpiDestroyRegion(hps, pWinData->hrgnShape); + WinReleasePS(hps); + } + + if (window->shaper) { + SDL_free(window->shaper); + window->shaper = NULL; + } + + if (!pWinData->fnUserWndProc) { + /* Window was created by SDL (OS2_CreateWindow()), + * not by user (OS2_CreateWindowFrom()) */ + WinDestroyWindow(pWinData->hwndFrame); + } else { + WinSetWindowULong(pWinData->hwnd, 0, 0); + } + + if ((pVData) && (pWinData->pVOData)) { + pVData->pOutput->Close(pWinData->pVOData); + pWinData->pVOData = NULL; + } + + if (pWinData->hptrIcon != NULLHANDLE) { + WinDestroyPointer(pWinData->hptrIcon); + pWinData->hptrIcon = NULLHANDLE; + } + + SDL_free(pWinData); + window->driverdata = NULL; +} + +static void OS2_SetWindowTitle(_THIS, SDL_Window *window) +{ + PSZ pszTitle = (!window->title)? NULL : OS2_UTF8ToSys(window->title); + + WinSetWindowText(((WINDATA *)window->driverdata)->hwndFrame, pszTitle); + SDL_free(pszTitle); +} + +static void OS2_SetWindowIcon(_THIS, SDL_Window *window, SDL_Surface *icon) +{ + WINDATA *pWinData = (WINDATA *)window->driverdata; + HPOINTER hptr = utilCreatePointer(icon, 0, 0); + + if (hptr == NULLHANDLE) + return; + + /* Destroy old icon */ + if (pWinData->hptrIcon != NULLHANDLE) + WinDestroyPointer(pWinData->hptrIcon); + + /* Set new window icon */ + pWinData->hptrIcon = hptr; + if (!WinSendMsg(pWinData->hwndFrame, WM_SETICON, MPFROMLONG(hptr), 0)) { + debug_os2("Cannot set icon for the window"); + } +} + +static void OS2_SetWindowPosition(_THIS, SDL_Window *window) +{ + WINDATA *pWinData = (WINDATA *)window->driverdata; + RECTL rectl; + ULONG ulFlags; + SDL_DisplayMode *pSDLDisplayMode = _getDisplayModeForSDLWindow(window); + + debug_os2("Enter"); + if (!pSDLDisplayMode) + return; + + rectl.xLeft = 0; + rectl.yBottom = 0; + rectl.xRight = window->w; + rectl.yTop = window->h; + WinCalcFrameRect(pWinData->hwndFrame, &rectl, FALSE); + + if (SDL_ShouldAllowTopmost() && + (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_INPUT_FOCUS)) == + (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_INPUT_FOCUS) ) + ulFlags = SWP_ZORDER | SWP_MOVE | SWP_SIZE; + else + ulFlags = SWP_MOVE | SWP_SIZE; + + pWinData->lSkipWMSize++; + pWinData->lSkipWMMove++; + WinSetWindowPos(pWinData->hwndFrame, HWND_TOP, + window->x + rectl.xLeft, + (pSDLDisplayMode->h - window->y) - window->h + rectl.yBottom, + rectl.xRight - rectl.xLeft, rectl.yTop - rectl.yBottom, + ulFlags); +} + +static void OS2_SetWindowSize(_THIS, SDL_Window *window) +{ + debug_os2("Enter"); + OS2_SetWindowPosition(_this, window); +} + +static void OS2_ShowWindow(_THIS, SDL_Window *window) +{ + WINDATA *pWinData = (WINDATA *)window->driverdata; + + debug_os2("Enter"); + WinShowWindow(pWinData->hwndFrame, TRUE); +} + +static void OS2_HideWindow(_THIS, SDL_Window *window) +{ + WINDATA *pWinData = (WINDATA *)window->driverdata; + + debug_os2("Enter"); + WinShowWindow(pWinData->hwndFrame, FALSE); +} + +static void OS2_RaiseWindow(_THIS, SDL_Window *window) +{ + debug_os2("Enter"); + OS2_SetWindowPosition(_this, window); +} + +static void OS2_MaximizeWindow(_THIS, SDL_Window *window) +{ + WINDATA *pWinData = (WINDATA *)window->driverdata; + + debug_os2("Enter"); + WinSetWindowPos(pWinData->hwndFrame, HWND_TOP, 0, 0, 0, 0, SWP_MAXIMIZE); +} + +static void OS2_MinimizeWindow(_THIS, SDL_Window *window) +{ + WINDATA *pWinData = (WINDATA *)window->driverdata; + + debug_os2("Enter"); + WinSetWindowPos(pWinData->hwndFrame, HWND_TOP, 0, 0, 0, 0, SWP_MINIMIZE | SWP_DEACTIVATE); +} + +static void OS2_RestoreWindow(_THIS, SDL_Window *window) +{ + WINDATA *pWinData = (WINDATA *)window->driverdata; + + debug_os2("Enter"); + WinSetWindowPos(pWinData->hwndFrame, HWND_TOP, 0, 0, 0, 0, SWP_RESTORE); +} + +static void OS2_SetWindowBordered(_THIS, SDL_Window * window, + SDL_bool bordered) +{ + WINDATA *pWinData = (WINDATA *)window->driverdata; + ULONG ulStyle = WinQueryWindowULong(pWinData->hwndFrame, QWL_STYLE); + RECTL rectl; + + debug_os2("Enter"); + + /* New frame sytle */ + if (bordered) + ulStyle |= ((window->flags & SDL_WINDOW_RESIZABLE) != 0) ? FS_SIZEBORDER : FS_DLGBORDER; + else + ulStyle &= ~(FS_SIZEBORDER | FS_BORDER | FS_DLGBORDER); + + /* Save client window position */ + WinQueryWindowRect(pWinData->hwnd, &rectl); + WinMapWindowPoints(pWinData->hwnd, HWND_DESKTOP, (PPOINTL)&rectl, 2); + + /* Change the frame */ + WinSetWindowULong(pWinData->hwndFrame, QWL_STYLE, ulStyle); + WinSendMsg(pWinData->hwndFrame, WM_UPDATEFRAME, MPFROMLONG(FCF_BORDER), 0); + + /* Restore client window position */ + WinCalcFrameRect(pWinData->hwndFrame, &rectl, FALSE); + pWinData->lSkipWMMove++; + WinSetWindowPos(pWinData->hwndFrame, HWND_TOP, rectl.xLeft, rectl.yBottom, + rectl.xRight - rectl.xLeft, + rectl.yTop - rectl.yBottom, + SWP_SIZE | SWP_MOVE | SWP_NOADJUST); +} + +static void OS2_SetWindowFullscreen(_THIS, SDL_Window *window, + SDL_VideoDisplay *display, + SDL_bool fullscreen) +{ + RECTL rectl; + ULONG ulFlags; + WINDATA *pWinData = (WINDATA *)window->driverdata; + SDL_DisplayMode *pSDLDisplayMode = &display->current_mode; + + debug_os2("Enter, fullscreen: %u", fullscreen); + + if (!pSDLDisplayMode) + return; + + if (SDL_ShouldAllowTopmost() && + (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_INPUT_FOCUS)) == (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_INPUT_FOCUS)) + ulFlags = SWP_SIZE | SWP_MOVE | SWP_ZORDER | SWP_NOADJUST; + else + ulFlags = SWP_SIZE | SWP_MOVE | SWP_NOADJUST; + + if (fullscreen) { + rectl.xLeft = 0; + rectl.yBottom = 0; + rectl.xRight = pSDLDisplayMode->w; + rectl.yTop = pSDLDisplayMode->h; + /* We need send the restore command now to allow WinCalcFrameRect() */ + WinSetWindowPos(pWinData->hwndFrame, HWND_TOP, 0, 0, 0, 0, SWP_RESTORE); + } else { + pWinData->lSkipWMMove++; + rectl.xLeft = window->windowed.x; + rectl.yTop = pSDLDisplayMode->h - window->windowed.y; + rectl.xRight = rectl.xLeft + window->windowed.w; + rectl.yBottom = rectl.yTop - window->windowed.h; + } + + if (!WinCalcFrameRect(pWinData->hwndFrame, &rectl, FALSE)) { + debug_os2("WinCalcFrameRect() failed"); + } + else if (!WinSetWindowPos(pWinData->hwndFrame, HWND_TOP, + rectl.xLeft, rectl.yBottom, + rectl.xRight - rectl.xLeft, rectl.yTop - rectl.yBottom, + ulFlags)) { + debug_os2("WinSetWindowPos() failed"); + } +} + +static SDL_bool OS2_GetWindowWMInfo(_THIS, SDL_Window * window, + struct SDL_SysWMinfo *info) +{ + WINDATA *pWinData = (WINDATA *)window->driverdata; + + if (info->version.major <= SDL_MAJOR_VERSION) { + info->subsystem = SDL_SYSWM_OS2; + info->info.os2.hwnd = pWinData->hwnd; + info->info.os2.hwndFrame = pWinData->hwndFrame; + return SDL_TRUE; + } + + SDL_SetError("Application not compiled with SDL %u", + SDL_MAJOR_VERSION); + return SDL_FALSE; +} + +static void OS2_OnWindowEnter(_THIS, SDL_Window * window) +{ +} + +static int OS2_SetWindowHitTest(SDL_Window *window, SDL_bool enabled) +{ + debug_os2("Enter"); + return 0; +} + +static void OS2_SetWindowMouseGrab(_THIS, SDL_Window *window, SDL_bool grabbed) +{ + WINDATA *pWinData = (WINDATA *)window->driverdata; + + debug_os2("Enter, %u", grabbed); + _mouseCheck(pWinData); +} + + +/* Shaper + */ +typedef struct _SHAPERECTS { + PRECTL pRects; + ULONG cRects; + ULONG ulWinHeight; +} SHAPERECTS; + +static void _combineRectRegions(SDL_ShapeTree *node, void *closure) +{ + SHAPERECTS *pShapeRects = (SHAPERECTS *)closure; + PRECTL pRect; + + /* Expand rectangles list */ + if ((pShapeRects->cRects & 0x0F) == 0) { + pRect = SDL_realloc(pShapeRects->pRects, (pShapeRects->cRects + 0x10) * sizeof(RECTL)); + if (!pRect) + return; + pShapeRects->pRects = pRect; + } + + /* Add a new rectangle */ + pRect = &pShapeRects->pRects[pShapeRects->cRects]; + pShapeRects->cRects++; + /* Fill rectangle data */ + pRect->xLeft = node->data.shape.x; + pRect->yTop = pShapeRects->ulWinHeight - node->data.shape.y; + pRect->xRight += node->data.shape.w; + pRect->yBottom = pRect->yTop - node->data.shape.h; +} + +static SDL_WindowShaper* OS2_CreateShaper(SDL_Window * window) +{ + SDL_WindowShaper* pSDLShaper = SDL_malloc(sizeof(SDL_WindowShaper)); + + debug_os2("Enter"); + pSDLShaper->window = window; + pSDLShaper->mode.mode = ShapeModeDefault; + pSDLShaper->mode.parameters.binarizationCutoff = 1; + pSDLShaper->userx = 0; + pSDLShaper->usery = 0; + pSDLShaper->driverdata = (SDL_ShapeTree *)NULL; + window->shaper = pSDLShaper; + + if (OS2_ResizeWindowShape(window) != 0) { + window->shaper = NULL; + SDL_free(pSDLShaper); + return NULL; + } + + return pSDLShaper; +} + +static int OS2_SetWindowShape(SDL_WindowShaper *shaper, SDL_Surface *shape, + SDL_WindowShapeMode *shape_mode) +{ + SDL_ShapeTree *pShapeTree; + WINDATA *pWinData; + SHAPERECTS stShapeRects; + HPS hps; + + debug_os2("Enter"); + if (!shaper || !shape || + (shape->format->Amask == 0 && shape_mode->mode != ShapeModeColorKey) || + shape->w != shaper->window->w || shape->h != shaper->window->h) { + return SDL_INVALID_SHAPE_ARGUMENT; + } + + if (shaper->driverdata) + SDL_FreeShapeTree((SDL_ShapeTree **)&shaper->driverdata); + + pShapeTree = SDL_CalculateShapeTree(*shape_mode, shape); + shaper->driverdata = pShapeTree; + + SDL_zero(stShapeRects); + stShapeRects.ulWinHeight = shaper->window->h; + SDL_TraverseShapeTree(pShapeTree, &_combineRectRegions, &stShapeRects); + + pWinData = (WINDATA *)shaper->window->driverdata; + hps = WinGetPS(pWinData->hwnd); + + if (pWinData->hrgnShape != NULLHANDLE) + GpiDestroyRegion(hps, pWinData->hrgnShape); + + pWinData->hrgnShape = (!stShapeRects.pRects) ? NULLHANDLE : + GpiCreateRegion(hps, stShapeRects.cRects, stShapeRects.pRects); + + WinReleasePS(hps); + SDL_free(stShapeRects.pRects); + WinSendMsg(pWinData->hwnd, WM_VRNENABLED, 0, 0); + + return 0; +} + +static int OS2_ResizeWindowShape(SDL_Window *window) +{ + debug_os2("Enter"); + if (!window) + return -1; + + if (window->x != -1000) { + if (window->shaper->driverdata) + SDL_FreeShapeTree((SDL_ShapeTree **)window->shaper->driverdata); + + if (window->shaper->hasshape == SDL_TRUE) { + window->shaper->userx = window->x; + window->shaper->usery = window->y; + SDL_SetWindowPosition(window, -1000, -1000); + } + } + + return 0; +} + + +/* Frame buffer + */ +static void OS2_DestroyWindowFramebuffer(_THIS, SDL_Window *window) +{ + WINDATA *pWinData = (WINDATA *)window->driverdata; + + debug_os2("Enter"); + if (pWinData && pWinData->pVOData) + pWinData->pOutput->VideoBufFree(pWinData->pVOData); +} + +static int OS2_CreateWindowFramebuffer(_THIS, SDL_Window *window, + Uint32 *format, void **pixels, + int *pitch) +{ + WINDATA *pWinData = (WINDATA *)window->driverdata; + SDL_VideoDisplay *pSDLDisplay = SDL_GetDisplayForWindow(window); + SDL_DisplayMode *pSDLDisplayMode; + MODEDATA *pModeData; + ULONG ulWidth, ulHeight; + + debug_os2("Enter"); + if (!pSDLDisplay) { + debug_os2("No display for the window"); + return -1; + } + + pSDLDisplayMode = &pSDLDisplay->current_mode; + pModeData = (MODEDATA *)pSDLDisplayMode->driverdata; + if (!pModeData) + return SDL_SetError("No mode data for the display"); + + SDL_GetWindowSize(window, (int *)&ulWidth, (int *)&ulHeight); + debug_os2("Window size: %u x %u", ulWidth, ulHeight); + + *pixels = pWinData->pOutput->VideoBufAlloc( + pWinData->pVOData, ulWidth, ulHeight, pModeData->ulDepth, + pModeData->fccColorEncoding, (PULONG)pitch); + if (!*pixels) + return -1; + + *format = pSDLDisplayMode->format; + debug_os2("Pitch: %u, frame buffer: 0x%X.", *pitch, *pixels); + WinSendMsg(pWinData->hwnd, WM_VRNENABLED, 0, 0); + + return 0; +} + +static int OS2_UpdateWindowFramebuffer(_THIS, SDL_Window * window, + const SDL_Rect *rects, int numrects) +{ + WINDATA *pWinData = (WINDATA *)window->driverdata; + + return pWinData->pOutput->Update(pWinData->pVOData, pWinData->hwnd, + (SDL_Rect *)rects, (ULONG)numrects) + ? 0 : -1; +} + + +/* Clipboard + */ +static int OS2_SetClipboardText(_THIS, const char *text) +{ + SDL_VideoData *pVData = (SDL_VideoData *)_this->driverdata; + PSZ pszClipboard; + PSZ pszText = (!text)? NULL : OS2_UTF8ToSys(text); + ULONG cbText; + ULONG ulRC; + BOOL fSuccess; + + debug_os2("Enter"); + if (!pszText) + return -1; + cbText = SDL_strlen(pszText) + 1; + + ulRC = DosAllocSharedMem((PPVOID)&pszClipboard, 0, cbText, + PAG_COMMIT | PAG_READ | PAG_WRITE | + OBJ_GIVEABLE | OBJ_GETTABLE | OBJ_TILE); + if (ulRC != NO_ERROR) { + debug_os2("DosAllocSharedMem() failed, rc = %u", ulRC); + SDL_free(pszText); + return -1; + } + + SDL_memcpy(pszClipboard, pszText, cbText); + SDL_free(pszText); + + if (!WinOpenClipbrd(pVData->hab)) { + debug_os2("WinOpenClipbrd() failed"); + fSuccess = FALSE; + } else { + WinEmptyClipbrd(pVData->hab); + fSuccess = WinSetClipbrdData(pVData->hab, (ULONG)pszClipboard, CF_TEXT, CFI_POINTER); + if (!fSuccess) { + debug_os2("WinOpenClipbrd() failed"); + } + WinCloseClipbrd(pVData->hab); + } + + if (!fSuccess) { + DosFreeMem(pszClipboard); + return -1; + } + return 0; +} + +static char *OS2_GetClipboardText(_THIS) +{ + SDL_VideoData *pVData = (SDL_VideoData *)_this->driverdata; + PSZ pszClipboard = NULL; + + if (!WinOpenClipbrd(pVData->hab)) { + debug_os2("WinOpenClipbrd() failed"); + } else { + pszClipboard = (PSZ)WinQueryClipbrdData(pVData->hab, CF_TEXT); + if (pszClipboard != NULL) + pszClipboard = OS2_SysToUTF8(pszClipboard); + WinCloseClipbrd(pVData->hab); + } + + return (!pszClipboard) ? SDL_strdup("") : pszClipboard; +} + +static SDL_bool OS2_HasClipboardText(_THIS) +{ + SDL_VideoData *pVData = (SDL_VideoData *)_this->driverdata; + PSZ pszClipboard; + SDL_bool result; + + if (!WinOpenClipbrd(pVData->hab)) { + debug_os2("WinOpenClipbrd() failed"); + return SDL_FALSE; + } + + pszClipboard = (PSZ)WinQueryClipbrdData(pVData->hab, CF_TEXT); + result = (pszClipboard && *pszClipboard) ? SDL_TRUE : SDL_FALSE; + WinCloseClipbrd(pVData->hab); + + return result; +} + + +static int OS2_VideoInit(_THIS) +{ + SDL_VideoData *pVData; + PTIB tib; + PPIB pib; + + /* Create SDL video driver private data */ + pVData = SDL_calloc(1, sizeof(SDL_VideoData)); + if (!pVData) + return SDL_OutOfMemory(); + + /* Change process type code for use Win* API from VIO session */ + DosGetInfoBlocks(&tib, &pib); + if (pib->pib_ultype == 2 || pib->pib_ultype == 0) { + /* VIO windowable or fullscreen protect-mode session */ + pib->pib_ultype = 3; /* Presentation Manager protect-mode session */ + } + + /* PM initialization */ + pVData->hab = WinInitialize(0); + pVData->hmq = WinCreateMsgQueue(pVData->hab, 0); + if (pVData->hmq == NULLHANDLE) { + SDL_free(pVData); + return SDL_SetError("Message queue cannot be created."); + } + + if (!WinRegisterClass(pVData->hab, WIN_CLIENT_CLASS, wndProc, + CS_SIZEREDRAW | CS_MOVENOTIFY | CS_SYNCPAINT, + sizeof(SDL_VideoData*))) { + SDL_free(pVData); + return SDL_SetError("Window class not successfully registered."); + } + + if (SDL_strcasecmp(_this->name, OS2DRIVER_NAME_VMAN) == 0) + pVData->pOutput = &voVMan; + else + pVData->pOutput = &voDive; + + _this->driverdata = pVData; + + /* Add display */ + { + SDL_VideoDisplay stSDLDisplay; + SDL_DisplayMode stSDLDisplayMode; + DISPLAYDATA *pDisplayData; + MODEDATA *pModeData; + VIDEOOUTPUTINFO stVOInfo; + + if (!pVData->pOutput->QueryInfo(&stVOInfo)) { + SDL_free(pVData); + return SDL_SetError("Video mode query failed."); + } + + SDL_zero(stSDLDisplay); SDL_zero(stSDLDisplayMode); + + stSDLDisplayMode.format = _getSDLPixelFormat(stVOInfo.ulBPP, + stVOInfo.fccColorEncoding); + stSDLDisplayMode.w = stVOInfo.ulHorizResolution; + stSDLDisplayMode.h = stVOInfo.ulVertResolution; + stSDLDisplayMode.refresh_rate = 0; + stSDLDisplayMode.driverdata = NULL; + + pModeData = SDL_malloc(sizeof(MODEDATA)); + if (pModeData) { + pModeData->ulDepth = stVOInfo.ulBPP; + pModeData->fccColorEncoding = stVOInfo.fccColorEncoding; + pModeData->ulScanLineBytes = stVOInfo.ulScanLineSize; + stSDLDisplayMode.driverdata = pModeData; + } + + stSDLDisplay.name = "Primary"; + stSDLDisplay.desktop_mode = stSDLDisplayMode; + stSDLDisplay.current_mode = stSDLDisplayMode; + stSDLDisplay.driverdata = NULL; + stSDLDisplay.num_display_modes = 0; + + pDisplayData = SDL_malloc(sizeof(DISPLAYDATA)); + if (pDisplayData) { + HPS hps = WinGetPS(HWND_DESKTOP); + HDC hdc = GpiQueryDevice(hps); + + /* May be we can use CAPS_HORIZONTAL_RESOLUTION and + * CAPS_VERTICAL_RESOLUTION - pels per meter? */ + DevQueryCaps(hdc, CAPS_HORIZONTAL_FONT_RES, 1, + (PLONG)&pDisplayData->ulDPIHor); + DevQueryCaps(hdc, CAPS_VERTICAL_FONT_RES, 1, + (PLONG)&pDisplayData->ulDPIVer); + WinReleasePS(hps); + + pDisplayData->ulDPIDiag = SDL_ComputeDiagonalDPI( + stVOInfo.ulHorizResolution, stVOInfo.ulVertResolution, + (float)stVOInfo.ulHorizResolution / pDisplayData->ulDPIHor, + (float)stVOInfo.ulVertResolution / pDisplayData->ulDPIVer); + + stSDLDisplayMode.driverdata = pDisplayData; + } + + SDL_AddVideoDisplay(&stSDLDisplay, SDL_FALSE); + } + + OS2_InitMouse(_this, pVData->hab); + + return 0; +} + +static void OS2_VideoQuit(_THIS) +{ + SDL_VideoData *pVData = (SDL_VideoData *)_this->driverdata; + + OS2_QuitMouse(_this); + + WinDestroyMsgQueue(pVData->hmq); + WinTerminate(pVData->hab); + + /* our caller SDL_VideoQuit() already frees display_modes, driverdata, etc. */ +} + +static int OS2_GetDisplayBounds(_THIS, SDL_VideoDisplay *display, + SDL_Rect *rect) +{ + debug_os2("Enter"); + + rect->x = 0; + rect->y = 0; + rect->w = display->desktop_mode.w; + rect->h = display->desktop_mode.h; + + return 0; +} + +static int OS2_GetDisplayDPI(_THIS, SDL_VideoDisplay *display, float *ddpi, + float *hdpi, float *vdpi) +{ + DISPLAYDATA *pDisplayData = (DISPLAYDATA *)display->driverdata; + + debug_os2("Enter"); + if (!pDisplayData) + return -1; + + if (ddpi) + *hdpi = pDisplayData->ulDPIDiag; + if (hdpi) + *hdpi = pDisplayData->ulDPIHor; + if (vdpi) + *vdpi = pDisplayData->ulDPIVer; + + return 0; +} + +static void OS2_GetDisplayModes(_THIS, SDL_VideoDisplay *display) +{ + SDL_DisplayMode mode; + + debug_os2("Enter"); + SDL_copyp(&mode, &display->current_mode); + mode.driverdata = (MODEDATA *) SDL_malloc(sizeof(MODEDATA)); + if (!mode.driverdata) return; /* yikes.. */ + SDL_memcpy(mode.driverdata, display->current_mode.driverdata, sizeof(MODEDATA)); + SDL_AddDisplayMode(display, &mode); +} + +static int OS2_SetDisplayMode(_THIS, SDL_VideoDisplay *display, + SDL_DisplayMode *mode) +{ + debug_os2("Enter"); + return -1; +} + + +static void OS2_DeleteDevice(SDL_VideoDevice *device) +{ + SDL_free(device); +} + +static SDL_VideoDevice *OS2_CreateDevice(void) +{ + SDL_VideoDevice *device; + + /* Initialize all variables that we clean on shutdown */ + device = (SDL_VideoDevice *)SDL_calloc(1, sizeof(SDL_VideoDevice)); + if (!device) { + SDL_OutOfMemory(); + return NULL; + } + + /* Set the function pointers */ + device->VideoInit = OS2_VideoInit; + device->VideoQuit = OS2_VideoQuit; + device->GetDisplayBounds = OS2_GetDisplayBounds; + device->GetDisplayDPI = OS2_GetDisplayDPI; + device->GetDisplayModes = OS2_GetDisplayModes; + device->SetDisplayMode = OS2_SetDisplayMode; + device->PumpEvents = OS2_PumpEvents; + device->CreateSDLWindow = OS2_CreateWindow; + device->CreateSDLWindowFrom = OS2_CreateWindowFrom; + device->DestroyWindow = OS2_DestroyWindow; + device->SetWindowTitle = OS2_SetWindowTitle; + device->SetWindowIcon = OS2_SetWindowIcon; + device->SetWindowPosition = OS2_SetWindowPosition; + device->SetWindowSize = OS2_SetWindowSize; + device->ShowWindow = OS2_ShowWindow; + device->HideWindow = OS2_HideWindow; + device->RaiseWindow = OS2_RaiseWindow; + device->MaximizeWindow = OS2_MaximizeWindow; + device->MinimizeWindow = OS2_MinimizeWindow; + device->RestoreWindow = OS2_RestoreWindow; + device->SetWindowBordered = OS2_SetWindowBordered; + device->SetWindowFullscreen = OS2_SetWindowFullscreen; + device->GetWindowWMInfo = OS2_GetWindowWMInfo; + device->OnWindowEnter = OS2_OnWindowEnter; + device->SetWindowHitTest = OS2_SetWindowHitTest; + device->SetWindowMouseGrab = OS2_SetWindowMouseGrab; + device->CreateWindowFramebuffer = OS2_CreateWindowFramebuffer; + device->UpdateWindowFramebuffer = OS2_UpdateWindowFramebuffer; + device->DestroyWindowFramebuffer = OS2_DestroyWindowFramebuffer; + + device->SetClipboardText = OS2_SetClipboardText; + device->GetClipboardText = OS2_GetClipboardText; + device->HasClipboardText = OS2_HasClipboardText; + + device->shape_driver.CreateShaper = OS2_CreateShaper; + device->shape_driver.SetWindowShape = OS2_SetWindowShape; + device->shape_driver.ResizeWindowShape = OS2_ResizeWindowShape; + + device->free = OS2_DeleteDevice; + + return device; +} + +static SDL_VideoDevice *OS2DIVE_CreateDevice(void) +{ + VIDEOOUTPUTINFO stVOInfo; + if (!voDive.QueryInfo(&stVOInfo)) { + return NULL; + } + return OS2_CreateDevice(); +} + +static SDL_VideoDevice *OS2VMAN_CreateDevice(void) +{ + VIDEOOUTPUTINFO stVOInfo; + if (!voVMan.QueryInfo(&stVOInfo)) { + return NULL; + } + return OS2_CreateDevice(); +} + + +/* DIVE and VMAN bootstraps both call the same OS2_CreateDevice() function. + * Video output system will be selected in OS2_VideoInit() by driver name. */ +VideoBootStrap OS2DIVE_bootstrap = +{ + OS2DRIVER_NAME_DIVE, "OS/2 video driver", + OS2DIVE_CreateDevice, + OS2_ShowMessageBox +}; +VideoBootStrap OS2VMAN_bootstrap = +{ + OS2DRIVER_NAME_VMAN, "OS/2 video driver", + OS2VMAN_CreateDevice, + OS2_ShowMessageBox +}; + +#endif /* SDL_VIDEO_DRIVER_OS2 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/os2/SDL_os2video.h b/SDL2-2.30.5/src/video/os2/SDL_os2video.h new file mode 100644 index 0000000..0f9f379 --- /dev/null +++ b/SDL2-2.30.5/src/video/os2/SDL_os2video.h @@ -0,0 +1,82 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifndef SDL_os2video_h_ +#define SDL_os2video_h_ + +#include "../SDL_sysvideo.h" +#include "../../core/os2/SDL_os2.h" + +#define INCL_DOS +#define INCL_DOSERRORS +#define INCL_DOSPROCESS +#define INCL_WIN +#define INCL_GPI +#define INCL_OS2MM +#define INCL_DOSMEMMGR +#include + +#include "SDL_os2mouse.h" +#include "SDL_os2output.h" + +typedef struct SDL_VideoData { + HAB hab; + HMQ hmq; + OS2VIDEOOUTPUT *pOutput; /* Video output routines */ +} SDL_VideoData; + +typedef struct _WINDATA { + SDL_Window *window; + OS2VIDEOOUTPUT *pOutput; /* Video output routines */ + HWND hwndFrame; + HWND hwnd; + PFNWP fnUserWndProc; + PFNWP fnWndFrameProc; + + PVODATA pVOData; /* Video output data */ + + HRGN hrgnShape; + HPOINTER hptrIcon; + RECTL rectlBeforeFS; + + LONG lSkipWMSize; + LONG lSkipWMMove; + LONG lSkipWMMouseMove; + LONG lSkipWMVRNEnabled; + LONG lSkipWMAdjustFramePos; +} WINDATA; + +typedef struct _DISPLAYDATA { + ULONG ulDPIHor; + ULONG ulDPIVer; + ULONG ulDPIDiag; +} DISPLAYDATA; + +typedef struct _MODEDATA { + ULONG ulDepth; + ULONG fccColorEncoding; + ULONG ulScanLineBytes; +} MODEDATA; + +#endif /* SDL_os2video_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/os2/SDL_os2vman.c b/SDL2-2.30.5/src/video/os2/SDL_os2vman.c new file mode 100644 index 0000000..5945e8e --- /dev/null +++ b/SDL2-2.30.5/src/video/os2/SDL_os2vman.c @@ -0,0 +1,483 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_sysvideo.h" + +#define INCL_DOSERRORS +#define INCL_DOSPROCESS +#define INCL_DOSMODULEMGR +#define INCL_WIN +#define INCL_GPI +#define INCL_GPIBITMAPS /* GPI bit map functions */ +#include +#include "SDL_os2output.h" +#include "SDL_os2video.h" + +#include "SDL_gradd.h" + +typedef struct _VODATA { + PVOID pBuffer; + HRGN hrgnVisible; + ULONG ulBPP; + ULONG ulScanLineSize; + ULONG ulWidth; + ULONG ulHeight; + ULONG ulScreenHeight; + ULONG ulScreenBytesPerLine; + RECTL rectlWin; + + PRECTL pRectl; + ULONG cRectl; + PBLTRECT pBltRect; + ULONG cBltRect; +} VODATA; + +static BOOL voQueryInfo(VIDEOOUTPUTINFO *pInfo); +static PVODATA voOpen(); +static VOID voClose(PVODATA pVOData); +static BOOL voSetVisibleRegion(PVODATA pVOData, HWND hwnd, + SDL_DisplayMode *pSDLDisplayMode, + HRGN hrgnShape, BOOL fVisible); +static PVOID voVideoBufAlloc(PVODATA pVOData, ULONG ulWidth, ULONG ulHeight, + ULONG ulBPP, ULONG fccColorEncoding, + PULONG pulScanLineSize); +static VOID voVideoBufFree(PVODATA pVOData); +static BOOL voUpdate(PVODATA pVOData, HWND hwnd, SDL_Rect *pSDLRects, + ULONG cSDLRects); + +OS2VIDEOOUTPUT voVMan = { + voQueryInfo, + voOpen, + voClose, + voSetVisibleRegion, + voVideoBufAlloc, + voVideoBufFree, + voUpdate +}; + + +static HMODULE hmodVMan = NULLHANDLE; +static FNVMIENTRY *pfnVMIEntry = NULL; +static ULONG ulVRAMAddress = 0; + +static VOID APIENTRY ExitVMan(VOID) +{ + if (ulVRAMAddress != 0 && hmodVMan != NULLHANDLE) { + pfnVMIEntry(0, VMI_CMD_TERMPROC, NULL, NULL); + DosFreeModule(hmodVMan); + } + + DosExitList(EXLST_EXIT, (PFNEXITLIST)NULL); +} + +static BOOL _vmanInit(void) +{ + ULONG ulRC; + CHAR acBuf[256]; + INITPROCOUT stInitProcOut; + + if (hmodVMan != NULLHANDLE) /* already initialized */ + return TRUE; + + /* Load vman.dll */ + ulRC = DosLoadModule(acBuf, sizeof(acBuf), "VMAN", &hmodVMan); + if (ulRC != NO_ERROR) { + debug_os2("Could not load VMAN.DLL, rc = %u : %s", ulRC, acBuf); + hmodVMan = NULLHANDLE; + return FALSE; + } + + /* Get VMIEntry */ + ulRC = DosQueryProcAddr(hmodVMan, 0L, "VMIEntry", (PFN *)&pfnVMIEntry); + if (ulRC != NO_ERROR) { + debug_os2("Could not query address of VMIEntry from VMAN.DLL (Err: %lu)", ulRC); + DosFreeModule(hmodVMan); + hmodVMan = NULLHANDLE; + return FALSE; + } + + /* VMAN initialization */ + stInitProcOut.ulLength = sizeof(stInitProcOut); + ulRC = pfnVMIEntry(0, VMI_CMD_INITPROC, NULL, &stInitProcOut); + if (ulRC != RC_SUCCESS) { + debug_os2("Could not initialize VMAN for this process"); + pfnVMIEntry = NULL; + DosFreeModule(hmodVMan); + hmodVMan = NULLHANDLE; + return FALSE; + } + + /* Store video memory virtual address */ + ulVRAMAddress = stInitProcOut.ulVRAMVirt; + /* We use exit list for VMI_CMD_TERMPROC */ + if (DosExitList(EXLST_ADD | 0x00001000, (PFNEXITLIST)ExitVMan) != NO_ERROR) { + debug_os2("DosExitList() failed"); + } + + return TRUE; +} + +static PRECTL _getRectlArray(PVODATA pVOData, ULONG cRects) +{ + PRECTL pRectl; + + if (pVOData->cRectl >= cRects) + return pVOData->pRectl; + + pRectl = SDL_realloc(pVOData->pRectl, cRects * sizeof(RECTL)); + if (!pRectl) + return NULL; + + pVOData->pRectl = pRectl; + pVOData->cRectl = cRects; + return pRectl; +} + +static PBLTRECT _getBltRectArray(PVODATA pVOData, ULONG cRects) +{ + PBLTRECT pBltRect; + + if (pVOData->cBltRect >= cRects) + return pVOData->pBltRect; + + pBltRect = SDL_realloc(pVOData->pBltRect, cRects * sizeof(BLTRECT)); + if (!pBltRect) + return NULL; + + pVOData->pBltRect = pBltRect; + pVOData->cBltRect = cRects; + return pBltRect; +} + + +static BOOL voQueryInfo(VIDEOOUTPUTINFO *pInfo) +{ + ULONG ulRC; + GDDMODEINFO sCurModeInfo; + + if (!_vmanInit()) + return FALSE; + + /* Query current (desktop) mode */ + ulRC = pfnVMIEntry(0, VMI_CMD_QUERYCURRENTMODE, NULL, &sCurModeInfo); + if (ulRC != RC_SUCCESS) { + debug_os2("Could not query desktop video mode."); + return FALSE; + } + + pInfo->ulBPP = sCurModeInfo.ulBpp; + pInfo->ulHorizResolution = sCurModeInfo.ulHorizResolution; + pInfo->ulVertResolution = sCurModeInfo.ulVertResolution; + pInfo->ulScanLineSize = sCurModeInfo.ulScanLineSize; + pInfo->fccColorEncoding = sCurModeInfo.fccColorEncoding; + + return TRUE; +} + +static PVODATA voOpen(void) +{ + PVODATA pVOData; + + if (!_vmanInit()) + return NULL; + + pVOData = SDL_calloc(1, sizeof(VODATA)); + if (!pVOData) { + SDL_OutOfMemory(); + return NULL; + } + + return pVOData; +} + +static VOID voClose(PVODATA pVOData) +{ + if (pVOData->pRectl) + SDL_free(pVOData->pRectl); + + if (pVOData->pBltRect) + SDL_free(pVOData->pBltRect); + + voVideoBufFree(pVOData); +} + +static BOOL voSetVisibleRegion(PVODATA pVOData, HWND hwnd, + SDL_DisplayMode *pSDLDisplayMode, + HRGN hrgnShape, BOOL fVisible) +{ + HPS hps; + BOOL fSuccess = FALSE; + + hps = WinGetPS(hwnd); + + if (pVOData->hrgnVisible != NULLHANDLE) { + GpiDestroyRegion(hps, pVOData->hrgnVisible); + pVOData->hrgnVisible = NULLHANDLE; + } + + if (fVisible) { + /* Query visible rectangles */ + pVOData->hrgnVisible = GpiCreateRegion(hps, 0, NULL); + if (pVOData->hrgnVisible == NULLHANDLE) { + SDL_SetError("GpiCreateRegion() failed"); + } else { + if (WinQueryVisibleRegion(hwnd, pVOData->hrgnVisible) == RGN_ERROR) { + GpiDestroyRegion(hps, pVOData->hrgnVisible); + pVOData->hrgnVisible = NULLHANDLE; + } else { + if (hrgnShape != NULLHANDLE) + GpiCombineRegion(hps, pVOData->hrgnVisible, pVOData->hrgnVisible, + hrgnShape, CRGN_AND); + fSuccess = TRUE; + } + } + + WinQueryWindowRect(hwnd, &pVOData->rectlWin); + WinMapWindowPoints(hwnd, HWND_DESKTOP, (PPOINTL)&pVOData->rectlWin, 2); + + if (pSDLDisplayMode) { + pVOData->ulScreenHeight = pSDLDisplayMode->h; + pVOData->ulScreenBytesPerLine = + ((MODEDATA *)pSDLDisplayMode->driverdata)->ulScanLineBytes; + } + } + + WinReleasePS(hps); + + return fSuccess; +} + +static PVOID voVideoBufAlloc(PVODATA pVOData, ULONG ulWidth, ULONG ulHeight, + ULONG ulBPP, ULONG fccColorEncoding, + PULONG pulScanLineSize) +{ + ULONG ulRC; + ULONG ulScanLineSize = ulWidth * (ulBPP >> 3); + + /* Destroy previous buffer */ + voVideoBufFree(pVOData); + + if (ulWidth == 0 || ulHeight == 0 || ulBPP == 0) + return NULL; + + /* Bytes per line */ + ulScanLineSize = (ulScanLineSize + 3) & ~3; /* 4-byte aligning */ + *pulScanLineSize = ulScanLineSize; + + ulRC = DosAllocMem(&pVOData->pBuffer, + (ulHeight * ulScanLineSize) + sizeof(ULONG), + PAG_COMMIT | PAG_EXECUTE | PAG_READ | PAG_WRITE); + if (ulRC != NO_ERROR) { + debug_os2("DosAllocMem(), rc = %u", ulRC); + return NULL; + } + + pVOData->ulBPP = ulBPP; + pVOData->ulScanLineSize = ulScanLineSize; + pVOData->ulWidth = ulWidth; + pVOData->ulHeight = ulHeight; + + return pVOData->pBuffer; +} + +static VOID voVideoBufFree(PVODATA pVOData) +{ + ULONG ulRC; + + if (!pVOData->pBuffer) + return; + + ulRC = DosFreeMem(pVOData->pBuffer); + if (ulRC != NO_ERROR) { + debug_os2("DosFreeMem(), rc = %u", ulRC); + } else { + pVOData->pBuffer = NULL; + } +} + +static BOOL voUpdate(PVODATA pVOData, HWND hwnd, SDL_Rect *pSDLRects, + ULONG cSDLRects) +{ + PRECTL prectlDst, prectlScan; + HPS hps; + HRGN hrgnUpdate; + RGNRECT rgnCtl; + SDL_Rect stSDLRectDef; + BMAPINFO bmiSrc; + BMAPINFO bmiDst; + PPOINTL pptlSrcOrg; + PBLTRECT pbrDst; + HWREQIN sHWReqIn; + BITBLTINFO sBitbltInfo; + ULONG ulIdx; + + if (!pVOData->pBuffer) + return FALSE; + + if (pVOData->hrgnVisible == NULLHANDLE) + return TRUE; + + bmiSrc.ulLength = sizeof(BMAPINFO); + bmiSrc.ulType = BMAP_MEMORY; + bmiSrc.ulWidth = pVOData->ulWidth; + bmiSrc.ulHeight = pVOData->ulHeight; + bmiSrc.ulBpp = pVOData->ulBPP; + bmiSrc.ulBytesPerLine = pVOData->ulScanLineSize; + bmiSrc.pBits = (PBYTE)pVOData->pBuffer; + + bmiDst.ulLength = sizeof(BMAPINFO); + bmiDst.ulType = BMAP_VRAM; + bmiDst.pBits = (PBYTE)ulVRAMAddress; + bmiDst.ulWidth = bmiSrc.ulWidth; + bmiDst.ulHeight = bmiSrc.ulHeight; + bmiDst.ulBpp = bmiSrc.ulBpp; + bmiDst.ulBytesPerLine = pVOData->ulScreenBytesPerLine; + + /* List of update rectangles. This is the intersection of requested + * rectangles and visible rectangles. */ + if (cSDLRects == 0) { + /* Full update requested */ + stSDLRectDef.x = 0; + stSDLRectDef.y = 0; + stSDLRectDef.w = bmiSrc.ulWidth; + stSDLRectDef.h = bmiSrc.ulHeight; + pSDLRects = &stSDLRectDef; + cSDLRects = 1; + } + + /* Make list of destination rectangles (prectlDst) list from the source + * list (prectl). */ + prectlDst = _getRectlArray(pVOData, cSDLRects); + if (!prectlDst) { + debug_os2("Not enough memory"); + return FALSE; + } + prectlScan = prectlDst; + for (ulIdx = 0; ulIdx < cSDLRects; ulIdx++, pSDLRects++, prectlScan++) { + prectlScan->xLeft = pSDLRects->x; + prectlScan->yTop = pVOData->ulHeight - pSDLRects->y; + prectlScan->xRight = prectlScan->xLeft + pSDLRects->w; + prectlScan->yBottom = prectlScan->yTop - pSDLRects->h; + } + + hps = WinGetPS(hwnd); + if (hps == NULLHANDLE) + return FALSE; + + /* Make destination region to update */ + hrgnUpdate = GpiCreateRegion(hps, cSDLRects, prectlDst); + /* "AND" on visible and destination regions, result is region to update */ + GpiCombineRegion(hps, hrgnUpdate, hrgnUpdate, pVOData->hrgnVisible, CRGN_AND); + + /* Get rectangles of the region to update */ + rgnCtl.ircStart = 1; + rgnCtl.crc = 0; + rgnCtl.ulDirection = 1; + rgnCtl.crcReturned = 0; + GpiQueryRegionRects(hps, hrgnUpdate, NULL, &rgnCtl, NULL); + if (rgnCtl.crcReturned == 0) { + GpiDestroyRegion(hps, hrgnUpdate); + WinReleasePS(hps); + return TRUE; + } + /* We don't need prectlDst, use it again to store update regions */ + prectlDst = _getRectlArray(pVOData, rgnCtl.crcReturned); + if (!prectlDst) { + debug_os2("Not enough memory"); + GpiDestroyRegion(hps, hrgnUpdate); + WinReleasePS(hps); + return FALSE; + } + rgnCtl.ircStart = 1; + rgnCtl.crc = rgnCtl.crcReturned; + rgnCtl.ulDirection = 1; + GpiQueryRegionRects(hps, hrgnUpdate, NULL, &rgnCtl, prectlDst); + GpiDestroyRegion(hps, hrgnUpdate); + WinReleasePS(hps); + cSDLRects = rgnCtl.crcReturned; + + /* Now cRect/prectlDst is a list of regions in window (update && visible) */ + + /* Make lists for blitting from update regions */ + pbrDst = _getBltRectArray(pVOData, cSDLRects); + if (!pbrDst) { + debug_os2("Not enough memory"); + return FALSE; + } + + prectlScan = prectlDst; + pptlSrcOrg = (PPOINTL)prectlDst; /* Yes, this memory block will be used again */ + for (ulIdx = 0; ulIdx < cSDLRects; ulIdx++, prectlScan++, pptlSrcOrg++) { + pbrDst[ulIdx].ulXOrg = pVOData->rectlWin.xLeft + prectlScan->xLeft; + pbrDst[ulIdx].ulYOrg = pVOData->ulScreenHeight - + (pVOData->rectlWin.yBottom + prectlScan->yTop); + pbrDst[ulIdx].ulXExt = prectlScan->xRight - prectlScan->xLeft; + pbrDst[ulIdx].ulYExt = prectlScan->yTop - prectlScan->yBottom; + pptlSrcOrg->x = prectlScan->xLeft; + pptlSrcOrg->y = bmiSrc.ulHeight - prectlScan->yTop; + } + pptlSrcOrg = (PPOINTL)prectlDst; + + /* Request HW */ + sHWReqIn.ulLength = sizeof(HWREQIN); + sHWReqIn.ulFlags = REQUEST_HW; + sHWReqIn.cScrChangeRects = 1; + sHWReqIn.arectlScreen = &pVOData->rectlWin; + if (pfnVMIEntry(0, VMI_CMD_REQUESTHW, &sHWReqIn, NULL) != RC_SUCCESS) { + debug_os2("pfnVMIEntry(,VMI_CMD_REQUESTHW,,) failed"); + sHWReqIn.cScrChangeRects = 0; /* for fail signal only */ + } else { + RECTL rclSrcBounds; + + rclSrcBounds.xLeft = 0; + rclSrcBounds.yBottom = 0; + rclSrcBounds.xRight = bmiSrc.ulWidth; + rclSrcBounds.yTop = bmiSrc.ulHeight; + + SDL_zero(sBitbltInfo); + sBitbltInfo.ulLength = sizeof(BITBLTINFO); + sBitbltInfo.ulBltFlags = BF_DEFAULT_STATE | BF_ROP_INCL_SRC | BF_PAT_HOLLOW; + sBitbltInfo.cBlits = cSDLRects; + sBitbltInfo.ulROP = ROP_SRCCOPY; + sBitbltInfo.pSrcBmapInfo = &bmiSrc; + sBitbltInfo.pDstBmapInfo = &bmiDst; + sBitbltInfo.prclSrcBounds = &rclSrcBounds; + sBitbltInfo.prclDstBounds = &pVOData->rectlWin; + sBitbltInfo.aptlSrcOrg = pptlSrcOrg; + sBitbltInfo.abrDst = pbrDst; + + /* Screen update */ + if (pfnVMIEntry(0, VMI_CMD_BITBLT, &sBitbltInfo, NULL) != RC_SUCCESS) { + debug_os2("pfnVMIEntry(,VMI_CMD_BITBLT,,) failed"); + sHWReqIn.cScrChangeRects = 0; /* for fail signal only */ + } + + /* Release HW */ + sHWReqIn.ulFlags = 0; + if (pfnVMIEntry(0, VMI_CMD_REQUESTHW, &sHWReqIn, NULL) != RC_SUCCESS) { + debug_os2("pfnVMIEntry(,VMI_CMD_REQUESTHW,,) failed"); + } + } + + return sHWReqIn.cScrChangeRects != 0; +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/pandora/SDL_pandora.c b/SDL2-2.30.5/src/video/pandora/SDL_pandora.c similarity index 88% rename from SDL2-2.0.12/src/video/pandora/SDL_pandora.c rename to SDL2-2.30.5/src/video/pandora/SDL_pandora.c index 8817e06..35e0623 100644 --- a/SDL2-2.0.12/src/video/pandora/SDL_pandora.c +++ b/SDL2-2.30.5/src/video/pandora/SDL_pandora.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_PANDORA +#ifdef SDL_VIDEO_DRIVER_PANDORA /* SDL internals */ #include "../SDL_sysvideo.h" @@ -41,46 +41,30 @@ static NativeWindowType hNativeWnd = 0; /* A handle to the window we will create. */ #endif -static int -PND_available(void) +static void PND_destroy(SDL_VideoDevice * device) { - return 1; -} - -static void -PND_destroy(SDL_VideoDevice * device) -{ - if (device->driverdata != NULL) { + if (device->driverdata) { SDL_free(device->driverdata); device->driverdata = NULL; } SDL_free(device); } -static SDL_VideoDevice * -PND_create() +static SDL_VideoDevice *PND_create(void) { SDL_VideoDevice *device; SDL_VideoData *phdata; - int status; - - /* Check if pandora could be initialized */ - status = PND_available(); - if (status == 0) { - /* PND could not be used */ - return NULL; - } /* Initialize SDL_VideoDevice structure */ device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice)); - if (device == NULL) { + if (!device) { SDL_OutOfMemory(); return NULL; } /* Initialize internal Pandora specific data */ phdata = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData)); - if (phdata == NULL) { + if (!phdata) { SDL_OutOfMemory(); SDL_free(device); return NULL; @@ -114,7 +98,6 @@ PND_create() device->MaximizeWindow = PND_maximizewindow; device->MinimizeWindow = PND_minimizewindow; device->RestoreWindow = PND_restorewindow; - device->SetWindowGrab = PND_setwindowgrab; device->DestroyWindow = PND_destroywindow; #if 0 device->GetWindowWMInfo = PND_getwindowwminfo; @@ -143,15 +126,14 @@ VideoBootStrap PND_bootstrap = { "pandora", "SDL Pandora Video Driver", #endif - PND_available, - PND_create + PND_create, + NULL /* no ShowMessageBox implementation */ }; /*****************************************************************************/ /* SDL Video and Display initialization/handling functions */ /*****************************************************************************/ -int -PND_videoinit(_THIS) +int PND_videoinit(_THIS) { SDL_VideoDisplay display; SDL_DisplayMode current_mode; @@ -173,31 +155,27 @@ PND_videoinit(_THIS) display.current_mode = current_mode; display.driverdata = NULL; - SDL_AddVideoDisplay(&display); + SDL_AddVideoDisplay(&display, SDL_FALSE); return 1; } -void -PND_videoquit(_THIS) +void PND_videoquit(_THIS) { } -void -PND_getdisplaymodes(_THIS, SDL_VideoDisplay * display) +void PND_getdisplaymodes(_THIS, SDL_VideoDisplay * display) { } -int -PND_setdisplaymode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) +int PND_setdisplaymode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) { return 0; } -int -PND_createwindow(_THIS, SDL_Window * window) +int PND_createwindow(_THIS, SDL_Window * window) { SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata; @@ -205,7 +183,7 @@ PND_createwindow(_THIS, SDL_Window * window) /* Allocate window internal data */ wdata = (SDL_WindowData *) SDL_calloc(1, sizeof(SDL_WindowData)); - if (wdata == NULL) { + if (!wdata) { return SDL_OutOfMemory(); } @@ -240,58 +218,42 @@ PND_createwindow(_THIS, SDL_Window * window) return 0; } -int -PND_createwindowfrom(_THIS, SDL_Window * window, const void *data) +int PND_createwindowfrom(_THIS, SDL_Window * window, const void *data) { return -1; } -void -PND_setwindowtitle(_THIS, SDL_Window * window) +void PND_setwindowtitle(_THIS, SDL_Window * window) { } -void -PND_setwindowicon(_THIS, SDL_Window * window, SDL_Surface * icon) +void PND_setwindowicon(_THIS, SDL_Window * window, SDL_Surface * icon) { } -void -PND_setwindowposition(_THIS, SDL_Window * window) +void PND_setwindowposition(_THIS, SDL_Window * window) { } -void -PND_setwindowsize(_THIS, SDL_Window * window) +void PND_setwindowsize(_THIS, SDL_Window * window) { } -void -PND_showwindow(_THIS, SDL_Window * window) +void PND_showwindow(_THIS, SDL_Window * window) { } -void -PND_hidewindow(_THIS, SDL_Window * window) +void PND_hidewindow(_THIS, SDL_Window * window) { } -void -PND_raisewindow(_THIS, SDL_Window * window) +void PND_raisewindow(_THIS, SDL_Window * window) { } -void -PND_maximizewindow(_THIS, SDL_Window * window) +void PND_maximizewindow(_THIS, SDL_Window * window) { } -void -PND_minimizewindow(_THIS, SDL_Window * window) +void PND_minimizewindow(_THIS, SDL_Window * window) { } -void -PND_restorewindow(_THIS, SDL_Window * window) +void PND_restorewindow(_THIS, SDL_Window * window) { } -void -PND_setwindowgrab(_THIS, SDL_Window * window, SDL_bool grabbed) -{ -} -void -PND_destroywindow(_THIS, SDL_Window * window) +void PND_destroywindow(_THIS, SDL_Window * window) { SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata; eglTerminate(phdata->egl_display); @@ -301,14 +263,13 @@ PND_destroywindow(_THIS, SDL_Window * window) /* SDL Window Manager function */ /*****************************************************************************/ #if 0 -SDL_bool -PND_getwindowwminfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info) +SDL_bool PND_getwindowwminfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info) { if (info->version.major <= SDL_MAJOR_VERSION) { return SDL_TRUE; } else { - SDL_SetError("application not compiled with SDL %d.%d", - SDL_MAJOR_VERSION, SDL_MINOR_VERSION); + SDL_SetError("application not compiled with SDL %d", + SDL_MAJOR_VERSION); return SDL_FALSE; } @@ -320,19 +281,18 @@ PND_getwindowwminfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info) /*****************************************************************************/ /* SDL OpenGL/OpenGL ES functions */ /*****************************************************************************/ -int -PND_gl_loadlibrary(_THIS, const char *path) +int PND_gl_loadlibrary(_THIS, const char *path) { /* Check if OpenGL ES library is specified for GF driver */ - if (path == NULL) { + if (!path) { path = SDL_getenv("SDL_OPENGL_LIBRARY"); - if (path == NULL) { + if (!path) { path = SDL_getenv("SDL_OPENGLES_LIBRARY"); } } /* Check if default library loading requested */ - if (path == NULL) { + if (!path) { /* Already linked with GF library which provides egl* subset of */ /* functions, use Common profile of OpenGL ES library by default */ #ifdef WIZ_GLES_LITE @@ -357,14 +317,13 @@ PND_gl_loadlibrary(_THIS, const char *path) return 0; } -void * -PND_gl_getprocaddres(_THIS, const char *proc) +void *PND_gl_getprocaddres(_THIS, const char *proc) { void *function_address; /* Try to get function address through the egl interface */ function_address = eglGetProcAddress(proc); - if (function_address != NULL) { + if (function_address) { return function_address; } @@ -372,7 +331,7 @@ PND_gl_getprocaddres(_THIS, const char *proc) if (_this->gl_config.dll_handle) { function_address = SDL_LoadFunction(_this->gl_config.dll_handle, proc); - if (function_address != NULL) { + if (function_address) { return function_address; } } @@ -382,8 +341,7 @@ PND_gl_getprocaddres(_THIS, const char *proc) return NULL; } -void -PND_gl_unloadlibrary(_THIS) +void PND_gl_unloadlibrary(_THIS) { SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata; @@ -398,8 +356,7 @@ PND_gl_unloadlibrary(_THIS) } } -SDL_GLContext -PND_gl_createcontext(_THIS, SDL_Window * window) +SDL_GLContext PND_gl_createcontext(_THIS, SDL_Window * window) { SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata; SDL_WindowData *wdata = (SDL_WindowData *) window->driverdata; @@ -616,16 +573,16 @@ PND_gl_createcontext(_THIS, SDL_Window * window) } #ifdef WIZ_GLES_LITE - if( !hNativeWnd ) { - hNativeWnd = (NativeWindowType)malloc(16*1024); - - if(!hNativeWnd) - printf( "Error: Wiz framebuffer allocatation failed\n" ); - else - printf( "SDL: Wiz framebuffer allocated: %X\n", hNativeWnd ); + if (!hNativeWnd) { + hNativeWnd = (NativeWindowType)SDL_malloc(16*1024); + if (!hNativeWnd) { + printf("Error: Wiz framebuffer allocatation failed\n"); + } else { + printf("SDL: Wiz framebuffer allocated: %X\n", hNativeWnd); + } } else { - printf( "SDL: Wiz framebuffer already allocated: %X\n", hNativeWnd ); + printf("SDL: Wiz framebuffer already allocated: %X\n", hNativeWnd); } wdata->gles_surface = @@ -703,8 +660,7 @@ PND_gl_createcontext(_THIS, SDL_Window * window) return wdata->gles_context; } -int -PND_gl_makecurrent(_THIS, SDL_Window * window, SDL_GLContext context) +int PND_gl_makecurrent(_THIS, SDL_Window * window, SDL_GLContext context) { SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata; SDL_WindowData *wdata; @@ -714,7 +670,7 @@ PND_gl_makecurrent(_THIS, SDL_Window * window, SDL_GLContext context) return SDL_SetError("PND: GF initialization failed, no OpenGL ES support"); } - if ((window == NULL) && (context == NULL)) { + if ((!window) && (!context)) { status = eglMakeCurrent(phdata->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); @@ -747,8 +703,7 @@ PND_gl_makecurrent(_THIS, SDL_Window * window, SDL_GLContext context) return 0; } -int -PND_gl_setswapinterval(_THIS, int interval) +int PND_gl_setswapinterval(_THIS, int interval) { SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata; EGLBoolean status; @@ -772,14 +727,12 @@ PND_gl_setswapinterval(_THIS, int interval) return SDL_SetError("PND: Cannot set swap interval"); } -int -PND_gl_getswapinterval(_THIS) +int PND_gl_getswapinterval(_THIS) { return ((SDL_VideoData *) _this->driverdata)->swapinterval; } -int -PND_gl_swapwindow(_THIS, SDL_Window * window) +int PND_gl_swapwindow(_THIS, SDL_Window * window) { SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata; SDL_WindowData *wdata = (SDL_WindowData *) window->driverdata; @@ -798,8 +751,7 @@ PND_gl_swapwindow(_THIS, SDL_Window * window) return 0; } -void -PND_gl_deletecontext(_THIS, SDL_GLContext context) +void PND_gl_deletecontext(_THIS, SDL_GLContext context) { SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata; EGLBoolean status; @@ -822,11 +774,10 @@ PND_gl_deletecontext(_THIS, SDL_GLContext context) } #ifdef WIZ_GLES_LITE - if( hNativeWnd != 0 ) - { - free(hNativeWnd); + if (hNativeWnd != 0) { + SDL_free(hNativeWnd); hNativeWnd = 0; - printf( "SDL: Wiz framebuffer released\n" ); + printf("SDL: Wiz framebuffer released\n"); } #endif diff --git a/SDL2-2.0.12/src/video/pandora/SDL_pandora.h b/SDL2-2.30.5/src/video/pandora/SDL_pandora.h similarity index 96% rename from SDL2-2.0.12/src/video/pandora/SDL_pandora.h rename to SDL2-2.30.5/src/video/pandora/SDL_pandora.h index 0d85691..43faa6a 100644 --- a/SDL2-2.0.12/src/video/pandora/SDL_pandora.h +++ b/SDL2-2.30.5/src/video/pandora/SDL_pandora.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -77,7 +77,6 @@ void PND_raisewindow(_THIS, SDL_Window * window); void PND_maximizewindow(_THIS, SDL_Window * window); void PND_minimizewindow(_THIS, SDL_Window * window); void PND_restorewindow(_THIS, SDL_Window * window); -void PND_setwindowgrab(_THIS, SDL_Window * window, SDL_bool grabbed); void PND_destroywindow(_THIS, SDL_Window * window); /* Window manager function */ diff --git a/SDL2-2.0.12/src/video/pandora/SDL_pandora_events.c b/SDL2-2.30.5/src/video/pandora/SDL_pandora_events.c similarity index 90% rename from SDL2-2.0.12/src/video/pandora/SDL_pandora_events.c rename to SDL2-2.30.5/src/video/pandora/SDL_pandora_events.c index 779a199..4d6ef6e 100644 --- a/SDL2-2.0.12/src/video/pandora/SDL_pandora_events.c +++ b/SDL2-2.30.5/src/video/pandora/SDL_pandora_events.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,15 +20,14 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_PANDORA +#ifdef SDL_VIDEO_DRIVER_PANDORA /* Being a null driver, there's no event stream. We just define stubs for most of the API. */ #include "../../events/SDL_events_c.h" -void -PND_PumpEvents(_THIS) +void PND_PumpEvents(_THIS) { /* Not implemented. */ } diff --git a/SDL2-2.0.12/src/video/pandora/SDL_pandora_events.h b/SDL2-2.30.5/src/video/pandora/SDL_pandora_events.h similarity index 94% rename from SDL2-2.0.12/src/video/pandora/SDL_pandora_events.h rename to SDL2-2.30.5/src/video/pandora/SDL_pandora_events.h index 399f69f..4753ff1 100644 --- a/SDL2-2.0.12/src/video/pandora/SDL_pandora_events.h +++ b/SDL2-2.30.5/src/video/pandora/SDL_pandora_events.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.30.5/src/video/ps2/SDL_ps2video.c b/SDL2-2.30.5/src/video/ps2/SDL_ps2video.c new file mode 100644 index 0000000..4e823fe --- /dev/null +++ b/SDL2-2.30.5/src/video/ps2/SDL_ps2video.c @@ -0,0 +1,135 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_PS2 + +/* PS2 SDL video driver implementation; this is just enough to make an + * SDL-based application THINK it's got a working video driver, for + * applications that call SDL_Init(SDL_INIT_VIDEO) when they don't need it, + * and also for use as a collection of stubs when porting SDL to a new + * platform for which you haven't yet written a valid video driver. + * + * This is also a great way to determine bottlenecks: if you think that SDL + * is a performance problem for a given platform, enable this driver, and + * then see if your application runs faster without video overhead. + * + * Initial work by Ryan C. Gordon (icculus@icculus.org). A good portion + * of this was cut-and-pasted from Stephane Peter's work in the AAlib + * SDL video driver. Renamed to "PS2" by Sam Lantinga. + */ + +#include "SDL_video.h" +#include "SDL_mouse.h" +#include "../SDL_sysvideo.h" +#include "../SDL_pixels_c.h" +#include "../../events/SDL_events_c.h" + +#include "SDL_ps2video.h" +#include "SDL_hints.h" + +/* PS2 driver bootstrap functions */ + +static int PS2_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode) +{ + return 0; +} + +static void PS2_DeleteDevice(SDL_VideoDevice *device) +{ + SDL_free(device); +} + +static int PS2_CreateWindow(_THIS, SDL_Window *window) +{ + SDL_SetKeyboardFocus(window); + + /* Window has been successfully created */ + return 0; +} + +static int PS2_VideoInit(_THIS) +{ + SDL_VideoDisplay display; + SDL_DisplayMode current_mode; + + SDL_zero(current_mode); + + current_mode.w = 640; + current_mode.h = 480; + current_mode.refresh_rate = 60; + + /* 32 bpp for default */ + current_mode.format = SDL_PIXELFORMAT_ABGR8888; + current_mode.driverdata = NULL; + + SDL_zero(display); + display.desktop_mode = current_mode; + display.current_mode = current_mode; + display.driverdata = NULL; + SDL_AddDisplayMode(&display, ¤t_mode); + + SDL_AddVideoDisplay(&display, SDL_FALSE); + + return 1; +} + +static void PS2_VideoQuit(_THIS) +{ +} + +static void PS2_PumpEvents(_THIS) +{ + /* do nothing. */ +} + +static SDL_VideoDevice *PS2_CreateDevice(void) +{ + SDL_VideoDevice *device; + + /* Initialize all variables that we clean on shutdown */ + device = (SDL_VideoDevice *)SDL_calloc(1, sizeof(SDL_VideoDevice)); + if (!device) { + SDL_OutOfMemory(); + return 0; + } + + /* Set the function pointers */ + device->VideoInit = PS2_VideoInit; + device->VideoQuit = PS2_VideoQuit; + device->SetDisplayMode = PS2_SetDisplayMode; + device->CreateSDLWindow = PS2_CreateWindow; + device->PumpEvents = PS2_PumpEvents; + device->free = PS2_DeleteDevice; + + return device; +} + +VideoBootStrap PS2_bootstrap = { + "PS2", + "PS2 Video Driver", + PS2_CreateDevice, + NULL /* no ShowMessageBox implementation */ +}; + +#endif /* SDL_VIDEO_DRIVER_PS2 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/ps2/SDL_ps2video.h b/SDL2-2.30.5/src/video/ps2/SDL_ps2video.h new file mode 100644 index 0000000..6bc13b8 --- /dev/null +++ b/SDL2-2.30.5/src/video/ps2/SDL_ps2video.h @@ -0,0 +1,42 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifndef SDL_ps2video_h_ +#define SDL_ps2video_h_ + +#include "../SDL_sysvideo.h" + +#include + +#include +#include + +#include + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeclaration-after-statement" +#include +#pragma GCC diagnostic pop + +#endif /* SDL_ps2video_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/psp/SDL_pspevents.c b/SDL2-2.30.5/src/video/psp/SDL_pspevents.c similarity index 69% rename from SDL2-2.0.12/src/video/psp/SDL_pspevents.c rename to SDL2-2.30.5/src/video/psp/SDL_pspevents.c index 37c7113..44b487f 100644 --- a/SDL2-2.0.12/src/video/psp/SDL_pspevents.c +++ b/SDL2-2.30.5/src/video/psp/SDL_pspevents.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,26 +20,27 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_PSP +#ifdef SDL_VIDEO_DRIVER_PSP /* Being a null driver, there's no event stream. We just define stubs for most of the API. */ #include "SDL.h" -#include "../../events/SDL_sysevents.h" #include "../../events/SDL_events_c.h" #include "../../events/SDL_keyboard_c.h" +#include "../SDL_sysvideo.h" #include "SDL_pspvideo.h" #include "SDL_pspevents_c.h" #include "SDL_keyboard.h" #include "../../thread/SDL_systhread.h" #include +#include #ifdef PSPIRKEYB #include #include -#define IRKBD_CONFIG_FILE NULL /* this will take ms0:/seplugins/pspirkeyb.ini */ +#define IRKBD_CONFIG_FILE NULL /* this will take ms0:/seplugins/pspirkeyb.ini */ static int irkbd_ready = 0; static SDL_Keycode keymap[256]; @@ -49,28 +50,29 @@ static enum PspHprmKeys hprm = 0; static SDL_sem *event_sem = NULL; static SDL_Thread *thread = NULL; static int running = 0; -static struct { +static struct +{ enum PspHprmKeys id; SDL_Keycode sym; } keymap_psp[] = { { PSP_HPRM_PLAYPAUSE, SDLK_F10 }, - { PSP_HPRM_FORWARD, SDLK_F11 }, - { PSP_HPRM_BACK, SDLK_F12 }, - { PSP_HPRM_VOL_UP, SDLK_F13 }, - { PSP_HPRM_VOL_DOWN, SDLK_F14 }, - { PSP_HPRM_HOLD, SDLK_F15 } + { PSP_HPRM_FORWARD, SDLK_F11 }, + { PSP_HPRM_BACK, SDLK_F12 }, + { PSP_HPRM_VOL_UP, SDLK_F13 }, + { PSP_HPRM_VOL_DOWN, SDLK_F14 }, + { PSP_HPRM_HOLD, SDLK_F15 } }; int EventUpdate(void *data) { while (running) { - SDL_SemWait(event_sem); - sceHprmPeekCurrentKey(&hprm); - SDL_SemPost(event_sem); - /* Delay 1/60th of a second */ - sceKernelDelayThread(1000000 / 60); - } - return 0; + SDL_SemWait(event_sem); + sceHprmPeekCurrentKey((u32 *)&hprm); + SDL_SemPost(event_sem); + /* Delay 1/60th of a second */ + sceKernelDelayThread(1000000 / 60); + } + return 0; } void PSP_PumpEvents(_THIS) @@ -79,7 +81,6 @@ void PSP_PumpEvents(_THIS) enum PspHprmKeys keys; enum PspHprmKeys changed; static enum PspHprmKeys old_keys = 0; - SDL_Keysym sym; SDL_SemWait(event_sem); keys = hprm; @@ -88,44 +89,33 @@ void PSP_PumpEvents(_THIS) /* HPRM Keyboard */ changed = old_keys ^ keys; old_keys = keys; - if(changed) { - for(i=0; i= 0) { - if((length % sizeof(SIrKeybScanCodeData)) == 0){ - count = length / sizeof(SIrKeybScanCodeData); - for( i=0; i < count; i++ ) { - unsigned char raw, pressed; - scanData=(SIrKeybScanCodeData*) buffer+i; - raw = scanData->raw; - pressed = scanData->pressed; - sym.scancode = raw; - sym.sym = keymap[raw]; - /* not tested */ - /* SDL_PrivateKeyboard(pressed?SDL_PRESSED:SDL_RELEASED, &sym); */ - SDL_SendKeyboardKey((keys & keymap_psp[i].id) ? - SDL_PRESSED : SDL_RELEASED, SDL_GetScancodeFromKey(keymap[raw])); - + if (pspIrKeybReadinput(buffer, &length) >= 0) { + if ((length % sizeof(SIrKeybScanCodeData)) == 0) { + count = length / sizeof(SIrKeybScanCodeData); + for (i = 0; i < count; i++) { + unsigned char raw, pressed; + scanData = (SIrKeybScanCodeData *)buffer + i; + raw = scanData->raw; + pressed = scanData->pressed; + sym.scancode = raw; + sym.sym = keymap[raw]; + /* not tested */ + /* SDL_PrivateKeyboard(pressed?SDL_PRESSED:SDL_RELEASED, &sym); */ + SDL_SendKeyboardKey((keys & keymap_psp[i].id) ? SDL_PRESSED : SDL_RELEASED, SDL_GetScancodeFromKey(keymap[raw])); } } } @@ -140,8 +130,9 @@ void PSP_InitOSKeymap(_THIS) { #ifdef PSPIRKEYB int i; - for (i=0; i + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -21,11 +21,9 @@ #include "SDL_pspvideo.h" -/* Variables and functions exported by SDL_sysevents.c to other parts - of the native video subsystem (SDL_sysvideo.c) -*/ extern void PSP_InitOSKeymap(_THIS); extern void PSP_PumpEvents(_THIS); +extern int PSP_EventInit(_THIS); +extern void PSP_EventQuit(_THIS); /* end of SDL_pspevents_c.h ... */ - diff --git a/SDL2-2.30.5/src/video/psp/SDL_pspgl.c b/SDL2-2.30.5/src/video/psp/SDL_pspgl.c new file mode 100644 index 0000000..7071091 --- /dev/null +++ b/SDL2-2.30.5/src/video/psp/SDL_pspgl.c @@ -0,0 +1,195 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_PSP + +#include +#include + +#include "SDL_error.h" +#include "SDL_pspvideo.h" +#include "SDL_pspgl_c.h" + +/*****************************************************************************/ +/* SDL OpenGL/OpenGL ES functions */ +/*****************************************************************************/ +#define EGLCHK(stmt) \ + do { \ + EGLint err; \ + \ + stmt; \ + err = eglGetError(); \ + if (err != EGL_SUCCESS) { \ + SDL_SetError("EGL error %d", err); \ + return 0; \ + } \ + } while (0) + +int PSP_GL_LoadLibrary(_THIS, const char *path) +{ + return 0; +} + +/* pspgl doesn't provide this call, so stub it out since SDL requires it. +#define GLSTUB(func,params) void func params {} + +GLSTUB(glOrtho,(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, + GLdouble zNear, GLdouble zFar)) +*/ +void *PSP_GL_GetProcAddress(_THIS, const char *proc) +{ + return eglGetProcAddress(proc); +} + +void PSP_GL_UnloadLibrary(_THIS) +{ + eglTerminate(_this->gl_data->display); +} + +static EGLint width = 480; +static EGLint height = 272; + +SDL_GLContext PSP_GL_CreateContext(_THIS, SDL_Window *window) +{ + + SDL_WindowData *wdata = (SDL_WindowData *)window->driverdata; + + EGLint attribs[32]; + EGLDisplay display; + EGLContext context; + EGLSurface surface; + EGLConfig config; + EGLint num_configs; + int i; + + /* EGL init taken from glutCreateWindow() in PSPGL's glut.c. */ + EGLCHK(display = eglGetDisplay(0)); + EGLCHK(eglInitialize(display, NULL, NULL)); + wdata->uses_gles = SDL_TRUE; + window->flags |= SDL_WINDOW_FULLSCREEN; + + /* Setup the config based on SDL's current values. */ + i = 0; + attribs[i++] = EGL_RED_SIZE; + attribs[i++] = _this->gl_config.red_size; + attribs[i++] = EGL_GREEN_SIZE; + attribs[i++] = _this->gl_config.green_size; + attribs[i++] = EGL_BLUE_SIZE; + attribs[i++] = _this->gl_config.blue_size; + attribs[i++] = EGL_DEPTH_SIZE; + attribs[i++] = _this->gl_config.depth_size; + + if (_this->gl_config.alpha_size) { + attribs[i++] = EGL_ALPHA_SIZE; + attribs[i++] = _this->gl_config.alpha_size; + } + if (_this->gl_config.stencil_size) { + attribs[i++] = EGL_STENCIL_SIZE; + attribs[i++] = _this->gl_config.stencil_size; + } + + attribs[i++] = EGL_NONE; + + EGLCHK(eglChooseConfig(display, attribs, &config, 1, &num_configs)); + + if (num_configs == 0) { + SDL_SetError("No valid EGL configs for requested mode"); + return 0; + } + + EGLCHK(eglGetConfigAttrib(display, config, EGL_WIDTH, &width)); + EGLCHK(eglGetConfigAttrib(display, config, EGL_HEIGHT, &height)); + + EGLCHK(context = eglCreateContext(display, config, NULL, NULL)); + EGLCHK(surface = eglCreateWindowSurface(display, config, 0, NULL)); + EGLCHK(eglMakeCurrent(display, surface, surface, context)); + + _this->gl_data->display = display; + _this->gl_data->context = context; + _this->gl_data->surface = surface; + + return context; +} + +int PSP_GL_MakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context) +{ + if (!eglMakeCurrent(_this->gl_data->display, _this->gl_data->surface, + _this->gl_data->surface, _this->gl_data->context)) { + return SDL_SetError("Unable to make EGL context current"); + } + return 0; +} + +int PSP_GL_SetSwapInterval(_THIS, int interval) +{ + EGLBoolean status; + status = eglSwapInterval(_this->gl_data->display, interval); + if (status == EGL_TRUE) { + /* Return success to upper level */ + _this->gl_data->swapinterval = interval; + return 0; + } + /* Failed to set swap interval */ + return SDL_SetError("Unable to set the EGL swap interval"); +} + +int PSP_GL_GetSwapInterval(_THIS) +{ + return _this->gl_data->swapinterval; +} + +int PSP_GL_SwapWindow(_THIS, SDL_Window *window) +{ + if (!eglSwapBuffers(_this->gl_data->display, _this->gl_data->surface)) { + return SDL_SetError("eglSwapBuffers() failed"); + } + return 0; +} + +void PSP_GL_DeleteContext(_THIS, SDL_GLContext context) +{ + SDL_VideoData *phdata = (SDL_VideoData *)_this->driverdata; + EGLBoolean status; + + if (phdata->egl_initialized != SDL_TRUE) { + SDL_SetError("PSP: GLES initialization failed, no OpenGL ES support"); + return; + } + + /* Check if OpenGL ES connection has been initialized */ + if (_this->gl_data->display != EGL_NO_DISPLAY) { + if (context != EGL_NO_CONTEXT) { + status = eglDestroyContext(_this->gl_data->display, context); + if (status != EGL_TRUE) { + /* Error during OpenGL ES context destroying */ + SDL_SetError("PSP: OpenGL ES context destroy error"); + return; + } + } + } + + return; +} + +#endif /* SDL_VIDEO_DRIVER_PSP */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/psp/SDL_pspgl_c.h b/SDL2-2.30.5/src/video/psp/SDL_pspgl_c.h similarity index 74% rename from SDL2-2.0.12/src/video/psp/SDL_pspgl_c.h rename to SDL2-2.30.5/src/video/psp/SDL_pspgl_c.h index a30a9bd..b302c8e 100644 --- a/SDL2-2.0.12/src/video/psp/SDL_pspgl_c.h +++ b/SDL2-2.30.5/src/video/psp/SDL_pspgl_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -22,33 +22,31 @@ #ifndef SDL_pspgl_c_h_ #define SDL_pspgl_c_h_ - #include #include #include "SDL_pspvideo.h" - -typedef struct SDL_GLDriverData { - EGLDisplay display; - EGLContext context; - EGLSurface surface; +typedef struct SDL_GLDriverData +{ + EGLDisplay display; + EGLContext context; + EGLSurface surface; uint32_t swapinterval; -}SDL_GLDriverData; +} SDL_GLDriverData; -extern void * PSP_GL_GetProcAddress(_THIS, const char *proc); -extern int PSP_GL_MakeCurrent(_THIS,SDL_Window * window, SDL_GLContext context); +extern void *PSP_GL_GetProcAddress(_THIS, const char *proc); +extern int PSP_GL_MakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context); extern void PSP_GL_SwapBuffers(_THIS); -extern int PSP_GL_SwapWindow(_THIS, SDL_Window * window); -extern SDL_GLContext PSP_GL_CreateContext(_THIS, SDL_Window * window); +extern int PSP_GL_SwapWindow(_THIS, SDL_Window *window); +extern SDL_GLContext PSP_GL_CreateContext(_THIS, SDL_Window *window); extern int PSP_GL_LoadLibrary(_THIS, const char *path); extern void PSP_GL_UnloadLibrary(_THIS); extern int PSP_GL_SetSwapInterval(_THIS, int interval); extern int PSP_GL_GetSwapInterval(_THIS); - #endif /* SDL_pspgl_c_h_ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/psp/SDL_pspmouse.c b/SDL2-2.30.5/src/video/psp/SDL_pspmouse.c similarity index 91% rename from SDL2-2.0.12/src/video/psp/SDL_pspmouse.c rename to SDL2-2.30.5/src/video/psp/SDL_pspmouse.c index 61f00b1..57fc45c 100644 --- a/SDL2-2.0.12/src/video/psp/SDL_pspmouse.c +++ b/SDL2-2.30.5/src/video/psp/SDL_pspmouse.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_PSP +#ifdef SDL_VIDEO_DRIVER_PSP #include @@ -30,9 +30,9 @@ #include "SDL_pspmouse_c.h" - /* The implementation dependent data for the window manager cursor */ -struct WMcursor { +struct WMcursor +{ int unused; }; diff --git a/SDL2-2.0.12/src/video/psp/SDL_pspmouse_c.h b/SDL2-2.30.5/src/video/psp/SDL_pspmouse_c.h similarity index 93% rename from SDL2-2.0.12/src/video/psp/SDL_pspmouse_c.h rename to SDL2-2.30.5/src/video/psp/SDL_pspmouse_c.h index e47ba25..a961232 100644 --- a/SDL2-2.0.12/src/video/psp/SDL_pspmouse_c.h +++ b/SDL2-2.30.5/src/video/psp/SDL_pspmouse_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/video/psp/SDL_pspvideo.c b/SDL2-2.30.5/src/video/psp/SDL_pspvideo.c similarity index 67% rename from SDL2-2.0.12/src/video/psp/SDL_pspvideo.c rename to SDL2-2.30.5/src/video/psp/SDL_pspvideo.c index 0688cf8..9631904 100644 --- a/SDL2-2.0.12/src/video/psp/SDL_pspvideo.c +++ b/SDL2-2.30.5/src/video/psp/SDL_pspvideo.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -21,7 +21,7 @@ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_PSP +#ifdef SDL_VIDEO_DRIVER_PSP /* SDL internals */ #include "../SDL_sysvideo.h" @@ -33,7 +33,6 @@ #include "../../events/SDL_keyboard_c.h" - /* PSP declarations */ #include "SDL_pspvideo.h" #include "SDL_pspevents_c.h" @@ -42,54 +41,39 @@ /* unused static SDL_bool PSP_initialized = SDL_FALSE; */ -static int -PSP_Available(void) -{ - return 1; -} -static void -PSP_Destroy(SDL_VideoDevice * device) +static void PSP_Destroy(SDL_VideoDevice *device) { -/* SDL_VideoData *phdata = (SDL_VideoData *) device->driverdata; */ + /* SDL_VideoData *phdata = (SDL_VideoData *) device->driverdata; */ - if (device->driverdata != NULL) { + if (device->driverdata) { device->driverdata = NULL; } } -static SDL_VideoDevice * -PSP_Create() +static SDL_VideoDevice *PSP_Create() { SDL_VideoDevice *device; SDL_VideoData *phdata; SDL_GLDriverData *gldata; - int status; - - /* Check if PSP could be initialized */ - status = PSP_Available(); - if (status == 0) { - /* PSP could not be used */ - return NULL; - } /* Initialize SDL_VideoDevice structure */ - device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice)); - if (device == NULL) { + device = (SDL_VideoDevice *)SDL_calloc(1, sizeof(SDL_VideoDevice)); + if (!device) { SDL_OutOfMemory(); return NULL; } /* Initialize internal PSP specific data */ - phdata = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData)); - if (phdata == NULL) { + phdata = (SDL_VideoData *)SDL_calloc(1, sizeof(SDL_VideoData)); + if (!phdata) { SDL_OutOfMemory(); SDL_free(device); return NULL; } - gldata = (SDL_GLDriverData *) SDL_calloc(1, sizeof(SDL_GLDriverData)); - if (gldata == NULL) { + gldata = (SDL_GLDriverData *)SDL_calloc(1, sizeof(SDL_GLDriverData)); + if (!gldata) { SDL_OutOfMemory(); SDL_free(device); SDL_free(phdata); @@ -101,7 +85,6 @@ PSP_Create() phdata->egl_initialized = SDL_TRUE; - /* Setup amount of available displays */ device->num_displays = 0; @@ -125,7 +108,6 @@ PSP_Create() device->MaximizeWindow = PSP_MaximizeWindow; device->MinimizeWindow = PSP_MinimizeWindow; device->RestoreWindow = PSP_RestoreWindow; - device->SetWindowGrab = PSP_SetWindowGrab; device->DestroyWindow = PSP_DestroyWindow; #if 0 device->GetWindowWMInfo = PSP_GetWindowWMInfo; @@ -152,19 +134,22 @@ PSP_Create() VideoBootStrap PSP_bootstrap = { "PSP", "PSP Video Driver", - PSP_Available, - PSP_Create + PSP_Create, + NULL /* no ShowMessageBox implementation */ }; /*****************************************************************************/ /* SDL Video and Display initialization/handling functions */ /*****************************************************************************/ -int -PSP_VideoInit(_THIS) +int PSP_VideoInit(_THIS) { SDL_VideoDisplay display; SDL_DisplayMode current_mode; + if (PSP_EventInit(_this) == -1) { + return -1; /* error string would already be set */ + } + SDL_zero(current_mode); current_mode.w = 480; @@ -173,7 +158,6 @@ PSP_VideoInit(_THIS) current_mode.refresh_rate = 60; /* 32 bpp for default */ current_mode.format = SDL_PIXELFORMAT_ABGR8888; - current_mode.driverdata = NULL; SDL_zero(display); @@ -181,112 +165,99 @@ PSP_VideoInit(_THIS) display.current_mode = current_mode; display.driverdata = NULL; - SDL_AddVideoDisplay(&display); + SDL_AddDisplayMode(&display, ¤t_mode); - return 1; + /* 16 bpp secondary mode */ + current_mode.format = SDL_PIXELFORMAT_BGR565; + display.desktop_mode = current_mode; + display.current_mode = current_mode; + SDL_AddDisplayMode(&display, ¤t_mode); + + SDL_AddVideoDisplay(&display, SDL_FALSE); + + return 0; } -void -PSP_VideoQuit(_THIS) +void PSP_VideoQuit(_THIS) { - + PSP_EventQuit(_this); } -void -PSP_GetDisplayModes(_THIS, SDL_VideoDisplay * display) +void PSP_GetDisplayModes(_THIS, SDL_VideoDisplay *display) { - } -int -PSP_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) +int PSP_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode) { return 0; } -#define EGLCHK(stmt) \ - do { \ - EGLint err; \ - \ - stmt; \ - err = eglGetError(); \ - if (err != EGL_SUCCESS) { \ - SDL_SetError("EGL error %d", err); \ - return 0; \ - } \ +#define EGLCHK(stmt) \ + do { \ + EGLint err; \ + \ + stmt; \ + err = eglGetError(); \ + if (err != EGL_SUCCESS) { \ + SDL_SetError("EGL error %d", err); \ + return 0; \ + } \ } while (0) -int -PSP_CreateWindow(_THIS, SDL_Window * window) +int PSP_CreateWindow(_THIS, SDL_Window *window) { SDL_WindowData *wdata; /* Allocate window internal data */ - wdata = (SDL_WindowData *) SDL_calloc(1, sizeof(SDL_WindowData)); - if (wdata == NULL) { + wdata = (SDL_WindowData *)SDL_calloc(1, sizeof(SDL_WindowData)); + if (!wdata) { return SDL_OutOfMemory(); } /* Setup driver data for this window */ window->driverdata = wdata; + SDL_SetKeyboardFocus(window); /* Window has been successfully created */ return 0; } -int -PSP_CreateWindowFrom(_THIS, SDL_Window * window, const void *data) +int PSP_CreateWindowFrom(_THIS, SDL_Window *window, const void *data) { return SDL_Unsupported(); } -void -PSP_SetWindowTitle(_THIS, SDL_Window * window) +void PSP_SetWindowTitle(_THIS, SDL_Window *window) { } -void -PSP_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon) +void PSP_SetWindowIcon(_THIS, SDL_Window *window, SDL_Surface *icon) { } -void -PSP_SetWindowPosition(_THIS, SDL_Window * window) +void PSP_SetWindowPosition(_THIS, SDL_Window *window) { } -void -PSP_SetWindowSize(_THIS, SDL_Window * window) +void PSP_SetWindowSize(_THIS, SDL_Window *window) { } -void -PSP_ShowWindow(_THIS, SDL_Window * window) +void PSP_ShowWindow(_THIS, SDL_Window *window) { } -void -PSP_HideWindow(_THIS, SDL_Window * window) +void PSP_HideWindow(_THIS, SDL_Window *window) { } -void -PSP_RaiseWindow(_THIS, SDL_Window * window) +void PSP_RaiseWindow(_THIS, SDL_Window *window) { } -void -PSP_MaximizeWindow(_THIS, SDL_Window * window) +void PSP_MaximizeWindow(_THIS, SDL_Window *window) { } -void -PSP_MinimizeWindow(_THIS, SDL_Window * window) +void PSP_MinimizeWindow(_THIS, SDL_Window *window) { } -void -PSP_RestoreWindow(_THIS, SDL_Window * window) +void PSP_RestoreWindow(_THIS, SDL_Window *window) { } -void -PSP_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed) -{ - -} -void -PSP_DestroyWindow(_THIS, SDL_Window * window) +void PSP_DestroyWindow(_THIS, SDL_Window *window) { } @@ -294,14 +265,13 @@ PSP_DestroyWindow(_THIS, SDL_Window * window) /* SDL Window Manager function */ /*****************************************************************************/ #if 0 -SDL_bool -PSP_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info) +SDL_bool PSP_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info) { if (info->version.major <= SDL_MAJOR_VERSION) { return SDL_TRUE; } else { - SDL_SetError("Application not compiled with SDL %d.%d", - SDL_MAJOR_VERSION, SDL_MINOR_VERSION); + SDL_SetError("Application not compiled with SDL %d", + SDL_MAJOR_VERSION); return SDL_FALSE; } @@ -327,7 +297,6 @@ SDL_bool PSP_IsScreenKeyboardShown(_THIS, SDL_Window *window) return SDL_FALSE; } - #endif /* SDL_VIDEO_DRIVER_PSP */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/psp/SDL_pspvideo.h b/SDL2-2.30.5/src/video/psp/SDL_pspvideo.h similarity index 61% rename from SDL2-2.0.12/src/video/psp/SDL_pspvideo.h rename to SDL2-2.30.5/src/video/psp/SDL_pspvideo.h index 484df87..442d3ea 100644 --- a/SDL2-2.0.12/src/video/psp/SDL_pspvideo.h +++ b/SDL2-2.30.5/src/video/psp/SDL_pspvideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -29,29 +29,22 @@ typedef struct SDL_VideoData { - SDL_bool egl_initialized; /* OpenGL ES device initialization status */ - uint32_t egl_refcount; /* OpenGL ES reference count */ - - + SDL_bool egl_initialized; /* OpenGL ES device initialization status */ + uint32_t egl_refcount; /* OpenGL ES reference count */ } SDL_VideoData; - typedef struct SDL_DisplayData { } SDL_DisplayData; - typedef struct SDL_WindowData { - SDL_bool uses_gles; /* if true window must support OpenGL ES */ + SDL_bool uses_gles; /* if true window must support OpenGL ES */ } SDL_WindowData; - - - /****************************************************************************/ /* SDL_VideoDevice functions declaration */ /****************************************************************************/ @@ -59,22 +52,21 @@ typedef struct SDL_WindowData /* Display and window functions */ int PSP_VideoInit(_THIS); void PSP_VideoQuit(_THIS); -void PSP_GetDisplayModes(_THIS, SDL_VideoDisplay * display); -int PSP_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode); -int PSP_CreateWindow(_THIS, SDL_Window * window); -int PSP_CreateWindowFrom(_THIS, SDL_Window * window, const void *data); -void PSP_SetWindowTitle(_THIS, SDL_Window * window); -void PSP_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon); -void PSP_SetWindowPosition(_THIS, SDL_Window * window); -void PSP_SetWindowSize(_THIS, SDL_Window * window); -void PSP_ShowWindow(_THIS, SDL_Window * window); -void PSP_HideWindow(_THIS, SDL_Window * window); -void PSP_RaiseWindow(_THIS, SDL_Window * window); -void PSP_MaximizeWindow(_THIS, SDL_Window * window); -void PSP_MinimizeWindow(_THIS, SDL_Window * window); -void PSP_RestoreWindow(_THIS, SDL_Window * window); -void PSP_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed); -void PSP_DestroyWindow(_THIS, SDL_Window * window); +void PSP_GetDisplayModes(_THIS, SDL_VideoDisplay *display); +int PSP_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode); +int PSP_CreateWindow(_THIS, SDL_Window *window); +int PSP_CreateWindowFrom(_THIS, SDL_Window *window, const void *data); +void PSP_SetWindowTitle(_THIS, SDL_Window *window); +void PSP_SetWindowIcon(_THIS, SDL_Window *window, SDL_Surface *icon); +void PSP_SetWindowPosition(_THIS, SDL_Window *window); +void PSP_SetWindowSize(_THIS, SDL_Window *window); +void PSP_ShowWindow(_THIS, SDL_Window *window); +void PSP_HideWindow(_THIS, SDL_Window *window); +void PSP_RaiseWindow(_THIS, SDL_Window *window); +void PSP_MaximizeWindow(_THIS, SDL_Window *window); +void PSP_MinimizeWindow(_THIS, SDL_Window *window); +void PSP_RestoreWindow(_THIS, SDL_Window *window); +void PSP_DestroyWindow(_THIS, SDL_Window *window); /* Window manager function */ SDL_bool PSP_GetWindowWMInfo(_THIS, SDL_Window * window, @@ -84,11 +76,11 @@ SDL_bool PSP_GetWindowWMInfo(_THIS, SDL_Window * window, int PSP_GL_LoadLibrary(_THIS, const char *path); void *PSP_GL_GetProcAddress(_THIS, const char *proc); void PSP_GL_UnloadLibrary(_THIS); -SDL_GLContext PSP_GL_CreateContext(_THIS, SDL_Window * window); -int PSP_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context); +SDL_GLContext PSP_GL_CreateContext(_THIS, SDL_Window *window); +int PSP_GL_MakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context); int PSP_GL_SetSwapInterval(_THIS, int interval); int PSP_GL_GetSwapInterval(_THIS); -int PSP_GL_SwapWindow(_THIS, SDL_Window * window); +int PSP_GL_SwapWindow(_THIS, SDL_Window *window); void PSP_GL_DeleteContext(_THIS, SDL_GLContext context); /* PSP on screen keyboard */ diff --git a/SDL2-2.0.12/src/video/qnx/gl.c b/SDL2-2.30.5/src/video/qnx/gl.c similarity index 91% rename from SDL2-2.0.12/src/video/qnx/gl.c rename to SDL2-2.30.5/src/video/qnx/gl.c index 19e1bd4..e6e999a 100644 --- a/SDL2-2.0.12/src/video/qnx/gl.c +++ b/SDL2-2.30.5/src/video/qnx/gl.c @@ -30,8 +30,7 @@ static EGLDisplay egl_disp; * @param egl_conf EGL configuration to use * @return A SCREEN_FORMAT* constant for the pixel format to use */ -static int -chooseFormat(EGLConfig egl_conf) +static int chooseFormat(EGLConfig egl_conf) { EGLint buffer_bit_depth; EGLint alpha_bit_depth; @@ -64,8 +63,7 @@ chooseFormat(EGLConfig egl_conf) * @param[out] pformat The chosen pixel format * @return 0 if successful, -1 on error */ -int -glGetConfig(EGLConfig *pconf, int *pformat) +int glGetConfig(EGLConfig *pconf, int *pformat) { EGLConfig egl_conf = (EGLConfig)0; EGLConfig *egl_configs; @@ -85,8 +83,8 @@ glGetConfig(EGLConfig *pconf, int *pformat) } // Allocate enough memory for all configurations. - egl_configs = malloc(egl_num_configs * sizeof(*egl_configs)); - if (egl_configs == NULL) { + egl_configs = SDL_malloc(egl_num_configs * sizeof(*egl_configs)); + if (!egl_configs) { return -1; } @@ -94,7 +92,7 @@ glGetConfig(EGLConfig *pconf, int *pformat) rc = eglGetConfigs(egl_disp, egl_configs, egl_num_configs, &egl_num_configs); if (rc != EGL_TRUE) { - free(egl_configs); + SDL_free(egl_configs); return -1; } @@ -119,7 +117,7 @@ glGetConfig(EGLConfig *pconf, int *pformat) break; } - free(egl_configs); + SDL_free(egl_configs); *pconf = egl_conf; *pformat = chooseFormat(egl_conf); @@ -132,8 +130,7 @@ glGetConfig(EGLConfig *pconf, int *pformat) * @param name unused * @return 0 if successful, -1 on error */ -int -glLoadLibrary(_THIS, const char *name) +int glLoadLibrary(_THIS, const char *name) { EGLNativeDisplayType disp_id = EGL_DEFAULT_DISPLAY; @@ -154,8 +151,7 @@ glLoadLibrary(_THIS, const char *name) * @param proc Function name * @return Function address */ -void * -glGetProcAddress(_THIS, const char *proc) +void *glGetProcAddress(_THIS, const char *proc) { return eglGetProcAddress(proc); } @@ -167,8 +163,7 @@ glGetProcAddress(_THIS, const char *proc) * @param window The SDL window to create the context for * @return A pointer to the created context, if successful, NULL on error */ -SDL_GLContext -glCreateContext(_THIS, SDL_Window *window) +SDL_GLContext glCreateContext(_THIS, SDL_Window *window) { window_impl_t *impl = (window_impl_t *)window->driverdata; EGLContext context; @@ -214,8 +209,7 @@ glCreateContext(_THIS, SDL_Window *window) * @param interval New interval value * @return 0 if successful, -1 on error */ -int -glSetSwapInterval(_THIS, int interval) +int glSetSwapInterval(_THIS, int interval) { if (eglSwapInterval(egl_disp, interval) != EGL_TRUE) { return -1; @@ -230,8 +224,7 @@ glSetSwapInterval(_THIS, int interval) * @param window Window to swap buffers for * @return 0 if successful, -1 on error */ -int -glSwapWindow(_THIS, SDL_Window *window) +int glSwapWindow(_THIS, SDL_Window *window) { /* !!! FIXME: should we migrate this all over to use SDL_egl.c? */ window_impl_t *impl = (window_impl_t *)window->driverdata; @@ -245,8 +238,7 @@ glSwapWindow(_THIS, SDL_Window *window) * @param context The context to activate * @return 0 if successful, -1 on error */ -int -glMakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context) +int glMakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context) { window_impl_t *impl; EGLSurface surface = NULL; @@ -268,8 +260,7 @@ glMakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context) * @param _THIS * @param context The context to destroy */ -void -glDeleteContext(_THIS, SDL_GLContext context) +void glDeleteContext(_THIS, SDL_GLContext context) { eglDestroyContext(egl_disp, context); } @@ -278,8 +269,7 @@ glDeleteContext(_THIS, SDL_GLContext context) * Terminates access to the EGL library. * @param _THIS */ -void -glUnloadLibrary(_THIS) +void glUnloadLibrary(_THIS) { eglTerminate(egl_disp); } diff --git a/SDL2-2.0.12/src/video/qnx/keyboard.c b/SDL2-2.30.5/src/video/qnx/keyboard.c similarity index 98% rename from SDL2-2.0.12/src/video/qnx/keyboard.c rename to SDL2-2.30.5/src/video/qnx/keyboard.c index 86c6395..9ec289d 100644 --- a/SDL2-2.0.12/src/video/qnx/keyboard.c +++ b/SDL2-2.30.5/src/video/qnx/keyboard.c @@ -95,8 +95,7 @@ static int key_to_sdl[] = { * Translates the event such that it can be handled by SDL. * @param event Screen keyboard event */ -void -handleKeyboardEvent(screen_event_t event) +void handleKeyboardEvent(screen_event_t event) { int val; SDL_Scancode scancode; diff --git a/SDL2-2.0.12/src/video/qnx/sdl_qnx.h b/SDL2-2.30.5/src/video/qnx/sdl_qnx.h similarity index 100% rename from SDL2-2.0.12/src/video/qnx/sdl_qnx.h rename to SDL2-2.30.5/src/video/qnx/sdl_qnx.h diff --git a/SDL2-2.0.12/src/video/qnx/video.c b/SDL2-2.30.5/src/video/qnx/video.c similarity index 91% rename from SDL2-2.0.12/src/video/qnx/video.c rename to SDL2-2.30.5/src/video/qnx/video.c index ff8223c..924eaa3 100644 --- a/SDL2-2.0.12/src/video/qnx/video.c +++ b/SDL2-2.30.5/src/video/qnx/video.c @@ -32,8 +32,7 @@ static screen_event_t event; * @param _THIS * @return 0 if successful, -1 on error */ -static int -videoInit(_THIS) +static int videoInit(_THIS) { SDL_VideoDisplay display; @@ -47,7 +46,7 @@ videoInit(_THIS) SDL_zero(display); - if (SDL_AddVideoDisplay(&display) < 0) { + if (SDL_AddVideoDisplay(&display, SDL_FALSE) < 0) { return -1; } @@ -55,8 +54,7 @@ videoInit(_THIS) return 0; } -static void -videoQuit(_THIS) +static void videoQuit(_THIS) { } @@ -67,8 +65,7 @@ videoQuit(_THIS) * @param window SDL window to initialize * @return 0 if successful, -1 on error */ -static int -createWindow(_THIS, SDL_Window *window) +static int createWindow(_THIS, SDL_Window *window) { window_impl_t *impl; int size[2]; @@ -77,7 +74,7 @@ createWindow(_THIS, SDL_Window *window) int usage; impl = SDL_calloc(1, sizeof(*impl)); - if (impl == NULL) { + if (!impl) { return -1; } @@ -150,8 +147,7 @@ fail: * @param[out] pitch Holds the number of bytes per line * @return 0 if successful, -1 on error */ -static int -createWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, +static int createWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch) { window_impl_t *impl = (window_impl_t *)window->driverdata; @@ -186,8 +182,7 @@ createWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, * @param numrects Rect array length * @return 0 if successful, -1 on error */ -static int -updateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_Rect *rects, +static int updateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_Rect *rects, int numrects) { window_impl_t *impl = (window_impl_t *)window->driverdata; @@ -207,8 +202,7 @@ updateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_Rect *rects, * Runs the main event loop. * @param _THIS */ -static void -pumpEvents(_THIS) +static void pumpEvents(_THIS) { int type; @@ -242,8 +236,7 @@ pumpEvents(_THIS) * @param _THIS * @param window SDL window to update */ -static void -setWindowSize(_THIS, SDL_Window *window) +static void setWindowSize(_THIS, SDL_Window *window) { window_impl_t *impl = (window_impl_t *)window->driverdata; int size[2]; @@ -261,8 +254,7 @@ setWindowSize(_THIS, SDL_Window *window) * @param _THIS * @param window SDL window to update */ -static void -showWindow(_THIS, SDL_Window *window) +static void showWindow(_THIS, SDL_Window *window) { window_impl_t *impl = (window_impl_t *)window->driverdata; const int visible = 1; @@ -276,8 +268,7 @@ showWindow(_THIS, SDL_Window *window) * @param _THIS * @param window SDL window to update */ -static void -hideWindow(_THIS, SDL_Window *window) +static void hideWindow(_THIS, SDL_Window *window) { window_impl_t *impl = (window_impl_t *)window->driverdata; const int visible = 0; @@ -291,8 +282,7 @@ hideWindow(_THIS, SDL_Window *window) * @param _THIS * @param window SDL window that is being destroyed */ -static void -destroyWindow(_THIS, SDL_Window *window) +static void destroyWindow(_THIS, SDL_Window *window) { window_impl_t *impl = (window_impl_t *)window->driverdata; @@ -306,8 +296,7 @@ destroyWindow(_THIS, SDL_Window *window) * Frees the plugin object created by createDevice(). * @param device Plugin object to free */ -static void -deleteDevice(SDL_VideoDevice *device) +static void deleteDevice(SDL_VideoDevice *device) { SDL_free(device); } @@ -317,13 +306,12 @@ deleteDevice(SDL_VideoDevice *device) * @param devindex Unused * @return Initialized device if successful, NULL otherwise */ -static SDL_VideoDevice * -createDevice(int devindex) +static SDL_VideoDevice *createDevice(int devindex) { SDL_VideoDevice *device; device = (SDL_VideoDevice *)SDL_calloc(1, sizeof(SDL_VideoDevice)); - if (device == NULL) { + if (!device) { return NULL; } @@ -352,13 +340,8 @@ createDevice(int devindex) return device; } -static int -available() -{ - return 1; -} - VideoBootStrap QNX_bootstrap = { "qnx", "QNX Screen", - available, createDevice + createDevice, + NULL /* no ShowMessageBox implementation */ }; diff --git a/SDL2-2.0.12/src/video/raspberry/SDL_rpievents.c b/SDL2-2.30.5/src/video/raspberry/SDL_rpievents.c similarity index 90% rename from SDL2-2.0.12/src/video/raspberry/SDL_rpievents.c rename to SDL2-2.30.5/src/video/raspberry/SDL_rpievents.c index c2847b3..5b9bdf0 100644 --- a/SDL2-2.0.12/src/video/raspberry/SDL_rpievents.c +++ b/SDL2-2.30.5/src/video/raspberry/SDL_rpievents.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -21,11 +21,11 @@ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_RPI +#ifdef SDL_VIDEO_DRIVER_RPI -#include "../../events/SDL_sysevents.h" #include "../../events/SDL_events_c.h" #include "../../events/SDL_keyboard_c.h" +#include "../SDL_sysvideo.h" #include "SDL_rpivideo.h" #include "SDL_rpievents_c.h" @@ -38,8 +38,6 @@ void RPI_PumpEvents(_THIS) #ifdef SDL_INPUT_LINUXEV SDL_EVDEV_Poll(); #endif - } #endif /* SDL_VIDEO_DRIVER_RPI */ - diff --git a/SDL2-2.0.12/src/video/raspberry/SDL_rpievents_c.h b/SDL2-2.30.5/src/video/raspberry/SDL_rpievents_c.h similarity index 89% rename from SDL2-2.0.12/src/video/raspberry/SDL_rpievents_c.h rename to SDL2-2.30.5/src/video/raspberry/SDL_rpievents_c.h index 20e04e9..e3b826c 100644 --- a/SDL2-2.0.12/src/video/raspberry/SDL_rpievents_c.h +++ b/SDL2-2.30.5/src/video/raspberry/SDL_rpievents_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -25,7 +25,5 @@ #include "SDL_rpivideo.h" void RPI_PumpEvents(_THIS); -void RPI_EventInit(_THIS); -void RPI_EventQuit(_THIS); #endif /* SDL_rpievents_c_h_ */ diff --git a/SDL2-2.0.12/src/video/raspberry/SDL_rpimouse.c b/SDL2-2.30.5/src/video/raspberry/SDL_rpimouse.c similarity index 72% rename from SDL2-2.0.12/src/video/raspberry/SDL_rpimouse.c rename to SDL2-2.30.5/src/video/raspberry/SDL_rpimouse.c index 378c305..ff35a79 100644 --- a/SDL2-2.0.12/src/video/raspberry/SDL_rpimouse.c +++ b/SDL2-2.30.5/src/video/raspberry/SDL_rpimouse.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,9 +20,8 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_RPI +#ifdef SDL_VIDEO_DRIVER_RPI -#include "SDL_assert.h" #include "SDL_surface.h" #include "SDL_hints.h" @@ -35,50 +34,48 @@ /* Copied from vc_vchi_dispmanx.h which is bugged and tries to include a non existing file */ /* Attributes changes flag mask */ -#define ELEMENT_CHANGE_LAYER (1<<0) -#define ELEMENT_CHANGE_OPACITY (1<<1) -#define ELEMENT_CHANGE_DEST_RECT (1<<2) -#define ELEMENT_CHANGE_SRC_RECT (1<<3) -#define ELEMENT_CHANGE_MASK_RESOURCE (1<<4) -#define ELEMENT_CHANGE_TRANSFORM (1<<5) +#define ELEMENT_CHANGE_LAYER (1 << 0) +#define ELEMENT_CHANGE_OPACITY (1 << 1) +#define ELEMENT_CHANGE_DEST_RECT (1 << 2) +#define ELEMENT_CHANGE_SRC_RECT (1 << 3) +#define ELEMENT_CHANGE_MASK_RESOURCE (1 << 4) +#define ELEMENT_CHANGE_TRANSFORM (1 << 5) /* End copied from vc_vchi_dispmanx.h */ static SDL_Cursor *RPI_CreateDefaultCursor(void); -static SDL_Cursor *RPI_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y); -static int RPI_ShowCursor(SDL_Cursor * cursor); -static void RPI_MoveCursor(SDL_Cursor * cursor); -static void RPI_FreeCursor(SDL_Cursor * cursor); -static void RPI_WarpMouse(SDL_Window * window, int x, int y); +static SDL_Cursor *RPI_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y); +static int RPI_ShowCursor(SDL_Cursor *cursor); +static void RPI_MoveCursor(SDL_Cursor *cursor); +static void RPI_FreeCursor(SDL_Cursor *cursor); +static void RPI_WarpMouse(SDL_Window *window, int x, int y); static int RPI_WarpMouseGlobal(int x, int y); static SDL_Cursor *global_cursor; -static SDL_Cursor * -RPI_CreateDefaultCursor(void) +static SDL_Cursor *RPI_CreateDefaultCursor(void) { return SDL_CreateCursor(default_cdata, default_cmask, DEFAULT_CWIDTH, DEFAULT_CHEIGHT, DEFAULT_CHOTX, DEFAULT_CHOTY); } /* Create a cursor from a surface */ -static SDL_Cursor * -RPI_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y) +static SDL_Cursor *RPI_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y) { RPI_CursorData *curdata; SDL_Cursor *cursor; int ret; VC_RECT_T dst_rect; Uint32 dummy; - + SDL_assert(surface->format->format == SDL_PIXELFORMAT_ARGB8888); SDL_assert(surface->pitch == surface->w * 4); - - cursor = (SDL_Cursor *) SDL_calloc(1, sizeof(*cursor)); - if (cursor == NULL) { + + cursor = (SDL_Cursor *)SDL_calloc(1, sizeof(*cursor)); + if (!cursor) { SDL_OutOfMemory(); return NULL; } - curdata = (RPI_CursorData *) SDL_calloc(1, sizeof(*curdata)); - if (curdata == NULL) { + curdata = (RPI_CursorData *)SDL_calloc(1, sizeof(*curdata)); + if (!curdata) { SDL_OutOfMemory(); SDL_free(cursor); return NULL; @@ -88,29 +85,27 @@ RPI_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y) curdata->hot_y = hot_y; curdata->w = surface->w; curdata->h = surface->h; - + /* This usage is inspired by Wayland/Weston RPI code, how they figured this out is anyone's guess */ curdata->resource = vc_dispmanx_resource_create(VC_IMAGE_ARGB8888, surface->w | (surface->pitch << 16), surface->h | (surface->h << 16), &dummy); SDL_assert(curdata->resource); vc_dispmanx_rect_set(&dst_rect, 0, 0, curdata->w, curdata->h); - /* A note from Weston: + /* A note from Weston: * vc_dispmanx_resource_write_data() ignores ifmt, * rect.x, rect.width, and uses stride only for computing * the size of the transfer as rect.height * stride. * Therefore we can only write rows starting at x=0. */ ret = vc_dispmanx_resource_write_data(curdata->resource, VC_IMAGE_ARGB8888, surface->pitch, surface->pixels, &dst_rect); - SDL_assert (ret == DISPMANX_SUCCESS); - - cursor->driverdata = curdata; - - return cursor; + SDL_assert(ret == DISPMANX_SUCCESS); + cursor->driverdata = curdata; + + return cursor; } /* Show the specified cursor, or hide if cursor is NULL */ -static int -RPI_ShowCursor(SDL_Cursor * cursor) +static int RPI_ShowCursor(SDL_Cursor *cursor) { int ret; DISPMANX_UPDATE_HANDLE_T update; @@ -119,18 +114,18 @@ RPI_ShowCursor(SDL_Cursor * cursor) SDL_Mouse *mouse; SDL_VideoDisplay *display; SDL_DisplayData *data; - VC_DISPMANX_ALPHA_T alpha = { DISPMANX_FLAGS_ALPHA_FROM_SOURCE /* flags */ , 255 /*opacity 0->255*/, 0 /* mask */ }; + VC_DISPMANX_ALPHA_T alpha = { DISPMANX_FLAGS_ALPHA_FROM_SOURCE /* flags */, 255 /*opacity 0->255*/, 0 /* mask */ }; uint32_t layer = SDL_RPI_MOUSELAYER; const char *env; mouse = SDL_GetMouse(); - if (mouse == NULL) { + if (!mouse) { return -1; } - + if (cursor != global_cursor) { - if (global_cursor != NULL) { - curdata = (RPI_CursorData *) global_cursor->driverdata; + if (global_cursor) { + curdata = (RPI_CursorData *)global_cursor->driverdata; if (curdata && curdata->element > DISPMANX_NO_HANDLE) { update = vc_dispmanx_update_start(0); SDL_assert(update); @@ -144,33 +139,33 @@ RPI_ShowCursor(SDL_Cursor * cursor) global_cursor = cursor; } - if (cursor == NULL) { + if (!cursor) { return 0; } - - curdata = (RPI_CursorData *) cursor->driverdata; - if (curdata == NULL) { + + curdata = (RPI_CursorData *)cursor->driverdata; + if (!curdata) { return -1; } - - if (mouse->focus == NULL) { + + if (!mouse->focus) { return -1; } display = SDL_GetDisplayForWindow(mouse->focus); - if (display == NULL) { + if (!display) { return -1; } - - data = (SDL_DisplayData*) display->driverdata; - if (data == NULL) { + + data = (SDL_DisplayData *)display->driverdata; + if (!data) { return -1; } - + if (curdata->element == DISPMANX_NO_HANDLE) { vc_dispmanx_rect_set(&src_rect, 0, 0, curdata->w << 16, curdata->h << 16); vc_dispmanx_rect_set(&dst_rect, mouse->x - curdata->hot_x, mouse->y - curdata->hot_y, curdata->w, curdata->h); - + update = vc_dispmanx_update_start(0); SDL_assert(update); @@ -180,35 +175,34 @@ RPI_ShowCursor(SDL_Cursor * cursor) } curdata->element = vc_dispmanx_element_add(update, - data->dispman_display, - layer, - &dst_rect, - curdata->resource, - &src_rect, - DISPMANX_PROTECTION_NONE, - &alpha, - DISPMANX_NO_HANDLE, // clamp - DISPMANX_NO_ROTATE); + data->dispman_display, + layer, + &dst_rect, + curdata->resource, + &src_rect, + DISPMANX_PROTECTION_NONE, + &alpha, + DISPMANX_NO_HANDLE, // clamp + DISPMANX_NO_ROTATE); SDL_assert(curdata->element > DISPMANX_NO_HANDLE); ret = vc_dispmanx_update_submit_sync(update); SDL_assert(ret == DISPMANX_SUCCESS); } - + return 0; } /* Free a window manager cursor */ -static void -RPI_FreeCursor(SDL_Cursor * cursor) +static void RPI_FreeCursor(SDL_Cursor *cursor) { int ret; DISPMANX_UPDATE_HANDLE_T update; RPI_CursorData *curdata; - - if (cursor != NULL) { - curdata = (RPI_CursorData *) cursor->driverdata; - - if (curdata != NULL) { + + if (cursor) { + curdata = (RPI_CursorData *)cursor->driverdata; + + if (curdata) { if (curdata->element != DISPMANX_NO_HANDLE) { update = vc_dispmanx_update_start(0); SDL_assert(update); @@ -217,12 +211,12 @@ RPI_FreeCursor(SDL_Cursor * cursor) ret = vc_dispmanx_update_submit_sync(update); SDL_assert(ret == DISPMANX_SUCCESS); } - + if (curdata->resource != DISPMANX_NO_HANDLE) { ret = vc_dispmanx_resource_delete(curdata->resource); SDL_assert(ret == DISPMANX_SUCCESS); } - + SDL_free(cursor->driverdata); } SDL_free(cursor); @@ -233,15 +227,13 @@ RPI_FreeCursor(SDL_Cursor * cursor) } /* Warp the mouse to (x,y) */ -static void -RPI_WarpMouse(SDL_Window * window, int x, int y) +static void RPI_WarpMouse(SDL_Window *window, int x, int y) { RPI_WarpMouseGlobal(x, y); } /* Warp the mouse to (x,y) */ -static int -RPI_WarpMouseGlobal(int x, int y) +static int RPI_WarpMouseGlobal(int x, int y) { RPI_CursorData *curdata; DISPMANX_UPDATE_HANDLE_T update; @@ -249,15 +241,15 @@ RPI_WarpMouseGlobal(int x, int y) VC_RECT_T dst_rect; VC_RECT_T src_rect; SDL_Mouse *mouse = SDL_GetMouse(); - - if (mouse == NULL || mouse->cur_cursor == NULL || mouse->cur_cursor->driverdata == NULL) { + + if (!mouse || !mouse->cur_cursor || !mouse->cur_cursor->driverdata) { return 0; } /* Update internal mouse position. */ SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 0, x, y); - curdata = (RPI_CursorData *) mouse->cur_cursor->driverdata; + curdata = (RPI_CursorData *)mouse->cur_cursor->driverdata; if (curdata->element == DISPMANX_NO_HANDLE) { return 0; } @@ -269,11 +261,11 @@ RPI_WarpMouseGlobal(int x, int y) src_rect.x = 0; src_rect.y = 0; - src_rect.width = curdata->w << 16; + src_rect.width = curdata->w << 16; src_rect.height = curdata->h << 16; dst_rect.x = x - curdata->hot_x; dst_rect.y = y - curdata->hot_y; - dst_rect.width = curdata->w; + dst_rect.width = curdata->w; dst_rect.height = curdata->h; ret = vc_dispmanx_element_change_attributes( @@ -299,8 +291,7 @@ RPI_WarpMouseGlobal(int x, int y) } /* Warp the mouse to (x,y) */ -static int -RPI_WarpMouseGlobalGraphicOnly(int x, int y) +static int RPI_WarpMouseGlobalGraphicOnly(int x, int y) { RPI_CursorData *curdata; DISPMANX_UPDATE_HANDLE_T update; @@ -308,12 +299,12 @@ RPI_WarpMouseGlobalGraphicOnly(int x, int y) VC_RECT_T dst_rect; VC_RECT_T src_rect; SDL_Mouse *mouse = SDL_GetMouse(); - - if (mouse == NULL || mouse->cur_cursor == NULL || mouse->cur_cursor->driverdata == NULL) { + + if (!mouse || !mouse->cur_cursor || !mouse->cur_cursor->driverdata) { return 0; } - curdata = (RPI_CursorData *) mouse->cur_cursor->driverdata; + curdata = (RPI_CursorData *)mouse->cur_cursor->driverdata; if (curdata->element == DISPMANX_NO_HANDLE) { return 0; } @@ -325,11 +316,11 @@ RPI_WarpMouseGlobalGraphicOnly(int x, int y) src_rect.x = 0; src_rect.y = 0; - src_rect.width = curdata->w << 16; + src_rect.width = curdata->w << 16; src_rect.height = curdata->h << 16; dst_rect.x = x - curdata->hot_x; dst_rect.y = y - curdata->hot_y; - dst_rect.width = curdata->w; + dst_rect.width = curdata->w; dst_rect.height = curdata->h; ret = vc_dispmanx_element_change_attributes( @@ -354,10 +345,9 @@ RPI_WarpMouseGlobalGraphicOnly(int x, int y) return 0; } -void -RPI_InitMouse(_THIS) +void RPI_InitMouse(_THIS) { - /* FIXME: Using UDEV it should be possible to scan all mice + /* FIXME: Using UDEV it should be possible to scan all mice * but there's no point in doing so as there's no multimice support...yet! */ SDL_Mouse *mouse = SDL_GetMouse(); @@ -372,17 +362,15 @@ RPI_InitMouse(_THIS) SDL_SetDefaultCursor(RPI_CreateDefaultCursor()); } -void -RPI_QuitMouse(_THIS) +void RPI_QuitMouse(_THIS) { } /* This is called when a mouse motion event occurs */ -static void -RPI_MoveCursor(SDL_Cursor * cursor) +static void RPI_MoveCursor(SDL_Cursor *cursor) { SDL_Mouse *mouse = SDL_GetMouse(); - /* We must NOT call SDL_SendMouseMotion() on the next call or we will enter recursivity, + /* We must NOT call SDL_SendMouseMotion() on the next call or we will enter recursivity, * so we create a version of WarpMouseGlobal without it. */ RPI_WarpMouseGlobalGraphicOnly(mouse->x, mouse->y); } diff --git a/SDL2-2.0.12/src/video/raspberry/SDL_rpimouse.h b/SDL2-2.30.5/src/video/raspberry/SDL_rpimouse.h similarity index 77% rename from SDL2-2.0.12/src/video/raspberry/SDL_rpimouse.h rename to SDL2-2.30.5/src/video/raspberry/SDL_rpimouse.h index 65c89df..8ff70de 100644 --- a/SDL2-2.0.12/src/video/raspberry/SDL_rpimouse.h +++ b/SDL2-2.30.5/src/video/raspberry/SDL_rpimouse.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -27,13 +27,13 @@ typedef struct _RPI_CursorData RPI_CursorData; struct _RPI_CursorData { - DISPMANX_RESOURCE_HANDLE_T resource; - DISPMANX_ELEMENT_HANDLE_T element; - int hot_x, hot_y; - int w, h; + DISPMANX_RESOURCE_HANDLE_T resource; + DISPMANX_ELEMENT_HANDLE_T element; + int hot_x, hot_y; + int w, h; }; -#define SDL_RPI_CURSORDATA(curs) RPI_CursorData *curdata = (RPI_CursorData *) ((curs) ? (curs)->driverdata : NULL) +#define SDL_RPI_CURSORDATA(curs) RPI_CursorData *curdata = (RPI_CursorData *)((curs) ? (curs)->driverdata : NULL) extern void RPI_InitMouse(_THIS); extern void RPI_QuitMouse(_THIS); diff --git a/SDL2-2.0.12/src/video/raspberry/SDL_rpiopengles.c b/SDL2-2.30.5/src/video/raspberry/SDL_rpiopengles.c similarity index 80% rename from SDL2-2.0.12/src/video/raspberry/SDL_rpiopengles.c rename to SDL2-2.30.5/src/video/raspberry/SDL_rpiopengles.c index eab129d..27b4edf 100644 --- a/SDL2-2.0.12/src/video/raspberry/SDL_rpiopengles.c +++ b/SDL2-2.30.5/src/video/raspberry/SDL_rpiopengles.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -19,32 +19,31 @@ 3. This notice may not be removed or altered from any source distribution. */ #include "../../SDL_internal.h" -#include "SDL_hints.h" -#include "SDL_log.h" -#if SDL_VIDEO_DRIVER_RPI && SDL_VIDEO_OPENGL_EGL +#include "SDL_hints.h" + +#if defined(SDL_VIDEO_DRIVER_RPI) && defined(SDL_VIDEO_OPENGL_EGL) #include "SDL_rpivideo.h" #include "SDL_rpiopengles.h" /* EGL implementation of SDL OpenGL support */ -void -RPI_GLES_DefaultProfileConfig(_THIS, int *mask, int *major, int *minor) +void RPI_GLES_DefaultProfileConfig(_THIS, int *mask, int *major, int *minor) { *mask = SDL_GL_CONTEXT_PROFILE_ES; *major = 2; *minor = 0; } -int -RPI_GLES_LoadLibrary(_THIS, const char *path) { +int RPI_GLES_LoadLibrary(_THIS, const char *path) +{ return SDL_EGL_LoadLibrary(_this, path, EGL_DEFAULT_DISPLAY, 0); } -int -RPI_GLES_SwapWindow(_THIS, SDL_Window * window) { - SDL_WindowData *wdata = ((SDL_WindowData *) window->driverdata); +int RPI_GLES_SwapWindow(_THIS, SDL_Window *window) +{ + SDL_WindowData *wdata = ((SDL_WindowData *)window->driverdata); if (!(_this->egl_data->eglSwapBuffers(_this->egl_data->egl_display, wdata->egl_surface))) { SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "eglSwapBuffers failed."); @@ -63,9 +62,8 @@ RPI_GLES_SwapWindow(_THIS, SDL_Window * window) { } SDL_EGL_CreateContext_impl(RPI) -SDL_EGL_MakeCurrent_impl(RPI) + SDL_EGL_MakeCurrent_impl(RPI) #endif /* SDL_VIDEO_DRIVER_RPI && SDL_VIDEO_OPENGL_EGL */ -/* vi: set ts=4 sw=4 expandtab: */ - + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/raspberry/SDL_rpiopengles.h b/SDL2-2.30.5/src/video/raspberry/SDL_rpiopengles.h similarity index 80% rename from SDL2-2.0.12/src/video/raspberry/SDL_rpiopengles.h rename to SDL2-2.30.5/src/video/raspberry/SDL_rpiopengles.h index 36f94ac..15c6ab1 100644 --- a/SDL2-2.0.12/src/video/raspberry/SDL_rpiopengles.h +++ b/SDL2-2.30.5/src/video/raspberry/SDL_rpiopengles.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,7 +23,7 @@ #ifndef SDL_rpiopengles_h_ #define SDL_rpiopengles_h_ -#if SDL_VIDEO_DRIVER_RPI && SDL_VIDEO_OPENGL_EGL +#if defined(SDL_VIDEO_DRIVER_RPI) && defined(SDL_VIDEO_OPENGL_EGL) #include "../SDL_sysvideo.h" #include "../SDL_egl_c.h" @@ -34,12 +34,12 @@ #define RPI_GLES_UnloadLibrary SDL_EGL_UnloadLibrary #define RPI_GLES_SetSwapInterval SDL_EGL_SetSwapInterval #define RPI_GLES_GetSwapInterval SDL_EGL_GetSwapInterval -#define RPI_GLES_DeleteContext SDL_EGL_DeleteContext +#define RPI_GLES_DeleteContext SDL_EGL_DeleteContext extern int RPI_GLES_LoadLibrary(_THIS, const char *path); -extern SDL_GLContext RPI_GLES_CreateContext(_THIS, SDL_Window * window); -extern int RPI_GLES_SwapWindow(_THIS, SDL_Window * window); -extern int RPI_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context); +extern SDL_GLContext RPI_GLES_CreateContext(_THIS, SDL_Window *window); +extern int RPI_GLES_SwapWindow(_THIS, SDL_Window *window); +extern int RPI_GLES_MakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context); extern void RPI_GLES_DefaultProfileConfig(_THIS, int *mask, int *major, int *minor); #endif /* SDL_VIDEO_DRIVER_RPI && SDL_VIDEO_OPENGL_EGL */ diff --git a/SDL2-2.0.12/src/video/raspberry/SDL_rpivideo.c b/SDL2-2.30.5/src/video/raspberry/SDL_rpivideo.c similarity index 68% rename from SDL2-2.0.12/src/video/raspberry/SDL_rpivideo.c rename to SDL2-2.30.5/src/video/raspberry/SDL_rpivideo.c index c43f49c..1442607 100644 --- a/SDL2-2.0.12/src/video/raspberry/SDL_rpivideo.c +++ b/SDL2-2.30.5/src/video/raspberry/SDL_rpivideo.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -21,7 +21,7 @@ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_RPI +#ifdef SDL_VIDEO_DRIVER_RPI /* References * http://elinux.org/RPi_VideoCore_APIs @@ -50,52 +50,41 @@ #include "SDL_rpiopengles.h" #include "SDL_rpimouse.h" -static int -RPI_Available(void) -{ - return 1; -} - -static void -RPI_Destroy(SDL_VideoDevice * device) +static void RPI_Destroy(SDL_VideoDevice *device) { SDL_free(device->driverdata); SDL_free(device); } -static int -RPI_GetRefreshRate() +static int RPI_GetRefreshRate() { TV_DISPLAY_STATE_T tvstate; - if (vc_tv_get_display_state( &tvstate ) == 0) { - //The width/height parameters are in the same position in the union - //for HDMI and SDTV + if (vc_tv_get_display_state(&tvstate) == 0) { + // The width/height parameters are in the same position in the union + // for HDMI and SDTV HDMI_PROPERTY_PARAM_T property; property.property = HDMI_PROPERTY_PIXEL_CLOCK_TYPE; vc_tv_hdmi_get_property(&property); - return property.param1 == HDMI_PIXEL_CLOCK_TYPE_NTSC ? - tvstate.display.hdmi.frame_rate * (1000.0f/1001.0f) : - tvstate.display.hdmi.frame_rate; - } - return 60; /* Failed to get display state, default to 60 */ + return property.param1 == HDMI_PIXEL_CLOCK_TYPE_NTSC ? tvstate.display.hdmi.frame_rate * (1000.0f / 1001.0f) : tvstate.display.hdmi.frame_rate; + } + return 60; /* Failed to get display state, default to 60 */ } -static SDL_VideoDevice * -RPI_Create() +static SDL_VideoDevice *RPI_Create() { SDL_VideoDevice *device; SDL_VideoData *phdata; /* Initialize SDL_VideoDevice structure */ - device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice)); - if (device == NULL) { + device = (SDL_VideoDevice *)SDL_calloc(1, sizeof(SDL_VideoDevice)); + if (!device) { SDL_OutOfMemory(); return NULL; } /* Initialize internal data */ - phdata = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData)); - if (phdata == NULL) { + phdata = (SDL_VideoData *)SDL_calloc(1, sizeof(SDL_VideoData)); + if (!phdata) { SDL_OutOfMemory(); SDL_free(device); return NULL; @@ -126,7 +115,6 @@ RPI_Create() device->MaximizeWindow = RPI_MaximizeWindow; device->MinimizeWindow = RPI_MinimizeWindow; device->RestoreWindow = RPI_RestoreWindow; - device->SetWindowGrab = RPI_SetWindowGrab; device->DestroyWindow = RPI_DestroyWindow; #if 0 device->GetWindowWMInfo = RPI_GetWindowWMInfo; @@ -150,17 +138,15 @@ RPI_Create() VideoBootStrap RPI_bootstrap = { "RPI", "RPI Video Driver", - RPI_Available, - RPI_Create + RPI_Create, + NULL /* no ShowMessageBox implementation */ }; - /*****************************************************************************/ /* SDL Video and Display initialization/handling functions */ /*****************************************************************************/ -static void -AddDispManXDisplay(const int display_id) +static void AddDispManXDisplay(const int display_id) { DISPMANX_MODEINFO_T modeinfo; DISPMANX_DISPLAY_HANDLE_T handle; @@ -170,7 +156,7 @@ AddDispManXDisplay(const int display_id) handle = vc_dispmanx_display_open(display_id); if (!handle) { - return; /* this display isn't available */ + return; /* this display isn't available */ } if (vc_dispmanx_display_get_info(handle, &modeinfo) < 0) { @@ -193,95 +179,89 @@ AddDispManXDisplay(const int display_id) display.current_mode = current_mode; /* Allocate display internal data */ - data = (SDL_DisplayData *) SDL_calloc(1, sizeof(SDL_DisplayData)); - if (data == NULL) { + data = (SDL_DisplayData *)SDL_calloc(1, sizeof(SDL_DisplayData)); + if (!data) { vc_dispmanx_display_close(handle); - return; /* oh well */ + return; /* oh well */ } data->dispman_display = handle; display.driverdata = data; - SDL_AddVideoDisplay(&display); + SDL_AddVideoDisplay(&display, SDL_FALSE); } -int -RPI_VideoInit(_THIS) +int RPI_VideoInit(_THIS) { /* Initialize BCM Host */ bcm_host_init(); - AddDispManXDisplay(DISPMANX_ID_MAIN_LCD); /* your default display */ - AddDispManXDisplay(DISPMANX_ID_FORCE_OTHER); /* an "other" display...maybe DSI-connected screen while HDMI is your main */ + AddDispManXDisplay(DISPMANX_ID_MAIN_LCD); /* your default display */ + AddDispManXDisplay(DISPMANX_ID_FORCE_OTHER); /* an "other" display...maybe DSI-connected screen while HDMI is your main */ -#ifdef SDL_INPUT_LINUXEV +#ifdef SDL_INPUT_LINUXEV if (SDL_EVDEV_Init() < 0) { return -1; } -#endif - +#endif + RPI_InitMouse(_this); return 1; } -void -RPI_VideoQuit(_THIS) +void RPI_VideoQuit(_THIS) { -#ifdef SDL_INPUT_LINUXEV +#ifdef SDL_INPUT_LINUXEV SDL_EVDEV_Quit(); -#endif +#endif } -void -RPI_GetDisplayModes(_THIS, SDL_VideoDisplay * display) +void RPI_GetDisplayModes(_THIS, SDL_VideoDisplay *display) { /* Only one display mode available, the current one */ SDL_AddDisplayMode(display, &display->current_mode); } -int -RPI_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) +int RPI_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode) { return 0; } -static void -RPI_vsync_callback(DISPMANX_UPDATE_HANDLE_T u, void *data) +static void RPI_vsync_callback(DISPMANX_UPDATE_HANDLE_T u, void *data) { - SDL_WindowData *wdata = ((SDL_WindowData *) data); + SDL_WindowData *wdata = ((SDL_WindowData *)data); - SDL_LockMutex(wdata->vsync_cond_mutex); - SDL_CondSignal(wdata->vsync_cond); - SDL_UnlockMutex(wdata->vsync_cond_mutex); + SDL_LockMutex(wdata->vsync_cond_mutex); + SDL_CondSignal(wdata->vsync_cond); + SDL_UnlockMutex(wdata->vsync_cond_mutex); } -int -RPI_CreateWindow(_THIS, SDL_Window * window) +int RPI_CreateWindow(_THIS, SDL_Window *window) { SDL_WindowData *wdata; SDL_VideoDisplay *display; SDL_DisplayData *displaydata; VC_RECT_T dst_rect; VC_RECT_T src_rect; - VC_DISPMANX_ALPHA_T dispman_alpha; + VC_DISPMANX_ALPHA_T dispman_alpha; DISPMANX_UPDATE_HANDLE_T dispman_update; uint32_t layer = SDL_RPI_VIDEOLAYER; const char *env; /* Disable alpha, otherwise the app looks composed with whatever dispman is showing (X11, console,etc) */ - dispman_alpha.flags = DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS; - dispman_alpha.opacity = 0xFF; + dispman_alpha.flags = DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS; + dispman_alpha.opacity = 0xFF; dispman_alpha.mask = 0; /* Allocate window internal data */ - wdata = (SDL_WindowData *) SDL_calloc(1, sizeof(SDL_WindowData)); - if (wdata == NULL) { + wdata = (SDL_WindowData *)SDL_calloc(1, sizeof(SDL_WindowData)); + if (!wdata) { return SDL_OutOfMemory(); } display = SDL_GetDisplayForWindow(window); - displaydata = (SDL_DisplayData *) display->driverdata; + displaydata = (SDL_DisplayData *)display->driverdata; /* Windows have one size for now */ window->w = display->desktop_mode.w; @@ -306,27 +286,27 @@ RPI_CreateWindow(_THIS, SDL_Window * window) layer = SDL_atoi(env); } - dispman_update = vc_dispmanx_update_start( 0 ); - wdata->dispman_window.element = vc_dispmanx_element_add (dispman_update, - displaydata->dispman_display, - layer /* layer */, - &dst_rect, - 0 /*src*/, - &src_rect, - DISPMANX_PROTECTION_NONE, - &dispman_alpha /*alpha*/, - 0 /*clamp*/, - 0 /*transform*/); + dispman_update = vc_dispmanx_update_start(0); + wdata->dispman_window.element = vc_dispmanx_element_add(dispman_update, + displaydata->dispman_display, + layer /* layer */, + &dst_rect, + 0 /*src*/, + &src_rect, + DISPMANX_PROTECTION_NONE, + &dispman_alpha /*alpha*/, + 0 /*clamp*/, + 0 /*transform*/); wdata->dispman_window.width = window->w; wdata->dispman_window.height = window->h; vc_dispmanx_update_submit_sync(dispman_update); - + if (!_this->egl_data) { if (SDL_GL_LoadLibrary(NULL) < 0) { return -1; } } - wdata->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) &wdata->dispman_window); + wdata->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType)&wdata->dispman_window); if (wdata->egl_surface == EGL_NO_SURFACE) { return SDL_SetError("Could not create GLES window surface"); @@ -338,7 +318,7 @@ RPI_CreateWindow(_THIS, SDL_Window * window) wdata->vsync_cond = SDL_CreateCond(); wdata->vsync_cond_mutex = SDL_CreateMutex(); wdata->double_buffer = SDL_TRUE; - vc_dispmanx_vsync_callback(displaydata->dispman_display, RPI_vsync_callback, (void*)wdata); + vc_dispmanx_vsync_callback(displaydata->dispman_display, RPI_vsync_callback, (void *)wdata); } /* Setup driver data for this window */ @@ -352,14 +332,13 @@ RPI_CreateWindow(_THIS, SDL_Window * window) return 0; } -void -RPI_DestroyWindow(_THIS, SDL_Window * window) +void RPI_DestroyWindow(_THIS, SDL_Window *window) { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); - SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata; + SDL_DisplayData *displaydata = (SDL_DisplayData *)display->driverdata; - if(data) { + if (data) { if (data->double_buffer) { /* Wait for vsync, and then stop vsync callbacks and destroy related stuff, if needed */ SDL_LockMutex(data->vsync_cond_mutex); @@ -372,7 +351,7 @@ RPI_DestroyWindow(_THIS, SDL_Window * window) SDL_DestroyMutex(data->vsync_cond_mutex); } -#if SDL_VIDEO_OPENGL_EGL +#ifdef SDL_VIDEO_OPENGL_EGL if (data->egl_surface != EGL_NO_SURFACE) { SDL_EGL_DestroySurface(_this, data->egl_surface); } @@ -382,70 +361,53 @@ RPI_DestroyWindow(_THIS, SDL_Window * window) } } -int -RPI_CreateWindowFrom(_THIS, SDL_Window * window, const void *data) +int RPI_CreateWindowFrom(_THIS, SDL_Window *window, const void *data) { return -1; } -void -RPI_SetWindowTitle(_THIS, SDL_Window * window) +void RPI_SetWindowTitle(_THIS, SDL_Window *window) { } -void -RPI_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon) +void RPI_SetWindowIcon(_THIS, SDL_Window *window, SDL_Surface *icon) { } -void -RPI_SetWindowPosition(_THIS, SDL_Window * window) +void RPI_SetWindowPosition(_THIS, SDL_Window *window) { } -void -RPI_SetWindowSize(_THIS, SDL_Window * window) +void RPI_SetWindowSize(_THIS, SDL_Window *window) { } -void -RPI_ShowWindow(_THIS, SDL_Window * window) +void RPI_ShowWindow(_THIS, SDL_Window *window) { } -void -RPI_HideWindow(_THIS, SDL_Window * window) +void RPI_HideWindow(_THIS, SDL_Window *window) { } -void -RPI_RaiseWindow(_THIS, SDL_Window * window) +void RPI_RaiseWindow(_THIS, SDL_Window *window) { } -void -RPI_MaximizeWindow(_THIS, SDL_Window * window) +void RPI_MaximizeWindow(_THIS, SDL_Window *window) { } -void -RPI_MinimizeWindow(_THIS, SDL_Window * window) +void RPI_MinimizeWindow(_THIS, SDL_Window *window) { } -void -RPI_RestoreWindow(_THIS, SDL_Window * window) +void RPI_RestoreWindow(_THIS, SDL_Window *window) { -} -void -RPI_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed) -{ - } /*****************************************************************************/ /* SDL Window Manager function */ /*****************************************************************************/ #if 0 -SDL_bool -RPI_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info) +SDL_bool RPI_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info) { if (info->version.major <= SDL_MAJOR_VERSION) { return SDL_TRUE; } else { - SDL_SetError("application not compiled with SDL %d.%d", - SDL_MAJOR_VERSION, SDL_MINOR_VERSION); + SDL_SetError("application not compiled with SDL %d", + SDL_MAJOR_VERSION); return SDL_FALSE; } diff --git a/SDL2-2.0.12/src/video/raspberry/SDL_rpivideo.h b/SDL2-2.30.5/src/video/raspberry/SDL_rpivideo.h similarity index 64% rename from SDL2-2.0.12/src/video/raspberry/SDL_rpivideo.h rename to SDL2-2.30.5/src/video/raspberry/SDL_rpivideo.h index 557201d..e2ffe6f 100644 --- a/SDL2-2.0.12/src/video/raspberry/SDL_rpivideo.h +++ b/SDL2-2.30.5/src/video/raspberry/SDL_rpivideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -32,25 +32,23 @@ typedef struct SDL_VideoData { - uint32_t egl_refcount; /* OpenGL ES reference count */ + uint32_t egl_refcount; /* OpenGL ES reference count */ } SDL_VideoData; - typedef struct SDL_DisplayData { DISPMANX_DISPLAY_HANDLE_T dispman_display; } SDL_DisplayData; - typedef struct SDL_WindowData { EGL_DISPMANX_WINDOW_T dispman_window; -#if SDL_VIDEO_OPENGL_EGL +#ifdef SDL_VIDEO_OPENGL_EGL EGLSurface egl_surface; -#endif +#endif /* Vsync callback cond and mutex */ - SDL_cond *vsync_cond; + SDL_cond *vsync_cond; SDL_mutex *vsync_cond_mutex; SDL_bool double_buffer; @@ -59,7 +57,6 @@ typedef struct SDL_WindowData #define SDL_RPI_VIDEOLAYER 10000 /* High enough so to occlude everything */ #define SDL_RPI_MOUSELAYER SDL_RPI_VIDEOLAYER + 1 - /****************************************************************************/ /* SDL_VideoDevice functions declaration */ /****************************************************************************/ @@ -67,22 +64,21 @@ typedef struct SDL_WindowData /* Display and window functions */ int RPI_VideoInit(_THIS); void RPI_VideoQuit(_THIS); -void RPI_GetDisplayModes(_THIS, SDL_VideoDisplay * display); -int RPI_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode); -int RPI_CreateWindow(_THIS, SDL_Window * window); -int RPI_CreateWindowFrom(_THIS, SDL_Window * window, const void *data); -void RPI_SetWindowTitle(_THIS, SDL_Window * window); -void RPI_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon); -void RPI_SetWindowPosition(_THIS, SDL_Window * window); -void RPI_SetWindowSize(_THIS, SDL_Window * window); -void RPI_ShowWindow(_THIS, SDL_Window * window); -void RPI_HideWindow(_THIS, SDL_Window * window); -void RPI_RaiseWindow(_THIS, SDL_Window * window); -void RPI_MaximizeWindow(_THIS, SDL_Window * window); -void RPI_MinimizeWindow(_THIS, SDL_Window * window); -void RPI_RestoreWindow(_THIS, SDL_Window * window); -void RPI_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed); -void RPI_DestroyWindow(_THIS, SDL_Window * window); +void RPI_GetDisplayModes(_THIS, SDL_VideoDisplay *display); +int RPI_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode); +int RPI_CreateWindow(_THIS, SDL_Window *window); +int RPI_CreateWindowFrom(_THIS, SDL_Window *window, const void *data); +void RPI_SetWindowTitle(_THIS, SDL_Window *window); +void RPI_SetWindowIcon(_THIS, SDL_Window *window, SDL_Surface *icon); +void RPI_SetWindowPosition(_THIS, SDL_Window *window); +void RPI_SetWindowSize(_THIS, SDL_Window *window); +void RPI_ShowWindow(_THIS, SDL_Window *window); +void RPI_HideWindow(_THIS, SDL_Window *window); +void RPI_RaiseWindow(_THIS, SDL_Window *window); +void RPI_MaximizeWindow(_THIS, SDL_Window *window); +void RPI_MinimizeWindow(_THIS, SDL_Window *window); +void RPI_RestoreWindow(_THIS, SDL_Window *window); +void RPI_DestroyWindow(_THIS, SDL_Window *window); /* Window manager function */ SDL_bool RPI_GetWindowWMInfo(_THIS, SDL_Window * window, @@ -92,11 +88,11 @@ SDL_bool RPI_GetWindowWMInfo(_THIS, SDL_Window * window, int RPI_GLES_LoadLibrary(_THIS, const char *path); void *RPI_GLES_GetProcAddress(_THIS, const char *proc); void RPI_GLES_UnloadLibrary(_THIS); -SDL_GLContext RPI_GLES_CreateContext(_THIS, SDL_Window * window); -int RPI_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context); +SDL_GLContext RPI_GLES_CreateContext(_THIS, SDL_Window *window); +int RPI_GLES_MakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context); int RPI_GLES_SetSwapInterval(_THIS, int interval); int RPI_GLES_GetSwapInterval(_THIS); -int RPI_GLES_SwapWindow(_THIS, SDL_Window * window); +int RPI_GLES_SwapWindow(_THIS, SDL_Window *window); void RPI_GLES_DeleteContext(_THIS, SDL_GLContext context); #endif /* __SDL_RPIVIDEO_H__ */ diff --git a/SDL2-2.30.5/src/video/riscos/SDL_riscosdefs.h b/SDL2-2.30.5/src/video/riscos/SDL_riscosdefs.h new file mode 100644 index 0000000..8a621c2 --- /dev/null +++ b/SDL2-2.30.5/src/video/riscos/SDL_riscosdefs.h @@ -0,0 +1,53 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifndef SDL_riscosdefs_h_ +#define SDL_riscosdefs_h_ + +typedef struct sprite_area +{ + int size; /* +0 */ + int count; /* +4 */ + int start; /* +8 */ + int end; /* +12 */ +} sprite_area; + +SDL_COMPILE_TIME_ASSERT(sprite_area, sizeof(sprite_area) == 16); + +typedef struct sprite_header +{ + int next; /* +0 */ + char name[12]; /* +4 */ + int width; /* +16 */ + int height; /* +20 */ + int first_bit; /* +24 */ + int last_bit; /* +28 */ + int image_offset; /* +32 */ + int mask_offset; /* +36 */ + int mode; /* +40 */ +} sprite_header; + +SDL_COMPILE_TIME_ASSERT(sprite_header, sizeof(sprite_header) == 44); + +#endif /* SDL_riscosdefs_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/riscos/SDL_riscosevents.c b/SDL2-2.30.5/src/video/riscos/SDL_riscosevents.c new file mode 100644 index 0000000..cebb89f --- /dev/null +++ b/SDL2-2.30.5/src/video/riscos/SDL_riscosevents.c @@ -0,0 +1,179 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_RISCOS + +#include "../../events/SDL_events_c.h" + +#include "SDL_log.h" +#include "SDL_riscosvideo.h" +#include "SDL_riscosevents_c.h" +#include "scancodes_riscos.h" + +#include +#include + +static SDL_Scancode SDL_RISCOS_translate_keycode(int keycode) +{ + SDL_Scancode scancode = SDL_SCANCODE_UNKNOWN; + + if (keycode < SDL_arraysize(riscos_scancode_table)) { + scancode = riscos_scancode_table[keycode]; + +#ifdef DEBUG_SCANCODES + if (scancode == SDL_SCANCODE_UNKNOWN) { + SDL_Log("The key you just pressed is not recognized by SDL: %d", keycode); + } +#endif + } + + return scancode; +} + +void RISCOS_PollKeyboard(_THIS) +{ + SDL_VideoData *driverdata = (SDL_VideoData *)_this->driverdata; + Uint8 key = 2; + int i; + + /* Check for key releases */ + for (i = 0; i < RISCOS_MAX_KEYS_PRESSED; i++) { + if (driverdata->key_pressed[i] != 255) { + if ((_kernel_osbyte(129, driverdata->key_pressed[i] ^ 0xff, 0xff) & 0xff) != 255) { + SDL_SendKeyboardKey(SDL_RELEASED, SDL_RISCOS_translate_keycode(driverdata->key_pressed[i])); + driverdata->key_pressed[i] = 255; + } + } + } + + /* Check for key presses */ + while (key < 0xff) { + key = _kernel_osbyte(121, key + 1, 0) & 0xff; + switch (key) { + case 255: + /* Ignore mouse keys */ + case 9: + case 10: + case 11: + /* Ignore keys with multiple INKEY codes */ + case 24: + case 40: + case 71: + case 87: + break; + + default: + SDL_SendKeyboardKey(SDL_PRESSED, SDL_RISCOS_translate_keycode(key)); + + /* Record the press so we can detect release later. */ + for (i = 0; i < RISCOS_MAX_KEYS_PRESSED; i++) { + if (driverdata->key_pressed[i] == key) { + break; + } + if (driverdata->key_pressed[i] == 255) { + driverdata->key_pressed[i] = key; + break; + } + } + } + } +} + +static const Uint8 mouse_button_map[] = { + SDL_BUTTON_RIGHT, + SDL_BUTTON_MIDDLE, + SDL_BUTTON_LEFT, + SDL_BUTTON_X1, + SDL_BUTTON_X2, + SDL_BUTTON_X2 + 1, + SDL_BUTTON_X2 + 2, + SDL_BUTTON_X2 + 3 +}; + +void RISCOS_PollMouse(_THIS) +{ + SDL_VideoData *driverdata = (SDL_VideoData *)_this->driverdata; + SDL_Mouse *mouse = SDL_GetMouse(); + SDL_Rect rect; + _kernel_swi_regs regs; + int i, x, y, buttons; + + if (SDL_GetDisplayBounds(0, &rect) < 0) { + return; + } + + _kernel_swi(OS_Mouse, ®s, ®s); + x = (regs.r[0] >> 1); + y = rect.h - (regs.r[1] >> 1); + buttons = regs.r[2]; + + if (mouse->x != x || mouse->y != y) { + SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 0, x, y); + } + + if (driverdata->last_mouse_buttons != buttons) { + for (i = 0; i < SDL_arraysize(mouse_button_map); i++) { + SDL_SendMouseButton(mouse->focus, mouse->mouseID, (buttons & (1 << i)) ? SDL_PRESSED : SDL_RELEASED, mouse_button_map[i]); + } + driverdata->last_mouse_buttons = buttons; + } +} + +int RISCOS_InitEvents(_THIS) +{ + SDL_VideoData *driverdata = (SDL_VideoData *)_this->driverdata; + _kernel_swi_regs regs; + int i, status; + + for (i = 0; i < RISCOS_MAX_KEYS_PRESSED; i++) { + driverdata->key_pressed[i] = 255; + } + + status = (_kernel_osbyte(202, 0, 255) & 0xFF); + SDL_ToggleModState(KMOD_NUM, (status & (1 << 2)) ? SDL_FALSE : SDL_TRUE); + SDL_ToggleModState(KMOD_CAPS, (status & (1 << 4)) ? SDL_FALSE : SDL_TRUE); + SDL_ToggleModState(KMOD_SCROLL, (status & (1 << 1)) ? SDL_TRUE : SDL_FALSE); + + _kernel_swi(OS_Mouse, ®s, ®s); + driverdata->last_mouse_buttons = regs.r[2]; + + /* Disable escape. */ + _kernel_osbyte(229, 1, 0); + + return 0; +} + +void RISCOS_PumpEvents(_THIS) +{ + RISCOS_PollMouse(_this); + RISCOS_PollKeyboard(_this); +} + +void RISCOS_QuitEvents(_THIS) +{ + /* Re-enable escape. */ + _kernel_osbyte(229, 0, 0); +} + +#endif /* SDL_VIDEO_DRIVER_RISCOS */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/riscos/SDL_riscosevents_c.h b/SDL2-2.30.5/src/video/riscos/SDL_riscosevents_c.h new file mode 100644 index 0000000..6f16b19 --- /dev/null +++ b/SDL2-2.30.5/src/video/riscos/SDL_riscosevents_c.h @@ -0,0 +1,35 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#ifndef SDL_riscosevents_c_h_ +#define SDL_riscosevents_c_h_ + +#include "../../SDL_internal.h" + +#include "SDL_riscosvideo.h" + +extern int RISCOS_InitEvents(_THIS); +extern void RISCOS_PumpEvents(_THIS); +extern void RISCOS_QuitEvents(_THIS); + +#endif /* SDL_riscosevents_c_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/riscos/SDL_riscosframebuffer.c b/SDL2-2.30.5/src/video/riscos/SDL_riscosframebuffer.c new file mode 100644 index 0000000..ae128d3 --- /dev/null +++ b/SDL2-2.30.5/src/video/riscos/SDL_riscosframebuffer.c @@ -0,0 +1,129 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_RISCOS + +#include "../SDL_sysvideo.h" +#include "SDL_riscosframebuffer_c.h" +#include "SDL_riscosvideo.h" +#include "SDL_riscoswindow.h" + +#include +#include + +int RISCOS_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format, void **pixels, int *pitch) +{ + SDL_WindowData *driverdata = (SDL_WindowData *)window->driverdata; + const char *sprite_name = "display"; + unsigned int sprite_mode; + _kernel_oserror *error; + _kernel_swi_regs regs; + SDL_DisplayMode mode; + int size; + int w, h; + + SDL_GetWindowSizeInPixels(window, &w, &h); + + /* Free the old framebuffer surface */ + RISCOS_DestroyWindowFramebuffer(_this, window); + + /* Create a new one */ + SDL_GetCurrentDisplayMode(SDL_GetWindowDisplayIndex(window), &mode); + if ((SDL_ISPIXELFORMAT_PACKED(mode.format) || SDL_ISPIXELFORMAT_ARRAY(mode.format))) { + *format = mode.format; + sprite_mode = (unsigned int)mode.driverdata; + } else { + *format = SDL_PIXELFORMAT_BGR888; + sprite_mode = (1 | (90 << 1) | (90 << 14) | (6 << 27)); + } + + /* Calculate pitch */ + *pitch = (((w * SDL_BYTESPERPIXEL(*format)) + 3) & ~3); + + /* Allocate the sprite area */ + size = sizeof(sprite_area) + sizeof(sprite_header) + ((*pitch) * h); + driverdata->fb_area = SDL_malloc(size); + if (!driverdata->fb_area) { + return SDL_OutOfMemory(); + } + + driverdata->fb_area->size = size; + driverdata->fb_area->count = 0; + driverdata->fb_area->start = 16; + driverdata->fb_area->end = 16; + + /* Create the actual image */ + regs.r[0] = 256 + 15; + regs.r[1] = (int)driverdata->fb_area; + regs.r[2] = (int)sprite_name; + regs.r[3] = 0; + regs.r[4] = w; + regs.r[5] = h; + regs.r[6] = sprite_mode; + error = _kernel_swi(OS_SpriteOp, ®s, ®s); + if (error) { + SDL_free(driverdata->fb_area); + return SDL_SetError("Unable to create sprite: %s (%i)", error->errmess, error->errnum); + } + + driverdata->fb_sprite = (sprite_header *)(((Uint8 *)driverdata->fb_area) + driverdata->fb_area->start); + *pixels = ((Uint8 *)driverdata->fb_sprite) + driverdata->fb_sprite->image_offset; + + return 0; +} + +int RISCOS_UpdateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_Rect *rects, int numrects) +{ + SDL_WindowData *driverdata = (SDL_WindowData *)window->driverdata; + _kernel_swi_regs regs; + _kernel_oserror *error; + + regs.r[0] = 512 + 52; + regs.r[1] = (int)driverdata->fb_area; + regs.r[2] = (int)driverdata->fb_sprite; + regs.r[3] = 0; /* window->x << 1; */ + regs.r[4] = 0; /* window->y << 1; */ + regs.r[5] = 0x50; + regs.r[6] = 0; + regs.r[7] = 0; + error = _kernel_swi(OS_SpriteOp, ®s, ®s); + if (error) { + return SDL_SetError("OS_SpriteOp 52 failed: %s (%i)", error->errmess, error->errnum); + } + + return 0; +} + +void RISCOS_DestroyWindowFramebuffer(_THIS, SDL_Window *window) +{ + SDL_WindowData *driverdata = (SDL_WindowData *)window->driverdata; + + if (driverdata->fb_area) { + SDL_free(driverdata->fb_area); + driverdata->fb_area = NULL; + } + driverdata->fb_sprite = NULL; +} + +#endif /* SDL_VIDEO_DRIVER_RISCOS */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/riscos/SDL_riscosframebuffer_c.h b/SDL2-2.30.5/src/video/riscos/SDL_riscosframebuffer_c.h new file mode 100644 index 0000000..e4f79ad --- /dev/null +++ b/SDL2-2.30.5/src/video/riscos/SDL_riscosframebuffer_c.h @@ -0,0 +1,33 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#ifndef SDL_riscosframebuffer_c_h_ +#define SDL_riscosframebuffer_c_h_ + +#include "../../SDL_internal.h" + +extern int RISCOS_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format, void **pixels, int *pitch); +extern int RISCOS_UpdateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_Rect *rects, int numrects); +extern void RISCOS_DestroyWindowFramebuffer(_THIS, SDL_Window *window); + +#endif /* SDL_riscosframebuffer_c_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/riscos/SDL_riscosmessagebox.c b/SDL2-2.30.5/src/video/riscos/SDL_riscosmessagebox.c new file mode 100644 index 0000000..9d44e07 --- /dev/null +++ b/SDL2-2.30.5/src/video/riscos/SDL_riscosmessagebox.c @@ -0,0 +1,70 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_RISCOS + +#include "SDL_messagebox.h" +#include "SDL_riscosmessagebox.h" + +#include +#include + +int RISCOS_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) +{ + _kernel_swi_regs regs; + _kernel_oserror error; + char buttonstring[1024]; + int i; + + error.errnum = 0; + SDL_strlcpy(error.errmess, messageboxdata->message, 252); + regs.r[0] = (unsigned int)&error; + + regs.r[1] = (1 << 8) | (1 << 4); + if (messageboxdata->flags == SDL_MESSAGEBOX_INFORMATION) { + regs.r[1] |= (1 << 9); + } else if (messageboxdata->flags == SDL_MESSAGEBOX_WARNING) { + regs.r[1] |= (2 << 9); + } + + regs.r[2] = (unsigned int)messageboxdata->title; + regs.r[3] = 0; + regs.r[4] = 0; + + SDL_strlcpy(buttonstring, "", 1024); + for (i = 0; i < messageboxdata->numbuttons; i++) { + SDL_strlcat(buttonstring, messageboxdata->buttons[i].text, 1024); + if (i + 1 < messageboxdata->numbuttons) { + SDL_strlcat(buttonstring, ",", 1024); + } + } + regs.r[5] = (unsigned int)buttonstring; + + _kernel_swi(Wimp_ReportError, ®s, ®s); + + *buttonid = (regs.r[1] == 0) ? -1 : messageboxdata->buttons[regs.r[1] - 3].buttonid; + return 0; +} + +#endif /* SDL_VIDEO_DRIVER_RISCOS */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/riscos/SDL_riscosmessagebox.h b/SDL2-2.30.5/src/video/riscos/SDL_riscosmessagebox.h new file mode 100644 index 0000000..09f9c76 --- /dev/null +++ b/SDL2-2.30.5/src/video/riscos/SDL_riscosmessagebox.h @@ -0,0 +1,29 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_RISCOS + +extern int RISCOS_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid); + +#endif /* SDL_VIDEO_DRIVER_RISCOS */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/riscos/SDL_riscosmodes.c b/SDL2-2.30.5/src/video/riscos/SDL_riscosmodes.c new file mode 100644 index 0000000..79f5fa3 --- /dev/null +++ b/SDL2-2.30.5/src/video/riscos/SDL_riscosmodes.c @@ -0,0 +1,310 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_RISCOS + +#include "../SDL_sysvideo.h" +#include "../../events/SDL_mouse_c.h" + +#include "SDL_riscosvideo.h" +#include "SDL_riscosmodes.h" + +#include +#include + +enum +{ + MODE_FLAG_565 = 1 << 7, + + MODE_FLAG_COLOUR_SPACE = 0xF << 12, + + MODE_FLAG_TBGR = 0, + MODE_FLAG_TRGB = 1 << 14, + MODE_FLAG_ABGR = 1 << 15, + MODE_FLAG_ARGB = MODE_FLAG_TRGB | MODE_FLAG_ABGR +}; + +static const struct +{ + SDL_PixelFormatEnum pixel_format; + int modeflags, ncolour, log2bpp; +} mode_to_pixelformat[] = { + /* { SDL_PIXELFORMAT_INDEX1LSB, 0, 1, 0 }, */ + /* { SDL_PIXELFORMAT_INDEX2LSB, 0, 3, 1 }, */ + /* { SDL_PIXELFORMAT_INDEX4LSB, 0, 15, 2 }, */ + /* { SDL_PIXELFORMAT_INDEX8, MODE_FLAG_565, 255, 3 }, */ + { SDL_PIXELFORMAT_XBGR1555, MODE_FLAG_TBGR, 65535, 4 }, + { SDL_PIXELFORMAT_XRGB1555, MODE_FLAG_TRGB, 65535, 4 }, + { SDL_PIXELFORMAT_ABGR1555, MODE_FLAG_ABGR, 65535, 4 }, + { SDL_PIXELFORMAT_ARGB1555, MODE_FLAG_ARGB, 65535, 4 }, + { SDL_PIXELFORMAT_XBGR4444, MODE_FLAG_TBGR, 4095, 4 }, + { SDL_PIXELFORMAT_XRGB4444, MODE_FLAG_TRGB, 4095, 4 }, + { SDL_PIXELFORMAT_ABGR4444, MODE_FLAG_ABGR, 4095, 4 }, + { SDL_PIXELFORMAT_ARGB4444, MODE_FLAG_ARGB, 4095, 4 }, + { SDL_PIXELFORMAT_BGR565, MODE_FLAG_TBGR | MODE_FLAG_565, 65535, 4 }, + { SDL_PIXELFORMAT_RGB565, MODE_FLAG_TRGB | MODE_FLAG_565, 65535, 4 }, + { SDL_PIXELFORMAT_BGR24, MODE_FLAG_TBGR, 16777215, 6 }, + { SDL_PIXELFORMAT_RGB24, MODE_FLAG_TRGB, 16777215, 6 }, + { SDL_PIXELFORMAT_XBGR8888, MODE_FLAG_TBGR, -1, 5 }, + { SDL_PIXELFORMAT_XRGB8888, MODE_FLAG_TRGB, -1, 5 }, + { SDL_PIXELFORMAT_ABGR8888, MODE_FLAG_ABGR, -1, 5 }, + { SDL_PIXELFORMAT_ARGB8888, MODE_FLAG_ARGB, -1, 5 } +}; + +static SDL_PixelFormatEnum RISCOS_ModeToPixelFormat(int ncolour, int modeflags, int log2bpp) +{ + int i; + + for (i = 0; i < SDL_arraysize(mode_to_pixelformat); i++) { + if (log2bpp == mode_to_pixelformat[i].log2bpp && + (ncolour == mode_to_pixelformat[i].ncolour || ncolour == 0) && + (modeflags & (MODE_FLAG_565 | MODE_FLAG_COLOUR_SPACE)) == mode_to_pixelformat[i].modeflags) { + return mode_to_pixelformat[i].pixel_format; + } + } + + return SDL_PIXELFORMAT_UNKNOWN; +} + +static size_t measure_mode_block(const int *block) +{ + size_t blockSize = ((block[0] & 0xFF) == 3) ? 7 : 5; + while (block[blockSize] != -1) { + blockSize += 2; + } + blockSize++; + + return blockSize * 4; +} + +static int read_mode_variable(int *block, int var) +{ + _kernel_swi_regs regs; + regs.r[0] = (int)block; + regs.r[1] = var; + _kernel_swi(OS_ReadModeVariable, ®s, ®s); + return regs.r[2]; +} + +static SDL_bool read_mode_block(int *block, SDL_DisplayMode *mode, SDL_bool extended) +{ + int xres, yres, ncolour, modeflags, log2bpp, rate; + + if ((block[0] & 0xFF) == 1) { + xres = block[1]; + yres = block[2]; + log2bpp = block[3]; + rate = block[4]; + ncolour = (1 << (1 << log2bpp)) - 1; + modeflags = MODE_FLAG_TBGR; + } else if ((block[0] & 0xFF) == 3) { + xres = block[1]; + yres = block[2]; + ncolour = block[3]; + modeflags = block[4]; + log2bpp = block[5]; + rate = block[6]; + } else { + return SDL_FALSE; + } + + if (extended) { + xres = read_mode_variable(block, 11) + 1; + yres = read_mode_variable(block, 12) + 1; + log2bpp = read_mode_variable(block, 9); + ncolour = read_mode_variable(block, 3); + modeflags = read_mode_variable(block, 0); + } + + mode->w = xres; + mode->h = yres; + mode->format = RISCOS_ModeToPixelFormat(ncolour, modeflags, log2bpp); + mode->refresh_rate = rate; + + return SDL_TRUE; +} + +static void *convert_mode_block(const int *block) +{ + int xres, yres, log2bpp, rate, ncolour = 0, modeflags = 0; + size_t pos = 0; + int *dst; + + if ((block[0] & 0xFF) == 1) { + xres = block[1]; + yres = block[2]; + log2bpp = block[3]; + rate = block[4]; + } else if ((block[0] & 0xFF) == 3) { + xres = block[1]; + yres = block[2]; + ncolour = block[3]; + modeflags = block[4]; + log2bpp = block[5]; + rate = block[6]; + } else { + return NULL; + } + + dst = SDL_malloc(40); + if (!dst) { + return NULL; + } + + dst[pos++] = 1; + dst[pos++] = xres; + dst[pos++] = yres; + dst[pos++] = log2bpp; + dst[pos++] = rate; + if (ncolour != 0) { + dst[pos++] = 3; + dst[pos++] = ncolour; + } + if (modeflags != 0) { + dst[pos++] = 0; + dst[pos++] = modeflags; + } + dst[pos++] = -1; + + return dst; +} + +static void *copy_memory(const void *src, size_t size, size_t alloc) +{ + void *dst = SDL_malloc(alloc); + if (dst) { + SDL_memcpy(dst, src, size); + } + return dst; +} + +int RISCOS_InitModes(_THIS) +{ + SDL_DisplayMode mode; + int *current_mode; + _kernel_swi_regs regs; + _kernel_oserror *error; + size_t size; + + regs.r[0] = 1; + error = _kernel_swi(OS_ScreenMode, ®s, ®s); + if (error) { + return SDL_SetError("Unable to retrieve the current screen mode: %s (%i)", error->errmess, error->errnum); + } + + current_mode = (int *)regs.r[1]; + if (!read_mode_block(current_mode, &mode, SDL_TRUE)) { + return SDL_SetError("Unsupported mode block format %d", current_mode[0]); + } + + size = measure_mode_block(current_mode); + mode.driverdata = copy_memory(current_mode, size, size); + if (!mode.driverdata) { + return SDL_OutOfMemory(); + } + + return SDL_AddBasicVideoDisplay(&mode); +} + +void RISCOS_GetDisplayModes(_THIS, SDL_VideoDisplay *display) +{ + SDL_DisplayMode mode; + _kernel_swi_regs regs; + _kernel_oserror *error; + void *block, *pos; + + regs.r[0] = 2; + regs.r[2] = 0; + regs.r[6] = 0; + regs.r[7] = 0; + error = _kernel_swi(OS_ScreenMode, ®s, ®s); + if (error) { + SDL_SetError("Unable to enumerate screen modes: %s (%i)", error->errmess, error->errnum); + return; + } + + block = SDL_malloc(-regs.r[7]); + if (!block) { + SDL_OutOfMemory(); + return; + } + + regs.r[6] = (int)block; + regs.r[7] = -regs.r[7]; + error = _kernel_swi(OS_ScreenMode, ®s, ®s); + if (error) { + SDL_free(block); + SDL_SetError("Unable to enumerate screen modes: %s (%i)", error->errmess, error->errnum); + return; + } + + for (pos = block; pos < (void *)regs.r[6]; pos += *((int *)pos)) { + if (!read_mode_block(pos + 4, &mode, SDL_FALSE)) { + continue; + } + + if (mode.format == SDL_PIXELFORMAT_UNKNOWN) { + continue; + } + + mode.driverdata = convert_mode_block(pos + 4); + if (!mode.driverdata) { + SDL_OutOfMemory(); + break; + } + + if (!SDL_AddDisplayMode(display, &mode)) { + SDL_free(mode.driverdata); + } + } + + SDL_free(block); +} + +int RISCOS_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode) +{ + const char disable_cursor[] = { 23, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + _kernel_swi_regs regs; + _kernel_oserror *error; + int i; + + regs.r[0] = 0; + regs.r[1] = (int)mode->driverdata; + error = _kernel_swi(OS_ScreenMode, ®s, ®s); + if (error) { + return SDL_SetError("Unable to set the current screen mode: %s (%i)", error->errmess, error->errnum); + } + + /* Turn the text cursor off */ + for (i = 0; i < SDL_arraysize(disable_cursor); i++) { + _kernel_oswrch(disable_cursor[i]); + } + + /* Update cursor visibility, since it may have been disabled by the mode change. */ + SDL_SetCursor(NULL); + + return 0; +} + +#endif /* SDL_VIDEO_DRIVER_RISCOS */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/riscos/SDL_riscosmodes.h b/SDL2-2.30.5/src/video/riscos/SDL_riscosmodes.h new file mode 100644 index 0000000..f523dd4 --- /dev/null +++ b/SDL2-2.30.5/src/video/riscos/SDL_riscosmodes.h @@ -0,0 +1,33 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifndef SDL_riscosmodes_h_ +#define SDL_riscosmodes_h_ + +extern int RISCOS_InitModes(_THIS); +extern void RISCOS_GetDisplayModes(_THIS, SDL_VideoDisplay *display); +extern int RISCOS_SetDisplayMode(_THIS, SDL_VideoDisplay *display, + SDL_DisplayMode *mode); + +#endif /* SDL_riscosmodes_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/riscos/SDL_riscosmouse.c b/SDL2-2.30.5/src/video/riscos/SDL_riscosmouse.c new file mode 100644 index 0000000..90c6de0 --- /dev/null +++ b/SDL2-2.30.5/src/video/riscos/SDL_riscosmouse.c @@ -0,0 +1,83 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_RISCOS + +#include "../../events/SDL_mouse_c.h" + +#include + +static SDL_Cursor *RISCOS_CreateDefaultCursor() +{ + SDL_Cursor *cursor; + + cursor = SDL_calloc(1, sizeof(*cursor)); + if (cursor) { + /* NULL is used to indicate the default cursor */ + cursor->driverdata = NULL; + } else { + SDL_OutOfMemory(); + } + + return cursor; +} + +static void RISCOS_FreeCursor(SDL_Cursor *cursor) +{ + SDL_free(cursor); +} + +static int RISCOS_ShowCursor(SDL_Cursor *cursor) +{ + if (cursor) { + /* Turn the mouse pointer on */ + _kernel_osbyte(106, 1, 0); + } else { + /* Turn the mouse pointer off */ + _kernel_osbyte(106, 0, 0); + } + + return 0; +} + +int RISCOS_InitMouse(_THIS) +{ + SDL_Mouse *mouse = SDL_GetMouse(); + + /* mouse->CreateCursor = RISCOS_CreateCursor; */ + /* mouse->CreateSystemCursor = RISCOS_CreateSystemCursor; */ + mouse->ShowCursor = RISCOS_ShowCursor; + mouse->FreeCursor = RISCOS_FreeCursor; + /* mouse->WarpMouse = RISCOS_WarpMouse; */ + /* mouse->WarpMouseGlobal = RISCOS_WarpMouseGlobal; */ + /* mouse->SetRelativeMouseMode = RISCOS_SetRelativeMouseMode; */ + /* mouse->CaptureMouse = RISCOS_CaptureMouse; */ + /* mouse->GetGlobalMouseState = RISCOS_GetGlobalMouseState; */ + + SDL_SetDefaultCursor(RISCOS_CreateDefaultCursor()); + + return 0; +} + +#endif /* SDL_VIDEO_DRIVER_RISCOS */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/riscos/SDL_riscosmouse.h b/SDL2-2.30.5/src/video/riscos/SDL_riscosmouse.h new file mode 100644 index 0000000..e675d84 --- /dev/null +++ b/SDL2-2.30.5/src/video/riscos/SDL_riscosmouse.h @@ -0,0 +1,30 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifndef SDL_riscosmouse_h_ +#define SDL_riscosmouse_h_ + +extern int RISCOS_InitMouse(_THIS); + +#endif /* SDL_riscosmouse_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/riscos/SDL_riscosvideo.c b/SDL2-2.30.5/src/video/riscos/SDL_riscosvideo.c new file mode 100644 index 0000000..1550139 --- /dev/null +++ b/SDL2-2.30.5/src/video/riscos/SDL_riscosvideo.c @@ -0,0 +1,127 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_RISCOS + +#include "SDL_video.h" +#include "SDL_mouse.h" +#include "../SDL_sysvideo.h" +#include "../SDL_pixels_c.h" +#include "../../events/SDL_events_c.h" + +#include "SDL_riscosvideo.h" +#include "SDL_riscosevents_c.h" +#include "SDL_riscosframebuffer_c.h" +#include "SDL_riscosmouse.h" +#include "SDL_riscosmodes.h" +#include "SDL_riscoswindow.h" +#include "SDL_riscosmessagebox.h" + +#define RISCOSVID_DRIVER_NAME "riscos" + +/* Initialization/Query functions */ +static int RISCOS_VideoInit(_THIS); +static void RISCOS_VideoQuit(_THIS); + +/* RISC OS driver bootstrap functions */ + +static void RISCOS_DeleteDevice(SDL_VideoDevice *device) +{ + SDL_free(device->driverdata); + SDL_free(device); +} + +static SDL_VideoDevice *RISCOS_CreateDevice(void) +{ + SDL_VideoDevice *device; + SDL_VideoData *phdata; + + /* Initialize all variables that we clean on shutdown */ + device = (SDL_VideoDevice *)SDL_calloc(1, sizeof(SDL_VideoDevice)); + if (!device) { + SDL_OutOfMemory(); + return 0; + } + + /* Initialize internal data */ + phdata = (SDL_VideoData *)SDL_calloc(1, sizeof(SDL_VideoData)); + if (!phdata) { + SDL_OutOfMemory(); + SDL_free(device); + return NULL; + } + + device->driverdata = phdata; + + /* Set the function pointers */ + device->VideoInit = RISCOS_VideoInit; + device->VideoQuit = RISCOS_VideoQuit; + device->PumpEvents = RISCOS_PumpEvents; + + device->GetDisplayModes = RISCOS_GetDisplayModes; + device->SetDisplayMode = RISCOS_SetDisplayMode; + + device->CreateSDLWindow = RISCOS_CreateWindow; + device->DestroyWindow = RISCOS_DestroyWindow; + device->GetWindowWMInfo = RISCOS_GetWindowWMInfo; + + device->CreateWindowFramebuffer = RISCOS_CreateWindowFramebuffer; + device->UpdateWindowFramebuffer = RISCOS_UpdateWindowFramebuffer; + device->DestroyWindowFramebuffer = RISCOS_DestroyWindowFramebuffer; + + device->free = RISCOS_DeleteDevice; + + return device; +} + +VideoBootStrap RISCOS_bootstrap = { + RISCOSVID_DRIVER_NAME, "SDL RISC OS video driver", + RISCOS_CreateDevice, + RISCOS_ShowMessageBox +}; + +static int RISCOS_VideoInit(_THIS) +{ + if (RISCOS_InitEvents(_this) < 0) { + return -1; + } + + if (RISCOS_InitMouse(_this) < 0) { + return -1; + } + + if (RISCOS_InitModes(_this) < 0) { + return -1; + } + + /* We're done! */ + return 0; +} + +static void RISCOS_VideoQuit(_THIS) +{ + RISCOS_QuitEvents(_this); +} + +#endif /* SDL_VIDEO_DRIVER_RISCOS */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/riscos/SDL_riscosvideo.h b/SDL2-2.30.5/src/video/riscos/SDL_riscosvideo.h new file mode 100644 index 0000000..d014458 --- /dev/null +++ b/SDL2-2.30.5/src/video/riscos/SDL_riscosvideo.h @@ -0,0 +1,38 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifndef SDL_riscosvideo_h_ +#define SDL_riscosvideo_h_ + +#include "../SDL_sysvideo.h" + +#define RISCOS_MAX_KEYS_PRESSED 6 + +typedef struct SDL_VideoData +{ + int last_mouse_buttons; + Uint8 key_pressed[RISCOS_MAX_KEYS_PRESSED]; +} SDL_VideoData; + +#endif /* SDL_riscosvideo_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/riscos/SDL_riscoswindow.c b/SDL2-2.30.5/src/video/riscos/SDL_riscoswindow.c new file mode 100644 index 0000000..5a59c49 --- /dev/null +++ b/SDL2-2.30.5/src/video/riscos/SDL_riscoswindow.c @@ -0,0 +1,79 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_RISCOS + +#include "SDL_version.h" +#include "SDL_syswm.h" +#include "../SDL_sysvideo.h" +#include "../../events/SDL_mouse_c.h" + + +#include "SDL_riscosvideo.h" +#include "SDL_riscoswindow.h" + +int RISCOS_CreateWindow(_THIS, SDL_Window *window) +{ + SDL_WindowData *driverdata; + + driverdata = (SDL_WindowData *)SDL_calloc(1, sizeof(*driverdata)); + if (!driverdata) { + return SDL_OutOfMemory(); + } + driverdata->window = window; + + window->flags |= SDL_WINDOW_FULLSCREEN; + + SDL_SetMouseFocus(window); + + /* All done! */ + window->driverdata = driverdata; + return 0; +} + +void RISCOS_DestroyWindow(_THIS, SDL_Window *window) +{ + SDL_WindowData *driverdata = (SDL_WindowData *)window->driverdata; + + if (!driverdata) { + return; + } + + SDL_free(driverdata); + window->driverdata = NULL; +} + +SDL_bool RISCOS_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info) +{ + if (info->version.major == SDL_MAJOR_VERSION) { + info->subsystem = SDL_SYSWM_RISCOS; + return SDL_TRUE; + } else { + SDL_SetError("Application not compiled with SDL %d", + SDL_MAJOR_VERSION); + return SDL_FALSE; + } +} + +#endif /* SDL_VIDEO_DRIVER_RISCOS */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/riscos/SDL_riscoswindow.h b/SDL2-2.30.5/src/video/riscos/SDL_riscoswindow.h new file mode 100644 index 0000000..48d17ba --- /dev/null +++ b/SDL2-2.30.5/src/video/riscos/SDL_riscoswindow.h @@ -0,0 +1,42 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifndef SDL_riscoswindow_h_ +#define SDL_riscoswindow_h_ + +#include "SDL_riscosdefs.h" + +typedef struct +{ + SDL_Window *window; + sprite_area *fb_area; + sprite_header *fb_sprite; +} SDL_WindowData; + +extern int RISCOS_CreateWindow(_THIS, SDL_Window * window); +extern void RISCOS_DestroyWindow(_THIS, SDL_Window * window); +extern SDL_bool RISCOS_GetWindowWMInfo(_THIS, SDL_Window * window, + struct SDL_SysWMinfo *info); + +#endif /* SDL_riscoswindow_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/riscos/scancodes_riscos.h b/SDL2-2.30.5/src/video/riscos/scancodes_riscos.h new file mode 100644 index 0000000..1caa33a --- /dev/null +++ b/SDL2-2.30.5/src/video/riscos/scancodes_riscos.h @@ -0,0 +1,158 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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_scancode.h" + +/* RISC OS key code to SDL_Keycode mapping table + Sources: + - https://www.riscosopen.org/wiki/documentation/show/Keyboard Scan Codes +*/ +/* *INDENT-OFF* */ /* clang-format off */ +static SDL_Scancode const riscos_scancode_table[] = { + /* 0 */ SDL_SCANCODE_UNKNOWN, /* Shift */ + /* 1 */ SDL_SCANCODE_UNKNOWN, /* Ctrl */ + /* 2 */ SDL_SCANCODE_UNKNOWN, /* Alt */ + /* 3 */ SDL_SCANCODE_LSHIFT, + /* 4 */ SDL_SCANCODE_LCTRL, + /* 5 */ SDL_SCANCODE_LALT, + /* 6 */ SDL_SCANCODE_RSHIFT, + /* 7 */ SDL_SCANCODE_RCTRL, + /* 8 */ SDL_SCANCODE_RALT, + /* 9 */ SDL_SCANCODE_UNKNOWN, /* Left mouse */ + /* 10 */ SDL_SCANCODE_UNKNOWN, /* Center mouse */ + /* 11 */ SDL_SCANCODE_UNKNOWN, /* Right mouse */ + /* 12 */ SDL_SCANCODE_UNKNOWN, + /* 13 */ SDL_SCANCODE_UNKNOWN, + /* 14 */ SDL_SCANCODE_UNKNOWN, + /* 15 */ SDL_SCANCODE_UNKNOWN, + /* 16 */ SDL_SCANCODE_Q, + /* 17 */ SDL_SCANCODE_3, + /* 18 */ SDL_SCANCODE_4, + /* 19 */ SDL_SCANCODE_5, + /* 20 */ SDL_SCANCODE_F4, + /* 21 */ SDL_SCANCODE_8, + /* 22 */ SDL_SCANCODE_F7, + /* 23 */ SDL_SCANCODE_MINUS, + /* 24 */ SDL_SCANCODE_6, /* Duplicate of 52 */ + /* 25 */ SDL_SCANCODE_LEFT, + /* 26 */ SDL_SCANCODE_KP_6, + /* 27 */ SDL_SCANCODE_KP_7, + /* 28 */ SDL_SCANCODE_F11, + /* 29 */ SDL_SCANCODE_F12, + /* 30 */ SDL_SCANCODE_F10, + /* 31 */ SDL_SCANCODE_SCROLLLOCK, + /* 32 */ SDL_SCANCODE_PRINTSCREEN, + /* 33 */ SDL_SCANCODE_W, + /* 34 */ SDL_SCANCODE_E, + /* 35 */ SDL_SCANCODE_T, + /* 36 */ SDL_SCANCODE_7, + /* 37 */ SDL_SCANCODE_I, + /* 38 */ SDL_SCANCODE_9, + /* 39 */ SDL_SCANCODE_0, + /* 40 */ SDL_SCANCODE_MINUS, /* Duplicate of 23 */ + /* 41 */ SDL_SCANCODE_DOWN, + /* 42 */ SDL_SCANCODE_KP_8, + /* 43 */ SDL_SCANCODE_KP_9, + /* 44 */ SDL_SCANCODE_PAUSE, + /* 45 */ SDL_SCANCODE_GRAVE, + /* 46 */ SDL_SCANCODE_CURRENCYUNIT, + /* 47 */ SDL_SCANCODE_BACKSPACE, + /* 48 */ SDL_SCANCODE_1, + /* 49 */ SDL_SCANCODE_2, + /* 50 */ SDL_SCANCODE_D, + /* 51 */ SDL_SCANCODE_R, + /* 52 */ SDL_SCANCODE_6, + /* 53 */ SDL_SCANCODE_U, + /* 54 */ SDL_SCANCODE_O, + /* 55 */ SDL_SCANCODE_P, + /* 56 */ SDL_SCANCODE_LEFTBRACKET, + /* 57 */ SDL_SCANCODE_UP, + /* 58 */ SDL_SCANCODE_KP_PLUS, + /* 59 */ SDL_SCANCODE_KP_MINUS, + /* 60 */ SDL_SCANCODE_KP_ENTER, + /* 61 */ SDL_SCANCODE_INSERT, + /* 62 */ SDL_SCANCODE_HOME, + /* 63 */ SDL_SCANCODE_PAGEUP, + /* 64 */ SDL_SCANCODE_CAPSLOCK, + /* 65 */ SDL_SCANCODE_A, + /* 66 */ SDL_SCANCODE_X, + /* 67 */ SDL_SCANCODE_F, + /* 68 */ SDL_SCANCODE_Y, + /* 69 */ SDL_SCANCODE_J, + /* 70 */ SDL_SCANCODE_K, + /* 71 */ SDL_SCANCODE_2, /* Duplicate of 49 */ + /* 72 */ SDL_SCANCODE_SEMICOLON, /* Duplicate of 87 */ + /* 73 */ SDL_SCANCODE_RETURN, + /* 74 */ SDL_SCANCODE_KP_DIVIDE, + /* 75 */ SDL_SCANCODE_UNKNOWN, + /* 76 */ SDL_SCANCODE_KP_PERIOD, + /* 77 */ SDL_SCANCODE_NUMLOCKCLEAR, + /* 78 */ SDL_SCANCODE_PAGEDOWN, + /* 79 */ SDL_SCANCODE_APOSTROPHE, + /* 80 */ SDL_SCANCODE_UNKNOWN, + /* 81 */ SDL_SCANCODE_S, + /* 82 */ SDL_SCANCODE_C, + /* 83 */ SDL_SCANCODE_G, + /* 84 */ SDL_SCANCODE_H, + /* 85 */ SDL_SCANCODE_N, + /* 86 */ SDL_SCANCODE_L, + /* 87 */ SDL_SCANCODE_SEMICOLON, + /* 88 */ SDL_SCANCODE_RIGHTBRACKET, + /* 89 */ SDL_SCANCODE_DELETE, + /* 90 */ SDL_SCANCODE_KP_HASH, + /* 91 */ SDL_SCANCODE_KP_MULTIPLY, + /* 92 */ SDL_SCANCODE_UNKNOWN, + /* 93 */ SDL_SCANCODE_EQUALS, + /* 94 */ SDL_SCANCODE_NONUSBACKSLASH, + /* 95 */ SDL_SCANCODE_UNKNOWN, + /* 96 */ SDL_SCANCODE_TAB, + /* 97 */ SDL_SCANCODE_Z, + /* 98 */ SDL_SCANCODE_SPACE, + /* 99 */ SDL_SCANCODE_V, + /* 100 */ SDL_SCANCODE_B, + /* 101 */ SDL_SCANCODE_M, + /* 102 */ SDL_SCANCODE_COMMA, + /* 103 */ SDL_SCANCODE_PERIOD, + /* 104 */ SDL_SCANCODE_SLASH, + /* 105 */ SDL_SCANCODE_END, + /* 106 */ SDL_SCANCODE_KP_0, + /* 107 */ SDL_SCANCODE_KP_1, + /* 108 */ SDL_SCANCODE_KP_3, + /* 109 */ SDL_SCANCODE_UNKNOWN, + /* 110 */ SDL_SCANCODE_UNKNOWN, + /* 111 */ SDL_SCANCODE_UNKNOWN, + /* 112 */ SDL_SCANCODE_ESCAPE, + /* 113 */ SDL_SCANCODE_F1, + /* 114 */ SDL_SCANCODE_F2, + /* 115 */ SDL_SCANCODE_F3, + /* 116 */ SDL_SCANCODE_F5, + /* 117 */ SDL_SCANCODE_F6, + /* 118 */ SDL_SCANCODE_F8, + /* 119 */ SDL_SCANCODE_F9, + /* 120 */ SDL_SCANCODE_BACKSLASH, + /* 121 */ SDL_SCANCODE_RIGHT, + /* 122 */ SDL_SCANCODE_KP_4, + /* 123 */ SDL_SCANCODE_KP_5, + /* 124 */ SDL_SCANCODE_KP_2, + /* 125 */ SDL_SCANCODE_LGUI, + /* 126 */ SDL_SCANCODE_RGUI, + /* 127 */ SDL_SCANCODE_MENU +}; +/* *INDENT-ON* */ /* clang-format on */ diff --git a/SDL2-2.0.12/src/video/sdlgenblit.pl b/SDL2-2.30.5/src/video/sdlgenblit.pl similarity index 85% rename from SDL2-2.0.12/src/video/sdlgenblit.pl rename to SDL2-2.30.5/src/video/sdlgenblit.pl index 6206ec2..4afef7a 100644 --- a/SDL2-2.0.12/src/video/sdlgenblit.pl +++ b/SDL2-2.30.5/src/video/sdlgenblit.pl @@ -92,7 +92,7 @@ sub open_file { /* DO NOT EDIT! This file is generated by sdlgenblit.pl */ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -114,7 +114,7 @@ sub open_file { #if SDL_HAVE_BLIT_AUTO -/* *INDENT-OFF* */ +/* *INDENT-OFF* */ /* clang-format off */ __EOF__ } @@ -122,7 +122,7 @@ __EOF__ sub close_file { my $name = shift; print FILE <<__EOF__; -/* *INDENT-ON* */ +/* *INDENT-ON* */ /* clang-format on */ #endif /* SDL_HAVE_BLIT_AUTO */ @@ -220,16 +220,82 @@ sub output_copycore my $A_is_const_FF = shift; my $s = ""; my $d = ""; + my $dst_has_alpha = ($dst =~ /A/) ? 1 : 0; + my $src_has_alpha = ($src =~ /A/) ? 1 : 0; + my $sa = ""; + my $da = ""; - # Nice and easy... - if ( $src eq $dst && !$modulate && !$blend ) { - print FILE <<__EOF__; + if (!$modulate && !$blend) { + # Nice and easy... + if ( $src eq $dst ) { + print FILE <<__EOF__; *dst = *src; __EOF__ - return; + return; + } + + # Matching color-order + $sa = $src; + $sa =~ s/[A8]//g; + $da = $dst; + $da =~ s/[A8]//g; + if ($sa eq $da) { + if ($dst_has_alpha && $src_has_alpha) { + $da = substr $dst, 0, 1; + if ($da eq "A") { + # RGBA -> ARGB + print FILE <<__EOF__; + pixel = *src; + pixel = (pixel >> 8) | (pixel << 24); + *dst = pixel; +__EOF__ + } else { + # ARGB -> RGBA -- unused + print FILE <<__EOF__; + pixel = *src; + pixel = (pixel << 8) | A; + *dst = pixel; +__EOF__ + } + } elsif ($dst_has_alpha) { + $da = substr $dst, 0, 1; + if ($da eq "A") { + # RGB -> ARGB + print FILE <<__EOF__; + pixel = *src; + pixel |= (A << 24); + *dst = pixel; +__EOF__ + } else { + # RGB -> RGBA -- unused + print FILE <<__EOF__; + pixel = *src; + pixel = (pixel << 8) | A; + *dst = pixel; +__EOF__ + } + } else { + $sa = substr $src, 0, 1; + if ($sa eq "A") { + # ARGB -> RGB + print FILE <<__EOF__; + pixel = *src; + pixel &= 0xFFFFFF; + *dst = pixel; +__EOF__ + } else { + # RGBA -> RGB + print FILE <<__EOF__; + pixel = *src; + pixel >>= 8; + *dst = pixel; +__EOF__ + } + } + return; + } } - my $dst_has_alpha = ($dst =~ /A/) ? 1 : 0; my $ignore_dst_alpha = !$dst_has_alpha && !$blend; if ( $blend ) { @@ -326,17 +392,6 @@ __EOF__ ${d}B = ((${s}B * ${d}B) + (${d}B * (255 - ${s}A))) / 255; if (${d}B > 255) ${d}B = 255; __EOF__ } - if ( $dst_has_alpha ) { - if ($A_is_const_FF) { - print FILE <<__EOF__; - ${d}A = 0xFF; -__EOF__ - } else { - print FILE <<__EOF__; - ${d}A = ((${s}A * ${d}A) + (${d}A * (255 - ${s}A))) / 255; if (${d}A > 255) ${d}A = 255; -__EOF__ - } - } print FILE <<__EOF__; break; @@ -360,12 +415,20 @@ sub output_copyfunc my $dst_has_alpha = ($dst =~ /A/) ? 1 : 0; my $ignore_dst_alpha = !$dst_has_alpha && !$blend; - + my $src_has_alpha = ($src =~ /A/) ? 1 : 0; my $is_modulateA_done = 0; my $A_is_const_FF = 0; + my $sa = $src; + my $da = $dst; + my $matching_colors = 0; + + $sa =~ s/[A8]//g; + $da =~ s/[A8]//g; + $matching_colors = (!$modulate && !$blend && ($sa eq $da)) ? 1 : 0; + output_copyfuncname("static void", $src, $dst, $modulate, $blend, $scale, 1, "\n"); print FILE <<__EOF__; { @@ -424,8 +487,8 @@ __EOF__ print FILE <<__EOF__; Uint32 pixel; __EOF__ - if (!$ignore_dst_alpha && !$src_has_alpha) { - if ($modulate){ + if ( !$ignore_dst_alpha && !$src_has_alpha ) { + if ( $modulate ) { $is_modulateA_done = 1; print FILE <<__EOF__; const Uint32 A = (flags & SDL_COPY_MODULATE_ALPHA) ? modulateA : 0xFF; @@ -436,14 +499,18 @@ __EOF__ const Uint32 A = 0xFF; __EOF__ } - print FILE <<__EOF__; + if ( !$matching_colors ) { + print FILE <<__EOF__; Uint32 R, G, B; __EOF__ - } elsif (!$ignore_dst_alpha) { - print FILE <<__EOF__; + } + } elsif ( !$ignore_dst_alpha ) { + if ( !$matching_colors ) { + print FILE <<__EOF__; Uint32 R, G, B, A; __EOF__ - } else { + } + } elsif ( !$matching_colors ) { print FILE <<__EOF__; Uint32 R, G, B; __EOF__ @@ -451,38 +518,29 @@ __EOF__ } if ( $scale ) { print FILE <<__EOF__; - int srcy, srcx; - int posy, posx; - int incy, incx; + Uint64 srcy, srcx; + Uint64 posy, posx; + Uint64 incy, incx; __EOF__ print FILE <<__EOF__; - srcy = 0; - posy = 0; - incy = (info->src_h << 16) / info->dst_h; - incx = (info->src_w << 16) / info->dst_w; + incy = ((Uint64)info->src_h << 16) / info->dst_h; + incx = ((Uint64)info->src_w << 16) / info->dst_w; + posy = incy / 2; while (info->dst_h--) { $format_type{$src} *src = 0; $format_type{$dst} *dst = ($format_type{$dst} *)info->dst; int n = info->dst_w; - srcx = -1; - posx = 0x10000L; - while (posy >= 0x10000L) { - ++srcy; - posy -= 0x10000L; - } + posx = incx / 2; + + srcy = posy >> 16; while (n--) { - if (posx >= 0x10000L) { - while (posx >= 0x10000L) { - ++srcx; - posx -= 0x10000L; - } - src = ($format_type{$src} *)(info->src + (srcy * info->src_pitch) + (srcx * $format_size{$src})); + srcx = posx >> 16; + src = ($format_type{$src} *)(info->src + (srcy * info->src_pitch) + (srcx * $format_size{$src})); __EOF__ print FILE <<__EOF__; - } __EOF__ output_copycore($src, $dst, $modulate, $blend, $is_modulateA_done, $A_is_const_FF); print FILE <<__EOF__; diff --git a/SDL2-2.0.12/src/video/uikit/SDL_uikitappdelegate.h b/SDL2-2.30.5/src/video/uikit/SDL_uikitappdelegate.h similarity index 96% rename from SDL2-2.0.12/src/video/uikit/SDL_uikitappdelegate.h rename to SDL2-2.30.5/src/video/uikit/SDL_uikitappdelegate.h index 1d19b9d..c40dae0 100644 --- a/SDL2-2.0.12/src/video/uikit/SDL_uikitappdelegate.h +++ b/SDL2-2.30.5/src/video/uikit/SDL_uikitappdelegate.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/video/uikit/SDL_uikitappdelegate.m b/SDL2-2.30.5/src/video/uikit/SDL_uikitappdelegate.m similarity index 85% rename from SDL2-2.0.12/src/video/uikit/SDL_uikitappdelegate.m rename to SDL2-2.30.5/src/video/uikit/SDL_uikitappdelegate.m index ac37ebd..8fd4c71 100644 --- a/SDL2-2.0.12/src/video/uikit/SDL_uikitappdelegate.m +++ b/SDL2-2.30.5/src/video/uikit/SDL_uikitappdelegate.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,10 +20,9 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_UIKIT +#ifdef SDL_VIDEO_DRIVER_UIKIT #include "../SDL_sysvideo.h" -#include "SDL_assert.h" #include "SDL_hints.h" #include "SDL_system.h" #include "SDL_main.h" @@ -34,6 +33,14 @@ #include "../../events/SDL_events_c.h" +#if !TARGET_OS_TV +#include + +# ifndef __IPHONE_13_0 +# define __IPHONE_13_0 130000 +# endif +#endif + #ifdef main #undef main #endif @@ -43,20 +50,12 @@ static int forward_argc; static char **forward_argv; static int exit_status; -#if defined(SDL_MAIN_NEEDED) && !defined(IOS_DYLIB) -/* SDL is being built as a static library, include main() */ -int main(int argc, char *argv[]) -{ - return SDL_UIKitRunApp(argc, argv, SDL_main); -} -#endif /* SDL_MAIN_NEEDED && !IOS_DYLIB */ - int SDL_UIKitRunApp(int argc, char *argv[], SDL_main_func mainFunction) { int i; /* store arguments */ - forward_main = mainFunction; + forward_main = mainFunction; forward_argc = argc; forward_argv = (char **)malloc((argc+1) * sizeof(char *)); for (i = 0; i < argc; i++) { @@ -88,8 +87,7 @@ SDL_IdleTimerDisabledChanged(void *userdata, const char *name, const char *oldVa #if !TARGET_OS_TV /* Load a launch image using the old UILaunchImageFile-era naming rules. */ -static UIImage * -SDL_LoadLaunchImageNamed(NSString *name, int screenh) +static UIImage *SDL_LoadLaunchImageNamed(NSString *name, int screenh) { UIInterfaceOrientation curorient = [UIApplication sharedApplication].statusBarOrientation; UIUserInterfaceIdiom idiom = [UIDevice currentDevice].userInterfaceIdiom; @@ -125,6 +123,53 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh) return image; } + +@interface SDLLaunchStoryboardViewController : UIViewController +@property (nonatomic, strong) UIViewController *storyboardViewController; +- (instancetype)initWithStoryboardViewController:(UIViewController *)storyboardViewController; +@end + +@implementation SDLLaunchStoryboardViewController + +- (instancetype)initWithStoryboardViewController:(UIViewController *)storyboardViewController { + self = [super init]; + self.storyboardViewController = storyboardViewController; + return self; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + + [self addChildViewController:self.storyboardViewController]; + [self.view addSubview:self.storyboardViewController.view]; + self.storyboardViewController.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + self.storyboardViewController.view.frame = self.view.bounds; + [self.storyboardViewController didMoveToParentViewController:self]; + + UIApplication.sharedApplication.statusBarHidden = self.prefersStatusBarHidden; + UIApplication.sharedApplication.statusBarStyle = self.preferredStatusBarStyle; +} + +- (BOOL)prefersStatusBarHidden { + return [[NSBundle.mainBundle objectForInfoDictionaryKey:@"UIStatusBarHidden"] boolValue]; +} + +- (UIStatusBarStyle)preferredStatusBarStyle { + NSString *statusBarStyle = [NSBundle.mainBundle objectForInfoDictionaryKey:@"UIStatusBarStyle"]; + if ([statusBarStyle isEqualToString:@"UIStatusBarStyleLightContent"]) { + return UIStatusBarStyleLightContent; + } +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0 + if (@available(iOS 13.0, *)) { + if ([statusBarStyle isEqualToString:@"UIStatusBarStyleDarkContent"]) { + return UIStatusBarStyleDarkContent; + } + } +#endif + return UIStatusBarStyleDefault; +} + +@end #endif /* !TARGET_OS_TV */ @interface SDLLaunchScreenController () @@ -150,10 +195,9 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh) NSString *screenname = nibNameOrNil; NSBundle *bundle = nibBundleOrNil; - BOOL atleastiOS8 = UIKit_IsSystemVersionAtLeast(8.0); - /* Launch screens were added in iOS 8. Otherwise we use launch images. */ - if (screenname && atleastiOS8) { + /* A launch screen may not exist. Fall back to launch images in that case. */ + if (screenname) { @try { self.view = [bundle loadNibNamed:screenname owner:self options:nil][0]; } @@ -250,9 +294,9 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh) UIImageOrientation imageorient = UIImageOrientationUp; #if !TARGET_OS_TV - /* Bugs observed / workaround tested in iOS 8.3, 7.1, and 6.1. */ + /* Bugs observed / workaround tested in iOS 8.3. */ if (UIInterfaceOrientationIsLandscape(curorient)) { - if (atleastiOS8 && image.size.width < image.size.height) { + if (image.size.width < image.size.height) { /* On iOS 8, portrait launch images displayed in forced- * landscape mode (e.g. a standard Default.png on an iPhone * when Info.plist only supports landscape orientations) need @@ -262,15 +306,6 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh) } else if (curorient == UIInterfaceOrientationLandscapeRight) { imageorient = UIImageOrientationLeft; } - } else if (!atleastiOS8 && image.size.width > image.size.height) { - /* On iOS 7 and below, landscape launch images displayed in - * landscape mode (e.g. landscape iPad launch images) need - * to be rotated to display in the expected orientation. */ - if (curorient == UIInterfaceOrientationLandscapeLeft) { - imageorient = UIImageOrientationLeft; - } else if (curorient == UIInterfaceOrientationLandscapeRight) { - imageorient = UIImageOrientationRight; - } } } #endif @@ -373,7 +408,7 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh) { NSBundle *bundle = [NSBundle mainBundle]; -#if SDL_IPHONE_LAUNCHSCREEN +#ifdef SDL_IPHONE_LAUNCHSCREEN /* The normal launch screen is displayed until didFinishLaunching returns, * but SDL_main is called after that happens and there may be a noticeable * delay between the start of SDL_main and when the first real frame is @@ -387,13 +422,14 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh) #if !TARGET_OS_TV screenname = [bundle objectForInfoDictionaryKey:@"UILaunchStoryboardName"]; - if (screenname && UIKit_IsSystemVersionAtLeast(8.0)) { + if (screenname) { @try { /* The launch storyboard is actually a nib in some older versions of * Xcode. We'll try to load it as a storyboard first, as it's more * modern. */ UIStoryboard *storyboard = [UIStoryboard storyboardWithName:screenname bundle:bundle]; - vc = [storyboard instantiateInitialViewController]; + __auto_type storyboardVc = [storyboard instantiateInitialViewController]; + vc = [[SDLLaunchStoryboardViewController alloc] initWithStoryboardViewController:storyboardVc]; } @catch (NSException *exception) { /* Do nothing (there's more code to execute below). */ @@ -453,43 +489,6 @@ SDL_LoadLaunchImageNamed(NSString *name, int screenh) /* Do nothing. */ } -#if !TARGET_OS_TV -- (void)application:(UIApplication *)application didChangeStatusBarOrientation:(UIInterfaceOrientation)oldStatusBarOrientation -{ - SDL_OnApplicationDidChangeStatusBarOrientation(); -} -#endif - -- (void)applicationWillTerminate:(UIApplication *)application -{ - SDL_OnApplicationWillTerminate(); -} - -- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application -{ - SDL_OnApplicationDidReceiveMemoryWarning(); -} - -- (void)applicationWillResignActive:(UIApplication*)application -{ - SDL_OnApplicationWillResignActive(); -} - -- (void)applicationDidEnterBackground:(UIApplication*)application -{ - SDL_OnApplicationDidEnterBackground(); -} - -- (void)applicationWillEnterForeground:(UIApplication*)application -{ - SDL_OnApplicationWillEnterForeground(); -} - -- (void)applicationDidBecomeActive:(UIApplication*)application -{ - SDL_OnApplicationDidBecomeActive(); -} - - (void)sendDropFileForURL:(NSURL *)url { NSURL *fileURL = url.filePathURL; diff --git a/SDL2-2.0.12/src/video/uikit/SDL_uikitclipboard.h b/SDL2-2.30.5/src/video/uikit/SDL_uikitclipboard.h similarity index 95% rename from SDL2-2.0.12/src/video/uikit/SDL_uikitclipboard.h rename to SDL2-2.30.5/src/video/uikit/SDL_uikitclipboard.h index 4240b61..ad26742 100644 --- a/SDL2-2.0.12/src/video/uikit/SDL_uikitclipboard.h +++ b/SDL2-2.30.5/src/video/uikit/SDL_uikitclipboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/video/uikit/SDL_uikitclipboard.m b/SDL2-2.30.5/src/video/uikit/SDL_uikitclipboard.m similarity index 90% rename from SDL2-2.0.12/src/video/uikit/SDL_uikitclipboard.m rename to SDL2-2.30.5/src/video/uikit/SDL_uikitclipboard.m index df3122e..b025697 100644 --- a/SDL2-2.0.12/src/video/uikit/SDL_uikitclipboard.m +++ b/SDL2-2.30.5/src/video/uikit/SDL_uikitclipboard.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,15 +20,14 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_UIKIT +#ifdef SDL_VIDEO_DRIVER_UIKIT #include "SDL_uikitvideo.h" #include "../../events/SDL_clipboardevents_c.h" #import -int -UIKit_SetClipboardText(_THIS, const char *text) +int UIKit_SetClipboardText(_THIS, const char *text) { #if TARGET_OS_TV return SDL_SetError("The clipboard is not available on tvOS"); @@ -40,8 +39,7 @@ UIKit_SetClipboardText(_THIS, const char *text) #endif } -char * -UIKit_GetClipboardText(_THIS) +char *UIKit_GetClipboardText(_THIS) { #if TARGET_OS_TV return SDL_strdup(""); // Unsupported. @@ -59,8 +57,7 @@ UIKit_GetClipboardText(_THIS) #endif } -SDL_bool -UIKit_HasClipboardText(_THIS) +SDL_bool UIKit_HasClipboardText(_THIS) { @autoreleasepool { #if !TARGET_OS_TV @@ -72,8 +69,7 @@ UIKit_HasClipboardText(_THIS) } } -void -UIKit_InitClipboard(_THIS) +void UIKit_InitClipboard(_THIS) { #if !TARGET_OS_TV @autoreleasepool { @@ -92,8 +88,7 @@ UIKit_InitClipboard(_THIS) #endif } -void -UIKit_QuitClipboard(_THIS) +void UIKit_QuitClipboard(_THIS) { @autoreleasepool { SDL_VideoData *data = (__bridge SDL_VideoData *) _this->driverdata; diff --git a/SDL2-2.0.12/src/video/uikit/SDL_uikitevents.h b/SDL2-2.30.5/src/video/uikit/SDL_uikitevents.h similarity index 76% rename from SDL2-2.0.12/src/video/uikit/SDL_uikitevents.h rename to SDL2-2.30.5/src/video/uikit/SDL_uikitevents.h index f4ae9c7..fae3759 100644 --- a/SDL2-2.0.12/src/video/uikit/SDL_uikitevents.h +++ b/SDL2-2.30.5/src/video/uikit/SDL_uikitevents.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -25,6 +25,15 @@ extern void UIKit_PumpEvents(_THIS); +extern void SDL_InitGCKeyboard(void); +extern SDL_bool SDL_HasGCKeyboard(void); +extern void SDL_QuitGCKeyboard(void); + +extern void SDL_InitGCMouse(void); +extern SDL_bool SDL_HasGCMouse(void); +extern SDL_bool SDL_GCMouseRelativeMode(void); +extern void SDL_QuitGCMouse(void); + #endif /* SDL_uikitevents_h_ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/uikit/SDL_uikitevents.m b/SDL2-2.30.5/src/video/uikit/SDL_uikitevents.m new file mode 100644 index 0000000..938b70a --- /dev/null +++ b/SDL2-2.30.5/src/video/uikit/SDL_uikitevents.m @@ -0,0 +1,483 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_UIKIT + +#include "../../events/SDL_events_c.h" + +#include "SDL_system.h" +#include "SDL_uikitevents.h" +#include "SDL_uikitopengles.h" +#include "SDL_uikitvideo.h" +#include "SDL_uikitwindow.h" + +#import + +#if (__IPHONE_OS_VERSION_MAX_ALLOWED >= 140000) || (__APPLETV_OS_VERSION_MAX_ALLOWED >= 140000) || (__MAC_OS_VERSION_MAX_ALLOWED > 1500000) +#import + +#define ENABLE_GCKEYBOARD +#define ENABLE_GCMOUSE +#endif + +static BOOL UIKit_EventPumpEnabled = YES; + + +@interface SDL_LifecycleObserver : NSObject +@property (nonatomic, assign) BOOL isObservingNotifications; +@end + +@implementation SDL_LifecycleObserver + +- (void)eventPumpChanged +{ + NSNotificationCenter *notificationCenter = NSNotificationCenter.defaultCenter; + if (UIKit_EventPumpEnabled && !self.isObservingNotifications) { + self.isObservingNotifications = YES; + [notificationCenter addObserver:self selector:@selector(applicationDidBecomeActive) name:UIApplicationDidBecomeActiveNotification object:nil]; + [notificationCenter addObserver:self selector:@selector(applicationWillResignActive) name:UIApplicationWillResignActiveNotification object:nil]; + [notificationCenter addObserver:self selector:@selector(applicationDidEnterBackground) name:UIApplicationDidEnterBackgroundNotification object:nil]; + [notificationCenter addObserver:self selector:@selector(applicationWillEnterForeground) name:UIApplicationWillEnterForegroundNotification object:nil]; + [notificationCenter addObserver:self selector:@selector(applicationWillTerminate) name:UIApplicationWillTerminateNotification object:nil]; + [notificationCenter addObserver:self selector:@selector(applicationDidReceiveMemoryWarning) name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; +#if !TARGET_OS_TV + [notificationCenter addObserver:self selector:@selector(applicationDidChangeStatusBarOrientation) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil]; +#endif + } else if (!UIKit_EventPumpEnabled && self.isObservingNotifications) { + self.isObservingNotifications = NO; + [notificationCenter removeObserver:self]; + } +} + +- (void)applicationDidBecomeActive +{ + SDL_OnApplicationDidBecomeActive(); +} + +- (void)applicationWillResignActive +{ + SDL_OnApplicationWillResignActive(); +} + +- (void)applicationDidEnterBackground +{ + SDL_OnApplicationDidEnterBackground(); +} + +- (void)applicationWillEnterForeground +{ + SDL_OnApplicationWillEnterForeground(); +} + +- (void)applicationWillTerminate +{ + SDL_OnApplicationWillTerminate(); +} + +- (void)applicationDidReceiveMemoryWarning +{ + SDL_OnApplicationDidReceiveMemoryWarning(); +} + +#if !TARGET_OS_TV +- (void)applicationDidChangeStatusBarOrientation +{ + SDL_OnApplicationDidChangeStatusBarOrientation(); +} +#endif + +@end + + +void SDL_iPhoneSetEventPump(SDL_bool enabled) +{ + UIKit_EventPumpEnabled = enabled; + + static SDL_LifecycleObserver *lifecycleObserver; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + lifecycleObserver = [SDL_LifecycleObserver new]; + }); + [lifecycleObserver eventPumpChanged]; +} + +void UIKit_PumpEvents(_THIS) +{ + if (!UIKit_EventPumpEnabled) { + return; + } + + /* Let the run loop run for a short amount of time: long enough for + touch events to get processed (which is important to get certain + elements of Game Center's GKLeaderboardViewController to respond + to touch input), but not long enough to introduce a significant + delay in the rest of the app. + */ + const CFTimeInterval seconds = 0.000002; + + /* Pump most event types. */ + SInt32 result; + do { + result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, seconds, TRUE); + } while (result == kCFRunLoopRunHandledSource); + + /* Make sure UIScrollView objects scroll properly. */ + do { + result = CFRunLoopRunInMode((CFStringRef)UITrackingRunLoopMode, seconds, TRUE); + } while(result == kCFRunLoopRunHandledSource); + + /* See the comment in the function definition. */ +#if defined(SDL_VIDEO_OPENGL_ES) || defined(SDL_VIDEO_OPENGL_ES2) + UIKit_GL_RestoreCurrentContext(); +#endif +} + +#ifdef ENABLE_GCKEYBOARD + +static SDL_bool keyboard_connected = SDL_FALSE; +static id keyboard_connect_observer = nil; +static id keyboard_disconnect_observer = nil; + +static void OnGCKeyboardConnected(GCKeyboard *keyboard) API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0)) +{ + keyboard_connected = SDL_TRUE; + keyboard.keyboardInput.keyChangedHandler = ^(GCKeyboardInput *kbrd, GCControllerButtonInput *key, GCKeyCode keyCode, BOOL pressed) + { + SDL_SendKeyboardKey(pressed ? SDL_PRESSED : SDL_RELEASED, (SDL_Scancode)keyCode); + }; + + dispatch_queue_t queue = dispatch_queue_create( "org.libsdl.input.keyboard", DISPATCH_QUEUE_SERIAL ); + dispatch_set_target_queue( queue, dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_HIGH, 0 ) ); + keyboard.handlerQueue = queue; +} + +static void OnGCKeyboardDisconnected(GCKeyboard *keyboard) API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0)) +{ + keyboard.keyboardInput.keyChangedHandler = nil; + keyboard_connected = SDL_FALSE; +} + +void SDL_InitGCKeyboard(void) +{ + @autoreleasepool { + if (@available(iOS 14.0, tvOS 14.0, *)) { + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + + keyboard_connect_observer = [center addObserverForName:GCKeyboardDidConnectNotification + object:nil + queue:nil + usingBlock:^(NSNotification *note) { + GCKeyboard *keyboard = note.object; + OnGCKeyboardConnected(keyboard); + }]; + + keyboard_disconnect_observer = [center addObserverForName:GCKeyboardDidDisconnectNotification + object:nil + queue:nil + usingBlock:^(NSNotification *note) { + GCKeyboard *keyboard = note.object; + OnGCKeyboardDisconnected(keyboard); + }]; + + if (GCKeyboard.coalescedKeyboard != nil) { + OnGCKeyboardConnected(GCKeyboard.coalescedKeyboard); + } + } + } +} + +SDL_bool SDL_HasGCKeyboard(void) +{ + return keyboard_connected; +} + +void SDL_QuitGCKeyboard(void) +{ + @autoreleasepool { + if (@available(iOS 14.0, tvOS 14.0, *)) { + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + + if (keyboard_connect_observer) { + [center removeObserver:keyboard_connect_observer name:GCKeyboardDidConnectNotification object:nil]; + keyboard_connect_observer = nil; + } + + if (keyboard_disconnect_observer) { + [center removeObserver:keyboard_disconnect_observer name:GCKeyboardDidDisconnectNotification object:nil]; + keyboard_disconnect_observer = nil; + } + + if (GCKeyboard.coalescedKeyboard != nil) { + OnGCKeyboardDisconnected(GCKeyboard.coalescedKeyboard); + } + } + } +} + +#else + +void SDL_InitGCKeyboard(void) +{ +} + +SDL_bool SDL_HasGCKeyboard(void) +{ + return SDL_FALSE; +} + +void SDL_QuitGCKeyboard(void) +{ +} + +#endif /* ENABLE_GCKEYBOARD */ + + +#ifdef ENABLE_GCMOUSE + +static int mice_connected = 0; +static id mouse_connect_observer = nil; +static id mouse_disconnect_observer = nil; +static bool mouse_relative_mode = SDL_FALSE; +static SDL_MouseWheelDirection mouse_scroll_direction = SDL_MOUSEWHEEL_NORMAL; + +static void UpdateScrollDirection(void) +{ +#if 0 /* This code doesn't work for some reason */ + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + if ([userDefaults boolForKey:@"com.apple.swipescrolldirection"]) { + mouse_scroll_direction = SDL_MOUSEWHEEL_FLIPPED; + } else { + mouse_scroll_direction = SDL_MOUSEWHEEL_NORMAL; + } +#else + Boolean keyExistsAndHasValidFormat = NO; + Boolean naturalScrollDirection = CFPreferencesGetAppBooleanValue(CFSTR("com.apple.swipescrolldirection"), kCFPreferencesAnyApplication, &keyExistsAndHasValidFormat); + if (!keyExistsAndHasValidFormat) { + /* Couldn't read the preference, assume natural scrolling direction */ + naturalScrollDirection = YES; + } + if (naturalScrollDirection) { + mouse_scroll_direction = SDL_MOUSEWHEEL_FLIPPED; + } else { + mouse_scroll_direction = SDL_MOUSEWHEEL_NORMAL; + } +#endif +} + +static void UpdatePointerLock(void) +{ + SDL_VideoDevice *_this = SDL_GetVideoDevice(); + SDL_Window *window; + + for (window = _this->windows; window != NULL; window = window->next) { + UIKit_UpdatePointerLock(_this, window); + } +} + +static int SetGCMouseRelativeMode(SDL_bool enabled) +{ + mouse_relative_mode = enabled; + UpdatePointerLock(); + return 0; +} + +static void OnGCMouseButtonChanged(SDL_MouseID mouseID, Uint8 button, BOOL pressed) +{ + SDL_SendMouseButton(SDL_GetMouseFocus(), mouseID, pressed ? SDL_PRESSED : SDL_RELEASED, button); +} + +static void OnGCMouseConnected(GCMouse *mouse) API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0)) +{ + SDL_MouseID mouseID = mice_connected; + + mouse.mouseInput.leftButton.pressedChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) + { + OnGCMouseButtonChanged(mouseID, SDL_BUTTON_LEFT, pressed); + }; + mouse.mouseInput.middleButton.pressedChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) + { + OnGCMouseButtonChanged(mouseID, SDL_BUTTON_MIDDLE, pressed); + }; + mouse.mouseInput.rightButton.pressedChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) + { + OnGCMouseButtonChanged(mouseID, SDL_BUTTON_RIGHT, pressed); + }; + + int auxiliary_button = SDL_BUTTON_X1; + for (GCControllerButtonInput *btn in mouse.mouseInput.auxiliaryButtons) { + btn.pressedChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) + { + OnGCMouseButtonChanged(mouseID, auxiliary_button, pressed); + }; + ++auxiliary_button; + } + + mouse.mouseInput.mouseMovedHandler = ^(GCMouseInput *mouseInput, float deltaX, float deltaY) + { + if (SDL_GCMouseRelativeMode()) { + SDL_SendMouseMotion(SDL_GetMouseFocus(), mouseID, 1, (int)deltaX, -(int)deltaY); + } + }; + + mouse.mouseInput.scroll.valueChangedHandler = ^(GCControllerDirectionPad *dpad, float xValue, float yValue) { + /* Raw scroll values come in here, vertical values in the first axis, horizontal values in the second axis. + * The vertical values are negative moving the mouse wheel up and positive moving it down. + * The horizontal values are negative moving the mouse wheel left and positive moving it right. + * The vertical values are inverted compared to SDL, and the horizontal values are as expected. + */ + float vertical = -xValue; + float horizontal = yValue; + if (mouse_scroll_direction == SDL_MOUSEWHEEL_FLIPPED) { + /* Since these are raw values, we need to flip them ourselves */ + vertical = -vertical; + horizontal = -horizontal; + } + SDL_SendMouseWheel(SDL_GetMouseFocus(), mouseID, horizontal, vertical, mouse_scroll_direction); + }; + UpdateScrollDirection(); + + dispatch_queue_t queue = dispatch_queue_create( "org.libsdl.input.mouse", DISPATCH_QUEUE_SERIAL ); + dispatch_set_target_queue( queue, dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_HIGH, 0 ) ); + mouse.handlerQueue = queue; + + ++mice_connected; + + UpdatePointerLock(); +} + +static void OnGCMouseDisconnected(GCMouse *mouse) API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0)) +{ + --mice_connected; + + mouse.mouseInput.mouseMovedHandler = nil; + + mouse.mouseInput.leftButton.pressedChangedHandler = nil; + mouse.mouseInput.middleButton.pressedChangedHandler = nil; + mouse.mouseInput.rightButton.pressedChangedHandler = nil; + + for (GCControllerButtonInput *button in mouse.mouseInput.auxiliaryButtons) { + button.pressedChangedHandler = nil; + } + + UpdatePointerLock(); +} + +void SDL_InitGCMouse(void) +{ + @autoreleasepool { + /* There is a bug where mouse accumulates duplicate deltas over time in iOS 14.0 */ + if (@available(iOS 14.1, tvOS 14.1, *)) { + /* iOS will not send the new pointer touch events if you don't have this key, + * and we need them to differentiate between mouse events and real touch events. + */ + BOOL indirect_input_available = [[[[NSBundle mainBundle] infoDictionary] objectForKey:@"UIApplicationSupportsIndirectInputEvents"] boolValue]; + if (indirect_input_available) { + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + + mouse_connect_observer = [center addObserverForName:GCMouseDidConnectNotification + object:nil + queue:nil + usingBlock:^(NSNotification *note) { + GCMouse *mouse = note.object; + OnGCMouseConnected(mouse); + }]; + + mouse_disconnect_observer = [center addObserverForName:GCMouseDidDisconnectNotification + object:nil + queue:nil + usingBlock:^(NSNotification *note) { + GCMouse *mouse = note.object; + OnGCMouseDisconnected(mouse); + }]; + + for (GCMouse *mouse in [GCMouse mice]) { + OnGCMouseConnected(mouse); + } + + SDL_GetMouse()->SetRelativeMouseMode = SetGCMouseRelativeMode; + } else { + NSLog(@"You need UIApplicationSupportsIndirectInputEvents in your Info.plist for mouse support"); + } + } + } +} + +SDL_bool SDL_HasGCMouse(void) +{ + return (mice_connected > 0); +} + +SDL_bool SDL_GCMouseRelativeMode(void) +{ + return mouse_relative_mode; +} + +void SDL_QuitGCMouse(void) +{ + @autoreleasepool { + if (@available(iOS 14.1, tvOS 14.1, *)) { + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + + if (mouse_connect_observer) { + [center removeObserver:mouse_connect_observer name:GCMouseDidConnectNotification object:nil]; + mouse_connect_observer = nil; + } + + if (mouse_disconnect_observer) { + [center removeObserver:mouse_disconnect_observer name:GCMouseDidDisconnectNotification object:nil]; + mouse_disconnect_observer = nil; + } + + for (GCMouse *mouse in [GCMouse mice]) { + OnGCMouseDisconnected(mouse); + } + + SDL_GetMouse()->SetRelativeMouseMode = NULL; + } + } +} + +#else + +void SDL_InitGCMouse(void) +{ +} + +SDL_bool SDL_HasGCMouse(void) +{ + return SDL_FALSE; +} + +SDL_bool SDL_GCMouseRelativeMode(void) +{ + return SDL_FALSE; +} + +void SDL_QuitGCMouse(void) +{ +} + +#endif /* ENABLE_GCMOUSE */ + +#endif /* SDL_VIDEO_DRIVER_UIKIT */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/uikit/SDL_uikitmessagebox.h b/SDL2-2.30.5/src/video/uikit/SDL_uikitmessagebox.h similarity index 92% rename from SDL2-2.0.12/src/video/uikit/SDL_uikitmessagebox.h rename to SDL2-2.30.5/src/video/uikit/SDL_uikitmessagebox.h index 4d5fe1d..8723983 100644 --- a/SDL2-2.0.12/src/video/uikit/SDL_uikitmessagebox.h +++ b/SDL2-2.30.5/src/video/uikit/SDL_uikitmessagebox.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_UIKIT +#ifdef SDL_VIDEO_DRIVER_UIKIT extern SDL_bool UIKit_ShowingMessageBox(void); diff --git a/SDL2-2.0.12/src/video/uikit/SDL_uikitmessagebox.m b/SDL2-2.30.5/src/video/uikit/SDL_uikitmessagebox.m similarity index 55% rename from SDL2-2.0.12/src/video/uikit/SDL_uikitmessagebox.m rename to SDL2-2.30.5/src/video/uikit/SDL_uikitmessagebox.m index d5c0309..b68c065 100644 --- a/SDL2-2.0.12/src/video/uikit/SDL_uikitmessagebox.m +++ b/SDL2-2.30.5/src/video/uikit/SDL_uikitmessagebox.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_UIKIT +#ifdef SDL_VIDEO_DRIVER_UIKIT #include "SDL.h" #include "SDL_uikitvideo.h" @@ -30,14 +30,12 @@ static SDL_bool s_showingMessageBox = SDL_FALSE; -SDL_bool -UIKit_ShowingMessageBox(void) +SDL_bool UIKit_ShowingMessageBox(void) { return s_showingMessageBox; } -static void -UIKit_WaitUntilMessageBoxClosed(const SDL_MessageBoxData *messageboxdata, int *clickedindex) +static void UIKit_WaitUntilMessageBoxClosed(const SDL_MessageBoxData *messageboxdata, int *clickedindex) { *clickedindex = messageboxdata->numbuttons; @@ -52,8 +50,7 @@ UIKit_WaitUntilMessageBoxClosed(const SDL_MessageBoxData *messageboxdata, int *c } } -static BOOL -UIKit_ShowMessageBoxAlertController(const SDL_MessageBoxData *messageboxdata, int *buttonid) +static BOOL UIKit_ShowMessageBoxAlertController(const SDL_MessageBoxData *messageboxdata, int *buttonid) { int i; int __block clickedindex = messageboxdata->numbuttons; @@ -85,10 +82,10 @@ UIKit_ShowMessageBoxAlertController(const SDL_MessageBoxData *messageboxdata, in } action = [UIAlertAction actionWithTitle:@(sdlButton->text) - style:style - handler:^(UIAlertAction *action) { - clickedindex = (int)(sdlButton - messageboxdata->buttons); - }]; + style:style + handler:^(UIAlertAction *alertAction) { + clickedindex = (int)(sdlButton - messageboxdata->buttons); + }]; [alert addAction:action]; if (sdlButton->flags & SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT) { @@ -124,87 +121,28 @@ UIKit_ShowMessageBoxAlertController(const SDL_MessageBoxData *messageboxdata, in return YES; } -/* UIAlertView is deprecated in iOS 8+ in favor of UIAlertController. */ -#if __IPHONE_OS_VERSION_MIN_REQUIRED < 80000 -@interface SDLAlertViewDelegate : NSObject - -@property (nonatomic, assign) int *clickedIndex; - -@end - -@implementation SDLAlertViewDelegate - -- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex +static void UIKit_ShowMessageBoxImpl(const SDL_MessageBoxData *messageboxdata, int *buttonid, int *returnValue) +{ @autoreleasepool { - if (_clickedIndex != NULL) { - *_clickedIndex = (int) buttonIndex; + if (UIKit_ShowMessageBoxAlertController(messageboxdata, buttonid)) { + *returnValue = 0; + } else { + *returnValue = SDL_SetError("Could not show message box."); } -} +}} -@end -#endif /* __IPHONE_OS_VERSION_MIN_REQUIRED < 80000 */ - -static BOOL -UIKit_ShowMessageBoxAlertView(const SDL_MessageBoxData *messageboxdata, int *buttonid) +int UIKit_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) +{ @autoreleasepool { - /* UIAlertView is deprecated in iOS 8+ in favor of UIAlertController. */ -#if __IPHONE_OS_VERSION_MIN_REQUIRED < 80000 - int i; - int clickedindex = messageboxdata->numbuttons; - const SDL_MessageBoxButtonData *buttons = messageboxdata->buttons; - UIAlertView *alert = [[UIAlertView alloc] init]; - SDLAlertViewDelegate *delegate = [[SDLAlertViewDelegate alloc] init]; + __block int returnValue = 0; - alert.delegate = delegate; - alert.title = @(messageboxdata->title); - alert.message = @(messageboxdata->message); - - for (i = 0; i < messageboxdata->numbuttons; i++) { - const SDL_MessageBoxButtonData *sdlButton; - if (messageboxdata->flags & SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT) { - sdlButton = &messageboxdata->buttons[messageboxdata->numbuttons - 1 - i]; - } else { - sdlButton = &messageboxdata->buttons[i]; - } - [alert addButtonWithTitle:@(sdlButton->text)]; + if ([NSThread isMainThread]) { + UIKit_ShowMessageBoxImpl(messageboxdata, buttonid, &returnValue); + } else { + dispatch_sync(dispatch_get_main_queue(), ^{ UIKit_ShowMessageBoxImpl(messageboxdata, buttonid, &returnValue); }); } - - delegate.clickedIndex = &clickedindex; - - [alert show]; - - UIKit_WaitUntilMessageBoxClosed(messageboxdata, &clickedindex); - - alert.delegate = nil; - - if (messageboxdata->flags & SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT) { - clickedindex = messageboxdata->numbuttons - 1 - clickedindex; - } - *buttonid = messageboxdata->buttons[clickedindex].buttonid; - return YES; -#else - return NO; -#endif /* __IPHONE_OS_VERSION_MIN_REQUIRED < 80000 */ -} - -int -UIKit_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) -{ - BOOL success = NO; - - @autoreleasepool { - success = UIKit_ShowMessageBoxAlertController(messageboxdata, buttonid); - if (!success) { - success = UIKit_ShowMessageBoxAlertView(messageboxdata, buttonid); - } - } - - if (!success) { - return SDL_SetError("Could not show message box."); - } - - return 0; -} + return returnValue; +}} #endif /* SDL_VIDEO_DRIVER_UIKIT */ diff --git a/SDL2-2.0.12/src/video/uikit/SDL_uikitmetalview.h b/SDL2-2.30.5/src/video/uikit/SDL_uikitmetalview.h similarity index 79% rename from SDL2-2.0.12/src/video/uikit/SDL_uikitmetalview.h rename to SDL2-2.30.5/src/video/uikit/SDL_uikitmetalview.h index 9ae37cb..7a3060e 100644 --- a/SDL2-2.0.12/src/video/uikit/SDL_uikitmetalview.h +++ b/SDL2-2.30.5/src/video/uikit/SDL_uikitmetalview.h @@ -1,15 +1,15 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga - + Copyright (C) 1997-2024 Sam Lantinga + This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages 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 @@ -22,8 +22,8 @@ /* * @author Mark Callow, www.edgewise-consulting.com. * - * Thanks to Alex Szpakowski, @slime73 on GitHub, for his gist showing - * how to add a CAMetalLayer backed view. + * Thanks to @slime73 on GitHub for their gist showing how to add a CAMetalLayer + * backed view. */ #ifndef SDL_uikitmetalview_h_ @@ -32,13 +32,12 @@ #include "../SDL_sysvideo.h" #include "SDL_uikitwindow.h" -#if SDL_VIDEO_DRIVER_UIKIT && (SDL_VIDEO_VULKAN || SDL_VIDEO_METAL) +#if defined(SDL_VIDEO_DRIVER_UIKIT) && (defined(SDL_VIDEO_VULKAN) || defined(SDL_VIDEO_METAL)) #import #import #import -#define METALVIEW_TAG 255 @interface SDL_uikitmetalview : SDL_uikitview @@ -49,8 +48,8 @@ SDL_MetalView UIKit_Metal_CreateView(_THIS, SDL_Window * window); void UIKit_Metal_DestroyView(_THIS, SDL_MetalView view); - -void UIKit_Metal_GetDrawableSize(SDL_Window * window, int * w, int * h); +void *UIKit_Metal_GetLayer(_THIS, SDL_MetalView view); +void UIKit_Metal_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h); #endif /* SDL_VIDEO_DRIVER_UIKIT && (SDL_VIDEO_VULKAN || SDL_VIDEO_METAL) */ diff --git a/SDL2-2.0.12/src/video/uikit/SDL_uikitmetalview.m b/SDL2-2.30.5/src/video/uikit/SDL_uikitmetalview.m similarity index 78% rename from SDL2-2.0.12/src/video/uikit/SDL_uikitmetalview.m rename to SDL2-2.30.5/src/video/uikit/SDL_uikitmetalview.m index 29ed860..5c41aa5 100644 --- a/SDL2-2.0.12/src/video/uikit/SDL_uikitmetalview.m +++ b/SDL2-2.30.5/src/video/uikit/SDL_uikitmetalview.m @@ -1,15 +1,15 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga - + Copyright (C) 1997-2024 Sam Lantinga + This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages 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 @@ -22,19 +22,20 @@ /* * @author Mark Callow, www.edgewise-consulting.com. * - * Thanks to Alex Szpakowski, @slime73 on GitHub, for his gist showing - * how to add a CAMetalLayer backed view. + * Thanks to @slime73 on GitHub for their gist showing how to add a CAMetalLayer + * backed view. */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_UIKIT && (SDL_VIDEO_VULKAN || SDL_VIDEO_METAL) +#if defined(SDL_VIDEO_DRIVER_UIKIT) && (defined(SDL_VIDEO_VULKAN) || defined(SDL_VIDEO_METAL)) + +#include "SDL_syswm.h" +#include "../SDL_sysvideo.h" -#import "../SDL_sysvideo.h" #import "SDL_uikitwindow.h" #import "SDL_uikitmetalview.h" -#include "SDL_assert.h" @implementation SDL_uikitmetalview @@ -48,7 +49,7 @@ scale:(CGFloat)scale { if ((self = [super initWithFrame:frame])) { - self.tag = METALVIEW_TAG; + self.tag = SDL_METALVIEW_TAG; self.layer.contentsScale = scale; [self updateDrawableSize]; } @@ -73,8 +74,7 @@ @end -SDL_MetalView -UIKit_Metal_CreateView(_THIS, SDL_Window * window) +SDL_MetalView UIKit_Metal_CreateView(_THIS, SDL_Window * window) { @autoreleasepool { SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata; CGFloat scale = 1.0; @@ -86,22 +86,22 @@ UIKit_Metal_CreateView(_THIS, SDL_Window * window) * dimensions of the screen rather than the dimensions in points * yielding high resolution on retine displays. */ - if ([data.uiwindow.screen respondsToSelector:@selector(nativeScale)]) { - scale = data.uiwindow.screen.nativeScale; - } else { - scale = data.uiwindow.screen.scale; - } + scale = data.uiwindow.screen.nativeScale; } metalview = [[SDL_uikitmetalview alloc] initWithFrame:data.uiwindow.bounds scale:scale]; + if (metalview == nil) { + SDL_OutOfMemory(); + return NULL; + } + [metalview setSDLWindow:window]; return (void*)CFBridgingRetain(metalview); }} -void -UIKit_Metal_DestroyView(_THIS, SDL_MetalView view) +void UIKit_Metal_DestroyView(_THIS, SDL_MetalView view) { @autoreleasepool { SDL_uikitmetalview *metalview = CFBridgingRelease(view); @@ -110,13 +110,18 @@ UIKit_Metal_DestroyView(_THIS, SDL_MetalView view) } }} -void -UIKit_Metal_GetDrawableSize(SDL_Window * window, int * w, int * h) +void *UIKit_Metal_GetLayer(_THIS, SDL_MetalView view) +{ @autoreleasepool { + SDL_uikitview *uiview = (__bridge SDL_uikitview *)view; + return (__bridge void *)uiview.layer; +}} + +void UIKit_Metal_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h) { @autoreleasepool { SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata; SDL_uikitview *view = (SDL_uikitview*)data.uiwindow.rootViewController.view; - SDL_uikitmetalview* metalview = [view viewWithTag:METALVIEW_TAG]; + SDL_uikitmetalview* metalview = [view viewWithTag:SDL_METALVIEW_TAG]; if (metalview) { CAMetalLayer *layer = (CAMetalLayer*)metalview.layer; assert(layer != NULL); diff --git a/SDL2-2.0.12/src/video/uikit/SDL_uikitmodes.h b/SDL2-2.30.5/src/video/uikit/SDL_uikitmodes.h similarity index 91% rename from SDL2-2.0.12/src/video/uikit/SDL_uikitmodes.h rename to SDL2-2.30.5/src/video/uikit/SDL_uikitmodes.h index e895ce4..38511a2 100644 --- a/SDL2-2.0.12/src/video/uikit/SDL_uikitmodes.h +++ b/SDL2-2.30.5/src/video/uikit/SDL_uikitmodes.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -43,6 +43,8 @@ extern SDL_bool UIKit_IsDisplayLandscape(UIScreen *uiscreen); extern int UIKit_InitModes(_THIS); +extern int UIKit_AddDisplay(UIScreen *uiscreen, SDL_bool send_event); +extern void UIKit_DelDisplay(UIScreen *uiscreen); extern void UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display); extern int UIKit_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi, float * hdpi, float * vdpi); extern int UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode); diff --git a/SDL2-2.0.12/src/video/uikit/SDL_uikitmodes.m b/SDL2-2.30.5/src/video/uikit/SDL_uikitmodes.m similarity index 84% rename from SDL2-2.0.12/src/video/uikit/SDL_uikitmodes.m rename to SDL2-2.30.5/src/video/uikit/SDL_uikitmodes.m index 4c1c09a..4772307 100644 --- a/SDL2-2.0.12/src/video/uikit/SDL_uikitmodes.m +++ b/SDL2-2.30.5/src/video/uikit/SDL_uikitmodes.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,9 +20,8 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_UIKIT +#ifdef SDL_VIDEO_DRIVER_UIKIT -#include "SDL_assert.h" #include "SDL_system.h" #include "SDL_uikitmodes.h" @@ -151,11 +150,7 @@ * Estimate the DPI based on the screen scale multiplied by the base DPI for the device * type (e.g. based on iPhone 1 and iPad 1) */ - #if __IPHONE_OS_VERSION_MIN_REQUIRED >= 80000 float scale = (float)screen.nativeScale; - #else - float scale = (float)screen.scale; - #endif float defaultDPI; if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { defaultDPI = 132.0f; @@ -181,10 +176,46 @@ @end +@interface SDL_DisplayWatch : NSObject +@end -static int -UIKit_AllocateDisplayModeData(SDL_DisplayMode * mode, - UIScreenMode * uiscreenmode) +@implementation SDL_DisplayWatch + ++ (void)start +{ + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + + [center addObserver:self selector:@selector(screenConnected:) + name:UIScreenDidConnectNotification object:nil]; + [center addObserver:self selector:@selector(screenDisconnected:) + name:UIScreenDidDisconnectNotification object:nil]; +} + ++ (void)stop +{ + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + + [center removeObserver:self + name:UIScreenDidConnectNotification object:nil]; + [center removeObserver:self + name:UIScreenDidDisconnectNotification object:nil]; +} + ++ (void)screenConnected:(NSNotification*)notification +{ + UIScreen *uiscreen = [notification object]; + UIKit_AddDisplay(uiscreen, SDL_TRUE); +} + ++ (void)screenDisconnected:(NSNotification*)notification +{ + UIScreen *uiscreen = [notification object]; + UIKit_DelDisplay(uiscreen); +} + +@end + +static int UIKit_AllocateDisplayModeData(SDL_DisplayMode * mode, UIScreenMode * uiscreenmode) { SDL_DisplayModeData *data = nil; @@ -203,8 +234,7 @@ UIKit_AllocateDisplayModeData(SDL_DisplayMode * mode, return 0; } -static void -UIKit_FreeDisplayModeData(SDL_DisplayMode * mode) +static void UIKit_FreeDisplayModeData(SDL_DisplayMode * mode) { if (mode->driverdata != NULL) { CFRelease(mode->driverdata); @@ -212,8 +242,7 @@ UIKit_FreeDisplayModeData(SDL_DisplayMode * mode) } } -static NSUInteger -UIKit_GetDisplayModeRefreshRate(UIScreen *uiscreen) +static NSUInteger UIKit_GetDisplayModeRefreshRate(UIScreen *uiscreen) { #ifdef __IPHONE_10_3 if ([uiscreen respondsToSelector:@selector(maximumFramesPerSecond)]) { @@ -223,9 +252,7 @@ UIKit_GetDisplayModeRefreshRate(UIScreen *uiscreen) return 0; } -static int -UIKit_AddSingleDisplayMode(SDL_VideoDisplay * display, int w, int h, - UIScreen * uiscreen, UIScreenMode * uiscreenmode) +static int UIKit_AddSingleDisplayMode(SDL_VideoDisplay * display, int w, int h, UIScreen * uiscreen, UIScreenMode * uiscreenmode) { SDL_DisplayMode mode; SDL_zero(mode); @@ -247,9 +274,7 @@ UIKit_AddSingleDisplayMode(SDL_VideoDisplay * display, int w, int h, } } -static int -UIKit_AddDisplayMode(SDL_VideoDisplay * display, int w, int h, UIScreen * uiscreen, - UIScreenMode * uiscreenmode, SDL_bool addRotation) +static int UIKit_AddDisplayMode(SDL_VideoDisplay * display, int w, int h, UIScreen * uiscreen, UIScreenMode * uiscreenmode, SDL_bool addRotation) { if (UIKit_AddSingleDisplayMode(display, w, h, uiscreen, uiscreenmode) < 0) { return -1; @@ -265,8 +290,7 @@ UIKit_AddDisplayMode(SDL_VideoDisplay * display, int w, int h, UIScreen * uiscre return 0; } -static int -UIKit_AddDisplay(UIScreen *uiscreen) +int UIKit_AddDisplay(UIScreen *uiscreen, SDL_bool send_event) { UIScreenMode *uiscreenmode = uiscreen.currentMode; CGSize size = uiscreen.bounds.size; @@ -302,13 +326,27 @@ UIKit_AddDisplay(UIScreen *uiscreen) } display.driverdata = (void *) CFBridgingRetain(data); - SDL_AddVideoDisplay(&display); + SDL_AddVideoDisplay(&display, send_event); return 0; } -SDL_bool -UIKit_IsDisplayLandscape(UIScreen *uiscreen) +void UIKit_DelDisplay(UIScreen *uiscreen) +{ + int i; + + for (i = 0; i < SDL_GetNumVideoDisplays(); ++i) { + SDL_DisplayData *data = (__bridge SDL_DisplayData *)SDL_GetDisplayDriverData(i); + + if (data && data.uiscreen == uiscreen) { + CFRelease(SDL_GetDisplayDriverData(i)); + SDL_DelVideoDisplay(i); + return; + } + } +} + +SDL_bool UIKit_IsDisplayLandscape(UIScreen *uiscreen) { #if !TARGET_OS_TV if (uiscreen == [UIScreen mainScreen]) { @@ -321,25 +359,25 @@ UIKit_IsDisplayLandscape(UIScreen *uiscreen) } } -int -UIKit_InitModes(_THIS) +int UIKit_InitModes(_THIS) { @autoreleasepool { for (UIScreen *uiscreen in [UIScreen screens]) { - if (UIKit_AddDisplay(uiscreen) < 0) { + if (UIKit_AddDisplay(uiscreen, SDL_FALSE) < 0) { return -1; } } #if !TARGET_OS_TV SDL_OnApplicationDidChangeStatusBarOrientation(); #endif + + [SDL_DisplayWatch start]; } return 0; } -void -UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display) +void UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display) { @autoreleasepool { SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata; @@ -383,8 +421,7 @@ UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display) } } -int -UIKit_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi, float * hdpi, float * vdpi) +int UIKit_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi, float * hdpi, float * vdpi) { @autoreleasepool { SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata; @@ -404,8 +441,7 @@ UIKit_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi, float * hdp return 0; } -int -UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) +int UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) { @autoreleasepool { SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata; @@ -434,8 +470,7 @@ UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) return 0; } -int -UIKit_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect) +int UIKit_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect) { @autoreleasepool { int displayIndex = (int) (display - _this->displays); @@ -448,12 +483,6 @@ UIKit_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect) return -1; } -#if !TARGET_OS_TV && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0 - if (!UIKit_IsSystemVersionAtLeast(7.0)) { - frame = [data.uiscreen applicationFrame]; - } -#endif - rect->x += frame.origin.x; rect->y += frame.origin.y; rect->w = frame.size.width; @@ -463,9 +492,10 @@ UIKit_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect) return 0; } -void -UIKit_QuitModes(_THIS) +void UIKit_QuitModes(_THIS) { + [SDL_DisplayWatch stop]; + /* Release Objective-C objects, so higher level doesn't free() them. */ int i, j; @autoreleasepool { @@ -487,7 +517,7 @@ UIKit_QuitModes(_THIS) } #if !TARGET_OS_TV -void SDL_OnApplicationDidChangeStatusBarOrientation() +void SDL_OnApplicationDidChangeStatusBarOrientation(void) { BOOL isLandscape = UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation); SDL_VideoDisplay *display = SDL_GetDisplay(0); diff --git a/SDL2-2.0.12/src/video/uikit/SDL_uikitopengles.h b/SDL2-2.30.5/src/video/uikit/SDL_uikitopengles.h similarity index 89% rename from SDL2-2.0.12/src/video/uikit/SDL_uikitopengles.h rename to SDL2-2.30.5/src/video/uikit/SDL_uikitopengles.h index 1d24b98..00efc46 100644 --- a/SDL2-2.0.12/src/video/uikit/SDL_uikitopengles.h +++ b/SDL2-2.30.5/src/video/uikit/SDL_uikitopengles.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -21,7 +21,7 @@ #ifndef SDL_uikitopengles_ #define SDL_uikitopengles_ -#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 +#if defined(SDL_VIDEO_OPENGL_ES) || defined(SDL_VIDEO_OPENGL_ES2) #include "../SDL_sysvideo.h" @@ -37,7 +37,7 @@ extern int UIKit_GL_LoadLibrary(_THIS, const char *path); extern void UIKit_GL_RestoreCurrentContext(void); -#endif // SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 +#endif // SDL_VIDEO_OPENGL_ES || defined(SDL_VIDEO_OPENGL_ES2) #endif /* SDL_uikitopengles_ */ diff --git a/SDL2-2.0.12/src/video/uikit/SDL_uikitopengles.m b/SDL2-2.30.5/src/video/uikit/SDL_uikitopengles.m similarity index 87% rename from SDL2-2.0.12/src/video/uikit/SDL_uikitopengles.m rename to SDL2-2.30.5/src/video/uikit/SDL_uikitopengles.m index fb0dae5..8713ae3 100644 --- a/SDL2-2.0.12/src/video/uikit/SDL_uikitopengles.m +++ b/SDL2-2.30.5/src/video/uikit/SDL_uikitopengles.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_UIKIT && (SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2) +#if defined(SDL_VIDEO_DRIVER_UIKIT) && (defined(SDL_VIDEO_OPENGL_ES) || defined(SDL_VIDEO_OPENGL_ES2)) #include "SDL_uikitopengles.h" #import "SDL_uikitopenglview.h" @@ -52,8 +52,7 @@ @end -void * -UIKit_GL_GetProcAddress(_THIS, const char *proc) +void *UIKit_GL_GetProcAddress(_THIS, const char *proc) { /* Look through all SO's for the proc symbol. Here's why: * -Looking for the path to the OpenGL Library seems not to work in the iOS Simulator. @@ -64,8 +63,7 @@ UIKit_GL_GetProcAddress(_THIS, const char *proc) /* note that SDL_GL_DeleteContext makes it current without passing the window */ -int -UIKit_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) +int UIKit_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) { @autoreleasepool { SDLEAGLContext *eaglcontext = (__bridge SDLEAGLContext *) context; @@ -82,8 +80,7 @@ UIKit_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) return 0; } -void -UIKit_GL_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h) +void UIKit_GL_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h) { @autoreleasepool { SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata; @@ -102,8 +99,7 @@ UIKit_GL_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h) } } -int -UIKit_GL_LoadLibrary(_THIS, const char *path) +int UIKit_GL_LoadLibrary(_THIS, const char *path) { /* We shouldn't pass a path to this function, since we've already loaded the * library. */ @@ -118,7 +114,7 @@ int UIKit_GL_SwapWindow(_THIS, SDL_Window * window) @autoreleasepool { SDLEAGLContext *context = (__bridge SDLEAGLContext *) SDL_GL_GetCurrentContext(); -#if SDL_POWER_UIKIT +#ifdef SDL_POWER_UIKIT /* Check once a frame to see if we should turn off the battery monitor. */ SDL_UIKit_UpdateBatteryMonitoring(); #endif @@ -132,8 +128,7 @@ int UIKit_GL_SwapWindow(_THIS, SDL_Window * window) return 0; } -SDL_GLContext -UIKit_GL_CreateContext(_THIS, SDL_Window * window) +SDL_GLContext UIKit_GL_CreateContext(_THIS, SDL_Window * window) { @autoreleasepool { SDLEAGLContext *context = nil; @@ -150,9 +145,8 @@ UIKit_GL_CreateContext(_THIS, SDL_Window * window) * versions. */ EAGLRenderingAPI api = major; - /* iOS currently doesn't support GLES >3.0. iOS 6 also only supports up - * to GLES 2.0. */ - if (major > 3 || (major == 3 && (minor > 0 || !UIKit_IsSystemVersionAtLeast(7.0)))) { + /* iOS currently doesn't support GLES >3.0. */ + if (major > 3 || (major == 3 && minor > 0)) { SDL_SetError("OpenGL ES %d.%d context could not be created", major, minor); return NULL; } @@ -162,19 +156,15 @@ UIKit_GL_CreateContext(_THIS, SDL_Window * window) } if (_this->gl_config.share_with_current_context) { - EAGLContext *context = (__bridge EAGLContext *) SDL_GL_GetCurrentContext(); - sharegroup = context.sharegroup; + EAGLContext *currContext = (__bridge EAGLContext *) SDL_GL_GetCurrentContext(); + sharegroup = currContext.sharegroup; } if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) { /* Set the scale to the natural scale factor of the screen - the * backing dimensions of the OpenGL view will match the pixel * dimensions of the screen rather than the dimensions in points. */ - if ([data.uiwindow.screen respondsToSelector:@selector(nativeScale)]) { - scale = data.uiwindow.screen.nativeScale; - } else { - scale = data.uiwindow.screen.scale; - } + scale = data.uiwindow.screen.nativeScale; } context = [[SDLEAGLContext alloc] initWithAPI:api sharegroup:sharegroup]; @@ -215,8 +205,7 @@ UIKit_GL_CreateContext(_THIS, SDL_Window * window) } } -void -UIKit_GL_DeleteContext(_THIS, SDL_GLContext context) +void UIKit_GL_DeleteContext(_THIS, SDL_GLContext context) { @autoreleasepool { /* The context was retained in SDL_GL_CreateContext, so we release it @@ -226,8 +215,7 @@ UIKit_GL_DeleteContext(_THIS, SDL_GLContext context) } } -void -UIKit_GL_RestoreCurrentContext(void) +void UIKit_GL_RestoreCurrentContext(void) { @autoreleasepool { /* Some iOS system functionality (such as Dictation on the on-screen diff --git a/SDL2-2.0.12/src/video/uikit/SDL_uikitopenglview.h b/SDL2-2.30.5/src/video/uikit/SDL_uikitopenglview.h similarity index 94% rename from SDL2-2.0.12/src/video/uikit/SDL_uikitopenglview.h rename to SDL2-2.30.5/src/video/uikit/SDL_uikitopenglview.h index 91d6ab0..d0eb0ac 100644 --- a/SDL2-2.0.12/src/video/uikit/SDL_uikitopenglview.h +++ b/SDL2-2.30.5/src/video/uikit/SDL_uikitopenglview.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -19,7 +19,7 @@ 3. This notice may not be removed or altered from any source distribution. */ -#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 +#if defined(SDL_VIDEO_OPENGL_ES) || defined(SDL_VIDEO_OPENGL_ES2) #import #import diff --git a/SDL2-2.0.12/src/video/uikit/SDL_uikitopenglview.m b/SDL2-2.30.5/src/video/uikit/SDL_uikitopenglview.m similarity index 95% rename from SDL2-2.0.12/src/video/uikit/SDL_uikitopenglview.m rename to SDL2-2.30.5/src/video/uikit/SDL_uikitopenglview.m index b59f1d6..145e867 100644 --- a/SDL2-2.0.12/src/video/uikit/SDL_uikitopenglview.m +++ b/SDL2-2.30.5/src/video/uikit/SDL_uikitopenglview.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_UIKIT && (SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2) +#if defined(SDL_VIDEO_DRIVER_UIKIT) && (defined(SDL_VIDEO_OPENGL_ES) || defined(SDL_VIDEO_OPENGL_ES2)) #include #include @@ -89,18 +89,12 @@ glGetIntegerv(GL_MAX_SAMPLES, &maxsamples); /* Clamp the samples to the max supported count. */ - samples = MIN(samples, maxsamples); + samples = SDL_min(samples, maxsamples); } if (sRGB) { - /* sRGB EAGL drawable support was added in iOS 7. */ - if (UIKit_IsSystemVersionAtLeast(7.0)) { - colorFormat = kEAGLColorFormatSRGBA8; - colorBufferFormat = GL_SRGB8_ALPHA8; - } else { - SDL_SetError("sRGB drawables are not supported."); - return nil; - } + colorFormat = kEAGLColorFormatSRGBA8; + colorBufferFormat = GL_SRGB8_ALPHA8; } else if (rBits >= 8 || gBits >= 8 || bBits >= 8 || aBits > 0) { /* if user specifically requests rbg888 or some color format higher than 16bpp */ colorFormat = kEAGLColorFormatRGBA8; diff --git a/SDL2-2.0.12/src/video/uikit/SDL_uikitvideo.h b/SDL2-2.30.5/src/video/uikit/SDL_uikitvideo.h similarity index 95% rename from SDL2-2.0.12/src/video/uikit/SDL_uikitvideo.h rename to SDL2-2.30.5/src/video/uikit/SDL_uikitvideo.h index 9b2b7b2..02a0110 100644 --- a/SDL2-2.0.12/src/video/uikit/SDL_uikitvideo.h +++ b/SDL2-2.30.5/src/video/uikit/SDL_uikitvideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/video/uikit/SDL_uikitvideo.m b/SDL2-2.30.5/src/video/uikit/SDL_uikitvideo.m similarity index 80% rename from SDL2-2.0.12/src/video/uikit/SDL_uikitvideo.m rename to SDL2-2.30.5/src/video/uikit/SDL_uikitvideo.m index 807b8d5..f3257ea 100644 --- a/SDL2-2.0.12/src/video/uikit/SDL_uikitvideo.m +++ b/SDL2-2.30.5/src/video/uikit/SDL_uikitvideo.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_UIKIT +#ifdef SDL_VIDEO_DRIVER_UIKIT #import @@ -39,6 +39,7 @@ #include "SDL_uikitclipboard.h" #include "SDL_uikitvulkan.h" #include "SDL_uikitmetalview.h" +#include "SDL_uikitmessagebox.h" #define UIKITVID_DRIVER_NAME "uikit" @@ -52,12 +53,6 @@ static void UIKit_VideoQuit(_THIS); /* DUMMY driver bootstrap functions */ -static int -UIKit_Available(void) -{ - return 1; -} - static void UIKit_DeleteDevice(SDL_VideoDevice * device) { @autoreleasepool { @@ -66,8 +61,7 @@ static void UIKit_DeleteDevice(SDL_VideoDevice * device) } } -static SDL_VideoDevice * -UIKit_CreateDevice(int devindex) +static SDL_VideoDevice *UIKit_CreateDevice(void) { @autoreleasepool { SDL_VideoDevice *device; @@ -99,11 +93,14 @@ UIKit_CreateDevice(int devindex) device->RaiseWindow = UIKit_RaiseWindow; device->SetWindowBordered = UIKit_SetWindowBordered; device->SetWindowFullscreen = UIKit_SetWindowFullscreen; + device->SetWindowMouseGrab = UIKit_SetWindowMouseGrab; device->DestroyWindow = UIKit_DestroyWindow; device->GetWindowWMInfo = UIKit_GetWindowWMInfo; device->GetDisplayUsableBounds = UIKit_GetDisplayUsableBounds; + device->GetDisplayDPI = UIKit_GetDisplayDPI; + device->GetWindowSizeInPixels = UIKit_GetWindowSizeInPixels; -#if SDL_IPHONE_KEYBOARD +#ifdef SDL_IPHONE_KEYBOARD device->HasScreenKeyboardSupport = UIKit_HasScreenKeyboardSupport; device->ShowScreenKeyboard = UIKit_ShowScreenKeyboard; device->HideScreenKeyboard = UIKit_HideScreenKeyboard; @@ -116,7 +113,7 @@ UIKit_CreateDevice(int devindex) device->HasClipboardText = UIKit_HasClipboardText; /* OpenGL (ES) functions */ -#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 +#if defined(SDL_VIDEO_OPENGL_ES) || defined(SDL_VIDEO_OPENGL_ES2) device->GL_MakeCurrent = UIKit_GL_MakeCurrent; device->GL_GetDrawableSize = UIKit_GL_GetDrawableSize; device->GL_SwapWindow = UIKit_GL_SwapWindow; @@ -127,7 +124,7 @@ UIKit_CreateDevice(int devindex) #endif device->free = UIKit_DeleteDevice; -#if SDL_VIDEO_VULKAN +#ifdef SDL_VIDEO_VULKAN device->Vulkan_LoadLibrary = UIKit_Vulkan_LoadLibrary; device->Vulkan_UnloadLibrary = UIKit_Vulkan_UnloadLibrary; device->Vulkan_GetInstanceExtensions @@ -136,9 +133,11 @@ UIKit_CreateDevice(int devindex) device->Vulkan_GetDrawableSize = UIKit_Vulkan_GetDrawableSize; #endif -#if SDL_VIDEO_METAL +#ifdef SDL_VIDEO_METAL device->Metal_CreateView = UIKit_Metal_CreateView; device->Metal_DestroyView = UIKit_Metal_DestroyView; + device->Metal_GetLayer = UIKit_Metal_GetLayer; + device->Metal_GetDrawableSize = UIKit_Metal_GetDrawableSize; #endif device->gl_config.accelerated = 1; @@ -149,29 +148,34 @@ UIKit_CreateDevice(int devindex) VideoBootStrap UIKIT_bootstrap = { UIKITVID_DRIVER_NAME, "SDL UIKit video driver", - UIKit_Available, UIKit_CreateDevice + UIKit_CreateDevice, + UIKit_ShowMessageBox }; -int -UIKit_VideoInit(_THIS) +int UIKit_VideoInit(_THIS) { _this->gl_config.driver_loaded = 1; if (UIKit_InitModes(_this) < 0) { return -1; } + + SDL_InitGCKeyboard(); + SDL_InitGCMouse(); + return 0; } -void -UIKit_VideoQuit(_THIS) +void UIKit_VideoQuit(_THIS) { + SDL_QuitGCKeyboard(); + SDL_QuitGCMouse(); + UIKit_QuitModes(_this); } -void -UIKit_SuspendScreenSaver(_THIS) +void UIKit_SuspendScreenSaver(_THIS) { @autoreleasepool { /* Ignore ScreenSaver API calls if the idle timer hint has been set. */ @@ -185,14 +189,12 @@ UIKit_SuspendScreenSaver(_THIS) } } -SDL_bool -UIKit_IsSystemVersionAtLeast(double version) +SDL_bool UIKit_IsSystemVersionAtLeast(double version) { return [[UIDevice currentDevice].systemVersion doubleValue] >= version; } -CGRect -UIKit_ComputeViewFrame(SDL_Window *window, UIScreen *screen) +CGRect UIKit_ComputeViewFrame(SDL_Window *window, UIScreen *screen) { SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata; CGRect frame = screen.bounds; @@ -204,15 +206,6 @@ UIKit_ComputeViewFrame(SDL_Window *window, UIScreen *screen) frame = data.uiwindow.bounds; } -#if !TARGET_OS_TV && (__IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0) - BOOL hasiOS7 = UIKit_IsSystemVersionAtLeast(7.0); - - /* The view should always show behind the status bar in iOS 7+. */ - if (!hasiOS7 && !(window->flags & (SDL_WINDOW_BORDERLESS|SDL_WINDOW_FULLSCREEN))) { - frame = screen.applicationFrame; - } -#endif - #if !TARGET_OS_TV /* iOS 10 seems to have a bug where, in certain conditions, putting the * device to sleep with the a landscape-only app open, re-orienting the @@ -222,26 +215,24 @@ UIKit_ComputeViewFrame(SDL_Window *window, UIScreen *screen) * https://bugzilla.libsdl.org/show_bug.cgi?id=3505 * https://bugzilla.libsdl.org/show_bug.cgi?id=3465 * https://forums.developer.apple.com/thread/65337 */ - if (UIKit_IsSystemVersionAtLeast(8.0)) { - UIInterfaceOrientation orient = [UIApplication sharedApplication].statusBarOrientation; - BOOL landscape = UIInterfaceOrientationIsLandscape(orient); - BOOL fullscreen = CGRectEqualToRect(screen.bounds, frame); + UIInterfaceOrientation orient = [UIApplication sharedApplication].statusBarOrientation; + BOOL landscape = UIInterfaceOrientationIsLandscape(orient) || + !(UIKit_GetSupportedOrientations(window) & (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown)); + BOOL fullscreen = CGRectEqualToRect(screen.bounds, frame); - /* The orientation flip doesn't make sense when the window is smaller - * than the screen (iPad Split View, for example). */ - if (fullscreen && (landscape != (frame.size.width > frame.size.height))) { - float height = frame.size.width; - frame.size.width = frame.size.height; - frame.size.height = height; - } + /* The orientation flip doesn't make sense when the window is smaller + * than the screen (iPad Split View, for example). */ + if (fullscreen && (landscape != (frame.size.width > frame.size.height))) { + float height = frame.size.width; + frame.size.width = frame.size.height; + frame.size.height = height; } #endif return frame; } -void -UIKit_ForceUpdateHomeIndicator() +void UIKit_ForceUpdateHomeIndicator(void) { #if !TARGET_OS_TV /* Force the main SDL window to re-evaluate home indicator state */ @@ -273,9 +264,17 @@ UIKit_ForceUpdateHomeIndicator() */ #if !defined(SDL_VIDEO_DRIVER_COCOA) -void SDL_NSLog(const char *text) +void SDL_NSLog(const char *prefix, const char *text) { - NSLog(@"%s", text); + @autoreleasepool { + NSString *nsText = [NSString stringWithUTF8String:text]; + if (prefix) { + NSString *nsPrefix = [NSString stringWithUTF8String:prefix]; + NSLog(@"%@: %@", nsPrefix, nsText); + } else { + NSLog(@"%@", nsText); + } + } } #endif /* SDL_VIDEO_DRIVER_COCOA */ diff --git a/SDL2-2.0.12/src/video/uikit/SDL_uikitview.h b/SDL2-2.30.5/src/video/uikit/SDL_uikitview.h similarity index 70% rename from SDL2-2.0.12/src/video/uikit/SDL_uikitview.h rename to SDL2-2.30.5/src/video/uikit/SDL_uikitview.h index ce8ad3b..c7fa8a8 100644 --- a/SDL2-2.0.12/src/video/uikit/SDL_uikitview.h +++ b/SDL2-2.30.5/src/video/uikit/SDL_uikitview.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -25,12 +25,21 @@ #include "SDL_touch.h" +#if !TARGET_OS_TV && defined(__IPHONE_13_4) +@interface SDL_uikitview : UIView +#else @interface SDL_uikitview : UIView +#endif - (instancetype)initWithFrame:(CGRect)frame; - (void)setSDLWindow:(SDL_Window *)window; +#if !TARGET_OS_TV && defined(__IPHONE_13_4) +- (UIPointerRegion *)pointerInteraction:(UIPointerInteraction *)interaction regionForRequest:(UIPointerRegionRequest *)request defaultRegion:(UIPointerRegion *)defaultRegion API_AVAILABLE(ios(13.4)); +- (UIPointerStyle *)pointerInteraction:(UIPointerInteraction *)interaction styleForRegion:(UIPointerRegion *)region API_AVAILABLE(ios(13.4)); +#endif + - (CGPoint)touchLocation:(UITouch *)touch shouldNormalize:(BOOL)normalize; - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event; - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event; diff --git a/SDL2-2.30.5/src/video/uikit/SDL_uikitview.m b/SDL2-2.30.5/src/video/uikit/SDL_uikitview.m new file mode 100644 index 0000000..63afa09 --- /dev/null +++ b/SDL2-2.30.5/src/video/uikit/SDL_uikitview.m @@ -0,0 +1,489 @@ + /* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_UIKIT + +#include "SDL_uikitview.h" + +#include "SDL_hints.h" +#include "../../events/SDL_mouse_c.h" +#include "../../events/SDL_touch_c.h" +#include "../../events/SDL_events_c.h" + +#include "SDL_uikitappdelegate.h" +#include "SDL_uikitevents.h" +#include "SDL_uikitmodes.h" +#include "SDL_uikitwindow.h" + +/* The maximum number of mouse buttons we support */ +#define MAX_MOUSE_BUTTONS 5 + +/* This is defined in SDL_sysjoystick.m */ +#ifndef SDL_JOYSTICK_DISABLED +extern int SDL_AppleTVRemoteOpenedAsJoystick; +#endif + +@implementation SDL_uikitview { + SDL_Window *sdlwindow; + + SDL_TouchID directTouchId; + SDL_TouchID indirectTouchId; +} + +- (instancetype)initWithFrame:(CGRect)frame +{ + if ((self = [super initWithFrame:frame])) { +#if TARGET_OS_TV + /* Apple TV Remote touchpad swipe gestures. */ + UISwipeGestureRecognizer *swipeUp = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeGesture:)]; + swipeUp.direction = UISwipeGestureRecognizerDirectionUp; + [self addGestureRecognizer:swipeUp]; + + UISwipeGestureRecognizer *swipeDown = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeGesture:)]; + swipeDown.direction = UISwipeGestureRecognizerDirectionDown; + [self addGestureRecognizer:swipeDown]; + + UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeGesture:)]; + swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft; + [self addGestureRecognizer:swipeLeft]; + + UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeGesture:)]; + swipeRight.direction = UISwipeGestureRecognizerDirectionRight; + [self addGestureRecognizer:swipeRight]; +#endif + + self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + self.autoresizesSubviews = YES; + + directTouchId = 1; + indirectTouchId = 2; + +#if !TARGET_OS_TV + self.multipleTouchEnabled = YES; + SDL_AddTouch(directTouchId, SDL_TOUCH_DEVICE_DIRECT, ""); +#endif + +#if !TARGET_OS_TV && defined(__IPHONE_13_4) + if (@available(iOS 13.4, *)) { + [self addInteraction:[[UIPointerInteraction alloc] initWithDelegate:self]]; + } +#endif + } + + return self; +} + +- (void)setSDLWindow:(SDL_Window *)window +{ + SDL_WindowData *data = nil; + + if (window == sdlwindow) { + return; + } + + /* Remove ourself from the old window. */ + if (sdlwindow) { + SDL_uikitview *view = nil; + data = (__bridge SDL_WindowData *) sdlwindow->driverdata; + + [data.views removeObject:self]; + + [self removeFromSuperview]; + + /* Restore the next-oldest view in the old window. */ + view = data.views.lastObject; + + data.viewcontroller.view = view; + + data.uiwindow.rootViewController = nil; + data.uiwindow.rootViewController = data.viewcontroller; + + [data.uiwindow layoutIfNeeded]; + } + + /* Add ourself to the new window. */ + if (window) { + data = (__bridge SDL_WindowData *) window->driverdata; + + /* Make sure the SDL window has a strong reference to this view. */ + [data.views addObject:self]; + + /* Replace the view controller's old view with this one. */ + [data.viewcontroller.view removeFromSuperview]; + data.viewcontroller.view = self; + + /* The root view controller handles rotation and the status bar. + * Assigning it also adds the controller's view to the window. We + * explicitly re-set it to make sure the view is properly attached to + * the window. Just adding the sub-view if the root view controller is + * already correct causes orientation issues on iOS 7 and below. */ + data.uiwindow.rootViewController = nil; + data.uiwindow.rootViewController = data.viewcontroller; + + /* The view's bounds may not be correct until the next event cycle. That + * might happen after the current dimensions are queried, so we force a + * layout now to immediately update the bounds. */ + [data.uiwindow layoutIfNeeded]; + } + + sdlwindow = window; +} + +#if !TARGET_OS_TV && defined(__IPHONE_13_4) +- (UIPointerRegion *)pointerInteraction:(UIPointerInteraction *)interaction regionForRequest:(UIPointerRegionRequest *)request defaultRegion:(UIPointerRegion *)defaultRegion API_AVAILABLE(ios(13.4)){ + if (request != nil && !SDL_GCMouseRelativeMode()) { + CGPoint origin = self.bounds.origin; + CGPoint point = request.location; + + point.x -= origin.x; + point.y -= origin.y; + + SDL_SendMouseMotion(sdlwindow, 0, 0, (int)point.x, (int)point.y); + } + return [UIPointerRegion regionWithRect:self.bounds identifier:nil]; +} + +- (UIPointerStyle *)pointerInteraction:(UIPointerInteraction *)interaction styleForRegion:(UIPointerRegion *)region API_AVAILABLE(ios(13.4)){ + if (SDL_ShowCursor(-1)) { + return nil; + } else { + return [UIPointerStyle hiddenPointerStyle]; + } +} +#endif /* !TARGET_OS_TV && __IPHONE_13_4 */ + +- (SDL_TouchDeviceType)touchTypeForTouch:(UITouch *)touch +{ +#ifdef __IPHONE_9_0 + if ([touch respondsToSelector:@selector((type))]) { + if (touch.type == UITouchTypeIndirect) { + return SDL_TOUCH_DEVICE_INDIRECT_RELATIVE; + } + } +#endif + + return SDL_TOUCH_DEVICE_DIRECT; +} + +- (SDL_TouchID)touchIdForType:(SDL_TouchDeviceType)type +{ + switch (type) { + case SDL_TOUCH_DEVICE_DIRECT: + default: + return directTouchId; + case SDL_TOUCH_DEVICE_INDIRECT_RELATIVE: + return indirectTouchId; + } +} + +- (CGPoint)touchLocation:(UITouch *)touch shouldNormalize:(BOOL)normalize +{ + CGPoint point = [touch locationInView:self]; + + if (normalize) { + CGRect bounds = self.bounds; + point.x /= bounds.size.width; + point.y /= bounds.size.height; + } + + return point; +} + +- (float)pressureForTouch:(UITouch *)touch +{ +#ifdef __IPHONE_9_0 + if ([touch respondsToSelector:@selector(force)]) { + return (float) touch.force; + } +#endif + + return 1.0f; +} + +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event +{ + for (UITouch *touch in touches) { + BOOL handled = NO; + +#if !TARGET_OS_TV && defined(__IPHONE_13_4) + if (@available(iOS 13.4, *)) { + if (touch.type == UITouchTypeIndirectPointer) { + if (!SDL_HasGCMouse()) { + int i; + + for (i = 1; i <= MAX_MOUSE_BUTTONS; ++i) { + if (event.buttonMask & SDL_BUTTON(i)) { + Uint8 button; + + switch (i) { + case 1: + button = SDL_BUTTON_LEFT; + break; + case 2: + button = SDL_BUTTON_RIGHT; + break; + case 3: + button = SDL_BUTTON_MIDDLE; + break; + default: + button = (Uint8)i; + break; + } + SDL_SendMouseButton(sdlwindow, 0, SDL_PRESSED, button); + } + } + } + handled = YES; + } + } +#endif + if (!handled) { + SDL_TouchDeviceType touchType = [self touchTypeForTouch:touch]; + SDL_TouchID touchId = [self touchIdForType:touchType]; + float pressure = [self pressureForTouch:touch]; + + if (SDL_AddTouch(touchId, touchType, "") < 0) { + continue; + } + + /* FIXME, need to send: int clicks = (int) touch.tapCount; ? */ + + CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES]; + SDL_SendTouch(touchId, (SDL_FingerID)((size_t)touch), sdlwindow, + SDL_TRUE, locationInView.x, locationInView.y, pressure); + } + } +} + +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event +{ + for (UITouch *touch in touches) { + BOOL handled = NO; + +#if !TARGET_OS_TV && defined(__IPHONE_13_4) + if (@available(iOS 13.4, *)) { + if (touch.type == UITouchTypeIndirectPointer) { + if (!SDL_HasGCMouse()) { + int i; + + for (i = 1; i <= MAX_MOUSE_BUTTONS; ++i) { + if (event.buttonMask & SDL_BUTTON(i)) { + Uint8 button; + + switch (i) { + case 1: + button = SDL_BUTTON_LEFT; + break; + case 2: + button = SDL_BUTTON_RIGHT; + break; + case 3: + button = SDL_BUTTON_MIDDLE; + break; + default: + button = (Uint8)i; + break; + } + SDL_SendMouseButton(sdlwindow, 0, SDL_RELEASED, button); + } + } + } + handled = YES; + } + } +#endif + if (!handled) { + SDL_TouchDeviceType touchType = [self touchTypeForTouch:touch]; + SDL_TouchID touchId = [self touchIdForType:touchType]; + float pressure = [self pressureForTouch:touch]; + + if (SDL_AddTouch(touchId, touchType, "") < 0) { + continue; + } + + /* FIXME, need to send: int clicks = (int) touch.tapCount; ? */ + + CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES]; + SDL_SendTouch(touchId, (SDL_FingerID)((size_t)touch), sdlwindow, + SDL_FALSE, locationInView.x, locationInView.y, pressure); + } + } +} + +- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event +{ + [self touchesEnded:touches withEvent:event]; +} + +- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event +{ + for (UITouch *touch in touches) { + BOOL handled = NO; + +#if !TARGET_OS_TV && defined(__IPHONE_13_4) + if (@available(iOS 13.4, *)) { + if (touch.type == UITouchTypeIndirectPointer) { + /* Already handled in pointerInteraction callback */ + handled = YES; + } + } +#endif + if (!handled) { + SDL_TouchDeviceType touchType = [self touchTypeForTouch:touch]; + SDL_TouchID touchId = [self touchIdForType:touchType]; + float pressure = [self pressureForTouch:touch]; + + if (SDL_AddTouch(touchId, touchType, "") < 0) { + continue; + } + + CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES]; + SDL_SendTouchMotion(touchId, (SDL_FingerID)((size_t)touch), sdlwindow, + locationInView.x, locationInView.y, pressure); + } + } +} + +#if TARGET_OS_TV || defined(__IPHONE_9_1) +- (SDL_Scancode)scancodeFromPress:(UIPress*)press +{ +#ifdef __IPHONE_13_4 + if ([press respondsToSelector:@selector((key))]) { + if (press.key != nil) { + return (SDL_Scancode)press.key.keyCode; + } + } +#endif + +#ifndef SDL_JOYSTICK_DISABLED + /* Presses from Apple TV remote */ + if (!SDL_AppleTVRemoteOpenedAsJoystick) { + switch (press.type) { + case UIPressTypeUpArrow: + return SDL_SCANCODE_UP; + case UIPressTypeDownArrow: + return SDL_SCANCODE_DOWN; + case UIPressTypeLeftArrow: + return SDL_SCANCODE_LEFT; + case UIPressTypeRightArrow: + return SDL_SCANCODE_RIGHT; + case UIPressTypeSelect: + /* HIG says: "primary button behavior" */ + return SDL_SCANCODE_RETURN; + case UIPressTypeMenu: + /* HIG says: "returns to previous screen" */ + return SDL_SCANCODE_ESCAPE; + case UIPressTypePlayPause: + /* HIG says: "secondary button behavior" */ + return SDL_SCANCODE_PAUSE; + default: + break; + } + } +#endif /* !SDL_JOYSTICK_DISABLED */ + + return SDL_SCANCODE_UNKNOWN; +} + +- (void)pressesBegan:(NSSet *)presses withEvent:(UIPressesEvent *)event +{ + if (!SDL_HasGCKeyboard()) { + for (UIPress *press in presses) { + SDL_Scancode scancode = [self scancodeFromPress:press]; + SDL_SendKeyboardKey(SDL_PRESSED, scancode); + } + } + if (SDL_IsTextInputActive()) { + [super pressesBegan:presses withEvent:event]; + } +} + +- (void)pressesEnded:(NSSet *)presses withEvent:(UIPressesEvent *)event +{ + if (!SDL_HasGCKeyboard()) { + for (UIPress *press in presses) { + SDL_Scancode scancode = [self scancodeFromPress:press]; + SDL_SendKeyboardKey(SDL_RELEASED, scancode); + } + } + if (SDL_IsTextInputActive()) { + [super pressesEnded:presses withEvent:event]; + } +} + +- (void)pressesCancelled:(NSSet *)presses withEvent:(UIPressesEvent *)event +{ + if (!SDL_HasGCKeyboard()) { + for (UIPress *press in presses) { + SDL_Scancode scancode = [self scancodeFromPress:press]; + SDL_SendKeyboardKey(SDL_RELEASED, scancode); + } + } + if (SDL_IsTextInputActive()) { + [super pressesCancelled:presses withEvent:event]; + } +} + +- (void)pressesChanged:(NSSet *)presses withEvent:(UIPressesEvent *)event +{ + /* This is only called when the force of a press changes. */ + if (SDL_IsTextInputActive()) { + [super pressesChanged:presses withEvent:event]; + } +} + +#endif /* TARGET_OS_TV || defined(__IPHONE_9_1) */ + +#if TARGET_OS_TV +-(void)swipeGesture:(UISwipeGestureRecognizer *)gesture +{ + /* Swipe gestures don't trigger begin states. */ + if (gesture.state == UIGestureRecognizerStateEnded) { +#ifndef SDL_JOYSTICK_DISABLED + if (!SDL_AppleTVRemoteOpenedAsJoystick) { + /* Send arrow key presses for now, as we don't have an external API + * which better maps to swipe gestures. */ + switch (gesture.direction) { + case UISwipeGestureRecognizerDirectionUp: + SDL_SendKeyboardKeyAutoRelease(SDL_SCANCODE_UP); + break; + case UISwipeGestureRecognizerDirectionDown: + SDL_SendKeyboardKeyAutoRelease(SDL_SCANCODE_DOWN); + break; + case UISwipeGestureRecognizerDirectionLeft: + SDL_SendKeyboardKeyAutoRelease(SDL_SCANCODE_LEFT); + break; + case UISwipeGestureRecognizerDirectionRight: + SDL_SendKeyboardKeyAutoRelease(SDL_SCANCODE_RIGHT); + break; + } + } +#endif /* !SDL_JOYSTICK_DISABLED */ + } +} +#endif /* TARGET_OS_TV */ + +@end + +#endif /* SDL_VIDEO_DRIVER_UIKIT */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/uikit/SDL_uikitviewcontroller.h b/SDL2-2.30.5/src/video/uikit/SDL_uikitviewcontroller.h similarity index 89% rename from SDL2-2.0.12/src/video/uikit/SDL_uikitviewcontroller.h rename to SDL2-2.30.5/src/video/uikit/SDL_uikitviewcontroller.h index 77076d7..660e11c 100644 --- a/SDL2-2.0.12/src/video/uikit/SDL_uikitviewcontroller.h +++ b/SDL2-2.30.5/src/video/uikit/SDL_uikitviewcontroller.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -33,7 +33,11 @@ #define SDLRootViewController UIViewController #endif -#if SDL_IPHONE_KEYBOARD +@interface SDLUITextField : UITextField +- (BOOL)canPerformAction:(SEL)action withSender:(id)sender; +@end + +#ifdef SDL_IPHONE_KEYBOARD @interface SDL_uikitviewcontroller : SDLRootViewController #else @interface SDL_uikitviewcontroller : SDLRootViewController @@ -64,7 +68,7 @@ @property (nonatomic, assign) int homeIndicatorHidden; #endif -#if SDL_IPHONE_KEYBOARD +#ifdef SDL_IPHONE_KEYBOARD - (void)showKeyboard; - (void)hideKeyboard; - (void)initKeyboard; @@ -82,10 +86,10 @@ @end -#if SDL_IPHONE_KEYBOARD +#ifdef SDL_IPHONE_KEYBOARD SDL_bool UIKit_HasScreenKeyboardSupport(_THIS); void UIKit_ShowScreenKeyboard(_THIS, SDL_Window *window); void UIKit_HideScreenKeyboard(_THIS, SDL_Window *window); SDL_bool UIKit_IsScreenKeyboardShown(_THIS, SDL_Window *window); -void UIKit_SetTextInputRect(_THIS, SDL_Rect *rect); +void UIKit_SetTextInputRect(_THIS, const SDL_Rect *rect); #endif diff --git a/SDL2-2.0.12/src/video/uikit/SDL_uikitviewcontroller.m b/SDL2-2.30.5/src/video/uikit/SDL_uikitviewcontroller.m similarity index 72% rename from SDL2-2.0.12/src/video/uikit/SDL_uikitviewcontroller.m rename to SDL2-2.30.5/src/video/uikit/SDL_uikitviewcontroller.m index fcb27ff..0d8052b 100644 --- a/SDL2-2.0.12/src/video/uikit/SDL_uikitviewcontroller.m +++ b/SDL2-2.30.5/src/video/uikit/SDL_uikitviewcontroller.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,25 +20,21 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_UIKIT +#ifdef SDL_VIDEO_DRIVER_UIKIT #include "SDL_video.h" -#include "SDL_assert.h" #include "SDL_hints.h" #include "../SDL_sysvideo.h" #include "../../events/SDL_events_c.h" -#import "SDL_uikitviewcontroller.h" -#import "SDL_uikitmessagebox.h" +#include "SDL_uikitviewcontroller.h" +#include "SDL_uikitmessagebox.h" +#include "SDL_uikitevents.h" #include "SDL_uikitvideo.h" #include "SDL_uikitmodes.h" #include "SDL_uikitwindow.h" #include "SDL_uikitopengles.h" -#if SDL_IPHONE_KEYBOARD -#include "keyinfotable.h" -#endif - #if TARGET_OS_TV static void SDLCALL SDL_AppleTVControllerUIHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint) @@ -68,18 +64,30 @@ SDL_HideHomeIndicatorHintChanged(void *userdata, const char *name, const char *o } #endif +@implementation SDLUITextField : UITextField +- (BOOL)canPerformAction:(SEL)action withSender:(id)sender +{ + if (action == @selector(paste:)) { + return NO; + } + + return [super canPerformAction:action withSender:sender]; +} +@end + @implementation SDL_uikitviewcontroller { CADisplayLink *displayLink; int animationInterval; void (*animationCallback)(void*); void *animationCallbackParam; -#if SDL_IPHONE_KEYBOARD - UITextField *textField; +#ifdef SDL_IPHONE_KEYBOARD + SDLUITextField *textField; BOOL hardwareKeyboard; BOOL showingKeyboard; + BOOL hidingKeyboard; BOOL rotatingOrientation; - NSString *changeText; + NSString *committedText; NSString *obligateForBackspace; #endif } @@ -91,10 +99,11 @@ SDL_HideHomeIndicatorHintChanged(void *userdata, const char *name, const char *o if (self = [super initWithNibName:nil bundle:nil]) { self.window = _window; -#if SDL_IPHONE_KEYBOARD +#ifdef SDL_IPHONE_KEYBOARD [self initKeyboard]; hardwareKeyboard = NO; showingKeyboard = NO; + hidingKeyboard = NO; rotatingOrientation = NO; #endif @@ -115,7 +124,7 @@ SDL_HideHomeIndicatorHintChanged(void *userdata, const char *name, const char *o - (void)dealloc { -#if SDL_IPHONE_KEYBOARD +#ifdef SDL_IPHONE_KEYBOARD [self deinitKeyboard]; #endif @@ -180,7 +189,7 @@ SDL_HideHomeIndicatorHintChanged(void *userdata, const char *name, const char *o /* Don't run the game loop while a messagebox is up */ if (!UIKit_ShowingMessageBox()) { /* See the comment in the function definition. */ -#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 +#if defined(SDL_VIDEO_OPENGL_ES) || defined(SDL_VIDEO_OPENGL_ES2) UIKit_GL_RestoreCurrentContext(); #endif @@ -208,13 +217,6 @@ SDL_HideHomeIndicatorHintChanged(void *userdata, const char *name, const char *o return UIKit_GetSupportedOrientations(window); } -#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0 -- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orient -{ - return ([self supportedInterfaceOrientations] & (1 << orient)) != 0; -} -#endif - - (BOOL)prefersStatusBarHidden { BOOL hidden = (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) != 0; @@ -247,12 +249,18 @@ SDL_HideHomeIndicatorHintChanged(void *userdata, const char *name, const char *o return UIRectEdgeNone; } } -#endif + +- (BOOL)prefersPointerLocked +{ + return SDL_GCMouseRelativeMode() ? YES : NO; +} + +#endif /* !TARGET_OS_TV */ /* ---- Keyboard related functionality below this line ---- */ -#if SDL_IPHONE_KEYBOARD +#ifdef SDL_IPHONE_KEYBOARD @synthesize textInputRect; @synthesize keyboardHeight; @@ -261,12 +269,12 @@ SDL_HideHomeIndicatorHintChanged(void *userdata, const char *name, const char *o /* Set ourselves up as a UITextFieldDelegate */ - (void)initKeyboard { - changeText = nil; obligateForBackspace = @" "; /* 64 space */ - textField = [[UITextField alloc] initWithFrame:CGRectZero]; + textField = [[SDLUITextField alloc] initWithFrame:CGRectZero]; textField.delegate = self; /* placeholder so there is something to delete! */ textField.text = obligateForBackspace; + committedText = textField.text; /* set UITextInputTrait properties, mostly to defaults */ textField.autocapitalizationType = UITextAutocapitalizationTypeNone; @@ -282,8 +290,22 @@ SDL_HideHomeIndicatorHintChanged(void *userdata, const char *name, const char *o NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; #if !TARGET_OS_TV - [center addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; - [center addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; + [center addObserver:self + selector:@selector(keyboardWillShow:) + name:UIKeyboardWillShowNotification + object:nil]; + [center addObserver:self + selector:@selector(keyboardDidShow:) + name:UIKeyboardDidShowNotification + object:nil]; + [center addObserver:self + selector:@selector(keyboardWillHide:) + name:UIKeyboardWillHideNotification + object:nil]; + [center addObserver:self + selector:@selector(keyboardDidHide:) + name:UIKeyboardDidHideNotification + object:nil]; #endif [center addObserver:self selector:@selector(textFieldTextDidChange:) name:UITextFieldTextDidChangeNotification object:nil]; } @@ -317,8 +339,7 @@ SDL_HideHomeIndicatorHintChanged(void *userdata, const char *name, const char *o } if (scancode != SDL_SCANCODE_UNKNOWN) { - SDL_SendKeyboardKey(SDL_PRESSED, scancode); - SDL_SendKeyboardKey(SDL_RELEASED, scancode); + SDL_SendKeyboardKeyAutoRelease(scancode); } } @@ -333,8 +354,6 @@ SDL_HideHomeIndicatorHintChanged(void *userdata, const char *name, const char *o } } -/* willRotateToInterfaceOrientation and didRotateFromInterfaceOrientation are deprecated in iOS 8+ in favor of viewWillTransitionToSize */ -#if TARGET_OS_TV || __IPHONE_OS_VERSION_MIN_REQUIRED >= 80000 - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id)coordinator { [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; @@ -342,26 +361,25 @@ SDL_HideHomeIndicatorHintChanged(void *userdata, const char *name, const char *o [coordinator animateAlongsideTransition:^(id context) {} completion:^(id context) { self->rotatingOrientation = NO; - }]; + }]; } -#else -- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { - [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration]; - rotatingOrientation = YES; -} - -- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { - [super didRotateFromInterfaceOrientation:fromInterfaceOrientation]; - rotatingOrientation = NO; -} -#endif /* TARGET_OS_TV || __IPHONE_OS_VERSION_MIN_REQUIRED >= 80000 */ - (void)deinitKeyboard { NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; #if !TARGET_OS_TV - [center removeObserver:self name:UIKeyboardWillShowNotification object:nil]; - [center removeObserver:self name:UIKeyboardWillHideNotification object:nil]; + [center removeObserver:self + name:UIKeyboardWillShowNotification + object:nil]; + [center removeObserver:self + name:UIKeyboardDidShowNotification + object:nil]; + [center removeObserver:self + name:UIKeyboardWillHideNotification + object:nil]; + [center removeObserver:self + name:UIKeyboardDidHideNotification + object:nil]; #endif [center removeObserver:self name:UITextFieldTextDidChangeNotification object:nil]; } @@ -369,23 +387,40 @@ SDL_HideHomeIndicatorHintChanged(void *userdata, const char *name, const char *o /* reveal onscreen virtual keyboard */ - (void)showKeyboard { + if (keyboardVisible) { + return; + } + keyboardVisible = YES; if (textField.window) { showingKeyboard = YES; [textField becomeFirstResponder]; - showingKeyboard = NO; } } /* hide onscreen virtual keyboard */ - (void)hideKeyboard { + if (!keyboardVisible) { + return; + } + keyboardVisible = NO; - [textField resignFirstResponder]; + if (textField.window) { + hidingKeyboard = YES; + [textField resignFirstResponder]; + } } - (void)keyboardWillShow:(NSNotification *)notification { + BOOL shouldStartTextInput = NO; + + if (!SDL_IsTextInputActive() && !hidingKeyboard && !rotatingOrientation) { + shouldStartTextInput = YES; + } + + showingKeyboard = YES; #if !TARGET_OS_TV CGRect kbrect = [[notification userInfo][UIKeyboardFrameEndUserInfoKey] CGRectValue]; @@ -395,65 +430,83 @@ SDL_HideHomeIndicatorHintChanged(void *userdata, const char *name, const char *o [self setKeyboardHeight:(int)kbrect.size.height]; #endif + + if (shouldStartTextInput) { + SDL_StartTextInput(); + } +} + +- (void)keyboardDidShow:(NSNotification *)notification +{ + showingKeyboard = NO; } - (void)keyboardWillHide:(NSNotification *)notification { - if (!showingKeyboard && !rotatingOrientation) { + BOOL shouldStopTextInput = NO; + + if (SDL_IsTextInputActive() && !showingKeyboard && !rotatingOrientation) { + shouldStopTextInput = YES; + } + + hidingKeyboard = YES; + [self setKeyboardHeight:0]; + + if (shouldStopTextInput) { SDL_StopTextInput(); } - [self setKeyboardHeight:0]; +} + +- (void)keyboardDidHide:(NSNotification *)notification +{ + hidingKeyboard = NO; } - (void)textFieldTextDidChange:(NSNotification *)notification { - if (changeText!=nil && textField.markedTextRange == nil) - { - NSUInteger len = changeText.length; - if (len > 0) { - /* Go through all the characters in the string we've been sent and - * convert them to key presses */ - int i; - for (i = 0; i < len; i++) { - unichar c = [changeText characterAtIndex:i]; - SDL_Scancode code; - Uint16 mod; + if (textField.markedTextRange == nil) { + NSUInteger compareLength = SDL_min(textField.text.length, committedText.length); + NSUInteger matchLength; - if (c < 127) { - /* Figure out the SDL_Scancode and SDL_keymod for this unichar */ - code = unicharToUIKeyInfoTable[c].code; - mod = unicharToUIKeyInfoTable[c].mod; - } else { - /* We only deal with ASCII right now */ - code = SDL_SCANCODE_UNKNOWN; - mod = 0; - } + /* Backspace over characters that are no longer in the string */ + for (matchLength = 0; matchLength < compareLength; ++matchLength) { + if ([committedText characterAtIndex:matchLength] != [textField.text characterAtIndex:matchLength]) { + break; + } + } + if (matchLength < committedText.length) { + size_t deleteLength = SDL_utf8strlen([[committedText substringFromIndex:matchLength] UTF8String]); + while (deleteLength > 0) { + /* Send distinct down and up events for each backspace action */ + SDL_SendVirtualKeyboardKey(SDL_PRESSED, SDL_SCANCODE_BACKSPACE); + SDL_SendVirtualKeyboardKey(SDL_RELEASED, SDL_SCANCODE_BACKSPACE); + --deleteLength; + } + } - if (mod & KMOD_SHIFT) { - /* If character uses shift, press shift down */ - SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_LSHIFT); - } - - /* send a keydown and keyup even for the character */ - SDL_SendKeyboardKey(SDL_PRESSED, code); - SDL_SendKeyboardKey(SDL_RELEASED, code); - - if (mod & KMOD_SHIFT) { - /* If character uses shift, press shift back up */ - SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LSHIFT); + if (matchLength < textField.text.length) { + NSString *pendingText = [textField.text substringFromIndex:matchLength]; + if (!SDL_HardwareKeyboardKeyPressed()) { + /* Go through all the characters in the string we've been sent and + * convert them to key presses */ + NSUInteger i; + for (i = 0; i < pendingText.length; i++) { + SDL_SendKeyboardUnicodeKey([pendingText characterAtIndex:i]); } } - SDL_SendKeyboardText([changeText UTF8String]); + SDL_SendKeyboardText([pendingText UTF8String]); } - changeText = nil; + committedText = textField.text; } } - (void)updateKeyboard { + SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata; + CGAffineTransform t = self.view.transform; CGPoint offset = CGPointMake(0.0, 0.0); - CGRect frame = UIKit_ComputeViewFrame(window, self.view.window.screen); + CGRect frame = UIKit_ComputeViewFrame(window, data.uiwindow.screen); if (self.keyboardHeight) { int rectbottom = self.textInputRect.y + self.textInputRect.h; @@ -486,19 +539,11 @@ SDL_HideHomeIndicatorHintChanged(void *userdata, const char *name, const char *o /* UITextFieldDelegate method. Invoked when user types something. */ - (BOOL)textField:(UITextField *)_textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { - NSUInteger len = string.length; - if (len == 0) { - changeText = nil; - if (textField.markedTextRange == nil) { - /* it wants to replace text with nothing, ie a delete */ - SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_BACKSPACE); - SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_BACKSPACE); - } + if (textField.markedTextRange == nil) { if (textField.text.length < 16) { textField.text = obligateForBackspace; + committedText = textField.text; } - } else { - changeText = string; } return YES; } @@ -506,8 +551,7 @@ SDL_HideHomeIndicatorHintChanged(void *userdata, const char *name, const char *o /* Terminates the editing session */ - (BOOL)textFieldShouldReturn:(UITextField*)_textField { - SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_RETURN); - SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_RETURN); + SDL_SendKeyboardKeyAutoRelease(SDL_SCANCODE_RETURN); if (keyboardVisible && SDL_GetHintBoolean(SDL_HINT_RETURN_KEY_HIDES_IME, SDL_FALSE)) { SDL_StopTextInput(); @@ -520,10 +564,9 @@ SDL_HideHomeIndicatorHintChanged(void *userdata, const char *name, const char *o @end /* iPhone keyboard addition functions */ -#if SDL_IPHONE_KEYBOARD +#ifdef SDL_IPHONE_KEYBOARD -static SDL_uikitviewcontroller * -GetWindowViewController(SDL_Window * window) +static SDL_uikitviewcontroller *GetWindowViewController(SDL_Window * window) { if (!window || !window->driverdata) { SDL_SetError("Invalid window"); @@ -535,14 +578,12 @@ GetWindowViewController(SDL_Window * window) return data.viewcontroller; } -SDL_bool -UIKit_HasScreenKeyboardSupport(_THIS) +SDL_bool UIKit_HasScreenKeyboardSupport(_THIS) { return SDL_TRUE; } -void -UIKit_ShowScreenKeyboard(_THIS, SDL_Window *window) +void UIKit_ShowScreenKeyboard(_THIS, SDL_Window *window) { @autoreleasepool { SDL_uikitviewcontroller *vc = GetWindowViewController(window); @@ -550,8 +591,7 @@ UIKit_ShowScreenKeyboard(_THIS, SDL_Window *window) } } -void -UIKit_HideScreenKeyboard(_THIS, SDL_Window *window) +void UIKit_HideScreenKeyboard(_THIS, SDL_Window *window) { @autoreleasepool { SDL_uikitviewcontroller *vc = GetWindowViewController(window); @@ -559,8 +599,7 @@ UIKit_HideScreenKeyboard(_THIS, SDL_Window *window) } } -SDL_bool -UIKit_IsScreenKeyboardShown(_THIS, SDL_Window *window) +SDL_bool UIKit_IsScreenKeyboardShown(_THIS, SDL_Window *window) { @autoreleasepool { SDL_uikitviewcontroller *vc = GetWindowViewController(window); @@ -571,8 +610,7 @@ UIKit_IsScreenKeyboardShown(_THIS, SDL_Window *window) } } -void -UIKit_SetTextInputRect(_THIS, SDL_Rect *rect) +void UIKit_SetTextInputRect(_THIS, const SDL_Rect *rect) { if (!rect) { SDL_InvalidParamError("rect"); diff --git a/SDL2-2.0.12/src/video/uikit/SDL_uikitvulkan.h b/SDL2-2.30.5/src/video/uikit/SDL_uikitvulkan.h similarity index 93% rename from SDL2-2.0.12/src/video/uikit/SDL_uikitvulkan.h rename to SDL2-2.30.5/src/video/uikit/SDL_uikitvulkan.h index eb7accb..fe558f9 100644 --- a/SDL2-2.0.12/src/video/uikit/SDL_uikitvulkan.h +++ b/SDL2-2.30.5/src/video/uikit/SDL_uikitvulkan.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -32,7 +32,7 @@ #include "../SDL_vulkan_internal.h" #include "../SDL_sysvideo.h" -#if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_UIKIT +#if defined(SDL_VIDEO_VULKAN) && defined(SDL_VIDEO_DRIVER_UIKIT) int UIKit_Vulkan_LoadLibrary(_THIS, const char *path); void UIKit_Vulkan_UnloadLibrary(_THIS); diff --git a/SDL2-2.0.12/src/video/uikit/SDL_uikitvulkan.m b/SDL2-2.30.5/src/video/uikit/SDL_uikitvulkan.m similarity index 75% rename from SDL2-2.0.12/src/video/uikit/SDL_uikitvulkan.m rename to SDL2-2.30.5/src/video/uikit/SDL_uikitvulkan.m index b92940b..c0dfd29 100644 --- a/SDL2-2.0.12/src/video/uikit/SDL_uikitvulkan.m +++ b/SDL2-2.30.5/src/video/uikit/SDL_uikitvulkan.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,11 +26,10 @@ #include "../../SDL_internal.h" -#if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_UIKIT +#if defined(SDL_VIDEO_VULKAN) && defined(SDL_VIDEO_DRIVER_UIKIT) #include "SDL_uikitvideo.h" #include "SDL_uikitwindow.h" -#include "SDL_assert.h" #include "SDL_loadso.h" #include "SDL_uikitvulkan.h" @@ -52,6 +51,7 @@ int UIKit_Vulkan_LoadLibrary(_THIS, const char *path) VkExtensionProperties *extensions = NULL; Uint32 extensionCount = 0; SDL_bool hasSurfaceExtension = SDL_FALSE; + SDL_bool hasMetalSurfaceExtension = SDL_FALSE; SDL_bool hasIOSSurfaceExtension = SDL_FALSE; PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL; @@ -135,6 +135,8 @@ int UIKit_Vulkan_LoadLibrary(_THIS, const char *path) for (Uint32 i = 0; i < extensionCount; i++) { if (SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) { hasSurfaceExtension = SDL_TRUE; + } else if (SDL_strcmp(VK_EXT_METAL_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) { + hasMetalSurfaceExtension = SDL_TRUE; } else if (SDL_strcmp(VK_MVK_IOS_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) { hasIOSSurfaceExtension = SDL_TRUE; } @@ -146,9 +148,10 @@ int UIKit_Vulkan_LoadLibrary(_THIS, const char *path) SDL_SetError("Installed Vulkan Portability doesn't implement the " VK_KHR_SURFACE_EXTENSION_NAME " extension"); goto fail; - } else if (!hasIOSSurfaceExtension) { + } else if (!hasMetalSurfaceExtension && !hasIOSSurfaceExtension) { SDL_SetError("Installed Vulkan Portability doesn't implement the " - VK_MVK_IOS_SURFACE_EXTENSION_NAME "extension"); + VK_EXT_METAL_SURFACE_EXTENSION_NAME " or " + VK_MVK_IOS_SURFACE_EXTENSION_NAME " extensions"); goto fail; } @@ -175,7 +178,7 @@ SDL_bool UIKit_Vulkan_GetInstanceExtensions(_THIS, const char **names) { static const char *const extensionsForUIKit[] = { - VK_KHR_SURFACE_EXTENSION_NAME, VK_MVK_IOS_SURFACE_EXTENSION_NAME + VK_KHR_SURFACE_EXTENSION_NAME, VK_EXT_METAL_SURFACE_EXTENSION_NAME }; if (!_this->vulkan_config.loader_handle) { SDL_SetError("Vulkan is not loaded"); @@ -194,11 +197,14 @@ SDL_bool UIKit_Vulkan_CreateSurface(_THIS, { PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr; + PFN_vkCreateMetalSurfaceEXT vkCreateMetalSurfaceEXT = + (PFN_vkCreateMetalSurfaceEXT)vkGetInstanceProcAddr( + (VkInstance)instance, + "vkCreateMetalSurfaceEXT"); PFN_vkCreateIOSSurfaceMVK vkCreateIOSSurfaceMVK = (PFN_vkCreateIOSSurfaceMVK)vkGetInstanceProcAddr( (VkInstance)instance, "vkCreateIOSSurfaceMVK"); - VkIOSSurfaceCreateInfoMVK createInfo = {}; VkResult result; SDL_MetalView metalview; @@ -207,9 +213,10 @@ SDL_bool UIKit_Vulkan_CreateSurface(_THIS, return SDL_FALSE; } - if (!vkCreateIOSSurfaceMVK) { - SDL_SetError(VK_MVK_IOS_SURFACE_EXTENSION_NAME - " extension is not enabled in the Vulkan instance."); + if (!vkCreateMetalSurfaceEXT && !vkCreateIOSSurfaceMVK) { + SDL_SetError(VK_EXT_METAL_SURFACE_EXTENSION_NAME " or " + VK_MVK_IOS_SURFACE_EXTENSION_NAME + " extensions are not enabled in the Vulkan instance."); return SDL_FALSE; } @@ -218,17 +225,34 @@ SDL_bool UIKit_Vulkan_CreateSurface(_THIS, return SDL_FALSE; } - createInfo.sType = VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK; - createInfo.pNext = NULL; - createInfo.flags = 0; - createInfo.pView = (const void *)metalview; - result = vkCreateIOSSurfaceMVK(instance, &createInfo, - NULL, surface); - if (result != VK_SUCCESS) { - UIKit_Metal_DestroyView(_this, metalview); - SDL_SetError("vkCreateIOSSurfaceMVK failed: %s", - SDL_Vulkan_GetResultString(result)); - return SDL_FALSE; + if (vkCreateMetalSurfaceEXT) { + VkMetalSurfaceCreateInfoEXT createInfo = {}; + createInfo.sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT; + createInfo.pNext = NULL; + createInfo.flags = 0; + createInfo.pLayer = (__bridge const CAMetalLayer *) + UIKit_Metal_GetLayer(_this, metalview); + result = vkCreateMetalSurfaceEXT(instance, &createInfo, NULL, surface); + if (result != VK_SUCCESS) { + UIKit_Metal_DestroyView(_this, metalview); + SDL_SetError("vkCreateMetalSurfaceEXT failed: %s", + SDL_Vulkan_GetResultString(result)); + return SDL_FALSE; + } + } else { + VkIOSSurfaceCreateInfoMVK createInfo = {}; + createInfo.sType = VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK; + createInfo.pNext = NULL; + createInfo.flags = 0; + createInfo.pView = (const void *)metalview; + result = vkCreateIOSSurfaceMVK(instance, &createInfo, + NULL, surface); + if (result != VK_SUCCESS) { + UIKit_Metal_DestroyView(_this, metalview); + SDL_SetError("vkCreateIOSSurfaceMVK failed: %s", + SDL_Vulkan_GetResultString(result)); + return SDL_FALSE; + } } /* Unfortunately there's no SDL_Vulkan_DestroySurface function we can call @@ -243,7 +267,7 @@ SDL_bool UIKit_Vulkan_CreateSurface(_THIS, void UIKit_Vulkan_GetDrawableSize(_THIS, SDL_Window *window, int *w, int *h) { - UIKit_Metal_GetDrawableSize(window, w, h); + UIKit_Metal_GetDrawableSize(_this, window, w, h); } #endif diff --git a/SDL2-2.0.12/src/video/uikit/SDL_uikitwindow.h b/SDL2-2.30.5/src/video/uikit/SDL_uikitwindow.h similarity index 88% rename from SDL2-2.0.12/src/video/uikit/SDL_uikitwindow.h rename to SDL2-2.30.5/src/video/uikit/SDL_uikitwindow.h index dd7c388..bf79ee1 100644 --- a/SDL2-2.0.12/src/video/uikit/SDL_uikitwindow.h +++ b/SDL2-2.30.5/src/video/uikit/SDL_uikitwindow.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -33,7 +33,10 @@ extern void UIKit_HideWindow(_THIS, SDL_Window * window); extern void UIKit_RaiseWindow(_THIS, SDL_Window * window); extern void UIKit_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered); extern void UIKit_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen); +extern void UIKit_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed); +extern void UIKit_UpdatePointerLock(_THIS, SDL_Window * window); extern void UIKit_DestroyWindow(_THIS, SDL_Window * window); +extern void UIKit_GetWindowSizeInPixels(_THIS, SDL_Window * window, int *w, int *h); extern SDL_bool UIKit_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo * info); diff --git a/SDL2-2.0.12/src/video/uikit/SDL_uikitwindow.m b/SDL2-2.30.5/src/video/uikit/SDL_uikitwindow.m similarity index 82% rename from SDL2-2.0.12/src/video/uikit/SDL_uikitwindow.m rename to SDL2-2.30.5/src/video/uikit/SDL_uikitwindow.m index 9a9f4af..ff3cb85 100644 --- a/SDL2-2.0.12/src/video/uikit/SDL_uikitwindow.m +++ b/SDL2-2.30.5/src/video/uikit/SDL_uikitwindow.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,13 +20,13 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_UIKIT +#ifdef SDL_VIDEO_DRIVER_UIKIT +#include "SDL_hints.h" +#include "SDL_mouse.h" +#include "SDL_system.h" #include "SDL_syswm.h" #include "SDL_video.h" -#include "SDL_mouse.h" -#include "SDL_assert.h" -#include "SDL_hints.h" #include "../SDL_sysvideo.h" #include "../SDL_pixels_c.h" #include "../../events/SDL_events_c.h" @@ -84,8 +84,7 @@ @end -static int -SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bool created) +static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bool created) { SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); SDL_DisplayData *displaydata = (__bridge SDL_DisplayData *) display->driverdata; @@ -115,14 +114,6 @@ SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bool created) #if !TARGET_OS_TV if (displaydata.uiscreen == [UIScreen mainScreen]) { - /* SDL_CreateWindow sets the window w&h to the display's bounds if the - * fullscreen flag is set. But the display bounds orientation might not - * match what we want, and GetSupportedOrientations call below uses the - * window w&h. They're overridden below anyway, so we'll just set them - * to the requested size for the purposes of determining orientation. */ - window->w = window->windowed.w; - window->h = window->windowed.h; - NSUInteger orients = UIKit_GetSupportedOrientations(window); BOOL supportsLandscape = (orients & UIInterfaceOrientationMaskLandscape) != 0; BOOL supportsPortrait = (orients & (UIInterfaceOrientationMaskPortrait|UIInterfaceOrientationMaskPortraitUpsideDown)) != 0; @@ -136,8 +127,10 @@ SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bool created) } #endif /* !TARGET_OS_TV */ +#if 0 /* Don't set the x/y position, it's already placed on a display */ window->x = 0; window->y = 0; +#endif window->w = width; window->h = height; @@ -156,19 +149,18 @@ SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bool created) return 0; } -int -UIKit_CreateWindow(_THIS, SDL_Window *window) +int UIKit_CreateWindow(_THIS, SDL_Window *window) { @autoreleasepool { SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata; - - /* SDL currently puts this window at the start of display's linked list. We rely on this. */ - SDL_assert(_this->windows == window); + SDL_Window *other; /* We currently only handle a single window per display on iOS */ - if (window->next != NULL) { - return SDL_SetError("Only one window allowed per display."); + for (other = _this->windows; other; other = other->next) { + if (other != window && SDL_GetDisplayForWindow(other) == display) { + return SDL_SetError("Only one window allowed per display."); + } } /* If monitor has a resolution of 0x0 (hasn't been explicitly set by the @@ -227,8 +219,7 @@ UIKit_CreateWindow(_THIS, SDL_Window *window) return 1; } -void -UIKit_SetWindowTitle(_THIS, SDL_Window * window) +void UIKit_SetWindowTitle(_THIS, SDL_Window * window) { @autoreleasepool { SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata; @@ -236,8 +227,7 @@ UIKit_SetWindowTitle(_THIS, SDL_Window * window) } } -void -UIKit_ShowWindow(_THIS, SDL_Window * window) +void UIKit_ShowWindow(_THIS, SDL_Window * window) { @autoreleasepool { SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata; @@ -253,8 +243,7 @@ UIKit_ShowWindow(_THIS, SDL_Window * window) } } -void -UIKit_HideWindow(_THIS, SDL_Window * window) +void UIKit_HideWindow(_THIS, SDL_Window * window) { @autoreleasepool { SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata; @@ -262,8 +251,7 @@ UIKit_HideWindow(_THIS, SDL_Window * window) } } -void -UIKit_RaiseWindow(_THIS, SDL_Window * window) +void UIKit_RaiseWindow(_THIS, SDL_Window * window) { /* We don't currently offer a concept of "raising" the SDL window, since * we only allow one per display, in the iOS fashion. @@ -272,8 +260,7 @@ UIKit_RaiseWindow(_THIS, SDL_Window * window) _this->GL_MakeCurrent(_this, _this->current_glwin, _this->current_glctx); } -static void -UIKit_UpdateWindowBorder(_THIS, SDL_Window * window) +static void UIKit_UpdateWindowBorder(_THIS, SDL_Window * window) { SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata; SDL_uikitviewcontroller *viewcontroller = data.viewcontroller; @@ -286,10 +273,7 @@ UIKit_UpdateWindowBorder(_THIS, SDL_Window * window) [UIApplication sharedApplication].statusBarHidden = NO; } - /* iOS 7+ won't update the status bar until we tell it to. */ - if ([viewcontroller respondsToSelector:@selector(setNeedsStatusBarAppearanceUpdate)]) { - [viewcontroller setNeedsStatusBarAppearanceUpdate]; - } + [viewcontroller setNeedsStatusBarAppearanceUpdate]; } /* Update the view's frame to account for the status bar change. */ @@ -305,28 +289,45 @@ UIKit_UpdateWindowBorder(_THIS, SDL_Window * window) [viewcontroller.view layoutIfNeeded]; } -void -UIKit_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered) +void UIKit_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered) { @autoreleasepool { UIKit_UpdateWindowBorder(_this, window); } } -void -UIKit_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen) +void UIKit_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen) { @autoreleasepool { UIKit_UpdateWindowBorder(_this, window); } } -void -UIKit_DestroyWindow(_THIS, SDL_Window * window) +void UIKit_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed) +{ + /* There really isn't a concept of window grab or cursor confinement on iOS */ +} + +void UIKit_UpdatePointerLock(_THIS, SDL_Window * window) +{ +#if !TARGET_OS_TV +#if defined(__IPHONE_14_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_14_0 + @autoreleasepool { + SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata; + SDL_uikitviewcontroller *viewcontroller = data.viewcontroller; + if (@available(iOS 14.0, *)) { + [viewcontroller setNeedsUpdateOfPrefersPointerLocked]; + } + } +#endif /* defined(__IPHONE_14_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_14_0 */ +#endif /* !TARGET_OS_TV */ +} + +void UIKit_DestroyWindow(_THIS, SDL_Window * window) { @autoreleasepool { if (window->driverdata != NULL) { - SDL_WindowData *data = (SDL_WindowData *) CFBridgingRelease(window->driverdata); + SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata; NSArray *views = nil; [data.viewcontroller stopAnimation]; @@ -345,13 +346,32 @@ UIKit_DestroyWindow(_THIS, SDL_Window * window) * SDL window. */ data.uiwindow.rootViewController = nil; data.uiwindow.hidden = YES; + + CFRelease(window->driverdata); + window->driverdata = NULL; } } - window->driverdata = NULL; } -SDL_bool -UIKit_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info) +void UIKit_GetWindowSizeInPixels(_THIS, SDL_Window * window, int *w, int *h) +{ @autoreleasepool +{ + SDL_WindowData *windata = (__bridge SDL_WindowData *) window->driverdata; + UIView *view = windata.viewcontroller.view; + CGSize size = view.bounds.size; + CGFloat scale = 1.0; + + if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) { + scale = windata.uiwindow.screen.nativeScale; + } + + /* Integer truncation of fractional values matches SDL_uikitmetalview and + * SDL_uikitopenglview. */ + *w = size.width * scale; + *h = size.height * scale; +}} + +SDL_bool UIKit_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info) { @autoreleasepool { SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata; @@ -364,7 +384,7 @@ UIKit_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info) /* These struct members were added in SDL 2.0.4. */ if (versionnum >= SDL_VERSIONNUM(2,0,4)) { -#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 +#if defined(SDL_VIDEO_OPENGL_ES) || defined(SDL_VIDEO_OPENGL_ES2) if ([data.viewcontroller.view isKindOfClass:[SDL_uikitopenglview class]]) { SDL_uikitopenglview *glview = (SDL_uikitopenglview *)data.viewcontroller.view; info->info.uikit.framebuffer = glview.drawableFramebuffer; @@ -382,16 +402,15 @@ UIKit_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info) return SDL_TRUE; } else { - SDL_SetError("Application not compiled with SDL %d.%d", - SDL_MAJOR_VERSION, SDL_MINOR_VERSION); + SDL_SetError("Application not compiled with SDL %d", + SDL_MAJOR_VERSION); return SDL_FALSE; } } } #if !TARGET_OS_TV -NSUInteger -UIKit_GetSupportedOrientations(SDL_Window * window) +NSUInteger UIKit_GetSupportedOrientations(SDL_Window * window) { const char *hint = SDL_GetHint(SDL_HINT_ORIENTATIONS); NSUInteger validOrientations = UIInterfaceOrientationMaskAll; @@ -405,7 +424,7 @@ UIKit_GetSupportedOrientations(SDL_Window * window) * us, we get the orientations from Info.plist via UIApplication. */ if ([app.delegate respondsToSelector:@selector(application:supportedInterfaceOrientationsForWindow:)]) { validOrientations = [app.delegate application:app supportedInterfaceOrientationsForWindow:data.uiwindow]; - } else if ([app respondsToSelector:@selector(supportedInterfaceOrientationsForWindow:)]) { + } else { validOrientations = [app supportedInterfaceOrientationsForWindow:data.uiwindow]; } @@ -432,10 +451,10 @@ UIKit_GetSupportedOrientations(SDL_Window * window) } if (orientationMask == 0) { - if (window->w >= window->h) { + if (window->windowed.w >= window->windowed.h) { orientationMask |= UIInterfaceOrientationMaskLandscape; } - if (window->h >= window->w) { + if (window->windowed.h >= window->windowed.w) { orientationMask |= (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown); } } @@ -457,8 +476,7 @@ UIKit_GetSupportedOrientations(SDL_Window * window) } #endif /* !TARGET_OS_TV */ -int -SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (*callback)(void*), void *callbackParam) +int SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (*callback)(void*), void *callbackParam) { if (!window || !window->driverdata) { return SDL_SetError("Invalid window"); diff --git a/SDL2-2.30.5/src/video/vita/SDL_vitaframebuffer.c b/SDL2-2.30.5/src/video/vita/SDL_vitaframebuffer.c new file mode 100644 index 0000000..56069b2 --- /dev/null +++ b/SDL2-2.30.5/src/video/vita/SDL_vitaframebuffer.c @@ -0,0 +1,118 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_VITA + +#include "SDL_vitavideo.h" + +#include + +#define SCREEN_W 960 +#define SCREEN_H 544 +#define ALIGN(x, a) (((x) + ((a)-1)) & ~((a)-1)) +#define DISPLAY_PIXEL_FORMAT SCE_DISPLAY_PIXELFORMAT_A8B8G8R8 + +void *vita_gpu_alloc(unsigned int type, unsigned int size, SceUID *uid) +{ + void *mem; + + if (type == SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW) { + size = ALIGN(size, 256 * 1024); + } else { + size = ALIGN(size, 4 * 1024); + } + + *uid = sceKernelAllocMemBlock("gpu_mem", type, size, NULL); + + if (*uid < 0) { + return NULL; + } + + if (sceKernelGetMemBlockBase(*uid, &mem) < 0) { + return NULL; + } + + return mem; +} + +void vita_gpu_free(SceUID uid) +{ + void *mem = NULL; + if (sceKernelGetMemBlockBase(uid, &mem) < 0) { + return; + } + sceKernelFreeMemBlock(uid); +} + +int VITA_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format, void **pixels, int *pitch) +{ + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + SceDisplayFrameBuf framebuf; + + *format = SDL_PIXELFORMAT_ABGR8888; + *pitch = SCREEN_W * 4; + + data->buffer = vita_gpu_alloc( + SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, + 4 * SCREEN_W * SCREEN_H, + &data->buffer_uid); + + // SDL_memset the buffer to black + SDL_memset(data->buffer, 0x0, SCREEN_W * SCREEN_H * 4); + + SDL_memset(&framebuf, 0x00, sizeof(SceDisplayFrameBuf)); + framebuf.size = sizeof(SceDisplayFrameBuf); + framebuf.base = data->buffer; + framebuf.pitch = SCREEN_W; + framebuf.pixelformat = DISPLAY_PIXEL_FORMAT; + framebuf.width = SCREEN_W; + framebuf.height = SCREEN_H; + sceDisplaySetFrameBuf(&framebuf, SCE_DISPLAY_SETBUF_NEXTFRAME); + + *pixels = data->buffer; + + return 0; +} + +int VITA_UpdateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_Rect *rects, int numrects) +{ + // do nothing + return 0; +} + +void VITA_DestroyWindowFramebuffer(_THIS, SDL_Window *window) +{ + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + + if (!data) { + /* The window wasn't fully initialized */ + return; + } + + vita_gpu_free(data->buffer_uid); + data->buffer = NULL; + return; +} + +#endif /* SDL_VIDEO_DRIVER_VITA */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/windows/SDL_windowsframebuffer.h b/SDL2-2.30.5/src/video/vita/SDL_vitaframebuffer.h similarity index 73% rename from SDL2-2.0.12/src/video/windows/SDL_windowsframebuffer.h rename to SDL2-2.30.5/src/video/vita/SDL_vitaframebuffer.h index 9a9e243..495d51b 100644 --- a/SDL2-2.0.12/src/video/windows/SDL_windowsframebuffer.h +++ b/SDL2-2.30.5/src/video/vita/SDL_vitaframebuffer.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,8 +20,8 @@ */ #include "../../SDL_internal.h" -extern int WIN_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch); -extern int WIN_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects); -extern void WIN_DestroyWindowFramebuffer(_THIS, SDL_Window * window); +extern int VITA_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format, void **pixels, int *pitch); +extern int VITA_UpdateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_Rect *rects, int numrects); +extern void VITA_DestroyWindowFramebuffer(_THIS, SDL_Window *window); /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/vita/SDL_vitagl_pvr.c b/SDL2-2.30.5/src/video/vita/SDL_vitagl_pvr.c new file mode 100644 index 0000000..5e148f9 --- /dev/null +++ b/SDL2-2.30.5/src/video/vita/SDL_vitagl_pvr.c @@ -0,0 +1,126 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#if defined(SDL_VIDEO_DRIVER_VITA) && defined(SDL_VIDEO_VITA_PVR) && defined(SDL_VIDEO_VITA_PVR_OGL) +#include +#include +#include +#include +#include + +#include "SDL_error.h" +#include "SDL_log.h" +#include "SDL_vitavideo.h" +#include "../SDL_egl_c.h" +#include "SDL_vitagl_pvr_c.h" + +#define MAX_PATH 256 // vita limits are somehow wrong + +/* Defaults */ +int FB_WIDTH = 960; +int FB_HEIGHT = 544; + +void getFBSize(int *width, int *height) +{ + *width = FB_WIDTH; + *height = FB_HEIGHT; +} + +int VITA_GL_LoadLibrary(_THIS, const char *path) +{ + PVRSRV_PSP2_APPHINT hint; + char *override = SDL_getenv("VITA_MODULE_PATH"); + char *skip_init = SDL_getenv("VITA_PVR_SKIP_INIT"); + char *default_path = "app0:module"; + char target_path[MAX_PATH]; + + if (!skip_init) { // we don't care about actual value + if (override) { + default_path = override; + } + + sceKernelLoadStartModule("vs0:sys/external/libfios2.suprx", 0, NULL, 0, NULL, NULL); + sceKernelLoadStartModule("vs0:sys/external/libc.suprx", 0, NULL, 0, NULL, NULL); + + SDL_snprintf(target_path, MAX_PATH, "%s/%s", default_path, "libGL.suprx"); + sceKernelLoadStartModule(target_path, 0, NULL, 0, NULL, NULL); + + SDL_snprintf(target_path, MAX_PATH, "%s/%s", default_path, "libgpu_es4_ext.suprx"); + sceKernelLoadStartModule(target_path, 0, NULL, 0, NULL, NULL); + + SDL_snprintf(target_path, MAX_PATH, "%s/%s", default_path, "libIMGEGL.suprx"); + sceKernelLoadStartModule(target_path, 0, NULL, 0, NULL, NULL); + + PVRSRVInitializeAppHint(&hint); + + SDL_snprintf(hint.szGLES1, MAX_PATH, "%s/%s", default_path, "libGLESv1_CM.suprx"); + SDL_snprintf(hint.szGLES2, MAX_PATH, "%s/%s", default_path, "libGLESv2.suprx"); + SDL_snprintf(hint.szWindowSystem, MAX_PATH, "%s/%s", default_path, "libpvrPSP2_WSEGL.suprx"); + + PVRSRVCreateVirtualAppHint(&hint); + } + + return SDL_EGL_LoadLibrary(_this, path, (NativeDisplayType)0, 0); +} + +SDL_GLContext VITA_GL_CreateContext(_THIS, SDL_Window *window) +{ + char gl_version[3]; + SDL_GLContext context = NULL; + int temp_major = _this->gl_config.major_version; + int temp_minor = _this->gl_config.minor_version; + int temp_profile = _this->gl_config.profile_mask; + + /* Set version to 2.0 and PROFILE to ES */ + _this->gl_config.major_version = 2; + _this->gl_config.minor_version = 0; + _this->gl_config.profile_mask = SDL_GL_CONTEXT_PROFILE_ES; + + context = SDL_EGL_CreateContext(_this, ((SDL_WindowData *)window->driverdata)->egl_surface); + + if (context != NULL) { + FB_WIDTH = window->w; + FB_HEIGHT = window->h; + set_getprocaddress((void *(*)(const char *))eglGetProcAddress); + set_getmainfbsize(getFBSize); + SDL_snprintf(gl_version, 3, "%d%d", temp_major, temp_minor); + gl4es_setenv("LIBGL_NOTEXRECT", "1", 1); /* Currently broken in driver */ + gl4es_setenv("LIBGL_GL", gl_version, 1); + initialize_gl4es(); + } + + /* Restore gl_config */ + _this->gl_config.major_version = temp_major; + _this->gl_config.minor_version = temp_minor; + _this->gl_config.profile_mask = temp_profile; + + return context; +} + +void *VITA_GL_GetProcAddress(_THIS, const char *proc) +{ + return gl4es_GetProcAddress(proc); +} + +#endif /* SDL_VIDEO_DRIVER_VITA && SDL_VIDEO_VITA_PVR */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/vita/SDL_vitagl_pvr_c.h b/SDL2-2.30.5/src/video/vita/SDL_vitagl_pvr_c.h new file mode 100644 index 0000000..fee3d30 --- /dev/null +++ b/SDL2-2.30.5/src/video/vita/SDL_vitagl_pvr_c.h @@ -0,0 +1,33 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#ifndef SDL_vitagl_pvr_c_h_ +#define SDL_vitagl_pvr_c_h_ + +#include "SDL_vitavideo.h" + +extern SDL_GLContext VITA_GL_CreateContext(_THIS, SDL_Window *window); +extern int VITA_GL_LoadLibrary(_THIS, const char *path); +extern void *VITA_GL_GetProcAddress(_THIS, const char *proc); + +#endif /* SDL_vitagl_pvr_c_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/vita/SDL_vitagles.c b/SDL2-2.30.5/src/video/vita/SDL_vitagles.c new file mode 100644 index 0000000..1944112 --- /dev/null +++ b/SDL2-2.30.5/src/video/vita/SDL_vitagles.c @@ -0,0 +1,222 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#if defined(SDL_VIDEO_DRIVER_VITA) && defined(SDL_VIDEO_VITA_PIB) +#include +#include + +#include "SDL_error.h" +#include "SDL_log.h" +#include "SDL_vitavideo.h" +#include "SDL_vitagles_c.h" + +/*****************************************************************************/ +/* SDL OpenGL/OpenGL ES functions */ +/*****************************************************************************/ +#define EGLCHK(stmt) \ + do { \ + EGLint err; \ + \ + stmt; \ + err = eglGetError(); \ + if (err != EGL_SUCCESS) { \ + SDL_SetError("EGL error %d", err); \ + return 0; \ + } \ + } while (0) + +void VITA_GLES_KeyboardCallback(ScePigletPreSwapData *data) +{ + SceCommonDialogUpdateParam commonDialogParam; + SDL_zero(commonDialogParam); + commonDialogParam.renderTarget.colorFormat = data->colorFormat; + commonDialogParam.renderTarget.surfaceType = data->surfaceType; + commonDialogParam.renderTarget.colorSurfaceData = data->colorSurfaceData; + commonDialogParam.renderTarget.depthSurfaceData = data->depthSurfaceData; + commonDialogParam.renderTarget.width = data->width; + commonDialogParam.renderTarget.height = data->height; + commonDialogParam.renderTarget.strideInPixels = data->strideInPixels; + commonDialogParam.displaySyncObject = data->displaySyncObject; + + sceCommonDialogUpdate(&commonDialogParam); +} + +int VITA_GLES_LoadLibrary(_THIS, const char *path) +{ + pibInit(PIB_SHACCCG | PIB_GET_PROC_ADDR_CORE); + return 0; +} + +void *VITA_GLES_GetProcAddress(_THIS, const char *proc) +{ + return eglGetProcAddress(proc); +} + +void VITA_GLES_UnloadLibrary(_THIS) +{ + eglTerminate(_this->gl_data->display); +} + +static EGLint width = 960; +static EGLint height = 544; + +SDL_GLContext VITA_GLES_CreateContext(_THIS, SDL_Window *window) +{ + + SDL_WindowData *wdata = (SDL_WindowData *)window->driverdata; + + EGLint attribs[32]; + EGLDisplay display; + EGLContext context; + EGLSurface surface; + EGLConfig config; + EGLint num_configs; + PFNEGLPIGLETVITASETPRESWAPCALLBACKSCEPROC preSwapCallback; + int i; + + const EGLint contextAttribs[] = { + EGL_CONTEXT_CLIENT_VERSION, 2, + EGL_NONE + }; + + EGLCHK(display = eglGetDisplay(0)); + + EGLCHK(eglInitialize(display, NULL, NULL)); + wdata->uses_gles = SDL_TRUE; + window->flags |= SDL_WINDOW_FULLSCREEN; + + EGLCHK(eglBindAPI(EGL_OPENGL_ES_API)); + + i = 0; + attribs[i++] = EGL_RED_SIZE; + attribs[i++] = 8; + attribs[i++] = EGL_GREEN_SIZE; + attribs[i++] = 8; + attribs[i++] = EGL_BLUE_SIZE; + attribs[i++] = 8; + attribs[i++] = EGL_DEPTH_SIZE; + attribs[i++] = 0; + attribs[i++] = EGL_ALPHA_SIZE; + attribs[i++] = 8; + attribs[i++] = EGL_STENCIL_SIZE; + attribs[i++] = 0; + + attribs[i++] = EGL_SURFACE_TYPE; + attribs[i++] = 5; + + attribs[i++] = EGL_RENDERABLE_TYPE; + attribs[i++] = EGL_OPENGL_ES2_BIT; + + attribs[i++] = EGL_CONFORMANT; + attribs[i++] = EGL_OPENGL_ES2_BIT; + + attribs[i++] = EGL_NONE; + + EGLCHK(eglChooseConfig(display, attribs, &config, 1, &num_configs)); + + if (num_configs == 0) { + SDL_SetError("No valid EGL configs for requested mode"); + return 0; + } + + EGLCHK(surface = eglCreateWindowSurface(display, config, VITA_WINDOW_960X544, NULL)); + + EGLCHK(context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs)); + + EGLCHK(eglMakeCurrent(display, surface, surface, context)); + + EGLCHK(eglQuerySurface(display, surface, EGL_WIDTH, &width)); + EGLCHK(eglQuerySurface(display, surface, EGL_HEIGHT, &height)); + + _this->gl_data->display = display; + _this->gl_data->context = context; + _this->gl_data->surface = surface; + + preSwapCallback = (PFNEGLPIGLETVITASETPRESWAPCALLBACKSCEPROC)eglGetProcAddress("eglPigletVitaSetPreSwapCallbackSCE"); + preSwapCallback(VITA_GLES_KeyboardCallback); + + return context; +} + +int VITA_GLES_MakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context) +{ + if (!eglMakeCurrent(_this->gl_data->display, _this->gl_data->surface, + _this->gl_data->surface, _this->gl_data->context)) { + return SDL_SetError("Unable to make EGL context current"); + } + return 0; +} + +int VITA_GLES_SetSwapInterval(_THIS, int interval) +{ + EGLBoolean status; + status = eglSwapInterval(_this->gl_data->display, interval); + if (status == EGL_TRUE) { + /* Return success to upper level */ + _this->gl_data->swapinterval = interval; + return 0; + } + /* Failed to set swap interval */ + return SDL_SetError("Unable to set the EGL swap interval"); +} + +int VITA_GLES_GetSwapInterval(_THIS) +{ + return _this->gl_data->swapinterval; +} + +int VITA_GLES_SwapWindow(_THIS, SDL_Window *window) +{ + if (!eglSwapBuffers(_this->gl_data->display, _this->gl_data->surface)) { + return SDL_SetError("eglSwapBuffers() failed"); + } + return 0; +} + +void VITA_GLES_DeleteContext(_THIS, SDL_GLContext context) +{ + SDL_VideoData *phdata = (SDL_VideoData *)_this->driverdata; + EGLBoolean status; + + if (phdata->egl_initialized != SDL_TRUE) { + SDL_SetError("VITA: GLES initialization failed, no OpenGL ES support"); + return; + } + + /* Check if OpenGL ES connection has been initialized */ + if (_this->gl_data->display != EGL_NO_DISPLAY) { + if (context != EGL_NO_CONTEXT) { + status = eglDestroyContext(_this->gl_data->display, context); + if (status != EGL_TRUE) { + /* Error during OpenGL ES context destroying */ + SDL_SetError("VITA: OpenGL ES context destroy error"); + return; + } + } + } + + return; +} + +#endif /* SDL_VIDEO_DRIVER_VITA */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/vita/SDL_vitagles_c.h b/SDL2-2.30.5/src/video/vita/SDL_vitagles_c.h new file mode 100644 index 0000000..6dcc651 --- /dev/null +++ b/SDL2-2.30.5/src/video/vita/SDL_vitagles_c.h @@ -0,0 +1,55 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#ifndef SDL_vitagles_c_h_ +#define SDL_vitagles_c_h_ + +#include +#include +#include +#include +#include + +#include "SDL_vitavideo.h" + +typedef struct SDL_GLDriverData +{ + EGLDisplay display; + EGLContext context; + EGLSurface surface; + uint32_t swapinterval; +} SDL_GLDriverData; + +extern void *VITA_GLES_GetProcAddress(_THIS, const char *proc); +extern int VITA_GLES_MakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context); +extern void VITA_GLES_SwapBuffers(_THIS); + +extern int VITA_GLES_SwapWindow(_THIS, SDL_Window *window); +extern SDL_GLContext VITA_GLES_CreateContext(_THIS, SDL_Window *window); + +extern int VITA_GLES_LoadLibrary(_THIS, const char *path); +extern void VITA_GLES_UnloadLibrary(_THIS); +extern int VITA_GLES_SetSwapInterval(_THIS, int interval); +extern int VITA_GLES_GetSwapInterval(_THIS); + +#endif /* SDL_vitagles_c_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/vita/SDL_vitagles_pvr.c b/SDL2-2.30.5/src/video/vita/SDL_vitagles_pvr.c new file mode 100644 index 0000000..cf917af --- /dev/null +++ b/SDL2-2.30.5/src/video/vita/SDL_vitagles_pvr.c @@ -0,0 +1,97 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#if defined(SDL_VIDEO_DRIVER_VITA) && defined(SDL_VIDEO_VITA_PVR) +#include +#include +#include +#include + +#include "SDL_error.h" +#include "SDL_log.h" +#include "SDL_vitavideo.h" +#include "../SDL_egl_c.h" +#include "SDL_vitagles_pvr_c.h" + +#define MAX_PATH 256 // vita limits are somehow wrong + +int VITA_GLES_LoadLibrary(_THIS, const char *path) +{ + PVRSRV_PSP2_APPHINT hint; + char *override = SDL_getenv("VITA_MODULE_PATH"); + char *skip_init = SDL_getenv("VITA_PVR_SKIP_INIT"); + char *default_path = "app0:module"; + char target_path[MAX_PATH]; + + if (!skip_init) { // we don't care about actual value + + if (override) { + default_path = override; + } + + sceKernelLoadStartModule("vs0:sys/external/libfios2.suprx", 0, NULL, 0, NULL, NULL); + sceKernelLoadStartModule("vs0:sys/external/libc.suprx", 0, NULL, 0, NULL, NULL); + + SDL_snprintf(target_path, MAX_PATH, "%s/%s", default_path, "libgpu_es4_ext.suprx"); + sceKernelLoadStartModule(target_path, 0, NULL, 0, NULL, NULL); + + SDL_snprintf(target_path, MAX_PATH, "%s/%s", default_path, "libIMGEGL.suprx"); + sceKernelLoadStartModule(target_path, 0, NULL, 0, NULL, NULL); + + PVRSRVInitializeAppHint(&hint); + + SDL_snprintf(hint.szGLES1, MAX_PATH, "%s/%s", default_path, "libGLESv1_CM.suprx"); + SDL_snprintf(hint.szGLES2, MAX_PATH, "%s/%s", default_path, "libGLESv2.suprx"); + SDL_snprintf(hint.szWindowSystem, MAX_PATH, "%s/%s", default_path, "libpvrPSP2_WSEGL.suprx"); + + PVRSRVCreateVirtualAppHint(&hint); + } + + return SDL_EGL_LoadLibrary(_this, path, (NativeDisplayType)0, 0); +} + +SDL_GLContext VITA_GLES_CreateContext(_THIS, SDL_Window *window) +{ + return SDL_EGL_CreateContext(_this, ((SDL_WindowData *)window->driverdata)->egl_surface); +} + +int VITA_GLES_MakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context) +{ + if (window && context) { + return SDL_EGL_MakeCurrent(_this, ((SDL_WindowData *)window->driverdata)->egl_surface, context); + } else { + return SDL_EGL_MakeCurrent(_this, NULL, NULL); + } +} + +int VITA_GLES_SwapWindow(_THIS, SDL_Window *window) +{ + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + if (videodata->ime_active) { + sceImeUpdate(); + } + return SDL_EGL_SwapBuffers(_this, ((SDL_WindowData *)window->driverdata)->egl_surface); +} + +#endif /* SDL_VIDEO_DRIVER_VITA && SDL_VIDEO_VITA_PVR */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/vita/SDL_vitagles_pvr_c.h b/SDL2-2.30.5/src/video/vita/SDL_vitagles_pvr_c.h new file mode 100644 index 0000000..2815057 --- /dev/null +++ b/SDL2-2.30.5/src/video/vita/SDL_vitagles_pvr_c.h @@ -0,0 +1,34 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#ifndef SDL_vitagles_pvr_c_h_ +#define SDL_vitagles_pvr_c_h_ + +#include "SDL_vitavideo.h" + +extern int VITA_GLES_MakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context); +extern int VITA_GLES_SwapWindow(_THIS, SDL_Window *window); +extern SDL_GLContext VITA_GLES_CreateContext(_THIS, SDL_Window *window); +extern int VITA_GLES_LoadLibrary(_THIS, const char *path); + +#endif /* SDL_vitagles_pvr_c_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/vita/SDL_vitakeyboard.c b/SDL2-2.30.5/src/video/vita/SDL_vitakeyboard.c new file mode 100644 index 0000000..038e0ff --- /dev/null +++ b/SDL2-2.30.5/src/video/vita/SDL_vitakeyboard.c @@ -0,0 +1,189 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_VITA + +#include +#include +#include + +#include "SDL_events.h" +#include "SDL_log.h" +#include "SDL_vitavideo.h" +#include "SDL_vitakeyboard.h" +#include "../../events/SDL_keyboard_c.h" + +SceHidKeyboardReport k_reports[SCE_HID_MAX_REPORT]; +int keyboard_hid_handle = 0; +Uint8 prev_keys[6] = { 0 }; +Uint8 prev_modifiers = 0; +Uint8 locks = 0; +Uint8 lock_key_down = 0; + +void VITA_InitKeyboard(void) +{ +#if defined(SDL_VIDEO_VITA_PVR) + sceSysmoduleLoadModule(SCE_SYSMODULE_IME); /** For PVR OSK Support **/ +#endif + sceHidKeyboardEnumerate(&keyboard_hid_handle, 1); +} + +void VITA_PollKeyboard(void) +{ + // We skip polling keyboard if no window is created + if (!Vita_Window) { + return; + } + + if (keyboard_hid_handle > 0) { + int numReports = sceHidKeyboardRead(keyboard_hid_handle, (SceHidKeyboardReport **)&k_reports, SCE_HID_MAX_REPORT); + + if (numReports < 0) { + keyboard_hid_handle = 0; + } else if (numReports) { + // Numlock and Capslock state changes only on a SDL_PRESSED event + // The k_report only reports the state of the LED + if (k_reports[numReports - 1].modifiers[1] & 0x1) { + if (!(locks & 0x1)) { + SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_NUMLOCKCLEAR); + locks |= 0x1; + } + } else { + if (locks & 0x1) { + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_NUMLOCKCLEAR); + SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_NUMLOCKCLEAR); + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_NUMLOCKCLEAR); + locks &= ~0x1; + } + } + + if (k_reports[numReports - 1].modifiers[1] & 0x2) { + if (!(locks & 0x2)) { + SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_CAPSLOCK); + locks |= 0x2; + } + } else { + if (locks & 0x2) { + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_CAPSLOCK); + SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_CAPSLOCK); + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_CAPSLOCK); + locks &= ~0x2; + } + } + + if (k_reports[numReports - 1].modifiers[1] & 0x4) { + if (!(locks & 0x4)) { + SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_SCROLLLOCK); + locks |= 0x4; + } + } else { + if (locks & 0x4) { + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_SCROLLLOCK); + locks &= ~0x4; + } + } + + { + Uint8 changed_modifiers = k_reports[numReports - 1].modifiers[0] ^ prev_modifiers; + + if (changed_modifiers & 0x01) { + if (prev_modifiers & 0x01) { + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LCTRL); + } else { + SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_LCTRL); + } + } + if (changed_modifiers & 0x02) { + if (prev_modifiers & 0x02) { + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LSHIFT); + } else { + SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_LSHIFT); + } + } + if (changed_modifiers & 0x04) { + if (prev_modifiers & 0x04) { + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LALT); + } else { + SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_LALT); + } + } + if (changed_modifiers & 0x08) { + if (prev_modifiers & 0x08) { + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LGUI); + } else { + SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_LGUI); + } + } + if (changed_modifiers & 0x10) { + if (prev_modifiers & 0x10) { + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_RCTRL); + } else { + SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_RCTRL); + } + } + if (changed_modifiers & 0x20) { + if (prev_modifiers & 0x20) { + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_RSHIFT); + } else { + SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_RSHIFT); + } + } + if (changed_modifiers & 0x40) { + if (prev_modifiers & 0x40) { + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_RALT); + } else { + SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_RALT); + } + } + if (changed_modifiers & 0x80) { + if (prev_modifiers & 0x80) { + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_RGUI); + } else { + SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_RGUI); + } + } + } + + prev_modifiers = k_reports[numReports - 1].modifiers[0]; + + for (int i = 0; i < 6; i++) { + + int keyCode = k_reports[numReports - 1].keycodes[i]; + + if (keyCode != prev_keys[i]) { + + if (prev_keys[i]) { + SDL_SendKeyboardKey(SDL_RELEASED, prev_keys[i]); + } + if (keyCode) { + SDL_SendKeyboardKey(SDL_PRESSED, keyCode); + } + prev_keys[i] = keyCode; + } + } + } + } +} + +#endif /* SDL_VIDEO_DRIVER_VITA */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/vita/SDL_vitakeyboard.h b/SDL2-2.30.5/src/video/vita/SDL_vitakeyboard.h new file mode 100644 index 0000000..3ea6465 --- /dev/null +++ b/SDL2-2.30.5/src/video/vita/SDL_vitakeyboard.h @@ -0,0 +1,33 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#ifndef _SDL_vitakeyboard_h +#define _SDL_vitakeyboard_h + +#include "../../SDL_internal.h" + +/* Keyboard functions */ +extern void VITA_InitKeyboard(void); +extern void VITA_PollKeyboard(void); + +#endif /* _SDL_vitakeyboard_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/vita/SDL_vitamessagebox.c b/SDL2-2.30.5/src/video/vita/SDL_vitamessagebox.c new file mode 100644 index 0000000..6811748 --- /dev/null +++ b/SDL2-2.30.5/src/video/vita/SDL_vitamessagebox.c @@ -0,0 +1,127 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_VITA + +#include "SDL_vitavideo.h" +#include "SDL_vitamessagebox.h" +#include + +#if SDL_VIDEO_RENDER_VITA_GXM +#include "../../render/vitagxm/SDL_render_vita_gxm_tools.h" +#endif /* SDL_VIDEO_RENDER_VITA_GXM */ + +int VITA_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) +{ +#if SDL_VIDEO_RENDER_VITA_GXM + SceMsgDialogParam param; + SceMsgDialogUserMessageParam msgParam; + SceMsgDialogButtonsParam buttonParam; + SceDisplayFrameBuf dispparam; + char message[512]; + + SceMsgDialogResult dialog_result; + SceCommonDialogErrorCode init_result; + SDL_bool setup_minimal_gxm = SDL_FALSE; + + if (messageboxdata->numbuttons > 3) { + return -1; + } + + SDL_zero(param); + sceMsgDialogParamInit(¶m); + param.mode = SCE_MSG_DIALOG_MODE_USER_MSG; + + SDL_zero(msgParam); + SDL_snprintf(message, sizeof(message), "%s\r\n\r\n%s", messageboxdata->title, messageboxdata->message); + + msgParam.msg = (const SceChar8 *)message; + SDL_zero(buttonParam); + + if (messageboxdata->numbuttons == 3) { + msgParam.buttonType = SCE_MSG_DIALOG_BUTTON_TYPE_3BUTTONS; + msgParam.buttonParam = &buttonParam; + buttonParam.msg1 = messageboxdata->buttons[0].text; + buttonParam.msg2 = messageboxdata->buttons[1].text; + buttonParam.msg3 = messageboxdata->buttons[2].text; + } else if (messageboxdata->numbuttons == 2) { + msgParam.buttonType = SCE_MSG_DIALOG_BUTTON_TYPE_YESNO; + } else if (messageboxdata->numbuttons == 1) { + msgParam.buttonType = SCE_MSG_DIALOG_BUTTON_TYPE_OK; + } + param.userMsgParam = &msgParam; + + dispparam.size = sizeof(dispparam); + + init_result = sceMsgDialogInit(¶m); + + // Setup display if it hasn't been initialized before + if (init_result == SCE_COMMON_DIALOG_ERROR_GXM_IS_UNINITIALIZED) { + gxm_minimal_init_for_common_dialog(); + init_result = sceMsgDialogInit(¶m); + setup_minimal_gxm = SDL_TRUE; + } + + gxm_init_for_common_dialog(); + + if (init_result >= 0) { + while (sceMsgDialogGetStatus() == SCE_COMMON_DIALOG_STATUS_RUNNING) { + gxm_swap_for_common_dialog(); + } + SDL_zero(dialog_result); + sceMsgDialogGetResult(&dialog_result); + + if (dialog_result.buttonId == SCE_MSG_DIALOG_BUTTON_ID_BUTTON1) { + *buttonid = messageboxdata->buttons[0].buttonid; + } else if (dialog_result.buttonId == SCE_MSG_DIALOG_BUTTON_ID_BUTTON2) { + *buttonid = messageboxdata->buttons[1].buttonid; + } else if (dialog_result.buttonId == SCE_MSG_DIALOG_BUTTON_ID_BUTTON3) { + *buttonid = messageboxdata->buttons[2].buttonid; + } else if (dialog_result.buttonId == SCE_MSG_DIALOG_BUTTON_ID_YES) { + *buttonid = messageboxdata->buttons[0].buttonid; + } else if (dialog_result.buttonId == SCE_MSG_DIALOG_BUTTON_ID_NO) { + *buttonid = messageboxdata->buttons[1].buttonid; + } else if (dialog_result.buttonId == SCE_MSG_DIALOG_BUTTON_ID_OK) { + *buttonid = messageboxdata->buttons[0].buttonid; + } + sceMsgDialogTerm(); + } else { + return -1; + } + + gxm_term_for_common_dialog(); + + if (setup_minimal_gxm) { + gxm_minimal_term_for_common_dialog(); + } + + return 0; +#else + (void)messageboxdata; + (void)buttonid; + return -1; +#endif +} + +#endif /* SDL_VIDEO_DRIVER_VITA */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/vita/SDL_vitamessagebox.h b/SDL2-2.30.5/src/video/vita/SDL_vitamessagebox.h new file mode 100644 index 0000000..15aeb6d --- /dev/null +++ b/SDL2-2.30.5/src/video/vita/SDL_vitamessagebox.h @@ -0,0 +1,33 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#ifndef SDL_vitamessagebox_h_ +#define SDL_vitamessagebox_h_ + +#ifdef SDL_VIDEO_DRIVER_VITA + +extern int VITA_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid); + +#endif /* SDL_VIDEO_DRIVER_VITA */ + +#endif /* SDL_vitamessagebox_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/vita/SDL_vitamouse.c b/SDL2-2.30.5/src/video/vita/SDL_vitamouse.c new file mode 100644 index 0000000..47fa095 --- /dev/null +++ b/SDL2-2.30.5/src/video/vita/SDL_vitamouse.c @@ -0,0 +1,89 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_VITA + +#include +#include +#include + +#include "SDL_events.h" +#include "SDL_log.h" +#include "SDL_mouse.h" +#include "SDL_vitavideo.h" +#include "SDL_vitamouse_c.h" +#include "../../events/SDL_mouse_c.h" + +SceHidMouseReport m_reports[SCE_HID_MAX_REPORT]; +int mouse_hid_handle = 0; +Uint8 prev_buttons = 0; + +void VITA_InitMouse(void) +{ + sceHidMouseEnumerate(&mouse_hid_handle, 1); +} + +void VITA_PollMouse(void) +{ + // We skip polling mouse if no window is created + if (!Vita_Window) { + return; + } + + if (mouse_hid_handle > 0) { + int numReports = sceHidMouseRead(mouse_hid_handle, (SceHidMouseReport **)&m_reports, SCE_HID_MAX_REPORT); + if (numReports > 0) { + for (int i = 0; i <= numReports - 1; i++) { + Uint8 changed_buttons = m_reports[i].buttons ^ prev_buttons; + + if (changed_buttons & 0x1) { + if (prev_buttons & 0x1) + SDL_SendMouseButton(Vita_Window, 0, SDL_RELEASED, SDL_BUTTON_LEFT); + else + SDL_SendMouseButton(Vita_Window, 0, SDL_PRESSED, SDL_BUTTON_LEFT); + } + if (changed_buttons & 0x2) { + if (prev_buttons & 0x2) + SDL_SendMouseButton(Vita_Window, 0, SDL_RELEASED, SDL_BUTTON_RIGHT); + else + SDL_SendMouseButton(Vita_Window, 0, SDL_PRESSED, SDL_BUTTON_RIGHT); + } + if (changed_buttons & 0x4) { + if (prev_buttons & 0x4) + SDL_SendMouseButton(Vita_Window, 0, SDL_RELEASED, SDL_BUTTON_MIDDLE); + else + SDL_SendMouseButton(Vita_Window, 0, SDL_PRESSED, SDL_BUTTON_MIDDLE); + } + + prev_buttons = m_reports[i].buttons; + + if (m_reports[i].rel_x || m_reports[i].rel_y) { + SDL_SendMouseMotion(Vita_Window, 0, 1, m_reports[i].rel_x, m_reports[i].rel_y); + } + } + } + } +} + +#endif /* SDL_VIDEO_DRIVER_VITA */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/vita/SDL_vitamouse_c.h b/SDL2-2.30.5/src/video/vita/SDL_vitamouse_c.h new file mode 100644 index 0000000..281a611 --- /dev/null +++ b/SDL2-2.30.5/src/video/vita/SDL_vitamouse_c.h @@ -0,0 +1,33 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#ifndef _SDL_vitamouse_h +#define _SDL_vitamouse_h + +#include "../../SDL_internal.h" + +/* mouse functions */ +extern void VITA_InitMouse(void); +extern void VITA_PollMouse(void); + +#endif /* _SDL_vitamouse_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/vita/SDL_vitatouch.c b/SDL2-2.30.5/src/video/vita/SDL_vitatouch.c new file mode 100644 index 0000000..07cbede --- /dev/null +++ b/SDL2-2.30.5/src/video/vita/SDL_vitatouch.c @@ -0,0 +1,193 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_VITA + +#include +#include + +#include "SDL_events.h" +#include "SDL_log.h" +#include "SDL_vitavideo.h" +#include "SDL_vitatouch.h" +#include "../../events/SDL_mouse_c.h" +#include "../../events/SDL_touch_c.h" + +SceTouchData touch_old[SCE_TOUCH_PORT_MAX_NUM]; +SceTouchData touch[SCE_TOUCH_PORT_MAX_NUM]; + +SDL_FRect area_info[SCE_TOUCH_PORT_MAX_NUM]; + +struct +{ + float min; + float range; +} force_info[SCE_TOUCH_PORT_MAX_NUM]; + +char *disableFrontPoll = NULL; +char *disableBackPoll = NULL; + +void VITA_InitTouch(void) +{ + disableFrontPoll = SDL_getenv("VITA_DISABLE_TOUCH_FRONT"); + disableBackPoll = SDL_getenv("VITA_DISABLE_TOUCH_BACK"); + + sceTouchSetSamplingState(SCE_TOUCH_PORT_FRONT, SCE_TOUCH_SAMPLING_STATE_START); + sceTouchSetSamplingState(SCE_TOUCH_PORT_BACK, SCE_TOUCH_SAMPLING_STATE_START); + sceTouchEnableTouchForce(SCE_TOUCH_PORT_FRONT); + sceTouchEnableTouchForce(SCE_TOUCH_PORT_BACK); + + for (int port = 0; port < SCE_TOUCH_PORT_MAX_NUM; port++) { + SceTouchPanelInfo panelinfo; + sceTouchGetPanelInfo(port, &panelinfo); + + area_info[port].x = (float)panelinfo.minAaX; + area_info[port].y = (float)panelinfo.minAaY; + area_info[port].w = (float)(panelinfo.maxAaX - panelinfo.minAaX); + area_info[port].h = (float)(panelinfo.maxAaY - panelinfo.minAaY); + + force_info[port].min = (float)panelinfo.minForce; + force_info[port].range = (float)(panelinfo.maxForce - panelinfo.minForce); + } + + // Support passing both front and back touch devices in events + SDL_AddTouch((SDL_TouchID)0, SDL_TOUCH_DEVICE_DIRECT, "Front"); + SDL_AddTouch((SDL_TouchID)1, SDL_TOUCH_DEVICE_INDIRECT_ABSOLUTE, "Back"); +} + +void VITA_QuitTouch(void) +{ + sceTouchDisableTouchForce(SCE_TOUCH_PORT_FRONT); + sceTouchDisableTouchForce(SCE_TOUCH_PORT_BACK); +} + +void VITA_PollTouch(void) +{ + SDL_FingerID finger_id = 0; + int port; + + // We skip polling touch if no window is created + if (!Vita_Window) { + return; + } + + SDL_memcpy(touch_old, touch, sizeof(touch_old)); + + for (port = 0; port < SCE_TOUCH_PORT_MAX_NUM; port++) { + /** Skip polling of Touch Device if environment variable is set **/ + if (((port == 0) && disableFrontPoll) || ((port == 1) && disableBackPoll)) { + continue; + } + sceTouchPeek(port, &touch[port], 1); + if (touch[port].reportNum > 0) { + for (int i = 0; i < touch[port].reportNum; i++) { + // adjust coordinates and forces to return normalized values + // for the front, screen area is used as a reference (for direct touch) + // e.g. touch_x = 1.0 corresponds to screen_x = 960 + // for the back panel, the active touch area is used as reference + float x = 0; + float y = 0; + float force = (touch[port].report[i].force - force_info[port].min) / force_info[port].range; + int finger_down = 0; + + if (touch_old[port].reportNum > 0) { + for (int j = 0; j < touch_old[port].reportNum; j++) { + if (touch[port].report[i].id == touch_old[port].report[j].id) { + finger_down = 1; + } + } + } + + VITA_ConvertTouchXYToSDLXY(&x, &y, touch[port].report[i].x, touch[port].report[i].y, port); + finger_id = (SDL_FingerID)touch[port].report[i].id; + + // Skip if finger was already previously down + if (!finger_down) { + // Send an initial touch + SDL_SendTouch((SDL_TouchID)port, + finger_id, + Vita_Window, + SDL_TRUE, + x, + y, + force); + } + + // Always send the motion + SDL_SendTouchMotion((SDL_TouchID)port, + finger_id, + Vita_Window, + x, + y, + force); + } + } + + // some fingers might have been let go + if (touch_old[port].reportNum > 0) { + for (int i = 0; i < touch_old[port].reportNum; i++) { + int finger_up = 1; + if (touch[port].reportNum > 0) { + for (int j = 0; j < touch[port].reportNum; j++) { + if (touch[port].report[j].id == touch_old[port].report[i].id) { + finger_up = 0; + } + } + } + if (finger_up == 1) { + float x = 0; + float y = 0; + float force = (touch_old[port].report[i].force - force_info[port].min) / force_info[port].range; + VITA_ConvertTouchXYToSDLXY(&x, &y, touch_old[port].report[i].x, touch_old[port].report[i].y, port); + finger_id = (SDL_FingerID)touch_old[port].report[i].id; + // Finger released from screen + SDL_SendTouch((SDL_TouchID)port, + finger_id, + Vita_Window, + SDL_FALSE, + x, + y, + force); + } + } + } + } +} + +void VITA_ConvertTouchXYToSDLXY(float *sdl_x, float *sdl_y, int vita_x, int vita_y, int port) +{ + float x = (vita_x - area_info[port].x) / area_info[port].w; + float y = (vita_y - area_info[port].y) / area_info[port].h; + + x = SDL_max(x, 0.0); + x = SDL_min(x, 1.0); + + y = SDL_max(y, 0.0); + y = SDL_min(y, 1.0); + + *sdl_x = x; + *sdl_y = y; +} + +#endif /* SDL_VIDEO_DRIVER_VITA */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/vita/SDL_vitatouch.h b/SDL2-2.30.5/src/video/vita/SDL_vitatouch.h new file mode 100644 index 0000000..29369dc --- /dev/null +++ b/SDL2-2.30.5/src/video/vita/SDL_vitatouch.h @@ -0,0 +1,35 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#ifndef _SDL_vitatouch_h +#define _SDL_vitatouch_h + +#include "../../SDL_internal.h" + +/* Touch functions */ +extern void VITA_InitTouch(void); +extern void VITA_QuitTouch(void); +extern void VITA_PollTouch(void); +void VITA_ConvertTouchXYToSDLXY(float *sdl_x, float *sdl_y, int vita_x, int vita_y, int port); + +#endif /* _SDL_vitatouch_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/vita/SDL_vitavideo.c b/SDL2-2.30.5/src/video/vita/SDL_vitavideo.c new file mode 100644 index 0000000..9b8839d --- /dev/null +++ b/SDL2-2.30.5/src/video/vita/SDL_vitavideo.c @@ -0,0 +1,610 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_VITA + +/* SDL internals */ +#include "../SDL_sysvideo.h" +#include "SDL_version.h" +#include "SDL_syswm.h" +#include "SDL_loadso.h" +#include "SDL_events.h" +#include "../../events/SDL_mouse_c.h" +#include "../../events/SDL_keyboard_c.h" + +/* VITA declarations */ +#include +#include "SDL_vitavideo.h" +#include "SDL_vitatouch.h" +#include "SDL_vitakeyboard.h" +#include "SDL_vitamouse_c.h" +#include "SDL_vitaframebuffer.h" +#include "SDL_vitamessagebox.h" + +#if defined(SDL_VIDEO_VITA_PIB) +#include "SDL_vitagles_c.h" +#elif defined(SDL_VIDEO_VITA_PVR) +#include "SDL_vitagles_pvr_c.h" +#if defined(SDL_VIDEO_VITA_PVR_OGL) +#include "SDL_vitagl_pvr_c.h" +#endif + #define VITA_GLES_GetProcAddress SDL_EGL_GetProcAddress + #define VITA_GLES_UnloadLibrary SDL_EGL_UnloadLibrary + #define VITA_GLES_SetSwapInterval SDL_EGL_SetSwapInterval + #define VITA_GLES_GetSwapInterval SDL_EGL_GetSwapInterval + #define VITA_GLES_DeleteContext SDL_EGL_DeleteContext +#endif + +SDL_Window *Vita_Window; + +static void VITA_Destroy(SDL_VideoDevice *device) +{ + /* SDL_VideoData *phdata = (SDL_VideoData *) device->driverdata; */ + + SDL_free(device->driverdata); + SDL_free(device); + // if (device->driverdata != NULL) { + // device->driverdata = NULL; + // } +} + +static SDL_VideoDevice *VITA_Create() +{ + SDL_VideoDevice *device; + SDL_VideoData *phdata; +#ifdef SDL_VIDEO_VITA_PIB + SDL_GLDriverData *gldata; +#endif + /* Initialize SDL_VideoDevice structure */ + device = (SDL_VideoDevice *)SDL_calloc(1, sizeof(SDL_VideoDevice)); + if (!device) { + SDL_OutOfMemory(); + return NULL; + } + + /* Initialize internal VITA specific data */ + phdata = (SDL_VideoData *)SDL_calloc(1, sizeof(SDL_VideoData)); + if (!phdata) { + SDL_OutOfMemory(); + SDL_free(device); + return NULL; + } +#ifdef SDL_VIDEO_VITA_PIB + + gldata = (SDL_GLDriverData *)SDL_calloc(1, sizeof(SDL_GLDriverData)); + if (!gldata) { + SDL_OutOfMemory(); + SDL_free(device); + SDL_free(phdata); + return NULL; + } + device->gl_data = gldata; + phdata->egl_initialized = SDL_TRUE; +#endif + phdata->ime_active = SDL_FALSE; + + device->driverdata = phdata; + + /* Setup amount of available displays and current display */ + device->num_displays = 0; + + /* Set device free function */ + device->free = VITA_Destroy; + + /* Setup all functions which we can handle */ + device->VideoInit = VITA_VideoInit; + device->VideoQuit = VITA_VideoQuit; + device->GetDisplayModes = VITA_GetDisplayModes; + device->SetDisplayMode = VITA_SetDisplayMode; + device->CreateSDLWindow = VITA_CreateWindow; + device->CreateSDLWindowFrom = VITA_CreateWindowFrom; + device->SetWindowTitle = VITA_SetWindowTitle; + device->SetWindowIcon = VITA_SetWindowIcon; + device->SetWindowPosition = VITA_SetWindowPosition; + device->SetWindowSize = VITA_SetWindowSize; + device->ShowWindow = VITA_ShowWindow; + device->HideWindow = VITA_HideWindow; + device->RaiseWindow = VITA_RaiseWindow; + device->MaximizeWindow = VITA_MaximizeWindow; + device->MinimizeWindow = VITA_MinimizeWindow; + device->RestoreWindow = VITA_RestoreWindow; + device->SetWindowMouseGrab = VITA_SetWindowGrab; + device->SetWindowKeyboardGrab = VITA_SetWindowGrab; + device->DestroyWindow = VITA_DestroyWindow; + device->GetWindowWMInfo = VITA_GetWindowWMInfo; + + /* + // Disabled, causes issues on high-framerate updates. SDL still emulates this. + device->CreateWindowFramebuffer = VITA_CreateWindowFramebuffer; + device->UpdateWindowFramebuffer = VITA_UpdateWindowFramebuffer; + device->DestroyWindowFramebuffer = VITA_DestroyWindowFramebuffer; + */ + +#if defined(SDL_VIDEO_VITA_PIB) || defined(SDL_VIDEO_VITA_PVR) +#if defined(SDL_VIDEO_VITA_PVR_OGL) + if (SDL_getenv("VITA_PVR_OGL") != NULL) { + device->GL_LoadLibrary = VITA_GL_LoadLibrary; + device->GL_CreateContext = VITA_GL_CreateContext; + device->GL_GetProcAddress = VITA_GL_GetProcAddress; + } else { +#endif + device->GL_LoadLibrary = VITA_GLES_LoadLibrary; + device->GL_CreateContext = VITA_GLES_CreateContext; + device->GL_GetProcAddress = VITA_GLES_GetProcAddress; +#if defined(SDL_VIDEO_VITA_PVR_OGL) + } +#endif + + device->GL_UnloadLibrary = VITA_GLES_UnloadLibrary; + device->GL_MakeCurrent = VITA_GLES_MakeCurrent; + device->GL_SetSwapInterval = VITA_GLES_SetSwapInterval; + device->GL_GetSwapInterval = VITA_GLES_GetSwapInterval; + device->GL_SwapWindow = VITA_GLES_SwapWindow; + device->GL_DeleteContext = VITA_GLES_DeleteContext; +#endif + + device->HasScreenKeyboardSupport = VITA_HasScreenKeyboardSupport; + device->ShowScreenKeyboard = VITA_ShowScreenKeyboard; + device->HideScreenKeyboard = VITA_HideScreenKeyboard; + device->IsScreenKeyboardShown = VITA_IsScreenKeyboardShown; + + device->PumpEvents = VITA_PumpEvents; + + return device; +} + +VideoBootStrap VITA_bootstrap = { + "VITA", + "VITA Video Driver", + VITA_Create, + VITA_ShowMessageBox +}; + +/*****************************************************************************/ +/* SDL Video and Display initialization/handling functions */ +/*****************************************************************************/ +int VITA_VideoInit(_THIS) +{ + SDL_VideoDisplay display; + SDL_DisplayMode current_mode; +#if defined(SDL_VIDEO_VITA_PVR) + char *res = SDL_getenv("VITA_RESOLUTION"); +#endif + SDL_zero(current_mode); + +#if defined(SDL_VIDEO_VITA_PVR) + if (res) { + /* 1088i for PSTV (Or Sharpscale) */ + if (!SDL_strncmp(res, "1080", 4)) { + current_mode.w = 1920; + current_mode.h = 1088; + } + /* 725p for PSTV (Or Sharpscale) */ + else if (!SDL_strncmp(res, "720", 3)) { + current_mode.w = 1280; + current_mode.h = 725; + } + } + /* 544p */ + else { +#endif + current_mode.w = 960; + current_mode.h = 544; +#if defined(SDL_VIDEO_VITA_PVR) + } +#endif + + current_mode.refresh_rate = 60; + /* 32 bpp for default */ + current_mode.format = SDL_PIXELFORMAT_ABGR8888; + + current_mode.driverdata = NULL; + + SDL_zero(display); + display.desktop_mode = current_mode; + display.current_mode = current_mode; + display.driverdata = NULL; + + SDL_AddVideoDisplay(&display, SDL_FALSE); + VITA_InitTouch(); + VITA_InitKeyboard(); + VITA_InitMouse(); + + return 1; +} + +void VITA_VideoQuit(_THIS) +{ + VITA_QuitTouch(); +} + +void VITA_GetDisplayModes(_THIS, SDL_VideoDisplay *display) +{ + SDL_AddDisplayMode(display, &display->current_mode); +} + +int VITA_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode) +{ + return 0; +} + +int VITA_CreateWindow(_THIS, SDL_Window *window) +{ + SDL_WindowData *wdata; +#if defined(SDL_VIDEO_VITA_PVR) + Psp2NativeWindow win; + int temp_major = 2; + int temp_minor = 1; + int temp_profile = 0; +#endif + + /* Allocate window internal data */ + wdata = (SDL_WindowData *)SDL_calloc(1, sizeof(SDL_WindowData)); + if (!wdata) { + return SDL_OutOfMemory(); + } + + /* Setup driver data for this window */ + window->driverdata = wdata; + + // Vita can only have one window + if (Vita_Window) { + return SDL_SetError("Only one window supported"); + } + + Vita_Window = window; + +#if defined(SDL_VIDEO_VITA_PVR) + win.type = PSP2_DRAWABLE_TYPE_WINDOW; + win.numFlipBuffers = 2; + win.flipChainThrdAffinity = 0x20000; + + /* 1088i for PSTV (Or Sharpscale) */ + if (window->w == 1920) { + win.windowSize = PSP2_WINDOW_1920X1088; + } + /* 725p for PSTV (Or Sharpscale) */ + else if (window->w == 1280) { + win.windowSize = PSP2_WINDOW_1280X725; + } + /* 544p */ + else { + win.windowSize = PSP2_WINDOW_960X544; + } + if (window->flags & SDL_WINDOW_OPENGL) { + if (SDL_getenv("VITA_PVR_OGL") != NULL) { + /* Set version to 2.1 and PROFILE to ES */ + temp_major = _this->gl_config.major_version; + temp_minor = _this->gl_config.minor_version; + temp_profile = _this->gl_config.profile_mask; + + _this->gl_config.major_version = 2; + _this->gl_config.minor_version = 1; + _this->gl_config.profile_mask = SDL_GL_CONTEXT_PROFILE_ES; + } + wdata->egl_surface = SDL_EGL_CreateSurface(_this, &win); + if (wdata->egl_surface == EGL_NO_SURFACE) { + return SDL_SetError("Could not create GLES window surface"); + } + if (SDL_getenv("VITA_PVR_OGL") != NULL) { + /* Revert */ + _this->gl_config.major_version = temp_major; + _this->gl_config.minor_version = temp_minor; + _this->gl_config.profile_mask = temp_profile; + } + } +#endif + + // fix input, we need to find a better way + SDL_SetKeyboardFocus(window); + + /* Window has been successfully created */ + return 0; +} + +int VITA_CreateWindowFrom(_THIS, SDL_Window *window, const void *data) +{ + return -1; +} + +void VITA_SetWindowTitle(_THIS, SDL_Window *window) +{ +} +void VITA_SetWindowIcon(_THIS, SDL_Window *window, SDL_Surface *icon) +{ +} +void VITA_SetWindowPosition(_THIS, SDL_Window *window) +{ +} +void VITA_SetWindowSize(_THIS, SDL_Window *window) +{ +} +void VITA_ShowWindow(_THIS, SDL_Window *window) +{ +} +void VITA_HideWindow(_THIS, SDL_Window *window) +{ +} +void VITA_RaiseWindow(_THIS, SDL_Window *window) +{ +} +void VITA_MaximizeWindow(_THIS, SDL_Window *window) +{ +} +void VITA_MinimizeWindow(_THIS, SDL_Window *window) +{ +} +void VITA_RestoreWindow(_THIS, SDL_Window *window) +{ +} +void VITA_SetWindowGrab(_THIS, SDL_Window *window, SDL_bool grabbed) +{ +} + +void VITA_DestroyWindow(_THIS, SDL_Window *window) +{ + // SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + SDL_WindowData *data; + + data = window->driverdata; + if (data) { + // TODO: should we destroy egl context? No one sane should recreate ogl window as non-ogl + SDL_free(data); + } + + window->driverdata = NULL; + Vita_Window = NULL; +} + +/*****************************************************************************/ +/* SDL Window Manager function */ +/*****************************************************************************/ +SDL_bool VITA_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info) +{ + if (info->version.major <= SDL_MAJOR_VERSION) { + return SDL_TRUE; + } else { + SDL_SetError("application not compiled with SDL %d\n", + SDL_MAJOR_VERSION); + return SDL_FALSE; + } + + /* Failed to get window manager information */ + return SDL_FALSE; +} + +SDL_bool VITA_HasScreenKeyboardSupport(_THIS) +{ + return SDL_TRUE; +} + +#if !defined(SCE_IME_LANGUAGE_ENGLISH_US) +#define SCE_IME_LANGUAGE_ENGLISH_US SCE_IME_LANGUAGE_ENGLISH +#endif + +static void utf16_to_utf8(const uint16_t *src, uint8_t *dst) +{ + int i; + for (i = 0; src[i]; i++) { + if (!(src[i] & 0xFF80)) { + *(dst++) = src[i] & 0xFF; + } else if (!(src[i] & 0xF800)) { + *(dst++) = ((src[i] >> 6) & 0xFF) | 0xC0; + *(dst++) = (src[i] & 0x3F) | 0x80; + } else if ((src[i] & 0xFC00) == 0xD800 && (src[i + 1] & 0xFC00) == 0xDC00) { + *(dst++) = (((src[i] + 64) >> 8) & 0x3) | 0xF0; + *(dst++) = (((src[i] >> 2) + 16) & 0x3F) | 0x80; + *(dst++) = ((src[i] >> 4) & 0x30) | 0x80 | ((src[i + 1] << 2) & 0xF); + *(dst++) = (src[i + 1] & 0x3F) | 0x80; + i += 1; + } else { + *(dst++) = ((src[i] >> 12) & 0xF) | 0xE0; + *(dst++) = ((src[i] >> 6) & 0x3F) | 0x80; + *(dst++) = (src[i] & 0x3F) | 0x80; + } + } + + *dst = '\0'; +} + +#if defined(SDL_VIDEO_VITA_PVR) +SceWChar16 libime_out[SCE_IME_MAX_PREEDIT_LENGTH + SCE_IME_MAX_TEXT_LENGTH + 1]; +char libime_initval[8] = { 1 }; +SceImeCaret caret_rev; + +void VITA_ImeEventHandler(void *arg, const SceImeEventData *e) +{ + SDL_VideoData *videodata = (SDL_VideoData *)arg; + SDL_Scancode scancode; + uint8_t utf8_buffer[SCE_IME_MAX_TEXT_LENGTH]; + switch (e->id) { + case SCE_IME_EVENT_UPDATE_TEXT: + if (e->param.text.caretIndex == 0) { + SDL_SendKeyboardKeyAutoRelease(SDL_SCANCODE_BACKSPACE); + sceImeSetText((SceWChar16 *)libime_initval, 4); + } else { + scancode = SDL_GetScancodeFromKey(*(SceWChar16 *)&libime_out[1]); + if (scancode == SDL_SCANCODE_SPACE) { + SDL_SendKeyboardKeyAutoRelease(SDL_SCANCODE_SPACE); + } else { + utf16_to_utf8((SceWChar16 *)&libime_out[1], utf8_buffer); + SDL_SendKeyboardText((const char *)utf8_buffer); + } + SDL_memset(&caret_rev, 0, sizeof(SceImeCaret)); + SDL_memset(libime_out, 0, ((SCE_IME_MAX_PREEDIT_LENGTH + SCE_IME_MAX_TEXT_LENGTH + 1) * sizeof(SceWChar16))); + caret_rev.index = 1; + sceImeSetCaret(&caret_rev); + sceImeSetText((SceWChar16 *)libime_initval, 4); + } + break; + case SCE_IME_EVENT_PRESS_ENTER: + SDL_SendKeyboardKeyAutoRelease(SDL_SCANCODE_RETURN); + case SCE_IME_EVENT_PRESS_CLOSE: + sceImeClose(); + videodata->ime_active = SDL_FALSE; + break; + } +} +#endif + +void VITA_ShowScreenKeyboard(_THIS, SDL_Window *window) +{ + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + SceInt32 res; + +#if defined(SDL_VIDEO_VITA_PVR) + + SceUInt32 libime_work[SCE_IME_WORK_BUFFER_SIZE / sizeof(SceInt32)]; + SceImeParam param; + + sceImeParamInit(¶m); + + SDL_memset(libime_out, 0, ((SCE_IME_MAX_PREEDIT_LENGTH + SCE_IME_MAX_TEXT_LENGTH + 1) * sizeof(SceWChar16))); + + param.supportedLanguages = SCE_IME_LANGUAGE_ENGLISH_US; + param.languagesForced = SCE_FALSE; + param.type = SCE_IME_TYPE_DEFAULT; + param.option = SCE_IME_OPTION_NO_ASSISTANCE; + param.inputTextBuffer = libime_out; + param.maxTextLength = SCE_IME_MAX_TEXT_LENGTH; + param.handler = VITA_ImeEventHandler; + param.filter = NULL; + param.initialText = (SceWChar16 *)libime_initval; + param.arg = videodata; + param.work = libime_work; + + res = sceImeOpen(¶m); + if (res < 0) { + SDL_SetError("Failed to init IME"); + return; + } + +#else + SceWChar16 *title = u""; + SceWChar16 *text = u""; + + SceImeDialogParam param; + sceImeDialogParamInit(¶m); + + param.supportedLanguages = 0; + param.languagesForced = SCE_FALSE; + param.type = SCE_IME_TYPE_DEFAULT; + param.option = 0; + param.textBoxMode = SCE_IME_DIALOG_TEXTBOX_MODE_WITH_CLEAR; + param.maxTextLength = SCE_IME_DIALOG_MAX_TEXT_LENGTH; + + param.title = title; + param.initialText = text; + param.inputTextBuffer = videodata->ime_buffer; + + res = sceImeDialogInit(¶m); + if (res < 0) { + SDL_SetError("Failed to init IME dialog"); + return; + } + +#endif + + videodata->ime_active = SDL_TRUE; +} + +void VITA_HideScreenKeyboard(_THIS, SDL_Window *window) +{ +#if !defined(SDL_VIDEO_VITA_PVR) + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + + SceCommonDialogStatus dialogStatus = sceImeDialogGetStatus(); + + switch (dialogStatus) { + default: + case SCE_COMMON_DIALOG_STATUS_NONE: + case SCE_COMMON_DIALOG_STATUS_RUNNING: + break; + case SCE_COMMON_DIALOG_STATUS_FINISHED: + sceImeDialogTerm(); + break; + } + + videodata->ime_active = SDL_FALSE; +#endif +} + +SDL_bool VITA_IsScreenKeyboardShown(_THIS, SDL_Window *window) +{ +#if defined(SDL_VIDEO_VITA_PVR) + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + return videodata->ime_active; +#else + SceCommonDialogStatus dialogStatus = sceImeDialogGetStatus(); + return dialogStatus == SCE_COMMON_DIALOG_STATUS_RUNNING; +#endif +} + +void VITA_PumpEvents(_THIS) +{ +#if !defined(SDL_VIDEO_VITA_PVR) + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; +#endif + + if (_this->suspend_screensaver) { + // cancel all idle timers to prevent vita going to sleep + sceKernelPowerTick(SCE_KERNEL_POWER_TICK_DEFAULT); + } + + VITA_PollTouch(); + VITA_PollKeyboard(); + VITA_PollMouse(); + +#if !defined(SDL_VIDEO_VITA_PVR) + if (videodata->ime_active == SDL_TRUE) { + // update IME status. Terminate, if finished + SceCommonDialogStatus dialogStatus = sceImeDialogGetStatus(); + if (dialogStatus == SCE_COMMON_DIALOG_STATUS_FINISHED) { + uint8_t utf8_buffer[SCE_IME_DIALOG_MAX_TEXT_LENGTH]; + + SceImeDialogResult result; + SDL_memset(&result, 0, sizeof(SceImeDialogResult)); + sceImeDialogGetResult(&result); + + // Convert UTF16 to UTF8 + utf16_to_utf8(videodata->ime_buffer, utf8_buffer); + + // Send SDL event + SDL_SendKeyboardText((const char *)utf8_buffer); + + // Send enter key only on enter + if (result.button == SCE_IME_DIALOG_BUTTON_ENTER) { + SDL_SendKeyboardKeyAutoRelease(SDL_SCANCODE_RETURN); + } + + sceImeDialogTerm(); + + videodata->ime_active = SDL_FALSE; + } + } +#endif +} + +#endif /* SDL_VIDEO_DRIVER_VITA */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/vita/SDL_vitavideo.h b/SDL2-2.30.5/src/video/vita/SDL_vitavideo.h new file mode 100644 index 0000000..5f23459 --- /dev/null +++ b/SDL2-2.30.5/src/video/vita/SDL_vitavideo.h @@ -0,0 +1,119 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#ifndef _SDL_vitavideo_h +#define _SDL_vitavideo_h + +#include "../../SDL_internal.h" +#include "../SDL_sysvideo.h" +#include "../SDL_egl_c.h" + +#include +#include +#include +#include + +typedef struct SDL_VideoData +{ + SDL_bool egl_initialized; /* OpenGL device initialization status */ + uint32_t egl_refcount; /* OpenGL reference count */ + + SceWChar16 ime_buffer[SCE_IME_DIALOG_MAX_TEXT_LENGTH]; + SDL_bool ime_active; +} SDL_VideoData; + +typedef struct SDL_DisplayData +{ + +} SDL_DisplayData; + +typedef struct SDL_WindowData +{ + SDL_bool uses_gles; + SceUID buffer_uid; + void *buffer; +#if defined(SDL_VIDEO_VITA_PVR) + EGLSurface egl_surface; + EGLContext egl_context; +#endif +} SDL_WindowData; + +extern SDL_Window *Vita_Window; + +/****************************************************************************/ +/* SDL_VideoDevice functions declaration */ +/****************************************************************************/ + +/* Display and window functions */ +int VITA_VideoInit(_THIS); +void VITA_VideoQuit(_THIS); +void VITA_GetDisplayModes(_THIS, SDL_VideoDisplay *display); +int VITA_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode); +int VITA_CreateWindow(_THIS, SDL_Window *window); +int VITA_CreateWindowFrom(_THIS, SDL_Window *window, const void *data); +void VITA_SetWindowTitle(_THIS, SDL_Window *window); +void VITA_SetWindowIcon(_THIS, SDL_Window *window, SDL_Surface *icon); +void VITA_SetWindowPosition(_THIS, SDL_Window *window); +void VITA_SetWindowSize(_THIS, SDL_Window *window); +void VITA_ShowWindow(_THIS, SDL_Window *window); +void VITA_HideWindow(_THIS, SDL_Window *window); +void VITA_RaiseWindow(_THIS, SDL_Window *window); +void VITA_MaximizeWindow(_THIS, SDL_Window *window); +void VITA_MinimizeWindow(_THIS, SDL_Window *window); +void VITA_RestoreWindow(_THIS, SDL_Window *window); +void VITA_SetWindowGrab(_THIS, SDL_Window *window, SDL_bool grabbed); +void VITA_DestroyWindow(_THIS, SDL_Window *window); + +/* Window manager function */ +SDL_bool VITA_GetWindowWMInfo(_THIS, SDL_Window * window, + struct SDL_SysWMinfo *info); + +#ifdef SDL_VIDEO_DRIVER_VITA +#if defined(SDL_VIDEO_VITA_PVR_OGL) +/* OpenGL functions */ +int VITA_GL_LoadLibrary(_THIS, const char *path); +SDL_GLContext VITA_GL_CreateContext(_THIS, SDL_Window *window); +void *VITA_GL_GetProcAddress(_THIS, const char *proc); +#endif + +/* OpenGLES functions */ +int VITA_GLES_LoadLibrary(_THIS, const char *path); +void *VITA_GLES_GetProcAddress(_THIS, const char *proc); +void VITA_GLES_UnloadLibrary(_THIS); +SDL_GLContext VITA_GLES_CreateContext(_THIS, SDL_Window *window); +int VITA_GLES_MakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context); +int VITA_GLES_SetSwapInterval(_THIS, int interval); +int VITA_GLES_GetSwapInterval(_THIS); +int VITA_GLES_SwapWindow(_THIS, SDL_Window *window); +void VITA_GLES_DeleteContext(_THIS, SDL_GLContext context); +#endif + +/* VITA on screen keyboard */ +SDL_bool VITA_HasScreenKeyboardSupport(_THIS); +void VITA_ShowScreenKeyboard(_THIS, SDL_Window *window); +void VITA_HideScreenKeyboard(_THIS, SDL_Window *window); +SDL_bool VITA_IsScreenKeyboardShown(_THIS, SDL_Window *window); + +void VITA_PumpEvents(_THIS); + +#endif /* _SDL_pspvideo_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/vivante/SDL_vivanteopengles.c b/SDL2-2.30.5/src/video/vivante/SDL_vivanteopengles.c similarity index 80% rename from SDL2-2.0.12/src/video/vivante/SDL_vivanteopengles.c rename to SDL2-2.30.5/src/video/vivante/SDL_vivanteopengles.c index 308f7ee..e088cf4 100644 --- a/SDL2-2.0.12/src/video/vivante/SDL_vivanteopengles.c +++ b/SDL2-2.30.5/src/video/vivante/SDL_vivanteopengles.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,15 +20,14 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_VIVANTE && SDL_VIDEO_OPENGL_EGL +#if defined(SDL_VIDEO_DRIVER_VIVANTE) && defined(SDL_VIDEO_OPENGL_EGL) #include "SDL_vivanteopengles.h" #include "SDL_vivantevideo.h" /* EGL implementation of SDL OpenGL support */ -int -VIVANTE_GLES_LoadLibrary(_THIS, const char *path) +int VIVANTE_GLES_LoadLibrary(_THIS, const char *path) { SDL_DisplayData *displaydata; @@ -38,10 +37,9 @@ VIVANTE_GLES_LoadLibrary(_THIS, const char *path) } SDL_EGL_CreateContext_impl(VIVANTE) -SDL_EGL_SwapWindow_impl(VIVANTE) -SDL_EGL_MakeCurrent_impl(VIVANTE) + SDL_EGL_SwapWindow_impl(VIVANTE) + SDL_EGL_MakeCurrent_impl(VIVANTE) #endif /* SDL_VIDEO_DRIVER_VIVANTE && SDL_VIDEO_OPENGL_EGL */ -/* vi: set ts=4 sw=4 expandtab: */ - + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/vivante/SDL_vivanteopengles.h b/SDL2-2.30.5/src/video/vivante/SDL_vivanteopengles.h similarity index 82% rename from SDL2-2.0.12/src/video/vivante/SDL_vivanteopengles.h rename to SDL2-2.30.5/src/video/vivante/SDL_vivanteopengles.h index 6241eae..7dc55c2 100644 --- a/SDL2-2.0.12/src/video/vivante/SDL_vivanteopengles.h +++ b/SDL2-2.30.5/src/video/vivante/SDL_vivanteopengles.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,7 +23,7 @@ #ifndef SDL_vivanteopengles_h_ #define SDL_vivanteopengles_h_ -#if SDL_VIDEO_DRIVER_VIVANTE && SDL_VIDEO_OPENGL_EGL +#if defined(SDL_VIDEO_DRIVER_VIVANTE) && defined(SDL_VIDEO_OPENGL_EGL) #include "../SDL_sysvideo.h" #include "../SDL_egl_c.h" @@ -34,12 +34,12 @@ #define VIVANTE_GLES_UnloadLibrary SDL_EGL_UnloadLibrary #define VIVANTE_GLES_SetSwapInterval SDL_EGL_SetSwapInterval #define VIVANTE_GLES_GetSwapInterval SDL_EGL_GetSwapInterval -#define VIVANTE_GLES_DeleteContext SDL_EGL_DeleteContext +#define VIVANTE_GLES_DeleteContext SDL_EGL_DeleteContext extern int VIVANTE_GLES_LoadLibrary(_THIS, const char *path); -extern SDL_GLContext VIVANTE_GLES_CreateContext(_THIS, SDL_Window * window); -extern int VIVANTE_GLES_SwapWindow(_THIS, SDL_Window * window); -extern int VIVANTE_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context); +extern SDL_GLContext VIVANTE_GLES_CreateContext(_THIS, SDL_Window *window); +extern int VIVANTE_GLES_SwapWindow(_THIS, SDL_Window *window); +extern int VIVANTE_GLES_MakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context); #endif /* SDL_VIDEO_DRIVER_VIVANTE && SDL_VIDEO_OPENGL_EGL */ diff --git a/SDL2-2.0.12/src/video/vivante/SDL_vivanteplatform.c b/SDL2-2.30.5/src/video/vivante/SDL_vivanteplatform.c similarity index 85% rename from SDL2-2.0.12/src/video/vivante/SDL_vivanteplatform.c rename to SDL2-2.30.5/src/video/vivante/SDL_vivanteplatform.c index f6f37cf..cf4b5ac 100644 --- a/SDL2-2.0.12/src/video/vivante/SDL_vivanteplatform.c +++ b/SDL2-2.30.5/src/video/vivante/SDL_vivanteplatform.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,14 +20,13 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_VIVANTE +#ifdef SDL_VIDEO_DRIVER_VIVANTE #include "SDL_vivanteplatform.h" #ifdef VIVANTE_PLATFORM_GENERIC -int -VIVANTE_SetupPlatform(_THIS) +int VIVANTE_SetupPlatform(_THIS) { return 0; } @@ -37,13 +36,11 @@ char *VIVANTE_GetDisplayName(_THIS) return NULL; } -void -VIVANTE_UpdateDisplayScale(_THIS) +void VIVANTE_UpdateDisplayScale(_THIS) { } -void -VIVANTE_CleanupPlatform(_THIS) +void VIVANTE_CleanupPlatform(_THIS) { } diff --git a/SDL2-2.0.12/src/video/vivante/SDL_vivanteplatform.h b/SDL2-2.30.5/src/video/vivante/SDL_vivanteplatform.h similarity index 94% rename from SDL2-2.0.12/src/video/vivante/SDL_vivanteplatform.h rename to SDL2-2.30.5/src/video/vivante/SDL_vivanteplatform.h index 0f0e3f3..19e8e3e 100644 --- a/SDL2-2.0.12/src/video/vivante/SDL_vivanteplatform.h +++ b/SDL2-2.30.5/src/video/vivante/SDL_vivanteplatform.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,7 +23,7 @@ #ifndef SDL_vivanteplatform_h_ #define SDL_vivanteplatform_h_ -#if SDL_VIDEO_DRIVER_VIVANTE +#ifdef SDL_VIDEO_DRIVER_VIVANTE #include "SDL_vivantevideo.h" diff --git a/SDL2-2.0.12/src/video/vivante/SDL_vivantevideo.c b/SDL2-2.30.5/src/video/vivante/SDL_vivantevideo.c similarity index 80% rename from SDL2-2.0.12/src/video/vivante/SDL_vivantevideo.c rename to SDL2-2.30.5/src/video/vivante/SDL_vivantevideo.c index ea1f54c..a501f65 100644 --- a/SDL2-2.0.12/src/video/vivante/SDL_vivantevideo.c +++ b/SDL2-2.30.5/src/video/vivante/SDL_vivantevideo.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_VIVANTE +#ifdef SDL_VIDEO_DRIVER_VIVANTE /* SDL internals */ #include "../SDL_sysvideo.h" @@ -39,38 +39,29 @@ #include "SDL_vivanteopengles.h" #include "SDL_vivantevulkan.h" - -static int -VIVANTE_Available(void) +static void VIVANTE_Destroy(SDL_VideoDevice *device) { - return 1; -} - -static void -VIVANTE_Destroy(SDL_VideoDevice * device) -{ - if (device->driverdata != NULL) { + if (device->driverdata) { SDL_free(device->driverdata); device->driverdata = NULL; } } -static SDL_VideoDevice * -VIVANTE_Create() +static SDL_VideoDevice *VIVANTE_Create() { SDL_VideoDevice *device; SDL_VideoData *data; /* Initialize SDL_VideoDevice structure */ - device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice)); - if (device == NULL) { + device = (SDL_VideoDevice *)SDL_calloc(1, sizeof(SDL_VideoDevice)); + if (!device) { SDL_OutOfMemory(); return NULL; } /* Initialize internal data */ - data = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData)); - if (data == NULL) { + data = (SDL_VideoData *)SDL_calloc(1, sizeof(SDL_VideoData)); + if (!data) { SDL_OutOfMemory(); SDL_free(device); return NULL; @@ -98,7 +89,7 @@ VIVANTE_Create() device->DestroyWindow = VIVANTE_DestroyWindow; device->GetWindowWMInfo = VIVANTE_GetWindowWMInfo; -#if SDL_VIDEO_OPENGL_EGL +#ifdef SDL_VIDEO_OPENGL_EGL device->GL_LoadLibrary = VIVANTE_GLES_LoadLibrary; device->GL_GetProcAddress = VIVANTE_GLES_GetProcAddress; device->GL_UnloadLibrary = VIVANTE_GLES_UnloadLibrary; @@ -110,7 +101,7 @@ VIVANTE_Create() device->GL_DeleteContext = VIVANTE_GLES_DeleteContext; #endif -#if SDL_VIDEO_VULKAN +#ifdef SDL_VIDEO_VULKAN device->Vulkan_LoadLibrary = VIVANTE_Vulkan_LoadLibrary; device->Vulkan_UnloadLibrary = VIVANTE_Vulkan_UnloadLibrary; device->Vulkan_GetInstanceExtensions = VIVANTE_Vulkan_GetInstanceExtensions; @@ -125,16 +116,15 @@ VIVANTE_Create() VideoBootStrap VIVANTE_bootstrap = { "vivante", "Vivante EGL Video Driver", - VIVANTE_Available, - VIVANTE_Create + VIVANTE_Create, + NULL /* no ShowMessageBox implementation */ }; /*****************************************************************************/ /* SDL Video and Display initialization/handling functions */ /*****************************************************************************/ -static int -VIVANTE_AddVideoDisplays(_THIS) +static int VIVANTE_AddVideoDisplays(_THIS) { SDL_VideoData *videodata = _this->driverdata; SDL_VideoDisplay display; @@ -143,13 +133,13 @@ VIVANTE_AddVideoDisplays(_THIS) int pitch = 0, bpp = 0; unsigned long pixels = 0; - data = (SDL_DisplayData *) SDL_calloc(1, sizeof(SDL_DisplayData)); - if (data == NULL) { + data = (SDL_DisplayData *)SDL_calloc(1, sizeof(SDL_DisplayData)); + if (!data) { return SDL_OutOfMemory(); } SDL_zero(current_mode); -#if SDL_VIDEO_DRIVER_VIVANTE_VDK +#ifdef SDL_VIDEO_DRIVER_VIVANTE_VDK data->native_display = vdkGetDisplay(videodata->vdk_private); vdkGetDisplayInfo(data->native_display, ¤t_mode.w, ¤t_mode.h, &pixels, &pitch, &bpp); @@ -159,8 +149,7 @@ VIVANTE_AddVideoDisplays(_THIS) videodata->fbGetDisplayInfo(data->native_display, ¤t_mode.w, ¤t_mode.h, &pixels, &pitch, &bpp); #endif /* SDL_VIDEO_DRIVER_VIVANTE_VDK */ - switch (bpp) - { + switch (bpp) { default: /* Is another format used? */ case 32: current_mode.format = SDL_PIXELFORMAT_ARGB8888; @@ -177,16 +166,15 @@ VIVANTE_AddVideoDisplays(_THIS) display.desktop_mode = current_mode; display.current_mode = current_mode; display.driverdata = data; - SDL_AddVideoDisplay(&display); + SDL_AddVideoDisplay(&display, SDL_FALSE); return 0; } -int -VIVANTE_VideoInit(_THIS) +int VIVANTE_VideoInit(_THIS) { SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; -#if SDL_VIDEO_DRIVER_VIVANTE_VDK +#ifdef SDL_VIDEO_DRIVER_VIVANTE_VDK videodata->vdk_private = vdkInitialize(); if (!videodata->vdk_private) { return SDL_SetError("vdkInitialize() failed"); @@ -199,9 +187,10 @@ VIVANTE_VideoInit(_THIS) return -1; } } -#define LOAD_FUNC(NAME) \ +#define LOAD_FUNC(NAME) \ videodata->NAME = SDL_LoadFunction(videodata->egl_handle, #NAME); \ - if (!videodata->NAME) return -1; + if (!videodata->NAME) \ + return -1; LOAD_FUNC(fbGetDisplay); LOAD_FUNC(fbGetDisplayByIndex); @@ -233,8 +222,7 @@ VIVANTE_VideoInit(_THIS) return 0; } -void -VIVANTE_VideoQuit(_THIS) +void VIVANTE_VideoQuit(_THIS) { SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; @@ -244,7 +232,7 @@ VIVANTE_VideoQuit(_THIS) VIVANTE_CleanupPlatform(_this); -#if SDL_VIDEO_DRIVER_VIVANTE_VDK +#ifdef SDL_VIDEO_DRIVER_VIVANTE_VDK if (videodata->vdk_private) { vdkExit(videodata->vdk_private); videodata->vdk_private = NULL; @@ -257,21 +245,18 @@ VIVANTE_VideoQuit(_THIS) #endif } -void -VIVANTE_GetDisplayModes(_THIS, SDL_VideoDisplay * display) +void VIVANTE_GetDisplayModes(_THIS, SDL_VideoDisplay *display) { /* Only one display mode available, the current one */ SDL_AddDisplayMode(display, &display->current_mode); } -int -VIVANTE_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) +int VIVANTE_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode) { return 0; } -int -VIVANTE_CreateWindow(_THIS, SDL_Window * window) +int VIVANTE_CreateWindow(_THIS, SDL_Window *window) { SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; SDL_DisplayData *displaydata; @@ -280,15 +265,15 @@ VIVANTE_CreateWindow(_THIS, SDL_Window * window) displaydata = SDL_GetDisplayDriverData(0); /* Allocate window internal data */ - data = (SDL_WindowData *) SDL_calloc(1, sizeof(SDL_WindowData)); - if (data == NULL) { + data = (SDL_WindowData *)SDL_calloc(1, sizeof(SDL_WindowData)); + if (!data) { return SDL_OutOfMemory(); } /* Setup driver data for this window */ window->driverdata = data; -#if SDL_VIDEO_DRIVER_VIVANTE_VDK +#ifdef SDL_VIDEO_DRIVER_VIVANTE_VDK data->native_window = vdkCreateWindow(displaydata->native_display, window->x, window->y, window->w, window->h); #else data->native_window = videodata->fbCreateWindow(displaydata->native_display, window->x, window->y, window->w, window->h); @@ -297,7 +282,7 @@ VIVANTE_CreateWindow(_THIS, SDL_Window * window) return SDL_SetError("VIVANTE: Can't create native window"); } -#if SDL_VIDEO_OPENGL_EGL +#ifdef 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) { @@ -312,22 +297,21 @@ VIVANTE_CreateWindow(_THIS, SDL_Window * window) return 0; } -void -VIVANTE_DestroyWindow(_THIS, SDL_Window * window) +void VIVANTE_DestroyWindow(_THIS, SDL_Window *window) { SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; SDL_WindowData *data; data = window->driverdata; if (data) { -#if SDL_VIDEO_OPENGL_EGL +#ifdef 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 +#ifdef SDL_VIDEO_DRIVER_VIVANTE_VDK vdkDestroyWindow(data->native_window); #else videodata->fbDestroyWindow(data->native_window); @@ -339,31 +323,27 @@ VIVANTE_DestroyWindow(_THIS, SDL_Window * window) window->driverdata = NULL; } -void -VIVANTE_SetWindowTitle(_THIS, SDL_Window * window) +void VIVANTE_SetWindowTitle(_THIS, SDL_Window *window) { -#if SDL_VIDEO_DRIVER_VIVANTE_VDK +#ifdef SDL_VIDEO_DRIVER_VIVANTE_VDK SDL_WindowData *data = window->driverdata; vdkSetWindowTitle(data->native_window, window->title); #endif } -void -VIVANTE_SetWindowPosition(_THIS, SDL_Window * window) +void VIVANTE_SetWindowPosition(_THIS, SDL_Window *window) { /* FIXME */ } -void -VIVANTE_SetWindowSize(_THIS, SDL_Window * window) +void VIVANTE_SetWindowSize(_THIS, SDL_Window *window) { /* FIXME */ } -void -VIVANTE_ShowWindow(_THIS, SDL_Window * window) +void VIVANTE_ShowWindow(_THIS, SDL_Window *window) { -#if SDL_VIDEO_DRIVER_VIVANTE_VDK +#ifdef SDL_VIDEO_DRIVER_VIVANTE_VDK SDL_WindowData *data = window->driverdata; vdkShowWindow(data->native_window); #endif @@ -371,33 +351,32 @@ VIVANTE_ShowWindow(_THIS, SDL_Window * window) SDL_SetKeyboardFocus(window); } -void -VIVANTE_HideWindow(_THIS, SDL_Window * window) +void VIVANTE_HideWindow(_THIS, SDL_Window *window) { -#if SDL_VIDEO_DRIVER_VIVANTE_VDK +#ifdef SDL_VIDEO_DRIVER_VIVANTE_VDK SDL_WindowData *data = window->driverdata; vdkHideWindow(data->native_window); #endif + SDL_SetMouseFocus(NULL); + SDL_SetKeyboardFocus(NULL); } /*****************************************************************************/ /* SDL Window Manager function */ /*****************************************************************************/ -SDL_bool -VIVANTE_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info) +SDL_bool VIVANTE_GetWindowWMInfo(_THIS, SDL_Window *window, struct SDL_SysWMinfo *info) { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; SDL_DisplayData *displaydata = SDL_GetDisplayDriverData(0); - if (info->version.major == SDL_MAJOR_VERSION && - info->version.minor == SDL_MINOR_VERSION) { + if (info->version.major == SDL_MAJOR_VERSION) { info->subsystem = SDL_SYSWM_VIVANTE; info->info.vivante.display = displaydata->native_display; info->info.vivante.window = data->native_window; return SDL_TRUE; } else { - SDL_SetError("Application not compiled with SDL %d.%d", - SDL_MAJOR_VERSION, SDL_MINOR_VERSION); + SDL_SetError("Application not compiled with SDL %d", + SDL_MAJOR_VERSION); return SDL_FALSE; } } diff --git a/SDL2-2.0.12/src/video/vivante/SDL_vivantevideo.h b/SDL2-2.30.5/src/video/vivante/SDL_vivantevideo.h similarity index 56% rename from SDL2-2.0.12/src/video/vivante/SDL_vivantevideo.h rename to SDL2-2.30.5/src/video/vivante/SDL_vivantevideo.h index 8d59a1d..03dcb7e 100644 --- a/SDL2-2.0.12/src/video/vivante/SDL_vivantevideo.h +++ b/SDL2-2.30.5/src/video/vivante/SDL_vivantevideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -27,7 +27,7 @@ #include "SDL_egl.h" -#if SDL_VIDEO_DRIVER_VIVANTE_VDK +#ifdef SDL_VIDEO_DRIVER_VIVANTE_VDK #include #else #include @@ -35,19 +35,19 @@ typedef struct SDL_VideoData { -#if SDL_VIDEO_DRIVER_VIVANTE_VDK +#ifdef SDL_VIDEO_DRIVER_VIVANTE_VDK vdkPrivate vdk_private; #else void *egl_handle; /* EGL shared library handle */ - EGLNativeDisplayType (EGLAPIENTRY *fbGetDisplay)(void *context); - EGLNativeDisplayType (EGLAPIENTRY *fbGetDisplayByIndex)(int DisplayIndex); - void (EGLAPIENTRY *fbGetDisplayGeometry)(EGLNativeDisplayType Display, int *Width, int *Height); - void (EGLAPIENTRY *fbGetDisplayInfo)(EGLNativeDisplayType Display, int *Width, int *Height, unsigned long *Physical, int *Stride, int *BitsPerPixel); - void (EGLAPIENTRY *fbDestroyDisplay)(EGLNativeDisplayType Display); - EGLNativeWindowType (EGLAPIENTRY *fbCreateWindow)(EGLNativeDisplayType Display, int X, int Y, int Width, int Height); - void (EGLAPIENTRY *fbGetWindowGeometry)(EGLNativeWindowType Window, int *X, int *Y, int *Width, int *Height); - void (EGLAPIENTRY *fbGetWindowInfo)(EGLNativeWindowType Window, int *X, int *Y, int *Width, int *Height, int *BitsPerPixel, unsigned int *Offset); - void (EGLAPIENTRY *fbDestroyWindow)(EGLNativeWindowType Window); + EGLNativeDisplayType(EGLAPIENTRY *fbGetDisplay)(void *context); + EGLNativeDisplayType(EGLAPIENTRY *fbGetDisplayByIndex)(int DisplayIndex); + void(EGLAPIENTRY *fbGetDisplayGeometry)(EGLNativeDisplayType Display, int *Width, int *Height); + void(EGLAPIENTRY *fbGetDisplayInfo)(EGLNativeDisplayType Display, int *Width, int *Height, unsigned long *Physical, int *Stride, int *BitsPerPixel); + void(EGLAPIENTRY *fbDestroyDisplay)(EGLNativeDisplayType Display); + EGLNativeWindowType(EGLAPIENTRY *fbCreateWindow)(EGLNativeDisplayType Display, int X, int Y, int Width, int Height); + void(EGLAPIENTRY *fbGetWindowGeometry)(EGLNativeWindowType Window, int *X, int *Y, int *Width, int *Height); + void(EGLAPIENTRY *fbGetWindowInfo)(EGLNativeWindowType Window, int *X, int *Y, int *Width, int *Height, int *BitsPerPixel, unsigned int *Offset); + void(EGLAPIENTRY *fbDestroyWindow)(EGLNativeWindowType Window); #endif } SDL_VideoData; @@ -69,15 +69,15 @@ typedef struct SDL_WindowData /* Display and window functions */ int VIVANTE_VideoInit(_THIS); void VIVANTE_VideoQuit(_THIS); -void VIVANTE_GetDisplayModes(_THIS, SDL_VideoDisplay * display); -int VIVANTE_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode); -int VIVANTE_CreateWindow(_THIS, SDL_Window * window); -void VIVANTE_SetWindowTitle(_THIS, SDL_Window * window); -void VIVANTE_SetWindowPosition(_THIS, SDL_Window * window); -void VIVANTE_SetWindowSize(_THIS, SDL_Window * window); -void VIVANTE_ShowWindow(_THIS, SDL_Window * window); -void VIVANTE_HideWindow(_THIS, SDL_Window * window); -void VIVANTE_DestroyWindow(_THIS, SDL_Window * window); +void VIVANTE_GetDisplayModes(_THIS, SDL_VideoDisplay *display); +int VIVANTE_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode); +int VIVANTE_CreateWindow(_THIS, SDL_Window *window); +void VIVANTE_SetWindowTitle(_THIS, SDL_Window *window); +void VIVANTE_SetWindowPosition(_THIS, SDL_Window *window); +void VIVANTE_SetWindowSize(_THIS, SDL_Window *window); +void VIVANTE_ShowWindow(_THIS, SDL_Window *window); +void VIVANTE_HideWindow(_THIS, SDL_Window *window); +void VIVANTE_DestroyWindow(_THIS, SDL_Window *window); /* Window manager function */ SDL_bool VIVANTE_GetWindowWMInfo(_THIS, SDL_Window * window, diff --git a/SDL2-2.0.12/src/video/vivante/SDL_vivantevulkan.c b/SDL2-2.30.5/src/video/vivante/SDL_vivantevulkan.c similarity index 71% rename from SDL2-2.0.12/src/video/vivante/SDL_vivantevulkan.c rename to SDL2-2.30.5/src/video/vivante/SDL_vivantevulkan.c index 2ff623b..ce1e80c 100644 --- a/SDL2-2.0.12/src/video/vivante/SDL_vivantevulkan.c +++ b/SDL2-2.30.5/src/video/vivante/SDL_vivantevulkan.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -27,15 +27,13 @@ #include "../../SDL_internal.h" -#if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_VIVANTE +#if defined(SDL_VIDEO_VULKAN) && defined(SDL_VIDEO_DRIVER_VIVANTE) #include "SDL_vivantevideo.h" -#include "SDL_assert.h" #include "SDL_loadso.h" #include "SDL_vivantevulkan.h" #include "SDL_syswm.h" -#include "SDL_log.h" int VIVANTE_Vulkan_LoadLibrary(_THIS, const char *path) { @@ -44,19 +42,19 @@ int VIVANTE_Vulkan_LoadLibrary(_THIS, const char *path) SDL_bool hasSurfaceExtension = SDL_FALSE; SDL_bool hasDisplayExtension = SDL_FALSE; PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL; - if(_this->vulkan_config.loader_handle) + if (_this->vulkan_config.loader_handle) { return SDL_SetError("Vulkan already loaded"); + } /* Load the Vulkan loader library */ - if(!path) + if (!path) { path = SDL_getenv("SDL_VULKAN_LIBRARY"); - if(!path) - { + } + if (!path) { /* If no path set, try Vivante fb vulkan driver explicitly */ path = "libvulkan-fb.so"; _this->vulkan_config.loader_handle = SDL_LoadObject(path); - if(!_this->vulkan_config.loader_handle) - { + if (!_this->vulkan_config.loader_handle) { /* If that couldn't be loaded, fall back to default name */ path = "libvulkan.so"; _this->vulkan_config.loader_handle = SDL_LoadObject(path); @@ -64,45 +62,44 @@ int VIVANTE_Vulkan_LoadLibrary(_THIS, const char *path) } else { _this->vulkan_config.loader_handle = SDL_LoadObject(path); } - if(!_this->vulkan_config.loader_handle) + if (!_this->vulkan_config.loader_handle) { return -1; + } SDL_strlcpy(_this->vulkan_config.loader_path, path, SDL_arraysize(_this->vulkan_config.loader_path)); SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "vivante: Loaded vulkan driver %s", path); vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)SDL_LoadFunction( _this->vulkan_config.loader_handle, "vkGetInstanceProcAddr"); - if(!vkGetInstanceProcAddr) + if (!vkGetInstanceProcAddr) { goto fail; + } _this->vulkan_config.vkGetInstanceProcAddr = (void *)vkGetInstanceProcAddr; _this->vulkan_config.vkEnumerateInstanceExtensionProperties = (void *)((PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr)( VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties"); - if(!_this->vulkan_config.vkEnumerateInstanceExtensionProperties) + if (!_this->vulkan_config.vkEnumerateInstanceExtensionProperties) { goto fail; + } extensions = SDL_Vulkan_CreateInstanceExtensionsList( (PFN_vkEnumerateInstanceExtensionProperties) _this->vulkan_config.vkEnumerateInstanceExtensionProperties, &extensionCount); - if(!extensions) + if (!extensions) { goto fail; - for(i = 0; i < extensionCount; i++) - { - if(SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) + } + for (i = 0; i < extensionCount; i++) { + if (SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) { hasSurfaceExtension = SDL_TRUE; - else if(SDL_strcmp(VK_KHR_DISPLAY_EXTENSION_NAME, extensions[i].extensionName) == 0) + } else if (SDL_strcmp(VK_KHR_DISPLAY_EXTENSION_NAME, extensions[i].extensionName) == 0) { hasDisplayExtension = SDL_TRUE; + } } SDL_free(extensions); - if(!hasSurfaceExtension) - { - SDL_SetError("Installed Vulkan doesn't implement the " - VK_KHR_SURFACE_EXTENSION_NAME " extension"); + if (!hasSurfaceExtension) { + SDL_SetError("Installed Vulkan doesn't implement the " VK_KHR_SURFACE_EXTENSION_NAME " extension"); goto fail; - } - else if(!hasDisplayExtension) - { - SDL_SetError("Installed Vulkan doesn't implement the " - VK_KHR_DISPLAY_EXTENSION_NAME "extension"); + } else if (!hasDisplayExtension) { + SDL_SetError("Installed Vulkan doesn't implement the " VK_KHR_DISPLAY_EXTENSION_NAME "extension"); goto fail; } return 0; @@ -115,38 +112,35 @@ fail: void VIVANTE_Vulkan_UnloadLibrary(_THIS) { - if(_this->vulkan_config.loader_handle) - { + if (_this->vulkan_config.loader_handle) { SDL_UnloadObject(_this->vulkan_config.loader_handle); _this->vulkan_config.loader_handle = NULL; } } SDL_bool VIVANTE_Vulkan_GetInstanceExtensions(_THIS, - SDL_Window *window, - unsigned *count, - const char **names) + SDL_Window *window, + unsigned *count, + const char **names) { static const char *const extensionsForVivante[] = { VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_DISPLAY_EXTENSION_NAME }; - if(!_this->vulkan_config.loader_handle) - { + if (!_this->vulkan_config.loader_handle) { SDL_SetError("Vulkan is not loaded"); return SDL_FALSE; } return SDL_Vulkan_GetInstanceExtensions_Helper( - count, names, SDL_arraysize(extensionsForVivante), - extensionsForVivante); + count, names, SDL_arraysize(extensionsForVivante), + extensionsForVivante); } SDL_bool VIVANTE_Vulkan_CreateSurface(_THIS, - SDL_Window *window, - VkInstance instance, - VkSurfaceKHR *surface) + SDL_Window *window, + VkInstance instance, + VkSurfaceKHR *surface) { - if(!_this->vulkan_config.loader_handle) - { + if (!_this->vulkan_config.loader_handle) { SDL_SetError("Vulkan is not loaded"); return SDL_FALSE; } @@ -156,4 +150,3 @@ SDL_bool VIVANTE_Vulkan_CreateSurface(_THIS, #endif /* vi: set ts=4 sw=4 expandtab: */ - diff --git a/SDL2-2.0.12/src/video/vivante/SDL_vivantevulkan.h b/SDL2-2.30.5/src/video/vivante/SDL_vivantevulkan.h similarity index 74% rename from SDL2-2.0.12/src/video/vivante/SDL_vivantevulkan.h rename to SDL2-2.30.5/src/video/vivante/SDL_vivantevulkan.h index 764ae2e..4fb6964 100644 --- a/SDL2-2.0.12/src/video/vivante/SDL_vivantevulkan.h +++ b/SDL2-2.30.5/src/video/vivante/SDL_vivantevulkan.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -32,22 +32,21 @@ #include "../SDL_vulkan_internal.h" #include "../SDL_sysvideo.h" -#if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_VIVANTE +#if defined(SDL_VIDEO_VULKAN) && defined(SDL_VIDEO_DRIVER_VIVANTE) int VIVANTE_Vulkan_LoadLibrary(_THIS, const char *path); void VIVANTE_Vulkan_UnloadLibrary(_THIS); SDL_bool VIVANTE_Vulkan_GetInstanceExtensions(_THIS, - SDL_Window *window, - unsigned *count, - const char **names); + SDL_Window *window, + unsigned *count, + const char **names); SDL_bool VIVANTE_Vulkan_CreateSurface(_THIS, - SDL_Window *window, - VkInstance instance, - VkSurfaceKHR *surface); + SDL_Window *window, + VkInstance instance, + VkSurfaceKHR *surface); #endif #endif /* SDL_vivantevulkan_h_ */ /* vi: set ts=4 sw=4 expandtab: */ - diff --git a/SDL2-2.30.5/src/video/wayland/SDL_waylandclipboard.c b/SDL2-2.30.5/src/video/wayland/SDL_waylandclipboard.c new file mode 100644 index 0000000..fc3d285 --- /dev/null +++ b/SDL2-2.30.5/src/video/wayland/SDL_waylandclipboard.c @@ -0,0 +1,204 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_WAYLAND + +#include "SDL_waylanddatamanager.h" +#include "SDL_waylandevents_c.h" +#include "SDL_waylandclipboard.h" + +int Wayland_SetClipboardText(_THIS, const char *text) +{ + SDL_VideoData *video_data = NULL; + SDL_WaylandDataDevice *data_device = NULL; + + int status = 0; + + if (!_this || !_this->driverdata) { + status = SDL_SetError("Video driver uninitialized"); + } else { + video_data = _this->driverdata; + if (video_data->input && video_data->input->data_device) { + data_device = video_data->input->data_device; + if (text[0] != '\0') { + SDL_WaylandDataSource *source = Wayland_data_source_create(_this); + Wayland_data_source_add_data(source, TEXT_MIME, text, + SDL_strlen(text)); + + status = Wayland_data_device_set_selection(data_device, source); + if (status != 0) { + Wayland_data_source_destroy(source); + } + } else { + status = Wayland_data_device_clear_selection(data_device); + } + } + } + + return status; +} + +int Wayland_SetPrimarySelectionText(_THIS, const char *text) +{ + SDL_VideoData *video_data = NULL; + SDL_WaylandPrimarySelectionDevice *primary_selection_device = NULL; + + int status = 0; + + if (!_this || !_this->driverdata) { + status = SDL_SetError("Video driver uninitialized"); + } else { + video_data = _this->driverdata; + if (video_data->input && video_data->input->primary_selection_device) { + primary_selection_device = video_data->input->primary_selection_device; + if (text[0] != '\0') { + SDL_WaylandPrimarySelectionSource *source = Wayland_primary_selection_source_create(_this); + Wayland_primary_selection_source_add_data(source, TEXT_MIME, text, + SDL_strlen(text)); + + status = Wayland_primary_selection_device_set_selection(primary_selection_device, + source); + if (status != 0) { + Wayland_primary_selection_source_destroy(source); + } + } else { + status = Wayland_primary_selection_device_clear_selection(primary_selection_device); + } + } + } + + return status; +} + +char *Wayland_GetClipboardText(_THIS) +{ + SDL_VideoData *video_data = NULL; + SDL_WaylandDataDevice *data_device = NULL; + + char *text = NULL; + size_t length = 0; + + if (!_this || !_this->driverdata) { + SDL_SetError("Video driver uninitialized"); + } else { + video_data = _this->driverdata; + if (video_data->input && video_data->input->data_device) { + data_device = video_data->input->data_device; + /* Prefer own selection, if not canceled */ + if (Wayland_data_source_has_mime( + data_device->selection_source, TEXT_MIME)) { + text = Wayland_data_source_get_data(data_device->selection_source, + &length, TEXT_MIME, SDL_TRUE); + } else if (Wayland_data_offer_has_mime( + data_device->selection_offer, TEXT_MIME)) { + text = Wayland_data_offer_receive(data_device->selection_offer, + &length, TEXT_MIME, SDL_TRUE); + } + } + } + + if (!text) { + text = SDL_strdup(""); + } + + return text; +} + +char *Wayland_GetPrimarySelectionText(_THIS) +{ + SDL_VideoData *video_data = NULL; + SDL_WaylandPrimarySelectionDevice *primary_selection_device = NULL; + + char *text = NULL; + size_t length = 0; + + if (!_this || !_this->driverdata) { + SDL_SetError("Video driver uninitialized"); + } else { + video_data = _this->driverdata; + if (video_data->input && video_data->input->primary_selection_device) { + primary_selection_device = video_data->input->primary_selection_device; + /* Prefer own selection, if not canceled */ + if (Wayland_primary_selection_source_has_mime( + primary_selection_device->selection_source, TEXT_MIME)) { + text = Wayland_primary_selection_source_get_data(primary_selection_device->selection_source, + &length, TEXT_MIME, SDL_TRUE); + } else if (Wayland_primary_selection_offer_has_mime( + primary_selection_device->selection_offer, TEXT_MIME)) { + text = Wayland_primary_selection_offer_receive(primary_selection_device->selection_offer, + &length, TEXT_MIME, SDL_TRUE); + } + } + } + + if (!text) { + text = SDL_strdup(""); + } + + return text; +} + +SDL_bool Wayland_HasClipboardText(_THIS) +{ + SDL_VideoData *video_data = NULL; + SDL_WaylandDataDevice *data_device = NULL; + + SDL_bool result = SDL_FALSE; + if (!_this || !_this->driverdata) { + SDL_SetError("Video driver uninitialized"); + } else { + video_data = _this->driverdata; + if (video_data->input && video_data->input->data_device) { + data_device = video_data->input->data_device; + result = result || + Wayland_data_source_has_mime(data_device->selection_source, TEXT_MIME) || + Wayland_data_offer_has_mime(data_device->selection_offer, TEXT_MIME); + } + } + return result; +} + +SDL_bool Wayland_HasPrimarySelectionText(_THIS) +{ + SDL_VideoData *video_data = NULL; + SDL_WaylandPrimarySelectionDevice *primary_selection_device = NULL; + + SDL_bool result = SDL_FALSE; + if (!_this || !_this->driverdata) { + SDL_SetError("Video driver uninitialized"); + } else { + video_data = _this->driverdata; + if (video_data->input && video_data->input->primary_selection_device) { + primary_selection_device = video_data->input->primary_selection_device; + result = result || + Wayland_primary_selection_source_has_mime( + primary_selection_device->selection_source, TEXT_MIME) || + Wayland_primary_selection_offer_has_mime( + primary_selection_device->selection_offer, TEXT_MIME); + } + } + return result; +} + +#endif /* SDL_VIDEO_DRIVER_WAYLAND */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/wayland/SDL_waylandclipboard.h b/SDL2-2.30.5/src/video/wayland/SDL_waylandclipboard.h similarity index 83% rename from SDL2-2.0.12/src/video/wayland/SDL_waylandclipboard.h rename to SDL2-2.30.5/src/video/wayland/SDL_waylandclipboard.h index d82af23..012bf82 100644 --- a/SDL2-2.0.12/src/video/wayland/SDL_waylandclipboard.h +++ b/SDL2-2.30.5/src/video/wayland/SDL_waylandclipboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,6 +26,9 @@ extern int Wayland_SetClipboardText(_THIS, const char *text); extern char *Wayland_GetClipboardText(_THIS); extern SDL_bool Wayland_HasClipboardText(_THIS); +extern int Wayland_SetPrimarySelectionText(_THIS, const char *text); +extern char *Wayland_GetPrimarySelectionText(_THIS); +extern SDL_bool Wayland_HasPrimarySelectionText(_THIS); #endif /* SDL_waylandclipboard_h_ */ diff --git a/SDL2-2.30.5/src/video/wayland/SDL_waylanddatamanager.c b/SDL2-2.30.5/src/video/wayland/SDL_waylanddatamanager.c new file mode 100644 index 0000000..8839e23 --- /dev/null +++ b/SDL2-2.30.5/src/video/wayland/SDL_waylanddatamanager.c @@ -0,0 +1,708 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_WAYLAND + +#include +#include +#include +#include + +#include "SDL_stdinc.h" +#include "../../core/unix/SDL_poll.h" + +#include "SDL_waylandvideo.h" +#include "SDL_waylanddatamanager.h" +#include "primary-selection-unstable-v1-client-protocol.h" + +/* FIXME: This is arbitrary, but we want this to be less than a frame because + * any longer can potentially spin an infinite loop of PumpEvents (!) + */ +#define PIPE_MS_TIMEOUT 14 + +static ssize_t write_pipe(int fd, const void *buffer, size_t total_length, size_t *pos) +{ + int ready = 0; + ssize_t bytes_written = 0; + ssize_t length = total_length - *pos; + + sigset_t sig_set; + sigset_t old_sig_set; + struct timespec zerotime = { 0 }; + + ready = SDL_IOReady(fd, SDL_IOR_WRITE, PIPE_MS_TIMEOUT); + + sigemptyset(&sig_set); + sigaddset(&sig_set, SIGPIPE); + +#ifdef SDL_THREADS_DISABLED + sigprocmask(SIG_BLOCK, &sig_set, &old_sig_set); +#else + pthread_sigmask(SIG_BLOCK, &sig_set, &old_sig_set); +#endif + + if (ready == 0) { + bytes_written = SDL_SetError("Pipe timeout"); + } else if (ready < 0) { + bytes_written = SDL_SetError("Pipe select error"); + } else { + if (length > 0) { + bytes_written = write(fd, (Uint8 *)buffer + *pos, SDL_min(length, PIPE_BUF)); + } + + if (bytes_written > 0) { + *pos += bytes_written; + } + } + + sigtimedwait(&sig_set, 0, &zerotime); + +#ifdef SDL_THREADS_DISABLED + sigprocmask(SIG_SETMASK, &old_sig_set, NULL); +#else + pthread_sigmask(SIG_SETMASK, &old_sig_set, NULL); +#endif + + return bytes_written; +} + +static ssize_t read_pipe(int fd, void **buffer, size_t *total_length, SDL_bool null_terminate) +{ + int ready = 0; + void *output_buffer = NULL; + char temp[PIPE_BUF]; + size_t new_buffer_length = 0; + ssize_t bytes_read = 0; + size_t pos = 0; + + ready = SDL_IOReady(fd, SDL_IOR_READ, PIPE_MS_TIMEOUT); + + if (ready == 0) { + bytes_read = SDL_SetError("Pipe timeout"); + } else if (ready < 0) { + bytes_read = SDL_SetError("Pipe select error"); + } else { + bytes_read = read(fd, temp, sizeof(temp)); + } + + if (bytes_read > 0) { + pos = *total_length; + *total_length += bytes_read; + + if (null_terminate == SDL_TRUE) { + new_buffer_length = *total_length + 1; + } else { + new_buffer_length = *total_length; + } + + if (!*buffer) { + output_buffer = SDL_malloc(new_buffer_length); + } else { + output_buffer = SDL_realloc(*buffer, new_buffer_length); + } + + if (!output_buffer) { + bytes_read = SDL_OutOfMemory(); + } else { + SDL_memcpy((Uint8 *)output_buffer + pos, temp, bytes_read); + + if (null_terminate == SDL_TRUE) { + SDL_memset((Uint8 *)output_buffer + (new_buffer_length - 1), 0, 1); + } + + *buffer = output_buffer; + } + } + + return bytes_read; +} + +#define MIME_LIST_SIZE 4 + +static const char *mime_conversion_list[MIME_LIST_SIZE][2] = { + { "text/plain", TEXT_MIME }, + { "TEXT", TEXT_MIME }, + { "UTF8_STRING", TEXT_MIME }, + { "STRING", TEXT_MIME } +}; + +const char *Wayland_convert_mime_type(const char *mime_type) +{ + const char *found = mime_type; + + size_t index = 0; + + for (index = 0; index < MIME_LIST_SIZE; ++index) { + if (SDL_strcmp(mime_conversion_list[index][0], mime_type) == 0) { + found = mime_conversion_list[index][1]; + break; + } + } + + return found; +} + +static SDL_MimeDataList *mime_data_list_find(struct wl_list *list, + const char *mime_type) +{ + SDL_MimeDataList *found = NULL; + + SDL_MimeDataList *mime_list = NULL; + wl_list_for_each (mime_list, list, link) { + if (SDL_strcmp(mime_list->mime_type, mime_type) == 0) { + found = mime_list; + break; + } + } + return found; +} + +static int mime_data_list_add(struct wl_list *list, + const char *mime_type, + const void *buffer, size_t length) +{ + int status = 0; + size_t mime_type_length = 0; + SDL_MimeDataList *mime_data = NULL; + void *internal_buffer = NULL; + + if (buffer) { + internal_buffer = SDL_malloc(length); + if (!internal_buffer) { + return SDL_OutOfMemory(); + } + SDL_memcpy(internal_buffer, buffer, length); + } + + mime_data = mime_data_list_find(list, mime_type); + + if (!mime_data) { + mime_data = SDL_calloc(1, sizeof(*mime_data)); + if (!mime_data) { + status = SDL_OutOfMemory(); + } else { + WAYLAND_wl_list_insert(list, &(mime_data->link)); + + mime_type_length = SDL_strlen(mime_type) + 1; + mime_data->mime_type = SDL_malloc(mime_type_length); + if (!mime_data->mime_type) { + status = SDL_OutOfMemory(); + } else { + SDL_memcpy(mime_data->mime_type, mime_type, mime_type_length); + } + } + } + + if (mime_data && buffer && length > 0) { + if (mime_data->data) { + SDL_free(mime_data->data); + } + mime_data->data = internal_buffer; + mime_data->length = length; + } else { + SDL_free(internal_buffer); + } + + return status; +} + +static void mime_data_list_free(struct wl_list *list) +{ + SDL_MimeDataList *mime_data = NULL; + SDL_MimeDataList *next = NULL; + + wl_list_for_each_safe(mime_data, next, list, link) + { + if (mime_data->data) { + SDL_free(mime_data->data); + } + if (mime_data->mime_type) { + SDL_free(mime_data->mime_type); + } + SDL_free(mime_data); + } +} + +static ssize_t Wayland_source_send(SDL_MimeDataList *mime_data, const char *mime_type, int fd) +{ + size_t written_bytes = 0; + ssize_t status = 0; + + if (!mime_data || !mime_data->data) { + status = SDL_SetError("Invalid mime type"); + close(fd); + } else { + while (write_pipe(fd, + mime_data->data, + mime_data->length, + &written_bytes) > 0) { + } + close(fd); + status = written_bytes; + } + return status; +} + +ssize_t Wayland_data_source_send(SDL_WaylandDataSource *source, const char *mime_type, int fd) +{ + SDL_MimeDataList *mime_data = NULL; + + mime_type = Wayland_convert_mime_type(mime_type); + mime_data = mime_data_list_find(&source->mimes, + mime_type); + + return Wayland_source_send(mime_data, mime_type, fd); +} + +ssize_t Wayland_primary_selection_source_send(SDL_WaylandPrimarySelectionSource *source, const char *mime_type, int fd) +{ + SDL_MimeDataList *mime_data = NULL; + + mime_type = Wayland_convert_mime_type(mime_type); + mime_data = mime_data_list_find(&source->mimes, + mime_type); + + return Wayland_source_send(mime_data, mime_type, fd); +} + +int Wayland_data_source_add_data(SDL_WaylandDataSource *source, + const char *mime_type, + const void *buffer, + size_t length) +{ + return mime_data_list_add(&source->mimes, mime_type, buffer, length); +} + +int Wayland_primary_selection_source_add_data(SDL_WaylandPrimarySelectionSource *source, + const char *mime_type, + const void *buffer, + size_t length) +{ + return mime_data_list_add(&source->mimes, mime_type, buffer, length); +} + +SDL_bool Wayland_data_source_has_mime(SDL_WaylandDataSource *source, + const char *mime_type) +{ + SDL_bool found = SDL_FALSE; + + if (source) { + found = mime_data_list_find(&source->mimes, mime_type) != NULL; + } + return found; +} + +SDL_bool Wayland_primary_selection_source_has_mime(SDL_WaylandPrimarySelectionSource *source, + const char *mime_type) +{ + SDL_bool found = SDL_FALSE; + + if (source) { + found = mime_data_list_find(&source->mimes, mime_type) != NULL; + } + return found; +} + +static void *Wayland_source_get_data(SDL_MimeDataList *mime_data, + size_t *length, + SDL_bool null_terminate) +{ + void *buffer = NULL; + + if (mime_data && mime_data->length > 0) { + size_t buffer_length = mime_data->length; + + if (null_terminate == SDL_TRUE) { + ++buffer_length; + } + buffer = SDL_malloc(buffer_length); + if (!buffer) { + *length = SDL_OutOfMemory(); + } else { + *length = mime_data->length; + SDL_memcpy(buffer, mime_data->data, mime_data->length); + if (null_terminate) { + *((Uint8 *)buffer + mime_data->length) = 0; + } + } + } + + return buffer; +} + +void *Wayland_data_source_get_data(SDL_WaylandDataSource *source, + size_t *length, const char *mime_type, + SDL_bool null_terminate) +{ + SDL_MimeDataList *mime_data = NULL; + void *buffer = NULL; + *length = 0; + + if (!source) { + SDL_SetError("Invalid data source"); + } else { + mime_data = mime_data_list_find(&source->mimes, mime_type); + buffer = Wayland_source_get_data(mime_data, length, null_terminate); + } + + return buffer; +} + +void *Wayland_primary_selection_source_get_data(SDL_WaylandPrimarySelectionSource *source, + size_t *length, const char *mime_type, + SDL_bool null_terminate) +{ + SDL_MimeDataList *mime_data = NULL; + void *buffer = NULL; + *length = 0; + + if (!source) { + SDL_SetError("Invalid primary selection source"); + } else { + mime_data = mime_data_list_find(&source->mimes, mime_type); + buffer = Wayland_source_get_data(mime_data, length, null_terminate); + } + + return buffer; +} + +void Wayland_data_source_destroy(SDL_WaylandDataSource *source) +{ + if (source) { + SDL_WaylandDataDevice *data_device = (SDL_WaylandDataDevice *)source->data_device; + if (data_device && (data_device->selection_source == source)) { + data_device->selection_source = NULL; + } + wl_data_source_destroy(source->source); + mime_data_list_free(&source->mimes); + SDL_free(source); + } +} + +void Wayland_primary_selection_source_destroy(SDL_WaylandPrimarySelectionSource *source) +{ + if (source) { + SDL_WaylandPrimarySelectionDevice *primary_selection_device = (SDL_WaylandPrimarySelectionDevice *)source->primary_selection_device; + if (primary_selection_device && (primary_selection_device->selection_source == source)) { + primary_selection_device->selection_source = NULL; + } + zwp_primary_selection_source_v1_destroy(source->source); + mime_data_list_free(&source->mimes); + SDL_free(source); + } +} + +void *Wayland_data_offer_receive(SDL_WaylandDataOffer *offer, + size_t *length, const char *mime_type, + SDL_bool null_terminate) +{ + SDL_WaylandDataDevice *data_device = NULL; + + int pipefd[2]; + void *buffer = NULL; + *length = 0; + + if (!offer) { + SDL_SetError("Invalid data offer"); + return NULL; + } + data_device = offer->data_device; + if (!data_device) { + SDL_SetError("Data device not initialized"); + } else if (pipe2(pipefd, O_CLOEXEC | O_NONBLOCK) == -1) { + SDL_SetError("Could not read pipe"); + } else { + wl_data_offer_receive(offer->offer, mime_type, pipefd[1]); + + /* TODO: Needs pump and flush? */ + WAYLAND_wl_display_flush(data_device->video_data->display); + + close(pipefd[1]); + + while (read_pipe(pipefd[0], &buffer, length, null_terminate) > 0) { + } + close(pipefd[0]); + } + return buffer; +} + +void *Wayland_primary_selection_offer_receive(SDL_WaylandPrimarySelectionOffer *offer, + size_t *length, const char *mime_type, + SDL_bool null_terminate) +{ + SDL_WaylandPrimarySelectionDevice *primary_selection_device = NULL; + + int pipefd[2]; + void *buffer = NULL; + *length = 0; + + if (!offer) { + SDL_SetError("Invalid data offer"); + return NULL; + } + primary_selection_device = offer->primary_selection_device; + if (!primary_selection_device) { + SDL_SetError("Primary selection device not initialized"); + } else if (pipe2(pipefd, O_CLOEXEC | O_NONBLOCK) == -1) { + SDL_SetError("Could not read pipe"); + } else { + zwp_primary_selection_offer_v1_receive(offer->offer, mime_type, pipefd[1]); + + /* TODO: Needs pump and flush? */ + WAYLAND_wl_display_flush(primary_selection_device->video_data->display); + + close(pipefd[1]); + + while (read_pipe(pipefd[0], &buffer, length, null_terminate) > 0) { + } + close(pipefd[0]); + } + return buffer; +} + +int Wayland_data_offer_add_mime(SDL_WaylandDataOffer *offer, + const char *mime_type) +{ + return mime_data_list_add(&offer->mimes, mime_type, NULL, 0); +} + +int Wayland_primary_selection_offer_add_mime(SDL_WaylandPrimarySelectionOffer *offer, + const char *mime_type) +{ + return mime_data_list_add(&offer->mimes, mime_type, NULL, 0); +} + +SDL_bool Wayland_data_offer_has_mime(SDL_WaylandDataOffer *offer, + const char *mime_type) +{ + SDL_bool found = SDL_FALSE; + + if (offer) { + found = mime_data_list_find(&offer->mimes, mime_type) != NULL; + } + return found; +} + +SDL_bool Wayland_primary_selection_offer_has_mime(SDL_WaylandPrimarySelectionOffer *offer, + const char *mime_type) +{ + SDL_bool found = SDL_FALSE; + + if (offer) { + found = mime_data_list_find(&offer->mimes, mime_type) != NULL; + } + return found; +} + +void Wayland_data_offer_destroy(SDL_WaylandDataOffer *offer) +{ + if (offer) { + wl_data_offer_destroy(offer->offer); + mime_data_list_free(&offer->mimes); + SDL_free(offer); + } +} + +void Wayland_primary_selection_offer_destroy(SDL_WaylandPrimarySelectionOffer *offer) +{ + if (offer) { + zwp_primary_selection_offer_v1_destroy(offer->offer); + mime_data_list_free(&offer->mimes); + SDL_free(offer); + } +} + +int Wayland_data_device_clear_selection(SDL_WaylandDataDevice *data_device) +{ + int status = 0; + + if (!data_device || !data_device->data_device) { + status = SDL_SetError("Invalid Data Device"); + } else if (data_device->selection_source) { + wl_data_device_set_selection(data_device->data_device, NULL, 0); + Wayland_data_source_destroy(data_device->selection_source); + data_device->selection_source = NULL; + } + return status; +} + +int Wayland_primary_selection_device_clear_selection(SDL_WaylandPrimarySelectionDevice *primary_selection_device) +{ + int status = 0; + + if (!primary_selection_device || !primary_selection_device->primary_selection_device) { + status = SDL_SetError("Invalid Primary Selection Device"); + } else if (primary_selection_device->selection_source) { + zwp_primary_selection_device_v1_set_selection(primary_selection_device->primary_selection_device, + NULL, 0); + Wayland_primary_selection_source_destroy(primary_selection_device->selection_source); + primary_selection_device->selection_source = NULL; + } + return status; +} + +int Wayland_data_device_set_selection(SDL_WaylandDataDevice *data_device, + SDL_WaylandDataSource *source) +{ + int status = 0; + size_t num_offers = 0; + size_t index = 0; + + if (!data_device) { + status = SDL_SetError("Invalid Data Device"); + } else if (!source) { + status = SDL_SetError("Invalid source"); + } else { + SDL_MimeDataList *mime_data = NULL; + + wl_list_for_each (mime_data, &(source->mimes), link) { + wl_data_source_offer(source->source, + mime_data->mime_type); + + /* TODO - Improve system for multiple mime types to same data */ + for (index = 0; index < MIME_LIST_SIZE; ++index) { + if (SDL_strcmp(mime_conversion_list[index][1], mime_data->mime_type) == 0) { + wl_data_source_offer(source->source, + mime_conversion_list[index][0]); + } + } + /* */ + + ++num_offers; + } + + if (num_offers == 0) { + Wayland_data_device_clear_selection(data_device); + status = SDL_SetError("No mime data"); + } else { + /* Only set if there is a valid serial if not set it later */ + if (data_device->selection_serial != 0) { + wl_data_device_set_selection(data_device->data_device, + source->source, + data_device->selection_serial); + } + if (data_device->selection_source) { + Wayland_data_source_destroy(data_device->selection_source); + } + data_device->selection_source = source; + source->data_device = data_device; + } + } + + return status; +} + +int Wayland_primary_selection_device_set_selection(SDL_WaylandPrimarySelectionDevice *primary_selection_device, + SDL_WaylandPrimarySelectionSource *source) +{ + int status = 0; + size_t num_offers = 0; + size_t index = 0; + + if (!primary_selection_device) { + status = SDL_SetError("Invalid Primary Selection Device"); + } else if (!source) { + status = SDL_SetError("Invalid source"); + } else { + SDL_MimeDataList *mime_data = NULL; + + wl_list_for_each (mime_data, &(source->mimes), link) { + zwp_primary_selection_source_v1_offer(source->source, + mime_data->mime_type); + + /* TODO - Improve system for multiple mime types to same data */ + for (index = 0; index < MIME_LIST_SIZE; ++index) { + if (SDL_strcmp(mime_conversion_list[index][1], mime_data->mime_type) == 0) { + zwp_primary_selection_source_v1_offer(source->source, + mime_conversion_list[index][0]); + } + } + /* */ + + ++num_offers; + } + + if (num_offers == 0) { + Wayland_primary_selection_device_clear_selection(primary_selection_device); + status = SDL_SetError("No mime data"); + } else { + /* Only set if there is a valid serial if not set it later */ + if (primary_selection_device->selection_serial != 0) { + zwp_primary_selection_device_v1_set_selection(primary_selection_device->primary_selection_device, + source->source, + primary_selection_device->selection_serial); + } + if (primary_selection_device->selection_source) { + Wayland_primary_selection_source_destroy(primary_selection_device->selection_source); + } + primary_selection_device->selection_source = source; + source->primary_selection_device = primary_selection_device; + } + } + + return status; +} + +int Wayland_data_device_set_serial(SDL_WaylandDataDevice *data_device, + uint32_t serial) +{ + int status = -1; + if (data_device) { + status = 0; + + /* If there was no serial and there is a pending selection set it now. */ + if (data_device->selection_serial == 0 && data_device->selection_source) { + wl_data_device_set_selection(data_device->data_device, + data_device->selection_source->source, + data_device->selection_serial); + } + + data_device->selection_serial = serial; + } + + return status; +} + +int Wayland_primary_selection_device_set_serial(SDL_WaylandPrimarySelectionDevice *primary_selection_device, + uint32_t serial) +{ + int status = -1; + if (primary_selection_device) { + status = 0; + + /* If there was no serial and there is a pending selection set it now. */ + if (primary_selection_device->selection_serial == 0 && primary_selection_device->selection_source) { + zwp_primary_selection_device_v1_set_selection(primary_selection_device->primary_selection_device, + primary_selection_device->selection_source->source, + primary_selection_device->selection_serial); + } + + primary_selection_device->selection_serial = serial; + } + + return status; +} + +#endif /* SDL_VIDEO_DRIVER_WAYLAND */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/wayland/SDL_waylanddatamanager.h b/SDL2-2.30.5/src/video/wayland/SDL_waylanddatamanager.h new file mode 100644 index 0000000..496de21 --- /dev/null +++ b/SDL2-2.30.5/src/video/wayland/SDL_waylanddatamanager.h @@ -0,0 +1,161 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifndef SDL_waylanddatamanager_h_ +#define SDL_waylanddatamanager_h_ + +#include "SDL_waylandvideo.h" +#include "SDL_waylandwindow.h" + +#define TEXT_MIME "text/plain;charset=utf-8" +#define FILE_MIME "text/uri-list" +#define FILE_PORTAL_MIME "application/vnd.portal.filetransfer" + +typedef struct +{ + char *mime_type; + void *data; + size_t length; + struct wl_list link; +} SDL_MimeDataList; + +typedef struct +{ + struct wl_data_source *source; + struct wl_list mimes; + void *data_device; +} SDL_WaylandDataSource; + +typedef struct +{ + struct zwp_primary_selection_source_v1 *source; + struct wl_list mimes; + void *primary_selection_device; +} SDL_WaylandPrimarySelectionSource; + +typedef struct +{ + struct wl_data_offer *offer; + struct wl_list mimes; + void *data_device; +} SDL_WaylandDataOffer; + +typedef struct +{ + struct zwp_primary_selection_offer_v1 *offer; + struct wl_list mimes; + void *primary_selection_device; +} SDL_WaylandPrimarySelectionOffer; + +typedef struct +{ + struct wl_data_device *data_device; + SDL_VideoData *video_data; + + /* Drag and Drop */ + uint32_t drag_serial; + SDL_WaylandDataOffer *drag_offer; + SDL_WaylandDataOffer *selection_offer; + SDL_Window *dnd_window; + + /* Clipboard and Primary Selection */ + uint32_t selection_serial; + SDL_WaylandDataSource *selection_source; +} SDL_WaylandDataDevice; + +typedef struct +{ + struct zwp_primary_selection_device_v1 *primary_selection_device; + SDL_VideoData *video_data; + + uint32_t selection_serial; + SDL_WaylandPrimarySelectionSource *selection_source; + SDL_WaylandPrimarySelectionOffer *selection_offer; +} SDL_WaylandPrimarySelectionDevice; + +extern const char *Wayland_convert_mime_type(const char *mime_type); + +/* Wayland Data Source / Primary Selection Source - (Sending) */ +extern SDL_WaylandDataSource *Wayland_data_source_create(_THIS); +extern SDL_WaylandPrimarySelectionSource *Wayland_primary_selection_source_create(_THIS); +extern ssize_t Wayland_data_source_send(SDL_WaylandDataSource *source, + const char *mime_type, int fd); +extern ssize_t Wayland_primary_selection_source_send(SDL_WaylandPrimarySelectionSource *source, + const char *mime_type, int fd); +extern int Wayland_data_source_add_data(SDL_WaylandDataSource *source, + const char *mime_type, + const void *buffer, + size_t length); +extern int Wayland_primary_selection_source_add_data(SDL_WaylandPrimarySelectionSource *source, + const char *mime_type, + const void *buffer, + size_t length); +extern SDL_bool Wayland_data_source_has_mime(SDL_WaylandDataSource *source, + const char *mime_type); +extern SDL_bool Wayland_primary_selection_source_has_mime(SDL_WaylandPrimarySelectionSource *source, + const char *mime_type); +extern void *Wayland_data_source_get_data(SDL_WaylandDataSource *source, + size_t *length, + const char *mime_type, + SDL_bool null_terminate); +extern void *Wayland_primary_selection_source_get_data(SDL_WaylandPrimarySelectionSource *source, + size_t *length, + const char *mime_type, + SDL_bool null_terminate); +extern void Wayland_data_source_destroy(SDL_WaylandDataSource *source); +extern void Wayland_primary_selection_source_destroy(SDL_WaylandPrimarySelectionSource *source); + +/* Wayland Data / Primary Selection Offer - (Receiving) */ +extern void *Wayland_data_offer_receive(SDL_WaylandDataOffer *offer, + size_t *length, + const char *mime_type, + SDL_bool null_terminate); +extern void *Wayland_primary_selection_offer_receive(SDL_WaylandPrimarySelectionOffer *offer, + size_t *length, + const char *mime_type, + SDL_bool null_terminate); +extern SDL_bool Wayland_data_offer_has_mime(SDL_WaylandDataOffer *offer, + const char *mime_type); +extern SDL_bool Wayland_primary_selection_offer_has_mime(SDL_WaylandPrimarySelectionOffer *offer, + const char *mime_type); +extern int Wayland_data_offer_add_mime(SDL_WaylandDataOffer *offer, + const char *mime_type); +extern int Wayland_primary_selection_offer_add_mime(SDL_WaylandPrimarySelectionOffer *offer, + const char *mime_type); +extern void Wayland_data_offer_destroy(SDL_WaylandDataOffer *offer); +extern void Wayland_primary_selection_offer_destroy(SDL_WaylandPrimarySelectionOffer *offer); + +/* Clipboard / Primary Selection */ +extern int Wayland_data_device_clear_selection(SDL_WaylandDataDevice *device); +extern int Wayland_primary_selection_device_clear_selection(SDL_WaylandPrimarySelectionDevice *device); +extern int Wayland_data_device_set_selection(SDL_WaylandDataDevice *device, + SDL_WaylandDataSource *source); +extern int Wayland_primary_selection_device_set_selection(SDL_WaylandPrimarySelectionDevice *device, + SDL_WaylandPrimarySelectionSource *source); +extern int Wayland_data_device_set_serial(SDL_WaylandDataDevice *device, + uint32_t serial); +extern int Wayland_primary_selection_device_set_serial(SDL_WaylandPrimarySelectionDevice *device, + uint32_t serial); +#endif /* SDL_waylanddatamanager_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/wayland/SDL_waylanddyn.c b/SDL2-2.30.5/src/video/wayland/SDL_waylanddyn.c similarity index 52% rename from SDL2-2.0.12/src/video/wayland/SDL_waylanddyn.c rename to SDL2-2.30.5/src/video/wayland/SDL_waylanddyn.c index f160094..f7d501a 100644 --- a/SDL2-2.0.12/src/video/wayland/SDL_waylanddyn.c +++ b/SDL2-2.30.5/src/video/wayland/SDL_waylanddyn.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,16 +20,12 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_WAYLAND +#ifdef SDL_VIDEO_DRIVER_WAYLAND #define DEBUG_DYNAMIC_WAYLAND 0 #include "SDL_waylanddyn.h" -#if DEBUG_DYNAMIC_WAYLAND -#include "SDL_log.h" -#endif - #ifdef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC #include "SDL_name.h" @@ -41,79 +37,85 @@ typedef struct const char *libname; } waylanddynlib; -#ifndef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL -#define SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL NULL -#endif -#ifndef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR -#define SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR NULL -#endif -#ifndef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON -#define SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON NULL -#endif - static waylanddynlib waylandlibs[] = { - {NULL, SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC}, - {NULL, SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL}, - {NULL, SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR}, - {NULL, SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON} + { NULL, SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC }, +#ifdef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL + { NULL, SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL }, +#endif +#ifdef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR + { NULL, SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR }, +#endif +#ifdef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON + { NULL, SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON }, +#endif +#ifdef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR + { NULL, SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR }, +#endif + { NULL, NULL } }; -static void * -WAYLAND_GetSym(const char *fnname, int *pHasModule) +static void *WAYLAND_GetSym(const char *fnname, int *pHasModule, SDL_bool required) { - int i; void *fn = NULL; - for (i = 0; i < SDL_TABLESIZE(waylandlibs); i++) { - if (waylandlibs[i].lib != NULL) { - fn = SDL_LoadFunction(waylandlibs[i].lib, fnname); - if (fn != NULL) + waylanddynlib *dynlib; + for (dynlib = waylandlibs; dynlib->libname; dynlib++) { + if (dynlib->lib) { + fn = SDL_LoadFunction(dynlib->lib, fnname); + if (fn) { break; + } } } #if DEBUG_DYNAMIC_WAYLAND - if (fn != NULL) - SDL_Log("WAYLAND: Found '%s' in %s (%p)\n", fnname, waylandlibs[i].libname, fn); - else + if (fn) { + SDL_Log("WAYLAND: Found '%s' in %s (%p)\n", fnname, dynlib->libname, fn); + } else { SDL_Log("WAYLAND: Symbol '%s' NOT FOUND!\n", fnname); + } #endif - if (fn == NULL) - *pHasModule = 0; /* kill this module. */ + if (!fn && required) { + *pHasModule = 0; /* kill this module. */ + } return fn; } +#else + +#include + #endif /* SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC */ /* Define all the function pointers and wrappers... */ -#define SDL_WAYLAND_MODULE(modname) int SDL_WAYLAND_HAVE_##modname = 0; -#define SDL_WAYLAND_SYM(rc,fn,params) SDL_DYNWAYLANDFN_##fn WAYLAND_##fn = NULL; -#define SDL_WAYLAND_INTERFACE(iface) const struct wl_interface *WAYLAND_##iface = NULL; +#define SDL_WAYLAND_MODULE(modname) int SDL_WAYLAND_HAVE_##modname = 0; +#define SDL_WAYLAND_SYM(rc, fn, params) SDL_DYNWAYLANDFN_##fn WAYLAND_##fn = NULL; +#define SDL_WAYLAND_SYM_OPT(rc, fn, params) SDL_DYNWAYLANDFN_##fn WAYLAND_##fn = NULL; +#define SDL_WAYLAND_INTERFACE(iface) const struct wl_interface *WAYLAND_##iface = NULL; #include "SDL_waylandsym.h" static int wayland_load_refcount = 0; -void -SDL_WAYLAND_UnloadSymbols(void) +void SDL_WAYLAND_UnloadSymbols(void) { /* Don't actually unload if more than one module is using the libs... */ if (wayland_load_refcount > 0) { if (--wayland_load_refcount == 0) { -#ifdef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC +#ifdef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC int i; #endif - - /* set all the function pointers to NULL. */ -#define SDL_WAYLAND_MODULE(modname) SDL_WAYLAND_HAVE_##modname = 0; -#define SDL_WAYLAND_SYM(rc,fn,params) WAYLAND_##fn = NULL; -#define SDL_WAYLAND_INTERFACE(iface) WAYLAND_##iface = NULL; -#include "SDL_waylandsym.h" + /* set all the function pointers to NULL. */ +#define SDL_WAYLAND_MODULE(modname) SDL_WAYLAND_HAVE_##modname = 0; +#define SDL_WAYLAND_SYM(rc, fn, params) WAYLAND_##fn = NULL; +#define SDL_WAYLAND_SYM_OPT(rc, fn, params) WAYLAND_##fn = NULL; +#define SDL_WAYLAND_INTERFACE(iface) WAYLAND_##iface = NULL; +#include "SDL_waylandsym.h" #ifdef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC for (i = 0; i < SDL_TABLESIZE(waylandlibs); i++) { - if (waylandlibs[i].lib != NULL) { + if (waylandlibs[i].lib) { SDL_UnloadObject(waylandlibs[i].lib); waylandlibs[i].lib = NULL; } @@ -124,10 +126,9 @@ SDL_WAYLAND_UnloadSymbols(void) } /* returns non-zero if all needed symbols were loaded. */ -int -SDL_WAYLAND_LoadSymbols(void) +int SDL_WAYLAND_LoadSymbols(void) { - int rc = 1; /* always succeed if not using Dynamic WAYLAND stuff. */ + int rc = 1; /* always succeed if not using Dynamic WAYLAND stuff. */ /* deal with multiple modules (dga, wayland, etc) needing these symbols... */ if (wayland_load_refcount++ == 0) { @@ -135,7 +136,7 @@ SDL_WAYLAND_LoadSymbols(void) int i; int *thismod = NULL; for (i = 0; i < SDL_TABLESIZE(waylandlibs); i++) { - if (waylandlibs[i].libname != NULL) { + if (waylandlibs[i].libname) { waylandlibs[i].lib = SDL_LoadObject(waylandlibs[i].libname); } } @@ -143,9 +144,10 @@ SDL_WAYLAND_LoadSymbols(void) #define SDL_WAYLAND_MODULE(modname) SDL_WAYLAND_HAVE_##modname = 1; /* default yes */ #include "SDL_waylandsym.h" -#define SDL_WAYLAND_MODULE(modname) thismod = &SDL_WAYLAND_HAVE_##modname; -#define SDL_WAYLAND_SYM(rc,fn,params) WAYLAND_##fn = (SDL_DYNWAYLANDFN_##fn) WAYLAND_GetSym(#fn,thismod); -#define SDL_WAYLAND_INTERFACE(iface) WAYLAND_##iface = (struct wl_interface *) WAYLAND_GetSym(#iface,thismod); +#define SDL_WAYLAND_MODULE(modname) thismod = &SDL_WAYLAND_HAVE_##modname; +#define SDL_WAYLAND_SYM(rc, fn, params) WAYLAND_##fn = (SDL_DYNWAYLANDFN_##fn)WAYLAND_GetSym(#fn, thismod, SDL_TRUE); +#define SDL_WAYLAND_SYM_OPT(rc, fn, params) WAYLAND_##fn = (SDL_DYNWAYLANDFN_##fn)WAYLAND_GetSym(#fn, thismod, SDL_FALSE); +#define SDL_WAYLAND_INTERFACE(iface) WAYLAND_##iface = (struct wl_interface *)WAYLAND_GetSym(#iface, thismod, SDL_TRUE); #include "SDL_waylandsym.h" if (SDL_WAYLAND_HAVE_WAYLAND_CLIENT) { @@ -157,11 +159,12 @@ SDL_WAYLAND_LoadSymbols(void) rc = 0; } -#else /* no dynamic WAYLAND */ +#else /* no dynamic WAYLAND */ -#define SDL_WAYLAND_MODULE(modname) SDL_WAYLAND_HAVE_##modname = 1; /* default yes */ -#define SDL_WAYLAND_SYM(rc,fn,params) WAYLAND_##fn = fn; -#define SDL_WAYLAND_INTERFACE(iface) WAYLAND_##iface = &iface; +#define SDL_WAYLAND_MODULE(modname) SDL_WAYLAND_HAVE_##modname = 1; /* default yes */ +#define SDL_WAYLAND_SYM(rc, fn, params) WAYLAND_##fn = fn; +#define SDL_WAYLAND_SYM_OPT(rc, fn, params) WAYLAND_##fn = fn; +#define SDL_WAYLAND_INTERFACE(iface) WAYLAND_##iface = &iface; #include "SDL_waylandsym.h" #endif diff --git a/SDL2-2.30.5/src/video/wayland/SDL_waylanddyn.h b/SDL2-2.30.5/src/video/wayland/SDL_waylanddyn.h new file mode 100644 index 0000000..6feb343 --- /dev/null +++ b/SDL2-2.30.5/src/video/wayland/SDL_waylanddyn.h @@ -0,0 +1,188 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ +#ifndef SDL_waylanddyn_h_ +#define SDL_waylanddyn_h_ + +#include "../../SDL_internal.h" + +/* We can't include wayland-client.h here + * but we need some structs from it + */ +struct wl_interface; +struct wl_proxy; +struct wl_event_queue; +struct wl_display; +struct wl_surface; +struct wl_shm; + +/* We also need some for libdecor */ +struct wl_seat; +struct wl_output; +struct libdecor; +struct libdecor_frame; +struct libdecor_state; +struct libdecor_configuration; +struct libdecor_interface; +struct libdecor_frame_interface; +enum libdecor_resize_edge; +enum libdecor_capabilities; +enum libdecor_window_state; + +#include +#include "wayland-cursor.h" +#include "wayland-util.h" +#include "xkbcommon/xkbcommon.h" +#include "xkbcommon/xkbcommon-compose.h" + +/* Must be included before our #defines, see Bugzilla #4957 */ +#include "wayland-client-core.h" + +#define SDL_WAYLAND_CHECK_VERSION(x, y, z) \ + (WAYLAND_VERSION_MAJOR > x || \ + (WAYLAND_VERSION_MAJOR == x && WAYLAND_VERSION_MINOR > y) || \ + (WAYLAND_VERSION_MAJOR == x && WAYLAND_VERSION_MINOR == y && WAYLAND_VERSION_MICRO >= z)) + +#ifdef __cplusplus +extern "C" { +#endif + +int SDL_WAYLAND_LoadSymbols(void); +void SDL_WAYLAND_UnloadSymbols(void); + +#define SDL_WAYLAND_MODULE(modname) extern int SDL_WAYLAND_HAVE_##modname; +#define SDL_WAYLAND_SYM(rc, fn, params) \ + typedef rc(*SDL_DYNWAYLANDFN_##fn) params; \ + extern SDL_DYNWAYLANDFN_##fn WAYLAND_##fn; +#define SDL_WAYLAND_SYM_OPT(rc, fn, params) \ + typedef rc(*SDL_DYNWAYLANDFN_##fn) params; \ + extern SDL_DYNWAYLANDFN_##fn WAYLAND_##fn; +#define SDL_WAYLAND_INTERFACE(iface) extern const struct wl_interface *WAYLAND_##iface; +#include "SDL_waylandsym.h" + +#ifdef __cplusplus +} +#endif + +#ifdef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC + +#if defined(_WAYLAND_CLIENT_H) || defined(WAYLAND_CLIENT_H) +#error Do not include wayland-client ahead of SDL_waylanddyn.h in dynamic loading mode +#endif + +/* wayland-client-protocol.h included from wayland-client.h + * has inline functions that require these to be defined in dynamic loading mode + */ + +#define wl_proxy_create (*WAYLAND_wl_proxy_create) +#define wl_proxy_destroy (*WAYLAND_wl_proxy_destroy) +#define wl_proxy_marshal (*WAYLAND_wl_proxy_marshal) +#define wl_proxy_set_user_data (*WAYLAND_wl_proxy_set_user_data) +#define wl_proxy_get_user_data (*WAYLAND_wl_proxy_get_user_data) +#define wl_proxy_get_version (*WAYLAND_wl_proxy_get_version) +#define wl_proxy_add_listener (*WAYLAND_wl_proxy_add_listener) +#define wl_proxy_marshal_constructor (*WAYLAND_wl_proxy_marshal_constructor) +#define wl_proxy_marshal_constructor_versioned (*WAYLAND_wl_proxy_marshal_constructor_versioned) +#define wl_proxy_set_tag (*WAYLAND_wl_proxy_set_tag) +#define wl_proxy_get_tag (*WAYLAND_wl_proxy_get_tag) +#define wl_proxy_marshal_flags (*WAYLAND_wl_proxy_marshal_flags) +#define wl_proxy_marshal_array_flags (*WAYLAND_wl_proxy_marshal_array_flags) +#define wl_display_reconnect (*WAYLAND_wl_display_reconnect) + +#define wl_seat_interface (*WAYLAND_wl_seat_interface) +#define wl_surface_interface (*WAYLAND_wl_surface_interface) +#define wl_shm_pool_interface (*WAYLAND_wl_shm_pool_interface) +#define wl_buffer_interface (*WAYLAND_wl_buffer_interface) +#define wl_registry_interface (*WAYLAND_wl_registry_interface) +#define wl_region_interface (*WAYLAND_wl_region_interface) +#define wl_pointer_interface (*WAYLAND_wl_pointer_interface) +#define wl_keyboard_interface (*WAYLAND_wl_keyboard_interface) +#define wl_compositor_interface (*WAYLAND_wl_compositor_interface) +#define wl_output_interface (*WAYLAND_wl_output_interface) +#define wl_shm_interface (*WAYLAND_wl_shm_interface) +#define wl_data_device_interface (*WAYLAND_wl_data_device_interface) +#define wl_data_offer_interface (*WAYLAND_wl_data_offer_interface) +#define wl_data_source_interface (*WAYLAND_wl_data_source_interface) +#define wl_data_device_manager_interface (*WAYLAND_wl_data_device_manager_interface) + +/* + * These must be included before libdecor.h, otherwise the libdecor header + * pulls in the system Wayland protocol headers instead of ours. + */ +#include "wayland-client-protocol.h" +#include "wayland-egl.h" + +#ifdef HAVE_LIBDECOR_H +/* Must be included before our defines */ +#include + +#define libdecor_unref (*WAYLAND_libdecor_unref) +#define libdecor_new (*WAYLAND_libdecor_new) +#define libdecor_decorate (*WAYLAND_libdecor_decorate) +#define libdecor_frame_unref (*WAYLAND_libdecor_frame_unref) +#define libdecor_frame_set_title (*WAYLAND_libdecor_frame_set_title) +#define libdecor_frame_set_app_id (*WAYLAND_libdecor_frame_set_app_id) +#define libdecor_frame_set_max_content_size (*WAYLAND_libdecor_frame_set_max_content_size) +#define libdecor_frame_get_max_content_size (*WAYLAND_libdecor_frame_get_max_content_size) +#define libdecor_frame_set_min_content_size (*WAYLAND_libdecor_frame_set_min_content_size) +#define libdecor_frame_get_min_content_size (*WAYLAND_libdecor_frame_get_min_content_size) +#define libdecor_frame_resize (*WAYLAND_libdecor_frame_resize) +#define libdecor_frame_move (*WAYLAND_libdecor_frame_move) +#define libdecor_frame_commit (*WAYLAND_libdecor_frame_commit) +#define libdecor_frame_set_minimized (*WAYLAND_libdecor_frame_set_minimized) +#define libdecor_frame_set_maximized (*WAYLAND_libdecor_frame_set_maximized) +#define libdecor_frame_unset_maximized (*WAYLAND_libdecor_frame_unset_maximized) +#define libdecor_frame_set_fullscreen (*WAYLAND_libdecor_frame_set_fullscreen) +#define libdecor_frame_unset_fullscreen (*WAYLAND_libdecor_frame_unset_fullscreen) +#define libdecor_frame_set_capabilities (*WAYLAND_libdecor_frame_set_capabilities) +#define libdecor_frame_unset_capabilities (*WAYLAND_libdecor_frame_unset_capabilities) +#define libdecor_frame_has_capability (*WAYLAND_libdecor_frame_has_capability) +#define libdecor_frame_set_visibility (*WAYLAND_libdecor_frame_set_visibility) +#define libdecor_frame_is_visible (*WAYLAND_libdecor_frame_is_visible) +#define libdecor_frame_is_floating (*WAYLAND_libdecor_frame_is_floating) +#define libdecor_frame_set_parent (*WAYLAND_libdecor_frame_set_parent) +#define libdecor_frame_get_xdg_surface (*WAYLAND_libdecor_frame_get_xdg_surface) +#define libdecor_frame_get_xdg_toplevel (*WAYLAND_libdecor_frame_get_xdg_toplevel) +#define libdecor_frame_map (*WAYLAND_libdecor_frame_map) +#define libdecor_state_new (*WAYLAND_libdecor_state_new) +#define libdecor_state_free (*WAYLAND_libdecor_state_free) +#define libdecor_configuration_get_content_size (*WAYLAND_libdecor_configuration_get_content_size) +#define libdecor_configuration_get_window_state (*WAYLAND_libdecor_configuration_get_window_state) +#define libdecor_dispatch (*WAYLAND_libdecor_dispatch) +#endif + +#else /* SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC */ + +/* + * These must be included before libdecor.h, otherwise the libdecor header + * pulls in the system Wayland protocol headers instead of ours. + */ +#include "wayland-client-protocol.h" +#include "wayland-egl.h" + +#ifdef HAVE_LIBDECOR_H +#include +#endif + +#endif /* SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC */ + +#endif /* SDL_waylanddyn_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/wayland/SDL_waylandevents.c b/SDL2-2.30.5/src/video/wayland/SDL_waylandevents.c new file mode 100644 index 0000000..9e9c393 --- /dev/null +++ b/SDL2-2.30.5/src/video/wayland/SDL_waylandevents.c @@ -0,0 +1,2890 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_WAYLAND + +#include "SDL_stdinc.h" +#include "SDL_timer.h" +#include "SDL_hints.h" + +#include "../../core/unix/SDL_poll.h" +#include "../../events/SDL_events_c.h" +#include "../../events/SDL_scancode_tables_c.h" +#include "../SDL_sysvideo.h" + +#include "SDL_waylandvideo.h" +#include "SDL_waylandevents_c.h" +#include "SDL_waylandwindow.h" + +#include "pointer-constraints-unstable-v1-client-protocol.h" +#include "relative-pointer-unstable-v1-client-protocol.h" +#include "xdg-shell-client-protocol.h" +#include "keyboard-shortcuts-inhibit-unstable-v1-client-protocol.h" +#include "text-input-unstable-v3-client-protocol.h" +#include "tablet-unstable-v2-client-protocol.h" +#include "primary-selection-unstable-v1-client-protocol.h" + +#ifdef HAVE_LIBDECOR_H +#include +#endif + +#ifdef SDL_INPUT_LINUXEV +#include +#else +#define BTN_LEFT (0x110) +#define BTN_RIGHT (0x111) +#define BTN_MIDDLE (0x112) +#define BTN_SIDE (0x113) +#define BTN_EXTRA (0x114) +#endif +#include +#include +#include +#include +#include +#include "../../events/imKStoUCS.h" +#include "../../events/SDL_keysym_to_scancode_c.h" + +/* Clamp the wl_seat version on older versions of libwayland. */ +#if SDL_WAYLAND_CHECK_VERSION(1, 21, 0) +#define SDL_WL_SEAT_VERSION 8 +#else +#define SDL_WL_SEAT_VERSION 5 +#endif + +/* Weston uses a ratio of 10 units per scroll tick */ +#define WAYLAND_WHEEL_AXIS_UNIT 10 + +struct SDL_WaylandTouchPoint +{ + SDL_TouchID id; + wl_fixed_t x; + wl_fixed_t y; + struct wl_surface *surface; + + struct SDL_WaylandTouchPoint *prev; + struct SDL_WaylandTouchPoint *next; +}; + +struct SDL_WaylandTouchPointList +{ + struct SDL_WaylandTouchPoint *head; + struct SDL_WaylandTouchPoint *tail; +}; + +static struct SDL_WaylandTouchPointList touch_points = { NULL, NULL }; + +static void touch_add(SDL_TouchID id, wl_fixed_t x, wl_fixed_t y, struct wl_surface *surface) +{ + struct SDL_WaylandTouchPoint *tp = SDL_malloc(sizeof(struct SDL_WaylandTouchPoint)); + + tp->id = id; + tp->x = x; + tp->y = y; + tp->surface = surface; + + if (touch_points.tail) { + touch_points.tail->next = tp; + tp->prev = touch_points.tail; + } else { + touch_points.head = tp; + tp->prev = NULL; + } + + touch_points.tail = tp; + tp->next = NULL; +} + +static void touch_update(SDL_TouchID id, wl_fixed_t x, wl_fixed_t y, struct wl_surface **surface) +{ + struct SDL_WaylandTouchPoint *tp = touch_points.head; + + while (tp) { + if (tp->id == id) { + tp->x = x; + tp->y = y; + *surface = tp->surface; + } + + tp = tp->next; + } +} + +static void touch_del(SDL_TouchID id, wl_fixed_t *x, wl_fixed_t *y, struct wl_surface **surface) +{ + struct SDL_WaylandTouchPoint *tp = touch_points.head; + + while (tp) { + if (tp->id == id) { + *x = tp->x; + *y = tp->y; + *surface = tp->surface; + + if (tp->prev) { + tp->prev->next = tp->next; + } else { + touch_points.head = tp->next; + } + + if (tp->next) { + tp->next->prev = tp->prev; + } else { + touch_points.tail = tp->prev; + } + + { + struct SDL_WaylandTouchPoint *next = tp->next; + SDL_free(tp); + tp = next; + } + } else { + tp = tp->next; + } + } +} + +static SDL_bool Wayland_SurfaceHasActiveTouches(struct wl_surface *surface) +{ + struct SDL_WaylandTouchPoint *tp = touch_points.head; + + while (tp) { + if (tp->surface == surface) { + return SDL_TRUE; + } + + tp = tp->next; + } + + return SDL_FALSE; +} + +/* Returns SDL_TRUE if a key repeat event was due */ +static SDL_bool keyboard_repeat_handle(SDL_WaylandKeyboardRepeat *repeat_info, uint32_t elapsed) +{ + SDL_bool ret = SDL_FALSE; + while ((elapsed - repeat_info->next_repeat_ms) < 0x80000000U) { + if (repeat_info->scancode != SDL_SCANCODE_UNKNOWN) { + SDL_SendKeyboardKey(SDL_PRESSED, repeat_info->scancode); + } + if (repeat_info->text[0]) { + SDL_SendKeyboardText(repeat_info->text); + } + repeat_info->next_repeat_ms += 1000 / repeat_info->repeat_rate; + ret = SDL_TRUE; + } + return ret; +} + +static void keyboard_repeat_clear(SDL_WaylandKeyboardRepeat *repeat_info) +{ + if (!repeat_info->is_initialized) { + return; + } + repeat_info->is_key_down = SDL_FALSE; +} + +static void keyboard_repeat_set(SDL_WaylandKeyboardRepeat *repeat_info, uint32_t key, uint32_t wl_press_time, + uint32_t scancode, SDL_bool has_text, char text[8]) +{ + if (!repeat_info->is_initialized || !repeat_info->repeat_rate) { + return; + } + repeat_info->is_key_down = SDL_TRUE; + repeat_info->key = key; + repeat_info->wl_press_time = wl_press_time; + repeat_info->sdl_press_time = SDL_GetTicks(); + repeat_info->next_repeat_ms = repeat_info->repeat_delay; + repeat_info->scancode = scancode; + if (has_text) { + SDL_memcpy(repeat_info->text, text, 8); + } else { + repeat_info->text[0] = '\0'; + } +} + +static uint32_t keyboard_repeat_get_key(SDL_WaylandKeyboardRepeat *repeat_info) +{ + if (repeat_info->is_initialized && repeat_info->is_key_down) { + return repeat_info->key; + } + + return 0; +} + +static void keyboard_repeat_set_text(SDL_WaylandKeyboardRepeat *repeat_info, const char text[8]) +{ + if (repeat_info->is_initialized) { + SDL_memcpy(repeat_info->text, text, 8); + } +} + +static SDL_bool keyboard_repeat_is_set(SDL_WaylandKeyboardRepeat *repeat_info) +{ + return repeat_info->is_initialized && repeat_info->is_key_down; +} + +static SDL_bool keyboard_repeat_key_is_set(SDL_WaylandKeyboardRepeat *repeat_info, uint32_t key) +{ + return repeat_info->is_initialized && repeat_info->is_key_down && key == repeat_info->key; +} + +void Wayland_SendWakeupEvent(_THIS, SDL_Window *window) +{ + SDL_VideoData *d = _this->driverdata; + + /* TODO: Maybe use a pipe to avoid the compositor roundtrip? */ + wl_display_sync(d->display); + WAYLAND_wl_display_flush(d->display); +} + +static int dispatch_queued_events(SDL_VideoData *viddata) +{ + int ret; + + /* + * NOTE: When reconnection is implemented, check if libdecor needs to be + * involved in the reconnection process. + */ +#ifdef HAVE_LIBDECOR_H + if (viddata->shell.libdecor) { + libdecor_dispatch(viddata->shell.libdecor, 0); + } +#endif + + ret = WAYLAND_wl_display_dispatch_pending(viddata->display); + return ret >= 0 ? 1 : ret; +} + +int Wayland_WaitEventTimeout(_THIS, int timeout) +{ + SDL_VideoData *d = _this->driverdata; + struct SDL_WaylandInput *input = d->input; + SDL_bool key_repeat_active = SDL_FALSE; + + WAYLAND_wl_display_flush(d->display); + +#ifdef SDL_USE_IME + if (!d->text_input_manager && SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE) { + SDL_IME_PumpEvents(); + } +#endif + + /* If key repeat is active, we'll need to cap our maximum wait time to handle repeats */ + if (input && keyboard_repeat_is_set(&input->keyboard_repeat)) { + uint32_t elapsed = SDL_GetTicks() - input->keyboard_repeat.sdl_press_time; + if (keyboard_repeat_handle(&input->keyboard_repeat, elapsed)) { + /* A repeat key event was already due */ + return 1; + } else { + uint32_t next_repeat_wait_time = (input->keyboard_repeat.next_repeat_ms - elapsed) + 1; + if (timeout >= 0) { + timeout = SDL_min(timeout, next_repeat_wait_time); + } else { + timeout = next_repeat_wait_time; + } + key_repeat_active = SDL_TRUE; + } + } + + /* wl_display_prepare_read() will return -1 if the default queue is not empty. + * If the default queue is empty, it will prepare us for our SDL_IOReady() call. */ + if (WAYLAND_wl_display_prepare_read(d->display) == 0) { + /* Use SDL_IOR_NO_RETRY to ensure SIGINT will break us out of our wait */ + int err = SDL_IOReady(WAYLAND_wl_display_get_fd(d->display), SDL_IOR_READ | SDL_IOR_NO_RETRY, timeout); + if (err > 0) { + /* There are new events available to read */ + WAYLAND_wl_display_read_events(d->display); + return dispatch_queued_events(d); + } else if (err == 0) { + /* No events available within the timeout */ + WAYLAND_wl_display_cancel_read(d->display); + + /* If key repeat is active, we might have woken up to generate a key event */ + if (key_repeat_active) { + uint32_t elapsed = SDL_GetTicks() - input->keyboard_repeat.sdl_press_time; + if (keyboard_repeat_handle(&input->keyboard_repeat, elapsed)) { + return 1; + } + } + + return 0; + } else { + /* Error returned from poll()/select() */ + WAYLAND_wl_display_cancel_read(d->display); + + if (errno == EINTR) { + /* If the wait was interrupted by a signal, we may have generated a + * SDL_QUIT event. Let the caller know to call SDL_PumpEvents(). */ + return 1; + } else { + return err; + } + } + } else { + /* We already had pending events */ + return dispatch_queued_events(d); + } +} + +void Wayland_PumpEvents(_THIS) +{ + SDL_VideoData *d = _this->driverdata; + struct SDL_WaylandInput *input = d->input; + int err; + +#ifdef SDL_USE_IME + if (!d->text_input_manager && SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE) { + SDL_IME_PumpEvents(); + } +#endif + +#ifdef HAVE_LIBDECOR_H + if (d->shell.libdecor) { + libdecor_dispatch(d->shell.libdecor, 0); + } +#endif + + WAYLAND_wl_display_flush(d->display); + + /* wl_display_prepare_read() will return -1 if the default queue is not empty. + * If the default queue is empty, it will prepare us for our SDL_IOReady() call. */ + if (WAYLAND_wl_display_prepare_read(d->display) == 0) { + if (SDL_IOReady(WAYLAND_wl_display_get_fd(d->display), SDL_IOR_READ, 0) > 0) { + WAYLAND_wl_display_read_events(d->display); + } else { + WAYLAND_wl_display_cancel_read(d->display); + } + } + + /* Dispatch any pre-existing pending events or new events we may have read */ + err = WAYLAND_wl_display_dispatch_pending(d->display); + + if (input && keyboard_repeat_is_set(&input->keyboard_repeat)) { + uint32_t elapsed = SDL_GetTicks() - input->keyboard_repeat.sdl_press_time; + keyboard_repeat_handle(&input->keyboard_repeat, elapsed); + } + + if (err < 0 && !d->display_disconnected) { + /* Something has failed with the Wayland connection -- for example, + * the compositor may have shut down and closed its end of the socket, + * or there is a library-specific error. + * + * Try to recover once, then quit. + */ + if (!Wayland_VideoReconnect(_this)) { + d->display_disconnected = 1; + + /* Only send a single quit message, as application shutdown might call + * SDL_PumpEvents + */ + SDL_SendQuit(); + } + } +} + +static void pointer_handle_motion(void *data, struct wl_pointer *pointer, + uint32_t time, wl_fixed_t sx_w, wl_fixed_t sy_w) +{ + struct SDL_WaylandInput *input = data; + SDL_WindowData *window = input->pointer_focus; + input->sx_w = sx_w; + input->sy_w = sy_w; + if (input->pointer_focus) { + const float sx_f = (float)wl_fixed_to_double(sx_w); + const float sy_f = (float)wl_fixed_to_double(sy_w); + const int sx = (int)SDL_floorf(sx_f * window->pointer_scale_x); + const int sy = (int)SDL_floorf(sy_f * window->pointer_scale_y); + SDL_SendMouseMotion(window->sdlwindow, 0, 0, sx, sy); + } +} + +static void pointer_handle_enter(void *data, struct wl_pointer *pointer, + uint32_t serial, struct wl_surface *surface, + wl_fixed_t sx_w, wl_fixed_t sy_w) +{ + struct SDL_WaylandInput *input = data; + SDL_WindowData *window; + + if (!surface) { + /* enter event for a window we've just destroyed */ + return; + } + + /* check that this surface belongs to one of the SDL windows */ + if (!SDL_WAYLAND_own_surface(surface)) { + return; + } + + /* This handler will be called twice in Wayland 1.4 + * Once for the window surface which has valid user data + * and again for the mouse cursor surface which does not have valid user data + * We ignore the later + */ + + window = (SDL_WindowData *)wl_surface_get_user_data(surface); + + if (window) { + input->pointer_focus = window; + input->pointer_enter_serial = serial; + SDL_SetMouseFocus(window->sdlwindow); + /* In the case of e.g. a pointer confine warp, we may receive an enter + * event with no following motion event, but with the new coordinates + * as part of the enter event. */ + pointer_handle_motion(data, pointer, serial, sx_w, sy_w); + /* If the cursor was changed while our window didn't have pointer + * focus, we might need to trigger another call to + * wl_pointer_set_cursor() for the new cursor to be displayed. */ + SDL_SetCursor(NULL); + } +} + +static void pointer_handle_leave(void *data, struct wl_pointer *pointer, + uint32_t serial, struct wl_surface *surface) +{ + struct SDL_WaylandInput *input = data; + + if (!surface || !SDL_WAYLAND_own_surface(surface)) { + return; + } + + if (input->pointer_focus) { + /* A pointer leave event may be emitted if the compositor hides the pointer in response to receiving a touch event. + * Don't relinquish focus if the surface has active touches, as the compositor is just transitioning from mouse to touch mode. + */ + if (!Wayland_SurfaceHasActiveTouches(surface)) { + SDL_SetMouseFocus(NULL); + } + input->pointer_focus = NULL; + } +} + +static SDL_bool ProcessHitTest(struct SDL_WaylandInput *input, uint32_t serial) +{ + SDL_WindowData *window_data = input->pointer_focus; + SDL_Window *window = window_data->sdlwindow; + + if (window->hit_test) { + const SDL_Point point = { wl_fixed_to_int(input->sx_w), wl_fixed_to_int(input->sy_w) }; + const SDL_HitTestResult rc = window->hit_test(window, &point, window->hit_test_data); + + static const uint32_t directions[] = { + XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT, XDG_TOPLEVEL_RESIZE_EDGE_TOP, + XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT, XDG_TOPLEVEL_RESIZE_EDGE_RIGHT, + XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT, XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM, + XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT, XDG_TOPLEVEL_RESIZE_EDGE_LEFT + }; + +#ifdef HAVE_LIBDECOR_H + static const uint32_t directions_libdecor[] = { + LIBDECOR_RESIZE_EDGE_TOP_LEFT, LIBDECOR_RESIZE_EDGE_TOP, + LIBDECOR_RESIZE_EDGE_TOP_RIGHT, LIBDECOR_RESIZE_EDGE_RIGHT, + LIBDECOR_RESIZE_EDGE_BOTTOM_RIGHT, LIBDECOR_RESIZE_EDGE_BOTTOM, + LIBDECOR_RESIZE_EDGE_BOTTOM_LEFT, LIBDECOR_RESIZE_EDGE_LEFT + }; +#endif + + switch (rc) { + case SDL_HITTEST_DRAGGABLE: +#ifdef HAVE_LIBDECOR_H + if (window_data->shell_surface_type == WAYLAND_SURFACE_LIBDECOR) { + if (window_data->shell_surface.libdecor.frame) { + libdecor_frame_move(window_data->shell_surface.libdecor.frame, input->seat, serial); + } + } else +#endif + if (window_data->shell_surface_type == WAYLAND_SURFACE_XDG_TOPLEVEL) { + if (window_data->shell_surface.xdg.roleobj.toplevel) { + xdg_toplevel_move(window_data->shell_surface.xdg.roleobj.toplevel, + input->seat, + serial); + } + } + return SDL_TRUE; + + case SDL_HITTEST_RESIZE_TOPLEFT: + case SDL_HITTEST_RESIZE_TOP: + case SDL_HITTEST_RESIZE_TOPRIGHT: + case SDL_HITTEST_RESIZE_RIGHT: + case SDL_HITTEST_RESIZE_BOTTOMRIGHT: + case SDL_HITTEST_RESIZE_BOTTOM: + case SDL_HITTEST_RESIZE_BOTTOMLEFT: + case SDL_HITTEST_RESIZE_LEFT: +#ifdef HAVE_LIBDECOR_H + if (window_data->shell_surface_type == WAYLAND_SURFACE_LIBDECOR) { + if (window_data->shell_surface.libdecor.frame) { + libdecor_frame_resize(window_data->shell_surface.libdecor.frame, input->seat, serial, directions_libdecor[rc - SDL_HITTEST_RESIZE_TOPLEFT]); + } + } else +#endif + if (window_data->shell_surface_type == WAYLAND_SURFACE_XDG_TOPLEVEL) { + if (window_data->shell_surface.xdg.roleobj.toplevel) { + xdg_toplevel_resize(window_data->shell_surface.xdg.roleobj.toplevel, + input->seat, + serial, + directions[rc - SDL_HITTEST_RESIZE_TOPLEFT]); + } + } + return SDL_TRUE; + + default: + return SDL_FALSE; + } + } + + return SDL_FALSE; +} + +static void pointer_handle_button_common(struct SDL_WaylandInput *input, uint32_t serial, + uint32_t time, uint32_t button, uint32_t state_w) +{ + SDL_WindowData *window = input->pointer_focus; + enum wl_pointer_button_state state = state_w; + uint32_t sdl_button; + + if (window) { + SDL_VideoData *viddata = window->waylandData; + switch (button) { + case BTN_LEFT: + sdl_button = SDL_BUTTON_LEFT; + if (ProcessHitTest(input, serial)) { + return; /* don't pass this event on to app. */ + } + break; + case BTN_MIDDLE: + sdl_button = SDL_BUTTON_MIDDLE; + break; + case BTN_RIGHT: + sdl_button = SDL_BUTTON_RIGHT; + break; + case BTN_SIDE: + sdl_button = SDL_BUTTON_X1; + break; + case BTN_EXTRA: + sdl_button = SDL_BUTTON_X2; + break; + default: + return; + } + + /* Wayland won't let you "capture" the mouse, but it will + automatically track the mouse outside the window if you + drag outside of it, until you let go of all buttons (even + if you add or remove presses outside the window, as long + as any button is still down, the capture remains) */ + if (state) { /* update our mask of currently-pressed buttons */ + input->buttons_pressed |= SDL_BUTTON(sdl_button); + } else { + input->buttons_pressed &= ~(SDL_BUTTON(sdl_button)); + } + + /* Don't modify the capture flag in relative mode. */ + if (!viddata->relative_mouse_mode) { + if (input->buttons_pressed != 0) { + window->sdlwindow->flags |= SDL_WINDOW_MOUSE_CAPTURE; + } else { + window->sdlwindow->flags &= ~SDL_WINDOW_MOUSE_CAPTURE; + } + } + + Wayland_data_device_set_serial(input->data_device, serial); + Wayland_primary_selection_device_set_serial(input->primary_selection_device, serial); + + SDL_SendMouseButton(window->sdlwindow, 0, + state ? SDL_PRESSED : SDL_RELEASED, sdl_button); + } +} + +static void pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial, + uint32_t time, uint32_t button, uint32_t state_w) +{ + struct SDL_WaylandInput *input = data; + + pointer_handle_button_common(input, serial, time, button, state_w); +} + +static void pointer_handle_axis_common_v1(struct SDL_WaylandInput *input, + uint32_t time, uint32_t axis, wl_fixed_t value) +{ + SDL_WindowData *window = input->pointer_focus; + enum wl_pointer_axis a = axis; + float x, y; + + if (input->pointer_focus) { + switch (a) { + case WL_POINTER_AXIS_VERTICAL_SCROLL: + x = 0; + y = 0 - (float)wl_fixed_to_double(value); + break; + case WL_POINTER_AXIS_HORIZONTAL_SCROLL: + x = (float)wl_fixed_to_double(value); + y = 0; + break; + default: + return; + } + + x /= WAYLAND_WHEEL_AXIS_UNIT; + y /= WAYLAND_WHEEL_AXIS_UNIT; + + SDL_SendMouseWheel(window->sdlwindow, 0, x, y, SDL_MOUSEWHEEL_NORMAL); + } +} + +static void pointer_handle_axis_common(struct SDL_WaylandInput *input, enum SDL_WaylandAxisEvent type, + uint32_t axis, wl_fixed_t value) +{ + enum wl_pointer_axis a = axis; + + if (input->pointer_focus) { + switch (a) { + case WL_POINTER_AXIS_VERTICAL_SCROLL: + switch (type) { + case AXIS_EVENT_VALUE120: + /* + * High resolution scroll event. The spec doesn't state that axis_value120 + * events are limited to one per frame, so the values are accumulated. + */ + if (input->pointer_curr_axis_info.y_axis_type != AXIS_EVENT_VALUE120) { + input->pointer_curr_axis_info.y_axis_type = AXIS_EVENT_VALUE120; + input->pointer_curr_axis_info.y = 0.0f; + } + input->pointer_curr_axis_info.y += 0 - (float)wl_fixed_to_double(value); + break; + case AXIS_EVENT_DISCRETE: + /* + * This is a discrete axis event, so we process it and set the + * flag to ignore future continuous axis events in this frame. + */ + if (input->pointer_curr_axis_info.y_axis_type != AXIS_EVENT_DISCRETE) { + input->pointer_curr_axis_info.y_axis_type = AXIS_EVENT_DISCRETE; + input->pointer_curr_axis_info.y = 0 - (float)wl_fixed_to_double(value); + } + break; + case AXIS_EVENT_CONTINUOUS: + /* Only process continuous events if no discrete events have been received. */ + if (input->pointer_curr_axis_info.y_axis_type == AXIS_EVENT_CONTINUOUS) { + input->pointer_curr_axis_info.y = 0 - (float)wl_fixed_to_double(value); + } + break; + } + break; + case WL_POINTER_AXIS_HORIZONTAL_SCROLL: + switch (type) { + case AXIS_EVENT_VALUE120: + /* + * High resolution scroll event. The spec doesn't state that axis_value120 + * events are limited to one per frame, so the values are accumulated. + */ + if (input->pointer_curr_axis_info.x_axis_type != AXIS_EVENT_VALUE120) { + input->pointer_curr_axis_info.x_axis_type = AXIS_EVENT_VALUE120; + input->pointer_curr_axis_info.x = 0.0f; + } + input->pointer_curr_axis_info.x += (float)wl_fixed_to_double(value); + break; + case AXIS_EVENT_DISCRETE: + /* + * This is a discrete axis event, so we process it and set the + * flag to ignore future continuous axis events in this frame. + */ + if (input->pointer_curr_axis_info.x_axis_type != AXIS_EVENT_DISCRETE) { + input->pointer_curr_axis_info.x_axis_type = AXIS_EVENT_DISCRETE; + input->pointer_curr_axis_info.x = (float)wl_fixed_to_double(value); + } + break; + case AXIS_EVENT_CONTINUOUS: + /* Only process continuous events if no discrete events have been received. */ + if (input->pointer_curr_axis_info.x_axis_type == AXIS_EVENT_CONTINUOUS) { + input->pointer_curr_axis_info.x = (float)wl_fixed_to_double(value); + } + break; + } + break; + } + } +} + +static void pointer_handle_axis(void *data, struct wl_pointer *pointer, + uint32_t time, uint32_t axis, wl_fixed_t value) +{ + struct SDL_WaylandInput *input = data; + + if (wl_seat_get_version(input->seat) >= 5) { + pointer_handle_axis_common(input, AXIS_EVENT_CONTINUOUS, axis, value); + } else { + pointer_handle_axis_common_v1(input, time, axis, value); + } +} + +static void pointer_handle_frame(void *data, struct wl_pointer *pointer) +{ + struct SDL_WaylandInput *input = data; + SDL_WindowData *window = input->pointer_focus; + float x, y; + + switch (input->pointer_curr_axis_info.x_axis_type) { + case AXIS_EVENT_CONTINUOUS: + x = input->pointer_curr_axis_info.x / WAYLAND_WHEEL_AXIS_UNIT; + break; + case AXIS_EVENT_DISCRETE: + x = input->pointer_curr_axis_info.x; + break; + case AXIS_EVENT_VALUE120: + x = input->pointer_curr_axis_info.x / 120.0f; + break; + default: + x = 0.0f; + break; + } + + switch (input->pointer_curr_axis_info.y_axis_type) { + case AXIS_EVENT_CONTINUOUS: + y = input->pointer_curr_axis_info.y / WAYLAND_WHEEL_AXIS_UNIT; + break; + case AXIS_EVENT_DISCRETE: + y = input->pointer_curr_axis_info.y; + break; + case AXIS_EVENT_VALUE120: + y = input->pointer_curr_axis_info.y / 120.0f; + break; + default: + y = 0.0f; + break; + } + + /* clear pointer_curr_axis_info for next frame */ + SDL_memset(&input->pointer_curr_axis_info, 0, sizeof(input->pointer_curr_axis_info)); + + if (x != 0.0f || y != 0.0f) { + SDL_SendMouseWheel(window->sdlwindow, 0, x, y, SDL_MOUSEWHEEL_NORMAL); + } +} + +static void pointer_handle_axis_source(void *data, struct wl_pointer *pointer, + uint32_t axis_source) +{ + /* unimplemented */ +} + +static void pointer_handle_axis_stop(void *data, struct wl_pointer *pointer, + uint32_t time, uint32_t axis) +{ + /* unimplemented */ +} + +static void pointer_handle_axis_discrete(void *data, struct wl_pointer *pointer, + uint32_t axis, int32_t discrete) +{ + struct SDL_WaylandInput *input = data; + + pointer_handle_axis_common(input, AXIS_EVENT_DISCRETE, axis, wl_fixed_from_int(discrete)); +} + +static void pointer_handle_axis_value120(void *data, struct wl_pointer *pointer, + uint32_t axis, int32_t value120) +{ + struct SDL_WaylandInput *input = data; + + pointer_handle_axis_common(input, AXIS_EVENT_VALUE120, axis, wl_fixed_from_int(value120)); +} + +static const struct wl_pointer_listener pointer_listener = { + pointer_handle_enter, + pointer_handle_leave, + pointer_handle_motion, + pointer_handle_button, + pointer_handle_axis, + pointer_handle_frame, /* Version 5 */ + pointer_handle_axis_source, /* Version 5 */ + pointer_handle_axis_stop, /* Version 5 */ + pointer_handle_axis_discrete, /* Version 5 */ + pointer_handle_axis_value120 /* Version 8 */ +}; + +static void touch_handler_down(void *data, struct wl_touch *touch, uint32_t serial, + uint32_t timestamp, struct wl_surface *surface, + int id, wl_fixed_t fx, wl_fixed_t fy) +{ + SDL_WindowData *window_data; + + /* Check that this surface belongs to one of the SDL windows */ + if (!SDL_WAYLAND_own_surface(surface)) { + return; + } + + touch_add(id, fx, fy, surface); + window_data = (SDL_WindowData *)wl_surface_get_user_data(surface); + + if (window_data) { + const double dblx = wl_fixed_to_double(fx) * window_data->pointer_scale_x; + const double dbly = wl_fixed_to_double(fy) * window_data->pointer_scale_y; + const float x = dblx / window_data->sdlwindow->w; + const float y = dbly / window_data->sdlwindow->h; + + SDL_SetMouseFocus(window_data->sdlwindow); + + SDL_SendTouch((SDL_TouchID)(intptr_t)touch, (SDL_FingerID)id, + window_data->sdlwindow, SDL_TRUE, x, y, 1.0f); + } +} + +static void touch_handler_up(void *data, struct wl_touch *touch, uint32_t serial, + uint32_t timestamp, int id) +{ + wl_fixed_t fx = 0, fy = 0; + struct SDL_WaylandInput *input = (struct SDL_WaylandInput *)data; + struct wl_surface *surface = NULL; + + touch_del(id, &fx, &fy, &surface); + + if (surface) { + SDL_WindowData *window_data = (SDL_WindowData *)wl_surface_get_user_data(surface); + + if (window_data) { + const double dblx = wl_fixed_to_double(fx) * window_data->pointer_scale_x; + const double dbly = wl_fixed_to_double(fy) * window_data->pointer_scale_y; + const float x = dblx / window_data->sdlwindow->w; + const float y = dbly / window_data->sdlwindow->h; + + SDL_SendTouch((SDL_TouchID)(intptr_t)touch, (SDL_FingerID)id, + window_data->sdlwindow, SDL_FALSE, x, y, 1.0f); + + /* If the seat lacks pointer focus, the seat's keyboard focus is another window or NULL, this window curently + * has mouse focus, and the surface has no active touch events, consider mouse focus to be lost. + */ + if (!input->pointer_focus && input->keyboard_focus != window_data && + SDL_GetMouseFocus() == window_data->sdlwindow && !Wayland_SurfaceHasActiveTouches(surface)) { + SDL_SetMouseFocus(NULL); + } + } + } +} + +static void touch_handler_motion(void *data, struct wl_touch *touch, uint32_t timestamp, + int id, wl_fixed_t fx, wl_fixed_t fy) +{ + struct wl_surface *surface = NULL; + + touch_update(id, fx, fy, &surface); + + if (surface) { + SDL_WindowData *window_data = (SDL_WindowData *)wl_surface_get_user_data(surface); + + if (window_data) { + const double dblx = wl_fixed_to_double(fx) * window_data->pointer_scale_x; + const double dbly = wl_fixed_to_double(fy) * window_data->pointer_scale_y; + const float x = dblx / window_data->sdlwindow->w; + const float y = dbly / window_data->sdlwindow->h; + + SDL_SendTouchMotion((SDL_TouchID)(intptr_t)touch, (SDL_FingerID)id, + window_data->sdlwindow, x, y, 1.0f); + } + } +} + +static void touch_handler_frame(void *data, struct wl_touch *touch) +{ +} + +static void touch_handler_cancel(void *data, struct wl_touch *touch) +{ +} + +static const struct wl_touch_listener touch_listener = { + touch_handler_down, + touch_handler_up, + touch_handler_motion, + touch_handler_frame, + touch_handler_cancel, + NULL, /* shape */ + NULL, /* orientation */ +}; + +typedef struct Wayland_Keymap +{ + xkb_layout_index_t layout; + SDL_Keycode keymap[SDL_NUM_SCANCODES]; +} Wayland_Keymap; + +static void Wayland_keymap_iter(struct xkb_keymap *keymap, xkb_keycode_t key, void *data) +{ + const xkb_keysym_t *syms; + Wayland_Keymap *sdlKeymap = (Wayland_Keymap *)data; + SDL_Scancode scancode; + + scancode = SDL_GetScancodeFromTable(SDL_SCANCODE_TABLE_XFREE86_2, (key - 8)); + if (scancode == SDL_SCANCODE_UNKNOWN) { + return; + } + + if (WAYLAND_xkb_keymap_key_get_syms_by_level(keymap, key, sdlKeymap->layout, 0, &syms) > 0) { + uint32_t keycode = SDL_KeySymToUcs4(syms[0]); + + if (!keycode) { + const SDL_Scancode sc = SDL_GetScancodeFromKeySym(syms[0], key); + keycode = SDL_GetDefaultKeyFromScancode(sc); + } + + if (keycode) { + sdlKeymap->keymap[scancode] = keycode; + } else { + switch (scancode) { + case SDL_SCANCODE_RETURN: + sdlKeymap->keymap[scancode] = SDLK_RETURN; + break; + case SDL_SCANCODE_ESCAPE: + sdlKeymap->keymap[scancode] = SDLK_ESCAPE; + break; + case SDL_SCANCODE_BACKSPACE: + sdlKeymap->keymap[scancode] = SDLK_BACKSPACE; + break; + case SDL_SCANCODE_TAB: + sdlKeymap->keymap[scancode] = SDLK_TAB; + break; + case SDL_SCANCODE_DELETE: + sdlKeymap->keymap[scancode] = SDLK_DELETE; + break; + default: + sdlKeymap->keymap[scancode] = SDL_SCANCODE_TO_KEYCODE(scancode); + break; + } + } + } +} + +static void keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard, + uint32_t format, int fd, uint32_t size) +{ + struct SDL_WaylandInput *input = data; + char *map_str; + const char *locale; + + if (!data) { + close(fd); + return; + } + + if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) { + close(fd); + return; + } + + map_str = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); + if (map_str == MAP_FAILED) { + close(fd); + return; + } + + if (input->xkb.keymap != NULL) { + /* if there's already a keymap loaded, throw it away rather than leaking it before + * parsing the new one + */ + WAYLAND_xkb_keymap_unref(input->xkb.keymap); + input->xkb.keymap = NULL; + } + input->xkb.keymap = WAYLAND_xkb_keymap_new_from_string(input->display->xkb_context, + map_str, + XKB_KEYMAP_FORMAT_TEXT_V1, + 0); + munmap(map_str, size); + close(fd); + + if (!input->xkb.keymap) { + SDL_SetError("failed to compile keymap\n"); + return; + } + +#define GET_MOD_INDEX(mod) \ + WAYLAND_xkb_keymap_mod_get_index(input->xkb.keymap, XKB_MOD_NAME_##mod) + input->xkb.idx_shift = 1 << GET_MOD_INDEX(SHIFT); + input->xkb.idx_ctrl = 1 << GET_MOD_INDEX(CTRL); + input->xkb.idx_alt = 1 << GET_MOD_INDEX(ALT); + input->xkb.idx_gui = 1 << GET_MOD_INDEX(LOGO); + input->xkb.idx_num = 1 << GET_MOD_INDEX(NUM); + input->xkb.idx_caps = 1 << GET_MOD_INDEX(CAPS); +#undef GET_MOD_INDEX + + if (input->xkb.state != NULL) { + /* if there's already a state, throw it away rather than leaking it before + * trying to create a new one with the new keymap. + */ + WAYLAND_xkb_state_unref(input->xkb.state); + input->xkb.state = NULL; + } + input->xkb.state = WAYLAND_xkb_state_new(input->xkb.keymap); + if (!input->xkb.state) { + SDL_SetError("failed to create XKB state\n"); + WAYLAND_xkb_keymap_unref(input->xkb.keymap); + input->xkb.keymap = NULL; + return; + } + + /* + * Assume that a nameless layout implies a virtual keyboard with an arbitrary layout. + * TODO: Use a better method of detection? + */ + input->keyboard_is_virtual = WAYLAND_xkb_keymap_layout_get_name(input->xkb.keymap, 0) == NULL; + + /* Update the keymap if changed. Virtual keyboards use the default keymap. */ + if (input->xkb.current_group != XKB_GROUP_INVALID) { + Wayland_Keymap keymap; + keymap.layout = input->xkb.current_group; + SDL_GetDefaultKeymap(keymap.keymap); + if (!input->keyboard_is_virtual) { + WAYLAND_xkb_keymap_key_for_each(input->xkb.keymap, + Wayland_keymap_iter, + &keymap); + } + SDL_SetKeymap(0, keymap.keymap, SDL_NUM_SCANCODES, SDL_TRUE); + } + + /* + * See https://blogs.s-osg.org/compose-key-support-weston/ + * for further explanation on dead keys in Wayland. + */ + + /* Look up the preferred locale, falling back to "C" as default */ + locale = SDL_getenv("LC_ALL"); + if (!locale) { + locale = SDL_getenv("LC_CTYPE"); + if (!locale) { + locale = SDL_getenv("LANG"); + if (!locale) { + locale = "C"; + } + } + } + + /* Set up XKB compose table */ + if (input->xkb.compose_table != NULL) { + WAYLAND_xkb_compose_table_unref(input->xkb.compose_table); + input->xkb.compose_table = NULL; + } + input->xkb.compose_table = WAYLAND_xkb_compose_table_new_from_locale(input->display->xkb_context, + locale, XKB_COMPOSE_COMPILE_NO_FLAGS); + if (input->xkb.compose_table) { + /* Set up XKB compose state */ + if (input->xkb.compose_state != NULL) { + WAYLAND_xkb_compose_state_unref(input->xkb.compose_state); + input->xkb.compose_state = NULL; + } + input->xkb.compose_state = WAYLAND_xkb_compose_state_new(input->xkb.compose_table, + XKB_COMPOSE_STATE_NO_FLAGS); + if (!input->xkb.compose_state) { + SDL_SetError("could not create XKB compose state\n"); + WAYLAND_xkb_compose_table_unref(input->xkb.compose_table); + input->xkb.compose_table = NULL; + } + } +} + +/* + * Virtual keyboards can have arbitrary layouts, arbitrary scancodes/keycodes, etc... + * Key presses from these devices must be looked up by their keysym value. + */ +static SDL_Scancode Wayland_get_scancode_from_key(struct SDL_WaylandInput *input, uint32_t key) +{ + SDL_Scancode scancode = SDL_SCANCODE_UNKNOWN; + + if (!input->keyboard_is_virtual) { + scancode = SDL_GetScancodeFromTable(SDL_SCANCODE_TABLE_XFREE86_2, key - 8); + } else { + const xkb_keysym_t *syms; + if (WAYLAND_xkb_keymap_key_get_syms_by_level(input->xkb.keymap, key, input->xkb.current_group, 0, &syms) > 0) { + scancode = SDL_GetScancodeFromKeySym(syms[0], key); + } + } + + return scancode; +} + +static void keyboard_handle_enter(void *data, struct wl_keyboard *keyboard, + uint32_t serial, struct wl_surface *surface, + struct wl_array *keys) +{ + /* Caps Lock not included because it only makes sense to consider modifiers + * that get held down, for the case where a user clicks on an unfocused + * window with a modifier key like Shift pressed, in a situation where the + * application handles Shift+click differently from a click + */ + const SDL_Scancode mod_scancodes[] = { + SDL_SCANCODE_LSHIFT, + SDL_SCANCODE_RSHIFT, + SDL_SCANCODE_LCTRL, + SDL_SCANCODE_RCTRL, + SDL_SCANCODE_LALT, + SDL_SCANCODE_RALT, + SDL_SCANCODE_LGUI, + SDL_SCANCODE_RGUI, + }; + struct SDL_WaylandInput *input = data; + SDL_WindowData *window; + uint32_t *key; + + if (!surface) { + /* enter event for a window we've just destroyed */ + return; + } + + if (!SDL_WAYLAND_own_surface(surface)) { + return; + } + + window = wl_surface_get_user_data(surface); + + if (window) { + input->keyboard_focus = window; + window->keyboard_device = input; + SDL_SetKeyboardFocus(window->sdlwindow); + } +#ifdef SDL_USE_IME + if (!input->text_input) { + SDL_IME_SetFocus(SDL_TRUE); + } +#endif + + wl_array_for_each (key, keys) { + const SDL_Scancode scancode = Wayland_get_scancode_from_key(input, *key + 8); + + if (scancode != SDL_SCANCODE_UNKNOWN) { + uint32_t i; + for (i = 0; i < SDL_arraysize(mod_scancodes); ++i) { + if (mod_scancodes[i] == scancode) { + SDL_SendKeyboardKey(SDL_PRESSED, scancode); + break; + } + } + } + } +} + +static void keyboard_handle_leave(void *data, struct wl_keyboard *keyboard, + uint32_t serial, struct wl_surface *surface) +{ + struct SDL_WaylandInput *input = data; + SDL_WindowData *wind; + SDL_Window *window = NULL; + + if (!surface || !SDL_WAYLAND_own_surface(surface)) { + return; + } + + wind = wl_surface_get_user_data(surface); + if (wind) { + wind->keyboard_device = NULL; + window = wind->sdlwindow; + window->flags &= ~SDL_WINDOW_MOUSE_CAPTURE; + } + + /* Stop key repeat before clearing keyboard focus */ + keyboard_repeat_clear(&input->keyboard_repeat); + + /* This will release any keys still pressed */ + SDL_SetKeyboardFocus(NULL); + input->keyboard_focus = NULL; + +#ifdef SDL_USE_IME + if (!input->text_input) { + SDL_IME_SetFocus(SDL_FALSE); + } +#endif + + /* If the surface had a pointer leave event while still having active touch events, it retained mouse focus. + * Clear it now if all touch events are raised. + */ + if (!input->pointer_focus && SDL_GetMouseFocus() == window && !Wayland_SurfaceHasActiveTouches(surface)) { + SDL_SetMouseFocus(NULL); + } +} + +static SDL_bool keyboard_input_get_text(char text[8], const struct SDL_WaylandInput *input, uint32_t key, Uint8 state, SDL_bool *handled_by_ime) +{ + SDL_WindowData *window = input->keyboard_focus; + const xkb_keysym_t *syms; + xkb_keysym_t sym; + + if (!window || window->keyboard_device != input || !input->xkb.state) { + return SDL_FALSE; + } + + /* TODO: Can this happen? */ + if (WAYLAND_xkb_state_key_get_syms(input->xkb.state, key + 8, &syms) != 1) { + return SDL_FALSE; + } + sym = syms[0]; + +#ifdef SDL_USE_IME + if (SDL_IME_ProcessKeyEvent(sym, key + 8, state)) { + if (handled_by_ime) { + *handled_by_ime = SDL_TRUE; + } + return SDL_TRUE; + } +#endif + + if (state == SDL_RELEASED) { + return SDL_FALSE; + } + + if (input->xkb.compose_state && WAYLAND_xkb_compose_state_feed(input->xkb.compose_state, sym) == XKB_COMPOSE_FEED_ACCEPTED) { + switch (WAYLAND_xkb_compose_state_get_status(input->xkb.compose_state)) { + case XKB_COMPOSE_COMPOSING: + if (handled_by_ime) { + *handled_by_ime = SDL_TRUE; + } + return SDL_TRUE; + case XKB_COMPOSE_CANCELLED: + default: + sym = XKB_KEY_NoSymbol; + break; + case XKB_COMPOSE_NOTHING: + break; + case XKB_COMPOSE_COMPOSED: + sym = WAYLAND_xkb_compose_state_get_one_sym(input->xkb.compose_state); + break; + } + } + + return WAYLAND_xkb_keysym_to_utf8(sym, text, 8) > 0; +} + +static void keyboard_handle_key(void *data, struct wl_keyboard *keyboard, + uint32_t serial, uint32_t time, uint32_t key, + uint32_t state_w) +{ + struct SDL_WaylandInput *input = data; + enum wl_keyboard_key_state state = state_w; + SDL_Scancode scancode = SDL_SCANCODE_UNKNOWN; + char text[8]; + SDL_bool has_text = SDL_FALSE; + SDL_bool handled_by_ime = SDL_FALSE; + + if (state == WL_KEYBOARD_KEY_STATE_PRESSED) { + has_text = keyboard_input_get_text(text, input, key, SDL_PRESSED, &handled_by_ime); + } else { + if (keyboard_repeat_key_is_set(&input->keyboard_repeat, key)) { + /* Send any due key repeat events before stopping the repeat and generating the key up event. + * Compute time based on the Wayland time, as it reports when the release event happened. + * Using SDL_GetTicks would be wrong, as it would report when the release event is processed, + * which may be off if the application hasn't pumped events for a while. + */ + keyboard_repeat_handle(&input->keyboard_repeat, time - input->keyboard_repeat.wl_press_time); + keyboard_repeat_clear(&input->keyboard_repeat); + } + keyboard_input_get_text(text, input, key, SDL_RELEASED, &handled_by_ime); + } + + if (!handled_by_ime) { + scancode = Wayland_get_scancode_from_key(input, key + 8); + SDL_SendKeyboardKey(state == WL_KEYBOARD_KEY_STATE_PRESSED ? SDL_PRESSED : SDL_RELEASED, scancode); + } + + Wayland_data_device_set_serial(input->data_device, serial); + Wayland_primary_selection_device_set_serial(input->primary_selection_device, serial); + + if (state == WL_KEYBOARD_KEY_STATE_PRESSED) { + if (has_text && !(SDL_GetModState() & KMOD_CTRL)) { + if (!handled_by_ime) { + SDL_SendKeyboardText(text); + } + } + if (input->xkb.keymap && WAYLAND_xkb_keymap_key_repeats(input->xkb.keymap, key + 8)) { + keyboard_repeat_set(&input->keyboard_repeat, key, time, scancode, has_text, text); + } + } +} + +static void keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard, + uint32_t serial, uint32_t mods_depressed, + uint32_t mods_latched, uint32_t mods_locked, + uint32_t group) +{ + struct SDL_WaylandInput *input = data; + Wayland_Keymap keymap; + const uint32_t modstate = (mods_depressed | mods_latched | mods_locked); + + if (input->xkb.state == NULL) { + /* if we get a modifier notification before the keymap, there's nothing we can do with the information + */ + return; + } + + WAYLAND_xkb_state_update_mask(input->xkb.state, mods_depressed, mods_latched, + mods_locked, 0, 0, group); + + SDL_ToggleModState(KMOD_NUM, modstate & input->xkb.idx_num); + SDL_ToggleModState(KMOD_CAPS, modstate & input->xkb.idx_caps); + + /* Toggle the modifier states for virtual keyboards, as they may not send key presses. */ + if (input->keyboard_is_virtual) { + SDL_ToggleModState(KMOD_SHIFT, modstate & input->xkb.idx_shift); + SDL_ToggleModState(KMOD_CTRL, modstate & input->xkb.idx_ctrl); + SDL_ToggleModState(KMOD_ALT, modstate & input->xkb.idx_alt); + SDL_ToggleModState(KMOD_GUI, modstate & input->xkb.idx_gui); + } + + /* If a key is repeating, update the text to apply the modifier. */ + if (keyboard_repeat_is_set(&input->keyboard_repeat)) { + char text[8]; + const uint32_t key = keyboard_repeat_get_key(&input->keyboard_repeat); + + if (keyboard_input_get_text(text, input, key, SDL_PRESSED, NULL)) { + keyboard_repeat_set_text(&input->keyboard_repeat, text); + } + } + + if (group == input->xkb.current_group) { + return; + } + + /* The layout changed, remap and fire an event. Virtual keyboards use the default keymap. */ + input->xkb.current_group = group; + keymap.layout = group; + SDL_GetDefaultKeymap(keymap.keymap); + if (!input->keyboard_is_virtual) { + WAYLAND_xkb_keymap_key_for_each(input->xkb.keymap, + Wayland_keymap_iter, + &keymap); + } + SDL_SetKeymap(0, keymap.keymap, SDL_NUM_SCANCODES, SDL_TRUE); +} + +static void keyboard_handle_repeat_info(void *data, struct wl_keyboard *wl_keyboard, + int32_t rate, int32_t delay) +{ + struct SDL_WaylandInput *input = data; + input->keyboard_repeat.repeat_rate = SDL_clamp(rate, 0, 1000); + input->keyboard_repeat.repeat_delay = delay; + input->keyboard_repeat.is_initialized = SDL_TRUE; +} + +static const struct wl_keyboard_listener keyboard_listener = { + keyboard_handle_keymap, + keyboard_handle_enter, + keyboard_handle_leave, + keyboard_handle_key, + keyboard_handle_modifiers, + keyboard_handle_repeat_info, /* Version 4 */ +}; + +static void seat_handle_capabilities(void *data, struct wl_seat *seat, + enum wl_seat_capability caps) +{ + struct SDL_WaylandInput *input = data; + + if ((caps & WL_SEAT_CAPABILITY_POINTER) && !input->pointer) { + input->pointer = wl_seat_get_pointer(seat); + SDL_memset(&input->pointer_curr_axis_info, 0, sizeof(input->pointer_curr_axis_info)); + input->display->pointer = input->pointer; + wl_pointer_set_user_data(input->pointer, input); + wl_pointer_add_listener(input->pointer, &pointer_listener, + input); + } else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && input->pointer) { + wl_pointer_destroy(input->pointer); + input->pointer = NULL; + input->display->pointer = NULL; + } + + if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !input->touch) { + input->touch = wl_seat_get_touch(seat); + SDL_AddTouch((SDL_TouchID)(intptr_t)input->touch, SDL_TOUCH_DEVICE_DIRECT, "wayland_touch"); + wl_touch_set_user_data(input->touch, input); + wl_touch_add_listener(input->touch, &touch_listener, + input); + } else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && input->touch) { + SDL_DelTouch((SDL_TouchID)(intptr_t)input->touch); + wl_touch_destroy(input->touch); + input->touch = NULL; + } + + if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !input->keyboard) { + input->keyboard = wl_seat_get_keyboard(seat); + wl_keyboard_set_user_data(input->keyboard, input); + wl_keyboard_add_listener(input->keyboard, &keyboard_listener, + input); + } else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && input->keyboard) { + wl_keyboard_destroy(input->keyboard); + input->keyboard = NULL; + } +} + +static void seat_handle_name(void *data, struct wl_seat *wl_seat, const char *name) +{ + /* unimplemented */ +} + +static const struct wl_seat_listener seat_listener = { + seat_handle_capabilities, + seat_handle_name, /* Version 2 */ +}; + +static void data_source_handle_target(void *data, struct wl_data_source *wl_data_source, + const char *mime_type) +{ +} + +static void data_source_handle_send(void *data, struct wl_data_source *wl_data_source, + const char *mime_type, int32_t fd) +{ + Wayland_data_source_send((SDL_WaylandDataSource *)data, mime_type, fd); +} + +static void data_source_handle_cancelled(void *data, struct wl_data_source *wl_data_source) +{ + Wayland_data_source_destroy(data); +} + +static void data_source_handle_dnd_drop_performed(void *data, struct wl_data_source *wl_data_source) +{ +} + +static void data_source_handle_dnd_finished(void *data, struct wl_data_source *wl_data_source) +{ +} + +static void data_source_handle_action(void *data, struct wl_data_source *wl_data_source, + uint32_t dnd_action) +{ +} + +static const struct wl_data_source_listener data_source_listener = { + data_source_handle_target, + data_source_handle_send, + data_source_handle_cancelled, + data_source_handle_dnd_drop_performed, /* Version 3 */ + data_source_handle_dnd_finished, /* Version 3 */ + data_source_handle_action, /* Version 3 */ +}; + +static void primary_selection_source_send(void *data, struct zwp_primary_selection_source_v1 *zwp_primary_selection_source_v1, + const char *mime_type, int32_t fd) +{ + Wayland_primary_selection_source_send((SDL_WaylandPrimarySelectionSource *)data, + mime_type, fd); +} + +static void primary_selection_source_cancelled(void *data, struct zwp_primary_selection_source_v1 *zwp_primary_selection_source_v1) +{ + Wayland_primary_selection_source_destroy(data); +} + +static const struct zwp_primary_selection_source_v1_listener primary_selection_source_listener = { + primary_selection_source_send, + primary_selection_source_cancelled, +}; + +SDL_WaylandDataSource *Wayland_data_source_create(_THIS) +{ + SDL_WaylandDataSource *data_source = NULL; + SDL_VideoData *driver_data = NULL; + struct wl_data_source *id = NULL; + + if (!_this || !_this->driverdata) { + SDL_SetError("Video driver uninitialized"); + } else { + driver_data = _this->driverdata; + + if (driver_data->data_device_manager) { + id = wl_data_device_manager_create_data_source( + driver_data->data_device_manager); + } + + if (!id) { + SDL_SetError("Wayland unable to create data source"); + } else { + data_source = SDL_calloc(1, sizeof(*data_source)); + if (!data_source) { + SDL_OutOfMemory(); + wl_data_source_destroy(id); + } else { + WAYLAND_wl_list_init(&(data_source->mimes)); + data_source->source = id; + wl_data_source_set_user_data(id, data_source); + wl_data_source_add_listener(id, &data_source_listener, + data_source); + } + } + } + return data_source; +} + +SDL_WaylandPrimarySelectionSource *Wayland_primary_selection_source_create(_THIS) +{ + SDL_WaylandPrimarySelectionSource *primary_selection_source = NULL; + SDL_VideoData *driver_data = NULL; + struct zwp_primary_selection_source_v1 *id = NULL; + + if (!_this || !_this->driverdata) { + SDL_SetError("Video driver uninitialized"); + } else { + driver_data = _this->driverdata; + + if (driver_data->primary_selection_device_manager) { + id = zwp_primary_selection_device_manager_v1_create_source( + driver_data->primary_selection_device_manager); + } + + if (!id) { + SDL_SetError("Wayland unable to create primary selection source"); + } else { + primary_selection_source = SDL_calloc(1, sizeof(*primary_selection_source)); + if (!primary_selection_source) { + SDL_OutOfMemory(); + zwp_primary_selection_source_v1_destroy(id); + } else { + WAYLAND_wl_list_init(&(primary_selection_source->mimes)); + primary_selection_source->source = id; + zwp_primary_selection_source_v1_add_listener(id, &primary_selection_source_listener, + primary_selection_source); + } + } + } + return primary_selection_source; +} + +static void data_offer_handle_offer(void *data, struct wl_data_offer *wl_data_offer, + const char *mime_type) +{ + SDL_WaylandDataOffer *offer = data; + Wayland_data_offer_add_mime(offer, mime_type); +} + +static void data_offer_handle_source_actions(void *data, struct wl_data_offer *wl_data_offer, + uint32_t source_actions) +{ +} + +static void data_offer_handle_actions(void *data, struct wl_data_offer *wl_data_offer, + uint32_t dnd_action) +{ +} + +static const struct wl_data_offer_listener data_offer_listener = { + data_offer_handle_offer, + data_offer_handle_source_actions, /* Version 3 */ + data_offer_handle_actions, /* Version 3 */ +}; + +static void primary_selection_offer_handle_offer(void *data, struct zwp_primary_selection_offer_v1 *zwp_primary_selection_offer_v1, + const char *mime_type) +{ + SDL_WaylandPrimarySelectionOffer *offer = data; + Wayland_primary_selection_offer_add_mime(offer, mime_type); +} + +static const struct zwp_primary_selection_offer_v1_listener primary_selection_offer_listener = { + primary_selection_offer_handle_offer, +}; + +static void data_device_handle_data_offer(void *data, struct wl_data_device *wl_data_device, + struct wl_data_offer *id) +{ + SDL_WaylandDataOffer *data_offer = NULL; + + data_offer = SDL_calloc(1, sizeof(*data_offer)); + if (!data_offer) { + SDL_OutOfMemory(); + } else { + data_offer->offer = id; + data_offer->data_device = data; + WAYLAND_wl_list_init(&(data_offer->mimes)); + wl_data_offer_set_user_data(id, data_offer); + wl_data_offer_add_listener(id, &data_offer_listener, data_offer); + } +} + +static void data_device_handle_enter(void *data, struct wl_data_device *wl_data_device, + uint32_t serial, struct wl_surface *surface, + wl_fixed_t x, wl_fixed_t y, struct wl_data_offer *id) +{ + SDL_WaylandDataDevice *data_device = data; + SDL_bool has_mime = SDL_FALSE; + uint32_t dnd_action = WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE; + + data_device->drag_serial = serial; + + if (id) { + data_device->drag_offer = wl_data_offer_get_user_data(id); + + /* TODO: SDL Support more mime types */ +#ifdef SDL_USE_LIBDBUS + if (Wayland_data_offer_has_mime(data_device->drag_offer, FILE_PORTAL_MIME)) { + has_mime = SDL_TRUE; + wl_data_offer_accept(id, serial, FILE_PORTAL_MIME); + } +#endif + if (Wayland_data_offer_has_mime(data_device->drag_offer, FILE_MIME)) { + has_mime = SDL_TRUE; + wl_data_offer_accept(id, serial, FILE_MIME); + } + + /* SDL only supports "copy" style drag and drop */ + if (has_mime) { + dnd_action = WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY; + } else { + /* drag_mime is NULL this will decline the offer */ + wl_data_offer_accept(id, serial, NULL); + } + if (wl_data_offer_get_version(data_device->drag_offer->offer) >= 3) { + wl_data_offer_set_actions(data_device->drag_offer->offer, + dnd_action, dnd_action); + } + + /* find the current window */ + if (surface && SDL_WAYLAND_own_surface(surface)) { + SDL_WindowData *window = (SDL_WindowData *)wl_surface_get_user_data(surface); + if (window) { + data_device->dnd_window = window->sdlwindow; + } + } + } +} + +static void data_device_handle_leave(void *data, struct wl_data_device *wl_data_device) +{ + SDL_WaylandDataDevice *data_device = data; + + if (data_device->drag_offer) { + Wayland_data_offer_destroy(data_device->drag_offer); + data_device->drag_offer = NULL; + } +} + +static void data_device_handle_motion(void *data, struct wl_data_device *wl_data_device, + uint32_t time, wl_fixed_t x, wl_fixed_t y) +{ +} + +/* Decodes URI escape sequences in string buf of len bytes + * (excluding the terminating NULL byte) in-place. Since + * URI-encoded characters take three times the space of + * normal characters, this should not be an issue. + * + * Returns the number of decoded bytes that wound up in + * the buffer, excluding the terminating NULL byte. + * + * The buffer is guaranteed to be NULL-terminated but + * may contain embedded NULL bytes. + * + * On error, -1 is returned. + * + * FIXME: This was shamelessly copied from SDL_x11events.c + */ +static int Wayland_URIDecode(char *buf, int len) +{ + int ri, wi, di; + char decode = '\0'; + if (!buf || len < 0) { + errno = EINVAL; + return -1; + } + if (len == 0) { + len = SDL_strlen(buf); + } + for (ri = 0, wi = 0, di = 0; ri < len && wi < len; ri += 1) { + if (di == 0) { + /* start decoding */ + if (buf[ri] == '%') { + decode = '\0'; + di += 1; + continue; + } + /* normal write */ + buf[wi] = buf[ri]; + wi += 1; + continue; + } else if (di == 1 || di == 2) { + char off = '\0'; + char isa = buf[ri] >= 'a' && buf[ri] <= 'f'; + char isA = buf[ri] >= 'A' && buf[ri] <= 'F'; + char isn = buf[ri] >= '0' && buf[ri] <= '9'; + if (!(isa || isA || isn)) { + /* not a hexadecimal */ + int sri; + for (sri = ri - di; sri <= ri; sri += 1) { + buf[wi] = buf[sri]; + wi += 1; + } + di = 0; + continue; + } + /* itsy bitsy magicsy */ + if (isn) { + off = 0 - '0'; + } else if (isa) { + off = 10 - 'a'; + } else if (isA) { + off = 10 - 'A'; + } + decode |= (buf[ri] + off) << (2 - di) * 4; + if (di == 2) { + buf[wi] = decode; + wi += 1; + di = 0; + } else { + di += 1; + } + continue; + } + } + buf[wi] = '\0'; + return wi; +} + +/* Convert URI to local filename + * return filename if possible, else NULL + * + * FIXME: This was shamelessly copied from SDL_x11events.c + */ +static char *Wayland_URIToLocal(char *uri) +{ + char *file = NULL; + SDL_bool local; + + if (SDL_memcmp(uri, "file:/", 6) == 0) { + uri += 6; /* local file? */ + } else if (SDL_strstr(uri, ":/") != NULL) { + return file; /* wrong scheme */ + } + + local = uri[0] != '/' || (uri[0] != '\0' && uri[1] == '/'); + + /* got a hostname? */ + if (!local && uri[0] == '/' && uri[2] != '/') { + char *hostname_end = SDL_strchr(uri + 1, '/'); + if (hostname_end) { + char hostname[257]; + if (gethostname(hostname, 255) == 0) { + hostname[256] = '\0'; + if (SDL_memcmp(uri + 1, hostname, hostname_end - (uri + 1)) == 0) { + uri = hostname_end + 1; + local = SDL_TRUE; + } + } + } + } + if (local) { + file = uri; + /* Convert URI escape sequences to real characters */ + Wayland_URIDecode(file, 0); + if (uri[1] == '/') { + file++; + } else { + file--; + } + } + return file; +} + +static void data_device_handle_drop(void *data, struct wl_data_device *wl_data_device) +{ + SDL_WaylandDataDevice *data_device = data; + + if (data_device->drag_offer) { + /* TODO: SDL Support more mime types */ + size_t length; + SDL_bool drop_handled = SDL_FALSE; +#ifdef SDL_USE_LIBDBUS + if (Wayland_data_offer_has_mime( + data_device->drag_offer, FILE_PORTAL_MIME)) { + void *buffer = Wayland_data_offer_receive(data_device->drag_offer, + &length, FILE_PORTAL_MIME, SDL_TRUE); + if (buffer) { + SDL_DBusContext *dbus = SDL_DBus_GetContext(); + if (dbus) { + int path_count = 0; + char **paths = SDL_DBus_DocumentsPortalRetrieveFiles(buffer, &path_count); + /* If dropped files contain a directory the list is empty */ + if (paths && path_count > 0) { + int i; + for (i = 0; i < path_count; i++) { + SDL_SendDropFile(data_device->dnd_window, paths[i]); + } + dbus->free_string_array(paths); + SDL_SendDropComplete(data_device->dnd_window); + drop_handled = SDL_TRUE; + } + } + SDL_free(buffer); + } + } +#endif + /* If XDG document portal fails fallback. + * When running a flatpak sandbox this will most likely be a list of + * non paths that are not visible to the application + */ + if (!drop_handled && Wayland_data_offer_has_mime( + data_device->drag_offer, FILE_MIME)) { + void *buffer = Wayland_data_offer_receive(data_device->drag_offer, + &length, FILE_MIME, SDL_TRUE); + if (buffer) { + char *saveptr = NULL; + char *token = SDL_strtokr((char *)buffer, "\r\n", &saveptr); + while (token) { + char *fn = Wayland_URIToLocal(token); + if (fn) { + SDL_SendDropFile(data_device->dnd_window, fn); + } + token = SDL_strtokr(NULL, "\r\n", &saveptr); + } + SDL_SendDropComplete(data_device->dnd_window); + SDL_free(buffer); + drop_handled = SDL_TRUE; + } + } + + if (drop_handled && wl_data_offer_get_version(data_device->drag_offer->offer) >= + WL_DATA_OFFER_FINISH_SINCE_VERSION) { + wl_data_offer_finish(data_device->drag_offer->offer); + } + Wayland_data_offer_destroy(data_device->drag_offer); + data_device->drag_offer = NULL; + } +} + +static void data_device_handle_selection(void *data, struct wl_data_device *wl_data_device, + struct wl_data_offer *id) +{ + SDL_WaylandDataDevice *data_device = data; + SDL_WaylandDataOffer *offer = NULL; + + if (id) { + offer = wl_data_offer_get_user_data(id); + } + + if (data_device->selection_offer != offer) { + Wayland_data_offer_destroy(data_device->selection_offer); + data_device->selection_offer = offer; + } + + SDL_SendClipboardUpdate(); +} + +static const struct wl_data_device_listener data_device_listener = { + data_device_handle_data_offer, + data_device_handle_enter, + data_device_handle_leave, + data_device_handle_motion, + data_device_handle_drop, + data_device_handle_selection +}; + +static void primary_selection_device_handle_offer(void *data, struct zwp_primary_selection_device_v1 *zwp_primary_selection_device_v1, + struct zwp_primary_selection_offer_v1 *id) +{ + SDL_WaylandPrimarySelectionOffer *primary_selection_offer = NULL; + + primary_selection_offer = SDL_calloc(1, sizeof(*primary_selection_offer)); + if (!primary_selection_offer) { + SDL_OutOfMemory(); + } else { + primary_selection_offer->offer = id; + primary_selection_offer->primary_selection_device = data; + WAYLAND_wl_list_init(&(primary_selection_offer->mimes)); + zwp_primary_selection_offer_v1_set_user_data(id, primary_selection_offer); + zwp_primary_selection_offer_v1_add_listener(id, &primary_selection_offer_listener, primary_selection_offer); + } +} + +static void primary_selection_device_handle_selection(void *data, struct zwp_primary_selection_device_v1 *zwp_primary_selection_device_v1, + struct zwp_primary_selection_offer_v1 *id) +{ + SDL_WaylandPrimarySelectionDevice *primary_selection_device = data; + SDL_WaylandPrimarySelectionOffer *offer = NULL; + + if (id) { + offer = zwp_primary_selection_offer_v1_get_user_data(id); + } + + if (primary_selection_device->selection_offer != offer) { + Wayland_primary_selection_offer_destroy(primary_selection_device->selection_offer); + primary_selection_device->selection_offer = offer; + } + + SDL_SendClipboardUpdate(); +} + +static const struct zwp_primary_selection_device_v1_listener primary_selection_device_listener = { + primary_selection_device_handle_offer, + primary_selection_device_handle_selection +}; + +static void text_input_enter(void *data, + struct zwp_text_input_v3 *zwp_text_input_v3, + struct wl_surface *surface) +{ + /* No-op */ +} + +static void text_input_leave(void *data, + struct zwp_text_input_v3 *zwp_text_input_v3, + struct wl_surface *surface) +{ + /* No-op */ +} + +static void text_input_preedit_string(void *data, + struct zwp_text_input_v3 *zwp_text_input_v3, + const char *text, + int32_t cursor_begin, + int32_t cursor_end) +{ + SDL_WaylandTextInput *text_input = data; + char buf[SDL_TEXTEDITINGEVENT_TEXT_SIZE]; + text_input->has_preedit = SDL_TRUE; + if (text) { + if (SDL_GetHintBoolean(SDL_HINT_IME_SUPPORT_EXTENDED_TEXT, SDL_FALSE)) { + int cursor_begin_utf8 = cursor_begin >= 0 ? (int)SDL_utf8strnlen(text, cursor_begin) : -1; + int cursor_end_utf8 = cursor_end >= 0 ? (int)SDL_utf8strnlen(text, cursor_end) : -1; + int cursor_size_utf8; + if (cursor_end_utf8 >= 0) { + if (cursor_begin_utf8 >= 0) { + cursor_size_utf8 = cursor_end_utf8 - cursor_begin_utf8; + } else { + cursor_size_utf8 = cursor_end_utf8; + } + } else { + cursor_size_utf8 = -1; + } + SDL_SendEditingText(text, cursor_begin_utf8, cursor_size_utf8); + } else { + int text_bytes = (int)SDL_strlen(text), i = 0; + int cursor = 0; + do { + const int sz = (int)SDL_utf8strlcpy(buf, text + i, sizeof(buf)); + const int chars = (int)SDL_utf8strlen(buf); + + SDL_SendEditingText(buf, cursor, chars); + + i += sz; + cursor += chars; + } while (i < text_bytes); + } + } else { + buf[0] = '\0'; + SDL_SendEditingText(buf, 0, 0); + } +} + +static void text_input_commit_string(void *data, + struct zwp_text_input_v3 *zwp_text_input_v3, + const char *text) +{ + if (text && *text) { + char buf[SDL_TEXTINPUTEVENT_TEXT_SIZE]; + size_t text_bytes = SDL_strlen(text), i = 0; + + while (i < text_bytes) { + size_t sz = SDL_utf8strlcpy(buf, text + i, sizeof(buf)); + SDL_SendKeyboardText(buf); + + i += sz; + } + } +} + +static void text_input_delete_surrounding_text(void *data, + struct zwp_text_input_v3 *zwp_text_input_v3, + uint32_t before_length, + uint32_t after_length) +{ + /* FIXME: Do we care about this event? */ +} + +static void text_input_done(void *data, + struct zwp_text_input_v3 *zwp_text_input_v3, + uint32_t serial) +{ + SDL_WaylandTextInput *text_input = data; + if (!text_input->has_preedit) { + SDL_SendEditingText("", 0, 0); + } + text_input->has_preedit = SDL_FALSE; +} + +static const struct zwp_text_input_v3_listener text_input_listener = { + text_input_enter, + text_input_leave, + text_input_preedit_string, + text_input_commit_string, + text_input_delete_surrounding_text, + text_input_done +}; + +static void Wayland_create_data_device(SDL_VideoData *d) +{ + SDL_WaylandDataDevice *data_device = NULL; + + if (!d->input->seat) { + /* No seat yet, will be initialized later. */ + return; + } + + data_device = SDL_calloc(1, sizeof(*data_device)); + if (!data_device) { + return; + } + + data_device->data_device = wl_data_device_manager_get_data_device( + d->data_device_manager, d->input->seat); + data_device->video_data = d; + + if (!data_device->data_device) { + SDL_free(data_device); + } else { + wl_data_device_set_user_data(data_device->data_device, data_device); + wl_data_device_add_listener(data_device->data_device, + &data_device_listener, data_device); + d->input->data_device = data_device; + } +} + +static void Wayland_create_primary_selection_device(SDL_VideoData *d) +{ + SDL_WaylandPrimarySelectionDevice *primary_selection_device = NULL; + + if (!d->input->seat) { + /* No seat yet, will be initialized later. */ + return; + } + + primary_selection_device = SDL_calloc(1, sizeof(*primary_selection_device)); + if (!primary_selection_device) { + return; + } + + primary_selection_device->primary_selection_device = zwp_primary_selection_device_manager_v1_get_device( + d->primary_selection_device_manager, d->input->seat); + primary_selection_device->video_data = d; + + if (!primary_selection_device->primary_selection_device) { + SDL_free(primary_selection_device); + } else { + zwp_primary_selection_device_v1_set_user_data(primary_selection_device->primary_selection_device, + primary_selection_device); + zwp_primary_selection_device_v1_add_listener(primary_selection_device->primary_selection_device, + &primary_selection_device_listener, primary_selection_device); + d->input->primary_selection_device = primary_selection_device; + } +} + +static void Wayland_create_text_input(SDL_VideoData *d) +{ + SDL_WaylandTextInput *text_input = NULL; + + if (!d->input->seat) { + /* No seat yet, will be initialized later. */ + return; + } + + text_input = SDL_calloc(1, sizeof(*text_input)); + if (!text_input) { + return; + } + + text_input->text_input = zwp_text_input_manager_v3_get_text_input( + d->text_input_manager, d->input->seat); + + if (!text_input->text_input) { + SDL_free(text_input); + } else { + zwp_text_input_v3_set_user_data(text_input->text_input, text_input); + zwp_text_input_v3_add_listener(text_input->text_input, + &text_input_listener, text_input); + d->input->text_input = text_input; + } +} + +void Wayland_add_data_device_manager(SDL_VideoData *d, uint32_t id, uint32_t version) +{ + d->data_device_manager = wl_registry_bind(d->registry, id, &wl_data_device_manager_interface, SDL_min(3, version)); + + if (d->input) { + Wayland_create_data_device(d); + } +} + +void Wayland_add_primary_selection_device_manager(SDL_VideoData *d, uint32_t id, uint32_t version) +{ + d->primary_selection_device_manager = wl_registry_bind(d->registry, id, &zwp_primary_selection_device_manager_v1_interface, 1); + + if (d->input) { + Wayland_create_primary_selection_device(d); + } +} + +void Wayland_add_text_input_manager(SDL_VideoData *d, uint32_t id, uint32_t version) +{ + d->text_input_manager = wl_registry_bind(d->registry, id, &zwp_text_input_manager_v3_interface, 1); + + if (d->input) { + Wayland_create_text_input(d); + } +} + +static void tablet_tool_handle_type(void *data, struct zwp_tablet_tool_v2 *tool, uint32_t type) +{ + /* unimplemented */ +} + +static void tablet_tool_handle_hardware_serial(void *data, struct zwp_tablet_tool_v2 *tool, uint32_t serial_hi, uint32_t serial_lo) +{ + /* unimplemented */ +} + +static void tablet_tool_handle_hardware_id_wacom(void *data, struct zwp_tablet_tool_v2 *tool, uint32_t id_hi, uint32_t id_lo) +{ + /* unimplemented */ +} + +static void tablet_tool_handle_capability(void *data, struct zwp_tablet_tool_v2 *tool, uint32_t capability) +{ + /* unimplemented */ +} + +static void tablet_tool_handle_done(void *data, struct zwp_tablet_tool_v2 *tool) +{ + /* unimplemented */ +} + +static void tablet_tool_handle_removed(void *data, struct zwp_tablet_tool_v2 *tool) +{ + /* unimplemented */ +} + +static void tablet_tool_handle_proximity_in(void *data, struct zwp_tablet_tool_v2 *tool, uint32_t serial, struct zwp_tablet_v2 *tablet, struct wl_surface *surface) +{ + struct SDL_WaylandTabletInput *input = data; + SDL_WindowData *window; + + if (!surface) { + return; + } + + if (!SDL_WAYLAND_own_surface(surface)) { + return; + } + + window = (SDL_WindowData *)wl_surface_get_user_data(surface); + + if (window) { + input->tool_focus = window; + input->tool_prox_serial = serial; + + input->is_down = SDL_FALSE; + + input->btn_stylus = SDL_FALSE; + input->btn_stylus2 = SDL_FALSE; + input->btn_stylus3 = SDL_FALSE; + + SDL_SetMouseFocus(window->sdlwindow); + SDL_SetCursor(NULL); + } +} + +static void tablet_tool_handle_proximity_out(void *data, struct zwp_tablet_tool_v2 *tool) +{ + struct SDL_WaylandTabletInput *input = data; + + if (input->tool_focus) { + SDL_SetMouseFocus(NULL); + input->tool_focus = NULL; + } +} + +uint32_t tablet_tool_btn_to_sdl_button(struct SDL_WaylandTabletInput *input) +{ + unsigned int tool_btn = input->btn_stylus3 << 2 | input->btn_stylus2 << 1 | input->btn_stylus << 0; + switch (tool_btn) { + case 0b000: + return SDL_BUTTON_LEFT; + case 0b001: + return SDL_BUTTON_RIGHT; + case 0b010: + return SDL_BUTTON_MIDDLE; + case 0b100: + return SDL_BUTTON_X1; + default: + return SDL_BUTTON_LEFT; + } +} + +static void tablet_tool_handle_down(void *data, struct zwp_tablet_tool_v2 *tool, uint32_t serial) +{ + struct SDL_WaylandTabletInput *input = data; + SDL_WindowData *window = input->tool_focus; + input->is_down = SDL_TRUE; + if (!window) { + /* tablet_tool_handle_proximity_out gets called when moving over the libdecoration csd. + * that sets input->tool_focus (window) to NULL, but handle_{down,up} events are still + * received. To prevent SIGSEGV this returns when this is the case. + */ + return; + } + + SDL_SendMouseButton(window->sdlwindow, 0, SDL_PRESSED, tablet_tool_btn_to_sdl_button(input)); +} + +static void tablet_tool_handle_up(void *data, struct zwp_tablet_tool_v2 *tool) +{ + struct SDL_WaylandTabletInput *input = data; + SDL_WindowData *window = input->tool_focus; + + input->is_down = SDL_FALSE; + + if (!window) { + /* tablet_tool_handle_proximity_out gets called when moving over the libdecoration csd. + * that sets input->tool_focus (window) to NULL, but handle_{down,up} events are still + * received. To prevent SIGSEGV this returns when this is the case. + */ + return; + } + + SDL_SendMouseButton(window->sdlwindow, 0, SDL_RELEASED, tablet_tool_btn_to_sdl_button(input)); +} + +static void tablet_tool_handle_motion(void *data, struct zwp_tablet_tool_v2 *tool, wl_fixed_t sx_w, wl_fixed_t sy_w) +{ + struct SDL_WaylandTabletInput *input = data; + SDL_WindowData *window = input->tool_focus; + + input->sx_w = sx_w; + input->sy_w = sy_w; + if (input->tool_focus) { + const float sx_f = (float)wl_fixed_to_double(sx_w); + const float sy_f = (float)wl_fixed_to_double(sy_w); + const int sx = (int)SDL_floorf(sx_f * window->pointer_scale_x); + const int sy = (int)SDL_floorf(sy_f * window->pointer_scale_y); + SDL_SendMouseMotion(window->sdlwindow, 0, 0, sx, sy); + } +} + +static void tablet_tool_handle_pressure(void *data, struct zwp_tablet_tool_v2 *tool, uint32_t pressure) +{ + /* unimplemented */ +} + +static void tablet_tool_handle_distance(void *data, struct zwp_tablet_tool_v2 *tool, uint32_t distance) +{ + /* unimplemented */ +} + +static void tablet_tool_handle_tilt(void *data, struct zwp_tablet_tool_v2 *tool, wl_fixed_t xtilt, wl_fixed_t ytilt) +{ + /* unimplemented */ +} + +static void tablet_tool_handle_button(void *data, struct zwp_tablet_tool_v2 *tool, uint32_t serial, uint32_t button, uint32_t state) +{ + struct SDL_WaylandTabletInput *input = data; + + if (input->is_down) { + tablet_tool_handle_up(data, tool); + input->is_down = SDL_TRUE; + } + + switch (button) { + /* see %{_includedir}/linux/input-event-codes.h */ + case 0x14b: /* BTN_STYLUS */ + input->btn_stylus = state == ZWP_TABLET_PAD_V2_BUTTON_STATE_PRESSED ? SDL_TRUE : SDL_FALSE; + break; + case 0x14c: /* BTN_STYLUS2 */ + input->btn_stylus2 = state == ZWP_TABLET_PAD_V2_BUTTON_STATE_PRESSED ? SDL_TRUE : SDL_FALSE; + break; + case 0x149: /* BTN_STYLUS3 */ + input->btn_stylus3 = state == ZWP_TABLET_PAD_V2_BUTTON_STATE_PRESSED ? SDL_TRUE : SDL_FALSE; + break; + } + + if (input->is_down) { + tablet_tool_handle_down(data, tool, serial); + } +} + +static void tablet_tool_handle_rotation(void *data, struct zwp_tablet_tool_v2 *tool, wl_fixed_t degrees) +{ + /* unimplemented */ +} + +static void tablet_tool_handle_slider(void *data, struct zwp_tablet_tool_v2 *tool, int32_t position) +{ + /* unimplemented */ +} + +static void tablet_tool_handle_wheel(void *data, struct zwp_tablet_tool_v2 *tool, int32_t degrees, int32_t clicks) +{ + /* unimplemented */ +} + +static void tablet_tool_handle_frame(void *data, struct zwp_tablet_tool_v2 *tool, uint32_t time) +{ + /* unimplemented */ +} + +static const struct zwp_tablet_tool_v2_listener tablet_tool_listener = { + tablet_tool_handle_type, + tablet_tool_handle_hardware_serial, + tablet_tool_handle_hardware_id_wacom, + tablet_tool_handle_capability, + tablet_tool_handle_done, + tablet_tool_handle_removed, + tablet_tool_handle_proximity_in, + tablet_tool_handle_proximity_out, + tablet_tool_handle_down, + tablet_tool_handle_up, + tablet_tool_handle_motion, + tablet_tool_handle_pressure, + tablet_tool_handle_distance, + tablet_tool_handle_tilt, + tablet_tool_handle_rotation, + tablet_tool_handle_slider, + tablet_tool_handle_wheel, + tablet_tool_handle_button, + tablet_tool_handle_frame +}; + +struct SDL_WaylandTabletObjectListNode *tablet_object_list_new_node(void *object) +{ + struct SDL_WaylandTabletObjectListNode *node; + + node = SDL_calloc(1, sizeof(*node)); + if (!node) { + return NULL; + } + + node->next = NULL; + node->object = object; + + return node; +} + +void tablet_object_list_append(struct SDL_WaylandTabletObjectListNode *head, void *object) +{ + if (!head->object) { + head->object = object; + return; + } + + while (head->next) { + head = head->next; + } + + head->next = tablet_object_list_new_node(object); +} + +void tablet_object_list_destroy(struct SDL_WaylandTabletObjectListNode *head, void (*deleter)(void *object)) +{ + while (head) { + struct SDL_WaylandTabletObjectListNode *next = head->next; + if (head->object) { + (*deleter)(head->object); + } + SDL_free(head); + head = next; + } +} + +static void tablet_seat_handle_tablet_added(void *data, struct zwp_tablet_seat_v2 *seat, struct zwp_tablet_v2 *tablet) +{ + struct SDL_WaylandTabletInput *input = data; + + tablet_object_list_append(input->tablets, tablet); +} + +static void tablet_seat_handle_tool_added(void *data, struct zwp_tablet_seat_v2 *seat, struct zwp_tablet_tool_v2 *tool) +{ + struct SDL_WaylandTabletInput *input = data; + + zwp_tablet_tool_v2_add_listener(tool, &tablet_tool_listener, data); + zwp_tablet_tool_v2_set_user_data(tool, data); + + tablet_object_list_append(input->tools, tool); +} + +static void tablet_seat_handle_pad_added(void *data, struct zwp_tablet_seat_v2 *seat, struct zwp_tablet_pad_v2 *pad) +{ + struct SDL_WaylandTabletInput *input = data; + + tablet_object_list_append(input->pads, pad); +} + +static const struct zwp_tablet_seat_v2_listener tablet_seat_listener = { + tablet_seat_handle_tablet_added, + tablet_seat_handle_tool_added, + tablet_seat_handle_pad_added +}; + +void Wayland_input_add_tablet(struct SDL_WaylandInput *input, struct SDL_WaylandTabletManager *tablet_manager) +{ + struct SDL_WaylandTabletInput *tablet_input; + + if (!tablet_manager || !input->seat) { + return; + } + + tablet_input = SDL_calloc(1, sizeof(*tablet_input)); + if (!tablet_input) { + return; + } + + input->tablet = tablet_input; + + tablet_input->seat = (struct SDL_WaylandTabletSeat *)zwp_tablet_manager_v2_get_tablet_seat((struct zwp_tablet_manager_v2 *)tablet_manager, input->seat); + + tablet_input->tablets = tablet_object_list_new_node(NULL); + tablet_input->tools = tablet_object_list_new_node(NULL); + tablet_input->pads = tablet_object_list_new_node(NULL); + + zwp_tablet_seat_v2_add_listener((struct zwp_tablet_seat_v2 *)tablet_input->seat, &tablet_seat_listener, tablet_input); +} + +#define TABLET_OBJECT_LIST_DELETER(fun) (void (*)(void *)) fun +void Wayland_input_destroy_tablet(struct SDL_WaylandInput *input) +{ + tablet_object_list_destroy(input->tablet->pads, TABLET_OBJECT_LIST_DELETER(zwp_tablet_pad_v2_destroy)); + tablet_object_list_destroy(input->tablet->tools, TABLET_OBJECT_LIST_DELETER(zwp_tablet_tool_v2_destroy)); + tablet_object_list_destroy(input->tablet->tablets, TABLET_OBJECT_LIST_DELETER(zwp_tablet_v2_destroy)); + + zwp_tablet_seat_v2_destroy((struct zwp_tablet_seat_v2 *)input->tablet->seat); + + SDL_free(input->tablet); + input->tablet = NULL; +} + +void Wayland_display_add_input(SDL_VideoData *d, uint32_t id, uint32_t version) +{ + struct SDL_WaylandInput *input = d->input; + + input->seat = wl_registry_bind(d->registry, id, &wl_seat_interface, SDL_min(SDL_WL_SEAT_VERSION, version)); + + if (d->data_device_manager) { + Wayland_create_data_device(d); + } + if (d->primary_selection_device_manager) { + Wayland_create_primary_selection_device(d); + } + if (d->text_input_manager) { + Wayland_create_text_input(d); + } + + wl_seat_add_listener(input->seat, &seat_listener, input); + wl_seat_set_user_data(input->seat, input); + + if (d->tablet_manager) { + Wayland_input_add_tablet(input, d->tablet_manager); + } + + WAYLAND_wl_display_flush(d->display); +} + +void Wayland_display_destroy_input(SDL_VideoData *d) +{ + struct SDL_WaylandInput *input = d->input; + + if (!input) { + return; + } + + if (input->data_device) { + Wayland_data_device_clear_selection(input->data_device); + if (input->data_device->selection_offer) { + Wayland_data_offer_destroy(input->data_device->selection_offer); + } + if (input->data_device->drag_offer) { + Wayland_data_offer_destroy(input->data_device->drag_offer); + } + if (input->data_device->data_device) { + wl_data_device_release(input->data_device->data_device); + } + SDL_free(input->data_device); + } + + if (input->primary_selection_device) { + if (input->primary_selection_device->selection_offer) { + Wayland_primary_selection_offer_destroy(input->primary_selection_device->selection_offer); + } + SDL_free(input->primary_selection_device); + } + + if (input->text_input) { + zwp_text_input_v3_destroy(input->text_input->text_input); + SDL_free(input->text_input); + } + + if (input->keyboard) { + wl_keyboard_destroy(input->keyboard); + } + + if (input->pointer) { + wl_pointer_destroy(input->pointer); + } + + if (input->touch) { + SDL_DelTouch(1); + wl_touch_destroy(input->touch); + } + + if (input->tablet) { + Wayland_input_destroy_tablet(input); + } + + if (input->seat) { + wl_seat_destroy(input->seat); + } + + if (input->xkb.compose_state) { + WAYLAND_xkb_compose_state_unref(input->xkb.compose_state); + } + + if (input->xkb.compose_table) { + WAYLAND_xkb_compose_table_unref(input->xkb.compose_table); + } + + if (input->xkb.state) { + WAYLAND_xkb_state_unref(input->xkb.state); + } + + if (input->xkb.keymap) { + WAYLAND_xkb_keymap_unref(input->xkb.keymap); + } + + SDL_free(input); + d->input = NULL; +} + +/* !!! FIXME: just merge these into display_handle_global(). */ +void Wayland_display_add_relative_pointer_manager(SDL_VideoData *d, uint32_t id) +{ + d->relative_pointer_manager = + wl_registry_bind(d->registry, id, + &zwp_relative_pointer_manager_v1_interface, 1); +} + +void Wayland_display_destroy_relative_pointer_manager(SDL_VideoData *d) +{ + if (d->relative_pointer_manager) { + zwp_relative_pointer_manager_v1_destroy(d->relative_pointer_manager); + } +} + +void Wayland_display_add_pointer_constraints(SDL_VideoData *d, uint32_t id) +{ + d->pointer_constraints = + wl_registry_bind(d->registry, id, + &zwp_pointer_constraints_v1_interface, 1); +} + +void Wayland_display_destroy_pointer_constraints(SDL_VideoData *d) +{ + if (d->pointer_constraints) { + zwp_pointer_constraints_v1_destroy(d->pointer_constraints); + } +} + +static void relative_pointer_handle_relative_motion(void *data, + struct zwp_relative_pointer_v1 *pointer, + uint32_t time_hi, + uint32_t time_lo, + wl_fixed_t dx_w, + wl_fixed_t dy_w, + wl_fixed_t dx_unaccel_w, + wl_fixed_t dy_unaccel_w) +{ + struct SDL_WaylandInput *input = data; + SDL_VideoData *d = input->display; + SDL_WindowData *window = input->pointer_focus; + double dx_unaccel; + double dy_unaccel; + double dx; + double dy; + + dx_unaccel = wl_fixed_to_double(dx_unaccel_w); + dy_unaccel = wl_fixed_to_double(dy_unaccel_w); + + /* Add left over fraction from last event. */ + dx_unaccel += input->dx_frac; + dy_unaccel += input->dy_frac; + + input->dx_frac = modf(dx_unaccel, &dx); + input->dy_frac = modf(dy_unaccel, &dy); + + if (input->pointer_focus && d->relative_mouse_mode) { + SDL_SendMouseMotion(window->sdlwindow, 0, 1, (int)dx, (int)dy); + } +} + +static const struct zwp_relative_pointer_v1_listener relative_pointer_listener = { + relative_pointer_handle_relative_motion, +}; + +static void locked_pointer_locked(void *data, + struct zwp_locked_pointer_v1 *locked_pointer) +{ +} + +static void locked_pointer_unlocked(void *data, + struct zwp_locked_pointer_v1 *locked_pointer) +{ +} + +static const struct zwp_locked_pointer_v1_listener locked_pointer_listener = { + locked_pointer_locked, + locked_pointer_unlocked, +}; + +static void lock_pointer_to_window(SDL_Window *window, + struct SDL_WaylandInput *input) +{ + SDL_WindowData *w = window->driverdata; + SDL_VideoData *d = input->display; + struct zwp_locked_pointer_v1 *locked_pointer; + + if (!d->pointer_constraints || !input->pointer) { + return; + } + + if (w->locked_pointer) { + return; + } + + locked_pointer = + zwp_pointer_constraints_v1_lock_pointer(d->pointer_constraints, + w->surface, + input->pointer, + NULL, + ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT); + zwp_locked_pointer_v1_add_listener(locked_pointer, + &locked_pointer_listener, + window); + + w->locked_pointer = locked_pointer; +} + +static void pointer_confine_destroy(SDL_Window *window) +{ + SDL_WindowData *w = window->driverdata; + if (w->confined_pointer) { + zwp_confined_pointer_v1_destroy(w->confined_pointer); + w->confined_pointer = NULL; + } +} + +int Wayland_input_lock_pointer(struct SDL_WaylandInput *input) +{ + SDL_VideoDevice *vd = SDL_GetVideoDevice(); + SDL_VideoData *d = input->display; + SDL_Window *window; + struct zwp_relative_pointer_v1 *relative_pointer; + + if (!d->relative_pointer_manager) { + return -1; + } + + if (!d->pointer_constraints) { + return -1; + } + + if (!input->pointer) { + return -1; + } + + /* If we have a pointer confine active, we must destroy it here because + * creating a locked pointer otherwise would be a protocol error. + */ + for (window = vd->windows; window; window = window->next) { + pointer_confine_destroy(window); + } + + if (!input->relative_pointer) { + relative_pointer = + zwp_relative_pointer_manager_v1_get_relative_pointer( + d->relative_pointer_manager, + input->pointer); + zwp_relative_pointer_v1_add_listener(relative_pointer, + &relative_pointer_listener, + input); + input->relative_pointer = relative_pointer; + } + + for (window = vd->windows; window; window = window->next) { + lock_pointer_to_window(window, input); + } + + d->relative_mouse_mode = 1; + + return 0; +} + +int Wayland_input_unlock_pointer(struct SDL_WaylandInput *input) +{ + SDL_VideoDevice *vd = SDL_GetVideoDevice(); + SDL_VideoData *d = input->display; + SDL_Window *window; + SDL_WindowData *w; + + for (window = vd->windows; window; window = window->next) { + w = window->driverdata; + if (w->locked_pointer) { + zwp_locked_pointer_v1_destroy(w->locked_pointer); + } + w->locked_pointer = NULL; + } + + if (input->relative_pointer) { + zwp_relative_pointer_v1_destroy(input->relative_pointer); + input->relative_pointer = NULL; + } + + d->relative_mouse_mode = 0; + + for (window = vd->windows; window; window = window->next) { + Wayland_input_confine_pointer(input, window); + } + + return 0; +} + +static void confined_pointer_confined(void *data, + struct zwp_confined_pointer_v1 *confined_pointer) +{ +} + +static void confined_pointer_unconfined(void *data, + struct zwp_confined_pointer_v1 *confined_pointer) +{ +} + +static const struct zwp_confined_pointer_v1_listener confined_pointer_listener = { + confined_pointer_confined, + confined_pointer_unconfined, +}; + +int Wayland_input_confine_pointer(struct SDL_WaylandInput *input, SDL_Window *window) +{ + SDL_WindowData *w = window->driverdata; + SDL_VideoData *d = input->display; + struct zwp_confined_pointer_v1 *confined_pointer; + struct wl_region *confine_rect; + + if (!d->pointer_constraints) { + return -1; + } + + if (!input->pointer) { + return -1; + } + + /* A confine may already be active, in which case we should destroy it and + * create a new one. + */ + pointer_confine_destroy(window); + + /* We cannot create a confine if the pointer is already locked. Defer until + * the pointer is unlocked. + */ + if (d->relative_mouse_mode) { + return 0; + } + + /* Don't confine the pointer if it shouldn't be confined. */ + if (SDL_RectEmpty(&window->mouse_rect) && !(window->flags & SDL_WINDOW_MOUSE_GRABBED)) { + return 0; + } + + if (SDL_RectEmpty(&window->mouse_rect)) { + confine_rect = NULL; + } else { + SDL_Rect scaled_mouse_rect; + + scaled_mouse_rect.x = (int)SDL_floorf((float)window->mouse_rect.x / w->pointer_scale_x); + scaled_mouse_rect.y = (int)SDL_floorf((float)window->mouse_rect.y / w->pointer_scale_y); + scaled_mouse_rect.w = (int)SDL_ceilf((float)window->mouse_rect.w / w->pointer_scale_x); + scaled_mouse_rect.h = (int)SDL_ceilf((float)window->mouse_rect.h / w->pointer_scale_y); + + confine_rect = wl_compositor_create_region(d->compositor); + wl_region_add(confine_rect, + scaled_mouse_rect.x, + scaled_mouse_rect.y, + scaled_mouse_rect.w, + scaled_mouse_rect.h); + } + + confined_pointer = + zwp_pointer_constraints_v1_confine_pointer(d->pointer_constraints, + w->surface, + input->pointer, + confine_rect, + ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT); + zwp_confined_pointer_v1_add_listener(confined_pointer, + &confined_pointer_listener, + window); + + if (confine_rect) { + wl_region_destroy(confine_rect); + } + + w->confined_pointer = confined_pointer; + return 0; +} + +int Wayland_input_unconfine_pointer(struct SDL_WaylandInput *input, SDL_Window *window) +{ + pointer_confine_destroy(window); + return 0; +} + +int Wayland_input_grab_keyboard(SDL_Window *window, struct SDL_WaylandInput *input) +{ + SDL_WindowData *w = window->driverdata; + SDL_VideoData *d = input->display; + + if (!d->key_inhibitor_manager) { + return -1; + } + + if (w->key_inhibitor) { + return 0; + } + + w->key_inhibitor = + zwp_keyboard_shortcuts_inhibit_manager_v1_inhibit_shortcuts(d->key_inhibitor_manager, + w->surface, + input->seat); + + return 0; +} + +int Wayland_input_ungrab_keyboard(SDL_Window *window) +{ + SDL_WindowData *w = window->driverdata; + + if (w->key_inhibitor) { + zwp_keyboard_shortcuts_inhibitor_v1_destroy(w->key_inhibitor); + w->key_inhibitor = NULL; + } + + return 0; +} + +#endif /* SDL_VIDEO_DRIVER_WAYLAND */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/wayland/SDL_waylandevents_c.h b/SDL2-2.30.5/src/video/wayland/SDL_waylandevents_c.h new file mode 100644 index 0000000..d69888c --- /dev/null +++ b/SDL2-2.30.5/src/video/wayland/SDL_waylandevents_c.h @@ -0,0 +1,180 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifndef SDL_waylandevents_h_ +#define SDL_waylandevents_h_ + +#include "SDL_waylandvideo.h" +#include "SDL_waylandwindow.h" +#include "SDL_waylanddatamanager.h" +#include "SDL_waylandkeyboard.h" + +enum SDL_WaylandAxisEvent +{ + AXIS_EVENT_CONTINUOUS = 0, + AXIS_EVENT_DISCRETE, + AXIS_EVENT_VALUE120 +}; + +struct SDL_WaylandTabletSeat; + +struct SDL_WaylandTabletObjectListNode +{ + void *object; + struct SDL_WaylandTabletObjectListNode *next; +}; + +struct SDL_WaylandTabletInput +{ + struct SDL_WaylandTabletSeat *seat; + + struct SDL_WaylandTabletObjectListNode *tablets; + struct SDL_WaylandTabletObjectListNode *tools; + struct SDL_WaylandTabletObjectListNode *pads; + + SDL_WindowData *tool_focus; + uint32_t tool_prox_serial; + + /* Last motion location */ + wl_fixed_t sx_w; + wl_fixed_t sy_w; + + SDL_bool is_down; + + SDL_bool btn_stylus; + SDL_bool btn_stylus2; + SDL_bool btn_stylus3; +}; + +typedef struct +{ + // repeat_rate in range of [1, 1000] + int32_t repeat_rate; + int32_t repeat_delay; + SDL_bool is_initialized; + + SDL_bool is_key_down; + uint32_t key; + uint32_t wl_press_time; // Key press time as reported by the Wayland API + uint32_t sdl_press_time; // Key press time expressed in SDL ticks + uint32_t next_repeat_ms; + uint32_t scancode; + char text[8]; +} SDL_WaylandKeyboardRepeat; + +struct SDL_WaylandInput +{ + SDL_VideoData *display; + struct wl_seat *seat; + struct wl_pointer *pointer; + struct wl_touch *touch; + struct wl_keyboard *keyboard; + SDL_WaylandDataDevice *data_device; + SDL_WaylandPrimarySelectionDevice *primary_selection_device; + SDL_WaylandTextInput *text_input; + struct zwp_relative_pointer_v1 *relative_pointer; + SDL_WindowData *pointer_focus; + SDL_WindowData *keyboard_focus; + uint32_t pointer_enter_serial; + + /* Last motion location */ + wl_fixed_t sx_w; + wl_fixed_t sy_w; + + uint32_t buttons_pressed; + + double dx_frac; + double dy_frac; + + struct + { + struct xkb_keymap *keymap; + struct xkb_state *state; + struct xkb_compose_table *compose_table; + struct xkb_compose_state *compose_state; + + /* Keyboard layout "group" */ + uint32_t current_group; + + /* Modifier bitshift values */ + uint32_t idx_shift; + uint32_t idx_ctrl; + uint32_t idx_alt; + uint32_t idx_gui; + uint32_t idx_num; + uint32_t idx_caps; + } xkb; + + /* information about axis events on current frame */ + struct + { + enum SDL_WaylandAxisEvent x_axis_type; + float x; + + enum SDL_WaylandAxisEvent y_axis_type; + float y; + } pointer_curr_axis_info; + + SDL_WaylandKeyboardRepeat keyboard_repeat; + + struct SDL_WaylandTabletInput *tablet; + + /* are we forcing relative mouse mode? */ + SDL_bool cursor_visible; + SDL_bool relative_mode_override; + SDL_bool warp_emulation_prohibited; + SDL_bool keyboard_is_virtual; +}; + +extern void Wayland_PumpEvents(_THIS); +extern void Wayland_SendWakeupEvent(_THIS, SDL_Window *window); +extern int Wayland_WaitEventTimeout(_THIS, int timeout); + +extern void Wayland_add_data_device_manager(SDL_VideoData *d, uint32_t id, uint32_t version); +extern void Wayland_add_primary_selection_device_manager(SDL_VideoData *d, uint32_t id, uint32_t version); +extern void Wayland_add_text_input_manager(SDL_VideoData *d, uint32_t id, uint32_t version); + +extern void Wayland_display_add_input(SDL_VideoData *d, uint32_t id, uint32_t version); +extern void Wayland_display_destroy_input(SDL_VideoData *d); + +extern void Wayland_display_add_pointer_constraints(SDL_VideoData *d, uint32_t id); +extern void Wayland_display_destroy_pointer_constraints(SDL_VideoData *d); + +extern int Wayland_input_lock_pointer(struct SDL_WaylandInput *input); +extern int Wayland_input_unlock_pointer(struct SDL_WaylandInput *input); + +extern int Wayland_input_confine_pointer(struct SDL_WaylandInput *input, SDL_Window *window); +extern int Wayland_input_unconfine_pointer(struct SDL_WaylandInput *input, SDL_Window *window); + +extern void Wayland_display_add_relative_pointer_manager(SDL_VideoData *d, uint32_t id); +extern void Wayland_display_destroy_relative_pointer_manager(SDL_VideoData *d); + +extern int Wayland_input_grab_keyboard(SDL_Window *window, struct SDL_WaylandInput *input); +extern int Wayland_input_ungrab_keyboard(SDL_Window *window); + +extern void Wayland_input_add_tablet(struct SDL_WaylandInput *input, struct SDL_WaylandTabletManager *tablet_manager); +extern void Wayland_input_destroy_tablet(struct SDL_WaylandInput *input); + +#endif /* SDL_waylandevents_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/wayland/SDL_waylandkeyboard.c b/SDL2-2.30.5/src/video/wayland/SDL_waylandkeyboard.c new file mode 100644 index 0000000..df0f865 --- /dev/null +++ b/SDL2-2.30.5/src/video/wayland/SDL_waylandkeyboard.c @@ -0,0 +1,160 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_WAYLAND + +#include "../SDL_sysvideo.h" +#include "SDL_waylandvideo.h" +#include "SDL_waylandevents_c.h" +#include "../../events/SDL_keyboard_c.h" +#include "text-input-unstable-v3-client-protocol.h" + +int Wayland_InitKeyboard(_THIS) +{ +#ifdef SDL_USE_IME + SDL_VideoData *driverdata = _this->driverdata; + if (!driverdata->text_input_manager) { + SDL_IME_Init(); + } +#endif + SDL_SetScancodeName(SDL_SCANCODE_APPLICATION, "Menu"); + + return 0; +} + +void Wayland_QuitKeyboard(_THIS) +{ +#ifdef SDL_USE_IME + SDL_VideoData *driverdata = _this->driverdata; + if (!driverdata->text_input_manager) { + SDL_IME_Quit(); + } +#endif +} + +void Wayland_StartTextInput(_THIS) +{ + SDL_VideoData *driverdata = _this->driverdata; + + if (driverdata->text_input_manager) { + struct SDL_WaylandInput *input = driverdata->input; + if (input && input->text_input) { + const SDL_Rect *rect = &input->text_input->cursor_rect; + + /* Don't re-enable if we're already enabled. */ + if (input->text_input->is_enabled) { + return; + } + + /* For some reason this has to be done twice, it appears to be a + * bug in mutter? Maybe? + * -flibit + */ + zwp_text_input_v3_enable(input->text_input->text_input); + zwp_text_input_v3_commit(input->text_input->text_input); + zwp_text_input_v3_enable(input->text_input->text_input); + zwp_text_input_v3_commit(input->text_input->text_input); + + /* Now that it's enabled, set the input properties */ + zwp_text_input_v3_set_content_type(input->text_input->text_input, + ZWP_TEXT_INPUT_V3_CONTENT_HINT_NONE, + ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NORMAL); + if (!SDL_RectEmpty(rect)) { + /* This gets reset on enable so we have to cache it */ + zwp_text_input_v3_set_cursor_rectangle(input->text_input->text_input, + rect->x, + rect->y, + rect->w, + rect->h); + } + zwp_text_input_v3_commit(input->text_input->text_input); + input->text_input->is_enabled = SDL_TRUE; + } + } +} + +void Wayland_StopTextInput(_THIS) +{ + SDL_VideoData *driverdata = _this->driverdata; + + if (driverdata->text_input_manager) { + struct SDL_WaylandInput *input = driverdata->input; + if (input && input->text_input) { + zwp_text_input_v3_disable(input->text_input->text_input); + zwp_text_input_v3_commit(input->text_input->text_input); + input->text_input->is_enabled = SDL_FALSE; + } + } + +#ifdef SDL_USE_IME + else { + SDL_IME_Reset(); + } +#endif +} + +void Wayland_SetTextInputRect(_THIS, const SDL_Rect *rect) +{ + SDL_VideoData *driverdata = _this->driverdata; + + if (!rect) { + SDL_InvalidParamError("rect"); + return; + } + + if (driverdata->text_input_manager) { + struct SDL_WaylandInput *input = driverdata->input; + if (input && input->text_input) { + if (!SDL_RectEquals(rect, &input->text_input->cursor_rect)) { + SDL_copyp(&input->text_input->cursor_rect, rect); + zwp_text_input_v3_set_cursor_rectangle(input->text_input->text_input, + rect->x, + rect->y, + rect->w, + rect->h); + zwp_text_input_v3_commit(input->text_input->text_input); + } + } + } + +#ifdef SDL_USE_IME + else { + SDL_IME_UpdateTextRect(rect); + } +#endif +} + +SDL_bool Wayland_HasScreenKeyboardSupport(_THIS) +{ + /* In reality we just want to return true when the screen keyboard is the + * _only_ way to get text input. So, in addition to checking for the text + * input protocol, make sure we don't have any physical keyboards either. + */ + SDL_VideoData *driverdata = _this->driverdata; + SDL_bool haskeyboard = (driverdata->input != NULL) && (driverdata->input->keyboard != NULL); + SDL_bool hastextmanager = (driverdata->text_input_manager != NULL); + return !haskeyboard && hastextmanager; +} + +#endif /* SDL_VIDEO_DRIVER_WAYLAND */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/wayland/SDL_waylandkeyboard.h b/SDL2-2.30.5/src/video/wayland/SDL_waylandkeyboard.h new file mode 100644 index 0000000..6a0fccd --- /dev/null +++ b/SDL2-2.30.5/src/video/wayland/SDL_waylandkeyboard.h @@ -0,0 +1,43 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifndef SDL_waylandkeyboard_h_ +#define SDL_waylandkeyboard_h_ + +typedef struct SDL_WaylandTextInput +{ + struct zwp_text_input_v3 *text_input; + SDL_Rect cursor_rect; + SDL_bool has_preedit; + SDL_bool is_enabled; +} SDL_WaylandTextInput; + +extern int Wayland_InitKeyboard(_THIS); +extern void Wayland_QuitKeyboard(_THIS); +extern void Wayland_StartTextInput(_THIS); +extern void Wayland_StopTextInput(_THIS); +extern void Wayland_SetTextInputRect(_THIS, const SDL_Rect *rect); +extern SDL_bool Wayland_HasScreenKeyboardSupport(_THIS); + +#endif /* SDL_waylandkeyboard_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/wayland/SDL_waylandmessagebox.c b/SDL2-2.30.5/src/video/wayland/SDL_waylandmessagebox.c new file mode 100644 index 0000000..2fea3de --- /dev/null +++ b/SDL2-2.30.5/src/video/wayland/SDL_waylandmessagebox.c @@ -0,0 +1,252 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_WAYLAND + +#include "SDL.h" +#include /* fgets */ +#include /* FILE, STDOUT_FILENO, fdopen, fclose */ +#include /* pid_t, pipe, fork, close, dup2, execvp, _exit */ +#include /* waitpid, WIFEXITED, WEXITSTATUS */ +#include /* strerr */ +#include + +#include "SDL_waylandmessagebox.h" + +#define ZENITY_VERSION_LEN 32 /* Number of bytes to read from zenity --version (including NUL)*/ + +#define MAX_BUTTONS 8 /* Maximum number of buttons supported */ + +static int run_zenity(const char **args, int fd_pipe[2]) { + int status; + pid_t pid1; + + pid1 = fork(); + if (pid1 == 0) { /* child process */ + close(fd_pipe[0]); /* no reading from pipe */ + /* write stdout in pipe */ + if (dup2(fd_pipe[1], STDOUT_FILENO) == -1) { + _exit(128); + } + + /* const casting argv is fine: + * https://pubs.opengroup.org/onlinepubs/9699919799/functions/fexecve.html -> rational + */ + execvp("zenity", (char **)args); + _exit(129); + } else if (pid1 < 0) { /* fork() failed */ + return SDL_SetError("fork() failed: %s", strerror(errno)); + } else { /* parent process */ + close(fd_pipe[1]); /* no writing to the pipe */ + if (waitpid(pid1, &status, 0) != pid1) { + return SDL_SetError("Waiting on zenity failed: %s", strerror(errno)); + } + + if (!WIFEXITED(status)) { + return SDL_SetError("zenity failed for some reason"); + } + + if (WEXITSTATUS(status) >= 128) { + return SDL_SetError("zenity reported error or failed to launch: %d", WEXITSTATUS(status)); + } + + return 0; /* success! */ + } +} + +static int get_zenity_version(int *major, int *minor) { + int fd_pipe[2]; /* fd_pipe[0]: read end of pipe, fd_pipe[1]: write end of pipe */ + const char *argv[] = { "zenity", "--version", NULL }; + + if (pipe(fd_pipe) != 0) { /* create a pipe */ + return SDL_SetError("pipe() failed: %s", strerror(errno)); + } + + if (run_zenity(argv, fd_pipe) == 0) { + FILE *outputfp = NULL; + char version_str[ZENITY_VERSION_LEN]; + char *version_ptr = NULL, *end_ptr = NULL; + int tmp; + + outputfp = fdopen(fd_pipe[0], "r"); + if (!outputfp) { + close(fd_pipe[0]); + return SDL_SetError("failed to open pipe for reading: %s", strerror(errno)); + } + + version_ptr = fgets(version_str, ZENITY_VERSION_LEN, outputfp); + (void)fclose(outputfp); /* will close underlying fd */ + + /* we expect the version string is in the form of MAJOR.MINOR.MICRO + * as described in meson.build. We'll ignore everything after that. + */ + tmp = (int) SDL_strtol(version_ptr, &end_ptr, 10); + if (tmp == 0 && end_ptr == version_ptr) { + return SDL_SetError("failed to get zenity major version number"); + } + *major = tmp; + + version_ptr = end_ptr + 1; /* skip the dot */ + tmp = (int) SDL_strtol(version_ptr, &end_ptr, 10); + if (tmp == 0 && end_ptr == version_ptr) { + return SDL_SetError("failed to get zenity minor version number"); + } + *minor = tmp; + + return 0; /* success */ + } + + close(fd_pipe[0]); + close(fd_pipe[1]); + return -1; /* run_zenity should've called SDL_SetError() */ +} + +int Wayland_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) { + int fd_pipe[2]; /* fd_pipe[0]: read end of pipe, fd_pipe[1]: write end of pipe */ + int zenity_major = 0, zenity_minor = 0, output_len = 0; + int argc = 5, i; + const char *argv[5 + 2 /* icon name */ + 2 /* title */ + 2 /* message */ + 2 * MAX_BUTTONS + 1 /* NULL */] = { + "zenity", "--question", "--switch", "--no-wrap", "--no-markup" + }; + + if (messageboxdata->numbuttons > MAX_BUTTONS) { + return SDL_SetError("Too many buttons (%d max allowed)", MAX_BUTTONS); + } + + /* get zenity version so we know which arg to use */ + if (get_zenity_version(&zenity_major, &zenity_minor) != 0) { + return -1; /* get_zenity_version() calls SDL_SetError(), so message is already set */ + } + + if (pipe(fd_pipe) != 0) { /* create a pipe */ + return SDL_SetError("pipe() failed: %s", strerror(errno)); + } + + /* https://gitlab.gnome.org/GNOME/zenity/-/commit/c686bdb1b45e95acf010efd9ca0c75527fbb4dea + * This commit removed --icon-name without adding a deprecation notice. + * We need to handle it gracefully, otherwise no message box will be shown. + */ + argv[argc++] = zenity_major > 3 || (zenity_major == 3 && zenity_minor >= 90) ? "--icon" : "--icon-name"; + switch (messageboxdata->flags) { + case SDL_MESSAGEBOX_ERROR: + argv[argc++] = "dialog-error"; + break; + case SDL_MESSAGEBOX_WARNING: + argv[argc++] = "dialog-warning"; + break; + case SDL_MESSAGEBOX_INFORMATION: + default: + argv[argc++] = "dialog-information"; + break; + } + + if (messageboxdata->title && messageboxdata->title[0]) { + argv[argc++] = "--title"; + argv[argc++] = messageboxdata->title; + } else { + argv[argc++] = "--title=\"\""; + } + + if (messageboxdata->message && messageboxdata->message[0]) { + argv[argc++] = "--text"; + argv[argc++] = messageboxdata->message; + } else { + argv[argc++] = "--text=\"\""; + } + + for (i = 0; i < messageboxdata->numbuttons; ++i) { + if (messageboxdata->buttons[i].text && messageboxdata->buttons[i].text[0]) { + int len = SDL_strlen(messageboxdata->buttons[i].text); + if (len > output_len) { + output_len = len; + } + + argv[argc++] = "--extra-button"; + argv[argc++] = messageboxdata->buttons[i].text; + } else { + argv[argc++] = "--extra-button=\"\""; + } + } + argv[argc] = NULL; + + if (run_zenity(argv, fd_pipe) == 0) { + FILE *outputfp = NULL; + char *output = NULL; + char *tmp = NULL; + + if (!buttonid) { + /* if we don't need buttonid, we can return immediately */ + close(fd_pipe[0]); + return 0; /* success */ + } + *buttonid = -1; + + output = SDL_malloc(output_len + 1); + if (!output) { + close(fd_pipe[0]); + return SDL_OutOfMemory(); + } + output[0] = '\0'; + + outputfp = fdopen(fd_pipe[0], "r"); + if (!outputfp) { + SDL_free(output); + close(fd_pipe[0]); + return SDL_SetError("Couldn't open pipe for reading: %s", strerror(errno)); + } + tmp = fgets(output, output_len + 1, outputfp); + (void)fclose(outputfp); + + if ((!tmp) || (*tmp == '\0') || (*tmp == '\n')) { + SDL_free(output); + return 0; /* User simply closed the dialog */ + } + + /* It likes to add a newline... */ + tmp = SDL_strrchr(output, '\n'); + if (tmp) { + *tmp = '\0'; + } + + /* Check which button got pressed */ + for (i = 0; i < messageboxdata->numbuttons; i += 1) { + if (messageboxdata->buttons[i].text) { + if (SDL_strcmp(output, messageboxdata->buttons[i].text) == 0) { + *buttonid = messageboxdata->buttons[i].buttonid; + break; + } + } + } + + SDL_free(output); + return 0; /* success! */ + } + + close(fd_pipe[0]); + close(fd_pipe[1]); + return -1; /* run_zenity() calls SDL_SetError(), so message is already set */ +} + +#endif /* SDL_VIDEO_DRIVER_WAYLAND */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/wayland/SDL_waylandmessagebox.h b/SDL2-2.30.5/src/video/wayland/SDL_waylandmessagebox.h new file mode 100644 index 0000000..2193a6b --- /dev/null +++ b/SDL2-2.30.5/src/video/wayland/SDL_waylandmessagebox.h @@ -0,0 +1,33 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#ifndef SDL_waylandmessagebox_h_ +#define SDL_waylandmessagebox_h_ + +#ifdef SDL_VIDEO_DRIVER_WAYLAND + +extern int Wayland_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid); + +#endif /* SDL_VIDEO_DRIVER_WAYLAND */ + +#endif /* SDL_waylandmessagebox_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/wayland/SDL_waylandmouse.c b/SDL2-2.30.5/src/video/wayland/SDL_waylandmouse.c new file mode 100644 index 0000000..4b72645 --- /dev/null +++ b/SDL2-2.30.5/src/video/wayland/SDL_waylandmouse.c @@ -0,0 +1,732 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_WAYLAND + +#include +#include +#include +#include +#include +#include + +#include "../SDL_sysvideo.h" + +#include "SDL_mouse.h" +#include "../../events/SDL_mouse_c.h" +#include "SDL_waylandvideo.h" +#include "../SDL_pixels_c.h" +#include "SDL_waylandevents_c.h" + +#include "wayland-cursor.h" +#include "SDL_waylandmouse.h" + +#include "SDL_hints.h" +#include "../../SDL_hints_c.h" + +static int Wayland_SetRelativeMouseMode(SDL_bool enabled); + +typedef struct +{ + struct wl_buffer *buffer; + struct wl_surface *surface; + + int hot_x, hot_y; + int w, h; + + /* shm_data is non-NULL for custom cursors. + * When shm_data is NULL, system_cursor must be valid + */ + SDL_SystemCursor system_cursor; + void *shm_data; + size_t shm_data_size; +} Wayland_CursorData; + +#ifdef SDL_USE_LIBDBUS + +#include "../../core/linux/SDL_dbus.h" + +static DBusMessage *wayland_read_dbus_setting(SDL_DBusContext *dbus, const char *key) +{ + static const char *iface = "org.gnome.desktop.interface"; + + DBusMessage *reply = NULL; + DBusMessage *msg = dbus->message_new_method_call("org.freedesktop.portal.Desktop", /* Node */ + "/org/freedesktop/portal/desktop", /* Path */ + "org.freedesktop.portal.Settings", /* Interface */ + "Read"); /* Method */ + + if (msg) { + if (dbus->message_append_args(msg, DBUS_TYPE_STRING, &iface, DBUS_TYPE_STRING, &key, DBUS_TYPE_INVALID)) { + reply = dbus->connection_send_with_reply_and_block(dbus->session_conn, msg, DBUS_TIMEOUT_USE_DEFAULT, NULL); + } + dbus->message_unref(msg); + } + + return reply; +} + +static SDL_bool wayland_parse_dbus_reply(SDL_DBusContext *dbus, DBusMessage *reply, int type, void *value) +{ + DBusMessageIter iter[3]; + + dbus->message_iter_init(reply, &iter[0]); + if (dbus->message_iter_get_arg_type(&iter[0]) != DBUS_TYPE_VARIANT) { + return SDL_FALSE; + } + + dbus->message_iter_recurse(&iter[0], &iter[1]); + if (dbus->message_iter_get_arg_type(&iter[1]) != DBUS_TYPE_VARIANT) { + return SDL_FALSE; + } + + dbus->message_iter_recurse(&iter[1], &iter[2]); + if (dbus->message_iter_get_arg_type(&iter[2]) != type) { + return SDL_FALSE; + } + + dbus->message_iter_get_basic(&iter[2], value); + + return SDL_TRUE; +} + +static SDL_bool wayland_dbus_read_cursor_size(int *size) +{ + static const char *cursor_size_value = "cursor-size"; + + DBusMessage *reply; + SDL_DBusContext *dbus = SDL_DBus_GetContext(); + + if (!dbus || !size) { + return SDL_FALSE; + } + + if ((reply = wayland_read_dbus_setting(dbus, cursor_size_value))) { + if (wayland_parse_dbus_reply(dbus, reply, DBUS_TYPE_INT32, size)) { + dbus->message_unref(reply); + return SDL_TRUE; + } + dbus->message_unref(reply); + } + + return SDL_FALSE; +} + +static SDL_bool wayland_dbus_read_cursor_theme(char **theme) +{ + static const char *cursor_theme_value = "cursor-theme"; + + DBusMessage *reply; + SDL_DBusContext *dbus = SDL_DBus_GetContext(); + + if (!dbus || !theme) { + return SDL_FALSE; + } + + if ((reply = wayland_read_dbus_setting(dbus, cursor_theme_value))) { + const char *temp; + if (wayland_parse_dbus_reply(dbus, reply, DBUS_TYPE_STRING, &temp)) { + *theme = SDL_strdup(temp); + dbus->message_unref(reply); + return SDL_TRUE; + } + dbus->message_unref(reply); + } + + return SDL_FALSE; +} + +#endif + + +static const char *GetLegacyCursorName(SDL_SystemCursor system_cursor) +{ + switch (system_cursor) { + case SDL_SYSTEM_CURSOR_ARROW: return "left_ptr"; + case SDL_SYSTEM_CURSOR_IBEAM: return "xterm"; + case SDL_SYSTEM_CURSOR_WAIT: return "watch"; + case SDL_SYSTEM_CURSOR_CROSSHAIR: return "tcross"; + case SDL_SYSTEM_CURSOR_WAITARROW: return "watch"; + case SDL_SYSTEM_CURSOR_SIZENWSE: return "top_left_corner"; + case SDL_SYSTEM_CURSOR_SIZENESW: return "top_right_corner"; + case SDL_SYSTEM_CURSOR_SIZEWE: return "sb_h_double_arrow"; + case SDL_SYSTEM_CURSOR_SIZENS: return "sb_v_double_arrow"; + case SDL_SYSTEM_CURSOR_SIZEALL: return "fleur"; + case SDL_SYSTEM_CURSOR_NO: return "pirate"; + case SDL_SYSTEM_CURSOR_HAND: return "hand2"; + case SDL_NUM_SYSTEM_CURSORS: break; /* so the compiler might notice if an enum value is missing here. */ + } + + SDL_assert(0); + return NULL; +} + +static SDL_bool wayland_get_system_cursor(SDL_VideoData *vdata, Wayland_CursorData *cdata, float *scale) +{ + struct wl_cursor_theme *theme = NULL; + struct wl_cursor *cursor; + const char *cssname = NULL; + const char *fallback_name = NULL; + + char *xcursor_size; + int size = 0; + + SDL_Window *focus; + SDL_WindowData *focusdata; + int i; + + /* + * GNOME based desktops expose the cursor size and theme via the + * org.freedesktop.portal.Settings interface of the xdg-desktop portal. + * Try XCURSOR_SIZE and XCURSOR_THEME first, so user specified sizes and + * themes take precedence over all, then try D-Bus if the envvar isn't + * set, then fall back to the defaults if none of the preceding values + * are available or valid. + */ + if ((xcursor_size = SDL_getenv("XCURSOR_SIZE"))) { + size = SDL_atoi(xcursor_size); + } +#ifdef SDL_USE_LIBDBUS + if (size <= 0) { + wayland_dbus_read_cursor_size(&size); + } +#endif + if (size <= 0) { + size = 24; + } + /* First, find the appropriate theme based on the current scale... */ + focus = SDL_GetMouse()->focus; + if (!focus) { + /* Nothing to see here, bail. */ + return SDL_FALSE; + } + focusdata = focus->driverdata; + + /* Cursors use integer scaling. */ + *scale = SDL_ceilf(focusdata->scale_factor); + size *= *scale; + for (i = 0; i < vdata->num_cursor_themes; i += 1) { + if (vdata->cursor_themes[i].size == size) { + theme = vdata->cursor_themes[i].theme; + break; + } + } + if (!theme) { + char *xcursor_theme = NULL; + SDL_bool free_theme_str = SDL_FALSE; + + vdata->cursor_themes = SDL_realloc(vdata->cursor_themes, + sizeof(SDL_WaylandCursorTheme) * (vdata->num_cursor_themes + 1)); + if (!vdata->cursor_themes) { + SDL_OutOfMemory(); + return SDL_FALSE; + } + xcursor_theme = SDL_getenv("XCURSOR_THEME"); +#ifdef SDL_USE_LIBDBUS + if (!xcursor_theme) { + /* Allocates the string with SDL_strdup, which must be freed. */ + free_theme_str = wayland_dbus_read_cursor_theme(&xcursor_theme); + } +#endif + theme = WAYLAND_wl_cursor_theme_load(xcursor_theme, size, vdata->shm); + vdata->cursor_themes[vdata->num_cursor_themes].size = size; + vdata->cursor_themes[vdata->num_cursor_themes++].theme = theme; + + if (free_theme_str) { + SDL_free(xcursor_theme); + } + } + + /* Next, find the cursor from the theme... */ + cssname = SDL_GetCSSCursorName(cdata->system_cursor, &fallback_name); + + cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, cssname); + if (!cursor && fallback_name) { + cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, fallback_name); + } + + /* try the legacy name if the fancy new CSS name doesn't work... */ + if (!cursor) { + cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, GetLegacyCursorName(cdata->system_cursor)); + } + + /* Fallback to the default cursor if the chosen one wasn't found */ + if (!cursor) { + cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "default"); + } + /* Try the old X11 name as a last resort */ + if (!cursor) { + cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "left_ptr"); + } + if (!cursor) { + return SDL_FALSE; + } + + /* ... Set the cursor data, finally. */ + cdata->buffer = WAYLAND_wl_cursor_image_get_buffer(cursor->images[0]); + cdata->hot_x = cursor->images[0]->hotspot_x; + cdata->hot_y = cursor->images[0]->hotspot_y; + cdata->w = cursor->images[0]->width; + cdata->h = cursor->images[0]->height; + return SDL_TRUE; +} + +static int set_tmp_file_size(int fd, off_t size) +{ +#ifdef HAVE_POSIX_FALLOCATE + sigset_t set, old_set; + int ret; + + /* SIGALRM can potentially block a large posix_fallocate() operation + * from succeeding, so block it. + */ + sigemptyset(&set); + sigaddset(&set, SIGALRM); + sigprocmask(SIG_BLOCK, &set, &old_set); + + do { + ret = posix_fallocate(fd, 0, size); + } while (ret == EINTR); + + sigprocmask(SIG_SETMASK, &old_set, NULL); + + if (ret == 0) { + return 0; + } + else if (ret != EINVAL && errno != EOPNOTSUPP) { + return -1; + } +#endif + + if (ftruncate(fd, size) < 0) { + return -1; + } + return 0; +} + +static int wayland_create_tmp_file(off_t size) +{ + int fd; + +#ifdef HAVE_MEMFD_CREATE + fd = memfd_create("SDL", MFD_CLOEXEC | MFD_ALLOW_SEALING); + if (fd >= 0) { + fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_SEAL); + } else +#endif + { + static const char template[] = "/sdl-shared-XXXXXX"; + char *xdg_path; + char tmp_path[PATH_MAX]; + + xdg_path = SDL_getenv("XDG_RUNTIME_DIR"); + if (!xdg_path) { + return -1; + } + + SDL_strlcpy(tmp_path, xdg_path, PATH_MAX); + SDL_strlcat(tmp_path, template, PATH_MAX); + + fd = mkostemp(tmp_path, O_CLOEXEC); + if (fd < 0) { + return -1; + } + + /* Need to manually unlink the temp files, or they can persist after close and fill up the temp storage. */ + unlink(tmp_path); + } + + if (set_tmp_file_size(fd, size) < 0) { + close(fd); + return -1; + } + + return fd; +} + +static void mouse_buffer_release(void *data, struct wl_buffer *buffer) +{ +} + +static const struct wl_buffer_listener mouse_buffer_listener = { + mouse_buffer_release +}; + +static int create_buffer_from_shm(Wayland_CursorData *d, + int width, + int height, + uint32_t format) +{ + SDL_VideoDevice *vd = SDL_GetVideoDevice(); + SDL_VideoData *data = (SDL_VideoData *)vd->driverdata; + struct wl_shm_pool *shm_pool; + int shm_fd; + + int stride = width * 4; + d->shm_data_size = stride * height; + + shm_fd = wayland_create_tmp_file(d->shm_data_size); + if (shm_fd < 0) { + return SDL_SetError("Creating mouse cursor buffer failed."); + } + + d->shm_data = mmap(NULL, + d->shm_data_size, + PROT_READ | PROT_WRITE, + MAP_SHARED, + shm_fd, + 0); + if (d->shm_data == MAP_FAILED) { + d->shm_data = NULL; + close(shm_fd); + return SDL_SetError("mmap() failed."); + } + + SDL_assert(d->shm_data != NULL); + + shm_pool = wl_shm_create_pool(data->shm, shm_fd, d->shm_data_size); + d->buffer = wl_shm_pool_create_buffer(shm_pool, + 0, + width, + height, + stride, + format); + wl_buffer_add_listener(d->buffer, + &mouse_buffer_listener, + d); + + wl_shm_pool_destroy(shm_pool); + close(shm_fd); + + return 0; +} + +static SDL_Cursor *Wayland_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y) +{ + SDL_Cursor *cursor; + + cursor = SDL_calloc(1, sizeof(*cursor)); + if (cursor) { + SDL_VideoDevice *vd = SDL_GetVideoDevice(); + SDL_VideoData *wd = (SDL_VideoData *)vd->driverdata; + Wayland_CursorData *data = SDL_calloc(1, sizeof(Wayland_CursorData)); + if (!data) { + SDL_OutOfMemory(); + SDL_free(cursor); + return NULL; + } + cursor->driverdata = (void *)data; + + /* Allocate shared memory buffer for this cursor */ + if (create_buffer_from_shm(data, + surface->w, + surface->h, + WL_SHM_FORMAT_ARGB8888) < 0) { + SDL_free(cursor->driverdata); + SDL_free(cursor); + return NULL; + } + + /* Wayland requires premultiplied alpha for its surfaces. */ + SDL_PremultiplyAlpha(surface->w, surface->h, + surface->format->format, surface->pixels, surface->pitch, + SDL_PIXELFORMAT_ARGB8888, data->shm_data, surface->w * 4); + + data->surface = wl_compositor_create_surface(wd->compositor); + wl_surface_set_user_data(data->surface, NULL); + + data->hot_x = hot_x; + data->hot_y = hot_y; + data->w = surface->w; + data->h = surface->h; + } else { + SDL_OutOfMemory(); + } + + return cursor; +} + +static SDL_Cursor *Wayland_CreateSystemCursor(SDL_SystemCursor id) +{ + SDL_VideoData *data = SDL_GetVideoDevice()->driverdata; + SDL_Cursor *cursor; + + cursor = SDL_calloc(1, sizeof(*cursor)); + if (cursor) { + Wayland_CursorData *cdata = SDL_calloc(1, sizeof(Wayland_CursorData)); + if (!cdata) { + SDL_OutOfMemory(); + SDL_free(cursor); + return NULL; + } + cursor->driverdata = (void *)cdata; + + cdata->surface = wl_compositor_create_surface(data->compositor); + wl_surface_set_user_data(cdata->surface, NULL); + + /* Note that we can't actually set any other cursor properties, as this + * is output-specific. See wayland_get_system_cursor for the rest! + */ + cdata->system_cursor = id; + } else { + SDL_OutOfMemory(); + } + + return cursor; +} + +static SDL_Cursor *Wayland_CreateDefaultCursor() +{ + return Wayland_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); +} + +static void Wayland_FreeCursorData(Wayland_CursorData *d) +{ + if (d->buffer) { + if (d->shm_data) { + wl_buffer_destroy(d->buffer); + munmap(d->shm_data, d->shm_data_size); + } + d->buffer = NULL; + } + + if (d->surface) { + wl_surface_destroy(d->surface); + d->surface = NULL; + } +} + +static void Wayland_FreeCursor(SDL_Cursor *cursor) +{ + if (!cursor) { + return; + } + + /* Probably not a cursor we own */ + if (!cursor->driverdata) { + return; + } + + Wayland_FreeCursorData((Wayland_CursorData *)cursor->driverdata); + + SDL_free(cursor->driverdata); + SDL_free(cursor); +} + +static int Wayland_ShowCursor(SDL_Cursor *cursor) +{ + SDL_VideoDevice *vd = SDL_GetVideoDevice(); + SDL_VideoData *d = vd->driverdata; + struct SDL_WaylandInput *input = d->input; + struct wl_pointer *pointer = d->pointer; + float scale = 1.0f; + + if (!pointer) { + return -1; + } + + if (cursor) { + Wayland_CursorData *data = cursor->driverdata; + + /* TODO: High-DPI custom cursors? -flibit */ + if (!data->shm_data) { + if (!wayland_get_system_cursor(d, data, &scale)) { + return -1; + } + } + + wl_surface_set_buffer_scale(data->surface, scale); + wl_pointer_set_cursor(pointer, + input->pointer_enter_serial, + data->surface, + data->hot_x / scale, + data->hot_y / scale); + wl_surface_attach(data->surface, data->buffer, 0, 0); + wl_surface_damage(data->surface, 0, 0, data->w, data->h); + wl_surface_commit(data->surface); + + input->cursor_visible = SDL_TRUE; + + if (input->relative_mode_override) { + Wayland_input_unlock_pointer(input); + input->relative_mode_override = SDL_FALSE; + } + + } else { + input->cursor_visible = SDL_FALSE; + wl_pointer_set_cursor(pointer, input->pointer_enter_serial, NULL, 0, 0); + } + + return 0; +} + +static void Wayland_WarpMouse(SDL_Window *window, int x, int y) +{ + SDL_VideoDevice *vd = SDL_GetVideoDevice(); + SDL_VideoData *d = vd->driverdata; + struct SDL_WaylandInput *input = d->input; + + if (input->cursor_visible == SDL_TRUE) { + SDL_Unsupported(); + } else if (input->warp_emulation_prohibited) { + SDL_Unsupported(); + } else { + if (!d->relative_mouse_mode) { + Wayland_input_lock_pointer(input); + input->relative_mode_override = SDL_TRUE; + } + } +} + +static int Wayland_WarpMouseGlobal(int x, int y) +{ + return SDL_Unsupported(); +} + +static int Wayland_SetRelativeMouseMode(SDL_bool enabled) +{ + SDL_VideoDevice *vd = SDL_GetVideoDevice(); + SDL_VideoData *data = (SDL_VideoData *)vd->driverdata; + + if (enabled) { + /* Disable mouse warp emulation if it's enabled. */ + if (data->input->relative_mode_override) { + data->input->relative_mode_override = SDL_FALSE; + } + + /* If the app has used relative mode before, it probably shouldn't + * also be emulating it using repeated mouse warps, so disable + * mouse warp emulation by default. + */ + data->input->warp_emulation_prohibited = SDL_TRUE; + return Wayland_input_lock_pointer(data->input); + } else { + return Wayland_input_unlock_pointer(data->input); + } +} + +static void SDLCALL Wayland_EmulateMouseWarpChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + struct SDL_WaylandInput *input = (struct SDL_WaylandInput *)userdata; + + input->warp_emulation_prohibited = !SDL_GetStringBoolean(hint, !input->warp_emulation_prohibited); +} + +#if 0 /* TODO RECONNECT: See waylandvideo.c for more information! */ +static void Wayland_RecreateCursor(SDL_Cursor *cursor, SDL_VideoData *vdata) +{ + Wayland_CursorData *cdata = (Wayland_CursorData *) cursor->driverdata; + + /* Probably not a cursor we own */ + if (cdata == NULL) { + return; + } + + Wayland_FreeCursorData(cdata); + + /* We're not currently freeing this, so... yolo? */ + if (cdata->shm_data != NULL) { + void *old_data_pointer = cdata->shm_data; + int stride = cdata->w * 4; + + create_buffer_from_shm(cdata, cdata->w, cdata->h, WL_SHM_FORMAT_ARGB8888); + + SDL_memcpy(cdata->shm_data, old_data_pointer, stride * cdata->h); + } + cdata->surface = wl_compositor_create_surface(vdata->compositor); + wl_surface_set_user_data(cdata->surface, NULL); +} + +void Wayland_RecreateCursors(void) +{ + SDL_Cursor *cursor; + SDL_Mouse *mouse = SDL_GetMouse(); + SDL_VideoData *vdata = SDL_GetVideoDevice()->driverdata; + + if (vdata && vdata->cursor_themes) { + SDL_free(vdata->cursor_themes); + vdata->cursor_themes = NULL; + vdata->num_cursor_themes = 0; + } + + if (mouse == NULL) { + return; + } + + for (cursor = mouse->cursors; cursor != NULL; cursor = cursor->next) { + Wayland_RecreateCursor(cursor, vdata); + } + if (mouse->def_cursor) { + Wayland_RecreateCursor(mouse->def_cursor, vdata); + } + if (mouse->cur_cursor) { + Wayland_RecreateCursor(mouse->cur_cursor, vdata); + if (mouse->cursor_shown) { + Wayland_ShowCursor(mouse->cur_cursor); + } + } +} +#endif /* 0 */ + +void Wayland_InitMouse(void) +{ + SDL_Mouse *mouse = SDL_GetMouse(); + SDL_VideoDevice *vd = SDL_GetVideoDevice(); + SDL_VideoData *d = vd->driverdata; + struct SDL_WaylandInput *input = d->input; + + mouse->CreateCursor = Wayland_CreateCursor; + mouse->CreateSystemCursor = Wayland_CreateSystemCursor; + mouse->ShowCursor = Wayland_ShowCursor; + mouse->FreeCursor = Wayland_FreeCursor; + mouse->WarpMouse = Wayland_WarpMouse; + mouse->WarpMouseGlobal = Wayland_WarpMouseGlobal; + mouse->SetRelativeMouseMode = Wayland_SetRelativeMouseMode; + + input->relative_mode_override = SDL_FALSE; + input->cursor_visible = SDL_TRUE; + + SDL_SetDefaultCursor(Wayland_CreateDefaultCursor()); + + SDL_AddHintCallback(SDL_HINT_VIDEO_WAYLAND_EMULATE_MOUSE_WARP, + Wayland_EmulateMouseWarpChanged, input); +} + +void Wayland_FiniMouse(SDL_VideoData *data) +{ + struct SDL_WaylandInput *input = data->input; + int i; + for (i = 0; i < data->num_cursor_themes; i += 1) { + WAYLAND_wl_cursor_theme_destroy(data->cursor_themes[i].theme); + } + data->num_cursor_themes = 0; + SDL_free(data->cursor_themes); + data->cursor_themes = NULL; + + SDL_DelHintCallback(SDL_HINT_VIDEO_WAYLAND_EMULATE_MOUSE_WARP, + Wayland_EmulateMouseWarpChanged, input); +} + +#endif /* SDL_VIDEO_DRIVER_WAYLAND */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/wayland/SDL_waylandmouse.h b/SDL2-2.30.5/src/video/wayland/SDL_waylandmouse.h similarity index 78% rename from SDL2-2.0.12/src/video/wayland/SDL_waylandmouse.h rename to SDL2-2.30.5/src/video/wayland/SDL_waylandmouse.h index 95ff719..4f3296d 100644 --- a/SDL2-2.0.12/src/video/wayland/SDL_waylandmouse.h +++ b/SDL2-2.30.5/src/video/wayland/SDL_waylandmouse.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,9 +23,12 @@ #include "SDL_mouse.h" #include "SDL_waylandvideo.h" -#if SDL_VIDEO_DRIVER_WAYLAND +#ifdef SDL_VIDEO_DRIVER_WAYLAND extern void Wayland_InitMouse(void); -extern void Wayland_FiniMouse(void); +extern void Wayland_FiniMouse(SDL_VideoData *data); +#if 0 /* TODO RECONNECT: See waylandvideo.c for more information! */ +extern void Wayland_RecreateCursors(void); +#endif /* 0 */ #endif diff --git a/SDL2-2.30.5/src/video/wayland/SDL_waylandopengles.c b/SDL2-2.30.5/src/video/wayland/SDL_waylandopengles.c new file mode 100644 index 0000000..22311a6 --- /dev/null +++ b/SDL2-2.30.5/src/video/wayland/SDL_waylandopengles.c @@ -0,0 +1,200 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#if defined(SDL_VIDEO_DRIVER_WAYLAND) && defined(SDL_VIDEO_OPENGL_EGL) + +#include "SDL_timer.h" +#include "../../core/unix/SDL_poll.h" +#include "../SDL_sysvideo.h" +#include "../../events/SDL_windowevents_c.h" +#include "SDL_waylandvideo.h" +#include "SDL_waylandopengles.h" +#include "SDL_waylandwindow.h" +#include "SDL_waylandevents_c.h" + +#include "xdg-shell-client-protocol.h" + +/* EGL implementation of SDL OpenGL ES support */ + +int Wayland_GLES_LoadLibrary(_THIS, const char *path) +{ + int ret; + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; + + ret = SDL_EGL_LoadLibrary(_this, path, (NativeDisplayType) data->display, 0); + + Wayland_PumpEvents(_this); + WAYLAND_wl_display_flush(data->display); + + return ret; +} + +SDL_GLContext Wayland_GLES_CreateContext(_THIS, SDL_Window *window) +{ + SDL_GLContext context; + context = SDL_EGL_CreateContext(_this, ((SDL_WindowData *)window->driverdata)->egl_surface); + WAYLAND_wl_display_flush(((SDL_VideoData *)_this->driverdata)->display); + + return context; +} + +/* Wayland wants to tell you when to provide new frames, and if you have a non-zero + swap interval, Mesa will block until a callback tells it to do so. On some + compositors, they might decide that a minimized window _never_ gets a callback, + which causes apps to hang during swapping forever. So we always set the official + eglSwapInterval to zero to avoid blocking inside EGL, and manage this ourselves. + If a swap blocks for too long waiting on a callback, we just go on, under the + assumption the frame will be wasted, but this is better than freezing the app. + I frown upon platforms that dictate this sort of control inversion (the callback + is intended for _rendering_, not stalling until vsync), but we can work around + this for now. --ryan. */ +/* Addendum: several recent APIs demand this sort of control inversion: Emscripten, + libretro, Wayland, probably others...it feels like we're eventually going to have + to give in with a future SDL API revision, since we can bend the other APIs to + this style, but this style is much harder to bend the other way. :/ */ +int Wayland_GLES_SetSwapInterval(_THIS, int interval) +{ + if (!_this->egl_data) { + return SDL_SetError("EGL not initialized"); + } + + /* technically, this is _all_ adaptive vsync (-1), because we can't + actually wait for the _next_ vsync if you set 1, but things that + request 1 probably won't care _that_ much. I hope. No matter what + you do, though, you never see tearing on Wayland. */ + if (interval > 1) { + interval = 1; + } else if (interval < -1) { + interval = -1; + } + + /* !!! FIXME: technically, this should be per-context, right? */ + _this->egl_data->egl_swapinterval = interval; + _this->egl_data->eglSwapInterval(_this->egl_data->egl_display, 0); + return 0; +} + +int Wayland_GLES_GetSwapInterval(_THIS) +{ + if (!_this->egl_data) { + SDL_SetError("EGL not initialized"); + return 0; + } + + return _this->egl_data->egl_swapinterval; +} + +int Wayland_GLES_SwapWindow(_THIS, SDL_Window *window) +{ + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + const int swap_interval = _this->egl_data->egl_swapinterval; + + /* For windows that we know are hidden, skip swaps entirely, if we don't do + * this compositors will intentionally stall us indefinitely and there's no + * way for an end user to show the window, unlike other situations (i.e. + * the window is minimized, behind another window, etc.). + * + * FIXME: Request EGL_WAYLAND_swap_buffers_with_timeout. + * -flibit + */ + if (window->flags & SDL_WINDOW_HIDDEN) { + return 0; + } + + /* Control swap interval ourselves. See comments on Wayland_GLES_SetSwapInterval */ + if (swap_interval != 0) { + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + struct wl_display *display = videodata->display; + SDL_VideoDisplay *sdldisplay = SDL_GetDisplayForWindow(window); + /* 1/3 speed (or 20hz), so we'll progress even if throttled to zero. */ + const Uint32 max_wait = SDL_GetTicks() + (sdldisplay && sdldisplay->current_mode.refresh_rate ? (3000 / sdldisplay->current_mode.refresh_rate) : 50); + while (SDL_AtomicGet(&data->swap_interval_ready) == 0) { + Uint32 now; + + WAYLAND_wl_display_flush(display); + + /* wl_display_prepare_read_queue() will return -1 if the event queue is not empty. + * If the event queue is empty, it will prepare us for our SDL_IOReady() call. */ + if (WAYLAND_wl_display_prepare_read_queue(display, data->gles_swap_frame_event_queue) != 0) { + /* We have some pending events. Check if the frame callback happened. */ + WAYLAND_wl_display_dispatch_queue_pending(display, data->gles_swap_frame_event_queue); + continue; + } + + /* Beyond this point, we must either call wl_display_cancel_read() or wl_display_read_events() */ + + now = SDL_GetTicks(); + if (SDL_TICKS_PASSED(now, max_wait)) { + /* Timeout expired. Cancel the read. */ + WAYLAND_wl_display_cancel_read(display); + break; + } + + if (SDL_IOReady(WAYLAND_wl_display_get_fd(display), SDL_IOR_READ, max_wait - now) <= 0) { + /* Error or timeout expired without any events for us. Cancel the read. */ + WAYLAND_wl_display_cancel_read(display); + break; + } + + /* We have events. Read and dispatch them. */ + WAYLAND_wl_display_read_events(display); + WAYLAND_wl_display_dispatch_queue_pending(display, data->gles_swap_frame_event_queue); + } + SDL_AtomicSet(&data->swap_interval_ready, 0); + } + + /* Feed the frame to Wayland. This will set it so the wl_surface_frame callback can fire again. */ + if (!_this->egl_data->eglSwapBuffers(_this->egl_data->egl_display, data->egl_surface)) { + return SDL_EGL_SetError("unable to show color buffer in an OS-native window", "eglSwapBuffers"); + } + + WAYLAND_wl_display_flush(data->waylandData->display); + + return 0; +} + +int Wayland_GLES_MakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context) +{ + int ret; + + if (window && context) { + ret = SDL_EGL_MakeCurrent(_this, ((SDL_WindowData *)window->driverdata)->egl_surface, context); + } else { + ret = SDL_EGL_MakeCurrent(_this, NULL, NULL); + } + + WAYLAND_wl_display_flush(((SDL_VideoData *)_this->driverdata)->display); + + _this->egl_data->eglSwapInterval(_this->egl_data->egl_display, 0); /* see comments on Wayland_GLES_SetSwapInterval. */ + + return ret; +} + +void Wayland_GLES_DeleteContext(_THIS, SDL_GLContext context) +{ + SDL_EGL_DeleteContext(_this, context); + WAYLAND_wl_display_flush(((SDL_VideoData *)_this->driverdata)->display); +} + +#endif /* SDL_VIDEO_DRIVER_WAYLAND && SDL_VIDEO_OPENGL_EGL */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/wayland/SDL_waylandopengles.h b/SDL2-2.30.5/src/video/wayland/SDL_waylandopengles.h similarity index 78% rename from SDL2-2.0.12/src/video/wayland/SDL_waylandopengles.h rename to SDL2-2.30.5/src/video/wayland/SDL_waylandopengles.h index 23039c3..772a80a 100644 --- a/SDL2-2.0.12/src/video/wayland/SDL_waylandopengles.h +++ b/SDL2-2.30.5/src/video/wayland/SDL_waylandopengles.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -35,14 +35,13 @@ typedef struct SDL_PrivateGLESData #define Wayland_GLES_GetAttribute SDL_EGL_GetAttribute #define Wayland_GLES_GetProcAddress SDL_EGL_GetProcAddress #define Wayland_GLES_UnloadLibrary SDL_EGL_UnloadLibrary -#define Wayland_GLES_SetSwapInterval SDL_EGL_SetSwapInterval -#define Wayland_GLES_GetSwapInterval SDL_EGL_GetSwapInterval extern int Wayland_GLES_LoadLibrary(_THIS, const char *path); -extern SDL_GLContext Wayland_GLES_CreateContext(_THIS, SDL_Window * window); -extern int Wayland_GLES_SwapWindow(_THIS, SDL_Window * window); -extern int Wayland_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context); -extern void Wayland_GLES_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h); +extern SDL_GLContext Wayland_GLES_CreateContext(_THIS, SDL_Window *window); +extern int Wayland_GLES_SetSwapInterval(_THIS, int interval); +extern int Wayland_GLES_GetSwapInterval(_THIS); +extern int Wayland_GLES_SwapWindow(_THIS, SDL_Window *window); +extern int Wayland_GLES_MakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context); extern void Wayland_GLES_DeleteContext(_THIS, SDL_GLContext context); #endif /* SDL_waylandopengles_h_ */ diff --git a/SDL2-2.30.5/src/video/wayland/SDL_waylandsym.h b/SDL2-2.30.5/src/video/wayland/SDL_waylandsym.h new file mode 100644 index 0000000..1b02b01 --- /dev/null +++ b/SDL2-2.30.5/src/video/wayland/SDL_waylandsym.h @@ -0,0 +1,239 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +/* *INDENT-OFF* */ /* clang-format off */ + +#ifndef SDL_WAYLAND_MODULE +#define SDL_WAYLAND_MODULE(modname) +#endif + +#ifndef SDL_WAYLAND_SYM +#define SDL_WAYLAND_SYM(rc,fn,params) +#endif + +#ifndef SDL_WAYLAND_SYM_OPT +#define SDL_WAYLAND_SYM_OPT(rc,fn,params) +#endif + +#ifndef SDL_WAYLAND_INTERFACE +#define SDL_WAYLAND_INTERFACE(iface) +#endif + +#include + +SDL_WAYLAND_MODULE(WAYLAND_CLIENT) +SDL_WAYLAND_SYM(void, wl_proxy_marshal, (struct wl_proxy *, uint32_t, ...)) +SDL_WAYLAND_SYM(struct wl_proxy *, wl_proxy_create, (struct wl_proxy *, const struct wl_interface *)) +SDL_WAYLAND_SYM(void, wl_proxy_destroy, (struct wl_proxy *)) +SDL_WAYLAND_SYM(int, wl_proxy_add_listener, (struct wl_proxy *, void (**)(void), void *)) +SDL_WAYLAND_SYM(void, wl_proxy_set_user_data, (struct wl_proxy *, void *)) +SDL_WAYLAND_SYM(void *, wl_proxy_get_user_data, (struct wl_proxy *)) +SDL_WAYLAND_SYM(uint32_t, wl_proxy_get_version, (struct wl_proxy *)) +SDL_WAYLAND_SYM(uint32_t, wl_proxy_get_id, (struct wl_proxy *)) +SDL_WAYLAND_SYM(const char *, wl_proxy_get_class, (struct wl_proxy *)) +SDL_WAYLAND_SYM(void, wl_proxy_set_queue, (struct wl_proxy *, struct wl_event_queue *)) +SDL_WAYLAND_SYM(void *, wl_proxy_create_wrapper, (void *)) +SDL_WAYLAND_SYM(void, wl_proxy_wrapper_destroy, (void *)) +SDL_WAYLAND_SYM(struct wl_display *, wl_display_connect, (const char *)) +SDL_WAYLAND_SYM(struct wl_display *, wl_display_connect_to_fd, (int)) +SDL_WAYLAND_SYM(void, wl_display_disconnect, (struct wl_display *)) +SDL_WAYLAND_SYM(int, wl_display_get_fd, (struct wl_display *)) +SDL_WAYLAND_SYM(int, wl_display_dispatch, (struct wl_display *)) +SDL_WAYLAND_SYM(int, wl_display_dispatch_queue, (struct wl_display *, struct wl_event_queue *)) +SDL_WAYLAND_SYM(int, wl_display_dispatch_queue_pending, (struct wl_display *, struct wl_event_queue *)) +SDL_WAYLAND_SYM(int, wl_display_dispatch_pending, (struct wl_display *)) +SDL_WAYLAND_SYM(int, wl_display_prepare_read, (struct wl_display *)) +SDL_WAYLAND_SYM(int, wl_display_prepare_read_queue, (struct wl_display *, struct wl_event_queue *)) +SDL_WAYLAND_SYM(int, wl_display_read_events, (struct wl_display *)) +SDL_WAYLAND_SYM(void, wl_display_cancel_read, (struct wl_display *)) +SDL_WAYLAND_SYM(int, wl_display_get_error, (struct wl_display *)) +SDL_WAYLAND_SYM(int, wl_display_flush, (struct wl_display *)) +SDL_WAYLAND_SYM(int, wl_display_roundtrip, (struct wl_display *)) +SDL_WAYLAND_SYM(struct wl_event_queue *, wl_display_create_queue, (struct wl_display *)) +SDL_WAYLAND_SYM(void, wl_event_queue_destroy, (struct wl_event_queue *)) +SDL_WAYLAND_SYM(void, wl_log_set_handler_client, (wl_log_func_t)) +SDL_WAYLAND_SYM(void, wl_list_init, (struct wl_list *)) +SDL_WAYLAND_SYM(void, wl_list_insert, (struct wl_list *, struct wl_list *) ) +SDL_WAYLAND_SYM(void, wl_list_remove, (struct wl_list *)) +SDL_WAYLAND_SYM(int, wl_list_length, (const struct wl_list *)) +SDL_WAYLAND_SYM(int, wl_list_empty, (const struct wl_list *)) +SDL_WAYLAND_SYM(void, wl_list_insert_list, (struct wl_list *, struct wl_list *)) +SDL_WAYLAND_SYM(struct wl_proxy *, wl_proxy_marshal_constructor, (struct wl_proxy *, uint32_t opcode, const struct wl_interface *interface, ...)) +SDL_WAYLAND_SYM(struct wl_proxy *, wl_proxy_marshal_constructor_versioned, (struct wl_proxy *proxy, uint32_t opcode, const struct wl_interface *interface, uint32_t version, ...)) +SDL_WAYLAND_SYM(void, wl_proxy_set_tag, (struct wl_proxy *, const char * const *)) +SDL_WAYLAND_SYM(const char * const *, wl_proxy_get_tag, (struct wl_proxy *)) + +#if SDL_WAYLAND_CHECK_VERSION(1, 20, 0) +/* wayland-scanner 1.20 generates code that will call these, so these are + * non-optional when we are compiling against Wayland 1.20. We don't + * explicitly call them ourselves, though, so if we are only compiling + * against Wayland 1.18, they're unnecessary. */ +SDL_WAYLAND_SYM(struct wl_proxy*, wl_proxy_marshal_flags, (struct wl_proxy *proxy, uint32_t opcode, const struct wl_interface *interfac, uint32_t version, uint32_t flags, ...)) +SDL_WAYLAND_SYM(struct wl_proxy*, wl_proxy_marshal_array_flags, (struct wl_proxy *proxy, uint32_t opcode, const struct wl_interface *interface, uint32_t version, uint32_t flags, union wl_argument *args)) +#endif + +#if 0 /* TODO RECONNECT: See waylandvideo.c for more information! */ +#if SDL_WAYLAND_CHECK_VERSION(broken, on, purpose) +SDL_WAYLAND_SYM(int, wl_display_reconnect, (struct wl_display*)); +#endif +#endif /* 0 */ + +SDL_WAYLAND_INTERFACE(wl_seat_interface) +SDL_WAYLAND_INTERFACE(wl_surface_interface) +SDL_WAYLAND_INTERFACE(wl_shm_pool_interface) +SDL_WAYLAND_INTERFACE(wl_buffer_interface) +SDL_WAYLAND_INTERFACE(wl_registry_interface) +SDL_WAYLAND_INTERFACE(wl_region_interface) +SDL_WAYLAND_INTERFACE(wl_pointer_interface) +SDL_WAYLAND_INTERFACE(wl_keyboard_interface) +SDL_WAYLAND_INTERFACE(wl_compositor_interface) +SDL_WAYLAND_INTERFACE(wl_output_interface) +SDL_WAYLAND_INTERFACE(wl_shm_interface) +SDL_WAYLAND_INTERFACE(wl_data_device_interface) +SDL_WAYLAND_INTERFACE(wl_data_source_interface) +SDL_WAYLAND_INTERFACE(wl_data_offer_interface) +SDL_WAYLAND_INTERFACE(wl_data_device_manager_interface) + +SDL_WAYLAND_MODULE(WAYLAND_EGL) +SDL_WAYLAND_SYM(struct wl_egl_window *, wl_egl_window_create, (struct wl_surface *, int, int)) +SDL_WAYLAND_SYM(void, wl_egl_window_destroy, (struct wl_egl_window *)) +SDL_WAYLAND_SYM(void, wl_egl_window_resize, (struct wl_egl_window *, int, int, int, int)) +SDL_WAYLAND_SYM(void, wl_egl_window_get_attached_size, (struct wl_egl_window *, int *, int *)) + +SDL_WAYLAND_MODULE(WAYLAND_CURSOR) +SDL_WAYLAND_SYM(struct wl_cursor_theme *, wl_cursor_theme_load, (const char *, int , struct wl_shm *)) +SDL_WAYLAND_SYM(void, wl_cursor_theme_destroy, (struct wl_cursor_theme *)) +SDL_WAYLAND_SYM(struct wl_cursor *, wl_cursor_theme_get_cursor, (struct wl_cursor_theme *, const char *)) +SDL_WAYLAND_SYM(struct wl_buffer *, wl_cursor_image_get_buffer, (struct wl_cursor_image *)) +SDL_WAYLAND_SYM(int, wl_cursor_frame, (struct wl_cursor *, uint32_t)) + +SDL_WAYLAND_MODULE(WAYLAND_XKB) +SDL_WAYLAND_SYM(int, xkb_state_key_get_syms, (struct xkb_state *, xkb_keycode_t, const xkb_keysym_t **)) +SDL_WAYLAND_SYM(int, xkb_keysym_to_utf8, (xkb_keysym_t, char *, size_t) ) +SDL_WAYLAND_SYM(struct xkb_keymap *, xkb_keymap_new_from_string, (struct xkb_context *, const char *, enum xkb_keymap_format, enum xkb_keymap_compile_flags)) +SDL_WAYLAND_SYM(struct xkb_state *, xkb_state_new, (struct xkb_keymap *) ) +SDL_WAYLAND_SYM(int, xkb_keymap_key_repeats, (struct xkb_keymap *keymap, xkb_keycode_t key) ); +SDL_WAYLAND_SYM(void, xkb_keymap_unref, (struct xkb_keymap *) ) +SDL_WAYLAND_SYM(void, xkb_state_unref, (struct xkb_state *) ) +SDL_WAYLAND_SYM(void, xkb_context_unref, (struct xkb_context *) ) +SDL_WAYLAND_SYM(struct xkb_context *, xkb_context_new, (enum xkb_context_flags flags) ) +SDL_WAYLAND_SYM(enum xkb_state_component, xkb_state_update_mask, (struct xkb_state *state,\ + xkb_mod_mask_t depressed_mods,\ + xkb_mod_mask_t latched_mods,\ + xkb_mod_mask_t locked_mods,\ + xkb_layout_index_t depressed_layout,\ + xkb_layout_index_t latched_layout,\ + xkb_layout_index_t locked_layout) ) +SDL_WAYLAND_SYM(struct xkb_compose_table *, xkb_compose_table_new_from_locale, (struct xkb_context *,\ + const char *locale, enum xkb_compose_compile_flags) ) +SDL_WAYLAND_SYM(void, xkb_compose_table_unref, (struct xkb_compose_table *) ) +SDL_WAYLAND_SYM(struct xkb_compose_state *, xkb_compose_state_new, (struct xkb_compose_table *, enum xkb_compose_state_flags) ) +SDL_WAYLAND_SYM(void, xkb_compose_state_unref, (struct xkb_compose_state *) ) +SDL_WAYLAND_SYM(enum xkb_compose_feed_result, xkb_compose_state_feed, (struct xkb_compose_state *, xkb_keysym_t) ) +SDL_WAYLAND_SYM(enum xkb_compose_status, xkb_compose_state_get_status, (struct xkb_compose_state *) ) +SDL_WAYLAND_SYM(xkb_keysym_t, xkb_compose_state_get_one_sym, (struct xkb_compose_state *) ) +SDL_WAYLAND_SYM(void, xkb_keymap_key_for_each, (struct xkb_keymap *, xkb_keymap_key_iter_t, void*) ) +SDL_WAYLAND_SYM(int, xkb_keymap_key_get_syms_by_level, (struct xkb_keymap *, + xkb_keycode_t, + xkb_layout_index_t, + xkb_layout_index_t, + const xkb_keysym_t **) ) +SDL_WAYLAND_SYM(uint32_t, xkb_keysym_to_utf32, (xkb_keysym_t) ) +SDL_WAYLAND_SYM(uint32_t, xkb_keymap_mod_get_index, (struct xkb_keymap *, + const char *) ) +SDL_WAYLAND_SYM(const char *, xkb_keymap_layout_get_name, (struct xkb_keymap*, xkb_layout_index_t)) + +#ifdef HAVE_LIBDECOR_H +SDL_WAYLAND_MODULE(WAYLAND_LIBDECOR) +SDL_WAYLAND_SYM(void, libdecor_unref, (struct libdecor *)) +SDL_WAYLAND_SYM(struct libdecor *, libdecor_new, (struct wl_display *, struct libdecor_interface *)) +SDL_WAYLAND_SYM(struct libdecor_frame *, libdecor_decorate, (struct libdecor *,\ + struct wl_surface *,\ + struct libdecor_frame_interface *,\ + void *)) +SDL_WAYLAND_SYM(void, libdecor_frame_unref, (struct libdecor_frame *)) +SDL_WAYLAND_SYM(void, libdecor_frame_set_title, (struct libdecor_frame *, const char *)) +SDL_WAYLAND_SYM(void, libdecor_frame_set_app_id, (struct libdecor_frame *, const char *)) +SDL_WAYLAND_SYM(void, libdecor_frame_set_max_content_size, (struct libdecor_frame *frame,\ + int content_width,\ + int content_height)) +SDL_WAYLAND_SYM(void, libdecor_frame_set_min_content_size, (struct libdecor_frame *frame,\ + int content_width,\ + int content_height)) +SDL_WAYLAND_SYM(void, libdecor_frame_resize, (struct libdecor_frame *,\ + struct wl_seat *,\ + uint32_t,\ + enum libdecor_resize_edge)) +SDL_WAYLAND_SYM(void, libdecor_frame_move, (struct libdecor_frame *,\ + struct wl_seat *,\ + uint32_t)) +SDL_WAYLAND_SYM(void, libdecor_frame_commit, (struct libdecor_frame *,\ + struct libdecor_state *,\ + struct libdecor_configuration *)) +SDL_WAYLAND_SYM(void, libdecor_frame_set_minimized, (struct libdecor_frame *)) +SDL_WAYLAND_SYM(void, libdecor_frame_set_maximized, (struct libdecor_frame *)) +SDL_WAYLAND_SYM(void, libdecor_frame_unset_maximized, (struct libdecor_frame *)) +SDL_WAYLAND_SYM(void, libdecor_frame_set_fullscreen, (struct libdecor_frame *, struct wl_output *)) +SDL_WAYLAND_SYM(void, libdecor_frame_unset_fullscreen, (struct libdecor_frame *)) +SDL_WAYLAND_SYM(void, libdecor_frame_set_capabilities, (struct libdecor_frame *, \ + enum libdecor_capabilities)) +SDL_WAYLAND_SYM(void, libdecor_frame_unset_capabilities, (struct libdecor_frame *, \ + enum libdecor_capabilities)) +SDL_WAYLAND_SYM(bool, libdecor_frame_has_capability, (struct libdecor_frame *, \ + enum libdecor_capabilities)) +SDL_WAYLAND_SYM(void, libdecor_frame_set_visibility, (struct libdecor_frame *, bool)) +SDL_WAYLAND_SYM(bool, libdecor_frame_is_visible, (struct libdecor_frame *)) +SDL_WAYLAND_SYM(bool, libdecor_frame_is_floating, (struct libdecor_frame *)) +SDL_WAYLAND_SYM(void, libdecor_frame_set_parent, (struct libdecor_frame *,\ + struct libdecor_frame *)) +SDL_WAYLAND_SYM(struct xdg_surface *, libdecor_frame_get_xdg_surface, (struct libdecor_frame *)) +SDL_WAYLAND_SYM(struct xdg_toplevel *, libdecor_frame_get_xdg_toplevel, (struct libdecor_frame *)) +SDL_WAYLAND_SYM(void, libdecor_frame_map, (struct libdecor_frame *)) +SDL_WAYLAND_SYM(struct libdecor_state *, libdecor_state_new, (int, int)) +SDL_WAYLAND_SYM(void, libdecor_state_free, (struct libdecor_state *)) +SDL_WAYLAND_SYM(bool, libdecor_configuration_get_content_size, (struct libdecor_configuration *,\ + struct libdecor_frame *,\ + int *,\ + int *)) +SDL_WAYLAND_SYM(bool, libdecor_configuration_get_window_state, (struct libdecor_configuration *,\ + enum libdecor_window_state *)) +SDL_WAYLAND_SYM(int, libdecor_dispatch, (struct libdecor *, int)) + +#if defined(SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR) || defined(SDL_HAVE_LIBDECOR_GET_MIN_MAX) +/* Only found in libdecor 0.1.1 or higher, so failure to load them is not fatal. */ +SDL_WAYLAND_SYM_OPT(void, libdecor_frame_get_min_content_size, (const struct libdecor_frame *,\ + int *,\ + int *)) +SDL_WAYLAND_SYM_OPT(void, libdecor_frame_get_max_content_size, (const struct libdecor_frame *,\ + int *,\ + int *)) +#endif + +#endif + +#undef SDL_WAYLAND_MODULE +#undef SDL_WAYLAND_SYM +#undef SDL_WAYLAND_SYM_OPT +#undef SDL_WAYLAND_INTERFACE + +/* *INDENT-ON* */ /* clang-format on */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/wayland/SDL_waylandtouch.c b/SDL2-2.30.5/src/video/wayland/SDL_waylandtouch.c similarity index 66% rename from SDL2-2.0.12/src/video/wayland/SDL_waylandtouch.c rename to SDL2-2.30.5/src/video/wayland/SDL_waylandtouch.c index 80ed6bd..7a6b7fc 100644 --- a/SDL2-2.0.12/src/video/wayland/SDL_waylandtouch.c +++ b/SDL2-2.30.5/src/video/wayland/SDL_waylandtouch.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -25,48 +25,47 @@ #ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH -#include "SDL_log.h" #include "SDL_mouse.h" #include "SDL_keyboard.h" #include "SDL_waylandtouch.h" #include "../../events/SDL_touch_c.h" -struct SDL_WaylandTouch { +struct SDL_WaylandTouch +{ struct qt_touch_extension *touch_extension; }; - /** * Qt TouchPointState * adapted from qtbase/src/corelib/global/qnamespace.h **/ -enum QtWaylandTouchPointState { - QtWaylandTouchPointPressed = 0x01, - QtWaylandTouchPointMoved = 0x02, +enum QtWaylandTouchPointState +{ + QtWaylandTouchPointPressed = 0x01, + QtWaylandTouchPointMoved = 0x02, /* Never sent by the server: QtWaylandTouchPointStationary = 0x04, */ - QtWaylandTouchPointReleased = 0x08, + QtWaylandTouchPointReleased = 0x08, }; -static void -touch_handle_touch(void *data, - struct qt_touch_extension *qt_touch_extension, - uint32_t time, - uint32_t id, - uint32_t state, - int32_t x, - int32_t y, - int32_t normalized_x, - int32_t normalized_y, - int32_t width, - int32_t height, - uint32_t pressure, - int32_t velocity_x, - int32_t velocity_y, - uint32_t flags, - struct wl_array *rawdata) +static void touch_handle_touch(void *data, + struct qt_touch_extension *qt_touch_extension, + uint32_t time, + uint32_t id, + uint32_t state, + int32_t x, + int32_t y, + int32_t normalized_x, + int32_t normalized_y, + int32_t width, + int32_t height, + uint32_t pressure, + int32_t velocity_x, + int32_t velocity_y, + uint32_t flags, + struct wl_array *rawdata) { /** * Event is assembled in QtWayland in TouchExtensionGlobal::postTouchEvent @@ -74,8 +73,8 @@ touch_handle_touch(void *data, **/ float FIXED_TO_FLOAT = 1. / 10000.; - float xf = FIXED_TO_FLOAT * x; - float yf = FIXED_TO_FLOAT * y; + float xf = FIXED_TO_FLOAT * normalized_x; + float yf = FIXED_TO_FLOAT * normalized_y; float PRESSURE_TO_FLOAT = 1. / 255.; float pressuref = PRESSURE_TO_FLOAT * pressure; @@ -90,44 +89,42 @@ touch_handle_touch(void *data, uint32_t capabilities = flags >> 16; */ - SDL_Window* window = NULL; + SDL_Window *window = NULL; SDL_TouchID deviceId = 1; if (SDL_AddTouch(deviceId, SDL_TOUCH_DEVICE_DIRECT, "qt_touch_extension") < 0) { - SDL_Log("error: can't add touch %s, %d", __FILE__, __LINE__); + SDL_Log("error: can't add touch %s, %d", __FILE__, __LINE__); } /* FIXME: This should be the window the given wayland surface is associated * with, but how do we get the wayland surface? */ window = SDL_GetMouseFocus(); - if (window == NULL) { + if (!window) { window = SDL_GetKeyboardFocus(); } switch (touchState) { - case QtWaylandTouchPointPressed: - case QtWaylandTouchPointReleased: - SDL_SendTouch(deviceId, (SDL_FingerID)id, window, - (touchState == QtWaylandTouchPointPressed) ? SDL_TRUE : SDL_FALSE, - xf, yf, pressuref); - break; - case QtWaylandTouchPointMoved: - SDL_SendTouchMotion(deviceId, (SDL_FingerID)id, window, xf, yf, pressuref); - break; - default: - /* Should not happen */ - break; + case QtWaylandTouchPointPressed: + case QtWaylandTouchPointReleased: + SDL_SendTouch(deviceId, (SDL_FingerID)id, window, + (touchState == QtWaylandTouchPointPressed) ? SDL_TRUE : SDL_FALSE, + xf, yf, pressuref); + break; + case QtWaylandTouchPointMoved: + SDL_SendTouchMotion(deviceId, (SDL_FingerID)id, window, xf, yf, pressuref); + break; + default: + /* Should not happen */ + break; } } -static void -touch_handle_configure(void *data, - struct qt_touch_extension *qt_touch_extension, - uint32_t flags) +static void touch_handle_configure(void *data, + struct qt_touch_extension *qt_touch_extension, + uint32_t flags) { } - /* wayland-qt-touch-extension.c BEGINS */ static const struct qt_touch_extension_listener touch_listener = { @@ -161,10 +158,13 @@ static const struct wl_message qt_touch_extension_events[] = { { "configure", "u", qt_touch_extension_types + 0 }, }; -WL_EXPORT const struct wl_interface qt_touch_extension_interface = { - "qt_touch_extension", 1, - 1, qt_touch_extension_requests, - 2, qt_touch_extension_events, +const struct wl_interface qt_touch_extension_interface = { + "qt_touch_extension", + 1, + 1, + qt_touch_extension_requests, + 2, + qt_touch_extension_events, }; /* wayland-qt-touch-extension.c ENDS */ @@ -184,10 +184,13 @@ static const struct wl_message qt_windowmanager_events[] = { { "quit", "", qt_windowmanager_types + 0 }, }; -WL_EXPORT const struct wl_interface qt_windowmanager_interface = { - "qt_windowmanager", 1, - 1, qt_windowmanager_requests, - 2, qt_windowmanager_events, +const struct wl_interface qt_windowmanager_interface = { + "qt_windowmanager", + 1, + 1, + qt_windowmanager_requests, + 2, + qt_windowmanager_events, }; /* wayland-qt-windowmanager.c ENDS */ @@ -201,24 +204,27 @@ static const struct wl_interface *qt_surface_extension_types[] = { NULL, &qt_extended_surface_interface, #ifdef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC - /* FIXME: Set this dynamically to (*WAYLAND_wl_surface_interface) ? - * The value comes from auto generated code and does + /* FIXME: Set this dynamically to (*WAYLAND_wl_surface_interface) ? + * The value comes from auto generated code and does * not appear to actually be used anywhere */ - NULL, + NULL, #else &wl_surface_interface, -#endif +#endif }; static const struct wl_message qt_surface_extension_requests[] = { { "get_extended_surface", "no", qt_surface_extension_types + 2 }, }; -WL_EXPORT const struct wl_interface qt_surface_extension_interface = { - "qt_surface_extension", 1, - 1, qt_surface_extension_requests, - 0, NULL, +const struct wl_interface qt_surface_extension_interface = { + "qt_surface_extension", + 1, + 1, + qt_surface_extension_requests, + 0, + NULL, }; static const struct wl_message qt_extended_surface_requests[] = { @@ -233,16 +239,18 @@ static const struct wl_message qt_extended_surface_events[] = { { "close", "", qt_surface_extension_types + 0 }, }; -WL_EXPORT const struct wl_interface qt_extended_surface_interface = { - "qt_extended_surface", 1, - 3, qt_extended_surface_requests, - 3, qt_extended_surface_events, +const struct wl_interface qt_extended_surface_interface = { + "qt_extended_surface", + 1, + 3, + qt_extended_surface_requests, + 3, + qt_extended_surface_events, }; /* wayland-qt-surface-extension.c ENDS */ -void -Wayland_touch_create(SDL_VideoData *data, uint32_t id) +void Wayland_touch_create(SDL_VideoData *data, uint32_t id) { struct SDL_WaylandTouch *touch; @@ -258,8 +266,7 @@ Wayland_touch_create(SDL_VideoData *data, uint32_t id) qt_touch_extension_add_listener(touch->touch_extension, &touch_listener, data); } -void -Wayland_touch_destroy(SDL_VideoData *data) +void Wayland_touch_destroy(SDL_VideoData *data) { if (data->touch) { struct SDL_WaylandTouch *touch = data->touch; diff --git a/SDL2-2.30.5/src/video/wayland/SDL_waylandtouch.h b/SDL2-2.30.5/src/video/wayland/SDL_waylandtouch.h new file mode 100644 index 0000000..ed260ea --- /dev/null +++ b/SDL2-2.30.5/src/video/wayland/SDL_waylandtouch.h @@ -0,0 +1,334 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#ifndef SDL_waylandtouch_h_ +#define SDL_waylandtouch_h_ + +#include "../../SDL_internal.h" + +#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH + +#include "SDL_waylandvideo.h" +#include +#include +#include "wayland-util.h" + +void Wayland_touch_create(SDL_VideoData *data, uint32_t id); +void Wayland_touch_destroy(SDL_VideoData *data); + +struct qt_touch_extension; + +/* Autogenerated QT headers */ + +/* + Support for Wayland with QmlCompositor as Server +================================================ + +The Wayland video driver has support for some additional features when +using QtWayland's "qmlcompositor" as Wayland server. This is needed for touch +input when running SDL applications under a qmlcompositor Wayland server. + +The files following headers have been +generated from the Wayland XML Protocol Definition in QtWayland as follows: + +Clone QtWayland from Git: + http://qt.gitorious.org/qt/qtwayland/ + +Generate headers and glue code: + for extension in touch-extension surface-extension windowmanager; do + wayland-scanner client-header < src/extensions/$extension.xml > wayland-qt-$extension.h + wayland-scanner code < src/extensions/$extension.xml > wayland-qt-$extension.c + done + +*/ + +/* wayland-qt-surface-extension.h */ + +struct wl_client; +struct wl_resource; + +struct qt_surface_extension; +struct qt_extended_surface; + +extern const struct wl_interface qt_surface_extension_interface; +extern const struct wl_interface qt_extended_surface_interface; + +#define QT_SURFACE_EXTENSION_GET_EXTENDED_SURFACE 0 + +static inline void qt_surface_extension_set_user_data(struct qt_surface_extension *qt_surface_extension, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *)qt_surface_extension, user_data); +} + +static inline void *qt_surface_extension_get_user_data(struct qt_surface_extension *qt_surface_extension) +{ + return wl_proxy_get_user_data((struct wl_proxy *)qt_surface_extension); +} + +static inline void qt_surface_extension_destroy(struct qt_surface_extension *qt_surface_extension) +{ + WAYLAND_wl_proxy_destroy((struct wl_proxy *)qt_surface_extension); +} + +static inline struct qt_extended_surface *qt_surface_extension_get_extended_surface(struct qt_surface_extension *qt_surface_extension, struct wl_surface *surface) +{ + struct wl_proxy *id; + + id = wl_proxy_create((struct wl_proxy *)qt_surface_extension, + &qt_extended_surface_interface); + if (!id) + return NULL; + + WAYLAND_wl_proxy_marshal((struct wl_proxy *)qt_surface_extension, + QT_SURFACE_EXTENSION_GET_EXTENDED_SURFACE, id, surface); + + return (struct qt_extended_surface *)id; +} + +#ifndef QT_EXTENDED_SURFACE_ORIENTATION_ENUM +#define QT_EXTENDED_SURFACE_ORIENTATION_ENUM +enum qt_extended_surface_orientation +{ + QT_EXTENDED_SURFACE_ORIENTATION_PRIMARYORIENTATION = 0, + QT_EXTENDED_SURFACE_ORIENTATION_PORTRAITORIENTATION = 1, + QT_EXTENDED_SURFACE_ORIENTATION_LANDSCAPEORIENTATION = 2, + QT_EXTENDED_SURFACE_ORIENTATION_INVERTEDPORTRAITORIENTATION = 4, + QT_EXTENDED_SURFACE_ORIENTATION_INVERTEDLANDSCAPEORIENTATION = 8, +}; +#endif /* QT_EXTENDED_SURFACE_ORIENTATION_ENUM */ + +#ifndef QT_EXTENDED_SURFACE_WINDOWFLAG_ENUM +#define QT_EXTENDED_SURFACE_WINDOWFLAG_ENUM +enum qt_extended_surface_windowflag +{ + QT_EXTENDED_SURFACE_WINDOWFLAG_OVERRIDESSYSTEMGESTURES = 1, + QT_EXTENDED_SURFACE_WINDOWFLAG_STAYSONTOP = 2, +}; +#endif /* QT_EXTENDED_SURFACE_WINDOWFLAG_ENUM */ + +struct qt_extended_surface_listener +{ + /** + * onscreen_visibility - (none) + * @visible: (none) + */ + void (*onscreen_visibility)(void *data, + struct qt_extended_surface *qt_extended_surface, + int32_t visible); + /** + * set_generic_property - (none) + * @name: (none) + * @value: (none) + */ + void (*set_generic_property)(void *data, + struct qt_extended_surface *qt_extended_surface, + const char *name, + struct wl_array *value); + /** + * close - (none) + */ + void (*close)(void *data, + struct qt_extended_surface *qt_extended_surface); +}; + +static inline int qt_extended_surface_add_listener(struct qt_extended_surface *qt_extended_surface, + const struct qt_extended_surface_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *)qt_extended_surface, + (void (**)(void))listener, data); +} + +#define QT_EXTENDED_SURFACE_UPDATE_GENERIC_PROPERTY 0 +#define QT_EXTENDED_SURFACE_SET_CONTENT_ORIENTATION 1 +#define QT_EXTENDED_SURFACE_SET_WINDOW_FLAGS 2 + +static inline void qt_extended_surface_set_user_data(struct qt_extended_surface *qt_extended_surface, void *user_data) +{ + WAYLAND_wl_proxy_set_user_data((struct wl_proxy *)qt_extended_surface, user_data); +} + +static inline void *qt_extended_surface_get_user_data(struct qt_extended_surface *qt_extended_surface) +{ + return WAYLAND_wl_proxy_get_user_data((struct wl_proxy *)qt_extended_surface); +} + +static inline void qt_extended_surface_destroy(struct qt_extended_surface *qt_extended_surface) +{ + WAYLAND_wl_proxy_destroy((struct wl_proxy *)qt_extended_surface); +} + +static inline void qt_extended_surface_update_generic_property(struct qt_extended_surface *qt_extended_surface, const char *name, struct wl_array *value) +{ + WAYLAND_wl_proxy_marshal((struct wl_proxy *)qt_extended_surface, + QT_EXTENDED_SURFACE_UPDATE_GENERIC_PROPERTY, name, value); +} + +static inline void qt_extended_surface_set_content_orientation(struct qt_extended_surface *qt_extended_surface, int32_t orientation) +{ + WAYLAND_wl_proxy_marshal((struct wl_proxy *)qt_extended_surface, + QT_EXTENDED_SURFACE_SET_CONTENT_ORIENTATION, orientation); +} + +static inline void qt_extended_surface_set_window_flags(struct qt_extended_surface *qt_extended_surface, int32_t flags) +{ + WAYLAND_wl_proxy_marshal((struct wl_proxy *)qt_extended_surface, + QT_EXTENDED_SURFACE_SET_WINDOW_FLAGS, flags); +} + +/* wayland-qt-touch-extension.h */ + +extern const struct wl_interface qt_touch_extension_interface; + +#ifndef QT_TOUCH_EXTENSION_FLAGS_ENUM +#define QT_TOUCH_EXTENSION_FLAGS_ENUM +enum qt_touch_extension_flags +{ + QT_TOUCH_EXTENSION_FLAGS_MOUSE_FROM_TOUCH = 0x1, +}; +#endif /* QT_TOUCH_EXTENSION_FLAGS_ENUM */ + +struct qt_touch_extension_listener +{ + /** + * touch - (none) + * @time: (none) + * @id: (none) + * @state: (none) + * @x: (none) + * @y: (none) + * @normalized_x: (none) + * @normalized_y: (none) + * @width: (none) + * @height: (none) + * @pressure: (none) + * @velocity_x: (none) + * @velocity_y: (none) + * @flags: (none) + * @rawdata: (none) + */ + void (*touch)(void *data, + struct qt_touch_extension *qt_touch_extension, + uint32_t time, + uint32_t id, + uint32_t state, + int32_t x, + int32_t y, + int32_t normalized_x, + int32_t normalized_y, + int32_t width, + int32_t height, + uint32_t pressure, + int32_t velocity_x, + int32_t velocity_y, + uint32_t flags, + struct wl_array *rawdata); + /** + * configure - (none) + * @flags: (none) + */ + void (*configure)(void *data, + struct qt_touch_extension *qt_touch_extension, + uint32_t flags); +}; + +static inline int qt_touch_extension_add_listener(struct qt_touch_extension *qt_touch_extension, + const struct qt_touch_extension_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *)qt_touch_extension, + (void (**)(void))listener, data); +} + +#define QT_TOUCH_EXTENSION_DUMMY 0 + +static inline void qt_touch_extension_set_user_data(struct qt_touch_extension *qt_touch_extension, void *user_data) +{ + WAYLAND_wl_proxy_set_user_data((struct wl_proxy *)qt_touch_extension, user_data); +} + +static inline void *qt_touch_extension_get_user_data(struct qt_touch_extension *qt_touch_extension) +{ + return WAYLAND_wl_proxy_get_user_data((struct wl_proxy *)qt_touch_extension); +} + +static inline void qt_touch_extension_destroy(struct qt_touch_extension *qt_touch_extension) +{ + WAYLAND_wl_proxy_destroy((struct wl_proxy *)qt_touch_extension); +} + +static inline void qt_touch_extension_dummy(struct qt_touch_extension *qt_touch_extension) +{ + WAYLAND_wl_proxy_marshal((struct wl_proxy *)qt_touch_extension, + QT_TOUCH_EXTENSION_DUMMY); +} + +/* wayland-qt-windowmanager.h */ + +extern const struct wl_interface qt_windowmanager_interface; + +struct qt_windowmanager_listener +{ + /** + * hints - (none) + * @show_is_fullscreen: (none) + */ + void (*hints)(void *data, + struct qt_windowmanager *qt_windowmanager, + int32_t show_is_fullscreen); + /** + * quit - (none) + */ + void (*quit)(void *data, + struct qt_windowmanager *qt_windowmanager); +}; + +static inline int qt_windowmanager_add_listener(struct qt_windowmanager *qt_windowmanager, + const struct qt_windowmanager_listener *listener, void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *)qt_windowmanager, + (void (**)(void))listener, data); +} + +#define QT_WINDOWMANAGER_OPEN_URL 0 + +static inline void qt_windowmanager_set_user_data(struct qt_windowmanager *qt_windowmanager, void *user_data) +{ + WAYLAND_wl_proxy_set_user_data((struct wl_proxy *)qt_windowmanager, user_data); +} + +static inline void *qt_windowmanager_get_user_data(struct qt_windowmanager *qt_windowmanager) +{ + return WAYLAND_wl_proxy_get_user_data((struct wl_proxy *)qt_windowmanager); +} + +static inline void qt_windowmanager_destroy(struct qt_windowmanager *qt_windowmanager) +{ + WAYLAND_wl_proxy_destroy((struct wl_proxy *)qt_windowmanager); +} + +static inline void qt_windowmanager_open_url(struct qt_windowmanager *qt_windowmanager, uint32_t remaining, const char *url) +{ + WAYLAND_wl_proxy_marshal((struct wl_proxy *)qt_windowmanager, + QT_WINDOWMANAGER_OPEN_URL, remaining, url); +} + +#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ + +#endif /* SDL_waylandtouch_h_ */ diff --git a/SDL2-2.30.5/src/video/wayland/SDL_waylandvideo.c b/SDL2-2.30.5/src/video/wayland/SDL_waylandvideo.c new file mode 100644 index 0000000..11f3695 --- /dev/null +++ b/SDL2-2.30.5/src/video/wayland/SDL_waylandvideo.c @@ -0,0 +1,1187 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_WAYLAND + +#include "SDL_video.h" +#include "SDL_mouse.h" +#include "SDL_stdinc.h" +#include "../../events/SDL_events_c.h" + +#include "SDL_waylandvideo.h" +#include "SDL_waylandevents_c.h" +#include "SDL_waylandwindow.h" +#include "SDL_waylandopengles.h" +#include "SDL_waylandmouse.h" +#include "SDL_waylandkeyboard.h" +#include "SDL_waylandtouch.h" +#include "SDL_waylandclipboard.h" +#include "SDL_waylandvulkan.h" +#include "SDL_waylandmessagebox.h" +#include "SDL_hints.h" + +#include +#include +#include +#include + +#include + +#include "xdg-shell-client-protocol.h" +#include "xdg-decoration-unstable-v1-client-protocol.h" +#include "keyboard-shortcuts-inhibit-unstable-v1-client-protocol.h" +#include "idle-inhibit-unstable-v1-client-protocol.h" +#include "xdg-activation-v1-client-protocol.h" +#include "text-input-unstable-v3-client-protocol.h" +#include "tablet-unstable-v2-client-protocol.h" +#include "xdg-output-unstable-v1-client-protocol.h" +#include "viewporter-client-protocol.h" +#include "primary-selection-unstable-v1-client-protocol.h" +#include "fractional-scale-v1-client-protocol.h" + +#ifdef HAVE_LIBDECOR_H +#include +#endif + +#define WAYLANDVID_DRIVER_NAME "wayland" + +static void display_handle_done(void *data, struct wl_output *output); + +/* Initialization/Query functions */ +static int Wayland_VideoInit(_THIS); + +static int Wayland_GetDisplayBounds(_THIS, SDL_VideoDisplay *display, SDL_Rect *rect); + +static int Wayland_GetDisplayDPI(_THIS, SDL_VideoDisplay *sdl_display, float *ddpi, float *hdpi, float *vdpi); + +static void Wayland_VideoQuit(_THIS); + +/* Find out what class name we should use + * Based on src/video/x11/SDL_x11video.c */ +static char *get_classname() +{ + /* !!! FIXME: this is probably wrong, albeit harmless in many common cases. From protocol spec: + "The surface class identifies the general class of applications + to which the surface belongs. A common convention is to use the + file name (or the full path if it is a non-standard location) of + the application's .desktop file as the class." */ + + char *spot; +#if defined(__LINUX__) || defined(__FREEBSD__) + char procfile[1024]; + char linkfile[1024]; + int linksize; +#endif + + /* First allow environment variable override */ + spot = SDL_getenv("SDL_VIDEO_WAYLAND_WMCLASS"); + if (spot) { + return SDL_strdup(spot); + } else { + /* Fallback to the "old" envvar */ + spot = SDL_getenv("SDL_VIDEO_X11_WMCLASS"); + if (spot) { + return SDL_strdup(spot); + } + } + + /* Next look at the application's executable name */ +#if defined(__LINUX__) || defined(__FREEBSD__) +#if defined(__LINUX__) + (void)SDL_snprintf(procfile, SDL_arraysize(procfile), "/proc/%d/exe", getpid()); +#elif defined(__FREEBSD__) + (void)SDL_snprintf(procfile, SDL_arraysize(procfile), "/proc/%d/file", getpid()); +#else +#error Where can we find the executable name? +#endif + linksize = readlink(procfile, linkfile, sizeof(linkfile) - 1); + if (linksize > 0) { + linkfile[linksize] = '\0'; + spot = SDL_strrchr(linkfile, '/'); + if (spot) { + return SDL_strdup(spot + 1); + } else { + return SDL_strdup(linkfile); + } + } +#endif /* __LINUX__ || __FREEBSD__ */ + + /* Finally use the default we've used forever */ + return SDL_strdup("SDL_App"); +} + +static const char *SDL_WAYLAND_surface_tag = "sdl-window"; +static const char *SDL_WAYLAND_output_tag = "sdl-output"; + +void SDL_WAYLAND_register_surface(struct wl_surface *surface) +{ + wl_proxy_set_tag((struct wl_proxy *)surface, &SDL_WAYLAND_surface_tag); +} + +void SDL_WAYLAND_register_output(struct wl_output *output) +{ + wl_proxy_set_tag((struct wl_proxy *)output, &SDL_WAYLAND_output_tag); +} + +SDL_bool SDL_WAYLAND_own_surface(struct wl_surface *surface) +{ + return wl_proxy_get_tag((struct wl_proxy *)surface) == &SDL_WAYLAND_surface_tag; +} + +SDL_bool SDL_WAYLAND_own_output(struct wl_output *output) +{ + return wl_proxy_get_tag((struct wl_proxy *)output) == &SDL_WAYLAND_output_tag; +} + +static void Wayland_DeleteDevice(SDL_VideoDevice *device) +{ + SDL_VideoData *data = (SDL_VideoData *)device->driverdata; + if (data->display) { + WAYLAND_wl_display_flush(data->display); + WAYLAND_wl_display_disconnect(data->display); + } + if (device->wakeup_lock) { + SDL_DestroyMutex(device->wakeup_lock); + } + SDL_free(data); + SDL_free(device); + SDL_WAYLAND_UnloadSymbols(); +} + +static SDL_VideoDevice *Wayland_CreateDevice(void) +{ + SDL_VideoDevice *device; + SDL_VideoData *data; + struct SDL_WaylandInput *input; + struct wl_display *display; + + /* Are we trying to connect to or are currently in a Wayland session? */ + if (!getenv("WAYLAND_DISPLAY")) { + const char *session = getenv("XDG_SESSION_TYPE"); + if (session && SDL_strcasecmp(session, "wayland")) { + return NULL; + } + } + + if (!SDL_WAYLAND_LoadSymbols()) { + return NULL; + } + + display = WAYLAND_wl_display_connect(NULL); + if (!display) { + SDL_WAYLAND_UnloadSymbols(); + return NULL; + } + + data = SDL_calloc(1, sizeof(*data)); + if (!data) { + WAYLAND_wl_display_disconnect(display); + SDL_WAYLAND_UnloadSymbols(); + SDL_OutOfMemory(); + return NULL; + } + + input = SDL_calloc(1, sizeof(*input)); + if (!input) { + SDL_free(data); + WAYLAND_wl_display_disconnect(display); + SDL_WAYLAND_UnloadSymbols(); + SDL_OutOfMemory(); + return NULL; + } + + input->display = data; + input->sx_w = wl_fixed_from_int(0); + input->sy_w = wl_fixed_from_int(0); + input->xkb.current_group = XKB_GROUP_INVALID; + + data->initializing = SDL_TRUE; + data->display = display; + data->input = input; + + /* Initialize all variables that we clean on shutdown */ + device = SDL_calloc(1, sizeof(SDL_VideoDevice)); + if (!device) { + SDL_free(data); + SDL_free(input); + WAYLAND_wl_display_disconnect(display); + SDL_WAYLAND_UnloadSymbols(); + SDL_OutOfMemory(); + return NULL; + } + + device->driverdata = data; + device->wakeup_lock = SDL_CreateMutex(); + + /* Set the function pointers */ + device->VideoInit = Wayland_VideoInit; + device->VideoQuit = Wayland_VideoQuit; + device->GetDisplayBounds = Wayland_GetDisplayBounds; + device->GetDisplayDPI = Wayland_GetDisplayDPI; + device->GetWindowWMInfo = Wayland_GetWindowWMInfo; + device->SuspendScreenSaver = Wayland_SuspendScreenSaver; + + device->PumpEvents = Wayland_PumpEvents; + device->WaitEventTimeout = Wayland_WaitEventTimeout; + device->SendWakeupEvent = Wayland_SendWakeupEvent; + +#ifdef SDL_VIDEO_OPENGL_EGL + device->GL_SwapWindow = Wayland_GLES_SwapWindow; + device->GL_GetSwapInterval = Wayland_GLES_GetSwapInterval; + device->GL_SetSwapInterval = Wayland_GLES_SetSwapInterval; + device->GL_MakeCurrent = Wayland_GLES_MakeCurrent; + device->GL_CreateContext = Wayland_GLES_CreateContext; + device->GL_LoadLibrary = Wayland_GLES_LoadLibrary; + device->GL_UnloadLibrary = Wayland_GLES_UnloadLibrary; + device->GL_GetProcAddress = Wayland_GLES_GetProcAddress; + device->GL_DeleteContext = Wayland_GLES_DeleteContext; +#endif + + device->CreateSDLWindow = Wayland_CreateWindow; + device->ShowWindow = Wayland_ShowWindow; + device->HideWindow = Wayland_HideWindow; + device->RaiseWindow = Wayland_RaiseWindow; + device->SetWindowFullscreen = Wayland_SetWindowFullscreen; + device->MaximizeWindow = Wayland_MaximizeWindow; + device->MinimizeWindow = Wayland_MinimizeWindow; + device->SetWindowMouseRect = Wayland_SetWindowMouseRect; + device->SetWindowMouseGrab = Wayland_SetWindowMouseGrab; + device->SetWindowKeyboardGrab = Wayland_SetWindowKeyboardGrab; + device->RestoreWindow = Wayland_RestoreWindow; + device->SetWindowBordered = Wayland_SetWindowBordered; + device->SetWindowResizable = Wayland_SetWindowResizable; + device->SetWindowSize = Wayland_SetWindowSize; + device->SetWindowMinimumSize = Wayland_SetWindowMinimumSize; + device->SetWindowMaximumSize = Wayland_SetWindowMaximumSize; + device->SetWindowModalFor = Wayland_SetWindowModalFor; + device->SetWindowTitle = Wayland_SetWindowTitle; + device->GetWindowSizeInPixels = Wayland_GetWindowSizeInPixels; + device->DestroyWindow = Wayland_DestroyWindow; + device->SetWindowHitTest = Wayland_SetWindowHitTest; + device->FlashWindow = Wayland_FlashWindow; + device->HasScreenKeyboardSupport = Wayland_HasScreenKeyboardSupport; + + device->SetClipboardText = Wayland_SetClipboardText; + device->GetClipboardText = Wayland_GetClipboardText; + device->HasClipboardText = Wayland_HasClipboardText; + device->SetPrimarySelectionText = Wayland_SetPrimarySelectionText; + device->GetPrimarySelectionText = Wayland_GetPrimarySelectionText; + device->HasPrimarySelectionText = Wayland_HasPrimarySelectionText; + device->StartTextInput = Wayland_StartTextInput; + device->StopTextInput = Wayland_StopTextInput; + device->SetTextInputRect = Wayland_SetTextInputRect; + +#ifdef SDL_VIDEO_VULKAN + device->Vulkan_LoadLibrary = Wayland_Vulkan_LoadLibrary; + device->Vulkan_UnloadLibrary = Wayland_Vulkan_UnloadLibrary; + device->Vulkan_GetInstanceExtensions = Wayland_Vulkan_GetInstanceExtensions; + device->Vulkan_CreateSurface = Wayland_Vulkan_CreateSurface; +#endif + + device->free = Wayland_DeleteDevice; + + device->quirk_flags = VIDEO_DEVICE_QUIRK_DISABLE_DISPLAY_MODE_SWITCHING | + VIDEO_DEVICE_QUIRK_DISABLE_UNSET_FULLSCREEN_ON_MINIMIZE; + + return device; +} + +VideoBootStrap Wayland_bootstrap = { + WAYLANDVID_DRIVER_NAME, "SDL Wayland video driver", + Wayland_CreateDevice, + Wayland_ShowMessageBox +}; + +static void xdg_output_handle_logical_position(void *data, struct zxdg_output_v1 *xdg_output, + int32_t x, int32_t y) +{ + SDL_WaylandOutputData *driverdata = data; + + driverdata->x = x; + driverdata->y = y; + driverdata->has_logical_position = SDL_TRUE; +} + +static void xdg_output_handle_logical_size(void *data, struct zxdg_output_v1 *xdg_output, + int32_t width, int32_t height) +{ + SDL_WaylandOutputData *driverdata = data; + + if (driverdata->width != 0 && driverdata->height != 0) { + /* FIXME: GNOME has a bug where the logical size does not account for + * scale, resulting in bogus viewport sizes. + * + * Until this is fixed, validate that _some_ kind of scaling is being + * done (we can't match exactly because fractional scaling can't be + * detected otherwise), then override if necessary. + * -flibit + */ + const float scale = (float)driverdata->width / (float)width; + if ((scale == 1.0f) && (driverdata->scale_factor != 1.0f)) { + SDL_LogWarn( + SDL_LOG_CATEGORY_VIDEO, + "xdg_output scale did not match, overriding with wl_output scale"); + return; + } + } + + driverdata->width = width; + driverdata->height = height; + driverdata->has_logical_size = SDL_TRUE; +} + +static void xdg_output_handle_done(void *data, struct zxdg_output_v1 *xdg_output) +{ + SDL_WaylandOutputData *driverdata = data; + + /* + * xdg-output.done events are deprecated and only apply below version 3 of the protocol. + * A wl-output.done event will be emitted in version 3 or higher. + */ + if (zxdg_output_v1_get_version(driverdata->xdg_output) < 3) { + display_handle_done(data, driverdata->output); + } +} + +static void xdg_output_handle_name(void *data, struct zxdg_output_v1 *xdg_output, + const char *name) +{ +} + +static void xdg_output_handle_description(void *data, struct zxdg_output_v1 *xdg_output, + const char *description) +{ + SDL_WaylandOutputData *driverdata = data; + + if (driverdata->index == -1) { + /* xdg-output descriptions, if available, supersede wl-output model names. */ + if (driverdata->placeholder.name) { + SDL_free(driverdata->placeholder.name); + } + + driverdata->placeholder.name = SDL_strdup(description); + } +} + +static const struct zxdg_output_v1_listener xdg_output_listener = { + xdg_output_handle_logical_position, + xdg_output_handle_logical_size, + xdg_output_handle_done, + xdg_output_handle_name, + xdg_output_handle_description, +}; + +static void AddEmulatedModes(SDL_VideoDisplay *dpy, SDL_bool rot_90) +{ + struct EmulatedMode + { + int w; + int h; + }; + + /* Resolution lists courtesy of XWayland */ + const struct EmulatedMode mode_list[] = { + /* 16:9 (1.77) */ + { 7680, 4320 }, + { 6144, 3160 }, + { 5120, 2880 }, + { 4096, 2304 }, + { 3840, 2160 }, + { 3200, 1800 }, + { 2880, 1620 }, + { 2560, 1440 }, + { 2048, 1152 }, + { 1920, 1080 }, + { 1600, 900 }, + { 1368, 768 }, + { 1280, 720 }, + { 864, 486 }, + + /* 16:10 (1.6) */ + { 2560, 1600 }, + { 1920, 1200 }, + { 1680, 1050 }, + { 1440, 900 }, + { 1280, 800 }, + + /* 3:2 (1.5) */ + { 720, 480 }, + + /* 4:3 (1.33) */ + { 2048, 1536 }, + { 1920, 1440 }, + { 1600, 1200 }, + { 1440, 1080 }, + { 1400, 1050 }, + { 1280, 1024 }, + { 1280, 960 }, + { 1152, 864 }, + { 1024, 768 }, + { 800, 600 }, + { 640, 480 } + }; + + int i; + SDL_DisplayMode mode; + const int native_width = dpy->display_modes->w; + const int native_height = dpy->display_modes->h; + + for (i = 0; i < SDL_arraysize(mode_list); ++i) { + mode = *dpy->display_modes; + + if (rot_90) { + mode.w = mode_list[i].h; + mode.h = mode_list[i].w; + } else { + mode.w = mode_list[i].w; + mode.h = mode_list[i].h; + } + + /* Only add modes that are smaller than the native mode. */ + if ((mode.w < native_width && mode.h < native_height) || + (mode.w < native_width && mode.h == native_height) || + (mode.w == native_width && mode.h < native_height)) { + SDL_AddDisplayMode(dpy, &mode); + } + } +} + +static void display_handle_geometry(void *data, + struct wl_output *output, + int x, int y, + int physical_width, + int physical_height, + int subpixel, + const char *make, + const char *model, + int transform) + +{ + SDL_WaylandOutputData *driverdata = data; + + if (driverdata->wl_output_done_count) { + SDL_ResetDisplayModes(driverdata->index); + + /* The display has officially started over. */ + driverdata->wl_output_done_count = 0; + } + + /* Apply the change from wl-output only if xdg-output is not supported */ + if (!driverdata->has_logical_position) { + driverdata->x = x; + driverdata->y = y; + } + driverdata->physical_width = physical_width; + driverdata->physical_height = physical_height; + + /* The output name is only set if xdg-output hasn't provided a description. */ + if (driverdata->index == -1 && !driverdata->placeholder.name) { + driverdata->placeholder.name = SDL_strdup(model); + } + + driverdata->transform = transform; +#define TF_CASE(in, out) \ + case WL_OUTPUT_TRANSFORM_##in: \ + driverdata->orientation = SDL_ORIENTATION_##out; \ + break; + if (driverdata->physical_width >= driverdata->physical_height) { + switch (transform) { + TF_CASE(NORMAL, LANDSCAPE) + TF_CASE(90, PORTRAIT) + TF_CASE(180, LANDSCAPE_FLIPPED) + TF_CASE(270, PORTRAIT_FLIPPED) + TF_CASE(FLIPPED, LANDSCAPE_FLIPPED) + TF_CASE(FLIPPED_90, PORTRAIT_FLIPPED) + TF_CASE(FLIPPED_180, LANDSCAPE) + TF_CASE(FLIPPED_270, PORTRAIT) + } + } else { + switch (transform) { + TF_CASE(NORMAL, PORTRAIT) + TF_CASE(90, LANDSCAPE) + TF_CASE(180, PORTRAIT_FLIPPED) + TF_CASE(270, LANDSCAPE_FLIPPED) + TF_CASE(FLIPPED, PORTRAIT_FLIPPED) + TF_CASE(FLIPPED_90, LANDSCAPE_FLIPPED) + TF_CASE(FLIPPED_180, PORTRAIT) + TF_CASE(FLIPPED_270, LANDSCAPE) + } + } +#undef TF_CASE +} + +static void display_handle_mode(void *data, + struct wl_output *output, + uint32_t flags, + int width, + int height, + int refresh) +{ + SDL_WaylandOutputData *driverdata = data; + + if (flags & WL_OUTPUT_MODE_CURRENT) { + driverdata->native_width = width; + driverdata->native_height = height; + + /* + * Don't rotate this yet, wl-output coordinates are transformed in + * handle_done and xdg-output coordinates are pre-transformed. + */ + if (!driverdata->has_logical_size) { + driverdata->width = width; + driverdata->height = height; + } + + driverdata->refresh = refresh; + } +} + +static void display_handle_done(void *data, + struct wl_output *output) +{ + SDL_WaylandOutputData *driverdata = data; + SDL_VideoData *video = driverdata->videodata; + SDL_DisplayMode native_mode, desktop_mode; + SDL_VideoDisplay *dpy; + const SDL_bool mode_emulation_enabled = SDL_GetHintBoolean(SDL_HINT_VIDEO_WAYLAND_MODE_EMULATION, SDL_TRUE); + + /* + * When using xdg-output, two wl-output.done events will be emitted: + * one at the completion of wl-display and one at the completion of xdg-output. + * + * All required events must be received before proceeding. + */ + const int event_await_count = 1 + (driverdata->xdg_output != NULL); + + driverdata->wl_output_done_count = SDL_min(driverdata->wl_output_done_count + 1, event_await_count + 1); + + if (driverdata->wl_output_done_count != event_await_count) { + return; + } + + /* The native display resolution */ + SDL_zero(native_mode); + native_mode.format = SDL_PIXELFORMAT_RGB888; + + if (driverdata->transform & WL_OUTPUT_TRANSFORM_90) { + native_mode.w = driverdata->native_height; + native_mode.h = driverdata->native_width; + } else { + native_mode.w = driverdata->native_width; + native_mode.h = driverdata->native_height; + } + native_mode.refresh_rate = (int)SDL_round(driverdata->refresh / 1000.0); /* mHz to Hz */ + + /* The scaled desktop mode */ + SDL_zero(desktop_mode); + desktop_mode.format = SDL_PIXELFORMAT_RGB888; + + if (driverdata->has_logical_size) { /* If xdg-output is present, calculate the true scale of the desktop */ + driverdata->scale_factor = (float)native_mode.w / (float)driverdata->width; + } else { /* Scale the desktop coordinates, if xdg-output isn't present */ + driverdata->width /= driverdata->scale_factor; + driverdata->height /= driverdata->scale_factor; + } + + /* xdg-output dimensions are already transformed, so no need to rotate. */ + if (driverdata->has_logical_size || !(driverdata->transform & WL_OUTPUT_TRANSFORM_90)) { + desktop_mode.w = driverdata->width; + desktop_mode.h = driverdata->height; + } else { + desktop_mode.w = driverdata->height; + desktop_mode.h = driverdata->width; + } + desktop_mode.refresh_rate = (int)SDL_round(driverdata->refresh / 1000.0); /* mHz to Hz */ + + /* + * The native display mode is only exposed separately from the desktop size if the + * desktop is scaled and the wp_viewporter protocol is supported. + */ + if (driverdata->scale_factor > 1.0f && video->viewporter) { + if (driverdata->index > -1) { + SDL_AddDisplayMode(SDL_GetDisplay(driverdata->index), &native_mode); + } else { + SDL_AddDisplayMode(&driverdata->placeholder, &native_mode); + } + } + + /* Calculate the display DPI */ + if (driverdata->transform & WL_OUTPUT_TRANSFORM_90) { + driverdata->hdpi = driverdata->physical_height ? (((float)driverdata->native_height) * 25.4f / driverdata->physical_height) : 0.0f; + driverdata->vdpi = driverdata->physical_width ? (((float)driverdata->native_width) * 25.4f / driverdata->physical_width) : 0.0f; + driverdata->ddpi = SDL_ComputeDiagonalDPI(driverdata->native_height, + driverdata->native_width, + ((float)driverdata->physical_height) / 25.4f, + ((float)driverdata->physical_width) / 25.4f); + } else { + driverdata->hdpi = driverdata->physical_width ? (((float)driverdata->native_width) * 25.4f / driverdata->physical_width) : 0.0f; + driverdata->vdpi = driverdata->physical_height ? (((float)driverdata->native_height) * 25.4f / driverdata->physical_height) : 0.0f; + driverdata->ddpi = SDL_ComputeDiagonalDPI(driverdata->native_width, + driverdata->native_height, + ((float)driverdata->physical_width) / 25.4f, + ((float)driverdata->physical_height) / 25.4f); + } + + if (driverdata->index > -1) { + dpy = SDL_GetDisplay(driverdata->index); + } else { + dpy = &driverdata->placeholder; + } + + SDL_AddDisplayMode(dpy, &desktop_mode); + SDL_SetCurrentDisplayMode(dpy, &desktop_mode); + SDL_SetDesktopDisplayMode(dpy, &desktop_mode); + + /* Add emulated modes if wp_viewporter is supported and mode emulation is enabled. */ + if (video->viewporter && mode_emulation_enabled) { + const SDL_bool rot_90 = (driverdata->transform & WL_OUTPUT_TRANSFORM_90) || + (driverdata->width < driverdata->height); + AddEmulatedModes(dpy, rot_90); + } + + if (driverdata->index == -1) { + /* First time getting display info, create the VideoDisplay */ + SDL_bool send_event = driverdata->videodata->initializing ? SDL_FALSE : SDL_TRUE; + driverdata->placeholder.orientation = driverdata->orientation; + driverdata->placeholder.driverdata = driverdata; + driverdata->index = SDL_AddVideoDisplay(&driverdata->placeholder, send_event); + SDL_free(driverdata->placeholder.name); + SDL_zero(driverdata->placeholder); + } else { + SDL_SendDisplayEvent(dpy, SDL_DISPLAYEVENT_ORIENTATION, driverdata->orientation); + } +} + +static void display_handle_scale(void *data, + struct wl_output *output, + int32_t factor) +{ + SDL_WaylandOutputData *driverdata = data; + driverdata->scale_factor = factor; +} + +static const struct wl_output_listener output_listener = { + display_handle_geometry, + display_handle_mode, + display_handle_done, + display_handle_scale +}; + +static void Wayland_add_display(SDL_VideoData *d, uint32_t id) +{ + struct wl_output *output; + SDL_WaylandOutputData *data; + + output = wl_registry_bind(d->registry, id, &wl_output_interface, 2); + if (!output) { + SDL_SetError("Failed to retrieve output."); + return; + } + data = (SDL_WaylandOutputData *)SDL_malloc(sizeof(*data)); + SDL_zerop(data); + data->videodata = d; + data->output = output; + data->registry_id = id; + data->scale_factor = 1.0f; + data->index = -1; + + wl_output_add_listener(output, &output_listener, data); + SDL_WAYLAND_register_output(output); + + /* Keep a list of outputs for deferred xdg-output initialization. */ + if (d->output_list) { + SDL_WaylandOutputData *node = d->output_list; + + while (node->next) { + node = node->next; + } + + node->next = (struct SDL_WaylandOutputData *)data; + } else { + d->output_list = (struct SDL_WaylandOutputData *)data; + } + + if (data->videodata->xdg_output_manager) { + data->xdg_output = zxdg_output_manager_v1_get_xdg_output(data->videodata->xdg_output_manager, output); + zxdg_output_v1_add_listener(data->xdg_output, &xdg_output_listener, data); + } +} + +static void Wayland_free_display(SDL_VideoData *d, uint32_t id) +{ + int num_displays = SDL_GetNumVideoDisplays(); + SDL_VideoDisplay *display; + SDL_WaylandOutputData *data; + int i; + + for (i = 0; i < num_displays; i += 1) { + display = SDL_GetDisplay(i); + data = (SDL_WaylandOutputData *)display->driverdata; + if (data->registry_id == id) { + if (d->output_list) { + SDL_WaylandOutputData *node = d->output_list; + if (node == data) { + d->output_list = node->next; + } else { + while (node->next != data && node->next) { + node = node->next; + } + if (node->next) { + node->next = node->next->next; + } + } + } + if (data->xdg_output) { + zxdg_output_v1_destroy(data->xdg_output); + } + wl_output_destroy(data->output); + SDL_DelVideoDisplay(i); + + /* Update the index for all remaining displays */ + num_displays -= 1; + for (; i < num_displays; i += 1) { + display = SDL_GetDisplay(i); + data = (SDL_WaylandOutputData *)display->driverdata; + data->index -= 1; + } + + return; + } + } +} + +static void Wayland_init_xdg_output(SDL_VideoData *d) +{ + SDL_WaylandOutputData *node; + for (node = d->output_list; node; node = node->next) { + node->xdg_output = zxdg_output_manager_v1_get_xdg_output(node->videodata->xdg_output_manager, node->output); + zxdg_output_v1_add_listener(node->xdg_output, &xdg_output_listener, node); + } +} + +#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH +static void windowmanager_hints(void *data, struct qt_windowmanager *qt_windowmanager, + int32_t show_is_fullscreen) +{ +} + +static void windowmanager_quit(void *data, struct qt_windowmanager *qt_windowmanager) +{ + SDL_SendQuit(); +} + +static const struct qt_windowmanager_listener windowmanager_listener = { + windowmanager_hints, + windowmanager_quit, +}; +#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ + +static void handle_ping_xdg_wm_base(void *data, struct xdg_wm_base *xdg, uint32_t serial) +{ + xdg_wm_base_pong(xdg, serial); +} + +static const struct xdg_wm_base_listener shell_listener_xdg = { + handle_ping_xdg_wm_base +}; + +#ifdef HAVE_LIBDECOR_H +static void libdecor_error(struct libdecor *context, + enum libdecor_error error, + const char *message) +{ + SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "libdecor error (%d): %s\n", error, message); +} + +static struct libdecor_interface libdecor_interface = { + libdecor_error, +}; +#endif + +static void display_handle_global(void *data, struct wl_registry *registry, uint32_t id, + const char *interface, uint32_t version) +{ + SDL_VideoData *d = data; + + /*printf("WAYLAND INTERFACE: %s\n", interface);*/ + + if (SDL_strcmp(interface, "wl_compositor") == 0) { + d->compositor = wl_registry_bind(d->registry, id, &wl_compositor_interface, SDL_min(4, version)); + } else if (SDL_strcmp(interface, "wl_output") == 0) { + Wayland_add_display(d, id); + } else if (SDL_strcmp(interface, "wl_seat") == 0) { + Wayland_display_add_input(d, id, version); + } else if (SDL_strcmp(interface, "xdg_wm_base") == 0) { + d->shell.xdg = wl_registry_bind(d->registry, id, &xdg_wm_base_interface, SDL_min(version, 3)); + xdg_wm_base_add_listener(d->shell.xdg, &shell_listener_xdg, NULL); + } else if (SDL_strcmp(interface, "wl_shm") == 0) { + d->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1); + } else if (SDL_strcmp(interface, "zwp_relative_pointer_manager_v1") == 0) { + Wayland_display_add_relative_pointer_manager(d, id); + } else if (SDL_strcmp(interface, "zwp_pointer_constraints_v1") == 0) { + Wayland_display_add_pointer_constraints(d, id); + } else if (SDL_strcmp(interface, "zwp_keyboard_shortcuts_inhibit_manager_v1") == 0) { + d->key_inhibitor_manager = wl_registry_bind(d->registry, id, &zwp_keyboard_shortcuts_inhibit_manager_v1_interface, 1); + } else if (SDL_strcmp(interface, "zwp_idle_inhibit_manager_v1") == 0) { + d->idle_inhibit_manager = wl_registry_bind(d->registry, id, &zwp_idle_inhibit_manager_v1_interface, 1); + } else if (SDL_strcmp(interface, "xdg_activation_v1") == 0) { + d->activation_manager = wl_registry_bind(d->registry, id, &xdg_activation_v1_interface, 1); + } else if (SDL_strcmp(interface, "zwp_text_input_manager_v3") == 0) { + Wayland_add_text_input_manager(d, id, version); + } else if (SDL_strcmp(interface, "wl_data_device_manager") == 0) { + Wayland_add_data_device_manager(d, id, version); + } else if (SDL_strcmp(interface, "zwp_primary_selection_device_manager_v1") == 0) { + Wayland_add_primary_selection_device_manager(d, id, version); + } else if (SDL_strcmp(interface, "zxdg_decoration_manager_v1") == 0) { + d->decoration_manager = wl_registry_bind(d->registry, id, &zxdg_decoration_manager_v1_interface, 1); + } else if (SDL_strcmp(interface, "zwp_tablet_manager_v2") == 0) { + d->tablet_manager = wl_registry_bind(d->registry, id, &zwp_tablet_manager_v2_interface, 1); + Wayland_input_add_tablet(d->input, d->tablet_manager); + } else if (SDL_strcmp(interface, "zxdg_output_manager_v1") == 0) { + version = SDL_min(version, 3); /* Versions 1 through 3 are supported. */ + d->xdg_output_manager = wl_registry_bind(d->registry, id, &zxdg_output_manager_v1_interface, version); + Wayland_init_xdg_output(d); + } else if (SDL_strcmp(interface, "wp_viewporter") == 0) { + d->viewporter = wl_registry_bind(d->registry, id, &wp_viewporter_interface, 1); + } else if (SDL_strcmp(interface, "wp_fractional_scale_manager_v1") == 0) { + d->fractional_scale_manager = wl_registry_bind(d->registry, id, &wp_fractional_scale_manager_v1_interface, 1); +#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH + } else if (SDL_strcmp(interface, "qt_touch_extension") == 0) { + Wayland_touch_create(d, id); + } else if (SDL_strcmp(interface, "qt_surface_extension") == 0) { + d->surface_extension = wl_registry_bind(registry, id, + &qt_surface_extension_interface, 1); + } else if (SDL_strcmp(interface, "qt_windowmanager") == 0) { + d->windowmanager = wl_registry_bind(registry, id, + &qt_windowmanager_interface, 1); + qt_windowmanager_add_listener(d->windowmanager, &windowmanager_listener, d); +#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ + } +} + +static void display_remove_global(void *data, struct wl_registry *registry, uint32_t id) +{ + SDL_VideoData *d = data; + /* We don't get an interface, just an ID, so assume it's a wl_output :shrug: */ + Wayland_free_display(d, id); +} + +static const struct wl_registry_listener registry_listener = { + display_handle_global, + display_remove_global +}; + +#ifdef HAVE_LIBDECOR_H +static SDL_bool should_use_libdecor(SDL_VideoData *data, SDL_bool ignore_xdg) +{ + if (!SDL_WAYLAND_HAVE_WAYLAND_LIBDECOR) { + return SDL_FALSE; + } + + if (!SDL_GetHintBoolean(SDL_HINT_VIDEO_WAYLAND_ALLOW_LIBDECOR, SDL_TRUE)) { + return SDL_FALSE; + } + + if (SDL_GetHintBoolean(SDL_HINT_VIDEO_WAYLAND_PREFER_LIBDECOR, SDL_FALSE)) { + return SDL_TRUE; + } + + if (ignore_xdg) { + return SDL_TRUE; + } + + if (data->decoration_manager) { + return SDL_FALSE; + } + + return SDL_TRUE; +} +#endif + +SDL_bool Wayland_LoadLibdecor(SDL_VideoData *data, SDL_bool ignore_xdg) +{ +#ifdef HAVE_LIBDECOR_H + if (data->shell.libdecor != NULL) { + return SDL_TRUE; /* Already loaded! */ + } + if (should_use_libdecor(data, ignore_xdg)) { + data->shell.libdecor = libdecor_new(data->display, &libdecor_interface); + return data->shell.libdecor != NULL; + } +#endif + return SDL_FALSE; +} + +int Wayland_VideoInit(_THIS) +{ + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; + + data->xkb_context = WAYLAND_xkb_context_new(0); + if (!data->xkb_context) { + return SDL_SetError("Failed to create XKB context"); + } + + data->registry = wl_display_get_registry(data->display); + if (!data->registry) { + return SDL_SetError("Failed to get the Wayland registry"); + } + + wl_registry_add_listener(data->registry, ®istry_listener, data); + + // First roundtrip to receive all registry objects. + WAYLAND_wl_display_roundtrip(data->display); + + /* Now that we have all the protocols, load libdecor if applicable */ + Wayland_LoadLibdecor(data, SDL_FALSE); + + // Second roundtrip to receive all output events. + WAYLAND_wl_display_roundtrip(data->display); + + Wayland_InitMouse(); + + /* Get the surface class name, usually the name of the application */ + data->classname = get_classname(); + + WAYLAND_wl_display_flush(data->display); + + Wayland_InitKeyboard(_this); + Wayland_InitWin(data); + + data->initializing = SDL_FALSE; + + return 0; +} + +static int Wayland_GetDisplayBounds(_THIS, SDL_VideoDisplay *display, SDL_Rect *rect) +{ + SDL_WaylandOutputData *driverdata = (SDL_WaylandOutputData *)display->driverdata; + rect->x = driverdata->x; + rect->y = driverdata->y; + rect->w = display->current_mode.w; + rect->h = display->current_mode.h; + return 0; +} + +static int Wayland_GetDisplayDPI(_THIS, SDL_VideoDisplay *sdl_display, float *ddpi, float *hdpi, float *vdpi) +{ + SDL_WaylandOutputData *driverdata = (SDL_WaylandOutputData *)sdl_display->driverdata; + + if (ddpi) { + *ddpi = driverdata->ddpi; + } + if (hdpi) { + *hdpi = driverdata->hdpi; + } + if (vdpi) { + *vdpi = driverdata->vdpi; + } + + return driverdata->ddpi != 0.0f ? 0 : SDL_SetError("Couldn't get DPI"); +} + +static void Wayland_VideoCleanup(_THIS) +{ + SDL_VideoData *data = _this->driverdata; + int i; + + Wayland_QuitWin(data); + Wayland_FiniMouse(data); + + for (i = _this->num_displays - 1; i >= 0; --i) { + SDL_VideoDisplay *display = &_this->displays[i]; + + if (((SDL_WaylandOutputData *)display->driverdata)->xdg_output) { + zxdg_output_v1_destroy(((SDL_WaylandOutputData *)display->driverdata)->xdg_output); + } + + wl_output_destroy(((SDL_WaylandOutputData *)display->driverdata)->output); + SDL_DelVideoDisplay(i); + } + data->output_list = NULL; + + Wayland_display_destroy_input(data); + Wayland_display_destroy_pointer_constraints(data); + Wayland_display_destroy_relative_pointer_manager(data); + + if (data->activation_manager) { + xdg_activation_v1_destroy(data->activation_manager); + data->activation_manager = NULL; + } + + if (data->idle_inhibit_manager) { + zwp_idle_inhibit_manager_v1_destroy(data->idle_inhibit_manager); + data->idle_inhibit_manager = NULL; + } + + if (data->key_inhibitor_manager) { + zwp_keyboard_shortcuts_inhibit_manager_v1_destroy(data->key_inhibitor_manager); + data->key_inhibitor_manager = NULL; + } + + Wayland_QuitKeyboard(_this); + + if (data->text_input_manager) { + zwp_text_input_manager_v3_destroy(data->text_input_manager); + data->text_input_manager = NULL; + } + + if (data->xkb_context) { + WAYLAND_xkb_context_unref(data->xkb_context); + data->xkb_context = NULL; + } +#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH + if (data->windowmanager) { + qt_windowmanager_destroy(data->windowmanager); + data->windowmanager = NULL; + } + + if (data->surface_extension) { + qt_surface_extension_destroy(data->surface_extension); + data->surface_extension = NULL; + } + + Wayland_touch_destroy(data); +#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ + + if (data->tablet_manager) { + zwp_tablet_manager_v2_destroy((struct zwp_tablet_manager_v2 *)data->tablet_manager); + data->tablet_manager = NULL; + } + + if (data->data_device_manager) { + wl_data_device_manager_destroy(data->data_device_manager); + data->data_device_manager = NULL; + } + + if (data->shm) { + wl_shm_destroy(data->shm); + data->shm = NULL; + } + + if (data->shell.xdg) { + xdg_wm_base_destroy(data->shell.xdg); + data->shell.xdg = NULL; + } + + if (data->decoration_manager) { + zxdg_decoration_manager_v1_destroy(data->decoration_manager); + data->decoration_manager = NULL; + } + + if (data->xdg_output_manager) { + zxdg_output_manager_v1_destroy(data->xdg_output_manager); + data->xdg_output_manager = NULL; + } + + if (data->viewporter) { + wp_viewporter_destroy(data->viewporter); + data->viewporter = NULL; + } + + if (data->primary_selection_device_manager) { + zwp_primary_selection_device_manager_v1_destroy(data->primary_selection_device_manager); + data->primary_selection_device_manager = NULL; + } + + if (data->fractional_scale_manager) { + wp_fractional_scale_manager_v1_destroy(data->fractional_scale_manager); + data->fractional_scale_manager = NULL; + } + + if (data->compositor) { + wl_compositor_destroy(data->compositor); + data->compositor = NULL; + } + + if (data->registry) { + wl_registry_destroy(data->registry); + data->registry = NULL; + } +} + +SDL_bool Wayland_VideoReconnect(_THIS) +{ +#if 0 /* TODO RECONNECT: Uncomment all when https://invent.kde.org/plasma/kwin/-/wikis/Restarting is completed */ + SDL_VideoData *data = _this->driverdata; + + SDL_Window *window = NULL; + + SDL_GLContext current_ctx = SDL_GL_GetCurrentContext(); + SDL_Window *current_window = SDL_GL_GetCurrentWindow(); + + SDL_GL_MakeCurrent(NULL, NULL); + Wayland_VideoCleanup(_this); + + SDL_ResetKeyboard(); + SDL_ResetMouse(); + if (WAYLAND_wl_display_reconnect(data->display) < 0) { + return SDL_FALSE; + } + + Wayland_VideoInit(_this); + + window = _this->windows; + while (window) { + /* We're going to cheat _just_ for a second and strip the OpenGL flag. + * The Wayland driver actually forces it in CreateWindow, and + * RecreateWindow does a bunch of unloading/loading of libGL, so just + * strip the flag so RecreateWindow doesn't mess with the GL context, + * and CreateWindow will add it right back! + * -flibit + */ + window->flags &= ~SDL_WINDOW_OPENGL; + + SDL_RecreateWindow(window, window->flags); + window = window->next; + } + + Wayland_RecreateCursors(); + + if (current_window && current_ctx) { + SDL_GL_MakeCurrent (current_window, current_ctx); + } + return SDL_TRUE; +#else + return SDL_FALSE; +#endif /* 0 */ +} + +void Wayland_VideoQuit(_THIS) +{ + SDL_VideoData *data = _this->driverdata; + + Wayland_VideoCleanup(_this); + +#ifdef HAVE_LIBDECOR_H + if (data->shell.libdecor) { + libdecor_unref(data->shell.libdecor); + data->shell.libdecor = NULL; + } +#endif + + SDL_free(data->classname); +} + +#endif /* SDL_VIDEO_DRIVER_WAYLAND */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/wayland/SDL_waylandvideo.h b/SDL2-2.30.5/src/video/wayland/SDL_waylandvideo.h similarity index 51% rename from SDL2-2.0.12/src/video/wayland/SDL_waylandvideo.h rename to SDL2-2.30.5/src/video/wayland/SDL_waylandvideo.h index 2c481d8..b7b3348 100644 --- a/SDL2-2.0.12/src/video/wayland/SDL_waylandvideo.h +++ b/SDL2-2.30.5/src/video/wayland/SDL_waylandvideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,25 +20,21 @@ */ #include "../../SDL_internal.h" +#include "SDL_stdinc.h" #ifndef SDL_waylandvideo_h_ #define SDL_waylandvideo_h_ - -/* -!!! FIXME: xdg_wm_base is the stable replacement for zxdg_shell_v6. While it's -!!! FIXME: harmless to leave it here, consider deleting the obsolete codepath -!!! FIXME: soon, since Wayland (with xdg_wm_base) will probably be mainline -!!! FIXME: by the time people are relying on this SDL target. It's available -!!! FIXME: in Ubuntu 18.04 (and other distros). -*/ - -#define MESA_EGL_NO_X11_HEADERS #include #include "wayland-util.h" +#include "../SDL_sysvideo.h" +#include "../../core/linux/SDL_dbus.h" +#include "../../core/linux/SDL_ime.h" + struct xkb_context; struct SDL_WaylandInput; +struct SDL_WaylandTabletManager; #ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH struct SDL_WaylandTouch; @@ -46,24 +42,44 @@ struct qt_surface_extension; struct qt_windowmanager; #endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ -typedef struct { +typedef struct +{ + struct wl_cursor_theme *theme; + int size; +} SDL_WaylandCursorTheme; + +typedef struct SDL_WaylandOutputData SDL_WaylandOutputData; + +typedef struct +{ + SDL_bool initializing; struct wl_display *display; int display_disconnected; struct wl_registry *registry; struct wl_compositor *compositor; struct wl_shm *shm; - struct wl_cursor_theme *cursor_theme; + SDL_WaylandCursorTheme *cursor_themes; + int num_cursor_themes; struct wl_pointer *pointer; - struct { + struct + { struct xdg_wm_base *xdg; - struct zxdg_shell_v6 *zxdg; - struct wl_shell *wl; +#ifdef HAVE_LIBDECOR_H + struct libdecor *libdecor; +#endif } shell; struct zwp_relative_pointer_manager_v1 *relative_pointer_manager; struct zwp_pointer_constraints_v1 *pointer_constraints; struct wl_data_device_manager *data_device_manager; + struct zwp_primary_selection_device_manager_v1 *primary_selection_device_manager; struct zxdg_decoration_manager_v1 *decoration_manager; - struct org_kde_kwin_server_decoration_manager *kwin_server_decoration_manager; + struct zwp_keyboard_shortcuts_inhibit_manager_v1 *key_inhibitor_manager; + struct zwp_idle_inhibit_manager_v1 *idle_inhibit_manager; + struct xdg_activation_v1 *activation_manager; + struct zwp_text_input_manager_v3 *text_input_manager; + struct zxdg_output_manager_v1 *xdg_output_manager; + struct wp_viewporter *viewporter; + struct wp_fractional_scale_manager_v1 *fractional_scale_manager; EGLDisplay edpy; EGLContext context; @@ -71,6 +87,8 @@ typedef struct { struct xkb_context *xkb_context; struct SDL_WaylandInput *input; + struct SDL_WaylandTabletManager *tablet_manager; + SDL_WaylandOutputData *output_list; #ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH struct SDL_WaylandTouch *touch; @@ -81,12 +99,39 @@ typedef struct { char *classname; int relative_mouse_mode; + SDL_bool egl_transparency_enabled; } SDL_VideoData; -typedef struct { +struct SDL_WaylandOutputData +{ + SDL_VideoData *videodata; struct wl_output *output; + struct zxdg_output_v1 *xdg_output; + uint32_t registry_id; float scale_factor; -} SDL_WaylandOutputData; + int native_width, native_height; + int x, y, width, height, refresh, transform; + SDL_DisplayOrientation orientation; + int physical_width, physical_height; + float ddpi, hdpi, vdpi; + SDL_bool has_logical_position, has_logical_size; + int index; + SDL_VideoDisplay placeholder; + int wl_output_done_count; + SDL_WaylandOutputData *next; +}; + +/* Needed here to get wl_surface declaration, fixes GitHub#4594 */ +#include "SDL_waylanddyn.h" + +extern void SDL_WAYLAND_register_surface(struct wl_surface *surface); +extern void SDL_WAYLAND_register_output(struct wl_output *output); +extern SDL_bool SDL_WAYLAND_own_surface(struct wl_surface *surface); +extern SDL_bool SDL_WAYLAND_own_output(struct wl_output *output); + +extern SDL_bool Wayland_LoadLibdecor(SDL_VideoData *data, SDL_bool ignore_xdg); + +extern SDL_bool Wayland_VideoReconnect(_THIS); #endif /* SDL_waylandvideo_h_ */ diff --git a/SDL2-2.0.12/src/video/wayland/SDL_waylandvulkan.c b/SDL2-2.30.5/src/video/wayland/SDL_waylandvulkan.c similarity index 67% rename from SDL2-2.0.12/src/video/wayland/SDL_waylandvulkan.c rename to SDL2-2.30.5/src/video/wayland/SDL_waylandvulkan.c index aa5e23f..af956da 100644 --- a/SDL2-2.0.12/src/video/wayland/SDL_waylandvulkan.c +++ b/SDL2-2.30.5/src/video/wayland/SDL_waylandvulkan.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,16 +26,21 @@ #include "../../SDL_internal.h" -#if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_WAYLAND +#if defined(SDL_VIDEO_VULKAN) && defined(SDL_VIDEO_DRIVER_WAYLAND) #include "SDL_waylandvideo.h" #include "SDL_waylandwindow.h" -#include "SDL_assert.h" #include "SDL_loadso.h" #include "SDL_waylandvulkan.h" #include "SDL_syswm.h" +#if defined(__OpenBSD__) +#define DEFAULT_VULKAN "libvulkan.so" +#else +#define DEFAULT_VULKAN "libvulkan.so.1" +#endif + int Wayland_Vulkan_LoadLibrary(_THIS, const char *path) { VkExtensionProperties *extensions = NULL; @@ -43,53 +48,55 @@ int Wayland_Vulkan_LoadLibrary(_THIS, const char *path) SDL_bool hasSurfaceExtension = SDL_FALSE; SDL_bool hasWaylandSurfaceExtension = SDL_FALSE; PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL; - if(_this->vulkan_config.loader_handle) + if (_this->vulkan_config.loader_handle) { return SDL_SetError("Vulkan already loaded"); + } /* Load the Vulkan loader library */ - if(!path) + if (!path) { path = SDL_getenv("SDL_VULKAN_LIBRARY"); - if(!path) - path = "libvulkan.so.1"; + } + if (!path) { + path = DEFAULT_VULKAN; + } _this->vulkan_config.loader_handle = SDL_LoadObject(path); - if(!_this->vulkan_config.loader_handle) + if (!_this->vulkan_config.loader_handle) { return -1; + } SDL_strlcpy(_this->vulkan_config.loader_path, path, SDL_arraysize(_this->vulkan_config.loader_path)); vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)SDL_LoadFunction( _this->vulkan_config.loader_handle, "vkGetInstanceProcAddr"); - if(!vkGetInstanceProcAddr) + if (!vkGetInstanceProcAddr) { goto fail; + } _this->vulkan_config.vkGetInstanceProcAddr = (void *)vkGetInstanceProcAddr; _this->vulkan_config.vkEnumerateInstanceExtensionProperties = (void *)((PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr)( VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties"); - if(!_this->vulkan_config.vkEnumerateInstanceExtensionProperties) + if (!_this->vulkan_config.vkEnumerateInstanceExtensionProperties) { goto fail; + } extensions = SDL_Vulkan_CreateInstanceExtensionsList( (PFN_vkEnumerateInstanceExtensionProperties) _this->vulkan_config.vkEnumerateInstanceExtensionProperties, &extensionCount); - if(!extensions) + if (!extensions) { goto fail; - for(i = 0; i < extensionCount; i++) - { - if(SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) + } + for (i = 0; i < extensionCount; i++) { + if (SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) { hasSurfaceExtension = SDL_TRUE; - else if(SDL_strcmp(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) + } else if (SDL_strcmp(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) { hasWaylandSurfaceExtension = SDL_TRUE; + } } SDL_free(extensions); - if(!hasSurfaceExtension) - { - SDL_SetError("Installed Vulkan doesn't implement the " - VK_KHR_SURFACE_EXTENSION_NAME " extension"); + if (!hasSurfaceExtension) { + SDL_SetError("Installed Vulkan doesn't implement the " VK_KHR_SURFACE_EXTENSION_NAME " extension"); goto fail; - } - else if(!hasWaylandSurfaceExtension) - { - SDL_SetError("Installed Vulkan doesn't implement the " - VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME "extension"); + } else if (!hasWaylandSurfaceExtension) { + SDL_SetError("Installed Vulkan doesn't implement the " VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME "extension"); goto fail; } return 0; @@ -102,70 +109,50 @@ fail: void Wayland_Vulkan_UnloadLibrary(_THIS) { - if(_this->vulkan_config.loader_handle) - { + if (_this->vulkan_config.loader_handle) { SDL_UnloadObject(_this->vulkan_config.loader_handle); _this->vulkan_config.loader_handle = NULL; } } SDL_bool Wayland_Vulkan_GetInstanceExtensions(_THIS, - SDL_Window *window, - unsigned *count, - const char **names) + SDL_Window *window, + unsigned *count, + const char **names) { static const char *const extensionsForWayland[] = { VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME }; - if(!_this->vulkan_config.loader_handle) - { + if (!_this->vulkan_config.loader_handle) { SDL_SetError("Vulkan is not loaded"); return SDL_FALSE; } return SDL_Vulkan_GetInstanceExtensions_Helper( - count, names, SDL_arraysize(extensionsForWayland), - extensionsForWayland); -} - -void Wayland_Vulkan_GetDrawableSize(_THIS, SDL_Window *window, int *w, int *h) -{ - SDL_WindowData *data; - if (window->driverdata) { - data = (SDL_WindowData *) window->driverdata; - - if (w) { - *w = window->w * data->scale_factor; - } - - if (h) { - *h = window->h * data->scale_factor; - } - } + count, names, SDL_arraysize(extensionsForWayland), + extensionsForWayland); } SDL_bool Wayland_Vulkan_CreateSurface(_THIS, - SDL_Window *window, - VkInstance instance, - VkSurfaceKHR *surface) + SDL_Window *window, + VkInstance instance, + VkSurfaceKHR *surface) { SDL_WindowData *windowData = (SDL_WindowData *)window->driverdata; PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr; PFN_vkCreateWaylandSurfaceKHR vkCreateWaylandSurfaceKHR = (PFN_vkCreateWaylandSurfaceKHR)vkGetInstanceProcAddr( - instance, - "vkCreateWaylandSurfaceKHR"); + instance, + "vkCreateWaylandSurfaceKHR"); VkWaylandSurfaceCreateInfoKHR createInfo; VkResult result; - if(!_this->vulkan_config.loader_handle) - { + if (!_this->vulkan_config.loader_handle) { SDL_SetError("Vulkan is not loaded"); return SDL_FALSE; } - if(!vkCreateWaylandSurfaceKHR) - { + if (!vkCreateWaylandSurfaceKHR) { SDL_SetError(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME " extension is not enabled in the Vulkan instance."); return SDL_FALSE; @@ -175,11 +162,10 @@ SDL_bool Wayland_Vulkan_CreateSurface(_THIS, createInfo.pNext = NULL; createInfo.flags = 0; createInfo.display = windowData->waylandData->display; - createInfo.surface = windowData->surface; + createInfo.surface = windowData->surface; result = vkCreateWaylandSurfaceKHR(instance, &createInfo, NULL, surface); - if(result != VK_SUCCESS) - { + if (result != VK_SUCCESS) { SDL_SetError("vkCreateWaylandSurfaceKHR failed: %s", SDL_Vulkan_GetResultString(result)); return SDL_FALSE; diff --git a/SDL2-2.0.12/src/video/wayland/SDL_waylandvulkan.h b/SDL2-2.30.5/src/video/wayland/SDL_waylandvulkan.h similarity index 72% rename from SDL2-2.0.12/src/video/wayland/SDL_waylandvulkan.h rename to SDL2-2.30.5/src/video/wayland/SDL_waylandvulkan.h index 224fa07..f42ed8e 100644 --- a/SDL2-2.0.12/src/video/wayland/SDL_waylandvulkan.h +++ b/SDL2-2.30.5/src/video/wayland/SDL_waylandvulkan.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -32,19 +32,18 @@ #include "../SDL_vulkan_internal.h" #include "../SDL_sysvideo.h" -#if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_WAYLAND +#if defined(SDL_VIDEO_VULKAN) && defined(SDL_VIDEO_DRIVER_WAYLAND) int Wayland_Vulkan_LoadLibrary(_THIS, const char *path); void Wayland_Vulkan_UnloadLibrary(_THIS); SDL_bool Wayland_Vulkan_GetInstanceExtensions(_THIS, - SDL_Window *window, - unsigned *count, - const char **names); -void Wayland_Vulkan_GetDrawableSize(_THIS, SDL_Window *window, int *w, int *h); + SDL_Window *window, + unsigned *count, + const char **names); SDL_bool Wayland_Vulkan_CreateSurface(_THIS, - SDL_Window *window, - VkInstance instance, - VkSurfaceKHR *surface); + SDL_Window *window, + VkInstance instance, + VkSurfaceKHR *surface); #endif diff --git a/SDL2-2.30.5/src/video/wayland/SDL_waylandwindow.c b/SDL2-2.30.5/src/video/wayland/SDL_waylandwindow.c new file mode 100644 index 0000000..c8d55de --- /dev/null +++ b/SDL2-2.30.5/src/video/wayland/SDL_waylandwindow.c @@ -0,0 +1,2362 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_WAYLAND + +#include "../SDL_sysvideo.h" +#include "../../events/SDL_windowevents_c.h" +#include "../../events/SDL_mouse_c.h" +#include "../SDL_egl_c.h" +#include "SDL_waylandevents_c.h" +#include "SDL_waylandwindow.h" +#include "SDL_waylandvideo.h" +#include "SDL_waylandtouch.h" +#include "SDL_hints.h" +#include "../../SDL_hints_c.h" +#include "SDL_events.h" + +#include "xdg-shell-client-protocol.h" +#include "xdg-decoration-unstable-v1-client-protocol.h" +#include "idle-inhibit-unstable-v1-client-protocol.h" +#include "xdg-activation-v1-client-protocol.h" +#include "viewporter-client-protocol.h" +#include "fractional-scale-v1-client-protocol.h" + +#ifdef HAVE_LIBDECOR_H +#include +#endif + +#define FULLSCREEN_MASK (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_FULLSCREEN_DESKTOP) + +SDL_FORCE_INLINE SDL_bool FloatEqual(float a, float b) +{ + const float diff = SDL_fabsf(a - b); + const float largest = SDL_max(SDL_fabsf(a), SDL_fabsf(b)); + + return diff <= largest * SDL_FLT_EPSILON; +} + +static void GetFullScreenDimensions(SDL_Window *window, int *width, int *height, int *drawable_width, int *drawable_height) +{ + SDL_WindowData *wind = (SDL_WindowData *)window->driverdata; + SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); + SDL_WaylandOutputData *output = display ? (SDL_WaylandOutputData *)display->driverdata : NULL; + + int fs_width, fs_height; + int buf_width, buf_height; + const int output_width = wind->fs_output_width ? wind->fs_output_width : (output ? output->width : wind->window_width); + const int output_height = wind->fs_output_height ? wind->fs_output_height : (output ? output->height : wind->window_height); + + /* + * Fullscreen desktop mandates a desktop sized window, so that's what applications will get. + * If the application is DPI aware, it will need to handle the transformations between the + * differently sized window and backbuffer spaces on its own. + */ + if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) { + fs_width = output_width; + fs_height = output_height; + + /* If the application is DPI aware, we can expose the true backbuffer size */ + if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) { + buf_width = output->native_width; + buf_height = output->native_height; + } else { + buf_width = fs_width; + buf_height = fs_height; + } + } else { + /* + * If a mode was set, use it, otherwise use the native resolution + * for DPI aware apps and the desktop size for legacy apps. + */ + if (window->fullscreen_mode.w != 0 && window->fullscreen_mode.h != 0) { + fs_width = window->fullscreen_mode.w; + fs_height = window->fullscreen_mode.h; + } else if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) { + fs_width = output->native_width; + fs_height = output->native_height; + } else { + fs_width = output_width; + fs_height = output_height; + } + + buf_width = fs_width; + buf_height = fs_height; + } + + if (width) { + *width = fs_width; + } + if (height) { + *height = fs_height; + } + if (drawable_width) { + *drawable_width = buf_width; + } + if (drawable_height) { + *drawable_height = buf_height; + } +} + +SDL_FORCE_INLINE SDL_bool SurfaceScaleIsFractional(SDL_Window *window) +{ + SDL_WindowData *data = window->driverdata; + return !FloatEqual(SDL_roundf(data->scale_factor), data->scale_factor); +} + +SDL_FORCE_INLINE SDL_bool FullscreenModeEmulation(SDL_Window *window) +{ + return (window->flags & SDL_WINDOW_FULLSCREEN) && + ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP); +} + +static SDL_bool NeedViewport(SDL_Window *window) +{ + SDL_WindowData *wind = window->driverdata; + SDL_VideoData *video = wind->waylandData; + SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); + SDL_WaylandOutputData *output = display ? ((SDL_WaylandOutputData *)display->driverdata) : NULL; + const int output_width = wind->fs_output_width ? wind->fs_output_width : (output ? output->width : wind->window_width); + const int output_height = wind->fs_output_height ? wind->fs_output_height : (output ? output->height : wind->window_height); + int fs_width, fs_height; + + /* + * A viewport is only required when scaling is enabled and: + * - A fullscreen mode is being emulated and the mode does not match the logical desktop dimensions. + * - The desktop uses fractional scaling and the high-DPI flag is set. + */ + if (video->viewporter) { + if (FullscreenModeEmulation(window)) { + GetFullScreenDimensions(window, &fs_width, &fs_height, NULL, NULL); + if (fs_width != output_width || fs_height != output_height) { + return SDL_TRUE; + } + } else if (SurfaceScaleIsFractional(window) && (window->flags & SDL_WINDOW_ALLOW_HIGHDPI)) { + return SDL_TRUE; + } + } + + return SDL_FALSE; +} + +static void GetBufferSize(SDL_Window *window, int *width, int *height) +{ + SDL_WindowData *data = window->driverdata; + int buf_width; + int buf_height; + + if (FullscreenModeEmulation(window)) { + GetFullScreenDimensions(window, NULL, NULL, &buf_width, &buf_height); + } else if (NeedViewport(window)) { + /* Round fractional backbuffer sizes halfway away from zero. */ + buf_width = (int)SDL_lroundf(window->w * data->scale_factor); + buf_height = (int)SDL_lroundf(window->h * data->scale_factor); + } else { + /* + * Integer scaled windowed or fullscreen with no viewport + * + * Round the scale factor up in the unlikely scenario of a compositor + * that supports fractional scaling, but not viewports. + */ + int scale_factor = (int)SDL_ceilf(data->scale_factor); + + buf_width = window->w * scale_factor; + buf_height = window->h * scale_factor; + } + + if (width) { + *width = buf_width; + } + if (height) { + *height = buf_height; + } +} + +static void SetDrawSurfaceViewport(SDL_Window *window, int src_width, int src_height, int dst_width, int dst_height) +{ + SDL_WindowData *wind = window->driverdata; + SDL_VideoData *video = wind->waylandData; + + if (video->viewporter) { + if (!wind->draw_viewport) { + wind->draw_viewport = wp_viewporter_get_viewport(video->viewporter, wind->surface); + } + + wp_viewport_set_source(wind->draw_viewport, wl_fixed_from_int(-1), wl_fixed_from_int(-1), wl_fixed_from_int(-1), wl_fixed_from_int(-1)); + wp_viewport_set_destination(wind->draw_viewport, dst_width, dst_height); + } +} + +static void UnsetDrawSurfaceViewport(SDL_Window *window) +{ + SDL_WindowData *wind = window->driverdata; + + if (wind->draw_viewport) { + wp_viewport_destroy(wind->draw_viewport); + wind->draw_viewport = NULL; + } +} + +static void ConfigureWindowGeometry(SDL_Window *window) +{ + SDL_WindowData *data = window->driverdata; + SDL_VideoData *viddata = data->waylandData; + SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); + SDL_WaylandOutputData *output = display ? (SDL_WaylandOutputData *)display->driverdata : NULL; + struct wl_region *region; + const int old_dw = data->drawable_width; + const int old_dh = data->drawable_height; + SDL_bool window_size_changed; + SDL_bool drawable_size_changed; + + /* Set the drawable backbuffer size. */ + GetBufferSize(window, &data->drawable_width, &data->drawable_height); + drawable_size_changed = data->drawable_width != old_dw || data->drawable_height != old_dh; + + if (data->egl_window && drawable_size_changed) { + WAYLAND_wl_egl_window_resize(data->egl_window, + data->drawable_width, + data->drawable_height, + 0, 0); + } + + if (FullscreenModeEmulation(window) && NeedViewport(window)) { + int fs_width, fs_height; + const int output_width = data->fs_output_width ? data->fs_output_width : (output ? output->width : data->window_width); + const int output_height = data->fs_output_height ? data->fs_output_height : (output ? output->height : data->window_height); + + window_size_changed = data->window_width != output_width || data->window_height != output_height; + + if (window_size_changed || drawable_size_changed) { + GetFullScreenDimensions(window, &fs_width, &fs_height, NULL, NULL); + + /* Set the buffer scale to 1 since a viewport will be used. */ + wl_surface_set_buffer_scale(data->surface, 1); + SetDrawSurfaceViewport(window, data->drawable_width, data->drawable_height, + output_width, output_height); + + data->window_width = output_width; + data->window_height = output_height; + + data->pointer_scale_x = (float)fs_width / (float)output_width; + data->pointer_scale_y = (float)fs_height / (float)output_height; + } + } else { + window_size_changed = data->window_width != window->w || data->window_height != window->h; + + if (window_size_changed || drawable_size_changed) { + if (NeedViewport(window)) { + wl_surface_set_buffer_scale(data->surface, 1); + SetDrawSurfaceViewport(window, data->drawable_width, data->drawable_height, window->w, window->h); + } else { + UnsetDrawSurfaceViewport(window); + + if (!FullscreenModeEmulation(window)) { + /* Round to the next integer in case of a fractional value. */ + wl_surface_set_buffer_scale(data->surface, (int32_t)SDL_ceilf(data->scale_factor)); + } else { + wl_surface_set_buffer_scale(data->surface, 1); + } + } + + /* Clamp the physical window size to the system minimum required size. */ + data->window_width = SDL_max(window->w, data->system_min_required_width); + data->window_height = SDL_max(window->h, data->system_min_required_height); + + data->pointer_scale_x = 1.0f; + data->pointer_scale_y = 1.0f; + } + } + + /* + * The surface geometry, opaque region and pointer confinement region only + * need to be recalculated if the output size has changed. + */ + if (window_size_changed) { + /* libdecor does this internally on frame commits, so it's only needed for xdg surfaces. */ + if (data->shell_surface_type != WAYLAND_SURFACE_LIBDECOR && + viddata->shell.xdg && data->shell_surface.xdg.surface) { + xdg_surface_set_window_geometry(data->shell_surface.xdg.surface, 0, 0, data->window_width, data->window_height); + } + + if (!viddata->egl_transparency_enabled) { + region = wl_compositor_create_region(viddata->compositor); + wl_region_add(region, 0, 0, + data->window_width, data->window_height); + wl_surface_set_opaque_region(data->surface, region); + wl_region_destroy(region); + } + + if (data->confined_pointer) { + Wayland_input_confine_pointer(viddata->input, window); + } + } +} + +static void CommitLibdecorFrame(SDL_Window *window) +{ +#ifdef HAVE_LIBDECOR_H + SDL_WindowData *wind = (SDL_WindowData *)window->driverdata; + + if (wind->shell_surface_type == WAYLAND_SURFACE_LIBDECOR && wind->shell_surface.libdecor.frame) { + struct libdecor_state *state = libdecor_state_new(wind->window_width, wind->window_height); + libdecor_frame_commit(wind->shell_surface.libdecor.frame, state, NULL); + libdecor_state_free(state); + } +#endif +} + +static void SetMinMaxDimensions(SDL_Window *window, SDL_bool commit) +{ + SDL_WindowData *wind = window->driverdata; + SDL_VideoData *viddata = wind->waylandData; + int min_width, min_height, max_width, max_height; + + /* Pop-ups don't get to change size */ + if (wind->shell_surface_type == WAYLAND_SURFACE_XDG_POPUP) { + /* ... but we still want to commit, particularly for ShowWindow */ + if (commit) { + wl_surface_commit(wind->surface); + } + return; + } + + if (window->flags & SDL_WINDOW_FULLSCREEN) { + min_width = 0; + min_height = 0; + max_width = 0; + max_height = 0; + } else if (window->flags & SDL_WINDOW_RESIZABLE) { + min_width = window->min_w; + min_height = window->min_h; + max_width = window->max_w; + max_height = window->max_h; + } else { + min_width = window->windowed.w; + min_height = window->windowed.h; + max_width = window->windowed.w; + max_height = window->windowed.h; + } + +#ifdef HAVE_LIBDECOR_H + if (wind->shell_surface_type == WAYLAND_SURFACE_LIBDECOR) { + if (!wind->shell_surface.libdecor.frame) { + return; /* Can't do anything yet, wait for ShowWindow */ + } + libdecor_frame_set_min_content_size(wind->shell_surface.libdecor.frame, + min_width, + min_height); + libdecor_frame_set_max_content_size(wind->shell_surface.libdecor.frame, + max_width, + max_height); + + if (commit) { + CommitLibdecorFrame(window); + wl_surface_commit(wind->surface); + } + } else +#endif + if (viddata->shell.xdg) { + if (wind->shell_surface.xdg.roleobj.toplevel == NULL) { + return; /* Can't do anything yet, wait for ShowWindow */ + } + xdg_toplevel_set_min_size(wind->shell_surface.xdg.roleobj.toplevel, + min_width, + min_height); + xdg_toplevel_set_max_size(wind->shell_surface.xdg.roleobj.toplevel, + max_width, + max_height); + if (commit) { + wl_surface_commit(wind->surface); + } + } +} + +static void SetFullscreen(SDL_Window *window, struct wl_output *output) +{ + SDL_WindowData *wind = window->driverdata; + SDL_VideoData *viddata = wind->waylandData; + + /* The desktop may try to enforce min/max sizes here, so turn them off for + * fullscreen and on (if applicable) for windowed + */ + SetMinMaxDimensions(window, SDL_FALSE); + +#ifdef HAVE_LIBDECOR_H + if (wind->shell_surface_type == WAYLAND_SURFACE_LIBDECOR) { + if (!wind->shell_surface.libdecor.frame) { + return; /* Can't do anything yet, wait for ShowWindow */ + } + if (output) { + if (!(window->flags & SDL_WINDOW_RESIZABLE)) { + /* Ensure that window is resizable before going into fullscreen. + * This triggers a frame commit internally, so a separate one is not necessary. + */ + libdecor_frame_set_capabilities(wind->shell_surface.libdecor.frame, LIBDECOR_ACTION_RESIZE); + wl_surface_commit(wind->surface); + } else { + CommitLibdecorFrame(window); + wl_surface_commit(wind->surface); + } + + libdecor_frame_set_fullscreen(wind->shell_surface.libdecor.frame, output); + } else { + libdecor_frame_unset_fullscreen(wind->shell_surface.libdecor.frame); + + if (!(window->flags & SDL_WINDOW_RESIZABLE)) { + /* restore previous RESIZE capability */ + libdecor_frame_unset_capabilities(wind->shell_surface.libdecor.frame, LIBDECOR_ACTION_RESIZE); + wl_surface_commit(wind->surface); + } else { + CommitLibdecorFrame(window); + wl_surface_commit(wind->surface); + } + } + } else +#endif + if (viddata->shell.xdg) { + if (wind->shell_surface.xdg.roleobj.toplevel == NULL) { + return; /* Can't do anything yet, wait for ShowWindow */ + } + + wl_surface_commit(wind->surface); + + if (output) { + xdg_toplevel_set_fullscreen(wind->shell_surface.xdg.roleobj.toplevel, output); + } else { + xdg_toplevel_unset_fullscreen(wind->shell_surface.xdg.roleobj.toplevel); + } + } +} + +static void UpdateWindowFullscreen(SDL_Window *window, SDL_bool fullscreen) +{ + SDL_WindowData *wind = (SDL_WindowData *)window->driverdata; + + if (fullscreen) { + if (!(window->flags & SDL_WINDOW_FULLSCREEN)) { + /* + * If the window was never previously made full screen, check if a particular + * fullscreen mode has been set for the window. If one is found, use SDL_WINDOW_FULLSCREEN, + * otherwise, use SDL_WINDOW_FULLSCREEN_DESKTOP. + * + * If the previous flag was SDL_WINDOW_FULLSCREEN, make sure a mode is still set, + * otherwise, fall back to SDL_WINDOW_FULLSCREEN_DESKTOP. + */ + if (!wind->fullscreen_flags) { + if (window->fullscreen_mode.w && window->fullscreen_mode.h) { + wind->fullscreen_flags = SDL_WINDOW_FULLSCREEN; + } else { + wind->fullscreen_flags = SDL_WINDOW_FULLSCREEN_DESKTOP; + } + } else if (wind->fullscreen_flags != SDL_WINDOW_FULLSCREEN_DESKTOP && + (!window->fullscreen_mode.w || !window->fullscreen_mode.h)) { + wind->fullscreen_flags = SDL_WINDOW_FULLSCREEN_DESKTOP; + } + + wind->is_fullscreen = SDL_TRUE; + + wind->in_fullscreen_transition = SDL_TRUE; + SDL_SetWindowFullscreen(window, wind->fullscreen_flags); + wind->in_fullscreen_transition = SDL_FALSE; + } + } else { + /* Don't change the fullscreen flags if the window is hidden or being hidden. */ + if (!window->is_hiding && !(window->flags & SDL_WINDOW_HIDDEN)) { + if (window->flags & SDL_WINDOW_FULLSCREEN) { + wind->is_fullscreen = SDL_FALSE; + + wind->in_fullscreen_transition = SDL_TRUE; + SDL_SetWindowFullscreen(window, 0); + wind->in_fullscreen_transition = SDL_FALSE; + SetMinMaxDimensions(window, SDL_FALSE); + } + } + } +} + +static const struct wl_callback_listener surface_damage_frame_listener; + +static void surface_damage_frame_done(void *data, struct wl_callback *cb, uint32_t time) +{ + SDL_WindowData *wind = (SDL_WindowData *)data; + + /* + * wl_surface.damage_buffer is the preferred method of setting the damage region + * on compositor version 4 and above. + */ + if (wl_compositor_get_version(wind->waylandData->compositor) >= 4) { + wl_surface_damage_buffer(wind->surface, 0, 0, + wind->drawable_width, wind->drawable_height); + } else { + wl_surface_damage(wind->surface, 0, 0, + wind->window_width, wind->window_height); + } + + wl_callback_destroy(cb); + wind->surface_damage_frame_callback = wl_surface_frame(wind->surface); + wl_callback_add_listener(wind->surface_damage_frame_callback, &surface_damage_frame_listener, data); +} + +static const struct wl_callback_listener surface_damage_frame_listener = { + surface_damage_frame_done +}; + +static const struct wl_callback_listener gles_swap_frame_listener; + +static void gles_swap_frame_done(void *data, struct wl_callback *cb, uint32_t time) +{ + SDL_WindowData *wind = (SDL_WindowData *)data; + SDL_AtomicSet(&wind->swap_interval_ready, 1); /* mark window as ready to present again. */ + + /* reset this callback to fire again once a new frame was presented and compositor wants the next one. */ + wind->gles_swap_frame_callback = wl_surface_frame(wind->gles_swap_frame_surface_wrapper); + wl_callback_destroy(cb); + wl_callback_add_listener(wind->gles_swap_frame_callback, &gles_swap_frame_listener, data); +} + +static const struct wl_callback_listener gles_swap_frame_listener = { + gles_swap_frame_done +}; + +static void Wayland_HandleResize(SDL_Window *window, int width, int height, float scale); + +static void handle_configure_xdg_shell_surface(void *data, struct xdg_surface *xdg, uint32_t serial) +{ + SDL_WindowData *wind = (SDL_WindowData *)data; + SDL_Window *window = wind->sdlwindow; + + Wayland_HandleResize(window, window->w, window->h, wind->scale_factor); + xdg_surface_ack_configure(xdg, serial); + + wind->shell_surface.xdg.initial_configure_seen = SDL_TRUE; +} + +static const struct xdg_surface_listener shell_surface_listener_xdg = { + handle_configure_xdg_shell_surface +}; + +static void handle_configure_xdg_toplevel(void *data, + struct xdg_toplevel *xdg_toplevel, + int32_t width, + int32_t height, + struct wl_array *states) +{ + SDL_WindowData *wind = (SDL_WindowData *)data; + SDL_Window *window = wind->sdlwindow; + + enum xdg_toplevel_state *state; + SDL_bool fullscreen = SDL_FALSE; + SDL_bool maximized = SDL_FALSE; + SDL_bool floating = SDL_TRUE; + wl_array_for_each (state, states) { + switch (*state) { + case XDG_TOPLEVEL_STATE_FULLSCREEN: + fullscreen = SDL_TRUE; + floating = SDL_FALSE; + break; + case XDG_TOPLEVEL_STATE_MAXIMIZED: + maximized = SDL_TRUE; + floating = SDL_FALSE; + break; + case XDG_TOPLEVEL_STATE_TILED_LEFT: + case XDG_TOPLEVEL_STATE_TILED_RIGHT: + case XDG_TOPLEVEL_STATE_TILED_TOP: + case XDG_TOPLEVEL_STATE_TILED_BOTTOM: + floating = SDL_FALSE; + break; + default: + break; + } + } + + UpdateWindowFullscreen(window, fullscreen); + + if (!fullscreen) { + if (width == 0 || height == 0) { + /* This usually happens when we're being restored from a + * non-floating state, so use the cached floating size here. + */ + width = wind->floating_width; + height = wind->floating_height; + } + + /* xdg_toplevel spec states that this is a suggestion. + Ignore if less than or greater than max/min size. */ + + if (window->flags & SDL_WINDOW_RESIZABLE) { + if (window->max_w > 0) { + width = SDL_min(width, window->max_w); + } + width = SDL_max(width, window->min_w); + + if (window->max_h > 0) { + height = SDL_min(height, window->max_h); + } + height = SDL_max(height, window->min_h); + } else if (floating) { + /* If we're a fixed-size window, we know our size for sure. + * Always assume the configure is wrong. + */ + width = window->windowed.w; + height = window->windowed.h; + } + + /* Always send a maximized/restore event; if the event is redundant it will + * automatically be discarded (see src/events/SDL_windowevents.c) + * + * No, we do not get minimize events from xdg-shell. + */ + SDL_SendWindowEvent(window, + maximized ? SDL_WINDOWEVENT_MAXIMIZED : SDL_WINDOWEVENT_RESTORED, + 0, 0); + + /* Store current floating dimensions for restoring */ + if (floating) { + wind->floating_width = width; + wind->floating_height = height; + } + + /* Store this now so the xdg_surface configure knows what to resize to */ + if (window->w != width || window->h != height) { + window->w = width; + window->h = height; + wind->needs_resize_event = SDL_TRUE; + } + } else { + /* For fullscreen, foolishly do what the compositor says. If it's wrong, + * don't blame us, we were explicitly instructed to do this. + * + * UPDATE: Nope, sure enough a compositor sends 0,0. This is a known bug: + * https://bugs.kde.org/show_bug.cgi?id=444962 + */ + if (width && height) { + wind->fs_output_width = width; + wind->fs_output_height = height; + } else { + wind->fs_output_width = 0; + wind->fs_output_height = 0; + } + + if (FullscreenModeEmulation(window)) { + GetFullScreenDimensions(window, &width, &height, NULL, NULL); + } + if (width != 0 && height != 0 && (window->w != width || window->h != height)) { + window->w = width; + window->h = height; + wind->needs_resize_event = SDL_TRUE; + } + } +} + +static void handle_close_xdg_toplevel(void *data, struct xdg_toplevel *xdg_toplevel) +{ + SDL_WindowData *window = (SDL_WindowData *)data; + SDL_SendWindowEvent(window->sdlwindow, SDL_WINDOWEVENT_CLOSE, 0, 0); +} + +static const struct xdg_toplevel_listener toplevel_listener_xdg = { + handle_configure_xdg_toplevel, + handle_close_xdg_toplevel +}; + +static void handle_configure_xdg_popup(void *data, + struct xdg_popup *xdg_popup, + int32_t x, + int32_t y, + int32_t width, + int32_t height) +{ + /* No-op, we don't use x/y and width/height are fixed-size */ +} + +static void handle_done_xdg_popup(void *data, struct xdg_popup *xdg_popup) +{ + SDL_WindowData *window = (SDL_WindowData *)data; + SDL_SendWindowEvent(window->sdlwindow, SDL_WINDOWEVENT_CLOSE, 0, 0); +} + +static void handle_repositioned_xdg_popup(void *data, + struct xdg_popup *xdg_popup, + uint32_t token) +{ + /* No-op, configure does all the work we care about */ +} + +static const struct xdg_popup_listener popup_listener_xdg = { + handle_configure_xdg_popup, + handle_done_xdg_popup, + handle_repositioned_xdg_popup +}; + +#define TOOLTIP_CURSOR_OFFSET 8 /* FIXME: Arbitrary, eyeballed from X tooltip */ + +static int Wayland_PopupWatch(void *data, SDL_Event *event) +{ + if (event->type == SDL_MOUSEMOTION) { + SDL_Window *window = (SDL_Window *)data; + SDL_WindowData *wind = window->driverdata; + + /* Coordinates might be relative to the popup, which we don't want */ + if (event->motion.windowID == wind->shell_surface.xdg.roleobj.popup.parentID) { + xdg_positioner_set_offset(wind->shell_surface.xdg.roleobj.popup.positioner, + event->motion.x + TOOLTIP_CURSOR_OFFSET, + event->motion.y + TOOLTIP_CURSOR_OFFSET); + xdg_popup_reposition(wind->shell_surface.xdg.roleobj.popup.popup, + wind->shell_surface.xdg.roleobj.popup.positioner, + 0); + } + } + return 1; +} + +static void handle_configure_zxdg_decoration(void *data, + struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1, + uint32_t mode) +{ + SDL_Window *window = (SDL_Window *)data; + SDL_WindowData *driverdata = (SDL_WindowData *)window->driverdata; + SDL_VideoDevice *device = SDL_GetVideoDevice(); + + /* If the compositor tries to force CSD anyway, bail on direct XDG support + * and fall back to libdecor, it will handle these events from then on. + * + * To do this we have to fully unmap, then map with libdecor loaded. + */ + if (mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE) { + if (window->flags & SDL_WINDOW_BORDERLESS) { + /* borderless windows do request CSD, so we got what we wanted */ + return; + } + if (!Wayland_LoadLibdecor(driverdata->waylandData, SDL_TRUE)) { + /* libdecor isn't available, so no borders for you... oh well */ + return; + } + WAYLAND_wl_display_roundtrip(driverdata->waylandData->display); + + Wayland_HideWindow(device, window); + SDL_zero(driverdata->shell_surface); + driverdata->shell_surface_type = WAYLAND_SURFACE_LIBDECOR; + + Wayland_ShowWindow(device, window); + } +} + +static const struct zxdg_toplevel_decoration_v1_listener decoration_listener = { + handle_configure_zxdg_decoration +}; + +#ifdef HAVE_LIBDECOR_H +/* + * XXX: Hack for older versions of libdecor that lack the function to query the + * minimum content size limit. The internal limits must always be overridden + * to ensure that very small windows don't cause errors or crashes. + * + * On versions of libdecor that expose the function to get the minimum content + * size limit, this function is a no-op. + * + * Can be removed if the minimum required version of libdecor is raised + * to a version that guarantees the availability of this function. + */ +static void OverrideLibdecorLimits(SDL_Window *window) +{ +#if defined(SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR) + if (!libdecor_frame_get_min_content_size) { + SetMinMaxDimensions(window, SDL_FALSE); + } +#elif !defined(SDL_HAVE_LIBDECOR_GET_MIN_MAX) + SetMinMaxDimensions(window, SDL_FALSE); +#endif +} + +/* + * NOTE: Retrieves the minimum content size limits, if the function for doing so is available. + * On versions of libdecor that lack the minimum content size retrieval function, this + * function is a no-op. + * + * Can be replaced with a direct call if the minimum required version of libdecor is raised + * to a version that guarantees the availability of this function. + */ +static void LibdecorGetMinContentSize(struct libdecor_frame *frame, int *min_w, int *min_h) +{ +#if defined(SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR) + if (libdecor_frame_get_min_content_size != NULL) { + libdecor_frame_get_min_content_size(frame, min_w, min_h); + } +#elif defined(SDL_HAVE_LIBDECOR_GET_MIN_MAX) + libdecor_frame_get_min_content_size(frame, min_w, min_h); +#endif +} + +static void decoration_frame_configure(struct libdecor_frame *frame, + struct libdecor_configuration *configuration, + void *user_data) +{ + SDL_WindowData *wind = (SDL_WindowData *)user_data; + SDL_Window *window = wind->sdlwindow; + struct libdecor_state *state; + + enum libdecor_window_state window_state; + int width, height; + + SDL_bool focused = SDL_FALSE; + SDL_bool fullscreen = SDL_FALSE; + SDL_bool maximized = SDL_FALSE; + SDL_bool tiled = SDL_FALSE; + SDL_bool floating; + + static const enum libdecor_window_state tiled_states = (LIBDECOR_WINDOW_STATE_TILED_LEFT | LIBDECOR_WINDOW_STATE_TILED_RIGHT | + LIBDECOR_WINDOW_STATE_TILED_TOP | LIBDECOR_WINDOW_STATE_TILED_BOTTOM); + + /* Window State */ + if (libdecor_configuration_get_window_state(configuration, &window_state)) { + fullscreen = (window_state & LIBDECOR_WINDOW_STATE_FULLSCREEN) != 0; + maximized = (window_state & LIBDECOR_WINDOW_STATE_MAXIMIZED) != 0; + focused = (window_state & LIBDECOR_WINDOW_STATE_ACTIVE) != 0; + tiled = (window_state & tiled_states) != 0; + } + floating = !(fullscreen || maximized || tiled); + + UpdateWindowFullscreen(window, fullscreen); + + if (!fullscreen) { + /* Always send a maximized/restore event; if the event is redundant it will + * automatically be discarded (see src/events/SDL_windowevents.c) + * + * No, we do not get minimize events from libdecor. + */ + SDL_SendWindowEvent(window, + maximized ? SDL_WINDOWEVENT_MAXIMIZED : SDL_WINDOWEVENT_RESTORED, + 0, 0); + } + + /* Similar to maximized/restore events above, send focus events too! */ + SDL_SendWindowEvent(window, + focused ? SDL_WINDOWEVENT_FOCUS_GAINED : SDL_WINDOWEVENT_FOCUS_LOST, + 0, 0); + + /* For fullscreen or fixed-size windows we know our size. + * Always assume the configure is wrong. + */ + if (fullscreen) { + /* FIXME: We have been explicitly told to respect the fullscreen size + * parameters here, even though they are known to be wrong on GNOME at + * bare minimum. If this is wrong, don't blame us, we were explicitly + * told to do this. + */ + if (libdecor_configuration_get_content_size(configuration, frame, + &width, &height)) { + wind->fs_output_width = width; + wind->fs_output_height = height; + } else { + width = window->w; + height = window->h; + wind->fs_output_width = 0; + wind->fs_output_height = 0; + } + + if (FullscreenModeEmulation(window)) { + GetFullScreenDimensions(window, &width, &height, NULL, NULL); + } + } else if (!(window->flags & SDL_WINDOW_RESIZABLE) || (floating && wind->floating_resize_pending)) { + width = window->windowed.w; + height = window->windowed.h; + wind->floating_resize_pending = SDL_FALSE; + + OverrideLibdecorLimits(window); + } else { + /* + * XXX: libdecor can send bogus content sizes that are +/- the height + * of the title bar when hiding a window or transitioning from + * non-floating to floating state, which distorts the window size. + * + * Ignore any size values from libdecor in these scenarios in + * favor of the cached window size. + * + * https://gitlab.gnome.org/jadahl/libdecor/-/issues/40 + */ + const SDL_bool use_cached_size = (floating && !wind->was_floating) || + (window->is_hiding || !!(window->flags & SDL_WINDOW_HIDDEN)); + + /* This will never set 0 for width/height unless the function returns false */ + if (use_cached_size || !libdecor_configuration_get_content_size(configuration, frame, &width, &height)) { + if (floating) { + /* This usually happens when we're being restored from a + * non-floating state, so use the cached floating size here. + */ + width = wind->floating_width; + height = wind->floating_height; + } else { + width = window->w; + height = window->h; + } + } + } + + /* Store current floating dimensions for restoring */ + if (floating) { + wind->floating_width = width; + wind->floating_height = height; + } + + wind->was_floating = floating; + + /* Do the resize on the SDL side (this will set window->w/h)... */ + Wayland_HandleResize(window, width, height, wind->scale_factor); + + /* ... then commit the changes on the libdecor side. */ + state = libdecor_state_new(wind->window_width, wind->window_height); + libdecor_frame_commit(frame, state, configuration); + libdecor_state_free(state); + + if (!wind->shell_surface.libdecor.initial_configure_seen) { + LibdecorGetMinContentSize(frame, &wind->system_min_required_width, &wind->system_min_required_height); + wind->shell_surface.libdecor.initial_configure_seen = SDL_TRUE; + } + + /* Update the resize capability. Since this will change the capabilities and + * commit a new frame state with the last known content dimension, this has + * to be called after the new state has been committed and the new content + * dimensions were updated. + */ + Wayland_SetWindowResizable(SDL_GetVideoDevice(), window, + window->flags & SDL_WINDOW_RESIZABLE); +} + +static void decoration_frame_close(struct libdecor_frame *frame, void *user_data) +{ + SDL_SendWindowEvent(((SDL_WindowData *)user_data)->sdlwindow, SDL_WINDOWEVENT_CLOSE, 0, 0); +} + +static void decoration_frame_commit(struct libdecor_frame *frame, void *user_data) +{ + SDL_WindowData *wind = user_data; + + SDL_SendWindowEvent(wind->sdlwindow, SDL_WINDOWEVENT_EXPOSED, 0, 0); +} + +static struct libdecor_frame_interface libdecor_frame_interface = { + decoration_frame_configure, + decoration_frame_close, + decoration_frame_commit, +}; +#endif + +#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH +static void handle_onscreen_visibility(void *data, + struct qt_extended_surface *qt_extended_surface, int32_t visible) +{ +} + +static void handle_set_generic_property(void *data, + struct qt_extended_surface *qt_extended_surface, const char *name, + struct wl_array *value) +{ +} + +static void handle_close(void *data, struct qt_extended_surface *qt_extended_surface) +{ + SDL_WindowData *window = (SDL_WindowData *)data; + SDL_SendWindowEvent(window->sdlwindow, SDL_WINDOWEVENT_CLOSE, 0, 0); +} + +static const struct qt_extended_surface_listener extended_surface_listener = { + handle_onscreen_visibility, + handle_set_generic_property, + handle_close, +}; +#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ + +static void update_scale_factor(SDL_WindowData *window) +{ + const float old_factor = window->scale_factor; + float new_factor; + int i; + + if (!(window->sdlwindow->flags & SDL_WINDOW_ALLOW_HIGHDPI)) { + /* Scale will always be 1, just ignore this */ + return; + } + + if (window->num_outputs == 0) { + /* No display connected, just fall back. */ + new_factor = old_factor; + } else if (FULLSCREEN_VISIBLE(window->sdlwindow)) { + /* For fullscreen, use the active display's scale factor */ + SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window->sdlwindow); + if (display) { + SDL_WaylandOutputData *driverdata = display->driverdata; + new_factor = driverdata->scale_factor; + } else { + new_factor = old_factor; + } + } else { + /* Check every display's factor, use the highest */ + new_factor = 0.0f; + for (i = 0; i < window->num_outputs; i++) { + SDL_WaylandOutputData *driverdata = window->outputs[i]; + new_factor = SDL_max(new_factor, driverdata->scale_factor); + } + } + + if (!FloatEqual(new_factor, old_factor)) { + Wayland_HandleResize(window->sdlwindow, window->sdlwindow->w, window->sdlwindow->h, new_factor); + } +} + +/* While we can't get window position from the compositor, we do at least know + * what monitor we're on, so let's send move events that put the window at the + * center of the whatever display the wl_surface_listener events give us. + */ +static void Wayland_move_window(SDL_Window *window, + SDL_WaylandOutputData *driverdata) +{ + SDL_WindowData *wind = (SDL_WindowData *)window->driverdata; + SDL_VideoDisplay *display; + SDL_bool fs_display_changed = SDL_FALSE; + int i, j; + const int numdisplays = SDL_GetNumVideoDisplays(); + for (i = 0; i < numdisplays; i += 1) { + display = SDL_GetDisplay(i); + if (display->driverdata == driverdata) { + SDL_Rect bounds; + + /* If the window is fullscreen and not on the target display, move it. */ + if ((window->flags & SDL_WINDOW_FULLSCREEN) && display->fullscreen_window != window) { + /* If the target display already has a fullscreen window, minimize it. */ + if (display->fullscreen_window) { + SDL_MinimizeWindow(display->fullscreen_window); + } + + /* Find the window and move it to the target display. */ + for (j = 0; j < numdisplays; ++j) { + SDL_VideoDisplay *v = SDL_GetDisplay(j); + + if (v->fullscreen_window == window) { + v->fullscreen_window = NULL; + } + } + + display->fullscreen_window = window; + fs_display_changed = SDL_TRUE; + } + + /* We want to send a very very specific combination here: + * + * 1. A coordinate that tells the application what display we're on + * 2. Exactly (0, 0) + * + * Part 1 is useful information but is also really important for + * ensuring we end up on the right display for fullscreen, while + * part 2 is important because numerous applications use a specific + * combination of GetWindowPosition and GetGlobalMouseState, and of + * course neither are supported by Wayland. Since global mouse will + * fall back to just GetMouseState, we need the window position to + * be zero so the cursor math works without it going off in some + * random direction. See UE5 Editor for a notable example of this! + * + * This may be an issue some day if we're ever able to implement + * SDL_GetDisplayUsableBounds! + * + * -flibit + */ + SDL_GetDisplayBounds(i, &bounds); + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MOVED, bounds.x, bounds.y); + + /* + * If the fullscreen output was changed, and we have bad dimensions from + * the compositor, commit with the dimensions of the new display. + */ + if (fs_display_changed && + (!wind->fs_output_width || !wind->fs_output_height)) { + ConfigureWindowGeometry(window); + CommitLibdecorFrame(window); + } + + break; + } + } +} + +static void handle_surface_enter(void *data, struct wl_surface *surface, + struct wl_output *output) +{ + SDL_WindowData *window = data; + SDL_WaylandOutputData *driverdata = wl_output_get_user_data(output); + + if (!SDL_WAYLAND_own_output(output) || !SDL_WAYLAND_own_surface(surface)) { + return; + } + + window->outputs = SDL_realloc(window->outputs, + sizeof(SDL_WaylandOutputData *) * (window->num_outputs + 1)); + window->outputs[window->num_outputs++] = driverdata; + + /* Update the scale factor after the move so that fullscreen outputs are updated. */ + Wayland_move_window(window->sdlwindow, driverdata); + + if (!window->fractional_scale) { + update_scale_factor(window); + } +} + +static void handle_surface_leave(void *data, struct wl_surface *surface, + struct wl_output *output) +{ + SDL_WindowData *window = data; + int i, send_move_event = 0; + SDL_WaylandOutputData *driverdata = wl_output_get_user_data(output); + + if (!SDL_WAYLAND_own_output(output) || !SDL_WAYLAND_own_surface(surface)) { + return; + } + + for (i = 0; i < window->num_outputs; i++) { + if (window->outputs[i] == driverdata) { /* remove this one */ + if (i == (window->num_outputs - 1)) { + window->outputs[i] = NULL; + send_move_event = 1; + } else { + SDL_memmove(&window->outputs[i], + &window->outputs[i + 1], + sizeof(SDL_WaylandOutputData *) * ((window->num_outputs - i) - 1)); + } + window->num_outputs--; + i--; + } + } + + if (window->num_outputs == 0) { + SDL_free(window->outputs); + window->outputs = NULL; + } else if (send_move_event) { + Wayland_move_window(window->sdlwindow, + window->outputs[window->num_outputs - 1]); + } + + if (!window->fractional_scale) { + update_scale_factor(window); + } +} + +static const struct wl_surface_listener surface_listener = { + handle_surface_enter, + handle_surface_leave +}; + +static void Wayland_FillEmptyShellInfo(SDL_SysWMinfo * info, const Uint32 version) +{ + info->info.wl.xdg_surface = NULL; + if (version >= SDL_VERSIONNUM(2, 0, 17)) { + info->info.wl.xdg_toplevel = NULL; + if (version >= SDL_VERSIONNUM(2, 0, 22)) { + info->info.wl.xdg_popup = NULL; + info->info.wl.xdg_positioner = NULL; + } + } +} + +SDL_bool Wayland_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info) +{ + SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata; + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + const Uint32 version = SDL_VERSIONNUM((Uint32)info->version.major, + (Uint32)info->version.minor, + (Uint32)info->version.patch); + + /* Before 2.0.6, it was possible to build an SDL with Wayland support + (SDL_SysWMinfo will be large enough to hold Wayland info), but build + your app against SDL headers that didn't have Wayland support + (SDL_SysWMinfo could be smaller than Wayland needs. This would lead + to an app properly using SDL_GetWindowWMInfo() but we'd accidentally + overflow memory on the stack or heap. To protect against this, we've + padded out the struct unconditionally in the headers and Wayland will + just return an error for older apps using this function. Those apps + will need to be recompiled against newer headers or not use Wayland, + maybe by forcing SDL_VIDEODRIVER=x11. */ + if (version < SDL_VERSIONNUM(2, 0, 6)) { + info->subsystem = SDL_SYSWM_UNKNOWN; + SDL_SetError("Version must be 2.0.6 or newer"); + return SDL_FALSE; + } + + info->info.wl.display = data->waylandData->display; + info->info.wl.surface = data->surface; + + if (version >= SDL_VERSIONNUM(2, 0, 15)) { + info->info.wl.egl_window = data->egl_window; + +#ifdef HAVE_LIBDECOR_H + if (data->shell_surface_type == WAYLAND_SURFACE_LIBDECOR) { + if (data->shell_surface.libdecor.frame) { + info->info.wl.xdg_surface = libdecor_frame_get_xdg_surface(data->shell_surface.libdecor.frame); + if (version >= SDL_VERSIONNUM(2, 0, 17)) { + info->info.wl.xdg_toplevel = libdecor_frame_get_xdg_toplevel(data->shell_surface.libdecor.frame); + if (version >= SDL_VERSIONNUM(2, 0, 22)) { + info->info.wl.xdg_popup = NULL; + info->info.wl.xdg_positioner = NULL; + } + } + } else { + /* Not mapped yet */ + Wayland_FillEmptyShellInfo(info, version); + } + } else +#endif + if (viddata->shell.xdg && data->shell_surface.xdg.surface) { + info->info.wl.xdg_surface = data->shell_surface.xdg.surface; + if (version >= SDL_VERSIONNUM(2, 0, 17)) { + SDL_bool popup = data->shell_surface_type == WAYLAND_SURFACE_XDG_POPUP; + info->info.wl.xdg_toplevel = popup ? NULL : data->shell_surface.xdg.roleobj.toplevel; + if (version >= SDL_VERSIONNUM(2, 0, 22)) { + if (popup) { + info->info.wl.xdg_popup = data->shell_surface.xdg.roleobj.popup.popup; + info->info.wl.xdg_positioner = data->shell_surface.xdg.roleobj.popup.positioner; + } else { + info->info.wl.xdg_popup = NULL; + info->info.wl.xdg_positioner = NULL; + } + } + } + } else { + /* Either it's not mapped yet or we don't have a shell protocol */ + Wayland_FillEmptyShellInfo(info, version); + } + } + + /* Deprecated in 2.0.16 */ + info->info.wl.shell_surface = NULL; + + info->subsystem = SDL_SYSWM_WAYLAND; + + return SDL_TRUE; +} + +int Wayland_SetWindowHitTest(SDL_Window *window, SDL_bool enabled) +{ + return 0; /* just succeed, the real work is done elsewhere. */ +} + +int Wayland_SetWindowModalFor(_THIS, SDL_Window *modal_window, SDL_Window *parent_window) +{ + SDL_VideoData *viddata = (SDL_VideoData *)_this->driverdata; + SDL_WindowData *modal_data = modal_window->driverdata; + SDL_WindowData *parent_data = parent_window->driverdata; + + if (modal_data->shell_surface_type == WAYLAND_SURFACE_XDG_POPUP || parent_data->shell_surface_type == WAYLAND_SURFACE_XDG_POPUP) { + return SDL_SetError("Modal/Parent was a popup, not a toplevel"); + } + +#ifdef HAVE_LIBDECOR_H + if (viddata->shell.libdecor) { + if (!modal_data->shell_surface.libdecor.frame) { + return SDL_SetError("Modal window was hidden"); + } + if (!parent_data->shell_surface.libdecor.frame) { + return SDL_SetError("Parent window was hidden"); + } + libdecor_frame_set_parent(modal_data->shell_surface.libdecor.frame, + parent_data->shell_surface.libdecor.frame); + } else +#endif + if (viddata->shell.xdg) { + if (modal_data->shell_surface.xdg.roleobj.toplevel == NULL) { + return SDL_SetError("Modal window was hidden"); + } + if (parent_data->shell_surface.xdg.roleobj.toplevel == NULL) { + return SDL_SetError("Parent window was hidden"); + } + xdg_toplevel_set_parent(modal_data->shell_surface.xdg.roleobj.toplevel, + parent_data->shell_surface.xdg.roleobj.toplevel); + } else { + return SDL_Unsupported(); + } + + WAYLAND_wl_display_flush(viddata->display); + return 0; +} + +void Wayland_ShowWindow(_THIS, SDL_Window *window) +{ + SDL_VideoData *c = _this->driverdata; + SDL_WindowData *data = window->driverdata; + + /* Detach any previous buffers before resetting everything, otherwise when + * calling this a second time you'll get an annoying protocol error! + * + * FIXME: This was originally moved to HideWindow, which _should_ make + * sense, but for whatever reason UE5's popups require that this actually + * be in both places at once? Possibly from renderers making commits? I can't + * fully remember if this location caused crashes or if I was fixing a pair + * of Hide/Show calls. In any case, UE gives us a pretty good test and having + * both detach calls passes. This bug may be relevant if I'm wrong: + * + * https://bugs.kde.org/show_bug.cgi?id=448856 + * + * -flibit + */ + wl_surface_attach(data->surface, NULL, 0, 0); + wl_surface_commit(data->surface); + + /* Create the shell surface and map the toplevel/popup */ +#ifdef HAVE_LIBDECOR_H + if (data->shell_surface_type == WAYLAND_SURFACE_LIBDECOR) { + data->shell_surface.libdecor.frame = libdecor_decorate(c->shell.libdecor, + data->surface, + &libdecor_frame_interface, + data); + if (!data->shell_surface.libdecor.frame) { + SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Failed to create libdecor frame!"); + } else { + libdecor_frame_set_app_id(data->shell_surface.libdecor.frame, c->classname); + libdecor_frame_map(data->shell_surface.libdecor.frame); + } + } else +#endif + if (c->shell.xdg) { + data->shell_surface.xdg.surface = xdg_wm_base_get_xdg_surface(c->shell.xdg, data->surface); + xdg_surface_set_user_data(data->shell_surface.xdg.surface, data); + xdg_surface_add_listener(data->shell_surface.xdg.surface, &shell_surface_listener_xdg, data); + + if (data->shell_surface_type == WAYLAND_SURFACE_XDG_POPUP) { + SDL_Mouse *mouse = SDL_GetMouse(); + SDL_Window *focused = SDL_GetMouseFocus(); + SDL_WindowData *focuseddata = focused->driverdata; + + /* This popup may be a child of another popup! */ + data->shell_surface.xdg.roleobj.popup.parentID = SDL_GetWindowID(focused); + data->shell_surface.xdg.roleobj.popup.child = NULL; + if (focuseddata->shell_surface_type == WAYLAND_SURFACE_XDG_POPUP) { + SDL_assert(focuseddata->shell_surface.xdg.roleobj.popup.child == NULL); + focuseddata->shell_surface.xdg.roleobj.popup.child = window; + } + + /* Set up the positioner for the popup */ + data->shell_surface.xdg.roleobj.popup.positioner = xdg_wm_base_create_positioner(c->shell.xdg); + xdg_positioner_set_offset(data->shell_surface.xdg.roleobj.popup.positioner, + mouse->x + TOOLTIP_CURSOR_OFFSET, + mouse->y + TOOLTIP_CURSOR_OFFSET); + + /* Assign the popup role */ + data->shell_surface.xdg.roleobj.popup.popup = xdg_surface_get_popup(data->shell_surface.xdg.surface, + focuseddata->shell_surface.xdg.surface, + data->shell_surface.xdg.roleobj.popup.positioner); + xdg_popup_add_listener(data->shell_surface.xdg.roleobj.popup.popup, &popup_listener_xdg, data); + + /* For tooltips, track mouse motion so it follows the cursor */ + if (window->flags & SDL_WINDOW_TOOLTIP) { + if (xdg_popup_get_version(data->shell_surface.xdg.roleobj.popup.popup) >= 3) { + SDL_AddEventWatch(Wayland_PopupWatch, window); + } + } + } else { + data->shell_surface.xdg.roleobj.toplevel = xdg_surface_get_toplevel(data->shell_surface.xdg.surface); + xdg_toplevel_set_app_id(data->shell_surface.xdg.roleobj.toplevel, c->classname); + xdg_toplevel_add_listener(data->shell_surface.xdg.roleobj.toplevel, &toplevel_listener_xdg, data); + + SetMinMaxDimensions(window, SDL_FALSE); + } + } + + /* Restore state that was set prior to this call */ + Wayland_SetWindowTitle(_this, window); + if (window->flags & SDL_WINDOW_MAXIMIZED) { + Wayland_MaximizeWindow(_this, window); + } + if (window->flags & SDL_WINDOW_MINIMIZED) { + Wayland_MinimizeWindow(_this, window); + } + + /* We have to wait until the surface gets a "configure" event, or use of + * this surface will fail. This is a new rule for xdg_shell. + */ +#ifdef HAVE_LIBDECOR_H + if (data->shell_surface_type == WAYLAND_SURFACE_LIBDECOR) { + if (data->shell_surface.libdecor.frame) { + while (!data->shell_surface.libdecor.initial_configure_seen) { + WAYLAND_wl_display_flush(c->display); + WAYLAND_wl_display_dispatch(c->display); + } + } + } else +#endif + if (c->shell.xdg) { + /* Unlike libdecor we need to call this explicitly to prevent a deadlock. + * libdecor will call this as part of their configure event! + * -flibit + */ + wl_surface_commit(data->surface); + if (data->shell_surface.xdg.surface) { + while (!data->shell_surface.xdg.initial_configure_seen) { + WAYLAND_wl_display_flush(c->display); + WAYLAND_wl_display_dispatch(c->display); + } + } + + /* Create the window decorations */ + if (data->shell_surface_type != WAYLAND_SURFACE_XDG_POPUP && data->shell_surface.xdg.roleobj.toplevel && c->decoration_manager) { + data->server_decoration = zxdg_decoration_manager_v1_get_toplevel_decoration(c->decoration_manager, data->shell_surface.xdg.roleobj.toplevel); + zxdg_toplevel_decoration_v1_add_listener(data->server_decoration, + &decoration_listener, + window); + } + + /* Set the geometry */ + xdg_surface_set_window_geometry(data->shell_surface.xdg.surface, 0, 0, data->window_width, data->window_height); + } else { + /* Nothing to see here, just commit. */ + wl_surface_commit(data->surface); + } + + /* Unlike the rest of window state we have to set this _after_ flushing the + * display, because we need to create the decorations before possibly hiding + * them immediately afterward. + */ +#ifdef HAVE_LIBDECOR_H + if (data->shell_surface_type == WAYLAND_SURFACE_LIBDECOR) { + /* ... but don't call it redundantly for libdecor, the decorator + * may not interpret a redundant call nicely and cause weird stuff to happen + */ + if (data->shell_surface.libdecor.frame && window->flags & SDL_WINDOW_BORDERLESS) { + Wayland_SetWindowBordered(_this, window, SDL_FALSE); + } + + /* Libdecor plugins can enforce minimum window sizes, so adjust if the initial window size is too small. */ + if (window->windowed.w < data->system_min_required_width || + window->windowed.h < data->system_min_required_height) { + + /* Warn if the window frame will be larger than the content surface. */ + SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, + "Window dimensions (%i, %i) are smaller than the system enforced minimum (%i, %i); window borders will be larger than the content surface.", + window->windowed.w, window->windowed.h, data->system_min_required_width, data->system_min_required_height); + + data->window_width = SDL_max(window->windowed.w, data->system_min_required_width); + data->window_height = SDL_max(window->windowed.h, data->system_min_required_height); + CommitLibdecorFrame(window); + } + } else +#endif + { + Wayland_SetWindowBordered(_this, window, !(window->flags & SDL_WINDOW_BORDERLESS)); + } + + /* We're finally done putting the window together, raise if possible */ + if (c->activation_manager) { + /* Note that we don't check for empty strings, as that is still + * considered a valid activation token! + */ + const char *activation_token = SDL_getenv("XDG_ACTIVATION_TOKEN"); + if (activation_token) { + xdg_activation_v1_activate(c->activation_manager, + activation_token, + data->surface); + + /* Clear this variable, per the protocol's request */ + unsetenv("XDG_ACTIVATION_TOKEN"); + } + } + + /* + * Roundtrip required to avoid a possible protocol violation when + * HideWindow was called immediately before ShowWindow. + */ + WAYLAND_wl_display_roundtrip(c->display); +} + +static void Wayland_ReleasePopup(_THIS, SDL_Window *popup) +{ + SDL_WindowData *popupdata; + + /* Basic sanity checks to weed out the weird popup closures */ + if (!popup || popup->magic != &_this->window_magic) { + return; + } + popupdata = popup->driverdata; + if (!popupdata) { + return; + } + + /* This may already be freed by a parent popup! */ + if (popupdata->shell_surface.xdg.roleobj.popup.popup == NULL) { + return; + } + + /* Release the child _first_, otherwise a protocol error triggers */ + if (popupdata->shell_surface.xdg.roleobj.popup.child != NULL) { + Wayland_ReleasePopup(_this, popupdata->shell_surface.xdg.roleobj.popup.child); + popupdata->shell_surface.xdg.roleobj.popup.child = NULL; + } + + if (popup->flags & SDL_WINDOW_TOOLTIP) { + if (xdg_popup_get_version(popupdata->shell_surface.xdg.roleobj.popup.popup) >= 3) { + SDL_DelEventWatch(Wayland_PopupWatch, popup); + } + } + xdg_popup_destroy(popupdata->shell_surface.xdg.roleobj.popup.popup); + xdg_positioner_destroy(popupdata->shell_surface.xdg.roleobj.popup.positioner); + popupdata->shell_surface.xdg.roleobj.popup.popup = NULL; + popupdata->shell_surface.xdg.roleobj.popup.positioner = NULL; +} + +void Wayland_HideWindow(_THIS, SDL_Window *window) +{ + SDL_VideoData *data = _this->driverdata; + SDL_WindowData *wind = window->driverdata; + + if (wind->server_decoration) { + zxdg_toplevel_decoration_v1_destroy(wind->server_decoration); + wind->server_decoration = NULL; + } + + /* Be sure to detach after this is done, otherwise ShowWindow crashes! */ + wl_surface_attach(wind->surface, NULL, 0, 0); + wl_surface_commit(wind->surface); + +#ifdef HAVE_LIBDECOR_H + if (wind->shell_surface_type == WAYLAND_SURFACE_LIBDECOR) { + if (wind->shell_surface.libdecor.frame) { + libdecor_frame_unref(wind->shell_surface.libdecor.frame); + wind->shell_surface.libdecor.frame = NULL; + } + } else +#endif + if (data->shell.xdg) { + if (wind->shell_surface_type == WAYLAND_SURFACE_XDG_POPUP) { + Wayland_ReleasePopup(_this, window); + } else if (wind->shell_surface.xdg.roleobj.toplevel) { + xdg_toplevel_destroy(wind->shell_surface.xdg.roleobj.toplevel); + wind->shell_surface.xdg.roleobj.toplevel = NULL; + } + if (wind->shell_surface.xdg.surface) { + xdg_surface_destroy(wind->shell_surface.xdg.surface); + wind->shell_surface.xdg.surface = NULL; + } + } + + /* + * Roundtrip required to avoid a possible protocol violation when + * ShowWindow is called immediately after HideWindow. + */ + WAYLAND_wl_display_roundtrip(data->display); +} + +static void handle_xdg_activation_done(void *data, + struct xdg_activation_token_v1 *xdg_activation_token_v1, + const char *token) +{ + SDL_WindowData *window = data; + if (xdg_activation_token_v1 == window->activation_token) { + xdg_activation_v1_activate(window->waylandData->activation_manager, + token, + window->surface); + xdg_activation_token_v1_destroy(window->activation_token); + window->activation_token = NULL; + } +} + +static const struct xdg_activation_token_v1_listener activation_listener_xdg = { + handle_xdg_activation_done +}; + +/* The xdg-activation protocol considers "activation" to be one of two things: + * + * 1: Raising a window to the top and flashing the titlebar + * 2: Flashing the titlebar while keeping the window where it is + * + * As you might expect from Wayland, the general policy is to go with #2 unless + * the client can prove to the compositor beyond a reasonable doubt that raising + * the window will not be malicuous behavior. + * + * For SDL this means RaiseWindow and FlashWindow both use the same protocol, + * but in different ways: RaiseWindow will provide as _much_ information as + * possible while FlashWindow will provide as _little_ information as possible, + * to nudge the compositor into doing what we want. + * + * This isn't _strictly_ what the protocol says will happen, but this is what + * current implementations are doing (as of writing, YMMV in the far distant + * future). + * + * -flibit + */ +static void Wayland_activate_window(SDL_VideoData *data, SDL_WindowData *wind, + struct wl_surface *surface, + uint32_t serial, struct wl_seat *seat) +{ + if (data->activation_manager) { + if (wind->activation_token) { + /* We're about to overwrite this with a new request */ + xdg_activation_token_v1_destroy(wind->activation_token); + } + + wind->activation_token = xdg_activation_v1_get_activation_token(data->activation_manager); + xdg_activation_token_v1_add_listener(wind->activation_token, + &activation_listener_xdg, + wind); + + /* Note that we are not setting the app_id or serial here. + * + * Hypothetically we could set the app_id from data->classname, but + * that part of the API is for _external_ programs, not ourselves. + * + * -flibit + */ + if (surface) { + xdg_activation_token_v1_set_surface(wind->activation_token, surface); + } + if (seat) { + xdg_activation_token_v1_set_serial(wind->activation_token, serial, seat); + } + xdg_activation_token_v1_commit(wind->activation_token); + } +} + +void Wayland_RaiseWindow(_THIS, SDL_Window *window) +{ + SDL_WindowData *wind = window->driverdata; + + /* FIXME: This Raise event is arbitrary and doesn't come from an event, so + * it's actually very likely that this token will be ignored! Maybe add + * support for passing serials (and the associated seat) so this can have + * a better chance of actually raising the window. + * -flibit + */ + Wayland_activate_window(_this->driverdata, + wind, + wind->surface, + 0, + NULL); +} + +int Wayland_FlashWindow(_THIS, SDL_Window *window, SDL_FlashOperation operation) +{ + Wayland_activate_window(_this->driverdata, + window->driverdata, + NULL, + 0, + NULL); + return 0; +} + +void handle_preferred_scale_changed(void *data, + struct wp_fractional_scale_v1 *wp_fractional_scale_v1, + uint preferred_scale) +{ + SDL_WindowData *window = data; + float old_factor = window->scale_factor; + float new_factor = preferred_scale / 120.; /* 120 is a magic number defined in the spec as a common denominator*/ + + if (!(window->sdlwindow->flags & SDL_WINDOW_ALLOW_HIGHDPI)) { + /* Scale will always be 1, just ignore this */ + return; + } + + if (!FloatEqual(new_factor, old_factor)) { + Wayland_HandleResize(window->sdlwindow, window->sdlwindow->w, window->sdlwindow->h, new_factor); + } +} + +static const struct wp_fractional_scale_v1_listener fractional_scale_listener = { + handle_preferred_scale_changed +}; + +#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH +static void SDLCALL QtExtendedSurface_OnHintChanged(void *userdata, const char *name, + const char *oldValue, const char *newValue) +{ + struct qt_extended_surface *qt_extended_surface = userdata; + int i; + + static struct + { + const char *name; + int32_t value; + } orientations[] = { + { "portrait", QT_EXTENDED_SURFACE_ORIENTATION_PRIMARYORIENTATION }, + { "landscape", QT_EXTENDED_SURFACE_ORIENTATION_LANDSCAPEORIENTATION }, + { "inverted-portrait", QT_EXTENDED_SURFACE_ORIENTATION_INVERTEDPORTRAITORIENTATION }, + { "inverted-landscape", QT_EXTENDED_SURFACE_ORIENTATION_INVERTEDLANDSCAPEORIENTATION } + }; + + if (!name) { + return; + } + + if (SDL_strcmp(name, SDL_HINT_QTWAYLAND_CONTENT_ORIENTATION) == 0) { + int32_t orientation = QT_EXTENDED_SURFACE_ORIENTATION_PRIMARYORIENTATION; + + if (newValue) { + const char *value_attempt = newValue; + + orientation = 0; + while (value_attempt && *value_attempt != 0) { + const char *value_attempt_end = SDL_strchr(value_attempt, ','); + size_t value_attempt_len = (value_attempt_end) ? (value_attempt_end - value_attempt) + : SDL_strlen(value_attempt); + + for (i = 0; i < SDL_arraysize(orientations); i += 1) { + if ((value_attempt_len == SDL_strlen(orientations[i].name)) && + (SDL_strncasecmp(orientations[i].name, value_attempt, value_attempt_len) == 0)) { + orientation |= orientations[i].value; + break; + } + } + + value_attempt = (value_attempt_end) ? (value_attempt_end + 1) : NULL; + } + } + + qt_extended_surface_set_content_orientation(qt_extended_surface, orientation); + } else if (SDL_strcmp(name, SDL_HINT_QTWAYLAND_WINDOW_FLAGS) == 0) { + uint32_t flags = 0; + + if (newValue) { + char *tmp = SDL_strdup(newValue); + char *saveptr = NULL; + + char *flag = SDL_strtokr(tmp, " ", &saveptr); + while (flag) { + if (SDL_strcmp(flag, "OverridesSystemGestures") == 0) { + flags |= QT_EXTENDED_SURFACE_WINDOWFLAG_OVERRIDESSYSTEMGESTURES; + } else if (SDL_strcmp(flag, "StaysOnTop") == 0) { + flags |= QT_EXTENDED_SURFACE_WINDOWFLAG_STAYSONTOP; + } else if (SDL_strcmp(flag, "BypassWindowManager") == 0) { + // See https://github.com/qtproject/qtwayland/commit/fb4267103d + flags |= 4 /* QT_EXTENDED_SURFACE_WINDOWFLAG_BYPASSWINDOWMANAGER */; + } + + flag = SDL_strtokr(NULL, " ", &saveptr); + } + + SDL_free(tmp); + } + + qt_extended_surface_set_window_flags(qt_extended_surface, flags); + } +} + +static void QtExtendedSurface_Subscribe(struct qt_extended_surface *surface, const char *name) +{ + SDL_AddHintCallback(name, QtExtendedSurface_OnHintChanged, surface); +} + +static void QtExtendedSurface_Unsubscribe(struct qt_extended_surface *surface, const char *name) +{ + SDL_DelHintCallback(name, QtExtendedSurface_OnHintChanged, surface); +} +#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ + +void Wayland_SetWindowFullscreen(_THIS, SDL_Window *window, + SDL_VideoDisplay *_display, SDL_bool fullscreen) +{ + SDL_WindowData *wind = (SDL_WindowData *)window->driverdata; + struct wl_output *output = ((SDL_WaylandOutputData *)_display->driverdata)->output; + SDL_VideoData *viddata = (SDL_VideoData *)_this->driverdata; + + /* Called from within a configure event or the window is a popup, drop it. */ + if (wind->in_fullscreen_transition || wind->shell_surface_type == WAYLAND_SURFACE_XDG_POPUP) { + return; + } + + /* Save the last fullscreen flags for future requests by the compositor. */ + if (fullscreen) { + wind->fullscreen_flags = window->flags & FULLSCREEN_MASK; + } + + /* Don't send redundant fullscreen set/unset events. */ + if (wind->is_fullscreen != fullscreen) { + wind->is_fullscreen = fullscreen; + SetFullscreen(window, fullscreen ? output : NULL); + + /* Roundtrip required to receive the updated window dimensions */ + WAYLAND_wl_display_roundtrip(viddata->display); + } else if (wind->is_fullscreen) { + /* + * If the window is already fullscreen, this is likely a request to switch between + * fullscreen and fullscreen desktop, or to change the video mode. Update the + * geometry and trigger a commit. + */ + ConfigureWindowGeometry(window); + CommitLibdecorFrame(window); + + /* Roundtrip required to receive the updated window dimensions */ + WAYLAND_wl_display_roundtrip(viddata->display); + } +} + +void Wayland_RestoreWindow(_THIS, SDL_Window *window) +{ + SDL_WindowData *wind = window->driverdata; + SDL_VideoData *viddata = (SDL_VideoData *)_this->driverdata; + + if (wind->shell_surface_type == WAYLAND_SURFACE_XDG_POPUP) { + return; + } + + /* Set this flag now even if we never actually maximized, eventually + * ShowWindow will take care of it along with the other window state. + */ + window->flags &= ~SDL_WINDOW_MAXIMIZED; + +#ifdef HAVE_LIBDECOR_H + if (wind->shell_surface_type == WAYLAND_SURFACE_LIBDECOR) { + if (!wind->shell_surface.libdecor.frame) { + return; /* Can't do anything yet, wait for ShowWindow */ + } + libdecor_frame_unset_maximized(wind->shell_surface.libdecor.frame); + } else +#endif + /* Note that xdg-shell does NOT provide a way to unset minimize! */ + if (viddata->shell.xdg) { + if (wind->shell_surface.xdg.roleobj.toplevel == NULL) { + return; /* Can't do anything yet, wait for ShowWindow */ + } + xdg_toplevel_unset_maximized(wind->shell_surface.xdg.roleobj.toplevel); + } + + WAYLAND_wl_display_roundtrip(viddata->display); +} + +void Wayland_SetWindowBordered(_THIS, SDL_Window *window, SDL_bool bordered) +{ + SDL_WindowData *wind = window->driverdata; + const SDL_VideoData *viddata = (const SDL_VideoData *)_this->driverdata; + + if (wind->shell_surface_type == WAYLAND_SURFACE_XDG_POPUP) { + return; + } + +#ifdef HAVE_LIBDECOR_H + if (wind->shell_surface_type == WAYLAND_SURFACE_LIBDECOR) { + if (wind->shell_surface.libdecor.frame) { + libdecor_frame_set_visibility(wind->shell_surface.libdecor.frame, bordered); + } + } else +#endif + if ((viddata->decoration_manager) && (wind->server_decoration)) { + const enum zxdg_toplevel_decoration_v1_mode mode = bordered ? ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE : ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE; + zxdg_toplevel_decoration_v1_set_mode(wind->server_decoration, mode); + } +} + +void Wayland_SetWindowResizable(_THIS, SDL_Window *window, SDL_bool resizable) +{ +#ifdef HAVE_LIBDECOR_H + const SDL_WindowData *wind = window->driverdata; + + if (wind->shell_surface_type == WAYLAND_SURFACE_LIBDECOR) { + if (!wind->shell_surface.libdecor.frame) { + return; /* Can't do anything yet, wait for ShowWindow */ + } + if (resizable) { + libdecor_frame_set_capabilities(wind->shell_surface.libdecor.frame, LIBDECOR_ACTION_RESIZE); + } else { + libdecor_frame_unset_capabilities(wind->shell_surface.libdecor.frame, LIBDECOR_ACTION_RESIZE); + } + } else +#endif + { + SetMinMaxDimensions(window, SDL_TRUE); + } +} + +void Wayland_MaximizeWindow(_THIS, SDL_Window *window) +{ + SDL_WindowData *wind = window->driverdata; + SDL_VideoData *viddata = (SDL_VideoData *)_this->driverdata; + + if (wind->shell_surface_type == WAYLAND_SURFACE_XDG_POPUP) { + return; + } + + if (!(window->flags & SDL_WINDOW_RESIZABLE)) { + return; + } + + /* Set this flag now even if we don't actually maximize yet, eventually + * ShowWindow will take care of it along with the other window state. + */ + window->flags |= SDL_WINDOW_MAXIMIZED; + +#ifdef HAVE_LIBDECOR_H + if (wind->shell_surface_type == WAYLAND_SURFACE_LIBDECOR) { + if (!wind->shell_surface.libdecor.frame) { + return; /* Can't do anything yet, wait for ShowWindow */ + } + libdecor_frame_set_maximized(wind->shell_surface.libdecor.frame); + } else +#endif + if (viddata->shell.xdg) { + if (wind->shell_surface.xdg.roleobj.toplevel == NULL) { + return; /* Can't do anything yet, wait for ShowWindow */ + } + xdg_toplevel_set_maximized(wind->shell_surface.xdg.roleobj.toplevel); + } + + WAYLAND_wl_display_roundtrip(viddata->display); +} + +void Wayland_MinimizeWindow(_THIS, SDL_Window *window) +{ + SDL_WindowData *wind = window->driverdata; + SDL_VideoData *viddata = (SDL_VideoData *)_this->driverdata; + + if (wind->shell_surface_type == WAYLAND_SURFACE_XDG_POPUP) { + return; + } + +#ifdef HAVE_LIBDECOR_H + if (wind->shell_surface_type == WAYLAND_SURFACE_LIBDECOR) { + if (!wind->shell_surface.libdecor.frame) { + return; /* Can't do anything yet, wait for ShowWindow */ + } + libdecor_frame_set_minimized(wind->shell_surface.libdecor.frame); + } else +#endif + if (viddata->shell.xdg) { + if (wind->shell_surface.xdg.roleobj.toplevel == NULL) { + return; /* Can't do anything yet, wait for ShowWindow */ + } + xdg_toplevel_set_minimized(wind->shell_surface.xdg.roleobj.toplevel); + } + + WAYLAND_wl_display_flush(viddata->display); +} + +void Wayland_SetWindowMouseRect(_THIS, SDL_Window *window) +{ + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; + + /* This may look suspiciously like SetWindowGrab, despite SetMouseRect not + * implicitly doing a grab. And you're right! Wayland doesn't let us mess + * around with mouse focus whatsoever, so it just happens to be that the + * work that we can do in these two functions ends up being the same. + * + * Just know that this call lets you confine with a rect, SetWindowGrab + * lets you confine without a rect. + */ + if (SDL_RectEmpty(&window->mouse_rect) && !(window->flags & SDL_WINDOW_MOUSE_GRABBED)) { + Wayland_input_unconfine_pointer(data->input, window); + } else { + Wayland_input_confine_pointer(data->input, window); + } +} + +void Wayland_SetWindowMouseGrab(_THIS, SDL_Window *window, SDL_bool grabbed) +{ + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; + + if (grabbed) { + Wayland_input_confine_pointer(data->input, window); + } else if (SDL_RectEmpty(&window->mouse_rect)) { + Wayland_input_unconfine_pointer(data->input, window); + } +} + +void Wayland_SetWindowKeyboardGrab(_THIS, SDL_Window *window, SDL_bool grabbed) +{ + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; + + if (grabbed) { + Wayland_input_grab_keyboard(window, data->input); + } else { + Wayland_input_ungrab_keyboard(window); + } +} + +int Wayland_CreateWindow(_THIS, SDL_Window *window) +{ + SDL_WindowData *data; + SDL_VideoData *c; + + data = SDL_calloc(1, sizeof(*data)); + if (!data) { + return SDL_OutOfMemory(); + } + + c = _this->driverdata; + window->driverdata = data; + + if (!(window->flags & SDL_WINDOW_VULKAN)) { + if (!(window->flags & SDL_WINDOW_OPENGL)) { + SDL_GL_LoadLibrary(NULL); + window->flags |= SDL_WINDOW_OPENGL; + } + } + + if (window->x == SDL_WINDOWPOS_UNDEFINED) { + window->x = 0; + } + if (window->y == SDL_WINDOWPOS_UNDEFINED) { + window->y = 0; + } + + data->waylandData = c; + data->sdlwindow = window; + + data->scale_factor = 1.0f; + + if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) { + int i; + for (i = 0; i < SDL_GetVideoDevice()->num_displays; i++) { + float scale = ((SDL_WaylandOutputData *)SDL_GetVideoDevice()->displays[i].driverdata)->scale_factor; + data->scale_factor = SDL_max(data->scale_factor, scale); + } + } + + data->outputs = NULL; + data->num_outputs = 0; + + data->floating_width = window->windowed.w; + data->floating_height = window->windowed.h; + + data->surface = + wl_compositor_create_surface(c->compositor); + wl_surface_add_listener(data->surface, &surface_listener, data); + + SDL_WAYLAND_register_surface(data->surface); + + /* Must be called before EGL configuration to set the drawable backbuffer size. */ + ConfigureWindowGeometry(window); + + /* Fire a callback when the compositor wants a new frame rendered. + * Right now this only matters for OpenGL; we use this callback to add a + * wait timeout that avoids getting deadlocked by the compositor when the + * window isn't visible. + */ + if (window->flags & SDL_WINDOW_OPENGL) { + data->gles_swap_frame_event_queue = WAYLAND_wl_display_create_queue(data->waylandData->display); + data->gles_swap_frame_surface_wrapper = WAYLAND_wl_proxy_create_wrapper(data->surface); + WAYLAND_wl_proxy_set_queue((struct wl_proxy *)data->gles_swap_frame_surface_wrapper, data->gles_swap_frame_event_queue); + data->gles_swap_frame_callback = wl_surface_frame(data->gles_swap_frame_surface_wrapper); + wl_callback_add_listener(data->gles_swap_frame_callback, &gles_swap_frame_listener, data); + } + + /* Fire a callback when the compositor wants a new frame to set the surface damage region. */ + data->surface_damage_frame_callback = wl_surface_frame(data->surface); + wl_callback_add_listener(data->surface_damage_frame_callback, &surface_damage_frame_listener, data); + +#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH + if (c->surface_extension) { + data->extended_surface = qt_surface_extension_get_extended_surface( + c->surface_extension, data->surface); + + QtExtendedSurface_Subscribe(data->extended_surface, SDL_HINT_QTWAYLAND_CONTENT_ORIENTATION); + QtExtendedSurface_Subscribe(data->extended_surface, SDL_HINT_QTWAYLAND_WINDOW_FLAGS); + } +#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ + + if (window->flags & SDL_WINDOW_OPENGL) { + data->egl_window = WAYLAND_wl_egl_window_create(data->surface, data->drawable_width, data->drawable_height); + +#ifdef SDL_VIDEO_OPENGL_EGL + /* Create the GLES window surface */ + data->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType)data->egl_window); + + if (data->egl_surface == EGL_NO_SURFACE) { + return -1; /* SDL_EGL_CreateSurface should have set error */ + } +#endif + } + +#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH + if (data->extended_surface) { + qt_extended_surface_set_user_data(data->extended_surface, data); + qt_extended_surface_add_listener(data->extended_surface, + &extended_surface_listener, data); + } +#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ + + if (c->relative_mouse_mode) { + Wayland_input_lock_pointer(c->input); + } + + if (c->fractional_scale_manager) { + data->fractional_scale = wp_fractional_scale_manager_v1_get_fractional_scale(c->fractional_scale_manager, data->surface); + wp_fractional_scale_v1_add_listener(data->fractional_scale, + &fractional_scale_listener, data); + } + + /* Moved this call to ShowWindow: wl_surface_commit(data->surface); */ + WAYLAND_wl_display_flush(c->display); + + /* We may need to create an idle inhibitor for this new window */ + Wayland_SuspendScreenSaver(_this); + +#define IS_POPUP(window) \ + (window->flags & (SDL_WINDOW_TOOLTIP | SDL_WINDOW_POPUP_MENU)) +#ifdef HAVE_LIBDECOR_H + if (c->shell.libdecor && !IS_POPUP(window)) { + data->shell_surface_type = WAYLAND_SURFACE_LIBDECOR; + } else +#endif + if (c->shell.xdg) { + if (IS_POPUP(window)) { + data->shell_surface_type = WAYLAND_SURFACE_XDG_POPUP; + } else { + data->shell_surface_type = WAYLAND_SURFACE_XDG_TOPLEVEL; + } + } /* All other cases will be WAYLAND_SURFACE_UNKNOWN */ +#undef IS_POPUP + + return 0; +} + +static void Wayland_HandleResize(SDL_Window *window, int width, int height, float scale) +{ + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + const int old_w = window->w, old_h = window->h; + const int old_drawable_width = data->drawable_width; + const int old_drawable_height = data->drawable_height; + + /* Update the window geometry. */ + window->w = width; + window->h = height; + data->scale_factor = scale; + ConfigureWindowGeometry(window); + + if (data->needs_resize_event || + old_w != width || old_h != height || + old_drawable_width != data->drawable_width || old_drawable_height != data->drawable_height) { + /* We may have already updated window w/h (or only adjusted scale factor), + * so we must override the deduplication logic in the video core */ + window->w = 0; + window->h = 0; + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, width, height); + window->w = width; + window->h = height; + data->needs_resize_event = SDL_FALSE; + } +} + +void Wayland_SetWindowMinimumSize(_THIS, SDL_Window *window) +{ + SetMinMaxDimensions(window, SDL_TRUE); +} + +void Wayland_SetWindowMaximumSize(_THIS, SDL_Window *window) +{ + SetMinMaxDimensions(window, SDL_TRUE); +} + +void Wayland_SetWindowSize(_THIS, SDL_Window *window) +{ + SDL_WindowData *wind = window->driverdata; + +#ifdef HAVE_LIBDECOR_H + /* we must not resize the window while we have a static (non-floating) size */ + if (wind->shell_surface_type == WAYLAND_SURFACE_LIBDECOR) { + if (wind->shell_surface.libdecor.frame && + !libdecor_frame_is_floating(wind->shell_surface.libdecor.frame)) { + /* Commit the resize when we re-enter floating state */ + wind->floating_resize_pending = SDL_TRUE; + return; + } + + OverrideLibdecorLimits(window); + } +#endif + + /* Update the window geometry. */ + ConfigureWindowGeometry(window); + CommitLibdecorFrame(window); + + /* windowed is unconditionally set, so we can trust it here */ + wind->floating_width = window->windowed.w; + wind->floating_height = window->windowed.h; +} + +void Wayland_GetWindowSizeInPixels(_THIS, SDL_Window *window, int *w, int *h) +{ + SDL_WindowData *data; + if (window->driverdata) { + data = (SDL_WindowData *)window->driverdata; + *w = data->drawable_width; + *h = data->drawable_height; + } +} + +void Wayland_SetWindowTitle(_THIS, SDL_Window *window) +{ + SDL_WindowData *wind = window->driverdata; + SDL_VideoData *viddata = _this->driverdata; + const char *title = window->title ? window->title : ""; + + if (wind->shell_surface_type == WAYLAND_SURFACE_XDG_POPUP) { + return; + } + +#ifdef HAVE_LIBDECOR_H + if (wind->shell_surface_type == WAYLAND_SURFACE_LIBDECOR) { + if (!wind->shell_surface.libdecor.frame) { + return; /* Can't do anything yet, wait for ShowWindow */ + } + libdecor_frame_set_title(wind->shell_surface.libdecor.frame, title); + } else +#endif + if (viddata->shell.xdg) { + if (wind->shell_surface.xdg.roleobj.toplevel == NULL) { + return; /* Can't do anything yet, wait for ShowWindow */ + } + xdg_toplevel_set_title(wind->shell_surface.xdg.roleobj.toplevel, title); + } + + WAYLAND_wl_display_flush(viddata->display); +} + +void Wayland_SuspendScreenSaver(_THIS) +{ + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; + +#ifdef SDL_USE_LIBDBUS + if (SDL_DBus_ScreensaverInhibit(_this->suspend_screensaver)) { + return; + } +#endif + + /* The idle_inhibit_unstable_v1 protocol suspends the screensaver + on a per wl_surface basis, but SDL assumes that suspending + the screensaver can be done independently of any window. + + To reconcile these differences, we propagate the idle inhibit + state to each window. If there is no window active, we will + be able to inhibit idle once the first window is created. + */ + if (data->idle_inhibit_manager) { + SDL_Window *window = _this->windows; + while (window) { + SDL_WindowData *win_data = window->driverdata; + + if (_this->suspend_screensaver && !win_data->idle_inhibitor) { + win_data->idle_inhibitor = + zwp_idle_inhibit_manager_v1_create_inhibitor(data->idle_inhibit_manager, + win_data->surface); + } else if (!_this->suspend_screensaver && win_data->idle_inhibitor) { + zwp_idle_inhibitor_v1_destroy(win_data->idle_inhibitor); + win_data->idle_inhibitor = NULL; + } + + window = window->next; + } + } +} + +void Wayland_DestroyWindow(_THIS, SDL_Window *window) +{ + SDL_VideoData *data = _this->driverdata; + SDL_WindowData *wind = window->driverdata; + + if (data) { +#ifdef SDL_VIDEO_OPENGL_EGL + if (wind->egl_surface) { + SDL_EGL_DestroySurface(_this, wind->egl_surface); + } +#endif + if (wind->egl_window) { + WAYLAND_wl_egl_window_destroy(wind->egl_window); + } + + if (wind->idle_inhibitor) { + zwp_idle_inhibitor_v1_destroy(wind->idle_inhibitor); + } + + if (wind->activation_token) { + xdg_activation_token_v1_destroy(wind->activation_token); + } + + if (wind->draw_viewport) { + wp_viewport_destroy(wind->draw_viewport); + } + + if (wind->fractional_scale) { + wp_fractional_scale_v1_destroy(wind->fractional_scale); + } + + SDL_free(wind->outputs); + + if (wind->gles_swap_frame_callback) { + wl_callback_destroy(wind->gles_swap_frame_callback); + WAYLAND_wl_proxy_wrapper_destroy(wind->gles_swap_frame_surface_wrapper); + WAYLAND_wl_event_queue_destroy(wind->gles_swap_frame_event_queue); + } + + if (wind->surface_damage_frame_callback) { + wl_callback_destroy(wind->surface_damage_frame_callback); + } + +#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH + if (wind->extended_surface) { + QtExtendedSurface_Unsubscribe(wind->extended_surface, SDL_HINT_QTWAYLAND_CONTENT_ORIENTATION); + QtExtendedSurface_Unsubscribe(wind->extended_surface, SDL_HINT_QTWAYLAND_WINDOW_FLAGS); + qt_extended_surface_destroy(wind->extended_surface); + } +#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ + wl_surface_destroy(wind->surface); + + SDL_free(wind); + WAYLAND_wl_display_flush(data->display); + } + window->driverdata = NULL; +} + +static void EGLTransparencyChangedCallback(void *userdata, const char *name, const char *oldValue, const char *newValue) +{ + const SDL_bool oldval = SDL_GetStringBoolean(oldValue, SDL_FALSE); + const SDL_bool newval = SDL_GetStringBoolean(newValue, SDL_FALSE); + + if (oldval != newval) { + SDL_Window *window; + SDL_VideoData *viddata = (SDL_VideoData *)userdata; + SDL_VideoDevice *dev = SDL_GetVideoDevice(); + + viddata->egl_transparency_enabled = newval; + + /* Iterate over all windows and update the surface opaque regions */ + for (window = dev->windows; window; window = window->next) { + SDL_WindowData *wind = (SDL_WindowData *)window->driverdata; + + if (!newval) { + struct wl_region *region = wl_compositor_create_region(wind->waylandData->compositor); + wl_region_add(region, 0, 0, wind->window_width, wind->window_height); + wl_surface_set_opaque_region(wind->surface, region); + wl_region_destroy(region); + } else { + wl_surface_set_opaque_region(wind->surface, NULL); + } + } + } +} + +void Wayland_InitWin(SDL_VideoData *data) +{ + data->egl_transparency_enabled = SDL_GetHintBoolean(SDL_HINT_VIDEO_EGL_ALLOW_TRANSPARENCY, SDL_FALSE); + SDL_AddHintCallback(SDL_HINT_VIDEO_EGL_ALLOW_TRANSPARENCY, EGLTransparencyChangedCallback, data); +} + +void Wayland_QuitWin(SDL_VideoData *data) +{ + SDL_DelHintCallback(SDL_HINT_VIDEO_EGL_ALLOW_TRANSPARENCY, EGLTransparencyChangedCallback, data); +} + +#endif /* SDL_VIDEO_DRIVER_WAYLAND */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/wayland/SDL_waylandwindow.h b/SDL2-2.30.5/src/video/wayland/SDL_waylandwindow.h new file mode 100644 index 0000000..36600a4 --- /dev/null +++ b/SDL2-2.30.5/src/video/wayland/SDL_waylandwindow.h @@ -0,0 +1,155 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifndef SDL_waylandwindow_h_ +#define SDL_waylandwindow_h_ + +#include "../SDL_sysvideo.h" +#include "SDL_syswm.h" +#include "../../events/SDL_touch_c.h" + +#include "SDL_waylandvideo.h" + +struct SDL_WaylandInput; + +typedef struct +{ + SDL_Window *sdlwindow; + SDL_VideoData *waylandData; + struct wl_surface *surface; + struct wl_callback *gles_swap_frame_callback; + struct wl_event_queue *gles_swap_frame_event_queue; + struct wl_surface *gles_swap_frame_surface_wrapper; + struct wl_callback *surface_damage_frame_callback; + + union + { +#ifdef HAVE_LIBDECOR_H + struct + { + struct libdecor_frame *frame; + SDL_bool initial_configure_seen; + } libdecor; +#endif + struct + { + struct xdg_surface *surface; + union + { + struct xdg_toplevel *toplevel; + struct + { + struct xdg_popup *popup; + struct xdg_positioner *positioner; + Uint32 parentID; + SDL_Window *child; + } popup; + } roleobj; + SDL_bool initial_configure_seen; + } xdg; + } shell_surface; + enum + { + WAYLAND_SURFACE_UNKNOWN = 0, + WAYLAND_SURFACE_XDG_TOPLEVEL, + WAYLAND_SURFACE_XDG_POPUP, + WAYLAND_SURFACE_LIBDECOR + } shell_surface_type; + + struct wl_egl_window *egl_window; + struct SDL_WaylandInput *keyboard_device; +#ifdef SDL_VIDEO_OPENGL_EGL + EGLSurface egl_surface; +#endif + struct zwp_locked_pointer_v1 *locked_pointer; + struct zwp_confined_pointer_v1 *confined_pointer; + struct zxdg_toplevel_decoration_v1 *server_decoration; + struct zwp_keyboard_shortcuts_inhibitor_v1 *key_inhibitor; + struct zwp_idle_inhibitor_v1 *idle_inhibitor; + struct xdg_activation_token_v1 *activation_token; + struct wp_viewport *draw_viewport; + struct wp_fractional_scale_v1 *fractional_scale; + + /* floating dimensions for restoring from maximized and fullscreen */ + int floating_width, floating_height; + + SDL_atomic_t swap_interval_ready; + +#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH + struct qt_extended_surface *extended_surface; +#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */ + + SDL_WaylandOutputData **outputs; + int num_outputs; + + float scale_factor; + float pointer_scale_x; + float pointer_scale_y; + int drawable_width, drawable_height; + int fs_output_width, fs_output_height; + int window_width, window_height; + int system_min_required_width; + int system_min_required_height; + SDL_bool needs_resize_event; + SDL_bool floating_resize_pending; + SDL_bool was_floating; + SDL_bool is_fullscreen; + SDL_bool in_fullscreen_transition; + Uint32 fullscreen_flags; +} SDL_WindowData; + +extern void Wayland_ShowWindow(_THIS, SDL_Window *window); +extern void Wayland_HideWindow(_THIS, SDL_Window *window); +extern void Wayland_RaiseWindow(_THIS, SDL_Window *window); +extern void Wayland_SetWindowFullscreen(_THIS, SDL_Window *window, + SDL_VideoDisplay *_display, + SDL_bool fullscreen); +extern void Wayland_MaximizeWindow(_THIS, SDL_Window *window); +extern void Wayland_MinimizeWindow(_THIS, SDL_Window *window); +extern void Wayland_SetWindowMouseRect(_THIS, SDL_Window *window); +extern void Wayland_SetWindowMouseGrab(_THIS, SDL_Window *window, SDL_bool grabbed); +extern void Wayland_SetWindowKeyboardGrab(_THIS, SDL_Window *window, SDL_bool grabbed); +extern void Wayland_RestoreWindow(_THIS, SDL_Window *window); +extern void Wayland_SetWindowBordered(_THIS, SDL_Window *window, SDL_bool bordered); +extern void Wayland_SetWindowResizable(_THIS, SDL_Window *window, SDL_bool resizable); +extern int Wayland_CreateWindow(_THIS, SDL_Window *window); +extern void Wayland_SetWindowSize(_THIS, SDL_Window *window); +extern void Wayland_SetWindowMinimumSize(_THIS, SDL_Window *window); +extern void Wayland_SetWindowMaximumSize(_THIS, SDL_Window *window); +extern void Wayland_GetWindowSizeInPixels(_THIS, SDL_Window *window, int *w, int *h); +extern int Wayland_SetWindowModalFor(_THIS, SDL_Window *modal_window, SDL_Window *parent_window); +extern void Wayland_SetWindowTitle(_THIS, SDL_Window *window); +extern void Wayland_DestroyWindow(_THIS, SDL_Window *window); +extern void Wayland_SuspendScreenSaver(_THIS); + +extern SDL_bool +Wayland_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info); +extern int Wayland_SetWindowHitTest(SDL_Window *window, SDL_bool enabled); +extern int Wayland_FlashWindow(_THIS, SDL_Window *window, SDL_FlashOperation operation); + +extern void Wayland_InitWin(SDL_VideoData *data); +extern void Wayland_QuitWin(SDL_VideoData *data); + +#endif /* SDL_waylandwindow_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/windows/SDL_msctf.h b/SDL2-2.30.5/src/video/windows/SDL_msctf.h similarity index 97% rename from SDL2-2.0.12/src/video/windows/SDL_msctf.h rename to SDL2-2.30.5/src/video/windows/SDL_msctf.h index 1397e59..738696f 100644 --- a/SDL2-2.0.12/src/video/windows/SDL_msctf.h +++ b/SDL2-2.30.5/src/video/windows/SDL_msctf.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -24,9 +24,11 @@ #include -#define TF_INVALID_COOKIE (0xffffffff) -#define TF_IPSINK_FLAG_ACTIVE 0x0001 -#define TF_TMAE_UIELEMENTENABLEDONLY 0x00000004 +#define TF_INVALID_COOKIE (0xffffffff) +#define TF_IPSINK_FLAG_ACTIVE 0x0001 +#define TF_TMAE_UIELEMENTENABLEDONLY 0x00000004 + +/* *INDENT-OFF* */ /* clang-format off */ typedef struct ITfThreadMgr ITfThreadMgr; typedef struct ITfDocumentMgr ITfDocumentMgr; @@ -239,4 +241,6 @@ struct ITfSource const struct ITfSourceVtbl *lpVtbl; }; +/* *INDENT-ON* */ /* clang-format on */ + #endif /* SDL_msctf_h_ */ diff --git a/SDL2-2.30.5/src/video/windows/SDL_vkeys.h b/SDL2-2.30.5/src/video/windows/SDL_vkeys.h new file mode 100644 index 0000000..fb4d27d --- /dev/null +++ b/SDL2-2.30.5/src/video/windows/SDL_vkeys.h @@ -0,0 +1,76 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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. +*/ + +#ifndef VK_0 +#define VK_0 '0' +#define VK_1 '1' +#define VK_2 '2' +#define VK_3 '3' +#define VK_4 '4' +#define VK_5 '5' +#define VK_6 '6' +#define VK_7 '7' +#define VK_8 '8' +#define VK_9 '9' +#define VK_A 'A' +#define VK_B 'B' +#define VK_C 'C' +#define VK_D 'D' +#define VK_E 'E' +#define VK_F 'F' +#define VK_G 'G' +#define VK_H 'H' +#define VK_I 'I' +#define VK_J 'J' +#define VK_K 'K' +#define VK_L 'L' +#define VK_M 'M' +#define VK_N 'N' +#define VK_O 'O' +#define VK_P 'P' +#define VK_Q 'Q' +#define VK_R 'R' +#define VK_S 'S' +#define VK_T 'T' +#define VK_U 'U' +#define VK_V 'V' +#define VK_W 'W' +#define VK_X 'X' +#define VK_Y 'Y' +#define VK_Z 'Z' +#endif /* VK_0 */ + +/* These keys haven't been defined, but were experimentally determined */ +#define VK_SEMICOLON 0xBA +#define VK_EQUALS 0xBB +#define VK_COMMA 0xBC +#define VK_MINUS 0xBD +#define VK_PERIOD 0xBE +#define VK_SLASH 0xBF +#define VK_GRAVE 0xC0 +#define VK_LBRACKET 0xDB +#define VK_BACKSLASH 0xDC +#define VK_RBRACKET 0xDD +#define VK_APOSTROPHE 0xDE +#define VK_BACKTICK 0xDF +#define VK_OEM_102 0xE2 + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/windows/SDL_windowsclipboard.c b/SDL2-2.30.5/src/video/windows/SDL_windowsclipboard.c similarity index 67% rename from SDL2-2.0.12/src/video/windows/SDL_windowsclipboard.c rename to SDL2-2.30.5/src/video/windows/SDL_windowsclipboard.c index 1ac477f..24bc5ab 100644 --- a/SDL2-2.0.12/src/video/windows/SDL_windowsclipboard.c +++ b/SDL2-2.30.5/src/video/windows/SDL_windowsclipboard.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,37 +20,34 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_WINDOWS +#if defined(SDL_VIDEO_DRIVER_WINDOWS) && !defined(__XBOXONE__) && !defined(__XBOXSERIES__) #include "SDL_windowsvideo.h" #include "SDL_windowswindow.h" +#include "SDL_timer.h" #include "../../events/SDL_clipboardevents_c.h" - #ifdef UNICODE -#define TEXT_FORMAT CF_UNICODETEXT +#define TEXT_FORMAT CF_UNICODETEXT #else -#define TEXT_FORMAT CF_TEXT +#define TEXT_FORMAT CF_TEXT #endif - /* Get any application owned window handle for clipboard association */ -static HWND -GetWindowHandle(_THIS) +static HWND GetWindowHandle(_THIS) { SDL_Window *window; window = _this->windows; if (window) { - return ((SDL_WindowData *) window->driverdata)->hwnd; + return ((SDL_WindowData *)window->driverdata)->hwnd; } return NULL; } -int -WIN_SetClipboardText(_THIS, const char *text) +int WIN_SetClipboardText(_THIS, const char *text) { - SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; int result = 0; if (OpenClipboard(GetWindowHandle(_this))) { @@ -66,12 +63,12 @@ WIN_SetClipboardText(_THIS, const char *text) /* Find out the size of the data */ for (size = 0, i = 0; tstr[i]; ++i, ++size) { - if (tstr[i] == '\n' && (i == 0 || tstr[i-1] != '\r')) { + if (tstr[i] == '\n' && (i == 0 || tstr[i - 1] != '\r')) { /* We're going to insert a carriage return */ ++size; } } - size = (size+1)*sizeof(*tstr); + size = (size + 1) * sizeof(*tstr); /* Save the data to the clipboard */ hMem = GlobalAlloc(GMEM_MOVEABLE, size); @@ -80,7 +77,7 @@ WIN_SetClipboardText(_THIS, const char *text) if (dst) { /* Copy the text over, adding carriage returns as necessary */ for (i = 0; tstr[i]; ++i) { - if (tstr[i] == '\n' && (i == 0 || tstr[i-1] != '\r')) { + if (tstr[i] == '\n' && (i == 0 || tstr[i - 1] != '\r')) { *dst++ = '\r'; } *dst++ = tstr[i]; @@ -104,26 +101,33 @@ WIN_SetClipboardText(_THIS, const char *text) return result; } -char * -WIN_GetClipboardText(_THIS) +char *WIN_GetClipboardText(_THIS) { - char *text; + char *text = NULL; - text = NULL; - if (IsClipboardFormatAvailable(TEXT_FORMAT) && - OpenClipboard(GetWindowHandle(_this))) { - HANDLE hMem; - LPTSTR tstr; + if (IsClipboardFormatAvailable(TEXT_FORMAT)) { + /* Retry to open the clipboard in case another application has it open */ + const int MAX_ATTEMPTS = 3; + int attempt; - hMem = GetClipboardData(TEXT_FORMAT); - if (hMem) { - tstr = (LPTSTR)GlobalLock(hMem); - text = WIN_StringToUTF8(tstr); - GlobalUnlock(hMem); - } else { - WIN_SetError("Couldn't get clipboard data"); + for (attempt = 0; attempt < MAX_ATTEMPTS; ++attempt) { + if (OpenClipboard(GetWindowHandle(_this))) { + HANDLE hMem; + LPTSTR tstr; + + hMem = GetClipboardData(TEXT_FORMAT); + if (hMem) { + tstr = (LPTSTR)GlobalLock(hMem); + text = WIN_StringToUTF8(tstr); + GlobalUnlock(hMem); + } else { + WIN_SetError("Couldn't get clipboard data"); + } + CloseClipboard(); + break; + } + SDL_Delay(10); } - CloseClipboard(); } if (!text) { text = SDL_strdup(""); @@ -131,8 +135,7 @@ WIN_GetClipboardText(_THIS) return text; } -SDL_bool -WIN_HasClipboardText(_THIS) +SDL_bool WIN_HasClipboardText(_THIS) { SDL_bool result = SDL_FALSE; char *text = WIN_GetClipboardText(_this); @@ -143,8 +146,7 @@ WIN_HasClipboardText(_THIS) return result; } -void -WIN_CheckClipboardUpdate(struct SDL_VideoData * data) +void WIN_CheckClipboardUpdate(struct SDL_VideoData *data) { const DWORD count = GetClipboardSequenceNumber(); if (count != data->clipboard_count) { diff --git a/SDL2-2.0.12/src/video/windows/SDL_windowsclipboard.h b/SDL2-2.30.5/src/video/windows/SDL_windowsclipboard.h similarity index 90% rename from SDL2-2.0.12/src/video/windows/SDL_windowsclipboard.h rename to SDL2-2.30.5/src/video/windows/SDL_windowsclipboard.h index 18642da..3db9bb9 100644 --- a/SDL2-2.0.12/src/video/windows/SDL_windowsclipboard.h +++ b/SDL2-2.30.5/src/video/windows/SDL_windowsclipboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -29,7 +29,7 @@ struct SDL_VideoData; extern int WIN_SetClipboardText(_THIS, const char *text); extern char *WIN_GetClipboardText(_THIS); extern SDL_bool WIN_HasClipboardText(_THIS); -extern void WIN_CheckClipboardUpdate(struct SDL_VideoData * data); +extern void WIN_CheckClipboardUpdate(struct SDL_VideoData *data); #endif /* SDL_windowsclipboard_h_ */ diff --git a/SDL2-2.30.5/src/video/windows/SDL_windowsevents.c b/SDL2-2.30.5/src/video/windows/SDL_windowsevents.c new file mode 100644 index 0000000..35bae25 --- /dev/null +++ b/SDL2-2.30.5/src/video/windows/SDL_windowsevents.c @@ -0,0 +1,2118 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_WINDOWS + +#include "SDL_windowsvideo.h" +#include "SDL_windowsshape.h" +#include "SDL_system.h" +#include "SDL_syswm.h" +#include "SDL_timer.h" +#include "SDL_vkeys.h" +#include "SDL_hints.h" +#include "SDL_main.h" +#include "../../events/SDL_events_c.h" +#include "../../events/SDL_touch_c.h" +#include "../../events/scancodes_windows.h" +#include "SDL_hints.h" +#include "SDL_log.h" + +/* Dropfile support */ +#include + +/* For GET_X_LPARAM, GET_Y_LPARAM. */ +#include + +/* For WM_TABLET_QUERYSYSTEMGESTURESTATUS et. al. */ +#ifdef HAVE_TPCSHRD_H +#include +#endif /* HAVE_TPCSHRD_H */ + +/* #define WMMSG_DEBUG */ +#ifdef WMMSG_DEBUG +#include +#include "wmmsg.h" +#endif + +#ifdef __GDK__ +#include "../../core/gdk/SDL_gdk.h" +#endif + +/* #define HIGHDPI_DEBUG */ + +/* Masks for processing the windows KEYDOWN and KEYUP messages */ +#define REPEATED_KEYMASK (1 << 30) +#define EXTENDED_KEYMASK (1 << 24) + +#define VK_ENTER 10 /* Keypad Enter ... no VKEY defined? */ +#ifndef VK_OEM_NEC_EQUAL +#define VK_OEM_NEC_EQUAL 0x92 +#endif + +/* Make sure XBUTTON stuff is defined that isn't in older Platform SDKs... */ +#ifndef WM_XBUTTONDOWN +#define WM_XBUTTONDOWN 0x020B +#endif +#ifndef WM_XBUTTONUP +#define WM_XBUTTONUP 0x020C +#endif +#ifndef GET_XBUTTON_WPARAM +#define GET_XBUTTON_WPARAM(w) (HIWORD(w)) +#endif +#ifndef WM_INPUT +#define WM_INPUT 0x00ff +#endif +#ifndef WM_TOUCH +#define WM_TOUCH 0x0240 +#endif +#ifndef WM_MOUSEHWHEEL +#define WM_MOUSEHWHEEL 0x020E +#endif +#ifndef WM_POINTERUPDATE +#define WM_POINTERUPDATE 0x0245 +#endif +#ifndef WM_UNICHAR +#define WM_UNICHAR 0x0109 +#endif +#ifndef WM_DPICHANGED +#define WM_DPICHANGED 0x02E0 +#endif +#ifndef WM_GETDPISCALEDSIZE +#define WM_GETDPISCALEDSIZE 0x02E4 +#endif +#ifndef TOUCHEVENTF_PEN +#define TOUCHEVENTF_PEN 0x0040 +#endif + +#ifndef IS_HIGH_SURROGATE +#define IS_HIGH_SURROGATE(x) (((x) >= 0xd800) && ((x) <= 0xdbff)) +#endif +#ifndef IS_LOW_SURROGATE +#define IS_LOW_SURROGATE(x) (((x) >= 0xdc00) && ((x) <= 0xdfff)) +#endif +#ifndef IS_SURROGATE_PAIR +#define IS_SURROGATE_PAIR(h, l) (IS_HIGH_SURROGATE(h) && IS_LOW_SURROGATE(l)) +#endif + +#ifndef USER_TIMER_MINIMUM +#define USER_TIMER_MINIMUM 0x0000000A +#endif + +static SDL_Scancode VKeytoScancodeFallback(WPARAM vkey) +{ + switch (vkey) { + case VK_LEFT: + return SDL_SCANCODE_LEFT; + case VK_UP: + return SDL_SCANCODE_UP; + case VK_RIGHT: + return SDL_SCANCODE_RIGHT; + case VK_DOWN: + return SDL_SCANCODE_DOWN; + case VK_CONTROL: + return SDL_SCANCODE_LCTRL; + case VK_V: + return SDL_SCANCODE_V; + + default: + return SDL_SCANCODE_UNKNOWN; + } +} + +static SDL_Scancode VKeytoScancode(WPARAM vkey) +{ + switch (vkey) { + case VK_BACK: + return SDL_SCANCODE_BACKSPACE; + case VK_CAPITAL: + return SDL_SCANCODE_CAPSLOCK; + + case VK_MODECHANGE: + return SDL_SCANCODE_MODE; + case VK_SELECT: + return SDL_SCANCODE_SELECT; + case VK_EXECUTE: + return SDL_SCANCODE_EXECUTE; + case VK_HELP: + return SDL_SCANCODE_HELP; + case VK_PAUSE: + return SDL_SCANCODE_PAUSE; + case VK_NUMLOCK: + return SDL_SCANCODE_NUMLOCKCLEAR; + + case VK_F13: + return SDL_SCANCODE_F13; + case VK_F14: + return SDL_SCANCODE_F14; + case VK_F15: + return SDL_SCANCODE_F15; + case VK_F16: + return SDL_SCANCODE_F16; + case VK_F17: + return SDL_SCANCODE_F17; + case VK_F18: + return SDL_SCANCODE_F18; + case VK_F19: + return SDL_SCANCODE_F19; + case VK_F20: + return SDL_SCANCODE_F20; + case VK_F21: + return SDL_SCANCODE_F21; + case VK_F22: + return SDL_SCANCODE_F22; + case VK_F23: + return SDL_SCANCODE_F23; + case VK_F24: + return SDL_SCANCODE_F24; + + case VK_OEM_NEC_EQUAL: + return SDL_SCANCODE_KP_EQUALS; + case VK_BROWSER_BACK: + return SDL_SCANCODE_AC_BACK; + case VK_BROWSER_FORWARD: + return SDL_SCANCODE_AC_FORWARD; + case VK_BROWSER_REFRESH: + return SDL_SCANCODE_AC_REFRESH; + case VK_BROWSER_STOP: + return SDL_SCANCODE_AC_STOP; + case VK_BROWSER_SEARCH: + return SDL_SCANCODE_AC_SEARCH; + case VK_BROWSER_FAVORITES: + return SDL_SCANCODE_AC_BOOKMARKS; + case VK_BROWSER_HOME: + return SDL_SCANCODE_AC_HOME; + case VK_VOLUME_MUTE: + return SDL_SCANCODE_MUTE; + case VK_VOLUME_DOWN: + return SDL_SCANCODE_VOLUMEDOWN; + case VK_VOLUME_UP: + return SDL_SCANCODE_VOLUMEUP; + + case VK_MEDIA_NEXT_TRACK: + return SDL_SCANCODE_AUDIONEXT; + case VK_MEDIA_PREV_TRACK: + return SDL_SCANCODE_AUDIOPREV; + case VK_MEDIA_STOP: + return SDL_SCANCODE_AUDIOSTOP; + case VK_MEDIA_PLAY_PAUSE: + return SDL_SCANCODE_AUDIOPLAY; + case VK_LAUNCH_MAIL: + return SDL_SCANCODE_MAIL; + case VK_LAUNCH_MEDIA_SELECT: + return SDL_SCANCODE_MEDIASELECT; + + case VK_OEM_102: + return SDL_SCANCODE_NONUSBACKSLASH; + + case VK_ATTN: + return SDL_SCANCODE_SYSREQ; + case VK_CRSEL: + return SDL_SCANCODE_CRSEL; + case VK_EXSEL: + return SDL_SCANCODE_EXSEL; + case VK_OEM_CLEAR: + return SDL_SCANCODE_CLEAR; + + case VK_LAUNCH_APP1: + return SDL_SCANCODE_APP1; + case VK_LAUNCH_APP2: + return SDL_SCANCODE_APP2; + + default: + return SDL_SCANCODE_UNKNOWN; + } +} + +static SDL_Scancode WindowsScanCodeToSDLScanCode(LPARAM lParam, WPARAM wParam) +{ + SDL_Scancode code; + int nScanCode = (lParam >> 16) & 0xFF; + SDL_bool bIsExtended = (lParam & (1 << 24)) != 0; + + code = VKeytoScancode(wParam); + + if (code == SDL_SCANCODE_UNKNOWN && nScanCode <= 127) { + code = windows_scancode_table[nScanCode]; + + if (bIsExtended) { + switch (code) { + case SDL_SCANCODE_RETURN: + code = SDL_SCANCODE_KP_ENTER; + break; + case SDL_SCANCODE_LALT: + code = SDL_SCANCODE_RALT; + break; + case SDL_SCANCODE_LCTRL: + code = SDL_SCANCODE_RCTRL; + break; + case SDL_SCANCODE_SLASH: + code = SDL_SCANCODE_KP_DIVIDE; + break; + case SDL_SCANCODE_CAPSLOCK: + code = SDL_SCANCODE_KP_PLUS; + break; + default: + break; + } + } else { + switch (code) { + case SDL_SCANCODE_HOME: + code = SDL_SCANCODE_KP_7; + break; + case SDL_SCANCODE_UP: + code = SDL_SCANCODE_KP_8; + break; + case SDL_SCANCODE_PAGEUP: + code = SDL_SCANCODE_KP_9; + break; + case SDL_SCANCODE_LEFT: + code = SDL_SCANCODE_KP_4; + break; + case SDL_SCANCODE_RIGHT: + code = SDL_SCANCODE_KP_6; + break; + case SDL_SCANCODE_END: + code = SDL_SCANCODE_KP_1; + break; + case SDL_SCANCODE_DOWN: + code = SDL_SCANCODE_KP_2; + break; + case SDL_SCANCODE_PAGEDOWN: + code = SDL_SCANCODE_KP_3; + break; + case SDL_SCANCODE_INSERT: + code = SDL_SCANCODE_KP_0; + break; + case SDL_SCANCODE_DELETE: + code = SDL_SCANCODE_KP_PERIOD; + break; + case SDL_SCANCODE_PRINTSCREEN: + code = SDL_SCANCODE_KP_MULTIPLY; + break; + default: + break; + } + } + } + + /* The on-screen keyboard can generate VK_LEFT and VK_RIGHT events without a scancode + * value set, however we cannot simply map these in VKeytoScancode() or we will be + * incorrectly handling the arrow keys on the number pad when NumLock is disabled + * (which also generate VK_LEFT, VK_RIGHT, etc in that scenario). Instead, we'll only + * map them if none of the above special number pad mappings applied. */ + if (code == SDL_SCANCODE_UNKNOWN) { + code = VKeytoScancodeFallback(wParam); + } + + return code; +} + +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) +static SDL_bool WIN_ShouldIgnoreFocusClick() +{ + return !SDL_GetHintBoolean(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, SDL_FALSE); +} + +static void WIN_CheckWParamMouseButton(SDL_bool bwParamMousePressed, Uint32 mouseFlags, SDL_bool bSwapButtons, SDL_WindowData *data, Uint8 button, SDL_MouseID mouseID) +{ + if (bSwapButtons) { + if (button == SDL_BUTTON_LEFT) { + button = SDL_BUTTON_RIGHT; + } else if (button == SDL_BUTTON_RIGHT) { + button = SDL_BUTTON_LEFT; + } + } + + if (data->focus_click_pending & SDL_BUTTON(button)) { + /* Ignore the button click for activation */ + if (!bwParamMousePressed) { + data->focus_click_pending &= ~SDL_BUTTON(button); + WIN_UpdateClipCursor(data->window); + } + if (WIN_ShouldIgnoreFocusClick()) { + return; + } + } + + if (bwParamMousePressed && !(mouseFlags & SDL_BUTTON(button))) { + SDL_SendMouseButton(data->window, mouseID, SDL_PRESSED, button); + } else if (!bwParamMousePressed && (mouseFlags & SDL_BUTTON(button))) { + SDL_SendMouseButton(data->window, mouseID, SDL_RELEASED, button); + } +} + +/* + * Some windows systems fail to send a WM_LBUTTONDOWN sometimes, but each mouse move contains the current button state also + * so this function reconciles our view of the world with the current buttons reported by windows + */ +static void WIN_CheckWParamMouseButtons(WPARAM wParam, SDL_WindowData *data, SDL_MouseID mouseID) +{ + if (wParam != data->mouse_button_flags) { + Uint32 mouseFlags = SDL_GetMouseState(NULL, NULL); + + /* WM_LBUTTONDOWN and friends handle button swapping for us. No need to check SM_SWAPBUTTON here. */ + WIN_CheckWParamMouseButton((wParam & MK_LBUTTON), mouseFlags, SDL_FALSE, data, SDL_BUTTON_LEFT, mouseID); + WIN_CheckWParamMouseButton((wParam & MK_MBUTTON), mouseFlags, SDL_FALSE, data, SDL_BUTTON_MIDDLE, mouseID); + WIN_CheckWParamMouseButton((wParam & MK_RBUTTON), mouseFlags, SDL_FALSE, data, SDL_BUTTON_RIGHT, mouseID); + WIN_CheckWParamMouseButton((wParam & MK_XBUTTON1), mouseFlags, SDL_FALSE, data, SDL_BUTTON_X1, mouseID); + WIN_CheckWParamMouseButton((wParam & MK_XBUTTON2), mouseFlags, SDL_FALSE, data, SDL_BUTTON_X2, mouseID); + + data->mouse_button_flags = wParam; + } +} + +static void WIN_CheckRawMouseButtons(HANDLE hDevice, ULONG rawButtons, SDL_WindowData *data, SDL_MouseID mouseID) +{ + // Add a flag to distinguish raw mouse buttons from wParam above + rawButtons |= 0x8000000; + + if (rawButtons != data->mouse_button_flags) { + Uint32 mouseFlags = SDL_GetMouseState(NULL, NULL); + SDL_bool swapButtons = GetSystemMetrics(SM_SWAPBUTTON) != 0; + if (swapButtons && hDevice == NULL) { + /* Touchpad, already has buttons swapped */ + swapButtons = SDL_FALSE; + } + if (rawButtons & RI_MOUSE_BUTTON_1_DOWN) { + WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_1_DOWN), mouseFlags, swapButtons, data, SDL_BUTTON_LEFT, mouseID); + } + if (rawButtons & RI_MOUSE_BUTTON_1_UP) { + WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_1_UP), mouseFlags, swapButtons, data, SDL_BUTTON_LEFT, mouseID); + } + if (rawButtons & RI_MOUSE_BUTTON_2_DOWN) { + WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_2_DOWN), mouseFlags, swapButtons, data, SDL_BUTTON_RIGHT, mouseID); + } + if (rawButtons & RI_MOUSE_BUTTON_2_UP) { + WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_2_UP), mouseFlags, swapButtons, data, SDL_BUTTON_RIGHT, mouseID); + } + if (rawButtons & RI_MOUSE_BUTTON_3_DOWN) { + WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_3_DOWN), mouseFlags, swapButtons, data, SDL_BUTTON_MIDDLE, mouseID); + } + if (rawButtons & RI_MOUSE_BUTTON_3_UP) { + WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_3_UP), mouseFlags, swapButtons, data, SDL_BUTTON_MIDDLE, mouseID); + } + if (rawButtons & RI_MOUSE_BUTTON_4_DOWN) { + WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_4_DOWN), mouseFlags, swapButtons, data, SDL_BUTTON_X1, mouseID); + } + if (rawButtons & RI_MOUSE_BUTTON_4_UP) { + WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_4_UP), mouseFlags, swapButtons, data, SDL_BUTTON_X1, mouseID); + } + if (rawButtons & RI_MOUSE_BUTTON_5_DOWN) { + WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_5_DOWN), mouseFlags, swapButtons, data, SDL_BUTTON_X2, mouseID); + } + if (rawButtons & RI_MOUSE_BUTTON_5_UP) { + WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_5_UP), mouseFlags, swapButtons, data, SDL_BUTTON_X2, mouseID); + } + data->mouse_button_flags = rawButtons; + } +} + +static void WIN_CheckAsyncMouseRelease(SDL_WindowData *data) +{ + Uint32 mouseFlags; + SHORT keyState; + SDL_bool swapButtons; + + /* mouse buttons may have changed state here, we need to resync them, + but we will get a WM_MOUSEMOVE right away which will fix things up if in non raw mode also + */ + mouseFlags = SDL_GetMouseState(NULL, NULL); + swapButtons = GetSystemMetrics(SM_SWAPBUTTON) != 0; + + keyState = GetAsyncKeyState(VK_LBUTTON); + if (!(keyState & 0x8000)) { + WIN_CheckWParamMouseButton(SDL_FALSE, mouseFlags, swapButtons, data, SDL_BUTTON_LEFT, 0); + } + keyState = GetAsyncKeyState(VK_RBUTTON); + if (!(keyState & 0x8000)) { + WIN_CheckWParamMouseButton(SDL_FALSE, mouseFlags, swapButtons, data, SDL_BUTTON_RIGHT, 0); + } + keyState = GetAsyncKeyState(VK_MBUTTON); + if (!(keyState & 0x8000)) { + WIN_CheckWParamMouseButton(SDL_FALSE, mouseFlags, swapButtons, data, SDL_BUTTON_MIDDLE, 0); + } + keyState = GetAsyncKeyState(VK_XBUTTON1); + if (!(keyState & 0x8000)) { + WIN_CheckWParamMouseButton(SDL_FALSE, mouseFlags, swapButtons, data, SDL_BUTTON_X1, 0); + } + keyState = GetAsyncKeyState(VK_XBUTTON2); + if (!(keyState & 0x8000)) { + WIN_CheckWParamMouseButton(SDL_FALSE, mouseFlags, swapButtons, data, SDL_BUTTON_X2, 0); + } + data->mouse_button_flags = (WPARAM)-1; +} + +static void WIN_UpdateFocus(SDL_Window *window, SDL_bool expect_focus) +{ + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + HWND hwnd = data->hwnd; + SDL_bool had_focus = (SDL_GetKeyboardFocus() == window) ? SDL_TRUE : SDL_FALSE; + SDL_bool has_focus = (GetForegroundWindow() == hwnd) ? SDL_TRUE : SDL_FALSE; + + if (had_focus == has_focus || has_focus != expect_focus) { + return; + } + + if (has_focus) { + POINT cursorPos; + + SDL_bool swapButtons = GetSystemMetrics(SM_SWAPBUTTON) != 0; + if (GetAsyncKeyState(VK_LBUTTON)) { + data->focus_click_pending |= !swapButtons ? SDL_BUTTON_LMASK : SDL_BUTTON_RMASK; + } + if (GetAsyncKeyState(VK_RBUTTON)) { + data->focus_click_pending |= !swapButtons ? SDL_BUTTON_RMASK : SDL_BUTTON_LMASK; + } + if (GetAsyncKeyState(VK_MBUTTON)) { + data->focus_click_pending |= SDL_BUTTON_MMASK; + } + if (GetAsyncKeyState(VK_XBUTTON1)) { + data->focus_click_pending |= SDL_BUTTON_X1MASK; + } + if (GetAsyncKeyState(VK_XBUTTON2)) { + data->focus_click_pending |= SDL_BUTTON_X2MASK; + } + + SDL_SetKeyboardFocus(window); + + /* In relative mode we are guaranteed to have mouse focus if we have keyboard focus */ + if (!SDL_GetMouse()->relative_mode) { + SDL_Point point; + GetCursorPos(&cursorPos); + ScreenToClient(hwnd, &cursorPos); + point.x = cursorPos.x; + point.y = cursorPos.y; + WIN_ClientPointToSDL(data->window, &point.x, &point.y); + SDL_SendMouseMotion(window, 0, 0, point.x, point.y); + } + + WIN_CheckAsyncMouseRelease(data); + WIN_UpdateClipCursor(window); + + /* + * FIXME: Update keyboard state + */ + WIN_CheckClipboardUpdate(data->videodata); + + SDL_ToggleModState(KMOD_CAPS, (GetKeyState(VK_CAPITAL) & 0x0001) ? SDL_TRUE : SDL_FALSE); + SDL_ToggleModState(KMOD_NUM, (GetKeyState(VK_NUMLOCK) & 0x0001) ? SDL_TRUE : SDL_FALSE); + SDL_ToggleModState(KMOD_SCROLL, (GetKeyState(VK_SCROLL) & 0x0001) ? SDL_TRUE : SDL_FALSE); + + WIN_UpdateWindowICCProfile(data->window, SDL_TRUE); + } else { + RECT rect; + + data->in_window_deactivation = SDL_TRUE; + + SDL_SetKeyboardFocus(NULL); + /* In relative mode we are guaranteed to not have mouse focus if we don't have keyboard focus */ + if (SDL_GetMouse()->relative_mode) { + SDL_SetMouseFocus(NULL); + } + WIN_ResetDeadKeys(); + + if (GetClipCursor(&rect) && SDL_memcmp(&rect, &data->cursor_clipped_rect, sizeof(rect)) == 0) { + ClipCursor(NULL); + SDL_zero(data->cursor_clipped_rect); + } + + data->in_window_deactivation = SDL_FALSE; + } +} +#endif /*!defined(__XBOXONE__) && !defined(__XBOXSERIES__)*/ + +static BOOL WIN_ConvertUTF32toUTF8(UINT32 codepoint, char *text) +{ + if (codepoint <= 0x7F) { + text[0] = (char)codepoint; + text[1] = '\0'; + } else if (codepoint <= 0x7FF) { + text[0] = 0xC0 | (char)((codepoint >> 6) & 0x1F); + text[1] = 0x80 | (char)(codepoint & 0x3F); + text[2] = '\0'; + } else if (codepoint <= 0xFFFF) { + text[0] = 0xE0 | (char)((codepoint >> 12) & 0x0F); + text[1] = 0x80 | (char)((codepoint >> 6) & 0x3F); + text[2] = 0x80 | (char)(codepoint & 0x3F); + text[3] = '\0'; + } else if (codepoint <= 0x10FFFF) { + text[0] = 0xF0 | (char)((codepoint >> 18) & 0x0F); + text[1] = 0x80 | (char)((codepoint >> 12) & 0x3F); + text[2] = 0x80 | (char)((codepoint >> 6) & 0x3F); + text[3] = 0x80 | (char)(codepoint & 0x3F); + text[4] = '\0'; + } else { + return SDL_FALSE; + } + return SDL_TRUE; +} + +static BOOL WIN_ConvertUTF16toUTF8(UINT32 high_surrogate, UINT32 low_surrogate, char *text) +{ + const UINT32 SURROGATE_OFFSET = 0x10000 - (0xD800 << 10) - 0xDC00; + const UINT32 codepoint = (high_surrogate << 10) + low_surrogate + SURROGATE_OFFSET; + return WIN_ConvertUTF32toUTF8(codepoint, text); +} + +static SDL_bool ShouldGenerateWindowCloseOnAltF4(void) +{ + return !SDL_GetHintBoolean(SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4, SDL_FALSE); +} + +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) +/* We want to generate mouse events from mouse and pen, and touch events from touchscreens */ +#define MI_WP_SIGNATURE 0xFF515700 +#define MI_WP_SIGNATURE_MASK 0xFFFFFF00 +#define IsTouchEvent(dw) ((dw)&MI_WP_SIGNATURE_MASK) == MI_WP_SIGNATURE + +typedef enum +{ + SDL_MOUSE_EVENT_SOURCE_UNKNOWN, + SDL_MOUSE_EVENT_SOURCE_MOUSE, + SDL_MOUSE_EVENT_SOURCE_TOUCH, + SDL_MOUSE_EVENT_SOURCE_PEN, +} SDL_MOUSE_EVENT_SOURCE; + +static SDL_MOUSE_EVENT_SOURCE GetMouseMessageSource(void) +{ + LPARAM extrainfo = GetMessageExtraInfo(); + /* Mouse data (ignoring synthetic mouse events generated for touchscreens) */ + /* Versions below Vista will set the low 7 bits to the Mouse ID and don't use bit 7: + Check bits 8-32 for the signature (which will indicate a Tablet PC Pen or Touch Device). + Only check bit 7 when Vista and up(Cleared=Pen, Set=Touch(which we need to filter out)), + when the signature is set. The Mouse ID will be zero for an actual mouse. */ + if (IsTouchEvent(extrainfo)) { + if (extrainfo & 0x80) { + return SDL_MOUSE_EVENT_SOURCE_TOUCH; + } else { + return SDL_MOUSE_EVENT_SOURCE_PEN; + } + } + return SDL_MOUSE_EVENT_SOURCE_MOUSE; +} +#endif /*!defined(__XBOXONE__) && !defined(__XBOXSERIES__)*/ + +static SDL_WindowData *WIN_GetWindowDataFromHWND(HWND hwnd) +{ + SDL_VideoDevice *_this = SDL_GetVideoDevice(); + SDL_Window *window; + + if (_this) { + for (window = _this->windows; window; window = window->next) { + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + if (data && data->hwnd == hwnd) { + return data; + } + } + } + return NULL; +} + +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) +LRESULT CALLBACK +WIN_KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam) +{ + KBDLLHOOKSTRUCT *hookData = (KBDLLHOOKSTRUCT *)lParam; + SDL_VideoData *data = SDL_GetVideoDevice()->driverdata; + SDL_Scancode scanCode; + + if (nCode < 0 || nCode != HC_ACTION) { + return CallNextHookEx(NULL, nCode, wParam, lParam); + } + if (hookData->scanCode == 0x21d) { + // Skip fake LCtrl when RAlt is pressed + return 1; + } + + switch (hookData->vkCode) { + case VK_LWIN: + scanCode = SDL_SCANCODE_LGUI; + break; + case VK_RWIN: + scanCode = SDL_SCANCODE_RGUI; + break; + case VK_LMENU: + scanCode = SDL_SCANCODE_LALT; + break; + case VK_RMENU: + scanCode = SDL_SCANCODE_RALT; + break; + case VK_LCONTROL: + scanCode = SDL_SCANCODE_LCTRL; + break; + case VK_RCONTROL: + scanCode = SDL_SCANCODE_RCTRL; + break; + + /* These are required to intercept Alt+Tab and Alt+Esc on Windows 7 */ + case VK_TAB: + scanCode = SDL_SCANCODE_TAB; + break; + case VK_ESCAPE: + scanCode = SDL_SCANCODE_ESCAPE; + break; + + default: + return CallNextHookEx(NULL, nCode, wParam, lParam); + } + + if (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) { + SDL_SendKeyboardKey(SDL_PRESSED, scanCode); + } else { + SDL_SendKeyboardKey(SDL_RELEASED, scanCode); + + /* If the key was down prior to our hook being installed, allow the + key up message to pass normally the first time. This ensures other + windows have a consistent view of the key state, and avoids keys + being stuck down in those windows if they are down when the grab + happens and raised while grabbed. */ + if (hookData->vkCode <= 0xFF && data->pre_hook_key_state[hookData->vkCode]) { + data->pre_hook_key_state[hookData->vkCode] = 0; + return CallNextHookEx(NULL, nCode, wParam, lParam); + } + } + + return 1; +} + +#endif /*!defined(__XBOXONE__) && !defined(__XBOXSERIES__)*/ + + +// Return 1 if spruious LCtrl is pressed +// LCtrl is sent when RAltGR is pressed +int skip_bad_lcrtl(WPARAM wParam, LPARAM lParam) +{ + MSG next_msg; + DWORD msg_time; + if (wParam != VK_CONTROL) { + return 0; + } + // Is this an extended key (i.e. right key)? + if (lParam & 0x01000000) + return 0; + + // Here is a trick: "Alt Gr" sends LCTRL, then RALT. We only + // want the RALT message, so we try to see if the next message + // is a RALT message. In that case, this is a false LCTRL! + msg_time = GetMessageTime(); + if (PeekMessage(&next_msg, NULL, 0, 0, PM_NOREMOVE)) { + if (next_msg.message == WM_KEYDOWN || + next_msg.message == WM_SYSKEYDOWN) { + if (next_msg.wParam == VK_MENU && + (next_msg.lParam & 0x01000000) && + next_msg.time == msg_time) { + // Next message is a RALT down message, which + // means that this is NOT a proper LCTRL message! + return 1; + } + } + } + return 0; +} + +LRESULT CALLBACK +WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static SDL_bool s_ModalMoveResizeLoop; + SDL_WindowData *data; + LRESULT returnCode = -1; + + /* Send a SDL_SYSWMEVENT if the application wants them */ + if (SDL_GetEventState(SDL_SYSWMEVENT) == SDL_ENABLE) { + SDL_SysWMmsg wmmsg; + + SDL_VERSION(&wmmsg.version); + wmmsg.subsystem = SDL_SYSWM_WINDOWS; + wmmsg.msg.win.hwnd = hwnd; + wmmsg.msg.win.msg = msg; + wmmsg.msg.win.wParam = wParam; + wmmsg.msg.win.lParam = lParam; + SDL_SendSysWMEvent(&wmmsg); + } + + /* Get the window data for the window */ + data = WIN_GetWindowDataFromHWND(hwnd); +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + if (!data) { + /* Fallback */ + data = (SDL_WindowData *)GetProp(hwnd, TEXT("SDL_WindowData")); + } +#endif + if (!data) { + return CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam); + } + +#ifdef WMMSG_DEBUG + { + char message[1024]; + if (msg > MAX_WMMSG) { + SDL_snprintf(message, sizeof(message), "Received windows message: %p UNKNOWN (%d) -- 0x%p, 0x%p\n", hwnd, msg, wParam, lParam); + } else { + SDL_snprintf(message, sizeof(message), "Received windows message: %p %s -- 0x%p, 0x%p\n", hwnd, wmtab[msg], wParam, lParam); + } + OutputDebugStringA(message); + } +#endif /* WMMSG_DEBUG */ + +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + if (IME_HandleMessage(hwnd, msg, wParam, &lParam, data->videodata)) { + return 0; + } +#endif + + switch (msg) { + + case WM_SHOWWINDOW: + { + if (wParam) { + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_SHOWN, 0, 0); + } else { + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_HIDDEN, 0, 0); + } + } break; + +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + case WM_NCACTIVATE: + { + /* Don't immediately clip the cursor in case we're clicking minimize/maximize buttons */ + data->skip_update_clipcursor = SDL_TRUE; + + /* Update the focus here, since it's possible to get WM_ACTIVATE and WM_SETFOCUS without + actually being the foreground window, but this appears to get called in all cases where + the global foreground window changes to and from this window. */ + WIN_UpdateFocus(data->window, !!wParam); + } break; + + case WM_ACTIVATE: + { + /* Update the focus in case we changed focus to a child window and then away from the application */ + WIN_UpdateFocus(data->window, !!LOWORD(wParam)); + } break; + + case WM_SETFOCUS: + { + /* Update the focus in case it's changing between top-level windows in the same application */ + WIN_UpdateFocus(data->window, SDL_TRUE); + } break; + + case WM_KILLFOCUS: + case WM_ENTERIDLE: + { + /* Update the focus in case it's changing between top-level windows in the same application */ + WIN_UpdateFocus(data->window, SDL_FALSE); + } break; + + case WM_POINTERUPDATE: + { + data->last_pointer_update = lParam; + break; + } + + case WM_MOUSEMOVE: + { + SDL_Mouse *mouse = SDL_GetMouse(); + + if (!data->mouse_tracked) { + TRACKMOUSEEVENT trackMouseEvent; + + trackMouseEvent.cbSize = sizeof(TRACKMOUSEEVENT); + trackMouseEvent.dwFlags = TME_LEAVE; + trackMouseEvent.hwndTrack = data->hwnd; + + if (TrackMouseEvent(&trackMouseEvent)) { + data->mouse_tracked = SDL_TRUE; + } + } + + if (!mouse->relative_mode || mouse->relative_mode_warp) { + /* Only generate mouse events for real mouse */ + if (GetMouseMessageSource() != SDL_MOUSE_EVENT_SOURCE_TOUCH && + lParam != data->last_pointer_update) { + int x = GET_X_LPARAM(lParam); + int y = GET_Y_LPARAM(lParam); + + WIN_ClientPointToSDL(data->window, &x, &y); + + SDL_SendMouseMotion(data->window, 0, 0, x, y); + } + } + } break; + + case WM_LBUTTONUP: + case WM_RBUTTONUP: + case WM_MBUTTONUP: + case WM_XBUTTONUP: + case WM_LBUTTONDOWN: + case WM_LBUTTONDBLCLK: + case WM_RBUTTONDOWN: + case WM_RBUTTONDBLCLK: + case WM_MBUTTONDOWN: + case WM_MBUTTONDBLCLK: + case WM_XBUTTONDOWN: + case WM_XBUTTONDBLCLK: + { + SDL_Mouse *mouse = SDL_GetMouse(); + if (!mouse->relative_mode || mouse->relative_mode_warp) { + if (GetMouseMessageSource() != SDL_MOUSE_EVENT_SOURCE_TOUCH && + lParam != data->last_pointer_update) { + WIN_CheckWParamMouseButtons(wParam, data, 0); + } + } + } break; + + case WM_INPUT: + { + SDL_Mouse *mouse = SDL_GetMouse(); + HRAWINPUT hRawInput = (HRAWINPUT)lParam; + RAWINPUT inp; + UINT size = sizeof(inp); + + /* We only use raw mouse input in relative mode */ + if (!mouse->relative_mode || mouse->relative_mode_warp) { + break; + } + + /* Relative mouse motion is delivered to the window with keyboard focus */ + if (data->window != SDL_GetKeyboardFocus()) { + break; + } + + GetRawInputData(hRawInput, RID_INPUT, &inp, &size, sizeof(RAWINPUTHEADER)); + + /* Mouse data (ignoring synthetic mouse events generated for touchscreens) */ + if (inp.header.dwType == RIM_TYPEMOUSE) { + SDL_MouseID mouseID; + RAWMOUSE *rawmouse; + if (SDL_GetNumTouchDevices() > 0 && + (GetMouseMessageSource() == SDL_MOUSE_EVENT_SOURCE_TOUCH || (GetMessageExtraInfo() & 0x80) == 0x80)) { + break; + } + /* We do all of our mouse state checking against mouse ID 0 + * We would only use the actual hDevice if we were tracking + * all mouse motion independently, and never using mouse ID 0. + */ + mouseID = 0; /* (SDL_MouseID)(uintptr_t)inp.header.hDevice; */ + rawmouse = &inp.data.mouse; + + if ((rawmouse->usFlags & 0x01) == MOUSE_MOVE_RELATIVE) { + SDL_SendMouseMotion(data->window, mouseID, 1, (int)rawmouse->lLastX, (int)rawmouse->lLastY); + } else if (rawmouse->lLastX || rawmouse->lLastY) { + /* This is absolute motion, either using a tablet or mouse over RDP + + Notes on how RDP appears to work, as of Windows 10 2004: + - SetCursorPos() calls are cached, with multiple calls coalesced into a single call that's sent to the RDP client. If the last call to SetCursorPos() has the same value as the last one that was sent to the client, it appears to be ignored and not sent. This means that we need to jitter the SetCursorPos() position slightly in order for the recentering to work correctly. + - User mouse motion is coalesced with SetCursorPos(), so the WM_INPUT positions we see will not necessarily match the positon we requested with SetCursorPos(). + - SetCursorPos() outside of the bounds of the focus window appears not to do anything. + - SetCursorPos() while the cursor is NULL doesn't do anything + + We handle this by creating a safe area within the application window, and when the mouse leaves that safe area, we warp back to the opposite side. Any single motion > 50% of the safe area is assumed to be a warp and ignored. + */ + SDL_bool remote_desktop = GetSystemMetrics(SM_REMOTESESSION) ? SDL_TRUE : SDL_FALSE; + SDL_bool virtual_desktop = (rawmouse->usFlags & MOUSE_VIRTUAL_DESKTOP) ? SDL_TRUE : SDL_FALSE; + SDL_bool normalized_coordinates = !(rawmouse->usFlags & 0x40) ? SDL_TRUE : SDL_FALSE; + int w = GetSystemMetrics(virtual_desktop ? SM_CXVIRTUALSCREEN : SM_CXSCREEN); + int h = GetSystemMetrics(virtual_desktop ? SM_CYVIRTUALSCREEN : SM_CYSCREEN); + int x = normalized_coordinates ? (int)(((float)rawmouse->lLastX / 65535.0f) * w) : (int)rawmouse->lLastX; + int y = normalized_coordinates ? (int)(((float)rawmouse->lLastY / 65535.0f) * h) : (int)rawmouse->lLastY; + int relX, relY; + + /* Calculate relative motion */ + if (data->last_raw_mouse_position.x == 0 && data->last_raw_mouse_position.y == 0) { + data->last_raw_mouse_position.x = x; + data->last_raw_mouse_position.y = y; + } + relX = x - data->last_raw_mouse_position.x; + relY = y - data->last_raw_mouse_position.y; + + if (remote_desktop) { + if (!data->in_title_click && !data->focus_click_pending) { + static int wobble; + float floatX = (float)x / w; + float floatY = (float)y / h; + + /* See if the mouse is at the edge of the screen, or in the RDP title bar area */ + if (floatX <= 0.01f || floatX >= 0.99f || floatY <= 0.01f || floatY >= 0.99f || y < 32) { + /* Wobble the cursor position so it's not ignored if the last warp didn't have any effect */ + RECT rect = data->cursor_clipped_rect; + int warpX = rect.left + ((rect.right - rect.left) / 2) + wobble; + int warpY = rect.top + ((rect.bottom - rect.top) / 2); + + WIN_SetCursorPos(warpX, warpY); + + ++wobble; + if (wobble > 1) { + wobble = -1; + } + } else { + /* Send relative motion if we didn't warp last frame (had good position data) + We also sometimes get large deltas due to coalesced mouse motion and warping, + so ignore those. + */ + const int MAX_RELATIVE_MOTION = (h / 6); + if (SDL_abs(relX) < MAX_RELATIVE_MOTION && + SDL_abs(relY) < MAX_RELATIVE_MOTION) { + SDL_SendMouseMotion(data->window, mouseID, 1, relX, relY); + } + } + } + } else { + const int MAXIMUM_TABLET_RELATIVE_MOTION = 32; + if (SDL_abs(relX) > MAXIMUM_TABLET_RELATIVE_MOTION || + SDL_abs(relY) > MAXIMUM_TABLET_RELATIVE_MOTION) { + /* Ignore this motion, probably a pen lift and drop */ + } else { + SDL_SendMouseMotion(data->window, mouseID, 1, relX, relY); + } + } + + data->last_raw_mouse_position.x = x; + data->last_raw_mouse_position.y = y; + } + WIN_CheckRawMouseButtons(inp.header.hDevice, rawmouse->usButtonFlags, data, mouseID); + } + } break; + + case WM_MOUSEWHEEL: + case WM_MOUSEHWHEEL: + { + short amount = GET_WHEEL_DELTA_WPARAM(wParam); + float fAmount = (float)amount / WHEEL_DELTA; + if (msg == WM_MOUSEWHEEL) { + SDL_SendMouseWheel(data->window, 0, 0.0f, fAmount, SDL_MOUSEWHEEL_NORMAL); + } else { + SDL_SendMouseWheel(data->window, 0, fAmount, 0.0f, SDL_MOUSEWHEEL_NORMAL); + } + } break; + + case WM_MOUSELEAVE: + if (!(data->window->flags & SDL_WINDOW_MOUSE_CAPTURE)) { + if (SDL_GetMouseFocus() == data->window && !SDL_GetMouse()->relative_mode && !IsIconic(hwnd)) { + SDL_Mouse *mouse; + POINT cursorPos; + SDL_Point point; + GetCursorPos(&cursorPos); + ScreenToClient(hwnd, &cursorPos); + point.x = cursorPos.x; + point.y = cursorPos.y; + WIN_ClientPointToSDL(data->window, &point.x, &point.y); + mouse = SDL_GetMouse(); + if (!mouse->was_touch_mouse_events) { /* we're not a touch handler causing a mouse leave? */ + SDL_SendMouseMotion(data->window, 0, 0, point.x, point.y); + } else { /* touch handling? */ + mouse->was_touch_mouse_events = SDL_FALSE; /* not anymore */ + if (mouse->touch_mouse_events) { /* convert touch to mouse events */ + SDL_SendMouseMotion(data->window, SDL_TOUCH_MOUSEID, 0, point.x, point.y); + } else { /* normal handling */ + SDL_SendMouseMotion(data->window, 0, 0, point.x, point.y); + } + } + } + + if (!SDL_GetMouse()->relative_mode) { + /* When WM_MOUSELEAVE is fired we can be assured that the cursor has left the window */ + SDL_SetMouseFocus(NULL); + } + } + + /* Once we get WM_MOUSELEAVE we're guaranteed that the window is no longer tracked */ + data->mouse_tracked = SDL_FALSE; + + returnCode = 0; + break; +#endif /*!defined(__XBOXONE__) && !defined(__XBOXSERIES__)*/ + + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + { + SDL_Scancode code = WindowsScanCodeToSDLScanCode(lParam, wParam); + const Uint8 *keyboardState = SDL_GetKeyboardState(NULL); + + if (skip_bad_lcrtl(wParam, lParam)) { + returnCode = 0; + break; + } + + /* Detect relevant keyboard shortcuts */ + if (keyboardState[SDL_SCANCODE_LALT] == SDL_PRESSED || keyboardState[SDL_SCANCODE_RALT] == SDL_PRESSED) { + /* ALT+F4: Close window */ + if (code == SDL_SCANCODE_F4 && ShouldGenerateWindowCloseOnAltF4()) { + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_CLOSE, 0, 0); + } + } + + if (code != SDL_SCANCODE_UNKNOWN) { + SDL_SendKeyboardKey(SDL_PRESSED, code); + } + } + + returnCode = 0; + break; + + case WM_SYSKEYUP: + case WM_KEYUP: + { + SDL_Scancode code = WindowsScanCodeToSDLScanCode(lParam, wParam); + const Uint8 *keyboardState = SDL_GetKeyboardState(NULL); + + if (skip_bad_lcrtl(wParam, lParam)) { + returnCode = 0; + break; + } + + if (code != SDL_SCANCODE_UNKNOWN) { + if (code == SDL_SCANCODE_PRINTSCREEN && + keyboardState[code] == SDL_RELEASED) { + SDL_SendKeyboardKey(SDL_PRESSED, code); + } + SDL_SendKeyboardKey(SDL_RELEASED, code); + } + } + returnCode = 0; + break; + + case WM_UNICHAR: + if (wParam == UNICODE_NOCHAR) { + returnCode = 1; + } else { + char text[5]; + if (WIN_ConvertUTF32toUTF8((UINT32)wParam, text)) { + SDL_SendKeyboardText(text); + } + returnCode = 0; + } + break; + + case WM_CHAR: + /* When a user enters a Unicode code point defined in the Basic Multilingual Plane, Windows sends a WM_CHAR + message with the code point encoded as UTF-16. When a user enters a Unicode code point from a Supplementary + Plane, Windows sends the code point in two separate WM_CHAR messages: The first message includes the UTF-16 + High Surrogate and the second the UTF-16 Low Surrogate. The High and Low Surrogates cannot be individually + converted to valid UTF-8, therefore, we must save the High Surrogate from the first WM_CHAR message and + concatenate it with the Low Surrogate from the second WM_CHAR message. At that point, we have a valid + UTF-16 surrogate pair ready to re-encode as UTF-8. */ + if (IS_HIGH_SURROGATE(wParam)) { + data->high_surrogate = (WCHAR)wParam; + } else if (IS_SURROGATE_PAIR(data->high_surrogate, wParam)) { + /* The code point is in a Supplementary Plane. + Here wParam is the Low Surrogate. */ + char text[5]; + if (WIN_ConvertUTF16toUTF8((UINT32)data->high_surrogate, (UINT32)wParam, text)) { + SDL_SendKeyboardText(text); + } + data->high_surrogate = 0; + } else { + /* The code point is in the Basic Multilingual Plane. + It's numerically equal to UTF-32. */ + char text[5]; + if (WIN_ConvertUTF32toUTF8((UINT32)wParam, text)) { + SDL_SendKeyboardText(text); + } + } + returnCode = 0; + break; + +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) +#ifdef WM_INPUTLANGCHANGE + case WM_INPUTLANGCHANGE: + { + WIN_UpdateKeymap(SDL_TRUE); + } + returnCode = 1; + break; +#endif /* WM_INPUTLANGCHANGE */ + + case WM_NCLBUTTONDOWN: + { + data->in_title_click = SDL_TRUE; + } break; + + case WM_CAPTURECHANGED: + { + data->in_title_click = SDL_FALSE; + + /* The mouse may have been released during a modal loop */ + WIN_CheckAsyncMouseRelease(data); + } break; + +#ifdef WM_GETMINMAXINFO + case WM_GETMINMAXINFO: + { + MINMAXINFO *info; + RECT size; + int x, y; + int w, h; + int min_w, min_h; + int max_w, max_h; + BOOL constrain_max_size; + + if (SDL_IsShapedWindow(data->window)) { + Win32_ResizeWindowShape(data->window); + } + + /* If this is an expected size change, allow it */ + if (data->expected_resize) { + break; + } + + /* Get the current position of our window */ + GetWindowRect(hwnd, &size); + x = size.left; + y = size.top; + + /* Calculate current size of our window */ + SDL_GetWindowSize(data->window, &w, &h); + SDL_GetWindowMinimumSize(data->window, &min_w, &min_h); + SDL_GetWindowMaximumSize(data->window, &max_w, &max_h); + + /* Convert w, h, min_w, min_h, max_w, max_h from dpi-scaled points to pixels, + treating them as coordinates within the client area. */ + WIN_ClientPointFromSDL(data->window, &w, &h); + WIN_ClientPointFromSDL(data->window, &min_w, &min_h); + WIN_ClientPointFromSDL(data->window, &max_w, &max_h); + + /* Store in min_w and min_h difference between current size and minimal + size so we don't need to call AdjustWindowRectEx twice */ + min_w -= w; + min_h -= h; + if (max_w && max_h) { + max_w -= w; + max_h -= h; + constrain_max_size = TRUE; + } else { + constrain_max_size = FALSE; + } + + if (!(SDL_GetWindowFlags(data->window) & SDL_WINDOW_BORDERLESS)) { + LONG style = GetWindowLong(hwnd, GWL_STYLE); + /* DJM - according to the docs for GetMenu(), the + return value is undefined if hwnd is a child window. + Apparently it's too difficult for MS to check + inside their function, so I have to do it here. + */ + BOOL menu = (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != NULL); + UINT dpi; + + dpi = 96; + size.top = 0; + size.left = 0; + size.bottom = h; + size.right = w; + + if (WIN_IsPerMonitorV2DPIAware(SDL_GetVideoDevice())) { + dpi = data->videodata->GetDpiForWindow(hwnd); + data->videodata->AdjustWindowRectExForDpi(&size, style, menu, 0, dpi); + } else { + AdjustWindowRectEx(&size, style, menu, 0); + } + w = size.right - size.left; + h = size.bottom - size.top; +#ifdef HIGHDPI_DEBUG + SDL_Log("WM_GETMINMAXINFO: max window size: %dx%d using dpi: %u", w, h, dpi); +#endif + } + + /* Fix our size to the current size */ + info = (MINMAXINFO *)lParam; + if (SDL_GetWindowFlags(data->window) & SDL_WINDOW_RESIZABLE) { + if (SDL_GetWindowFlags(data->window) & SDL_WINDOW_BORDERLESS) { + int screenW = GetSystemMetrics(SM_CXSCREEN); + int screenH = GetSystemMetrics(SM_CYSCREEN); + info->ptMaxSize.x = SDL_max(w, screenW); + info->ptMaxSize.y = SDL_max(h, screenH); + info->ptMaxPosition.x = SDL_min(0, ((screenW - w) / 2)); + info->ptMaxPosition.y = SDL_min(0, ((screenH - h) / 2)); + } + info->ptMinTrackSize.x = (LONG)w + min_w; + info->ptMinTrackSize.y = (LONG)h + min_h; + if (constrain_max_size) { + info->ptMaxTrackSize.x = (LONG)w + max_w; + info->ptMaxTrackSize.y = (LONG)h + max_h; + } + } else { + info->ptMaxSize.x = w; + info->ptMaxSize.y = h; + info->ptMaxPosition.x = x; + info->ptMaxPosition.y = y; + info->ptMinTrackSize.x = w; + info->ptMinTrackSize.y = h; + info->ptMaxTrackSize.x = w; + info->ptMaxTrackSize.y = h; + } + } + returnCode = 0; + break; +#endif /* WM_GETMINMAXINFO */ + + case WM_WINDOWPOSCHANGING: + + if (data->expected_resize) { + returnCode = 0; + } + break; + + case WM_WINDOWPOSCHANGED: + { + RECT rect; + int x, y; + int w, h; + int display_index = data->window->display_index; + + if (data->initializing || data->in_border_change) { + break; + } + + /* When the window is minimized it's resized to the dock icon size, ignore this */ + if (IsIconic(hwnd)) { + break; + } + + if (!GetClientRect(hwnd, &rect) || WIN_IsRectEmpty(&rect)) { + break; + } + ClientToScreen(hwnd, (LPPOINT)&rect); + ClientToScreen(hwnd, (LPPOINT)&rect + 1); + + WIN_UpdateClipCursor(data->window); + + x = rect.left; + y = rect.top; + WIN_ScreenPointToSDL(&x, &y); + + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_MOVED, x, y); + + /* Convert client area width/height from pixels to dpi-scaled points */ + w = rect.right - rect.left; + h = rect.bottom - rect.top; + WIN_ClientPointToSDL(data->window, &w, &h); + + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_RESIZED, w, h); + +#ifdef HIGHDPI_DEBUG + SDL_Log("WM_WINDOWPOSCHANGED: Windows client rect (pixels): (%d, %d) (%d x %d)\tSDL client rect (points): (%d, %d) (%d x %d) cached dpi %d, windows reported dpi %d", + rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, + x, y, w, h, data->scaling_dpi, data->videodata->GetDpiForWindow ? data->videodata->GetDpiForWindow(data->hwnd) : 0); +#endif + + /* Forces a WM_PAINT event */ + InvalidateRect(hwnd, NULL, FALSE); + + if (data->window->display_index != display_index) { + /* Display changed, check ICC profile */ + WIN_UpdateWindowICCProfile(data->window, SDL_TRUE); + } + } break; + + case WM_ENTERSIZEMOVE: + case WM_ENTERMENULOOP: + { + SetTimer(hwnd, (UINT_PTR)&s_ModalMoveResizeLoop, USER_TIMER_MINIMUM, NULL); + } break; + + case WM_TIMER: + { + if (wParam == (UINT_PTR)&s_ModalMoveResizeLoop) { + // Send an expose event so the application can redraw + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_EXPOSED, 0, 0); + return 0; + } + } break; + + case WM_EXITSIZEMOVE: + case WM_EXITMENULOOP: + { + KillTimer(hwnd, (UINT_PTR)&s_ModalMoveResizeLoop); + } break; + + case WM_SIZE: + { + switch (wParam) { + case SIZE_MAXIMIZED: + SDL_SendWindowEvent(data->window, + SDL_WINDOWEVENT_RESTORED, 0, 0); + SDL_SendWindowEvent(data->window, + SDL_WINDOWEVENT_MAXIMIZED, 0, 0); + break; + case SIZE_MINIMIZED: + SDL_SendWindowEvent(data->window, + SDL_WINDOWEVENT_MINIMIZED, 0, 0); + break; + case SIZE_RESTORED: + SDL_SendWindowEvent(data->window, + SDL_WINDOWEVENT_RESTORED, 0, 0); + break; + default: + break; + } + } break; + + case WM_SETCURSOR: + { + Uint16 hittest; + + hittest = LOWORD(lParam); + if (hittest == HTCLIENT) { + SetCursor(SDL_cursor); + returnCode = TRUE; + } else if (!g_WindowFrameUsableWhileCursorHidden && !SDL_cursor) { + SetCursor(NULL); + returnCode = TRUE; + } + } break; + + /* We were occluded, refresh our display */ + case WM_PAINT: + { + RECT rect; + if (GetUpdateRect(hwnd, &rect, FALSE)) { + ValidateRect(hwnd, NULL); + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_EXPOSED, 0, 0); + } + } + returnCode = 0; + break; + + /* We'll do our own drawing, prevent flicker */ + case WM_ERASEBKGND: + if (!data->videodata->cleared) { + RECT client_rect; + HBRUSH brush; + data->videodata->cleared = SDL_TRUE; + GetClientRect(hwnd, &client_rect); + brush = CreateSolidBrush(0); + FillRect(GetDC(hwnd), &client_rect, brush); + DeleteObject(brush); + } + return 1; + + case WM_SYSCOMMAND: + { + if (!g_WindowsEnableMenuMnemonics) { + if ((wParam & 0xFFF0) == SC_KEYMENU) { + return 0; + } + } + +#if defined(SC_SCREENSAVE) || defined(SC_MONITORPOWER) + /* Don't start the screensaver or blank the monitor in fullscreen apps */ + if ((wParam & 0xFFF0) == SC_SCREENSAVE || + (wParam & 0xFFF0) == SC_MONITORPOWER) { + if (SDL_GetVideoDevice()->suspend_screensaver) { + return 0; + } + } +#endif /* System has screensaver support */ + } break; + + case WM_CLOSE: + { + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_CLOSE, 0, 0); + } + returnCode = 0; + break; + + case WM_TOUCH: + if (data->videodata->GetTouchInputInfo && data->videodata->CloseTouchInputHandle) { + UINT i, num_inputs = LOWORD(wParam); + SDL_bool isstack; + PTOUCHINPUT inputs = SDL_small_alloc(TOUCHINPUT, num_inputs, &isstack); + if (data->videodata->GetTouchInputInfo((HTOUCHINPUT)lParam, num_inputs, inputs, sizeof(TOUCHINPUT))) { + RECT rect; + float x, y; + + if (!GetClientRect(hwnd, &rect) || WIN_IsRectEmpty(&rect)) { + if (inputs) { + SDL_small_free(inputs, isstack); + } + break; + } + ClientToScreen(hwnd, (LPPOINT)&rect); + ClientToScreen(hwnd, (LPPOINT)&rect + 1); + rect.top *= 100; + rect.left *= 100; + rect.bottom *= 100; + rect.right *= 100; + + for (i = 0; i < num_inputs; ++i) { + PTOUCHINPUT input = &inputs[i]; + + const SDL_TouchID touchId = (SDL_TouchID)((size_t)input->hSource); + + /* TODO: Can we use GetRawInputDeviceInfo and HID info to + determine if this is a direct or indirect touch device? + */ + if (SDL_AddTouch(touchId, SDL_TOUCH_DEVICE_DIRECT, (input->dwFlags & TOUCHEVENTF_PEN) == TOUCHEVENTF_PEN ? "pen" : "touch") < 0) { + continue; + } + + /* Get the normalized coordinates for the window */ + x = (float)(input->x - rect.left) / (rect.right - rect.left); + y = (float)(input->y - rect.top) / (rect.bottom - rect.top); + + if (input->dwFlags & TOUCHEVENTF_DOWN) { + SDL_SendTouch(touchId, input->dwID, data->window, SDL_TRUE, x, y, 1.0f); + } + if (input->dwFlags & TOUCHEVENTF_MOVE) { + SDL_SendTouchMotion(touchId, input->dwID, data->window, x, y, 1.0f); + } + if (input->dwFlags & TOUCHEVENTF_UP) { + SDL_SendTouch(touchId, input->dwID, data->window, SDL_FALSE, x, y, 1.0f); + } + } + } + SDL_small_free(inputs, isstack); + + data->videodata->CloseTouchInputHandle((HTOUCHINPUT)lParam); + return 0; + } + break; + +#ifdef HAVE_TPCSHRD_H + + case WM_TABLET_QUERYSYSTEMGESTURESTATUS: + /* See https://msdn.microsoft.com/en-us/library/windows/desktop/bb969148(v=vs.85).aspx . + * If we're handling our own touches, we don't want any gestures. + * Not all of these settings are documented. + * The use of the undocumented ones was suggested by https://github.com/bjarkeck/GCGJ/blob/master/Monogame/Windows/WinFormsGameForm.cs . */ + return TABLET_DISABLE_PRESSANDHOLD | TABLET_DISABLE_PENTAPFEEDBACK | TABLET_DISABLE_PENBARRELFEEDBACK | TABLET_DISABLE_TOUCHUIFORCEON | TABLET_DISABLE_TOUCHUIFORCEOFF | TABLET_DISABLE_TOUCHSWITCH | TABLET_DISABLE_FLICKS | TABLET_DISABLE_SMOOTHSCROLLING | TABLET_DISABLE_FLICKFALLBACKKEYS; /* disables press and hold (right-click) gesture */ + /* disables UI feedback on pen up (waves) */ + /* disables UI feedback on pen button down (circle) */ + /* disables pen flicks (back, forward, drag down, drag up) */ + +#endif /* HAVE_TPCSHRD_H */ + + case WM_DROPFILES: + { + UINT i; + HDROP drop = (HDROP)wParam; + UINT count = DragQueryFile(drop, 0xFFFFFFFF, NULL, 0); + for (i = 0; i < count; ++i) { + SDL_bool isstack; + UINT size = DragQueryFile(drop, i, NULL, 0) + 1; + LPTSTR buffer = SDL_small_alloc(TCHAR, size, &isstack); + if (buffer) { + if (DragQueryFile(drop, i, buffer, size)) { + char *file = WIN_StringToUTF8(buffer); + SDL_SendDropFile(data->window, file); + SDL_free(file); + } + SDL_small_free(buffer, isstack); + } + } + SDL_SendDropComplete(data->window); + DragFinish(drop); + return 0; + } break; + + case WM_DISPLAYCHANGE: + { + // Reacquire displays if any were added or removed + WIN_RefreshDisplays(SDL_GetVideoDevice()); + } break; + + case WM_NCCALCSIZE: + { + Uint32 window_flags = SDL_GetWindowFlags(data->window); + if (wParam == TRUE && (window_flags & SDL_WINDOW_BORDERLESS) && !(window_flags & SDL_WINDOW_FULLSCREEN)) { + /* When borderless, need to tell windows that the size of the non-client area is 0 */ + if (!(window_flags & SDL_WINDOW_RESIZABLE)) { + int w, h; + NCCALCSIZE_PARAMS *params = (NCCALCSIZE_PARAMS *)lParam; + w = data->window->windowed.w; + h = data->window->windowed.h; + WIN_ClientPointFromSDL(data->window, &w, &h); + params->rgrc[0].right = params->rgrc[0].left + w; + params->rgrc[0].bottom = params->rgrc[0].top + h; + } + return 0; + } + } break; + + case WM_NCHITTEST: + { + SDL_Window *window = data->window; + if (window->hit_test) { + POINT winpoint; + winpoint.x = GET_X_LPARAM(lParam); + winpoint.y = GET_Y_LPARAM(lParam); + if (ScreenToClient(hwnd, &winpoint)) { + SDL_Point point; + SDL_HitTestResult rc; + point.x = winpoint.x; + point.y = winpoint.y; + WIN_ClientPointToSDL(data->window, &point.x, &point.y); + rc = window->hit_test(window, &point, window->hit_test_data); + switch (rc) { +#define POST_HIT_TEST(ret) \ + { \ + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_HIT_TEST, 0, 0); \ + return ret; \ + } + case SDL_HITTEST_DRAGGABLE: + POST_HIT_TEST(HTCAPTION); + case SDL_HITTEST_RESIZE_TOPLEFT: + POST_HIT_TEST(HTTOPLEFT); + case SDL_HITTEST_RESIZE_TOP: + POST_HIT_TEST(HTTOP); + case SDL_HITTEST_RESIZE_TOPRIGHT: + POST_HIT_TEST(HTTOPRIGHT); + case SDL_HITTEST_RESIZE_RIGHT: + POST_HIT_TEST(HTRIGHT); + case SDL_HITTEST_RESIZE_BOTTOMRIGHT: + POST_HIT_TEST(HTBOTTOMRIGHT); + case SDL_HITTEST_RESIZE_BOTTOM: + POST_HIT_TEST(HTBOTTOM); + case SDL_HITTEST_RESIZE_BOTTOMLEFT: + POST_HIT_TEST(HTBOTTOMLEFT); + case SDL_HITTEST_RESIZE_LEFT: + POST_HIT_TEST(HTLEFT); +#undef POST_HIT_TEST + case SDL_HITTEST_NORMAL: + return HTCLIENT; + } + } + /* If we didn't return, this will call DefWindowProc below. */ + } + } break; + + case WM_GETDPISCALEDSIZE: + /* Windows 10 Creators Update+ */ + /* Documented as only being sent to windows that are per-monitor V2 DPI aware. + + Experimentation shows it's only sent during interactive dragging, not in response to + SetWindowPos. */ + if (data->videodata->GetDpiForWindow && data->videodata->AdjustWindowRectExForDpi) { + /* Windows expects applications to scale their window rects linearly + when dragging between monitors with different DPI's. + e.g. a 100x100 window dragged to a 200% scaled monitor + becomes 200x200. + + For SDL, we instead want the client size to scale linearly. + This is not the same as the window rect scaling linearly, + because Windows doesn't scale the non-client area (titlebar etc.) + linearly. So, we need to handle this message to request custom + scaling. */ + + const int nextDPI = (int)wParam; + const int prevDPI = (int)data->videodata->GetDpiForWindow(hwnd); + SIZE *sizeInOut = (SIZE *)lParam; + + int frame_w, frame_h; + int query_client_w_win, query_client_h_win; + + const DWORD style = GetWindowLong(hwnd, GWL_STYLE); + const BOOL menu = (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != NULL); + +#ifdef HIGHDPI_DEBUG + SDL_Log("WM_GETDPISCALEDSIZE: current DPI: %d potential DPI: %d input size: (%dx%d)", + prevDPI, nextDPI, sizeInOut->cx, sizeInOut->cy); +#endif + + /* Subtract the window frame size that would have been used at prevDPI */ + { + RECT rect = { 0 }; + + if (!(data->window->flags & SDL_WINDOW_BORDERLESS)) { + data->videodata->AdjustWindowRectExForDpi(&rect, style, menu, 0, prevDPI); + } + + frame_w = -rect.left + rect.right; + frame_h = -rect.top + rect.bottom; + + query_client_w_win = sizeInOut->cx - frame_w; + query_client_h_win = sizeInOut->cy - frame_h; + } + + /* Convert to new dpi if we are using scaling. + * Otherwise leave as pixels. + */ + if (data->videodata->dpi_scaling_enabled) { + query_client_w_win = MulDiv(query_client_w_win, nextDPI, prevDPI); + query_client_h_win = MulDiv(query_client_h_win, nextDPI, prevDPI); + } + + /* Add the window frame size that would be used at nextDPI */ + { + RECT rect = { 0 }; + rect.right = query_client_w_win; + rect.bottom = query_client_h_win; + + if (!(data->window->flags & SDL_WINDOW_BORDERLESS)) { + data->videodata->AdjustWindowRectExForDpi(&rect, style, menu, 0, nextDPI); + } + + /* This is supposed to control the suggested rect param of WM_DPICHANGED */ + sizeInOut->cx = rect.right - rect.left; + sizeInOut->cy = rect.bottom - rect.top; + } + +#ifdef HIGHDPI_DEBUG + SDL_Log("WM_GETDPISCALEDSIZE: output size: (%dx%d)", sizeInOut->cx, sizeInOut->cy); +#endif + return TRUE; + } + break; + + case WM_DPICHANGED: + /* Windows 8.1+ */ + { + const int newDPI = HIWORD(wParam); + RECT *const suggestedRect = (RECT *)lParam; + int w, h; + +#ifdef HIGHDPI_DEBUG + SDL_Log("WM_DPICHANGED: to %d\tsuggested rect: (%d, %d), (%dx%d)\n", newDPI, + suggestedRect->left, suggestedRect->top, suggestedRect->right - suggestedRect->left, suggestedRect->bottom - suggestedRect->top); +#endif + + if (data->expected_resize) { + /* This DPI change is coming from an explicit SetWindowPos call within SDL. + Assume all call sites are calculating the DPI-aware frame correctly, so + we don't need to do any further adjustment. */ + + if (data->videodata->dpi_scaling_enabled) { + /* Update the cached DPI value for this window */ + data->scaling_dpi = newDPI; + + /* Send a SDL_WINDOWEVENT_SIZE_CHANGED saying that the client size (in dpi-scaled points) is unchanged. + Renderers need to get this to know that the framebuffer size changed. + + We clear the window size to force the event to be delivered, but what we really + want for SDL3 is a new event to notify that the DPI changed and then watch for + that in the renderer directly. + */ + data->window->w = 0; + data->window->h = 0; + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_SIZE_CHANGED, data->window->w, data->window->h); + } + +#ifdef HIGHDPI_DEBUG + SDL_Log("WM_DPICHANGED: Doing nothing, assuming window is already sized correctly"); +#endif + return 0; + } + + /* Interactive user-initiated resizing/movement */ + + if (WIN_IsPerMonitorV2DPIAware(SDL_GetVideoDevice())) { + /* WM_GETDPISCALEDSIZE should have been called prior, so we can trust the given + suggestedRect. */ + w = suggestedRect->right - suggestedRect->left; + h = suggestedRect->bottom - suggestedRect->top; + +#ifdef HIGHDPI_DEBUG + SDL_Log("WM_DPICHANGED: using suggestedRect"); +#endif + } else { + /* permonitor and earlier DPI awareness: calculate the new frame w/h such that + the client area size is maintained. */ + const DWORD style = GetWindowLong(hwnd, GWL_STYLE); + const BOOL menu = (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != NULL); + + RECT rect = { 0 }; + rect.right = data->window->w; + rect.bottom = data->window->h; + + if (data->videodata->dpi_scaling_enabled) { + /* scale client size to from points to the new DPI */ + rect.right = MulDiv(rect.right, newDPI, 96); + rect.bottom = MulDiv(rect.bottom, newDPI, 96); + } + + if (!(data->window->flags & SDL_WINDOW_BORDERLESS)) { + AdjustWindowRectEx(&rect, style, menu, 0); + } + + w = rect.right - rect.left; + h = rect.bottom - rect.top; + } + +#ifdef HIGHDPI_DEBUG + SDL_Log("WM_DPICHANGED: current SDL window size: (%dx%d)\tcalling SetWindowPos: (%d, %d), (%dx%d)\n", + data->window->w, data->window->h, + suggestedRect->left, suggestedRect->top, w, h); +#endif + + data->expected_resize = SDL_TRUE; + SetWindowPos(hwnd, + NULL, + suggestedRect->left, + suggestedRect->top, + w, + h, + SWP_NOZORDER | SWP_NOACTIVATE); + data->expected_resize = SDL_FALSE; + + if (data->videodata->dpi_scaling_enabled) { + /* Update the cached DPI value for this window */ + data->scaling_dpi = newDPI; + + /* Send a SDL_WINDOWEVENT_SIZE_CHANGED saying that the client size (in dpi-scaled points) is unchanged. + Renderers need to get this to know that the framebuffer size changed. */ + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_SIZE_CHANGED, data->window->w, data->window->h); + } + + return 0; + } + break; + + case WM_SETTINGCHANGE: + if (wParam == SPI_SETMOUSE || wParam == SPI_SETMOUSESPEED) { + WIN_UpdateMouseSystemScale(); + } + break; + +#endif /*!defined(__XBOXONE__) && !defined(__XBOXSERIES__)*/ + } + + /* If there's a window proc, assume it's going to handle messages */ + if (data->wndproc) { + return CallWindowProc(data->wndproc, hwnd, msg, wParam, lParam); + } else if (returnCode >= 0) { + return returnCode; + } else { + return CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam); + } +} + +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) +static void WIN_UpdateClipCursorForWindows() +{ + SDL_VideoDevice *_this = SDL_GetVideoDevice(); + SDL_Window *window; + Uint32 now = SDL_GetTicks(); + const Uint32 CLIPCURSOR_UPDATE_INTERVAL_MS = 3000; + + if (_this) { + for (window = _this->windows; window; window = window->next) { + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + if (data) { + if (data->skip_update_clipcursor) { + data->skip_update_clipcursor = SDL_FALSE; + WIN_UpdateClipCursor(window); + } else if ((now - data->last_updated_clipcursor) >= CLIPCURSOR_UPDATE_INTERVAL_MS) { + WIN_UpdateClipCursor(window); + } + } + } + } +} + +static void WIN_UpdateMouseCapture() +{ + SDL_Window *focusWindow = SDL_GetKeyboardFocus(); + + if (focusWindow && (focusWindow->flags & SDL_WINDOW_MOUSE_CAPTURE)) { + SDL_WindowData *data = (SDL_WindowData *)focusWindow->driverdata; + + if (!data->mouse_tracked) { + POINT cursorPos; + + if (GetCursorPos(&cursorPos) && ScreenToClient(data->hwnd, &cursorPos)) { + SDL_bool swapButtons = GetSystemMetrics(SM_SWAPBUTTON) != 0; + SDL_MouseID mouseID = SDL_GetMouse()->mouseID; + SDL_Point point; + point.x = cursorPos.x; + point.y = cursorPos.y; + WIN_ClientPointToSDL(data->window, &point.x, &point.y); + + SDL_SendMouseMotion(data->window, mouseID, 0, point.x, point.y); + SDL_SendMouseButton(data->window, mouseID, GetAsyncKeyState(VK_LBUTTON) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, !swapButtons ? SDL_BUTTON_LEFT : SDL_BUTTON_RIGHT); + SDL_SendMouseButton(data->window, mouseID, GetAsyncKeyState(VK_RBUTTON) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, !swapButtons ? SDL_BUTTON_RIGHT : SDL_BUTTON_LEFT); + SDL_SendMouseButton(data->window, mouseID, GetAsyncKeyState(VK_MBUTTON) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_MIDDLE); + SDL_SendMouseButton(data->window, mouseID, GetAsyncKeyState(VK_XBUTTON1) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_X1); + SDL_SendMouseButton(data->window, mouseID, GetAsyncKeyState(VK_XBUTTON2) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_X2); + } + } + } +} +#endif /*!defined(__XBOXONE__) && !defined(__XBOXSERIES__)*/ + +/* A message hook called before TranslateMessage() */ +static SDL_WindowsMessageHook g_WindowsMessageHook = NULL; +static void *g_WindowsMessageHookData = NULL; + +void SDL_SetWindowsMessageHook(SDL_WindowsMessageHook callback, void *userdata) +{ + g_WindowsMessageHook = callback; + g_WindowsMessageHookData = userdata; +} + +int WIN_WaitEventTimeout(_THIS, int timeout) +{ + if (g_WindowsEnableMessageLoop) { +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + DWORD dwMilliseconds, ret; + dwMilliseconds = timeout < 0 ? INFINITE : (DWORD)timeout; + ret = MsgWaitForMultipleObjects(0, NULL, FALSE, dwMilliseconds, QS_ALLINPUT); + if (ret == WAIT_OBJECT_0) { + return 1; + } else { + return 0; + } +#else + /* MsgWaitForMultipleObjects is desktop-only. */ + MSG msg; + BOOL message_result; + UINT_PTR timer_id = 0; + if (timeout > 0) { + timer_id = SetTimer(NULL, 0, timeout, NULL); + message_result = GetMessage(&msg, 0, 0, 0); + KillTimer(NULL, timer_id); + } else if (timeout == 0) { + message_result = PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); + } else { + message_result = GetMessage(&msg, 0, 0, 0); + } + if (message_result) { + if (msg.message == WM_TIMER && !msg.hwnd && msg.wParam == timer_id) { + return 0; + } + if (g_WindowsMessageHook) { + g_WindowsMessageHook(g_WindowsMessageHookData, msg.hwnd, msg.message, msg.wParam, msg.lParam); + } + /* Always translate the message in case it's a non-SDL window (e.g. with Qt integration) */ + TranslateMessage(&msg); + DispatchMessage(&msg); + return 1; + } else { + return 0; + } +#endif /*!defined(__XBOXONE__) && !defined(__XBOXSERIES__)*/ + } else { + /* Fail the wait so the caller falls back to polling */ + return -1; + } +} + +void WIN_SendWakeupEvent(_THIS, SDL_Window *window) +{ + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + PostMessage(data->hwnd, data->videodata->_SDL_WAKEUP, 0, 0); +} + +void WIN_PumpEvents(_THIS) +{ + MSG msg; + DWORD end_ticks = GetTickCount() + 1; + int new_messages = 0; +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + const Uint8 *keystate; + SDL_Window *focusWindow; +#endif + + if (g_WindowsEnableMessageLoop) { + while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { + if (g_WindowsMessageHook) { + g_WindowsMessageHook(g_WindowsMessageHookData, msg.hwnd, msg.message, msg.wParam, msg.lParam); + } + +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + /* Don't dispatch any mouse motion queued prior to or including the last mouse warp */ + if (msg.message == WM_MOUSEMOVE && SDL_last_warp_time) { + if (!SDL_TICKS_PASSED(msg.time, (SDL_last_warp_time + 1))) { + continue; + } + + /* This mouse message happened after the warp */ + SDL_last_warp_time = 0; + } +#endif /*!defined(__XBOXONE__) && !defined(__XBOXSERIES__)*/ + + /* Always translate the message in case it's a non-SDL window (e.g. with Qt integration) */ + TranslateMessage(&msg); + DispatchMessage(&msg); + + /* Make sure we don't busy loop here forever if there are lots of events coming in */ + if (SDL_TICKS_PASSED(msg.time, end_ticks)) { + /* We might get a few new messages generated by the Steam overlay or other application hooks + In this case those messages will be processed before any pending input, so we want to continue after those messages. + (thanks to Peter Deayton for his investigation here) + */ + const int MAX_NEW_MESSAGES = 3; + ++new_messages; + if (new_messages > MAX_NEW_MESSAGES) { + break; + } + } + } + } + +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + /* Windows loses a shift KEYUP event when you have both pressed at once and let go of one. + You won't get a KEYUP until both are released, and that keyup will only be for the second + key you released. Take heroic measures and check the keystate as of the last handled event, + and if we think a key is pressed when Windows doesn't, unstick it in SDL's state. */ + keystate = SDL_GetKeyboardState(NULL); + if ((keystate[SDL_SCANCODE_LSHIFT] == SDL_PRESSED) && !(GetKeyState(VK_LSHIFT) & 0x8000)) { + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LSHIFT); + } + if ((keystate[SDL_SCANCODE_RSHIFT] == SDL_PRESSED) && !(GetKeyState(VK_RSHIFT) & 0x8000)) { + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_RSHIFT); + } + + /* The Windows key state gets lost when using Windows+Space or Windows+G shortcuts and + not grabbing the keyboard. Note: If we *are* grabbing the keyboard, GetKeyState() + will return inaccurate results for VK_LWIN and VK_RWIN but we don't need it anyway. */ + focusWindow = SDL_GetKeyboardFocus(); + if (!focusWindow || !(focusWindow->flags & SDL_WINDOW_KEYBOARD_GRABBED)) { + if ((keystate[SDL_SCANCODE_LGUI] == SDL_PRESSED) && !(GetKeyState(VK_LWIN) & 0x8000)) { + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LGUI); + } + if ((keystate[SDL_SCANCODE_RGUI] == SDL_PRESSED) && !(GetKeyState(VK_RWIN) & 0x8000)) { + SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_RGUI); + } + } + + /* Update the clipping rect in case someone else has stolen it */ + WIN_UpdateClipCursorForWindows(); + + /* Update mouse capture */ + WIN_UpdateMouseCapture(); +#endif /*!defined(__XBOXONE__) && !defined(__XBOXSERIES__)*/ + +#ifdef __GDK__ + GDK_DispatchTaskQueue(); +#endif +} + +static int app_registered = 0; +LPTSTR SDL_Appname = NULL; +Uint32 SDL_Appstyle = 0; +HINSTANCE SDL_Instance = NULL; + +static void WIN_CleanRegisterApp(WNDCLASSEX wcex) +{ +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + if (wcex.hIcon) { + DestroyIcon(wcex.hIcon); + } + if (wcex.hIconSm) { + DestroyIcon(wcex.hIconSm); + } +#endif + SDL_free(SDL_Appname); + SDL_Appname = NULL; +} + +static BOOL CALLBACK WIN_ResourceNameCallback(HMODULE hModule, LPCTSTR lpType, LPTSTR lpName, LONG_PTR lParam) +{ + WNDCLASSEX *wcex = (WNDCLASSEX *)lParam; + + (void)lpType; /* We already know that the resource type is RT_GROUP_ICON. */ + + /* We leave hIconSm as NULL as it will allow Windows to automatically + choose the appropriate small icon size to suit the current DPI. */ + wcex->hIcon = LoadIcon(hModule, lpName); + + /* Do not bother enumerating any more. */ + return FALSE; +} + +/* Register the class for this application */ +int SDL_RegisterApp(const char *name, Uint32 style, void *hInst) +{ + WNDCLASSEX wcex; +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + const char *hint; +#endif + + /* Only do this once... */ + if (app_registered) { + ++app_registered; + return 0; + } + SDL_assert(!SDL_Appname); + if (!name) { + name = "SDL_app"; +#if defined(CS_BYTEALIGNCLIENT) || defined(CS_OWNDC) + style = (CS_BYTEALIGNCLIENT | CS_OWNDC); +#endif + } + SDL_Appname = WIN_UTF8ToString(name); + SDL_Appstyle = style; + SDL_Instance = hInst ? hInst : GetModuleHandle(NULL); + + /* Register the application class */ + wcex.cbSize = sizeof(WNDCLASSEX); + wcex.hCursor = NULL; + wcex.hIcon = NULL; + wcex.hIconSm = NULL; + wcex.lpszMenuName = NULL; + wcex.lpszClassName = SDL_Appname; + wcex.style = SDL_Appstyle; + wcex.hbrBackground = NULL; + wcex.lpfnWndProc = WIN_WindowProc; + wcex.hInstance = SDL_Instance; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = 0; + +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + hint = SDL_GetHint(SDL_HINT_WINDOWS_INTRESOURCE_ICON); + if (hint && *hint) { + wcex.hIcon = LoadIcon(SDL_Instance, MAKEINTRESOURCE(SDL_atoi(hint))); + + hint = SDL_GetHint(SDL_HINT_WINDOWS_INTRESOURCE_ICON_SMALL); + if (hint && *hint) { + wcex.hIconSm = LoadIcon(SDL_Instance, MAKEINTRESOURCE(SDL_atoi(hint))); + } + } else { + /* Use the first icon as a default icon, like in the Explorer. */ + EnumResourceNames(SDL_Instance, RT_GROUP_ICON, WIN_ResourceNameCallback, (LONG_PTR)&wcex); + } +#endif /*!defined(__XBOXONE__) && !defined(__XBOXSERIES__)*/ + + if (!RegisterClassEx(&wcex)) { + WIN_CleanRegisterApp(wcex); + return SDL_SetError("Couldn't register application class"); + } + + app_registered = 1; + return 0; +} + +/* Unregisters the windowclass registered in SDL_RegisterApp above. */ +void SDL_UnregisterApp() +{ + WNDCLASSEX wcex; + + /* SDL_RegisterApp might not have been called before */ + if (!app_registered) { + return; + } + --app_registered; + if (app_registered == 0) { + /* Ensure the icons are initialized. */ + wcex.hIcon = NULL; + wcex.hIconSm = NULL; + /* Check for any registered window classes. */ +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + if (GetClassInfoEx(SDL_Instance, SDL_Appname, &wcex)) { + UnregisterClass(SDL_Appname, SDL_Instance); + } +#endif + WIN_CleanRegisterApp(wcex); + } +} + +#endif /* SDL_VIDEO_DRIVER_WINDOWS */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/windows/SDL_windowsevents.h b/SDL2-2.30.5/src/video/windows/SDL_windowsevents.h similarity index 83% rename from SDL2-2.0.12/src/video/windows/SDL_windowsevents.h rename to SDL2-2.30.5/src/video/windows/SDL_windowsevents.h index 80d429f..3e337d0 100644 --- a/SDL2-2.0.12/src/video/windows/SDL_windowsevents.h +++ b/SDL2-2.30.5/src/video/windows/SDL_windowsevents.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -27,9 +27,12 @@ extern LPTSTR SDL_Appname; extern Uint32 SDL_Appstyle; extern HINSTANCE SDL_Instance; +extern LRESULT CALLBACK WIN_KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam); extern LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); extern void WIN_PumpEvents(_THIS); +extern void WIN_SendWakeupEvent(_THIS, SDL_Window *window); +extern int WIN_WaitEventTimeout(_THIS, int timeout); #endif /* SDL_windowsevents_h_ */ diff --git a/SDL2-2.0.12/src/video/windows/SDL_windowsframebuffer.c b/SDL2-2.30.5/src/video/windows/SDL_windowsframebuffer.c similarity index 71% rename from SDL2-2.0.12/src/video/windows/SDL_windowsframebuffer.c rename to SDL2-2.30.5/src/video/windows/SDL_windowsframebuffer.c index 509233e..4234622 100644 --- a/SDL2-2.0.12/src/video/windows/SDL_windowsframebuffer.c +++ b/SDL2-2.30.5/src/video/windows/SDL_windowsframebuffer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,17 +20,20 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_WINDOWS +#if defined(SDL_VIDEO_DRIVER_WINDOWS) && !defined(__XBOXONE__) && !defined(__XBOXSERIES__) #include "SDL_windowsvideo.h" -int WIN_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch) +int WIN_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format, void **pixels, int *pitch) { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; SDL_bool isstack; size_t size; LPBITMAPINFO info; HBITMAP hbm; + int w, h; + + SDL_GetWindowSizeInPixels(window, &w, &h); /* Free the old framebuffer surface */ if (data->mdc) { @@ -41,7 +44,7 @@ int WIN_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, voi } /* Find out the format of the screen */ - size = sizeof(BITMAPINFOHEADER) + 256 * sizeof (RGBQUAD); + size = sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD); info = (LPBITMAPINFO)SDL_small_alloc(Uint8, size, &isstack); if (!info) { return SDL_OutOfMemory(); @@ -62,11 +65,10 @@ int WIN_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, voi Uint32 *masks; bpp = info->bmiHeader.biPlanes * info->bmiHeader.biBitCount; - masks = (Uint32*)((Uint8*)info + info->bmiHeader.biSize); + masks = (Uint32 *)((Uint8 *)info + info->bmiHeader.biSize); *format = SDL_MasksToPixelFormatEnum(bpp, masks[0], masks[1], masks[2], 0); } - if (*format == SDL_PIXELFORMAT_UNKNOWN) - { + if (*format == SDL_PIXELFORMAT_UNKNOWN) { /* We'll use RGB format for now */ *format = SDL_PIXELFORMAT_RGB888; @@ -79,10 +81,10 @@ int WIN_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, voi } /* Fill in the size information */ - *pitch = (((window->w * SDL_BYTESPERPIXEL(*format)) + 3) & ~3); - info->bmiHeader.biWidth = window->w; - info->bmiHeader.biHeight = -window->h; /* negative for topdown bitmap */ - info->bmiHeader.biSizeImage = window->h * (*pitch); + *pitch = (((w * SDL_BYTESPERPIXEL(*format)) + 3) & ~3); + info->bmiHeader.biWidth = w; + info->bmiHeader.biHeight = -h; /* negative for topdown bitmap */ + info->bmiHeader.biSizeImage = (DWORD)h * (*pitch); data->mdc = CreateCompatibleDC(data->hdc); data->hbm = CreateDIBSection(data->hdc, info, DIB_RGB_COLORS, pixels, NULL, 0); @@ -96,17 +98,21 @@ int WIN_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, voi return 0; } -int WIN_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects) +int WIN_UpdateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_Rect *rects, int numrects) { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + int i; - BitBlt(data->hdc, 0, 0, window->w, window->h, data->mdc, 0, 0, SRCCOPY); + for (i = 0; i < numrects; ++i) { + BitBlt(data->hdc, rects[i].x, rects[i].y, rects[i].w, rects[i].h, + data->mdc, rects[i].x, rects[i].y, SRCCOPY); + } return 0; } -void WIN_DestroyWindowFramebuffer(_THIS, SDL_Window * window) +void WIN_DestroyWindowFramebuffer(_THIS, SDL_Window *window) { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; if (!data) { /* The window wasn't fully initialized */ diff --git a/SDL2-2.30.5/src/video/windows/SDL_windowsframebuffer.h b/SDL2-2.30.5/src/video/windows/SDL_windowsframebuffer.h new file mode 100644 index 0000000..adcac8a --- /dev/null +++ b/SDL2-2.30.5/src/video/windows/SDL_windowsframebuffer.h @@ -0,0 +1,27 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +extern int WIN_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format, void **pixels, int *pitch); +extern int WIN_UpdateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_Rect *rects, int numrects); +extern void WIN_DestroyWindowFramebuffer(_THIS, SDL_Window *window); + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/windows/SDL_windowskeyboard.c b/SDL2-2.30.5/src/video/windows/SDL_windowskeyboard.c similarity index 61% rename from SDL2-2.0.12/src/video/windows/SDL_windowskeyboard.c rename to SDL2-2.30.5/src/video/windows/SDL_windowskeyboard.c index 5e1ec46..1ae4fe0 100644 --- a/SDL2-2.0.12/src/video/windows/SDL_windowskeyboard.c +++ b/SDL2-2.30.5/src/video/windows/SDL_windowskeyboard.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,9 +20,10 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_WINDOWS +#if defined(SDL_VIDEO_DRIVER_WINDOWS) && !defined(__XBOXONE__) && !defined(__XBOXSERIES__) #include "SDL_windowsvideo.h" +#include "SDL_hints.h" #include "../../events/SDL_keyboard_c.h" #include "../../events/scancodes_windows.h" @@ -35,23 +36,24 @@ static void IME_Init(SDL_VideoData *videodata, HWND hwnd); static void IME_Enable(SDL_VideoData *videodata, HWND hwnd); static void IME_Disable(SDL_VideoData *videodata, HWND hwnd); static void IME_Quit(SDL_VideoData *videodata); +static SDL_bool IME_IsTextInputShown(SDL_VideoData *videodata); #endif /* !SDL_DISABLE_WINDOWS_IME */ #ifndef MAPVK_VK_TO_VSC -#define MAPVK_VK_TO_VSC 0 +#define MAPVK_VK_TO_VSC 0 #endif #ifndef MAPVK_VSC_TO_VK -#define MAPVK_VSC_TO_VK 1 +#define MAPVK_VSC_TO_VK 1 #endif #ifndef MAPVK_VK_TO_CHAR -#define MAPVK_VK_TO_CHAR 2 +#define MAPVK_VK_TO_CHAR 2 #endif /* Alphabetic scancodes for PC keyboards */ -void -WIN_InitKeyboard(_THIS) +void WIN_InitKeyboard(_THIS) { - SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; +#ifndef SDL_DISABLE_WINDOWS_IME + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; data->ime_com_initialized = SDL_FALSE; data->ime_threadmgr = 0; @@ -61,12 +63,14 @@ WIN_InitKeyboard(_THIS) data->ime_hwnd_main = 0; data->ime_hwnd_current = 0; data->ime_himc = 0; + data->ime_composition_length = 32 * sizeof(WCHAR); + data->ime_composition = (WCHAR *)SDL_malloc(data->ime_composition_length + sizeof(WCHAR)); data->ime_composition[0] = 0; data->ime_readingstring[0] = 0; data->ime_cursor = 0; data->ime_candlist = SDL_FALSE; - SDL_memset(data->ime_candidates, 0, sizeof(data->ime_candidates)); + data->ime_candidates = NULL; data->ime_candcount = 0; data->ime_candref = 0; data->ime_candsel = 0; @@ -96,20 +100,21 @@ WIN_InitKeyboard(_THIS) data->ime_convmodesinkcookie = TF_INVALID_COOKIE; data->ime_uielemsink = 0; data->ime_ippasink = 0; +#endif /* !SDL_DISABLE_WINDOWS_IME */ - WIN_UpdateKeymap(); + WIN_UpdateKeymap(SDL_FALSE); SDL_SetScancodeName(SDL_SCANCODE_APPLICATION, "Menu"); SDL_SetScancodeName(SDL_SCANCODE_LGUI, "Left Windows"); SDL_SetScancodeName(SDL_SCANCODE_RGUI, "Right Windows"); /* Are system caps/num/scroll lock active? Set our state to match. */ - SDL_ToggleModState(KMOD_CAPS, (GetKeyState(VK_CAPITAL) & 0x0001) != 0); - SDL_ToggleModState(KMOD_NUM, (GetKeyState(VK_NUMLOCK) & 0x0001) != 0); + SDL_ToggleModState(KMOD_CAPS, (GetKeyState(VK_CAPITAL) & 0x0001) ? SDL_TRUE : SDL_FALSE); + SDL_ToggleModState(KMOD_NUM, (GetKeyState(VK_NUMLOCK) & 0x0001) ? SDL_TRUE : SDL_FALSE); + SDL_ToggleModState(KMOD_SCROLL, (GetKeyState(VK_SCROLL) & 0x0001) ? SDL_TRUE : SDL_FALSE); } -void -WIN_UpdateKeymap() +void WIN_UpdateKeymap(SDL_bool send_event) { int i; SDL_Scancode scancode; @@ -121,24 +126,22 @@ WIN_UpdateKeymap() int vk; /* Make sure this scancode is a valid character scancode */ scancode = windows_scancode_table[i]; - if (scancode == SDL_SCANCODE_UNKNOWN ) { + if (scancode == SDL_SCANCODE_UNKNOWN) { continue; } /* If this key is one of the non-mappable keys, ignore it */ - /* Not mapping numbers fixes the French layout, giving numeric keycodes for the number keys, which is the expected behavior */ - if ((keymap[scancode] & SDLK_SCANCODE_MASK) || - /* scancode == SDL_SCANCODE_GRAVE || */ /* Uncomment this line to re-enable the behavior of not mapping the "`"(grave) key to the users actual keyboard layout */ - (scancode >= SDL_SCANCODE_1 && scancode <= SDL_SCANCODE_0) ) { + /* Uncomment the second part re-enable the behavior of not mapping the "`"(grave) key to the users actual keyboard layout */ + if ((keymap[scancode] & SDLK_SCANCODE_MASK) /*|| scancode == SDL_SCANCODE_GRAVE*/) { continue; } - vk = MapVirtualKey(i, MAPVK_VSC_TO_VK); - if ( vk ) { - int ch = (MapVirtualKey( vk, MAPVK_VK_TO_CHAR ) & 0x7FFF); - if ( ch ) { - if ( ch >= 'A' && ch <= 'Z' ) { - keymap[scancode] = SDLK_a + ( ch - 'A' ); + vk = MapVirtualKey(i, MAPVK_VSC_TO_VK); + if (vk) { + int ch = (MapVirtualKey(vk, MAPVK_VK_TO_CHAR) & 0x7FFF); + if (ch) { + if (ch >= 'A' && ch <= 'Z') { + keymap[scancode] = SDLK_a + (ch - 'A'); } else { keymap[scancode] = ch; } @@ -146,22 +149,27 @@ WIN_UpdateKeymap() } } - SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES); + SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES, send_event); } -void -WIN_QuitKeyboard(_THIS) +void WIN_QuitKeyboard(_THIS) { + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; + #ifndef SDL_DISABLE_WINDOWS_IME - IME_Quit((SDL_VideoData *)_this->driverdata); -#endif + IME_Quit(data); + + if (data->ime_composition) { + SDL_free(data->ime_composition); + data->ime_composition = NULL; + } +#endif /* !SDL_DISABLE_WINDOWS_IME */ } -void -WIN_ResetDeadKeys() +void WIN_ResetDeadKeys() { /* - if a deadkey has been typed, but not the next character (which the deadkey might modify), + if a deadkey has been typed, but not the next character (which the deadkey might modify), this tries to undo the effect pressing the deadkey. see: http://archives.miloush.net/michkap/archive/2006/09/10/748775.html */ @@ -187,8 +195,7 @@ WIN_ResetDeadKeys() } } -void -WIN_StartTextInput(_THIS) +void WIN_StartTextInput(_THIS) { #ifndef SDL_DISABLE_WINDOWS_IME SDL_Window *window; @@ -199,7 +206,7 @@ WIN_StartTextInput(_THIS) #ifndef SDL_DISABLE_WINDOWS_IME window = SDL_GetKeyboardFocus(); if (window) { - HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + HWND hwnd = ((SDL_WindowData *)window->driverdata)->hwnd; SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; SDL_GetWindowSize(window, &videodata->ime_winwidth, &videodata->ime_winheight); IME_Init(videodata, hwnd); @@ -208,8 +215,7 @@ WIN_StartTextInput(_THIS) #endif /* !SDL_DISABLE_WINDOWS_IME */ } -void -WIN_StopTextInput(_THIS) +void WIN_StopTextInput(_THIS) { #ifndef SDL_DISABLE_WINDOWS_IME SDL_Window *window; @@ -220,7 +226,7 @@ WIN_StopTextInput(_THIS) #ifndef SDL_DISABLE_WINDOWS_IME window = SDL_GetKeyboardFocus(); if (window) { - HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + HWND hwnd = ((SDL_WindowData *)window->driverdata)->hwnd; SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; IME_Init(videodata, hwnd); IME_Disable(videodata, hwnd); @@ -228,8 +234,7 @@ WIN_StopTextInput(_THIS) #endif /* !SDL_DISABLE_WINDOWS_IME */ } -void -WIN_SetTextInputRect(_THIS, SDL_Rect *rect) +void WIN_SetTextInputRect(_THIS, const SDL_Rect *rect) { SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; HIMC himc = 0; @@ -239,25 +244,50 @@ WIN_SetTextInputRect(_THIS, SDL_Rect *rect) return; } +#ifndef SDL_DISABLE_WINDOWS_IME videodata->ime_rect = *rect; himc = ImmGetContext(videodata->ime_hwnd_current); - if (himc) - { - COMPOSITIONFORM cf; - cf.ptCurrentPos.x = videodata->ime_rect.x; - cf.ptCurrentPos.y = videodata->ime_rect.y; - cf.dwStyle = CFS_FORCE_POSITION; - ImmSetCompositionWindow(himc, &cf); + if (himc) { + COMPOSITIONFORM cof; + CANDIDATEFORM caf; + + cof.dwStyle = CFS_RECT; + cof.ptCurrentPos.x = videodata->ime_rect.x; + cof.ptCurrentPos.y = videodata->ime_rect.y; + cof.rcArea.left = videodata->ime_rect.x; + cof.rcArea.right = (LONG)videodata->ime_rect.x + videodata->ime_rect.w; + cof.rcArea.top = videodata->ime_rect.y; + cof.rcArea.bottom = (LONG)videodata->ime_rect.y + videodata->ime_rect.h; + ImmSetCompositionWindow(himc, &cof); + + caf.dwIndex = 0; + caf.dwStyle = CFS_EXCLUDE; + caf.ptCurrentPos.x = videodata->ime_rect.x; + caf.ptCurrentPos.y = videodata->ime_rect.y; + caf.rcArea.left = videodata->ime_rect.x; + caf.rcArea.right = (LONG)videodata->ime_rect.x + videodata->ime_rect.w; + caf.rcArea.top = videodata->ime_rect.y; + caf.rcArea.bottom = (LONG)videodata->ime_rect.y + videodata->ime_rect.h; + ImmSetCandidateWindow(himc, &caf); + ImmReleaseContext(videodata->ime_hwnd_current, himc); } +#endif /* !SDL_DISABLE_WINDOWS_IME */ } #ifdef SDL_DISABLE_WINDOWS_IME +void WIN_ClearComposition(_THIS) +{ +} -SDL_bool -IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, SDL_VideoData *videodata) +SDL_bool WIN_IsTextInputShown(_THIS) +{ + return SDL_FALSE; +} + +SDL_bool IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, SDL_VideoData *videodata) { return SDL_FALSE; } @@ -275,57 +305,58 @@ void IME_Present(SDL_VideoData *videodata) #endif #ifdef USE_INIT_GUID #undef DEFINE_GUID -#define DEFINE_GUID(n,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) static const GUID n = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}} -DEFINE_GUID(IID_ITfInputProcessorProfileActivationSink, 0x71C6E74E,0x0F28,0x11D8,0xA8,0x2A,0x00,0x06,0x5B,0x84,0x43,0x5C); -DEFINE_GUID(IID_ITfUIElementSink, 0xEA1EA136,0x19DF,0x11D7,0xA6,0xD2,0x00,0x06,0x5B,0x84,0x43,0x5C); -DEFINE_GUID(GUID_TFCAT_TIP_KEYBOARD, 0x34745C63,0xB2F0,0x4784,0x8B,0x67,0x5E,0x12,0xC8,0x70,0x1A,0x31); -DEFINE_GUID(IID_ITfSource, 0x4EA48A35,0x60AE,0x446F,0x8F,0xD6,0xE6,0xA8,0xD8,0x24,0x59,0xF7); -DEFINE_GUID(IID_ITfUIElementMgr, 0xEA1EA135,0x19DF,0x11D7,0xA6,0xD2,0x00,0x06,0x5B,0x84,0x43,0x5C); -DEFINE_GUID(IID_ITfCandidateListUIElement, 0xEA1EA138,0x19DF,0x11D7,0xA6,0xD2,0x00,0x06,0x5B,0x84,0x43,0x5C); -DEFINE_GUID(IID_ITfReadingInformationUIElement, 0xEA1EA139,0x19DF,0x11D7,0xA6,0xD2,0x00,0x06,0x5B,0x84,0x43,0x5C); -DEFINE_GUID(IID_ITfThreadMgr, 0xAA80E801,0x2021,0x11D2,0x93,0xE0,0x00,0x60,0xB0,0x67,0xB8,0x6E); -DEFINE_GUID(CLSID_TF_ThreadMgr, 0x529A9E6B,0x6587,0x4F23,0xAB,0x9E,0x9C,0x7D,0x68,0x3E,0x3C,0x50); -DEFINE_GUID(IID_ITfThreadMgrEx, 0x3E90ADE3,0x7594,0x4CB0,0xBB,0x58,0x69,0x62,0x8F,0x5F,0x45,0x8C); +#define DEFINE_GUID(n, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) static const GUID n = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } +DEFINE_GUID(IID_ITfInputProcessorProfileActivationSink, 0x71C6E74E, 0x0F28, 0x11D8, 0xA8, 0x2A, 0x00, 0x06, 0x5B, 0x84, 0x43, 0x5C); +DEFINE_GUID(IID_ITfUIElementSink, 0xEA1EA136, 0x19DF, 0x11D7, 0xA6, 0xD2, 0x00, 0x06, 0x5B, 0x84, 0x43, 0x5C); +DEFINE_GUID(GUID_TFCAT_TIP_KEYBOARD, 0x34745C63, 0xB2F0, 0x4784, 0x8B, 0x67, 0x5E, 0x12, 0xC8, 0x70, 0x1A, 0x31); +DEFINE_GUID(IID_ITfSource, 0x4EA48A35, 0x60AE, 0x446F, 0x8F, 0xD6, 0xE6, 0xA8, 0xD8, 0x24, 0x59, 0xF7); +DEFINE_GUID(IID_ITfUIElementMgr, 0xEA1EA135, 0x19DF, 0x11D7, 0xA6, 0xD2, 0x00, 0x06, 0x5B, 0x84, 0x43, 0x5C); +DEFINE_GUID(IID_ITfCandidateListUIElement, 0xEA1EA138, 0x19DF, 0x11D7, 0xA6, 0xD2, 0x00, 0x06, 0x5B, 0x84, 0x43, 0x5C); +DEFINE_GUID(IID_ITfReadingInformationUIElement, 0xEA1EA139, 0x19DF, 0x11D7, 0xA6, 0xD2, 0x00, 0x06, 0x5B, 0x84, 0x43, 0x5C); +DEFINE_GUID(IID_ITfThreadMgr, 0xAA80E801, 0x2021, 0x11D2, 0x93, 0xE0, 0x00, 0x60, 0xB0, 0x67, 0xB8, 0x6E); +DEFINE_GUID(CLSID_TF_ThreadMgr, 0x529A9E6B, 0x6587, 0x4F23, 0xAB, 0x9E, 0x9C, 0x7D, 0x68, 0x3E, 0x3C, 0x50); +DEFINE_GUID(IID_ITfThreadMgrEx, 0x3E90ADE3, 0x7594, 0x4CB0, 0xBB, 0x58, 0x69, 0x62, 0x8F, 0x5F, 0x45, 0x8C); #endif #define LANG_CHT MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL) #define LANG_CHS MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED) -#define MAKEIMEVERSION(major,minor) ((DWORD) (((BYTE)(major) << 24) | ((BYTE)(minor) << 16) )) -#define IMEID_VER(id) ((id) & 0xffff0000) -#define IMEID_LANG(id) ((id) & 0x0000ffff) +#define MAKEIMEVERSION(major, minor) ((DWORD)(((BYTE)(major) << 24) | ((BYTE)(minor) << 16))) +#define IMEID_VER(id) ((id)&0xffff0000) +#define IMEID_LANG(id) ((id)&0x0000ffff) -#define CHT_HKL_DAYI ((HKL)(UINT_PTR)0xE0060404) -#define CHT_HKL_NEW_PHONETIC ((HKL)(UINT_PTR)0xE0080404) -#define CHT_HKL_NEW_CHANG_JIE ((HKL)(UINT_PTR)0xE0090404) -#define CHT_HKL_NEW_QUICK ((HKL)(UINT_PTR)0xE00A0404) -#define CHT_HKL_HK_CANTONESE ((HKL)(UINT_PTR)0xE00B0404) -#define CHT_IMEFILENAME1 "TINTLGNT.IME" -#define CHT_IMEFILENAME2 "CINTLGNT.IME" -#define CHT_IMEFILENAME3 "MSTCIPHA.IME" -#define IMEID_CHT_VER42 (LANG_CHT | MAKEIMEVERSION(4, 2)) -#define IMEID_CHT_VER43 (LANG_CHT | MAKEIMEVERSION(4, 3)) -#define IMEID_CHT_VER44 (LANG_CHT | MAKEIMEVERSION(4, 4)) -#define IMEID_CHT_VER50 (LANG_CHT | MAKEIMEVERSION(5, 0)) -#define IMEID_CHT_VER51 (LANG_CHT | MAKEIMEVERSION(5, 1)) -#define IMEID_CHT_VER52 (LANG_CHT | MAKEIMEVERSION(5, 2)) -#define IMEID_CHT_VER60 (LANG_CHT | MAKEIMEVERSION(6, 0)) -#define IMEID_CHT_VER_VISTA (LANG_CHT | MAKEIMEVERSION(7, 0)) +#define CHT_HKL_DAYI ((HKL)(UINT_PTR)0xE0060404) +#define CHT_HKL_NEW_PHONETIC ((HKL)(UINT_PTR)0xE0080404) +#define CHT_HKL_NEW_CHANG_JIE ((HKL)(UINT_PTR)0xE0090404) +#define CHT_HKL_NEW_QUICK ((HKL)(UINT_PTR)0xE00A0404) +#define CHT_HKL_HK_CANTONESE ((HKL)(UINT_PTR)0xE00B0404) +#define CHT_IMEFILENAME1 "TINTLGNT.IME" +#define CHT_IMEFILENAME2 "CINTLGNT.IME" +#define CHT_IMEFILENAME3 "MSTCIPHA.IME" +#define IMEID_CHT_VER42 (LANG_CHT | MAKEIMEVERSION(4, 2)) +#define IMEID_CHT_VER43 (LANG_CHT | MAKEIMEVERSION(4, 3)) +#define IMEID_CHT_VER44 (LANG_CHT | MAKEIMEVERSION(4, 4)) +#define IMEID_CHT_VER50 (LANG_CHT | MAKEIMEVERSION(5, 0)) +#define IMEID_CHT_VER51 (LANG_CHT | MAKEIMEVERSION(5, 1)) +#define IMEID_CHT_VER52 (LANG_CHT | MAKEIMEVERSION(5, 2)) +#define IMEID_CHT_VER60 (LANG_CHT | MAKEIMEVERSION(6, 0)) +#define IMEID_CHT_VER_VISTA (LANG_CHT | MAKEIMEVERSION(7, 0)) -#define CHS_HKL ((HKL)(UINT_PTR)0xE00E0804) -#define CHS_IMEFILENAME1 "PINTLGNT.IME" -#define CHS_IMEFILENAME2 "MSSCIPYA.IME" -#define IMEID_CHS_VER41 (LANG_CHS | MAKEIMEVERSION(4, 1)) -#define IMEID_CHS_VER42 (LANG_CHS | MAKEIMEVERSION(4, 2)) -#define IMEID_CHS_VER53 (LANG_CHS | MAKEIMEVERSION(5, 3)) +#define CHS_HKL ((HKL)(UINT_PTR)0xE00E0804) +#define CHS_IMEFILENAME1 "PINTLGNT.IME" +#define CHS_IMEFILENAME2 "MSSCIPYA.IME" +#define IMEID_CHS_VER41 (LANG_CHS | MAKEIMEVERSION(4, 1)) +#define IMEID_CHS_VER42 (LANG_CHS | MAKEIMEVERSION(4, 2)) +#define IMEID_CHS_VER53 (LANG_CHS | MAKEIMEVERSION(5, 3)) -#define LANG() LOWORD((videodata->ime_hkl)) -#define PRIMLANG() ((WORD)PRIMARYLANGID(LANG())) -#define SUBLANG() SUBLANGID(LANG()) +#define LANG() LOWORD((videodata->ime_hkl)) +#define PRIMLANG() ((WORD)PRIMARYLANGID(LANG())) +#define SUBLANG() SUBLANGID(LANG()) static void IME_UpdateInputLocale(SDL_VideoData *videodata); +static int IME_ShowCandidateList(SDL_VideoData *videodata); static void IME_ClearComposition(SDL_VideoData *videodata); -static void IME_SetWindow(SDL_VideoData* videodata, HWND hwnd); +static void IME_SetWindow(SDL_VideoData *videodata, HWND hwnd); static void IME_SetupAPI(SDL_VideoData *videodata); static DWORD IME_GetId(SDL_VideoData *videodata, UINT uIndex); static void IME_SendEditingEvent(SDL_VideoData *videodata); @@ -336,16 +367,28 @@ static void UILess_ReleaseSinks(SDL_VideoData *videodata); static void UILess_EnableUIUpdates(SDL_VideoData *videodata); static void UILess_DisableUIUpdates(SDL_VideoData *videodata); -static void -IME_Init(SDL_VideoData *videodata, HWND hwnd) +static SDL_bool WIN_ShouldShowNativeUI() { - if (videodata->ime_initialized) + return SDL_GetHintBoolean(SDL_HINT_IME_SHOW_UI, SDL_FALSE); +} + +static void IME_Init(SDL_VideoData *videodata, HWND hwnd) +{ + HRESULT hResult = S_OK; + + if (videodata->ime_initialized) { return; + } videodata->ime_hwnd_main = hwnd; if (SUCCEEDED(WIN_CoInitialize())) { videodata->ime_com_initialized = SDL_TRUE; - CoCreateInstance(&CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER, &IID_ITfThreadMgr, (LPVOID *)&videodata->ime_threadmgr); + hResult = CoCreateInstance(&CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER, &IID_ITfThreadMgr, (LPVOID *)&videodata->ime_threadmgr); + if (hResult != S_OK) { + videodata->ime_available = SDL_FALSE; + SDL_SetError("CoCreateInstance() failed, HRESULT is %08X", (unsigned int)hResult); + return; + } } videodata->ime_initialized = SDL_TRUE; videodata->ime_himm32 = SDL_LoadObject("imm32.dll"); @@ -354,10 +397,12 @@ IME_Init(SDL_VideoData *videodata, HWND hwnd) SDL_ClearError(); return; } + /* *INDENT-OFF* */ /* clang-format off */ videodata->ImmLockIMC = (LPINPUTCONTEXT2 (WINAPI *)(HIMC))SDL_LoadFunction(videodata->ime_himm32, "ImmLockIMC"); videodata->ImmUnlockIMC = (BOOL (WINAPI *)(HIMC))SDL_LoadFunction(videodata->ime_himm32, "ImmUnlockIMC"); videodata->ImmLockIMCC = (LPVOID (WINAPI *)(HIMCC))SDL_LoadFunction(videodata->ime_himm32, "ImmLockIMCC"); videodata->ImmUnlockIMCC = (BOOL (WINAPI *)(HIMCC))SDL_LoadFunction(videodata->ime_himm32, "ImmUnlockIMCC"); + /* *INDENT-ON* */ /* clang-format on */ IME_SetWindow(videodata, hwnd); videodata->ime_himc = ImmGetContext(hwnd); @@ -370,52 +415,59 @@ IME_Init(SDL_VideoData *videodata, HWND hwnd) videodata->ime_available = SDL_TRUE; IME_UpdateInputLocale(videodata); IME_SetupAPI(videodata); - videodata->ime_uiless = UILess_SetupSinks(videodata); + if (WIN_ShouldShowNativeUI()) { + videodata->ime_uiless = SDL_FALSE; + } else { + videodata->ime_uiless = UILess_SetupSinks(videodata); + } IME_UpdateInputLocale(videodata); IME_Disable(videodata, hwnd); } -static void -IME_Enable(SDL_VideoData *videodata, HWND hwnd) +static void IME_Enable(SDL_VideoData *videodata, HWND hwnd) { - if (!videodata->ime_initialized || !videodata->ime_hwnd_current) + if (!videodata->ime_initialized || !videodata->ime_hwnd_current) { return; + } if (!videodata->ime_available) { IME_Disable(videodata, hwnd); return; } - if (videodata->ime_hwnd_current == videodata->ime_hwnd_main) + if (videodata->ime_hwnd_current == videodata->ime_hwnd_main) { ImmAssociateContext(videodata->ime_hwnd_current, videodata->ime_himc); + } videodata->ime_enabled = SDL_TRUE; IME_UpdateInputLocale(videodata); UILess_EnableUIUpdates(videodata); } -static void -IME_Disable(SDL_VideoData *videodata, HWND hwnd) +static void IME_Disable(SDL_VideoData *videodata, HWND hwnd) { - if (!videodata->ime_initialized || !videodata->ime_hwnd_current) + if (!videodata->ime_initialized || !videodata->ime_hwnd_current) { return; + } IME_ClearComposition(videodata); - if (videodata->ime_hwnd_current == videodata->ime_hwnd_main) + if (videodata->ime_hwnd_current == videodata->ime_hwnd_main) { ImmAssociateContext(videodata->ime_hwnd_current, (HIMC)0); + } videodata->ime_enabled = SDL_FALSE; UILess_DisableUIUpdates(videodata); } -static void -IME_Quit(SDL_VideoData *videodata) +static void IME_Quit(SDL_VideoData *videodata) { - if (!videodata->ime_initialized) + if (!videodata->ime_initialized) { return; + } UILess_ReleaseSinks(videodata); - if (videodata->ime_hwnd_main) + if (videodata->ime_hwnd_main) { ImmAssociateContext(videodata->ime_hwnd_main, videodata->ime_himc); + } videodata->ime_hwnd_main = 0; videodata->ime_himc = 0; @@ -435,8 +487,7 @@ IME_Quit(SDL_VideoData *videodata) videodata->ime_initialized = SDL_FALSE; } -static void -IME_GetReadingString(SDL_VideoData *videodata, HWND hwnd) +static void IME_GetReadingString(SDL_VideoData *videodata, HWND hwnd) { DWORD id = 0; HIMC himc = 0; @@ -447,77 +498,83 @@ IME_GetReadingString(SDL_VideoData *videodata, HWND hwnd) BOOL vertical = FALSE; UINT maxuilen = 0; - if (videodata->ime_uiless) + if (videodata->ime_uiless) { return; + } videodata->ime_readingstring[0] = 0; - + id = IME_GetId(videodata, 0); - if (!id) + if (!id) { return; + } himc = ImmGetContext(hwnd); - if (!himc) + if (!himc) { return; + } if (videodata->GetReadingString) { len = videodata->GetReadingString(himc, 0, 0, &err, &vertical, &maxuilen); if (len) { - if (len > SDL_arraysize(buffer)) + if (len > SDL_arraysize(buffer)) { len = SDL_arraysize(buffer); + } len = videodata->GetReadingString(himc, len, s, &err, &vertical, &maxuilen); } SDL_wcslcpy(videodata->ime_readingstring, s, len); - } - else { + } else { LPINPUTCONTEXT2 lpimc = videodata->ImmLockIMC(himc); LPBYTE p = 0; s = 0; - switch (id) - { + switch (id) { case IMEID_CHT_VER42: case IMEID_CHT_VER43: case IMEID_CHT_VER44: p = *(LPBYTE *)((LPBYTE)videodata->ImmLockIMCC(lpimc->hPrivate) + 24); - if (!p) + if (!p) { break; + } - len = *(DWORD *)(p + 7*4 + 32*4); + len = *(DWORD *)(p + 7 * 4 + 32 * 4); s = (WCHAR *)(p + 56); break; case IMEID_CHT_VER51: case IMEID_CHT_VER52: case IMEID_CHS_VER53: p = *(LPBYTE *)((LPBYTE)videodata->ImmLockIMCC(lpimc->hPrivate) + 4); - if (!p) + if (!p) { break; + } - p = *(LPBYTE *)((LPBYTE)p + 1*4 + 5*4); - if (!p) + p = *(LPBYTE *)(p + 1 * 4 + 5 * 4); + if (!p) { break; + } - len = *(DWORD *)(p + 1*4 + (16*2+2*4) + 5*4 + 16*2); - s = (WCHAR *)(p + 1*4 + (16*2+2*4) + 5*4); + len = *(DWORD *)(p + 1 * 4 + (16 * 2 + 2 * 4) + 5 * 4 + 16 * 2); + s = (WCHAR *)(p + 1 * 4 + (16 * 2 + 2 * 4) + 5 * 4); break; case IMEID_CHS_VER41: - { - int offset = (IME_GetId(videodata, 1) >= 0x00000002) ? 8 : 7; - p = *(LPBYTE *)((LPBYTE)videodata->ImmLockIMCC(lpimc->hPrivate) + offset * 4); - if (!p) - break; - - len = *(DWORD *)(p + 7*4 + 16*2*4); - s = (WCHAR *)(p + 6*4 + 16*2*1); - } - break; - case IMEID_CHS_VER42: - p = *(LPBYTE *)((LPBYTE)videodata->ImmLockIMCC(lpimc->hPrivate) + 1*4 + 1*4 + 6*4); - if (!p) + { + int offset = (IME_GetId(videodata, 1) >= 0x00000002) ? 8 : 7; + p = *(LPBYTE *)((LPBYTE)videodata->ImmLockIMCC(lpimc->hPrivate) + offset * 4); + if (!p) { break; + } - len = *(DWORD *)(p + 1*4 + (16*2+2*4) + 5*4 + 16*2); - s = (WCHAR *)(p + 1*4 + (16*2+2*4) + 5*4); + len = *(DWORD *)(p + 7 * 4 + 16 * 2 * 4); + s = (WCHAR *)(p + 6 * 4 + 16 * 2 * 1); + } break; + case IMEID_CHS_VER42: + p = *(LPBYTE *)((LPBYTE)videodata->ImmLockIMCC(lpimc->hPrivate) + 1 * 4 + 1 * 4 + 6 * 4); + if (!p) { + break; + } + + len = *(DWORD *)(p + 1 * 4 + (16 * 2 + 2 * 4) + 5 * 4 + 16 * 2); + s = (WCHAR *)(p + 1 * 4 + (16 * 2 + 2 * 4) + 5 * 4); break; } if (s) { @@ -532,13 +589,13 @@ IME_GetReadingString(SDL_VideoData *videodata, HWND hwnd) IME_SendEditingEvent(videodata); } -static void -IME_InputLangChanged(SDL_VideoData *videodata) +static void IME_InputLangChanged(SDL_VideoData *videodata) { UINT lang = PRIMLANG(); IME_UpdateInputLocale(videodata); - if (!videodata->ime_uiless) + if (!videodata->ime_uiless) { videodata->ime_candlistindexbase = (videodata->ime_hkl == CHT_HKL_DAYI) ? 0 : 1; + } IME_SetupAPI(videodata); if (lang != PRIMLANG()) { @@ -546,11 +603,10 @@ IME_InputLangChanged(SDL_VideoData *videodata) } } -static DWORD -IME_GetId(SDL_VideoData *videodata, UINT uIndex) +static DWORD IME_GetId(SDL_VideoData *videodata, UINT uIndex) { static HKL hklprev = 0; - static DWORD dwRet[2] = {0}; + static DWORD dwRet[2] = { 0 }; DWORD dwVerSize = 0; DWORD dwVerHandle = 0; LPVOID lpVerBuffer = 0; @@ -559,72 +615,62 @@ IME_GetId(SDL_VideoData *videodata, UINT uIndex) char szTemp[256]; HKL hkl = 0; DWORD dwLang = 0; - if (uIndex >= sizeof(dwRet) / sizeof(dwRet[0])) - return 0; + SDL_assert(uIndex < sizeof(dwRet) / sizeof(dwRet[0])); hkl = videodata->ime_hkl; - if (hklprev == hkl) + if (hklprev == hkl) { return dwRet[uIndex]; - + } hklprev = hkl; + + SDL_assert(uIndex == 0); dwLang = ((DWORD_PTR)hkl & 0xffff); - if (videodata->ime_uiless && LANG() == LANG_CHT) { + if (videodata->ime_uiless && dwLang == LANG_CHT) { dwRet[0] = IMEID_CHT_VER_VISTA; dwRet[1] = 0; return dwRet[0]; } - if (hkl != CHT_HKL_NEW_PHONETIC - && hkl != CHT_HKL_NEW_CHANG_JIE - && hkl != CHT_HKL_NEW_QUICK - && hkl != CHT_HKL_HK_CANTONESE - && hkl != CHS_HKL) { + if (hkl != CHT_HKL_NEW_PHONETIC && hkl != CHT_HKL_NEW_CHANG_JIE && hkl != CHT_HKL_NEW_QUICK && hkl != CHT_HKL_HK_CANTONESE && hkl != CHS_HKL) { dwRet[0] = dwRet[1] = 0; - return dwRet[uIndex]; + return dwRet[0]; } - if (ImmGetIMEFileNameA(hkl, szTemp, sizeof(szTemp) - 1) <= 0) { + if (!ImmGetIMEFileNameA(hkl, szTemp, sizeof(szTemp) - 1)) { dwRet[0] = dwRet[1] = 0; - return dwRet[uIndex]; + return dwRet[0]; } if (!videodata->GetReadingString) { - #define LCID_INVARIANT MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT) - if (CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHT_IMEFILENAME1, -1) != 2 - && CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHT_IMEFILENAME2, -1) != 2 - && CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHT_IMEFILENAME3, -1) != 2 - && CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHS_IMEFILENAME1, -1) != 2 - && CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHS_IMEFILENAME2, -1) != 2) { +#define LCID_INVARIANT MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT) + if (CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHT_IMEFILENAME1, -1) != 2 && CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHT_IMEFILENAME2, -1) != 2 && CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHT_IMEFILENAME3, -1) != 2 && CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHS_IMEFILENAME1, -1) != 2 && CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHS_IMEFILENAME2, -1) != 2) { dwRet[0] = dwRet[1] = 0; - return dwRet[uIndex]; + return dwRet[0]; } - #undef LCID_INVARIANT +#undef LCID_INVARIANT dwVerSize = GetFileVersionInfoSizeA(szTemp, &dwVerHandle); if (dwVerSize) { lpVerBuffer = SDL_malloc(dwVerSize); if (lpVerBuffer) { if (GetFileVersionInfoA(szTemp, dwVerHandle, dwVerSize, lpVerBuffer)) { if (VerQueryValueA(lpVerBuffer, "\\", &lpVerData, &cbVerData)) { - #define pVerFixedInfo ((VS_FIXEDFILEINFO FAR*)lpVerData) +#define pVerFixedInfo ((VS_FIXEDFILEINFO FAR *)lpVerData) DWORD dwVer = pVerFixedInfo->dwFileVersionMS; dwVer = (dwVer & 0x00ff0000) << 8 | (dwVer & 0x000000ff) << 16; if ((videodata->GetReadingString) || - ((dwLang == LANG_CHT) && ( - dwVer == MAKEIMEVERSION(4, 2) || - dwVer == MAKEIMEVERSION(4, 3) || - dwVer == MAKEIMEVERSION(4, 4) || - dwVer == MAKEIMEVERSION(5, 0) || - dwVer == MAKEIMEVERSION(5, 1) || - dwVer == MAKEIMEVERSION(5, 2) || - dwVer == MAKEIMEVERSION(6, 0))) - || - ((dwLang == LANG_CHS) && ( - dwVer == MAKEIMEVERSION(4, 1) || - dwVer == MAKEIMEVERSION(4, 2) || - dwVer == MAKEIMEVERSION(5, 3)))) { + ((dwLang == LANG_CHT) && (dwVer == MAKEIMEVERSION(4, 2) || + dwVer == MAKEIMEVERSION(4, 3) || + dwVer == MAKEIMEVERSION(4, 4) || + dwVer == MAKEIMEVERSION(5, 0) || + dwVer == MAKEIMEVERSION(5, 1) || + dwVer == MAKEIMEVERSION(5, 2) || + dwVer == MAKEIMEVERSION(6, 0))) || + ((dwLang == LANG_CHS) && (dwVer == MAKEIMEVERSION(4, 1) || + dwVer == MAKEIMEVERSION(4, 2) || + dwVer == MAKEIMEVERSION(5, 3)))) { dwRet[0] = dwVer | dwLang; dwRet[1] = pVerFixedInfo->dwFileVersionLS; SDL_free(lpVerBuffer); return dwRet[0]; } - #undef pVerFixedInfo +#undef pVerFixedInfo } } } @@ -632,32 +678,36 @@ IME_GetId(SDL_VideoData *videodata, UINT uIndex) } } dwRet[0] = dwRet[1] = 0; - return dwRet[uIndex]; + return dwRet[0]; } -static void -IME_SetupAPI(SDL_VideoData *videodata) +static void IME_SetupAPI(SDL_VideoData *videodata) { char ime_file[MAX_PATH + 1]; - void* hime = 0; + void *hime = 0; HKL hkl = 0; videodata->GetReadingString = 0; videodata->ShowReadingWindow = 0; - if (videodata->ime_uiless) + if (videodata->ime_uiless) { return; + } hkl = videodata->ime_hkl; - if (ImmGetIMEFileNameA(hkl, ime_file, sizeof(ime_file) - 1) <= 0) + if (!ImmGetIMEFileNameA(hkl, ime_file, sizeof(ime_file) - 1)) { return; + } hime = SDL_LoadObject(ime_file); - if (!hime) + if (!hime) { return; + } + /* *INDENT-OFF* */ /* clang-format off */ videodata->GetReadingString = (UINT (WINAPI *)(HIMC, UINT, LPWSTR, PINT, BOOL*, PUINT)) SDL_LoadFunction(hime, "GetReadingString"); videodata->ShowReadingWindow = (BOOL (WINAPI *)(HIMC, BOOL)) SDL_LoadFunction(hime, "ShowReadingWindow"); + /* *INDENT-ON* */ /* clang-format on */ if (videodata->ShowReadingWindow) { HIMC himc = ImmGetContext(videodata->ime_hwnd_current); @@ -668,88 +718,143 @@ IME_SetupAPI(SDL_VideoData *videodata) } } -static void -IME_SetWindow(SDL_VideoData* videodata, HWND hwnd) +static void IME_SetWindow(SDL_VideoData *videodata, HWND hwnd) { videodata->ime_hwnd_current = hwnd; if (videodata->ime_threadmgr) { struct ITfDocumentMgr *document_mgr = 0; if (SUCCEEDED(videodata->ime_threadmgr->lpVtbl->AssociateFocus(videodata->ime_threadmgr, hwnd, NULL, &document_mgr))) { - if (document_mgr) + if (document_mgr) { document_mgr->lpVtbl->Release(document_mgr); + } } } } -static void -IME_UpdateInputLocale(SDL_VideoData *videodata) +static void IME_UpdateInputLocale(SDL_VideoData *videodata) { - static HKL hklprev = 0; - videodata->ime_hkl = GetKeyboardLayout(0); - if (hklprev == videodata->ime_hkl) + HKL hklnext = GetKeyboardLayout(0); + + if (hklnext == videodata->ime_hkl) { return; - - hklprev = videodata->ime_hkl; - switch (PRIMLANG()) { - case LANG_CHINESE: - videodata->ime_candvertical = SDL_TRUE; - if (SUBLANG() == SUBLANG_CHINESE_SIMPLIFIED) - videodata->ime_candvertical = SDL_FALSE; - - break; - case LANG_JAPANESE: - videodata->ime_candvertical = SDL_TRUE; - break; - case LANG_KOREAN: - videodata->ime_candvertical = SDL_FALSE; - break; } + + videodata->ime_hkl = hklnext; + videodata->ime_candvertical = (PRIMLANG() == LANG_KOREAN || LANG() == LANG_CHS) ? SDL_FALSE : SDL_TRUE; } -static void -IME_ClearComposition(SDL_VideoData *videodata) +static void IME_ClearComposition(SDL_VideoData *videodata) { HIMC himc = 0; - if (!videodata->ime_initialized) + if (!videodata->ime_initialized) { return; + } himc = ImmGetContext(videodata->ime_hwnd_current); - if (!himc) + if (!himc) { return; + } ImmNotifyIME(himc, NI_COMPOSITIONSTR, CPS_CANCEL, 0); - if (videodata->ime_uiless) + if (videodata->ime_uiless) { ImmSetCompositionString(himc, SCS_SETSTR, TEXT(""), sizeof(TCHAR), TEXT(""), sizeof(TCHAR)); + } ImmNotifyIME(himc, NI_CLOSECANDIDATE, 0, 0); ImmReleaseContext(videodata->ime_hwnd_current, himc); SDL_SendEditingText("", 0, 0); } -static void -IME_GetCompositionString(SDL_VideoData *videodata, HIMC himc, DWORD string) +static SDL_bool IME_IsTextInputShown(SDL_VideoData *videodata) { - LONG length = ImmGetCompositionStringW(himc, string, videodata->ime_composition, sizeof(videodata->ime_composition) - sizeof(videodata->ime_composition[0])); - if (length < 0) - length = 0; + if (!videodata->ime_initialized || !videodata->ime_available || !videodata->ime_enabled) { + return SDL_FALSE; + } - length /= sizeof(videodata->ime_composition[0]); + return videodata->ime_uicontext != 0 ? SDL_TRUE : SDL_FALSE; +} + +static void IME_GetCompositionString(SDL_VideoData *videodata, HIMC himc, DWORD string) +{ + LONG length; + DWORD dwLang = ((DWORD_PTR)videodata->ime_hkl & 0xffff); + + length = ImmGetCompositionStringW(himc, string, NULL, 0); + if (length > 0 && videodata->ime_composition_length < length) { + if (videodata->ime_composition) { + SDL_free(videodata->ime_composition); + } + + videodata->ime_composition = (WCHAR *)SDL_malloc(length + sizeof(WCHAR)); + videodata->ime_composition_length = length; + } + + length = ImmGetCompositionStringW( + himc, + string, + videodata->ime_composition, + videodata->ime_composition_length); + + if (length < 0) { + length = 0; + } + + length /= sizeof(WCHAR); videodata->ime_cursor = LOWORD(ImmGetCompositionStringW(himc, GCS_CURSORPOS, 0, 0)); - if (videodata->ime_cursor < SDL_arraysize(videodata->ime_composition) && videodata->ime_composition[videodata->ime_cursor] == 0x3000) { + if ((dwLang == LANG_CHT || dwLang == LANG_CHS) && + videodata->ime_cursor > 0 && + videodata->ime_cursor < (int)(videodata->ime_composition_length / sizeof(WCHAR)) && + (videodata->ime_composition[0] == 0x3000 || videodata->ime_composition[0] == 0x0020)) { + // Traditional Chinese IMEs add a placeholder U+3000 + // Simplified Chinese IMEs seem to add a placeholder U+0020 sometimes int i; - for (i = videodata->ime_cursor + 1; i < length; ++i) + for (i = videodata->ime_cursor + 1; i < length; ++i) { videodata->ime_composition[i - 1] = videodata->ime_composition[i]; + } --length; } + videodata->ime_composition[length] = 0; + + // Get the correct caret position if we've selected a candidate from the candidate window + if (videodata->ime_cursor == 0 && length > 0) { + Sint32 start = 0; + Sint32 end = 0; + + length = ImmGetCompositionStringW(himc, GCS_COMPATTR, NULL, 0); + if (length > 0) { + Uint8 *attributes = (Uint8 *)SDL_malloc(length + sizeof(WCHAR)); + ImmGetCompositionString(himc, GCS_COMPATTR, attributes, length); + + for (start = 0; start < length; ++start) { + if (attributes[start] == ATTR_TARGET_CONVERTED || attributes[start] == ATTR_TARGET_NOTCONVERTED) { + break; + } + } + + for (end = start; end < length; ++end) { + if (attributes[end] != ATTR_TARGET_CONVERTED && attributes[end] != ATTR_TARGET_NOTCONVERTED) { + break; + } + } + + if (start == length) { + start = 0; + end = length; + } + + SDL_free(attributes); + } + + videodata->ime_cursor = end; + } } -static void -IME_SendInputEvent(SDL_VideoData *videodata) +static void IME_SendInputEvent(SDL_VideoData *videodata) { char *s = 0; - s = WIN_StringToUTF8(videodata->ime_composition); + s = WIN_StringToUTF8W(videodata->ime_composition); SDL_SendKeyboardText(s); SDL_free(s); @@ -758,51 +863,69 @@ IME_SendInputEvent(SDL_VideoData *videodata) videodata->ime_cursor = 0; } -static void -IME_SendEditingEvent(SDL_VideoData *videodata) +static void IME_SendEditingEvent(SDL_VideoData *videodata) { - char *s = 0; - WCHAR buffer[SDL_TEXTEDITINGEVENT_TEXT_SIZE]; - const size_t size = SDL_arraysize(buffer); - buffer[0] = 0; + char *s = NULL; + WCHAR *buffer = NULL; + size_t size = videodata->ime_composition_length; if (videodata->ime_readingstring[0]) { size_t len = SDL_min(SDL_wcslen(videodata->ime_composition), (size_t)videodata->ime_cursor); + + size += sizeof(videodata->ime_readingstring); + buffer = (WCHAR *)SDL_malloc(size + sizeof(WCHAR)); + buffer[0] = 0; + SDL_wcslcpy(buffer, videodata->ime_composition, len + 1); SDL_wcslcat(buffer, videodata->ime_readingstring, size); SDL_wcslcat(buffer, &videodata->ime_composition[len], size); - } - else { + } else { + buffer = (WCHAR *)SDL_malloc(size + sizeof(WCHAR)); + buffer[0] = 0; SDL_wcslcpy(buffer, videodata->ime_composition, size); } - s = WIN_StringToUTF8(buffer); + + s = WIN_StringToUTF8W(buffer); SDL_SendEditingText(s, videodata->ime_cursor + (int)SDL_wcslen(videodata->ime_readingstring), 0); SDL_free(s); + SDL_free(buffer); } -static void -IME_AddCandidate(SDL_VideoData *videodata, UINT i, LPCWSTR candidate) +static void IME_AddCandidate(SDL_VideoData *videodata, UINT i, LPCWSTR candidate) { - LPWSTR dst = videodata->ime_candidates[i]; + LPWSTR dst = &videodata->ime_candidates[i * MAX_CANDLENGTH]; + LPWSTR end = &dst[MAX_CANDLENGTH - 1]; + SDL_COMPILE_TIME_ASSERT(IME_CANDIDATE_INDEXING_REQUIRES, MAX_CANDLIST == 10); *dst++ = (WCHAR)(TEXT('0') + ((i + videodata->ime_candlistindexbase) % 10)); - if (videodata->ime_candvertical) + if (videodata->ime_candvertical) { *dst++ = TEXT(' '); + } - while (*candidate && (SDL_arraysize(videodata->ime_candidates[i]) > (dst - videodata->ime_candidates[i]))) + while (*candidate && dst < end) { *dst++ = *candidate++; + } *dst = (WCHAR)'\0'; } -static void -IME_GetCandidateList(HIMC himc, SDL_VideoData *videodata) +static void IME_GetCandidateList(HWND hwnd, SDL_VideoData *videodata) { - LPCANDIDATELIST cand_list = 0; - DWORD size = ImmGetCandidateListW(himc, 0, 0, 0); - if (size) { + HIMC himc; + DWORD size; + LPCANDIDATELIST cand_list; + + if (IME_ShowCandidateList(videodata) < 0) { + return; + } + himc = ImmGetContext(hwnd); + if (!himc) { + return; + } + size = ImmGetCandidateListW(himc, 0, 0, 0); + if (size != 0) { cand_list = (LPCANDIDATELIST)SDL_malloc(size); - if (cand_list) { + if (cand_list != NULL) { size = ImmGetCandidateListW(himc, 0, cand_list, size); - if (size) { + if (size != 0) { UINT i, j; UINT page_start = 0; videodata->ime_candsel = cand_list->dwSelection; @@ -815,50 +938,59 @@ IME_GetCandidateList(HIMC himc, SDL_VideoData *videodata) for (i = 0; i < videodata->ime_candcount; ++i) { size_t len = SDL_wcslen((LPWSTR)((DWORD_PTR)cand_list + cand_list->dwOffset[i])) + 1; if (len + cchars > maxcandchar) { - if (i > cand_list->dwSelection) + if (i > cand_list->dwSelection) { break; + } page_start = i; cchars = len; - } - else { + } else { cchars += len; } } videodata->ime_candpgsize = i - page_start; } else { - videodata->ime_candpgsize = SDL_min(cand_list->dwPageSize, MAX_CANDLIST); - if (videodata->ime_candpgsize > 0) { - page_start = (cand_list->dwSelection / videodata->ime_candpgsize) * videodata->ime_candpgsize; - } else { - page_start = 0; - } + videodata->ime_candpgsize = SDL_min(cand_list->dwPageSize == 0 ? MAX_CANDLIST : cand_list->dwPageSize, MAX_CANDLIST); + page_start = (cand_list->dwSelection / videodata->ime_candpgsize) * videodata->ime_candpgsize; } - SDL_memset(&videodata->ime_candidates, 0, sizeof(videodata->ime_candidates)); - for (i = page_start, j = 0; (DWORD)i < cand_list->dwCount && j < (int)videodata->ime_candpgsize; i++, j++) { + for (i = page_start, j = 0; (DWORD)i < cand_list->dwCount && j < videodata->ime_candpgsize; i++, j++) { LPCWSTR candidate = (LPCWSTR)((DWORD_PTR)cand_list + cand_list->dwOffset[i]); IME_AddCandidate(videodata, j, candidate); } - if (PRIMLANG() == LANG_KOREAN || (PRIMLANG() == LANG_CHT && !IME_GetId(videodata, 0))) - videodata->ime_candsel = -1; - + // TODO: why was this necessary? check ime_candvertical instead? PRIMLANG() never equals LANG_CHT ! + // if (PRIMLANG() == LANG_KOREAN || (PRIMLANG() == LANG_CHT && !IME_GetId(videodata, 0))) + // videodata->ime_candsel = -1; } SDL_free(cand_list); } } + ImmReleaseContext(hwnd, himc); } -static void -IME_ShowCandidateList(SDL_VideoData *videodata) +static int IME_ShowCandidateList(SDL_VideoData *videodata) { + void *candidates; + + videodata->ime_candcount = 0; + candidates = SDL_realloc(videodata->ime_candidates, MAX_CANDSIZE); + if (candidates) { + videodata->ime_candidates = (WCHAR *)candidates; + } + + if (!videodata->ime_candidates) { + return -1; + } + + SDL_memset(videodata->ime_candidates, 0, MAX_CANDSIZE); + videodata->ime_dirty = SDL_TRUE; videodata->ime_candlist = SDL_TRUE; IME_DestroyTextures(videodata); IME_SendEditingEvent(videodata); + return 0; } -static void -IME_HideCandidateList(SDL_VideoData *videodata) +static void IME_HideCandidateList(SDL_VideoData *videodata) { videodata->ime_dirty = SDL_FALSE; videodata->ime_candlist = SDL_FALSE; @@ -866,34 +998,48 @@ IME_HideCandidateList(SDL_VideoData *videodata) IME_SendEditingEvent(videodata); } -SDL_bool -IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, SDL_VideoData *videodata) +SDL_bool IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, SDL_VideoData *videodata) { SDL_bool trap = SDL_FALSE; HIMC himc = 0; - if (!videodata->ime_initialized || !videodata->ime_available || !videodata->ime_enabled) + if (!videodata->ime_initialized || !videodata->ime_available || !videodata->ime_enabled) { return SDL_FALSE; + } switch (msg) { + case WM_KEYDOWN: + if (wParam == VK_PROCESSKEY) { + videodata->ime_uicontext = 1; + trap = SDL_TRUE; + } else { + videodata->ime_uicontext = 0; + } + break; case WM_INPUTLANGCHANGE: IME_InputLangChanged(videodata); break; case WM_IME_SETCONTEXT: - *lParam = 0; + if (videodata->ime_uiless) { + *lParam = 0; + } break; case WM_IME_STARTCOMPOSITION: + videodata->ime_suppress_endcomposition_event = SDL_FALSE; trap = SDL_TRUE; break; case WM_IME_COMPOSITION: trap = SDL_TRUE; himc = ImmGetContext(hwnd); if (*lParam & GCS_RESULTSTR) { + videodata->ime_suppress_endcomposition_event = SDL_TRUE; IME_GetCompositionString(videodata, himc, GCS_RESULTSTR); + SDL_SendEditingText("", 0, 0); IME_SendInputEvent(videodata); } if (*lParam & GCS_COMPSTR) { - if (!videodata->ime_uiless) + if (!videodata->ime_uiless) { videodata->ime_readingstring[0] = 0; + } IME_GetCompositionString(videodata, himc, GCS_COMPSTR); IME_SendEditingEvent(videodata); @@ -901,10 +1047,14 @@ IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, SDL_VideoD ImmReleaseContext(hwnd, himc); break; case WM_IME_ENDCOMPOSITION: + videodata->ime_uicontext = 0; videodata->ime_composition[0] = 0; videodata->ime_readingstring[0] = 0; videodata->ime_cursor = 0; - SDL_SendEditingText("", 0, 0); + if (videodata->ime_suppress_endcomposition_event == SDL_FALSE) { + SDL_SendEditingText("", 0, 0); + } + videodata->ime_suppress_endcomposition_event = SDL_FALSE; break; case WM_IME_NOTIFY: switch (wParam) { @@ -914,52 +1064,45 @@ IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, SDL_VideoD break; case IMN_OPENCANDIDATE: case IMN_CHANGECANDIDATE: - if (videodata->ime_uiless) + if (videodata->ime_uiless) { break; + } trap = SDL_TRUE; - IME_ShowCandidateList(videodata); - himc = ImmGetContext(hwnd); - if (!himc) - break; - - IME_GetCandidateList(himc, videodata); - ImmReleaseContext(hwnd, himc); + videodata->ime_uicontext = 1; + IME_GetCandidateList(hwnd, videodata); break; case IMN_CLOSECANDIDATE: trap = SDL_TRUE; + videodata->ime_uicontext = 0; IME_HideCandidateList(videodata); break; case IMN_PRIVATE: - { - DWORD dwId = IME_GetId(videodata, 0); - IME_GetReadingString(videodata, hwnd); - switch (dwId) - { - case IMEID_CHT_VER42: - case IMEID_CHT_VER43: - case IMEID_CHT_VER44: - case IMEID_CHS_VER41: - case IMEID_CHS_VER42: - if (*lParam == 1 || *lParam == 2) - trap = SDL_TRUE; - - break; - case IMEID_CHT_VER50: - case IMEID_CHT_VER51: - case IMEID_CHT_VER52: - case IMEID_CHT_VER60: - case IMEID_CHS_VER53: - if (*lParam == 16 - || *lParam == 17 - || *lParam == 26 - || *lParam == 27 - || *lParam == 28) - trap = SDL_TRUE; - break; + { + DWORD dwId = IME_GetId(videodata, 0); + IME_GetReadingString(videodata, hwnd); + switch (dwId) { + case IMEID_CHT_VER42: + case IMEID_CHT_VER43: + case IMEID_CHT_VER44: + case IMEID_CHS_VER41: + case IMEID_CHS_VER42: + if (*lParam == 1 || *lParam == 2) { + trap = SDL_TRUE; } + + break; + case IMEID_CHT_VER50: + case IMEID_CHT_VER51: + case IMEID_CHT_VER52: + case IMEID_CHT_VER60: + case IMEID_CHS_VER53: + if (*lParam == 16 || *lParam == 17 || *lParam == 26 || *lParam == 27 || *lParam == 28) { + trap = SDL_TRUE; + } + break; } - break; + } break; default: trap = SDL_TRUE; break; @@ -969,16 +1112,15 @@ IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, SDL_VideoD return trap; } -static void -IME_CloseCandidateList(SDL_VideoData *videodata) +static void IME_CloseCandidateList(SDL_VideoData *videodata) { IME_HideCandidateList(videodata); videodata->ime_candcount = 0; - SDL_memset(videodata->ime_candidates, 0, sizeof(videodata->ime_candidates)); + SDL_free(videodata->ime_candidates); + videodata->ime_candidates = NULL; } -static void -UILess_GetCandidateList(SDL_VideoData *videodata, ITfCandidateListUIElement *pcandlist) +static void UILess_GetCandidateList(SDL_VideoData *videodata, ITfCandidateListUIElement *pcandlist) { UINT selection = 0; UINT count = 0; @@ -987,13 +1129,17 @@ UILess_GetCandidateList(SDL_VideoData *videodata, ITfCandidateListUIElement *pca DWORD pgstart = 0; DWORD pgsize = 0; UINT i, j; + + if (IME_ShowCandidateList(videodata) < 0) { + return; + } + pcandlist->lpVtbl->GetSelection(pcandlist, &selection); pcandlist->lpVtbl->GetCount(pcandlist, &count); pcandlist->lpVtbl->GetCurrentPage(pcandlist, &page); videodata->ime_candsel = selection; videodata->ime_candcount = count; - IME_ShowCandidateList(videodata); pcandlist->lpVtbl->GetPageIndex(pcandlist, 0, 0, &pgcount); if (pgcount > 0) { @@ -1001,18 +1147,17 @@ UILess_GetCandidateList(SDL_VideoData *videodata, ITfCandidateListUIElement *pca if (idxlist) { pcandlist->lpVtbl->GetPageIndex(pcandlist, idxlist, pgcount, &pgcount); pgstart = idxlist[page]; - if (page < pgcount - 1) + if (page < pgcount - 1) { pgsize = SDL_min(count, idxlist[page + 1]) - pgstart; - else + } else { pgsize = count - pgstart; + } SDL_free(idxlist); } } videodata->ime_candpgsize = SDL_min(pgsize, MAX_CANDLIST); videodata->ime_candsel = videodata->ime_candsel - pgstart; - - SDL_memset(videodata->ime_candidates, 0, sizeof(videodata->ime_candidates)); for (i = pgstart, j = 0; (DWORD)i < count && j < videodata->ime_candpgsize; i++, j++) { BSTR bstr; if (SUCCEEDED(pcandlist->lpVtbl->GetString(pcandlist, i, &bstr))) { @@ -1022,16 +1167,19 @@ UILess_GetCandidateList(SDL_VideoData *videodata, ITfCandidateListUIElement *pca } } } - if (PRIMLANG() == LANG_KOREAN) - videodata->ime_candsel = -1; + // TODO: why was this necessary? check ime_candvertical instead? + // if (PRIMLANG() == LANG_KOREAN) + // videodata->ime_candsel = -1; } -STDMETHODIMP_(ULONG) TSFSink_AddRef(TSFSink *sink) +STDMETHODIMP_(ULONG) +TSFSink_AddRef(TSFSink *sink) { return ++sink->refcount; } -STDMETHODIMP_(ULONG) TSFSink_Release(TSFSink *sink) +STDMETHODIMP_(ULONG) +TSFSink_Release(TSFSink *sink) { --sink->refcount; if (sink->refcount == 0) { @@ -1043,14 +1191,16 @@ STDMETHODIMP_(ULONG) TSFSink_Release(TSFSink *sink) STDMETHODIMP UIElementSink_QueryInterface(TSFSink *sink, REFIID riid, PVOID *ppv) { - if (!ppv) + if (!ppv) { return E_INVALIDARG; + } *ppv = 0; - if (WIN_IsEqualIID(riid, &IID_IUnknown)) + if (WIN_IsEqualIID(riid, &IID_IUnknown)) { *ppv = (IUnknown *)sink; - else if (WIN_IsEqualIID(riid, &IID_ITfUIElementSink)) + } else if (WIN_IsEqualIID(riid, &IID_ITfUIElementSink)) { *ppv = (ITfUIElementSink *)sink; + } if (*ppv) { TSFSink_AddRef(sink); @@ -1078,8 +1228,9 @@ STDMETHODIMP UIElementSink_BeginUIElement(TSFSink *sink, DWORD dwUIElementId, BO ITfReadingInformationUIElement *preading = 0; ITfCandidateListUIElement *pcandlist = 0; SDL_VideoData *videodata = (SDL_VideoData *)sink->data; - if (!element) + if (!element) { return E_INVALIDARG; + } *pbShow = FALSE; if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfReadingInformationUIElement, (LPVOID *)&preading))) { @@ -1088,8 +1239,7 @@ STDMETHODIMP UIElementSink_BeginUIElement(TSFSink *sink, DWORD dwUIElementId, BO SysFreeString(bstr); } preading->lpVtbl->Release(preading); - } - else if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfCandidateListUIElement, (LPVOID *)&pcandlist))) { + } else if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfCandidateListUIElement, (LPVOID *)&pcandlist))) { videodata->ime_candref++; UILess_GetCandidateList(videodata, pcandlist); pcandlist->lpVtbl->Release(pcandlist); @@ -1103,8 +1253,9 @@ STDMETHODIMP UIElementSink_UpdateUIElement(TSFSink *sink, DWORD dwUIElementId) ITfReadingInformationUIElement *preading = 0; ITfCandidateListUIElement *pcandlist = 0; SDL_VideoData *videodata = (SDL_VideoData *)sink->data; - if (!element) + if (!element) { return E_INVALIDARG; + } if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfReadingInformationUIElement, (LPVOID *)&preading))) { BSTR bstr; @@ -1115,8 +1266,7 @@ STDMETHODIMP UIElementSink_UpdateUIElement(TSFSink *sink, DWORD dwUIElementId) SysFreeString(bstr); } preading->lpVtbl->Release(preading); - } - else if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfCandidateListUIElement, (LPVOID *)&pcandlist))) { + } else if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfCandidateListUIElement, (LPVOID *)&pcandlist))) { UILess_GetCandidateList(videodata, pcandlist); pcandlist->lpVtbl->Release(pcandlist); } @@ -1129,8 +1279,9 @@ STDMETHODIMP UIElementSink_EndUIElement(TSFSink *sink, DWORD dwUIElementId) ITfReadingInformationUIElement *preading = 0; ITfCandidateListUIElement *pcandlist = 0; SDL_VideoData *videodata = (SDL_VideoData *)sink->data; - if (!element) + if (!element) { return E_INVALIDARG; + } if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfReadingInformationUIElement, (LPVOID *)&preading))) { videodata->ime_readingstring[0] = 0; @@ -1139,8 +1290,9 @@ STDMETHODIMP UIElementSink_EndUIElement(TSFSink *sink, DWORD dwUIElementId) } if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfCandidateListUIElement, (LPVOID *)&pcandlist))) { videodata->ime_candref--; - if (videodata->ime_candref == 0) + if (videodata->ime_candref == 0) { IME_CloseCandidateList(videodata); + } pcandlist->lpVtbl->Release(pcandlist); } @@ -1149,14 +1301,16 @@ STDMETHODIMP UIElementSink_EndUIElement(TSFSink *sink, DWORD dwUIElementId) STDMETHODIMP IPPASink_QueryInterface(TSFSink *sink, REFIID riid, PVOID *ppv) { - if (!ppv) + if (!ppv) { return E_INVALIDARG; + } *ppv = 0; - if (WIN_IsEqualIID(riid, &IID_IUnknown)) + if (WIN_IsEqualIID(riid, &IID_IUnknown)) { *ppv = (IUnknown *)sink; - else if (WIN_IsEqualIID(riid, &IID_ITfInputProcessorProfileActivationSink)) + } else if (WIN_IsEqualIID(riid, &IID_ITfInputProcessorProfileActivationSink)) { *ppv = (ITfInputProcessorProfileActivationSink *)sink; + } if (*ppv) { TSFSink_AddRef(sink); @@ -1167,11 +1321,12 @@ STDMETHODIMP IPPASink_QueryInterface(TSFSink *sink, REFIID riid, PVOID *ppv) STDMETHODIMP IPPASink_OnActivated(TSFSink *sink, DWORD dwProfileType, LANGID langid, REFCLSID clsid, REFGUID catid, REFGUID guidProfile, HKL hkl, DWORD dwFlags) { - static const GUID TF_PROFILE_DAYI = { 0x037B2C25, 0x480C, 0x4D7F, { 0xB0, 0x27, 0xD6, 0xCA, 0x6B, 0x69, 0x78, 0x8A } }; + static const GUID SDL_TF_PROFILE_DAYI = { 0x037B2C25, 0x480C, 0x4D7F, { 0xB0, 0x27, 0xD6, 0xCA, 0x6B, 0x69, 0x78, 0x8A } }; SDL_VideoData *videodata = (SDL_VideoData *)sink->data; - videodata->ime_candlistindexbase = WIN_IsEqualGUID(&TF_PROFILE_DAYI, guidProfile) ? 0 : 1; - if (WIN_IsEqualIID(catid, &GUID_TFCAT_TIP_KEYBOARD) && (dwFlags & TF_IPSINK_FLAG_ACTIVE)) + videodata->ime_candlistindexbase = WIN_IsEqualGUID(&SDL_TF_PROFILE_DAYI, guidProfile) ? 0 : 1; + if (WIN_IsEqualIID(catid, &GUID_TFCAT_TIP_KEYBOARD) && (dwFlags & TF_IPSINK_FLAG_ACTIVE)) { IME_InputLangChanged((SDL_VideoData *)sink->data); + } IME_HideCandidateList(videodata); return S_OK; @@ -1193,12 +1348,12 @@ static void *vtIPPASink[] = { (void *)(IPPASink_OnActivated) }; -static void -UILess_EnableUIUpdates(SDL_VideoData *videodata) +static void UILess_EnableUIUpdates(SDL_VideoData *videodata) { ITfSource *source = 0; - if (!videodata->ime_threadmgrex || videodata->ime_uielemsinkcookie != TF_INVALID_COOKIE) + if (!videodata->ime_threadmgrex || videodata->ime_uielemsinkcookie != TF_INVALID_COOKIE) { return; + } if (SUCCEEDED(videodata->ime_threadmgrex->lpVtbl->QueryInterface(videodata->ime_threadmgrex, &IID_ITfSource, (LPVOID *)&source))) { source->lpVtbl->AdviseSink(source, &IID_ITfUIElementSink, (IUnknown *)videodata->ime_uielemsink, &videodata->ime_uielemsinkcookie); @@ -1206,12 +1361,12 @@ UILess_EnableUIUpdates(SDL_VideoData *videodata) } } -static void -UILess_DisableUIUpdates(SDL_VideoData *videodata) +static void UILess_DisableUIUpdates(SDL_VideoData *videodata) { ITfSource *source = 0; - if (!videodata->ime_threadmgrex || videodata->ime_uielemsinkcookie == TF_INVALID_COOKIE) + if (!videodata->ime_threadmgrex || videodata->ime_uielemsinkcookie == TF_INVALID_COOKIE) { return; + } if (SUCCEEDED(videodata->ime_threadmgrex->lpVtbl->QueryInterface(videodata->ime_threadmgrex, &IID_ITfSource, (LPVOID *)&source))) { source->lpVtbl->UnadviseSink(source, videodata->ime_uielemsinkcookie); @@ -1220,17 +1375,18 @@ UILess_DisableUIUpdates(SDL_VideoData *videodata) } } -static SDL_bool -UILess_SetupSinks(SDL_VideoData *videodata) +static SDL_bool UILess_SetupSinks(SDL_VideoData *videodata) { TfClientId clientid = 0; SDL_bool result = SDL_FALSE; ITfSource *source = 0; - if (FAILED(CoCreateInstance(&CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER, &IID_ITfThreadMgrEx, (LPVOID *)&videodata->ime_threadmgrex))) + if (FAILED(CoCreateInstance(&CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER, &IID_ITfThreadMgrEx, (LPVOID *)&videodata->ime_threadmgrex))) { return SDL_FALSE; + } - if (FAILED(videodata->ime_threadmgrex->lpVtbl->ActivateEx(videodata->ime_threadmgrex, &clientid, TF_TMAE_UIELEMENTENABLEDONLY))) + if (FAILED(videodata->ime_threadmgrex->lpVtbl->ActivateEx(videodata->ime_threadmgrex, &clientid, TF_TMAE_UIELEMENTENABLEDONLY))) { return SDL_FALSE; + } videodata->ime_uielemsink = SDL_malloc(sizeof(TSFSink)); videodata->ime_ippasink = SDL_malloc(sizeof(TSFSink)); @@ -1254,16 +1410,15 @@ UILess_SetupSinks(SDL_VideoData *videodata) return result; } -#define SAFE_RELEASE(p) \ -{ \ - if (p) { \ - (p)->lpVtbl->Release((p)); \ - (p) = 0; \ - } \ -} +#define SAFE_RELEASE(p) \ + { \ + if (p) { \ + (p)->lpVtbl->Release((p)); \ + (p) = 0; \ + } \ + } -static void -UILess_ReleaseSinks(SDL_VideoData *videodata) +static void UILess_ReleaseSinks(SDL_VideoData *videodata) { ITfSource *source = 0; if (videodata->ime_threadmgrex && SUCCEEDED(videodata->ime_threadmgrex->lpVtbl->QueryInterface(videodata->ime_threadmgrex, &IID_ITfSource, (LPVOID *)&source))) { @@ -1279,8 +1434,7 @@ UILess_ReleaseSinks(SDL_VideoData *videodata) } } -static void * -StartDrawToBitmap(HDC hdc, HBITMAP *hhbm, int width, int height) +static void *StartDrawToBitmap(HDC hdc, HBITMAP *hhbm, int width, int height) { BITMAPINFO info; BITMAPINFOHEADER *infoHeader = &info.bmiHeader; @@ -1289,19 +1443,19 @@ StartDrawToBitmap(HDC hdc, HBITMAP *hhbm, int width, int height) SDL_zero(info); infoHeader->biSize = sizeof(BITMAPINFOHEADER); infoHeader->biWidth = width; - infoHeader->biHeight = -1 * SDL_abs(height); + infoHeader->biHeight = (LONG)-1 * SDL_abs(height); infoHeader->biPlanes = 1; infoHeader->biBitCount = 32; infoHeader->biCompression = BI_RGB; *hhbm = CreateDIBSection(hdc, &info, DIB_RGB_COLORS, (void **)&bits, 0, 0); - if (*hhbm) + if (*hhbm) { SelectObject(hdc, *hhbm); + } } return bits; } -static void -StopDrawToBitmap(HDC hdc, HBITMAP *hhbm) +static void StopDrawToBitmap(HDC hdc, HBITMAP *hhbm) { if (hhbm && *hhbm) { DeleteObject(*hhbm); @@ -1310,8 +1464,7 @@ StopDrawToBitmap(HDC hdc, HBITMAP *hhbm) } /* This draws only within the specified area and fills the entire region. */ -static void -DrawRect(HDC hdc, int left, int top, int right, int bottom, int pensize) +static void DrawRect(HDC hdc, int left, int top, int right, int bottom, int pensize) { /* The case of no pen (PenSize = 0) is automatically taken care of. */ const int penadjust = (int)SDL_floor(pensize / 2.0f - 0.5f); @@ -1322,19 +1475,18 @@ DrawRect(HDC hdc, int left, int top, int right, int bottom, int pensize) Rectangle(hdc, left, top, right, bottom); } -static void -IME_DestroyTextures(SDL_VideoData *videodata) +static void IME_DestroyTextures(SDL_VideoData *videodata) { } -#define SDL_swap(a,b) { \ - int c = (a); \ - (a) = (b); \ - (b) = c; \ +#define SDL_swap(a, b) \ + { \ + int c = (a); \ + (a) = (b); \ + (b) = c; \ } -static void -IME_PositionCandidateList(SDL_VideoData *videodata, SIZE size) +static void IME_PositionCandidateList(SDL_VideoData *videodata, SIZE size) { int left, top, right, bottom; SDL_bool ok = SDL_FALSE; @@ -1350,8 +1502,9 @@ IME_PositionCandidateList(SDL_VideoData *videodata, SIZE size) left -= right - winw; right = winw; } - if (bottom < winh) + if (bottom < winh) { ok = SDL_TRUE; + } /* Top */ if (!ok) { @@ -1363,8 +1516,9 @@ IME_PositionCandidateList(SDL_VideoData *videodata, SIZE size) left -= right - winw; right = winw; } - if (top >= 0) + if (top >= 0) { ok = SDL_TRUE; + } } /* Right */ @@ -1373,8 +1527,9 @@ IME_PositionCandidateList(SDL_VideoData *videodata, SIZE size) top = 0; right = left + size.cx; bottom = size.cy; - if (right < winw) + if (right < winw) { ok = SDL_TRUE; + } } /* Left */ @@ -1383,8 +1538,9 @@ IME_PositionCandidateList(SDL_VideoData *videodata, SIZE size) top = 0; right = videodata->ime_rect.x; bottom = size.cy; - if (right >= 0) + if (right >= 0) { ok = SDL_TRUE; + } } /* Window too small, show at (0,0) */ @@ -1401,15 +1557,14 @@ IME_PositionCandidateList(SDL_VideoData *videodata, SIZE size) videodata->ime_candlistrect.h = bottom - top; } -static void -IME_RenderCandidateList(SDL_VideoData *videodata, HDC hdc) +static void IME_RenderCandidateList(SDL_VideoData *videodata, HDC hdc) { int i, j; - SIZE size = {0}; + SIZE size = { 0 }; SIZE candsizes[MAX_CANDLIST]; - SIZE maxcandsize = {0}; + SIZE maxcandsize = { 0 }; HBITMAP hbm = NULL; - const int candcount = SDL_min(SDL_min(MAX_CANDLIST, videodata->ime_candcount), videodata->ime_candpgsize); + int candcount = SDL_min(SDL_min(MAX_CANDLIST, videodata->ime_candcount), videodata->ime_candpgsize); SDL_bool vertical = videodata->ime_candvertical; const int listborder = 1; @@ -1440,14 +1595,15 @@ IME_RenderCandidateList(SDL_VideoData *videodata, HDC hdc) SelectObject(hdc, font); for (i = 0; i < candcount; ++i) { - const WCHAR *s = videodata->ime_candidates[i]; - if (!*s) + const WCHAR *s = &videodata->ime_candidates[i * MAX_CANDLENGTH]; + if (!*s) { + candcount = i; break; + } GetTextExtentPoint32W(hdc, s, (int)SDL_wcslen(s), &candsizes[i]); maxcandsize.cx = SDL_max(maxcandsize.cx, candsizes[i].cx); maxcandsize.cy = SDL_max(maxcandsize.cy, candsizes[i].cy); - } if (vertical) { size.cx = @@ -1456,29 +1612,26 @@ IME_RenderCandidateList(SDL_VideoData *videodata, HDC hdc) (candmargin * 2) + (candborder * 2) + (candpadding * 2) + - (maxcandsize.cx) - ; + (maxcandsize.cx); size.cy = (listborder * 2) + (listpadding * 2) + ((candcount + 1) * candmargin) + (candcount * candborder * 2) + (candcount * candpadding * 2) + - (candcount * maxcandsize.cy) - ; - } - else { + (candcount * maxcandsize.cy); + } else { size.cx = - (listborder * 2) + + (LONG)(listborder * 2) + (listpadding * 2) + ((candcount + 1) * candmargin) + (candcount * candborder * 2) + (candcount * candpadding * 2) + ((candcount - 1) * horzcandspacing); - ; - for (i = 0; i < candcount; ++i) + for (i = 0; i < candcount; ++i) { size.cx += candsizes[i].cx; + } size.cy = (listborder * 2) + @@ -1486,8 +1639,7 @@ IME_RenderCandidateList(SDL_VideoData *videodata, HDC hdc) (candmargin * 2) + (candborder * 2) + (candpadding * 2) + - (maxcandsize.cy) - ; + (maxcandsize.cy); } StartDrawToBitmap(hdc, &hbm, size.cx, size.cy); @@ -1502,22 +1654,20 @@ IME_RenderCandidateList(SDL_VideoData *videodata, HDC hdc) SetBkMode(hdc, TRANSPARENT); for (i = 0; i < candcount; ++i) { - const WCHAR *s = videodata->ime_candidates[i]; + const WCHAR *s = &videodata->ime_candidates[i * MAX_CANDLENGTH]; int left, top, right, bottom; - if (!*s) - break; if (vertical) { left = listborder + listpadding + candmargin; top = listborder + listpadding + (i * candborder * 2) + (i * candpadding * 2) + ((i + 1) * candmargin) + (i * maxcandsize.cy); right = size.cx - listborder - listpadding - candmargin; bottom = top + maxcandsize.cy + (candpadding * 2) + (candborder * 2); - } - else { + } else { left = listborder + listpadding + (i * candborder * 2) + (i * candpadding * 2) + ((i + 1) * candmargin) + (i * horzcandspacing); - for (j = 0; j < i; ++j) + for (j = 0; j < i; ++j) { left += candsizes[j].cx; + } top = listborder + listpadding + candmargin; right = left + candsizes[i].cx + (candpadding * 2) + (candborder * 2); @@ -1528,8 +1678,7 @@ IME_RenderCandidateList(SDL_VideoData *videodata, HDC hdc) SelectObject(hdc, selpen); SelectObject(hdc, selbrush); SetTextColor(hdc, seltextcolor); - } - else { + } else { SelectObject(hdc, candpen); SelectObject(hdc, candbrush); SetTextColor(hdc, candtextcolor); @@ -1551,13 +1700,13 @@ IME_RenderCandidateList(SDL_VideoData *videodata, HDC hdc) IME_PositionCandidateList(videodata, size); } -static void -IME_Render(SDL_VideoData *videodata) +static void IME_Render(SDL_VideoData *videodata) { HDC hdc = CreateCompatibleDC(NULL); - if (videodata->ime_candlist) + if (videodata->ime_candlist) { IME_RenderCandidateList(videodata, hdc); + } DeleteDC(hdc); @@ -1566,12 +1715,25 @@ IME_Render(SDL_VideoData *videodata) void IME_Present(SDL_VideoData *videodata) { - if (videodata->ime_dirty) + if (videodata->ime_dirty) { IME_Render(videodata); + } /* FIXME: Need to show the IME bitmap */ } +SDL_bool WIN_IsTextInputShown(_THIS) +{ + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + return IME_IsTextInputShown(videodata); +} + +void WIN_ClearComposition(_THIS) +{ + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + IME_ClearComposition(videodata); +} + #endif /* SDL_DISABLE_WINDOWS_IME */ #endif /* SDL_VIDEO_DRIVER_WINDOWS */ diff --git a/SDL2-2.0.12/src/video/windows/SDL_windowskeyboard.h b/SDL2-2.30.5/src/video/windows/SDL_windowskeyboard.h similarity index 83% rename from SDL2-2.0.12/src/video/windows/SDL_windowskeyboard.h rename to SDL2-2.30.5/src/video/windows/SDL_windowskeyboard.h index ec20f9a..3eb2398 100644 --- a/SDL2-2.0.12/src/video/windows/SDL_windowskeyboard.h +++ b/SDL2-2.30.5/src/video/windows/SDL_windowskeyboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -24,14 +24,16 @@ #define SDL_windowskeyboard_h_ extern void WIN_InitKeyboard(_THIS); -extern void WIN_UpdateKeymap(void); +extern void WIN_UpdateKeymap(SDL_bool send_event); extern void WIN_QuitKeyboard(_THIS); extern void WIN_ResetDeadKeys(void); extern void WIN_StartTextInput(_THIS); extern void WIN_StopTextInput(_THIS); -extern void WIN_SetTextInputRect(_THIS, SDL_Rect *rect); +extern void WIN_SetTextInputRect(_THIS, const SDL_Rect *rect); +extern void WIN_ClearComposition(_THIS); +extern SDL_bool WIN_IsTextInputShown(_THIS); extern SDL_bool IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, struct SDL_VideoData *videodata); diff --git a/SDL2-2.0.12/src/video/windows/SDL_windowsmessagebox.c b/SDL2-2.30.5/src/video/windows/SDL_windowsmessagebox.c similarity index 73% rename from SDL2-2.0.12/src/video/windows/SDL_windowsmessagebox.c rename to SDL2-2.30.5/src/video/windows/SDL_windowsmessagebox.c index b40c974..f90e0d2 100644 --- a/SDL2-2.0.12/src/video/windows/SDL_windowsmessagebox.c +++ b/SDL2-2.30.5/src/video/windows/SDL_windowsmessagebox.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,24 +20,21 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_WINDOWS +#if defined(SDL_VIDEO_DRIVER_WINDOWS) && !defined(__XBOXONE__) && !defined(__XBOXSERIES__) #ifdef HAVE_LIMITS_H #include -#else +#endif #ifndef SIZE_MAX #define SIZE_MAX ((size_t)-1) #endif -#endif #include "../../core/windows/SDL_windows.h" -#include "SDL_assert.h" #include "SDL_windowsvideo.h" -#include "SDL_windowstaskdialog.h" #ifndef SS_EDITCONTROL -#define SS_EDITCONTROL 0x2000 +#define SS_EDITCONTROL 0x2000 #endif #ifndef IDOK @@ -49,11 +46,11 @@ #endif /* Custom dialog return codes */ -#define IDCLOSED 20 -#define IDINVALPTRINIT 50 -#define IDINVALPTRCOMMAND 51 +#define IDCLOSED 20 +#define IDINVALPTRINIT 50 +#define IDINVALPTRCOMMAND 51 #define IDINVALPTRSETFOCUS 52 -#define IDINVALPTRDLGITEM 53 +#define IDINVALPTRDLGITEM 53 /* First button ID */ #define IDBUTTONINDEX0 100 @@ -67,11 +64,143 @@ */ #define MAX_BUTTONS (0xffff - 100) - /* Display a Windows message box */ +typedef HRESULT(CALLBACK *PFTASKDIALOGCALLBACK)(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, LONG_PTR lpRefData); + +enum _TASKDIALOG_FLAGS +{ + TDF_ENABLE_HYPERLINKS = 0x0001, + TDF_USE_HICON_MAIN = 0x0002, + TDF_USE_HICON_FOOTER = 0x0004, + TDF_ALLOW_DIALOG_CANCELLATION = 0x0008, + TDF_USE_COMMAND_LINKS = 0x0010, + TDF_USE_COMMAND_LINKS_NO_ICON = 0x0020, + TDF_EXPAND_FOOTER_AREA = 0x0040, + TDF_EXPANDED_BY_DEFAULT = 0x0080, + TDF_VERIFICATION_FLAG_CHECKED = 0x0100, + TDF_SHOW_PROGRESS_BAR = 0x0200, + TDF_SHOW_MARQUEE_PROGRESS_BAR = 0x0400, + TDF_CALLBACK_TIMER = 0x0800, + TDF_POSITION_RELATIVE_TO_WINDOW = 0x1000, + TDF_RTL_LAYOUT = 0x2000, + TDF_NO_DEFAULT_RADIO_BUTTON = 0x4000, + TDF_CAN_BE_MINIMIZED = 0x8000, + // #if (NTDDI_VERSION >= NTDDI_WIN8) + TDF_NO_SET_FOREGROUND = 0x00010000, // Don't call SetForegroundWindow() when activating the dialog + // #endif // (NTDDI_VERSION >= NTDDI_WIN8) + TDF_SIZE_TO_CONTENT = 0x01000000 // used by ShellMessageBox to emulate MessageBox sizing behavior +}; +typedef int TASKDIALOG_FLAGS; // Note: _TASKDIALOG_FLAGS is an int + +typedef enum _TASKDIALOG_MESSAGES +{ + TDM_NAVIGATE_PAGE = WM_USER + 101, + TDM_CLICK_BUTTON = WM_USER + 102, // wParam = Button ID + TDM_SET_MARQUEE_PROGRESS_BAR = WM_USER + 103, // wParam = 0 (nonMarque) wParam != 0 (Marquee) + TDM_SET_PROGRESS_BAR_STATE = WM_USER + 104, // wParam = new progress state + TDM_SET_PROGRESS_BAR_RANGE = WM_USER + 105, // lParam = MAKELPARAM(nMinRange, nMaxRange) + TDM_SET_PROGRESS_BAR_POS = WM_USER + 106, // wParam = new position + TDM_SET_PROGRESS_BAR_MARQUEE = WM_USER + 107, // wParam = 0 (stop marquee), wParam != 0 (start marquee), lparam = speed (milliseconds between repaints) + TDM_SET_ELEMENT_TEXT = WM_USER + 108, // wParam = element (TASKDIALOG_ELEMENTS), lParam = new element text (LPCWSTR) + TDM_CLICK_RADIO_BUTTON = WM_USER + 110, // wParam = Radio Button ID + TDM_ENABLE_BUTTON = WM_USER + 111, // lParam = 0 (disable), lParam != 0 (enable), wParam = Button ID + TDM_ENABLE_RADIO_BUTTON = WM_USER + 112, // lParam = 0 (disable), lParam != 0 (enable), wParam = Radio Button ID + TDM_CLICK_VERIFICATION = WM_USER + 113, // wParam = 0 (unchecked), 1 (checked), lParam = 1 (set key focus) + TDM_UPDATE_ELEMENT_TEXT = WM_USER + 114, // wParam = element (TASKDIALOG_ELEMENTS), lParam = new element text (LPCWSTR) + TDM_SET_BUTTON_ELEVATION_REQUIRED_STATE = WM_USER + 115, // wParam = Button ID, lParam = 0 (elevation not required), lParam != 0 (elevation required) + TDM_UPDATE_ICON = WM_USER + 116 // wParam = icon element (TASKDIALOG_ICON_ELEMENTS), lParam = new icon (hIcon if TDF_USE_HICON_* was set, PCWSTR otherwise) +} TASKDIALOG_MESSAGES; + +typedef enum _TASKDIALOG_NOTIFICATIONS +{ + TDN_CREATED = 0, + TDN_NAVIGATED = 1, + TDN_BUTTON_CLICKED = 2, // wParam = Button ID + TDN_HYPERLINK_CLICKED = 3, // lParam = (LPCWSTR)pszHREF + TDN_TIMER = 4, // wParam = Milliseconds since dialog created or timer reset + TDN_DESTROYED = 5, + TDN_RADIO_BUTTON_CLICKED = 6, // wParam = Radio Button ID + TDN_DIALOG_CONSTRUCTED = 7, + TDN_VERIFICATION_CLICKED = 8, // wParam = 1 if checkbox checked, 0 if not, lParam is unused and always 0 + TDN_HELP = 9, + TDN_EXPANDO_BUTTON_CLICKED = 10 // wParam = 0 (dialog is now collapsed), wParam != 0 (dialog is now expanded) +} TASKDIALOG_NOTIFICATIONS; + +typedef enum _TASKDIALOG_ELEMENTS +{ + TDE_CONTENT, + TDE_EXPANDED_INFORMATION, + TDE_FOOTER, + TDE_MAIN_INSTRUCTION +} TASKDIALOG_ELEMENTS; + +typedef enum _TASKDIALOG_ICON_ELEMENTS +{ + TDIE_ICON_MAIN, + TDIE_ICON_FOOTER +} TASKDIALOG_ICON_ELEMENTS; + +#define TD_WARNING_ICON MAKEINTRESOURCEW(-1) +#define TD_ERROR_ICON MAKEINTRESOURCEW(-2) +#define TD_INFORMATION_ICON MAKEINTRESOURCEW(-3) +#define TD_SHIELD_ICON MAKEINTRESOURCEW(-4) + +enum _TASKDIALOG_COMMON_BUTTON_FLAGS +{ + TDCBF_OK_BUTTON = 0x0001, // selected control return value IDOK + TDCBF_YES_BUTTON = 0x0002, // selected control return value IDYES + TDCBF_NO_BUTTON = 0x0004, // selected control return value IDNO + TDCBF_CANCEL_BUTTON = 0x0008, // selected control return value IDCANCEL + TDCBF_RETRY_BUTTON = 0x0010, // selected control return value IDRETRY + TDCBF_CLOSE_BUTTON = 0x0020 // selected control return value IDCLOSE +}; +typedef int TASKDIALOG_COMMON_BUTTON_FLAGS; // Note: _TASKDIALOG_COMMON_BUTTON_FLAGS is an int + #pragma pack(push, 1) +typedef struct _TASKDIALOG_BUTTON +{ + int nButtonID; + PCWSTR pszButtonText; +} TASKDIALOG_BUTTON; + +typedef struct _TASKDIALOGCONFIG +{ + UINT cbSize; + HWND hwndParent; // incorrectly named, this is the owner window, not a parent. + HINSTANCE hInstance; // used for MAKEINTRESOURCE() strings + TASKDIALOG_FLAGS dwFlags; // TASKDIALOG_FLAGS (TDF_XXX) flags + TASKDIALOG_COMMON_BUTTON_FLAGS dwCommonButtons; // TASKDIALOG_COMMON_BUTTON (TDCBF_XXX) flags + PCWSTR pszWindowTitle; // string or MAKEINTRESOURCE() + union + { + HICON hMainIcon; + PCWSTR pszMainIcon; + } /*DUMMYUNIONNAME*/; + PCWSTR pszMainInstruction; + PCWSTR pszContent; + UINT cButtons; + const TASKDIALOG_BUTTON *pButtons; + int nDefaultButton; + UINT cRadioButtons; + const TASKDIALOG_BUTTON *pRadioButtons; + int nDefaultRadioButton; + PCWSTR pszVerificationText; + PCWSTR pszExpandedInformation; + PCWSTR pszExpandedControlText; + PCWSTR pszCollapsedControlText; + union + { + HICON hFooterIcon; + PCWSTR pszFooterIcon; + } /*DUMMYUNIONNAME2*/; + PCWSTR pszFooter; + PFTASKDIALOGCALLBACK pfCallback; + LONG_PTR lpCallbackData; + UINT cxWidth; // width of the Task Dialog's client area in DLU's. If 0, Task Dialog will calculate the ideal width. +} TASKDIALOGCONFIG; + typedef struct { WORD dlgVer; @@ -102,7 +231,7 @@ typedef struct typedef struct { - DLGTEMPLATEEX* lpDialog; + DLGTEMPLATEEX *lpDialog; Uint8 *data; size_t size; size_t used; @@ -119,12 +248,12 @@ static SDL_bool GetButtonIndex(const SDL_MessageBoxData *messageboxdata, Uint32 return SDL_FALSE; } -static INT_PTR MessageBoxDialogProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam) +static INT_PTR CALLBACK MessageBoxDialogProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam) { const SDL_MessageBoxData *messageboxdata; size_t buttonindex; - switch ( iMessage ) { + switch (iMessage) { case WM_INITDIALOG: if (lParam == 0) { EndDialog(hDlg, IDINVALPTRINIT); @@ -136,7 +265,7 @@ static INT_PTR MessageBoxDialogProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPA if (GetButtonIndex(messageboxdata, SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, &buttonindex)) { /* Focus on the first default return-key button */ HWND buttonctl = GetDlgItem(hDlg, (int)(IDBUTTONINDEX0 + buttonindex)); - if (buttonctl == NULL) { + if (!buttonctl) { EndDialog(hDlg, IDINVALPTRDLGITEM); } PostMessage(hDlg, WM_NEXTDLGCTL, (WPARAM)buttonctl, TRUE); @@ -147,7 +276,7 @@ static INT_PTR MessageBoxDialogProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPA return FALSE; case WM_SETFOCUS: messageboxdata = (const SDL_MessageBoxData *)GetWindowLongPtr(hDlg, GWLP_USERDATA); - if (messageboxdata == NULL) { + if (!messageboxdata) { EndDialog(hDlg, IDINVALPTRSETFOCUS); return TRUE; } @@ -159,7 +288,7 @@ static INT_PTR MessageBoxDialogProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPA return TRUE; case WM_COMMAND: messageboxdata = (const SDL_MessageBoxData *)GetWindowLongPtr(hDlg, GWLP_USERDATA); - if (messageboxdata == NULL) { + if (!messageboxdata) { EndDialog(hDlg, IDINVALPTRCOMMAND); return TRUE; } @@ -221,7 +350,7 @@ static SDL_bool ExpandDialogSpace(WIN_DialogData *dialog, size_t space) } dialog->data = data; dialog->size = size; - dialog->lpDialog = (DLGTEMPLATEEX*)dialog->data; + dialog->lpDialog = (DLGTEMPLATEEX *)dialog->data; } return SDL_TRUE; } @@ -245,7 +374,7 @@ static SDL_bool AddDialogData(WIN_DialogData *dialog, const void *data, size_t s return SDL_FALSE; } - SDL_memcpy(dialog->data+dialog->used, data, size); + SDL_memcpy(dialog->data + dialog->used, data, size); dialog->used += size; return SDL_TRUE; @@ -262,7 +391,7 @@ static SDL_bool AddDialogString(WIN_DialogData *dialog, const char *string) string = ""; } - wstring = WIN_UTF8ToString(string); + wstring = WIN_UTF8ToStringW(string); if (!wstring) { return SDL_FALSE; } @@ -274,7 +403,7 @@ static SDL_bool AddDialogString(WIN_DialogData *dialog, const char *string) } ++count; - status = AddDialogData(dialog, wstring, count*sizeof(WCHAR)); + status = AddDialogData(dialog, wstring, count * sizeof(WCHAR)); SDL_free(wstring); return status; } @@ -289,7 +418,6 @@ static void Vec2ToDLU(short *x, short *y) *y = MulDiv(*y, 8, s_BaseUnitsY); } - static SDL_bool AddDialogControl(WIN_DialogData *dialog, WORD type, DWORD style, DWORD exStyle, int x, int y, int w, int h, int id, const char *caption, WORD ordinal) { DLGITEMTEMPLATEEX item; @@ -320,7 +448,7 @@ static SDL_bool AddDialogControl(WIN_DialogData *dialog, WORD type, DWORD style, if (!AddDialogData(dialog, &type, sizeof(type))) { return SDL_FALSE; } - if (type == DLGITEMTYPEBUTTON || (type == DLGITEMTYPESTATIC && caption != NULL)) { + if (type == DLGITEMTYPEBUTTON || (type == DLGITEMTYPESTATIC && caption)) { if (!AddDialogString(dialog, caption)) { return SDL_FALSE; } @@ -436,8 +564,10 @@ static WIN_DialogData *CreateDialogData(int w, int h, const char *caption) { HDC ScreenDC = GetDC(NULL); int LogicalPixelsY = GetDeviceCaps(ScreenDC, LOGPIXELSY); - if (!LogicalPixelsY) /* This can happen if the application runs out of GDI handles */ - LogicalPixelsY = 72; + if (!LogicalPixelsY) { + LogicalPixelsY = 72; /* This can happen if the application runs out of GDI handles */ + } + WordToPass = (WORD)(-72 * NCM.lfMessageFont.lfHeight / LogicalPixelsY); ReleaseDC(NULL, ScreenDC); } @@ -493,7 +623,7 @@ static const char *EscapeAmpersands(char **dst, size_t *dstlen, const char *src) size_t ampcount = 0; size_t srclen = 0; - if (src == NULL) { + if (!src) { return NULL; } @@ -512,7 +642,7 @@ static const char *EscapeAmpersands(char **dst, size_t *dstlen, const char *src) if (SIZE_MAX - srclen < ampcount) { return NULL; } - if (*dst == NULL || *dstlen < srclen + ampcount) { + if (!*dst || *dstlen < srclen + ampcount) { /* Allocating extra space in case the next strings are a bit longer. */ size_t extraspace = SIZE_MAX - (srclen + ampcount); if (extraspace > 512) { @@ -522,7 +652,7 @@ static const char *EscapeAmpersands(char **dst, size_t *dstlen, const char *src) SDL_free(*dst); *dst = NULL; newdst = SDL_malloc(*dstlen); - if (newdst == NULL) { + if (!newdst) { return NULL; } *dst = newdst; @@ -542,15 +672,14 @@ static const char *EscapeAmpersands(char **dst, size_t *dstlen, const char *src) } /* This function is called if a Task Dialog is unsupported. */ -static int -WIN_ShowOldMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) +static int WIN_ShowOldMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) { WIN_DialogData *dialog; int i, x, y, retval; HFONT DialogFont; SIZE Size; RECT TextSize; - wchar_t* wmessage; + wchar_t *wmessage; TEXTMETRIC TM; HDC FontDC; INT_PTR result; @@ -586,7 +715,6 @@ WIN_ShowOldMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) } /* Jan 25th, 2013 - dant@fleetsa.com - * * * I've tried to make this more reasonable, but I've run in to a lot * of nonsense. @@ -611,8 +739,6 @@ WIN_ShowOldMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) * somewhat correct. * * Honestly, a long term solution is to use CreateWindow, not CreateDialog. - * - * * In order to get text dimensions we need to have a DC with the desired font. * I'm assuming a dialog box in SDL is rare enough we can to the create. @@ -650,9 +776,9 @@ WIN_ShowOldMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) } /* Measure the *pixel* size of the string. */ - wmessage = WIN_UTF8ToString(messageboxdata->message); + wmessage = WIN_UTF8ToStringW(messageboxdata->message); SDL_zero(TextSize); - DrawText(FontDC, wmessage, -1, &TextSize, DT_CALCRECT | DT_LEFT | DT_NOPREFIX | DT_EDITCONTROL); + DrawTextW(FontDC, wmessage, -1, &TextSize, DT_CALCRECT | DT_LEFT | DT_NOPREFIX | DT_EDITCONTROL); /* Add margins and some padding for hangs, etc. */ TextSize.left += TextMargin; @@ -678,12 +804,13 @@ WIN_ShowOldMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) } /* Ensure the size is wide enough for all of the buttons. */ - if (Size.cx < messageboxdata->numbuttons * (ButtonWidth + ButtonMargin) + ButtonMargin) - Size.cx = messageboxdata->numbuttons * (ButtonWidth + ButtonMargin) + ButtonMargin; + if (Size.cx < (LONG)messageboxdata->numbuttons * (ButtonWidth + ButtonMargin) + ButtonMargin) { + Size.cx = (LONG)messageboxdata->numbuttons * (ButtonWidth + ButtonMargin) + ButtonMargin; + } /* Reset the height to the icon size if it is actually bigger than the text. */ - if (icon && Size.cy < IconMargin * 2 + IconHeight) { - Size.cy = IconMargin * 2 + IconHeight; + if (icon && Size.cy < (LONG)IconMargin * 2 + IconHeight) { + Size.cy = (LONG)IconMargin * 2 + IconHeight; } /* Add vertical space for the buttons and border. */ @@ -694,7 +821,7 @@ WIN_ShowOldMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) return -1; } - if (icon && ! AddDialogStaticIcon(dialog, IconMargin, IconMargin, IconWidth, IconHeight, icon)) { + if (icon && !AddDialogStaticIcon(dialog, IconMargin, IconMargin, IconWidth, IconHeight, icon)) { FreeDialogData(dialog); return -1; } @@ -731,7 +858,7 @@ WIN_ShowOldMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) buttontext = EscapeAmpersands(&escape, &escapesize, sdlButton->text); /* Make sure to provide the correct ID to keep buttons indexed in the * same order as how they are in messageboxdata. */ - if (buttontext == NULL || !AddDialogButton(dialog, x, y, ButtonWidth, ButtonHeight, buttontext, IDBUTTONINDEX0 + (int)(sdlButton - messageboxdata->buttons), isdefault)) { + if (!buttontext || !AddDialogButton(dialog, x, y, ButtonWidth, ButtonHeight, buttontext, IDBUTTONINDEX0 + (int)(sdlButton - messageboxdata->buttons), isdefault)) { FreeDialogData(dialog); SDL_free(ampescape); return -1; @@ -744,10 +871,10 @@ WIN_ShowOldMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) /* If we have a parent window, get the Instance and HWND for them * so that our little dialog gets exclusive focus at all times. */ if (messageboxdata->window) { - ParentWindow = ((SDL_WindowData*)messageboxdata->window->driverdata)->hwnd; + ParentWindow = ((SDL_WindowData *)messageboxdata->window->driverdata)->hwnd; } - result = DialogBoxIndirectParam(NULL, (DLGTEMPLATE*)dialog->lpDialog, ParentWindow, (DLGPROC)MessageBoxDialogProc, (LPARAM)messageboxdata); + result = DialogBoxIndirectParam(NULL, (DLGTEMPLATE *)dialog->lpDialog, ParentWindow, MessageBoxDialogProc, (LPARAM)messageboxdata); if (result >= IDBUTTONINDEX0 && result - IDBUTTONINDEX0 < messageboxdata->numbuttons) { *buttonid = messageboxdata->buttons[result - IDBUTTONINDEX0].buttonid; retval = 0; @@ -766,7 +893,7 @@ WIN_ShowOldMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) } else if (result == IDINVALPTRDLGITEM) { SDL_SetError("Couldn't find dialog control of the default enter-key button"); } else { - SDL_SetError("An unknown error occured"); + SDL_SetError("An unknown error occurred"); } retval = -1; } @@ -778,10 +905,11 @@ WIN_ShowOldMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) /* TaskDialogIndirect procedure * This is because SDL targets Windows XP (0x501), so this is not defined in the platform SDK. */ -typedef HRESULT(FAR WINAPI *TASKDIALOGINDIRECTPROC)(const TASKDIALOGCONFIG *pTaskConfig, int *pnButton, int *pnRadioButton, BOOL *pfVerificationFlagChecked); +/* *INDENT-OFF* */ /* clang-format off */ +typedef HRESULT (FAR WINAPI *TASKDIALOGINDIRECTPROC)(const TASKDIALOGCONFIG *pTaskConfig, int *pnButton, int *pnRadioButton, BOOL *pfVerificationFlagChecked); +/* *INDENT-ON* */ /* clang-format on */ -int -WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) +int WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) { HWND ParentWindow = NULL; wchar_t *wmessage; @@ -803,8 +931,8 @@ WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) } /* If we cannot load comctl32.dll use the old messagebox! */ - hComctl32 = LoadLibrary(TEXT("Comctl32.dll")); - if (hComctl32 == NULL) { + hComctl32 = LoadLibrary(TEXT("comctl32.dll")); + if (!hComctl32) { return WIN_ShowOldMessageBox(messageboxdata, buttonid); } @@ -815,8 +943,8 @@ WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) If you don't want to bother with manifests, put this #pragma in your app's source code somewhere: pragma comment(linker,"\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") */ - pfnTaskDialogIndirect = (TASKDIALOGINDIRECTPROC) GetProcAddress(hComctl32, "TaskDialogIndirect"); - if (pfnTaskDialogIndirect == NULL) { + pfnTaskDialogIndirect = (TASKDIALOGINDIRECTPROC)GetProcAddress(hComctl32, "TaskDialogIndirect"); + if (!pfnTaskDialogIndirect) { FreeLibrary(hComctl32); return WIN_ShowOldMessageBox(messageboxdata, buttonid); } @@ -824,14 +952,14 @@ WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) /* If we have a parent window, get the Instance and HWND for them so that our little dialog gets exclusive focus at all times. */ if (messageboxdata->window) { - ParentWindow = ((SDL_WindowData *) messageboxdata->window->driverdata)->hwnd; + ParentWindow = ((SDL_WindowData *)messageboxdata->window->driverdata)->hwnd; } - wmessage = WIN_UTF8ToString(messageboxdata->message); - wtitle = WIN_UTF8ToString(messageboxdata->title); + wmessage = WIN_UTF8ToStringW(messageboxdata->message); + wtitle = WIN_UTF8ToStringW(messageboxdata->title); SDL_zero(TaskConfig); - TaskConfig.cbSize = sizeof (TASKDIALOGCONFIG); + TaskConfig.cbSize = sizeof(TASKDIALOGCONFIG); TaskConfig.hwndParent = ParentWindow; TaskConfig.dwFlags = TDF_SIZE_TO_CONTENT; TaskConfig.pszWindowTitle = wtitle; @@ -847,11 +975,10 @@ WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) TaskConfig.pszContent = wmessage; TaskConfig.cButtons = messageboxdata->numbuttons; - pButtons = SDL_malloc(sizeof (TASKDIALOG_BUTTON) * messageboxdata->numbuttons); + pButtons = SDL_malloc(sizeof(TASKDIALOG_BUTTON) * messageboxdata->numbuttons); TaskConfig.nDefaultButton = 0; nCancelButton = 0; - for (i = 0; i < messageboxdata->numbuttons; i++) - { + for (i = 0; i < messageboxdata->numbuttons; i++) { const char *buttontext; if (messageboxdata->flags & SDL_MESSAGEBOX_BUTTONS_LEFT_TO_RIGHT) { pButton = &pButtons[i]; @@ -865,19 +992,19 @@ WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) pButton->nButtonID = IDBUTTONINDEX0 + i; } buttontext = EscapeAmpersands(&escape, &escapesize, messageboxdata->buttons[i].text); - if (buttontext == NULL) { + if (!buttontext) { int j; FreeLibrary(hComctl32); SDL_free(ampescape); SDL_free(wmessage); SDL_free(wtitle); for (j = 0; j < i; j++) { - SDL_free((wchar_t *) pButtons[j].pszButtonText); + SDL_free((wchar_t *)pButtons[j].pszButtonText); } SDL_free(pButtons); return -1; } - pButton->pszButtonText = WIN_UTF8ToString(buttontext); + pButton->pszButtonText = WIN_UTF8ToStringW(buttontext); if (messageboxdata->buttons[i].flags & SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT) { TaskConfig.nDefaultButton = pButton->nButtonID; } @@ -893,7 +1020,7 @@ WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) SDL_free(wmessage); SDL_free(wtitle); for (i = 0; i < messageboxdata->numbuttons; i++) { - SDL_free((wchar_t *) pButtons[i].pszButtonText); + SDL_free((wchar_t *)pButtons[i].pszButtonText); } SDL_free(pButtons); diff --git a/SDL2-2.0.12/src/video/windows/SDL_windowsmessagebox.h b/SDL2-2.30.5/src/video/windows/SDL_windowsmessagebox.h similarity index 91% rename from SDL2-2.0.12/src/video/windows/SDL_windowsmessagebox.h rename to SDL2-2.30.5/src/video/windows/SDL_windowsmessagebox.h index 9f1ea00..5cddc87 100644 --- a/SDL2-2.0.12/src/video/windows/SDL_windowsmessagebox.h +++ b/SDL2-2.30.5/src/video/windows/SDL_windowsmessagebox.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_WINDOWS +#if defined(SDL_VIDEO_DRIVER_WINDOWS) extern int WIN_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid); diff --git a/SDL2-2.30.5/src/video/windows/SDL_windowsmodes.c b/SDL2-2.30.5/src/video/windows/SDL_windowsmodes.c new file mode 100644 index 0000000..9a37a11 --- /dev/null +++ b/SDL2-2.30.5/src/video/windows/SDL_windowsmodes.c @@ -0,0 +1,849 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#if defined(SDL_VIDEO_DRIVER_WINDOWS) && !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + +#include "SDL_windowsvideo.h" +#include "../../events/SDL_displayevents_c.h" + +/* Windows CE compatibility */ +#ifndef CDS_FULLSCREEN +#define CDS_FULLSCREEN 0 +#endif + +/* #define DEBUG_MODES */ +/* #define HIGHDPI_DEBUG_VERBOSE */ + +static void WIN_UpdateDisplayMode(_THIS, LPCWSTR deviceName, DWORD index, SDL_DisplayMode *mode) +{ + SDL_DisplayModeData *data = (SDL_DisplayModeData *)mode->driverdata; + HDC hdc; + + data->DeviceMode.dmFields = + (DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY | + DM_DISPLAYFLAGS); + + /* NOLINTNEXTLINE(bugprone-assignment-in-if-condition): No simple way to extract the assignment */ + if (index == ENUM_CURRENT_SETTINGS && (hdc = CreateDC(deviceName, NULL, NULL, NULL)) != NULL) { + char bmi_data[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)]; + LPBITMAPINFO bmi; + HBITMAP hbm; + int logical_width = GetDeviceCaps(hdc, HORZRES); + int logical_height = GetDeviceCaps(hdc, VERTRES); + + /* High-DPI notes: + + If DPI-unaware: + - GetDeviceCaps( hdc, HORZRES ) will return the monitor width in points. + - DeviceMode.dmPelsWidth is actual pixels (unlike almost all other Windows API's, + it's not virtualized when DPI unaware). + + If DPI-aware: + - GetDeviceCaps( hdc, HORZRES ) will return pixels, same as DeviceMode.dmPelsWidth */ + mode->w = logical_width; + mode->h = logical_height; + + SDL_zeroa(bmi_data); + bmi = (LPBITMAPINFO)bmi_data; + bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + + hbm = CreateCompatibleBitmap(hdc, 1, 1); + GetDIBits(hdc, hbm, 0, 1, NULL, bmi, DIB_RGB_COLORS); + GetDIBits(hdc, hbm, 0, 1, NULL, bmi, DIB_RGB_COLORS); + DeleteObject(hbm); + DeleteDC(hdc); + if (bmi->bmiHeader.biCompression == BI_BITFIELDS) { + switch (*(Uint32 *)bmi->bmiColors) { + case 0x00FF0000: + mode->format = SDL_PIXELFORMAT_RGB888; + break; + case 0x000000FF: + mode->format = SDL_PIXELFORMAT_BGR888; + break; + case 0xF800: + mode->format = SDL_PIXELFORMAT_RGB565; + break; + case 0x7C00: + mode->format = SDL_PIXELFORMAT_RGB555; + break; + } + } else if (bmi->bmiHeader.biBitCount == 8) { + mode->format = SDL_PIXELFORMAT_INDEX8; + } else if (bmi->bmiHeader.biBitCount == 4) { + mode->format = SDL_PIXELFORMAT_INDEX4LSB; + } + } else if (mode->format == SDL_PIXELFORMAT_UNKNOWN) { + /* FIXME: Can we tell what this will be? */ + if ((data->DeviceMode.dmFields & DM_BITSPERPEL) == DM_BITSPERPEL) { + switch (data->DeviceMode.dmBitsPerPel) { + case 32: + mode->format = SDL_PIXELFORMAT_RGB888; + break; + case 24: + mode->format = SDL_PIXELFORMAT_RGB24; + break; + case 16: + mode->format = SDL_PIXELFORMAT_RGB565; + break; + case 15: + mode->format = SDL_PIXELFORMAT_RGB555; + break; + case 8: + mode->format = SDL_PIXELFORMAT_INDEX8; + break; + case 4: + mode->format = SDL_PIXELFORMAT_INDEX4LSB; + break; + } + } + } +} + +static SDL_DisplayOrientation WIN_GetDisplayOrientation(DEVMODE *mode) +{ + int width = mode->dmPelsWidth; + int height = mode->dmPelsHeight; + + /* Use unrotated width/height to guess orientation */ + if (mode->dmDisplayOrientation == DMDO_90 || mode->dmDisplayOrientation == DMDO_270) { + int temp = width; + width = height; + height = temp; + } + + if (width >= height) { + switch (mode->dmDisplayOrientation) { + case DMDO_DEFAULT: + return SDL_ORIENTATION_LANDSCAPE; + case DMDO_90: + return SDL_ORIENTATION_PORTRAIT; + case DMDO_180: + return SDL_ORIENTATION_LANDSCAPE_FLIPPED; + case DMDO_270: + return SDL_ORIENTATION_PORTRAIT_FLIPPED; + default: + return SDL_ORIENTATION_UNKNOWN; + } + } else { + switch (mode->dmDisplayOrientation) { + case DMDO_DEFAULT: + return SDL_ORIENTATION_PORTRAIT; + case DMDO_90: + return SDL_ORIENTATION_LANDSCAPE_FLIPPED; + case DMDO_180: + return SDL_ORIENTATION_PORTRAIT_FLIPPED; + case DMDO_270: + return SDL_ORIENTATION_LANDSCAPE; + default: + return SDL_ORIENTATION_UNKNOWN; + } + } +} + +static SDL_bool WIN_GetDisplayMode(_THIS, LPCWSTR deviceName, DWORD index, SDL_DisplayMode *mode, SDL_DisplayOrientation *orientation) +{ + SDL_DisplayModeData *data; + DEVMODE devmode; + + devmode.dmSize = sizeof(devmode); + devmode.dmDriverExtra = 0; + if (!EnumDisplaySettingsW(deviceName, index, &devmode)) { + return SDL_FALSE; + } + + data = (SDL_DisplayModeData *)SDL_malloc(sizeof(*data)); + if (!data) { + return SDL_FALSE; + } + + mode->driverdata = data; + data->DeviceMode = devmode; + + mode->format = SDL_PIXELFORMAT_UNKNOWN; + mode->w = data->DeviceMode.dmPelsWidth; + mode->h = data->DeviceMode.dmPelsHeight; + mode->refresh_rate = data->DeviceMode.dmDisplayFrequency; + + /* Fill in the mode information */ + WIN_UpdateDisplayMode(_this, deviceName, index, mode); + + if (orientation) { + *orientation = WIN_GetDisplayOrientation(&devmode); + } + + return SDL_TRUE; +} + +/* The win32 API calls in this function require Windows Vista or later. */ +/* *INDENT-OFF* */ /* clang-format off */ +typedef LONG (WINAPI *SDL_WIN32PROC_GetDisplayConfigBufferSizes)(UINT32 flags, UINT32* numPathArrayElements, UINT32* numModeInfoArrayElements); +typedef LONG (WINAPI *SDL_WIN32PROC_QueryDisplayConfig)(UINT32 flags, UINT32* numPathArrayElements, DISPLAYCONFIG_PATH_INFO* pathArray, UINT32* numModeInfoArrayElements, DISPLAYCONFIG_MODE_INFO* modeInfoArray, DISPLAYCONFIG_TOPOLOGY_ID* currentTopologyId); +typedef LONG (WINAPI *SDL_WIN32PROC_DisplayConfigGetDeviceInfo)(DISPLAYCONFIG_DEVICE_INFO_HEADER* requestPacket); +/* *INDENT-ON* */ /* clang-format on */ + +static char *WIN_GetDisplayNameVista(const WCHAR *deviceName) +{ + void *dll; + SDL_WIN32PROC_GetDisplayConfigBufferSizes pGetDisplayConfigBufferSizes; + SDL_WIN32PROC_QueryDisplayConfig pQueryDisplayConfig; + SDL_WIN32PROC_DisplayConfigGetDeviceInfo pDisplayConfigGetDeviceInfo; + DISPLAYCONFIG_PATH_INFO *paths = NULL; + DISPLAYCONFIG_MODE_INFO *modes = NULL; + char *retval = NULL; + UINT32 pathCount = 0; + UINT32 modeCount = 0; + UINT32 i; + LONG rc; + + dll = SDL_LoadObject("USER32.DLL"); + if (!dll) { + return NULL; + } + + pGetDisplayConfigBufferSizes = (SDL_WIN32PROC_GetDisplayConfigBufferSizes)SDL_LoadFunction(dll, "GetDisplayConfigBufferSizes"); + pQueryDisplayConfig = (SDL_WIN32PROC_QueryDisplayConfig)SDL_LoadFunction(dll, "QueryDisplayConfig"); + pDisplayConfigGetDeviceInfo = (SDL_WIN32PROC_DisplayConfigGetDeviceInfo)SDL_LoadFunction(dll, "DisplayConfigGetDeviceInfo"); + + if (!pGetDisplayConfigBufferSizes || !pQueryDisplayConfig || !pDisplayConfigGetDeviceInfo) { + goto WIN_GetDisplayNameVista_failed; + } + + do { + rc = pGetDisplayConfigBufferSizes(QDC_ONLY_ACTIVE_PATHS, &pathCount, &modeCount); + if (rc != ERROR_SUCCESS) { + goto WIN_GetDisplayNameVista_failed; + } + + SDL_free(paths); + SDL_free(modes); + + paths = (DISPLAYCONFIG_PATH_INFO *)SDL_malloc(sizeof(DISPLAYCONFIG_PATH_INFO) * pathCount); + modes = (DISPLAYCONFIG_MODE_INFO *)SDL_malloc(sizeof(DISPLAYCONFIG_MODE_INFO) * modeCount); + if ((!paths) || (!modes)) { + goto WIN_GetDisplayNameVista_failed; + } + + rc = pQueryDisplayConfig(QDC_ONLY_ACTIVE_PATHS, &pathCount, paths, &modeCount, modes, 0); + } while (rc == ERROR_INSUFFICIENT_BUFFER); + + if (rc == ERROR_SUCCESS) { + for (i = 0; i < pathCount; i++) { + DISPLAYCONFIG_SOURCE_DEVICE_NAME sourceName; + DISPLAYCONFIG_TARGET_DEVICE_NAME targetName; + + SDL_zero(sourceName); + sourceName.header.adapterId = paths[i].targetInfo.adapterId; + sourceName.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME; + sourceName.header.size = sizeof(sourceName); + sourceName.header.id = paths[i].sourceInfo.id; + rc = pDisplayConfigGetDeviceInfo(&sourceName.header); + if (rc != ERROR_SUCCESS) { + break; + } else if (SDL_wcscmp(deviceName, sourceName.viewGdiDeviceName) != 0) { + continue; + } + + SDL_zero(targetName); + targetName.header.adapterId = paths[i].targetInfo.adapterId; + targetName.header.id = paths[i].targetInfo.id; + targetName.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME; + targetName.header.size = sizeof(targetName); + rc = pDisplayConfigGetDeviceInfo(&targetName.header); + if (rc == ERROR_SUCCESS) { + retval = WIN_StringToUTF8W(targetName.monitorFriendlyDeviceName); + /* if we got an empty string, treat it as failure so we'll fallback + to getting the generic name. */ + if (retval && (*retval == '\0')) { + SDL_free(retval); + retval = NULL; + } + } + break; + } + } + + SDL_free(paths); + SDL_free(modes); + SDL_UnloadObject(dll); + return retval; + +WIN_GetDisplayNameVista_failed: + SDL_free(retval); + SDL_free(paths); + SDL_free(modes); + SDL_UnloadObject(dll); + return NULL; +} + +static void WIN_AddDisplay(_THIS, HMONITOR hMonitor, const MONITORINFOEXW *info, int *display_index, SDL_bool send_event) +{ + int i, index = *display_index; + SDL_VideoDisplay display; + SDL_DisplayData *displaydata; + SDL_DisplayMode mode; + SDL_DisplayOrientation orientation; + +#ifdef DEBUG_MODES + SDL_Log("Display: %s\n", WIN_StringToUTF8W(info->szDevice)); +#endif + + if (!WIN_GetDisplayMode(_this, info->szDevice, ENUM_CURRENT_SETTINGS, &mode, &orientation)) { + return; + } + + // Prevent adding duplicate displays. Do this after we know the display is + // ready to be added to allow any displays that we can't fully query to be + // removed + for (i = 0; i < _this->num_displays; ++i) { + SDL_DisplayData *driverdata = (SDL_DisplayData *)_this->displays[i].driverdata; + if (SDL_wcscmp(driverdata->DeviceName, info->szDevice) == 0) { + SDL_bool moved = (index != i); + + if (index >= _this->num_displays) { + return; + } + + if (moved) { + SDL_VideoDisplay tmp; + + SDL_memcpy(&tmp, &_this->displays[index], sizeof(tmp)); + SDL_memcpy(&_this->displays[index], &_this->displays[i], sizeof(tmp)); + SDL_memcpy(&_this->displays[i], &tmp, sizeof(tmp)); + i = index; + } + + driverdata->MonitorHandle = hMonitor; + driverdata->IsValid = SDL_TRUE; + + if (!_this->setting_display_mode) { + SDL_Rect bounds; + + SDL_ResetDisplayModes(i); + SDL_SetCurrentDisplayMode(&_this->displays[i], &mode); + SDL_SetDesktopDisplayMode(&_this->displays[i], &mode); + if (WIN_GetDisplayBounds(_this, &_this->displays[i], &bounds) == 0) { + if (SDL_memcmp(&driverdata->bounds, &bounds, sizeof(bounds)) != 0 || moved) { + SDL_SendDisplayEvent(&_this->displays[i], SDL_DISPLAYEVENT_MOVED, 0); + } + } + SDL_SendDisplayEvent(&_this->displays[i], SDL_DISPLAYEVENT_ORIENTATION, orientation); + } + goto done; + } + } + + displaydata = (SDL_DisplayData *)SDL_calloc(1, sizeof(*displaydata)); + if (!displaydata) { + return; + } + SDL_memcpy(displaydata->DeviceName, info->szDevice, sizeof(displaydata->DeviceName)); + displaydata->MonitorHandle = hMonitor; + displaydata->IsValid = SDL_TRUE; + + SDL_zero(display); + display.name = WIN_GetDisplayNameVista(info->szDevice); + if (!display.name) { + DISPLAY_DEVICEW device; + SDL_zero(device); + device.cb = sizeof(device); + if (EnumDisplayDevicesW(info->szDevice, 0, &device, 0)) { + display.name = WIN_StringToUTF8W(device.DeviceString); + } + } + + display.desktop_mode = mode; + display.current_mode = mode; + display.orientation = orientation; + display.device = _this; + display.driverdata = displaydata; + WIN_GetDisplayBounds(_this, &display, &displaydata->bounds); + index = SDL_AddVideoDisplay(&display, send_event); + SDL_assert(index == *display_index); + SDL_free(display.name); + +done: + *display_index += 1; +} + +typedef struct _WIN_AddDisplaysData +{ + SDL_VideoDevice *video_device; + int display_index; + SDL_bool send_event; + SDL_bool want_primary; +} WIN_AddDisplaysData; + +static BOOL CALLBACK WIN_AddDisplaysCallback(HMONITOR hMonitor, + HDC hdcMonitor, + LPRECT lprcMonitor, + LPARAM dwData) +{ + WIN_AddDisplaysData *data = (WIN_AddDisplaysData *)dwData; + MONITORINFOEXW info; + + SDL_zero(info); + info.cbSize = sizeof(info); + + if (GetMonitorInfoW(hMonitor, (LPMONITORINFO)&info) != 0) { + const SDL_bool is_primary = ((info.dwFlags & MONITORINFOF_PRIMARY) == MONITORINFOF_PRIMARY); + + if (is_primary == data->want_primary) { + WIN_AddDisplay(data->video_device, hMonitor, &info, &data->display_index, data->send_event); + } + } + + // continue enumeration + return TRUE; +} + +static void WIN_AddDisplays(_THIS, SDL_bool send_event) +{ + WIN_AddDisplaysData callback_data; + callback_data.video_device = _this; + callback_data.display_index = 0; + callback_data.send_event = send_event; + + callback_data.want_primary = SDL_TRUE; + EnumDisplayMonitors(NULL, NULL, WIN_AddDisplaysCallback, (LPARAM)&callback_data); + + callback_data.want_primary = SDL_FALSE; + EnumDisplayMonitors(NULL, NULL, WIN_AddDisplaysCallback, (LPARAM)&callback_data); +} + +int WIN_InitModes(_THIS) +{ + WIN_AddDisplays(_this, SDL_FALSE); + + if (_this->num_displays == 0) { + return SDL_SetError("No displays available"); + } + return 0; +} + +/** + * Convert the monitor rect and work rect from pixels to the SDL coordinate system (monitor origins are in pixels, + * monitor size in DPI-scaled points). + * + * No-op if DPI scaling is not enabled. + */ +static void WIN_MonitorInfoToSDL(const SDL_VideoData *videodata, HMONITOR monitor, MONITORINFO *info) +{ + UINT xdpi, ydpi; + + if (!videodata->dpi_scaling_enabled) { + return; + } + + /* Check for Windows < 8.1*/ + if (!videodata->GetDpiForMonitor) { + return; + } + if (videodata->GetDpiForMonitor(monitor, MDT_EFFECTIVE_DPI, &xdpi, &ydpi) != S_OK) { + /* Shouldn't happen? */ + return; + } + + /* Convert monitor size to points, leaving the monitor position in pixels */ + info->rcMonitor.right = info->rcMonitor.left + MulDiv(info->rcMonitor.right - info->rcMonitor.left, 96, xdpi); + info->rcMonitor.bottom = info->rcMonitor.top + MulDiv(info->rcMonitor.bottom - info->rcMonitor.top, 96, ydpi); + + /* Convert monitor work rect to points */ + info->rcWork.left = info->rcMonitor.left + MulDiv(info->rcWork.left - info->rcMonitor.left, 96, xdpi); + info->rcWork.right = info->rcMonitor.left + MulDiv(info->rcWork.right - info->rcMonitor.left, 96, xdpi); + info->rcWork.top = info->rcMonitor.top + MulDiv(info->rcWork.top - info->rcMonitor.top, 96, ydpi); + info->rcWork.bottom = info->rcMonitor.top + MulDiv(info->rcWork.bottom - info->rcMonitor.top, 96, ydpi); +} + +int WIN_GetDisplayBounds(_THIS, SDL_VideoDisplay *display, SDL_Rect *rect) +{ + const SDL_DisplayData *data = (const SDL_DisplayData *)display->driverdata; + const SDL_VideoData *videodata = (SDL_VideoData *)display->device->driverdata; + MONITORINFO minfo; + BOOL rc; + + SDL_zero(minfo); + minfo.cbSize = sizeof(MONITORINFO); + rc = GetMonitorInfo(data->MonitorHandle, &minfo); + + if (!rc) { + return SDL_SetError("Couldn't find monitor data"); + } + + WIN_MonitorInfoToSDL(videodata, data->MonitorHandle, &minfo); + rect->x = minfo.rcMonitor.left; + rect->y = minfo.rcMonitor.top; + rect->w = minfo.rcMonitor.right - minfo.rcMonitor.left; + rect->h = minfo.rcMonitor.bottom - minfo.rcMonitor.top; + + return 0; +} + +int WIN_GetDisplayDPI(_THIS, SDL_VideoDisplay *display, float *ddpi_out, float *hdpi_out, float *vdpi_out) +{ + const SDL_DisplayData *displaydata = (SDL_DisplayData *)display->driverdata; + const SDL_VideoData *videodata = (SDL_VideoData *)display->device->driverdata; + float hdpi = 0, vdpi = 0, ddpi = 0; + + if (videodata->GetDpiForMonitor) { + UINT hdpi_uint, vdpi_uint; + // Windows 8.1+ codepath + if (videodata->GetDpiForMonitor(displaydata->MonitorHandle, MDT_EFFECTIVE_DPI, &hdpi_uint, &vdpi_uint) == S_OK) { + // GetDpiForMonitor docs promise to return the same hdpi/vdpi + hdpi = (float)hdpi_uint; + vdpi = (float)hdpi_uint; + ddpi = (float)hdpi_uint; + } else { + return SDL_SetError("GetDpiForMonitor failed"); + } + } else { + // Window 8.0 and below: same DPI for all monitors. + HDC hdc; + int hdpi_int, vdpi_int, hpoints, vpoints, hpix, vpix; + float hinches, vinches; + + hdc = GetDC(NULL); + if (!hdc) { + return SDL_SetError("GetDC failed"); + } + hdpi_int = GetDeviceCaps(hdc, LOGPIXELSX); + vdpi_int = GetDeviceCaps(hdc, LOGPIXELSY); + ReleaseDC(NULL, hdc); + + hpoints = GetSystemMetrics(SM_CXVIRTUALSCREEN); + vpoints = GetSystemMetrics(SM_CYVIRTUALSCREEN); + + hpix = MulDiv(hpoints, hdpi_int, 96); + vpix = MulDiv(vpoints, vdpi_int, 96); + + hinches = (float)hpoints / 96.0f; + vinches = (float)vpoints / 96.0f; + + hdpi = (float)hdpi_int; + vdpi = (float)vdpi_int; + ddpi = SDL_ComputeDiagonalDPI(hpix, vpix, hinches, vinches); + } + + if (ddpi_out) { + *ddpi_out = ddpi; + } + if (hdpi_out) { + *hdpi_out = hdpi; + } + if (vdpi_out) { + *vdpi_out = vdpi; + } + + return ddpi != 0.0f ? 0 : SDL_SetError("Couldn't get DPI"); +} + +int WIN_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay *display, SDL_Rect *rect) +{ + const SDL_DisplayData *data = (const SDL_DisplayData *)display->driverdata; + const SDL_VideoData *videodata = (SDL_VideoData *)display->device->driverdata; + MONITORINFO minfo; + BOOL rc; + + SDL_zero(minfo); + minfo.cbSize = sizeof(MONITORINFO); + rc = GetMonitorInfo(data->MonitorHandle, &minfo); + + if (!rc) { + return SDL_SetError("Couldn't find monitor data"); + } + + WIN_MonitorInfoToSDL(videodata, data->MonitorHandle, &minfo); + rect->x = minfo.rcWork.left; + rect->y = minfo.rcWork.top; + rect->w = minfo.rcWork.right - minfo.rcWork.left; + rect->h = minfo.rcWork.bottom - minfo.rcWork.top; + + return 0; +} + +/** + * Convert a point from the SDL coordinate system (monitor origins are in pixels, + * offset within a monitor in DPI-scaled points) to Windows virtual screen coordinates (pixels). + * + * No-op if DPI scaling is not enabled (returns 96 dpi). + * + * Returns the DPI of the monitor that was closest to x, y and used for the conversion. + */ +void WIN_ScreenPointFromSDL(int *x, int *y, int *dpiOut) +{ + const SDL_VideoDevice *videodevice = SDL_GetVideoDevice(); + const SDL_VideoData *videodata; + int displayIndex; + SDL_Rect bounds; + float ddpi, hdpi, vdpi; + int x_sdl, y_sdl; + SDL_Point point; + point.x = *x; + point.y = *y; + + if (dpiOut) { + *dpiOut = 96; + } + + if (!videodevice || !videodevice->driverdata) { + return; + } + + videodata = (SDL_VideoData *)videodevice->driverdata; + if (!videodata->dpi_scaling_enabled) { + return; + } + + /* Can't use MonitorFromPoint for this because we currently have SDL coordinates, not pixels */ + displayIndex = SDL_GetPointDisplayIndex(&point); + + if (displayIndex < 0) { + return; + } + + if (SDL_GetDisplayBounds(displayIndex, &bounds) < 0 || SDL_GetDisplayDPI(displayIndex, &ddpi, &hdpi, &vdpi) < 0) { + return; + } + + if (dpiOut) { + *dpiOut = (int)ddpi; + } + + /* Undo the DPI-scaling within the monitor bounds to convert back to pixels */ + x_sdl = *x; + y_sdl = *y; + *x = bounds.x + MulDiv(x_sdl - bounds.x, (int)ddpi, 96); + *y = bounds.y + MulDiv(y_sdl - bounds.y, (int)ddpi, 96); + +#ifdef HIGHDPI_DEBUG_VERBOSE + SDL_Log("WIN_ScreenPointFromSDL: (%d, %d) points -> (%d x %d) pixels, using %d DPI monitor", + x_sdl, y_sdl, *x, *y, (int)ddpi); +#endif +} + +/** + * Convert a point from Windows virtual screen coordinates (pixels) to the SDL + * coordinate system (monitor origins are in pixels, offset within a monitor in DPI-scaled points). + * + * No-op if DPI scaling is not enabled. + */ +void WIN_ScreenPointToSDL(int *x, int *y) +{ + const SDL_VideoDevice *videodevice = SDL_GetVideoDevice(); + const SDL_VideoData *videodata; + POINT point; + HMONITOR monitor; + int i, displayIndex; + SDL_Rect bounds; + float ddpi, hdpi, vdpi; + int x_pixels, y_pixels; + + if (!videodevice || !videodevice->driverdata) { + return; + } + + videodata = (SDL_VideoData *)videodevice->driverdata; + if (!videodata->dpi_scaling_enabled) { + return; + } + + point.x = *x; + point.y = *y; + monitor = MonitorFromPoint(point, MONITOR_DEFAULTTONEAREST); + + /* Search for the corresponding SDL monitor */ + displayIndex = -1; + for (i = 0; i < videodevice->num_displays; ++i) { + SDL_DisplayData *driverdata = (SDL_DisplayData *)videodevice->displays[i].driverdata; + if (driverdata->MonitorHandle == monitor) { + displayIndex = i; + } + } + if (displayIndex == -1) { + return; + } + + /* Get SDL display properties */ + if (SDL_GetDisplayBounds(displayIndex, &bounds) < 0 || SDL_GetDisplayDPI(displayIndex, &ddpi, &hdpi, &vdpi) < 0) { + return; + } + + /* Convert the point's offset within the monitor from pixels to DPI-scaled points */ + x_pixels = *x; + y_pixels = *y; + *x = bounds.x + MulDiv(x_pixels - bounds.x, 96, (int)ddpi); + *y = bounds.y + MulDiv(y_pixels - bounds.y, 96, (int)ddpi); + +#ifdef HIGHDPI_DEBUG_VERBOSE + SDL_Log("WIN_ScreenPointToSDL: (%d, %d) pixels -> (%d x %d) points, using %d DPI monitor", + x_pixels, y_pixels, *x, *y, (int)ddpi); +#endif +} + +void WIN_GetDisplayModes(_THIS, SDL_VideoDisplay *display) +{ + SDL_DisplayData *data = (SDL_DisplayData *)display->driverdata; + DWORD i; + SDL_DisplayMode mode; + + for (i = 0;; ++i) { + if (!WIN_GetDisplayMode(_this, data->DeviceName, i, &mode, NULL)) { + break; + } + if (SDL_ISPIXELFORMAT_INDEXED(mode.format)) { + /* We don't support palettized modes now */ + SDL_free(mode.driverdata); + continue; + } + if (mode.format != SDL_PIXELFORMAT_UNKNOWN) { + if (!SDL_AddDisplayMode(display, &mode)) { + SDL_free(mode.driverdata); + } + } else { + SDL_free(mode.driverdata); + } + } +} + +#ifdef DEBUG_MODES +static void WIN_LogMonitor(_THIS, HMONITOR mon) +{ + const SDL_VideoData *vid_data = (const SDL_VideoData *)_this->driverdata; + MONITORINFOEX minfo; + UINT xdpi = 0, ydpi = 0; + char *name_utf8; + + if (vid_data->GetDpiForMonitor) { + vid_data->GetDpiForMonitor(mon, MDT_EFFECTIVE_DPI, &xdpi, &ydpi); + } + + SDL_zero(minfo); + minfo.cbSize = sizeof(minfo); + GetMonitorInfo(mon, (LPMONITORINFO)&minfo); + + name_utf8 = WIN_StringToUTF8(minfo.szDevice); + + SDL_Log("WIN_LogMonitor: monitor \"%s\": dpi: %d windows screen coordinates: %d, %d, %dx%d", + name_utf8, + xdpi, + minfo.rcMonitor.left, + minfo.rcMonitor.top, + minfo.rcMonitor.right - minfo.rcMonitor.left, + minfo.rcMonitor.bottom - minfo.rcMonitor.top); + + SDL_free(name_utf8); +} +#endif + +int WIN_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode) +{ + SDL_DisplayData *displaydata = (SDL_DisplayData *)display->driverdata; + SDL_DisplayModeData *data = (SDL_DisplayModeData *)mode->driverdata; + LONG status; + +#ifdef DEBUG_MODES + SDL_Log("WIN_SetDisplayMode: monitor state before mode change:"); + WIN_LogMonitor(_this, displaydata->MonitorHandle); +#endif + + /* High-DPI notes: + + - ChangeDisplaySettingsEx always takes pixels. + - e.g. if the display is set to 2880x1800 with 200% scaling in Display Settings + - calling ChangeDisplaySettingsEx with a dmPelsWidth/Height other than 2880x1800 will + change the monitor DPI to 96. (100% scaling) + - calling ChangeDisplaySettingsEx with a dmPelsWidth/Height of 2880x1800 (or a NULL DEVMODE*) will + reset the monitor DPI to 192. (200% scaling) + + NOTE: these are temporary changes in DPI, not modifications to the Control Panel setting. */ + if (mode->driverdata == display->desktop_mode.driverdata) { +#ifdef DEBUG_MODES + SDL_Log("WIN_SetDisplayMode: resetting to original resolution"); +#endif + status = ChangeDisplaySettingsExW(displaydata->DeviceName, NULL, NULL, CDS_FULLSCREEN, NULL); + } else { +#ifdef DEBUG_MODES + SDL_Log("WIN_SetDisplayMode: changing to %dx%d pixels", data->DeviceMode.dmPelsWidth, data->DeviceMode.dmPelsHeight); +#endif + status = ChangeDisplaySettingsExW(displaydata->DeviceName, &data->DeviceMode, NULL, CDS_FULLSCREEN, NULL); + } + if (status != DISP_CHANGE_SUCCESSFUL) { + const char *reason = "Unknown reason"; + switch (status) { + case DISP_CHANGE_BADFLAGS: + reason = "DISP_CHANGE_BADFLAGS"; + break; + case DISP_CHANGE_BADMODE: + reason = "DISP_CHANGE_BADMODE"; + break; + case DISP_CHANGE_BADPARAM: + reason = "DISP_CHANGE_BADPARAM"; + break; + case DISP_CHANGE_FAILED: + reason = "DISP_CHANGE_FAILED"; + break; + } + return SDL_SetError("ChangeDisplaySettingsEx() failed: %s", reason); + } + +#ifdef DEBUG_MODES + SDL_Log("WIN_SetDisplayMode: monitor state after mode change:"); + WIN_LogMonitor(_this, displaydata->MonitorHandle); +#endif + + EnumDisplaySettingsW(displaydata->DeviceName, ENUM_CURRENT_SETTINGS, &data->DeviceMode); + WIN_UpdateDisplayMode(_this, displaydata->DeviceName, ENUM_CURRENT_SETTINGS, mode); + return 0; +} + +void WIN_RefreshDisplays(_THIS) +{ + int i; + + // Mark all displays as potentially invalid to detect + // entries that have actually been removed + for (i = 0; i < _this->num_displays; ++i) { + SDL_DisplayData *driverdata = (SDL_DisplayData *)_this->displays[i].driverdata; + driverdata->IsValid = SDL_FALSE; + } + + // Enumerate displays to add any new ones and mark still + // connected entries as valid + WIN_AddDisplays(_this, SDL_TRUE); + + // Delete any entries still marked as invalid, iterate + // in reverse as each delete takes effect immediately + for (i = _this->num_displays - 1; i >= 0; --i) { + SDL_DisplayData *driverdata = (SDL_DisplayData *)_this->displays[i].driverdata; + if (driverdata->IsValid == SDL_FALSE) { + SDL_DelVideoDisplay(i); + } + } +} + +void WIN_QuitModes(_THIS) +{ + /* All fullscreen windows should have restored modes by now */ +} + +#endif /* SDL_VIDEO_DRIVER_WINDOWS */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/windows/SDL_windowsmodes.h b/SDL2-2.30.5/src/video/windows/SDL_windowsmodes.h similarity index 63% rename from SDL2-2.0.12/src/video/windows/SDL_windowsmodes.h rename to SDL2-2.30.5/src/video/windows/SDL_windowsmodes.h index a89159a..9cec89e 100644 --- a/SDL2-2.0.12/src/video/windows/SDL_windowsmodes.h +++ b/SDL2-2.30.5/src/video/windows/SDL_windowsmodes.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -25,8 +25,10 @@ typedef struct { - TCHAR DeviceName[32]; + WCHAR DeviceName[32]; HMONITOR MonitorHandle; + SDL_bool IsValid; + SDL_Rect bounds; } SDL_DisplayData; typedef struct @@ -35,11 +37,14 @@ typedef struct } SDL_DisplayModeData; extern int WIN_InitModes(_THIS); -extern int WIN_GetDisplayBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect); -extern int WIN_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect); -extern int WIN_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi, float * hdpi, float * vdpi); -extern void WIN_GetDisplayModes(_THIS, SDL_VideoDisplay * display); -extern int WIN_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode); +extern int WIN_GetDisplayBounds(_THIS, SDL_VideoDisplay *display, SDL_Rect *rect); +extern int WIN_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay *display, SDL_Rect *rect); +extern void WIN_ScreenPointFromSDL(int *x, int *y, int *dpiOut); +extern void WIN_ScreenPointToSDL(int *x, int *y); +extern int WIN_GetDisplayDPI(_THIS, SDL_VideoDisplay *display, float *ddpi, float *hdpi, float *vdpi); +extern void WIN_GetDisplayModes(_THIS, SDL_VideoDisplay *display); +extern int WIN_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode); +extern void WIN_RefreshDisplays(_THIS); extern void WIN_QuitModes(_THIS); #endif /* SDL_windowsmodes_h_ */ diff --git a/SDL2-2.30.5/src/video/windows/SDL_windowsmouse.c b/SDL2-2.30.5/src/video/windows/SDL_windowsmouse.c new file mode 100644 index 0000000..214197b --- /dev/null +++ b/SDL2-2.30.5/src/video/windows/SDL_windowsmouse.c @@ -0,0 +1,494 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#if defined(SDL_VIDEO_DRIVER_WINDOWS) && !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + +#include "SDL_windowsvideo.h" + +#include "../../events/SDL_mouse_c.h" + +DWORD SDL_last_warp_time = 0; +HCURSOR SDL_cursor = NULL; +static SDL_Cursor *SDL_blank_cursor = NULL; + +static int rawInputEnableCount = 0; + +static int ToggleRawInput(SDL_bool enabled) +{ + RAWINPUTDEVICE rawMouse = { 0x01, 0x02, 0, NULL }; /* Mouse: UsagePage = 1, Usage = 2 */ + + if (enabled) { + rawInputEnableCount++; + if (rawInputEnableCount > 1) { + return 0; /* already done. */ + } + } else { + if (rawInputEnableCount == 0) { + return 0; /* already done. */ + } + rawInputEnableCount--; + if (rawInputEnableCount > 0) { + return 0; /* not time to disable yet */ + } + } + + if (!enabled) { + rawMouse.dwFlags |= RIDEV_REMOVE; + } + + /* (Un)register raw input for mice */ + if (RegisterRawInputDevices(&rawMouse, 1, sizeof(RAWINPUTDEVICE)) == FALSE) { + /* Reset the enable count, otherwise subsequent enable calls will + believe raw input is enabled */ + rawInputEnableCount = 0; + + /* Only return an error when registering. If we unregister and fail, + then it's probably that we unregistered twice. That's OK. */ + if (enabled) { + return SDL_Unsupported(); + } + } + return 0; +} + +static SDL_Cursor *WIN_CreateDefaultCursor() +{ + SDL_Cursor *cursor; + + cursor = SDL_calloc(1, sizeof(*cursor)); + if (cursor) { + cursor->driverdata = LoadCursor(NULL, IDC_ARROW); + } else { + SDL_OutOfMemory(); + } + + return cursor; +} + +static SDL_Cursor *WIN_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y) +{ + /* msdn says cursor mask has to be padded out to word alignment. Not sure + if that means machine word or WORD, but this handles either case. */ + const size_t pad = (sizeof(size_t) * 8); /* 32 or 64, or whatever. */ + SDL_Cursor *cursor; + HICON hicon; + HICON hcursor; + HDC hdc; + BITMAPV4HEADER bmh; + LPVOID pixels; + LPVOID maskbits; + size_t maskbitslen; + SDL_bool isstack; + ICONINFO ii; + + SDL_zero(bmh); + bmh.bV4Size = sizeof(bmh); + bmh.bV4Width = surface->w; + bmh.bV4Height = -surface->h; /* Invert the image */ + bmh.bV4Planes = 1; + bmh.bV4BitCount = 32; + bmh.bV4V4Compression = BI_BITFIELDS; + bmh.bV4AlphaMask = 0xFF000000; + bmh.bV4RedMask = 0x00FF0000; + bmh.bV4GreenMask = 0x0000FF00; + bmh.bV4BlueMask = 0x000000FF; + + maskbitslen = ((surface->w + (pad - (surface->w % pad))) / 8) * surface->h; + maskbits = SDL_small_alloc(Uint8, maskbitslen, &isstack); + if (!maskbits) { + SDL_OutOfMemory(); + return NULL; + } + + /* AND the cursor against full bits: no change. We already have alpha. */ + SDL_memset(maskbits, 0xFF, maskbitslen); + + hdc = GetDC(NULL); + SDL_zero(ii); + ii.fIcon = FALSE; + ii.xHotspot = (DWORD)hot_x; + ii.yHotspot = (DWORD)hot_y; + ii.hbmColor = CreateDIBSection(hdc, (BITMAPINFO *)&bmh, DIB_RGB_COLORS, &pixels, NULL, 0); + ii.hbmMask = CreateBitmap(surface->w, surface->h, 1, 1, maskbits); + ReleaseDC(NULL, hdc); + SDL_small_free(maskbits, isstack); + + SDL_assert(surface->format->format == SDL_PIXELFORMAT_ARGB8888); + SDL_assert(surface->pitch == surface->w * 4); + SDL_memcpy(pixels, surface->pixels, (size_t)surface->h * surface->pitch); + + hicon = CreateIconIndirect(&ii); + + DeleteObject(ii.hbmColor); + DeleteObject(ii.hbmMask); + + if (!hicon) { + WIN_SetError("CreateIconIndirect()"); + return NULL; + } + + /* The cursor returned by CreateIconIndirect does not respect system cursor size + preference, use CopyImage to duplicate the cursor with desired sizes */ + hcursor = CopyImage(hicon, IMAGE_CURSOR, surface->w, surface->h, 0); + DestroyIcon(hicon); + + if (!hcursor) { + WIN_SetError("CopyImage()"); + return NULL; + } + + cursor = SDL_calloc(1, sizeof(*cursor)); + if (cursor) { + cursor->driverdata = hcursor; + } else { + DestroyIcon(hcursor); + SDL_OutOfMemory(); + } + + return cursor; +} + +static SDL_Cursor *WIN_CreateBlankCursor() +{ + SDL_Cursor *cursor = NULL; + SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormat(0, 32, 32, 32, SDL_PIXELFORMAT_ARGB8888); + if (surface) { + cursor = WIN_CreateCursor(surface, 0, 0); + SDL_FreeSurface(surface); + } + return cursor; +} + +static SDL_Cursor *WIN_CreateSystemCursor(SDL_SystemCursor id) +{ + SDL_Cursor *cursor; + LPCTSTR name; + + switch (id) { + default: + SDL_assert(0); + return NULL; + case SDL_SYSTEM_CURSOR_ARROW: + name = IDC_ARROW; + break; + case SDL_SYSTEM_CURSOR_IBEAM: + name = IDC_IBEAM; + break; + case SDL_SYSTEM_CURSOR_WAIT: + name = IDC_WAIT; + break; + case SDL_SYSTEM_CURSOR_CROSSHAIR: + name = IDC_CROSS; + break; + case SDL_SYSTEM_CURSOR_WAITARROW: + name = IDC_WAIT; + break; + case SDL_SYSTEM_CURSOR_SIZENWSE: + name = IDC_SIZENWSE; + break; + case SDL_SYSTEM_CURSOR_SIZENESW: + name = IDC_SIZENESW; + break; + case SDL_SYSTEM_CURSOR_SIZEWE: + name = IDC_SIZEWE; + break; + case SDL_SYSTEM_CURSOR_SIZENS: + name = IDC_SIZENS; + break; + case SDL_SYSTEM_CURSOR_SIZEALL: + name = IDC_SIZEALL; + break; + case SDL_SYSTEM_CURSOR_NO: + name = IDC_NO; + break; + case SDL_SYSTEM_CURSOR_HAND: + name = IDC_HAND; + break; + } + + cursor = SDL_calloc(1, sizeof(*cursor)); + if (cursor) { + HICON hicon; + + hicon = LoadCursor(NULL, name); + + cursor->driverdata = hicon; + } else { + SDL_OutOfMemory(); + } + + return cursor; +} + +static void WIN_FreeCursor(SDL_Cursor *cursor) +{ + HICON hicon = (HICON)cursor->driverdata; + + DestroyIcon(hicon); + SDL_free(cursor); +} + +static int WIN_ShowCursor(SDL_Cursor *cursor) +{ + if (!cursor) { + cursor = SDL_blank_cursor; + } + if (cursor) { + SDL_cursor = (HCURSOR)cursor->driverdata; + } else { + SDL_cursor = NULL; + } + if (SDL_GetMouseFocus() != NULL) { + SetCursor(SDL_cursor); + } + return 0; +} + +void WIN_SetCursorPos(int x, int y) +{ + /* We need to jitter the value because otherwise Windows will occasionally inexplicably ignore the SetCursorPos() or SendInput() */ + SetCursorPos(x, y); + SetCursorPos(x + 1, y); + SetCursorPos(x, y); + + /* Flush any mouse motion prior to or associated with this warp */ + SDL_last_warp_time = GetTickCount(); + if (!SDL_last_warp_time) { + SDL_last_warp_time = 1; + } +} + +static void WIN_WarpMouse(SDL_Window *window, int x, int y) +{ + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + HWND hwnd = data->hwnd; + POINT pt; + int warp_x = x; + int warp_y = y; + + /* Don't warp the mouse while we're doing a modal interaction */ + if (data->in_title_click || data->focus_click_pending) { + return; + } + + WIN_ClientPointFromSDL(window, &x, &y); + pt.x = x; + pt.y = y; + ClientToScreen(hwnd, &pt); + WIN_SetCursorPos(pt.x, pt.y); + + /* Send the exact mouse motion associated with this warp */ + SDL_SendMouseMotion(window, SDL_GetMouse()->mouseID, 0, warp_x, warp_y); +} + +static int WIN_WarpMouseGlobal(int x, int y) +{ + POINT pt; + + WIN_ScreenPointFromSDL(&x, &y, NULL); + pt.x = x; + pt.y = y; + SetCursorPos(pt.x, pt.y); + return 0; +} + +static int WIN_SetRelativeMouseMode(SDL_bool enabled) +{ + return ToggleRawInput(enabled); +} + +static int WIN_CaptureMouse(SDL_Window *window) +{ + if (window) { + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + SetCapture(data->hwnd); + } else { + SDL_Window *focus_window = SDL_GetMouseFocus(); + + if (focus_window) { + SDL_WindowData *data = (SDL_WindowData *)focus_window->driverdata; + if (!data->mouse_tracked) { + SDL_SetMouseFocus(NULL); + } + } + ReleaseCapture(); + } + + return 0; +} + +static Uint32 WIN_GetGlobalMouseState(int *x, int *y) +{ + Uint32 retval = 0; + POINT pt = { 0, 0 }; + SDL_bool swapButtons = GetSystemMetrics(SM_SWAPBUTTON) != 0; + + GetCursorPos(&pt); + *x = (int)pt.x; + *y = (int)pt.y; + WIN_ScreenPointToSDL(x, y); + + retval |= GetAsyncKeyState(!swapButtons ? VK_LBUTTON : VK_RBUTTON) & 0x8000 ? SDL_BUTTON_LMASK : 0; + retval |= GetAsyncKeyState(!swapButtons ? VK_RBUTTON : VK_LBUTTON) & 0x8000 ? SDL_BUTTON_RMASK : 0; + retval |= GetAsyncKeyState(VK_MBUTTON) & 0x8000 ? SDL_BUTTON_MMASK : 0; + retval |= GetAsyncKeyState(VK_XBUTTON1) & 0x8000 ? SDL_BUTTON_X1MASK : 0; + retval |= GetAsyncKeyState(VK_XBUTTON2) & 0x8000 ? SDL_BUTTON_X2MASK : 0; + + return retval; +} + +void WIN_InitMouse(_THIS) +{ + SDL_Mouse *mouse = SDL_GetMouse(); + + mouse->CreateCursor = WIN_CreateCursor; + mouse->CreateSystemCursor = WIN_CreateSystemCursor; + mouse->ShowCursor = WIN_ShowCursor; + mouse->FreeCursor = WIN_FreeCursor; + mouse->WarpMouse = WIN_WarpMouse; + mouse->WarpMouseGlobal = WIN_WarpMouseGlobal; + mouse->SetRelativeMouseMode = WIN_SetRelativeMouseMode; + mouse->CaptureMouse = WIN_CaptureMouse; + mouse->GetGlobalMouseState = WIN_GetGlobalMouseState; + + SDL_SetDefaultCursor(WIN_CreateDefaultCursor()); + + SDL_blank_cursor = WIN_CreateBlankCursor(); + + WIN_UpdateMouseSystemScale(); +} + +void WIN_QuitMouse(_THIS) +{ + if (rawInputEnableCount) { /* force RAWINPUT off here. */ + rawInputEnableCount = 1; + ToggleRawInput(SDL_FALSE); + } + + if (SDL_blank_cursor) { + WIN_FreeCursor(SDL_blank_cursor); + SDL_blank_cursor = NULL; + } +} + +/* For a great description of how the enhanced mouse curve works, see: + * https://superuser.com/questions/278362/windows-mouse-acceleration-curve-smoothmousexcurve-and-smoothmouseycurve + * http://www.esreality.com/?a=post&id=1846538/ + */ +static SDL_bool LoadFiveFixedPointFloats(const BYTE *bytes, float *values) +{ + int i; + + for (i = 0; i < 5; ++i) { + float fraction = (float)((Uint16)bytes[1] << 8 | bytes[0]) / 65535.0f; + float value = (float)(((Uint16)bytes[3] << 8) | bytes[2]) + fraction; + *values++ = value; + bytes += 8; + } + return SDL_TRUE; +} + +static void WIN_SetEnhancedMouseScale(int mouse_speed) +{ + float scale = (float)mouse_speed / 10.0f; + HKEY hKey; + DWORD dwType = REG_BINARY; + BYTE value[40]; + DWORD length = sizeof(value); + int i; + float xpoints[5]; + float ypoints[5]; + float scale_points[10]; + const int dpi = 96; // FIXME, how do we handle different monitors with different DPI? + const float display_factor = 3.5f * (150.0f / dpi); + + if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Control Panel\\Mouse", 0, KEY_READ, &hKey) == ERROR_SUCCESS) { + if (RegQueryValueExW(hKey, L"SmoothMouseXCurve", 0, &dwType, value, &length) == ERROR_SUCCESS && + LoadFiveFixedPointFloats(value, xpoints) && + RegQueryValueExW(hKey, L"SmoothMouseYCurve", 0, &dwType, value, &length) == ERROR_SUCCESS && + LoadFiveFixedPointFloats(value, ypoints)) { + for (i = 0; i < 5; ++i) { + float gain; + if (xpoints[i] > 0.0f) { + gain = (ypoints[i] / xpoints[i]) * scale; + } else { + gain = 0.0f; + } + scale_points[i * 2] = xpoints[i]; + scale_points[i * 2 + 1] = gain / display_factor; + // SDL_Log("Point %d = %f,%f\n", i, scale_points[i * 2], scale_points[i * 2 + 1]); + } + SDL_SetMouseSystemScale(SDL_arraysize(scale_points), scale_points); + } + RegCloseKey(hKey); + } +} + +static void WIN_SetLinearMouseScale(int mouse_speed) +{ + static float mouse_speed_scale[] = { + 0.0f, + 1 / 32.0f, + 1 / 16.0f, + 1 / 8.0f, + 2 / 8.0f, + 3 / 8.0f, + 4 / 8.0f, + 5 / 8.0f, + 6 / 8.0f, + 7 / 8.0f, + 1.0f, + 1.25f, + 1.5f, + 1.75f, + 2.0f, + 2.25f, + 2.5f, + 2.75f, + 3.0f, + 3.25f, + 3.5f + }; + + if (mouse_speed > 0 && mouse_speed < SDL_arraysize(mouse_speed_scale)) { + SDL_SetMouseSystemScale(1, &mouse_speed_scale[mouse_speed]); + } +} + +void WIN_UpdateMouseSystemScale() +{ + int mouse_speed; + int params[3] = { 0, 0, 0 }; + + if (SystemParametersInfo(SPI_GETMOUSESPEED, 0, &mouse_speed, 0) && + SystemParametersInfo(SPI_GETMOUSE, 0, params, 0)) { + if (params[2]) { + WIN_SetEnhancedMouseScale(mouse_speed); + } else { + WIN_SetLinearMouseScale(mouse_speed); + } + } +} + +#endif /* SDL_VIDEO_DRIVER_WINDOWS */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/windows/SDL_windowsmouse.h b/SDL2-2.30.5/src/video/windows/SDL_windowsmouse.h similarity index 86% rename from SDL2-2.0.12/src/video/windows/SDL_windowsmouse.h rename to SDL2-2.30.5/src/video/windows/SDL_windowsmouse.h index 7212210..25f510e 100644 --- a/SDL2-2.0.12/src/video/windows/SDL_windowsmouse.h +++ b/SDL2-2.30.5/src/video/windows/SDL_windowsmouse.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,10 +23,13 @@ #ifndef SDL_windowsmouse_h_ #define SDL_windowsmouse_h_ +extern DWORD SDL_last_warp_time; extern HCURSOR SDL_cursor; extern void WIN_InitMouse(_THIS); extern void WIN_QuitMouse(_THIS); +extern void WIN_SetCursorPos(int x, int y); +extern void WIN_UpdateMouseSystemScale(); #endif /* SDL_windowsmouse_h_ */ diff --git a/SDL2-2.0.12/src/video/windows/SDL_windowsopengl.c b/SDL2-2.30.5/src/video/windows/SDL_windowsopengl.c similarity index 74% rename from SDL2-2.0.12/src/video/windows/SDL_windowsopengl.c rename to SDL2-2.30.5/src/video/windows/SDL_windowsopengl.c index cd87eea..ba505f1 100644 --- a/SDL2-2.0.12/src/video/windows/SDL_windowsopengl.c +++ b/SDL2-2.30.5/src/video/windows/SDL_windowsopengl.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,9 +20,8 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_WINDOWS +#ifdef SDL_VIDEO_DRIVER_WINDOWS -#include "SDL_assert.h" #include "SDL_loadso.h" #include "SDL_windowsvideo.h" #include "SDL_windowsopengles.h" @@ -30,19 +29,19 @@ /* WGL implementation of SDL OpenGL support */ -#if SDL_VIDEO_OPENGL_WGL +#ifdef SDL_VIDEO_OPENGL_WGL #include "SDL_opengl.h" #define DEFAULT_OPENGL "OPENGL32.DLL" #ifndef WGL_ARB_create_context #define WGL_ARB_create_context -#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 -#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 -#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093 -#define WGL_CONTEXT_FLAGS_ARB 0x2094 -#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001 -#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 +#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 +#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093 +#define WGL_CONTEXT_FLAGS_ARB 0x2094 +#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001 +#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 #ifndef WGL_ARB_create_context_profile #define WGL_ARB_create_context_profile @@ -53,48 +52,62 @@ #ifndef WGL_ARB_create_context_robustness #define WGL_ARB_create_context_robustness -#define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004 -#define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 -#define WGL_NO_RESET_NOTIFICATION_ARB 0x8261 -#define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252 +#define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004 +#define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 +#define WGL_NO_RESET_NOTIFICATION_ARB 0x8261 +#define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252 #endif #endif #ifndef WGL_EXT_create_context_es2_profile #define WGL_EXT_create_context_es2_profile -#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004 +#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004 #endif #ifndef WGL_EXT_create_context_es_profile #define WGL_EXT_create_context_es_profile -#define WGL_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004 +#define WGL_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004 #endif #ifndef WGL_ARB_framebuffer_sRGB #define WGL_ARB_framebuffer_sRGB -#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9 +#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9 +#endif + +#ifndef WGL_ARB_pixel_format_float +#define WGL_ARB_pixel_format_float +#define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0 #endif #ifndef WGL_ARB_context_flush_control #define WGL_ARB_context_flush_control -#define WGL_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097 -#define WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0x0000 -#define WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098 +#define WGL_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097 +#define WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0x0000 +#define WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098 #endif #ifndef WGL_ARB_create_context_no_error #define WGL_ARB_create_context_no_error -#define WGL_CONTEXT_OPENGL_NO_ERROR_ARB 0x31B3 +#define WGL_CONTEXT_OPENGL_NO_ERROR_ARB 0x31B3 #endif -typedef HGLRC(APIENTRYP PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, - HGLRC - hShareContext, - const int - *attribList); +typedef HGLRC(APIENTRYP PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC hDC, + HGLRC + hShareContext, + const int + *attribList); -int -WIN_GL_LoadLibrary(_THIS, const char *path) +#if defined(__XBOXONE__) || defined(__XBOXSERIES__) +#define GetDC(hwnd) (HDC) hwnd +#define ReleaseDC(hwnd, hdc) 1 +#define SwapBuffers _this->gl_data->wglSwapBuffers +#define DescribePixelFormat _this->gl_data->wglDescribePixelFormat +#define ChoosePixelFormat _this->gl_data->wglChoosePixelFormat +#define GetPixelFormat _this->gl_data->wglGetPixelFormat +#define SetPixelFormat _this->gl_data->wglSetPixelFormat +#endif + +int WIN_GL_LoadLibrary(_THIS, const char *path) { void *handle; @@ -112,28 +125,51 @@ WIN_GL_LoadLibrary(_THIS, const char *path) SDL_arraysize(_this->gl_config.driver_path)); /* Allocate OpenGL memory */ - _this->gl_data = (struct SDL_GLDriverData *) SDL_calloc(1, sizeof(struct SDL_GLDriverData)); + _this->gl_data = (struct SDL_GLDriverData *)SDL_calloc(1, sizeof(struct SDL_GLDriverData)); if (!_this->gl_data) { return SDL_OutOfMemory(); } /* Load function pointers */ handle = _this->gl_config.dll_handle; - _this->gl_data->wglGetProcAddress = (void *(WINAPI *) (const char *)) + /* *INDENT-OFF* */ /* clang-format off */ + _this->gl_data->wglGetProcAddress = (void *(WINAPI *)(const char *)) SDL_LoadFunction(handle, "wglGetProcAddress"); - _this->gl_data->wglCreateContext = (HGLRC(WINAPI *) (HDC)) + _this->gl_data->wglCreateContext = (HGLRC (WINAPI *)(HDC)) SDL_LoadFunction(handle, "wglCreateContext"); - _this->gl_data->wglDeleteContext = (BOOL(WINAPI *) (HGLRC)) + _this->gl_data->wglDeleteContext = (BOOL (WINAPI *)(HGLRC)) SDL_LoadFunction(handle, "wglDeleteContext"); - _this->gl_data->wglMakeCurrent = (BOOL(WINAPI *) (HDC, HGLRC)) + _this->gl_data->wglMakeCurrent = (BOOL (WINAPI *)(HDC, HGLRC)) SDL_LoadFunction(handle, "wglMakeCurrent"); - _this->gl_data->wglShareLists = (BOOL(WINAPI *) (HGLRC, HGLRC)) + _this->gl_data->wglShareLists = (BOOL (WINAPI *)(HGLRC, HGLRC)) SDL_LoadFunction(handle, "wglShareLists"); + /* *INDENT-ON* */ /* clang-format on */ + +#if defined(__XBOXONE__) || defined(__XBOXSERIES__) + _this->gl_data->wglSwapBuffers = (BOOL(WINAPI *)(HDC)) + SDL_LoadFunction(handle, "wglSwapBuffers"); + _this->gl_data->wglDescribePixelFormat = (int(WINAPI *)(HDC, int, UINT, LPPIXELFORMATDESCRIPTOR)) + SDL_LoadFunction(handle, "wglDescribePixelFormat"); + _this->gl_data->wglChoosePixelFormat = (int(WINAPI *)(HDC, const PIXELFORMATDESCRIPTOR *)) + SDL_LoadFunction(handle, "wglChoosePixelFormat"); + _this->gl_data->wglSetPixelFormat = (BOOL(WINAPI *)(HDC, int, const PIXELFORMATDESCRIPTOR *)) + SDL_LoadFunction(handle, "wglSetPixelFormat"); + _this->gl_data->wglGetPixelFormat = (int(WINAPI *)(HDC hdc)) + SDL_LoadFunction(handle, "wglGetPixelFormat"); +#endif if (!_this->gl_data->wglGetProcAddress || !_this->gl_data->wglCreateContext || !_this->gl_data->wglDeleteContext || - !_this->gl_data->wglMakeCurrent) { + !_this->gl_data->wglMakeCurrent +#if defined(__XBOXONE__) || defined(__XBOXSERIES__) + || !_this->gl_data->wglSwapBuffers || + !_this->gl_data->wglDescribePixelFormat || + !_this->gl_data->wglChoosePixelFormat || + !_this->gl_data->wglGetPixelFormat || + !_this->gl_data->wglSetPixelFormat +#endif + ) { return SDL_SetError("Could not retrieve OpenGL functions"); } @@ -178,8 +214,7 @@ WIN_GL_LoadLibrary(_THIS, const char *path) return 0; } -void * -WIN_GL_GetProcAddress(_THIS, const char *proc) +void *WIN_GL_GetProcAddress(_THIS, const char *proc) { void *func; @@ -192,8 +227,7 @@ WIN_GL_GetProcAddress(_THIS, const char *proc) return func; } -void -WIN_GL_UnloadLibrary(_THIS) +void WIN_GL_UnloadLibrary(_THIS) { SDL_UnloadObject(_this->gl_config.dll_handle); _this->gl_config.dll_handle = NULL; @@ -203,8 +237,7 @@ WIN_GL_UnloadLibrary(_THIS) _this->gl_data = NULL; } -static void -WIN_GL_SetupPixelFormat(_THIS, PIXELFORMATDESCRIPTOR * pfd) +static void WIN_GL_SetupPixelFormat(_THIS, PIXELFORMATDESCRIPTOR *pfd) { SDL_zerop(pfd); pfd->nSize = sizeof(*pfd); @@ -242,8 +275,7 @@ WIN_GL_SetupPixelFormat(_THIS, PIXELFORMATDESCRIPTOR * pfd) /* Choose the closest pixel format that meets or exceeds the target. FIXME: Should we weight any particular attribute over any other? */ -static int -WIN_GL_ChoosePixelFormat(HDC hdc, PIXELFORMATDESCRIPTOR * target) +static int WIN_GL_ChoosePixelFormat(_THIS, HDC hdc, PIXELFORMATDESCRIPTOR *target) { PIXELFORMATDESCRIPTOR pfd; int count, index, best = 0; @@ -340,19 +372,20 @@ WIN_GL_ChoosePixelFormat(HDC hdc, PIXELFORMATDESCRIPTOR * target) return best; } -static SDL_bool -HasExtension(const char *extension, const char *extensions) +static SDL_bool HasExtension(const char *extension, const char *extensions) { const char *start; const char *where, *terminator; /* Extension names should not have spaces. */ where = SDL_strchr(extension, ' '); - if (where || *extension == '\0') + if (where || *extension == '\0') { return SDL_FALSE; + } - if (!extensions) + if (!extensions) { return SDL_FALSE; + } /* It takes a bit of care to be fool-proof about parsing the * OpenGL extensions string. Don't be fooled by sub-strings, @@ -362,23 +395,27 @@ HasExtension(const char *extension, const char *extensions) for (;;) { where = SDL_strstr(start, extension); - if (!where) + if (!where) { break; + } terminator = where + SDL_strlen(extension); - if (where == start || *(where - 1) == ' ') - if (*terminator == ' ' || *terminator == '\0') + if (where == start || *(where - 1) == ' ') { + if (*terminator == ' ' || *terminator == '\0') { return SDL_TRUE; + } + } start = terminator; } return SDL_FALSE; } -void -WIN_GL_InitExtensions(_THIS) +void WIN_GL_InitExtensions(_THIS) { - const char *(WINAPI * wglGetExtensionsStringARB) (HDC) = 0; + /* *INDENT-OFF* */ /* clang-format off */ + const char *(WINAPI * wglGetExtensionsStringARB)(HDC) = 0; + /* *INDENT-ON* */ /* clang-format on */ const char *extensions; HWND hwnd; HDC hdc; @@ -391,7 +428,7 @@ WIN_GL_InitExtensions(_THIS) hwnd = CreateWindow(SDL_Appname, SDL_Appname, (WS_POPUP | WS_DISABLED), 0, 0, - 10, 10, NULL, NULL, SDL_Instance, NULL); + 10, 10, NULL, NULL, SDL_Instance, NULL); if (!hwnd) { return; } @@ -409,8 +446,10 @@ WIN_GL_InitExtensions(_THIS) } _this->gl_data->wglMakeCurrent(hdc, hglrc); - wglGetExtensionsStringARB = (const char *(WINAPI *) (HDC)) + /* *INDENT-OFF* */ /* clang-format off */ + wglGetExtensionsStringARB = (const char *(WINAPI *)(HDC)) _this->gl_data->wglGetProcAddress("wglGetExtensionsStringARB"); + /* *INDENT-ON* */ /* clang-format on */ if (wglGetExtensionsStringARB) { extensions = wglGetExtensionsStringARB(hdc); } else { @@ -420,14 +459,14 @@ WIN_GL_InitExtensions(_THIS) /* Check for WGL_ARB_pixel_format */ _this->gl_data->HAS_WGL_ARB_pixel_format = SDL_FALSE; if (HasExtension("WGL_ARB_pixel_format", extensions)) { - _this->gl_data->wglChoosePixelFormatARB = (BOOL(WINAPI *) - (HDC, const int *, - const FLOAT *, UINT, - int *, UINT *)) + /* *INDENT-OFF* */ /* clang-format off */ + _this->gl_data->wglChoosePixelFormatARB = + (BOOL (WINAPI *)(HDC, const int *, const FLOAT *, UINT, int *, UINT *)) WIN_GL_GetProcAddress(_this, "wglChoosePixelFormatARB"); _this->gl_data->wglGetPixelFormatAttribivARB = - (BOOL(WINAPI *) (HDC, int, int, UINT, const int *, int *)) + (BOOL (WINAPI *)(HDC, int, int, UINT, const int *, int *)) WIN_GL_GetProcAddress(_this, "wglGetPixelFormatAttribivARB"); + /* *INDENT-ON* */ /* clang-format on */ if ((_this->gl_data->wglChoosePixelFormatARB != NULL) && (_this->gl_data->wglGetPixelFormatAttribivARB != NULL)) { @@ -454,8 +493,7 @@ WIN_GL_InitExtensions(_THIS) if (HasExtension("WGL_EXT_create_context_es2_profile", extensions)) { SDL_GL_DeduceMaxSupportedESProfile( &_this->gl_data->es_profile_max_supported_version.major, - &_this->gl_data->es_profile_max_supported_version.minor - ); + &_this->gl_data->es_profile_max_supported_version.minor); } /* Check for WGL_ARB_context_flush_control */ @@ -480,8 +518,7 @@ WIN_GL_InitExtensions(_THIS) WIN_PumpEvents(_this); } -static int -WIN_GL_ChoosePixelFormatARB(_THIS, int *iAttribs, float *fAttribs) +static int WIN_GL_ChoosePixelFormatARB(_THIS, int *iAttribs, float *fAttribs) { HWND hwnd; HDC hdc; @@ -490,6 +527,9 @@ WIN_GL_ChoosePixelFormatARB(_THIS, int *iAttribs, float *fAttribs) int pixel_format = 0; unsigned int matching; + int qAttrib = WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB; + int srgb = 0; + hwnd = CreateWindow(SDL_Appname, SDL_Appname, (WS_POPUP | WS_DISABLED), 0, 0, 10, 10, NULL, NULL, SDL_Instance, NULL); @@ -509,6 +549,10 @@ WIN_GL_ChoosePixelFormatARB(_THIS, int *iAttribs, float *fAttribs) _this->gl_data->wglChoosePixelFormatARB(hdc, iAttribs, fAttribs, 1, &pixel_format, &matching); + + /* Check whether we actually got an SRGB capable buffer */ + _this->gl_data->wglGetPixelFormatAttribivARB(hdc, pixel_format, 0, 1, &qAttrib, &srgb); + _this->gl_config.framebuffer_srgb_capable = srgb; } _this->gl_data->wglMakeCurrent(hdc, NULL); @@ -522,10 +566,9 @@ WIN_GL_ChoosePixelFormatARB(_THIS, int *iAttribs, float *fAttribs) } /* actual work of WIN_GL_SetupWindow() happens here. */ -static int -WIN_GL_SetupWindowInternal(_THIS, SDL_Window * window) +static int WIN_GL_SetupWindowInternal(_THIS, SDL_Window *window) { - HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc; + HDC hdc = ((SDL_WindowData *)window->driverdata)->hdc; PIXELFORMATDESCRIPTOR pfd; int pixel_format = 0; int iAttribs[64]; @@ -598,6 +641,10 @@ WIN_GL_SetupWindowInternal(_THIS, SDL_Window * window) *iAttr++ = _this->gl_config.multisamplesamples; } + if (_this->gl_config.floatbuffers) { + *iAttr++ = WGL_TYPE_RGBA_FLOAT_ARB; + } + if (_this->gl_config.framebuffer_srgb_capable) { *iAttr++ = WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB; *iAttr++ = _this->gl_config.framebuffer_srgb_capable; @@ -621,13 +668,13 @@ WIN_GL_SetupWindowInternal(_THIS, SDL_Window * window) pixel_format = WIN_GL_ChoosePixelFormatARB(_this, iAttribs, fAttribs); /* App said "don't care about accel" and FULL accel failed. Try NO. */ - if ( ( !pixel_format ) && ( _this->gl_config.accelerated < 0 ) ) { + if ((!pixel_format) && (_this->gl_config.accelerated < 0)) { *iAccelAttr = WGL_NO_ACCELERATION_ARB; pixel_format = WIN_GL_ChoosePixelFormatARB(_this, iAttribs, fAttribs); - *iAccelAttr = WGL_FULL_ACCELERATION_ARB; /* if we try again. */ + *iAccelAttr = WGL_FULL_ACCELERATION_ARB; /* if we try again. */ } if (!pixel_format) { - pixel_format = WIN_GL_ChoosePixelFormat(hdc, &pfd); + pixel_format = WIN_GL_ChoosePixelFormat(_this, hdc, &pfd); } if (!pixel_format) { return SDL_SetError("No matching GL pixel format available"); @@ -638,8 +685,7 @@ WIN_GL_SetupWindowInternal(_THIS, SDL_Window * window) return 0; } -int -WIN_GL_SetupWindow(_THIS, SDL_Window * window) +int WIN_GL_SetupWindow(_THIS, SDL_Window *window) { /* The current context is lost in here; save it and reset it. */ SDL_Window *current_win = SDL_GL_GetCurrentWindow(); @@ -649,27 +695,21 @@ WIN_GL_SetupWindow(_THIS, SDL_Window * window) return retval; } -SDL_bool -WIN_GL_UseEGL(_THIS) +SDL_bool WIN_GL_UseEGL(_THIS) { SDL_assert(_this->gl_data != NULL); SDL_assert(_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES); - return (SDL_GetHintBoolean(SDL_HINT_OPENGL_ES_DRIVER, SDL_FALSE) - || _this->gl_config.major_version == 1 /* No WGL extension for OpenGL ES 1.x profiles. */ - || _this->gl_config.major_version > _this->gl_data->es_profile_max_supported_version.major - || (_this->gl_config.major_version == _this->gl_data->es_profile_max_supported_version.major - && _this->gl_config.minor_version > _this->gl_data->es_profile_max_supported_version.minor)); + return SDL_GetHintBoolean(SDL_HINT_OPENGL_ES_DRIVER, SDL_FALSE) || _this->gl_config.major_version == 1 || _this->gl_config.major_version > _this->gl_data->es_profile_max_supported_version.major || (_this->gl_config.major_version == _this->gl_data->es_profile_max_supported_version.major && _this->gl_config.minor_version > _this->gl_data->es_profile_max_supported_version.minor); /* No WGL extension for OpenGL ES 1.x profiles. */ } -SDL_GLContext -WIN_GL_CreateContext(_THIS, SDL_Window * window) +SDL_GLContext WIN_GL_CreateContext(_THIS, SDL_Window *window) { - HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc; + HDC hdc = ((SDL_WindowData *)window->driverdata)->hdc; HGLRC context, share_context; if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES && WIN_GL_UseEGL(_this)) { -#if SDL_VIDEO_OPENGL_EGL +#ifdef SDL_VIDEO_OPENGL_EGL /* Switch to EGL based functions */ WIN_GL_UnloadLibrary(_this); _this->GL_LoadLibrary = WIN_GLES_LoadLibrary; @@ -681,11 +721,11 @@ WIN_GL_CreateContext(_THIS, SDL_Window * window) _this->GL_GetSwapInterval = WIN_GLES_GetSwapInterval; _this->GL_SwapWindow = WIN_GLES_SwapWindow; _this->GL_DeleteContext = WIN_GLES_DeleteContext; - + if (WIN_GLES_LoadLibrary(_this, NULL) != 0) { return NULL; } - + return WIN_GLES_CreateContext(_this, window); #else SDL_SetError("SDL not configured with EGL support"); @@ -704,7 +744,7 @@ WIN_GL_CreateContext(_THIS, SDL_Window * window) _this->gl_config.flags == 0) { /* Create legacy context */ context = _this->gl_data->wglCreateContext(hdc); - if( share_context != 0 ) { + if (share_context != 0) { _this->gl_data->wglShareLists(share_context, context); } } else { @@ -722,13 +762,12 @@ WIN_GL_CreateContext(_THIS, SDL_Window * window) } wglCreateContextAttribsARB = - (PFNWGLCREATECONTEXTATTRIBSARBPROC) _this->gl_data-> - wglGetProcAddress("wglCreateContextAttribsARB"); + (PFNWGLCREATECONTEXTATTRIBSARBPROC)_this->gl_data->wglGetProcAddress("wglCreateContextAttribsARB"); if (!wglCreateContextAttribsARB) { SDL_SetError("GL 3.x is not supported"); context = temp_context; } else { - int attribs[15]; /* max 14 attributes plus terminator */ + int attribs[15]; /* max 14 attributes plus terminator */ int iattr = 0; attribs[iattr++] = WGL_CONTEXT_MAJOR_VERSION_ARB; @@ -748,24 +787,20 @@ WIN_GL_CreateContext(_THIS, SDL_Window * window) attribs[iattr++] = _this->gl_config.flags; } - /* only set if wgl extension is available */ - if (_this->gl_data->HAS_WGL_ARB_context_flush_control) { + /* only set if wgl extension is available and not the default setting */ + if ((_this->gl_data->HAS_WGL_ARB_context_flush_control) && (_this->gl_config.release_behavior == 0)) { attribs[iattr++] = WGL_CONTEXT_RELEASE_BEHAVIOR_ARB; - attribs[iattr++] = _this->gl_config.release_behavior ? - WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB : - WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB; + attribs[iattr++] = _this->gl_config.release_behavior ? WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB : WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB; } - /* only set if wgl extension is available */ - if (_this->gl_data->HAS_WGL_ARB_create_context_robustness) { + /* only set if wgl extension is available and not the default setting */ + if ((_this->gl_data->HAS_WGL_ARB_create_context_robustness) && (_this->gl_config.reset_notification != 0)) { attribs[iattr++] = WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB; - attribs[iattr++] = _this->gl_config.reset_notification ? - WGL_LOSE_CONTEXT_ON_RESET_ARB : - WGL_NO_RESET_NOTIFICATION_ARB; + attribs[iattr++] = _this->gl_config.reset_notification ? WGL_LOSE_CONTEXT_ON_RESET_ARB : WGL_NO_RESET_NOTIFICATION_ARB; } - /* only set if wgl extension is available */ - if (_this->gl_data->HAS_WGL_ARB_create_context_no_error) { + /* only set if wgl extension is available and not the default setting */ + if ((_this->gl_data->HAS_WGL_ARB_create_context_no_error) && (_this->gl_config.no_error != 0)) { attribs[iattr++] = WGL_CONTEXT_OPENGL_NO_ERROR_ARB; attribs[iattr++] = _this->gl_config.no_error; } @@ -792,8 +827,7 @@ WIN_GL_CreateContext(_THIS, SDL_Window * window) return context; } -int -WIN_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) +int WIN_GL_MakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context) { HDC hdc; @@ -802,7 +836,7 @@ WIN_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) } /* sanity check that higher level handled this. */ - SDL_assert(window || (!window && !context)); + SDL_assert(window || (window == NULL && !context)); /* Some Windows drivers freak out if hdc is NULL, even when context is NULL, against spec. Since hdc is _supposed_ to be ignored if context @@ -812,19 +846,18 @@ WIN_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) window = SDL_GL_GetCurrentWindow(); if (!window) { SDL_assert(SDL_GL_GetCurrentContext() == NULL); - return 0; /* already done. */ + return 0; /* already done. */ } } - hdc = ((SDL_WindowData *) window->driverdata)->hdc; - if (!_this->gl_data->wglMakeCurrent(hdc, (HGLRC) context)) { + hdc = ((SDL_WindowData *)window->driverdata)->hdc; + if (!_this->gl_data->wglMakeCurrent(hdc, (HGLRC)context)) { return WIN_SetError("wglMakeCurrent()"); } return 0; } -int -WIN_GL_SetSwapInterval(_THIS, int interval) +int WIN_GL_SetSwapInterval(_THIS, int interval) { if ((interval < 0) && (!_this->gl_data->HAS_WGL_EXT_swap_control_tear)) { return SDL_SetError("Negative swap interval unsupported in this GL"); @@ -838,8 +871,7 @@ WIN_GL_SetSwapInterval(_THIS, int interval) return 0; } -int -WIN_GL_GetSwapInterval(_THIS) +int WIN_GL_GetSwapInterval(_THIS) { int retval = 0; if (_this->gl_data->wglGetSwapIntervalEXT) { @@ -848,10 +880,9 @@ WIN_GL_GetSwapInterval(_THIS) return retval; } -int -WIN_GL_SwapWindow(_THIS, SDL_Window * window) +int WIN_GL_SwapWindow(_THIS, SDL_Window *window) { - HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc; + HDC hdc = ((SDL_WindowData *)window->driverdata)->hdc; if (!SwapBuffers(hdc)) { return WIN_SetError("SwapBuffers()"); @@ -859,21 +890,18 @@ WIN_GL_SwapWindow(_THIS, SDL_Window * window) return 0; } -void -WIN_GL_DeleteContext(_THIS, SDL_GLContext context) +void WIN_GL_DeleteContext(_THIS, SDL_GLContext context) { if (!_this->gl_data) { return; } - _this->gl_data->wglDeleteContext((HGLRC) context); + _this->gl_data->wglDeleteContext((HGLRC)context); } - -SDL_bool -WIN_GL_SetPixelFormatFrom(_THIS, SDL_Window * fromWindow, SDL_Window * toWindow) +SDL_bool WIN_GL_SetPixelFormatFrom(_THIS, SDL_Window *fromWindow, SDL_Window *toWindow) { - HDC hfromdc = ((SDL_WindowData *) fromWindow->driverdata)->hdc; - HDC htodc = ((SDL_WindowData *) toWindow->driverdata)->hdc; + HDC hfromdc = ((SDL_WindowData *)fromWindow->driverdata)->hdc; + HDC htodc = ((SDL_WindowData *)toWindow->driverdata)->hdc; BOOL result; /* get the pixel format of the fromWindow */ diff --git a/SDL2-2.30.5/src/video/windows/SDL_windowsopengl.h b/SDL2-2.30.5/src/video/windows/SDL_windowsopengl.h new file mode 100644 index 0000000..184a313 --- /dev/null +++ b/SDL2-2.30.5/src/video/windows/SDL_windowsopengl.h @@ -0,0 +1,181 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifndef SDL_windowsopengl_h_ +#define SDL_windowsopengl_h_ + +#ifdef SDL_VIDEO_OPENGL_WGL + +#if defined(__XBOXONE__) || defined(__XBOXSERIES__) +typedef struct tagPIXELFORMATDESCRIPTOR +{ + WORD nSize; + WORD nVersion; + DWORD dwFlags; + BYTE iPixelType; + BYTE cColorBits; + BYTE cRedBits; + BYTE cRedShift; + BYTE cGreenBits; + BYTE cGreenShift; + BYTE cBlueBits; + BYTE cBlueShift; + BYTE cAlphaBits; + BYTE cAlphaShift; + BYTE cAccumBits; + BYTE cAccumRedBits; + BYTE cAccumGreenBits; + BYTE cAccumBlueBits; + BYTE cAccumAlphaBits; + BYTE cDepthBits; + BYTE cStencilBits; + BYTE cAuxBuffers; + BYTE iLayerType; + BYTE bReserved; + DWORD dwLayerMask; + DWORD dwVisibleMask; + DWORD dwDamageMask; +} PIXELFORMATDESCRIPTOR, *PPIXELFORMATDESCRIPTOR, *LPPIXELFORMATDESCRIPTOR; +#endif + +struct SDL_GLDriverData +{ + SDL_bool HAS_WGL_ARB_pixel_format; + SDL_bool HAS_WGL_EXT_swap_control_tear; + SDL_bool HAS_WGL_ARB_context_flush_control; + SDL_bool HAS_WGL_ARB_create_context_robustness; + SDL_bool HAS_WGL_ARB_create_context_no_error; + + /* Max version of OpenGL ES context that can be created if the + implementation supports WGL_EXT_create_context_es2_profile. + major = minor = 0 when unsupported. + */ + struct + { + int major; + int minor; + } es_profile_max_supported_version; + + /* *INDENT-OFF* */ /* clang-format off */ + void *(WINAPI *wglGetProcAddress)(const char *proc); + HGLRC (WINAPI *wglCreateContext)(HDC hdc); + BOOL (WINAPI *wglDeleteContext)(HGLRC hglrc); + BOOL (WINAPI *wglMakeCurrent)(HDC hdc, HGLRC hglrc); + BOOL (WINAPI *wglShareLists)(HGLRC hglrc1, HGLRC hglrc2); + BOOL (WINAPI *wglChoosePixelFormatARB)(HDC hdc, const int *piAttribIList, const FLOAT * pfAttribFList, UINT nMaxFormats, int *piFormats, UINT * nNumFormats); + BOOL (WINAPI *wglGetPixelFormatAttribivARB)(HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues); + BOOL (WINAPI *wglSwapIntervalEXT)(int interval); + int (WINAPI *wglGetSwapIntervalEXT)(void); +#if defined(__XBOXONE__) || defined(__XBOXSERIES__) + BOOL (WINAPI *wglSwapBuffers)(HDC hdc); + int (WINAPI *wglDescribePixelFormat)(HDC hdc, + int iPixelFormat, + UINT nBytes, + LPPIXELFORMATDESCRIPTOR ppfd); + int (WINAPI *wglChoosePixelFormat)(HDC hdc, + const PIXELFORMATDESCRIPTOR *ppfd); + BOOL (WINAPI *wglSetPixelFormat)(HDC hdc, + int format, + const PIXELFORMATDESCRIPTOR *ppfd); + int (WINAPI *wglGetPixelFormat)(HDC hdc); +#endif + /* *INDENT-ON* */ /* clang-format on */ +}; + +/* OpenGL functions */ +extern int WIN_GL_LoadLibrary(_THIS, const char *path); +extern void *WIN_GL_GetProcAddress(_THIS, const char *proc); +extern void WIN_GL_UnloadLibrary(_THIS); +extern SDL_bool WIN_GL_UseEGL(_THIS); +extern int WIN_GL_SetupWindow(_THIS, SDL_Window *window); +extern SDL_GLContext WIN_GL_CreateContext(_THIS, SDL_Window *window); +extern int WIN_GL_MakeCurrent(_THIS, SDL_Window *window, + SDL_GLContext context); +extern int WIN_GL_SetSwapInterval(_THIS, int interval); +extern int WIN_GL_GetSwapInterval(_THIS); +extern int WIN_GL_SwapWindow(_THIS, SDL_Window *window); +extern void WIN_GL_DeleteContext(_THIS, SDL_GLContext context); +extern void WIN_GL_InitExtensions(_THIS); +extern SDL_bool WIN_GL_SetPixelFormatFrom(_THIS, SDL_Window *fromWindow, SDL_Window *toWindow); + +#ifndef WGL_ARB_pixel_format +#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 +#define WGL_DRAW_TO_WINDOW_ARB 0x2001 +#define WGL_DRAW_TO_BITMAP_ARB 0x2002 +#define WGL_ACCELERATION_ARB 0x2003 +#define WGL_NEED_PALETTE_ARB 0x2004 +#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 +#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 +#define WGL_SWAP_METHOD_ARB 0x2007 +#define WGL_NUMBER_OVERLAYS_ARB 0x2008 +#define WGL_NUMBER_UNDERLAYS_ARB 0x2009 +#define WGL_TRANSPARENT_ARB 0x200A +#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 +#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 +#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 +#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A +#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B +#define WGL_SHARE_DEPTH_ARB 0x200C +#define WGL_SHARE_STENCIL_ARB 0x200D +#define WGL_SHARE_ACCUM_ARB 0x200E +#define WGL_SUPPORT_GDI_ARB 0x200F +#define WGL_SUPPORT_OPENGL_ARB 0x2010 +#define WGL_DOUBLE_BUFFER_ARB 0x2011 +#define WGL_STEREO_ARB 0x2012 +#define WGL_PIXEL_TYPE_ARB 0x2013 +#define WGL_COLOR_BITS_ARB 0x2014 +#define WGL_RED_BITS_ARB 0x2015 +#define WGL_RED_SHIFT_ARB 0x2016 +#define WGL_GREEN_BITS_ARB 0x2017 +#define WGL_GREEN_SHIFT_ARB 0x2018 +#define WGL_BLUE_BITS_ARB 0x2019 +#define WGL_BLUE_SHIFT_ARB 0x201A +#define WGL_ALPHA_BITS_ARB 0x201B +#define WGL_ALPHA_SHIFT_ARB 0x201C +#define WGL_ACCUM_BITS_ARB 0x201D +#define WGL_ACCUM_RED_BITS_ARB 0x201E +#define WGL_ACCUM_GREEN_BITS_ARB 0x201F +#define WGL_ACCUM_BLUE_BITS_ARB 0x2020 +#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 +#define WGL_DEPTH_BITS_ARB 0x2022 +#define WGL_STENCIL_BITS_ARB 0x2023 +#define WGL_AUX_BUFFERS_ARB 0x2024 +#define WGL_NO_ACCELERATION_ARB 0x2025 +#define WGL_GENERIC_ACCELERATION_ARB 0x2026 +#define WGL_FULL_ACCELERATION_ARB 0x2027 +#define WGL_SWAP_EXCHANGE_ARB 0x2028 +#define WGL_SWAP_COPY_ARB 0x2029 +#define WGL_SWAP_UNDEFINED_ARB 0x202A +#define WGL_TYPE_RGBA_ARB 0x202B +#define WGL_TYPE_COLORINDEX_ARB 0x202C +#endif + +#ifndef WGL_ARB_multisample +#define WGL_SAMPLE_BUFFERS_ARB 0x2041 +#define WGL_SAMPLES_ARB 0x2042 +#endif + +#endif /* SDL_VIDEO_OPENGL_WGL */ + +#endif /* SDL_windowsopengl_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/windows/SDL_windowsopengles.c b/SDL2-2.30.5/src/video/windows/SDL_windowsopengles.c similarity index 77% rename from SDL2-2.0.12/src/video/windows/SDL_windowsopengles.c rename to SDL2-2.30.5/src/video/windows/SDL_windowsopengles.c index 879448c..1450d50 100644 --- a/SDL2-2.0.12/src/video/windows/SDL_windowsopengles.c +++ b/SDL2-2.30.5/src/video/windows/SDL_windowsopengles.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,21 +20,21 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_WINDOWS && SDL_VIDEO_OPENGL_EGL +#if defined(SDL_VIDEO_DRIVER_WINDOWS) && defined(SDL_VIDEO_OPENGL_EGL) && !defined(__XBOXONE__) && !defined(__XBOXSERIES__) #include "SDL_windowsvideo.h" #include "SDL_windowsopengles.h" #include "SDL_windowsopengl.h" -#include "SDL_log.h" +#include "SDL_windowswindow.h" /* EGL implementation of SDL OpenGL support */ -int -WIN_GLES_LoadLibrary(_THIS, const char *path) { +int WIN_GLES_LoadLibrary(_THIS, const char *path) +{ /* If the profile requested is not GL ES, switch over to WIN_GL functions */ if (_this->gl_config.profile_mask != SDL_GL_CONTEXT_PROFILE_ES) { -#if SDL_VIDEO_OPENGL_WGL +#ifdef SDL_VIDEO_OPENGL_WGL WIN_GLES_UnloadLibrary(_this); _this->GL_LoadLibrary = WIN_GL_LoadLibrary; _this->GL_GetProcAddress = WIN_GL_GetProcAddress; @@ -50,21 +50,20 @@ WIN_GLES_LoadLibrary(_THIS, const char *path) { return SDL_SetError("SDL not configured with OpenGL/WGL support"); #endif } - - if (_this->egl_data == NULL) { + + if (!_this->egl_data) { return SDL_EGL_LoadLibrary(_this, NULL, EGL_DEFAULT_DISPLAY, 0); } return 0; } -SDL_GLContext -WIN_GLES_CreateContext(_THIS, SDL_Window * window) +SDL_GLContext WIN_GLES_CreateContext(_THIS, SDL_Window *window) { SDL_GLContext context; SDL_WindowData *data = (SDL_WindowData *)window->driverdata; -#if SDL_VIDEO_OPENGL_WGL +#ifdef SDL_VIDEO_OPENGL_WGL if (_this->gl_config.profile_mask != SDL_GL_CONTEXT_PROFILE_ES) { /* Switch to WGL based functions */ WIN_GLES_UnloadLibrary(_this); @@ -90,32 +89,35 @@ WIN_GLES_CreateContext(_THIS, SDL_Window * window) return context; } -void -WIN_GLES_DeleteContext(_THIS, SDL_GLContext context) +void WIN_GLES_DeleteContext(_THIS, SDL_GLContext context) { SDL_EGL_DeleteContext(_this, context); - WIN_GLES_UnloadLibrary(_this); } +/* *INDENT-OFF* */ /* clang-format off */ SDL_EGL_SwapWindow_impl(WIN) SDL_EGL_MakeCurrent_impl(WIN) +/* *INDENT-ON* */ /* clang-format on */ -int -WIN_GLES_SetupWindow(_THIS, SDL_Window * window) +int WIN_GLES_SetupWindow(_THIS, SDL_Window *window) { /* The current context is lost in here; save it and reset it. */ - SDL_WindowData *windowdata = (SDL_WindowData *) window->driverdata; + SDL_WindowData *windowdata = (SDL_WindowData *)window->driverdata; SDL_Window *current_win = SDL_GL_GetCurrentWindow(); SDL_GLContext current_ctx = SDL_GL_GetCurrentContext(); - - if (_this->egl_data == NULL) { + if (!_this->egl_data) { +/* !!! FIXME: commenting out this assertion is (I think) incorrect; figure out why driver_loaded is wrong for ANGLE instead. --ryan. */ +#if 0 /* When hint SDL_HINT_OPENGL_ES_DRIVER is set to "1" (e.g. for ANGLE support), _this->gl_config.driver_loaded can be 1, while the below lines function. */ + SDL_assert(!_this->gl_config.driver_loaded); + #endif if (SDL_EGL_LoadLibrary(_this, NULL, EGL_DEFAULT_DISPLAY, 0) < 0) { SDL_EGL_UnloadLibrary(_this); return -1; } + _this->gl_config.driver_loaded = 1; } - + /* Create the GLES window surface */ windowdata->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType)windowdata->hwnd); @@ -123,7 +125,7 @@ WIN_GLES_SetupWindow(_THIS, SDL_Window * window) return SDL_SetError("Could not create GLES window surface"); } - return WIN_GLES_MakeCurrent(_this, current_win, current_ctx); + return WIN_GLES_MakeCurrent(_this, current_win, current_ctx); } #endif /* SDL_VIDEO_DRIVER_WINDOWS && SDL_VIDEO_OPENGL_EGL */ diff --git a/SDL2-2.0.12/src/video/windows/SDL_windowsopengles.h b/SDL2-2.30.5/src/video/windows/SDL_windowsopengles.h similarity index 84% rename from SDL2-2.0.12/src/video/windows/SDL_windowsopengles.h rename to SDL2-2.30.5/src/video/windows/SDL_windowsopengles.h index 6ac5f7b..f7844b4 100644 --- a/SDL2-2.0.12/src/video/windows/SDL_windowsopengles.h +++ b/SDL2-2.30.5/src/video/windows/SDL_windowsopengles.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,7 +23,7 @@ #ifndef SDL_winopengles_h_ #define SDL_winopengles_h_ -#if SDL_VIDEO_OPENGL_EGL +#ifdef SDL_VIDEO_OPENGL_EGL #include "../SDL_sysvideo.h" #include "../SDL_egl_c.h" @@ -36,9 +36,9 @@ #define WIN_GLES_SetSwapInterval SDL_EGL_SetSwapInterval extern int WIN_GLES_LoadLibrary(_THIS, const char *path); -extern SDL_GLContext WIN_GLES_CreateContext(_THIS, SDL_Window * window); -extern int WIN_GLES_SwapWindow(_THIS, SDL_Window * window); -extern int WIN_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context); +extern SDL_GLContext WIN_GLES_CreateContext(_THIS, SDL_Window *window); +extern int WIN_GLES_SwapWindow(_THIS, SDL_Window *window); +extern int WIN_GLES_MakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context); extern void WIN_GLES_DeleteContext(_THIS, SDL_GLContext context); extern int WIN_GLES_SetupWindow(_THIS, SDL_Window * window); diff --git a/SDL2-2.0.12/src/video/windows/SDL_windowsshape.c b/SDL2-2.30.5/src/video/windows/SDL_windowsshape.c similarity index 54% rename from SDL2-2.0.12/src/video/windows/SDL_windowsshape.c rename to SDL2-2.30.5/src/video/windows/SDL_windowsshape.c index 1eb2e50..fdeb1cd 100644 --- a/SDL2-2.0.12/src/video/windows/SDL_windowsshape.c +++ b/SDL2-2.30.5/src/video/windows/SDL_windowsshape.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,66 +20,78 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_WINDOWS +#if defined(SDL_VIDEO_DRIVER_WINDOWS) && !defined(__XBOXONE__) && !defined(__XBOXSERIES__) -#include "SDL_assert.h" #include "SDL_windowsshape.h" #include "SDL_windowsvideo.h" -SDL_WindowShaper* -Win32_CreateShaper(SDL_Window * window) { +SDL_WindowShaper *Win32_CreateShaper(SDL_Window *window) +{ int resized_properly; - SDL_WindowShaper* result = (SDL_WindowShaper *)SDL_malloc(sizeof(SDL_WindowShaper)); + SDL_WindowShaper *result = (SDL_WindowShaper *)SDL_malloc(sizeof(SDL_WindowShaper)); + if (!result) { + SDL_OutOfMemory(); + return NULL; + } result->window = window; result->mode.mode = ShapeModeDefault; result->mode.parameters.binarizationCutoff = 1; result->userx = result->usery = 0; result->hasshape = SDL_FALSE; - result->driverdata = (SDL_ShapeData*)SDL_malloc(sizeof(SDL_ShapeData)); - ((SDL_ShapeData*)result->driverdata)->mask_tree = NULL; - /* Put some driver-data here. */ + result->driverdata = (SDL_ShapeData *)SDL_calloc(1, sizeof(SDL_ShapeData)); + if (!result->driverdata) { + SDL_free(result); + SDL_OutOfMemory(); + return NULL; + } window->shaper = result; + /* Put some driver-data here. */ resized_properly = Win32_ResizeWindowShape(window); - if (resized_properly != 0) - return NULL; + if (resized_properly != 0) { + SDL_free(result->driverdata); + SDL_free(result); + window->shaper = NULL; + return NULL; + } return result; } -static void -CombineRectRegions(SDL_ShapeTree* node,void* closure) { - HRGN mask_region = *((HRGN*)closure),temp_region = NULL; - if(node->kind == OpaqueShape) { +static void CombineRectRegions(SDL_ShapeTree *node, void *closure) +{ + HRGN mask_region = *((HRGN *)closure), temp_region = NULL; + if (node->kind == OpaqueShape) { /* Win32 API regions exclude their outline, so we widen the region by one pixel in each direction to include the real outline. */ - temp_region = CreateRectRgn(node->data.shape.x,node->data.shape.y,node->data.shape.x + node->data.shape.w + 1,node->data.shape.y + node->data.shape.h + 1); - if(mask_region != NULL) { - CombineRgn(mask_region,mask_region,temp_region,RGN_OR); + temp_region = CreateRectRgn(node->data.shape.x, node->data.shape.y, node->data.shape.x + node->data.shape.w + 1, node->data.shape.y + node->data.shape.h + 1); + if (mask_region != NULL) { + CombineRgn(mask_region, mask_region, temp_region, RGN_OR); DeleteObject(temp_region); + } else { + *((HRGN *)closure) = temp_region; } - else - *((HRGN*)closure) = temp_region; } } -int -Win32_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shape_mode) { +int Win32_SetWindowShape(SDL_WindowShaper *shaper, SDL_Surface *shape, SDL_WindowShapeMode *shape_mode) +{ SDL_ShapeData *data; HRGN mask_region = NULL; - if( (shaper == NULL) || - (shape == NULL) || + if ((!shaper) || + (!shape) || ((shape->format->Amask == 0) && (shape_mode->mode != ShapeModeColorKey)) || (shape->w != shaper->window->w) || - (shape->h != shaper->window->h) ) { + (shape->h != shaper->window->h)) { return SDL_INVALID_SHAPE_ARGUMENT; } - data = (SDL_ShapeData*)shaper->driverdata; - if(data->mask_tree != NULL) + data = (SDL_ShapeData *)shaper->driverdata; + if (data->mask_tree) { SDL_FreeShapeTree(&data->mask_tree); - data->mask_tree = SDL_CalculateShapeTree(*shape_mode,shape); + } + data->mask_tree = SDL_CalculateShapeTree(*shape_mode, shape); - SDL_TraverseShapeTree(data->mask_tree,&CombineRectRegions,&mask_region); + SDL_TraverseShapeTree(data->mask_tree, &CombineRectRegions, &mask_region); SDL_assert(mask_region != NULL); SetWindowRgn(((SDL_WindowData *)(shaper->window->driverdata))->hwnd, mask_region, TRUE); @@ -87,22 +99,25 @@ Win32_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShape return 0; } -int -Win32_ResizeWindowShape(SDL_Window *window) { - SDL_ShapeData* data; +int Win32_ResizeWindowShape(SDL_Window *window) +{ + SDL_ShapeData *data; - if (window == NULL) + if (!window) { return -1; + } data = (SDL_ShapeData *)window->shaper->driverdata; - if (data == NULL) + if (!data) { return -1; + } - if(data->mask_tree != NULL) + if (data->mask_tree) { SDL_FreeShapeTree(&data->mask_tree); - if(window->shaper->hasshape == SDL_TRUE) { + } + if (window->shaper->hasshape == SDL_TRUE) { window->shaper->userx = window->x; window->shaper->usery = window->y; - SDL_SetWindowPosition(window,-1000,-1000); + SDL_SetWindowPosition(window, -1000, -1000); } return 0; diff --git a/SDL2-2.0.12/src/video/windows/SDL_windowsshape.h b/SDL2-2.30.5/src/video/windows/SDL_windowsshape.h similarity index 82% rename from SDL2-2.0.12/src/video/windows/SDL_windowsshape.h rename to SDL2-2.30.5/src/video/windows/SDL_windowsshape.h index a5c786e..e1ce96a 100644 --- a/SDL2-2.0.12/src/video/windows/SDL_windowsshape.h +++ b/SDL2-2.30.5/src/video/windows/SDL_windowsshape.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -29,12 +29,13 @@ #include "../SDL_sysvideo.h" #include "../SDL_shape_internals.h" -typedef struct { +typedef struct +{ SDL_ShapeTree *mask_tree; } SDL_ShapeData; -extern SDL_WindowShaper* Win32_CreateShaper(SDL_Window * window); -extern int Win32_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shape_mode); +extern SDL_WindowShaper *Win32_CreateShaper(SDL_Window *window); +extern int Win32_SetWindowShape(SDL_WindowShaper *shaper, SDL_Surface *shape, SDL_WindowShapeMode *shape_mode); extern int Win32_ResizeWindowShape(SDL_Window *window); #endif /* SDL_windowsshape_h_ */ diff --git a/SDL2-2.30.5/src/video/windows/SDL_windowsvideo.c b/SDL2-2.30.5/src/video/windows/SDL_windowsvideo.c new file mode 100644 index 0000000..5f1902a --- /dev/null +++ b/SDL2-2.30.5/src/video/windows/SDL_windowsvideo.c @@ -0,0 +1,705 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_WINDOWS + +#include "SDL_main.h" +#include "SDL_video.h" +#include "SDL_hints.h" +#include "SDL_mouse.h" +#include "SDL_system.h" +#include "../SDL_sysvideo.h" +#include "../SDL_pixels_c.h" +#include "../../SDL_hints_c.h" + +#include "SDL_windowsvideo.h" +#include "SDL_windowsframebuffer.h" +#include "SDL_windowsshape.h" +#include "SDL_windowsvulkan.h" +#include "SDL_windowsmessagebox.h" + +/* #define HIGHDPI_DEBUG */ + +/* Initialization/Query functions */ +static int WIN_VideoInit(_THIS); +static void WIN_VideoQuit(_THIS); + +/* Hints */ +SDL_bool g_WindowsEnableMessageLoop = SDL_TRUE; +SDL_bool g_WindowsEnableMenuMnemonics = SDL_FALSE; +SDL_bool g_WindowFrameUsableWhileCursorHidden = SDL_TRUE; + +static void SDLCALL UpdateWindowsEnableMessageLoop(void *userdata, const char *name, const char *oldValue, const char *newValue) +{ + g_WindowsEnableMessageLoop = SDL_GetStringBoolean(newValue, SDL_TRUE); +} + +static void SDLCALL UpdateWindowsEnableMenuMnemonics(void *userdata, const char *name, const char *oldValue, const char *newValue) +{ + g_WindowsEnableMenuMnemonics = SDL_GetStringBoolean(newValue, SDL_FALSE); +} + +static void SDLCALL UpdateWindowFrameUsableWhileCursorHidden(void *userdata, const char *name, const char *oldValue, const char *newValue) +{ + g_WindowFrameUsableWhileCursorHidden = SDL_GetStringBoolean(newValue, SDL_TRUE); +} + +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) +static void WIN_SuspendScreenSaver(_THIS) +{ + if (_this->suspend_screensaver) { + SetThreadExecutionState(ES_CONTINUOUS | ES_DISPLAY_REQUIRED); + } else { + SetThreadExecutionState(ES_CONTINUOUS); + } +} +#endif + +#if defined(__XBOXONE__) || defined(__XBOXSERIES__) +extern void D3D12_XBOX_GetResolution(Uint32 *width, Uint32 *height); +#endif + +/* Windows driver bootstrap functions */ + +static void WIN_DeleteDevice(SDL_VideoDevice *device) +{ + SDL_VideoData *data = (SDL_VideoData *)device->driverdata; + + SDL_UnregisterApp(); +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + if (data->userDLL) { + SDL_UnloadObject(data->userDLL); + } + if (data->shcoreDLL) { + SDL_UnloadObject(data->shcoreDLL); + } +#endif + if (device->wakeup_lock) { + SDL_DestroyMutex(device->wakeup_lock); + } + SDL_free(device->driverdata); + SDL_free(device); +} + +static SDL_VideoDevice *WIN_CreateDevice(void) +{ + SDL_VideoDevice *device; + SDL_VideoData *data; + + SDL_RegisterApp(NULL, 0, NULL); + + /* Initialize all variables that we clean on shutdown */ + device = (SDL_VideoDevice *)SDL_calloc(1, sizeof(SDL_VideoDevice)); + if (device) { + data = (struct SDL_VideoData *)SDL_calloc(1, sizeof(SDL_VideoData)); + } else { + data = NULL; + } + if (!data) { + SDL_free(device); + SDL_OutOfMemory(); + return NULL; + } + device->driverdata = data; + device->wakeup_lock = SDL_CreateMutex(); + +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + data->userDLL = SDL_LoadObject("USER32.DLL"); + if (data->userDLL) { + /* *INDENT-OFF* */ /* clang-format off */ + data->CloseTouchInputHandle = (BOOL (WINAPI *)(HTOUCHINPUT))SDL_LoadFunction(data->userDLL, "CloseTouchInputHandle"); + data->GetTouchInputInfo = (BOOL (WINAPI *)(HTOUCHINPUT, UINT, PTOUCHINPUT, int)) SDL_LoadFunction(data->userDLL, "GetTouchInputInfo"); + data->RegisterTouchWindow = (BOOL (WINAPI *)(HWND, ULONG))SDL_LoadFunction(data->userDLL, "RegisterTouchWindow"); + data->SetProcessDPIAware = (BOOL (WINAPI *)(void))SDL_LoadFunction(data->userDLL, "SetProcessDPIAware"); + data->SetProcessDpiAwarenessContext = (BOOL (WINAPI *)(DPI_AWARENESS_CONTEXT))SDL_LoadFunction(data->userDLL, "SetProcessDpiAwarenessContext"); + data->SetThreadDpiAwarenessContext = (DPI_AWARENESS_CONTEXT (WINAPI *)(DPI_AWARENESS_CONTEXT))SDL_LoadFunction(data->userDLL, "SetThreadDpiAwarenessContext"); + data->GetThreadDpiAwarenessContext = (DPI_AWARENESS_CONTEXT (WINAPI *)(void))SDL_LoadFunction(data->userDLL, "GetThreadDpiAwarenessContext"); + data->GetAwarenessFromDpiAwarenessContext = (DPI_AWARENESS (WINAPI *)(DPI_AWARENESS_CONTEXT))SDL_LoadFunction(data->userDLL, "GetAwarenessFromDpiAwarenessContext"); + data->EnableNonClientDpiScaling = (BOOL (WINAPI *)(HWND))SDL_LoadFunction(data->userDLL, "EnableNonClientDpiScaling"); + data->AdjustWindowRectExForDpi = (BOOL (WINAPI *)(LPRECT, DWORD, BOOL, DWORD, UINT))SDL_LoadFunction(data->userDLL, "AdjustWindowRectExForDpi"); + data->GetDpiForWindow = (UINT (WINAPI *)(HWND))SDL_LoadFunction(data->userDLL, "GetDpiForWindow"); + data->AreDpiAwarenessContextsEqual = (BOOL (WINAPI *)(DPI_AWARENESS_CONTEXT, DPI_AWARENESS_CONTEXT))SDL_LoadFunction(data->userDLL, "AreDpiAwarenessContextsEqual"); + data->IsValidDpiAwarenessContext = (BOOL (WINAPI *)(DPI_AWARENESS_CONTEXT))SDL_LoadFunction(data->userDLL, "IsValidDpiAwarenessContext"); + /* *INDENT-ON* */ /* clang-format on */ + } else { + SDL_ClearError(); + } + + data->shcoreDLL = SDL_LoadObject("SHCORE.DLL"); + if (data->shcoreDLL) { + /* *INDENT-OFF* */ /* clang-format off */ + data->GetDpiForMonitor = (HRESULT (WINAPI *)(HMONITOR, MONITOR_DPI_TYPE, UINT *, UINT *))SDL_LoadFunction(data->shcoreDLL, "GetDpiForMonitor"); + data->SetProcessDpiAwareness = (HRESULT (WINAPI *)(PROCESS_DPI_AWARENESS))SDL_LoadFunction(data->shcoreDLL, "SetProcessDpiAwareness"); + /* *INDENT-ON* */ /* clang-format on */ + } else { + SDL_ClearError(); + } +#endif /* #if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) */ + + /* Set the function pointers */ + device->VideoInit = WIN_VideoInit; + device->VideoQuit = WIN_VideoQuit; +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + device->RefreshDisplays = WIN_RefreshDisplays; + device->GetDisplayBounds = WIN_GetDisplayBounds; + device->GetDisplayUsableBounds = WIN_GetDisplayUsableBounds; + device->GetDisplayDPI = WIN_GetDisplayDPI; + device->GetDisplayModes = WIN_GetDisplayModes; + device->SetDisplayMode = WIN_SetDisplayMode; +#endif + device->PumpEvents = WIN_PumpEvents; + device->WaitEventTimeout = WIN_WaitEventTimeout; +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + device->SendWakeupEvent = WIN_SendWakeupEvent; + device->SuspendScreenSaver = WIN_SuspendScreenSaver; +#endif + + device->CreateSDLWindow = WIN_CreateWindow; + device->CreateSDLWindowFrom = WIN_CreateWindowFrom; + device->SetWindowTitle = WIN_SetWindowTitle; + device->SetWindowIcon = WIN_SetWindowIcon; + device->SetWindowPosition = WIN_SetWindowPosition; + device->SetWindowSize = WIN_SetWindowSize; + device->GetWindowBordersSize = WIN_GetWindowBordersSize; + device->GetWindowSizeInPixels = WIN_GetWindowSizeInPixels; + device->SetWindowOpacity = WIN_SetWindowOpacity; + device->ShowWindow = WIN_ShowWindow; + device->HideWindow = WIN_HideWindow; + device->RaiseWindow = WIN_RaiseWindow; + device->MaximizeWindow = WIN_MaximizeWindow; + device->MinimizeWindow = WIN_MinimizeWindow; + device->RestoreWindow = WIN_RestoreWindow; + device->SetWindowBordered = WIN_SetWindowBordered; + device->SetWindowResizable = WIN_SetWindowResizable; + device->SetWindowAlwaysOnTop = WIN_SetWindowAlwaysOnTop; + device->SetWindowFullscreen = WIN_SetWindowFullscreen; +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + device->SetWindowGammaRamp = WIN_SetWindowGammaRamp; + device->GetWindowICCProfile = WIN_GetWindowICCProfile; + device->GetWindowGammaRamp = WIN_GetWindowGammaRamp; + device->SetWindowMouseRect = WIN_SetWindowMouseRect; + device->SetWindowMouseGrab = WIN_SetWindowMouseGrab; + device->SetWindowKeyboardGrab = WIN_SetWindowKeyboardGrab; +#endif + device->DestroyWindow = WIN_DestroyWindow; + device->GetWindowWMInfo = WIN_GetWindowWMInfo; +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + device->CreateWindowFramebuffer = WIN_CreateWindowFramebuffer; + device->UpdateWindowFramebuffer = WIN_UpdateWindowFramebuffer; + device->DestroyWindowFramebuffer = WIN_DestroyWindowFramebuffer; + device->OnWindowEnter = WIN_OnWindowEnter; + device->SetWindowHitTest = WIN_SetWindowHitTest; + device->AcceptDragAndDrop = WIN_AcceptDragAndDrop; + device->FlashWindow = WIN_FlashWindow; + + device->shape_driver.CreateShaper = Win32_CreateShaper; + device->shape_driver.SetWindowShape = Win32_SetWindowShape; + device->shape_driver.ResizeWindowShape = Win32_ResizeWindowShape; +#endif + +#ifdef SDL_VIDEO_OPENGL_WGL + device->GL_LoadLibrary = WIN_GL_LoadLibrary; + device->GL_GetProcAddress = WIN_GL_GetProcAddress; + device->GL_UnloadLibrary = WIN_GL_UnloadLibrary; + device->GL_CreateContext = WIN_GL_CreateContext; + device->GL_MakeCurrent = WIN_GL_MakeCurrent; + device->GL_SetSwapInterval = WIN_GL_SetSwapInterval; + device->GL_GetSwapInterval = WIN_GL_GetSwapInterval; + device->GL_SwapWindow = WIN_GL_SwapWindow; + device->GL_DeleteContext = WIN_GL_DeleteContext; +#elif defined(SDL_VIDEO_OPENGL_EGL) + /* Use EGL based functions */ + device->GL_LoadLibrary = WIN_GLES_LoadLibrary; + device->GL_GetProcAddress = WIN_GLES_GetProcAddress; + device->GL_UnloadLibrary = WIN_GLES_UnloadLibrary; + device->GL_CreateContext = WIN_GLES_CreateContext; + device->GL_MakeCurrent = WIN_GLES_MakeCurrent; + device->GL_SetSwapInterval = WIN_GLES_SetSwapInterval; + device->GL_GetSwapInterval = WIN_GLES_GetSwapInterval; + device->GL_SwapWindow = WIN_GLES_SwapWindow; + device->GL_DeleteContext = WIN_GLES_DeleteContext; +#endif +#ifdef SDL_VIDEO_VULKAN + device->Vulkan_LoadLibrary = WIN_Vulkan_LoadLibrary; + device->Vulkan_UnloadLibrary = WIN_Vulkan_UnloadLibrary; + device->Vulkan_GetInstanceExtensions = WIN_Vulkan_GetInstanceExtensions; + device->Vulkan_CreateSurface = WIN_Vulkan_CreateSurface; +#endif + +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + device->StartTextInput = WIN_StartTextInput; + device->StopTextInput = WIN_StopTextInput; + device->SetTextInputRect = WIN_SetTextInputRect; + device->ClearComposition = WIN_ClearComposition; + device->IsTextInputShown = WIN_IsTextInputShown; + + device->SetClipboardText = WIN_SetClipboardText; + device->GetClipboardText = WIN_GetClipboardText; + device->HasClipboardText = WIN_HasClipboardText; +#endif + + device->free = WIN_DeleteDevice; + + return device; +} + +VideoBootStrap WINDOWS_bootstrap = { + "windows", "SDL Windows video driver", WIN_CreateDevice, + #if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + WIN_ShowMessageBox + #else + NULL + #endif +}; + +static BOOL WIN_DeclareDPIAwareUnaware(_THIS) +{ +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; + + if (data->SetProcessDpiAwarenessContext) { + return data->SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_UNAWARE); + } else if (data->SetProcessDpiAwareness) { + /* Windows 8.1 */ + return SUCCEEDED(data->SetProcessDpiAwareness(PROCESS_DPI_UNAWARE)); + } +#endif + return FALSE; +} + +static BOOL WIN_DeclareDPIAwareSystem(_THIS) +{ +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; + + if (data->SetProcessDpiAwarenessContext) { + /* Windows 10, version 1607 */ + return data->SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_SYSTEM_AWARE); + } else if (data->SetProcessDpiAwareness) { + /* Windows 8.1 */ + return SUCCEEDED(data->SetProcessDpiAwareness(PROCESS_SYSTEM_DPI_AWARE)); + } else if (data->SetProcessDPIAware) { + /* Windows Vista */ + return data->SetProcessDPIAware(); + } +#endif + return FALSE; +} + +static BOOL WIN_DeclareDPIAwarePerMonitor(_THIS) +{ +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; + + if (data->SetProcessDpiAwarenessContext) { + /* Windows 10, version 1607 */ + return data->SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE); + } else if (data->SetProcessDpiAwareness) { + /* Windows 8.1 */ + return SUCCEEDED(data->SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE)); + } else { + /* Older OS: fall back to system DPI aware */ + return WIN_DeclareDPIAwareSystem(_this); + } +#endif + return FALSE; +} + +static BOOL WIN_DeclareDPIAwarePerMonitorV2(_THIS) +{ +#if defined(__XBOXONE__) || defined(__XBOXSERIES__) + return FALSE; +#else + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; + + /* Declare DPI aware (may have been done in external code or a manifest, as well) */ + if (data->SetProcessDpiAwarenessContext) { + /* Windows 10, version 1607 */ + + /* NOTE: SetThreadDpiAwarenessContext doesn't work here with OpenGL - the OpenGL contents + end up still getting OS scaled. (tested on Windows 10 21H1 19043.1348, NVIDIA 496.49) + + NOTE: Enabling DPI awareness through Windows Explorer + (right click .exe -> Properties -> Compatibility -> High DPI Settings -> + check "Override high DPI Scaling behaviour", select Application) gives + a DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE context (at least on Windows 10 21H1), and + setting DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 will fail. + + NOTE: Entering exclusive fullscreen in a DPI_AWARENESS_CONTEXT_UNAWARE process + appears to cause Windows to change the .exe manifest to DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE + on future launches. This means attempting to use DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 + will fail in the future until you manually clear the "Override high DPI Scaling behaviour" + setting in Windows Explorer (tested on Windows 10 21H2). + */ + if (data->SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2)) { + return TRUE; + } else { + return WIN_DeclareDPIAwarePerMonitor(_this); + } + } else { + /* Older OS: fall back to per-monitor (or system) */ + return WIN_DeclareDPIAwarePerMonitor(_this); + } +#endif +} + +#ifdef HIGHDPI_DEBUG +static const char *WIN_GetDPIAwareness(_THIS) +{ + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; + + if (data->GetThreadDpiAwarenessContext && data->AreDpiAwarenessContextsEqual) { + DPI_AWARENESS_CONTEXT context = data->GetThreadDpiAwarenessContext(); + + if (data->AreDpiAwarenessContextsEqual(context, DPI_AWARENESS_CONTEXT_UNAWARE)) { + return "unaware"; + } else if (data->AreDpiAwarenessContextsEqual(context, DPI_AWARENESS_CONTEXT_SYSTEM_AWARE)) { + return "system"; + } else if (data->AreDpiAwarenessContextsEqual(context, DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE)) { + return "permonitor"; + } else if (data->AreDpiAwarenessContextsEqual(context, DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2)) { + return "permonitorv2"; + } else if (data->AreDpiAwarenessContextsEqual(context, DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED)) { + return "unaware_gdiscaled"; + } + } + + return ""; +} +#endif + +static void WIN_InitDPIAwareness(_THIS) +{ + const char *hint = SDL_GetHint(SDL_HINT_WINDOWS_DPI_AWARENESS); + + if (hint) { + if (SDL_strcmp(hint, "permonitorv2") == 0) { + WIN_DeclareDPIAwarePerMonitorV2(_this); + } else if (SDL_strcmp(hint, "permonitor") == 0) { + WIN_DeclareDPIAwarePerMonitor(_this); + } else if (SDL_strcmp(hint, "system") == 0) { + WIN_DeclareDPIAwareSystem(_this); + } else if (SDL_strcmp(hint, "unaware") == 0) { + WIN_DeclareDPIAwareUnaware(_this); + } + } +} + +static void WIN_InitDPIScaling(_THIS) +{ + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; + + if (SDL_GetHintBoolean(SDL_HINT_WINDOWS_DPI_SCALING, SDL_FALSE)) { + WIN_DeclareDPIAwarePerMonitorV2(_this); + + data->dpi_scaling_enabled = SDL_TRUE; + } +} + +int WIN_VideoInit(_THIS) +{ + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; + + WIN_InitDPIAwareness(_this); + WIN_InitDPIScaling(_this); + +#ifdef HIGHDPI_DEBUG + SDL_Log("DPI awareness: %s", WIN_GetDPIAwareness(_this)); +#endif + +#if defined(__XBOXONE__) || defined(__XBOXSERIES__) + /* For Xbox, we just need to create the single display */ + { + SDL_VideoDisplay display; + SDL_DisplayMode current_mode; + + SDL_zero(current_mode); + D3D12_XBOX_GetResolution(¤t_mode.w, ¤t_mode.h); + current_mode.refresh_rate = 60; + current_mode.format = SDL_PIXELFORMAT_ARGB8888; + + SDL_zero(display); + display.desktop_mode = current_mode; + display.current_mode = current_mode; + + SDL_AddVideoDisplay(&display, SDL_FALSE); + } +#else /*!defined(__XBOXONE__) && !defined(__XBOXSERIES__)*/ + if (WIN_InitModes(_this) < 0) { + return -1; + } + + WIN_InitKeyboard(_this); + WIN_InitMouse(_this); +#endif + + SDL_AddHintCallback(SDL_HINT_WINDOWS_ENABLE_MESSAGELOOP, UpdateWindowsEnableMessageLoop, NULL); + SDL_AddHintCallback(SDL_HINT_WINDOWS_ENABLE_MENU_MNEMONICS, UpdateWindowsEnableMenuMnemonics, NULL); + SDL_AddHintCallback(SDL_HINT_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN, UpdateWindowFrameUsableWhileCursorHidden, NULL); + +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + data->_SDL_WAKEUP = RegisterWindowMessageA("_SDL_WAKEUP"); +#endif + + return 0; +} + +void WIN_VideoQuit(_THIS) +{ +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + WIN_QuitModes(_this); + WIN_QuitKeyboard(_this); + WIN_QuitMouse(_this); +#endif +} + +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) +#define D3D_DEBUG_INFO +#include + +#ifdef D3D_DEBUG_INFO +#ifndef D3D_SDK_VERSION +#define D3D_SDK_VERSION (32 | 0x80000000) +#endif +#ifndef D3D9b_SDK_VERSION +#define D3D9b_SDK_VERSION (31 | 0x80000000) +#endif +#else /**/ +#ifndef D3D_SDK_VERSION +#define D3D_SDK_VERSION 32 +#endif +#ifndef D3D9b_SDK_VERSION +#define D3D9b_SDK_VERSION 31 +#endif +#endif + +SDL_bool D3D_LoadDLL(void **pD3DDLL, IDirect3D9 **pDirect3D9Interface) +{ + *pD3DDLL = SDL_LoadObject("D3D9.DLL"); + if (*pD3DDLL) { + /* *INDENT-OFF* */ /* clang-format off */ + typedef IDirect3D9 *(WINAPI *Direct3DCreate9_t)(UINT SDKVersion); + typedef HRESULT (WINAPI* Direct3DCreate9Ex_t)(UINT SDKVersion, IDirect3D9Ex** ppD3D); + /* *INDENT-ON* */ /* clang-format on */ + Direct3DCreate9_t Direct3DCreate9Func; + + if (SDL_GetHintBoolean(SDL_HINT_WINDOWS_USE_D3D9EX, SDL_FALSE)) { + Direct3DCreate9Ex_t Direct3DCreate9ExFunc; + + Direct3DCreate9ExFunc = (Direct3DCreate9Ex_t)SDL_LoadFunction(*pD3DDLL, "Direct3DCreate9Ex"); + if (Direct3DCreate9ExFunc) { + IDirect3D9Ex *pDirect3D9ExInterface; + HRESULT hr = Direct3DCreate9ExFunc(D3D_SDK_VERSION, &pDirect3D9ExInterface); + if (SUCCEEDED(hr)) { + const GUID IDirect3D9_GUID = { 0x81bdcbca, 0x64d4, 0x426d, { 0xae, 0x8d, 0xad, 0x1, 0x47, 0xf4, 0x27, 0x5c } }; + hr = IDirect3D9Ex_QueryInterface(pDirect3D9ExInterface, &IDirect3D9_GUID, (void **)pDirect3D9Interface); + IDirect3D9Ex_Release(pDirect3D9ExInterface); + if (SUCCEEDED(hr)) { + return SDL_TRUE; + } + } + } + } + + Direct3DCreate9Func = (Direct3DCreate9_t)SDL_LoadFunction(*pD3DDLL, "Direct3DCreate9"); + if (Direct3DCreate9Func) { + *pDirect3D9Interface = Direct3DCreate9Func(D3D_SDK_VERSION); + if (*pDirect3D9Interface) { + return SDL_TRUE; + } + } + + SDL_UnloadObject(*pD3DDLL); + *pD3DDLL = NULL; + } + *pDirect3D9Interface = NULL; + return SDL_FALSE; +} + +int SDL_Direct3D9GetAdapterIndex(int displayIndex) +{ + void *pD3DDLL; + IDirect3D9 *pD3D; + if (!D3D_LoadDLL(&pD3DDLL, &pD3D)) { + SDL_SetError("Unable to create Direct3D interface"); + return D3DADAPTER_DEFAULT; + } else { + SDL_DisplayData *pData = (SDL_DisplayData *)SDL_GetDisplayDriverData(displayIndex); + int adapterIndex = D3DADAPTER_DEFAULT; + + if (!pData) { + SDL_SetError("Invalid display index"); + adapterIndex = -1; /* make sure we return something invalid */ + } else { + char *displayName = WIN_StringToUTF8W(pData->DeviceName); + unsigned int count = IDirect3D9_GetAdapterCount(pD3D); + unsigned int i; + for (i = 0; i < count; i++) { + D3DADAPTER_IDENTIFIER9 id; + IDirect3D9_GetAdapterIdentifier(pD3D, i, 0, &id); + + if (SDL_strcmp(id.DeviceName, displayName) == 0) { + adapterIndex = i; + break; + } + } + SDL_free(displayName); + } + + /* free up the D3D stuff we inited */ + IDirect3D9_Release(pD3D); + SDL_UnloadObject(pD3DDLL); + + return adapterIndex; + } +} +#endif /* !defined(__XBOXONE__) && !defined(__XBOXSERIES__) */ + +#if HAVE_DXGI_H +#define CINTERFACE +#define COBJMACROS +#include + +static SDL_bool DXGI_LoadDLL(void **pDXGIDLL, IDXGIFactory **pDXGIFactory) +{ + *pDXGIDLL = SDL_LoadObject("DXGI.DLL"); + if (*pDXGIDLL) { + /* *INDENT-OFF* */ /* clang-format off */ + typedef HRESULT (WINAPI *CreateDXGI_t)(REFIID riid, void **ppFactory); + /* *INDENT-ON* */ /* clang-format on */ + CreateDXGI_t CreateDXGI; + + CreateDXGI = (CreateDXGI_t)SDL_LoadFunction(*pDXGIDLL, "CreateDXGIFactory"); + if (CreateDXGI) { + GUID dxgiGUID = { 0x7b7166ec, 0x21c7, 0x44ae, { 0xb2, 0x1a, 0xc9, 0xae, 0x32, 0x1a, 0xe3, 0x69 } }; + if (!SUCCEEDED(CreateDXGI(&dxgiGUID, (void **)pDXGIFactory))) { + *pDXGIFactory = NULL; + } + } + if (!*pDXGIFactory) { + SDL_UnloadObject(*pDXGIDLL); + *pDXGIDLL = NULL; + return SDL_FALSE; + } + + return SDL_TRUE; + } else { + *pDXGIFactory = NULL; + return SDL_FALSE; + } +} +#endif + +SDL_bool SDL_DXGIGetOutputInfo(int displayIndex, int *adapterIndex, int *outputIndex) +{ +#if !HAVE_DXGI_H + if (adapterIndex) { + *adapterIndex = -1; + } + if (outputIndex) { + *outputIndex = -1; + } + SDL_SetError("SDL was compiled without DXGI support due to missing dxgi.h header"); + return SDL_FALSE; +#else + SDL_DisplayData *pData = (SDL_DisplayData *)SDL_GetDisplayDriverData(displayIndex); + void *pDXGIDLL; + char *displayName; + int nAdapter, nOutput; + IDXGIFactory *pDXGIFactory = NULL; + IDXGIAdapter *pDXGIAdapter; + IDXGIOutput *pDXGIOutput; + + if (!adapterIndex) { + SDL_InvalidParamError("adapterIndex"); + return SDL_FALSE; + } + + if (!outputIndex) { + SDL_InvalidParamError("outputIndex"); + return SDL_FALSE; + } + + *adapterIndex = -1; + *outputIndex = -1; + + if (!pData) { + SDL_SetError("Invalid display index"); + return SDL_FALSE; + } + + if (!DXGI_LoadDLL(&pDXGIDLL, &pDXGIFactory)) { + SDL_SetError("Unable to create DXGI interface"); + return SDL_FALSE; + } + + displayName = WIN_StringToUTF8W(pData->DeviceName); + nAdapter = 0; + while (*adapterIndex == -1 && SUCCEEDED(IDXGIFactory_EnumAdapters(pDXGIFactory, nAdapter, &pDXGIAdapter))) { + nOutput = 0; + while (*adapterIndex == -1 && SUCCEEDED(IDXGIAdapter_EnumOutputs(pDXGIAdapter, nOutput, &pDXGIOutput))) { + DXGI_OUTPUT_DESC outputDesc; + if (SUCCEEDED(IDXGIOutput_GetDesc(pDXGIOutput, &outputDesc))) { + char *outputName = WIN_StringToUTF8W(outputDesc.DeviceName); + if (SDL_strcmp(outputName, displayName) == 0) { + *adapterIndex = nAdapter; + *outputIndex = nOutput; + } + SDL_free(outputName); + } + IDXGIOutput_Release(pDXGIOutput); + nOutput++; + } + IDXGIAdapter_Release(pDXGIAdapter); + nAdapter++; + } + SDL_free(displayName); + + /* free up the DXGI factory */ + IDXGIFactory_Release(pDXGIFactory); + SDL_UnloadObject(pDXGIDLL); + + if (*adapterIndex == -1) { + return SDL_FALSE; + } else { + return SDL_TRUE; + } +#endif +} + +SDL_bool WIN_IsPerMonitorV2DPIAware(_THIS) +{ +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; + + if (data->AreDpiAwarenessContextsEqual && data->GetThreadDpiAwarenessContext) { + /* Windows 10, version 1607 */ + return (SDL_bool)data->AreDpiAwarenessContextsEqual(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2, + data->GetThreadDpiAwarenessContext()); + } +#endif + return SDL_FALSE; +} + +#endif /* SDL_VIDEO_DRIVER_WINDOWS */ + +/* vim: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/windows/SDL_windowsvideo.h b/SDL2-2.30.5/src/video/windows/SDL_windowsvideo.h new file mode 100644 index 0000000..93ca1cb --- /dev/null +++ b/SDL2-2.30.5/src/video/windows/SDL_windowsvideo.h @@ -0,0 +1,475 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifndef SDL_windowsvideo_h_ +#define SDL_windowsvideo_h_ + +#include "../../core/windows/SDL_windows.h" + +#include "../SDL_sysvideo.h" + +#if defined(_MSC_VER) && (_MSC_VER >= 1500) && !defined(__XBOXONE__) && !defined(__XBOXSERIES__) +#include +#else +#include "SDL_msctf.h" +#endif + +#include + +#define MAX_CANDLIST 10 +#define MAX_CANDLENGTH 256 +#define MAX_CANDSIZE (sizeof(WCHAR) * MAX_CANDLIST * MAX_CANDLENGTH) + +#include "SDL_windowsclipboard.h" +#include "SDL_windowsevents.h" +#include "SDL_windowsopengl.h" + +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) +#include "SDL_windowskeyboard.h" +#include "SDL_windowsmodes.h" +#include "SDL_windowsmouse.h" +#include "SDL_windowsopengles.h" +#endif + +#include "SDL_windowswindow.h" +#include "SDL_events.h" +#include "SDL_loadso.h" + +#if WINVER < 0x0601 +/* Touch input definitions */ +#define TWF_FINETOUCH 1 +#define TWF_WANTPALM 2 + +#define TOUCHEVENTF_MOVE 0x0001 +#define TOUCHEVENTF_DOWN 0x0002 +#define TOUCHEVENTF_UP 0x0004 + +DECLARE_HANDLE(HTOUCHINPUT); + +typedef struct _TOUCHINPUT +{ + LONG x; + LONG y; + HANDLE hSource; + DWORD dwID; + DWORD dwFlags; + DWORD dwMask; + DWORD dwTime; + ULONG_PTR dwExtraInfo; + DWORD cxContact; + DWORD cyContact; +} TOUCHINPUT, *PTOUCHINPUT; + +/* More-robust display information in Vista... */ +/* This is a huge amount of data to be stuffing into three API calls. :( */ +typedef struct DISPLAYCONFIG_PATH_SOURCE_INFO +{ + LUID adapterId; + UINT32 id; + union + { + UINT32 modeInfoIdx; + struct + { + UINT32 cloneGroupId : 16; + UINT32 sourceModeInfoIdx : 16; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; + + UINT32 statusFlags; +} DISPLAYCONFIG_PATH_SOURCE_INFO; + +typedef struct DISPLAYCONFIG_RATIONAL +{ + UINT32 Numerator; + UINT32 Denominator; +} DISPLAYCONFIG_RATIONAL; + +typedef struct DISPLAYCONFIG_PATH_TARGET_INFO +{ + LUID adapterId; + UINT32 id; + union + { + UINT32 modeInfoIdx; + struct + { + UINT32 desktopModeInfoIdx : 16; + UINT32 targetModeInfoIdx : 16; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; + UINT32 /*DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY*/ outputTechnology; + UINT32 /*DISPLAYCONFIG_ROTATION*/ rotation; + UINT32 /*DISPLAYCONFIG_SCALING*/ scaling; + DISPLAYCONFIG_RATIONAL refreshRate; + UINT32 /*DISPLAYCONFIG_SCANLINE_ORDERING*/ scanLineOrdering; + BOOL targetAvailable; + UINT32 statusFlags; +} DISPLAYCONFIG_PATH_TARGET_INFO; + +typedef struct DISPLAYCONFIG_PATH_INFO +{ + DISPLAYCONFIG_PATH_SOURCE_INFO sourceInfo; + DISPLAYCONFIG_PATH_TARGET_INFO targetInfo; + UINT32 flags; +} DISPLAYCONFIG_PATH_INFO; + +typedef enum +{ + DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE = 1, + DISPLAYCONFIG_MODE_INFO_TYPE_TARGET = 2, + DISPLAYCONFIG_MODE_INFO_TYPE_DESKTOP_IMAGE = 3, + DISPLAYCONFIG_MODE_INFO_TYPE_FORCE_UINT32 = 0xFFFFFFFF +} DISPLAYCONFIG_MODE_INFO_TYPE; + +typedef struct DISPLAYCONFIG_2DREGION +{ + UINT32 cx; + UINT32 cy; +} DISPLAYCONFIG_2DREGION; + +typedef struct DISPLAYCONFIG_VIDEO_SIGNAL_INFO +{ + UINT64 pixelRate; + DISPLAYCONFIG_RATIONAL hSyncFreq; + DISPLAYCONFIG_RATIONAL vSyncFreq; + DISPLAYCONFIG_2DREGION activeSize; + DISPLAYCONFIG_2DREGION totalSize; + + union + { + struct + { + UINT32 videoStandard : 16; + + // Vertical refresh frequency divider + UINT32 vSyncFreqDivider : 6; + + UINT32 reserved : 10; + } AdditionalSignalInfo; + + UINT32 videoStandard; + } DUMMYUNIONNAME; + + // Scan line ordering (e.g. progressive, interlaced). + UINT32 /*DISPLAYCONFIG_SCANLINE_ORDERING*/ scanLineOrdering; +} DISPLAYCONFIG_VIDEO_SIGNAL_INFO; + +typedef struct DISPLAYCONFIG_SOURCE_MODE +{ + UINT32 width; + UINT32 height; + UINT32 /*DISPLAYCONFIG_PIXELFORMAT*/ pixelFormat; + POINTL position; +} DISPLAYCONFIG_SOURCE_MODE; + +typedef struct DISPLAYCONFIG_TARGET_MODE +{ + DISPLAYCONFIG_VIDEO_SIGNAL_INFO targetVideoSignalInfo; +} DISPLAYCONFIG_TARGET_MODE; + +typedef struct DISPLAYCONFIG_DESKTOP_IMAGE_INFO +{ + POINTL PathSourceSize; + RECTL DesktopImageRegion; + RECTL DesktopImageClip; +} DISPLAYCONFIG_DESKTOP_IMAGE_INFO; + +typedef struct DISPLAYCONFIG_MODE_INFO +{ + DISPLAYCONFIG_MODE_INFO_TYPE infoType; + UINT32 id; + LUID adapterId; + union + { + DISPLAYCONFIG_TARGET_MODE targetMode; + DISPLAYCONFIG_SOURCE_MODE sourceMode; + DISPLAYCONFIG_DESKTOP_IMAGE_INFO desktopImageInfo; + } DUMMYUNIONNAME; +} DISPLAYCONFIG_MODE_INFO; + +typedef enum DISPLAYCONFIG_TOPOLOGY_ID +{ + DISPLAYCONFIG_TOPOLOGY_INTERNAL = 0x00000001, + DISPLAYCONFIG_TOPOLOGY_CLONE = 0x00000002, + DISPLAYCONFIG_TOPOLOGY_EXTEND = 0x00000004, + DISPLAYCONFIG_TOPOLOGY_EXTERNAL = 0x00000008, + DISPLAYCONFIG_TOPOLOGY_FORCE_UINT32 = 0xFFFFFFFF +} DISPLAYCONFIG_TOPOLOGY_ID; + +typedef enum +{ + DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME = 1, + DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME = 2, + DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_PREFERRED_MODE = 3, + DISPLAYCONFIG_DEVICE_INFO_GET_ADAPTER_NAME = 4, + DISPLAYCONFIG_DEVICE_INFO_SET_TARGET_PERSISTENCE = 5, + DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_BASE_TYPE = 6, + DISPLAYCONFIG_DEVICE_INFO_GET_SUPPORT_VIRTUAL_RESOLUTION = 7, + DISPLAYCONFIG_DEVICE_INFO_SET_SUPPORT_VIRTUAL_RESOLUTION = 8, + DISPLAYCONFIG_DEVICE_INFO_GET_ADVANCED_COLOR_INFO = 9, + DISPLAYCONFIG_DEVICE_INFO_SET_ADVANCED_COLOR_STATE = 10, + DISPLAYCONFIG_DEVICE_INFO_GET_SDR_WHITE_LEVEL = 11, + DISPLAYCONFIG_DEVICE_INFO_FORCE_UINT32 = 0xFFFFFFFF +} DISPLAYCONFIG_DEVICE_INFO_TYPE; + +typedef struct DISPLAYCONFIG_DEVICE_INFO_HEADER +{ + DISPLAYCONFIG_DEVICE_INFO_TYPE type; + UINT32 size; + LUID adapterId; + UINT32 id; +} DISPLAYCONFIG_DEVICE_INFO_HEADER; + +typedef struct DISPLAYCONFIG_SOURCE_DEVICE_NAME +{ + DISPLAYCONFIG_DEVICE_INFO_HEADER header; + WCHAR viewGdiDeviceName[CCHDEVICENAME]; +} DISPLAYCONFIG_SOURCE_DEVICE_NAME; + +typedef struct DISPLAYCONFIG_TARGET_DEVICE_NAME_FLAGS +{ + union + { + struct + { + UINT32 friendlyNameFromEdid : 1; + UINT32 friendlyNameForced : 1; + UINT32 edidIdsValid : 1; + UINT32 reserved : 29; + } DUMMYSTRUCTNAME; + UINT32 value; + } DUMMYUNIONNAME; +} DISPLAYCONFIG_TARGET_DEVICE_NAME_FLAGS; + +typedef struct DISPLAYCONFIG_TARGET_DEVICE_NAME +{ + DISPLAYCONFIG_DEVICE_INFO_HEADER header; + DISPLAYCONFIG_TARGET_DEVICE_NAME_FLAGS flags; + UINT32 /*DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY*/ outputTechnology; + UINT16 edidManufactureId; + UINT16 edidProductCodeId; + UINT32 connectorInstance; + WCHAR monitorFriendlyDeviceName[64]; + WCHAR monitorDevicePath[128]; +} DISPLAYCONFIG_TARGET_DEVICE_NAME; + +#define QDC_ONLY_ACTIVE_PATHS 0x00000002 + +#endif /* WINVER < 0x0601 */ + +#ifndef HAVE_SHELLSCALINGAPI_H + +typedef enum MONITOR_DPI_TYPE +{ + MDT_EFFECTIVE_DPI = 0, + MDT_ANGULAR_DPI = 1, + MDT_RAW_DPI = 2, + MDT_DEFAULT = MDT_EFFECTIVE_DPI +} MONITOR_DPI_TYPE; + +typedef enum PROCESS_DPI_AWARENESS +{ + PROCESS_DPI_UNAWARE = 0, + PROCESS_SYSTEM_DPI_AWARE = 1, + PROCESS_PER_MONITOR_DPI_AWARE = 2 +} PROCESS_DPI_AWARENESS; + +#else +#include +#endif + +#ifndef _DPI_AWARENESS_CONTEXTS_ + +typedef enum DPI_AWARENESS +{ + DPI_AWARENESS_INVALID = -1, + DPI_AWARENESS_UNAWARE = 0, + DPI_AWARENESS_SYSTEM_AWARE = 1, + DPI_AWARENESS_PER_MONITOR_AWARE = 2 +} DPI_AWARENESS; + +DECLARE_HANDLE(DPI_AWARENESS_CONTEXT); + +#define DPI_AWARENESS_CONTEXT_UNAWARE ((DPI_AWARENESS_CONTEXT)-1) +#define DPI_AWARENESS_CONTEXT_SYSTEM_AWARE ((DPI_AWARENESS_CONTEXT)-2) +#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE ((DPI_AWARENESS_CONTEXT)-3) + +#endif /* _DPI_AWARENESS_CONTEXTS_ */ + +/* Windows 10 Creators Update */ +#if NTDDI_VERSION < 0x0A000003 +#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((DPI_AWARENESS_CONTEXT)-4) +#endif /* NTDDI_VERSION < 0x0A000003 */ + +/* Windows 10 version 1809 */ +#if NTDDI_VERSION < 0x0A000006 +#define DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED ((DPI_AWARENESS_CONTEXT)-5) +#endif /* NTDDI_VERSION < 0x0A000006 */ + +typedef BOOL (*PFNSHFullScreen)(HWND, DWORD); +typedef void (*PFCoordTransform)(SDL_Window *, POINT *); + +typedef struct +{ + void **lpVtbl; + int refcount; + void *data; +} TSFSink; + +#ifndef SDL_DISABLE_WINDOWS_IME +/* Definition from Win98DDK version of IMM.H */ +typedef struct tagINPUTCONTEXT2 +{ + HWND hWnd; + BOOL fOpen; + POINT ptStatusWndPos; + POINT ptSoftKbdPos; + DWORD fdwConversion; + DWORD fdwSentence; + union + { + LOGFONTA A; + LOGFONTW W; + } lfFont; + COMPOSITIONFORM cfCompForm; + CANDIDATEFORM cfCandForm[4]; + HIMCC hCompStr; + HIMCC hCandInfo; + HIMCC hGuideLine; + HIMCC hPrivate; + DWORD dwNumMsgBuf; + HIMCC hMsgBuf; + DWORD fdwInit; + DWORD dwReserve[3]; +} INPUTCONTEXT2, *PINPUTCONTEXT2, NEAR *NPINPUTCONTEXT2, FAR *LPINPUTCONTEXT2; +#endif /* !SDL_DISABLE_WINDOWS_IME */ + +/* Private display data */ + +typedef struct SDL_VideoData +{ + int render; + + DWORD clipboard_count; + +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) /* Xbox doesn't support user32/shcore*/ + /* Touch input functions */ + void *userDLL; + /* *INDENT-OFF* */ /* clang-format off */ + BOOL (WINAPI *CloseTouchInputHandle)( HTOUCHINPUT ); + BOOL (WINAPI *GetTouchInputInfo)( HTOUCHINPUT, UINT, PTOUCHINPUT, int ); + BOOL (WINAPI *RegisterTouchWindow)( HWND, ULONG ); + BOOL (WINAPI *SetProcessDPIAware)( void ); + BOOL (WINAPI *SetProcessDpiAwarenessContext)( DPI_AWARENESS_CONTEXT ); + DPI_AWARENESS_CONTEXT (WINAPI *SetThreadDpiAwarenessContext)( DPI_AWARENESS_CONTEXT ); + DPI_AWARENESS_CONTEXT (WINAPI *GetThreadDpiAwarenessContext)( void ); + DPI_AWARENESS (WINAPI *GetAwarenessFromDpiAwarenessContext)( DPI_AWARENESS_CONTEXT ); + BOOL (WINAPI *EnableNonClientDpiScaling)( HWND ); + BOOL (WINAPI *AdjustWindowRectExForDpi)( LPRECT, DWORD, BOOL, DWORD, UINT ); + UINT (WINAPI *GetDpiForWindow)( HWND ); + BOOL (WINAPI *AreDpiAwarenessContextsEqual)(DPI_AWARENESS_CONTEXT, DPI_AWARENESS_CONTEXT); + BOOL (WINAPI *IsValidDpiAwarenessContext)(DPI_AWARENESS_CONTEXT); + /* *INDENT-ON* */ /* clang-format on */ + + void *shcoreDLL; + /* *INDENT-OFF* */ /* clang-format off */ + HRESULT (WINAPI *GetDpiForMonitor)( HMONITOR hmonitor, + MONITOR_DPI_TYPE dpiType, + UINT *dpiX, + UINT *dpiY ); + HRESULT (WINAPI *SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS dpiAwareness); + /* *INDENT-ON* */ /* clang-format on */ +#endif /*!defined(__XBOXONE__) && !defined(__XBOXSERIES__)*/ + + SDL_bool dpi_scaling_enabled; + SDL_bool cleared; + +#ifndef SDL_DISABLE_WINDOWS_IME + SDL_bool ime_com_initialized; + struct ITfThreadMgr *ime_threadmgr; + SDL_bool ime_initialized; + SDL_bool ime_enabled; + SDL_bool ime_available; + HWND ime_hwnd_main; + HWND ime_hwnd_current; + SDL_bool ime_suppress_endcomposition_event; + HIMC ime_himc; + + WCHAR *ime_composition; + int ime_composition_length; + WCHAR ime_readingstring[16]; + int ime_cursor; + + SDL_bool ime_candlist; + WCHAR *ime_candidates; + DWORD ime_candcount; + DWORD ime_candref; + DWORD ime_candsel; + UINT ime_candpgsize; + int ime_candlistindexbase; + SDL_bool ime_candvertical; + + SDL_bool ime_dirty; + SDL_Rect ime_rect; + SDL_Rect ime_candlistrect; + int ime_winwidth; + int ime_winheight; + + HKL ime_hkl; + void *ime_himm32; + /* *INDENT-OFF* */ /* clang-format off */ + UINT (WINAPI *GetReadingString)(HIMC himc, UINT uReadingBufLen, LPWSTR lpwReadingBuf, PINT pnErrorIndex, BOOL *pfIsVertical, PUINT puMaxReadingLen); + BOOL (WINAPI *ShowReadingWindow)(HIMC himc, BOOL bShow); + LPINPUTCONTEXT2 (WINAPI *ImmLockIMC)(HIMC himc); + BOOL (WINAPI *ImmUnlockIMC)(HIMC himc); + LPVOID (WINAPI *ImmLockIMCC)(HIMCC himcc); + BOOL (WINAPI *ImmUnlockIMCC)(HIMCC himcc); + /* *INDENT-ON* */ /* clang-format on */ + + SDL_bool ime_uiless; + struct ITfThreadMgrEx *ime_threadmgrex; + DWORD ime_uielemsinkcookie; + DWORD ime_alpnsinkcookie; + DWORD ime_openmodesinkcookie; + DWORD ime_convmodesinkcookie; + TSFSink *ime_uielemsink; + TSFSink *ime_ippasink; + LONG ime_uicontext; +#endif /* !SDL_DISABLE_WINDOWS_IME */ + + BYTE pre_hook_key_state[256]; + UINT _SDL_WAKEUP; +} SDL_VideoData; + +extern SDL_bool g_WindowsEnableMessageLoop; +extern SDL_bool g_WindowsEnableMenuMnemonics; +extern SDL_bool g_WindowFrameUsableWhileCursorHidden; + +typedef struct IDirect3D9 IDirect3D9; +extern SDL_bool D3D_LoadDLL(void **pD3DDLL, IDirect3D9 **pDirect3D9Interface); + +extern SDL_bool WIN_IsPerMonitorV2DPIAware(_THIS); + +#endif /* SDL_windowsvideo_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/windows/SDL_windowsvulkan.c b/SDL2-2.30.5/src/video/windows/SDL_windowsvulkan.c similarity index 77% rename from SDL2-2.0.12/src/video/windows/SDL_windowsvulkan.c rename to SDL2-2.30.5/src/video/windows/SDL_windowsvulkan.c index dc95c62..01ab8a5 100644 --- a/SDL2-2.0.12/src/video/windows/SDL_windowsvulkan.c +++ b/SDL2-2.30.5/src/video/windows/SDL_windowsvulkan.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,11 +26,10 @@ #include "../../SDL_internal.h" -#if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_WINDOWS +#if defined(SDL_VIDEO_VULKAN) && defined(SDL_VIDEO_DRIVER_WINDOWS) #include "SDL_windowsvideo.h" #include "SDL_windowswindow.h" -#include "SDL_assert.h" #include "SDL_loadso.h" #include "SDL_windowsvulkan.h" @@ -44,53 +43,55 @@ int WIN_Vulkan_LoadLibrary(_THIS, const char *path) SDL_bool hasSurfaceExtension = SDL_FALSE; SDL_bool hasWin32SurfaceExtension = SDL_FALSE; PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL; - if(_this->vulkan_config.loader_handle) + if (_this->vulkan_config.loader_handle) { return SDL_SetError("Vulkan already loaded"); + } /* Load the Vulkan loader library */ - if(!path) + if (!path) { path = SDL_getenv("SDL_VULKAN_LIBRARY"); - if(!path) + } + if (!path) { path = "vulkan-1.dll"; + } _this->vulkan_config.loader_handle = SDL_LoadObject(path); - if(!_this->vulkan_config.loader_handle) + if (!_this->vulkan_config.loader_handle) { return -1; + } SDL_strlcpy(_this->vulkan_config.loader_path, path, SDL_arraysize(_this->vulkan_config.loader_path)); vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)SDL_LoadFunction( _this->vulkan_config.loader_handle, "vkGetInstanceProcAddr"); - if(!vkGetInstanceProcAddr) + if (!vkGetInstanceProcAddr) { goto fail; + } _this->vulkan_config.vkGetInstanceProcAddr = (void *)vkGetInstanceProcAddr; _this->vulkan_config.vkEnumerateInstanceExtensionProperties = (void *)((PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr)( VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties"); - if(!_this->vulkan_config.vkEnumerateInstanceExtensionProperties) + if (!_this->vulkan_config.vkEnumerateInstanceExtensionProperties) { goto fail; + } extensions = SDL_Vulkan_CreateInstanceExtensionsList( (PFN_vkEnumerateInstanceExtensionProperties) _this->vulkan_config.vkEnumerateInstanceExtensionProperties, &extensionCount); - if(!extensions) + if (!extensions) { goto fail; - for(i = 0; i < extensionCount; i++) - { - if(SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) + } + for (i = 0; i < extensionCount; i++) { + if (SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) { hasSurfaceExtension = SDL_TRUE; - else if(SDL_strcmp(VK_KHR_WIN32_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) + } else if (SDL_strcmp(VK_KHR_WIN32_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) { hasWin32SurfaceExtension = SDL_TRUE; + } } SDL_free(extensions); - if(!hasSurfaceExtension) - { - SDL_SetError("Installed Vulkan doesn't implement the " - VK_KHR_SURFACE_EXTENSION_NAME " extension"); + if (!hasSurfaceExtension) { + SDL_SetError("Installed Vulkan doesn't implement the " VK_KHR_SURFACE_EXTENSION_NAME " extension"); goto fail; - } - else if(!hasWin32SurfaceExtension) - { - SDL_SetError("Installed Vulkan doesn't implement the " - VK_KHR_WIN32_SURFACE_EXTENSION_NAME "extension"); + } else if (!hasWin32SurfaceExtension) { + SDL_SetError("Installed Vulkan doesn't implement the " VK_KHR_WIN32_SURFACE_EXTENSION_NAME "extension"); goto fail; } return 0; @@ -103,8 +104,7 @@ fail: void WIN_Vulkan_UnloadLibrary(_THIS) { - if(_this->vulkan_config.loader_handle) - { + if (_this->vulkan_config.loader_handle) { SDL_UnloadObject(_this->vulkan_config.loader_handle); _this->vulkan_config.loader_handle = NULL; } @@ -118,14 +118,13 @@ SDL_bool WIN_Vulkan_GetInstanceExtensions(_THIS, static const char *const extensionsForWin32[] = { VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_WIN32_SURFACE_EXTENSION_NAME }; - if(!_this->vulkan_config.loader_handle) - { + if (!_this->vulkan_config.loader_handle) { SDL_SetError("Vulkan is not loaded"); return SDL_FALSE; } return SDL_Vulkan_GetInstanceExtensions_Helper( - count, names, SDL_arraysize(extensionsForWin32), - extensionsForWin32); + count, names, SDL_arraysize(extensionsForWin32), + extensionsForWin32); } SDL_bool WIN_Vulkan_CreateSurface(_THIS, @@ -138,19 +137,17 @@ SDL_bool WIN_Vulkan_CreateSurface(_THIS, (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr; PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR = (PFN_vkCreateWin32SurfaceKHR)vkGetInstanceProcAddr( - (VkInstance)instance, - "vkCreateWin32SurfaceKHR"); + instance, + "vkCreateWin32SurfaceKHR"); VkWin32SurfaceCreateInfoKHR createInfo; VkResult result; - if(!_this->vulkan_config.loader_handle) - { + if (!_this->vulkan_config.loader_handle) { SDL_SetError("Vulkan is not loaded"); return SDL_FALSE; } - if(!vkCreateWin32SurfaceKHR) - { + if (!vkCreateWin32SurfaceKHR) { SDL_SetError(VK_KHR_WIN32_SURFACE_EXTENSION_NAME " extension is not enabled in the Vulkan instance."); return SDL_FALSE; @@ -161,9 +158,8 @@ SDL_bool WIN_Vulkan_CreateSurface(_THIS, createInfo.hinstance = windowData->hinstance; createInfo.hwnd = windowData->hwnd; result = vkCreateWin32SurfaceKHR(instance, &createInfo, - NULL, surface); - if(result != VK_SUCCESS) - { + NULL, surface); + if (result != VK_SUCCESS) { SDL_SetError("vkCreateWin32SurfaceKHR failed: %s", SDL_Vulkan_GetResultString(result)); return SDL_FALSE; diff --git a/SDL2-2.0.12/src/video/windows/SDL_windowsvulkan.h b/SDL2-2.30.5/src/video/windows/SDL_windowsvulkan.h similarity index 93% rename from SDL2-2.0.12/src/video/windows/SDL_windowsvulkan.h rename to SDL2-2.30.5/src/video/windows/SDL_windowsvulkan.h index edf02b8..1545dcd 100644 --- a/SDL2-2.0.12/src/video/windows/SDL_windowsvulkan.h +++ b/SDL2-2.30.5/src/video/windows/SDL_windowsvulkan.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -32,7 +32,7 @@ #include "../SDL_vulkan_internal.h" #include "../SDL_sysvideo.h" -#if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_WINDOWS +#if defined(SDL_VIDEO_VULKAN) && defined(SDL_VIDEO_DRIVER_WINDOWS) int WIN_Vulkan_LoadLibrary(_THIS, const char *path); void WIN_Vulkan_UnloadLibrary(_THIS); diff --git a/SDL2-2.30.5/src/video/windows/SDL_windowswindow.c b/SDL2-2.30.5/src/video/windows/SDL_windowswindow.c new file mode 100644 index 0000000..cf49fbf --- /dev/null +++ b/SDL2-2.30.5/src/video/windows/SDL_windowswindow.c @@ -0,0 +1,1490 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_WINDOWS + +#include "../../core/windows/SDL_windows.h" + +#include "SDL_log.h" +#include "../SDL_sysvideo.h" +#include "../SDL_pixels_c.h" +#include "../../events/SDL_keyboard_c.h" +#include "../../events/SDL_mouse_c.h" +#include "../../events/SDL_windowevents_c.h" +#include "../../SDL_hints_c.h" + +#include "SDL_windowsvideo.h" +#include "SDL_windowswindow.h" +#include "SDL_windowsshape.h" +#include "SDL_hints.h" +#include "SDL_timer.h" + +/* Dropfile support */ +#include + +/* This is included after SDL_windowsvideo.h, which includes windows.h */ +#include "SDL_syswm.h" + +/* Windows CE compatibility */ +#ifndef SWP_NOCOPYBITS +#define SWP_NOCOPYBITS 0 +#endif + +/* #define HIGHDPI_DEBUG */ + +/* Fake window to help with DirectInput events. */ +HWND SDL_HelperWindow = NULL; +static const TCHAR *SDL_HelperWindowClassName = TEXT("SDLHelperWindowInputCatcher"); +static const TCHAR *SDL_HelperWindowName = TEXT("SDLHelperWindowInputMsgWindow"); +static ATOM SDL_HelperWindowClass = 0; + +/* For borderless Windows, still want the following flag: + - WS_MINIMIZEBOX: window will respond to Windows minimize commands sent to all windows, such as windows key + m, shaking title bar, etc. + Additionally, non-fullscreen windows can add: + - WS_CAPTION: this seems to enable the Windows minimize animation + - WS_SYSMENU: enables system context menu on task bar + This will also cause the task bar to overlap the window and other windowed behaviors, so only use this for windows that shouldn't appear to be fullscreen + */ + +#define STYLE_BASIC (WS_CLIPSIBLINGS | WS_CLIPCHILDREN) +#define STYLE_FULLSCREEN (WS_POPUP | WS_MINIMIZEBOX) +#define STYLE_BORDERLESS (WS_POPUP | WS_MINIMIZEBOX) +#define STYLE_BORDERLESS_WINDOWED (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) + +static DWORD GetWindowStyle(SDL_Window *window) +{ + DWORD style = 0; + + if (window->flags & SDL_WINDOW_FULLSCREEN) { + style |= STYLE_FULLSCREEN; + } else { + if (window->flags & SDL_WINDOW_BORDERLESS) { + /* SDL 2.1: + This behavior more closely matches other platform where the window is borderless + but still interacts with the window manager (e.g. task bar shows above it, it can + be resized to fit within usable desktop area, etc.) so this should be the behavior + for a future SDL release. + + If you want a borderless window the size of the desktop that looks like a fullscreen + window, then you should use the SDL_WINDOW_FULLSCREEN_DESKTOP flag. + */ + if (SDL_GetHintBoolean("SDL_BORDERLESS_WINDOWED_STYLE", SDL_FALSE)) { + style |= STYLE_BORDERLESS_WINDOWED; + } else { + style |= STYLE_BORDERLESS; + } + } else { + style |= STYLE_NORMAL; + } + + if (window->flags & SDL_WINDOW_RESIZABLE) { + /* You can have a borderless resizable window, but Windows doesn't always draw it correctly, + see https://bugzilla.libsdl.org/show_bug.cgi?id=4466 + */ + if (!(window->flags & SDL_WINDOW_BORDERLESS) || + SDL_GetHintBoolean("SDL_BORDERLESS_RESIZABLE_STYLE", SDL_FALSE)) { + style |= STYLE_RESIZABLE; + } + } + + /* Need to set initialize minimize style, or when we call ShowWindow with WS_MINIMIZE it will activate a random window */ + if (window->flags & SDL_WINDOW_MINIMIZED) { + style |= WS_MINIMIZE; + } + } + return style; +} + +/** + * Returns arguments to pass to SetWindowPos - the window rect, including frame, in Windows coordinates. + * Can be called before we have a HWND. + */ +static void WIN_AdjustWindowRectWithStyle(SDL_Window *window, DWORD style, BOOL menu, int *x, int *y, int *width, int *height, SDL_bool use_current) +{ + SDL_VideoData *videodata = SDL_GetVideoDevice() ? SDL_GetVideoDevice()->driverdata : NULL; + RECT rect; + int dpi = 96; +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + UINT frame_dpi; +#endif + + /* Client rect, in SDL screen coordinates */ + *x = (use_current ? window->x : window->windowed.x); + *y = (use_current ? window->y : window->windowed.y); + *width = (use_current ? window->w : window->windowed.w); + *height = (use_current ? window->h : window->windowed.h); + + /* Convert client rect from SDL coordinates to pixels (no-op if DPI scaling not enabled) */ +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + WIN_ScreenPointFromSDL(x, y, &dpi); +#endif + /* Note, use the guessed DPI returned from WIN_ScreenPointFromSDL rather than the cached one in + data->scaling_dpi. + + - This is called before the window is created, so we can't rely on data->scaling_dpi + - Bug workaround: when leaving exclusive fullscreen, the cached DPI and window DPI reported + by GetDpiForWindow will be wrong, and would cause windows shrinking slightly when + going from exclusive fullscreen to windowed on a HighDPI monitor with scaling if we used them. + */ + *width = MulDiv(*width, dpi, 96); + *height = MulDiv(*height, dpi, 96); + + /* Copy the client size in pixels into this rect structure, + which we'll then adjust with AdjustWindowRectEx */ + rect.left = 0; + rect.top = 0; + rect.right = *width; + rect.bottom = *height; + + /* 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)) { +#if defined(__XBOXONE__) || defined(__XBOXSERIES__) + AdjustWindowRectEx(&rect, style, menu, 0); +#else + if (WIN_IsPerMonitorV2DPIAware(SDL_GetVideoDevice())) { + /* With per-monitor v2, the window border/titlebar size depend on the DPI, so we need to call AdjustWindowRectExForDpi instead of + AdjustWindowRectEx. */ + UINT unused; + RECT screen_rect; + HMONITOR mon; + + screen_rect.left = *x; + screen_rect.top = *y; + screen_rect.right = (LONG)*x + *width; + screen_rect.bottom = (LONG)*y + *height; + + mon = MonitorFromRect(&screen_rect, MONITOR_DEFAULTTONEAREST); + + if (videodata) { + /* GetDpiForMonitor docs promise to return the same hdpi / vdpi */ + if (videodata->GetDpiForMonitor(mon, MDT_EFFECTIVE_DPI, &frame_dpi, &unused) != S_OK) { + frame_dpi = 96; + } + + videodata->AdjustWindowRectExForDpi(&rect, style, menu, 0, frame_dpi); + } + } else { + AdjustWindowRectEx(&rect, style, menu, 0); + } +#endif + } + + /* Final rect in Windows screen space, including the frame */ + *x += rect.left; + *y += rect.top; + *width = (rect.right - rect.left); + *height = (rect.bottom - rect.top); + +#ifdef HIGHDPI_DEBUG + SDL_Log("WIN_AdjustWindowRectWithStyle: in: %d, %d, %dx%d, returning: %d, %d, %dx%d, used dpi %d for frame calculation", + (use_current ? window->x : window->windowed.x), + (use_current ? window->y : window->windowed.y), + (use_current ? window->w : window->windowed.w), + (use_current ? window->h : window->windowed.h), + *x, *y, *width, *height, frame_dpi); +#endif +} + +static void WIN_AdjustWindowRect(SDL_Window *window, int *x, int *y, int *width, int *height, SDL_bool use_current) +{ + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + HWND hwnd = data->hwnd; + DWORD style; + BOOL menu; + + style = GetWindowLong(hwnd, GWL_STYLE); +#if defined(__XBOXONE__) || defined(__XBOXSERIES__) + menu = FALSE; +#else + menu = (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != NULL); +#endif + WIN_AdjustWindowRectWithStyle(window, style, menu, x, y, width, height, use_current); +} + +static void WIN_SetWindowPositionInternal(_THIS, SDL_Window *window, UINT flags) +{ + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + HWND hwnd = data->hwnd; + HWND top; + int x, y; + int w, h; + + /* Figure out what the window area will be */ + if (SDL_ShouldAllowTopmost() && (window->flags & SDL_WINDOW_ALWAYS_ON_TOP)) { + top = HWND_TOPMOST; + } else { + top = HWND_NOTOPMOST; + } + + WIN_AdjustWindowRect(window, &x, &y, &w, &h, SDL_TRUE); + + data->expected_resize = SDL_TRUE; + SetWindowPos(hwnd, top, x, y, w, h, flags); + data->expected_resize = SDL_FALSE; +} + +static void SDLCALL WIN_MouseRelativeModeCenterChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + SDL_WindowData *data = (SDL_WindowData *)userdata; + data->mouse_relative_mode_center = SDL_GetStringBoolean(hint, SDL_TRUE); +} + +static int WIN_GetScalingDPIForHWND(const SDL_VideoData *videodata, HWND hwnd) +{ +#if defined(__XBOXONE__) || defined(__XBOXSERIES__) + return 96; +#else + /* DPI scaling not requested? */ + if (!videodata->dpi_scaling_enabled) { + return 96; + } + + /* Window 10+ */ + if (videodata->GetDpiForWindow) { + return videodata->GetDpiForWindow(hwnd); + } + + /* Window 8.1+ */ + if (videodata->GetDpiForMonitor) { + HMONITOR monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); + if (monitor) { + UINT dpi_uint, unused; + if (S_OK == videodata->GetDpiForMonitor(monitor, MDT_EFFECTIVE_DPI, &dpi_uint, &unused)) { + return (int)dpi_uint; + } + } + return 96; + } + + /* Windows Vista-8.0 */ + { + HDC hdc = GetDC(NULL); + if (hdc) { + int dpi = GetDeviceCaps(hdc, LOGPIXELSX); + ReleaseDC(NULL, hdc); + return dpi; + } + return 96; + } +#endif +} + +static int SetupWindowData(_THIS, SDL_Window *window, HWND hwnd, HWND parent, SDL_bool created) +{ + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + SDL_WindowData *data; + + /* Allocate the window data */ + data = (SDL_WindowData *)SDL_calloc(1, sizeof(*data)); + if (!data) { + return SDL_OutOfMemory(); + } + data->window = window; + data->hwnd = hwnd; + data->parent = parent; +#if defined(__XBOXONE__) || defined(__XBOXSERIES__) + data->hdc = (HDC) data->hwnd; +#else + data->hdc = GetDC(hwnd); +#endif + data->hinstance = (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE); + data->created = created; + data->high_surrogate = 0; + data->mouse_button_flags = (WPARAM)-1; + data->last_pointer_update = (LPARAM)-1; + data->videodata = videodata; + data->initializing = SDL_TRUE; + data->scaling_dpi = WIN_GetScalingDPIForHWND(videodata, hwnd); + +#ifdef HIGHDPI_DEBUG + SDL_Log("SetupWindowData: initialized data->scaling_dpi to %d", data->scaling_dpi); +#endif + + SDL_AddHintCallback(SDL_HINT_MOUSE_RELATIVE_MODE_CENTER, WIN_MouseRelativeModeCenterChanged, data); + + window->driverdata = data; + +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + /* Associate the data with the window */ + if (!SetProp(hwnd, TEXT("SDL_WindowData"), data)) { + ReleaseDC(hwnd, data->hdc); + SDL_free(data); + return WIN_SetError("SetProp() failed"); + } +#endif + + /* Set up the window proc function */ +#ifdef GWLP_WNDPROC + data->wndproc = (WNDPROC)GetWindowLongPtr(hwnd, GWLP_WNDPROC); + if (data->wndproc == WIN_WindowProc) { + data->wndproc = NULL; + } else { + SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)WIN_WindowProc); + } +#else + data->wndproc = (WNDPROC)GetWindowLong(hwnd, GWL_WNDPROC); + if (data->wndproc == WIN_WindowProc) { + data->wndproc = NULL; + } else { + SetWindowLong(hwnd, GWL_WNDPROC, (LONG_PTR)WIN_WindowProc); + } +#endif + + /* Fill in the SDL window with the window data */ + { + RECT rect; + if (GetClientRect(hwnd, &rect)) { + int w = rect.right; + int h = rect.bottom; + + WIN_ClientPointToSDL(window, &w, &h); + if ((window->windowed.w && window->windowed.w != w) || (window->windowed.h && window->windowed.h != h)) { + /* We tried to create a window larger than the desktop and Windows didn't allow it. Override! */ + int x, y; + /* Figure out what the window area will be */ + WIN_AdjustWindowRect(window, &x, &y, &w, &h, SDL_FALSE); + data->expected_resize = SDL_TRUE; + SetWindowPos(hwnd, HWND_NOTOPMOST, x, y, w, h, SWP_NOCOPYBITS | SWP_NOZORDER | SWP_NOACTIVATE); + data->expected_resize = SDL_FALSE; + } else { + window->w = w; + window->h = h; + } + } + } +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + { + POINT point; + point.x = 0; + point.y = 0; + if (ClientToScreen(hwnd, &point)) { + int x = point.x; + int y = point.y; + WIN_ScreenPointToSDL(&x, &y); + window->x = x; + window->y = y; + } + } + WIN_UpdateWindowICCProfile(window, SDL_FALSE); +#endif + { + DWORD style = GetWindowLong(hwnd, GWL_STYLE); + if (style & WS_VISIBLE) { + window->flags |= SDL_WINDOW_SHOWN; + } else { + window->flags &= ~SDL_WINDOW_SHOWN; + } + if (style & WS_POPUP) { + window->flags |= SDL_WINDOW_BORDERLESS; + } else { + window->flags &= ~SDL_WINDOW_BORDERLESS; + } + if (style & WS_THICKFRAME) { + window->flags |= SDL_WINDOW_RESIZABLE; + } else { + window->flags &= ~SDL_WINDOW_RESIZABLE; + } +#ifdef WS_MAXIMIZE + if (style & WS_MAXIMIZE) { + window->flags |= SDL_WINDOW_MAXIMIZED; + } else +#endif + { + window->flags &= ~SDL_WINDOW_MAXIMIZED; + } +#ifdef WS_MINIMIZE + if (style & WS_MINIMIZE) { + window->flags |= SDL_WINDOW_MINIMIZED; + } else +#endif + { + window->flags &= ~SDL_WINDOW_MINIMIZED; + } + } +#if defined(__XBOXONE__) || defined(__XBOXSERIES__) + window->flags |= SDL_WINDOW_INPUT_FOCUS; +#else + if (GetFocus() == hwnd) { + window->flags |= SDL_WINDOW_INPUT_FOCUS; + SDL_SetKeyboardFocus(window); + WIN_UpdateClipCursor(window); + } +#endif + +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + /* Enable multi-touch */ + if (videodata->RegisterTouchWindow) { + videodata->RegisterTouchWindow(hwnd, (TWF_FINETOUCH | TWF_WANTPALM)); + } +#endif + + /* Force the SDL_WINDOW_ALLOW_HIGHDPI window flag if we are doing DPI scaling */ + if (videodata->dpi_scaling_enabled) { + window->flags |= SDL_WINDOW_ALLOW_HIGHDPI; + } + + data->initializing = SDL_FALSE; + + /* All done! */ + return 0; +} + +static void CleanupWindowData(_THIS, SDL_Window *window) +{ + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + + if (data) { + SDL_DelHintCallback(SDL_HINT_MOUSE_RELATIVE_MODE_CENTER, WIN_MouseRelativeModeCenterChanged, data); + +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + if (data->ICMFileName) { + SDL_free(data->ICMFileName); + } + if (data->keyboard_hook) { + UnhookWindowsHookEx(data->keyboard_hook); + } + ReleaseDC(data->hwnd, data->hdc); + RemoveProp(data->hwnd, TEXT("SDL_WindowData")); +#endif + if (data->created) { + DestroyWindow(data->hwnd); + if (data->parent) { + DestroyWindow(data->parent); + } + } else { + /* Restore any original event handler... */ + if (data->wndproc) { +#ifdef GWLP_WNDPROC + SetWindowLongPtr(data->hwnd, GWLP_WNDPROC, + (LONG_PTR)data->wndproc); +#else + SetWindowLong(data->hwnd, GWL_WNDPROC, + (LONG_PTR)data->wndproc); +#endif + } + } + SDL_free(data); + } + window->driverdata = NULL; +} + +int WIN_CreateWindow(_THIS, SDL_Window *window) +{ + HWND hwnd, parent = NULL; + DWORD style = STYLE_BASIC; + int x, y; + int w, h; + + if (window->flags & SDL_WINDOW_SKIP_TASKBAR) { + parent = CreateWindow(SDL_Appname, TEXT(""), STYLE_BASIC, 0, 0, 32, 32, NULL, NULL, SDL_Instance, NULL); + } + + style |= GetWindowStyle(window); + + /* Figure out what the window area will be */ + WIN_AdjustWindowRectWithStyle(window, style, FALSE, &x, &y, &w, &h, SDL_FALSE); + + hwnd = + CreateWindow(SDL_Appname, TEXT(""), style, x, y, w, h, parent, NULL, + SDL_Instance, NULL); + if (!hwnd) { + return WIN_SetError("Couldn't create window"); + } + + WIN_PumpEvents(_this); + + if (SetupWindowData(_this, window, hwnd, parent, SDL_TRUE) < 0) { + DestroyWindow(hwnd); + if (parent) { + DestroyWindow(parent); + } + 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_MINIMIZED) { + ShowWindow(hwnd, SW_SHOWMINNOACTIVE); + } + + if (!(window->flags & SDL_WINDOW_OPENGL)) { + return 0; + } + + /* The rest of this macro mess is for OpenGL or OpenGL ES windows */ +#ifdef SDL_VIDEO_OPENGL_ES2 + if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES +#ifdef SDL_VIDEO_OPENGL_WGL + && (!_this->gl_data || WIN_GL_UseEGL(_this)) +#endif /* SDL_VIDEO_OPENGL_WGL */ + ) { +#ifdef SDL_VIDEO_OPENGL_EGL + if (WIN_GLES_SetupWindow(_this, window) < 0) { + WIN_DestroyWindow(_this, window); + return -1; + } + return 0; +#else + return SDL_SetError("Could not create GLES window surface (EGL support not configured)"); +#endif /* SDL_VIDEO_OPENGL_EGL */ + } +#endif /* SDL_VIDEO_OPENGL_ES2 */ + +#ifdef SDL_VIDEO_OPENGL_WGL + if (WIN_GL_SetupWindow(_this, window) < 0) { + WIN_DestroyWindow(_this, window); + return -1; + } +#else + return SDL_SetError("Could not create GL window (WGL support not configured)"); +#endif + + return 0; +} + +int WIN_CreateWindowFrom(_THIS, SDL_Window *window, const void *data) +{ +#if defined(__XBOXONE__) || defined(__XBOXSERIES__) + return -1; +#else + HWND hwnd = (HWND)data; + LPTSTR title; + int titleLen; + SDL_bool isstack; + + /* Query the title from the existing window */ + titleLen = GetWindowTextLength(hwnd); + title = SDL_small_alloc(TCHAR, titleLen + 1, &isstack); + if (title) { + titleLen = GetWindowText(hwnd, title, titleLen + 1); + } else { + titleLen = 0; + } + if (titleLen > 0) { + window->title = WIN_StringToUTF8(title); + } + if (title) { + SDL_small_free(title, isstack); + } + + if (SetupWindowData(_this, window, hwnd, GetParent(hwnd), SDL_FALSE) < 0) { + return -1; + } + +#ifdef SDL_VIDEO_OPENGL_WGL + { + const char *hint = SDL_GetHint(SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT); + if (hint) { + /* This hint is a pointer (in string form) of the address of + the window to share a pixel format with + */ + SDL_Window *otherWindow = NULL; + (void)SDL_sscanf(hint, "%p", (void **)&otherWindow); + + /* Do some error checking on the pointer */ + if (otherWindow && otherWindow->magic == &_this->window_magic) { + /* If the otherWindow has SDL_WINDOW_OPENGL set, set it for the new window as well */ + if (otherWindow->flags & SDL_WINDOW_OPENGL) { + window->flags |= SDL_WINDOW_OPENGL; + if (!WIN_GL_SetPixelFormatFrom(_this, otherWindow, window)) { + return -1; + } + } + } + } else if (window->flags & SDL_WINDOW_OPENGL) { + /* Try to set up the pixel format, if it hasn't been set by the application */ + WIN_GL_SetupWindow(_this, window); + } + } +#endif + return 0; +#endif /*!defined(__XBOXONE__) && !defined(__XBOXSERIES__)*/ +} + +void WIN_SetWindowTitle(_THIS, SDL_Window *window) +{ +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + HWND hwnd = ((SDL_WindowData *)window->driverdata)->hwnd; + LPTSTR title = WIN_UTF8ToString(window->title); + SetWindowText(hwnd, title); + SDL_free(title); +#endif +} + +void WIN_SetWindowIcon(_THIS, SDL_Window *window, SDL_Surface *icon) +{ +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + HWND hwnd = ((SDL_WindowData *)window->driverdata)->hwnd; + HICON hicon = NULL; + BYTE *icon_bmp; + int icon_len, mask_len, row_len, y; + BITMAPINFOHEADER *bmi; + Uint8 *dst; + SDL_bool isstack; + + /* Create temporary buffer for ICONIMAGE structure */ + SDL_COMPILE_TIME_ASSERT(WIN_SetWindowIcon_uses_BITMAPINFOHEADER_to_prepare_an_ICONIMAGE, sizeof(BITMAPINFOHEADER) == 40); + mask_len = (icon->h * (icon->w + 7) / 8); + icon_len = sizeof(BITMAPINFOHEADER) + icon->h * icon->w * sizeof(Uint32) + mask_len; + icon_bmp = SDL_small_alloc(BYTE, icon_len, &isstack); + + /* Write the BITMAPINFO header */ + bmi = (BITMAPINFOHEADER *)icon_bmp; + bmi->biSize = SDL_SwapLE32(sizeof(BITMAPINFOHEADER)); + bmi->biWidth = SDL_SwapLE32(icon->w); + bmi->biHeight = SDL_SwapLE32(icon->h * 2); + bmi->biPlanes = SDL_SwapLE16(1); + bmi->biBitCount = SDL_SwapLE16(32); + bmi->biCompression = SDL_SwapLE32(BI_RGB); + bmi->biSizeImage = SDL_SwapLE32(icon->h * icon->w * sizeof(Uint32)); + bmi->biXPelsPerMeter = SDL_SwapLE32(0); + bmi->biYPelsPerMeter = SDL_SwapLE32(0); + bmi->biClrUsed = SDL_SwapLE32(0); + bmi->biClrImportant = SDL_SwapLE32(0); + + /* Write the pixels upside down into the bitmap buffer */ + SDL_assert(icon->format->format == SDL_PIXELFORMAT_ARGB8888); + dst = &icon_bmp[sizeof(BITMAPINFOHEADER)]; + row_len = icon->w * sizeof(Uint32); + y = icon->h; + while (y--) { + Uint8 *src = (Uint8 *)icon->pixels + y * icon->pitch; + SDL_memcpy(dst, src, row_len); + dst += row_len; + } + + /* Write the mask */ + SDL_memset(icon_bmp + icon_len - mask_len, 0xFF, mask_len); + + hicon = CreateIconFromResource(icon_bmp, icon_len, TRUE, 0x00030000); + + SDL_small_free(icon_bmp, isstack); + + /* Set the icon for the window */ + SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)hicon); + + /* Set the icon in the task manager (should we do this?) */ + SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)hicon); +#endif +} + +void WIN_SetWindowPosition(_THIS, SDL_Window *window) +{ + /* HighDPI support: removed SWP_NOSIZE. If the move results in a DPI change, we need to allow + * the window to resize (e.g. AdjustWindowRectExForDpi frame sizes are different). + */ + WIN_SetWindowPositionInternal(_this, window, SWP_NOCOPYBITS | SWP_NOACTIVATE); +} + +void WIN_SetWindowSize(_THIS, SDL_Window *window) +{ + WIN_SetWindowPositionInternal(_this, window, SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOACTIVATE); +} + +int WIN_GetWindowBordersSize(_THIS, SDL_Window *window, int *top, int *left, int *bottom, int *right) +{ +#if defined(__XBOXONE__) || defined(__XBOXSERIES__) + HWND hwnd = ((SDL_WindowData *)window->driverdata)->hwnd; + RECT rcClient; + + /* rcClient stores the size of the inner window, while rcWindow stores the outer size relative to the top-left + * screen position; so the top/left values of rcClient are always {0,0} and bottom/right are {height,width} */ + GetClientRect(hwnd, &rcClient); + + *top = rcClient.top; + *left = rcClient.left; + *bottom = rcClient.bottom; + *right = rcClient.right; + + return 0; +#else /*!defined(__XBOXONE__) && !defined(__XBOXSERIES__)*/ + HWND hwnd = ((SDL_WindowData *)window->driverdata)->hwnd; + RECT rcClient, rcWindow; + POINT ptDiff; + + /* rcClient stores the size of the inner window, while rcWindow stores the outer size relative to the top-left + * screen position; so the top/left values of rcClient are always {0,0} and bottom/right are {height,width} */ + if (!GetClientRect(hwnd, &rcClient)) { + return SDL_SetError("GetClientRect() failed, error %08X", (unsigned int)GetLastError()); + } + + if (!GetWindowRect(hwnd, &rcWindow)) { + return SDL_SetError("GetWindowRect() failed, error %08X", (unsigned int)GetLastError()); + } + + /* convert the top/left values to make them relative to + * the window; they will end up being slightly negative */ + ptDiff.y = rcWindow.top; + ptDiff.x = rcWindow.left; + + if (!ScreenToClient(hwnd, &ptDiff)) { + return SDL_SetError("ScreenToClient() failed, error %08X", (unsigned int)GetLastError()); + } + + rcWindow.top = ptDiff.y; + rcWindow.left = ptDiff.x; + + /* convert the bottom/right values to make them relative to the window, + * these will be slightly bigger than the inner width/height */ + ptDiff.y = rcWindow.bottom; + ptDiff.x = rcWindow.right; + + if (!ScreenToClient(hwnd, &ptDiff)) { + return SDL_SetError("ScreenToClient() failed, error %08X", (unsigned int)GetLastError()); + } + + rcWindow.bottom = ptDiff.y; + rcWindow.right = ptDiff.x; + + /* Now that both the inner and outer rects use the same coordinate system we can substract them to get the border size. + * Keep in mind that the top/left coordinates of rcWindow are negative because the border lies slightly before {0,0}, + * so switch them around because SDL2 wants them in positive. */ + *top = rcClient.top - rcWindow.top; + *left = rcClient.left - rcWindow.left; + *bottom = rcWindow.bottom - rcClient.bottom; + *right = rcWindow.right - rcClient.right; + + return 0; +#endif /*!defined(__XBOXONE__) && !defined(__XBOXSERIES__)*/ +} + +void WIN_GetWindowSizeInPixels(_THIS, SDL_Window *window, int *w, int *h) +{ + const SDL_WindowData *data = ((SDL_WindowData *)window->driverdata); + HWND hwnd = data->hwnd; + RECT rect; + + if (GetClientRect(hwnd, &rect) && !WIN_IsRectEmpty(&rect)) { + *w = rect.right; + *h = rect.bottom; + } else { + *w = window->w; + *h = window->h; + } +} + +void WIN_ShowWindow(_THIS, SDL_Window *window) +{ + DWORD style; + HWND hwnd; + int nCmdShow; + + hwnd = ((SDL_WindowData *)window->driverdata)->hwnd; + nCmdShow = SDL_GetHintBoolean(SDL_HINT_WINDOW_NO_ACTIVATION_WHEN_SHOWN, SDL_FALSE) ? SW_SHOWNA : SW_SHOW; + style = GetWindowLong(hwnd, GWL_EXSTYLE); + if (style & WS_EX_NOACTIVATE) { + nCmdShow = SW_SHOWNOACTIVATE; + } + ShowWindow(hwnd, nCmdShow); +} + +void WIN_HideWindow(_THIS, SDL_Window *window) +{ + HWND hwnd = ((SDL_WindowData *)window->driverdata)->hwnd; + ShowWindow(hwnd, SW_HIDE); +} + +void WIN_RaiseWindow(_THIS, SDL_Window *window) +{ +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + /* If desired, raise the window more forcefully. + * Technique taken from http://stackoverflow.com/questions/916259/ . + * Specifically, http://stackoverflow.com/a/34414846 . + * + * The issue is that Microsoft has gone through a lot of trouble to make it + * nearly impossible to programmatically move a window to the foreground, + * for "security" reasons. Apparently, the following song-and-dance gets + * around their objections. */ + SDL_bool bForce = SDL_GetHintBoolean(SDL_HINT_FORCE_RAISEWINDOW, SDL_FALSE); + + HWND hCurWnd = NULL; + DWORD dwMyID = 0u; + DWORD dwCurID = 0u; + + HWND hwnd = ((SDL_WindowData *)window->driverdata)->hwnd; + if (bForce) { + hCurWnd = GetForegroundWindow(); + dwMyID = GetCurrentThreadId(); + dwCurID = GetWindowThreadProcessId(hCurWnd, NULL); + ShowWindow(hwnd, SW_RESTORE); + AttachThreadInput(dwCurID, dwMyID, TRUE); + SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); + SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); + } + SetForegroundWindow(hwnd); + if (bForce) { + AttachThreadInput(dwCurID, dwMyID, FALSE); + SetFocus(hwnd); + SetActiveWindow(hwnd); + } +#endif /*!defined(__XBOXONE__) && !defined(__XBOXSERIES__)*/ +} + +void WIN_MaximizeWindow(_THIS, SDL_Window *window) +{ + /* Other platforms refuse to maximize a non-resizable window, and with win32, + the OS resizes the window weirdly (covering the taskbar) if you don't have + the STYLE_RESIZABLE flag set. So just forbid it for now. */ + if (window->flags & SDL_WINDOW_RESIZABLE) { + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + HWND hwnd = data->hwnd; + data->expected_resize = SDL_TRUE; + ShowWindow(hwnd, SW_MAXIMIZE); + data->expected_resize = SDL_FALSE; + } +} + +void WIN_MinimizeWindow(_THIS, SDL_Window *window) +{ + HWND hwnd = ((SDL_WindowData *)window->driverdata)->hwnd; + ShowWindow(hwnd, SW_MINIMIZE); +} + +void WIN_SetWindowBordered(_THIS, SDL_Window *window, SDL_bool bordered) +{ + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + HWND hwnd = data->hwnd; + DWORD style; + + style = GetWindowLong(hwnd, GWL_STYLE); + style &= ~STYLE_MASK; + style |= GetWindowStyle(window); + + data->in_border_change = SDL_TRUE; + SetWindowLong(hwnd, GWL_STYLE, style); + WIN_SetWindowPositionInternal(_this, window, SWP_NOCOPYBITS | SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOACTIVATE); + data->in_border_change = SDL_FALSE; +} + +void WIN_SetWindowResizable(_THIS, SDL_Window *window, SDL_bool resizable) +{ + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + HWND hwnd = data->hwnd; + DWORD style; + + style = GetWindowLong(hwnd, GWL_STYLE); + style &= ~STYLE_MASK; + style |= GetWindowStyle(window); + + SetWindowLong(hwnd, GWL_STYLE, style); +} + +void WIN_SetWindowAlwaysOnTop(_THIS, SDL_Window *window, SDL_bool on_top) +{ + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + HWND hwnd = data->hwnd; + if (on_top) { + SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + } else { + SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + } +} + +void WIN_RestoreWindow(_THIS, SDL_Window *window) +{ + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + HWND hwnd = data->hwnd; + data->expected_resize = SDL_TRUE; + ShowWindow(hwnd, SW_RESTORE); + data->expected_resize = SDL_FALSE; +} + +/** + * Reconfigures the window to fill the given display, if fullscreen is true, otherwise restores the window. + */ +void WIN_SetWindowFullscreen(_THIS, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen) +{ +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + SDL_DisplayData *displaydata = (SDL_DisplayData *)display->driverdata; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + HWND hwnd = data->hwnd; + MONITORINFO minfo; + DWORD style; + HWND top; + int x, y; + int w, h; + + if (!fullscreen && (window->flags & (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_FULLSCREEN_DESKTOP))) { + /* Resizing the window on hide causes problems restoring it in Wine, and it's unnecessary. + * Also, Windows would preview the minimized window with the wrong size. + */ + return; + } + +#ifdef HIGHDPI_DEBUG + SDL_Log("WIN_SetWindowFullscreen: %d", (int)fullscreen); +#endif + + if (SDL_ShouldAllowTopmost() && (window->flags & SDL_WINDOW_ALWAYS_ON_TOP)) { + top = HWND_TOPMOST; + } else { + top = HWND_NOTOPMOST; + } + + style = GetWindowLong(hwnd, GWL_STYLE); + style &= ~STYLE_MASK; + style |= GetWindowStyle(window); + + /* Use GetMonitorInfo instead of WIN_GetDisplayBounds because we want the + monitor bounds in Windows coordinates (pixels) rather than SDL coordinates (points). */ + SDL_zero(minfo); + minfo.cbSize = sizeof(MONITORINFO); + if (!GetMonitorInfo(displaydata->MonitorHandle, &minfo)) { + SDL_SetError("GetMonitorInfo failed"); + return; + } + + if (fullscreen) { + x = minfo.rcMonitor.left; + y = minfo.rcMonitor.top; + w = minfo.rcMonitor.right - minfo.rcMonitor.left; + h = minfo.rcMonitor.bottom - minfo.rcMonitor.top; + + /* Unset the maximized flag. This fixes + https://bugzilla.libsdl.org/show_bug.cgi?id=3215 + */ + if (style & WS_MAXIMIZE) { + data->windowed_mode_was_maximized = SDL_TRUE; + 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 + in_window_deactivation), otherwise + https://bugzilla.libsdl.org/show_bug.cgi?id=3215 can reproduce! + */ + if (data->windowed_mode_was_maximized && !data->in_window_deactivation) { + style |= WS_MAXIMIZE; + data->windowed_mode_was_maximized = 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; + SetWindowPos(hwnd, top, x, y, w, h, SWP_NOCOPYBITS | SWP_NOACTIVATE); + data->expected_resize = SDL_FALSE; + +#ifdef HIGHDPI_DEBUG + SDL_Log("WIN_SetWindowFullscreen: %d finished. Set window to %d,%d, %dx%d", (int)fullscreen, x, y, w, h); +#endif + +#endif /*!defined(__XBOXONE__) && !defined(__XBOXSERIES__)*/ +} + +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) +int WIN_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp) +{ + SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); + SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata; + HDC hdc; + BOOL succeeded = FALSE; + + hdc = CreateDCW(data->DeviceName, NULL, NULL, NULL); + if (hdc) { + succeeded = SetDeviceGammaRamp(hdc, (LPVOID)ramp); + if (!succeeded) { + WIN_SetError("SetDeviceGammaRamp()"); + } + DeleteDC(hdc); + } + return succeeded ? 0 : -1; +} + +void WIN_UpdateWindowICCProfile(SDL_Window * window, SDL_bool send_event) +{ + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); + SDL_DisplayData *displaydata = display ? (SDL_DisplayData *)display->driverdata : NULL; + + if (displaydata) { + HDC hdc = CreateDCW(displaydata->DeviceName, NULL, NULL, NULL); + if (hdc) { + WCHAR fileName[MAX_PATH]; + DWORD fileNameSize = SDL_arraysize(fileName); + if (GetICMProfileW(hdc, &fileNameSize, fileName)) { + /* fileNameSize includes '\0' on return */ + if (!data->ICMFileName || + SDL_wcscmp(data->ICMFileName, fileName) != 0) { + if (data->ICMFileName) { + SDL_free(data->ICMFileName); + } + data->ICMFileName = SDL_wcsdup(fileName); + if (send_event) { + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_ICCPROF_CHANGED, 0, 0); + } + } + } + DeleteDC(hdc); + } + } +} + +void *WIN_GetWindowICCProfile(_THIS, SDL_Window *window, size_t *size) +{ + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + char *filename_utf8; + void *iccProfileData = NULL; + + filename_utf8 = WIN_StringToUTF8(data->ICMFileName); + if (filename_utf8) { + iccProfileData = SDL_LoadFile(filename_utf8, size); + if (!iccProfileData) { + SDL_SetError("Could not open ICC profile"); + } + SDL_free(filename_utf8); + } else { + SDL_OutOfMemory(); + } + return iccProfileData; +} + +int WIN_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp) +{ + SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); + SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata; + HDC hdc; + BOOL succeeded = FALSE; + + hdc = CreateDCW(data->DeviceName, NULL, NULL, NULL); + if (hdc) { + succeeded = GetDeviceGammaRamp(hdc, (LPVOID)ramp); + if (!succeeded) { + WIN_SetError("GetDeviceGammaRamp()"); + } + DeleteDC(hdc); + } + return succeeded ? 0 : -1; +} + +static void WIN_GrabKeyboard(SDL_Window *window) +{ + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + HMODULE module; + + if (data->keyboard_hook) { + return; + } + + /* SetWindowsHookEx() needs to know which module contains the hook we + want to install. This is complicated by the fact that SDL can be + linked statically or dynamically. Fortunately XP and later provide + this nice API that will go through the loaded modules and find the + one containing our code. + */ + if (!GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, + (LPTSTR)WIN_KeyboardHookProc, + &module)) { + return; + } + + /* Capture a snapshot of the current keyboard state before the hook */ + if (!GetKeyboardState(data->videodata->pre_hook_key_state)) { + return; + } + + /* To grab the keyboard, we have to install a low-level keyboard hook to + intercept keys that would normally be captured by the OS. Intercepting + all key events on the system is rather invasive, but it's what Microsoft + actually documents that you do to capture these. + */ + data->keyboard_hook = SetWindowsHookEx(WH_KEYBOARD_LL, WIN_KeyboardHookProc, module, 0); +} + +void WIN_UngrabKeyboard(SDL_Window *window) +{ + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + + if (data->keyboard_hook) { + UnhookWindowsHookEx(data->keyboard_hook); + data->keyboard_hook = NULL; + } +} + +void WIN_SetWindowMouseRect(_THIS, SDL_Window *window) +{ + WIN_UpdateClipCursor(window); +} + +void WIN_SetWindowMouseGrab(_THIS, SDL_Window *window, SDL_bool grabbed) +{ + WIN_UpdateClipCursor(window); +} + +void WIN_SetWindowKeyboardGrab(_THIS, SDL_Window *window, SDL_bool grabbed) +{ + if (grabbed) { + WIN_GrabKeyboard(window); + } else { + WIN_UngrabKeyboard(window); + } +} +#endif /*!defined(__XBOXONE__) && !defined(__XBOXSERIES__)*/ + +void WIN_DestroyWindow(_THIS, SDL_Window *window) +{ + if (window->shaper) { + SDL_ShapeData *shapedata = (SDL_ShapeData *)window->shaper->driverdata; + if (shapedata) { + if (shapedata->mask_tree) { + SDL_FreeShapeTree(&shapedata->mask_tree); + } + SDL_free(shapedata); + } + SDL_free(window->shaper); + window->shaper = NULL; + } + + CleanupWindowData(_this, window); +} + +SDL_bool WIN_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info) +{ + const SDL_WindowData *data = (const SDL_WindowData *) window->driverdata; + if (info->version.major <= SDL_MAJOR_VERSION) { + int versionnum = SDL_VERSIONNUM(info->version.major, info->version.minor, info->version.patch); + + info->subsystem = SDL_SYSWM_WINDOWS; + info->info.win.window = data->hwnd; + + if (versionnum >= SDL_VERSIONNUM(2, 0, 4)) { + info->info.win.hdc = data->hdc; + } + + if (versionnum >= SDL_VERSIONNUM(2, 0, 5)) { + info->info.win.hinstance = data->hinstance; + } + + return SDL_TRUE; + } else { + SDL_SetError("Application not compiled with SDL %d", + SDL_MAJOR_VERSION); + return SDL_FALSE; + } +} + +/* + * Creates a HelperWindow used for DirectInput. + */ +int SDL_HelperWindowCreate(void) +{ + HINSTANCE hInstance = GetModuleHandle(NULL); + WNDCLASS wce; + + /* Make sure window isn't created twice. */ + if (SDL_HelperWindow != NULL) { + return 0; + } + + /* Create the class. */ + SDL_zero(wce); + wce.lpfnWndProc = DefWindowProc; + wce.lpszClassName = SDL_HelperWindowClassName; + wce.hInstance = hInstance; + + /* Register the class. */ + SDL_HelperWindowClass = RegisterClass(&wce); + if (SDL_HelperWindowClass == 0 && GetLastError() != ERROR_CLASS_ALREADY_EXISTS) { + return WIN_SetError("Unable to create Helper Window Class"); + } + + /* Create the window. */ + SDL_HelperWindow = CreateWindowEx(0, SDL_HelperWindowClassName, + SDL_HelperWindowName, + WS_OVERLAPPED, CW_USEDEFAULT, + CW_USEDEFAULT, CW_USEDEFAULT, + CW_USEDEFAULT, HWND_MESSAGE, NULL, + hInstance, NULL); + if (!SDL_HelperWindow) { + UnregisterClass(SDL_HelperWindowClassName, hInstance); + return WIN_SetError("Unable to create Helper Window"); + } + + return 0; +} + +/* + * Destroys the HelperWindow previously created with SDL_HelperWindowCreate. + */ +void SDL_HelperWindowDestroy(void) +{ + HINSTANCE hInstance = GetModuleHandle(NULL); + + /* Destroy the window. */ + if (SDL_HelperWindow != NULL) { + if (DestroyWindow(SDL_HelperWindow) == 0) { + WIN_SetError("Unable to destroy Helper Window"); + return; + } + SDL_HelperWindow = NULL; + } + + /* Unregister the class. */ + if (SDL_HelperWindowClass != 0) { + if ((UnregisterClass(SDL_HelperWindowClassName, hInstance)) == 0) { + WIN_SetError("Unable to destroy Helper Window Class"); + return; + } + SDL_HelperWindowClass = 0; + } +} + +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) +void WIN_OnWindowEnter(_THIS, SDL_Window *window) +{ + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + + if (!data || !data->hwnd) { + /* The window wasn't fully initialized */ + return; + } + + if (window->flags & SDL_WINDOW_ALWAYS_ON_TOP) { + WIN_SetWindowPositionInternal(_this, window, SWP_NOCOPYBITS | SWP_NOSIZE | SWP_NOACTIVATE); + } +} + +static BOOL GetClientScreenRect(HWND hwnd, RECT *rect) +{ + return GetClientRect(hwnd, rect) && /* RECT( left , top , right , bottom ) */ + ClientToScreen(hwnd, (LPPOINT)rect) && /* POINT( left , top ) */ + ClientToScreen(hwnd, (LPPOINT)rect + 1); /* POINT( right , bottom ) */ +} + +void WIN_UpdateClipCursor(SDL_Window *window) +{ + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + SDL_Mouse *mouse = SDL_GetMouse(); + RECT rect, clipped_rect; + + if (data->in_title_click || data->focus_click_pending) { + return; + } + if (data->skip_update_clipcursor) { + return; + } + if (!GetClipCursor(&clipped_rect)) { + return; + } + + if ((mouse->relative_mode || (window->flags & SDL_WINDOW_MOUSE_GRABBED) || + (window->mouse_rect.w > 0 && window->mouse_rect.h > 0)) && + (window->flags & SDL_WINDOW_INPUT_FOCUS)) { + if (mouse->relative_mode && !mouse->relative_mode_warp && data->mouse_relative_mode_center) { + if (GetClientScreenRect(data->hwnd, &rect)) { + /* WIN_WarpCursor() jitters by +1, and remote desktop warp wobble is +/- 1 */ + LONG remote_desktop_adjustment = GetSystemMetrics(SM_REMOTESESSION) ? 2 : 0; + LONG cx, cy; + + cx = (rect.left + rect.right) / 2; + cy = (rect.top + rect.bottom) / 2; + + /* Make an absurdly small clip rect */ + rect.left = cx - remote_desktop_adjustment; + rect.right = cx + 1 + remote_desktop_adjustment; + rect.top = cy; + rect.bottom = cy + 1; + + if (SDL_memcmp(&rect, &clipped_rect, sizeof(rect)) != 0) { + if (ClipCursor(&rect)) { + data->cursor_clipped_rect = rect; + } + } + } + } else { + if (GetClientScreenRect(data->hwnd, &rect)) { + if (window->mouse_rect.w > 0 && window->mouse_rect.h > 0) { + SDL_Rect mouse_rect_win_client; + RECT mouse_rect, intersection; + + /* mouse_rect_win_client is the mouse rect in Windows client space */ + mouse_rect_win_client = window->mouse_rect; + WIN_ClientPointFromSDL(window, &mouse_rect_win_client.x, &mouse_rect_win_client.y); + WIN_ClientPointFromSDL(window, &mouse_rect_win_client.w, &mouse_rect_win_client.h); + + /* mouse_rect is the rect in Windows screen space */ + mouse_rect.left = rect.left + mouse_rect_win_client.x; + mouse_rect.top = rect.top + mouse_rect_win_client.y; + mouse_rect.right = mouse_rect.left + mouse_rect_win_client.w; + mouse_rect.bottom = mouse_rect.top + mouse_rect_win_client.h; + if (IntersectRect(&intersection, &rect, &mouse_rect)) { + SDL_memcpy(&rect, &intersection, sizeof(rect)); + } else if (window->flags & SDL_WINDOW_MOUSE_GRABBED) { + /* Mouse rect was invalid, just do the normal grab */ + } else { + SDL_zero(rect); + } + } + if (SDL_memcmp(&rect, &clipped_rect, sizeof(rect)) != 0) { + if (!WIN_IsRectEmpty(&rect)) { + if (ClipCursor(&rect)) { + data->cursor_clipped_rect = rect; + } + } else { + ClipCursor(NULL); + SDL_zero(data->cursor_clipped_rect); + } + } + } + } + } else { + POINT first, second; + + first.x = clipped_rect.left; + first.y = clipped_rect.top; + second.x = clipped_rect.right - 1; + second.y = clipped_rect.bottom - 1; + if (PtInRect(&data->cursor_clipped_rect, first) && + PtInRect(&data->cursor_clipped_rect, second)) { + ClipCursor(NULL); + SDL_zero(data->cursor_clipped_rect); + } + } + data->last_updated_clipcursor = SDL_GetTicks(); +} + +int WIN_SetWindowHitTest(SDL_Window *window, SDL_bool enabled) +{ + return 0; /* just succeed, the real work is done elsewhere. */ +} +#endif /*!defined(__XBOXONE__) && !defined(__XBOXSERIES__)*/ + +int WIN_SetWindowOpacity(_THIS, SDL_Window *window, float opacity) +{ +#if defined(__XBOXONE__) || defined(__XBOXSERIES__) + return -1; +#else + const SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + HWND hwnd = data->hwnd; + const LONG style = GetWindowLong(hwnd, GWL_EXSTYLE); + + SDL_assert(style != 0); + + if (opacity == 1.0f) { + /* want it fully opaque, just mark it unlayered if necessary. */ + if (style & WS_EX_LAYERED) { + if (SetWindowLong(hwnd, GWL_EXSTYLE, style & ~WS_EX_LAYERED) == 0) { + return WIN_SetError("SetWindowLong()"); + } + } + } else { + const BYTE alpha = (BYTE)((int)(opacity * 255.0f)); + /* want it transparent, mark it layered if necessary. */ + if (!(style & WS_EX_LAYERED)) { + if (SetWindowLong(hwnd, GWL_EXSTYLE, style | WS_EX_LAYERED) == 0) { + return WIN_SetError("SetWindowLong()"); + } + } + + if (SetLayeredWindowAttributes(hwnd, 0, alpha, LWA_ALPHA) == 0) { + return WIN_SetError("SetLayeredWindowAttributes()"); + } + } + + return 0; +#endif /*!defined(__XBOXONE__) && !defined(__XBOXSERIES__)*/ +} + +/** + * Convert a point in the client area from pixels to DPI-scaled points. + * + * No-op if DPI scaling is not enabled. + */ +void WIN_ClientPointToSDL(const SDL_Window *window, int *x, int *y) +{ + const SDL_WindowData *data = ((SDL_WindowData *)window->driverdata); + const SDL_VideoData *videodata = data->videodata; + + if (!videodata->dpi_scaling_enabled) { + return; + } + + *x = MulDiv(*x, 96, data->scaling_dpi); + *y = MulDiv(*y, 96, data->scaling_dpi); +} + +/** + * Convert a point in the client area from DPI-scaled points to pixels. + * + * No-op if DPI scaling is not enabled. + */ +void WIN_ClientPointFromSDL(const SDL_Window *window, int *x, int *y) +{ + const SDL_WindowData *data = ((SDL_WindowData *)window->driverdata); + const SDL_VideoData *videodata = data->videodata; + + if (!videodata->dpi_scaling_enabled) { + return; + } + + *x = MulDiv(*x, data->scaling_dpi, 96); + *y = MulDiv(*y, data->scaling_dpi, 96); +} + +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) +void WIN_AcceptDragAndDrop(SDL_Window *window, SDL_bool accept) +{ + const SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + DragAcceptFiles(data->hwnd, accept ? TRUE : FALSE); +} + +int WIN_FlashWindow(_THIS, SDL_Window *window, SDL_FlashOperation operation) +{ + FLASHWINFO desc; + + SDL_zero(desc); + desc.cbSize = sizeof(desc); + desc.hwnd = ((SDL_WindowData *)window->driverdata)->hwnd; + switch (operation) { + case SDL_FLASH_CANCEL: + desc.dwFlags = FLASHW_STOP; + break; + case SDL_FLASH_BRIEFLY: + desc.dwFlags = FLASHW_TRAY; + desc.uCount = 1; + break; + case SDL_FLASH_UNTIL_FOCUSED: + desc.dwFlags = (FLASHW_TRAY | FLASHW_TIMERNOFG); + break; + default: + return SDL_Unsupported(); + } + + FlashWindowEx(&desc); + + return 0; +} +#endif /*!defined(__XBOXONE__) && !defined(__XBOXSERIES__)*/ + +#endif /* SDL_VIDEO_DRIVER_WINDOWS */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/windows/SDL_windowswindow.h b/SDL2-2.30.5/src/video/windows/SDL_windowswindow.h similarity index 67% rename from SDL2-2.0.12/src/video/windows/SDL_windowswindow.h rename to SDL2-2.30.5/src/video/windows/SDL_windowswindow.h index 7191412..20f78b9 100644 --- a/SDL2-2.0.12/src/video/windows/SDL_windowswindow.h +++ b/SDL2-2.30.5/src/video/windows/SDL_windowswindow.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,8 +23,15 @@ #ifndef SDL_windowswindow_h_ #define SDL_windowswindow_h_ -#if SDL_VIDEO_OPENGL_EGL +#ifdef SDL_VIDEO_OPENGL_EGL #include "../SDL_egl_c.h" +#else +#include "../SDL_sysvideo.h" +#endif + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { #endif typedef struct @@ -37,21 +44,34 @@ typedef struct HINSTANCE hinstance; HBITMAP hbm; WNDPROC wndproc; + HHOOK keyboard_hook; SDL_bool created; WPARAM mouse_button_flags; + LPARAM last_pointer_update; + WCHAR high_surrogate; SDL_bool initializing; SDL_bool expected_resize; SDL_bool in_border_change; SDL_bool in_title_click; Uint8 focus_click_pending; SDL_bool skip_update_clipcursor; + Uint32 last_updated_clipcursor; + SDL_bool mouse_relative_mode_center; SDL_bool windowed_mode_was_maximized; SDL_bool in_window_deactivation; RECT cursor_clipped_rect; + SDL_Point last_raw_mouse_position; + SDL_bool mouse_tracked; + WCHAR *ICMFileName; struct SDL_VideoData *videodata; -#if SDL_VIDEO_OPENGL_EGL +#ifdef SDL_VIDEO_OPENGL_EGL EGLSurface egl_surface; #endif + /** + * Cached value of GetDpiForWindow, for use for scaling points in the client area + * between dpi-scaled points and pixels. Only used if videodata->dpi_scaling_enabled. + */ + int scaling_dpi; } SDL_WindowData; extern int WIN_CreateWindow(_THIS, SDL_Window * window); @@ -61,6 +81,7 @@ extern void WIN_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon); extern void WIN_SetWindowPosition(_THIS, SDL_Window * window); extern void WIN_SetWindowSize(_THIS, SDL_Window * window); extern int WIN_GetWindowBordersSize(_THIS, SDL_Window * window, int *top, int *left, int *bottom, int *right); +extern void WIN_GetWindowSizeInPixels(_THIS, SDL_Window * window, int *width, int *height); extern int WIN_SetWindowOpacity(_THIS, SDL_Window * window, float opacity); extern void WIN_ShowWindow(_THIS, SDL_Window * window); extern void WIN_HideWindow(_THIS, SDL_Window * window); @@ -70,17 +91,30 @@ extern void WIN_MinimizeWindow(_THIS, SDL_Window * window); extern void WIN_RestoreWindow(_THIS, SDL_Window * window); extern void WIN_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered); extern void WIN_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable); +extern void WIN_SetWindowAlwaysOnTop(_THIS, SDL_Window * window, SDL_bool on_top); extern void WIN_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen); extern int WIN_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp); +extern void WIN_UpdateWindowICCProfile(SDL_Window * window, SDL_bool send_event); +extern void* WIN_GetWindowICCProfile(_THIS, SDL_Window * window, size_t * size); extern int WIN_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp); -extern void WIN_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed); +extern void WIN_SetWindowMouseRect(_THIS, SDL_Window * window); +extern void WIN_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed); +extern void WIN_SetWindowKeyboardGrab(_THIS, SDL_Window * window, SDL_bool grabbed); extern void WIN_DestroyWindow(_THIS, SDL_Window * window); extern SDL_bool WIN_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info); extern void WIN_OnWindowEnter(_THIS, SDL_Window * window); extern void WIN_UpdateClipCursor(SDL_Window *window); extern int WIN_SetWindowHitTest(SDL_Window *window, SDL_bool enabled); -extern void WIN_AcceptDragAndDrop(SDL_Window * window, SDL_bool accept); +extern void WIN_ClientPointToSDL(const SDL_Window *window, int *x, int *y); +extern void WIN_ClientPointFromSDL(const SDL_Window *window, int *x, int *y); +extern void WIN_AcceptDragAndDrop(SDL_Window *window, SDL_bool accept); +extern int WIN_FlashWindow(_THIS, SDL_Window *window, SDL_FlashOperation operation); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif #endif /* SDL_windowswindow_h_ */ diff --git a/SDL2-2.0.12/src/video/windows/wmmsg.h b/SDL2-2.30.5/src/video/windows/wmmsg.h similarity index 99% rename from SDL2-2.0.12/src/video/windows/wmmsg.h rename to SDL2-2.30.5/src/video/windows/wmmsg.h index 37ad7be..86e6c2a 100644 --- a/SDL2-2.0.12/src/video/windows/wmmsg.h +++ b/SDL2-2.30.5/src/video/windows/wmmsg.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -19,9 +19,9 @@ 3. This notice may not be removed or altered from any source distribution. */ -#define MAX_WMMSG (sizeof(wmtab)/sizeof(wmtab[0])) +#define MAX_WMMSG (sizeof(wmtab) / sizeof(wmtab[0])) -char *wmtab[] = { +const char *wmtab[] = { "WM_NULL", "WM_CREATE", "WM_DESTROY", @@ -762,7 +762,7 @@ char *wmtab[] = { "UNKNOWN (737)", "UNKNOWN (738)", "UNKNOWN (739)", - "UNKNOWN (740)", + "WM_GETDPISCALEDSIZE", "UNKNOWN (741)", "UNKNOWN (742)", "UNKNOWN (743)", diff --git a/SDL2-2.0.12/src/video/winrt/SDL_winrtevents.cpp b/SDL2-2.30.5/src/video/winrt/SDL_winrtevents.cpp similarity index 64% rename from SDL2-2.0.12/src/video/winrt/SDL_winrtevents.cpp rename to SDL2-2.30.5/src/video/winrt/SDL_winrtevents.cpp index b985462..79468f7 100644 --- a/SDL2-2.0.12/src/video/winrt/SDL_winrtevents.cpp +++ b/SDL2-2.30.5/src/video/winrt/SDL_winrtevents.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_WINRT +#ifdef SDL_VIDEO_DRIVER_WINRT /* * Windows includes: @@ -36,7 +36,6 @@ using Windows::UI::Core::CoreCursor; #include "../../core/winrt/SDL_winrtapp_common.h" #include "../../core/winrt/SDL_winrtapp_direct3d.h" #include "../../core/winrt/SDL_winrtapp_xaml.h" -#include "SDL_assert.h" #include "SDL_system.h" extern "C" { @@ -45,15 +44,12 @@ extern "C" { #include "../../events/SDL_events_c.h" } - /* Forward declarations */ static void WINRT_YieldXAMLThread(); - /* Global event management */ -void -WINRT_PumpEvents(_THIS) +void WINRT_PumpEvents(_THIS) { if (SDL_WinRTGlobalApp) { SDL_WinRTGlobalApp->PumpEvents(); @@ -62,7 +58,6 @@ WINRT_PumpEvents(_THIS) } } - /* XAML Thread management */ enum SDL_XAMLAppThreadState @@ -73,12 +68,11 @@ enum SDL_XAMLAppThreadState }; static SDL_XAMLAppThreadState _threadState = ThreadState_NotLaunched; -static SDL_Thread * _XAMLThread = nullptr; -static SDL_mutex * _mutex = nullptr; -static SDL_cond * _cond = nullptr; +static SDL_Thread *_XAMLThread = nullptr; +static SDL_mutex *_mutex = nullptr; +static SDL_cond *_cond = nullptr; -static void -WINRT_YieldXAMLThread() +static void WINRT_YieldXAMLThread() { SDL_LockMutex(_mutex); SDL_assert(_threadState == ThreadState_Running); @@ -94,8 +88,7 @@ WINRT_YieldXAMLThread() SDL_UnlockMutex(_mutex); } -static int -WINRT_XAMLThreadMain(void * userdata) +static int WINRT_XAMLThreadMain(void *userdata) { // TODO, WinRT: pass the C-style main() a reasonably realistic // representation of command line arguments. @@ -104,48 +97,47 @@ WINRT_XAMLThreadMain(void * userdata) return WINRT_SDLAppEntryPoint(argc, argv); } -void -WINRT_CycleXAMLThread(void) +void WINRT_CycleXAMLThread(void) { switch (_threadState) { - case ThreadState_NotLaunched: - { - _cond = SDL_CreateCond(); + case ThreadState_NotLaunched: + { + _cond = SDL_CreateCond(); - _mutex = SDL_CreateMutex(); - _threadState = ThreadState_Running; - _XAMLThread = SDL_CreateThreadInternal(WINRT_XAMLThreadMain, "SDL/XAML App Thread", 0, nullptr); + _mutex = SDL_CreateMutex(); + _threadState = ThreadState_Running; + _XAMLThread = SDL_CreateThreadInternal(WINRT_XAMLThreadMain, "SDL/XAML App Thread", 0, nullptr); - SDL_LockMutex(_mutex); - while (_threadState != ThreadState_Yielding) { - SDL_CondWait(_cond, _mutex); - } - SDL_UnlockMutex(_mutex); - - break; + SDL_LockMutex(_mutex); + while (_threadState != ThreadState_Yielding) { + SDL_CondWait(_cond, _mutex); } + SDL_UnlockMutex(_mutex); - case ThreadState_Running: - { - SDL_assert(false); - break; - } - - case ThreadState_Yielding: - { - SDL_LockMutex(_mutex); - SDL_assert(_threadState == ThreadState_Yielding); - _threadState = ThreadState_Running; - SDL_UnlockMutex(_mutex); - - SDL_CondSignal(_cond); - - SDL_LockMutex(_mutex); - while (_threadState != ThreadState_Yielding) { - SDL_CondWait(_cond, _mutex); - } - SDL_UnlockMutex(_mutex); + break; + } + + case ThreadState_Running: + { + SDL_assert(false); + break; + } + + case ThreadState_Yielding: + { + SDL_LockMutex(_mutex); + SDL_assert(_threadState == ThreadState_Yielding); + _threadState = ThreadState_Running; + SDL_UnlockMutex(_mutex); + + SDL_CondSignal(_cond); + + SDL_LockMutex(_mutex); + while (_threadState != ThreadState_Yielding) { + SDL_CondWait(_cond, _mutex); } + SDL_UnlockMutex(_mutex); + } } } diff --git a/SDL2-2.0.12/src/video/winrt/SDL_winrtevents_c.h b/SDL2-2.30.5/src/video/winrt/SDL_winrtevents_c.h similarity index 76% rename from SDL2-2.0.12/src/video/winrt/SDL_winrtevents_c.h rename to SDL2-2.30.5/src/video/winrt/SDL_winrtevents_c.h index 6f2bced..d08cf9a 100644 --- a/SDL2-2.0.12/src/video/winrt/SDL_winrtevents_c.h +++ b/SDL2-2.30.5/src/video/winrt/SDL_winrtevents_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -39,40 +39,41 @@ extern void WINRT_PumpEvents(_THIS); } #endif - /* * Internal-use, C++/CX functions: */ #ifdef __cplusplus_winrt /* Pointers (Mice, Touch, etc.) */ -typedef enum { +typedef enum +{ NormalizeZeroToOne, TransformToSDLWindowSize } WINRT_CursorNormalizationType; -extern Windows::Foundation::Point WINRT_TransformCursorPosition(SDL_Window * window, +extern Windows::Foundation::Point WINRT_TransformCursorPosition(SDL_Window *window, Windows::Foundation::Point rawPosition, WINRT_CursorNormalizationType normalization); -extern Uint8 WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^pt); -extern void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint); -extern void WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint); -extern void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint); -extern void WINRT_ProcessPointerEnteredEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint); -extern void WINRT_ProcessPointerExitedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint); -extern void WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint); -extern void WINRT_ProcessMouseMovedEvent(SDL_Window * window, Windows::Devices::Input::MouseEventArgs ^args); +extern SDL_bool WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^ pt, Uint8 *button, Uint8 *pressed); +extern void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^ pointerPoint); +extern void WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^ pointerPoint); +extern void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^ pointerPoint); +extern void WINRT_ProcessPointerEnteredEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^ pointerPoint); +extern void WINRT_ProcessPointerExitedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^ pointerPoint); +extern void WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^ pointerPoint); +extern void WINRT_ProcessMouseMovedEvent(SDL_Window *window, Windows::Devices::Input::MouseEventArgs ^ args); /* Keyboard */ -extern void WINRT_ProcessKeyDownEvent(Windows::UI::Core::KeyEventArgs ^args); -extern void WINRT_ProcessKeyUpEvent(Windows::UI::Core::KeyEventArgs ^args); -extern void WINRT_ProcessCharacterReceivedEvent(Windows::UI::Core::CharacterReceivedEventArgs ^args); +extern void WINRT_ProcessKeyDownEvent(Windows::UI::Core::KeyEventArgs ^ args); +extern void WINRT_ProcessKeyUpEvent(Windows::UI::Core::KeyEventArgs ^ args); +extern void WINRT_ProcessCharacterReceivedEvent(Windows::UI::Core::CharacterReceivedEventArgs ^ args); #if NTDDI_VERSION >= NTDDI_WIN10 +extern void WINTRT_InitialiseInputPaneEvents(_THIS); extern SDL_bool WINRT_HasScreenKeyboardSupport(_THIS); extern void WINRT_ShowScreenKeyboard(_THIS, SDL_Window *window); extern void WINRT_HideScreenKeyboard(_THIS, SDL_Window *window); extern SDL_bool WINRT_IsScreenKeyboardShown(_THIS, SDL_Window *window); -#endif // NTDDI_VERSION >= ... +#endif // NTDDI_VERSION >= ... /* XAML Thread Management */ extern void WINRT_CycleXAMLThread(void); diff --git a/SDL2-2.0.12/src/video/winrt/SDL_winrtgamebar.cpp b/SDL2-2.30.5/src/video/winrt/SDL_winrtgamebar.cpp similarity index 78% rename from SDL2-2.0.12/src/video/winrt/SDL_winrtgamebar.cpp rename to SDL2-2.30.5/src/video/winrt/SDL_winrtgamebar.cpp index 03fd60b..e56def1 100644 --- a/SDL2-2.0.12/src/video/winrt/SDL_winrtgamebar.cpp +++ b/SDL2-2.30.5/src/video/winrt/SDL_winrtgamebar.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,13 +20,12 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_WINRT +#ifdef SDL_VIDEO_DRIVER_WINRT /* Windows includes */ #include #include -#include - +#include /* SDL includes */ extern "C" { @@ -35,13 +34,11 @@ extern "C" { } #include "SDL_winrtvideo_cpp.h" - /* Game Bar events can come in off the main thread. Use the following WinRT CoreDispatcher to deal with them on SDL's thread. */ static Platform::WeakReference WINRT_MainThreadDispatcher; - /* Win10's initial SDK (the 10.0.10240.0 release) does not include references to Game Bar APIs, as the Game Bar was released via Win10 10.0.10586.0. @@ -51,26 +48,26 @@ static Platform::WeakReference WINRT_MainThreadDispatcher; MIDL_INTERFACE("1DB9A292-CC78-4173-BE45-B61E67283EA7") IGameBarStatics_ : public IInspectable { -public: - virtual HRESULT STDMETHODCALLTYPE add_VisibilityChanged( - __FIEventHandler_1_IInspectable *handler, - Windows::Foundation::EventRegistrationToken *token) = 0; - - virtual HRESULT STDMETHODCALLTYPE remove_VisibilityChanged( + public: + virtual HRESULT STDMETHODCALLTYPE add_VisibilityChanged( + __FIEventHandler_1_IInspectable * handler, + Windows::Foundation::EventRegistrationToken * token) = 0; + + virtual HRESULT STDMETHODCALLTYPE remove_VisibilityChanged( Windows::Foundation::EventRegistrationToken token) = 0; - - virtual HRESULT STDMETHODCALLTYPE add_IsInputRedirectedChanged( - __FIEventHandler_1_IInspectable *handler, - Windows::Foundation::EventRegistrationToken *token) = 0; - - virtual HRESULT STDMETHODCALLTYPE remove_IsInputRedirectedChanged( + + virtual HRESULT STDMETHODCALLTYPE add_IsInputRedirectedChanged( + __FIEventHandler_1_IInspectable * handler, + Windows::Foundation::EventRegistrationToken * token) = 0; + + virtual HRESULT STDMETHODCALLTYPE remove_IsInputRedirectedChanged( Windows::Foundation::EventRegistrationToken token) = 0; - - virtual HRESULT STDMETHODCALLTYPE get_Visible( - boolean *value) = 0; - - virtual HRESULT STDMETHODCALLTYPE get_IsInputRedirected( - boolean *value) = 0; + + virtual HRESULT STDMETHODCALLTYPE get_Visible( + boolean * value) = 0; + + virtual HRESULT STDMETHODCALLTYPE get_IsInputRedirected( + boolean * value) = 0; }; /* Declare the game bar's COM GUID */ @@ -80,8 +77,7 @@ static GUID IID_IGameBarStatics_ = { MAKELONG(0xA292, 0x1DB9), 0xCC78, 0x4173, { If a pointer is returned, it's ->Release() method must be called after the caller has finished using it. */ -static IGameBarStatics_ * -WINRT_GetGameBar() +static IGameBarStatics_ *WINRT_GetGameBar() { wchar_t *wClassName = L"Windows.Gaming.UI.GameBar"; HSTRING hClassName; @@ -89,7 +85,7 @@ WINRT_GetGameBar() IGameBarStatics_ *pGameBar = NULL; HRESULT hr; - hr = ::WindowsCreateString(wClassName, (UINT32)wcslen(wClassName), &hClassName); + hr = ::WindowsCreateString(wClassName, (UINT32)SDL_wcslen(wClassName), &hClassName); if (FAILED(hr)) { goto done; } @@ -99,7 +95,7 @@ WINRT_GetGameBar() goto done; } - pActivationFactory->QueryInterface(IID_IGameBarStatics_, (void **) &pGameBar); + pActivationFactory->QueryInterface(IID_IGameBarStatics_, (void **)&pGameBar); done: if (pActivationFactory) { @@ -111,8 +107,7 @@ done: return pGameBar; } -static void -WINRT_HandleGameBarIsInputRedirected_MainThread() +static void WINRT_HandleGameBarIsInputRedirected_MainThread() { IGameBarStatics_ *gameBar; boolean isInputRedirected = 0; @@ -126,7 +121,7 @@ WINRT_HandleGameBarIsInputRedirected_MainThread() return; } if (SUCCEEDED(gameBar->get_IsInputRedirected(&isInputRedirected))) { - if ( ! isInputRedirected) { + if (!isInputRedirected) { /* Input-control is now back to the SDL app. Restore the cursor, in case Windows does not (it does not in either Win10 10.0.10240.0 or 10.0.10586.0, maybe later version(s) too. @@ -138,10 +133,9 @@ WINRT_HandleGameBarIsInputRedirected_MainThread() gameBar->Release(); } -static void -WINRT_HandleGameBarIsInputRedirected_NonMainThread(Platform::Object ^ o1, Platform::Object ^o2) +static void WINRT_HandleGameBarIsInputRedirected_NonMainThread(Platform::Object ^ o1, Platform::Object ^ o2) { - Windows::UI::Core::CoreDispatcher ^dispatcher = WINRT_MainThreadDispatcher.Resolve(); + Windows::UI::Core::CoreDispatcher ^ dispatcher = WINRT_MainThreadDispatcher.Resolve(); if (dispatcher) { dispatcher->RunAsync( Windows::UI::Core::CoreDispatcherPriority::Normal, @@ -149,8 +143,7 @@ WINRT_HandleGameBarIsInputRedirected_NonMainThread(Platform::Object ^ o1, Platfo } } -void -WINRT_InitGameBar(_THIS) +void WINRT_InitGameBar(_THIS) { SDL_VideoData *driverdata = (SDL_VideoData *)_this->driverdata; IGameBarStatics_ *gameBar = WINRT_GetGameBar(); @@ -162,16 +155,15 @@ WINRT_InitGameBar(_THIS) SDL thread. */ WINRT_MainThreadDispatcher = Windows::UI::Core::CoreWindow::GetForCurrentThread()->Dispatcher; - Windows::Foundation::EventHandler ^handler = \ + Windows::Foundation::EventHandler ^ handler = ref new Windows::Foundation::EventHandler(&WINRT_HandleGameBarIsInputRedirected_NonMainThread); - __FIEventHandler_1_IInspectable * pHandler = reinterpret_cast<__FIEventHandler_1_IInspectable *>(handler); + __FIEventHandler_1_IInspectable *pHandler = reinterpret_cast<__FIEventHandler_1_IInspectable *>(handler); gameBar->add_IsInputRedirectedChanged(pHandler, &driverdata->gameBarIsInputRedirectedToken); gameBar->Release(); } } -void -WINRT_QuitGameBar(_THIS) +void WINRT_QuitGameBar(_THIS) { SDL_VideoData *driverdata; IGameBarStatics_ *gameBar; diff --git a/SDL2-2.0.12/src/video/winrt/SDL_winrtgamebar_cpp.h b/SDL2-2.30.5/src/video/winrt/SDL_winrtgamebar_cpp.h similarity index 95% rename from SDL2-2.0.12/src/video/winrt/SDL_winrtgamebar_cpp.h rename to SDL2-2.30.5/src/video/winrt/SDL_winrtgamebar_cpp.h index f9b474b..7e3f5d9 100644 --- a/SDL2-2.0.12/src/video/winrt/SDL_winrtgamebar_cpp.h +++ b/SDL2-2.30.5/src/video/winrt/SDL_winrtgamebar_cpp.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.30.5/src/video/winrt/SDL_winrtkeyboard.cpp b/SDL2-2.30.5/src/video/winrt/SDL_winrtkeyboard.cpp new file mode 100644 index 0000000..26a1902 --- /dev/null +++ b/SDL2-2.30.5/src/video/winrt/SDL_winrtkeyboard.cpp @@ -0,0 +1,479 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_WINRT + +/* Windows-specific includes */ +#include +#include + +/* SDL-specific includes */ +#include "SDL.h" +#include "SDL_winrtevents_c.h" + +extern "C" { +#include "../../events/scancodes_windows.h" +#include "../../events/SDL_keyboard_c.h" +} + +static SDL_Scancode WinRT_Official_Keycodes[] = { + SDL_SCANCODE_UNKNOWN, /* VirtualKey.None -- 0 */ + SDL_SCANCODE_UNKNOWN, /* VirtualKey.LeftButton -- 1 */ + SDL_SCANCODE_UNKNOWN, /* VirtualKey.RightButton -- 2 */ + SDL_SCANCODE_CANCEL, /* VirtualKey.Cancel -- 3 */ + SDL_SCANCODE_UNKNOWN, /* VirtualKey.MiddleButton -- 4 */ + SDL_SCANCODE_UNKNOWN, /* VirtualKey.XButton1 -- 5 */ + SDL_SCANCODE_UNKNOWN, /* VirtualKey.XButton2 -- 6 */ + SDL_SCANCODE_UNKNOWN, /* -- 7 */ + SDL_SCANCODE_BACKSPACE, /* VirtualKey.Back -- 8 */ + SDL_SCANCODE_TAB, /* VirtualKey.Tab -- 9 */ + SDL_SCANCODE_UNKNOWN, /* -- 10 */ + SDL_SCANCODE_UNKNOWN, /* -- 11 */ + SDL_SCANCODE_CLEAR, /* VirtualKey.Clear -- 12 */ + SDL_SCANCODE_RETURN, /* VirtualKey.Enter -- 13 */ + SDL_SCANCODE_UNKNOWN, /* -- 14 */ + SDL_SCANCODE_UNKNOWN, /* -- 15 */ + SDL_SCANCODE_LSHIFT, /* VirtualKey.Shift -- 16 */ + SDL_SCANCODE_LCTRL, /* VirtualKey.Control -- 17 */ + SDL_SCANCODE_MENU, /* VirtualKey.Menu -- 18 */ + SDL_SCANCODE_PAUSE, /* VirtualKey.Pause -- 19 */ + SDL_SCANCODE_CAPSLOCK, /* VirtualKey.CapitalLock -- 20 */ + SDL_SCANCODE_UNKNOWN, /* VirtualKey.Kana or VirtualKey.Hangul -- 21 */ + SDL_SCANCODE_UNKNOWN, /* -- 22 */ + SDL_SCANCODE_UNKNOWN, /* VirtualKey.Junja -- 23 */ + SDL_SCANCODE_UNKNOWN, /* VirtualKey.Final -- 24 */ + SDL_SCANCODE_UNKNOWN, /* VirtualKey.Hanja or VirtualKey.Kanji -- 25 */ + SDL_SCANCODE_UNKNOWN, /* -- 26 */ + SDL_SCANCODE_ESCAPE, /* VirtualKey.Escape -- 27 */ + SDL_SCANCODE_UNKNOWN, /* VirtualKey.Convert -- 28 */ + SDL_SCANCODE_UNKNOWN, /* VirtualKey.NonConvert -- 29 */ + SDL_SCANCODE_UNKNOWN, /* VirtualKey.Accept -- 30 */ + SDL_SCANCODE_UNKNOWN, /* VirtualKey.ModeChange -- 31 (maybe SDL_SCANCODE_MODE ?) */ + SDL_SCANCODE_SPACE, /* VirtualKey.Space -- 32 */ + SDL_SCANCODE_PAGEUP, /* VirtualKey.PageUp -- 33 */ + SDL_SCANCODE_PAGEDOWN, /* VirtualKey.PageDown -- 34 */ + SDL_SCANCODE_END, /* VirtualKey.End -- 35 */ + SDL_SCANCODE_HOME, /* VirtualKey.Home -- 36 */ + SDL_SCANCODE_LEFT, /* VirtualKey.Left -- 37 */ + SDL_SCANCODE_UP, /* VirtualKey.Up -- 38 */ + SDL_SCANCODE_RIGHT, /* VirtualKey.Right -- 39 */ + SDL_SCANCODE_DOWN, /* VirtualKey.Down -- 40 */ + SDL_SCANCODE_SELECT, /* VirtualKey.Select -- 41 */ + SDL_SCANCODE_UNKNOWN, /* VirtualKey.Print -- 42 (maybe SDL_SCANCODE_PRINTSCREEN ?) */ + SDL_SCANCODE_EXECUTE, /* VirtualKey.Execute -- 43 */ + SDL_SCANCODE_UNKNOWN, /* VirtualKey.Snapshot -- 44 */ + SDL_SCANCODE_INSERT, /* VirtualKey.Insert -- 45 */ + SDL_SCANCODE_DELETE, /* VirtualKey.Delete -- 46 */ + SDL_SCANCODE_HELP, /* VirtualKey.Help -- 47 */ + SDL_SCANCODE_0, /* VirtualKey.Number0 -- 48 */ + SDL_SCANCODE_1, /* VirtualKey.Number1 -- 49 */ + SDL_SCANCODE_2, /* VirtualKey.Number2 -- 50 */ + SDL_SCANCODE_3, /* VirtualKey.Number3 -- 51 */ + SDL_SCANCODE_4, /* VirtualKey.Number4 -- 52 */ + SDL_SCANCODE_5, /* VirtualKey.Number5 -- 53 */ + SDL_SCANCODE_6, /* VirtualKey.Number6 -- 54 */ + SDL_SCANCODE_7, /* VirtualKey.Number7 -- 55 */ + SDL_SCANCODE_8, /* VirtualKey.Number8 -- 56 */ + SDL_SCANCODE_9, /* VirtualKey.Number9 -- 57 */ + SDL_SCANCODE_UNKNOWN, /* -- 58 */ + SDL_SCANCODE_UNKNOWN, /* -- 59 */ + SDL_SCANCODE_UNKNOWN, /* -- 60 */ + SDL_SCANCODE_UNKNOWN, /* -- 61 */ + SDL_SCANCODE_UNKNOWN, /* -- 62 */ + SDL_SCANCODE_UNKNOWN, /* -- 63 */ + SDL_SCANCODE_UNKNOWN, /* -- 64 */ + SDL_SCANCODE_A, /* VirtualKey.A -- 65 */ + SDL_SCANCODE_B, /* VirtualKey.B -- 66 */ + SDL_SCANCODE_C, /* VirtualKey.C -- 67 */ + SDL_SCANCODE_D, /* VirtualKey.D -- 68 */ + SDL_SCANCODE_E, /* VirtualKey.E -- 69 */ + SDL_SCANCODE_F, /* VirtualKey.F -- 70 */ + SDL_SCANCODE_G, /* VirtualKey.G -- 71 */ + SDL_SCANCODE_H, /* VirtualKey.H -- 72 */ + SDL_SCANCODE_I, /* VirtualKey.I -- 73 */ + SDL_SCANCODE_J, /* VirtualKey.J -- 74 */ + SDL_SCANCODE_K, /* VirtualKey.K -- 75 */ + SDL_SCANCODE_L, /* VirtualKey.L -- 76 */ + SDL_SCANCODE_M, /* VirtualKey.M -- 77 */ + SDL_SCANCODE_N, /* VirtualKey.N -- 78 */ + SDL_SCANCODE_O, /* VirtualKey.O -- 79 */ + SDL_SCANCODE_P, /* VirtualKey.P -- 80 */ + SDL_SCANCODE_Q, /* VirtualKey.Q -- 81 */ + SDL_SCANCODE_R, /* VirtualKey.R -- 82 */ + SDL_SCANCODE_S, /* VirtualKey.S -- 83 */ + SDL_SCANCODE_T, /* VirtualKey.T -- 84 */ + SDL_SCANCODE_U, /* VirtualKey.U -- 85 */ + SDL_SCANCODE_V, /* VirtualKey.V -- 86 */ + SDL_SCANCODE_W, /* VirtualKey.W -- 87 */ + SDL_SCANCODE_X, /* VirtualKey.X -- 88 */ + SDL_SCANCODE_Y, /* VirtualKey.Y -- 89 */ + SDL_SCANCODE_Z, /* VirtualKey.Z -- 90 */ + SDL_SCANCODE_UNKNOWN, /* VirtualKey.LeftWindows -- 91 (maybe SDL_SCANCODE_APPLICATION or SDL_SCANCODE_LGUI ?) */ + SDL_SCANCODE_UNKNOWN, /* VirtualKey.RightWindows -- 92 (maybe SDL_SCANCODE_APPLICATION or SDL_SCANCODE_RGUI ?) */ + SDL_SCANCODE_APPLICATION, /* VirtualKey.Application -- 93 */ + SDL_SCANCODE_UNKNOWN, /* -- 94 */ + SDL_SCANCODE_SLEEP, /* VirtualKey.Sleep -- 95 */ + SDL_SCANCODE_KP_0, /* VirtualKey.NumberPad0 -- 96 */ + SDL_SCANCODE_KP_1, /* VirtualKey.NumberPad1 -- 97 */ + SDL_SCANCODE_KP_2, /* VirtualKey.NumberPad2 -- 98 */ + SDL_SCANCODE_KP_3, /* VirtualKey.NumberPad3 -- 99 */ + SDL_SCANCODE_KP_4, /* VirtualKey.NumberPad4 -- 100 */ + SDL_SCANCODE_KP_5, /* VirtualKey.NumberPad5 -- 101 */ + SDL_SCANCODE_KP_6, /* VirtualKey.NumberPad6 -- 102 */ + SDL_SCANCODE_KP_7, /* VirtualKey.NumberPad7 -- 103 */ + SDL_SCANCODE_KP_8, /* VirtualKey.NumberPad8 -- 104 */ + SDL_SCANCODE_KP_9, /* VirtualKey.NumberPad9 -- 105 */ + SDL_SCANCODE_KP_MULTIPLY, /* VirtualKey.Multiply -- 106 */ + SDL_SCANCODE_KP_PLUS, /* VirtualKey.Add -- 107 */ + SDL_SCANCODE_UNKNOWN, /* VirtualKey.Separator -- 108 */ + SDL_SCANCODE_KP_MINUS, /* VirtualKey.Subtract -- 109 */ + SDL_SCANCODE_UNKNOWN, /* VirtualKey.Decimal -- 110 (maybe SDL_SCANCODE_DECIMALSEPARATOR, SDL_SCANCODE_KP_DECIMAL, or SDL_SCANCODE_KP_PERIOD ?) */ + SDL_SCANCODE_KP_DIVIDE, /* VirtualKey.Divide -- 111 */ + SDL_SCANCODE_F1, /* VirtualKey.F1 -- 112 */ + SDL_SCANCODE_F2, /* VirtualKey.F2 -- 113 */ + SDL_SCANCODE_F3, /* VirtualKey.F3 -- 114 */ + SDL_SCANCODE_F4, /* VirtualKey.F4 -- 115 */ + SDL_SCANCODE_F5, /* VirtualKey.F5 -- 116 */ + SDL_SCANCODE_F6, /* VirtualKey.F6 -- 117 */ + SDL_SCANCODE_F7, /* VirtualKey.F7 -- 118 */ + SDL_SCANCODE_F8, /* VirtualKey.F8 -- 119 */ + SDL_SCANCODE_F9, /* VirtualKey.F9 -- 120 */ + SDL_SCANCODE_F10, /* VirtualKey.F10 -- 121 */ + SDL_SCANCODE_F11, /* VirtualKey.F11 -- 122 */ + SDL_SCANCODE_F12, /* VirtualKey.F12 -- 123 */ + SDL_SCANCODE_F13, /* VirtualKey.F13 -- 124 */ + SDL_SCANCODE_F14, /* VirtualKey.F14 -- 125 */ + SDL_SCANCODE_F15, /* VirtualKey.F15 -- 126 */ + SDL_SCANCODE_F16, /* VirtualKey.F16 -- 127 */ + SDL_SCANCODE_F17, /* VirtualKey.F17 -- 128 */ + SDL_SCANCODE_F18, /* VirtualKey.F18 -- 129 */ + SDL_SCANCODE_F19, /* VirtualKey.F19 -- 130 */ + SDL_SCANCODE_F20, /* VirtualKey.F20 -- 131 */ + SDL_SCANCODE_F21, /* VirtualKey.F21 -- 132 */ + SDL_SCANCODE_F22, /* VirtualKey.F22 -- 133 */ + SDL_SCANCODE_F23, /* VirtualKey.F23 -- 134 */ + SDL_SCANCODE_F24, /* VirtualKey.F24 -- 135 */ + SDL_SCANCODE_UNKNOWN, /* -- 136 */ + SDL_SCANCODE_UNKNOWN, /* -- 137 */ + SDL_SCANCODE_UNKNOWN, /* -- 138 */ + SDL_SCANCODE_UNKNOWN, /* -- 139 */ + SDL_SCANCODE_UNKNOWN, /* -- 140 */ + SDL_SCANCODE_UNKNOWN, /* -- 141 */ + SDL_SCANCODE_UNKNOWN, /* -- 142 */ + SDL_SCANCODE_UNKNOWN, /* -- 143 */ + SDL_SCANCODE_NUMLOCKCLEAR, /* VirtualKey.NumberKeyLock -- 144 */ + SDL_SCANCODE_SCROLLLOCK, /* VirtualKey.Scroll -- 145 */ + SDL_SCANCODE_UNKNOWN, /* -- 146 */ + SDL_SCANCODE_UNKNOWN, /* -- 147 */ + SDL_SCANCODE_UNKNOWN, /* -- 148 */ + SDL_SCANCODE_UNKNOWN, /* -- 149 */ + SDL_SCANCODE_UNKNOWN, /* -- 150 */ + SDL_SCANCODE_UNKNOWN, /* -- 151 */ + SDL_SCANCODE_UNKNOWN, /* -- 152 */ + SDL_SCANCODE_UNKNOWN, /* -- 153 */ + SDL_SCANCODE_UNKNOWN, /* -- 154 */ + SDL_SCANCODE_UNKNOWN, /* -- 155 */ + SDL_SCANCODE_UNKNOWN, /* -- 156 */ + SDL_SCANCODE_UNKNOWN, /* -- 157 */ + SDL_SCANCODE_UNKNOWN, /* -- 158 */ + SDL_SCANCODE_UNKNOWN, /* -- 159 */ + SDL_SCANCODE_LSHIFT, /* VirtualKey.LeftShift -- 160 */ + SDL_SCANCODE_RSHIFT, /* VirtualKey.RightShift -- 161 */ + SDL_SCANCODE_LCTRL, /* VirtualKey.LeftControl -- 162 */ + SDL_SCANCODE_RCTRL, /* VirtualKey.RightControl -- 163 */ + SDL_SCANCODE_MENU, /* VirtualKey.LeftMenu -- 164 */ + SDL_SCANCODE_MENU, /* VirtualKey.RightMenu -- 165 */ + SDL_SCANCODE_AC_BACK, /* VirtualKey.GoBack -- 166 : The go back key. */ + SDL_SCANCODE_AC_FORWARD, /* VirtualKey.GoForward -- 167 : The go forward key. */ + SDL_SCANCODE_AC_REFRESH, /* VirtualKey.Refresh -- 168 : The refresh key. */ + SDL_SCANCODE_AC_STOP, /* VirtualKey.Stop -- 169 : The stop key. */ + SDL_SCANCODE_AC_SEARCH, /* VirtualKey.Search -- 170 : The search key. */ + SDL_SCANCODE_AC_BOOKMARKS, /* VirtualKey.Favorites -- 171 : The favorites key. */ + SDL_SCANCODE_AC_HOME /* VirtualKey.GoHome -- 172 : The go home key. */ +}; + +/* Attempt to translate a keycode that isn't listed in WinRT's VirtualKey enum. + */ +static SDL_Scancode WINRT_TranslateUnofficialKeycode(int keycode) +{ + switch (keycode) { + case 173: + return SDL_SCANCODE_MUTE; /* VK_VOLUME_MUTE */ + case 174: + return SDL_SCANCODE_VOLUMEDOWN; /* VK_VOLUME_DOWN */ + case 175: + return SDL_SCANCODE_VOLUMEUP; /* VK_VOLUME_UP */ + case 176: + return SDL_SCANCODE_AUDIONEXT; /* VK_MEDIA_NEXT_TRACK */ + case 177: + return SDL_SCANCODE_AUDIOPREV; /* VK_MEDIA_PREV_TRACK */ + // case 178: return ; /* VK_MEDIA_STOP */ + case 179: + return SDL_SCANCODE_AUDIOPLAY; /* VK_MEDIA_PLAY_PAUSE */ + case 180: + return SDL_SCANCODE_MAIL; /* VK_LAUNCH_MAIL */ + case 181: + return SDL_SCANCODE_MEDIASELECT; /* VK_LAUNCH_MEDIA_SELECT */ + // case 182: return ; /* VK_LAUNCH_APP1 */ + case 183: + return SDL_SCANCODE_CALCULATOR; /* VK_LAUNCH_APP2 */ + // case 184: return ; /* ... reserved ... */ + // case 185: return ; /* ... reserved ... */ + case 186: + return SDL_SCANCODE_SEMICOLON; /* VK_OEM_1, ';:' key on US standard keyboards */ + case 187: + return SDL_SCANCODE_EQUALS; /* VK_OEM_PLUS */ + case 188: + return SDL_SCANCODE_COMMA; /* VK_OEM_COMMA */ + case 189: + return SDL_SCANCODE_MINUS; /* VK_OEM_MINUS */ + case 190: + return SDL_SCANCODE_PERIOD; /* VK_OEM_PERIOD */ + case 191: + return SDL_SCANCODE_SLASH; /* VK_OEM_2, '/?' key on US standard keyboards */ + case 192: + return SDL_SCANCODE_GRAVE; /* VK_OEM_3, '`~' key on US standard keyboards */ + // ? + // ... reserved or unassigned ... + // ? + case 219: + return SDL_SCANCODE_LEFTBRACKET; /* VK_OEM_4, '[{' key on US standard keyboards */ + case 220: + return SDL_SCANCODE_BACKSLASH; /* VK_OEM_5, '\|' key on US standard keyboards */ + case 221: + return SDL_SCANCODE_RIGHTBRACKET; /* VK_OEM_6, ']}' key on US standard keyboards */ + case 222: + return SDL_SCANCODE_APOSTROPHE; /* VK_OEM_7, 'single/double quote' on US standard keyboards */ + default: + break; + } + return SDL_SCANCODE_UNKNOWN; +} + +static SDL_Scancode WINRT_TranslateKeycode(int keycode, unsigned int nativeScancode) +{ + // TODO, WinRT: try filling out the WinRT keycode table as much as possible, using the Win32 table for interpretation hints + + SDL_Scancode scancode = SDL_SCANCODE_UNKNOWN; + + /* HACK ALERT: At least one VirtualKey constant (Shift) with a left/right + * designation might not get reported with its correct handedness, however + * its hardware scan code can fill in the gaps. If this is detected, + * use the hardware scan code to try telling if the left, or the right + * side's key was used. + * + * If Microsoft ever allows MapVirtualKey or MapVirtualKeyEx to be used + * in WinRT apps, or something similar to these (it doesn't appear to be, + * at least not for Windows [Phone] 8/8.1, as of Oct 24, 2014), then this + * hack might become deprecated, or obsolete. + */ + if (nativeScancode < SDL_arraysize(windows_scancode_table)) { + switch (keycode) { + case 16: // VirtualKey.Shift + switch (windows_scancode_table[nativeScancode]) { + case SDL_SCANCODE_LSHIFT: + case SDL_SCANCODE_RSHIFT: + return windows_scancode_table[nativeScancode]; + } + break; + + // Add others, as necessary. + // + // Unfortunately, this hack doesn't seem to work in determining + // handedness with Control keys. + + default: + break; + } + } + + /* Try to get a documented, WinRT, 'VirtualKey' next (as documented at + http://msdn.microsoft.com/en-us/library/windows/apps/windows.system.virtualkey.aspx ). + If that fails, fall back to a Win32 virtual key. + If that fails, attempt to fall back to a scancode-derived key. + */ + if (keycode < SDL_arraysize(WinRT_Official_Keycodes)) { + scancode = WinRT_Official_Keycodes[keycode]; + } + if (scancode == SDL_SCANCODE_UNKNOWN) { + scancode = WINRT_TranslateUnofficialKeycode(keycode); + } + if (scancode == SDL_SCANCODE_UNKNOWN) { + if (nativeScancode < SDL_arraysize(windows_scancode_table)) { + scancode = windows_scancode_table[nativeScancode]; + } + } + /* + if (scancode == SDL_SCANCODE_UNKNOWN) { + SDL_Log("WinRT TranslateKeycode, unknown keycode=%d\n", (int)keycode); + } + */ + return scancode; +} + +void WINRT_ProcessKeyDownEvent(Windows::UI::Core::KeyEventArgs ^ args) +{ + SDL_Scancode sdlScancode = WINRT_TranslateKeycode((int)args->VirtualKey, args->KeyStatus.ScanCode); +#if 0 + SDL_Keycode keycode = SDL_GetKeyFromScancode(sdlScancode); + SDL_Log("key down, handled=%s, ext?=%s, released?=%s, menu key down?=%s, " + "repeat count=%d, native scan code=0x%x, was down?=%s, vkey=%d, " + "sdl scan code=%d (%s), sdl key code=%d (%s)\n", + (args->Handled ? "1" : "0"), + (args->KeyStatus.IsExtendedKey ? "1" : "0"), + (args->KeyStatus.IsKeyReleased ? "1" : "0"), + (args->KeyStatus.IsMenuKeyDown ? "1" : "0"), + args->KeyStatus.RepeatCount, + args->KeyStatus.ScanCode, + (args->KeyStatus.WasKeyDown ? "1" : "0"), + args->VirtualKey, + sdlScancode, + SDL_GetScancodeName(sdlScancode), + keycode, + SDL_GetKeyName(keycode)); + //args->Handled = true; +#endif + SDL_SendKeyboardKey(SDL_PRESSED, sdlScancode); +} + +void WINRT_ProcessKeyUpEvent(Windows::UI::Core::KeyEventArgs ^ args) +{ + SDL_Scancode sdlScancode = WINRT_TranslateKeycode((int)args->VirtualKey, args->KeyStatus.ScanCode); +#if 0 + SDL_Keycode keycode = SDL_GetKeyFromScancode(sdlScancode); + SDL_Log("key up, handled=%s, ext?=%s, released?=%s, menu key down?=%s, " + "repeat count=%d, native scan code=0x%x, was down?=%s, vkey=%d, " + "sdl scan code=%d (%s), sdl key code=%d (%s)\n", + (args->Handled ? "1" : "0"), + (args->KeyStatus.IsExtendedKey ? "1" : "0"), + (args->KeyStatus.IsKeyReleased ? "1" : "0"), + (args->KeyStatus.IsMenuKeyDown ? "1" : "0"), + args->KeyStatus.RepeatCount, + args->KeyStatus.ScanCode, + (args->KeyStatus.WasKeyDown ? "1" : "0"), + args->VirtualKey, + sdlScancode, + SDL_GetScancodeName(sdlScancode), + keycode, + SDL_GetKeyName(keycode)); + //args->Handled = true; +#endif + SDL_SendKeyboardKey(SDL_RELEASED, sdlScancode); +} + +void WINRT_ProcessCharacterReceivedEvent(Windows::UI::Core::CharacterReceivedEventArgs ^ args) +{ + wchar_t src_ucs2[2]; + char dest_utf8[16]; + int result; + + /* Setup src */ + src_ucs2[0] = args->KeyCode; + src_ucs2[1] = L'\0'; + + /* Convert the text, then send an SDL_TEXTINPUT event. */ + result = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)&src_ucs2, -1, (LPSTR)dest_utf8, sizeof(dest_utf8), NULL, NULL); + if (result > 0) { + SDL_SendKeyboardText(dest_utf8); + } +} + +#if NTDDI_VERSION >= NTDDI_WIN10 + +static bool WINRT_InputPaneVisible = false; + +void WINTRT_OnInputPaneShowing(Windows::UI::ViewManagement::InputPane ^ sender, Windows::UI::ViewManagement::InputPaneVisibilityEventArgs ^ args) +{ + WINRT_InputPaneVisible = true; +} + +void WINTRT_OnInputPaneHiding(Windows::UI::ViewManagement::InputPane ^ sender, Windows::UI::ViewManagement::InputPaneVisibilityEventArgs ^ args) +{ + WINRT_InputPaneVisible = false; +} + +void WINTRT_InitialiseInputPaneEvents(_THIS) +{ + using namespace Windows::UI::ViewManagement; + InputPane ^ inputPane = InputPane::GetForCurrentView(); + if (inputPane) { + inputPane->Showing += ref new Windows::Foundation::TypedEventHandler(&WINTRT_OnInputPaneShowing); + inputPane->Hiding += ref new Windows::Foundation::TypedEventHandler(&WINTRT_OnInputPaneHiding); + } +} + +SDL_bool WINRT_HasScreenKeyboardSupport(_THIS) +{ + return SDL_TRUE; +} + +void WINRT_ShowScreenKeyboard(_THIS, SDL_Window *window) +{ + using namespace Windows::UI::ViewManagement; + InputPane ^ inputPane = InputPane::GetForCurrentView(); + if (inputPane) { + inputPane->TryShow(); + } +} + +void WINRT_HideScreenKeyboard(_THIS, SDL_Window *window) +{ + using namespace Windows::UI::ViewManagement; + InputPane ^ inputPane = InputPane::GetForCurrentView(); + if (inputPane) { + inputPane->TryHide(); + } +} + +SDL_bool WINRT_IsScreenKeyboardShown(_THIS, SDL_Window *window) +{ + using namespace Windows::UI::ViewManagement; + InputPane ^ inputPane = InputPane::GetForCurrentView(); + if (inputPane) { + switch (SDL_WinRTGetDeviceFamily()) { + case SDL_WINRT_DEVICEFAMILY_XBOX: + // Documentation recommends using inputPane->Visible + // https://learn.microsoft.com/en-us/uwp/api/windows.ui.viewmanagement.inputpane.visible?view=winrt-22621 + // This does not seem to work on latest UWP/Xbox. + // Workaround: Listen to Showing/Hiding events + if (WINRT_InputPaneVisible) { + return SDL_TRUE; + } + break; + default: + // OccludedRect is recommend on universal apps per docs + // https://learn.microsoft.com/en-us/uwp/api/windows.ui.viewmanagement.inputpane.visible?view=winrt-22621 + Windows::Foundation::Rect rect = inputPane->OccludedRect; + if (rect.Width > 0 && rect.Height > 0) { + return SDL_TRUE; + } + break; + } + } + return SDL_FALSE; +} + +#endif // NTDDI_VERSION >= ... + +#endif // SDL_VIDEO_DRIVER_WINRT diff --git a/SDL2-2.0.12/src/video/winrt/SDL_winrtmessagebox.cpp b/SDL2-2.30.5/src/video/winrt/SDL_winrtmessagebox.cpp similarity index 82% rename from SDL2-2.0.12/src/video/winrt/SDL_winrtmessagebox.cpp rename to SDL2-2.30.5/src/video/winrt/SDL_winrtmessagebox.cpp index 44973f2..a2d66a3 100644 --- a/SDL2-2.0.12/src/video/winrt/SDL_winrtmessagebox.cpp +++ b/SDL2-2.30.5/src/video/winrt/SDL_winrtmessagebox.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_WINRT +#ifdef SDL_VIDEO_DRIVER_WINRT extern "C" { #include "SDL_messagebox.h" @@ -34,23 +34,20 @@ using namespace Platform; using namespace Windows::Foundation; using namespace Windows::UI::Popups; -static String ^ -WINRT_UTF8ToPlatformString(const char * str) -{ - wchar_t * wstr = WIN_UTF8ToString(str); +static String ^ WINRT_UTF8ToPlatformString(const char *str) { + wchar_t *wstr = WIN_UTF8ToString(str); String ^ rtstr = ref new String(wstr); SDL_free(wstr); return rtstr; } -extern "C" int -WINRT_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) +extern "C" int WINRT_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) { -#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) && (NTDDI_VERSION == NTDDI_WIN8) +#if SDL_WINAPI_FAMILY_PHONE && (NTDDI_VERSION == NTDDI_WIN8) /* Sadly, Windows Phone 8 doesn't include the MessageDialog class that * Windows 8.x/RT does, even though MSDN's reference documentation for * Windows Phone 8 mentions it. - * + * * The .NET runtime on Windows Phone 8 does, however, include a * MessageBox class. Perhaps this could be called, somehow? */ @@ -58,17 +55,17 @@ WINRT_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) #else SDL_VideoDevice *_this = SDL_GetVideoDevice(); -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP +#if SDL_WINAPI_FAMILY_PHONE const int maxbuttons = 2; - const char * platform = "Windows Phone 8.1+"; + const char *platform = "Windows Phone 8.1+"; #else const int maxbuttons = 3; - const char * platform = "Windows 8.x"; + const char *platform = "Windows 8.x"; #endif if (messageboxdata->numbuttons > maxbuttons) { return SDL_SetError("WinRT's MessageDialog only supports %d buttons, at most, on %s. %d were requested.", - maxbuttons, platform, messageboxdata->numbuttons); + maxbuttons, platform, messageboxdata->numbuttons); } /* Build a MessageDialog object and its buttons */ @@ -82,7 +79,7 @@ WINRT_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) sdlButton = &messageboxdata->buttons[i]; } UICommand ^ button = ref new UICommand(WINRT_UTF8ToPlatformString(sdlButton->text)); - button->Id = safe_cast((int)(sdlButton - messageboxdata->buttons)); + button->Id = IntPtr((int)((size_t)(sdlButton - messageboxdata->buttons))); dialog->Commands->Append(button); if (sdlButton->flags & SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT) { dialog->CancelCommandIndex = i; @@ -104,15 +101,14 @@ WINRT_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) return SDL_SetError("An unknown error occurred in displaying the WinRT MessageDialog"); } if (buttonid) { - IntPtr results = safe_cast((int)(operation->GetResults()->Id)); + IntPtr results = safe_cast(operation->GetResults()->Id); int clicked_index = results.ToInt32(); *buttonid = messageboxdata->buttons[clicked_index].buttonid; } return 0; -#endif /* if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP / else */ +#endif /* if SDL_WINAPI_FAMILY_PHONE / else */ } #endif /* SDL_VIDEO_DRIVER_WINRT */ /* vi: set ts=4 sw=4 expandtab: */ - diff --git a/SDL2-2.0.12/src/video/winrt/SDL_winrtmessagebox.h b/SDL2-2.30.5/src/video/winrt/SDL_winrtmessagebox.h similarity index 92% rename from SDL2-2.0.12/src/video/winrt/SDL_winrtmessagebox.h rename to SDL2-2.30.5/src/video/winrt/SDL_winrtmessagebox.h index 8ece578..ab02d3a 100644 --- a/SDL2-2.0.12/src/video/winrt/SDL_winrtmessagebox.h +++ b/SDL2-2.30.5/src/video/winrt/SDL_winrtmessagebox.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_WINRT +#ifdef SDL_VIDEO_DRIVER_WINRT extern int WINRT_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid); diff --git a/SDL2-2.0.12/src/video/winrt/SDL_winrtmouse.cpp b/SDL2-2.30.5/src/video/winrt/SDL_winrtmouse.cpp similarity index 71% rename from SDL2-2.0.12/src/video/winrt/SDL_winrtmouse.cpp rename to SDL2-2.30.5/src/video/winrt/SDL_winrtmouse.cpp index 9e595ff..e46687f 100644 --- a/SDL2-2.0.12/src/video/winrt/SDL_winrtmouse.cpp +++ b/SDL2-2.30.5/src/video/winrt/SDL_winrtmouse.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_WINRT +#ifdef SDL_VIDEO_DRIVER_WINRT /* * Windows includes: @@ -34,57 +34,75 @@ using Windows::UI::Core::CoreCursor; * SDL includes: */ extern "C" { -#include "SDL_assert.h" #include "../../events/SDL_mouse_c.h" #include "../../events/SDL_touch_c.h" #include "../SDL_sysvideo.h" #include "SDL_events.h" -#include "SDL_log.h" } #include "../../core/winrt/SDL_winrtapp_direct3d.h" #include "SDL_winrtvideo_cpp.h" #include "SDL_winrtmouse_c.h" - extern "C" SDL_bool WINRT_UsingRelativeMouseMode = SDL_FALSE; - -static SDL_Cursor * -WINRT_CreateSystemCursor(SDL_SystemCursor id) +static SDL_Cursor *WINRT_CreateSystemCursor(SDL_SystemCursor id) { SDL_Cursor *cursor; CoreCursorType cursorType = CoreCursorType::Arrow; - switch(id) - { + switch (id) { default: SDL_assert(0); return NULL; - case SDL_SYSTEM_CURSOR_ARROW: cursorType = CoreCursorType::Arrow; break; - case SDL_SYSTEM_CURSOR_IBEAM: cursorType = CoreCursorType::IBeam; break; - case SDL_SYSTEM_CURSOR_WAIT: cursorType = CoreCursorType::Wait; break; - case SDL_SYSTEM_CURSOR_CROSSHAIR: cursorType = CoreCursorType::Cross; break; - case SDL_SYSTEM_CURSOR_WAITARROW: cursorType = CoreCursorType::Wait; break; - case SDL_SYSTEM_CURSOR_SIZENWSE: cursorType = CoreCursorType::SizeNorthwestSoutheast; break; - case SDL_SYSTEM_CURSOR_SIZENESW: cursorType = CoreCursorType::SizeNortheastSouthwest; break; - case SDL_SYSTEM_CURSOR_SIZEWE: cursorType = CoreCursorType::SizeWestEast; break; - case SDL_SYSTEM_CURSOR_SIZENS: cursorType = CoreCursorType::SizeNorthSouth; break; - case SDL_SYSTEM_CURSOR_SIZEALL: cursorType = CoreCursorType::SizeAll; break; - case SDL_SYSTEM_CURSOR_NO: cursorType = CoreCursorType::UniversalNo; break; - case SDL_SYSTEM_CURSOR_HAND: cursorType = CoreCursorType::Hand; break; + case SDL_SYSTEM_CURSOR_ARROW: + cursorType = CoreCursorType::Arrow; + break; + case SDL_SYSTEM_CURSOR_IBEAM: + cursorType = CoreCursorType::IBeam; + break; + case SDL_SYSTEM_CURSOR_WAIT: + cursorType = CoreCursorType::Wait; + break; + case SDL_SYSTEM_CURSOR_CROSSHAIR: + cursorType = CoreCursorType::Cross; + break; + case SDL_SYSTEM_CURSOR_WAITARROW: + cursorType = CoreCursorType::Wait; + break; + case SDL_SYSTEM_CURSOR_SIZENWSE: + cursorType = CoreCursorType::SizeNorthwestSoutheast; + break; + case SDL_SYSTEM_CURSOR_SIZENESW: + cursorType = CoreCursorType::SizeNortheastSouthwest; + break; + case SDL_SYSTEM_CURSOR_SIZEWE: + cursorType = CoreCursorType::SizeWestEast; + break; + case SDL_SYSTEM_CURSOR_SIZENS: + cursorType = CoreCursorType::SizeNorthSouth; + break; + case SDL_SYSTEM_CURSOR_SIZEALL: + cursorType = CoreCursorType::SizeAll; + break; + case SDL_SYSTEM_CURSOR_NO: + cursorType = CoreCursorType::UniversalNo; + break; + case SDL_SYSTEM_CURSOR_HAND: + cursorType = CoreCursorType::Hand; + break; } - cursor = (SDL_Cursor *) SDL_calloc(1, sizeof(*cursor)); + cursor = (SDL_Cursor *)SDL_calloc(1, sizeof(*cursor)); if (cursor) { /* Create a pointer to a COM reference to a cursor. The extra pointer is used (on top of the COM reference) to allow the cursor to be referenced by the SDL_cursor's driverdata field, which is a void pointer. */ - CoreCursor ^* theCursor = new CoreCursor^(nullptr); + CoreCursor ^ *theCursor = new CoreCursor ^ (nullptr); *theCursor = ref new CoreCursor(cursorType, 0); - cursor->driverdata = (void *) theCursor; + cursor->driverdata = (void *)theCursor; } else { SDL_OutOfMemory(); } @@ -92,34 +110,31 @@ WINRT_CreateSystemCursor(SDL_SystemCursor id) return cursor; } -static SDL_Cursor * -WINRT_CreateDefaultCursor() +static SDL_Cursor *WINRT_CreateDefaultCursor() { return WINRT_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); } -static void -WINRT_FreeCursor(SDL_Cursor * cursor) +static void WINRT_FreeCursor(SDL_Cursor *cursor) { if (cursor->driverdata) { - CoreCursor ^* theCursor = (CoreCursor ^*) cursor->driverdata; - *theCursor = nullptr; // Release the COM reference to the CoreCursor - delete theCursor; // Delete the pointer to the COM reference + CoreCursor ^ *theCursor = (CoreCursor ^ *)cursor->driverdata; + *theCursor = nullptr; // Release the COM reference to the CoreCursor + delete theCursor; // Delete the pointer to the COM reference } SDL_free(cursor); } -static int -WINRT_ShowCursor(SDL_Cursor * cursor) +static int WINRT_ShowCursor(SDL_Cursor *cursor) { // TODO, WinRT, XAML: make WINRT_ShowCursor work when XAML support is enabled. - if ( ! CoreWindow::GetForCurrentThread()) { + if (!CoreWindow::GetForCurrentThread()) { return 0; } CoreWindow ^ coreWindow = CoreWindow::GetForCurrentThread(); if (cursor) { - CoreCursor ^* theCursor = (CoreCursor ^*) cursor->driverdata; + CoreCursor ^ *theCursor = (CoreCursor ^ *)cursor->driverdata; coreWindow->PointerCursor = *theCursor; } else { // HACK ALERT: TL;DR - Hiding the cursor in WinRT/UWP apps is weird, and @@ -166,13 +181,13 @@ WINRT_ShowCursor(SDL_Cursor * cursor) // - src/main/winrt/SDL2-WinRTResources.rc -- declares the cursor resource, and its ID (of 5000) // - const unsigned int win32CursorResourceID = 5000; + const unsigned int win32CursorResourceID = 5000; CoreCursor ^ blankCursor = ref new CoreCursor(CoreCursorType::Custom, win32CursorResourceID); // Set 'PointerCursor' to 'blankCursor' in a way that shouldn't throw // an exception if the app hasn't loaded that resource. - ABI::Windows::UI::Core::ICoreCursor * iblankCursor = reinterpret_cast(blankCursor); - ABI::Windows::UI::Core::ICoreWindow * icoreWindow = reinterpret_cast(coreWindow); + ABI::Windows::UI::Core::ICoreCursor *iblankCursor = reinterpret_cast(blankCursor); + ABI::Windows::UI::Core::ICoreWindow *icoreWindow = reinterpret_cast(coreWindow); HRESULT hr = icoreWindow->put_PointerCursor(iblankCursor); if (FAILED(hr)) { // The app doesn't contain the cursor resource, or some other error @@ -184,15 +199,13 @@ WINRT_ShowCursor(SDL_Cursor * cursor) return 0; } -static int -WINRT_SetRelativeMouseMode(SDL_bool enabled) +static int WINRT_SetRelativeMouseMode(SDL_bool enabled) { WINRT_UsingRelativeMouseMode = enabled; return 0; } -void -WINRT_InitMouse(_THIS) +void WINRT_InitMouse(_THIS) { SDL_Mouse *mouse = SDL_GetMouse(); @@ -202,20 +215,19 @@ WINRT_InitMouse(_THIS) - programmatically moveable cursors */ -#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP - //mouse->CreateCursor = WINRT_CreateCursor; +#if !SDL_WINAPI_FAMILY_PHONE + // mouse->CreateCursor = WINRT_CreateCursor; mouse->CreateSystemCursor = WINRT_CreateSystemCursor; mouse->ShowCursor = WINRT_ShowCursor; mouse->FreeCursor = WINRT_FreeCursor; - //mouse->WarpMouse = WINRT_WarpMouse; + // mouse->WarpMouse = WINRT_WarpMouse; mouse->SetRelativeMouseMode = WINRT_SetRelativeMouseMode; SDL_SetDefaultCursor(WINRT_CreateDefaultCursor()); #endif } -void -WINRT_QuitMouse(_THIS) +void WINRT_QuitMouse(_THIS) { } diff --git a/SDL2-2.0.12/src/video/winrt/SDL_winrtmouse_c.h b/SDL2-2.30.5/src/video/winrt/SDL_winrtmouse_c.h similarity index 95% rename from SDL2-2.0.12/src/video/winrt/SDL_winrtmouse_c.h rename to SDL2-2.30.5/src/video/winrt/SDL_winrtmouse_c.h index 39dfba6..2271a14 100644 --- a/SDL2-2.0.12/src/video/winrt/SDL_winrtmouse_c.h +++ b/SDL2-2.30.5/src/video/winrt/SDL_winrtmouse_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/video/winrt/SDL_winrtopengles.cpp b/SDL2-2.30.5/src/video/winrt/SDL_winrtopengles.cpp similarity index 76% rename from SDL2-2.0.12/src/video/winrt/SDL_winrtopengles.cpp rename to SDL2-2.30.5/src/video/winrt/SDL_winrtopengles.cpp index adb6208..cf70241 100644 --- a/SDL2-2.0.12/src/video/winrt/SDL_winrtopengles.cpp +++ b/SDL2-2.30.5/src/video/winrt/SDL_winrtopengles.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_WINRT && SDL_VIDEO_OPENGL_EGL +#if defined(SDL_VIDEO_DRIVER_WINRT) && defined(SDL_VIDEO_OPENGL_EGL) /* EGL implementation of SDL OpenGL support */ @@ -37,17 +37,16 @@ using namespace Windows::UI::Core; /* ANGLE/WinRT constants */ static const int ANGLE_D3D_FEATURE_LEVEL_ANY = 0; -#define EGL_PLATFORM_ANGLE_ANGLE 0x3202 -#define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3203 -#define EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE 0x3204 -#define EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE 0x3205 -#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3208 -#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE 0x3209 -#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE 0x320B -#define EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE 0x320F - -#define EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER 0x320B +#define EGL_PLATFORM_ANGLE_ANGLE 0x3202 +#define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3203 +#define EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE 0x3204 +#define EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE 0x3205 +#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3208 +#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE 0x3209 +#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE 0x320B +#define EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE 0x320F +#define EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER 0x320B /* * SDL/EGL top-level implementation @@ -63,7 +62,7 @@ WINRT_GLES_LoadLibrary(_THIS, const char *path) } /* Load ANGLE/WinRT-specific functions */ - CreateWinrtEglWindow_Old_Function CreateWinrtEglWindow = (CreateWinrtEglWindow_Old_Function) SDL_LoadFunction(_this->egl_data->egl_dll_handle, "CreateWinrtEglWindow"); + CreateWinrtEglWindow_Old_Function CreateWinrtEglWindow = (CreateWinrtEglWindow_Old_Function)SDL_LoadFunction(_this->egl_data->opengl_dll_handle, "CreateWinrtEglWindow"); if (CreateWinrtEglWindow) { /* 'CreateWinrtEglWindow' was found, which means that an an older * version of ANGLE/WinRT is being used. Continue setting up EGL, @@ -98,30 +97,39 @@ WINRT_GLES_LoadLibrary(_THIS, const char *path) /* Declare some ANGLE/EGL initialization property-sets, as suggested by * MSOpenTech's ANGLE-for-WinRT template apps: */ - const EGLint defaultDisplayAttributes[] = - { - EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, - EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE, - EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE, + const EGLint defaultDisplayAttributes[] = { + EGL_PLATFORM_ANGLE_TYPE_ANGLE, + EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, + EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, + EGL_TRUE, + EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, + EGL_TRUE, EGL_NONE, }; - const EGLint fl9_3DisplayAttributes[] = - { - EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, - EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, 9, - EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, 3, - EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE, - EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE, + const EGLint fl9_3DisplayAttributes[] = { + EGL_PLATFORM_ANGLE_TYPE_ANGLE, + EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, + EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, + 9, + EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, + 3, + EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, + EGL_TRUE, + EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, + EGL_TRUE, EGL_NONE, }; - const EGLint warpDisplayAttributes[] = - { - EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, - EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE, - EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE, - EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE, + const EGLint warpDisplayAttributes[] = { + EGL_PLATFORM_ANGLE_TYPE_ANGLE, + EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, + EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, + EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE, + EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, + EGL_TRUE, + EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, + EGL_TRUE, EGL_NONE, }; @@ -136,7 +144,7 @@ WINRT_GLES_LoadLibrary(_THIS, const char *path) return SDL_EGL_SetError("Could not retrieve ANGLE/WinRT display function(s)", "eglGetProcAddress"); } -#if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) +#if !SDL_WINAPI_FAMILY_PHONE /* Try initializing EGL at D3D11 Feature Level 10_0+ (which is not * supported on WinPhone 8.x. */ @@ -193,11 +201,10 @@ WINRT_GLES_UnloadLibrary(_THIS) extern "C" { SDL_EGL_CreateContext_impl(WINRT) -SDL_EGL_SwapWindow_impl(WINRT) -SDL_EGL_MakeCurrent_impl(WINRT) + SDL_EGL_SwapWindow_impl(WINRT) + SDL_EGL_MakeCurrent_impl(WINRT) } #endif /* SDL_VIDEO_DRIVER_WINRT && SDL_VIDEO_OPENGL_EGL */ /* vi: set ts=4 sw=4 expandtab: */ - diff --git a/SDL2-2.0.12/src/video/winrt/SDL_winrtopengles.h b/SDL2-2.30.5/src/video/winrt/SDL_winrtopengles.h similarity index 72% rename from SDL2-2.0.12/src/video/winrt/SDL_winrtopengles.h rename to SDL2-2.30.5/src/video/winrt/SDL_winrtopengles.h index 5e142b1..c48a2df 100644 --- a/SDL2-2.0.12/src/video/winrt/SDL_winrtopengles.h +++ b/SDL2-2.30.5/src/video/winrt/SDL_winrtopengles.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,7 +23,7 @@ #ifndef SDL_winrtopengles_h_ #define SDL_winrtopengles_h_ -#if SDL_VIDEO_DRIVER_WINRT && SDL_VIDEO_OPENGL_EGL +#if defined(SDL_VIDEO_DRIVER_WINRT) && defined(SDL_VIDEO_OPENGL_EGL) #include "../SDL_sysvideo.h" #include "../SDL_egl_c.h" @@ -33,14 +33,13 @@ #define WINRT_GLES_GetProcAddress SDL_EGL_GetProcAddress #define WINRT_GLES_SetSwapInterval SDL_EGL_SetSwapInterval #define WINRT_GLES_GetSwapInterval SDL_EGL_GetSwapInterval -#define WINRT_GLES_DeleteContext SDL_EGL_DeleteContext +#define WINRT_GLES_DeleteContext SDL_EGL_DeleteContext extern int WINRT_GLES_LoadLibrary(_THIS, const char *path); extern void WINRT_GLES_UnloadLibrary(_THIS); -extern SDL_GLContext WINRT_GLES_CreateContext(_THIS, SDL_Window * window); -extern int WINRT_GLES_SwapWindow(_THIS, SDL_Window * window); -extern int WINRT_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context); - +extern SDL_GLContext WINRT_GLES_CreateContext(_THIS, SDL_Window *window); +extern int WINRT_GLES_SwapWindow(_THIS, SDL_Window *window); +extern int WINRT_GLES_MakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context); #ifdef __cplusplus @@ -52,16 +51,16 @@ typedef Microsoft::WRL::ComPtr WINRT_EGLNativeWindowType_Old; /* Function pointer typedefs for 'old' ANGLE/WinRT's functions, which may * require that C++ objects be passed in: */ -typedef EGLDisplay (EGLAPIENTRY *eglGetDisplay_Old_Function)(WINRT_EGLNativeWindowType_Old); -typedef EGLSurface (EGLAPIENTRY *eglCreateWindowSurface_Old_Function)(EGLDisplay, EGLConfig, WINRT_EGLNativeWindowType_Old, const EGLint *); -typedef HRESULT (EGLAPIENTRY *CreateWinrtEglWindow_Old_Function)(Microsoft::WRL::ComPtr, int, IUnknown ** result); +typedef EGLDisplay(EGLAPIENTRY *eglGetDisplay_Old_Function)(WINRT_EGLNativeWindowType_Old); +typedef EGLSurface(EGLAPIENTRY *eglCreateWindowSurface_Old_Function)(EGLDisplay, EGLConfig, WINRT_EGLNativeWindowType_Old, const EGLint *); +typedef HRESULT(EGLAPIENTRY *CreateWinrtEglWindow_Old_Function)(Microsoft::WRL::ComPtr, int, IUnknown **result); #endif /* __cplusplus */ /* Function pointer typedefs for 'new' ANGLE/WinRT functions, which, unlike * the old functions, do not require C++ support and work with plain C. */ -typedef EGLDisplay (EGLAPIENTRY *eglGetPlatformDisplayEXT_Function)(EGLenum, void *, const EGLint *); +typedef EGLDisplay(EGLAPIENTRY *eglGetPlatformDisplayEXT_Function)(EGLenum, void *, const EGLint *); #endif /* SDL_VIDEO_DRIVER_WINRT && SDL_VIDEO_OPENGL_EGL */ diff --git a/SDL2-2.0.12/src/video/winrt/SDL_winrtpointerinput.cpp b/SDL2-2.30.5/src/video/winrt/SDL_winrtpointerinput.cpp similarity index 61% rename from SDL2-2.0.12/src/video/winrt/SDL_winrtpointerinput.cpp rename to SDL2-2.30.5/src/video/winrt/SDL_winrtpointerinput.cpp index 94663ff..63c2c86 100644 --- a/SDL2-2.0.12/src/video/winrt/SDL_winrtpointerinput.cpp +++ b/SDL2-2.30.5/src/video/winrt/SDL_winrtpointerinput.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,13 +20,12 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_WINRT +#ifdef SDL_VIDEO_DRIVER_WINRT /* SDL includes */ #include "SDL_winrtevents_c.h" #include "SDL_winrtmouse_c.h" #include "SDL_winrtvideo_cpp.h" -#include "SDL_assert.h" #include "SDL_system.h" extern "C" { @@ -39,19 +38,16 @@ extern "C" { /* File-specific globals: */ static SDL_TouchID WINRT_TouchID = 1; - -void -WINRT_InitTouch(_THIS) +void WINRT_InitTouch(_THIS) { SDL_AddTouch(WINRT_TouchID, SDL_TOUCH_DEVICE_DIRECT, ""); } - // // Applies necessary geometric transformations to raw cursor positions: // Windows::Foundation::Point -WINRT_TransformCursorPosition(SDL_Window * window, +WINRT_TransformCursorPosition(SDL_Window *window, Windows::Foundation::Point rawPosition, WINRT_CursorNormalizationType normalization) { @@ -62,7 +58,7 @@ WINRT_TransformCursorPosition(SDL_Window * window, return rawPosition; } - SDL_WindowData * windowData = (SDL_WindowData *) window->driverdata; + SDL_WindowData *windowData = (SDL_WindowData *)window->driverdata; if (windowData->coreWindow == nullptr) { // For some reason, the window isn't associated with a CoreWindow. // This might end up being the case as XAML support is extended. @@ -82,149 +78,149 @@ WINRT_TransformCursorPosition(SDL_Window * window, // Compute coordinates normalized from 0..1. // If the coordinates need to be sized to the SDL window, // we'll do that after. -#if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) || (NTDDI_VERSION > NTDDI_WIN8) +#if !SDL_WINAPI_FAMILY_PHONE || (NTDDI_VERSION > NTDDI_WIN8) outputPosition.X = rawPosition.X / nativeWindow->Bounds.Width; outputPosition.Y = rawPosition.Y / nativeWindow->Bounds.Height; #else - switch (WINRT_DISPLAY_PROPERTY(CurrentOrientation)) - { - case DisplayOrientations::Portrait: - outputPosition.X = rawPosition.X / nativeWindow->Bounds.Width; - outputPosition.Y = rawPosition.Y / nativeWindow->Bounds.Height; - break; - case DisplayOrientations::PortraitFlipped: - outputPosition.X = 1.0f - (rawPosition.X / nativeWindow->Bounds.Width); - outputPosition.Y = 1.0f - (rawPosition.Y / nativeWindow->Bounds.Height); - break; - case DisplayOrientations::Landscape: - outputPosition.X = rawPosition.Y / nativeWindow->Bounds.Height; - outputPosition.Y = 1.0f - (rawPosition.X / nativeWindow->Bounds.Width); - break; - case DisplayOrientations::LandscapeFlipped: - outputPosition.X = 1.0f - (rawPosition.Y / nativeWindow->Bounds.Height); - outputPosition.Y = rawPosition.X / nativeWindow->Bounds.Width; - break; - default: - break; + switch (WINRT_DISPLAY_PROPERTY(CurrentOrientation)) { + case DisplayOrientations::Portrait: + outputPosition.X = rawPosition.X / nativeWindow->Bounds.Width; + outputPosition.Y = rawPosition.Y / nativeWindow->Bounds.Height; + break; + case DisplayOrientations::PortraitFlipped: + outputPosition.X = 1.0f - (rawPosition.X / nativeWindow->Bounds.Width); + outputPosition.Y = 1.0f - (rawPosition.Y / nativeWindow->Bounds.Height); + break; + case DisplayOrientations::Landscape: + outputPosition.X = rawPosition.Y / nativeWindow->Bounds.Height; + outputPosition.Y = 1.0f - (rawPosition.X / nativeWindow->Bounds.Width); + break; + case DisplayOrientations::LandscapeFlipped: + outputPosition.X = 1.0f - (rawPosition.Y / nativeWindow->Bounds.Height); + outputPosition.Y = rawPosition.X / nativeWindow->Bounds.Width; + break; + default: + break; } #endif if (normalization == TransformToSDLWindowSize) { - outputPosition.X *= ((float32) window->w); - outputPosition.Y *= ((float32) window->h); + outputPosition.X *= ((float32)window->w); + outputPosition.Y *= ((float32)window->h); } return outputPosition; } -static inline int -_lround(float arg) -{ - if (arg >= 0.0f) { - return (int)floor(arg + 0.5f); - } else { - return (int)ceil(arg - 0.5f); - } -} - -Uint8 -WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^pt) +SDL_bool WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^ pt, Uint8 *button, Uint8 *pressed) { using namespace Windows::UI::Input; -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP - return SDL_BUTTON_LEFT; +#if SDL_WINAPI_FAMILY_PHONE + *button = SDL_BUTTON_LEFT; + return SDL_TRUE; #else - switch (pt->Properties->PointerUpdateKind) - { - case PointerUpdateKind::LeftButtonPressed: - case PointerUpdateKind::LeftButtonReleased: - return SDL_BUTTON_LEFT; + switch (pt->Properties->PointerUpdateKind) { + case PointerUpdateKind::LeftButtonPressed: + case PointerUpdateKind::LeftButtonReleased: + *button = SDL_BUTTON_LEFT; + *pressed = (pt->Properties->PointerUpdateKind == PointerUpdateKind::LeftButtonPressed); + return SDL_TRUE; - case PointerUpdateKind::RightButtonPressed: - case PointerUpdateKind::RightButtonReleased: - return SDL_BUTTON_RIGHT; + case PointerUpdateKind::RightButtonPressed: + case PointerUpdateKind::RightButtonReleased: + *button = SDL_BUTTON_RIGHT; + *pressed = (pt->Properties->PointerUpdateKind == PointerUpdateKind::RightButtonPressed); + return SDL_TRUE; - case PointerUpdateKind::MiddleButtonPressed: - case PointerUpdateKind::MiddleButtonReleased: - return SDL_BUTTON_MIDDLE; + case PointerUpdateKind::MiddleButtonPressed: + case PointerUpdateKind::MiddleButtonReleased: + *button = SDL_BUTTON_MIDDLE; + *pressed = (pt->Properties->PointerUpdateKind == PointerUpdateKind::MiddleButtonPressed); + return SDL_TRUE; - case PointerUpdateKind::XButton1Pressed: - case PointerUpdateKind::XButton1Released: - return SDL_BUTTON_X1; + case PointerUpdateKind::XButton1Pressed: + case PointerUpdateKind::XButton1Released: + *button = SDL_BUTTON_X1; + *pressed = (pt->Properties->PointerUpdateKind == PointerUpdateKind::XButton1Pressed); + return SDL_TRUE; - case PointerUpdateKind::XButton2Pressed: - case PointerUpdateKind::XButton2Released: - return SDL_BUTTON_X2; + case PointerUpdateKind::XButton2Pressed: + case PointerUpdateKind::XButton2Released: + *button = SDL_BUTTON_X2; + *pressed = (pt->Properties->PointerUpdateKind == PointerUpdateKind::XButton2Pressed); + return SDL_TRUE; - default: - break; + default: + break; } #endif - return 0; + *button = 0; + *pressed = 0; + return SDL_FALSE; } -//const char * -//WINRT_ConvertPointerUpdateKindToString(Windows::UI::Input::PointerUpdateKind kind) +// const char * +// WINRT_ConvertPointerUpdateKindToString(Windows::UI::Input::PointerUpdateKind kind) //{ -// using namespace Windows::UI::Input; +// using namespace Windows::UI::Input; // -// switch (kind) -// { -// case PointerUpdateKind::Other: -// return "Other"; -// case PointerUpdateKind::LeftButtonPressed: -// return "LeftButtonPressed"; -// case PointerUpdateKind::LeftButtonReleased: -// return "LeftButtonReleased"; -// case PointerUpdateKind::RightButtonPressed: -// return "RightButtonPressed"; -// case PointerUpdateKind::RightButtonReleased: -// return "RightButtonReleased"; -// case PointerUpdateKind::MiddleButtonPressed: -// return "MiddleButtonPressed"; -// case PointerUpdateKind::MiddleButtonReleased: -// return "MiddleButtonReleased"; -// case PointerUpdateKind::XButton1Pressed: -// return "XButton1Pressed"; -// case PointerUpdateKind::XButton1Released: -// return "XButton1Released"; -// case PointerUpdateKind::XButton2Pressed: -// return "XButton2Pressed"; -// case PointerUpdateKind::XButton2Released: -// return "XButton2Released"; -// } +// switch (kind) +// { +// case PointerUpdateKind::Other: +// return "Other"; +// case PointerUpdateKind::LeftButtonPressed: +// return "LeftButtonPressed"; +// case PointerUpdateKind::LeftButtonReleased: +// return "LeftButtonReleased"; +// case PointerUpdateKind::RightButtonPressed: +// return "RightButtonPressed"; +// case PointerUpdateKind::RightButtonReleased: +// return "RightButtonReleased"; +// case PointerUpdateKind::MiddleButtonPressed: +// return "MiddleButtonPressed"; +// case PointerUpdateKind::MiddleButtonReleased: +// return "MiddleButtonReleased"; +// case PointerUpdateKind::XButton1Pressed: +// return "XButton1Pressed"; +// case PointerUpdateKind::XButton1Released: +// return "XButton1Released"; +// case PointerUpdateKind::XButton2Pressed: +// return "XButton2Pressed"; +// case PointerUpdateKind::XButton2Released: +// return "XButton2Released"; +// } // -// return ""; -//} +// return ""; +// } -static bool -WINRT_IsTouchEvent(Windows::UI::Input::PointerPoint ^pointerPoint) +static bool WINRT_IsTouchEvent(Windows::UI::Input::PointerPoint ^ pointerPoint) { -#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP +#if SDL_WINAPI_FAMILY_PHONE return true; #else using namespace Windows::Devices::Input; switch (pointerPoint->PointerDevice->PointerDeviceType) { - case PointerDeviceType::Touch: - case PointerDeviceType::Pen: - return true; - default: - return false; + case PointerDeviceType::Touch: + case PointerDeviceType::Pen: + return true; + default: + return false; } #endif } -void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) +void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^ pointerPoint) { if (!window) { return; } - Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint); - - if ( ! WINRT_IsTouchEvent(pointerPoint)) { + if (!WINRT_IsTouchEvent(pointerPoint)) { + Uint8 button, pressed; + WINRT_GetSDLButtonForPointerPoint(pointerPoint, &button, &pressed); + SDL_assert(pressed == 1); SDL_SendMouseButton(window, 0, SDL_PRESSED, button); } else { Windows::Foundation::Point normalizedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, NormalizeZeroToOne); @@ -232,7 +228,7 @@ void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::Po SDL_SendTouch( WINRT_TouchID, - (SDL_FingerID) pointerPoint->PointerId, + (SDL_FingerID)pointerPoint->PointerId, window, SDL_TRUE, normalizedPoint.X, @@ -241,8 +237,7 @@ void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::Po } } -void -WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) +void WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^ pointerPoint) { if (!window || WINRT_UsingRelativeMouseMode) { return; @@ -251,12 +246,18 @@ WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPo Windows::Foundation::Point normalizedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, NormalizeZeroToOne); Windows::Foundation::Point windowPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, TransformToSDLWindowSize); - if ( ! WINRT_IsTouchEvent(pointerPoint)) { + if (!WINRT_IsTouchEvent(pointerPoint)) { + /* For some odd reason Moved events are used for multiple mouse buttons */ + Uint8 button, pressed; + if (WINRT_GetSDLButtonForPointerPoint(pointerPoint, &button, &pressed)) { + SDL_SendMouseButton(window, 0, pressed, button); + } + SDL_SendMouseMotion(window, 0, 0, (int)windowPoint.X, (int)windowPoint.Y); } else { SDL_SendTouchMotion( WINRT_TouchID, - (SDL_FingerID) pointerPoint->PointerId, + (SDL_FingerID)pointerPoint->PointerId, window, normalizedPoint.X, normalizedPoint.Y, @@ -264,22 +265,23 @@ WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPo } } -void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) +void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^ pointerPoint) { if (!window) { return; } - Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint); - if (!WINRT_IsTouchEvent(pointerPoint)) { + Uint8 button, pressed; + WINRT_GetSDLButtonForPointerPoint(pointerPoint, &button, &pressed); + SDL_assert(pressed == 0); SDL_SendMouseButton(window, 0, SDL_RELEASED, button); } else { Windows::Foundation::Point normalizedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, NormalizeZeroToOne); SDL_SendTouch( WINRT_TouchID, - (SDL_FingerID) pointerPoint->PointerId, + (SDL_FingerID)pointerPoint->PointerId, window, SDL_FALSE, normalizedPoint.X, @@ -288,7 +290,7 @@ void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::P } } -void WINRT_ProcessPointerEnteredEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) +void WINRT_ProcessPointerEnteredEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^ pointerPoint) { if (!window) { return; @@ -299,7 +301,7 @@ void WINRT_ProcessPointerEnteredEvent(SDL_Window *window, Windows::UI::Input::Po } } -void WINRT_ProcessPointerExitedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) +void WINRT_ProcessPointerExitedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^ pointerPoint) { if (!window) { return; @@ -310,19 +312,17 @@ void WINRT_ProcessPointerExitedEvent(SDL_Window *window, Windows::UI::Input::Poi } } -void -WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint) +void WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^ pointerPoint) { if (!window) { return; } - float motion = (float) pointerPoint->Properties->MouseWheelDelta / WHEEL_DELTA; - SDL_SendMouseWheel(window, 0, 0, (float) motion, SDL_MOUSEWHEEL_NORMAL); + float motion = (float)pointerPoint->Properties->MouseWheelDelta / WHEEL_DELTA; + SDL_SendMouseWheel(window, 0, 0, (float)motion, SDL_MOUSEWHEEL_NORMAL); } -void -WINRT_ProcessMouseMovedEvent(SDL_Window * window, Windows::Devices::Input::MouseEventArgs ^args) +void WINRT_ProcessMouseMovedEvent(SDL_Window *window, Windows::Devices::Input::MouseEventArgs ^ args) { if (!window || !WINRT_UsingRelativeMouseMode) { return; @@ -390,8 +390,8 @@ WINRT_ProcessMouseMovedEvent(SDL_Window * window, Windows::Devices::Input::Mouse window, 0, 1, - _lround(mouseDeltaInSDLWindowCoords.X), - _lround(mouseDeltaInSDLWindowCoords.Y)); + SDL_lroundf(mouseDeltaInSDLWindowCoords.X), + SDL_lroundf(mouseDeltaInSDLWindowCoords.Y)); } #endif // SDL_VIDEO_DRIVER_WINRT diff --git a/SDL2-2.0.12/src/video/winrt/SDL_winrtvideo.cpp b/SDL2-2.30.5/src/video/winrt/SDL_winrtvideo.cpp similarity index 70% rename from SDL2-2.0.12/src/video/winrt/SDL_winrtvideo.cpp rename to SDL2-2.30.5/src/video/winrt/SDL_winrtvideo.cpp index 5d24886..9160bbb 100644 --- a/SDL2-2.0.12/src/video/winrt/SDL_winrtvideo.cpp +++ b/SDL2-2.30.5/src/video/winrt/SDL_winrtvideo.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_WINRT +#ifdef SDL_VIDEO_DRIVER_WINRT /* WinRT SDL video driver implementation @@ -28,6 +28,10 @@ was based off of SDL's "dummy" video driver. */ +/* Standard C++11 includes */ +#include +#include + /* Windows includes */ #include #include @@ -40,11 +44,9 @@ using namespace Windows::Graphics::Display; using namespace Windows::UI::Core; using namespace Windows::UI::ViewManagement; - /* [re]declare Windows GUIDs locally, to limit the amount of external lib(s) SDL has to link to */ -static const GUID IID_IDisplayRequest = { 0xe5732044, 0xf49f, 0x4b60, { 0x8d, 0xd4, 0x5e, 0x7e, 0x3a, 0x63, 0x2a, 0xc0 } }; -static const GUID IID_IDXGIFactory2 = { 0x50c83a1c, 0xe072, 0x4c48, { 0x87, 0xb0, 0x36, 0x30, 0xfa, 0x36, 0xa6, 0xd0 } }; - +static const GUID SDL_IID_IDisplayRequest = { 0xe5732044, 0xf49f, 0x4b60, { 0x8d, 0xd4, 0x5e, 0x7e, 0x3a, 0x63, 0x2a, 0xc0 } }; +static const GUID SDL_IID_IDXGIFactory2 = { 0x50c83a1c, 0xe072, 0x4c48, { 0x87, 0xb0, 0x36, 0x30, 0xfa, 0x36, 0xa6, 0xd0 } }; /* SDL includes */ extern "C" { @@ -57,6 +59,7 @@ extern "C" { #include "SDL_syswm.h" #include "SDL_winrtopengles.h" #include "../../core/windows/SDL_windows.h" +#include "SDL_winrtmessagebox.h" } #include "../../core/winrt/SDL_winrtapp_direct3d.h" @@ -67,16 +70,14 @@ extern "C" { #include "SDL_winrtmouse_c.h" #include "SDL_main.h" #include "SDL_system.h" -//#include "SDL_log.h" - +#include "SDL_hints.h" /* Initialization/Query functions */ static int WINRT_VideoInit(_THIS); static int WINRT_InitModes(_THIS); -static int WINRT_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode); +static int WINRT_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode); static void WINRT_VideoQuit(_THIS); - /* Window functions */ static int WINRT_CreateWindow(_THIS, SDL_Window * window); static void WINRT_SetWindowSize(_THIS, SDL_Window * window); @@ -86,27 +87,18 @@ static SDL_bool WINRT_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo /* Misc functions */ -static ABI::Windows::System::Display::IDisplayRequest * WINRT_CreateDisplayRequest(_THIS); +static ABI::Windows::System::Display::IDisplayRequest *WINRT_CreateDisplayRequest(_THIS); extern void WINRT_SuspendScreenSaver(_THIS); - /* SDL-internal globals: */ -SDL_Window * WINRT_GlobalSDLWindow = NULL; - +SDL_Window *WINRT_GlobalSDLWindow = NULL; /* WinRT driver bootstrap functions */ -static int -WINRT_Available(void) -{ - return (1); -} - -static void -WINRT_DeleteDevice(SDL_VideoDevice * device) +static void WINRT_DeleteDevice(SDL_VideoDevice *device) { if (device->driverdata) { - SDL_VideoData * video_data = (SDL_VideoData *)device->driverdata; + SDL_VideoData *video_data = (SDL_VideoData *)device->driverdata; if (video_data->winrtEglWindow) { video_data->winrtEglWindow->Release(); } @@ -116,24 +108,23 @@ WINRT_DeleteDevice(SDL_VideoDevice * device) SDL_free(device); } -static SDL_VideoDevice * -WINRT_CreateDevice(int devindex) +static SDL_VideoDevice *WINRT_CreateDevice(void) { SDL_VideoDevice *device; SDL_VideoData *data; /* Initialize all variables that we clean on shutdown */ - device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice)); + device = (SDL_VideoDevice *)SDL_calloc(1, sizeof(SDL_VideoDevice)); if (!device) { SDL_OutOfMemory(); - return (0); + return 0; } - data = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData)); + data = (SDL_VideoData *)SDL_calloc(1, sizeof(SDL_VideoData)); if (!data) { SDL_OutOfMemory(); SDL_free(device); - return (0); + return 0; } device->driverdata = data; @@ -154,6 +145,8 @@ WINRT_CreateDevice(int devindex) device->ShowScreenKeyboard = WINRT_ShowScreenKeyboard; device->HideScreenKeyboard = WINRT_HideScreenKeyboard; device->IsScreenKeyboardShown = WINRT_IsScreenKeyboardShown; + + WINTRT_InitialiseInputPaneEvents(device); #endif #ifdef SDL_VIDEO_OPENGL_EGL @@ -172,19 +165,83 @@ WINRT_CreateDevice(int devindex) return device; } -#define WINRTVID_DRIVER_NAME "winrt" VideoBootStrap WINRT_bootstrap = { - WINRTVID_DRIVER_NAME, "SDL WinRT video driver", - WINRT_Available, WINRT_CreateDevice + "winrt", "SDL WinRT video driver", + WINRT_CreateDevice, + WINRT_ShowMessageBox }; -int -WINRT_VideoInit(_THIS) +static void SDLCALL WINRT_SetDisplayOrientationsPreference(void *userdata, const char *name, const char *oldValue, const char *newValue) { - SDL_VideoData * driverdata = (SDL_VideoData *) _this->driverdata; + SDL_assert(SDL_strcmp(name, SDL_HINT_ORIENTATIONS) == 0); + + /* HACK: prevent SDL from altering an app's .appxmanifest-set orientation + * from being changed on startup, by detecting when SDL_HINT_ORIENTATIONS + * is getting registered. + * + * TODO, WinRT: consider reading in an app's .appxmanifest file, and apply its orientation when 'newValue == NULL'. + */ + if ((!oldValue) && (!newValue)) { + return; + } + + // Start with no orientation flags, then add each in as they're parsed + // from newValue. + unsigned int orientationFlags = 0; + if (newValue) { + std::istringstream tokenizer(newValue); + while (!tokenizer.eof()) { + std::string orientationName; + std::getline(tokenizer, orientationName, ' '); + if (orientationName == "LandscapeLeft") { + orientationFlags |= (unsigned int)DisplayOrientations::LandscapeFlipped; + } else if (orientationName == "LandscapeRight") { + orientationFlags |= (unsigned int)DisplayOrientations::Landscape; + } else if (orientationName == "Portrait") { + orientationFlags |= (unsigned int)DisplayOrientations::Portrait; + } else if (orientationName == "PortraitUpsideDown") { + orientationFlags |= (unsigned int)DisplayOrientations::PortraitFlipped; + } + } + } + + // If no valid orientation flags were specified, use a reasonable set of defaults: + if (!orientationFlags) { + // TODO, WinRT: consider seeing if an app's default orientation flags can be found out via some API call(s). + orientationFlags = (unsigned int)(DisplayOrientations::Landscape | + DisplayOrientations::LandscapeFlipped | + DisplayOrientations::Portrait | + DisplayOrientations::PortraitFlipped); + } + + // Set the orientation/rotation preferences. Please note that this does + // not constitute a 100%-certain lock of a given set of possible + // orientations. According to Microsoft's documentation on WinRT [1] + // when a device is not capable of being rotated, Windows may ignore + // the orientation preferences, and stick to what the device is capable of + // displaying. + // + // [1] Documentation on the 'InitialRotationPreference' setting for a + // Windows app's manifest file describes how some orientation/rotation + // preferences may be ignored. See + // http://msdn.microsoft.com/en-us/library/windows/apps/hh700343.aspx + // for details. Microsoft's "Display orientation sample" also gives an + // outline of how Windows treats device rotation + // (http://code.msdn.microsoft.com/Display-Orientation-Sample-19a58e93). + WINRT_DISPLAY_PROPERTY(AutoRotationPreferences) = (DisplayOrientations)orientationFlags; +} + +int WINRT_VideoInit(_THIS) +{ + SDL_VideoData *driverdata = (SDL_VideoData *)_this->driverdata; if (WINRT_InitModes(_this) < 0) { return -1; } + + // Register the hint, SDL_HINT_ORIENTATIONS, with SDL. + // TODO, WinRT: see if an app's default orientation can be found out via WinRT API(s), then set the initial value of SDL_HINT_ORIENTATIONS accordingly. + SDL_AddHintCallback(SDL_HINT_ORIENTATIONS, WINRT_SetDisplayOrientationsPreference, NULL); + WINRT_InitMouse(_this); WINRT_InitTouch(_this); WINRT_InitGameBar(_this); @@ -195,11 +252,9 @@ WINRT_VideoInit(_THIS) return 0; } -extern "C" -Uint32 D3D11_DXGIFormatToSDLPixelFormat(DXGI_FORMAT dxgiFormat); +extern "C" Uint32 D3D11_DXGIFormatToSDLPixelFormat(DXGI_FORMAT dxgiFormat); -static void -WINRT_DXGIModeToSDLDisplayMode(const DXGI_MODE_DESC * dxgiMode, SDL_DisplayMode * sdlMode) +static void WINRT_DXGIModeToSDLDisplayMode(const DXGI_MODE_DESC *dxgiMode, SDL_DisplayMode *sdlMode) { SDL_zerop(sdlMode); sdlMode->w = dxgiMode->Width; @@ -208,17 +263,16 @@ WINRT_DXGIModeToSDLDisplayMode(const DXGI_MODE_DESC * dxgiMode, SDL_DisplayMode sdlMode->format = D3D11_DXGIFormatToSDLPixelFormat(dxgiMode->Format); } -static int -WINRT_AddDisplaysForOutput (_THIS, IDXGIAdapter1 * dxgiAdapter1, int outputIndex) +static int WINRT_AddDisplaysForOutput(_THIS, IDXGIAdapter1 *dxgiAdapter1, int outputIndex) { HRESULT hr; - IDXGIOutput * dxgiOutput = NULL; + IDXGIOutput *dxgiOutput = NULL; DXGI_OUTPUT_DESC dxgiOutputDesc; SDL_VideoDisplay display; - char * displayName = NULL; + char *displayName = NULL; UINT numModes; - DXGI_MODE_DESC * dxgiModes = NULL; - int functionResult = -1; /* -1 for failure, 0 for success */ + DXGI_MODE_DESC *dxgiModes = NULL; + int functionResult = -1; /* -1 for failure, 0 for success */ DXGI_MODE_DESC modeToMatch, closestMatch; SDL_zero(display); @@ -257,10 +311,10 @@ WINRT_AddDisplaysForOutput (_THIS, IDXGIAdapter1 * dxgiAdapter1, int outputIndex mode.w = (dxgiOutputDesc.DesktopCoordinates.right - dxgiOutputDesc.DesktopCoordinates.left); mode.h = (dxgiOutputDesc.DesktopCoordinates.bottom - dxgiOutputDesc.DesktopCoordinates.top); mode.format = DXGI_FORMAT_B8G8R8A8_UNORM; - mode.refresh_rate = 0; /* Display mode is unknown, so just fill in zero, as specified by SDL's header files */ + mode.refresh_rate = 0; /* Display mode is unknown, so just fill in zero, as specified by SDL's header files */ display.desktop_mode = mode; display.current_mode = mode; - if ( ! SDL_AddDisplayMode(&display, &mode)) { + if (!SDL_AddDisplayMode(&display, &mode)) { goto done; } } else if (FAILED(hr)) { @@ -282,7 +336,7 @@ WINRT_AddDisplaysForOutput (_THIS, IDXGIAdapter1 * dxgiAdapter1, int outputIndex } dxgiModes = (DXGI_MODE_DESC *)SDL_calloc(numModes, sizeof(DXGI_MODE_DESC)); - if ( ! dxgiModes) { + if (!dxgiModes) { SDL_OutOfMemory(); goto done; } @@ -300,11 +354,11 @@ WINRT_AddDisplaysForOutput (_THIS, IDXGIAdapter1 * dxgiAdapter1, int outputIndex } } - if (SDL_AddVideoDisplay(&display) < 0) { + if (SDL_AddVideoDisplay(&display, SDL_FALSE) < 0) { goto done; } - functionResult = 0; /* 0 for Success! */ + functionResult = 0; /* 0 for Success! */ done: if (dxgiModes) { SDL_free(dxgiModes); @@ -318,11 +372,10 @@ done: return functionResult; } -static int -WINRT_AddDisplaysForAdapter (_THIS, IDXGIFactory2 * dxgiFactory2, int adapterIndex) +static int WINRT_AddDisplaysForAdapter(_THIS, IDXGIFactory2 *dxgiFactory2, int adapterIndex) { HRESULT hr; - IDXGIAdapter1 * dxgiAdapter1; + IDXGIAdapter1 *dxgiAdapter1; hr = dxgiFactory2->EnumAdapters1(adapterIndex, &dxgiAdapter1); if (FAILED(hr)) { @@ -332,7 +385,7 @@ WINRT_AddDisplaysForAdapter (_THIS, IDXGIFactory2 * dxgiFactory2, int adapterInd return -1; } - for (int outputIndex = 0; ; ++outputIndex) { + for (int outputIndex = 0;; ++outputIndex) { if (WINRT_AddDisplaysForOutput(_this, dxgiAdapter1, outputIndex) < 0) { /* HACK: The Windows App Certification Kit 10.0 can fail, when running the Store Apps' test, "Direct3D Feature Test". The @@ -352,7 +405,7 @@ WINRT_AddDisplaysForAdapter (_THIS, IDXGIFactory2 * dxgiFactory2, int adapterInd if (adapterIndex == 0 && outputIndex == 0) { SDL_VideoDisplay display; SDL_DisplayMode mode; -#if SDL_WINRT_USE_APPLICATIONVIEW +#ifdef SDL_WINRT_USE_APPLICATIONVIEW ApplicationView ^ appView = ApplicationView::GetForCurrentView(); #endif CoreWindow ^ coreWin = CoreWindow::GetForCurrentThread(); @@ -367,7 +420,7 @@ WINRT_AddDisplaysForAdapter (_THIS, IDXGIFactory2 * dxgiFactory2, int adapterInd failing test), whereas CoreWindow might not. -- DavidL */ -#if (NTDDI_VERSION >= NTDDI_WIN10) || (SDL_WINRT_USE_APPLICATIONVIEW && WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) +#if (NTDDI_VERSION >= NTDDI_WIN10) || (defined(SDL_WINRT_USE_APPLICATIONVIEW) && SDL_WINAPI_FAMILY_PHONE) mode.w = WINRT_DIPS_TO_PHYSICAL_PIXELS(appView->VisibleBounds.Width); mode.h = WINRT_DIPS_TO_PHYSICAL_PIXELS(appView->VisibleBounds.Height); #else @@ -379,12 +432,11 @@ WINRT_AddDisplaysForAdapter (_THIS, IDXGIFactory2 * dxgiFactory2, int adapterInd #endif mode.format = DXGI_FORMAT_B8G8R8A8_UNORM; - mode.refresh_rate = 0; /* Display mode is unknown, so just fill in zero, as specified by SDL's header files */ + mode.refresh_rate = 0; /* Display mode is unknown, so just fill in zero, as specified by SDL's header files */ display.desktop_mode = mode; display.current_mode = mode; if ((SDL_AddDisplayMode(&display, &mode) < 0) || - (SDL_AddVideoDisplay(&display) < 0)) - { + (SDL_AddVideoDisplay(&display, SDL_FALSE) < 0)) { return SDL_SetError("Failed to apply DXGI Display-detection workaround"); } } @@ -397,8 +449,7 @@ WINRT_AddDisplaysForAdapter (_THIS, IDXGIFactory2 * dxgiFactory2, int adapterInd return 0; } -int -WINRT_InitModes(_THIS) +int WINRT_InitModes(_THIS) { /* HACK: Initialize a single display, for whatever screen the app's CoreApplicationView is on. @@ -407,15 +458,14 @@ WINRT_InitModes(_THIS) */ HRESULT hr; - IDXGIFactory2 * dxgiFactory2 = NULL; + IDXGIFactory2 *dxgiFactory2 = NULL; - hr = CreateDXGIFactory1(IID_IDXGIFactory2, (void **)&dxgiFactory2); + hr = CreateDXGIFactory1(SDL_IID_IDXGIFactory2, (void **)&dxgiFactory2); if (FAILED(hr)) { - WIN_SetErrorFromHRESULT(__FUNCTION__ ", CreateDXGIFactory1() failed", hr); - return -1; + return WIN_SetErrorFromHRESULT(__FUNCTION__ ", CreateDXGIFactory1() failed", hr); } - for (int adapterIndex = 0; ; ++adapterIndex) { + for (int adapterIndex = 0;; ++adapterIndex) { if (WINRT_AddDisplaysForAdapter(_this, dxgiFactory2, adapterIndex) < 0) { break; } @@ -424,16 +474,14 @@ WINRT_InitModes(_THIS) return 0; } -static int -WINRT_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) +static int WINRT_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode) { return 0; } -void -WINRT_VideoQuit(_THIS) +void WINRT_VideoQuit(_THIS) { - SDL_VideoData * driverdata = (SDL_VideoData *) _this->driverdata; + SDL_VideoData *driverdata = (SDL_VideoData *)_this->driverdata; if (driverdata && driverdata->displayRequest) { driverdata->displayRequest->Release(); driverdata->displayRequest = NULL; @@ -442,52 +490,47 @@ WINRT_VideoQuit(_THIS) WINRT_QuitMouse(_this); } -static const Uint32 WINRT_DetectableFlags = - SDL_WINDOW_MAXIMIZED | - SDL_WINDOW_FULLSCREEN_DESKTOP | - SDL_WINDOW_SHOWN | - SDL_WINDOW_HIDDEN | - SDL_WINDOW_MOUSE_FOCUS; +static const Uint32 WINRT_DetectableFlags = SDL_WINDOW_MAXIMIZED | SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_SHOWN | SDL_WINDOW_HIDDEN | SDL_WINDOW_MOUSE_FOCUS; extern "C" Uint32 -WINRT_DetectWindowFlags(SDL_Window * window) +WINRT_DetectWindowFlags(SDL_Window *window) { Uint32 latestFlags = 0; - SDL_WindowData * data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; bool is_fullscreen = false; -#if SDL_WINRT_USE_APPLICATIONVIEW +#ifdef SDL_WINRT_USE_APPLICATIONVIEW if (data->appView) { - is_fullscreen = data->appView->IsFullScreen; + is_fullscreen = data->appView->IsFullScreenMode; } -#elif (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) || (NTDDI_VERSION == NTDDI_WIN8) +#elif SDL_WINAPI_FAMILY_PHONE || (NTDDI_VERSION == NTDDI_WIN8) is_fullscreen = true; #endif if (data->coreWindow.Get()) { if (is_fullscreen) { - SDL_VideoDisplay * display = SDL_GetDisplayForWindow(window); + SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); int w = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Width); int h = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Height); -#if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) || (NTDDI_VERSION > NTDDI_WIN8) +#if !SDL_WINAPI_FAMILY_PHONE || (NTDDI_VERSION > NTDDI_WIN8) // On all WinRT platforms, except for WinPhone 8.0, rotate the // window size. This is needed to properly calculate // fullscreen vs. maximized. const DisplayOrientations currentOrientation = WINRT_DISPLAY_PROPERTY(CurrentOrientation); switch (currentOrientation) { -#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) - case DisplayOrientations::Landscape: - case DisplayOrientations::LandscapeFlipped: +#if SDL_WINAPI_FAMILY_PHONE + case DisplayOrientations::Landscape: + case DisplayOrientations::LandscapeFlipped: #else - case DisplayOrientations::Portrait: - case DisplayOrientations::PortraitFlipped: + case DisplayOrientations::Portrait: + case DisplayOrientations::PortraitFlipped: #endif - { - int tmp = w; - w = h; - h = tmp; - } break; + { + int tmp = w; + w = h; + h = tmp; + } break; } #endif @@ -504,7 +547,7 @@ WINRT_DetectWindowFlags(SDL_Window * window) latestFlags |= SDL_WINDOW_HIDDEN; } -#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) && (NTDDI_VERSION < NTDDI_WINBLUE) +#if SDL_WINAPI_FAMILY_PHONE && (NTDDI_VERSION < NTDDI_WINBLUE) // data->coreWindow->PointerPosition is not supported on WinPhone 8.0 latestFlags |= SDL_WINDOW_MOUSE_FOCUS; #else @@ -518,59 +561,54 @@ WINRT_DetectWindowFlags(SDL_Window * window) } // TODO, WinRT: consider removing WINRT_UpdateWindowFlags, and just calling WINRT_DetectWindowFlags as-appropriate (with appropriate calls to SDL_SendWindowEvent) -void -WINRT_UpdateWindowFlags(SDL_Window * window, Uint32 mask) +void WINRT_UpdateWindowFlags(SDL_Window *window, Uint32 mask) { mask &= WINRT_DetectableFlags; if (window) { Uint32 apply = WINRT_DetectWindowFlags(window); if ((apply & mask) & SDL_WINDOW_FULLSCREEN) { - window->last_fullscreen_flags = window->flags; // seems necessary to programmatically un-fullscreen, via SDL APIs + window->last_fullscreen_flags = window->flags; // seems necessary to programmatically un-fullscreen, via SDL APIs } window->flags = (window->flags & ~mask) | (apply & mask); } } -static bool -WINRT_IsCoreWindowActive(CoreWindow ^ coreWindow) +static bool WINRT_IsCoreWindowActive(CoreWindow ^ coreWindow) { /* WinRT does not appear to offer API(s) to determine window-activation state, at least not that I am aware of in Win8 - Win10. As such, SDL tracks this itself, via window-activation events. - + If there *is* an API to track this, it should probably get used instead of the following hack (that uses "SDLHelperWindowActivationState"). -- DavidL. */ if (coreWindow->CustomProperties->HasKey("SDLHelperWindowActivationState")) { - CoreWindowActivationState activationState = \ + CoreWindowActivationState activationState = safe_cast(coreWindow->CustomProperties->Lookup("SDLHelperWindowActivationState")); - return (activationState != CoreWindowActivationState::Deactivated); + return activationState != CoreWindowActivationState::Deactivated; } /* Assume that non-SDL tracked windows are active, although this should probably be avoided, if possible. - + This might not even be possible, in normal SDL use, at least as of this writing (Dec 22, 2015; via latest hg.libsdl.org/SDL clone) -- DavidL */ return true; } -int -WINRT_CreateWindow(_THIS, SDL_Window * window) +int WINRT_CreateWindow(_THIS, SDL_Window *window) { // Make sure that only one window gets created, at least until multimonitor // support is added. if (WINRT_GlobalSDLWindow != NULL) { - SDL_SetError("WinRT only supports one window"); - return -1; + return SDL_SetError("WinRT only supports one window"); } - SDL_WindowData *data = new SDL_WindowData; /* use 'new' here as SDL_WindowData may use WinRT/C++ types */ + SDL_WindowData *data = new SDL_WindowData; /* use 'new' here as SDL_WindowData may use WinRT/C++ types */ if (!data) { - SDL_OutOfMemory(); - return -1; + return SDL_OutOfMemory(); } window->driverdata = data; data->sdlWindow = window; @@ -583,7 +621,7 @@ WINRT_CreateWindow(_THIS, SDL_Window * window) */ if (!WINRT_XAMLWasEnabled) { data->coreWindow = CoreWindow::GetForCurrentThread(); -#if SDL_WINRT_USE_APPLICATIONVIEW +#ifdef SDL_WINRT_USE_APPLICATIONVIEW data->appView = ApplicationView::GetForCurrentView(); #endif } @@ -591,14 +629,14 @@ WINRT_CreateWindow(_THIS, SDL_Window * window) /* Make note of the requested window flags, before they start getting changed. */ const Uint32 requestedFlags = window->flags; -#if SDL_VIDEO_OPENGL_EGL +#ifdef SDL_VIDEO_OPENGL_EGL /* Setup the EGL surface, but only if OpenGL ES 2 was requested. */ if (!(window->flags & SDL_WINDOW_OPENGL)) { /* OpenGL ES 2 wasn't requested. Don't set up an EGL surface. */ data->egl_surface = EGL_NO_SURFACE; } else { /* OpenGL ES 2 was reuqested. Set up an EGL surface. */ - SDL_VideoData * video_data = (SDL_VideoData *)_this->driverdata; + SDL_VideoData *video_data = (SDL_VideoData *)_this->driverdata; /* Call SDL_EGL_ChooseConfig and eglCreateWindowSurface directly, * rather than via SDL_EGL_CreateSurface, as older versions of @@ -606,12 +644,11 @@ WINRT_CreateWindow(_THIS, SDL_Window * window) * be passed into eglCreateWindowSurface. */ if (SDL_EGL_ChooseConfig(_this) != 0) { - char buf[512]; - SDL_snprintf(buf, sizeof(buf), "SDL_EGL_ChooseConfig failed: %s", SDL_GetError()); - return SDL_SetError("%s", buf); + /* SDL_EGL_ChooseConfig failed, SDL_GetError() should have info */ + return -1; } - if (video_data->winrtEglWindow) { /* ... is the 'old' version of ANGLE/WinRT being used? */ + if (video_data->winrtEglWindow) { /* ... is the 'old' version of ANGLE/WinRT being used? */ /* Attempt to create a window surface using older versions of * ANGLE/WinRT: */ @@ -627,11 +664,11 @@ WINRT_CreateWindow(_THIS, SDL_Window * window) /* Attempt to create a window surface using newer versions of * ANGLE/WinRT: */ - IInspectable * coreWindowAsIInspectable = reinterpret_cast(data->coreWindow.Get()); + IInspectable *coreWindowAsIInspectable = reinterpret_cast(data->coreWindow.Get()); data->egl_surface = _this->egl_data->eglCreateWindowSurface( _this->egl_data->egl_display, _this->egl_data->egl_config, - coreWindowAsIInspectable, + (NativeWindowType)coreWindowAsIInspectable, NULL); if (data->egl_surface == NULL) { return SDL_EGL_SetError("unable to create EGL native-window surface", "eglCreateWindowSurface"); @@ -647,7 +684,7 @@ WINRT_CreateWindow(_THIS, SDL_Window * window) SDL_WINDOW_BORDERLESS | SDL_WINDOW_RESIZABLE; -#if SDL_VIDEO_OPENGL_EGL +#ifdef SDL_VIDEO_OPENGL_EGL if (data->egl_surface) { window->flags |= SDL_WINDOW_OPENGL; } @@ -658,8 +695,8 @@ WINRT_CreateWindow(_THIS, SDL_Window * window) window->x = 0; window->y = 0; window->flags |= SDL_WINDOW_SHOWN; - SDL_SetMouseFocus(NULL); // TODO: detect this - SDL_SetKeyboardFocus(NULL); // TODO: detect this + SDL_SetMouseFocus(NULL); // TODO: detect this + SDL_SetKeyboardFocus(NULL); // TODO: detect this } else { /* WinRT 8.x apps seem to live in an environment where the OS controls the app's window size, with some apps being fullscreen, depending on @@ -693,7 +730,7 @@ WINRT_CreateWindow(_THIS, SDL_Window * window) WINRT_UpdateWindowFlags( window, - 0xffffffff /* Update any window flag(s) that WINRT_UpdateWindow can handle */ + 0xffffffff /* Update any window flag(s) that WINRT_UpdateWindow can handle */ ); /* Try detecting if the window is active */ @@ -702,7 +739,7 @@ WINRT_CreateWindow(_THIS, SDL_Window * window) SDL_SetKeyboardFocus(window); } } - + /* Make sure the WinRT app's IFramworkView can post events on behalf of SDL: */ @@ -712,27 +749,25 @@ WINRT_CreateWindow(_THIS, SDL_Window * window) return 0; } -void -WINRT_SetWindowSize(_THIS, SDL_Window * window) +void WINRT_SetWindowSize(_THIS, SDL_Window *window) { #if NTDDI_VERSION >= NTDDI_WIN10 - SDL_WindowData * data = (SDL_WindowData *)window->driverdata; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; const Windows::Foundation::Size size(WINRT_PHYSICAL_PIXELS_TO_DIPS(window->w), WINRT_PHYSICAL_PIXELS_TO_DIPS(window->h)); data->appView->TryResizeView(size); // TODO, WinRT: return failure (to caller?) from TryResizeView() #endif } -void -WINRT_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen) +void WINRT_SetWindowFullscreen(_THIS, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen) { #if NTDDI_VERSION >= NTDDI_WIN10 - SDL_WindowData * data = (SDL_WindowData *)window->driverdata; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; bool isWindowActive = WINRT_IsCoreWindowActive(data->coreWindow.Get()); if (isWindowActive) { if (fullscreen) { if (!data->appView->IsFullScreenMode) { - data->appView->TryEnterFullScreenMode(); // TODO, WinRT: return failure (to caller?) from TryEnterFullScreenMode() + data->appView->TryEnterFullScreenMode(); // TODO, WinRT: return failure (to caller?) from TryEnterFullScreenMode() } } else { if (data->appView->IsFullScreenMode) { @@ -743,11 +778,9 @@ WINRT_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display #endif } - -void -WINRT_DestroyWindow(_THIS, SDL_Window * window) +void WINRT_DestroyWindow(_THIS, SDL_Window *window) { - SDL_WindowData * data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; if (WINRT_GlobalSDLWindow == window) { WINRT_GlobalSDLWindow = NULL; @@ -761,8 +794,7 @@ WINRT_DestroyWindow(_THIS, SDL_Window * window) } } -SDL_bool -WINRT_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info) +SDL_bool WINRT_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info) { SDL_WindowData * data = (SDL_WindowData *) window->driverdata; @@ -771,25 +803,24 @@ WINRT_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info) info->info.winrt.window = reinterpret_cast(data->coreWindow.Get()); return SDL_TRUE; } else { - SDL_SetError("Application not compiled with SDL %d.%d", - SDL_MAJOR_VERSION, SDL_MINOR_VERSION); + SDL_SetError("Application not compiled with SDL %d", + SDL_MAJOR_VERSION); return SDL_FALSE; } return SDL_FALSE; } -static ABI::Windows::System::Display::IDisplayRequest * -WINRT_CreateDisplayRequest(_THIS) +static ABI::Windows::System::Display::IDisplayRequest *WINRT_CreateDisplayRequest(_THIS) { /* Setup a WinRT DisplayRequest object, usable for enabling/disabling screensaver requests */ wchar_t *wClassName = L"Windows.System.Display.DisplayRequest"; HSTRING hClassName; IActivationFactory *pActivationFactory = NULL; - IInspectable * pDisplayRequestRaw = nullptr; - ABI::Windows::System::Display::IDisplayRequest * pDisplayRequest = nullptr; + IInspectable *pDisplayRequestRaw = nullptr; + ABI::Windows::System::Display::IDisplayRequest *pDisplayRequest = nullptr; HRESULT hr; - hr = ::WindowsCreateString(wClassName, (UINT32)wcslen(wClassName), &hClassName); + hr = ::WindowsCreateString(wClassName, (UINT32)SDL_wcslen(wClassName), &hClassName); if (FAILED(hr)) { goto done; } @@ -804,7 +835,7 @@ WINRT_CreateDisplayRequest(_THIS) goto done; } - hr = pDisplayRequestRaw->QueryInterface(IID_IDisplayRequest, (void **) &pDisplayRequest); + hr = pDisplayRequestRaw->QueryInterface(SDL_IID_IDisplayRequest, (void **)&pDisplayRequest); if (FAILED(hr)) { goto done; } @@ -823,12 +854,11 @@ done: return pDisplayRequest; } -void -WINRT_SuspendScreenSaver(_THIS) +void WINRT_SuspendScreenSaver(_THIS) { SDL_VideoData *driverdata = (SDL_VideoData *)_this->driverdata; if (driverdata && driverdata->displayRequest) { - ABI::Windows::System::Display::IDisplayRequest * displayRequest = (ABI::Windows::System::Display::IDisplayRequest *) driverdata->displayRequest; + ABI::Windows::System::Display::IDisplayRequest *displayRequest = (ABI::Windows::System::Display::IDisplayRequest *)driverdata->displayRequest; if (_this->suspend_screensaver) { displayRequest->RequestActive(); } else { diff --git a/SDL2-2.0.12/src/video/winrt/SDL_winrtvideo_cpp.h b/SDL2-2.30.5/src/video/winrt/SDL_winrtvideo_cpp.h similarity index 74% rename from SDL2-2.0.12/src/video/winrt/SDL_winrtvideo_cpp.h rename to SDL2-2.30.5/src/video/winrt/SDL_winrtvideo_cpp.h index c167b88..a60b3aa 100644 --- a/SDL2-2.0.12/src/video/winrt/SDL_winrtvideo_cpp.h +++ b/SDL2-2.30.5/src/video/winrt/SDL_winrtvideo_cpp.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -29,9 +29,9 @@ #include "SDL_video.h" #include "SDL_events.h" -#if NTDDI_VERSION >= NTDDI_WINBLUE /* ApplicationView's functionality only becomes - useful for SDL in Win[Phone] 8.1 and up. - Plus, it is not available at all in WinPhone 8.0. */ +#if NTDDI_VERSION >= NTDDI_WINBLUE /* ApplicationView's functionality only becomes \ + useful for SDL in Win[Phone] 8.1 and up. \ + Plus, it is not available at all in WinPhone 8.0. */ #define SDL_WINRT_USE_APPLICATIONVIEW 1 #endif @@ -41,7 +41,8 @@ extern "C" { } /* Private display data */ -typedef struct SDL_VideoData { +typedef struct SDL_VideoData +{ /* An object created by ANGLE/WinRT (OpenGL ES 2 for WinRT) that gets * passed to eglGetDisplay and eglCreateWindowSurface: */ @@ -55,7 +56,7 @@ typedef struct SDL_VideoData { /* A WinRT DisplayRequest, used for implementing SDL_*ScreenSaver() functions. * This is really a pointer to a 'ABI::Windows::System::Display::IDisplayRequest *', * It's casted to 'IUnknown *', to help with building SDL. - */ + */ IUnknown *displayRequest; } SDL_VideoData; @@ -63,19 +64,19 @@ typedef struct SDL_VideoData { For now, SDL/WinRT only supports one window (due to platform limitations of WinRT. */ -extern SDL_Window * WINRT_GlobalSDLWindow; +extern SDL_Window *WINRT_GlobalSDLWindow; /* Updates one or more SDL_Window flags, by querying the OS' native windowing APIs. SDL_Window flags that can be updated should be specified in 'mask'. */ -extern void WINRT_UpdateWindowFlags(SDL_Window * window, Uint32 mask); -extern "C" Uint32 WINRT_DetectWindowFlags(SDL_Window * window); /* detects flags w/o applying them */ +extern void WINRT_UpdateWindowFlags(SDL_Window *window, Uint32 mask); +extern "C" Uint32 WINRT_DetectWindowFlags(SDL_Window *window); /* detects flags w/o applying them */ /* Display mode internals */ -//typedef struct +// typedef struct //{ -// Windows::Graphics::Display::DisplayOrientations currentOrientation; -//} SDL_DisplayModeData; +// Windows::Graphics::Display::DisplayOrientations currentOrientation; +// } SDL_DisplayModeData; #ifdef __cplusplus_winrt @@ -87,8 +88,8 @@ extern "C" Uint32 WINRT_DetectWindowFlags(SDL_Window * window); /* detects flag #endif /* Converts DIPS to/from physical pixels */ -#define WINRT_DIPS_TO_PHYSICAL_PIXELS(DIPS) ((int)(0.5f + (((float)(DIPS) * (float)WINRT_DISPLAY_PROPERTY(LogicalDpi)) / 96.f))) -#define WINRT_PHYSICAL_PIXELS_TO_DIPS(PHYSPIX) (((float)(PHYSPIX) * 96.f)/WINRT_DISPLAY_PROPERTY(LogicalDpi)) +#define WINRT_DIPS_TO_PHYSICAL_PIXELS(DIPS) ((int)(0.5f + (((float)(DIPS) * (float)WINRT_DISPLAY_PROPERTY(LogicalDpi)) / 96.f))) +#define WINRT_PHYSICAL_PIXELS_TO_DIPS(PHYSPIX) (((float)(PHYSPIX)*96.f) / WINRT_DISPLAY_PROPERTY(LogicalDpi)) /* Internal window data */ struct SDL_WindowData @@ -98,7 +99,7 @@ struct SDL_WindowData #ifdef SDL_VIDEO_OPENGL_EGL EGLSurface egl_surface; #endif -#if SDL_WINRT_USE_APPLICATIONVIEW +#ifdef SDL_WINRT_USE_APPLICATIONVIEW Windows::UI::ViewManagement::ApplicationView ^ appView; #endif }; diff --git a/SDL2-2.0.12/src/video/x11/SDL_x11clipboard.c b/SDL2-2.30.5/src/video/x11/SDL_x11clipboard.c similarity index 50% rename from SDL2-2.0.12/src/video/x11/SDL_x11clipboard.c rename to SDL2-2.30.5/src/video/x11/SDL_x11clipboard.c index d1469c0..cf826a5 100644 --- a/SDL2-2.0.12/src/video/x11/SDL_x11clipboard.c +++ b/SDL2-2.30.5/src/video/x11/SDL_x11clipboard.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,27 +20,19 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_X11 +#ifdef SDL_VIDEO_DRIVER_X11 #include /* For INT_MAX */ #include "SDL_events.h" #include "SDL_x11video.h" #include "SDL_timer.h" - - -/* If you don't support UTF-8, you might use XA_STRING here */ -#ifdef X_HAVE_UTF8_STRING -#define TEXT_FORMAT X11_XInternAtom(display, "UTF8_STRING", False) -#else -#define TEXT_FORMAT XA_STRING -#endif +#include "SDL_x11clipboard.h" /* Get any application owned window handle for clipboard association */ -static Window -GetWindow(_THIS) +static Window GetWindow(_THIS) { - SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; /* We create an unmapped window that exists just to manage the clipboard, since X11 selection data is tied to a specific window and dies with it. @@ -59,21 +51,74 @@ GetWindow(_THIS) return data->clipboard_window; } -/* We use our own cut-buffer for intermediate storage instead of - XA_CUT_BUFFER0 because their use isn't really defined for holding UTF8. */ -Atom -X11_GetSDLCutBufferClipboardType(Display *display) +/* We use our own cut-buffer for intermediate storage instead of + XA_CUT_BUFFER0 because their use isn't really defined for holding UTF8. */ +Atom X11_GetSDLCutBufferClipboardType(Display *display, enum ESDLX11ClipboardMimeType mime_type, + Atom selection_type) { - return X11_XInternAtom(display, "SDL_CUTBUFFER", False); + switch (mime_type) { + case SDL_X11_CLIPBOARD_MIME_TYPE_STRING: + case SDL_X11_CLIPBOARD_MIME_TYPE_TEXT_PLAIN: +#ifdef X_HAVE_UTF8_STRING + case SDL_X11_CLIPBOARD_MIME_TYPE_TEXT_PLAIN_UTF8: +#endif + case SDL_X11_CLIPBOARD_MIME_TYPE_TEXT: + return X11_XInternAtom(display, selection_type == XA_PRIMARY ? "SDL_CUTBUFFER_PRIMARY_SELECTION" : "SDL_CUTBUFFER", + False); + default: + SDL_SetError("Can't find mime_type."); + return XA_STRING; + } } -int -X11_SetClipboardText(_THIS, const char *text) +Atom X11_GetSDLCutBufferClipboardExternalFormat(Display *display, enum ESDLX11ClipboardMimeType mime_type) { - Display *display = ((SDL_VideoData *) _this->driverdata)->display; - Atom format; + switch (mime_type) { + case SDL_X11_CLIPBOARD_MIME_TYPE_STRING: +/* If you don't support UTF-8, you might use XA_STRING here */ +#ifdef X_HAVE_UTF8_STRING + return X11_XInternAtom(display, "UTF8_STRING", False); +#else + return XA_STRING; +#endif + case SDL_X11_CLIPBOARD_MIME_TYPE_TEXT_PLAIN: + return X11_XInternAtom(display, "text/plain", False); +#ifdef X_HAVE_UTF8_STRING + case SDL_X11_CLIPBOARD_MIME_TYPE_TEXT_PLAIN_UTF8: + return X11_XInternAtom(display, "text/plain;charset=utf-8", False); +#endif + case SDL_X11_CLIPBOARD_MIME_TYPE_TEXT: + return X11_XInternAtom(display, "TEXT", False); + default: + SDL_SetError("Can't find mime_type."); + return XA_STRING; + } +} +Atom X11_GetSDLCutBufferClipboardInternalFormat(Display *display, enum ESDLX11ClipboardMimeType mime_type) +{ + switch (mime_type) { + case SDL_X11_CLIPBOARD_MIME_TYPE_STRING: + case SDL_X11_CLIPBOARD_MIME_TYPE_TEXT_PLAIN: +#ifdef X_HAVE_UTF8_STRING + case SDL_X11_CLIPBOARD_MIME_TYPE_TEXT_PLAIN_UTF8: +#endif + case SDL_X11_CLIPBOARD_MIME_TYPE_TEXT: +/* If you don't support UTF-8, you might use XA_STRING here */ +#ifdef X_HAVE_UTF8_STRING + return X11_XInternAtom(display, "UTF8_STRING", False); +#else + return XA_STRING; +#endif + default: + SDL_SetError("Can't find mime_type."); + return XA_STRING; + } +} + +static int SetSelectionText(_THIS, const char *text, Atom selection_type) +{ + Display *display = ((SDL_VideoData *)_this->driverdata)->display; Window window; - Atom XA_CLIPBOARD = X11_XInternAtom(display, "CLIPBOARD", 0); /* Get the SDL window that will own the selection */ window = GetWindow(_this); @@ -82,26 +127,18 @@ X11_SetClipboardText(_THIS, const char *text) } /* Save the selection on the root window */ - format = TEXT_FORMAT; X11_XChangeProperty(display, DefaultRootWindow(display), - X11_GetSDLCutBufferClipboardType(display), format, 8, PropModeReplace, - (const unsigned char *)text, SDL_strlen(text)); + X11_GetSDLCutBufferClipboardType(display, SDL_X11_CLIPBOARD_MIME_TYPE_STRING, selection_type), + X11_GetSDLCutBufferClipboardInternalFormat(display, SDL_X11_CLIPBOARD_MIME_TYPE_STRING), 8, PropModeReplace, + (const unsigned char *)text, SDL_strlen(text)); - if (XA_CLIPBOARD != None && - X11_XGetSelectionOwner(display, XA_CLIPBOARD) != window) { - X11_XSetSelectionOwner(display, XA_CLIPBOARD, window, CurrentTime); - } - - if (X11_XGetSelectionOwner(display, XA_PRIMARY) != window) { - X11_XSetSelectionOwner(display, XA_PRIMARY, window, CurrentTime); - } + X11_XSetSelectionOwner(display, selection_type, window, CurrentTime); return 0; } -char * -X11_GetClipboardText(_THIS) +static char *GetSlectionText(_THIS, Atom selection_type) { - SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; Display *display = videodata->display; Atom format; Window window; @@ -115,18 +152,13 @@ X11_GetClipboardText(_THIS) char *text; Uint32 waitStart; Uint32 waitElapsed; - Atom XA_CLIPBOARD = X11_XInternAtom(display, "CLIPBOARD", 0); - if (XA_CLIPBOARD == None) { - SDL_SetError("Couldn't access X clipboard"); - return SDL_strdup(""); - } text = NULL; /* Get the window that holds the selection */ window = GetWindow(_this); - format = TEXT_FORMAT; - owner = X11_XGetSelectionOwner(display, XA_CLIPBOARD); + format = X11_GetSDLCutBufferClipboardInternalFormat(display, SDL_X11_CLIPBOARD_MIME_TYPE_STRING); + owner = X11_XGetSelectionOwner(display, selection_type); if (owner == None) { /* Fall back to ancient X10 cut-buffers which do not support UTF8 strings*/ owner = DefaultRootWindow(display); @@ -134,13 +166,13 @@ X11_GetClipboardText(_THIS) format = XA_STRING; } else if (owner == window) { owner = DefaultRootWindow(display); - selection = X11_GetSDLCutBufferClipboardType(display); + selection = X11_GetSDLCutBufferClipboardType(display, SDL_X11_CLIPBOARD_MIME_TYPE_STRING, selection_type); } else { /* Request that the selection owner copy the data to our window */ owner = window; selection = X11_XInternAtom(display, "SDL_SELECTION", False); - X11_XConvertSelection(display, XA_CLIPBOARD, format, selection, owner, - CurrentTime); + X11_XConvertSelection(display, selection_type, format, selection, owner, + CurrentTime); /* When using synergy on Linux and when data has been put in the clipboard on the remote (Windows anyway) machine then selection_waiting may never @@ -150,23 +182,22 @@ X11_GetClipboardText(_THIS) while (videodata->selection_waiting) { SDL_PumpEvents(); waitElapsed = SDL_GetTicks() - waitStart; - /* Wait one second for a clipboard response. */ + /* Wait one second for a selection response. */ if (waitElapsed > 1000) { videodata->selection_waiting = SDL_FALSE; - SDL_SetError("Clipboard timeout"); - /* We need to set the clipboard text so that next time we won't + SDL_SetError("Selection timeout"); + /* We need to set the selection text so that next time we won't timeout, otherwise we will hang on every call to this function. */ - X11_SetClipboardText(_this, ""); + SetSelectionText(_this, "", selection_type); return SDL_strdup(""); } } } - if (X11_XGetWindowProperty(display, owner, selection, 0, INT_MAX/4, False, - format, &seln_type, &seln_format, &nbytes, &overflow, &src) - == Success) { + if (X11_XGetWindowProperty(display, owner, selection, 0, INT_MAX / 4, False, + format, &seln_type, &seln_format, &nbytes, &overflow, &src) == Success) { if (seln_type == format) { - text = (char *)SDL_malloc(nbytes+1); + text = (char *)SDL_malloc(nbytes + 1); if (text) { SDL_memcpy(text, src, nbytes); text[nbytes] = '\0'; @@ -182,8 +213,38 @@ X11_GetClipboardText(_THIS) return text; } -SDL_bool -X11_HasClipboardText(_THIS) +int X11_SetClipboardText(_THIS, const char *text) +{ + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + Atom XA_CLIPBOARD = X11_XInternAtom(videodata->display, "CLIPBOARD", 0); + if (XA_CLIPBOARD == None) { + return SDL_SetError("Couldn't access X clipboard"); + } + return SetSelectionText(_this, text, XA_CLIPBOARD); +} + +int X11_SetPrimarySelectionText(_THIS, const char *text) +{ + return SetSelectionText(_this, text, XA_PRIMARY); +} + +char *X11_GetClipboardText(_THIS) +{ + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + Atom XA_CLIPBOARD = X11_XInternAtom(videodata->display, "CLIPBOARD", 0); + if (XA_CLIPBOARD == None) { + SDL_SetError("Couldn't access X clipboard"); + return SDL_strdup(""); + } + return GetSlectionText(_this, XA_CLIPBOARD); +} + +char *X11_GetPrimarySelectionText(_THIS) +{ + return GetSlectionText(_this, XA_PRIMARY); +} + +SDL_bool X11_HasClipboardText(_THIS) { SDL_bool result = SDL_FALSE; char *text = X11_GetClipboardText(_this); @@ -194,6 +255,17 @@ X11_HasClipboardText(_THIS) return result; } +SDL_bool X11_HasPrimarySelectionText(_THIS) +{ + SDL_bool result = SDL_FALSE; + char *text = X11_GetPrimarySelectionText(_this); + if (text) { + result = text[0] != '\0' ? SDL_TRUE : SDL_FALSE; + SDL_free(text); + } + return result; +} + #endif /* SDL_VIDEO_DRIVER_X11 */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/x11/SDL_x11clipboard.h b/SDL2-2.30.5/src/video/x11/SDL_x11clipboard.h similarity index 57% rename from SDL2-2.0.12/src/video/x11/SDL_x11clipboard.h rename to SDL2-2.30.5/src/video/x11/SDL_x11clipboard.h index 87fb827..c9849b7 100644 --- a/SDL2-2.0.12/src/video/x11/SDL_x11clipboard.h +++ b/SDL2-2.30.5/src/video/x11/SDL_x11clipboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,10 +23,26 @@ #ifndef SDL_x11clipboard_h_ #define SDL_x11clipboard_h_ +enum ESDLX11ClipboardMimeType +{ + SDL_X11_CLIPBOARD_MIME_TYPE_STRING, + SDL_X11_CLIPBOARD_MIME_TYPE_TEXT_PLAIN, +#ifdef X_HAVE_UTF8_STRING + SDL_X11_CLIPBOARD_MIME_TYPE_TEXT_PLAIN_UTF8, +#endif + SDL_X11_CLIPBOARD_MIME_TYPE_TEXT, + SDL_X11_CLIPBOARD_MIME_TYPE_MAX +}; + extern int X11_SetClipboardText(_THIS, const char *text); extern char *X11_GetClipboardText(_THIS); extern SDL_bool X11_HasClipboardText(_THIS); -extern Atom X11_GetSDLCutBufferClipboardType(Display *display); +extern int X11_SetPrimarySelectionText(_THIS, const char *text); +extern char *X11_GetPrimarySelectionText(_THIS); +extern SDL_bool X11_HasPrimarySelectionText(_THIS); +extern Atom X11_GetSDLCutBufferClipboardType(Display *display, enum ESDLX11ClipboardMimeType mime_type, Atom selection_type); +extern Atom X11_GetSDLCutBufferClipboardExternalFormat(Display *display, enum ESDLX11ClipboardMimeType mime_type); +extern Atom X11_GetSDLCutBufferClipboardInternalFormat(Display *display, enum ESDLX11ClipboardMimeType mime_type); #endif /* SDL_x11clipboard_h_ */ diff --git a/SDL2-2.0.12/src/video/x11/SDL_x11dyn.c b/SDL2-2.30.5/src/video/x11/SDL_x11dyn.c similarity index 70% rename from SDL2-2.0.12/src/video/x11/SDL_x11dyn.c rename to SDL2-2.30.5/src/video/x11/SDL_x11dyn.c index 777f4bf..7a4f5cc 100644 --- a/SDL2-2.0.12/src/video/x11/SDL_x11dyn.c +++ b/SDL2-2.30.5/src/video/x11/SDL_x11dyn.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_X11 +#ifdef SDL_VIDEO_DRIVER_X11 #define DEBUG_DYNAMIC_X11 0 @@ -47,55 +47,52 @@ typedef struct #ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR NULL #endif -#ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA -#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA NULL -#endif #ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2 #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2 NULL #endif +#ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XFIXES +#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XFIXES NULL +#endif #ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR NULL #endif #ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS NULL #endif -#ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE -#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE NULL -#endif static x11dynlib x11libs[] = { - {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC}, - {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT}, - {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR}, - {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA}, - {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2}, - {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR}, - {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS}, - {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE} + { NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC }, + { NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT }, + { NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR }, + { NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2 }, + { NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XFIXES }, + { NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR }, + { NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS } }; -static void * -X11_GetSym(const char *fnname, int *pHasModule) +static void *X11_GetSym(const char *fnname, int *pHasModule) { int i; void *fn = NULL; for (i = 0; i < SDL_TABLESIZE(x11libs); i++) { - if (x11libs[i].lib != NULL) { + if (x11libs[i].lib) { fn = SDL_LoadFunction(x11libs[i].lib, fnname); - if (fn != NULL) + if (fn) { break; + } } } #if DEBUG_DYNAMIC_X11 - if (fn != NULL) + if (fn) printf("X11: Found '%s' in %s (%p)\n", fnname, x11libs[i].libname, fn); else printf("X11: Symbol '%s' NOT FOUND!\n", fnname); #endif - if (fn == NULL) - *pHasModule = 0; /* kill this module. */ + if (!fn) { + *pHasModule = 0; /* kill this module. */ + } return fn; } @@ -103,7 +100,7 @@ X11_GetSym(const char *fnname, int *pHasModule) #endif /* SDL_VIDEO_DRIVER_X11_DYNAMIC */ /* Define all the function pointers and wrappers... */ -#define SDL_X11_SYM(rc,fn,params,args,ret) SDL_DYNX11FN_##fn X11_##fn = NULL; +#define SDL_X11_SYM(rc, fn, params, args, ret) SDL_DYNX11FN_##fn X11_##fn = NULL; #include "SDL_x11sym.h" /* Annoying varargs entry point... */ @@ -118,17 +115,18 @@ SDL_DYNX11FN_XGetICValues X11_XGetICValues = NULL; static int x11_load_refcount = 0; -void -SDL_X11_UnloadSymbols(void) +void SDL_X11_UnloadSymbols(void) { /* Don't actually unload if more than one module is using the libs... */ if (x11_load_refcount > 0) { if (--x11_load_refcount == 0) { +#ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC int i; +#endif /* set all the function pointers to NULL. */ -#define SDL_X11_MODULE(modname) SDL_X11_HAVE_##modname = 0; -#define SDL_X11_SYM(rc,fn,params,args,ret) X11_##fn = NULL; +#define SDL_X11_MODULE(modname) SDL_X11_HAVE_##modname = 0; +#define SDL_X11_SYM(rc, fn, params, args, ret) X11_##fn = NULL; #include "SDL_x11sym.h" #ifdef X_HAVE_UTF8_STRING @@ -138,7 +136,7 @@ SDL_X11_UnloadSymbols(void) #ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC for (i = 0; i < SDL_TABLESIZE(x11libs); i++) { - if (x11libs[i].lib != NULL) { + if (x11libs[i].lib) { SDL_UnloadObject(x11libs[i].lib); x11libs[i].lib = NULL; } @@ -149,10 +147,9 @@ SDL_X11_UnloadSymbols(void) } /* returns non-zero if all needed symbols were loaded. */ -int -SDL_X11_LoadSymbols(void) +int SDL_X11_LoadSymbols(void) { - int rc = 1; /* always succeed if not using Dynamic X11 stuff. */ + int rc = 1; /* always succeed if not using Dynamic X11 stuff. */ /* deal with multiple modules (dga, x11, etc) needing these symbols... */ if (x11_load_refcount++ == 0) { @@ -160,7 +157,7 @@ SDL_X11_LoadSymbols(void) int i; int *thismod = NULL; for (i = 0; i < SDL_TABLESIZE(x11libs); i++) { - if (x11libs[i].libname != NULL) { + if (x11libs[i].libname) { x11libs[i].lib = SDL_LoadObject(x11libs[i].libname); } } @@ -168,15 +165,15 @@ SDL_X11_LoadSymbols(void) #define SDL_X11_MODULE(modname) SDL_X11_HAVE_##modname = 1; /* default yes */ #include "SDL_x11sym.h" -#define SDL_X11_MODULE(modname) thismod = &SDL_X11_HAVE_##modname; -#define SDL_X11_SYM(a,fn,x,y,z) X11_##fn = (SDL_DYNX11FN_##fn) X11_GetSym(#fn,thismod); +#define SDL_X11_MODULE(modname) thismod = &SDL_X11_HAVE_##modname; +#define SDL_X11_SYM(a, fn, x, y, z) X11_##fn = (SDL_DYNX11FN_##fn)X11_GetSym(#fn, thismod); #include "SDL_x11sym.h" #ifdef X_HAVE_UTF8_STRING X11_XCreateIC = (SDL_DYNX11FN_XCreateIC) - X11_GetSym("XCreateIC", &SDL_X11_HAVE_UTF8); + X11_GetSym("XCreateIC", &SDL_X11_HAVE_UTF8); X11_XGetICValues = (SDL_DYNX11FN_XGetICValues) - X11_GetSym("XGetICValues", &SDL_X11_HAVE_UTF8); + X11_GetSym("XGetICValues", &SDL_X11_HAVE_UTF8); #endif if (SDL_X11_HAVE_BASEXLIB) { @@ -188,10 +185,10 @@ SDL_X11_LoadSymbols(void) rc = 0; } -#else /* no dynamic X11 */ +#else /* no dynamic X11 */ -#define SDL_X11_MODULE(modname) SDL_X11_HAVE_##modname = 1; /* default yes */ -#define SDL_X11_SYM(a,fn,x,y,z) X11_##fn = (SDL_DYNX11FN_##fn) fn; +#define SDL_X11_MODULE(modname) SDL_X11_HAVE_##modname = 1; /* default yes */ +#define SDL_X11_SYM(a, fn, x, y, z) X11_##fn = (SDL_DYNX11FN_##fn)fn; #include "SDL_x11sym.h" #ifdef X_HAVE_UTF8_STRING diff --git a/SDL2-2.0.12/src/video/x11/SDL_x11dyn.h b/SDL2-2.30.5/src/video/x11/SDL_x11dyn.h similarity index 71% rename from SDL2-2.0.12/src/video/x11/SDL_x11dyn.h rename to SDL2-2.30.5/src/video/x11/SDL_x11dyn.h index ecdf764..5a78ad0 100644 --- a/SDL2-2.0.12/src/video/x11/SDL_x11dyn.h +++ b/SDL2-2.30.5/src/video/x11/SDL_x11dyn.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -27,7 +27,7 @@ #include #include -#if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM +#ifdef SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM #include #endif @@ -39,7 +39,6 @@ #include #include -#include #ifndef NO_SHARED_MEMORY #include @@ -47,54 +46,50 @@ #include #endif -#if SDL_VIDEO_DRIVER_X11_XCURSOR +#ifdef SDL_VIDEO_DRIVER_X11_XCURSOR #include #endif -#if SDL_VIDEO_DRIVER_X11_XDBE +#ifdef SDL_VIDEO_DRIVER_X11_XDBE #include #endif -#if SDL_VIDEO_DRIVER_X11_XINERAMA -#include -#endif -#if SDL_VIDEO_DRIVER_X11_XINPUT2 +#if defined(SDL_VIDEO_DRIVER_X11_XINPUT2) || defined(SDL_VIDEO_DRIVER_X11_XFIXES) #include #endif -#if SDL_VIDEO_DRIVER_X11_XRANDR +#ifdef SDL_VIDEO_DRIVER_X11_XFIXES +#include +#endif +#ifdef SDL_VIDEO_DRIVER_X11_XRANDR #include #endif -#if SDL_VIDEO_DRIVER_X11_XSCRNSAVER +#ifdef SDL_VIDEO_DRIVER_X11_XSCRNSAVER #include #endif -#if SDL_VIDEO_DRIVER_X11_XSHAPE +#ifdef SDL_VIDEO_DRIVER_X11_XSHAPE #include #endif -#if SDL_VIDEO_DRIVER_X11_XVIDMODE -#include -#endif #ifdef __cplusplus -extern "C" -{ +extern "C" { #endif /* evil function signatures... */ -typedef Bool(*SDL_X11_XESetWireToEventRetType) (Display *, XEvent *, xEvent *); -typedef int (*SDL_X11_XSynchronizeRetType) (Display *); -typedef Status(*SDL_X11_XESetEventToWireRetType) (Display *, XEvent *, xEvent *); +typedef Bool (*SDL_X11_XESetWireToEventRetType)(Display *, XEvent *, xEvent *); +typedef int (*SDL_X11_XSynchronizeRetType)(Display *); +typedef Status (*SDL_X11_XESetEventToWireRetType)(Display *, XEvent *, xEvent *); int SDL_X11_LoadSymbols(void); void SDL_X11_UnloadSymbols(void); /* Declare all the function pointers and wrappers... */ -#define SDL_X11_SYM(rc,fn,params,args,ret) \ - typedef rc (*SDL_DYNX11FN_##fn) params; \ +#define SDL_X11_SYM(rc, fn, params, args, ret) \ + typedef rc(*SDL_DYNX11FN_##fn) params; \ extern SDL_DYNX11FN_##fn X11_##fn; #include "SDL_x11sym.h" /* Annoying varargs entry point... */ #ifdef X_HAVE_UTF8_STRING -typedef XIC(*SDL_DYNX11FN_XCreateIC) (XIM,...); -typedef char *(*SDL_DYNX11FN_XGetICValues) (XIC, ...); +typedef XIC (*SDL_DYNX11FN_XCreateIC)(XIM, ...); +typedef char *(*SDL_DYNX11FN_XGetICValues)(XIC, ...); extern SDL_DYNX11FN_XCreateIC X11_XCreateIC; extern SDL_DYNX11FN_XGetICValues X11_XGetICValues; #endif @@ -107,5 +102,5 @@ extern SDL_DYNX11FN_XGetICValues X11_XGetICValues; } #endif -#endif /* !defined SDL_x11dyn_h_ */ +#endif /* !defined SDL_x11dyn_h_ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/x11/SDL_x11events.c b/SDL2-2.30.5/src/video/x11/SDL_x11events.c new file mode 100644 index 0000000..21b66ff --- /dev/null +++ b/SDL2-2.30.5/src/video/x11/SDL_x11events.c @@ -0,0 +1,1811 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_X11 + +#include +#include +#include +#include +#include /* For INT_MAX */ + +#include "SDL_x11video.h" +#include "SDL_x11touch.h" +#include "SDL_x11xinput2.h" +#include "SDL_x11xfixes.h" +#include "../../core/unix/SDL_poll.h" +#include "../../events/SDL_events_c.h" +#include "../../events/SDL_mouse_c.h" +#include "../../events/SDL_touch_c.h" +#include "../../SDL_utils_c.h" + +#include "SDL_hints.h" +#include "SDL_timer.h" +#include "SDL_syswm.h" + +#include + +/*#define DEBUG_XEVENTS*/ + +#ifndef _NET_WM_MOVERESIZE_SIZE_TOPLEFT +#define _NET_WM_MOVERESIZE_SIZE_TOPLEFT 0 +#endif + +#ifndef _NET_WM_MOVERESIZE_SIZE_TOP +#define _NET_WM_MOVERESIZE_SIZE_TOP 1 +#endif + +#ifndef _NET_WM_MOVERESIZE_SIZE_TOPRIGHT +#define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT 2 +#endif + +#ifndef _NET_WM_MOVERESIZE_SIZE_RIGHT +#define _NET_WM_MOVERESIZE_SIZE_RIGHT 3 +#endif + +#ifndef _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT +#define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT 4 +#endif + +#ifndef _NET_WM_MOVERESIZE_SIZE_BOTTOM +#define _NET_WM_MOVERESIZE_SIZE_BOTTOM 5 +#endif + +#ifndef _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT +#define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT 6 +#endif + +#ifndef _NET_WM_MOVERESIZE_SIZE_LEFT +#define _NET_WM_MOVERESIZE_SIZE_LEFT 7 +#endif + +#ifndef _NET_WM_MOVERESIZE_MOVE +#define _NET_WM_MOVERESIZE_MOVE 8 +#endif + +typedef struct +{ + unsigned char *data; + int format, count; + Atom type; +} SDL_x11Prop; + +/* Reads property + Must call X11_XFree on results + */ +static void X11_ReadProperty(SDL_x11Prop *p, Display *disp, Window w, Atom prop) +{ + unsigned char *ret = NULL; + Atom type; + int fmt; + unsigned long count; + unsigned long bytes_left; + int bytes_fetch = 0; + + do { + if (ret) { + X11_XFree(ret); + } + X11_XGetWindowProperty(disp, w, prop, 0, bytes_fetch, False, AnyPropertyType, &type, &fmt, &count, &bytes_left, &ret); + bytes_fetch += bytes_left; + } while (bytes_left != 0); + + p->data = ret; + p->format = fmt; + p->count = count; + p->type = type; +} + +/* Find text-uri-list in a list of targets and return it's atom + if available, else return None */ +static Atom X11_PickTarget(Display *disp, Atom list[], int list_count) +{ + Atom request = None; + char *name; + int i; + for (i = 0; i < list_count && request == None; i++) { + name = X11_XGetAtomName(disp, list[i]); + if ((SDL_strcmp("text/uri-list", name) == 0) || (SDL_strcmp("text/plain", name) == 0)) { + request = list[i]; + } + X11_XFree(name); + } + return request; +} + +/* Wrapper for X11_PickTarget for a maximum of three targets, a special + case in the Xdnd protocol */ +static Atom X11_PickTargetFromAtoms(Display *disp, Atom a0, Atom a1, Atom a2) +{ + int count = 0; + Atom atom[3]; + if (a0 != None) { + atom[count++] = a0; + } + if (a1 != None) { + atom[count++] = a1; + } + if (a2 != None) { + atom[count++] = a2; + } + return X11_PickTarget(disp, atom, count); +} + +struct KeyRepeatCheckData +{ + XEvent *event; + SDL_bool found; +}; + +static Bool X11_KeyRepeatCheckIfEvent(Display *display, XEvent *chkev, + XPointer arg) +{ + struct KeyRepeatCheckData *d = (struct KeyRepeatCheckData *)arg; + if (chkev->type == KeyPress && chkev->xkey.keycode == d->event->xkey.keycode && chkev->xkey.time - d->event->xkey.time < 2) { + d->found = SDL_TRUE; + } + return False; +} + +/* Check to see if this is a repeated key. + (idea shamelessly lifted from GII -- thanks guys! :) + */ +static SDL_bool X11_KeyRepeat(Display *display, XEvent *event) +{ + XEvent dummyev; + struct KeyRepeatCheckData d; + d.event = event; + d.found = SDL_FALSE; + if (X11_XPending(display)) { + X11_XCheckIfEvent(display, &dummyev, X11_KeyRepeatCheckIfEvent, (XPointer)&d); + } + return d.found; +} + +static SDL_bool X11_IsWheelEvent(Display *display, XEvent *event, int *xticks, int *yticks) +{ + /* according to the xlib docs, no specific mouse wheel events exist. + However, the defacto standard is that the vertical wheel is X buttons + 4 (up) and 5 (down) and a horizontal wheel is 6 (left) and 7 (right). */ + + /* Xlib defines "Button1" through 5, so we just use literals here. */ + switch (event->xbutton.button) { + case 4: + *yticks = 1; + return SDL_TRUE; + case 5: + *yticks = -1; + return SDL_TRUE; + case 6: + *xticks = 1; + return SDL_TRUE; + case 7: + *xticks = -1; + return SDL_TRUE; + default: + break; + } + return SDL_FALSE; +} + +/* Decodes URI escape sequences in string buf of len bytes + (excluding the terminating NULL byte) in-place. Since + URI-encoded characters take three times the space of + normal characters, this should not be an issue. + + Returns the number of decoded bytes that wound up in + the buffer, excluding the terminating NULL byte. + + The buffer is guaranteed to be NULL-terminated but + may contain embedded NULL bytes. + + On error, -1 is returned. + */ +static int X11_URIDecode(char *buf, int len) +{ + int ri, wi, di; + char decode = '\0'; + if (!buf || len < 0) { + errno = EINVAL; + return -1; + } + if (len == 0) { + len = SDL_strlen(buf); + } + for (ri = 0, wi = 0, di = 0; ri < len && wi < len; ri += 1) { + if (di == 0) { + /* start decoding */ + if (buf[ri] == '%') { + decode = '\0'; + di += 1; + continue; + } + /* normal write */ + buf[wi] = buf[ri]; + wi += 1; + continue; + } else if (di == 1 || di == 2) { + char off = '\0'; + char isa = buf[ri] >= 'a' && buf[ri] <= 'f'; + char isA = buf[ri] >= 'A' && buf[ri] <= 'F'; + char isn = buf[ri] >= '0' && buf[ri] <= '9'; + if (!(isa || isA || isn)) { + /* not a hexadecimal */ + int sri; + for (sri = ri - di; sri <= ri; sri += 1) { + buf[wi] = buf[sri]; + wi += 1; + } + di = 0; + continue; + } + /* itsy bitsy magicsy */ + if (isn) { + off = 0 - '0'; + } else if (isa) { + off = 10 - 'a'; + } else if (isA) { + off = 10 - 'A'; + } + decode |= (buf[ri] + off) << (2 - di) * 4; + if (di == 2) { + buf[wi] = decode; + wi += 1; + di = 0; + } else { + di += 1; + } + continue; + } + } + buf[wi] = '\0'; + return wi; +} + +/* Convert URI to local filename + return filename if possible, else NULL +*/ +static char *X11_URIToLocal(char *uri) +{ + char *file = NULL; + SDL_bool local; + + if (SDL_memcmp(uri, "file:/", 6) == 0) { + uri += 6; /* local file? */ + } else if (SDL_strstr(uri, ":/") != NULL) { + return file; /* wrong scheme */ + } + + local = uri[0] != '/' || (uri[0] != '\0' && uri[1] == '/'); + + /* got a hostname? */ + if (!local && uri[0] == '/' && uri[2] != '/') { + char *hostname_end = SDL_strchr(uri + 1, '/'); + if (hostname_end) { + char hostname[257]; + if (gethostname(hostname, 255) == 0) { + hostname[256] = '\0'; + if (SDL_memcmp(uri + 1, hostname, hostname_end - (uri + 1)) == 0) { + uri = hostname_end + 1; + local = SDL_TRUE; + } + } + } + } + if (local) { + file = uri; + /* Convert URI escape sequences to real characters */ + X11_URIDecode(file, 0); + if (uri[1] == '/') { + file++; + } else { + file--; + } + } + return file; +} + +#ifdef SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS +static void X11_HandleGenericEvent(SDL_VideoData *videodata, XEvent *xev) +{ + /* event is a union, so cookie == &event, but this is type safe. */ + XGenericEventCookie *cookie = &xev->xcookie; + if (X11_XGetEventData(videodata->display, cookie)) { + X11_HandleXinput2Event(videodata, cookie); + + /* Send a SDL_SYSWMEVENT if the application wants them. + * Since event data is only available until XFreeEventData is called, + * the *only* way for an application to access it is to register an event filter/watcher + * and do all the processing on the SDL_SYSWMEVENT inside the callback. */ + if (SDL_GetEventState(SDL_SYSWMEVENT) == SDL_ENABLE) { + SDL_SysWMmsg wmmsg; + + SDL_VERSION(&wmmsg.version); + wmmsg.subsystem = SDL_SYSWM_X11; + wmmsg.msg.x11.event = *xev; + SDL_SendSysWMEvent(&wmmsg); + } + + X11_XFreeEventData(videodata->display, cookie); + } +} +#endif /* SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS */ + +static unsigned X11_GetNumLockModifierMask(_THIS) +{ + SDL_VideoData *viddata = (SDL_VideoData *)_this->driverdata; + Display *display = viddata->display; + unsigned num_mask = 0; + int i, j; + XModifierKeymap *xmods; + unsigned n; + + xmods = X11_XGetModifierMapping(display); + n = xmods->max_keypermod; + for (i = 3; i < 8; i++) { + for (j = 0; j < n; j++) { + KeyCode kc = xmods->modifiermap[i * n + j]; + if (viddata->key_layout[kc] == SDL_SCANCODE_NUMLOCKCLEAR) { + num_mask = 1 << i; + break; + } + } + } + X11_XFreeModifiermap(xmods); + + return num_mask; +} + +static unsigned X11_GetScrollLockModifierMask(_THIS) +{ + SDL_VideoData *viddata = (SDL_VideoData *)_this->driverdata; + Display *display = viddata->display; + unsigned num_mask = 0; + int i, j; + XModifierKeymap *xmods; + unsigned n; + + xmods = X11_XGetModifierMapping(display); + n = xmods->max_keypermod; + for (i = 3; i < 8; i++) { + for (j = 0; j < n; j++) { + KeyCode kc = xmods->modifiermap[i * n + j]; + if (viddata->key_layout[kc] == SDL_SCANCODE_SCROLLLOCK) { + num_mask = 1 << i; + break; + } + } + } + X11_XFreeModifiermap(xmods); + + return num_mask; +} + +void X11_ReconcileKeyboardState(_THIS) +{ + SDL_VideoData *viddata = (SDL_VideoData *)_this->driverdata; + Display *display = viddata->display; + char keys[32]; + int keycode; + Window junk_window; + int x, y; + unsigned int mask; + const Uint8 *keyboardState; + + X11_XQueryKeymap(display, keys); + + /* Sync up the keyboard modifier state */ + if (X11_XQueryPointer(display, DefaultRootWindow(display), &junk_window, &junk_window, &x, &y, &x, &y, &mask)) { + SDL_ToggleModState(KMOD_CAPS, (mask & LockMask) ? SDL_TRUE : SDL_FALSE); + SDL_ToggleModState(KMOD_NUM, (mask & X11_GetNumLockModifierMask(_this)) ? SDL_TRUE : SDL_FALSE); + SDL_ToggleModState(KMOD_SCROLL, (mask & X11_GetScrollLockModifierMask(_this)) ? SDL_TRUE : SDL_FALSE); + } + + keyboardState = SDL_GetKeyboardState(0); + for (keycode = 0; keycode < SDL_arraysize(viddata->key_layout); ++keycode) { + SDL_Scancode scancode = viddata->key_layout[keycode]; + SDL_bool x11KeyPressed = (keys[keycode / 8] & (1 << (keycode % 8))) != 0; + SDL_bool sdlKeyPressed = keyboardState[scancode] == SDL_PRESSED; + + if (x11KeyPressed && !sdlKeyPressed) { + /* Only update modifier state for keys that are pressed in another application */ + switch (SDL_GetKeyFromScancode(scancode)) { + case SDLK_LCTRL: + case SDLK_RCTRL: + case SDLK_LSHIFT: + case SDLK_RSHIFT: + case SDLK_LALT: + case SDLK_RALT: + case SDLK_LGUI: + case SDLK_RGUI: + case SDLK_MODE: + SDL_SendKeyboardKey(SDL_PRESSED, scancode); + break; + default: + break; + } + } else if (!x11KeyPressed && sdlKeyPressed) { + SDL_SendKeyboardKey(SDL_RELEASED, scancode); + } + } +} + +static void X11_DispatchFocusIn(_THIS, SDL_WindowData *data) +{ +#ifdef DEBUG_XEVENTS + printf("window %p: Dispatching FocusIn\n", data); +#endif + SDL_SetKeyboardFocus(data->window); + X11_ReconcileKeyboardState(_this); +#ifdef X_HAVE_UTF8_STRING + if (data->ic) { + X11_XSetICFocus(data->ic); + } +#endif +#ifdef SDL_USE_IME + SDL_IME_SetFocus(SDL_TRUE); +#endif + if (data->flashing_window) { + X11_FlashWindow(_this, data->window, SDL_FLASH_CANCEL); + } +} + +static void X11_DispatchFocusOut(_THIS, SDL_WindowData *data) +{ +#ifdef DEBUG_XEVENTS + printf("window %p: Dispatching FocusOut\n", data); +#endif + /* If another window has already processed a focus in, then don't try to + * remove focus here. Doing so will incorrectly remove focus from that + * window, and the focus lost event for this window will have already + * been dispatched anyway. */ + if (data->window == SDL_GetKeyboardFocus()) { + SDL_SetKeyboardFocus(NULL); + } +#ifdef X_HAVE_UTF8_STRING + if (data->ic) { + X11_XUnsetICFocus(data->ic); + } +#endif +#ifdef SDL_USE_IME + SDL_IME_SetFocus(SDL_FALSE); +#endif +} + +static void X11_DispatchMapNotify(SDL_WindowData *data) +{ + SDL_Window *window = data->window; + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESTORED, 0, 0); + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SHOWN, 0, 0); + if (!(window->flags & SDL_WINDOW_HIDDEN) && (window->flags & SDL_WINDOW_INPUT_FOCUS)) { + SDL_UpdateWindowGrab(window); + } +} + +static void X11_DispatchUnmapNotify(SDL_WindowData *data) +{ + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_HIDDEN, 0, 0); + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_MINIMIZED, 0, 0); +} + +static void InitiateWindowMove(_THIS, const SDL_WindowData *data, const SDL_Point *point) +{ + SDL_VideoData *viddata = (SDL_VideoData *)_this->driverdata; + SDL_Window *window = data->window; + Display *display = viddata->display; + XEvent evt; + + /* !!! FIXME: we need to regrab this if necessary when the drag is done. */ + X11_XUngrabPointer(display, 0L); + X11_XFlush(display); + + evt.xclient.type = ClientMessage; + evt.xclient.window = data->xwindow; + evt.xclient.message_type = X11_XInternAtom(display, "_NET_WM_MOVERESIZE", True); + evt.xclient.format = 32; + evt.xclient.data.l[0] = (size_t)window->x + point->x; + evt.xclient.data.l[1] = (size_t)window->y + point->y; + evt.xclient.data.l[2] = _NET_WM_MOVERESIZE_MOVE; + evt.xclient.data.l[3] = Button1; + evt.xclient.data.l[4] = 0; + X11_XSendEvent(display, DefaultRootWindow(display), False, SubstructureRedirectMask | SubstructureNotifyMask, &evt); + + X11_XSync(display, 0); +} + +static void InitiateWindowResize(_THIS, const SDL_WindowData *data, const SDL_Point *point, int direction) +{ + SDL_VideoData *viddata = (SDL_VideoData *)_this->driverdata; + SDL_Window *window = data->window; + Display *display = viddata->display; + XEvent evt; + + if (direction < _NET_WM_MOVERESIZE_SIZE_TOPLEFT || direction > _NET_WM_MOVERESIZE_SIZE_LEFT) { + return; + } + + /* !!! FIXME: we need to regrab this if necessary when the drag is done. */ + X11_XUngrabPointer(display, 0L); + X11_XFlush(display); + + evt.xclient.type = ClientMessage; + evt.xclient.window = data->xwindow; + evt.xclient.message_type = X11_XInternAtom(display, "_NET_WM_MOVERESIZE", True); + evt.xclient.format = 32; + evt.xclient.data.l[0] = (size_t)window->x + point->x; + evt.xclient.data.l[1] = (size_t)window->y + point->y; + evt.xclient.data.l[2] = direction; + evt.xclient.data.l[3] = Button1; + evt.xclient.data.l[4] = 0; + X11_XSendEvent(display, DefaultRootWindow(display), False, SubstructureRedirectMask | SubstructureNotifyMask, &evt); + + X11_XSync(display, 0); +} + +static SDL_bool ProcessHitTest(_THIS, const SDL_WindowData *data, const XEvent *xev) +{ + SDL_Window *window = data->window; + + if (window->hit_test) { + const SDL_Point point = { xev->xbutton.x, xev->xbutton.y }; + const SDL_HitTestResult rc = window->hit_test(window, &point, window->hit_test_data); + static const int directions[] = { + _NET_WM_MOVERESIZE_SIZE_TOPLEFT, _NET_WM_MOVERESIZE_SIZE_TOP, + _NET_WM_MOVERESIZE_SIZE_TOPRIGHT, _NET_WM_MOVERESIZE_SIZE_RIGHT, + _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT, _NET_WM_MOVERESIZE_SIZE_BOTTOM, + _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT, _NET_WM_MOVERESIZE_SIZE_LEFT + }; + + switch (rc) { + case SDL_HITTEST_DRAGGABLE: + InitiateWindowMove(_this, data, &point); + return SDL_TRUE; + + case SDL_HITTEST_RESIZE_TOPLEFT: + case SDL_HITTEST_RESIZE_TOP: + case SDL_HITTEST_RESIZE_TOPRIGHT: + case SDL_HITTEST_RESIZE_RIGHT: + case SDL_HITTEST_RESIZE_BOTTOMRIGHT: + case SDL_HITTEST_RESIZE_BOTTOM: + case SDL_HITTEST_RESIZE_BOTTOMLEFT: + case SDL_HITTEST_RESIZE_LEFT: + InitiateWindowResize(_this, data, &point, directions[rc - SDL_HITTEST_RESIZE_TOPLEFT]); + return SDL_TRUE; + + default: + return SDL_FALSE; + } + } + + return SDL_FALSE; +} + +static void X11_UpdateUserTime(SDL_WindowData *data, const unsigned long latest) +{ + if (latest && (latest != data->user_time)) { + SDL_VideoData *videodata = data->videodata; + Display *display = videodata->display; + X11_XChangeProperty(display, data->xwindow, videodata->_NET_WM_USER_TIME, + XA_CARDINAL, 32, PropModeReplace, + (const unsigned char *)&latest, 1); +#ifdef DEBUG_XEVENTS + printf("window %p: updating _NET_WM_USER_TIME to %lu\n", data, latest); +#endif + data->user_time = latest; + } +} + +static void X11_HandleClipboardEvent(_THIS, const XEvent *xevent) +{ + int i; + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + Display *display = videodata->display; + + SDL_assert(videodata->clipboard_window != None); + SDL_assert(xevent->xany.window == videodata->clipboard_window); + + switch (xevent->type) { + /* Copy the selection from our own CUTBUFFER to the requested property */ + case SelectionRequest: + { + const XSelectionRequestEvent *req = &xevent->xselectionrequest; + XEvent sevent; + int seln_format, mime_formats; + unsigned long nbytes; + unsigned long overflow; + unsigned char *seln_data; + Atom supportedFormats[SDL_X11_CLIPBOARD_MIME_TYPE_MAX + 1]; + Atom XA_TARGETS = X11_XInternAtom(display, "TARGETS", 0); + +#ifdef DEBUG_XEVENTS + printf("window CLIPBOARD: SelectionRequest (requestor = %ld, target = %ld)\n", + req->requestor, req->target); +#endif + + SDL_zero(sevent); + sevent.xany.type = SelectionNotify; + sevent.xselection.selection = req->selection; + sevent.xselection.target = None; + sevent.xselection.property = None; /* tell them no by default */ + sevent.xselection.requestor = req->requestor; + sevent.xselection.time = req->time; + + /* !!! FIXME: We were probably storing this on the root window + because an SDL window might go away...? but we don't have to do + this now (or ever, really). */ + + if (req->target == XA_TARGETS) { + supportedFormats[0] = XA_TARGETS; + mime_formats = 1; + for (i = 0; i < SDL_X11_CLIPBOARD_MIME_TYPE_MAX; ++i) { + supportedFormats[mime_formats++] = X11_GetSDLCutBufferClipboardExternalFormat(display, i); + } + X11_XChangeProperty(display, req->requestor, req->property, + XA_ATOM, 32, PropModeReplace, + (unsigned char *)supportedFormats, + mime_formats); + sevent.xselection.property = req->property; + sevent.xselection.target = XA_TARGETS; + } else { + for (i = 0; i < SDL_X11_CLIPBOARD_MIME_TYPE_MAX; ++i) { + if (X11_GetSDLCutBufferClipboardExternalFormat(display, i) != req->target) { + continue; + } + if (X11_XGetWindowProperty(display, DefaultRootWindow(display), + X11_GetSDLCutBufferClipboardType(display, i, req->selection), 0, INT_MAX / 4, False, X11_GetSDLCutBufferClipboardInternalFormat(display, i), + &sevent.xselection.target, &seln_format, &nbytes, + &overflow, &seln_data) == Success) { + if (seln_format != None) { + X11_XChangeProperty(display, req->requestor, req->property, + sevent.xselection.target, seln_format, PropModeReplace, + seln_data, nbytes); + sevent.xselection.property = req->property; + X11_XFree(seln_data); + break; + } else { + X11_XFree(seln_data); + } + } + } + } + X11_XSendEvent(display, req->requestor, False, 0, &sevent); + X11_XSync(display, False); + } break; + + case SelectionNotify: + { +#ifdef DEBUG_XEVENTS + printf("window CLIPBOARD: SelectionNotify (requestor = %ld, target = %ld)\n", + xevent->xselection.requestor, xevent->xselection.target); +#endif + videodata->selection_waiting = SDL_FALSE; + } break; + + case SelectionClear: + { + /* !!! FIXME: cache atoms */ + Atom XA_CLIPBOARD = X11_XInternAtom(display, "CLIPBOARD", 0); + +#ifdef DEBUG_XEVENTS + printf("window CLIPBOARD: SelectionClear (requestor = %ld, target = %ld)\n", + xevent->xselection.requestor, xevent->xselection.target); +#endif + + if (xevent->xselectionclear.selection == XA_PRIMARY || + (XA_CLIPBOARD != None && xevent->xselectionclear.selection == XA_CLIPBOARD)) { + SDL_SendClipboardUpdate(); + } + } break; + } +} + +static Bool isMapNotify(Display *display, XEvent *ev, XPointer arg) +{ + XUnmapEvent *unmap; + + unmap = (XUnmapEvent *)arg; + + return ev->type == MapNotify && + ev->xmap.window == unmap->window && + ev->xmap.serial == unmap->serial; +} + +static Bool isReparentNotify(Display *display, XEvent *ev, XPointer arg) +{ + XUnmapEvent *unmap; + + unmap = (XUnmapEvent *)arg; + + return ev->type == ReparentNotify && + ev->xreparent.window == unmap->window && + ev->xreparent.serial == unmap->serial; +} + +static SDL_bool IsHighLatin1(const char *string, int length) +{ + while (length-- > 0) { + Uint8 ch = (Uint8)*string; + if (ch >= 0x80) { + return SDL_TRUE; + } + ++string; + } + return SDL_FALSE; +} + +static int XLookupStringAsUTF8(XKeyEvent *event_struct, char *buffer_return, int bytes_buffer, KeySym *keysym_return, XComposeStatus *status_in_out) +{ + int result = X11_XLookupString(event_struct, buffer_return, bytes_buffer, keysym_return, status_in_out); + if (IsHighLatin1(buffer_return, result)) { + char *utf8_text = SDL_iconv_string("UTF-8", "ISO-8859-1", buffer_return, result + 1); + if (utf8_text) { + SDL_strlcpy(buffer_return, utf8_text, bytes_buffer); + SDL_free(utf8_text); + return SDL_strlen(buffer_return); + } else { + return 0; + } + } + return result; +} + +void X11_GetBorderValues(void /* SDL_WindowData */ *data_) +{ + SDL_WindowData *data = (SDL_WindowData *)data_; + SDL_VideoData *videodata = data->videodata; + Display *display = videodata->display; + + Atom type; + int format; + unsigned long nitems, bytes_after; + unsigned char *property; + if (X11_XGetWindowProperty(display, data->xwindow, videodata->_NET_FRAME_EXTENTS, 0, 16, 0, XA_CARDINAL, &type, &format, &nitems, &bytes_after, &property) == Success) { + if (type != None && nitems == 4) { + data->border_left = (int)((long *)property)[0]; + data->border_right = (int)((long *)property)[1]; + data->border_top = (int)((long *)property)[2]; + data->border_bottom = (int)((long *)property)[3]; + } + X11_XFree(property); + +#ifdef DEBUG_XEVENTS + printf("New _NET_FRAME_EXTENTS: left=%d right=%d, top=%d, bottom=%d\n", data->border_left, data->border_right, data->border_top, data->border_bottom); +#endif + } +} + +static void X11_DispatchEvent(_THIS, XEvent *xevent) +{ + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + Display *display; + SDL_WindowData *data; + int orig_event_type; + KeyCode orig_keycode; + XClientMessageEvent m; + int i; + + SDL_assert(videodata != NULL); + display = videodata->display; + + /* Save the original keycode for dead keys, which are filtered out by + the XFilterEvent() call below. + */ + orig_event_type = xevent->type; + if (orig_event_type == KeyPress || orig_event_type == KeyRelease) { + orig_keycode = xevent->xkey.keycode; + } else { + orig_keycode = 0; + } + + /* filter events catchs XIM events and sends them to the correct handler */ + if (X11_XFilterEvent(xevent, None) == True) { +#if 0 + printf("Filtered event type = %d display = %d window = %d\n", + xevent->type, xevent->xany.display, xevent->xany.window); +#endif + /* Make sure dead key press/release events are sent */ + /* But only if we're using one of the DBus IMEs, otherwise + some XIM IMEs will generate duplicate events */ + if (orig_keycode) { +#if defined(HAVE_IBUS_IBUS_H) || defined(HAVE_FCITX) + SDL_Scancode scancode = videodata->key_layout[orig_keycode]; + videodata->filter_code = orig_keycode; + videodata->filter_time = xevent->xkey.time; + + if (orig_event_type == KeyPress) { + SDL_SendKeyboardKey(SDL_PRESSED, scancode); + } else { + SDL_SendKeyboardKey(SDL_RELEASED, scancode); + } +#endif + } + return; + } + +#ifdef SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS + if (xevent->type == GenericEvent) { + X11_HandleGenericEvent(videodata, xevent); + return; + } +#endif + +#ifdef SDL_VIDEO_DRIVER_X11_XRANDR + if (videodata->xrandr_event_base && (xevent->type == (videodata->xrandr_event_base + RRNotify))) { + X11_HandleXRandREvent(_this, xevent); + } +#endif + + /* Send a SDL_SYSWMEVENT if the application wants them */ + if (SDL_GetEventState(SDL_SYSWMEVENT) == SDL_ENABLE) { + SDL_SysWMmsg wmmsg; + + SDL_VERSION(&wmmsg.version); + wmmsg.subsystem = SDL_SYSWM_X11; + wmmsg.msg.x11.event = *xevent; + SDL_SendSysWMEvent(&wmmsg); + } + +#if 0 + printf("type = %d display = %d window = %d\n", + xevent->type, xevent->xany.display, xevent->xany.window); +#endif + +#ifdef SDL_VIDEO_DRIVER_X11_XFIXES + if (SDL_X11_HAVE_XFIXES && + xevent->type == X11_GetXFixesSelectionNotifyEvent()) { + XFixesSelectionNotifyEvent *ev = (XFixesSelectionNotifyEvent *) xevent; + + /* !!! FIXME: cache atoms */ + Atom XA_CLIPBOARD = X11_XInternAtom(display, "CLIPBOARD", 0); + +#ifdef DEBUG_XEVENTS + printf("window CLIPBOARD: XFixesSelectionNotify (selection = %s)\n", + X11_XGetAtomName(display, ev->selection)); +#endif + + if (ev->selection == XA_PRIMARY || + (XA_CLIPBOARD != None && ev->selection == XA_CLIPBOARD)) { + SDL_SendClipboardUpdate(); + return; + } + } +#endif /* SDL_VIDEO_DRIVER_X11_XFIXES */ + + if ((videodata->clipboard_window != None) && + (videodata->clipboard_window == xevent->xany.window)) { + X11_HandleClipboardEvent(_this, xevent); + return; + } + + data = NULL; + if (videodata && videodata->windowlist) { + for (i = 0; i < videodata->numwindows; ++i) { + if ((videodata->windowlist[i] != NULL) && + (videodata->windowlist[i]->xwindow == xevent->xany.window)) { + data = videodata->windowlist[i]; + break; + } + } + } + if (!data) { + /* The window for KeymapNotify, etc events is 0 */ + if (xevent->type == KeymapNotify) { +#ifdef DEBUG_XEVENTS + printf("window %p: KeymapNotify!\n", data); +#endif + if (SDL_GetKeyboardFocus() != NULL) { + X11_ReconcileKeyboardState(_this); + } + } else if (xevent->type == MappingNotify) { + /* Has the keyboard layout changed? */ + const int request = xevent->xmapping.request; + +#ifdef DEBUG_XEVENTS + printf("window %p: MappingNotify!\n", data); +#endif + if ((request == MappingKeyboard) || (request == MappingModifier)) { + X11_XRefreshKeyboardMapping(&xevent->xmapping); + } + + X11_UpdateKeymap(_this, SDL_TRUE); + } else if (xevent->type == PropertyNotify && videodata && videodata->windowlist) { + char *name_of_atom = X11_XGetAtomName(display, xevent->xproperty.atom); + + if (SDL_strncmp(name_of_atom, "_ICC_PROFILE", sizeof("_ICC_PROFILE") - 1) == 0) { + XWindowAttributes attrib; + int screennum; + for (i = 0; i < videodata->numwindows; ++i) { + if (videodata->windowlist[i] != NULL) { + data = videodata->windowlist[i]; + X11_XGetWindowAttributes(display, data->xwindow, &attrib); + screennum = X11_XScreenNumberOfScreen(attrib.screen); + if (screennum == 0 && SDL_strcmp(name_of_atom, "_ICC_PROFILE") == 0) { + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_ICCPROF_CHANGED, 0, 0); + } else if (SDL_strncmp(name_of_atom, "_ICC_PROFILE_", sizeof("_ICC_PROFILE_") - 1) == 0 && SDL_strlen(name_of_atom) > sizeof("_ICC_PROFILE_") - 1) { + int iccscreennum = SDL_atoi(&name_of_atom[sizeof("_ICC_PROFILE_") - 1]); + + if (screennum == iccscreennum) { + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_ICCPROF_CHANGED, 0, 0); + } + } + } + } + } + + if (name_of_atom) { + X11_XFree(name_of_atom); + } + } + return; + } + + switch (xevent->type) { + + /* Gaining mouse coverage? */ + case EnterNotify: + { + SDL_Mouse *mouse = SDL_GetMouse(); +#ifdef DEBUG_XEVENTS + printf("window %p: EnterNotify! (%d,%d,%d)\n", data, + xevent->xcrossing.x, + xevent->xcrossing.y, + xevent->xcrossing.mode); + if (xevent->xcrossing.mode == NotifyGrab) { + printf("Mode: NotifyGrab\n"); + } + if (xevent->xcrossing.mode == NotifyUngrab) { + printf("Mode: NotifyUngrab\n"); + } +#endif + SDL_SetMouseFocus(data->window); + + mouse->last_x = xevent->xcrossing.x; + mouse->last_y = xevent->xcrossing.y; + +#ifdef SDL_VIDEO_DRIVER_X11_XFIXES + { + /* Only create the barriers if we have input focus */ + SDL_WindowData *windowdata = (SDL_WindowData *)data->window->driverdata; + if ((data->pointer_barrier_active == SDL_TRUE) && windowdata->window->flags & SDL_WINDOW_INPUT_FOCUS) { + X11_ConfineCursorWithFlags(_this, windowdata->window, &windowdata->barrier_rect, X11_BARRIER_HANDLED_BY_EVENT); + } + } +#endif + + if (!mouse->relative_mode) { + SDL_SendMouseMotion(data->window, 0, 0, xevent->xcrossing.x, xevent->xcrossing.y); + } + + /* We ungrab in LeaveNotify, so we may need to grab again here */ + SDL_UpdateWindowGrab(data->window); + } break; + /* Losing mouse coverage? */ + case LeaveNotify: + { +#ifdef DEBUG_XEVENTS + printf("window %p: LeaveNotify! (%d,%d,%d)\n", data, + xevent->xcrossing.x, + xevent->xcrossing.y, + xevent->xcrossing.mode); + if (xevent->xcrossing.mode == NotifyGrab) { + printf("Mode: NotifyGrab\n"); + } + if (xevent->xcrossing.mode == NotifyUngrab) { + printf("Mode: NotifyUngrab\n"); + } +#endif + if (!SDL_GetMouse()->relative_mode) { + SDL_SendMouseMotion(data->window, 0, 0, xevent->xcrossing.x, xevent->xcrossing.y); + } + + if (xevent->xcrossing.mode != NotifyGrab && + xevent->xcrossing.mode != NotifyUngrab && + xevent->xcrossing.detail != NotifyInferior) { + + /* In order for interaction with the window decorations and menu to work properly + on Mutter, we need to ungrab the keyboard when the the mouse leaves. */ + if (!(data->window->flags & SDL_WINDOW_FULLSCREEN)) { + X11_SetWindowKeyboardGrab(_this, data->window, SDL_FALSE); + } + + SDL_SetMouseFocus(NULL); + } + } break; + + /* Gaining input focus? */ + case FocusIn: + { + if (xevent->xfocus.mode == NotifyGrab || xevent->xfocus.mode == NotifyUngrab) { + /* Someone is handling a global hotkey, ignore it */ +#ifdef DEBUG_XEVENTS + printf("window %p: FocusIn (NotifyGrab/NotifyUngrab, ignoring)\n", data); +#endif + break; + } + + if (xevent->xfocus.detail == NotifyInferior || xevent->xfocus.detail == NotifyPointer) { +#ifdef DEBUG_XEVENTS + printf("window %p: FocusIn (NotifyInferior/NotifyPointer, ignoring)\n", data); +#endif + break; + } +#ifdef DEBUG_XEVENTS + printf("window %p: FocusIn!\n", data); +#endif + if (!videodata->last_mode_change_deadline) /* no recent mode changes */ { + data->pending_focus = PENDING_FOCUS_NONE; + data->pending_focus_time = 0; + X11_DispatchFocusIn(_this, data); + } else { + data->pending_focus = PENDING_FOCUS_IN; + data->pending_focus_time = SDL_GetTicks() + PENDING_FOCUS_TIME; + } + data->last_focus_event_time = SDL_GetTicks(); + } break; + + /* Losing input focus? */ + case FocusOut: + { + if (xevent->xfocus.mode == NotifyGrab || xevent->xfocus.mode == NotifyUngrab) { + /* Someone is handling a global hotkey, ignore it */ +#ifdef DEBUG_XEVENTS + printf("window %p: FocusOut (NotifyGrab/NotifyUngrab, ignoring)\n", data); +#endif + break; + } + if (xevent->xfocus.detail == NotifyInferior || xevent->xfocus.detail == NotifyPointer) { + /* We still have focus if a child gets focus. We also don't + care about the position of the pointer when the keyboard + focus changed. */ +#ifdef DEBUG_XEVENTS + printf("window %p: FocusOut (NotifyInferior/NotifyPointer, ignoring)\n", data); +#endif + break; + } +#ifdef DEBUG_XEVENTS + printf("window %p: FocusOut!\n", data); +#endif + if (!videodata->last_mode_change_deadline) /* no recent mode changes */ { + data->pending_focus = PENDING_FOCUS_NONE; + data->pending_focus_time = 0; + X11_DispatchFocusOut(_this, data); + } else { + data->pending_focus = PENDING_FOCUS_OUT; + data->pending_focus_time = SDL_GetTicks() + PENDING_FOCUS_TIME; + } + +#ifdef SDL_VIDEO_DRIVER_X11_XFIXES + /* Disable confinement if it is activated. */ + if (data->pointer_barrier_active == SDL_TRUE) { + X11_ConfineCursorWithFlags(_this, data->window, NULL, X11_BARRIER_HANDLED_BY_EVENT); + } +#endif /* SDL_VIDEO_DRIVER_X11_XFIXES */ + } break; + + /* Key press/release? */ + case KeyPress: + case KeyRelease: + { + KeyCode keycode = xevent->xkey.keycode; + KeySym keysym = NoSymbol; + char text[SDL_TEXTINPUTEVENT_TEXT_SIZE]; + Status status = 0; + SDL_bool handled_by_ime = SDL_FALSE; + +#ifdef DEBUG_XEVENTS + printf("window %p: %s (X11 keycode = 0x%X)\n", data, (xevent->type == KeyPress ? "KeyPress" : "KeyRelease"), xevent->xkey.keycode); +#endif +#ifdef DEBUG_SCANCODES + if (videodata->key_layout[keycode] == SDL_SCANCODE_UNKNOWN && keycode) { + int min_keycode, max_keycode; + X11_XDisplayKeycodes(display, &min_keycode, &max_keycode); + keysym = X11_KeyCodeToSym(_this, keycode, xevent->xkey.state >> 13); + SDL_Log("The key you just pressed is not recognized by SDL. To help get this fixed, please report this to the SDL forums/mailing list X11 KeyCode %d (%d), X11 KeySym 0x%lX (%s).\n", + keycode, keycode - min_keycode, keysym, + X11_XKeysymToString(keysym)); + } +#endif /* DEBUG SCANCODES */ + + SDL_zeroa(text); +#ifdef X_HAVE_UTF8_STRING + if (data->ic && xevent->type == KeyPress) { + X11_Xutf8LookupString(data->ic, &xevent->xkey, text, sizeof(text), + &keysym, &status); + } else { + XLookupStringAsUTF8(&xevent->xkey, text, sizeof(text), &keysym, NULL); + } +#else + XLookupStringAsUTF8(&xevent->xkey, text, sizeof(text), &keysym, NULL); +#endif + +#ifdef SDL_USE_IME + if (SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE) { + handled_by_ime = SDL_IME_ProcessKeyEvent(keysym, keycode, (xevent->type == KeyPress ? SDL_PRESSED : SDL_RELEASED)); + } +#endif + if (!handled_by_ime) { + if (xevent->type == KeyPress) { + /* Don't send the key if it looks like a duplicate of a filtered key sent by an IME */ + if (xevent->xkey.keycode != videodata->filter_code || xevent->xkey.time != videodata->filter_time) { + SDL_SendKeyboardKey(SDL_PRESSED, videodata->key_layout[keycode]); + } + if (*text) { + SDL_SendKeyboardText(text); + } + } else { + if (X11_KeyRepeat(display, xevent)) { + /* We're about to get a repeated key down, ignore the key up */ + break; + } + SDL_SendKeyboardKey(SDL_RELEASED, videodata->key_layout[keycode]); + } + } + + if (xevent->type == KeyPress) { + X11_UpdateUserTime(data, xevent->xkey.time); + } + } break; + + /* Have we been iconified? */ + case UnmapNotify: + { + XEvent ev; + +#ifdef DEBUG_XEVENTS + printf("window %p: UnmapNotify!\n", data); +#endif + + if (X11_XCheckIfEvent(display, &ev, &isReparentNotify, (XPointer)&xevent->xunmap)) { + X11_XCheckIfEvent(display, &ev, &isMapNotify, (XPointer)&xevent->xunmap); + } else { + X11_DispatchUnmapNotify(data); + } + +#ifdef SDL_VIDEO_DRIVER_X11_XFIXES + /* Disable confinement if the window gets hidden. */ + if (data->pointer_barrier_active == SDL_TRUE) { + X11_ConfineCursorWithFlags(_this, data->window, NULL, X11_BARRIER_HANDLED_BY_EVENT); + } +#endif /* SDL_VIDEO_DRIVER_X11_XFIXES */ + } break; + + /* Have we been restored? */ + case MapNotify: + { +#ifdef DEBUG_XEVENTS + printf("window %p: MapNotify!\n", data); +#endif + X11_DispatchMapNotify(data); + +#ifdef SDL_VIDEO_DRIVER_X11_XFIXES + /* Enable confinement if it was activated. */ + if (data->pointer_barrier_active == SDL_TRUE) { + X11_ConfineCursorWithFlags(_this, data->window, &data->barrier_rect, X11_BARRIER_HANDLED_BY_EVENT); + } +#endif /* SDL_VIDEO_DRIVER_X11_XFIXES */ + } break; + + /* Have we been resized or moved? */ + case ConfigureNotify: + { +#ifdef DEBUG_XEVENTS + printf("window %p: ConfigureNotify! (position: %d,%d, size: %dx%d)\n", data, + xevent->xconfigure.x, xevent->xconfigure.y, + xevent->xconfigure.width, xevent->xconfigure.height); +#endif + /* Real configure notify events are relative to the parent, synthetic events are absolute. */ + if (!xevent->xconfigure.send_event) { + unsigned int NumChildren; + Window ChildReturn, Root, Parent; + Window *Children; + /* Translate these coodinates back to relative to root */ + X11_XQueryTree(data->videodata->display, xevent->xconfigure.window, &Root, &Parent, &Children, &NumChildren); + X11_XTranslateCoordinates(xevent->xconfigure.display, + Parent, DefaultRootWindow(xevent->xconfigure.display), + xevent->xconfigure.x, xevent->xconfigure.y, + &xevent->xconfigure.x, &xevent->xconfigure.y, + &ChildReturn); + } + + if (xevent->xconfigure.x != data->last_xconfigure.x || + xevent->xconfigure.y != data->last_xconfigure.y) { + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_MOVED, + xevent->xconfigure.x, xevent->xconfigure.y); +#ifdef SDL_USE_IME + if (SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE) { + /* Update IME candidate list position */ + SDL_IME_UpdateTextRect(NULL); + } +#endif + } + if (xevent->xconfigure.width != data->last_xconfigure.width || + xevent->xconfigure.height != data->last_xconfigure.height) { + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_RESIZED, + xevent->xconfigure.width, + xevent->xconfigure.height); + } + data->last_xconfigure = xevent->xconfigure; + } break; + + /* Have we been requested to quit (or another client message?) */ + case ClientMessage: + { + + static int xdnd_version = 0; + + if (xevent->xclient.message_type == videodata->XdndEnter) { + + SDL_bool use_list = xevent->xclient.data.l[1] & 1; + data->xdnd_source = xevent->xclient.data.l[0]; + xdnd_version = (xevent->xclient.data.l[1] >> 24); +#ifdef DEBUG_XEVENTS + printf("XID of source window : %ld\n", data->xdnd_source); + printf("Protocol version to use : %d\n", xdnd_version); + printf("More then 3 data types : %d\n", (int)use_list); +#endif + + if (use_list) { + /* fetch conversion targets */ + SDL_x11Prop p; + X11_ReadProperty(&p, display, data->xdnd_source, videodata->XdndTypeList); + /* pick one */ + data->xdnd_req = X11_PickTarget(display, (Atom *)p.data, p.count); + X11_XFree(p.data); + } else { + /* pick from list of three */ + data->xdnd_req = X11_PickTargetFromAtoms(display, xevent->xclient.data.l[2], xevent->xclient.data.l[3], xevent->xclient.data.l[4]); + } + } else if (xevent->xclient.message_type == videodata->XdndPosition) { + +#ifdef DEBUG_XEVENTS + Atom act = videodata->XdndActionCopy; + if (xdnd_version >= 2) { + act = xevent->xclient.data.l[4]; + } + printf("Action requested by user is : %s\n", X11_XGetAtomName(display, act)); +#endif + + /* reply with status */ + SDL_memset(&m, 0, sizeof(XClientMessageEvent)); + m.type = ClientMessage; + m.display = xevent->xclient.display; + m.window = xevent->xclient.data.l[0]; + m.message_type = videodata->XdndStatus; + m.format = 32; + m.data.l[0] = data->xwindow; + m.data.l[1] = (data->xdnd_req != None); + m.data.l[2] = 0; /* specify an empty rectangle */ + m.data.l[3] = 0; + m.data.l[4] = videodata->XdndActionCopy; /* we only accept copying anyway */ + + X11_XSendEvent(display, xevent->xclient.data.l[0], False, NoEventMask, (XEvent *)&m); + X11_XFlush(display); + } else if (xevent->xclient.message_type == videodata->XdndDrop) { + if (data->xdnd_req == None) { + /* say again - not interested! */ + SDL_memset(&m, 0, sizeof(XClientMessageEvent)); + m.type = ClientMessage; + m.display = xevent->xclient.display; + m.window = xevent->xclient.data.l[0]; + m.message_type = videodata->XdndFinished; + m.format = 32; + m.data.l[0] = data->xwindow; + m.data.l[1] = 0; + m.data.l[2] = None; /* fail! */ + X11_XSendEvent(display, xevent->xclient.data.l[0], False, NoEventMask, (XEvent *)&m); + } else { + /* convert */ + if (xdnd_version >= 1) { + X11_XConvertSelection(display, videodata->XdndSelection, data->xdnd_req, videodata->PRIMARY, data->xwindow, xevent->xclient.data.l[2]); + } else { + X11_XConvertSelection(display, videodata->XdndSelection, data->xdnd_req, videodata->PRIMARY, data->xwindow, CurrentTime); + } + } + } else if ((xevent->xclient.message_type == videodata->WM_PROTOCOLS) && + (xevent->xclient.format == 32) && + (xevent->xclient.data.l[0] == videodata->_NET_WM_PING)) { + Window root = DefaultRootWindow(display); + +#ifdef DEBUG_XEVENTS + printf("window %p: _NET_WM_PING\n", data); +#endif + xevent->xclient.window = root; + X11_XSendEvent(display, root, False, SubstructureRedirectMask | SubstructureNotifyMask, xevent); + break; + } + + else if ((xevent->xclient.message_type == videodata->WM_PROTOCOLS) && + (xevent->xclient.format == 32) && + (xevent->xclient.data.l[0] == videodata->WM_DELETE_WINDOW)) { + +#ifdef DEBUG_XEVENTS + printf("window %p: WM_DELETE_WINDOW\n", data); +#endif + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_CLOSE, 0, 0); + break; + } else if ((xevent->xclient.message_type == videodata->WM_PROTOCOLS) && + (xevent->xclient.format == 32) && + (xevent->xclient.data.l[0] == videodata->WM_TAKE_FOCUS)) { + +#ifdef DEBUG_XEVENTS + printf("window %p: WM_TAKE_FOCUS\n", data); +#endif + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_TAKE_FOCUS, 0, 0); + break; + } + } break; + + /* Do we need to refresh ourselves? */ + case Expose: + { +#ifdef DEBUG_XEVENTS + printf("window %p: Expose (count = %d)\n", data, xevent->xexpose.count); +#endif + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_EXPOSED, 0, 0); + } break; + + case MotionNotify: + { + SDL_Mouse *mouse = SDL_GetMouse(); + if (!mouse->relative_mode || mouse->relative_mode_warp) { +#ifdef DEBUG_MOTION + printf("window %p: X11 motion: %d,%d\n", data, xevent->xmotion.x, xevent->xmotion.y); +#endif + + SDL_SendMouseMotion(data->window, 0, 0, xevent->xmotion.x, xevent->xmotion.y); + } + } break; + + case ButtonPress: + { + int xticks = 0, yticks = 0; +#ifdef DEBUG_XEVENTS + printf("window %p: ButtonPress (X11 button = %d)\n", data, xevent->xbutton.button); +#endif + if (X11_IsWheelEvent(display, xevent, &xticks, &yticks)) { + SDL_SendMouseWheel(data->window, 0, (float)-xticks, (float)yticks, SDL_MOUSEWHEEL_NORMAL); + } else { + SDL_bool ignore_click = SDL_FALSE; + int button = xevent->xbutton.button; + if (button == Button1) { + if (ProcessHitTest(_this, data, xevent)) { + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_HIT_TEST, 0, 0); + break; /* don't pass this event on to app. */ + } + } else if (button > 7) { + /* X button values 4-7 are used for scrolling, so X1 is 8, X2 is 9, ... + => subtract (8-SDL_BUTTON_X1) to get value SDL expects */ + button -= (8 - SDL_BUTTON_X1); + } + if (data->last_focus_event_time) { + const int X11_FOCUS_CLICK_TIMEOUT = 10; + if (!SDL_TICKS_PASSED(SDL_GetTicks(), data->last_focus_event_time + X11_FOCUS_CLICK_TIMEOUT)) { + ignore_click = !SDL_GetHintBoolean(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, SDL_FALSE); + } + data->last_focus_event_time = 0; + } + if (!ignore_click) { + SDL_SendMouseButton(data->window, 0, SDL_PRESSED, button); + } + } + X11_UpdateUserTime(data, xevent->xbutton.time); + } break; + + case ButtonRelease: + { + int button = xevent->xbutton.button; + /* The X server sends a Release event for each Press for wheels. Ignore them. */ + int xticks = 0, yticks = 0; +#ifdef DEBUG_XEVENTS + printf("window %p: ButtonRelease (X11 button = %d)\n", data, xevent->xbutton.button); +#endif + if (!X11_IsWheelEvent(display, xevent, &xticks, &yticks)) { + if (button > 7) { + /* see explanation at case ButtonPress */ + button -= (8 - SDL_BUTTON_X1); + } + SDL_SendMouseButton(data->window, 0, SDL_RELEASED, button); + } + } break; + + case PropertyNotify: + { +#ifdef DEBUG_XEVENTS + unsigned char *propdata; + int status, real_format; + Atom real_type; + unsigned long items_read, items_left; + + char *name = X11_XGetAtomName(display, xevent->xproperty.atom); + if (name) { + printf("window %p: PropertyNotify: %s %s time=%lu\n", data, name, (xevent->xproperty.state == PropertyDelete) ? "deleted" : "changed", xevent->xproperty.time); + X11_XFree(name); + } + + status = X11_XGetWindowProperty(display, data->xwindow, xevent->xproperty.atom, 0L, 8192L, False, AnyPropertyType, &real_type, &real_format, &items_read, &items_left, &propdata); + if (status == Success && items_read > 0) { + if (real_type == XA_INTEGER) { + int *values = (int *)propdata; + + printf("{"); + for (i = 0; i < items_read; i++) { + printf(" %d", values[i]); + } + printf(" }\n"); + } else if (real_type == XA_CARDINAL) { + if (real_format == 32) { + Uint32 *values = (Uint32 *)propdata; + + printf("{"); + for (i = 0; i < items_read; i++) { + printf(" %d", values[i]); + } + printf(" }\n"); + } else if (real_format == 16) { + Uint16 *values = (Uint16 *)propdata; + + printf("{"); + for (i = 0; i < items_read; i++) { + printf(" %d", values[i]); + } + printf(" }\n"); + } else if (real_format == 8) { + Uint8 *values = (Uint8 *)propdata; + + printf("{"); + for (i = 0; i < items_read; i++) { + printf(" %d", values[i]); + } + printf(" }\n"); + } + } else if (real_type == XA_STRING || + real_type == videodata->UTF8_STRING) { + printf("{ \"%s\" }\n", propdata); + } else if (real_type == XA_ATOM) { + Atom *atoms = (Atom *)propdata; + + printf("{"); + for (i = 0; i < items_read; i++) { + char *atomname = X11_XGetAtomName(display, atoms[i]); + if (atomname) { + printf(" %s", atomname); + X11_XFree(atomname); + } + } + printf(" }\n"); + } else { + char *atomname = X11_XGetAtomName(display, real_type); + printf("Unknown type: %ld (%s)\n", real_type, atomname ? atomname : "UNKNOWN"); + if (atomname) { + X11_XFree(atomname); + } + } + } + if (status == Success) { + X11_XFree(propdata); + } +#endif /* DEBUG_XEVENTS */ + + /* Take advantage of this moment to make sure user_time has a + valid timestamp from the X server, so if we later try to + raise/restore this window, _NET_ACTIVE_WINDOW can have a + non-zero timestamp, even if there's never been a mouse or + key press to this window so far. Note that we don't try to + set _NET_WM_USER_TIME here, though. That's only for legit + user interaction with the window. */ + if (!data->user_time) { + data->user_time = xevent->xproperty.time; + } + + if (xevent->xproperty.atom == data->videodata->_NET_WM_STATE) { + /* Get the new state from the window manager. + Compositing window managers can alter visibility of windows + without ever mapping / unmapping them, so we handle that here, + because they use the NETWM protocol to notify us of changes. + */ + const Uint32 flags = X11_GetNetWMState(_this, data->window, xevent->xproperty.window); + const Uint32 changed = flags ^ data->window->flags; + + if ((changed & SDL_WINDOW_HIDDEN) || (changed & SDL_WINDOW_FULLSCREEN)) { + if (flags & SDL_WINDOW_HIDDEN) { + X11_DispatchUnmapNotify(data); + } else { + X11_DispatchMapNotify(data); + } + } + + if (changed & SDL_WINDOW_MAXIMIZED) { + if (flags & SDL_WINDOW_MAXIMIZED) { + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_MAXIMIZED, 0, 0); + } else { + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_RESTORED, 0, 0); + } + } + } else if (xevent->xproperty.atom == videodata->XKLAVIER_STATE) { + /* Hack for Ubuntu 12.04 (etc) that doesn't send MappingNotify + events when the keyboard layout changes (for example, + changing from English to French on the menubar's keyboard + icon). Since it changes the XKLAVIER_STATE property, we + notice and reinit our keymap here. This might not be the + right approach, but it seems to work. */ + X11_UpdateKeymap(_this, SDL_TRUE); + } else if (xevent->xproperty.atom == videodata->_NET_FRAME_EXTENTS) { + X11_GetBorderValues(data); + } + } break; + + case SelectionNotify: + { + Atom target = xevent->xselection.target; +#ifdef DEBUG_XEVENTS + printf("window %p: SelectionNotify (requestor = %ld, target = %ld)\n", data, + xevent->xselection.requestor, xevent->xselection.target); +#endif + if (target == data->xdnd_req) { + /* read data */ + SDL_x11Prop p; + X11_ReadProperty(&p, display, data->xwindow, videodata->PRIMARY); + + if (p.format == 8) { + char *saveptr = NULL; + char *name = X11_XGetAtomName(display, target); + if (name) { + char *token = SDL_strtokr((char *)p.data, "\r\n", &saveptr); + while (token) { + if (SDL_strcmp("text/plain", name) == 0) { + SDL_SendDropText(data->window, token); + } else if (SDL_strcmp("text/uri-list", name) == 0) { + char *fn = X11_URIToLocal(token); + if (fn) { + SDL_SendDropFile(data->window, fn); + } + } + token = SDL_strtokr(NULL, "\r\n", &saveptr); + } + X11_XFree(name); + } + SDL_SendDropComplete(data->window); + } + X11_XFree(p.data); + + /* send reply */ + SDL_memset(&m, 0, sizeof(XClientMessageEvent)); + m.type = ClientMessage; + m.display = display; + m.window = data->xdnd_source; + m.message_type = videodata->XdndFinished; + m.format = 32; + m.data.l[0] = data->xwindow; + m.data.l[1] = 1; + m.data.l[2] = videodata->XdndActionCopy; + X11_XSendEvent(display, data->xdnd_source, False, NoEventMask, (XEvent *)&m); + + X11_XSync(display, False); + } + } break; + + default: + { +#ifdef DEBUG_XEVENTS + printf("window %p: Unhandled event %d\n", data, xevent->type); +#endif + } break; + } +} + +static void X11_HandleFocusChanges(_THIS) +{ + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + int i; + + if (videodata && videodata->windowlist) { + for (i = 0; i < videodata->numwindows; ++i) { + SDL_WindowData *data = videodata->windowlist[i]; + if (data && data->pending_focus != PENDING_FOCUS_NONE) { + Uint32 now = SDL_GetTicks(); + if (SDL_TICKS_PASSED(now, data->pending_focus_time)) { + if (data->pending_focus == PENDING_FOCUS_IN) { + X11_DispatchFocusIn(_this, data); + } else { + X11_DispatchFocusOut(_this, data); + } + data->pending_focus = PENDING_FOCUS_NONE; + } + } + } + } +} + +static Bool isAnyEvent(Display *display, XEvent *ev, XPointer arg) +{ + return True; +} + +static SDL_bool X11_PollEvent(Display *display, XEvent *event) +{ + if (!X11_XCheckIfEvent(display, event, isAnyEvent, NULL)) { + return SDL_FALSE; + } + + return SDL_TRUE; +} + +void X11_SendWakeupEvent(_THIS, SDL_Window *window) +{ + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; + Display *req_display = data->request_display; + Window xwindow = ((SDL_WindowData *)window->driverdata)->xwindow; + XClientMessageEvent event; + + SDL_memset(&event, 0, sizeof(XClientMessageEvent)); + event.type = ClientMessage; + event.display = req_display; + event.send_event = True; + event.message_type = data->_SDL_WAKEUP; + event.format = 8; + + X11_XSendEvent(req_display, xwindow, False, NoEventMask, (XEvent *)&event); + /* XSendEvent returns a status and it could be BadValue or BadWindow. If an + error happens it is an SDL's internal error and there is nothing we can do here. */ + X11_XFlush(req_display); +} + +int X11_WaitEventTimeout(_THIS, int timeout) +{ + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + Display *display; + XEvent xevent; + display = videodata->display; + + SDL_zero(xevent); + + /* Flush and poll to grab any events already read and queued */ + X11_XFlush(display); + if (X11_PollEvent(display, &xevent)) { + /* Fall through */ + } else if (timeout == 0) { + return 0; + } else { + /* Use SDL_IOR_NO_RETRY to ensure SIGINT will break us out of our wait */ + int err = SDL_IOReady(ConnectionNumber(display), SDL_IOR_READ | SDL_IOR_NO_RETRY, timeout); + if (err > 0) { + if (!X11_PollEvent(display, &xevent)) { + /* Someone may have beat us to reading the fd. Return 1 here to + * trigger the normal spurious wakeup logic in the event core. */ + return 1; + } + } else if (err == 0) { + /* Timeout */ + return 0; + } else { + /* Error returned from poll()/select() */ + + if (errno == EINTR) { + /* If the wait was interrupted by a signal, we may have generated a + * SDL_QUIT event. Let the caller know to call SDL_PumpEvents(). */ + return 1; + } else { + return err; + } + } + } + + X11_DispatchEvent(_this, &xevent); + +#ifdef SDL_USE_IME + if (SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE) { + SDL_IME_PumpEvents(); + } +#endif + return 1; +} + +void X11_PumpEvents(_THIS) +{ + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; + XEvent xevent; + int i; + + if (data->last_mode_change_deadline) { + if (SDL_TICKS_PASSED(SDL_GetTicks(), data->last_mode_change_deadline)) { + data->last_mode_change_deadline = 0; /* assume we're done. */ + } + } + + /* Update activity every 30 seconds to prevent screensaver */ + if (_this->suspend_screensaver) { + const Uint32 now = SDL_GetTicks(); + if (!data->screensaver_activity || + SDL_TICKS_PASSED(now, data->screensaver_activity + 30000)) { + X11_XResetScreenSaver(data->display); + +#ifdef SDL_USE_LIBDBUS + SDL_DBus_ScreensaverTickle(); +#endif + + data->screensaver_activity = now; + } + } + + SDL_zero(xevent); + + /* Keep processing pending events */ + while (X11_PollEvent(data->display, &xevent)) { + X11_DispatchEvent(_this, &xevent); + } + +#ifdef SDL_USE_IME + if (SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE) { + SDL_IME_PumpEvents(); + } +#endif + + /* FIXME: Only need to do this when there are pending focus changes */ + X11_HandleFocusChanges(_this); + + /* FIXME: Only need to do this when there are flashing windows */ + for (i = 0; i < data->numwindows; ++i) { + if (data->windowlist[i] != NULL && + data->windowlist[i]->flash_cancel_time && + SDL_TICKS_PASSED(SDL_GetTicks(), data->windowlist[i]->flash_cancel_time)) { + X11_FlashWindow(_this, data->windowlist[i]->window, SDL_FLASH_CANCEL); + } + } +} + +void X11_SuspendScreenSaver(_THIS) +{ +#ifdef SDL_VIDEO_DRIVER_X11_XSCRNSAVER + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; + int dummy; + int major_version, minor_version; +#endif /* SDL_VIDEO_DRIVER_X11_XSCRNSAVER */ + +#ifdef SDL_USE_LIBDBUS + if (SDL_DBus_ScreensaverInhibit(_this->suspend_screensaver)) { + return; + } + + if (_this->suspend_screensaver) { + SDL_DBus_ScreensaverTickle(); + } +#endif + +#ifdef SDL_VIDEO_DRIVER_X11_XSCRNSAVER + if (SDL_X11_HAVE_XSS) { + /* X11_XScreenSaverSuspend was introduced in MIT-SCREEN-SAVER 1.1 */ + if (!X11_XScreenSaverQueryExtension(data->display, &dummy, &dummy) || + !X11_XScreenSaverQueryVersion(data->display, + &major_version, &minor_version) || + major_version < 1 || (major_version == 1 && minor_version < 1)) { + return; + } + + X11_XScreenSaverSuspend(data->display, _this->suspend_screensaver); + X11_XResetScreenSaver(data->display); + } +#endif +} + +#endif /* SDL_VIDEO_DRIVER_X11 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/x11/SDL_x11events.h b/SDL2-2.30.5/src/video/x11/SDL_x11events.h similarity index 79% rename from SDL2-2.0.12/src/video/x11/SDL_x11events.h rename to SDL2-2.30.5/src/video/x11/SDL_x11events.h index df0782c..cec823c 100644 --- a/SDL2-2.0.12/src/video/x11/SDL_x11events.h +++ b/SDL2-2.30.5/src/video/x11/SDL_x11events.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -24,7 +24,11 @@ #define SDL_x11events_h_ extern void X11_PumpEvents(_THIS); +extern int X11_WaitEventTimeout(_THIS, int timeout); +extern void X11_SendWakeupEvent(_THIS, SDL_Window *window); extern void X11_SuspendScreenSaver(_THIS); +extern void X11_ReconcileKeyboardState(_THIS); +extern void X11_GetBorderValues(void /*SDL_WindowData*/ *data); #endif /* SDL_x11events_h_ */ diff --git a/SDL2-2.0.12/src/video/x11/SDL_x11framebuffer.c b/SDL2-2.30.5/src/video/x11/SDL_x11framebuffer.c similarity index 70% rename from SDL2-2.0.12/src/video/x11/SDL_x11framebuffer.c rename to SDL2-2.30.5/src/video/x11/SDL_x11framebuffer.c index 53e7ab0..0a63eda 100644 --- a/SDL2-2.0.12/src/video/x11/SDL_x11framebuffer.c +++ b/SDL2-2.30.5/src/video/x11/SDL_x11framebuffer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,12 +20,11 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_X11 +#ifdef SDL_VIDEO_DRIVER_X11 #include "SDL_x11video.h" #include "SDL_x11framebuffer.h" - #ifndef NO_SHARED_MEMORY /* Shared memory error handler routine */ @@ -33,11 +32,11 @@ static int shm_error; static int (*X_handler)(Display *, XErrorEvent *) = NULL; static int shm_errhandler(Display *d, XErrorEvent *e) { - if ( e->error_code == BadAccess ) { - shm_error = True; - return(0); - } else - return(X_handler(d,e)); + if (e->error_code == BadAccess) { + shm_error = True; + return 0; + } + return X_handler(d, e); } static SDL_bool have_mitshm(Display *dpy) @@ -48,14 +47,16 @@ static SDL_bool have_mitshm(Display *dpy) #endif /* !NO_SHARED_MEMORY */ -int -X11_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, - void ** pixels, int *pitch) +int X11_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format, + void **pixels, int *pitch) { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; Display *display = data->videodata->display; XGCValues gcv; XVisualInfo vinfo; + int w, h; + + SDL_GetWindowSizeInPixels(window, &w, &h); /* Free the old framebuffer surface */ X11_DestroyWindowFramebuffer(_this, window); @@ -78,25 +79,26 @@ X11_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, } /* Calculate pitch */ - *pitch = (((window->w * SDL_BYTESPERPIXEL(*format)) + 3) & ~3); + *pitch = (((w * SDL_BYTESPERPIXEL(*format)) + 3) & ~3); /* Create the actual image */ #ifndef NO_SHARED_MEMORY if (have_mitshm(display)) { XShmSegmentInfo *shminfo = &data->shminfo; - shminfo->shmid = shmget(IPC_PRIVATE, window->h*(*pitch), IPC_CREAT | 0777); - if ( shminfo->shmid >= 0 ) { + shminfo->shmid = shmget(IPC_PRIVATE, (size_t)h * (*pitch), IPC_CREAT | 0777); + if (shminfo->shmid >= 0) { shminfo->shmaddr = (char *)shmat(shminfo->shmid, 0, 0); shminfo->readOnly = False; - if ( shminfo->shmaddr != (char *)-1 ) { + if (shminfo->shmaddr != (char *)-1) { shm_error = False; X_handler = X11_XSetErrorHandler(shm_errhandler); X11_XShmAttach(display, shminfo); X11_XSync(display, False); X11_XSetErrorHandler(X_handler); - if ( shm_error ) + if (shm_error) { shmdt(shminfo->shmaddr); + } } else { shm_error = True; } @@ -106,15 +108,16 @@ X11_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, } if (!shm_error) { data->ximage = X11_XShmCreateImage(display, data->visual, - vinfo.depth, ZPixmap, - shminfo->shmaddr, shminfo, - window->w, window->h); + vinfo.depth, ZPixmap, + shminfo->shmaddr, shminfo, + w, h); if (!data->ximage) { X11_XShmDetach(display, shminfo); X11_XSync(display, False); shmdt(shminfo->shmaddr); } else { /* Done! */ + data->ximage->byte_order = (SDL_BYTEORDER == SDL_BIG_ENDIAN) ? MSBFirst : LSBFirst; data->use_mitshm = SDL_TRUE; *pixels = shminfo->shmaddr; return 0; @@ -123,29 +126,33 @@ X11_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, } #endif /* not NO_SHARED_MEMORY */ - *pixels = SDL_malloc(window->h*(*pitch)); - if (*pixels == NULL) { + *pixels = SDL_malloc((size_t)h * (*pitch)); + if (!*pixels) { return SDL_OutOfMemory(); } data->ximage = X11_XCreateImage(display, data->visual, - vinfo.depth, ZPixmap, 0, (char *)(*pixels), - window->w, window->h, 32, 0); + vinfo.depth, ZPixmap, 0, (char *)(*pixels), + w, h, 32, 0); if (!data->ximage) { SDL_free(*pixels); return SDL_SetError("Couldn't create XImage"); } + data->ximage->byte_order = (SDL_BYTEORDER == SDL_BIG_ENDIAN) ? MSBFirst : LSBFirst; return 0; } -int -X11_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, - int numrects) +int X11_UpdateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_Rect *rects, + int numrects) { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; Display *display = data->videodata->display; int i; - int x, y, w ,h; + int x, y, w, h; + int window_w, window_h; + + SDL_GetWindowSizeInPixels(window, &window_w, &window_h); + #ifndef NO_SHARED_MEMORY if (data->use_mitshm) { for (i = 0; i < numrects; ++i) { @@ -158,26 +165,25 @@ X11_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, /* Clipped? */ continue; } - if (x < 0) - { + if (x < 0) { x += w; w += rects[i].x; } - if (y < 0) - { + if (y < 0) { y += h; h += rects[i].y; } - if (x + w > window->w) - w = window->w - x; - if (y + h > window->h) - h = window->h - y; + if (x + w > window_w) { + w = window_w - x; + } + if (y + h > window_h) { + h = window_h - y; + } X11_XShmPutImage(display, data->xwindow, data->gc, data->ximage, - x, y, x, y, w, h, False); + x, y, x, y, w, h, False); } - } - else + } else #endif /* !NO_SHARED_MEMORY */ { for (i = 0; i < numrects; ++i) { @@ -190,23 +196,23 @@ X11_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, /* Clipped? */ continue; } - if (x < 0) - { + if (x < 0) { x += w; w += rects[i].x; } - if (y < 0) - { + if (y < 0) { y += h; h += rects[i].y; } - if (x + w > window->w) - w = window->w - x; - if (y + h > window->h) - h = window->h - y; + if (x + w > window_w) { + w = window_w - x; + } + if (y + h > window_h) { + h = window_h - y; + } X11_XPutImage(display, data->xwindow, data->gc, data->ximage, - x, y, x, y, w, h); + x, y, x, y, w, h); } } @@ -215,10 +221,9 @@ X11_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, return 0; } -void -X11_DestroyWindowFramebuffer(_THIS, SDL_Window * window) +void X11_DestroyWindowFramebuffer(_THIS, SDL_Window *window) { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; Display *display; if (!data) { diff --git a/SDL2-2.0.12/src/video/x11/SDL_x11framebuffer.h b/SDL2-2.30.5/src/video/x11/SDL_x11framebuffer.h similarity index 69% rename from SDL2-2.0.12/src/video/x11/SDL_x11framebuffer.h rename to SDL2-2.30.5/src/video/x11/SDL_x11framebuffer.h index c26b4d9..f5fe142 100644 --- a/SDL2-2.0.12/src/video/x11/SDL_x11framebuffer.h +++ b/SDL2-2.30.5/src/video/x11/SDL_x11framebuffer.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -24,13 +24,12 @@ #include "../../SDL_internal.h" - -extern int X11_CreateWindowFramebuffer(_THIS, SDL_Window * window, - Uint32 * format, - void ** pixels, int *pitch); -extern int X11_UpdateWindowFramebuffer(_THIS, SDL_Window * window, - const SDL_Rect * rects, int numrects); -extern void X11_DestroyWindowFramebuffer(_THIS, SDL_Window * window); +extern int X11_CreateWindowFramebuffer(_THIS, SDL_Window *window, + Uint32 *format, + void **pixels, int *pitch); +extern int X11_UpdateWindowFramebuffer(_THIS, SDL_Window *window, + const SDL_Rect *rects, int numrects); +extern void X11_DestroyWindowFramebuffer(_THIS, SDL_Window *window); #endif /* SDL_x11framebuffer_h_ */ diff --git a/SDL2-2.30.5/src/video/x11/SDL_x11keyboard.c b/SDL2-2.30.5/src/video/x11/SDL_x11keyboard.c new file mode 100644 index 0000000..9a23baf --- /dev/null +++ b/SDL2-2.30.5/src/video/x11/SDL_x11keyboard.c @@ -0,0 +1,506 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_X11 + +#include "SDL_hints.h" +#include "SDL_misc.h" +#include "SDL_x11video.h" + +#include "../../events/SDL_keyboard_c.h" +#include "../../events/SDL_scancode_tables_c.h" + +#include +#include + +#include "../../events/imKStoUCS.h" +#include "../../events/SDL_keysym_to_scancode_c.h" + +#ifdef X_HAVE_UTF8_STRING +#include +#endif + +static SDL_ScancodeTable scancode_set[] = { + SDL_SCANCODE_TABLE_DARWIN, + SDL_SCANCODE_TABLE_XFREE86_1, + SDL_SCANCODE_TABLE_XFREE86_2, + SDL_SCANCODE_TABLE_XVNC, +}; + +static SDL_bool X11_ScancodeIsRemappable(SDL_Scancode scancode) +{ + /* + * XKB remappings can assign different keysyms for these scancodes, but + * as these keys are in fixed positions, the scancodes themselves shouldn't + * be switched. Mark them as not being remappable. + */ + switch (scancode) { + case SDL_SCANCODE_ESCAPE: + case SDL_SCANCODE_CAPSLOCK: + case SDL_SCANCODE_NUMLOCKCLEAR: + case SDL_SCANCODE_LSHIFT: + case SDL_SCANCODE_RSHIFT: + case SDL_SCANCODE_LCTRL: + case SDL_SCANCODE_RCTRL: + case SDL_SCANCODE_LALT: + case SDL_SCANCODE_RALT: + case SDL_SCANCODE_LGUI: + case SDL_SCANCODE_RGUI: + return SDL_FALSE; + default: + return SDL_TRUE; + } +} + +/* This function only correctly maps letters and numbers for keyboards in US QWERTY layout */ +static SDL_Scancode X11_KeyCodeToSDLScancode(_THIS, KeyCode keycode) +{ + const KeySym keysym = X11_KeyCodeToSym(_this, keycode, 0); + + if (keysym == NoSymbol) { + return SDL_SCANCODE_UNKNOWN; + } + + return SDL_GetScancodeFromKeySym(keysym, keycode); +} + +static Uint32 X11_KeyCodeToUcs4(_THIS, KeyCode keycode, unsigned char group) +{ + KeySym keysym = X11_KeyCodeToSym(_this, keycode, group); + + if (keysym == NoSymbol) { + return 0; + } + + return SDL_KeySymToUcs4(keysym); +} + +KeySym +X11_KeyCodeToSym(_THIS, KeyCode keycode, unsigned char group) +{ + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; + KeySym keysym; + +#ifdef SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM + if (data->xkb) { + int num_groups = XkbKeyNumGroups(data->xkb, keycode); + unsigned char info = XkbKeyGroupInfo(data->xkb, keycode); + + if (num_groups && group >= num_groups) { + + int action = XkbOutOfRangeGroupAction(info); + + if (action == XkbRedirectIntoRange) { + group = XkbOutOfRangeGroupNumber(info); + if (group >= num_groups) { + group = 0; + } + } else if (action == XkbClampIntoRange) { + group = num_groups - 1; + } else { + group %= num_groups; + } + } + keysym = X11_XkbKeycodeToKeysym(data->display, keycode, group, 0); + } else { + keysym = X11_XKeycodeToKeysym(data->display, keycode, 0); + } +#else + keysym = X11_XKeycodeToKeysym(data->display, keycode, 0); +#endif + + return keysym; +} + +int X11_InitKeyboard(_THIS) +{ + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; + int i = 0; + int j = 0; + int min_keycode, max_keycode; + struct + { + SDL_Scancode scancode; + KeySym keysym; + int value; + } fingerprint[] = { + { SDL_SCANCODE_HOME, XK_Home, 0 }, + { SDL_SCANCODE_PAGEUP, XK_Prior, 0 }, + { SDL_SCANCODE_UP, XK_Up, 0 }, + { SDL_SCANCODE_LEFT, XK_Left, 0 }, + { SDL_SCANCODE_DELETE, XK_Delete, 0 }, + { SDL_SCANCODE_KP_ENTER, XK_KP_Enter, 0 }, + }; + int best_distance; + int best_index; + int distance; + Bool xkb_repeat = 0; + +#ifdef SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM + { + int xkb_major = XkbMajorVersion; + int xkb_minor = XkbMinorVersion; + + if (X11_XkbQueryExtension(data->display, NULL, &data->xkb_event, NULL, &xkb_major, &xkb_minor)) { + data->xkb = X11_XkbGetMap(data->display, XkbAllClientInfoMask, XkbUseCoreKbd); + } + + /* This will remove KeyRelease events for held keys */ + X11_XkbSetDetectableAutoRepeat(data->display, True, &xkb_repeat); + } +#endif + + /* Open a connection to the X input manager */ +#ifdef X_HAVE_UTF8_STRING + if (SDL_X11_HAVE_UTF8) { + /* Set the locale, and call XSetLocaleModifiers before XOpenIM so that + Compose keys will work correctly. */ + char *prev_locale = setlocale(LC_ALL, NULL); + char *prev_xmods = X11_XSetLocaleModifiers(NULL); + const char *new_xmods = ""; + const char *env_xmods = SDL_getenv("XMODIFIERS"); + SDL_bool has_dbus_ime_support = SDL_FALSE; + + if (prev_locale) { + prev_locale = SDL_strdup(prev_locale); + } + + if (prev_xmods) { + prev_xmods = SDL_strdup(prev_xmods); + } + + /* IBus resends some key events that were filtered by XFilterEvents + when it is used via XIM which causes issues. Prevent this by forcing + @im=none if XMODIFIERS contains @im=ibus. IBus can still be used via + the DBus implementation, which also has support for pre-editing. */ + if (env_xmods && SDL_strstr(env_xmods, "@im=ibus") != NULL) { + has_dbus_ime_support = SDL_TRUE; + } + if (env_xmods && SDL_strstr(env_xmods, "@im=fcitx") != NULL) { + has_dbus_ime_support = SDL_TRUE; + } + if (has_dbus_ime_support || !xkb_repeat) { + new_xmods = "@im=none"; + } + + (void)setlocale(LC_ALL, ""); + X11_XSetLocaleModifiers(new_xmods); + + data->im = X11_XOpenIM(data->display, NULL, data->classname, data->classname); + + /* Reset the locale + X locale modifiers back to how they were, + locale first because the X locale modifiers depend on it. */ + (void)setlocale(LC_ALL, prev_locale); + X11_XSetLocaleModifiers(prev_xmods); + + if (prev_locale) { + SDL_free(prev_locale); + } + + if (prev_xmods) { + SDL_free(prev_xmods); + } + } +#endif + /* Try to determine which scancodes are being used based on fingerprint */ + best_distance = SDL_arraysize(fingerprint) + 1; + best_index = -1; + X11_XDisplayKeycodes(data->display, &min_keycode, &max_keycode); + for (i = 0; i < SDL_arraysize(fingerprint); ++i) { + fingerprint[i].value = X11_XKeysymToKeycode(data->display, fingerprint[i].keysym) - min_keycode; + } + for (i = 0; i < SDL_arraysize(scancode_set); ++i) { + int table_size; + const SDL_Scancode *table = SDL_GetScancodeTable(scancode_set[i], &table_size); + + distance = 0; + for (j = 0; j < SDL_arraysize(fingerprint); ++j) { + if (fingerprint[j].value < 0 || fingerprint[j].value >= table_size) { + distance += 1; + } else if (table[fingerprint[j].value] != fingerprint[j].scancode) { + distance += 1; + } + } + if (distance < best_distance) { + best_distance = distance; + best_index = i; + } + } + if (best_index < 0 || best_distance > 2) { + /* This is likely to be SDL_SCANCODE_TABLE_XFREE86_2 with remapped keys, double check a rarely remapped value */ + int fingerprint_value = X11_XKeysymToKeycode(data->display, 0x1008FF5B /* XF86Documents */) - min_keycode; + if (fingerprint_value == 235) { + for (i = 0; i < SDL_arraysize(scancode_set); ++i) { + if (scancode_set[i] == SDL_SCANCODE_TABLE_XFREE86_2) { + best_index = i; + best_distance = 0; + break; + } + } + } + } + if (best_index >= 0 && best_distance <= 2) { + SDL_Keycode default_keymap[SDL_NUM_SCANCODES]; + int table_size; + const SDL_Scancode *table = SDL_GetScancodeTable(scancode_set[best_index], &table_size); + +#ifdef DEBUG_KEYBOARD + SDL_Log("Using scancode set %d, min_keycode = %d, max_keycode = %d, table_size = %d\n", best_index, min_keycode, max_keycode, table_size); +#endif + /* This should never happen, but just in case... */ + if (table_size > (SDL_arraysize(data->key_layout) - min_keycode)) { + table_size = (SDL_arraysize(data->key_layout) - min_keycode); + } + SDL_memcpy(&data->key_layout[min_keycode], table, sizeof(SDL_Scancode) * table_size); + + /* Scancodes represent physical locations on the keyboard, unaffected by keyboard mapping. + However, there are a number of extended scancodes that have no standard location, so use + the X11 mapping for all non-character keys. + */ + SDL_GetDefaultKeymap(default_keymap); + + for (i = min_keycode; i <= max_keycode; ++i) { + SDL_Scancode scancode = X11_KeyCodeToSDLScancode(_this, i); +#ifdef DEBUG_KEYBOARD + { + KeySym sym; + sym = X11_KeyCodeToSym(_this, (KeyCode)i, 0); + SDL_Log("code = %d, sym = 0x%X (%s) ", i - min_keycode, + (unsigned int)sym, sym == NoSymbol ? "NoSymbol" : X11_XKeysymToString(sym)); + } +#endif + if (scancode == data->key_layout[i]) { + continue; + } + if (default_keymap[scancode] >= SDLK_SCANCODE_MASK && X11_ScancodeIsRemappable(scancode)) { + /* Not a character key and the scancode is safe to remap */ +#ifdef DEBUG_KEYBOARD + SDL_Log("Changing scancode, was %d (%s), now %d (%s)\n", data->key_layout[i], SDL_GetScancodeName(data->key_layout[i]), scancode, SDL_GetScancodeName(scancode)); +#endif + data->key_layout[i] = scancode; + } + } + } else { +#ifdef DEBUG_SCANCODES + SDL_Log("Keyboard layout unknown, please report the following to the SDL forums/mailing list (https://discourse.libsdl.org/):\n"); +#endif + + /* Determine key_layout - only works on US QWERTY layout */ + for (i = min_keycode; i <= max_keycode; ++i) { + SDL_Scancode scancode = X11_KeyCodeToSDLScancode(_this, i); +#ifdef DEBUG_SCANCODES + { + KeySym sym; + sym = X11_KeyCodeToSym(_this, (KeyCode)i, 0); + SDL_Log("code = %d, sym = 0x%X (%s) ", i - min_keycode, + (unsigned int)sym, sym == NoSymbol ? "NoSymbol" : X11_XKeysymToString(sym)); + } + if (scancode == SDL_SCANCODE_UNKNOWN) { + SDL_Log("scancode not found\n"); + } else { + SDL_Log("scancode = %d (%s)\n", scancode, SDL_GetScancodeName(scancode)); + } +#endif + data->key_layout[i] = scancode; + } + } + + X11_UpdateKeymap(_this, SDL_FALSE); + + SDL_SetScancodeName(SDL_SCANCODE_APPLICATION, "Menu"); + +#ifdef SDL_USE_IME + SDL_IME_Init(); +#endif + + X11_ReconcileKeyboardState(_this); + + return 0; +} + +void X11_UpdateKeymap(_THIS, SDL_bool send_event) +{ + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; + int i; + SDL_Scancode scancode; + SDL_Keycode keymap[SDL_NUM_SCANCODES]; + unsigned char group = 0; + + SDL_GetDefaultKeymap(keymap); + +#ifdef SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM + if (data->xkb) { + XkbStateRec state; + X11_XkbGetUpdatedMap(data->display, XkbAllClientInfoMask, data->xkb); + + if (X11_XkbGetState(data->display, XkbUseCoreKbd, &state) == Success) { + group = state.group; + } + } +#endif + + for (i = 0; i < SDL_arraysize(data->key_layout); i++) { + Uint32 key; + + /* Make sure this is a valid scancode */ + scancode = data->key_layout[i]; + if (scancode == SDL_SCANCODE_UNKNOWN) { + continue; + } + + /* See if there is a UCS keycode for this scancode */ + key = X11_KeyCodeToUcs4(_this, (KeyCode)i, group); + if (key) { + keymap[scancode] = key; + } else { + SDL_Scancode keyScancode = X11_KeyCodeToSDLScancode(_this, (KeyCode)i); + + switch (keyScancode) { + case SDL_SCANCODE_RETURN: + keymap[scancode] = SDLK_RETURN; + break; + case SDL_SCANCODE_ESCAPE: + keymap[scancode] = SDLK_ESCAPE; + break; + case SDL_SCANCODE_BACKSPACE: + keymap[scancode] = SDLK_BACKSPACE; + break; + case SDL_SCANCODE_TAB: + keymap[scancode] = SDLK_TAB; + break; + case SDL_SCANCODE_DELETE: + keymap[scancode] = SDLK_DELETE; + break; + default: + keymap[scancode] = SDL_SCANCODE_TO_KEYCODE(keyScancode); + break; + } + } + } + SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES, send_event); +} + +void X11_QuitKeyboard(_THIS) +{ + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; + +#ifdef SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM + if (data->xkb) { + X11_XkbFreeKeyboard(data->xkb, 0, True); + data->xkb = NULL; + } +#endif + +#ifdef SDL_USE_IME + SDL_IME_Quit(); +#endif +} + +static void X11_ResetXIM(_THIS) +{ +#ifdef X_HAVE_UTF8_STRING + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + int i; + + if (videodata && videodata->windowlist) { + for (i = 0; i < videodata->numwindows; ++i) { + SDL_WindowData *data = videodata->windowlist[i]; + if (data && data->ic) { + /* Clear any partially entered dead keys */ + char *contents = X11_Xutf8ResetIC(data->ic); + if (contents) { + X11_XFree(contents); + } + } + } + } +#endif +} + +void X11_StartTextInput(_THIS) +{ + X11_ResetXIM(_this); +} + +void X11_StopTextInput(_THIS) +{ + X11_ResetXIM(_this); +#ifdef SDL_USE_IME + SDL_IME_Reset(); +#endif +} + +void X11_SetTextInputRect(_THIS, const SDL_Rect *rect) +{ + if (!rect) { + SDL_InvalidParamError("rect"); + return; + } + +#ifdef SDL_USE_IME + SDL_IME_UpdateTextRect(rect); +#endif +} + +SDL_bool X11_HasScreenKeyboardSupport(_THIS) +{ + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + return videodata->is_steam_deck; +} + +void X11_ShowScreenKeyboard(_THIS, SDL_Window *window) +{ + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + + if (videodata->is_steam_deck) { + /* For more documentation of the URL parameters, see: + * https://partner.steamgames.com/doc/api/ISteamUtils#ShowFloatingGamepadTextInput + */ + char deeplink[128]; + (void)SDL_snprintf(deeplink, sizeof(deeplink), + "steam://open/keyboard?XPosition=0&YPosition=0&Width=0&Height=0&Mode=%d", + SDL_GetHintBoolean(SDL_HINT_RETURN_KEY_HIDES_IME, SDL_FALSE) ? 0 : 1); + SDL_OpenURL(deeplink); + videodata->steam_keyboard_open = SDL_TRUE; + } +} + +void X11_HideScreenKeyboard(_THIS, SDL_Window *window) +{ + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + + if (videodata->is_steam_deck) { + SDL_OpenURL("steam://close/keyboard"); + videodata->steam_keyboard_open = SDL_FALSE; + } +} + +SDL_bool X11_IsScreenKeyboardShown(_THIS, SDL_Window *window) +{ + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + + return videodata->steam_keyboard_open; +} + +#endif /* SDL_VIDEO_DRIVER_X11 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/x11/SDL_x11keyboard.h b/SDL2-2.30.5/src/video/x11/SDL_x11keyboard.h similarity index 74% rename from SDL2-2.0.12/src/video/x11/SDL_x11keyboard.h rename to SDL2-2.30.5/src/video/x11/SDL_x11keyboard.h index a894375..53cf512 100644 --- a/SDL2-2.0.12/src/video/x11/SDL_x11keyboard.h +++ b/SDL2-2.30.5/src/video/x11/SDL_x11keyboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -24,11 +24,15 @@ #define SDL_x11keyboard_h_ extern int X11_InitKeyboard(_THIS); -extern void X11_UpdateKeymap(_THIS); +extern void X11_UpdateKeymap(_THIS, SDL_bool send_event); extern void X11_QuitKeyboard(_THIS); extern void X11_StartTextInput(_THIS); extern void X11_StopTextInput(_THIS); -extern void X11_SetTextInputRect(_THIS, SDL_Rect *rect); +extern void X11_SetTextInputRect(_THIS, const SDL_Rect *rect); +extern SDL_bool X11_HasScreenKeyboardSupport(_THIS); +extern void X11_ShowScreenKeyboard(_THIS, SDL_Window *window); +extern void X11_HideScreenKeyboard(_THIS, SDL_Window *window); +extern SDL_bool X11_IsScreenKeyboardShown(_THIS, SDL_Window *window); extern KeySym X11_KeyCodeToSym(_THIS, KeyCode, unsigned char group); #endif /* SDL_x11keyboard_h_ */ diff --git a/SDL2-2.30.5/src/video/x11/SDL_x11messagebox.c b/SDL2-2.30.5/src/video/x11/SDL_x11messagebox.c new file mode 100644 index 0000000..0e3b67a --- /dev/null +++ b/SDL2-2.30.5/src/video/x11/SDL_x11messagebox.c @@ -0,0 +1,859 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_X11 + +#include "SDL.h" +#include "SDL_x11video.h" +#include "SDL_x11dyn.h" +#include "SDL_x11messagebox.h" + +#include +#include + +#define SDL_FORK_MESSAGEBOX 1 +#define SDL_SET_LOCALE 1 + +#if SDL_FORK_MESSAGEBOX +#include +#include +#include +#include +#endif + +#define MAX_BUTTONS 8 /* Maximum number of buttons supported */ +#define MIN_BUTTON_WIDTH 64 /* Minimum button width */ +#define MIN_DIALOG_WIDTH 200 /* Minimum dialog width */ +#define MIN_DIALOG_HEIGHT 100 /* Minimum dialog height */ + +static const char g_MessageBoxFontLatin1[] = "-*-*-medium-r-normal--0-120-*-*-p-0-iso8859-1"; +static const char g_MessageBoxFont[] = "-*-*-medium-r-normal--*-120-*-*-*-*-*-*"; + +static const SDL_MessageBoxColor g_default_colors[SDL_MESSAGEBOX_COLOR_MAX] = { + { 56, 54, 53 }, /* SDL_MESSAGEBOX_COLOR_BACKGROUND, */ + { 209, 207, 205 }, /* SDL_MESSAGEBOX_COLOR_TEXT, */ + { 140, 135, 129 }, /* SDL_MESSAGEBOX_COLOR_BUTTON_BORDER, */ + { 105, 102, 99 }, /* SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND, */ + { 205, 202, 53 }, /* SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED, */ +}; + +#define SDL_MAKE_RGB(_r, _g, _b) (((Uint32)(_r) << 16) | \ + ((Uint32)(_g) << 8) | \ + ((Uint32)(_b))) + +typedef struct SDL_MessageBoxButtonDataX11 +{ + int x, y; /* Text position */ + int length; /* Text length */ + int text_width; /* Text width */ + + SDL_Rect rect; /* Rectangle for entire button */ + + const SDL_MessageBoxButtonData *buttondata; /* Button data from caller */ +} SDL_MessageBoxButtonDataX11; + +typedef struct TextLineData +{ + int width; /* Width of this text line */ + int length; /* String length of this text line */ + const char *text; /* Text for this line */ +} TextLineData; + +typedef struct SDL_MessageBoxDataX11 +{ + Display *display; + int screen; + Window window; +#ifdef SDL_VIDEO_DRIVER_X11_XDBE + XdbeBackBuffer buf; + SDL_bool xdbe; /* Whether Xdbe is present or not */ +#endif + long event_mask; + Atom wm_protocols; + Atom wm_delete_message; + + int dialog_width; /* Dialog box width. */ + int dialog_height; /* Dialog box height. */ + + XFontSet font_set; /* for UTF-8 systems */ + XFontStruct *font_struct; /* Latin1 (ASCII) fallback. */ + int xtext, ytext; /* Text position to start drawing at. */ + int numlines; /* Count of Text lines. */ + int text_height; /* Height for text lines. */ + TextLineData *linedata; + + int *pbuttonid; /* Pointer to user return buttonid value. */ + + int button_press_index; /* Index into buttondata/buttonpos for button which is pressed (or -1). */ + int mouse_over_index; /* Index into buttondata/buttonpos for button mouse is over (or -1). */ + + int numbuttons; /* Count of buttons. */ + const SDL_MessageBoxButtonData *buttondata; + SDL_MessageBoxButtonDataX11 buttonpos[MAX_BUTTONS]; + + Uint32 color[SDL_MESSAGEBOX_COLOR_MAX]; + + const SDL_MessageBoxData *messageboxdata; +} SDL_MessageBoxDataX11; + +/* Maximum helper for ints. */ +static SDL_INLINE int IntMax(int a, int b) +{ + return (a > b) ? a : b; +} + +/* Return width and height for a string. */ +static void GetTextWidthHeight(SDL_MessageBoxDataX11 *data, const char *str, int nbytes, int *pwidth, int *pheight) +{ + if (SDL_X11_HAVE_UTF8) { + XRectangle overall_ink, overall_logical; + X11_Xutf8TextExtents(data->font_set, str, nbytes, &overall_ink, &overall_logical); + *pwidth = overall_logical.width; + *pheight = overall_logical.height; + } else { + XCharStruct text_structure; + int font_direction, font_ascent, font_descent; + X11_XTextExtents(data->font_struct, str, nbytes, + &font_direction, &font_ascent, &font_descent, + &text_structure); + *pwidth = text_structure.width; + *pheight = text_structure.ascent + text_structure.descent; + } +} + +/* Return index of button if position x,y is contained therein. */ +static int GetHitButtonIndex(SDL_MessageBoxDataX11 *data, int x, int y) +{ + int i; + int numbuttons = data->numbuttons; + SDL_MessageBoxButtonDataX11 *buttonpos = data->buttonpos; + + for (i = 0; i < numbuttons; i++) { + SDL_Rect *rect = &buttonpos[i].rect; + + if ((x >= rect->x) && + (x <= (rect->x + rect->w)) && + (y >= rect->y) && + (y <= (rect->y + rect->h))) { + return i; + } + } + + return -1; +} + +/* Initialize SDL_MessageBoxData structure and Display, etc. */ +static int X11_MessageBoxInit(SDL_MessageBoxDataX11 *data, const SDL_MessageBoxData *messageboxdata, int *pbuttonid) +{ + int i; + int numbuttons = messageboxdata->numbuttons; + const SDL_MessageBoxButtonData *buttondata = messageboxdata->buttons; + const SDL_MessageBoxColor *colorhints; + + if (numbuttons > MAX_BUTTONS) { + return SDL_SetError("Too many buttons (%d max allowed)", MAX_BUTTONS); + } + + data->dialog_width = MIN_DIALOG_WIDTH; + data->dialog_height = MIN_DIALOG_HEIGHT; + data->messageboxdata = messageboxdata; + data->buttondata = buttondata; + data->numbuttons = numbuttons; + data->pbuttonid = pbuttonid; + + data->display = X11_XOpenDisplay(NULL); + if (!data->display) { + return SDL_SetError("Couldn't open X11 display"); + } + + if (SDL_X11_HAVE_UTF8) { + char **missing = NULL; + int num_missing = 0; + data->font_set = X11_XCreateFontSet(data->display, g_MessageBoxFont, + &missing, &num_missing, NULL); + if (missing) { + X11_XFreeStringList(missing); + } + if (!data->font_set) { + return SDL_SetError("Couldn't load font %s", g_MessageBoxFont); + } + } else { + data->font_struct = X11_XLoadQueryFont(data->display, g_MessageBoxFontLatin1); + if (!data->font_struct) { + return SDL_SetError("Couldn't load font %s", g_MessageBoxFontLatin1); + } + } + + if (messageboxdata->colorScheme) { + colorhints = messageboxdata->colorScheme->colors; + } else { + colorhints = g_default_colors; + } + + /* Convert our SDL_MessageBoxColor r,g,b values to packed RGB format. */ + for (i = 0; i < SDL_MESSAGEBOX_COLOR_MAX; i++) { + data->color[i] = SDL_MAKE_RGB(colorhints[i].r, colorhints[i].g, colorhints[i].b); + } + + return 0; +} + +static int CountLinesOfText(const char *text) +{ + int retval = 0; + while (text && *text) { + const char *lf = SDL_strchr(text, '\n'); + retval++; /* even without an endline, this counts as a line. */ + text = lf ? lf + 1 : NULL; + } + return retval; +} + +/* Calculate and initialize text and button locations. */ +static int X11_MessageBoxInitPositions(SDL_MessageBoxDataX11 *data) +{ + int i; + int ybuttons; + int text_width_max = 0; + int button_text_height = 0; + int button_width = MIN_BUTTON_WIDTH; + const SDL_MessageBoxData *messageboxdata = data->messageboxdata; + + /* Go over text and break linefeeds into separate lines. */ + if (messageboxdata && messageboxdata->message[0]) { + const char *text = messageboxdata->message; + const int linecount = CountLinesOfText(text); + TextLineData *plinedata = (TextLineData *)SDL_malloc(sizeof(TextLineData) * linecount); + + if (!plinedata) { + return SDL_OutOfMemory(); + } + + data->linedata = plinedata; + data->numlines = linecount; + + for (i = 0; i < linecount; i++, plinedata++) { + const char *lf = SDL_strchr(text, '\n'); + const int length = lf ? (lf - text) : SDL_strlen(text); + int height; + + plinedata->text = text; + + GetTextWidthHeight(data, text, length, &plinedata->width, &height); + + /* Text and widths are the largest we've ever seen. */ + data->text_height = IntMax(data->text_height, height); + text_width_max = IntMax(text_width_max, plinedata->width); + + plinedata->length = length; + if (lf && (lf > text) && (lf[-1] == '\r')) { + plinedata->length--; + } + + text += length + 1; + + /* Break if there are no more linefeeds. */ + if (!lf) { + break; + } + } + + /* Bump up the text height slightly. */ + data->text_height += 2; + } + + /* Loop through all buttons and calculate the button widths and height. */ + for (i = 0; i < data->numbuttons; i++) { + int height; + + data->buttonpos[i].buttondata = &data->buttondata[i]; + data->buttonpos[i].length = SDL_strlen(data->buttondata[i].text); + + GetTextWidthHeight(data, data->buttondata[i].text, SDL_strlen(data->buttondata[i].text), + &data->buttonpos[i].text_width, &height); + + button_width = IntMax(button_width, data->buttonpos[i].text_width); + button_text_height = IntMax(button_text_height, height); + } + + if (data->numlines) { + /* x,y for this line of text. */ + data->xtext = data->text_height; + data->ytext = data->text_height + data->text_height; + + /* Bump button y down to bottom of text. */ + ybuttons = 3 * data->ytext / 2 + (data->numlines - 1) * data->text_height; + + /* Bump the dialog box width and height up if needed. */ + data->dialog_width = IntMax(data->dialog_width, 2 * data->xtext + text_width_max); + data->dialog_height = IntMax(data->dialog_height, ybuttons); + } else { + /* Button y starts at height of button text. */ + ybuttons = button_text_height; + } + + if (data->numbuttons) { + int x, y; + int width_of_buttons; + int button_spacing = button_text_height; + int button_height = 2 * button_text_height; + + /* Bump button width up a bit. */ + button_width += button_text_height; + + /* Get width of all buttons lined up. */ + width_of_buttons = data->numbuttons * button_width + (data->numbuttons - 1) * button_spacing; + + /* Bump up dialog width and height if buttons are wider than text. */ + data->dialog_width = IntMax(data->dialog_width, width_of_buttons + 2 * button_spacing); + data->dialog_height = IntMax(data->dialog_height, ybuttons + 2 * button_height); + + /* Location for first button. */ + if (messageboxdata->flags & SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT) { + x = data->dialog_width - (data->dialog_width - width_of_buttons) / 2 - (button_width + button_spacing); + } else { + x = (data->dialog_width - width_of_buttons) / 2; + } + y = ybuttons + (data->dialog_height - ybuttons - button_height) / 2; + + for (i = 0; i < data->numbuttons; i++) { + /* Button coordinates. */ + data->buttonpos[i].rect.x = x; + data->buttonpos[i].rect.y = y; + data->buttonpos[i].rect.w = button_width; + data->buttonpos[i].rect.h = button_height; + + /* Button text coordinates. */ + data->buttonpos[i].x = x + (button_width - data->buttonpos[i].text_width) / 2; + data->buttonpos[i].y = y + (button_height - button_text_height - 1) / 2 + button_text_height; + + /* Scoot over for next button. */ + if (messageboxdata->flags & SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT) { + x -= button_width + button_spacing; + } else { + x += button_width + button_spacing; + } + } + } + + return 0; +} + +/* Free SDL_MessageBoxData data. */ +static void X11_MessageBoxShutdown(SDL_MessageBoxDataX11 *data) +{ + if (data->font_set) { + X11_XFreeFontSet(data->display, data->font_set); + data->font_set = NULL; + } + + if (data->font_struct) { + X11_XFreeFont(data->display, data->font_struct); + data->font_struct = NULL; + } + +#ifdef SDL_VIDEO_DRIVER_X11_XDBE + if (SDL_X11_HAVE_XDBE && data->xdbe) { + X11_XdbeDeallocateBackBufferName(data->display, data->buf); + } +#endif + + if (data->display) { + if (data->window != None) { + X11_XWithdrawWindow(data->display, data->window, data->screen); + X11_XDestroyWindow(data->display, data->window); + data->window = None; + } + + X11_XCloseDisplay(data->display); + data->display = NULL; + } + + SDL_free(data->linedata); +} + +/* Create and set up our X11 dialog box indow. */ +static int X11_MessageBoxCreateWindow(SDL_MessageBoxDataX11 *data) +{ + int x, y; + XSizeHints *sizehints; + XSetWindowAttributes wnd_attr; + Atom _NET_WM_WINDOW_TYPE, _NET_WM_WINDOW_TYPE_DIALOG; + Display *display = data->display; + SDL_WindowData *windowdata = NULL; + const SDL_MessageBoxData *messageboxdata = data->messageboxdata; + + if (messageboxdata->window) { + SDL_DisplayData *displaydata = + (SDL_DisplayData *)SDL_GetDisplayForWindow(messageboxdata->window)->driverdata; + windowdata = (SDL_WindowData *)messageboxdata->window->driverdata; + data->screen = displaydata->screen; + } else { + data->screen = DefaultScreen(display); + } + + data->event_mask = ExposureMask | + ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask | + StructureNotifyMask | FocusChangeMask | PointerMotionMask; + wnd_attr.event_mask = data->event_mask; + + data->window = X11_XCreateWindow( + display, RootWindow(display, data->screen), + 0, 0, + data->dialog_width, data->dialog_height, + 0, CopyFromParent, InputOutput, CopyFromParent, + CWEventMask, &wnd_attr); + if (data->window == None) { + return SDL_SetError("Couldn't create X window"); + } + + if (windowdata) { + Atom _NET_WM_STATE = X11_XInternAtom(display, "_NET_WM_STATE", False); + Atom stateatoms[16]; + size_t statecount = 0; + /* Set some message-boxy window states when attached to a parent window... */ + /* we skip the taskbar since this will pop to the front when the parent window is clicked in the taskbar, etc */ + stateatoms[statecount++] = X11_XInternAtom(display, "_NET_WM_STATE_SKIP_TASKBAR", False); + stateatoms[statecount++] = X11_XInternAtom(display, "_NET_WM_STATE_SKIP_PAGER", False); + stateatoms[statecount++] = X11_XInternAtom(display, "_NET_WM_STATE_FOCUSED", False); + stateatoms[statecount++] = X11_XInternAtom(display, "_NET_WM_STATE_MODAL", False); + SDL_assert(statecount <= SDL_arraysize(stateatoms)); + X11_XChangeProperty(display, data->window, _NET_WM_STATE, XA_ATOM, 32, + PropModeReplace, (unsigned char *)stateatoms, statecount); + + /* http://tronche.com/gui/x/icccm/sec-4.html#WM_TRANSIENT_FOR */ + X11_XSetTransientForHint(display, data->window, windowdata->xwindow); + } + + SDL_X11_SetWindowTitle(display, data->window, (char *)messageboxdata->title); + + /* Let the window manager know this is a dialog box */ + _NET_WM_WINDOW_TYPE = X11_XInternAtom(display, "_NET_WM_WINDOW_TYPE", False); + _NET_WM_WINDOW_TYPE_DIALOG = X11_XInternAtom(display, "_NET_WM_WINDOW_TYPE_DIALOG", False); + X11_XChangeProperty(display, data->window, _NET_WM_WINDOW_TYPE, XA_ATOM, 32, + PropModeReplace, + (unsigned char *)&_NET_WM_WINDOW_TYPE_DIALOG, 1); + + /* Allow the window to be deleted by the window manager */ + data->wm_protocols = X11_XInternAtom(display, "WM_PROTOCOLS", False); + data->wm_delete_message = X11_XInternAtom(display, "WM_DELETE_WINDOW", False); + X11_XSetWMProtocols(display, data->window, &data->wm_delete_message, 1); + + if (windowdata) { + XWindowAttributes attrib; + Window dummy; + + X11_XGetWindowAttributes(display, windowdata->xwindow, &attrib); + x = attrib.x + (attrib.width - data->dialog_width) / 2; + y = attrib.y + (attrib.height - data->dialog_height) / 3; + X11_XTranslateCoordinates(display, windowdata->xwindow, RootWindow(display, data->screen), x, y, &x, &y, &dummy); + } else { + const SDL_VideoDevice *dev = SDL_GetVideoDevice(); + if ((dev) && (dev->displays) && (dev->num_displays > 0)) { + const SDL_VideoDisplay *dpy = &dev->displays[0]; + const SDL_DisplayData *dpydata = (SDL_DisplayData *)dpy->driverdata; + x = dpydata->x + ((dpy->current_mode.w - data->dialog_width) / 2); + y = dpydata->y + ((dpy->current_mode.h - data->dialog_height) / 3); + } else { /* oh well. This will misposition on a multi-head setup. Init first next time. */ + x = (DisplayWidth(display, data->screen) - data->dialog_width) / 2; + y = (DisplayHeight(display, data->screen) - data->dialog_height) / 3; + } + } + X11_XMoveWindow(display, data->window, x, y); + + sizehints = X11_XAllocSizeHints(); + if (sizehints) { + sizehints->flags = USPosition | USSize | PMaxSize | PMinSize; + sizehints->x = x; + sizehints->y = y; + sizehints->width = data->dialog_width; + sizehints->height = data->dialog_height; + + sizehints->min_width = sizehints->max_width = data->dialog_width; + sizehints->min_height = sizehints->max_height = data->dialog_height; + + X11_XSetWMNormalHints(display, data->window, sizehints); + + X11_XFree(sizehints); + } + + X11_XMapRaised(display, data->window); + +#ifdef SDL_VIDEO_DRIVER_X11_XDBE + /* Initialise a back buffer for double buffering */ + if (SDL_X11_HAVE_XDBE) { + int xdbe_major, xdbe_minor; + if (X11_XdbeQueryExtension(display, &xdbe_major, &xdbe_minor) != 0) { + data->xdbe = SDL_TRUE; + data->buf = X11_XdbeAllocateBackBufferName(display, data->window, XdbeUndefined); + } else { + data->xdbe = SDL_FALSE; + } + } +#endif + + return 0; +} + +/* Draw our message box. */ +static void X11_MessageBoxDraw(SDL_MessageBoxDataX11 *data, GC ctx) +{ + int i; + Drawable window = data->window; + Display *display = data->display; + +#ifdef SDL_VIDEO_DRIVER_X11_XDBE + if (SDL_X11_HAVE_XDBE && data->xdbe) { + window = data->buf; + X11_XdbeBeginIdiom(data->display); + } +#endif + + X11_XSetForeground(display, ctx, data->color[SDL_MESSAGEBOX_COLOR_BACKGROUND]); + X11_XFillRectangle(display, window, ctx, 0, 0, data->dialog_width, data->dialog_height); + + X11_XSetForeground(display, ctx, data->color[SDL_MESSAGEBOX_COLOR_TEXT]); + for (i = 0; i < data->numlines; i++) { + TextLineData *plinedata = &data->linedata[i]; + + if (SDL_X11_HAVE_UTF8) { + X11_Xutf8DrawString(display, window, data->font_set, ctx, + data->xtext, data->ytext + i * data->text_height, + plinedata->text, plinedata->length); + } else { + X11_XDrawString(display, window, ctx, + data->xtext, data->ytext + i * data->text_height, + plinedata->text, plinedata->length); + } + } + + for (i = 0; i < data->numbuttons; i++) { + SDL_MessageBoxButtonDataX11 *buttondatax11 = &data->buttonpos[i]; + const SDL_MessageBoxButtonData *buttondata = buttondatax11->buttondata; + int border = (buttondata->flags & SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT) ? 2 : 0; + int offset = ((data->mouse_over_index == i) && (data->button_press_index == data->mouse_over_index)) ? 1 : 0; + + X11_XSetForeground(display, ctx, data->color[SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND]); + X11_XFillRectangle(display, window, ctx, + buttondatax11->rect.x - border, buttondatax11->rect.y - border, + buttondatax11->rect.w + 2 * border, buttondatax11->rect.h + 2 * border); + + X11_XSetForeground(display, ctx, data->color[SDL_MESSAGEBOX_COLOR_BUTTON_BORDER]); + X11_XDrawRectangle(display, window, ctx, + buttondatax11->rect.x, buttondatax11->rect.y, + buttondatax11->rect.w, buttondatax11->rect.h); + + X11_XSetForeground(display, ctx, (data->mouse_over_index == i) ? data->color[SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED] : data->color[SDL_MESSAGEBOX_COLOR_TEXT]); + + if (SDL_X11_HAVE_UTF8) { + X11_Xutf8DrawString(display, window, data->font_set, ctx, + buttondatax11->x + offset, + buttondatax11->y + offset, + buttondata->text, buttondatax11->length); + } else { + X11_XDrawString(display, window, ctx, + buttondatax11->x + offset, buttondatax11->y + offset, + buttondata->text, buttondatax11->length); + } + } + +#ifdef SDL_VIDEO_DRIVER_X11_XDBE + if (SDL_X11_HAVE_XDBE && data->xdbe) { + XdbeSwapInfo swap_info; + swap_info.swap_window = data->window; + swap_info.swap_action = XdbeUndefined; + X11_XdbeSwapBuffers(data->display, &swap_info, 1); + X11_XdbeEndIdiom(data->display); + } +#endif +} + +/* NOLINTNEXTLINE(readability-non-const-parameter): cannot make XPointer a const pointer due to typedef */ +static Bool X11_MessageBoxEventTest(Display *display, XEvent *event, XPointer arg) +{ + const SDL_MessageBoxDataX11 *data = (const SDL_MessageBoxDataX11 *)arg; + return ((event->xany.display == data->display) && (event->xany.window == data->window)) ? True : False; +} + +/* Loop and handle message box event messages until something kills it. */ +static int X11_MessageBoxLoop(SDL_MessageBoxDataX11 *data) +{ + GC ctx; + XGCValues ctx_vals; + SDL_bool close_dialog = SDL_FALSE; + SDL_bool has_focus = SDL_TRUE; + KeySym last_key_pressed = XK_VoidSymbol; + unsigned long gcflags = GCForeground | GCBackground; + + SDL_zero(ctx_vals); + ctx_vals.foreground = data->color[SDL_MESSAGEBOX_COLOR_BACKGROUND]; + ctx_vals.background = data->color[SDL_MESSAGEBOX_COLOR_BACKGROUND]; + + if (!SDL_X11_HAVE_UTF8) { + gcflags |= GCFont; + ctx_vals.font = data->font_struct->fid; + } + + ctx = X11_XCreateGC(data->display, data->window, gcflags, &ctx_vals); + if (ctx == None) { + return SDL_SetError("Couldn't create graphics context"); + } + + data->button_press_index = -1; /* Reset what button is currently depressed. */ + data->mouse_over_index = -1; /* Reset what button the mouse is over. */ + + while (!close_dialog) { + XEvent e; + SDL_bool draw = SDL_TRUE; + + /* can't use XWindowEvent() because it can't handle ClientMessage events. */ + /* can't use XNextEvent() because we only want events for this window. */ + X11_XIfEvent(data->display, &e, X11_MessageBoxEventTest, (XPointer)data); + + /* If X11_XFilterEvent returns True, then some input method has filtered the + event, and the client should discard the event. */ + if ((e.type != Expose) && X11_XFilterEvent(&e, None)) { + continue; + } + + switch (e.type) { + case Expose: + if (e.xexpose.count > 0) { + draw = SDL_FALSE; + } + break; + + case FocusIn: + /* Got focus. */ + has_focus = SDL_TRUE; + break; + + case FocusOut: + /* lost focus. Reset button and mouse info. */ + has_focus = SDL_FALSE; + data->button_press_index = -1; + data->mouse_over_index = -1; + break; + + case MotionNotify: + if (has_focus) { + /* Mouse moved... */ + const int previndex = data->mouse_over_index; + data->mouse_over_index = GetHitButtonIndex(data, e.xbutton.x, e.xbutton.y); + if (data->mouse_over_index == previndex) { + draw = SDL_FALSE; + } + } + break; + + case ClientMessage: + if (e.xclient.message_type == data->wm_protocols && + e.xclient.format == 32 && + e.xclient.data.l[0] == data->wm_delete_message) { + close_dialog = SDL_TRUE; + } + break; + + case KeyPress: + /* Store key press - we make sure in key release that we got both. */ + last_key_pressed = X11_XLookupKeysym(&e.xkey, 0); + break; + + case KeyRelease: + { + Uint32 mask = 0; + KeySym key = X11_XLookupKeysym(&e.xkey, 0); + + /* If this is a key release for something we didn't get the key down for, then bail. */ + if (key != last_key_pressed) { + break; + } + + if (key == XK_Escape) { + mask = SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT; + } else if ((key == XK_Return) || (key == XK_KP_Enter)) { + mask = SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT; + } + + if (mask) { + int i; + + /* Look for first button with this mask set, and return it if found. */ + for (i = 0; i < data->numbuttons; i++) { + SDL_MessageBoxButtonDataX11 *buttondatax11 = &data->buttonpos[i]; + + if (buttondatax11->buttondata->flags & mask) { + *data->pbuttonid = buttondatax11->buttondata->buttonid; + close_dialog = SDL_TRUE; + break; + } + } + } + break; + } + + case ButtonPress: + data->button_press_index = -1; + if (e.xbutton.button == Button1) { + /* Find index of button they clicked on. */ + data->button_press_index = GetHitButtonIndex(data, e.xbutton.x, e.xbutton.y); + } + break; + + case ButtonRelease: + /* If button is released over the same button that was clicked down on, then return it. */ + if ((e.xbutton.button == Button1) && (data->button_press_index >= 0)) { + int button = GetHitButtonIndex(data, e.xbutton.x, e.xbutton.y); + + if (data->button_press_index == button) { + SDL_MessageBoxButtonDataX11 *buttondatax11 = &data->buttonpos[button]; + + *data->pbuttonid = buttondatax11->buttondata->buttonid; + close_dialog = SDL_TRUE; + } + } + data->button_press_index = -1; + break; + } + + if (draw) { + /* Draw our dialog box. */ + X11_MessageBoxDraw(data, ctx); + } + } + + X11_XFreeGC(data->display, ctx); + return 0; +} + +static int X11_ShowMessageBoxImpl(const SDL_MessageBoxData *messageboxdata, int *buttonid) +{ + int ret; + SDL_MessageBoxDataX11 data; +#if SDL_SET_LOCALE + char *origlocale; +#endif + + SDL_zero(data); + + if (!SDL_X11_LoadSymbols()) { + return -1; + } + +#if SDL_SET_LOCALE + origlocale = setlocale(LC_ALL, NULL); + if (origlocale) { + origlocale = SDL_strdup(origlocale); + if (!origlocale) { + return SDL_OutOfMemory(); + } + (void)setlocale(LC_ALL, ""); + } +#endif + + /* This code could get called from multiple threads maybe? */ + X11_XInitThreads(); + + /* Initialize the return buttonid value to -1 (for error or dialogbox closed). */ + *buttonid = -1; + + /* Init and display the message box. */ + ret = X11_MessageBoxInit(&data, messageboxdata, buttonid); + if (ret != -1) { + ret = X11_MessageBoxInitPositions(&data); + if (ret != -1) { + ret = X11_MessageBoxCreateWindow(&data); + if (ret != -1) { + ret = X11_MessageBoxLoop(&data); + } + } + } + + X11_MessageBoxShutdown(&data); + +#if SDL_SET_LOCALE + if (origlocale) { + (void)setlocale(LC_ALL, origlocale); + SDL_free(origlocale); + } +#endif + + return ret; +} + +/* Display an x11 message box. */ +int X11_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) +{ +#if SDL_FORK_MESSAGEBOX + /* Use a child process to protect against setlocale(). Annoying. */ + pid_t pid; + int fds[2]; + int status = 0; + + if (pipe(fds) == -1) { + return X11_ShowMessageBoxImpl(messageboxdata, buttonid); /* oh well. */ + } + + pid = fork(); + if (pid == -1) { /* failed */ + close(fds[0]); + close(fds[1]); + return X11_ShowMessageBoxImpl(messageboxdata, buttonid); /* oh well. */ + } else if (pid == 0) { /* we're the child */ + int exitcode = 0; + close(fds[0]); + status = X11_ShowMessageBoxImpl(messageboxdata, buttonid); + if (write(fds[1], &status, sizeof(int)) != sizeof(int)) { + exitcode = 1; + } else if (write(fds[1], buttonid, sizeof(int)) != sizeof(int)) { + exitcode = 1; + } + close(fds[1]); + _exit(exitcode); /* don't run atexit() stuff, static destructors, etc. */ + } else { /* we're the parent */ + pid_t rc; + close(fds[1]); + do { + rc = waitpid(pid, &status, 0); + } while ((rc == -1) && (errno == EINTR)); + + SDL_assert(rc == pid); /* not sure what to do if this fails. */ + + if ((rc == -1) || (!WIFEXITED(status)) || (WEXITSTATUS(status) != 0)) { + status = SDL_SetError("msgbox child process failed"); + } else if ((read(fds[0], &status, sizeof(int)) != sizeof(int)) || + (read(fds[0], buttonid, sizeof(int)) != sizeof(int))) { + status = SDL_SetError("read from msgbox child process failed"); + *buttonid = 0; + } + close(fds[0]); + + return status; + } +#else + return X11_ShowMessageBoxImpl(messageboxdata, buttonid); +#endif +} +#endif /* SDL_VIDEO_DRIVER_X11 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/x11/SDL_x11messagebox.h b/SDL2-2.30.5/src/video/x11/SDL_x11messagebox.h similarity index 92% rename from SDL2-2.0.12/src/video/x11/SDL_x11messagebox.h rename to SDL2-2.30.5/src/video/x11/SDL_x11messagebox.h index 1fd91e4..1675979 100644 --- a/SDL2-2.0.12/src/video/x11/SDL_x11messagebox.h +++ b/SDL2-2.30.5/src/video/x11/SDL_x11messagebox.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -22,7 +22,7 @@ #ifndef SDL_x11messagebox_h_ #define SDL_x11messagebox_h_ -#if SDL_VIDEO_DRIVER_X11 +#ifdef SDL_VIDEO_DRIVER_X11 extern int X11_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid); diff --git a/SDL2-2.30.5/src/video/x11/SDL_x11modes.c b/SDL2-2.30.5/src/video/x11/SDL_x11modes.c new file mode 100644 index 0000000..35c02e3 --- /dev/null +++ b/SDL2-2.30.5/src/video/x11/SDL_x11modes.c @@ -0,0 +1,895 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_X11 + +#include "SDL_hints.h" +#include "SDL_x11video.h" +#include "SDL_timer.h" +#include "edid.h" + +/* #define X11MODES_DEBUG */ + +/* I'm becoming more and more convinced that the application should never + * use XRandR, and it's the window manager's responsibility to track and + * manage display modes for fullscreen windows. Right now XRandR is completely + * broken with respect to window manager behavior on every window manager that + * I can find. For example, on Unity 3D if you show a fullscreen window while + * the resolution is changing (within ~250 ms) your window will retain the + * fullscreen state hint but be decorated and windowed. + * + * However, many people swear by it, so let them swear at it. :) + */ +/* #define XRANDR_DISABLED_BY_DEFAULT */ + +static int get_visualinfo(Display *display, int screen, XVisualInfo *vinfo) +{ + const char *visual_id = SDL_getenv("SDL_VIDEO_X11_VISUALID"); + int depth; + + /* Look for an exact visual, if requested */ + if (visual_id) { + XVisualInfo *vi, template; + int nvis; + + SDL_zero(template); + template.visualid = SDL_strtol(visual_id, NULL, 0); + vi = X11_XGetVisualInfo(display, VisualIDMask, &template, &nvis); + if (vi) { + *vinfo = *vi; + X11_XFree(vi); + return 0; + } + } + + depth = DefaultDepth(display, screen); + if ((X11_UseDirectColorVisuals() && + X11_XMatchVisualInfo(display, screen, depth, DirectColor, vinfo)) || + X11_XMatchVisualInfo(display, screen, depth, TrueColor, vinfo) || + X11_XMatchVisualInfo(display, screen, depth, PseudoColor, vinfo) || + X11_XMatchVisualInfo(display, screen, depth, StaticColor, vinfo)) { + return 0; + } + return -1; +} + +int X11_GetVisualInfoFromVisual(Display *display, Visual *visual, XVisualInfo *vinfo) +{ + XVisualInfo *vi; + int nvis; + + vinfo->visualid = X11_XVisualIDFromVisual(visual); + vi = X11_XGetVisualInfo(display, VisualIDMask, vinfo, &nvis); + if (vi) { + *vinfo = *vi; + X11_XFree(vi); + return 0; + } + return -1; +} + +Uint32 X11_GetPixelFormatFromVisualInfo(Display *display, XVisualInfo *vinfo) +{ + if (vinfo->class == DirectColor || vinfo->class == TrueColor) { + int bpp; + Uint32 Rmask, Gmask, Bmask, Amask; + + Rmask = vinfo->visual->red_mask; + Gmask = vinfo->visual->green_mask; + Bmask = vinfo->visual->blue_mask; + if (vinfo->depth == 32) { + Amask = (0xFFFFFFFF & ~(Rmask | Gmask | Bmask)); + } else { + Amask = 0; + } + + bpp = vinfo->depth; + if (bpp == 24) { + int i, n; + XPixmapFormatValues *p = X11_XListPixmapFormats(display, &n); + if (p) { + for (i = 0; i < n; ++i) { + if (p[i].depth == 24) { + bpp = p[i].bits_per_pixel; + break; + } + } + X11_XFree(p); + } + } + + return SDL_MasksToPixelFormatEnum(bpp, Rmask, Gmask, Bmask, Amask); + } + + if (vinfo->class == PseudoColor || vinfo->class == StaticColor) { + switch (vinfo->depth) { + case 8: + return SDL_PIXELFORMAT_INDEX8; + case 4: + if (BitmapBitOrder(display) == LSBFirst) { + return SDL_PIXELFORMAT_INDEX4LSB; + } else { + return SDL_PIXELFORMAT_INDEX4MSB; + } + /* break; -Wunreachable-code-break */ + case 1: + if (BitmapBitOrder(display) == LSBFirst) { + return SDL_PIXELFORMAT_INDEX1LSB; + } else { + return SDL_PIXELFORMAT_INDEX1MSB; + } + /* break; -Wunreachable-code-break */ + } + } + + return SDL_PIXELFORMAT_UNKNOWN; +} + +#ifdef SDL_VIDEO_DRIVER_X11_XRANDR +static SDL_bool CheckXRandR(Display *display, int *major, int *minor) +{ + /* Default the extension not available */ + *major = *minor = 0; + + /* Allow environment override */ +#ifdef XRANDR_DISABLED_BY_DEFAULT + if (!SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_XRANDR, SDL_FALSE)) { +#ifdef X11MODES_DEBUG + printf("XRandR disabled by default due to window manager issues\n"); +#endif + return SDL_FALSE; + } +#else + if (!SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_XRANDR, SDL_TRUE)) { +#ifdef X11MODES_DEBUG + printf("XRandR disabled due to hint\n"); +#endif + return SDL_FALSE; + } +#endif /* XRANDR_ENABLED_BY_DEFAULT */ + + if (!SDL_X11_HAVE_XRANDR) { +#ifdef X11MODES_DEBUG + printf("XRandR support not available\n"); +#endif + return SDL_FALSE; + } + + /* Query the extension version */ + *major = 1; + *minor = 3; /* we want 1.3 */ + if (!X11_XRRQueryVersion(display, major, minor)) { +#ifdef X11MODES_DEBUG + printf("XRandR not active on the display\n"); +#endif + *major = *minor = 0; + return SDL_FALSE; + } +#ifdef X11MODES_DEBUG + printf("XRandR available at version %d.%d!\n", *major, *minor); +#endif + return SDL_TRUE; +} + +#define XRANDR_ROTATION_LEFT (1 << 1) +#define XRANDR_ROTATION_RIGHT (1 << 3) + +static int CalculateXRandRRefreshRate(const XRRModeInfo *info) +{ + return (info->hTotal && info->vTotal) ? SDL_round(((double)info->dotClock / (double)(info->hTotal * info->vTotal))) : 0; +} + +static SDL_bool SetXRandRModeInfo(Display *display, XRRScreenResources *res, RRCrtc crtc, + RRMode modeID, SDL_DisplayMode *mode) +{ + int i; + for (i = 0; i < res->nmode; ++i) { + const XRRModeInfo *info = &res->modes[i]; + if (info->id == modeID) { + XRRCrtcInfo *crtcinfo; + Rotation rotation = 0; + + crtcinfo = X11_XRRGetCrtcInfo(display, res, crtc); + if (crtcinfo) { + rotation = crtcinfo->rotation; + X11_XRRFreeCrtcInfo(crtcinfo); + } + + if (rotation & (XRANDR_ROTATION_LEFT | XRANDR_ROTATION_RIGHT)) { + mode->w = info->height; + mode->h = info->width; + } else { + mode->w = info->width; + mode->h = info->height; + } + mode->refresh_rate = CalculateXRandRRefreshRate(info); + ((SDL_DisplayModeData *)mode->driverdata)->xrandr_mode = modeID; +#ifdef X11MODES_DEBUG + printf("XRandR mode %d: %dx%d@%dHz\n", (int)modeID, mode->w, mode->h, mode->refresh_rate); +#endif + return SDL_TRUE; + } + } + return SDL_FALSE; +} + +static void SetXRandRDisplayName(Display *dpy, Atom EDID, char *name, const size_t namelen, RROutput output, const unsigned long widthmm, const unsigned long heightmm) +{ + /* See if we can get the EDID data for the real monitor name */ + int inches; + int nprop; + Atom *props = X11_XRRListOutputProperties(dpy, output, &nprop); + int i; + + for (i = 0; i < nprop; ++i) { + unsigned char *prop; + int actual_format; + unsigned long nitems, bytes_after; + Atom actual_type; + + if (props[i] == EDID) { + if (X11_XRRGetOutputProperty(dpy, output, props[i], 0, 100, False, + False, AnyPropertyType, &actual_type, + &actual_format, &nitems, &bytes_after, + &prop) == Success) { + MonitorInfo *info = decode_edid(prop); + if (info) { +#ifdef X11MODES_DEBUG + printf("Found EDID data for %s\n", name); + dump_monitor_info(info); +#endif + SDL_strlcpy(name, info->dsc_product_name, namelen); + SDL_free(info); + } + X11_XFree(prop); + } + break; + } + } + + if (props) { + X11_XFree(props); + } + + inches = (int)((SDL_sqrtf(widthmm * widthmm + heightmm * heightmm) / 25.4f) + 0.5f); + if (*name && inches) { + const size_t len = SDL_strlen(name); + (void)SDL_snprintf(&name[len], namelen - len, " %d\"", inches); + } + +#ifdef X11MODES_DEBUG + printf("Display name: %s\n", name); +#endif +} + +static int X11_AddXRandRDisplay(_THIS, Display *dpy, int screen, RROutput outputid, XRRScreenResources *res, SDL_bool send_event) +{ + Atom EDID = X11_XInternAtom(dpy, "EDID", False); + XRROutputInfo *output_info; + int display_x, display_y; + unsigned long display_mm_width, display_mm_height; + SDL_DisplayData *displaydata; + char display_name[128]; + SDL_DisplayMode mode; + SDL_DisplayModeData *modedata; + SDL_VideoDisplay display; + RRMode modeID; + RRCrtc output_crtc; + XRRCrtcInfo *crtc; + XVisualInfo vinfo; + Uint32 pixelformat; + XPixmapFormatValues *pixmapformats; + int scanline_pad; + int i, n; + + if (get_visualinfo(dpy, screen, &vinfo) < 0) { + return 0; /* uh, skip this screen? */ + } + + pixelformat = X11_GetPixelFormatFromVisualInfo(dpy, &vinfo); + if (SDL_ISPIXELFORMAT_INDEXED(pixelformat)) { + return 0; /* Palettized video modes are no longer supported, ignore this one. */ + } + + scanline_pad = SDL_BYTESPERPIXEL(pixelformat) * 8; + pixmapformats = X11_XListPixmapFormats(dpy, &n); + if (pixmapformats) { + for (i = 0; i < n; i++) { + if (pixmapformats[i].depth == vinfo.depth) { + scanline_pad = pixmapformats[i].scanline_pad; + break; + } + } + X11_XFree(pixmapformats); + } + + output_info = X11_XRRGetOutputInfo(dpy, res, outputid); + if (!output_info || !output_info->crtc || output_info->connection == RR_Disconnected) { + X11_XRRFreeOutputInfo(output_info); + return 0; /* ignore this one. */ + } + + SDL_strlcpy(display_name, output_info->name, sizeof(display_name)); + display_mm_width = output_info->mm_width; + display_mm_height = output_info->mm_height; + output_crtc = output_info->crtc; + X11_XRRFreeOutputInfo(output_info); + + crtc = X11_XRRGetCrtcInfo(dpy, res, output_crtc); + if (!crtc) { + return 0; /* oh well, ignore it. */ + } + + SDL_zero(mode); + modeID = crtc->mode; + mode.w = crtc->width; + mode.h = crtc->height; + mode.format = pixelformat; + + display_x = crtc->x; + display_y = crtc->y; + + X11_XRRFreeCrtcInfo(crtc); + + displaydata = (SDL_DisplayData *)SDL_calloc(1, sizeof(*displaydata)); + if (!displaydata) { + return SDL_OutOfMemory(); + } + + modedata = (SDL_DisplayModeData *)SDL_calloc(1, sizeof(SDL_DisplayModeData)); + if (!modedata) { + SDL_free(displaydata); + return SDL_OutOfMemory(); + } + + modedata->xrandr_mode = modeID; + mode.driverdata = modedata; + + displaydata->screen = screen; + displaydata->visual = vinfo.visual; + displaydata->depth = vinfo.depth; + displaydata->hdpi = display_mm_width ? (((float)mode.w) * 25.4f / display_mm_width) : 0.0f; + displaydata->vdpi = display_mm_height ? (((float)mode.h) * 25.4f / display_mm_height) : 0.0f; + displaydata->ddpi = SDL_ComputeDiagonalDPI(mode.w, mode.h, ((float)display_mm_width) / 25.4f, ((float)display_mm_height) / 25.4f); + displaydata->scanline_pad = scanline_pad; + displaydata->x = display_x; + displaydata->y = display_y; + displaydata->use_xrandr = SDL_TRUE; + displaydata->xrandr_output = outputid; + + SetXRandRModeInfo(dpy, res, output_crtc, modeID, &mode); + SetXRandRDisplayName(dpy, EDID, display_name, sizeof(display_name), outputid, display_mm_width, display_mm_height); + + SDL_zero(display); + if (*display_name) { + display.name = display_name; + } + display.desktop_mode = mode; + display.current_mode = mode; + display.driverdata = displaydata; + return SDL_AddVideoDisplay(&display, send_event); +} + +static void X11_HandleXRandROutputChange(_THIS, const XRROutputChangeNotifyEvent *ev) +{ + const int num_displays = SDL_GetNumVideoDisplays(); + SDL_VideoDisplay *display = NULL; + int displayidx = -1; + int i; + +#if 0 + printf("XRROutputChangeNotifyEvent! [output=%u, crtc=%u, mode=%u, rotation=%u, connection=%u]", (unsigned int) ev->output, (unsigned int) ev->crtc, (unsigned int) ev->mode, (unsigned int) ev->rotation, (unsigned int) ev->connection); +#endif + + for (i = 0; i < num_displays; i++) { + SDL_VideoDisplay *thisdisplay = SDL_GetDisplay(i); + const SDL_DisplayData *displaydata = (const SDL_DisplayData *)thisdisplay->driverdata; + if (displaydata->xrandr_output == ev->output) { + display = thisdisplay; + displayidx = i; + break; + } + } + + SDL_assert((displayidx == -1) == (display == NULL)); + + if (ev->connection == RR_Disconnected) { /* output is going away */ + if (display) { + SDL_DelVideoDisplay(displayidx); + } + } else if (ev->connection == RR_Connected) { /* output is coming online */ + if (display) { + /* !!! FIXME: update rotation or current mode of existing display? */ + } else { + Display *dpy = ev->display; + const int screen = DefaultScreen(dpy); + XVisualInfo vinfo; + if (get_visualinfo(dpy, screen, &vinfo) == 0) { + XRRScreenResources *res = X11_XRRGetScreenResourcesCurrent(dpy, RootWindow(dpy, screen)); + if (!res || res->noutput == 0) { + if (res) { + X11_XRRFreeScreenResources(res); + } + res = X11_XRRGetScreenResources(dpy, RootWindow(dpy, screen)); + } + + if (res) { + X11_AddXRandRDisplay(_this, dpy, screen, ev->output, res, SDL_TRUE); + X11_XRRFreeScreenResources(res); + } + } + } + } +} + +void X11_HandleXRandREvent(_THIS, const XEvent *xevent) +{ + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; + SDL_assert(xevent->type == (videodata->xrandr_event_base + RRNotify)); + + switch (((const XRRNotifyEvent *)xevent)->subtype) { + case RRNotify_OutputChange: + X11_HandleXRandROutputChange(_this, (const XRROutputChangeNotifyEvent *)xevent); + break; + default: + break; + } +} + +static int X11_InitModes_XRandR(_THIS) +{ + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; + Display *dpy = data->display; + const int screencount = ScreenCount(dpy); + const int default_screen = DefaultScreen(dpy); + RROutput primary = X11_XRRGetOutputPrimary(dpy, RootWindow(dpy, default_screen)); + XRRScreenResources *res = NULL; + int xrandr_error_base = 0; + int looking_for_primary; + int output; + int screen; + + if (!X11_XRRQueryExtension(dpy, &data->xrandr_event_base, &xrandr_error_base)) { + return SDL_SetError("XRRQueryExtension failed"); + } + + for (looking_for_primary = 1; looking_for_primary >= 0; looking_for_primary--) { + for (screen = 0; screen < screencount; screen++) { + + /* we want the primary output first, and then skipped later. */ + if (looking_for_primary && (screen != default_screen)) { + continue; + } + + res = X11_XRRGetScreenResourcesCurrent(dpy, RootWindow(dpy, screen)); + if (!res || res->noutput == 0) { + if (res) { + X11_XRRFreeScreenResources(res); + } + + res = X11_XRRGetScreenResources(dpy, RootWindow(dpy, screen)); + if (!res) { + continue; + } + } + + for (output = 0; output < res->noutput; output++) { + /* The primary output _should_ always be sorted first, but just in case... */ + if ((looking_for_primary && (res->outputs[output] != primary)) || + (!looking_for_primary && (screen == default_screen) && (res->outputs[output] == primary))) { + continue; + } + if (X11_AddXRandRDisplay(_this, dpy, screen, res->outputs[output], res, SDL_FALSE) == -1) { + break; + } + } + + X11_XRRFreeScreenResources(res); + + /* This will generate events for displays that come and go at runtime. */ + X11_XRRSelectInput(dpy, RootWindow(dpy, screen), RROutputChangeNotifyMask); + } + } + + if (_this->num_displays == 0) { + return SDL_SetError("No available displays"); + } + + return 0; +} +#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */ + +static int GetXftDPI(Display *dpy) +{ + char *xdefault_resource; + int xft_dpi, err; + + xdefault_resource = X11_XGetDefault(dpy, "Xft", "dpi"); + + if (!xdefault_resource) { + return 0; + } + + /* + * It's possible for SDL_atoi to call SDL_strtol, if it fails due to a + * overflow or an underflow, it will return LONG_MAX or LONG_MIN and set + * errno to ERANGE. So we need to check for this so we dont get crazy dpi + * values + */ + xft_dpi = SDL_atoi(xdefault_resource); + err = errno; + + return err == ERANGE ? 0 : xft_dpi; +} + +/* This is used if there's no better functionality--like XRandR--to use. + It won't attempt to supply different display modes at all, but it can + enumerate the current displays and their current sizes. */ +static int X11_InitModes_StdXlib(_THIS) +{ + /* !!! FIXME: a lot of copy/paste from X11_InitModes_XRandR in this function. */ + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; + Display *dpy = data->display; + const int default_screen = DefaultScreen(dpy); + Screen *screen = ScreenOfDisplay(dpy, default_screen); + int display_mm_width, display_mm_height, xft_dpi, scanline_pad, n, i; + SDL_DisplayModeData *modedata; + SDL_DisplayData *displaydata; + SDL_DisplayMode mode; + XPixmapFormatValues *pixmapformats; + Uint32 pixelformat; + XVisualInfo vinfo; + SDL_VideoDisplay display; + + /* note that generally even if you have a multiple physical monitors, ScreenCount(dpy) still only reports ONE screen. */ + + if (get_visualinfo(dpy, default_screen, &vinfo) < 0) { + return SDL_SetError("Failed to find an X11 visual for the primary display"); + } + + pixelformat = X11_GetPixelFormatFromVisualInfo(dpy, &vinfo); + if (SDL_ISPIXELFORMAT_INDEXED(pixelformat)) { + return SDL_SetError("Palettized video modes are no longer supported"); + } + + SDL_zero(mode); + mode.w = WidthOfScreen(screen); + mode.h = HeightOfScreen(screen); + mode.format = pixelformat; + mode.refresh_rate = 0; /* don't know it, sorry. */ + + displaydata = (SDL_DisplayData *)SDL_calloc(1, sizeof(*displaydata)); + if (!displaydata) { + return SDL_OutOfMemory(); + } + + modedata = (SDL_DisplayModeData *)SDL_calloc(1, sizeof(SDL_DisplayModeData)); + if (!modedata) { + SDL_free(displaydata); + return SDL_OutOfMemory(); + } + mode.driverdata = modedata; + + display_mm_width = WidthMMOfScreen(screen); + display_mm_height = HeightMMOfScreen(screen); + + displaydata->screen = default_screen; + displaydata->visual = vinfo.visual; + displaydata->depth = vinfo.depth; + displaydata->hdpi = display_mm_width ? (((float)mode.w) * 25.4f / display_mm_width) : 0.0f; + displaydata->vdpi = display_mm_height ? (((float)mode.h) * 25.4f / display_mm_height) : 0.0f; + displaydata->ddpi = SDL_ComputeDiagonalDPI(mode.w, mode.h, ((float)display_mm_width) / 25.4f, ((float)display_mm_height) / 25.4f); + + xft_dpi = GetXftDPI(dpy); + if (xft_dpi > 0) { + displaydata->hdpi = (float)xft_dpi; + displaydata->vdpi = (float)xft_dpi; + } + + scanline_pad = SDL_BYTESPERPIXEL(pixelformat) * 8; + pixmapformats = X11_XListPixmapFormats(dpy, &n); + if (pixmapformats) { + for (i = 0; i < n; ++i) { + if (pixmapformats[i].depth == vinfo.depth) { + scanline_pad = pixmapformats[i].scanline_pad; + break; + } + } + X11_XFree(pixmapformats); + } + + displaydata->scanline_pad = scanline_pad; + displaydata->x = 0; + displaydata->y = 0; + displaydata->use_xrandr = SDL_FALSE; + + SDL_zero(display); + display.name = (char *)"Generic X11 Display"; /* this is just copied and thrown away, it's safe to cast to char* here. */ + display.desktop_mode = mode; + display.current_mode = mode; + display.driverdata = displaydata; + SDL_AddVideoDisplay(&display, SDL_TRUE); + + return 0; +} + +int X11_InitModes(_THIS) +{ + /* XRandR is the One True Modern Way to do this on X11. If this + fails, we just won't report any display modes except the current + desktop size. */ +#ifdef SDL_VIDEO_DRIVER_X11_XRANDR + { + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; + int xrandr_major, xrandr_minor; + /* require at least XRandR v1.3 */ + if (CheckXRandR(data->display, &xrandr_major, &xrandr_minor) && + (xrandr_major >= 2 || (xrandr_major == 1 && xrandr_minor >= 3)) && + X11_InitModes_XRandR(_this) == 0) { + return 0; + } + } +#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */ + + /* still here? Just set up an extremely basic display. */ + return X11_InitModes_StdXlib(_this); +} + +void X11_GetDisplayModes(_THIS, SDL_VideoDisplay *sdl_display) +{ + SDL_DisplayData *data = (SDL_DisplayData *)sdl_display->driverdata; + SDL_DisplayMode mode; + + /* Unfortunately X11 requires the window to be created with the correct + * visual and depth ahead of time, but the SDL API allows you to create + * a window before setting the fullscreen display mode. This means that + * we have to use the same format for all windows and all display modes. + * (or support recreating the window with a new visual behind the scenes) + */ + mode.format = sdl_display->current_mode.format; + mode.driverdata = NULL; + +#ifdef SDL_VIDEO_DRIVER_X11_XRANDR + if (data->use_xrandr) { + Display *display = ((SDL_VideoData *)_this->driverdata)->display; + XRRScreenResources *res; + + res = X11_XRRGetScreenResources(display, RootWindow(display, data->screen)); + if (res) { + SDL_DisplayModeData *modedata; + XRROutputInfo *output_info; + int i; + + output_info = X11_XRRGetOutputInfo(display, res, data->xrandr_output); + if (output_info && output_info->connection != RR_Disconnected) { + for (i = 0; i < output_info->nmode; ++i) { + modedata = (SDL_DisplayModeData *)SDL_calloc(1, sizeof(SDL_DisplayModeData)); + if (!modedata) { + continue; + } + mode.driverdata = modedata; + + if (!SetXRandRModeInfo(display, res, output_info->crtc, output_info->modes[i], &mode) || + !SDL_AddDisplayMode(sdl_display, &mode)) { + SDL_free(modedata); + } + } + } + X11_XRRFreeOutputInfo(output_info); + X11_XRRFreeScreenResources(res); + } + return; + } +#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */ + + if (!data->use_xrandr) { + SDL_DisplayModeData *modedata; + /* Add the desktop mode */ + mode = sdl_display->desktop_mode; + modedata = (SDL_DisplayModeData *)SDL_calloc(1, sizeof(SDL_DisplayModeData)); + if (modedata) { + *modedata = *(SDL_DisplayModeData *)sdl_display->desktop_mode.driverdata; + } + mode.driverdata = modedata; + if (!SDL_AddDisplayMode(sdl_display, &mode)) { + SDL_free(modedata); + } + } +} + +#ifdef SDL_VIDEO_DRIVER_X11_XRANDR +/* This catches an error from XRRSetScreenSize, as a workaround for now. */ +/* !!! FIXME: remove this later when we have a better solution. */ +static int (*PreXRRSetScreenSizeErrorHandler)(Display *, XErrorEvent *) = NULL; +static int SDL_XRRSetScreenSizeErrHandler(Display *d, XErrorEvent *e) +{ + /* BadMatch: https://github.com/libsdl-org/SDL/issues/4561 */ + /* BadValue: https://github.com/libsdl-org/SDL/issues/4840 */ + if ((e->error_code == BadMatch) || (e->error_code == BadValue)) { + return 0; + } + + return PreXRRSetScreenSizeErrorHandler(d, e); +} +#endif + +int X11_SetDisplayMode(_THIS, SDL_VideoDisplay *sdl_display, SDL_DisplayMode *mode) +{ + SDL_VideoData *viddata = (SDL_VideoData *)_this->driverdata; + SDL_DisplayData *data = (SDL_DisplayData *)sdl_display->driverdata; + + viddata->last_mode_change_deadline = SDL_GetTicks() + (PENDING_FOCUS_TIME * 2); + +#ifdef SDL_VIDEO_DRIVER_X11_XRANDR + if (data->use_xrandr) { + Display *display = viddata->display; + SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)mode->driverdata; + int mm_width, mm_height; + XRRScreenResources *res; + XRROutputInfo *output_info; + XRRCrtcInfo *crtc; + Status status; + + res = X11_XRRGetScreenResources(display, RootWindow(display, data->screen)); + if (!res) { + return SDL_SetError("Couldn't get XRandR screen resources"); + } + + output_info = X11_XRRGetOutputInfo(display, res, data->xrandr_output); + if (!output_info || output_info->connection == RR_Disconnected) { + X11_XRRFreeScreenResources(res); + return SDL_SetError("Couldn't get XRandR output info"); + } + + crtc = X11_XRRGetCrtcInfo(display, res, output_info->crtc); + if (!crtc) { + X11_XRRFreeOutputInfo(output_info); + X11_XRRFreeScreenResources(res); + return SDL_SetError("Couldn't get XRandR crtc info"); + } + + if (crtc->mode == modedata->xrandr_mode) { +#ifdef X11MODES_DEBUG + printf("already in desired mode 0x%lx (%ux%u), nothing to do\n", + crtc->mode, crtc->width, crtc->height); +#endif + status = Success; + goto freeInfo; + } + + X11_XGrabServer(display); + status = X11_XRRSetCrtcConfig(display, res, output_info->crtc, CurrentTime, + 0, 0, None, crtc->rotation, NULL, 0); + if (status != Success) { + goto ungrabServer; + } + + mm_width = mode->w * DisplayWidthMM(display, data->screen) / DisplayWidth(display, data->screen); + mm_height = mode->h * DisplayHeightMM(display, data->screen) / DisplayHeight(display, data->screen); + + /* !!! FIXME: this can get into a problem scenario when a window is + bigger than a physical monitor in a configuration where one screen + spans multiple physical monitors. A detailed reproduction case is + discussed at https://github.com/libsdl-org/SDL/issues/4561 ... + for now we cheat and just catch the X11 error and carry on, which + is likely to cause subtle issues but is better than outright + crashing */ + X11_XSync(display, False); + PreXRRSetScreenSizeErrorHandler = X11_XSetErrorHandler(SDL_XRRSetScreenSizeErrHandler); + X11_XRRSetScreenSize(display, RootWindow(display, data->screen), mode->w, mode->h, mm_width, mm_height); + X11_XSync(display, False); + X11_XSetErrorHandler(PreXRRSetScreenSizeErrorHandler); + + status = X11_XRRSetCrtcConfig(display, res, output_info->crtc, CurrentTime, + crtc->x, crtc->y, modedata->xrandr_mode, crtc->rotation, + &data->xrandr_output, 1); + + ungrabServer: + X11_XUngrabServer(display); + freeInfo: + X11_XRRFreeCrtcInfo(crtc); + X11_XRRFreeOutputInfo(output_info); + X11_XRRFreeScreenResources(res); + + if (status != Success) { + return SDL_SetError("X11_XRRSetCrtcConfig failed"); + } + } +#else + (void)data; +#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */ + + return 0; +} + +void X11_QuitModes(_THIS) +{ +} + +int X11_GetDisplayBounds(_THIS, SDL_VideoDisplay *sdl_display, SDL_Rect *rect) +{ + SDL_DisplayData *data = (SDL_DisplayData *)sdl_display->driverdata; + + rect->x = data->x; + rect->y = data->y; + rect->w = sdl_display->current_mode.w; + rect->h = sdl_display->current_mode.h; + + return 0; +} + +int X11_GetDisplayDPI(_THIS, SDL_VideoDisplay *sdl_display, float *ddpi, float *hdpi, float *vdpi) +{ + SDL_DisplayData *data = (SDL_DisplayData *)sdl_display->driverdata; + + if (ddpi) { + *ddpi = data->ddpi; + } + if (hdpi) { + *hdpi = data->hdpi; + } + if (vdpi) { + *vdpi = data->vdpi; + } + + return data->ddpi != 0.0f ? 0 : SDL_SetError("Couldn't get DPI"); +} + +int X11_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay *sdl_display, SDL_Rect *rect) +{ + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; + Display *display = data->display; + Atom _NET_WORKAREA; + int status, real_format; + int retval = -1; + Atom real_type; + unsigned long items_read = 0, items_left = 0; + unsigned char *propdata = NULL; + + if (X11_GetDisplayBounds(_this, sdl_display, rect) < 0) { + return -1; + } + + _NET_WORKAREA = X11_XInternAtom(display, "_NET_WORKAREA", False); + status = X11_XGetWindowProperty(display, DefaultRootWindow(display), + _NET_WORKAREA, 0L, 4L, False, XA_CARDINAL, + &real_type, &real_format, &items_read, + &items_left, &propdata); + if ((status == Success) && (items_read >= 4)) { + const long *p = (long *)propdata; + const SDL_Rect usable = { (int)p[0], (int)p[1], (int)p[2], (int)p[3] }; + retval = 0; + if (!SDL_IntersectRect(rect, &usable, rect)) { + SDL_zerop(rect); + } + } + + if (propdata) { + X11_XFree(propdata); + } + + return retval; +} + +#endif /* SDL_VIDEO_DRIVER_X11 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/x11/SDL_x11modes.h b/SDL2-2.30.5/src/video/x11/SDL_x11modes.h similarity index 55% rename from SDL2-2.0.12/src/video/x11/SDL_x11modes.h rename to SDL2-2.30.5/src/video/x11/SDL_x11modes.h index fc5dd63..8c6c1c2 100644 --- a/SDL2-2.0.12/src/video/x11/SDL_x11modes.h +++ b/SDL2-2.30.5/src/video/x11/SDL_x11modes.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -35,50 +35,39 @@ typedef struct float hdpi; float vdpi; - int use_xinerama; - int use_xrandr; - int use_vidmode; + SDL_bool use_xrandr; -#if SDL_VIDEO_DRIVER_X11_XINERAMA - XineramaScreenInfo xinerama_info; - int xinerama_screen; -#endif - -#if SDL_VIDEO_DRIVER_X11_XRANDR +#ifdef SDL_VIDEO_DRIVER_X11_XRANDR RROutput xrandr_output; #endif - -#if SDL_VIDEO_DRIVER_X11_XVIDMODE - int vidmode_screen; -#endif - } SDL_DisplayData; typedef struct { -#if SDL_VIDEO_DRIVER_X11_XRANDR +#ifdef SDL_VIDEO_DRIVER_X11_XRANDR RRMode xrandr_mode; +#else + int unused; /* just so struct isn't empty. */ #endif - -#if SDL_VIDEO_DRIVER_X11_XVIDMODE - XF86VidModeModeInfo vm_mode; -#endif - } SDL_DisplayModeData; extern int X11_InitModes(_THIS); -extern void X11_GetDisplayModes(_THIS, SDL_VideoDisplay * display); -extern int X11_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode); +extern void X11_GetDisplayModes(_THIS, SDL_VideoDisplay *display); +extern int X11_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode); extern void X11_QuitModes(_THIS); /* Some utility functions for working with visuals */ -extern int X11_GetVisualInfoFromVisual(Display * display, Visual * visual, - XVisualInfo * vinfo); -extern Uint32 X11_GetPixelFormatFromVisualInfo(Display * display, - XVisualInfo * vinfo); -extern int X11_GetDisplayBounds(_THIS, SDL_VideoDisplay * sdl_display, SDL_Rect * rect); -extern int X11_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * sdl_display, SDL_Rect * rect); -extern int X11_GetDisplayDPI(_THIS, SDL_VideoDisplay * sdl_display, float * ddpi, float * hdpi, float * vdpi); +extern int X11_GetVisualInfoFromVisual(Display *display, Visual *visual, + XVisualInfo *vinfo); +extern Uint32 X11_GetPixelFormatFromVisualInfo(Display *display, + XVisualInfo *vinfo); +extern int X11_GetDisplayBounds(_THIS, SDL_VideoDisplay *sdl_display, SDL_Rect *rect); +extern int X11_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay *sdl_display, SDL_Rect *rect); +extern int X11_GetDisplayDPI(_THIS, SDL_VideoDisplay *sdl_display, float *ddpi, float *hdpi, float *vdpi); + +#ifdef SDL_VIDEO_DRIVER_X11_XRANDR +extern void X11_HandleXRandREvent(_THIS, const XEvent *xevent); +#endif #endif /* SDL_x11modes_h_ */ diff --git a/SDL2-2.0.12/src/video/x11/SDL_x11mouse.c b/SDL2-2.30.5/src/video/x11/SDL_x11mouse.c similarity index 57% rename from SDL2-2.0.12/src/video/x11/SDL_x11mouse.c rename to SDL2-2.30.5/src/video/x11/SDL_x11mouse.c index 4d65348..0938de9 100644 --- a/SDL2-2.0.12/src/video/x11/SDL_x11mouse.c +++ b/SDL2-2.30.5/src/video/x11/SDL_x11mouse.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,27 +20,23 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_X11 +#ifdef SDL_VIDEO_DRIVER_X11 #include -#include "SDL_assert.h" #include "SDL_x11video.h" #include "SDL_x11mouse.h" #include "SDL_x11xinput2.h" #include "../../events/SDL_mouse_c.h" - /* FIXME: Find a better place to put this... */ static Cursor x11_empty_cursor = None; -static Display * -GetDisplay(void) +static Display *GetDisplay(void) { return ((SDL_VideoData *)SDL_GetVideoDevice()->driverdata)->display; } -static Cursor -X11_CreateEmptyCursor() +static Cursor X11_CreateEmptyCursor() { if (x11_empty_cursor == None) { Display *display = GetDisplay(); @@ -51,18 +47,17 @@ X11_CreateEmptyCursor() SDL_zeroa(data); color.red = color.green = color.blue = 0; pixmap = X11_XCreateBitmapFromData(display, DefaultRootWindow(display), - data, 1, 1); + data, 1, 1); if (pixmap) { x11_empty_cursor = X11_XCreatePixmapCursor(display, pixmap, pixmap, - &color, &color, 0, 0); + &color, &color, 0, 0); X11_XFreePixmap(display, pixmap); } } return x11_empty_cursor; } -static void -X11_DestroyEmptyCursor(void) +static void X11_DestroyEmptyCursor(void) { if (x11_empty_cursor != None) { X11_XFreeCursor(GetDisplay(), x11_empty_cursor); @@ -70,15 +65,14 @@ X11_DestroyEmptyCursor(void) } } -static SDL_Cursor * -X11_CreateDefaultCursor() +static SDL_Cursor *X11_CreateDefaultCursor() { SDL_Cursor *cursor; cursor = SDL_calloc(1, sizeof(*cursor)); if (cursor) { /* None is used to indicate the default cursor */ - cursor->driverdata = (void*)None; + cursor->driverdata = (void *)(uintptr_t)None; } else { SDL_OutOfMemory(); } @@ -86,9 +80,8 @@ X11_CreateDefaultCursor() return cursor; } -#if SDL_VIDEO_DRIVER_X11_XCURSOR -static Cursor -X11_CreateXCursorCursor(SDL_Surface * surface, int hot_x, int hot_y) +#ifdef SDL_VIDEO_DRIVER_X11_XCURSOR +static Cursor X11_CreateXCursorCursor(SDL_Surface *surface, int hot_x, int hot_y) { Display *display = GetDisplay(); Cursor cursor = None; @@ -105,7 +98,7 @@ X11_CreateXCursorCursor(SDL_Surface * surface, int hot_x, int hot_y) SDL_assert(surface->format->format == SDL_PIXELFORMAT_ARGB8888); SDL_assert(surface->pitch == surface->w * 4); - SDL_memcpy(image->pixels, surface->pixels, surface->h * surface->pitch); + SDL_memcpy(image->pixels, surface->pixels, (size_t)surface->h * surface->pitch); cursor = X11_XcursorImageLoadCursor(display, image); @@ -115,8 +108,7 @@ X11_CreateXCursorCursor(SDL_Surface * surface, int hot_x, int hot_y) } #endif /* SDL_VIDEO_DRIVER_X11_XCURSOR */ -static Cursor -X11_CreatePixmapCursor(SDL_Surface * surface, int hot_x, int hot_y) +static Cursor X11_CreatePixmapCursor(SDL_Surface *surface, int hot_x, int hot_y) { Display *display = GetDisplay(); XColor fg, bg; @@ -126,7 +118,7 @@ X11_CreatePixmapCursor(SDL_Surface * surface, int hot_x, int hot_y) Pixmap data_pixmap, mask_pixmap; int x, y; unsigned int rfg, gfg, bfg, rbg, gbg, bbg, fgBits, bgBits; - unsigned int width_bytes = ((surface->w + 7) & ~7) / 8; + size_t width_bytes = ((surface->w + 7) & ~((size_t)7)) / 8; data_bits = SDL_calloc(1, surface->h * width_bytes); if (!data_bits) { @@ -149,9 +141,9 @@ X11_CreatePixmapCursor(SDL_Surface * surface, int hot_x, int hot_y) ptr = (Uint32 *)((Uint8 *)surface->pixels + y * surface->pitch); for (x = 0; x < surface->w; ++x) { int alpha = (*ptr >> 24) & 0xff; - int red = (*ptr >> 16) & 0xff; + int red = (*ptr >> 16) & 0xff; int green = (*ptr >> 8) & 0xff; - int blue = (*ptr >> 0) & 0xff; + int blue = (*ptr >> 0) & 0xff; if (alpha > 25) { mask_bits[y * width_bytes + x / 8] |= (0x01 << (x % 8)); @@ -173,35 +165,38 @@ X11_CreatePixmapCursor(SDL_Surface * surface, int hot_x, int hot_y) } if (fgBits) { - fg.red = rfg * 257 / fgBits; + fg.red = rfg * 257 / fgBits; fg.green = gfg * 257 / fgBits; - fg.blue = bfg * 257 / fgBits; + fg.blue = bfg * 257 / fgBits; + } else { + fg.red = fg.green = fg.blue = 0; } - else fg.red = fg.green = fg.blue = 0; if (bgBits) { - bg.red = rbg * 257 / bgBits; + bg.red = rbg * 257 / bgBits; bg.green = gbg * 257 / bgBits; - bg.blue = bbg * 257 / bgBits; + bg.blue = bbg * 257 / bgBits; + } else { + bg.red = bg.green = bg.blue = 0; } - else bg.red = bg.green = bg.blue = 0; data_pixmap = X11_XCreateBitmapFromData(display, DefaultRootWindow(display), - (char*)data_bits, - surface->w, surface->h); + (char *)data_bits, + surface->w, surface->h); mask_pixmap = X11_XCreateBitmapFromData(display, DefaultRootWindow(display), - (char*)mask_bits, - surface->w, surface->h); + (char *)mask_bits, + surface->w, surface->h); cursor = X11_XCreatePixmapCursor(display, data_pixmap, mask_pixmap, - &fg, &bg, hot_x, hot_y); + &fg, &bg, hot_x, hot_y); X11_XFreePixmap(display, data_pixmap); X11_XFreePixmap(display, mask_pixmap); + SDL_free(data_bits); + SDL_free(mask_bits); return cursor; } -static SDL_Cursor * -X11_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y) +static SDL_Cursor *X11_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y) { SDL_Cursor *cursor; @@ -209,7 +204,7 @@ X11_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y) if (cursor) { Cursor x11_cursor = None; -#if SDL_VIDEO_DRIVER_X11_XCURSOR +#ifdef SDL_VIDEO_DRIVER_X11_XCURSOR if (SDL_X11_HAVE_XCURSOR) { x11_cursor = X11_CreateXCursorCursor(surface, hot_x, hot_y); } @@ -217,7 +212,7 @@ X11_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y) if (x11_cursor == None) { x11_cursor = X11_CreatePixmapCursor(surface, hot_x, hot_y); } - cursor->driverdata = (void*)x11_cursor; + cursor->driverdata = (void *)(uintptr_t)x11_cursor; } else { SDL_OutOfMemory(); } @@ -225,49 +220,59 @@ X11_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y) return cursor; } -static SDL_Cursor * -X11_CreateSystemCursor(SDL_SystemCursor id) +static unsigned int GetLegacySystemCursorShape(SDL_SystemCursor id) { - SDL_Cursor *cursor; - unsigned int shape; - - switch(id) - { - default: - SDL_assert(0); - return NULL; - /* X Font Cursors reference: */ - /* http://tronche.com/gui/x/xlib/appendix/b/ */ - case SDL_SYSTEM_CURSOR_ARROW: shape = XC_left_ptr; break; - case SDL_SYSTEM_CURSOR_IBEAM: shape = XC_xterm; break; - case SDL_SYSTEM_CURSOR_WAIT: shape = XC_watch; break; - case SDL_SYSTEM_CURSOR_CROSSHAIR: shape = XC_tcross; break; - case SDL_SYSTEM_CURSOR_WAITARROW: shape = XC_watch; break; - case SDL_SYSTEM_CURSOR_SIZENWSE: shape = XC_fleur; break; - case SDL_SYSTEM_CURSOR_SIZENESW: shape = XC_fleur; break; - case SDL_SYSTEM_CURSOR_SIZEWE: shape = XC_sb_h_double_arrow; break; - case SDL_SYSTEM_CURSOR_SIZENS: shape = XC_sb_v_double_arrow; break; - case SDL_SYSTEM_CURSOR_SIZEALL: shape = XC_fleur; break; - case SDL_SYSTEM_CURSOR_NO: shape = XC_pirate; break; - case SDL_SYSTEM_CURSOR_HAND: shape = XC_hand2; break; + switch (id) { + /* X Font Cursors reference: */ + /* http://tronche.com/gui/x/xlib/appendix/b/ */ + case SDL_SYSTEM_CURSOR_ARROW: return XC_left_ptr; + case SDL_SYSTEM_CURSOR_IBEAM: return XC_xterm; + case SDL_SYSTEM_CURSOR_WAIT: return XC_watch; + case SDL_SYSTEM_CURSOR_CROSSHAIR: return XC_tcross; + case SDL_SYSTEM_CURSOR_WAITARROW: return XC_watch; + case SDL_SYSTEM_CURSOR_SIZENWSE: return XC_top_left_corner; + case SDL_SYSTEM_CURSOR_SIZENESW: return XC_top_right_corner; + case SDL_SYSTEM_CURSOR_SIZEWE: return XC_sb_h_double_arrow; + case SDL_SYSTEM_CURSOR_SIZENS: return XC_sb_v_double_arrow; + case SDL_SYSTEM_CURSOR_SIZEALL: return XC_fleur; + case SDL_SYSTEM_CURSOR_NO: return XC_pirate; + case SDL_SYSTEM_CURSOR_HAND: return XC_hand2; + case SDL_NUM_SYSTEM_CURSORS: break; /* so the compiler might notice if an enum value is missing here. */ } - cursor = SDL_calloc(1, sizeof(*cursor)); - if (cursor) { - Cursor x11_cursor; + SDL_assert(0); + return 0; +} - x11_cursor = X11_XCreateFontCursor(GetDisplay(), shape); +static SDL_Cursor *X11_CreateSystemCursor(SDL_SystemCursor id) +{ + SDL_Cursor *cursor = NULL; + Display *dpy = GetDisplay(); + Cursor x11_cursor = None; - cursor->driverdata = (void*)x11_cursor; - } else { - SDL_OutOfMemory(); +#ifdef SDL_VIDEO_DRIVER_X11_XCURSOR + if (SDL_X11_HAVE_XCURSOR) { + x11_cursor = X11_XcursorLibraryLoadCursor(dpy, SDL_GetCSSCursorName(id, NULL)); + } +#endif + + if (x11_cursor == None) { + x11_cursor = X11_XCreateFontCursor(dpy, GetLegacySystemCursorShape(id)); + } + + if (x11_cursor != None) { + cursor = SDL_calloc(1, sizeof(*cursor)); + if (!cursor) { + SDL_OutOfMemory(); + } else { + cursor->driverdata = (void *)(uintptr_t)x11_cursor; + } } return cursor; } -static void -X11_FreeCursor(SDL_Cursor * cursor) +static void X11_FreeCursor(SDL_Cursor *cursor) { Cursor x11_cursor = (Cursor)cursor->driverdata; @@ -277,8 +282,7 @@ X11_FreeCursor(SDL_Cursor * cursor) SDL_free(cursor); } -static int -X11_ShowCursor(SDL_Cursor * cursor) +static int X11_ShowCursor(SDL_Cursor *cursor) { Cursor x11_cursor = 0; @@ -293,14 +297,15 @@ X11_ShowCursor(SDL_Cursor * cursor) SDL_VideoDevice *video = SDL_GetVideoDevice(); Display *display = GetDisplay(); SDL_Window *window; - SDL_WindowData *data; for (window = video->windows; window; window = window->next) { - data = (SDL_WindowData *)window->driverdata; - if (x11_cursor != None) { - X11_XDefineCursor(display, data->xwindow, x11_cursor); - } else { - X11_XUndefineCursor(display, data->xwindow); + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + if (data) { + if (x11_cursor != None) { + X11_XDefineCursor(display, data->xwindow, x11_cursor); + } else { + X11_XUndefineCursor(display, data->xwindow); + } } } X11_XFlush(display); @@ -308,56 +313,89 @@ X11_ShowCursor(SDL_Cursor * cursor) return 0; } -static void -WarpMouseInternal(Window xwindow, const int x, const int y) +static void WarpMouseInternal(Window xwindow, const int x, const int y) { - SDL_VideoData *videodata = (SDL_VideoData *) SDL_GetVideoDevice()->driverdata; + SDL_VideoData *videodata = (SDL_VideoData *)SDL_GetVideoDevice()->driverdata; Display *display = videodata->display; - X11_XWarpPointer(display, None, xwindow, 0, 0, 0, 0, x, y); + SDL_Mouse *mouse = SDL_GetMouse(); + int deviceid = 0; + SDL_bool warp_hack = SDL_FALSE; + + /* XWayland will only warp the cursor if it is hidden, so this workaround is required. */ + if (videodata->is_xwayland && mouse && mouse->cursor_shown) { + warp_hack = SDL_TRUE; + } + + if (warp_hack) { + X11_ShowCursor(NULL); + } +#ifdef SDL_VIDEO_DRIVER_X11_XINPUT2 + if (X11_Xinput2IsInitialized()) { + /* It seems XIWarpPointer() doesn't work correctly on multi-head setups: + * https://developer.blender.org/rB165caafb99c6846e53d11c4e966990aaffc06cea + */ + if (ScreenCount(display) == 1) { + X11_XIGetClientPointer(display, None, &deviceid); + } + } + if (deviceid != 0) { + SDL_assert(SDL_X11_HAVE_XINPUT2); + X11_XIWarpPointer(display, deviceid, None, xwindow, 0.0, 0.0, 0, 0, (double)x, (double)y); + } else +#endif + { + X11_XWarpPointer(display, None, xwindow, 0, 0, 0, 0, x, y); + } + + if (warp_hack) { + X11_ShowCursor(SDL_GetCursor()); + } X11_XSync(display, False); videodata->global_mouse_changed = SDL_TRUE; } -static void -X11_WarpMouse(SDL_Window * window, int x, int y) +static void X11_WarpMouse(SDL_Window *window, int x, int y) { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + +#ifdef SDL_VIDEO_DRIVER_X11_XFIXES + /* If we have no barrier, we need to warp */ + if (data->pointer_barrier_active == SDL_FALSE) { + WarpMouseInternal(data->xwindow, x, y); + } +#else WarpMouseInternal(data->xwindow, x, y); +#endif } -static int -X11_WarpMouseGlobal(int x, int y) +static int X11_WarpMouseGlobal(int x, int y) { WarpMouseInternal(DefaultRootWindow(GetDisplay()), x, y); return 0; } -static int -X11_SetRelativeMouseMode(SDL_bool enabled) +static int X11_SetRelativeMouseMode(SDL_bool enabled) { -#if SDL_VIDEO_DRIVER_X11_XINPUT2 - if(X11_Xinput2IsInitialized()) - return 0; -#else - SDL_Unsupported(); -#endif - return -1; + return X11_Xinput2IsInitialized() ? 0 : SDL_Unsupported(); } -static int -X11_CaptureMouse(SDL_Window *window) +static int X11_CaptureMouse(SDL_Window *window) { Display *display = GetDisplay(); + SDL_Window *mouse_focus = SDL_GetMouseFocus(); if (window) { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; const unsigned int mask = ButtonPressMask | ButtonReleaseMask | PointerMotionMask | FocusChangeMask; + Window confined = (data->mouse_grabbed ? data->xwindow : None); const int rc = X11_XGrabPointer(display, data->xwindow, False, mask, GrabModeAsync, GrabModeAsync, - None, None, CurrentTime); + confined, None, CurrentTime); if (rc != GrabSuccess) { return SDL_SetError("X server refused mouse capture"); } + } else if (mouse_focus) { + SDL_UpdateWindowGrab(mouse_focus); } else { X11_XUngrabPointer(display, CurrentTime); } @@ -367,26 +405,25 @@ X11_CaptureMouse(SDL_Window *window) return 0; } -static Uint32 -X11_GetGlobalMouseState(int *x, int *y) +static Uint32 X11_GetGlobalMouseState(int *x, int *y) { - SDL_VideoData *videodata = (SDL_VideoData *) SDL_GetVideoDevice()->driverdata; + SDL_VideoData *videodata = (SDL_VideoData *)SDL_GetVideoDevice()->driverdata; Display *display = GetDisplay(); const int num_screens = SDL_GetNumVideoDisplays(); int i; /* !!! FIXME: should we XSync() here first? */ -#if !SDL_VIDEO_DRIVER_X11_XINPUT2 - videodata->global_mouse_changed = SDL_TRUE; -#endif + if (!X11_Xinput2IsInitialized()) { + videodata->global_mouse_changed = SDL_TRUE; + } /* check if we have this cached since XInput last saw the mouse move. */ /* !!! FIXME: can we just calculate this from XInput's events? */ if (videodata->global_mouse_changed) { for (i = 0; i < num_screens; i++) { - SDL_DisplayData *data = (SDL_DisplayData *) SDL_GetDisplayDriverData(i); - if (data != NULL) { + SDL_DisplayData *data = (SDL_DisplayData *)SDL_GetDisplayDriverData(i); + if (data) { Window root, child; int rootx, rooty, winx, winy; unsigned int mask; @@ -396,6 +433,8 @@ X11_GetGlobalMouseState(int *x, int *y) buttons |= (mask & Button1Mask) ? SDL_BUTTON_LMASK : 0; buttons |= (mask & Button2Mask) ? SDL_BUTTON_MMASK : 0; buttons |= (mask & Button3Mask) ? SDL_BUTTON_RMASK : 0; + /* Use the SDL state for the extended buttons - it's better than nothing */ + buttons |= (SDL_GetMouseState(NULL, NULL) & (SDL_BUTTON_X1MASK | SDL_BUTTON_X2MASK)); /* SDL_DisplayData->x,y point to screen origin, and adding them to mouse coordinates relative to root window doesn't do the right thing * (observed on dual monitor setup with primary display being the rightmost one - mouse was offset to the right). * @@ -411,16 +450,14 @@ X11_GetGlobalMouseState(int *x, int *y) } } - SDL_assert(!videodata->global_mouse_changed); /* The pointer wasn't on any X11 screen?! */ + SDL_assert(!videodata->global_mouse_changed); /* The pointer wasn't on any X11 screen?! */ *x = videodata->global_mouse_position.x; *y = videodata->global_mouse_position.y; return videodata->global_mouse_buttons; } - -void -X11_InitMouse(_THIS) +void X11_InitMouse(_THIS) { SDL_Mouse *mouse = SDL_GetMouse(); @@ -437,9 +474,18 @@ X11_InitMouse(_THIS) SDL_SetDefaultCursor(X11_CreateDefaultCursor()); } -void -X11_QuitMouse(_THIS) +void X11_QuitMouse(_THIS) { + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; + SDL_XInput2DeviceInfo *i; + SDL_XInput2DeviceInfo *next; + + for (i = data->mouse_device_info; i; i = next) { + next = i->next; + SDL_free(i); + } + data->mouse_device_info = NULL; + X11_DestroyEmptyCursor(); } diff --git a/SDL2-2.0.12/src/video/x11/SDL_x11mouse.h b/SDL2-2.30.5/src/video/x11/SDL_x11mouse.h similarity index 79% rename from SDL2-2.0.12/src/video/x11/SDL_x11mouse.h rename to SDL2-2.30.5/src/video/x11/SDL_x11mouse.h index b6628e1..5cccd31 100644 --- a/SDL2-2.0.12/src/video/x11/SDL_x11mouse.h +++ b/SDL2-2.30.5/src/video/x11/SDL_x11mouse.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,6 +23,16 @@ #ifndef SDL_x11mouse_h_ #define SDL_x11mouse_h_ +typedef struct SDL_XInput2DeviceInfo +{ + int device_id; + SDL_bool relative[2]; + double minval[2]; + double maxval[2]; + double prev_coords[2]; + struct SDL_XInput2DeviceInfo *next; +} SDL_XInput2DeviceInfo; + extern void X11_InitMouse(_THIS); extern void X11_QuitMouse(_THIS); diff --git a/SDL2-2.0.12/src/video/x11/SDL_x11opengl.c b/SDL2-2.30.5/src/video/x11/SDL_x11opengl.c similarity index 64% rename from SDL2-2.0.12/src/video/x11/SDL_x11opengl.c rename to SDL2-2.30.5/src/video/x11/SDL_x11opengl.c index 8747ff2..30563fc 100644 --- a/SDL2-2.0.12/src/video/x11/SDL_x11opengl.c +++ b/SDL2-2.30.5/src/video/x11/SDL_x11opengl.c @@ -1,6 +1,7 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 2021 NVIDIA Corporation This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,110 +21,123 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_X11 +#ifdef SDL_VIDEO_DRIVER_X11 #include "SDL_x11video.h" -#include "SDL_assert.h" #include "SDL_hints.h" /* GLX implementation of SDL OpenGL support */ -#if SDL_VIDEO_OPENGL_GLX +#ifdef SDL_VIDEO_OPENGL_GLX #include "SDL_loadso.h" #include "SDL_x11opengles.h" -#if defined(__IRIX__) -/* IRIX doesn't have a GL library versioning system */ +#if defined(__IRIX__) || defined(__NetBSD__) || defined(__OpenBSD__) +/* + * IRIX doesn't have a GL library versioning system. + * NetBSD and OpenBSD have different GL library versions depending on how + * the library was installed. + */ #define DEFAULT_OPENGL "libGL.so" #elif defined(__MACOSX__) #define DEFAULT_OPENGL "/opt/X11/lib/libGL.1.dylib" #elif defined(__QNXNTO__) #define DEFAULT_OPENGL "libGL.so.3" #else -#define DEFAULT_OPENGL "libGL.so.1" +#define DEFAULT_OPENGL "libGL.so.1" #endif #ifndef GLX_NONE_EXT -#define GLX_NONE_EXT 0x8000 +#define GLX_NONE_EXT 0x8000 #endif #ifndef GLX_ARB_multisample #define GLX_ARB_multisample -#define GLX_SAMPLE_BUFFERS_ARB 100000 -#define GLX_SAMPLES_ARB 100001 +#define GLX_SAMPLE_BUFFERS_ARB 100000 +#define GLX_SAMPLES_ARB 100001 #endif #ifndef GLX_EXT_visual_rating #define GLX_EXT_visual_rating -#define GLX_VISUAL_CAVEAT_EXT 0x20 -#define GLX_NONE_EXT 0x8000 -#define GLX_SLOW_VISUAL_EXT 0x8001 -#define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D +#define GLX_VISUAL_CAVEAT_EXT 0x20 +#define GLX_NONE_EXT 0x8000 +#define GLX_SLOW_VISUAL_EXT 0x8001 +#define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D #endif #ifndef GLX_EXT_visual_info #define GLX_EXT_visual_info -#define GLX_X_VISUAL_TYPE_EXT 0x22 -#define GLX_DIRECT_COLOR_EXT 0x8003 +#define GLX_X_VISUAL_TYPE_EXT 0x22 +#define GLX_DIRECT_COLOR_EXT 0x8003 #endif #ifndef GLX_ARB_create_context #define GLX_ARB_create_context -#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 -#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 -#define GLX_CONTEXT_FLAGS_ARB 0x2094 -#define GLX_CONTEXT_DEBUG_BIT_ARB 0x0001 +#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 +#define GLX_CONTEXT_FLAGS_ARB 0x2094 +#define GLX_CONTEXT_DEBUG_BIT_ARB 0x0001 #define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 /* Typedef for the GL 3.0 context creation function */ -typedef GLXContext(*PFNGLXCREATECONTEXTATTRIBSARBPROC) (Display * dpy, +typedef GLXContext (*PFNGLXCREATECONTEXTATTRIBSARBPROC)(Display *dpy, GLXFBConfig config, GLXContext - share_context, + share_context, Bool direct, const int - *attrib_list); + *attrib_list); #endif #ifndef GLX_ARB_create_context_profile #define GLX_ARB_create_context_profile -#define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126 -#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 +#define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126 +#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 #define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 #endif #ifndef GLX_ARB_create_context_robustness #define GLX_ARB_create_context_robustness -#define GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004 -#define GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 -#define GLX_NO_RESET_NOTIFICATION_ARB 0x8261 -#define GLX_LOSE_CONTEXT_ON_RESET_ARB 0x8252 +#define GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004 +#define GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 +#define GLX_NO_RESET_NOTIFICATION_ARB 0x8261 +#define GLX_LOSE_CONTEXT_ON_RESET_ARB 0x8252 #endif #ifndef GLX_EXT_create_context_es2_profile #define GLX_EXT_create_context_es2_profile #ifndef GLX_CONTEXT_ES2_PROFILE_BIT_EXT -#define GLX_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000002 +#define GLX_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000002 #endif #endif #ifndef GLX_ARB_framebuffer_sRGB #define GLX_ARB_framebuffer_sRGB #ifndef GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB -#define GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20B2 +#define GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20B2 +#endif +#endif + +#ifndef GLX_ARB_fbconfig_float +#define GLX_ARB_fbconfig_float +#ifndef GLX_RGBA_FLOAT_TYPE_ARB +#define GLX_RGBA_FLOAT_TYPE_ARB 0x20B9 +#endif +#ifndef GLX_RGBA_FLOAT_BIT_ARB +#define GLX_RGBA_FLOAT_BIT_ARB 0x00000004 #endif #endif #ifndef GLX_ARB_create_context_no_error #define GLX_ARB_create_context_no_error #ifndef GLX_CONTEXT_OPENGL_NO_ERROR_ARB -#define GLX_CONTEXT_OPENGL_NO_ERROR_ARB 0x31B3 +#define GLX_CONTEXT_OPENGL_NO_ERROR_ARB 0x31B3 #endif #endif #ifndef GLX_EXT_swap_control -#define GLX_SWAP_INTERVAL_EXT 0x20F1 -#define GLX_MAX_SWAP_INTERVAL_EXT 0x20F2 +#define GLX_SWAP_INTERVAL_EXT 0x20F1 +#define GLX_MAX_SWAP_INTERVAL_EXT 0x20F2 #endif #ifndef GLX_EXT_swap_control_tear @@ -132,17 +146,17 @@ typedef GLXContext(*PFNGLXCREATECONTEXTATTRIBSARBPROC) (Display * dpy, #ifndef GLX_ARB_context_flush_control #define GLX_ARB_context_flush_control -#define GLX_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097 -#define GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0x0000 -#define GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098 +#define GLX_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097 +#define GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0x0000 +#define GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098 #endif #define OPENGL_REQUIRES_DLOPEN -#if defined(OPENGL_REQUIRES_DLOPEN) && defined(SDL_LOADSO_DLOPEN) +#if defined(OPENGL_REQUIRES_DLOPEN) && defined(HAVE_DLOPEN) #include -#define GL_LoadObject(X) dlopen(X, (RTLD_NOW|RTLD_GLOBAL)) -#define GL_LoadFunction dlsym -#define GL_UnloadObject dlclose +#define GL_LoadObject(X) dlopen(X, (RTLD_NOW | RTLD_GLOBAL)) +#define GL_LoadFunction dlsym +#define GL_UnloadObject dlclose #else #define GL_LoadObject SDL_LoadObject #define GL_LoadFunction SDL_LoadFunction @@ -151,8 +165,7 @@ typedef GLXContext(*PFNGLXCREATECONTEXTATTRIBSARBPROC) (Display * dpy, static void X11_GL_InitExtensions(_THIS); -int -X11_GL_LoadLibrary(_THIS, const char *path) +int X11_GL_LoadLibrary(_THIS, const char *path) { Display *display; void *handle; @@ -170,7 +183,7 @@ X11_GL_LoadLibrary(_THIS, const char *path) } _this->gl_config.dll_handle = GL_LoadObject(path); if (!_this->gl_config.dll_handle) { -#if defined(OPENGL_REQUIRES_DLOPEN) && defined(SDL_LOADSO_DLOPEN) +#if defined(OPENGL_REQUIRES_DLOPEN) && defined(HAVE_DLOPEN) SDL_SetError("Failed loading %s: %s", path, dlerror()); #endif return -1; @@ -180,9 +193,9 @@ X11_GL_LoadLibrary(_THIS, const char *path) /* Allocate OpenGL memory */ _this->gl_data = - (struct SDL_GLDriverData *) SDL_calloc(1, - sizeof(struct - SDL_GLDriverData)); + (struct SDL_GLDriverData *)SDL_calloc(1, + sizeof(struct + SDL_GLDriverData)); if (!_this->gl_data) { return SDL_OutOfMemory(); } @@ -190,7 +203,7 @@ X11_GL_LoadLibrary(_THIS, const char *path) /* Load function pointers */ handle = _this->gl_config.dll_handle; _this->gl_data->glXQueryExtension = - (Bool (*)(Display *, int *, int *)) + (Bool(*)(Display *, int *, int *)) GL_LoadFunction(handle, "glXQueryExtension"); _this->gl_data->glXGetProcAddress = (void *(*)(const GLubyte *)) @@ -211,7 +224,7 @@ X11_GL_LoadLibrary(_THIS, const char *path) (void (*)(Display *, GLXDrawable)) X11_GL_GetProcAddress(_this, "glXSwapBuffers"); _this->gl_data->glXQueryDrawable = - (void (*)(Display*,GLXDrawable,int,unsigned int*)) + (void (*)(Display *, GLXDrawable, int, unsigned int *)) X11_GL_GetProcAddress(_this, "glXQueryDrawable"); if (!_this->gl_data->glXQueryExtension || @@ -223,31 +236,28 @@ X11_GL_LoadLibrary(_THIS, const char *path) return SDL_SetError("Could not retrieve OpenGL functions"); } - display = ((SDL_VideoData *) _this->driverdata)->display; + display = ((SDL_VideoData *)_this->driverdata)->display; if (!_this->gl_data->glXQueryExtension(display, &_this->gl_data->errorBase, &_this->gl_data->eventBase)) { return SDL_SetError("GLX is not supported"); } + _this->gl_data->swap_interval_tear_behavior = SDL_SWAPINTERVALTEAR_UNTESTED; + /* Initialize extensions */ - /* See lengthy comment about the inc/dec in + /* See lengthy comment about the inc/dec in ../windows/SDL_windowsopengl.c. */ ++_this->gl_config.driver_loaded; X11_GL_InitExtensions(_this); --_this->gl_config.driver_loaded; - - /* If we need a GL ES context and there's no - * GLX_EXT_create_context_es2_profile extension, switch over to X11_GLES functions + + /* If we need a GL ES context and there's no + * GLX_EXT_create_context_es2_profile extension, switch over to X11_GLES functions */ if (((_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) || SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_FORCE_EGL, SDL_FALSE)) && X11_GL_UseEGL(_this) ) { -#if SDL_VIDEO_OPENGL_EGL +#ifdef SDL_VIDEO_OPENGL_EGL X11_GL_UnloadLibrary(_this); - /* Better avoid conflicts! */ - if (_this->gl_config.dll_handle != NULL ) { - GL_UnloadObject(_this->gl_config.dll_handle); - _this->gl_config.dll_handle = NULL; - } _this->GL_LoadLibrary = X11_GLES_LoadLibrary; _this->GL_GetProcAddress = X11_GLES_GetProcAddress; _this->GL_UnloadLibrary = X11_GLES_UnloadLibrary; @@ -266,17 +276,15 @@ X11_GL_LoadLibrary(_THIS, const char *path) return 0; } -void * -X11_GL_GetProcAddress(_THIS, const char *proc) +void *X11_GL_GetProcAddress(_THIS, const char *proc) { if (_this->gl_data->glXGetProcAddress) { - return _this->gl_data->glXGetProcAddress((const GLubyte *) proc); + return _this->gl_data->glXGetProcAddress((const GLubyte *)proc); } return GL_LoadFunction(_this->gl_config.dll_handle, proc); } -void -X11_GL_UnloadLibrary(_THIS) +void X11_GL_UnloadLibrary(_THIS) { /* Don't actually unload the library, since it may have registered * X11 shutdown hooks, per the notes at: @@ -292,19 +300,20 @@ X11_GL_UnloadLibrary(_THIS) _this->gl_data = NULL; } -static SDL_bool -HasExtension(const char *extension, const char *extensions) +static SDL_bool HasExtension(const char *extension, const char *extensions) { const char *start; const char *where, *terminator; - if (!extensions) + if (!extensions) { return SDL_FALSE; + } /* Extension names should not have spaces. */ where = SDL_strchr(extension, ' '); - if (where || *extension == '\0') + if (where || *extension == '\0') { return SDL_FALSE; + } /* It takes a bit of care to be fool-proof about parsing the * OpenGL extensions string. Don't be fooled by sub-strings, @@ -314,39 +323,41 @@ HasExtension(const char *extension, const char *extensions) for (;;) { where = SDL_strstr(start, extension); - if (!where) + if (!where) { break; + } terminator = where + SDL_strlen(extension); - if (where == start || *(where - 1) == ' ') - if (*terminator == ' ' || *terminator == '\0') + if (where == start || *(where - 1) == ' ') { + if (*terminator == ' ' || *terminator == '\0') { return SDL_TRUE; + } + } start = terminator; } return SDL_FALSE; } -static void -X11_GL_InitExtensions(_THIS) +static void X11_GL_InitExtensions(_THIS) { - Display *display = ((SDL_VideoData *) _this->driverdata)->display; + Display *display = ((SDL_VideoData *)_this->driverdata)->display; const int screen = DefaultScreen(display); XVisualInfo *vinfo = NULL; Window w = 0; GLXContext prev_ctx = 0; GLXDrawable prev_drawable = 0; GLXContext context = 0; - const char *(*glXQueryExtensionsStringFunc) (Display *, int); + const char *(*glXQueryExtensionsStringFunc)(Display *, int); const char *extensions; vinfo = X11_GL_GetVisual(_this, display, screen); if (vinfo) { - GLXContext (*glXGetCurrentContextFunc) (void) = + GLXContext (*glXGetCurrentContextFunc)(void) = (GLXContext(*)(void)) X11_GL_GetProcAddress(_this, "glXGetCurrentContext"); - GLXDrawable (*glXGetCurrentDrawableFunc) (void) = + GLXDrawable (*glXGetCurrentDrawableFunc)(void) = (GLXDrawable(*)(void)) X11_GL_GetProcAddress(_this, "glXGetCurrentDrawable"); @@ -361,11 +372,11 @@ X11_GL_InitExtensions(_THIS) X11_XCreateColormap(display, RootWindow(display, screen), vinfo->visual, AllocNone); w = X11_XCreateWindow(display, RootWindow(display, screen), 0, 0, - 32, 32, 0, vinfo->depth, InputOutput, vinfo->visual, - (CWBackPixel | CWBorderPixel | CWColormap), &xattr); + 32, 32, 0, vinfo->depth, InputOutput, vinfo->visual, + (CWBackPixel | CWBorderPixel | CWColormap), &xattr); context = _this->gl_data->glXCreateContext(display, vinfo, - NULL, True); + NULL, True); if (context) { _this->gl_data->glXMakeCurrent(display, w, context); } @@ -375,8 +386,8 @@ X11_GL_InitExtensions(_THIS) } glXQueryExtensionsStringFunc = - (const char *(*)(Display *, int)) X11_GL_GetProcAddress(_this, - "glXQueryExtensionsString"); + (const char *(*)(Display *, int))X11_GL_GetProcAddress(_this, + "glXQueryExtensionsString"); if (glXQueryExtensionsStringFunc) { extensions = glXQueryExtensionsStringFunc(display, screen); } else { @@ -387,7 +398,7 @@ X11_GL_InitExtensions(_THIS) _this->gl_data->HAS_GLX_EXT_swap_control_tear = SDL_FALSE; if (HasExtension("GLX_EXT_swap_control", extensions)) { _this->gl_data->glXSwapIntervalEXT = - (void (*)(Display*,GLXDrawable,int)) + (void (*)(Display *, GLXDrawable, int)) X11_GL_GetProcAddress(_this, "glXSwapIntervalEXT"); if (HasExtension("GLX_EXT_swap_control_tear", extensions)) { _this->gl_data->HAS_GLX_EXT_swap_control_tear = SDL_TRUE; @@ -397,26 +408,29 @@ X11_GL_InitExtensions(_THIS) /* Check for GLX_MESA_swap_control */ if (HasExtension("GLX_MESA_swap_control", extensions)) { _this->gl_data->glXSwapIntervalMESA = - (int(*)(int)) X11_GL_GetProcAddress(_this, "glXSwapIntervalMESA"); + (int (*)(int))X11_GL_GetProcAddress(_this, "glXSwapIntervalMESA"); _this->gl_data->glXGetSwapIntervalMESA = - (int(*)(void)) X11_GL_GetProcAddress(_this, - "glXGetSwapIntervalMESA"); + (int (*)(void))X11_GL_GetProcAddress(_this, + "glXGetSwapIntervalMESA"); } /* Check for GLX_SGI_swap_control */ if (HasExtension("GLX_SGI_swap_control", extensions)) { _this->gl_data->glXSwapIntervalSGI = - (int (*)(int)) X11_GL_GetProcAddress(_this, "glXSwapIntervalSGI"); + (int (*)(int))X11_GL_GetProcAddress(_this, "glXSwapIntervalSGI"); } /* Check for GLX_ARB_create_context */ if (HasExtension("GLX_ARB_create_context", extensions)) { _this->gl_data->glXCreateContextAttribsARB = - (GLXContext (*)(Display*,GLXFBConfig,GLXContext,Bool,const int *)) + (GLXContext(*)(Display *, GLXFBConfig, GLXContext, Bool, const int *)) X11_GL_GetProcAddress(_this, "glXCreateContextAttribsARB"); _this->gl_data->glXChooseFBConfig = - (GLXFBConfig *(*)(Display *, int, const int *, int *)) + (GLXFBConfig * (*)(Display *, int, const int *, int *)) X11_GL_GetProcAddress(_this, "glXChooseFBConfig"); + _this->gl_data->glXGetVisualFromFBConfig = + (XVisualInfo * (*)(Display *, GLXFBConfig)) + X11_GL_GetProcAddress(_this, "glXGetVisualFromFBConfig"); } /* Check for GLX_EXT_visual_rating */ @@ -428,7 +442,7 @@ X11_GL_InitExtensions(_THIS) if (HasExtension("GLX_EXT_visual_info", extensions)) { _this->gl_data->HAS_GLX_EXT_visual_info = SDL_TRUE; } - + /* Check for GLX_EXT_create_context_es2_profile */ if (HasExtension("GLX_EXT_create_context_es2_profile", extensions)) { /* this wants to call glGetString(), so it needs a context. */ @@ -436,8 +450,7 @@ X11_GL_InitExtensions(_THIS) if (context) { SDL_GL_DeduceMaxSupportedESProfile( &_this->gl_data->es_profile_max_supported_version.major, - &_this->gl_data->es_profile_max_supported_version.minor - ); + &_this->gl_data->es_profile_max_supported_version.minor); } } @@ -477,8 +490,7 @@ X11_GL_InitExtensions(_THIS) * In case of failure, if that pointer is not NULL, set that pointer to None * and try again. */ -static int -X11_GL_GetAttributes(_THIS, Display * display, int screen, int * attribs, int size, Bool for_FBConfig, int **_pvistypeattr) +static int X11_GL_GetAttributes(_THIS, Display *display, int screen, int *attribs, int size, Bool for_FBConfig, int **_pvistypeattr) { int i = 0; const int MAX_ATTRIBUTES = 64; @@ -488,9 +500,13 @@ X11_GL_GetAttributes(_THIS, Display * display, int screen, int * attribs, int si SDL_assert(size >= MAX_ATTRIBUTES); /* Setup our GLX attributes according to the gl_config. */ - if( for_FBConfig ) { + if (for_FBConfig) { attribs[i++] = GLX_RENDER_TYPE; - attribs[i++] = GLX_RGBA_BIT; + if (_this->gl_config.floatbuffers) { + attribs[i++] = GLX_RGBA_FLOAT_BIT_ARB; + } else { + attribs[i++] = GLX_RGBA_BIT; + } } else { attribs[i++] = GLX_RGBA; } @@ -508,7 +524,7 @@ X11_GL_GetAttributes(_THIS, Display * display, int screen, int * attribs, int si if (_this->gl_config.double_buffer) { attribs[i++] = GLX_DOUBLEBUFFER; - if( for_FBConfig ) { + if (for_FBConfig) { attribs[i++] = True; } } @@ -543,7 +559,7 @@ X11_GL_GetAttributes(_THIS, Display * display, int screen, int * attribs, int si if (_this->gl_config.stereo) { attribs[i++] = GLX_STEREO; - if( for_FBConfig ) { + if (for_FBConfig) { attribs[i++] = True; } } @@ -558,16 +574,19 @@ X11_GL_GetAttributes(_THIS, Display * display, int screen, int * attribs, int si attribs[i++] = _this->gl_config.multisamplesamples; } + if (_this->gl_config.floatbuffers) { + attribs[i++] = GLX_RGBA_FLOAT_TYPE_ARB; + } + if (_this->gl_config.framebuffer_srgb_capable) { attribs[i++] = GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB; - attribs[i++] = True; /* always needed, for_FBConfig or not! */ + attribs[i++] = True; /* always needed, for_FBConfig or not! */ } if (_this->gl_config.accelerated >= 0 && _this->gl_data->HAS_GLX_EXT_visual_rating) { attribs[i++] = GLX_VISUAL_CAVEAT_EXT; - attribs[i++] = _this->gl_config.accelerated ? GLX_NONE_EXT : - GLX_SLOW_VISUAL_EXT; + attribs[i++] = _this->gl_config.accelerated ? GLX_NONE_EXT : GLX_SLOW_VISUAL_EXT; } /* If we're supposed to use DirectColor visuals, and we've got the @@ -590,12 +609,11 @@ X11_GL_GetAttributes(_THIS, Display * display, int screen, int * attribs, int si return i; } -XVisualInfo * -X11_GL_GetVisual(_THIS, Display * display, int screen) +XVisualInfo *X11_GL_GetVisual(_THIS, Display *display, int screen) { /* 64 seems nice. */ int attribs[64]; - XVisualInfo *vinfo; + XVisualInfo *vinfo = NULL; int *pvistypeattr = NULL; if (!_this->gl_data) { @@ -603,12 +621,33 @@ X11_GL_GetVisual(_THIS, Display * display, int screen) return NULL; } - X11_GL_GetAttributes(_this, display, screen, attribs, 64, SDL_FALSE, &pvistypeattr); - vinfo = _this->gl_data->glXChooseVisual(display, screen, attribs); + if (_this->gl_data->glXChooseFBConfig && + _this->gl_data->glXGetVisualFromFBConfig) { + GLXFBConfig *framebuffer_config = NULL; + int fbcount = 0; - if (!vinfo && (pvistypeattr != NULL)) { - *pvistypeattr = None; + X11_GL_GetAttributes(_this, display, screen, attribs, 64, SDL_TRUE, &pvistypeattr); + framebuffer_config = _this->gl_data->glXChooseFBConfig(display, screen, attribs, &fbcount); + if (!framebuffer_config && (pvistypeattr != NULL)) { + *pvistypeattr = None; + framebuffer_config = _this->gl_data->glXChooseFBConfig(display, screen, attribs, &fbcount); + } + + if (framebuffer_config) { + vinfo = _this->gl_data->glXGetVisualFromFBConfig(display, framebuffer_config[0]); + } + + X11_XFree(framebuffer_config); + } + + if (!vinfo) { + X11_GL_GetAttributes(_this, display, screen, attribs, 64, SDL_FALSE, &pvistypeattr); vinfo = _this->gl_data->glXChooseVisual(display, screen, attribs); + + if (!vinfo && (pvistypeattr != NULL)) { + *pvistypeattr = None; + vinfo = _this->gl_data->glXChooseVisual(display, screen, attribs); + } } if (!vinfo) { @@ -617,37 +656,31 @@ X11_GL_GetVisual(_THIS, Display * display, int screen) return vinfo; } -static int (*handler) (Display *, XErrorEvent *) = NULL; +static int (*handler)(Display *, XErrorEvent *) = NULL; static const char *errorHandlerOperation = NULL; static int errorBase = 0; static int errorCode = 0; -static int -X11_GL_ErrorHandler(Display * d, XErrorEvent * e) +static int X11_GL_ErrorHandler(Display *d, XErrorEvent *e) { char *x11_error = NULL; char x11_error_locale[256]; errorCode = e->error_code; - if (X11_XGetErrorText(d, errorCode, x11_error_locale, sizeof(x11_error_locale)) == Success) - { - x11_error = SDL_iconv_string("UTF-8", "", x11_error_locale, SDL_strlen(x11_error_locale)+1); + if (X11_XGetErrorText(d, errorCode, x11_error_locale, sizeof(x11_error_locale)) == Success) { + x11_error = SDL_iconv_string("UTF-8", "", x11_error_locale, SDL_strlen(x11_error_locale) + 1); } - if (x11_error) - { + if (x11_error) { SDL_SetError("Could not %s: %s", errorHandlerOperation, x11_error); SDL_free(x11_error); - } - else - { + } else { SDL_SetError("Could not %s: %i (Base %i)", errorHandlerOperation, errorCode, errorBase); } return (0); } -SDL_bool -X11_GL_UseEGL(_THIS) +SDL_bool X11_GL_UseEGL(_THIS) { SDL_assert(_this->gl_data != NULL); if (SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_FORCE_EGL, SDL_FALSE)) @@ -657,20 +690,16 @@ X11_GL_UseEGL(_THIS) } SDL_assert(_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES); - return (SDL_GetHintBoolean(SDL_HINT_OPENGL_ES_DRIVER, SDL_FALSE) - || _this->gl_config.major_version == 1 /* No GLX extension for OpenGL ES 1.x profiles. */ - || _this->gl_config.major_version > _this->gl_data->es_profile_max_supported_version.major - || (_this->gl_config.major_version == _this->gl_data->es_profile_max_supported_version.major - && _this->gl_config.minor_version > _this->gl_data->es_profile_max_supported_version.minor)); + return (SDL_GetHintBoolean(SDL_HINT_OPENGL_ES_DRIVER, SDL_FALSE) || _this->gl_config.major_version == 1 /* No GLX extension for OpenGL ES 1.x profiles. */ + || _this->gl_config.major_version > _this->gl_data->es_profile_max_supported_version.major || (_this->gl_config.major_version == _this->gl_data->es_profile_max_supported_version.major && _this->gl_config.minor_version > _this->gl_data->es_profile_max_supported_version.minor)); } -SDL_GLContext -X11_GL_CreateContext(_THIS, SDL_Window * window) +SDL_GLContext X11_GL_CreateContext(_THIS, SDL_Window *window) { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; Display *display = data->videodata->display; int screen = - ((SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata)->screen; + ((SDL_DisplayData *)SDL_GetDisplayForWindow(window)->driverdata)->screen; XWindowAttributes xattr; XVisualInfo v, *vinfo; int n; @@ -711,37 +740,33 @@ X11_GL_CreateContext(_THIS, SDL_Window * window) int iattr = 4; /* SDL profile bits match GLX profile bits */ - if( _this->gl_config.profile_mask != 0 ) { + if (_this->gl_config.profile_mask != 0) { attribs[iattr++] = GLX_CONTEXT_PROFILE_MASK_ARB; attribs[iattr++] = _this->gl_config.profile_mask; } /* SDL flags match GLX flags */ - if( _this->gl_config.flags != 0 ) { + if (_this->gl_config.flags != 0) { attribs[iattr++] = GLX_CONTEXT_FLAGS_ARB; attribs[iattr++] = _this->gl_config.flags; } - /* only set if glx extension is available */ - if( _this->gl_data->HAS_GLX_ARB_context_flush_control ) { + /* only set if glx extension is available and not the default setting */ + if ((_this->gl_data->HAS_GLX_ARB_context_flush_control) && (_this->gl_config.release_behavior == 0)) { attribs[iattr++] = GLX_CONTEXT_RELEASE_BEHAVIOR_ARB; - attribs[iattr++] = - _this->gl_config.release_behavior ? - GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB : - GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB; + attribs[iattr++] = + _this->gl_config.release_behavior ? GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB : GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB; } - /* only set if glx extension is available */ - if( _this->gl_data->HAS_GLX_ARB_create_context_robustness ) { + /* only set if glx extension is available and not the default setting */ + if ((_this->gl_data->HAS_GLX_ARB_create_context_robustness) && (_this->gl_config.reset_notification != 0)) { attribs[iattr++] = GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB; attribs[iattr++] = - _this->gl_config.reset_notification ? - GLX_LOSE_CONTEXT_ON_RESET_ARB : - GLX_NO_RESET_NOTIFICATION_ARB; + _this->gl_config.reset_notification ? GLX_LOSE_CONTEXT_ON_RESET_ARB : GLX_NO_RESET_NOTIFICATION_ARB; } - /* only set if glx extension is available */ - if( _this->gl_data->HAS_GLX_ARB_create_context_no_error ) { + /* only set if glx extension is available and not the default setting */ + if ((_this->gl_data->HAS_GLX_ARB_create_context_no_error) && (_this->gl_config.no_error != 0)) { attribs[iattr++] = GLX_CONTEXT_OPENGL_NO_ERROR_ARB; attribs[iattr++] = _this->gl_config.no_error; } @@ -759,24 +784,24 @@ X11_GL_CreateContext(_THIS, SDL_Window * window) int fbcount = 0; int *pvistypeattr = NULL; - X11_GL_GetAttributes(_this,display,screen,glxAttribs,64,SDL_TRUE,&pvistypeattr); + X11_GL_GetAttributes(_this, display, screen, glxAttribs, 64, SDL_TRUE, &pvistypeattr); if (_this->gl_data->glXChooseFBConfig) { framebuffer_config = _this->gl_data->glXChooseFBConfig(display, - DefaultScreen(display), glxAttribs, - &fbcount); + DefaultScreen(display), glxAttribs, + &fbcount); if (!framebuffer_config && (pvistypeattr != NULL)) { *pvistypeattr = None; framebuffer_config = _this->gl_data->glXChooseFBConfig(display, - DefaultScreen(display), glxAttribs, - &fbcount); + DefaultScreen(display), glxAttribs, + &fbcount); } - + if (framebuffer_config) { context = _this->gl_data->glXCreateContextAttribsARB(display, - framebuffer_config[0], - share_context, True, attribs); + framebuffer_config[0], + share_context, True, attribs); X11_XFree(framebuffer_config); } } @@ -802,13 +827,12 @@ X11_GL_CreateContext(_THIS, SDL_Window * window) return context; } -int -X11_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) +int X11_GL_MakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context) { - Display *display = ((SDL_VideoData *) _this->driverdata)->display; + Display *display = ((SDL_VideoData *)_this->driverdata)->display; Window drawable = - (context ? ((SDL_WindowData *) window->driverdata)->xwindow : None); - GLXContext glx_context = (GLXContext) context; + (context ? ((SDL_WindowData *)window->driverdata)->xwindow : None); + GLXContext glx_context = (GLXContext)context; int rc; if (!_this->gl_data) { @@ -824,9 +848,9 @@ X11_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) rc = _this->gl_data->glXMakeCurrent(display, drawable, glx_context); X11_XSetErrorHandler(handler); - if (errorCode != Success) { /* uhoh, an X error was thrown! */ - return -1; /* the error handler called SDL_SetError() already. */ - } else if (!rc) { /* glXMakeCurrent() failed without throwing an X error */ + if (errorCode != Success) { /* uhoh, an X error was thrown! */ + return -1; /* the error handler called SDL_SetError() already. */ + } else if (!rc) { /* glXMakeCurrent() failed without throwing an X error */ return SDL_SetError("Unable to make GL context current"); } @@ -842,17 +866,17 @@ X11_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) */ static int swapinterval = 0; -int -X11_GL_SetSwapInterval(_THIS, int interval) +int X11_GL_SetSwapInterval(_THIS, int interval) { int status = -1; if ((interval < 0) && (!_this->gl_data->HAS_GLX_EXT_swap_control_tear)) { SDL_SetError("Negative swap interval unsupported in this GL"); } else if (_this->gl_data->glXSwapIntervalEXT) { - Display *display = ((SDL_VideoData *) _this->driverdata)->display; + Display *display = ((SDL_VideoData *)_this->driverdata)->display; const SDL_WindowData *windowdata = (SDL_WindowData *) - SDL_GL_GetCurrentWindow()->driverdata; + SDL_GL_GetCurrentWindow() + ->driverdata; Window drawable = windowdata->xwindow; @@ -867,7 +891,6 @@ X11_GL_SetSwapInterval(_THIS, int interval) int currentInterval = X11_GL_GetSwapInterval(_this); _this->gl_data->glXSwapIntervalEXT(display, drawable, currentInterval); _this->gl_data->glXSwapIntervalEXT(display, drawable, interval); - status = 0; swapinterval = interval; } else if (_this->gl_data->glXSwapIntervalMESA) { @@ -890,31 +913,87 @@ X11_GL_SetSwapInterval(_THIS, int interval) return status; } -int -X11_GL_GetSwapInterval(_THIS) +static SDL_GLSwapIntervalTearBehavior CheckSwapIntervalTearBehavior(SDL_VideoDevice *_this, Window drawable, unsigned int current_val, unsigned int current_allow_late) +{ + /* Mesa and Nvidia interpret GLX_EXT_swap_control_tear differently, as of this writing, so + figure out which behavior we have. + Technical details: https://github.com/libsdl-org/SDL/issues/8004#issuecomment-1819603282 */ + if (_this->gl_data->swap_interval_tear_behavior == SDL_SWAPINTERVALTEAR_UNTESTED) { + if (!_this->gl_data->HAS_GLX_EXT_swap_control_tear) { + _this->gl_data->swap_interval_tear_behavior = SDL_SWAPINTERVALTEAR_UNKNOWN; + } else { + Display *display = ((SDL_VideoData *)_this->driverdata)->display; + unsigned int allow_late_swap_tearing = 22; + int original_val = (int) current_val; + + /* + * This is a workaround for a bug in NVIDIA drivers. Bug has been reported + * and will be fixed in a future release (probably 319.xx). + * + * There's a bug where glXSetSwapIntervalEXT ignores updates because + * it has the wrong value cached. To work around it, we just run a no-op + * update to the current value. + */ + _this->gl_data->glXSwapIntervalEXT(display, drawable, current_val); + + /* set it to no swap interval and see how it affects GLX_LATE_SWAPS_TEAR_EXT... */ + _this->gl_data->glXSwapIntervalEXT(display, drawable, 0); + _this->gl_data->glXQueryDrawable(display, drawable, GLX_LATE_SWAPS_TEAR_EXT, &allow_late_swap_tearing); + + if (allow_late_swap_tearing == 0) { /* GLX_LATE_SWAPS_TEAR_EXT says whether late swapping is currently in use */ + _this->gl_data->swap_interval_tear_behavior = SDL_SWAPINTERVALTEAR_NVIDIA; + if (current_allow_late) { + original_val = -original_val; + } + } else if (allow_late_swap_tearing == 1) { /* GLX_LATE_SWAPS_TEAR_EXT says whether the Drawable can use late swapping at all */ + _this->gl_data->swap_interval_tear_behavior = SDL_SWAPINTERVALTEAR_MESA; + } else { /* unexpected outcome! */ + _this->gl_data->swap_interval_tear_behavior = SDL_SWAPINTERVALTEAR_UNKNOWN; + } + + /* set us back to what it was originally... */ + _this->gl_data->glXSwapIntervalEXT(display, drawable, original_val); + } + } + + return _this->gl_data->swap_interval_tear_behavior; +} + + +int X11_GL_GetSwapInterval(_THIS) { if (_this->gl_data->glXSwapIntervalEXT) { - Display *display = ((SDL_VideoData *) _this->driverdata)->display; + Display *display = ((SDL_VideoData *)_this->driverdata)->display; const SDL_WindowData *windowdata = (SDL_WindowData *) - SDL_GL_GetCurrentWindow()->driverdata; + SDL_GL_GetCurrentWindow() + ->driverdata; Window drawable = windowdata->xwindow; unsigned int allow_late_swap_tearing = 0; unsigned int interval = 0; if (_this->gl_data->HAS_GLX_EXT_swap_control_tear) { + allow_late_swap_tearing = 22; /* set this to nonsense. */ _this->gl_data->glXQueryDrawable(display, drawable, - GLX_LATE_SWAPS_TEAR_EXT, - &allow_late_swap_tearing); + GLX_LATE_SWAPS_TEAR_EXT, + &allow_late_swap_tearing); } _this->gl_data->glXQueryDrawable(display, drawable, GLX_SWAP_INTERVAL_EXT, &interval); - if ((allow_late_swap_tearing) && (interval > 0)) { - return -((int) interval); + switch (CheckSwapIntervalTearBehavior(_this, drawable, interval, allow_late_swap_tearing)) { + case SDL_SWAPINTERVALTEAR_MESA: + return (int)interval; /* unsigned int cast to signed that generates negative value if necessary. */ + + case SDL_SWAPINTERVALTEAR_NVIDIA: + default: + if ((allow_late_swap_tearing) && (interval > 0)) { + return -((int)interval); + } + return (int)interval; } - return (int) interval; + return (int)interval; /* shouldn't hit this, but just in case. */ } else if (_this->gl_data->glXGetSwapIntervalMESA) { return _this->gl_data->glXGetSwapIntervalMESA(); } else { @@ -922,21 +1001,19 @@ X11_GL_GetSwapInterval(_THIS) } } -int -X11_GL_SwapWindow(_THIS, SDL_Window * window) +int X11_GL_SwapWindow(_THIS, SDL_Window *window) { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; Display *display = data->videodata->display; _this->gl_data->glXSwapBuffers(display, data->xwindow); return 0; } -void -X11_GL_DeleteContext(_THIS, SDL_GLContext context) +void X11_GL_DeleteContext(_THIS, SDL_GLContext context) { - Display *display = ((SDL_VideoData *) _this->driverdata)->display; - GLXContext glx_context = (GLXContext) context; + Display *display = ((SDL_VideoData *)_this->driverdata)->display; + GLXContext glx_context = (GLXContext)context; if (!_this->gl_data) { return; diff --git a/SDL2-2.0.12/src/video/x11/SDL_x11opengl.h b/SDL2-2.30.5/src/video/x11/SDL_x11opengl.h similarity index 57% rename from SDL2-2.0.12/src/video/x11/SDL_x11opengl.h rename to SDL2-2.30.5/src/video/x11/SDL_x11opengl.h index 3726a23..e0e8e19 100644 --- a/SDL2-2.0.12/src/video/x11/SDL_x11opengl.h +++ b/SDL2-2.30.5/src/video/x11/SDL_x11opengl.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,10 +23,18 @@ #ifndef SDL_x11opengl_h_ #define SDL_x11opengl_h_ -#if SDL_VIDEO_OPENGL_GLX +#ifdef SDL_VIDEO_OPENGL_GLX #include "SDL_opengl.h" #include +typedef enum SDL_GLSwapIntervalTearBehavior +{ + SDL_SWAPINTERVALTEAR_UNTESTED, + SDL_SWAPINTERVALTEAR_UNKNOWN, + SDL_SWAPINTERVALTEAR_MESA, + SDL_SWAPINTERVALTEAR_NVIDIA +} SDL_GLSwapIntervalTearBehavior; + struct SDL_GLDriverData { int errorBase, eventBase; @@ -42,25 +50,29 @@ struct SDL_GLDriverData implementation supports GLX_EXT_create_context_es2_profile. major = minor = 0 when unsupported. */ - struct { + struct + { int major; int minor; } es_profile_max_supported_version; - Bool (*glXQueryExtension) (Display*,int*,int*); - void *(*glXGetProcAddress) (const GLubyte*); - XVisualInfo *(*glXChooseVisual) (Display*,int,int*); - GLXContext (*glXCreateContext) (Display*,XVisualInfo*,GLXContext,Bool); - GLXContext (*glXCreateContextAttribsARB) (Display*,GLXFBConfig,GLXContext,Bool,const int *); - GLXFBConfig *(*glXChooseFBConfig) (Display*,int,const int *,int *); - void (*glXDestroyContext) (Display*, GLXContext); - Bool(*glXMakeCurrent) (Display*,GLXDrawable,GLXContext); - void (*glXSwapBuffers) (Display*, GLXDrawable); - void (*glXQueryDrawable) (Display*,GLXDrawable,int,unsigned int*); - void (*glXSwapIntervalEXT) (Display*,GLXDrawable,int); - int (*glXSwapIntervalSGI) (int); - int (*glXSwapIntervalMESA) (int); - int (*glXGetSwapIntervalMESA) (void); + SDL_GLSwapIntervalTearBehavior swap_interval_tear_behavior; + + Bool (*glXQueryExtension)(Display *, int *, int *); + void *(*glXGetProcAddress)(const GLubyte *); + XVisualInfo *(*glXChooseVisual)(Display *, int, int *); + GLXContext (*glXCreateContext)(Display *, XVisualInfo *, GLXContext, Bool); + GLXContext (*glXCreateContextAttribsARB)(Display *, GLXFBConfig, GLXContext, Bool, const int *); + GLXFBConfig *(*glXChooseFBConfig)(Display *, int, const int *, int *); + XVisualInfo *(*glXGetVisualFromFBConfig)(Display *, GLXFBConfig); + void (*glXDestroyContext)(Display *, GLXContext); + Bool (*glXMakeCurrent)(Display *, GLXDrawable, GLXContext); + void (*glXSwapBuffers)(Display *, GLXDrawable); + void (*glXQueryDrawable)(Display *, GLXDrawable, int, unsigned int *); + void (*glXSwapIntervalEXT)(Display *, GLXDrawable, int); + int (*glXSwapIntervalSGI)(int); + int (*glXSwapIntervalMESA)(int); + int (*glXGetSwapIntervalMESA)(void); }; /* OpenGL functions */ @@ -68,13 +80,13 @@ extern int X11_GL_LoadLibrary(_THIS, const char *path); extern void *X11_GL_GetProcAddress(_THIS, const char *proc); extern void X11_GL_UnloadLibrary(_THIS); extern SDL_bool X11_GL_UseEGL(_THIS); -extern XVisualInfo *X11_GL_GetVisual(_THIS, Display * display, int screen); -extern SDL_GLContext X11_GL_CreateContext(_THIS, SDL_Window * window); -extern int X11_GL_MakeCurrent(_THIS, SDL_Window * window, +extern XVisualInfo *X11_GL_GetVisual(_THIS, Display *display, int screen); +extern SDL_GLContext X11_GL_CreateContext(_THIS, SDL_Window *window); +extern int X11_GL_MakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context); extern int X11_GL_SetSwapInterval(_THIS, int interval); extern int X11_GL_GetSwapInterval(_THIS); -extern int X11_GL_SwapWindow(_THIS, SDL_Window * window); +extern int X11_GL_SwapWindow(_THIS, SDL_Window *window); extern void X11_GL_DeleteContext(_THIS, SDL_GLContext context); #endif /* SDL_VIDEO_OPENGL_GLX */ diff --git a/SDL2-2.0.12/src/video/x11/SDL_x11opengles.c b/SDL2-2.30.5/src/video/x11/SDL_x11opengles.c similarity index 81% rename from SDL2-2.0.12/src/video/x11/SDL_x11opengles.c rename to SDL2-2.30.5/src/video/x11/SDL_x11opengles.c index d3bdaa6..ad1e26b 100644 --- a/SDL2-2.0.12/src/video/x11/SDL_x11opengles.c +++ b/SDL2-2.30.5/src/video/x11/SDL_x11opengles.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_X11 && SDL_VIDEO_OPENGL_EGL +#if defined(SDL_VIDEO_DRIVER_X11) && defined(SDL_VIDEO_OPENGL_EGL) #include "SDL_hints.h" #include "SDL_x11video.h" @@ -29,15 +29,14 @@ /* EGL implementation of SDL OpenGL support */ -int -X11_GLES_LoadLibrary(_THIS, const char *path) +int X11_GLES_LoadLibrary(_THIS, const char *path) { - SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; /* If the profile requested is not GL ES, switch over to X11_GL functions */ if ((_this->gl_config.profile_mask != SDL_GL_CONTEXT_PROFILE_ES) && !SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_FORCE_EGL, SDL_FALSE)) { - #if SDL_VIDEO_OPENGL_GLX + #ifdef SDL_VIDEO_OPENGL_GLX X11_GLES_UnloadLibrary(_this); _this->GL_LoadLibrary = X11_GL_LoadLibrary; _this->GL_GetProcAddress = X11_GL_GetProcAddress; @@ -49,18 +48,17 @@ X11_GLES_LoadLibrary(_THIS, const char *path) _this->GL_SwapWindow = X11_GL_SwapWindow; _this->GL_DeleteContext = X11_GL_DeleteContext; return X11_GL_LoadLibrary(_this, path); - #else +#else return SDL_SetError("SDL not configured with OpenGL/GLX support"); - #endif +#endif } - + return SDL_EGL_LoadLibrary(_this, path, (NativeDisplayType) data->display, 0); } -XVisualInfo * -X11_GLES_GetVisual(_THIS, Display * display, int screen) +XVisualInfo *X11_GLES_GetVisual(_THIS, Display *display, int screen) { - + XVisualInfo *egl_visualinfo = NULL; EGLint visual_id; XVisualInfo vi_in; @@ -74,12 +72,13 @@ X11_GLES_GetVisual(_THIS, Display * display, int screen) if (_this->egl_data->eglGetConfigAttrib(_this->egl_data->egl_display, _this->egl_data->egl_config, EGL_NATIVE_VISUAL_ID, - &visual_id) == EGL_FALSE || !visual_id) { + &visual_id) == EGL_FALSE || + !visual_id) { /* Use the default visual when all else fails */ vi_in.screen = screen; egl_visualinfo = X11_XGetVisualInfo(display, - VisualScreenMask, - &vi_in, &out_count); + VisualScreenMask, + &vi_in, &out_count); } else { vi_in.screen = screen; vi_in.visualid = visual_id; @@ -89,11 +88,10 @@ X11_GLES_GetVisual(_THIS, Display * display, int screen) return egl_visualinfo; } -SDL_GLContext -X11_GLES_CreateContext(_THIS, SDL_Window * window) +SDL_GLContext X11_GLES_CreateContext(_THIS, SDL_Window *window) { SDL_GLContext context; - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; Display *display = data->videodata->display; X11_XSync(display, False); @@ -104,8 +102,8 @@ X11_GLES_CreateContext(_THIS, SDL_Window * window) } SDL_EGL_SwapWindow_impl(X11) -SDL_EGL_MakeCurrent_impl(X11) + SDL_EGL_MakeCurrent_impl(X11) #endif /* SDL_VIDEO_DRIVER_X11 && SDL_VIDEO_OPENGL_EGL */ -/* vi: set ts=4 sw=4 expandtab: */ + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/x11/SDL_x11opengles.h b/SDL2-2.30.5/src/video/x11/SDL_x11opengles.h similarity index 84% rename from SDL2-2.0.12/src/video/x11/SDL_x11opengles.h rename to SDL2-2.30.5/src/video/x11/SDL_x11opengles.h index afb4edf..23530d8 100644 --- a/SDL2-2.0.12/src/video/x11/SDL_x11opengles.h +++ b/SDL2-2.30.5/src/video/x11/SDL_x11opengles.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,16 +23,16 @@ #ifndef SDL_x11opengles_h_ #define SDL_x11opengles_h_ -#if SDL_VIDEO_OPENGL_EGL +#ifdef SDL_VIDEO_OPENGL_EGL #include "../SDL_sysvideo.h" #include "../SDL_egl_c.h" typedef struct SDL_PrivateGLESData { - /* 1401 If the struct-declaration-list contains no named members, the behavior is undefined. */ - /* warning: empty struct has size 0 in C, size 1 in C++ [-Wc++-compat] */ - int dummy; + /* 1401 If the struct-declaration-list contains no named members, the behavior is undefined. */ + /* warning: empty struct has size 0 in C, size 1 in C++ [-Wc++-compat] */ + int dummy; } SDL_PrivateGLESData; /* OpenGLES functions */ @@ -41,7 +41,7 @@ typedef struct SDL_PrivateGLESData #define X11_GLES_UnloadLibrary SDL_EGL_UnloadLibrary #define X11_GLES_SetSwapInterval SDL_EGL_SetSwapInterval #define X11_GLES_GetSwapInterval SDL_EGL_GetSwapInterval -#define X11_GLES_DeleteContext SDL_EGL_DeleteContext +#define X11_GLES_DeleteContext SDL_EGL_DeleteContext extern int X11_GLES_LoadLibrary(_THIS, const char *path); extern XVisualInfo *X11_GLES_GetVisual(_THIS, Display * display, int screen); diff --git a/SDL2-2.0.12/src/video/x11/SDL_x11shape.c b/SDL2-2.30.5/src/video/x11/SDL_x11shape.c similarity index 50% rename from SDL2-2.0.12/src/video/x11/SDL_x11shape.c rename to SDL2-2.30.5/src/video/x11/SDL_x11shape.c index 666f5a4..fee1c7a 100644 --- a/SDL2-2.0.12/src/video/x11/SDL_x11shape.c +++ b/SDL2-2.30.5/src/video/x11/SDL_x11shape.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,93 +20,109 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_X11 +#ifdef SDL_VIDEO_DRIVER_X11 -#include "SDL_assert.h" #include "SDL_x11video.h" #include "SDL_x11shape.h" #include "SDL_x11window.h" #include "../SDL_shape_internals.h" -SDL_WindowShaper* -X11_CreateShaper(SDL_Window* window) { - SDL_WindowShaper* result = NULL; - SDL_ShapeData* data = NULL; - int resized_properly; +SDL_WindowShaper *X11_CreateShaper(SDL_Window *window) +{ + SDL_WindowShaper *result = NULL; -#if SDL_VIDEO_DRIVER_X11_XSHAPE - if (SDL_X11_HAVE_XSHAPE) { /* Make sure X server supports it. */ - result = malloc(sizeof(SDL_WindowShaper)); +#ifdef SDL_VIDEO_DRIVER_X11_XSHAPE + SDL_ShapeData *data = NULL; + if (SDL_X11_HAVE_XSHAPE) { /* Make sure X server supports it. */ + result = SDL_malloc(sizeof(SDL_WindowShaper)); + if (!result) { + SDL_OutOfMemory(); + return NULL; + } result->window = window; result->mode.mode = ShapeModeDefault; result->mode.parameters.binarizationCutoff = 1; result->userx = result->usery = 0; data = SDL_malloc(sizeof(SDL_ShapeData)); + if (!data) { + SDL_free(result); + SDL_OutOfMemory(); + return NULL; + } result->driverdata = data; data->bitmapsize = 0; data->bitmap = NULL; window->shaper = result; - resized_properly = X11_ResizeWindowShape(window); - SDL_assert(resized_properly == 0); + if (X11_ResizeWindowShape(window) != 0) { + SDL_free(result); + SDL_free(data); + window->shaper = NULL; + return NULL; + } } #endif return result; } -int -X11_ResizeWindowShape(SDL_Window* window) { - SDL_ShapeData* data = window->shaper->driverdata; +int X11_ResizeWindowShape(SDL_Window *window) +{ + SDL_ShapeData *data = window->shaper->driverdata; unsigned int bitmapsize = window->w / 8; SDL_assert(data != NULL); - if(window->w % 8 > 0) + if (window->w % 8 > 0) { bitmapsize += 1; + } bitmapsize *= window->h; - if(data->bitmapsize != bitmapsize || data->bitmap == NULL) { + if (data->bitmapsize != bitmapsize || !data->bitmap) { data->bitmapsize = bitmapsize; - if(data->bitmap != NULL) - free(data->bitmap); - data->bitmap = malloc(data->bitmapsize); - if(data->bitmap == NULL) { - return SDL_SetError("Could not allocate memory for shaped-window bitmap."); + SDL_free(data->bitmap); + data->bitmap = SDL_malloc(data->bitmapsize); + if (!data->bitmap) { + return SDL_OutOfMemory(); } } - memset(data->bitmap,0,data->bitmapsize); + SDL_memset(data->bitmap, 0, data->bitmapsize); window->shaper->userx = window->x; window->shaper->usery = window->y; - SDL_SetWindowPosition(window,-1000,-1000); + SDL_SetWindowPosition(window, -1000, -1000); return 0; } -int -X11_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shape_mode) { +int X11_SetWindowShape(SDL_WindowShaper *shaper, SDL_Surface *shape, SDL_WindowShapeMode *shape_mode) +{ +#ifdef SDL_VIDEO_DRIVER_X11_XSHAPE SDL_ShapeData *data = NULL; SDL_WindowData *windowdata = NULL; Pixmap shapemask; - - if(shaper == NULL || shape == NULL || shaper->driverdata == NULL) - return -1; +#endif -#if SDL_VIDEO_DRIVER_X11_XSHAPE - if(shape->format->Amask == 0 && SDL_SHAPEMODEALPHA(shape_mode->mode)) + if (!shaper || !shape || !shaper->driverdata) { + return -1; + } + +#ifdef SDL_VIDEO_DRIVER_X11_XSHAPE + if (shape->format->Amask == 0 && SDL_SHAPEMODEALPHA(shape_mode->mode)) { return -2; - if(shape->w != shaper->window->w || shape->h != shaper->window->h) + } + if (shape->w != shaper->window->w || shape->h != shaper->window->h) { return -3; + } data = shaper->driverdata; /* Assume that shaper->alphacutoff already has a value, because SDL_SetWindowShape() should have given it one. */ - SDL_CalculateShapeBitmap(shaper->mode,shape,data->bitmap,8); + SDL_CalculateShapeBitmap(shaper->mode, shape, data->bitmap, 8); - windowdata = (SDL_WindowData*)(shaper->window->driverdata); - shapemask = X11_XCreateBitmapFromData(windowdata->videodata->display,windowdata->xwindow,data->bitmap,shaper->window->w,shaper->window->h); + windowdata = (SDL_WindowData *)(shaper->window->driverdata); + shapemask = X11_XCreateBitmapFromData(windowdata->videodata->display, windowdata->xwindow, data->bitmap, shaper->window->w, shaper->window->h); - X11_XShapeCombineMask(windowdata->videodata->display,windowdata->xwindow, ShapeBounding, 0, 0,shapemask, ShapeSet); - X11_XSync(windowdata->videodata->display,False); + X11_XShapeCombineMask(windowdata->videodata->display, windowdata->xwindow, ShapeBounding, 0, 0, shapemask, ShapeSet); + X11_XSync(windowdata->videodata->display, False); - X11_XFreePixmap(windowdata->videodata->display,shapemask); + X11_XFreePixmap(windowdata->videodata->display, shapemask); #endif return 0; diff --git a/SDL2-2.0.12/src/video/x11/SDL_x11shape.h b/SDL2-2.30.5/src/video/x11/SDL_x11shape.h similarity index 77% rename from SDL2-2.0.12/src/video/x11/SDL_x11shape.h rename to SDL2-2.30.5/src/video/x11/SDL_x11shape.h index d0b26e8..7cd168c 100644 --- a/SDL2-2.0.12/src/video/x11/SDL_x11shape.h +++ b/SDL2-2.30.5/src/video/x11/SDL_x11shape.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -27,13 +27,14 @@ #include "SDL_shape.h" #include "../SDL_sysvideo.h" -typedef struct { - void* bitmap; +typedef struct +{ + void *bitmap; Uint32 bitmapsize; } SDL_ShapeData; -extern SDL_WindowShaper* X11_CreateShaper(SDL_Window* window); -extern int X11_ResizeWindowShape(SDL_Window* window); -extern int X11_SetWindowShape(SDL_WindowShaper *shaper,SDL_Surface *shape,SDL_WindowShapeMode *shapeMode); +extern SDL_WindowShaper *X11_CreateShaper(SDL_Window *window); +extern int X11_ResizeWindowShape(SDL_Window *window); +extern int X11_SetWindowShape(SDL_WindowShaper *shaper, SDL_Surface *shape, SDL_WindowShapeMode *shape_mode); #endif /* SDL_x11shape_h_ */ diff --git a/SDL2-2.0.12/src/video/x11/SDL_x11sym.h b/SDL2-2.30.5/src/video/x11/SDL_x11sym.h similarity index 88% rename from SDL2-2.0.12/src/video/x11/SDL_x11sym.h rename to SDL2-2.30.5/src/video/x11/SDL_x11sym.h index c7286d7..450c07e 100644 --- a/SDL2-2.0.12/src/video/x11/SDL_x11sym.h +++ b/SDL2-2.30.5/src/video/x11/SDL_x11sym.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -19,7 +19,7 @@ 3. This notice may not be removed or altered from any source distribution. */ -/* *INDENT-OFF* */ +/* *INDENT-OFF* */ /* clang-format off */ #ifndef SDL_X11_MODULE #define SDL_X11_MODULE(modname) @@ -33,8 +33,6 @@ SDL_X11_MODULE(BASEXLIB) SDL_X11_SYM(XSizeHints*,XAllocSizeHints,(void),(),return) SDL_X11_SYM(XWMHints*,XAllocWMHints,(void),(),return) SDL_X11_SYM(XClassHint*,XAllocClassHint,(void),(),return) -SDL_X11_SYM(int,XAutoRepeatOn,(Display* a),(a),return) -SDL_X11_SYM(int,XAutoRepeatOff,(Display* a),(a),return) SDL_X11_SYM(int,XChangePointerControl,(Display* a,Bool b,Bool c,int d,int e,int f),(a,b,c,d,e,f),return) SDL_X11_SYM(int,XChangeProperty,(Display* a,Window b,Atom c,Atom d,int e,int f,_Xconst unsigned char* g,int h),(a,b,c,d,e,f,g,h),return) SDL_X11_SYM(Bool,XCheckIfEvent,(Display* a,XEvent *b,Bool (*c)(Display*,XEvent*,XPointer),XPointer d),(a,b,c,d),return) @@ -72,7 +70,6 @@ SDL_X11_SYM(char*,XGetAtomName,(Display *a,Atom b),(a,b),return) SDL_X11_SYM(int,XGetInputFocus,(Display *a,Window *b,int *c),(a,b,c),return) SDL_X11_SYM(int,XGetErrorDatabaseText,(Display* a,_Xconst char* b,_Xconst char* c,_Xconst char* d,char* e,int f),(a,b,c,d,e,f),return) SDL_X11_SYM(XModifierKeymap*,XGetModifierMapping,(Display* a),(a),return) -SDL_X11_SYM(int,XGetKeyboardControl,(Display* a, XKeyboardState* b),(a,b),return) SDL_X11_SYM(int,XGetPointerControl,(Display* a,int* b,int* c,int* d),(a,b,c,d),return) SDL_X11_SYM(Window,XGetSelectionOwner,(Display* a,Atom b),(a,b),return) SDL_X11_SYM(XVisualInfo*,XGetVisualInfo,(Display* a,long b,XVisualInfo* c,int* d),(a,b,c,d),return) @@ -97,7 +94,6 @@ SDL_X11_SYM(int,XMapRaised,(Display* a,Window b),(a,b),return) SDL_X11_SYM(Status,XMatchVisualInfo,(Display* a,int b,int c,int d,XVisualInfo* e),(a,b,c,d,e),return) SDL_X11_SYM(int,XMissingExtension,(Display* a,_Xconst char* b),(a,b),return) SDL_X11_SYM(int,XMoveWindow,(Display* a,Window b,int c,int d),(a,b,c,d),return) -SDL_X11_SYM(int,XNextEvent,(Display* a,XEvent* b),(a,b),return) SDL_X11_SYM(Display*,XOpenDisplay,(_Xconst char* a),(a),return) SDL_X11_SYM(Status,XInitThreads,(void),(),return) SDL_X11_SYM(int,XPeekEvent,(Display* a,XEvent* b),(a,b),return) @@ -109,6 +105,7 @@ SDL_X11_SYM(int,XRaiseWindow,(Display* a,Window b),(a,b),return) SDL_X11_SYM(int,XReparentWindow,(Display* a,Window b,Window c,int d,int e),(a,b,c,d,e),return) SDL_X11_SYM(int,XResetScreenSaver,(Display* a),(a),return) SDL_X11_SYM(int,XResizeWindow,(Display* a,Window b,unsigned int c,unsigned int d),(a,b,c,d),return) +SDL_X11_SYM(int,XScreenNumberOfScreen,(Screen* a),(a),return) SDL_X11_SYM(int,XSelectInput,(Display* a,Window b,long c),(a,b,c),return) SDL_X11_SYM(Status,XSendEvent,(Display* a,Window b,Bool c,long d,XEvent* e),(a,b,c,d,e),return) SDL_X11_SYM(XErrorHandler,XSetErrorHandler,(XErrorHandler a),(a),return) @@ -119,8 +116,9 @@ SDL_X11_SYM(int,XSetSelectionOwner,(Display* a,Atom b,Window c,Time d),(a,b,c,d) SDL_X11_SYM(int,XSetTransientForHint,(Display* a,Window b,Window c),(a,b,c),return) SDL_X11_SYM(void,XSetTextProperty,(Display* a,Window b,XTextProperty* c,Atom d),(a,b,c,d),) SDL_X11_SYM(int,XSetWindowBackground,(Display* a,Window b,unsigned long c),(a,b,c),return) -SDL_X11_SYM(void,XSetWMProperties,(Display* a,Window b,XTextProperty* c,XTextProperty* d,char** e,int f,XSizeHints* g,XWMHints* h,XClassHint* i),(a,b,c,d,e,f,g,h,i),) +SDL_X11_SYM(void,XSetWMHints,(Display* a,Window b,XWMHints* c),(a,b,c),) SDL_X11_SYM(void,XSetWMNormalHints,(Display* a,Window b,XSizeHints* c),(a,b,c),) +SDL_X11_SYM(void,XSetWMProperties,(Display* a,Window b,XTextProperty* c,XTextProperty* d,char** e,int f,XSizeHints* g,XWMHints* h,XClassHint* i),(a,b,c,d,e,f,g,h,i),) SDL_X11_SYM(Status,XSetWMProtocols,(Display* a,Window b,Atom* c,int d),(a,b,c,d),return) SDL_X11_SYM(int,XStoreColors,(Display* a,Colormap b,XColor* c,int d),(a,b,c,d),return) SDL_X11_SYM(int,XStoreName,(Display* a,Window b,_Xconst char* c),(a,b,c),return) @@ -138,15 +136,7 @@ SDL_X11_SYM(int,XWarpPointer,(Display* a,Window b,Window c,int d,int e,unsigned SDL_X11_SYM(int,XWindowEvent,(Display* a,Window b,long c,XEvent* d),(a,b,c,d),return) SDL_X11_SYM(Status,XWithdrawWindow,(Display* a,Window b,int c),(a,b,c),return) SDL_X11_SYM(VisualID,XVisualIDFromVisual,(Visual* a),(a),return) -#if SDL_VIDEO_DRIVER_X11_CONST_PARAM_XEXTADDDISPLAY -SDL_X11_SYM(XExtDisplayInfo*,XextAddDisplay,(XExtensionInfo* a,Display* b,_Xconst char* c,XExtensionHooks* d,int e,XPointer f),(a,b,c,d,e,f),return) -#else -SDL_X11_SYM(XExtDisplayInfo*,XextAddDisplay,(XExtensionInfo* a,Display* b,char* c,XExtensionHooks* d,int e,XPointer f),(a,b,c,d,e,f),return) -#endif -SDL_X11_SYM(XExtensionInfo*,XextCreateExtension,(void),(),return) -SDL_X11_SYM(void,XextDestroyExtension,(XExtensionInfo* a),(a),) -SDL_X11_SYM(XExtDisplayInfo*,XextFindDisplay,(XExtensionInfo* a,Display* b),(a,b),return) -SDL_X11_SYM(int,XextRemoveDisplay,(XExtensionInfo* a,Display* b),(a,b),return) +SDL_X11_SYM(char*,XGetDefault,(Display* a,_Xconst char* b, _Xconst char* c),(a,b,c),return) SDL_X11_SYM(Bool,XQueryExtension,(Display* a,_Xconst char* b,int* c,int* d,int* e),(a,b,c,d,e),return) SDL_X11_SYM(char *,XDisplayString,(Display* a),(a),return) SDL_X11_SYM(int,XGetErrorText,(Display* a,int b,char* c,int d),(a,b,c,d),return) @@ -163,13 +153,24 @@ SDL_X11_SYM(SDL_X11_XESetWireToEventRetType,XESetWireToEvent,(Display* a,int b,S SDL_X11_SYM(SDL_X11_XESetEventToWireRetType,XESetEventToWire,(Display* a,int b,SDL_X11_XESetEventToWireRetType c),(a,b,c),return) SDL_X11_SYM(void,XRefreshKeyboardMapping,(XMappingEvent *a),(a),) SDL_X11_SYM(int,XQueryTree,(Display* a,Window b,Window* c,Window* d,Window** e,unsigned int* f),(a,b,c,d,e,f),return) +SDL_X11_SYM(Bool,XSupportsLocale,(void),(),return) +SDL_X11_SYM(Status,XmbTextListToTextProperty,(Display* a,char** b,int c,XICCEncodingStyle d,XTextProperty* e),(a,b,c,d,e),return) -#if SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS -SDL_X11_SYM(Bool,XGetEventData,(Display* a,XGenericEventCookie* b),(a,b),return) -SDL_X11_SYM(void,XFreeEventData,(Display* a,XGenericEventCookie* b),(a,b),) +#ifdef SDL_VIDEO_DRIVER_X11_XFIXES +SDL_X11_MODULE(XFIXES) +SDL_X11_SYM(PointerBarrier, XFixesCreatePointerBarrier, (Display* a, Window b, int c, int d, int e, int f, int g, int h, int *i),(a,b,c,d,e,f,g,h,i),return) +SDL_X11_SYM(void, XFixesDestroyPointerBarrier, (Display* a, PointerBarrier b), (a,b),) +SDL_X11_SYM(int, XIBarrierReleasePointer,(Display* a, int b, PointerBarrier c, BarrierEventID d), (a,b,c,d), return) /* this is actually Xinput2 */ +SDL_X11_SYM(Status, XFixesQueryVersion,(Display* a, int* b, int* c), (a,b,c), return) +SDL_X11_SYM(Status, XFixesSelectSelectionInput, (Display* a, Window b, Atom c, unsigned long d), (a,b,c,d), return) #endif -#if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM +#ifdef SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS +SDL_X11_SYM(Bool,XGetEventData,(Display* a,XGenericEventCookie* b),(a,b),return) +SDL_X11_SYM(void,XFreeEventData,(Display* a,XGenericEventCookie* b),(a,b),) +#endif + +#ifdef SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM SDL_X11_SYM(Bool,XkbQueryExtension,(Display* a,int * b,int * c,int * d,int * e, int *f),(a,b,c,d,e,f),return) #if NeedWidePrototypes SDL_X11_SYM(KeySym,XkbKeycodeToKeysym,(Display* a,unsigned int b,int c,int d),(a,b,c,d),return) @@ -184,11 +185,19 @@ SDL_X11_SYM(void,XkbFreeKeyboard,(XkbDescPtr a,unsigned int b, Bool c),(a,b,c),) SDL_X11_SYM(Bool,XkbSetDetectableAutoRepeat,(Display* a, Bool b, Bool* c),(a,b,c),return) #endif +/* XKeycodeToKeysym is a deprecated function */ +#if (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))) || defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif #if NeedWidePrototypes SDL_X11_SYM(KeySym,XKeycodeToKeysym,(Display* a,unsigned int b,int c),(a,b,c),return) #else SDL_X11_SYM(KeySym,XKeycodeToKeysym,(Display* a,KeyCode b,int c),(a,b,c),return) #endif +#if (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))) || defined(__clang__) +#pragma GCC diagnostic pop +#endif #ifdef X_HAVE_UTF8_STRING SDL_X11_MODULE(UTF8) @@ -239,15 +248,16 @@ SDL_X11_SYM(int,ipUnallocateAndSendData,(ChannelPtr a,IPCard b),(a,b),return) #endif /* XCursor support */ -#if SDL_VIDEO_DRIVER_X11_XCURSOR +#ifdef SDL_VIDEO_DRIVER_X11_XCURSOR SDL_X11_MODULE(XCURSOR) SDL_X11_SYM(XcursorImage*,XcursorImageCreate,(int a,int b),(a,b),return) SDL_X11_SYM(void,XcursorImageDestroy,(XcursorImage *a),(a),) SDL_X11_SYM(Cursor,XcursorImageLoadCursor,(Display *a,const XcursorImage *b),(a,b),return) +SDL_X11_SYM(Cursor,XcursorLibraryLoadCursor,(Display *a, const char *b),(a,b),return) #endif /* Xdbe support */ -#if SDL_VIDEO_DRIVER_X11_XDBE +#ifdef SDL_VIDEO_DRIVER_X11_XDBE SDL_X11_MODULE(XDBE) SDL_X11_SYM(Status,XdbeQueryExtension,(Display *dpy,int *major_version_return,int *minor_version_return),(dpy,major_version_return,minor_version_return),return) SDL_X11_SYM(XdbeBackBuffer,XdbeAllocateBackBufferName,(Display *dpy,Window window,XdbeSwapAction swap_action),(dpy,window,swap_action),return) @@ -260,29 +270,25 @@ SDL_X11_SYM(void,XdbeFreeVisualInfo,(XdbeScreenVisualInfo *visual_info),(visual_ SDL_X11_SYM(XdbeBackBufferAttributes*,XdbeGetBackBufferAttributes,(Display *dpy,XdbeBackBuffer buffer),(dpy,buffer),return) #endif -/* Xinerama support */ -#if SDL_VIDEO_DRIVER_X11_XINERAMA -SDL_X11_MODULE(XINERAMA) -SDL_X11_SYM(Bool,XineramaIsActive,(Display *a),(a),return) -SDL_X11_SYM(Bool,XineramaQueryExtension,(Display *a,int *b,int *c),(a,b,c),return) -SDL_X11_SYM(Status,XineramaQueryVersion,(Display *a,int *b,int *c),(a,b,c),return) -SDL_X11_SYM(XineramaScreenInfo*,XineramaQueryScreens,(Display *a, int *b),(a,b),return) -#endif - /* XInput2 support for multiple mice, tablets, etc. */ -#if SDL_VIDEO_DRIVER_X11_XINPUT2 +#ifdef SDL_VIDEO_DRIVER_X11_XINPUT2 SDL_X11_MODULE(XINPUT2) SDL_X11_SYM(XIDeviceInfo*,XIQueryDevice,(Display *a,int b,int *c),(a,b,c),return) SDL_X11_SYM(void,XIFreeDeviceInfo,(XIDeviceInfo *a),(a),) SDL_X11_SYM(int,XISelectEvents,(Display *a,Window b,XIEventMask *c,int d),(a,b,c,d),return) +SDL_X11_SYM(int,XIGrabTouchBegin,(Display *a,int b,Window c,int d,XIEventMask *e,int f,XIGrabModifiers *g),(a,b,c,d,e,f,g),return) +SDL_X11_SYM(int,XIUngrabTouchBegin, (Display *a,int b,Window c, int d,XIGrabModifiers *e),(a, b, c, d, e),return) SDL_X11_SYM(Status,XIQueryVersion,(Display *a,int *b,int *c),(a,b,c),return) SDL_X11_SYM(XIEventMask*,XIGetSelectedEvents,(Display *a,Window b,int *c),(a,b,c),return) +SDL_X11_SYM(Bool,XIGetClientPointer,(Display *a,Window b,int *c),(a,b,c),return) +SDL_X11_SYM(Bool,XIWarpPointer,(Display *a,int b,Window c,Window d,double e,double f,int g,int h,double i,double j),(a,b,c,d,e,f,g,h,i,j),return) #endif /* XRandR support */ -#if SDL_VIDEO_DRIVER_X11_XRANDR +#ifdef SDL_VIDEO_DRIVER_X11_XRANDR SDL_X11_MODULE(XRANDR) SDL_X11_SYM(Status,XRRQueryVersion,(Display *dpy,int *major_versionp,int *minor_versionp),(dpy,major_versionp,minor_versionp),return) +SDL_X11_SYM(Bool,XRRQueryExtension,(Display *dpy,int *event_base_return,int *error_base_return),(dpy,event_base_return,error_base_return),return); SDL_X11_SYM(XRRScreenConfiguration *,XRRGetScreenInfo,(Display *dpy,Drawable draw),(dpy,draw),return) SDL_X11_SYM(SizeID,XRRConfigCurrentConfiguration,(XRRScreenConfiguration *config,Rotation *rotation),(config,rotation),return) SDL_X11_SYM(short,XRRConfigCurrentRate,(XRRScreenConfiguration *config),(config),return) @@ -304,35 +310,25 @@ SDL_X11_SYM(Atom*,XRRListOutputProperties,(Display *dpy, RROutput output, int *n SDL_X11_SYM(XRRPropertyInfo*,XRRQueryOutputProperty,(Display *dpy,RROutput output, Atom property),(dpy,output,property),return) SDL_X11_SYM(int,XRRGetOutputProperty,(Display *dpy,RROutput output, Atom property, long offset, long length, Bool _delete, Bool pending, Atom req_type, Atom *actual_type, int *actual_format, unsigned long *nitems, unsigned long *bytes_after, unsigned char **prop),(dpy,output,property,offset,length, _delete, pending, req_type, actual_type, actual_format, nitems, bytes_after, prop),return) SDL_X11_SYM(RROutput,XRRGetOutputPrimary,(Display *dpy,Window window),(dpy,window),return) +SDL_X11_SYM(void,XRRSelectInput,(Display *dpy, Window window, int mask),(dpy,window,mask),) #endif /* MIT-SCREEN-SAVER support */ -#if SDL_VIDEO_DRIVER_X11_XSCRNSAVER +#ifdef SDL_VIDEO_DRIVER_X11_XSCRNSAVER SDL_X11_MODULE(XSS) SDL_X11_SYM(Bool,XScreenSaverQueryExtension,(Display *dpy,int *event_base,int *error_base),(dpy,event_base,error_base),return) SDL_X11_SYM(Status,XScreenSaverQueryVersion,(Display *dpy,int *major_versionp,int *minor_versionp),(dpy,major_versionp,minor_versionp),return) SDL_X11_SYM(void,XScreenSaverSuspend,(Display *dpy,Bool suspend),(dpy,suspend),return) #endif -#if SDL_VIDEO_DRIVER_X11_XSHAPE +#ifdef SDL_VIDEO_DRIVER_X11_XSHAPE SDL_X11_MODULE(XSHAPE) SDL_X11_SYM(void,XShapeCombineMask,(Display *dpy,Window dest,int dest_kind,int x_off,int y_off,Pixmap src,int op),(dpy,dest,dest_kind,x_off,y_off,src,op),) #endif -#if SDL_VIDEO_DRIVER_X11_XVIDMODE -SDL_X11_MODULE(XVIDMODE) -SDL_X11_SYM(Bool,XF86VidModeGetAllModeLines,(Display *a,int b,int *c,XF86VidModeModeInfo ***d),(a,b,c,d),return) -SDL_X11_SYM(Bool,XF86VidModeGetModeLine,(Display *a,int b,int *c,XF86VidModeModeLine *d),(a,b,c,d),return) -SDL_X11_SYM(Bool,XF86VidModeGetViewPort,(Display *a,int b,int *c,int *d),(a,b,c,d),return) -SDL_X11_SYM(Bool,XF86VidModeQueryExtension,(Display *a,int *b,int *c),(a,b,c),return) -SDL_X11_SYM(Bool,XF86VidModeQueryVersion,(Display *a,int *b,int *c),(a,b,c),return) -SDL_X11_SYM(Bool,XF86VidModeSwitchToMode,(Display *a,int b,XF86VidModeModeInfo *c),(a,b,c),return) -SDL_X11_SYM(Bool,XF86VidModeLockModeSwitch,(Display *a,int b,int c),(a,b,c),return) -#endif - #undef SDL_X11_MODULE #undef SDL_X11_SYM -/* *INDENT-ON* */ +/* *INDENT-ON* */ /* clang-format on */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/x11/SDL_x11touch.c b/SDL2-2.30.5/src/video/x11/SDL_x11touch.c similarity index 82% rename from SDL2-2.0.12/src/video/x11/SDL_x11touch.c rename to SDL2-2.30.5/src/video/x11/SDL_x11touch.c index aef86aa..338001f 100644 --- a/SDL2-2.0.12/src/video/x11/SDL_x11touch.c +++ b/SDL2-2.30.5/src/video/x11/SDL_x11touch.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,30 +20,24 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_X11 +#ifdef SDL_VIDEO_DRIVER_X11 #include "SDL_x11video.h" #include "SDL_x11touch.h" #include "SDL_x11xinput2.h" #include "../../events/SDL_touch_c.h" - -void -X11_InitTouch(_THIS) +void X11_InitTouch(_THIS) { - if (X11_Xinput2IsMultitouchSupported()) { - X11_InitXinput2Multitouch(_this); - } + X11_InitXinput2Multitouch(_this); } -void -X11_QuitTouch(_THIS) +void X11_QuitTouch(_THIS) { SDL_TouchQuit(); } -void -X11_ResetTouch(_THIS) +void X11_ResetTouch(_THIS) { X11_QuitTouch(_this); X11_InitTouch(_this); diff --git a/SDL2-2.0.12/src/video/x11/SDL_x11touch.h b/SDL2-2.30.5/src/video/x11/SDL_x11touch.h similarity index 94% rename from SDL2-2.0.12/src/video/x11/SDL_x11touch.h rename to SDL2-2.30.5/src/video/x11/SDL_x11touch.h index fba3f27..ca6edac 100644 --- a/SDL2-2.0.12/src/video/x11/SDL_x11touch.h +++ b/SDL2-2.30.5/src/video/x11/SDL_x11touch.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/SDL2-2.0.12/src/video/x11/SDL_x11video.c b/SDL2-2.30.5/src/video/x11/SDL_x11video.c similarity index 74% rename from SDL2-2.0.12/src/video/x11/SDL_x11video.c rename to SDL2-2.30.5/src/video/x11/SDL_x11video.c index 76cce58..6a543c1 100644 --- a/SDL2-2.0.12/src/video/x11/SDL_x11video.c +++ b/SDL2-2.30.5/src/video/x11/SDL_x11video.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_X11 +#ifdef SDL_VIDEO_DRIVER_X11 #include /* For getpid() and readlink() */ @@ -36,8 +36,10 @@ #include "SDL_x11shape.h" #include "SDL_x11touch.h" #include "SDL_x11xinput2.h" +#include "SDL_x11xfixes.h" +#include "SDL_x11messagebox.h" -#if SDL_VIDEO_OPENGL_EGL +#ifdef SDL_VIDEO_OPENGL_EGL #include "SDL_x11opengles.h" #endif @@ -48,8 +50,7 @@ static int X11_VideoInit(_THIS); static void X11_VideoQuit(_THIS); /* Find out what class name we should use */ -static char * -get_classname() +static char *get_classname() { char *spot; #if defined(__LINUX__) || defined(__FREEBSD__) @@ -67,10 +68,9 @@ get_classname() /* Next look at the application's executable name */ #if defined(__LINUX__) || defined(__FREEBSD__) #if defined(__LINUX__) - SDL_snprintf(procfile, SDL_arraysize(procfile), "/proc/%d/exe", getpid()); + (void)SDL_snprintf(procfile, SDL_arraysize(procfile), "/proc/%d/exe", getpid()); #elif defined(__FREEBSD__) - SDL_snprintf(procfile, SDL_arraysize(procfile), "/proc/%d/file", - getpid()); + (void)SDL_snprintf(procfile, SDL_arraysize(procfile), "/proc/%d/file", getpid()); #else #error Where can we find the executable name? #endif @@ -92,31 +92,25 @@ get_classname() /* X11 driver bootstrap functions */ -static int -X11_Available(void) -{ - Display *display = NULL; - if (SDL_X11_LoadSymbols()) { - display = X11_XOpenDisplay(NULL); - if (display != NULL) { - X11_XCloseDisplay(display); - } - SDL_X11_UnloadSymbols(); - } - return (display != NULL); -} +static int (*orig_x11_errhandler)(Display *, XErrorEvent *) = NULL; -static void -X11_DeleteDevice(SDL_VideoDevice * device) +static void X11_DeleteDevice(SDL_VideoDevice *device) { - SDL_VideoData *data = (SDL_VideoData *) device->driverdata; + SDL_VideoData *data = (SDL_VideoData *)device->driverdata; if (device->vulkan_config.loader_handle) { device->Vulkan_UnloadLibrary(device); } if (data->display) { + X11_XSetErrorHandler(orig_x11_errhandler); X11_XCloseDisplay(data->display); } + if (data->request_display) { + X11_XCloseDisplay(data->request_display); + } SDL_free(data->windowlist); + if (device->wakeup_lock) { + SDL_DestroyMutex(device->wakeup_lock); + } SDL_free(device->driverdata); SDL_free(device); @@ -125,40 +119,44 @@ X11_DeleteDevice(SDL_VideoDevice * device) /* An error handler to reset the vidmode and then call the default handler. */ static SDL_bool safety_net_triggered = SDL_FALSE; -static int (*orig_x11_errhandler) (Display *, XErrorEvent *) = NULL; -static int -X11_SafetyNetErrHandler(Display * d, XErrorEvent * e) +static int X11_SafetyNetErrHandler(Display *d, XErrorEvent *e) { SDL_VideoDevice *device = NULL; /* if we trigger an error in our error handler, don't try again. */ if (!safety_net_triggered) { safety_net_triggered = SDL_TRUE; device = SDL_GetVideoDevice(); - if (device != NULL) { + if (device) { int i; for (i = 0; i < device->num_displays; i++) { SDL_VideoDisplay *display = &device->displays[i]; if (SDL_memcmp(&display->current_mode, &display->desktop_mode, - sizeof (SDL_DisplayMode)) != 0) { + sizeof(SDL_DisplayMode)) != 0) { X11_SetDisplayMode(device, display, &display->desktop_mode); } } } } - if (orig_x11_errhandler != NULL) { - return orig_x11_errhandler(d, e); /* probably terminate. */ + if (orig_x11_errhandler) { + return orig_x11_errhandler(d, e); /* probably terminate. */ } return 0; } -static SDL_VideoDevice * -X11_CreateDevice(int devindex) +static SDL_bool X11_IsXWayland(Display *d) +{ + int opcode, event, error; + return X11_XQueryExtension(d, "XWAYLAND", &opcode, &event, &error) == True; +} + +static SDL_VideoDevice *X11_CreateDevice(void) { SDL_VideoDevice *device; SDL_VideoData *data; const char *display = NULL; /* Use the DISPLAY environment variable */ + Display *x11_display = NULL; if (!SDL_X11_LoadSymbols()) { return NULL; @@ -168,13 +166,21 @@ X11_CreateDevice(int devindex) nVidia driver to be threaded. */ X11_XInitThreads(); + /* Open the display first to be sure that X11 is available */ + x11_display = X11_XOpenDisplay(display); + + if (!x11_display) { + SDL_X11_UnloadSymbols(); + return NULL; + } + /* Initialize all variables that we clean on shutdown */ - device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice)); + device = (SDL_VideoDevice *)SDL_calloc(1, sizeof(SDL_VideoDevice)); if (!device) { SDL_OutOfMemory(); return NULL; } - data = (struct SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData)); + data = (struct SDL_VideoData *)SDL_calloc(1, sizeof(SDL_VideoData)); if (!data) { SDL_free(device); SDL_OutOfMemory(); @@ -184,34 +190,22 @@ X11_CreateDevice(int devindex) data->global_mouse_changed = SDL_TRUE; - /* FIXME: Do we need this? - if ( (SDL_strncmp(X11_XDisplayName(display), ":", 1) == 0) || - (SDL_strncmp(X11_XDisplayName(display), "unix:", 5) == 0) ) { - local_X11 = 1; - } else { - local_X11 = 0; - } - */ - data->display = X11_XOpenDisplay(display); -#ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC - /* On some systems if linking without -lX11, it fails and you get following message. - * Xlib: connection to ":0.0" refused by server - * Xlib: XDM authorization key matches an existing client! - * - * It succeeds if retrying 1 second later - * or if running xhost +localhost on shell. - */ - if (data->display == NULL) { - SDL_Delay(1000); - data->display = X11_XOpenDisplay(display); - } -#endif - if (data->display == NULL) { +#ifdef SDL_VIDEO_DRIVER_X11_XFIXES + data->active_cursor_confined_window = NULL; +#endif /* SDL_VIDEO_DRIVER_X11_XFIXES */ + + data->display = x11_display; + data->request_display = X11_XOpenDisplay(display); + if (!data->request_display) { + X11_XCloseDisplay(data->display); SDL_free(device->driverdata); SDL_free(device); - SDL_SetError("Couldn't open X11 display"); + SDL_X11_UnloadSymbols(); return NULL; } + + device->wakeup_lock = SDL_CreateMutex(); + #ifdef X11_DEBUG X11_XSynchronize(data->display, True); #endif @@ -220,6 +214,11 @@ X11_CreateDevice(int devindex) safety_net_triggered = SDL_FALSE; orig_x11_errhandler = X11_XSetErrorHandler(X11_SafetyNetErrHandler); + /* Steam Deck will have an on-screen keyboard, so check their environment + * variable so we can make use of SDL_StartTextInput. + */ + data->is_steam_deck = SDL_GetHintBoolean("SteamDeck", SDL_FALSE); + /* Set the function pointers */ device->VideoInit = X11_VideoInit; device->VideoQuit = X11_VideoQuit; @@ -228,9 +227,12 @@ X11_CreateDevice(int devindex) device->GetDisplayBounds = X11_GetDisplayBounds; device->GetDisplayUsableBounds = X11_GetDisplayUsableBounds; device->GetDisplayDPI = X11_GetDisplayDPI; + device->GetWindowICCProfile = X11_GetWindowICCProfile; device->SetDisplayMode = X11_SetDisplayMode; device->SuspendScreenSaver = X11_SuspendScreenSaver; device->PumpEvents = X11_PumpEvents; + device->WaitEventTimeout = X11_WaitEventTimeout; + device->SendWakeupEvent = X11_SendWakeupEvent; device->CreateSDLWindow = X11_CreateWindow; device->CreateSDLWindowFrom = X11_CreateWindowFrom; @@ -252,9 +254,11 @@ X11_CreateDevice(int devindex) device->RestoreWindow = X11_RestoreWindow; device->SetWindowBordered = X11_SetWindowBordered; device->SetWindowResizable = X11_SetWindowResizable; + device->SetWindowAlwaysOnTop = X11_SetWindowAlwaysOnTop; device->SetWindowFullscreen = X11_SetWindowFullscreen; device->SetWindowGammaRamp = X11_SetWindowGammaRamp; - device->SetWindowGrab = X11_SetWindowGrab; + device->SetWindowMouseGrab = X11_SetWindowMouseGrab; + device->SetWindowKeyboardGrab = X11_SetWindowKeyboardGrab; device->DestroyWindow = X11_DestroyWindow; device->CreateWindowFramebuffer = X11_CreateWindowFramebuffer; device->UpdateWindowFramebuffer = X11_UpdateWindowFramebuffer; @@ -262,12 +266,17 @@ X11_CreateDevice(int devindex) device->GetWindowWMInfo = X11_GetWindowWMInfo; device->SetWindowHitTest = X11_SetWindowHitTest; device->AcceptDragAndDrop = X11_AcceptDragAndDrop; + device->FlashWindow = X11_FlashWindow; + +#ifdef SDL_VIDEO_DRIVER_X11_XFIXES + device->SetWindowMouseRect = X11_SetWindowMouseRect; +#endif /* SDL_VIDEO_DRIVER_X11_XFIXES */ device->shape_driver.CreateShaper = X11_CreateShaper; device->shape_driver.SetWindowShape = X11_SetWindowShape; device->shape_driver.ResizeWindowShape = X11_ResizeWindowShape; -#if SDL_VIDEO_OPENGL_GLX +#ifdef SDL_VIDEO_OPENGL_GLX device->GL_LoadLibrary = X11_GL_LoadLibrary; device->GL_GetProcAddress = X11_GL_GetProcAddress; device->GL_UnloadLibrary = X11_GL_UnloadLibrary; @@ -278,8 +287,8 @@ X11_CreateDevice(int devindex) device->GL_SwapWindow = X11_GL_SwapWindow; device->GL_DeleteContext = X11_GL_DeleteContext; #endif -#if SDL_VIDEO_OPENGL_EGL -#if SDL_VIDEO_OPENGL_GLX +#ifdef SDL_VIDEO_OPENGL_EGL +#ifdef SDL_VIDEO_OPENGL_GLX if (SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_FORCE_EGL, SDL_FALSE)) { #endif device->GL_LoadLibrary = X11_GLES_LoadLibrary; @@ -291,7 +300,7 @@ X11_CreateDevice(int devindex) device->GL_GetSwapInterval = X11_GLES_GetSwapInterval; device->GL_SwapWindow = X11_GLES_SwapWindow; device->GL_DeleteContext = X11_GLES_DeleteContext; -#if SDL_VIDEO_OPENGL_GLX +#ifdef SDL_VIDEO_OPENGL_GLX } #endif #endif @@ -299,42 +308,50 @@ X11_CreateDevice(int devindex) device->SetClipboardText = X11_SetClipboardText; device->GetClipboardText = X11_GetClipboardText; device->HasClipboardText = X11_HasClipboardText; + device->SetPrimarySelectionText = X11_SetPrimarySelectionText; + device->GetPrimarySelectionText = X11_GetPrimarySelectionText; + device->HasPrimarySelectionText = X11_HasPrimarySelectionText; device->StartTextInput = X11_StartTextInput; device->StopTextInput = X11_StopTextInput; device->SetTextInputRect = X11_SetTextInputRect; + device->HasScreenKeyboardSupport = X11_HasScreenKeyboardSupport; + device->ShowScreenKeyboard = X11_ShowScreenKeyboard; + device->HideScreenKeyboard = X11_HideScreenKeyboard; + device->IsScreenKeyboardShown = X11_IsScreenKeyboardShown; device->free = X11_DeleteDevice; -#if SDL_VIDEO_VULKAN +#ifdef SDL_VIDEO_VULKAN device->Vulkan_LoadLibrary = X11_Vulkan_LoadLibrary; device->Vulkan_UnloadLibrary = X11_Vulkan_UnloadLibrary; device->Vulkan_GetInstanceExtensions = X11_Vulkan_GetInstanceExtensions; device->Vulkan_CreateSurface = X11_Vulkan_CreateSurface; #endif + data->is_xwayland = X11_IsXWayland(x11_display); + return device; } VideoBootStrap X11_bootstrap = { "x11", "SDL X11 video driver", - X11_Available, X11_CreateDevice + X11_CreateDevice, + X11_ShowMessageBox }; -static int (*handler) (Display *, XErrorEvent *) = NULL; -static int -X11_CheckWindowManagerErrorHandler(Display * d, XErrorEvent * e) +static int (*handler)(Display *, XErrorEvent *) = NULL; +static int X11_CheckWindowManagerErrorHandler(Display *d, XErrorEvent *e) { if (e->error_code == BadWindow) { - return (0); + return 0; } else { - return (handler(d, e)); + return handler(d, e); } } -static void -X11_CheckWindowManager(_THIS) +static void X11_CheckWindowManager(_THIS) { - SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; Display *display = data->display; Atom _NET_SUPPORTING_WM_CHECK; int status, real_format; @@ -354,7 +371,7 @@ X11_CheckWindowManager(_THIS) status = X11_XGetWindowProperty(display, DefaultRootWindow(display), _NET_SUPPORTING_WM_CHECK, 0L, 1L, False, XA_WINDOW, &real_type, &real_format, &items_read, &items_left, &propdata); if (status == Success) { if (items_read) { - wm_window = ((Window*)propdata)[0]; + wm_window = ((Window *)propdata)[0]; } if (propdata) { X11_XFree(propdata); @@ -364,7 +381,7 @@ X11_CheckWindowManager(_THIS) if (wm_window) { status = X11_XGetWindowProperty(display, wm_window, _NET_SUPPORTING_WM_CHECK, 0L, 1L, False, XA_WINDOW, &real_type, &real_format, &items_read, &items_left, &propdata); - if (status != Success || !items_read || wm_window != ((Window*)propdata)[0]) { + if (status != Success || !items_read || wm_window != ((Window *)propdata)[0]) { wm_window = None; } if (status == Success && propdata) { @@ -392,11 +409,9 @@ X11_CheckWindowManager(_THIS) #endif } - -int -X11_VideoInit(_THIS) +int X11_VideoInit(_THIS) { - SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; /* Get the window class name, usually the name of the application */ data->classname = get_classname(); @@ -405,13 +420,14 @@ X11_VideoInit(_THIS) data->pid = getpid(); /* I have no idea how random this actually is, or has to be. */ - data->window_group = (XID) (((size_t) data->pid) ^ ((size_t) _this)); + data->window_group = (XID)(((size_t)data->pid) ^ ((size_t)_this)); /* Look up some useful Atoms */ #define GET_ATOM(X) data->X = X11_XInternAtom(data->display, #X, False) GET_ATOM(WM_PROTOCOLS); GET_ATOM(WM_DELETE_WINDOW); GET_ATOM(WM_TAKE_FOCUS); + GET_ATOM(WM_NAME); GET_ATOM(_NET_WM_STATE); GET_ATOM(_NET_WM_STATE_HIDDEN); GET_ATOM(_NET_WM_STATE_FOCUSED); @@ -431,6 +447,7 @@ X11_VideoInit(_THIS) GET_ATOM(_NET_WM_USER_TIME); GET_ATOM(_NET_ACTIVE_WINDOW); GET_ATOM(_NET_FRAME_EXTENTS); + GET_ATOM(_SDL_WAKEUP); GET_ATOM(UTF8_STRING); GET_ATOM(PRIMARY); GET_ATOM(XdndEnter); @@ -452,6 +469,14 @@ X11_VideoInit(_THIS) X11_InitXinput2(_this); +#ifdef SDL_VIDEO_DRIVER_X11_XFIXES + X11_InitXfixes(_this); +#endif /* SDL_VIDEO_DRIVER_X11_XFIXES */ + +#ifndef X_HAVE_UTF8_STRING +#warning X server does not support UTF8_STRING, a feature introduced in 2000! This is likely to become a hard error in a future libSDL2. +#endif + if (X11_InitKeyboard(_this) != 0) { return -1; } @@ -459,17 +484,12 @@ X11_VideoInit(_THIS) X11_InitTouch(_this); -#if SDL_USE_LIBDBUS - SDL_DBus_Init(); -#endif - return 0; } -void -X11_VideoQuit(_THIS) +void X11_VideoQuit(_THIS) { - SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; if (data->clipboard_window) { X11_XDestroyWindow(data->display, data->clipboard_window); @@ -486,16 +506,9 @@ X11_VideoQuit(_THIS) X11_QuitKeyboard(_this); X11_QuitMouse(_this); X11_QuitTouch(_this); - -/* !!! FIXME: other subsystems use D-Bus, so we shouldn't quit it here; - have SDL.c do this at a higher level, or add refcounting. */ -#if SDL_USE_LIBDBUS - SDL_DBus_Quit(); -#endif } -SDL_bool -X11_UseDirectColorVisuals(void) +SDL_bool X11_UseDirectColorVisuals(void) { return SDL_getenv("SDL_VIDEO_X11_NODIRECTCOLOR") ? SDL_FALSE : SDL_TRUE; } diff --git a/SDL2-2.0.12/src/video/x11/SDL_x11video.h b/SDL2-2.30.5/src/video/x11/SDL_x11video.h similarity index 80% rename from SDL2-2.0.12/src/video/x11/SDL_x11video.h rename to SDL2-2.30.5/src/video/x11/SDL_x11video.h index 04bedfb..a12a34b 100644 --- a/SDL2-2.0.12/src/video/x11/SDL_x11video.h +++ b/SDL2-2.30.5/src/video/x11/SDL_x11video.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -31,30 +31,24 @@ #include #include -#if SDL_VIDEO_DRIVER_X11_XCURSOR +#ifdef SDL_VIDEO_DRIVER_X11_XCURSOR #include #endif -#if SDL_VIDEO_DRIVER_X11_XDBE +#ifdef SDL_VIDEO_DRIVER_X11_XDBE #include #endif -#if SDL_VIDEO_DRIVER_X11_XINERAMA -#include -#endif -#if SDL_VIDEO_DRIVER_X11_XINPUT2 +#ifdef SDL_VIDEO_DRIVER_X11_XINPUT2 #include #endif -#if SDL_VIDEO_DRIVER_X11_XRANDR +#ifdef SDL_VIDEO_DRIVER_X11_XRANDR #include #endif -#if SDL_VIDEO_DRIVER_X11_XSCRNSAVER +#ifdef SDL_VIDEO_DRIVER_X11_XSCRNSAVER #include #endif -#if SDL_VIDEO_DRIVER_X11_XSHAPE +#ifdef SDL_VIDEO_DRIVER_X11_XSHAPE #include #endif -#if SDL_VIDEO_DRIVER_X11_XVIDMODE -#include -#endif #include "../../core/linux/SDL_dbus.h" #include "../../core/linux/SDL_ime.h" @@ -75,6 +69,7 @@ typedef struct SDL_VideoData { Display *display; + Display *request_display; char *classname; pid_t pid; XIM im; @@ -84,6 +79,9 @@ typedef struct SDL_VideoData int windowlistlength; XID window_group; Window clipboard_window; +#ifdef SDL_VIDEO_DRIVER_X11_XFIXES + SDL_Window *active_cursor_confined_window; +#endif /* SDL_VIDEO_DRIVER_X11_XFIXES */ /* This is true for ICCCM2.0-compliant window managers */ SDL_bool net_wm; @@ -92,6 +90,7 @@ typedef struct SDL_VideoData Atom WM_PROTOCOLS; Atom WM_DELETE_WINDOW; Atom WM_TAKE_FOCUS; + Atom WM_NAME; Atom _NET_WM_STATE; Atom _NET_WM_STATE_HIDDEN; Atom _NET_WM_STATE_FOCUSED; @@ -111,6 +110,7 @@ typedef struct SDL_VideoData Atom _NET_WM_USER_TIME; Atom _NET_ACTIVE_WINDOW; Atom _NET_FRAME_EXTENTS; + Atom _SDL_WAKEUP; Atom UTF8_STRING; Atom PRIMARY; Atom XdndEnter; @@ -126,7 +126,7 @@ typedef struct SDL_VideoData SDL_Scancode key_layout[256]; SDL_bool selection_waiting; - SDL_bool broken_pointer_grab; /* true if XGrabPointer seems unreliable. */ + SDL_bool broken_pointer_grab; /* true if XGrabPointer seems unreliable. */ Uint32 last_mode_change_deadline; @@ -134,19 +134,30 @@ typedef struct SDL_VideoData SDL_Point global_mouse_position; Uint32 global_mouse_buttons; -#if SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM + SDL_XInput2DeviceInfo *mouse_device_info; + + int xrandr_event_base; + +#ifdef SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM XkbDescPtr xkb; #endif + int xkb_event; KeyCode filter_code; - Time filter_time; + Time filter_time; -#if SDL_VIDEO_VULKAN +#ifdef SDL_VIDEO_VULKAN /* Vulkan variables only valid if _this->vulkan_config.loader_handle is not NULL */ void *vulkan_xlib_xcb_library; PFN_XGetXCBConnection vulkan_XGetXCBConnection; #endif + /* Used to interact with the on-screen keyboard */ + SDL_bool is_steam_deck; + SDL_bool steam_keyboard_open; + + SDL_bool is_xwayland; + } SDL_VideoData; extern SDL_bool X11_UseDirectColorVisuals(void); diff --git a/SDL2-2.0.12/src/video/x11/SDL_x11vulkan.c b/SDL2-2.30.5/src/video/x11/SDL_x11vulkan.c similarity index 77% rename from SDL2-2.0.12/src/video/x11/SDL_x11vulkan.c rename to SDL2-2.30.5/src/video/x11/SDL_x11vulkan.c index 24819cc..d9a0d2f 100644 --- a/SDL2-2.0.12/src/video/x11/SDL_x11vulkan.c +++ b/SDL2-2.30.5/src/video/x11/SDL_x11vulkan.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,16 +20,22 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_X11 +#if defined(SDL_VIDEO_VULKAN) && defined(SDL_VIDEO_DRIVER_X11) #include "SDL_x11video.h" -#include "SDL_assert.h" #include "SDL_loadso.h" #include "SDL_x11vulkan.h" #include /*#include */ + +#if defined(__OpenBSD__) +#define DEFAULT_VULKAN "libvulkan.so" +#else +#define DEFAULT_VULKAN "libvulkan.so.1" +#endif + /* typedef uint32_t xcb_window_t; typedef uint32_t xcb_visualid_t; @@ -45,73 +51,72 @@ int X11_Vulkan_LoadLibrary(_THIS, const char *path) SDL_bool hasXCBSurfaceExtension = SDL_FALSE; PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL; Uint32 i; - if(_this->vulkan_config.loader_handle) + if (_this->vulkan_config.loader_handle) { return SDL_SetError("Vulkan already loaded"); + } /* Load the Vulkan loader library */ - if(!path) + if (!path) { path = SDL_getenv("SDL_VULKAN_LIBRARY"); - if(!path) - path = "libvulkan.so.1"; + } + if (!path) { + path = DEFAULT_VULKAN; + } _this->vulkan_config.loader_handle = SDL_LoadObject(path); - if(!_this->vulkan_config.loader_handle) + if (!_this->vulkan_config.loader_handle) { return -1; + } SDL_strlcpy(_this->vulkan_config.loader_path, path, SDL_arraysize(_this->vulkan_config.loader_path)); vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)SDL_LoadFunction( _this->vulkan_config.loader_handle, "vkGetInstanceProcAddr"); - if(!vkGetInstanceProcAddr) + if (!vkGetInstanceProcAddr) { goto fail; + } _this->vulkan_config.vkGetInstanceProcAddr = (void *)vkGetInstanceProcAddr; _this->vulkan_config.vkEnumerateInstanceExtensionProperties = (void *)((PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr)( VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties"); - if(!_this->vulkan_config.vkEnumerateInstanceExtensionProperties) + if (!_this->vulkan_config.vkEnumerateInstanceExtensionProperties) { goto fail; + } extensions = SDL_Vulkan_CreateInstanceExtensionsList( (PFN_vkEnumerateInstanceExtensionProperties) _this->vulkan_config.vkEnumerateInstanceExtensionProperties, &extensionCount); - if(!extensions) + if (!extensions) { goto fail; - for(i = 0; i < extensionCount; i++) - { - if(SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) + } + for (i = 0; i < extensionCount; i++) { + if (SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) { hasSurfaceExtension = SDL_TRUE; - else if(SDL_strcmp(VK_KHR_XCB_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) + } else if (SDL_strcmp(VK_KHR_XCB_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) { hasXCBSurfaceExtension = SDL_TRUE; - else if(SDL_strcmp(VK_KHR_XLIB_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) + } else if (SDL_strcmp(VK_KHR_XLIB_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) { hasXlibSurfaceExtension = SDL_TRUE; + } } SDL_free(extensions); - if(!hasSurfaceExtension) - { - SDL_SetError("Installed Vulkan doesn't implement the " - VK_KHR_SURFACE_EXTENSION_NAME " extension"); + if (!hasSurfaceExtension) { + SDL_SetError("Installed Vulkan doesn't implement the " VK_KHR_SURFACE_EXTENSION_NAME " extension"); goto fail; } - if(hasXlibSurfaceExtension) - { + if (hasXlibSurfaceExtension) { videoData->vulkan_xlib_xcb_library = NULL; - } - else if(!hasXCBSurfaceExtension) - { - SDL_SetError("Installed Vulkan doesn't implement either the " - VK_KHR_XCB_SURFACE_EXTENSION_NAME "extension or the " - VK_KHR_XLIB_SURFACE_EXTENSION_NAME " extension"); + } else if (!hasXCBSurfaceExtension) { + SDL_SetError("Installed Vulkan doesn't implement either the " VK_KHR_XCB_SURFACE_EXTENSION_NAME "extension or the " VK_KHR_XLIB_SURFACE_EXTENSION_NAME " extension"); goto fail; - } - else - { + } else { const char *libX11XCBLibraryName = SDL_getenv("SDL_X11_XCB_LIBRARY"); - if(!libX11XCBLibraryName) + if (!libX11XCBLibraryName) { libX11XCBLibraryName = "libX11-xcb.so"; + } videoData->vulkan_xlib_xcb_library = SDL_LoadObject(libX11XCBLibraryName); - if(!videoData->vulkan_xlib_xcb_library) + if (!videoData->vulkan_xlib_xcb_library) { goto fail; + } videoData->vulkan_XGetXCBConnection = SDL_LoadFunction(videoData->vulkan_xlib_xcb_library, "XGetXCBConnection"); - if(!videoData->vulkan_XGetXCBConnection) - { + if (!videoData->vulkan_XGetXCBConnection) { SDL_UnloadObject(videoData->vulkan_xlib_xcb_library); goto fail; } @@ -127,10 +132,10 @@ fail: void X11_Vulkan_UnloadLibrary(_THIS) { SDL_VideoData *videoData = (SDL_VideoData *)_this->driverdata; - if(_this->vulkan_config.loader_handle) - { - if(videoData->vulkan_xlib_xcb_library) + if (_this->vulkan_config.loader_handle) { + if (videoData->vulkan_xlib_xcb_library) { SDL_UnloadObject(videoData->vulkan_xlib_xcb_library); + } SDL_UnloadObject(_this->vulkan_config.loader_handle); _this->vulkan_config.loader_handle = NULL; } @@ -142,23 +147,21 @@ SDL_bool X11_Vulkan_GetInstanceExtensions(_THIS, const char **names) { SDL_VideoData *videoData = (SDL_VideoData *)_this->driverdata; - if(!_this->vulkan_config.loader_handle) - { + if (!_this->vulkan_config.loader_handle) { SDL_SetError("Vulkan is not loaded"); return SDL_FALSE; } - if(videoData->vulkan_xlib_xcb_library) - { + if (videoData->vulkan_xlib_xcb_library) { static const char *const extensionsForXCB[] = { - VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_XCB_SURFACE_EXTENSION_NAME, + VK_KHR_SURFACE_EXTENSION_NAME, + VK_KHR_XCB_SURFACE_EXTENSION_NAME, }; return SDL_Vulkan_GetInstanceExtensions_Helper( count, names, SDL_arraysize(extensionsForXCB), extensionsForXCB); - } - else - { + } else { static const char *const extensionsForXlib[] = { - VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_XLIB_SURFACE_EXTENSION_NAME, + VK_KHR_SURFACE_EXTENSION_NAME, + VK_KHR_XLIB_SURFACE_EXTENSION_NAME, }; return SDL_Vulkan_GetInstanceExtensions_Helper( count, names, SDL_arraysize(extensionsForXlib), extensionsForXlib); @@ -173,21 +176,18 @@ SDL_bool X11_Vulkan_CreateSurface(_THIS, SDL_VideoData *videoData = (SDL_VideoData *)_this->driverdata; SDL_WindowData *windowData = (SDL_WindowData *)window->driverdata; PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr; - if(!_this->vulkan_config.loader_handle) - { + if (!_this->vulkan_config.loader_handle) { SDL_SetError("Vulkan is not loaded"); return SDL_FALSE; } vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr; - if(videoData->vulkan_xlib_xcb_library) - { + if (videoData->vulkan_xlib_xcb_library) { PFN_vkCreateXcbSurfaceKHR vkCreateXcbSurfaceKHR = (PFN_vkCreateXcbSurfaceKHR)vkGetInstanceProcAddr(instance, "vkCreateXcbSurfaceKHR"); VkXcbSurfaceCreateInfoKHR createInfo; VkResult result; - if(!vkCreateXcbSurfaceKHR) - { + if (!vkCreateXcbSurfaceKHR) { SDL_SetError(VK_KHR_XCB_SURFACE_EXTENSION_NAME " extension is not enabled in the Vulkan instance."); return SDL_FALSE; @@ -195,30 +195,25 @@ SDL_bool X11_Vulkan_CreateSurface(_THIS, SDL_zero(createInfo); createInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR; createInfo.connection = videoData->vulkan_XGetXCBConnection(videoData->display); - if(!createInfo.connection) - { + if (!createInfo.connection) { SDL_SetError("XGetXCBConnection failed"); return SDL_FALSE; } createInfo.window = (xcb_window_t)windowData->xwindow; result = vkCreateXcbSurfaceKHR(instance, &createInfo, NULL, surface); - if(result != VK_SUCCESS) - { + if (result != VK_SUCCESS) { SDL_SetError("vkCreateXcbSurfaceKHR failed: %s", SDL_Vulkan_GetResultString(result)); return SDL_FALSE; } return SDL_TRUE; - } - else - { + } else { PFN_vkCreateXlibSurfaceKHR vkCreateXlibSurfaceKHR = (PFN_vkCreateXlibSurfaceKHR)vkGetInstanceProcAddr(instance, "vkCreateXlibSurfaceKHR"); VkXlibSurfaceCreateInfoKHR createInfo; VkResult result; - if(!vkCreateXlibSurfaceKHR) - { + if (!vkCreateXlibSurfaceKHR) { SDL_SetError(VK_KHR_XLIB_SURFACE_EXTENSION_NAME " extension is not enabled in the Vulkan instance."); return SDL_FALSE; @@ -229,8 +224,7 @@ SDL_bool X11_Vulkan_CreateSurface(_THIS, createInfo.window = (xcb_window_t)windowData->xwindow; result = vkCreateXlibSurfaceKHR(instance, &createInfo, NULL, surface); - if(result != VK_SUCCESS) - { + if (result != VK_SUCCESS) { SDL_SetError("vkCreateXlibSurfaceKHR failed: %s", SDL_Vulkan_GetResultString(result)); return SDL_FALSE; } diff --git a/SDL2-2.0.12/src/video/x11/SDL_x11vulkan.h b/SDL2-2.30.5/src/video/x11/SDL_x11vulkan.h similarity index 93% rename from SDL2-2.0.12/src/video/x11/SDL_x11vulkan.h rename to SDL2-2.30.5/src/video/x11/SDL_x11vulkan.h index c747072..438b16d 100644 --- a/SDL2-2.0.12/src/video/x11/SDL_x11vulkan.h +++ b/SDL2-2.30.5/src/video/x11/SDL_x11vulkan.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -25,7 +25,7 @@ #include "../SDL_vulkan_internal.h" -#if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_X11 +#if defined(SDL_VIDEO_VULKAN) && defined(SDL_VIDEO_DRIVER_X11) /*typedef struct xcb_connection_t xcb_connection_t;*/ typedef xcb_connection_t *(*PFN_XGetXCBConnection)(Display *dpy); diff --git a/SDL2-2.0.12/src/video/x11/SDL_x11window.c b/SDL2-2.30.5/src/video/x11/SDL_x11window.c similarity index 55% rename from SDL2-2.0.12/src/video/x11/SDL_x11window.c rename to SDL2-2.30.5/src/video/x11/SDL_x11window.c index f1a7948..07ec431 100644 --- a/SDL2-2.0.12/src/video/x11/SDL_x11window.c +++ b/SDL2-2.30.5/src/video/x11/SDL_x11window.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,38 +20,38 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_DRIVER_X11 +#ifdef SDL_VIDEO_DRIVER_X11 -#include "SDL_assert.h" #include "SDL_hints.h" #include "../SDL_sysvideo.h" #include "../SDL_pixels_c.h" #include "../../events/SDL_keyboard_c.h" #include "../../events/SDL_mouse_c.h" +#include "../../events/SDL_events_c.h" #include "SDL_x11video.h" #include "SDL_x11mouse.h" #include "SDL_x11shape.h" #include "SDL_x11xinput2.h" +#include "SDL_x11xfixes.h" -#if SDL_VIDEO_OPENGL_EGL +#ifdef SDL_VIDEO_OPENGL_EGL #include "SDL_x11opengles.h" #endif #include "SDL_timer.h" #include "SDL_syswm.h" -#include "SDL_log.h" -#define _NET_WM_STATE_REMOVE 0l -#define _NET_WM_STATE_ADD 1l +#define _NET_WM_STATE_REMOVE 0l +#define _NET_WM_STATE_ADD 1l -static Bool isMapNotify(Display *dpy, XEvent *ev, XPointer win) +static Bool isMapNotify(Display *dpy, XEvent *ev, XPointer win) /* NOLINT(readability-non-const-parameter): cannot make XPointer a const pointer due to typedef */ { - return ev->type == MapNotify && ev->xmap.window == *((Window*)win); + return ev->type == MapNotify && ev->xmap.window == *((Window *)win); } -static Bool isUnmapNotify(Display *dpy, XEvent *ev, XPointer win) +static Bool isUnmapNotify(Display *dpy, XEvent *ev, XPointer win) /* NOLINT(readability-non-const-parameter): cannot make XPointer a const pointer due to typedef */ { - return ev->type == UnmapNotify && ev->xunmap.window == *((Window*)win); + return ev->type == UnmapNotify && ev->xunmap.window == *((Window *)win); } /* @@ -59,8 +59,7 @@ static Bool isConfigureNotify(Display *dpy, XEvent *ev, XPointer win) { return ev->type == ConfigureNotify && ev->xconfigure.window == *((Window*)win); } -static Bool -X11_XIfEventTimeout(Display *display, XEvent *event_return, Bool (*predicate)(), XPointer arg, int timeoutMS) +static Bool X11_XIfEventTimeout(Display *display, XEvent *event_return, Bool (*predicate)(), XPointer arg, int timeoutMS) { Uint32 start = SDL_GetTicks(); @@ -73,18 +72,10 @@ X11_XIfEventTimeout(Display *display, XEvent *event_return, Bool (*predicate)(), } */ -static SDL_bool -X11_IsWindowLegacyFullscreen(_THIS, SDL_Window * window) +static SDL_bool X11_IsWindowMapped(_THIS, SDL_Window *window) { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - return (data->fswindow != 0); -} - -static SDL_bool -X11_IsWindowMapped(_THIS, SDL_Window * window) -{ - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; XWindowAttributes attr; X11_XGetWindowAttributes(videodata->display, data->xwindow, &attr); @@ -96,8 +87,7 @@ X11_IsWindowMapped(_THIS, SDL_Window * window) } #if 0 -static SDL_bool -X11_IsActionAllowed(SDL_Window *window, Atom action) +static SDL_bool X11_IsActionAllowed(SDL_Window *window, Atom action) { SDL_WindowData *data = (SDL_WindowData *) window->driverdata; Atom _NET_WM_ALLOWED_ACTIONS = data->videodata->_NET_WM_ALLOWED_ACTIONS; @@ -109,10 +99,8 @@ X11_IsActionAllowed(SDL_Window *window, Atom action) Atom *list; SDL_bool ret = SDL_FALSE; - if (X11_XGetWindowProperty(display, data->xwindow, _NET_WM_ALLOWED_ACTIONS, 0, 1024, False, XA_ATOM, &type, &form, &len, &remain, (unsigned char **)&list) == Success) - { - for (i=0; ixwindow, _NET_WM_ALLOWED_ACTIONS, 0, 1024, False, XA_ATOM, &type, &form, &len, &remain, (unsigned char **)&list) == Success) { + for (i=0; idriverdata; + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; Display *display = videodata->display; /* !!! FIXME: just dereference videodata below instead of copying to locals. */ Atom _NET_WM_STATE = videodata->_NET_WM_STATE; @@ -173,16 +160,15 @@ X11_SetNetWMState(_THIS, Window xwindow, Uint32 flags) if (count > 0) { X11_XChangeProperty(display, xwindow, _NET_WM_STATE, XA_ATOM, 32, - PropModeReplace, (unsigned char *)atoms, count); + PropModeReplace, (unsigned char *)atoms, count); } else { X11_XDeleteProperty(display, xwindow, _NET_WM_STATE); } } -Uint32 -X11_GetNetWMState(_THIS, Window xwindow) +Uint32 X11_GetNetWMState(_THIS, SDL_Window *window, Window xwindow) { - SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; Display *display = videodata->display; Atom _NET_WM_STATE = videodata->_NET_WM_STATE; Atom _NET_WM_STATE_HIDDEN = videodata->_NET_WM_STATE_HIDDEN; @@ -198,10 +184,10 @@ X11_GetNetWMState(_THIS, Window xwindow) Uint32 flags = 0; if (X11_XGetWindowProperty(display, xwindow, _NET_WM_STATE, - 0l, maxLength, False, XA_ATOM, &actualType, - &actualFormat, &numItems, &bytesAfter, - &propertyValue) == Success) { - Atom *atoms = (Atom *) propertyValue; + 0l, maxLength, False, XA_ATOM, &actualType, + &actualFormat, &numItems, &bytesAfter, + &propertyValue) == Success) { + Atom *atoms = (Atom *)propertyValue; int maximized = 0; int fullscreen = 0; @@ -214,25 +200,38 @@ X11_GetNetWMState(_THIS, Window xwindow) maximized |= 1; } else if (atoms[i] == _NET_WM_STATE_MAXIMIZED_HORZ) { maximized |= 2; - } else if ( atoms[i] == _NET_WM_STATE_FULLSCREEN) { + } else if (atoms[i] == _NET_WM_STATE_FULLSCREEN) { fullscreen = 1; } } - if (maximized == 3) { - flags |= SDL_WINDOW_MAXIMIZED; - } if (fullscreen == 1) { flags |= SDL_WINDOW_FULLSCREEN; } + if (maximized == 3) { + /* Fullscreen windows are maximized on some window managers, + and this is functional behavior - if maximized is removed, + the windows remain floating centered and not covering the + rest of the desktop. So we just won't change the maximize + state for fullscreen windows here, otherwise SDL would think + we're always maximized when fullscreen and not restore the + correct state when leaving fullscreen. + */ + if (fullscreen) { + flags |= (window->flags & SDL_WINDOW_MAXIMIZED); + } else { + flags |= SDL_WINDOW_MAXIMIZED; + } + } + /* If the window is unmapped, numItems will be zero and _NET_WM_STATE_HIDDEN * will not be set. Do an additional check to see if the window is unmapped * and mark it as SDL_WINDOW_HIDDEN if it is. */ { XWindowAttributes attr; - SDL_memset(&attr,0,sizeof(attr)); + SDL_memset(&attr, 0, sizeof(attr)); X11_XGetWindowAttributes(videodata->display, xwindow, &attr); if (attr.map_state == IsUnmapped) { flags |= SDL_WINDOW_HIDDEN; @@ -247,28 +246,28 @@ X11_GetNetWMState(_THIS, Window xwindow) return flags; } -static int -SetupWindowData(_THIS, SDL_Window * window, Window w, BOOL created) +static int SetupWindowData(_THIS, SDL_Window *window, Window w, BOOL created) { - SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; + SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; SDL_WindowData *data; int numwindows = videodata->numwindows; int windowlistlength = videodata->windowlistlength; SDL_WindowData **windowlist = videodata->windowlist; /* Allocate the window data */ - data = (SDL_WindowData *) SDL_calloc(1, sizeof(*data)); + data = (SDL_WindowData *)SDL_calloc(1, sizeof(*data)); if (!data) { return SDL_OutOfMemory(); } data->window = window; data->xwindow = w; + #ifdef X_HAVE_UTF8_STRING if (SDL_X11_HAVE_UTF8 && videodata->im) { data->ic = X11_XCreateIC(videodata->im, XNClientWindow, w, XNFocusWindow, w, - XNInputStyle, XIMPreeditNothing | XIMStatusNothing, - NULL); + XNInputStyle, XIMPreeditNothing | XIMStatusNothing, + NULL); } #endif data->created = created; @@ -281,9 +280,10 @@ SetupWindowData(_THIS, SDL_Window * window, Window w, BOOL created) videodata->numwindows++; } else { windowlist = - (SDL_WindowData **) SDL_realloc(windowlist, - (numwindows + - 1) * sizeof(*windowlist)); + (SDL_WindowData **)SDL_realloc(windowlist, + (numwindows + + 1) * + sizeof(*windowlist)); if (!windowlist) { SDL_free(data); return SDL_OutOfMemory(); @@ -312,14 +312,13 @@ SetupWindowData(_THIS, SDL_Window * window, Window w, BOOL created) data->colormap = attrib.colormap; } - window->flags |= X11_GetNetWMState(_this, w); + window->flags |= X11_GetNetWMState(_this, window, w); { Window FocalWindow; - int RevertTo=0; + int RevertTo = 0; X11_XGetInputFocus(data->videodata->display, &FocalWindow, &RevertTo); - if (FocalWindow==w) - { + if (FocalWindow == w) { window->flags |= SDL_WINDOW_INPUT_FOCUS; } @@ -327,7 +326,7 @@ SetupWindowData(_THIS, SDL_Window * window, Window w, BOOL created) SDL_SetKeyboardFocus(data->window); } - if (window->flags & SDL_WINDOW_INPUT_GRABBED) { + if (window->flags & SDL_WINDOW_MOUSE_GRABBED) { /* Tell x11 to clip mouse */ } } @@ -337,8 +336,7 @@ SetupWindowData(_THIS, SDL_Window * window, Window w, BOOL created) return 0; } -static void -SetWindowBordered(Display *display, int screen, Window window, SDL_bool border) +static void SetWindowBordered(Display *display, int screen, Window window, SDL_bool border) { /* * this code used to check for KWM_WIN_DECORATION, but KDE hasn't @@ -361,19 +359,19 @@ SetWindowBordered(Display *display, int screen, Window window, SDL_bool border) }; X11_XChangeProperty(display, window, WM_HINTS, WM_HINTS, 32, - PropModeReplace, (unsigned char *) &MWMHints, - sizeof(MWMHints) / sizeof(long)); - } else { /* set the transient hints instead, if necessary */ + PropModeReplace, (unsigned char *)&MWMHints, + sizeof(MWMHints) / sizeof(long)); + } else { /* set the transient hints instead, if necessary */ X11_XSetTransientForHint(display, window, RootWindow(display, screen)); } } -int -X11_CreateWindow(_THIS, SDL_Window * window) +int X11_CreateWindow(_THIS, SDL_Window *window) { - SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; SDL_DisplayData *displaydata = - (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; + (SDL_DisplayData *)SDL_GetDisplayForWindow(window)->driverdata; + const SDL_bool force_override_redirect = SDL_GetHintBoolean(SDL_HINT_X11_FORCE_OVERRIDE_REDIRECT, SDL_FALSE); SDL_WindowData *windowdata; Display *display = data->display; int screen = displaydata->screen; @@ -391,12 +389,12 @@ X11_CreateWindow(_THIS, SDL_Window * window) long compositor = 1; Atom _NET_WM_PID; long fevent = 0; + const char *hint = NULL; -#if SDL_VIDEO_OPENGL_GLX || SDL_VIDEO_OPENGL_EGL +#if defined(SDL_VIDEO_OPENGL_GLX) || defined(SDL_VIDEO_OPENGL_EGL) const char *forced_visual_id = SDL_GetHint(SDL_HINT_VIDEO_X11_WINDOW_VISUALID); - if (forced_visual_id != NULL && forced_visual_id[0] != '\0') - { + if (forced_visual_id && forced_visual_id[0] != '\0') { XVisualInfo *vi, template; int nvis; @@ -407,28 +405,25 @@ X11_CreateWindow(_THIS, SDL_Window * window) visual = vi->visual; depth = vi->depth; X11_XFree(vi); - } - else - { + } else { return -1; } - } - else if ((window->flags & SDL_WINDOW_OPENGL) && - !SDL_getenv("SDL_VIDEO_X11_VISUALID")) { + } else if ((window->flags & SDL_WINDOW_OPENGL) && + !SDL_getenv("SDL_VIDEO_X11_VISUALID")) { XVisualInfo *vinfo = NULL; -#if SDL_VIDEO_OPENGL_EGL +#ifdef SDL_VIDEO_OPENGL_EGL if (((_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) || SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_FORCE_EGL, SDL_FALSE)) -#if SDL_VIDEO_OPENGL_GLX - && ( !_this->gl_data || X11_GL_UseEGL(_this) ) +#ifdef SDL_VIDEO_OPENGL_GLX + && (!_this->gl_data || X11_GL_UseEGL(_this) ) #endif ) { vinfo = X11_GLES_GetVisual(_this, display, screen); } else #endif { -#if SDL_VIDEO_OPENGL_GLX +#ifdef SDL_VIDEO_OPENGL_GLX vinfo = X11_GL_GetVisual(_this, display, screen); #endif } @@ -446,7 +441,8 @@ X11_CreateWindow(_THIS, SDL_Window * window) depth = displaydata->depth; } - xattr.override_redirect = ((window->flags & SDL_WINDOW_TOOLTIP) || (window->flags & SDL_WINDOW_POPUP_MENU)) ? True : False; + xattr.override_redirect = ((window->flags & SDL_WINDOW_TOOLTIP) || (window->flags & SDL_WINDOW_POPUP_MENU) || force_override_redirect) ? True : False; + xattr.backing_store = NotUseful; xattr.background_pixmap = None; xattr.border_pixel = 0; @@ -460,7 +456,7 @@ X11_CreateWindow(_THIS, SDL_Window * window) xattr.colormap = X11_XCreateColormap(display, RootWindow(display, screen), - visual, AllocAll); + visual, AllocAll); /* If we can't create a colormap, then we must die */ if (!xattr.colormap) { @@ -526,14 +522,21 @@ X11_CreateWindow(_THIS, SDL_Window * window) } else { xattr.colormap = X11_XCreateColormap(display, RootWindow(display, screen), - visual, AllocNone); + visual, AllocNone); } + /* Always create this with the window->windowed.* fields; if we're + creating a windowed mode window, that's fine. If we're creating a + fullscreen window, the window manager will want to know these values + so it can use them if we go _back_ to windowed mode. SDL manages + migration to fullscreen after CreateSDLWindow returns, which will + put all the SDL_Window fields and system state as expected. */ w = X11_XCreateWindow(display, RootWindow(display, screen), - window->x, window->y, window->w, window->h, - 0, depth, InputOutput, visual, - (CWOverrideRedirect | CWBackPixmap | CWBorderPixel | - CWColormap), &xattr); + window->windowed.x, window->windowed.y, window->windowed.w, window->windowed.h, + 0, depth, InputOutput, visual, + (CWOverrideRedirect | CWBackPixmap | CWBorderPixel | + CWBackingStore | CWColormap), + &xattr); if (!w) { return SDL_SetError("Couldn't create window"); } @@ -572,38 +575,40 @@ X11_CreateWindow(_THIS, SDL_Window * window) X11_XFree(classhints); /* Set the PID related to the window for the given hostname, if possible */ if (data->pid > 0) { - long pid = (long) data->pid; + long pid = (long)data->pid; _NET_WM_PID = X11_XInternAtom(display, "_NET_WM_PID", False); X11_XChangeProperty(display, w, _NET_WM_PID, XA_CARDINAL, 32, PropModeReplace, - (unsigned char *) &pid, 1); + (unsigned char *)&pid, 1); } /* Set the window manager state */ X11_SetNetWMState(_this, w, window->flags); - compositor = 2; /* don't disable compositing except for "normal" windows */ - + compositor = 2; /* don't disable compositing except for "normal" windows */ + hint = SDL_GetHint(SDL_HINT_X11_WINDOW_TYPE); if (window->flags & SDL_WINDOW_UTILITY) { wintype_name = "_NET_WM_WINDOW_TYPE_UTILITY"; } else if (window->flags & SDL_WINDOW_TOOLTIP) { wintype_name = "_NET_WM_WINDOW_TYPE_TOOLTIP"; } else if (window->flags & SDL_WINDOW_POPUP_MENU) { wintype_name = "_NET_WM_WINDOW_TYPE_POPUP_MENU"; + } else if (hint && *hint) { + wintype_name = hint; } else { wintype_name = "_NET_WM_WINDOW_TYPE_NORMAL"; - compositor = 1; /* disable compositing for "normal" windows */ + compositor = 1; /* disable compositing for "normal" windows */ } /* Let the window manager know what type of window we are. */ _NET_WM_WINDOW_TYPE = X11_XInternAtom(display, "_NET_WM_WINDOW_TYPE", False); wintype = X11_XInternAtom(display, wintype_name, False); X11_XChangeProperty(display, w, _NET_WM_WINDOW_TYPE, XA_ATOM, 32, - PropModeReplace, (unsigned char *)&wintype, 1); + PropModeReplace, (unsigned char *)&wintype, 1); if (SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, SDL_TRUE)) { _NET_WM_BYPASS_COMPOSITOR = X11_XInternAtom(display, "_NET_WM_BYPASS_COMPOSITOR", False); X11_XChangeProperty(display, w, _NET_WM_BYPASS_COMPOSITOR, XA_CARDINAL, 32, - PropModeReplace, - (unsigned char *)&compositor, 1); + PropModeReplace, + (unsigned char *)&compositor, 1); } { @@ -611,7 +616,7 @@ X11_CreateWindow(_THIS, SDL_Window * window) int proto_count = 0; protocols[proto_count++] = data->WM_DELETE_WINDOW; /* Allow window to be deleted by the WM */ - protocols[proto_count++] = data->WM_TAKE_FOCUS; /* Since we will want to set input focus explicitly */ + protocols[proto_count++] = data->WM_TAKE_FOCUS; /* Since we will want to set input focus explicitly */ /* Default to using ping if there is no hint */ if (SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_NET_WM_PING, SDL_TRUE)) { @@ -627,23 +632,23 @@ X11_CreateWindow(_THIS, SDL_Window * window) X11_XDestroyWindow(display, w); return -1; } - windowdata = (SDL_WindowData *) window->driverdata; + windowdata = (SDL_WindowData *)window->driverdata; -#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 || SDL_VIDEO_OPENGL_EGL - if ((window->flags & SDL_WINDOW_OPENGL) && +#if defined(SDL_VIDEO_OPENGL_ES) || defined(SDL_VIDEO_OPENGL_ES2) || defined(SDL_VIDEO_OPENGL_EGL) + if ((window->flags & SDL_WINDOW_OPENGL) && ((_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) || SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_FORCE_EGL, SDL_FALSE)) -#if SDL_VIDEO_OPENGL_GLX - && ( !_this->gl_data || X11_GL_UseEGL(_this) ) -#endif +#ifdef SDL_VIDEO_OPENGL_GLX + && (!_this->gl_data || X11_GL_UseEGL(_this) ) +#endif ) { -#if SDL_VIDEO_OPENGL_EGL +#ifdef SDL_VIDEO_OPENGL_EGL if (!_this->egl_data) { return -1; } /* Create the GLES window surface */ - windowdata->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) w); + windowdata->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType)w); if (windowdata->egl_surface == EGL_NO_SURFACE) { return SDL_SetError("Could not create GLES window surface"); @@ -653,7 +658,6 @@ X11_CreateWindow(_THIS, SDL_Window * window) #endif /* SDL_VIDEO_OPENGL_EGL */ } #endif - #ifdef X_HAVE_UTF8_STRING if (SDL_X11_HAVE_UTF8 && windowdata->ic) { @@ -664,21 +668,23 @@ X11_CreateWindow(_THIS, SDL_Window * window) X11_Xinput2SelectTouch(_this, window); X11_XSelectInput(display, w, - (FocusChangeMask | EnterWindowMask | LeaveWindowMask | - ExposureMask | ButtonPressMask | ButtonReleaseMask | - PointerMotionMask | KeyPressMask | KeyReleaseMask | - PropertyChangeMask | StructureNotifyMask | - KeymapStateMask | fevent)); + (FocusChangeMask | EnterWindowMask | LeaveWindowMask | + ExposureMask | ButtonPressMask | ButtonReleaseMask | + PointerMotionMask | KeyPressMask | KeyReleaseMask | + PropertyChangeMask | StructureNotifyMask | + KeymapStateMask | fevent)); + + /* For _ICC_PROFILE. */ + X11_XSelectInput(display, RootWindow(display, screen), PropertyChangeMask); X11_XFlush(display); return 0; } -int -X11_CreateWindowFrom(_THIS, SDL_Window * window, const void *data) +int X11_CreateWindowFrom(_THIS, SDL_Window *window, const void *data) { - Window w = (Window) data; + Window w = (Window)data; window->title = X11_GetWindowTitle(_this, w); @@ -688,10 +694,9 @@ X11_CreateWindowFrom(_THIS, SDL_Window * window, const void *data) return 0; } -char * -X11_GetWindowTitle(_THIS, Window xwindow) +char *X11_GetWindowTitle(_THIS, Window xwindow) { - SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; Display *display = data->display; int status, real_format; Atom real_type; @@ -700,70 +705,40 @@ X11_GetWindowTitle(_THIS, Window xwindow) char *title = NULL; status = X11_XGetWindowProperty(display, xwindow, data->_NET_WM_NAME, - 0L, 8192L, False, data->UTF8_STRING, &real_type, &real_format, - &items_read, &items_left, &propdata); + 0L, 8192L, False, data->UTF8_STRING, &real_type, &real_format, + &items_read, &items_left, &propdata); if (status == Success && propdata) { - title = SDL_strdup(SDL_static_cast(char*, propdata)); + title = SDL_strdup(SDL_static_cast(char *, propdata)); X11_XFree(propdata); } else { status = X11_XGetWindowProperty(display, xwindow, XA_WM_NAME, - 0L, 8192L, False, XA_STRING, &real_type, &real_format, - &items_read, &items_left, &propdata); + 0L, 8192L, False, XA_STRING, &real_type, &real_format, + &items_read, &items_left, &propdata); if (status == Success && propdata) { - title = SDL_iconv_string("UTF-8", "", SDL_static_cast(char*, propdata), items_read+1); + title = SDL_iconv_string("UTF-8", "", SDL_static_cast(char *, propdata), items_read + 1); + SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Failed to convert WM_NAME title expecting UTF8! Title: %s", title); X11_XFree(propdata); } else { + SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Could not get any window title response from Xorg, returning empty string!"); title = SDL_strdup(""); } } return title; } -void -X11_SetWindowTitle(_THIS, SDL_Window * window) +void X11_SetWindowTitle(_THIS, SDL_Window *window) { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + Window xwindow = data->xwindow; Display *display = data->videodata->display; - XTextProperty titleprop; - Status status; - const char *title = window->title ? window->title : ""; - char *title_locale = NULL; + char *title = window->title ? window->title : ""; -#ifdef X_HAVE_UTF8_STRING - Atom _NET_WM_NAME = data->videodata->_NET_WM_NAME; -#endif - - title_locale = SDL_iconv_utf8_locale(title); - if (!title_locale) { - SDL_OutOfMemory(); - return; - } - - status = X11_XStringListToTextProperty(&title_locale, 1, &titleprop); - SDL_free(title_locale); - if (status) { - X11_XSetTextProperty(display, data->xwindow, &titleprop, XA_WM_NAME); - X11_XFree(titleprop.value); - } -#ifdef X_HAVE_UTF8_STRING - if (SDL_X11_HAVE_UTF8) { - status = X11_Xutf8TextListToTextProperty(display, (char **) &title, 1, - XUTF8StringStyle, &titleprop); - if (status == Success) { - X11_XSetTextProperty(display, data->xwindow, &titleprop, - _NET_WM_NAME); - X11_XFree(titleprop.value); - } - } -#endif - - X11_XFlush(display); + SDL_X11_SetWindowTitle(display, xwindow, title); } -void -X11_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon) +void X11_SetWindowIcon(_THIS, SDL_Window *window, SDL_Surface *icon) { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; Display *display = data->videodata->display; Atom _NET_WM_ICON = data->videodata->_NET_WM_ICON; @@ -784,14 +759,14 @@ X11_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon) propdata[1] = icon->h; dst = &propdata[2]; for (y = 0; y < icon->h; ++y) { - src = (Uint32*)((Uint8*)icon->pixels + y * icon->pitch); + src = (Uint32 *)((Uint8 *)icon->pixels + y * icon->pitch); for (x = 0; x < icon->w; ++x) { *dst++ = *src++; } } X11_XChangeProperty(display, data->xwindow, _NET_WM_ICON, XA_CARDINAL, - 32, PropModeReplace, (unsigned char *) propdata, - propsize); + 32, PropModeReplace, (unsigned char *)propdata, + propsize); } SDL_free(propdata); } else { @@ -800,15 +775,25 @@ X11_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon) X11_XFlush(display); } -void -X11_SetWindowPosition(_THIS, SDL_Window * window) +static SDL_bool caught_x11_error = SDL_FALSE; +static int X11_CatchAnyError(Display *d, XErrorEvent *e) { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + /* this may happen during tumultuous times when we are polling anyhow, + so just note we had an error and return control. */ + caught_x11_error = SDL_TRUE; + return 0; +} + +void X11_SetWindowPosition(_THIS, SDL_Window *window) +{ + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; Display *display = data->videodata->display; + int (*prev_handler)(Display *, XErrorEvent *) = NULL; unsigned int childCount; Window childReturn, root, parent; - Window* children; + Window *children; XWindowAttributes attrs; + int x, y; int orig_x, orig_y; Uint32 timeout; @@ -823,20 +808,23 @@ X11_SetWindowPosition(_THIS, SDL_Window * window) /* Wait a brief time to see if the window manager decided to let this move happen. If the window changes at all, even to an unexpected value, we break out. */ + X11_XSync(display, False); + prev_handler = X11_XSetErrorHandler(X11_CatchAnyError); + timeout = SDL_GetTicks() + 100; while (SDL_TRUE) { - int x, y; + caught_x11_error = SDL_FALSE; X11_XSync(display, False); X11_XGetWindowAttributes(display, data->xwindow, &attrs); X11_XTranslateCoordinates(display, parent, DefaultRootWindow(display), attrs.x, attrs.y, &x, &y, &childReturn); - if ((x != orig_x) || (y != orig_y)) { - window->x = x; - window->y = y; - break; /* window moved, time to go. */ - } else if ((x == window->x) && (y == window->y)) { - break; /* we're at the place we wanted to be anyhow, drop out. */ + if (!caught_x11_error) { + if ((x != orig_x) || (y != orig_y)) { + break; /* window moved, time to go. */ + } else if ((x == window->x) && (y == window->y)) { + break; /* we're at the place we wanted to be anyhow, drop out. */ + } } if (SDL_TICKS_PASSED(SDL_GetTicks(), timeout)) { @@ -845,27 +833,34 @@ X11_SetWindowPosition(_THIS, SDL_Window * window) SDL_Delay(10); } + + if (!caught_x11_error) { + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MOVED, x, y); + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, attrs.width, attrs.height); + } + + X11_XSetErrorHandler(prev_handler); + caught_x11_error = SDL_FALSE; } -void -X11_SetWindowMinimumSize(_THIS, SDL_Window * window) +void X11_SetWindowMinimumSize(_THIS, SDL_Window *window) { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; Display *display = data->videodata->display; if (window->flags & SDL_WINDOW_RESIZABLE) { - XSizeHints *sizehints = X11_XAllocSizeHints(); - long userhints; + XSizeHints *sizehints = X11_XAllocSizeHints(); + long userhints; - X11_XGetWMNormalHints(display, data->xwindow, sizehints, &userhints); + X11_XGetWMNormalHints(display, data->xwindow, sizehints, &userhints); - sizehints->min_width = window->min_w; - sizehints->min_height = window->min_h; - sizehints->flags |= PMinSize; + sizehints->min_width = window->min_w; + sizehints->min_height = window->min_h; + sizehints->flags |= PMinSize; - X11_XSetWMNormalHints(display, data->xwindow, sizehints); + X11_XSetWMNormalHints(display, data->xwindow, sizehints); - X11_XFree(sizehints); + X11_XFree(sizehints); /* See comment in X11_SetWindowSize. */ X11_XResizeWindow(display, data->xwindow, window->w, window->h); @@ -876,25 +871,24 @@ X11_SetWindowMinimumSize(_THIS, SDL_Window * window) X11_XFlush(display); } -void -X11_SetWindowMaximumSize(_THIS, SDL_Window * window) +void X11_SetWindowMaximumSize(_THIS, SDL_Window *window) { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; Display *display = data->videodata->display; if (window->flags & SDL_WINDOW_RESIZABLE) { - XSizeHints *sizehints = X11_XAllocSizeHints(); - long userhints; + XSizeHints *sizehints = X11_XAllocSizeHints(); + long userhints; - X11_XGetWMNormalHints(display, data->xwindow, sizehints, &userhints); + X11_XGetWMNormalHints(display, data->xwindow, sizehints, &userhints); - sizehints->max_width = window->max_w; - sizehints->max_height = window->max_h; - sizehints->flags |= PMaxSize; + sizehints->max_width = window->max_w; + sizehints->max_height = window->max_h; + sizehints->flags |= PMaxSize; - X11_XSetWMNormalHints(display, data->xwindow, sizehints); + X11_XSetWMNormalHints(display, data->xwindow, sizehints); - X11_XFree(sizehints); + X11_XFree(sizehints); /* See comment in X11_SetWindowSize. */ X11_XResizeWindow(display, data->xwindow, window->w, window->h); @@ -905,11 +899,11 @@ X11_SetWindowMaximumSize(_THIS, SDL_Window * window) X11_XFlush(display); } -void -X11_SetWindowSize(_THIS, SDL_Window * window) +void X11_SetWindowSize(_THIS, SDL_Window *window) { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; Display *display = data->videodata->display; + int (*prev_handler)(Display *, XErrorEvent *) = NULL; XWindowAttributes attrs; int orig_w, orig_h; Uint32 timeout; @@ -923,20 +917,20 @@ X11_SetWindowSize(_THIS, SDL_Window * window) X11_ResizeWindowShape(window); } if (!(window->flags & SDL_WINDOW_RESIZABLE)) { - /* Apparently, if the X11 Window is set to a 'non-resizable' window, you cannot resize it using the X11_XResizeWindow, thus - we must set the size hints to adjust the window size. */ - XSizeHints *sizehints = X11_XAllocSizeHints(); - long userhints; + /* Apparently, if the X11 Window is set to a 'non-resizable' window, you cannot resize it using the X11_XResizeWindow, thus + we must set the size hints to adjust the window size. */ + XSizeHints *sizehints = X11_XAllocSizeHints(); + long userhints; - X11_XGetWMNormalHints(display, data->xwindow, sizehints, &userhints); + X11_XGetWMNormalHints(display, data->xwindow, sizehints, &userhints); - sizehints->min_width = sizehints->max_width = window->w; - sizehints->min_height = sizehints->max_height = window->h; - sizehints->flags |= PMinSize | PMaxSize; + sizehints->min_width = sizehints->max_width = window->w; + sizehints->min_height = sizehints->max_height = window->h; + sizehints->flags |= PMinSize | PMaxSize; - X11_XSetWMNormalHints(display, data->xwindow, sizehints); + X11_XSetWMNormalHints(display, data->xwindow, sizehints); - X11_XFree(sizehints); + X11_XFree(sizehints); /* From Pierre-Loup: WMs each have their little quirks with that. When you change the @@ -961,31 +955,50 @@ X11_SetWindowSize(_THIS, SDL_Window * window) X11_XResizeWindow(display, data->xwindow, window->w, window->h); } + X11_XSync(display, False); + prev_handler = X11_XSetErrorHandler(X11_CatchAnyError); + /* Wait a brief time to see if the window manager decided to let this resize happen. If the window changes at all, even to an unexpected value, we break out. */ timeout = SDL_GetTicks() + 100; while (SDL_TRUE) { + caught_x11_error = SDL_FALSE; X11_XSync(display, False); X11_XGetWindowAttributes(display, data->xwindow, &attrs); - if ((attrs.width != orig_w) || (attrs.height != orig_h)) { - window->w = attrs.width; - window->h = attrs.height; - break; /* window changed, time to go. */ - } else if ((attrs.width == window->w) && (attrs.height == window->h)) { - break; /* we're at the place we wanted to be anyhow, drop out. */ + if (!caught_x11_error) { + if ((attrs.width != orig_w) || (attrs.height != orig_h)) { + break; /* window changed, time to go. */ + } else if ((attrs.width == window->w) && (attrs.height == window->h)) { + break; /* we're at the place we wanted to be anyhow, drop out. */ + } } if (SDL_TICKS_PASSED(SDL_GetTicks(), timeout)) { + /* Timeout occurred and window size didn't change + * window manager likely denied the resize, + * or the new size is the same as the existing: + * - current width: is 'full width'. + * - try to set new width at 'full width + 1', which get truncated to 'full width'. + * - new width is/remains 'full width' + * So, even if we break here as a timeout, we can send an event, since the requested size isn't the same + * as the final size. (even if final size is same as original size). + */ break; } SDL_Delay(10); } + + if (!caught_x11_error) { + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, attrs.width, attrs.height); + } + + X11_XSetErrorHandler(prev_handler); + caught_x11_error = SDL_FALSE; } -int -X11_GetWindowBordersSize(_THIS, SDL_Window * window, int *top, int *left, int *bottom, int *right) +int X11_GetWindowBordersSize(_THIS, SDL_Window *window, int *top, int *left, int *bottom, int *right) { SDL_WindowData *data = (SDL_WindowData *)window->driverdata; @@ -997,40 +1010,38 @@ X11_GetWindowBordersSize(_THIS, SDL_Window * window, int *top, int *left, int *b return 0; } -int -X11_SetWindowOpacity(_THIS, SDL_Window * window, float opacity) +int X11_SetWindowOpacity(_THIS, SDL_Window *window, float opacity) { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; Display *display = data->videodata->display; Atom _NET_WM_WINDOW_OPACITY = data->videodata->_NET_WM_WINDOW_OPACITY; if (opacity == 1.0f) { X11_XDeleteProperty(display, data->xwindow, _NET_WM_WINDOW_OPACITY); - } else { + } else { const Uint32 FullyOpaque = 0xFFFFFFFF; - const long alpha = (long) ((double)opacity * (double)FullyOpaque); + const long alpha = (long)((double)opacity * (double)FullyOpaque); X11_XChangeProperty(display, data->xwindow, _NET_WM_WINDOW_OPACITY, XA_CARDINAL, 32, - PropModeReplace, (unsigned char *)&alpha, 1); + PropModeReplace, (unsigned char *)&alpha, 1); } return 0; } -int -X11_SetWindowModalFor(_THIS, SDL_Window * modal_window, SDL_Window * parent_window) { - SDL_WindowData *data = (SDL_WindowData *) modal_window->driverdata; - SDL_WindowData *parent_data = (SDL_WindowData *) parent_window->driverdata; +int X11_SetWindowModalFor(_THIS, SDL_Window *modal_window, SDL_Window *parent_window) +{ + SDL_WindowData *data = (SDL_WindowData *)modal_window->driverdata; + SDL_WindowData *parent_data = (SDL_WindowData *)parent_window->driverdata; Display *display = data->videodata->display; X11_XSetTransientForHint(display, data->xwindow, parent_data->xwindow); return 0; } -int -X11_SetWindowInputFocus(_THIS, SDL_Window * window) +int X11_SetWindowInputFocus(_THIS, SDL_Window *window) { if (X11_IsWindowMapped(_this, window)) { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; Display *display = data->videodata->display; X11_XSetInputFocus(display, data->xwindow, RevertToNone, CurrentTime); X11_XFlush(display); @@ -1039,14 +1050,14 @@ X11_SetWindowInputFocus(_THIS, SDL_Window * window) return -1; } -void -X11_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered) +void X11_SetWindowBordered(_THIS, SDL_Window *window, SDL_bool bordered) { - const SDL_bool focused = ((window->flags & SDL_WINDOW_INPUT_FOCUS) != 0); - const SDL_bool visible = ((window->flags & SDL_WINDOW_HIDDEN) == 0); - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + const SDL_bool focused = (window->flags & SDL_WINDOW_INPUT_FOCUS) ? SDL_TRUE : SDL_FALSE; + const SDL_bool visible = (!(window->flags & SDL_WINDOW_HIDDEN)) ? SDL_TRUE : SDL_FALSE; + + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; SDL_DisplayData *displaydata = - (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; + (SDL_DisplayData *)SDL_GetDisplayForWindow(window)->driverdata; Display *display = data->videodata->display; XEvent event; @@ -1069,12 +1080,15 @@ X11_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered) X11_XSync(display, False); X11_XCheckIfEvent(display, &event, &isUnmapNotify, (XPointer)&data->xwindow); X11_XCheckIfEvent(display, &event, &isMapNotify, (XPointer)&data->xwindow); + + /* Make sure the window manager didn't resize our window for the difference. */ + X11_XResizeWindow(display, data->xwindow, window->w, window->h); + X11_XSync(display, False); } -void -X11_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable) +void X11_SetWindowResizable(_THIS, SDL_Window *window, SDL_bool resizable) { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; Display *display = data->videodata->display; XSizeHints *sizehints = X11_XAllocSizeHints(); @@ -1109,10 +1123,38 @@ X11_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable) X11_XFlush(display); } -void -X11_ShowWindow(_THIS, SDL_Window * window) +void X11_SetWindowAlwaysOnTop(_THIS, SDL_Window *window, SDL_bool on_top) { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + SDL_DisplayData *displaydata = (SDL_DisplayData *)SDL_GetDisplayForWindow(window)->driverdata; + Display *display = data->videodata->display; + Atom _NET_WM_STATE = data->videodata->_NET_WM_STATE; + Atom _NET_WM_STATE_ABOVE = data->videodata->_NET_WM_STATE_ABOVE; + + if (X11_IsWindowMapped(_this, window)) { + XEvent e; + + SDL_zero(e); + e.xany.type = ClientMessage; + e.xclient.message_type = _NET_WM_STATE; + e.xclient.format = 32; + e.xclient.window = data->xwindow; + e.xclient.data.l[0] = + on_top ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE; + e.xclient.data.l[1] = _NET_WM_STATE_ABOVE; + e.xclient.data.l[3] = 0l; + + X11_XSendEvent(display, RootWindow(display, displaydata->screen), 0, + SubstructureNotifyMask | SubstructureRedirectMask, &e); + } else { + X11_SetNetWMState(_this, data->xwindow, window->flags); + } + X11_XFlush(display); +} + +void X11_ShowWindow(_THIS, SDL_Window *window) +{ + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; Display *display = data->videodata->display; XEvent event; @@ -1121,41 +1163,47 @@ X11_ShowWindow(_THIS, SDL_Window * window) /* Blocking wait for "MapNotify" event. * We use X11_XIfEvent because pXWindowEvent takes a mask rather than a type, * and XCheckTypedWindowEvent doesn't block */ - if(!(window->flags & SDL_WINDOW_FOREIGN)) + if (!(window->flags & SDL_WINDOW_FOREIGN)) { X11_XIfEvent(display, &event, &isMapNotify, (XPointer)&data->xwindow); + } X11_XFlush(display); } if (!data->videodata->net_wm) { /* no WM means no FocusIn event, which confuses us. Force it. */ + X11_XSync(display, False); X11_XSetInputFocus(display, data->xwindow, RevertToNone, CurrentTime); X11_XFlush(display); } + + /* Get some valid border values, if we haven't them yet */ + if (data->border_left == 0 && data->border_right == 0 && data->border_top == 0 && data->border_bottom == 0) { + X11_GetBorderValues(data); + } } -void -X11_HideWindow(_THIS, SDL_Window * window) +void X11_HideWindow(_THIS, SDL_Window *window) { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - SDL_DisplayData *displaydata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + SDL_DisplayData *displaydata = (SDL_DisplayData *)SDL_GetDisplayForWindow(window)->driverdata; Display *display = data->videodata->display; XEvent event; if (X11_IsWindowMapped(_this, window)) { X11_XWithdrawWindow(display, data->xwindow, displaydata->screen); /* Blocking wait for "UnmapNotify" event */ - if(!(window->flags & SDL_WINDOW_FOREIGN)) + if (!(window->flags & SDL_WINDOW_FOREIGN)) { X11_XIfEvent(display, &event, &isUnmapNotify, (XPointer)&data->xwindow); + } X11_XFlush(display); } } -static void -SetWindowActive(_THIS, SDL_Window * window) +static void SetWindowActive(_THIS, SDL_Window *window) { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; SDL_DisplayData *displaydata = - (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; + (SDL_DisplayData *)SDL_GetDisplayForWindow(window)->driverdata; Display *display = data->videodata->display; Atom _NET_ACTIVE_WINDOW = data->videodata->_NET_ACTIVE_WINDOW; @@ -1169,21 +1217,20 @@ SetWindowActive(_THIS, SDL_Window * window) e.xclient.message_type = _NET_ACTIVE_WINDOW; e.xclient.format = 32; e.xclient.window = data->xwindow; - e.xclient.data.l[0] = 1; /* source indication. 1 = application */ + e.xclient.data.l[0] = 1; /* source indication. 1 = application */ e.xclient.data.l[1] = data->user_time; e.xclient.data.l[2] = 0; X11_XSendEvent(display, RootWindow(display, displaydata->screen), 0, - SubstructureNotifyMask | SubstructureRedirectMask, &e); + SubstructureNotifyMask | SubstructureRedirectMask, &e); X11_XFlush(display); } } -void -X11_RaiseWindow(_THIS, SDL_Window * window) +void X11_RaiseWindow(_THIS, SDL_Window *window) { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; Display *display = data->videodata->display; X11_XRaiseWindow(display, data->xwindow); @@ -1191,12 +1238,11 @@ X11_RaiseWindow(_THIS, SDL_Window * window) X11_XFlush(display); } -static void -SetWindowMaximized(_THIS, SDL_Window * window, SDL_bool maximized) +static void SetWindowMaximized(_THIS, SDL_Window *window, SDL_bool maximized) { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; SDL_DisplayData *displaydata = - (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; + (SDL_DisplayData *)SDL_GetDisplayForWindow(window)->driverdata; Display *display = data->videodata->display; Atom _NET_WM_STATE = data->videodata->_NET_WM_STATE; Atom _NET_WM_STATE_MAXIMIZED_VERT = data->videodata->_NET_WM_STATE_MAXIMIZED_VERT; @@ -1206,11 +1252,36 @@ SetWindowMaximized(_THIS, SDL_Window * window, SDL_bool maximized) window->flags |= SDL_WINDOW_MAXIMIZED; } else { window->flags &= ~SDL_WINDOW_MAXIMIZED; + + if (window->flags & SDL_WINDOW_FULLSCREEN) { + /* Fullscreen windows are maximized on some window managers, + and this is functional behavior, so don't remove that state + now, we'll take care of it when we leave fullscreen mode. + */ + return; + } } if (X11_IsWindowMapped(_this, window)) { + /* !!! FIXME: most of this waiting code is copy/pasted from elsewhere. */ + int (*prev_handler)(Display *, XErrorEvent *) = NULL; + XWindowAttributes attrs; + Window childReturn, root, parent; + Window *children; + unsigned int childCount; + int orig_w, orig_h, orig_x, orig_y; + int x, y; + Uint64 timeout; XEvent e; + X11_XSync(display, False); + X11_XQueryTree(display, data->xwindow, &root, &parent, &children, &childCount); + X11_XGetWindowAttributes(display, data->xwindow, &attrs); + X11_XTranslateCoordinates(display, parent, DefaultRootWindow(display), + attrs.x, attrs.y, &orig_x, &orig_y, &childReturn); + orig_w = attrs.width; + orig_h = attrs.height; + SDL_zero(e); e.xany.type = ClientMessage; e.xclient.message_type = _NET_WM_STATE; @@ -1223,33 +1294,64 @@ SetWindowMaximized(_THIS, SDL_Window * window, SDL_bool maximized) e.xclient.data.l[3] = 0l; X11_XSendEvent(display, RootWindow(display, displaydata->screen), 0, - SubstructureNotifyMask | SubstructureRedirectMask, &e); + SubstructureNotifyMask | SubstructureRedirectMask, &e); + + /* Wait a brief time to see if the window manager decided to let this happen. + If the window changes at all, even to an unexpected value, we break out. */ + X11_XSync(display, False); + prev_handler = X11_XSetErrorHandler(X11_CatchAnyError); + + timeout = SDL_GetTicks64() + 100; + while (SDL_TRUE) { + caught_x11_error = SDL_FALSE; + X11_XSync(display, False); + X11_XGetWindowAttributes(display, data->xwindow, &attrs); + X11_XTranslateCoordinates(display, parent, DefaultRootWindow(display), + attrs.x, attrs.y, &x, &y, &childReturn); + + if (!caught_x11_error) { + if ((x != orig_x) || (y != orig_y) || (attrs.width != orig_w) || (attrs.height != orig_h)) { + break; /* window changed, time to go. */ + } + } + + if (SDL_GetTicks64() >= timeout) { + break; + } + + SDL_Delay(10); + } + + if (!caught_x11_error) { + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MOVED, x, y); + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, attrs.width, attrs.height); + } + + X11_XSetErrorHandler(prev_handler); + caught_x11_error = SDL_FALSE; } else { X11_SetNetWMState(_this, data->xwindow, window->flags); } X11_XFlush(display); } -void -X11_MaximizeWindow(_THIS, SDL_Window * window) +void X11_MaximizeWindow(_THIS, SDL_Window *window) { SetWindowMaximized(_this, window, SDL_TRUE); } -void -X11_MinimizeWindow(_THIS, SDL_Window * window) +void X11_MinimizeWindow(_THIS, SDL_Window *window) { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; SDL_DisplayData *displaydata = - (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; + (SDL_DisplayData *)SDL_GetDisplayForWindow(window)->driverdata; Display *display = data->videodata->display; X11_XIconifyWindow(display, data->xwindow, displaydata->screen); X11_XFlush(display); } -void -X11_RestoreWindow(_THIS, SDL_Window * window) +void X11_RestoreWindow(_THIS, SDL_Window *window) { SetWindowMaximized(_this, window, SDL_FALSE); X11_ShowWindow(_this, window); @@ -1257,17 +1359,35 @@ X11_RestoreWindow(_THIS, SDL_Window * window) } /* This asks the Window Manager to handle fullscreen for us. This is the modern way. */ -static void -X11_SetWindowFullscreenViaWM(_THIS, SDL_Window * window, SDL_VideoDisplay * _display, SDL_bool fullscreen) +static void X11_SetWindowFullscreenViaWM(_THIS, SDL_Window *window, SDL_VideoDisplay *_display, SDL_bool fullscreen) { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - SDL_DisplayData *displaydata = (SDL_DisplayData *) _display->driverdata; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + SDL_DisplayData *displaydata = (SDL_DisplayData *)_display->driverdata; Display *display = data->videodata->display; Atom _NET_WM_STATE = data->videodata->_NET_WM_STATE; Atom _NET_WM_STATE_FULLSCREEN = data->videodata->_NET_WM_STATE_FULLSCREEN; + SDL_bool window_size_changed = SDL_FALSE; + int window_position_changed = 0; if (X11_IsWindowMapped(_this, window)) { XEvent e; + /* !!! FIXME: most of this waiting code is copy/pasted from elsewhere. */ + int (*prev_handler)(Display *, XErrorEvent *) = NULL; + unsigned int childCount; + Window childReturn, root, parent; + Window *children; + XWindowAttributes attrs; + int x, y; + int orig_w, orig_h, orig_x, orig_y; + Uint64 timeout; + + X11_XSync(display, False); + X11_XQueryTree(display, data->xwindow, &root, &parent, &children, &childCount); + X11_XGetWindowAttributes(display, data->xwindow, &attrs); + X11_XTranslateCoordinates(display, parent, DefaultRootWindow(display), + attrs.x, attrs.y, &orig_x, &orig_y, &childReturn); + orig_w = attrs.width; + orig_h = attrs.height; if (!(window->flags & SDL_WINDOW_RESIZABLE)) { /* Compiz refuses fullscreen toggle if we're not resizable, so update the hints so we @@ -1300,23 +1420,85 @@ X11_SetWindowFullscreenViaWM(_THIS, SDL_Window * window, SDL_VideoDisplay * _dis e.xclient.data.l[3] = 0l; X11_XSendEvent(display, RootWindow(display, displaydata->screen), 0, - SubstructureNotifyMask | SubstructureRedirectMask, &e); + SubstructureNotifyMask | SubstructureRedirectMask, &e); /* Fullscreen windows sometimes end up being marked maximized by window managers. Force it back to how we expect it to be. */ - if (!fullscreen && ((window->flags & SDL_WINDOW_MAXIMIZED) == 0)) { + if (!fullscreen) { SDL_zero(e); e.xany.type = ClientMessage; e.xclient.message_type = _NET_WM_STATE; e.xclient.format = 32; e.xclient.window = data->xwindow; - e.xclient.data.l[0] = _NET_WM_STATE_REMOVE; + if (window->flags & SDL_WINDOW_MAXIMIZED) { + e.xclient.data.l[0] = _NET_WM_STATE_ADD; + } else { + e.xclient.data.l[0] = _NET_WM_STATE_REMOVE; + } e.xclient.data.l[1] = data->videodata->_NET_WM_STATE_MAXIMIZED_VERT; e.xclient.data.l[2] = data->videodata->_NET_WM_STATE_MAXIMIZED_HORZ; e.xclient.data.l[3] = 0l; X11_XSendEvent(display, RootWindow(display, displaydata->screen), 0, - SubstructureNotifyMask | SubstructureRedirectMask, &e); + SubstructureNotifyMask | SubstructureRedirectMask, &e); } + + if (!fullscreen) { + int dest_x = 0, dest_y = 0; + dest_x = window->windowed.x - data->border_left; + dest_y = window->windowed.y - data->border_top; + + /* Attempt to move the window */ + X11_XMoveWindow(display, data->xwindow, dest_x, dest_y); + } + + + /* Wait a brief time to see if the window manager decided to let this happen. + If the window changes at all, even to an unexpected value, we break out. */ + X11_XSync(display, False); + prev_handler = X11_XSetErrorHandler(X11_CatchAnyError); + + timeout = SDL_GetTicks64() + 100; + while (SDL_TRUE) { + + caught_x11_error = SDL_FALSE; + X11_XSync(display, False); + X11_XGetWindowAttributes(display, data->xwindow, &attrs); + X11_XTranslateCoordinates(display, parent, DefaultRootWindow(display), + attrs.x, attrs.y, &x, &y, &childReturn); + + if (!caught_x11_error) { + if ((x != orig_x) || (y != orig_y)) { + orig_x = x; + orig_y = y; + window_position_changed += 1; + } + + if ((attrs.width != orig_w) || (attrs.height != orig_h)) { + orig_w = attrs.width; + orig_h = attrs.height; + window_size_changed = SDL_TRUE; + } + + /* Wait for at least 2 moves + 1 size changed to have valid values */ + if (window_position_changed >= 2 && window_size_changed) { + break; /* window changed, time to go. */ + } + } + + if (SDL_GetTicks64() >= timeout) { + break; + } + + SDL_Delay(10); + } + + if (!caught_x11_error) { + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MOVED, x, y); + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, attrs.width, attrs.height); + } + + X11_XSetErrorHandler(prev_handler); + caught_x11_error = SDL_FALSE; } else { Uint32 flags; @@ -1330,7 +1512,7 @@ X11_SetWindowFullscreenViaWM(_THIS, SDL_Window * window, SDL_VideoDisplay * _dis } if (data->visual->class == DirectColor) { - if ( fullscreen ) { + if (fullscreen) { X11_XInstallColormap(display, data->colormap); } else { X11_XUninstallColormap(display, data->colormap); @@ -1340,163 +1522,12 @@ X11_SetWindowFullscreenViaWM(_THIS, SDL_Window * window, SDL_VideoDisplay * _dis X11_XFlush(display); } -/* This handles fullscreen itself, outside the Window Manager. */ -static void -X11_BeginWindowFullscreenLegacy(_THIS, SDL_Window * window, SDL_VideoDisplay * _display) +void X11_SetWindowFullscreen(_THIS, SDL_Window *window, SDL_VideoDisplay *_display, SDL_bool fullscreen) { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - SDL_DisplayData *displaydata = (SDL_DisplayData *) _display->driverdata; - Visual *visual = data->visual; - Display *display = data->videodata->display; - const int screen = displaydata->screen; - Window root = RootWindow(display, screen); - const int def_vis = (visual == DefaultVisual(display, screen)); - unsigned long xattrmask = 0; - XSetWindowAttributes xattr; - XEvent ev; - SDL_Rect rect; - - if ( data->fswindow ) { - return; /* already fullscreen, I hope. */ - } - - X11_GetDisplayBounds(_this, _display, &rect); - - SDL_zero(xattr); - xattr.override_redirect = True; - xattrmask |= CWOverrideRedirect; - xattr.background_pixel = def_vis ? BlackPixel(display, screen) : 0; - xattrmask |= CWBackPixel; - xattr.border_pixel = 0; - xattrmask |= CWBorderPixel; - xattr.colormap = data->colormap; - xattrmask |= CWColormap; - - data->fswindow = X11_XCreateWindow(display, root, - rect.x, rect.y, rect.w, rect.h, 0, - displaydata->depth, InputOutput, - visual, xattrmask, &xattr); - - X11_XSelectInput(display, data->fswindow, StructureNotifyMask); - X11_XSetWindowBackground(display, data->fswindow, 0); - X11_XInstallColormap(display, data->colormap); - X11_XClearWindow(display, data->fswindow); - X11_XMapRaised(display, data->fswindow); - - /* Make sure the fswindow is in view by warping mouse to the corner */ - X11_XUngrabPointer(display, CurrentTime); - X11_XWarpPointer(display, None, root, 0, 0, 0, 0, rect.x, rect.y); - - /* Wait to be mapped, filter Unmap event out if it arrives. */ - X11_XIfEvent(display, &ev, &isMapNotify, (XPointer)&data->fswindow); - X11_XCheckIfEvent(display, &ev, &isUnmapNotify, (XPointer)&data->fswindow); - -#if SDL_VIDEO_DRIVER_X11_XVIDMODE - if ( displaydata->use_vidmode ) { - X11_XF86VidModeLockModeSwitch(display, screen, True); - } -#endif - - SetWindowBordered(display, displaydata->screen, data->xwindow, SDL_FALSE); - - /* Center actual window within our cover-the-screen window. */ - X11_XReparentWindow(display, data->xwindow, data->fswindow, - (rect.w - window->w) / 2, (rect.h - window->h) / 2); - - /* Move the mouse to the upper left to make sure it's on-screen */ - X11_XWarpPointer(display, None, root, 0, 0, 0, 0, rect.x, rect.y); - - /* Center mouse in the fullscreen window. */ - rect.x += (rect.w / 2); - rect.y += (rect.h / 2); - X11_XWarpPointer(display, None, root, 0, 0, 0, 0, rect.x, rect.y); - - /* Wait to be mapped, filter Unmap event out if it arrives. */ - X11_XIfEvent(display, &ev, &isMapNotify, (XPointer)&data->xwindow); - X11_XCheckIfEvent(display, &ev, &isUnmapNotify, (XPointer)&data->xwindow); - - SDL_UpdateWindowGrab(window); + X11_SetWindowFullscreenViaWM(_this, window, _display, fullscreen); } -static void -X11_EndWindowFullscreenLegacy(_THIS, SDL_Window * window, SDL_VideoDisplay * _display) -{ - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - SDL_DisplayData *displaydata = (SDL_DisplayData *) _display->driverdata; - Display *display = data->videodata->display; - const int screen = displaydata->screen; - Window root = RootWindow(display, screen); - Window fswindow = data->fswindow; - XEvent ev; - - if (!data->fswindow) { - return; /* already not fullscreen, I hope. */ - } - - data->fswindow = None; - -#if SDL_VIDEO_DRIVER_X11_VIDMODE - if ( displaydata->use_vidmode ) { - X11_XF86VidModeLockModeSwitch(display, screen, False); - } -#endif - - SDL_UpdateWindowGrab(window); - - X11_XReparentWindow(display, data->xwindow, root, window->x, window->y); - - /* flush these events so they don't confuse normal event handling */ - X11_XSync(display, False); - X11_XCheckIfEvent(display, &ev, &isMapNotify, (XPointer)&data->xwindow); - X11_XCheckIfEvent(display, &ev, &isUnmapNotify, (XPointer)&data->xwindow); - - SetWindowBordered(display, screen, data->xwindow, - (window->flags & SDL_WINDOW_BORDERLESS) == 0); - - X11_XWithdrawWindow(display, fswindow, screen); - - /* Wait to be unmapped. */ - X11_XIfEvent(display, &ev, &isUnmapNotify, (XPointer)&fswindow); - X11_XDestroyWindow(display, fswindow); -} - - -void -X11_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * _display, SDL_bool fullscreen) -{ - /* !!! FIXME: SDL_Hint? */ - SDL_bool legacy = SDL_FALSE; - const char *env = SDL_getenv("SDL_VIDEO_X11_LEGACY_FULLSCREEN"); - if (env) { - legacy = SDL_atoi(env); - } else { - SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; - SDL_DisplayData *displaydata = (SDL_DisplayData *) _display->driverdata; - if ( displaydata->use_vidmode ) { - legacy = SDL_TRUE; /* the new stuff only works with XRandR. */ - } else if ( !videodata->net_wm ) { - legacy = SDL_TRUE; /* The window manager doesn't support it */ - } else { - /* !!! FIXME: look at the window manager name, and blacklist certain ones? */ - /* http://stackoverflow.com/questions/758648/find-the-name-of-the-x-window-manager */ - legacy = SDL_FALSE; /* try the new way. */ - } - } - - if (legacy) { - if (fullscreen) { - X11_BeginWindowFullscreenLegacy(_this, window, _display); - } else { - X11_EndWindowFullscreenLegacy(_this, window, _display); - } - } else { - X11_SetWindowFullscreenViaWM(_this, window, _display, fullscreen); - } -} - - -int -X11_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp) +int X11_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp) { SDL_WindowData *data = (SDL_WindowData *) window->driverdata; Display *display = data->videodata->display; @@ -1562,32 +1593,119 @@ X11_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp) return 0; } -void -X11_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed) +typedef struct { + unsigned char *data; + int format, count; + Atom type; +} SDL_x11Prop; + +/* Reads property + Must call X11_XFree on results + */ +static void X11_ReadProperty(SDL_x11Prop *p, Display *disp, Window w, Atom prop) { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + unsigned char *ret = NULL; + Atom type; + int fmt; + unsigned long count; + unsigned long bytes_left; + int bytes_fetch = 0; + + do { + if (ret) { + X11_XFree(ret); + } + X11_XGetWindowProperty(disp, w, prop, 0, bytes_fetch, False, AnyPropertyType, &type, &fmt, &count, &bytes_left, &ret); + bytes_fetch += bytes_left; + } while (bytes_left != 0); + + p->data = ret; + p->format = fmt; + p->count = count; + p->type = type; +} + +void *X11_GetWindowICCProfile(_THIS, SDL_Window *window, size_t *size) +{ + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; Display *display = data->videodata->display; - SDL_bool oldstyle_fullscreen; - SDL_bool grab_keyboard; + XWindowAttributes attributes; + Atom icc_profile_atom; + char icc_atom_string[sizeof("_ICC_PROFILE_") + 12]; + void *ret_icc_profile_data = NULL; + CARD8 *icc_profile_data; + int real_format; + unsigned long real_nitems; + SDL_x11Prop atomProp; - /* ICCCM2.0-compliant window managers can handle fullscreen windows - If we're using XVidMode to change resolution we need to confine - the cursor so we don't pan around the virtual desktop. - */ - oldstyle_fullscreen = X11_IsWindowLegacyFullscreen(_this, window); + X11_XGetWindowAttributes(display, data->xwindow, &attributes); + if (X11_XScreenNumberOfScreen(attributes.screen) > 0) { + (void)SDL_snprintf(icc_atom_string, sizeof("_ICC_PROFILE_") + 12, "%s%d", "_ICC_PROFILE_", X11_XScreenNumberOfScreen(attributes.screen)); + } else { + SDL_strlcpy(icc_atom_string, "_ICC_PROFILE", sizeof("_ICC_PROFILE")); + } + X11_XGetWindowAttributes(display, RootWindowOfScreen(attributes.screen), &attributes); + + icc_profile_atom = X11_XInternAtom(display, icc_atom_string, True); + if (icc_profile_atom == None) { + SDL_SetError("Screen is not calibrated.\n"); + return NULL; + } + + X11_ReadProperty(&atomProp, display, RootWindowOfScreen(attributes.screen), icc_profile_atom); + real_format = atomProp.format; + real_nitems = atomProp.count; + icc_profile_data = atomProp.data; + if (real_format == None) { + SDL_SetError("Screen is not calibrated.\n"); + return NULL; + } + + ret_icc_profile_data = SDL_malloc(real_nitems); + if (!ret_icc_profile_data) { + SDL_OutOfMemory(); + return NULL; + } + + SDL_memcpy(ret_icc_profile_data, icc_profile_data, real_nitems); + *size = real_nitems; + X11_XFree(icc_profile_data); + + return ret_icc_profile_data; +} + +void X11_SetWindowMouseGrab(_THIS, SDL_Window *window, SDL_bool grabbed) +{ + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + Display *display; + + if (!data) { + return; + } + data->mouse_grabbed = SDL_FALSE; + + display = data->videodata->display; + + if (grabbed) { + /* If the window is unmapped, XGrab calls return GrabNotViewable, + so when we get a MapNotify later, we'll try to update the grab as + appropriate. */ + if (window->flags & SDL_WINDOW_HIDDEN) { + return; + } - if (oldstyle_fullscreen || grabbed) { /* Try to grab the mouse */ if (!data->videodata->broken_pointer_grab) { const unsigned int mask = ButtonPressMask | ButtonReleaseMask | PointerMotionMask | FocusChangeMask; int attempts; - int result; + int result = 0; /* Try for up to 5000ms (5s) to grab. If it still fails, stop trying. */ for (attempts = 0; attempts < 100; attempts++) { - result = X11_XGrabPointer(display, data->xwindow, True, mask, GrabModeAsync, - GrabModeAsync, data->xwindow, None, CurrentTime); + result = X11_XGrabPointer(display, data->xwindow, False, mask, GrabModeAsync, + GrabModeAsync, data->xwindow, None, CurrentTime); if (result == GrabSuccess) { + data->mouse_grabbed = SDL_TRUE; break; } SDL_Delay(50); @@ -1595,40 +1713,65 @@ X11_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed) if (result != GrabSuccess) { SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "The X server refused to let us grab the mouse. You might experience input bugs."); - data->videodata->broken_pointer_grab = SDL_TRUE; /* don't try again. */ + data->videodata->broken_pointer_grab = SDL_TRUE; /* don't try again. */ } } + X11_Xinput2GrabTouch(_this, window); + /* Raise the window if we grab the mouse */ X11_XRaiseWindow(display, data->xwindow); - - /* Now grab the keyboard */ - if (SDL_GetHintBoolean(SDL_HINT_GRAB_KEYBOARD, SDL_FALSE)) { - grab_keyboard = SDL_TRUE; - } else { - /* We need to do this with the old style override_redirect - fullscreen window otherwise we won't get keyboard focus. - */ - grab_keyboard = oldstyle_fullscreen; - } - if (grab_keyboard) { - X11_XGrabKeyboard(display, data->xwindow, True, GrabModeAsync, - GrabModeAsync, CurrentTime); - } } else { X11_XUngrabPointer(display, CurrentTime); + + X11_Xinput2UngrabTouch(_this, window); + } + X11_XSync(display, False); +} + +void X11_SetWindowKeyboardGrab(_THIS, SDL_Window *window, SDL_bool grabbed) +{ + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + Display *display; + + if (!data) { + return; + } + + display = data->videodata->display; + + if (grabbed) { + /* If the window is unmapped, XGrab calls return GrabNotViewable, + so when we get a MapNotify later, we'll try to update the grab as + appropriate. */ + if (window->flags & SDL_WINDOW_HIDDEN) { + return; + } + + X11_XGrabKeyboard(display, data->xwindow, True, GrabModeAsync, + GrabModeAsync, CurrentTime); + } else { X11_XUngrabKeyboard(display, CurrentTime); } X11_XSync(display, False); } -void -X11_DestroyWindow(_THIS, SDL_Window * window) +void X11_DestroyWindow(_THIS, SDL_Window *window) { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + + if (window->shaper) { + SDL_ShapeData *shapedata = (SDL_ShapeData *)window->shaper->driverdata; + if (shapedata) { + SDL_free(shapedata->bitmap); + SDL_free(shapedata); + } + SDL_free(window->shaper); + window->shaper = NULL; + } if (data) { - SDL_VideoData *videodata = (SDL_VideoData *) data->videodata; + SDL_VideoData *videodata = (SDL_VideoData *)data->videodata; Display *display = videodata->display; int numwindows = videodata->numwindows; SDL_WindowData **windowlist = videodata->windowlist; @@ -1654,51 +1797,143 @@ X11_DestroyWindow(_THIS, SDL_Window * window) X11_XFlush(display); } SDL_free(data); + +#ifdef SDL_VIDEO_DRIVER_X11_XFIXES + /* If the pointer barriers are active for this, deactivate it.*/ + if (videodata->active_cursor_confined_window == window) { + X11_DestroyPointerBarrier(_this, window); + } +#endif /* SDL_VIDEO_DRIVER_X11_XFIXES */ } window->driverdata = NULL; } -SDL_bool -X11_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info) +SDL_bool X11_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info) { SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - Display *display = data->videodata->display; + Display *display; - if (info->version.major == SDL_MAJOR_VERSION && - info->version.minor == SDL_MINOR_VERSION) { + if (!data) { + /* This sometimes happens in SDL_IBus_UpdateTextRect() while creating the window */ + SDL_SetError("Window not initialized"); + return SDL_FALSE; + } + + display = data->videodata->display; + + if (info->version.major == SDL_MAJOR_VERSION) { info->subsystem = SDL_SYSWM_X11; info->info.x11.display = display; info->info.x11.window = data->xwindow; return SDL_TRUE; } else { - SDL_SetError("Application not compiled with SDL %d.%d", - SDL_MAJOR_VERSION, SDL_MINOR_VERSION); + SDL_SetError("Application not compiled with SDL %d", + SDL_MAJOR_VERSION); return SDL_FALSE; } } -int -X11_SetWindowHitTest(SDL_Window *window, SDL_bool enabled) +int X11_SetWindowHitTest(SDL_Window *window, SDL_bool enabled) { - return 0; /* just succeed, the real work is done elsewhere. */ + return 0; /* just succeed, the real work is done elsewhere. */ } -void -X11_AcceptDragAndDrop(SDL_Window * window, SDL_bool accept) +void X11_AcceptDragAndDrop(SDL_Window *window, SDL_bool accept) { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; Display *display = data->videodata->display; Atom XdndAware = X11_XInternAtom(display, "XdndAware", False); if (accept) { Atom xdnd_version = 5; X11_XChangeProperty(display, data->xwindow, XdndAware, XA_ATOM, 32, - PropModeReplace, (unsigned char*)&xdnd_version, 1); + PropModeReplace, (unsigned char *)&xdnd_version, 1); } else { X11_XDeleteProperty(display, data->xwindow, XdndAware); } } +int X11_FlashWindow(_THIS, SDL_Window *window, SDL_FlashOperation operation) +{ + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + Display *display = data->videodata->display; + XWMHints *wmhints; + + wmhints = X11_XGetWMHints(display, data->xwindow); + if (!wmhints) { + return SDL_SetError("Couldn't get WM hints"); + } + + wmhints->flags &= ~XUrgencyHint; + data->flashing_window = SDL_FALSE; + data->flash_cancel_time = 0; + + switch (operation) { + case SDL_FLASH_CANCEL: + /* Taken care of above */ + break; + case SDL_FLASH_BRIEFLY: + if (!(window->flags & SDL_WINDOW_INPUT_FOCUS)) { + wmhints->flags |= XUrgencyHint; + data->flashing_window = SDL_TRUE; + /* On Ubuntu 21.04 this causes a dialog to pop up, so leave it up for a full second so users can see it */ + data->flash_cancel_time = SDL_GetTicks() + 1000; + if (!data->flash_cancel_time) { + data->flash_cancel_time = 1; + } + } + break; + case SDL_FLASH_UNTIL_FOCUSED: + if (!(window->flags & SDL_WINDOW_INPUT_FOCUS)) { + wmhints->flags |= XUrgencyHint; + data->flashing_window = SDL_TRUE; + } + break; + default: + break; + } + + X11_XSetWMHints(display, data->xwindow, wmhints); + X11_XFree(wmhints); + return 0; +} + +int SDL_X11_SetWindowTitle(Display *display, Window xwindow, char *title) +{ + Atom _NET_WM_NAME = X11_XInternAtom(display, "_NET_WM_NAME", False); + XTextProperty titleprop; + int conv = X11_XmbTextListToTextProperty(display, &title, 1, XTextStyle, &titleprop); + Status status; + + if (X11_XSupportsLocale() != True) { + return SDL_SetError("Current locale not supported by X server, cannot continue."); + } + + if (conv == 0) { + X11_XSetTextProperty(display, xwindow, &titleprop, XA_WM_NAME); + X11_XFree(titleprop.value); + /* we know this can't be a locale error as we checked X locale validity */ + } else if (conv < 0) { + return SDL_OutOfMemory(); + } else { /* conv > 0 */ + SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "%d characters were not convertible to the current locale!", conv); + return 0; + } + +#ifdef X_HAVE_UTF8_STRING + status = X11_Xutf8TextListToTextProperty(display, &title, 1, XUTF8StringStyle, &titleprop); + if (status == Success) { + X11_XSetTextProperty(display, xwindow, &titleprop, _NET_WM_NAME); + X11_XFree(titleprop.value); + } else { + return SDL_SetError("Failed to convert title to UTF8! Bad encoding, or bad Xorg encoding? Window title: «%s»", title); + } +#endif + + X11_XFlush(display); + return 0; +} + #endif /* SDL_VIDEO_DRIVER_X11 */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/x11/SDL_x11window.h b/SDL2-2.30.5/src/video/x11/SDL_x11window.h similarity index 76% rename from SDL2-2.0.12/src/video/x11/SDL_x11window.h rename to SDL2-2.30.5/src/video/x11/SDL_x11window.h index 8178ffc..12a89b0 100644 --- a/SDL2-2.0.12/src/video/x11/SDL_x11window.h +++ b/SDL2-2.30.5/src/video/x11/SDL_x11window.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -27,9 +27,9 @@ video mode changes and we can respond to them by triggering more mode changes. */ -#define PENDING_FOCUS_TIME 200 +#define PENDING_FOCUS_TIME 200 -#if SDL_VIDEO_OPENGL_EGL +#ifdef SDL_VIDEO_OPENGL_EGL #include #endif @@ -44,7 +44,6 @@ typedef struct { SDL_Window *window; Window xwindow; - Window fswindow; /* used if we can't have the WM handle fullscreen. */ Visual *visual; Colormap colormap; #ifndef NO_SHARED_MEMORY @@ -60,6 +59,7 @@ typedef struct int border_right; int border_top; int border_bottom; + SDL_bool mouse_grabbed; Uint32 last_focus_event_time; PendingFocusEnum pending_focus; Uint32 pending_focus_time; @@ -68,16 +68,23 @@ typedef struct unsigned long user_time; Atom xdnd_req; Window xdnd_source; -#if SDL_VIDEO_OPENGL_EGL + SDL_bool flashing_window; + Uint32 flash_cancel_time; +#ifdef SDL_VIDEO_OPENGL_EGL EGLSurface egl_surface; #endif +#ifdef SDL_VIDEO_DRIVER_X11_XFIXES + SDL_bool pointer_barrier_active; + PointerBarrier barrier[4]; + SDL_Rect barrier_rect; +#endif /* SDL_VIDEO_DRIVER_X11_XFIXES */ } SDL_WindowData; extern void X11_SetNetWMState(_THIS, Window xwindow, Uint32 flags); -extern Uint32 X11_GetNetWMState(_THIS, Window xwindow); +extern Uint32 X11_GetNetWMState(_THIS, SDL_Window *window, Window xwindow); -extern int X11_CreateWindow(_THIS, SDL_Window * window); -extern int X11_CreateWindowFrom(_THIS, SDL_Window * window, const void *data); +extern int X11_CreateWindow(_THIS, SDL_Window *window); +extern int X11_CreateWindowFrom(_THIS, SDL_Window *window, const void *data); extern char *X11_GetWindowTitle(_THIS, Window xwindow); extern void X11_SetWindowTitle(_THIS, SDL_Window * window); extern void X11_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon); @@ -97,14 +104,20 @@ extern void X11_MinimizeWindow(_THIS, SDL_Window * window); extern void X11_RestoreWindow(_THIS, SDL_Window * window); extern void X11_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered); extern void X11_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable); +extern void X11_SetWindowAlwaysOnTop(_THIS, SDL_Window * window, SDL_bool on_top); extern void X11_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen); extern int X11_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp); -extern void X11_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed); +extern void* X11_GetWindowICCProfile(_THIS, SDL_Window * window, size_t * size); +extern void X11_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed); +extern void X11_SetWindowKeyboardGrab(_THIS, SDL_Window * window, SDL_bool grabbed); extern void X11_DestroyWindow(_THIS, SDL_Window * window); extern SDL_bool X11_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info); extern int X11_SetWindowHitTest(SDL_Window *window, SDL_bool enabled); -extern void X11_AcceptDragAndDrop(SDL_Window * window, SDL_bool accept); +extern void X11_AcceptDragAndDrop(SDL_Window *window, SDL_bool accept); +extern int X11_FlashWindow(_THIS, SDL_Window *window, SDL_FlashOperation operation); + +int SDL_X11_SetWindowTitle(Display *display, Window xwindow, char *title); #endif /* SDL_x11window_h_ */ diff --git a/SDL2-2.30.5/src/video/x11/SDL_x11xfixes.c b/SDL2-2.30.5/src/video/x11/SDL_x11xfixes.c new file mode 100644 index 0000000..6ae7e05 --- /dev/null +++ b/SDL2-2.30.5/src/video/x11/SDL_x11xfixes.c @@ -0,0 +1,214 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#if defined(SDL_VIDEO_DRIVER_X11) && defined(SDL_VIDEO_DRIVER_X11_XFIXES) + +#include "SDL_x11video.h" +#include "SDL_x11xfixes.h" +#include "../../events/SDL_mouse_c.h" +#include "../../events/SDL_touch_c.h" + +static int xfixes_initialized = 0; +static int xfixes_selection_notify_event = 0; + +static int query_xfixes_version(Display *display, int major, int minor) +{ + /* We don't care if this fails, so long as it sets major/minor on it's way out the door. */ + X11_XFixesQueryVersion(display, &major, &minor); + return (major * 1000) + minor; +} + +static SDL_bool xfixes_version_atleast(const int version, const int wantmajor, const int wantminor) +{ + return version >= ((wantmajor * 1000) + wantminor); +} + +void X11_InitXfixes(_THIS) +{ + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; + + int version = 0; + int event, error; + int fixes_opcode; + + Atom XA_CLIPBOARD = X11_XInternAtom(data->display, "CLIPBOARD", 0); + + if (!SDL_X11_HAVE_XFIXES || + !X11_XQueryExtension(data->display, "XFIXES", &fixes_opcode, &event, &error)) { + return; + } + + /* Selection tracking is available in all versions of XFixes */ + xfixes_selection_notify_event = event + XFixesSelectionNotify; + X11_XFixesSelectSelectionInput(data->display, DefaultRootWindow(data->display), + XA_CLIPBOARD, XFixesSetSelectionOwnerNotifyMask); + X11_XFixesSelectSelectionInput(data->display, DefaultRootWindow(data->display), + XA_PRIMARY, XFixesSetSelectionOwnerNotifyMask); + + /* We need at least 5.0 for barriers. */ + version = query_xfixes_version(data->display, 5, 0); + if (!xfixes_version_atleast(version, 5, 0)) { + return; /* X server does not support the version we want at all. */ + } + + xfixes_initialized = 1; +} + +int X11_XfixesIsInitialized() +{ + return xfixes_initialized; +} + +int X11_GetXFixesSelectionNotifyEvent() +{ + return xfixes_selection_notify_event; +} + +void X11_SetWindowMouseRect(_THIS, SDL_Window *window) +{ + if (SDL_RectEmpty(&window->mouse_rect)) { + X11_ConfineCursorWithFlags(_this, window, NULL, 0); + } else { + if (window->flags & SDL_WINDOW_INPUT_FOCUS) { + X11_ConfineCursorWithFlags(_this, window, &window->mouse_rect, 0); + } else { + /* Save the state for when we get focus again */ + SDL_WindowData *wdata = (SDL_WindowData *)window->driverdata; + + SDL_memcpy(&wdata->barrier_rect, &window->mouse_rect, sizeof(wdata->barrier_rect)); + + wdata->pointer_barrier_active = SDL_TRUE; + } + } +} + +int X11_ConfineCursorWithFlags(_THIS, SDL_Window *window, const SDL_Rect *rect, int flags) +{ + /* Yaakuro: For some reason Xfixes when confining inside a rect where the + * edges exactly match, a rectangle the cursor 'slips' out of the barrier. + * To prevent that the lines for the barriers will span the whole screen. + */ + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; + SDL_WindowData *wdata; + + if (!X11_XfixesIsInitialized()) { + return SDL_Unsupported(); + } + + /* If there is already a set of barriers active, disable them. */ + if (data->active_cursor_confined_window) { + X11_DestroyPointerBarrier(_this, data->active_cursor_confined_window); + } + + SDL_assert(window != NULL); + wdata = (SDL_WindowData *)window->driverdata; + + /* If user did not specify an area to confine, destroy the barrier that was/is assigned to + * this window it was assigned */ + if (rect) { + int x1, y1, x2, y2; + SDL_Rect bounds; + SDL_GetWindowPosition(window, &bounds.x, &bounds.y); + SDL_GetWindowSize(window, &bounds.w, &bounds.h); + + /** Negative values are not allowed. Clip values relative to the specified window. */ + x1 = bounds.x + SDL_max(rect->x, 0); + y1 = bounds.y + SDL_max(rect->y, 0); + x2 = SDL_min(bounds.x + rect->x + rect->w, bounds.x + bounds.w); + y2 = SDL_min(bounds.y + rect->y + rect->h, bounds.y + bounds.h); + + if ((wdata->barrier_rect.x != rect->x) || + (wdata->barrier_rect.y != rect->y) || + (wdata->barrier_rect.w != rect->w) || + (wdata->barrier_rect.h != rect->h)) { + wdata->barrier_rect = *rect; + } + + /* Use the display bounds to ensure the barriers don't have corner gaps */ + SDL_GetDisplayBounds(SDL_GetWindowDisplayIndex(window), &bounds); + + /** Create the left barrier */ + wdata->barrier[0] = X11_XFixesCreatePointerBarrier(data->display, wdata->xwindow, + x1, bounds.y, + x1, bounds.y + bounds.h, + BarrierPositiveX, + 0, NULL); + /** Create the right barrier */ + wdata->barrier[1] = X11_XFixesCreatePointerBarrier(data->display, wdata->xwindow, + x2, bounds.y, + x2, bounds.y + bounds.h, + BarrierNegativeX, + 0, NULL); + /** Create the top barrier */ + wdata->barrier[2] = X11_XFixesCreatePointerBarrier(data->display, wdata->xwindow, + bounds.x, y1, + bounds.x + bounds.w, y1, + BarrierPositiveY, + 0, NULL); + /** Create the bottom barrier */ + wdata->barrier[3] = X11_XFixesCreatePointerBarrier(data->display, wdata->xwindow, + bounds.x, y2, + bounds.x + bounds.w, y2, + BarrierNegativeY, + 0, NULL); + + X11_XFlush(data->display); + + /* Lets remember current active confined window. */ + data->active_cursor_confined_window = window; + + /* User activated the confinement for this window. We use this later to reactivate + * the confinement if it got deactivated by FocusOut or UnmapNotify */ + wdata->pointer_barrier_active = SDL_TRUE; + } else { + X11_DestroyPointerBarrier(_this, window); + + /* Only set barrier inactive when user specified NULL and not handled by focus out. */ + if (flags != X11_BARRIER_HANDLED_BY_EVENT) { + wdata->pointer_barrier_active = SDL_FALSE; + } + } + return 0; +} + +void X11_DestroyPointerBarrier(_THIS, SDL_Window *window) +{ + int i; + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; + if (window) { + SDL_WindowData *wdata = (SDL_WindowData *)window->driverdata; + + for (i = 0; i < 4; i++) { + if (wdata->barrier[i] > 0) { + X11_XFixesDestroyPointerBarrier(data->display, wdata->barrier[i]); + wdata->barrier[i] = 0; + } + } + X11_XFlush(data->display); + } + data->active_cursor_confined_window = NULL; +} + +#endif /* SDL_VIDEO_DRIVER_X11 && SDL_VIDEO_DRIVER_X11_XFIXES */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/x11/SDL_x11xfixes.h b/SDL2-2.30.5/src/video/x11/SDL_x11xfixes.h new file mode 100644 index 0000000..3464867 --- /dev/null +++ b/SDL2-2.30.5/src/video/x11/SDL_x11xfixes.h @@ -0,0 +1,41 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifndef SDL_x11xfixes_h_ +#define SDL_x11xfixes_h_ + +#ifdef SDL_VIDEO_DRIVER_X11_XFIXES + +#define X11_BARRIER_HANDLED_BY_EVENT 1 + +extern void X11_InitXfixes(_THIS); +extern int X11_XfixesIsInitialized(void); +extern void X11_SetWindowMouseRect(_THIS, SDL_Window *window); +extern int X11_ConfineCursorWithFlags(_THIS, SDL_Window *window, const SDL_Rect *rect, int flags); +extern void X11_DestroyPointerBarrier(_THIS, SDL_Window *window); +extern int X11_GetXFixesSelectionNotifyEvent(void); +#endif /* SDL_VIDEO_DRIVER_X11_XFIXES */ + +#endif /* SDL_x11xfixes_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.30.5/src/video/x11/SDL_x11xinput2.c b/SDL2-2.30.5/src/video/x11/SDL_x11xinput2.c new file mode 100644 index 0000000..afed858 --- /dev/null +++ b/SDL2-2.30.5/src/video/x11/SDL_x11xinput2.c @@ -0,0 +1,525 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2024 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + 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" + +#ifdef SDL_VIDEO_DRIVER_X11 + +#include "SDL_x11video.h" +#include "SDL_x11xinput2.h" +#include "../../events/SDL_mouse_c.h" +#include "../../events/SDL_touch_c.h" + +#define MAX_AXIS 16 + +#ifdef SDL_VIDEO_DRIVER_X11_XINPUT2 +static int xinput2_initialized = 0; + +#ifdef SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH +static int xinput2_multitouch_supported = 0; +#endif + +/* Opcode returned X11_XQueryExtension + * It will be used in event processing + * to know that the event came from + * this extension */ +static int xinput2_opcode; + +static void parse_valuators(const double *input_values, const unsigned char *mask, int mask_len, + double *output_values, int output_values_len) +{ + int i = 0, z = 0; + int top = mask_len * 8; + if (top > MAX_AXIS) { + top = MAX_AXIS; + } + + SDL_memset(output_values, 0, output_values_len * sizeof(double)); + for (; i < top && z < output_values_len; i++) { + if (XIMaskIsSet(mask, i)) { + const int value = (int)*input_values; + output_values[z] = value; + input_values++; + } + z++; + } +} + +static int query_xinput2_version(Display *display, int major, int minor) +{ + /* We don't care if this fails, so long as it sets major/minor on it's way out the door. */ + X11_XIQueryVersion(display, &major, &minor); + return (major * 1000) + minor; +} + +static SDL_bool xinput2_version_atleast(const int version, const int wantmajor, const int wantminor) +{ + return version >= ((wantmajor * 1000) + wantminor); +} + +#ifdef SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH +static SDL_Window *xinput2_get_sdlwindow(SDL_VideoData *videodata, Window window) +{ + int i; + for (i = 0; i < videodata->numwindows; i++) { + SDL_WindowData *d = videodata->windowlist[i]; + if (d->xwindow == window) { + return d->window; + } + } + return NULL; +} + +static void xinput2_normalize_touch_coordinates(SDL_Window *window, double in_x, double in_y, float *out_x, float *out_y) +{ + if (window) { + if (window->w == 1) { + *out_x = 0.5f; + } else { + *out_x = in_x / (window->w - 1); + } + if (window->h == 1) { + *out_y = 0.5f; + } else { + *out_y = in_y / (window->h - 1); + } + } else { + // 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 X11_InitXinput2(_THIS) +{ +#ifdef SDL_VIDEO_DRIVER_X11_XINPUT2 + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; + + int version = 0; + XIEventMask eventmask; + unsigned char mask[4] = { 0, 0, 0, 0 }; + int event, err; + + /* + * Initialize XInput 2 + * According to http://who-t.blogspot.com/2009/05/xi2-recipes-part-1.html its better + * to inform Xserver what version of Xinput we support.The server will store the version we support. + * "As XI2 progresses it becomes important that you use this call as the server may treat the client + * differently depending on the supported version". + * + * FIXME:event and err are not needed but if not passed X11_XQueryExtension returns SegmentationFault + */ + if (!SDL_X11_HAVE_XINPUT2 || + !X11_XQueryExtension(data->display, "XInputExtension", &xinput2_opcode, &event, &err)) { + return; /* X server does not have XInput at all */ + } + + /* We need at least 2.2 for Multitouch, 2.0 otherwise. */ + version = query_xinput2_version(data->display, 2, 2); + if (!xinput2_version_atleast(version, 2, 0)) { + return; /* X server does not support the version we want at all. */ + } + + xinput2_initialized = 1; + +#ifdef SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH /* Multitouch needs XInput 2.2 */ + xinput2_multitouch_supported = xinput2_version_atleast(version, 2, 2); +#endif + + /* Enable raw motion events for this display */ + eventmask.deviceid = XIAllMasterDevices; + eventmask.mask_len = sizeof(mask); + eventmask.mask = mask; + + XISetMask(mask, XI_RawMotion); + XISetMask(mask, XI_RawButtonPress); + XISetMask(mask, XI_RawButtonRelease); + +#ifdef SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH + /* Enable raw touch events if supported */ + if (X11_Xinput2IsMultitouchSupported()) { + XISetMask(mask, XI_RawTouchBegin); + XISetMask(mask, XI_RawTouchUpdate); + XISetMask(mask, XI_RawTouchEnd); + } +#endif + + if (X11_XISelectEvents(data->display, DefaultRootWindow(data->display), &eventmask, 1) != Success) { + return; + } + + SDL_zero(eventmask); + SDL_zeroa(mask); + eventmask.deviceid = XIAllDevices; + eventmask.mask_len = sizeof(mask); + eventmask.mask = mask; + + XISetMask(mask, XI_HierarchyChanged); + if (X11_XISelectEvents(data->display, DefaultRootWindow(data->display), &eventmask, 1) != Success) { + return; + } +#endif +} + +#ifdef SDL_VIDEO_DRIVER_X11_XINPUT2 +/* xi2 device went away? take it out of the list. */ +static void xinput2_remove_device_info(SDL_VideoData *videodata, const int device_id) +{ + SDL_XInput2DeviceInfo *prev = NULL; + SDL_XInput2DeviceInfo *devinfo; + + for (devinfo = videodata->mouse_device_info; devinfo; devinfo = devinfo->next) { + if (devinfo->device_id == device_id) { + SDL_assert((devinfo == videodata->mouse_device_info) == (prev == NULL)); + if (!prev) { + videodata->mouse_device_info = devinfo->next; + } else { + prev->next = devinfo->next; + } + SDL_free(devinfo); + return; + } + prev = devinfo; + } +} + +static SDL_XInput2DeviceInfo *xinput2_get_device_info(SDL_VideoData *videodata, const int device_id) +{ + /* cache device info as we see new devices. */ + SDL_XInput2DeviceInfo *prev = NULL; + SDL_XInput2DeviceInfo *devinfo; + XIDeviceInfo *xidevinfo; + int axis = 0; + int i; + + for (devinfo = videodata->mouse_device_info; devinfo; devinfo = devinfo->next) { + if (devinfo->device_id == device_id) { + SDL_assert((devinfo == videodata->mouse_device_info) == (prev == NULL)); + if (prev) { /* move this to the front of the list, assuming we'll get more from this one. */ + prev->next = devinfo->next; + devinfo->next = videodata->mouse_device_info; + videodata->mouse_device_info = devinfo; + } + return devinfo; + } + prev = devinfo; + } + + /* don't know about this device yet, query and cache it. */ + devinfo = (SDL_XInput2DeviceInfo *)SDL_calloc(1, sizeof(SDL_XInput2DeviceInfo)); + if (!devinfo) { + SDL_OutOfMemory(); + return NULL; + } + + xidevinfo = X11_XIQueryDevice(videodata->display, device_id, &i); + if (!xidevinfo) { + SDL_free(devinfo); + return NULL; + } + + devinfo->device_id = device_id; + + /* !!! FIXME: this is sort of hacky because we only care about the first two axes we see, but any given + !!! FIXME: axis could be relative or absolute, and they might not even be the X and Y axes! + !!! FIXME: But we go on, for now. Maybe we need a more robust mouse API in SDL3... */ + for (i = 0; i < xidevinfo->num_classes; i++) { + const XIValuatorClassInfo *v = (const XIValuatorClassInfo *)xidevinfo->classes[i]; + if (v->type == XIValuatorClass) { + devinfo->relative[axis] = (v->mode == XIModeRelative) ? SDL_TRUE : SDL_FALSE; + devinfo->minval[axis] = v->min; + devinfo->maxval[axis] = v->max; + if (++axis >= 2) { + break; + } + } + } + + X11_XIFreeDeviceInfo(xidevinfo); + + devinfo->next = videodata->mouse_device_info; + videodata->mouse_device_info = devinfo; + + return devinfo; +} +#endif + +int X11_HandleXinput2Event(SDL_VideoData *videodata, XGenericEventCookie *cookie) +{ +#ifdef SDL_VIDEO_DRIVER_X11_XINPUT2 + if (cookie->extension != xinput2_opcode) { + return 0; + } + switch (cookie->evtype) { + case XI_RawMotion: + { + const XIRawEvent *rawev = (const XIRawEvent *)cookie->data; + SDL_Mouse *mouse = SDL_GetMouse(); + SDL_XInput2DeviceInfo *devinfo; + double coords[2]; + double processed_coords[2]; + int i; + + videodata->global_mouse_changed = SDL_TRUE; + + if (!mouse->relative_mode || mouse->relative_mode_warp) { + return 0; + } + + devinfo = xinput2_get_device_info(videodata, rawev->deviceid); + if (!devinfo) { + return 0; /* oh well. */ + } + + parse_valuators(rawev->raw_values, rawev->valuators.mask, + rawev->valuators.mask_len, coords, 2); + + for (i = 0; i < 2; i++) { + if (devinfo->relative[i]) { + processed_coords[i] = coords[i]; + } else { + processed_coords[i] = devinfo->prev_coords[i] - coords[i]; /* convert absolute to relative */ + } + } + + SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 1, (int)processed_coords[0], (int)processed_coords[1]); + devinfo->prev_coords[0] = coords[0]; + devinfo->prev_coords[1] = coords[1]; + return 1; + } break; + + case XI_HierarchyChanged: + { + const XIHierarchyEvent *hierev = (const XIHierarchyEvent *)cookie->data; + int i; + for (i = 0; i < hierev->num_info; i++) { + if (hierev->info[i].flags & XISlaveRemoved) { + xinput2_remove_device_info(videodata, hierev->info[i].deviceid); + } + } + } break; + + case XI_RawButtonPress: + case XI_RawButtonRelease: +#ifdef SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH + case XI_RawTouchBegin: + case XI_RawTouchUpdate: + case XI_RawTouchEnd: +#endif + videodata->global_mouse_changed = SDL_TRUE; + break; + +#ifdef SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH + /* With multitouch, register to receive XI_Motion (which desctivates MotionNotify), + * so that we can distinguish real mouse motions from synthetic one. */ + case XI_Motion: + { + const XIDeviceEvent *xev = (const XIDeviceEvent *)cookie->data; + int pointer_emulated = (xev->flags & XIPointerEmulated); + + videodata->global_mouse_changed = SDL_TRUE; + + if (!pointer_emulated) { + SDL_Mouse *mouse = SDL_GetMouse(); + if (!mouse->relative_mode || mouse->relative_mode_warp) { + SDL_Window *window = xinput2_get_sdlwindow(videodata, xev->event); + if (window) { + SDL_SendMouseMotion(window, 0, 0, xev->event_x, xev->event_y); + } + } + } + return 1; + } break; + + case XI_TouchBegin: + { + const XIDeviceEvent *xev = (const XIDeviceEvent *)cookie->data; + float x, y; + SDL_Window *window = xinput2_get_sdlwindow(videodata, xev->event); + xinput2_normalize_touch_coordinates(window, xev->event_x, xev->event_y, &x, &y); + SDL_SendTouch(xev->sourceid, xev->detail, window, SDL_TRUE, x, y, 1.0); + return 1; + } break; + case XI_TouchEnd: + { + const XIDeviceEvent *xev = (const XIDeviceEvent *)cookie->data; + float x, y; + SDL_Window *window = xinput2_get_sdlwindow(videodata, xev->event); + xinput2_normalize_touch_coordinates(window, xev->event_x, xev->event_y, &x, &y); + SDL_SendTouch(xev->sourceid, xev->detail, window, SDL_FALSE, x, y, 1.0); + return 1; + } break; + case XI_TouchUpdate: + { + const XIDeviceEvent *xev = (const XIDeviceEvent *)cookie->data; + float x, y; + SDL_Window *window = xinput2_get_sdlwindow(videodata, xev->event); + xinput2_normalize_touch_coordinates(window, xev->event_x, xev->event_y, &x, &y); + SDL_SendTouchMotion(xev->sourceid, xev->detail, window, x, y, 1.0); + return 1; + } break; + +#endif + } +#endif + return 0; +} + +void X11_InitXinput2Multitouch(_THIS) +{ +#ifdef SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata; + XIDeviceInfo *info; + int ndevices, i, j; + + if (!X11_Xinput2IsMultitouchSupported()) { + return; + } + + info = X11_XIQueryDevice(data->display, XIAllDevices, &ndevices); + + for (i = 0; i < ndevices; i++) { + XIDeviceInfo *dev = &info[i]; + for (j = 0; j < dev->num_classes; j++) { + SDL_TouchID touchId; + SDL_TouchDeviceType touchType; + XIAnyClassInfo *class = dev->classes[j]; + XITouchClassInfo *t = (XITouchClassInfo *)class; + + /* Only touch devices */ + if (class->type != XITouchClass) { + continue; + } + + if (t->mode == XIDependentTouch) { + touchType = SDL_TOUCH_DEVICE_INDIRECT_RELATIVE; + } else { /* XIDirectTouch */ + touchType = SDL_TOUCH_DEVICE_DIRECT; + } + + touchId = t->sourceid; + SDL_AddTouch(touchId, touchType, dev->name); + } + } + X11_XIFreeDeviceInfo(info); +#endif +} + +void X11_Xinput2SelectTouch(_THIS, SDL_Window *window) +{ +#ifdef SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH + SDL_VideoData *data = NULL; + XIEventMask eventmask; + unsigned char mask[4] = { 0, 0, 0, 0 }; + SDL_WindowData *window_data = NULL; + + if (!X11_Xinput2IsMultitouchSupported()) { + return; + } + + data = (SDL_VideoData *)_this->driverdata; + window_data = (SDL_WindowData *)window->driverdata; + + eventmask.deviceid = XIAllMasterDevices; + eventmask.mask_len = sizeof(mask); + eventmask.mask = mask; + + XISetMask(mask, XI_TouchBegin); + XISetMask(mask, XI_TouchUpdate); + XISetMask(mask, XI_TouchEnd); + XISetMask(mask, XI_Motion); + + X11_XISelectEvents(data->display, window_data->xwindow, &eventmask, 1); +#endif +} + +int X11_Xinput2IsInitialized() +{ +#ifdef SDL_VIDEO_DRIVER_X11_XINPUT2 + return xinput2_initialized; +#else + return 0; +#endif +} + +int X11_Xinput2IsMultitouchSupported() +{ +#ifdef SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH + return xinput2_initialized && xinput2_multitouch_supported; +#else + return 0; +#endif +} + +void X11_Xinput2GrabTouch(_THIS, SDL_Window *window) +{ +#ifdef SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + Display *display = data->videodata->display; + + unsigned char mask[4] = { 0, 0, 0, 0 }; + XIGrabModifiers mods; + XIEventMask eventmask; + + if (!X11_Xinput2IsMultitouchSupported()) { + return; + } + + mods.modifiers = XIAnyModifier; + mods.status = 0; + + eventmask.deviceid = XIAllDevices; + eventmask.mask_len = sizeof(mask); + eventmask.mask = mask; + + XISetMask(eventmask.mask, XI_TouchBegin); + XISetMask(eventmask.mask, XI_TouchUpdate); + XISetMask(eventmask.mask, XI_TouchEnd); + XISetMask(eventmask.mask, XI_Motion); + + X11_XIGrabTouchBegin(display, XIAllDevices, data->xwindow, True, &eventmask, 1, &mods); +#endif +} + +void X11_Xinput2UngrabTouch(_THIS, SDL_Window *window) +{ +#ifdef SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH + SDL_WindowData *data = (SDL_WindowData *)window->driverdata; + Display *display = data->videodata->display; + + XIGrabModifiers mods; + + if (!X11_Xinput2IsMultitouchSupported()) { + return; + } + + mods.modifiers = XIAnyModifier; + mods.status = 0; + + X11_XIUngrabTouchBegin(display, XIAllDevices, data->xwindow, 1, &mods); +#endif +} + +#endif /* SDL_VIDEO_DRIVER_X11 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/SDL2-2.0.12/src/video/x11/SDL_x11xinput2.h b/SDL2-2.30.5/src/video/x11/SDL_x11xinput2.h similarity index 84% rename from SDL2-2.0.12/src/video/x11/SDL_x11xinput2.h rename to SDL2-2.30.5/src/video/x11/SDL_x11xinput2.h index 022d81f..3a8e3c0 100644 --- a/SDL2-2.0.12/src/video/x11/SDL_x11xinput2.h +++ b/SDL2-2.30.5/src/video/x11/SDL_x11xinput2.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2020 Sam Lantinga + Copyright (C) 1997-2024 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -32,10 +32,12 @@ typedef struct XGenericEventCookie XGenericEventCookie; extern void X11_InitXinput2(_THIS); extern void X11_InitXinput2Multitouch(_THIS); -extern int X11_HandleXinput2Event(SDL_VideoData *videodata,XGenericEventCookie *cookie); +extern int X11_HandleXinput2Event(SDL_VideoData *videodata, XGenericEventCookie *cookie); extern int X11_Xinput2IsInitialized(void); extern int X11_Xinput2IsMultitouchSupported(void); extern void X11_Xinput2SelectTouch(_THIS, SDL_Window *window); +extern void X11_Xinput2GrabTouch(_THIS, SDL_Window *window); +extern void X11_Xinput2UngrabTouch(_THIS, SDL_Window *window); #endif /* SDL_x11xinput2_h_ */ diff --git a/SDL2-2.0.12/src/video/x11/edid-parse.c b/SDL2-2.30.5/src/video/x11/edid-parse.c similarity index 98% rename from SDL2-2.0.12/src/video/x11/edid-parse.c rename to SDL2-2.30.5/src/video/x11/edid-parse.c index e22324f..52c5d5f 100644 --- a/SDL2-2.0.12/src/video/x11/edid-parse.c +++ b/SDL2-2.30.5/src/video/x11/edid-parse.c @@ -50,7 +50,7 @@ get_bits (int in, int begin, int end) static int decode_header (const uchar *edid) { - if (memcmp (edid, "\x00\xff\xff\xff\xff\xff\xff\x00", 8) == 0) + if (SDL_memcmp (edid, "\x00\xff\xff\xff\xff\xff\xff\x00", 8) == 0) return TRUE; return FALSE; } @@ -76,7 +76,7 @@ decode_vendor_and_product_identification (const uchar *edid, MonitorInfo *info) /* Serial Number */ info->serial_number = - edid[0x0c] | edid[0x0d] << 8 | edid[0x0e] << 16 | edid[0x0f] << 24; + edid[0x0c] | edid[0x0d] << 8 | edid[0x0e] << 16 | (Uint32)edid[0x0f] << 24; /* Week and Year */ is_model_year = FALSE; @@ -522,7 +522,7 @@ decode_check_sum (const uchar *edid, MonitorInfo * decode_edid (const uchar *edid) { - MonitorInfo *info = calloc (1, sizeof (MonitorInfo)); + MonitorInfo *info = SDL_calloc (1, sizeof (MonitorInfo)); decode_check_sum (edid, info); @@ -534,8 +534,8 @@ decode_edid (const uchar *edid) !decode_established_timings (edid, info) || !decode_standard_timings (edid, info) || !decode_descriptors (edid, info)) { - free(info); - return NULL; + SDL_free(info); + return NULL; } return info; @@ -623,7 +623,7 @@ dump_monitor_info (MonitorInfo *info) case RGB: s = "rgb"; break; case OTHER_COLOR: s = "other color"; break; default: s = "unknown"; break; - }; + } printf ("Color: %s\n", s); } diff --git a/SDL2-2.30.5/src/video/x11/edid.h b/SDL2-2.30.5/src/video/x11/edid.h new file mode 100644 index 0000000..37abbec --- /dev/null +++ b/SDL2-2.30.5/src/video/x11/edid.h @@ -0,0 +1,167 @@ +typedef unsigned char uchar; +typedef struct MonitorInfo MonitorInfo; +typedef struct Timing Timing; +typedef struct DetailedTiming DetailedTiming; + +typedef enum +{ + UNDEFINED, + DVI, + HDMI_A, + HDMI_B, + MDDI, + DISPLAY_PORT +} Interface; + +typedef enum +{ + UNDEFINED_COLOR, + MONOCHROME, + RGB, + OTHER_COLOR +} ColorType; + +typedef enum +{ + NO_STEREO, + FIELD_RIGHT, + FIELD_LEFT, + TWO_WAY_RIGHT_ON_EVEN, + TWO_WAY_LEFT_ON_EVEN, + FOUR_WAY_INTERLEAVED, + SIDE_BY_SIDE +} StereoType; + +struct Timing +{ + int width; + int height; + int frequency; +}; + +struct DetailedTiming +{ + int pixel_clock; + int h_addr; + int h_blank; + int h_sync; + int h_front_porch; + int v_addr; + int v_blank; + int v_sync; + int v_front_porch; + int width_mm; + int height_mm; + int right_border; + int top_border; + int interlaced; + StereoType stereo; + + int digital_sync; + union + { + struct + { + int bipolar; + int serrations; + int sync_on_green; + } analog; + + struct + { + int composite; + int serrations; + int negative_vsync; + int negative_hsync; + } digital; + } ad; +}; + +struct MonitorInfo +{ + int checksum; + char manufacturer_code[4]; + int product_code; + unsigned int serial_number; + + int production_week; /* -1 if not specified */ + int production_year; /* -1 if not specified */ + int model_year; /* -1 if not specified */ + + int major_version; + int minor_version; + + int is_digital; + + union + { + struct + { + int bits_per_primary; + Interface interface; + int rgb444; + int ycrcb444; + int ycrcb422; + } digital; + + struct + { + double video_signal_level; + double sync_signal_level; + double total_signal_level; + + int blank_to_black; + + int separate_hv_sync; + int composite_sync_on_h; + int composite_sync_on_green; + int serration_on_vsync; + ColorType color_type; + } analog; + } ad; + + int width_mm; /* -1 if not specified */ + int height_mm; /* -1 if not specified */ + double aspect_ratio; /* -1.0 if not specififed */ + + double gamma; /* -1.0 if not specified */ + + int standby; + int suspend; + int active_off; + + int srgb_is_standard; + int preferred_timing_includes_native; + int continuous_frequency; + + double red_x; + double red_y; + double green_x; + double green_y; + double blue_x; + double blue_y; + double white_x; + double white_y; + + Timing established[24]; /* Terminated by 0x0x0 */ + Timing standard[8]; + + int n_detailed_timings; + DetailedTiming detailed_timings[4]; /* If monitor has a preferred + * mode, it is the first one + * (whether it has, is + * determined by the + * preferred_timing_includes + * bit. + */ + + /* Optional product description */ + char dsc_serial_number[14]; + char dsc_product_name[14]; + char dsc_string[14]; /* Unspecified ASCII data */ +}; + +MonitorInfo *decode_edid(const uchar *data); +void dump_monitor_info(MonitorInfo *info); +char *make_display_name(const char *output_name, + const MonitorInfo *info); diff --git a/SDL2-2.0.12/src/video/yuv2rgb/LICENSE b/SDL2-2.30.5/src/video/yuv2rgb/LICENSE similarity index 100% rename from SDL2-2.0.12/src/video/yuv2rgb/LICENSE rename to SDL2-2.30.5/src/video/yuv2rgb/LICENSE diff --git a/SDL2-2.0.12/src/video/yuv2rgb/README.md b/SDL2-2.30.5/src/video/yuv2rgb/README.md similarity index 100% rename from SDL2-2.0.12/src/video/yuv2rgb/README.md rename to SDL2-2.30.5/src/video/yuv2rgb/README.md diff --git a/SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb.h b/SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb.h new file mode 100644 index 0000000..c359316 --- /dev/null +++ b/SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb.h @@ -0,0 +1,33 @@ +#ifndef YUV_RGB_H_ +#define YUV_RGB_H_ + +// Copyright 2016 Adrien Descamps +// Distributed under BSD 3-Clause License + +// Provide optimized functions to convert images from 8bits yuv420 to rgb24 format + +// There are a few slightly different variations of the YCbCr color space with different parameters that +// change the conversion matrix. +// The three most common YCbCr color space, defined by BT.601, BT.709 and JPEG standard are implemented here. +// See the respective standards for details +// The matrix values used are derived from http://www.equasys.de/colorconversion.html + +// YUV420 is stored as three separate channels, with U and V (Cb and Cr) subsampled by a 2 factor +// For conversion from yuv to rgb, no interpolation is done, and the same UV value are used for 4 rgb pixels. This +// is suboptimal for image quality, but by far the fastest method. + +// For all methods, width and height should be even, if not, the last row/column of the result image won't be affected. +// For sse methods, if the width if not divisable by 32, the last (width%32) pixels of each line won't be affected. + +/*#include */ + +// yuv to rgb, standard c implementation +#include "yuv_rgb_std.h" + +// yuv to rgb, sse2 implementation +#include "yuv_rgb_sse.h" + +// yuv to rgb, lsx implementation +#include "yuv_rgb_lsx.h" + +#endif /* YUV_RGB_H_ */ diff --git a/SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb_common.h b/SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb_common.h new file mode 100644 index 0000000..ae787ed --- /dev/null +++ b/SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb_common.h @@ -0,0 +1,13 @@ +#ifndef YUV_RGB_COMMON_H_ +#define YUV_RGB_COMMON_H_ +// Copyright 2016 Adrien Descamps +// Distributed under BSD 3-Clause License + +typedef enum +{ + YCBCR_JPEG, + YCBCR_601, + YCBCR_709 +} YCbCrType; + +#endif /* YUV_RGB_COMMON_H_ */ diff --git a/SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb_internal.h b/SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb_internal.h new file mode 100644 index 0000000..cad978b --- /dev/null +++ b/SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb_internal.h @@ -0,0 +1,74 @@ +// Copyright 2016 Adrien Descamps +// Distributed under BSD 3-Clause License + +#define PRECISION 6 +#define PRECISION_FACTOR (1<[0-255]) +// for ITU-R BT.709-6 values are derived from equations in sections 3.2-3.4, assuming RGB is encoded using full range ([0-1]<->[0-255]) +// all values are rounded to the fourth decimal + +static const YUV2RGBParam YUV2RGB[3] = { + // ITU-T T.871 (JPEG) + {/*.y_shift=*/ 0, /*.y_factor=*/ V(1.0), /*.v_r_factor=*/ V(1.402), /*.u_g_factor=*/ -V(0.3441), /*.v_g_factor=*/ -V(0.7141), /*.u_b_factor=*/ V(1.772)}, + // ITU-R BT.601-7 + {/*.y_shift=*/ 16, /*.y_factor=*/ V(1.1644), /*.v_r_factor=*/ V(1.596), /*.u_g_factor=*/ -V(0.3918), /*.v_g_factor=*/ -V(0.813), /*.u_b_factor=*/ V(2.0172)}, + // ITU-R BT.709-6 + {/*.y_shift=*/ 16, /*.y_factor=*/ V(1.1644), /*.v_r_factor=*/ V(1.7927), /*.u_g_factor=*/ -V(0.2132), /*.v_g_factor=*/ -V(0.5329), /*.u_b_factor=*/ V(2.1124)} +}; + +static const RGB2YUVParam RGB2YUV[3] = { + // ITU-T T.871 (JPEG) + {/*.y_shift=*/ 0, /*.matrix=*/ {{V(0.299), V(0.587), V(0.114)}, {-V(0.1687), -V(0.3313), V(0.5)}, {V(0.5), -V(0.4187), -V(0.0813)}}}, + // ITU-R BT.601-7 + {/*.y_shift=*/ 16, /*.matrix=*/ {{V(0.2568), V(0.5041), V(0.0979)}, {-V(0.1482), -V(0.291), V(0.4392)}, {V(0.4392), -V(0.3678), -V(0.0714)}}}, + // ITU-R BT.709-6 + {/*.y_shift=*/ 16, /*.matrix=*/ {{V(0.1826), V(0.6142), V(0.062)}, {-V(0.1006), -V(0.3386), V(0.4392)}, {V(0.4392), -V(0.3989), -V(0.0403)}}} +}; + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +/* The various layouts of YUV data we support */ +#define YUV_FORMAT_420 1 +#define YUV_FORMAT_422 2 +#define YUV_FORMAT_NV12 3 + +/* The various formats of RGB pixel that we support */ +#define RGB_FORMAT_RGB565 1 +#define RGB_FORMAT_RGB24 2 +#define RGB_FORMAT_RGBA 3 +#define RGB_FORMAT_BGRA 4 +#define RGB_FORMAT_ARGB 5 +#define RGB_FORMAT_ABGR 6 diff --git a/SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb_lsx.c b/SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb_lsx.c new file mode 100644 index 0000000..f24a052 --- /dev/null +++ b/SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb_lsx.c @@ -0,0 +1,44 @@ +// Copyright 2016 Adrien Descamps +// Distributed under BSD 3-Clause License +#include "../../SDL_internal.h" + +#if SDL_HAVE_YUV +#include "yuv_rgb.h" +#include "yuv_rgb_internal.h" +#include "SDL_cpuinfo.h" + +#ifdef __loongarch_sx + +#define LSX_FUNCTION_NAME yuv420_rgb24_lsx +#define STD_FUNCTION_NAME yuv420_rgb24_std +#define YUV_FORMAT YUV_FORMAT_420 +#define RGB_FORMAT RGB_FORMAT_RGB24 +#include "yuv_rgb_lsx_func.h" + +#define LSX_FUNCTION_NAME yuv420_rgba_lsx +#define STD_FUNCTION_NAME yuv420_rgba_std +#define YUV_FORMAT YUV_FORMAT_420 +#define RGB_FORMAT RGB_FORMAT_RGBA +#include "yuv_rgb_lsx_func.h" + +#define LSX_FUNCTION_NAME yuv420_bgra_lsx +#define STD_FUNCTION_NAME yuv420_bgra_std +#define YUV_FORMAT YUV_FORMAT_420 +#define RGB_FORMAT RGB_FORMAT_BGRA +#include "yuv_rgb_lsx_func.h" + +#define LSX_FUNCTION_NAME yuv420_argb_lsx +#define STD_FUNCTION_NAME yuv420_argb_std +#define YUV_FORMAT YUV_FORMAT_420 +#define RGB_FORMAT RGB_FORMAT_ARGB +#include "yuv_rgb_lsx_func.h" + +#define LSX_FUNCTION_NAME yuv420_abgr_lsx +#define STD_FUNCTION_NAME yuv420_abgr_std +#define YUV_FORMAT YUV_FORMAT_420 +#define RGB_FORMAT RGB_FORMAT_ABGR +#include "yuv_rgb_lsx_func.h" + +#endif //__loongarch_sx + +#endif /* SDL_HAVE_YUV */ diff --git a/SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb_lsx.h b/SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb_lsx.h new file mode 100644 index 0000000..bcffd95 --- /dev/null +++ b/SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb_lsx.h @@ -0,0 +1,407 @@ +// Copyright 2016 Adrien Descamps +// Distributed under BSD 3-Clause License + +// Provide optimized functions to convert images from 8bits yuv420 to rgb24 format + +// There are a few slightly different variations of the YCbCr color space with different parameters that +// change the conversion matrix. +// The three most common YCbCr color space, defined by BT.601, BT.709 and JPEG standard are implemented here. +// See the respective standards for details +// The matrix values used are derived from http://www.equasys.de/colorconversion.html + +// YUV420 is stored as three separate channels, with U and V (Cb and Cr) subsampled by a 2 factor +// For conversion from yuv to rgb, no interpolation is done, and the same UV value are used for 4 rgb pixels. This +// is suboptimal for image quality, but by far the fastest method. + +// For all methods, width and height should be even, if not, the last row/column of the result image won't be affected. +// For sse methods, if the width if not divisable by 32, the last (width%32) pixels of each line won't be affected. + +/*#include */ +#include "yuv_rgb_common.h" + +#include "SDL_stdinc.h" + +// yuv to rgb, standard c implementation +void yuv420_rgb565_std( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv420_rgb24_std( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv420_rgba_std( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv420_bgra_std( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv420_argb_std( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv420_abgr_std( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv422_rgb565_std( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv422_rgb24_std( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv422_rgba_std( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv422_bgra_std( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv422_argb_std( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv422_abgr_std( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuvnv12_rgb565_std( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuvnv12_rgb24_std( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuvnv12_rgba_std( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuvnv12_bgra_std( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuvnv12_argb_std( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuvnv12_abgr_std( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +// yuv to rgb, sse implementation +// pointers must be 16 byte aligned, and strides must be divisable by 16 +void yuv420_rgb565_sse( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv420_rgb24_sse( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv420_rgba_sse( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv420_bgra_sse( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv420_argb_sse( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv420_abgr_sse( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv422_rgb565_sse( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv422_rgb24_sse( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv422_rgba_sse( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv422_bgra_sse( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv422_argb_sse( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv422_abgr_sse( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuvnv12_rgb565_sse( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuvnv12_rgb24_sse( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuvnv12_rgba_sse( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuvnv12_bgra_sse( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuvnv12_argb_sse( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuvnv12_abgr_sse( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +// yuv to rgb, sse implementation +// pointers do not need to be 16 byte aligned +void yuv420_rgb565_sseu( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv420_rgb24_sseu( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv420_rgba_sseu( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv420_bgra_sseu( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv420_argb_sseu( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv420_abgr_sseu( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv422_rgb565_sseu( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv422_rgb24_sseu( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv422_rgba_sseu( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv422_bgra_sseu( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv422_argb_sseu( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv422_abgr_sseu( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuvnv12_rgb565_sseu( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuvnv12_rgb24_sseu( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuvnv12_rgba_sseu( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuvnv12_bgra_sseu( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuvnv12_argb_sseu( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuvnv12_abgr_sseu( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + + +// rgb to yuv, standard c implementation +void rgb24_yuv420_std( + uint32_t width, uint32_t height, + const uint8_t *rgb, uint32_t rgb_stride, + uint8_t *y, uint8_t *u, uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + YCbCrType yuv_type); + +// rgb to yuv, sse implementation +// pointers must be 16 byte aligned, and strides must be divisible by 16 +void rgb24_yuv420_sse( + uint32_t width, uint32_t height, + const uint8_t *rgb, uint32_t rgb_stride, + uint8_t *y, uint8_t *u, uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + YCbCrType yuv_type); + +// rgb to yuv, sse implementation +// pointers do not need to be 16 byte aligned +void rgb24_yuv420_sseu( + uint32_t width, uint32_t height, + const uint8_t *rgb, uint32_t rgb_stride, + uint8_t *y, uint8_t *u, uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + YCbCrType yuv_type); + + +//yuv420 to bgra, lsx implementation +void yuv420_rgb24_lsx( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv420_rgba_lsx( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *v, const uint8_t *u, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv420_bgra_lsx( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *v, const uint8_t *u, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv420_argb_lsx( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *v, const uint8_t *u, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv420_abgr_lsx( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *v, const uint8_t *u, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); diff --git a/SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb_lsx_func.h b/SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb_lsx_func.h new file mode 100644 index 0000000..89d582a --- /dev/null +++ b/SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb_lsx_func.h @@ -0,0 +1,372 @@ +// Copyright 2016 Adrien Descamps +// // Distributed under BSD 3-Clause License + +#include + +#if YUV_FORMAT == YUV_FORMAT_420 + +#define READ_Y(y_ptr) \ + y = __lsx_vld(y_ptr, 0); \ + +#define READ_UV \ + u_temp = __lsx_vld(u_ptr, 0); \ + v_temp = __lsx_vld(v_ptr, 0); \ + +#else +#error READ_UV unimplemented +#endif + +#define PACK_RGBA_32(R1, R2, G1, G2, B1, B2, A1, A2, RGB1, RGB2, \ + RGB3, RGB4, RGB5, RGB6, RGB7, RGB8) \ +{ \ + __m128i ab_l, ab_h, gr_l, gr_h; \ + ab_l = __lsx_vilvl_b(B1, A1); \ + ab_h = __lsx_vilvh_b(B1, A1); \ + gr_l = __lsx_vilvl_b(R1, G1); \ + gr_h = __lsx_vilvh_b(R1, G1); \ + RGB1 = __lsx_vilvl_h(gr_l, ab_l); \ + RGB2 = __lsx_vilvh_h(gr_l, ab_l); \ + RGB3 = __lsx_vilvl_h(gr_h, ab_h); \ + RGB4 = __lsx_vilvh_h(gr_h, ab_h); \ + ab_l = __lsx_vilvl_b(B2, A2); \ + ab_h = __lsx_vilvh_b(B2, A2); \ + gr_l = __lsx_vilvl_b(R2, G2); \ + gr_h = __lsx_vilvh_b(R2, G2); \ + RGB5 = __lsx_vilvl_h(gr_l, ab_l); \ + RGB6 = __lsx_vilvh_h(gr_l, ab_l); \ + RGB7 = __lsx_vilvl_h(gr_h, ab_h); \ + RGB8 = __lsx_vilvh_h(gr_h, ab_h); \ +} + +#define PACK_RGB24_32_STEP(R, G, B, RGB1, RGB2, RGB3) \ + RGB1 = __lsx_vilvl_b(G, R); \ + RGB1 = __lsx_vshuf_b(B, RGB1, mask1); \ + RGB2 = __lsx_vshuf_b(B, G, mask2); \ + RGB2 = __lsx_vshuf_b(R, RGB2, mask3); \ + RGB3 = __lsx_vshuf_b(R, B, mask4); \ + RGB3 = __lsx_vshuf_b(G, RGB3, mask5); \ + +#define PACK_RGB24_32(R1, R2, G1, G2, B1, B2, RGB1, RGB2, RGB3, RGB4, RGB5, RGB6) \ + PACK_RGB24_32_STEP(R1, G1, B1, RGB1, RGB2, RGB3); \ + PACK_RGB24_32_STEP(R2, G2, B2, RGB4, RGB5, RGB6); \ + +#if RGB_FORMAT == RGB_FORMAT_RGB24 + +#define PACK_PIXEL \ + __m128i rgb_1, rgb_2, rgb_3, rgb_4, rgb_5, rgb_6; \ + __m128i rgb_7, rgb_8, rgb_9, rgb_10, rgb_11, rgb_12; \ + PACK_RGB24_32(r_8_11, r_8_12, g_8_11, g_8_12, b_8_11, b_8_12, \ + rgb_1, rgb_2, rgb_3, rgb_4, rgb_5, rgb_6) \ + PACK_RGB24_32(r_8_21, r_8_22, g_8_21, g_8_22, b_8_21, b_8_22, \ + rgb_7, rgb_8, rgb_9, rgb_10, rgb_11, rgb_12) \ + +#elif RGB_FORMAT == RGB_FORMAT_RGBA + +#define PACK_PIXEL \ + __m128i rgb_1, rgb_2, rgb_3, rgb_4, rgb_5, rgb_6, rgb_7, rgb_8; \ + __m128i rgb_9, rgb_10, rgb_11, rgb_12, rgb_13, rgb_14, rgb_15, rgb_16; \ + __m128i a = __lsx_vldi(0xFF); \ + PACK_RGBA_32(r_8_11, r_8_12, g_8_11, g_8_12, b_8_11, b_8_12, a, a, \ + rgb_1, rgb_2, rgb_3, rgb_4, rgb_5, rgb_6, rgb_7, rgb_8) \ + PACK_RGBA_32(r_8_21, r_8_22, g_8_21, g_8_22, b_8_21, b_8_22, a, a, \ + rgb_9, rgb_10, rgb_11, rgb_12, rgb_13, rgb_14, rgb_15, rgb_16) \ + +#elif RGB_FORMAT == RGB_FORMAT_BGRA + +#define PACK_PIXEL \ + __m128i rgb_1, rgb_2, rgb_3, rgb_4, rgb_5, rgb_6, rgb_7, rgb_8; \ + __m128i rgb_9, rgb_10, rgb_11, rgb_12, rgb_13, rgb_14, rgb_15, rgb_16; \ + __m128i a = __lsx_vldi(0xFF); \ + PACK_RGBA_32(b_8_11, b_8_12, g_8_11, g_8_12, r_8_11, r_8_12, a, a, \ + rgb_1, rgb_2, rgb_3, rgb_4, rgb_5, rgb_6, rgb_7, rgb_8) \ + PACK_RGBA_32(b_8_21, b_8_22, g_8_21, g_8_22, r_8_21, r_8_22, a, a, \ + rgb_9, rgb_10, rgb_11, rgb_12, rgb_13, rgb_14, rgb_15, rgb_16) \ + +#elif RGB_FORMAT == RGB_FORMAT_ARGB + +#define PACK_PIXEL \ + __m128i rgb_1, rgb_2, rgb_3, rgb_4, rgb_5, rgb_6, rgb_7, rgb_8; \ + __m128i rgb_9, rgb_10, rgb_11, rgb_12, rgb_13, rgb_14, rgb_15, rgb_16; \ + __m128i a = __lsx_vldi(0xFF); \ + PACK_RGBA_32(a, a, r_8_11, r_8_12, g_8_11, g_8_12, b_8_11, b_8_12, \ + rgb_1, rgb_2, rgb_3, rgb_4, rgb_5, rgb_6, rgb_7, rgb_8) \ + PACK_RGBA_32(a, a, r_8_21, r_8_22, g_8_21, g_8_22, b_8_21, b_8_22, \ + rgb_9, rgb_10, rgb_11, rgb_12, rgb_13, rgb_14, rgb_15, rgb_16) \ + +#elif RGB_FORMAT == RGB_FORMAT_ABGR + +#define PACK_PIXEL \ + __m128i rgb_1, rgb_2, rgb_3, rgb_4, rgb_5, rgb_6, rgb_7, rgb_8; \ + __m128i rgb_9, rgb_10, rgb_11, rgb_12, rgb_13, rgb_14, rgb_15, rgb_16; \ + __m128i a = __lsx_vldi(0xFF); \ + PACK_RGBA_32(a, a, b_8_11, b_8_12, g_8_11, g_8_12, r_8_11, r_8_12, \ + rgb_1, rgb_2, rgb_3, rgb_4, rgb_5, rgb_6, rgb_7, rgb_8) \ + PACK_RGBA_32(a, a, b_8_21, b_8_22, g_8_21, g_8_22, r_8_21, r_8_22, \ + rgb_9, rgb_10, rgb_11, rgb_12, rgb_13, rgb_14, rgb_15, rgb_16) \ + +#else +#error PACK_PIXEL unimplemented +#endif + +#define LSX_ST_UB2(in0, in1, pdst, stride) \ +{ \ + __lsx_vst(in0, pdst, 0); \ + __lsx_vst(in1, pdst + stride, 0); \ +} + +#if RGB_FORMAT == RGB_FORMAT_RGB24 \ + +#define SAVE_LINE1 \ + LSX_ST_UB2(rgb_1, rgb_2, rgb_ptr1, 16); \ + LSX_ST_UB2(rgb_3, rgb_4, rgb_ptr1 + 32, 16); \ + LSX_ST_UB2(rgb_5, rgb_6, rgb_ptr1 + 64, 16); \ + +#define SAVE_LINE2 \ + LSX_ST_UB2(rgb_7, rgb_8, rgb_ptr2, 16); \ + LSX_ST_UB2(rgb_9, rgb_10, rgb_ptr2 + 32, 16); \ + LSX_ST_UB2(rgb_11, rgb_12, rgb_ptr2 + 64, 16); \ + +#elif RGB_FORMAT == RGB_FORMAT_RGBA || RGB_FORMAT == RGB_FORMAT_BGRA || \ + RGB_FORMAT == RGB_FORMAT_ARGB || RGB_FORMAT == RGB_FORMAT_ABGR \ + +#define SAVE_LINE1 \ + LSX_ST_UB2(rgb_1, rgb_2, rgb_ptr1, 16); \ + LSX_ST_UB2(rgb_3, rgb_4, rgb_ptr1 + 32, 16); \ + LSX_ST_UB2(rgb_5, rgb_6, rgb_ptr1 + 64, 16); \ + LSX_ST_UB2(rgb_7, rgb_8, rgb_ptr1 + 96, 16); \ + +#define SAVE_LINE2 \ + LSX_ST_UB2(rgb_9, rgb_10, rgb_ptr2, 16); \ + LSX_ST_UB2(rgb_11, rgb_12, rgb_ptr2 + 32, 16); \ + LSX_ST_UB2(rgb_13, rgb_14, rgb_ptr2 + 64, 16); \ + LSX_ST_UB2(rgb_15, rgb_16, rgb_ptr2 + 96, 16); \ + +#else +#error SAVE_LINE unimplemented +#endif + +// = u*vr g=u*ug+v*vg b=u*ub +#define UV2RGB_16(U, V, R1, G1, B1, R2, G2, B2) \ + r_temp = __lsx_vmul_h(V, v2r); \ + g_temp = __lsx_vmul_h(U, u2g); \ + g_temp = __lsx_vmadd_h(g_temp, V, v2g); \ + b_temp = __lsx_vmul_h(U, u2b); \ + R1 = __lsx_vilvl_h(r_temp, r_temp); \ + G1 = __lsx_vilvl_h(g_temp, g_temp); \ + B1 = __lsx_vilvl_h(b_temp, b_temp); \ + R2 = __lsx_vilvh_h(r_temp, r_temp); \ + G2 = __lsx_vilvh_h(g_temp, g_temp); \ + B2 = __lsx_vilvh_h(b_temp, b_temp); \ + +// Y=(Y-shift)*shift R=(Y+R)>>6,G=(Y+G)>>6,B=(B+Y)>>6 +#define ADD_Y2RGB_16(Y1, Y2, R1, G1, B1, R2, G2, B2) \ + Y1 = __lsx_vsub_h(Y1, shift); \ + Y2 = __lsx_vsub_h(Y2, shift); \ + Y1 = __lsx_vmul_h(Y1, yf); \ + Y2 = __lsx_vmul_h(Y2, yf); \ + R1 = __lsx_vadd_h(R1, Y1); \ + G1 = __lsx_vadd_h(G1, Y1); \ + B1 = __lsx_vadd_h(B1, Y1); \ + R2 = __lsx_vadd_h(R2, Y2); \ + G2 = __lsx_vadd_h(G2, Y2); \ + B2 = __lsx_vadd_h(B2, Y2); \ + R1 = __lsx_vsrai_h(R1, PRECISION); \ + G1 = __lsx_vsrai_h(G1, PRECISION); \ + B1 = __lsx_vsrai_h(B1, PRECISION); \ + R2 = __lsx_vsrai_h(R2, PRECISION); \ + G2 = __lsx_vsrai_h(G2, PRECISION); \ + B2 = __lsx_vsrai_h(B2, PRECISION); \ + +#define CLIP(in0, in1, in2, in3, in4, in5) \ +{ \ + in0 = __lsx_vmaxi_h(in0, 0); \ + in1 = __lsx_vmaxi_h(in1, 0); \ + in2 = __lsx_vmaxi_h(in2, 0); \ + in3 = __lsx_vmaxi_h(in3, 0); \ + in4 = __lsx_vmaxi_h(in4, 0); \ + in5 = __lsx_vmaxi_h(in5, 0); \ + in0 = __lsx_vsat_hu(in0, 7); \ + in1 = __lsx_vsat_hu(in1, 7); \ + in2 = __lsx_vsat_hu(in2, 7); \ + in3 = __lsx_vsat_hu(in3, 7); \ + in4 = __lsx_vsat_hu(in4, 7); \ + in5 = __lsx_vsat_hu(in5, 7); \ +} + +#define YUV2RGB_32 \ + __m128i y, u_temp, v_temp; \ + __m128i r_8_11, g_8_11, b_8_11, r_8_21, g_8_21, b_8_21; \ + __m128i r_8_12, g_8_12, b_8_12, r_8_22, g_8_22, b_8_22; \ + __m128i u, v, r_temp, g_temp, b_temp; \ + __m128i r_1, g_1, b_1, r_2, g_2, b_2; \ + __m128i y_1, y_2; \ + __m128i r_uv_1, g_uv_1, b_uv_1, r_uv_2, g_uv_2, b_uv_2; \ + \ + READ_UV \ + \ + /* process first 16 pixels of first line */ \ + u = __lsx_vilvl_b(zero, u_temp); \ + v = __lsx_vilvl_b(zero, v_temp); \ + u = __lsx_vsub_h(u, bias); \ + v = __lsx_vsub_h(v, bias); \ + UV2RGB_16(u, v, r_1, g_1, b_1, r_2, g_2, b_2); \ + r_uv_1 = r_1; g_uv_1 = g_1; b_uv_1 = b_1; \ + r_uv_2 = r_2; g_uv_2 = g_2; b_uv_2 = b_2; \ + READ_Y(y_ptr1) \ + y_1 = __lsx_vilvl_b(zero, y); \ + y_2 = __lsx_vilvh_b(zero, y); \ + ADD_Y2RGB_16(y_1, y_2, r_1, g_1, b_1, r_2, g_2, b_2) \ + CLIP(r_1, g_1, b_1, r_2, g_2, b_2); \ + r_8_11 = __lsx_vpickev_b(r_2, r_1); \ + g_8_11 = __lsx_vpickev_b(g_2, g_1); \ + b_8_11 = __lsx_vpickev_b(b_2, b_1); \ + \ + /* process first 16 pixels of second line */ \ + r_1 = r_uv_1; g_1 = g_uv_1; b_1 = b_uv_1; \ + r_2 = r_uv_2; g_2 = g_uv_2; b_2 = b_uv_2; \ + \ + READ_Y(y_ptr2) \ + y_1 = __lsx_vilvl_b(zero, y); \ + y_2 = __lsx_vilvh_b(zero, y); \ + ADD_Y2RGB_16(y_1, y_2, r_1, g_1, b_1, r_2, g_2, b_2) \ + CLIP(r_1, g_1, b_1, r_2, g_2, b_2); \ + r_8_21 = __lsx_vpickev_b(r_2, r_1); \ + g_8_21 = __lsx_vpickev_b(g_2, g_1); \ + b_8_21 = __lsx_vpickev_b(b_2, b_1); \ + \ + /* process last 16 pixels of first line */ \ + u = __lsx_vilvh_b(zero, u_temp); \ + v = __lsx_vilvh_b(zero, v_temp); \ + u = __lsx_vsub_h(u, bias); \ + v = __lsx_vsub_h(v, bias); \ + UV2RGB_16(u, v, r_1, g_1, b_1, r_2, g_2, b_2); \ + r_uv_1 = r_1; g_uv_1 = g_1; b_uv_1 = b_1; \ + r_uv_2 = r_2; g_uv_2 = g_2; b_uv_2 = b_2; \ + READ_Y(y_ptr1 + 16 * y_pixel_stride) \ + y_1 = __lsx_vilvl_b(zero, y); \ + y_2 = __lsx_vilvh_b(zero, y); \ + ADD_Y2RGB_16(y_1, y_2, r_1, g_1, b_1, r_2, g_2, b_2) \ + CLIP(r_1, g_1, b_1, r_2, g_2, b_2); \ + r_8_12 = __lsx_vpickev_b(r_2, r_1); \ + g_8_12 = __lsx_vpickev_b(g_2, g_1); \ + b_8_12 = __lsx_vpickev_b(b_2, b_1); \ + \ + /* process last 16 pixels of second line */ \ + r_1 = r_uv_1; g_1 = g_uv_1; b_1 = b_uv_1; \ + r_2 = r_uv_2; g_2 = g_uv_2; b_2 = b_uv_2; \ + \ + READ_Y(y_ptr2 + 16 * y_pixel_stride) \ + y_1 = __lsx_vilvl_b(zero, y); \ + y_2 = __lsx_vilvh_b(zero, y); \ + ADD_Y2RGB_16(y_1, y_2, r_1, g_1, b_1, r_2, g_2, b_2) \ + CLIP(r_1, g_1, b_1, r_2, g_2, b_2); \ + r_8_22 = __lsx_vpickev_b(r_2, r_1); \ + g_8_22 = __lsx_vpickev_b(g_2, g_1); \ + b_8_22 = __lsx_vpickev_b(b_2, b_1); \ + \ + +void LSX_FUNCTION_NAME(uint32_t width, uint32_t height, const uint8_t *Y, + const uint8_t *U, const uint8_t *V, uint32_t Y_stride, + uint32_t UV_stride, uint8_t *RGB, uint32_t RGB_stride, + YCbCrType yuv_type) +{ + const YUV2RGBParam *const param = &(YUV2RGB[yuv_type]); +#if YUV_FORMAT == YUV_FORMAT_420 + const int y_pixel_stride = 1; + const int uv_pixel_stride = 1; + const int uv_x_sample_interval = 2; + const int uv_y_sample_interval = 2; +#endif + +#if RGB_FORMAT == RGB_FORMAT_RGB565 + const int rgb_pixel_stride = 2; +#elif RGB_FORMAT == RGB_FORMAT_RGB24 + const int rgb_pixel_stride = 3; + __m128i mask1 = {0x0504110302100100, 0x0A14090813070612}; + __m128i mask2 = {0x1808170716061505, 0x00000000000A1909}; + __m128i mask3 = {0x0504170302160100, 0x0A1A090819070618}; + __m128i mask4 = {0x1E0D1D0C1C0B1B0A, 0x00000000000F1F0E}; + __m128i mask5 = {0x05041C03021B0100, 0x0A1F09081E07061D}; +#elif RGB_FORMAT == RGB_FORMAT_RGBA || RGB_FORMAT_BGRA || \ + RGB_FORMAT == RGB_FORMAT_ARGB || RGB_FORMAT_ABGR + const int rgb_pixel_stride = 4; +#else +#error Unknown RGB pixel size +#endif + + uint32_t xpos, ypos; + __m128i v2r = __lsx_vreplgr2vr_h(param->v_r_factor); + __m128i v2g = __lsx_vreplgr2vr_h(param->v_g_factor); + __m128i u2g = __lsx_vreplgr2vr_h(param->u_g_factor); + __m128i u2b = __lsx_vreplgr2vr_h(param->u_b_factor); + __m128i bias = __lsx_vreplgr2vr_h(128); + __m128i shift = __lsx_vreplgr2vr_h(param->y_shift); + __m128i yf = __lsx_vreplgr2vr_h(param->y_factor); + __m128i zero = __lsx_vldi(0); + + if (width >= 32) { + for (ypos = 0; ypos < (height - (uv_y_sample_interval - 1)); ypos += uv_y_sample_interval) { + const uint8_t *y_ptr1 = Y + ypos * Y_stride, + *y_ptr2 = Y + (ypos + 1) * Y_stride, + *u_ptr = U + (ypos/uv_y_sample_interval) * UV_stride, + *v_ptr = V + (ypos/uv_y_sample_interval) * UV_stride; + uint8_t *rgb_ptr1 = RGB + ypos * RGB_stride, + *rgb_ptr2 = RGB + (ypos + 1) * RGB_stride; + + for (xpos = 0; xpos < (width - 31); xpos += 32){ + YUV2RGB_32 + { + PACK_PIXEL + SAVE_LINE1 + if (uv_y_sample_interval > 1) + { + SAVE_LINE2 + } + } + y_ptr1 += 32 * y_pixel_stride; + y_ptr2 += 32 * y_pixel_stride; + u_ptr += 32 * uv_pixel_stride/uv_x_sample_interval; + v_ptr += 32 * uv_pixel_stride/uv_x_sample_interval; + rgb_ptr1 += 32 * rgb_pixel_stride; + rgb_ptr2 += 32 * rgb_pixel_stride; + } + } + if (uv_y_sample_interval == 2 && ypos == (height - 1)) { + const uint8_t *y_ptr = Y + ypos * Y_stride, + *u_ptr = U + (ypos/uv_y_sample_interval) * UV_stride, + *v_ptr = V + (ypos/uv_y_sample_interval) * UV_stride; + uint8_t *rgb_ptr = RGB + ypos * RGB_stride; + STD_FUNCTION_NAME(width, 1, y_ptr, u_ptr, v_ptr, Y_stride, UV_stride, rgb_ptr, RGB_stride, yuv_type); + } + } + { + int converted = (width & ~31); + if (converted != width) + { + const uint8_t *y_ptr = Y + converted * y_pixel_stride, + *u_ptr = U + converted * uv_pixel_stride / uv_x_sample_interval, + *v_ptr = V + converted * uv_pixel_stride / uv_x_sample_interval; + uint8_t *rgb_ptr = RGB + converted * rgb_pixel_stride; + + STD_FUNCTION_NAME(width-converted, height, y_ptr, u_ptr, v_ptr, Y_stride, UV_stride, rgb_ptr, RGB_stride, yuv_type); + } + } +} + +#undef LSX_FUNCTION_NAME +#undef STD_FUNCTION_NAME +#undef YUV_FORMAT +#undef RGB_FORMAT +#undef LSX_ALIGNED +#undef LSX_ST_UB2 +#undef UV2RGB_16 +#undef ADD_Y2RGB_16 +#undef PACK_RGB24_32_STEP +#undef PACK_RGB24_32 +#undef PACK_PIXEL +#undef PACK_RGBA_32 +#undef SAVE_LINE1 +#undef SAVE_LINE2 +#undef READ_Y +#undef READ_UV +#undef YUV2RGB_32 diff --git a/SDL2-2.0.12/src/video/yuv2rgb/yuv_rgb.c b/SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb_sse.c similarity index 54% rename from SDL2-2.0.12/src/video/yuv2rgb/yuv_rgb.c rename to SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb_sse.c index 6e821a8..b22a89f 100644 --- a/SDL2-2.0.12/src/video/yuv2rgb/yuv_rgb.c +++ b/SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb_sse.c @@ -3,247 +3,15 @@ #include "../../SDL_internal.h" #if SDL_HAVE_YUV - #include "yuv_rgb.h" +#include "yuv_rgb_internal.h" #include "SDL_cpuinfo.h" /*#include */ -#define PRECISION 6 -#define PRECISION_FACTOR (1<[0-255]) -// for ITU-R BT.709-6 values are derived from equations in sections 3.2-3.4, assuming RGB is encoded using full range ([0-1]<->[0-255]) -// all values are rounded to the fourth decimal - -static const YUV2RGBParam YUV2RGB[3] = { - // ITU-T T.871 (JPEG) - {/*.y_shift=*/ 0, /*.y_factor=*/ V(1.0), /*.v_r_factor=*/ V(1.402), /*.u_g_factor=*/ -V(0.3441), /*.v_g_factor=*/ -V(0.7141), /*.u_b_factor=*/ V(1.772)}, - // ITU-R BT.601-7 - {/*.y_shift=*/ 16, /*.y_factor=*/ V(1.1644), /*.v_r_factor=*/ V(1.596), /*.u_g_factor=*/ -V(0.3918), /*.v_g_factor=*/ -V(0.813), /*.u_b_factor=*/ V(2.0172)}, - // ITU-R BT.709-6 - {/*.y_shift=*/ 16, /*.y_factor=*/ V(1.1644), /*.v_r_factor=*/ V(1.7927), /*.u_g_factor=*/ -V(0.2132), /*.v_g_factor=*/ -V(0.5329), /*.u_b_factor=*/ V(2.1124)} -}; - -static const RGB2YUVParam RGB2YUV[3] = { - // ITU-T T.871 (JPEG) - {/*.y_shift=*/ 0, /*.matrix=*/ {{V(0.299), V(0.587), V(0.114)}, {-V(0.1687), -V(0.3313), V(0.5)}, {V(0.5), -V(0.4187), -V(0.0813)}}}, - // ITU-R BT.601-7 - {/*.y_shift=*/ 16, /*.matrix=*/ {{V(0.2568), V(0.5041), V(0.0979)}, {-V(0.1482), -V(0.291), V(0.4392)}, {V(0.4392), -V(0.3678), -V(0.0714)}}}, - // ITU-R BT.709-6 - {/*.y_shift=*/ 16, /*.matrix=*/ {{V(0.1826), V(0.6142), V(0.062)}, {-V(0.1006), -V(0.3386), V(0.4392)}, {V(0.4392), -V(0.3989), -V(0.0403)}}} -}; - -/* The various layouts of YUV data we support */ -#define YUV_FORMAT_420 1 -#define YUV_FORMAT_422 2 -#define YUV_FORMAT_NV12 3 - -/* The various formats of RGB pixel that we support */ -#define RGB_FORMAT_RGB565 1 -#define RGB_FORMAT_RGB24 2 -#define RGB_FORMAT_RGBA 3 -#define RGB_FORMAT_BGRA 4 -#define RGB_FORMAT_ARGB 5 -#define RGB_FORMAT_ABGR 6 - -// divide by PRECISION_FACTOR and clamp to [0:255] interval -// input must be in the [-128*PRECISION_FACTOR:384*PRECISION_FACTOR] range -static uint8_t clampU8(int32_t v) -{ - static const uint8_t lut[512] = - {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46, - 47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90, - 91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125, - 126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158, - 159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, - 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224, - 225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255, - 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 - }; - return lut[(v+128*PRECISION_FACTOR)>>PRECISION]; -} - - -#define STD_FUNCTION_NAME yuv420_rgb565_std -#define YUV_FORMAT YUV_FORMAT_420 -#define RGB_FORMAT RGB_FORMAT_RGB565 -#include "yuv_rgb_std_func.h" - -#define STD_FUNCTION_NAME yuv420_rgb24_std -#define YUV_FORMAT YUV_FORMAT_420 -#define RGB_FORMAT RGB_FORMAT_RGB24 -#include "yuv_rgb_std_func.h" - -#define STD_FUNCTION_NAME yuv420_rgba_std -#define YUV_FORMAT YUV_FORMAT_420 -#define RGB_FORMAT RGB_FORMAT_RGBA -#include "yuv_rgb_std_func.h" - -#define STD_FUNCTION_NAME yuv420_bgra_std -#define YUV_FORMAT YUV_FORMAT_420 -#define RGB_FORMAT RGB_FORMAT_BGRA -#include "yuv_rgb_std_func.h" - -#define STD_FUNCTION_NAME yuv420_argb_std -#define YUV_FORMAT YUV_FORMAT_420 -#define RGB_FORMAT RGB_FORMAT_ARGB -#include "yuv_rgb_std_func.h" - -#define STD_FUNCTION_NAME yuv420_abgr_std -#define YUV_FORMAT YUV_FORMAT_420 -#define RGB_FORMAT RGB_FORMAT_ABGR -#include "yuv_rgb_std_func.h" - -#define STD_FUNCTION_NAME yuv422_rgb565_std -#define YUV_FORMAT YUV_FORMAT_422 -#define RGB_FORMAT RGB_FORMAT_RGB565 -#include "yuv_rgb_std_func.h" - -#define STD_FUNCTION_NAME yuv422_rgb24_std -#define YUV_FORMAT YUV_FORMAT_422 -#define RGB_FORMAT RGB_FORMAT_RGB24 -#include "yuv_rgb_std_func.h" - -#define STD_FUNCTION_NAME yuv422_rgba_std -#define YUV_FORMAT YUV_FORMAT_422 -#define RGB_FORMAT RGB_FORMAT_RGBA -#include "yuv_rgb_std_func.h" - -#define STD_FUNCTION_NAME yuv422_bgra_std -#define YUV_FORMAT YUV_FORMAT_422 -#define RGB_FORMAT RGB_FORMAT_BGRA -#include "yuv_rgb_std_func.h" - -#define STD_FUNCTION_NAME yuv422_argb_std -#define YUV_FORMAT YUV_FORMAT_422 -#define RGB_FORMAT RGB_FORMAT_ARGB -#include "yuv_rgb_std_func.h" - -#define STD_FUNCTION_NAME yuv422_abgr_std -#define YUV_FORMAT YUV_FORMAT_422 -#define RGB_FORMAT RGB_FORMAT_ABGR -#include "yuv_rgb_std_func.h" - -#define STD_FUNCTION_NAME yuvnv12_rgb565_std -#define YUV_FORMAT YUV_FORMAT_NV12 -#define RGB_FORMAT RGB_FORMAT_RGB565 -#include "yuv_rgb_std_func.h" - -#define STD_FUNCTION_NAME yuvnv12_rgb24_std -#define YUV_FORMAT YUV_FORMAT_NV12 -#define RGB_FORMAT RGB_FORMAT_RGB24 -#include "yuv_rgb_std_func.h" - -#define STD_FUNCTION_NAME yuvnv12_rgba_std -#define YUV_FORMAT YUV_FORMAT_NV12 -#define RGB_FORMAT RGB_FORMAT_RGBA -#include "yuv_rgb_std_func.h" - -#define STD_FUNCTION_NAME yuvnv12_bgra_std -#define YUV_FORMAT YUV_FORMAT_NV12 -#define RGB_FORMAT RGB_FORMAT_BGRA -#include "yuv_rgb_std_func.h" - -#define STD_FUNCTION_NAME yuvnv12_argb_std -#define YUV_FORMAT YUV_FORMAT_NV12 -#define RGB_FORMAT RGB_FORMAT_ARGB -#include "yuv_rgb_std_func.h" - -#define STD_FUNCTION_NAME yuvnv12_abgr_std -#define YUV_FORMAT YUV_FORMAT_NV12 -#define RGB_FORMAT RGB_FORMAT_ABGR -#include "yuv_rgb_std_func.h" - -void rgb24_yuv420_std( - uint32_t width, uint32_t height, - const uint8_t *RGB, uint32_t RGB_stride, - uint8_t *Y, uint8_t *U, uint8_t *V, uint32_t Y_stride, uint32_t UV_stride, - YCbCrType yuv_type) -{ - const RGB2YUVParam *const param = &(RGB2YUV[yuv_type]); - - uint32_t x, y; - for(y=0; y<(height-1); y+=2) - { - const uint8_t *rgb_ptr1=RGB+y*RGB_stride, - *rgb_ptr2=RGB+(y+1)*RGB_stride; - - uint8_t *y_ptr1=Y+y*Y_stride, - *y_ptr2=Y+(y+1)*Y_stride, - *u_ptr=U+(y/2)*UV_stride, - *v_ptr=V+(y/2)*UV_stride; - - for(x=0; x<(width-1); x+=2) - { - // compute yuv for the four pixels, u and v values are summed - int32_t y_tmp, u_tmp, v_tmp; - - y_tmp = param->matrix[0][0]*rgb_ptr1[0] + param->matrix[0][1]*rgb_ptr1[1] + param->matrix[0][2]*rgb_ptr1[2]; - u_tmp = param->matrix[1][0]*rgb_ptr1[0] + param->matrix[1][1]*rgb_ptr1[1] + param->matrix[1][2]*rgb_ptr1[2]; - v_tmp = param->matrix[2][0]*rgb_ptr1[0] + param->matrix[2][1]*rgb_ptr1[1] + param->matrix[2][2]*rgb_ptr1[2]; - y_ptr1[0]=clampU8(y_tmp+((param->y_shift)<matrix[0][0]*rgb_ptr1[3] + param->matrix[0][1]*rgb_ptr1[4] + param->matrix[0][2]*rgb_ptr1[5]; - u_tmp += param->matrix[1][0]*rgb_ptr1[3] + param->matrix[1][1]*rgb_ptr1[4] + param->matrix[1][2]*rgb_ptr1[5]; - v_tmp += param->matrix[2][0]*rgb_ptr1[3] + param->matrix[2][1]*rgb_ptr1[4] + param->matrix[2][2]*rgb_ptr1[5]; - y_ptr1[1]=clampU8(y_tmp+((param->y_shift)<matrix[0][0]*rgb_ptr2[0] + param->matrix[0][1]*rgb_ptr2[1] + param->matrix[0][2]*rgb_ptr2[2]; - u_tmp += param->matrix[1][0]*rgb_ptr2[0] + param->matrix[1][1]*rgb_ptr2[1] + param->matrix[1][2]*rgb_ptr2[2]; - v_tmp += param->matrix[2][0]*rgb_ptr2[0] + param->matrix[2][1]*rgb_ptr2[1] + param->matrix[2][2]*rgb_ptr2[2]; - y_ptr2[0]=clampU8(y_tmp+((param->y_shift)<matrix[0][0]*rgb_ptr2[3] + param->matrix[0][1]*rgb_ptr2[4] + param->matrix[0][2]*rgb_ptr2[5]; - u_tmp += param->matrix[1][0]*rgb_ptr2[3] + param->matrix[1][1]*rgb_ptr2[4] + param->matrix[1][2]*rgb_ptr2[5]; - v_tmp += param->matrix[2][0]*rgb_ptr2[3] + param->matrix[2][1]*rgb_ptr2[4] + param->matrix[2][2]*rgb_ptr2[5]; - y_ptr2[1]=clampU8(y_tmp+((param->y_shift)<matrix[0][0])), \ - _mm_mullo_epi16(G, _mm_set1_epi16(param->matrix[0][1]))); \ + _mm_mullo_epi16(G, _mm_set1_epi16(param->matrix[0][1]))); \ Y = _mm_add_epi16(Y, _mm_mullo_epi16(B, _mm_set1_epi16(param->matrix[0][2]))); \ Y = _mm_add_epi16(Y, _mm_set1_epi16((param->y_shift)<matrix[1][0])), \ - _mm_mullo_epi16(G, _mm_set1_epi16(param->matrix[1][1]))); \ + _mm_mullo_epi16(G, _mm_set1_epi16(param->matrix[1][1]))); \ U = _mm_add_epi16(U, _mm_mullo_epi16(B, _mm_set1_epi16(param->matrix[1][2]))); \ U = _mm_add_epi16(U, _mm_set1_epi16(128<matrix[2][0])), \ - _mm_mullo_epi16(G, _mm_set1_epi16(param->matrix[2][1]))); \ + _mm_mullo_epi16(G, _mm_set1_epi16(param->matrix[2][1]))); \ V = _mm_add_epi16(V, _mm_mullo_epi16(B, _mm_set1_epi16(param->matrix[2][2]))); \ V = _mm_add_epi16(V, _mm_set1_epi16(128<*/ +#include "yuv_rgb_common.h" + +#include "SDL_stdinc.h" + +// yuv to rgb, sse implementation +// pointers must be 16 byte aligned, and strides must be divisable by 16 +void yuv420_rgb565_sse( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv420_rgb24_sse( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv420_rgba_sse( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv420_bgra_sse( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv420_argb_sse( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv420_abgr_sse( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv422_rgb565_sse( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv422_rgb24_sse( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv422_rgba_sse( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv422_bgra_sse( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv422_argb_sse( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv422_abgr_sse( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuvnv12_rgb565_sse( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuvnv12_rgb24_sse( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuvnv12_rgba_sse( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuvnv12_bgra_sse( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuvnv12_argb_sse( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuvnv12_abgr_sse( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +// yuv to rgb, sse implementation +// pointers do not need to be 16 byte aligned +void yuv420_rgb565_sseu( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv420_rgb24_sseu( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv420_rgba_sseu( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv420_bgra_sseu( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv420_argb_sseu( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv420_abgr_sseu( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv422_rgb565_sseu( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv422_rgb24_sseu( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv422_rgba_sseu( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv422_bgra_sseu( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv422_argb_sseu( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv422_abgr_sseu( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuvnv12_rgb565_sseu( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuvnv12_rgb24_sseu( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuvnv12_rgba_sseu( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuvnv12_bgra_sseu( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuvnv12_argb_sseu( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuvnv12_abgr_sseu( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + + +// rgb to yuv, standard c implementation +void rgb24_yuv420_std( + uint32_t width, uint32_t height, + const uint8_t *rgb, uint32_t rgb_stride, + uint8_t *y, uint8_t *u, uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + YCbCrType yuv_type); + +// rgb to yuv, sse implementation +// pointers must be 16 byte aligned, and strides must be divisible by 16 +void rgb24_yuv420_sse( + uint32_t width, uint32_t height, + const uint8_t *rgb, uint32_t rgb_stride, + uint8_t *y, uint8_t *u, uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + YCbCrType yuv_type); + +// rgb to yuv, sse implementation +// pointers do not need to be 16 byte aligned +void rgb24_yuv420_sseu( + uint32_t width, uint32_t height, + const uint8_t *rgb, uint32_t rgb_stride, + uint8_t *y, uint8_t *u, uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + YCbCrType yuv_type); diff --git a/SDL2-2.0.12/src/video/yuv2rgb/yuv_rgb_sse_func.h b/SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb_sse_func.h similarity index 93% rename from SDL2-2.0.12/src/video/yuv2rgb/yuv_rgb_sse_func.h rename to SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb_sse_func.h index f81140e..295749a 100644 --- a/SDL2-2.0.12/src/video/yuv2rgb/yuv_rgb_sse_func.h +++ b/SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb_sse_func.h @@ -52,7 +52,7 @@ { \ __m128i red_mask, tmp1, tmp2, tmp3, tmp4; \ \ - red_mask = _mm_set1_epi16((short)0xF800); \ + red_mask = _mm_set1_epi16((unsigned short)0xF800); \ RGB1 = _mm_and_si128(_mm_unpacklo_epi8(_mm_setzero_si128(), R1), red_mask); \ RGB2 = _mm_and_si128(_mm_unpackhi_epi8(_mm_setzero_si128(), R1), red_mask); \ RGB3 = _mm_and_si128(_mm_unpacklo_epi8(_mm_setzero_si128(), R2), red_mask); \ @@ -145,7 +145,7 @@ PACK_RGB24_32_STEP1(R1, R2, G1, G2, B1, B2, RGB1, RGB2, RGB3, RGB4, RGB5, RGB6) #define PACK_PIXEL \ __m128i rgb_1, rgb_2, rgb_3, rgb_4, rgb_5, rgb_6, rgb_7, rgb_8; \ __m128i rgb_9, rgb_10, rgb_11, rgb_12, rgb_13, rgb_14, rgb_15, rgb_16; \ - __m128i a = _mm_set1_epi8((char)0xFF); \ + __m128i a = _mm_set1_epi8((unsigned char)0xFF); \ \ PACK_RGBA_32(r_8_11, r_8_12, g_8_11, g_8_12, b_8_11, b_8_12, a, a, rgb_1, rgb_2, rgb_3, rgb_4, rgb_5, rgb_6, rgb_7, rgb_8) \ \ @@ -156,7 +156,7 @@ PACK_RGB24_32_STEP1(R1, R2, G1, G2, B1, B2, RGB1, RGB2, RGB3, RGB4, RGB5, RGB6) #define PACK_PIXEL \ __m128i rgb_1, rgb_2, rgb_3, rgb_4, rgb_5, rgb_6, rgb_7, rgb_8; \ __m128i rgb_9, rgb_10, rgb_11, rgb_12, rgb_13, rgb_14, rgb_15, rgb_16; \ - __m128i a = _mm_set1_epi8((char)0xFF); \ + __m128i a = _mm_set1_epi8((unsigned char)0xFF); \ \ PACK_RGBA_32(b_8_11, b_8_12, g_8_11, g_8_12, r_8_11, r_8_12, a, a, rgb_1, rgb_2, rgb_3, rgb_4, rgb_5, rgb_6, rgb_7, rgb_8) \ \ @@ -167,7 +167,7 @@ PACK_RGB24_32_STEP1(R1, R2, G1, G2, B1, B2, RGB1, RGB2, RGB3, RGB4, RGB5, RGB6) #define PACK_PIXEL \ __m128i rgb_1, rgb_2, rgb_3, rgb_4, rgb_5, rgb_6, rgb_7, rgb_8; \ __m128i rgb_9, rgb_10, rgb_11, rgb_12, rgb_13, rgb_14, rgb_15, rgb_16; \ - __m128i a = _mm_set1_epi8((char)0xFF); \ + __m128i a = _mm_set1_epi8((unsigned char)0xFF); \ \ PACK_RGBA_32(a, a, r_8_11, r_8_12, g_8_11, g_8_12, b_8_11, b_8_12, rgb_1, rgb_2, rgb_3, rgb_4, rgb_5, rgb_6, rgb_7, rgb_8) \ \ @@ -178,7 +178,7 @@ PACK_RGB24_32_STEP1(R1, R2, G1, G2, B1, B2, RGB1, RGB2, RGB3, RGB4, RGB5, RGB6) #define PACK_PIXEL \ __m128i rgb_1, rgb_2, rgb_3, rgb_4, rgb_5, rgb_6, rgb_7, rgb_8; \ __m128i rgb_9, rgb_10, rgb_11, rgb_12, rgb_13, rgb_14, rgb_15, rgb_16; \ - __m128i a = _mm_set1_epi8((char)0xFF); \ + __m128i a = _mm_set1_epi8((unsigned char)0xFF); \ \ PACK_RGBA_32(a, a, b_8_11, b_8_12, g_8_11, g_8_12, r_8_11, r_8_12, rgb_1, rgb_2, rgb_3, rgb_4, rgb_5, rgb_6, rgb_7, rgb_8) \ \ @@ -415,9 +415,28 @@ void SSE_FUNCTION_NAME(uint32_t width, uint32_t height, #error Unknown RGB pixel size #endif +#if YUV_FORMAT == YUV_FORMAT_NV12 + /* For NV12 formats (where U/V are interleaved) + * SSE READ_UV does an invalid read access at the very last pixel. + * As a workaround. Make sure not to decode the last column using assembly but with STD fallback path. + * see https://github.com/libsdl-org/SDL/issues/4841 + */ + const int fix_read_nv12 = ((width & 31) == 0); +#else + const int fix_read_nv12 = 0; +#endif + +#if YUV_FORMAT == YUV_FORMAT_422 + /* Avoid invalid read on last line */ + const int fix_read_422 = 1; +#else + const int fix_read_422 = 0; +#endif + + if (width >= 32) { uint32_t xpos, ypos; - for(ypos=0; ypos<(height-(uv_y_sample_interval-1)); ypos+=uv_y_sample_interval) + for(ypos=0; ypos<(height-(uv_y_sample_interval-1)) - fix_read_422; ypos+=uv_y_sample_interval) { const uint8_t *y_ptr1=Y+ypos*Y_stride, *y_ptr2=Y+(ypos+1)*Y_stride, @@ -427,7 +446,7 @@ void SSE_FUNCTION_NAME(uint32_t width, uint32_t height, uint8_t *rgb_ptr1=RGB+ypos*RGB_stride, *rgb_ptr2=RGB+(ypos+1)*RGB_stride; - for(xpos=0; xpos<(width-31); xpos+=32) + for(xpos=0; xpos<(width-31) - fix_read_nv12; xpos+=32) { YUV2RGB_32 { @@ -448,6 +467,15 @@ void SSE_FUNCTION_NAME(uint32_t width, uint32_t height, } } + if (fix_read_422) { + const uint8_t *y_ptr=Y+ypos*Y_stride, + *u_ptr=U+(ypos/uv_y_sample_interval)*UV_stride, + *v_ptr=V+(ypos/uv_y_sample_interval)*UV_stride; + uint8_t *rgb_ptr=RGB+ypos*RGB_stride; + STD_FUNCTION_NAME(width, 1, y_ptr, u_ptr, v_ptr, Y_stride, UV_stride, rgb_ptr, RGB_stride, yuv_type); + ypos += uv_y_sample_interval; + } + /* Catch the last line, if needed */ if (uv_y_sample_interval == 2 && ypos == (height-1)) { @@ -463,7 +491,10 @@ void SSE_FUNCTION_NAME(uint32_t width, uint32_t height, /* Catch the right column, if needed */ { - int converted = (width & ~31); + uint32_t converted = (width & ~31); + if (fix_read_nv12) { + converted -= 32; + } if (converted != width) { const uint8_t *y_ptr=Y+converted*y_pixel_stride, diff --git a/SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb_std.c b/SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb_std.c new file mode 100644 index 0000000..a222a3a --- /dev/null +++ b/SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb_std.c @@ -0,0 +1,179 @@ +// Copyright 2016 Adrien Descamps +// Distributed under BSD 3-Clause License +#include "../../SDL_internal.h" + +#if SDL_HAVE_YUV +#include "yuv_rgb.h" +#include "yuv_rgb_internal.h" + +// divide by PRECISION_FACTOR and clamp to [0:255] interval +// input must be in the [-128*PRECISION_FACTOR:384*PRECISION_FACTOR] range +static uint8_t clampU8(int32_t v) +{ + static const uint8_t lut[512] = + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46, + 47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90, + 91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125, + 126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158, + 159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, + 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224, + 225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 + }; + return lut[((v+128*PRECISION_FACTOR)>>PRECISION)&511]; +} + + +#define STD_FUNCTION_NAME yuv420_rgb565_std +#define YUV_FORMAT YUV_FORMAT_420 +#define RGB_FORMAT RGB_FORMAT_RGB565 +#include "yuv_rgb_std_func.h" + +#define STD_FUNCTION_NAME yuv420_rgb24_std +#define YUV_FORMAT YUV_FORMAT_420 +#define RGB_FORMAT RGB_FORMAT_RGB24 +#include "yuv_rgb_std_func.h" + +#define STD_FUNCTION_NAME yuv420_rgba_std +#define YUV_FORMAT YUV_FORMAT_420 +#define RGB_FORMAT RGB_FORMAT_RGBA +#include "yuv_rgb_std_func.h" + +#define STD_FUNCTION_NAME yuv420_bgra_std +#define YUV_FORMAT YUV_FORMAT_420 +#define RGB_FORMAT RGB_FORMAT_BGRA +#include "yuv_rgb_std_func.h" + +#define STD_FUNCTION_NAME yuv420_argb_std +#define YUV_FORMAT YUV_FORMAT_420 +#define RGB_FORMAT RGB_FORMAT_ARGB +#include "yuv_rgb_std_func.h" + +#define STD_FUNCTION_NAME yuv420_abgr_std +#define YUV_FORMAT YUV_FORMAT_420 +#define RGB_FORMAT RGB_FORMAT_ABGR +#include "yuv_rgb_std_func.h" + +#define STD_FUNCTION_NAME yuv422_rgb565_std +#define YUV_FORMAT YUV_FORMAT_422 +#define RGB_FORMAT RGB_FORMAT_RGB565 +#include "yuv_rgb_std_func.h" + +#define STD_FUNCTION_NAME yuv422_rgb24_std +#define YUV_FORMAT YUV_FORMAT_422 +#define RGB_FORMAT RGB_FORMAT_RGB24 +#include "yuv_rgb_std_func.h" + +#define STD_FUNCTION_NAME yuv422_rgba_std +#define YUV_FORMAT YUV_FORMAT_422 +#define RGB_FORMAT RGB_FORMAT_RGBA +#include "yuv_rgb_std_func.h" + +#define STD_FUNCTION_NAME yuv422_bgra_std +#define YUV_FORMAT YUV_FORMAT_422 +#define RGB_FORMAT RGB_FORMAT_BGRA +#include "yuv_rgb_std_func.h" + +#define STD_FUNCTION_NAME yuv422_argb_std +#define YUV_FORMAT YUV_FORMAT_422 +#define RGB_FORMAT RGB_FORMAT_ARGB +#include "yuv_rgb_std_func.h" + +#define STD_FUNCTION_NAME yuv422_abgr_std +#define YUV_FORMAT YUV_FORMAT_422 +#define RGB_FORMAT RGB_FORMAT_ABGR +#include "yuv_rgb_std_func.h" + +#define STD_FUNCTION_NAME yuvnv12_rgb565_std +#define YUV_FORMAT YUV_FORMAT_NV12 +#define RGB_FORMAT RGB_FORMAT_RGB565 +#include "yuv_rgb_std_func.h" + +#define STD_FUNCTION_NAME yuvnv12_rgb24_std +#define YUV_FORMAT YUV_FORMAT_NV12 +#define RGB_FORMAT RGB_FORMAT_RGB24 +#include "yuv_rgb_std_func.h" + +#define STD_FUNCTION_NAME yuvnv12_rgba_std +#define YUV_FORMAT YUV_FORMAT_NV12 +#define RGB_FORMAT RGB_FORMAT_RGBA +#include "yuv_rgb_std_func.h" + +#define STD_FUNCTION_NAME yuvnv12_bgra_std +#define YUV_FORMAT YUV_FORMAT_NV12 +#define RGB_FORMAT RGB_FORMAT_BGRA +#include "yuv_rgb_std_func.h" + +#define STD_FUNCTION_NAME yuvnv12_argb_std +#define YUV_FORMAT YUV_FORMAT_NV12 +#define RGB_FORMAT RGB_FORMAT_ARGB +#include "yuv_rgb_std_func.h" + +#define STD_FUNCTION_NAME yuvnv12_abgr_std +#define YUV_FORMAT YUV_FORMAT_NV12 +#define RGB_FORMAT RGB_FORMAT_ABGR +#include "yuv_rgb_std_func.h" + +void rgb24_yuv420_std( + uint32_t width, uint32_t height, + const uint8_t *RGB, uint32_t RGB_stride, + uint8_t *Y, uint8_t *U, uint8_t *V, uint32_t Y_stride, uint32_t UV_stride, + YCbCrType yuv_type) +{ + const RGB2YUVParam *const param = &(RGB2YUV[yuv_type]); + + uint32_t x, y; + for(y=0; y<(height-1); y+=2) + { + const uint8_t *rgb_ptr1=RGB+y*RGB_stride, + *rgb_ptr2=RGB+(y+1)*RGB_stride; + + uint8_t *y_ptr1=Y+y*Y_stride, + *y_ptr2=Y+(y+1)*Y_stride, + *u_ptr=U+(y/2)*UV_stride, + *v_ptr=V+(y/2)*UV_stride; + + for(x=0; x<(width-1); x+=2) + { + // compute yuv for the four pixels, u and v values are summed + int32_t y_tmp, u_tmp, v_tmp; + + y_tmp = param->matrix[0][0]*rgb_ptr1[0] + param->matrix[0][1]*rgb_ptr1[1] + param->matrix[0][2]*rgb_ptr1[2]; + u_tmp = param->matrix[1][0]*rgb_ptr1[0] + param->matrix[1][1]*rgb_ptr1[1] + param->matrix[1][2]*rgb_ptr1[2]; + v_tmp = param->matrix[2][0]*rgb_ptr1[0] + param->matrix[2][1]*rgb_ptr1[1] + param->matrix[2][2]*rgb_ptr1[2]; + y_ptr1[0]=clampU8(y_tmp+((param->y_shift)<matrix[0][0]*rgb_ptr1[3] + param->matrix[0][1]*rgb_ptr1[4] + param->matrix[0][2]*rgb_ptr1[5]; + u_tmp += param->matrix[1][0]*rgb_ptr1[3] + param->matrix[1][1]*rgb_ptr1[4] + param->matrix[1][2]*rgb_ptr1[5]; + v_tmp += param->matrix[2][0]*rgb_ptr1[3] + param->matrix[2][1]*rgb_ptr1[4] + param->matrix[2][2]*rgb_ptr1[5]; + y_ptr1[1]=clampU8(y_tmp+((param->y_shift)<matrix[0][0]*rgb_ptr2[0] + param->matrix[0][1]*rgb_ptr2[1] + param->matrix[0][2]*rgb_ptr2[2]; + u_tmp += param->matrix[1][0]*rgb_ptr2[0] + param->matrix[1][1]*rgb_ptr2[1] + param->matrix[1][2]*rgb_ptr2[2]; + v_tmp += param->matrix[2][0]*rgb_ptr2[0] + param->matrix[2][1]*rgb_ptr2[1] + param->matrix[2][2]*rgb_ptr2[2]; + y_ptr2[0]=clampU8(y_tmp+((param->y_shift)<matrix[0][0]*rgb_ptr2[3] + param->matrix[0][1]*rgb_ptr2[4] + param->matrix[0][2]*rgb_ptr2[5]; + u_tmp += param->matrix[1][0]*rgb_ptr2[3] + param->matrix[1][1]*rgb_ptr2[4] + param->matrix[1][2]*rgb_ptr2[5]; + v_tmp += param->matrix[2][0]*rgb_ptr2[3] + param->matrix[2][1]*rgb_ptr2[4] + param->matrix[2][2]*rgb_ptr2[5]; + y_ptr2[1]=clampU8(y_tmp+((param->y_shift)<*/ +#include "yuv_rgb_common.h" + +#include "SDL_stdinc.h" + +// yuv to rgb, standard c implementation +void yuv420_rgb565_std( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv420_rgb24_std( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv420_rgba_std( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv420_bgra_std( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv420_argb_std( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv420_abgr_std( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv422_rgb565_std( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv422_rgb24_std( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv422_rgba_std( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv422_bgra_std( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv422_argb_std( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuv422_abgr_std( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuvnv12_rgb565_std( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuvnv12_rgb24_std( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuvnv12_rgba_std( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuvnv12_bgra_std( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuvnv12_argb_std( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); + +void yuvnv12_abgr_std( + uint32_t width, uint32_t height, + const uint8_t *y, const uint8_t *u, const uint8_t *v, uint32_t y_stride, uint32_t uv_stride, + uint8_t *rgb, uint32_t rgb_stride, + YCbCrType yuv_type); diff --git a/SDL2-2.0.12/src/video/yuv2rgb/yuv_rgb_std_func.h b/SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb_std_func.h similarity index 92% rename from SDL2-2.0.12/src/video/yuv2rgb/yuv_rgb_std_func.h rename to SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb_std_func.h index f0ab5c6..f359aba 100644 --- a/SDL2-2.0.12/src/video/yuv2rgb/yuv_rgb_std_func.h +++ b/SDL2-2.30.5/src/video/yuv2rgb/yuv_rgb_std_func.h @@ -69,10 +69,15 @@ #endif +#ifdef _MSC_VER /* Visual Studio analyzer can't tell that we're building this with different constants */ +#pragma warning(push) +#pragma warning(disable : 6239) +#endif + void STD_FUNCTION_NAME( - uint32_t width, uint32_t height, - const uint8_t *Y, const uint8_t *U, const uint8_t *V, uint32_t Y_stride, uint32_t UV_stride, - uint8_t *RGB, uint32_t RGB_stride, + uint32_t width, uint32_t height, + const uint8_t *Y, const uint8_t *U, const uint8_t *V, uint32_t Y_stride, uint32_t UV_stride, + uint8_t *RGB, uint32_t RGB_stride, YCbCrType yuv_type) { const YUV2RGBParam *const param = &(YUV2RGB[yuv_type]); @@ -97,10 +102,13 @@ void STD_FUNCTION_NAME( for(y=0; y<(height-(uv_y_sample_interval-1)); y+=uv_y_sample_interval) { const uint8_t *y_ptr1=Y+y*Y_stride, - *y_ptr2=Y+(y+1)*Y_stride, *u_ptr=U+(y/uv_y_sample_interval)*UV_stride, *v_ptr=V+(y/uv_y_sample_interval)*UV_stride; - + + #if uv_y_sample_interval > 1 + const uint8_t *y_ptr2=Y+(y+1)*Y_stride; + #endif + uint8_t *rgb_ptr1=RGB+y*RGB_stride; #if uv_y_sample_interval > 1 @@ -110,32 +118,34 @@ void STD_FUNCTION_NAME( for(x=0; x<(width-(uv_x_sample_interval-1)); x+=uv_x_sample_interval) { // Compute U and V contributions, common to the four pixels - + int32_t u_tmp = ((*u_ptr)-128); int32_t v_tmp = ((*v_ptr)-128); - + int32_t r_tmp = (v_tmp*param->v_r_factor); int32_t g_tmp = (u_tmp*param->u_g_factor + v_tmp*param->v_g_factor); int32_t b_tmp = (u_tmp*param->u_b_factor); - + // Compute the Y contribution for each pixel - + int32_t y_tmp = ((y_ptr1[0]-param->y_shift)*param->y_factor); PACK_PIXEL(rgb_ptr1); - + y_tmp = ((y_ptr1[y_pixel_stride]-param->y_shift)*param->y_factor); PACK_PIXEL(rgb_ptr1); - + #if uv_y_sample_interval > 1 y_tmp = ((y_ptr2[0]-param->y_shift)*param->y_factor); PACK_PIXEL(rgb_ptr2); - + y_tmp = ((y_ptr2[y_pixel_stride]-param->y_shift)*param->y_factor); PACK_PIXEL(rgb_ptr2); #endif y_ptr1+=2*y_pixel_stride; + #if uv_y_sample_interval > 1 y_ptr2+=2*y_pixel_stride; + #endif u_ptr+=2*uv_pixel_stride/uv_x_sample_interval; v_ptr+=2*uv_pixel_stride/uv_x_sample_interval; } @@ -144,19 +154,19 @@ void STD_FUNCTION_NAME( if (uv_x_sample_interval == 2 && x == (width-1)) { // Compute U and V contributions, common to the four pixels - + int32_t u_tmp = ((*u_ptr)-128); int32_t v_tmp = ((*v_ptr)-128); - + int32_t r_tmp = (v_tmp*param->v_r_factor); int32_t g_tmp = (u_tmp*param->u_g_factor + v_tmp*param->v_g_factor); int32_t b_tmp = (u_tmp*param->u_b_factor); - + // Compute the Y contribution for each pixel - + int32_t y_tmp = ((y_ptr1[0]-param->y_shift)*param->y_factor); PACK_PIXEL(rgb_ptr1); - + #if uv_y_sample_interval > 1 y_tmp = ((y_ptr2[0]-param->y_shift)*param->y_factor); PACK_PIXEL(rgb_ptr2); @@ -170,28 +180,28 @@ void STD_FUNCTION_NAME( const uint8_t *y_ptr1=Y+y*Y_stride, *u_ptr=U+(y/uv_y_sample_interval)*UV_stride, *v_ptr=V+(y/uv_y_sample_interval)*UV_stride; - + uint8_t *rgb_ptr1=RGB+y*RGB_stride; - + for(x=0; x<(width-(uv_x_sample_interval-1)); x+=uv_x_sample_interval) { // Compute U and V contributions, common to the four pixels - + int32_t u_tmp = ((*u_ptr)-128); int32_t v_tmp = ((*v_ptr)-128); - + int32_t r_tmp = (v_tmp*param->v_r_factor); int32_t g_tmp = (u_tmp*param->u_g_factor + v_tmp*param->v_g_factor); int32_t b_tmp = (u_tmp*param->u_b_factor); - + // Compute the Y contribution for each pixel - + int32_t y_tmp = ((y_ptr1[0]-param->y_shift)*param->y_factor); PACK_PIXEL(rgb_ptr1); - + y_tmp = ((y_ptr1[y_pixel_stride]-param->y_shift)*param->y_factor); PACK_PIXEL(rgb_ptr1); - + y_ptr1+=2*y_pixel_stride; u_ptr+=2*uv_pixel_stride/uv_x_sample_interval; v_ptr+=2*uv_pixel_stride/uv_x_sample_interval; @@ -201,16 +211,16 @@ void STD_FUNCTION_NAME( if (uv_x_sample_interval == 2 && x == (width-1)) { // Compute U and V contributions, common to the four pixels - + int32_t u_tmp = ((*u_ptr)-128); int32_t v_tmp = ((*v_ptr)-128); - + int32_t r_tmp = (v_tmp*param->v_r_factor); int32_t g_tmp = (u_tmp*param->u_g_factor + v_tmp*param->v_g_factor); int32_t b_tmp = (u_tmp*param->u_b_factor); - + // Compute the Y contribution for each pixel - + int32_t y_tmp = ((y_ptr1[0]-param->y_shift)*param->y_factor); PACK_PIXEL(rgb_ptr1); } @@ -222,6 +232,10 @@ void STD_FUNCTION_NAME( #undef uv_y_sample_interval } +#ifdef _MSC_VER +#pragma warning(pop) +#endif + #undef STD_FUNCTION_NAME #undef YUV_FORMAT #undef RGB_FORMAT diff --git a/SDL2-2.30.5/wayland-protocols/fractional-scale-v1.xml b/SDL2-2.30.5/wayland-protocols/fractional-scale-v1.xml new file mode 100644 index 0000000..350bfc0 --- /dev/null +++ b/SDL2-2.30.5/wayland-protocols/fractional-scale-v1.xml @@ -0,0 +1,102 @@ + + + + Copyright © 2022 Kenny Levinsen + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice (including the next + paragraph) shall be included in all copies or substantial portions of the + Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + + + This protocol allows a compositor to suggest for surfaces to render at + fractional scales. + + A client can submit scaled content by utilizing wp_viewport. This is done by + creating a wp_viewport object for the surface and setting the destination + rectangle to the surface size before the scale factor is applied. + + The buffer size is calculated by multiplying the surface size by the + intended scale. + + The wl_surface buffer scale should remain set to 1. + + If a surface has a surface-local size of 100 px by 50 px and wishes to + submit buffers with a scale of 1.5, then a buffer of 150px by 75 px should + be used and the wp_viewport destination rectangle should be 100 px by 50 px. + + For toplevel surfaces, the size is rounded halfway away from zero. The + rounding algorithm for subsurface position and size is not defined. + + + + + A global interface for requesting surfaces to use fractional scales. + + + + + Informs the server that the client will not be using this protocol + object anymore. This does not affect any other objects, + wp_fractional_scale_v1 objects included. + + + + + + + + + + Create an add-on object for the the wl_surface to let the compositor + request fractional scales. If the given wl_surface already has a + wp_fractional_scale_v1 object associated, the fractional_scale_exists + protocol error is raised. + + + + + + + + + An additional interface to a wl_surface object which allows the compositor + to inform the client of the preferred scale. + + + + + Destroy the fractional scale object. When this object is destroyed, + preferred_scale events will no longer be sent. + + + + + + Notification of a new preferred scale for this surface that the + compositor suggests that the client should use. + + The sent scale is the numerator of a fraction with a denominator of 120. + + + + + diff --git a/SDL2-2.30.5/wayland-protocols/idle-inhibit-unstable-v1.xml b/SDL2-2.30.5/wayland-protocols/idle-inhibit-unstable-v1.xml new file mode 100644 index 0000000..9c06cdc --- /dev/null +++ b/SDL2-2.30.5/wayland-protocols/idle-inhibit-unstable-v1.xml @@ -0,0 +1,83 @@ + + + + + Copyright © 2015 Samsung Electronics Co., Ltd + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice (including the next + paragraph) shall be included in all copies or substantial portions of the + Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + + + + This interface permits inhibiting the idle behavior such as screen + blanking, locking, and screensaving. The client binds the idle manager + globally, then creates idle-inhibitor objects for each surface. + + Warning! The protocol described in this file is experimental and + backward incompatible changes may be made. Backward compatible changes + may be added together with the corresponding interface version bump. + Backward incompatible changes are done by bumping the version number in + the protocol and interface names and resetting the interface version. + Once the protocol is to be declared stable, the 'z' prefix and the + version number in the protocol and interface names are removed and the + interface version number is reset. + + + + + Destroy the inhibit manager. + + + + + + Create a new inhibitor object associated with the given surface. + + + + + + + + + + An idle inhibitor prevents the output that the associated surface is + visible on from being set to a state where it is not visually usable due + to lack of user interaction (e.g. blanked, dimmed, locked, set to power + save, etc.) Any screensaver processes are also blocked from displaying. + + If the surface is destroyed, unmapped, becomes occluded, loses + visibility, or otherwise becomes not visually relevant for the user, the + idle inhibitor will not be honored by the compositor; if the surface + subsequently regains visibility the inhibitor takes effect once again. + Likewise, the inhibitor isn't honored if the system was already idled at + the time the inhibitor was established, although if the system later + de-idles and re-idles the inhibitor will take effect. + + + + + Remove the inhibitor effect from the associated wl_surface. + + + + + diff --git a/SDL2-2.30.5/wayland-protocols/keyboard-shortcuts-inhibit-unstable-v1.xml b/SDL2-2.30.5/wayland-protocols/keyboard-shortcuts-inhibit-unstable-v1.xml new file mode 100644 index 0000000..2774876 --- /dev/null +++ b/SDL2-2.30.5/wayland-protocols/keyboard-shortcuts-inhibit-unstable-v1.xml @@ -0,0 +1,143 @@ + + + + + Copyright © 2017 Red Hat Inc. + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice (including the next + paragraph) shall be included in all copies or substantial portions of the + Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + + + This protocol specifies a way for a client to request the compositor + to ignore its own keyboard shortcuts for a given seat, so that all + key events from that seat get forwarded to a surface. + + Warning! The protocol described in this file is experimental and + backward incompatible changes may be made. Backward compatible + changes may be added together with the corresponding interface + version bump. + Backward incompatible changes are done by bumping the version + number in the protocol and interface names and resetting the + interface version. Once the protocol is to be declared stable, + the 'z' prefix and the version number in the protocol and + interface names are removed and the interface version number is + reset. + + + + + A global interface used for inhibiting the compositor keyboard shortcuts. + + + + + Destroy the keyboard shortcuts inhibitor manager. + + + + + + Create a new keyboard shortcuts inhibitor object associated with + the given surface for the given seat. + + If shortcuts are already inhibited for the specified seat and surface, + a protocol error "already_inhibited" is raised by the compositor. + + + + + + + + + + + + + + A keyboard shortcuts inhibitor instructs the compositor to ignore + its own keyboard shortcuts when the associated surface has keyboard + focus. As a result, when the surface has keyboard focus on the given + seat, it will receive all key events originating from the specified + seat, even those which would normally be caught by the compositor for + its own shortcuts. + + The Wayland compositor is however under no obligation to disable + all of its shortcuts, and may keep some special key combo for its own + use, including but not limited to one allowing the user to forcibly + restore normal keyboard events routing in the case of an unwilling + client. The compositor may also use the same key combo to reactivate + an existing shortcut inhibitor that was previously deactivated on + user request. + + When the compositor restores its own keyboard shortcuts, an + "inactive" event is emitted to notify the client that the keyboard + shortcuts inhibitor is not effectively active for the surface and + seat any more, and the client should not expect to receive all + keyboard events. + + When the keyboard shortcuts inhibitor is inactive, the client has + no way to forcibly reactivate the keyboard shortcuts inhibitor. + + The user can chose to re-enable a previously deactivated keyboard + shortcuts inhibitor using any mechanism the compositor may offer, + in which case the compositor will send an "active" event to notify + the client. + + If the surface is destroyed, unmapped, or loses the seat's keyboard + focus, the keyboard shortcuts inhibitor becomes irrelevant and the + compositor will restore its own keyboard shortcuts but no "inactive" + event is emitted in this case. + + + + + Remove the keyboard shortcuts inhibitor from the associated wl_surface. + + + + + + This event indicates that the shortcut inhibitor is active. + + The compositor sends this event every time compositor shortcuts + are inhibited on behalf of the surface. When active, the client + may receive input events normally reserved by the compositor + (see zwp_keyboard_shortcuts_inhibitor_v1). + + This occurs typically when the initial request "inhibit_shortcuts" + first becomes active or when the user instructs the compositor to + re-enable and existing shortcuts inhibitor using any mechanism + offered by the compositor. + + + + + + This event indicates that the shortcuts inhibitor is inactive, + normal shortcuts processing is restored by the compositor. + + + + diff --git a/SDL2-2.0.12/wayland-protocols/pointer-constraints-unstable-v1.xml b/SDL2-2.30.5/wayland-protocols/pointer-constraints-unstable-v1.xml similarity index 100% rename from SDL2-2.0.12/wayland-protocols/pointer-constraints-unstable-v1.xml rename to SDL2-2.30.5/wayland-protocols/pointer-constraints-unstable-v1.xml diff --git a/SDL2-2.30.5/wayland-protocols/primary-selection-unstable-v1.xml b/SDL2-2.30.5/wayland-protocols/primary-selection-unstable-v1.xml new file mode 100644 index 0000000..e5a39e3 --- /dev/null +++ b/SDL2-2.30.5/wayland-protocols/primary-selection-unstable-v1.xml @@ -0,0 +1,225 @@ + + + + Copyright © 2015, 2016 Red Hat + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice (including the next + paragraph) shall be included in all copies or substantial portions of the + Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + + + This protocol provides the ability to have a primary selection device to + match that of the X server. This primary selection is a shortcut to the + common clipboard selection, where text just needs to be selected in order + to allow copying it elsewhere. The de facto way to perform this action + is the middle mouse button, although it is not limited to this one. + + Clients wishing to honor primary selection should create a primary + selection source and set it as the selection through + wp_primary_selection_device.set_selection whenever the text selection + changes. In order to minimize calls in pointer-driven text selection, + it should happen only once after the operation finished. Similarly, + a NULL source should be set when text is unselected. + + wp_primary_selection_offer objects are first announced through the + wp_primary_selection_device.data_offer event. Immediately after this event, + the primary data offer will emit wp_primary_selection_offer.offer events + to let know of the mime types being offered. + + When the primary selection changes, the client with the keyboard focus + will receive wp_primary_selection_device.selection events. Only the client + with the keyboard focus will receive such events with a non-NULL + wp_primary_selection_offer. Across keyboard focus changes, previously + focused clients will receive wp_primary_selection_device.events with a + NULL wp_primary_selection_offer. + + In order to request the primary selection data, the client must pass + a recent serial pertaining to the press event that is triggering the + operation, if the compositor deems the serial valid and recent, the + wp_primary_selection_source.send event will happen in the other end + to let the transfer begin. The client owning the primary selection + should write the requested data, and close the file descriptor + immediately. + + If the primary selection owner client disappeared during the transfer, + the client reading the data will receive a + wp_primary_selection_device.selection event with a NULL + wp_primary_selection_offer, the client should take this as a hint + to finish the reads related to the no longer existing offer. + + The primary selection owner should be checking for errors during + writes, merely cancelling the ongoing transfer if any happened. + + + + + The primary selection device manager is a singleton global object that + provides access to the primary selection. It allows to create + wp_primary_selection_source objects, as well as retrieving the per-seat + wp_primary_selection_device objects. + + + + + Create a new primary selection source. + + + + + + + Create a new data device for a given seat. + + + + + + + + Destroy the primary selection device manager. + + + + + + + + Replaces the current selection. The previous owner of the primary + selection will receive a wp_primary_selection_source.cancelled event. + + To unset the selection, set the source to NULL. + + + + + + + + Introduces a new wp_primary_selection_offer object that may be used + to receive the current primary selection. Immediately following this + event, the new wp_primary_selection_offer object will send + wp_primary_selection_offer.offer events to describe the offered mime + types. + + + + + + + The wp_primary_selection_device.selection event is sent to notify the + client of a new primary selection. This event is sent after the + wp_primary_selection.data_offer event introducing this object, and after + the offer has announced its mimetypes through + wp_primary_selection_offer.offer. + + The data_offer is valid until a new offer or NULL is received + or until the client loses keyboard focus. The client must destroy the + previous selection data_offer, if any, upon receiving this event. + + + + + + + Destroy the primary selection device. + + + + + + + A wp_primary_selection_offer represents an offer to transfer the contents + of the primary selection clipboard to the client. Similar to + wl_data_offer, the offer also describes the mime types that the data can + be converted to and provides the mechanisms for transferring the data + directly to the client. + + + + + To transfer the contents of the primary selection clipboard, the client + issues this request and indicates the mime type that it wants to + receive. The transfer happens through the passed file descriptor + (typically created with the pipe system call). The source client writes + the data in the mime type representation requested and then closes the + file descriptor. + + The receiving client reads from the read end of the pipe until EOF and + closes its end, at which point the transfer is complete. + + + + + + + + Destroy the primary selection offer. + + + + + + Sent immediately after creating announcing the + wp_primary_selection_offer through + wp_primary_selection_device.data_offer. One event is sent per offered + mime type. + + + + + + + + The source side of a wp_primary_selection_offer, it provides a way to + describe the offered data and respond to requests to transfer the + requested contents of the primary selection clipboard. + + + + + This request adds a mime type to the set of mime types advertised to + targets. Can be called several times to offer multiple types. + + + + + + + Destroy the primary selection source. + + + + + + Request for the current primary selection contents from the client. + Send the specified mime type over the passed file descriptor, then + close it. + + + + + + + + This primary selection source is no longer valid. The client should + clean up and destroy this primary selection source. + + + + diff --git a/SDL2-2.0.12/wayland-protocols/relative-pointer-unstable-v1.xml b/SDL2-2.30.5/wayland-protocols/relative-pointer-unstable-v1.xml similarity index 100% rename from SDL2-2.0.12/wayland-protocols/relative-pointer-unstable-v1.xml rename to SDL2-2.30.5/wayland-protocols/relative-pointer-unstable-v1.xml diff --git a/SDL2-2.30.5/wayland-protocols/tablet-unstable-v2.xml b/SDL2-2.30.5/wayland-protocols/tablet-unstable-v2.xml new file mode 100644 index 0000000..b286d96 --- /dev/null +++ b/SDL2-2.30.5/wayland-protocols/tablet-unstable-v2.xml @@ -0,0 +1,1178 @@ + + + + + Copyright 2014 © Stephen "Lyude" Chandler Paul + Copyright 2015-2016 © Red Hat, Inc. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice (including the + next paragraph) shall be included in all copies or substantial + portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + + + This description provides a high-level overview of the interplay between + the interfaces defined this protocol. For details, see the protocol + specification. + + More than one tablet may exist, and device-specifics matter. Tablets are + not represented by a single virtual device like wl_pointer. A client + binds to the tablet manager object which is just a proxy object. From + that, the client requests wp_tablet_manager.get_tablet_seat(wl_seat) + and that returns the actual interface that has all the tablets. With + this indirection, we can avoid merging wp_tablet into the actual Wayland + protocol, a long-term benefit. + + The wp_tablet_seat sends a "tablet added" event for each tablet + connected. That event is followed by descriptive events about the + hardware; currently that includes events for name, vid/pid and + a wp_tablet.path event that describes a local path. This path can be + used to uniquely identify a tablet or get more information through + libwacom. Emulated or nested tablets can skip any of those, e.g. a + virtual tablet may not have a vid/pid. The sequence of descriptive + events is terminated by a wp_tablet.done event to signal that a client + may now finalize any initialization for that tablet. + + Events from tablets require a tool in proximity. Tools are also managed + by the tablet seat; a "tool added" event is sent whenever a tool is new + to the compositor. That event is followed by a number of descriptive + events about the hardware; currently that includes capabilities, + hardware id and serial number, and tool type. Similar to the tablet + interface, a wp_tablet_tool.done event is sent to terminate that initial + sequence. + + Any event from a tool happens on the wp_tablet_tool interface. When the + tool gets into proximity of the tablet, a proximity_in event is sent on + the wp_tablet_tool interface, listing the tablet and the surface. That + event is followed by a motion event with the coordinates. After that, + it's the usual motion, axis, button, etc. events. The protocol's + serialisation means events are grouped by wp_tablet_tool.frame events. + + Two special events (that don't exist in X) are down and up. They signal + "tip touching the surface". For tablets without real proximity + detection, the sequence is: proximity_in, motion, down, frame. + + When the tool leaves proximity, a proximity_out event is sent. If any + button is still down, a button release event is sent before this + proximity event. These button events are sent in the same frame as the + proximity event to signal to the client that the buttons were held when + the tool left proximity. + + If the tool moves out of the surface but stays in proximity (i.e. + between windows), compositor-specific grab policies apply. This usually + means that the proximity-out is delayed until all buttons are released. + + Moving a tool physically from one tablet to the other has no real effect + on the protocol, since we already have the tool object from the "tool + added" event. All the information is already there and the proximity + events on both tablets are all a client needs to reconstruct what + happened. + + Some extra axes are normalized, i.e. the client knows the range as + specified in the protocol (e.g. [0, 65535]), the granularity however is + unknown. The current normalized axes are pressure, distance, and slider. + + Other extra axes are in physical units as specified in the protocol. + The current extra axes with physical units are tilt, rotation and + wheel rotation. + + Since tablets work independently of the pointer controlled by the mouse, + the focus handling is independent too and controlled by proximity. + The wp_tablet_tool.set_cursor request sets a tool-specific cursor. + This cursor surface may be the same as the mouse cursor, and it may be + the same across tools but it is possible to be more fine-grained. For + example, a client may set different cursors for the pen and eraser. + + Tools are generally independent of tablets and it is + compositor-specific policy when a tool can be removed. Common approaches + will likely include some form of removing a tool when all tablets the + tool was used on are removed. + + Warning! The protocol described in this file is experimental and + backward incompatible changes may be made. Backward compatible changes + may be added together with the corresponding interface version bump. + Backward incompatible changes are done by bumping the version number in + the protocol and interface names and resetting the interface version. + Once the protocol is to be declared stable, the 'z' prefix and the + version number in the protocol and interface names are removed and the + interface version number is reset. + + + + + An object that provides access to the graphics tablets available on this + system. All tablets are associated with a seat, to get access to the + actual tablets, use wp_tablet_manager.get_tablet_seat. + + + + + Get the wp_tablet_seat object for the given seat. This object + provides access to all graphics tablets in this seat. + + + + + + + + Destroy the wp_tablet_manager object. Objects created from this + object are unaffected and should be destroyed separately. + + + + + + + An object that provides access to the graphics tablets available on this + seat. After binding to this interface, the compositor sends a set of + wp_tablet_seat.tablet_added and wp_tablet_seat.tool_added events. + + + + + Destroy the wp_tablet_seat object. Objects created from this + object are unaffected and should be destroyed separately. + + + + + + This event is sent whenever a new tablet becomes available on this + seat. This event only provides the object id of the tablet, any + static information about the tablet (device name, vid/pid, etc.) is + sent through the wp_tablet interface. + + + + + + + This event is sent whenever a tool that has not previously been used + with a tablet comes into use. This event only provides the object id + of the tool; any static information about the tool (capabilities, + type, etc.) is sent through the wp_tablet_tool interface. + + + + + + + This event is sent whenever a new pad is known to the system. Typically, + pads are physically attached to tablets and a pad_added event is + sent immediately after the wp_tablet_seat.tablet_added. + However, some standalone pad devices logically attach to tablets at + runtime, and the client must wait for wp_tablet_pad.enter to know + the tablet a pad is attached to. + + This event only provides the object id of the pad. All further + features (buttons, strips, rings) are sent through the wp_tablet_pad + interface. + + + + + + + + An object that represents a physical tool that has been, or is + currently in use with a tablet in this seat. Each wp_tablet_tool + object stays valid until the client destroys it; the compositor + reuses the wp_tablet_tool object to indicate that the object's + respective physical tool has come into proximity of a tablet again. + + A wp_tablet_tool object's relation to a physical tool depends on the + tablet's ability to report serial numbers. If the tablet supports + this capability, then the object represents a specific physical tool + and can be identified even when used on multiple tablets. + + A tablet tool has a number of static characteristics, e.g. tool type, + hardware_serial and capabilities. These capabilities are sent in an + event sequence after the wp_tablet_seat.tool_added event before any + actual events from this tool. This initial event sequence is + terminated by a wp_tablet_tool.done event. + + Tablet tool events are grouped by wp_tablet_tool.frame events. + Any events received before a wp_tablet_tool.frame event should be + considered part of the same hardware state change. + + + + + Sets the surface of the cursor used for this tool on the given + tablet. This request only takes effect if the tool is in proximity + of one of the requesting client's surfaces or the surface parameter + is the current pointer surface. If there was a previous surface set + with this request it is replaced. If surface is NULL, the cursor + image is hidden. + + The parameters hotspot_x and hotspot_y define the position of the + pointer surface relative to the pointer location. Its top-left corner + is always at (x, y) - (hotspot_x, hotspot_y), where (x, y) are the + coordinates of the pointer location, in surface-local coordinates. + + On surface.attach requests to the pointer surface, hotspot_x and + hotspot_y are decremented by the x and y parameters passed to the + request. Attach must be confirmed by wl_surface.commit as usual. + + The hotspot can also be updated by passing the currently set pointer + surface to this request with new values for hotspot_x and hotspot_y. + + The current and pending input regions of the wl_surface are cleared, + and wl_surface.set_input_region is ignored until the wl_surface is no + longer used as the cursor. When the use as a cursor ends, the current + and pending input regions become undefined, and the wl_surface is + unmapped. + + This request gives the surface the role of a wp_tablet_tool cursor. A + surface may only ever be used as the cursor surface for one + wp_tablet_tool. If the surface already has another role or has + previously been used as cursor surface for a different tool, a + protocol error is raised. + + + + + + + + + + This destroys the client's resource for this tool object. + + + + + + Describes the physical type of a tool. The physical type of a tool + generally defines its base usage. + + The mouse tool represents a mouse-shaped tool that is not a relative + device but bound to the tablet's surface, providing absolute + coordinates. + + The lens tool is a mouse-shaped tool with an attached lens to + provide precision focus. + + + + + + + + + + + + + + The tool type is the high-level type of the tool and usually decides + the interaction expected from this tool. + + This event is sent in the initial burst of events before the + wp_tablet_tool.done event. + + + + + + + If the physical tool can be identified by a unique 64-bit serial + number, this event notifies the client of this serial number. + + If multiple tablets are available in the same seat and the tool is + uniquely identifiable by the serial number, that tool may move + between tablets. + + Otherwise, if the tool has no serial number and this event is + missing, the tool is tied to the tablet it first comes into + proximity with. Even if the physical tool is used on multiple + tablets, separate wp_tablet_tool objects will be created, one per + tablet. + + This event is sent in the initial burst of events before the + wp_tablet_tool.done event. + + + + + + + + This event notifies the client of a hardware id available on this tool. + + The hardware id is a device-specific 64-bit id that provides extra + information about the tool in use, beyond the wl_tool.type + enumeration. The format of the id is specific to tablets made by + Wacom Inc. For example, the hardware id of a Wacom Grip + Pen (a stylus) is 0x802. + + This event is sent in the initial burst of events before the + wp_tablet_tool.done event. + + + + + + + + Describes extra capabilities on a tablet. + + Any tool must provide x and y values, extra axes are + device-specific. + + + + + + + + + + + + This event notifies the client of any capabilities of this tool, + beyond the main set of x/y axes and tip up/down detection. + + One event is sent for each extra capability available on this tool. + + This event is sent in the initial burst of events before the + wp_tablet_tool.done event. + + + + + + + This event signals the end of the initial burst of descriptive + events. A client may consider the static description of the tool to + be complete and finalize initialization of the tool. + + + + + + This event is sent when the tool is removed from the system and will + send no further events. Should the physical tool come back into + proximity later, a new wp_tablet_tool object will be created. + + It is compositor-dependent when a tool is removed. A compositor may + remove a tool on proximity out, tablet removal or any other reason. + A compositor may also keep a tool alive until shutdown. + + If the tool is currently in proximity, a proximity_out event will be + sent before the removed event. See wp_tablet_tool.proximity_out for + the handling of any buttons logically down. + + When this event is received, the client must wp_tablet_tool.destroy + the object. + + + + + + Notification that this tool is focused on a certain surface. + + This event can be received when the tool has moved from one surface to + another, or when the tool has come back into proximity above the + surface. + + If any button is logically down when the tool comes into proximity, + the respective button event is sent after the proximity_in event but + within the same frame as the proximity_in event. + + + + + + + + + Notification that this tool has either left proximity, or is no + longer focused on a certain surface. + + When the tablet tool leaves proximity of the tablet, button release + events are sent for each button that was held down at the time of + leaving proximity. These events are sent before the proximity_out + event but within the same wp_tablet.frame. + + If the tool stays within proximity of the tablet, but the focus + changes from one surface to another, a button release event may not + be sent until the button is actually released or the tool leaves the + proximity of the tablet. + + + + + + Sent whenever the tablet tool comes in contact with the surface of the + tablet. + + If the tool is already in contact with the tablet when entering the + input region, the client owning said region will receive a + wp_tablet.proximity_in event, followed by a wp_tablet.down + event and a wp_tablet.frame event. + + Note that this event describes logical contact, not physical + contact. On some devices, a compositor may not consider a tool in + logical contact until a minimum physical pressure threshold is + exceeded. + + + + + + + Sent whenever the tablet tool stops making contact with the surface of + the tablet, or when the tablet tool moves out of the input region + and the compositor grab (if any) is dismissed. + + If the tablet tool moves out of the input region while in contact + with the surface of the tablet and the compositor does not have an + ongoing grab on the surface, the client owning said region will + receive a wp_tablet.up event, followed by a wp_tablet.proximity_out + event and a wp_tablet.frame event. If the compositor has an ongoing + grab on this device, this event sequence is sent whenever the grab + is dismissed in the future. + + Note that this event describes logical contact, not physical + contact. On some devices, a compositor may not consider a tool out + of logical contact until physical pressure falls below a specific + threshold. + + + + + + Sent whenever a tablet tool moves. + + + + + + + + Sent whenever the pressure axis on a tool changes. The value of this + event is normalized to a value between 0 and 65535. + + Note that pressure may be nonzero even when a tool is not in logical + contact. See the down and up events for more details. + + + + + + + Sent whenever the distance axis on a tool changes. The value of this + event is normalized to a value between 0 and 65535. + + Note that distance may be nonzero even when a tool is not in logical + contact. See the down and up events for more details. + + + + + + + Sent whenever one or both of the tilt axes on a tool change. Each tilt + value is in degrees, relative to the z-axis of the tablet. + The angle is positive when the top of a tool tilts along the + positive x or y axis. + + + + + + + + Sent whenever the z-rotation axis on the tool changes. The + rotation value is in degrees clockwise from the tool's + logical neutral position. + + + + + + + Sent whenever the slider position on the tool changes. The + value is normalized between -65535 and 65535, with 0 as the logical + neutral position of the slider. + + The slider is available on e.g. the Wacom Airbrush tool. + + + + + + + Sent whenever the wheel on the tool emits an event. This event + contains two values for the same axis change. The degrees value is + in the same orientation as the wl_pointer.vertical_scroll axis. The + clicks value is in discrete logical clicks of the mouse wheel. This + value may be zero if the movement of the wheel was less + than one logical click. + + Clients should choose either value and avoid mixing degrees and + clicks. The compositor may accumulate values smaller than a logical + click and emulate click events when a certain threshold is met. + Thus, wl_tablet_tool.wheel events with non-zero clicks values may + have different degrees values. + + + + + + + + Describes the physical state of a button that produced the button event. + + + + + + + + Sent whenever a button on the tool is pressed or released. + + If a button is held down when the tool moves in or out of proximity, + button events are generated by the compositor. See + wp_tablet_tool.proximity_in and wp_tablet_tool.proximity_out for + details. + + + + + + + + + Marks the end of a series of axis and/or button updates from the + tablet. The Wayland protocol requires axis updates to be sent + sequentially, however all events within a frame should be considered + one hardware event. + + + + + + + + + + + + The wp_tablet interface represents one graphics tablet device. The + tablet interface itself does not generate events; all events are + generated by wp_tablet_tool objects when in proximity above a tablet. + + A tablet has a number of static characteristics, e.g. device name and + pid/vid. These capabilities are sent in an event sequence after the + wp_tablet_seat.tablet_added event. This initial event sequence is + terminated by a wp_tablet.done event. + + + + + This destroys the client's resource for this tablet object. + + + + + + This event is sent in the initial burst of events before the + wp_tablet.done event. + + + + + + + This event is sent in the initial burst of events before the + wp_tablet.done event. + + + + + + + + A system-specific device path that indicates which device is behind + this wp_tablet. This information may be used to gather additional + information about the device, e.g. through libwacom. + + A device may have more than one device path. If so, multiple + wp_tablet.path events are sent. A device may be emulated and not + have a device path, and in that case this event will not be sent. + + The format of the path is unspecified, it may be a device node, a + sysfs path, or some other identifier. It is up to the client to + identify the string provided. + + This event is sent in the initial burst of events before the + wp_tablet.done event. + + + + + + + This event is sent immediately to signal the end of the initial + burst of descriptive events. A client may consider the static + description of the tablet to be complete and finalize initialization + of the tablet. + + + + + + Sent when the tablet has been removed from the system. When a tablet + is removed, some tools may be removed. + + When this event is received, the client must wp_tablet.destroy + the object. + + + + + + + A circular interaction area, such as the touch ring on the Wacom Intuos + Pro series tablets. + + Events on a ring are logically grouped by the wl_tablet_pad_ring.frame + event. + + + + + Request that the compositor use the provided feedback string + associated with this ring. This request should be issued immediately + after a wp_tablet_pad_group.mode_switch event from the corresponding + group is received, or whenever the ring is mapped to a different + action. See wp_tablet_pad_group.mode_switch for more details. + + Clients are encouraged to provide context-aware descriptions for + the actions associated with the ring; compositors may use this + information to offer visual feedback about the button layout + (eg. on-screen displays). + + The provided string 'description' is a UTF-8 encoded string to be + associated with this ring, and is considered user-visible; general + internationalization rules apply. + + The serial argument will be that of the last + wp_tablet_pad_group.mode_switch event received for the group of this + ring. Requests providing other serials than the most recent one will be + ignored. + + + + + + + + This destroys the client's resource for this ring object. + + + + + + Describes the source types for ring events. This indicates to the + client how a ring event was physically generated; a client may + adjust the user interface accordingly. For example, events + from a "finger" source may trigger kinetic scrolling. + + + + + + + Source information for ring events. + + This event does not occur on its own. It is sent before a + wp_tablet_pad_ring.frame event and carries the source information + for all events within that frame. + + The source specifies how this event was generated. If the source is + wp_tablet_pad_ring.source.finger, a wp_tablet_pad_ring.stop event + will be sent when the user lifts the finger off the device. + + This event is optional. If the source is unknown for an interaction, + no event is sent. + + + + + + + Sent whenever the angle on a ring changes. + + The angle is provided in degrees clockwise from the logical + north of the ring in the pad's current rotation. + + + + + + + Stop notification for ring events. + + For some wp_tablet_pad_ring.source types, a wp_tablet_pad_ring.stop + event is sent to notify a client that the interaction with the ring + has terminated. This enables the client to implement kinetic scrolling. + See the wp_tablet_pad_ring.source documentation for information on + when this event may be generated. + + Any wp_tablet_pad_ring.angle events with the same source after this + event should be considered as the start of a new interaction. + + + + + + Indicates the end of a set of ring events that logically belong + together. A client is expected to accumulate the data in all events + within the frame before proceeding. + + All wp_tablet_pad_ring events before a wp_tablet_pad_ring.frame event belong + logically together. For example, on termination of a finger interaction + on a ring the compositor will send a wp_tablet_pad_ring.source event, + a wp_tablet_pad_ring.stop event and a wp_tablet_pad_ring.frame event. + + A wp_tablet_pad_ring.frame event is sent for every logical event + group, even if the group only contains a single wp_tablet_pad_ring + event. Specifically, a client may get a sequence: angle, frame, + angle, frame, etc. + + + + + + + + A linear interaction area, such as the strips found in Wacom Cintiq + models. + + Events on a strip are logically grouped by the wl_tablet_pad_strip.frame + event. + + + + + Requests the compositor to use the provided feedback string + associated with this strip. This request should be issued immediately + after a wp_tablet_pad_group.mode_switch event from the corresponding + group is received, or whenever the strip is mapped to a different + action. See wp_tablet_pad_group.mode_switch for more details. + + Clients are encouraged to provide context-aware descriptions for + the actions associated with the strip, and compositors may use this + information to offer visual feedback about the button layout + (eg. on-screen displays). + + The provided string 'description' is a UTF-8 encoded string to be + associated with this ring, and is considered user-visible; general + internationalization rules apply. + + The serial argument will be that of the last + wp_tablet_pad_group.mode_switch event received for the group of this + strip. Requests providing other serials than the most recent one will be + ignored. + + + + + + + + This destroys the client's resource for this strip object. + + + + + + Describes the source types for strip events. This indicates to the + client how a strip event was physically generated; a client may + adjust the user interface accordingly. For example, events + from a "finger" source may trigger kinetic scrolling. + + + + + + + Source information for strip events. + + This event does not occur on its own. It is sent before a + wp_tablet_pad_strip.frame event and carries the source information + for all events within that frame. + + The source specifies how this event was generated. If the source is + wp_tablet_pad_strip.source.finger, a wp_tablet_pad_strip.stop event + will be sent when the user lifts their finger off the device. + + This event is optional. If the source is unknown for an interaction, + no event is sent. + + + + + + + Sent whenever the position on a strip changes. + + The position is normalized to a range of [0, 65535], the 0-value + represents the top-most and/or left-most position of the strip in + the pad's current rotation. + + + + + + + Stop notification for strip events. + + For some wp_tablet_pad_strip.source types, a wp_tablet_pad_strip.stop + event is sent to notify a client that the interaction with the strip + has terminated. This enables the client to implement kinetic + scrolling. See the wp_tablet_pad_strip.source documentation for + information on when this event may be generated. + + Any wp_tablet_pad_strip.position events with the same source after this + event should be considered as the start of a new interaction. + + + + + + Indicates the end of a set of events that represent one logical + hardware strip event. A client is expected to accumulate the data + in all events within the frame before proceeding. + + All wp_tablet_pad_strip events before a wp_tablet_pad_strip.frame event belong + logically together. For example, on termination of a finger interaction + on a strip the compositor will send a wp_tablet_pad_strip.source event, + a wp_tablet_pad_strip.stop event and a wp_tablet_pad_strip.frame + event. + + A wp_tablet_pad_strip.frame event is sent for every logical event + group, even if the group only contains a single wp_tablet_pad_strip + event. Specifically, a client may get a sequence: position, frame, + position, frame, etc. + + + + + + + + A pad group describes a distinct (sub)set of buttons, rings and strips + present in the tablet. The criteria of this grouping is usually positional, + eg. if a tablet has buttons on the left and right side, 2 groups will be + presented. The physical arrangement of groups is undisclosed and may + change on the fly. + + Pad groups will announce their features during pad initialization. Between + the corresponding wp_tablet_pad.group event and wp_tablet_pad_group.done, the + pad group will announce the buttons, rings and strips contained in it, + plus the number of supported modes. + + Modes are a mechanism to allow multiple groups of actions for every element + in the pad group. The number of groups and available modes in each is + persistent across device plugs. The current mode is user-switchable, it + will be announced through the wp_tablet_pad_group.mode_switch event both + whenever it is switched, and after wp_tablet_pad.enter. + + The current mode logically applies to all elements in the pad group, + although it is at clients' discretion whether to actually perform different + actions, and/or issue the respective .set_feedback requests to notify the + compositor. See the wp_tablet_pad_group.mode_switch event for more details. + + + + + Destroy the wp_tablet_pad_group object. Objects created from this object + are unaffected and should be destroyed separately. + + + + + + Sent on wp_tablet_pad_group initialization to announce the available + buttons in the group. Button indices start at 0, a button may only be + in one group at a time. + + This event is first sent in the initial burst of events before the + wp_tablet_pad_group.done event. + + Some buttons are reserved by the compositor. These buttons may not be + assigned to any wp_tablet_pad_group. Compositors may broadcast this + event in the case of changes to the mapping of these reserved buttons. + If the compositor happens to reserve all buttons in a group, this event + will be sent with an empty array. + + + + + + + Sent on wp_tablet_pad_group initialization to announce available rings. + One event is sent for each ring available on this pad group. + + This event is sent in the initial burst of events before the + wp_tablet_pad_group.done event. + + + + + + + Sent on wp_tablet_pad initialization to announce available strips. + One event is sent for each strip available on this pad group. + + This event is sent in the initial burst of events before the + wp_tablet_pad_group.done event. + + + + + + + Sent on wp_tablet_pad_group initialization to announce that the pad + group may switch between modes. A client may use a mode to store a + specific configuration for buttons, rings and strips and use the + wl_tablet_pad_group.mode_switch event to toggle between these + configurations. Mode indices start at 0. + + Switching modes is compositor-dependent. See the + wp_tablet_pad_group.mode_switch event for more details. + + This event is sent in the initial burst of events before the + wp_tablet_pad_group.done event. This event is only sent when more than + more than one mode is available. + + + + + + + This event is sent immediately to signal the end of the initial + burst of descriptive events. A client may consider the static + description of the tablet to be complete and finalize initialization + of the tablet group. + + + + + + Notification that the mode was switched. + + A mode applies to all buttons, rings and strips in a group + simultaneously, but a client is not required to assign different actions + for each mode. For example, a client may have mode-specific button + mappings but map the ring to vertical scrolling in all modes. Mode + indices start at 0. + + Switching modes is compositor-dependent. The compositor may provide + visual cues to the client about the mode, e.g. by toggling LEDs on + the tablet device. Mode-switching may be software-controlled or + controlled by one or more physical buttons. For example, on a Wacom + Intuos Pro, the button inside the ring may be assigned to switch + between modes. + + The compositor will also send this event after wp_tablet_pad.enter on + each group in order to notify of the current mode. Groups that only + feature one mode will use mode=0 when emitting this event. + + If a button action in the new mode differs from the action in the + previous mode, the client should immediately issue a + wp_tablet_pad.set_feedback request for each changed button. + + If a ring or strip action in the new mode differs from the action + in the previous mode, the client should immediately issue a + wp_tablet_ring.set_feedback or wp_tablet_strip.set_feedback request + for each changed ring or strip. + + + + + + + + + + A pad device is a set of buttons, rings and strips + usually physically present on the tablet device itself. Some + exceptions exist where the pad device is physically detached, e.g. the + Wacom ExpressKey Remote. + + Pad devices have no axes that control the cursor and are generally + auxiliary devices to the tool devices used on the tablet surface. + + A pad device has a number of static characteristics, e.g. the number + of rings. These capabilities are sent in an event sequence after the + wp_tablet_seat.pad_added event before any actual events from this pad. + This initial event sequence is terminated by a wp_tablet_pad.done + event. + + All pad features (buttons, rings and strips) are logically divided into + groups and all pads have at least one group. The available groups are + notified through the wp_tablet_pad.group event; the compositor will + emit one event per group before emitting wp_tablet_pad.done. + + Groups may have multiple modes. Modes allow clients to map multiple + actions to a single pad feature. Only one mode can be active per group, + although different groups may have different active modes. + + + + + Requests the compositor to use the provided feedback string + associated with this button. This request should be issued immediately + after a wp_tablet_pad_group.mode_switch event from the corresponding + group is received, or whenever a button is mapped to a different + action. See wp_tablet_pad_group.mode_switch for more details. + + Clients are encouraged to provide context-aware descriptions for + the actions associated with each button, and compositors may use + this information to offer visual feedback on the button layout + (e.g. on-screen displays). + + Button indices start at 0. Setting the feedback string on a button + that is reserved by the compositor (i.e. not belonging to any + wp_tablet_pad_group) does not generate an error but the compositor + is free to ignore the request. + + The provided string 'description' is a UTF-8 encoded string to be + associated with this ring, and is considered user-visible; general + internationalization rules apply. + + The serial argument will be that of the last + wp_tablet_pad_group.mode_switch event received for the group of this + button. Requests providing other serials than the most recent one will + be ignored. + + + + + + + + + Destroy the wp_tablet_pad object. Objects created from this object + are unaffected and should be destroyed separately. + + + + + + Sent on wp_tablet_pad initialization to announce available groups. + One event is sent for each pad group available. + + This event is sent in the initial burst of events before the + wp_tablet_pad.done event. At least one group will be announced. + + + + + + + A system-specific device path that indicates which device is behind + this wp_tablet_pad. This information may be used to gather additional + information about the device, e.g. through libwacom. + + The format of the path is unspecified, it may be a device node, a + sysfs path, or some other identifier. It is up to the client to + identify the string provided. + + This event is sent in the initial burst of events before the + wp_tablet_pad.done event. + + + + + + + Sent on wp_tablet_pad initialization to announce the available + buttons. + + This event is sent in the initial burst of events before the + wp_tablet_pad.done event. This event is only sent when at least one + button is available. + + + + + + + This event signals the end of the initial burst of descriptive + events. A client may consider the static description of the pad to + be complete and finalize initialization of the pad. + + + + + + Describes the physical state of a button that caused the button + event. + + + + + + + + Sent whenever the physical state of a button changes. + + + + + + + + + Notification that this pad is focused on the specified surface. + + + + + + + + + Notification that this pad is no longer focused on the specified + surface. + + + + + + + + Sent when the pad has been removed from the system. When a tablet + is removed its pad(s) will be removed too. + + When this event is received, the client must destroy all rings, strips + and groups that were offered by this pad, and issue wp_tablet_pad.destroy + the pad itself. + + + + diff --git a/SDL2-2.30.5/wayland-protocols/text-input-unstable-v3.xml b/SDL2-2.30.5/wayland-protocols/text-input-unstable-v3.xml new file mode 100644 index 0000000..d5f6322 --- /dev/null +++ b/SDL2-2.30.5/wayland-protocols/text-input-unstable-v3.xml @@ -0,0 +1,452 @@ + + + + + Copyright © 2012, 2013 Intel Corporation + Copyright © 2015, 2016 Jan Arne Petersen + Copyright © 2017, 2018 Red Hat, Inc. + Copyright © 2018 Purism SPC + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that copyright notice and this permission + notice appear in supporting documentation, and that the name of + the copyright holders not be used in advertising or publicity + pertaining to distribution of the software without specific, + written prior permission. The copyright holders make no + representations about the suitability of this software for any + purpose. It is provided "as is" without express or implied + warranty. + + THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF + THIS SOFTWARE. + + + + This protocol allows compositors to act as input methods and to send text + to applications. A text input object is used to manage state of what are + typically text entry fields in the application. + + This document adheres to the RFC 2119 when using words like "must", + "should", "may", etc. + + Warning! The protocol described in this file is experimental and + backward incompatible changes may be made. Backward compatible changes + may be added together with the corresponding interface version bump. + Backward incompatible changes are done by bumping the version number in + the protocol and interface names and resetting the interface version. + Once the protocol is to be declared stable, the 'z' prefix and the + version number in the protocol and interface names are removed and the + interface version number is reset. + + + + + The zwp_text_input_v3 interface represents text input and input methods + associated with a seat. It provides enter/leave events to follow the + text input focus for a seat. + + Requests are used to enable/disable the text-input object and set + state information like surrounding and selected text or the content type. + The information about the entered text is sent to the text-input object + via the preedit_string and commit_string events. + + Text is valid UTF-8 encoded, indices and lengths are in bytes. Indices + must not point to middle bytes inside a code point: they must either + point to the first byte of a code point or to the end of the buffer. + Lengths must be measured between two valid indices. + + Focus moving throughout surfaces will result in the emission of + zwp_text_input_v3.enter and zwp_text_input_v3.leave events. The focused + surface must commit zwp_text_input_v3.enable and + zwp_text_input_v3.disable requests as the keyboard focus moves across + editable and non-editable elements of the UI. Those two requests are not + expected to be paired with each other, the compositor must be able to + handle consecutive series of the same request. + + State is sent by the state requests (set_surrounding_text, + set_content_type and set_cursor_rectangle) and a commit request. After an + enter event or disable request all state information is invalidated and + needs to be resent by the client. + + + + + Destroy the wp_text_input object. Also disables all surfaces enabled + through this wp_text_input object. + + + + + + Requests text input on the surface previously obtained from the enter + event. + + This request must be issued every time the active text input changes + to a new one, including within the current surface. Use + zwp_text_input_v3.disable when there is no longer any input focus on + the current surface. + + Clients must not enable more than one text input on the single seat + and should disable the current text input before enabling the new one. + At most one instance of text input may be in enabled state per instance, + Requests to enable the another text input when some text input is active + must be ignored by compositor. + + This request resets all state associated with previous enable, disable, + set_surrounding_text, set_text_change_cause, set_content_type, and + set_cursor_rectangle requests, as well as the state associated with + preedit_string, commit_string, and delete_surrounding_text events. + + The set_surrounding_text, set_content_type and set_cursor_rectangle + requests must follow if the text input supports the necessary + functionality. + + State set with this request is double-buffered. It will get applied on + the next zwp_text_input_v3.commit request, and stay valid until the + next committed enable or disable request. + + The changes must be applied by the compositor after issuing a + zwp_text_input_v3.commit request. + + + + + + Explicitly disable text input on the current surface (typically when + there is no focus on any text entry inside the surface). + + State set with this request is double-buffered. It will get applied on + the next zwp_text_input_v3.commit request. + + + + + + Sets the surrounding plain text around the input, excluding the preedit + text. + + The client should notify the compositor of any changes in any of the + values carried with this request, including changes caused by handling + incoming text-input events as well as changes caused by other + mechanisms like keyboard typing. + + If the client is unaware of the text around the cursor, it should not + issue this request, to signify lack of support to the compositor. + + Text is UTF-8 encoded, and should include the cursor position, the + complete selection and additional characters before and after them. + There is a maximum length of wayland messages, so text can not be + longer than 4000 bytes. + + Cursor is the byte offset of the cursor within text buffer. + + Anchor is the byte offset of the selection anchor within text buffer. + If there is no selected text, anchor is the same as cursor. + + If any preedit text is present, it is replaced with a cursor for the + purpose of this event. + + Values set with this request are double-buffered. They will get applied + on the next zwp_text_input_v3.commit request, and stay valid until the + next committed enable or disable request. + + The initial state for affected fields is empty, meaning that the text + input does not support sending surrounding text. If the empty values + get applied, subsequent attempts to change them may have no effect. + + + + + + + + + Reason for the change of surrounding text or cursor posision. + + + + + + + + Tells the compositor why the text surrounding the cursor changed. + + Whenever the client detects an external change in text, cursor, or + anchor posision, it must issue this request to the compositor. This + request is intended to give the input method a chance to update the + preedit text in an appropriate way, e.g. by removing it when the user + starts typing with a keyboard. + + cause describes the source of the change. + + The value set with this request is double-buffered. It must be applied + and reset to initial at the next zwp_text_input_v3.commit request. + + The initial value of cause is input_method. + + + + + + + Content hint is a bitmask to allow to modify the behavior of the text + input. + + + + + + + + + + + + + + + + + The content purpose allows to specify the primary purpose of a text + input. + + This allows an input method to show special purpose input panels with + extra characters or to disallow some characters. + + + + + + + + + + + + + + + + + + + + Sets the content purpose and content hint. While the purpose is the + basic purpose of an input field, the hint flags allow to modify some of + the behavior. + + Values set with this request are double-buffered. They will get applied + on the next zwp_text_input_v3.commit request. + Subsequent attempts to update them may have no effect. The values + remain valid until the next committed enable or disable request. + + The initial value for hint is none, and the initial value for purpose + is normal. + + + + + + + + Marks an area around the cursor as a x, y, width, height rectangle in + surface local coordinates. + + Allows the compositor to put a window with word suggestions near the + cursor, without obstructing the text being input. + + If the client is unaware of the position of edited text, it should not + issue this request, to signify lack of support to the compositor. + + Values set with this request are double-buffered. They will get applied + on the next zwp_text_input_v3.commit request, and stay valid until the + next committed enable or disable request. + + The initial values describing a cursor rectangle are empty. That means + the text input does not support describing the cursor area. If the + empty values get applied, subsequent attempts to change them may have + no effect. + + + + + + + + + + Atomically applies state changes recently sent to the compositor. + + The commit request establishes and updates the state of the client, and + must be issued after any changes to apply them. + + Text input state (enabled status, content purpose, content hint, + surrounding text and change cause, cursor rectangle) is conceptually + double-buffered within the context of a text input, i.e. between a + committed enable request and the following committed enable or disable + request. + + Protocol requests modify the pending state, as opposed to the current + state in use by the input method. A commit request atomically applies + all pending state, replacing the current state. After commit, the new + pending state is as documented for each related request. + + Requests are applied in the order of arrival. + + Neither current nor pending state are modified unless noted otherwise. + + The compositor must count the number of commit requests coming from + each zwp_text_input_v3 object and use the count as the serial in done + events. + + + + + + Notification that this seat's text-input focus is on a certain surface. + + If client has created multiple text input objects, compositor must send + this event to all of them. + + When the seat has the keyboard capability the text-input focus follows + the keyboard focus. This event sets the current surface for the + text-input object. + + + + + + + Notification that this seat's text-input focus is no longer on a + certain surface. The client should reset any preedit string previously + set. + + The leave notification clears the current surface. It is sent before + the enter notification for the new focus. After leave event, compositor + must ignore requests from any text input instances until next enter + event. + + When the seat has the keyboard capability the text-input focus follows + the keyboard focus. + + + + + + + Notify when a new composing text (pre-edit) should be set at the + current cursor position. Any previously set composing text must be + removed. Any previously existing selected text must be removed. + + The argument text contains the pre-edit string buffer. + + The parameters cursor_begin and cursor_end are counted in bytes + relative to the beginning of the submitted text buffer. Cursor should + be hidden when both are equal to -1. + + They could be represented by the client as a line if both values are + the same, or as a text highlight otherwise. + + Values set with this event are double-buffered. They must be applied + and reset to initial on the next zwp_text_input_v3.done event. + + The initial value of text is an empty string, and cursor_begin, + cursor_end and cursor_hidden are all 0. + + + + + + + + + Notify when text should be inserted into the editor widget. The text to + commit could be either just a single character after a key press or the + result of some composing (pre-edit). + + Values set with this event are double-buffered. They must be applied + and reset to initial on the next zwp_text_input_v3.done event. + + The initial value of text is an empty string. + + + + + + + Notify when the text around the current cursor position should be + deleted. + + Before_length and after_length are the number of bytes before and after + the current cursor index (excluding the selection) to delete. + + If a preedit text is present, in effect before_length is counted from + the beginning of it, and after_length from its end (see done event + sequence). + + Values set with this event are double-buffered. They must be applied + and reset to initial on the next zwp_text_input_v3.done event. + + The initial values of both before_length and after_length are 0. + + + + + + + + Instruct the application to apply changes to state requested by the + preedit_string, commit_string and delete_surrounding_text events. The + state relating to these events is double-buffered, and each one + modifies the pending state. This event replaces the current state with + the pending state. + + The application must proceed by evaluating the changes in the following + order: + + 1. Replace existing preedit string with the cursor. + 2. Delete requested surrounding text. + 3. Insert commit string with the cursor at its end. + 4. Calculate surrounding text to send. + 5. Insert new preedit text in cursor position. + 6. Place cursor inside preedit text. + + The serial number reflects the last state of the zwp_text_input_v3 + object known to the compositor. The value of the serial argument must + be equal to the number of commit requests already issued on that object. + When the client receives a done event with a serial different than the + number of past commit requests, it must proceed as normal, except it + should not change the current state of the zwp_text_input_v3 object. + + + + + + + + A factory for text-input objects. This object is a global singleton. + + + + + Destroy the wp_text_input_manager object. + + + + + + Creates a new text-input object for a given seat. + + + + + + diff --git a/SDL2-2.30.5/wayland-protocols/viewporter.xml b/SDL2-2.30.5/wayland-protocols/viewporter.xml new file mode 100644 index 0000000..c732d8c --- /dev/null +++ b/SDL2-2.30.5/wayland-protocols/viewporter.xml @@ -0,0 +1,186 @@ + + + + + Copyright © 2013-2016 Collabora, Ltd. + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice (including the next + paragraph) shall be included in all copies or substantial portions of the + Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + + + + The global interface exposing surface cropping and scaling + capabilities is used to instantiate an interface extension for a + wl_surface object. This extended interface will then allow + cropping and scaling the surface contents, effectively + disconnecting the direct relationship between the buffer and the + surface size. + + + + + Informs the server that the client will not be using this + protocol object anymore. This does not affect any other objects, + wp_viewport objects included. + + + + + + + + + + Instantiate an interface extension for the given wl_surface to + crop and scale its content. If the given wl_surface already has + a wp_viewport object associated, the viewport_exists + protocol error is raised. + + + + + + + + + An additional interface to a wl_surface object, which allows the + client to specify the cropping and scaling of the surface + contents. + + This interface works with two concepts: the source rectangle (src_x, + src_y, src_width, src_height), and the destination size (dst_width, + dst_height). The contents of the source rectangle are scaled to the + destination size, and content outside the source rectangle is ignored. + This state is double-buffered, and is applied on the next + wl_surface.commit. + + The two parts of crop and scale state are independent: the source + rectangle, and the destination size. Initially both are unset, that + is, no scaling is applied. The whole of the current wl_buffer is + used as the source, and the surface size is as defined in + wl_surface.attach. + + If the destination size is set, it causes the surface size to become + dst_width, dst_height. The source (rectangle) is scaled to exactly + this size. This overrides whatever the attached wl_buffer size is, + unless the wl_buffer is NULL. If the wl_buffer is NULL, the surface + has no content and therefore no size. Otherwise, the size is always + at least 1x1 in surface local coordinates. + + If the source rectangle is set, it defines what area of the wl_buffer is + taken as the source. If the source rectangle is set and the destination + size is not set, then src_width and src_height must be integers, and the + surface size becomes the source rectangle size. This results in cropping + without scaling. If src_width or src_height are not integers and + destination size is not set, the bad_size protocol error is raised when + the surface state is applied. + + The coordinate transformations from buffer pixel coordinates up to + the surface-local coordinates happen in the following order: + 1. buffer_transform (wl_surface.set_buffer_transform) + 2. buffer_scale (wl_surface.set_buffer_scale) + 3. crop and scale (wp_viewport.set*) + This means, that the source rectangle coordinates of crop and scale + are given in the coordinates after the buffer transform and scale, + i.e. in the coordinates that would be the surface-local coordinates + if the crop and scale was not applied. + + If src_x or src_y are negative, the bad_value protocol error is raised. + Otherwise, if the source rectangle is partially or completely outside of + the non-NULL wl_buffer, then the out_of_buffer protocol error is raised + when the surface state is applied. A NULL wl_buffer does not raise the + out_of_buffer error. + + The x, y arguments of wl_surface.attach are applied as normal to + the surface. They indicate how many pixels to remove from the + surface size from the left and the top. In other words, they are + still in the surface-local coordinate system, just like dst_width + and dst_height are. + + If the wl_surface associated with the wp_viewport is destroyed, + all wp_viewport requests except 'destroy' raise the protocol error + no_surface. + + If the wp_viewport object is destroyed, the crop and scale + state is removed from the wl_surface. The change will be applied + on the next wl_surface.commit. + + + + + The associated wl_surface's crop and scale state is removed. + The change is applied on the next wl_surface.commit. + + + + + + + + + + + + + Set the source rectangle of the associated wl_surface. See + wp_viewport for the description, and relation to the wl_buffer + size. + + If all of x, y, width and height are -1.0, the source rectangle is + unset instead. Any other set of values where width or height are zero + or negative, or x or y are negative, raise the bad_value protocol + error. + + The crop and scale state is double-buffered state, and will be + applied on the next wl_surface.commit. + + + + + + + + + + Set the destination size of the associated wl_surface. See + wp_viewport for the description, and relation to the wl_buffer + size. + + If width is -1 and height is -1, the destination size is unset + instead. Any other pair of values for width and height that + contains zero or negative values raises the bad_value protocol + error. + + The crop and scale state is double-buffered state, and will be + applied on the next wl_surface.commit. + + + + + + + diff --git a/SDL2-2.0.12/wayland-protocols/wayland.xml b/SDL2-2.30.5/wayland-protocols/wayland.xml similarity index 86% rename from SDL2-2.0.12/wayland-protocols/wayland.xml rename to SDL2-2.30.5/wayland-protocols/wayland.xml index 29b63be..10781cf 100644 --- a/SDL2-2.0.12/wayland-protocols/wayland.xml +++ b/SDL2-2.30.5/wayland-protocols/wayland.xml @@ -57,6 +57,12 @@ This request creates a registry object that allows the client to list and bind the global objects available from the compositor. + + It should be noted that the server side resources consumed in + response to a get_registry request can only be released when the + client disconnects, not when the client side proxy is destroyed. + Therefore, clients should invoke get_registry as infrequently as + possible to avoid wasting memory. @@ -85,18 +91,20 @@ + summary="method doesn't exist on the specified interface or malformed request"/> + This event is used internally by the object ID management - logic. When a client deletes an object, the server will send - this event to acknowledge that it has seen the delete request. - When the client receives this event, it will know that it can - safely reuse the object ID. + logic. When a client deletes an object that it had created, + the server will send this event to acknowledge that it has + seen the delete request. When the client receives this event, + it will know that it can safely reuse the object ID. @@ -171,7 +179,7 @@ the related request is done. - + Notify the client when the related request is done. @@ -179,7 +187,7 @@ - + A compositor. This object is a singleton global. The compositor is in charge of combining the contents of multiple @@ -250,6 +258,12 @@ for the pool from the file descriptor passed when the pool was created, but using the new size. This request can only be used to make the pool bigger. + + This request only changes the amount of bytes that are mmapped + by the server and does not touch the file corresponding to the + file descriptor passed at creation time. It is the client's + responsibility to ensure that the file is at least as big as + the new pool size. @@ -263,8 +277,8 @@ Clients can create wl_shm_pool objects using the create_pool request. - At connection setup time, the wl_shm object emits one or more - format events to inform clients about the valid pixel formats + On binding the wl_shm object one or more format events + are emitted to inform clients about the valid pixel formats that can be used for buffers. @@ -285,10 +299,15 @@ formats are optional and may not be supported by the particular renderer in use. - The drm format codes match the macros defined in drm_fourcc.h. - The formats actually supported by the compositor will be - reported by the format event. + The drm format codes match the macros defined in drm_fourcc.h, except + argb8888 and xrgb8888. The formats actually supported by the compositor + will be reported by the format event. + + For all wl_shm formats and unless specified in another protocol + extension, pre-multiplied alpha is used for pixel values. + @@ -347,6 +366,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -375,10 +444,15 @@ A buffer provides the content for a wl_surface. Buffers are - created through factory interfaces such as wl_drm, wl_shm or - similar. It has a width and a height and can be attached to a - wl_surface, but the mechanism by which a client provides and - updates the contents is defined by the buffer factory interface. + created through factory interfaces such as wl_shm, wp_linux_buffer_params + (from the linux-dmabuf protocol extension) or similar. It has a width and + a height and can be attached to a wl_surface, but the mechanism by which a + client provides and updates the contents is defined by the buffer factory + interface. + + If the buffer uses a format that has an alpha channel, the alpha channel + is assumed to be premultiplied in the color channels unless otherwise + specified. @@ -501,6 +575,9 @@ this request after a NULL mime type has been set in wl_data_offer.accept or no action was received through wl_data_offer.action. + + If wl_data_offer.finish request is received for a non drag and drop + operation, the invalid_finish protocol error is raised. @@ -517,7 +594,7 @@ This request determines the final result of the drag-and-drop operation. If the end result is that no action is accepted, - the drag source will receive wl_drag_source.cancelled. + the drag source will receive wl_data_source.cancelled. The dnd_actions argument must contain only values expressed in the wl_data_device_manager.dnd_actions enum, and the preferred_action @@ -538,8 +615,10 @@ This request can only be made on drag-and-drop offers, a protocol error will be raised otherwise. - - + + @@ -548,7 +627,8 @@ will be sent right after wl_data_device.enter, or anytime the source side changes its offered actions through wl_data_source.set_actions. - + @@ -589,7 +669,8 @@ final wl_data_offer.set_actions and wl_data_offer.accept requests must happen before the call to wl_data_offer.finish. - + @@ -686,7 +767,8 @@ wl_data_device.start_drag. Attempting to use the source other than for drag-and-drop will raise a protocol error. - + @@ -742,7 +824,8 @@ Clients can trigger cursor surface changes from this point, so they reflect the current action. - + @@ -768,7 +851,8 @@ for the eventual data transfer. If source is NULL, enter, leave and motion events are sent only to the client that initiated the drag and the client is expected to handle the data passing - internally. + internally. If source is destroyed, the drag-and-drop session will be + cancelled. The origin surface is the surface where the drag originates and the client must have an active implicit grab that matches the @@ -812,7 +896,7 @@ which will subsequently be used in either the data_device.enter event (for drag-and-drop) or the data_device.selection event (for selections). Immediately - following the data_device_data_offer event, the new data_offer + following the data_device.data_offer event, the new data_offer object will send out data_offer.offer events to describe the mime types it offers. @@ -882,9 +966,10 @@ immediately before receiving keyboard focus and when a new selection is set while the client has keyboard focus. The data_offer is valid until a new data_offer or NULL is received - or until the client loses keyboard focus. The client must - destroy the previous selection data_offer, if any, upon receiving - this event. + or until the client loses keyboard focus. Switching surface with + keyboard focus within the same client doesn't mean a new selection + will be sent. The client must destroy the previous selection + data_offer, if any, upon receiving this event. @@ -970,6 +1055,10 @@ It allows clients to associate a wl_shell_surface with a basic surface. + + Note! This protocol is deprecated and not intended for production use. + For desktop-style user interfaces, use xdg_shell. Compositors and clients + should not implement this interface. @@ -1263,10 +1352,12 @@ - + - A surface is a rectangular area that is displayed on the screen. - It has a location, size and pixel contents. + A surface is a rectangular area that may be displayed on zero + or more outputs, and shown any number of times at the compositor's + discretion. They can present wl_buffers, receive user input, and + define a local coordinate system. The size of a surface (and relative positions on it) is described in surface-local coordinates, which may differ from the buffer @@ -1312,6 +1403,8 @@ + + @@ -1326,14 +1419,22 @@ The new size of the surface is calculated based on the buffer size transformed by the inverse buffer_transform and the - inverse buffer_scale. This means that the supplied buffer - must be an integer multiple of the buffer_scale. + inverse buffer_scale. This means that at commit time the supplied + buffer size must be an integer multiple of the buffer_scale. If + that's not the case, an invalid_size error is sent. The x and y arguments specify the location of the new pending buffer's upper left corner, relative to the current buffer's upper left corner, in surface-local coordinates. In other words, the x and y, combined with the new surface size define in which - directions the surface's size changes. + directions the surface's size changes. Setting anything other than 0 + as x and y arguments is discouraged, and should instead be replaced + with using the separate wl_surface.offset request. + + When the bound wl_surface version is 5 or higher, passing any + non-zero x or y is a protocol violation, and will result in an + 'invalid_offset' error being raised. To achieve equivalent semantics, + use wl_surface.offset. Surface contents are double-buffered state, see wl_surface.commit. @@ -1354,10 +1455,19 @@ will not receive a release event, and is not used by the compositor. + If a pending wl_buffer has been committed to more than one wl_surface, + the delivery of wl_buffer.release events becomes undefined. A well + behaved client should not rely on wl_buffer.release events in this + case. Alternatively, a client could create multiple wl_buffer objects + from the same backing storage or use wp_linux_buffer_release. + Destroying the wl_buffer after wl_buffer.release does not change - the surface contents. However, if the client destroys the - wl_buffer before receiving the wl_buffer.release event, the surface - contents become undefined immediately. + the surface contents. Destroying the wl_buffer before wl_buffer.release + is allowed as long as the underlying buffer storage isn't re-used (this + can happen e.g. on client process termination). However, if the client + destroys the wl_buffer before receiving the wl_buffer.release event and + mutates the underlying buffer storage, the surface contents become + undefined immediately. If wl_surface.attach is sent with a NULL wl_buffer, the following wl_surface.commit will remove the surface content. @@ -1388,9 +1498,9 @@ and clears pending damage. The server will clear the current damage as it repaints the surface. - Alternatively, damage can be posted with wl_surface.damage_buffer - which uses buffer coordinates instead of surface coordinates, - and is probably the preferred and intuitive way of doing this. + Note! New clients should not use this request. Instead damage can be + posted with wl_surface.damage_buffer which uses buffer coordinates + instead of surface coordinates. @@ -1534,6 +1644,12 @@ This is emitted whenever a surface's creation, movement, or resizing results in it no longer having any part of it within the scanout region of an output. + + Clients should not use the number of outputs the surface is on for frame + throttling purposes. The surface might be hidden even if no leave event + has been sent, and the compositor might expect new surface content + updates even if no enter event has been sent. The frame event should be + used instead. @@ -1649,9 +1765,30 @@ + + + + + + The x and y arguments specify the location of the new pending + buffer's upper left corner, relative to the current buffer's upper + left corner, in surface-local coordinates. In other words, the + x and y, combined with the new surface size define in which + directions the surface's size changes. + + Surface location offset is double-buffered state, see + wl_surface.commit. + + This request is semantically equivalent to and the replaces the x and y + arguments in the wl_surface.attach request in wl_surface versions prior + to 5. See wl_surface.attach for details. + + + + - + A seat is a group of keyboards, pointer and touch devices. This object is published as a global during start up, or when such a @@ -1669,6 +1806,14 @@ + + + These errors can be emitted in response to wl_seat requests. + + + + This is emitted whenever a seat gains or loses the pointer, @@ -1707,7 +1852,8 @@ This request only takes effect if the seat has the pointer capability, or has had the pointer capability in the past. It is a protocol violation to issue this request on a seat that has - never had the pointer capability. + never had the pointer capability. The missing_capability error will + be sent in this case. @@ -1720,7 +1866,8 @@ This request only takes effect if the seat has the keyboard capability, or has had the keyboard capability in the past. It is a protocol violation to issue this request on a seat that has - never had the keyboard capability. + never had the keyboard capability. The missing_capability error will + be sent in this case. @@ -1733,7 +1880,8 @@ This request only takes effect if the seat has the touch capability, or has had the touch capability in the past. It is a protocol violation to issue this request on a seat that has - never had the touch capability. + never had the touch capability. The missing_capability error will + be sent in this case. @@ -1742,9 +1890,22 @@ - In a multiseat configuration this can be used by the client to help - identify which physical devices the seat represents. Based on - the seat configuration used by the compositor. + In a multi-seat configuration the seat name can be used by clients to + help identify which physical devices the seat represents. + + The seat name is a UTF-8 string with no convention defined for its + contents. Each name is unique among all wl_seat globals. The name is + only guaranteed to be unique for the current compositor instance. + + The same seat names are used for all clients. Thus, the name can be + shared across processes to refer to a specific wl_seat global. + + The name event is sent after binding to the seat global. This event is + only sent once per seat object, and the name does not change over the + lifetime of the wl_seat global. + + Compositors may re-use the same seat name if the wl_seat global is + destroyed and re-created later. @@ -1760,7 +1921,7 @@ - + The wl_pointer interface represents one or more input devices, such as mice, which control the pointer location and pointer_focus @@ -1809,6 +1970,10 @@ wl_surface is no longer used as the cursor. When the use as a cursor ends, the current and pending input regions become undefined, and the wl_surface is unmapped. + + The serial parameter must match the latest wl_pointer.enter + serial number sent to the client. Otherwise the request will be + ignored. + + + + Discrete high-resolution scroll information. + + This event carries high-resolution wheel scroll information, + with each multiple of 120 representing one logical scroll step + (a wheel detent). For example, an axis_value120 of 30 is one quarter of + a logical scroll step in the positive direction, a value120 of + -240 are two logical scroll steps in the negative direction within the + same hardware event. + Clients that rely on discrete scrolling should accumulate the + value120 to multiples of 120 before processing the event. + + The value120 must not be zero. + + This event replaces the wl_pointer.axis_discrete event in clients + supporting wl_pointer version 8 or later. + + Where a wl_pointer.axis_source event occurs in the same + wl_pointer.frame, the axis source applies to this event. + + The order of wl_pointer.axis_value120 and wl_pointer.axis_source is + not guaranteed. + + + + - + The wl_keyboard interface represents one or more keyboards associated with a seat. @@ -2097,13 +2294,17 @@ + summary="libxkbcommon compatible, null-terminated string; to determine the xkb keycode, clients must add 8 to the key event keycode"/> This event provides a file descriptor to the client which can be - memory-mapped to provide a keyboard mapping description. + memory-mapped in read-only mode to provide a keyboard mapping + description. + + From version 7 onwards, the fd must be mapped with MAP_PRIVATE by + the recipient, as MAP_SHARED may fail. @@ -2114,6 +2315,9 @@ Notification that this seat's keyboard focus is on a certain surface. + + The compositor must send the wl_keyboard.modifiers event after this + event. @@ -2127,6 +2331,9 @@ The leave notification is sent before the enter notification for the new focus. + + After this event client must assume that all keys, including modifiers, + are lifted and also it must stop key repeating if there's some going on. @@ -2145,6 +2352,12 @@ A key was pressed or released. The time argument is a timestamp with millisecond granularity, with an undefined base. + + The key is a platform-specific key code that can be interpreted + by feeding it to the keyboard mapping (see the keymap event). + + If this event produces a change in modifiers, then the resulting + wl_keyboard.modifiers event must be sent after this event. @@ -2194,7 +2407,7 @@ - + The wl_touch interface represents a touchscreen associated with a seat. @@ -2338,7 +2551,7 @@ - + An output describes part of the compositor geometry. The compositor works in the 'compositor coordinate system' and an @@ -2390,6 +2603,19 @@ The geometry event describes geometric properties of the output. The event is sent when binding to the output object and whenever any of the properties change. + + The physical size can be set to zero if it doesn't make sense for this + output (e.g. for projectors or virtual outputs). + + The geometry event will be followed by a done event (starting from + version 2). + + Note: wl_output only advertises partial information about the output + position and identification. Some compositors, for instance those not + implementing a desktop-style output layout or those exposing virtual + outputs, might fake this information. Instead of using x and y, clients + should use xdg_output.logical_position. Instead of using make and model, + clients should use name and description. @@ -2430,11 +2656,31 @@ current. In other words, the current mode is always the last mode that was received with the current flag set. + Non-current modes are deprecated. A compositor can decide to only + advertise the current mode and never send other modes. Clients + should not rely on non-current modes. + The size of a mode is given in physical hardware units of the output device. This is not necessarily the same as the output size in the global compositor space. For instance, the output may be scaled, as described in wl_output.scale, - or transformed, as described in wl_output.transform. + or transformed, as described in wl_output.transform. Clients + willing to retrieve the output size in the global compositor + space should use xdg_output.logical_size instead. + + The vertical refresh rate can be set to zero if it doesn't make + sense for this output (e.g. for virtual outputs). + + The mode event will be followed by a done event (starting from + version 2). + + Clients should not use the refresh rate to schedule frames. Instead, + they should use the wl_surface.frame event or the presentation-time + protocol. + + Note: this information is not always meaningful for all outputs. Some + compositors, such as those exposing virtual outputs, might fake the + refresh rate or the size. @@ -2474,6 +2720,8 @@ the scale of the output. That way the compositor can avoid scaling the surface, and the client can supply a higher detail image. + + The scale event will be followed by a done event. @@ -2486,6 +2734,62 @@ use the output object anymore. + + + + + + Many compositors will assign user-friendly names to their outputs, show + them to the user, allow the user to refer to an output, etc. The client + may wish to know this name as well to offer the user similar behaviors. + + The name is a UTF-8 string with no convention defined for its contents. + Each name is unique among all wl_output globals. The name is only + guaranteed to be unique for the compositor instance. + + The same output name is used for all clients for a given wl_output + global. Thus, the name can be shared across processes to refer to a + specific wl_output global. + + The name is not guaranteed to be persistent across sessions, thus cannot + be used to reliably identify an output in e.g. configuration files. + + Examples of names include 'HDMI-A-1', 'WL-1', 'X11-1', etc. However, do + not assume that the name is a reflection of an underlying DRM connector, + X11 connection, etc. + + The name event is sent after binding the output object. This event is + only sent once per output object, and the name does not change over the + lifetime of the wl_output global. + + Compositors may re-use the same output name if the wl_output global is + destroyed and re-created later. Compositors should avoid re-using the + same name if possible. + + The name event will be followed by a done event. + + + + + + + Many compositors can produce human-readable descriptions of their + outputs. The client may wish to know this description as well, e.g. for + output selection purposes. + + The description is a UTF-8 string with no convention defined for its + contents. The description is not guaranteed to be unique among all + wl_output globals. Examples might include 'Foocorp 11" Display' or + 'Virtual X11 output via :1'. + + The description event is sent after binding the output object and + whenever the description changes. The description is optional, and may + not be sent at all. + + The description event will be followed by a done event. + + + @@ -2568,6 +2872,14 @@ The to-be sub-surface must not already have another role, and it must not have an existing wl_subsurface object. Otherwise a protocol error is raised. + + Adding sub-surfaces to a parent is a double-buffered operation on the + parent (see wl_surface.commit). The effect of adding a sub-surface + becomes visible on the next time the state of the parent surface is + applied. + + This request modifies the behaviour of wl_surface.commit request on + the sub-surface, see the documentation on wl_subsurface interface. @@ -2601,7 +2913,7 @@ wl_surface state directly. A sub-surface is initially in the synchronized mode. - Sub-surfaces have also other kind of state, which is managed by + Sub-surfaces also have another kind of state, which is managed by wl_subsurface requests, as opposed to wl_surface requests. This state includes the sub-surface position relative to the parent surface (wl_subsurface.set_position), and the stacking order of @@ -2637,7 +2949,7 @@ that was turned into a sub-surface with a wl_subcompositor.get_subsurface request. The wl_surface's association to the parent is deleted, and the wl_surface loses its role as - a sub-surface. The wl_surface is unmapped. + a sub-surface. The wl_surface is unmapped immediately. diff --git a/SDL2-2.30.5/wayland-protocols/xdg-activation-v1.xml b/SDL2-2.30.5/wayland-protocols/xdg-activation-v1.xml new file mode 100644 index 0000000..d87e633 --- /dev/null +++ b/SDL2-2.30.5/wayland-protocols/xdg-activation-v1.xml @@ -0,0 +1,186 @@ + + + + + Copyright © 2020 Aleix Pol Gonzalez <aleixpol@kde.org> + Copyright © 2020 Carlos Garnacho <carlosg@gnome.org> + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice (including the next + paragraph) shall be included in all copies or substantial portions of the + Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + + + The way for a client to pass focus to another toplevel is as follows. + + The client that intends to activate another toplevel uses the + xdg_activation_v1.get_activation_token request to get an activation token. + This token is then passed to the client to be activated through a separate + band of communication. The client to be activated will then pass the token + it received to the xdg_activation_v1.activate request. The compositor can + then use this token to decide how to react to the activation request. + + The token the activating client gets may be ineffective either already at + the time it receives it, for example if it was not focused, for focus + stealing prevention. The activating client will have no way to discover + the validity of the token, and may still forward it to the to be activated + client. + + The created activation token may optionally get information attached to it + that can be used by the compositor to identify the application that we + intend to activate. This can for example be used to display a visual hint + about what application is being started. + + Warning! The protocol described in this file is currently in the testing + phase. Backward compatible changes may be added together with the + corresponding interface version bump. Backward incompatible changes can + only be done by creating a new major version of the extension. + + + + + A global interface used for informing the compositor about applications + being activated or started, or for applications to request to be + activated. + + + + + Notify the compositor that the xdg_activation object will no longer be + used. + + The child objects created via this interface are unaffected and should + be destroyed separately. + + + + + + Creates an xdg_activation_token_v1 object that will provide + the initiating client with a unique token for this activation. This + token should be offered to the clients to be activated. + + + + + + + + Requests surface activation. It's up to the compositor to display + this information as desired, for example by placing the surface above + the rest. + + The compositor may know who requested this by checking the activation + token and might decide not to follow through with the activation if it's + considered unwanted. + + Compositors can ignore unknown presentation tokens when an invalid + token is passed. + + + + + + + + + An object for setting up a token and receiving a token handle that can + be passed as an activation token to another client. + + The object is created using the xdg_activation_v1.get_activation_token + request. This object should then be populated with the app_id, surface + and serial information and committed. The compositor shall then issue a + done event with the token. In case the request's parameters are invalid, + the compositor will provide an invalid token. + + + + + + + + + Provides information about the seat and serial event that requested the + token. + + Must be sent before commit. This information is optional. + + + + + + + + The requesting client can specify an app_id to associate the token + being created with it. + + Must be sent before commit. This information is optional. + + + + + + + The requesting client can specify a surface to associate the token + being created with it. + + Must be triggered before commit. This information is optional. + + + + + + + Requests an activation token based on the different parameters that + have been offered through set_serial, set_surface and set_app_id. + + + + + + The 'done' event contains the unique token of this activation request + and notifies that the provider is done. + + Applications will typically receive the token through the + XDG_ACTIVATION_TOKEN environment variable as set by its launcher, and + should unset the environment variable right after this request, in + order to avoid propagating it to child processes. + + Applications implementing the D-Bus interface org.freedesktop.Application + should get their token under XDG_ACTIVATION_TOKEN on their platform_data. + + Presentation tokens may be transferred across clients through means not + described in this protocol. + + + + + + + Notify the compositor that the xdg_activation_token_v1 object will no + longer be used. + + + + diff --git a/SDL2-2.0.12/wayland-protocols/xdg-decoration-unstable-v1.xml b/SDL2-2.30.5/wayland-protocols/xdg-decoration-unstable-v1.xml similarity index 100% rename from SDL2-2.0.12/wayland-protocols/xdg-decoration-unstable-v1.xml rename to SDL2-2.30.5/wayland-protocols/xdg-decoration-unstable-v1.xml diff --git a/SDL2-2.30.5/wayland-protocols/xdg-output-unstable-v1.xml b/SDL2-2.30.5/wayland-protocols/xdg-output-unstable-v1.xml new file mode 100644 index 0000000..9a5b790 --- /dev/null +++ b/SDL2-2.30.5/wayland-protocols/xdg-output-unstable-v1.xml @@ -0,0 +1,220 @@ + + + + + Copyright © 2017 Red Hat Inc. + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice (including the next + paragraph) shall be included in all copies or substantial portions of the + Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + + + This protocol aims at describing outputs in a way which is more in line + with the concept of an output on desktop oriented systems. + + Some information are more specific to the concept of an output for + a desktop oriented system and may not make sense in other applications, + such as IVI systems for example. + + Typically, the global compositor space on a desktop system is made of + a contiguous or overlapping set of rectangular regions. + + Some of the information provided in this protocol might be identical + to their counterparts already available from wl_output, in which case + the information provided by this protocol should be preferred to their + equivalent in wl_output. The goal is to move the desktop specific + concepts (such as output location within the global compositor space, + the connector name and types, etc.) out of the core wl_output protocol. + + Warning! The protocol described in this file is experimental and + backward incompatible changes may be made. Backward compatible + changes may be added together with the corresponding interface + version bump. + Backward incompatible changes are done by bumping the version + number in the protocol and interface names and resetting the + interface version. Once the protocol is to be declared stable, + the 'z' prefix and the version number in the protocol and + interface names are removed and the interface version number is + reset. + + + + + A global factory interface for xdg_output objects. + + + + + Using this request a client can tell the server that it is not + going to use the xdg_output_manager object anymore. + + Any objects already created through this instance are not affected. + + + + + + This creates a new xdg_output object for the given wl_output. + + + + + + + + + An xdg_output describes part of the compositor geometry. + + This typically corresponds to a monitor that displays part of the + compositor space. + + For objects version 3 onwards, after all xdg_output properties have been + sent (when the object is created and when properties are updated), a + wl_output.done event is sent. This allows changes to the output + properties to be seen as atomic, even if they happen via multiple events. + + + + + Using this request a client can tell the server that it is not + going to use the xdg_output object anymore. + + + + + + The position event describes the location of the wl_output within + the global compositor space. + + The logical_position event is sent after creating an xdg_output + (see xdg_output_manager.get_xdg_output) and whenever the location + of the output changes within the global compositor space. + + + + + + + + The logical_size event describes the size of the output in the + global compositor space. + + For example, a surface without any buffer scale, transformation + nor rotation set, with the size matching the logical_size will + have the same size as the corresponding output when displayed. + + Most regular Wayland clients should not pay attention to the + logical size and would rather rely on xdg_shell interfaces. + + Some clients such as Xwayland, however, need this to configure + their surfaces in the global compositor space as the compositor + may apply a different scale from what is advertised by the output + scaling property (to achieve fractional scaling, for example). + + For example, for a wl_output mode 3840×2160 and a scale factor 2: + + - A compositor not scaling the surface buffers will advertise a + logical size of 3840×2160, + + - A compositor automatically scaling the surface buffers will + advertise a logical size of 1920×1080, + + - A compositor using a fractional scale of 1.5 will advertise a + logical size of 2560×1440. + + For example, for a wl_output mode 1920×1080 and a 90 degree rotation, + the compositor will advertise a logical size of 1080x1920. + + The logical_size event is sent after creating an xdg_output + (see xdg_output_manager.get_xdg_output) and whenever the logical + size of the output changes, either as a result of a change in the + applied scale or because of a change in the corresponding output + mode(see wl_output.mode) or transform (see wl_output.transform). + + + + + + + + This event is sent after all other properties of an xdg_output + have been sent. + + This allows changes to the xdg_output properties to be seen as + atomic, even if they happen via multiple events. + + For objects version 3 onwards, this event is deprecated. Compositors + are not required to send it anymore and must send wl_output.done + instead. + + + + + + + + Many compositors will assign names to their outputs, show them to the + user, allow them to be configured by name, etc. The client may wish to + know this name as well to offer the user similar behaviors. + + The naming convention is compositor defined, but limited to + alphanumeric characters and dashes (-). Each name is unique among all + wl_output globals, but if a wl_output global is destroyed the same name + may be reused later. The names will also remain consistent across + sessions with the same hardware and software configuration. + + Examples of names include 'HDMI-A-1', 'WL-1', 'X11-1', etc. However, do + not assume that the name is a reflection of an underlying DRM + connector, X11 connection, etc. + + The name event is sent after creating an xdg_output (see + xdg_output_manager.get_xdg_output). This event is only sent once per + xdg_output, and the name does not change over the lifetime of the + wl_output global. + + + + + + + Many compositors can produce human-readable descriptions of their + outputs. The client may wish to know this description as well, to + communicate the user for various purposes. + + The description is a UTF-8 string with no convention defined for its + contents. Examples might include 'Foocorp 11" Display' or 'Virtual X11 + output via :1'. + + The description event is sent after creating an xdg_output (see + xdg_output_manager.get_xdg_output) and whenever the description + changes. The description is optional, and may not be sent at all. + + For objects of version 2 and lower, this event is only sent once per + xdg_output, and the description does not change over the lifetime of + the wl_output global. + + + + + + diff --git a/SDL2-2.0.12/wayland-protocols/xdg-shell.xml b/SDL2-2.30.5/wayland-protocols/xdg-shell.xml similarity index 86% rename from SDL2-2.0.12/wayland-protocols/xdg-shell.xml rename to SDL2-2.30.5/wayland-protocols/xdg-shell.xml index d524ea9..be64354 100644 --- a/SDL2-2.0.12/wayland-protocols/xdg-shell.xml +++ b/SDL2-2.30.5/wayland-protocols/xdg-shell.xml @@ -29,7 +29,7 @@ DEALINGS IN THE SOFTWARE. - + The xdg_wm_base interface is exposed as a global object enabling clients to turn their wl_surfaces into windows in a desktop environment. It @@ -101,7 +101,7 @@ The ping event asks the client if it's still alive. Pass the serial specified in the event back to the compositor by sending - a "pong" request back with the specified serial. See xdg_wm_base.ping. + a "pong" request back with the specified serial. See xdg_wm_base.pong. Compositors can use this to determine if the client is still alive. It's unspecified what will happen if the client doesn't @@ -115,7 +115,7 @@ - + The xdg_positioner provides a collection of rules for the placement of a child surface relative to a parent surface. Rules can be defined to ensure @@ -357,9 +357,49 @@ + + + + + + When set reactive, the surface is reconstrained if the conditions used + for constraining changed, e.g. the parent window moved. + + If the conditions changed and the popup was reconstrained, an + xdg_popup.configure event is sent with updated geometry, followed by an + xdg_surface.configure event. + + + + + + Set the parent window geometry the compositor should use when + positioning the popup. The compositor may use this information to + determine the future state the popup should be constrained using. If + this doesn't match the dimension of the parent the popup is eventually + positioned against, the behavior is undefined. + + The arguments are given in the surface-local coordinate space. + + + + + + + + Set the serial of a xdg_surface.configure event this positioner will be + used in response to. The compositor may use this information together + with set_parent_size to determine what future state the popup should be + constrained using. + + + - + An interface that may be implemented by a wl_surface, for implementations that provide a desktop-style user interface. @@ -526,9 +566,10 @@ + - + This interface defines an xdg_surface role which allows a surface to, among other things, set window-like properties such as maximize, @@ -604,6 +645,9 @@ For example, "org.freedesktop.FooViewer" where the .desktop file is "org.freedesktop.FooViewer.desktop". + Like other properties, a set_app_id request can be sent after the + xdg_toplevel has been mapped to update the property. + See the desktop-entry specification [0] for more details on application identifiers and how they relate to well-known D-Bus names and .desktop files. @@ -707,7 +751,7 @@ - + @@ -724,6 +768,9 @@ The surface is maximized. The window geometry specified in the configure event must be obeyed by the client. + + The client should draw without shadow or other + decoration outside of the window geometry. @@ -750,6 +797,30 @@ keyboard or pointer focus. + + + The window is currently in a tiled layout and the left edge is + considered to be adjacent to another part of the tiling grid. + + + + + The window is currently in a tiled layout and the right edge is + considered to be adjacent to another part of the tiling grid. + + + + + The window is currently in a tiled layout and the top edge is + considered to be adjacent to another part of the tiling grid. + + + + + The window is currently in a tiled layout and the bottom edge is + considered to be adjacent to another part of the tiling grid. + + @@ -839,12 +910,11 @@ Maximize the surface. After requesting that the surface should be maximized, the compositor - will respond by emitting a configure event with the "maximized" state - and the required window geometry. The client should then update its - content, drawing it in a maximized state, i.e. without shadow or other - decoration outside of the window geometry. The client must also - acknowledge the configure when committing the new content (see - ack_configure). + will respond by emitting a configure event. Whether this configure + actually sets the window maximized is subject to compositor policies. + The client must then update its content, drawing in the configured + state. The client must also acknowledge the configure when committing + the new content (see ack_configure). It is up to the compositor to decide how and where to maximize the surface, for example which output and what region of the screen should @@ -854,8 +924,8 @@ a configure event with the "maximized" state. If the surface is in a fullscreen state, this request has no direct - effect. It will alter the state the surface is returned to when - unmaximized if not overridden by the compositor. + effect. It may alter the state the surface is returned to when + unmaximized unless overridden by the compositor. @@ -864,13 +934,13 @@ Unmaximize the surface. After requesting that the surface should be unmaximized, the compositor - will respond by emitting a configure event without the "maximized" - state. If available, the compositor will include the window geometry - dimensions the window had prior to being maximized in the configure - event. The client must then update its content, drawing it in a - regular state, i.e. potentially with shadow, etc. The client must also - acknowledge the configure when committing the new content (see - ack_configure). + will respond by emitting a configure event. Whether this actually + un-maximizes the window is subject to compositor policies. + If available and applicable, the compositor will include the window + geometry dimensions the window had prior to being maximized in the + configure event. The client must then update its content, drawing it in + the configured state. The client must also acknowledge the configure + when committing the new content (see ack_configure). It is up to the compositor to position the surface after it was unmaximized; usually the position the surface had before maximizing, if @@ -880,8 +950,8 @@ emit a configure event without the "maximized" state. If the surface is in a fullscreen state, this request has no direct - effect. It will alter the state the surface is returned to when - unmaximized if not overridden by the compositor. + effect. It may alter the state the surface is returned to when + unmaximized unless overridden by the compositor. @@ -890,10 +960,10 @@ Make the surface fullscreen. After requesting that the surface should be fullscreened, the - compositor will respond by emitting a configure event with the - "fullscreen" state and the fullscreen window geometry. The client must - also acknowledge the configure when committing the new content (see - ack_configure). + compositor will respond by emitting a configure event. Whether the + client is actually put into a fullscreen state is subject to compositor + policies. The client must also acknowledge the configure when + committing the new content (see ack_configure). The output passed by the request indicates the client's preference as to which display it should be set fullscreen on. If this value is NULL, @@ -919,8 +989,9 @@ Make the surface no longer fullscreen. After requesting that the surface should be unfullscreened, the - compositor will respond by emitting a configure event without the - "fullscreen" state. + compositor will respond by emitting a configure event. + Whether this actually removes the fullscreen state of the client is + subject to compositor policies. Making a surface unfullscreen sets states for the surface based on the following: * the state(s) it may have had before becoming fullscreen @@ -989,7 +1060,7 @@ - + A popup surface is a short-lived, temporary surface. It can be used to implement for example menus, popovers, tooltips and other similar user @@ -1007,21 +1078,12 @@ surface of their own is clicked should dismiss the popup using the destroy request. - The parent surface must have either the xdg_toplevel or xdg_popup surface - role. - A newly created xdg_popup will be stacked on top of all previously created xdg_popup surfaces associated with the same xdg_toplevel. The parent of an xdg_popup must be mapped (see the xdg_surface description) before the xdg_popup itself. - The x and y arguments passed when creating the popup object specify - where the top left of the popup should be placed, relative to the - local surface coordinates of the parent surface. See - xdg_surface.get_popup. An xdg_popup must intersect with or be at least - partially adjacent to its parent surface. - The client must call wl_surface.commit on the corresponding wl_surface for the xdg_popup state to take effect. @@ -1099,6 +1161,11 @@ The x and y arguments represent the position the popup was placed at given the xdg_positioner rule, relative to the upper left corner of the window geometry of the parent surface. + + For version 2 or older, the configure event for an xdg_popup is only + ever sent once for the initial configuration. Starting with version 3, + it may be sent again if the popup is setup with an xdg_positioner with + set_reactive requested, or in response to xdg_popup.reposition requests. @@ -1116,5 +1183,58 @@ + + + + + Reposition an already-mapped popup. The popup will be placed given the + details in the passed xdg_positioner object, and a + xdg_popup.repositioned followed by xdg_popup.configure and + xdg_surface.configure will be emitted in response. Any parameters set + by the previous positioner will be discarded. + + The passed token will be sent in the corresponding + xdg_popup.repositioned event. The new popup position will not take + effect until the corresponding configure event is acknowledged by the + client. See xdg_popup.repositioned for details. The token itself is + opaque, and has no other special meaning. + + If multiple reposition requests are sent, the compositor may skip all + but the last one. + + If the popup is repositioned in response to a configure event for its + parent, the client should send an xdg_positioner.set_parent_configure + and possibly a xdg_positioner.set_parent_size request to allow the + compositor to properly constrain the popup. + + If the popup is repositioned together with a parent that is being + resized, but not in response to a configure event, the client should + send a xdg_positioner.set_parent_size request. + + + + + + + + The repositioned event is sent as part of a popup configuration + sequence, together with xdg_popup.configure and lastly + xdg_surface.configure to notify the completion of a reposition request. + + The repositioned event is to notify about the completion of a + xdg_popup.reposition request. The token argument is the token passed + in the xdg_popup.reposition request. + + Immediately after this event is emitted, xdg_popup.configure and + xdg_surface.configure will be sent with the updated size and position, + as well as a new configure serial. + + The client should optionally update the content of the popup, but must + acknowledge the new popup configuration for the new position to take + effect. See xdg_surface.ack_configure for details. + + + +